diff --git a/2022-retrospective.html b/2022-retrospective.html index 989c954df..4741b9af6 100644 --- a/2022-retrospective.html +++ b/2022-retrospective.html @@ -2,8 +2,8 @@ - -2022년 회고 | GG + +2022년 회고 | GG @@ -12,28 +12,38 @@ - - - + + + -
-
본문으로 건너뛰기

2022년 회고

· 약 4분

적당한 전환점, 2022년을 돌아보며

전역

약 1년 6개월간의 공군 정보보호병 생활을 마치고 전역을 했다.
-조기 전역 때문에 2021년 12월에 나왔지만, 실제 전역 날짜는 2022년이니 회고에 적어도 상관없겠지.

조금 더 미래에 대한 생각을 해볼걸 그랬다.
+

2022년 회고

· 약 4분

적당한 전환점, 2022년을 돌아보며

+

전역

+

약 1년 6개월간의 공군 정보보호병 생활을 마치고 전역을 했다.
+조기 전역 때문에 2021년 12월에 나왔지만, 실제 전역 날짜는 2022년이니 회고에 적어도 상관없겠지.

+

조금 더 미래에 대한 생각을 해볼걸 그랬다.
전역을 했지만 뭐 하나 제대로 할 줄 아는 것도 없으니 넓은 바닷속에 덩그러니 놓아진 기분이 괜히 들었었다.
-일찍 생각을 정리하여 방향을 잡지 못했기에 아쉬움이 많이 남았다.

자바

전역을 하고 진로를 고민하다 향로님의 자바 공화국 포스팅을 읽고 나서 자바 공부를 시작했다.
+일찍 생각을 정리하여 방향을 잡지 못했기에 아쉬움이 많이 남았다.

+

자바

+

전역을 하고 진로를 고민하다 향로님의 자바 공화국 포스팅을 읽고 나서 자바 공부를 시작했다.
유명한 인프런의 김영한님의 스프링 강의도 있고, 좋은 자바 개발 서적이 많아서 독학하기로 결정했다.
하다 보니 자바와 스프링을 공부하면서 “왜 진작하지 않았지”라는 생각도 많이 들었다.
-양질의 자료도 많았기 때문에, 예전에 노드로 개발했을 때 풀지 못했던 답답함을 많이 해소했던 것 같다.

23년에는 조금 더 깊게 자바를 공부해볼 생각이다.
-언어를 하나 깊게 공부하는 건 많은 도움이 되는 것 같다.

스터디

김영한님의 강의를 거의 다 들었을 때쯤, 항상 강의에서 언급되는 토비의 스프링을 읽어보고 싶어졌고
+양질의 자료도 많았기 때문에, 예전에 노드로 개발했을 때 풀지 못했던 답답함을 많이 해소했던 것 같다.

+

23년에는 조금 더 깊게 자바를 공부해볼 생각이다.
+언어를 하나 깊게 공부하는 건 많은 도움이 되는 것 같다.

+

스터디

+

김영한님의 강의를 거의 다 들었을 때쯤, 항상 강의에서 언급되는 토비의 스프링을 읽어보고 싶어졌고
혼자 공부하기에는 동기부여도 부족했기 때문에 스터디를 시작했다.
다른 사람에게 설명을 해야 했기 때문에 더욱 꼼꼼하게 공부를 할 수 있어서 좋았지만 나에게는 내용이 꽤나 어려워서 시간을 많이 소비했다.
-같이 스터디하시는 분과 7개월 동안 스터디를 꾸준히 이어나가 총 3권의 책을 읽을 수 있었다.

우아한 테크코스

군 복무 중일 때 지원했다 떨어진 우아한 테크코스를 다시 지원했다.
+같이 스터디하시는 분과 7개월 동안 스터디를 꾸준히 이어나가 총 3권의 책을 읽을 수 있었다.

+

우아한 테크코스

+

군 복무 중일 때 지원했다 떨어진 우아한 테크코스를 다시 지원했다.
이번 연도에 취업을 하는 게 목표였지만 내가 가지고 있는 특별한 무기가 없다는 걸 깨달았다.
-적지 않은 시간을 투자해 준비를 했고, 감사하게도 이번에는 최종 합격을 했다.

난 사람들과 소통하고, 협업하는 능력이 부족하다고 생각을 많이 했다.
-우아한 테크코스를 통해 그 빈 부분을 채우도록 노력해야겠다.

2023년에는

마음의 여유가 없었던 2022년이었던 것 같다.
-하고 싶은 건 많지만, 이번에는 여유를 가지고 할 수 있는 것에 최선을 다해야겠다.

- - +적지 않은 시간을 투자해 준비를 했고, 감사하게도 이번에는 최종 합격을 했다.

+

난 사람들과 소통하고, 협업하는 능력이 부족하다고 생각을 많이 했다.
+우아한 테크코스를 통해 그 빈 부분을 채우도록 노력해야겠다.

+

2023년에는

+

마음의 여유가 없었던 2022년이었던 것 같다.
+하고 싶은 건 많지만, 이번에는 여유를 가지고 할 수 있는 것에 최선을 다해야겠다.

\ No newline at end of file diff --git a/404.html b/404.html index 559eab2d7..15fe9fbb8 100644 --- a/404.html +++ b/404.html @@ -2,8 +2,8 @@ - -페이지를 찾을 수 없습니다. | GG + +페이지를 찾을 수 없습니다. | GG @@ -12,14 +12,11 @@ - - - + + + -
-
본문으로 건너뛰기

페이지를 찾을 수 없습니다.

원하는 페이지를 찾을 수 없습니다.

사이트 관리자에게 링크가 깨진 것을 알려주세요.

- - +
본문으로 건너뛰기

페이지를 찾을 수 없습니다.

원하는 페이지를 찾을 수 없습니다.

사이트 관리자에게 링크가 깨진 것을 알려주세요.

\ No newline at end of file diff --git a/accidental-duplication.html b/accidental-duplication.html index 34b170ca2..b335102c1 100644 --- a/accidental-duplication.html +++ b/accidental-duplication.html @@ -2,8 +2,8 @@ - -중복과 우발적 중복 | GG + +중복과 우발적 중복 | GG @@ -12,27 +12,142 @@ - - - + + + -
-
본문으로 건너뛰기

중복과 우발적 중복

· 약 8분

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.
-요청에 담긴 Body를 통해 전달받은 값을 DTO로 매핑하여 추가와 수정을 했다.

장바구니 미션에서의 상품 추가 및 수정

중복1

클래스명을 제외하고 필드와 검증로직 그 외 모든게 같은 DTO를 보며 중복이라고 생각했다.
+

중복과 우발적 중복

· 약 8분

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.
+요청에 담긴 Body를 통해 전달받은 값을 DTO로 매핑하여 추가와 수정을 했다.

+

장바구니 미션에서의 상품 추가 및 수정

+

중복1

+

클래스명을 제외하고 필드와 검증로직 그 외 모든게 같은 DTO를 보며 중복이라고 생각했다.
하지만 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-위 경우는 중복일까? 중복이 아닐까?

이 부분에 대해서 다음과 같은 리뷰를 받았다.

ProductSaveRequestProductUpdateRequest가 완전히 동일한데, 재사용할 수 없을까? 라는 리뷰를 남겼었어요. 사실 생성과 수정은 서로 달라질 개연성이 높아서 미리 분리해놓는 게 더 좋은 방법이긴 한데, 그래도 중복은 싫어서 저도 요즘 이런저런 방법들을 시도해보는 중 입니다. 허브는 이 부분에 대해 어떤 생각을 가지고 있을지 궁금하네요 ㅎㅎ

질문에 대해 아래와 같이 답변을 했다.

저장과 수정할 때 필요한 필드값이 동일하여 현재 구조에서는 하나로 사용해도 된다고 생각을 하지만, 말씀해주신대로 요구사항이 변경된다면 달라질 가능성이 높다고 판단하였습니다!

중복과 우발적 중복

로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 거짓된 중복, 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다. -그렇기 때문에 위 상황은 우발적 중복으로 보인다. 그래도 중복을 제거해볼 수 있지 않을까?

하나로 사용하는 건 안좋아보이고, 중복은 제거하고 싶은 마음

지금은 추가, 수정 2가지 경우 밖에 없지만 조금 더 복잡한 요구사항이 주어져서 10가지 경우로 입력을 받으면 어떻게 해야할까?
+위 경우는 중복일까? 중복이 아닐까?

+

이 부분에 대해서 다음과 같은 리뷰를 받았다.

+
+

ProductSaveRequestProductUpdateRequest가 완전히 동일한데, 재사용할 수 없을까? 라는 리뷰를 남겼었어요. 사실 생성과 수정은 서로 달라질 개연성이 높아서 미리 분리해놓는 게 더 좋은 방법이긴 한데, 그래도 중복은 싫어서 저도 요즘 이런저런 방법들을 시도해보는 중 입니다. 허브는 이 부분에 대해 어떤 생각을 가지고 있을지 궁금하네요 ㅎㅎ

+
+

질문에 대해 아래와 같이 답변을 했다.

+
+

저장과 수정할 때 필요한 필드값이 동일하여 현재 구조에서는 하나로 사용해도 된다고 생각을 하지만, 말씀해주신대로 요구사항이 변경된다면 달라질 가능성이 높다고 판단하였습니다!

+
+

중복과 우발적 중복

+

로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러가지 종류로 나누어 설명하고 있다.

+
    +
  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • +
  • 거짓된 중복, 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.
  • +
+

추가와 수정은 초기에는 중복으로 보이지만 초기 생성시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다. +그렇기 때문에 위 상황은 우발적 중복으로 보인다. 그래도 중복을 제거해볼 수 있지 않을까?

+

하나로 사용하는 건 안좋아보이고, 중복은 제거하고 싶은 마음

+

지금은 추가, 수정 2가지 경우 밖에 없지만 조금 더 복잡한 요구사항이 주어져서 10가지 경우로 입력을 받으면 어떻게 해야할까?
서비스 계층에서도 계층의 분리를 위해서 다른 DTO를 사용하고 있다면 20개의 DTO를 만들어야 할까?
-리뷰어가 알려준 의존 역전을 이용한 방법을 통해 이를 해결해보자!

중복 제거 전 코드

현재 코드에서는 아래와 같은 구조로 되어있다.
+리뷰어가 알려준 의존 역전을 이용한 방법을 통해 이를 해결해보자!

+

중복 제거 전 코드

+

현재 코드에서는 아래와 같은 구조로 되어있다.
Controller와 Service에서 저장, 수정할 때 각각의 DTO를 사용하고 있다. -현재 DTO는 controller, service 패키지 내에 있는 것이 아니라 dto라는 패키지에 위치하고 있다.

├── controller
│   └── ProductController
├── service
│   └── ProductService
├── dto
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest

중복2

인터페이스 작성하기

중복3

서비스 레이어에서 필요로 하는 값들을 인터페이스로 정의한다.
-해당 인터페이스는 서비스에서 사용하기 때문에 service 패키지 내부로 옮겨준다.

├── controller
│   └── ProductController
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public interface ProductSaveRequest {

String getName();

String getImage();

Long getPrice();
}

// ProductService
public Long save(final ProductSaveRequest request) {
final Product product = new Product(request.getName(), request.getImage(), request.getPrice());
return productDao.saveAndGetId(product);
}

구현체 작성하기

중복4

위에서 작성한 인터페이스를 구현하는 클래스를 작성한다.
-요청은 ProductRequest 클래스로 받고, 서비스에 전달할 땐 해당 인터페이스의 명세만 맞추면 문제없이 사용할 수 있다.

├── controller
│   ├── ProductController
│   └── ProductRequest
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {

@NotBlank(message = "이름은 공백일 수 없습니다.")
@Size(min = 1, max = 100, message = "이름은 최소 {min}자 이상, {max}자 이하여야 합니다.")
private final String name;

@NotBlank(message = "이미지는 공백일 수 없습니다.")
private final String image;

@Range(message = "가격은 최소 {min}원 이상, {max}원 이하여야 합니다.")
private final long price;

public ProductRequest(final String name, final String image, final long price) {
this.name = name;
this.image = image;
this.price = price;
}

@Override
public String getName() {
return name;
}

@Override
public String getImage() {
return image;
}

@Override
public long getPrice() {
return price;
}
}

// ProductController
@PostMapping("/products")
public ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {
final Long id = productService.save(request);
return ResponseEntity.created(URI.create("/products/" + id)).build();
}

정리

위와 같이 구현한다면 다음과 같은 장점을 얻을 수 있다.

  1. Service에서 모든 클라이언트 요청에 대한 DTO를 알지 않아도 된다.
  2. 공통적으로 사용하는 DTO를 제외하고 DTO 패키지에 대한 결합도가 낮아지고, 각 레이어의 응집도가 증가한다.
  3. 요청 객체만 다르고 서비스에서 동일한 행위를 수행하는 경우 중복을 제거할 수 있다.

위 방법을 지금 미션에서 바로 적용할까 하다가, 나중에 필요할 때 적용하면 더 좋을 것 같아서 미션에는 적용하지 않았다.
-상황에 맞춰 적재적소에 의존 역전을 이용해보는 것도 좋을 것 같다.

참고 자료

클린 아키텍처 16장 독립성, 로버트 C. 마틴
-https://techblog.woowahan.com/2647/
-https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/

- - +현재 DTO는 controller, service 패키지 내에 있는 것이 아니라 dto라는 패키지에 위치하고 있다.

+
├── controller
+│   └── ProductController
+├── service
+│   └── ProductService
+├── dto
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+

중복2

+

인터페이스 작성하기

+

중복3

+

서비스 레이어에서 필요로 하는 값들을 인터페이스로 정의한다.
+해당 인터페이스는 서비스에서 사용하기 때문에 service 패키지 내부로 옮겨준다.

+
├── controller
+│   └── ProductController
+├── service
+│   ├── ProductService
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+
public interface ProductSaveRequest {
+
+    String getName();
+
+    String getImage();
+
+    Long getPrice();
+}
+
+// ProductService
+public Long save(final ProductSaveRequest request) {
+    final Product product = new Product(request.getName(), request.getImage(), request.getPrice());
+    return productDao.saveAndGetId(product);
+}
+
+

구현체 작성하기

+

중복4

+

위에서 작성한 인터페이스를 구현하는 클래스를 작성한다.
+요청은 ProductRequest 클래스로 받고, 서비스에 전달할 땐 해당 인터페이스의 명세만 맞추면 문제없이 사용할 수 있다.

+
├── controller
+│   ├── ProductController
+│   └── ProductRequest
+├── service
+│   ├── ProductService
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+
public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {
+
+    @NotBlank(message = "이름은 공백일 수 없습니다.")
+    @Size(min = 1, max = 100, message = "이름은 최소 {min}자 이상, {max}자 이하여야 합니다.")
+    private final String name;
+
+    @NotBlank(message = "이미지는 공백일 수 없습니다.")
+    private final String image;
+
+    @Range(message = "가격은 최소 {min}원 이상, {max}원 이하여야 합니다.")
+    private final long price;
+
+    public ProductRequest(final String name, final String image, final long price) {
+        this.name = name;
+        this.image = image;
+        this.price = price;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getImage() {
+        return image;
+    }
+
+    @Override
+    public long getPrice() {
+        return price;
+    }
+}
+
+// ProductController
+@PostMapping("/products")
+public ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {
+    final Long id = productService.save(request);
+    return ResponseEntity.created(URI.create("/products/" + id)).build();
+}
+
+

정리

+

위와 같이 구현한다면 다음과 같은 장점을 얻을 수 있다.

+
    +
  1. Service에서 모든 클라이언트 요청에 대한 DTO를 알지 않아도 된다.
  2. +
  3. 공통적으로 사용하는 DTO를 제외하고 DTO 패키지에 대한 결합도가 낮아지고, 각 레이어의 응집도가 증가한다.
  4. +
  5. 요청 객체만 다르고 서비스에서 동일한 행위를 수행하는 경우 중복을 제거할 수 있다.
  6. +
+

위 방법을 지금 미션에서 바로 적용할까 하다가, 나중에 필요할 때 적용하면 더 좋을 것 같아서 미션에는 적용하지 않았다.
+상황에 맞춰 적재적소에 의존 역전을 이용해보는 것도 좋을 것 같다.

+

참고 자료

+

클린 아키텍처 16장 독립성, 로버트 C. 마틴
+https://techblog.woowahan.com/2647/
+https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/

\ No newline at end of file diff --git a/assets/css/styles.3e9e019f.css b/assets/css/styles.3e9e019f.css new file mode 100644 index 000000000..5366eff24 --- /dev/null +++ b/assets/css/styles.3e9e019f.css @@ -0,0 +1 @@ +@import url(https://fonts.googleapis.com/css?family=IBM+Plex+Sans+KR);@import url(https://fonts.googleapis.com/css2?family=Fredoka+One);.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,.hash-link{-webkit-user-select:none}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}*,.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#2a5934;--ifm-color-primary-dark:#111;--ifm-color-primary-darker:#111;--ifm-color-primary-darkest:#111;--ifm-color-primary-light:#111;--ifm-color-primary-lighter:#111;--ifm-color-primary-lightest:#111;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--ifm-font-family-base:"IBM Plex Sans KR",Arial,Verdana,Tahoma,sans-serif;--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:#656c85cc;--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 #ffffff80,0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px #1e235a66;--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 #45629b1f;--docsearch-primary-color:var(--ifm-color-primary);--docsearch-text-color:var(--ifm-font-color-base);--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}.container_lyt7,.container_lyt7>svg,img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul,.tabList__CuJ{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_Gvgb,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{list-style:none;padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;list-style:none;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_BuS1>:last-child,.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child,.footer__items,.tabItem_Ymn6>:last-child{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title,.title_f1Hy{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{list-style:none;margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;content:"";filter:var(--ifm-menu-link-sublist-icon-filter)}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover,.sidebarItemLink_mo7H:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.DocSearch-Hit[aria-selected=true] mark,.content_knG7 a{text-decoration:underline}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec;--docsearch-text-color:#f5f6f7;--docsearch-container-background:#090a11cc;--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 #0304094d;--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 #494c6a80,0 -4px 8px 0 #0003;--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#25c2a0;--ifm-color-primary-dark:#21af90;--ifm-color-primary-darker:#1fa588;--ifm-color-primary-darkest:#1a8870;--ifm-color-primary-light:#29d5b0;--ifm-color-primary-lighter:#32d8b4;--ifm-color-primary-lightest:#4fddbf;--docusaurus-highlighted-code-line-bg:#0000004d}.docusaurus-highlight-code-line{background-color:#0000001a;display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}html[data-theme=dark] .docusaurus-highlight-code-line{background-color:#0000004d}.header-github-link:hover{opacity:.6}.header-github-link:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat;content:"";display:flex;height:24px;width:24px}html[data-theme=dark] .header-github-link:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat}.navbar__title{font-family:Fredoka One;font-size:larger;font-weight:400}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_YfHR,.navbarSearchContainer_Bca1:not(:has(>*)),.sidebarLogo_isFc,.themedComponent_mlkZ,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);user-select:none}.hash-link:before{content:"#"}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size);font-weight:var(--ifm-font-weight-bold)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.searchQueryInput_u2C7,.searchVersionInput_m0Ui{background:var(--docsearch-searchbox-focus-background);border:2px solid var(--ifm-toc-border-color);border-radius:var(--ifm-global-radius);color:var(--docsearch-text-color);font:var(--ifm-font-size-base) var(--ifm-font-family-base);margin-bottom:.5rem;padding:.8rem;transition:border var(--ifm-transition-fast) ease;width:100%}.searchQueryInput_u2C7:focus,.searchVersionInput_m0Ui:focus{border-color:var(--docsearch-primary-color);outline:0}.searchQueryInput_u2C7::placeholder{color:var(--docsearch-muted-color)}.searchResultsColumn_JPFH{font-size:.9rem;font-weight:700}.algoliaLogo_rT1R{max-width:150px}.algoliaLogoPathFill_WdUC{fill:var(--ifm-font-color-base)}.searchResultItem_Tv2o{border-bottom:1px solid var(--ifm-toc-border-color);padding:1rem 0}.searchResultItemHeading_KbCB{font-weight:400;margin-bottom:0}.searchResultItemPath_lhe1{--ifm-breadcrumb-separator-size-multiplier:1;color:var(--ifm-color-content-secondary);font-size:.8rem}.searchResultItemSummary_AEaO{font-style:italic;margin:.5rem 0 0}.loadingSpinner_XVxU{animation:1s linear infinite a;border:.4em solid #eee;border-radius:50%;border-top:.4em solid var(--ifm-color-primary);height:3rem;margin:0 auto;width:3rem}@keyframes a{to{transform:rotate(1turn)}}.loader_vvXV{margin-top:2rem}.search-result-match{background:#ffd78e40;color:var(--docsearch-hit-color);padding:.09em 0}.authorCol_Hf19{flex-grow:1!important;max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}.DocSearch-Button,.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Button{background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;font-weight:500;height:36px;justify-content:space-between;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:0}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Hit-Tree,.DocSearch-Hit-action,.DocSearch-Hit-icon,.DocSearch-Reset{stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Input,.DocSearch-Link{-webkit-appearance:none;font:inherit}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 2px;position:relative;top:-1px;width:20px}.DocSearch--active{overflow:hidden!important}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{appearance:none;background:#0000;border:0;color:var(--docsearch-text-color);flex:1;font-size:1.2em;height:100%;outline:0;padding:0 0 0 8px;width:80%}.DocSearch-Hit-action-button,.DocSearch-Reset{-webkit-appearance:none;border:0;cursor:pointer}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Cancel,.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator,.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset{animation:.1s ease-in forwards b;appearance:none;background:none;border-radius:50%;color:var(--docsearch-icon-color);padding:2px;right:0}.DocSearch-Help,.DocSearch-HitsFooter,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:#0000}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}.DocSearch-Hit--deleting{opacity:0;transition:.25s linear}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:.25s linear .25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{appearance:none;background:none;border-radius:50%;color:inherit;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon,.tocCollapsibleContent_vkbj a{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:0;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands li,.DocSearch-Commands-Key{align-items:center;display:flex}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{background:var(--docsearch-key-gradient);border:0;border-radius:2px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;width:20px}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}@keyframes b{0%{opacity:0}to{opacity:1}}.DocSearch-Button{margin:0;transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.DocSearch-Container{z-index:calc(var(--ifm-z-index-fixed) + 1)}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;list-style:none;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.containsTaskList_mC6p{list-style:none}.img_ev3q{height:auto}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family)}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.blogPostFooterDetailsFull_mRVl{flex-direction:column}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn{max-width:75%!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media only screen and (max-width:996px){.searchQueryColumn_RTkw,.searchResultsColumn_JPFH{max-width:60%!important}.searchLogoColumn_rJIA,.searchVersionColumn_ypXd{max-width:40%!important}.searchLogoColumn_rJIA{padding-left:0!important}}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder,.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%;max-height:calc(var(--docsearch-vh,1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh,1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh,1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Cancel{-webkit-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:0;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.title_f1Hy{font-size:2rem}}@media screen and (max-width:576px){.searchQueryColumn_RTkw{max-width:100%!important}.searchVersionColumn_ypXd{max-width:100%!important;padding-left:var(--ifm-spacing-horizontal)!important}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{stroke-width:var(--docsearch-icon-stroke-width);animation:none;-webkit-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0}.DocSearch-Hit--deleting,.DocSearch-Hit--favoriting{transition:none}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/assets/css/styles.ca6d2131.css b/assets/css/styles.ca6d2131.css deleted file mode 100644 index 9e8980023..000000000 --- a/assets/css/styles.ca6d2131.css +++ /dev/null @@ -1 +0,0 @@ -@import url(https://fonts.googleapis.com/css?family=IBM+Plex+Sans+KR);@import url(https://fonts.googleapis.com/css2?family=Fredoka+One);.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}*,.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#2a5934;--ifm-color-primary-dark:#111;--ifm-color-primary-darker:#111;--ifm-color-primary-darkest:#111;--ifm-color-primary-light:#111;--ifm-color-primary-lighter:#111;--ifm-color-primary-lightest:#111;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--ifm-font-family-base:"IBM Plex Sans KR",Arial,Verdana,Tahoma,sans-serif;--docusaurus-announcement-bar-height:auto;--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:#656c85cc;--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 #ffffff80,0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px #1e235a66;--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 #45629b1f;--docsearch-primary-color:var(--ifm-color-primary);--docsearch-text-color:var(--ifm-font-color-base);--docusaurus-tag-list-border:var(--ifm-color-emphasis-300)}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}html{-webkit-font-smoothing:antialiased;-webkit-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);text-rendering:optimizelegibility}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}.container_lyt7,.container_lyt7>svg,img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul,.tabList__CuJ{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_tbUL,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{list-style:none;padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;list-style:none;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item{margin-top:0}.admonitionContent_S0QG>:last-child,.collapsibleContent_i85q>:last-child,.footer__items,.tabItem_Ymn6>:last-child{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title,.title_f1Hy{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{list-style:none;margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;content:"";filter:var(--ifm-menu-link-sublist-icon-filter)}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;position:fixed;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;left:0;top:0;visibility:hidden}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{-webkit-appearance:none;appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:.9rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover,.sidebarItemLink_mo7H:hover{text-decoration:none}.pagination-nav{grid-gap:var(--ifm-spacing-horizontal);display:grid;gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.DocSearch-Hit[aria-selected=true] mark,.content_knG7 a{text-decoration:underline}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec;--docsearch-text-color:#f5f6f7;--docsearch-container-background:#090a11cc;--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 #0304094d;--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 #494c6a80,0 -4px 8px 0 #0003;--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#25c2a0;--ifm-color-primary-dark:#21af90;--ifm-color-primary-darker:#1fa588;--ifm-color-primary-darkest:#1a8870;--ifm-color-primary-light:#29d5b0;--ifm-color-primary-lighter:#32d8b4;--ifm-color-primary-lightest:#4fddbf;--docusaurus-highlighted-code-line-bg:#0000004d}.docusaurus-highlight-code-line{background-color:#0000001a;display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}html[data-theme=dark] .docusaurus-highlight-code-line{background-color:#0000004d}.header-github-link:hover{opacity:.6}.header-github-link:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat;content:"";display:flex;height:24px;width:24px}html[data-theme=dark] .header-github-link:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23fff' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat}.navbar__title{font-family:Fredoka One;font-size:larger;font-weight:400}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}#__docusaurus-base-url-issue-banner-container,.docSidebarContainer_b6E3,.sidebarLogo_isFc,.themedImage_ToTc,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.toggleButton_gllP{align-items:center;border-radius:50%;display:flex;height:100%;justify-content:center;transition:background var(--ifm-transition-fast);width:100%}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}[data-theme=dark] .themedImage--dark_i4oU,[data-theme=light] .themedImage--light_HNdA,html:not([data-theme]) .themedComponent--light_NU7w{display:initial}.iconExternalLink_nPIU{margin-left:.3rem}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.sidebar_re4s{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 2rem)}.sidebarItemTitle_pO2u{font-size:var(--ifm-h3-font-size);font-weight:var(--ifm-font-weight-bold)}.container_mt6G,.sidebarItemList_Yudw{font-size:.9rem}.sidebarItem__DBe{margin-top:.7rem}.sidebarItemLink_mo7H{color:var(--ifm-font-color-base);display:block}.sidebarItemLinkActive_I1ZP{color:var(--ifm-color-primary)!important}.searchQueryInput_u2C7,.searchVersionInput_m0Ui{background:var(--docsearch-searchbox-focus-background);border:2px solid var(--ifm-toc-border-color);border-radius:var(--ifm-global-radius);color:var(--docsearch-text-color);font:var(--ifm-font-size-base) var(--ifm-font-family-base);margin-bottom:.5rem;padding:.8rem;transition:border var(--ifm-transition-fast) ease;width:100%}.searchQueryInput_u2C7:focus,.searchVersionInput_m0Ui:focus{border-color:var(--docsearch-primary-color);outline:0}.searchQueryInput_u2C7::placeholder{color:var(--docsearch-muted-color)}.searchResultsColumn_JPFH{font-size:.9rem;font-weight:700}.algoliaLogo_rT1R{max-width:150px}.algoliaLogoPathFill_WdUC{fill:var(--ifm-font-color-base)}.searchResultItem_Tv2o{border-bottom:1px solid var(--ifm-toc-border-color);padding:1rem 0}.searchResultItemHeading_KbCB{font-weight:400;margin-bottom:0}.searchResultItemPath_lhe1{--ifm-breadcrumb-separator-size-multiplier:1;color:var(--ifm-color-content-secondary);font-size:.8rem}.searchResultItemSummary_AEaO{font-style:italic;margin:.5rem 0 0}.loadingSpinner_XVxU{animation:1s linear infinite a;border:.4em solid #eee;border-radius:50%;border-top:.4em solid var(--ifm-color-primary);height:3rem;margin:0 auto;width:3rem}@keyframes a{to{transform:rotate(1turn)}}.loader_vvXV{margin-top:2rem}.search-result-match{background:#ffd78e40;color:var(--docsearch-hit-color);padding:.09em 0}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.docMainContainer_gTbr,.docPage__5DB{display:flex;width:100%}.docPage__5DB{flex:1 0}.docsWrapper_BCFX{display:flex;flex:1 0 auto}.authorCol_Hf19{flex-grow:1!important;max-width:inherit!important}.imageOnlyAuthorRow_pa_O{display:flex;flex-flow:row wrap}.DocSearch-Button,.DocSearch-Button-Container{align-items:center;display:flex}.imageOnlyAuthorCol_G86a{margin-left:.3rem;margin-right:.3rem}.DocSearch-Button{background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;font-weight:500;height:36px;justify-content:space-between;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:0}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Hit-Tree,.DocSearch-Hit-action,.DocSearch-Hit-icon,.DocSearch-Reset{stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Input,.DocSearch-Link{-webkit-appearance:none;font:inherit}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 2px;position:relative;top:-1px;width:20px}.DocSearch--active{overflow:hidden!important}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{appearance:none;background:#0000;border:0;color:var(--docsearch-text-color);flex:1;font-size:1.2em;height:100%;outline:0;padding:0 0 0 8px;width:80%}.DocSearch-Hit-action-button,.DocSearch-Reset{-webkit-appearance:none;border:0;cursor:pointer}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Cancel,.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator,.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset{animation:.1s ease-in forwards b;appearance:none;background:none;border-radius:50%;color:var(--docsearch-icon-color);padding:2px;right:0}.DocSearch-Help,.DocSearch-HitsFooter,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Reset:focus{outline:0}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:#0000}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}.DocSearch-Hit--deleting{opacity:0;transition:.25s linear}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:.25s linear .25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{appearance:none;background:none;border-radius:50%;color:inherit;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon,.tocCollapsibleContent_vkbj a{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:0;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands li,.DocSearch-Commands-Key{align-items:center;display:flex}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{background:var(--docsearch-key-gradient);border:0;border-radius:2px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;width:20px}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}@keyframes b{0%{opacity:0}to{opacity:1}}.DocSearch-Button{margin:0;transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.DocSearch-Container{z-index:calc(var(--ifm-z-index-fixed) + 1)}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{fill:currentColor;height:inherit;left:0;opacity:inherit;position:absolute;top:0;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tag_Nnez{display:inline-block;margin:.5rem .5rem 0 1rem}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.lastUpdated_vwxv{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;list-style:none;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.containsTaskList_mC6p{list-style:none}.img_ev3q{height:auto}.admonition_LlT9{margin-bottom:1em}.admonitionHeading_tbUL{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.3rem}.admonitionHeading_tbUL code{text-transform:none}.admonitionIcon_kALy{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_kALy svg{fill:var(--ifm-alert-foreground-color);display:inline-block;height:1.6em;width:1.6em}.blogPostFooterDetailsFull_mRVl{flex-direction:column}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_m80_{background-color:var(--docusaurus-collapse-button-bg)}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.searchBox_ZlJk{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_BlDH,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_m80_:focus,.expandButton_m80_:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_m80_{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_BlDH{transform:rotate(180deg)}.docSidebarContainer_b6E3{border-right:1px solid var(--ifm-toc-border-color);-webkit-clip-path:inset(0);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_b3ry{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_Xe31{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_gTbr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_Uz_u{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_czyv{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}.lastUpdated_vwxv{text-align:right}.tocMobile_ITEo{display:none}.docItemCol_VOVn{max-width:75%!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.sidebar_re4s,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.searchBox_ZlJk{position:absolute;right:var(--ifm-navbar-padding-horizontal)}.docItemContainer_F8PC{padding:0 .3rem}}@media only screen and (max-width:996px){.searchQueryColumn_RTkw,.searchResultsColumn_JPFH{max-width:60%!important}.searchLogoColumn_rJIA,.searchVersionColumn_ypXd{max-width:40%!important}.searchLogoColumn_rJIA{padding-left:0!important}}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder,.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%;max-height:calc(var(--docsearch-vh,1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh,1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh,1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Cancel{-webkit-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:0;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}.title_f1Hy{font-size:2rem}}@media screen and (max-width:576px){.searchQueryColumn_RTkw{max-width:100%!important}.searchVersionColumn_ypXd{max-width:100%!important;padding-left:var(--ifm-spacing-horizontal)!important}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{stroke-width:var(--docsearch-icon-stroke-width);animation:none;-webkit-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0}.DocSearch-Hit--deleting,.DocSearch-Hit--favoriting{transition:none}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/assets/js/01a85c17.1cd64a05.js b/assets/js/01a85c17.1cd64a05.js new file mode 100644 index 000000000..85d2efc89 --- /dev/null +++ b/assets/js/01a85c17.1cd64a05.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4013],{61460:(e,t,s)=>{s.d(t,{Z:()=>v});var a=s(67294),i=s(86010),r=s(58207),l=s(87524),n=s(39960),c=s(95999),o=s(16550),m=s(48596);function d(e){const{pathname:t}=(0,o.TH)();return(0,a.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,m.Mg)(e.permalink,t))}(e,t)))),[e,t])}const u={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};var g=s(85893);function b(e){let{sidebar:t}=e;const s=d(t.items);return(0,g.jsx)("aside",{className:"col col--3",children:(0,g.jsxs)("nav",{className:(0,i.Z)(u.sidebar,"thin-scrollbar"),"aria-label":(0,c.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,g.jsx)("div",{className:(0,i.Z)(u.sidebarItemTitle,"margin-bottom--md"),children:t.title}),(0,g.jsx)("ul",{className:(0,i.Z)(u.sidebarItemList,"clean-list"),children:s.map((e=>(0,g.jsx)("li",{className:u.sidebarItem,children:(0,g.jsx)(n.Z,{isNavLink:!0,to:e.permalink,className:u.sidebarItemLink,activeClassName:u.sidebarItemLinkActive,children:e.title})},e.permalink)))})]})})}var h=s(13102);function p(e){let{sidebar:t}=e;const s=d(t.items);return(0,g.jsx)("ul",{className:"menu__list",children:s.map((e=>(0,g.jsx)("li",{className:"menu__list-item",children:(0,g.jsx)(n.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active",children:e.title})},e.permalink)))})}function j(e){return(0,g.jsx)(h.Zo,{component:p,props:e})}function x(e){let{sidebar:t}=e;const s=(0,l.i)();return t?.items.length?"mobile"===s?(0,g.jsx)(j,{sidebar:t}):(0,g.jsx)(b,{sidebar:t}):null}function v(e){const{sidebar:t,toc:s,children:a,...l}=e,n=t&&t.items.length>0;return(0,g.jsx)(r.Z,{...l,children:(0,g.jsx)("div",{className:"container margin-vert--lg",children:(0,g.jsxs)("div",{className:"row",children:[(0,g.jsx)(x,{sidebar:t}),(0,g.jsx)("main",{className:(0,i.Z)("col",{"col--7":n,"col--9 col--offset-1":!n}),itemScope:!0,itemType:"https://schema.org/Blog",children:a}),s&&(0,g.jsx)("div",{className:"col col--2",children:s})]})})})}},24524:(e,t,s)=>{s.r(t),s.d(t,{default:()=>u});s(67294);var a=s(86010),i=s(35155),r=s(10833),l=s(35281),n=s(61460),c=s(26090),o=s(90197),m=s(92503),d=s(85893);function u(e){let{tags:t,sidebar:s}=e;const u=(0,i.M)();return(0,d.jsxs)(r.FG,{className:(0,a.Z)(l.k.wrapper.blogPages,l.k.page.blogTagsListPage),children:[(0,d.jsx)(r.d,{title:u}),(0,d.jsx)(o.Z,{tag:"blog_tags_list"}),(0,d.jsxs)(n.Z,{sidebar:s,children:[(0,d.jsx)(m.Z,{as:"h1",children:u}),(0,d.jsx)(c.Z,{tags:t})]})]})}},13008:(e,t,s)=>{s.d(t,{Z:()=>n});s(67294);var a=s(86010),i=s(39960);const r={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var l=s(85893);function n(e){let{permalink:t,label:s,count:n}=e;return(0,l.jsxs)(i.Z,{href:t,className:(0,a.Z)(r.tag,n?r.tagWithCount:r.tagRegular),children:[s,n&&(0,l.jsx)("span",{children:n})]})}},26090:(e,t,s)=>{s.d(t,{Z:()=>o});s(67294);var a=s(35155),i=s(13008),r=s(92503);const l={tag:"tag_Nnez"};var n=s(85893);function c(e){let{letterEntry:t}=e;return(0,n.jsxs)("article",{children:[(0,n.jsx)(r.Z,{as:"h2",id:t.letter,children:t.letter}),(0,n.jsx)("ul",{className:"padding--none",children:t.tags.map((e=>(0,n.jsx)("li",{className:l.tag,children:(0,n.jsx)(i.Z,{...e})},e.permalink)))}),(0,n.jsx)("hr",{})]})}function o(e){let{tags:t}=e;const s=(0,a.P)(t);return(0,n.jsx)("section",{className:"margin-vert--lg",children:s.map((e=>(0,n.jsx)(c,{letterEntry:e},e.letter)))})}},35155:(e,t,s)=>{s.d(t,{M:()=>i,P:()=>r});var a=s(95999);const i=()=>(0,a.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});function r(e){const t={};return Object.values(e).forEach((e=>{const s=function(e){return e[0].toUpperCase()}(e.label);t[s]??=[],t[s].push(e)})),Object.entries(t).sort(((e,t)=>{let[s]=e,[a]=t;return s.localeCompare(a)})).map((e=>{let[t,s]=e;return{letter:t,tags:s.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}}}]); \ No newline at end of file diff --git a/assets/js/01a85c17.6e93ad75.js b/assets/js/01a85c17.6e93ad75.js deleted file mode 100644 index 820178bca..000000000 --- a/assets/js/01a85c17.6e93ad75.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4013],{39058:(e,t,a)=>{a.d(t,{Z:()=>_});var l=a(67294),n=a(86010),r=a(7452),s=a(87524),c=a(39960),i=a(95999);const m="sidebar_re4s",o="sidebarItemTitle_pO2u",u="sidebarItemList_Yudw",g="sidebarItem__DBe",b="sidebarItemLink_mo7H",d="sidebarItemLinkActive_I1ZP";function E(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,n.Z)(m,"thin-scrollbar"),"aria-label":(0,i.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,n.Z)(o,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,n.Z)(u,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:g},l.createElement(c.Z,{isNavLink:!0,to:e.permalink,className:b,activeClassName:d},e.title)))))))}var p=a(13102);function h(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(c.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function k(e){return l.createElement(p.Zo,{component:h,props:e})}function N(e){let{sidebar:t}=e;const a=(0,s.i)();return t?.items.length?"mobile"===a?l.createElement(k,{sidebar:t}):l.createElement(E,{sidebar:t}):null}function _(e){const{sidebar:t,toc:a,children:s,...c}=e,i=t&&t.items.length>0;return l.createElement(r.Z,c,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(N,{sidebar:t}),l.createElement("main",{className:(0,n.Z)("col",{"col--7":i,"col--9 col--offset-1":!i}),itemScope:!0,itemType:"http://schema.org/Blog"},s),a&&l.createElement("div",{className:"col col--2"},a))))}},24524:(e,t,a)=>{a.r(t),a.d(t,{default:()=>u});var l=a(67294),n=a(86010),r=a(35155),s=a(10833),c=a(35281),i=a(39058),m=a(26090),o=a(90197);function u(e){let{tags:t,sidebar:a}=e;const u=(0,r.M)();return l.createElement(s.FG,{className:(0,n.Z)(c.k.wrapper.blogPages,c.k.page.blogTagsListPage)},l.createElement(s.d,{title:u}),l.createElement(o.Z,{tag:"blog_tags_list"}),l.createElement(i.Z,{sidebar:a},l.createElement("h1",null,u),l.createElement(m.Z,{tags:t})))}},13008:(e,t,a)=>{a.d(t,{Z:()=>m});var l=a(67294),n=a(86010),r=a(39960);const s="tag_zVej",c="tagRegular_sFm0",i="tagWithCount_h2kH";function m(e){let{permalink:t,label:a,count:m}=e;return l.createElement(r.Z,{href:t,className:(0,n.Z)(s,m?i:c)},a,m&&l.createElement("span",null,m))}},26090:(e,t,a)=>{a.d(t,{Z:()=>i});var l=a(67294),n=a(35155),r=a(13008);const s="tag_Nnez";function c(e){let{letterEntry:t}=e;return l.createElement("article",null,l.createElement("h2",null,t.letter),l.createElement("ul",{className:"padding--none"},t.tags.map((e=>l.createElement("li",{key:e.permalink,className:s},l.createElement(r.Z,e))))),l.createElement("hr",null))}function i(e){let{tags:t}=e;const a=(0,n.P)(t);return l.createElement("section",{className:"margin-vert--lg"},a.map((e=>l.createElement(c,{key:e.letter,letterEntry:e}))))}},35155:(e,t,a)=>{a.d(t,{M:()=>n,P:()=>r});var l=a(95999);const n=()=>(0,l.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});function r(e){const t={};return Object.values(e).forEach((e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)})),Object.entries(t).sort(((e,t)=>{let[a]=e,[l]=t;return a.localeCompare(l)})).map((e=>{let[t,a]=e;return{letter:t,tags:a.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}}}]); \ No newline at end of file diff --git a/assets/js/02689328.091cac7e.js b/assets/js/02689328.7a7f957d.js similarity index 84% rename from assets/js/02689328.091cac7e.js rename to assets/js/02689328.7a7f957d.js index a41e2a1bb..84c42aa4f 100644 --- a/assets/js/02689328.091cac7e.js +++ b/assets/js/02689328.7a7f957d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6346],{5577:a=>{a.exports=JSON.parse('{"label":"DataBase","permalink":"/tags/data-base","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6346],{5577:a=>{a.exports=JSON.parse('{"label":"DataBase","permalink":"/tags/data-base","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/02ede3c9.16e5bf41.js b/assets/js/02ede3c9.f2b1b1a0.js similarity index 81% rename from assets/js/02ede3c9.16e5bf41.js rename to assets/js/02ede3c9.f2b1b1a0.js index a9d655ec1..5da33a836 100644 --- a/assets/js/02ede3c9.16e5bf41.js +++ b/assets/js/02ede3c9.f2b1b1a0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4934],{51226:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4934],{51226:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/04644f5f.0a8f1a82.js b/assets/js/04644f5f.0a8f1a82.js new file mode 100644 index 000000000..589ee9733 --- /dev/null +++ b/assets/js/04644f5f.0a8f1a82.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2625],{37895:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>l,default:()=>u,frontMatter:()=>c,metadata:()=>o,toc:()=>a});var r=t(85893),i=t(3905);const c={title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",slug:"/etc/communication",last_update:{date:"2023/09/02"},tags:["etc"]},l=void 0,o={id:"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",description:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?",source:"@site/docs/\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00.mdx",sourceDirName:"\uae30\ud0c0",slug:"/etc/communication",permalink:"/docs/etc/communication",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00.mdx",tags:[{label:"etc",permalink:"/docs/tags/etc"}],version:"current",lastUpdatedAt:1693612800,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 2\uc77c",frontMatter:{title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",slug:"/etc/communication",last_update:{date:"2023/09/02"},tags:["etc"]},sidebar:"tutorialSidebar",previous:{title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",permalink:"/docs/etc/experience-and-self-question"},next:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",permalink:"/docs/network/load-balancing-algorithm"}},s={},a=[{value:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?",id:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158-\uc798-\ud558\ub294-\uac1c\ubc1c\uc790",level:3},{value:"\ubcc0\ud654\ub97c \ub9cc\ub4e4\ub824\uba74 \uc2b5\uad00\uc774 \ud544\uc694\ud558\ub2e4.",id:"\ubcc0\ud654\ub97c-\ub9cc\ub4e4\ub824\uba74-\uc2b5\uad00\uc774-\ud544\uc694\ud558\ub2e4",level:3},{value:"\uc88b\uc740 \uc2b5\uad00 4\uac00\uc9c0",id:"\uc88b\uc740-\uc2b5\uad00-4\uac00\uc9c0",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={br:"br",code:"code",h3:"h3",li:"li",ol:"ol",p:"p",ul:"ul",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158-\uc798-\ud558\ub294-\uac1c\ubc1c\uc790",children:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?"}),"\n",(0,r.jsx)(n.p,{children:"\uc2a4\ud399 \uad6c\ud604\ud615 \uac1c\ubc1c\uc790 vs \ubb38\uc81c \ud574\uacb0\ud615 \uac1c\ubc1c\uc790"}),"\n",(0,r.jsxs)(n.p,{children:["\uac1c\ubc1c\uc790 != \uc2a4\ud399\uc744 \uc8fc\uba74 \uc798 \uad6c\ud604\ud558\ub294 \uc0ac\ub78c",(0,r.jsx)(n.br,{}),"\n","\uad6c\ud604\uc5d0 \uc9d1\uc911\ud55c\ub2e4\uba74 \uc77c\uc758 \uc2dc\uc57c\uac00 \uc881\uc544\uc9c4\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\uc758\ub3c4\uc640 \ub9e5\ub77d\uc744 \uc774\ud574\ud574\uc11c, \ub354 \uc88b\uc740 \uc2a4\ud399\uc744 \ub9cc\ub4e4\uc5b4\ub0b4\ub824\uace0 \ud558\ub294 \uac1c\ubc1c\uc790\uac00 \ub418\uc5b4\uc57c \ud55c\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"\ubcc0\ud654\ub97c-\ub9cc\ub4e4\ub824\uba74-\uc2b5\uad00\uc774-\ud544\uc694\ud558\ub2e4",children:"\ubcc0\ud654\ub97c \ub9cc\ub4e4\ub824\uba74 \uc2b5\uad00\uc774 \ud544\uc694\ud558\ub2e4."}),"\n",(0,r.jsxs)(n.p,{children:["\uc8fc\ub2c8\uc5b4 \uac1c\ubc1c\uc790\ub294 \uc2a4\ud399 \uad6c\ud604 \uac1c\ubc1c\uc790\uc5d0\uc11c \uc2dc\uc791\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubcc0\ud654\ub97c \uc704\ud574 \uc2e4\uc81c\ub85c \ud589\ub3d9\ud558\ub294 ",(0,r.jsx)(n.code,{children:"\uc2b5\uad00"}),"\uc774 \ud544\uc694\ud558\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc88b\uc740-\uc2b5\uad00-4\uac00\uc9c0",children:"\uc88b\uc740 \uc2b5\uad00 4\uac00\uc9c0"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\ud574\uacb0\ud558\ub824\ub294 ",(0,r.jsx)(n.code,{children:"\ubb38\uc81c"}),"\uc640 ",(0,r.jsx)(n.code,{children:"\uc758\ub3c4/\uc0c1\ud669"}),"\uc5d0 \ub300\ud574 \ubb3b\ub294\ub2e4."]}),"\n",(0,r.jsxs)(n.li,{children:["\uc0c1\ub300\ubc29\uc758 \ub9d0\uc744 \ub4e3\uace0 ",(0,r.jsx)(n.code,{children:"\ub0b4\uac00"})," \uc774\ud574\ud55c \ubc14\ub97c \uc694\uc57d\ud558\uc5ec \uacf5\uc720\ud55c\ub2e4.","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ud55c \ubc88 \uc815\ub9ac\ud55c\ub2e4\uba74 1... 2... \uc774\ub807\uac8c \uc774\ud574\ud588\ub294\ub370 \ub9de\uc744\uae4c\uc694?"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\uc548 \ub41c\ub2e4\uace0 \ub9d0\ud560 \ub54c\ub294 \uc0c1\ub300\ubc29\uc5d0 \uad00\uc810\uc5d0\uc11c \ub300\uc548\uc744 \uc81c\uc2dc\ud55c\ub2e4.","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\uc81c\uc57d\uc744 \ub35c \ubc1b\ub294 \ub2e4\ub978 \ubc29\ud5a5\uc131/\ub300\uc548 \uc81c\uc2dc"}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\ubb38\uc81c\ub97c \ud574\uacb0\ud560 \ub610 \ub2e4\ub978 \ubc29\ubc95\uc740 \uc5c6\uc744\uc9c0 \uace0\ubbfc\ud574\ubcf8\ub2e4.","\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"\ub2e8\uc815\ub300\uc2e0 \ud55c \ubc88 \ub354 \uc9c8\ubb38\ud558\uace0 \uc0dd\uac01"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsx)(n.p,{children:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00 - \uc1a1\ubc94\uadfc, INFCON 2023"})]})}function u(e={}){const{wrapper:n}={...(0,i.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>a});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function c(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function l(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=r.createContext({}),a=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,c=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),p=a(t),h=i,j=p["".concat(s,".").concat(h)]||p[h]||d[h]||c;return t?r.createElement(j,l(l({ref:n},u),{},{components:t})):r.createElement(j,l({ref:n},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/04644f5f.6c9c9166.js b/assets/js/04644f5f.6c9c9166.js deleted file mode 100644 index c43fc14ae..000000000 --- a/assets/js/04644f5f.6c9c9166.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2625],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,c=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),m=p(n),d=a,f=m["".concat(c,".").concat(d)]||m[d]||s[d]||l;return n?r.createElement(f,i(i({ref:t},u),{},{components:n})):r.createElement(f,i({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,i=new Array(l);i[0]=m;var o={};for(var c in t)hasOwnProperty.call(t,c)&&(o[c]=t[c]);o.originalType=e,o.mdxType="string"==typeof e?e:a,i[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>s,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const l={title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",slug:"/etc/communication",last_update:{date:"2023/09/02"},tags:["etc"]},i=void 0,o={unversionedId:"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",id:"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",description:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?",source:"@site/docs/\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00.mdx",sourceDirName:"\uae30\ud0c0",slug:"/etc/communication",permalink:"/docs/etc/communication",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00.mdx",tags:[{label:"etc",permalink:"/docs/tags/etc"}],version:"current",lastUpdatedAt:1693612800,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 2\uc77c",frontMatter:{title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",slug:"/etc/communication",last_update:{date:"2023/09/02"},tags:["etc"]},sidebar:"tutorialSidebar",previous:{title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",permalink:"/docs/etc/experience-and-self-question"},next:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",permalink:"/docs/network/load-balancing-algorithm"}},c={},p=[{value:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?",id:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158-\uc798-\ud558\ub294-\uac1c\ubc1c\uc790",level:3},{value:"\ubcc0\ud654\ub97c \ub9cc\ub4e4\ub824\uba74 \uc2b5\uad00\uc774 \ud544\uc694\ud558\ub2e4.",id:"\ubcc0\ud654\ub97c-\ub9cc\ub4e4\ub824\uba74-\uc2b5\uad00\uc774-\ud544\uc694\ud558\ub2e4",level:3},{value:"\uc88b\uc740 \uc2b5\uad00 4\uac00\uc9c0",id:"\uc88b\uc740-\uc2b5\uad00-4\uac00\uc9c0",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:p};function s(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158-\uc798-\ud558\ub294-\uac1c\ubc1c\uc790"},"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?"),(0,a.kt)("p",null,"\uc2a4\ud399 \uad6c\ud604\ud615 \uac1c\ubc1c\uc790 vs \ubb38\uc81c \ud574\uacb0\ud615 \uac1c\ubc1c\uc790 "),(0,a.kt)("p",null,"\uac1c\ubc1c\uc790 != \uc2a4\ud399\uc744 \uc8fc\uba74 \uc798 \uad6c\ud604\ud558\ub294 \uc0ac\ub78c",(0,a.kt)("br",{parentName:"p"}),"\n","\uad6c\ud604\uc5d0 \uc9d1\uc911\ud55c\ub2e4\uba74 \uc77c\uc758 \uc2dc\uc57c\uac00 \uc881\uc544\uc9c4\ub2e4. "),(0,a.kt)("p",null,"\uc758\ub3c4\uc640 \ub9e5\ub77d\uc744 \uc774\ud574\ud574\uc11c, \ub354 \uc88b\uc740 \uc2a4\ud399\uc744 \ub9cc\ub4e4\uc5b4\ub0b4\ub824\uace0 \ud558\ub294 \uac1c\ubc1c\uc790\uac00 \ub418\uc5b4\uc57c \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ubcc0\ud654\ub97c-\ub9cc\ub4e4\ub824\uba74-\uc2b5\uad00\uc774-\ud544\uc694\ud558\ub2e4"},"\ubcc0\ud654\ub97c \ub9cc\ub4e4\ub824\uba74 \uc2b5\uad00\uc774 \ud544\uc694\ud558\ub2e4."),(0,a.kt)("p",null,"\uc8fc\ub2c8\uc5b4 \uac1c\ubc1c\uc790\ub294 \uc2a4\ud399 \uad6c\ud604 \uac1c\ubc1c\uc790\uc5d0\uc11c \uc2dc\uc791\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcc0\ud654\ub97c \uc704\ud574 \uc2e4\uc81c\ub85c \ud589\ub3d9\ud558\ub294 ",(0,a.kt)("inlineCode",{parentName:"p"},"\uc2b5\uad00"),"\uc774 \ud544\uc694\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\uc88b\uc740-\uc2b5\uad00-4\uac00\uc9c0"},"\uc88b\uc740 \uc2b5\uad00 4\uac00\uc9c0"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"\ud574\uacb0\ud558\ub824\ub294 ",(0,a.kt)("inlineCode",{parentName:"li"},"\ubb38\uc81c"),"\uc640 ",(0,a.kt)("inlineCode",{parentName:"li"},"\uc758\ub3c4/\uc0c1\ud669"),"\uc5d0 \ub300\ud574 \ubb3b\ub294\ub2e4. "),(0,a.kt)("li",{parentName:"ol"},"\uc0c1\ub300\ubc29\uc758 \ub9d0\uc744 \ub4e3\uace0 ",(0,a.kt)("inlineCode",{parentName:"li"},"\ub0b4\uac00")," \uc774\ud574\ud55c \ubc14\ub97c \uc694\uc57d\ud558\uc5ec \uacf5\uc720\ud55c\ub2e4. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"\ud55c \ubc88 \uc815\ub9ac\ud55c\ub2e4\uba74 1... 2... \uc774\ub807\uac8c \uc774\ud574\ud588\ub294\ub370 \ub9de\uc744\uae4c\uc694?"))),(0,a.kt)("li",{parentName:"ol"},"\uc548 \ub41c\ub2e4\uace0 \ub9d0\ud560 \ub54c\ub294 \uc0c1\ub300\ubc29\uc5d0 \uad00\uc810\uc5d0\uc11c \ub300\uc548\uc744 \uc81c\uc2dc\ud55c\ub2e4. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"\uc81c\uc57d\uc744 \ub35c \ubc1b\ub294 \ub2e4\ub978 \ubc29\ud5a5\uc131/\ub300\uc548 \uc81c\uc2dc"))),(0,a.kt)("li",{parentName:"ol"},"\ubb38\uc81c\ub97c \ud574\uacb0\ud560 \ub610 \ub2e4\ub978 \ubc29\ubc95\uc740 \uc5c6\uc744\uc9c0 \uace0\ubbfc\ud574\ubcf8\ub2e4. ",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"\ub2e8\uc815\ub300\uc2e0 \ud55c \ubc88 \ub354 \uc9c8\ubb38\ud558\uace0 \uc0dd\uac01")))),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00 - \uc1a1\ubc94\uadfc, INFCON 2023"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/051528db.29135bf1.js b/assets/js/051528db.29135bf1.js deleted file mode 100644 index c405a26d9..000000000 --- a/assets/js/051528db.29135bf1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5753],{3905:(t,e,a)=>{a.d(e,{Zo:()=>m,kt:()=>c});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function p(t){for(var e=1;e=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var u=n.createContext({}),o=function(t){var e=n.useContext(u),a=e;return t&&(a="function"==typeof t?t(e):p(p({},e),t)),a},m=function(t){var e=o(t.components);return n.createElement(u.Provider,{value:e},t.children)},d={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},k=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,u=t.parentName,m=i(t,["components","mdxType","originalType","parentName"]),k=o(a),c=r,s=k["".concat(u,".").concat(c)]||k[c]||d[c]||l;return a?n.createElement(s,p(p({ref:e},m),{},{components:a})):n.createElement(s,p({ref:e},m))}));function c(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,p=new Array(l);p[0]=k;var i={};for(var u in e)hasOwnProperty.call(e,u)&&(i[u]=e[u]);i.originalType=t,i.mdxType="string"==typeof t?t:r,p[1]=i;for(var o=2;o{a.r(e),a.d(e,{assets:()=>u,contentTitle:()=>p,default:()=>d,frontMatter:()=>l,metadata:()=>i,toc:()=>o});var n=a(87462),r=(a(67294),a(3905));const l={title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",slug:"/linux/shell",last_update:{date:"2023/08/01",author:"\ud5c8\ube0c"}},p=void 0,i={unversionedId:"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",id:"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",description:"\uacc4\uc815 \ubcc4 \ud130\ubbf8\ub110 \uc124\uc815",source:"@site/docs/\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815.md",sourceDirName:"\ub9ac\ub205\uc2a4",slug:"/linux/shell",permalink:"/docs/linux/shell",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815.md",tags:[],version:"current",lastUpdatedBy:"\ud5c8\ube0c",lastUpdatedAt:1690848e3,formattedLastUpdatedAt:"2023\ub144 8\uc6d4 1\uc77c",frontMatter:{title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",slug:"/linux/shell",last_update:{date:"2023/08/01",author:"\ud5c8\ube0c"}},sidebar:"tutorialSidebar",previous:{title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",permalink:"/docs/linux/swap"},next:{title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/docs/monitoring/intro"}},u={},o=[{value:"\uacc4\uc815 \ubcc4 \ud130\ubbf8\ub110 \uc124\uc815",id:"\uacc4\uc815-\ubcc4-\ud130\ubbf8\ub110-\uc124\uc815",level:3},{value:"\uc774\uc2a4\ucf00\uc774\ud504 \ubb38\uc790",id:"\uc774\uc2a4\ucf00\uc774\ud504-\ubb38\uc790",level:3},{value:"\uc0c9\uc0c1 \uc124\uc815",id:"\uc0c9\uc0c1-\uc124\uc815",level:3},{value:"\uc0c9\uc0c1\ud45c",id:"\uc0c9\uc0c1\ud45c",level:3},{value:"~/.bashrc \ud30c\uc77c\uc5d0 \uc801\uc6a9",id:"bashrc-\ud30c\uc77c\uc5d0-\uc801\uc6a9",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],m={toc:o};function d(t){let{components:e,...a}=t;return(0,r.kt)("wrapper",(0,n.Z)({},m,a,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"\uacc4\uc815-\ubcc4-\ud130\ubbf8\ub110-\uc124\uc815"},"\uacc4\uc815 \ubcc4 \ud130\ubbf8\ub110 \uc124\uc815"),(0,r.kt)("p",null,"PS1\uc740 \ub9ac\ub205\uc2a4 \uae30\ubc18 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc0ac\uc6a9\uc790\uc758 \uc258 \ud504\ub86c\ud504\ud2b8\ub97c \uc124\uc815\ud558\uae30 \uc704\ud574 \uc0ac\uc6a9\ub418\ub294 \ud658\uacbd \ubcc0\uc218\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \ud658\uacbd \ubcc0\uc218\ub97c \ubcc0\uacbd\ud558\uba74 \uc0ac\uc6a9\uc790\uba85, \uc2dc\uac04 \uc815\ubcf4 \ub4f1 \ud544\uc694\ud55c \uc815\ubcf4\ub97c \uc6d0\ud558\ub294 \ub300\ub85c \uc124\uc815\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","~/.bashrc \ud30c\uc77c\uc5d0 PS1\uc5d0 \ub300\ud55c \uac12\uc744 \uc124\uc815\ud558\uc5ec \ub3d9\uc77c\ud55c \uacc4\uc815\uc73c\ub85c \uc7ac\uc811\uc18d\ud558\uc5ec\ub3c4 \uc124\uc815\uc744 \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("h3",{id:"\uc774\uc2a4\ucf00\uc774\ud504-\ubb38\uc790"},"\uc774\uc2a4\ucf00\uc774\ud504 \ubb38\uc790"),(0,r.kt)("p",null,"\uc774\uc2a4\ucf00\uc774\ud504 \ubb38\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc258 \ud504\ub86c\ud504\ud2b8\uc5d0 \uc11c\ubc84\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \ucd94\uac00\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\uc774\uc2a4\ucf00\uc774\ud504 \ubb38\uc790"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"\\u"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc0ac\uc6a9\uc790 \uc774\ub984")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"\\h"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud638\uc2a4\ud2b8 \uc774\ub984")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"\\w"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud604\uc7ac \uc791\uc5c5 \ub514\ub809\ud1a0\ub9ac (\uc804\uccb4 \uacbd\ub85c)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"\\W"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud604\uc7ac \uc791\uc5c5 \ub514\ub809\ud1a0\ub9ac (\ub514\ub809\ud1a0\ub9ac \uc774\ub984)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"\\d"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud604\uc7ac \ub0a0\uc9dc (YYYY-MM-DD)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"\\t"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud604\uc7ac \uc2dc\uac04 (HH:MM:SS)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"\\n"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc904 \ubc14\uafc8 \ubb38\uc790")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"\\$"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc77c\ubc18 \uc0ac\uc6a9\uc790 $ root\uc758 \uacbd\uc6b0 #")))),(0,r.kt)("h3",{id:"\uc0c9\uc0c1-\uc124\uc815"},"\uc0c9\uc0c1 \uc124\uc815"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"\\e[")," - \uc0c9\uc0c1 \ubcc0\uacbd\uc744 \uc2dc\uc791\ud558\uace0 \uc2f6\uc744 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"\uc0c9\uc0c1\ucf54\ub4dcm")," - \uc0c9\uc0c1\uc744 \uc120\ud0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"\\e[0m")," - \uc0c9\uc0c1 \ubcc0\uacbd\uc744 \uc885\ub8cc\ud558\uace0 \uc2f6\uc744 \ub54c \uc0ac\uc6a9\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'\ube68\uac04\uc0c9 hello world \u2192 "\\e[31mhello world!\\e[0m"\n')),(0,r.kt)("p",null,"echo -e \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc0c9\uc0c1\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \uc801\uc6a9\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'echo -e "\\e[31mhello world! \\e[0m"\n')),(0,r.kt)("h3",{id:"\uc0c9\uc0c1\ud45c"},"\uc0c9\uc0c1\ud45c"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\uc0c9\uc0c1"),(0,r.kt)("th",{parentName:"tr",align:null},"\uae00\uc790\uc0c9"),(0,r.kt)("th",{parentName:"tr",align:null},"\ubc30\uacbd\uc0c9"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Black"),(0,r.kt)("td",{parentName:"tr",align:null},"30"),(0,r.kt)("td",{parentName:"tr",align:null},"40")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Red"),(0,r.kt)("td",{parentName:"tr",align:null},"31"),(0,r.kt)("td",{parentName:"tr",align:null},"41")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Green"),(0,r.kt)("td",{parentName:"tr",align:null},"32"),(0,r.kt)("td",{parentName:"tr",align:null},"42")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Yellow"),(0,r.kt)("td",{parentName:"tr",align:null},"33"),(0,r.kt)("td",{parentName:"tr",align:null},"43")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Blue"),(0,r.kt)("td",{parentName:"tr",align:null},"34"),(0,r.kt)("td",{parentName:"tr",align:null},"44")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Purple"),(0,r.kt)("td",{parentName:"tr",align:null},"35"),(0,r.kt)("td",{parentName:"tr",align:null},"45")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Cyan"),(0,r.kt)("td",{parentName:"tr",align:null},"36"),(0,r.kt)("td",{parentName:"tr",align:null},"46")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"White"),(0,r.kt)("td",{parentName:"tr",align:null},"37"),(0,r.kt)("td",{parentName:"tr",align:null},"47")))),(0,r.kt)("h3",{id:"bashrc-\ud30c\uc77c\uc5d0-\uc801\uc6a9"},"~/.bashrc \ud30c\uc77c\uc5d0 \uc801\uc6a9"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"sudo vim ~/.bashrc")," \uc744 \uc785\ub825\ud558\uc5ec \uc124\uc815 \ud30c\uc77c\uc744 \uc5f0 \ud6c4\uc5d0 \uc801\uc6a9\ud558\uace0 \uc2f6\uc740 \ubb38\uc790\ub97c PS1 \ud658\uacbd\ubcc0\uc218\uc5d0 \ud560\ub2f9\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title="~/.bashrc"',title:'"~/.bashrc"'},'PS1="\\e[32m[\\t TRIPDRAW-DEV \\u]\\$ \\e[0m"\n')),(0,r.kt)("p",null,"\uc801\uc6a9\uc740 source \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"source ~/.bashrc\n")),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://linuxhint.com/bash-ps1-customization/"},"Linux Hint")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/051528db.96920375.js b/assets/js/051528db.96920375.js new file mode 100644 index 000000000..b0caafb6e --- /dev/null +++ b/assets/js/051528db.96920375.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5753],{29837:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>i,contentTitle:()=>l,default:()=>o,frontMatter:()=>d,metadata:()=>c,toc:()=>h});var n=t(85893),s=t(3905);const d={title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",slug:"/linux/shell",last_update:{date:"2023/08/01",author:"\ud5c8\ube0c"}},l=void 0,c={id:"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",description:"\uacc4\uc815 \ubcc4 \ud130\ubbf8\ub110 \uc124\uc815",source:"@site/docs/\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815.md",sourceDirName:"\ub9ac\ub205\uc2a4",slug:"/linux/shell",permalink:"/docs/linux/shell",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815.md",tags:[],version:"current",lastUpdatedBy:"\ud5c8\ube0c",lastUpdatedAt:1690848e3,formattedLastUpdatedAt:"2023\ub144 8\uc6d4 1\uc77c",frontMatter:{title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",slug:"/linux/shell",last_update:{date:"2023/08/01",author:"\ud5c8\ube0c"}},sidebar:"tutorialSidebar",previous:{title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",permalink:"/docs/linux/swap"},next:{title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/docs/monitoring/intro"}},i={},h=[{value:"\uacc4\uc815 \ubcc4 \ud130\ubbf8\ub110 \uc124\uc815",id:"\uacc4\uc815-\ubcc4-\ud130\ubbf8\ub110-\uc124\uc815",level:3},{value:"\uc774\uc2a4\ucf00\uc774\ud504 \ubb38\uc790",id:"\uc774\uc2a4\ucf00\uc774\ud504-\ubb38\uc790",level:3},{value:"\uc0c9\uc0c1 \uc124\uc815",id:"\uc0c9\uc0c1-\uc124\uc815",level:3},{value:"\uc0c9\uc0c1\ud45c",id:"\uc0c9\uc0c1\ud45c",level:3},{value:"~/.bashrc \ud30c\uc77c\uc5d0 \uc801\uc6a9",id:"bashrc-\ud30c\uc77c\uc5d0-\uc801\uc6a9",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function a(e){const r={a:"a",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h3,{id:"\uacc4\uc815-\ubcc4-\ud130\ubbf8\ub110-\uc124\uc815",children:"\uacc4\uc815 \ubcc4 \ud130\ubbf8\ub110 \uc124\uc815"}),"\n",(0,n.jsxs)(r.p,{children:["PS1\uc740 \ub9ac\ub205\uc2a4 \uae30\ubc18 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc0ac\uc6a9\uc790\uc758 \uc258 \ud504\ub86c\ud504\ud2b8\ub97c \uc124\uc815\ud558\uae30 \uc704\ud574 \uc0ac\uc6a9\ub418\ub294 \ud658\uacbd \ubcc0\uc218\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud574\ub2f9 \ud658\uacbd \ubcc0\uc218\ub97c \ubcc0\uacbd\ud558\uba74 \uc0ac\uc6a9\uc790\uba85, \uc2dc\uac04 \uc815\ubcf4 \ub4f1 \ud544\uc694\ud55c \uc815\ubcf4\ub97c \uc6d0\ud558\ub294 \ub300\ub85c \uc124\uc815\ud560 \uc218 \uc788\ub2e4.",(0,n.jsx)(r.br,{}),"\n","~/.bashrc \ud30c\uc77c\uc5d0 PS1\uc5d0 \ub300\ud55c \uac12\uc744 \uc124\uc815\ud558\uc5ec \ub3d9\uc77c\ud55c \uacc4\uc815\uc73c\ub85c \uc7ac\uc811\uc18d\ud558\uc5ec\ub3c4 \uc124\uc815\uc744 \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc774\uc2a4\ucf00\uc774\ud504-\ubb38\uc790",children:"\uc774\uc2a4\ucf00\uc774\ud504 \ubb38\uc790"}),"\n",(0,n.jsx)(r.p,{children:"\uc774\uc2a4\ucf00\uc774\ud504 \ubb38\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc258 \ud504\ub86c\ud504\ud2b8\uc5d0 \uc11c\ubc84\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \ucd94\uac00\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,n.jsxs)(r.table,{children:[(0,n.jsx)(r.thead,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.th,{children:"\uc774\uc2a4\ucf00\uc774\ud504 \ubb38\uc790"}),(0,n.jsx)(r.th,{children:"\uc124\uba85"})]})}),(0,n.jsxs)(r.tbody,{children:[(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\\u"}),(0,n.jsx)(r.td,{children:"\uc0ac\uc6a9\uc790 \uc774\ub984"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\\h"}),(0,n.jsx)(r.td,{children:"\ud638\uc2a4\ud2b8 \uc774\ub984"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\\w"}),(0,n.jsx)(r.td,{children:"\ud604\uc7ac \uc791\uc5c5 \ub514\ub809\ud1a0\ub9ac (\uc804\uccb4 \uacbd\ub85c)"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\\W"}),(0,n.jsx)(r.td,{children:"\ud604\uc7ac \uc791\uc5c5 \ub514\ub809\ud1a0\ub9ac (\ub514\ub809\ud1a0\ub9ac \uc774\ub984)"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\\d"}),(0,n.jsx)(r.td,{children:"\ud604\uc7ac \ub0a0\uc9dc (YYYY-MM-DD)"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\\t"}),(0,n.jsxs)(r.td,{children:["\ud604\uc7ac \uc2dc\uac04 (HH:MM",":SS",")"]})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\\n"}),(0,n.jsx)(r.td,{children:"\uc904 \ubc14\uafc8 \ubb38\uc790"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"$"}),(0,n.jsx)(r.td,{children:"\uc77c\ubc18 \uc0ac\uc6a9\uc790 $ root\uc758 \uacbd\uc6b0 #"})]})]})]}),"\n",(0,n.jsx)(r.h3,{id:"\uc0c9\uc0c1-\uc124\uc815",children:"\uc0c9\uc0c1 \uc124\uc815"}),"\n",(0,n.jsxs)(r.p,{children:[(0,n.jsx)(r.code,{children:"\\e["})," - \uc0c9\uc0c1 \ubcc0\uacbd\uc744 \uc2dc\uc791\ud558\uace0 \uc2f6\uc744 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n",(0,n.jsx)(r.code,{children:"\uc0c9\uc0c1\ucf54\ub4dcm"})," - \uc0c9\uc0c1\uc744 \uc120\ud0dd\ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n",(0,n.jsx)(r.code,{children:"\\e[0m"})," - \uc0c9\uc0c1 \ubcc0\uacbd\uc744 \uc885\ub8cc\ud558\uace0 \uc2f6\uc744 \ub54c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",children:'\ube68\uac04\uc0c9 hello world \u2192 "\\e[31mhello world!\\e[0m"\n'})}),"\n",(0,n.jsx)(r.p,{children:"echo -e \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc0c9\uc0c1\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \uc801\uc6a9\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",children:'echo -e "\\e[31mhello world! \\e[0m"\n'})}),"\n",(0,n.jsx)(r.h3,{id:"\uc0c9\uc0c1\ud45c",children:"\uc0c9\uc0c1\ud45c"}),"\n",(0,n.jsxs)(r.table,{children:[(0,n.jsx)(r.thead,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.th,{children:"\uc0c9\uc0c1"}),(0,n.jsx)(r.th,{children:"\uae00\uc790\uc0c9"}),(0,n.jsx)(r.th,{children:"\ubc30\uacbd\uc0c9"})]})}),(0,n.jsxs)(r.tbody,{children:[(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"Black"}),(0,n.jsx)(r.td,{children:"30"}),(0,n.jsx)(r.td,{children:"40"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"Red"}),(0,n.jsx)(r.td,{children:"31"}),(0,n.jsx)(r.td,{children:"41"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"Green"}),(0,n.jsx)(r.td,{children:"32"}),(0,n.jsx)(r.td,{children:"42"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"Yellow"}),(0,n.jsx)(r.td,{children:"33"}),(0,n.jsx)(r.td,{children:"43"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"Blue"}),(0,n.jsx)(r.td,{children:"34"}),(0,n.jsx)(r.td,{children:"44"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"Purple"}),(0,n.jsx)(r.td,{children:"35"}),(0,n.jsx)(r.td,{children:"45"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"Cyan"}),(0,n.jsx)(r.td,{children:"36"}),(0,n.jsx)(r.td,{children:"46"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"White"}),(0,n.jsx)(r.td,{children:"37"}),(0,n.jsx)(r.td,{children:"47"})]})]})]}),"\n",(0,n.jsx)(r.h3,{id:"bashrc-\ud30c\uc77c\uc5d0-\uc801\uc6a9",children:"~/.bashrc \ud30c\uc77c\uc5d0 \uc801\uc6a9"}),"\n",(0,n.jsxs)(r.p,{children:[(0,n.jsx)(r.code,{children:"sudo vim ~/.bashrc"})," \uc744 \uc785\ub825\ud558\uc5ec \uc124\uc815 \ud30c\uc77c\uc744 \uc5f0 \ud6c4\uc5d0 \uc801\uc6a9\ud558\uace0 \uc2f6\uc740 \ubb38\uc790\ub97c PS1 \ud658\uacbd\ubcc0\uc218\uc5d0 \ud560\ub2f9\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",metastring:'title="~/.bashrc"',children:'PS1="\\e[32m[\\t TRIPDRAW-DEV \\u]\\$ \\e[0m"\n'})}),"\n",(0,n.jsx)(r.p,{children:"\uc801\uc6a9\uc740 source \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uba74 \ub41c\ub2e4."}),"\n",(0,n.jsx)(r.pre,{children:(0,n.jsx)(r.code,{className:"language-bash",children:"source ~/.bashrc\n"})}),"\n",(0,n.jsx)(r.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.a,{href:"https://linuxhint.com/bash-ps1-customization/",children:"Linux Hint"})})]})}function o(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(a,{...e})}):a(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>h});var n=t(67294);function s(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function d(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function l(e){for(var r=1;r=0||(s[t]=e[t]);return s}(e,r);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var i=n.createContext({}),h=function(e){var r=n.useContext(i),t=r;return e&&(t="function"==typeof e?e(r):l(l({},r),e)),t},a={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},o=n.forwardRef((function(e,r){var t=e.components,s=e.mdxType,d=e.originalType,i=e.parentName,o=c(e,["components","mdxType","originalType","parentName"]),j=h(t),x=s,u=j["".concat(i,".").concat(x)]||j[x]||a[x]||d;return t?n.createElement(u,l(l({ref:r},o),{},{components:t})):n.createElement(u,l({ref:r},o))}));o.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/0571a526.3199c893.js b/assets/js/0571a526.3199c893.js new file mode 100644 index 000000000..4db29db90 --- /dev/null +++ b/assets/js/0571a526.3199c893.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6204],{93516:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=n(85893),s=n(3905);const i={title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",slug:"performance-test-type",tags:["performance test"]},a=void 0,o={permalink:"/performance-test-type",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",source:"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",description:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8",date:"2023-09-10T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 10\uc77c",tags:[{label:"performance test",permalink:"/tags/performance-test"}],readingTime:5.8,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",slug:"performance-test-type",tags:["performance test"]},unlisted:!1,prevItem:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/tomcat-retrospective"},nextItem:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",permalink:"/db-replication"}},l={authorsImageUrls:[]},c=[{value:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8",id:"\uc131\ub2a5-\ud14c\uc2a4\ud2b8",level:2},{value:"\uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)",id:"\uc2a4\ubaa8\ud06c-\ud14c\uc2a4\ud2b8smoke-test",level:3},{value:"\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)",id:"\uc2a4\ud30c\uc774\ud06c-\ud14c\uc2a4\ud2b8spike-test",level:3},{value:"\ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)",id:"\ubd80\ud558-\ud14c\uc2a4\ud2b8load-test",level:3},{value:"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test)",id:"\uc2a4\ud2b8\ub808\uc2a4-\ud14c\uc2a4\ud2b8stress-test",level:3},{value:"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test)",id:"\ub0b4\uad6c-\ud14c\uc2a4\ud2b8endurance-test",level:3},{value:"\uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)",id:"\uc911\ub2e8\uc810-\ud14c\uc2a4\ud2b8breakpoint-test",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const t={a:"a",admonition:"admonition",br:"br",h2:"h2",h3:"h3",img:"img",p:"p",...(0,s.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"\uc131\ub2a5-\ud14c\uc2a4\ud2b8",children:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsx)(t.p,{children:"API\uc758 \uc694\uccad\uc774 \ub9ce\uc740 \uc0c1\ud669\uc5d0\uc11c \uc11c\ubc84\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2dc\uc2a4\ud15c\uc5d0 \ubd80\ud558\uac00 \uac78\ub9ac\uba74 \ubb38\uc81c \uc0c1\ud669\uc774 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\uc591\ud55c \uc0c1\ud669\uc5d0 \ub300\ube44\ud574\uc11c \uc131\ub2a5 \ud14c\uc2a4\ud2b8\ub97c \ud574\uc57c\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"./test.png",src:n(38715).Z+"",width:"2168",height:"1002"})}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ubaa8\ud06c-\ud14c\uc2a4\ud2b8smoke-test",children:"\uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)"}),"\n",(0,r.jsx)(t.p,{children:"\ucd5c\uc18c\ud55c\uc758 \ubd80\ud558\ub97c \uc8fc\uc5b4 \uc2dc\uc2a4\ud15c\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["VU\ub97c \ucd5c\uc18c\ud55c\uc73c\ub85c \ub450\uace0, \uc9e7\uc740 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \ud14c\uc2a4\ud2b8\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \uc2dc\uc791\ud558\uae30 \uc804\uc5d0 \uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud568\uc73c\ub85c\uc368 \ud14c\uc2a4\ud2b8 \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc624\ub958\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\uace0, \uc131\ub2a5 \uc9c0\ud45c\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \uc218\uc9d1, \ubaa8\ub2c8\ud130\ub9c1 \ub418\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.admonition,{title:"\uac00\uc0c1 \uc0ac\uc6a9\uc790(VU)",type:"note",children:(0,r.jsxs)(t.p,{children:["\uac00\uc0c1 \uc0ac\uc6a9\uc790\ub294 \uc11c\ubc84 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0 \ub300\ud574 \ud2b9\uc815 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub294 \ub2e4\ub978 \uac00\uc0c1 \uc0ac\uc6a9\uc790\uc640 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589\ub418\uba70, \uc5ec\ub7ec \uac00\uc0c1 \uc0ac\uc6a9\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub3d9\uc2dc \uc5f0\uacb0\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc2a4\ub808\ub4dc\ub77c\uace0 \uc0dd\uac01\ud558\uba74 \ub41c\ub2e4."]})}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ud30c\uc774\ud06c-\ud14c\uc2a4\ud2b8spike-test",children:"\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)"}),"\n",(0,r.jsx)(t.p,{children:"\uc0ac\uc6a9\ub7c9\uc774 \uae09\uc99d\ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uacac\ub514\uace0 \uc131\ub2a5\uc5d0 \ubb38\uc81c\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\ud2f0\ucf13 \ubc1c\uae09, \ud560\uc778 \ucfe0\ud3f0 \ubc1c\uae09\uacfc \uac19\uc740 \uc774\ubca4\ud2b8\ub97c \ud558\ub294 \uacbd\uc6b0 \ub300\uaddc\ubaa8 \ud2b8\ub798\ud53d\uc774 \ub4e4\uc5b4\uc628\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud574 \uae09\uc99d\ud558\ub294 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\uace0, \ubd80\ud558\ub97c \uc798 \ubc84\ud2f0\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ubd80\ud558-\ud14c\uc2a4\ud2b8load-test",children:"\ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)"}),"\n",(0,r.jsx)(t.p,{children:"\ubaa9\ud46f\uac12\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \uacac\ub51c \uc218 \uc788\uc744\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\uc77c\ubc18\uc801\uc778 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub7a8\ud504\uc5c5 \ub610\ub294 \ubb19\ud46f\uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ubd80\ud558 \uae30\uac04\ub3d9\uc548 \uc131\ub2a5\uc774 \ubb38\uc81c\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\uace0, \uc2dc\uc2a4\ud15c \ubcc0\uacbd \ud6c4\uc5d0\ub3c4 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \ub3cc\ub824 \ub3d9\uc77c\ud558\uac8c \ubaa9\ud46f\uac12\uc744 \ucc98\ub9ac\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.admonition,{title:"\ub7a8\ud504 \uc5c5(Ramp-up)",type:"note",children:(0,r.jsx)(t.p,{children:"\ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud574 \uc124\uc815\ud55c \uac00\uc0c1 \uc0ac\uc6a9\uc790 \uc218\uc5d0 \ub3c4\ub2ec\ud558\ub294 \ub370 \uac78\ub9ac\ub294 \uc2dc\uac04"})}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ud2b8\ub808\uc2a4-\ud14c\uc2a4\ud2b8stress-test",children:"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test)"}),"\n",(0,r.jsx)(t.p,{children:"\uc2dc\uc2a4\ud15c\uc758 \ucd5c\ub300\uce58\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \ubc1b\uc558\uc744 \ub54c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\uadf8\ub798\ud504\ub97c \ubd24\uc744 \ub54c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc640 \uc720\uc0ac\ud55c \ud615\ud0dc\ub85c \ubcf4\uc774\uc9c0\ub9cc, \ubd80\ud558\ub7c9\uc774 \ub2e4\ub974\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c \ud3c9\uade0\uc801\uc778 \ubaa9\ud46f\uac12 \ub300\ube44 \uc791\uac8c\ub294 50% \uc774\uc0c1, \ud544\uc694\uc758 \uacbd\uc6b0 \uadf8 \uc774\uc0c1\uc73c\ub85c \ubd80\ud558\ub97c \uc900\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub294 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c \ud6c4\uc5d0\ub9cc \uc2e4\ud589\ud574\uc57c \ud55c\ub2e4. \ubd80\ud558 \ud14c\uc2a4\ud2b8\uac00 \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\uc740 \uc0c1\ud669\uc5d0\uc11c \uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ubcd1\ubaa9 \uc9c0\uc810\uc774\ub098 \ubb38\uc81c \uc0c1\ud669\uc744 \ucc3e\uae30 \uc5b4\ub824\uc6cc\uc9c4\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub610\ud55c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \uc0ac\uc6a9\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c VU\uac12(\uc2a4\ub808\ub4dc \uc218)\ub9cc \uc218\uc815\ud558\uc5ec \uc7ac\uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ub0b4\uad6c-\ud14c\uc2a4\ud2b8endurance-test",children:"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test)"}),"\n",(0,r.jsx)(t.p,{children:"\ud3c9\uade0 \uc0ac\uc6a9\ub960\ub85c \uc77c\uc815 \ubd80\ud558\ub97c \uc9c0\uc18d\uc801\uc73c\ub85c \uc8fc\uba70 \uc2dc\uc2a4\ud15c\uc774 \ubb38\uc81c\ub418\ub294 \uc9c0\uc810\uc744 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\ud761\uc218 \ud14c\uc2a4\ud2b8(Soak Test)\ub77c\uace0\ub3c4 \ud558\uba70, \uae30\ubcf8\uc801\uc778 \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc758 \ubcc0\ud615\uc774\ub77c\uace0 \ubcfc \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc640 \ub2ec\ub9ac \uae34 \uc2dc\uac04\ub3d9\uc548 \ud14c\uc2a4\ud2b8\ub97c \ud558\ub294 \uac83\uc774 \ud2b9\uc9d5\uc774\uba70, \uba54\ubaa8\ub9ac \ub204\uc218 \ubb38\uc81c\uc640 \uac19\uc774 \uc7a5\uc2dc\uac04 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc2e4\ud589\ud560 \ub54c \uc2dc\uc2a4\ud15c\uc758 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \ubd80\ubd84\uc744 \ud655\uc778\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uc911\ub2e8\uc810-\ud14c\uc2a4\ud2b8breakpoint-test",children:"\uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)"}),"\n",(0,r.jsx)(t.p,{children:"\uc784\uacc4 \uc9c0\uc810\uc744 \ucc3e\uae30 \uc704\ud574 \ubd80\ud558\ub97c \uc810\uc9c4\uc801\uc73c\ub85c \uc99d\uac00\uc2dc\ud0a4\uba70 \uc9c4\ud589\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\ubb38\uc81c\ub418\ub294 \ubd80\ubd84\uc744 \ub354 \ube68\ub9ac \ucc3e\uae30 \uc704\ud574 \ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\uacfc\ud55c \ub2e4\uc74c\uc5d0 \uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud558\uace0, \uc774 \ub54c \uc810\uc9c4\uc801\uc73c\ub85c \ubd80\ud558\ub97c \ub298\ub824\ub098\uac00\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc131\ub2a5 \ud29c\ub2dd\uacfc \ubc18\ubcf5\ud574\uc11c \uc9c4\ud589\ud55c\ub2e4\uba74, \uc2dc\uc2a4\ud15c\uc744 \ub354\uc6b1 \ubc1c\uc804\uc2dc\ud0ac \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub9cc Auto Scaling\uc774 \uc801\uc6a9\ub41c \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd\uc5d0\uc11c\ub294 \uc9c4\ud589\ud558\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://k6.io/docs/test-types/load-test-types/",children:"Load test types, k6"}),(0,r.jsx)(t.br,{}),"\n","\uc790\ubc14 \ucd5c\uc801\ud654 - \ubca4\uc800\ubbfc J. \uc5d0\ubc88\uc2a4, \uc81c\uc784\uc2a4 \uace0\ud504, \ud06c\ub9ac\uc2a4 \ub274\ub79c\ub4dc",(0,r.jsx)(t.br,{}),"\n","\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04"]})]})}function d(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>c});var r=n(67294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),h=c(n),u=s,j=h["".concat(l,".").concat(u)]||h[u]||p[u]||i;return n?r.createElement(j,a(a({ref:t},d),{},{components:n})):r.createElement(j,a({ref:t},d))}));d.displayName="MDXCreateElement"},38715:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/test-355aba93f96ef7d6a0f3161bf6a9c25e.png"}}]); \ No newline at end of file diff --git a/assets/js/0571a526.e17175a4.js b/assets/js/0571a526.e17175a4.js deleted file mode 100644 index 5d4311f9e..000000000 --- a/assets/js/0571a526.e17175a4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6204],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>k});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),s=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=s(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),m=s(r),k=a,d=m["".concat(i,".").concat(k)]||m[k]||u[k]||p;return r?n.createElement(d,l(l({ref:t},c),{},{components:r})):n.createElement(d,l({ref:t},c))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=m;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var s=2;s{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>p,metadata:()=>o,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",slug:"performance-test-type",tags:["performance test"]},l=void 0,o={permalink:"/performance-test-type",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",source:"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",description:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8",date:"2023-09-10T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 10\uc77c",tags:[{label:"performance test",permalink:"/tags/performance-test"}],readingTime:5.8,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",slug:"performance-test-type",tags:["performance test"]},prevItem:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/tomcat-retrospective"},nextItem:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",permalink:"/db-replication"}},i={authorsImageUrls:[]},s=[{value:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8",id:"\uc131\ub2a5-\ud14c\uc2a4\ud2b8",level:2},{value:"\uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)",id:"\uc2a4\ubaa8\ud06c-\ud14c\uc2a4\ud2b8smoke-test",level:3},{value:"\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)",id:"\uc2a4\ud30c\uc774\ud06c-\ud14c\uc2a4\ud2b8spike-test",level:3},{value:"\ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)",id:"\ubd80\ud558-\ud14c\uc2a4\ud2b8load-test",level:3},{value:"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test)",id:"\uc2a4\ud2b8\ub808\uc2a4-\ud14c\uc2a4\ud2b8stress-test",level:3},{value:"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test)",id:"\ub0b4\uad6c-\ud14c\uc2a4\ud2b8endurance-test",level:3},{value:"\uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)",id:"\uc911\ub2e8\uc810-\ud14c\uc2a4\ud2b8breakpoint-test",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:s};function u(e){let{components:t,...p}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,p,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\uc131\ub2a5-\ud14c\uc2a4\ud2b8"},"\uc131\ub2a5 \ud14c\uc2a4\ud2b8"),(0,a.kt)("p",null,"API\uc758 \uc694\uccad\uc774 \ub9ce\uc740 \uc0c1\ud669\uc5d0\uc11c \uc11c\ubc84\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"),(0,a.kt)("p",null,"\uc2dc\uc2a4\ud15c\uc5d0 \ubd80\ud558\uac00 \uac78\ub9ac\uba74 \ubb38\uc81c \uc0c1\ud669\uc774 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc591\ud55c \uc0c1\ud669\uc5d0 \ub300\ube44\ud574\uc11c \uc131\ub2a5 \ud14c\uc2a4\ud2b8\ub97c \ud574\uc57c\ud55c\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./test.png",src:r(38715).Z,width:"2168",height:"1002"})),(0,a.kt)("h3",{id:"\uc2a4\ubaa8\ud06c-\ud14c\uc2a4\ud2b8smoke-test"},"\uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)"),(0,a.kt)("p",null,"\ucd5c\uc18c\ud55c\uc758 \ubd80\ud558\ub97c \uc8fc\uc5b4 \uc2dc\uc2a4\ud15c\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"VU\ub97c \ucd5c\uc18c\ud55c\uc73c\ub85c \ub450\uace0, \uc9e7\uc740 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \ud14c\uc2a4\ud2b8\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \uc2dc\uc791\ud558\uae30 \uc804\uc5d0 \uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud568\uc73c\ub85c\uc368 \ud14c\uc2a4\ud2b8 \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc624\ub958\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\uace0, \uc131\ub2a5 \uc9c0\ud45c\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \uc218\uc9d1, \ubaa8\ub2c8\ud130\ub9c1 \ub418\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("admonition",{title:"\uac00\uc0c1 \uc0ac\uc6a9\uc790(VU)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\uac00\uc0c1 \uc0ac\uc6a9\uc790\ub294 \uc11c\ubc84 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0 \ub300\ud574 \ud2b9\uc815 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 \ub2e4\ub978 \uac00\uc0c1 \uc0ac\uc6a9\uc790\uc640 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589\ub418\uba70, \uc5ec\ub7ec \uac00\uc0c1 \uc0ac\uc6a9\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub3d9\uc2dc \uc5f0\uacb0\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ub808\ub4dc\ub77c\uace0 \uc0dd\uac01\ud558\uba74 \ub41c\ub2e4. ")),(0,a.kt)("h3",{id:"\uc2a4\ud30c\uc774\ud06c-\ud14c\uc2a4\ud2b8spike-test"},"\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)"),(0,a.kt)("p",null,"\uc0ac\uc6a9\ub7c9\uc774 \uae09\uc99d\ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uacac\ub514\uace0 \uc131\ub2a5\uc5d0 \ubb38\uc81c\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"\ud2f0\ucf13 \ubc1c\uae09, \ud560\uc778 \ucfe0\ud3f0 \ubc1c\uae09\uacfc \uac19\uc740 \uc774\ubca4\ud2b8\ub97c \ud558\ub294 \uacbd\uc6b0 \ub300\uaddc\ubaa8 \ud2b8\ub798\ud53d\uc774 \ub4e4\uc5b4\uc628\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud574 \uae09\uc99d\ud558\ub294 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\uace0, \ubd80\ud558\ub97c \uc798 \ubc84\ud2f0\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\ubd80\ud558-\ud14c\uc2a4\ud2b8load-test"},"\ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)"),(0,a.kt)("p",null,"\ubaa9\ud46f\uac12\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \uacac\ub51c \uc218 \uc788\uc744\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"\uc77c\ubc18\uc801\uc778 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub7a8\ud504\uc5c5 \ub610\ub294 \ubb19\ud46f\uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ubd80\ud558 \uae30\uac04\ub3d9\uc548 \uc131\ub2a5\uc774 \ubb38\uc81c\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\uace0, \uc2dc\uc2a4\ud15c \ubcc0\uacbd \ud6c4\uc5d0\ub3c4 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \ub3cc\ub824 \ub3d9\uc77c\ud558\uac8c \ubaa9\ud46f\uac12\uc744 \ucc98\ub9ac\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("admonition",{title:"\ub7a8\ud504 \uc5c5(Ramp-up)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud574 \uc124\uc815\ud55c \uac00\uc0c1 \uc0ac\uc6a9\uc790 \uc218\uc5d0 \ub3c4\ub2ec\ud558\ub294 \ub370 \uac78\ub9ac\ub294 \uc2dc\uac04")),(0,a.kt)("h3",{id:"\uc2a4\ud2b8\ub808\uc2a4-\ud14c\uc2a4\ud2b8stress-test"},"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test)"),(0,a.kt)("p",null,"\uc2dc\uc2a4\ud15c\uc758 \ucd5c\ub300\uce58\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \ubc1b\uc558\uc744 \ub54c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"\uadf8\ub798\ud504\ub97c \ubd24\uc744 \ub54c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc640 \uc720\uc0ac\ud55c \ud615\ud0dc\ub85c \ubcf4\uc774\uc9c0\ub9cc, \ubd80\ud558\ub7c9\uc774 \ub2e4\ub974\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c \ud3c9\uade0\uc801\uc778 \ubaa9\ud46f\uac12 \ub300\ube44 \uc791\uac8c\ub294 50% \uc774\uc0c1, \ud544\uc694\uc758 \uacbd\uc6b0 \uadf8 \uc774\uc0c1\uc73c\ub85c \ubd80\ud558\ub97c \uc900\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub294 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c \ud6c4\uc5d0\ub9cc \uc2e4\ud589\ud574\uc57c \ud55c\ub2e4. \ubd80\ud558 \ud14c\uc2a4\ud2b8\uac00 \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\uc740 \uc0c1\ud669\uc5d0\uc11c \uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ubcd1\ubaa9 \uc9c0\uc810\uc774\ub098 \ubb38\uc81c \uc0c1\ud669\uc744 \ucc3e\uae30 \uc5b4\ub824\uc6cc\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \uc0ac\uc6a9\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c VU\uac12(\uc2a4\ub808\ub4dc \uc218)\ub9cc \uc218\uc815\ud558\uc5ec \uc7ac\uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. "),(0,a.kt)("h3",{id:"\ub0b4\uad6c-\ud14c\uc2a4\ud2b8endurance-test"},"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test)"),(0,a.kt)("p",null,"\ud3c9\uade0 \uc0ac\uc6a9\ub960\ub85c \uc77c\uc815 \ubd80\ud558\ub97c \uc9c0\uc18d\uc801\uc73c\ub85c \uc8fc\uba70 \uc2dc\uc2a4\ud15c\uc774 \ubb38\uc81c\ub418\ub294 \uc9c0\uc810\uc744 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"\ud761\uc218 \ud14c\uc2a4\ud2b8(Soak Test)\ub77c\uace0\ub3c4 \ud558\uba70, \uae30\ubcf8\uc801\uc778 \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc758 \ubcc0\ud615\uc774\ub77c\uace0 \ubcfc \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc640 \ub2ec\ub9ac \uae34 \uc2dc\uac04\ub3d9\uc548 \ud14c\uc2a4\ud2b8\ub97c \ud558\ub294 \uac83\uc774 \ud2b9\uc9d5\uc774\uba70, \uba54\ubaa8\ub9ac \ub204\uc218 \ubb38\uc81c\uc640 \uac19\uc774 \uc7a5\uc2dc\uac04 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc2e4\ud589\ud560 \ub54c \uc2dc\uc2a4\ud15c\uc758 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \ubd80\ubd84\uc744 \ud655\uc778\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4. "),(0,a.kt)("h3",{id:"\uc911\ub2e8\uc810-\ud14c\uc2a4\ud2b8breakpoint-test"},"\uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)"),(0,a.kt)("p",null,"\uc784\uacc4 \uc9c0\uc810\uc744 \ucc3e\uae30 \uc704\ud574 \ubd80\ud558\ub97c \uc810\uc9c4\uc801\uc73c\ub85c \uc99d\uac00\uc2dc\ud0a4\uba70 \uc9c4\ud589\ud558\ub294 \ud14c\uc2a4\ud2b8"),(0,a.kt)("p",null,"\ubb38\uc81c\ub418\ub294 \ubd80\ubd84\uc744 \ub354 \ube68\ub9ac \ucc3e\uae30 \uc704\ud574 \ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\uacfc\ud55c \ub2e4\uc74c\uc5d0 \uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud558\uace0, \uc774 \ub54c \uc810\uc9c4\uc801\uc73c\ub85c \ubd80\ud558\ub97c \ub298\ub824\ub098\uac00\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc131\ub2a5 \ud29c\ub2dd\uacfc \ubc18\ubcf5\ud574\uc11c \uc9c4\ud589\ud55c\ub2e4\uba74, \uc2dc\uc2a4\ud15c\uc744 \ub354\uc6b1 \ubc1c\uc804\uc2dc\ud0ac \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub9cc Auto Scaling\uc774 \uc801\uc6a9\ub41c \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd\uc5d0\uc11c\ub294 \uc9c4\ud589\ud558\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://k6.io/docs/test-types/load-test-types/"},"Load test types, k6"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\ubc14 \ucd5c\uc801\ud654 - \ubca4\uc800\ubbfc J. \uc5d0\ubc88\uc2a4, \uc81c\uc784\uc2a4 \uace0\ud504, \ud06c\ub9ac\uc2a4 \ub274\ub79c\ub4dc",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04"))}u.isMDXComponent=!0},38715:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/test-355aba93f96ef7d6a0f3161bf6a9c25e.png"}}]); \ No newline at end of file diff --git a/assets/js/087c46fa.efcd5e69.js b/assets/js/087c46fa.8ecf33d3.js similarity index 83% rename from assets/js/087c46fa.efcd5e69.js rename to assets/js/087c46fa.8ecf33d3.js index a2b6d5a48..1827bdc96 100644 --- a/assets/js/087c46fa.efcd5e69.js +++ b/assets/js/087c46fa.8ecf33d3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[96],{25774:e=>{e.exports=JSON.parse('{"label":"Spring Boot","permalink":"/tags/spring-boot","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[96],{25774:e=>{e.exports=JSON.parse('{"label":"Spring Boot","permalink":"/tags/spring-boot","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/08e37dbc.6c646e20.js b/assets/js/08e37dbc.6c646e20.js deleted file mode 100644 index 18d63d1ed..000000000 --- a/assets/js/08e37dbc.6c646e20.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1328],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=c(r),d=a,k=m["".concat(i,".").concat(d)]||m[d]||u[d]||o;return r?n.createElement(k,p(p({ref:t},s),{},{components:r})):n.createElement(k,p({ref:t},s))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,p=new Array(o);p[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,p[1]=l;for(var c=2;c{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",slug:"order-retrospective",tags:["Woowahan Techcourse","Retrospective"]},p=void 0,l={permalink:"/order-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4: AWS \ubc30\ud3ec",date:"2023-06-04T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 4\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.67,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",slug:"order-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",permalink:"/level2-interview-retrospective"},nextItem:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",permalink:"/tecochat-retrospective-3"}},i={authorsImageUrls:[]},c=[{value:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158",id:"\uc7a5\ubc14\uad6c\ub2c8-\uc8fc\ubb38-\ubbf8\uc158",level:3},{value:"\ubc30\ud3ec",id:"\ubc30\ud3ec",level:3},{value:"\ud611\uc5c5",id:"\ud611\uc5c5",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84",id:"\uc0c8\ub85c-\ubc30\uc6b4-\ubd80\ubd84",level:3}],s={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: AWS \ubc30\ud3ec",(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-shopping-order/pull/7"},"https://github.com/woowacourse/jwp-shopping-order/pull/7")," ")),(0,a.kt)("h3",{id:"\uc7a5\ubc14\uad6c\ub2c8-\uc8fc\ubb38-\ubbf8\uc158"},"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158"),(0,a.kt)("p",null,"\ubc30\ud3ec \ubc0f \ud611\uc5c5\uc744 \ud560 \uc218 \uc788\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9c8\ucf54, \uc6b0\uac00, \uc6b0\ucf54, \uc6b0\uc2a4 \uadf8\ub9ac\uace0 \ub098\uae4c\uc9c0 \ud569\uccd0\uc11c 5\uba85\uc774 \ud55c \ud300\uc774 \ub418\uc5c8\ub2e4. "),(0,a.kt)("h3",{id:"\ubc30\ud3ec"},"\ubc30\ud3ec"),(0,a.kt)("p",null,"\uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac AWS\ub97c \uc774\uc6a9\ud574 \ubc30\ud3ec\ub97c \ud574\uc57c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac01\uc790 \ud558\ub098\uc758 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc744 \uc218 \uc788\uc5c8\uace0, \ud300 \ubcc4\ub85c DB\ub97c \uc704\ud55c \ucd94\uac00 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc791\uc131\ud558\ub294 \uacbd\ud5d8\uc744 \ud574\ubcfc \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc2dc\uac04\uc744 \ub9ce\uc774 \ud22c\uc790\ud558\uc9c4 \uc54a\uc558\uace0, \ub2e4\uc74c\uacfc \uac19\uc774 \uac04\ub2e8\ud558\uac8c \uc791\uc131\ud588\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'echo "Start Deploy Script"\nREPOSITORY_NAME=/home/ubuntu/jwp-shopping-order\nPROJECT_NAME=jwp-shopping-order\n\necho "Change Directory"\ncd $REPOSITORY_NAME\n\necho "Git Pull"\ngit pull origin step2\n\necho "Build"\n./gradlew bootJar\n\necho "Copy, Start Server"\nmv ./build/libs/$PROJECT_NAME.jar .\n\nPID=$(pgrep -f $PROJECT_NAME)\n\nif [ -n $PID ]; then\n kill -9 $PID\n sleep 5\nfi\n\nnohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &\n')),(0,a.kt)("h3",{id:"\ud611\uc5c5"},"\ud611\uc5c5"),(0,a.kt)("p",null,"\uc77c\ub2e8 \uc6b0\uc2a4\ub791 \uc6b0\ucf54\uac00 \uba3c\uc800 \uc7a0\uc2e4\ub85c \uc640\uc918\uc11c \ub108\ubb34 \uac10\uc0ac\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc31\uc5d4\ub4dc\uac00 \uc544\ub2cc \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \ud574\ubcf4\ub294 \uccab \ud611\uc5c5\uc774\ub77c \uc57d\uac04 \ub450\uadfc\uac70\ub838\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\uc0c1\uc678\ub85c \ub300\ud654\uac00 \uc798 \ub418\uc5b4\uc11c, \ube60\ub974\uac8c \uba85\uc138\ub97c \uc815\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc5ec\ub7ec\uac00\uc9c0 \ubc29\ubc95\uc5d0 \ub300\ud55c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud574\ubcf4\uae30")),(0,a.kt)("p",null,"\ubc31\uc5d4\ub4dc\uc640 \ud14c\uc774\ube14 \uba85\uc138\ub098 \ucfe0\ud3f0 \uad6c\ud604\uc5d0 \ub300\ud574\uc11c \uc774\uc57c\uae30\ud560 \ub54c \uc7a5\ub2e8\uc5d0 \ub300\ud574 \ub9ce\uc774 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub9ce\uc774 \ub4e4\uc5ec\uc11c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud588\ub2e4\uba74 \ub354 \uc88b\uc740 \uacb0\uacfc\ubb3c\uc774 \ub098\uc624\uc9c0 \uc54a\uc558\uc744\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc120\ud0dd\uc758 \uc21c\uac04\uc5d0\uc11c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub4e4\uc5ec\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ubc30\uc6b4-\ubd80\ubd84"},"\uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"expose headers")),(0,a.kt)("p",null,"\uc6f9 \ud398\uc774\uc9c0\uc5d0\uc11c Location \ud5e4\ub354\ub97c \ubc1b\uc744 \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c ",(0,a.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header"},"\ud5c8\uc6a9 \ubaa9\ub85d\uc5d0 \uc874\uc7ac\ud558\ub294 \uc751\ub2f5\ud5e4\ub354"),"\ub9cc \ubc18\ud658\ud55c\ub2e4\ub294 \uac83\uc744 \ubaa8\ub974\uace0 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c expose headers \uc124\uc815\uc744 \ud1b5\ud574 \ud574\uacb0\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","nginx \uc124\uc815\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \ucd94\uac00\ud574 \uc8fc\uc5c8\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"add_header 'Access-Control-Expose-Headers' 'Location'\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158")," "),(0,a.kt)("p",null,"\ub2e8\uc21c \uc870\ud68c \uc694\uccad\uc5d0 \ub300\ud55c \uc131\ub2a5\uc744 \ud5a5\uc0c1\uc2dc\ucf1c\uc900\ub2e4\ub294 \uac83\uc774\ub77c\uace0 \uac04\ub2e8\ud788\ub9cc \uc54c\uace0 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0 \ucf54\uba58\ud2b8\uac00 \ub2ec\ub824\uc11c \uc870\uae08 \ub354 \uc790\uc138\ud788 \uacf5\ubd80\ud574 \ubcf4\uae30\ub85c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Transactional(readOnly = true)\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc774 \ub3d9\uc791\ud55c\ub2e4."),(0,a.kt)("p",null,"setReadOnly(true) \uc124\uc815\uc774 \ub41c Connection\uc73c\ub85c \uc5f0\uacb0\uc744 \uc2dc\ub3c4\ub97c \ud55c\ub2e4. \uc774 \uc124\uc815\uc744 \ud558\ub294 \uacbd\uc6b0 DB\ub9c8\ub2e4 \ub2e4\ub974\uac8c \ub3d9\uc791\ud55c\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"h2\uc758 Connection \uad6c\ud604\uccb4\ub294 readOnly \uc124\uc815\uc744 \ubb34\uc2dc\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 Transactional \uc801\uc6a9\ub418\uc9c0 \uc54a\ub294\ub2e4. "),(0,a.kt)("li",{parentName:"ul"},"MySQL 8.0(InnoDB \uc0ac\uc6a9 \uc2dc)\uc758 \uacbd\uc6b0 \uc77d\uae30 \uc804\uc6a9\uc73c\ub85c \uc54c\ub824\uc9c4 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158 ID\ub97c \uc124\uc815\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uc870\ud68c \uc18d\ub3c4\uac00 \ub354 \ube68\ub77c\uc9c4\ub2e4.")),(0,a.kt)("p",null,"ORM \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 prepareTransactionalConnection\ub97c \ud638\ucd9c\ud55c\ub2e4\uace0 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ud604\uc5c5\uc5d0\uc11c\ub294 \uace0\uac00\uc6a9\uc131 \ub0b4\uacb0\ud568\uc131 \ub4f1\uc744 \uc704\ud558\uc5ec \ud074\ub7ec\uc2a4\ud130\ub97c \uad6c\uc131\ud558\uc5ec \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uace0, \uc774 \uacbd\uc6b0 readOnly \uc124\uc815\uc774 \ub418\uc5b4\uc788\ub2e4\uba74 \uc77d\uae30 \uc804\uc6a9 DB\ub85c \uc9c8\uc758\uac00 \ub4e4\uc5b4\uac00\uc11c \ubd80\ud558 \ubd84\uc0b0\uc758 \ud6a8\uacfc\uac00 \uc788\ub2e4\uace0 \ud55c\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"DAO\uc5d0 ",(0,a.kt)("inlineCode",{parentName:"strong"},"@Transactional")," \uc801\uc6a9")," "),(0,a.kt)("p",null,"DAO\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \ubcf4\ub294 \uac74 \uc5b4\ub5bb\uaca0\ub0d0\uace0 \ub9ac\ubdf0\uac00 \ub2ec\ub824\uc11c \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Service \uacc4\uce35\uc5d0 \uc774\ubbf8 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \uc8fc\uace0 \uc788\uae30\uc5d0 \ud544\uc694 \uc5c6\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","DAO\ub97c \ub2e4\ub978 \uacf3\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574(\ud655\uc7a5\uc131 \uace0\ub824) ",(0,a.kt)("inlineCode",{parentName:"p"},"@Transactional"),"\uc744 \uc801\uc6a9\ud558\ub294 \uac83\ub3c4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/08e37dbc.83c072d2.js b/assets/js/08e37dbc.83c072d2.js new file mode 100644 index 000000000..5ba62e59a --- /dev/null +++ b/assets/js/08e37dbc.83c072d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1328],{95883:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>c,toc:()=>a});var t=r(85893),o=r(3905);const s={title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",slug:"order-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,c={permalink:"/order-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4: AWS \ubc30\ud3ec",date:"2023-06-04T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 4\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.67,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",slug:"order-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",permalink:"/level2-interview-retrospective"},nextItem:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",permalink:"/tecochat-retrospective-3"}},l={authorsImageUrls:[]},a=[{value:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158",id:"\uc7a5\ubc14\uad6c\ub2c8-\uc8fc\ubb38-\ubbf8\uc158",level:3},{value:"\ubc30\ud3ec",id:"\ubc30\ud3ec",level:3},{value:"\ud611\uc5c5",id:"\ud611\uc5c5",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84",id:"\uc0c8\ub85c-\ubc30\uc6b4-\ubd80\ubd84",level:3}];function p(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(n.p,{children:["1\ub2e8\uacc4: AWS \ubc30\ud3ec",(0,t.jsx)(n.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-shopping-order/pull/7",children:"https://github.com/woowacourse/jwp-shopping-order/pull/7"})]})}),"\n",(0,t.jsx)(n.h3,{id:"\uc7a5\ubc14\uad6c\ub2c8-\uc8fc\ubb38-\ubbf8\uc158",children:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158"}),"\n",(0,t.jsxs)(n.p,{children:["\ubc30\ud3ec \ubc0f \ud611\uc5c5\uc744 \ud560 \uc218 \uc788\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub9c8\ucf54, \uc6b0\uac00, \uc6b0\ucf54, \uc6b0\uc2a4 \uadf8\ub9ac\uace0 \ub098\uae4c\uc9c0 \ud569\uccd0\uc11c 5\uba85\uc774 \ud55c \ud300\uc774 \ub418\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc30\ud3ec",children:"\ubc30\ud3ec"}),"\n",(0,t.jsxs)(n.p,{children:["\uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac AWS\ub97c \uc774\uc6a9\ud574 \ubc30\ud3ec\ub97c \ud574\uc57c \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uac01\uc790 \ud558\ub098\uc758 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc744 \uc218 \uc788\uc5c8\uace0, \ud300 \ubcc4\ub85c DB\ub97c \uc704\ud55c \ucd94\uac00 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc791\uc131\ud558\ub294 \uacbd\ud5d8\uc744 \ud574\ubcfc \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc2dc\uac04\uc744 \ub9ce\uc774 \ud22c\uc790\ud558\uc9c4 \uc54a\uc558\uace0, \ub2e4\uc74c\uacfc \uac19\uc774 \uac04\ub2e8\ud558\uac8c \uc791\uc131\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "Start Deploy Script"\nREPOSITORY_NAME=/home/ubuntu/jwp-shopping-order\nPROJECT_NAME=jwp-shopping-order\n\necho "Change Directory"\ncd $REPOSITORY_NAME\n\necho "Git Pull"\ngit pull origin step2\n\necho "Build"\n./gradlew bootJar\n\necho "Copy, Start Server"\nmv ./build/libs/$PROJECT_NAME.jar .\n\nPID=$(pgrep -f $PROJECT_NAME)\n\nif [ -n $PID ]; then\n kill -9 $PID\n\tsleep 5\nfi\n\nnohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &\n'})}),"\n",(0,t.jsx)(n.h3,{id:"\ud611\uc5c5",children:"\ud611\uc5c5"}),"\n",(0,t.jsxs)(n.p,{children:["\uc77c\ub2e8 \uc6b0\uc2a4\ub791 \uc6b0\ucf54\uac00 \uba3c\uc800 \uc7a0\uc2e4\ub85c \uc640\uc918\uc11c \ub108\ubb34 \uac10\uc0ac\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc31\uc5d4\ub4dc\uac00 \uc544\ub2cc \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \ud574\ubcf4\ub294 \uccab \ud611\uc5c5\uc774\ub77c \uc57d\uac04 \ub450\uadfc\uac70\ub838\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc608\uc0c1\uc678\ub85c \ub300\ud654\uac00 \uc798 \ub418\uc5b4\uc11c, \ube60\ub974\uac8c \uba85\uc138\ub97c \uc815\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uc5ec\ub7ec\uac00\uc9c0 \ubc29\ubc95\uc5d0 \ub300\ud55c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud574\ubcf4\uae30"})}),"\n",(0,t.jsxs)(n.p,{children:["\ubc31\uc5d4\ub4dc\uc640 \ud14c\uc774\ube14 \uba85\uc138\ub098 \ucfe0\ud3f0 \uad6c\ud604\uc5d0 \ub300\ud574\uc11c \uc774\uc57c\uae30\ud560 \ub54c \uc7a5\ub2e8\uc5d0 \ub300\ud574 \ub9ce\uc774 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub9ce\uc774 \ub4e4\uc5ec\uc11c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud588\ub2e4\uba74 \ub354 \uc88b\uc740 \uacb0\uacfc\ubb3c\uc774 \ub098\uc624\uc9c0 \uc54a\uc558\uc744\uae4c?",(0,t.jsx)(n.br,{}),"\n","\uc55e\uc73c\ub85c \uc120\ud0dd\uc758 \uc21c\uac04\uc5d0\uc11c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub4e4\uc5ec\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc0c8\ub85c-\ubc30\uc6b4-\ubd80\ubd84",children:"\uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"expose headers"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc6f9 \ud398\uc774\uc9c0\uc5d0\uc11c Location \ud5e4\ub354\ub97c \ubc1b\uc744 \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c ",(0,t.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header",children:"\ud5c8\uc6a9 \ubaa9\ub85d\uc5d0 \uc874\uc7ac\ud558\ub294 \uc751\ub2f5\ud5e4\ub354"}),"\ub9cc \ubc18\ud658\ud55c\ub2e4\ub294 \uac83\uc744 \ubaa8\ub974\uace0 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub97c expose headers \uc124\uc815\uc744 \ud1b5\ud574 \ud574\uacb0\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","nginx \uc124\uc815\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \ucd94\uac00\ud574 \uc8fc\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"add_header 'Access-Control-Expose-Headers' 'Location'\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158"})}),"\n",(0,t.jsxs)(n.p,{children:["\ub2e8\uc21c \uc870\ud68c \uc694\uccad\uc5d0 \ub300\ud55c \uc131\ub2a5\uc744 \ud5a5\uc0c1\uc2dc\ucf1c\uc900\ub2e4\ub294 \uac83\uc774\ub77c\uace0 \uac04\ub2e8\ud788\ub9cc \uc54c\uace0 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ubc88\uc5d0 \ucf54\uba58\ud2b8\uac00 \ub2ec\ub824\uc11c \uc870\uae08 \ub354 \uc790\uc138\ud788 \uacf5\ubd80\ud574 \ubcf4\uae30\ub85c \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Transactional(readOnly = true)\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc774 \ub3d9\uc791\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:"setReadOnly(true) \uc124\uc815\uc774 \ub41c Connection\uc73c\ub85c \uc5f0\uacb0\uc744 \uc2dc\ub3c4\ub97c \ud55c\ub2e4. \uc774 \uc124\uc815\uc744 \ud558\ub294 \uacbd\uc6b0 DB\ub9c8\ub2e4 \ub2e4\ub974\uac8c \ub3d9\uc791\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"h2\uc758 Connection \uad6c\ud604\uccb4\ub294 readOnly \uc124\uc815\uc744 \ubb34\uc2dc\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 Transactional \uc801\uc6a9\ub418\uc9c0 \uc54a\ub294\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"MySQL 8.0(InnoDB \uc0ac\uc6a9 \uc2dc)\uc758 \uacbd\uc6b0 \uc77d\uae30 \uc804\uc6a9\uc73c\ub85c \uc54c\ub824\uc9c4 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158 ID\ub97c \uc124\uc815\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uc870\ud68c \uc18d\ub3c4\uac00 \ub354 \ube68\ub77c\uc9c4\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["ORM \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 prepareTransactionalConnection\ub97c \ud638\ucd9c\ud55c\ub2e4\uace0 \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ud604\uc5c5\uc5d0\uc11c\ub294 \uace0\uac00\uc6a9\uc131 \ub0b4\uacb0\ud568\uc131 \ub4f1\uc744 \uc704\ud558\uc5ec \ud074\ub7ec\uc2a4\ud130\ub97c \uad6c\uc131\ud558\uc5ec \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uace0, \uc774 \uacbd\uc6b0 readOnly \uc124\uc815\uc774 \ub418\uc5b4\uc788\ub2e4\uba74 \uc77d\uae30 \uc804\uc6a9 DB\ub85c \uc9c8\uc758\uac00 \ub4e4\uc5b4\uac00\uc11c \ubd80\ud558 \ubd84\uc0b0\uc758 \ud6a8\uacfc\uac00 \uc788\ub2e4\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsxs)(n.strong,{children:["DAO\uc5d0 ",(0,t.jsx)(n.code,{children:"@Transactional"})," \uc801\uc6a9"]})}),"\n",(0,t.jsxs)(n.p,{children:["DAO\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \ubcf4\ub294 \uac74 \uc5b4\ub5bb\uaca0\ub0d0\uace0 \ub9ac\ubdf0\uac00 \ub2ec\ub824\uc11c \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Service \uacc4\uce35\uc5d0 \uc774\ubbf8 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \uc8fc\uace0 \uc788\uae30\uc5d0 \ud544\uc694 \uc5c6\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","DAO\ub97c \ub2e4\ub978 \uacf3\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574(\ud655\uc7a5\uc131 \uace0\ub824) ",(0,t.jsx)(n.code,{children:"@Transactional"}),"\uc744 \uc801\uc6a9\ud558\ub294 \uac83\ub3c4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4."]})]})}function d(e={}){const{wrapper:n}={...(0,o.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=t.createContext({}),a=function(e){var n=t.useContext(l),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),h=a(r),u=o,j=h["".concat(l,".").concat(u)]||h[u]||p[u]||s;return r?t.createElement(j,i(i({ref:n},d),{},{components:r})):t.createElement(j,i({ref:n},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/0a2eaa84.338d4c36.js b/assets/js/0a2eaa84.93ab101b.js similarity index 84% rename from assets/js/0a2eaa84.338d4c36.js rename to assets/js/0a2eaa84.93ab101b.js index abfd1f6c2..0fb10f4e0 100644 --- a/assets/js/0a2eaa84.338d4c36.js +++ b/assets/js/0a2eaa84.93ab101b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8942],{52930:a=>{a.exports=JSON.parse('{"label":"DataBase","permalink":"/tags/data-base","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8942],{52930:a=>{a.exports=JSON.parse('{"label":"DataBase","permalink":"/tags/data-base","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/0c390f0d.d414135a.js b/assets/js/0c390f0d.a2395ac7.js similarity index 81% rename from assets/js/0c390f0d.d414135a.js rename to assets/js/0c390f0d.a2395ac7.js index 96c356bb1..596bf046b 100644 --- a/assets/js/0c390f0d.d414135a.js +++ b/assets/js/0c390f0d.a2395ac7.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6550],{13321:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6550],{13321:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/0cb009d1.ddadf169.js b/assets/js/0cb009d1.553227fe.js similarity index 87% rename from assets/js/0cb009d1.ddadf169.js rename to assets/js/0cb009d1.553227fe.js index 683b11c36..ce022763d 100644 --- a/assets/js/0cb009d1.ddadf169.js +++ b/assets/js/0cb009d1.553227fe.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[116],{66643:e=>{e.exports=JSON.parse('{"label":"event","permalink":"/tags/event","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[116],{66643:e=>{e.exports=JSON.parse('{"label":"event","permalink":"/tags/event","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/0e33a907.8661cb3c.js b/assets/js/0e33a907.8661cb3c.js new file mode 100644 index 000000000..8baae3e45 --- /dev/null +++ b/assets/js/0e33a907.8661cb3c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3092],{33520:(A,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>s,default:()=>o,frontMatter:()=>I,metadata:()=>j,toc:()=>w});var r=n(85893),t=n(3905),E=n(17779);const I={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",slug:"woowacourse-level3-retrospective",tags:["Woowahan Techcourse","Retrospective"]},s=void 0,j={permalink:"/woowacourse-level3-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",source:"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",description:"\ud68c\uace0",date:"2023-08-19T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 19\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.945,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",slug:"woowacourse-level3-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",permalink:"/db-replication"},nextItem:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/cloudwatch"}},c={authorsImageUrls:[]},w=[{value:"\ud68c\uace0",id:"\ud68c\uace0",level:3},{value:"\uc544\uc26c\uc6b4 \uc810",id:"\uc544\uc26c\uc6b4-\uc810",level:3},{value:"\uc88b\uc558\ub358 \uc810",id:"\uc88b\uc558\ub358-\uc810",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3}];function l(A){const e={a:"a",br:"br",h3:"h3",p:"p",strong:"strong",...(0,t.ah)(),...A.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h3,{id:"\ud68c\uace0",children:"\ud68c\uace0"}),"\n",(0,r.jsxs)(e.p,{children:["\uc9c0\ub09c 8\uc8fc\ub294 \ub808\ubca8 1, 2 \ub54c\ubcf4\ub2e4 5\ubc30 \uc815\ub3c4 \ube60\ub974\uac8c \uc9c0\ub098\uac04 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub808\ubca8 3\uc5d0\ub294 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4, \uae30\uc220 \uc678\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4 \ubd80\uc871\ud568\uc774 \ub9ce\uc774 \ubcf4\uc600\ub358 \uac83 \uac19\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ubd80\uc871\ud55c \ubd80\ubd84\uc744 \uc54c\uc558\uae30\uc5d0, \uc55e\uc73c\ub85c \ub354\uc6b1 \uc131\uc7a5\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub0b4\uac00 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \ud300\uc6d0\ub4e4\uc774 \uc798 \ubcf4\ucda9\ud574 \uc918\uc11c \ub4e0\ub4e0\ud588\ub2e4."]}),"\n",(0,r.jsx)(e.h3,{id:"\uc544\uc26c\uc6b4-\uc810",children:"\uc544\uc26c\uc6b4 \uc810"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\ubb38\uc11c\ud654"})}),"\n",(0,r.jsxs)(e.p,{children:["\uac1c\uc778\uc801\uc73c\ub85c\ub294 \uae30\uc220 \uc678\uc801\uc73c\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ub0b4\uac00 \ud55c \ubd80\ubd84\uc744 \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c, \uc774\ud574\ud558\uae30 \uc27d\uac8c \ubb38\uc11c\ud654\ub97c \ud588\ub354\ub77c\uba74 \ud300\uc6d0\ub4e4\uc5d0\uac8c \ub354\uc6b1 \ub3c4\uc6c0\uc774 \ub418\uc5c8\uc744 \ud150\ub370 \uc774 \ubd80\ubd84\uc5d0 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ud22c\uc790\ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc5d0\uc11c \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ubc29\ud559 \uae30\uac04 \ub3d9\uc548 \ubb38\uc11c\ud654\ub97c \ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc778 \ube14\ub85c\uadf8 \uc62c\ub9ac\uba74\uc11c \uc870\uae08 \ub354 \ucc44\uc6cc\ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\ub0b4\uac00 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc774\uc790"})}),"\n",(0,r.jsxs)(e.p,{children:["\uc798 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc5ec\uc11c\ub77c\ub3c4 \uc911\uac04\uc740 \uac00\ub3c4\ub85d \ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub9d0\uc744 \ud558\uae30 \uc804\uc5d0 \uc815\ub9ac\ud574\uc11c \uc758\uacac\uc744 \ub0b4\ub294 \uac83, \ubc1c\ud45c \uc900\ube44, \uac10\uc815 \uc870\uc808 \ub4f1\ub4f1\n\ubabb\ud558\ub294 \ubd80\ubd84\uc744 \uc778\uc9c0\ud558\uace0, \uac1c\uc120\ud558\uc790."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\ucef4\ud3ec\ud2b8 \uc874 \ubc97\uc5b4\ub098\uae30"})}),"\n",(0,r.jsxs)(e.p,{children:["\uc870\uae08 \ub354 \ub3c4\uc804\uc801\uc73c\ub85c \ubaa9\ud45c\ub97c \uc7a1\uc558\uc73c\uba74 \uc88b\uc558\uc744 \uac83 \uac19\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub9e4\ubc88 \uadfc\uac70\ub97c \uac00\uc9c0\uace0 \uae30\uc220\uc744 \ub3c4\uc785\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ud558\uc9c0\ub9cc \uc9c0\uc18d\uc801\uc73c\ub85c \uac1c\uc120\ud558\ub824\uace0 \ud558\ub294 \ubd80\ubd84\uc774 \ub2e4\uc18c \ubd80\uc871\ud588\ub2e4."]}),"\n",(0,r.jsx)(e.h3,{id:"\uc88b\uc558\ub358-\uc810",children:"\uc88b\uc558\ub358 \uc810"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\uc88b\uc558\ub358 \uc810\ub3c4 \ubb38\uc11c\ud654"})}),"\n",(0,r.jsxs)(e.p,{children:[(0,r.jsx)(e.a,{href:"https://tripdraw.blog",children:"\ud300 \ube14\ub85c\uadf8"}),"\ub3c4 \uba3c\uc800 \ub3c4\uc785\ud558\uc790\uace0 \uc81c\uc548\ud558\uace0, \ub0b4\uac00 \ud588\ub358 \ubd80\ubd84\uc740 \ubb38\uc11c\ud654\ub97c \uaf64 \ub9ce\uc774 \ud574\uc11c \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ubc31\uc5d4\ub4dc \ud06c\ub8e8 4\uba85\uc774\uc11c \uac19\uc774 \ud55c \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c\ub294 \uae30\ub2a5 \uad6c\ud604\ud55c\ub2e4\uace0 \ubb38\uc11c\ud654\uac00 \uc870\uae08 \ubbf8\ud761\ud574\uc11c \ubcf4\ucda9\uc744 \ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\ub0b4\uac00 \ub514\uc790\uc778\ud55c \ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0"})}),"\n",(0,r.jsx)("img",{src:E.Z,width:"100"}),"\n",(0,r.jsxs)(e.p,{children:["\ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ud300\uc6d0\ub4e4\uc774 \ub300\ud45c \uc0c9\uc0c1(\ud30c\ub780\uc0c9)\uc744 \uc815\ud574\uc92c\uace0, \uc8fc\ub9d0 \ub3d9\uc548 \uc2e0\ub098\uac8c \ub85c\uace0 \ub514\uc790\uc778\uc744 \ud588\ub358 \uac83 \uac19\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\uc544\ub798\uc758 D \ubd80\ubd84\uc740 \uc720\ud29c\ube0c \uac15\uc758 \ub4e4\uc73c\uba74\uc11c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\uc11c \ubfcc\ub4ef\ud558\ub2e4."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\uae30\uc220 \uc120\ud0dd\uc758 \uc774\uc720"})}),"\n",(0,r.jsxs)(e.p,{children:["\uae30\uc220\uc758 \ud559\uc2b5 \ube44\uc6a9, \ud604\uc7ac \uad6c\uc870\uc5d0 \uc801\ud569\ud55c\uc9c0, \uc2e4\uc81c \uac00\uc9c0\uace0 \uc788\ub294 \ub9ac\uc18c\uc2a4\ub97c \uace0\ub824\ud574\uc11c \uae30\uc220 \uc120\ud0dd\uc744 \ud558\uace0, \ub3c4\uc785\ud588\ub358 \ubd80\ubd84\uc774 \uc88b\uc558\ub2e4.",(0,r.jsx)(e.br,{}),"\n","100% \uc88b\uc740 \uc120\ud0dd\uc77c \uc21c \uc5c6\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \uc120\ud0dd\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \uc874\uc7ac\ud55c\ub2e4\uba74 \ud655\ub960\uc744 \ub192\ud600\uc8fc\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsx)(e.h3,{id:"\ub9c8\uce58\uba70",children:"\ub9c8\uce58\uba70"}),"\n",(0,r.jsxs)(e.p,{children:["\ud50c\ub808\uc774\uc2a4\ud1a0\uc5b4\uc5d0 \uc571\uc774 \uc62c\ub77c\uac00 \uc788\ub294 \uac70 \ub108\ubb34 \uc2e0\uae30\ud558\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\uc548\ub4dc\ub85c\uc774\ub4dc \ube0c\ub808\uba58 \uc74c\uc545\ub300(\uba67\ub3fc\uc9c0, \uc218\ub2ec, \ud551\uad6c), \uadf8\ub9ac\uace0 \ubc31\uc5d4\ub4dc \ud300\uc6d0\ub4e4(\uccb4\uc778\uc800, \ud6c4\ucd94, \ub9ac\uc624) \ub108\ubb34 \uace0\uc0dd\uc774 \ub9ce\uc558\ub2e4."]})]})}function o(A={}){const{wrapper:e}={...(0,t.ah)(),...A.components};return e?(0,r.jsx)(e,{...A,children:(0,r.jsx)(l,{...A})}):l(A)}},3905:(A,e,n)=>{n.d(e,{ah:()=>c});var r=n(67294);function t(A,e,n){return e in A?Object.defineProperty(A,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):A[e]=n,A}function E(A,e){var n=Object.keys(A);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(A);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(A,e).enumerable}))),n.push.apply(n,r)}return n}function I(A){for(var e=1;e=0||(t[n]=A[n]);return t}(A,e);if(Object.getOwnPropertySymbols){var E=Object.getOwnPropertySymbols(A);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(A,n)&&(t[n]=A[n])}return t}var j=r.createContext({}),c=function(A){var e=r.useContext(j),n=e;return A&&(n="function"==typeof A?A(e):I(I({},e),A)),n},w={inlineCode:"code",wrapper:function(A){var e=A.children;return r.createElement(r.Fragment,{},e)}},l=r.forwardRef((function(A,e){var n=A.components,t=A.mdxType,E=A.originalType,j=A.parentName,l=s(A,["components","mdxType","originalType","parentName"]),o=c(n),i=t,h=o["".concat(j,".").concat(i)]||o[i]||w[i]||E;return n?r.createElement(h,I(I({ref:e},l),{},{components:n})):r.createElement(h,I({ref:e},l))}));l.displayName="MDXCreateElement"},17779:(A,e,n)=>{n.d(e,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAGwCAYAAADITjAqAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAABauSURBVHgB7d1viF3lncDx59yJsZpWU6wxoqmjLthGS2vBP4u7dEqb7FIXVKIFX9Qa3xTqiyisfWeNyEKphWZgLesbxyqLi4m0wiprXHCWIlUD1bKaRljt1CjGfzSmjdaYzNn73Dg2f5wkk8w95/nd+/nANCaZ0HHM3O/8nuc551SpRYvHJhYvXLhgrJquR+sqfblK9WiqqtGPfns0AdC6uk7bq6qaSvX09jpVU52q/kOanp78y+703PbJ1dtTS6rUoI+DVU2Ppbq6IokUQHRT3QFksvua/vCuXbsnmwxaIwFb+s2JsbozsqZb8W680uIEwEDqxuzeHLM3N37nl6nP+hawj6atNd3Z8ybRAhg6U1Wdbk8f7pncNrl6KvXBvAdMuADYx1R33+ze7kR2e5pn8xqwpSvuu747Pt6W7G0BsL/eRLbt8evuTfNkXgK2dGxitD5uwUSq6rEEALP7ZbVrz83zsazYScfotBX3r5k+buRZ8QLgCFxZLxx5Nq/YpWN01BNY3us6fuFIXi68KQHAXFVp3RuPXXdzOkpHFbDekuHCkXxE8ssJAI5a9Vy1a/dVR7OkOOeAfRSvJ5KDGgDMj6nuvtjX5xqxOQVMvADokzlH7IgDJl4A9NmcInZEARMvABpyxBE7omP0Hx3YGE0A0F/dgWnBL/JJ98O942EDdtrK+36anDYEoDH1V44/vneZ1iGNHOo3exeaVelHCQCademn/+aqd3e+9IunZnuHWffA8r5XvsOGG/IC0JLt3f2wC2fbD5t1CbG77/VT8QKgRYvr4zsTs/3mJwbso3tUXZkAoE11NTbbfRM7n/z+6bCbZwDQhNykTzqVeFDAlqy83/O8ACjJ6KcWdg66cfx+hzhcsAxAobZ/sGvP2dsnV2+f+YX9J7DjRsaSeAFQnsUHTmH7BczeFwClqlO1Zt+ffxywJd+4P586HE0AUKbFS785MTbzk79OYCPTjs0DULS6M/LxFNY7xJGPJx6/cOSPCQDK9vFhjt4EtnBkwVgCgPItPmHh3mbtXUK0fAhAENNVGss/9gJWpeprCQAiqOsr8g+V/S8Aounug32286kF6SsJAALJ+2Cd1OmMJQAIZLqqR/Me2GgCgECqlL7cqevOWQkAAqmnuxNYnTx1GYBgqiovIdajCQCC6VSVCQyAcEY7CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQlqQAPrkzCUnpi+edXI6adFx3X8+IZ104nHp5EULP/F93925K+1478P0p50fps1TO9KO3o/vJpiNgLUkf0FfPbYsrbjo9HTmqSf2vtCJ49U33+u9uD6+6fW0YXJrIqVLz/9cWj56Uvdtcbpk+Snz9nc6f57z5/vpzW/3wvbUC28nyKrTVt5XJxqVv7AfWHtZL1zEl19gv3fnM70X2WGS/x6vvGhp75uw5aN7p6ym5Ijlbx42bto2dJ93/krAGiZegym/oF679sk06PLf31VfW9ZdPfh8MasG+RuIiUdeSk9tfkfMhowlxIb1llbEa+Dk5bM8jeSJYNDsu9yd/z1Lk6e/O2/8au+fNz6zd0k3T2cMPgFr2DVjZyUG06ruVDJIAcvhWv2tc9INl5/b6PLgsVh58em9t1ffei+NP7jF/uSAE7CGfbG7yc1gWn72yWkQ5KXBNdec11smjCqvcuSpbM23vyBkA8weWMN+v/6KxOA6+5qHU1SDEK7Z5InslruedYJxwJjAYMhFXCqcqzyR5cNTeRIbX7/FYY8BIWAwxFaNLUs/vP5LAxuuA+XDKJeef4plxQEhYDCE8nLhnd+/sMhThf02sz92yfmnmsaCcy9EGDJ5qfCRH48NZbz2laex3jWZ7oITloDBkMjLhLdef0HvbViWDA8nT2O/umtFbw+QeCwhwhDIU8bdt1zcu+iXg/1w9d59wPH1LybiMIHBgMvRyktl4nVoN337C929sQsTcZjAYIDNxMuS4ZHJ18DlR77ka8byo10omwkMBpR4HZ18K6oHbr+sFzLKJmAwgMTr2OTP362rL0iUTcBgwMw8ske8jk1eTrQnVjYBgwEiXvMrRyzfH5IyCRgMiBwtD0udf/l04iDe4HgQCBgMiHyBsnj1R/7cugyhPAIGA+Cma0wJ/ZSn27t/cLGTiYURMAiu9xyvb9un6bc83eYHZFIOAYPg8r4Xzbjh8nPSiotOT5RBwCCwvHRo36tZP7nxQkuJhRAwCMrSYTvyfpilxDIIGARl6bA9eSlx2J+nVgIBg4DyQyktHbbLBc7tEzAIJi8drr7cAxjblicwU1i7BAyCyd/5m77K4F6J7RIwCCRPXy5YLkf+RuLqsWWJdggYBGLfpTyrfEPRGgGDebJjZ3+f4Gv6KpO9sPYIWMNefeu9xGDq939b01e5/Ldpx4JEozZPvWsDfkBtntqR+iXy9JUn0xz3P+3cvd+vf2bRgoG5w3uewPLdOXa8198pnP0JWMMemtyaVrqX2kAaf3BL6pdI3+HnYG2YfCU9vfmd3jdsr7556Mk0RywHIH9dXHL+KSmq1f90TvfvwIuJ5lSnrbyvTjTqP9b+XegvVA52zyMvpTvufT71Q56+fnXXilS6p154O42vf7H349HKqxM5ZvkWWdFWKvKU+ffffzzRnJFPn3vV2kSj8hd4vp+aB+TFl6eNf3v4/9KP/31z6pcVFy1NKy8ud2rfuGlbuv5ffp0mHn35mPcB8xJcntomHnk5vfbW+2n52Sf3vlYiyB9nnjrtczfHBNai/B1m/gL94uhJadmpi1IbzlhyQrp0ecwTVE9tfju99ub7qQ1b39rZXRp7Pz3+zOt93/f41c9WFDmN5BfqW+569pgmrsPZ+wyu88Ls/61bv8UyYoPsgbUovwDkt43dF8G2rBpbFjZgG554pbenOMjyclqJ8cp7XHdMPN/3eM9E8ndTO9Kt11+QSpe/lsaTgDXFMXoo2KoC7/KQp4wclSZP3OU9xstvmez7tXbHauY0Is0QMChUiUfn21wiy3tj1659sviIrbh4aaIZAgaFumR5WSdVS9jfyRH73p3PpJI5nNUcAYNCXTN2VipFXsIr5XBCPjTSr0sW5kPJJ0YHjYBBgfLyYSnXCuaDFKUFIwf16RfeSSXKh27sgzVDwKBAJd2t5drbnkwl+ue7flPsflj+BoT+EzAoUCkBy/tepV6Ymz+ufPF0ifK1nfSfgEFhSlk+zIF46Imyr7PLS4klTmEOcjRDwKAwpZw+zIc2Sr8tUo5XiVOYJ040Q8CgMKWcPuznLaLmU57CSmMPrBkCBgXJN4QtYflww+TWMDelzVNYaScSTWDNEDAoSCl7J4+3eH/Oo5Fv7FySKHfQj07AoCCl3IZo46ZgAStwudMU1n8CBgUp4ckAUfa+9pVvMcXwETAoRN74L2EJMWIM8j6YB0kOHwGDQpRy8WvUELT1cNPZOInYfwIGhSjl7hv54ZER5adkM1wEDArh7g0wNwIGBcjHrksJ2Ktv2ksiBgGDApi+jt2yUxelkvhGoP8EDApQyrO/MocPiELAoAB/u/zUVIqoD2Ms7REmjvX3n4BBAUp68T1jyQkpmjw1un3T8BEwaFlpL74R9+NMX8NJwKBlpb34Xnp++7ezmqtSrqGb4QBHMwQMWlbaxJNvQhttH6y06JrAmiFg0LISl+xWfX1ZiiLHq7Q7vwtYMwQMWlbiYzdKW5I7lFVj5cX2d7+PeTuuaAQMWlbiBJanmgh7YfkAzNVjn0+lMYE1Q8CgRcvPLvfE35przkulK/Vj9HyyZggYtOiMU8u95qr0KSxPriVOXxEfCBqVgEGLSr/mquQp7O4fXJxKZPpqjoBBi0oPWJ7AVn/rnFSaW6+/oMjDL9nTL7yTaIaAQYtOPnFhKt0PV3+pqKXEGy4/t/dWKhNYcwQMWlTaXThmc/ctFxdxl/q855Wnr1LleDmB2BwBg5bk+x9GuQFt/jgfWHtZqxHL8brzxgtTyRzgaJaAQUuiPXcr7znliLWxb5eXDEuPV/b4pm2J5ggYtCTic7dyxB65c6yxgx158rvz+xcWvWw4Iy8dmsCatSABrYj42JIZ+WDH8rMXp/H1W/p25/V8cCRPXaWeNjzQU04fNk7AoCWfWRT7y+/qsWW9t3seeSlNPPryvIUshytffxbtsS7jD25JNEvAoCWRJ7B9zRxr3zC5NT00+cpRLaPlpcIcwxUXnR7yeWT539npw+YJGLQkwjVgczEzke3Y+WHvBf3pzW+nzVM7ej/f8d6H+71vXhY8o/u2fPSkXrCix3x8/YuJ5gkYtCT6EuJs8jS18uLTe2/DwOGN9jiFCC2JcjiBQxt/0PTVFgGDFkS6iJnZ5elrQ3ffj3YIGLQg4jVgHOyWu55NtEfAoAXR7sLBwfKpS3tf7RIwgDnKJytd99U+AYMWlPwkZg7vnkdfct1XAQQMWmAJMa4cLicPyyBgAEcoLx1ee9uTiTIIGLTANWAx5TtuWDosh4ABHIF80+L8RjkEDFqw7NRFiTjse5VJwAAOIccr73sdeENi2idg0IJBvZHvIPrej5+x71UoAYMWuA9iDLf87Nm0eerdRJkEDOATrFu/JW14wo16SyZg0ALH6MuW4+XQRvkEDGAf4hWHgAF8RLxiETCAJF4ROcsLDbP/VZ477n3eXTYCEjBgaOWb8+anKm/c9HoiHgEDhlK+ODlfpOw6r7gEDBg6OVrusBGfgAFDZcPkK+mOiefd23AACBgwNBzWGCwCBgy8vFSYD2s89cLbicEhYMBA27hpW7rlX39jyXAACRg07MwlrgNrQj4iP77+RUuGA0zAoGEmgf7LS4V5ydApw8EmYNCwHX8WsH7KU9e6B7ckBp+AAQPB1DV8BAwIzV7X8BIwIKx8wvCOif81dQ0pAQPCcV0XmYABYeTlwolHX3ZIgx4BA0LIe1z5gZMuQ2CGgAFFc7qQ2QgYNMwL8ZHJ4cqnC+1zMRsBA4oiXBwpAQOKIFzMlYABrRIujpaAQQvyPtiZpw73XemFi2MlYECjNkxuTQ9NviJcHDMBA/pu5gLke/7zJddxMW8EDFrw2pvvD8US4uapd7vT1ta04YlXhIt5J2DAvLO/RRMEDFqw9a2d6ZJ0ShoklglpmoABx8S0RVsEDFoQfULJe1uPb9pm2qJVAgYtyMtt0eSPecPkK71wmbYogYBBC/60c3eKIEcrT1t5iXDz7981bVEUAYMWvLtzVypZnrDypOX4OyUTMGhBiVEQLaIRMGjBa2+9n9o2szwoWkQlYNCCHX9uJxY5WjlYv87T1jOvixahCRhhlTDFHK18N/qm7kj/6pvvpY2bXnd6kIEjYEPu6RfeSVHlU3GR5XsErrnmvDTf9l0azOHKAYNBJGBDLk8B+QXvpEXHpUjyJBF9+eueR15Kq8aWzcsUloM1cwjDcXeGhYDRu8bn1usvSJHk6SW6/I3Dtbc9mR64/bI5R2xmWXDz1A57WQyt6rSV99WJoXfr6gvSDd86N0Wwbv2WNP7gi2lQ5Hj95MavpkvOn/3mvjlYT29+p3f44unNb1sWhCRg7OPS8z/XW9JaPnpy70W1lGXFPKnkpc6ZJbJBPYiQP/8rLlqali1Z1Pv51jd3mrDgEAQMgJA6CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAELKAZtKABDLdhMYAAFVU51UV1MJACKpp7d3qmr6DwkAAqk63Qmsnq6eSwAQSV3/oVNbQgQgmunpyc6uPbsnEwAE8pfd6bnO9snV25Oj9ABEUaWp3K69x+jr+uEEAAFUKU3mH3sBq6c7kwkAAqjqqjd09QKW98HqOm1PAFC493ftPbvRC1heS6yq+n8SABSsqtK9H53d+OvNfKvp6XUJAAo2s3zY++d9f2PJivv+2K3b4gQApanS1BuPXXf2zE/3u5lvp6rHEwAUqJpOt+/78/0C9pdd0+sc5gCgON3pK43smdz3l/YLWO/CMFMYAIWp6vrn2/5r9dS+v3bQ88DyFNYrHQCUoNukbRu/u/bAXz4oYL0j9QesMwJAW2ZrUjXbHzjtH+5/ItX1WAKA1lS/fGPjd676pN/pzPpHqt2rHegAoC11d1Gw6uy+ebbfnzVgebOsqi0lAtCOTp1uPvDgxr5GDvWHd778i6c+fc6Vn+2OY5cmAGhKVY2/sfG6Hx3qXTrpMD74cHptnarnEgA047dvPPadmw73TocNWO/asM7uqxytB6Dvuq2pOnuuPLJ3PUJL/3FitK5Hnujuqo0mAJhvOV7Vnq8fat9r/3efAxEDoC/mGK+9f2SORAyAeXUU8coOuwd2oN7x+u7/kYMdAMyD3x5NvLI5T2D7Om3Fz9elqlqTAGCuqmr8gw92r515wvKc/3g6RktX3Hf9dEo/9SBMAI5E7w4bVbr9jceuW5eOwTEHLOvti013uh9IdUUCgNnU1WQ1snv10SwZHmheAjYjT2N1J93mgAcA+8kHNabT7dsev+7eNE/mNWAzlq78+dq6qr4rZADDLS8XdlI9np81ebR7XbPpS8CyvKyY9oyMmcgAhk8/wzWjbwHb15JvTFzZGelcWafuVAbAQOodzkjdPa7p3ePb/nv1ZOqzRgI2Y/HYxOKFI2msF7Oq+prJDCC8qVTVD9e7pyd37UmT/Zq2PkmjATtQDtqnFqSvpE5nbLquzuqWe7Rb8MXdT8ZolRzLByjEVO9/62qqTnV+VuRv63rPVNPBOtD/A6oeNVega6lDAAAAAElFTkSuQmCC"}}]); \ No newline at end of file diff --git a/assets/js/0e33a907.f1035e02.js b/assets/js/0e33a907.f1035e02.js deleted file mode 100644 index 26dbaffa1..000000000 --- a/assets/js/0e33a907.f1035e02.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3092],{3905:(A,e,t)=>{t.d(e,{Zo:()=>w,kt:()=>c});var r=t(67294);function n(A,e,t){return e in A?Object.defineProperty(A,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):A[e]=t,A}function p(A,e){var t=Object.keys(A);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(A);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(A,e).enumerable}))),t.push.apply(t,r)}return t}function E(A){for(var e=1;e=0||(n[t]=A[t]);return n}(A,e);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(A);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(A,t)&&(n[t]=A[t])}return n}var I=r.createContext({}),l=function(A){var e=r.useContext(I),t=e;return A&&(t="function"==typeof A?A(e):E(E({},e),A)),t},w=function(A){var e=l(A.components);return r.createElement(I.Provider,{value:e},A.children)},o={inlineCode:"code",wrapper:function(A){var e=A.children;return r.createElement(r.Fragment,{},e)}},u=r.forwardRef((function(A,e){var t=A.components,n=A.mdxType,p=A.originalType,I=A.parentName,w=a(A,["components","mdxType","originalType","parentName"]),u=l(t),c=n,C=u["".concat(I,".").concat(c)]||u[c]||o[c]||p;return t?r.createElement(C,E(E({ref:e},w),{},{components:t})):r.createElement(C,E({ref:e},w))}));function c(A,e){var t=arguments,n=e&&e.mdxType;if("string"==typeof A||n){var p=t.length,E=new Array(p);E[0]=u;var a={};for(var I in e)hasOwnProperty.call(e,I)&&(a[I]=e[I]);a.originalType=A,a.mdxType="string"==typeof A?A:n,E[1]=a;for(var l=2;l{t.r(e),t.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>E,metadata:()=>I,toc:()=>w});var r=t(87462),n=(t(67294),t(3905)),p=t(17779);const E={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",slug:"woowacourse-level3-retrospective",tags:["Woowahan Techcourse","Retrospective"]},a=void 0,I={permalink:"/woowacourse-level3-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",source:"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",description:"\ud68c\uace0",date:"2023-08-19T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 19\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.945,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",slug:"woowacourse-level3-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",permalink:"/db-replication"},nextItem:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/cloudwatch"}},l={authorsImageUrls:[]},w=[{value:"\ud68c\uace0",id:"\ud68c\uace0",level:3},{value:"\uc544\uc26c\uc6b4 \uc810",id:"\uc544\uc26c\uc6b4-\uc810",level:3},{value:"\uc88b\uc558\ub358 \uc810",id:"\uc88b\uc558\ub358-\uc810",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3}],o={toc:w};function u(A){let{components:e,...t}=A;return(0,n.kt)("wrapper",(0,r.Z)({},o,t,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h3",{id:"\ud68c\uace0"},"\ud68c\uace0"),(0,n.kt)("p",null,"\uc9c0\ub09c 8\uc8fc\ub294 \ub808\ubca8 1, 2 \ub54c\ubcf4\ub2e4 5\ubc30 \uc815\ub3c4 \ube60\ub974\uac8c \uc9c0\ub098\uac04 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 3\uc5d0\ub294 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4, \uae30\uc220 \uc678\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4 \ubd80\uc871\ud568\uc774 \ub9ce\uc774 \ubcf4\uc600\ub358 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ubd80\uc871\ud55c \ubd80\ubd84\uc744 \uc54c\uc558\uae30\uc5d0, \uc55e\uc73c\ub85c \ub354\uc6b1 \uc131\uc7a5\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \ud300\uc6d0\ub4e4\uc774 \uc798 \ubcf4\ucda9\ud574 \uc918\uc11c \ub4e0\ub4e0\ud588\ub2e4. "),(0,n.kt)("h3",{id:"\uc544\uc26c\uc6b4-\uc810"},"\uc544\uc26c\uc6b4 \uc810"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\ubb38\uc11c\ud654")),(0,n.kt)("p",null,"\uac1c\uc778\uc801\uc73c\ub85c\ub294 \uae30\uc220 \uc678\uc801\uc73c\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ub0b4\uac00 \ud55c \ubd80\ubd84\uc744 \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c, \uc774\ud574\ud558\uae30 \uc27d\uac8c \ubb38\uc11c\ud654\ub97c \ud588\ub354\ub77c\uba74 \ud300\uc6d0\ub4e4\uc5d0\uac8c \ub354\uc6b1 \ub3c4\uc6c0\uc774 \ub418\uc5c8\uc744 \ud150\ub370 \uc774 \ubd80\ubd84\uc5d0 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ud22c\uc790\ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc5d0\uc11c \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ubc29\ud559 \uae30\uac04 \ub3d9\uc548 \ubb38\uc11c\ud654\ub97c \ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc778 \ube14\ub85c\uadf8 \uc62c\ub9ac\uba74\uc11c \uc870\uae08 \ub354 \ucc44\uc6cc\ubcf4\ub824\uace0 \ud55c\ub2e4. "),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\ub0b4\uac00 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc774\uc790")),(0,n.kt)("p",null,"\uc798 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc5ec\uc11c\ub77c\ub3c4 \uc911\uac04\uc740 \uac00\ub3c4\ub85d \ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ub9d0\uc744 \ud558\uae30 \uc804\uc5d0 \uc815\ub9ac\ud574\uc11c \uc758\uacac\uc744 \ub0b4\ub294 \uac83, \ubc1c\ud45c \uc900\ube44, \uac10\uc815 \uc870\uc808 \ub4f1\ub4f1\n\ubabb\ud558\ub294 \ubd80\ubd84\uc744 \uc778\uc9c0\ud558\uace0, \uac1c\uc120\ud558\uc790. "),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\ucef4\ud3ec\ud2b8 \uc874 \ubc97\uc5b4\ub098\uae30")),(0,n.kt)("p",null,"\uc870\uae08 \ub354 \ub3c4\uc804\uc801\uc73c\ub85c \ubaa9\ud45c\ub97c \uc7a1\uc558\uc73c\uba74 \uc88b\uc558\uc744 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ub9e4\ubc88 \uadfc\uac70\ub97c \uac00\uc9c0\uace0 \uae30\uc220\uc744 \ub3c4\uc785\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uc9c0\uc18d\uc801\uc73c\ub85c \uac1c\uc120\ud558\ub824\uace0 \ud558\ub294 \ubd80\ubd84\uc774 \ub2e4\uc18c \ubd80\uc871\ud588\ub2e4. "),(0,n.kt)("h3",{id:"\uc88b\uc558\ub358-\uc810"},"\uc88b\uc558\ub358 \uc810"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\uc88b\uc558\ub358 \uc810\ub3c4 \ubb38\uc11c\ud654")),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://tripdraw.blog"},"\ud300 \ube14\ub85c\uadf8"),"\ub3c4 \uba3c\uc800 \ub3c4\uc785\ud558\uc790\uace0 \uc81c\uc548\ud558\uace0, \ub0b4\uac00 \ud588\ub358 \ubd80\ubd84\uc740 \ubb38\uc11c\ud654\ub97c \uaf64 \ub9ce\uc774 \ud574\uc11c \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ubc31\uc5d4\ub4dc \ud06c\ub8e8 4\uba85\uc774\uc11c \uac19\uc774 \ud55c \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c\ub294 \uae30\ub2a5 \uad6c\ud604\ud55c\ub2e4\uace0 \ubb38\uc11c\ud654\uac00 \uc870\uae08 \ubbf8\ud761\ud574\uc11c \ubcf4\ucda9\uc744 \ud574\uc57c\uaca0\ub2e4. "),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\ub0b4\uac00 \ub514\uc790\uc778\ud55c \ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0")),(0,n.kt)("img",{src:p.Z,width:"100"}),(0,n.kt)("p",null,"\ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud300\uc6d0\ub4e4\uc774 \ub300\ud45c \uc0c9\uc0c1(\ud30c\ub780\uc0c9)\uc744 \uc815\ud574\uc92c\uace0, \uc8fc\ub9d0 \ub3d9\uc548 \uc2e0\ub098\uac8c \ub85c\uace0 \ub514\uc790\uc778\uc744 \ud588\ub358 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc758 D \ubd80\ubd84\uc740 \uc720\ud29c\ube0c \uac15\uc758 \ub4e4\uc73c\uba74\uc11c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\uc11c \ubfcc\ub4ef\ud558\ub2e4. "),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\uae30\uc220 \uc120\ud0dd\uc758 \uc774\uc720")),(0,n.kt)("p",null,"\uae30\uc220\uc758 \ud559\uc2b5 \ube44\uc6a9, \ud604\uc7ac \uad6c\uc870\uc5d0 \uc801\ud569\ud55c\uc9c0, \uc2e4\uc81c \uac00\uc9c0\uace0 \uc788\ub294 \ub9ac\uc18c\uc2a4\ub97c \uace0\ub824\ud574\uc11c \uae30\uc220 \uc120\ud0dd\uc744 \ud558\uace0, \ub3c4\uc785\ud588\ub358 \ubd80\ubd84\uc774 \uc88b\uc558\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","100% \uc88b\uc740 \uc120\ud0dd\uc77c \uc21c \uc5c6\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \uc120\ud0dd\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \uc874\uc7ac\ud55c\ub2e4\uba74 \ud655\ub960\uc744 \ub192\ud600\uc8fc\ub294 \uac83 \uac19\ub2e4. "),(0,n.kt)("h3",{id:"\ub9c8\uce58\uba70"},"\ub9c8\uce58\uba70"),(0,n.kt)("p",null,"\ud50c\ub808\uc774\uc2a4\ud1a0\uc5b4\uc5d0 \uc571\uc774 \uc62c\ub77c\uac00 \uc788\ub294 \uac70 \ub108\ubb34 \uc2e0\uae30\ud558\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc548\ub4dc\ub85c\uc774\ub4dc \ube0c\ub808\uba58 \uc74c\uc545\ub300(\uba67\ub3fc\uc9c0, \uc218\ub2ec, \ud551\uad6c), \uadf8\ub9ac\uace0 \ubc31\uc5d4\ub4dc \ud300\uc6d0\ub4e4(\uccb4\uc778\uc800, \ud6c4\ucd94, \ub9ac\uc624) \ub108\ubb34 \uace0\uc0dd\uc774 \ub9ce\uc558\ub2e4."))}u.isMDXComponent=!0},17779:(A,e,t)=>{t.d(e,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAGwCAYAAADITjAqAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAABauSURBVHgB7d1viF3lncDx59yJsZpWU6wxoqmjLthGS2vBP4u7dEqb7FIXVKIFX9Qa3xTqiyisfWeNyEKphWZgLesbxyqLi4m0wiprXHCWIlUD1bKaRljt1CjGfzSmjdaYzNn73Dg2f5wkk8w95/nd+/nANCaZ0HHM3O/8nuc551SpRYvHJhYvXLhgrJquR+sqfblK9WiqqtGPfns0AdC6uk7bq6qaSvX09jpVU52q/kOanp78y+703PbJ1dtTS6rUoI+DVU2Ppbq6IokUQHRT3QFksvua/vCuXbsnmwxaIwFb+s2JsbozsqZb8W680uIEwEDqxuzeHLM3N37nl6nP+hawj6atNd3Z8ybRAhg6U1Wdbk8f7pncNrl6KvXBvAdMuADYx1R33+ze7kR2e5pn8xqwpSvuu747Pt6W7G0BsL/eRLbt8evuTfNkXgK2dGxitD5uwUSq6rEEALP7ZbVrz83zsazYScfotBX3r5k+buRZ8QLgCFxZLxx5Nq/YpWN01BNY3us6fuFIXi68KQHAXFVp3RuPXXdzOkpHFbDekuHCkXxE8ssJAI5a9Vy1a/dVR7OkOOeAfRSvJ5KDGgDMj6nuvtjX5xqxOQVMvADokzlH7IgDJl4A9NmcInZEARMvABpyxBE7omP0Hx3YGE0A0F/dgWnBL/JJ98O942EDdtrK+36anDYEoDH1V44/vneZ1iGNHOo3exeaVelHCQCademn/+aqd3e+9IunZnuHWffA8r5XvsOGG/IC0JLt3f2wC2fbD5t1CbG77/VT8QKgRYvr4zsTs/3mJwbso3tUXZkAoE11NTbbfRM7n/z+6bCbZwDQhNykTzqVeFDAlqy83/O8ACjJ6KcWdg66cfx+hzhcsAxAobZ/sGvP2dsnV2+f+YX9J7DjRsaSeAFQnsUHTmH7BczeFwClqlO1Zt+ffxywJd+4P586HE0AUKbFS785MTbzk79OYCPTjs0DULS6M/LxFNY7xJGPJx6/cOSPCQDK9vFhjt4EtnBkwVgCgPItPmHh3mbtXUK0fAhAENNVGss/9gJWpeprCQAiqOsr8g+V/S8Aounug32286kF6SsJAALJ+2Cd1OmMJQAIZLqqR/Me2GgCgECqlL7cqevOWQkAAqmnuxNYnTx1GYBgqiovIdajCQCC6VSVCQyAcEY7CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQlqQAPrkzCUnpi+edXI6adFx3X8+IZ104nHp5EULP/F93925K+1478P0p50fps1TO9KO3o/vJpiNgLUkf0FfPbYsrbjo9HTmqSf2vtCJ49U33+u9uD6+6fW0YXJrIqVLz/9cWj56Uvdtcbpk+Snz9nc6f57z5/vpzW/3wvbUC28nyKrTVt5XJxqVv7AfWHtZL1zEl19gv3fnM70X2WGS/x6vvGhp75uw5aN7p6ym5Ijlbx42bto2dJ93/krAGiZegym/oF679sk06PLf31VfW9ZdPfh8MasG+RuIiUdeSk9tfkfMhowlxIb1llbEa+Dk5bM8jeSJYNDsu9yd/z1Lk6e/O2/8au+fNz6zd0k3T2cMPgFr2DVjZyUG06ruVDJIAcvhWv2tc9INl5/b6PLgsVh58em9t1ffei+NP7jF/uSAE7CGfbG7yc1gWn72yWkQ5KXBNdec11smjCqvcuSpbM23vyBkA8weWMN+v/6KxOA6+5qHU1SDEK7Z5InslruedYJxwJjAYMhFXCqcqzyR5cNTeRIbX7/FYY8BIWAwxFaNLUs/vP5LAxuuA+XDKJeef4plxQEhYDCE8nLhnd+/sMhThf02sz92yfmnmsaCcy9EGDJ5qfCRH48NZbz2laex3jWZ7oITloDBkMjLhLdef0HvbViWDA8nT2O/umtFbw+QeCwhwhDIU8bdt1zcu+iXg/1w9d59wPH1LybiMIHBgMvRyktl4nVoN337C929sQsTcZjAYIDNxMuS4ZHJ18DlR77ka8byo10omwkMBpR4HZ18K6oHbr+sFzLKJmAwgMTr2OTP362rL0iUTcBgwMw8ske8jk1eTrQnVjYBgwEiXvMrRyzfH5IyCRgMiBwtD0udf/l04iDe4HgQCBgMiHyBsnj1R/7cugyhPAIGA+Cma0wJ/ZSn27t/cLGTiYURMAiu9xyvb9un6bc83eYHZFIOAYPg8r4Xzbjh8nPSiotOT5RBwCCwvHRo36tZP7nxQkuJhRAwCMrSYTvyfpilxDIIGARl6bA9eSlx2J+nVgIBg4DyQyktHbbLBc7tEzAIJi8drr7cAxjblicwU1i7BAyCyd/5m77K4F6J7RIwCCRPXy5YLkf+RuLqsWWJdggYBGLfpTyrfEPRGgGDebJjZ3+f4Gv6KpO9sPYIWMNefeu9xGDq939b01e5/Ldpx4JEozZPvWsDfkBtntqR+iXy9JUn0xz3P+3cvd+vf2bRgoG5w3uewPLdOXa8198pnP0JWMMemtyaVrqX2kAaf3BL6pdI3+HnYG2YfCU9vfmd3jdsr7556Mk0RywHIH9dXHL+KSmq1f90TvfvwIuJ5lSnrbyvTjTqP9b+XegvVA52zyMvpTvufT71Q56+fnXXilS6p154O42vf7H349HKqxM5ZvkWWdFWKvKU+ffffzzRnJFPn3vV2kSj8hd4vp+aB+TFl6eNf3v4/9KP/31z6pcVFy1NKy8ud2rfuGlbuv5ffp0mHn35mPcB8xJcntomHnk5vfbW+2n52Sf3vlYiyB9nnjrtczfHBNai/B1m/gL94uhJadmpi1IbzlhyQrp0ecwTVE9tfju99ub7qQ1b39rZXRp7Pz3+zOt93/f41c9WFDmN5BfqW+569pgmrsPZ+wyu88Ls/61bv8UyYoPsgbUovwDkt43dF8G2rBpbFjZgG554pbenOMjyclqJ8cp7XHdMPN/3eM9E8ndTO9Kt11+QSpe/lsaTgDXFMXoo2KoC7/KQp4wclSZP3OU9xstvmez7tXbHauY0Is0QMChUiUfn21wiy3tj1659sviIrbh4aaIZAgaFumR5WSdVS9jfyRH73p3PpJI5nNUcAYNCXTN2VipFXsIr5XBCPjTSr0sW5kPJJ0YHjYBBgfLyYSnXCuaDFKUFIwf16RfeSSXKh27sgzVDwKBAJd2t5drbnkwl+ue7flPsflj+BoT+EzAoUCkBy/tepV6Ymz+ufPF0ifK1nfSfgEFhSlk+zIF46Imyr7PLS4klTmEOcjRDwKAwpZw+zIc2Sr8tUo5XiVOYJ040Q8CgMKWcPuznLaLmU57CSmMPrBkCBgXJN4QtYflww+TWMDelzVNYaScSTWDNEDAoSCl7J4+3eH/Oo5Fv7FySKHfQj07AoCCl3IZo46ZgAStwudMU1n8CBgUp4ckAUfa+9pVvMcXwETAoRN74L2EJMWIM8j6YB0kOHwGDQpRy8WvUELT1cNPZOInYfwIGhSjl7hv54ZER5adkM1wEDArh7g0wNwIGBcjHrksJ2Ktv2ksiBgGDApi+jt2yUxelkvhGoP8EDApQyrO/MocPiELAoAB/u/zUVIqoD2Ms7REmjvX3n4BBAUp68T1jyQkpmjw1un3T8BEwaFlpL74R9+NMX8NJwKBlpb34Xnp++7ezmqtSrqGb4QBHMwQMWlbaxJNvQhttH6y06JrAmiFg0LISl+xWfX1ZiiLHq7Q7vwtYMwQMWlbiYzdKW5I7lFVj5cX2d7+PeTuuaAQMWlbiBJanmgh7YfkAzNVjn0+lMYE1Q8CgRcvPLvfE35przkulK/Vj9HyyZggYtOiMU8u95qr0KSxPriVOXxEfCBqVgEGLSr/mquQp7O4fXJxKZPpqjoBBi0oPWJ7AVn/rnFSaW6+/oMjDL9nTL7yTaIaAQYtOPnFhKt0PV3+pqKXEGy4/t/dWKhNYcwQMWlTaXThmc/ctFxdxl/q855Wnr1LleDmB2BwBg5bk+x9GuQFt/jgfWHtZqxHL8brzxgtTyRzgaJaAQUuiPXcr7znliLWxb5eXDEuPV/b4pm2J5ggYtCTic7dyxB65c6yxgx158rvz+xcWvWw4Iy8dmsCatSABrYj42JIZ+WDH8rMXp/H1W/p25/V8cCRPXaWeNjzQU04fNk7AoCWfWRT7y+/qsWW9t3seeSlNPPryvIUshytffxbtsS7jD25JNEvAoCWRJ7B9zRxr3zC5NT00+cpRLaPlpcIcwxUXnR7yeWT539npw+YJGLQkwjVgczEzke3Y+WHvBf3pzW+nzVM7ej/f8d6H+71vXhY8o/u2fPSkXrCix3x8/YuJ5gkYtCT6EuJs8jS18uLTe2/DwOGN9jiFCC2JcjiBQxt/0PTVFgGDFkS6iJnZ5elrQ3ffj3YIGLQg4jVgHOyWu55NtEfAoAXR7sLBwfKpS3tf7RIwgDnKJytd99U+AYMWlPwkZg7vnkdfct1XAQQMWmAJMa4cLicPyyBgAEcoLx1ee9uTiTIIGLTANWAx5TtuWDosh4ABHIF80+L8RjkEDFqw7NRFiTjse5VJwAAOIccr73sdeENi2idg0IJBvZHvIPrej5+x71UoAYMWuA9iDLf87Nm0eerdRJkEDOATrFu/JW14wo16SyZg0ALH6MuW4+XQRvkEDGAf4hWHgAF8RLxiETCAJF4ROcsLDbP/VZ477n3eXTYCEjBgaOWb8+anKm/c9HoiHgEDhlK+ODlfpOw6r7gEDBg6OVrusBGfgAFDZcPkK+mOiefd23AACBgwNBzWGCwCBgy8vFSYD2s89cLbicEhYMBA27hpW7rlX39jyXAACRg07MwlrgNrQj4iP77+RUuGA0zAoGEmgf7LS4V5ydApw8EmYNCwHX8WsH7KU9e6B7ckBp+AAQPB1DV8BAwIzV7X8BIwIKx8wvCOif81dQ0pAQPCcV0XmYABYeTlwolHX3ZIgx4BA0LIe1z5gZMuQ2CGgAFFc7qQ2QgYNMwL8ZHJ4cqnC+1zMRsBA4oiXBwpAQOKIFzMlYABrRIujpaAQQvyPtiZpw73XemFi2MlYECjNkxuTQ9NviJcHDMBA/pu5gLke/7zJddxMW8EDFrw2pvvD8US4uapd7vT1ta04YlXhIt5J2DAvLO/RRMEDFqw9a2d6ZJ0ShoklglpmoABx8S0RVsEDFoQfULJe1uPb9pm2qJVAgYtyMtt0eSPecPkK71wmbYogYBBC/60c3eKIEcrT1t5iXDz7981bVEUAYMWvLtzVypZnrDypOX4OyUTMGhBiVEQLaIRMGjBa2+9n9o2szwoWkQlYNCCHX9uJxY5WjlYv87T1jOvixahCRhhlTDFHK18N/qm7kj/6pvvpY2bXnd6kIEjYEPu6RfeSVHlU3GR5XsErrnmvDTf9l0azOHKAYNBJGBDLk8B+QXvpEXHpUjyJBF9+eueR15Kq8aWzcsUloM1cwjDcXeGhYDRu8bn1usvSJHk6SW6/I3Dtbc9mR64/bI5R2xmWXDz1A57WQyt6rSV99WJoXfr6gvSDd86N0Wwbv2WNP7gi2lQ5Hj95MavpkvOn/3mvjlYT29+p3f44unNb1sWhCRg7OPS8z/XW9JaPnpy70W1lGXFPKnkpc6ZJbJBPYiQP/8rLlqali1Z1Pv51jd3mrDgEAQMgJA6CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAELKAZtKABDLdhMYAAFVU51UV1MJACKpp7d3qmr6DwkAAqk63Qmsnq6eSwAQSV3/oVNbQgQgmunpyc6uPbsnEwAE8pfd6bnO9snV25Oj9ABEUaWp3K69x+jr+uEEAAFUKU3mH3sBq6c7kwkAAqjqqjd09QKW98HqOm1PAFC493ftPbvRC1heS6yq+n8SABSsqtK9H53d+OvNfKvp6XUJAAo2s3zY++d9f2PJivv+2K3b4gQApanS1BuPXXf2zE/3u5lvp6rHEwAUqJpOt+/78/0C9pdd0+sc5gCgON3pK43smdz3l/YLWO/CMFMYAIWp6vrn2/5r9dS+v3bQ88DyFNYrHQCUoNukbRu/u/bAXz4oYL0j9QesMwJAW2ZrUjXbHzjtH+5/ItX1WAKA1lS/fGPjd676pN/pzPpHqt2rHegAoC11d1Gw6uy+ebbfnzVgebOsqi0lAtCOTp1uPvDgxr5GDvWHd778i6c+fc6Vn+2OY5cmAGhKVY2/sfG6Hx3qXTrpMD74cHptnarnEgA047dvPPadmw73TocNWO/asM7uqxytB6Dvuq2pOnuuPLJ3PUJL/3FitK5Hnujuqo0mAJhvOV7Vnq8fat9r/3efAxEDoC/mGK+9f2SORAyAeXUU8coOuwd2oN7x+u7/kYMdAMyD3x5NvLI5T2D7Om3Fz9elqlqTAGCuqmr8gw92r515wvKc/3g6RktX3Hf9dEo/9SBMAI5E7w4bVbr9jceuW5eOwTEHLOvti013uh9IdUUCgNnU1WQ1snv10SwZHmheAjYjT2N1J93mgAcA+8kHNabT7dsev+7eNE/mNWAzlq78+dq6qr4rZADDLS8XdlI9np81ebR7XbPpS8CyvKyY9oyMmcgAhk8/wzWjbwHb15JvTFzZGelcWafuVAbAQOodzkjdPa7p3ePb/nv1ZOqzRgI2Y/HYxOKFI2msF7Oq+prJDCC8qVTVD9e7pyd37UmT/Zq2PkmjATtQDtqnFqSvpE5nbLquzuqWe7Rb8MXdT8ZolRzLByjEVO9/62qqTnV+VuRv63rPVNPBOtD/A6oeNVega6lDAAAAAElFTkSuQmCC"}}]); \ No newline at end of file diff --git a/assets/js/101b58de.2b9af44d.js b/assets/js/101b58de.2b9af44d.js new file mode 100644 index 000000000..c88f088be --- /dev/null +++ b/assets/js/101b58de.2b9af44d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6084],{86942:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var r=n(85893),a=n(3905);const l={title:"JSR-310",slug:"jsr-310",tags:["Java","Time"]},i=void 0,o={permalink:"/jsr-310",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-08-JSR-310.mdx",source:"@site/blog/2023-1/2023-01-08-JSR-310.mdx",title:"JSR-310",description:"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API",date:"2023-01-08T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 8\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Time",permalink:"/tags/time"}],readingTime:1.685,hasTruncateMarker:!1,authors:[],frontMatter:{title:"JSR-310",slug:"jsr-310",tags:["Java","Time"]},unlisted:!1,prevItem:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",permalink:"/kotlin-null"},nextItem:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",permalink:"/the-essence-of-object-orientation"}},s={authorsImageUrls:[]},c=[{value:"LocalDate, LocalTime, LocalDateTime",id:"localdate-localtime-localdatetime",level:3},{value:"Instant",id:"instant",level:3},{value:"Duration, Period",id:"duration-period",level:3},{value:"TemporalAdjusters",id:"temporaladjusters",level:3},{value:"DateTimeFormatter",id:"datetimeformatter",level:3},{value:"ZoneId, ZoneOffset",id:"zoneid-zoneoffset",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(t.p,{children:["\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API",(0,r.jsx)(t.br,{}),"\n","ISO-8601\uc744 \uae30\ubc18\uc73c\ub85c \uc791\uc131",(0,r.jsx)(t.br,{}),"\n","\uc124\uacc4 \ubaa9\ud45c \u2192 \ubd88\ubcc0, Fluent API, \uba85\ud655\ud558\uace0 \uba85\uc2dc\uc801, \ud655\uc7a5 \uac00\ub2a5\uc131"]}),"\n",(0,r.jsx)(t.admonition,{title:"ISO-8601",type:"note",children:(0,r.jsx)(t.p,{children:"\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc5d0 \uad00\ub828\ub41c \ub370\uc774\ud130\ub97c \ub2e4\ub8e8\ub294 \uad6d\uc81c \ud45c\uc900"})}),"\n",(0,r.jsx)(t.h3,{id:"localdate-localtime-localdatetime",children:"LocalDate, LocalTime, LocalDateTime"}),"\n",(0,r.jsx)(t.p,{children:"\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4"}),"\n",(0,r.jsx)(t.h3,{id:"instant",children:"Instant"}),"\n",(0,r.jsxs)(t.p,{children:["\uc720\ub2c9\uc2a4 \uc2dc\uac04(1970-01-01, 00:00:00 UTC) \uae30\uc900\uc73c\ub85c \ud2b9\uc815 \uc9c0\uc810\uae4c\uc9c0\uc758 \uc2dc\uac04\uc744 \ucd08\ub85c \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4",(0,r.jsx)(t.br,{}),"\n","\uae30\uacc4\uc758 \uad00\uc810\uc5d0\uc11c \uc2dc\uac04 \ud45c\ud604"]}),"\n",(0,r.jsx)(t.h3,{id:"duration-period",children:"Duration, Period"}),"\n",(0,r.jsx)(t.p,{children:"\uac04\uaca9\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4"}),"\n",(0,r.jsx)(t.h3,{id:"temporaladjusters",children:"TemporalAdjusters"}),"\n",(0,r.jsxs)(t.p,{children:["\ubcf5\uc7a1\ud55c \ub0a0\uc9dc \uc870\uc815\uc774 \ud544\uc694\ud560 \ub54c \uc0ac\uc6a9",(0,r.jsx)(t.br,{}),"\n","\ud544\uc694\ud55c \uacbd\uc6b0 \ub2e4\uc74c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\uc5ec \ucee4\uc2a4\ud140 TemporalAdjuster\ub97c \uad6c\ud604 \uac00\ub2a5"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",children:"@FunctionalInterface\npublic interface TemporalAdjuster {\n Temporal adjustInto(Temporal temporal);\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"datetimeformatter",children:"DateTimeFormatter"}),"\n",(0,r.jsxs)(t.p,{children:["\ub0a0\uc9dc\uc640 \uc2dc\uac04 \ud3ec\ub9f7 \ud074\ub798\uc2a4",(0,r.jsx)(t.br,{}),"\n","\ud2b9\uc815 \ub0a0\uc9dc \ud328\ud134\uc774\ub098, DateTimeFormatterBuilder\ub97c \uc774\uc6a9\ud574\uc11c \ucee4\uc2a4\ud140\ud55c \ud3ec\ub9f7\uc744 \uc0dd\uc131 \uac00\ub2a5"]}),"\n",(0,r.jsx)(t.h3,{id:"zoneid-zoneoffset",children:"ZoneId, ZoneOffset"}),"\n",(0,r.jsxs)(t.p,{children:["ZoneId\ub294 \uc9c0\uc5ed ID\ub294 ",(0,r.jsx)(t.code,{children:"\u2018\uc9c0\uc5ed/\ub3c4\uc2dc\u2019"})," \ud615\uc2dd, ZoneOffset\uc740 \uc2dc\ucc28 UTC \uae30\uc900 \uace0\uc815\ub41c \uc2dc\uac04 \ucc28\uc774 \uc774\uc6a9",(0,r.jsx)(t.br,{}),"\n","ZoneId\uc758 \uacbd\uc6b0 IANA Time Zone Database\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc9c0\uc5ed \uc9d1\ud569 \uc815\ubcf4 \uc0ac\uc6a9"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",children:"Instant instant = Instant.now();\nLocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);\n"})}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://product.kyobobook.co.kr/detail/S000001810171",children:"\ubaa8\ub358 \uc790\ubc14 \uc778 \uc561\uc158"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://d2.naver.com/helloworld/645609",children:"Java\uc758 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://www.w3.org/TR/NOTE-datetime",children:"ISO-8601"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://download.oracle.com/otn-pub/jcp/date_time-0.2-edr-oth-JSpec/date_time-0_2-edr-spec.pdf?AuthParam=1673171124_74a718be92efe4911c6977c02965aff4",children:"JSR-310 Spec"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://www.baeldung.com/java-temporal-adjuster",children:"Temporal Adjuster"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html",children:"DateTimeFormatter"})}),"\n"]})]})}function m(e={}){const{wrapper:t}={...(0,a.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>c});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),p=c(n),u=a,h=p["".concat(s,".").concat(u)]||p[u]||d[u]||l;return n?r.createElement(h,i(i({ref:t},m),{},{components:n})):r.createElement(h,i({ref:t},m))}));m.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/101b58de.c3fca784.js b/assets/js/101b58de.c3fca784.js deleted file mode 100644 index 2333191c5..000000000 --- a/assets/js/101b58de.c3fca784.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6084],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var r=a(67294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var p=r.createContext({}),m=function(e){var t=r.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=m(e.components);return r.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},s=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,l=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),s=m(a),d=n,f=s["".concat(p,".").concat(d)]||s[d]||u[d]||l;return a?r.createElement(f,o(o({ref:t},c),{},{components:a})):r.createElement(f,o({ref:t},c))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var l=a.length,o=new Array(l);o[0]=s;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:n,o[1]=i;for(var m=2;m{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>i,toc:()=>m});var r=a(87462),n=(a(67294),a(3905));const l={title:"JSR-310",slug:"jsr-310",tags:["Java","Time"]},o=void 0,i={permalink:"/jsr-310",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-08-JSR-310.mdx",source:"@site/blog/2023-1/2023-01-08-JSR-310.mdx",title:"JSR-310",description:"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API",date:"2023-01-08T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 8\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Time",permalink:"/tags/time"}],readingTime:1.685,hasTruncateMarker:!1,authors:[],frontMatter:{title:"JSR-310",slug:"jsr-310",tags:["Java","Time"]},prevItem:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",permalink:"/kotlin-null"},nextItem:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",permalink:"/the-essence-of-object-orientation"}},p={authorsImageUrls:[]},m=[{value:"LocalDate, LocalTime, LocalDateTime",id:"localdate-localtime-localdatetime",level:3},{value:"Instant",id:"instant",level:3},{value:"Duration, Period",id:"duration-period",level:3},{value:"TemporalAdjusters",id:"temporaladjusters",level:3},{value:"DateTimeFormatter",id:"datetimeformatter",level:3},{value:"ZoneId, ZoneOffset",id:"zoneid-zoneoffset",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:m};function u(e){let{components:t,...a}=e;return(0,n.kt)("wrapper",(0,r.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API",(0,n.kt)("br",{parentName:"p"}),"\n","ISO-8601\uc744 \uae30\ubc18\uc73c\ub85c \uc791\uc131",(0,n.kt)("br",{parentName:"p"}),"\n","\uc124\uacc4 \ubaa9\ud45c \u2192 \ubd88\ubcc0, Fluent API, \uba85\ud655\ud558\uace0 \uba85\uc2dc\uc801, \ud655\uc7a5 \uac00\ub2a5\uc131"),(0,n.kt)("admonition",{title:"ISO-8601",type:"note"},(0,n.kt)("p",{parentName:"admonition"},"\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc5d0 \uad00\ub828\ub41c \ub370\uc774\ud130\ub97c \ub2e4\ub8e8\ub294 \uad6d\uc81c \ud45c\uc900")),(0,n.kt)("h3",{id:"localdate-localtime-localdatetime"},"LocalDate, LocalTime, LocalDateTime"),(0,n.kt)("p",null,"\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4"),(0,n.kt)("h3",{id:"instant"},"Instant"),(0,n.kt)("p",null,"\uc720\ub2c9\uc2a4 \uc2dc\uac04(1970-01-01, 00:00:00 UTC) \uae30\uc900\uc73c\ub85c \ud2b9\uc815 \uc9c0\uc810\uae4c\uc9c0\uc758 \uc2dc\uac04\uc744 \ucd08\ub85c \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4",(0,n.kt)("br",{parentName:"p"}),"\n","\uae30\uacc4\uc758 \uad00\uc810\uc5d0\uc11c \uc2dc\uac04 \ud45c\ud604"),(0,n.kt)("h3",{id:"duration-period"},"Duration, Period"),(0,n.kt)("p",null,"\uac04\uaca9\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4"),(0,n.kt)("h3",{id:"temporaladjusters"},"TemporalAdjusters"),(0,n.kt)("p",null,"\ubcf5\uc7a1\ud55c \ub0a0\uc9dc \uc870\uc815\uc774 \ud544\uc694\ud560 \ub54c \uc0ac\uc6a9",(0,n.kt)("br",{parentName:"p"}),"\n","\ud544\uc694\ud55c \uacbd\uc6b0 \ub2e4\uc74c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\uc5ec \ucee4\uc2a4\ud140 TemporalAdjuster\ub97c \uad6c\ud604 \uac00\ub2a5"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},"@FunctionalInterface\npublic interface TemporalAdjuster {\n Temporal adjustInto(Temporal temporal);\n}\n")),(0,n.kt)("h3",{id:"datetimeformatter"},"DateTimeFormatter"),(0,n.kt)("p",null,"\ub0a0\uc9dc\uc640 \uc2dc\uac04 \ud3ec\ub9f7 \ud074\ub798\uc2a4",(0,n.kt)("br",{parentName:"p"}),"\n","\ud2b9\uc815 \ub0a0\uc9dc \ud328\ud134\uc774\ub098, DateTimeFormatterBuilder\ub97c \uc774\uc6a9\ud574\uc11c \ucee4\uc2a4\ud140\ud55c \ud3ec\ub9f7\uc744 \uc0dd\uc131 \uac00\ub2a5"),(0,n.kt)("h3",{id:"zoneid-zoneoffset"},"ZoneId, ZoneOffset"),(0,n.kt)("p",null,"ZoneId\ub294 \uc9c0\uc5ed ID\ub294 ",(0,n.kt)("inlineCode",{parentName:"p"},"\u2018\uc9c0\uc5ed/\ub3c4\uc2dc\u2019")," \ud615\uc2dd, ZoneOffset\uc740 \uc2dc\ucc28 UTC \uae30\uc900 \uace0\uc815\ub41c \uc2dc\uac04 \ucc28\uc774 \uc774\uc6a9",(0,n.kt)("br",{parentName:"p"}),"\n","ZoneId\uc758 \uacbd\uc6b0 IANA Time Zone Database\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc9c0\uc5ed \uc9d1\ud569 \uc815\ubcf4 \uc0ac\uc6a9"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},"Instant instant = Instant.now();\nLocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);\n")),(0,n.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://product.kyobobook.co.kr/detail/S000001810171"},"\ubaa8\ub358 \uc790\ubc14 \uc778 \uc561\uc158")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://d2.naver.com/helloworld/645609"},"Java\uc758 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.w3.org/TR/NOTE-datetime"},"ISO-8601")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://download.oracle.com/otn-pub/jcp/date_time-0.2-edr-oth-JSpec/date_time-0_2-edr-spec.pdf?AuthParam=1673171124_74a718be92efe4911c6977c02965aff4"},"JSR-310 Spec")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.baeldung.com/java-temporal-adjuster"},"Temporal Adjuster")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html"},"DateTimeFormatter"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/111.1a77f36c.js b/assets/js/111.1a77f36c.js new file mode 100644 index 000000000..cb502041e --- /dev/null +++ b/assets/js/111.1a77f36c.js @@ -0,0 +1,2600 @@ +"use strict"; +exports.id = 111; +exports.ids = [111]; +exports.modules = { + +/***/ 67111: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(93799); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17967); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27484); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 24], $V1 = [1, 25], $V2 = [1, 26], $V3 = [1, 27], $V4 = [1, 28], $V5 = [1, 63], $V6 = [1, 64], $V7 = [1, 65], $V8 = [1, 66], $V9 = [1, 67], $Va = [1, 68], $Vb = [1, 69], $Vc = [1, 29], $Vd = [1, 30], $Ve = [1, 31], $Vf = [1, 32], $Vg = [1, 33], $Vh = [1, 34], $Vi = [1, 35], $Vj = [1, 36], $Vk = [1, 37], $Vl = [1, 38], $Vm = [1, 39], $Vn = [1, 40], $Vo = [1, 41], $Vp = [1, 42], $Vq = [1, 43], $Vr = [1, 44], $Vs = [1, 45], $Vt = [1, 46], $Vu = [1, 47], $Vv = [1, 48], $Vw = [1, 50], $Vx = [1, 51], $Vy = [1, 52], $Vz = [1, 53], $VA = [1, 54], $VB = [1, 55], $VC = [1, 56], $VD = [1, 57], $VE = [1, 58], $VF = [1, 59], $VG = [1, 60], $VH = [14, 42], $VI = [14, 34, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74], $VJ = [12, 14, 34, 36, 37, 38, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74], $VK = [1, 82], $VL = [1, 83], $VM = [1, 84], $VN = [1, 85], $VO = [12, 14, 42], $VP = [12, 14, 33, 42], $VQ = [12, 14, 33, 42, 76, 77, 79, 80], $VR = [12, 33], $VS = [34, 36, 37, 38, 39, 40, 41, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "mermaidDoc": 4, "direction": 5, "direction_tb": 6, "direction_bt": 7, "direction_rl": 8, "direction_lr": 9, "graphConfig": 10, "C4_CONTEXT": 11, "NEWLINE": 12, "statements": 13, "EOF": 14, "C4_CONTAINER": 15, "C4_COMPONENT": 16, "C4_DYNAMIC": 17, "C4_DEPLOYMENT": 18, "otherStatements": 19, "diagramStatements": 20, "otherStatement": 21, "title": 22, "accDescription": 23, "acc_title": 24, "acc_title_value": 25, "acc_descr": 26, "acc_descr_value": 27, "acc_descr_multiline_value": 28, "boundaryStatement": 29, "boundaryStartStatement": 30, "boundaryStopStatement": 31, "boundaryStart": 32, "LBRACE": 33, "ENTERPRISE_BOUNDARY": 34, "attributes": 35, "SYSTEM_BOUNDARY": 36, "BOUNDARY": 37, "CONTAINER_BOUNDARY": 38, "NODE": 39, "NODE_L": 40, "NODE_R": 41, "RBRACE": 42, "diagramStatement": 43, "PERSON": 44, "PERSON_EXT": 45, "SYSTEM": 46, "SYSTEM_DB": 47, "SYSTEM_QUEUE": 48, "SYSTEM_EXT": 49, "SYSTEM_EXT_DB": 50, "SYSTEM_EXT_QUEUE": 51, "CONTAINER": 52, "CONTAINER_DB": 53, "CONTAINER_QUEUE": 54, "CONTAINER_EXT": 55, "CONTAINER_EXT_DB": 56, "CONTAINER_EXT_QUEUE": 57, "COMPONENT": 58, "COMPONENT_DB": 59, "COMPONENT_QUEUE": 60, "COMPONENT_EXT": 61, "COMPONENT_EXT_DB": 62, "COMPONENT_EXT_QUEUE": 63, "REL": 64, "BIREL": 65, "REL_U": 66, "REL_D": 67, "REL_L": 68, "REL_R": 69, "REL_B": 70, "REL_INDEX": 71, "UPDATE_EL_STYLE": 72, "UPDATE_REL_STYLE": 73, "UPDATE_LAYOUT_CONFIG": 74, "attribute": 75, "STR": 76, "STR_KEY": 77, "STR_VALUE": 78, "ATTRIBUTE": 79, "ATTRIBUTE_EMPTY": 80, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 6: "direction_tb", 7: "direction_bt", 8: "direction_rl", 9: "direction_lr", 11: "C4_CONTEXT", 12: "NEWLINE", 14: "EOF", 15: "C4_CONTAINER", 16: "C4_COMPONENT", 17: "C4_DYNAMIC", 18: "C4_DEPLOYMENT", 22: "title", 23: "accDescription", 24: "acc_title", 25: "acc_title_value", 26: "acc_descr", 27: "acc_descr_value", 28: "acc_descr_multiline_value", 33: "LBRACE", 34: "ENTERPRISE_BOUNDARY", 36: "SYSTEM_BOUNDARY", 37: "BOUNDARY", 38: "CONTAINER_BOUNDARY", 39: "NODE", 40: "NODE_L", 41: "NODE_R", 42: "RBRACE", 44: "PERSON", 45: "PERSON_EXT", 46: "SYSTEM", 47: "SYSTEM_DB", 48: "SYSTEM_QUEUE", 49: "SYSTEM_EXT", 50: "SYSTEM_EXT_DB", 51: "SYSTEM_EXT_QUEUE", 52: "CONTAINER", 53: "CONTAINER_DB", 54: "CONTAINER_QUEUE", 55: "CONTAINER_EXT", 56: "CONTAINER_EXT_DB", 57: "CONTAINER_EXT_QUEUE", 58: "COMPONENT", 59: "COMPONENT_DB", 60: "COMPONENT_QUEUE", 61: "COMPONENT_EXT", 62: "COMPONENT_EXT_DB", 63: "COMPONENT_EXT_QUEUE", 64: "REL", 65: "BIREL", 66: "REL_U", 67: "REL_D", 68: "REL_L", 69: "REL_R", 70: "REL_B", 71: "REL_INDEX", 72: "UPDATE_EL_STYLE", 73: "UPDATE_REL_STYLE", 74: "UPDATE_LAYOUT_CONFIG", 76: "STR", 77: "STR_KEY", 78: "STR_VALUE", 79: "ATTRIBUTE", 80: "ATTRIBUTE_EMPTY" }, + productions_: [0, [3, 1], [3, 1], [5, 1], [5, 1], [5, 1], [5, 1], [4, 1], [10, 4], [10, 4], [10, 4], [10, 4], [10, 4], [13, 1], [13, 1], [13, 2], [19, 1], [19, 2], [19, 3], [21, 1], [21, 1], [21, 2], [21, 2], [21, 1], [29, 3], [30, 3], [30, 3], [30, 4], [32, 2], [32, 2], [32, 2], [32, 2], [32, 2], [32, 2], [32, 2], [31, 1], [20, 1], [20, 2], [20, 3], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 1], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [43, 2], [35, 1], [35, 2], [75, 1], [75, 2], [75, 1], [75, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.setDirection("TB"); + break; + case 4: + yy.setDirection("BT"); + break; + case 5: + yy.setDirection("RL"); + break; + case 6: + yy.setDirection("LR"); + break; + case 8: + case 9: + case 10: + case 11: + case 12: + yy.setC4Type($$[$0 - 3]); + break; + case 19: + yy.setTitle($$[$0].substring(6)); + this.$ = $$[$0].substring(6); + break; + case 20: + yy.setAccDescription($$[$0].substring(15)); + this.$ = $$[$0].substring(15); + break; + case 21: + this.$ = $$[$0].trim(); + yy.setTitle(this.$); + break; + case 22: + case 23: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 28: + case 29: + $$[$0].splice(2, 0, "ENTERPRISE"); + yy.addPersonOrSystemBoundary(...$$[$0]); + this.$ = $$[$0]; + break; + case 30: + yy.addPersonOrSystemBoundary(...$$[$0]); + this.$ = $$[$0]; + break; + case 31: + $$[$0].splice(2, 0, "CONTAINER"); + yy.addContainerBoundary(...$$[$0]); + this.$ = $$[$0]; + break; + case 32: + yy.addDeploymentNode("node", ...$$[$0]); + this.$ = $$[$0]; + break; + case 33: + yy.addDeploymentNode("nodeL", ...$$[$0]); + this.$ = $$[$0]; + break; + case 34: + yy.addDeploymentNode("nodeR", ...$$[$0]); + this.$ = $$[$0]; + break; + case 35: + yy.popBoundaryParseStack(); + break; + case 39: + yy.addPersonOrSystem("person", ...$$[$0]); + this.$ = $$[$0]; + break; + case 40: + yy.addPersonOrSystem("external_person", ...$$[$0]); + this.$ = $$[$0]; + break; + case 41: + yy.addPersonOrSystem("system", ...$$[$0]); + this.$ = $$[$0]; + break; + case 42: + yy.addPersonOrSystem("system_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 43: + yy.addPersonOrSystem("system_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 44: + yy.addPersonOrSystem("external_system", ...$$[$0]); + this.$ = $$[$0]; + break; + case 45: + yy.addPersonOrSystem("external_system_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 46: + yy.addPersonOrSystem("external_system_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 47: + yy.addContainer("container", ...$$[$0]); + this.$ = $$[$0]; + break; + case 48: + yy.addContainer("container_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 49: + yy.addContainer("container_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 50: + yy.addContainer("external_container", ...$$[$0]); + this.$ = $$[$0]; + break; + case 51: + yy.addContainer("external_container_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 52: + yy.addContainer("external_container_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 53: + yy.addComponent("component", ...$$[$0]); + this.$ = $$[$0]; + break; + case 54: + yy.addComponent("component_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 55: + yy.addComponent("component_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 56: + yy.addComponent("external_component", ...$$[$0]); + this.$ = $$[$0]; + break; + case 57: + yy.addComponent("external_component_db", ...$$[$0]); + this.$ = $$[$0]; + break; + case 58: + yy.addComponent("external_component_queue", ...$$[$0]); + this.$ = $$[$0]; + break; + case 60: + yy.addRel("rel", ...$$[$0]); + this.$ = $$[$0]; + break; + case 61: + yy.addRel("birel", ...$$[$0]); + this.$ = $$[$0]; + break; + case 62: + yy.addRel("rel_u", ...$$[$0]); + this.$ = $$[$0]; + break; + case 63: + yy.addRel("rel_d", ...$$[$0]); + this.$ = $$[$0]; + break; + case 64: + yy.addRel("rel_l", ...$$[$0]); + this.$ = $$[$0]; + break; + case 65: + yy.addRel("rel_r", ...$$[$0]); + this.$ = $$[$0]; + break; + case 66: + yy.addRel("rel_b", ...$$[$0]); + this.$ = $$[$0]; + break; + case 67: + $$[$0].splice(0, 1); + yy.addRel("rel", ...$$[$0]); + this.$ = $$[$0]; + break; + case 68: + yy.updateElStyle("update_el_style", ...$$[$0]); + this.$ = $$[$0]; + break; + case 69: + yy.updateRelStyle("update_rel_style", ...$$[$0]); + this.$ = $$[$0]; + break; + case 70: + yy.updateLayoutConfig("update_layout_config", ...$$[$0]); + this.$ = $$[$0]; + break; + case 71: + this.$ = [$$[$0]]; + break; + case 72: + $$[$0].unshift($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 73: + case 75: + this.$ = $$[$0].trim(); + break; + case 74: + let kv = {}; + kv[$$[$0 - 1].trim()] = $$[$0].trim(); + this.$ = kv; + break; + case 76: + this.$ = ""; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: [1, 5], 7: [1, 6], 8: [1, 7], 9: [1, 8], 10: 4, 11: [1, 9], 15: [1, 10], 16: [1, 11], 17: [1, 12], 18: [1, 13] }, { 1: [3] }, { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 7] }, { 1: [2, 3] }, { 1: [2, 4] }, { 1: [2, 5] }, { 1: [2, 6] }, { 12: [1, 14] }, { 12: [1, 15] }, { 12: [1, 16] }, { 12: [1, 17] }, { 12: [1, 18] }, { 13: 19, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 13: 70, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 13: 71, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 13: 72, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 13: 73, 19: 20, 20: 21, 21: 22, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 14: [1, 74] }, o($VH, [2, 13], { 43: 23, 29: 49, 30: 61, 32: 62, 20: 75, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }), o($VH, [2, 14]), o($VI, [2, 16], { 12: [1, 76] }), o($VH, [2, 36], { 12: [1, 77] }), o($VJ, [2, 19]), o($VJ, [2, 20]), { 25: [1, 78] }, { 27: [1, 79] }, o($VJ, [2, 23]), { 35: 80, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 86, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 87, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 88, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 89, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 90, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 91, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 92, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 93, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 94, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 95, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 96, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 97, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 98, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 99, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 100, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 101, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 102, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 103, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 104, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, o($VO, [2, 59]), { 35: 105, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 106, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 107, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 108, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 109, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 110, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 111, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 112, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 113, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 114, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 115, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 20: 116, 29: 49, 30: 61, 32: 62, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 43: 23, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }, { 12: [1, 118], 33: [1, 117] }, { 35: 119, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 120, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 121, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 122, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 123, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 124, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 35: 125, 75: 81, 76: $VK, 77: $VL, 79: $VM, 80: $VN }, { 14: [1, 126] }, { 14: [1, 127] }, { 14: [1, 128] }, { 14: [1, 129] }, { 1: [2, 8] }, o($VH, [2, 15]), o($VI, [2, 17], { 21: 22, 19: 130, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4 }), o($VH, [2, 37], { 19: 20, 20: 21, 21: 22, 43: 23, 29: 49, 30: 61, 32: 62, 13: 131, 22: $V0, 23: $V1, 24: $V2, 26: $V3, 28: $V4, 34: $V5, 36: $V6, 37: $V7, 38: $V8, 39: $V9, 40: $Va, 41: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi, 51: $Vj, 52: $Vk, 53: $Vl, 54: $Vm, 55: $Vn, 56: $Vo, 57: $Vp, 58: $Vq, 59: $Vr, 60: $Vs, 61: $Vt, 62: $Vu, 63: $Vv, 64: $Vw, 65: $Vx, 66: $Vy, 67: $Vz, 68: $VA, 69: $VB, 70: $VC, 71: $VD, 72: $VE, 73: $VF, 74: $VG }), o($VJ, [2, 21]), o($VJ, [2, 22]), o($VO, [2, 39]), o($VP, [2, 71], { 75: 81, 35: 132, 76: $VK, 77: $VL, 79: $VM, 80: $VN }), o($VQ, [2, 73]), { 78: [1, 133] }, o($VQ, [2, 75]), o($VQ, [2, 76]), o($VO, [2, 40]), o($VO, [2, 41]), o($VO, [2, 42]), o($VO, [2, 43]), o($VO, [2, 44]), o($VO, [2, 45]), o($VO, [2, 46]), o($VO, [2, 47]), o($VO, [2, 48]), o($VO, [2, 49]), o($VO, [2, 50]), o($VO, [2, 51]), o($VO, [2, 52]), o($VO, [2, 53]), o($VO, [2, 54]), o($VO, [2, 55]), o($VO, [2, 56]), o($VO, [2, 57]), o($VO, [2, 58]), o($VO, [2, 60]), o($VO, [2, 61]), o($VO, [2, 62]), o($VO, [2, 63]), o($VO, [2, 64]), o($VO, [2, 65]), o($VO, [2, 66]), o($VO, [2, 67]), o($VO, [2, 68]), o($VO, [2, 69]), o($VO, [2, 70]), { 31: 134, 42: [1, 135] }, { 12: [1, 136] }, { 33: [1, 137] }, o($VR, [2, 28]), o($VR, [2, 29]), o($VR, [2, 30]), o($VR, [2, 31]), o($VR, [2, 32]), o($VR, [2, 33]), o($VR, [2, 34]), { 1: [2, 9] }, { 1: [2, 10] }, { 1: [2, 11] }, { 1: [2, 12] }, o($VI, [2, 18]), o($VH, [2, 38]), o($VP, [2, 72]), o($VQ, [2, 74]), o($VO, [2, 24]), o($VO, [2, 35]), o($VS, [2, 25]), o($VS, [2, 26], { 12: [1, 138] }), o($VS, [2, 27])], + defaultActions: { 2: [2, 1], 3: [2, 2], 4: [2, 7], 5: [2, 3], 6: [2, 4], 7: [2, 5], 8: [2, 6], 74: [2, 8], 126: [2, 9], 127: [2, 10], 128: [2, 11], 129: [2, 12] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c2 = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c2 + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 6; + case 1: + return 7; + case 2: + return 8; + case 3: + return 9; + case 4: + return 22; + case 5: + return 23; + case 6: + this.begin("acc_title"); + return 24; + case 7: + this.popState(); + return "acc_title_value"; + case 8: + this.begin("acc_descr"); + return 26; + case 9: + this.popState(); + return "acc_descr_value"; + case 10: + this.begin("acc_descr_multiline"); + break; + case 11: + this.popState(); + break; + case 12: + return "acc_descr_multiline_value"; + case 13: + break; + case 14: + c; + break; + case 15: + return 12; + case 16: + break; + case 17: + return 11; + case 18: + return 15; + case 19: + return 16; + case 20: + return 17; + case 21: + return 18; + case 22: + this.begin("person_ext"); + return 45; + case 23: + this.begin("person"); + return 44; + case 24: + this.begin("system_ext_queue"); + return 51; + case 25: + this.begin("system_ext_db"); + return 50; + case 26: + this.begin("system_ext"); + return 49; + case 27: + this.begin("system_queue"); + return 48; + case 28: + this.begin("system_db"); + return 47; + case 29: + this.begin("system"); + return 46; + case 30: + this.begin("boundary"); + return 37; + case 31: + this.begin("enterprise_boundary"); + return 34; + case 32: + this.begin("system_boundary"); + return 36; + case 33: + this.begin("container_ext_queue"); + return 57; + case 34: + this.begin("container_ext_db"); + return 56; + case 35: + this.begin("container_ext"); + return 55; + case 36: + this.begin("container_queue"); + return 54; + case 37: + this.begin("container_db"); + return 53; + case 38: + this.begin("container"); + return 52; + case 39: + this.begin("container_boundary"); + return 38; + case 40: + this.begin("component_ext_queue"); + return 63; + case 41: + this.begin("component_ext_db"); + return 62; + case 42: + this.begin("component_ext"); + return 61; + case 43: + this.begin("component_queue"); + return 60; + case 44: + this.begin("component_db"); + return 59; + case 45: + this.begin("component"); + return 58; + case 46: + this.begin("node"); + return 39; + case 47: + this.begin("node"); + return 39; + case 48: + this.begin("node_l"); + return 40; + case 49: + this.begin("node_r"); + return 41; + case 50: + this.begin("rel"); + return 64; + case 51: + this.begin("birel"); + return 65; + case 52: + this.begin("rel_u"); + return 66; + case 53: + this.begin("rel_u"); + return 66; + case 54: + this.begin("rel_d"); + return 67; + case 55: + this.begin("rel_d"); + return 67; + case 56: + this.begin("rel_l"); + return 68; + case 57: + this.begin("rel_l"); + return 68; + case 58: + this.begin("rel_r"); + return 69; + case 59: + this.begin("rel_r"); + return 69; + case 60: + this.begin("rel_b"); + return 70; + case 61: + this.begin("rel_index"); + return 71; + case 62: + this.begin("update_el_style"); + return 72; + case 63: + this.begin("update_rel_style"); + return 73; + case 64: + this.begin("update_layout_config"); + return 74; + case 65: + return "EOF_IN_STRUCT"; + case 66: + this.begin("attribute"); + return "ATTRIBUTE_EMPTY"; + case 67: + this.begin("attribute"); + break; + case 68: + this.popState(); + this.popState(); + break; + case 69: + return 80; + case 70: + break; + case 71: + return 80; + case 72: + this.begin("string"); + break; + case 73: + this.popState(); + break; + case 74: + return "STR"; + case 75: + this.begin("string_kv"); + break; + case 76: + this.begin("string_kv_key"); + return "STR_KEY"; + case 77: + this.popState(); + this.begin("string_kv_value"); + break; + case 78: + return "STR_VALUE"; + case 79: + this.popState(); + this.popState(); + break; + case 80: + return "STR"; + case 81: + return "LBRACE"; + case 82: + return "RBRACE"; + case 83: + return "SPACE"; + case 84: + return "EOL"; + case 85: + return 14; + } + }, + rules: [/^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:title\s[^#\n;]+)/, /^(?:accDescription\s[^#\n;]+)/, /^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/, /^(?:%%[^\n]*(\r?\n)*)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:C4Context\b)/, /^(?:C4Container\b)/, /^(?:C4Component\b)/, /^(?:C4Dynamic\b)/, /^(?:C4Deployment\b)/, /^(?:Person_Ext\b)/, /^(?:Person\b)/, /^(?:SystemQueue_Ext\b)/, /^(?:SystemDb_Ext\b)/, /^(?:System_Ext\b)/, /^(?:SystemQueue\b)/, /^(?:SystemDb\b)/, /^(?:System\b)/, /^(?:Boundary\b)/, /^(?:Enterprise_Boundary\b)/, /^(?:System_Boundary\b)/, /^(?:ContainerQueue_Ext\b)/, /^(?:ContainerDb_Ext\b)/, /^(?:Container_Ext\b)/, /^(?:ContainerQueue\b)/, /^(?:ContainerDb\b)/, /^(?:Container\b)/, /^(?:Container_Boundary\b)/, /^(?:ComponentQueue_Ext\b)/, /^(?:ComponentDb_Ext\b)/, /^(?:Component_Ext\b)/, /^(?:ComponentQueue\b)/, /^(?:ComponentDb\b)/, /^(?:Component\b)/, /^(?:Deployment_Node\b)/, /^(?:Node\b)/, /^(?:Node_L\b)/, /^(?:Node_R\b)/, /^(?:Rel\b)/, /^(?:BiRel\b)/, /^(?:Rel_Up\b)/, /^(?:Rel_U\b)/, /^(?:Rel_Down\b)/, /^(?:Rel_D\b)/, /^(?:Rel_Left\b)/, /^(?:Rel_L\b)/, /^(?:Rel_Right\b)/, /^(?:Rel_R\b)/, /^(?:Rel_Back\b)/, /^(?:RelIndex\b)/, /^(?:UpdateElementStyle\b)/, /^(?:UpdateRelStyle\b)/, /^(?:UpdateLayoutConfig\b)/, /^(?:$)/, /^(?:[(][ ]*[,])/, /^(?:[(])/, /^(?:[)])/, /^(?:,,)/, /^(?:,)/, /^(?:[ ]*["]["])/, /^(?:[ ]*["])/, /^(?:["])/, /^(?:[^"]*)/, /^(?:[ ]*[\$])/, /^(?:[^=]*)/, /^(?:[=][ ]*["])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:[^,]+)/, /^(?:\{)/, /^(?:\})/, /^(?:[\s]+)/, /^(?:[\n\r]+)/, /^(?:$)/], + conditions: { "acc_descr_multiline": { "rules": [11, 12], "inclusive": false }, "acc_descr": { "rules": [9], "inclusive": false }, "acc_title": { "rules": [7], "inclusive": false }, "string_kv_value": { "rules": [78, 79], "inclusive": false }, "string_kv_key": { "rules": [77], "inclusive": false }, "string_kv": { "rules": [76], "inclusive": false }, "string": { "rules": [73, 74], "inclusive": false }, "attribute": { "rules": [68, 69, 70, 71, 72, 75, 80], "inclusive": false }, "update_layout_config": { "rules": [65, 66, 67, 68], "inclusive": false }, "update_rel_style": { "rules": [65, 66, 67, 68], "inclusive": false }, "update_el_style": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_b": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_r": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_l": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_d": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_u": { "rules": [65, 66, 67, 68], "inclusive": false }, "rel_bi": { "rules": [], "inclusive": false }, "rel": { "rules": [65, 66, 67, 68], "inclusive": false }, "node_r": { "rules": [65, 66, 67, 68], "inclusive": false }, "node_l": { "rules": [65, 66, 67, 68], "inclusive": false }, "node": { "rules": [65, 66, 67, 68], "inclusive": false }, "index": { "rules": [], "inclusive": false }, "rel_index": { "rules": [65, 66, 67, 68], "inclusive": false }, "component_ext_queue": { "rules": [], "inclusive": false }, "component_ext_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "component_ext": { "rules": [65, 66, 67, 68], "inclusive": false }, "component_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "component_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "component": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_boundary": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_ext_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_ext_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_ext": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "container_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "container": { "rules": [65, 66, 67, 68], "inclusive": false }, "birel": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_boundary": { "rules": [65, 66, 67, 68], "inclusive": false }, "enterprise_boundary": { "rules": [65, 66, 67, 68], "inclusive": false }, "boundary": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_ext_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_ext_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_ext": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_queue": { "rules": [65, 66, 67, 68], "inclusive": false }, "system_db": { "rules": [65, 66, 67, 68], "inclusive": false }, "system": { "rules": [65, 66, 67, 68], "inclusive": false }, "person_ext": { "rules": [65, 66, 67, 68], "inclusive": false }, "person": { "rules": [65, 66, 67, 68], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 81, 82, 83, 84, 85], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let c4ShapeArray = []; +let boundaryParseStack = [""]; +let currentBoundaryParse = "global"; +let parentBoundaryParse = ""; +let boundarys = [ + { + alias: "global", + label: { text: "global" }, + type: { text: "global" }, + tags: null, + link: null, + parentBoundary: "" + } +]; +let rels = []; +let title = ""; +let wrapEnabled = false; +let c4ShapeInRow$1 = 4; +let c4BoundaryInRow$1 = 2; +var c4Type; +const getC4Type = function() { + return c4Type; +}; +const setC4Type = function(c4TypeParam) { + let sanitizedText = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.d)(c4TypeParam, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + c4Type = sanitizedText; +}; +const addRel = function(type, from, to, label, techn, descr, sprite, tags, link) { + if (type === void 0 || type === null || from === void 0 || from === null || to === void 0 || to === null || label === void 0 || label === null) { + return; + } + let rel = {}; + const old = rels.find((rel2) => rel2.from === from && rel2.to === to); + if (old) { + rel = old; + } else { + rels.push(rel); + } + rel.type = type; + rel.from = from; + rel.to = to; + rel.label = { text: label }; + if (techn === void 0 || techn === null) { + rel.techn = { text: "" }; + } else { + if (typeof techn === "object") { + let [key, value] = Object.entries(techn)[0]; + rel[key] = { text: value }; + } else { + rel.techn = { text: techn }; + } + } + if (descr === void 0 || descr === null) { + rel.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + rel[key] = { text: value }; + } else { + rel.descr = { text: descr }; + } + } + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + rel[key] = value; + } else { + rel.sprite = sprite; + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + rel[key] = value; + } else { + rel.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + rel[key] = value; + } else { + rel.link = link; + } + rel.wrap = autoWrap(); +}; +const addPersonOrSystem = function(typeC4Shape, alias, label, descr, sprite, tags, link) { + if (alias === null || label === null) { + return; + } + let personOrSystem = {}; + const old = c4ShapeArray.find((personOrSystem2) => personOrSystem2.alias === alias); + if (old && alias === old.alias) { + personOrSystem = old; + } else { + personOrSystem.alias = alias; + c4ShapeArray.push(personOrSystem); + } + if (label === void 0 || label === null) { + personOrSystem.label = { text: "" }; + } else { + personOrSystem.label = { text: label }; + } + if (descr === void 0 || descr === null) { + personOrSystem.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + personOrSystem[key] = { text: value }; + } else { + personOrSystem.descr = { text: descr }; + } + } + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + personOrSystem[key] = value; + } else { + personOrSystem.sprite = sprite; + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + personOrSystem[key] = value; + } else { + personOrSystem.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + personOrSystem[key] = value; + } else { + personOrSystem.link = link; + } + personOrSystem.typeC4Shape = { text: typeC4Shape }; + personOrSystem.parentBoundary = currentBoundaryParse; + personOrSystem.wrap = autoWrap(); +}; +const addContainer = function(typeC4Shape, alias, label, techn, descr, sprite, tags, link) { + if (alias === null || label === null) { + return; + } + let container = {}; + const old = c4ShapeArray.find((container2) => container2.alias === alias); + if (old && alias === old.alias) { + container = old; + } else { + container.alias = alias; + c4ShapeArray.push(container); + } + if (label === void 0 || label === null) { + container.label = { text: "" }; + } else { + container.label = { text: label }; + } + if (techn === void 0 || techn === null) { + container.techn = { text: "" }; + } else { + if (typeof techn === "object") { + let [key, value] = Object.entries(techn)[0]; + container[key] = { text: value }; + } else { + container.techn = { text: techn }; + } + } + if (descr === void 0 || descr === null) { + container.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + container[key] = { text: value }; + } else { + container.descr = { text: descr }; + } + } + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + container[key] = value; + } else { + container.sprite = sprite; + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + container[key] = value; + } else { + container.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + container[key] = value; + } else { + container.link = link; + } + container.wrap = autoWrap(); + container.typeC4Shape = { text: typeC4Shape }; + container.parentBoundary = currentBoundaryParse; +}; +const addComponent = function(typeC4Shape, alias, label, techn, descr, sprite, tags, link) { + if (alias === null || label === null) { + return; + } + let component = {}; + const old = c4ShapeArray.find((component2) => component2.alias === alias); + if (old && alias === old.alias) { + component = old; + } else { + component.alias = alias; + c4ShapeArray.push(component); + } + if (label === void 0 || label === null) { + component.label = { text: "" }; + } else { + component.label = { text: label }; + } + if (techn === void 0 || techn === null) { + component.techn = { text: "" }; + } else { + if (typeof techn === "object") { + let [key, value] = Object.entries(techn)[0]; + component[key] = { text: value }; + } else { + component.techn = { text: techn }; + } + } + if (descr === void 0 || descr === null) { + component.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + component[key] = { text: value }; + } else { + component.descr = { text: descr }; + } + } + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + component[key] = value; + } else { + component.sprite = sprite; + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + component[key] = value; + } else { + component.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + component[key] = value; + } else { + component.link = link; + } + component.wrap = autoWrap(); + component.typeC4Shape = { text: typeC4Shape }; + component.parentBoundary = currentBoundaryParse; +}; +const addPersonOrSystemBoundary = function(alias, label, type, tags, link) { + if (alias === null || label === null) { + return; + } + let boundary = {}; + const old = boundarys.find((boundary2) => boundary2.alias === alias); + if (old && alias === old.alias) { + boundary = old; + } else { + boundary.alias = alias; + boundarys.push(boundary); + } + if (label === void 0 || label === null) { + boundary.label = { text: "" }; + } else { + boundary.label = { text: label }; + } + if (type === void 0 || type === null) { + boundary.type = { text: "system" }; + } else { + if (typeof type === "object") { + let [key, value] = Object.entries(type)[0]; + boundary[key] = { text: value }; + } else { + boundary.type = { text: type }; + } + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + boundary[key] = value; + } else { + boundary.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + boundary[key] = value; + } else { + boundary.link = link; + } + boundary.parentBoundary = currentBoundaryParse; + boundary.wrap = autoWrap(); + parentBoundaryParse = currentBoundaryParse; + currentBoundaryParse = alias; + boundaryParseStack.push(parentBoundaryParse); +}; +const addContainerBoundary = function(alias, label, type, tags, link) { + if (alias === null || label === null) { + return; + } + let boundary = {}; + const old = boundarys.find((boundary2) => boundary2.alias === alias); + if (old && alias === old.alias) { + boundary = old; + } else { + boundary.alias = alias; + boundarys.push(boundary); + } + if (label === void 0 || label === null) { + boundary.label = { text: "" }; + } else { + boundary.label = { text: label }; + } + if (type === void 0 || type === null) { + boundary.type = { text: "container" }; + } else { + if (typeof type === "object") { + let [key, value] = Object.entries(type)[0]; + boundary[key] = { text: value }; + } else { + boundary.type = { text: type }; + } + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + boundary[key] = value; + } else { + boundary.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + boundary[key] = value; + } else { + boundary.link = link; + } + boundary.parentBoundary = currentBoundaryParse; + boundary.wrap = autoWrap(); + parentBoundaryParse = currentBoundaryParse; + currentBoundaryParse = alias; + boundaryParseStack.push(parentBoundaryParse); +}; +const addDeploymentNode = function(nodeType, alias, label, type, descr, sprite, tags, link) { + if (alias === null || label === null) { + return; + } + let boundary = {}; + const old = boundarys.find((boundary2) => boundary2.alias === alias); + if (old && alias === old.alias) { + boundary = old; + } else { + boundary.alias = alias; + boundarys.push(boundary); + } + if (label === void 0 || label === null) { + boundary.label = { text: "" }; + } else { + boundary.label = { text: label }; + } + if (type === void 0 || type === null) { + boundary.type = { text: "node" }; + } else { + if (typeof type === "object") { + let [key, value] = Object.entries(type)[0]; + boundary[key] = { text: value }; + } else { + boundary.type = { text: type }; + } + } + if (descr === void 0 || descr === null) { + boundary.descr = { text: "" }; + } else { + if (typeof descr === "object") { + let [key, value] = Object.entries(descr)[0]; + boundary[key] = { text: value }; + } else { + boundary.descr = { text: descr }; + } + } + if (typeof tags === "object") { + let [key, value] = Object.entries(tags)[0]; + boundary[key] = value; + } else { + boundary.tags = tags; + } + if (typeof link === "object") { + let [key, value] = Object.entries(link)[0]; + boundary[key] = value; + } else { + boundary.link = link; + } + boundary.nodeType = nodeType; + boundary.parentBoundary = currentBoundaryParse; + boundary.wrap = autoWrap(); + parentBoundaryParse = currentBoundaryParse; + currentBoundaryParse = alias; + boundaryParseStack.push(parentBoundaryParse); +}; +const popBoundaryParseStack = function() { + currentBoundaryParse = parentBoundaryParse; + boundaryParseStack.pop(); + parentBoundaryParse = boundaryParseStack.pop(); + boundaryParseStack.push(parentBoundaryParse); +}; +const updateElStyle = function(typeC4Shape, elementName, bgColor, fontColor, borderColor, shadowing, shape, sprite, techn, legendText, legendSprite) { + let old = c4ShapeArray.find((element) => element.alias === elementName); + if (old === void 0) { + old = boundarys.find((element) => element.alias === elementName); + if (old === void 0) { + return; + } + } + if (bgColor !== void 0 && bgColor !== null) { + if (typeof bgColor === "object") { + let [key, value] = Object.entries(bgColor)[0]; + old[key] = value; + } else { + old.bgColor = bgColor; + } + } + if (fontColor !== void 0 && fontColor !== null) { + if (typeof fontColor === "object") { + let [key, value] = Object.entries(fontColor)[0]; + old[key] = value; + } else { + old.fontColor = fontColor; + } + } + if (borderColor !== void 0 && borderColor !== null) { + if (typeof borderColor === "object") { + let [key, value] = Object.entries(borderColor)[0]; + old[key] = value; + } else { + old.borderColor = borderColor; + } + } + if (shadowing !== void 0 && shadowing !== null) { + if (typeof shadowing === "object") { + let [key, value] = Object.entries(shadowing)[0]; + old[key] = value; + } else { + old.shadowing = shadowing; + } + } + if (shape !== void 0 && shape !== null) { + if (typeof shape === "object") { + let [key, value] = Object.entries(shape)[0]; + old[key] = value; + } else { + old.shape = shape; + } + } + if (sprite !== void 0 && sprite !== null) { + if (typeof sprite === "object") { + let [key, value] = Object.entries(sprite)[0]; + old[key] = value; + } else { + old.sprite = sprite; + } + } + if (techn !== void 0 && techn !== null) { + if (typeof techn === "object") { + let [key, value] = Object.entries(techn)[0]; + old[key] = value; + } else { + old.techn = techn; + } + } + if (legendText !== void 0 && legendText !== null) { + if (typeof legendText === "object") { + let [key, value] = Object.entries(legendText)[0]; + old[key] = value; + } else { + old.legendText = legendText; + } + } + if (legendSprite !== void 0 && legendSprite !== null) { + if (typeof legendSprite === "object") { + let [key, value] = Object.entries(legendSprite)[0]; + old[key] = value; + } else { + old.legendSprite = legendSprite; + } + } +}; +const updateRelStyle = function(typeC4Shape, from, to, textColor, lineColor, offsetX, offsetY) { + const old = rels.find((rel) => rel.from === from && rel.to === to); + if (old === void 0) { + return; + } + if (textColor !== void 0 && textColor !== null) { + if (typeof textColor === "object") { + let [key, value] = Object.entries(textColor)[0]; + old[key] = value; + } else { + old.textColor = textColor; + } + } + if (lineColor !== void 0 && lineColor !== null) { + if (typeof lineColor === "object") { + let [key, value] = Object.entries(lineColor)[0]; + old[key] = value; + } else { + old.lineColor = lineColor; + } + } + if (offsetX !== void 0 && offsetX !== null) { + if (typeof offsetX === "object") { + let [key, value] = Object.entries(offsetX)[0]; + old[key] = parseInt(value); + } else { + old.offsetX = parseInt(offsetX); + } + } + if (offsetY !== void 0 && offsetY !== null) { + if (typeof offsetY === "object") { + let [key, value] = Object.entries(offsetY)[0]; + old[key] = parseInt(value); + } else { + old.offsetY = parseInt(offsetY); + } + } +}; +const updateLayoutConfig = function(typeC4Shape, c4ShapeInRowParam, c4BoundaryInRowParam) { + let c4ShapeInRowValue = c4ShapeInRow$1; + let c4BoundaryInRowValue = c4BoundaryInRow$1; + if (typeof c4ShapeInRowParam === "object") { + const value = Object.values(c4ShapeInRowParam)[0]; + c4ShapeInRowValue = parseInt(value); + } else { + c4ShapeInRowValue = parseInt(c4ShapeInRowParam); + } + if (typeof c4BoundaryInRowParam === "object") { + const value = Object.values(c4BoundaryInRowParam)[0]; + c4BoundaryInRowValue = parseInt(value); + } else { + c4BoundaryInRowValue = parseInt(c4BoundaryInRowParam); + } + if (c4ShapeInRowValue >= 1) { + c4ShapeInRow$1 = c4ShapeInRowValue; + } + if (c4BoundaryInRowValue >= 1) { + c4BoundaryInRow$1 = c4BoundaryInRowValue; + } +}; +const getC4ShapeInRow = function() { + return c4ShapeInRow$1; +}; +const getC4BoundaryInRow = function() { + return c4BoundaryInRow$1; +}; +const getCurrentBoundaryParse = function() { + return currentBoundaryParse; +}; +const getParentBoundaryParse = function() { + return parentBoundaryParse; +}; +const getC4ShapeArray = function(parentBoundary) { + if (parentBoundary === void 0 || parentBoundary === null) { + return c4ShapeArray; + } else { + return c4ShapeArray.filter((personOrSystem) => { + return personOrSystem.parentBoundary === parentBoundary; + }); + } +}; +const getC4Shape = function(alias) { + return c4ShapeArray.find((personOrSystem) => personOrSystem.alias === alias); +}; +const getC4ShapeKeys = function(parentBoundary) { + return Object.keys(getC4ShapeArray(parentBoundary)); +}; +const getBoundarys = function(parentBoundary) { + if (parentBoundary === void 0 || parentBoundary === null) { + return boundarys; + } else { + return boundarys.filter((boundary) => boundary.parentBoundary === parentBoundary); + } +}; +const getRels = function() { + return rels; +}; +const getTitle = function() { + return title; +}; +const setWrap = function(wrapSetting) { + wrapEnabled = wrapSetting; +}; +const autoWrap = function() { + return wrapEnabled; +}; +const clear = function() { + c4ShapeArray = []; + boundarys = [ + { + alias: "global", + label: { text: "global" }, + type: { text: "global" }, + tags: null, + link: null, + parentBoundary: "" + } + ]; + parentBoundaryParse = ""; + currentBoundaryParse = "global"; + boundaryParseStack = [""]; + rels = []; + boundaryParseStack = [""]; + title = ""; + wrapEnabled = false; + c4ShapeInRow$1 = 4; + c4BoundaryInRow$1 = 2; +}; +const LINETYPE = { + SOLID: 0, + DOTTED: 1, + NOTE: 2, + SOLID_CROSS: 3, + DOTTED_CROSS: 4, + SOLID_OPEN: 5, + DOTTED_OPEN: 6, + LOOP_START: 10, + LOOP_END: 11, + ALT_START: 12, + ALT_ELSE: 13, + ALT_END: 14, + OPT_START: 15, + OPT_END: 16, + ACTIVE_START: 17, + ACTIVE_END: 18, + PAR_START: 19, + PAR_AND: 20, + PAR_END: 21, + RECT_START: 22, + RECT_END: 23, + SOLID_POINT: 24, + DOTTED_POINT: 25 +}; +const ARROWTYPE = { + FILLED: 0, + OPEN: 1 +}; +const PLACEMENT = { + LEFTOF: 0, + RIGHTOF: 1, + OVER: 2 +}; +const setTitle = function(txt) { + let sanitizedText = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.d)(txt, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + title = sanitizedText; +}; +const db = { + addPersonOrSystem, + addPersonOrSystemBoundary, + addContainer, + addContainerBoundary, + addComponent, + addDeploymentNode, + popBoundaryParseStack, + addRel, + updateElStyle, + updateRelStyle, + updateLayoutConfig, + autoWrap, + setWrap, + getC4ShapeArray, + getC4Shape, + getC4ShapeKeys, + getBoundarys, + getCurrentBoundaryParse, + getParentBoundaryParse, + getRels, + getTitle, + getC4Type, + getC4ShapeInRow, + getC4BoundaryInRow, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.g, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.b, + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().c4, + clear, + LINETYPE, + ARROWTYPE, + PLACEMENT, + setTitle, + setC4Type + // apply, +}; +const drawRect = function(elem, rectData) { + return (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.d)(elem, rectData); +}; +const drawImage = function(elem, width, height, x, y, link) { + const imageElem = elem.append("image"); + imageElem.attr("width", width); + imageElem.attr("height", height); + imageElem.attr("x", x); + imageElem.attr("y", y); + let sanitizedLink = link.startsWith("data:image/png;base64") ? link : (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__/* .sanitizeUrl */ .Nm)(link); + imageElem.attr("xlink:href", sanitizedLink); +}; +const drawRels$1 = (elem, rels2, conf2) => { + const relsElem = elem.append("g"); + let i = 0; + for (let rel of rels2) { + let textColor = rel.textColor ? rel.textColor : "#444444"; + let strokeColor = rel.lineColor ? rel.lineColor : "#444444"; + let offsetX = rel.offsetX ? parseInt(rel.offsetX) : 0; + let offsetY = rel.offsetY ? parseInt(rel.offsetY) : 0; + let url = ""; + if (i === 0) { + let line = relsElem.append("line"); + line.attr("x1", rel.startPoint.x); + line.attr("y1", rel.startPoint.y); + line.attr("x2", rel.endPoint.x); + line.attr("y2", rel.endPoint.y); + line.attr("stroke-width", "1"); + line.attr("stroke", strokeColor); + line.style("fill", "none"); + if (rel.type !== "rel_b") { + line.attr("marker-end", "url(" + url + "#arrowhead)"); + } + if (rel.type === "birel" || rel.type === "rel_b") { + line.attr("marker-start", "url(" + url + "#arrowend)"); + } + i = -1; + } else { + let line = relsElem.append("path"); + line.attr("fill", "none").attr("stroke-width", "1").attr("stroke", strokeColor).attr( + "d", + "Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx", rel.startPoint.x).replaceAll("starty", rel.startPoint.y).replaceAll( + "controlx", + rel.startPoint.x + (rel.endPoint.x - rel.startPoint.x) / 2 - (rel.endPoint.x - rel.startPoint.x) / 4 + ).replaceAll("controly", rel.startPoint.y + (rel.endPoint.y - rel.startPoint.y) / 2).replaceAll("stopx", rel.endPoint.x).replaceAll("stopy", rel.endPoint.y) + ); + if (rel.type !== "rel_b") { + line.attr("marker-end", "url(" + url + "#arrowhead)"); + } + if (rel.type === "birel" || rel.type === "rel_b") { + line.attr("marker-start", "url(" + url + "#arrowend)"); + } + } + let messageConf = conf2.messageFont(); + _drawTextCandidateFunc(conf2)( + rel.label.text, + relsElem, + Math.min(rel.startPoint.x, rel.endPoint.x) + Math.abs(rel.endPoint.x - rel.startPoint.x) / 2 + offsetX, + Math.min(rel.startPoint.y, rel.endPoint.y) + Math.abs(rel.endPoint.y - rel.startPoint.y) / 2 + offsetY, + rel.label.width, + rel.label.height, + { fill: textColor }, + messageConf + ); + if (rel.techn && rel.techn.text !== "") { + messageConf = conf2.messageFont(); + _drawTextCandidateFunc(conf2)( + "[" + rel.techn.text + "]", + relsElem, + Math.min(rel.startPoint.x, rel.endPoint.x) + Math.abs(rel.endPoint.x - rel.startPoint.x) / 2 + offsetX, + Math.min(rel.startPoint.y, rel.endPoint.y) + Math.abs(rel.endPoint.y - rel.startPoint.y) / 2 + conf2.messageFontSize + 5 + offsetY, + Math.max(rel.label.width, rel.techn.width), + rel.techn.height, + { fill: textColor, "font-style": "italic" }, + messageConf + ); + } + } +}; +const drawBoundary$1 = function(elem, boundary, conf2) { + const boundaryElem = elem.append("g"); + let fillColor = boundary.bgColor ? boundary.bgColor : "none"; + let strokeColor = boundary.borderColor ? boundary.borderColor : "#444444"; + let fontColor = boundary.fontColor ? boundary.fontColor : "black"; + let attrsValue = { "stroke-width": 1, "stroke-dasharray": "7.0,7.0" }; + if (boundary.nodeType) { + attrsValue = { "stroke-width": 1 }; + } + let rectData = { + x: boundary.x, + y: boundary.y, + fill: fillColor, + stroke: strokeColor, + width: boundary.width, + height: boundary.height, + rx: 2.5, + ry: 2.5, + attrs: attrsValue + }; + drawRect(boundaryElem, rectData); + let boundaryConf = conf2.boundaryFont(); + boundaryConf.fontWeight = "bold"; + boundaryConf.fontSize = boundaryConf.fontSize + 2; + boundaryConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + boundary.label.text, + boundaryElem, + boundary.x, + boundary.y + boundary.label.Y, + boundary.width, + boundary.height, + { fill: "#444444" }, + boundaryConf + ); + if (boundary.type && boundary.type.text !== "") { + boundaryConf = conf2.boundaryFont(); + boundaryConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + boundary.type.text, + boundaryElem, + boundary.x, + boundary.y + boundary.type.Y, + boundary.width, + boundary.height, + { fill: "#444444" }, + boundaryConf + ); + } + if (boundary.descr && boundary.descr.text !== "") { + boundaryConf = conf2.boundaryFont(); + boundaryConf.fontSize = boundaryConf.fontSize - 2; + boundaryConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + boundary.descr.text, + boundaryElem, + boundary.x, + boundary.y + boundary.descr.Y, + boundary.width, + boundary.height, + { fill: "#444444" }, + boundaryConf + ); + } +}; +const drawC4Shape = function(elem, c4Shape, conf2) { + var _a; + let fillColor = c4Shape.bgColor ? c4Shape.bgColor : conf2[c4Shape.typeC4Shape.text + "_bg_color"]; + let strokeColor = c4Shape.borderColor ? c4Shape.borderColor : conf2[c4Shape.typeC4Shape.text + "_border_color"]; + let fontColor = c4Shape.fontColor ? c4Shape.fontColor : "#FFFFFF"; + let personImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII="; + switch (c4Shape.typeC4Shape.text) { + case "person": + personImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII="; + break; + case "external_person": + personImg = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII="; + break; + } + const c4ShapeElem = elem.append("g"); + c4ShapeElem.attr("class", "person-man"); + const rect = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + switch (c4Shape.typeC4Shape.text) { + case "person": + case "external_person": + case "system": + case "external_system": + case "container": + case "external_container": + case "component": + case "external_component": + rect.x = c4Shape.x; + rect.y = c4Shape.y; + rect.fill = fillColor; + rect.width = c4Shape.width; + rect.height = c4Shape.height; + rect.stroke = strokeColor; + rect.rx = 2.5; + rect.ry = 2.5; + rect.attrs = { "stroke-width": 0.5 }; + drawRect(c4ShapeElem, rect); + break; + case "system_db": + case "external_system_db": + case "container_db": + case "external_container_db": + case "component_db": + case "external_component_db": + c4ShapeElem.append("path").attr("fill", fillColor).attr("stroke-width", "0.5").attr("stroke", strokeColor).attr( + "d", + "Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx", c4Shape.x).replaceAll("starty", c4Shape.y).replaceAll("half", c4Shape.width / 2).replaceAll("height", c4Shape.height) + ); + c4ShapeElem.append("path").attr("fill", "none").attr("stroke-width", "0.5").attr("stroke", strokeColor).attr( + "d", + "Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx", c4Shape.x).replaceAll("starty", c4Shape.y).replaceAll("half", c4Shape.width / 2) + ); + break; + case "system_queue": + case "external_system_queue": + case "container_queue": + case "external_container_queue": + case "component_queue": + case "external_component_queue": + c4ShapeElem.append("path").attr("fill", fillColor).attr("stroke-width", "0.5").attr("stroke", strokeColor).attr( + "d", + "Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx", c4Shape.x).replaceAll("starty", c4Shape.y).replaceAll("width", c4Shape.width).replaceAll("half", c4Shape.height / 2) + ); + c4ShapeElem.append("path").attr("fill", "none").attr("stroke-width", "0.5").attr("stroke", strokeColor).attr( + "d", + "Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx", c4Shape.x + c4Shape.width).replaceAll("starty", c4Shape.y).replaceAll("half", c4Shape.height / 2) + ); + break; + } + let c4ShapeFontConf = getC4ShapeFont(conf2, c4Shape.typeC4Shape.text); + c4ShapeElem.append("text").attr("fill", fontColor).attr("font-family", c4ShapeFontConf.fontFamily).attr("font-size", c4ShapeFontConf.fontSize - 2).attr("font-style", "italic").attr("lengthAdjust", "spacing").attr("textLength", c4Shape.typeC4Shape.width).attr("x", c4Shape.x + c4Shape.width / 2 - c4Shape.typeC4Shape.width / 2).attr("y", c4Shape.y + c4Shape.typeC4Shape.Y).text("<<" + c4Shape.typeC4Shape.text + ">>"); + switch (c4Shape.typeC4Shape.text) { + case "person": + case "external_person": + drawImage( + c4ShapeElem, + 48, + 48, + c4Shape.x + c4Shape.width / 2 - 24, + c4Shape.y + c4Shape.image.Y, + personImg + ); + break; + } + let textFontConf = conf2[c4Shape.typeC4Shape.text + "Font"](); + textFontConf.fontWeight = "bold"; + textFontConf.fontSize = textFontConf.fontSize + 2; + textFontConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + c4Shape.label.text, + c4ShapeElem, + c4Shape.x, + c4Shape.y + c4Shape.label.Y, + c4Shape.width, + c4Shape.height, + { fill: fontColor }, + textFontConf + ); + textFontConf = conf2[c4Shape.typeC4Shape.text + "Font"](); + textFontConf.fontColor = fontColor; + if (c4Shape.techn && ((_a = c4Shape.techn) == null ? void 0 : _a.text) !== "") { + _drawTextCandidateFunc(conf2)( + c4Shape.techn.text, + c4ShapeElem, + c4Shape.x, + c4Shape.y + c4Shape.techn.Y, + c4Shape.width, + c4Shape.height, + { fill: fontColor, "font-style": "italic" }, + textFontConf + ); + } else if (c4Shape.type && c4Shape.type.text !== "") { + _drawTextCandidateFunc(conf2)( + c4Shape.type.text, + c4ShapeElem, + c4Shape.x, + c4Shape.y + c4Shape.type.Y, + c4Shape.width, + c4Shape.height, + { fill: fontColor, "font-style": "italic" }, + textFontConf + ); + } + if (c4Shape.descr && c4Shape.descr.text !== "") { + textFontConf = conf2.personFont(); + textFontConf.fontColor = fontColor; + _drawTextCandidateFunc(conf2)( + c4Shape.descr.text, + c4ShapeElem, + c4Shape.x, + c4Shape.y + c4Shape.descr.Y, + c4Shape.width, + c4Shape.height, + { fill: fontColor }, + textFontConf + ); + } + return c4Shape.height; +}; +const insertDatabaseIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "database").attr("fill-rule", "evenodd").attr("clip-rule", "evenodd").append("path").attr("transform", "scale(.5)").attr( + "d", + "M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z" + ); +}; +const insertComputerIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "computer").attr("width", "24").attr("height", "24").append("path").attr("transform", "scale(.5)").attr( + "d", + "M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z" + ); +}; +const insertClockIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "clock").attr("width", "24").attr("height", "24").append("path").attr("transform", "scale(.5)").attr( + "d", + "M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z" + ); +}; +const insertArrowHead = function(elem) { + elem.append("defs").append("marker").attr("id", "arrowhead").attr("refX", 9).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z"); +}; +const insertArrowEnd = function(elem) { + elem.append("defs").append("marker").attr("id", "arrowend").attr("refX", 1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 10 0 L 0 5 L 10 10 z"); +}; +const insertArrowFilledHead = function(elem) { + elem.append("defs").append("marker").attr("id", "filled-head").attr("refX", 18).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const insertDynamicNumber = function(elem) { + elem.append("defs").append("marker").attr("id", "sequencenumber").attr("refX", 15).attr("refY", 15).attr("markerWidth", 60).attr("markerHeight", 40).attr("orient", "auto").append("circle").attr("cx", 15).attr("cy", 15).attr("r", 6); +}; +const insertArrowCrossHead = function(elem) { + const defs = elem.append("defs"); + const marker = defs.append("marker").attr("id", "crosshead").attr("markerWidth", 15).attr("markerHeight", 8).attr("orient", "auto").attr("refX", 16).attr("refY", 4); + marker.append("path").attr("fill", "black").attr("stroke", "#000000").style("stroke-dasharray", "0, 0").attr("stroke-width", "1px").attr("d", "M 9,2 V 6 L16,4 Z"); + marker.append("path").attr("fill", "none").attr("stroke", "#000000").style("stroke-dasharray", "0, 0").attr("stroke-width", "1px").attr("d", "M 0,1 L 6,7 M 6,1 L 0,7"); +}; +const getC4ShapeFont = (cnf, typeC4Shape) => { + return { + fontFamily: cnf[typeC4Shape + "FontFamily"], + fontSize: cnf[typeC4Shape + "FontSize"], + fontWeight: cnf[typeC4Shape + "FontWeight"] + }; +}; +const _drawTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs) { + const text = g.append("text").attr("x", x + width / 2).attr("y", y + height / 2 + 5).style("text-anchor", "middle").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf2) { + const { fontSize, fontFamily, fontWeight } = conf2; + const lines = content.split(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + for (let i = 0; i < lines.length; i++) { + const dy = i * fontSize - fontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x + width / 2).attr("y", y).style("text-anchor", "middle").attr("dominant-baseline", "middle").style("font-size", fontSize).style("font-weight", fontWeight).style("font-family", fontFamily); + text.append("tspan").attr("dy", dy).text(lines[i]).attr("alignment-baseline", "mathematical"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf2) { + const s = g.append("switch"); + const f = s.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, s, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (fromTextAttrsDict.hasOwnProperty(key)) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf2) { + return conf2.textPlacement === "fo" ? byFo : conf2.textPlacement === "old" ? byText : byTspan; + }; +}(); +const svgDraw = { + drawRect, + drawBoundary: drawBoundary$1, + drawC4Shape, + drawRels: drawRels$1, + drawImage, + insertArrowHead, + insertArrowEnd, + insertArrowFilledHead, + insertDynamicNumber, + insertArrowCrossHead, + insertDatabaseIcon, + insertComputerIcon, + insertClockIcon +}; +let globalBoundaryMaxX = 0, globalBoundaryMaxY = 0; +let c4ShapeInRow = 4; +let c4BoundaryInRow = 2; +parser.yy = db; +let conf = {}; +class Bounds { + constructor(diagObj) { + this.name = ""; + this.data = {}; + this.data.startx = void 0; + this.data.stopx = void 0; + this.data.starty = void 0; + this.data.stopy = void 0; + this.data.widthLimit = void 0; + this.nextData = {}; + this.nextData.startx = void 0; + this.nextData.stopx = void 0; + this.nextData.starty = void 0; + this.nextData.stopy = void 0; + this.nextData.cnt = 0; + setConf(diagObj.db.getConfig()); + } + setData(startx, stopx, starty, stopy) { + this.nextData.startx = this.data.startx = startx; + this.nextData.stopx = this.data.stopx = stopx; + this.nextData.starty = this.data.starty = starty; + this.nextData.stopy = this.data.stopy = stopy; + } + updateVal(obj, key, val, fun) { + if (obj[key] === void 0) { + obj[key] = val; + } else { + obj[key] = fun(val, obj[key]); + } + } + insert(c4Shape) { + this.nextData.cnt = this.nextData.cnt + 1; + let _startx = this.nextData.startx === this.nextData.stopx ? this.nextData.stopx + c4Shape.margin : this.nextData.stopx + c4Shape.margin * 2; + let _stopx = _startx + c4Shape.width; + let _starty = this.nextData.starty + c4Shape.margin * 2; + let _stopy = _starty + c4Shape.height; + if (_startx >= this.data.widthLimit || _stopx >= this.data.widthLimit || this.nextData.cnt > c4ShapeInRow) { + _startx = this.nextData.startx + c4Shape.margin + conf.nextLinePaddingX; + _starty = this.nextData.stopy + c4Shape.margin * 2; + this.nextData.stopx = _stopx = _startx + c4Shape.width; + this.nextData.starty = this.nextData.stopy; + this.nextData.stopy = _stopy = _starty + c4Shape.height; + this.nextData.cnt = 1; + } + c4Shape.x = _startx; + c4Shape.y = _starty; + this.updateVal(this.data, "startx", _startx, Math.min); + this.updateVal(this.data, "starty", _starty, Math.min); + this.updateVal(this.data, "stopx", _stopx, Math.max); + this.updateVal(this.data, "stopy", _stopy, Math.max); + this.updateVal(this.nextData, "startx", _startx, Math.min); + this.updateVal(this.nextData, "starty", _starty, Math.min); + this.updateVal(this.nextData, "stopx", _stopx, Math.max); + this.updateVal(this.nextData, "stopy", _stopy, Math.max); + } + init(diagObj) { + this.name = ""; + this.data = { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0, + widthLimit: void 0 + }; + this.nextData = { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0, + cnt: 0 + }; + setConf(diagObj.db.getConfig()); + } + bumpLastMargin(margin) { + this.data.stopx += margin; + this.data.stopy += margin; + } +} +const setConf = function(cnf) { + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.f)(conf, cnf); + if (cnf.fontFamily) { + conf.personFontFamily = conf.systemFontFamily = conf.messageFontFamily = cnf.fontFamily; + } + if (cnf.fontSize) { + conf.personFontSize = conf.systemFontSize = conf.messageFontSize = cnf.fontSize; + } + if (cnf.fontWeight) { + conf.personFontWeight = conf.systemFontWeight = conf.messageFontWeight = cnf.fontWeight; + } +}; +const c4ShapeFont = (cnf, typeC4Shape) => { + return { + fontFamily: cnf[typeC4Shape + "FontFamily"], + fontSize: cnf[typeC4Shape + "FontSize"], + fontWeight: cnf[typeC4Shape + "FontWeight"] + }; +}; +const boundaryFont = (cnf) => { + return { + fontFamily: cnf.boundaryFontFamily, + fontSize: cnf.boundaryFontSize, + fontWeight: cnf.boundaryFontWeight + }; +}; +const messageFont = (cnf) => { + return { + fontFamily: cnf.messageFontFamily, + fontSize: cnf.messageFontSize, + fontWeight: cnf.messageFontWeight + }; +}; +function calcC4ShapeTextWH(textType, c4Shape, c4ShapeTextWrap, textConf, textLimitWidth) { + if (!c4Shape[textType].width) { + if (c4ShapeTextWrap) { + c4Shape[textType].text = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.w)(c4Shape[textType].text, textLimitWidth, textConf); + c4Shape[textType].textLines = c4Shape[textType].text.split(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex).length; + c4Shape[textType].width = textLimitWidth; + c4Shape[textType].height = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.j)(c4Shape[textType].text, textConf); + } else { + let lines = c4Shape[textType].text.split(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + c4Shape[textType].textLines = lines.length; + let lineHeight = 0; + c4Shape[textType].height = 0; + c4Shape[textType].width = 0; + for (const line of lines) { + c4Shape[textType].width = Math.max( + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.h)(line, textConf), + c4Shape[textType].width + ); + lineHeight = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.j)(line, textConf); + c4Shape[textType].height = c4Shape[textType].height + lineHeight; + } + } + } +} +const drawBoundary = function(diagram2, boundary, bounds) { + boundary.x = bounds.data.startx; + boundary.y = bounds.data.starty; + boundary.width = bounds.data.stopx - bounds.data.startx; + boundary.height = bounds.data.stopy - bounds.data.starty; + boundary.label.y = conf.c4ShapeMargin - 35; + let boundaryTextWrap = boundary.wrap && conf.wrap; + let boundaryLabelConf = boundaryFont(conf); + boundaryLabelConf.fontSize = boundaryLabelConf.fontSize + 2; + boundaryLabelConf.fontWeight = "bold"; + let textLimitWidth = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.h)(boundary.label.text, boundaryLabelConf); + calcC4ShapeTextWH("label", boundary, boundaryTextWrap, boundaryLabelConf, textLimitWidth); + svgDraw.drawBoundary(diagram2, boundary, conf); +}; +const drawC4ShapeArray = function(currentBounds, diagram2, c4ShapeArray2, c4ShapeKeys) { + let Y = 0; + for (const c4ShapeKey of c4ShapeKeys) { + Y = 0; + const c4Shape = c4ShapeArray2[c4ShapeKey]; + let c4ShapeTypeConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text); + c4ShapeTypeConf.fontSize = c4ShapeTypeConf.fontSize - 2; + c4Shape.typeC4Shape.width = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.h)( + "«" + c4Shape.typeC4Shape.text + "»", + c4ShapeTypeConf + ); + c4Shape.typeC4Shape.height = c4ShapeTypeConf.fontSize + 2; + c4Shape.typeC4Shape.Y = conf.c4ShapePadding; + Y = c4Shape.typeC4Shape.Y + c4Shape.typeC4Shape.height - 4; + c4Shape.image = { width: 0, height: 0, Y: 0 }; + switch (c4Shape.typeC4Shape.text) { + case "person": + case "external_person": + c4Shape.image.width = 48; + c4Shape.image.height = 48; + c4Shape.image.Y = Y; + Y = c4Shape.image.Y + c4Shape.image.height; + break; + } + if (c4Shape.sprite) { + c4Shape.image.width = 48; + c4Shape.image.height = 48; + c4Shape.image.Y = Y; + Y = c4Shape.image.Y + c4Shape.image.height; + } + let c4ShapeTextWrap = c4Shape.wrap && conf.wrap; + let textLimitWidth = conf.width - conf.c4ShapePadding * 2; + let c4ShapeLabelConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text); + c4ShapeLabelConf.fontSize = c4ShapeLabelConf.fontSize + 2; + c4ShapeLabelConf.fontWeight = "bold"; + calcC4ShapeTextWH("label", c4Shape, c4ShapeTextWrap, c4ShapeLabelConf, textLimitWidth); + c4Shape["label"].Y = Y + 8; + Y = c4Shape["label"].Y + c4Shape["label"].height; + if (c4Shape.type && c4Shape.type.text !== "") { + c4Shape.type.text = "[" + c4Shape.type.text + "]"; + let c4ShapeTypeConf2 = c4ShapeFont(conf, c4Shape.typeC4Shape.text); + calcC4ShapeTextWH("type", c4Shape, c4ShapeTextWrap, c4ShapeTypeConf2, textLimitWidth); + c4Shape["type"].Y = Y + 5; + Y = c4Shape["type"].Y + c4Shape["type"].height; + } else if (c4Shape.techn && c4Shape.techn.text !== "") { + c4Shape.techn.text = "[" + c4Shape.techn.text + "]"; + let c4ShapeTechnConf = c4ShapeFont(conf, c4Shape.techn.text); + calcC4ShapeTextWH("techn", c4Shape, c4ShapeTextWrap, c4ShapeTechnConf, textLimitWidth); + c4Shape["techn"].Y = Y + 5; + Y = c4Shape["techn"].Y + c4Shape["techn"].height; + } + let rectHeight = Y; + let rectWidth = c4Shape.label.width; + if (c4Shape.descr && c4Shape.descr.text !== "") { + let c4ShapeDescrConf = c4ShapeFont(conf, c4Shape.typeC4Shape.text); + calcC4ShapeTextWH("descr", c4Shape, c4ShapeTextWrap, c4ShapeDescrConf, textLimitWidth); + c4Shape["descr"].Y = Y + 20; + Y = c4Shape["descr"].Y + c4Shape["descr"].height; + rectWidth = Math.max(c4Shape.label.width, c4Shape.descr.width); + rectHeight = Y - c4Shape["descr"].textLines * 5; + } + rectWidth = rectWidth + conf.c4ShapePadding; + c4Shape.width = Math.max(c4Shape.width || conf.width, rectWidth, conf.width); + c4Shape.height = Math.max(c4Shape.height || conf.height, rectHeight, conf.height); + c4Shape.margin = c4Shape.margin || conf.c4ShapeMargin; + currentBounds.insert(c4Shape); + svgDraw.drawC4Shape(diagram2, c4Shape, conf); + } + currentBounds.bumpLastMargin(conf.c4ShapeMargin); +}; +class Point { + constructor(x, y) { + this.x = x; + this.y = y; + } +} +let getIntersectPoint = function(fromNode, endPoint) { + let x1 = fromNode.x; + let y1 = fromNode.y; + let x2 = endPoint.x; + let y2 = endPoint.y; + let fromCenterX = x1 + fromNode.width / 2; + let fromCenterY = y1 + fromNode.height / 2; + let dx = Math.abs(x1 - x2); + let dy = Math.abs(y1 - y2); + let tanDYX = dy / dx; + let fromDYX = fromNode.height / fromNode.width; + let returnPoint = null; + if (y1 == y2 && x1 < x2) { + returnPoint = new Point(x1 + fromNode.width, fromCenterY); + } else if (y1 == y2 && x1 > x2) { + returnPoint = new Point(x1, fromCenterY); + } else if (x1 == x2 && y1 < y2) { + returnPoint = new Point(fromCenterX, y1 + fromNode.height); + } else if (x1 == x2 && y1 > y2) { + returnPoint = new Point(fromCenterX, y1); + } + if (x1 > x2 && y1 < y2) { + if (fromDYX >= tanDYX) { + returnPoint = new Point(x1, fromCenterY + tanDYX * fromNode.width / 2); + } else { + returnPoint = new Point( + fromCenterX - dx / dy * fromNode.height / 2, + y1 + fromNode.height + ); + } + } else if (x1 < x2 && y1 < y2) { + if (fromDYX >= tanDYX) { + returnPoint = new Point(x1 + fromNode.width, fromCenterY + tanDYX * fromNode.width / 2); + } else { + returnPoint = new Point( + fromCenterX + dx / dy * fromNode.height / 2, + y1 + fromNode.height + ); + } + } else if (x1 < x2 && y1 > y2) { + if (fromDYX >= tanDYX) { + returnPoint = new Point(x1 + fromNode.width, fromCenterY - tanDYX * fromNode.width / 2); + } else { + returnPoint = new Point(fromCenterX + fromNode.height / 2 * dx / dy, y1); + } + } else if (x1 > x2 && y1 > y2) { + if (fromDYX >= tanDYX) { + returnPoint = new Point(x1, fromCenterY - fromNode.width / 2 * tanDYX); + } else { + returnPoint = new Point(fromCenterX - fromNode.height / 2 * dx / dy, y1); + } + } + return returnPoint; +}; +let getIntersectPoints = function(fromNode, endNode) { + let endIntersectPoint = { x: 0, y: 0 }; + endIntersectPoint.x = endNode.x + endNode.width / 2; + endIntersectPoint.y = endNode.y + endNode.height / 2; + let startPoint = getIntersectPoint(fromNode, endIntersectPoint); + endIntersectPoint.x = fromNode.x + fromNode.width / 2; + endIntersectPoint.y = fromNode.y + fromNode.height / 2; + let endPoint = getIntersectPoint(endNode, endIntersectPoint); + return { startPoint, endPoint }; +}; +const drawRels = function(diagram2, rels2, getC4ShapeObj, diagObj) { + let i = 0; + for (let rel of rels2) { + i = i + 1; + let relTextWrap = rel.wrap && conf.wrap; + let relConf = messageFont(conf); + let diagramType = diagObj.db.getC4Type(); + if (diagramType === "C4Dynamic") { + rel.label.text = i + ": " + rel.label.text; + } + let textLimitWidth = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.h)(rel.label.text, relConf); + calcC4ShapeTextWH("label", rel, relTextWrap, relConf, textLimitWidth); + if (rel.techn && rel.techn.text !== "") { + textLimitWidth = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.h)(rel.techn.text, relConf); + calcC4ShapeTextWH("techn", rel, relTextWrap, relConf, textLimitWidth); + } + if (rel.descr && rel.descr.text !== "") { + textLimitWidth = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.h)(rel.descr.text, relConf); + calcC4ShapeTextWH("descr", rel, relTextWrap, relConf, textLimitWidth); + } + let fromNode = getC4ShapeObj(rel.from); + let endNode = getC4ShapeObj(rel.to); + let points = getIntersectPoints(fromNode, endNode); + rel.startPoint = points.startPoint; + rel.endPoint = points.endPoint; + } + svgDraw.drawRels(diagram2, rels2, conf); +}; +function drawInsideBoundary(diagram2, parentBoundaryAlias, parentBounds, currentBoundaries, diagObj) { + let currentBounds = new Bounds(diagObj); + currentBounds.data.widthLimit = parentBounds.data.widthLimit / Math.min(c4BoundaryInRow, currentBoundaries.length); + for (let [i, currentBoundary] of currentBoundaries.entries()) { + let Y = 0; + currentBoundary.image = { width: 0, height: 0, Y: 0 }; + if (currentBoundary.sprite) { + currentBoundary.image.width = 48; + currentBoundary.image.height = 48; + currentBoundary.image.Y = Y; + Y = currentBoundary.image.Y + currentBoundary.image.height; + } + let currentBoundaryTextWrap = currentBoundary.wrap && conf.wrap; + let currentBoundaryLabelConf = boundaryFont(conf); + currentBoundaryLabelConf.fontSize = currentBoundaryLabelConf.fontSize + 2; + currentBoundaryLabelConf.fontWeight = "bold"; + calcC4ShapeTextWH( + "label", + currentBoundary, + currentBoundaryTextWrap, + currentBoundaryLabelConf, + currentBounds.data.widthLimit + ); + currentBoundary["label"].Y = Y + 8; + Y = currentBoundary["label"].Y + currentBoundary["label"].height; + if (currentBoundary.type && currentBoundary.type.text !== "") { + currentBoundary.type.text = "[" + currentBoundary.type.text + "]"; + let currentBoundaryTypeConf = boundaryFont(conf); + calcC4ShapeTextWH( + "type", + currentBoundary, + currentBoundaryTextWrap, + currentBoundaryTypeConf, + currentBounds.data.widthLimit + ); + currentBoundary["type"].Y = Y + 5; + Y = currentBoundary["type"].Y + currentBoundary["type"].height; + } + if (currentBoundary.descr && currentBoundary.descr.text !== "") { + let currentBoundaryDescrConf = boundaryFont(conf); + currentBoundaryDescrConf.fontSize = currentBoundaryDescrConf.fontSize - 2; + calcC4ShapeTextWH( + "descr", + currentBoundary, + currentBoundaryTextWrap, + currentBoundaryDescrConf, + currentBounds.data.widthLimit + ); + currentBoundary["descr"].Y = Y + 20; + Y = currentBoundary["descr"].Y + currentBoundary["descr"].height; + } + if (i == 0 || i % c4BoundaryInRow === 0) { + let _x = parentBounds.data.startx + conf.diagramMarginX; + let _y = parentBounds.data.stopy + conf.diagramMarginY + Y; + currentBounds.setData(_x, _x, _y, _y); + } else { + let _x = currentBounds.data.stopx !== currentBounds.data.startx ? currentBounds.data.stopx + conf.diagramMarginX : currentBounds.data.startx; + let _y = currentBounds.data.starty; + currentBounds.setData(_x, _x, _y, _y); + } + currentBounds.name = currentBoundary.alias; + let currentPersonOrSystemArray = diagObj.db.getC4ShapeArray(currentBoundary.alias); + let currentPersonOrSystemKeys = diagObj.db.getC4ShapeKeys(currentBoundary.alias); + if (currentPersonOrSystemKeys.length > 0) { + drawC4ShapeArray( + currentBounds, + diagram2, + currentPersonOrSystemArray, + currentPersonOrSystemKeys + ); + } + parentBoundaryAlias = currentBoundary.alias; + let nextCurrentBoundarys = diagObj.db.getBoundarys(parentBoundaryAlias); + if (nextCurrentBoundarys.length > 0) { + drawInsideBoundary( + diagram2, + parentBoundaryAlias, + currentBounds, + nextCurrentBoundarys, + diagObj + ); + } + if (currentBoundary.alias !== "global") { + drawBoundary(diagram2, currentBoundary, currentBounds); + } + parentBounds.data.stopy = Math.max( + currentBounds.data.stopy + conf.c4ShapeMargin, + parentBounds.data.stopy + ); + parentBounds.data.stopx = Math.max( + currentBounds.data.stopx + conf.c4ShapeMargin, + parentBounds.data.stopx + ); + globalBoundaryMaxX = Math.max(globalBoundaryMaxX, parentBounds.data.stopx); + globalBoundaryMaxY = Math.max(globalBoundaryMaxY, parentBounds.data.stopy); + } +} +const draw = function(_text, id, _version, diagObj) { + conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().c4; + const securityLevel = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + let db2 = diagObj.db; + diagObj.db.setWrap(conf.wrap); + c4ShapeInRow = db2.getC4ShapeInRow(); + c4BoundaryInRow = db2.getC4BoundaryInRow(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`C:${JSON.stringify(conf, null, 2)}`); + const diagram2 = securityLevel === "sandbox" ? root.select(`[id="${id}"]`) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(`[id="${id}"]`); + svgDraw.insertComputerIcon(diagram2); + svgDraw.insertDatabaseIcon(diagram2); + svgDraw.insertClockIcon(diagram2); + let screenBounds = new Bounds(diagObj); + screenBounds.setData( + conf.diagramMarginX, + conf.diagramMarginX, + conf.diagramMarginY, + conf.diagramMarginY + ); + screenBounds.data.widthLimit = screen.availWidth; + globalBoundaryMaxX = conf.diagramMarginX; + globalBoundaryMaxY = conf.diagramMarginY; + const title2 = diagObj.db.getTitle(); + let currentBoundaries = diagObj.db.getBoundarys(""); + drawInsideBoundary(diagram2, "", screenBounds, currentBoundaries, diagObj); + svgDraw.insertArrowHead(diagram2); + svgDraw.insertArrowEnd(diagram2); + svgDraw.insertArrowCrossHead(diagram2); + svgDraw.insertArrowFilledHead(diagram2); + drawRels(diagram2, diagObj.db.getRels(), diagObj.db.getC4Shape, diagObj); + screenBounds.data.stopx = globalBoundaryMaxX; + screenBounds.data.stopy = globalBoundaryMaxY; + const box = screenBounds.data; + let boxHeight = box.stopy - box.starty; + let height = boxHeight + 2 * conf.diagramMarginY; + let boxWidth = box.stopx - box.startx; + const width = boxWidth + 2 * conf.diagramMarginX; + if (title2) { + diagram2.append("text").text(title2).attr("x", (box.stopx - box.startx) / 2 - 4 * conf.diagramMarginX).attr("y", box.starty + conf.diagramMarginY); + } + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.i)(diagram2, height, width, conf.useMaxWidth); + const extraVertForTitle = title2 ? 60 : 0; + diagram2.attr( + "viewBox", + box.startx - conf.diagramMarginX + " -" + (conf.diagramMarginY + extraVertForTitle) + " " + width + " " + (height + extraVertForTitle) + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`models:`, box); +}; +const renderer = { + drawPersonOrSystemArray: drawC4ShapeArray, + drawBoundary, + setConf, + draw +}; +const getStyles = (options) => `.person { + stroke: ${options.personBorder}; + fill: ${options.personBkg}; + } +`; +const styles = getStyles; +const diagram = { + parser: parser$1, + db, + renderer, + styles, + init: ({ c4, wrap }) => { + renderer.setConf(c4); + db.setWrap(wrap); + } +}; + + + +/***/ }), + +/***/ 93799: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ drawBackgroundRect), +/* harmony export */ b: () => (/* binding */ drawEmbeddedImage), +/* harmony export */ c: () => (/* binding */ drawImage), +/* harmony export */ d: () => (/* binding */ drawRect), +/* harmony export */ e: () => (/* binding */ getTextObj), +/* harmony export */ f: () => (/* binding */ drawText), +/* harmony export */ g: () => (/* binding */ getNoteRect) +/* harmony export */ }); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(17967); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); + + +const drawRect = (element, rectData) => { + const rectElement = element.append("rect"); + rectElement.attr("x", rectData.x); + rectElement.attr("y", rectData.y); + rectElement.attr("fill", rectData.fill); + rectElement.attr("stroke", rectData.stroke); + rectElement.attr("width", rectData.width); + rectElement.attr("height", rectData.height); + rectData.rx !== void 0 && rectElement.attr("rx", rectData.rx); + rectData.ry !== void 0 && rectElement.attr("ry", rectData.ry); + if (rectData.attrs !== void 0) { + for (const attrKey in rectData.attrs) { + rectElement.attr(attrKey, rectData.attrs[attrKey]); + } + } + rectData.class !== void 0 && rectElement.attr("class", rectData.class); + return rectElement; +}; +const drawBackgroundRect = (element, bounds) => { + const rectData = { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + stroke: bounds.stroke, + class: "rect" + }; + const rectElement = drawRect(element, rectData); + rectElement.lower(); +}; +const drawText = (element, textData) => { + const nText = textData.text.replace(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.H, " "); + const textElem = element.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", textData.y); + textElem.attr("class", "legend"); + textElem.style("text-anchor", textData.anchor); + textData.class !== void 0 && textElem.attr("class", textData.class); + const tspan = textElem.append("tspan"); + tspan.attr("x", textData.x + textData.textMargin * 2); + tspan.text(nText); + return textElem; +}; +const drawImage = (elem, x, y, link) => { + const imageElement = elem.append("image"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Nm)(link); + imageElement.attr("xlink:href", sanitizedLink); +}; +const drawEmbeddedImage = (element, x, y, link) => { + const imageElement = element.append("use"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Nm)(link); + imageElement.attr("xlink:href", `#${sanitizedLink}`); +}; +const getNoteRect = () => { + const noteRectData = { + x: 0, + y: 0, + width: 100, + height: 100, + fill: "#EDF2AE", + stroke: "#666", + anchor: "start", + rx: 0, + ry: 0 + }; + return noteRectData; +}; +const getTextObj = () => { + const testObject = { + x: 0, + y: 0, + width: 100, + height: 100, + "text-anchor": "start", + style: "#666", + textMargin: 0, + rx: 0, + ry: 0, + tspan: true + }; + return testObject; +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/1236fad7.e7249cac.js b/assets/js/1236fad7.e7249cac.js new file mode 100644 index 000000000..ce219e47e --- /dev/null +++ b/assets/js/1236fad7.e7249cac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6515],{38491:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>o});var t=s(85893),r=s(3905);const i={title:"Docusaurus",slug:"docusaurus",tags:["Documentation"]},a=void 0,c={permalink:"/docusaurus",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",source:"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",title:"Docusaurus",description:"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4.",date:"2023-06-18T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 18\uc77c",tags:[{label:"Documentation",permalink:"/tags/documentation"}],readingTime:10.095,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Docusaurus",slug:"docusaurus",tags:["Documentation"]},unlisted:!1,prevItem:{title:"\uc6f9\uc18c\ucf13",permalink:"/websocket"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",permalink:"/woowacourse-level2-retrospective"}},l={authorsImageUrls:[]},o=[{value:"\uc124\uce58",id:"\uc124\uce58",level:2},{value:"\ubc30\ud3ec",id:"\ubc30\ud3ec",level:2},{value:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131",id:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac-\uc0dd\uc131",level:3},{value:"\uc124\uc815 \ud30c\uc77c \uc218\uc815",id:"\uc124\uc815-\ud30c\uc77c-\uc218\uc815",level:3},{value:"\ud1a0\ud070 \uc124\uc815",id:"\ud1a0\ud070-\uc124\uc815",level:3},{value:"\ube0c\ub79c\uce58 \uc0dd\uc131",id:"\ube0c\ub79c\uce58-\uc0dd\uc131",level:3},{value:"\uc6cc\ud06c\ud50c\ub85c \uc791\uc131",id:"\uc6cc\ud06c\ud50c\ub85c-\uc791\uc131",level:3},{value:"\ub313\uae00 \uae30\ub2a5",id:"\ub313\uae00-\uae30\ub2a5",level:2},{value:"giscus \uc124\uc815",id:"giscus-\uc124\uc815",level:3},{value:"docusaurus \uc124\uc815",id:"docusaurus-\uc124\uc815",level:3},{value:"\uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30",id:"\uc54c\uace0\ub9ac\uc544-\uc124\uc815-\ubc0f-\uc9c1\uc811-\uad00\ub9ac\ud558\uae30",level:2},{value:"\uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778",id:"\uc54c\uace0\ub9ac\uc544-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\uc0dd\uc131-\ubc0f-\ud0a4-\ud655\uc778",level:3},{value:"\ud0a4 \uc0dd\uc131",id:"\ud0a4-\uc0dd\uc131",level:3},{value:".env \ud30c\uc77c \uc0dd\uc131",id:"env-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"config \ud30c\uc77c \uc0dd\uc131",id:"config-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1",id:"docker-\uc774\uc6a9\ud558\uc5ec-\ud06c\ub864\ub9c1",level:3},{value:"docusaurus \uc124\uc815",id:"docusaurus-\uc124\uc815-1",level:3},{value:"\ubd80\uac00 \uc124\uc815",id:"\ubd80\uac00-\uc124\uc815",level:2},{value:"\ud654\uba74 \uc0c1\ub2e8 Github Icon",id:"\ud654\uba74-\uc0c1\ub2e8-github-icon",level:3},{value:"\ucf54\ub4dc\ube14\ub7ed",id:"\ucf54\ub4dc\ube14\ub7ed",level:3},{value:"mermaid",id:"mermaid",level:3},{value:"\uad6d\uc81c\ud654 \uc124\uc815",id:"\uad6d\uc81c\ud654-\uc124\uc815",level:3},{value:"\ube14\ub85c\uadf8 \uae00 author",id:"\ube14\ub85c\uadf8-\uae00-author",level:3}];function u(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,r.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.h2,{id:"\uc124\uce58",children:"\uc124\uce58"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docusaurus.io/docs/installation",children:"\uacf5\uc2dd \ud648\ud398\uc774\uc9c0"}),"\uc5d0 \ub4e4\uc5b4\uac00\uc11c \ucd5c\uc2e0 \ubc84\uc804\uc744 \uc124\uce58\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn create docusaurus\n"})}),"\n",(0,t.jsx)(n.h2,{id:"\ubc30\ud3ec",children:"\ubc30\ud3ec"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docusaurus.io/docs/next/deployment#deploying-to-github-pages",children:"\ubc30\ud3ec \uc548\ub0b4 \ubb38\uc11c"}),(0,t.jsx)(n.br,{}),"\n","netlify\ub098 vercel \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ud50c\ub7ab\ud3fc\uc744 \ucd94\ucc9c\ud558\uace0 \uc788\uace0, \uac04\ub2e8\ud558\uace0, \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \ubc30\ud3ec\ub97c \ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 github pages\ub97c \uc774\uc6a9\ud574\uc11c \ubc30\ud3ec\ud558\ub294 \ubc29\ubc95\uc744 \uc124\uba85\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac-\uc0dd\uc131",children:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["github pages\ub97c \uc774\uc6a9\ud558\ub824\uba74 ",(0,t.jsx)(n.a,{href:"https://github.com/greeng00se/greeng00se.github.io",children:"\uc608\uc2dc"}),"\uc640 \uac19\uc774 ",(0,t.jsx)(n.code,{children:"username.github.io"})," \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub54c organization\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ",(0,t.jsx)(n.code,{children:"organization.github.io"})," \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc124\uc815-\ud30c\uc77c-\uc218\uc815",children:"\uc124\uc815 \ud30c\uc77c \uc218\uc815"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"module.exports = {\n // ...\n url: 'https://greeng00se.github.io',\n baseUrl: '/',\n projectName: 'greeng00se.github.io',\n organizationName: 'greeng00se',\n trailingSlash: false,\n // ...\n};\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\ud1a0\ud070-\uc124\uc815",children:"\ud1a0\ud070 \uc124\uc815"}),"\n",(0,t.jsxs)(n.p,{children:["github action\uc744 \uc704\ud574 \ubc30\ud3ec\uc6a9 \ud1a0\ud070\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uc5ec \uc0dd\uc131\ud55c \ub808\ud3ec\uc9c0\ud1a0\ub9ac\uc5d0 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 \ud1a0\ud070\uc744 \ud074\ub798\uc2dd \ubc29\uc2dd\uc73c\ub85c \uc0dd\uc131\ud588\uace0 \uc2a4\ucf54\ud504\ub294 [repo, user, workflow] \uc744 \uc124\uc815\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"github",src:s(29094).Z+"",width:"1598",height:"1670"})}),"\n",(0,t.jsx)(n.h3,{id:"\ube0c\ub79c\uce58-\uc0dd\uc131",children:"\ube0c\ub79c\uce58 \uc0dd\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["github\uc5d0\uc11c gh-pages \ube0c\ub79c\uce58\ub97c \ud558\ub098 \uc0dd\uc131\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","repository -> settings -> pages -> branch\uc5d0\uc11c \uc0dd\uc131\ud55c gh-pages\ub85c \ube0c\ub79c\uce58\ub97c \ubcc0\uacbd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc124\uc815\ud55c \ube0c\ub79c\uce58\uac00 \ubc30\ud3ec \ube0c\ub79c\uce58\uac00 \ub418\uba70, \ud574\ub2f9 \ube0c\ub79c\uce58\uc5d0 \uc788\ub294 \ud30c\uc77c\ub4e4\uc744 \uc774\uc6a9\ud574\uc11c \uc815\uc801 \uc6f9\uc0ac\uc774\ud2b8\ub97c \uc81c\uacf5\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc6cc\ud06c\ud50c\ub85c-\uc791\uc131",children:"\uc6cc\ud06c\ud50c\ub85c \uc791\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["Docusaurus 2.0 \uae30\uc900 Node.js 16.14 \uc774\uc0c1\uc758 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc30\ud3ec\uc2dc\uc5d0\ub294 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c DEPLOY_TOKEN \uc744 \uc774\uc6a9\ud569\ub2c8\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yml",metastring:'title=".github/workflows/deploy.yml"',children:"name: blog\n\non:\n push:\n branches: [main]\n\njobs:\n deploy:\n name: Deploy to GitHub Pages\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n - uses: actions/setup-node@v3\n with:\n node-version: 18\n cache: yarn\n\n - name: Install dependencies\n run: yarn install --frozen-lockfile\n - name: Build website\n run: yarn build\n\n - name: Deploy to GitHub Pages\n uses: peaceiris/actions-gh-pages@v3\n with:\n github_token: ${{ secrets.DEPLOY_TOKEN }}\n publish_dir: ./build\n user_name: github-actions[bot]\n user_email: 41898282+github-actions[bot]@users.noreply.github.com\n"})}),"\n",(0,t.jsx)(n.h2,{id:"\ub313\uae00-\uae30\ub2a5",children:"\ub313\uae00 \uae30\ub2a5"}),"\n",(0,t.jsx)(n.p,{children:"giscus\ub97c \uc774\uc6a9\ud558\uc5ec \ub313\uae00 \uae30\ub2a5\uc744 \ucd94\uac00\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.h3,{id:"giscus-\uc124\uc815",children:"giscus \uc124\uc815"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"\uacf5\uac1c \uc800\uc7a5\uc18c\uc5ec\uc57c \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"giscus \uc571\uc774 \uc124\uce58\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"Discussions \uae30\ub2a5\uc774 \ud574\ub2f9 \uc800\uc7a5\uc18c\uc5d0\uc11c \ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 ",(0,t.jsx)(n.a,{href:"https://giscus.app/ko",children:"giscus"}),"\ub97c \ud655\uc778\ud558\uc790."]}),"\n",(0,t.jsx)(n.h3,{id:"docusaurus-\uc124\uc815",children:"docusaurus \uc124\uc815"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docusaurus.io/ko/docs/next/swizzling",children:"swizzling"}),"\uc744 \uc774\uc6a9\ud558\uc5ec \ucef4\ud3ec\ub10c\ud2b8\ub97c \uac10\uc2fc\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae30\uc874\uc5d0 \uac8c\uc2dc\ubb3c\uc744 giscus\uac00 \ud3ec\ud568\ub41c \ub9ac\uc561\ud2b8 \ucef4\ud3ec\ub10c\ud2b8\ub85c \uac10\uc2f8\ub294 \ud615\ud0dc\uac00 \ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec BlogPostItem\uc744 \ucd94\ucd9c\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap\n"})}),"\n",(0,t.jsxs)(n.p,{children:["\uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uba74 ",(0,t.jsx)(n.code,{children:"/src/theme/BlogPostItem/index.js"})," \uc704\uce58\uc5d0 \ud30c\uc77c\uc774 \uc0dd\uc131\ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud30c\uc77c\uc758 \ub0b4\uc6a9\uc744 \uc544\ub798\uc640 \uac19\uc774 \uc218\uc815\ud558\uace0, \uc774\ub54c setAttribute \ubd80\ubd84\uc740 \uc801\uc808\ud558\uac8c \uc790\uc2e0\uc758 giscus \uc124\uc815\uc744 \uc774\uc6a9\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="/src/theme/BlogPostItem/index.js"',children:'import OriginalBlogPostItem from "@theme-original/BlogPostItem";\nimport React, { useEffect, useRef } from "react";\n// @ts-expect-error internal code\nimport { useColorMode } from "@docusaurus/theme-common";\nimport { useBlogPost } from "@docusaurus/theme-common/internal";\n\nconst giscusSelector = "iframe.giscus-frame";\n\nfunction BlogPostItem(props) {\n const { colorMode } = useColorMode();\n const { isBlogPostPage } = useBlogPost();\n const giscusTheme = colorMode === "dark" ? "dark" : "light";\n const containerRef = useRef(null);\n\n useEffect(() => {\n if (!isBlogPostPage) return;\n\n const giscusEl = containerRef.current.querySelector(giscusSelector);\n\n const createGiscusEl = () => {\n const script = document.createElement("script");\n\n script.src = "https://giscus.app/client.js";\n script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");\n script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");\n script.setAttribute("data-category", "Announcements");\n script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");\n script.setAttribute("data-mapping", "pathname");\n script.setAttribute("data-strict", "0");\n script.setAttribute("data-reactions-enabled", "1");\n script.setAttribute("data-emit-metadata", "0");\n script.setAttribute("data-input-position", "bottom");\n script.setAttribute("data-theme", giscusTheme);\n script.setAttribute("data-lang", "ko");\n script.crossOrigin = "anonymous";\n script.async = true;\n \n containerRef.current.appendChild(script);\n };\n\n const postThemeMessage = () => {\n const message = {\n setConfig: {\n theme: giscusTheme,\n }\n };\n\n giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");\n };\n\n giscusEl ? postThemeMessage() : createGiscusEl();\n }, [giscusTheme]);\n\n return (\n <>\n \n {isBlogPostPage &&
}\n \n );\n}\n\nexport default BlogPostItem;\n'})}),"\n",(0,t.jsx)(n.h2,{id:"\uc54c\uace0\ub9ac\uc544-\uc124\uc815-\ubc0f-\uc9c1\uc811-\uad00\ub9ac\ud558\uae30",children:"\uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30"}),"\n",(0,t.jsxs)(n.p,{children:["\uc54c\uace0\ub9ac\uc544\ub97c \uc0ac\uc6a9\ud558\uba74 \uac80\uc0c9 \uae30\ub2a5\uc744 \ucd94\uac00\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc720\ub8cc \ud50c\ub79c\uc774\ub098 netlify\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ud06c\ub864\ub7ec\ub97c \ub530\ub85c \uc81c\uacf5\ud574 \uc8fc\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\ubb34\ub8cc \ud50c\ub79c\uc740 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uacfc, ",(0,t.jsx)(n.a,{href:"https://docsearch.algolia.com/",children:"docsearch"}),"\ub97c \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","docsearch\uc5d0 \ub4f1\ub85d\ud55c\ub2e4\uba74 \uc77c\uc8fc\uc77c\uc5d0 \ud55c \ubc88\uc529 \ud06c\ub864\ub9c1\uc774 \uc9c4\ud589\ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docsearch.algolia.com/docs/legacy/run-your-own/",children:"\uc9c1\uc811 \uc778\ub371\uc2a4 \uc218\uc9d1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docsearch.algolia.com/docs/legacy/config-file",children:"\uc124\uc815 \ud30c\uc77c"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc54c\uace0\ub9ac\uc544-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\uc0dd\uc131-\ubc0f-\ud0a4-\ud655\uc778",children:"\uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778"}),"\n",(0,t.jsxs)(n.p,{children:["\ud68c\uc6d0\uac00\uc785\uc744 \ud558\uace0 \uc0c8\ub85c\uc6b4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131\uc744 \ub204\ub978\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc0dd\uc131\uc744 \ub2e4 \ub9c8\uce58\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 api \ud0a4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"algolia",src:s(41785).Z+"",width:"3194",height:"1520"})}),"\n",(0,t.jsx)(n.h3,{id:"\ud0a4-\uc0dd\uc131",children:"\ud0a4 \uc0dd\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["\uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\uae30 \uc704\ud55c \ud0a4\ub97c \uc0dd\uc131\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","addObject, editSettings, deleteIndex acl(\uc811\uadfc \uc81c\uc5b4 \ubaa9\ub85d)\uc774 \uc788\uc73c\uba74 \ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"key",src:s(4730).Z+"",width:"2496",height:"832"})}),"\n",(0,t.jsx)(n.h3,{id:"env-\ud30c\uc77c-\uc0dd\uc131",children:".env \ud30c\uc77c \uc0dd\uc131"}),"\n",(0,t.jsx)(n.p,{children:"\ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354 \uc0c1\ub2e8\uc5d0 .env \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:"APPLICATION_ID=MVIU5UEMOM\nAPI_KEY=\uc778\ub371\uc2a4_\uc0dd\uc131\uc6a9_\ud0a4\n"})}),"\n",(0,t.jsx)(n.h3,{id:"config-\ud30c\uc77c-\uc0dd\uc131",children:"config \ud30c\uc77c \uc0dd\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["\ub9c8\ucc2c\uac00\uc9c0\ub85c \ucd5c\uc0c1\ub2e8\uc5d0 config.json \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4.\n\uc124\uc815 \ud30c\uc77c\uc740 \ud574\ub2f9 ",(0,t.jsx)(n.a,{href:"https://docsearch.algolia.com/docs/legacy/config-file",children:"\ub9c1\ud06c"}),"\ub97c \ucc38\uace0\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ub294 Docusaurus\uc758 ",(0,t.jsx)(n.a,{href:"https://github.com/algolia/docsearch-configs/blob/master/configs/docusaurus-2.json",children:"\uc124\uc815 \ud30c\uc77c"}),"\uc744 \ucc38\uace0\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",metastring:'title="config.json"',children:'{\n "index_name": "teco",\n "start_urls": [\n "https://teco-chat.github.io/"\n ],\n "sitemap_urls": [\n "https://teco-chat.github.io/sitemap.xml"\n ],\n "sitemap_alternate_links": true,\n "stop_urls": [\n "/tests"\n ],\n "selectors": {\n "lvl0": {\n "selector": "(//ul[contains(@class,\'menu__list\')]//a[contains(@class, \'menu__link menu__link--sublist menu__link--active\')]/text() | //nav[contains(@class, \'navbar\')]//a[contains(@class, \'navbar__link--active\')]/text())[last()]",\n "type": "xpath",\n "global": true,\n "default_value": "Documentation"\n },\n "lvl1": "header h1",\n "lvl2": "article h2",\n "lvl3": "article h3",\n "lvl4": "article h4",\n "lvl5": "article h5, article td:first-child",\n "lvl6": "article h6",\n "text": "article p, article li, article td:last-child"\n },\n "strip_chars": " .,;:#",\n "custom_settings": {\n "separatorsToIndex": "_",\n "attributesForFaceting": [\n "language",\n "version",\n "type",\n "docusaurus_tag"\n ],\n "attributesToRetrieve": [\n "hierarchy",\n "content",\n "anchor",\n "url",\n "url_without_anchor",\n "type"\n ]\n },\n "conversation_id": [\n "833762294"\n ],\n "nb_hits": 46250\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"docker-\uc774\uc6a9\ud558\uc5ec-\ud06c\ub864\ub9c1",children:"docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1"}),"\n",(0,t.jsxs)(n.p,{children:["docker\uc640 jq\uac00 \ud544\uc694\ud558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","jq\uac00 \uc124\uce58\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc73c\uba74 mac \uae30\uc900 brew\ub97c \uc774\uc6a9\ud574\uc11c \uc124\uce58\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install jq\n"})}),"\n",(0,t.jsx)(n.p,{children:"\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec .env\uc640 config.json\uc744 \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1\uc744 \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper\n'})}),"\n",(0,t.jsx)(n.h3,{id:"docusaurus-\uc124\uc815-1",children:"docusaurus \uc124\uc815"}),"\n",(0,t.jsx)(n.p,{children:"\uc804\uc5d0 \ud655\uc778\ud55c APP ID, Search-Only API KEY, IndexName\uc744 \uc774\uc6a9\ud558\uc5ec docusaurus.config \ud30c\uc77c\uc5d0 \uc124\uc815\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"themeConfig:\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n ({\n ...\n algolia: {\n appId: 'MVIU5UEMOM', // Application ID\n apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key\n indexName: 'teco', // config.json\uc5d0 \uc124\uc815\ud55c \uc778\ub371\uc2a4\uba85\n contextualSearch: true,\n },\n })\n"})}),"\n",(0,t.jsx)(n.h2,{id:"\ubd80\uac00-\uc124\uc815",children:"\ubd80\uac00 \uc124\uc815"}),"\n",(0,t.jsx)(n.h3,{id:"\ud654\uba74-\uc0c1\ub2e8-github-icon",children:"\ud654\uba74 \uc0c1\ub2e8 Github Icon"}),"\n",(0,t.jsx)(n.p,{children:"\ud30c\uc77c \ucd5c\ud558\ub2e8\uc5d0 \uc544\ub798 css \uad6c\ubb38\uc744 \ucd94\uac00\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-css",metastring:'title="/src/css/custom.css"',children:".header-github-link:hover {\n opacity: 0.6;\n}\n\n.header-github-link:before {\n content: '';\n width: 24px;\n height: 24px;\n display: flex;\n background: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")\n no-repeat;\n}\n\nhtml[data-theme='dark'] .header-github-link:before {\n background: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")\n no-repeat;\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"themeconfig -> navbar\uc5d0 github link\ub97c \uc124\uc815\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"navbar: {\n title: 'HELLO',\n items: [\n {\n href: 'https://github.com/greeng00se',\n position: 'right',\n className: 'header-github-link',\n 'aria-label': 'GitHub repository',\n },\n ],\n},\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\ucf54\ub4dc\ube14\ub7ed",children:"\ucf54\ub4dc\ube14\ub7ed"}),"\n",(0,t.jsxs)(n.p,{children:["java\ub098 kotlin\uc758 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ud558\uc774\ub77c\uc774\ud305\uc744 \uc9c0\uc6d0\ud574 \uc8fc\uc9c0 \uc54a\ub294\ub2e4.",(0,t.jsx)(n.br,{}),"\n","prism \uc124\uc815\uc744 \uc544\ub798\uc640 \uac19\uc774 \ubcc0\uacbd\ud574 \uc900\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"prism: {\n theme: lightCodeTheme,\n darkTheme: darkCodeTheme,\n additionalLanguages: ['java', 'kotlin'],\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"mermaid",children:"mermaid"}),"\n",(0,t.jsxs)(n.p,{children:["mermaid\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 ",(0,t.jsx)(n.code,{children:"@docusaurus/theme-mermaid"})," \ub97c \uc124\uce58\ud574\uc57c \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn add @docusaurus/theme-mermaid\n"})}),"\n",(0,t.jsx)(n.p,{children:"\uc124\uce58 \ud6c4 \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\uc744 \ucd94\uac00\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"const config = {\n ...\n markdown: {\n mermaid: true,\n },\n themes: [\n '@docusaurus/theme-mermaid'\n ],\n};\n"})}),"\n",(0,t.jsx)(n.p,{children:"themeConfig\uc5d0\uc11c mermaid\uc758 \ud14c\ub9c8\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"themeConfig:\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n ({\n ...\n mermaid: {\n theme: {\n light: 'neutral', \n dark: 'dark'\n },\n },\n }),\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\uad6d\uc81c\ud654-\uc124\uc815",children:"\uad6d\uc81c\ud654 \uc124\uc815"}),"\n",(0,t.jsxs)(n.p,{children:["\uad6d\uc81c\ud654 \uc124\uc815\uc744 \ud55c\ub2e4\uba74 ",(0,t.jsx)(n.code,{children:"Older Entries"})," \ud615\ud0dc\uc758 \uc124\uba85\uc774 ",(0,t.jsx)(n.code,{children:"\ub2e4\uc74c \ud398\uc774\uc9c0"})," \ub85c \ubcc0\uacbd\ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc124\uc815\ud30c\uc77c\uc5d0\uc11c i18n\uc5d0 \uc788\ub294 \ub85c\ucf00\uc77c \uc124\uc815\uc744 ko\ub85c \ubcc0\uacbd\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:'i18n: {\n defaultLocale: "ko",\n locales: ["ko"],\n},\n'})}),"\n",(0,t.jsx)(n.h3,{id:"\ube14\ub85c\uadf8-\uae00-author",children:"\ube14\ub85c\uadf8 \uae00 author"}),"\n",(0,t.jsx)(n.p,{children:"\ud300\uc6d0 \ubcc4\ub85c \ubb38\uc11c\ub97c \uad00\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 \uc5b4\ub5a4 \ud300\uc6d0\uc774 \uae00\uc744 \uc791\uc131\ud588\ub294\uc9c0 \uc124\uc815\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"author",src:s(31897).Z+"",width:"2362",height:"1076"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"authors.yml"})," \ud30c\uc77c\uc744 \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790\uc5d0 \ub300\ud55c \uae30\ubcf8 \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yml",metastring:'title="/blog/authors.yml"',children:"herb:\n name: \ud5c8\ube0c\n title: Backend\n url: https://github.com/greeng00se\n image_url: https://github.com/greeng00se.png\n\nmallang:\n name: \ub9d0\ub791\n title: Backend\n url: https://github.com/shin-mallang\n image_url: https://github.com/shin-mallang.png\n"})}),"\n",(0,t.jsx)(n.p,{children:"\ube14\ub85c\uadf8 \uae00\uc744 \uc791\uc131\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc774 authors\uc5d0 \ub123\uc5b4\uc8fc\uae30\ub9cc \ud558\uba74 \ub41c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-mdx",children:"---\nslug: 1\ntitle: Hello World\nauthors: [herb, mallang]\ntags: [hello, docusaurus]\n---\n\n\uccab \ubc88\uc9f8 \ubb38\uc11c \ub0b4\uc6a9\n"})})]})}function d(e={}){const{wrapper:n}={...(0,r.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},3905:(e,n,s)=>{s.d(n,{ah:()=>o});var t=s(67294);function r(e,n,s){return n in e?Object.defineProperty(e,n,{value:s,enumerable:!0,configurable:!0,writable:!0}):e[n]=s,e}function i(e,n){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),s.push.apply(s,t)}return s}function a(e){for(var n=1;n=0||(r[s]=e[s]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,s)&&(r[s]=e[s])}return r}var l=t.createContext({}),o=function(e){var n=t.useContext(l),s=n;return e&&(s="function"==typeof e?e(n):a(a({},n),e)),s},u={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var s=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),h=o(s),g=r,p=h["".concat(l,".").concat(g)]||h[g]||u[g]||i;return s?t.createElement(p,a(a({ref:n},d),{},{components:s})):t.createElement(p,a({ref:n},d))}));d.displayName="MDXCreateElement"},41785:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/algolia-3dbac5c1606f7f0daed9cb27a429db50.png"},31897:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/author-1bd517bb7763257e2139e1063fd92492.png"},29094:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/github-d866f69755a1e17d4f17a262bd30d56d.png"},4730:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/key-2d0b59e69e9ca0b21c49b76159266e74.png"}}]); \ No newline at end of file diff --git a/assets/js/1236fad7.f0e8ba67.js b/assets/js/1236fad7.f0e8ba67.js deleted file mode 100644 index 46c8a3f1b..000000000 --- a/assets/js/1236fad7.f0e8ba67.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6515],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=a.createContext({}),u=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(o.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,o=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),g=u(n),m=r,d=g["".concat(o,".").concat(m)]||g[m]||p[m]||s;return n?a.createElement(d,l(l({ref:t},c),{},{components:n})):a.createElement(d,l({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,l=new Array(s);l[0]=g;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var u=2;u{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>p,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var a=n(87462),r=(n(67294),n(3905));const s={title:"Docusaurus",slug:"docusaurus",tags:["Documentation"]},l=void 0,i={permalink:"/docusaurus",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",source:"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",title:"Docusaurus",description:"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4.",date:"2023-06-18T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 18\uc77c",tags:[{label:"Documentation",permalink:"/tags/documentation"}],readingTime:10.095,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Docusaurus",slug:"docusaurus",tags:["Documentation"]},prevItem:{title:"\uc6f9\uc18c\ucf13",permalink:"/websocket"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",permalink:"/woowacourse-level2-retrospective"}},o={authorsImageUrls:[]},u=[{value:"\uc124\uce58",id:"\uc124\uce58",level:2},{value:"\ubc30\ud3ec",id:"\ubc30\ud3ec",level:2},{value:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131",id:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac-\uc0dd\uc131",level:3},{value:"\uc124\uc815 \ud30c\uc77c \uc218\uc815",id:"\uc124\uc815-\ud30c\uc77c-\uc218\uc815",level:3},{value:"\ud1a0\ud070 \uc124\uc815",id:"\ud1a0\ud070-\uc124\uc815",level:3},{value:"\ube0c\ub79c\uce58 \uc0dd\uc131",id:"\ube0c\ub79c\uce58-\uc0dd\uc131",level:3},{value:"\uc6cc\ud06c\ud50c\ub85c \uc791\uc131",id:"\uc6cc\ud06c\ud50c\ub85c-\uc791\uc131",level:3},{value:"\ub313\uae00 \uae30\ub2a5",id:"\ub313\uae00-\uae30\ub2a5",level:2},{value:"giscus \uc124\uc815",id:"giscus-\uc124\uc815",level:3},{value:"docusaurus \uc124\uc815",id:"docusaurus-\uc124\uc815",level:3},{value:"\uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30",id:"\uc54c\uace0\ub9ac\uc544-\uc124\uc815-\ubc0f-\uc9c1\uc811-\uad00\ub9ac\ud558\uae30",level:2},{value:"\uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778",id:"\uc54c\uace0\ub9ac\uc544-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\uc0dd\uc131-\ubc0f-\ud0a4-\ud655\uc778",level:3},{value:"\ud0a4 \uc0dd\uc131",id:"\ud0a4-\uc0dd\uc131",level:3},{value:".env \ud30c\uc77c \uc0dd\uc131",id:"env-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"config \ud30c\uc77c \uc0dd\uc131",id:"config-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1",id:"docker-\uc774\uc6a9\ud558\uc5ec-\ud06c\ub864\ub9c1",level:3},{value:"docusaurus \uc124\uc815",id:"docusaurus-\uc124\uc815-1",level:3},{value:"\ubd80\uac00 \uc124\uc815",id:"\ubd80\uac00-\uc124\uc815",level:2},{value:"\ud654\uba74 \uc0c1\ub2e8 Github Icon",id:"\ud654\uba74-\uc0c1\ub2e8-github-icon",level:3},{value:"\ucf54\ub4dc\ube14\ub7ed",id:"\ucf54\ub4dc\ube14\ub7ed",level:3},{value:"mermaid",id:"mermaid",level:3},{value:"\uad6d\uc81c\ud654 \uc124\uc815",id:"\uad6d\uc81c\ud654-\uc124\uc815",level:3},{value:"\ube14\ub85c\uadf8 \uae00 author",id:"\ube14\ub85c\uadf8-\uae00-author",level:3}],c={toc:u};function p(e){let{components:t,...s}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,s,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4. "),(0,r.kt)("h2",{id:"\uc124\uce58"},"\uc124\uce58"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io/docs/installation"},"\uacf5\uc2dd \ud648\ud398\uc774\uc9c0"),"\uc5d0 \ub4e4\uc5b4\uac00\uc11c \ucd5c\uc2e0 \ubc84\uc804\uc744 \uc124\uce58\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"yarn create docusaurus\n")),(0,r.kt)("h2",{id:"\ubc30\ud3ec"},"\ubc30\ud3ec"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io/docs/next/deployment#deploying-to-github-pages"},"\ubc30\ud3ec \uc548\ub0b4 \ubb38\uc11c"),(0,r.kt)("br",{parentName:"p"}),"\n","netlify\ub098 vercel \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ud50c\ub7ab\ud3fc\uc744 \ucd94\ucc9c\ud558\uace0 \uc788\uace0, \uac04\ub2e8\ud558\uace0, \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \ubc30\ud3ec\ub97c \ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 github pages\ub97c \uc774\uc6a9\ud574\uc11c \ubc30\ud3ec\ud558\ub294 \ubc29\ubc95\uc744 \uc124\uba85\ud55c\ub2e4."),(0,r.kt)("h3",{id:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac-\uc0dd\uc131"},"\ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131"),(0,r.kt)("p",null,"github pages\ub97c \uc774\uc6a9\ud558\ub824\uba74 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/greeng00se/greeng00se.github.io"},"\uc608\uc2dc"),"\uc640 \uac19\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"username.github.io")," \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub54c organization\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ",(0,r.kt)("inlineCode",{parentName:"p"},"organization.github.io")," \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("h3",{id:"\uc124\uc815-\ud30c\uc77c-\uc218\uc815"},"\uc124\uc815 \ud30c\uc77c \uc218\uc815"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"module.exports = {\n // ...\n url: 'https://greeng00se.github.io',\n baseUrl: '/',\n projectName: 'greeng00se.github.io',\n organizationName: 'greeng00se',\n trailingSlash: false,\n // ...\n};\n")),(0,r.kt)("h3",{id:"\ud1a0\ud070-\uc124\uc815"},"\ud1a0\ud070 \uc124\uc815"),(0,r.kt)("p",null,"github action\uc744 \uc704\ud574 \ubc30\ud3ec\uc6a9 \ud1a0\ud070\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uc5ec \uc0dd\uc131\ud55c \ub808\ud3ec\uc9c0\ud1a0\ub9ac\uc5d0 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 \ud1a0\ud070\uc744 \ud074\ub798\uc2dd \ubc29\uc2dd\uc73c\ub85c \uc0dd\uc131\ud588\uace0 \uc2a4\ucf54\ud504\ub294 ","[repo, user, workflow]"," \uc744 \uc124\uc815\ud588\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"github",src:n(29094).Z,width:"1598",height:"1670"})),(0,r.kt)("h3",{id:"\ube0c\ub79c\uce58-\uc0dd\uc131"},"\ube0c\ub79c\uce58 \uc0dd\uc131"),(0,r.kt)("p",null,"github\uc5d0\uc11c gh-pages \ube0c\ub79c\uce58\ub97c \ud558\ub098 \uc0dd\uc131\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","repository -> settings -> pages -> branch\uc5d0\uc11c \uc0dd\uc131\ud55c gh-pages\ub85c \ube0c\ub79c\uce58\ub97c \ubcc0\uacbd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc124\uc815\ud55c \ube0c\ub79c\uce58\uac00 \ubc30\ud3ec \ube0c\ub79c\uce58\uac00 \ub418\uba70, \ud574\ub2f9 \ube0c\ub79c\uce58\uc5d0 \uc788\ub294 \ud30c\uc77c\ub4e4\uc744 \uc774\uc6a9\ud574\uc11c \uc815\uc801 \uc6f9\uc0ac\uc774\ud2b8\ub97c \uc81c\uacf5\ud55c\ub2e4. "),(0,r.kt)("h3",{id:"\uc6cc\ud06c\ud50c\ub85c-\uc791\uc131"},"\uc6cc\ud06c\ud50c\ub85c \uc791\uc131"),(0,r.kt)("p",null,"Docusaurus 2.0 \uae30\uc900 Node.js 16.14 \uc774\uc0c1\uc758 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubc30\ud3ec\uc2dc\uc5d0\ub294 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c DEPLOY_TOKEN \uc744 \uc774\uc6a9\ud569\ub2c8\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml",metastring:'title=".github/workflows/deploy.yml"',title:'".github/workflows/deploy.yml"'},"name: blog\n\non:\n push:\n branches: [main]\n\njobs:\n deploy:\n name: Deploy to GitHub Pages\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n - uses: actions/setup-node@v3\n with:\n node-version: 18\n cache: yarn\n\n - name: Install dependencies\n run: yarn install --frozen-lockfile\n - name: Build website\n run: yarn build\n\n - name: Deploy to GitHub Pages\n uses: peaceiris/actions-gh-pages@v3\n with:\n github_token: ${{ secrets.DEPLOY_TOKEN }}\n publish_dir: ./build\n user_name: github-actions[bot]\n user_email: 41898282+github-actions[bot]@users.noreply.github.com\n")),(0,r.kt)("h2",{id:"\ub313\uae00-\uae30\ub2a5"},"\ub313\uae00 \uae30\ub2a5"),(0,r.kt)("p",null,"giscus\ub97c \uc774\uc6a9\ud558\uc5ec \ub313\uae00 \uae30\ub2a5\uc744 \ucd94\uac00\ud55c\ub2e4. "),(0,r.kt)("h3",{id:"giscus-\uc124\uc815"},"giscus \uc124\uc815"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"\uacf5\uac1c \uc800\uc7a5\uc18c\uc5ec\uc57c \ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ol"},"giscus \uc571\uc774 \uc124\uce58\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ol"},"Discussions \uae30\ub2a5\uc774 \ud574\ub2f9 \uc800\uc7a5\uc18c\uc5d0\uc11c \ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4.")),(0,r.kt)("p",null,"\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 ",(0,r.kt)("a",{parentName:"p",href:"https://giscus.app/ko"},"giscus"),"\ub97c \ud655\uc778\ud558\uc790."),(0,r.kt)("h3",{id:"docusaurus-\uc124\uc815"},"docusaurus \uc124\uc815"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io/ko/docs/next/swizzling"},"swizzling"),"\uc744 \uc774\uc6a9\ud558\uc5ec \ucef4\ud3ec\ub10c\ud2b8\ub97c \uac10\uc2fc\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc5d0 \uac8c\uc2dc\ubb3c\uc744 giscus\uac00 \ud3ec\ud568\ub41c \ub9ac\uc561\ud2b8 \ucef4\ud3ec\ub10c\ud2b8\ub85c \uac10\uc2f8\ub294 \ud615\ud0dc\uac00 \ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec BlogPostItem\uc744 \ucd94\ucd9c\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap\n")),(0,r.kt)("p",null,"\uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uba74 ",(0,r.kt)("inlineCode",{parentName:"p"},"/src/theme/BlogPostItem/index.js")," \uc704\uce58\uc5d0 \ud30c\uc77c\uc774 \uc0dd\uc131\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud30c\uc77c\uc758 \ub0b4\uc6a9\uc744 \uc544\ub798\uc640 \uac19\uc774 \uc218\uc815\ud558\uace0, \uc774\ub54c setAttribute \ubd80\ubd84\uc740 \uc801\uc808\ud558\uac8c \uc790\uc2e0\uc758 giscus \uc124\uc815\uc744 \uc774\uc6a9\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="/src/theme/BlogPostItem/index.js"',title:'"/src/theme/BlogPostItem/index.js"'},'import OriginalBlogPostItem from "@theme-original/BlogPostItem";\nimport React, { useEffect, useRef } from "react";\n// @ts-expect-error internal code\nimport { useColorMode } from "@docusaurus/theme-common";\nimport { useBlogPost } from "@docusaurus/theme-common/internal";\n\nconst giscusSelector = "iframe.giscus-frame";\n\nfunction BlogPostItem(props) {\n const { colorMode } = useColorMode();\n const { isBlogPostPage } = useBlogPost();\n const giscusTheme = colorMode === "dark" ? "dark" : "light";\n const containerRef = useRef(null);\n\n useEffect(() => {\n if (!isBlogPostPage) return;\n\n const giscusEl = containerRef.current.querySelector(giscusSelector);\n\n const createGiscusEl = () => {\n const script = document.createElement("script");\n\n script.src = "https://giscus.app/client.js";\n script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");\n script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");\n script.setAttribute("data-category", "Announcements");\n script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");\n script.setAttribute("data-mapping", "pathname");\n script.setAttribute("data-strict", "0");\n script.setAttribute("data-reactions-enabled", "1");\n script.setAttribute("data-emit-metadata", "0");\n script.setAttribute("data-input-position", "bottom");\n script.setAttribute("data-theme", giscusTheme);\n script.setAttribute("data-lang", "ko");\n script.crossOrigin = "anonymous";\n script.async = true;\n \n containerRef.current.appendChild(script);\n };\n\n const postThemeMessage = () => {\n const message = {\n setConfig: {\n theme: giscusTheme,\n }\n };\n\n giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");\n };\n\n giscusEl ? postThemeMessage() : createGiscusEl();\n }, [giscusTheme]);\n\n return (\n <>\n \n {isBlogPostPage &&
}\n \n );\n}\n\nexport default BlogPostItem;\n')),(0,r.kt)("h2",{id:"\uc54c\uace0\ub9ac\uc544-\uc124\uc815-\ubc0f-\uc9c1\uc811-\uad00\ub9ac\ud558\uae30"},"\uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30"),(0,r.kt)("p",null,"\uc54c\uace0\ub9ac\uc544\ub97c \uc0ac\uc6a9\ud558\uba74 \uac80\uc0c9 \uae30\ub2a5\uc744 \ucd94\uac00\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc720\ub8cc \ud50c\ub79c\uc774\ub098 netlify\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ud06c\ub864\ub7ec\ub97c \ub530\ub85c \uc81c\uacf5\ud574 \uc8fc\ub294 \uac83 \uac19\ub2e4. "),(0,r.kt)("p",null,"\ubb34\ub8cc \ud50c\ub79c\uc740 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uacfc, ",(0,r.kt)("a",{parentName:"p",href:"https://docsearch.algolia.com/"},"docsearch"),"\ub97c \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","docsearch\uc5d0 \ub4f1\ub85d\ud55c\ub2e4\uba74 \uc77c\uc8fc\uc77c\uc5d0 \ud55c \ubc88\uc529 \ud06c\ub864\ub9c1\uc774 \uc9c4\ud589\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docsearch.algolia.com/docs/legacy/run-your-own/"},"\uc9c1\uc811 \uc778\ub371\uc2a4 \uc218\uc9d1")," "),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docsearch.algolia.com/docs/legacy/config-file"},"\uc124\uc815 \ud30c\uc77c"))),(0,r.kt)("h3",{id:"\uc54c\uace0\ub9ac\uc544-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\uc0dd\uc131-\ubc0f-\ud0a4-\ud655\uc778"},"\uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778"),(0,r.kt)("p",null,"\ud68c\uc6d0\uac00\uc785\uc744 \ud558\uace0 \uc0c8\ub85c\uc6b4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131\uc744 \ub204\ub978\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc0dd\uc131\uc744 \ub2e4 \ub9c8\uce58\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 api \ud0a4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"algolia",src:n(41785).Z,width:"3194",height:"1520"})),(0,r.kt)("h3",{id:"\ud0a4-\uc0dd\uc131"},"\ud0a4 \uc0dd\uc131"),(0,r.kt)("p",null,"\uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\uae30 \uc704\ud55c \ud0a4\ub97c \uc0dd\uc131\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","addObject, editSettings, deleteIndex acl(\uc811\uadfc \uc81c\uc5b4 \ubaa9\ub85d)\uc774 \uc788\uc73c\uba74 \ub41c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"key",src:n(4730).Z,width:"2496",height:"832"})),(0,r.kt)("h3",{id:"env-\ud30c\uc77c-\uc0dd\uc131"},".env \ud30c\uc77c \uc0dd\uc131"),(0,r.kt)("p",null,"\ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354 \uc0c1\ub2e8\uc5d0 .env \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title=".env"',title:'".env"'},"APPLICATION_ID=MVIU5UEMOM\nAPI_KEY=\uc778\ub371\uc2a4_\uc0dd\uc131\uc6a9_\ud0a4\n")),(0,r.kt)("h3",{id:"config-\ud30c\uc77c-\uc0dd\uc131"},"config \ud30c\uc77c \uc0dd\uc131"),(0,r.kt)("p",null,"\ub9c8\ucc2c\uac00\uc9c0\ub85c \ucd5c\uc0c1\ub2e8\uc5d0 config.json \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4.\n\uc124\uc815 \ud30c\uc77c\uc740 \ud574\ub2f9 ",(0,r.kt)("a",{parentName:"p",href:"https://docsearch.algolia.com/docs/legacy/config-file"},"\ub9c1\ud06c"),"\ub97c \ucc38\uace0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub610\ub294 Docusaurus\uc758 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/algolia/docsearch-configs/blob/master/configs/docusaurus-2.json"},"\uc124\uc815 \ud30c\uc77c"),"\uc744 \ucc38\uace0\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="config.json"',title:'"config.json"'},'{\n "index_name": "teco",\n "start_urls": [\n "https://teco-chat.github.io/"\n ],\n "sitemap_urls": [\n "https://teco-chat.github.io/sitemap.xml"\n ],\n "sitemap_alternate_links": true,\n "stop_urls": [\n "/tests"\n ],\n "selectors": {\n "lvl0": {\n "selector": "(//ul[contains(@class,\'menu__list\')]//a[contains(@class, \'menu__link menu__link--sublist menu__link--active\')]/text() | //nav[contains(@class, \'navbar\')]//a[contains(@class, \'navbar__link--active\')]/text())[last()]",\n "type": "xpath",\n "global": true,\n "default_value": "Documentation"\n },\n "lvl1": "header h1",\n "lvl2": "article h2",\n "lvl3": "article h3",\n "lvl4": "article h4",\n "lvl5": "article h5, article td:first-child",\n "lvl6": "article h6",\n "text": "article p, article li, article td:last-child"\n },\n "strip_chars": " .,;:#",\n "custom_settings": {\n "separatorsToIndex": "_",\n "attributesForFaceting": [\n "language",\n "version",\n "type",\n "docusaurus_tag"\n ],\n "attributesToRetrieve": [\n "hierarchy",\n "content",\n "anchor",\n "url",\n "url_without_anchor",\n "type"\n ]\n },\n "conversation_id": [\n "833762294"\n ],\n "nb_hits": 46250\n}\n')),(0,r.kt)("h3",{id:"docker-\uc774\uc6a9\ud558\uc5ec-\ud06c\ub864\ub9c1"},"docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1"),(0,r.kt)("p",null,"docker\uc640 jq\uac00 \ud544\uc694\ud558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","jq\uac00 \uc124\uce58\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc73c\uba74 mac \uae30\uc900 brew\ub97c \uc774\uc6a9\ud574\uc11c \uc124\uce58\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"brew install jq\n")),(0,r.kt)("p",null,"\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec .env\uc640 config.json\uc744 \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1\uc744 \ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper\n')),(0,r.kt)("h3",{id:"docusaurus-\uc124\uc815-1"},"docusaurus \uc124\uc815"),(0,r.kt)("p",null,"\uc804\uc5d0 \ud655\uc778\ud55c APP ID, Search-Only API KEY, IndexName\uc744 \uc774\uc6a9\ud558\uc5ec docusaurus.config \ud30c\uc77c\uc5d0 \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"themeConfig:\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n ({\n ...\n algolia: {\n appId: 'MVIU5UEMOM', // Application ID\n apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key\n indexName: 'teco', // config.json\uc5d0 \uc124\uc815\ud55c \uc778\ub371\uc2a4\uba85\n contextualSearch: true,\n },\n })\n")),(0,r.kt)("h2",{id:"\ubd80\uac00-\uc124\uc815"},"\ubd80\uac00 \uc124\uc815"),(0,r.kt)("h3",{id:"\ud654\uba74-\uc0c1\ub2e8-github-icon"},"\ud654\uba74 \uc0c1\ub2e8 Github Icon"),(0,r.kt)("p",null,"\ud30c\uc77c \ucd5c\ud558\ub2e8\uc5d0 \uc544\ub798 css \uad6c\ubb38\uc744 \ucd94\uac00\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-css",metastring:'title="/src/css/custom.css"',title:'"/src/css/custom.css"'},".header-github-link:hover {\n opacity: 0.6;\n}\n\n.header-github-link:before {\n content: '';\n width: 24px;\n height: 24px;\n display: flex;\n background: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")\n no-repeat;\n}\n\nhtml[data-theme='dark'] .header-github-link:before {\n background: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")\n no-repeat;\n}\n")),(0,r.kt)("p",null,"themeconfig -> navbar\uc5d0 github link\ub97c \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"navbar: {\n title: 'HELLO',\n items: [\n {\n href: 'https://github.com/greeng00se',\n position: 'right',\n className: 'header-github-link',\n 'aria-label': 'GitHub repository',\n },\n ],\n},\n")),(0,r.kt)("h3",{id:"\ucf54\ub4dc\ube14\ub7ed"},"\ucf54\ub4dc\ube14\ub7ed"),(0,r.kt)("p",null,"java\ub098 kotlin\uc758 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ud558\uc774\ub77c\uc774\ud305\uc744 \uc9c0\uc6d0\ud574 \uc8fc\uc9c0 \uc54a\ub294\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","prism \uc124\uc815\uc744 \uc544\ub798\uc640 \uac19\uc774 \ubcc0\uacbd\ud574 \uc900\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"prism: {\n theme: lightCodeTheme,\n darkTheme: darkCodeTheme,\n additionalLanguages: ['java', 'kotlin'],\n}\n")),(0,r.kt)("h3",{id:"mermaid"},"mermaid"),(0,r.kt)("p",null,"mermaid\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 ",(0,r.kt)("inlineCode",{parentName:"p"},"@docusaurus/theme-mermaid")," \ub97c \uc124\uce58\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"yarn add @docusaurus/theme-mermaid\n")),(0,r.kt)("p",null,"\uc124\uce58 \ud6c4 \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\uc744 \ucd94\uac00\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"const config = {\n ...\n markdown: {\n mermaid: true,\n },\n themes: [\n '@docusaurus/theme-mermaid'\n ],\n};\n")),(0,r.kt)("p",null,"themeConfig\uc5d0\uc11c mermaid\uc758 \ud14c\ub9c8\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"themeConfig:\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n ({\n ...\n mermaid: {\n theme: {\n light: 'neutral', \n dark: 'dark'\n },\n },\n }),\n")),(0,r.kt)("h3",{id:"\uad6d\uc81c\ud654-\uc124\uc815"},"\uad6d\uc81c\ud654 \uc124\uc815"),(0,r.kt)("p",null,"\uad6d\uc81c\ud654 \uc124\uc815\uc744 \ud55c\ub2e4\uba74 ",(0,r.kt)("inlineCode",{parentName:"p"},"Older Entries")," \ud615\ud0dc\uc758 \uc124\uba85\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"\ub2e4\uc74c \ud398\uc774\uc9c0")," \ub85c \ubcc0\uacbd\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc124\uc815\ud30c\uc77c\uc5d0\uc11c i18n\uc5d0 \uc788\ub294 \ub85c\ucf00\uc77c \uc124\uc815\uc744 ko\ub85c \ubcc0\uacbd\ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},'i18n: {\n defaultLocale: "ko",\n locales: ["ko"],\n},\n')),(0,r.kt)("h3",{id:"\ube14\ub85c\uadf8-\uae00-author"},"\ube14\ub85c\uadf8 \uae00 author"),(0,r.kt)("p",null,"\ud300\uc6d0 \ubcc4\ub85c \ubb38\uc11c\ub97c \uad00\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 \uc5b4\ub5a4 \ud300\uc6d0\uc774 \uae00\uc744 \uc791\uc131\ud588\ub294\uc9c0 \uc124\uc815\ud574\uc57c \ud55c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"author",src:n(31897).Z,width:"2362",height:"1076"})),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"authors.yml")," \ud30c\uc77c\uc744 \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790\uc5d0 \ub300\ud55c \uae30\ubcf8 \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml",metastring:'title="/blog/authors.yml"',title:'"/blog/authors.yml"'},"herb:\n name: \ud5c8\ube0c\n title: Backend\n url: https://github.com/greeng00se\n image_url: https://github.com/greeng00se.png\n\nmallang:\n name: \ub9d0\ub791\n title: Backend\n url: https://github.com/shin-mallang\n image_url: https://github.com/shin-mallang.png\n")),(0,r.kt)("p",null,"\ube14\ub85c\uadf8 \uae00\uc744 \uc791\uc131\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc774 authors\uc5d0 \ub123\uc5b4\uc8fc\uae30\ub9cc \ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mdx"},"---\nslug: 1\ntitle: Hello World\nauthors: [herb, mallang]\ntags: [hello, docusaurus]\n---\n\n\uccab \ubc88\uc9f8 \ubb38\uc11c \ub0b4\uc6a9\n")))}p.isMDXComponent=!0},41785:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/algolia-3dbac5c1606f7f0daed9cb27a429db50.png"},31897:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/author-1bd517bb7763257e2139e1063fd92492.png"},29094:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/github-d866f69755a1e17d4f17a262bd30d56d.png"},4730:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/key-2d0b59e69e9ca0b21c49b76159266e74.png"}}]); \ No newline at end of file diff --git a/assets/js/1251d98b.79f485fe.js b/assets/js/1251d98b.79f485fe.js deleted file mode 100644 index 54146f9cf..000000000 --- a/assets/js/1251d98b.79f485fe.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6276],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>k});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,u=e.parentName,s=o(e,["components","mdxType","originalType","parentName"]),m=c(r),k=a,b=m["".concat(u,".").concat(k)]||m[k]||i[k]||p;return r?n.createElement(b,l(l({ref:t},s),{},{components:r})):n.createElement(b,l({ref:t},s))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=m;var o={};for(var u in t)hasOwnProperty.call(t,u)&&(o[u]=t[u]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var c=2;c{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>i,frontMatter:()=>p,metadata:()=>o,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",slug:"chess-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,o={permalink:"/chess-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",description:"1, 2\ub2e8\uacc4//github.com/woowacourse/java-chess/pull/441",date:"2023-03-31T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 31\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.705,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",slug:"chess-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",permalink:"/woowacourse-level1-retrospective"},nextItem:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",permalink:"/grasp"}},u={authorsImageUrls:[]},c=[{value:"\uccb4\uc2a4",id:"\uccb4\uc2a4",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],s={toc:c};function i(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1, 2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-chess/pull/441"},"https://github.com/woowacourse/java-chess/pull/441"),(0,a.kt)("br",{parentName:"p"}),"\n","3, 4\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-chess/pull/529"},"https://github.com/woowacourse/java-chess/pull/529")," ")),(0,a.kt)("h3",{id:"\uccb4\uc2a4"},"\uccb4\uc2a4"),(0,a.kt)("p",null,"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\ub294 \uac00\ube44\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4!",(0,a.kt)("br",{parentName:"p"}),"\n","\uccb4\uc2a4\ub294 \uc774\uc804 \ubbf8\uc158\ub4e4\ubcf4\ub2e4 \ud6e8\uc52c \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uac00\ube44\uc640 \ub098\ub294 \uccb4\uc2a4 \ub3c4\uba54\uc778\uc774 \uc775\uc219\ud574\uc11c \ub354 \ud3b8\ud55c \ub9c8\uc74c\uc73c\ub85c \uc2dc\uc791\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc5b4\ub824\uc6e0\ub358 \ubd80\ubd84\uc740 \uae30\ubb3c\uc758 \uc774\ub3d9, \uc774\ub3d9\uc2dc \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uac00\ube44\uac00 \uc9d1\uc5d0\uac00\uc11c\ub3c4 \uae30\ubb3c\uc758 \uc774\ub3d9 \uad00\ub828\ud574 \uc0dd\uac01 \uc815\ub9ac\ud55c \uae00\uc744 \ubcf4\ub0b4\uc918\uc11c \ub354\uc6b1 \ube68\ub9ac \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\uc885\uc801\uc73c\ub85c \uacb0\uc815\ud55c \ubd80\ubd84\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5\uc5ec\ubd80"),(0,a.kt)("br",{parentName:"p"}),"\n","Rank\uc640 File\uc740 \uac01\uac01 \uc704\uce58\uac12\uc744 \uac00\uc9c0\uace0 \uc788\uace0, \uac12\uc758 \ucc28\uc774\ub97c \uc774\uc6a9\ud574\uc11c \uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uacc4\uc0b0\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c1\uc120 \u2192 Rank\uc640 File \ucc28\uc774 \uc911 \ud558\ub098\uac00 0\uc774\uc5b4\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub300\uac01\uc120 \u2192 Rank\uc640 File \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \uac19\uc544\uc57c \ud55c\ub2e4. ex) abs(-2) == abs(2)",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\uc774\ud2b8 \u2192 \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \ud558\ub098\ub294 2 \ub098\uba38\uc9c0 \ud558\ub098\ub294 1\uc774\uc5b4\uc57c \ud55c\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub3c4\ucc29 \uce78\uc758 \uae30\ubb3c \uc5ec\ubd80"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\uad70 \u2192 \uc774\ub3d9\uc774 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc801\uad70 \u2192 \uc774\ub3d9\uc774 \uac00\ub2a5\ud558\ub2e4. \uc801\uad70\uc744 \uc7a1\ub294\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc911\uac04\uc5d0 \uae30\ubb3c \uc874\uc7ac \uc5ec\ubd80"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub3d9 \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\uba74 \uc548\ub41c\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0ac\uc6a9"),(0,a.kt)("br",{parentName:"p"}),"\n","\uccb4\uc2a4 \ubbf8\uc158\uc740 \ud2b9\ubcc4\ud558\uac8c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc5f0\uacb0\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uccb4\uc2a4 \uac8c\uc784\uc758 \uc0c1\ud0dc\ub97c \ub2e4\uc74c\uc758 \ub450\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uc815\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95 "),(0,a.kt)("li",{parentName:"ul"},"\uae30\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uac8c\uc784\uc744 \ubd88\ub7ec\uc640 \uae30\ubcf4\ub300\ub85c \uc774\ub3d9\uc2dc\ud0a4\ub294 \ubc29\ubc95 ")),(0,a.kt)("p",null,"\uae30\ubb3c\uc774 \uc774\ub3d9\ud560 \ub54c\ub9c8\ub2e4 \uac12\uc744 \uc800\uc7a5\ud558\uace0 \uc2f6\uc5c8\uace0, \uae30\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\uc9c0 \uc54a\uc740 \uc774\uc720\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\ud134\uacfc \uac19\uc740 \ubd80\uac00\uc801\uc778 \uc694\uc18c\ub97c \uc800\uc7a5\ud574\uc57c \ud55c\ub2e4. "),(0,a.kt)("li",{parentName:"ul"},"\uc774\ub3d9\uc744 \ud560 \ub54c \uae30\ubb3c\uc774 \uc7a1\ud788\ub294 \uacbd\uc6b0 update \ucffc\ub9ac(\uc774\ub3d9 \uae30\ubb3c)\uc640 delete(\uc7a1\ud78c \uae30\ubb3c) 2\uac1c\uc758 \ucffc\ub9ac\ub97c \ub0a0\ub824\uc57c \ud55c\ub2e4. "),(0,a.kt)("li",{parentName:"ul"},"\ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ub3c4\uba54\uc778\uc758 \ubcc0\uacbd\uc774 \ud06c\uac8c(\ucd08\uae30 \uc0c1\ud0dc\ub97c \uad6c\uc131\ud558\ub294 \ubd80\ubd84) \uc77c\uc5b4\ub098\uc57c \ud55c\ub2e4. ")),(0,a.kt)("p",null,"\uc815\ub9ac\ud558\uc790\uba74 \uae30\ubb3c \uc804\uccb4 \uc800\uc7a5\uacfc \uae30\ubcf4 \uc800\uc7a5\uc740 \ub2e4\uc74c\uacfc \ucc28\uc774\uac00 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcf4\ub4dc\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc\uc5d0\uc11c 32\uac1c\uc758 Insert \ucffc\ub9ac(\uae30\ubb3c\uc758 \uc704\uce58) + \uae30\ubb3c \uc774\ub3d9 \uc2dc \uc6c0\uc9c1\uc784 \ubcc0\uacbd(\uc7a1\ud788\ub294 \uacbd\uc6b0 2\uac1c\uc758 \ucffc\ub9ac)",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ubcf4\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uad6c\uc131 + \uc800\uc7a5\ub41c \uae30\ubcf4\ub97c select \ucffc\ub9ac\ub85c \uc870\ud68c\ud574\uc11c \uc0ac\uc6a9(1\ud68c) + insert \ucffc\ub9ac(\uc774\ub3d9 \ub2f9 1\ud68c)"),(0,a.kt)("p",null,"\ucd94\uac00\ub85c \uae30\ubcf4\uc800\uc7a5\uc774 \uad6c\ud604\ub3c4 \ub354\uc6b1 \uac04\ub2e8\ud558\ub2e4. \ud83d\udc4d "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ubd80\uac00\uc801\uc778 \ubd80\ubd84")),(0,a.kt)("p",null,"\ub9ac\ubdf0\uc5b4\uc778 \ucc30\ub9ac\ud83c\udf6b\uac00 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \uac8c\uc784\uc774 \uc9c4\ud589\ub41c\ub2e4\uba74 \uc5b4\ub5a8\uc9c0? \uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ub2e4\uc591\ud55c \uc2dc\ub3c4\ub97c \ud574\ubd24\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\ub204\ub204\uc758 \ub3c4\uc6c0\uc73c\ub85c ConnectionPool \uad6c\ud604 "),(0,a.kt)("li",{parentName:"ul"},"ThreadLocal \uc0ac\uc6a9\ud574\uc11c \uc4f0\ub808\ub4dc \ubcc4 \uc138\uc158 \uad00\ub9ac "),(0,a.kt)("li",{parentName:"ul"},"\uc2e4\uc81c\ub85c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4\uc5d0\uc11c \uccb4\uc2a4 \uac8c\uc784\uc774 \uc9c4\ud589\ub418\ub294 Board\ub97c ConcurrentHashMap\uc73c\ub85c \uc800\uc7a5(\uc0ac\uc2e4 \uc774 \ubd80\ubd84\uc740 \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ud544\uc694\uc5c6\uc9c0\ub9cc 2\uba85\uc774 \uc11c\ub85c \uac8c\uc784\ud558\ub294 \uacbd\uc6b0\ub97c \uc0dd\uac01\ud574\uc11c \ub123\uc5b4\ubcf4\uc558\ub2e4.) ")),(0,a.kt)("p",null,"\ub450 \uba85\uc774 \uc11c\ub85c \uac19\uc740 \ubc29\uc5d0 \uc785\uc7a5\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4\uba74 \ucd9c\ub825\ud558\ub294 \ubd80\ubd84\uc774 \uae4c\ub2e4\ub85c\uc6cc\uc9c8 \uac83 \uac19\ub2e4\uace0 \uc608\uc0c1\ub418\uc5b4(Board\uc5d0 \uc635\uc800\ubc84 \ud328\ud134\uc744 \uc0ac\uc6a9\ud574\uc57c\ub418\ub098?) \ud574\ubcfc \uc5c4\ub450\uac00 \ub098\uc9c0 \uc54a\uc558\ub2e4. "),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc9c0 \ubabb\ud55c \ubd80\ubd84"),(0,a.kt)("br",{parentName:"p"}),"\n","DB \uad00\ub828 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub3c4\uba54\uc778 \ub85c\uc9c1\uc5d0\ub9cc \uc9d1\uc911\ud558\ub2e4\ubcf4\ub2c8 \uc815\uc801 \uc911\uc694\ud55c DB\uc758 \ucf54\ub4dc\uc758 \uc608\uc678\ucc98\ub9ac, \ube48 \uac12\uc744 \ubc18\ud658 \ud558\ub294 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucc98\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ucc30\ub9ac\uc758 \uaf3c\uaf3c\ud55c \ub9ac\ubdf0\ub85c DB\ubd80\ubd84\uacfc \ub098\ub9cc\uc758 JdbcTemplate\uc744 \uae54\ub054\ud558\uac8c \uad6c\ud604\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ub2f4\uac10"),(0,a.kt)("br",{parentName:"p"}),"\n","\ucd08\ubc18\uc5d0\ub294 \uc5ec\uc720\ub86d\uc9c0\ub9cc \uc81c\ucd9c \ub9c8\uac10\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \uc218\ub85d \uc0ac\ub78c\uc774 \uae09\ud574\uc9c0\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\ud560 \ub550 \uc18d\ub3c4\ub97c \uc870\uc808\ud558\uace0, \ub9c8\uc74c\uc5d0 \uc5ec\uc720\ub97c \uac00\uc838\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"DAO \uc911\ubcf5 \uc81c\uac70")),(0,a.kt)("p",null,"\ud504\ub864\ub85c\uadf8\uc5d0 ",(0,a.kt)("a",{parentName:"p",href:"https://prolog.techcourse.co.kr/studylogs/2947"},"\uae00"),"\uc744 \uc791\uc131\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","DAO\ub97c \uc791\uc131\ud558\ub294\ub370 try-catch-resources\uc640 \uc5ec\ub7ec \ucf54\ub4dc\uac00 \uc911\ubcf5\ub418\uc11c \uc81c\uac70\ud558\uace0\uc2f6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc73c\ub85c \uae54\ub054\ud558\uac8c \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\udc4d"),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud398\uc5b4 \uc0dd\uac01\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uac00\ube44\ub294 \ub204\uad6c\ubcf4\ub2e4 \ud398\uc5b4\ub97c \uc0dd\uac01\ud558\uace0, \ubc30\ub824\ud574\uc8fc\ub294 \ud398\uc5b4\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04 \uc911\uac04 \ub2f9 \ub5a8\uc5b4\uc9c8\uae4c\ubd10 \uac71\uc815\ub3c4 \ud574\uc8fc\uace0, \ub098\uc758 \ucee8\ub514\uc158\ub3c4 \ud655\uc778\ud574\uc92c\ub2e4! "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ubbf8\uc158 \ubab0\uc785\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\uadfc\uc5d0 \ubbf8\uc158\uc5d0 \uc798 \ubab0\uc785\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac00\ube44\ub294 \ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \ubbf8\uc158\uc5d0 \ub300\ud55c \ubab0\uc785\ub3c4\uac00 \ub9e4\uc6b0 \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9d1\uc5d0\uac00\uc11c\ub3c4 \uccb4\uc2a4 \uc774\ub3d9\uc5d0 \ub300\ud55c \ub85c\uc9c1\uc744 \uc5b4\ub5bb\uac8c \uad6c\ud604\ud560 \uc9c0 \uc0dd\uac01\ud55c \ub4a4 \uaf3c\uaf3c\ud574\uc11c \uc815\ub9ac\ud574\uc11c \ub098\uc5d0\uac8c \ubcf4\ub0b4\uc8fc\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub355\ubd84\uc5d0 \ub098\ub3c4 \uac00\ube44\uc758 \uc0dd\uac01\uc744 \uc54c \uc218 \uc788\uc5b4\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294\ub370 \uac00\uc18d\ub3c4\uac00 \ubd99\uc740 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ubbf8\uc158\uc744 \uc798 \ub9c8\ubb34\ub9ac\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c\uc774 \uc804\ub2ec\ub418\uc11c \uadf8\ub7f0\uc9c0 \ub098\ub3c4 \ub369\ub2ec\uc544 \uc5f4\uc2ec\ud788 \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\ude04 "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc194\uc9c1\ud568"),(0,a.kt)("br",{parentName:"p"}),"\n","\uba3c\uc800 \ud68c\uace0\ud558\uc790\uace0 \ub9d0 \uac78\uc5b4\uc918\uc11c \uc815\ub9d0 \uace0\ub9c8\uc6e0\ub2e4\uace0 \ud45c\ud604\ud574\uc8fc\ub294 \ubd80\ubd84",(0,a.kt)("br",{parentName:"p"}),"\n","\ubaa8\ub974\ub294\uac8c \uc788\uc73c\uba74 \uc194\uc9c1\ud558\uac8c \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\uc758 \uc758\uacac\uc744 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud55c \uc0c1\ud0dc\ub85c \uc804\ub2ec\ud560 \ub54c \uc774\ud574\uac00 \uc548\ub418\uc5c8\ub2e4\uace0 \uc815\ud655\ud788 \uc804\ub2ec\ud574\uc8fc\ub294 \ubd80\ubd84",(0,a.kt)("br",{parentName:"p"}),"\n","\uc194\uc9c1\ud568\uc740 \ud398\uc5b4\ud560 \ub54c \uc911\uc694\ud55c \ubd80\ubd84\uc778 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ucc30\ub9ac\ud83c\udf6b \uccb4\uc2a4 \ubbf8\uc158\ub54c \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0 \ub0a8\uaca8\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4!"))}i.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1251d98b.8c5715bc.js b/assets/js/1251d98b.8c5715bc.js new file mode 100644 index 000000000..946a12804 --- /dev/null +++ b/assets/js/1251d98b.8c5715bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6276],{40469:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>j,frontMatter:()=>c,metadata:()=>l,toc:()=>a});var s=r(85893),t=r(3905);const c={title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",slug:"chess-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,l={permalink:"/chess-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",description:"1, 2\ub2e8\uacc4//github.com/woowacourse/java-chess/pull/441",date:"2023-03-31T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 31\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.705,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",slug:"chess-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",permalink:"/woowacourse-level1-retrospective"},nextItem:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",permalink:"/grasp"}},o={authorsImageUrls:[]},a=[{value:"\uccb4\uc2a4",id:"\uccb4\uc2a4",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function h(e){const n={a:"a",admonition:"admonition",br:"br",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.ah)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,s.jsxs)(n.p,{children:["1, 2\ub2e8\uacc4: ",(0,s.jsx)(n.a,{href:"https://github.com/woowacourse/java-chess/pull/441",children:"https://github.com/woowacourse/java-chess/pull/441"}),(0,s.jsx)(n.br,{}),"\n","3, 4\ub2e8\uacc4: ",(0,s.jsx)(n.a,{href:"https://github.com/woowacourse/java-chess/pull/529",children:"https://github.com/woowacourse/java-chess/pull/529"})]})}),"\n",(0,s.jsx)(n.h3,{id:"\uccb4\uc2a4",children:"\uccb4\uc2a4"}),"\n",(0,s.jsxs)(n.p,{children:["\uccb4\uc2a4 \ubbf8\uc158\uc5d0\ub294 \uac00\ube44\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4!",(0,s.jsx)(n.br,{}),"\n","\uccb4\uc2a4\ub294 \uc774\uc804 \ubbf8\uc158\ub4e4\ubcf4\ub2e4 \ud6e8\uc52c \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778\uc774\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \uac00\ube44\uc640 \ub098\ub294 \uccb4\uc2a4 \ub3c4\uba54\uc778\uc774 \uc775\uc219\ud574\uc11c \ub354 \ud3b8\ud55c \ub9c8\uc74c\uc73c\ub85c \uc2dc\uc791\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc5b4\ub824\uc6e0\ub358 \ubd80\ubd84\uc740 \uae30\ubb3c\uc758 \uc774\ub3d9, \uc774\ub3d9\uc2dc \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:["\uac00\ube44\uac00 \uc9d1\uc5d0\uac00\uc11c\ub3c4 \uae30\ubb3c\uc758 \uc774\ub3d9 \uad00\ub828\ud574 \uc0dd\uac01 \uc815\ub9ac\ud55c \uae00\uc744 \ubcf4\ub0b4\uc918\uc11c \ub354\uc6b1 \ube68\ub9ac \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ucd5c\uc885\uc801\uc73c\ub85c \uacb0\uc815\ud55c \ubd80\ubd84\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5\uc5ec\ubd80"}),(0,s.jsx)(n.br,{}),"\n","Rank\uc640 File\uc740 \uac01\uac01 \uc704\uce58\uac12\uc744 \uac00\uc9c0\uace0 \uc788\uace0, \uac12\uc758 \ucc28\uc774\ub97c \uc774\uc6a9\ud574\uc11c \uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uacc4\uc0b0\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uc9c1\uc120 \u2192 Rank\uc640 File \ucc28\uc774 \uc911 \ud558\ub098\uac00 0\uc774\uc5b4\uc57c \ud55c\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub300\uac01\uc120 \u2192 Rank\uc640 File \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \uac19\uc544\uc57c \ud55c\ub2e4. ex) abs(-2) == abs(2)",(0,s.jsx)(n.br,{}),"\n","\ub098\uc774\ud2b8 \u2192 \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \ud558\ub098\ub294 2 \ub098\uba38\uc9c0 \ud558\ub098\ub294 1\uc774\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\ub3c4\ucc29 \uce78\uc758 \uae30\ubb3c \uc5ec\ubd80"}),(0,s.jsx)(n.br,{}),"\n","\uc544\uad70 \u2192 \uc774\ub3d9\uc774 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uc801\uad70 \u2192 \uc774\ub3d9\uc774 \uac00\ub2a5\ud558\ub2e4. \uc801\uad70\uc744 \uc7a1\ub294\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uc911\uac04\uc5d0 \uae30\ubb3c \uc874\uc7ac \uc5ec\ubd80"}),(0,s.jsx)(n.br,{}),"\n","\uc774\ub3d9 \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\uba74 \uc548\ub41c\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0ac\uc6a9"}),(0,s.jsx)(n.br,{}),"\n","\uccb4\uc2a4 \ubbf8\uc158\uc740 \ud2b9\ubcc4\ud558\uac8c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc5f0\uacb0\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uccb4\uc2a4 \uac8c\uc784\uc758 \uc0c1\ud0dc\ub97c \ub2e4\uc74c\uc758 \ub450\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uc815\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95"}),"\n",(0,s.jsx)(n.li,{children:"\uae30\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uac8c\uc784\uc744 \ubd88\ub7ec\uc640 \uae30\ubcf4\ub300\ub85c \uc774\ub3d9\uc2dc\ud0a4\ub294 \ubc29\ubc95"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["\uae30\ubb3c\uc774 \uc774\ub3d9\ud560 \ub54c\ub9c8\ub2e4 \uac12\uc744 \uc800\uc7a5\ud558\uace0 \uc2f6\uc5c8\uace0, \uae30\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\uc9c0 \uc54a\uc740 \uc774\uc720\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\ud134\uacfc \uac19\uc740 \ubd80\uac00\uc801\uc778 \uc694\uc18c\ub97c \uc800\uc7a5\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,s.jsx)(n.li,{children:"\uc774\ub3d9\uc744 \ud560 \ub54c \uae30\ubb3c\uc774 \uc7a1\ud788\ub294 \uacbd\uc6b0 update \ucffc\ub9ac(\uc774\ub3d9 \uae30\ubb3c)\uc640 delete(\uc7a1\ud78c \uae30\ubb3c) 2\uac1c\uc758 \ucffc\ub9ac\ub97c \ub0a0\ub824\uc57c \ud55c\ub2e4."}),"\n",(0,s.jsx)(n.li,{children:"\ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ub3c4\uba54\uc778\uc758 \ubcc0\uacbd\uc774 \ud06c\uac8c(\ucd08\uae30 \uc0c1\ud0dc\ub97c \uad6c\uc131\ud558\ub294 \ubd80\ubd84) \uc77c\uc5b4\ub098\uc57c \ud55c\ub2e4."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["\uc815\ub9ac\ud558\uc790\uba74 \uae30\ubb3c \uc804\uccb4 \uc800\uc7a5\uacfc \uae30\ubcf4 \uc800\uc7a5\uc740 \ub2e4\uc74c\uacfc \ucc28\uc774\uac00 \uc788\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ubcf4\ub4dc\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc\uc5d0\uc11c 32\uac1c\uc758 Insert \ucffc\ub9ac(\uae30\ubb3c\uc758 \uc704\uce58) + \uae30\ubb3c \uc774\ub3d9 \uc2dc \uc6c0\uc9c1\uc784 \ubcc0\uacbd(\uc7a1\ud788\ub294 \uacbd\uc6b0 2\uac1c\uc758 \ucffc\ub9ac)",(0,s.jsx)(n.br,{}),"\n","\uae30\ubcf4\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uad6c\uc131 + \uc800\uc7a5\ub41c \uae30\ubcf4\ub97c select \ucffc\ub9ac\ub85c \uc870\ud68c\ud574\uc11c \uc0ac\uc6a9(1\ud68c) + insert \ucffc\ub9ac(\uc774\ub3d9 \ub2f9 1\ud68c)"]}),"\n",(0,s.jsx)(n.p,{children:"\ucd94\uac00\ub85c \uae30\ubcf4\uc800\uc7a5\uc774 \uad6c\ud604\ub3c4 \ub354\uc6b1 \uac04\ub2e8\ud558\ub2e4. \ud83d\udc4d"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"\ubd80\uac00\uc801\uc778 \ubd80\ubd84"})}),"\n",(0,s.jsx)(n.p,{children:"\ub9ac\ubdf0\uc5b4\uc778 \ucc30\ub9ac\ud83c\udf6b\uac00 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \uac8c\uc784\uc774 \uc9c4\ud589\ub41c\ub2e4\uba74 \uc5b4\ub5a8\uc9c0? \uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ub2e4\uc591\ud55c \uc2dc\ub3c4\ub97c \ud574\ubd24\ub2e4."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\ub204\ub204\uc758 \ub3c4\uc6c0\uc73c\ub85c ConnectionPool \uad6c\ud604"}),"\n",(0,s.jsx)(n.li,{children:"ThreadLocal \uc0ac\uc6a9\ud574\uc11c \uc4f0\ub808\ub4dc \ubcc4 \uc138\uc158 \uad00\ub9ac"}),"\n",(0,s.jsx)(n.li,{children:"\uc2e4\uc81c\ub85c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4\uc5d0\uc11c \uccb4\uc2a4 \uac8c\uc784\uc774 \uc9c4\ud589\ub418\ub294 Board\ub97c ConcurrentHashMap\uc73c\ub85c \uc800\uc7a5(\uc0ac\uc2e4 \uc774 \ubd80\ubd84\uc740 \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ud544\uc694\uc5c6\uc9c0\ub9cc 2\uba85\uc774 \uc11c\ub85c \uac8c\uc784\ud558\ub294 \uacbd\uc6b0\ub97c \uc0dd\uac01\ud574\uc11c \ub123\uc5b4\ubcf4\uc558\ub2e4.)"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"\ub450 \uba85\uc774 \uc11c\ub85c \uac19\uc740 \ubc29\uc5d0 \uc785\uc7a5\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4\uba74 \ucd9c\ub825\ud558\ub294 \ubd80\ubd84\uc774 \uae4c\ub2e4\ub85c\uc6cc\uc9c8 \uac83 \uac19\ub2e4\uace0 \uc608\uc0c1\ub418\uc5b4(Board\uc5d0 \uc635\uc800\ubc84 \ud328\ud134\uc744 \uc0ac\uc6a9\ud574\uc57c\ub418\ub098?) \ud574\ubcfc \uc5c4\ub450\uac00 \ub098\uc9c0 \uc54a\uc558\ub2e4."}),"\n",(0,s.jsx)(n.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc9c0 \ubabb\ud55c \ubd80\ubd84"}),(0,s.jsx)(n.br,{}),"\n","DB \uad00\ub828 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub3c4\uba54\uc778 \ub85c\uc9c1\uc5d0\ub9cc \uc9d1\uc911\ud558\ub2e4\ubcf4\ub2c8 \uc815\uc801 \uc911\uc694\ud55c DB\uc758 \ucf54\ub4dc\uc758 \uc608\uc678\ucc98\ub9ac, \ube48 \uac12\uc744 \ubc18\ud658 \ud558\ub294 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucc98\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \ucc30\ub9ac\uc758 \uaf3c\uaf3c\ud55c \ub9ac\ubdf0\ub85c DB\ubd80\ubd84\uacfc \ub098\ub9cc\uc758 JdbcTemplate\uc744 \uae54\ub054\ud558\uac8c \uad6c\ud604\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ub2f4\uac10"}),(0,s.jsx)(n.br,{}),"\n","\ucd08\ubc18\uc5d0\ub294 \uc5ec\uc720\ub86d\uc9c0\ub9cc \uc81c\ucd9c \ub9c8\uac10\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \uc218\ub85d \uc0ac\ub78c\uc774 \uae09\ud574\uc9c0\ub294 \uac83 \uac19\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub2e4\uc74c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\ud560 \ub550 \uc18d\ub3c4\ub97c \uc870\uc808\ud558\uace0, \ub9c8\uc74c\uc5d0 \uc5ec\uc720\ub97c \uac00\uc838\uc57c\uaca0\ub2e4."]}),"\n",(0,s.jsx)(n.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"DAO \uc911\ubcf5 \uc81c\uac70"})}),"\n",(0,s.jsxs)(n.p,{children:["\ud504\ub864\ub85c\uadf8\uc5d0 ",(0,s.jsx)(n.a,{href:"https://prolog.techcourse.co.kr/studylogs/2947",children:"\uae00"}),"\uc744 \uc791\uc131\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","DAO\ub97c \uc791\uc131\ud558\ub294\ub370 try-catch-resources\uc640 \uc5ec\ub7ec \ucf54\ub4dc\uac00 \uc911\ubcf5\ub418\uc11c \uc81c\uac70\ud558\uace0\uc2f6\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc73c\ub85c \uae54\ub054\ud558\uac8c \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\udc4d"]}),"\n",(0,s.jsx)(n.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\ud398\uc5b4 \uc0dd\uac01\ud558\uae30"}),(0,s.jsx)(n.br,{}),"\n","\uac00\ube44\ub294 \ub204\uad6c\ubcf4\ub2e4 \ud398\uc5b4\ub97c \uc0dd\uac01\ud558\uace0, \ubc30\ub824\ud574\uc8fc\ub294 \ud398\uc5b4\uc600\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uc911\uac04 \uc911\uac04 \ub2f9 \ub5a8\uc5b4\uc9c8\uae4c\ubd10 \uac71\uc815\ub3c4 \ud574\uc8fc\uace0, \ub098\uc758 \ucee8\ub514\uc158\ub3c4 \ud655\uc778\ud574\uc92c\ub2e4!"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\ubbf8\uc158 \ubab0\uc785\ud558\uae30"}),(0,s.jsx)(n.br,{}),"\n","\ucd5c\uadfc\uc5d0 \ubbf8\uc158\uc5d0 \uc798 \ubab0\uc785\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uac00\ube44\ub294 \ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \ubbf8\uc158\uc5d0 \ub300\ud55c \ubab0\uc785\ub3c4\uac00 \ub9e4\uc6b0 \uc88b\uc558\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uc9d1\uc5d0\uac00\uc11c\ub3c4 \uccb4\uc2a4 \uc774\ub3d9\uc5d0 \ub300\ud55c \ub85c\uc9c1\uc744 \uc5b4\ub5bb\uac8c \uad6c\ud604\ud560 \uc9c0 \uc0dd\uac01\ud55c \ub4a4 \uaf3c\uaf3c\ud574\uc11c \uc815\ub9ac\ud574\uc11c \ub098\uc5d0\uac8c \ubcf4\ub0b4\uc8fc\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub355\ubd84\uc5d0 \ub098\ub3c4 \uac00\ube44\uc758 \uc0dd\uac01\uc744 \uc54c \uc218 \uc788\uc5b4\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294\ub370 \uac00\uc18d\ub3c4\uac00 \ubd99\uc740 \uac83 \uac19\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub610\ud55c \ubbf8\uc158\uc744 \uc798 \ub9c8\ubb34\ub9ac\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c\uc774 \uc804\ub2ec\ub418\uc11c \uadf8\ub7f0\uc9c0 \ub098\ub3c4 \ub369\ub2ec\uc544 \uc5f4\uc2ec\ud788 \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\ude04"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uc194\uc9c1\ud568"}),(0,s.jsx)(n.br,{}),"\n","\uba3c\uc800 \ud68c\uace0\ud558\uc790\uace0 \ub9d0 \uac78\uc5b4\uc918\uc11c \uc815\ub9d0 \uace0\ub9c8\uc6e0\ub2e4\uace0 \ud45c\ud604\ud574\uc8fc\ub294 \ubd80\ubd84",(0,s.jsx)(n.br,{}),"\n","\ubaa8\ub974\ub294\uac8c \uc788\uc73c\uba74 \uc194\uc9c1\ud558\uac8c \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84",(0,s.jsx)(n.br,{}),"\n","\ub098\uc758 \uc758\uacac\uc744 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud55c \uc0c1\ud0dc\ub85c \uc804\ub2ec\ud560 \ub54c \uc774\ud574\uac00 \uc548\ub418\uc5c8\ub2e4\uace0 \uc815\ud655\ud788 \uc804\ub2ec\ud574\uc8fc\ub294 \ubd80\ubd84",(0,s.jsx)(n.br,{}),"\n","\uc194\uc9c1\ud568\uc740 \ud398\uc5b4\ud560 \ub54c \uc911\uc694\ud55c \ubd80\ubd84\uc778 \uac83 \uac19\ub2e4."]}),"\n",(0,s.jsx)(n.p,{children:"\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ucc30\ub9ac\ud83c\udf6b \uccb4\uc2a4 \ubbf8\uc158\ub54c \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0 \ub0a8\uaca8\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4!"})]})}function j(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var s=r(67294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function c(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);n&&(s=s.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,s)}return r}function i(e){for(var n=1;n=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var o=s.createContext({}),a=function(e){var n=s.useContext(o),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},h={inlineCode:"code",wrapper:function(e){var n=e.children;return s.createElement(s.Fragment,{},n)}},j=s.forwardRef((function(e,n){var r=e.components,t=e.mdxType,c=e.originalType,o=e.parentName,j=l(e,["components","mdxType","originalType","parentName"]),x=a(r),p=t,d=x["".concat(o,".").concat(p)]||x[p]||h[p]||c;return r?s.createElement(d,i(i({ref:n},j),{},{components:r})):s.createElement(d,i({ref:n},j))}));j.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/130.233dcaf1.js b/assets/js/130.233dcaf1.js new file mode 100644 index 000000000..b389b51c2 --- /dev/null +++ b/assets/js/130.233dcaf1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[130],{61460:(e,t,s)=>{s.d(t,{Z:()=>f});var r=s(67294),a=s(86010),n=s(58207),l=s(87524),i=s(39960),o=s(95999),c=s(16550),m=s(48596);function d(e){const{pathname:t}=(0,c.TH)();return(0,r.useMemo)((()=>e.filter((e=>function(e,t){return!(e.unlisted&&!(0,m.Mg)(e.permalink,t))}(e,t)))),[e,t])}const u={sidebar:"sidebar_re4s",sidebarItemTitle:"sidebarItemTitle_pO2u",sidebarItemList:"sidebarItemList_Yudw",sidebarItem:"sidebarItem__DBe",sidebarItemLink:"sidebarItemLink_mo7H",sidebarItemLinkActive:"sidebarItemLinkActive_I1ZP"};var h=s(85893);function g(e){let{sidebar:t}=e;const s=d(t.items);return(0,h.jsx)("aside",{className:"col col--3",children:(0,h.jsxs)("nav",{className:(0,a.Z)(u.sidebar,"thin-scrollbar"),"aria-label":(0,o.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"}),children:[(0,h.jsx)("div",{className:(0,a.Z)(u.sidebarItemTitle,"margin-bottom--md"),children:t.title}),(0,h.jsx)("ul",{className:(0,a.Z)(u.sidebarItemList,"clean-list"),children:s.map((e=>(0,h.jsx)("li",{className:u.sidebarItem,children:(0,h.jsx)(i.Z,{isNavLink:!0,to:e.permalink,className:u.sidebarItemLink,activeClassName:u.sidebarItemLinkActive,children:e.title})},e.permalink)))})]})})}var p=s(13102);function x(e){let{sidebar:t}=e;const s=d(t.items);return(0,h.jsx)("ul",{className:"menu__list",children:s.map((e=>(0,h.jsx)("li",{className:"menu__list-item",children:(0,h.jsx)(i.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active",children:e.title})},e.permalink)))})}function j(e){return(0,h.jsx)(p.Zo,{component:x,props:e})}function b(e){let{sidebar:t}=e;const s=(0,l.i)();return t?.items.length?"mobile"===s?(0,h.jsx)(j,{sidebar:t}):(0,h.jsx)(g,{sidebar:t}):null}function f(e){const{sidebar:t,toc:s,children:r,...l}=e,i=t&&t.items.length>0;return(0,h.jsx)(n.Z,{...l,children:(0,h.jsx)("div",{className:"container margin-vert--lg",children:(0,h.jsxs)("div",{className:"row",children:[(0,h.jsx)(b,{sidebar:t}),(0,h.jsx)("main",{className:(0,a.Z)("col",{"col--7":i,"col--9 col--offset-1":!i}),itemScope:!0,itemType:"https://schema.org/Blog",children:r}),s&&(0,h.jsx)("div",{className:"col col--2",children:s})]})})})}},30390:(e,t,s)=>{s.d(t,{Z:()=>L});s(67294);var r=s(86010),a=s(9460),n=s(44996),l=s(85893);function i(e){let{children:t,className:s}=e;const{frontMatter:r,assets:i,metadata:{description:o}}=(0,a.C)(),{withBaseUrl:c}=(0,n.C)(),m=i.image??r.image,d=r.keywords??[];return(0,l.jsxs)("article",{className:s,itemProp:"blogPost",itemScope:!0,itemType:"https://schema.org/BlogPosting",children:[o&&(0,l.jsx)("meta",{itemProp:"description",content:o}),m&&(0,l.jsx)("link",{itemProp:"image",href:c(m,{absolute:!0})}),d.length>0&&(0,l.jsx)("meta",{itemProp:"keywords",content:d.join(",")}),t]})}var o=s(39960);const c={title:"title_f1Hy"};function m(e){let{className:t}=e;const{metadata:s,isBlogPostPage:n}=(0,a.C)(),{permalink:i,title:m}=s,d=n?"h1":"h2";return(0,l.jsx)(d,{className:(0,r.Z)(c.title,t),itemProp:"headline",children:n?m:(0,l.jsx)(o.Z,{itemProp:"url",to:i,children:m})})}var d=s(95999),u=s(88824);const h={container:"container_mt6G"};function g(e){let{readingTime:t}=e;const s=function(){const{selectMessage:e}=(0,u.c)();return t=>{const s=Math.ceil(t);return e(s,(0,d.I)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:s}))}}();return(0,l.jsx)(l.Fragment,{children:s(t)})}function p(e){let{date:t,formattedDate:s}=e;return(0,l.jsx)("time",{dateTime:t,itemProp:"datePublished",children:s})}function x(){return(0,l.jsx)(l.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:s}=(0,a.C)(),{date:n,formattedDate:i,readingTime:o}=s;return(0,l.jsxs)("div",{className:(0,r.Z)(h.container,"margin-vert--md",t),children:[(0,l.jsx)(p,{date:n,formattedDate:i}),void 0!==o&&(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(x,{}),(0,l.jsx)(g,{readingTime:o})]})]})}function b(e){return e.href?(0,l.jsx)(o.Z,{...e}):(0,l.jsx)(l.Fragment,{children:e.children})}function f(e){let{author:t,className:s}=e;const{name:a,title:n,url:i,imageURL:o,email:c}=t,m=i||c&&`mailto:${c}`||void 0;return(0,l.jsxs)("div",{className:(0,r.Z)("avatar margin-bottom--sm",s),children:[o&&(0,l.jsx)(b,{href:m,className:"avatar__photo-link",children:(0,l.jsx)("img",{className:"avatar__photo",src:o,alt:a,itemProp:"image"})}),a&&(0,l.jsxs)("div",{className:"avatar__intro",itemProp:"author",itemScope:!0,itemType:"https://schema.org/Person",children:[(0,l.jsx)("div",{className:"avatar__name",children:(0,l.jsx)(b,{href:m,itemProp:"url",children:(0,l.jsx)("span",{itemProp:"name",children:a})})}),n&&(0,l.jsx)("small",{className:"avatar__subtitle",itemProp:"description",children:n})]})]})}const v={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function P(e){let{className:t}=e;const{metadata:{authors:s},assets:n}=(0,a.C)();if(0===s.length)return null;const i=s.every((e=>{let{name:t}=e;return!t}));return(0,l.jsx)("div",{className:(0,r.Z)("margin-top--md margin-bottom--sm",i?v.imageOnlyAuthorRow:"row",t),children:s.map(((e,t)=>(0,l.jsx)("div",{className:(0,r.Z)(!i&&"col col--6",i?v.imageOnlyAuthorCol:v.authorCol),children:(0,l.jsx)(f,{author:{...e,imageURL:n.authorsImageUrls[t]??e.imageURL}})},t)))})}function N(){return(0,l.jsxs)("header",{children:[(0,l.jsx)(m,{}),(0,l.jsx)(j,{}),(0,l.jsx)(P,{})]})}var _=s(18780),k=s(76643);function Z(e){let{children:t,className:s}=e;const{isBlogPostPage:n}=(0,a.C)();return(0,l.jsx)("div",{id:n?_.blogPostContainerID:void 0,className:(0,r.Z)("markdown",s),itemProp:"articleBody",children:(0,l.jsx)(k.Z,{children:t})})}var I=s(84881),w=s(71526);function C(){return(0,l.jsx)("b",{children:(0,l.jsx)(d.Z,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read More"})})}function T(e){const{blogPostTitle:t,...s}=e;return(0,l.jsx)(o.Z,{"aria-label":(0,d.I)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...s,children:(0,l.jsx)(C,{})})}const y={blogPostFooterDetailsFull:"blogPostFooterDetailsFull_mRVl"};function F(){const{metadata:e,isBlogPostPage:t}=(0,a.C)(),{tags:s,title:n,editUrl:i,hasTruncateMarker:o}=e,c=!t&&o,m=s.length>0;return m||c||i?(0,l.jsxs)("footer",{className:(0,r.Z)("row docusaurus-mt-lg",t&&y.blogPostFooterDetailsFull),children:[m&&(0,l.jsx)("div",{className:(0,r.Z)("col",{"col--9":c}),children:(0,l.jsx)(w.Z,{tags:s})}),t&&i&&(0,l.jsx)("div",{className:"col margin-top--sm",children:(0,l.jsx)(I.Z,{editUrl:i})}),c&&(0,l.jsx)("div",{className:(0,r.Z)("col text--right",{"col--3":m}),children:(0,l.jsx)(T,{blogPostTitle:n,to:e.permalink})})]}):null}function L(e){let{children:t,className:s}=e;const n=function(){const{isBlogPostPage:e}=(0,a.C)();return e?void 0:"margin-bottom--xl"}();return(0,l.jsxs)(i,{className:(0,r.Z)(n,s),children:[(0,l.jsx)(N,{}),(0,l.jsx)(Z,{children:t}),(0,l.jsx)(F,{})]})}},9460:(e,t,s)=>{s.d(t,{C:()=>o,n:()=>i});var r=s(67294),a=s(902),n=s(85893);const l=r.createContext(null);function i(e){let{children:t,content:s,isBlogPostPage:a=!1}=e;const i=function(e){let{content:t,isBlogPostPage:s}=e;return(0,r.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:s})),[t,s])}({content:s,isBlogPostPage:a});return(0,n.jsx)(l.Provider,{value:i,children:t})}function o(){const e=(0,r.useContext)(l);if(null===e)throw new a.i6("BlogPostProvider");return e}},88824:(e,t,s)=>{s.d(t,{c:()=>c});var r=s(67294),a=s(52263);const n=["zero","one","two","few","many","other"];function l(e){return n.filter((t=>e.includes(t)))}const i={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,a.Z)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),i}}),[e])}function c(){const e=o();return{selectMessage:(t,s)=>function(e,t,s){const r=e.split("|");if(1===r.length)return r[0];r.length>s.pluralForms.length&&console.error(`For locale=${s.locale}, a maximum of ${s.pluralForms.length} plural forms are expected (${s.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const a=s.select(t),n=s.pluralForms.indexOf(a);return r[Math.min(n,r.length-1)]}(s,t,e)}}}}]); \ No newline at end of file diff --git a/assets/js/130df38c.26766cc3.js b/assets/js/130df38c.26766cc3.js deleted file mode 100644 index 5d581fb3b..000000000 --- a/assets/js/130df38c.26766cc3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6493],{3905:(e,t,n)=>{n.d(t,{Zo:()=>k,kt:()=>d});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),c=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},k=function(e){var t=c(e.components);return a.createElement(p.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},s=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,k=i(e,["components","mdxType","originalType","parentName"]),s=c(n),d=r,u=s["".concat(p,".").concat(d)]||s[d]||m[d]||l;return n?a.createElement(u,o(o({ref:t},k),{},{components:n})):a.createElement(u,o({ref:t},k))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=s;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>i,toc:()=>c});var a=n(87462),r=(n(67294),n(3905));const l={title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"innodb-lock",tags:["DataBase","Lock","InnoDB"]},o=void 0,i={permalink:"/innodb-lock",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",source:"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",description:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",date:"2023-04-07T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 7\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Lock",permalink:"/tags/lock"},{label:"InnoDB",permalink:"/tags/inno-db"}],readingTime:5.805,hasTruncateMarker:!1,authors:[],frontMatter:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"innodb-lock",tags:["DataBase","Lock","InnoDB"]},prevItem:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",permalink:"/book-leadership-and-self-deception"},nextItem:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/mysql-lock"}},p={authorsImageUrls:[]},c=[{value:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",id:"innodb-\uc2a4\ud1a0\ub9ac\uc9c0-\uc5d4\uc9c4\uc758-\uc7a0\uae08",level:2},{value:"Shared & Exclusive Locks",id:"shared--exclusive-locks",level:3},{value:"Intention Locks",id:"intention-locks",level:3},{value:"Record Locks",id:"record-locks",level:3},{value:"Gap Locks",id:"gap-locks",level:3},{value:"Next-Key Locks",id:"next-key-locks",level:3},{value:"AUTO-INC Locks",id:"auto-inc-locks",level:3},{value:"\uc7a0\uae08 \uc608\uc2dc",id:"\uc7a0\uae08-\uc608\uc2dc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],k={toc:c};function m(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},k,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"innodb-\uc2a4\ud1a0\ub9ac\uc9c0-\uc5d4\uc9c4\uc758-\uc7a0\uae08"},"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08"),(0,r.kt)("p",null,"MySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08\uacfc \ubcc4\uac1c\ub85c \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub0b4\ubd80\uc5d0\uc11c \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubcf4\ud1b5 \uba85\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\ub294 \ub4dc\ubb3c\uace0, \uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ubb35\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc774 \uc0ac\uc6a9\ub41c\ub2e4. "),(0,r.kt)("p",null,"\ub3d9\uc2dc\uc131 \uc81c\uc5b4 \ubc29\uc2dd\uc5d0\ub294 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uacfc \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc774 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB\ub294 \uae30\ubcf8\uc801\uc73c\ub85c MVCC(\ub2e4\uc911 \ubc84\uc804 \ub3d9\uc2dc\uc131 \uc81c\uc5b4)\ub97c \ud1b5\ud574 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uace0 \ub77d\uc744 \ud1b5\ud574 \ud2b9\uc815 \uc0c1\ud669\uc5d0\uc11c \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("admonition",{title:"\ub099\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(OCC, Optimistic concurrency control)",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc11c\ub85c \ucda9\ub3cc\ud558\uc9c0 \uc54a\ub294\ub2e4\uace0 \uac00\uc815\ud558\ub294 \ubc29\uc2dd ")),(0,r.kt)("admonition",{title:"\ube44\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(PCC, Pessimistic Concurrency Control)",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\ud2b8\ub79c\uc7ad\uc158\uc774 \ucda9\ub3cc\ud558\ub294 \uac00\uc815\ud558\uc5d0 \uc7a0\uae08\uc744 \uac70\ub294 \ubc29\uc2dd",(0,r.kt)("br",{parentName:"p"}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c\xa0Shared Lock, Exclusive Lock\uc744 \ud1b5\ud574 \uc774\ub97c \uad6c\ud604\ud55c\ub2e4.")),(0,r.kt)("h3",{id:"shared--exclusive-locks"},"Shared & Exclusive Locks"),(0,r.kt)("p",null,"InnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc218\ud589\ud560 \ub54c \uacf5\uc720 \uc7a0\uae08\uacfc \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uacf5\uc720 \uc7a0\uae08(S, shared lock)")),(0,r.kt)("p",null,"\ub370\uc774\ud130 \uc870\ud68c\ub97c \uc704\ud55c \ub77d, \uc77d\uae30 \uc7a0\uae08(read lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uae30\uac00 \uac00\ub2a5\ud558\uc9c0\ub9cc, \uc4f0\uae30\ub294 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) ",(0,r.kt)("inlineCode",{parentName:"p"},"SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\ubc30\ud0c0\uc801 \uc7a0\uae08(X, exclusive lock)")," "),(0,r.kt)("p",null,"\ub370\uc774\ud130 \ubcc0\uacbd\uc744 \uc704\ud55c \ub77d, \uc4f0\uae30 \uc7a0\uae08(write lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub77d\uc744 \uac74 \ud2b8\ub79c\uc7ad\uc158\ub9cc\uc774 \ud574\ub2f9 \ub370\uc774\ud130\uc5d0 \uc811\uadfc \uac00\ub2a5\ud558\ub2e4. \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \uc77d\uae30, \uc4f0\uae30\uac00 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) ",(0,r.kt)("inlineCode",{parentName:"p"},"SELECT * FROM table_name WHERE id = 1 FOR UPDATE;")),(0,r.kt)("h3",{id:"intention-locks"},"Intention Locks"),(0,r.kt)("p",null,"InnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uacfc \ud14c\uc774\ube14 \uc7a0\uae08\uc758 \uacf5\uc874\uc744 \uc704\ud574 \uc778\ud14d\uc158 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud14c\uc774\ube14\uc5d0 \uc788\ub294 \ub85c\uc6b0\uc5d0 \ub300\ud574\uc11c \ub098\uc911\uc5d0 \uc694\uccad\ub418\ub294 \uac83\uc774 \uc5b4\ub5a4 \ud615\ud0dc\uc758 \uc7a0\uae08\uc778\uc9c0 \uac00\ub9ac\ud0a4\uae30 \uc704\ud574 \uc0ac\uc6a9\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uc744 \uc218\ud589\ud558\uae30 \uc804\uc5d0 \uc778\ud150\uc158 \uc7a0\uae08\uc744 \uba3c\uc800 \ud68d\ub4dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc778\ud150\uc158 \ub77d\uc740 \uae30\ubcf8\uc801\uc73c\ub85c \ucda9\ub3cc\uc744 \ubc29\uc9c0\ud558\uace0 \ub370\ub4dc\ub77d\uc744 \ubc29\uc9c0\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uc778\ud150\uc158 \uacf5\uc720 \uc7a0\uae08(IS, intention shared lock)")),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \uacf5\uc720 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uc778\ud150\uc158 \ubc30\ud0c0\uc801 \uc7a0\uae08(IX, intention exclusive lock)")," "),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"}," \uc7a0\uae08\uac04\uc758 \ud638\ud658\uc131 ")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null}),(0,r.kt)("th",{parentName:"tr",align:null},"X"),(0,r.kt)("th",{parentName:"tr",align:null},"IX"),(0,r.kt)("th",{parentName:"tr",align:null},"S"),(0,r.kt)("th",{parentName:"tr",align:null},"IS"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"IX"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"S"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"IS"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible")))),(0,r.kt)("h3",{id:"record-locks"},"Record Locks"),(0,r.kt)("p",null,"\ub808\ucf54\ub4dc \uc790\uccb4\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc740 \ub808\ucf54\ub4dc \uc790\uccb4\uac00 \uc544\ub2c8\ub77c \uc778\ub371\uc2a4\uc758 \ub808\ucf54\ub4dc\ub97c \uc7a0\uadfc\ub2e4. "),(0,r.kt)("h3",{id:"gap-locks"},"Gap Locks"),(0,r.kt)("p",null,"\ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub808\ucf54\ub4dc\uc640 \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\uc5d0 \uc0c8\ub85c\uc6b4 \ub808\ucf54\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc744 \uc81c\uc5b4\ud558\uace0, \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc758 \uc77c\ubd80\ub85c \uc0ac\uc6a9\ub41c\ub2e4. "),(0,r.kt)("h3",{id:"next-key-locks"},"Next-Key Locks"),(0,r.kt)("p",null,"\ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"REPEATABLE READ")," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ud32c\ud140 \ub9ac\ub4dc\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud55c \uc7a0\uae08\uc774\ub2e4. "),(0,r.kt)("h3",{id:"auto-inc-locks"},"AUTO-INC Locks"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"AUTO_INCREMENT")," \uce7c\ub9bc\uc774 \uc0ac\uc6a9\ub41c \ud14c\uc774\ube14\uc5d0 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \ub808\ucf54\ub4dc\uac00 ",(0,r.kt)("inlineCode",{parentName:"p"},"INSERT"),"\ub418\ub294 \uacbd\uc6b0, \uac01 \ub808\ucf54\ub4dc\ub294 \uc911\ubcf5\ub418\uc9c0 \uc54a\uace0 \uc800\uc7a5\ub41c \uc21c\uc11c\ub300\ub85c \uc99d\uac00\ud558\ub294 \uc77c\ub828\ubc88\ud638 \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB \ub294 \ub0b4\ubd80\uc801\uc73c\ub85c AUTO-INC \ub77d\uc774\ub77c\uace0 \ud558\ub294 \ud14c\uc774\ube14 \uc218\uc900\uc758 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158\uacfc \uad00\uacc4 \uc5c6\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"INSERT"),"\ub098 ",(0,r.kt)("inlineCode",{parentName:"p"},"REPLACE")," \ubb38\uc7a5\uc5d0\uc11c ",(0,r.kt)("inlineCode",{parentName:"p"},"AUTO_INCREMENT")," \uac12\uc744 \uac00\uc838\uc624\ub294 \uc21c\uac04\ub9cc \ub77d\uc774 \uac78\ub838\ub2e4\uac00 \ud574\uc81c\ub41c\ub2e4."),(0,r.kt)("h3",{id:"\uc7a0\uae08-\uc608\uc2dc"},"\uc7a0\uae08 \uc608\uc2dc"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- \ub808\ucf54\ub4dc\ub294 id \uae30\uc900 10, 20, 30, 40, 50\uc774 \uc788\ub2e4\uace0 \uac00\uc815\n-- Record Locks: 10\uc5d0 \ub300\ud574 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id = 10 for update;\n\n-- Gap Locks: 51\ubd80\ud130 PositiveInfinity\uae4c\uc9c0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id > 100 for update;\n\n-- Next-Key Locks: 21\ubd80\ud130 30, 31\ubd80\ud130 40\uc5d0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id BETWEEN 25 AND 35 for update;\n")),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.ibm.com/docs/en/rational-clearquest/9.0.0?topic=clearquest-optimistic-pessimistic-record-locking"},"Optimistic and Pessimistic record locking, IBM"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://cecil1018.wordpress.com/2016/06/18/mysql-innodb-locks/"},"MySQL Innodb Locks, cecil1018"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html"},"MySQL 8.0 InnoDB Locks, MySQL"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html"},"Locks Set by Different SQL Statements in InnoDB, MySQL")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/130df38c.c25a1b6d.js b/assets/js/130df38c.c25a1b6d.js new file mode 100644 index 000000000..5c19f4cae --- /dev/null +++ b/assets/js/130df38c.c25a1b6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6493],{83278:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>d});var r=t(85893),c=t(3905);const i={title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"innodb-lock",tags:["DataBase","Lock","InnoDB"]},s=void 0,l={permalink:"/innodb-lock",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",source:"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",description:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",date:"2023-04-07T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 7\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Lock",permalink:"/tags/lock"},{label:"InnoDB",permalink:"/tags/inno-db"}],readingTime:5.805,hasTruncateMarker:!1,authors:[],frontMatter:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"innodb-lock",tags:["DataBase","Lock","InnoDB"]},unlisted:!1,prevItem:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",permalink:"/book-leadership-and-self-deception"},nextItem:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/mysql-lock"}},o={authorsImageUrls:[]},d=[{value:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",id:"innodb-\uc2a4\ud1a0\ub9ac\uc9c0-\uc5d4\uc9c4\uc758-\uc7a0\uae08",level:2},{value:"Shared & Exclusive Locks",id:"shared--exclusive-locks",level:3},{value:"Intention Locks",id:"intention-locks",level:3},{value:"Record Locks",id:"record-locks",level:3},{value:"Gap Locks",id:"gap-locks",level:3},{value:"Next-Key Locks",id:"next-key-locks",level:3},{value:"AUTO-INC Locks",id:"auto-inc-locks",level:3},{value:"\uc7a0\uae08 \uc608\uc2dc",id:"\uc7a0\uae08-\uc608\uc2dc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function a(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"innodb-\uc2a4\ud1a0\ub9ac\uc9c0-\uc5d4\uc9c4\uc758-\uc7a0\uae08",children:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08"}),"\n",(0,r.jsxs)(n.p,{children:["MySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08\uacfc \ubcc4\uac1c\ub85c \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub0b4\ubd80\uc5d0\uc11c \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubcf4\ud1b5 \uba85\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\ub294 \ub4dc\ubb3c\uace0, \uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ubb35\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc774 \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ub3d9\uc2dc\uc131 \uc81c\uc5b4 \ubc29\uc2dd\uc5d0\ub294 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uacfc \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc774 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","InnoDB\ub294 \uae30\ubcf8\uc801\uc73c\ub85c MVCC(\ub2e4\uc911 \ubc84\uc804 \ub3d9\uc2dc\uc131 \uc81c\uc5b4)\ub97c \ud1b5\ud574 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uace0 \ub77d\uc744 \ud1b5\ud574 \ud2b9\uc815 \uc0c1\ud669\uc5d0\uc11c \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.admonition,{title:"\ub099\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(OCC, Optimistic concurrency control)",type:"note",children:(0,r.jsx)(n.p,{children:"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc11c\ub85c \ucda9\ub3cc\ud558\uc9c0 \uc54a\ub294\ub2e4\uace0 \uac00\uc815\ud558\ub294 \ubc29\uc2dd"})}),"\n",(0,r.jsx)(n.admonition,{title:"\ube44\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(PCC, Pessimistic Concurrency Control)",type:"note",children:(0,r.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc774 \ucda9\ub3cc\ud558\ub294 \uac00\uc815\ud558\uc5d0 \uc7a0\uae08\uc744 \uac70\ub294 \ubc29\uc2dd",(0,r.jsx)(n.br,{}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c\xa0Shared Lock, Exclusive Lock\uc744 \ud1b5\ud574 \uc774\ub97c \uad6c\ud604\ud55c\ub2e4."]})}),"\n",(0,r.jsx)(n.h3,{id:"shared--exclusive-locks",children:"Shared & Exclusive Locks"}),"\n",(0,r.jsx)(n.p,{children:"InnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc218\ud589\ud560 \ub54c \uacf5\uc720 \uc7a0\uae08\uacfc \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\uacf5\uc720 \uc7a0\uae08(S, shared lock)"})}),"\n",(0,r.jsxs)(n.p,{children:["\ub370\uc774\ud130 \uc870\ud68c\ub97c \uc704\ud55c \ub77d, \uc77d\uae30 \uc7a0\uae08(read lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uae30\uac00 \uac00\ub2a5\ud558\uc9c0\ub9cc, \uc4f0\uae30\ub294 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc608) ",(0,r.jsx)(n.code,{children:"SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;"})]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\ubc30\ud0c0\uc801 \uc7a0\uae08(X, exclusive lock)"})}),"\n",(0,r.jsxs)(n.p,{children:["\ub370\uc774\ud130 \ubcc0\uacbd\uc744 \uc704\ud55c \ub77d, \uc4f0\uae30 \uc7a0\uae08(write lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub77d\uc744 \uac74 \ud2b8\ub79c\uc7ad\uc158\ub9cc\uc774 \ud574\ub2f9 \ub370\uc774\ud130\uc5d0 \uc811\uadfc \uac00\ub2a5\ud558\ub2e4. \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \uc77d\uae30, \uc4f0\uae30\uac00 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc608) ",(0,r.jsx)(n.code,{children:"SELECT * FROM table_name WHERE id = 1 FOR UPDATE;"})]}),"\n",(0,r.jsx)(n.h3,{id:"intention-locks",children:"Intention Locks"}),"\n",(0,r.jsxs)(n.p,{children:["InnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uacfc \ud14c\uc774\ube14 \uc7a0\uae08\uc758 \uacf5\uc874\uc744 \uc704\ud574 \uc778\ud14d\uc158 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud14c\uc774\ube14\uc5d0 \uc788\ub294 \ub85c\uc6b0\uc5d0 \ub300\ud574\uc11c \ub098\uc911\uc5d0 \uc694\uccad\ub418\ub294 \uac83\uc774 \uc5b4\ub5a4 \ud615\ud0dc\uc758 \uc7a0\uae08\uc778\uc9c0 \uac00\ub9ac\ud0a4\uae30 \uc704\ud574 \uc0ac\uc6a9\ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uc744 \uc218\ud589\ud558\uae30 \uc804\uc5d0 \uc778\ud150\uc158 \uc7a0\uae08\uc744 \uba3c\uc800 \ud68d\ub4dd\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc778\ud150\uc158 \ub77d\uc740 \uae30\ubcf8\uc801\uc73c\ub85c \ucda9\ub3cc\uc744 \ubc29\uc9c0\ud558\uace0 \ub370\ub4dc\ub77d\uc744 \ubc29\uc9c0\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\uc778\ud150\uc158 \uacf5\uc720 \uc7a0\uae08(IS, intention shared lock)"})}),"\n",(0,r.jsx)(n.p,{children:"\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \uacf5\uc720 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\uc778\ud150\uc158 \ubc30\ud0c0\uc801 \uc7a0\uae08(IX, intention exclusive lock)"})}),"\n",(0,r.jsx)(n.p,{children:"\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:"** \uc7a0\uae08\uac04\uc758 \ud638\ud658\uc131 **"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{}),(0,r.jsx)(n.th,{children:"X"}),(0,r.jsx)(n.th,{children:"IX"}),(0,r.jsx)(n.th,{children:"S"}),(0,r.jsx)(n.th,{children:"IS"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"X"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Conflict"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"IX"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Compatible"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Compatible"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"S"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Compatible"}),(0,r.jsx)(n.td,{children:"Compatible"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"IS"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Compatible"}),(0,r.jsx)(n.td,{children:"Compatible"}),(0,r.jsx)(n.td,{children:"Compatible"})]})]})]}),"\n",(0,r.jsx)(n.h3,{id:"record-locks",children:"Record Locks"}),"\n",(0,r.jsxs)(n.p,{children:["\ub808\ucf54\ub4dc \uc790\uccb4\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.jsx)(n.br,{}),"\n","InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc740 \ub808\ucf54\ub4dc \uc790\uccb4\uac00 \uc544\ub2c8\ub77c \uc778\ub371\uc2a4\uc758 \ub808\ucf54\ub4dc\ub97c \uc7a0\uadfc\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"gap-locks",children:"Gap Locks"}),"\n",(0,r.jsxs)(n.p,{children:["\ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub808\ucf54\ub4dc\uc640 \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\uc5d0 \uc0c8\ub85c\uc6b4 \ub808\ucf54\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc744 \uc81c\uc5b4\ud558\uace0, \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc758 \uc77c\ubd80\ub85c \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"next-key-locks",children:"Next-Key Locks"}),"\n",(0,r.jsxs)(n.p,{children:["\ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.code,{children:"REPEATABLE READ"})," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ud32c\ud140 \ub9ac\ub4dc\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud55c \uc7a0\uae08\uc774\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"auto-inc-locks",children:"AUTO-INC Locks"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"AUTO_INCREMENT"})," \uce7c\ub9bc\uc774 \uc0ac\uc6a9\ub41c \ud14c\uc774\ube14\uc5d0 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \ub808\ucf54\ub4dc\uac00 ",(0,r.jsx)(n.code,{children:"INSERT"}),"\ub418\ub294 \uacbd\uc6b0, \uac01 \ub808\ucf54\ub4dc\ub294 \uc911\ubcf5\ub418\uc9c0 \uc54a\uace0 \uc800\uc7a5\ub41c \uc21c\uc11c\ub300\ub85c \uc99d\uac00\ud558\ub294 \uc77c\ub828\ubc88\ud638 \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","InnoDB \ub294 \ub0b4\ubd80\uc801\uc73c\ub85c AUTO-INC \ub77d\uc774\ub77c\uace0 \ud558\ub294 \ud14c\uc774\ube14 \uc218\uc900\uc758 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158\uacfc \uad00\uacc4 \uc5c6\uc774 ",(0,r.jsx)(n.code,{children:"INSERT"}),"\ub098 ",(0,r.jsx)(n.code,{children:"REPLACE"})," \ubb38\uc7a5\uc5d0\uc11c ",(0,r.jsx)(n.code,{children:"AUTO_INCREMENT"})," \uac12\uc744 \uac00\uc838\uc624\ub294 \uc21c\uac04\ub9cc \ub77d\uc774 \uac78\ub838\ub2e4\uac00 \ud574\uc81c\ub41c\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc7a0\uae08-\uc608\uc2dc",children:"\uc7a0\uae08 \uc608\uc2dc"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sql",children:"-- \ub808\ucf54\ub4dc\ub294 id \uae30\uc900 10, 20, 30, 40, 50\uc774 \uc788\ub2e4\uace0 \uac00\uc815\n-- Record Locks: 10\uc5d0 \ub300\ud574 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id = 10 for update;\n\n-- Gap Locks: 51\ubd80\ud130 PositiveInfinity\uae4c\uc9c0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id > 100 for update;\n\n-- Next-Key Locks: 21\ubd80\ud130 30, 31\ubd80\ud130 40\uc5d0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id BETWEEN 25 AND 35 for update;\n"})}),"\n",(0,r.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:["Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.ibm.com/docs/en/rational-clearquest/9.0.0?topic=clearquest-optimistic-pessimistic-record-locking",children:"Optimistic and Pessimistic record locking, IBM"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://cecil1018.wordpress.com/2016/06/18/mysql-innodb-locks/",children:"MySQL Innodb Locks, cecil1018"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html",children:"MySQL 8.0 InnoDB Locks, MySQL"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html",children:"Locks Set by Different SQL Statements in InnoDB, MySQL"})]})]})}function h(e={}){const{wrapper:n}={...(0,c.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>d});var r=t(67294);function c(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(c[t]=e[t]);return c}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(c[t]=e[t])}return c}var o=r.createContext({}),d=function(e){var n=r.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},a={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},h=r.forwardRef((function(e,n){var t=e.components,c=e.mdxType,i=e.originalType,o=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),x=d(t),j=c,p=x["".concat(o,".").concat(j)]||x[j]||a[j]||i;return t?r.createElement(p,s(s({ref:n},h),{},{components:t})):r.createElement(p,s({ref:n},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/1398b403.522981cc.js b/assets/js/1398b403.f0f9481a.js similarity index 81% rename from assets/js/1398b403.522981cc.js rename to assets/js/1398b403.f0f9481a.js index 46fd35da4..e098de55e 100644 --- a/assets/js/1398b403.522981cc.js +++ b/assets/js/1398b403.f0f9481a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5652],{93561:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5652],{93561:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/1426.d71a045b.js b/assets/js/1426.d71a045b.js new file mode 100644 index 000000000..7e09bbf6c --- /dev/null +++ b/assets/js/1426.d71a045b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1426],{61426:(e,t,r)=>{function n(e,t){var r=void 0;return function(){for(var n=arguments.length,o=new Array(n),i=0;ipn});var a=function(){};function c(e){var t=e.item,r=e.items;return{index:t.__autocomplete_indexName,items:[t],positions:[1+r.findIndex((function(e){return e.objectID===t.objectID}))],queryID:t.__autocomplete_queryID,algoliaSource:["autocomplete"]}}function l(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,i,a,c=[],l=!0,u=!1;try{if(i=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;l=!1}else for(;!(l=(n=i.call(r)).done)&&(c.push(n.value),c.length!==t);l=!0);}catch(s){u=!0,o=s}finally{try{if(!l&&null!=r.return&&(a=r.return(),Object(a)!==a))return}finally{if(u)throw o}}return c}}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return u(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return u(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function u(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);re.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function y(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function h(e){for(var t=1;t=3||2===r&&n>=4||1===r&&n>=10);function i(t,r,n){if(o&&void 0!==n){var i=n[0].__autocomplete_algoliaCredentials,a={"X-Algolia-Application-Id":i.appId,"X-Algolia-API-Key":i.apiKey};e.apply(void 0,[t].concat(p(r),[{headers:a}]))}else e.apply(void 0,[t].concat(p(r)))}return{init:function(t,r){e("init",{appId:t,apiKey:r})},setUserToken:function(t){e("setUserToken",t)},clickedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),r=0;r0&&i("clickedObjectIDsAfterSearch",g(t),t[0].items)},clickedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r0&&i("clickedObjectIDs",g(t),t[0].items)},clickedFilters:function(){for(var t=arguments.length,r=new Array(t),n=0;n0&&e.apply(void 0,["clickedFilters"].concat(r))},convertedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),r=0;r0&&i("convertedObjectIDsAfterSearch",g(t),t[0].items)},convertedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r0&&i("convertedObjectIDs",g(t),t[0].items)},convertedFilters:function(){for(var t=arguments.length,r=new Array(t),n=0;n0&&e.apply(void 0,["convertedFilters"].concat(r))},viewedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r0&&t.reduce((function(e,t){var r=t.items,n=d(t,f);return[].concat(p(e),p(function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:20,r=[],n=0;n0&&e.apply(void 0,["viewedFilters"].concat(r))}}}function S(e){var t=e.items.reduce((function(e,t){var r;return e[t.__autocomplete_indexName]=(null!==(r=e[t.__autocomplete_indexName])&&void 0!==r?r:[]).concat(t),e}),{});return Object.keys(t).map((function(e){return{index:e,items:t[e],algoliaSource:["autocomplete"]}}))}function j(e){return e.objectID&&e.__autocomplete_indexName&&e.__autocomplete_queryID}function w(e){return w="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},w(e)}function E(e){return function(e){if(Array.isArray(e))return P(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return P(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return P(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function P(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r0&&C({onItemsChange:o,items:r,insights:f,state:t}))}}),0);return{name:"aa.algoliaInsightsPlugin",subscribe:function(e){var t=e.setContext,r=e.onSelect,n=e.onActive;s("addAlgoliaAgent","insights-plugin"),t({algoliaInsightsPlugin:{__algoliaSearchParameters:{clickAnalytics:!0},insights:f}}),r((function(e){var t=e.item,r=e.state,n=e.event;j(t)&&l({state:r,event:n,insights:f,item:t,insightsEvents:[D({eventName:"Item Selected"},c({item:t,items:m.current}))]})})),n((function(e){var t=e.item,r=e.state,n=e.event;j(t)&&u({state:r,event:n,insights:f,item:t,insightsEvents:[D({eventName:"Item Active"},c({item:t,items:m.current}))]})}))},onStateChange:function(e){var t=e.state;p({state:t})},__autocomplete_pluginOptions:e}}function N(e){return N="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},N(e)}function T(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function q(e,t,r){return(t=function(e){var t=function(e,t){if("object"!==N(e)||null===e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!==N(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===N(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function R(e,t,r){var n,o=t.initialState;return{getState:function(){return o},dispatch:function(n,i){var a=function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r0},reshape:function(e){return e.sources}},e),{},{id:null!==(r=e.id)&&void 0!==r?r:"autocomplete-".concat(V++),plugins:o,initialState:X({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var r;null===(r=e.onStateChange)||void 0===r||r.call(e,t),o.forEach((function(e){var r;return null===(r=e.onStateChange)||void 0===r?void 0:r.call(e,t)}))},onSubmit:function(t){var r;null===(r=e.onSubmit)||void 0===r||r.call(e,t),o.forEach((function(e){var r;return null===(r=e.onSubmit)||void 0===r?void 0:r.call(e,t)}))},onReset:function(t){var r;null===(r=e.onReset)||void 0===r||r.call(e,t),o.forEach((function(e){var r;return null===(r=e.onReset)||void 0===r?void 0:r.call(e,t)}))},getSources:function(r){return Promise.all([].concat(Q(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return function(e,t){var r=[];return Promise.resolve(e(t)).then((function(e){return Array.isArray(e),Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,r.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));r.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:a,onResolve:a};Object.keys(t).forEach((function(e){t[e].__default=!0}));var n=$($({},t),e);return Promise.resolve(n)})))}))}(e,r)}))).then((function(e){return L(e)})).then((function(e){return e.map((function(e){return X(X({},e),{},{onSelect:function(r){e.onSelect(r),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,r)}))},onActive:function(r){e.onActive(r),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,r)}))},onResolve:function(r){e.onResolve(r),t.forEach((function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,r)}))}})}))}))},navigator:X({navigate:function(e){var t=e.itemUrl;n.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,r=n.open(t,"_blank","noopener");null==r||r.focus()},navigateNewWindow:function(e){var t=e.itemUrl;n.open(t,"_blank","noopener")}},e.navigator)})}function te(e){return te="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},te(e)}function re(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function ne(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var Ie,De,Ae,ke=null,xe=(Ie=-1,De=-1,Ae=void 0,function(e){var t=++Ie;return Promise.resolve(e).then((function(e){return Ae&&t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var Me=/((gt|sm)-|galaxy nexus)|samsung[- ]|samsungbrowser/i;function He(e){return He="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},He(e)}var Fe=["props","refresh","store"],Ue=["inputElement","formElement","panelElement"],Be=["inputElement"],Ve=["inputElement","maxLength"],Ke=["sourceIndex"],$e=["sourceIndex"],Je=["item","source","sourceIndex"];function ze(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function We(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function Ge(e){var t=e.props,r=e.refresh,n=e.store,o=Ze(e,Fe),i=function(e,t){return void 0!==t?"".concat(e,"-").concat(t):e};return{getEnvironmentProps:function(e){var r=e.inputElement,o=e.formElement,i=e.panelElement;function a(e){!n.getState().isOpen&&n.pendingRequests.isEmpty()||e.target===r||!1===[o,i].some((function(t){return r=t,n=e.target,r===n||r.contains(n);var r,n}))&&(n.dispatch("blur",null),t.debug||n.pendingRequests.cancelAll())}return We({onTouchStart:a,onMouseDown:a,onTouchMove:function(e){!1!==n.getState().isOpen&&r===t.environment.document.activeElement&&e.target!==r&&r.blur()}},Ze(e,Ue))},getRootProps:function(e){return We({role:"combobox","aria-expanded":n.getState().isOpen,"aria-haspopup":"listbox","aria-owns":n.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label")},e)},getFormProps:function(e){e.inputElement;return We({action:"",noValidate:!0,role:"search",onSubmit:function(i){var a;i.preventDefault(),t.onSubmit(We({event:i,refresh:r,state:n.getState()},o)),n.dispatch("submit",null),null===(a=e.inputElement)||void 0===a||a.blur()},onReset:function(i){var a;i.preventDefault(),t.onReset(We({event:i,refresh:r,state:n.getState()},o)),n.dispatch("reset",null),null===(a=e.inputElement)||void 0===a||a.focus()}},Ze(e,Be))},getLabelProps:function(e){var r=e||{},n=r.sourceIndex,o=Ze(r,Ke);return We({htmlFor:"".concat(i(t.id,n),"-input"),id:"".concat(i(t.id,n),"-label")},o)},getInputProps:function(e){var i;function c(e){(t.openOnFocus||Boolean(n.getState().query))&&Ce(We({event:e,props:t,query:n.getState().completion||n.getState().query,refresh:r,store:n},o)),n.dispatch("focus",null)}var l=e||{},u=(l.inputElement,l.maxLength),s=void 0===u?512:u,f=Ze(l,Ve),m=ge(n.getState()),p=function(e){return Boolean(e&&e.match(Me))}((null===(i=t.environment.navigator)||void 0===i?void 0:i.userAgent)||""),v=null!=m&&m.itemUrl&&!p?"go":"search";return We({"aria-autocomplete":"both","aria-activedescendant":n.getState().isOpen&&null!==n.getState().activeItemId?"".concat(t.id,"-item-").concat(n.getState().activeItemId):void 0,"aria-controls":n.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label"),value:n.getState().completion||n.getState().query,id:"".concat(t.id,"-input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:v,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:s,type:"search",onChange:function(e){Ce(We({event:e,props:t,query:e.currentTarget.value.slice(0,s),refresh:r,store:n},o))},onKeyDown:function(e){!function(e){var t=e.event,r=e.props,n=e.refresh,o=e.store,i=Le(e,Ne);if("ArrowUp"===t.key||"ArrowDown"===t.key){var a=function(){var e=r.environment.document.getElementById("".concat(r.id,"-item-").concat(o.getState().activeItemId));e&&(e.scrollIntoViewIfNeeded?e.scrollIntoViewIfNeeded(!1):e.scrollIntoView(!1))},c=function(){var e=ge(o.getState());if(null!==o.getState().activeItemId&&e){var r=e.item,a=e.itemInputValue,c=e.itemUrl,l=e.source;l.onActive(qe({event:t,item:r,itemInputValue:a,itemUrl:c,refresh:n,source:l,state:o.getState()},i))}};t.preventDefault(),!1===o.getState().isOpen&&(r.openOnFocus||Boolean(o.getState().query))?Ce(qe({event:t,props:r,query:o.getState().query,refresh:n,store:o},i)).then((function(){o.dispatch(t.key,{nextActiveItemId:r.defaultActiveItemId}),c(),setTimeout(a,0)})):(o.dispatch(t.key,{}),c(),a())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every((function(e){return 0===e.items.length})))return void(r.debug||o.pendingRequests.cancelAll());t.preventDefault();var l=ge(o.getState()),u=l.item,s=l.itemInputValue,f=l.itemUrl,m=l.source;if(t.metaKey||t.ctrlKey)void 0!==f&&(m.onSelect(qe({event:t,item:u,itemInputValue:s,itemUrl:f,refresh:n,source:m,state:o.getState()},i)),r.navigator.navigateNewTab({itemUrl:f,item:u,state:o.getState()}));else if(t.shiftKey)void 0!==f&&(m.onSelect(qe({event:t,item:u,itemInputValue:s,itemUrl:f,refresh:n,source:m,state:o.getState()},i)),r.navigator.navigateNewWindow({itemUrl:f,item:u,state:o.getState()}));else if(t.altKey);else{if(void 0!==f)return m.onSelect(qe({event:t,item:u,itemInputValue:s,itemUrl:f,refresh:n,source:m,state:o.getState()},i)),void r.navigator.navigate({itemUrl:f,item:u,state:o.getState()});Ce(qe({event:t,nextState:{isOpen:!1},props:r,query:s,refresh:n,store:o},i)).then((function(){m.onSelect(qe({event:t,item:u,itemInputValue:s,itemUrl:f,refresh:n,source:m,state:o.getState()},i))}))}}}(We({event:e,props:t,refresh:r,store:n},o))},onFocus:c,onBlur:a,onClick:function(r){e.inputElement!==t.environment.document.activeElement||n.getState().isOpen||c(r)}},f)},getPanelProps:function(e){return We({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){n.dispatch("mouseleave",null)}},e)},getListProps:function(e){var r=e||{},n=r.sourceIndex,o=Ze(r,$e);return We({role:"listbox","aria-labelledby":"".concat(i(t.id,n),"-label"),id:"".concat(i(t.id,n),"-list")},o)},getItemProps:function(e){var a=e.item,c=e.source,l=e.sourceIndex,u=Ze(e,Je);return We({id:"".concat(i(t.id,l),"-item-").concat(a.__autocomplete_id),role:"option","aria-selected":n.getState().activeItemId===a.__autocomplete_id,onMouseMove:function(e){if(a.__autocomplete_id!==n.getState().activeItemId){n.dispatch("mousemove",a.__autocomplete_id);var t=ge(n.getState());if(null!==n.getState().activeItemId&&t){var i=t.item,c=t.itemInputValue,l=t.itemUrl,u=t.source;u.onActive(We({event:e,item:i,itemInputValue:c,itemUrl:l,refresh:r,source:u,state:n.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var i=c.getItemInputValue({item:a,state:n.getState()}),l=c.getItemUrl({item:a,state:n.getState()});(l?Promise.resolve():Ce(We({event:e,nextState:{isOpen:!1},props:t,query:i,refresh:r,store:n},o))).then((function(){c.onSelect(We({event:e,item:a,itemInputValue:i,itemUrl:l,refresh:r,source:c,state:n.getState()},o))}))}},u)}}}var Xe=[{segment:"autocomplete-core",version:"1.9.3"}];function Ye(e){return Ye="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ye(e)}function et(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function tt(e){for(var t=1;t=r?null===n?null:0:o}function at(e){return at="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},at(e)}function ct(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function lt(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function kt(e){var t=e.translations,r=void 0===t?{}:t,n=At(e,Pt),o=r.noResultsText,i=void 0===o?"No results for":o,a=r.suggestedQueryText,c=void 0===a?"Try searching for":a,l=r.reportMissingResultsText,u=void 0===l?"Believe this query should return results?":l,s=r.reportMissingResultsLinkText,f=void 0===s?"Let us know.":s,m=n.state.context.searchSuggestions;return yt.createElement("div",{className:"DocSearch-NoResults"},yt.createElement("div",{className:"DocSearch-Screen-Icon"},yt.createElement(Et,null)),yt.createElement("p",{className:"DocSearch-Title"},i,' "',yt.createElement("strong",null,n.state.query),'"'),m&&m.length>0&&yt.createElement("div",{className:"DocSearch-NoResults-Prefill-List"},yt.createElement("p",{className:"DocSearch-Help"},c,":"),yt.createElement("ul",null,m.slice(0,3).reduce((function(e,t){return[].concat(It(e),[yt.createElement("li",{key:t},yt.createElement("button",{className:"DocSearch-Prefill",key:t,type:"button",onClick:function(){n.setQuery(t.toLowerCase()+" "),n.refresh(),n.inputRef.current.focus()}},t))])}),[]))),n.getMissingResultsUrl&&yt.createElement("p",{className:"DocSearch-Help"},"".concat(u," "),yt.createElement("a",{href:n.getMissingResultsUrl({query:n.state.query}),target:"_blank",rel:"noopener noreferrer"},f)))}var xt=function(){return yt.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},yt.createElement("path",{d:"M17 6v12c0 .52-.2 1-1 1H4c-.7 0-1-.33-1-1V2c0-.55.42-1 1-1h8l5 5zM14 8h-3.13c-.51 0-.87-.34-.87-.87V4",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinejoin:"round"}))};function Ct(e){switch(e.type){case"lvl1":return yt.createElement(xt,null);case"content":return yt.createElement(Nt,null);default:return yt.createElement(_t,null)}}function _t(){return yt.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},yt.createElement("path",{d:"M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}function Nt(){return yt.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},yt.createElement("path",{d:"M17 5H3h14zm0 5H3h14zm0 5H3h14z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinejoin:"round"}))}function Tt(){return yt.createElement("svg",{className:"DocSearch-Hit-Select-Icon",width:"20",height:"20",viewBox:"0 0 20 20"},yt.createElement("g",{stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},yt.createElement("path",{d:"M18 3v4c0 2-2 4-4 4H2"}),yt.createElement("path",{d:"M8 17l-6-6 6-6"})))}var qt=["hit","attribute","tagName"];function Rt(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function Lt(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function Ft(e,t){return t.split(".").reduce((function(e,t){return null!=e&&e[t]?e[t]:null}),e)}function Ut(e){var t=e.hit,r=e.attribute,n=e.tagName,o=void 0===n?"span":n,i=Ht(e,qt);return(0,yt.createElement)(o,Lt(Lt({},i),{},{dangerouslySetInnerHTML:{__html:Ft(t,"_snippetResult.".concat(r,".value"))||Ft(t,r)}}))}function Bt(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==r)return;var n,o,i=[],a=!0,c=!1;try{for(r=r.call(e);!(a=(n=r.next()).done)&&(i.push(n.value),!t||i.length!==t);a=!0);}catch(l){c=!0,o=l}finally{try{a||null==r.return||r.return()}finally{if(c)throw o}}return i}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return Vt(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Vt(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Vt(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r|<\/mark>)/g,Wt=RegExp(zt.source);function Qt(e){var t,r,n=e;if(!n.__docsearch_parent&&!e._highlightResult)return e.hierarchy.lvl0;var o=((n.__docsearch_parent?null===(t=n.__docsearch_parent)||void 0===t||null===(t=t._highlightResult)||void 0===t||null===(t=t.hierarchy)||void 0===t?void 0:t.lvl0:null===(r=e._highlightResult)||void 0===r||null===(r=r.hierarchy)||void 0===r?void 0:r.lvl0)||{}).value;return o&&Wt.test(o)?o.replace(zt,""):o}function Zt(){return Zt=Object.assign||function(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function or(e){var t=e.translations,r=void 0===t?{}:t,n=nr(e,tr),o=r.recentSearchesTitle,i=void 0===o?"Recent":o,a=r.noRecentSearchesText,c=void 0===a?"No recent searches":a,l=r.saveRecentSearchButtonTitle,u=void 0===l?"Save this search":l,s=r.removeRecentSearchButtonTitle,f=void 0===s?"Remove this search from history":s,m=r.favoriteSearchesTitle,p=void 0===m?"Favorite":m,v=r.removeFavoriteSearchButtonTitle,d=void 0===v?"Remove this search from favorites":v;return"idle"===n.state.status&&!1===n.hasCollections?n.disableUserPersonalization?null:yt.createElement("div",{className:"DocSearch-StartScreen"},yt.createElement("p",{className:"DocSearch-Help"},c)):!1===n.hasCollections?null:yt.createElement("div",{className:"DocSearch-Dropdown-Container"},yt.createElement($t,rr({},n,{title:i,collection:n.state.collections[0],renderIcon:function(){return yt.createElement("div",{className:"DocSearch-Hit-icon"},yt.createElement(Xt,null))},renderAction:function(e){var t=e.item,r=e.runFavoriteTransition,o=e.runDeleteTransition;return yt.createElement(yt.Fragment,null,yt.createElement("div",{className:"DocSearch-Hit-action"},yt.createElement("button",{className:"DocSearch-Hit-action-button",title:u,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),r((function(){n.favoriteSearches.add(t),n.recentSearches.remove(t),n.refresh()}))}},yt.createElement(Yt,null))),yt.createElement("div",{className:"DocSearch-Hit-action"},yt.createElement("button",{className:"DocSearch-Hit-action-button",title:f,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),o((function(){n.recentSearches.remove(t),n.refresh()}))}},yt.createElement(er,null))))}})),yt.createElement($t,rr({},n,{title:p,collection:n.state.collections[1],renderIcon:function(){return yt.createElement("div",{className:"DocSearch-Hit-icon"},yt.createElement(Yt,null))},renderAction:function(e){var t=e.item,r=e.runDeleteTransition;return yt.createElement("div",{className:"DocSearch-Hit-action"},yt.createElement("button",{className:"DocSearch-Hit-action-button",title:d,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),r((function(){n.favoriteSearches.remove(t),n.refresh()}))}},yt.createElement(er,null)))}})))}var ir=["translations"];function ar(){return ar=Object.assign||function(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var lr=yt.memo((function(e){var t=e.translations,r=void 0===t?{}:t,n=cr(e,ir);if("error"===n.state.status)return yt.createElement(wt,{translations:null==r?void 0:r.errorScreen});var o=n.state.collections.some((function(e){return e.items.length>0}));return n.state.query?!1===o?yt.createElement(kt,ar({},n,{translations:null==r?void 0:r.noResultsScreen})):yt.createElement(Gt,n):yt.createElement(or,ar({},n,{hasCollections:o,translations:null==r?void 0:r.startScreen}))}),(function(e,t){return"loading"===t.state.status||"stalled"===t.state.status}));function ur(){return yt.createElement("svg",{viewBox:"0 0 38 38",stroke:"currentColor",strokeOpacity:".5"},yt.createElement("g",{fill:"none",fillRule:"evenodd"},yt.createElement("g",{transform:"translate(1 1)",strokeWidth:"2"},yt.createElement("circle",{strokeOpacity:".3",cx:"18",cy:"18",r:"18"}),yt.createElement("path",{d:"M36 18c0-9.94-8.06-18-18-18"},yt.createElement("animateTransform",{attributeName:"transform",type:"rotate",from:"0 18 18",to:"360 18 18",dur:"1s",repeatCount:"indefinite"})))))}var sr=r(20830),fr=["translations"];function mr(){return mr=Object.assign||function(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function vr(e){var t=e.translations,r=void 0===t?{}:t,n=pr(e,fr),o=r.resetButtonTitle,i=void 0===o?"Clear the query":o,a=r.resetButtonAriaLabel,c=void 0===a?"Clear the query":a,l=r.cancelButtonText,u=void 0===l?"Cancel":l,s=r.cancelButtonAriaLabel,f=void 0===s?"Cancel":s,m=n.getFormProps({inputElement:n.inputRef.current}).onReset;return yt.useEffect((function(){n.autoFocus&&n.inputRef.current&&n.inputRef.current.focus()}),[n.autoFocus,n.inputRef]),yt.useEffect((function(){n.isFromSelection&&n.inputRef.current&&n.inputRef.current.select()}),[n.isFromSelection,n.inputRef]),yt.createElement(yt.Fragment,null,yt.createElement("form",{className:"DocSearch-Form",onSubmit:function(e){e.preventDefault()},onReset:m},yt.createElement("label",mr({className:"DocSearch-MagnifierLabel"},n.getLabelProps()),yt.createElement(sr.W,null)),yt.createElement("div",{className:"DocSearch-LoadingIndicator"},yt.createElement(ur,null)),yt.createElement("input",mr({className:"DocSearch-Input",ref:n.inputRef},n.getInputProps({inputElement:n.inputRef.current,autoFocus:n.autoFocus,maxLength:ht}))),yt.createElement("button",{type:"reset",title:i,className:"DocSearch-Reset","aria-label":c,hidden:!n.state.query},yt.createElement(er,null))),yt.createElement("button",{className:"DocSearch-Cancel",type:"reset","aria-label":f,onClick:n.onClose},u))}var dr=["_highlightResult","_snippetResult"];function yr(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function hr(e){return!1===function(){var e="__TEST_KEY__";try{return localStorage.setItem(e,""),localStorage.removeItem(e),!0}catch(t){return!1}}()?{setItem:function(){},getItem:function(){return[]}}:{setItem:function(t){return window.localStorage.setItem(e,JSON.stringify(t))},getItem:function(){var t=window.localStorage.getItem(e);return t?JSON.parse(t):[]}}}function br(e){var t=e.key,r=e.limit,n=void 0===r?5:r,o=hr(t),i=o.getItem().slice(0,n);return{add:function(e){var t=e,r=(t._highlightResult,t._snippetResult,yr(t,dr)),a=i.findIndex((function(e){return e.objectID===r.objectID}));a>-1&&i.splice(a,1),i.unshift(r),i=i.slice(0,n),o.setItem(i)},remove:function(e){i=i.filter((function(t){return t.objectID!==e.objectID})),o.setItem(i)},getAll:function(){return i}}}function gr(e){const t=`algoliasearch-client-js-${e.key}`;let r;const n=()=>(void 0===r&&(r=e.localStorage||window.localStorage),r),o=()=>JSON.parse(n().getItem(t)||"{}"),i=e=>{n().setItem(t,JSON.stringify(e))};return{get:(t,r,n={miss:()=>Promise.resolve()})=>Promise.resolve().then((()=>{(()=>{const t=e.timeToLive?1e3*e.timeToLive:null,r=o(),n=Object.fromEntries(Object.entries(r).filter((([,e])=>void 0!==e.timestamp)));if(i(n),!t)return;const a=Object.fromEntries(Object.entries(n).filter((([,e])=>{const r=(new Date).getTime();return!(e.timestamp+tPromise.all([e?e.value:r(),void 0!==e]))).then((([e,t])=>Promise.all([e,t||n.miss(e)]))).then((([e])=>e)),set:(e,r)=>Promise.resolve().then((()=>{const i=o();return i[JSON.stringify(e)]={timestamp:(new Date).getTime(),value:r},n().setItem(t,JSON.stringify(i)),r})),delete:e=>Promise.resolve().then((()=>{const r=o();delete r[JSON.stringify(e)],n().setItem(t,JSON.stringify(r))})),clear:()=>Promise.resolve().then((()=>{n().removeItem(t)}))}}function Or(e){const t=[...e.caches],r=t.shift();return void 0===r?{get:(e,t,r={miss:()=>Promise.resolve()})=>t().then((e=>Promise.all([e,r.miss(e)]))).then((([e])=>e)),set:(e,t)=>Promise.resolve(t),delete:e=>Promise.resolve(),clear:()=>Promise.resolve()}:{get:(e,n,o={miss:()=>Promise.resolve()})=>r.get(e,n,o).catch((()=>Or({caches:t}).get(e,n,o))),set:(e,n)=>r.set(e,n).catch((()=>Or({caches:t}).set(e,n))),delete:e=>r.delete(e).catch((()=>Or({caches:t}).delete(e))),clear:()=>r.clear().catch((()=>Or({caches:t}).clear()))}}function Sr(e={serializable:!0}){let t={};return{get(r,n,o={miss:()=>Promise.resolve()}){const i=JSON.stringify(r);if(i in t)return Promise.resolve(e.serializable?JSON.parse(t[i]):t[i]);const a=n(),c=o&&o.miss||(()=>Promise.resolve());return a.then((e=>c(e))).then((()=>a))},set:(r,n)=>(t[JSON.stringify(r)]=e.serializable?JSON.stringify(n):n,Promise.resolve(n)),delete:e=>(delete t[JSON.stringify(e)],Promise.resolve()),clear:()=>(t={},Promise.resolve())}}function jr(e){let t=e.length-1;for(;t>0;t--){const r=Math.floor(Math.random()*(t+1)),n=e[t];e[t]=e[r],e[r]=n}return e}function wr(e,t){return t?(Object.keys(t).forEach((r=>{e[r]=t[r](e)})),e):e}function Er(e,...t){let r=0;return e.replace(/%s/g,(()=>encodeURIComponent(t[r++])))}const Pr="4.20.0",Ir={WithinQueryParameters:0,WithinHeaders:1};function Dr(e,t){const r=e||{},n=r.data||{};return Object.keys(r).forEach((e=>{-1===["timeout","headers","queryParameters","data","cacheable"].indexOf(e)&&(n[e]=r[e])})),{data:Object.entries(n).length>0?n:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}const Ar={Read:1,Write:2,Any:3},kr={Up:1,Down:2,Timeouted:3},xr=12e4;function Cr(e,t=kr.Up){return{...e,status:t,lastUpdate:Date.now()}}function _r(e){return"string"==typeof e?{protocol:"https",url:e,accept:Ar.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||Ar.Any}}const Nr={Delete:"DELETE",Get:"GET",Post:"POST",Put:"PUT"};function Tr(e,t){return Promise.all(t.map((t=>e.get(t,(()=>Promise.resolve(Cr(t))))))).then((e=>{const r=e.filter((e=>function(e){return e.status===kr.Up||Date.now()-e.lastUpdate>xr}(e))),n=e.filter((e=>function(e){return e.status===kr.Timeouted&&Date.now()-e.lastUpdate<=xr}(e))),o=[...r,...n];return{getTimeout:(e,t)=>(0===n.length&&0===e?1:n.length+3+e)*t,statelessHosts:o.length>0?o.map((e=>_r(e))):t}}))}const qr=(e,t)=>(e=>{const t=e.status;return e.isTimedOut||(({isTimedOut:e,status:t})=>!e&&0==~~t)(e)||2!=~~(t/100)&&4!=~~(t/100)})(e)?t.onRetry(e):(({status:e})=>2==~~(e/100))(e)?t.onSuccess(e):t.onFail(e);function Rr(e,t,r,n){const o=[],i=function(e,t){if(e.method===Nr.Get||void 0===e.data&&void 0===t.data)return;const r=Array.isArray(e.data)?e.data:{...e.data,...t.data};return JSON.stringify(r)}(r,n),a=function(e,t){const r={...e.headers,...t.headers},n={};return Object.keys(r).forEach((e=>{const t=r[e];n[e.toLowerCase()]=t})),n}(e,n),c=r.method,l=r.method!==Nr.Get?{}:{...r.data,...n.data},u={"x-algolia-agent":e.userAgent.value,...e.queryParameters,...l,...n.queryParameters};let s=0;const f=(t,l)=>{const m=t.pop();if(void 0===m)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:Fr(o)};const p={data:i,headers:a,method:c,url:Mr(m,r.path,u),connectTimeout:l(s,e.timeouts.connect),responseTimeout:l(s,n.timeout)},v=e=>{const r={request:p,response:e,host:m,triesLeft:t.length};return o.push(r),r},d={onSuccess:e=>function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e),onRetry(r){const n=v(r);return r.isTimedOut&&s++,Promise.all([e.logger.info("Retryable failure",Ur(n)),e.hostsCache.set(m,Cr(m,r.isTimedOut?kr.Timeouted:kr.Down))]).then((()=>f(t,l)))},onFail(e){throw v(e),function({content:e,status:t},r){let n=e;try{n=JSON.parse(e).message}catch(o){}return function(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}(n,t,r)}(e,Fr(o))}};return e.requester.send(p).then((e=>qr(e,d)))};return Tr(e.hostsCache,t).then((e=>f([...e.statelessHosts].reverse(),e.getTimeout)))}function Lr(e){const t={value:`Algolia for JavaScript (${e})`,add(e){const r=`; ${e.segment}${void 0!==e.version?` (${e.version})`:""}`;return-1===t.value.indexOf(r)&&(t.value=`${t.value}${r}`),t}};return t}function Mr(e,t,r){const n=Hr(r);let o=`${e.protocol}://${e.url}/${"/"===t.charAt(0)?t.substr(1):t}`;return n.length&&(o+=`?${n}`),o}function Hr(e){return Object.keys(e).map((t=>{return Er("%s=%s",t,(r=e[t],"[object Object]"===Object.prototype.toString.call(r)||"[object Array]"===Object.prototype.toString.call(r)?JSON.stringify(e[t]):e[t]));var r})).join("&")}function Fr(e){return e.map((e=>Ur(e)))}function Ur(e){const t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return{...e,request:{...e.request,headers:{...e.request.headers,...t}}}}const Br=e=>{const t=e.appId,r=function(e,t,r){const n={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers:()=>e===Ir.WithinHeaders?n:{},queryParameters:()=>e===Ir.WithinQueryParameters?n:{}}}(void 0!==e.authMode?e.authMode:Ir.WithinHeaders,t,e.apiKey),n=function(e){const{hostsCache:t,logger:r,requester:n,requestsCache:o,responsesCache:i,timeouts:a,userAgent:c,hosts:l,queryParameters:u,headers:s}=e,f={hostsCache:t,logger:r,requester:n,requestsCache:o,responsesCache:i,timeouts:a,userAgent:c,headers:s,queryParameters:u,hosts:l.map((e=>_r(e))),read(e,t){const r=Dr(t,f.timeouts.read),n=()=>Rr(f,f.hosts.filter((e=>0!=(e.accept&Ar.Read))),e,r);if(!0!==(void 0!==r.cacheable?r.cacheable:e.cacheable))return n();const o={request:e,mappedRequestOptions:r,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(o,(()=>f.requestsCache.get(o,(()=>f.requestsCache.set(o,n()).then((e=>Promise.all([f.requestsCache.delete(o),e])),(e=>Promise.all([f.requestsCache.delete(o),Promise.reject(e)]))).then((([e,t])=>t))))),{miss:e=>f.responsesCache.set(o,e)})},write:(e,t)=>Rr(f,f.hosts.filter((e=>0!=(e.accept&Ar.Write))),e,Dr(t,f.timeouts.write))};return f}({hosts:[{url:`${t}-dsn.algolia.net`,accept:Ar.Read},{url:`${t}.algolia.net`,accept:Ar.Write}].concat(jr([{url:`${t}-1.algolianet.com`},{url:`${t}-2.algolianet.com`},{url:`${t}-3.algolianet.com`}])),...e,headers:{...r.headers(),"content-type":"application/x-www-form-urlencoded",...e.headers},queryParameters:{...r.queryParameters(),...e.queryParameters}}),o={transporter:n,appId:t,addAlgoliaAgent(e,t){n.userAgent.add({segment:e,version:t})},clearCache:()=>Promise.all([n.requestsCache.clear(),n.responsesCache.clear()]).then((()=>{}))};return wr(o,e.methods)},Vr=e=>(t,r)=>t.method===Nr.Get?e.transporter.read(t,r):e.transporter.write(t,r),Kr=e=>(t,r={})=>wr({transporter:e.transporter,appId:e.appId,indexName:t},r.methods),$r=e=>(t,r)=>{const n=t.map((e=>({...e,params:Hr(e.params||{})})));return e.transporter.read({method:Nr.Post,path:"1/indexes/*/queries",data:{requests:n},cacheable:!0},r)},Jr=e=>(t,r)=>Promise.all(t.map((t=>{const{facetName:n,facetQuery:o,...i}=t.params;return Kr(e)(t.indexName,{methods:{searchForFacetValues:Qr}}).searchForFacetValues(n,o,{...r,...i})}))),zr=e=>(t,r,n)=>e.transporter.read({method:Nr.Post,path:Er("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:r},cacheable:!0},n),Wr=e=>(t,r)=>e.transporter.read({method:Nr.Post,path:Er("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r),Qr=e=>(t,r,n)=>e.transporter.read({method:Nr.Post,path:Er("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},n),Zr={Debug:1,Info:2,Error:3};function Gr(e,t,r){const n={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:e=>new Promise((t=>{const r=new XMLHttpRequest;r.open(e.method,e.url,!0),Object.keys(e.headers).forEach((t=>r.setRequestHeader(t,e.headers[t])));const n=(e,n)=>setTimeout((()=>{r.abort(),t({status:0,content:n,isTimedOut:!0})}),1e3*e),o=n(e.connectTimeout,"Connection timeout");let i;r.onreadystatechange=()=>{r.readyState>r.OPENED&&void 0===i&&(clearTimeout(o),i=n(e.responseTimeout,"Socket timeout"))},r.onerror=()=>{0===r.status&&(clearTimeout(o),clearTimeout(i),t({content:r.responseText||"Network request failed",status:r.status,isTimedOut:!1}))},r.onload=()=>{clearTimeout(o),clearTimeout(i),t({content:r.responseText,status:r.status,isTimedOut:!1})},r.send(e.data)}))},logger:(o=Zr.Error,{debug:(e,t)=>(Zr.Debug>=o&&console.debug(e,t),Promise.resolve()),info:(e,t)=>(Zr.Info>=o&&console.info(e,t),Promise.resolve()),error:(e,t)=>(console.error(e,t),Promise.resolve())}),responsesCache:Sr(),requestsCache:Sr({serializable:!1}),hostsCache:Or({caches:[gr({key:`${Pr}-${e}`}),Sr()]}),userAgent:Lr(Pr).add({segment:"Browser",version:"lite"}),authMode:Ir.WithinQueryParameters};var o;return Br({...n,...r,methods:{search:$r,searchForFacetValues:Jr,multipleQueries:$r,multipleSearchForFacetValues:Jr,customRequest:Vr,initIndex:e=>t=>Kr(e)(t,{methods:{search:Wr,searchForFacetValues:Qr,findAnswers:zr}})}})}Gr.version=Pr;const Xr=Gr;var Yr="3.5.2";function en(){}function tn(e){return e}function rn(e){return 1===e.button||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey}function nn(e,t,r){return e.reduce((function(e,n){var o=t(n);return e.hasOwnProperty(o)||(e[o]=[]),e[o].length<(r||5)&&e[o].push(n),e}),{})}var on=["footer","searchBox"];function an(){return an=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var r=0,n=new Array(t);r=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function pn(e){var t=e.appId,r=e.apiKey,n=e.indexName,o=e.placeholder,i=void 0===o?"Search docs":o,a=e.searchParameters,c=e.maxResultsPerGroup,l=e.onClose,u=void 0===l?en:l,s=e.transformItems,f=void 0===s?tn:s,m=e.hitComponent,p=void 0===m?St:m,v=e.resultsFooterComponent,d=void 0===v?function(){return null}:v,y=e.navigator,h=e.initialScrollY,b=void 0===h?0:h,g=e.transformSearchClient,O=void 0===g?tn:g,S=e.disableUserPersonalization,j=void 0!==S&&S,w=e.initialQuery,E=void 0===w?"":w,P=e.translations,I=void 0===P?{}:P,D=e.getMissingResultsUrl,A=e.insights,k=void 0!==A&&A,x=I.footer,C=I.searchBox,_=mn(I,on),N=sn(yt.useState({query:"",collections:[],completion:null,context:{},isOpen:!1,activeItemId:null,status:"idle"}),2),T=N[0],q=N[1],R=yt.useRef(null),L=yt.useRef(null),M=yt.useRef(null),H=yt.useRef(null),F=yt.useRef(null),U=yt.useRef(10),B=yt.useRef("undefined"!=typeof window?window.getSelection().toString().slice(0,ht):"").current,V=yt.useRef(E||B).current,K=function(e,t,r){return yt.useMemo((function(){var n=Xr(e,t);return n.addAlgoliaAgent("docsearch",Yr),!1===/docsearch.js \(.*\)/.test(n.transporter.userAgent.value)&&n.addAlgoliaAgent("docsearch-react",Yr),r(n)}),[e,t,r])}(t,r,O),$=yt.useRef(br({key:"__DOCSEARCH_FAVORITE_SEARCHES__".concat(n),limit:10})).current,J=yt.useRef(br({key:"__DOCSEARCH_RECENT_SEARCHES__".concat(n),limit:0===$.getAll().length?7:4})).current,z=yt.useCallback((function(e){if(!j){var t="content"===e.type?e.__docsearch_parent:e;t&&-1===$.getAll().findIndex((function(e){return e.objectID===t.objectID}))&&J.add(t)}}),[$,J,j]),W=yt.useCallback((function(e){if(T.context.algoliaInsightsPlugin&&e.__autocomplete_id){var t=e,r={eventName:"Item Selected",index:t.__autocomplete_indexName,items:[t],positions:[e.__autocomplete_id],queryID:t.__autocomplete_queryID};T.context.algoliaInsightsPlugin.insights.clickedObjectIDsAfterSearch(r)}}),[T.context.algoliaInsightsPlugin]),Q=yt.useMemo((function(){return dt({id:"docsearch",defaultActiveItemId:0,placeholder:i,openOnFocus:!0,initialState:{query:V,context:{searchSuggestions:[]}},insights:k,navigator:y,onStateChange:function(e){q(e.state)},getSources:function(e){var o=e.query,i=e.state,l=e.setContext,s=e.setStatus;if(!o)return j?[]:[{sourceId:"recentSearches",onSelect:function(e){var t=e.item,r=e.event;z(t),rn(r)||u()},getItemUrl:function(e){return e.item.url},getItems:function(){return J.getAll()}},{sourceId:"favoriteSearches",onSelect:function(e){var t=e.item,r=e.event;z(t),rn(r)||u()},getItemUrl:function(e){return e.item.url},getItems:function(){return $.getAll()}}];var m=Boolean(k);return K.search([{query:o,indexName:n,params:ln({attributesToRetrieve:["hierarchy.lvl0","hierarchy.lvl1","hierarchy.lvl2","hierarchy.lvl3","hierarchy.lvl4","hierarchy.lvl5","hierarchy.lvl6","content","type","url"],attributesToSnippet:["hierarchy.lvl1:".concat(U.current),"hierarchy.lvl2:".concat(U.current),"hierarchy.lvl3:".concat(U.current),"hierarchy.lvl4:".concat(U.current),"hierarchy.lvl5:".concat(U.current),"hierarchy.lvl6:".concat(U.current),"content:".concat(U.current)],snippetEllipsisText:"\u2026",highlightPreTag:"",highlightPostTag:"",hitsPerPage:20,clickAnalytics:m},a)}]).catch((function(e){throw"RetryError"===e.name&&s("error"),e})).then((function(e){var o=e.results[0],a=o.hits,s=o.nbHits,p=nn(a,(function(e){return Qt(e)}),c);i.context.searchSuggestions.length0&&(X(),F.current&&F.current.focus())}),[V,X]),yt.useEffect((function(){function e(){if(L.current){var e=.01*window.innerHeight;L.current.style.setProperty("--docsearch-vh","".concat(e,"px"))}}return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[]),yt.createElement("div",an({ref:R},G({"aria-expanded":!0}),{className:["DocSearch","DocSearch-Container","stalled"===T.status&&"DocSearch-Container--Stalled","error"===T.status&&"DocSearch-Container--Errored"].filter(Boolean).join(" "),role:"button",tabIndex:0,onMouseDown:function(e){e.target===e.currentTarget&&u()}}),yt.createElement("div",{className:"DocSearch-Modal",ref:L},yt.createElement("header",{className:"DocSearch-SearchBar",ref:M},yt.createElement(vr,an({},Q,{state:T,autoFocus:0===V.length,inputRef:F,isFromSelection:Boolean(V)&&V===B,translations:C,onClose:u}))),yt.createElement("div",{className:"DocSearch-Dropdown",ref:H},yt.createElement(lr,an({},Q,{indexName:n,state:T,hitComponent:p,resultsFooterComponent:d,disableUserPersonalization:j,recentSearches:J,favoriteSearches:$,inputRef:F,translations:_,getMissingResultsUrl:D,onItemClick:function(e,t){W(e),z(e),rn(t)||u()}}))),yt.createElement("footer",{className:"DocSearch-Footer"},yt.createElement(Ot,{translations:x}))))}}}]); \ No newline at end of file diff --git a/assets/js/14dc1923.1aa6fe97.js b/assets/js/14dc1923.1aa6fe97.js new file mode 100644 index 000000000..fe625f2ba --- /dev/null +++ b/assets/js/14dc1923.1aa6fe97.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7403],{40742:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var r=n(85893),i=n(3905);const l={title:"IntelliJ \uc124\uc815",slug:"intellij-settings",tags:["IntelliJ"]},a=void 0,o={permalink:"/intellij-settings",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",source:"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",title:"IntelliJ \uc124\uc815",description:"Import \uc790\ub3d9 \uc801\uc6a9",date:"2023-01-30T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 30\uc77c",tags:[{label:"IntelliJ",permalink:"/tags/intelli-j"}],readingTime:.465,hasTruncateMarker:!1,authors:[],frontMatter:{title:"IntelliJ \uc124\uc815",slug:"intellij-settings",tags:["IntelliJ"]},unlisted:!1,prevItem:{title:"Parameterized Tests",permalink:"/parameterized-tests"},nextItem:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",permalink:"/kotlin-null"}},s={authorsImageUrls:[]},c=[{value:"Import \uc790\ub3d9 \uc801\uc6a9",id:"import-\uc790\ub3d9-\uc801\uc6a9",level:3},{value:"\uc800\uc7a5\uc2dc \ub3d9\uc791",id:"\uc800\uc7a5\uc2dc-\ub3d9\uc791",level:3},{value:"\uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9",id:"\uba54\uc18c\ub4dc-\ucd94\ucd9c-\ubcc0\uc218-\ucd94\ucd9c\uc2dc-final-\uc801\uc6a9",level:3}];function p(e){const t={h3:"h3",img:"img",p:"p",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"import-\uc790\ub3d9-\uc801\uc6a9",children:"Import \uc790\ub3d9 \uc801\uc6a9"}),"\n",(0,r.jsx)(t.p,{children:"Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"auto-import",src:n(41394).Z+"",width:"2558",height:"1656"})}),"\n",(0,r.jsx)(t.h3,{id:"\uc800\uc7a5\uc2dc-\ub3d9\uc791",children:"\uc800\uc7a5\uc2dc \ub3d9\uc791"}),"\n",(0,r.jsx)(t.p,{children:"Prefrences > Tools > Actions on Save"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"actions-on-save",src:n(24927).Z+"",width:"2558",height:"1656"})}),"\n",(0,r.jsx)(t.p,{children:"Reformat Code: Code Reformmating"}),"\n",(0,r.jsx)(t.p,{children:"Optimize imports: \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 Import \uc81c\uac70"}),"\n",(0,r.jsx)(t.p,{children:"Rearrange: Code Style > Arrangement \uc124\uc815 \uae30\ubc18 \ucf54\ub4dc \uc7ac\uc815\ub82c"}),"\n",(0,r.jsx)(t.h3,{id:"\uba54\uc18c\ub4dc-\ucd94\ucd9c-\ubcc0\uc218-\ucd94\ucd9c\uc2dc-final-\uc801\uc6a9",children:"\uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9"}),"\n",(0,r.jsx)(t.p,{children:"Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"final-modifier",src:n(21796).Z+"",width:"2558",height:"1656"})})]})}function d(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>c});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),m=c(n),u=i,f=m["".concat(s,".").concat(u)]||m[u]||p[u]||l;return n?r.createElement(f,a(a({ref:t},d),{},{components:n})):r.createElement(f,a({ref:t},d))}));d.displayName="MDXCreateElement"},24927:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/actions-on-save-6c1203027c28ff08919e045812c7d456.png"},41394:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/auto-import-3dbe46f0109af17296039d52d498225e.png"},21796:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/final-modifier-1dd2aea35979423a30869a7b0ebe501a.png"}}]); \ No newline at end of file diff --git a/assets/js/14dc1923.82248792.js b/assets/js/14dc1923.82248792.js deleted file mode 100644 index 858efbde5..000000000 --- a/assets/js/14dc1923.82248792.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7403],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),m=p(n),f=i,d=m["".concat(s,".").concat(f)]||m[f]||u[f]||l;return n?r.createElement(d,a(a({ref:t},c),{},{components:n})):r.createElement(d,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var l=n.length,a=new Array(l);a[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:i,a[1]=o;for(var p=2;p{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const l={title:"IntelliJ \uc124\uc815",slug:"intellij-settings",tags:["IntelliJ"]},a=void 0,o={permalink:"/intellij-settings",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",source:"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",title:"IntelliJ \uc124\uc815",description:"Import \uc790\ub3d9 \uc801\uc6a9",date:"2023-01-30T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 30\uc77c",tags:[{label:"IntelliJ",permalink:"/tags/intelli-j"}],readingTime:.465,hasTruncateMarker:!1,authors:[],frontMatter:{title:"IntelliJ \uc124\uc815",slug:"intellij-settings",tags:["IntelliJ"]},prevItem:{title:"Parameterized Tests",permalink:"/parameterized-tests"},nextItem:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",permalink:"/kotlin-null"}},s={authorsImageUrls:[]},p=[{value:"Import \uc790\ub3d9 \uc801\uc6a9",id:"import-\uc790\ub3d9-\uc801\uc6a9",level:3},{value:"\uc800\uc7a5\uc2dc \ub3d9\uc791",id:"\uc800\uc7a5\uc2dc-\ub3d9\uc791",level:3},{value:"\uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9",id:"\uba54\uc18c\ub4dc-\ucd94\ucd9c-\ubcc0\uc218-\ucd94\ucd9c\uc2dc-final-\uc801\uc6a9",level:3}],c={toc:p};function u(e){let{components:t,...l}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,l,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h3",{id:"import-\uc790\ub3d9-\uc801\uc6a9"},"Import \uc790\ub3d9 \uc801\uc6a9"),(0,i.kt)("p",null,"Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"auto-import",src:n(41394).Z,width:"2558",height:"1656"})),(0,i.kt)("h3",{id:"\uc800\uc7a5\uc2dc-\ub3d9\uc791"},"\uc800\uc7a5\uc2dc \ub3d9\uc791"),(0,i.kt)("p",null,"Prefrences > Tools > Actions on Save"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"actions-on-save",src:n(24927).Z,width:"2558",height:"1656"})),(0,i.kt)("p",null,"Reformat Code: Code Reformmating"),(0,i.kt)("p",null,"Optimize imports: \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 Import \uc81c\uac70"),(0,i.kt)("p",null,"Rearrange: Code Style > Arrangement \uc124\uc815 \uae30\ubc18 \ucf54\ub4dc \uc7ac\uc815\ub82c"),(0,i.kt)("h3",{id:"\uba54\uc18c\ub4dc-\ucd94\ucd9c-\ubcc0\uc218-\ucd94\ucd9c\uc2dc-final-\uc801\uc6a9"},"\uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9"),(0,i.kt)("p",null,"Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"final-modifier",src:n(21796).Z,width:"2558",height:"1656"})))}u.isMDXComponent=!0},24927:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/actions-on-save-6c1203027c28ff08919e045812c7d456.png"},41394:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/auto-import-3dbe46f0109af17296039d52d498225e.png"},21796:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/final-modifier-1dd2aea35979423a30869a7b0ebe501a.png"}}]); \ No newline at end of file diff --git a/assets/js/1644.29f069a4.js b/assets/js/1644.29f069a4.js new file mode 100644 index 000000000..f8f1c6302 --- /dev/null +++ b/assets/js/1644.29f069a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1644],{41644:(n,e,t)=>{t.d(e,{bK:()=>Me});var r=t(70870),o=t(66749),i=t(17452),u=t(62002),a=t(27961),c=t(43836),s=t(74379),f=t(45625);class d{constructor(){var n={};n._next=n._prev=n,this._sentinel=n}dequeue(){var n=this._sentinel,e=n._prev;if(e!==n)return h(e),e}enqueue(n){var e=this._sentinel;n._prev&&n._next&&h(n),n._next=e._next,e._next._prev=n,e._next=n,n._prev=e}toString(){for(var n=[],e=this._sentinel,t=e._prev;t!==e;)n.push(JSON.stringify(t,v)),t=t._prev;return"["+n.join(", ")+"]"}}function h(n){n._prev._next=n._next,n._next._prev=n._prev,delete n._next,delete n._prev}function v(n,e){if("_next"!==n&&"_prev"!==n)return e}var l=u.Z(1);function Z(n,e){if(n.nodeCount()<=1)return[];var t=function(n,e){var t=new f.k,o=0,i=0;r.Z(n.nodes(),(function(n){t.setNode(n,{v:n,in:0,out:0})})),r.Z(n.edges(),(function(n){var r=t.edge(n.v,n.w)||0,u=e(n),a=r+u;t.setEdge(n.v,n.w,a),i=Math.max(i,t.node(n.v).out+=u),o=Math.max(o,t.node(n.w).in+=u)}));var u=s.Z(i+o+3).map((function(){return new d})),a=o+1;return r.Z(t.nodes(),(function(n){p(u,a,t.node(n))})),{graph:t,buckets:u,zeroIdx:a}}(n,e||l),o=function(n,e,t){var r,o=[],i=e[e.length-1],u=e[0];for(;n.nodeCount();){for(;r=u.dequeue();)g(n,e,t,r);for(;r=i.dequeue();)g(n,e,t,r);if(n.nodeCount())for(var a=e.length-2;a>0;--a)if(r=e[a].dequeue()){o=o.concat(g(n,e,t,r,!0));break}}return o}(t.graph,t.buckets,t.zeroIdx);return a.Z(c.Z(o,(function(e){return n.outEdges(e.v,e.w)})))}function g(n,e,t,o,i){var u=i?[]:void 0;return r.Z(n.inEdges(o.v),(function(r){var o=n.edge(r),a=n.node(r.v);i&&u.push({v:r.v,w:r.w}),a.out-=o,p(e,t,a)})),r.Z(n.outEdges(o.v),(function(r){var o=n.edge(r),i=r.w,u=n.node(i);u.in-=o,p(e,t,u)})),n.removeNode(o.v),u}function p(n,e,t){t.out?t.in?n[t.out-t.in+e].enqueue(t):n[n.length-1].enqueue(t):n[0].enqueue(t)}function b(n){var e="greedy"===n.graph().acyclicer?Z(n,function(n){return function(e){return n.edge(e).weight}}(n)):function(n){var e=[],t={},o={};function u(a){i.Z(o,a)||(o[a]=!0,t[a]=!0,r.Z(n.outEdges(a),(function(n){i.Z(t,n.w)?e.push(n):u(n.w)})),delete t[a])}return r.Z(n.nodes(),u),e}(n);r.Z(e,(function(e){var t=n.edge(e);n.removeEdge(e),t.forwardName=e.name,t.reversed=!0,n.setEdge(e.w,e.v,t,o.Z("rev"))}))}var w=t(59236),m=t(61666),y=t(3688),_=t(72714);const E=function(n,e,t){for(var r=-1,o=n.length;++re};var k=t(69203);const x=function(n){return n&&n.length?E(n,k.Z,j):void 0};const N=function(n){var e=null==n?0:n.length;return e?n[e-1]:void 0};var I=t(74752),C=t(2693),O=t(74765);const L=function(n,e){var t={};return e=(0,O.Z)(e,3),(0,C.Z)(n,(function(n,r,o){(0,I.Z)(t,r,e(n,r,o))})),t};var M=t(49360);const A=function(n,e){return nMath.abs(u)*s?(a<0&&(s=-s),t=s*u/a,r=s):(u<0&&(c=-c),t=c,r=c*a/u),{x:o+t,y:i+r}}function B(n){var e=c.Z(s.Z(V(n)+1),(function(){return[]}));return r.Z(n.nodes(),(function(t){var r=n.node(t),o=r.rank;M.Z(o)||(e[o][r.order]=t)})),e}function G(n,e,t,r){var o={width:0,height:0};return arguments.length>=4&&(o.rank=t,o.order=r),T(n,"border",o,e)}function V(n){return x(c.Z(n.nodes(),(function(e){var t=n.node(e).rank;if(!M.Z(t))return t})))}function z(n,e){var t=P();try{return e()}finally{console.log(n+" time: "+(P()-t)+"ms")}}function q(n,e){return e()}function U(n,e,t,r,o,i){var u={width:0,height:0,rank:i,borderType:e},a=o[e][i-1],c=T(n,"border",u,t);o[e][i]=c,n.setParent(c,r),a&&n.setEdge(a,c,{weight:1})}function Y(n){var e=n.graph().rankdir.toLowerCase();"bt"!==e&&"rl"!==e||function(n){r.Z(n.nodes(),(function(e){K(n.node(e))})),r.Z(n.edges(),(function(e){var t=n.edge(e);r.Z(t.points,K),i.Z(t,"y")&&K(t)}))}(n),"lr"!==e&&"rl"!==e||(!function(n){r.Z(n.nodes(),(function(e){W(n.node(e))})),r.Z(n.edges(),(function(e){var t=n.edge(e);r.Z(t.points,W),i.Z(t,"x")&&W(t)}))}(n),$(n))}function $(n){r.Z(n.nodes(),(function(e){J(n.node(e))})),r.Z(n.edges(),(function(e){J(n.edge(e))}))}function J(n){var e=n.width;n.width=n.height,n.height=e}function K(n){n.y=-n.y}function W(n){var e=n.x;n.x=n.y,n.y=e}function H(n){n.graph().dummyChains=[],r.Z(n.edges(),(function(e){!function(n,e){var t,r,o,i=e.v,u=n.node(i).rank,a=e.w,c=n.node(a).rank,s=e.name,f=n.edge(e),d=f.labelRank;if(c===u+1)return;for(n.removeEdge(e),o=0,++u;u-1?o[i?e[u]:u]:void 0}};var sn=t(21692),fn=t(94099);const dn=function(n){var e=(0,fn.Z)(n),t=e%1;return e==e?t?e-t:e:0};var hn=Math.max;const vn=cn((function(n,e,t){var r=null==n?0:n.length;if(!r)return-1;var o=null==t?0:dn(t);return o<0&&(o=hn(r+o,0)),(0,sn.Z)(n,(0,O.Z)(e,3),o)}));var ln=t(13445);u.Z(1);u.Z(1);t(39473),t(83970),t(93589);var Zn=t(27771);t(18533);(0,t(54193).Z)("length");RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");var gn="\\ud800-\\udfff",pn="["+gn+"]",bn="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",wn="\\ud83c[\\udffb-\\udfff]",mn="[^"+gn+"]",yn="(?:\\ud83c[\\udde6-\\uddff]){2}",_n="[\\ud800-\\udbff][\\udc00-\\udfff]",En="(?:"+bn+"|"+wn+")"+"?",jn="[\\ufe0e\\ufe0f]?",kn=jn+En+("(?:\\u200d(?:"+[mn,yn,_n].join("|")+")"+jn+En+")*"),xn="(?:"+[mn+bn+"?",bn,yn,_n,pn].join("|")+")";RegExp(wn+"(?="+wn+")|"+xn+kn,"g");function Nn(){}function In(n,e,t){Zn.Z(e)||(e=[e]);var o=(n.isDirected()?n.successors:n.neighbors).bind(n),i=[],u={};return r.Z(e,(function(e){if(!n.hasNode(e))throw new Error("Graph does not have node: "+e);Cn(n,e,"post"===t,u,o,i)})),i}function Cn(n,e,t,o,u,a){i.Z(o,e)||(o[e]=!0,t||a.push(e),r.Z(u(e),(function(e){Cn(n,e,t,o,u,a)})),t&&a.push(e))}Nn.prototype=new Error;t(52544);function On(n){n=function(n){var e=(new f.k).setGraph(n.graph());return r.Z(n.nodes(),(function(t){e.setNode(t,n.node(t))})),r.Z(n.edges(),(function(t){var r=e.edge(t.v,t.w)||{weight:0,minlen:1},o=n.edge(t);e.setEdge(t.v,t.w,{weight:r.weight+o.weight,minlen:Math.max(r.minlen,o.minlen)})})),e}(n),X(n);var e,t=en(n);for(An(t),Ln(t,n);e=Sn(t);)Tn(t,n,e,Pn(t,n,e))}function Ln(n,e){var t=function(n,e){return In(n,e,"post")}(n,n.nodes());t=t.slice(0,t.length-1),r.Z(t,(function(t){!function(n,e,t){var r=n.node(t),o=r.parent;n.edge(t,o).cutvalue=Mn(n,e,t)}(n,e,t)}))}function Mn(n,e,t){var o=n.node(t).parent,i=!0,u=e.edge(t,o),a=0;return u||(i=!1,u=e.edge(o,t)),a=u.weight,r.Z(e.nodeEdges(t),(function(r){var u,c,s=r.v===t,f=s?r.w:r.v;if(f!==o){var d=s===i,h=e.edge(r).weight;if(a+=d?h:-h,u=t,c=f,n.hasEdge(u,c)){var v=n.edge(t,f).cutvalue;a+=d?-v:v}}})),a}function An(n,e){arguments.length<2&&(e=n.nodes()[0]),Rn(n,{},1,e)}function Rn(n,e,t,o,u){var a=t,c=n.node(o);return e[o]=!0,r.Z(n.neighbors(o),(function(r){i.Z(e,r)||(t=Rn(n,e,t,r,o))})),c.low=a,c.lim=t++,u?c.parent=u:delete c.parent,t}function Sn(n){return vn(n.edges(),(function(e){return n.edge(e).cutvalue<0}))}function Pn(n,e,t){var r=t.v,o=t.w;e.hasEdge(r,o)||(r=t.w,o=t.v);var i=n.node(r),u=n.node(o),a=i,c=!1;i.lim>u.lim&&(a=u,c=!0);var s=ln.Z(e.edges(),(function(e){return c===Fn(n,n.node(e.v),a)&&c!==Fn(n,n.node(e.w),a)}));return Q(s,(function(n){return nn(e,n)}))}function Tn(n,e,t,o){var i=t.v,u=t.w;n.removeEdge(i,u),n.setEdge(o.v,o.w,{}),An(n),Ln(n,e),function(n,e){var t=vn(n.nodes(),(function(n){return!e.node(n).parent})),o=function(n,e){return In(n,e,"pre")}(n,t);o=o.slice(1),r.Z(o,(function(t){var r=n.node(t).parent,o=e.edge(t,r),i=!1;o||(o=e.edge(r,t),i=!0),e.node(t).rank=e.node(r).rank+(i?o.minlen:-o.minlen)}))}(n,e)}function Fn(n,e,t){return t.low<=e.lim&&e.lim<=t.lim}function Dn(n){switch(n.graph().ranker){case"network-simplex":default:Gn(n);break;case"tight-tree":!function(n){X(n),en(n)}(n);break;case"longest-path":Bn(n)}}On.initLowLimValues=An,On.initCutValues=Ln,On.calcCutValue=Mn,On.leaveEdge=Sn,On.enterEdge=Pn,On.exchangeEdges=Tn;var Bn=X;function Gn(n){On(n)}var Vn=t(34148),zn=t(92344);function qn(n){var e=T(n,"root",{},"_root"),t=function(n){var e={};function t(o,i){var u=n.children(o);u&&u.length&&r.Z(u,(function(n){t(n,i+1)})),e[o]=i}return r.Z(n.children(),(function(n){t(n,1)})),e}(n),o=x(Vn.Z(t))-1,i=2*o+1;n.graph().nestingRoot=e,r.Z(n.edges(),(function(e){n.edge(e).minlen*=i}));var u=function(n){return zn.Z(n.edges(),(function(e,t){return e+n.edge(t).weight}),0)}(n)+1;r.Z(n.children(),(function(r){Un(n,e,i,u,o,t,r)})),n.graph().nodeRankFactor=i}function Un(n,e,t,o,i,u,a){var c=n.children(a);if(c.length){var s=G(n,"_bt"),f=G(n,"_bb"),d=n.node(a);n.setParent(s,a),d.borderTop=s,n.setParent(f,a),d.borderBottom=f,r.Z(c,(function(r){Un(n,e,t,o,i,u,r);var c=n.node(r),d=c.borderTop?c.borderTop:r,h=c.borderBottom?c.borderBottom:r,v=c.borderTop?o:2*o,l=d!==h?1:i-u[a]+1;n.setEdge(s,d,{weight:v,minlen:l,nestingEdge:!0}),n.setEdge(h,f,{weight:v,minlen:l,nestingEdge:!0})})),n.parent(a)||n.setEdge(e,s,{weight:0,minlen:i+u[a]})}else a!==e&&n.setEdge(e,a,{weight:0,minlen:t})}var Yn=t(48451);const $n=function(n){return(0,Yn.Z)(n,5)};function Jn(n,e,t){var u=function(n){var e;for(;n.hasNode(e=o.Z("_root")););return e}(n),a=new f.k({compound:!0}).setGraph({root:u}).setDefaultNodeLabel((function(e){return n.node(e)}));return r.Z(n.nodes(),(function(o){var c=n.node(o),s=n.parent(o);(c.rank===e||c.minRank<=e&&e<=c.maxRank)&&(a.setNode(o),a.setParent(o,s||u),r.Z(n[t](o),(function(e){var t=e.v===o?e.w:e.v,r=a.edge(t,o),i=M.Z(r)?0:r.weight;a.setEdge(t,o,{weight:n.edge(e).weight+i})})),i.Z(c,"minRank")&&a.setNode(o,{borderLeft:c.borderLeft[e],borderRight:c.borderRight[e]}))})),a}var Kn=t(72954);const Wn=function(n,e,t){for(var r=-1,o=n.length,i=e.length,u={};++re||i&&u&&c&&!a&&!s||r&&u&&c||!t&&c||!o)return 1;if(!r&&!i&&!s&&n=a?c:c*("desc"==t[r]?-1:1)}return n.index-e.index};const ue=function(n,e,t){e=e.length?(0,Xn.Z)(e,(function(n){return(0,Zn.Z)(n)?function(e){return(0,ne.Z)(e,1===n.length?n[0]:n)}:n})):[k.Z];var r=-1;e=(0,Xn.Z)(e,(0,re.Z)(O.Z));var o=(0,ee.Z)(n,(function(n,t,o){return{criteria:(0,Xn.Z)(e,(function(e){return e(n)})),index:++r,value:n}}));return te(o,(function(n,e){return ie(n,e,t)}))};var ae=t(69581),ce=t(50439);const se=(0,ae.Z)((function(n,e){if(null==n)return[];var t=e.length;return t>1&&(0,ce.Z)(n,e[0],e[1])?e=[]:t>2&&(0,ce.Z)(e[0],e[1],e[2])&&(e=[e[0]]),ue(n,(0,Qn.Z)(e,1),[])}));function fe(n,e){for(var t=0,r=1;r0;)e%2&&(t+=f[e+1]),f[e=e-1>>1]+=n.weight;d+=n.weight*t}))),d}function he(n,e){var t={};return r.Z(n,(function(n,e){var r=t[n.v]={indegree:0,in:[],out:[],vs:[n.v],i:e};M.Z(n.barycenter)||(r.barycenter=n.barycenter,r.weight=n.weight)})),r.Z(e.edges(),(function(n){var e=t[n.v],r=t[n.w];M.Z(e)||M.Z(r)||(r.indegree++,e.out.push(t[n.w]))})),function(n){var e=[];function t(n){return function(e){e.merged||(M.Z(e.barycenter)||M.Z(n.barycenter)||e.barycenter>=n.barycenter)&&function(n,e){var t=0,r=0;n.weight&&(t+=n.barycenter*n.weight,r+=n.weight);e.weight&&(t+=e.barycenter*e.weight,r+=e.weight);n.vs=e.vs.concat(n.vs),n.barycenter=t/r,n.weight=r,n.i=Math.min(e.i,n.i),e.merged=!0}(n,e)}}function o(e){return function(t){t.in.push(e),0==--t.indegree&&n.push(t)}}for(;n.length;){var i=n.pop();e.push(i),r.Z(i.in.reverse(),t(i)),r.Z(i.out,o(i))}return c.Z(ln.Z(e,(function(n){return!n.merged})),(function(n){return m.Z(n,["vs","i","barycenter","weight"])}))}(ln.Z(t,(function(n){return!n.indegree})))}function ve(n,e){var t,o=function(n,e){var t={lhs:[],rhs:[]};return r.Z(n,(function(n){e(n)?t.lhs.push(n):t.rhs.push(n)})),t}(n,(function(n){return i.Z(n,"barycenter")})),u=o.lhs,c=se(o.rhs,(function(n){return-n.i})),s=[],f=0,d=0,h=0;u.sort((t=!!e,function(n,e){return n.barycentere.barycenter?1:t?e.i-n.i:n.i-e.i})),h=le(s,c,h),r.Z(u,(function(n){h+=n.vs.length,s.push(n.vs),f+=n.barycenter*n.weight,d+=n.weight,h=le(s,c,h)}));var v={vs:a.Z(s)};return d&&(v.barycenter=f/d,v.weight=d),v}function le(n,e,t){for(var r;e.length&&(r=N(e)).i<=t;)e.pop(),n.push(r.vs),t++;return t}function Ze(n,e,t,o){var u=n.children(e),s=n.node(e),f=s?s.borderLeft:void 0,d=s?s.borderRight:void 0,h={};f&&(u=ln.Z(u,(function(n){return n!==f&&n!==d})));var v=function(n,e){return c.Z(e,(function(e){var t=n.inEdges(e);if(t.length){var r=zn.Z(t,(function(e,t){var r=n.edge(t),o=n.node(t.v);return{sum:e.sum+r.weight*o.order,weight:e.weight+r.weight}}),{sum:0,weight:0});return{v:e,barycenter:r.sum/r.weight,weight:r.weight}}return{v:e}}))}(n,u);r.Z(v,(function(e){if(n.children(e.v).length){var r=Ze(n,e.v,t,o);h[e.v]=r,i.Z(r,"barycenter")&&(u=e,a=r,M.Z(u.barycenter)?(u.barycenter=a.barycenter,u.weight=a.weight):(u.barycenter=(u.barycenter*u.weight+a.barycenter*a.weight)/(u.weight+a.weight),u.weight+=a.weight))}var u,a}));var l=he(v,t);!function(n,e){r.Z(n,(function(n){n.vs=a.Z(n.vs.map((function(n){return e[n]?e[n].vs:n})))}))}(l,h);var Z=ve(l,o);if(f&&(Z.vs=a.Z([f,Z.vs,d]),n.predecessors(f).length)){var g=n.node(n.predecessors(f)[0]),p=n.node(n.predecessors(d)[0]);i.Z(Z,"barycenter")||(Z.barycenter=0,Z.weight=0),Z.barycenter=(Z.barycenter*Z.weight+g.order+p.order)/(Z.weight+2),Z.weight+=2}return Z}function ge(n){var e=V(n),t=pe(n,s.Z(1,e+1),"inEdges"),o=pe(n,s.Z(e-1,-1,-1),"outEdges"),u=function(n){var e={},t=ln.Z(n.nodes(),(function(e){return!n.children(e).length})),o=x(c.Z(t,(function(e){return n.node(e).rank}))),u=c.Z(s.Z(o+1),(function(){return[]})),a=se(t,(function(e){return n.node(e).rank}));return r.Z(a,(function t(o){if(!i.Z(e,o)){e[o]=!0;var a=n.node(o);u[a.rank].push(o),r.Z(n.successors(o),t)}})),u}(n);we(n,u);for(var a,f=Number.POSITIVE_INFINITY,d=0,h=0;h<4;++d,++h){be(d%2?t:o,d%4>=2);var v=fe(n,u=B(n));vc||s>e[o].lim));i=o,o=r;for(;(o=n.parent(o))!==i;)a.push(o);return{path:u.concat(a.reverse()),lca:i}}(n,e,o.v,o.w),u=i.path,a=i.lca,c=0,s=u[c],f=!0;t!==o.w;){if(r=n.node(t),f){for(;(s=u[c])!==a&&n.node(s).maxRankt){var r=e;e=t,t=r}var o=n[e];o||(n[e]=o={}),o[t]=!0}function Ie(n,e,t){if(e>t){var r=e;e=t,t=r}return i.Z(n[e],t)}function Ce(n,e,t,o,u){var a={},c=function(n,e,t,o){var u=new f.k,a=n.graph(),c=function(n,e,t){return function(r,o,u){var a,c=r.node(o),s=r.node(u),f=0;if(f+=c.width/2,i.Z(c,"labelpos"))switch(c.labelpos.toLowerCase()){case"l":a=-c.width/2;break;case"r":a=c.width/2}if(a&&(f+=t?a:-a),a=0,f+=(c.dummy?e:n)/2,f+=(s.dummy?e:n)/2,f+=s.width/2,i.Z(s,"labelpos"))switch(s.labelpos.toLowerCase()){case"l":a=s.width/2;break;case"r":a=-s.width/2}return a&&(f+=t?a:-a),a=0,f}}(a.nodesep,a.edgesep,o);return r.Z(e,(function(e){var o;r.Z(e,(function(e){var r=t[e];if(u.setNode(r),o){var i=t[o],a=u.edge(i,r);u.setEdge(i,r,Math.max(c(n,e,o),a||0))}o=e}))})),u}(n,e,t,u),s=u?"borderLeft":"borderRight";function d(n,e){for(var t=c.nodes(),r=t.pop(),o={};r;)o[r]?n(r):(o[r]=!0,t.push(r),t=t.concat(e(r))),r=t.pop()}return d((function(n){a[n]=c.inEdges(n).reduce((function(n,e){return Math.max(n,a[e.v]+c.edge(e))}),0)}),c.predecessors.bind(c)),d((function(e){var t=c.outEdges(e).reduce((function(n,e){return Math.min(n,a[e.w]-c.edge(e))}),Number.POSITIVE_INFINITY),r=n.node(e);t!==Number.POSITIVE_INFINITY&&r.borderType!==s&&(a[e]=Math.max(a[e],t))}),c.successors.bind(c)),r.Z(o,(function(n){a[n]=a[t[n]]})),a}function Oe(n){var e,t=B(n),o=w.Z(xe(n,t),function(n,e){var t={};function o(e,o,i,u,a){var c;r.Z(s.Z(o,i),(function(o){c=e[o],n.node(c).dummy&&r.Z(n.predecessors(c),(function(e){var r=n.node(e);r.dummy&&(r.ordera)&&Ne(t,e,c)}))}))}return zn.Z(e,(function(e,t){var i,u=-1,a=0;return r.Z(t,(function(r,c){if("border"===n.node(r).dummy){var s=n.predecessors(r);s.length&&(i=n.node(s[0]).order,o(t,a,c,u,i),a=c,u=i)}o(t,a,t.length,i,e.length)})),t})),t}(n,t)),i={};r.Z(["u","d"],(function(u){e="u"===u?t:Vn.Z(t).reverse(),r.Z(["l","r"],(function(t){"r"===t&&(e=c.Z(e,(function(n){return Vn.Z(n).reverse()})));var a=("u"===u?n.predecessors:n.successors).bind(n),s=function(n,e,t,o){var i={},u={},a={};return r.Z(e,(function(n){r.Z(n,(function(n,e){i[n]=n,u[n]=n,a[n]=e}))})),r.Z(e,(function(n){var e=-1;r.Z(n,(function(n){var r=o(n);if(r.length){r=se(r,(function(n){return a[n]}));for(var c=(r.length-1)/2,s=Math.floor(c),f=Math.ceil(c);s<=f;++s){var d=r[s];u[n]===n&&e{t.d(e,{k:()=>R});var r=t(17452),o=t(62002),i=t(73234),u=t(17179),a=t(13445),c=t(79697),s=t(70870),f=t(49360),d=t(10626),h=t(69581),v=t(63001),l=t(21692);const Z=function(n){return n!=n};const g=function(n,e,t){for(var r=t-1,o=n.length;++r-1};const w=function(n,e,t){for(var r=-1,o=null==n?0:n.length;++r=200){var s=e?null:k(n);if(s)return(0,E.Z)(s);u=!1,o=m.Z,c=new v.Z}else c=e?[]:a;n:for(;++r1?r.setNode(n,e):r.setNode(n)})),this}setNode(n,e){return r.Z(this._nodes,n)?(arguments.length>1&&(this._nodes[n]=e),this):(this._nodes[n]=arguments.length>1?e:this._defaultNodeLabelFn(n),this._isCompound&&(this._parent[n]=M,this._children[n]={},this._children[M][n]=!0),this._in[n]={},this._preds[n]={},this._out[n]={},this._sucs[n]={},++this._nodeCount,this)}node(n){return this._nodes[n]}hasNode(n){return r.Z(this._nodes,n)}removeNode(n){var e=this;if(r.Z(this._nodes,n)){var t=function(n){e.removeEdge(e._edgeObjs[n])};delete this._nodes[n],this._isCompound&&(this._removeFromParentsChildList(n),delete this._parent[n],s.Z(this.children(n),(function(n){e.setParent(n)})),delete this._children[n]),s.Z(u.Z(this._in[n]),t),delete this._in[n],delete this._preds[n],s.Z(u.Z(this._out[n]),t),delete this._out[n],delete this._sucs[n],--this._nodeCount}return this}setParent(n,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(f.Z(e))e=M;else{for(var t=e+="";!f.Z(t);t=this.parent(t))if(t===n)throw new Error("Setting "+e+" as parent of "+n+" would create a cycle");this.setNode(e)}return this.setNode(n),this._removeFromParentsChildList(n),this._parent[n]=e,this._children[e][n]=!0,this}_removeFromParentsChildList(n){delete this._children[this._parent[n]][n]}parent(n){if(this._isCompound){var e=this._parent[n];if(e!==M)return e}}children(n){if(f.Z(n)&&(n=M),this._isCompound){var e=this._children[n];if(e)return u.Z(e)}else{if(n===M)return this.nodes();if(this.hasNode(n))return[]}}predecessors(n){var e=this._preds[n];if(e)return u.Z(e)}successors(n){var e=this._sucs[n];if(e)return u.Z(e)}neighbors(n){var e=this.predecessors(n);if(e)return I(e,this.successors(n))}isLeaf(n){return 0===(this.isDirected()?this.successors(n):this.neighbors(n)).length}filterNodes(n){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var t=this;s.Z(this._nodes,(function(t,r){n(r)&&e.setNode(r,t)})),s.Z(this._edgeObjs,(function(n){e.hasNode(n.v)&&e.hasNode(n.w)&&e.setEdge(n,t.edge(n))}));var r={};function o(n){var i=t.parent(n);return void 0===i||e.hasNode(i)?(r[n]=i,i):i in r?r[i]:o(i)}return this._isCompound&&s.Z(e.nodes(),(function(n){e.setParent(n,o(n))})),e}setDefaultEdgeLabel(n){return i.Z(n)||(n=o.Z(n)),this._defaultEdgeLabelFn=n,this}edgeCount(){return this._edgeCount}edges(){return C.Z(this._edgeObjs)}setPath(n,e){var t=this,r=arguments;return O.Z(n,(function(n,o){return r.length>1?t.setEdge(n,o,e):t.setEdge(n,o),o})),this}setEdge(){var n,e,t,o,i=!1,u=arguments[0];"object"==typeof u&&null!==u&&"v"in u?(n=u.v,e=u.w,t=u.name,2===arguments.length&&(o=arguments[1],i=!0)):(n=u,e=arguments[1],t=arguments[3],arguments.length>2&&(o=arguments[2],i=!0)),n=""+n,e=""+e,f.Z(t)||(t=""+t);var a=T(this._isDirected,n,e,t);if(r.Z(this._edgeLabels,a))return i&&(this._edgeLabels[a]=o),this;if(!f.Z(t)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(n),this.setNode(e),this._edgeLabels[a]=i?o:this._defaultEdgeLabelFn(n,e,t);var c=function(n,e,t,r){var o=""+e,i=""+t;if(!n&&o>i){var u=o;o=i,i=u}var a={v:o,w:i};r&&(a.name=r);return a}(this._isDirected,n,e,t);return n=c.v,e=c.w,Object.freeze(c),this._edgeObjs[a]=c,S(this._preds[e],n),S(this._sucs[n],e),this._in[e][a]=c,this._out[n][a]=c,this._edgeCount++,this}edge(n,e,t){var r=1===arguments.length?F(this._isDirected,arguments[0]):T(this._isDirected,n,e,t);return this._edgeLabels[r]}hasEdge(n,e,t){var o=1===arguments.length?F(this._isDirected,arguments[0]):T(this._isDirected,n,e,t);return r.Z(this._edgeLabels,o)}removeEdge(n,e,t){var r=1===arguments.length?F(this._isDirected,arguments[0]):T(this._isDirected,n,e,t),o=this._edgeObjs[r];return o&&(n=o.v,e=o.w,delete this._edgeLabels[r],delete this._edgeObjs[r],P(this._preds[e],n),P(this._sucs[n],e),delete this._in[e][r],delete this._out[n][r],this._edgeCount--),this}inEdges(n,e){var t=this._in[n];if(t){var r=C.Z(t);return e?a.Z(r,(function(n){return n.v===e})):r}}outEdges(n,e){var t=this._out[n];if(t){var r=C.Z(t);return e?a.Z(r,(function(n){return n.w===e})):r}}nodeEdges(n,e){var t=this.inEdges(n,e);if(t)return t.concat(this.outEdges(n,e))}}function S(n,e){n[e]?n[e]++:n[e]=1}function P(n,e){--n[e]||delete n[e]}function T(n,e,t,r){var o=""+e,i=""+t;if(!n&&o>i){var u=o;o=i,i=u}return o+A+i+A+(f.Z(r)?L:r)}function F(n,e){return T(n,e.v,e.w,e.name)}R.prototype._nodeCount=0,R.prototype._edgeCount=0},45625:(n,e,t)=>{t.d(e,{k:()=>r.k});var r=t(52544)},63001:(n,e,t)=>{t.d(e,{Z:()=>a});var r=t(37834);const o=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this};const i=function(n){return this.__data__.has(n)};function u(n){var e=-1,t=null==n?0:n.length;for(this.__data__=new r.Z;++e{t.d(e,{Z:()=>r});const r=function(n,e){for(var t=-1,r=null==n?0:n.length;++t{t.d(e,{Z:()=>r});const r=function(n,e){for(var t=-1,r=null==n?0:n.length,o=0,i=[];++t{t.d(e,{Z:()=>r});const r=function(n,e){for(var t=-1,r=null==n?0:n.length,o=Array(r);++t{t.d(e,{Z:()=>r});const r=function(n,e){for(var t=-1,r=e.length,o=n.length;++t{t.d(e,{Z:()=>X});var r=t(31667),o=t(76579),i=t(72954),u=t(31899),a=t(17179);const c=function(n,e){return n&&(0,u.Z)(e,(0,a.Z)(e),n)};var s=t(32957);const f=function(n,e){return n&&(0,u.Z)(e,(0,s.Z)(e),n)};var d=t(91050),h=t(87215),v=t(95695);const l=function(n,e){return(0,u.Z)(n,(0,v.Z)(n),e)};var Z=t(58694),g=t(12513),p=t(60532);const b=Object.getOwnPropertySymbols?function(n){for(var e=[];n;)(0,Z.Z)(e,(0,v.Z)(n)),n=(0,g.Z)(n);return e}:p.Z;const w=function(n,e){return(0,u.Z)(n,b(n),e)};var m=t(1808),y=t(63327);const _=function(n){return(0,y.Z)(n,s.Z,b)};var E=t(83970),j=Object.prototype.hasOwnProperty;const k=function(n){var e=n.length,t=new n.constructor(e);return e&&"string"==typeof n[0]&&j.call(n,"index")&&(t.index=n.index,t.input=n.input),t};var x=t(41884);const N=function(n,e){var t=e?(0,x.Z)(n.buffer):n.buffer;return new n.constructor(t,n.byteOffset,n.byteLength)};var I=/\w*$/;const C=function(n){var e=new n.constructor(n.source,I.exec(n));return e.lastIndex=n.lastIndex,e};var O=t(17685),L=O.Z?O.Z.prototype:void 0,M=L?L.valueOf:void 0;const A=function(n){return M?Object(M.call(n)):{}};var R=t(12701);const S=function(n,e,t){var r=n.constructor;switch(e){case"[object ArrayBuffer]":return(0,x.Z)(n);case"[object Boolean]":case"[object Date]":return new r(+n);case"[object DataView]":return N(n,t);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return(0,R.Z)(n,t);case"[object Map]":case"[object Set]":return new r;case"[object Number]":case"[object String]":return new r(n);case"[object RegExp]":return C(n);case"[object Symbol]":return A(n)}};var P=t(73658),T=t(27771),F=t(77008),D=t(18533);const B=function(n){return(0,D.Z)(n)&&"[object Map]"==(0,E.Z)(n)};var G=t(21162),V=t(98351),z=V.Z&&V.Z.isMap;const q=z?(0,G.Z)(z):B;var U=t(77226);const Y=function(n){return(0,D.Z)(n)&&"[object Set]"==(0,E.Z)(n)};var $=V.Z&&V.Z.isSet;const J=$?(0,G.Z)($):Y;var K="[object Arguments]",W="[object Function]",H="[object Object]",Q={};Q[K]=Q["[object Array]"]=Q["[object ArrayBuffer]"]=Q["[object DataView]"]=Q["[object Boolean]"]=Q["[object Date]"]=Q["[object Float32Array]"]=Q["[object Float64Array]"]=Q["[object Int8Array]"]=Q["[object Int16Array]"]=Q["[object Int32Array]"]=Q["[object Map]"]=Q["[object Number]"]=Q[H]=Q["[object RegExp]"]=Q["[object Set]"]=Q["[object String]"]=Q["[object Symbol]"]=Q["[object Uint8Array]"]=Q["[object Uint8ClampedArray]"]=Q["[object Uint16Array]"]=Q["[object Uint32Array]"]=!0,Q["[object Error]"]=Q[W]=Q["[object WeakMap]"]=!1;const X=function n(e,t,u,v,Z,g){var p,b=1&t,y=2&t,j=4&t;if(u&&(p=Z?u(e,v,Z,g):u(e)),void 0!==p)return p;if(!(0,U.Z)(e))return e;var x=(0,T.Z)(e);if(x){if(p=k(e),!b)return(0,h.Z)(e,p)}else{var N=(0,E.Z)(e),I=N==W||"[object GeneratorFunction]"==N;if((0,F.Z)(e))return(0,d.Z)(e,b);if(N==H||N==K||I&&!Z){if(p=y||I?{}:(0,P.Z)(e),!b)return y?w(e,f(p,e)):l(e,c(p,e))}else{if(!Q[N])return Z?e:{};p=S(e,N,b)}}g||(g=new r.Z);var C=g.get(e);if(C)return C;g.set(e,p),J(e)?e.forEach((function(r){p.add(n(r,t,u,r,e,g))})):q(e)&&e.forEach((function(r,o){p.set(o,n(r,t,u,o,e,g))}));var O=j?y?_:m.Z:y?s.Z:a.Z,L=x?void 0:O(e);return(0,o.Z)(L||e,(function(r,o){L&&(r=e[o=r]),(0,i.Z)(p,o,n(r,t,u,o,e,g))})),p}},49811:(n,e,t)=>{t.d(e,{Z:()=>i});var r=t(2693),o=t(50585);const i=function(n,e){return function(t,r){if(null==t)return t;if(!(0,o.Z)(t))return n(t,r);for(var i=t.length,u=e?i:-1,a=Object(t);(e?u--:++u{t.d(e,{Z:()=>r});const r=function(n,e,t,r){for(var o=n.length,i=t+(r?1:-1);r?i--:++i{t.d(e,{Z:()=>s});var r=t(58694),o=t(17685),i=t(29169),u=t(27771),a=o.Z?o.Z.isConcatSpreadable:void 0;const c=function(n){return(0,u.Z)(n)||(0,i.Z)(n)||!!(a&&n&&n[a])};const s=function n(e,t,o,i,u){var a=-1,s=e.length;for(o||(o=c),u||(u=[]);++a0&&o(f)?t>1?n(f,t-1,o,i,u):(0,r.Z)(u,f):i||(u[u.length]=f)}return u}},2693:(n,e,t)=>{t.d(e,{Z:()=>i});var r=t(61395),o=t(17179);const i=function(n,e){return n&&(0,r.Z)(n,e,o.Z)}},13317:(n,e,t)=>{t.d(e,{Z:()=>i});var r=t(22823),o=t(62281);const i=function(n,e){for(var t=0,i=(e=(0,r.Z)(e,n)).length;null!=n&&t{t.d(e,{Z:()=>i});var r=t(58694),o=t(27771);const i=function(n,e,t){var i=e(n);return(0,o.Z)(n)?i:(0,r.Z)(i,t(n))}},74765:(n,e,t)=>{t.d(e,{Z:()=>$});var r=t(31667),o=t(63001);const i=function(n,e){for(var t=-1,r=null==n?0:n.length;++tf))return!1;var h=c.get(n),v=c.get(e);if(h&&v)return h==e&&v==n;var l=-1,Z=!0,g=2&t?new o.Z:void 0;for(c.set(n,e),c.set(e,n);++l{t.d(e,{Z:()=>i});var r=t(49811),o=t(50585);const i=function(n,e){var t=-1,i=(0,o.Z)(n)?Array(n.length):[];return(0,r.Z)(n,(function(n,r,o){i[++t]=e(n,r,o)})),i}},54193:(n,e,t)=>{t.d(e,{Z:()=>r});const r=function(n){return function(e){return null==e?void 0:e[n]}}},59548:(n,e,t)=>{t.d(e,{Z:()=>r});const r=function(n,e){return n.has(e)}},68882:(n,e,t)=>{t.d(e,{Z:()=>o});var r=t(69203);const o=function(n){return"function"==typeof n?n:r.Z}},22823:(n,e,t)=>{t.d(e,{Z:()=>f});var r=t(27771),o=t(99365),i=t(42454);var u=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g;const c=function(n){var e=(0,i.Z)(n,(function(n){return 500===t.size&&t.clear(),n})),t=e.cache;return e}((function(n){var e=[];return 46===n.charCodeAt(0)&&e.push(""),n.replace(u,(function(n,t,r,o){e.push(r?o.replace(a,"$1"):t||n)})),e}));var s=t(50751);const f=function(n,e){return(0,r.Z)(n)?n:(0,o.Z)(n,e)?[n]:c((0,s.Z)(n))}},1808:(n,e,t)=>{t.d(e,{Z:()=>u});var r=t(63327),o=t(95695),i=t(17179);const u=function(n){return(0,r.Z)(n,i.Z,o.Z)}},95695:(n,e,t)=>{t.d(e,{Z:()=>a});var r=t(68774),o=t(60532),i=Object.prototype.propertyIsEnumerable,u=Object.getOwnPropertySymbols;const a=u?function(n){return null==n?[]:(n=Object(n),(0,r.Z)(u(n),(function(e){return i.call(n,e)})))}:o.Z},16174:(n,e,t)=>{t.d(e,{Z:()=>s});var r=t(22823),o=t(29169),i=t(27771),u=t(56009),a=t(1656),c=t(62281);const s=function(n,e,t){for(var s=-1,f=(e=(0,r.Z)(e,n)).length,d=!1;++s{t.d(e,{Z:()=>a});var r=t(27771),o=t(72714),i=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,u=/^\w*$/;const a=function(n,e){if((0,r.Z)(n))return!1;var t=typeof n;return!("number"!=t&&"symbol"!=t&&"boolean"!=t&&null!=n&&!(0,o.Z)(n))||(u.test(n)||!i.test(n)||null!=e&&n in Object(e))}},6545:(n,e,t)=>{t.d(e,{Z:()=>r});const r=function(n){var e=-1,t=Array(n.size);return n.forEach((function(n){t[++e]=n})),t}},62281:(n,e,t)=>{t.d(e,{Z:()=>o});var r=t(72714);const o=function(n){if("string"==typeof n||(0,r.Z)(n))return n;var e=n+"";return"0"==e&&1/n==-Infinity?"-0":e}},3688:(n,e,t)=>{t.d(e,{Z:()=>s});var r=t(69581),o=t(79651),i=t(50439),u=t(32957),a=Object.prototype,c=a.hasOwnProperty;const s=(0,r.Z)((function(n,e){n=Object(n);var t=-1,r=e.length,s=r>2?e[2]:void 0;for(s&&(0,i.Z)(e[0],e[1],s)&&(r=1);++t{t.d(e,{Z:()=>c});var r=t(68774),o=t(49811);const i=function(n,e){var t=[];return(0,o.Z)(n,(function(n,r,o){e(n,r,o)&&t.push(n)})),t};var u=t(74765),a=t(27771);const c=function(n,e){return((0,a.Z)(n)?r.Z:i)(n,(0,u.Z)(e,3))}},27961:(n,e,t)=>{t.d(e,{Z:()=>o});var r=t(10626);const o=function(n){return(null==n?0:n.length)?(0,r.Z)(n,1):[]}},70870:(n,e,t)=>{t.d(e,{Z:()=>a});var r=t(76579),o=t(49811),i=t(68882),u=t(27771);const a=function(n,e){return((0,u.Z)(n)?r.Z:o.Z)(n,(0,i.Z)(e))}},17452:(n,e,t)=>{t.d(e,{Z:()=>u});var r=Object.prototype.hasOwnProperty;const o=function(n,e){return null!=n&&r.call(n,e)};var i=t(16174);const u=function(n,e){return null!=n&&(0,i.Z)(n,e,o)}},75487:(n,e,t)=>{t.d(e,{Z:()=>i});const r=function(n,e){return null!=n&&e in Object(n)};var o=t(16174);const i=function(n,e){return null!=n&&(0,o.Z)(n,e,r)}},72714:(n,e,t)=>{t.d(e,{Z:()=>i});var r=t(93589),o=t(18533);const i=function(n){return"symbol"==typeof n||(0,o.Z)(n)&&"[object Symbol]"==(0,r.Z)(n)}},49360:(n,e,t)=>{t.d(e,{Z:()=>r});const r=function(n){return void 0===n}},17179:(n,e,t)=>{t.d(e,{Z:()=>u});var r=t(87668),o=t(39473),i=t(50585);const u=function(n){return(0,i.Z)(n)?(0,r.Z)(n):(0,o.Z)(n)}},43836:(n,e,t)=>{t.d(e,{Z:()=>a});var r=t(74073),o=t(74765),i=t(21018),u=t(27771);const a=function(n,e){return((0,u.Z)(n)?r.Z:i.Z)(n,(0,o.Z)(e,3))}},61666:(n,e,t)=>{t.d(e,{Z:()=>g});var r=t(13317),o=t(72954),i=t(22823),u=t(56009),a=t(77226),c=t(62281);const s=function(n,e,t,r){if(!(0,a.Z)(n))return n;for(var s=-1,f=(e=(0,i.Z)(e,n)).length,d=f-1,h=n;null!=h&&++s{t.d(e,{Z:()=>c});var r=Math.ceil,o=Math.max;const i=function(n,e,t,i){for(var u=-1,a=o(r((e-n)/(t||1)),0),c=Array(a);a--;)c[i?a:++u]=n,n+=t;return c};var u=t(50439),a=t(94099);const c=function(n){return function(e,t,r){return r&&"number"!=typeof r&&(0,u.Z)(e,t,r)&&(t=r=void 0),e=(0,a.Z)(e),void 0===t?(t=e,e=0):t=(0,a.Z)(t),r=void 0===r?e{t.d(e,{Z:()=>c});const r=function(n,e,t,r){var o=-1,i=null==n?0:n.length;for(r&&i&&(t=n[++o]);++o{t.d(e,{Z:()=>r});const r=function(){return[]}},94099:(n,e,t)=>{t.d(e,{Z:()=>Z});var r=/\s/;const o=function(n){for(var e=n.length;e--&&r.test(n.charAt(e)););return e};var i=/^\s+/;const u=function(n){return n?n.slice(0,o(n)+1).replace(i,""):n};var a=t(77226),c=t(72714),s=/^[-+]0x[0-9a-f]+$/i,f=/^0b[01]+$/i,d=/^0o[0-7]+$/i,h=parseInt;const v=function(n){if("number"==typeof n)return n;if((0,c.Z)(n))return NaN;if((0,a.Z)(n)){var e="function"==typeof n.valueOf?n.valueOf():n;n=(0,a.Z)(e)?e+"":e}if("string"!=typeof n)return 0===n?n:+n;n=u(n);var t=f.test(n);return t||d.test(n)?h(n.slice(2),t?2:8):s.test(n)?NaN:+n};var l=1/0;const Z=function(n){return n?(n=v(n))===l||n===-1/0?17976931348623157e292*(n<0?-1:1):n==n?n:0:0===n?n:0}},50751:(n,e,t)=>{t.d(e,{Z:()=>f});var r=t(17685),o=t(74073),i=t(27771),u=t(72714),a=r.Z?r.Z.prototype:void 0,c=a?a.toString:void 0;const s=function n(e){if("string"==typeof e)return e;if((0,i.Z)(e))return(0,o.Z)(e,n)+"";if((0,u.Z)(e))return c?c.call(e):"";var t=e+"";return"0"==t&&1/e==-Infinity?"-0":t};const f=function(n){return null==n?"":s(n)}},66749:(n,e,t)=>{t.d(e,{Z:()=>i});var r=t(50751),o=0;const i=function(n){var e=++o;return(0,r.Z)(n)+e}},34148:(n,e,t)=>{t.d(e,{Z:()=>u});var r=t(74073);const o=function(n,e){return(0,r.Z)(e,(function(e){return n[e]}))};var i=t(17179);const u=function(n){return null==n?[]:o(n,(0,i.Z)(n))}}}]); \ No newline at end of file diff --git a/assets/js/1664646a.a30b9a81.js b/assets/js/1664646a.a30b9a81.js deleted file mode 100644 index f26b273d8..000000000 --- a/assets/js/1664646a.a30b9a81.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8036],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>v});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),u=c(r),v=a,d=u["".concat(i,".").concat(v)]||u[v]||m[v]||l;return r?n.createElement(d,o(o({ref:t},s),{},{components:r})):n.createElement(d,o({ref:t},s))}));function v(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=u;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:a,o[1]=p;for(var c=2;c{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",slug:"web-application-evolution",tags:["web application"]},o=void 0,p={permalink:"/web-application-evolution",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",source:"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",description:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",date:"2023-09-30T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 30\uc77c",tags:[{label:"web application",permalink:"/tags/web-application"}],readingTime:7.5,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",slug:"web-application-evolution",tags:["web application"]},prevItem:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",permalink:"/spring-test-isolation"},nextItem:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",permalink:"/log-async-exception"}},i={authorsImageUrls:[]},c=[{value:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",level:3},{value:"WWW(1989)",id:"www1989",level:3},{value:"CGI(1993)",id:"cgi1993",level:3},{value:"Servlet(1996)",id:"servlet1996",level:3},{value:"JSP(1999)",id:"jsp1999",level:3},{value:"MVC(2000)",id:"mvc2000",level:3},{value:"Spring Framework(2003)",id:"spring-framework2003",level:3},{value:"WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)",id:"webflux-\uc774\uc804-servlet-302009-312013",level:3},{value:"Spring WebFlux(2017)",id:"spring-webflux2017",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:c};function m(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815"},"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815"),(0,a.kt)("p",null,"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6d0\ub798 \ud68c\uace0\uc5d0 \uc791\uc131\ud558\ub824\uace0 \ud588\uc9c0\ub9cc, \uc815\ub9ac\ud558\ub2e4 \ubcf4\ub2c8 \uc870\uae08 \uae38\uc5b4\uc838\uc11c \ub530\ub85c \ubd84\ub9ac\ud588\ub2e4. "),(0,a.kt)("mermaid",{value:"graph LR\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking"}),(0,a.kt)("h3",{id:"www1989"},"WWW(1989)"),(0,a.kt)("p",null,"\uc815\uc801 \ud398\uc774\uc9c0\ub97c \uc81c\uacf5\ud558\ub294 \uc6f9 \uc11c\ubc84\ub97c \uc2dc\uc791\uc73c\ub85c \ub3d9\uc801 \ud398\uc774\uc9c0\uac00 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 CGI\uac00 \ub4f1\uc7a5\ud588\ub2e4. "),(0,a.kt)("h3",{id:"cgi1993"},"CGI(1993)"),(0,a.kt)("p",null,"CGI\ub294 \ub3d9\uc801 \ucf58\ud150\uce20\ub97c \uc81c\uacf5\ud558\uae30 \uc704\ud55c \uaddc\uc57d\uc73c\ub85c, \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc774\uc6a9\ud574\uc11c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ucf1c \uc815\ubcf4\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ub9ce\uc740 \ubd80\ud558\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc774\ub7ec\ud55c \ub2e8\uc810\uc744 \uadf9\ubcf5\ud558\uae30 \uc704\ud574 \ub098\uc628 \uac83\uc774 Servlet\uc774\ub2e4. "),(0,a.kt)("h3",{id:"servlet1996"},"Servlet(1996)"),(0,a.kt)("p",null,"Servlet\uc740 \uc6f9 \uc11c\ubc84\uc5d0\uc11c \uc2e4\ud589\ub418\ub294 \uc790\ubc14 \ud504\ub85c\uadf8\ub7a8\uc73c\ub85c HTTP\ub97c \uc774\uc6a9\ud558\uc5ec \uc6f9 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc744 \uc218\uc2e0\ud558\uace0 \uc751\ub2f5\ud55c\ub2e4. CGI\uc640 \ub2e4\ub974\uac8c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\uac00 \uc544\ub2cc \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uc5ec \uc751\ub2f5\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc View \uc601\uc5ed\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uae30 \uc704\ud574 Servlet\uc758 \uc18c\uc2a4 \ucf54\ub4dc\ub97c \uc54c\uc544\uc57c \ud558\ub294 \ub4f1 \ubcf5\uc7a1\ub3c4\uac00 \ub108\ubb34 \ub192\uc558\ub2e4. \ub530\ub77c\uc11c \ud574\ub2f9 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 JSP\uac00 \ub4f1\uc7a5\ud588\ub2e4. "),(0,a.kt)("h3",{id:"jsp1999"},"JSP(1999)"),(0,a.kt)("p",null,"JSP\ub294 HTML\uc5d0 \uc790\ubc14 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ub3d9\uc801 \uc6f9 \ud398\uc774\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\uc220\ub85c, \uc720\uc0ac\ud55c \uae30\uc220\ub85c\ub294 ASP, PHP\uac00 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","JSP\ub9cc \uc0ac\uc6a9\ud558\uc5ec \ud504\ub85c\uadf8\ub798\ubc0d\ud55c\ub2e4\uba74 Model 1, \uc544\ub798 \uad6c\uc131\ub3c4\uc640 \uac19\uc774 JSP\uac00 View \uc601\uc5ed\ub9cc \ub2f4\ub2f9\ud55c\ub2e4\uba74 Model 2\ub77c\uace0 \ud55c\ub2e4. "),(0,a.kt)("mermaid",{value:"---\ntitle: JSP Model 2\n---\ngraph LR\n Client -- Request --\x3e Servlet <-- JDBC --\x3e Database\n\tServlet --\x3e Bean\n\tServlet --\x3e JSP\n\tBean <--\x3e JSP\n\tJSP -- Response --\x3e Client"}),(0,a.kt)("h3",{id:"mvc2000"},"MVC(2000)"),(0,a.kt)("p",null,"\uc704 JSP\uc758 \uad6c\uc131\ub3c4\ub97c \ubcf4\uba74 \ud604\uc7ac MVC\uc640 \ub9e4\uc6b0 \uc720\uc0ac\ud55c\ub370, Govind Seshadri\ub77c\ub294 \uc0ac\ub78c\uc774 JSP Model 2\ub97c MVC \ud328\ud134\uc73c\ub85c \uacf5\uc2dd\ud654\ub97c \uc81c\uc548\ud588\ub2e4. "),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.",(0,a.kt)("br",{parentName:"p"}),"\n","Govind Seshadri")),(0,a.kt)("p",null,"\uc774\ub54c MVC \ud328\ud134\uc774 \ucc98\uc74c \ud0c4\uc0dd\ud55c \uac83\uc740 \uc544\ub2c8\uace0, \uc11c\ubc84 \uce21 \uad6c\ud604\uc774\ub77c\uace0 \ud558\ub294 \uac83\uc744 \ubcf4\ub2c8 MVC\uac00 \ucc98\uc74c \ub4f1\uc7a5\ud55c \uac74 \uc544\ub2cc \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html"},"\ud574\ub2f9 \ubb38\uc11c"),"\ub97c \ubcf4\uba74 MVC\ub77c\ub294 \uc6a9\uc5b4\uc758 \ub4f1\uc7a5\uc740 1978\ub144\uc5d0 \ub4f1\uc7a5\ud55c \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4. "),(0,a.kt)("h3",{id:"spring-framework2003"},"Spring Framework(2003)"),(0,a.kt)("p",null,"Spring\uc740 \ubcf5\uc7a1\ud588\ub358 J2EE\uc744 \ub300\uccb4\ud558\uae30 \uc704\ud574 2003\ub144\uc5d0 \ub4f1\uc7a5\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","J2EE\ub294 \uc6f9 \uae30\ubc18\uc758 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\uae30 \uc704\ud55c \ud50c\ub7ab\ud3fc\uc73c\ub85c \uc704\uc5d0\uc11c \uc124\uba85\ud55c Servlet, JSP, EJB \ub4f1\uc758 \uae30\uc220\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uc774\uc911 EJB\ub77c\ub294 \uae30\uc220\uc774 J2EE\uc758 \ud575\uc2ec \uae30\uc220\uc774\uc5c8\ub294\ub370, \ud574\ub2f9 \uae30\uc220\uc774 \ub9e4\uc6b0 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub9ce\uc558\ub2e4\uace0 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","2002\ub144\uc5d0 Rod Johnson\uc774 EJB\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 J2EE \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc800\uc220\ud55c ",(0,a.kt)("inlineCode",{parentName:"p"},"Expert One-to-One J2EE Development"),"\ub77c\ub294 \ucc45\uc744 \ubc1c\ud589\ud588\uace0, \ucd9c\uac04 \ud6c4 Juergen Hoeller, Yann Caroff\uac00 Rod Johnson\uc5d0\uac8c \uc624\ud508\uc18c\uc2a4 \uc81c\uc548\uc744 \ud558\uc5ec \uc2a4\ud504\ub9c1\uc774 \ud0c4\uc0dd\ud588\ub2e4\uace0 \ud55c\ub2e4. "),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uc740 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\uba70, \uc774 \ub355\ubd84\uc5d0 \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"webflux-\uc774\uc804-servlet-302009-312013"},"WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)"),(0,a.kt)("p",null,"Tomcat\uc758 NIO \ub3d9\uc791 \ubc29\uc2dd\uc744 \ubcf4\uba74 Poller\uac00 \uc18c\ucf13 \ucee4\ub125\uc158\uc744 \ub4e4\uace0 \uc788\ub2e4\uac00 \ucc98\ub9ac\uac00 \uac00\ub2a5\ud560 \ub54c \uc2a4\ub808\ub4dc\ub97c \ud560\ub2f9\ud558\ub294 \uc2dd\uc73c\ub85c \ucc98\ub9ac\ub97c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ud560\ub2f9 \ud6c4 Servlet\uacfc \ud1b5\uc2e0\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \uc694\uccad\uc774 \ub05d\ub0a0 \ub54c\uae4c\uc9c0 \uc2a4\ub808\ub4dc\ub97c \uc810\uc720\ud558\uace0 \uc788\uc5c8\uace0, \uc2a4\ub808\ub4dc \uc810\uc720\ub85c \uc778\ud574 \uc694\uccad\uc774 max thread\uc5d0 \ub3c4\ub2ec\ud558\uba74 \uc694\uccad\uc744 \ucc98\ub9ac\ud560 \uc218 \uc5c6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub798\uc11c \ube44\ub3d9\uae30 \ubc29\uc2dd\uc758 Servlet\uc774 Servlet 3.0\uc5d0 \ub4f1\uc7a5\ud588\ub2e4. \ud558\uc9c0\ub9cc \uc804\ud1b5\uc801\uc778 I/O \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \ub3d9\uc791\ud588\ub2e4. Servlet 3.1\uc5d0\uc11c \ub17c\ube14\ub85c\ud0b9 I/O\uac00 \ucd94\uac00\ub418\uc5c8\uc9c0\ub9cc, \ub9ce\uc774 \uc0ac\uc6a9\ub418\uc9c0 \uc54a\uc558\ub2e4\uace0 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"spring-webflux2017"},"Spring WebFlux(2017)"),(0,a.kt)("p",null,"\uc801\uc740 \uc218\uc758 \uc2a4\ub808\ub4dc\ub85c \ub3d9\uc2dc\uc131\uc744 \ucc98\ub9ac\ud558\uace0, \uc801\uc740 \ub9ac\uc18c\uc2a4\ub85c \ud655\uc7a5\uc774 \uac00\ub2a5\ud55c \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd\uc758 \uc6f9 \uae30\uc220\uc774 \ud544\uc694\ud588\uace0, \uae30\uc874\uc758 Servlet\uc758 \uacbd\uc6b0 \ube44\ub3d9\uae30\ub97c \uc9c0\uc6d0\ud55c\ub2e4 \ud574\ub3c4 \ub3d9\uae30\uc2dd API\ub4e4\uc774 \ub9ce\uc774 \ub0a8\uc544\uc788\uc5c8\uae30 \ub54c\ubb38\uc5d0 \uc774\ub7ec\ud55c Servlet\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294 \uae30\uc220\uc774 \ud544\uc694\ud588\ub2e4. \ub610\ud55c \uae30\uc874\uc5d0 Netty\uc640 \uac19\uc774 \ube44\ub3d9\uae30, \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd \uc11c\ubc84\ub85c \uc790\ub9ac\ub97c \uc798 \uc7a1\uc740 \uc11c\ubc84\ub97c \uc704\ud574 Spring WebFlux\uac00 \ub4f1\uc7a5\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ub370\uc774\ud130 \uc811\uadfc\uc744 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 JDBC\uc758 \uacbd\uc6b0 Blocking API\ub77c, Spring Webflux\uc5d0\uc11c\ub294 R2DBC\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uace0 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ub9c8\uce58\uba70"},"\ub9c8\uce58\uba70"),(0,a.kt)("p",null,"\ud574\ub2f9 \uc815\ub9ac \ub0b4\uc6a9\uc758 \uacbd\uc6b0 Async, Non Blocking \uad00\ub828\ub41c \ub0b4\uc6a9\uc744 \uae4a\uac8c \uacf5\ubd80\ud55c \uc801\uc774 \uc5c6\uc5b4\uc11c \uc815\ud655\ud558\uc9c0 \uc54a\uc744 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub798\ub3c4 \uae30\uc220\uc758 \ub4f1\uc7a5 \ubc30\uacbd\uc774\ub098 \uacfc\uc815\uc744 \uc54c\uace0 \uc788\ub2e4\uba74 \uc870\uae08 \ub354 \uae4a\uc774 \uc788\ub294 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815, \uad6c\uad6c \uac15\uc758",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://httpd.apache.org/docs/trunk/en/howto/cgi.html"},"Dynamic Content with CGI, Apache Tutorial"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/reference/overview.html#overview-history"},"History of Spring and the Spring Framework, Spring"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.infoworld.com/article/2076557/understanding-javaserver-pages-model-2-architecture.html"},"Understanding JavaServer Pages Model 2 architecture, Govind Seshadri"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html"},"MVC, XEROX PARC"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.amazon.com/Expert-One-One-Development-without/dp/0764558315"},"Expert One-to-One J2EE Development, Rod Johnson"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/2667/"},"\ubc30\ub2ec\uc758\ubbfc\uc871 \ucd5c\uc804\ubc29 \uc2dc\uc2a4\ud15c! \u2018\uac00\uac8c\ub178\ucd9c \uc2dc\uc2a4\ud15c\u2019\uc744 \uc18c\uac1c\ud569\ub2c8\ub2e4, \ubc30\ub2ec\uc758\ubbfc\uc871"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.infoworld.com/article/2077995/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html"},"Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu"),"\n",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/reference/web/webflux/new-framework.html"},"WebFlux Overview, Spring"),"\n",(0,a.kt)("a",{parentName:"p",href:"https://d2.naver.com/helloworld/6080222"},"Spring WebFlux\uc640 Armeria\ub97c \uc774\uc6a9\ud558\uc5ec Microservice\uc5d0 \ud544\uc694\ud55c Reactive + RPC \ub3d9\uc2dc\uc5d0 \uc7a1\uae30, Naver D2"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://tweety1121.tistory.com/entry/Spring-WebFlux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C"},"Spring WebFlux\ub780 \ubb34\uc5c7\uc77c\uae4c")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1664646a.eba2ca7c.js b/assets/js/1664646a.eba2ca7c.js new file mode 100644 index 000000000..069eaa5c8 --- /dev/null +++ b/assets/js/1664646a.eba2ca7c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8036],{60367:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>d,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var t=n(85893),i=n(3905);const l={title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",slug:"web-application-evolution",tags:["web application"]},o=void 0,s={permalink:"/web-application-evolution",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",source:"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",description:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",date:"2023-09-30T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 30\uc77c",tags:[{label:"web application",permalink:"/tags/web-application"}],readingTime:7.5,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",slug:"web-application-evolution",tags:["web application"]},unlisted:!1,prevItem:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",permalink:"/spring-test-isolation"},nextItem:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",permalink:"/log-async-exception"}},a={authorsImageUrls:[]},c=[{value:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",level:3},{value:"WWW(1989)",id:"www1989",level:3},{value:"CGI(1993)",id:"cgi1993",level:3},{value:"Servlet(1996)",id:"servlet1996",level:3},{value:"JSP(1999)",id:"jsp1999",level:3},{value:"MVC(2000)",id:"mvc2000",level:3},{value:"Spring Framework(2003)",id:"spring-framework2003",level:3},{value:"WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)",id:"webflux-\uc774\uc804-servlet-302009-312013",level:3},{value:"Spring WebFlux(2017)",id:"spring-webflux2017",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const r={a:"a",blockquote:"blockquote",br:"br",code:"code",h3:"h3",mermaid:"mermaid",p:"p",...(0,i.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h3,{id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",children:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815"}),"\n",(0,t.jsxs)(r.p,{children:["\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6d0\ub798 \ud68c\uace0\uc5d0 \uc791\uc131\ud558\ub824\uace0 \ud588\uc9c0\ub9cc, \uc815\ub9ac\ud558\ub2e4 \ubcf4\ub2c8 \uc870\uae08 \uae38\uc5b4\uc838\uc11c \ub530\ub85c \ubd84\ub9ac\ud588\ub2e4."]}),"\n",(0,t.jsx)(r.mermaid,{value:"graph LR\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking"}),"\n",(0,t.jsx)(r.h3,{id:"www1989",children:"WWW(1989)"}),"\n",(0,t.jsx)(r.p,{children:"\uc815\uc801 \ud398\uc774\uc9c0\ub97c \uc81c\uacf5\ud558\ub294 \uc6f9 \uc11c\ubc84\ub97c \uc2dc\uc791\uc73c\ub85c \ub3d9\uc801 \ud398\uc774\uc9c0\uac00 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 CGI\uac00 \ub4f1\uc7a5\ud588\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"cgi1993",children:"CGI(1993)"}),"\n",(0,t.jsx)(r.p,{children:"CGI\ub294 \ub3d9\uc801 \ucf58\ud150\uce20\ub97c \uc81c\uacf5\ud558\uae30 \uc704\ud55c \uaddc\uc57d\uc73c\ub85c, \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc774\uc6a9\ud574\uc11c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ucf1c \uc815\ubcf4\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ub9ce\uc740 \ubd80\ud558\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc774\ub7ec\ud55c \ub2e8\uc810\uc744 \uadf9\ubcf5\ud558\uae30 \uc704\ud574 \ub098\uc628 \uac83\uc774 Servlet\uc774\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"servlet1996",children:"Servlet(1996)"}),"\n",(0,t.jsxs)(r.p,{children:["Servlet\uc740 \uc6f9 \uc11c\ubc84\uc5d0\uc11c \uc2e4\ud589\ub418\ub294 \uc790\ubc14 \ud504\ub85c\uadf8\ub7a8\uc73c\ub85c HTTP\ub97c \uc774\uc6a9\ud558\uc5ec \uc6f9 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc744 \uc218\uc2e0\ud558\uace0 \uc751\ub2f5\ud55c\ub2e4. CGI\uc640 \ub2e4\ub974\uac8c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\uac00 \uc544\ub2cc \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uc5ec \uc751\ub2f5\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\uc9c0\ub9cc View \uc601\uc5ed\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uae30 \uc704\ud574 Servlet\uc758 \uc18c\uc2a4 \ucf54\ub4dc\ub97c \uc54c\uc544\uc57c \ud558\ub294 \ub4f1 \ubcf5\uc7a1\ub3c4\uac00 \ub108\ubb34 \ub192\uc558\ub2e4. \ub530\ub77c\uc11c \ud574\ub2f9 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 JSP\uac00 \ub4f1\uc7a5\ud588\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"jsp1999",children:"JSP(1999)"}),"\n",(0,t.jsxs)(r.p,{children:["JSP\ub294 HTML\uc5d0 \uc790\ubc14 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ub3d9\uc801 \uc6f9 \ud398\uc774\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\uc220\ub85c, \uc720\uc0ac\ud55c \uae30\uc220\ub85c\ub294 ASP, PHP\uac00 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","JSP\ub9cc \uc0ac\uc6a9\ud558\uc5ec \ud504\ub85c\uadf8\ub798\ubc0d\ud55c\ub2e4\uba74 Model 1, \uc544\ub798 \uad6c\uc131\ub3c4\uc640 \uac19\uc774 JSP\uac00 View \uc601\uc5ed\ub9cc \ub2f4\ub2f9\ud55c\ub2e4\uba74 Model 2\ub77c\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.mermaid,{value:"---\ntitle: JSP Model 2\n---\ngraph LR\n Client -- Request --\x3e Servlet <-- JDBC --\x3e Database\n\tServlet --\x3e Bean\n\tServlet --\x3e JSP\n\tBean <--\x3e JSP\n\tJSP -- Response --\x3e Client"}),"\n",(0,t.jsx)(r.h3,{id:"mvc2000",children:"MVC(2000)"}),"\n",(0,t.jsx)(r.p,{children:"\uc704 JSP\uc758 \uad6c\uc131\ub3c4\ub97c \ubcf4\uba74 \ud604\uc7ac MVC\uc640 \ub9e4\uc6b0 \uc720\uc0ac\ud55c\ub370, Govind Seshadri\ub77c\ub294 \uc0ac\ub78c\uc774 JSP Model 2\ub97c MVC \ud328\ud134\uc73c\ub85c \uacf5\uc2dd\ud654\ub97c \uc81c\uc548\ud588\ub2e4."}),"\n",(0,t.jsxs)(r.blockquote,{children:["\n",(0,t.jsxs)(r.p,{children:["I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.",(0,t.jsx)(r.br,{}),"\n","Govind Seshadri"]}),"\n"]}),"\n",(0,t.jsxs)(r.p,{children:["\uc774\ub54c MVC \ud328\ud134\uc774 \ucc98\uc74c \ud0c4\uc0dd\ud55c \uac83\uc740 \uc544\ub2c8\uace0, \uc11c\ubc84 \uce21 \uad6c\ud604\uc774\ub77c\uace0 \ud558\ub294 \uac83\uc744 \ubcf4\ub2c8 MVC\uac00 \ucc98\uc74c \ub4f1\uc7a5\ud55c \uac74 \uc544\ub2cc \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html",children:"\ud574\ub2f9 \ubb38\uc11c"}),"\ub97c \ubcf4\uba74 MVC\ub77c\ub294 \uc6a9\uc5b4\uc758 \ub4f1\uc7a5\uc740 1978\ub144\uc5d0 \ub4f1\uc7a5\ud55c \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"spring-framework2003",children:"Spring Framework(2003)"}),"\n",(0,t.jsxs)(r.p,{children:["Spring\uc740 \ubcf5\uc7a1\ud588\ub358 J2EE\uc744 \ub300\uccb4\ud558\uae30 \uc704\ud574 2003\ub144\uc5d0 \ub4f1\uc7a5\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","J2EE\ub294 \uc6f9 \uae30\ubc18\uc758 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\uae30 \uc704\ud55c \ud50c\ub7ab\ud3fc\uc73c\ub85c \uc704\uc5d0\uc11c \uc124\uba85\ud55c Servlet, JSP, EJB \ub4f1\uc758 \uae30\uc220\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\uc9c0\ub9cc \uc774\uc911 EJB\ub77c\ub294 \uae30\uc220\uc774 J2EE\uc758 \ud575\uc2ec \uae30\uc220\uc774\uc5c8\ub294\ub370, \ud574\ub2f9 \uae30\uc220\uc774 \ub9e4\uc6b0 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub9ce\uc558\ub2e4\uace0 \ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","2002\ub144\uc5d0 Rod Johnson\uc774 EJB\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 J2EE \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc800\uc220\ud55c ",(0,t.jsx)(r.code,{children:"Expert One-to-One J2EE Development"}),"\ub77c\ub294 \ucc45\uc744 \ubc1c\ud589\ud588\uace0, \ucd9c\uac04 \ud6c4 Juergen Hoeller, Yann Caroff\uac00 Rod Johnson\uc5d0\uac8c \uc624\ud508\uc18c\uc2a4 \uc81c\uc548\uc744 \ud558\uc5ec \uc2a4\ud504\ub9c1\uc774 \ud0c4\uc0dd\ud588\ub2e4\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:"\uc2a4\ud504\ub9c1\uc740 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\uba70, \uc774 \ub355\ubd84\uc5d0 \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"webflux-\uc774\uc804-servlet-302009-312013",children:"WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)"}),"\n",(0,t.jsxs)(r.p,{children:["Tomcat\uc758 NIO \ub3d9\uc791 \ubc29\uc2dd\uc744 \ubcf4\uba74 Poller\uac00 \uc18c\ucf13 \ucee4\ub125\uc158\uc744 \ub4e4\uace0 \uc788\ub2e4\uac00 \ucc98\ub9ac\uac00 \uac00\ub2a5\ud560 \ub54c \uc2a4\ub808\ub4dc\ub97c \ud560\ub2f9\ud558\ub294 \uc2dd\uc73c\ub85c \ucc98\ub9ac\ub97c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ud560\ub2f9 \ud6c4 Servlet\uacfc \ud1b5\uc2e0\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \uc694\uccad\uc774 \ub05d\ub0a0 \ub54c\uae4c\uc9c0 \uc2a4\ub808\ub4dc\ub97c \uc810\uc720\ud558\uace0 \uc788\uc5c8\uace0, \uc2a4\ub808\ub4dc \uc810\uc720\ub85c \uc778\ud574 \uc694\uccad\uc774 max thread\uc5d0 \ub3c4\ub2ec\ud558\uba74 \uc694\uccad\uc744 \ucc98\ub9ac\ud560 \uc218 \uc5c6\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uadf8\ub798\uc11c \ube44\ub3d9\uae30 \ubc29\uc2dd\uc758 Servlet\uc774 Servlet 3.0\uc5d0 \ub4f1\uc7a5\ud588\ub2e4. \ud558\uc9c0\ub9cc \uc804\ud1b5\uc801\uc778 I/O \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \ub3d9\uc791\ud588\ub2e4. Servlet 3.1\uc5d0\uc11c \ub17c\ube14\ub85c\ud0b9 I/O\uac00 \ucd94\uac00\ub418\uc5c8\uc9c0\ub9cc, \ub9ce\uc774 \uc0ac\uc6a9\ub418\uc9c0 \uc54a\uc558\ub2e4\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"spring-webflux2017",children:"Spring WebFlux(2017)"}),"\n",(0,t.jsxs)(r.p,{children:["\uc801\uc740 \uc218\uc758 \uc2a4\ub808\ub4dc\ub85c \ub3d9\uc2dc\uc131\uc744 \ucc98\ub9ac\ud558\uace0, \uc801\uc740 \ub9ac\uc18c\uc2a4\ub85c \ud655\uc7a5\uc774 \uac00\ub2a5\ud55c \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd\uc758 \uc6f9 \uae30\uc220\uc774 \ud544\uc694\ud588\uace0, \uae30\uc874\uc758 Servlet\uc758 \uacbd\uc6b0 \ube44\ub3d9\uae30\ub97c \uc9c0\uc6d0\ud55c\ub2e4 \ud574\ub3c4 \ub3d9\uae30\uc2dd API\ub4e4\uc774 \ub9ce\uc774 \ub0a8\uc544\uc788\uc5c8\uae30 \ub54c\ubb38\uc5d0 \uc774\ub7ec\ud55c Servlet\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294 \uae30\uc220\uc774 \ud544\uc694\ud588\ub2e4. \ub610\ud55c \uae30\uc874\uc5d0 Netty\uc640 \uac19\uc774 \ube44\ub3d9\uae30, \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd \uc11c\ubc84\ub85c \uc790\ub9ac\ub97c \uc798 \uc7a1\uc740 \uc11c\ubc84\ub97c \uc704\ud574 Spring WebFlux\uac00 \ub4f1\uc7a5\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucd94\uac00\ub85c \ub370\uc774\ud130 \uc811\uadfc\uc744 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 JDBC\uc758 \uacbd\uc6b0 Blocking API\ub77c, Spring Webflux\uc5d0\uc11c\ub294 R2DBC\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ub9c8\uce58\uba70",children:"\ub9c8\uce58\uba70"}),"\n",(0,t.jsxs)(r.p,{children:["\ud574\ub2f9 \uc815\ub9ac \ub0b4\uc6a9\uc758 \uacbd\uc6b0 Async, Non Blocking \uad00\ub828\ub41c \ub0b4\uc6a9\uc744 \uae4a\uac8c \uacf5\ubd80\ud55c \uc801\uc774 \uc5c6\uc5b4\uc11c \uc815\ud655\ud558\uc9c0 \uc54a\uc744 \uc218 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uadf8\ub798\ub3c4 \uae30\uc220\uc758 \ub4f1\uc7a5 \ubc30\uacbd\uc774\ub098 \uacfc\uc815\uc744 \uc54c\uace0 \uc788\ub2e4\uba74 \uc870\uae08 \ub354 \uae4a\uc774 \uc788\ub294 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(r.p,{children:["\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815, \uad6c\uad6c \uac15\uc758",(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://httpd.apache.org/docs/trunk/en/howto/cgi.html",children:"Dynamic Content with CGI, Apache Tutorial"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://docs.spring.io/spring-framework/reference/overview.html#overview-history",children:"History of Spring and the Spring Framework, Spring"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://www.infoworld.com/article/2076557/understanding-javaserver-pages-model-2-architecture.html",children:"Understanding JavaServer Pages Model 2 architecture, Govind Seshadri"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html",children:"MVC, XEROX PARC"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://www.amazon.com/Expert-One-One-Development-without/dp/0764558315",children:"Expert One-to-One J2EE Development, Rod Johnson"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://techblog.woowahan.com/2667/",children:"\ubc30\ub2ec\uc758\ubbfc\uc871 \ucd5c\uc804\ubc29 \uc2dc\uc2a4\ud15c! \u2018\uac00\uac8c\ub178\ucd9c \uc2dc\uc2a4\ud15c\u2019\uc744 \uc18c\uac1c\ud569\ub2c8\ub2e4, \ubc30\ub2ec\uc758\ubbfc\uc871"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://www.infoworld.com/article/2077995/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html",children:"Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu"}),"\n",(0,t.jsx)(r.a,{href:"https://docs.spring.io/spring-framework/reference/web/webflux/new-framework.html",children:"WebFlux Overview, Spring"}),"\n",(0,t.jsx)(r.a,{href:"https://d2.naver.com/helloworld/6080222",children:"Spring WebFlux\uc640 Armeria\ub97c \uc774\uc6a9\ud558\uc5ec Microservice\uc5d0 \ud544\uc694\ud55c Reactive + RPC \ub3d9\uc2dc\uc5d0 \uc7a1\uae30, Naver D2"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://tweety1121.tistory.com/entry/Spring-WebFlux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C",children:"Spring WebFlux\ub780 \ubb34\uc5c7\uc77c\uae4c"})]})]})}function d(e={}){const{wrapper:r}={...(0,i.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>c});var t=n(67294);function i(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function l(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var r=1;r=0||(i[n]=e[n]);return i}(e,r);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var a=t.createContext({}),c=function(e){var r=t.useContext(a),n=r;return e&&(n="function"==typeof e?e(r):o(o({},r),e)),n},p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},d=t.forwardRef((function(e,r){var n=e.components,i=e.mdxType,l=e.originalType,a=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),h=c(n),u=i,x=h["".concat(a,".").concat(u)]||h[u]||p[u]||l;return n?t.createElement(x,o(o({ref:r},d),{},{components:n})):t.createElement(x,o({ref:r},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/1688.375d0e2c.js b/assets/js/1688.375d0e2c.js new file mode 100644 index 000000000..ba320b19b --- /dev/null +++ b/assets/js/1688.375d0e2c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1688],{11688:(e,t,l)=>{l.d(t,{diagram:()=>f});var n=l(82127),a=l(64218),o=l(45625),i=l(56363),s=l(90360);l(27484),l(17967),l(27856),l(41644),l(39354);const d=e=>i.e.sanitizeText(e,(0,i.c)());let r={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const c=function(e,t,l,n,a){const o=Object.keys(e);i.l.info("keys:",o),i.l.info(e),o.filter((t=>e[t].parent==a)).forEach((function(l){var o,s;const r=e[l],c=r.cssClasses.join(" "),p="",b="",f=r.label??r.id,u={labelStyle:p,shape:"class_box",labelText:d(f),classData:r,rx:0,ry:0,class:c,style:b,id:r.id,domId:r.domId,tooltip:n.db.getTooltip(r.id,a)||"",haveCallback:r.haveCallback,link:r.link,width:"group"===r.type?500:void 0,type:r.type,padding:(null==(o=(0,i.c)().flowchart)?void 0:o.padding)??(null==(s=(0,i.c)().class)?void 0:s.padding)};t.setNode(r.id,u),a&&t.setParent(r.id,a),i.l.info("setNode",u)}))};function p(e){let t;switch(e){case 0:t="aggregation";break;case 1:t="extension";break;case 2:t="composition";break;case 3:t="dependency";break;case 4:t="lollipop";break;default:t="none"}return t}const b={setConf:function(e){r={...r,...e}},draw:async function(e,t,l,n){i.l.info("Drawing class - ",t);const b=(0,i.c)().flowchart??(0,i.c)().class,f=(0,i.c)().securityLevel;i.l.info("config:",b);const u=(null==b?void 0:b.nodeSpacing)??50,y=(null==b?void 0:b.rankSpacing)??50,g=new o.k({multigraph:!0,compound:!0}).setGraph({rankdir:n.db.getDirection(),nodesep:u,ranksep:y,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),h=n.db.getNamespaces(),v=n.db.getClasses(),w=n.db.getRelations(),k=n.db.getNotes();let m;i.l.info(w),function(e,t,l,n){const a=Object.keys(e);i.l.info("keys:",a),i.l.info(e),a.forEach((function(a){var o,s;const r=e[a],p={shape:"rect",id:r.id,domId:r.domId,labelText:d(r.id),labelStyle:"",style:"fill: none; stroke: black",padding:(null==(o=(0,i.c)().flowchart)?void 0:o.padding)??(null==(s=(0,i.c)().class)?void 0:s.padding)};t.setNode(r.id,p),c(r.classes,t,l,n,r.id),i.l.info("setNode",p)}))}(h,g,t,n),c(v,g,t,n),function(e,t){const l=(0,i.c)().flowchart;let n=0;e.forEach((function(e){var o;n++;const s={classes:"relation",pattern:1==e.relation.lineType?"dashed":"solid",id:"id"+n,arrowhead:"arrow_open"===e.type?"none":"normal",startLabelRight:"none"===e.relationTitle1?"":e.relationTitle1,endLabelLeft:"none"===e.relationTitle2?"":e.relationTitle2,arrowTypeStart:p(e.relation.type1),arrowTypeEnd:p(e.relation.type2),style:"fill:none",labelStyle:"",curve:(0,i.n)(null==l?void 0:l.curve,a.c_6)};if(i.l.info(s,e),void 0!==e.style){const t=(0,i.k)(e.style);s.style=t.style,s.labelStyle=t.labelStyle}e.text=e.title,void 0===e.text?void 0!==e.style&&(s.arrowheadStyle="fill: #333"):(s.arrowheadStyle="fill: #333",s.labelpos="c",(null==(o=(0,i.c)().flowchart)?void 0:o.htmlLabels)??(0,i.c)().htmlLabels?(s.labelType="html",s.label=''+e.text+""):(s.labelType="text",s.label=e.text.replace(i.e.lineBreakRegex,"\n"),void 0===e.style&&(s.style=s.style||"stroke: #333; stroke-width: 1.5px;fill:none"),s.labelStyle=s.labelStyle.replace("color:","fill:"))),t.setEdge(e.id1,e.id2,s,n)}))}(w,g),function(e,t,l,n){i.l.info(e),e.forEach((function(e,o){var s,c;const p=e,b="",f="",u=p.text,y={labelStyle:b,shape:"note",labelText:d(u),noteData:p,rx:0,ry:0,class:"",style:f,id:p.id,domId:p.id,tooltip:"",type:"note",padding:(null==(s=(0,i.c)().flowchart)?void 0:s.padding)??(null==(c=(0,i.c)().class)?void 0:c.padding)};if(t.setNode(p.id,y),i.l.info("setNode",y),!p.class||!(p.class in n))return;const g=l+o,h={id:`edgeNote${g}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:(0,i.n)(r.curve,a.c_6)};t.setEdge(p.id,p.class,h,g)}))}(k,g,w.length+1,v),"sandbox"===f&&(m=(0,a.Ys)("#i"+t));const x="sandbox"===f?(0,a.Ys)(m.nodes()[0].contentDocument.body):(0,a.Ys)("body"),T=x.select(`[id="${t}"]`),S=x.select("#"+t+" g");if(await(0,s.r)(S,g,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",t),i.u.insertTitle(T,"classTitleText",(null==b?void 0:b.titleTopMargin)??5,n.db.getDiagramTitle()),(0,i.o)(g,T,null==b?void 0:b.diagramPadding,null==b?void 0:b.useMaxWidth),!(null==b?void 0:b.htmlLabels)){const e="sandbox"===f?m.nodes()[0].contentDocument:document,l=e.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of l){const l=t.getBBox(),n=e.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("rx",0),n.setAttribute("ry",0),n.setAttribute("width",l.width),n.setAttribute("height",l.height),t.insertBefore(n,t.firstChild)}}}},f={parser:n.p,db:n.d,renderer:b,styles:n.s,init:e=>{e.class||(e.class={}),e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute,n.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/16cc6f3a.f10a7b3c.js b/assets/js/16cc6f3a.6b184b3b.js similarity index 81% rename from assets/js/16cc6f3a.f10a7b3c.js rename to assets/js/16cc6f3a.6b184b3b.js index 9f52f84ae..635fedd8c 100644 --- a/assets/js/16cc6f3a.f10a7b3c.js +++ b/assets/js/16cc6f3a.6b184b3b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[425],{12946:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[425],{12946:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/16f719ab.0a2e8f52.js b/assets/js/16f719ab.0a2e8f52.js new file mode 100644 index 000000000..8057140e9 --- /dev/null +++ b/assets/js/16f719ab.0a2e8f52.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9875],{3081:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=r(85893),s=r(3905);const i={title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",slug:"subway-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,c={permalink:"/subway-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-subway-path/pull/16",date:"2023-05-25T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 25\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.98,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",slug:"subway-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",permalink:"/composite"},nextItem:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",permalink:"/accidental-duplication"}},l={authorsImageUrls:[]},a=[{value:"\uc9c0\ud558\ucca0 \ubbf8\uc158",id:"\uc9c0\ud558\ucca0-\ubbf8\uc158",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function p(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(n.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-subway-path/pull/16",children:"https://github.com/woowacourse/jwp-subway-path/pull/16"}),(0,t.jsx)(n.br,{}),"\n","2, 3\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-subway-path/pull/126",children:"https://github.com/woowacourse/jwp-subway-path/pull/126"})]})}),"\n",(0,t.jsx)(n.h3,{id:"\uc9c0\ud558\ucca0-\ubbf8\uc158",children:"\uc9c0\ud558\ucca0 \ubbf8\uc158"}),"\n",(0,t.jsxs)(n.p,{children:["\uc810\uc810 \uc77c\uc815\uc774 \ub9ce\uc544\uc9c0\ub294 \ub290\ub08c\uc774 \ub4e4\uba74\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc9c4\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc9c0\ud558\ucca0 \ubbf8\uc158\uc740 \ubc00\ub9ac\ub791 \ud398\uc5b4\ub97c \uc9c4\ud589\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uac04\ub2e8\ud55c CRUD\ub9cc \uc788\ub358 \uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac, \uc870\uae08 \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub54c API, \ud14c\uc774\ube14, \ub3c4\uba54\uc778 \uc124\uacc4\ub97c \ud574\uc57c \ud588\ub294\ub370 \uc5b4\ub5a4 \uac83\ubd80\ud130 \ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","API\uc640 \ud14c\uc774\ube14 \uad6c\uc870\ub97c \uc6b0\ub9ac\uac00 \uc815\ud560 \uc218 \uc788\ub294 \uc0c1\ud669\uc774\uc5c8\uace0, \ub3c4\uba54\uc778 \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \ub3c4\uba54\uc778\uc744 \uba3c\uc800 \uad6c\ud604\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\ub178\uc120\uc758 \uad6c\uac04 \ucd94\uac00 \ubc0f \uc0ad\uc81c"})}),"\n",(0,t.jsx)(n.p,{children:"\ub178\uc120\uc744 \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574\uc11c \ubc00\ub9ac\uc640 \uc774\uc57c\uae30\ub97c \ub098\ub234\ub2e4."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"\uad6c\uac04\uc744 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uc804\ubd80 \uc81c\uac70\ud558\uace0 \uc804\ubd80 \ucd94\uac00\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsx)(n.li,{children:"\ubcc0\uacbd\ub41c \uc694\uc18c\ub9cc \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ubc18\uc601\ud558\ub294 \ubc29\ubc95"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\ud398\uc5b4 \uc2dc\uac04\uc774 \uc9e7\uc544\uc11c \ub354\uc6b1 \uac04\ub2e8\ud55c 1\ubc88\uc744 \uc120\ud0dd\ud588\uace0, \uc2dc\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\uc2dc\ud0a4\uae30 \uc704\ud574 \ub354 \uac04\ub2e8\ud558\uac8c \uad6c\ud604\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud558\ub294 \uac83\ub3c4 \uc88b\uc740 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\uc600\ub358 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ucd94\ud6c4 \ud398\uc5b4\uac00 \ub05d\ub098\uace0 \ub9ac\ubdf0\uc5b4\uc778 \uc11c\ube0c\uc6e8\uc774\uac00 \uc77c\ubd80\ubd84\ub9cc \ubc18\uc601\ud558\ub294 \uac83\uc73c\ub85c \uac1c\uc120\ud574 \ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4\uace0 \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ucd94\uac00 \ubc0f \uc81c\uac70\ub41c \uc694\uc18c\ub9cc \ubc18\uc601\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(n.p,{children:["\ubbf8\uc158\uc758 \ub09c\uc774\ub3c4\uac00 \uc62c\ub77c\uac04 \ub9cc\ud07c, \ud398\uc5b4 \ud560 \ub550 \ucee8\ub514\uc158 \uad00\ub9ac\ub3c4 \uc798\ud558\ub824\uace0 \ub178\ub825\ud558\uace0 \ubbf8\uc158 \ud560 \ub54c\ub3c4 \uc9d1\uc911\ud574\uc11c \uc798 \ub05d\ub0b8 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc54c\uc544\uc57c \ud558\ub294 \uac8c \ub9ce\uc544\uc9c0\uba74\uc11c \uac00\ub054 \uc870\ubc14\uc2ec\uc744 \uac00\uc9c8 \ub54c\uac00 \uc788\ub294 \uac83 \uac19\uc740\ub370, \uc870\ubc14\uc2ec\uc744 \uacbd\uacc4\ud560 \ud544\uc694\uac00 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubd80\uc871\ud55c \ubd80\ubd84\uc740 \uc778\uc815\ud558\uace0, \uc55e\uc73c\ub85c \ub098\uc544\uac00\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc694\uae08 \uc815\ucc45\uc740 \uae30\ubcf8\uc694\uae08 \uc815\ucc45, \uac70\ub9ac\ubcc4 \uc694\uae08 \uc815\ucc45, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc774 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc694\uae08\uc744 \ub354\ud558\ub294 \ubd80\ubd84\uacfc, \ud560\uc778\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5b4\uc11c \uc774 \ub458\uc744 \ubd84\ub9ac\ud560\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc, \uc774 \uc815\ub3c4 \ud06c\uae30\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c\ub294 \uc624\ud788\ub824 \ubd84\ub9ac\ud558\uc9c0 \uc54a\uace0 \ud558\ub098\ub85c \ud569\uce58\ub294 \uac8c \ub354 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ud55c \ubd84\ub9ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \uc815\ucc45\uc758 \uc21c\uc11c\uac00 \uc911\uc694\ud55c\ub370, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc744 \ub9c8\uc9c0\ub9c9\uc5d0 \ub450\uc5b4\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ucc45\uc784 \uc5f0\uc1c4 \ud328\ud134\ub3c4 \uace0\ub824\ub97c \ud588\uc9c0\ub9cc \uc870\uae08 \ub354 \uac04\uacb0\ud574 \ubcf4\uc774\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \uc120\ud0dd\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\ub3c4\uba54\uc778\uc5d0 \ud2b9\uc815 \uae30\uc220\uc758 \uc758\uc874\uc131\uc744 \ubd84\ub9ac"})}),"\n",(0,t.jsxs)(n.p,{children:["\ucc98\uc74c\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uc5d0 jgrapht \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc758\uc874\ud558\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \ub450\uc5b4\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uac00 jgrapht\uc640 \uac15\uacb0\ud569\uc774 \ub418\uc5b4\ubc84\ub838\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\uc5d0\ub294 \uacbd\ub85c \uac80\uc0c9\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0, \uc138\ubd80 \uad6c\ud604\uc740 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \uc678\ubd80\ub85c \ubd84\ub9ac\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ucd5c\ub300\ud55c \uac04\uacb0\ud558\uac8c \uad6c\ud604\ud55c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud574\ub3c4, \uc774\ub7f0 \ubd80\ubd84\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uc5b4 \uacb0\ud569\uc744 \ud53c\ud558\ub294 \uac83\uc774 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.admonition,{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134",type:"note",children:(0,t.jsxs)(n.p,{children:["\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uc778\uc218 \ud14c\uc2a4\ud2b8 \uc791\uc131"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc778\uc218 \ud14c\uc2a4\ud2b8\ub294 \uc0ac\uc6a9\uc790 \uc2a4\ud1a0\ub9ac \uc2dc\ub098\ub9ac\uc624 \uae30\ubc18 \ud14c\uc2a4\ud2b8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ube0c\ub77c\uc6b4\uc774 \ud574\uc8fc\uc2e0 \uac15\uc758 + \uc720\ud29c\ube0c\uc5d0 \uc788\ub294 \ube0c\ub77c\uc6b4\uc758 \uac15\uc758\ub97c \ubcf4\uace0 \uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0 \uc778\uc218 \ud14c\uc2a4\ud2b8\ub97c \uc801\uc6a9\ud574 \ubcf4\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba54\uc11c\ub4dc, \ubcc0\uc218\uba85\uc744 \uc804\ubd80 \ud55c\uae00\ub85c \uc791\uc131\ud588\ub294\ub370 \uc804\uccb4\uc801\uc778 \ud750\ub984\uc744 \uc54c\uae30 \ud3b8\ud558\uace0 \uc77d\uae30\ub3c4 \uc88b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\ub9ac\uace0 \uc778\uc218 \ud14c\uc2a4\ud2b8\uc5d0 \ud544\uc694\ud55c Steps\ub97c \ub9cc\ub4dc\ub294 \uacfc\uc815\uc774 \ub108\ubb34 \uc7ac\ubc0c\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:"\uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'@Nested\npublic class \ub178\uc120\uc744_\uc804\uccb4_\uc870\ud68c\ud560_\ub54c {\n\n @Test\n void \uc0c1\ud589\uc885\uc810\uc5ed_\ubd80\ud130_\ud558\ud589\uc885\uc810\uc5ed\uc73c\ub85c_\uc815\ub82c\ub41c_\uacb0\uacfc\ub97c_\ubc18\ud658\ud55c\ub2e4() {\n // given\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\ucd08\ub85d", 0);\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\uc7a0\uc2e4", "\uc7a0\uc2e4\uc0c8\ub0b4", 5);\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\uc7a0\uc2e4\uc0c8\ub0b4", "\uc885\ud569\uc6b4\ub3d9\uc7a5", \uc624\ub978\ucabd, 5);\n\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\uace0\ub3d9", 0);\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\ubd09\uc740\uc0ac", "\uc885\ud569\uc6b4\ub3d9\uc7a5", 3);\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\uc885\ud569\uc6b4\ub3d9\uc7a5", "\uc0bc\uc804", \uc624\ub978\ucabd, 7);\n\n // when\n final var \uc870\ud68c_\uacb0\uacfc = \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uc694\uccad();\n\n // then\n \uc694\uccad_\uacb0\uacfc\uc758_\uc0c1\ud0dc\ub97c_\uac80\uc99d\ud55c\ub2e4(\uc870\ud68c_\uacb0\uacfc, \uc815\uc0c1_\uc694\uccad);\n \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uacb0\uacfc\ub97c_\ud655\uc778\ud55c\ub2e4(\n \uc870\ud68c_\uacb0\uacfc,\n \ub178\uc120_\uc815\ubcf4("2\ud638\uc120", "\ucd08\ub85d", 0, "\uc7a0\uc2e4", "\uc7a0\uc2e4\uc0c8\ub0b4", "\uc885\ud569\uc6b4\ub3d9\uc7a5"),\n \ub178\uc120_\uc815\ubcf4("9\ud638\uc120", "\uace0\ub3d9", 0, "\ubd09\uc740\uc0ac", "\uc885\ud569\uc6b4\ub3d9\uc7a5", "\uc0bc\uc804")\n );\n }\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uc758\uacac \uc870\uc728\ud558\uae30"})}),"\n",(0,t.jsxs)(n.p,{children:["\ubc00\ub9ac\uac00 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\uc11c \uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \uc9c4\ud589\uc774 \uc218\uc6d4\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc758\uc0ac\uc18c\ud1b5\uc774 \ub9e4\uc6b0 \uc798 \ub3fc\uc11c \uc88b\uc558\uace0 \ub355\ubd84\uc5d0 \uc2dc\uac04 \ub0b4\uc5d0 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574 \ubbf8\uc158\uc744 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub358 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\ud558\uae30"})}),"\n",(0,t.jsxs)(n.p,{children:["\ubc00\ub9ac\ub294 \ucf54\ub529\uc744 \uc5c4\uccad \uaf3c\uaf3c\ud558\uac8c \ud558\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubcc0\uc218\uba85, \uba54\uc11c\ub4dc\uba85\uc744 \uc911\uc694\ud558\uac8c \uc0dd\uac01\ud588\uace0, \uc88b\uc740 \ubcc0\uc218\uba85\uc744 \uc798 \uc9d3\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ud55c \ucf54\ub529\ud560 \ub54c \ub0b4\uac00 \ud3c9\uc18c\uc5d0 \uc0ac\uc6a9\ud558\ub294 \ucf54\ub529 \ucee8\ubca4\uc158\uc5d0 \ub9de\ucdb0\uc8fc\ub294 \uac83 \uac19\uc544\uc11c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud588\ub2e4!"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\ud3b8\ud55c \ubd84\uc704\uae30"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc804\uccb4\uc801\uc73c\ub85c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud558\uac8c \uc9c4\ud589\ud588\ub358 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc77c\uc815\ub3c4 \uadf8\ub807\uace0, \ud398\uc5b4 \uc9c4\ud589\ud560 \ub54c\ub3c4 \uadf8\ub807\uace0 \ud070 \ubb38\uc81c\uac00 \uc5c6\uc5c8\ub358 \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub098\ub294 \uacfc\uc5f0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c \ud3b8\ud55c \uc0ac\ub78c\uc77c\uae4c?"]})]})}function h(e={}){const{wrapper:n}={...(0,s.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function s(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n=0||(s[r]=e[r]);return s}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var l=t.createContext({}),a=function(e){var n=t.useContext(l),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},h=t.forwardRef((function(e,n){var r=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,h=c(e,["components","mdxType","originalType","parentName"]),j=a(r),d=s,u=j["".concat(l,".").concat(d)]||j[d]||p[d]||i;return r?t.createElement(u,o(o({ref:n},h),{},{components:r})):t.createElement(u,o({ref:n},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/16f719ab.a33933ef.js b/assets/js/16f719ab.a33933ef.js deleted file mode 100644 index c52e0bd66..000000000 --- a/assets/js/16f719ab.a33933ef.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9875],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>k});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=u(n),k=a,b=m["".concat(i,".").concat(k)]||m[k]||s[k]||p;return n?r.createElement(b,o(o({ref:t},c),{},{components:n})):r.createElement(b,o({ref:t},c))}));function k(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=n.length,o=new Array(p);o[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>s,frontMatter:()=>p,metadata:()=>l,toc:()=>u});var r=n(87462),a=(n(67294),n(3905));const p={title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",slug:"subway-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,l={permalink:"/subway-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-subway-path/pull/16",date:"2023-05-25T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 25\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.98,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",slug:"subway-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",permalink:"/composite"},nextItem:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",permalink:"/accidental-duplication"}},i={authorsImageUrls:[]},u=[{value:"\uc9c0\ud558\ucca0 \ubbf8\uc158",id:"\uc9c0\ud558\ucca0-\ubbf8\uc158",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],c={toc:u};function s(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-subway-path/pull/16"},"https://github.com/woowacourse/jwp-subway-path/pull/16"),(0,a.kt)("br",{parentName:"p"}),"\n","2, 3\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-subway-path/pull/126"},"https://github.com/woowacourse/jwp-subway-path/pull/126")," ")),(0,a.kt)("h3",{id:"\uc9c0\ud558\ucca0-\ubbf8\uc158"},"\uc9c0\ud558\ucca0 \ubbf8\uc158"),(0,a.kt)("p",null,"\uc810\uc810 \uc77c\uc815\uc774 \ub9ce\uc544\uc9c0\ub294 \ub290\ub08c\uc774 \ub4e4\uba74\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c0\ud558\ucca0 \ubbf8\uc158\uc740 \ubc00\ub9ac\ub791 \ud398\uc5b4\ub97c \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud55c CRUD\ub9cc \uc788\ub358 \uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac, \uc870\uae08 \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub54c API, \ud14c\uc774\ube14, \ub3c4\uba54\uc778 \uc124\uacc4\ub97c \ud574\uc57c \ud588\ub294\ub370 \uc5b4\ub5a4 \uac83\ubd80\ud130 \ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","API\uc640 \ud14c\uc774\ube14 \uad6c\uc870\ub97c \uc6b0\ub9ac\uac00 \uc815\ud560 \uc218 \uc788\ub294 \uc0c1\ud669\uc774\uc5c8\uace0, \ub3c4\uba54\uc778 \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \ub3c4\uba54\uc778\uc744 \uba3c\uc800 \uad6c\ud604\ud588\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub178\uc120\uc758 \uad6c\uac04 \ucd94\uac00 \ubc0f \uc0ad\uc81c")),(0,a.kt)("p",null,"\ub178\uc120\uc744 \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574\uc11c \ubc00\ub9ac\uc640 \uc774\uc57c\uae30\ub97c \ub098\ub234\ub2e4."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"\uad6c\uac04\uc744 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uc804\ubd80 \uc81c\uac70\ud558\uace0 \uc804\ubd80 \ucd94\uac00\ud558\ub294 \ubc29\ubc95"),(0,a.kt)("li",{parentName:"ol"},"\ubcc0\uacbd\ub41c \uc694\uc18c\ub9cc \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ubc18\uc601\ud558\ub294 \ubc29\ubc95")),(0,a.kt)("p",null,"\ud398\uc5b4 \uc2dc\uac04\uc774 \uc9e7\uc544\uc11c \ub354\uc6b1 \uac04\ub2e8\ud55c 1\ubc88\uc744 \uc120\ud0dd\ud588\uace0, \uc2dc\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\uc2dc\ud0a4\uae30 \uc704\ud574 \ub354 \uac04\ub2e8\ud558\uac8c \uad6c\ud604\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud558\ub294 \uac83\ub3c4 \uc88b\uc740 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\uc600\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\ud6c4 \ud398\uc5b4\uac00 \ub05d\ub098\uace0 \ub9ac\ubdf0\uc5b4\uc778 \uc11c\ube0c\uc6e8\uc774\uac00 \uc77c\ubd80\ubd84\ub9cc \ubc18\uc601\ud558\ub294 \uac83\uc73c\ub85c \uac1c\uc120\ud574 \ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4\uace0 \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ucd94\uac00 \ubc0f \uc81c\uac70\ub41c \uc694\uc18c\ub9cc \ubc18\uc601\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4."),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,"\ubbf8\uc158\uc758 \ub09c\uc774\ub3c4\uac00 \uc62c\ub77c\uac04 \ub9cc\ud07c, \ud398\uc5b4 \ud560 \ub550 \ucee8\ub514\uc158 \uad00\ub9ac\ub3c4 \uc798\ud558\ub824\uace0 \ub178\ub825\ud558\uace0 \ubbf8\uc158 \ud560 \ub54c\ub3c4 \uc9d1\uc911\ud574\uc11c \uc798 \ub05d\ub0b8 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc54c\uc544\uc57c \ud558\ub294 \uac8c \ub9ce\uc544\uc9c0\uba74\uc11c \uac00\ub054 \uc870\ubc14\uc2ec\uc744 \uac00\uc9c8 \ub54c\uac00 \uc788\ub294 \uac83 \uac19\uc740\ub370, \uc870\ubc14\uc2ec\uc744 \uacbd\uacc4\ud560 \ud544\uc694\uac00 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubd80\uc871\ud55c \ubd80\ubd84\uc740 \uc778\uc815\ud558\uace0, \uc55e\uc73c\ub85c \ub098\uc544\uac00\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654")),(0,a.kt)("p",null,"\uc694\uae08 \uc815\ucc45\uc740 \uae30\ubcf8\uc694\uae08 \uc815\ucc45, \uac70\ub9ac\ubcc4 \uc694\uae08 \uc815\ucc45, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uae08\uc744 \ub354\ud558\ub294 \ubd80\ubd84\uacfc, \ud560\uc778\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5b4\uc11c \uc774 \ub458\uc744 \ubd84\ub9ac\ud560\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc, \uc774 \uc815\ub3c4 \ud06c\uae30\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c\ub294 \uc624\ud788\ub824 \ubd84\ub9ac\ud558\uc9c0 \uc54a\uace0 \ud558\ub098\ub85c \ud569\uce58\ub294 \uac8c \ub354 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ubd84\ub9ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \uc815\ucc45\uc758 \uc21c\uc11c\uac00 \uc911\uc694\ud55c\ub370, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc744 \ub9c8\uc9c0\ub9c9\uc5d0 \ub450\uc5b4\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ucc45\uc784 \uc5f0\uc1c4 \ud328\ud134\ub3c4 \uace0\ub824\ub97c \ud588\uc9c0\ub9cc \uc870\uae08 \ub354 \uac04\uacb0\ud574 \ubcf4\uc774\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \uc120\ud0dd\ud588\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub3c4\uba54\uc778\uc5d0 \ud2b9\uc815 \uae30\uc220\uc758 \uc758\uc874\uc131\uc744 \ubd84\ub9ac")),(0,a.kt)("p",null,"\ucc98\uc74c\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uc5d0 jgrapht \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc758\uc874\ud558\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \ub450\uc5b4\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uac00 jgrapht\uc640 \uac15\uacb0\ud569\uc774 \ub418\uc5b4\ubc84\ub838\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\uc5d0\ub294 \uacbd\ub85c \uac80\uc0c9\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0, \uc138\ubd80 \uad6c\ud604\uc740 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \uc678\ubd80\ub85c \ubd84\ub9ac\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\ub300\ud55c \uac04\uacb0\ud558\uac8c \uad6c\ud604\ud55c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud574\ub3c4, \uc774\ub7f0 \ubd80\ubd84\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uc5b4 \uacb0\ud569\uc744 \ud53c\ud558\ub294 \uac83\uc774 \uc88b\uc744 \uac83 \uac19\ub2e4."),(0,a.kt)("admonition",{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc778\uc218 \ud14c\uc2a4\ud2b8 \uc791\uc131")),(0,a.kt)("p",null,"\uc778\uc218 \ud14c\uc2a4\ud2b8\ub294 \uc0ac\uc6a9\uc790 \uc2a4\ud1a0\ub9ac \uc2dc\ub098\ub9ac\uc624 \uae30\ubc18 \ud14c\uc2a4\ud2b8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube0c\ub77c\uc6b4\uc774 \ud574\uc8fc\uc2e0 \uac15\uc758 + \uc720\ud29c\ube0c\uc5d0 \uc788\ub294 \ube0c\ub77c\uc6b4\uc758 \uac15\uc758\ub97c \ubcf4\uace0 \uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0 \uc778\uc218 \ud14c\uc2a4\ud2b8\ub97c \uc801\uc6a9\ud574 \ubcf4\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uba54\uc11c\ub4dc, \ubcc0\uc218\uba85\uc744 \uc804\ubd80 \ud55c\uae00\ub85c \uc791\uc131\ud588\ub294\ub370 \uc804\uccb4\uc801\uc778 \ud750\ub984\uc744 \uc54c\uae30 \ud3b8\ud558\uace0 \uc77d\uae30\ub3c4 \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub9ac\uace0 \uc778\uc218 \ud14c\uc2a4\ud2b8\uc5d0 \ud544\uc694\ud55c Steps\ub97c \ub9cc\ub4dc\ub294 \uacfc\uc815\uc774 \ub108\ubb34 \uc7ac\ubc0c\uc5c8\ub2e4."),(0,a.kt)("p",null,"\uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@Nested\npublic class \ub178\uc120\uc744_\uc804\uccb4_\uc870\ud68c\ud560_\ub54c {\n\n @Test\n void \uc0c1\ud589\uc885\uc810\uc5ed_\ubd80\ud130_\ud558\ud589\uc885\uc810\uc5ed\uc73c\ub85c_\uc815\ub82c\ub41c_\uacb0\uacfc\ub97c_\ubc18\ud658\ud55c\ub2e4() {\n // given\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\ucd08\ub85d", 0);\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\uc7a0\uc2e4", "\uc7a0\uc2e4\uc0c8\ub0b4", 5);\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\uc7a0\uc2e4\uc0c8\ub0b4", "\uc885\ud569\uc6b4\ub3d9\uc7a5", \uc624\ub978\ucabd, 5);\n\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\uace0\ub3d9", 0);\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\ubd09\uc740\uc0ac", "\uc885\ud569\uc6b4\ub3d9\uc7a5", 3);\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\uc885\ud569\uc6b4\ub3d9\uc7a5", "\uc0bc\uc804", \uc624\ub978\ucabd, 7);\n\n // when\n final var \uc870\ud68c_\uacb0\uacfc = \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uc694\uccad();\n\n // then\n \uc694\uccad_\uacb0\uacfc\uc758_\uc0c1\ud0dc\ub97c_\uac80\uc99d\ud55c\ub2e4(\uc870\ud68c_\uacb0\uacfc, \uc815\uc0c1_\uc694\uccad);\n \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uacb0\uacfc\ub97c_\ud655\uc778\ud55c\ub2e4(\n \uc870\ud68c_\uacb0\uacfc,\n \ub178\uc120_\uc815\ubcf4("2\ud638\uc120", "\ucd08\ub85d", 0, "\uc7a0\uc2e4", "\uc7a0\uc2e4\uc0c8\ub0b4", "\uc885\ud569\uc6b4\ub3d9\uc7a5"),\n \ub178\uc120_\uc815\ubcf4("9\ud638\uc120", "\uace0\ub3d9", 0, "\ubd09\uc740\uc0ac", "\uc885\ud569\uc6b4\ub3d9\uc7a5", "\uc0bc\uc804")\n );\n }\n}\n')),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc758\uacac \uc870\uc728\ud558\uae30")),(0,a.kt)("p",null,"\ubc00\ub9ac\uac00 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\uc11c \uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \uc9c4\ud589\uc774 \uc218\uc6d4\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc758\uc0ac\uc18c\ud1b5\uc774 \ub9e4\uc6b0 \uc798 \ub3fc\uc11c \uc88b\uc558\uace0 \ub355\ubd84\uc5d0 \uc2dc\uac04 \ub0b4\uc5d0 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574 \ubbf8\uc158\uc744 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub358 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\ud558\uae30")),(0,a.kt)("p",null,"\ubc00\ub9ac\ub294 \ucf54\ub529\uc744 \uc5c4\uccad \uaf3c\uaf3c\ud558\uac8c \ud558\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcc0\uc218\uba85, \uba54\uc11c\ub4dc\uba85\uc744 \uc911\uc694\ud558\uac8c \uc0dd\uac01\ud588\uace0, \uc88b\uc740 \ubcc0\uc218\uba85\uc744 \uc798 \uc9d3\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ucf54\ub529\ud560 \ub54c \ub0b4\uac00 \ud3c9\uc18c\uc5d0 \uc0ac\uc6a9\ud558\ub294 \ucf54\ub529 \ucee8\ubca4\uc158\uc5d0 \ub9de\ucdb0\uc8fc\ub294 \uac83 \uac19\uc544\uc11c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud588\ub2e4! "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud3b8\ud55c \ubd84\uc704\uae30")),(0,a.kt)("p",null,"\uc804\uccb4\uc801\uc73c\ub85c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud558\uac8c \uc9c4\ud589\ud588\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\uc815\ub3c4 \uadf8\ub807\uace0, \ud398\uc5b4 \uc9c4\ud589\ud560 \ub54c\ub3c4 \uadf8\ub807\uace0 \ud070 \ubb38\uc81c\uac00 \uc5c6\uc5c8\ub358 \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub294 \uacfc\uc5f0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c \ud3b8\ud55c \uc0ac\ub78c\uc77c\uae4c?"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1781b1c4.215572b1.js b/assets/js/1781b1c4.215572b1.js deleted file mode 100644 index 1ed187e5c..000000000 --- a/assets/js/1781b1c4.215572b1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5785],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>k});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),u=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=u(n),k=a,b=m["".concat(i,".").concat(k)]||m[k]||s[k]||p;return n?r.createElement(b,o(o({ref:t},c),{},{components:n})):r.createElement(b,o({ref:t},c))}));function k(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=n.length,o=new Array(p);o[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>s,frontMatter:()=>p,metadata:()=>l,toc:()=>u});var r=n(87462),a=(n(67294),n(3905));const p={title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",slug:"subway-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,l={permalink:"/subway-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-subway-path/pull/16",date:"2023-05-25T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 25\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.98,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",slug:"subway-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",permalink:"/composite"},nextItem:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",permalink:"/accidental-duplication"}},i={authorsImageUrls:[]},u=[{value:"\uc9c0\ud558\ucca0 \ubbf8\uc158",id:"\uc9c0\ud558\ucca0-\ubbf8\uc158",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],c={toc:u};function s(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-subway-path/pull/16"},"https://github.com/woowacourse/jwp-subway-path/pull/16"),(0,a.kt)("br",{parentName:"p"}),"\n","2, 3\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-subway-path/pull/126"},"https://github.com/woowacourse/jwp-subway-path/pull/126")," ")),(0,a.kt)("h3",{id:"\uc9c0\ud558\ucca0-\ubbf8\uc158"},"\uc9c0\ud558\ucca0 \ubbf8\uc158"),(0,a.kt)("p",null,"\uc810\uc810 \uc77c\uc815\uc774 \ub9ce\uc544\uc9c0\ub294 \ub290\ub08c\uc774 \ub4e4\uba74\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c0\ud558\ucca0 \ubbf8\uc158\uc740 \ubc00\ub9ac\ub791 \ud398\uc5b4\ub97c \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud55c CRUD\ub9cc \uc788\ub358 \uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac, \uc870\uae08 \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub54c API, \ud14c\uc774\ube14, \ub3c4\uba54\uc778 \uc124\uacc4\ub97c \ud574\uc57c \ud588\ub294\ub370 \uc5b4\ub5a4 \uac83\ubd80\ud130 \ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","API\uc640 \ud14c\uc774\ube14 \uad6c\uc870\ub97c \uc6b0\ub9ac\uac00 \uc815\ud560 \uc218 \uc788\ub294 \uc0c1\ud669\uc774\uc5c8\uace0, \ub3c4\uba54\uc778 \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \ub3c4\uba54\uc778\uc744 \uba3c\uc800 \uad6c\ud604\ud588\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub178\uc120\uc758 \uad6c\uac04 \ucd94\uac00 \ubc0f \uc0ad\uc81c")),(0,a.kt)("p",null,"\ub178\uc120\uc744 \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574\uc11c \ubc00\ub9ac\uc640 \uc774\uc57c\uae30\ub97c \ub098\ub234\ub2e4."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"\uad6c\uac04\uc744 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uc804\ubd80 \uc81c\uac70\ud558\uace0 \uc804\ubd80 \ucd94\uac00\ud558\ub294 \ubc29\ubc95"),(0,a.kt)("li",{parentName:"ol"},"\ubcc0\uacbd\ub41c \uc694\uc18c\ub9cc \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ubc18\uc601\ud558\ub294 \ubc29\ubc95")),(0,a.kt)("p",null,"\ud398\uc5b4 \uc2dc\uac04\uc774 \uc9e7\uc544\uc11c \ub354\uc6b1 \uac04\ub2e8\ud55c 1\ubc88\uc744 \uc120\ud0dd\ud588\uace0, \uc2dc\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\uc2dc\ud0a4\uae30 \uc704\ud574 \ub354 \uac04\ub2e8\ud558\uac8c \uad6c\ud604\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud558\ub294 \uac83\ub3c4 \uc88b\uc740 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\uc600\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\ud6c4 \ud398\uc5b4\uac00 \ub05d\ub098\uace0 \ub9ac\ubdf0\uc5b4\uc778 \uc11c\ube0c\uc6e8\uc774\uac00 \uc77c\ubd80\ubd84\ub9cc \ubc18\uc601\ud558\ub294 \uac83\uc73c\ub85c \uac1c\uc120\ud574 \ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4\uace0 \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ucd94\uac00 \ubc0f \uc81c\uac70\ub41c \uc694\uc18c\ub9cc \ubc18\uc601\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4."),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,"\ubbf8\uc158\uc758 \ub09c\uc774\ub3c4\uac00 \uc62c\ub77c\uac04 \ub9cc\ud07c, \ud398\uc5b4 \ud560 \ub550 \ucee8\ub514\uc158 \uad00\ub9ac\ub3c4 \uc798\ud558\ub824\uace0 \ub178\ub825\ud558\uace0 \ubbf8\uc158 \ud560 \ub54c\ub3c4 \uc9d1\uc911\ud574\uc11c \uc798 \ub05d\ub0b8 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc54c\uc544\uc57c \ud558\ub294 \uac8c \ub9ce\uc544\uc9c0\uba74\uc11c \uac00\ub054 \uc870\ubc14\uc2ec\uc744 \uac00\uc9c8 \ub54c\uac00 \uc788\ub294 \uac83 \uac19\uc740\ub370, \uc870\ubc14\uc2ec\uc744 \uacbd\uacc4\ud560 \ud544\uc694\uac00 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubd80\uc871\ud55c \ubd80\ubd84\uc740 \uc778\uc815\ud558\uace0, \uc55e\uc73c\ub85c \ub098\uc544\uac00\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654")),(0,a.kt)("p",null,"\uc694\uae08 \uc815\ucc45\uc740 \uae30\ubcf8\uc694\uae08 \uc815\ucc45, \uac70\ub9ac\ubcc4 \uc694\uae08 \uc815\ucc45, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uae08\uc744 \ub354\ud558\ub294 \ubd80\ubd84\uacfc, \ud560\uc778\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5b4\uc11c \uc774 \ub458\uc744 \ubd84\ub9ac\ud560\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc, \uc774 \uc815\ub3c4 \ud06c\uae30\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c\ub294 \uc624\ud788\ub824 \ubd84\ub9ac\ud558\uc9c0 \uc54a\uace0 \ud558\ub098\ub85c \ud569\uce58\ub294 \uac8c \ub354 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ubd84\ub9ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \uc815\ucc45\uc758 \uc21c\uc11c\uac00 \uc911\uc694\ud55c\ub370, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc744 \ub9c8\uc9c0\ub9c9\uc5d0 \ub450\uc5b4\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ucc45\uc784 \uc5f0\uc1c4 \ud328\ud134\ub3c4 \uace0\ub824\ub97c \ud588\uc9c0\ub9cc \uc870\uae08 \ub354 \uac04\uacb0\ud574 \ubcf4\uc774\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \uc120\ud0dd\ud588\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub3c4\uba54\uc778\uc5d0 \ud2b9\uc815 \uae30\uc220\uc758 \uc758\uc874\uc131\uc744 \ubd84\ub9ac")),(0,a.kt)("p",null,"\ucc98\uc74c\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uc5d0 jgrapht \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc758\uc874\ud558\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \ub450\uc5b4\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uac00 jgrapht\uc640 \uac15\uacb0\ud569\uc774 \ub418\uc5b4\ubc84\ub838\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\uc5d0\ub294 \uacbd\ub85c \uac80\uc0c9\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0, \uc138\ubd80 \uad6c\ud604\uc740 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \uc678\ubd80\ub85c \ubd84\ub9ac\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\ub300\ud55c \uac04\uacb0\ud558\uac8c \uad6c\ud604\ud55c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud574\ub3c4, \uc774\ub7f0 \ubd80\ubd84\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uc5b4 \uacb0\ud569\uc744 \ud53c\ud558\ub294 \uac83\uc774 \uc88b\uc744 \uac83 \uac19\ub2e4."),(0,a.kt)("admonition",{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc778\uc218 \ud14c\uc2a4\ud2b8 \uc791\uc131")),(0,a.kt)("p",null,"\uc778\uc218 \ud14c\uc2a4\ud2b8\ub294 \uc0ac\uc6a9\uc790 \uc2a4\ud1a0\ub9ac \uc2dc\ub098\ub9ac\uc624 \uae30\ubc18 \ud14c\uc2a4\ud2b8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube0c\ub77c\uc6b4\uc774 \ud574\uc8fc\uc2e0 \uac15\uc758 + \uc720\ud29c\ube0c\uc5d0 \uc788\ub294 \ube0c\ub77c\uc6b4\uc758 \uac15\uc758\ub97c \ubcf4\uace0 \uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0 \uc778\uc218 \ud14c\uc2a4\ud2b8\ub97c \uc801\uc6a9\ud574 \ubcf4\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uba54\uc11c\ub4dc, \ubcc0\uc218\uba85\uc744 \uc804\ubd80 \ud55c\uae00\ub85c \uc791\uc131\ud588\ub294\ub370 \uc804\uccb4\uc801\uc778 \ud750\ub984\uc744 \uc54c\uae30 \ud3b8\ud558\uace0 \uc77d\uae30\ub3c4 \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub9ac\uace0 \uc778\uc218 \ud14c\uc2a4\ud2b8\uc5d0 \ud544\uc694\ud55c Steps\ub97c \ub9cc\ub4dc\ub294 \uacfc\uc815\uc774 \ub108\ubb34 \uc7ac\ubc0c\uc5c8\ub2e4."),(0,a.kt)("p",null,"\uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@Nested\npublic class \ub178\uc120\uc744_\uc804\uccb4_\uc870\ud68c\ud560_\ub54c {\n\n @Test\n void \uc0c1\ud589\uc885\uc810\uc5ed_\ubd80\ud130_\ud558\ud589\uc885\uc810\uc5ed\uc73c\ub85c_\uc815\ub82c\ub41c_\uacb0\uacfc\ub97c_\ubc18\ud658\ud55c\ub2e4() {\n // given\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\ucd08\ub85d", 0);\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\uc7a0\uc2e4", "\uc7a0\uc2e4\uc0c8\ub0b4", 5);\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\uc7a0\uc2e4\uc0c8\ub0b4", "\uc885\ud569\uc6b4\ub3d9\uc7a5", \uc624\ub978\ucabd, 5);\n\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\uace0\ub3d9", 0);\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\ubd09\uc740\uc0ac", "\uc885\ud569\uc6b4\ub3d9\uc7a5", 3);\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\uc885\ud569\uc6b4\ub3d9\uc7a5", "\uc0bc\uc804", \uc624\ub978\ucabd, 7);\n\n // when\n final var \uc870\ud68c_\uacb0\uacfc = \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uc694\uccad();\n\n // then\n \uc694\uccad_\uacb0\uacfc\uc758_\uc0c1\ud0dc\ub97c_\uac80\uc99d\ud55c\ub2e4(\uc870\ud68c_\uacb0\uacfc, \uc815\uc0c1_\uc694\uccad);\n \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uacb0\uacfc\ub97c_\ud655\uc778\ud55c\ub2e4(\n \uc870\ud68c_\uacb0\uacfc,\n \ub178\uc120_\uc815\ubcf4("2\ud638\uc120", "\ucd08\ub85d", 0, "\uc7a0\uc2e4", "\uc7a0\uc2e4\uc0c8\ub0b4", "\uc885\ud569\uc6b4\ub3d9\uc7a5"),\n \ub178\uc120_\uc815\ubcf4("9\ud638\uc120", "\uace0\ub3d9", 0, "\ubd09\uc740\uc0ac", "\uc885\ud569\uc6b4\ub3d9\uc7a5", "\uc0bc\uc804")\n );\n }\n}\n')),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc758\uacac \uc870\uc728\ud558\uae30")),(0,a.kt)("p",null,"\ubc00\ub9ac\uac00 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\uc11c \uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \uc9c4\ud589\uc774 \uc218\uc6d4\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc758\uc0ac\uc18c\ud1b5\uc774 \ub9e4\uc6b0 \uc798 \ub3fc\uc11c \uc88b\uc558\uace0 \ub355\ubd84\uc5d0 \uc2dc\uac04 \ub0b4\uc5d0 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574 \ubbf8\uc158\uc744 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub358 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\ud558\uae30")),(0,a.kt)("p",null,"\ubc00\ub9ac\ub294 \ucf54\ub529\uc744 \uc5c4\uccad \uaf3c\uaf3c\ud558\uac8c \ud558\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcc0\uc218\uba85, \uba54\uc11c\ub4dc\uba85\uc744 \uc911\uc694\ud558\uac8c \uc0dd\uac01\ud588\uace0, \uc88b\uc740 \ubcc0\uc218\uba85\uc744 \uc798 \uc9d3\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ucf54\ub529\ud560 \ub54c \ub0b4\uac00 \ud3c9\uc18c\uc5d0 \uc0ac\uc6a9\ud558\ub294 \ucf54\ub529 \ucee8\ubca4\uc158\uc5d0 \ub9de\ucdb0\uc8fc\ub294 \uac83 \uac19\uc544\uc11c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud588\ub2e4! "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud3b8\ud55c \ubd84\uc704\uae30")),(0,a.kt)("p",null,"\uc804\uccb4\uc801\uc73c\ub85c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud558\uac8c \uc9c4\ud589\ud588\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\uc815\ub3c4 \uadf8\ub807\uace0, \ud398\uc5b4 \uc9c4\ud589\ud560 \ub54c\ub3c4 \uadf8\ub807\uace0 \ud070 \ubb38\uc81c\uac00 \uc5c6\uc5c8\ub358 \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub294 \uacfc\uc5f0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c \ud3b8\ud55c \uc0ac\ub78c\uc77c\uae4c?"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1781b1c4.511d5aa4.js b/assets/js/1781b1c4.511d5aa4.js new file mode 100644 index 000000000..da085d8cb --- /dev/null +++ b/assets/js/1781b1c4.511d5aa4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5785],{16865:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=r(85893),s=r(3905);const i={title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",slug:"subway-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,c={permalink:"/subway-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-subway-path/pull/16",date:"2023-05-25T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 25\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.98,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",slug:"subway-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",permalink:"/composite"},nextItem:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",permalink:"/accidental-duplication"}},l={authorsImageUrls:[]},a=[{value:"\uc9c0\ud558\ucca0 \ubbf8\uc158",id:"\uc9c0\ud558\ucca0-\ubbf8\uc158",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function p(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(n.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-subway-path/pull/16",children:"https://github.com/woowacourse/jwp-subway-path/pull/16"}),(0,t.jsx)(n.br,{}),"\n","2, 3\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-subway-path/pull/126",children:"https://github.com/woowacourse/jwp-subway-path/pull/126"})]})}),"\n",(0,t.jsx)(n.h3,{id:"\uc9c0\ud558\ucca0-\ubbf8\uc158",children:"\uc9c0\ud558\ucca0 \ubbf8\uc158"}),"\n",(0,t.jsxs)(n.p,{children:["\uc810\uc810 \uc77c\uc815\uc774 \ub9ce\uc544\uc9c0\ub294 \ub290\ub08c\uc774 \ub4e4\uba74\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc9c4\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc9c0\ud558\ucca0 \ubbf8\uc158\uc740 \ubc00\ub9ac\ub791 \ud398\uc5b4\ub97c \uc9c4\ud589\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uac04\ub2e8\ud55c CRUD\ub9cc \uc788\ub358 \uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac, \uc870\uae08 \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub54c API, \ud14c\uc774\ube14, \ub3c4\uba54\uc778 \uc124\uacc4\ub97c \ud574\uc57c \ud588\ub294\ub370 \uc5b4\ub5a4 \uac83\ubd80\ud130 \ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","API\uc640 \ud14c\uc774\ube14 \uad6c\uc870\ub97c \uc6b0\ub9ac\uac00 \uc815\ud560 \uc218 \uc788\ub294 \uc0c1\ud669\uc774\uc5c8\uace0, \ub3c4\uba54\uc778 \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \ub3c4\uba54\uc778\uc744 \uba3c\uc800 \uad6c\ud604\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\ub178\uc120\uc758 \uad6c\uac04 \ucd94\uac00 \ubc0f \uc0ad\uc81c"})}),"\n",(0,t.jsx)(n.p,{children:"\ub178\uc120\uc744 \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574\uc11c \ubc00\ub9ac\uc640 \uc774\uc57c\uae30\ub97c \ub098\ub234\ub2e4."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"\uad6c\uac04\uc744 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uc804\ubd80 \uc81c\uac70\ud558\uace0 \uc804\ubd80 \ucd94\uac00\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsx)(n.li,{children:"\ubcc0\uacbd\ub41c \uc694\uc18c\ub9cc \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ubc18\uc601\ud558\ub294 \ubc29\ubc95"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\ud398\uc5b4 \uc2dc\uac04\uc774 \uc9e7\uc544\uc11c \ub354\uc6b1 \uac04\ub2e8\ud55c 1\ubc88\uc744 \uc120\ud0dd\ud588\uace0, \uc2dc\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\uc2dc\ud0a4\uae30 \uc704\ud574 \ub354 \uac04\ub2e8\ud558\uac8c \uad6c\ud604\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud558\ub294 \uac83\ub3c4 \uc88b\uc740 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\uc600\ub358 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ucd94\ud6c4 \ud398\uc5b4\uac00 \ub05d\ub098\uace0 \ub9ac\ubdf0\uc5b4\uc778 \uc11c\ube0c\uc6e8\uc774\uac00 \uc77c\ubd80\ubd84\ub9cc \ubc18\uc601\ud558\ub294 \uac83\uc73c\ub85c \uac1c\uc120\ud574 \ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4\uace0 \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ucd94\uac00 \ubc0f \uc81c\uac70\ub41c \uc694\uc18c\ub9cc \ubc18\uc601\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(n.p,{children:["\ubbf8\uc158\uc758 \ub09c\uc774\ub3c4\uac00 \uc62c\ub77c\uac04 \ub9cc\ud07c, \ud398\uc5b4 \ud560 \ub550 \ucee8\ub514\uc158 \uad00\ub9ac\ub3c4 \uc798\ud558\ub824\uace0 \ub178\ub825\ud558\uace0 \ubbf8\uc158 \ud560 \ub54c\ub3c4 \uc9d1\uc911\ud574\uc11c \uc798 \ub05d\ub0b8 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc54c\uc544\uc57c \ud558\ub294 \uac8c \ub9ce\uc544\uc9c0\uba74\uc11c \uac00\ub054 \uc870\ubc14\uc2ec\uc744 \uac00\uc9c8 \ub54c\uac00 \uc788\ub294 \uac83 \uac19\uc740\ub370, \uc870\ubc14\uc2ec\uc744 \uacbd\uacc4\ud560 \ud544\uc694\uac00 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubd80\uc871\ud55c \ubd80\ubd84\uc740 \uc778\uc815\ud558\uace0, \uc55e\uc73c\ub85c \ub098\uc544\uac00\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc694\uae08 \uc815\ucc45\uc740 \uae30\ubcf8\uc694\uae08 \uc815\ucc45, \uac70\ub9ac\ubcc4 \uc694\uae08 \uc815\ucc45, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc774 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc694\uae08\uc744 \ub354\ud558\ub294 \ubd80\ubd84\uacfc, \ud560\uc778\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5b4\uc11c \uc774 \ub458\uc744 \ubd84\ub9ac\ud560\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc, \uc774 \uc815\ub3c4 \ud06c\uae30\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c\ub294 \uc624\ud788\ub824 \ubd84\ub9ac\ud558\uc9c0 \uc54a\uace0 \ud558\ub098\ub85c \ud569\uce58\ub294 \uac8c \ub354 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ud55c \ubd84\ub9ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \uc815\ucc45\uc758 \uc21c\uc11c\uac00 \uc911\uc694\ud55c\ub370, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc744 \ub9c8\uc9c0\ub9c9\uc5d0 \ub450\uc5b4\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ucc45\uc784 \uc5f0\uc1c4 \ud328\ud134\ub3c4 \uace0\ub824\ub97c \ud588\uc9c0\ub9cc \uc870\uae08 \ub354 \uac04\uacb0\ud574 \ubcf4\uc774\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \uc120\ud0dd\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\ub3c4\uba54\uc778\uc5d0 \ud2b9\uc815 \uae30\uc220\uc758 \uc758\uc874\uc131\uc744 \ubd84\ub9ac"})}),"\n",(0,t.jsxs)(n.p,{children:["\ucc98\uc74c\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uc5d0 jgrapht \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc758\uc874\ud558\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \ub450\uc5b4\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uac00 jgrapht\uc640 \uac15\uacb0\ud569\uc774 \ub418\uc5b4\ubc84\ub838\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\uc5d0\ub294 \uacbd\ub85c \uac80\uc0c9\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0, \uc138\ubd80 \uad6c\ud604\uc740 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \uc678\ubd80\ub85c \ubd84\ub9ac\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ucd5c\ub300\ud55c \uac04\uacb0\ud558\uac8c \uad6c\ud604\ud55c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud574\ub3c4, \uc774\ub7f0 \ubd80\ubd84\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uc5b4 \uacb0\ud569\uc744 \ud53c\ud558\ub294 \uac83\uc774 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.admonition,{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134",type:"note",children:(0,t.jsxs)(n.p,{children:["\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uc778\uc218 \ud14c\uc2a4\ud2b8 \uc791\uc131"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc778\uc218 \ud14c\uc2a4\ud2b8\ub294 \uc0ac\uc6a9\uc790 \uc2a4\ud1a0\ub9ac \uc2dc\ub098\ub9ac\uc624 \uae30\ubc18 \ud14c\uc2a4\ud2b8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ube0c\ub77c\uc6b4\uc774 \ud574\uc8fc\uc2e0 \uac15\uc758 + \uc720\ud29c\ube0c\uc5d0 \uc788\ub294 \ube0c\ub77c\uc6b4\uc758 \uac15\uc758\ub97c \ubcf4\uace0 \uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0 \uc778\uc218 \ud14c\uc2a4\ud2b8\ub97c \uc801\uc6a9\ud574 \ubcf4\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba54\uc11c\ub4dc, \ubcc0\uc218\uba85\uc744 \uc804\ubd80 \ud55c\uae00\ub85c \uc791\uc131\ud588\ub294\ub370 \uc804\uccb4\uc801\uc778 \ud750\ub984\uc744 \uc54c\uae30 \ud3b8\ud558\uace0 \uc77d\uae30\ub3c4 \uc88b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\ub9ac\uace0 \uc778\uc218 \ud14c\uc2a4\ud2b8\uc5d0 \ud544\uc694\ud55c Steps\ub97c \ub9cc\ub4dc\ub294 \uacfc\uc815\uc774 \ub108\ubb34 \uc7ac\ubc0c\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:"\uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'@Nested\npublic class \ub178\uc120\uc744_\uc804\uccb4_\uc870\ud68c\ud560_\ub54c {\n\n @Test\n void \uc0c1\ud589\uc885\uc810\uc5ed_\ubd80\ud130_\ud558\ud589\uc885\uc810\uc5ed\uc73c\ub85c_\uc815\ub82c\ub41c_\uacb0\uacfc\ub97c_\ubc18\ud658\ud55c\ub2e4() {\n // given\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\ucd08\ub85d", 0);\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\uc7a0\uc2e4", "\uc7a0\uc2e4\uc0c8\ub0b4", 5);\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad("2\ud638\uc120", "\uc7a0\uc2e4\uc0c8\ub0b4", "\uc885\ud569\uc6b4\ub3d9\uc7a5", \uc624\ub978\ucabd, 5);\n\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\uace0\ub3d9", 0);\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\ubd09\uc740\uc0ac", "\uc885\ud569\uc6b4\ub3d9\uc7a5", 3);\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad("9\ud638\uc120", "\uc885\ud569\uc6b4\ub3d9\uc7a5", "\uc0bc\uc804", \uc624\ub978\ucabd, 7);\n\n // when\n final var \uc870\ud68c_\uacb0\uacfc = \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uc694\uccad();\n\n // then\n \uc694\uccad_\uacb0\uacfc\uc758_\uc0c1\ud0dc\ub97c_\uac80\uc99d\ud55c\ub2e4(\uc870\ud68c_\uacb0\uacfc, \uc815\uc0c1_\uc694\uccad);\n \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uacb0\uacfc\ub97c_\ud655\uc778\ud55c\ub2e4(\n \uc870\ud68c_\uacb0\uacfc,\n \ub178\uc120_\uc815\ubcf4("2\ud638\uc120", "\ucd08\ub85d", 0, "\uc7a0\uc2e4", "\uc7a0\uc2e4\uc0c8\ub0b4", "\uc885\ud569\uc6b4\ub3d9\uc7a5"),\n \ub178\uc120_\uc815\ubcf4("9\ud638\uc120", "\uace0\ub3d9", 0, "\ubd09\uc740\uc0ac", "\uc885\ud569\uc6b4\ub3d9\uc7a5", "\uc0bc\uc804")\n );\n }\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uc758\uacac \uc870\uc728\ud558\uae30"})}),"\n",(0,t.jsxs)(n.p,{children:["\ubc00\ub9ac\uac00 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\uc11c \uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \uc9c4\ud589\uc774 \uc218\uc6d4\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc758\uc0ac\uc18c\ud1b5\uc774 \ub9e4\uc6b0 \uc798 \ub3fc\uc11c \uc88b\uc558\uace0 \ub355\ubd84\uc5d0 \uc2dc\uac04 \ub0b4\uc5d0 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574 \ubbf8\uc158\uc744 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub358 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\ud558\uae30"})}),"\n",(0,t.jsxs)(n.p,{children:["\ubc00\ub9ac\ub294 \ucf54\ub529\uc744 \uc5c4\uccad \uaf3c\uaf3c\ud558\uac8c \ud558\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubcc0\uc218\uba85, \uba54\uc11c\ub4dc\uba85\uc744 \uc911\uc694\ud558\uac8c \uc0dd\uac01\ud588\uace0, \uc88b\uc740 \ubcc0\uc218\uba85\uc744 \uc798 \uc9d3\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ud55c \ucf54\ub529\ud560 \ub54c \ub0b4\uac00 \ud3c9\uc18c\uc5d0 \uc0ac\uc6a9\ud558\ub294 \ucf54\ub529 \ucee8\ubca4\uc158\uc5d0 \ub9de\ucdb0\uc8fc\ub294 \uac83 \uac19\uc544\uc11c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud588\ub2e4!"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\ud3b8\ud55c \ubd84\uc704\uae30"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc804\uccb4\uc801\uc73c\ub85c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud558\uac8c \uc9c4\ud589\ud588\ub358 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc77c\uc815\ub3c4 \uadf8\ub807\uace0, \ud398\uc5b4 \uc9c4\ud589\ud560 \ub54c\ub3c4 \uadf8\ub807\uace0 \ud070 \ubb38\uc81c\uac00 \uc5c6\uc5c8\ub358 \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub098\ub294 \uacfc\uc5f0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c \ud3b8\ud55c \uc0ac\ub78c\uc77c\uae4c?"]})]})}function h(e={}){const{wrapper:n}={...(0,s.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function s(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n=0||(s[r]=e[r]);return s}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var l=t.createContext({}),a=function(e){var n=t.useContext(l),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},h=t.forwardRef((function(e,n){var r=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,h=c(e,["components","mdxType","originalType","parentName"]),j=a(r),d=s,u=j["".concat(l,".").concat(d)]||j[d]||p[d]||i;return r?t.createElement(u,o(o({ref:n},h),{},{components:r})):t.createElement(u,o({ref:n},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/17896441.5e6fba35.js b/assets/js/17896441.5e6fba35.js deleted file mode 100644 index 573b36b77..000000000 --- a/assets/js/17896441.5e6fba35.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7918],{78945:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>ve});var a=n(67294),l=n(10833),r=n(902);const s=a.createContext(null);function o(e){let{children:t,content:n}=e;const l=function(e){return(0,a.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return a.createElement(s.Provider,{value:l},t)}function c(){const e=(0,a.useContext)(s);if(null===e)throw new r.i6("DocProvider");return e}function i(){const{metadata:e,frontMatter:t,assets:n}=c();return a.createElement(l.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var d=n(86010),m=n(87524),u=n(87462),v=n(95999),h=n(32244);function b(e){const{previous:t,next:n}=e;return a.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,v.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"})},t&&a.createElement(h.Z,(0,u.Z)({},t,{subLabel:a.createElement(v.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc"},"Previous")})),n&&a.createElement(h.Z,(0,u.Z)({},n,{subLabel:a.createElement(v.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc"},"Next"),isNext:!0})))}function f(){const{metadata:e}=c();return a.createElement(b,{previous:e.previous,next:e.next})}var p=n(52263),E=n(39960),g=n(80143),L=n(35281),N=n(60373),k=n(74477);const _={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(v.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is unreleased documentation for {siteTitle} {versionLabel} version.")},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return a.createElement(v.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:a.createElement("b",null,n.label)}},"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained.")}};function Z(e){const t=_[e.versionMetadata.banner];return a.createElement(t,e)}function C(e){let{versionLabel:t,to:n,onClick:l}=e;return a.createElement(v.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:a.createElement("b",null,a.createElement(E.Z,{to:n,onClick:l},a.createElement(v.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label"},"latest version")))}},"For up-to-date documentation, see the {latestVersionLink} ({versionLabel}).")}function x(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:l}}=(0,p.Z)(),{pluginId:r}=(0,g.gA)({failfast:!0}),{savePreferredVersionName:s}=(0,N.J)(r),{latestDocSuggestion:o,latestVersionSuggestion:c}=(0,g.Jo)(r),i=o??(m=c).docs.find((e=>e.id===m.mainDocId));var m;return a.createElement("div",{className:(0,d.Z)(t,L.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert"},a.createElement("div",null,a.createElement(Z,{siteTitle:l,versionMetadata:n})),a.createElement("div",{className:"margin-top--md"},a.createElement(C,{versionLabel:c.label,to:i.path,onClick:()=>s(c.name)})))}function T(e){let{className:t}=e;const n=(0,k.E)();return n.banner?a.createElement(x,{className:t,versionMetadata:n}):null}function y(e){let{className:t}=e;const n=(0,k.E)();return n.badge?a.createElement("span",{className:(0,d.Z)(t,L.k.docs.docVersionBadge,"badge badge--secondary")},a.createElement(v.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label}},"Version: {versionLabel}")):null}function U(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return a.createElement(v.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:a.createElement("b",null,a.createElement("time",{dateTime:new Date(1e3*t).toISOString()},n))}}," on {date}")}function H(e){let{lastUpdatedBy:t}=e;return a.createElement(v.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:a.createElement("b",null,t)}}," by {user}")}function w(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:l}=e;return a.createElement("span",{className:L.k.common.lastUpdated},a.createElement(v.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?a.createElement(U,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:l?a.createElement(H,{lastUpdatedBy:l}):""}},"Last updated{atDate}{byUser}"),!1)}var A=n(84881),M=n(71526);const B="lastUpdated_vwxv";function I(e){return a.createElement("div",{className:(0,d.Z)(L.k.docs.docFooterTagsRow,"row margin-bottom--sm")},a.createElement("div",{className:"col"},a.createElement(M.Z,e)))}function O(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:l,formattedLastUpdatedAt:r}=e;return a.createElement("div",{className:(0,d.Z)(L.k.docs.docFooterEditMetaRow,"row")},a.createElement("div",{className:"col"},t&&a.createElement(A.Z,{editUrl:t})),a.createElement("div",{className:(0,d.Z)("col",B)},(n||l)&&a.createElement(w,{lastUpdatedAt:n,formattedLastUpdatedAt:r,lastUpdatedBy:l})))}function V(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:l,lastUpdatedBy:r,tags:s}=e,o=s.length>0,i=!!(t||n||r);return o||i?a.createElement("footer",{className:(0,d.Z)(L.k.docs.docFooter,"docusaurus-mt-lg")},o&&a.createElement(I,{tags:s}),i&&a.createElement(O,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:r,formattedLastUpdatedAt:l})):null}var D=n(86043),S=n(93743);const P="tocCollapsibleButton_TO0P",R="tocCollapsibleButtonExpanded_MG3E";function F(e){let{collapsed:t,...n}=e;return a.createElement("button",(0,u.Z)({type:"button"},n,{className:(0,d.Z)("clean-btn",P,!t&&R,n.className)}),a.createElement(v.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component"},"On this page"))}const j="tocCollapsible_ETCw",z="tocCollapsibleContent_vkbj",q="tocCollapsibleExpanded_sAul";function $(e){let{toc:t,className:n,minHeadingLevel:l,maxHeadingLevel:r}=e;const{collapsed:s,toggleCollapsed:o}=(0,D.u)({initialState:!0});return a.createElement("div",{className:(0,d.Z)(j,!s&&q,n)},a.createElement(F,{collapsed:s,onClick:o}),a.createElement(D.z,{lazy:!0,className:z,collapsed:s},a.createElement(S.Z,{toc:t,minHeadingLevel:l,maxHeadingLevel:r})))}const G="tocMobile_ITEo";function J(){const{toc:e,frontMatter:t}=c();return a.createElement($,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,d.Z)(L.k.docs.docTocMobile,G)})}var Y=n(39407);function K(){const{toc:e,frontMatter:t}=c();return a.createElement(Y.Z,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:L.k.docs.docTocDesktop})}var Q=n(92503),W=n(38617);function X(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return a.createElement("div",{className:(0,d.Z)(L.k.docs.docMarkdown,"markdown")},n&&a.createElement("header",null,a.createElement(Q.Z,{as:"h1"},n)),a.createElement(W.Z,null,t))}var ee=n(53438),te=n(48596),ne=n(44996);function ae(e){return a.createElement("svg",(0,u.Z)({viewBox:"0 0 24 24"},e),a.createElement("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"}))}const le="breadcrumbHomeIcon_YNFT";function re(){const e=(0,ne.Z)("/");return a.createElement("li",{className:"breadcrumbs__item"},a.createElement(E.Z,{"aria-label":(0,v.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e},a.createElement(ae,{className:le})))}const se="breadcrumbsContainer_Z_bl";function oe(e){let{children:t,href:n,isLast:l}=e;const r="breadcrumbs__link";return l?a.createElement("span",{className:r,itemProp:"name"},t):n?a.createElement(E.Z,{className:r,href:n,itemProp:"item"},a.createElement("span",{itemProp:"name"},t)):a.createElement("span",{className:r},t)}function ce(e){let{children:t,active:n,index:l,addMicrodata:r}=e;return a.createElement("li",(0,u.Z)({},r&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},{className:(0,d.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n})}),t,a.createElement("meta",{itemProp:"position",content:String(l+1)}))}function ie(){const e=(0,ee.s1)(),t=(0,te.Ns)();return e?a.createElement("nav",{className:(0,d.Z)(L.k.docs.docBreadcrumbs,se),"aria-label":(0,v.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"})},a.createElement("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList"},t&&a.createElement(re,null),e.map(((t,n)=>{const l=n===e.length-1;return a.createElement(ce,{key:n,active:l,index:n,addMicrodata:!!t.href},a.createElement(oe,{href:t.href,isLast:l},t.label))})))):null}const de="docItemContainer_Djhp",me="docItemCol_VOVn";function ue(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.i)(),l=e.hide_table_of_contents,r=!l&&t.length>0;return{hidden:l,mobile:r?a.createElement(J,null):void 0,desktop:!r||"desktop"!==n&&"ssr"!==n?void 0:a.createElement(K,null)}}();return a.createElement("div",{className:"row"},a.createElement("div",{className:(0,d.Z)("col",!n.hidden&&me)},a.createElement(T,null),a.createElement("div",{className:de},a.createElement("article",null,a.createElement(ie,null),a.createElement(y,null),n.mobile,a.createElement(X,null,t),a.createElement(V,null)),a.createElement(f,null))),n.desktop&&a.createElement("div",{className:"col col--3"},n.desktop))}function ve(e){const t=`docs-doc-id-${e.content.metadata.unversionedId}`,n=e.content;return a.createElement(o,{content:e.content},a.createElement(l.FG,{className:t},a.createElement(i,null),a.createElement(ue,null,a.createElement(n,null))))}},39407:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var a=n(87462),l=n(67294),r=n(86010),s=n(93743);const o="tableOfContents_bqdL";function c(e){let{className:t,...n}=e;return l.createElement("div",{className:(0,r.Z)(o,"thin-scrollbar",t)},l.createElement(s.Z,(0,a.Z)({},n,{linkClassName:"table-of-contents__link toc-highlight",linkActiveClassName:"table-of-contents__link--active"})))}},93743:(e,t,n)=>{"use strict";n.d(t,{Z:()=>h});var a=n(87462),l=n(67294),r=n(86668);function s(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...l}=e;n>=0?t[n].children.push(l):a.push(l)})),a}function o(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=o({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function c(e){const t=e.getBoundingClientRect();return t.top===t.bottom?c(e.parentNode):t}function i(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>c(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function m(e){const t=(0,l.useRef)(void 0),n=d();(0,l.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:l,minHeadingLevel:r,maxHeadingLevel:s}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),o=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let l=t;l<=n;l+=1)a.push(`h${l}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:r,maxHeadingLevel:s}),c=i(o,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(l),e.classList.add(l),t.current=e):e.classList.remove(l)}(e,e===d)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,n])}function u(e){let{toc:t,className:n,linkClassName:a,isChild:r}=e;return t.length?l.createElement("ul",{className:r?void 0:n},t.map((e=>l.createElement("li",{key:e.id},l.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),l.createElement(u,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const v=l.memo(u);function h(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:c="table-of-contents__link",linkActiveClassName:i,minHeadingLevel:d,maxHeadingLevel:u,...h}=e;const b=(0,r.L)(),f=d??b.tableOfContents.minHeadingLevel,p=u??b.tableOfContents.maxHeadingLevel,E=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,l.useMemo)((()=>o({toc:s(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:f,maxHeadingLevel:p});return m((0,l.useMemo)((()=>{if(c&&i)return{linkClassName:c,linkActiveClassName:i,minHeadingLevel:f,maxHeadingLevel:p}}),[c,i,f,p])),l.createElement(v,(0,a.Z)({toc:E,className:n,linkClassName:c},h))}},74477:(e,t,n)=>{"use strict";n.d(t,{E:()=>o,q:()=>s});var a=n(67294),l=n(902);const r=a.createContext(null);function s(e){let{children:t,version:n}=e;return a.createElement(r.Provider,{value:n},t)}function o(){const e=(0,a.useContext)(r);if(null===e)throw new l.i6("DocsVersionProvider");return e}},11748:(e,t,n)=>{var a={"./locale":89234,"./locale.js":89234};function l(e){var t=r(e);return n(t)}function r(e){if(!n.o(a,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return a[e]}l.keys=function(){return Object.keys(a)},l.resolve=r,e.exports=l,l.id=11748}}]); \ No newline at end of file diff --git a/assets/js/17896441.d0d75e41.js b/assets/js/17896441.d0d75e41.js new file mode 100644 index 000000000..6dc9b6146 --- /dev/null +++ b/assets/js/17896441.d0d75e41.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7918],{78945:(e,t,n)=>{n.r(t),n.d(t,{default:()=>de});var s=n(67294),a=n(10833),i=n(902),l=n(85893);const o=s.createContext(null);function r(e){let{children:t,content:n}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,l.jsx)(o.Provider,{value:a,children:t})}function c(){const e=(0,s.useContext)(o);if(null===e)throw new i.i6("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=c();return(0,l.jsx)(a.d,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(86010),m=n(87524),h=n(95999),b=n(32244);function v(e){const{previous:t,next:n}=e;return(0,l.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,h.I)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,l.jsx)(b.Z,{...t,subLabel:(0,l.jsx)(h.Z,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,l.jsx)(b.Z,{...n,subLabel:(0,l.jsx)(h.Z,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}function x(){const{metadata:e}=c();return(0,l.jsx)(v,{previous:e.previous,next:e.next})}var p=n(52263),f=n(39960),g=n(80143),j=n(35281),L=n(60373),C=n(74477);const N={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,l.jsx)(h.Z,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,l.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,l.jsx)(h.Z,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,l.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function k(e){const t=N[e.versionMetadata.banner];return(0,l.jsx)(t,{...e})}function _(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,l.jsx)(h.Z,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,l.jsx)("b",{children:(0,l.jsx)(f.Z,{to:n,onClick:s,children:(0,l.jsx)(h.Z,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function Z(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:s}}=(0,p.Z)(),{pluginId:a}=(0,g.gA)({failfast:!0}),{savePreferredVersionName:i}=(0,L.J)(a),{latestDocSuggestion:o,latestVersionSuggestion:r}=(0,g.Jo)(a),c=o??(d=r).docs.find((e=>e.id===d.mainDocId));var d;return(0,l.jsxs)("div",{className:(0,u.Z)(t,j.k.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,l.jsx)("div",{children:(0,l.jsx)(k,{siteTitle:s,versionMetadata:n})}),(0,l.jsx)("div",{className:"margin-top--md",children:(0,l.jsx)(_,{versionLabel:r.label,to:c.path,onClick:()=>i(r.name)})})]})}function T(e){let{className:t}=e;const n=(0,C.E)();return n.banner?(0,l.jsx)(Z,{className:t,versionMetadata:n}):null}function U(e){let{className:t}=e;const n=(0,C.E)();return n.badge?(0,l.jsx)("span",{className:(0,u.Z)(t,j.k.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(h.Z,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}function H(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n}=e;return(0,l.jsx)(h.Z,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,l.jsx)("b",{children:(0,l.jsx)("time",{dateTime:new Date(1e3*t).toISOString(),children:n})})},children:" on {date}"})}function y(e){let{lastUpdatedBy:t}=e;return(0,l.jsx)(h.Z,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,l.jsx)("b",{children:t})},children:" by {user}"})}function w(e){let{lastUpdatedAt:t,formattedLastUpdatedAt:n,lastUpdatedBy:s}=e;return(0,l.jsxs)("span",{className:j.k.common.lastUpdated,children:[(0,l.jsx)(h.Z,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t&&n?(0,l.jsx)(H,{lastUpdatedAt:t,formattedLastUpdatedAt:n}):"",byUser:s?(0,l.jsx)(y,{lastUpdatedBy:s}):""},children:"Last updated{atDate}{byUser}"}),!1]})}var A=n(84881),M=n(71526);const I={lastUpdated:"lastUpdated_vwxv"};function B(e){return(0,l.jsx)("div",{className:(0,u.Z)(j.k.docs.docFooterTagsRow,"row margin-bottom--sm"),children:(0,l.jsx)("div",{className:"col",children:(0,l.jsx)(M.Z,{...e})})})}function E(e){let{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,formattedLastUpdatedAt:a}=e;return(0,l.jsxs)("div",{className:(0,u.Z)(j.k.docs.docFooterEditMetaRow,"row"),children:[(0,l.jsx)("div",{className:"col",children:t&&(0,l.jsx)(A.Z,{editUrl:t})}),(0,l.jsx)("div",{className:(0,u.Z)("col",I.lastUpdated),children:(n||s)&&(0,l.jsx)(w,{lastUpdatedAt:n,formattedLastUpdatedAt:a,lastUpdatedBy:s})})]})}function O(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,formattedLastUpdatedAt:s,lastUpdatedBy:a,tags:i}=e,o=i.length>0,r=!!(t||n||a);return o||r?(0,l.jsxs)("footer",{className:(0,u.Z)(j.k.docs.docFooter,"docusaurus-mt-lg"),children:[o&&(0,l.jsx)(B,{tags:i}),r&&(0,l.jsx)(E,{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:a,formattedLastUpdatedAt:s})]}):null}var S=n(86043),V=n(93743);const P={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function D(e){let{collapsed:t,...n}=e;return(0,l.jsx)("button",{type:"button",...n,className:(0,u.Z)("clean-btn",P.tocCollapsibleButton,!t&&P.tocCollapsibleButtonExpanded,n.className),children:(0,l.jsx)(h.Z,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const R={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function F(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:i,toggleCollapsed:o}=(0,S.u)({initialState:!0});return(0,l.jsxs)("div",{className:(0,u.Z)(R.tocCollapsible,!i&&R.tocCollapsibleExpanded,n),children:[(0,l.jsx)(D,{collapsed:i,onClick:o}),(0,l.jsx)(S.z,{lazy:!0,className:R.tocCollapsibleContent,collapsed:i,children:(0,l.jsx)(V.Z,{toc:t,minHeadingLevel:s,maxHeadingLevel:a})})]})}const z={tocMobile:"tocMobile_ITEo"};function q(){const{toc:e,frontMatter:t}=c();return(0,l.jsx)(F,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.Z)(j.k.docs.docTocMobile,z.tocMobile)})}var $=n(39407);function G(){const{toc:e,frontMatter:t}=c();return(0,l.jsx)($.Z,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:j.k.docs.docTocDesktop})}var J=n(92503),Y=n(76643);function K(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return(0,l.jsxs)("div",{className:(0,u.Z)(j.k.docs.docMarkdown,"markdown"),children:[n&&(0,l.jsx)("header",{children:(0,l.jsx)(J.Z,{as:"h1",children:n})}),(0,l.jsx)(Y.Z,{children:t})]})}var Q=n(53438),W=n(48596),X=n(44996);function ee(e){return(0,l.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,l.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const te={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function ne(){const e=(0,X.Z)("/");return(0,l.jsx)("li",{className:"breadcrumbs__item",children:(0,l.jsx)(f.Z,{"aria-label":(0,h.I)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,l.jsx)(ee,{className:te.breadcrumbHomeIcon})})})}const se={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function ae(e){let{children:t,href:n,isLast:s}=e;const a="breadcrumbs__link";return s?(0,l.jsx)("span",{className:a,itemProp:"name",children:t}):n?(0,l.jsx)(f.Z,{className:a,href:n,itemProp:"item",children:(0,l.jsx)("span",{itemProp:"name",children:t})}):(0,l.jsx)("span",{className:a,children:t})}function ie(e){let{children:t,active:n,index:s,addMicrodata:a}=e;return(0,l.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,u.Z)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,l.jsx)("meta",{itemProp:"position",content:String(s+1)})]})}function le(){const e=(0,Q.s1)(),t=(0,W.Ns)();return e?(0,l.jsx)("nav",{className:(0,u.Z)(j.k.docs.docBreadcrumbs,se.breadcrumbsContainer),"aria-label":(0,h.I)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,l.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,l.jsx)(ne,{}),e.map(((t,n)=>{const s=n===e.length-1,a="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,l.jsx)(ie,{active:s,index:n,addMicrodata:!!a,children:(0,l.jsx)(ae,{href:a,isLast:s,children:t.label})},n)}))]})}):null}var oe=n(22212);const re={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function ce(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.i)(),s=e.hide_table_of_contents,a=!s&&t.length>0;return{hidden:s,mobile:a?(0,l.jsx)(q,{}):void 0,desktop:!a||"desktop"!==n&&"ssr"!==n?void 0:(0,l.jsx)(G,{})}}(),{metadata:{unlisted:s}}=c();return(0,l.jsxs)("div",{className:"row",children:[(0,l.jsxs)("div",{className:(0,u.Z)("col",!n.hidden&&re.docItemCol),children:[s&&(0,l.jsx)(oe.Z,{}),(0,l.jsx)(T,{}),(0,l.jsxs)("div",{className:re.docItemContainer,children:[(0,l.jsxs)("article",{children:[(0,l.jsx)(le,{}),(0,l.jsx)(U,{}),n.mobile,(0,l.jsx)(K,{children:t}),(0,l.jsx)(O,{})]}),(0,l.jsx)(x,{})]})]}),n.desktop&&(0,l.jsx)("div",{className:"col col--3",children:n.desktop})]})}function de(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,l.jsx)(r,{content:e.content,children:(0,l.jsxs)(a.FG,{className:t,children:[(0,l.jsx)(d,{}),(0,l.jsx)(ce,{children:(0,l.jsx)(n,{})})]})})}},39407:(e,t,n)=>{n.d(t,{Z:()=>c});n(67294);var s=n(86010),a=n(93743);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var l=n(85893);const o="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,l.jsx)("div",{className:(0,s.Z)(i.tableOfContents,"thin-scrollbar",t),children:(0,l.jsx)(a.Z,{...n,linkClassName:o,linkActiveClassName:r})})}},93743:(e,t,n)=>{n.d(t,{Z:()=>v});var s=n(67294),a=n(86668);function i(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):s.push(a)})),s}function l(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=l({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function o(e){const t=e.getBoundingClientRect();return t.top===t.bottom?o(e.parentNode):t}function r(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>o(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,s.useRef)(void 0),n=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:l}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),o=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let a=t;a<=n;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:i,maxHeadingLevel:l}),c=r(o,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,n])}var u=n(39960),m=n(85893);function h(e){let{toc:t,className:n,linkClassName:s,isChild:a}=e;return t.length?(0,m.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.Z,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const b=s.memo(h);function v(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:o="table-of-contents__link",linkActiveClassName:r,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const v=(0,a.L)(),x=c??v.tableOfContents.minHeadingLevel,p=u??v.tableOfContents.maxHeadingLevel,f=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>l({toc:i(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:x,maxHeadingLevel:p});return d((0,s.useMemo)((()=>{if(o&&r)return{linkClassName:o,linkActiveClassName:r,minHeadingLevel:x,maxHeadingLevel:p}}),[o,r,x,p])),(0,m.jsx)(b,{toc:f,className:n,linkClassName:o,...h})}},22212:(e,t,n)=>{n.d(t,{Z:()=>h});n(67294);var s=n(86010),a=n(95999),i=n(35742),l=n(85893);function o(){return(0,l.jsx)(a.Z,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function r(){return(0,l.jsx)(a.Z,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,l.jsx)(i.Z,{children:(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=n(35281),u=n(59047);function m(e){let{className:t}=e;return(0,l.jsx)(u.Z,{type:"caution",title:(0,l.jsx)(o,{}),className:(0,s.Z)(t,d.k.common.unlistedBanner),children:(0,l.jsx)(r,{})})}function h(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c,{}),(0,l.jsx)(m,{...e})]})}}}]); \ No newline at end of file diff --git a/assets/js/189.5aec15e9.js b/assets/js/189.5aec15e9.js new file mode 100644 index 000000000..a6f254cc5 --- /dev/null +++ b/assets/js/189.5aec15e9.js @@ -0,0 +1,10065 @@ +"use strict"; +exports.id = 189; +exports.ids = [189]; +exports.modules = { + +/***/ 41644: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + bK: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.Z(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.Z( + map/* default */.Z(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.Z(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.Z(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.k(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.Z(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.Z(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.Z(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.Z(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.Z(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.Z('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.Z(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.Z(g.outEdges(v), function (e) { + if (has/* default */.Z(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.Z(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.Z(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(59236); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.Z)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(74752); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.Z)(iteratee, 3); + + (0,_baseForOwn/* default */.Z)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.Z)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(66092); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.Z.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.Z(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.k().setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.k({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.Z(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.Z(range/* default */.Z(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.Z(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.Z(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.Z(layers, function (vs, i) { + if (isUndefined/* default */.Z(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.Z(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.Z(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.Z(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.Z(children, dfs); + } + + if (has/* default */.Z(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.Z(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, reverseYOne); + if (has/* default */.Z(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, swapXYOne); + if (has/* default */.Z(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.Z(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.Z)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.Z(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.Z(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.Z(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.k({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.Z(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.Z(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.Z(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.Z)(collection)) { + var iteratee = (0,_baseIteratee/* default */.Z)(predicate, 3); + collection = (0,keys/* default */.Z)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.Z)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.Z)(array, (0,_baseIteratee/* default */.Z)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(39473); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(93589); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.Z)(value) && (0,isObjectLike/* default */.Z)(value) && (0,_baseGetTag/* default */.Z)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.Z)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.Z)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.Z)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.Z)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.Z(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.Z(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.Z(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.Z(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.Z(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.Z(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.Z(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.Z(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.Z(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.Z(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.Z(tree.neighbors(v), function (w) { + if (!has/* default */.Z(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.Z(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.Z(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.Z(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.Z(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.Z(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.Z(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.Z(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.Z(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.Z( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.Z(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.k({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.Z(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.Z(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.Z(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.Z('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.Z); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(21018); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.Z)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.Z)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + if ((0,isArray/* default */.Z)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.Z)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.Z]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.Z)(iteratees, (0,_baseUnary/* default */.Z)(_baseIteratee/* default */.Z)); + + var result = (0,_baseMap/* default */.Z)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.Z)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.Z)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.Z)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.Z)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.Z(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.Z( + map/* default */.Z(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.Z(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.Z(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.Z( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.Z(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.Z(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.Z(range/* default */.Z(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.Z(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.Z(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.Z(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.Z(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.Z( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.Z(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.Z(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.Z(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.Z(entryV) && !isUndefined/* default */.Z(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.Z(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.Z(uEntry.barycenter) || + isUndefined/* default */.Z(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.Z(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.Z(entry.out, handleOut(entry)); + } + + return map/* default */.Z( + filter/* default */.Z(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.Z(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.Z(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.Z(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.Z(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.Z(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.Z(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.Z(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.Z([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.Z(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.Z(entries, function (entry) { + entry.vs = flatten/* default */.Z( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.Z(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.Z(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.Z(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.Z(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.k(); + forEach/* default */.Z(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.Z(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.Z(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.Z(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(68882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(61395); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee), keysIn/* default */.Z); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.Z(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.Z(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.Z(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.Z(range/* default */.Z(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.Z(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.Z(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.Z(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.Z(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.Z(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.Z(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.k(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.Z(layering, function (layer) { + var u; + forEach/* default */.Z(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.Z(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.Z(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.Z(['u', 'd'], function (vert) { + forEach/* default */.Z(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.Z(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.Z(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.Z(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.Z(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.Z(layering).reverse(); + forEach/* default */.Z(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.Z(adjustedLayering, function (inner) { + return values/* default */.Z(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.Z(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.Z(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.Z(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.Z(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.Z(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.Z(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.k({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.Z({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.Z(graph, graphAttrs)) + ); + + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.Z(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.Z({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.Z(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.Z(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.Z(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.Z(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.Z(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.Z(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.Z(layers, function (layer) { + var orderShift = 0; + forEach/* default */.Z(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.Z(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.Z(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.Z(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 52544: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + k: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(73234); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(79697); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.Z)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(93203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.Z && (1 / (0,_setToArray/* default */.Z)(new _Set/* default */.Z([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.Z(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.Z)(set); + } + isCommon = false; + includes = _cacheHas/* default */.Z; + seen = new _SetCache/* default */.Z; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(836); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.Z)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.Z)(arrays, 1, isArrayLikeObject/* default */.Z, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.Z(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.Z(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.Z(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.Z(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.Z(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.Z(this._nodes); + } + sources() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.Z(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.Z(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.Z(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.Z(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.Z(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.Z(keys/* default */.Z(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.Z(keys/* default */.Z(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.Z(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.Z(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.Z(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.Z(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.Z(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.Z(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.Z(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.Z(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.Z(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.Z(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.Z(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.Z(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.Z(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.Z(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.Z(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.Z(inV); + if (!u) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.Z(outV); + if (!w) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.Z(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 45625: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ k: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.k) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52544); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 63001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(37834); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.Z; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 76579: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 68774: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 74073: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 58694: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 48451: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(76579); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(31899); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keys/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keysIn/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(91050); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(87215); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(95695); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.Z)(source, (0,_getSymbols/* default */.Z)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(12513); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(60532); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.Z : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.Z)(result, (0,_getSymbols/* default */.Z)(object)); + object = (0,_getPrototype/* default */.Z)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.Z)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(63327); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.Z)(object, keysIn/* default */.Z, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(41884); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.Z)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(12701); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.Z)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.Z)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(73658); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(98351); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.Z)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.Z)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.Z)(value)) { + return value; + } + var isArr = (0,isArray/* default */.Z)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.Z)(value, result); + } + } else { + var tag = (0,_getTag/* default */.Z)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.Z)(value)) { + return (0,_cloneBuffer/* default */.Z)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.Z)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.Z); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.Z) + : (isFlat ? keysIn/* default */.Z : keys/* default */.Z); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.Z)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.Z)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 49811: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.Z)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.Z); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 21692: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 10626: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(29169); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.Z ? _Symbol/* default */.Z.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.Z)(value) || (0,isArguments/* default */.Z)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.Z)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 2693: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61395); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 13317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 63327: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58694); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 74765: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.Z : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.Z)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(84073); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(79651); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.Z(object), new _Uint8Array/* default */.Z(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.Z)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.Z); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.Z)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.Z)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(18843); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.Z)(object), + othIsArr = (0,isArray/* default */.Z)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.Z)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.Z)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.Z)(object)) { + if (!(0,isBuffer/* default */.Z)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.Z); + return (objIsArr || (0,isTypedArray/* default */.Z)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.Z); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.Z); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.Z)(value) && !(0,isObjectLike/* default */.Z)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.Z; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.Z)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.Z)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.Z)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.Z)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.Z)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.Z)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.Z)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.Z)(path) ? (0,_baseProperty/* default */.Z)((0,_toKey/* default */.Z)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.Z; + } + if (typeof value == 'object') { + return (0,isArray/* default */.Z)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 21018: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49811); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 54193: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 59548: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 68882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69203); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 22823: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(42454); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.Z)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(50751); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.Z)(value)) { + return value; + } + return (0,_isKey/* default */.Z)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.Z)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 1808: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63327); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(95695); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 95695: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68774); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(60532); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 16174: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29169); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27771); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(56009); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1656); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 99365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72714); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 6545: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 62281: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72714); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 3688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69581); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(79651); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50439); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32957); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 13445: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(68774); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.Z)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayFilter/* default */.Z : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.Z)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 27961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10626); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 70870: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76579); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49811); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(68882); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 17452: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 75487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 72714: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93589); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18533); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 49360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 17179: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87668); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39473); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 43836: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74073); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74765); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21018); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 61666: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(22823); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(56009); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.Z)(object)) { + return object; + } + path = (0,_castPath/* default */.Z)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.Z)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.Z)(objValue) + ? objValue + : ((0,_isIndex/* default */.Z)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.Z)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.Z)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.Z)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.Z)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(81211); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(27227); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.Z)((0,_overRest/* default */.Z)(func, undefined, flatten/* default */.Z), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 74379: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.Z)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.Z)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.Z)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.Z)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 92344: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.Z)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.Z); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 60532: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 94099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.Z)(value)) { + return NAN; + } + if ((0,isObject/* default */.Z)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.Z)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 50751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.Z)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.Z)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.Z)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 66749: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50751); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 34148: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.Z)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.Z)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 18189: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(45625); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(20683); + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 3], $V1 = [1, 4], $V2 = [1, 5], $V3 = [1, 6], $V4 = [5, 6, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 62, 63], $V5 = [1, 18], $V6 = [2, 7], $V7 = [1, 22], $V8 = [1, 23], $V9 = [1, 24], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 20], $Ve = [1, 28], $Vf = [1, 29], $Vg = [62, 63], $Vh = [5, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 51, 53, 62, 63], $Vi = [1, 47], $Vj = [1, 48], $Vk = [1, 49], $Vl = [1, 50], $Vm = [1, 51], $Vn = [1, 52], $Vo = [1, 53], $Vp = [53, 54], $Vq = [1, 64], $Vr = [1, 60], $Vs = [1, 61], $Vt = [1, 62], $Vu = [1, 63], $Vv = [1, 65], $Vw = [1, 69], $Vx = [1, 70], $Vy = [1, 67], $Vz = [1, 68], $VA = [5, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 62, 63]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "directive": 4, "NEWLINE": 5, "RD": 6, "diagram": 7, "EOF": 8, "acc_title": 9, "acc_title_value": 10, "acc_descr": 11, "acc_descr_value": 12, "acc_descr_multiline_value": 13, "requirementDef": 14, "elementDef": 15, "relationshipDef": 16, "requirementType": 17, "requirementName": 18, "STRUCT_START": 19, "requirementBody": 20, "ID": 21, "COLONSEP": 22, "id": 23, "TEXT": 24, "text": 25, "RISK": 26, "riskLevel": 27, "VERIFYMTHD": 28, "verifyType": 29, "STRUCT_STOP": 30, "REQUIREMENT": 31, "FUNCTIONAL_REQUIREMENT": 32, "INTERFACE_REQUIREMENT": 33, "PERFORMANCE_REQUIREMENT": 34, "PHYSICAL_REQUIREMENT": 35, "DESIGN_CONSTRAINT": 36, "LOW_RISK": 37, "MED_RISK": 38, "HIGH_RISK": 39, "VERIFY_ANALYSIS": 40, "VERIFY_DEMONSTRATION": 41, "VERIFY_INSPECTION": 42, "VERIFY_TEST": 43, "ELEMENT": 44, "elementName": 45, "elementBody": 46, "TYPE": 47, "type": 48, "DOCREF": 49, "ref": 50, "END_ARROW_L": 51, "relationship": 52, "LINE": 53, "END_ARROW_R": 54, "CONTAINS": 55, "COPIES": 56, "DERIVES": 57, "SATISFIES": 58, "VERIFIES": 59, "REFINES": 60, "TRACES": 61, "unqString": 62, "qString": 63, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "NEWLINE", 6: "RD", 8: "EOF", 9: "acc_title", 10: "acc_title_value", 11: "acc_descr", 12: "acc_descr_value", 13: "acc_descr_multiline_value", 19: "STRUCT_START", 21: "ID", 22: "COLONSEP", 24: "TEXT", 26: "RISK", 28: "VERIFYMTHD", 30: "STRUCT_STOP", 31: "REQUIREMENT", 32: "FUNCTIONAL_REQUIREMENT", 33: "INTERFACE_REQUIREMENT", 34: "PERFORMANCE_REQUIREMENT", 35: "PHYSICAL_REQUIREMENT", 36: "DESIGN_CONSTRAINT", 37: "LOW_RISK", 38: "MED_RISK", 39: "HIGH_RISK", 40: "VERIFY_ANALYSIS", 41: "VERIFY_DEMONSTRATION", 42: "VERIFY_INSPECTION", 43: "VERIFY_TEST", 44: "ELEMENT", 47: "TYPE", 49: "DOCREF", 51: "END_ARROW_L", 53: "LINE", 54: "END_ARROW_R", 55: "CONTAINS", 56: "COPIES", 57: "DERIVES", 58: "SATISFIES", 59: "VERIFIES", 60: "REFINES", 61: "TRACES", 62: "unqString", 63: "qString" }, + productions_: [0, [3, 3], [3, 2], [3, 4], [4, 2], [4, 2], [4, 1], [7, 0], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [14, 5], [20, 5], [20, 5], [20, 5], [20, 5], [20, 2], [20, 1], [17, 1], [17, 1], [17, 1], [17, 1], [17, 1], [17, 1], [27, 1], [27, 1], [27, 1], [29, 1], [29, 1], [29, 1], [29, 1], [15, 5], [46, 5], [46, 5], [46, 2], [46, 1], [16, 5], [16, 5], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [18, 1], [18, 1], [23, 1], [23, 1], [25, 1], [25, 1], [45, 1], [45, 1], [48, 1], [48, 1], [50, 1], [50, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 4: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 5: + case 6: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 7: + this.$ = []; + break; + case 13: + yy.addRequirement($$[$0 - 3], $$[$0 - 4]); + break; + case 14: + yy.setNewReqId($$[$0 - 2]); + break; + case 15: + yy.setNewReqText($$[$0 - 2]); + break; + case 16: + yy.setNewReqRisk($$[$0 - 2]); + break; + case 17: + yy.setNewReqVerifyMethod($$[$0 - 2]); + break; + case 20: + this.$ = yy.RequirementType.REQUIREMENT; + break; + case 21: + this.$ = yy.RequirementType.FUNCTIONAL_REQUIREMENT; + break; + case 22: + this.$ = yy.RequirementType.INTERFACE_REQUIREMENT; + break; + case 23: + this.$ = yy.RequirementType.PERFORMANCE_REQUIREMENT; + break; + case 24: + this.$ = yy.RequirementType.PHYSICAL_REQUIREMENT; + break; + case 25: + this.$ = yy.RequirementType.DESIGN_CONSTRAINT; + break; + case 26: + this.$ = yy.RiskLevel.LOW_RISK; + break; + case 27: + this.$ = yy.RiskLevel.MED_RISK; + break; + case 28: + this.$ = yy.RiskLevel.HIGH_RISK; + break; + case 29: + this.$ = yy.VerifyType.VERIFY_ANALYSIS; + break; + case 30: + this.$ = yy.VerifyType.VERIFY_DEMONSTRATION; + break; + case 31: + this.$ = yy.VerifyType.VERIFY_INSPECTION; + break; + case 32: + this.$ = yy.VerifyType.VERIFY_TEST; + break; + case 33: + yy.addElement($$[$0 - 3]); + break; + case 34: + yy.setNewElementType($$[$0 - 2]); + break; + case 35: + yy.setNewElementDocRef($$[$0 - 2]); + break; + case 38: + yy.addRelationship($$[$0 - 2], $$[$0], $$[$0 - 4]); + break; + case 39: + yy.addRelationship($$[$0 - 2], $$[$0 - 4], $$[$0]); + break; + case 40: + this.$ = yy.Relationships.CONTAINS; + break; + case 41: + this.$ = yy.Relationships.COPIES; + break; + case 42: + this.$ = yy.Relationships.DERIVES; + break; + case 43: + this.$ = yy.Relationships.SATISFIES; + break; + case 44: + this.$ = yy.Relationships.VERIFIES; + break; + case 45: + this.$ = yy.Relationships.REFINES; + break; + case 46: + this.$ = yy.Relationships.TRACES; + break; + } + }, + table: [{ 3: 1, 4: 2, 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 1: [3] }, { 3: 8, 4: 2, 5: [1, 7], 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 5: [1, 9] }, { 10: [1, 10] }, { 12: [1, 11] }, o($V4, [2, 6]), { 3: 12, 4: 2, 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 1: [2, 2] }, { 4: 17, 5: $V5, 7: 13, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, o($V4, [2, 4]), o($V4, [2, 5]), { 1: [2, 1] }, { 8: [1, 30] }, { 4: 17, 5: $V5, 7: 31, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 32, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 33, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 34, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 35, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 18: 36, 62: [1, 37], 63: [1, 38] }, { 45: 39, 62: [1, 40], 63: [1, 41] }, { 51: [1, 42], 53: [1, 43] }, o($Vg, [2, 20]), o($Vg, [2, 21]), o($Vg, [2, 22]), o($Vg, [2, 23]), o($Vg, [2, 24]), o($Vg, [2, 25]), o($Vh, [2, 49]), o($Vh, [2, 50]), { 1: [2, 3] }, { 8: [2, 8] }, { 8: [2, 9] }, { 8: [2, 10] }, { 8: [2, 11] }, { 8: [2, 12] }, { 19: [1, 44] }, { 19: [2, 47] }, { 19: [2, 48] }, { 19: [1, 45] }, { 19: [2, 53] }, { 19: [2, 54] }, { 52: 46, 55: $Vi, 56: $Vj, 57: $Vk, 58: $Vl, 59: $Vm, 60: $Vn, 61: $Vo }, { 52: 54, 55: $Vi, 56: $Vj, 57: $Vk, 58: $Vl, 59: $Vm, 60: $Vn, 61: $Vo }, { 5: [1, 55] }, { 5: [1, 56] }, { 53: [1, 57] }, o($Vp, [2, 40]), o($Vp, [2, 41]), o($Vp, [2, 42]), o($Vp, [2, 43]), o($Vp, [2, 44]), o($Vp, [2, 45]), o($Vp, [2, 46]), { 54: [1, 58] }, { 5: $Vq, 20: 59, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vw, 30: $Vx, 46: 66, 47: $Vy, 49: $Vz }, { 23: 71, 62: $Ve, 63: $Vf }, { 23: 72, 62: $Ve, 63: $Vf }, o($VA, [2, 13]), { 22: [1, 73] }, { 22: [1, 74] }, { 22: [1, 75] }, { 22: [1, 76] }, { 5: $Vq, 20: 77, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, o($VA, [2, 19]), o($VA, [2, 33]), { 22: [1, 78] }, { 22: [1, 79] }, { 5: $Vw, 30: $Vx, 46: 80, 47: $Vy, 49: $Vz }, o($VA, [2, 37]), o($VA, [2, 38]), o($VA, [2, 39]), { 23: 81, 62: $Ve, 63: $Vf }, { 25: 82, 62: [1, 83], 63: [1, 84] }, { 27: 85, 37: [1, 86], 38: [1, 87], 39: [1, 88] }, { 29: 89, 40: [1, 90], 41: [1, 91], 42: [1, 92], 43: [1, 93] }, o($VA, [2, 18]), { 48: 94, 62: [1, 95], 63: [1, 96] }, { 50: 97, 62: [1, 98], 63: [1, 99] }, o($VA, [2, 36]), { 5: [1, 100] }, { 5: [1, 101] }, { 5: [2, 51] }, { 5: [2, 52] }, { 5: [1, 102] }, { 5: [2, 26] }, { 5: [2, 27] }, { 5: [2, 28] }, { 5: [1, 103] }, { 5: [2, 29] }, { 5: [2, 30] }, { 5: [2, 31] }, { 5: [2, 32] }, { 5: [1, 104] }, { 5: [2, 55] }, { 5: [2, 56] }, { 5: [1, 105] }, { 5: [2, 57] }, { 5: [2, 58] }, { 5: $Vq, 20: 106, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 107, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 108, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 109, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vw, 30: $Vx, 46: 110, 47: $Vy, 49: $Vz }, { 5: $Vw, 30: $Vx, 46: 111, 47: $Vy, 49: $Vz }, o($VA, [2, 14]), o($VA, [2, 15]), o($VA, [2, 16]), o($VA, [2, 17]), o($VA, [2, 34]), o($VA, [2, 35])], + defaultActions: { 8: [2, 2], 12: [2, 1], 30: [2, 3], 31: [2, 8], 32: [2, 9], 33: [2, 10], 34: [2, 11], 35: [2, 12], 37: [2, 47], 38: [2, 48], 40: [2, 53], 41: [2, 54], 83: [2, 51], 84: [2, 52], 86: [2, 26], 87: [2, 27], 88: [2, 28], 90: [2, 29], 91: [2, 30], 92: [2, 31], 93: [2, 32], 95: [2, 55], 96: [2, 56], 98: [2, 57], 99: [2, 58] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return "title"; + case 1: + this.begin("acc_title"); + return 9; + case 2: + this.popState(); + return "acc_title_value"; + case 3: + this.begin("acc_descr"); + return 11; + case 4: + this.popState(); + return "acc_descr_value"; + case 5: + this.begin("acc_descr_multiline"); + break; + case 6: + this.popState(); + break; + case 7: + return "acc_descr_multiline_value"; + case 8: + return 5; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + return 8; + case 13: + return 6; + case 14: + return 19; + case 15: + return 30; + case 16: + return 22; + case 17: + return 21; + case 18: + return 24; + case 19: + return 26; + case 20: + return 28; + case 21: + return 31; + case 22: + return 32; + case 23: + return 33; + case 24: + return 34; + case 25: + return 35; + case 26: + return 36; + case 27: + return 37; + case 28: + return 38; + case 29: + return 39; + case 30: + return 40; + case 31: + return 41; + case 32: + return 42; + case 33: + return 43; + case 34: + return 44; + case 35: + return 55; + case 36: + return 56; + case 37: + return 57; + case 38: + return 58; + case 39: + return 59; + case 40: + return 60; + case 41: + return 61; + case 42: + return 47; + case 43: + return 49; + case 44: + return 51; + case 45: + return 54; + case 46: + return 53; + case 47: + this.begin("string"); + break; + case 48: + this.popState(); + break; + case 49: + return "qString"; + case 50: + yy_.yytext = yy_.yytext.trim(); + return 62; + } + }, + rules: [/^(?:title\s[^#\n;]+)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:(\r?\n)+)/i, /^(?:\s+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:$)/i, /^(?:requirementDiagram\b)/i, /^(?:\{)/i, /^(?:\})/i, /^(?::)/i, /^(?:id\b)/i, /^(?:text\b)/i, /^(?:risk\b)/i, /^(?:verifyMethod\b)/i, /^(?:requirement\b)/i, /^(?:functionalRequirement\b)/i, /^(?:interfaceRequirement\b)/i, /^(?:performanceRequirement\b)/i, /^(?:physicalRequirement\b)/i, /^(?:designConstraint\b)/i, /^(?:low\b)/i, /^(?:medium\b)/i, /^(?:high\b)/i, /^(?:analysis\b)/i, /^(?:demonstration\b)/i, /^(?:inspection\b)/i, /^(?:test\b)/i, /^(?:element\b)/i, /^(?:contains\b)/i, /^(?:copies\b)/i, /^(?:derives\b)/i, /^(?:satisfies\b)/i, /^(?:verifies\b)/i, /^(?:refines\b)/i, /^(?:traces\b)/i, /^(?:type\b)/i, /^(?:docref\b)/i, /^(?:<-)/i, /^(?:->)/i, /^(?:-)/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[\w][^\r\n\{\<\>\-\=]*)/i], + conditions: { "acc_descr_multiline": { "rules": [6, 7], "inclusive": false }, "acc_descr": { "rules": [4], "inclusive": false }, "acc_title": { "rules": [2], "inclusive": false }, "unqString": { "rules": [], "inclusive": false }, "token": { "rules": [], "inclusive": false }, "string": { "rules": [48, 49], "inclusive": false }, "INITIAL": { "rules": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 50], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let relations = []; +let latestRequirement = {}; +let requirements = {}; +let latestElement = {}; +let elements = {}; +const RequirementType = { + REQUIREMENT: "Requirement", + FUNCTIONAL_REQUIREMENT: "Functional Requirement", + INTERFACE_REQUIREMENT: "Interface Requirement", + PERFORMANCE_REQUIREMENT: "Performance Requirement", + PHYSICAL_REQUIREMENT: "Physical Requirement", + DESIGN_CONSTRAINT: "Design Constraint" +}; +const RiskLevel = { + LOW_RISK: "Low", + MED_RISK: "Medium", + HIGH_RISK: "High" +}; +const VerifyType = { + VERIFY_ANALYSIS: "Analysis", + VERIFY_DEMONSTRATION: "Demonstration", + VERIFY_INSPECTION: "Inspection", + VERIFY_TEST: "Test" +}; +const Relationships = { + CONTAINS: "contains", + COPIES: "copies", + DERIVES: "derives", + SATISFIES: "satisfies", + VERIFIES: "verifies", + REFINES: "refines", + TRACES: "traces" +}; +const addRequirement = (name, type) => { + if (requirements[name] === void 0) { + requirements[name] = { + name, + type, + id: latestRequirement.id, + text: latestRequirement.text, + risk: latestRequirement.risk, + verifyMethod: latestRequirement.verifyMethod + }; + } + latestRequirement = {}; + return requirements[name]; +}; +const getRequirements = () => requirements; +const setNewReqId = (id) => { + if (latestRequirement !== void 0) { + latestRequirement.id = id; + } +}; +const setNewReqText = (text) => { + if (latestRequirement !== void 0) { + latestRequirement.text = text; + } +}; +const setNewReqRisk = (risk) => { + if (latestRequirement !== void 0) { + latestRequirement.risk = risk; + } +}; +const setNewReqVerifyMethod = (verifyMethod) => { + if (latestRequirement !== void 0) { + latestRequirement.verifyMethod = verifyMethod; + } +}; +const addElement = (name) => { + if (elements[name] === void 0) { + elements[name] = { + name, + type: latestElement.type, + docRef: latestElement.docRef + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Added new requirement: ", name); + } + latestElement = {}; + return elements[name]; +}; +const getElements = () => elements; +const setNewElementType = (type) => { + if (latestElement !== void 0) { + latestElement.type = type; + } +}; +const setNewElementDocRef = (docRef) => { + if (latestElement !== void 0) { + latestElement.docRef = docRef; + } +}; +const addRelationship = (type, src, dst) => { + relations.push({ + type, + src, + dst + }); +}; +const getRelationships = () => relations; +const clear = () => { + relations = []; + latestRequirement = {}; + requirements = {}; + latestElement = {}; + elements = {}; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.t)(); +}; +const db = { + RequirementType, + RiskLevel, + VerifyType, + Relationships, + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().req, + addRequirement, + getRequirements, + setNewReqId, + setNewReqText, + setNewReqRisk, + setNewReqVerifyMethod, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.g, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.b, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.a, + addElement, + getElements, + setNewElementType, + setNewElementDocRef, + addRelationship, + getRelationships, + clear +}; +const getStyles = (options) => ` + + marker { + fill: ${options.relationColor}; + stroke: ${options.relationColor}; + } + + marker.cross { + stroke: ${options.lineColor}; + } + + svg { + font-family: ${options.fontFamily}; + font-size: ${options.fontSize}; + } + + .reqBox { + fill: ${options.requirementBackground}; + fill-opacity: 1.0; + stroke: ${options.requirementBorderColor}; + stroke-width: ${options.requirementBorderSize}; + } + + .reqTitle, .reqLabel{ + fill: ${options.requirementTextColor}; + } + .reqLabelBox { + fill: ${options.relationLabelBackground}; + fill-opacity: 1.0; + } + + .req-title-line { + stroke: ${options.requirementBorderColor}; + stroke-width: ${options.requirementBorderSize}; + } + .relationshipLine { + stroke: ${options.relationColor}; + stroke-width: 1; + } + .relationshipLabel { + fill: ${options.relationLabelColor}; + } + +`; +const styles = getStyles; +const ReqMarkers = { + CONTAINS: "contains", + ARROW: "arrow" +}; +const insertLineEndings = (parentNode, conf2) => { + let containsNode = parentNode.append("defs").append("marker").attr("id", ReqMarkers.CONTAINS + "_line_ending").attr("refX", 0).attr("refY", conf2.line_height / 2).attr("markerWidth", conf2.line_height).attr("markerHeight", conf2.line_height).attr("orient", "auto").append("g"); + containsNode.append("circle").attr("cx", conf2.line_height / 2).attr("cy", conf2.line_height / 2).attr("r", conf2.line_height / 2).attr("fill", "none"); + containsNode.append("line").attr("x1", 0).attr("x2", conf2.line_height).attr("y1", conf2.line_height / 2).attr("y2", conf2.line_height / 2).attr("stroke-width", 1); + containsNode.append("line").attr("y1", 0).attr("y2", conf2.line_height).attr("x1", conf2.line_height / 2).attr("x2", conf2.line_height / 2).attr("stroke-width", 1); + parentNode.append("defs").append("marker").attr("id", ReqMarkers.ARROW + "_line_ending").attr("refX", conf2.line_height).attr("refY", 0.5 * conf2.line_height).attr("markerWidth", conf2.line_height).attr("markerHeight", conf2.line_height).attr("orient", "auto").append("path").attr( + "d", + `M0,0 + L${conf2.line_height},${conf2.line_height / 2} + M${conf2.line_height},${conf2.line_height / 2} + L0,${conf2.line_height}` + ).attr("stroke-width", 1); +}; +const markers = { + ReqMarkers, + insertLineEndings +}; +let conf = {}; +let relCnt = 0; +const newRectNode = (parentNode, id) => { + return parentNode.insert("rect", "#" + id).attr("class", "req reqBox").attr("x", 0).attr("y", 0).attr("width", conf.rect_min_width + "px").attr("height", conf.rect_min_height + "px"); +}; +const newTitleNode = (parentNode, id, txts) => { + let x = conf.rect_min_width / 2; + let title = parentNode.append("text").attr("class", "req reqLabel reqTitle").attr("id", id).attr("x", x).attr("y", conf.rect_padding).attr("dominant-baseline", "hanging"); + let i = 0; + txts.forEach((textStr) => { + if (i == 0) { + title.append("tspan").attr("text-anchor", "middle").attr("x", conf.rect_min_width / 2).attr("dy", 0).text(textStr); + } else { + title.append("tspan").attr("text-anchor", "middle").attr("x", conf.rect_min_width / 2).attr("dy", conf.line_height * 0.75).text(textStr); + } + i++; + }); + let yPadding = 1.5 * conf.rect_padding; + let linePadding = i * conf.line_height * 0.75; + let totalY = yPadding + linePadding; + parentNode.append("line").attr("class", "req-title-line").attr("x1", "0").attr("x2", conf.rect_min_width).attr("y1", totalY).attr("y2", totalY); + return { + titleNode: title, + y: totalY + }; +}; +const newBodyNode = (parentNode, id, txts, yStart) => { + let body = parentNode.append("text").attr("class", "req reqLabel").attr("id", id).attr("x", conf.rect_padding).attr("y", yStart).attr("dominant-baseline", "hanging"); + let currentRow = 0; + const charLimit = 30; + let wrappedTxts = []; + txts.forEach((textStr) => { + let currentTextLen = textStr.length; + while (currentTextLen > charLimit && currentRow < 3) { + let firstPart = textStr.substring(0, charLimit); + textStr = textStr.substring(charLimit, textStr.length); + currentTextLen = textStr.length; + wrappedTxts[wrappedTxts.length] = firstPart; + currentRow++; + } + if (currentRow == 3) { + let lastStr = wrappedTxts[wrappedTxts.length - 1]; + wrappedTxts[wrappedTxts.length - 1] = lastStr.substring(0, lastStr.length - 4) + "..."; + } else { + wrappedTxts[wrappedTxts.length] = textStr; + } + currentRow = 0; + }); + wrappedTxts.forEach((textStr) => { + body.append("tspan").attr("x", conf.rect_padding).attr("dy", conf.line_height).text(textStr); + }); + return body; +}; +const addEdgeLabel = (parentNode, svgPath, conf2, txt) => { + const len = svgPath.node().getTotalLength(); + const labelPoint = svgPath.node().getPointAtLength(len * 0.5); + const labelId = "rel" + relCnt; + relCnt++; + const labelNode = parentNode.append("text").attr("class", "req relationshipLabel").attr("id", labelId).attr("x", labelPoint.x).attr("y", labelPoint.y).attr("text-anchor", "middle").attr("dominant-baseline", "middle").text(txt); + const labelBBox = labelNode.node().getBBox(); + parentNode.insert("rect", "#" + labelId).attr("class", "req reqLabelBox").attr("x", labelPoint.x - labelBBox.width / 2).attr("y", labelPoint.y - labelBBox.height / 2).attr("width", labelBBox.width).attr("height", labelBBox.height).attr("fill", "white").attr("fill-opacity", "85%"); +}; +const drawRelationshipFromLayout = function(svg, rel, g, insert, diagObj) { + const edge = g.edge(elementString(rel.src), elementString(rel.dst)); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(function(d) { + return d.x; + }).y(function(d) { + return d.y; + }); + const svgPath = svg.insert("path", "#" + insert).attr("class", "er relationshipLine").attr("d", lineFunction(edge.points)).attr("fill", "none"); + if (rel.type == diagObj.db.Relationships.CONTAINS) { + svgPath.attr( + "marker-start", + "url(" + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.e.getUrl(conf.arrowMarkerAbsolute) + "#" + rel.type + "_line_ending)" + ); + } else { + svgPath.attr("stroke-dasharray", "10,7"); + svgPath.attr( + "marker-end", + "url(" + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.e.getUrl(conf.arrowMarkerAbsolute) + "#" + markers.ReqMarkers.ARROW + "_line_ending)" + ); + } + addEdgeLabel(svg, svgPath, conf, `<<${rel.type}>>`); + return; +}; +const drawReqs = (reqs, graph, svgNode) => { + Object.keys(reqs).forEach((reqName) => { + let req = reqs[reqName]; + reqName = elementString(reqName); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Added new requirement: ", reqName); + const groupNode = svgNode.append("g").attr("id", reqName); + const textId = "req-" + reqName; + const rectNode = newRectNode(groupNode, textId); + let titleNodeInfo = newTitleNode(groupNode, reqName + "_title", [ + `<<${req.type}>>`, + `${req.name}` + ]); + newBodyNode( + groupNode, + reqName + "_body", + [ + `Id: ${req.id}`, + `Text: ${req.text}`, + `Risk: ${req.risk}`, + `Verification: ${req.verifyMethod}` + ], + titleNodeInfo.y + ); + const rectBBox = rectNode.node().getBBox(); + graph.setNode(reqName, { + width: rectBBox.width, + height: rectBBox.height, + shape: "rect", + id: reqName + }); + }); +}; +const drawElements = (els, graph, svgNode) => { + Object.keys(els).forEach((elName) => { + let el = els[elName]; + const id = elementString(elName); + const groupNode = svgNode.append("g").attr("id", id); + const textId = "element-" + id; + const rectNode = newRectNode(groupNode, textId); + let titleNodeInfo = newTitleNode(groupNode, textId + "_title", [`<>`, `${elName}`]); + newBodyNode( + groupNode, + textId + "_body", + [`Type: ${el.type || "Not Specified"}`, `Doc Ref: ${el.docRef || "None"}`], + titleNodeInfo.y + ); + const rectBBox = rectNode.node().getBBox(); + graph.setNode(id, { + width: rectBBox.width, + height: rectBBox.height, + shape: "rect", + id + }); + }); +}; +const addRelationships = (relationships, g) => { + relationships.forEach(function(r) { + let src = elementString(r.src); + let dst = elementString(r.dst); + g.setEdge(src, dst, { relationship: r }); + }); + return relationships; +}; +const adjustEntities = function(svgNode, graph) { + graph.nodes().forEach(function(v) { + if (v !== void 0 && graph.node(v) !== void 0) { + svgNode.select("#" + v); + svgNode.select("#" + v).attr( + "transform", + "translate(" + (graph.node(v).x - graph.node(v).width / 2) + "," + (graph.node(v).y - graph.node(v).height / 2) + " )" + ); + } + }); + return; +}; +const elementString = (str) => { + return str.replace(/\s/g, "").replace(/\./g, "_"); +}; +const draw = (text, id, _version, diagObj) => { + conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().requirement; + const securityLevel = conf.securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const svg = root.select(`[id='${id}']`); + markers.insertLineEndings(svg, conf); + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .k({ + multigraph: false, + compound: false, + directed: true + }).setGraph({ + rankdir: conf.layoutDirection, + marginx: 20, + marginy: 20, + nodesep: 100, + edgesep: 100, + ranksep: 100 + }).setDefaultEdgeLabel(function() { + return {}; + }); + let requirements2 = diagObj.db.getRequirements(); + let elements2 = diagObj.db.getElements(); + let relationships = diagObj.db.getRelationships(); + drawReqs(requirements2, g, svg); + drawElements(elements2, g, svg); + addRelationships(relationships, g); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__/* .layout */ .bK)(g); + adjustEntities(svg, g); + relationships.forEach(function(rel) { + drawRelationshipFromLayout(svg, rel, g, id, diagObj); + }); + const padding = conf.rect_padding; + const svgBounds = svg.node().getBBox(); + const width = svgBounds.width + padding * 2; + const height = svgBounds.height + padding * 2; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.i)(svg, height, width, conf.useMaxWidth); + svg.attr("viewBox", `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); +}; +const renderer = { + draw +}; +const diagram = { + parser: parser$1, + db, + renderer, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/1893cb59.8a4bc4b2.js b/assets/js/1893cb59.7a0eb710.js similarity index 88% rename from assets/js/1893cb59.8a4bc4b2.js rename to assets/js/1893cb59.7a0eb710.js index 45c01b8ac..4e7e98c9d 100644 --- a/assets/js/1893cb59.8a4bc4b2.js +++ b/assets/js/1893cb59.7a0eb710.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[286],{16269:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[286],{16269:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/19f4ae8e.f32f8930.js b/assets/js/19f4ae8e.54b6b5f0.js similarity index 59% rename from assets/js/19f4ae8e.f32f8930.js rename to assets/js/19f4ae8e.54b6b5f0.js index fb5f48f64..b10541782 100644 --- a/assets/js/19f4ae8e.f32f8930.js +++ b/assets/js/19f4ae8e.54b6b5f0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8161],{25680:e=>{e.exports=JSON.parse('{"label":"log","permalink":"/tags/log","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8161],{25680:e=>{e.exports=JSON.parse('{"label":"log","permalink":"/tags/log","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/1a3abee6.be6aaff1.js b/assets/js/1a3abee6.b1ea2356.js similarity index 81% rename from assets/js/1a3abee6.be6aaff1.js rename to assets/js/1a3abee6.b1ea2356.js index 376729e47..951a36aa4 100644 --- a/assets/js/1a3abee6.be6aaff1.js +++ b/assets/js/1a3abee6.b1ea2356.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5035],{87753:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5035],{87753:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/1a4e3797.3cfcc719.js b/assets/js/1a4e3797.3cfcc719.js new file mode 100644 index 000000000..4b33bf02c --- /dev/null +++ b/assets/js/1a4e3797.3cfcc719.js @@ -0,0 +1,2 @@ +/*! For license information please see 1a4e3797.3cfcc719.js.LICENSE.txt */ +(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7920],{17331:e=>{function t(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function n(e){return"object"==typeof e&&null!==e}function i(e){return void 0===e}e.exports=t,t.prototype._events=void 0,t.prototype._maxListeners=void 0,t.defaultMaxListeners=10,t.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},t.prototype.emit=function(e){var t,s,a,c,u,o;if(this._events||(this._events={}),"error"===e&&(!this._events.error||n(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var h=new Error('Uncaught, unspecified "error" event. ('+t+")");throw h.context=t,h}if(i(s=this._events[e]))return!1;if(r(s))switch(arguments.length){case 1:s.call(this);break;case 2:s.call(this,arguments[1]);break;case 3:s.call(this,arguments[1],arguments[2]);break;default:c=Array.prototype.slice.call(arguments,1),s.apply(this,c)}else if(n(s))for(c=Array.prototype.slice.call(arguments,1),a=(o=s.slice()).length,u=0;u0&&this._events[e].length>a&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},t.prototype.on=t.prototype.addListener,t.prototype.once=function(e,t){if(!r(t))throw TypeError("listener must be a function");var n=!1;function i(){this.removeListener(e,i),n||(n=!0,t.apply(this,arguments))}return i.listener=t,this.on(e,i),this},t.prototype.removeListener=function(e,t){var i,s,a,c;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(a=(i=this._events[e]).length,s=-1,i===t||r(i.listener)&&i.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(n(i)){for(c=a;c-- >0;)if(i[c]===t||i[c].listener&&i[c].listener===t){s=c;break}if(s<0)return this;1===i.length?(i.length=0,delete this._events[e]):i.splice(s,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},t.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r(n=this._events[e]))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},t.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},t.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},t.listenerCount=function(e,t){return e.listenerCount(t)}},8131:(e,t,r)=>{"use strict";var n=r(49374),i=r(17775),s=r(23076);function a(e,t,r){return new n(e,t,r)}a.version=r(24336),a.AlgoliaSearchHelper=n,a.SearchParameters=i,a.SearchResults=s,e.exports=a},68078:(e,t,r)=>{"use strict";var n=r(17331);function i(e,t){this.main=e,this.fn=t,this.lastResults=null}r(14853)(i,n),i.prototype.detach=function(){this.removeAllListeners(),this.main.detachDerivedHelper(this)},i.prototype.getModifiedState=function(e){return this.fn(e)},e.exports=i},82437:(e,t,r)=>{"use strict";var n=r(52344),i=r(90116),s=r(49803),a={addRefinement:function(e,t,r){if(a.isRefined(e,t,r))return e;var i=""+r,s=e[t]?e[t].concat(i):[i],c={};return c[t]=s,n({},c,e)},removeRefinement:function(e,t,r){if(void 0===r)return a.clearRefinement(e,(function(e,r){return t===r}));var n=""+r;return a.clearRefinement(e,(function(e,r){return t===r&&n===e}))},toggleRefinement:function(e,t,r){if(void 0===r)throw new Error("toggleRefinement should be used with a value");return a.isRefined(e,t,r)?a.removeRefinement(e,t,r):a.addRefinement(e,t,r)},clearRefinement:function(e,t,r){if(void 0===t)return i(e)?{}:e;if("string"==typeof t)return s(e,[t]);if("function"==typeof t){var n=!1,a=Object.keys(e).reduce((function(i,s){var a=e[s]||[],c=a.filter((function(e){return!t(e,s,r)}));return c.length!==a.length&&(n=!0),i[s]=c,i}),{});return n?a:e}},isRefined:function(e,t,r){var n=Boolean(e[t])&&e[t].length>0;if(void 0===r||!n)return n;var i=""+r;return-1!==e[t].indexOf(i)}};e.exports=a},17775:(e,t,r)=>{"use strict";var n=r(52344),i=r(7888),s=r(22686),a=r(60185),c=r(90116),u=r(49803),o=r(28023),h=r(46801),f=r(82437);function l(e,t){return Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((function(e,r){return l(t[r],e)})):e===t}function m(e){var t=e?m._parseNumbers(e):{};void 0===t.userToken||h(t.userToken)||console.warn("[algoliasearch-helper] The `userToken` parameter is invalid. This can lead to wrong analytics.\n - Format: [a-zA-Z0-9_-]{1,64}"),this.facets=t.facets||[],this.disjunctiveFacets=t.disjunctiveFacets||[],this.hierarchicalFacets=t.hierarchicalFacets||[],this.facetsRefinements=t.facetsRefinements||{},this.facetsExcludes=t.facetsExcludes||{},this.disjunctiveFacetsRefinements=t.disjunctiveFacetsRefinements||{},this.numericRefinements=t.numericRefinements||{},this.tagRefinements=t.tagRefinements||[],this.hierarchicalFacetsRefinements=t.hierarchicalFacetsRefinements||{};var r=this;Object.keys(t).forEach((function(e){var n=-1!==m.PARAMETERS.indexOf(e),i=void 0!==t[e];!n&&i&&(r[e]=t[e])}))}m.PARAMETERS=Object.keys(new m),m._parseNumbers=function(e){if(e instanceof m)return e;var t={};if(["aroundPrecision","aroundRadius","getRankingInfo","minWordSizefor2Typos","minWordSizefor1Typo","page","maxValuesPerFacet","distinct","minimumAroundRadius","hitsPerPage","minProximity"].forEach((function(r){var n=e[r];if("string"==typeof n){var i=parseFloat(n);t[r]=isNaN(i)?n:i}})),Array.isArray(e.insideBoundingBox)&&(t.insideBoundingBox=e.insideBoundingBox.map((function(e){return Array.isArray(e)?e.map((function(e){return parseFloat(e)})):e}))),e.numericRefinements){var r={};Object.keys(e.numericRefinements).forEach((function(t){var n=e.numericRefinements[t]||{};r[t]={},Object.keys(n).forEach((function(e){var i=n[e].map((function(e){return Array.isArray(e)?e.map((function(e){return"string"==typeof e?parseFloat(e):e})):"string"==typeof e?parseFloat(e):e}));r[t][e]=i}))})),t.numericRefinements=r}return a({},e,t)},m.make=function(e){var t=new m(e);return(e.hierarchicalFacets||[]).forEach((function(e){if(e.rootPath){var r=t.getHierarchicalRefinement(e.name);r.length>0&&0!==r[0].indexOf(e.rootPath)&&(t=t.clearRefinements(e.name)),0===(r=t.getHierarchicalRefinement(e.name)).length&&(t=t.toggleHierarchicalFacetRefinement(e.name,e.rootPath))}})),t},m.validate=function(e,t){var r=t||{};return e.tagFilters&&r.tagRefinements&&r.tagRefinements.length>0?new Error("[Tags] Cannot switch from the managed tag API to the advanced API. It is probably an error, if it is really what you want, you should first clear the tags with clearTags method."):e.tagRefinements.length>0&&r.tagFilters?new Error("[Tags] Cannot switch from the advanced tag API to the managed API. It is probably an error, if it is not, you should first clear the tags with clearTags method."):e.numericFilters&&r.numericRefinements&&c(r.numericRefinements)?new Error("[Numeric filters] Can't switch from the advanced to the managed API. It is probably an error, if this is really what you want, you have to first clear the numeric filters."):c(e.numericRefinements)&&r.numericFilters?new Error("[Numeric filters] Can't switch from the managed API to the advanced. It is probably an error, if this is really what you want, you have to first clear the numeric filters."):null},m.prototype={constructor:m,clearRefinements:function(e){var t={numericRefinements:this._clearNumericRefinements(e),facetsRefinements:f.clearRefinement(this.facetsRefinements,e,"conjunctiveFacet"),facetsExcludes:f.clearRefinement(this.facetsExcludes,e,"exclude"),disjunctiveFacetsRefinements:f.clearRefinement(this.disjunctiveFacetsRefinements,e,"disjunctiveFacet"),hierarchicalFacetsRefinements:f.clearRefinement(this.hierarchicalFacetsRefinements,e,"hierarchicalFacet")};return t.numericRefinements===this.numericRefinements&&t.facetsRefinements===this.facetsRefinements&&t.facetsExcludes===this.facetsExcludes&&t.disjunctiveFacetsRefinements===this.disjunctiveFacetsRefinements&&t.hierarchicalFacetsRefinements===this.hierarchicalFacetsRefinements?this:this.setQueryParameters(t)},clearTags:function(){return void 0===this.tagFilters&&0===this.tagRefinements.length?this:this.setQueryParameters({tagFilters:void 0,tagRefinements:[]})},setIndex:function(e){return e===this.index?this:this.setQueryParameters({index:e})},setQuery:function(e){return e===this.query?this:this.setQueryParameters({query:e})},setPage:function(e){return e===this.page?this:this.setQueryParameters({page:e})},setFacets:function(e){return this.setQueryParameters({facets:e})},setDisjunctiveFacets:function(e){return this.setQueryParameters({disjunctiveFacets:e})},setHitsPerPage:function(e){return this.hitsPerPage===e?this:this.setQueryParameters({hitsPerPage:e})},setTypoTolerance:function(e){return this.typoTolerance===e?this:this.setQueryParameters({typoTolerance:e})},addNumericRefinement:function(e,t,r){var n=o(r);if(this.isNumericRefined(e,t,n))return this;var i=a({},this.numericRefinements);return i[e]=a({},i[e]),i[e][t]?(i[e][t]=i[e][t].slice(),i[e][t].push(n)):i[e][t]=[n],this.setQueryParameters({numericRefinements:i})},getConjunctiveRefinements:function(e){return this.isConjunctiveFacet(e)&&this.facetsRefinements[e]||[]},getDisjunctiveRefinements:function(e){return this.isDisjunctiveFacet(e)&&this.disjunctiveFacetsRefinements[e]||[]},getHierarchicalRefinement:function(e){return this.hierarchicalFacetsRefinements[e]||[]},getExcludeRefinements:function(e){return this.isConjunctiveFacet(e)&&this.facetsExcludes[e]||[]},removeNumericRefinement:function(e,t,r){var n=r;return void 0!==n?this.isNumericRefined(e,t,n)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(r,i){return i===e&&r.op===t&&l(r.val,o(n))}))}):this:void 0!==t?this.isNumericRefined(e,t)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(r,n){return n===e&&r.op===t}))}):this:this.isNumericRefined(e)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(t,r){return r===e}))}):this},getNumericRefinements:function(e){return this.numericRefinements[e]||{}},getNumericRefinement:function(e,t){return this.numericRefinements[e]&&this.numericRefinements[e][t]},_clearNumericRefinements:function(e){if(void 0===e)return c(this.numericRefinements)?{}:this.numericRefinements;if("string"==typeof e)return u(this.numericRefinements,[e]);if("function"==typeof e){var t=!1,r=this.numericRefinements,n=Object.keys(r).reduce((function(n,i){var s=r[i],a={};return s=s||{},Object.keys(s).forEach((function(r){var n=s[r]||[],c=[];n.forEach((function(t){e({val:t,op:r},i,"numeric")||c.push(t)})),c.length!==n.length&&(t=!0),a[r]=c})),n[i]=a,n}),{});return t?n:this.numericRefinements}},addFacet:function(e){return this.isConjunctiveFacet(e)?this:this.setQueryParameters({facets:this.facets.concat([e])})},addDisjunctiveFacet:function(e){return this.isDisjunctiveFacet(e)?this:this.setQueryParameters({disjunctiveFacets:this.disjunctiveFacets.concat([e])})},addHierarchicalFacet:function(e){if(this.isHierarchicalFacet(e.name))throw new Error("Cannot declare two hierarchical facets with the same name: `"+e.name+"`");return this.setQueryParameters({hierarchicalFacets:this.hierarchicalFacets.concat([e])})},addFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsRefinements,e,t)?this:this.setQueryParameters({facetsRefinements:f.addRefinement(this.facetsRefinements,e,t)})},addExcludeRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsExcludes,e,t)?this:this.setQueryParameters({facetsExcludes:f.addRefinement(this.facetsExcludes,e,t)})},addDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return f.isRefined(this.disjunctiveFacetsRefinements,e,t)?this:this.setQueryParameters({disjunctiveFacetsRefinements:f.addRefinement(this.disjunctiveFacetsRefinements,e,t)})},addTagRefinement:function(e){if(this.isTagRefined(e))return this;var t={tagRefinements:this.tagRefinements.concat(e)};return this.setQueryParameters(t)},removeFacet:function(e){return this.isConjunctiveFacet(e)?this.clearRefinements(e).setQueryParameters({facets:this.facets.filter((function(t){return t!==e}))}):this},removeDisjunctiveFacet:function(e){return this.isDisjunctiveFacet(e)?this.clearRefinements(e).setQueryParameters({disjunctiveFacets:this.disjunctiveFacets.filter((function(t){return t!==e}))}):this},removeHierarchicalFacet:function(e){return this.isHierarchicalFacet(e)?this.clearRefinements(e).setQueryParameters({hierarchicalFacets:this.hierarchicalFacets.filter((function(t){return t.name!==e}))}):this},removeFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsRefinements,e,t)?this.setQueryParameters({facetsRefinements:f.removeRefinement(this.facetsRefinements,e,t)}):this},removeExcludeRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsExcludes,e,t)?this.setQueryParameters({facetsExcludes:f.removeRefinement(this.facetsExcludes,e,t)}):this},removeDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return f.isRefined(this.disjunctiveFacetsRefinements,e,t)?this.setQueryParameters({disjunctiveFacetsRefinements:f.removeRefinement(this.disjunctiveFacetsRefinements,e,t)}):this},removeTagRefinement:function(e){if(!this.isTagRefined(e))return this;var t={tagRefinements:this.tagRefinements.filter((function(t){return t!==e}))};return this.setQueryParameters(t)},toggleRefinement:function(e,t){return this.toggleFacetRefinement(e,t)},toggleFacetRefinement:function(e,t){if(this.isHierarchicalFacet(e))return this.toggleHierarchicalFacetRefinement(e,t);if(this.isConjunctiveFacet(e))return this.toggleConjunctiveFacetRefinement(e,t);if(this.isDisjunctiveFacet(e))return this.toggleDisjunctiveFacetRefinement(e,t);throw new Error("Cannot refine the undeclared facet "+e+"; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets")},toggleConjunctiveFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return this.setQueryParameters({facetsRefinements:f.toggleRefinement(this.facetsRefinements,e,t)})},toggleExcludeFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return this.setQueryParameters({facetsExcludes:f.toggleRefinement(this.facetsExcludes,e,t)})},toggleDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return this.setQueryParameters({disjunctiveFacetsRefinements:f.toggleRefinement(this.disjunctiveFacetsRefinements,e,t)})},toggleHierarchicalFacetRefinement:function(e,t){if(!this.isHierarchicalFacet(e))throw new Error(e+" is not defined in the hierarchicalFacets attribute of the helper configuration");var r=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e)),i={};return void 0!==this.hierarchicalFacetsRefinements[e]&&this.hierarchicalFacetsRefinements[e].length>0&&(this.hierarchicalFacetsRefinements[e][0]===t||0===this.hierarchicalFacetsRefinements[e][0].indexOf(t+r))?-1===t.indexOf(r)?i[e]=[]:i[e]=[t.slice(0,t.lastIndexOf(r))]:i[e]=[t],this.setQueryParameters({hierarchicalFacetsRefinements:n({},i,this.hierarchicalFacetsRefinements)})},addHierarchicalFacetRefinement:function(e,t){if(this.isHierarchicalFacetRefined(e))throw new Error(e+" is already refined.");if(!this.isHierarchicalFacet(e))throw new Error(e+" is not defined in the hierarchicalFacets attribute of the helper configuration.");var r={};return r[e]=[t],this.setQueryParameters({hierarchicalFacetsRefinements:n({},r,this.hierarchicalFacetsRefinements)})},removeHierarchicalFacetRefinement:function(e){if(!this.isHierarchicalFacetRefined(e))return this;var t={};return t[e]=[],this.setQueryParameters({hierarchicalFacetsRefinements:n({},t,this.hierarchicalFacetsRefinements)})},toggleTagRefinement:function(e){return this.isTagRefined(e)?this.removeTagRefinement(e):this.addTagRefinement(e)},isDisjunctiveFacet:function(e){return this.disjunctiveFacets.indexOf(e)>-1},isHierarchicalFacet:function(e){return void 0!==this.getHierarchicalFacetByName(e)},isConjunctiveFacet:function(e){return this.facets.indexOf(e)>-1},isFacetRefined:function(e,t){return!!this.isConjunctiveFacet(e)&&f.isRefined(this.facetsRefinements,e,t)},isExcludeRefined:function(e,t){return!!this.isConjunctiveFacet(e)&&f.isRefined(this.facetsExcludes,e,t)},isDisjunctiveFacetRefined:function(e,t){return!!this.isDisjunctiveFacet(e)&&f.isRefined(this.disjunctiveFacetsRefinements,e,t)},isHierarchicalFacetRefined:function(e,t){if(!this.isHierarchicalFacet(e))return!1;var r=this.getHierarchicalRefinement(e);return t?-1!==r.indexOf(t):r.length>0},isNumericRefined:function(e,t,r){if(void 0===r&&void 0===t)return Boolean(this.numericRefinements[e]);var n=this.numericRefinements[e]&&void 0!==this.numericRefinements[e][t];if(void 0===r||!n)return n;var s,a,c=o(r),u=void 0!==(s=this.numericRefinements[e][t],a=c,i(s,(function(e){return l(e,a)})));return n&&u},isTagRefined:function(e){return-1!==this.tagRefinements.indexOf(e)},getRefinedDisjunctiveFacets:function(){var e=this,t=s(Object.keys(this.numericRefinements).filter((function(t){return Object.keys(e.numericRefinements[t]).length>0})),this.disjunctiveFacets);return Object.keys(this.disjunctiveFacetsRefinements).filter((function(t){return e.disjunctiveFacetsRefinements[t].length>0})).concat(t).concat(this.getRefinedHierarchicalFacets()).sort()},getRefinedHierarchicalFacets:function(){var e=this;return s(this.hierarchicalFacets.map((function(e){return e.name})),Object.keys(this.hierarchicalFacetsRefinements).filter((function(t){return e.hierarchicalFacetsRefinements[t].length>0}))).sort()},getUnrefinedDisjunctiveFacets:function(){var e=this.getRefinedDisjunctiveFacets();return this.disjunctiveFacets.filter((function(t){return-1===e.indexOf(t)}))},managedParameters:["index","facets","disjunctiveFacets","facetsRefinements","hierarchicalFacets","facetsExcludes","disjunctiveFacetsRefinements","numericRefinements","tagRefinements","hierarchicalFacetsRefinements"],getQueryParams:function(){var e=this.managedParameters,t={},r=this;return Object.keys(this).forEach((function(n){var i=r[n];-1===e.indexOf(n)&&void 0!==i&&(t[n]=i)})),t},setQueryParameter:function(e,t){if(this[e]===t)return this;var r={};return r[e]=t,this.setQueryParameters(r)},setQueryParameters:function(e){if(!e)return this;var t=m.validate(this,e);if(t)throw t;var r=this,n=m._parseNumbers(e),i=Object.keys(this).reduce((function(e,t){return e[t]=r[t],e}),{}),s=Object.keys(n).reduce((function(e,t){var r=void 0!==e[t],i=void 0!==n[t];return r&&!i?u(e,[t]):(i&&(e[t]=n[t]),e)}),i);return new this.constructor(s)},resetPage:function(){return void 0===this.page?this:this.setPage(0)},_getHierarchicalFacetSortBy:function(e){return e.sortBy||["isRefined:desc","name:asc"]},_getHierarchicalFacetSeparator:function(e){return e.separator||" > "},_getHierarchicalRootPath:function(e){return e.rootPath||null},_getHierarchicalShowParentLevel:function(e){return"boolean"!=typeof e.showParentLevel||e.showParentLevel},getHierarchicalFacetByName:function(e){return i(this.hierarchicalFacets,(function(t){return t.name===e}))},getHierarchicalFacetBreadcrumb:function(e){if(!this.isHierarchicalFacet(e))return[];var t=this.getHierarchicalRefinement(e)[0];if(!t)return[];var r=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e));return t.split(r).map((function(e){return e.trim()}))},toString:function(){return JSON.stringify(this,null,2)}},e.exports=m},10210:(e,t,r)=>{"use strict";e.exports=function(e){return function(t,r){var n=e.hierarchicalFacets[r],o=e.hierarchicalFacetsRefinements[n.name]&&e.hierarchicalFacetsRefinements[n.name][0]||"",h=e._getHierarchicalFacetSeparator(n),f=e._getHierarchicalRootPath(n),l=e._getHierarchicalShowParentLevel(n),m=s(e._getHierarchicalFacetSortBy(n)),d=t.every((function(e){return e.exhaustive})),p=function(e,t,r,n,s){return function(o,h,f){var l=o;if(f>0){var m=0;for(l=o;m{"use strict";var n=r(74587),i=r(52344),s=r(94039),a=r(7888),c=r(69725),u=r(82293),o=r(60185),h=r(42148),f=s.escapeFacetValue,l=s.unescapeFacetValue,m=r(10210);function d(e){var t={};return e.forEach((function(e,r){t[e]=r})),t}function p(e,t,r){t&&t[r]&&(e.stats=t[r])}function v(e,t,r){var s=t[0];this._rawResults=t;var u=this;Object.keys(s).forEach((function(e){u[e]=s[e]})),Object.keys(r||{}).forEach((function(e){u[e]=r[e]})),this.processingTimeMS=t.reduce((function(e,t){return void 0===t.processingTimeMS?e:e+t.processingTimeMS}),0),this.disjunctiveFacets=[],this.hierarchicalFacets=e.hierarchicalFacets.map((function(){return[]})),this.facets=[];var h=e.getRefinedDisjunctiveFacets(),f=d(e.facets),v=d(e.disjunctiveFacets),g=1,y=s.facets||{};Object.keys(y).forEach((function(t){var r,n,i=y[t],o=(r=e.hierarchicalFacets,n=t,a(r,(function(e){return(e.attributes||[]).indexOf(n)>-1})));if(o){var h=o.attributes.indexOf(t),l=c(e.hierarchicalFacets,(function(e){return e.name===o.name}));u.hierarchicalFacets[l][h]={attribute:t,data:i,exhaustive:s.exhaustiveFacetsCount}}else{var m,d=-1!==e.disjunctiveFacets.indexOf(t),g=-1!==e.facets.indexOf(t);d&&(m=v[t],u.disjunctiveFacets[m]={name:t,data:i,exhaustive:s.exhaustiveFacetsCount},p(u.disjunctiveFacets[m],s.facets_stats,t)),g&&(m=f[t],u.facets[m]={name:t,data:i,exhaustive:s.exhaustiveFacetsCount},p(u.facets[m],s.facets_stats,t))}})),this.hierarchicalFacets=n(this.hierarchicalFacets),h.forEach((function(r){var n=t[g],a=n&&n.facets?n.facets:{},h=e.getHierarchicalFacetByName(r);Object.keys(a).forEach((function(t){var r,f=a[t];if(h){r=c(e.hierarchicalFacets,(function(e){return e.name===h.name}));var m=c(u.hierarchicalFacets[r],(function(e){return e.attribute===t}));if(-1===m)return;u.hierarchicalFacets[r][m].data=o({},u.hierarchicalFacets[r][m].data,f)}else{r=v[t];var d=s.facets&&s.facets[t]||{};u.disjunctiveFacets[r]={name:t,data:i({},f,d),exhaustive:n.exhaustiveFacetsCount},p(u.disjunctiveFacets[r],n.facets_stats,t),e.disjunctiveFacetsRefinements[t]&&e.disjunctiveFacetsRefinements[t].forEach((function(n){!u.disjunctiveFacets[r].data[n]&&e.disjunctiveFacetsRefinements[t].indexOf(l(n))>-1&&(u.disjunctiveFacets[r].data[n]=0)}))}})),g++})),e.getRefinedHierarchicalFacets().forEach((function(r){var n=e.getHierarchicalFacetByName(r),s=e._getHierarchicalFacetSeparator(n),a=e.getHierarchicalRefinement(r);0===a.length||a[0].split(s).length<2||t.slice(g).forEach((function(t){var r=t&&t.facets?t.facets:{};Object.keys(r).forEach((function(t){var o=r[t],h=c(e.hierarchicalFacets,(function(e){return e.name===n.name})),f=c(u.hierarchicalFacets[h],(function(e){return e.attribute===t}));if(-1!==f){var l={};if(a.length>0){var m=a[0].split(s)[0];l[m]=u.hierarchicalFacets[h][f].data[m]}u.hierarchicalFacets[h][f].data=i(l,o,u.hierarchicalFacets[h][f].data)}})),g++}))})),Object.keys(e.facetsExcludes).forEach((function(t){var r=e.facetsExcludes[t],n=f[t];u.facets[n]={name:t,data:y[t],exhaustive:s.exhaustiveFacetsCount},r.forEach((function(e){u.facets[n]=u.facets[n]||{name:t},u.facets[n].data=u.facets[n].data||{},u.facets[n].data[e]=0}))})),this.hierarchicalFacets=this.hierarchicalFacets.map(m(e)),this.facets=n(this.facets),this.disjunctiveFacets=n(this.disjunctiveFacets),this._state=e}function g(e,t){function r(e){return e.name===t}if(e._state.isConjunctiveFacet(t)){var n=a(e.facets,r);return n?Object.keys(n.data).map((function(r){var i=f(r);return{name:r,escapedValue:i,count:n.data[r],isRefined:e._state.isFacetRefined(t,i),isExcluded:e._state.isExcludeRefined(t,r)}})):[]}if(e._state.isDisjunctiveFacet(t)){var i=a(e.disjunctiveFacets,r);return i?Object.keys(i.data).map((function(r){var n=f(r);return{name:r,escapedValue:n,count:i.data[r],isRefined:e._state.isDisjunctiveFacetRefined(t,n)}})):[]}if(e._state.isHierarchicalFacet(t)){var s=a(e.hierarchicalFacets,r);if(!s)return s;var c=e._state.getHierarchicalFacetByName(t),u=e._state._getHierarchicalFacetSeparator(c),o=l(e._state.getHierarchicalRefinement(t)[0]||"");0===o.indexOf(c.rootPath)&&(o=o.replace(c.rootPath+u,""));var h=o.split(u);return h.unshift(t),y(s,h,0),s}}function y(e,t,r){e.isRefined=e.name===t[r],e.data&&e.data.forEach((function(e){y(e,t,r+1)}))}function R(e,t,r,n){if(n=n||0,Array.isArray(t))return e(t,r[n]);if(!t.data||0===t.data.length)return t;var s=t.data.map((function(t){return R(e,t,r,n+1)})),a=e(s,r[n]);return i({data:a},t)}function F(e,t){var r=a(e,(function(e){return e.name===t}));return r&&r.stats}function b(e,t,r,n,i){var s=a(i,(function(e){return e.name===r})),c=s&&s.data&&s.data[n]?s.data[n]:0,u=s&&s.exhaustive||!1;return{type:t,attributeName:r,name:n,count:c,exhaustive:u}}v.prototype.getFacetByName=function(e){function t(t){return t.name===e}return a(this.facets,t)||a(this.disjunctiveFacets,t)||a(this.hierarchicalFacets,t)},v.DEFAULT_SORT=["isRefined:desc","count:desc","name:asc"],v.prototype.getFacetValues=function(e,t){var r=g(this,e);if(r){var n,s=i({},t,{sortBy:v.DEFAULT_SORT,facetOrdering:!(t&&t.sortBy)}),a=this;if(Array.isArray(r))n=[e];else n=a._state.getHierarchicalFacetByName(r.name).attributes;return R((function(e,t){if(s.facetOrdering){var r=function(e,t){return e.renderingContent&&e.renderingContent.facetOrdering&&e.renderingContent.facetOrdering.values&&e.renderingContent.facetOrdering.values[t]}(a,t);if(r)return function(e,t){var r=[],n=[],i=(t.order||[]).reduce((function(e,t,r){return e[t]=r,e}),{});e.forEach((function(e){var t=e.path||e.name;void 0!==i[t]?r[i[t]]=e:n.push(e)})),r=r.filter((function(e){return e}));var s,a=t.sortRemainingBy;return"hidden"===a?r:(s="alpha"===a?[["path","name"],["asc","asc"]]:[["count"],["desc"]],r.concat(h(n,s[0],s[1])))}(e,r)}if(Array.isArray(s.sortBy)){var n=u(s.sortBy,v.DEFAULT_SORT);return h(e,n[0],n[1])}if("function"==typeof s.sortBy)return function(e,t){return t.sort(e)}(s.sortBy,e);throw new Error("options.sortBy is optional but if defined it must be either an array of string (predicates) or a sorting function")}),r,n)}},v.prototype.getFacetStats=function(e){return this._state.isConjunctiveFacet(e)?F(this.facets,e):this._state.isDisjunctiveFacet(e)?F(this.disjunctiveFacets,e):void 0},v.prototype.getRefinements=function(){var e=this._state,t=this,r=[];return Object.keys(e.facetsRefinements).forEach((function(n){e.facetsRefinements[n].forEach((function(i){r.push(b(e,"facet",n,i,t.facets))}))})),Object.keys(e.facetsExcludes).forEach((function(n){e.facetsExcludes[n].forEach((function(i){r.push(b(e,"exclude",n,i,t.facets))}))})),Object.keys(e.disjunctiveFacetsRefinements).forEach((function(n){e.disjunctiveFacetsRefinements[n].forEach((function(i){r.push(b(e,"disjunctive",n,i,t.disjunctiveFacets))}))})),Object.keys(e.hierarchicalFacetsRefinements).forEach((function(n){e.hierarchicalFacetsRefinements[n].forEach((function(i){r.push(function(e,t,r,n){var i=e.getHierarchicalFacetByName(t),s=e._getHierarchicalFacetSeparator(i),c=r.split(s),u=a(n,(function(e){return e.name===t})),o=c.reduce((function(e,t){var r=e&&a(e.data,(function(e){return e.name===t}));return void 0!==r?r:e}),u),h=o&&o.count||0,f=o&&o.exhaustive||!1,l=o&&o.path||"";return{type:"hierarchical",attributeName:t,name:l,count:h,exhaustive:f}}(e,n,i,t.hierarchicalFacets))}))})),Object.keys(e.numericRefinements).forEach((function(t){var n=e.numericRefinements[t];Object.keys(n).forEach((function(e){n[e].forEach((function(n){r.push({type:"numeric",attributeName:t,name:n,numericValue:n,operator:e})}))}))})),e.tagRefinements.forEach((function(e){r.push({type:"tag",attributeName:"_tags",name:e})})),r},e.exports=v},49374:(e,t,r)=>{"use strict";var n=r(17331),i=r(68078),s=r(94039).escapeFacetValue,a=r(14853),c=r(60185),u=r(90116),o=r(49803),h=r(96394),f=r(17775),l=r(23076),m=r(24336);function d(e,t,r){"function"==typeof e.addAlgoliaAgent&&e.addAlgoliaAgent("JS Helper ("+m+")"),this.setClient(e);var n=r||{};n.index=t,this.state=f.make(n),this.lastResults=null,this._queryId=0,this._lastQueryIdReceived=-1,this.derivedHelpers=[],this._currentNbQueries=0}function p(e){if(e<0)throw new Error("Page requested below 0.");return this._change({state:this.state.setPage(e),isPageReset:!1}),this}function v(){return this.state.page}a(d,n),d.prototype.search=function(){return this._search({onlyWithDerivedHelpers:!1}),this},d.prototype.searchOnlyWithDerivedHelpers=function(){return this._search({onlyWithDerivedHelpers:!0}),this},d.prototype.getQuery=function(){var e=this.state;return h._getHitsSearchParams(e)},d.prototype.searchOnce=function(e,t){var r=e?this.state.setQueryParameters(e):this.state,n=h._getQueries(r.index,r),i=this;if(this._currentNbQueries++,this.emit("searchOnce",{state:r}),!t)return this.client.search(n).then((function(e){return i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),{content:new l(r,e.results),state:r,_originalResponse:e}}),(function(e){throw i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),e}));this.client.search(n).then((function(e){i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),t(null,new l(r,e.results),r)})).catch((function(e){i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),t(e,null,r)}))},d.prototype.findAnswers=function(e){console.warn("[algoliasearch-helper] answers is no longer supported");var t=this.state,r=this.derivedHelpers[0];if(!r)return Promise.resolve([]);var n=r.getModifiedState(t),i=c({attributesForPrediction:e.attributesForPrediction,nbHits:e.nbHits},{params:o(h._getHitsSearchParams(n),["attributesToSnippet","hitsPerPage","restrictSearchableAttributes","snippetEllipsisText"])}),s="search for answers was called, but this client does not have a function client.initIndex(index).findAnswers";if("function"!=typeof this.client.initIndex)throw new Error(s);var a=this.client.initIndex(n.index);if("function"!=typeof a.findAnswers)throw new Error(s);return a.findAnswers(n.query,e.queryLanguages,i)},d.prototype.searchForFacetValues=function(e,t,r,n){var i="function"==typeof this.client.searchForFacetValues,a="function"==typeof this.client.initIndex;if(!i&&!a&&"function"!=typeof this.client.search)throw new Error("search for facet values (searchable) was called, but this client does not have a function client.searchForFacetValues or client.initIndex(index).searchForFacetValues");var c=this.state.setQueryParameters(n||{}),u=c.isDisjunctiveFacet(e),o=h.getSearchForFacetQuery(e,t,r,c);this._currentNbQueries++;var f,l=this;return i?f=this.client.searchForFacetValues([{indexName:c.index,params:o}]):a?f=this.client.initIndex(c.index).searchForFacetValues(o):(delete o.facetName,f=this.client.search([{type:"facet",facet:e,indexName:c.index,params:o}]).then((function(e){return e.results[0]}))),this.emit("searchForFacetValues",{state:c,facet:e,query:t}),f.then((function(t){return l._currentNbQueries--,0===l._currentNbQueries&&l.emit("searchQueueEmpty"),(t=Array.isArray(t)?t[0]:t).facetHits.forEach((function(t){t.escapedValue=s(t.value),t.isRefined=u?c.isDisjunctiveFacetRefined(e,t.escapedValue):c.isFacetRefined(e,t.escapedValue)})),t}),(function(e){throw l._currentNbQueries--,0===l._currentNbQueries&&l.emit("searchQueueEmpty"),e}))},d.prototype.setQuery=function(e){return this._change({state:this.state.resetPage().setQuery(e),isPageReset:!0}),this},d.prototype.clearRefinements=function(e){return this._change({state:this.state.resetPage().clearRefinements(e),isPageReset:!0}),this},d.prototype.clearTags=function(){return this._change({state:this.state.resetPage().clearTags(),isPageReset:!0}),this},d.prototype.addDisjunctiveFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addDisjunctiveFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.addDisjunctiveRefine=function(){return this.addDisjunctiveFacetRefinement.apply(this,arguments)},d.prototype.addHierarchicalFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addHierarchicalFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.addNumericRefinement=function(e,t,r){return this._change({state:this.state.resetPage().addNumericRefinement(e,t,r),isPageReset:!0}),this},d.prototype.addFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.addRefine=function(){return this.addFacetRefinement.apply(this,arguments)},d.prototype.addFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().addExcludeRefinement(e,t),isPageReset:!0}),this},d.prototype.addExclude=function(){return this.addFacetExclusion.apply(this,arguments)},d.prototype.addTag=function(e){return this._change({state:this.state.resetPage().addTagRefinement(e),isPageReset:!0}),this},d.prototype.removeNumericRefinement=function(e,t,r){return this._change({state:this.state.resetPage().removeNumericRefinement(e,t,r),isPageReset:!0}),this},d.prototype.removeDisjunctiveFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().removeDisjunctiveFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.removeDisjunctiveRefine=function(){return this.removeDisjunctiveFacetRefinement.apply(this,arguments)},d.prototype.removeHierarchicalFacetRefinement=function(e){return this._change({state:this.state.resetPage().removeHierarchicalFacetRefinement(e),isPageReset:!0}),this},d.prototype.removeFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().removeFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.removeRefine=function(){return this.removeFacetRefinement.apply(this,arguments)},d.prototype.removeFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().removeExcludeRefinement(e,t),isPageReset:!0}),this},d.prototype.removeExclude=function(){return this.removeFacetExclusion.apply(this,arguments)},d.prototype.removeTag=function(e){return this._change({state:this.state.resetPage().removeTagRefinement(e),isPageReset:!0}),this},d.prototype.toggleFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().toggleExcludeFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.toggleExclude=function(){return this.toggleFacetExclusion.apply(this,arguments)},d.prototype.toggleRefinement=function(e,t){return this.toggleFacetRefinement(e,t)},d.prototype.toggleFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().toggleFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.toggleRefine=function(){return this.toggleFacetRefinement.apply(this,arguments)},d.prototype.toggleTag=function(e){return this._change({state:this.state.resetPage().toggleTagRefinement(e),isPageReset:!0}),this},d.prototype.nextPage=function(){var e=this.state.page||0;return this.setPage(e+1)},d.prototype.previousPage=function(){var e=this.state.page||0;return this.setPage(e-1)},d.prototype.setCurrentPage=p,d.prototype.setPage=p,d.prototype.setIndex=function(e){return this._change({state:this.state.resetPage().setIndex(e),isPageReset:!0}),this},d.prototype.setQueryParameter=function(e,t){return this._change({state:this.state.resetPage().setQueryParameter(e,t),isPageReset:!0}),this},d.prototype.setState=function(e){return this._change({state:f.make(e),isPageReset:!1}),this},d.prototype.overrideStateWithoutTriggeringChangeEvent=function(e){return this.state=new f(e),this},d.prototype.hasRefinements=function(e){return!!u(this.state.getNumericRefinements(e))||(this.state.isConjunctiveFacet(e)?this.state.isFacetRefined(e):this.state.isDisjunctiveFacet(e)?this.state.isDisjunctiveFacetRefined(e):!!this.state.isHierarchicalFacet(e)&&this.state.isHierarchicalFacetRefined(e))},d.prototype.isExcluded=function(e,t){return this.state.isExcludeRefined(e,t)},d.prototype.isDisjunctiveRefined=function(e,t){return this.state.isDisjunctiveFacetRefined(e,t)},d.prototype.hasTag=function(e){return this.state.isTagRefined(e)},d.prototype.isTagRefined=function(){return this.hasTagRefinements.apply(this,arguments)},d.prototype.getIndex=function(){return this.state.index},d.prototype.getCurrentPage=v,d.prototype.getPage=v,d.prototype.getTags=function(){return this.state.tagRefinements},d.prototype.getRefinements=function(e){var t=[];if(this.state.isConjunctiveFacet(e))this.state.getConjunctiveRefinements(e).forEach((function(e){t.push({value:e,type:"conjunctive"})})),this.state.getExcludeRefinements(e).forEach((function(e){t.push({value:e,type:"exclude"})}));else if(this.state.isDisjunctiveFacet(e)){this.state.getDisjunctiveRefinements(e).forEach((function(e){t.push({value:e,type:"disjunctive"})}))}var r=this.state.getNumericRefinements(e);return Object.keys(r).forEach((function(e){var n=r[e];t.push({value:n,operator:e,type:"numeric"})})),t},d.prototype.getNumericRefinement=function(e,t){return this.state.getNumericRefinement(e,t)},d.prototype.getHierarchicalFacetBreadcrumb=function(e){return this.state.getHierarchicalFacetBreadcrumb(e)},d.prototype._search=function(e){var t=this.state,r=[],n=[];e.onlyWithDerivedHelpers||(n=h._getQueries(t.index,t),r.push({state:t,queriesCount:n.length,helper:this}),this.emit("search",{state:t,results:this.lastResults}));var i=this.derivedHelpers.map((function(e){var n=e.getModifiedState(t),i=n.index?h._getQueries(n.index,n):[];return r.push({state:n,queriesCount:i.length,helper:e}),e.emit("search",{state:n,results:e.lastResults}),i})),s=Array.prototype.concat.apply(n,i),a=this._queryId++;if(this._currentNbQueries++,!s.length)return Promise.resolve({results:[]}).then(this._dispatchAlgoliaResponse.bind(this,r,a));try{this.client.search(s).then(this._dispatchAlgoliaResponse.bind(this,r,a)).catch(this._dispatchAlgoliaError.bind(this,a))}catch(c){this.emit("error",{error:c})}},d.prototype._dispatchAlgoliaResponse=function(e,t,r){if(!(t0},d.prototype._change=function(e){var t=e.state,r=e.isPageReset;t!==this.state&&(this.state=t,this.emit("change",{state:this.state,results:this.lastResults,isPageReset:r}))},d.prototype.clearCache=function(){return this.client.clearCache&&this.client.clearCache(),this},d.prototype.setClient=function(e){return this.client===e||("function"==typeof e.addAlgoliaAgent&&e.addAlgoliaAgent("JS Helper ("+m+")"),this.client=e),this},d.prototype.getClient=function(){return this.client},d.prototype.derive=function(e){var t=new i(this,e);return this.derivedHelpers.push(t),t},d.prototype.detachDerivedHelper=function(e){var t=this.derivedHelpers.indexOf(e);if(-1===t)throw new Error("Derived helper already detached");this.derivedHelpers.splice(t,1)},d.prototype.hasPendingRequests=function(){return this._currentNbQueries>0},e.exports=d},74587:e=>{"use strict";e.exports=function(e){return Array.isArray(e)?e.filter(Boolean):[]}},52344:e=>{"use strict";e.exports=function(){return Array.prototype.slice.call(arguments).reduceRight((function(e,t){return Object.keys(Object(t)).forEach((function(r){void 0!==t[r]&&(void 0!==e[r]&&delete e[r],e[r]=t[r])})),e}),{})}},94039:e=>{"use strict";e.exports={escapeFacetValue:function(e){return"string"!=typeof e?e:String(e).replace(/^-/,"\\-")},unescapeFacetValue:function(e){return"string"!=typeof e?e:e.replace(/^\\-/,"-")}}},7888:e=>{"use strict";e.exports=function(e,t){if(Array.isArray(e))for(var r=0;r{"use strict";e.exports=function(e,t){if(!Array.isArray(e))return-1;for(var r=0;r{"use strict";var n=r(7888);e.exports=function(e,t){var r=(t||[]).map((function(e){return e.split(":")}));return e.reduce((function(e,t){var i=t.split(":"),s=n(r,(function(e){return e[0]===i[0]}));return i.length>1||!s?(e[0].push(i[0]),e[1].push(i[1]),e):(e[0].push(s[0]),e[1].push(s[1]),e)}),[[],[]])}},14853:e=>{"use strict";e.exports=function(e,t){e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}},22686:e=>{"use strict";e.exports=function(e,t){return e.filter((function(r,n){return t.indexOf(r)>-1&&e.indexOf(r)===n}))}},60185:e=>{"use strict";function t(e){return"function"==typeof e||Array.isArray(e)||"[object Object]"===Object.prototype.toString.call(e)}function r(e,n){if(e===n)return e;for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)&&"__proto__"!==i&&"constructor"!==i){var s=n[i],a=e[i];void 0!==a&&void 0===s||(t(a)&&t(s)?e[i]=r(a,s):e[i]="object"==typeof(c=s)&&null!==c?r(Array.isArray(c)?[]:{},c):c)}var c;return e}e.exports=function(e){t(e)||(e={});for(var n=1,i=arguments.length;n{"use strict";e.exports=function(e){return e&&Object.keys(e).length>0}},49803:e=>{"use strict";e.exports=function(e,t){if(null===e)return{};var r,n,i={},s=Object.keys(e);for(n=0;n=0||(i[r]=e[r]);return i}},42148:e=>{"use strict";function t(e,t){if(e!==t){var r=void 0!==e,n=null===e,i=void 0!==t,s=null===t;if(!s&&e>t||n&&i||!r)return 1;if(!n&&e=n.length?s:"desc"===n[i]?-s:s}return e.index-r.index})),i.map((function(e){return e.value}))}},28023:e=>{"use strict";e.exports=function e(t){if("number"==typeof t)return t;if("string"==typeof t)return parseFloat(t);if(Array.isArray(t))return t.map(e);throw new Error("The value should be a number, a parsable string or an array of those.")}},96394:(e,t,r)=>{"use strict";var n=r(60185);function i(e){return Object.keys(e).sort().reduce((function(t,r){return t[r]=e[r],t}),{})}var s={_getQueries:function(e,t){var r=[];return r.push({indexName:e,params:s._getHitsSearchParams(t)}),t.getRefinedDisjunctiveFacets().forEach((function(n){r.push({indexName:e,params:s._getDisjunctiveFacetSearchParams(t,n)})})),t.getRefinedHierarchicalFacets().forEach((function(n){var i=t.getHierarchicalFacetByName(n),a=t.getHierarchicalRefinement(n),c=t._getHierarchicalFacetSeparator(i);if(a.length>0&&a[0].split(c).length>1){var u=a[0].split(c).slice(0,-1).reduce((function(e,t,r){return e.concat({attribute:i.attributes[r],value:0===r?t:[e[e.length-1].value,t].join(c)})}),[]);u.forEach((function(n,a){var c=s._getDisjunctiveFacetSearchParams(t,n.attribute,0===a);function o(e){return i.attributes.some((function(t){return t===e.split(":")[0]}))}var h=(c.facetFilters||[]).reduce((function(e,t){if(Array.isArray(t)){var r=t.filter((function(e){return!o(e)}));r.length>0&&e.push(r)}return"string"!=typeof t||o(t)||e.push(t),e}),[]),f=u[a-1];c.facetFilters=a>0?h.concat(f.attribute+":"+f.value):h.length>0?h:void 0,r.push({indexName:e,params:c})}))}})),r},_getHitsSearchParams:function(e){var t=e.facets.concat(e.disjunctiveFacets).concat(s._getHitsHierarchicalFacetsAttributes(e)).sort(),r=s._getFacetFilters(e),a=s._getNumericFilters(e),c=s._getTagFilters(e),u={facets:t.indexOf("*")>-1?["*"]:t,tagFilters:c};return r.length>0&&(u.facetFilters=r),a.length>0&&(u.numericFilters=a),i(n({},e.getQueryParams(),u))},_getDisjunctiveFacetSearchParams:function(e,t,r){var a=s._getFacetFilters(e,t,r),c=s._getNumericFilters(e,t),u=s._getTagFilters(e),o={hitsPerPage:0,page:0,analytics:!1,clickAnalytics:!1};u.length>0&&(o.tagFilters=u);var h=e.getHierarchicalFacetByName(t);return o.facets=h?s._getDisjunctiveHierarchicalFacetAttribute(e,h,r):t,c.length>0&&(o.numericFilters=c),a.length>0&&(o.facetFilters=a),i(n({},e.getQueryParams(),o))},_getNumericFilters:function(e,t){if(e.numericFilters)return e.numericFilters;var r=[];return Object.keys(e.numericRefinements).forEach((function(n){var i=e.numericRefinements[n]||{};Object.keys(i).forEach((function(e){var s=i[e]||[];t!==n&&s.forEach((function(t){if(Array.isArray(t)){var i=t.map((function(t){return n+e+t}));r.push(i)}else r.push(n+e+t)}))}))})),r},_getTagFilters:function(e){return e.tagFilters?e.tagFilters:e.tagRefinements.join(",")},_getFacetFilters:function(e,t,r){var n=[],i=e.facetsRefinements||{};Object.keys(i).sort().forEach((function(e){(i[e]||[]).sort().forEach((function(t){n.push(e+":"+t)}))}));var s=e.facetsExcludes||{};Object.keys(s).sort().forEach((function(e){(s[e]||[]).sort().forEach((function(t){n.push(e+":-"+t)}))}));var a=e.disjunctiveFacetsRefinements||{};Object.keys(a).sort().forEach((function(e){var r=a[e]||[];if(e!==t&&r&&0!==r.length){var i=[];r.sort().forEach((function(t){i.push(e+":"+t)})),n.push(i)}}));var c=e.hierarchicalFacetsRefinements||{};return Object.keys(c).sort().forEach((function(i){var s=(c[i]||[])[0];if(void 0!==s){var a,u,o=e.getHierarchicalFacetByName(i),h=e._getHierarchicalFacetSeparator(o),f=e._getHierarchicalRootPath(o);if(t===i){if(-1===s.indexOf(h)||!f&&!0===r||f&&f.split(h).length===s.split(h).length)return;f?(u=f.split(h).length-1,s=f):(u=s.split(h).length-2,s=s.slice(0,s.lastIndexOf(h))),a=o.attributes[u]}else u=s.split(h).length-1,a=o.attributes[u];a&&n.push([a+":"+s])}})),n},_getHitsHierarchicalFacetsAttributes:function(e){return e.hierarchicalFacets.reduce((function(t,r){var n=e.getHierarchicalRefinement(r.name)[0];if(!n)return t.push(r.attributes[0]),t;var i=e._getHierarchicalFacetSeparator(r),s=n.split(i).length,a=r.attributes.slice(0,s+1);return t.concat(a)}),[])},_getDisjunctiveHierarchicalFacetAttribute:function(e,t,r){var n=e._getHierarchicalFacetSeparator(t);if(!0===r){var i=e._getHierarchicalRootPath(t),s=0;return i&&(s=i.split(n).length),[t.attributes[s]]}var a=(e.getHierarchicalRefinement(t.name)[0]||"").split(n).length-1;return t.attributes.slice(0,a+1)},getSearchForFacetQuery:function(e,t,r,a){var c=a.isDisjunctiveFacet(e)?a.clearRefinements(e):a,u={facetQuery:t,facetName:e};return"number"==typeof r&&(u.maxFacetHits=r),i(n({},s._getHitsSearchParams(c),u))}};e.exports=s},46801:e=>{"use strict";e.exports=function(e){return null!==e&&/^[a-zA-Z0-9_-]{1,64}$/.test(e)}},24336:e=>{"use strict";e.exports="3.15.0"},70290:function(e){e.exports=function(){"use strict";function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function r(r){for(var n=1;n=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)){var r=[],n=!0,i=!1,s=void 0;try{for(var a,c=e[Symbol.iterator]();!(n=(a=c.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){i=!0,s=e}finally{try{n||null==c.return||c.return()}finally{if(i)throw s}}return r}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function s(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return Promise.resolve().then((function(){c();var t=JSON.stringify(e);return s()[t]})).then((function(e){return Promise.all([e?e.value:t(),void 0!==e])})).then((function(e){var t=i(e,2),n=t[0],s=t[1];return Promise.all([n,s||r.miss(n)])})).then((function(e){return i(e,1)[0]}))},set:function(e,t){return Promise.resolve().then((function(){var i=s();return i[JSON.stringify(e)]={timestamp:(new Date).getTime(),value:t},n().setItem(r,JSON.stringify(i)),t}))},delete:function(e){return Promise.resolve().then((function(){var t=s();delete t[JSON.stringify(e)],n().setItem(r,JSON.stringify(t))}))},clear:function(){return Promise.resolve().then((function(){n().removeItem(r)}))}}}function c(e){var t=s(e.caches),r=t.shift();return void 0===r?{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return t().then((function(e){return Promise.all([e,r.miss(e)])})).then((function(e){return i(e,1)[0]}))},set:function(e,t){return Promise.resolve(t)},delete:function(e){return Promise.resolve()},clear:function(){return Promise.resolve()}}:{get:function(e,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return r.get(e,n,i).catch((function(){return c({caches:t}).get(e,n,i)}))},set:function(e,n){return r.set(e,n).catch((function(){return c({caches:t}).set(e,n)}))},delete:function(e){return r.delete(e).catch((function(){return c({caches:t}).delete(e)}))},clear:function(){return r.clear().catch((function(){return c({caches:t}).clear()}))}}}function u(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{serializable:!0},t={};return{get:function(r,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},s=JSON.stringify(r);if(s in t)return Promise.resolve(e.serializable?JSON.parse(t[s]):t[s]);var a=n(),c=i&&i.miss||function(){return Promise.resolve()};return a.then((function(e){return c(e)})).then((function(){return a}))},set:function(r,n){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(n):n,Promise.resolve(n)},delete:function(e){return delete t[JSON.stringify(e)],Promise.resolve()},clear:function(){return t={},Promise.resolve()}}}function o(e){for(var t=e.length-1;t>0;t--){var r=Math.floor(Math.random()*(t+1)),n=e[t];e[t]=e[r],e[r]=n}return e}function h(e,t){return t?(Object.keys(t).forEach((function(r){e[r]=t[r](e)})),e):e}function f(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n0?n:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var d={Read:1,Write:2,Any:3},p=1,v=2,g=3;function y(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;return r(r({},e),{},{status:t,lastUpdate:Date.now()})}function R(e){return"string"==typeof e?{protocol:"https",url:e,accept:d.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||d.Any}}var F="GET",b="POST";function j(e,t){return Promise.all(t.map((function(t){return e.get(t,(function(){return Promise.resolve(y(t))}))}))).then((function(e){var r=e.filter((function(e){return function(e){return e.status===p||Date.now()-e.lastUpdate>12e4}(e)})),n=e.filter((function(e){return function(e){return e.status===g&&Date.now()-e.lastUpdate<=12e4}(e)})),i=[].concat(s(r),s(n));return{getTimeout:function(e,t){return(0===n.length&&0===e?1:n.length+3+e)*t},statelessHosts:i.length>0?i.map((function(e){return R(e)})):t}}))}function P(e,t,n,i){var a=[],c=function(e,t){if(e.method!==F&&(void 0!==e.data||void 0!==t.data)){var n=Array.isArray(e.data)?e.data:r(r({},e.data),t.data);return JSON.stringify(n)}}(n,i),u=function(e,t){var n=r(r({},e.headers),t.headers),i={};return Object.keys(n).forEach((function(e){var t=n[e];i[e.toLowerCase()]=t})),i}(e,i),o=n.method,h=n.method!==F?{}:r(r({},n.data),i.data),f=r(r(r({"x-algolia-agent":e.userAgent.value},e.queryParameters),h),i.queryParameters),l=0,m=function t(r,s){var h=r.pop();if(void 0===h)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:w(a)};var m={data:c,headers:u,method:o,url:_(h,n.path,f),connectTimeout:s(l,e.timeouts.connect),responseTimeout:s(l,i.timeout)},d=function(e){var t={request:m,response:e,host:h,triesLeft:r.length};return a.push(t),t},p={onSuccess:function(e){return function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e)},onRetry:function(n){var i=d(n);return n.isTimedOut&&l++,Promise.all([e.logger.info("Retryable failure",O(i)),e.hostsCache.set(h,y(h,n.isTimedOut?g:v))]).then((function(){return t(r,s)}))},onFail:function(e){throw d(e),function(e,t){var r=e.content,n=e.status,i=r;try{i=JSON.parse(r).message}catch(e){}return function(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}(i,n,t)}(e,w(a))}};return e.requester.send(m).then((function(e){return function(e,t){return function(e){var t=e.status;return e.isTimedOut||function(e){var t=e.isTimedOut,r=e.status;return!t&&0==~~r}(e)||2!=~~(t/100)&&4!=~~(t/100)}(e)?t.onRetry(e):2==~~(e.status/100)?t.onSuccess(e):t.onFail(e)}(e,p)}))};return j(e.hostsCache,t).then((function(e){return m(s(e.statelessHosts).reverse(),e.getTimeout)}))}function x(e){var t={value:"Algolia for JavaScript (".concat(e,")"),add:function(e){var r="; ".concat(e.segment).concat(void 0!==e.version?" (".concat(e.version,")"):"");return-1===t.value.indexOf(r)&&(t.value="".concat(t.value).concat(r)),t}};return t}function _(e,t,r){var n=E(r),i="".concat(e.protocol,"://").concat(e.url,"/").concat("/"===t.charAt(0)?t.substr(1):t);return n.length&&(i+="?".concat(n)),i}function E(e){return Object.keys(e).map((function(t){return f("%s=%s",t,(r=e[t],"[object Object]"===Object.prototype.toString.call(r)||"[object Array]"===Object.prototype.toString.call(r)?JSON.stringify(e[t]):e[t]));var r})).join("&")}function w(e){return e.map((function(e){return O(e)}))}function O(e){var t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return r(r({},e),{},{request:r(r({},e.request),{},{headers:r(r({},e.request.headers),t)})})}var N=function(e){var t=e.appId,n=function(e,t,r){var n={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers:function(){return e===l.WithinHeaders?n:{}},queryParameters:function(){return e===l.WithinQueryParameters?n:{}}}}(void 0!==e.authMode?e.authMode:l.WithinHeaders,t,e.apiKey),s=function(e){var t=e.hostsCache,r=e.logger,n=e.requester,s=e.requestsCache,a=e.responsesCache,c=e.timeouts,u=e.userAgent,o=e.hosts,h=e.queryParameters,f={hostsCache:t,logger:r,requester:n,requestsCache:s,responsesCache:a,timeouts:c,userAgent:u,headers:e.headers,queryParameters:h,hosts:o.map((function(e){return R(e)})),read:function(e,t){var r=m(t,f.timeouts.read),n=function(){return P(f,f.hosts.filter((function(e){return 0!=(e.accept&d.Read)})),e,r)};if(!0!==(void 0!==r.cacheable?r.cacheable:e.cacheable))return n();var s={request:e,mappedRequestOptions:r,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(s,(function(){return f.requestsCache.get(s,(function(){return f.requestsCache.set(s,n()).then((function(e){return Promise.all([f.requestsCache.delete(s),e])}),(function(e){return Promise.all([f.requestsCache.delete(s),Promise.reject(e)])})).then((function(e){var t=i(e,2);return t[0],t[1]}))}))}),{miss:function(e){return f.responsesCache.set(s,e)}})},write:function(e,t){return P(f,f.hosts.filter((function(e){return 0!=(e.accept&d.Write)})),e,m(t,f.timeouts.write))}};return f}(r(r({hosts:[{url:"".concat(t,"-dsn.algolia.net"),accept:d.Read},{url:"".concat(t,".algolia.net"),accept:d.Write}].concat(o([{url:"".concat(t,"-1.algolianet.com")},{url:"".concat(t,"-2.algolianet.com")},{url:"".concat(t,"-3.algolianet.com")}]))},e),{},{headers:r(r(r({},n.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:r(r({},n.queryParameters()),e.queryParameters)}));return h({transporter:s,appId:t,addAlgoliaAgent:function(e,t){s.userAgent.add({segment:e,version:t})},clearCache:function(){return Promise.all([s.requestsCache.clear(),s.responsesCache.clear()]).then((function(){}))}},e.methods)},A=function(e){return function(t,r){return t.method===F?e.transporter.read(t,r):e.transporter.write(t,r)}},H=function(e){return function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return h({transporter:e.transporter,appId:e.appId,indexName:t},r.methods)}},S=function(e){return function(t,n){var i=t.map((function(e){return r(r({},e),{},{params:E(e.params||{})})}));return e.transporter.read({method:b,path:"1/indexes/*/queries",data:{requests:i},cacheable:!0},n)}},T=function(e){return function(t,i){return Promise.all(t.map((function(t){var s=t.params,a=s.facetName,c=s.facetQuery,u=n(s,["facetName","facetQuery"]);return H(e)(t.indexName,{methods:{searchForFacetValues:I}}).searchForFacetValues(a,c,r(r({},i),u))})))}},Q=function(e){return function(t,r,n){return e.transporter.read({method:b,path:f("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:r},cacheable:!0},n)}},C=function(e){return function(t,r){return e.transporter.read({method:b,path:f("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r)}},I=function(e){return function(t,r,n){return e.transporter.read({method:b,path:f("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},n)}},D=1,k=2,q=3;function V(e,t,n){var i,s={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:function(e){return new Promise((function(t){var r=new XMLHttpRequest;r.open(e.method,e.url,!0),Object.keys(e.headers).forEach((function(t){return r.setRequestHeader(t,e.headers[t])}));var n,i=function(e,n){return setTimeout((function(){r.abort(),t({status:0,content:n,isTimedOut:!0})}),1e3*e)},s=i(e.connectTimeout,"Connection timeout");r.onreadystatechange=function(){r.readyState>r.OPENED&&void 0===n&&(clearTimeout(s),n=i(e.responseTimeout,"Socket timeout"))},r.onerror=function(){0===r.status&&(clearTimeout(s),clearTimeout(n),t({content:r.responseText||"Network request failed",status:r.status,isTimedOut:!1}))},r.onload=function(){clearTimeout(s),clearTimeout(n),t({content:r.responseText,status:r.status,isTimedOut:!1})},r.send(e.data)}))}},logger:(i=q,{debug:function(e,t){return D>=i&&console.debug(e,t),Promise.resolve()},info:function(e,t){return k>=i&&console.info(e,t),Promise.resolve()},error:function(e,t){return console.error(e,t),Promise.resolve()}}),responsesCache:u(),requestsCache:u({serializable:!1}),hostsCache:c({caches:[a({key:"".concat("4.20.0","-").concat(e)}),u()]}),userAgent:x("4.20.0").add({segment:"Browser",version:"lite"}),authMode:l.WithinQueryParameters};return N(r(r(r({},s),n),{},{methods:{search:S,searchForFacetValues:T,multipleQueries:S,multipleSearchForFacetValues:T,customRequest:A,initIndex:function(e){return function(t){return H(e)(t,{methods:{search:C,searchForFacetValues:I,findAnswers:Q}})}}}}))}return V.version="4.20.0",V}()},88824:(e,t,r)=>{"use strict";r.d(t,{c:()=>o});var n=r(67294),i=r(52263);const s=["zero","one","two","few","many","other"];function a(e){return s.filter((t=>e.includes(t)))}const c={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,i.Z)();return(0,n.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),c}}),[e])}function o(){const e=u();return{selectMessage:(t,r)=>function(e,t,r){const n=e.split("|");if(1===n.length)return n[0];n.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const i=r.select(t),s=r.pluralForms.indexOf(i);return n[Math.min(s,n.length-1)]}(r,t,e)}}},39172:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>O});var n=r(67294),i=r(86010),s=r(8131),a=r.n(s),c=r(70290),u=r.n(c),o=r(10412),h=r(35742),f=r(39960),l=r(80143),m=r(88824),d=r(66177),p=r(902),v=r(10833),g=r(82128),y=r(95999),R=r(52263),F=r(6278),b=r(239),j=r(58207),P=r(92503);const x={searchQueryInput:"searchQueryInput_u2C7",searchVersionInput:"searchVersionInput_m0Ui",searchResultsColumn:"searchResultsColumn_JPFH",algoliaLogo:"algoliaLogo_rT1R",algoliaLogoPathFill:"algoliaLogoPathFill_WdUC",searchResultItem:"searchResultItem_Tv2o",searchResultItemHeading:"searchResultItemHeading_KbCB",searchResultItemPath:"searchResultItemPath_lhe1",searchResultItemSummary:"searchResultItemSummary_AEaO",searchQueryColumn:"searchQueryColumn_RTkw",searchVersionColumn:"searchVersionColumn_ypXd",searchLogoColumn:"searchLogoColumn_rJIA",loadingSpinner:"loadingSpinner_XVxU","loading-spin":"loading-spin_vzvp",loader:"loader_vvXV"};var _=r(85893);function E(e){let{docsSearchVersionsHelpers:t}=e;const r=Object.entries(t.allDocsData).filter((e=>{let[,t]=e;return t.versions.length>1}));return(0,_.jsx)("div",{className:(0,i.Z)("col","col--3","padding-left--none",x.searchVersionColumn),children:r.map((e=>{let[n,i]=e;const s=r.length>1?`${n}: `:"";return(0,_.jsx)("select",{onChange:e=>t.setSearchVersion(n,e.target.value),defaultValue:t.searchVersions[n],className:x.searchVersionInput,children:i.versions.map(((e,t)=>(0,_.jsx)("option",{label:`${s}${e.label}`,value:e.name},t)))},n)}))})}function w(){const{i18n:{currentLocale:e}}=(0,R.Z)(),{algolia:{appId:t,apiKey:r,indexName:s}}=(0,F.L)(),c=(0,b.l)(),v=function(){const{selectMessage:e}=(0,m.c)();return t=>e(t,(0,y.I)({id:"theme.SearchPage.documentsFound.plurals",description:'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One document found|{count} documents found"},{count:t}))}(),w=function(){const e=(0,l._r)(),[t,r]=(0,n.useState)((()=>Object.entries(e).reduce(((e,t)=>{let[r,n]=t;return{...e,[r]:n.versions[0].name}}),{}))),i=Object.values(e).some((e=>e.versions.length>1));return{allDocsData:e,versioningEnabled:i,searchVersions:t,setSearchVersion:(e,t)=>r((r=>({...r,[e]:t})))}}(),[O,N]=(0,d.K)(),A={items:[],query:null,totalResults:null,totalPages:null,lastPage:null,hasMore:null,loading:null},[H,S]=(0,n.useReducer)(((e,t)=>{switch(t.type){case"reset":return A;case"loading":return{...e,loading:!0};case"update":return O!==t.value.query?e:{...t.value,items:0===t.value.lastPage?t.value.items:e.items.concat(t.value.items)};case"advance":{const t=e.totalPages>e.lastPage+1;return{...e,lastPage:t?e.lastPage+1:e.lastPage,hasMore:t}}default:return e}}),A),T=u()(t,r),Q=a()(T,s,{hitsPerPage:15,advancedSyntax:!0,disjunctiveFacets:["language","docusaurus_tag"]});Q.on("result",(e=>{let{results:{query:t,hits:r,page:n,nbHits:i,nbPages:s}}=e;if(""===t||!Array.isArray(r))return void S({type:"reset"});const a=e=>e.replace(/algolia-docsearch-suggestion--highlight/g,"search-result-match"),u=r.map((e=>{let{url:t,_highlightResult:{hierarchy:r},_snippetResult:n={}}=e;const i=Object.keys(r).map((e=>a(r[e].value)));return{title:i.pop(),url:c(t),summary:n.content?`${a(n.content.value)}...`:"",breadcrumbs:i}}));S({type:"update",value:{items:u,query:t,totalResults:i,totalPages:s,lastPage:n,hasMore:s>n+1,loading:!1}})}));const[C,I]=(0,n.useState)(null),D=(0,n.useRef)(0),k=(0,n.useRef)(o.Z.canUseIntersectionObserver&&new IntersectionObserver((e=>{const{isIntersecting:t,boundingClientRect:{y:r}}=e[0];t&&D.current>r&&S({type:"advance"}),D.current=r}),{threshold:1})),q=()=>O?(0,y.I)({id:"theme.SearchPage.existingResultsTitle",message:'Search results for "{query}"',description:"The search page title for non-empty query"},{query:O}):(0,y.I)({id:"theme.SearchPage.emptyResultsTitle",message:"Search the documentation",description:"The search page title for empty query"}),V=(0,p.zX)((function(t){void 0===t&&(t=0),Q.addDisjunctiveFacetRefinement("docusaurus_tag","default"),Q.addDisjunctiveFacetRefinement("language",e),Object.entries(w.searchVersions).forEach((e=>{let[t,r]=e;Q.addDisjunctiveFacetRefinement("docusaurus_tag",`docs-${t}-${r}`)})),Q.setQuery(O).setPage(t).search()}));return(0,n.useEffect)((()=>{if(!C)return;const e=k.current;return e?(e.observe(C),()=>e.unobserve(C)):()=>!0}),[C]),(0,n.useEffect)((()=>{S({type:"reset"}),O&&(S({type:"loading"}),setTimeout((()=>{V()}),300))}),[O,w.searchVersions,V]),(0,n.useEffect)((()=>{H.lastPage&&0!==H.lastPage&&V(H.lastPage)}),[V,H.lastPage]),(0,_.jsxs)(j.Z,{children:[(0,_.jsxs)(h.Z,{children:[(0,_.jsx)("title",{children:(0,g.p)(q())}),(0,_.jsx)("meta",{property:"robots",content:"noindex, follow"})]}),(0,_.jsxs)("div",{className:"container margin-vert--lg",children:[(0,_.jsx)(P.Z,{as:"h1",children:q()}),(0,_.jsxs)("form",{className:"row",onSubmit:e=>e.preventDefault(),children:[(0,_.jsx)("div",{className:(0,i.Z)("col",x.searchQueryColumn,{"col--9":w.versioningEnabled,"col--12":!w.versioningEnabled}),children:(0,_.jsx)("input",{type:"search",name:"q",className:x.searchQueryInput,placeholder:(0,y.I)({id:"theme.SearchPage.inputPlaceholder",message:"Type your search here",description:"The placeholder for search page input"}),"aria-label":(0,y.I)({id:"theme.SearchPage.inputLabel",message:"Search",description:"The ARIA label for search page input"}),onChange:e=>N(e.target.value),value:O,autoComplete:"off",autoFocus:!0})}),w.versioningEnabled&&(0,_.jsx)(E,{docsSearchVersionsHelpers:w})]}),(0,_.jsxs)("div",{className:"row",children:[(0,_.jsx)("div",{className:(0,i.Z)("col","col--8",x.searchResultsColumn),children:!!H.totalResults&&v(H.totalResults)}),(0,_.jsx)("div",{className:(0,i.Z)("col","col--4","text--right",x.searchLogoColumn),children:(0,_.jsx)(f.Z,{to:"https://www.algolia.com/","aria-label":(0,y.I)({id:"theme.SearchPage.algoliaLabel",message:"Search by Algolia",description:"The ARIA label for Algolia mention"}),children:(0,_.jsx)("svg",{viewBox:"0 0 168 24",className:x.algoliaLogo,children:(0,_.jsxs)("g",{fill:"none",children:[(0,_.jsx)("path",{className:x.algoliaLogoPathFill,d:"M120.925 18.804c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 0 0-1.574-.199 5.7 5.7 0 0 0-.897.069 2.699 2.699 0 0 0-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 0 1-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 0 1-1.471-.636 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 0 1 1.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 0 1 1.82-.185 8.404 8.404 0 0 1 1.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 0 0-.384-.73 1.784 1.784 0 0 0-.724-.493 3.164 3.164 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 0 0-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 0 1 2.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 0 0-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 0 0-.814.24 1.46 1.46 0 0 0-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 0 1 .233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 0 1-1.471-.635 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 0 1 2.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 0 0-.109-.875 1.873 1.873 0 0 0-.384-.731 1.784 1.784 0 0 0-.724-.492 3.165 3.165 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 0 0-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 0 1 2.073-.177zm-8.034-1.271a1.626 1.626 0 0 1-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 0 1-1.128 1.906 4.986 4.986 0 0 1-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 0 1-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 0 1-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 0 1 1.15-1.892 5.133 5.133 0 0 1 1.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 0 1 1.753 1.216 5.644 5.644 0 0 1 1.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 0 0-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 0 1-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 0 1-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 0 1 2.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17zM6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 0 0-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 0 1-.582-.271 13.67 13.67 0 0 1-.55-.287 4.275 4.275 0 0 1-.567-.351 6.92 6.92 0 0 1-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 0 1-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 0 0-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 0 0-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 0 0-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 0 1-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z"}),(0,_.jsx)("path",{fill:"#5468FF",d:"M78.988.938h16.594a2.968 2.968 0 0 1 2.966 2.966V20.5a2.967 2.967 0 0 1-2.966 2.964H78.988a2.967 2.967 0 0 1-2.966-2.964V3.897A2.961 2.961 0 0 1 78.988.938z"}),(0,_.jsx)("path",{fill:"white",d:"M89.632 5.967v-.772a.978.978 0 0 0-.978-.977h-2.28a.978.978 0 0 0-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 0 1 1.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 0 0-1.382 0l-.465.465a.973.973 0 0 0 0 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 0 0-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 0 1-4.49-4.482 4.488 4.488 0 0 1 4.49-4.482 4.488 4.488 0 0 1 4.489 4.482 4.484 4.484 0 0 1-4.49 4.482m0-10.85a6.363 6.363 0 1 0 0 12.729 6.37 6.37 0 0 0 6.372-6.368 6.358 6.358 0 0 0-6.371-6.36"})]})})})})]}),H.items.length>0?(0,_.jsx)("main",{children:H.items.map(((e,t)=>{let{title:r,url:n,summary:s,breadcrumbs:a}=e;return(0,_.jsxs)("article",{className:x.searchResultItem,children:[(0,_.jsx)(P.Z,{as:"h2",className:x.searchResultItemHeading,children:(0,_.jsx)(f.Z,{to:n,dangerouslySetInnerHTML:{__html:r}})}),a.length>0&&(0,_.jsx)("nav",{"aria-label":"breadcrumbs",children:(0,_.jsx)("ul",{className:(0,i.Z)("breadcrumbs",x.searchResultItemPath),children:a.map(((e,t)=>(0,_.jsx)("li",{className:"breadcrumbs__item",dangerouslySetInnerHTML:{__html:e}},t)))})}),s&&(0,_.jsx)("p",{className:x.searchResultItemSummary,dangerouslySetInnerHTML:{__html:s}})]},t)}))}):[O&&!H.loading&&(0,_.jsx)("p",{children:(0,_.jsx)(y.Z,{id:"theme.SearchPage.noResultsText",description:"The paragraph for empty search result",children:"No results were found"})},"no-results"),!!H.loading&&(0,_.jsx)("div",{className:x.loadingSpinner},"spinner")],H.hasMore&&(0,_.jsx)("div",{className:x.loader,ref:I,children:(0,_.jsx)(y.Z,{id:"theme.SearchPage.fetchingNewResults",description:"The paragraph for fetching new search results",children:"Fetching new results..."})})]})]})}function O(){return(0,_.jsx)(v.FG,{className:"search-page-wrapper",children:(0,_.jsx)(w,{})})}}}]); \ No newline at end of file diff --git a/assets/js/1a4e3797.3cfcc719.js.LICENSE.txt b/assets/js/1a4e3797.3cfcc719.js.LICENSE.txt new file mode 100644 index 000000000..8c17e740e --- /dev/null +++ b/assets/js/1a4e3797.3cfcc719.js.LICENSE.txt @@ -0,0 +1 @@ +/*! algoliasearch-lite.umd.js | 4.20.0 | © Algolia, inc. | https://github.com/algolia/algoliasearch-client-javascript */ diff --git a/assets/js/1a4e3797.b205bd12.js b/assets/js/1a4e3797.b205bd12.js deleted file mode 100644 index 457ff78d0..000000000 --- a/assets/js/1a4e3797.b205bd12.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see 1a4e3797.b205bd12.js.LICENSE.txt */ -(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7920],{17331:e=>{function t(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function n(e){return"object"==typeof e&&null!==e}function i(e){return void 0===e}e.exports=t,t.prototype._events=void 0,t.prototype._maxListeners=void 0,t.defaultMaxListeners=10,t.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},t.prototype.emit=function(e){var t,a,s,c,u,o;if(this._events||(this._events={}),"error"===e&&(!this._events.error||n(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var h=new Error('Uncaught, unspecified "error" event. ('+t+")");throw h.context=t,h}if(i(a=this._events[e]))return!1;if(r(a))switch(arguments.length){case 1:a.call(this);break;case 2:a.call(this,arguments[1]);break;case 3:a.call(this,arguments[1],arguments[2]);break;default:c=Array.prototype.slice.call(arguments,1),a.apply(this,c)}else if(n(a))for(c=Array.prototype.slice.call(arguments,1),s=(o=a.slice()).length,u=0;u0&&this._events[e].length>s&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},t.prototype.on=t.prototype.addListener,t.prototype.once=function(e,t){if(!r(t))throw TypeError("listener must be a function");var n=!1;function i(){this.removeListener(e,i),n||(n=!0,t.apply(this,arguments))}return i.listener=t,this.on(e,i),this},t.prototype.removeListener=function(e,t){var i,a,s,c;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(s=(i=this._events[e]).length,a=-1,i===t||r(i.listener)&&i.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(n(i)){for(c=s;c-- >0;)if(i[c]===t||i[c].listener&&i[c].listener===t){a=c;break}if(a<0)return this;1===i.length?(i.length=0,delete this._events[e]):i.splice(a,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},t.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r(n=this._events[e]))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},t.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},t.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},t.listenerCount=function(e,t){return e.listenerCount(t)}},8131:(e,t,r)=>{"use strict";var n=r(49374),i=r(17775),a=r(23076);function s(e,t,r){return new n(e,t,r)}s.version=r(24336),s.AlgoliaSearchHelper=n,s.SearchParameters=i,s.SearchResults=a,e.exports=s},68078:(e,t,r)=>{"use strict";var n=r(17331);function i(e,t){this.main=e,this.fn=t,this.lastResults=null}r(14853)(i,n),i.prototype.detach=function(){this.removeAllListeners(),this.main.detachDerivedHelper(this)},i.prototype.getModifiedState=function(e){return this.fn(e)},e.exports=i},82437:(e,t,r)=>{"use strict";var n=r(52344),i=r(49803),a=r(90116),s={addRefinement:function(e,t,r){if(s.isRefined(e,t,r))return e;var i=""+r,a=e[t]?e[t].concat(i):[i],c={};return c[t]=a,n({},c,e)},removeRefinement:function(e,t,r){if(void 0===r)return s.clearRefinement(e,(function(e,r){return t===r}));var n=""+r;return s.clearRefinement(e,(function(e,r){return t===r&&n===e}))},toggleRefinement:function(e,t,r){if(void 0===r)throw new Error("toggleRefinement should be used with a value");return s.isRefined(e,t,r)?s.removeRefinement(e,t,r):s.addRefinement(e,t,r)},clearRefinement:function(e,t,r){if(void 0===t)return a(e)?{}:e;if("string"==typeof t)return i(e,[t]);if("function"==typeof t){var n=!1,s=Object.keys(e).reduce((function(i,a){var s=e[a]||[],c=s.filter((function(e){return!t(e,a,r)}));return c.length!==s.length&&(n=!0),i[a]=c,i}),{});return n?s:e}},isRefined:function(e,t,r){var n=!!e[t]&&e[t].length>0;if(void 0===r||!n)return n;var i=""+r;return-1!==e[t].indexOf(i)}};e.exports=s},17775:(e,t,r)=>{"use strict";var n=r(60185),i=r(52344),a=r(22686),s=r(7888),c=r(28023),u=r(49803),o=r(90116),h=r(46801),f=r(82437);function l(e,t){return Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((function(e,r){return l(t[r],e)})):e===t}function m(e){var t=e?m._parseNumbers(e):{};void 0===t.userToken||h(t.userToken)||console.warn("[algoliasearch-helper] The `userToken` parameter is invalid. This can lead to wrong analytics.\n - Format: [a-zA-Z0-9_-]{1,64}"),this.facets=t.facets||[],this.disjunctiveFacets=t.disjunctiveFacets||[],this.hierarchicalFacets=t.hierarchicalFacets||[],this.facetsRefinements=t.facetsRefinements||{},this.facetsExcludes=t.facetsExcludes||{},this.disjunctiveFacetsRefinements=t.disjunctiveFacetsRefinements||{},this.numericRefinements=t.numericRefinements||{},this.tagRefinements=t.tagRefinements||[],this.hierarchicalFacetsRefinements=t.hierarchicalFacetsRefinements||{};var r=this;Object.keys(t).forEach((function(e){var n=-1!==m.PARAMETERS.indexOf(e),i=void 0!==t[e];!n&&i&&(r[e]=t[e])}))}m.PARAMETERS=Object.keys(new m),m._parseNumbers=function(e){if(e instanceof m)return e;var t={};if(["aroundPrecision","aroundRadius","getRankingInfo","minWordSizefor2Typos","minWordSizefor1Typo","page","maxValuesPerFacet","distinct","minimumAroundRadius","hitsPerPage","minProximity"].forEach((function(r){var n=e[r];if("string"==typeof n){var i=parseFloat(n);t[r]=isNaN(i)?n:i}})),Array.isArray(e.insideBoundingBox)&&(t.insideBoundingBox=e.insideBoundingBox.map((function(e){return Array.isArray(e)?e.map((function(e){return parseFloat(e)})):e}))),e.numericRefinements){var r={};Object.keys(e.numericRefinements).forEach((function(t){var n=e.numericRefinements[t]||{};r[t]={},Object.keys(n).forEach((function(e){var i=n[e].map((function(e){return Array.isArray(e)?e.map((function(e){return"string"==typeof e?parseFloat(e):e})):"string"==typeof e?parseFloat(e):e}));r[t][e]=i}))})),t.numericRefinements=r}return n({},e,t)},m.make=function(e){var t=new m(e);return(e.hierarchicalFacets||[]).forEach((function(e){if(e.rootPath){var r=t.getHierarchicalRefinement(e.name);r.length>0&&0!==r[0].indexOf(e.rootPath)&&(t=t.clearRefinements(e.name)),0===(r=t.getHierarchicalRefinement(e.name)).length&&(t=t.toggleHierarchicalFacetRefinement(e.name,e.rootPath))}})),t},m.validate=function(e,t){var r=t||{};return e.tagFilters&&r.tagRefinements&&r.tagRefinements.length>0?new Error("[Tags] Cannot switch from the managed tag API to the advanced API. It is probably an error, if it is really what you want, you should first clear the tags with clearTags method."):e.tagRefinements.length>0&&r.tagFilters?new Error("[Tags] Cannot switch from the advanced tag API to the managed API. It is probably an error, if it is not, you should first clear the tags with clearTags method."):e.numericFilters&&r.numericRefinements&&o(r.numericRefinements)?new Error("[Numeric filters] Can't switch from the advanced to the managed API. It is probably an error, if this is really what you want, you have to first clear the numeric filters."):o(e.numericRefinements)&&r.numericFilters?new Error("[Numeric filters] Can't switch from the managed API to the advanced. It is probably an error, if this is really what you want, you have to first clear the numeric filters."):null},m.prototype={constructor:m,clearRefinements:function(e){var t={numericRefinements:this._clearNumericRefinements(e),facetsRefinements:f.clearRefinement(this.facetsRefinements,e,"conjunctiveFacet"),facetsExcludes:f.clearRefinement(this.facetsExcludes,e,"exclude"),disjunctiveFacetsRefinements:f.clearRefinement(this.disjunctiveFacetsRefinements,e,"disjunctiveFacet"),hierarchicalFacetsRefinements:f.clearRefinement(this.hierarchicalFacetsRefinements,e,"hierarchicalFacet")};return t.numericRefinements===this.numericRefinements&&t.facetsRefinements===this.facetsRefinements&&t.facetsExcludes===this.facetsExcludes&&t.disjunctiveFacetsRefinements===this.disjunctiveFacetsRefinements&&t.hierarchicalFacetsRefinements===this.hierarchicalFacetsRefinements?this:this.setQueryParameters(t)},clearTags:function(){return void 0===this.tagFilters&&0===this.tagRefinements.length?this:this.setQueryParameters({tagFilters:void 0,tagRefinements:[]})},setIndex:function(e){return e===this.index?this:this.setQueryParameters({index:e})},setQuery:function(e){return e===this.query?this:this.setQueryParameters({query:e})},setPage:function(e){return e===this.page?this:this.setQueryParameters({page:e})},setFacets:function(e){return this.setQueryParameters({facets:e})},setDisjunctiveFacets:function(e){return this.setQueryParameters({disjunctiveFacets:e})},setHitsPerPage:function(e){return this.hitsPerPage===e?this:this.setQueryParameters({hitsPerPage:e})},setTypoTolerance:function(e){return this.typoTolerance===e?this:this.setQueryParameters({typoTolerance:e})},addNumericRefinement:function(e,t,r){var i=c(r);if(this.isNumericRefined(e,t,i))return this;var a=n({},this.numericRefinements);return a[e]=n({},a[e]),a[e][t]?(a[e][t]=a[e][t].slice(),a[e][t].push(i)):a[e][t]=[i],this.setQueryParameters({numericRefinements:a})},getConjunctiveRefinements:function(e){return this.isConjunctiveFacet(e)&&this.facetsRefinements[e]||[]},getDisjunctiveRefinements:function(e){return this.isDisjunctiveFacet(e)&&this.disjunctiveFacetsRefinements[e]||[]},getHierarchicalRefinement:function(e){return this.hierarchicalFacetsRefinements[e]||[]},getExcludeRefinements:function(e){return this.isConjunctiveFacet(e)&&this.facetsExcludes[e]||[]},removeNumericRefinement:function(e,t,r){return void 0!==r?this.isNumericRefined(e,t,r)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(n,i){return i===e&&n.op===t&&l(n.val,c(r))}))}):this:void 0!==t?this.isNumericRefined(e,t)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(r,n){return n===e&&r.op===t}))}):this:this.isNumericRefined(e)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(t,r){return r===e}))}):this},getNumericRefinements:function(e){return this.numericRefinements[e]||{}},getNumericRefinement:function(e,t){return this.numericRefinements[e]&&this.numericRefinements[e][t]},_clearNumericRefinements:function(e){if(void 0===e)return o(this.numericRefinements)?{}:this.numericRefinements;if("string"==typeof e)return u(this.numericRefinements,[e]);if("function"==typeof e){var t=!1,r=this.numericRefinements,n=Object.keys(r).reduce((function(n,i){var a=r[i],s={};return a=a||{},Object.keys(a).forEach((function(r){var n=a[r]||[],c=[];n.forEach((function(t){e({val:t,op:r},i,"numeric")||c.push(t)})),c.length!==n.length&&(t=!0),s[r]=c})),n[i]=s,n}),{});return t?n:this.numericRefinements}},addFacet:function(e){return this.isConjunctiveFacet(e)?this:this.setQueryParameters({facets:this.facets.concat([e])})},addDisjunctiveFacet:function(e){return this.isDisjunctiveFacet(e)?this:this.setQueryParameters({disjunctiveFacets:this.disjunctiveFacets.concat([e])})},addHierarchicalFacet:function(e){if(this.isHierarchicalFacet(e.name))throw new Error("Cannot declare two hierarchical facets with the same name: `"+e.name+"`");return this.setQueryParameters({hierarchicalFacets:this.hierarchicalFacets.concat([e])})},addFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsRefinements,e,t)?this:this.setQueryParameters({facetsRefinements:f.addRefinement(this.facetsRefinements,e,t)})},addExcludeRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsExcludes,e,t)?this:this.setQueryParameters({facetsExcludes:f.addRefinement(this.facetsExcludes,e,t)})},addDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return f.isRefined(this.disjunctiveFacetsRefinements,e,t)?this:this.setQueryParameters({disjunctiveFacetsRefinements:f.addRefinement(this.disjunctiveFacetsRefinements,e,t)})},addTagRefinement:function(e){if(this.isTagRefined(e))return this;var t={tagRefinements:this.tagRefinements.concat(e)};return this.setQueryParameters(t)},removeFacet:function(e){return this.isConjunctiveFacet(e)?this.clearRefinements(e).setQueryParameters({facets:this.facets.filter((function(t){return t!==e}))}):this},removeDisjunctiveFacet:function(e){return this.isDisjunctiveFacet(e)?this.clearRefinements(e).setQueryParameters({disjunctiveFacets:this.disjunctiveFacets.filter((function(t){return t!==e}))}):this},removeHierarchicalFacet:function(e){return this.isHierarchicalFacet(e)?this.clearRefinements(e).setQueryParameters({hierarchicalFacets:this.hierarchicalFacets.filter((function(t){return t.name!==e}))}):this},removeFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsRefinements,e,t)?this.setQueryParameters({facetsRefinements:f.removeRefinement(this.facetsRefinements,e,t)}):this},removeExcludeRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsExcludes,e,t)?this.setQueryParameters({facetsExcludes:f.removeRefinement(this.facetsExcludes,e,t)}):this},removeDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return f.isRefined(this.disjunctiveFacetsRefinements,e,t)?this.setQueryParameters({disjunctiveFacetsRefinements:f.removeRefinement(this.disjunctiveFacetsRefinements,e,t)}):this},removeTagRefinement:function(e){if(!this.isTagRefined(e))return this;var t={tagRefinements:this.tagRefinements.filter((function(t){return t!==e}))};return this.setQueryParameters(t)},toggleRefinement:function(e,t){return this.toggleFacetRefinement(e,t)},toggleFacetRefinement:function(e,t){if(this.isHierarchicalFacet(e))return this.toggleHierarchicalFacetRefinement(e,t);if(this.isConjunctiveFacet(e))return this.toggleConjunctiveFacetRefinement(e,t);if(this.isDisjunctiveFacet(e))return this.toggleDisjunctiveFacetRefinement(e,t);throw new Error("Cannot refine the undeclared facet "+e+"; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets")},toggleConjunctiveFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return this.setQueryParameters({facetsRefinements:f.toggleRefinement(this.facetsRefinements,e,t)})},toggleExcludeFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return this.setQueryParameters({facetsExcludes:f.toggleRefinement(this.facetsExcludes,e,t)})},toggleDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return this.setQueryParameters({disjunctiveFacetsRefinements:f.toggleRefinement(this.disjunctiveFacetsRefinements,e,t)})},toggleHierarchicalFacetRefinement:function(e,t){if(!this.isHierarchicalFacet(e))throw new Error(e+" is not defined in the hierarchicalFacets attribute of the helper configuration");var r=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e)),n={};return void 0!==this.hierarchicalFacetsRefinements[e]&&this.hierarchicalFacetsRefinements[e].length>0&&(this.hierarchicalFacetsRefinements[e][0]===t||0===this.hierarchicalFacetsRefinements[e][0].indexOf(t+r))?-1===t.indexOf(r)?n[e]=[]:n[e]=[t.slice(0,t.lastIndexOf(r))]:n[e]=[t],this.setQueryParameters({hierarchicalFacetsRefinements:i({},n,this.hierarchicalFacetsRefinements)})},addHierarchicalFacetRefinement:function(e,t){if(this.isHierarchicalFacetRefined(e))throw new Error(e+" is already refined.");if(!this.isHierarchicalFacet(e))throw new Error(e+" is not defined in the hierarchicalFacets attribute of the helper configuration.");var r={};return r[e]=[t],this.setQueryParameters({hierarchicalFacetsRefinements:i({},r,this.hierarchicalFacetsRefinements)})},removeHierarchicalFacetRefinement:function(e){if(!this.isHierarchicalFacetRefined(e))return this;var t={};return t[e]=[],this.setQueryParameters({hierarchicalFacetsRefinements:i({},t,this.hierarchicalFacetsRefinements)})},toggleTagRefinement:function(e){return this.isTagRefined(e)?this.removeTagRefinement(e):this.addTagRefinement(e)},isDisjunctiveFacet:function(e){return this.disjunctiveFacets.indexOf(e)>-1},isHierarchicalFacet:function(e){return void 0!==this.getHierarchicalFacetByName(e)},isConjunctiveFacet:function(e){return this.facets.indexOf(e)>-1},isFacetRefined:function(e,t){return!!this.isConjunctiveFacet(e)&&f.isRefined(this.facetsRefinements,e,t)},isExcludeRefined:function(e,t){return!!this.isConjunctiveFacet(e)&&f.isRefined(this.facetsExcludes,e,t)},isDisjunctiveFacetRefined:function(e,t){return!!this.isDisjunctiveFacet(e)&&f.isRefined(this.disjunctiveFacetsRefinements,e,t)},isHierarchicalFacetRefined:function(e,t){if(!this.isHierarchicalFacet(e))return!1;var r=this.getHierarchicalRefinement(e);return t?-1!==r.indexOf(t):r.length>0},isNumericRefined:function(e,t,r){if(void 0===r&&void 0===t)return!!this.numericRefinements[e];var n=this.numericRefinements[e]&&void 0!==this.numericRefinements[e][t];if(void 0===r||!n)return n;var i,a,u=c(r),o=void 0!==(i=this.numericRefinements[e][t],a=u,s(i,(function(e){return l(e,a)})));return n&&o},isTagRefined:function(e){return-1!==this.tagRefinements.indexOf(e)},getRefinedDisjunctiveFacets:function(){var e=this,t=a(Object.keys(this.numericRefinements).filter((function(t){return Object.keys(e.numericRefinements[t]).length>0})),this.disjunctiveFacets);return Object.keys(this.disjunctiveFacetsRefinements).filter((function(t){return e.disjunctiveFacetsRefinements[t].length>0})).concat(t).concat(this.getRefinedHierarchicalFacets())},getRefinedHierarchicalFacets:function(){var e=this;return a(this.hierarchicalFacets.map((function(e){return e.name})),Object.keys(this.hierarchicalFacetsRefinements).filter((function(t){return e.hierarchicalFacetsRefinements[t].length>0})))},getUnrefinedDisjunctiveFacets:function(){var e=this.getRefinedDisjunctiveFacets();return this.disjunctiveFacets.filter((function(t){return-1===e.indexOf(t)}))},managedParameters:["index","facets","disjunctiveFacets","facetsRefinements","hierarchicalFacets","facetsExcludes","disjunctiveFacetsRefinements","numericRefinements","tagRefinements","hierarchicalFacetsRefinements"],getQueryParams:function(){var e=this.managedParameters,t={},r=this;return Object.keys(this).forEach((function(n){var i=r[n];-1===e.indexOf(n)&&void 0!==i&&(t[n]=i)})),t},setQueryParameter:function(e,t){if(this[e]===t)return this;var r={};return r[e]=t,this.setQueryParameters(r)},setQueryParameters:function(e){if(!e)return this;var t=m.validate(this,e);if(t)throw t;var r=this,n=m._parseNumbers(e),i=Object.keys(this).reduce((function(e,t){return e[t]=r[t],e}),{}),a=Object.keys(n).reduce((function(e,t){var r=void 0!==e[t],i=void 0!==n[t];return r&&!i?u(e,[t]):(i&&(e[t]=n[t]),e)}),i);return new this.constructor(a)},resetPage:function(){return void 0===this.page?this:this.setPage(0)},_getHierarchicalFacetSortBy:function(e){return e.sortBy||["isRefined:desc","name:asc"]},_getHierarchicalFacetSeparator:function(e){return e.separator||" > "},_getHierarchicalRootPath:function(e){return e.rootPath||null},_getHierarchicalShowParentLevel:function(e){return"boolean"!=typeof e.showParentLevel||e.showParentLevel},getHierarchicalFacetByName:function(e){return s(this.hierarchicalFacets,(function(t){return t.name===e}))},getHierarchicalFacetBreadcrumb:function(e){if(!this.isHierarchicalFacet(e))return[];var t=this.getHierarchicalRefinement(e)[0];if(!t)return[];var r=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e));return t.split(r).map((function(e){return e.trim()}))},toString:function(){return JSON.stringify(this,null,2)}},e.exports=m},10210:(e,t,r)=>{"use strict";e.exports=function(e){return function(t,r){var s=e.hierarchicalFacets[r],o=e.hierarchicalFacetsRefinements[s.name]&&e.hierarchicalFacetsRefinements[s.name][0]||"",h=e._getHierarchicalFacetSeparator(s),f=e._getHierarchicalRootPath(s),l=e._getHierarchicalShowParentLevel(s),m=a(e._getHierarchicalFacetSortBy(s)),d=t.every((function(e){return e.exhaustive})),p=function(e,t,r,a,s){return function(o,h,f){var l=o;if(f>0){var m=0;for(l=o;m{"use strict";var n=r(60185),i=r(52344),a=r(42148),s=r(74587),c=r(7888),u=r(69725),o=r(82293),h=r(94039),f=h.escapeFacetValue,l=h.unescapeFacetValue,m=r(10210);function d(e){var t={};return e.forEach((function(e,r){t[e]=r})),t}function p(e,t,r){t&&t[r]&&(e.stats=t[r])}function v(e,t,r){var a=t[0];this._rawResults=t;var o=this;Object.keys(a).forEach((function(e){o[e]=a[e]})),Object.keys(r||{}).forEach((function(e){o[e]=r[e]})),this.processingTimeMS=t.reduce((function(e,t){return void 0===t.processingTimeMS?e:e+t.processingTimeMS}),0),this.disjunctiveFacets=[],this.hierarchicalFacets=e.hierarchicalFacets.map((function(){return[]})),this.facets=[];var h=e.getRefinedDisjunctiveFacets(),f=d(e.facets),v=d(e.disjunctiveFacets),g=1,y=a.facets||{};Object.keys(y).forEach((function(t){var r,n,i=y[t],s=(r=e.hierarchicalFacets,n=t,c(r,(function(e){return(e.attributes||[]).indexOf(n)>-1})));if(s){var h=s.attributes.indexOf(t),l=u(e.hierarchicalFacets,(function(e){return e.name===s.name}));o.hierarchicalFacets[l][h]={attribute:t,data:i,exhaustive:a.exhaustiveFacetsCount}}else{var m,d=-1!==e.disjunctiveFacets.indexOf(t),g=-1!==e.facets.indexOf(t);d&&(m=v[t],o.disjunctiveFacets[m]={name:t,data:i,exhaustive:a.exhaustiveFacetsCount},p(o.disjunctiveFacets[m],a.facets_stats,t)),g&&(m=f[t],o.facets[m]={name:t,data:i,exhaustive:a.exhaustiveFacetsCount},p(o.facets[m],a.facets_stats,t))}})),this.hierarchicalFacets=s(this.hierarchicalFacets),h.forEach((function(r){var s=t[g],c=s&&s.facets?s.facets:{},h=e.getHierarchicalFacetByName(r);Object.keys(c).forEach((function(t){var r,f=c[t];if(h){r=u(e.hierarchicalFacets,(function(e){return e.name===h.name}));var m=u(o.hierarchicalFacets[r],(function(e){return e.attribute===t}));if(-1===m)return;o.hierarchicalFacets[r][m].data=n({},o.hierarchicalFacets[r][m].data,f)}else{r=v[t];var d=a.facets&&a.facets[t]||{};o.disjunctiveFacets[r]={name:t,data:i({},f,d),exhaustive:s.exhaustiveFacetsCount},p(o.disjunctiveFacets[r],s.facets_stats,t),e.disjunctiveFacetsRefinements[t]&&e.disjunctiveFacetsRefinements[t].forEach((function(n){!o.disjunctiveFacets[r].data[n]&&e.disjunctiveFacetsRefinements[t].indexOf(l(n))>-1&&(o.disjunctiveFacets[r].data[n]=0)}))}})),g++})),e.getRefinedHierarchicalFacets().forEach((function(r){var n=e.getHierarchicalFacetByName(r),a=e._getHierarchicalFacetSeparator(n),s=e.getHierarchicalRefinement(r);0===s.length||s[0].split(a).length<2||t.slice(g).forEach((function(t){var r=t&&t.facets?t.facets:{};Object.keys(r).forEach((function(t){var c=r[t],h=u(e.hierarchicalFacets,(function(e){return e.name===n.name})),f=u(o.hierarchicalFacets[h],(function(e){return e.attribute===t}));if(-1!==f){var l={};if(s.length>0){var m=s[0].split(a)[0];l[m]=o.hierarchicalFacets[h][f].data[m]}o.hierarchicalFacets[h][f].data=i(l,c,o.hierarchicalFacets[h][f].data)}})),g++}))})),Object.keys(e.facetsExcludes).forEach((function(t){var r=e.facetsExcludes[t],n=f[t];o.facets[n]={name:t,data:a.facets[t],exhaustive:a.exhaustiveFacetsCount},r.forEach((function(e){o.facets[n]=o.facets[n]||{name:t},o.facets[n].data=o.facets[n].data||{},o.facets[n].data[e]=0}))})),this.hierarchicalFacets=this.hierarchicalFacets.map(m(e)),this.facets=s(this.facets),this.disjunctiveFacets=s(this.disjunctiveFacets),this._state=e}function g(e,t,r,n){if(n=n||0,Array.isArray(t))return e(t,r[n]);if(!t.data||0===t.data.length)return t;var a=t.data.map((function(t){return g(e,t,r,n+1)})),s=e(a,r[n]);return i({data:s},t)}function y(e,t){var r=c(e,(function(e){return e.name===t}));return r&&r.stats}function R(e,t,r,n,i){var a=c(i,(function(e){return e.name===r})),s=a&&a.data&&a.data[n]?a.data[n]:0,u=a&&a.exhaustive||!1;return{type:t,attributeName:r,name:n,count:s,exhaustive:u}}v.prototype.getFacetByName=function(e){function t(t){return t.name===e}return c(this.facets,t)||c(this.disjunctiveFacets,t)||c(this.hierarchicalFacets,t)},v.DEFAULT_SORT=["isRefined:desc","count:desc","name:asc"],v.prototype.getFacetValues=function(e,t){var r=function(e,t){function r(e){return e.name===t}if(e._state.isConjunctiveFacet(t)){var n=c(e.facets,r);return n?Object.keys(n.data).map((function(r){var i=f(r);return{name:r,escapedValue:i,count:n.data[r],isRefined:e._state.isFacetRefined(t,i),isExcluded:e._state.isExcludeRefined(t,r)}})):[]}if(e._state.isDisjunctiveFacet(t)){var i=c(e.disjunctiveFacets,r);return i?Object.keys(i.data).map((function(r){var n=f(r);return{name:r,escapedValue:n,count:i.data[r],isRefined:e._state.isDisjunctiveFacetRefined(t,n)}})):[]}if(e._state.isHierarchicalFacet(t))return c(e.hierarchicalFacets,r)}(this,e);if(r){var n,s=i({},t,{sortBy:v.DEFAULT_SORT,facetOrdering:!(t&&t.sortBy)}),u=this;if(Array.isArray(r))n=[e];else n=u._state.getHierarchicalFacetByName(r.name).attributes;return g((function(e,t){if(s.facetOrdering){var r=function(e,t){return e.renderingContent&&e.renderingContent.facetOrdering&&e.renderingContent.facetOrdering.values&&e.renderingContent.facetOrdering.values[t]}(u,t);if(Boolean(r))return function(e,t){var r=[],n=[],i=(t.order||[]).reduce((function(e,t,r){return e[t]=r,e}),{});e.forEach((function(e){var t=e.path||e.name;void 0!==i[t]?r[i[t]]=e:n.push(e)})),r=r.filter((function(e){return e}));var s,c=t.sortRemainingBy;return"hidden"===c?r:(s="alpha"===c?[["path","name"],["asc","asc"]]:[["count"],["desc"]],r.concat(a(n,s[0],s[1])))}(e,r)}if(Array.isArray(s.sortBy)){var n=o(s.sortBy,v.DEFAULT_SORT);return a(e,n[0],n[1])}if("function"==typeof s.sortBy)return function(e,t){return t.sort(e)}(s.sortBy,e);throw new Error("options.sortBy is optional but if defined it must be either an array of string (predicates) or a sorting function")}),r,n)}},v.prototype.getFacetStats=function(e){return this._state.isConjunctiveFacet(e)?y(this.facets,e):this._state.isDisjunctiveFacet(e)?y(this.disjunctiveFacets,e):void 0},v.prototype.getRefinements=function(){var e=this._state,t=this,r=[];return Object.keys(e.facetsRefinements).forEach((function(n){e.facetsRefinements[n].forEach((function(i){r.push(R(e,"facet",n,i,t.facets))}))})),Object.keys(e.facetsExcludes).forEach((function(n){e.facetsExcludes[n].forEach((function(i){r.push(R(e,"exclude",n,i,t.facets))}))})),Object.keys(e.disjunctiveFacetsRefinements).forEach((function(n){e.disjunctiveFacetsRefinements[n].forEach((function(i){r.push(R(e,"disjunctive",n,i,t.disjunctiveFacets))}))})),Object.keys(e.hierarchicalFacetsRefinements).forEach((function(n){e.hierarchicalFacetsRefinements[n].forEach((function(i){r.push(function(e,t,r,n){var i=e.getHierarchicalFacetByName(t),a=e._getHierarchicalFacetSeparator(i),s=r.split(a),u=c(n,(function(e){return e.name===t})),o=s.reduce((function(e,t){var r=e&&c(e.data,(function(e){return e.name===t}));return void 0!==r?r:e}),u),h=o&&o.count||0,f=o&&o.exhaustive||!1,l=o&&o.path||"";return{type:"hierarchical",attributeName:t,name:l,count:h,exhaustive:f}}(e,n,i,t.hierarchicalFacets))}))})),Object.keys(e.numericRefinements).forEach((function(t){var n=e.numericRefinements[t];Object.keys(n).forEach((function(e){n[e].forEach((function(n){r.push({type:"numeric",attributeName:t,name:n,numericValue:n,operator:e})}))}))})),e.tagRefinements.forEach((function(e){r.push({type:"tag",attributeName:"_tags",name:e})})),r},e.exports=v},49374:(e,t,r)=>{"use strict";var n=r(17775),i=r(23076),a=r(68078),s=r(96394),c=r(17331),u=r(14853),o=r(90116),h=r(49803),f=r(60185),l=r(24336),m=r(94039).escapeFacetValue;function d(e,t,r){"function"==typeof e.addAlgoliaAgent&&e.addAlgoliaAgent("JS Helper ("+l+")"),this.setClient(e);var i=r||{};i.index=t,this.state=n.make(i),this.lastResults=null,this._queryId=0,this._lastQueryIdReceived=-1,this.derivedHelpers=[],this._currentNbQueries=0}function p(e){if(e<0)throw new Error("Page requested below 0.");return this._change({state:this.state.setPage(e),isPageReset:!1}),this}function v(){return this.state.page}u(d,c),d.prototype.search=function(){return this._search({onlyWithDerivedHelpers:!1}),this},d.prototype.searchOnlyWithDerivedHelpers=function(){return this._search({onlyWithDerivedHelpers:!0}),this},d.prototype.getQuery=function(){var e=this.state;return s._getHitsSearchParams(e)},d.prototype.searchOnce=function(e,t){var r=e?this.state.setQueryParameters(e):this.state,n=s._getQueries(r.index,r),a=this;if(this._currentNbQueries++,this.emit("searchOnce",{state:r}),!t)return this.client.search(n).then((function(e){return a._currentNbQueries--,0===a._currentNbQueries&&a.emit("searchQueueEmpty"),{content:new i(r,e.results),state:r,_originalResponse:e}}),(function(e){throw a._currentNbQueries--,0===a._currentNbQueries&&a.emit("searchQueueEmpty"),e}));this.client.search(n).then((function(e){a._currentNbQueries--,0===a._currentNbQueries&&a.emit("searchQueueEmpty"),t(null,new i(r,e.results),r)})).catch((function(e){a._currentNbQueries--,0===a._currentNbQueries&&a.emit("searchQueueEmpty"),t(e,null,r)}))},d.prototype.findAnswers=function(e){var t=this.state,r=this.derivedHelpers[0];if(!r)return Promise.resolve([]);var n=r.getModifiedState(t),i=f({attributesForPrediction:e.attributesForPrediction,nbHits:e.nbHits},{params:h(s._getHitsSearchParams(n),["attributesToSnippet","hitsPerPage","restrictSearchableAttributes","snippetEllipsisText"])}),a="search for answers was called, but this client does not have a function client.initIndex(index).findAnswers";if("function"!=typeof this.client.initIndex)throw new Error(a);var c=this.client.initIndex(n.index);if("function"!=typeof c.findAnswers)throw new Error(a);return c.findAnswers(n.query,e.queryLanguages,i)},d.prototype.searchForFacetValues=function(e,t,r,n){var i="function"==typeof this.client.searchForFacetValues,a="function"==typeof this.client.initIndex;if(!i&&!a&&"function"!=typeof this.client.search)throw new Error("search for facet values (searchable) was called, but this client does not have a function client.searchForFacetValues or client.initIndex(index).searchForFacetValues");var c=this.state.setQueryParameters(n||{}),u=c.isDisjunctiveFacet(e),o=s.getSearchForFacetQuery(e,t,r,c);this._currentNbQueries++;var h,f=this;return i?h=this.client.searchForFacetValues([{indexName:c.index,params:o}]):a?h=this.client.initIndex(c.index).searchForFacetValues(o):(delete o.facetName,h=this.client.search([{type:"facet",facet:e,indexName:c.index,params:o}]).then((function(e){return e.results[0]}))),this.emit("searchForFacetValues",{state:c,facet:e,query:t}),h.then((function(t){return f._currentNbQueries--,0===f._currentNbQueries&&f.emit("searchQueueEmpty"),(t=Array.isArray(t)?t[0]:t).facetHits.forEach((function(t){t.escapedValue=m(t.value),t.isRefined=u?c.isDisjunctiveFacetRefined(e,t.escapedValue):c.isFacetRefined(e,t.escapedValue)})),t}),(function(e){throw f._currentNbQueries--,0===f._currentNbQueries&&f.emit("searchQueueEmpty"),e}))},d.prototype.setQuery=function(e){return this._change({state:this.state.resetPage().setQuery(e),isPageReset:!0}),this},d.prototype.clearRefinements=function(e){return this._change({state:this.state.resetPage().clearRefinements(e),isPageReset:!0}),this},d.prototype.clearTags=function(){return this._change({state:this.state.resetPage().clearTags(),isPageReset:!0}),this},d.prototype.addDisjunctiveFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addDisjunctiveFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.addDisjunctiveRefine=function(){return this.addDisjunctiveFacetRefinement.apply(this,arguments)},d.prototype.addHierarchicalFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addHierarchicalFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.addNumericRefinement=function(e,t,r){return this._change({state:this.state.resetPage().addNumericRefinement(e,t,r),isPageReset:!0}),this},d.prototype.addFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.addRefine=function(){return this.addFacetRefinement.apply(this,arguments)},d.prototype.addFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().addExcludeRefinement(e,t),isPageReset:!0}),this},d.prototype.addExclude=function(){return this.addFacetExclusion.apply(this,arguments)},d.prototype.addTag=function(e){return this._change({state:this.state.resetPage().addTagRefinement(e),isPageReset:!0}),this},d.prototype.removeNumericRefinement=function(e,t,r){return this._change({state:this.state.resetPage().removeNumericRefinement(e,t,r),isPageReset:!0}),this},d.prototype.removeDisjunctiveFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().removeDisjunctiveFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.removeDisjunctiveRefine=function(){return this.removeDisjunctiveFacetRefinement.apply(this,arguments)},d.prototype.removeHierarchicalFacetRefinement=function(e){return this._change({state:this.state.resetPage().removeHierarchicalFacetRefinement(e),isPageReset:!0}),this},d.prototype.removeFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().removeFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.removeRefine=function(){return this.removeFacetRefinement.apply(this,arguments)},d.prototype.removeFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().removeExcludeRefinement(e,t),isPageReset:!0}),this},d.prototype.removeExclude=function(){return this.removeFacetExclusion.apply(this,arguments)},d.prototype.removeTag=function(e){return this._change({state:this.state.resetPage().removeTagRefinement(e),isPageReset:!0}),this},d.prototype.toggleFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().toggleExcludeFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.toggleExclude=function(){return this.toggleFacetExclusion.apply(this,arguments)},d.prototype.toggleRefinement=function(e,t){return this.toggleFacetRefinement(e,t)},d.prototype.toggleFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().toggleFacetRefinement(e,t),isPageReset:!0}),this},d.prototype.toggleRefine=function(){return this.toggleFacetRefinement.apply(this,arguments)},d.prototype.toggleTag=function(e){return this._change({state:this.state.resetPage().toggleTagRefinement(e),isPageReset:!0}),this},d.prototype.nextPage=function(){var e=this.state.page||0;return this.setPage(e+1)},d.prototype.previousPage=function(){var e=this.state.page||0;return this.setPage(e-1)},d.prototype.setCurrentPage=p,d.prototype.setPage=p,d.prototype.setIndex=function(e){return this._change({state:this.state.resetPage().setIndex(e),isPageReset:!0}),this},d.prototype.setQueryParameter=function(e,t){return this._change({state:this.state.resetPage().setQueryParameter(e,t),isPageReset:!0}),this},d.prototype.setState=function(e){return this._change({state:n.make(e),isPageReset:!1}),this},d.prototype.overrideStateWithoutTriggeringChangeEvent=function(e){return this.state=new n(e),this},d.prototype.hasRefinements=function(e){return!!o(this.state.getNumericRefinements(e))||(this.state.isConjunctiveFacet(e)?this.state.isFacetRefined(e):this.state.isDisjunctiveFacet(e)?this.state.isDisjunctiveFacetRefined(e):!!this.state.isHierarchicalFacet(e)&&this.state.isHierarchicalFacetRefined(e))},d.prototype.isExcluded=function(e,t){return this.state.isExcludeRefined(e,t)},d.prototype.isDisjunctiveRefined=function(e,t){return this.state.isDisjunctiveFacetRefined(e,t)},d.prototype.hasTag=function(e){return this.state.isTagRefined(e)},d.prototype.isTagRefined=function(){return this.hasTagRefinements.apply(this,arguments)},d.prototype.getIndex=function(){return this.state.index},d.prototype.getCurrentPage=v,d.prototype.getPage=v,d.prototype.getTags=function(){return this.state.tagRefinements},d.prototype.getRefinements=function(e){var t=[];if(this.state.isConjunctiveFacet(e))this.state.getConjunctiveRefinements(e).forEach((function(e){t.push({value:e,type:"conjunctive"})})),this.state.getExcludeRefinements(e).forEach((function(e){t.push({value:e,type:"exclude"})}));else if(this.state.isDisjunctiveFacet(e)){this.state.getDisjunctiveRefinements(e).forEach((function(e){t.push({value:e,type:"disjunctive"})}))}var r=this.state.getNumericRefinements(e);return Object.keys(r).forEach((function(e){var n=r[e];t.push({value:n,operator:e,type:"numeric"})})),t},d.prototype.getNumericRefinement=function(e,t){return this.state.getNumericRefinement(e,t)},d.prototype.getHierarchicalFacetBreadcrumb=function(e){return this.state.getHierarchicalFacetBreadcrumb(e)},d.prototype._search=function(e){var t=this.state,r=[],n=[];e.onlyWithDerivedHelpers||(n=s._getQueries(t.index,t),r.push({state:t,queriesCount:n.length,helper:this}),this.emit("search",{state:t,results:this.lastResults}));var i=this.derivedHelpers.map((function(e){var n=e.getModifiedState(t),i=s._getQueries(n.index,n);return r.push({state:n,queriesCount:i.length,helper:e}),e.emit("search",{state:n,results:e.lastResults}),i})),a=Array.prototype.concat.apply(n,i),c=this._queryId++;this._currentNbQueries++;try{this.client.search(a).then(this._dispatchAlgoliaResponse.bind(this,r,c)).catch(this._dispatchAlgoliaError.bind(this,c))}catch(u){this.emit("error",{error:u})}},d.prototype._dispatchAlgoliaResponse=function(e,t,r){if(!(t0},d.prototype._change=function(e){var t=e.state,r=e.isPageReset;t!==this.state&&(this.state=t,this.emit("change",{state:this.state,results:this.lastResults,isPageReset:r}))},d.prototype.clearCache=function(){return this.client.clearCache&&this.client.clearCache(),this},d.prototype.setClient=function(e){return this.client===e||("function"==typeof e.addAlgoliaAgent&&e.addAlgoliaAgent("JS Helper ("+l+")"),this.client=e),this},d.prototype.getClient=function(){return this.client},d.prototype.derive=function(e){var t=new a(this,e);return this.derivedHelpers.push(t),t},d.prototype.detachDerivedHelper=function(e){var t=this.derivedHelpers.indexOf(e);if(-1===t)throw new Error("Derived helper already detached");this.derivedHelpers.splice(t,1)},d.prototype.hasPendingRequests=function(){return this._currentNbQueries>0},e.exports=d},74587:e=>{"use strict";e.exports=function(e){return Array.isArray(e)?e.filter(Boolean):[]}},52344:e=>{"use strict";e.exports=function(){var e=Array.prototype.slice.call(arguments);return e.reduceRight((function(e,t){return Object.keys(Object(t)).forEach((function(r){void 0!==t[r]&&(void 0!==e[r]&&delete e[r],e[r]=t[r])})),e}),{})}},94039:e=>{"use strict";e.exports={escapeFacetValue:function(e){return"string"!=typeof e?e:String(e).replace(/^-/,"\\-")},unescapeFacetValue:function(e){return"string"!=typeof e?e:e.replace(/^\\-/,"-")}}},7888:e=>{"use strict";e.exports=function(e,t){if(Array.isArray(e))for(var r=0;r{"use strict";e.exports=function(e,t){if(!Array.isArray(e))return-1;for(var r=0;r{"use strict";var n=r(7888);e.exports=function(e,t){var r=(t||[]).map((function(e){return e.split(":")}));return e.reduce((function(e,t){var i=t.split(":"),a=n(r,(function(e){return e[0]===i[0]}));return i.length>1||!a?(e[0].push(i[0]),e[1].push(i[1]),e):(e[0].push(a[0]),e[1].push(a[1]),e)}),[[],[]])}},14853:e=>{"use strict";e.exports=function(e,t){e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}},22686:e=>{"use strict";e.exports=function(e,t){return e.filter((function(r,n){return t.indexOf(r)>-1&&e.indexOf(r)===n}))}},60185:e=>{"use strict";function t(e){return"function"==typeof e||Array.isArray(e)||"[object Object]"===Object.prototype.toString.call(e)}function r(e,n){if(e===n)return e;for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)&&"__proto__"!==i){var a=n[i],s=e[i];void 0!==s&&void 0===a||(t(s)&&t(a)?e[i]=r(s,a):e[i]="object"==typeof(c=a)&&null!==c?r(Array.isArray(c)?[]:{},c):c)}var c;return e}e.exports=function(e){t(e)||(e={});for(var n=1,i=arguments.length;n{"use strict";e.exports=function(e){return e&&Object.keys(e).length>0}},49803:e=>{"use strict";e.exports=function(e,t){if(null===e)return{};var r,n,i={},a=Object.keys(e);for(n=0;n=0||(i[r]=e[r]);return i}},42148:e=>{"use strict";function t(e,t){if(e!==t){var r=void 0!==e,n=null===e,i=void 0!==t,a=null===t;if(!a&&e>t||n&&i||!r)return 1;if(!n&&e=n.length?a:"desc"===n[i]?-a:a}return e.index-r.index})),i.map((function(e){return e.value}))}},28023:e=>{"use strict";e.exports=function e(t){if("number"==typeof t)return t;if("string"==typeof t)return parseFloat(t);if(Array.isArray(t))return t.map(e);throw new Error("The value should be a number, a parsable string or an array of those.")}},96394:(e,t,r)=>{"use strict";var n=r(60185);function i(e){return Object.keys(e).sort((function(e,t){return e.localeCompare(t)})).reduce((function(t,r){return t[r]=e[r],t}),{})}var a={_getQueries:function(e,t){var r=[];return r.push({indexName:e,params:a._getHitsSearchParams(t)}),t.getRefinedDisjunctiveFacets().forEach((function(n){r.push({indexName:e,params:a._getDisjunctiveFacetSearchParams(t,n)})})),t.getRefinedHierarchicalFacets().forEach((function(n){var i=t.getHierarchicalFacetByName(n),s=t.getHierarchicalRefinement(n),c=t._getHierarchicalFacetSeparator(i);if(s.length>0&&s[0].split(c).length>1){var u=s[0].split(c).slice(0,-1).reduce((function(e,t,r){return e.concat({attribute:i.attributes[r],value:0===r?t:[e[e.length-1].value,t].join(c)})}),[]);u.forEach((function(n,s){var c=a._getDisjunctiveFacetSearchParams(t,n.attribute,0===s);function o(e){return i.attributes.some((function(t){return t===e.split(":")[0]}))}var h=(c.facetFilters||[]).reduce((function(e,t){if(Array.isArray(t)){var r=t.filter((function(e){return!o(e)}));r.length>0&&e.push(r)}return"string"!=typeof t||o(t)||e.push(t),e}),[]),f=u[s-1];c.facetFilters=s>0?h.concat(f.attribute+":"+f.value):h.length>0?h:void 0,r.push({indexName:e,params:c})}))}})),r},_getHitsSearchParams:function(e){var t=e.facets.concat(e.disjunctiveFacets).concat(a._getHitsHierarchicalFacetsAttributes(e)),r=a._getFacetFilters(e),s=a._getNumericFilters(e),c=a._getTagFilters(e),u={facets:t.indexOf("*")>-1?["*"]:t,tagFilters:c};return r.length>0&&(u.facetFilters=r),s.length>0&&(u.numericFilters=s),i(n({},e.getQueryParams(),u))},_getDisjunctiveFacetSearchParams:function(e,t,r){var s=a._getFacetFilters(e,t,r),c=a._getNumericFilters(e,t),u=a._getTagFilters(e),o={hitsPerPage:0,page:0,analytics:!1,clickAnalytics:!1};u.length>0&&(o.tagFilters=u);var h=e.getHierarchicalFacetByName(t);return o.facets=h?a._getDisjunctiveHierarchicalFacetAttribute(e,h,r):t,c.length>0&&(o.numericFilters=c),s.length>0&&(o.facetFilters=s),i(n({},e.getQueryParams(),o))},_getNumericFilters:function(e,t){if(e.numericFilters)return e.numericFilters;var r=[];return Object.keys(e.numericRefinements).forEach((function(n){var i=e.numericRefinements[n]||{};Object.keys(i).forEach((function(e){var a=i[e]||[];t!==n&&a.forEach((function(t){if(Array.isArray(t)){var i=t.map((function(t){return n+e+t}));r.push(i)}else r.push(n+e+t)}))}))})),r},_getTagFilters:function(e){return e.tagFilters?e.tagFilters:e.tagRefinements.join(",")},_getFacetFilters:function(e,t,r){var n=[],i=e.facetsRefinements||{};Object.keys(i).forEach((function(e){(i[e]||[]).forEach((function(t){n.push(e+":"+t)}))}));var a=e.facetsExcludes||{};Object.keys(a).forEach((function(e){(a[e]||[]).forEach((function(t){n.push(e+":-"+t)}))}));var s=e.disjunctiveFacetsRefinements||{};Object.keys(s).forEach((function(e){var r=s[e]||[];if(e!==t&&r&&0!==r.length){var i=[];r.forEach((function(t){i.push(e+":"+t)})),n.push(i)}}));var c=e.hierarchicalFacetsRefinements||{};return Object.keys(c).forEach((function(i){var a=(c[i]||[])[0];if(void 0!==a){var s,u,o=e.getHierarchicalFacetByName(i),h=e._getHierarchicalFacetSeparator(o),f=e._getHierarchicalRootPath(o);if(t===i){if(-1===a.indexOf(h)||!f&&!0===r||f&&f.split(h).length===a.split(h).length)return;f?(u=f.split(h).length-1,a=f):(u=a.split(h).length-2,a=a.slice(0,a.lastIndexOf(h))),s=o.attributes[u]}else u=a.split(h).length-1,s=o.attributes[u];s&&n.push([s+":"+a])}})),n},_getHitsHierarchicalFacetsAttributes:function(e){return e.hierarchicalFacets.reduce((function(t,r){var n=e.getHierarchicalRefinement(r.name)[0];if(!n)return t.push(r.attributes[0]),t;var i=e._getHierarchicalFacetSeparator(r),a=n.split(i).length,s=r.attributes.slice(0,a+1);return t.concat(s)}),[])},_getDisjunctiveHierarchicalFacetAttribute:function(e,t,r){var n=e._getHierarchicalFacetSeparator(t);if(!0===r){var i=e._getHierarchicalRootPath(t),a=0;return i&&(a=i.split(n).length),[t.attributes[a]]}var s=(e.getHierarchicalRefinement(t.name)[0]||"").split(n).length-1;return t.attributes.slice(0,s+1)},getSearchForFacetQuery:function(e,t,r,s){var c=s.isDisjunctiveFacet(e)?s.clearRefinements(e):s,u={facetQuery:t,facetName:e};return"number"==typeof r&&(u.maxFacetHits=r),i(n({},a._getHitsSearchParams(c),u))}};e.exports=a},46801:e=>{"use strict";e.exports=function(e){return null!==e&&/^[a-zA-Z0-9_-]{1,64}$/.test(e)}},24336:e=>{"use strict";e.exports="3.11.1"},70290:function(e){e.exports=function(){"use strict";function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function r(r){for(var n=1;n=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)){var r=[],n=!0,i=!1,a=void 0;try{for(var s,c=e[Symbol.iterator]();!(n=(s=c.next()).done)&&(r.push(s.value),!t||r.length!==t);n=!0);}catch(e){i=!0,a=e}finally{try{n||null==c.return||c.return()}finally{if(i)throw a}}return r}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function a(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return Promise.resolve().then((function(){var r=JSON.stringify(e),n=a()[r];return Promise.all([n||t(),void 0!==n])})).then((function(e){var t=i(e,2),n=t[0],a=t[1];return Promise.all([n,a||r.miss(n)])})).then((function(e){return i(e,1)[0]}))},set:function(e,t){return Promise.resolve().then((function(){var i=a();return i[JSON.stringify(e)]=t,n().setItem(r,JSON.stringify(i)),t}))},delete:function(e){return Promise.resolve().then((function(){var t=a();delete t[JSON.stringify(e)],n().setItem(r,JSON.stringify(t))}))},clear:function(){return Promise.resolve().then((function(){n().removeItem(r)}))}}}function c(e){var t=a(e.caches),r=t.shift();return void 0===r?{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return t().then((function(e){return Promise.all([e,r.miss(e)])})).then((function(e){return i(e,1)[0]}))},set:function(e,t){return Promise.resolve(t)},delete:function(e){return Promise.resolve()},clear:function(){return Promise.resolve()}}:{get:function(e,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return r.get(e,n,i).catch((function(){return c({caches:t}).get(e,n,i)}))},set:function(e,n){return r.set(e,n).catch((function(){return c({caches:t}).set(e,n)}))},delete:function(e){return r.delete(e).catch((function(){return c({caches:t}).delete(e)}))},clear:function(){return r.clear().catch((function(){return c({caches:t}).clear()}))}}}function u(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{serializable:!0},t={};return{get:function(r,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},a=JSON.stringify(r);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);var s=n(),c=i&&i.miss||function(){return Promise.resolve()};return s.then((function(e){return c(e)})).then((function(){return s}))},set:function(r,n){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(n):n,Promise.resolve(n)},delete:function(e){return delete t[JSON.stringify(e)],Promise.resolve()},clear:function(){return t={},Promise.resolve()}}}function o(e){for(var t=e.length-1;t>0;t--){var r=Math.floor(Math.random()*(t+1)),n=e[t];e[t]=e[r],e[r]=n}return e}function h(e,t){return t?(Object.keys(t).forEach((function(r){e[r]=t[r](e)})),e):e}function f(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n0?n:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var d={Read:1,Write:2,Any:3},p=1,v=2,g=3;function y(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;return r(r({},e),{},{status:t,lastUpdate:Date.now()})}function R(e){return"string"==typeof e?{protocol:"https",url:e,accept:d.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||d.Any}}var F="GET",b="POST";function P(e,t){return Promise.all(t.map((function(t){return e.get(t,(function(){return Promise.resolve(y(t))}))}))).then((function(e){var r=e.filter((function(e){return function(e){return e.status===p||Date.now()-e.lastUpdate>12e4}(e)})),n=e.filter((function(e){return function(e){return e.status===g&&Date.now()-e.lastUpdate<=12e4}(e)})),i=[].concat(a(r),a(n));return{getTimeout:function(e,t){return(0===n.length&&0===e?1:n.length+3+e)*t},statelessHosts:i.length>0?i.map((function(e){return R(e)})):t}}))}function j(e,t,n,i){var s=[],c=function(e,t){if(e.method!==F&&(void 0!==e.data||void 0!==t.data)){var n=Array.isArray(e.data)?e.data:r(r({},e.data),t.data);return JSON.stringify(n)}}(n,i),u=function(e,t){var n=r(r({},e.headers),t.headers),i={};return Object.keys(n).forEach((function(e){var t=n[e];i[e.toLowerCase()]=t})),i}(e,i),o=n.method,h=n.method!==F?{}:r(r({},n.data),i.data),f=r(r(r({"x-algolia-agent":e.userAgent.value},e.queryParameters),h),i.queryParameters),l=0,m=function t(r,a){var h=r.pop();if(void 0===h)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:w(s)};var m={data:c,headers:u,method:o,url:E(h,n.path,f),connectTimeout:a(l,e.timeouts.connect),responseTimeout:a(l,i.timeout)},d=function(e){var t={request:m,response:e,host:h,triesLeft:r.length};return s.push(t),t},p={onSuccess:function(e){return function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e)},onRetry:function(n){var i=d(n);return n.isTimedOut&&l++,Promise.all([e.logger.info("Retryable failure",O(i)),e.hostsCache.set(h,y(h,n.isTimedOut?g:v))]).then((function(){return t(r,a)}))},onFail:function(e){throw d(e),function(e,t){var r=e.content,n=e.status,i=r;try{i=JSON.parse(r).message}catch(e){}return function(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}(i,n,t)}(e,w(s))}};return e.requester.send(m).then((function(e){return function(e,t){return function(e){var t=e.status;return e.isTimedOut||function(e){var t=e.isTimedOut,r=e.status;return!t&&0==~~r}(e)||2!=~~(t/100)&&4!=~~(t/100)}(e)?t.onRetry(e):2==~~(e.status/100)?t.onSuccess(e):t.onFail(e)}(e,p)}))};return P(e.hostsCache,t).then((function(e){return m(a(e.statelessHosts).reverse(),e.getTimeout)}))}function _(e){var t={value:"Algolia for JavaScript (".concat(e,")"),add:function(e){var r="; ".concat(e.segment).concat(void 0!==e.version?" (".concat(e.version,")"):"");return-1===t.value.indexOf(r)&&(t.value="".concat(t.value).concat(r)),t}};return t}function E(e,t,r){var n=x(r),i="".concat(e.protocol,"://").concat(e.url,"/").concat("/"===t.charAt(0)?t.substr(1):t);return n.length&&(i+="?".concat(n)),i}function x(e){return Object.keys(e).map((function(t){return f("%s=%s",t,(r=e[t],"[object Object]"===Object.prototype.toString.call(r)||"[object Array]"===Object.prototype.toString.call(r)?JSON.stringify(e[t]):e[t]));var r})).join("&")}function w(e){return e.map((function(e){return O(e)}))}function O(e){var t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return r(r({},e),{},{request:r(r({},e.request),{},{headers:r(r({},e.request.headers),t)})})}var N=function(e){var t=e.appId,n=function(e,t,r){var n={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers:function(){return e===l.WithinHeaders?n:{}},queryParameters:function(){return e===l.WithinQueryParameters?n:{}}}}(void 0!==e.authMode?e.authMode:l.WithinHeaders,t,e.apiKey),a=function(e){var t=e.hostsCache,r=e.logger,n=e.requester,a=e.requestsCache,s=e.responsesCache,c=e.timeouts,u=e.userAgent,o=e.hosts,h=e.queryParameters,f={hostsCache:t,logger:r,requester:n,requestsCache:a,responsesCache:s,timeouts:c,userAgent:u,headers:e.headers,queryParameters:h,hosts:o.map((function(e){return R(e)})),read:function(e,t){var r=m(t,f.timeouts.read),n=function(){return j(f,f.hosts.filter((function(e){return 0!=(e.accept&d.Read)})),e,r)};if(!0!==(void 0!==r.cacheable?r.cacheable:e.cacheable))return n();var a={request:e,mappedRequestOptions:r,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(a,(function(){return f.requestsCache.get(a,(function(){return f.requestsCache.set(a,n()).then((function(e){return Promise.all([f.requestsCache.delete(a),e])}),(function(e){return Promise.all([f.requestsCache.delete(a),Promise.reject(e)])})).then((function(e){var t=i(e,2);return t[0],t[1]}))}))}),{miss:function(e){return f.responsesCache.set(a,e)}})},write:function(e,t){return j(f,f.hosts.filter((function(e){return 0!=(e.accept&d.Write)})),e,m(t,f.timeouts.write))}};return f}(r(r({hosts:[{url:"".concat(t,"-dsn.algolia.net"),accept:d.Read},{url:"".concat(t,".algolia.net"),accept:d.Write}].concat(o([{url:"".concat(t,"-1.algolianet.com")},{url:"".concat(t,"-2.algolianet.com")},{url:"".concat(t,"-3.algolianet.com")}]))},e),{},{headers:r(r(r({},n.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:r(r({},n.queryParameters()),e.queryParameters)}));return h({transporter:a,appId:t,addAlgoliaAgent:function(e,t){a.userAgent.add({segment:e,version:t})},clearCache:function(){return Promise.all([a.requestsCache.clear(),a.responsesCache.clear()]).then((function(){}))}},e.methods)},A=function(e){return function(t,r){return t.method===F?e.transporter.read(t,r):e.transporter.write(t,r)}},H=function(e){return function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return h({transporter:e.transporter,appId:e.appId,indexName:t},r.methods)}},S=function(e){return function(t,n){var i=t.map((function(e){return r(r({},e),{},{params:x(e.params||{})})}));return e.transporter.read({method:b,path:"1/indexes/*/queries",data:{requests:i},cacheable:!0},n)}},T=function(e){return function(t,i){return Promise.all(t.map((function(t){var a=t.params,s=a.facetName,c=a.facetQuery,u=n(a,["facetName","facetQuery"]);return H(e)(t.indexName,{methods:{searchForFacetValues:k}}).searchForFacetValues(s,c,r(r({},i),u))})))}},Q=function(e){return function(t,r,n){return e.transporter.read({method:b,path:f("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:r},cacheable:!0},n)}},C=function(e){return function(t,r){return e.transporter.read({method:b,path:f("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r)}},k=function(e){return function(t,r,n){return e.transporter.read({method:b,path:f("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},n)}},D=1,I=2,q=3;function V(e,t,n){var i,a={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:function(e){return new Promise((function(t){var r=new XMLHttpRequest;r.open(e.method,e.url,!0),Object.keys(e.headers).forEach((function(t){return r.setRequestHeader(t,e.headers[t])}));var n,i=function(e,n){return setTimeout((function(){r.abort(),t({status:0,content:n,isTimedOut:!0})}),1e3*e)},a=i(e.connectTimeout,"Connection timeout");r.onreadystatechange=function(){r.readyState>r.OPENED&&void 0===n&&(clearTimeout(a),n=i(e.responseTimeout,"Socket timeout"))},r.onerror=function(){0===r.status&&(clearTimeout(a),clearTimeout(n),t({content:r.responseText||"Network request failed",status:r.status,isTimedOut:!1}))},r.onload=function(){clearTimeout(a),clearTimeout(n),t({content:r.responseText,status:r.status,isTimedOut:!1})},r.send(e.data)}))}},logger:(i=q,{debug:function(e,t){return D>=i&&console.debug(e,t),Promise.resolve()},info:function(e,t){return I>=i&&console.info(e,t),Promise.resolve()},error:function(e,t){return console.error(e,t),Promise.resolve()}}),responsesCache:u(),requestsCache:u({serializable:!1}),hostsCache:c({caches:[s({key:"".concat("4.14.2","-").concat(e)}),u()]}),userAgent:_("4.14.2").add({segment:"Browser",version:"lite"}),authMode:l.WithinQueryParameters};return N(r(r(r({},a),n),{},{methods:{search:S,searchForFacetValues:T,multipleQueries:S,multipleSearchForFacetValues:T,customRequest:A,initIndex:function(e){return function(t){return H(e)(t,{methods:{search:C,searchForFacetValues:k,findAnswers:Q}})}}}}))}return V.version="4.14.2",V}()},88824:(e,t,r)=>{"use strict";r.d(t,{c:()=>o});var n=r(67294),i=r(52263);const a=["zero","one","two","few","many","other"];function s(e){return a.filter((t=>e.includes(t)))}const c={locale:"en",pluralForms:s(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,i.Z)();return(0,n.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:s(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),c}}),[e])}function o(){const e=u();return{selectMessage:(t,r)=>function(e,t,r){const n=e.split("|");if(1===n.length)return n[0];n.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const i=r.select(t),a=r.pluralForms.indexOf(i);return n[Math.min(a,n.length-1)]}(r,t,e)}}},39172:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>q});var n=r(67294),i=r(86010),a=r(8131),s=r.n(a),c=r(70290),u=r.n(c),o=r(10412),h=r(35742),f=r(39960),l=r(80143),m=r(88824),d=r(66177),p=r(902),v=r(10833),g=r(82128),y=r(95999),R=r(52263),F=r(6278),b=r(239),P=r(7452);const j="searchQueryInput_u2C7",_="searchVersionInput_m0Ui",E="searchResultsColumn_JPFH",x="algoliaLogo_rT1R",w="algoliaLogoPathFill_WdUC",O="searchResultItem_Tv2o",N="searchResultItemHeading_KbCB",A="searchResultItemPath_lhe1",H="searchResultItemSummary_AEaO",S="searchQueryColumn_RTkw",T="searchVersionColumn_ypXd",Q="searchLogoColumn_rJIA",C="loadingSpinner_XVxU",k="loader_vvXV";function D(e){let{docsSearchVersionsHelpers:t}=e;const r=Object.entries(t.allDocsData).filter((e=>{let[,t]=e;return t.versions.length>1}));return n.createElement("div",{className:(0,i.Z)("col","col--3","padding-left--none",T)},r.map((e=>{let[i,a]=e;const s=r.length>1?`${i}: `:"";return n.createElement("select",{key:i,onChange:e=>t.setSearchVersion(i,e.target.value),defaultValue:t.searchVersions[i],className:_},a.versions.map(((e,t)=>n.createElement("option",{key:t,label:`${s}${e.label}`,value:e.name}))))})))}function I(){const{i18n:{currentLocale:e}}=(0,R.Z)(),{algolia:{appId:t,apiKey:r,indexName:a}}=(0,F.L)(),c=(0,b.l)(),v=function(){const{selectMessage:e}=(0,m.c)();return t=>e(t,(0,y.I)({id:"theme.SearchPage.documentsFound.plurals",description:'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One document found|{count} documents found"},{count:t}))}(),_=function(){const e=(0,l._r)(),[t,r]=(0,n.useState)((()=>Object.entries(e).reduce(((e,t)=>{let[r,n]=t;return{...e,[r]:n.versions[0].name}}),{}))),i=Object.values(e).some((e=>e.versions.length>1));return{allDocsData:e,versioningEnabled:i,searchVersions:t,setSearchVersion:(e,t)=>r((r=>({...r,[e]:t})))}}(),[T,I]=(0,d.K)(),q={items:[],query:null,totalResults:null,totalPages:null,lastPage:null,hasMore:null,loading:null},[V,L]=(0,n.useReducer)(((e,t)=>{switch(t.type){case"reset":return q;case"loading":return{...e,loading:!0};case"update":return T!==t.value.query?e:{...t.value,items:0===t.value.lastPage?t.value.items:e.items.concat(t.value.items)};case"advance":{const t=e.totalPages>e.lastPage+1;return{...e,lastPage:t?e.lastPage+1:e.lastPage,hasMore:t}}default:return e}}),q),B=u()(t,r),z=s()(B,a,{hitsPerPage:15,advancedSyntax:!0,disjunctiveFacets:["language","docusaurus_tag"]});z.on("result",(e=>{let{results:{query:t,hits:r,page:n,nbHits:i,nbPages:a}}=e;if(""===t||!Array.isArray(r))return void L({type:"reset"});const s=e=>e.replace(/algolia-docsearch-suggestion--highlight/g,"search-result-match"),u=r.map((e=>{let{url:t,_highlightResult:{hierarchy:r},_snippetResult:n={}}=e;const i=Object.keys(r).map((e=>s(r[e].value)));return{title:i.pop(),url:c(t),summary:n.content?`${s(n.content.value)}...`:"",breadcrumbs:i}}));L({type:"update",value:{items:u,query:t,totalResults:i,totalPages:a,lastPage:n,hasMore:a>n+1,loading:!1}})}));const[M,J]=(0,n.useState)(null),W=(0,n.useRef)(0),U=(0,n.useRef)(o.Z.canUseIntersectionObserver&&new IntersectionObserver((e=>{const{isIntersecting:t,boundingClientRect:{y:r}}=e[0];t&&W.current>r&&L({type:"advance"}),W.current=r}),{threshold:1})),Z=()=>T?(0,y.I)({id:"theme.SearchPage.existingResultsTitle",message:'Search results for "{query}"',description:"The search page title for non-empty query"},{query:T}):(0,y.I)({id:"theme.SearchPage.emptyResultsTitle",message:"Search the documentation",description:"The search page title for empty query"}),$=(0,p.zX)((function(t){void 0===t&&(t=0),z.addDisjunctiveFacetRefinement("docusaurus_tag","default"),z.addDisjunctiveFacetRefinement("language",e),Object.entries(_.searchVersions).forEach((e=>{let[t,r]=e;z.addDisjunctiveFacetRefinement("docusaurus_tag",`docs-${t}-${r}`)})),z.setQuery(T).setPage(t).search()}));return(0,n.useEffect)((()=>{if(!M)return;const e=U.current;return e?(e.observe(M),()=>e.unobserve(M)):()=>!0}),[M]),(0,n.useEffect)((()=>{L({type:"reset"}),T&&(L({type:"loading"}),setTimeout((()=>{$()}),300))}),[T,_.searchVersions,$]),(0,n.useEffect)((()=>{V.lastPage&&0!==V.lastPage&&$(V.lastPage)}),[$,V.lastPage]),n.createElement(P.Z,null,n.createElement(h.Z,null,n.createElement("title",null,(0,g.p)(Z())),n.createElement("meta",{property:"robots",content:"noindex, follow"})),n.createElement("div",{className:"container margin-vert--lg"},n.createElement("h1",null,Z()),n.createElement("form",{className:"row",onSubmit:e=>e.preventDefault()},n.createElement("div",{className:(0,i.Z)("col",S,{"col--9":_.versioningEnabled,"col--12":!_.versioningEnabled})},n.createElement("input",{type:"search",name:"q",className:j,placeholder:(0,y.I)({id:"theme.SearchPage.inputPlaceholder",message:"Type your search here",description:"The placeholder for search page input"}),"aria-label":(0,y.I)({id:"theme.SearchPage.inputLabel",message:"Search",description:"The ARIA label for search page input"}),onChange:e=>I(e.target.value),value:T,autoComplete:"off",autoFocus:!0})),_.versioningEnabled&&n.createElement(D,{docsSearchVersionsHelpers:_})),n.createElement("div",{className:"row"},n.createElement("div",{className:(0,i.Z)("col","col--8",E)},!!V.totalResults&&v(V.totalResults)),n.createElement("div",{className:(0,i.Z)("col","col--4","text--right",Q)},n.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:"https://www.algolia.com/","aria-label":(0,y.I)({id:"theme.SearchPage.algoliaLabel",message:"Search by Algolia",description:"The ARIA label for Algolia mention"})},n.createElement("svg",{viewBox:"0 0 168 24",className:x},n.createElement("g",{fill:"none"},n.createElement("path",{className:w,d:"M120.925 18.804c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 0 0-1.574-.199 5.7 5.7 0 0 0-.897.069 2.699 2.699 0 0 0-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 0 1-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 0 1-1.471-.636 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 0 1 1.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 0 1 1.82-.185 8.404 8.404 0 0 1 1.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 0 0-.384-.73 1.784 1.784 0 0 0-.724-.493 3.164 3.164 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 0 0-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 0 1 2.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 0 0-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 0 0-.814.24 1.46 1.46 0 0 0-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 0 1 .233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 0 1-1.471-.635 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 0 1 2.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 0 0-.109-.875 1.873 1.873 0 0 0-.384-.731 1.784 1.784 0 0 0-.724-.492 3.165 3.165 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 0 0-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 0 1 2.073-.177zm-8.034-1.271a1.626 1.626 0 0 1-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 0 1-1.128 1.906 4.986 4.986 0 0 1-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 0 1-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 0 1-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 0 1 1.15-1.892 5.133 5.133 0 0 1 1.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 0 1 1.753 1.216 5.644 5.644 0 0 1 1.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 0 0-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 0 1-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 0 1-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 0 1 2.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17zM6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 0 0-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 0 1-.582-.271 13.67 13.67 0 0 1-.55-.287 4.275 4.275 0 0 1-.567-.351 6.92 6.92 0 0 1-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 0 1-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 0 0-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 0 0-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 0 0-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 0 1-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z"}),n.createElement("path",{fill:"#5468FF",d:"M78.988.938h16.594a2.968 2.968 0 0 1 2.966 2.966V20.5a2.967 2.967 0 0 1-2.966 2.964H78.988a2.967 2.967 0 0 1-2.966-2.964V3.897A2.961 2.961 0 0 1 78.988.938z"}),n.createElement("path",{fill:"white",d:"M89.632 5.967v-.772a.978.978 0 0 0-.978-.977h-2.28a.978.978 0 0 0-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 0 1 1.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 0 0-1.382 0l-.465.465a.973.973 0 0 0 0 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 0 0-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 0 1-4.49-4.482 4.488 4.488 0 0 1 4.49-4.482 4.488 4.488 0 0 1 4.489 4.482 4.484 4.484 0 0 1-4.49 4.482m0-10.85a6.363 6.363 0 1 0 0 12.729 6.37 6.37 0 0 0 6.372-6.368 6.358 6.358 0 0 0-6.371-6.36"})))))),V.items.length>0?n.createElement("main",null,V.items.map(((e,t)=>{let{title:r,url:a,summary:s,breadcrumbs:c}=e;return n.createElement("article",{key:t,className:O},n.createElement("h2",{className:N},n.createElement(f.Z,{to:a,dangerouslySetInnerHTML:{__html:r}})),c.length>0&&n.createElement("nav",{"aria-label":"breadcrumbs"},n.createElement("ul",{className:(0,i.Z)("breadcrumbs",A)},c.map(((e,t)=>n.createElement("li",{key:t,className:"breadcrumbs__item",dangerouslySetInnerHTML:{__html:e}}))))),s&&n.createElement("p",{className:H,dangerouslySetInnerHTML:{__html:s}}))}))):[T&&!V.loading&&n.createElement("p",{key:"no-results"},n.createElement(y.Z,{id:"theme.SearchPage.noResultsText",description:"The paragraph for empty search result"},"No results were found")),!!V.loading&&n.createElement("div",{key:"spinner",className:C})],V.hasMore&&n.createElement("div",{className:k,ref:J},n.createElement(y.Z,{id:"theme.SearchPage.fetchingNewResults",description:"The paragraph for fetching new search results"},"Fetching new results..."))))}function q(){return n.createElement(v.FG,{className:"search-page-wrapper"},n.createElement(I,null))}}}]); \ No newline at end of file diff --git a/assets/js/1a4e3797.b205bd12.js.LICENSE.txt b/assets/js/1a4e3797.b205bd12.js.LICENSE.txt deleted file mode 100644 index 1d9697b99..000000000 --- a/assets/js/1a4e3797.b205bd12.js.LICENSE.txt +++ /dev/null @@ -1 +0,0 @@ -/*! algoliasearch-lite.umd.js | 4.14.2 | © Algolia, inc. | https://github.com/algolia/algoliasearch-client-javascript */ diff --git a/assets/js/1a6b9123.2138ce03.js b/assets/js/1a6b9123.f05b7812.js similarity index 84% rename from assets/js/1a6b9123.2138ce03.js rename to assets/js/1a6b9123.f05b7812.js index b3ee1bb37..74c4b8eb1 100644 --- a/assets/js/1a6b9123.2138ce03.js +++ b/assets/js/1a6b9123.f05b7812.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9874],{14343:e=>{e.exports=JSON.parse('{"label":"TecoChat","permalink":"/tags/teco-chat","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9874],{14343:e=>{e.exports=JSON.parse('{"label":"TecoChat","permalink":"/tags/teco-chat","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/1be78505.9fa0cbc0.js b/assets/js/1be78505.9fa0cbc0.js deleted file mode 100644 index 4e4c70ceb..000000000 --- a/assets/js/1be78505.9fa0cbc0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9514,4972],{19963:(e,t,n)=>{n.r(t),n.d(t,{default:()=>Se});var a=n(67294),l=n(86010),o=n(10833),r=n(35281),i=n(43320),c=n(53438),s=n(74477),d=n(1116),m=n(7452),u=n(95999),b=n(12466),p=n(85936);const h="backToTopButton_sjWU",E="backToTopButtonShow_xfvO";function f(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,l]=(0,a.useState)(!1),o=(0,a.useRef)(!1),{startScroll:r,cancelScroll:i}=(0,b.Ct)();return(0,b.RF)(((e,n)=>{let{scrollY:a}=e;const r=n?.scrollY;r&&(o.current?o.current=!1:a>=r?(i(),l(!1)):a{e.location.hash&&(o.current=!0,l(!1))})),{shown:n,scrollToTop:()=>r(0)}}({threshold:300});return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,l.Z)("clean-btn",r.k.common.backToTopButton,h,e&&E),type:"button",onClick:t})}var v=n(91442),g=n(16550),_=n(87524),k=n(86668),C=n(21327),S=n(87462);function I(e){return a.createElement("svg",(0,S.Z)({width:"20",height:"20","aria-hidden":"true"},e),a.createElement("g",{fill:"#7a7a7a"},a.createElement("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),a.createElement("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})))}const N="collapseSidebarButton_PEFL",Z="collapseSidebarButtonIcon_kv0_";function y(e){let{onClick:t}=e;return a.createElement("button",{type:"button",title:(0,u.I)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,l.Z)("button button--secondary button--outline",N),onClick:t},a.createElement(I,{className:Z}))}var x=n(59689),T=n(902);const w=Symbol("EmptyContext"),L=a.createContext(w);function A(e){let{children:t}=e;const[n,l]=(0,a.useState)(null),o=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:l})),[n]);return a.createElement(L.Provider,{value:o},t)}var M=n(86043),B=n(48596),F=n(39960),H=n(72389);function P(e){let{categoryLabel:t,onClick:n}=e;return a.createElement("button",{"aria-label":(0,u.I)({id:"theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel",message:"Toggle the collapsible sidebar category '{label}'",description:"The ARIA label to toggle the collapsible sidebar category"},{label:t}),type:"button",className:"clean-btn menu__caret",onClick:n})}function D(e){let{item:t,onItemClick:n,activePath:o,level:i,index:s,...d}=e;const{items:m,label:u,collapsible:b,className:p,href:h}=t,{docs:{sidebar:{autoCollapseCategories:E}}}=(0,k.L)(),f=function(e){const t=(0,H.Z)();return(0,a.useMemo)((()=>e.href?e.href:!t&&e.collapsible?(0,c.Wl)(e):void 0),[e,t])}(t),v=(0,c._F)(t,o),g=(0,B.Mg)(h,o),{collapsed:_,setCollapsed:C}=(0,M.u)({initialState:()=>!!b&&(!v&&t.collapsed)}),{expandedItem:I,setExpandedItem:N}=function(){const e=(0,a.useContext)(L);if(e===w)throw new T.i6("DocSidebarItemsExpandedStateProvider");return e}(),Z=function(e){void 0===e&&(e=!_),N(e?null:s),C(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:l}=e;const o=(0,T.D9)(t);(0,a.useEffect)((()=>{t&&!o&&n&&l(!1)}),[t,o,n,l])}({isActive:v,collapsed:_,updateCollapsed:Z}),(0,a.useEffect)((()=>{b&&null!=I&&I!==s&&E&&C(!0)}),[b,I,s,C,E]),a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemCategory,r.k.docs.docSidebarItemCategoryLevel(i),"menu__list-item",{"menu__list-item--collapsed":_},p)},a.createElement("div",{className:(0,l.Z)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":g})},a.createElement(F.Z,(0,S.Z)({className:(0,l.Z)("menu__link",{"menu__link--sublist":b,"menu__link--sublist-caret":!h&&b,"menu__link--active":v}),onClick:b?e=>{n?.(t),h?Z(!1):(e.preventDefault(),Z())}:()=>{n?.(t)},"aria-current":g?"page":void 0,"aria-expanded":b?!_:void 0,href:b?f??"#":f},d),u),h&&b&&a.createElement(P,{categoryLabel:u,onClick:e=>{e.preventDefault(),Z()}})),a.createElement(M.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:_},a.createElement(G,{items:m,tabIndex:_?-1:0,onItemClick:n,activePath:o,level:i+1})))}var W=n(13919),R=n(39471);const V="menuExternalLink_NmtK";function z(e){let{item:t,onItemClick:n,activePath:o,level:i,index:s,...d}=e;const{href:m,label:u,className:b,autoAddBaseUrl:p}=t,h=(0,c._F)(t,o),E=(0,W.Z)(m);return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(i),"menu__list-item",b),key:u},a.createElement(F.Z,(0,S.Z)({className:(0,l.Z)("menu__link",!E&&V,{"menu__link--active":h}),autoAddBaseUrl:p,"aria-current":h?"page":void 0,to:m},E&&{onClick:n?()=>n(t):void 0},d),u,!E&&a.createElement(R.Z,null)))}const U="menuHtmlItem_M9Kj";function K(e){let{item:t,level:n,index:o}=e;const{value:i,defaultStyle:c,className:s}=t;return a.createElement("li",{className:(0,l.Z)(r.k.docs.docSidebarItemLink,r.k.docs.docSidebarItemLinkLevel(n),c&&[U,"menu__list-item"],s),key:o,dangerouslySetInnerHTML:{__html:i}})}function j(e){let{item:t,...n}=e;switch(t.type){case"category":return a.createElement(D,(0,S.Z)({item:t},n));case"html":return a.createElement(K,(0,S.Z)({item:t},n));default:return a.createElement(z,(0,S.Z)({item:t},n))}}function q(e){let{items:t,...n}=e;return a.createElement(A,null,t.map(((e,t)=>a.createElement(j,(0,S.Z)({key:t,item:e,index:t},n)))))}const G=(0,a.memo)(q),Y="menu_SIkG",O="menuWithAnnouncementBar_GW3s";function X(e){let{path:t,sidebar:n,className:o}=e;const i=function(){const{isActive:e}=(0,x.nT)(),[t,n]=(0,a.useState)(e);return(0,b.RF)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return a.createElement("nav",{"aria-label":(0,u.I)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,l.Z)("menu thin-scrollbar",Y,i&&O,o)},a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(G,{items:n,activePath:t,level:1})))}const J="sidebar_njMd",Q="sidebarWithHideableNavbar_wUlq",$="sidebarHidden_VK0M",ee="sidebarLogo_isFc";function te(e){let{path:t,sidebar:n,onCollapse:o,isHidden:r}=e;const{navbar:{hideOnScroll:i},docs:{sidebar:{hideable:c}}}=(0,k.L)();return a.createElement("div",{className:(0,l.Z)(J,i&&Q,r&&$)},i&&a.createElement(C.Z,{tabIndex:-1,className:ee}),a.createElement(X,{path:t,sidebar:n}),c&&a.createElement(y,{onClick:o}))}const ne=a.memo(te);var ae=n(13102),le=n(93163);const oe=e=>{let{sidebar:t,path:n}=e;const o=(0,le.e)();return a.createElement("ul",{className:(0,l.Z)(r.k.docs.docSidebarMenu,"menu__list")},a.createElement(G,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&o.toggle(),"link"===e.type&&o.toggle()},level:1}))};function re(e){return a.createElement(ae.Zo,{component:oe,props:e})}const ie=a.memo(re);function ce(e){const t=(0,_.i)(),n="desktop"===t||"ssr"===t,l="mobile"===t;return a.createElement(a.Fragment,null,n&&a.createElement(ne,e),l&&a.createElement(ie,e))}const se="expandButton_m80_",de="expandButtonIcon_BlDH";function me(e){let{toggleSidebar:t}=e;return a.createElement("div",{className:se,title:(0,u.I)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,u.I)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t},a.createElement(I,{className:de}))}const ue={docSidebarContainer:"docSidebarContainer_b6E3",docSidebarContainerHidden:"docSidebarContainerHidden_b3ry",sidebarViewport:"sidebarViewport_Xe31"};function be(e){let{children:t}=e;const n=(0,d.V)();return a.createElement(a.Fragment,{key:n?.name??"noSidebar"},t)}function pe(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:o}=e;const{pathname:i}=(0,g.TH)(),[c,s]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{c&&s(!1),!c&&(0,v.n)()&&s(!0),o((e=>!e))}),[o,c]);return a.createElement("aside",{className:(0,l.Z)(r.k.docs.docSidebarContainer,ue.docSidebarContainer,n&&ue.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ue.docSidebarContainer)&&n&&s(!0)}},a.createElement(be,null,a.createElement("div",{className:(0,l.Z)(ue.sidebarViewport,c&&ue.sidebarViewportHidden)},a.createElement(ce,{sidebar:t,path:i,onCollapse:d,isHidden:c}),c&&a.createElement(me,{toggleSidebar:d}))))}const he={docMainContainer:"docMainContainer_gTbr",docMainContainerEnhanced:"docMainContainerEnhanced_Uz_u",docItemWrapperEnhanced:"docItemWrapperEnhanced_czyv"};function Ee(e){let{hiddenSidebarContainer:t,children:n}=e;const o=(0,d.V)();return a.createElement("main",{className:(0,l.Z)(he.docMainContainer,(t||!o)&&he.docMainContainerEnhanced)},a.createElement("div",{className:(0,l.Z)("container padding-top--md padding-bottom--lg",he.docItemWrapper,t&&he.docItemWrapperEnhanced)},n))}const fe="docPage__5DB",ve="docsWrapper_BCFX";function ge(e){let{children:t}=e;const n=(0,d.V)(),[l,o]=(0,a.useState)(!1);return a.createElement(m.Z,{wrapperClassName:ve},a.createElement(f,null),a.createElement("div",{className:fe},n&&a.createElement(pe,{sidebar:n.items,hiddenSidebarContainer:l,setHiddenSidebarContainer:o}),a.createElement(Ee,{hiddenSidebarContainer:l},t)))}var _e=n(4972),ke=n(90197);function Ce(e){const{versionMetadata:t}=e;return a.createElement(a.Fragment,null,a.createElement(ke.Z,{version:t.version,tag:(0,i.os)(t.pluginId,t.version)}),a.createElement(o.d,null,t.noIndex&&a.createElement("meta",{name:"robots",content:"noindex, nofollow"})))}function Se(e){const{versionMetadata:t}=e,n=(0,c.hI)(e);if(!n)return a.createElement(_e.default,null);const{docElement:i,sidebarName:m,sidebarItems:u}=n;return a.createElement(a.Fragment,null,a.createElement(Ce,e),a.createElement(o.FG,{className:(0,l.Z)(r.k.wrapper.docsPages,r.k.page.docsDocPage,e.versionMetadata.className)},a.createElement(s.q,{version:t},a.createElement(d.b,{name:m,items:u},a.createElement(ge,null,i)))))}},4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});var a=n(67294),l=n(95999),o=n(10833),r=n(7452);function i(){return a.createElement(a.Fragment,null,a.createElement(o.d,{title:(0,l.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(l.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}},74477:(e,t,n)=>{n.d(t,{E:()=>i,q:()=>r});var a=n(67294),l=n(902);const o=a.createContext(null);function r(e){let{children:t,version:n}=e;return a.createElement(o.Provider,{value:n},t)}function i(){const e=(0,a.useContext)(o);if(null===e)throw new l.i6("DocsVersionProvider");return e}}}]); \ No newline at end of file diff --git a/assets/js/1c93669b.866c6364.js b/assets/js/1c93669b.857fc62a.js similarity index 91% rename from assets/js/1c93669b.866c6364.js rename to assets/js/1c93669b.857fc62a.js index ba1753159..a1761f01c 100644 --- a/assets/js/1c93669b.866c6364.js +++ b/assets/js/1c93669b.857fc62a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6526],{37579:e=>{e.exports=JSON.parse('{"label":"monitoring","permalink":"/docs/tags/monitoring","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","title":"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","description":"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4","permalink":"/docs/monitoring/intro"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6526],{37579:e=>{e.exports=JSON.parse('{"label":"monitoring","permalink":"/docs/tags/monitoring","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","title":"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","description":"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4","permalink":"/docs/monitoring/intro"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/1d81daa1.821e44e6.js b/assets/js/1d81daa1.3c02c51a.js similarity index 88% rename from assets/js/1d81daa1.821e44e6.js rename to assets/js/1d81daa1.3c02c51a.js index d54dd4f70..4e8265ac1 100644 --- a/assets/js/1d81daa1.821e44e6.js +++ b/assets/js/1d81daa1.3c02c51a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7681],{76725:e=>{e.exports=JSON.parse('{"label":"Mock","permalink":"/tags/mock","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7681],{76725:e=>{e.exports=JSON.parse('{"label":"Mock","permalink":"/tags/mock","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/1e8ecffe.3c06cdf1.js b/assets/js/1e8ecffe.3c06cdf1.js deleted file mode 100644 index e9eee0042..000000000 --- a/assets/js/1e8ecffe.3c06cdf1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3333],{3905:(t,e,r)=>{r.d(e,{Zo:()=>c,kt:()=>k});var n=r(67294);function a(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function l(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function p(t){for(var e=1;e=0||(a[r]=t[r]);return a}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(a[r]=t[r])}return a}var i=n.createContext({}),u=function(t){var e=n.useContext(i),r=e;return t&&(r="function"==typeof t?t(e):p(p({},e),t)),r},c=function(t){var e=u(t.components);return n.createElement(i.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},s=n.forwardRef((function(t,e){var r=t.components,a=t.mdxType,l=t.originalType,i=t.parentName,c=o(t,["components","mdxType","originalType","parentName"]),s=u(r),k=a,d=s["".concat(i,".").concat(k)]||s[k]||m[k]||l;return r?n.createElement(d,p(p({ref:e},c),{},{components:r})):n.createElement(d,p({ref:e},c))}));function k(t,e){var r=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var l=r.length,p=new Array(l);p[0]=s;var o={};for(var i in e)hasOwnProperty.call(e,i)&&(o[i]=e[i]);o.originalType=t,o.mdxType="string"==typeof t?t:a,p[1]=o;for(var u=2;u{r.r(e),r.d(e,{assets:()=>i,contentTitle:()=>p,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const l={title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",slug:"refactoring-retrospective",tags:["Woowahan Techcourse","Retrospective"]},p=void 0,o={permalink:"/refactoring-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-refactoring/pull/465",date:"2023-10-31T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 31\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:8.055,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",slug:"refactoring-retrospective",tags:["Woowahan Techcourse","Retrospective"]},nextItem:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/jdbc-retrospective"}},i={authorsImageUrls:[]},u=[{value:"\ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158",id:"\ub9ac\ud329\ud130\ub9c1-\ubbf8\uc158",level:3},{value:"1, 2\ub2e8\uacc4",id:"1-2\ub2e8\uacc4",level:3},{value:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c",id:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758-\ubcf5\uc7a1\uc131\uc744-\ub2e4\ub8e8\ub294-\uc9c0\ud61c",level:3},{value:"3, 4\ub2e8\uacc4",id:"3-4\ub2e8\uacc4",level:3},{value:"\ub9c8\ubb34\ub9ac",id:"\ub9c8\ubb34\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:u};function m(t){let{components:e,...r}=t;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-refactoring/pull/465"},"https://github.com/woowacourse/jwp-refactoring/pull/465"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-refactoring/pull/547"},"https://github.com/woowacourse/jwp-refactoring/pull/547"),(0,a.kt)("br",{parentName:"p"}),"\n","3\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-refactoring/pull/610"},"https://github.com/woowacourse/jwp-refactoring/pull/610"),(0,a.kt)("br",{parentName:"p"}),"\n","4\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-refactoring/pull/721"},"https://github.com/woowacourse/jwp-refactoring/pull/721")," ")),(0,a.kt)("h3",{id:"\ub9ac\ud329\ud130\ub9c1-\ubbf8\uc158"},"\ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158"),(0,a.kt)("p",null,"\uc694\uad6c\uc0ac\ud56d \uc791\uc131 \u2192 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud55c \ucf54\ub4dc \ubcf4\ud638 \u2192 \ub9ac\ud329\ud130\ub9c1 \u2192 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1 \u2192 \uba40\ud2f0\ubaa8\ub4c8 \uc21c\uc11c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc5d0 \uc628\uc804\ud788 \uc9d1\uc911\ud558\uace0 \uc2f6\uc5c8\uc9c0\ub9cc, \ud504\ub85c\uc81d\ud2b8\uc640 \ubcd1\ud589\ud558\uba74\uc11c \uc9c4\ud589\ud588\uae30\uc5d0 \uc5b4\ub290\uc815\ub3c4 \ud0c0\ud611\ubcf4\uace0 \uc9c4\ud589\ud55c \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c \uc544\uc26c\uc6e0\ub2e4. "),(0,a.kt)("h3",{id:"1-2\ub2e8\uacc4"},"1, 2\ub2e8\uacc4"),(0,a.kt)("p",null,"1\ub2e8\uacc4\ub294 \uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud558\uace0, \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ucd94\ud6c4\uc5d0 \ub9ac\ud329\ud130\ub9c1 \ud560 \ub54c \uc548\uc815\uac10 \uc788\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\ub3c4\ub85d \uc900\ube44\ud558\ub294 \uacfc\uc815\uc774\uc5c8\ub2e4.\n\uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud560 \ub54c \uc81c\uacf5\ub41c \uc6a9\uc5b4 \uc0ac\uc804\uc744 \ucd5c\ub300\ud55c \ud65c\uc6a9\ud558\uba74\uc11c \uae30\uc874\uc758 \ucf54\ub4dc\ub97c \ubcf4\uba74\uc11c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud588\ub2e4.\n\ud14c\uc2a4\ud2b8\ub294 \uc2dc\uac04 \uad00\uacc4\uc0c1 API, \uc11c\ube44\uc2a4 \ub458 \uc911 \ud558\ub098\ub9cc \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ucd5c\uc885\uc801\uc73c\ub85c \uc11c\ube44\uc2a4 \uae30\uc900\uc73c\ub85c \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud588\ub294\ub370 \uc57d\uac04 \ud6c4\ud68c\ub418\ub294 \uacb0\uc815\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ud329\ud130\ub9c1 \uacfc\uc815\uc5d0\uc11c API \uba85\uc138\uac00 \ubc14\ub00c\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4\ub294 \uac83\uc744 \uae30\uc900\uc744 \uc7a1\uace0 \uc774\ubc88 \ubbf8\uc158\uc744 \ud55c\ub2e4\uace0 \uac00\uc815\ud588\uc744 \ub54c API \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\uace0, \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ub354 \uc548\uc815\uac10 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,a.kt)("p",null,"2\ub2e8\uacc4\ub294 \uc791\uc131\ub41c \ud14c\uc2a4\ud2b8 \uae30\ubc18\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc11c\ube44\uc2a4\uc5d0\uc11c \ub3c4\uba54\uc778\uc744 \uc9c1\uc811 \ubc18\ud658\ud558\ub294 \uad6c\uc870\uc600\ub294\ub370, \ub3c4\uba54\uc778\uc5d0 JPA\ub97c \uc801\uc6a9\ud558\uba74 \uae30\uc874 \uba85\uc138\uc640 \ub2ec\ub77c\uc9c8 \uac83\uc744 \uc6b0\ub824\ud574\uc11c DTO\ub85c \uc218\uc815\ud558\ub294 \uc791\uc5c5\uc744 \uba3c\uc800 \uc9c4\ud589\ud588\ub2e4.\nDTO \uc774\ud6c4\uc5d0 \uc11c\ube44\uc2a4\uc5d0 \uc788\ub294 \ub85c\uc9c1\uc744 \ub3c4\uba54\uc778\uc73c\ub85c \uc774\ub3d9\uc2dc\ud0a4\uace0, \ucd5c\uc885\uc801\uc73c\ub85c JPA\ub97c \uc801\uc6a9\ud558\ub294 \uc21c\uc11c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud588\ub2e4.\n\uc774 \uacfc\uc815\uc5d0\uc11c \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \uc591\ubc29\ud5a5\uc778 \ubd80\ubd84\ub3c4 \uc0dd\uaca8\ub0ac\ub2e4. "),(0,a.kt)("h3",{id:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758-\ubcf5\uc7a1\uc131\uc744-\ub2e4\ub8e8\ub294-\uc9c0\ud61c"},"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c"),(0,a.kt)("p",null,"\uc911\uac04\uc5d0 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\uc5d0 \uad00\ud55c \uc81c\uc774\uc2a8\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\ub294 \uc5d0\ub9ad \uc5d0\ubc18\uc2a4\uc758 \uc800\uc11c ",(0,a.kt)("inlineCode",{parentName:"p"},"\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4"),"\uc758 \ubd80\uc81c\uc774\ub2e4. "),(0,a.kt)("p",null,"\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\ub294 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4, \uc804\uc220\uc801 \uc124\uacc4\uac00 \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4\uac00 \uc804\uccb4\uc758 90%\uc5d0 \ud574\ub2f9\ud560 \uc815\ub3c4\ub85c \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4. \ub610\ud55c \uc804\uc220\uc801 \uc124\uacc4\ub9cc \ud558\ub294 \uacbd\uc6b0\ub97c DDD Lite \ub77c\uace0 \ud55c\ub2e4. "),(0,a.kt)("p",null,"\uac04\ub2e8\ud788 \ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\uc5d0\uc11c \ub098\uc624\ub294 \ub2e8\uc5b4\ub97c \uc815\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"\ub2e8\uc5b4"),(0,a.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ub3c4\uba54\uc778"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc18c\ud504\ud2b8\uc6e8\uc5b4\ub85c \ud574\uacb0\ud558\uace0\uc790 \ud558\ub294 \ubb38\uc81c \uc601\uc5ed")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud574\uacb0 \uc601\uc5ed, \uad00\uc2ec\uc0ac\ub97c \ubd84\ub9ac\ud558\uace0 \uaca9\ub9ac\ud558\uc5ec \ubb38\uc81c \ud574\uacb0\uc5d0 \uc9d1\uc911\ud560 \ubc94\uc704")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud504\ub85c\uc81d\ud2b8\uc5d0 \uc774\ud574\uad00\uacc4\uc790\ub4e4\uc758 \uacf5\ud1b5\ub41c \uc5b8\uc5b4\ub85c, \uc11c\ub85c\uc758 \uc758\uc0ac\uc18c\ud1b5 \ube44\uc6a9\uc744 \uc904\uc774\uae30 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 \uc5b8\uc5b4")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc804\ub7b5\uc801 \uc124\uacc4"),(0,a.kt)("td",{parentName:"tr",align:null},"\ub3c4\uba54\uc778 \uc804\ubb38\uac00\uc640 \uac1c\ubc1c\uc790\uac00 \ud568\uaed8 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec \ub3c4\uba54\uc778\uacfc \uad00\ub828\ub41c \uc9c0\uc2dd\uc744 \uc774\ud574\ud558\uace0 \uc774\ub97c \ubc14\ud0d5\uc73c\ub85c \uacbd\uacc4\ub97c \ub098\ub220 \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc815\uc758\ud558\uace0, \ucee8\ud14d\uc2a4\ud2b8 \ub9f5\uc744 \uc0dd\uc131\ud558\ub294 \uac83\uc744 \ud3ec\ud568\ud558\ub294 \uacfc\uc815")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc804\uc220\uc801 \uc124\uacc4"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc804\ub7b5\uc801 \uc124\uacc4\uc5d0\uc11c \uc815\uc758\ud55c \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\uc640 \ub3c4\uba54\uc778\uc744 \uc774\uc6a9\ud558\uc5ec \uc560\uadf8\ub9ac\uac70\ud2b8, Entity\uc640 VO, Repository \ub4f1\uc744 \uad6c\ud604\ud558\ub294 \uacfc\uc815")))),(0,a.kt)("p",null,"\uc774 \uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ub0b4\uc6a9\ub4e4\uc774 \ub098\uc654\uc9c0\ub9cc, \uc9c0\uc2dd\uc744 \uc81c\ub300\ub85c \ud761\uc218\ud558\uc9c0\ub294 \ubabb\ud588\ub2e4. "),(0,a.kt)("h3",{id:"3-4\ub2e8\uacc4"},"3, 4\ub2e8\uacc4"),(0,a.kt)("p",null,"\uc81c\uc774\uc2a8\uc758 \uac15\uc758\ub97c \ub4e3\uace0, \uc870\uc601\ud638\ub2d8\uc758 \uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5 \uc720\ud29c\ube0c \uc601\uc0c1\uc744 \ubcf8 \ub2e4\uc74c 3, 4\ub2e8\uacc4\ub97c \uc9c4\ud589\ud588\ub2e4. "),(0,a.kt)("p",null,"3\ub2e8\uacc4\ub294 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1\uc5d0 \uad00\ud55c \ub0b4\uc6a9\uc774\uc5c8\ub2e4. \ud074\ub798\uc2a4 \uac04 \ubc29\ud5a5, \ud328\ud0a4\uc9c0 \uac04 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc774 \ub418\ub3c4\ub85d \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud574\uc57c \ud588\uc5c8\ub2e4.\n\ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4\ub4e4\uc744 \ubb36\uace0, \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uae30 \uc704\ud574 \uc0dd\uba85\uc8fc\uae30\uac00 \ub2e4\ub974\ub2e4\uba74 id\ub97c \uc774\uc6a9\ud558\uc5ec \ucc38\uc870\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4. "),(0,a.kt)("p",null,"\uc758\uc874\uc131\uc744 \ubd84\ub9ac\ud558\uae30 \uc704\ud574 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. \uc774\ubca4\ud2b8\ub294 \ud604\uc7ac \uae30\uc900\uc73c\ub85c \uacfc\uac70\uc5d0 \ubc8c\uc5b4\uc9c4 \uac83\uc744 \ud45c\ud604\ud558\uae30 \ub54c\ubb38\uc5d0 \uc774\ubca4\ud2b8\uba85\uc740 \uacfc\uac70 \uc2dc\uc81c\uac00 \ub418\uc5b4\uc57c\ud558\ub294 \uac83\uc744 \uc54c\uc558\ub2e4.\n\ucc98\uc74c\uc5d0\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud588\uc9c0\ub9cc, \uc11c\ube44\uc2a4 \ub85c\uc9c1\uc744 \ucd5c\ub300\ud55c \uac04\ub2e8\ud558\uac8c \ud558\uae30 \uc704\ud574 \ub3c4\uba54\uc778 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. "),(0,a.kt)("p",null,"4\ub2e8\uacc4\ub294 \uba40\ud2f0\ubaa8\ub4c8\ub85c \ubd84\ub9ac\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub294\ub370 3\ub2e8\uacc4\uc5d0\uc11c \ubd84\ub9ac\ud574\ub454 \ud328\ud0a4\uc9c0 \uadf8\ub300\ub85c \ubd84\ub9ac\ud558\uc9c0\ub294 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","3\ub2e8\uacc4\uc5d0\uc11c\ub294 \ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4 \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ud588\ub2e4. 4\ub2e8\uacc4\uc5d0\uc11c\ub294 \ub0b4\uac00 \uc778\uc2dd\ud558\uae30 \ud3b8\ud55c \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ub97c \ud588\ub2e4.\n\uc544\uc9c1 \ubd84\ub9ac\ud55c \uae30\uc900\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \ubaa8\ud638\ud588\uace0, \uc774\uc5d0 \ub300\ud55c \uacf5\ubd80\ub97c \uc870\uae08 \ub354 \ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("mermaid",{value:"graph LR\n\tsubgraph Table\n\t\tOrderTable --\x3e TableGroup\n\tend\n\tsubgraph Order\n\t\tO\n\tend\n O[Order] --\x3e OrderTable\n\tsubgraph Menu\n\t\tM[Menu] --\x3e MenuGroup\n\t\tM --\x3e Product\n\tend\n\tO --\x3e M"}),(0,a.kt)("p",null,"\ucd94\uac00\ub85c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc704\ud55c ",(0,a.kt)("inlineCode",{parentName:"p"},"@ServiceTest")," \uc560\ub108\ud14c\uc774\uc158\uc774 \uc788\uc5c8\ub294\ub370, \uc0c1\uc704 \ubaa8\ub4c8\uc758 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \ub9cc\ub4e0 \ud074\ub798\uc2a4\ub97c \ud558\uc704 \ubaa8\ub4c8\uc5d0\uc11c\ub294 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4.\n\ub530\ub77c\uc11c TestFixtures\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\uacb0\ud588\ub2e4. "),(0,a.kt)("h3",{id:"\ub9c8\ubb34\ub9ac"},"\ub9c8\ubb34\ub9ac"),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc758 \ub9c8\uc9c0\ub9c9 \ubbf8\uc158\uc774\ub2c8 \ub9cc\ud07c, \uac00\uc7a5 \ud765\ubbf8\ub85c\uc6b4 \ubbf8\uc158\uc774\uc5c8\uace0 \ubc30\uc6b8\uc810\ub3c4 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc14\uc05c \uae30\uac04\uc774\ub77c \ub9ce\uc740 \ub9ac\ubdf0\ub97c \ub0a8\uae30\uc9c0 \ubabb\ud588\ub358 \ub9ac\ubdf0\uc774 \ud638\uc774\uc5d0\uac8c \ubbf8\uc548\ud558\uace0, \ucf54\uba58\ud2b8 \uaf3c\uaf3c\ud558\uac8c \ub2ec\uc544\uc8fc\uace0 \ubbf8\uc158\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub3c4 \uc624\ud504\ub77c\uc778\uc73c\ub85c \ub9ce\uc774 \ub098\ub208 \ub9ac\ubdf0\uc5b4 \ud14c\uc624\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=kmUneexSxk0"},"\ub3c4\uba54\uc778 \uc6d0\uc815\ub300, \uc6b0\uc544\ucf58 2021"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=dJ5C4qRqAgA"},"\uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5, \uc6b0\uc544\ud55c\ud14c\ud06c\uc138\ubbf8\ub098"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://kwonnam.pe.kr/wiki/gradle/testfixtures"},"TestFixtures, \uad8c\ub0a8\ub2d8")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1e8ecffe.de94e202.js b/assets/js/1e8ecffe.de94e202.js new file mode 100644 index 000000000..085d63f10 --- /dev/null +++ b/assets/js/1e8ecffe.de94e202.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3333],{58307:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>a});var n=t(85893),s=t(3905);const i={title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",slug:"refactoring-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,o={permalink:"/refactoring-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-refactoring/pull/465",date:"2023-10-31T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 31\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:8.095,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",slug:"refactoring-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,nextItem:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/jdbc-retrospective"}},l={authorsImageUrls:[]},a=[{value:"\ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158",id:"\ub9ac\ud329\ud130\ub9c1-\ubbf8\uc158",level:3},{value:"1, 2\ub2e8\uacc4",id:"1-2\ub2e8\uacc4",level:3},{value:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c",id:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758-\ubcf5\uc7a1\uc131\uc744-\ub2e4\ub8e8\ub294-\uc9c0\ud61c",level:3},{value:"3, 4\ub2e8\uacc4",id:"3-4\ub2e8\uacc4",level:3},{value:"\ub9c8\ubb34\ub9ac",id:"\ub9c8\ubb34\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const r={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",mermaid:"mermaid",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,n.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-refactoring/pull/465",children:"https://github.com/woowacourse/jwp-refactoring/pull/465"}),(0,n.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-refactoring/pull/547",children:"https://github.com/woowacourse/jwp-refactoring/pull/547"}),(0,n.jsx)(r.br,{}),"\n","3\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-refactoring/pull/610",children:"https://github.com/woowacourse/jwp-refactoring/pull/610"}),(0,n.jsx)(r.br,{}),"\n","4\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-refactoring/pull/721",children:"https://github.com/woowacourse/jwp-refactoring/pull/721"})]})}),"\n",(0,n.jsx)(r.h3,{id:"\ub9ac\ud329\ud130\ub9c1-\ubbf8\uc158",children:"\ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158"}),"\n",(0,n.jsxs)(r.p,{children:["\uc694\uad6c\uc0ac\ud56d \uc791\uc131 \u2192 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud55c \ucf54\ub4dc \ubcf4\ud638 \u2192 \ub9ac\ud329\ud130\ub9c1 \u2192 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1 \u2192 \uba40\ud2f0\ubaa8\ub4c8 \uc21c\uc11c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc5d0 \uc628\uc804\ud788 \uc9d1\uc911\ud558\uace0 \uc2f6\uc5c8\uc9c0\ub9cc, \ud504\ub85c\uc81d\ud2b8\uc640 \ubcd1\ud589\ud558\uba74\uc11c \uc9c4\ud589\ud588\uae30\uc5d0 \uc5b4\ub290\uc815\ub3c4 \ud0c0\ud611\ubcf4\uace0 \uc9c4\ud589\ud55c \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c \uc544\uc26c\uc6e0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"1-2\ub2e8\uacc4",children:"1, 2\ub2e8\uacc4"}),"\n",(0,n.jsx)(r.p,{children:"1\ub2e8\uacc4\ub294 \uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud558\uace0, \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ucd94\ud6c4\uc5d0 \ub9ac\ud329\ud130\ub9c1 \ud560 \ub54c \uc548\uc815\uac10 \uc788\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\ub3c4\ub85d \uc900\ube44\ud558\ub294 \uacfc\uc815\uc774\uc5c8\ub2e4.\n\uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud560 \ub54c \uc81c\uacf5\ub41c \uc6a9\uc5b4 \uc0ac\uc804\uc744 \ucd5c\ub300\ud55c \ud65c\uc6a9\ud558\uba74\uc11c \uae30\uc874\uc758 \ucf54\ub4dc\ub97c \ubcf4\uba74\uc11c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud588\ub2e4.\n\ud14c\uc2a4\ud2b8\ub294 \uc2dc\uac04 \uad00\uacc4\uc0c1 API, \uc11c\ube44\uc2a4 \ub458 \uc911 \ud558\ub098\ub9cc \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4."}),"\n",(0,n.jsxs)(r.p,{children:["\ucd5c\uc885\uc801\uc73c\ub85c \uc11c\ube44\uc2a4 \uae30\uc900\uc73c\ub85c \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud588\ub294\ub370 \uc57d\uac04 \ud6c4\ud68c\ub418\ub294 \uacb0\uc815\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub9ac\ud329\ud130\ub9c1 \uacfc\uc815\uc5d0\uc11c API \uba85\uc138\uac00 \ubc14\ub00c\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4\ub294 \uac83\uc744 \uae30\uc900\uc744 \uc7a1\uace0 \uc774\ubc88 \ubbf8\uc158\uc744 \ud55c\ub2e4\uace0 \uac00\uc815\ud588\uc744 \ub54c API \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\uace0, \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ub354 \uc548\uc815\uac10 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["2\ub2e8\uacc4\ub294 \uc791\uc131\ub41c \ud14c\uc2a4\ud2b8 \uae30\ubc18\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc11c\ube44\uc2a4\uc5d0\uc11c \ub3c4\uba54\uc778\uc744 \uc9c1\uc811 \ubc18\ud658\ud558\ub294 \uad6c\uc870\uc600\ub294\ub370, \ub3c4\uba54\uc778\uc5d0 JPA\ub97c \uc801\uc6a9\ud558\uba74 \uae30\uc874 \uba85\uc138\uc640 \ub2ec\ub77c\uc9c8 \uac83\uc744 \uc6b0\ub824\ud574\uc11c DTO\ub85c \uc218\uc815\ud558\ub294 \uc791\uc5c5\uc744 \uba3c\uc800 \uc9c4\ud589\ud588\ub2e4.\nDTO \uc774\ud6c4\uc5d0 \uc11c\ube44\uc2a4\uc5d0 \uc788\ub294 \ub85c\uc9c1\uc744 \ub3c4\uba54\uc778\uc73c\ub85c \uc774\ub3d9\uc2dc\ud0a4\uace0, \ucd5c\uc885\uc801\uc73c\ub85c JPA\ub97c \uc801\uc6a9\ud558\ub294 \uc21c\uc11c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud588\ub2e4.\n\uc774 \uacfc\uc815\uc5d0\uc11c \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \uc591\ubc29\ud5a5\uc778 \ubd80\ubd84\ub3c4 \uc0dd\uaca8\ub0ac\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758-\ubcf5\uc7a1\uc131\uc744-\ub2e4\ub8e8\ub294-\uc9c0\ud61c",children:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c"}),"\n",(0,n.jsxs)(r.p,{children:["\uc911\uac04\uc5d0 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\uc5d0 \uad00\ud55c \uc81c\uc774\uc2a8\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\ub294 \uc5d0\ub9ad \uc5d0\ubc18\uc2a4\uc758 \uc800\uc11c ",(0,n.jsx)(r.code,{children:"\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4"}),"\uc758 \ubd80\uc81c\uc774\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\ub294 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4, \uc804\uc220\uc801 \uc124\uacc4\uac00 \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4\uac00 \uc804\uccb4\uc758 90%\uc5d0 \ud574\ub2f9\ud560 \uc815\ub3c4\ub85c \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4. \ub610\ud55c \uc804\uc220\uc801 \uc124\uacc4\ub9cc \ud558\ub294 \uacbd\uc6b0\ub97c DDD Lite \ub77c\uace0 \ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:"\uac04\ub2e8\ud788 \ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\uc5d0\uc11c \ub098\uc624\ub294 \ub2e8\uc5b4\ub97c \uc815\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,n.jsxs)(r.table,{children:[(0,n.jsx)(r.thead,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.th,{children:"\ub2e8\uc5b4"}),(0,n.jsx)(r.th,{children:"\uc124\uba85"})]})}),(0,n.jsxs)(r.tbody,{children:[(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\ub3c4\uba54\uc778"}),(0,n.jsx)(r.td,{children:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\ub85c \ud574\uacb0\ud558\uace0\uc790 \ud558\ub294 \ubb38\uc81c \uc601\uc5ed"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8"}),(0,n.jsx)(r.td,{children:"\ud574\uacb0 \uc601\uc5ed, \uad00\uc2ec\uc0ac\ub97c \ubd84\ub9ac\ud558\uace0 \uaca9\ub9ac\ud558\uc5ec \ubb38\uc81c \ud574\uacb0\uc5d0 \uc9d1\uc911\ud560 \ubc94\uc704"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4"}),(0,n.jsx)(r.td,{children:"\ud504\ub85c\uc81d\ud2b8\uc5d0 \uc774\ud574\uad00\uacc4\uc790\ub4e4\uc758 \uacf5\ud1b5\ub41c \uc5b8\uc5b4\ub85c, \uc11c\ub85c\uc758 \uc758\uc0ac\uc18c\ud1b5 \ube44\uc6a9\uc744 \uc904\uc774\uae30 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 \uc5b8\uc5b4"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\uc804\ub7b5\uc801 \uc124\uacc4"}),(0,n.jsx)(r.td,{children:"\ub3c4\uba54\uc778 \uc804\ubb38\uac00\uc640 \uac1c\ubc1c\uc790\uac00 \ud568\uaed8 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec \ub3c4\uba54\uc778\uacfc \uad00\ub828\ub41c \uc9c0\uc2dd\uc744 \uc774\ud574\ud558\uace0 \uc774\ub97c \ubc14\ud0d5\uc73c\ub85c \uacbd\uacc4\ub97c \ub098\ub220 \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc815\uc758\ud558\uace0, \ucee8\ud14d\uc2a4\ud2b8 \ub9f5\uc744 \uc0dd\uc131\ud558\ub294 \uac83\uc744 \ud3ec\ud568\ud558\ub294 \uacfc\uc815"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\uc804\uc220\uc801 \uc124\uacc4"}),(0,n.jsx)(r.td,{children:"\uc804\ub7b5\uc801 \uc124\uacc4\uc5d0\uc11c \uc815\uc758\ud55c \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\uc640 \ub3c4\uba54\uc778\uc744 \uc774\uc6a9\ud558\uc5ec \uc560\uadf8\ub9ac\uac70\ud2b8, Entity\uc640 VO, Repository \ub4f1\uc744 \uad6c\ud604\ud558\ub294 \uacfc\uc815"})]})]})]}),"\n",(0,n.jsx)(r.p,{children:"\uc774 \uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ub0b4\uc6a9\ub4e4\uc774 \ub098\uc654\uc9c0\ub9cc, \uc9c0\uc2dd\uc744 \uc81c\ub300\ub85c \ud761\uc218\ud558\uc9c0\ub294 \ubabb\ud588\ub2e4."}),"\n",(0,n.jsx)(r.h3,{id:"3-4\ub2e8\uacc4",children:"3, 4\ub2e8\uacc4"}),"\n",(0,n.jsx)(r.p,{children:"\uc81c\uc774\uc2a8\uc758 \uac15\uc758\ub97c \ub4e3\uace0, \uc870\uc601\ud638\ub2d8\uc758 \uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5 \uc720\ud29c\ube0c \uc601\uc0c1\uc744 \ubcf8 \ub2e4\uc74c 3, 4\ub2e8\uacc4\ub97c \uc9c4\ud589\ud588\ub2e4."}),"\n",(0,n.jsx)(r.p,{children:"3\ub2e8\uacc4\ub294 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1\uc5d0 \uad00\ud55c \ub0b4\uc6a9\uc774\uc5c8\ub2e4. \ud074\ub798\uc2a4 \uac04 \ubc29\ud5a5, \ud328\ud0a4\uc9c0 \uac04 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc774 \ub418\ub3c4\ub85d \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud574\uc57c \ud588\uc5c8\ub2e4.\n\ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4\ub4e4\uc744 \ubb36\uace0, \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uae30 \uc704\ud574 \uc0dd\uba85\uc8fc\uae30\uac00 \ub2e4\ub974\ub2e4\uba74 id\ub97c \uc774\uc6a9\ud558\uc5ec \ucc38\uc870\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4."}),"\n",(0,n.jsx)(r.p,{children:"\uc758\uc874\uc131\uc744 \ubd84\ub9ac\ud558\uae30 \uc704\ud574 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. \uc774\ubca4\ud2b8\ub294 \ud604\uc7ac \uae30\uc900\uc73c\ub85c \uacfc\uac70\uc5d0 \ubc8c\uc5b4\uc9c4 \uac83\uc744 \ud45c\ud604\ud558\uae30 \ub54c\ubb38\uc5d0 \uc774\ubca4\ud2b8\uba85\uc740 \uacfc\uac70 \uc2dc\uc81c\uac00 \ub418\uc5b4\uc57c\ud558\ub294 \uac83\uc744 \uc54c\uc558\ub2e4.\n\ucc98\uc74c\uc5d0\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud588\uc9c0\ub9cc, \uc11c\ube44\uc2a4 \ub85c\uc9c1\uc744 \ucd5c\ub300\ud55c \uac04\ub2e8\ud558\uac8c \ud558\uae30 \uc704\ud574 \ub3c4\uba54\uc778 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4."}),"\n",(0,n.jsxs)(r.p,{children:["4\ub2e8\uacc4\ub294 \uba40\ud2f0\ubaa8\ub4c8\ub85c \ubd84\ub9ac\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub294\ub370 3\ub2e8\uacc4\uc5d0\uc11c \ubd84\ub9ac\ud574\ub454 \ud328\ud0a4\uc9c0 \uadf8\ub300\ub85c \ubd84\ub9ac\ud558\uc9c0\ub294 \uc54a\uc558\ub2e4.",(0,n.jsx)(r.br,{}),"\n","3\ub2e8\uacc4\uc5d0\uc11c\ub294 \ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4 \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ud588\ub2e4. 4\ub2e8\uacc4\uc5d0\uc11c\ub294 \ub0b4\uac00 \uc778\uc2dd\ud558\uae30 \ud3b8\ud55c \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ub97c \ud588\ub2e4.\n\uc544\uc9c1 \ubd84\ub9ac\ud55c \uae30\uc900\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \ubaa8\ud638\ud588\uace0, \uc774\uc5d0 \ub300\ud55c \uacf5\ubd80\ub97c \uc870\uae08 \ub354 \ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,n.jsx)(r.mermaid,{value:"graph LR\n\tsubgraph Table\n\t\tOrderTable --\x3e TableGroup\n\tend\n\tsubgraph Order\n\t\tO\n\tend\n O[Order] --\x3e OrderTable\n\tsubgraph Menu\n\t\tM[Menu] --\x3e MenuGroup\n\t\tM --\x3e Product\n\tend\n\tO --\x3e M"}),"\n",(0,n.jsxs)(r.p,{children:["\ucd94\uac00\ub85c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc704\ud55c \uc9c1\uc811 \uc791\uc131\ud55c ",(0,n.jsx)(r.code,{children:"@ServiceTest"})," \ucee4\uc2a4\ud140 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc788\uc5c8\ub294\ub370, \uc0c1\uc704 \ubaa8\ub4c8\uc758 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \ub9cc\ub4e0 \ud074\ub798\uc2a4\ub97c \ud558\uc704 \ubaa8\ub4c8\uc5d0\uc11c\ub294 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4.\n\ub530\ub77c\uc11c TestFixtures\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\uacb0\ud588\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ub9c8\ubb34\ub9ac",children:"\ub9c8\ubb34\ub9ac"}),"\n",(0,n.jsxs)(r.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc758 \ub9c8\uc9c0\ub9c9 \ubbf8\uc158\uc774\ub2c8 \ub9cc\ud07c, \uac00\uc7a5 \ud765\ubbf8\ub85c\uc6b4 \ubbf8\uc158\uc774\uc5c8\uace0 \ubc30\uc6b8\uc810\ub3c4 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubc14\uc05c \uae30\uac04\uc774\ub77c \ub9ce\uc740 \ub9ac\ubdf0\ub97c \ub0a8\uae30\uc9c0 \ubabb\ud588\ub358 \ub9ac\ubdf0\uc774 \ud638\uc774\uc5d0\uac8c \ubbf8\uc548\ud558\uace0, \ucf54\uba58\ud2b8 \uaf3c\uaf3c\ud558\uac8c \ub2ec\uc544\uc8fc\uace0 \ubbf8\uc158\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub3c4 \uc624\ud504\ub77c\uc778\uc73c\ub85c \ub9ce\uc774 \ub098\ub208 \ub9ac\ubdf0\uc5b4 \ud14c\uc624\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsxs)(r.p,{children:[(0,n.jsx)(r.a,{href:"https://www.youtube.com/watch?v=kmUneexSxk0",children:"\ub3c4\uba54\uc778 \uc6d0\uc815\ub300, \uc6b0\uc544\ucf58 2021"}),(0,n.jsx)(r.br,{}),"\n",(0,n.jsx)(r.a,{href:"https://www.youtube.com/watch?v=dJ5C4qRqAgA",children:"\uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5, \uc6b0\uc544\ud55c\ud14c\ud06c\uc138\ubbf8\ub098"}),(0,n.jsx)(r.br,{}),"\n",(0,n.jsx)(r.a,{href:"https://kwonnam.pe.kr/wiki/gradle/testfixtures",children:"TestFixtures, \uad8c\ub0a8\ub2d8"})]})]})}function h(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>a});var n=t(67294);function s(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function c(e){for(var r=1;r=0||(s[t]=e[t]);return s}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var l=n.createContext({}),a=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},h=n.forwardRef((function(e,r){var t=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,h=o(e,["components","mdxType","originalType","parentName"]),p=a(t),u=s,j=p["".concat(l,".").concat(u)]||p[u]||d[u]||i;return t?n.createElement(j,c(c({ref:r},h),{},{components:t})):n.createElement(j,c({ref:r},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/1f05d14a.8224f0a8.js b/assets/js/1f05d14a.8224f0a8.js deleted file mode 100644 index 404fa5487..000000000 --- a/assets/js/1f05d14a.8224f0a8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[656],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var l=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);t&&(l=l.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,l)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(l=0;l=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=l.createContext({}),s=function(e){var t=l.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=s(e.components);return l.createElement(i.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return l.createElement(l.Fragment,{},t)}},d=l.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,c=u(e,["components","mdxType","originalType","parentName"]),d=s(n),m=a,f=d["".concat(i,".").concat(m)]||d[m]||p[m]||r;return n?l.createElement(f,o(o({ref:t},c),{},{components:n})):l.createElement(f,o({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=d;var u={};for(var i in t)hasOwnProperty.call(t,i)&&(u[i]=t[i]);u.originalType=e,u.mdxType="string"==typeof e?e:a,o[1]=u;for(var s=2;s{n.d(t,{Z:()=>o});var l=n(67294),a=n(86010);const r="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return l.createElement("div",{role:"tabpanel",className:(0,a.Z)(r,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>w});var l=n(87462),a=n(67294),r=n(86010),o=n(12466),u=n(16550),i=n(91980),s=n(67392),c=n(50012);function p(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:l,default:a}}=e;return{value:t,label:n,attributes:l,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,s.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const l=(0,u.k6)(),r=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,i._X)(r),(0,a.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(l.location.search);t.set(r,e),l.replace({...l.location,search:t.toString()})}),[r,l])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:l}=e,r=d(e),[o,u]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const l=n.find((e=>e.default))??n[0];if(!l)throw new Error("Unexpected error: 0 tabValues");return l.value}({defaultValue:t,tabValues:r}))),[i,s]=f({queryString:n,groupId:l}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[l,r]=(0,c.Nk)(n);return[l,(0,a.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:l}),k=(()=>{const e=i??p;return m({value:e,tabValues:r})?e:null})();(0,a.useLayoutEffect)((()=>{k&&u(k)}),[k]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);u(e),s(e),b(e)}),[s,b,r]),tabValues:r}}var k=n(72389);const g="tabList__CuJ",v="tabItem_LNqP";function h(e){let{className:t,block:n,selectedValue:u,selectValue:i,tabValues:s}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),l=s[n].value;l!==u&&(p(t),i(l))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},s.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,l.Z)({role:"tab",tabIndex:u===t?0:-1,"aria-selected":u===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,r.Z)("tabs__item",v,o?.className,{"tabs__item--active":u===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:l}=e;const r=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=r.find((e=>e.props.value===l));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==l}))))}function N(e){const t=b(e);return a.createElement("div",{className:(0,r.Z)("tabs-container",g)},a.createElement(h,(0,l.Z)({},e,t)),a.createElement(y,(0,l.Z)({},e,t)))}function w(e){const t=(0,k.Z)();return a.createElement(N,(0,l.Z)({key:String(t)},e))}},65945:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>u,metadata:()=>s,toc:()=>p});var l=n(87462),a=(n(67294),n(3905)),r=n(74866),o=n(85162);const u={title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",slug:"kotlin-null",tags:["Kotlin"]},i=void 0,s={permalink:"/kotlin-null",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",source:"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",description:"nullable \ud0c0\uc785",date:"2023-01-16T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 16\uc77c",tags:[{label:"Kotlin",permalink:"/tags/kotlin"}],readingTime:4.225,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",slug:"kotlin-null",tags:["Kotlin"]},prevItem:{title:"IntelliJ \uc124\uc815",permalink:"/intellij-settings"},nextItem:{title:"JSR-310",permalink:"/jsr-310"}},c={authorsImageUrls:[]},p=[{value:"nullable \ud0c0\uc785",id:"nullable-\ud0c0\uc785",level:3},{value:"?. Safe Calls \uc5f0\uc0b0\uc790",id:"-safe-calls-\uc5f0\uc0b0\uc790",level:3},{value:"?: \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790",id:"-\uc5d8\ube44\uc2a4-\uc5f0\uc0b0\uc790",level:3},{value:"!! \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790",id:"-\ub110-\uc544\ub2d8-\ub2e8\uc5b8-\uc5f0\uc0b0\uc790",level:3},{value:"as? \uc548\uc804\ud55c \uce90\uc2a4\ud305",id:"as-\uc548\uc804\ud55c-\uce90\uc2a4\ud305",level:3},{value:"List\uc5d0\uc11c\uc758 null \ucc98\ub9ac",id:"list\uc5d0\uc11c\uc758-null-\ucc98\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],d={toc:p};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,l.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"nullable-\ud0c0\uc785"},"nullable \ud0c0\uc785"),(0,a.kt)("p",null,"\ucf54\ud2c0\ub9b0\uc740 ",(0,a.kt)("inlineCode",{parentName:"p"},"NullPointerException")," \uc608\uc678\ub97c \ucd5c\ub300\ud55c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 \ud0c0\uc785 \uc2dc\uc2a4\ud15c\uc774 \uc124\uacc4\ub418\uc5b4 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 \uc2e4\ud589 \uc2dc\uc810\uc774 \uc544\ub2cc \ucef4\ud30c\uc77c \uc2dc \ubbf8\ub9ac \uc624\ub958\uac00 \ubc1c\uc0dd\ud560 \uac00\ub2a5\uc131\uc774 \uc788\ub294 \ubd80\ubd84\uc744 \ubbf8\ub9ac \uac10\uc9c0\ud558\uc5ec NPE \ubc1c\uc0dd\uc758 \uac00\ub2a5\uc131\uc744 \uc904\uc5ec\uc900\ub2e4."),(0,a.kt)("p",null,"\ucf54\ud2c0\ub9b0\uc758 \uacbd\uc6b0 nullable \ud0c0\uc785\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \ud45c\ud604\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"val number: Int?\n")),(0,a.kt)("p",null,"\ud0c0\uc785 \ub4a4\uc5d0 ",(0,a.kt)("inlineCode",{parentName:"p"},"?"),"\ub97c \ubd99\uc5ec \ud574\ub2f9 \uac12\uc774 null\uc774 \ub420 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9cc\uc57d ",(0,a.kt)("inlineCode",{parentName:"p"},"?"),"\ub97c \ubd99\uc774\uc9c0 \uc54a\uc744 \ub54c null\uc744 \ubc1b\ub294 \uacbd\uc6b0 \ucef4\ud30c\uc77c \uc2dc \uc624\ub958\uac00 \ubc1c\uc0dd\ud55c\ub2e4."),(0,a.kt)("h3",{id:"-safe-calls-\uc5f0\uc0b0\uc790"},(0,a.kt)("inlineCode",{parentName:"h3"},"?.")," Safe Calls \uc5f0\uc0b0\uc790"),(0,a.kt)("p",null,"\uc790\ubc14\uc5d0\uc11c NPE\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 null\uc744 \ucc98\ub9ac\ud558\ub294 \uac00\uc7a5 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c\ub294 \ubd84\uae30\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4."),(0,a.kt)("p",null,"\ucf54\ud2c0\ub9b0\uc740 \uc548\uc804\ud55c \ud638\ucd9c \uc5f0\uc0b0\uc790\uc778 ",(0,a.kt)("inlineCode",{parentName:"p"},"?.")," \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ucc38\uc870 \uac12\uc774 null\uc774 \uc544\ub2d0 \uacbd\uc6b0\uc5d0\ub9cc \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc38\uc870 \uac12\uc774 null\uc778 \uacbd\uc6b0 \uba54\uc11c\ub4dc \ud638\ucd9c\uc774 \ubb34\uc2dc\ub418\uace0, null\uc744 \ubc18\ud658\ud55c\ub2e4. "),(0,a.kt)(r.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Java",label:"Java",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public String repeat(String word) {\n if (word == null) {\n return null;\n }\n return word.repeat(2);\n}\n"))),(0,a.kt)(o.Z,{value:"Kotlin",label:"Kotlin",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"fun repeat(word: String?): String? {\n return word?.repeat(2)\n}\n")))),(0,a.kt)("h3",{id:"-\uc5d8\ube44\uc2a4-\uc5f0\uc0b0\uc790"},(0,a.kt)("inlineCode",{parentName:"h3"},"?:")," \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790"),(0,a.kt)("p",null,"\ucc38\uc870\ud558\ub824\ub294 \uac12\uc774 null\uc77c \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud558\uace0 \uc2f6\uc744 \ub54c\ub294 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\ucf54\ud2c0\ub9b0\uc740 null\uc774 \uc544\ub2cc \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \ub54c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4."),(0,a.kt)(r.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Java",label:"Java",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public String stringSafe(String word) {\n if (word == null) {\n return "";\n }\n return word;\n}\n'))),(0,a.kt)(o.Z,{value:"Kotlin",label:"Kotlin",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'fun stringSafe(word: String?): String {\n return word ?: ""\n}\n')))),(0,a.kt)("p",null,"\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 throw\ub3c4 \uc2dd\uc774\uae30 \ub54c\ubb38\uc5d0 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\ub97c \ub4e4\uc5b4 \uc0ac\uc6a9\uc790 \uc815\ubcf4\uac00 \uc788\ub294 \uc800\uc7a5\uc18c\uc5d0 \ucc3e\ub294 \uc0ac\uc6a9\uc790\uac00 \uc5c6\ub294 \uacbd\uc6b0 \uc544\ub798\uc640 \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"userRepository.findByName(name) ?: throw IllegalArgumentException()\n")),(0,a.kt)("h3",{id:"-\ub110-\uc544\ub2d8-\ub2e8\uc5b8-\uc5f0\uc0b0\uc790"},(0,a.kt)("inlineCode",{parentName:"h3"},"!!")," \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790"),(0,a.kt)("p",null,"!! \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud55c\ub2e4\uba74 \uac15\uc81c\ub85c \uc5b4\ub5a4 \uac12\uc774\ub4e0 non-nullable \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc null\uc778 \uac12\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4\uba74 NPE\uac00 \ubc1c\uc0dd\ud558\uac8c \ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ubc18\uc801\uc778 \uacbd\uc6b0\uc5d0\ub294 !! \uc5f0\uc0b0\uc790\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc704\ud5d8\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc6a9\ud558\uae30 \uc27d\uc9c0\ub9cc, \ub9ac\uc2a4\ud06c\uac00 \ud06c\uace0 \ud639\uc2dc\ub098 \ud574\ub2f9 \uac12\uc774 \ucd94\ud6c4\uc5d0\ub294 null\uc774 \ub420 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc591\ud574\uc57c \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"val length: Int = word!!.length\n")),(0,a.kt)("h3",{id:"as-\uc548\uc804\ud55c-\uce90\uc2a4\ud305"},(0,a.kt)("inlineCode",{parentName:"h3"},"as?")," \uc548\uc804\ud55c \uce90\uc2a4\ud305"),(0,a.kt)("p",null,"\ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \ub54c \uc9c0\uc815\ud55c \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc5c6\ub2e4\uba74 ",(0,a.kt)("inlineCode",{parentName:"p"},"ClassCastException"),"\uc774 \ubc1c\uc0dd\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 as \ub4a4\uc5d0 ?\ub97c \ubd99\uc5ec \uc548\uc804\ud558\uac8c \ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ubbf8\ub9ac \ubcc0\ud658 \uac00\ub2a5\ud55c \ud0c0\uc785\uc778\uc9c0 \ud655\uc778\ud558\uc9c0 \uc54a\uace0, \uc548\uc804\ud558\uac8c \ud0c0\uc785\uc744 \ubcc0\ud658 \ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("p",null,"\ud0c0\uc785 \ubcc0\ud658\uc774 \ubd88\uac00\ub2a5 \ud560 \uacbd\uc6b0 \uc608\uc678\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uace0 null\uc744 \ubc18\ud658\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"val value: Int? = something as? Int\n")),(0,a.kt)("h3",{id:"list\uc5d0\uc11c\uc758-null-\ucc98\ub9ac"},"List\uc5d0\uc11c\uc758 null \ucc98\ub9ac"),(0,a.kt)("p",null,"List\uc5d0\ub294 null\uc774 \uc544\ub2cc \uac12\ub9cc \ubc18\ud658\ud558\ub294 ",(0,a.kt)("inlineCode",{parentName:"p"},"filterNotNull")," \uc720\ud2f8\ub9ac\ud2f0 \uba54\uc11c\ub4dc\ub97c \uc81c\uacf5\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'val foodsWithNull: List = listOf("Pizza", "Cheese", null, "Potato")\nval foods = foodsWithNull.filterNotNull()\n')),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://product.kyobobook.co.kr/detail/S000001804588"},"Kotlin in Action")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://product.kyobobook.co.kr/detail/S000001033129"},"Effective Kotlin Item 8")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.baeldung.com/kotlin/null-safety"},"Comprehensive Guide to Null Safety in Kotlin")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kotlinlang.org/docs/null-safety.html"},"Kotlin NullSafety"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1f05d14a.da3635f1.js b/assets/js/1f05d14a.da3635f1.js new file mode 100644 index 000000000..b89ba1072 --- /dev/null +++ b/assets/js/1f05d14a.da3635f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[656],{9938:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>u,toc:()=>d});var r=l(85893),t=l(3905),a=l(74866),s=l(85162);const i={title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",slug:"kotlin-null",tags:["Kotlin"]},o=void 0,u={permalink:"/kotlin-null",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",source:"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",description:"nullable \ud0c0\uc785",date:"2023-01-16T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 16\uc77c",tags:[{label:"Kotlin",permalink:"/tags/kotlin"}],readingTime:4.225,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",slug:"kotlin-null",tags:["Kotlin"]},unlisted:!1,prevItem:{title:"IntelliJ \uc124\uc815",permalink:"/intellij-settings"},nextItem:{title:"JSR-310",permalink:"/jsr-310"}},c={authorsImageUrls:[]},d=[{value:"nullable \ud0c0\uc785",id:"nullable-\ud0c0\uc785",level:3},{value:"?. Safe Calls \uc5f0\uc0b0\uc790",id:"-safe-calls-\uc5f0\uc0b0\uc790",level:3},{value:"?: \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790",id:"-\uc5d8\ube44\uc2a4-\uc5f0\uc0b0\uc790",level:3},{value:"!! \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790",id:"-\ub110-\uc544\ub2d8-\ub2e8\uc5b8-\uc5f0\uc0b0\uc790",level:3},{value:"as? \uc548\uc804\ud55c \uce90\uc2a4\ud305",id:"as-\uc548\uc804\ud55c-\uce90\uc2a4\ud305",level:3},{value:"List\uc5d0\uc11c\uc758 null \ucc98\ub9ac",id:"list\uc5d0\uc11c\uc758-null-\ucc98\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function h(e){const n={a:"a",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"nullable-\ud0c0\uc785",children:"nullable \ud0c0\uc785"}),"\n",(0,r.jsxs)(n.p,{children:["\ucf54\ud2c0\ub9b0\uc740 ",(0,r.jsx)(n.code,{children:"NullPointerException"})," \uc608\uc678\ub97c \ucd5c\ub300\ud55c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 \ud0c0\uc785 \uc2dc\uc2a4\ud15c\uc774 \uc124\uacc4\ub418\uc5b4 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ub294 \uc2e4\ud589 \uc2dc\uc810\uc774 \uc544\ub2cc \ucef4\ud30c\uc77c \uc2dc \ubbf8\ub9ac \uc624\ub958\uac00 \ubc1c\uc0dd\ud560 \uac00\ub2a5\uc131\uc774 \uc788\ub294 \ubd80\ubd84\uc744 \ubbf8\ub9ac \uac10\uc9c0\ud558\uc5ec NPE \ubc1c\uc0dd\uc758 \uac00\ub2a5\uc131\uc744 \uc904\uc5ec\uc900\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\ucf54\ud2c0\ub9b0\uc758 \uacbd\uc6b0 nullable \ud0c0\uc785\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \ud45c\ud604\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"val number: Int?\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\ud0c0\uc785 \ub4a4\uc5d0 ",(0,r.jsx)(n.code,{children:"?"}),"\ub97c \ubd99\uc5ec \ud574\ub2f9 \uac12\uc774 null\uc774 \ub420 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub9cc\uc57d ",(0,r.jsx)(n.code,{children:"?"}),"\ub97c \ubd99\uc774\uc9c0 \uc54a\uc744 \ub54c null\uc744 \ubc1b\ub294 \uacbd\uc6b0 \ucef4\ud30c\uc77c \uc2dc \uc624\ub958\uac00 \ubc1c\uc0dd\ud55c\ub2e4."]}),"\n",(0,r.jsxs)(n.h3,{id:"-safe-calls-\uc5f0\uc0b0\uc790",children:[(0,r.jsx)(n.code,{children:"?."})," Safe Calls \uc5f0\uc0b0\uc790"]}),"\n",(0,r.jsx)(n.p,{children:"\uc790\ubc14\uc5d0\uc11c NPE\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 null\uc744 \ucc98\ub9ac\ud558\ub294 \uac00\uc7a5 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c\ub294 \ubd84\uae30\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4."}),"\n",(0,r.jsxs)(n.p,{children:["\ucf54\ud2c0\ub9b0\uc740 \uc548\uc804\ud55c \ud638\ucd9c \uc5f0\uc0b0\uc790\uc778 ",(0,r.jsx)(n.code,{children:"?."})," \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ucc38\uc870 \uac12\uc774 null\uc774 \uc544\ub2d0 \uacbd\uc6b0\uc5d0\ub9cc \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucc38\uc870 \uac12\uc774 null\uc778 \uacbd\uc6b0 \uba54\uc11c\ub4dc \ud638\ucd9c\uc774 \ubb34\uc2dc\ub418\uace0, null\uc744 \ubc18\ud658\ud55c\ub2e4."]}),"\n",(0,r.jsxs)(a.Z,{children:[(0,r.jsx)(s.Z,{value:"Java",label:"Java",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public String repeat(String word) {\n if (word == null) {\n return null;\n }\n return word.repeat(2);\n}\n"})})}),(0,r.jsx)(s.Z,{value:"Kotlin",label:"Kotlin",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"fun repeat(word: String?): String? {\n return word?.repeat(2)\n}\n"})})})]}),"\n",(0,r.jsxs)(n.h3,{id:"-\uc5d8\ube44\uc2a4-\uc5f0\uc0b0\uc790",children:[(0,r.jsx)(n.code,{children:"?:"})," \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790"]}),"\n",(0,r.jsxs)(n.p,{children:["\ucc38\uc870\ud558\ub824\ub294 \uac12\uc774 null\uc77c \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud558\uace0 \uc2f6\uc744 \ub54c\ub294 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?",(0,r.jsx)(n.br,{}),"\n","\ucf54\ud2c0\ub9b0\uc740 null\uc774 \uc544\ub2cc \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \ub54c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4."]}),"\n",(0,r.jsxs)(a.Z,{children:[(0,r.jsx)(s.Z,{value:"Java",label:"Java",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public String stringSafe(String word) {\n if (word == null) {\n return "";\n }\n return word;\n}\n'})})}),(0,r.jsx)(s.Z,{value:"Kotlin",label:"Kotlin",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:'fun stringSafe(word: String?): String {\n return word ?: ""\n}\n'})})})]}),"\n",(0,r.jsxs)(n.p,{children:["\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 throw\ub3c4 \uc2dd\uc774\uae30 \ub54c\ubb38\uc5d0 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc608\ub97c \ub4e4\uc5b4 \uc0ac\uc6a9\uc790 \uc815\ubcf4\uac00 \uc788\ub294 \uc800\uc7a5\uc18c\uc5d0 \ucc3e\ub294 \uc0ac\uc6a9\uc790\uac00 \uc5c6\ub294 \uacbd\uc6b0 \uc544\ub798\uc640 \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"userRepository.findByName(name) ?: throw IllegalArgumentException()\n"})}),"\n",(0,r.jsxs)(n.h3,{id:"-\ub110-\uc544\ub2d8-\ub2e8\uc5b8-\uc5f0\uc0b0\uc790",children:[(0,r.jsx)(n.code,{children:"!!"})," \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790"]}),"\n",(0,r.jsxs)(n.p,{children:["!! \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud55c\ub2e4\uba74 \uac15\uc81c\ub85c \uc5b4\ub5a4 \uac12\uc774\ub4e0 non-nullable \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc null\uc778 \uac12\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4\uba74 NPE\uac00 \ubc1c\uc0dd\ud558\uac8c \ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc77c\ubc18\uc801\uc778 \uacbd\uc6b0\uc5d0\ub294 !! \uc5f0\uc0b0\uc790\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc704\ud5d8\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc0ac\uc6a9\ud558\uae30 \uc27d\uc9c0\ub9cc, \ub9ac\uc2a4\ud06c\uac00 \ud06c\uace0 \ud639\uc2dc\ub098 \ud574\ub2f9 \uac12\uc774 \ucd94\ud6c4\uc5d0\ub294 null\uc774 \ub420 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc591\ud574\uc57c \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"val length: Int = word!!.length\n"})}),"\n",(0,r.jsxs)(n.h3,{id:"as-\uc548\uc804\ud55c-\uce90\uc2a4\ud305",children:[(0,r.jsx)(n.code,{children:"as?"})," \uc548\uc804\ud55c \uce90\uc2a4\ud305"]}),"\n",(0,r.jsxs)(n.p,{children:["\ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \ub54c \uc9c0\uc815\ud55c \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc5c6\ub2e4\uba74 ",(0,r.jsx)(n.code,{children:"ClassCastException"}),"\uc774 \ubc1c\uc0dd\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 as \ub4a4\uc5d0 ?\ub97c \ubd99\uc5ec \uc548\uc804\ud558\uac8c \ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ubbf8\ub9ac \ubcc0\ud658 \uac00\ub2a5\ud55c \ud0c0\uc785\uc778\uc9c0 \ud655\uc778\ud558\uc9c0 \uc54a\uace0, \uc548\uc804\ud558\uac8c \ud0c0\uc785\uc744 \ubcc0\ud658 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\ud0c0\uc785 \ubcc0\ud658\uc774 \ubd88\uac00\ub2a5 \ud560 \uacbd\uc6b0 \uc608\uc678\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uace0 null\uc744 \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"val value: Int? = something as? Int\n"})}),"\n",(0,r.jsx)(n.h3,{id:"list\uc5d0\uc11c\uc758-null-\ucc98\ub9ac",children:"List\uc5d0\uc11c\uc758 null \ucc98\ub9ac"}),"\n",(0,r.jsxs)(n.p,{children:["List\uc5d0\ub294 null\uc774 \uc544\ub2cc \uac12\ub9cc \ubc18\ud658\ud558\ub294 ",(0,r.jsx)(n.code,{children:"filterNotNull"})," \uc720\ud2f8\ub9ac\ud2f0 \uba54\uc11c\ub4dc\ub97c \uc81c\uacf5\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:'val foodsWithNull: List = listOf("Pizza", "Cheese", null, "Potato")\nval foods = foodsWithNull.filterNotNull()\n'})}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://product.kyobobook.co.kr/detail/S000001804588",children:"Kotlin in Action"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://product.kyobobook.co.kr/detail/S000001033129",children:"Effective Kotlin Item 8"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://www.baeldung.com/kotlin/null-safety",children:"Comprehensive Guide to Null Safety in Kotlin"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://kotlinlang.org/docs/null-safety.html",children:"Kotlin NullSafety"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},3905:(e,n,l)=>{l.d(n,{ah:()=>u});var r=l(67294);function t(e,n,l){return n in e?Object.defineProperty(e,n,{value:l,enumerable:!0,configurable:!0,writable:!0}):e[n]=l,e}function a(e,n){var l=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),l.push.apply(l,r)}return l}function s(e){for(var n=1;n=0||(t[l]=e[l]);return t}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,l)&&(t[l]=e[l])}return t}var o=r.createContext({}),u=function(e){var n=r.useContext(o),l=n;return e&&(l="function"==typeof e?e(n):s(s({},n),e)),l},c={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var l=e.components,t=e.mdxType,a=e.originalType,o=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),h=u(l),p=t,f=h["".concat(o,".").concat(p)]||h[p]||c[p]||a;return l?r.createElement(f,s(s({ref:n},d),{},{components:l})):r.createElement(f,s({ref:n},d))}));d.displayName="MDXCreateElement"},85162:(e,n,l)=>{l.d(n,{Z:()=>s});l(67294);var r=l(86010);const t={tabItem:"tabItem_Ymn6"};var a=l(85893);function s(e){let{children:n,hidden:l,className:s}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,r.Z)(t.tabItem,s),hidden:l,children:n})}},74866:(e,n,l)=>{l.d(n,{Z:()=>w});var r=l(67294),t=l(86010),a=l(12466),s=l(16550),i=l(20469),o=l(91980),u=l(67392),c=l(50012);function d(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:l}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:l,attributes:r,default:t}}=e;return{value:n,label:l,attributes:r,default:t}}))}(l);return function(e){const n=(0,u.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[n,l])}function p(e){let{value:n,tabValues:l}=e;return l.some((e=>e.value===n))}function f(e){let{queryString:n=!1,groupId:l}=e;const t=(0,s.k6)(),a=function(e){let{queryString:n=!1,groupId:l}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!l)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return l??null}({queryString:n,groupId:l});return[(0,o._X)(a),(0,r.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function b(e){const{defaultValue:n,queryString:l=!1,groupId:t}=e,a=h(e),[s,o]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:l}=e;if(0===l.length)throw new Error("Docusaurus error: the component requires at least one children component");if(n){if(!p({value:n,tabValues:l}))throw new Error(`Docusaurus error: The has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${l.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=l.find((e=>e.default))??l[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:a}))),[u,d]=f({queryString:l,groupId:t}),[b,j]=function(e){let{groupId:n}=e;const l=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,a]=(0,c.Nk)(l);return[t,(0,r.useCallback)((e=>{l&&a.set(e)}),[l,a])]}({groupId:t}),m=(()=>{const e=u??b;return p({value:e,tabValues:a})?e:null})();(0,i.Z)((()=>{m&&o(m)}),[m]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!p({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);o(e),d(e),j(e)}),[d,j,a]),tabValues:a}}var j=l(72389);const m={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=l(85893);function g(e){let{className:n,block:l,selectedValue:r,selectValue:s,tabValues:i}=e;const o=[],{blockElementScrollPositionUntilNextRender:u}=(0,a.o5)(),c=e=>{const n=e.currentTarget,l=o.indexOf(n),t=i[l].value;t!==r&&(u(n),s(t))},d=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const l=o.indexOf(e.currentTarget)+1;n=o[l]??o[0];break}case"ArrowLeft":{const l=o.indexOf(e.currentTarget)-1;n=o[l]??o[o.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.Z)("tabs",{"tabs--block":l},n),children:i.map((e=>{let{value:n,label:l,attributes:a}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>o.push(e),onKeyDown:d,onClick:c,...a,className:(0,t.Z)("tabs__item",m.tabItem,a?.className,{"tabs__item--active":r===n}),children:l??n},n)}))})}function v(e){let{lazy:n,children:l,selectedValue:t}=e;const a=(Array.isArray(l)?l:[l]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===t));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function y(e){const n=b(e);return(0,x.jsxs)("div",{className:(0,t.Z)("tabs-container",m.tabList),children:[(0,x.jsx)(g,{...e,...n}),(0,x.jsx)(v,{...e,...n})]})}function w(e){const n=(0,j.Z)();return(0,x.jsx)(y,{...e,children:d(e.children)},String(n))}}}]); \ No newline at end of file diff --git a/assets/js/1f61820a.d2bb9f6d.js b/assets/js/1f61820a.d2bb9f6d.js deleted file mode 100644 index 29e123ccc..000000000 --- a/assets/js/1f61820a.d2bb9f6d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2233],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function u(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),o=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):u(u({},t),e)),r},c=function(e){var t=o(e.components);return n.createElement(i.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=o(r),d=a,v=p["".concat(i,".").concat(d)]||p[d]||m[d]||l;return r?n.createElement(v,u(u({ref:t},c),{},{components:r})):n.createElement(v,u({ref:t},c))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,u=new Array(l);u[0]=p;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,u[1]=s;for(var o=2;o{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>u,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>o});var n=r(87462),a=(r(67294),r(3905));const l={title:"Parameterized Tests",slug:"parameterized-tests",tags:["Java"]},u=void 0,s={permalink:"/parameterized-tests",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-12-Parameterized Tests.mdx",source:"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx",title:"Parameterized Tests",description:"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.",date:"2023-02-12T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 12\uc77c",tags:[{label:"Java",permalink:"/tags/java"}],readingTime:3.17,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Parameterized Tests",slug:"parameterized-tests",tags:["Java"]},prevItem:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",permalink:"/racing-car-retrospective"},nextItem:{title:"IntelliJ \uc124\uc815",permalink:"/intellij-settings"}},i={authorsImageUrls:[]},o=[{value:"Argument Sources",id:"argument-sources",level:2},{value:"Value Source",id:"value-source",level:3},{value:"Null & Empty Source",id:"null--empty-source",level:3},{value:"Enum Source",id:"enum-source",level:3},{value:"CSV Source",id:"csv-source",level:3},{value:"Method Source",id:"method-source",level:3},{value:"ETC.",id:"etc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],c={toc:o};function m(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c ",(0,a.kt)("inlineCode",{parentName:"p"},"@ParameterizedTest"),"\ub97c \uc0ac\uc6a9\ud558\uba74 \ub2e8\uc77c \ud14c\uc2a4\ud2b8\ub97c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc5ec\ub7ec \ubc88 \ubc18\ubcf5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("h2",{id:"argument-sources"},"Argument Sources"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"@ParameterizedTest"),"\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \ucd5c\uc18c \ud558\ub098 \uc774\uc0c1\uc758 Source \uc560\ub178\ud14c\uc774\uc158\uc774 \ud544\uc694\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","JUnit\uc774 \uc81c\uacf5\ud558\ub294 \ub2e4\uc591\ud55c Source\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0, \ud14c\uc2a4\ud2b8\uc5d0 \ub9de\ucdb0 \ub2e4\uc591\ud558\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("h3",{id:"value-source"},"Value Source"),(0,a.kt)("p",null,"\uac12\uc744 \uc774\uc6a9\ud558\uc5ec \uc81c\uacf5\ud558\ub294 \ud615\ud0dc\ub85c, \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"short, int, long, float, double"),(0,a.kt)("li",{parentName:"ul"},"byte, char, boolean, String, Class ")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@ParameterizedTest\n@ValueSource(ints = {1, 100, Integer.MAX_VALUE})\nvoid valueTest(final int value) {\n Assertions.assertThat(value).isPositive();\n}\n")),(0,a.kt)("h3",{id:"null--empty-source"},"Null & Empty Source"),(0,a.kt)("p",null,"null \uac12, \ube48 \uac12\uc744 \uc81c\uacf5\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Empty Source\uc758 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc5d0 \ud55c\ud574 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"String"),(0,a.kt)("li",{parentName:"ul"},"java.util.List, java.util.Set, java.util.Map"),(0,a.kt)("li",{parentName:"ul"},"primitive arrays \u2014 ex) int[]"),(0,a.kt)("li",{parentName:"ul"},"object arrays \u2014 ex) String[]")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@ParameterizedTest\n@NullAndEmptySource\nvoid nullAndEmptyTest(final String value) {\n Assertions.assertThat(value).isNullOrEmpty();\n}\n")),(0,a.kt)("h3",{id:"enum-source"},"Enum Source"),(0,a.kt)("p",null,"EnumSource\ub97c \uc774\uc6a9\ud558\uc5ec Enum \ub610\ud55c \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"enum Day {\n MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n}\n\n@ParameterizedTest\n@EnumSource(Day.class)\nvoid enumTest(final Day day) {\n assertThat(day).isInstanceOf(Day.class);\n}\n")),(0,a.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 mode \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b9\uc9d5 Enum\uc744 \uc81c\uc678\ud558\uac70\ub098, \ud3ec\ud568\uc2dc\ud0ac \uc218 \uc788\ub2e4. (default: Mode.Include)"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@ParameterizedTest\n@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)\nvoid enumTest(final Day day) {\n // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY\n assertThat(day).isInstanceOf(Day.class);\n}\n')),(0,a.kt)("h3",{id:"csv-source"},"CSV Source"),(0,a.kt)("p",null,"csv \ud615\uc2dd\uc758 \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uad6c\ubd84\uc790\uc758 \uae30\ubcf8\uac12\uc740 \uc27c\ud45c(,)\ub85c \uad6c\ubd84\uc790\ub97c \ubcc0\uacbd\ud558\uace0 \uc2f6\uc744 \ub550 delimeter \uac12\uc744 \ub530\ub85c \uc804\ub2ec\ud558\uc5ec \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\n\uac1c\uc778\uc801\uc73c\ub85c 2\uac1c \uc815\ub3c4\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc804\ub2ec\ud558\ub294 \uacbd\uc6b0 CsvSource\ub97c \uc0ac\uc6a9\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@ParameterizedTest\n@CsvSource({"1,1", "2,4", "3,9", "4,16"})\nvoid csvTest(final int number, final int result) {\n assertThat(number * number).isEqualTo(result);\n}\n')),(0,a.kt)("h3",{id:"method-source"},"Method Source"),(0,a.kt)("p",null,"\ubcf5\uc7a1\ud55c \ud0c0\uc785\uc758 \uac12\uc744 \uc804\ub2ec\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uba54\uc11c\ub4dc\uba85\uc744 \uc785\ub825\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uba54\uc11c\ub4dc\uba85\uc744 \ub530\ub85c \uc785\ub825\ud558\uc9c0 \uc54a\uc73c\uba74 \ud14c\uc2a4\ud2b8\uba85\uacfc \ub3d9\uc77c\ud55c static \uba54\uc11c\ub4dc\uac00 \uc9c0\uc815\ub41c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@ParameterizedTest\n@MethodSource\nvoid methodTest(final List numbers, final int count) {\n assertThat(numbers).hasSize(count);\n}\n\nprivate static Stream methodTest() {\n return Stream.of(\n Arguments.of(List.of(1), 1),\n Arguments.of(List.of(1, 2), 2),\n Arguments.of(List.of(1, 2, 3), 3)\n );\n}\n")),(0,a.kt)("h3",{id:"etc"},"ETC."),(0,a.kt)("p",null,"\uc704\uc5d0\uc11c \uc5b8\uae09\ud55c \ubc29\ubc95 \uc774\uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ubc29\ubc95\uc73c\ub85c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"CSV \ud30c\uc77c\uc744 \uc774\uc6a9\ud55c CsvFileSource"),(0,a.kt)("li",{parentName:"ul"},"ArgumentsProvider \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \uc774\uc6a9\ud558\ub294 ArgumentsSource")),(0,a.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.baeldung.com/parameterized-tests-junit-5"},"Guide to JUnit 5 Parameterized Tests"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/1f61820a.d2fe9ecf.js b/assets/js/1f61820a.d2fe9ecf.js new file mode 100644 index 000000000..eb01871d3 --- /dev/null +++ b/assets/js/1f61820a.d2fe9ecf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2233],{74123:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>u});var t=r(85893),s=r(3905);const a={title:"Parameterized Tests",slug:"parameterized-tests",tags:["Java"]},i=void 0,l={permalink:"/parameterized-tests",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-12-Parameterized Tests.mdx",source:"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx",title:"Parameterized Tests",description:"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.",date:"2023-02-12T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 12\uc77c",tags:[{label:"Java",permalink:"/tags/java"}],readingTime:3.17,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Parameterized Tests",slug:"parameterized-tests",tags:["Java"]},unlisted:!1,prevItem:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",permalink:"/racing-car-retrospective"},nextItem:{title:"IntelliJ \uc124\uc815",permalink:"/intellij-settings"}},c={authorsImageUrls:[]},u=[{value:"Argument Sources",id:"argument-sources",level:2},{value:"Value Source",id:"value-source",level:3},{value:"Null & Empty Source",id:"null--empty-source",level:3},{value:"Enum Source",id:"enum-source",level:3},{value:"CSV Source",id:"csv-source",level:3},{value:"Method Source",id:"method-source",level:3},{value:"ETC.",id:"etc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function o(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \ub54c ",(0,t.jsx)(n.code,{children:"@ParameterizedTest"}),"\ub97c \uc0ac\uc6a9\ud558\uba74 \ub2e8\uc77c \ud14c\uc2a4\ud2b8\ub97c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc5ec\ub7ec \ubc88 \ubc18\ubcf5\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.h2,{id:"argument-sources",children:"Argument Sources"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"@ParameterizedTest"}),"\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \ucd5c\uc18c \ud558\ub098 \uc774\uc0c1\uc758 Source \uc560\ub178\ud14c\uc774\uc158\uc774 \ud544\uc694\ud558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","JUnit\uc774 \uc81c\uacf5\ud558\ub294 \ub2e4\uc591\ud55c Source\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0, \ud14c\uc2a4\ud2b8\uc5d0 \ub9de\ucdb0 \ub2e4\uc591\ud558\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"value-source",children:"Value Source"}),"\n",(0,t.jsx)(n.p,{children:"\uac12\uc744 \uc774\uc6a9\ud558\uc5ec \uc81c\uacf5\ud558\ub294 \ud615\ud0dc\ub85c, \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"short, int, long, float, double"}),"\n",(0,t.jsx)(n.li,{children:"byte, char, boolean, String, Class"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"@ParameterizedTest\n@ValueSource(ints = {1, 100, Integer.MAX_VALUE})\nvoid valueTest(final int value) {\n Assertions.assertThat(value).isPositive();\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"null--empty-source",children:"Null & Empty Source"}),"\n",(0,t.jsxs)(n.p,{children:["null \uac12, \ube48 \uac12\uc744 \uc81c\uacf5\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Empty Source\uc758 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc5d0 \ud55c\ud574 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"String"}),"\n",(0,t.jsx)(n.li,{children:"java.util.List, java.util.Set, java.util.Map"}),"\n",(0,t.jsx)(n.li,{children:"primitive arrays \u2014 ex) int[]"}),"\n",(0,t.jsx)(n.li,{children:"object arrays \u2014 ex) String[]"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"@ParameterizedTest\n@NullAndEmptySource\nvoid nullAndEmptyTest(final String value) {\n Assertions.assertThat(value).isNullOrEmpty();\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"enum-source",children:"Enum Source"}),"\n",(0,t.jsx)(n.p,{children:"EnumSource\ub97c \uc774\uc6a9\ud558\uc5ec Enum \ub610\ud55c \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"enum Day {\n MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n}\n\n@ParameterizedTest\n@EnumSource(Day.class)\nvoid enumTest(final Day day) {\n assertThat(day).isInstanceOf(Day.class);\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 mode \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b9\uc9d5 Enum\uc744 \uc81c\uc678\ud558\uac70\ub098, \ud3ec\ud568\uc2dc\ud0ac \uc218 \uc788\ub2e4. (default: Mode.Include)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'@ParameterizedTest\n@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)\nvoid enumTest(final Day day) {\n // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY\n assertThat(day).isInstanceOf(Day.class);\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"csv-source",children:"CSV Source"}),"\n",(0,t.jsxs)(n.p,{children:["csv \ud615\uc2dd\uc758 \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uad6c\ubd84\uc790\uc758 \uae30\ubcf8\uac12\uc740 \uc27c\ud45c(,)\ub85c \uad6c\ubd84\uc790\ub97c \ubcc0\uacbd\ud558\uace0 \uc2f6\uc744 \ub550 delimeter \uac12\uc744 \ub530\ub85c \uc804\ub2ec\ud558\uc5ec \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\n\uac1c\uc778\uc801\uc73c\ub85c 2\uac1c \uc815\ub3c4\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc804\ub2ec\ud558\ub294 \uacbd\uc6b0 CsvSource\ub97c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'@ParameterizedTest\n@CsvSource({"1,1", "2,4", "3,9", "4,16"})\nvoid csvTest(final int number, final int result) {\n assertThat(number * number).isEqualTo(result);\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"method-source",children:"Method Source"}),"\n",(0,t.jsxs)(n.p,{children:["\ubcf5\uc7a1\ud55c \ud0c0\uc785\uc758 \uac12\uc744 \uc804\ub2ec\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba54\uc11c\ub4dc\uba85\uc744 \uc785\ub825\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba54\uc11c\ub4dc\uba85\uc744 \ub530\ub85c \uc785\ub825\ud558\uc9c0 \uc54a\uc73c\uba74 \ud14c\uc2a4\ud2b8\uba85\uacfc \ub3d9\uc77c\ud55c static \uba54\uc11c\ub4dc\uac00 \uc9c0\uc815\ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"@ParameterizedTest\n@MethodSource\nvoid methodTest(final List numbers, final int count) {\n assertThat(numbers).hasSize(count);\n}\n\nprivate static Stream methodTest() {\n return Stream.of(\n Arguments.of(List.of(1), 1),\n Arguments.of(List.of(1, 2), 2),\n Arguments.of(List.of(1, 2, 3), 3)\n );\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"etc",children:"ETC."}),"\n",(0,t.jsx)(n.p,{children:"\uc704\uc5d0\uc11c \uc5b8\uae09\ud55c \ubc29\ubc95 \uc774\uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ubc29\ubc95\uc73c\ub85c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"CSV \ud30c\uc77c\uc744 \uc774\uc6a9\ud55c CsvFileSource"}),"\n",(0,t.jsx)(n.li,{children:"ArgumentsProvider \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \uc774\uc6a9\ud558\ub294 ArgumentsSource"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.baeldung.com/parameterized-tests-junit-5",children:"Guide to JUnit 5 Parameterized Tests"})}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,s.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>u});var t=r(67294);function s(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n=0||(s[r]=e[r]);return s}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var c=t.createContext({}),u=function(e){var n=t.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},o={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,s=e.mdxType,a=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=u(r),h=s,p=m["".concat(c,".").concat(h)]||m[h]||o[h]||a;return r?t.createElement(p,i(i({ref:n},d),{},{components:r})):t.createElement(p,i({ref:n},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/2027.ab074e16.js b/assets/js/2027.ab074e16.js new file mode 100644 index 000000000..6d6bba019 --- /dev/null +++ b/assets/js/2027.ab074e16.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2027],{42027:(t,i,n)=>{n.d(i,{diagram:()=>o});var s=n(56363),e=(n(27484),n(17967),n(64218),n(27856),function(){var t=function(t,i,n,s){for(n=n||{},s=t.length;s--;n[t[s]]=i);return n},i=[6,9,10],n={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,i,n,s,e,r,h){switch(r.length,e){case 1:return s;case 4:break;case 6:s.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(i,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(i,[2,3]),t(i,[2,4]),t(i,[2,5]),t(i,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,i){if(!i.recoverable){var n=new Error(t);throw n.hash=i,n}this.trace(t)},parse:function(t){var i=this,n=[0],s=[],e=[null],r=[],h=this.table,o="",l=0,c=0,a=r.slice.call(arguments,1),y=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);y.setInput(t,u.yy),u.yy.lexer=y,u.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var f=y.yylloc;r.push(f);var g=y.options&&y.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,m,d,k,b,x,v,w,I,S={};;){if(m=n[n.length-1],this.defaultActions[m]?d=this.defaultActions[m]:(null==_&&(I=void 0,"number"!=typeof(I=s.pop()||y.lex()||1)&&(I instanceof Array&&(I=(s=I).pop()),I=i.symbols_[I]||I),_=I),d=h[m]&&h[m][_]),void 0===d||!d.length||!d[0]){var E="";for(b in w=[],h[m])this.terminals_[b]&&b>2&&w.push("'"+this.terminals_[b]+"'");E=y.showPosition?"Parse error on line "+(l+1)+":\n"+y.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(E,{text:y.match,token:this.terminals_[_]||_,line:y.yylineno,loc:f,expected:w})}if(d[0]instanceof Array&&d.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+_);switch(d[0]){case 1:n.push(_),e.push(y.yytext),r.push(y.yylloc),n.push(d[1]),_=null,c=y.yyleng,o=y.yytext,l=y.yylineno,f=y.yylloc;break;case 2:if(x=this.productions_[d[1]][1],S.$=e[e.length-x],S._$={first_line:r[r.length-(x||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(x||1)].first_column,last_column:r[r.length-1].last_column},g&&(S._$.range=[r[r.length-(x||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,c,l,u.yy,d[1],e,r].concat(a))))return k;x&&(n=n.slice(0,-1*x*2),e=e.slice(0,-1*x),r=r.slice(0,-1*x)),n.push(this.productions_[d[1]][0]),e.push(S.$),r.push(S._$),v=h[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},s={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===s.length?this.yylloc.first_column:0)+s[s.length-n.length].length-n[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var n,s,e;if(this.options.backtrack_lexer&&(e={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(e.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in e)this[r]=e[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,n,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var e=this._currentRules(),r=0;ri[0].length)){if(i=n,s=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,e[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,e[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,n,s){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function e(){this.yy={}}return n.lexer=s,e.prototype=n,n.Parser=e,new e}());e.parser=e;const r=!1;let h=r;const o={parser:e,db:{clear:()=>{h=r},setInfo:t=>{h=t},getInfo:()=>h},renderer:{draw:(t,i,n)=>{s.l.debug("rendering info diagram\n"+t);const e=(0,s.z)(i);(0,s.i)(e,100,400,!0);e.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${n}`)}}}}}]); \ No newline at end of file diff --git a/assets/js/205.1662f0db.js b/assets/js/205.1662f0db.js new file mode 100644 index 000000000..8171e12b5 --- /dev/null +++ b/assets/js/205.1662f0db.js @@ -0,0 +1,28345 @@ +"use strict"; +exports.id = 205; +exports.ids = [205]; +exports.modules = { + +/***/ 43349: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ addHtmlLabel) +/* harmony export */ }); +/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(96225); + + + + +function addHtmlLabel(root, node) { + var fo = root.append('foreignObject').attr('width', '100000'); + + var div = fo.append('xhtml:div'); + div.attr('xmlns', 'http://www.w3.org/1999/xhtml'); + + var label = node.label; + switch (typeof label) { + case 'function': + div.insert(label); + break; + case 'object': + // Currently we assume this is a DOM object. + div.insert(function () { + return label; + }); + break; + default: + div.html(label); + } + + _util_js__WEBPACK_IMPORTED_MODULE_0__/* .applyStyle */ .bg(div, node.labelStyle); + div.style('display', 'inline-block'); + // Fix for firefox + div.style('white-space', 'nowrap'); + + var client = div.node().getBoundingClientRect(); + fo.attr('width', client.width).attr('height', client.height); + + return fo; +} + + +/***/ }), + +/***/ 96225: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ $p: () => (/* binding */ applyClass), +/* harmony export */ O1: () => (/* binding */ edgeToId), +/* harmony export */ WR: () => (/* binding */ applyTransition), +/* harmony export */ bF: () => (/* binding */ isSubgraph), +/* harmony export */ bg: () => (/* binding */ applyStyle) +/* harmony export */ }); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(37514); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(73234); + + +// Public utility functions + + +/* + * Returns true if the specified node in the graph is a subgraph node. A + * subgraph node is one that contains other nodes. + */ +function isSubgraph(g, v) { + return !!g.children(v).length; +} + +function edgeToId(e) { + return escapeId(e.v) + ':' + escapeId(e.w) + ':' + escapeId(e.name); +} + +var ID_DELIM = /:/g; +function escapeId(str) { + return str ? String(str).replace(ID_DELIM, '\\:') : ''; +} + +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr('style', styleFn); + } +} + +function applyClass(dom, classFn, otherClasses) { + if (classFn) { + dom.attr('class', classFn).attr('class', otherClasses + ' ' + dom.attr('class')); + } +} + +function applyTransition(selection, g) { + var graph = g.graph(); + + if (lodash_es__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z(graph)) { + var transition = graph.transition; + if (lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z(transition)) { + return transition(selection); + } + } + + return selection; +} + + +/***/ }), + +/***/ 41644: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + bK: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.Z(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.Z( + map/* default */.Z(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.Z(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.Z(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.k(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.Z(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.Z(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.Z(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.Z(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.Z(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.Z('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.Z(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.Z(g.outEdges(v), function (e) { + if (has/* default */.Z(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.Z(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.Z(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(59236); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.Z)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(74752); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.Z)(iteratee, 3); + + (0,_baseForOwn/* default */.Z)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.Z)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(66092); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.Z.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.Z(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.k().setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.k({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.Z(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.Z(range/* default */.Z(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.Z(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.Z(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.Z(layers, function (vs, i) { + if (isUndefined/* default */.Z(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.Z(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.Z(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.Z(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.Z(children, dfs); + } + + if (has/* default */.Z(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.Z(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, reverseYOne); + if (has/* default */.Z(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, swapXYOne); + if (has/* default */.Z(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.Z(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.Z)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.Z(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.Z(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.Z(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.k({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.Z(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.Z(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.Z(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.Z)(collection)) { + var iteratee = (0,_baseIteratee/* default */.Z)(predicate, 3); + collection = (0,keys/* default */.Z)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.Z)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.Z)(array, (0,_baseIteratee/* default */.Z)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(39473); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(93589); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.Z)(value) && (0,isObjectLike/* default */.Z)(value) && (0,_baseGetTag/* default */.Z)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.Z)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.Z)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.Z)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.Z)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.Z(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.Z(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.Z(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.Z(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.Z(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.Z(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.Z(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.Z(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.Z(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.Z(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.Z(tree.neighbors(v), function (w) { + if (!has/* default */.Z(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.Z(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.Z(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.Z(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.Z(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.Z(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.Z(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.Z(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.Z(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.Z( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.Z(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.k({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.Z(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.Z(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.Z(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.Z('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.Z); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(21018); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.Z)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.Z)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + if ((0,isArray/* default */.Z)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.Z)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.Z]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.Z)(iteratees, (0,_baseUnary/* default */.Z)(_baseIteratee/* default */.Z)); + + var result = (0,_baseMap/* default */.Z)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.Z)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.Z)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.Z)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.Z)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.Z(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.Z( + map/* default */.Z(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.Z(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.Z(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.Z( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.Z(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.Z(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.Z(range/* default */.Z(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.Z(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.Z(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.Z(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.Z(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.Z( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.Z(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.Z(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.Z(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.Z(entryV) && !isUndefined/* default */.Z(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.Z(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.Z(uEntry.barycenter) || + isUndefined/* default */.Z(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.Z(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.Z(entry.out, handleOut(entry)); + } + + return map/* default */.Z( + filter/* default */.Z(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.Z(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.Z(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.Z(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.Z(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.Z(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.Z(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.Z(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.Z([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.Z(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.Z(entries, function (entry) { + entry.vs = flatten/* default */.Z( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.Z(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.Z(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.Z(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.Z(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.k(); + forEach/* default */.Z(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.Z(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.Z(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.Z(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(68882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(61395); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee), keysIn/* default */.Z); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.Z(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.Z(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.Z(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.Z(range/* default */.Z(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.Z(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.Z(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.Z(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.Z(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.Z(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.Z(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.k(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.Z(layering, function (layer) { + var u; + forEach/* default */.Z(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.Z(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.Z(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.Z(['u', 'd'], function (vert) { + forEach/* default */.Z(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.Z(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.Z(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.Z(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.Z(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.Z(layering).reverse(); + forEach/* default */.Z(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.Z(adjustedLayering, function (inner) { + return values/* default */.Z(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.Z(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.Z(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.Z(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.Z(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.Z(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.Z(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.k({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.Z({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.Z(graph, graphAttrs)) + ); + + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.Z(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.Z({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.Z(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.Z(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.Z(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.Z(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.Z(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.Z(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.Z(layers, function (layer) { + var orderShift = 0; + forEach/* default */.Z(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.Z(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.Z(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.Z(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 52544: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + k: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(73234); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(79697); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.Z)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(93203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.Z && (1 / (0,_setToArray/* default */.Z)(new _Set/* default */.Z([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.Z(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.Z)(set); + } + isCommon = false; + includes = _cacheHas/* default */.Z; + seen = new _SetCache/* default */.Z; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(836); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.Z)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.Z)(arrays, 1, isArrayLikeObject/* default */.Z, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.Z(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.Z(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.Z(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.Z(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.Z(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.Z(this._nodes); + } + sources() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.Z(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.Z(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.Z(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.Z(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.Z(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.Z(keys/* default */.Z(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.Z(keys/* default */.Z(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.Z(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.Z(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.Z(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.Z(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.Z(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.Z(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.Z(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.Z(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.Z(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.Z(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.Z(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.Z(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.Z(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.Z(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.Z(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.Z(inV); + if (!u) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.Z(outV); + if (!w) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.Z(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 45625: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ k: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.k) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52544); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 39354: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + c: () => (/* binding */ write) +}); + +// UNUSED EXPORTS: read + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/clone.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_clone = (clone); + +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/json.js + + + + + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound(), + }, + nodes: writeNodes(g), + edges: writeEdges(g), + }; + if (!isUndefined/* default */.Z(g.graph())) { + json.value = lodash_es_clone(g.graph()); + } + return json; +} + +function writeNodes(g) { + return map/* default */.Z(g.nodes(), function (v) { + var nodeValue = g.node(v); + var parent = g.parent(v); + var node = { v: v }; + if (!isUndefined/* default */.Z(nodeValue)) { + node.value = nodeValue; + } + if (!isUndefined/* default */.Z(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return map/* default */.Z(g.edges(), function (e) { + var edgeValue = g.edge(e); + var edge = { v: e.v, w: e.w }; + if (!isUndefined/* default */.Z(e.name)) { + edge.name = e.name; + } + if (!isUndefined/* default */.Z(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function (entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function (entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + + +/***/ }), + +/***/ 63001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(37834); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.Z; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 76579: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 68774: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 74073: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 58694: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 48451: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(76579); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(31899); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keys/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keysIn/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(91050); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(87215); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(95695); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.Z)(source, (0,_getSymbols/* default */.Z)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(12513); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(60532); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.Z : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.Z)(result, (0,_getSymbols/* default */.Z)(object)); + object = (0,_getPrototype/* default */.Z)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.Z)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(63327); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.Z)(object, keysIn/* default */.Z, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(41884); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.Z)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(12701); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.Z)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.Z)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(73658); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(98351); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.Z)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.Z)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.Z)(value)) { + return value; + } + var isArr = (0,isArray/* default */.Z)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.Z)(value, result); + } + } else { + var tag = (0,_getTag/* default */.Z)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.Z)(value)) { + return (0,_cloneBuffer/* default */.Z)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.Z)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.Z); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.Z) + : (isFlat ? keysIn/* default */.Z : keys/* default */.Z); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.Z)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.Z)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 49811: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.Z)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.Z); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 21692: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 10626: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(29169); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.Z ? _Symbol/* default */.Z.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.Z)(value) || (0,isArguments/* default */.Z)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.Z)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 2693: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61395); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 13317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 63327: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58694); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 74765: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.Z : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.Z)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(84073); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(79651); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.Z(object), new _Uint8Array/* default */.Z(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.Z)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.Z); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.Z)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.Z)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(18843); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.Z)(object), + othIsArr = (0,isArray/* default */.Z)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.Z)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.Z)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.Z)(object)) { + if (!(0,isBuffer/* default */.Z)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.Z); + return (objIsArr || (0,isTypedArray/* default */.Z)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.Z); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.Z); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.Z)(value) && !(0,isObjectLike/* default */.Z)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.Z; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.Z)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.Z)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.Z)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.Z)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.Z)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.Z)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.Z)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.Z)(path) ? (0,_baseProperty/* default */.Z)((0,_toKey/* default */.Z)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.Z; + } + if (typeof value == 'object') { + return (0,isArray/* default */.Z)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 21018: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49811); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 54193: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 59548: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 68882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69203); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 22823: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(42454); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.Z)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(50751); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.Z)(value)) { + return value; + } + return (0,_isKey/* default */.Z)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.Z)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 1808: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63327); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(95695); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 95695: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68774); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(60532); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 16174: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29169); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27771); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(56009); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1656); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 99365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72714); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 6545: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 62281: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72714); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 3688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69581); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(79651); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50439); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32957); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 13445: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(68774); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.Z)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayFilter/* default */.Z : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.Z)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 27961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10626); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 70870: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76579); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49811); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(68882); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 17452: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 75487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 72714: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93589); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18533); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 49360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 17179: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87668); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39473); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 43836: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74073); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74765); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21018); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 61666: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(22823); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(56009); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.Z)(object)) { + return object; + } + path = (0,_castPath/* default */.Z)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.Z)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.Z)(objValue) + ? objValue + : ((0,_isIndex/* default */.Z)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.Z)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.Z)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.Z)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.Z)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(81211); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(27227); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.Z)((0,_overRest/* default */.Z)(func, undefined, flatten/* default */.Z), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 74379: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.Z)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.Z)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.Z)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.Z)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 92344: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.Z)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.Z); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 60532: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 94099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.Z)(value)) { + return NAN; + } + if ((0,isObject/* default */.Z)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.Z)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 50751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.Z)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.Z)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.Z)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 66749: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50751); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 34148: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.Z)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.Z)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 64589: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record} */ + const left = maybe || (all[hook] = {}) + /** @type {Record | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array} existing + * @param {Array} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function micromark_util_chunked_splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function micromark_util_chunked_push(list, items) { + if (list.length > 0) { + micromark_util_chunked_splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array} */ + let parameters + /** @type {Array} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + micromark_util_chunked_splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array} events + * @param {number} eventIndex + * @returns {Record} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record} */ + const gaps = {} + /** @type {Array} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + micromark_util_chunked_splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record} */ + const columnStart = {} + /** @type {Array} */ + const resolveAllConstructs = [] + /** @type {Array} */ + let chunks = [] + /** @type {Array} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array} chunks + * @param {Pick} token + * @returns {Array} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * + * b> + * + * + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`` or `b`). + * @param {TokenType} literalType + * Type when enclosed (``). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * . + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After ` | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | &<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | + * ^^ + * > | + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > |

블랙잭

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
-이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
-후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
-"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
-중간 중간 회고를 하고, 나의 소프트스킬을 높히는게 답일까?
-부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
-터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

부족했던 부분

페어 신경쓰기
-이번 페어할 때 적극적으로 의견을 내보도록 했다. 그렇기에 너무 의견을 강하게 밀어붙인 느낌이 들어서 미안했다.
-후추가 압박을 느꼈을 수도 있을 것 같다는 생각이 든다.
-중간 중간 작은 회고를 진행해보는 것이 좋을까?

체력 관리
-요즘 잘 못먹는 것 같다.
-앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

중간 중간 돌아보기
-이번 미션과 관련된 내용은 아니지만 우테코를 잘 활용 하고 있는지 생각을 해봐야겠다.
-내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

새로 학습한 부분

상태 패턴
-객체의 내부 상태에 따라 스스로 행동을 변경하도록 하는 패턴으로 if/else/switch와 같은 조건문을 효과적으로 제거할 수 있다.
-블랙잭 미션을 진행하면서 상태 패턴에 대한 부분을 처음 적용해보았다.
-처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

일관성, 가독성, 추상화
-이번 리뷰어는 검프🍫 였다!
-검프의 리뷰는 간결함에 관련된 내용이 많았다.
-일관성이 있는 코드, 가독성이 좋은 코드, 추상화가 잘 되어있는 코드
-읽기 좋고, 간결한 방향으로 코드를 작성하는 방법을 배운 것 같다.
-코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

페어에게 배울 부분

생각 정리
-중간 중간 현재 상황에 대해 그림을 그리거나, 글을 적으면서 정리한다.
-페어와 동일한 부분을 이해하고 있는지 확인한다.
-진행하는데 매우 도움이 되었던 것 같다.
-나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

가감없이 의견을 말해주는 부분
-진행 상황에 대한 부분, 진행 속도, 지금 자신이 이해하고 있는 부분을 말해줘서 편했다.
-회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

도메인 언어에 신경쓰는 부분
-클래스명, 변수명과 같은 언어를 세심하게 신경쓴다.
-요구사항 정리도 깔끔하게 잘하는 것 같다.

후추 최고 👍

]]> - - - - - <![CDATA[사다리 타기 미션 회고]]> - https://greeng00se.github.io/ladder-retrospective - - 2023-02-26T00:00:00.000Z - -
PR 링크
+ * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after ` | + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > |
+ * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + *

!^a

+ *

!^a

+ * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | ab + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a c + * ^ + * > | a c + * ^ + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * > | a c + * ^ + * > | a &<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after ` | a c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After ` | a &<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a &<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array} events + * @returns {Array} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract} Parent + * + * @typedef {Omit & {type: 'fragment', children: Array}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array} transforms + * Tree transforms. + * + * @typedef {Partial} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array} stack + * Stack of nodes. + * @property {Array} tokenStack + * Stack of tokens. + * @property {(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(18464); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-62fc7601.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.Z)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "
"); + } else if (node.type === "strong") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "emphasis") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "paragraph") { + return `

${node.children.map(output).join("")}

`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + " + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_8af3addd.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_8af3addd.J)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 27707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ insertEdge), +/* harmony export */ h: () => (/* binding */ positionEdgeLabel), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(64589); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '" + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "
"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + img.style.width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = bbox.width + node.padding; + const totalHeight = bbox.height + node.padding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("
") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc82", edge, edge.labelType); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Moving label abc78 ", edge.id, edge.label, edgeLabels[edge.id]); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc78" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundryNode) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 cutPathAtIntersect", _points, boundryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 checking point", point2, boundryNode); + if (!outsideNode(boundryNode, point2) && !isInside) { + const inter = intersection(boundryNode, lastPointOutside, point2); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 inside", point2, lastPointOutside, inter); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 intersection", inter); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 no intersect", inter, points); + } + isInside = true; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 outside", point2, lastPointOutside); + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 returning points", points); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 InsertEdge: ", edge); + if (head.intersect && tail.intersect) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Last point", + points[points.length - 1], + head, + head.intersect(points[points.length - 1]) + ); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .$0Z; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeStart", edge.arrowTypeStart); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeEnd", edge.arrowTypeEnd); + switch (edge.arrowTypeStart) { + case "arrow_cross": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-crossStart)" + ); + break; + case "arrow_point": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-pointStart)" + ); + break; + case "arrow_barb": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-barbStart)" + ); + break; + case "arrow_circle": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-circleStart)" + ); + break; + case "aggregation": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationStart)" + ); + break; + case "extension": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-extensionStart)" + ); + break; + case "composition": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-compositionStart)" + ); + break; + case "dependency": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyStart)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopStart)" + ); + break; + } + switch (edge.arrowTypeEnd) { + case "arrow_cross": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-crossEnd)"); + break; + case "arrow_point": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-pointEnd)"); + break; + case "arrow_barb": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-barbEnd)"); + break; + case "arrow_circle": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-circleEnd)"); + break; + case "aggregation": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationEnd)" + ); + break; + case "extension": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-extensionEnd)" + ); + break; + case "composition": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-compositionEnd)" + ); + break; + case "dependency": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyEnd)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopEnd)" + ); + break; + } + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 75254: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ f: () => (/* binding */ flowDb), +/* harmony export */ p: () => (/* binding */ parser$1) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 4], $V1 = [1, 3], $V2 = [1, 5], $V3 = [1, 8, 9, 10, 11, 27, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $V4 = [2, 2], $V5 = [1, 13], $V6 = [1, 14], $V7 = [1, 15], $V8 = [1, 16], $V9 = [1, 23], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 49], $Ve = [1, 48], $Vf = [1, 29], $Vg = [1, 30], $Vh = [1, 31], $Vi = [1, 32], $Vj = [1, 33], $Vk = [1, 44], $Vl = [1, 46], $Vm = [1, 42], $Vn = [1, 47], $Vo = [1, 43], $Vp = [1, 50], $Vq = [1, 45], $Vr = [1, 51], $Vs = [1, 52], $Vt = [1, 34], $Vu = [1, 35], $Vv = [1, 36], $Vw = [1, 37], $Vx = [1, 57], $Vy = [1, 8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vz = [1, 61], $VA = [1, 60], $VB = [1, 62], $VC = [8, 9, 11, 73, 75], $VD = [1, 88], $VE = [1, 93], $VF = [1, 92], $VG = [1, 89], $VH = [1, 85], $VI = [1, 91], $VJ = [1, 87], $VK = [1, 94], $VL = [1, 90], $VM = [1, 95], $VN = [1, 86], $VO = [8, 9, 10, 11, 73, 75], $VP = [8, 9, 10, 11, 44, 73, 75], $VQ = [8, 9, 10, 11, 29, 42, 44, 46, 48, 50, 52, 54, 56, 58, 61, 63, 65, 66, 68, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VR = [8, 9, 11, 42, 58, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VS = [42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VT = [1, 121], $VU = [1, 120], $VV = [1, 128], $VW = [1, 142], $VX = [1, 143], $VY = [1, 144], $VZ = [1, 145], $V_ = [1, 130], $V$ = [1, 132], $V01 = [1, 136], $V11 = [1, 137], $V21 = [1, 138], $V31 = [1, 139], $V41 = [1, 140], $V51 = [1, 141], $V61 = [1, 146], $V71 = [1, 147], $V81 = [1, 126], $V91 = [1, 127], $Va1 = [1, 134], $Vb1 = [1, 129], $Vc1 = [1, 133], $Vd1 = [1, 131], $Ve1 = [8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vf1 = [1, 149], $Vg1 = [8, 9, 11], $Vh1 = [8, 9, 10, 11, 14, 42, 58, 86, 102, 103, 106, 108, 111, 112, 113], $Vi1 = [1, 169], $Vj1 = [1, 165], $Vk1 = [1, 166], $Vl1 = [1, 170], $Vm1 = [1, 167], $Vn1 = [1, 168], $Vo1 = [75, 113, 116], $Vp1 = [8, 9, 10, 11, 12, 14, 27, 29, 32, 42, 58, 73, 81, 82, 83, 84, 85, 86, 87, 102, 106, 108, 111, 112, 113], $Vq1 = [10, 103], $Vr1 = [31, 47, 49, 51, 53, 55, 60, 62, 64, 65, 67, 69, 113, 114, 115], $Vs1 = [1, 235], $Vt1 = [1, 233], $Vu1 = [1, 237], $Vv1 = [1, 231], $Vw1 = [1, 232], $Vx1 = [1, 234], $Vy1 = [1, 236], $Vz1 = [1, 238], $VA1 = [1, 255], $VB1 = [8, 9, 11, 103], $VC1 = [8, 9, 10, 11, 58, 81, 102, 103, 106, 107, 108, 109]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "graphConfig": 4, "document": 5, "line": 6, "statement": 7, "SEMI": 8, "NEWLINE": 9, "SPACE": 10, "EOF": 11, "GRAPH": 12, "NODIR": 13, "DIR": 14, "FirstStmtSeperator": 15, "ending": 16, "endToken": 17, "spaceList": 18, "spaceListNewline": 19, "verticeStatement": 20, "separator": 21, "styleStatement": 22, "linkStyleStatement": 23, "classDefStatement": 24, "classStatement": 25, "clickStatement": 26, "subgraph": 27, "textNoTags": 28, "SQS": 29, "text": 30, "SQE": 31, "end": 32, "direction": 33, "acc_title": 34, "acc_title_value": 35, "acc_descr": 36, "acc_descr_value": 37, "acc_descr_multiline_value": 38, "link": 39, "node": 40, "styledVertex": 41, "AMP": 42, "vertex": 43, "STYLE_SEPARATOR": 44, "idString": 45, "DOUBLECIRCLESTART": 46, "DOUBLECIRCLEEND": 47, "PS": 48, "PE": 49, "(-": 50, "-)": 51, "STADIUMSTART": 52, "STADIUMEND": 53, "SUBROUTINESTART": 54, "SUBROUTINEEND": 55, "VERTEX_WITH_PROPS_START": 56, "NODE_STRING[field]": 57, "COLON": 58, "NODE_STRING[value]": 59, "PIPE": 60, "CYLINDERSTART": 61, "CYLINDEREND": 62, "DIAMOND_START": 63, "DIAMOND_STOP": 64, "TAGEND": 65, "TRAPSTART": 66, "TRAPEND": 67, "INVTRAPSTART": 68, "INVTRAPEND": 69, "linkStatement": 70, "arrowText": 71, "TESTSTR": 72, "START_LINK": 73, "edgeText": 74, "LINK": 75, "edgeTextToken": 76, "STR": 77, "MD_STR": 78, "textToken": 79, "keywords": 80, "STYLE": 81, "LINKSTYLE": 82, "CLASSDEF": 83, "CLASS": 84, "CLICK": 85, "DOWN": 86, "UP": 87, "textNoTagsToken": 88, "stylesOpt": 89, "idString[vertex]": 90, "idString[class]": 91, "CALLBACKNAME": 92, "CALLBACKARGS": 93, "HREF": 94, "LINK_TARGET": 95, "STR[link]": 96, "STR[tooltip]": 97, "alphaNum": 98, "DEFAULT": 99, "numList": 100, "INTERPOLATE": 101, "NUM": 102, "COMMA": 103, "style": 104, "styleComponent": 105, "NODE_STRING": 106, "UNIT": 107, "BRKT": 108, "PCT": 109, "idStringToken": 110, "MINUS": 111, "MULT": 112, "UNICODE_TEXT": 113, "TEXT": 114, "TAGSTART": 115, "EDGE_TEXT": 116, "alphaNumToken": 117, "direction_tb": 118, "direction_bt": 119, "direction_rl": 120, "direction_lr": 121, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 8: "SEMI", 9: "NEWLINE", 10: "SPACE", 11: "EOF", 12: "GRAPH", 13: "NODIR", 14: "DIR", 27: "subgraph", 29: "SQS", 31: "SQE", 32: "end", 34: "acc_title", 35: "acc_title_value", 36: "acc_descr", 37: "acc_descr_value", 38: "acc_descr_multiline_value", 42: "AMP", 44: "STYLE_SEPARATOR", 46: "DOUBLECIRCLESTART", 47: "DOUBLECIRCLEEND", 48: "PS", 49: "PE", 50: "(-", 51: "-)", 52: "STADIUMSTART", 53: "STADIUMEND", 54: "SUBROUTINESTART", 55: "SUBROUTINEEND", 56: "VERTEX_WITH_PROPS_START", 57: "NODE_STRING[field]", 58: "COLON", 59: "NODE_STRING[value]", 60: "PIPE", 61: "CYLINDERSTART", 62: "CYLINDEREND", 63: "DIAMOND_START", 64: "DIAMOND_STOP", 65: "TAGEND", 66: "TRAPSTART", 67: "TRAPEND", 68: "INVTRAPSTART", 69: "INVTRAPEND", 72: "TESTSTR", 73: "START_LINK", 75: "LINK", 77: "STR", 78: "MD_STR", 81: "STYLE", 82: "LINKSTYLE", 83: "CLASSDEF", 84: "CLASS", 85: "CLICK", 86: "DOWN", 87: "UP", 90: "idString[vertex]", 91: "idString[class]", 92: "CALLBACKNAME", 93: "CALLBACKARGS", 94: "HREF", 95: "LINK_TARGET", 96: "STR[link]", 97: "STR[tooltip]", 99: "DEFAULT", 101: "INTERPOLATE", 102: "NUM", 103: "COMMA", 106: "NODE_STRING", 107: "UNIT", 108: "BRKT", 109: "PCT", 111: "MINUS", 112: "MULT", 113: "UNICODE_TEXT", 114: "TEXT", 115: "TAGSTART", 116: "EDGE_TEXT", 118: "direction_tb", 119: "direction_bt", 120: "direction_rl", 121: "direction_lr" }, + productions_: [0, [3, 2], [5, 0], [5, 2], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [4, 2], [4, 2], [4, 2], [4, 3], [16, 2], [16, 1], [17, 1], [17, 1], [17, 1], [15, 1], [15, 1], [15, 2], [19, 2], [19, 2], [19, 1], [19, 1], [18, 2], [18, 1], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 9], [7, 6], [7, 4], [7, 1], [7, 2], [7, 2], [7, 1], [21, 1], [21, 1], [21, 1], [20, 3], [20, 4], [20, 2], [20, 1], [40, 1], [40, 5], [41, 1], [41, 3], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 8], [43, 4], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 4], [43, 4], [43, 1], [39, 2], [39, 3], [39, 3], [39, 1], [39, 3], [74, 1], [74, 2], [74, 1], [74, 1], [70, 1], [71, 3], [30, 1], [30, 2], [30, 1], [30, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [28, 1], [28, 2], [28, 1], [28, 1], [24, 5], [25, 5], [26, 2], [26, 4], [26, 3], [26, 5], [26, 3], [26, 5], [26, 5], [26, 7], [26, 2], [26, 4], [26, 2], [26, 4], [26, 4], [26, 6], [22, 5], [23, 5], [23, 5], [23, 9], [23, 9], [23, 7], [23, 7], [100, 1], [100, 3], [89, 1], [89, 3], [104, 1], [104, 2], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [79, 1], [79, 1], [79, 1], [79, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [76, 1], [76, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [45, 1], [45, 2], [98, 1], [98, 2], [33, 1], [33, 1], [33, 1], [33, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 2: + this.$ = []; + break; + case 3: + if (!Array.isArray($$[$0]) || $$[$0].length > 0) { + $$[$0 - 1].push($$[$0]); + } + this.$ = $$[$0 - 1]; + break; + case 4: + case 176: + this.$ = $$[$0]; + break; + case 11: + yy.setDirection("TB"); + this.$ = "TB"; + break; + case 12: + yy.setDirection($$[$0 - 1]); + this.$ = $$[$0 - 1]; + break; + case 27: + this.$ = $$[$0 - 1].nodes; + break; + case 28: + case 29: + case 30: + case 31: + case 32: + this.$ = []; + break; + case 33: + this.$ = yy.addSubGraph($$[$0 - 6], $$[$0 - 1], $$[$0 - 4]); + break; + case 34: + this.$ = yy.addSubGraph($$[$0 - 3], $$[$0 - 1], $$[$0 - 3]); + break; + case 35: + this.$ = yy.addSubGraph(void 0, $$[$0 - 1], void 0); + break; + case 37: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 38: + case 39: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 43: + yy.addLink($$[$0 - 2].stmt, $$[$0], $$[$0 - 1]); + this.$ = { stmt: $$[$0], nodes: $$[$0].concat($$[$0 - 2].nodes) }; + break; + case 44: + yy.addLink($$[$0 - 3].stmt, $$[$0 - 1], $$[$0 - 2]); + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1].concat($$[$0 - 3].nodes) }; + break; + case 45: + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1] }; + break; + case 46: + this.$ = { stmt: $$[$0], nodes: $$[$0] }; + break; + case 47: + this.$ = [$$[$0]]; + break; + case 48: + this.$ = $$[$0 - 4].concat($$[$0]); + break; + case 49: + this.$ = $$[$0]; + break; + case 50: + this.$ = $$[$0 - 2]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 51: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "square"); + break; + case 52: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "doublecircle"); + break; + case 53: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "circle"); + break; + case 54: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "ellipse"); + break; + case 55: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "stadium"); + break; + case 56: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "subroutine"); + break; + case 57: + this.$ = $$[$0 - 7]; + yy.addVertex($$[$0 - 7], $$[$0 - 1], "rect", void 0, void 0, void 0, Object.fromEntries([[$$[$0 - 5], $$[$0 - 3]]])); + break; + case 58: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "cylinder"); + break; + case 59: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "round"); + break; + case 60: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "diamond"); + break; + case 61: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "hexagon"); + break; + case 62: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "odd"); + break; + case 63: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "trapezoid"); + break; + case 64: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "inv_trapezoid"); + break; + case 65: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_right"); + break; + case 66: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_left"); + break; + case 67: + this.$ = $$[$0]; + yy.addVertex($$[$0]); + break; + case 68: + $$[$0 - 1].text = $$[$0]; + this.$ = $$[$0 - 1]; + break; + case 69: + case 70: + $$[$0 - 2].text = $$[$0 - 1]; + this.$ = $$[$0 - 2]; + break; + case 71: + this.$ = $$[$0]; + break; + case 72: + var inf = yy.destructLink($$[$0], $$[$0 - 2]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length, "text": $$[$0 - 1] }; + break; + case 73: + this.$ = { text: $$[$0], type: "text" }; + break; + case 74: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 75: + this.$ = { text: $$[$0], type: "string" }; + break; + case 76: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 77: + var inf = yy.destructLink($$[$0]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length }; + break; + case 78: + this.$ = $$[$0 - 1]; + break; + case 79: + this.$ = { text: $$[$0], type: "text" }; + break; + case 80: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 81: + this.$ = { text: $$[$0], type: "string" }; + break; + case 82: + case 97: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 94: + this.$ = { text: $$[$0], type: "text" }; + break; + case 95: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 96: + this.$ = { text: $$[$0], type: "text" }; + break; + case 98: + this.$ = $$[$0 - 4]; + yy.addClass($$[$0 - 2], $$[$0]); + break; + case 99: + this.$ = $$[$0 - 4]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 100: + case 108: + this.$ = $$[$0 - 1]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 101: + case 109: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 102: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 103: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 4], $$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 104: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 105: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 106: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 107: + this.$ = $$[$0 - 6]; + yy.setLink($$[$0 - 6], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 6], $$[$0 - 2]); + break; + case 110: + this.$ = $$[$0 - 1]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 111: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 112: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + break; + case 113: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 5], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 5], $$[$0 - 2]); + break; + case 114: + this.$ = $$[$0 - 4]; + yy.addVertex($$[$0 - 2], void 0, void 0, $$[$0]); + break; + case 115: + this.$ = $$[$0 - 4]; + yy.updateLink([$$[$0 - 2]], $$[$0]); + break; + case 116: + this.$ = $$[$0 - 4]; + yy.updateLink($$[$0 - 2], $$[$0]); + break; + case 117: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate([$$[$0 - 6]], $$[$0 - 2]); + yy.updateLink([$$[$0 - 6]], $$[$0]); + break; + case 118: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate($$[$0 - 6], $$[$0 - 2]); + yy.updateLink($$[$0 - 6], $$[$0]); + break; + case 119: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate([$$[$0 - 4]], $$[$0]); + break; + case 120: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate($$[$0 - 4], $$[$0]); + break; + case 121: + case 123: + this.$ = [$$[$0]]; + break; + case 122: + case 124: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 126: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 174: + this.$ = $$[$0]; + break; + case 175: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 177: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 178: + this.$ = { stmt: "dir", value: "TB" }; + break; + case 179: + this.$ = { stmt: "dir", value: "BT" }; + break; + case 180: + this.$ = { stmt: "dir", value: "RL" }; + break; + case 181: + this.$ = { stmt: "dir", value: "LR" }; + break; + } + }, + table: [{ 3: 1, 4: 2, 9: $V0, 10: $V1, 12: $V2 }, { 1: [3] }, o($V3, $V4, { 5: 6 }), { 4: 7, 9: $V0, 10: $V1, 12: $V2 }, { 4: 8, 9: $V0, 10: $V1, 12: $V2 }, { 13: [1, 9], 14: [1, 10] }, { 1: [2, 1], 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($V3, [2, 9]), o($V3, [2, 10]), o($V3, [2, 11]), { 8: [1, 54], 9: [1, 55], 10: $Vx, 15: 53, 18: 56 }, o($Vy, [2, 3]), o($Vy, [2, 4]), o($Vy, [2, 5]), o($Vy, [2, 6]), o($Vy, [2, 7]), o($Vy, [2, 8]), { 8: $Vz, 9: $VA, 11: $VB, 21: 58, 39: 59, 70: 63, 73: [1, 64], 75: [1, 65] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 66 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 67 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 68 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 69 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 70 }, { 8: $Vz, 9: $VA, 10: [1, 71], 11: $VB, 21: 72 }, o($Vy, [2, 36]), { 35: [1, 73] }, { 37: [1, 74] }, o($Vy, [2, 39]), o($VC, [2, 46], { 18: 75, 10: $Vx }), { 10: [1, 76] }, { 10: [1, 77] }, { 10: [1, 78] }, { 10: [1, 79] }, { 14: $VD, 42: $VE, 58: $VF, 77: [1, 83], 86: $VG, 92: [1, 80], 94: [1, 81], 98: 82, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, o($Vy, [2, 178]), o($Vy, [2, 179]), o($Vy, [2, 180]), o($Vy, [2, 181]), o($VO, [2, 47]), o($VO, [2, 49], { 44: [1, 96] }), o($VP, [2, 67], { 110: 109, 29: [1, 97], 42: $Vd, 46: [1, 98], 48: [1, 99], 50: [1, 100], 52: [1, 101], 54: [1, 102], 56: [1, 103], 58: $Ve, 61: [1, 104], 63: [1, 105], 65: [1, 106], 66: [1, 107], 68: [1, 108], 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($VQ, [2, 174]), o($VQ, [2, 135]), o($VQ, [2, 136]), o($VQ, [2, 137]), o($VQ, [2, 138]), o($VQ, [2, 139]), o($VQ, [2, 140]), o($VQ, [2, 141]), o($VQ, [2, 142]), o($VQ, [2, 143]), o($VQ, [2, 144]), o($VQ, [2, 145]), o($V3, [2, 12]), o($V3, [2, 18]), o($V3, [2, 19]), { 9: [1, 110] }, o($VR, [2, 26], { 18: 111, 10: $Vx }), o($Vy, [2, 27]), { 40: 112, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vy, [2, 40]), o($Vy, [2, 41]), o($Vy, [2, 42]), o($VS, [2, 71], { 71: 113, 60: [1, 115], 72: [1, 114] }), { 74: 116, 76: 117, 77: [1, 118], 78: [1, 119], 113: $VT, 116: $VU }, o([42, 58, 60, 72, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 77]), o($Vy, [2, 28]), o($Vy, [2, 29]), o($Vy, [2, 30]), o($Vy, [2, 31]), o($Vy, [2, 32]), { 10: $VV, 12: $VW, 14: $VX, 27: $VY, 28: 122, 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 77: [1, 124], 78: [1, 125], 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 123, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Ve1, $V4, { 5: 148 }), o($Vy, [2, 37]), o($Vy, [2, 38]), o($VC, [2, 45], { 42: $Vf1 }), { 42: $Vd, 45: 150, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 99: [1, 151], 100: 152, 102: [1, 153] }, { 42: $Vd, 45: 154, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 42: $Vd, 45: 155, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 100], { 10: [1, 156], 93: [1, 157] }), { 77: [1, 158] }, o($Vg1, [2, 108], { 117: 160, 10: [1, 159], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 110], { 10: [1, 161] }), o($Vh1, [2, 176]), o($Vh1, [2, 163]), o($Vh1, [2, 164]), o($Vh1, [2, 165]), o($Vh1, [2, 166]), o($Vh1, [2, 167]), o($Vh1, [2, 168]), o($Vh1, [2, 169]), o($Vh1, [2, 170]), o($Vh1, [2, 171]), o($Vh1, [2, 172]), o($Vh1, [2, 173]), { 42: $Vd, 45: 162, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 30: 163, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 171, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 173, 48: [1, 172], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 174, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 175, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 176, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 106: [1, 177] }, { 30: 178, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 179, 63: [1, 180], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 181, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 182, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 183, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VQ, [2, 175]), o($V3, [2, 20]), o($VR, [2, 25]), o($VC, [2, 43], { 18: 184, 10: $Vx }), o($VS, [2, 68], { 10: [1, 185] }), { 10: [1, 186] }, { 30: 187, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 75: [1, 188], 76: 189, 113: $VT, 116: $VU }, o($Vo1, [2, 73]), o($Vo1, [2, 75]), o($Vo1, [2, 76]), o($Vo1, [2, 161]), o($Vo1, [2, 162]), { 8: $Vz, 9: $VA, 10: $VV, 11: $VB, 12: $VW, 14: $VX, 21: 191, 27: $VY, 29: [1, 190], 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 192, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Vp1, [2, 94]), o($Vp1, [2, 96]), o($Vp1, [2, 97]), o($Vp1, [2, 150]), o($Vp1, [2, 151]), o($Vp1, [2, 152]), o($Vp1, [2, 153]), o($Vp1, [2, 154]), o($Vp1, [2, 155]), o($Vp1, [2, 156]), o($Vp1, [2, 157]), o($Vp1, [2, 158]), o($Vp1, [2, 159]), o($Vp1, [2, 160]), o($Vp1, [2, 83]), o($Vp1, [2, 84]), o($Vp1, [2, 85]), o($Vp1, [2, 86]), o($Vp1, [2, 87]), o($Vp1, [2, 88]), o($Vp1, [2, 89]), o($Vp1, [2, 90]), o($Vp1, [2, 91]), o($Vp1, [2, 92]), o($Vp1, [2, 93]), { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 193], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vx, 18: 194 }, { 10: [1, 195], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 196] }, { 10: [1, 197], 103: [1, 198] }, o($Vq1, [2, 121]), { 10: [1, 199], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 200], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 77: [1, 201] }, o($Vg1, [2, 102], { 10: [1, 202] }), o($Vg1, [2, 104], { 10: [1, 203] }), { 77: [1, 204] }, o($Vh1, [2, 177]), { 77: [1, 205], 95: [1, 206] }, o($VO, [2, 50], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), { 31: [1, 207], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Vr1, [2, 79]), o($Vr1, [2, 81]), o($Vr1, [2, 82]), o($Vr1, [2, 146]), o($Vr1, [2, 147]), o($Vr1, [2, 148]), o($Vr1, [2, 149]), { 47: [1, 209], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 210, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 49: [1, 211], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 51: [1, 212], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 53: [1, 213], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 55: [1, 214], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 58: [1, 215] }, { 62: [1, 216], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 64: [1, 217], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 218, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 31: [1, 219], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 220], 69: [1, 221], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 223], 69: [1, 222], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VC, [2, 44], { 42: $Vf1 }), o($VS, [2, 70]), o($VS, [2, 69]), { 60: [1, 224], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VS, [2, 72]), o($Vo1, [2, 74]), { 30: 225, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Ve1, $V4, { 5: 226 }), o($Vp1, [2, 95]), o($Vy, [2, 35]), { 41: 227, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 228, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 239, 101: [1, 240], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 241, 101: [1, 242], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 102: [1, 243] }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 244, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 42: $Vd, 45: 245, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 101]), { 77: [1, 246] }, { 77: [1, 247], 95: [1, 248] }, o($Vg1, [2, 109]), o($Vg1, [2, 111], { 10: [1, 249] }), o($Vg1, [2, 112]), o($VP, [2, 51]), o($Vr1, [2, 80]), o($VP, [2, 52]), { 49: [1, 250], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 59]), o($VP, [2, 54]), o($VP, [2, 55]), o($VP, [2, 56]), { 106: [1, 251] }, o($VP, [2, 58]), o($VP, [2, 60]), { 64: [1, 252], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 62]), o($VP, [2, 63]), o($VP, [2, 65]), o($VP, [2, 64]), o($VP, [2, 66]), o([10, 42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 78]), { 31: [1, 253], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 254], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($VO, [2, 48]), o($Vg1, [2, 114], { 103: $VA1 }), o($VB1, [2, 123], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($VC1, [2, 125]), o($VC1, [2, 127]), o($VC1, [2, 128]), o($VC1, [2, 129]), o($VC1, [2, 130]), o($VC1, [2, 131]), o($VC1, [2, 132]), o($VC1, [2, 133]), o($VC1, [2, 134]), o($Vg1, [2, 115], { 103: $VA1 }), { 10: [1, 257] }, o($Vg1, [2, 116], { 103: $VA1 }), { 10: [1, 258] }, o($Vq1, [2, 122]), o($Vg1, [2, 98], { 103: $VA1 }), o($Vg1, [2, 99], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($Vg1, [2, 103]), o($Vg1, [2, 105], { 10: [1, 259] }), o($Vg1, [2, 106]), { 95: [1, 260] }, { 49: [1, 261] }, { 60: [1, 262] }, { 64: [1, 263] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 264 }, o($Vy, [2, 34]), { 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 104: 265, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VC1, [2, 126]), { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 266, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 267, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 95: [1, 268] }, o($Vg1, [2, 113]), o($VP, [2, 53]), { 30: 269, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 61]), o($Ve1, $V4, { 5: 270 }), o($VB1, [2, 124], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($Vg1, [2, 119], { 117: 160, 10: [1, 271], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 120], { 117: 160, 10: [1, 272], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 107]), { 31: [1, 273], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 274], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 275, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 276, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VP, [2, 57]), o($Vy, [2, 33]), o($Vg1, [2, 117], { 103: $VA1 }), o($Vg1, [2, 118], { 103: $VA1 })], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex2() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex2(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex2() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 34; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 36; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + this.begin("callbackname"); + break; + case 8: + this.popState(); + break; + case 9: + this.popState(); + this.begin("callbackargs"); + break; + case 10: + return 92; + case 11: + this.popState(); + break; + case 12: + return 93; + case 13: + return "MD_STR"; + case 14: + this.popState(); + break; + case 15: + this.begin("md_string"); + break; + case 16: + return "STR"; + case 17: + this.popState(); + break; + case 18: + this.pushState("string"); + break; + case 19: + return 81; + case 20: + return 99; + case 21: + return 82; + case 22: + return 101; + case 23: + return 83; + case 24: + return 84; + case 25: + return 94; + case 26: + this.begin("click"); + break; + case 27: + this.popState(); + break; + case 28: + return 85; + case 29: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 30: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 31: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 32: + return 27; + case 33: + return 32; + case 34: + return 95; + case 35: + return 95; + case 36: + return 95; + case 37: + return 95; + case 38: + this.popState(); + return 13; + case 39: + this.popState(); + return 14; + case 40: + this.popState(); + return 14; + case 41: + this.popState(); + return 14; + case 42: + this.popState(); + return 14; + case 43: + this.popState(); + return 14; + case 44: + this.popState(); + return 14; + case 45: + this.popState(); + return 14; + case 46: + this.popState(); + return 14; + case 47: + this.popState(); + return 14; + case 48: + this.popState(); + return 14; + case 49: + return 118; + case 50: + return 119; + case 51: + return 120; + case 52: + return 121; + case 53: + return 102; + case 54: + return 108; + case 55: + return 44; + case 56: + return 58; + case 57: + return 42; + case 58: + return 8; + case 59: + return 103; + case 60: + return 112; + case 61: + this.popState(); + return 75; + case 62: + this.pushState("edgeText"); + return 73; + case 63: + return 116; + case 64: + this.popState(); + return 75; + case 65: + this.pushState("thickEdgeText"); + return 73; + case 66: + return 116; + case 67: + this.popState(); + return 75; + case 68: + this.pushState("dottedEdgeText"); + return 73; + case 69: + return 116; + case 70: + return 75; + case 71: + this.popState(); + return 51; + case 72: + return "TEXT"; + case 73: + this.pushState("ellipseText"); + return 50; + case 74: + this.popState(); + return 53; + case 75: + this.pushState("text"); + return 52; + case 76: + this.popState(); + return 55; + case 77: + this.pushState("text"); + return 54; + case 78: + return 56; + case 79: + this.pushState("text"); + return 65; + case 80: + this.popState(); + return 62; + case 81: + this.pushState("text"); + return 61; + case 82: + this.popState(); + return 47; + case 83: + this.pushState("text"); + return 46; + case 84: + this.popState(); + return 67; + case 85: + this.popState(); + return 69; + case 86: + return 114; + case 87: + this.pushState("trapText"); + return 66; + case 88: + this.pushState("trapText"); + return 68; + case 89: + return 115; + case 90: + return 65; + case 91: + return 87; + case 92: + return "SEP"; + case 93: + return 86; + case 94: + return 112; + case 95: + return 108; + case 96: + return 42; + case 97: + return 106; + case 98: + return 111; + case 99: + return 113; + case 100: + this.popState(); + return 60; + case 101: + this.pushState("text"); + return 60; + case 102: + this.popState(); + return 49; + case 103: + this.pushState("text"); + return 48; + case 104: + this.popState(); + return 31; + case 105: + this.pushState("text"); + return 29; + case 106: + this.popState(); + return 64; + case 107: + this.pushState("text"); + return 63; + case 108: + return "TEXT"; + case 109: + return "QUOTE"; + case 110: + return 9; + case 111: + return 10; + case 112: + return 11; + } + }, + rules: [/^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:[^`"]+)/, /^(?:[`]["])/, /^(?:["][`])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:["])/, /^(?:style\b)/, /^(?:default\b)/, /^(?:linkStyle\b)/, /^(?:interpolate\b)/, /^(?:classDef\b)/, /^(?:class\b)/, /^(?:href[\s])/, /^(?:click[\s]+)/, /^(?:[\s\n])/, /^(?:[^\s\n]*)/, /^(?:flowchart-elk\b)/, /^(?:graph\b)/, /^(?:flowchart\b)/, /^(?:subgraph\b)/, /^(?:end\b\s*)/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:(\r?\n)*\s*\n)/, /^(?:\s*LR\b)/, /^(?:\s*RL\b)/, /^(?:\s*TB\b)/, /^(?:\s*BT\b)/, /^(?:\s*TD\b)/, /^(?:\s*BR\b)/, /^(?:\s*<)/, /^(?:\s*>)/, /^(?:\s*\^)/, /^(?:\s*v\b)/, /^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:[0-9]+)/, /^(?:#)/, /^(?::::)/, /^(?::)/, /^(?:&)/, /^(?:;)/, /^(?:,)/, /^(?:\*)/, /^(?:\s*[xo<]?--+[-xo>]\s*)/, /^(?:\s*[xo<]?--\s*)/, /^(?:[^-]|-(?!-)+)/, /^(?:\s*[xo<]?==+[=xo>]\s*)/, /^(?:\s*[xo<]?==\s*)/, /^(?:[^=]|=(?!))/, /^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/, /^(?:\s*[xo<]?-\.\s*)/, /^(?:[^\.]|\.(?!))/, /^(?:\s*~~[\~]+\s*)/, /^(?:[-/\)][\)])/, /^(?:[^\(\)\[\]\{\}]|(?!\)+))/, /^(?:\(-)/, /^(?:\]\))/, /^(?:\(\[)/, /^(?:\]\])/, /^(?:\[\[)/, /^(?:\[\|)/, /^(?:>)/, /^(?:\)\])/, /^(?:\[\()/, /^(?:\)\)\))/, /^(?:\(\(\()/, /^(?:[\\(?=\])][\]])/, /^(?:\/(?=\])\])/, /^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/, /^(?:\[\/)/, /^(?:\[\\)/, /^(?:<)/, /^(?:>)/, /^(?:\^)/, /^(?:\\\|)/, /^(?:v\b)/, /^(?:\*)/, /^(?:#)/, /^(?:&)/, /^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/, /^(?:-)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\|)/, /^(?:\|)/, /^(?:\))/, /^(?:\()/, /^(?:\])/, /^(?:\[)/, /^(?:(\}))/, /^(?:\{)/, /^(?:[^\[\]\(\)\{\}\|\"]+)/, /^(?:")/, /^(?:(\r?\n)+)/, /^(?:\s)/, /^(?:$)/], + conditions: { "callbackargs": { "rules": [11, 12, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "callbackname": { "rules": [8, 9, 10, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "href": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "click": { "rules": [15, 18, 27, 28, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dottedEdgeText": { "rules": [15, 18, 67, 69, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "thickEdgeText": { "rules": [15, 18, 64, 66, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "edgeText": { "rules": [15, 18, 61, 63, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "trapText": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 84, 85, 86, 87, 88, 101, 103, 105, 107], "inclusive": false }, "ellipseText": { "rules": [15, 18, 70, 71, 72, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "text": { "rules": [15, 18, 70, 73, 74, 75, 76, 77, 80, 81, 82, 83, 87, 88, 100, 101, 102, 103, 104, 105, 106, 107, 108], "inclusive": false }, "vertex": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dir": { "rules": [15, 18, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr_multiline": { "rules": [5, 6, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr": { "rules": [3, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_title": { "rules": [1, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "md_string": { "rules": [13, 14, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "string": { "rules": [15, 16, 17, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 67, 68, 70, 73, 75, 77, 78, 79, 81, 83, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 101, 103, 105, 107, 109, 110, 111, 112], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const MERMAID_DOM_ID_PREFIX = "flowchart-"; +let vertexCounter = 0; +let config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); +let vertices = {}; +let edges = []; +let classes = {}; +let subGraphs = []; +let subGraphLookup = {}; +let tooltips = {}; +let subCount = 0; +let firstGraphFlag = true; +let direction; +let version; +let funs = []; +const sanitizeText = (txt) => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, config); +const lookUpDomId = function(id) { + const veritceKeys = Object.keys(vertices); + for (const veritceKey of veritceKeys) { + if (vertices[veritceKey].id === id) { + return vertices[veritceKey].domId; + } + } + return id; +}; +const addVertex = function(_id, textObj, type, style, classes2, dir, props = {}) { + let txt; + let id = _id; + if (id === void 0) { + return; + } + if (id.trim().length === 0) { + return; + } + if (vertices[id] === void 0) { + vertices[id] = { + id, + labelType: "text", + domId: MERMAID_DOM_ID_PREFIX + id + "-" + vertexCounter, + styles: [], + classes: [] + }; + } + vertexCounter++; + if (textObj !== void 0) { + config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + txt = sanitizeText(textObj.text.trim()); + vertices[id].labelType = textObj.type; + if (txt[0] === '"' && txt[txt.length - 1] === '"') { + txt = txt.substring(1, txt.length - 1); + } + vertices[id].text = txt; + } else { + if (vertices[id].text === void 0) { + vertices[id].text = _id; + } + } + if (type !== void 0) { + vertices[id].type = type; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + vertices[id].styles.push(s); + }); + } + if (classes2 !== void 0 && classes2 !== null) { + classes2.forEach(function(s) { + vertices[id].classes.push(s); + }); + } + if (dir !== void 0) { + vertices[id].dir = dir; + } + if (vertices[id].props === void 0) { + vertices[id].props = props; + } else if (props !== void 0) { + Object.assign(vertices[id].props, props); + } +}; +const addSingleLink = function(_start, _end, type) { + let start = _start; + let end = _end; + const edge = { start, end, type: void 0, text: "", labelType: "text" }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 Got edge...", edge); + const linkTextObj = type.text; + if (linkTextObj !== void 0) { + edge.text = sanitizeText(linkTextObj.text.trim()); + if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { + edge.text = edge.text.substring(1, edge.text.length - 1); + } + edge.labelType = linkTextObj.type; + } + if (type !== void 0) { + edge.type = type.type; + edge.stroke = type.stroke; + edge.length = type.length; + } + if ((edge == null ? void 0 : edge.length) > 10) { + edge.length = 10; + } + if (edges.length < 280) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 pushing edge..."); + edges.push(edge); + } else { + throw new Error("Too many edges"); + } +}; +const addLink = function(_start, _end, type) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("addLink (abc78)", _start, _end, type); + let i, j; + for (i = 0; i < _start.length; i++) { + for (j = 0; j < _end.length; j++) { + addSingleLink(_start[i], _end[j], type); + } + } +}; +const updateLinkInterpolate = function(positions, interp) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultInterpolate = interp; + } else { + edges[pos].interpolate = interp; + } + }); +}; +const updateLink = function(positions, style) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultStyle = style; + } else { + if (_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.isSubstringInArray("fill", style) === -1) { + style.push("fill:none"); + } + edges[pos].style = style; + } + }); +}; +const addClass = function(ids, style) { + ids.split(",").forEach(function(id) { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + if (s.match("color")) { + const newStyle = s.replace("fill", "bgFill").replace("color", "fill"); + classes[id].textStyles.push(newStyle); + } + classes[id].styles.push(s); + }); + } + }); +}; +const setDirection = function(dir) { + direction = dir; + if (direction.match(/.*/)) { + direction = "LR"; + } + if (direction.match(/.*v/)) { + direction = "TB"; + } + if (direction === "TD") { + direction = "TB"; + } +}; +const setClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (vertices[id] !== void 0) { + vertices[id].classes.push(className); + } + if (subGraphLookup[id] !== void 0) { + subGraphLookup[id].classes.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + tooltips[version === "gen-1" ? lookUpDomId(id) : id] = sanitizeText(tooltip); + } + }); +}; +const setClickFun = function(id, functionName, functionArgs) { + let domId = lookUpDomId(id); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(id); + } + if (vertices[id] !== void 0) { + vertices[id].haveCallback = true; + funs.push(function() { + const elem = document.querySelector(`[id="${domId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const setLink = function(ids, linkStr, target) { + ids.split(",").forEach(function(id) { + if (vertices[id] !== void 0) { + vertices[id].link = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + vertices[id].linkTarget = target; + } + }); + setClass(ids, "clickable"); +}; +const getTooltip = function(id) { + if (tooltips.hasOwnProperty(id)) { + return tooltips[id]; + } + return void 0; +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFun(id, functionName, functionArgs); + }); + setClass(ids, "clickable"); +}; +const bindFunctions = function(element) { + funs.forEach(function(fun) { + fun(element); + }); +}; +const getDirection = function() { + return direction.trim(); +}; +const getVertices = function() { + return vertices; +}; +const getEdges = function() { + return edges; +}; +const getClasses = function() { + return classes; +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.top - 14 + document.body.scrollTop + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "
")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + el.classed("hover", false); + }); +}; +funs.push(setupToolTips); +const clear = function(ver = "gen-1") { + vertices = {}; + classes = {}; + edges = []; + funs = [setupToolTips]; + subGraphs = []; + subGraphLookup = {}; + subCount = 0; + tooltips = {}; + firstGraphFlag = true; + version = ver; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.t)(); +}; +const setGen = (ver) => { + version = ver || "gen-2"; +}; +const defaultStyle = function() { + return "fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"; +}; +const addSubGraph = function(_id, list, _title) { + let id = _id.text.trim(); + let title = _title.text; + if (_id === _title && _title.text.match(/\s/)) { + id = void 0; + } + function uniq(a) { + const prims = { boolean: {}, number: {}, string: {} }; + const objs = []; + let dir2; + const nodeList2 = a.filter(function(item) { + const type = typeof item; + if (item.stmt && item.stmt === "dir") { + dir2 = item.value; + return false; + } + if (item.trim() === "") { + return false; + } + if (type in prims) { + return prims[type].hasOwnProperty(item) ? false : prims[type][item] = true; + } else { + return objs.includes(item) ? false : objs.push(item); + } + }); + return { nodeList: nodeList2, dir: dir2 }; + } + let nodeList = []; + const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list)); + nodeList = nl; + if (version === "gen-1") { + for (let i = 0; i < nodeList.length; i++) { + nodeList[i] = lookUpDomId(nodeList[i]); + } + } + id = id || "subGraph" + subCount; + title = title || ""; + title = sanitizeText(title); + subCount = subCount + 1; + const subGraph = { + id, + nodes: nodeList, + title: title.trim(), + classes: [], + dir, + labelType: _title.type + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Adding", subGraph.id, subGraph.nodes, subGraph.dir); + subGraph.nodes = makeUniq(subGraph, subGraphs).nodes; + subGraphs.push(subGraph); + subGraphLookup[id] = subGraph; + return id; +}; +const getPosForId = function(id) { + for (const [i, subGraph] of subGraphs.entries()) { + if (subGraph.id === id) { + return i; + } + } + return -1; +}; +let secCount = -1; +const posCrossRef = []; +const indexNodes2 = function(id, pos) { + const nodes = subGraphs[pos].nodes; + secCount = secCount + 1; + if (secCount > 2e3) { + return; + } + posCrossRef[secCount] = pos; + if (subGraphs[pos].id === id) { + return { + result: true, + count: 0 + }; + } + let count = 0; + let posCount = 1; + while (count < nodes.length) { + const childPos = getPosForId(nodes[count]); + if (childPos >= 0) { + const res = indexNodes2(id, childPos); + if (res.result) { + return { + result: true, + count: posCount + res.count + }; + } else { + posCount = posCount + res.count; + } + } + count = count + 1; + } + return { + result: false, + count: posCount + }; +}; +const getDepthFirstPos = function(pos) { + return posCrossRef[pos]; +}; +const indexNodes = function() { + secCount = -1; + if (subGraphs.length > 0) { + indexNodes2("none", subGraphs.length - 1); + } +}; +const getSubGraphs = function() { + return subGraphs; +}; +const firstGraph = () => { + if (firstGraphFlag) { + firstGraphFlag = false; + return true; + } + return false; +}; +const destructStartLink = (_str) => { + let str = _str.trim(); + let type = "arrow_open"; + switch (str[0]) { + case "<": + type = "arrow_point"; + str = str.slice(1); + break; + case "x": + type = "arrow_cross"; + str = str.slice(1); + break; + case "o": + type = "arrow_circle"; + str = str.slice(1); + break; + } + let stroke = "normal"; + if (str.includes("=")) { + stroke = "thick"; + } + if (str.includes(".")) { + stroke = "dotted"; + } + return { type, stroke }; +}; +const countChar = (char, str) => { + const length = str.length; + let count = 0; + for (let i = 0; i < length; ++i) { + if (str[i] === char) { + ++count; + } + } + return count; +}; +const destructEndLink = (_str) => { + const str = _str.trim(); + let line = str.slice(0, -1); + let type = "arrow_open"; + switch (str.slice(-1)) { + case "x": + type = "arrow_cross"; + if (str[0] === "x") { + type = "double_" + type; + line = line.slice(1); + } + break; + case ">": + type = "arrow_point"; + if (str[0] === "<") { + type = "double_" + type; + line = line.slice(1); + } + break; + case "o": + type = "arrow_circle"; + if (str[0] === "o") { + type = "double_" + type; + line = line.slice(1); + } + break; + } + let stroke = "normal"; + let length = line.length - 1; + if (line[0] === "=") { + stroke = "thick"; + } + if (line[0] === "~") { + stroke = "invisible"; + } + let dots = countChar(".", line); + if (dots) { + stroke = "dotted"; + length = dots; + } + return { type, stroke, length }; +}; +const destructLink = (_str, _startStr) => { + const info = destructEndLink(_str); + let startInfo; + if (_startStr) { + startInfo = destructStartLink(_startStr); + if (startInfo.stroke !== info.stroke) { + return { type: "INVALID", stroke: "INVALID" }; + } + if (startInfo.type === "arrow_open") { + startInfo.type = info.type; + } else { + if (startInfo.type !== info.type) { + return { type: "INVALID", stroke: "INVALID" }; + } + startInfo.type = "double_" + startInfo.type; + } + if (startInfo.type === "double_arrow") { + startInfo.type = "double_arrow_point"; + } + startInfo.length = info.length; + return startInfo; + } + return info; +}; +const exists = (allSgs, _id) => { + let res = false; + allSgs.forEach((sg) => { + const pos = sg.nodes.indexOf(_id); + if (pos >= 0) { + res = true; + } + }); + return res; +}; +const makeUniq = (sg, allSubgraphs) => { + const res = []; + sg.nodes.forEach((_id, pos) => { + if (!exists(allSubgraphs, _id)) { + res.push(sg.nodes[pos]); + } + }); + return { nodes: res }; +}; +const lex = { + firstGraph +}; +const flowDb = { + defaultConfig: () => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.I.flowchart, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.b, + addVertex, + lookUpDomId, + addLink, + updateLinkInterpolate, + updateLink, + addClass, + setDirection, + setClass, + setTooltip, + getTooltip, + setClickEvent, + setLink, + bindFunctions, + getDirection, + getVertices, + getEdges, + getClasses, + clear, + setGen, + defaultStyle, + addSubGraph, + getDepthFirstPos, + indexNodes, + getSubGraphs, + destructLink, + lex, + exists, + makeUniq, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.r +}; +const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addClass, + addLink, + addSingleLink, + addSubGraph, + addVertex, + bindFunctions, + clear, + default: flowDb, + defaultStyle, + destructLink, + firstGraph, + getClasses, + getDepthFirstPos, + getDirection, + getEdges, + getSubGraphs, + getTooltip, + getVertices, + indexNodes, + lex, + lookUpDomId, + setClass, + setClickEvent, + setDirection, + setGen, + setLink, + updateLink, + updateLinkInterpolate +}, Symbol.toStringTag, { value: "Module" })); + + + +/***/ }), + +/***/ 69205: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + diagram: () => (/* binding */ diagram) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/flowDb-1972c806.js +var flowDb_1972c806 = __webpack_require__(75254); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +// EXTERNAL MODULE: ./node_modules/d3/src/index.js + 197 modules +var src = __webpack_require__(64218); +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + 64 modules +var dagre = __webpack_require__(41644); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre-js/util.js +var util = __webpack_require__(96225); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/arrows.js + + + + +var arrows = { + normal, + vee, + undirected, +}; + +function setArrows(value) { + arrows = value; +} + +function normal(parent, id, edge, type) { + var marker = parent + .append('marker') + .attr('id', id) + .attr('viewBox', '0 0 10 10') + .attr('refX', 9) + .attr('refY', 5) + .attr('markerUnits', 'strokeWidth') + .attr('markerWidth', 8) + .attr('markerHeight', 6) + .attr('orient', 'auto'); + + var path = marker + .append('path') + .attr('d', 'M 0 0 L 10 5 L 0 10 z') + .style('stroke-width', 1) + .style('stroke-dasharray', '1,0'); + util/* applyStyle */.bg(path, edge[type + 'Style']); + if (edge[type + 'Class']) { + path.attr('class', edge[type + 'Class']); + } +} + +function vee(parent, id, edge, type) { + var marker = parent + .append('marker') + .attr('id', id) + .attr('viewBox', '0 0 10 10') + .attr('refX', 9) + .attr('refY', 5) + .attr('markerUnits', 'strokeWidth') + .attr('markerWidth', 8) + .attr('markerHeight', 6) + .attr('orient', 'auto'); + + var path = marker + .append('path') + .attr('d', 'M 0 0 L 10 5 L 0 10 L 4 5 z') + .style('stroke-width', 1) + .style('stroke-dasharray', '1,0'); + util/* applyStyle */.bg(path, edge[type + 'Style']); + if (edge[type + 'Class']) { + path.attr('class', edge[type + 'Class']); + } +} + +function undirected(parent, id, edge, type) { + var marker = parent + .append('marker') + .attr('id', id) + .attr('viewBox', '0 0 10 10') + .attr('refX', 9) + .attr('refY', 5) + .attr('markerUnits', 'strokeWidth') + .attr('markerWidth', 8) + .attr('markerHeight', 6) + .attr('orient', 'auto'); + + var path = marker + .append('path') + .attr('d', 'M 0 5 L 10 5') + .style('stroke-width', 1) + .style('stroke-dasharray', '1,0'); + util/* applyStyle */.bg(path, edge[type + 'Style']); + if (edge[type + 'Class']) { + path.attr('class', edge[type + 'Class']); + } +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-html-label.js +var add_html_label = __webpack_require__(43349); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-svg-label.js + + + + +function addSVGLabel(root, node) { + var domNode = root; + + domNode.node().appendChild(node.label); + + util/* applyStyle */.bg(domNode, node.labelStyle); + + return domNode; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-text-label.js + + + + +/* + * Attaches a text label to the specified root. Handles escape sequences. + */ +function addTextLabel(root, node) { + var domNode = root.append('text'); + + var lines = processEscapeSequences(node.label).split('\n'); + for (var i = 0; i < lines.length; i++) { + domNode + .append('tspan') + .attr('xml:space', 'preserve') + .attr('dy', '1em') + .attr('x', '1') + .text(lines[i]); + } + + util/* applyStyle */.bg(domNode, node.labelStyle); + + return domNode; +} + +function processEscapeSequences(text) { + var newText = ''; + var escaped = false; + var ch; + for (var i = 0; i < text.length; ++i) { + ch = text[i]; + if (escaped) { + switch (ch) { + case 'n': + newText += '\n'; + break; + default: + newText += ch; + } + escaped = false; + } else if (ch === '\\') { + escaped = true; + } else { + newText += ch; + } + } + return newText; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-label.js + + + + + + +function addLabel(root, node, location) { + var label = node.label; + var labelSvg = root.append('g'); + + // Allow the label to be a string, a function that returns a DOM element, or + // a DOM element itself. + if (node.labelType === 'svg') { + addSVGLabel(labelSvg, node); + } else if (typeof label !== 'string' || node.labelType === 'html') { + (0,add_html_label/* addHtmlLabel */.a)(labelSvg, node); + } else { + addTextLabel(labelSvg, node); + } + + var labelBBox = labelSvg.node().getBBox(); + var y; + switch (location) { + case 'top': + y = -node.height / 2; + break; + case 'bottom': + y = node.height / 2 - labelBBox.height; + break; + default: + y = -labelBBox.height / 2; + } + labelSvg.attr('transform', 'translate(' + -labelBBox.width / 2 + ',' + y + ')'); + + return labelSvg; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/create-clusters.js + + + + + + +var createClusters = function (selection, g) { + var clusters = g.nodes().filter(function (v) { + return util/* isSubgraph */.bF(g, v); + }); + var svgClusters = selection.selectAll('g.cluster').data(clusters, function (v) { + return v; + }); + + util/* applyTransition */.WR(svgClusters.exit(), g).style('opacity', 0).remove(); + + var enterSelection = svgClusters + .enter() + .append('g') + .attr('class', 'cluster') + .attr('id', function (v) { + var node = g.node(v); + return node.id; + }) + .style('opacity', 0) + .each(function (v) { + var node = g.node(v); + var thisGroup = src/* select */.Ys(this); + src/* select */.Ys(this).append('rect'); + var labelGroup = thisGroup.append('g').attr('class', 'label'); + addLabel(labelGroup, node, node.clusterLabelPos); + }); + + svgClusters = svgClusters.merge(enterSelection); + + svgClusters = util/* applyTransition */.WR(svgClusters, g).style('opacity', 1); + + svgClusters.selectAll('rect').each(function (c) { + var node = g.node(c); + var domCluster = src/* select */.Ys(this); + util/* applyStyle */.bg(domCluster, node.style); + }); + + return svgClusters; +}; + +function setCreateClusters(value) { + createClusters = value; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/create-edge-labels.js + + + + + + + +let createEdgeLabels = function (selection, g) { + var svgEdgeLabels = selection + .selectAll('g.edgeLabel') + .data(g.edges(), function (e) { + return util/* edgeToId */.O1(e); + }) + .classed('update', true); + + svgEdgeLabels.exit().remove(); + svgEdgeLabels.enter().append('g').classed('edgeLabel', true).style('opacity', 0); + + svgEdgeLabels = selection.selectAll('g.edgeLabel'); + + svgEdgeLabels.each(function (e) { + var root = src/* select */.Ys(this); + root.select('.label').remove(); + var edge = g.edge(e); + var label = addLabel(root, g.edge(e), 0).classed('label', true); + var bbox = label.node().getBBox(); + + if (edge.labelId) { + label.attr('id', edge.labelId); + } + if (!has/* default */.Z(edge, 'width')) { + edge.width = bbox.width; + } + if (!has/* default */.Z(edge, 'height')) { + edge.height = bbox.height; + } + }); + + var exitSelection; + + if (svgEdgeLabels.exit) { + exitSelection = svgEdgeLabels.exit(); + } else { + exitSelection = svgEdgeLabels.selectAll(null); // empty selection + } + + util/* applyTransition */.WR(exitSelection, g).style('opacity', 0).remove(); + + return svgEdgeLabels; +}; + +function setCreateEdgeLabels(value) { + createEdgeLabels = value; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-node.js + + +function intersectNode(node, point) { + return node.intersect(point); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/create-edge-paths.js + + + + + + + +var createEdgePaths = function (selection, g, arrows) { + var previousPaths = selection + .selectAll('g.edgePath') + .data(g.edges(), function (e) { + return util/* edgeToId */.O1(e); + }) + .classed('update', true); + + var newPaths = enter(previousPaths, g); + exit(previousPaths, g); + + var svgPaths = previousPaths.merge !== undefined ? previousPaths.merge(newPaths) : previousPaths; + util/* applyTransition */.WR(svgPaths, g).style('opacity', 1); + + // Save DOM element in the path group, and set ID and class + svgPaths.each(function (e) { + var domEdge = src/* select */.Ys(this); + var edge = g.edge(e); + edge.elem = this; + + if (edge.id) { + domEdge.attr('id', edge.id); + } + + util/* applyClass */.$p( + domEdge, + edge['class'], + (domEdge.classed('update') ? 'update ' : '') + 'edgePath' + ); + }); + + svgPaths.selectAll('path.path').each(function (e) { + var edge = g.edge(e); + edge.arrowheadId = uniqueId/* default */.Z('arrowhead'); + + var domEdge = src/* select */.Ys(this) + .attr('marker-end', function () { + return 'url(' + makeFragmentRef(location.href, edge.arrowheadId) + ')'; + }) + .style('fill', 'none'); + + util/* applyTransition */.WR(domEdge, g).attr('d', function (e) { + return calcPoints(g, e); + }); + + util/* applyStyle */.bg(domEdge, edge.style); + }); + + svgPaths.selectAll('defs *').remove(); + svgPaths.selectAll('defs').each(function (e) { + var edge = g.edge(e); + var arrowhead = arrows[edge.arrowhead]; + arrowhead(src/* select */.Ys(this), edge.arrowheadId, edge, 'arrowhead'); + }); + + return svgPaths; +}; + +function setCreateEdgePaths(value) { + createEdgePaths = value; +} + +function makeFragmentRef(url, fragmentId) { + var baseUrl = url.split('#')[0]; + return baseUrl + '#' + fragmentId; +} + +function calcPoints(g, e) { + var edge = g.edge(e); + var tail = g.node(e.v); + var head = g.node(e.w); + var points = edge.points.slice(1, edge.points.length - 1); + points.unshift(intersectNode(tail, points[0])); + points.push(intersectNode(head, points[points.length - 1])); + + return createLine(edge, points); +} + +function createLine(edge, points) { + // @ts-expect-error + var line = (src/* line */.jvg || src/* svg */.YPS.line)() + .x(function (d) { + return d.x; + }) + .y(function (d) { + return d.y; + }); + + (line.curve || line.interpolate)(edge.curve); + + return line(points); +} + +function getCoords(elem) { + var bbox = elem.getBBox(); + var matrix = elem.ownerSVGElement + .getScreenCTM() + .inverse() + .multiply(elem.getScreenCTM()) + .translate(bbox.width / 2, bbox.height / 2); + return { x: matrix.e, y: matrix.f }; +} + +function enter(svgPaths, g) { + var svgPathsEnter = svgPaths.enter().append('g').attr('class', 'edgePath').style('opacity', 0); + svgPathsEnter + .append('path') + .attr('class', 'path') + .attr('d', function (e) { + var edge = g.edge(e); + var sourceElem = g.node(e.v).elem; + var points = range/* default */.Z(edge.points.length).map(function () { + return getCoords(sourceElem); + }); + return createLine(edge, points); + }); + svgPathsEnter.append('defs'); + return svgPathsEnter; +} + +function exit(svgPaths, g) { + var svgPathExit = svgPaths.exit(); + util/* applyTransition */.WR(svgPathExit, g).style('opacity', 0).remove(); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/create-nodes.js + + + + + + + +var createNodes = function (selection, g, shapes) { + var simpleNodes = g.nodes().filter(function (v) { + return !util/* isSubgraph */.bF(g, v); + }); + var svgNodes = selection + .selectAll('g.node') + .data(simpleNodes, function (v) { + return v; + }) + .classed('update', true); + + svgNodes.exit().remove(); + + svgNodes.enter().append('g').attr('class', 'node').style('opacity', 0); + + svgNodes = selection.selectAll('g.node'); + + svgNodes.each(function (v) { + var node = g.node(v); + var thisGroup = src/* select */.Ys(this); + util/* applyClass */.$p( + thisGroup, + node['class'], + (thisGroup.classed('update') ? 'update ' : '') + 'node' + ); + + thisGroup.select('g.label').remove(); + var labelGroup = thisGroup.append('g').attr('class', 'label'); + var labelDom = addLabel(labelGroup, node); + var shape = shapes[node.shape]; + var bbox = pick/* default */.Z(labelDom.node().getBBox(), 'width', 'height'); + + node.elem = this; + + if (node.id) { + thisGroup.attr('id', node.id); + } + if (node.labelId) { + labelGroup.attr('id', node.labelId); + } + + if (has/* default */.Z(node, 'width')) { + bbox.width = node.width; + } + if (has/* default */.Z(node, 'height')) { + bbox.height = node.height; + } + + bbox.width += node.paddingLeft + node.paddingRight; + bbox.height += node.paddingTop + node.paddingBottom; + labelGroup.attr( + 'transform', + 'translate(' + + (node.paddingLeft - node.paddingRight) / 2 + + ',' + + (node.paddingTop - node.paddingBottom) / 2 + + ')' + ); + + var root = src/* select */.Ys(this); + root.select('.label-container').remove(); + var shapeSvg = shape(root, bbox, node).classed('label-container', true); + util/* applyStyle */.bg(shapeSvg, node.style); + + var shapeBBox = shapeSvg.node().getBBox(); + node.width = shapeBBox.width; + node.height = shapeBBox.height; + }); + + var exitSelection; + + if (svgNodes.exit) { + exitSelection = svgNodes.exit(); + } else { + exitSelection = svgNodes.selectAll(null); // empty selection + } + + util/* applyTransition */.WR(exitSelection, g).style('opacity', 0).remove(); + + return svgNodes; +}; + +function setCreateNodes(value) { + createNodes = value; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/position-clusters.js + + + + + +function positionClusters(selection, g) { + var created = selection.filter(function () { + return !src/* select */.Ys(this).classed('update'); + }); + + function translate(v) { + var node = g.node(v); + return 'translate(' + node.x + ',' + node.y + ')'; + } + + created.attr('transform', translate); + + util/* applyTransition */.WR(selection, g).style('opacity', 1).attr('transform', translate); + + util/* applyTransition */.WR(created.selectAll('rect'), g) + .attr('width', function (v) { + return g.node(v).width; + }) + .attr('height', function (v) { + return g.node(v).height; + }) + .attr('x', function (v) { + var node = g.node(v); + return -node.width / 2; + }) + .attr('y', function (v) { + var node = g.node(v); + return -node.height / 2; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/position-edge-labels.js + + + + + + +function positionEdgeLabels(selection, g) { + var created = selection.filter(function () { + return !src/* select */.Ys(this).classed('update'); + }); + + function translate(e) { + var edge = g.edge(e); + return has/* default */.Z(edge, 'x') ? 'translate(' + edge.x + ',' + edge.y + ')' : ''; + } + + created.attr('transform', translate); + + util/* applyTransition */.WR(selection, g).style('opacity', 1).attr('transform', translate); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/position-nodes.js + + + + + +function positionNodes(selection, g) { + var created = selection.filter(function () { + return !src/* select */.Ys(this).classed('update'); + }); + + function translate(v) { + var node = g.node(v); + return 'translate(' + node.x + ',' + node.y + ')'; + } + + created.attr('transform', translate); + + util/* applyTransition */.WR(selection, g).style('opacity', 1).attr('transform', translate); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-ellipse.js + + +function intersectEllipse(node, rx, ry, point) { + // Formulae from: http://mathworld.wolfram.com/Ellipse-LineIntersection.html + + var cx = node.x; + var cy = node.y; + + var px = cx - point.x; + var py = cy - point.y; + + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + + var dx = Math.abs((rx * ry * px) / det); + if (point.x < cx) { + dx = -dx; + } + var dy = Math.abs((rx * ry * py) / det); + if (point.y < cy) { + dy = -dy; + } + + return { x: cx + dx, y: cy + dy }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-circle.js + + + + +function intersectCircle(node, rx, point) { + return intersectEllipse(node, rx, rx, point); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-line.js + + +/* + * Returns the point at which two lines, p and q, intersect or returns + * undefined if they do not intersect. + */ +function intersectLine(p1, p2, q1, q2) { + // Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994, + // p7 and p473. + + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + + // Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x + + // b1 y + c1 = 0. + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + + // Compute r3 and r4. + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + + // Check signs of r3 and r4. If both point 3 and point 4 lie on + // same side of line 1, the line segments do not intersect. + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return /*DONT_INTERSECT*/; + } + + // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0 + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + + // Compute r1 and r2 + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + + // Check signs of r1 and r2. If both point 1 and point 2 lie + // on same side of second line segment, the line segments do + // not intersect. + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return /*DONT_INTERSECT*/; + } + + // Line segments intersect: compute intersection point. + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return /*COLLINEAR*/; + } + + offset = Math.abs(denom / 2); + + // The denom/2 is to get rounding instead of truncating. It + // is added or subtracted to the numerator, depending upon the + // sign of the numerator. + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + + return { x: x, y: y }; +} + +function sameSign(r1, r2) { + return r1 * r2 > 0; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-polygon.js + + + + +/* + * Returns the point ({x, y}) at which the point argument intersects with the + * node argument assuming that it has the shape specified by polygon. + */ +function intersectPolygon(node, polyPoints, point) { + var x1 = node.x; + var y1 = node.y; + + var intersections = []; + + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + polyPoints.forEach(function (entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect = intersectLine( + node, + point, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect) { + intersections.push(intersect); + } + } + + if (!intersections.length) { + console.log('NO INTERSECTION FOUND, RETURN NODE CENTER', node); + return node; + } + + if (intersections.length > 1) { + // More intersections, find the one nearest to edge end point + intersections.sort(function (p, q) { + var pdx = p.x - point.x; + var pdy = p.y - point.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + + var qdx = q.x - point.x; + var qdy = q.y - point.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/intersect/intersect-rect.js + + +function intersectRect(node, point) { + var x = node.x; + var y = node.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = node.width / 2; + var h = node.height / 2; + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/shapes.js + + + + + + + +var shapes = { + rect, + ellipse, + circle, + diamond, +}; + +function setShapes(value) { + shapes = value; +} + +function rect(parent, bbox, node) { + var shapeSvg = parent + .insert('rect', ':first-child') + .attr('rx', node.rx) + .attr('ry', node.ry) + .attr('x', -bbox.width / 2) + .attr('y', -bbox.height / 2) + .attr('width', bbox.width) + .attr('height', bbox.height); + + node.intersect = function (point) { + return intersectRect(node, point); + }; + + return shapeSvg; +} + +function ellipse(parent, bbox, node) { + var rx = bbox.width / 2; + var ry = bbox.height / 2; + var shapeSvg = parent + .insert('ellipse', ':first-child') + .attr('x', -bbox.width / 2) + .attr('y', -bbox.height / 2) + .attr('rx', rx) + .attr('ry', ry); + + node.intersect = function (point) { + return intersectEllipse(node, rx, ry, point); + }; + + return shapeSvg; +} + +function circle(parent, bbox, node) { + var r = Math.max(bbox.width, bbox.height) / 2; + var shapeSvg = parent + .insert('circle', ':first-child') + .attr('x', -bbox.width / 2) + .attr('y', -bbox.height / 2) + .attr('r', r); + + node.intersect = function (point) { + return intersectCircle(node, r, point); + }; + + return shapeSvg; +} + +// Circumscribe an ellipse for the bounding box with a diamond shape. I derived +// the function to calculate the diamond shape from: +// http://mathforum.org/kb/message.jspa?messageID=3750236 +function diamond(parent, bbox, node) { + var w = (bbox.width * Math.SQRT2) / 2; + var h = (bbox.height * Math.SQRT2) / 2; + var points = [ + { x: 0, y: -h }, + { x: -w, y: 0 }, + { x: 0, y: h }, + { x: w, y: 0 }, + ]; + var shapeSvg = parent.insert('polygon', ':first-child').attr( + 'points', + points + .map(function (p) { + return p.x + ',' + p.y; + }) + .join(' ') + ); + + node.intersect = function (p) { + return intersectPolygon(node, points, p); + }; + + return shapeSvg; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre-js/render.js + + + + + + + + + + + + + + + +// This design is based on http://bost.ocks.org/mike/chart/. +function render() { + var fn = function (svg, g) { + preProcessGraph(g); + + var outputGroup = createOrSelectGroup(svg, 'output'); + var clustersGroup = createOrSelectGroup(outputGroup, 'clusters'); + var edgePathsGroup = createOrSelectGroup(outputGroup, 'edgePaths'); + var edgeLabels = createEdgeLabels(createOrSelectGroup(outputGroup, 'edgeLabels'), g); + var nodes = createNodes(createOrSelectGroup(outputGroup, 'nodes'), g, shapes); + + (0,dagre/* layout */.bK)(g); + + positionNodes(nodes, g); + positionEdgeLabels(edgeLabels, g); + createEdgePaths(edgePathsGroup, g, arrows); + + var clusters = createClusters(clustersGroup, g); + positionClusters(clusters, g); + + postProcessGraph(g); + }; + + fn.createNodes = function (value) { + if (!arguments.length) return createNodes; + setCreateNodes(value); + return fn; + }; + + fn.createClusters = function (value) { + if (!arguments.length) return createClusters; + setCreateClusters(value); + return fn; + }; + + fn.createEdgeLabels = function (value) { + if (!arguments.length) return createEdgeLabels; + setCreateEdgeLabels(value); + return fn; + }; + + fn.createEdgePaths = function (value) { + if (!arguments.length) return createEdgePaths; + setCreateEdgePaths(value); + return fn; + }; + + fn.shapes = function (value) { + if (!arguments.length) return shapes; + setShapes(value); + return fn; + }; + + fn.arrows = function (value) { + if (!arguments.length) return arrows; + setArrows(value); + return fn; + }; + + return fn; +} + +var NODE_DEFAULT_ATTRS = { + paddingLeft: 10, + paddingRight: 10, + paddingTop: 10, + paddingBottom: 10, + rx: 0, + ry: 0, + shape: 'rect', +}; + +var EDGE_DEFAULT_ATTRS = { + arrowhead: 'normal', + curve: src/* curveLinear */.c_6, +}; + +function preProcessGraph(g) { + g.nodes().forEach(function (v) { + var node = g.node(v); + if (!has/* default */.Z(node, 'label') && !g.children(v).length) { + node.label = v; + } + + if (has/* default */.Z(node, 'paddingX')) { + defaults/* default */.Z(node, { + paddingLeft: node.paddingX, + paddingRight: node.paddingX, + }); + } + + if (has/* default */.Z(node, 'paddingY')) { + defaults/* default */.Z(node, { + paddingTop: node.paddingY, + paddingBottom: node.paddingY, + }); + } + + if (has/* default */.Z(node, 'padding')) { + defaults/* default */.Z(node, { + paddingLeft: node.padding, + paddingRight: node.padding, + paddingTop: node.padding, + paddingBottom: node.padding, + }); + } + + defaults/* default */.Z(node, NODE_DEFAULT_ATTRS); + + forEach/* default */.Z(['paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom'], function (k) { + node[k] = Number(node[k]); + }); + + // Save dimensions for restore during post-processing + if (has/* default */.Z(node, 'width')) { + node._prevWidth = node.width; + } + if (has/* default */.Z(node, 'height')) { + node._prevHeight = node.height; + } + }); + + g.edges().forEach(function (e) { + var edge = g.edge(e); + if (!has/* default */.Z(edge, 'label')) { + edge.label = ''; + } + defaults/* default */.Z(edge, EDGE_DEFAULT_ATTRS); + }); +} + +function postProcessGraph(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + + // Restore original dimensions + if (has/* default */.Z(node, '_prevWidth')) { + node.width = node._prevWidth; + } else { + delete node.width; + } + + if (has/* default */.Z(node, '_prevHeight')) { + node.height = node._prevHeight; + } else { + delete node.height; + } + + delete node._prevWidth; + delete node._prevHeight; + }); +} + +function createOrSelectGroup(root, name) { + var selection = root.select('g.' + name); + if (selection.empty()) { + selection = root.append('g').attr('class', name); + } + return selection; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/index.js + + + + + + + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/styles-080da4f6.js + 1 modules +var styles_080da4f6 = __webpack_require__(38621); +// EXTERNAL MODULE: ./node_modules/dayjs/dayjs.min.js +var dayjs_min = __webpack_require__(27484); +// EXTERNAL MODULE: ./node_modules/@braintree/sanitize-url/dist/index.js +var dist = __webpack_require__(17967); +// EXTERNAL MODULE: ./node_modules/dompurify/dist/purify.es.js +var purify_es = __webpack_require__(20683); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/json.js + 1 modules +var json = __webpack_require__(39354); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/flowDiagram-7ea5b25a.js + + + + + + + + + + + + + + + + + + + + + + + + + +function question(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const s = (w + h) * 0.9; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + const shapeSvg = insertPolygonShape(parent, s, s, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function hexagon(parent, bbox, node) { + const f = 4; + const h = bbox.height; + const m = h / f; + const w = bbox.width + 2 * m; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function rect_left_inv_arrow(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function lean_right(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function lean_left(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function trapezoid(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function inv_trapezoid(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function rect_right_inv_arrow(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function stadium(parent, bbox, node) { + const h = bbox.height; + const w = bbox.width + h / 4; + const shapeSvg = parent.insert("rect", ":first-child").attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + node.intersect = function(point) { + return intersectRect(node, point); + }; + return shapeSvg; +} +function subroutine(parent, bbox, node) { + const w = bbox.width; + const h = bbox.height; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const shapeSvg = insertPolygonShape(parent, w, h, points); + node.intersect = function(point) { + return intersectPolygon(node, points, point); + }; + return shapeSvg; +} +function cylinder(parent, bbox, node) { + const w = bbox.width; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const shapeSvg = parent.attr("label-offset-y", ry).insert("path", ":first-child").attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + node.intersect = function(point) { + const pos = intersectRect(node, point); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +} +function addToRender(render2) { + render2.shapes().question = question; + render2.shapes().hexagon = hexagon; + render2.shapes().stadium = stadium; + render2.shapes().subroutine = subroutine; + render2.shapes().cylinder = cylinder; + render2.shapes().rect_left_inv_arrow = rect_left_inv_arrow; + render2.shapes().lean_right = lean_right; + render2.shapes().lean_left = lean_left; + render2.shapes().trapezoid = trapezoid; + render2.shapes().inv_trapezoid = inv_trapezoid; + render2.shapes().rect_right_inv_arrow = rect_right_inv_arrow; +} +function addToRenderV2(addShape) { + addShape({ question }); + addShape({ hexagon }); + addShape({ stadium }); + addShape({ subroutine }); + addShape({ cylinder }); + addShape({ rect_left_inv_arrow }); + addShape({ lean_right }); + addShape({ lean_left }); + addShape({ trapezoid }); + addShape({ inv_trapezoid }); + addShape({ rect_right_inv_arrow }); +} +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +const flowChartShapes = { + addToRender, + addToRenderV2 +}; +const conf = {}; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + conf[key] = cnf[key]; + } +}; +const addVertices = function(vert, g, svgId, root, _doc, diagObj) { + const svg = !root ? (0,src/* select */.Ys)(`[id="${svgId}"]`) : root.select(`[id="${svgId}"]`); + const doc = !_doc ? document : _doc; + const keys = Object.keys(vert); + keys.forEach(function(id) { + const vertex = vert[id]; + let classStr = "default"; + if (vertex.classes.length > 0) { + classStr = vertex.classes.join(" "); + } + const styles = (0,mermaid_8af3addd.k)(vertex.styles); + let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; + let vertexNode; + if ((0,mermaid_8af3addd.m)((0,mermaid_8af3addd.c)().flowchart.htmlLabels)) { + const node = { + label: vertexText.replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ) + }; + vertexNode = (0,add_html_label/* addHtmlLabel */.a)(svg, node).node(); + vertexNode.parentNode.removeChild(vertexNode); + } else { + const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:")); + const rows = vertexText.split(mermaid_8af3addd.e.lineBreakRegex); + for (const row of rows) { + const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "1"); + tspan.textContent = row; + svgLabel.appendChild(tspan); + } + vertexNode = svgLabel; + } + let radious = 0; + let _shape = ""; + switch (vertex.type) { + case "round": + radious = 5; + _shape = "rect"; + break; + case "square": + _shape = "rect"; + break; + case "diamond": + _shape = "question"; + break; + case "hexagon": + _shape = "hexagon"; + break; + case "odd": + _shape = "rect_left_inv_arrow"; + break; + case "lean_right": + _shape = "lean_right"; + break; + case "lean_left": + _shape = "lean_left"; + break; + case "trapezoid": + _shape = "trapezoid"; + break; + case "inv_trapezoid": + _shape = "inv_trapezoid"; + break; + case "odd_right": + _shape = "rect_left_inv_arrow"; + break; + case "circle": + _shape = "circle"; + break; + case "ellipse": + _shape = "ellipse"; + break; + case "stadium": + _shape = "stadium"; + break; + case "subroutine": + _shape = "subroutine"; + break; + case "cylinder": + _shape = "cylinder"; + break; + case "group": + _shape = "rect"; + break; + default: + _shape = "rect"; + } + mermaid_8af3addd.l.warn("Adding node", vertex.id, vertex.domId); + g.setNode(diagObj.db.lookUpDomId(vertex.id), { + labelType: "svg", + labelStyle: styles.labelStyle, + shape: _shape, + label: vertexNode, + rx: radious, + ry: radious, + class: classStr, + style: styles.style, + id: diagObj.db.lookUpDomId(vertex.id) + }); + }); +}; +const addEdges = function(edges, g, diagObj) { + let cnt = 0; + let defaultStyle; + let defaultLabelStyle; + if (edges.defaultStyle !== void 0) { + const defaultStyles = (0,mermaid_8af3addd.k)(edges.defaultStyle); + defaultStyle = defaultStyles.style; + defaultLabelStyle = defaultStyles.labelStyle; + } + edges.forEach(function(edge) { + cnt++; + const linkId = "L-" + edge.start + "-" + edge.end; + const linkNameStart = "LS-" + edge.start; + const linkNameEnd = "LE-" + edge.end; + const edgeData = {}; + if (edge.type === "arrow_open") { + edgeData.arrowhead = "none"; + } else { + edgeData.arrowhead = "normal"; + } + let style = ""; + let labelStyle = ""; + if (edge.style !== void 0) { + const styles = (0,mermaid_8af3addd.k)(edge.style); + style = styles.style; + labelStyle = styles.labelStyle; + } else { + switch (edge.stroke) { + case "normal": + style = "fill:none"; + if (defaultStyle !== void 0) { + style = defaultStyle; + } + if (defaultLabelStyle !== void 0) { + labelStyle = defaultLabelStyle; + } + break; + case "dotted": + style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; + break; + case "thick": + style = " stroke-width: 3.5px;fill:none"; + break; + } + } + edgeData.style = style; + edgeData.labelStyle = labelStyle; + if (edge.interpolate !== void 0) { + edgeData.curve = (0,mermaid_8af3addd.n)(edge.interpolate, src/* curveLinear */.c_6); + } else if (edges.defaultInterpolate !== void 0) { + edgeData.curve = (0,mermaid_8af3addd.n)(edges.defaultInterpolate, src/* curveLinear */.c_6); + } else { + edgeData.curve = (0,mermaid_8af3addd.n)(conf.curve, src/* curveLinear */.c_6); + } + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + if ((0,mermaid_8af3addd.m)((0,mermaid_8af3addd.c)().flowchart.htmlLabels)) { + edgeData.labelType = "html"; + edgeData.label = `${edge.text.replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + )}`; + } else { + edgeData.labelType = "text"; + edgeData.label = edge.text.replace(mermaid_8af3addd.e.lineBreakRegex, "\n"); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + } + } + edgeData.id = linkId; + edgeData.class = linkNameStart + " " + linkNameEnd; + edgeData.minlen = edge.length || 1; + g.setEdge(diagObj.db.lookUpDomId(edge.start), diagObj.db.lookUpDomId(edge.end), edgeData, cnt); + }); +}; +const getClasses = function(text, diagObj) { + mermaid_8af3addd.l.info("Extracting classes"); + return diagObj.db.getClasses(); +}; +const draw = function(text, id, _version, diagObj) { + mermaid_8af3addd.l.info("Drawing flowchart"); + const { securityLevel, flowchart: conf2 } = (0,mermaid_8af3addd.c)(); + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,src/* select */.Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,src/* select */.Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,src/* select */.Ys)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + let dir = diagObj.db.getDirection(); + if (dir === void 0) { + dir = "TD"; + } + const nodeSpacing = conf2.nodeSpacing || 50; + const rankSpacing = conf2.rankSpacing || 50; + const g = new graphlib/* Graph */.k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + let subG; + const subGraphs = diagObj.db.getSubGraphs(); + for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) { + subG = subGraphs[i2]; + diagObj.db.addVertex(subG.id, subG.title, "group", void 0, subG.classes); + } + const vert = diagObj.db.getVertices(); + mermaid_8af3addd.l.warn("Get vertices", vert); + const edges = diagObj.db.getEdges(); + let i = 0; + for (i = subGraphs.length - 1; i >= 0; i--) { + subG = subGraphs[i]; + (0,src/* selectAll */.td_)("cluster").append("text"); + for (let j = 0; j < subG.nodes.length; j++) { + mermaid_8af3addd.l.warn( + "Setting subgraph", + subG.nodes[j], + diagObj.db.lookUpDomId(subG.nodes[j]), + diagObj.db.lookUpDomId(subG.id) + ); + g.setParent(diagObj.db.lookUpDomId(subG.nodes[j]), diagObj.db.lookUpDomId(subG.id)); + } + } + addVertices(vert, g, id, root, doc, diagObj); + addEdges(edges, g, diagObj); + const render$1 = new render(); + flowChartShapes.addToRender(render$1); + render$1.arrows().none = function normal(parent, id2, edge, type) { + const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto"); + const path = marker.append("path").attr("d", "M 0 0 L 0 0 L 0 0 z"); + (0,util/* applyStyle */.bg)(path, edge[type + "Style"]); + }; + render$1.arrows().normal = function normal(parent, id2) { + const marker = parent.append("marker").attr("id", id2).attr("viewBox", "0 0 10 10").attr("refX", 9).attr("refY", 5).attr("markerUnits", "strokeWidth").attr("markerWidth", 8).attr("markerHeight", 6).attr("orient", "auto"); + marker.append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowheadPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + }; + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + render$1(element, g); + element.selectAll("g.node").attr("title", function() { + return diagObj.db.getTooltip(this.id); + }); + diagObj.db.indexNodes("subGraph" + i); + for (i = 0; i < subGraphs.length; i++) { + subG = subGraphs[i]; + if (subG.title !== "undefined") { + const clusterRects = doc.querySelectorAll( + "#" + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"] rect' + ); + const clusterEl = doc.querySelectorAll( + "#" + id + ' [id="' + diagObj.db.lookUpDomId(subG.id) + '"]' + ); + const xPos = clusterRects[0].x.baseVal.value; + const yPos = clusterRects[0].y.baseVal.value; + const _width = clusterRects[0].width.baseVal.value; + const cluster = (0,src/* select */.Ys)(clusterEl[0]); + const te = cluster.select(".label"); + te.attr("transform", `translate(${xPos + _width / 2}, ${yPos + 14})`); + te.attr("id", id + "Text"); + for (let j = 0; j < subG.classes.length; j++) { + clusterEl[0].classList.add(subG.classes[j]); + } + } + } + if (!conf2.htmlLabels) { + const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } + } + (0,mermaid_8af3addd.o)(g, svg, conf2.diagramPadding, conf2.useMaxWidth); + const keys = Object.keys(vert); + keys.forEach(function(key) { + const vertex = vert[key]; + if (vertex.link) { + const node = root.select("#" + id + ' [id="' + diagObj.db.lookUpDomId(key) + '"]'); + if (node) { + const link = doc.createElementNS("http://www.w3.org/2000/svg", "a"); + link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" ")); + link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link); + link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener"); + if (securityLevel === "sandbox") { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top"); + } else if (vertex.linkTarget) { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget); + } + const linkNode = node.insert(function() { + return link; + }, ":first-child"); + const shape = node.select(".label-container"); + if (shape) { + linkNode.append(function() { + return shape.node(); + }); + } + const label = node.select(".label"); + if (label) { + linkNode.append(function() { + return label.node(); + }); + } + } + } + }); +}; +const flowRenderer = { + setConf, + addVertices, + addEdges, + getClasses, + draw +}; +const diagram = { + parser: flowDb_1972c806.p, + db: flowDb_1972c806.f, + renderer: styles_080da4f6.f, + styles: styles_080da4f6.a, + init: (cnf) => { + if (!cnf.flowchart) { + cnf.flowchart = {}; + } + cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + flowRenderer.setConf(cnf.flowchart); + flowDb_1972c806.f.clear(); + flowDb_1972c806.f.setGen("gen-1"); + } +}; + + + +/***/ }), + +/***/ 90360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ r: () => (/* binding */ render) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39354); +/* harmony import */ var _edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(27707); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(45625); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(64589); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(64218); + + + + + + + +let clusterDb = {}; +let descendants = {}; +let parents = {}; +const clear$1 = () => { + descendants = {}; + parents = {}; + clusterDb = {}; +}; +const isDescendant = (id, ancenstorId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("In isDecendant", ancenstorId, " ", id, " = ", descendants[ancenstorId].includes(id)); + if (descendants[ancenstorId].includes(id)) { + return true; + } + return false; +}; +const edgeInCluster = (edge, clusterId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Decendants of ", clusterId, " is ", descendants[clusterId]); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge is ", edge); + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } + if (!descendants[clusterId]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Tilt, ", clusterId, ",not in decendants"); + return false; + } + return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w); +}; +const copy = (clusterId, graph, newGraph, rootId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Copying children of ", + clusterId, + "root", + rootId, + "data", + graph.node(clusterId), + rootId + ); + const nodes = graph.children(clusterId) || []; + if (clusterId !== rootId) { + nodes.push(clusterId); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes); + nodes.forEach((node) => { + if (graph.children(node).length > 0) { + copy(node, graph, newGraph, rootId); + } else { + const data = graph.node(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("cp ", node, " to ", rootId, " with parent ", clusterId); + newGraph.setNode(node, data); + if (rootId !== graph.parent(node)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Setting parent", node, graph.parent(node)); + newGraph.setParent(node, graph.parent(node)); + } + if (clusterId !== rootId && node !== clusterId) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Setting parent", node, clusterId); + newGraph.setParent(node, clusterId); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Not Setting parent for node=", + node, + "cluster!==rootId", + clusterId !== rootId, + "node!==clusterId", + node !== clusterId + ); + } + const edges = graph.edges(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Copying Edges", edges); + edges.forEach((edge) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge", edge); + const data2 = graph.edge(edge.v, edge.w, edge.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge data", data2, rootId); + try { + if (edgeInCluster(edge, rootId)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Copying as ", edge.v, edge.w, data2, edge.name); + newGraph.setEdge(edge.v, edge.w, data2, edge.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0])); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Skipping copy of edge ", + edge.v, + "-->", + edge.w, + " rootId: ", + rootId, + " clusterId:", + clusterId + ); + } + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error(e); + } + }); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Removing node", node); + graph.removeNode(node); + }); +}; +const extractDescendants = (id, graph) => { + const children = graph.children(id); + let res = [...children]; + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; + } + return res; +}; +const findNonClusterChild = (id, graph) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching", id); + const children = graph.children(id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching children of id ", id, children); + if (children.length < 1) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("This is a valid node", id); + return id; + } + for (const child of children) { + const _id = findNonClusterChild(child, graph); + if (_id) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Found replacement for", id, " => ", _id); + return _id; + } + } +}; +const getAnchorId = (id) => { + if (!clusterDb[id]) { + return id; + } + if (!clusterDb[id].externalConnections) { + return id; + } + if (clusterDb[id]) { + return clusterDb[id].id; + } + return id; +}; +const adjustClustersAndEdges = (graph, depth) => { + if (!graph || depth > 10) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting out, no graph "); + return; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting in, graph "); + } + graph.nodes().forEach(function(id) { + const children = graph.children(id); + if (children.length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster identified", + id, + " Replacement id in edges: ", + findNonClusterChild(id, graph) + ); + descendants[id] = extractDescendants(id, graph); + clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; + } + }); + graph.nodes().forEach(function(id) { + const children = graph.children(id); + const edges = graph.edges(); + if (children.length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Cluster identified", id, descendants); + edges.forEach((edge) => { + if (edge.v !== id && edge.w !== id) { + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); + if (d1 ^ d2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge: ", edge, " leaves cluster ", id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Decendants of XXX ", id, ": ", descendants[id]); + clusterDb[id].externalConnections = true; + } + } + }); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster ", id, descendants); + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + let v = e.v; + let w = e.w; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Fix XXX", + clusterDb, + "ids:", + e.v, + e.w, + "Translating: ", + clusterDb[e.v], + " --- ", + clusterDb[e.w] + ); + if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + const specialId = e.w + "---" + e.v; + graph.setNode(specialId, { + domId: specialId, + id: specialId, + labelStyle: "", + labelText: edge.label, + padding: 0, + shape: "labelRect", + style: "" + }); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); + edge1.label = ""; + edge1.arrowTypeEnd = "none"; + edge2.label = ""; + edge1.fromCluster = e.v; + edge2.toCluster = e.v; + graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special"); + graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special"); + } else if (clusterDb[e.v] || clusterDb[e.w]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + if (v !== e.v) { + edge.fromCluster = e.v; + } + if (w !== e.w) { + edge.toCluster = e.w; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fix Replacing with XXX", v, w, e.name); + graph.setEdge(v, w, edge, e.name); + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Adjusted Graph", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + extractor(graph, 0); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace(clusterDb); +}; +const extractor = (graph, depth) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("extractor - ", depth, dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph), graph.children("D")); + if (depth > 10) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("Bailing out"); + return; + } + let nodes = graph.nodes(); + let hasChildren = false; + for (const node of nodes) { + const children = graph.children(node); + hasChildren = hasChildren || children.length > 0; + } + if (!hasChildren) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Done, no node has children", graph.nodes()); + return; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Nodes = ", nodes, depth); + for (const node of nodes) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Extracting node", + node, + clusterDb, + clusterDb[node] && !clusterDb[node].externalConnections, + !graph.parent(node), + graph.node(node), + graph.children("D"), + " Depth ", + depth + ); + if (!clusterDb[node]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster", node, depth); + } else if (!clusterDb[node].externalConnections && // !graph.parent(node) && + graph.children(node) && graph.children(node).length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster without external connections, without a parent and with children", + node, + depth + ); + const graphSettings = graph.graph(); + let dir = graphSettings.rankdir === "TB" ? "LR" : "TB"; + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing dir", clusterDb[node].clusterData.dir, dir); + } + const clusterGraph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + // Todo: set proper spacing + nodesep: 50, + ranksep: 50, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Old graph before copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + copy(node, graph, clusterGraph, node); + graph.setNode(node, { + clusterNode: true, + id: node, + clusterData: clusterDb[node].clusterData, + labelText: clusterDb[node].labelText, + graph: clusterGraph + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New graph after copy node: (", node, ")", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(clusterGraph)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Old graph after copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster ** ", + node, + " **not meeting the criteria !externalConnections:", + !clusterDb[node].externalConnections, + " no parent: ", + !graph.parent(node), + " children ", + graph.children(node) && graph.children(node).length > 0, + graph.children("D"), + depth + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(clusterDb); + } + } + nodes = graph.nodes(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New list of nodes", nodes); + for (const node of nodes) { + const data = graph.node(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn(" Now next level", node, data); + if (data.clusterNode) { + extractor(data.graph, depth + 1); + } + } +}; +const sorter = (graph, nodes) => { + if (nodes.length === 0) { + return []; + } + let result = Object.assign(nodes); + nodes.forEach((node) => { + const children = graph.children(node); + const sorted = sorter(graph, children); + result = [...result, ...sorted]; + }); + return result; +}; +const sortNodesByHierarchy = (graph) => sorter(graph, graph.children()); +const rect = (parent, node) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Creating subgraph rect for ", node.id, node); + const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const text = node.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_5__.a)(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild((0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width; + if (node.width <= bbox.width + padding) { + node.diff = (bbox.width - node.width) / 2 - node.padding / 2; + } else { + node.diff = -node.padding / 2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Data ", node, JSON.stringify(node)); + rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding); + if (useHtmlLabels) { + label.attr( + "transform", + // This puts the labal on top of the box instead of inside it + "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2) + ")" + ); + } else { + label.attr( + "transform", + // This puts the labal on top of the box instead of inside it + "translate(" + node.x + ", " + (node.y - node.height / 2) + ")" + ); + } + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const noteGroup = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none"); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const roundedWithTitle = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const innerRect = shapeSvg.append("rect"); + const text = label.node().appendChild((0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + bbox = text.getBBox(); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (bbox.width + node.padding * 0 - node.width) / 2; + } else { + node.diff = -node.padding / 2; + } + rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding); + innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3); + label.attr( + "transform", + "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2 - node.padding / 3 + ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels) ? 5 : 3)) + ")" + ); + const rectBox = rect2.node().getBBox(); + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const divider = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.diff = -node.padding / 2; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const shapes = { rect, roundedWithTitle, noteGroup, divider }; +let clusterElems = {}; +const insertCluster = (elem, node) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Inserting cluster"); + const shape = node.shape || "rect"; + clusterElems[node.id] = shapes[shape](elem, node); +}; +const clear = () => { + clusterElems = {}; +}; +const recursiveRender = async (_elem, graph, diagramtype, id, parentCluster) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph in recursive render: XXX", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph), parentCluster); + const dir = graph.graph().rankdir; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Dir in recursive render - dir:", dir); + const elem = _elem.insert("g").attr("class", "root"); + if (!graph.nodes()) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("No nodes found for", graph); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Recursive render XXX", graph.nodes()); + } + if (graph.edges().length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Recursive edges", graph.edge(graph.edges()[0])); + } + const clusters = elem.insert("g").attr("class", "clusters"); + const edgePaths = elem.insert("g").attr("class", "edgePaths"); + const edgeLabels = elem.insert("g").attr("class", "edgeLabels"); + const nodes = elem.insert("g").attr("class", "nodes"); + await Promise.all( + graph.nodes().map(async function(v) { + const node = graph.node(v); + if (parentCluster !== void 0) { + const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Setting data for cluster XXX (", v, ") ", data, parentCluster); + graph.setNode(parentCluster.id, data); + if (!graph.parent(v)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Setting parent", v, parentCluster.id); + graph.setParent(v, parentCluster.id, data); + } + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v))); + if (node && node.clusterNode) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster identified", v, node.width, graph.node(v)); + const o = await recursiveRender(nodes, node.graph, diagramtype, id, graph.node(v)); + const newEl = o.elem; + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.u)(node, newEl); + node.diff = o.diff || 0; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node bounds (abc123)", v, node, node.width, node.x, node.y); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.s)(newEl, node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Recursive render complete ", newEl, node); + } else { + if (graph.children(v).length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster - the non recursive path XXX", v, node.id, node, graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(findNonClusterChild(node.id, graph)); + clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node - the non recursive path", v, node.id, node); + await (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, graph.node(v), dir); + } + } + }) + ); + graph.edges().forEach(function(e) { + const edge = graph.edge(e.v, e.w, e.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e))); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Fix", clusterDb, "ids:", e.v, e.w, "Translateing: ", clusterDb[e.v], clusterDb[e.w]); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.f)(edgeLabels, edge); + }); + graph.edges().forEach(function(e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("### Layout ###"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(graph); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__/* .layout */ .bK)(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph after layout:", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + let diff = 0; + sortNodesByHierarchy(graph).forEach(function(v) { + const node = graph.node(v); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Position " + v + ": " + JSON.stringify(graph.node(v))); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Position " + v + ": (" + node.x, + "," + node.y, + ") width: ", + node.width, + " height: ", + node.height + ); + if (node && node.clusterNode) { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } else { + if (graph.children(v).length > 0) { + insertCluster(clusters, node); + clusterDb[node.id].node = node; + } else { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge); + const paths = (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.g)(edgePaths, e, edge, clusterDb, diagramtype, graph, id); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.h)(edge, paths); + }); + graph.nodes().forEach(function(v) { + const n = graph.node(v); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(v, n.type, n.diff); + if (n.type === "group") { + diff = n.diff; + } + }); + return { elem, diff }; +}; +const render = async (elem, graph, markers, diagramtype, id) => { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.a)(elem, markers, diagramtype, id); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.b)(); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.d)(); + clear(); + clear$1(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph at first:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph))); + adjustClustersAndEdges(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph after:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph))); + await recursiveRender(elem, graph, diagramtype, id); +}; + + + +/***/ }), + +/***/ 38621: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ flowStyles), + f: () => (/* binding */ flowRendererV2) +}); + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +// EXTERNAL MODULE: ./node_modules/d3/src/index.js + 197 modules +var src = __webpack_require__(64218); +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +// EXTERNAL MODULE: ./node_modules/mermaid/dist/index-2c4b9a3b.js +var index_2c4b9a3b = __webpack_require__(90360); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-html-label.js +var add_html_label = __webpack_require__(43349); +// EXTERNAL MODULE: ./node_modules/khroma/dist/utils/index.js + 3 modules +var utils = __webpack_require__(61691); +// EXTERNAL MODULE: ./node_modules/khroma/dist/color/index.js + 4 modules +var dist_color = __webpack_require__(71610); +;// CONCATENATED MODULE: ./node_modules/khroma/dist/methods/channel.js +/* IMPORT */ + + +/* MAIN */ +const channel = (color, channel) => { + return utils/* default */.Z.lang.round(dist_color/* default */.Z.parse(color)[channel]); +}; +/* EXPORT */ +/* harmony default export */ const methods_channel = (channel); + +// EXTERNAL MODULE: ./node_modules/khroma/dist/methods/rgba.js +var rgba = __webpack_require__(51117); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/styles-080da4f6.js + + + + + + +const conf = {}; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + conf[key] = cnf[key]; + } +}; +const addVertices = function(vert, g, svgId, root, doc, diagObj) { + const svg = root.select(`[id="${svgId}"]`); + const keys = Object.keys(vert); + keys.forEach(function(id) { + const vertex = vert[id]; + let classStr = "default"; + if (vertex.classes.length > 0) { + classStr = vertex.classes.join(" "); + } + classStr = classStr + " flowchart-label"; + const styles = (0,mermaid_8af3addd.k)(vertex.styles); + let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; + let vertexNode; + mermaid_8af3addd.l.info("vertex", vertex, vertex.labelType); + if (vertex.labelType === "markdown") { + mermaid_8af3addd.l.info("vertex", vertex, vertex.labelType); + } else { + if ((0,mermaid_8af3addd.m)((0,mermaid_8af3addd.c)().flowchart.htmlLabels)) { + const node = { + label: vertexText.replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ) + }; + vertexNode = (0,add_html_label/* addHtmlLabel */.a)(svg, node).node(); + vertexNode.parentNode.removeChild(vertexNode); + } else { + const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:")); + const rows = vertexText.split(mermaid_8af3addd.e.lineBreakRegex); + for (const row of rows) { + const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "1"); + tspan.textContent = row; + svgLabel.appendChild(tspan); + } + vertexNode = svgLabel; + } + } + let radious = 0; + let _shape = ""; + switch (vertex.type) { + case "round": + radious = 5; + _shape = "rect"; + break; + case "square": + _shape = "rect"; + break; + case "diamond": + _shape = "question"; + break; + case "hexagon": + _shape = "hexagon"; + break; + case "odd": + _shape = "rect_left_inv_arrow"; + break; + case "lean_right": + _shape = "lean_right"; + break; + case "lean_left": + _shape = "lean_left"; + break; + case "trapezoid": + _shape = "trapezoid"; + break; + case "inv_trapezoid": + _shape = "inv_trapezoid"; + break; + case "odd_right": + _shape = "rect_left_inv_arrow"; + break; + case "circle": + _shape = "circle"; + break; + case "ellipse": + _shape = "ellipse"; + break; + case "stadium": + _shape = "stadium"; + break; + case "subroutine": + _shape = "subroutine"; + break; + case "cylinder": + _shape = "cylinder"; + break; + case "group": + _shape = "rect"; + break; + case "doublecircle": + _shape = "doublecircle"; + break; + default: + _shape = "rect"; + } + g.setNode(vertex.id, { + labelStyle: styles.labelStyle, + shape: _shape, + labelText: vertexText, + labelType: vertex.labelType, + rx: radious, + ry: radious, + class: classStr, + style: styles.style, + id: vertex.id, + link: vertex.link, + linkTarget: vertex.linkTarget, + tooltip: diagObj.db.getTooltip(vertex.id) || "", + domId: diagObj.db.lookUpDomId(vertex.id), + haveCallback: vertex.haveCallback, + width: vertex.type === "group" ? 500 : void 0, + dir: vertex.dir, + type: vertex.type, + props: vertex.props, + padding: (0,mermaid_8af3addd.c)().flowchart.padding + }); + mermaid_8af3addd.l.info("setNode", { + labelStyle: styles.labelStyle, + labelType: vertex.labelType, + shape: _shape, + labelText: vertexText, + rx: radious, + ry: radious, + class: classStr, + style: styles.style, + id: vertex.id, + domId: diagObj.db.lookUpDomId(vertex.id), + width: vertex.type === "group" ? 500 : void 0, + type: vertex.type, + dir: vertex.dir, + props: vertex.props, + padding: (0,mermaid_8af3addd.c)().flowchart.padding + }); + }); +}; +const addEdges = function(edges, g, diagObj) { + mermaid_8af3addd.l.info("abc78 edges = ", edges); + let cnt = 0; + let linkIdCnt = {}; + let defaultStyle; + let defaultLabelStyle; + if (edges.defaultStyle !== void 0) { + const defaultStyles = (0,mermaid_8af3addd.k)(edges.defaultStyle); + defaultStyle = defaultStyles.style; + defaultLabelStyle = defaultStyles.labelStyle; + } + edges.forEach(function(edge) { + cnt++; + const linkIdBase = "L-" + edge.start + "-" + edge.end; + if (linkIdCnt[linkIdBase] === void 0) { + linkIdCnt[linkIdBase] = 0; + mermaid_8af3addd.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } else { + linkIdCnt[linkIdBase]++; + mermaid_8af3addd.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } + let linkId = linkIdBase + "-" + linkIdCnt[linkIdBase]; + mermaid_8af3addd.l.info("abc78 new link id to be used is", linkIdBase, linkId, linkIdCnt[linkIdBase]); + const linkNameStart = "LS-" + edge.start; + const linkNameEnd = "LE-" + edge.end; + const edgeData = { style: "", labelStyle: "" }; + edgeData.minlen = edge.length || 1; + if (edge.type === "arrow_open") { + edgeData.arrowhead = "none"; + } else { + edgeData.arrowhead = "normal"; + } + edgeData.arrowTypeStart = "arrow_open"; + edgeData.arrowTypeEnd = "arrow_open"; + switch (edge.type) { + case "double_arrow_cross": + edgeData.arrowTypeStart = "arrow_cross"; + case "arrow_cross": + edgeData.arrowTypeEnd = "arrow_cross"; + break; + case "double_arrow_point": + edgeData.arrowTypeStart = "arrow_point"; + case "arrow_point": + edgeData.arrowTypeEnd = "arrow_point"; + break; + case "double_arrow_circle": + edgeData.arrowTypeStart = "arrow_circle"; + case "arrow_circle": + edgeData.arrowTypeEnd = "arrow_circle"; + break; + } + let style = ""; + let labelStyle = ""; + switch (edge.stroke) { + case "normal": + style = "fill:none;"; + if (defaultStyle !== void 0) { + style = defaultStyle; + } + if (defaultLabelStyle !== void 0) { + labelStyle = defaultLabelStyle; + } + edgeData.thickness = "normal"; + edgeData.pattern = "solid"; + break; + case "dotted": + edgeData.thickness = "normal"; + edgeData.pattern = "dotted"; + edgeData.style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; + break; + case "thick": + edgeData.thickness = "thick"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 3.5px;fill:none;"; + break; + case "invisible": + edgeData.thickness = "invisible"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 0;fill:none;"; + break; + } + if (edge.style !== void 0) { + const styles = (0,mermaid_8af3addd.k)(edge.style); + style = styles.style; + labelStyle = styles.labelStyle; + } + edgeData.style = edgeData.style += style; + edgeData.labelStyle = edgeData.labelStyle += labelStyle; + if (edge.interpolate !== void 0) { + edgeData.curve = (0,mermaid_8af3addd.n)(edge.interpolate, src/* curveLinear */.c_6); + } else if (edges.defaultInterpolate !== void 0) { + edgeData.curve = (0,mermaid_8af3addd.n)(edges.defaultInterpolate, src/* curveLinear */.c_6); + } else { + edgeData.curve = (0,mermaid_8af3addd.n)(conf.curve, src/* curveLinear */.c_6); + } + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + } + edgeData.labelType = edge.labelType; + edgeData.label = edge.text.replace(mermaid_8af3addd.e.lineBreakRegex, "\n"); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none;"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + edgeData.id = linkId; + edgeData.classes = "flowchart-link " + linkNameStart + " " + linkNameEnd; + g.setEdge(edge.start, edge.end, edgeData, cnt); + }); +}; +const getClasses = function(text, diagObj) { + return diagObj.db.getClasses(); +}; +const draw = async function(text, id, _version, diagObj) { + mermaid_8af3addd.l.info("Drawing flowchart"); + let dir = diagObj.db.getDirection(); + if (dir === void 0) { + dir = "TD"; + } + const { securityLevel, flowchart: conf2 } = (0,mermaid_8af3addd.c)(); + const nodeSpacing = conf2.nodeSpacing || 50; + const rankSpacing = conf2.rankSpacing || 50; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,src/* select */.Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,src/* select */.Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,src/* select */.Ys)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const g = new graphlib/* Graph */.k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 0, + marginy: 0 + }).setDefaultEdgeLabel(function() { + return {}; + }); + let subG; + const subGraphs = diagObj.db.getSubGraphs(); + mermaid_8af3addd.l.info("Subgraphs - ", subGraphs); + for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) { + subG = subGraphs[i2]; + mermaid_8af3addd.l.info("Subgraph - ", subG); + diagObj.db.addVertex( + subG.id, + { text: subG.title, type: subG.labelType }, + "group", + void 0, + subG.classes, + subG.dir + ); + } + const vert = diagObj.db.getVertices(); + const edges = diagObj.db.getEdges(); + mermaid_8af3addd.l.info("Edges", edges); + let i = 0; + for (i = subGraphs.length - 1; i >= 0; i--) { + subG = subGraphs[i]; + (0,src/* selectAll */.td_)("cluster").append("text"); + for (let j = 0; j < subG.nodes.length; j++) { + mermaid_8af3addd.l.info("Setting up subgraphs", subG.nodes[j], subG.id); + g.setParent(subG.nodes[j], subG.id); + } + } + addVertices(vert, g, id, root, doc, diagObj); + addEdges(edges, g); + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + await (0,index_2c4b9a3b.r)(element, g, ["point", "circle", "cross"], "flowchart", id); + mermaid_8af3addd.u.insertTitle(svg, "flowchartTitleText", conf2.titleTopMargin, diagObj.db.getDiagramTitle()); + (0,mermaid_8af3addd.o)(g, svg, conf2.diagramPadding, conf2.useMaxWidth); + diagObj.db.indexNodes("subGraph" + i); + if (!conf2.htmlLabels) { + const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } + } + const keys = Object.keys(vert); + keys.forEach(function(key) { + const vertex = vert[key]; + if (vertex.link) { + const node = (0,src/* select */.Ys)("#" + id + ' [id="' + key + '"]'); + if (node) { + const link = doc.createElementNS("http://www.w3.org/2000/svg", "a"); + link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" ")); + link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link); + link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener"); + if (securityLevel === "sandbox") { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top"); + } else if (vertex.linkTarget) { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget); + } + const linkNode = node.insert(function() { + return link; + }, ":first-child"); + const shape = node.select(".label-container"); + if (shape) { + linkNode.append(function() { + return shape.node(); + }); + } + const label = node.select(".label"); + if (label) { + linkNode.append(function() { + return label.node(); + }); + } + } + } + }); +}; +const flowRendererV2 = { + setConf, + addVertices, + addEdges, + getClasses, + draw +}; +const fade = (color, opacity) => { + const channel = methods_channel; + const r = channel(color, "r"); + const g = channel(color, "g"); + const b = channel(color, "b"); + return rgba/* default */.Z(r, g, b, opacity); +}; +const getStyles = (options) => `.label { + font-family: ${options.fontFamily}; + color: ${options.nodeTextColor || options.textColor}; + } + .cluster-label text { + fill: ${options.titleColor}; + } + .cluster-label span,p { + color: ${options.titleColor}; + } + + .label text,span,p { + fill: ${options.nodeTextColor || options.textColor}; + color: ${options.nodeTextColor || options.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + .flowchart-label text { + text-anchor: middle; + } + // .flowchart-label .text-outer-tspan { + // text-anchor: middle; + // } + // .flowchart-label .text-inner-tspan { + // text-anchor: start; + // } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.5; + background-color: ${options.edgeLabelBackground}; + fill: ${options.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${fade(options.edgeLabelBackground, 0.5)}; + // background-color: + } + + .cluster rect { + fill: ${options.clusterBkg}; + stroke: ${options.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${options.titleColor}; + } + + .cluster span,p { + color: ${options.titleColor}; + } + /* .cluster div { + color: ${options.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${options.fontFamily}; + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } +`; +const flowStyles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/211d6170.a3a55376.js b/assets/js/211d6170.ccc60dec.js similarity index 93% rename from assets/js/211d6170.a3a55376.js rename to assets/js/211d6170.ccc60dec.js index 8c5f1377e..bd3846232 100644 --- a/assets/js/211d6170.a3a55376.js +++ b/assets/js/211d6170.ccc60dec.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3109],{41078:e=>{e.exports=JSON.parse('{"label":"package","permalink":"/docs/tags/package","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc124\uacc4/\ud328\ud0a4\uc9c0","title":"\ud328\ud0a4\uc9c0","description":"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0","permalink":"/docs/design/package"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3109],{41078:e=>{e.exports=JSON.parse('{"label":"package","permalink":"/docs/tags/package","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc124\uacc4/\ud328\ud0a4\uc9c0","title":"\ud328\ud0a4\uc9c0","description":"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0","permalink":"/docs/design/package"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/2127.52913f0e.js b/assets/js/2127.52913f0e.js new file mode 100644 index 000000000..cc6eae064 --- /dev/null +++ b/assets/js/2127.52913f0e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2127],{82127:(t,e,n)=>{n.d(e,{d:()=>D,p:()=>r,s:()=>_});var s=n(64218),i=n(56363),u=function(){var t=function(t,e,n,s){for(n=n||{},s=t.length;s--;n[t[s]]=e);return n},e=[1,16],n=[1,17],s=[1,18],i=[1,37],u=[1,38],r=[1,24],a=[1,22],c=[1,23],o=[1,29],l=[1,30],h=[1,31],A=[1,32],p=[1,33],d=[1,34],y=[1,25],E=[1,26],C=[1,27],m=[1,28],b=[1,42],f=[1,39],F=[1,40],g=[1,41],k=[1,43],T=[1,9],B=[1,8,9],D=[1,54],_=[1,55],S=[1,56],N=[1,57],L=[1,58],$=[1,59],v=[1,60],I=[1,8,9,38],x=[1,71],O=[1,8,9,12,13,21,36,38,41,58,59,60,61,62,63,64,69,71],R=[1,8,9,12,13,19,21,36,38,41,45,58,59,60,61,62,63,64,69,71,84,86,87,88,89],w=[13,84,86,87,88,89],P=[13,63,64,84,86,87,88,89],G=[13,58,59,60,61,62,84,86,87,88,89],M=[1,90],U=[1,8,9,36,38,41],Y=[1,8,9,21],z={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,className:17,classLiteralName:18,GENERICTYPE:19,relationStatement:20,LABEL:21,namespaceStatement:22,classStatement:23,memberStatement:24,annotationStatement:25,clickStatement:26,cssClassStatement:27,noteStatement:28,direction:29,acc_title:30,acc_title_value:31,acc_descr:32,acc_descr_value:33,acc_descr_multiline_value:34,namespaceIdentifier:35,STRUCT_START:36,classStatements:37,STRUCT_STOP:38,NAMESPACE:39,classIdentifier:40,STYLE_SEPARATOR:41,members:42,CLASS:43,ANNOTATION_START:44,ANNOTATION_END:45,MEMBER:46,SEPARATOR:47,relation:48,NOTE_FOR:49,noteText:50,NOTE:51,direction_tb:52,direction_bt:53,direction_rl:54,direction_lr:55,relationType:56,lineType:57,AGGREGATION:58,EXTENSION:59,COMPOSITION:60,DEPENDENCY:61,LOLLIPOP:62,LINE:63,DOTTED_LINE:64,CALLBACK:65,LINK:66,LINK_TARGET:67,CLICK:68,CALLBACK_NAME:69,CALLBACK_ARGS:70,HREF:71,CSSCLASS:72,commentToken:73,textToken:74,graphCodeTokens:75,textNoTagsToken:76,TAGSTART:77,TAGEND:78,"==":79,"--":80,PCT:81,DEFAULT:82,SPACE:83,MINUS:84,keywords:85,UNICODE_TEXT:86,NUM:87,ALPHA:88,BQUOTE_STR:89,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",19:"GENERICTYPE",21:"LABEL",30:"acc_title",31:"acc_title_value",32:"acc_descr",33:"acc_descr_value",34:"acc_descr_multiline_value",36:"STRUCT_START",38:"STRUCT_STOP",39:"NAMESPACE",41:"STYLE_SEPARATOR",43:"CLASS",44:"ANNOTATION_START",45:"ANNOTATION_END",46:"MEMBER",47:"SEPARATOR",49:"NOTE_FOR",51:"NOTE",52:"direction_tb",53:"direction_bt",54:"direction_rl",55:"direction_lr",58:"AGGREGATION",59:"EXTENSION",60:"COMPOSITION",61:"DEPENDENCY",62:"LOLLIPOP",63:"LINE",64:"DOTTED_LINE",65:"CALLBACK",66:"LINK",67:"LINK_TARGET",68:"CLICK",69:"CALLBACK_NAME",70:"CALLBACK_ARGS",71:"HREF",72:"CSSCLASS",75:"graphCodeTokens",77:"TAGSTART",78:"TAGEND",79:"==",80:"--",81:"PCT",82:"DEFAULT",83:"SPACE",84:"MINUS",85:"keywords",86:"UNICODE_TEXT",87:"NUM",88:"ALPHA",89:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,2],[17,1],[17,1],[17,2],[17,2],[17,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[22,4],[22,5],[35,2],[37,1],[37,2],[37,3],[23,1],[23,3],[23,4],[23,6],[40,2],[40,3],[25,4],[42,1],[42,2],[24,1],[24,2],[24,1],[24,1],[20,3],[20,4],[20,4],[20,5],[28,3],[28,2],[29,1],[29,1],[29,1],[29,1],[48,3],[48,2],[48,2],[48,1],[56,1],[56,1],[56,1],[56,1],[56,1],[57,1],[57,1],[26,3],[26,4],[26,3],[26,4],[26,4],[26,5],[26,3],[26,4],[26,4],[26,5],[26,4],[26,5],[26,5],[26,6],[27,3],[73,1],[73,1],[74,1],[74,1],[74,1],[74,1],[74,1],[74,1],[74,1],[76,1],[76,1],[76,1],[76,1],[16,1],[16,1],[16,1],[16,1],[18,1],[50,1]],performAction:function(t,e,n,s,i,u,r){var a=u.length-1;switch(i){case 8:this.$=u[a-1];break;case 9:case 11:case 12:this.$=u[a];break;case 10:case 13:this.$=u[a-1]+u[a];break;case 14:case 15:this.$=u[a-1]+"~"+u[a]+"~";break;case 16:s.addRelation(u[a]);break;case 17:u[a-1].title=s.cleanupLabel(u[a]),s.addRelation(u[a-1]);break;case 26:this.$=u[a].trim(),s.setAccTitle(this.$);break;case 27:case 28:this.$=u[a].trim(),s.setAccDescription(this.$);break;case 29:s.addClassesToNamespace(u[a-3],u[a-1]);break;case 30:s.addClassesToNamespace(u[a-4],u[a-1]);break;case 31:this.$=u[a],s.addNamespace(u[a]);break;case 32:case 42:this.$=[u[a]];break;case 33:this.$=[u[a-1]];break;case 34:u[a].unshift(u[a-2]),this.$=u[a];break;case 36:s.setCssClass(u[a-2],u[a]);break;case 37:s.addMembers(u[a-3],u[a-1]);break;case 38:s.setCssClass(u[a-5],u[a-3]),s.addMembers(u[a-5],u[a-1]);break;case 39:this.$=u[a],s.addClass(u[a]);break;case 40:this.$=u[a-1],s.addClass(u[a-1]),s.setClassLabel(u[a-1],u[a]);break;case 41:s.addAnnotation(u[a],u[a-2]);break;case 43:u[a].push(u[a-1]),this.$=u[a];break;case 44:case 46:case 47:break;case 45:s.addMember(u[a-1],s.cleanupLabel(u[a]));break;case 48:this.$={id1:u[a-2],id2:u[a],relation:u[a-1],relationTitle1:"none",relationTitle2:"none"};break;case 49:this.$={id1:u[a-3],id2:u[a],relation:u[a-1],relationTitle1:u[a-2],relationTitle2:"none"};break;case 50:this.$={id1:u[a-3],id2:u[a],relation:u[a-2],relationTitle1:"none",relationTitle2:u[a-1]};break;case 51:this.$={id1:u[a-4],id2:u[a],relation:u[a-2],relationTitle1:u[a-3],relationTitle2:u[a-1]};break;case 52:s.addNote(u[a],u[a-1]);break;case 53:s.addNote(u[a]);break;case 54:s.setDirection("TB");break;case 55:s.setDirection("BT");break;case 56:s.setDirection("RL");break;case 57:s.setDirection("LR");break;case 58:this.$={type1:u[a-2],type2:u[a],lineType:u[a-1]};break;case 59:this.$={type1:"none",type2:u[a],lineType:u[a-1]};break;case 60:this.$={type1:u[a-1],type2:"none",lineType:u[a]};break;case 61:this.$={type1:"none",type2:"none",lineType:u[a]};break;case 62:this.$=s.relationType.AGGREGATION;break;case 63:this.$=s.relationType.EXTENSION;break;case 64:this.$=s.relationType.COMPOSITION;break;case 65:this.$=s.relationType.DEPENDENCY;break;case 66:this.$=s.relationType.LOLLIPOP;break;case 67:this.$=s.lineType.LINE;break;case 68:this.$=s.lineType.DOTTED_LINE;break;case 69:case 75:this.$=u[a-2],s.setClickEvent(u[a-1],u[a]);break;case 70:case 76:this.$=u[a-3],s.setClickEvent(u[a-2],u[a-1]),s.setTooltip(u[a-2],u[a]);break;case 71:this.$=u[a-2],s.setLink(u[a-1],u[a]);break;case 72:this.$=u[a-3],s.setLink(u[a-2],u[a-1],u[a]);break;case 73:this.$=u[a-3],s.setLink(u[a-2],u[a-1]),s.setTooltip(u[a-2],u[a]);break;case 74:this.$=u[a-4],s.setLink(u[a-3],u[a-2],u[a]),s.setTooltip(u[a-3],u[a-1]);break;case 77:this.$=u[a-3],s.setClickEvent(u[a-2],u[a-1],u[a]);break;case 78:this.$=u[a-4],s.setClickEvent(u[a-3],u[a-2],u[a-1]),s.setTooltip(u[a-3],u[a]);break;case 79:this.$=u[a-3],s.setLink(u[a-2],u[a]);break;case 80:this.$=u[a-4],s.setLink(u[a-3],u[a-1],u[a]);break;case 81:this.$=u[a-4],s.setLink(u[a-3],u[a-1]),s.setTooltip(u[a-3],u[a]);break;case 82:this.$=u[a-5],s.setLink(u[a-4],u[a-2],u[a]),s.setTooltip(u[a-4],u[a-1]);break;case 83:s.setCssClass(u[a-1],u[a])}},table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:35,17:19,18:36,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:e,32:n,34:s,35:20,39:i,40:21,43:u,44:r,46:a,47:c,49:o,51:l,52:h,53:A,54:p,55:d,65:y,66:E,68:C,72:m,84:b,86:f,87:F,88:g,89:k},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(T,[2,5],{8:[1,44]}),{8:[1,45]},t(B,[2,16],{21:[1,46]}),t(B,[2,18]),t(B,[2,19]),t(B,[2,20]),t(B,[2,21]),t(B,[2,22]),t(B,[2,23]),t(B,[2,24]),t(B,[2,25]),{31:[1,47]},{33:[1,48]},t(B,[2,28]),t(B,[2,44],{48:49,56:52,57:53,13:[1,50],21:[1,51],58:D,59:_,60:S,61:N,62:L,63:$,64:v}),{36:[1,61]},t(I,[2,35],{36:[1,63],41:[1,62]}),t(B,[2,46]),t(B,[2,47]),{16:64,84:b,86:f,87:F,88:g},{16:35,17:65,18:36,84:b,86:f,87:F,88:g,89:k},{16:35,17:66,18:36,84:b,86:f,87:F,88:g,89:k},{16:35,17:67,18:36,84:b,86:f,87:F,88:g,89:k},{13:[1,68]},{16:35,17:69,18:36,84:b,86:f,87:F,88:g,89:k},{13:x,50:70},t(B,[2,54]),t(B,[2,55]),t(B,[2,56]),t(B,[2,57]),t(O,[2,11],{16:35,18:36,17:72,19:[1,73],84:b,86:f,87:F,88:g,89:k}),t(O,[2,12],{19:[1,74]}),{15:75,16:76,84:b,86:f,87:F,88:g},{16:35,17:77,18:36,84:b,86:f,87:F,88:g,89:k},t(R,[2,97]),t(R,[2,98]),t(R,[2,99]),t(R,[2,100]),t([1,8,9,12,13,19,21,36,38,41,58,59,60,61,62,63,64,69,71],[2,101]),t(T,[2,6],{10:5,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,17:19,35:20,40:21,16:35,18:36,5:78,30:e,32:n,34:s,39:i,43:u,44:r,46:a,47:c,49:o,51:l,52:h,53:A,54:p,55:d,65:y,66:E,68:C,72:m,84:b,86:f,87:F,88:g,89:k}),{5:79,10:5,16:35,17:19,18:36,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:e,32:n,34:s,35:20,39:i,40:21,43:u,44:r,46:a,47:c,49:o,51:l,52:h,53:A,54:p,55:d,65:y,66:E,68:C,72:m,84:b,86:f,87:F,88:g,89:k},t(B,[2,17]),t(B,[2,26]),t(B,[2,27]),{13:[1,81],16:35,17:80,18:36,84:b,86:f,87:F,88:g,89:k},{48:82,56:52,57:53,58:D,59:_,60:S,61:N,62:L,63:$,64:v},t(B,[2,45]),{57:83,63:$,64:v},t(w,[2,61],{56:84,58:D,59:_,60:S,61:N,62:L}),t(P,[2,62]),t(P,[2,63]),t(P,[2,64]),t(P,[2,65]),t(P,[2,66]),t(G,[2,67]),t(G,[2,68]),{8:[1,86],23:87,37:85,40:21,43:u},{16:88,84:b,86:f,87:F,88:g},{42:89,46:M},{45:[1,91]},{13:[1,92]},{13:[1,93]},{69:[1,94],71:[1,95]},{16:96,84:b,86:f,87:F,88:g},{13:x,50:97},t(B,[2,53]),t(B,[2,102]),t(O,[2,13]),t(O,[2,14]),t(O,[2,15]),{36:[2,31]},{15:98,16:76,36:[2,9],84:b,86:f,87:F,88:g},t(U,[2,39],{11:99,12:[1,100]}),t(T,[2,7]),{9:[1,101]},t(Y,[2,48]),{16:35,17:102,18:36,84:b,86:f,87:F,88:g,89:k},{13:[1,104],16:35,17:103,18:36,84:b,86:f,87:F,88:g,89:k},t(w,[2,60],{56:105,58:D,59:_,60:S,61:N,62:L}),t(w,[2,59]),{38:[1,106]},{23:87,37:107,40:21,43:u},{8:[1,108],38:[2,32]},t(I,[2,36],{36:[1,109]}),{38:[1,110]},{38:[2,42],42:111,46:M},{16:35,17:112,18:36,84:b,86:f,87:F,88:g,89:k},t(B,[2,69],{13:[1,113]}),t(B,[2,71],{13:[1,115],67:[1,114]}),t(B,[2,75],{13:[1,116],70:[1,117]}),{13:[1,118]},t(B,[2,83]),t(B,[2,52]),{36:[2,10]},t(U,[2,40]),{13:[1,119]},{1:[2,4]},t(Y,[2,50]),t(Y,[2,49]),{16:35,17:120,18:36,84:b,86:f,87:F,88:g,89:k},t(w,[2,58]),t(B,[2,29]),{38:[1,121]},{23:87,37:122,38:[2,33],40:21,43:u},{42:123,46:M},t(I,[2,37]),{38:[2,43]},t(B,[2,41]),t(B,[2,70]),t(B,[2,72]),t(B,[2,73],{67:[1,124]}),t(B,[2,76]),t(B,[2,77],{13:[1,125]}),t(B,[2,79],{13:[1,127],67:[1,126]}),{14:[1,128]},t(Y,[2,51]),t(B,[2,30]),{38:[2,34]},{38:[1,129]},t(B,[2,74]),t(B,[2,78]),t(B,[2,80]),t(B,[2,81],{67:[1,130]}),t(U,[2,8]),t(I,[2,38]),t(B,[2,82])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],75:[2,31],98:[2,10],101:[2,4],111:[2,43],122:[2,34]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],s=[],i=[null],u=[],r=this.table,a="",c=0,o=0,l=u.slice.call(arguments,1),h=Object.create(this.lexer),A={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(A.yy[p]=this.yy[p]);h.setInput(t,A.yy),A.yy.lexer=h,A.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var d=h.yylloc;u.push(d);var y=h.options&&h.options.ranges;"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,C,m,b,f,F,g,k,T,B={};;){if(C=n[n.length-1],this.defaultActions[C]?m=this.defaultActions[C]:(null==E&&(T=void 0,"number"!=typeof(T=s.pop()||h.lex()||1)&&(T instanceof Array&&(T=(s=T).pop()),T=e.symbols_[T]||T),E=T),m=r[C]&&r[C][E]),void 0===m||!m.length||!m[0]){var D="";for(f in k=[],r[C])this.terminals_[f]&&f>2&&k.push("'"+this.terminals_[f]+"'");D=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(D,{text:h.match,token:this.terminals_[E]||E,line:h.yylineno,loc:d,expected:k})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+C+", token: "+E);switch(m[0]){case 1:n.push(E),i.push(h.yytext),u.push(h.yylloc),n.push(m[1]),E=null,o=h.yyleng,a=h.yytext,c=h.yylineno,d=h.yylloc;break;case 2:if(F=this.productions_[m[1]][1],B.$=i[i.length-F],B._$={first_line:u[u.length-(F||1)].first_line,last_line:u[u.length-1].last_line,first_column:u[u.length-(F||1)].first_column,last_column:u[u.length-1].last_column},y&&(B._$.range=[u[u.length-(F||1)].range[0],u[u.length-1].range[1]]),void 0!==(b=this.performAction.apply(B,[a,o,c,A.yy,m[1],i,u].concat(l))))return b;F&&(n=n.slice(0,-1*F*2),i=i.slice(0,-1*F),u=u.slice(0,-1*F)),n.push(this.productions_[m[1]][0]),i.push(B.$),u.push(B._$),g=r[n[n.length-2]][n[n.length-1]],n.push(g);break;case 3:return!0}}return!0}},K={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===s.length?this.yylloc.first_column:0)+s[s.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,s,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var u in i)this[u]=i[u];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),u=0;ue[0].length)){if(e=n,s=u,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[u])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,s){switch(n){case 0:return 52;case 1:return 53;case 2:return 54;case 3:return 55;case 4:case 5:case 14:case 29:case 34:case 38:case 45:break;case 6:return this.begin("acc_title"),30;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),32;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 19:case 22:case 24:case 56:case 59:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 33:return 8;case 15:case 16:return 7;case 17:case 35:case 43:return"EDGE_STATE";case 18:this.begin("callback_name");break;case 20:this.popState(),this.begin("callback_args");break;case 21:return 69;case 23:return 70;case 25:return"STR";case 26:this.begin("string");break;case 27:return this.begin("namespace"),39;case 28:case 37:return this.popState(),8;case 30:return this.begin("namespace-body"),36;case 31:case 41:return this.popState(),38;case 32:case 42:return"EOF_IN_STRUCT";case 36:return this.begin("class"),43;case 39:return this.popState(),this.popState(),38;case 40:return this.begin("class-body"),36;case 44:return"OPEN_IN_STRUCT";case 46:return"MEMBER";case 47:return 72;case 48:return 65;case 49:return 66;case 50:return 68;case 51:return 49;case 52:return 51;case 53:return 44;case 54:return 45;case 55:return 71;case 57:return"GENERICTYPE";case 58:this.begin("generic");break;case 60:return"BQUOTE_STR";case 61:this.begin("bqstring");break;case 62:case 63:case 64:case 65:return 67;case 66:case 67:return 59;case 68:case 69:return 61;case 70:return 60;case 71:return 58;case 72:return 62;case 73:return 63;case 74:return 64;case 75:return 21;case 76:return 41;case 77:return 84;case 78:return"DOT";case 79:return"PLUS";case 80:return 81;case 81:case 82:return"EQUALS";case 83:return 88;case 84:return 12;case 85:return 14;case 86:return"PUNCTUATION";case 87:return 87;case 88:return 86;case 89:return 83;case 90:return 9}},rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[26,31,32,33,34,35,36,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},namespace:{rules:[26,27,28,29,30,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},"class-body":{rules:[26,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},class:{rules:[26,37,38,39,40,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},acc_descr:{rules:[9,26,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},acc_title:{rules:[7,26,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},callback_args:{rules:[22,23,26,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},callback_name:{rules:[19,20,21,26,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},href:{rules:[26,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},struct:{rules:[26,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},generic:{rules:[26,47,48,49,50,51,52,53,54,55,56,57,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},bqstring:{rules:[26,47,48,49,50,51,52,53,54,55,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},string:{rules:[24,25,26,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,36,47,48,49,50,51,52,53,54,55,58,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90],inclusive:!0}}};function j(){this.yy={}}return z.lexer=K,j.prototype=z,z.Parser=j,new j}();u.parser=u;const r=u,a=["#","+","~","-",""];class c{constructor(t,e){this.memberType=e,this.visibility="",this.classifier="";const n=(0,i.d)(t,(0,i.c)());this.parseMember(n)}getDisplayDetails(){let t=this.visibility+(0,i.v)(this.id);"method"===this.memberType&&(t+=`(${(0,i.v)(this.parameters.trim())})`,this.returnType&&(t+=" : "+(0,i.v)(this.returnType))),t=t.trim();return{displayText:t,cssStyle:this.parseClassifier()}}parseMember(t){let e="";if("method"===this.memberType){const n=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/,s=t.match(n);if(s){const t=s[1]?s[1].trim():"";if(a.includes(t)&&(this.visibility=t),this.id=s[2].trim(),this.parameters=s[3]?s[3].trim():"",e=s[4]?s[4].trim():"",this.returnType=s[5]?s[5].trim():"",""===e){const t=this.returnType.substring(this.returnType.length-1);t.match(/[$*]/)&&(e=t,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{const n=t.length,s=t.substring(0,1),i=t.substring(n-1);a.includes(s)&&(this.visibility=s),i.match(/[*?]/)&&(e=i),this.id=t.substring(""===this.visibility?0:1,""===e?n:n-1)}this.classifier=e}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}}const o="classId-";let l=[],h={},A=[],p=0,d={},y=0,E=[];const C=t=>i.e.sanitizeText(t,(0,i.c)()),m=function(t){const e=i.e.sanitizeText(t,(0,i.c)());let n="",s=e;if(e.indexOf("~")>0){const t=e.split("~");s=C(t[0]),n=C(t[1])}return{className:s,type:n}},b=function(t){const e=i.e.sanitizeText(t,(0,i.c)()),{className:n,type:s}=m(e);if(Object.hasOwn(h,n))return;const u=i.e.sanitizeText(n,(0,i.c)());h[u]={id:u,type:s,label:u,cssClasses:[],methods:[],members:[],annotations:[],domId:o+u+"-"+p},p++},f=function(t){const e=i.e.sanitizeText(t,(0,i.c)());if(e in h)return h[e].domId;throw new Error("Class not found: "+e)},F=function(t,e){b(t);const n=m(t).className,s=h[n];if("string"==typeof e){const t=e.trim();t.startsWith("<<")&&t.endsWith(">>")?s.annotations.push(C(t.substring(2,t.length-2))):t.indexOf(")")>0?s.methods.push(new c(t,"method")):t&&s.members.push(new c(t,"attribute"))}},g=function(t,e){t.split(",").forEach((function(t){let n=t;t[0].match(/\d/)&&(n=o+n),void 0!==h[n]&&h[n].cssClasses.push(e)}))},k=function(t,e,n){const s=i.e.sanitizeText(t,(0,i.c)());if("loose"!==(0,i.c)().securityLevel)return;if(void 0===e)return;const u=s;if(void 0!==h[u]){const t=f(u);let s=[];if("string"==typeof n){s=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);(0,s.Ys)(this).classed("hover",!1)}))};E.push(T);let B="TB";const D={setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,getConfig:()=>(0,i.c)().class,addClass:b,bindFunctions:function(t){E.forEach((function(e){e(t)}))},clear:function(){l=[],h={},A=[],E=[],E.push(T),d={},y=0,(0,i.t)()},getClass:function(t){return h[t]},getClasses:function(){return h},getNotes:function(){return A},addAnnotation:function(t,e){const n=m(t).className;h[n].annotations.push(e)},addNote:function(t,e){const n={id:`note${A.length}`,class:e,text:t};A.push(n)},getRelations:function(){return l},addRelation:function(t){i.l.debug("Adding relation: "+JSON.stringify(t)),b(t.id1),b(t.id2),t.id1=m(t.id1).className,t.id2=m(t.id2).className,t.relationTitle1=i.e.sanitizeText(t.relationTitle1.trim(),(0,i.c)()),t.relationTitle2=i.e.sanitizeText(t.relationTitle2.trim(),(0,i.c)()),l.push(t)},getDirection:()=>B,setDirection:t=>{B=t},addMember:F,addMembers:function(t,e){Array.isArray(e)&&(e.reverse(),e.forEach((e=>F(t,e))))},cleanupLabel:function(t){return t.startsWith(":")&&(t=t.substring(1)),C(t.trim())},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},setClickEvent:function(t,e,n){t.split(",").forEach((function(t){k(t,e,n),h[t].haveCallback=!0})),g(t,"clickable")},setCssClass:g,setLink:function(t,e,n){const s=(0,i.c)();t.split(",").forEach((function(t){let u=t;t[0].match(/\d/)&&(u=o+u),void 0!==h[u]&&(h[u].link=i.u.formatUrl(e,s),"sandbox"===s.securityLevel?h[u].linkTarget="_top":h[u].linkTarget="string"==typeof n?C(n):"_blank")})),g(t,"clickable")},getTooltip:function(t,e){return e?d[e].classes[t].tooltip:h[t].tooltip},setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(h[t].tooltip=C(e))}))},lookUpDomId:f,setDiagramTitle:i.q,getDiagramTitle:i.r,setClassLabel:function(t,e){const n=i.e.sanitizeText(t,(0,i.c)());e&&(e=C(e));const{className:s}=m(n);h[s].label=e},addNamespace:function(t){void 0===d[t]&&(d[t]={id:t,classes:{},children:{},domId:o+t+"-"+y},y++)},addClassesToNamespace:function(t,e){void 0!==d[t]&&e.map((e=>{h[e].parent=t,d[t].classes[e]=h[e]}))},getNamespace:function(t){return d[t]},getNamespaces:function(){return d}},_=t=>`g.classGroup text {\n fill: ${t.nodeBorder||t.classText};\n stroke: none;\n font-family: ${t.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${t.classText};\n}\n.edgeLabel .label rect {\n fill: ${t.mainBkg};\n}\n.label text {\n fill: ${t.classText};\n}\n.edgeLabel .label span {\n background: ${t.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${t.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${t.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`}}]); \ No newline at end of file diff --git a/assets/js/21294bbb.58721559.js b/assets/js/21294bbb.58721559.js new file mode 100644 index 000000000..3f7913798 --- /dev/null +++ b/assets/js/21294bbb.58721559.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9412],{72794:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var t=n(85893),s=n(3905);const c={title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",slug:"web-racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,a={permalink:"/web-racing-car-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-racingcar/pull/24",date:"2023-05-02T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 2\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.6,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",slug:"web-racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",permalink:"/shopping-cart-retrospective"},nextItem:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",permalink:"/tecochat-retrospective-2"}},i={authorsImageUrls:[]},l=[{value:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158",id:"\uc6f9-\uc790\ub3d9\ucc28-\ubbf8\uc158",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function p(e){const r={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-racingcar/pull/24",children:"https://github.com/woowacourse/jwp-racingcar/pull/24"}),(0,t.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-racingcar/pull/128",children:"https://github.com/woowacourse/jwp-racingcar/pull/128"})]})}),"\n",(0,t.jsx)(r.h3,{id:"\uc6f9-\uc790\ub3d9\ucc28-\ubbf8\uc158",children:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158"}),"\n",(0,t.jsxs)(r.p,{children:["\uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud55c\ub2e4\uace0 \uc2dc\uac04\uc774 \ub9ce\uc774 \uc5c6\uc5b4\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc84c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158\uc5d0\uc11c\ub294 \ube44\ubc84\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub808\ubca8 2\uc5d0\uc11c \uc9c4\ud589\ud558\ub294 \uccab \ubbf8\uc158\uc774\ub77c \ub9ce\uc774 \uae34\uc7a5\ub418\uc5c8\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ube44\ubc84\ub791 \ucd08\ubc18\uc5d0 \ub9db\uc788\ub294 \uac83\ub3c4 \ub9ce\uc774 \uba39\uc73c\uba74\uc11c \ube68\ub9ac \uce5c\ud574\uc838\uc11c \uc7ac\ubc0c\uac8c \ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc2a4\ud504\ub9c1\uc744 \uc870\uae08 \uc0ac\uc6a9\ud560 \uc904 \uc54c\uc544\uc11c, \ube44\ubc84\ub791 \uac19\uc774 \ud559\uc2b5\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uccab \ubbf8\uc158\uc774\ub77c \uadf8\ub7f0\uc9c0 \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc740 \uc5c6\uc5c8\uace0, \ucd5c\ub300\ud55c \uae54\ub054\ud558\uac8c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub09c\uc774\ub3c4 \ub192\uc740 \ubbf8\uc158\uc774 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ub9ac\ubdf0\uc5b4\uc778 \ub77c\ube48\uc5d0\uac8c \uce6d\ucc2c\uc744 \ub9ce\uc774 \ubc1b\uc544\uc11c \uae30\ubd84\uc774 \uc88b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub77c\ube48 \uac10\uc0ac\ud569\ub2c8\ub2e4!"]}),"\n",(0,t.jsx)(r.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:["\ucee8\ub514\uc158\ub3c4 \uc88b\uc9c0 \uc54a\uace0 \uc5f4\uc815\ub3c4 \uc2dd\uc740 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc774 \ub2e4\uc18c \uc5ec\uc720\ub86d\ub2e4\uace0 \ub290\uaef4\uc838\uc11c, \uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ubd84\ub3c4 \uc798 \uad00\ub9ac\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud574\uc11c \ud398\uc5b4\uc5d0\uac8c \ub9ce\uc774 \ubbf8\uc548\ud588\uace0, \ub098 \uc790\uc2e0\uc5d0\uac8c \uc544\uc26c\uc6e0\ub358 \ubd80\ubd84\uc774 \ub9ce\uc558\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc9c0\ub09c\ubc88 \ud68c\uace0\ub97c \ub2e4\uc2dc \ubcf4\ub294\ub370 \uc9d1\uc911\uc744 \uc798 \ubabb\ud55c \uacbd\uc6b0\uac00 \ub9ce\uc740 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub3c4\uc804\uc801\uc774\uc9c0 \uc54a\uac70\ub098 \uc2dc\uac04\uc774 \ubd80\uc871\ud558\uc9c0 \uc54a\uc73c\uba74 \uc9d1\uc911\uc744 \uc798 \ubabb\ud558\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uba38\ub9bf\uc18d\uc5d0\uc11c \uc2dc\uac04\uc801 \uc5ec\uc720\uac00 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \ub54c\uac00 \uac00\uc7a5 \uc704\ud5d8\ud55c \uc21c\uac04\uc778 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ud568\uaed8 \uc790\ub77c\uae30\uc5d0\uc11c \ub098\uc628 ",(0,t.jsx)(r.code,{children:"\ub09c\uc774\ub3c4 \ub192\uc774\uae30"}),"\uac00 \ud544\uc694\ud574\uc9c0\ub294 \uc21c\uac04\uc774\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uc911\uc694\ub3c4\uac00 \uc788\ub294 \uc5b4\ub178\ud14c\uc774\uc158\ubd80\ud130 \ud074\ub798\uc2a4 \uc774\ub984\uc5d0 \uac00\uae5d\uac8c \uba85\uc2dc\ud558\uae30"})}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-java",children:'@SuppressWarnings("NonAsciiCharacters")\n@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)\n@Transactional\n@AutoConfigureMockMvc\n@SpringBootTest\npublic class RacingGameIntegrationTest {\n'})}),"\n",(0,t.jsx)(r.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ube44\ubc84\uc758 \uc131\uaca9"}),(0,t.jsx)(r.br,{}),"\n","\ube44\ubc84\uac00 \uc131\uaca9\uc774 \uc88b\uc544\uc11c \ud3b8\ud558\uac8c \ud398\uc5b4\ub97c \ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc131\uae09\ud558\uc9c0 \uc54a\uace0 \uc5ec\uc720\ub85c\uc6cc\uc11c \uc88b\uc558\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ubbf8\uc158\uc5d0 \uc9d1\uc911\ud558\ub294 \ubd80\ubd84"}),(0,t.jsx)(r.br,{}),"\n","\ub0b4\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud588\ub294\ub370\ub3c4 \uac19\uc774 \ud398\uc5b4\ub97c \uc798 \uc9c4\ud589\ud55c \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ube44\ubc84\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud574\uc11c \uadf8\ub807\uc9c0 \uc54a\uc558\ub098 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uadfc\uc721\ub9e8 \ube44\ubc84\ub77c \uadf8\ub7f0\uc9c0 \uccb4\ub825\uc774 \uc88b\uc544\uc11c \uadf8\ub7f0\uac00?",(0,t.jsx)(r.br,{}),"\n","\uc911\uac04\uc5d0 \uc798 \uc548 \uc26c\uace0\ub3c4 \uc9d1\uc911\ud574\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac78 \ubcf4\uace0 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ud559\uc2b5\uc5d0 \ub300\ud55c \uc5f4\uc815"}),(0,t.jsx)(r.br,{}),"\n","\ucd94\uac00\uc801\uc73c\ub85c \uc54c\uace0 \uc2f6\uc740 \ubd80\ubd84\uc744 \ub530\ub85c \ud559\uc2b5\ud558\ub294 \uc5f4\uc815\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ube44\ubc84\uc640 \uc2a4\ud504\ub9c1\uc5d0 \ub300\ud574 \uc54c\uc544\uac00\ub294 \uc2dc\uac04\uc744 \ub9ce\uc774 \uac00\uc9c4 \ubd80\ubd84\uc774 \ub9e4\uc6b0 \uc88b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub098\ub3c4 5\uc6d4\ubd80\ud130 \uc870\uae08 \ub354 \ud654\uc774\ud305 \ud574\uc57c\uaca0\ub2e4."]})]})}function u(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>l});var t=n(67294);function s(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function c(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var r=1;r=0||(s[n]=e[n]);return s}(e,r);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var i=t.createContext({}),l=function(e){var r=t.useContext(i),n=r;return e&&(n="function"==typeof e?e(r):o(o({},r),e)),n},p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},u=t.forwardRef((function(e,r){var n=e.components,s=e.mdxType,c=e.originalType,i=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),h=l(n),j=s,d=h["".concat(i,".").concat(j)]||h[j]||p[j]||c;return n?t.createElement(d,o(o({ref:r},u),{},{components:n})):t.createElement(d,o({ref:r},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/21294bbb.8ea9233b.js b/assets/js/21294bbb.8ea9233b.js deleted file mode 100644 index 7ccb213c6..000000000 --- a/assets/js/21294bbb.8ea9233b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9412],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>b});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),m=l(r),b=a,g=m["".concat(i,".").concat(b)]||m[b]||u[b]||p;return r?n.createElement(g,o(o({ref:t},s),{},{components:r})):n.createElement(g,o({ref:t},s))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,o[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>p,metadata:()=>c,toc:()=>l});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",slug:"web-racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,c={permalink:"/web-racing-car-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-racingcar/pull/24",date:"2023-05-02T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 2\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.6,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",slug:"web-racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",permalink:"/shopping-cart-retrospective"},nextItem:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",permalink:"/tecochat-retrospective-2"}},i={authorsImageUrls:[]},l=[{value:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158",id:"\uc6f9-\uc790\ub3d9\ucc28-\ubbf8\uc158",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],s={toc:l};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-racingcar/pull/24"},"https://github.com/woowacourse/jwp-racingcar/pull/24"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-racingcar/pull/128"},"https://github.com/woowacourse/jwp-racingcar/pull/128")," ")),(0,a.kt)("h3",{id:"\uc6f9-\uc790\ub3d9\ucc28-\ubbf8\uc158"},"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158"),(0,a.kt)("p",null,"\uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud55c\ub2e4\uace0 \uc2dc\uac04\uc774 \ub9ce\uc774 \uc5c6\uc5b4\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc84c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158\uc5d0\uc11c\ub294 \ube44\ubc84\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 2\uc5d0\uc11c \uc9c4\ud589\ud558\ub294 \uccab \ubbf8\uc158\uc774\ub77c \ub9ce\uc774 \uae34\uc7a5\ub418\uc5c8\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ube44\ubc84\ub791 \ucd08\ubc18\uc5d0 \ub9db\uc788\ub294 \uac83\ub3c4 \ub9ce\uc774 \uba39\uc73c\uba74\uc11c \ube68\ub9ac \uce5c\ud574\uc838\uc11c \uc7ac\ubc0c\uac8c \ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uc744 \uc870\uae08 \uc0ac\uc6a9\ud560 \uc904 \uc54c\uc544\uc11c, \ube44\ubc84\ub791 \uac19\uc774 \ud559\uc2b5\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uccab \ubbf8\uc158\uc774\ub77c \uadf8\ub7f0\uc9c0 \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc740 \uc5c6\uc5c8\uace0, \ucd5c\ub300\ud55c \uae54\ub054\ud558\uac8c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub09c\uc774\ub3c4 \ub192\uc740 \ubbf8\uc158\uc774 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ub9ac\ubdf0\uc5b4\uc778 \ub77c\ube48\uc5d0\uac8c \uce6d\ucc2c\uc744 \ub9ce\uc774 \ubc1b\uc544\uc11c \uae30\ubd84\uc774 \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub77c\ube48 \uac10\uc0ac\ud569\ub2c8\ub2e4! "),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,"\ucee8\ub514\uc158\ub3c4 \uc88b\uc9c0 \uc54a\uace0 \uc5f4\uc815\ub3c4 \uc2dd\uc740 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc774 \ub2e4\uc18c \uc5ec\uc720\ub86d\ub2e4\uace0 \ub290\uaef4\uc838\uc11c, \uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ubd84\ub3c4 \uc798 \uad00\ub9ac\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud574\uc11c \ud398\uc5b4\uc5d0\uac8c \ub9ce\uc774 \ubbf8\uc548\ud588\uace0, \ub098 \uc790\uc2e0\uc5d0\uac8c \uc544\uc26c\uc6e0\ub358 \ubd80\ubd84\uc774 \ub9ce\uc558\ub2e4. "),(0,a.kt)("p",null,"\uc9c0\ub09c\ubc88 \ud68c\uace0\ub97c \ub2e4\uc2dc \ubcf4\ub294\ub370 \uc9d1\uc911\uc744 \uc798 \ubabb\ud55c \uacbd\uc6b0\uac00 \ub9ce\uc740 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub3c4\uc804\uc801\uc774\uc9c0 \uc54a\uac70\ub098 \uc2dc\uac04\uc774 \ubd80\uc871\ud558\uc9c0 \uc54a\uc73c\uba74 \uc9d1\uc911\uc744 \uc798 \ubabb\ud558\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uba38\ub9bf\uc18d\uc5d0\uc11c \uc2dc\uac04\uc801 \uc5ec\uc720\uac00 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \ub54c\uac00 \uac00\uc7a5 \uc704\ud5d8\ud55c \uc21c\uac04\uc778 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\ud568\uaed8 \uc790\ub77c\uae30\uc5d0\uc11c \ub098\uc628 ",(0,a.kt)("inlineCode",{parentName:"p"},"\ub09c\uc774\ub3c4 \ub192\uc774\uae30"),"\uac00 \ud544\uc694\ud574\uc9c0\ub294 \uc21c\uac04\uc774\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc911\uc694\ub3c4\uac00 \uc788\ub294 \uc5b4\ub178\ud14c\uc774\uc158\ubd80\ud130 \ud074\ub798\uc2a4 \uc774\ub984\uc5d0 \uac00\uae5d\uac8c \uba85\uc2dc\ud558\uae30")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@SuppressWarnings("NonAsciiCharacters")\n@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)\n@Transactional\n@AutoConfigureMockMvc\n@SpringBootTest\npublic class RacingGameIntegrationTest {\n')),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ube44\ubc84\uc758 \uc131\uaca9"),(0,a.kt)("br",{parentName:"p"}),"\n","\ube44\ubc84\uac00 \uc131\uaca9\uc774 \uc88b\uc544\uc11c \ud3b8\ud558\uac8c \ud398\uc5b4\ub97c \ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc131\uae09\ud558\uc9c0 \uc54a\uace0 \uc5ec\uc720\ub85c\uc6cc\uc11c \uc88b\uc558\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ubbf8\uc158\uc5d0 \uc9d1\uc911\ud558\ub294 \ubd80\ubd84"),(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud588\ub294\ub370\ub3c4 \uac19\uc774 \ud398\uc5b4\ub97c \uc798 \uc9c4\ud589\ud55c \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube44\ubc84\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud574\uc11c \uadf8\ub807\uc9c0 \uc54a\uc558\ub098 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadfc\uc721\ub9e8 \ube44\ubc84\ub77c \uadf8\ub7f0\uc9c0 \uccb4\ub825\uc774 \uc88b\uc544\uc11c \uadf8\ub7f0\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04\uc5d0 \uc798 \uc548 \uc26c\uace0\ub3c4 \uc9d1\uc911\ud574\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac78 \ubcf4\uace0 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud559\uc2b5\uc5d0 \ub300\ud55c \uc5f4\uc815"),(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\uc801\uc73c\ub85c \uc54c\uace0 \uc2f6\uc740 \ubd80\ubd84\uc744 \ub530\ub85c \ud559\uc2b5\ud558\ub294 \uc5f4\uc815\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube44\ubc84\uc640 \uc2a4\ud504\ub9c1\uc5d0 \ub300\ud574 \uc54c\uc544\uac00\ub294 \uc2dc\uac04\uc744 \ub9ce\uc774 \uac00\uc9c4 \ubd80\ubd84\uc774 \ub9e4\uc6b0 \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 5\uc6d4\ubd80\ud130 \uc870\uae08 \ub354 \ud654\uc774\ud305 \ud574\uc57c\uaca0\ub2e4."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2244.3fbf946f.js b/assets/js/2244.3fbf946f.js new file mode 100644 index 000000000..4c07fa0f9 --- /dev/null +++ b/assets/js/2244.3fbf946f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2244],{52244:(t,e,s)=>{s.d(e,{D:()=>l,S:()=>c,a:()=>h,b:()=>a,c:()=>o,d:()=>B,p:()=>r,s:()=>P});var i=s(56363),n=function(){var t=function(t,e,s,i){for(s=s||{},i=t.length;i--;s[t[i]]=e);return s},e=[1,2],s=[1,3],i=[1,4],n=[2,4],r=[1,9],o=[1,11],a=[1,15],c=[1,16],l=[1,17],h=[1,18],u=[1,30],d=[1,19],p=[1,20],y=[1,21],f=[1,22],m=[1,23],g=[1,25],S=[1,26],_=[1,27],k=[1,28],T=[1,29],b=[1,32],E=[1,33],x=[1,34],C=[1,35],$=[1,31],v=[1,4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],D=[1,4,5,13,14,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],A=[4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],L={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,cssClassStatement:11,idStatement:12,DESCR:13,"--\x3e":14,HIDE_EMPTY:15,scale:16,WIDTH:17,COMPOSIT_STATE:18,STRUCT_START:19,STRUCT_STOP:20,STATE_DESCR:21,AS:22,ID:23,FORK:24,JOIN:25,CHOICE:26,CONCURRENT:27,note:28,notePosition:29,NOTE_TEXT:30,direction:31,acc_title:32,acc_title_value:33,acc_descr:34,acc_descr_value:35,acc_descr_multiline_value:36,classDef:37,CLASSDEF_ID:38,CLASSDEF_STYLEOPTS:39,DEFAULT:40,class:41,CLASSENTITY_IDS:42,STYLECLASS:43,direction_tb:44,direction_bt:45,direction_rl:46,direction_lr:47,eol:48,";":49,EDGE_STATE:50,STYLE_SEPARATOR:51,left_of:52,right_of:53,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",13:"DESCR",14:"--\x3e",15:"HIDE_EMPTY",16:"scale",17:"WIDTH",18:"COMPOSIT_STATE",19:"STRUCT_START",20:"STRUCT_STOP",21:"STATE_DESCR",22:"AS",23:"ID",24:"FORK",25:"JOIN",26:"CHOICE",27:"CONCURRENT",28:"note",30:"NOTE_TEXT",32:"acc_title",33:"acc_title_value",34:"acc_descr",35:"acc_descr_value",36:"acc_descr_multiline_value",37:"classDef",38:"CLASSDEF_ID",39:"CLASSDEF_STYLEOPTS",40:"DEFAULT",41:"class",42:"CLASSENTITY_IDS",43:"STYLECLASS",44:"direction_tb",45:"direction_bt",46:"direction_rl",47:"direction_lr",49:";",50:"EDGE_STATE",51:"STYLE_SEPARATOR",52:"left_of",53:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[10,3],[10,3],[11,3],[31,1],[31,1],[31,1],[31,1],[48,1],[48,1],[12,1],[12,1],[12,3],[12,3],[29,1],[29,1]],performAction:function(t,e,s,i,n,r,o){var a=r.length-1;switch(n){case 3:return i.setRootDoc(r[a]),r[a];case 4:this.$=[];break;case 5:"nl"!=r[a]&&(r[a-1].push(r[a]),this.$=r[a-1]);break;case 6:case 7:case 11:this.$=r[a];break;case 8:this.$="nl";break;case 12:const t=r[a-1];t.description=i.trimColon(r[a]),this.$=t;break;case 13:this.$={stmt:"relation",state1:r[a-2],state2:r[a]};break;case 14:const e=i.trimColon(r[a]);this.$={stmt:"relation",state1:r[a-3],state2:r[a-1],description:e};break;case 18:this.$={stmt:"state",id:r[a-3],type:"default",description:"",doc:r[a-1]};break;case 19:var c=r[a],l=r[a-2].trim();if(r[a].match(":")){var h=r[a].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 20:this.$={stmt:"state",id:r[a-3],type:"default",description:r[a-5],doc:r[a-1]};break;case 21:this.$={stmt:"state",id:r[a],type:"fork"};break;case 22:this.$={stmt:"state",id:r[a],type:"join"};break;case 23:this.$={stmt:"state",id:r[a],type:"choice"};break;case 24:this.$={stmt:"state",id:i.getDividerId(),type:"divider"};break;case 25:this.$={stmt:"state",id:r[a-1].trim(),note:{position:r[a-2].trim(),text:r[a].trim()}};break;case 28:this.$=r[a].trim(),i.setAccTitle(this.$);break;case 29:case 30:this.$=r[a].trim(),i.setAccDescription(this.$);break;case 31:case 32:this.$={stmt:"classDef",id:r[a-1].trim(),classes:r[a].trim()};break;case 33:this.$={stmt:"applyClass",id:r[a-1].trim(),styleClass:r[a].trim()};break;case 34:i.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 35:i.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 36:i.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 37:i.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 40:case 41:this.$={stmt:"state",id:r[a].trim(),type:"default",description:""};break;case 42:case 43:this.$={stmt:"state",id:r[a-2].trim(),classes:[r[a].trim()],type:"default",description:""}}},table:[{3:1,4:e,5:s,6:i},{1:[3]},{3:5,4:e,5:s,6:i},{3:6,4:e,5:s,6:i},t([1,4,5,15,16,18,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],n,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,5]),{9:36,10:12,11:13,12:14,15:a,16:c,18:l,21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,7]),t(v,[2,8]),t(v,[2,9]),t(v,[2,10]),t(v,[2,11],{13:[1,37],14:[1,38]}),t(v,[2,15]),{17:[1,39]},t(v,[2,17],{19:[1,40]}),{22:[1,41]},t(v,[2,21]),t(v,[2,22]),t(v,[2,23]),t(v,[2,24]),{29:42,30:[1,43],52:[1,44],53:[1,45]},t(v,[2,27]),{33:[1,46]},{35:[1,47]},t(v,[2,30]),{38:[1,48],40:[1,49]},{42:[1,50]},t(D,[2,40],{51:[1,51]}),t(D,[2,41],{51:[1,52]}),t(v,[2,34]),t(v,[2,35]),t(v,[2,36]),t(v,[2,37]),t(v,[2,6]),t(v,[2,12]),{12:53,23:u,50:$},t(v,[2,16]),t(A,n,{7:54}),{23:[1,55]},{23:[1,56]},{22:[1,57]},{23:[2,44]},{23:[2,45]},t(v,[2,28]),t(v,[2,29]),{39:[1,58]},{39:[1,59]},{43:[1,60]},{23:[1,61]},{23:[1,62]},t(v,[2,13],{13:[1,63]}),{4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,20:[1,64],21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,19],{19:[1,65]}),{30:[1,66]},{23:[1,67]},t(v,[2,31]),t(v,[2,32]),t(v,[2,33]),t(D,[2,42]),t(D,[2,43]),t(v,[2,14]),t(v,[2,18]),t(A,n,{7:68}),t(v,[2,25]),t(v,[2,26]),{4:r,5:o,8:8,9:10,10:12,11:13,12:14,15:a,16:c,18:l,20:[1,69],21:h,23:u,24:d,25:p,26:y,27:f,28:m,31:24,32:g,34:S,36:_,37:k,41:T,44:b,45:E,46:x,47:C,50:$},t(v,[2,20])],defaultActions:{5:[2,1],6:[2,2],44:[2,44],45:[2,45]},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],i=[],n=[null],r=[],o=this.table,a="",c=0,l=0,h=r.slice.call(arguments,1),u=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);u.setInput(t,d.yy),d.yy.lexer=u,d.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var y=u.yylloc;r.push(y);var f=u.options&&u.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var m,g,S,_,k,T,b,E,x,C={};;){if(g=s[s.length-1],this.defaultActions[g]?S=this.defaultActions[g]:(null==m&&(x=void 0,"number"!=typeof(x=i.pop()||u.lex()||1)&&(x instanceof Array&&(x=(i=x).pop()),x=e.symbols_[x]||x),m=x),S=o[g]&&o[g][m]),void 0===S||!S.length||!S[0]){var $="";for(k in E=[],o[g])this.terminals_[k]&&k>2&&E.push("'"+this.terminals_[k]+"'");$=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError($,{text:u.match,token:this.terminals_[m]||m,line:u.yylineno,loc:y,expected:E})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+m);switch(S[0]){case 1:s.push(m),n.push(u.yytext),r.push(u.yylloc),s.push(S[1]),m=null,l=u.yyleng,a=u.yytext,c=u.yylineno,y=u.yylloc;break;case 2:if(T=this.productions_[S[1]][1],C.$=n[n.length-T],C._$={first_line:r[r.length-(T||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(T||1)].first_column,last_column:r[r.length-1].last_column},f&&(C._$.range=[r[r.length-(T||1)].range[0],r[r.length-1].range[1]]),void 0!==(_=this.performAction.apply(C,[a,l,c,d.yy,S[1],n,r].concat(h))))return _;T&&(s=s.slice(0,-1*T*2),n=n.slice(0,-1*T),r=r.slice(0,-1*T)),s.push(this.productions_[S[1]][0]),n.push(C.$),r.push(C._$),b=o[s[s.length-2]][s[s.length-1]],s.push(b);break;case 3:return!0}}return!0}},I={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;re[0].length)){if(e=s,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,s,i){switch(s){case 0:return 40;case 1:case 39:return 44;case 2:case 40:return 45;case 3:case 41:return 46;case 4:case 42:return 47;case 5:case 6:case 8:case 9:case 10:case 11:case 51:case 53:case 59:break;case 7:case 74:return 5;case 12:case 29:return this.pushState("SCALE"),16;case 13:case 30:return 17;case 14:case 20:case 31:case 46:case 49:this.popState();break;case 15:return this.begin("acc_title"),32;case 16:return this.popState(),"acc_title_value";case 17:return this.begin("acc_descr"),34;case 18:return this.popState(),"acc_descr_value";case 19:this.begin("acc_descr_multiline");break;case 21:return"acc_descr_multiline_value";case 22:return this.pushState("CLASSDEF"),37;case 23:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 24:return this.popState(),this.pushState("CLASSDEFID"),38;case 25:return this.popState(),39;case 26:return this.pushState("CLASS"),41;case 27:return this.popState(),this.pushState("CLASS_STYLE"),42;case 28:return this.popState(),43;case 32:this.pushState("STATE");break;case 33:case 36:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),24;case 34:case 37:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 35:case 38:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),26;case 43:this.pushState("STATE_STRING");break;case 44:return this.pushState("STATE_ID"),"AS";case 45:case 61:return this.popState(),"ID";case 47:return"STATE_DESCR";case 48:return 18;case 50:return this.popState(),this.pushState("struct"),19;case 52:return this.popState(),20;case 54:return this.begin("NOTE"),28;case 55:return this.popState(),this.pushState("NOTE_ID"),52;case 56:return this.popState(),this.pushState("NOTE_ID"),53;case 57:this.popState(),this.pushState("FLOATING_NOTE");break;case 58:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 60:return"NOTE_TEXT";case 62:return this.popState(),this.pushState("NOTE_TEXT"),23;case 63:return this.popState(),e.yytext=e.yytext.substr(2).trim(),30;case 64:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),30;case 65:case 66:return 6;case 67:return 15;case 68:return 50;case 69:return 23;case 70:return e.yytext=e.yytext.trim(),13;case 71:return 14;case 72:return 27;case 73:return 51;case 75:return"INVALID"}},rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[9,10],inclusive:!1},struct:{rules:[9,10,22,26,32,39,40,41,42,51,52,53,54,68,69,70,71,72],inclusive:!1},FLOATING_NOTE_ID:{rules:[61],inclusive:!1},FLOATING_NOTE:{rules:[58,59,60],inclusive:!1},NOTE_TEXT:{rules:[63,64],inclusive:!1},NOTE_ID:{rules:[62],inclusive:!1},NOTE:{rules:[55,56,57],inclusive:!1},CLASS_STYLE:{rules:[28],inclusive:!1},CLASS:{rules:[27],inclusive:!1},CLASSDEFID:{rules:[25],inclusive:!1},CLASSDEF:{rules:[23,24],inclusive:!1},acc_descr_multiline:{rules:[20,21],inclusive:!1},acc_descr:{rules:[18],inclusive:!1},acc_title:{rules:[16],inclusive:!1},SCALE:{rules:[13,14,30,31],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[45],inclusive:!1},STATE_STRING:{rules:[46,47],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[9,10,33,34,35,36,37,38,43,44,48,49,50],inclusive:!1},ID:{rules:[9,10],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,10,11,12,15,17,19,22,26,29,32,50,54,65,66,67,68,69,70,71,73,74,75],inclusive:!0}}};function O(){this.yy={}}return L.lexer=I,O.prototype=L,L.Parser=O,new O}();n.parser=n;const r=n,o="TB",a="state",c="relation",l="default",h="divider",u="[*]",d="start",p=u,y="color",f="fill";let m="LR",g=[],S={};let _={root:{relations:[],states:{},documents:{}}},k=_.root,T=0,b=0;const E=t=>JSON.parse(JSON.stringify(t)),x=(t,e,s)=>{if(e.stmt===c)x(t,e.state1,!0),x(t,e.state2,!1);else if(e.stmt===a&&("[*]"===e.id?(e.id=s?t.id+"_start":t.id+"_end",e.start=s):e.id=e.id.trim()),e.doc){const t=[];let s,n=[];for(s=0;s0&&n.length>0){const s={stmt:a,id:(0,i.G)(),type:"divider",doc:E(n)};t.push(E(s)),e.doc=t}e.doc.forEach((t=>x(e,t,!0)))}},C=function(t,e=l,s=null,n=null,r=null,o=null,a=null,c=null){const h=null==t?void 0:t.trim();if(void 0===k.states[h]?(i.l.info("Adding state ",h,n),k.states[h]={id:h,descriptions:[],type:e,doc:s,note:r,classes:[],styles:[],textStyles:[]}):(k.states[h].doc||(k.states[h].doc=s),k.states[h].type||(k.states[h].type=e)),n&&(i.l.info("Setting state description",h,n),"string"==typeof n&&I(h,n.trim()),"object"==typeof n&&n.forEach((t=>I(h,t.trim())))),r&&(k.states[h].note=r,k.states[h].note.text=i.e.sanitizeText(k.states[h].note.text,(0,i.c)())),o){i.l.info("Setting state classes",h,o);("string"==typeof o?[o]:o).forEach((t=>N(h,t.trim())))}if(a){i.l.info("Setting state styles",h,a);("string"==typeof a?[a]:a).forEach((t=>R(h,t.trim())))}if(c){i.l.info("Setting state styles",h,a);("string"==typeof c?[c]:c).forEach((t=>w(h,t.trim())))}},$=function(t){_={root:{relations:[],states:{},documents:{}}},k=_.root,T=0,S={},t||(0,i.t)()},v=function(t){return k.states[t]};function D(t=""){let e=t;return t===u&&(T++,e=`${d}${T}`),e}function A(t="",e=l){return t===u?d:e}const L=function(t,e,s){if("object"==typeof t)!function(t,e,s){let n=D(t.id.trim()),r=A(t.id.trim(),t.type),o=D(e.id.trim()),a=A(e.id.trim(),e.type);C(n,r,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles),C(o,a,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),k.relations.push({id1:n,id2:o,relationTitle:i.e.sanitizeText(s,(0,i.c)())})}(t,e,s);else{const n=D(t.trim()),r=A(t),o=function(t=""){let e=t;return t===p&&(T++,e=`end${T}`),e}(e.trim()),a=function(t="",e=l){return t===p?"end":e}(e);C(n,r),C(o,a),k.relations.push({id1:n,id2:o,title:i.e.sanitizeText(s,(0,i.c)())})}},I=function(t,e){const s=k.states[t],n=e.startsWith(":")?e.replace(":","").trim():e;s.descriptions.push(i.e.sanitizeText(n,(0,i.c)()))},O=function(t,e=""){void 0===S[t]&&(S[t]={id:t,styles:[],textStyles:[]});const s=S[t];null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(t.match(y)){const t=e.replace(f,"bgFill").replace(y,f);s.textStyles.push(t)}s.styles.push(e)}))},N=function(t,e){t.split(",").forEach((function(t){let s=v(t);if(void 0===s){const e=t.trim();C(e),s=v(e)}s.classes.push(e)}))},R=function(t,e){const s=v(t);void 0!==s&&s.textStyles.push(e)},w=function(t,e){const s=v(t);void 0!==s&&s.textStyles.push(e)},B={getConfig:()=>(0,i.c)().state,addState:C,clear:$,getState:v,getStates:function(){return k.states},getRelations:function(){return k.relations},getClasses:function(){return S},getDirection:()=>m,addRelation:L,getDividerId:()=>(b++,"divider-id-"+b),setDirection:t=>{m=t},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:function(){i.l.info("Documents = ",_)},getRootDoc:()=>g,setRootDoc:t=>{i.l.info("Setting root doc",t),g=t},getRootDocV2:()=>(x({id:"root"},{id:"root",doc:g},!0),{id:"root",doc:g}),extract:t=>{let e;e=t.doc?t.doc:t,i.l.info(e),$(!0),i.l.info("Extract",e),e.forEach((t=>{switch(t.stmt){case a:C(t.id.trim(),t.type,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles);break;case c:L(t.state1,t.state2,t.description);break;case"classDef":O(t.id.trim(),t.classes);break;case"applyClass":N(t.id.trim(),t.styleClass)}}))},trimColon:t=>t&&":"===t[0]?t.substr(1).trim():t.trim(),getAccTitle:i.g,setAccTitle:i.s,getAccDescription:i.a,setAccDescription:i.b,addStyleClass:O,setCssClass:N,addDescription:I,setDiagramTitle:i.q,getDiagramTitle:i.r},P=t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`}}]); \ No newline at end of file diff --git a/assets/js/24b9bc70.6793a550.js b/assets/js/24b9bc70.6793a550.js new file mode 100644 index 000000000..0f5fef603 --- /dev/null +++ b/assets/js/24b9bc70.6793a550.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5798],{58346:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>o});var r=n(85893),s=n(3905);const i={title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",slug:"test-double",tags:["Test","Mock"]},l=void 0,c={permalink:"/test-double",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",source:"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",description:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?",date:"2023-04-04T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 4\uc77c",tags:[{label:"Test",permalink:"/tags/test"},{label:"Mock",permalink:"/tags/mock"}],readingTime:4.52,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",slug:"test-double",tags:["Test","Mock"]},unlisted:!1,prevItem:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",permalink:"/transaction-and-isolation"},nextItem:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",permalink:"/java-class-file"}},d={authorsImageUrls:[]},o=[{value:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?",id:"\ud14c\uc2a4\ud2b8-\ub300\uc5ed\uc774\ub780",level:3},{value:"\ub354\ubbf8(Dummy)",id:"\ub354\ubbf8dummy",level:3},{value:"\uc2a4\ud141(Stub)",id:"\uc2a4\ud141stub",level:3},{value:"\uc2a4\ud30c\uc774(Spy)",id:"\uc2a4\ud30c\uc774spy",level:3},{value:"\ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)",id:"\ubaa9-\ubaa8\uc758-\uac1d\uccb4mock",level:3},{value:"\uac00\uc9dc(Fake)",id:"\uac00\uc9dcfake",level:3},{value:"\uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84",id:"\uc0c1\ud638\uc791\uc6a9\uc5d0-\ub530\ub978-\ubaa9\uacfc-\uc2a4\ud141-\uad6c\ubd84",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function a(e){const t={a:"a",admonition:"admonition",br:"br",h3:"h3",mermaid:"mermaid",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"\ud14c\uc2a4\ud2b8-\ub300\uc5ed\uc774\ub780",children:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?"}),"\n",(0,r.jsxs)(t.p,{children:["\ubaa8\ub4e0 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \uac00\uc9dc \uc758\uc874\uc131\uc744 \uc758\ubbf8\ud558\uace0, \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud589\ub420 \ub54c \ub2e4\ub978 \uac1d\uccb4\ub97c \ub300\uc2e0\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","Gerard Meszaros\uc758 xUnit Test Patterns\ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ub2e4\uc12f \uac00\uc9c0(\ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774, \ubaa9, \ud398\uc774\ud06c)\ub85c \uad6c\ubd84\ud55c\ub2e4."]}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \uae30\ubcf8 \uba54\ucee4\ub2c8\uc998\uc740 \ub2e4\ud615\uc131\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc678\ubd80 \uc11c\ube44\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uacbd\uc6b0, \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc815\uc758\ud558\uace0 \uc678\ubd80 \uc11c\ube44\uc2a4 \ub300\uc2e0 \ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\uc758 \uad6c\ud604\uccb4\ub97c \uc0dd\uc131\ud558\ub294 \uac83\uc774\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.strong,{children:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \ud0c0\uc785 \uacc4\uce35 \uad6c\uc870"})}),"\n",(0,r.jsx)(t.mermaid,{value:"flowchart LR\n Mock --\x3e Spy --\x3e Stub --\x3e Dummy --\x3e TestDouble\n Fake --\x3e TestDouble"}),"\n",(0,r.jsx)(t.h3,{id:"\ub354\ubbf8dummy",children:"\ub354\ubbf8(Dummy)"}),"\n",(0,r.jsxs)(t.p,{children:["\uac00\uc7a5 \ub2e8\uc21c\ud558\uace0, \uc6d0\uc2dc\uc801\uc778 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c \uc544\ubb34 \uc77c\ub3c4 \ud558\uc9c0 \uc54a\ub294 \uad6c\ud604\uccb4\ub85c \uc778\uc2a4\ud134\uc2a4\ud654\uac00 \ud544\uc694\ud55c \uacbd\uc6b0 \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub9cc\uc57d \uba54\uc11c\ub4dc\uac00 \ubb34\uc5b8\uac00 \ubc18\ud658\uc744 \ud574\uc57c\ud558\ub294 \uacbd\uc6b0 0, null\uacfc \uac19\uc740 \uac12\uc744 \ubc18\ud658\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ud141stub",children:"\uc2a4\ud141(Stub)"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2dc\ub098\ub9ac\uc624\ub9c8\ub2e4 \ub2e4\ub978 \uac12(\ubbf8\ub9ac \uc900\ube44 \ub41c \uacb0\uacfc)\uc744 \ubc18\ud658\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub97c \ud1b5\ud574 \ud2b9\uc815 \uc870\uac74\uc5d0\uc11c \uba54\uc11c\ub4dc\uac00 \uc608\uc0c1\ud55c\ub300\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ud30c\uc774spy",children:"\uc2a4\ud30c\uc774(Spy)"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2a4\ud141\uacfc \uc720\uc0ac\ud558\uc9c0\ub9cc \ud638\ucd9c \uc5ec\ubd80\ub97c \uae30\ub85d\ud558\uac70\ub098 \ud638\ucd9c\ud560 \ub54c \uc804\ub2ec\ud55c \uc778\uc790\uac12\uc744 \uae30\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc608) \uba54\uc77c \uc804\uc1a1 \uae30\ub2a5\uc744 \uac00\uc9c4 \uac1d\uccb4\ub97c \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc73c\ub85c \uad6c\ud604\ud588\uc744 \ub54c \uba54\uc77c \uc804\uc1a1 \ud69f\uc218\ub97c \uae30\ub85d\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ubaa9-\ubaa8\uc758-\uac1d\uccb4mock",children:"\ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)"}),"\n",(0,r.jsxs)(t.p,{children:["\ubaa9\uc740 \ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774\ub97c \ud3ec\ud568\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud638\ucd9c \uc2dc \uc0ac\uc804\uc5d0 \uc815\uc758\ub41c \uacb0\uacfc\ub97c \ubc18\ud658\ud558\uace0, \uc608\uc0c1\uce58 \ubabb\ud55c \ud638\ucd9c\uc774 \uc788\uc744 \uacbd\uc6b0 \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub610\ud55c \ud638\ucd9c\uc5d0 \ub300\ud55c \uac80\uc99d\uc744 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uac00\uc9dcfake",children:"\uac00\uc9dc(Fake)"}),"\n",(0,r.jsxs)(t.p,{children:["DOC\uc640 \ub3d9\uc77c\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\uc9c0\ub9cc, \ub354\uc6b1 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ub41c \uac83\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc608) \uc2e4\uc81c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc720\uc0ac\ud558\uac8c \ub3d9\uc791\ud558\ub294 \uac00\uc9dc \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.admonition,{title:"DOC(depended-on component)",type:"note",children:(0,r.jsxs)(t.p,{children:["\uc758\uc874 \uad6c\uc131 \uc694\uc18c, DOC\ub97c \ud14c\uc2a4\ud2b8 \ub354\ube14\ub85c \ub300\uccb4\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud14c\uc2a4\ud2b8 \ub354\ube14\uc740 DOC\uc640 \ub3d9\uc77c\ud55c API\ub97c \uc81c\uacf5\ud574\uc57c \ud55c\ub2e4."]})}),"\n",(0,r.jsx)(t.h3,{id:"\uc0c1\ud638\uc791\uc6a9\uc5d0-\ub530\ub978-\ubaa9\uacfc-\uc2a4\ud141-\uad6c\ubd84",children:"\uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84"}),"\n",(0,r.jsxs)(t.p,{children:["\ub2e8\uc704 \ud14c\uc2a4\ud2b8 p.149 \uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ud06c\uac8c \ubaa9\uacfc \uc2a4\ud141\uc73c\ub85c \uad6c\ubd84\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ubaa9\uc740 SUT\uc640 \uad00\ub828\ub41c \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ubc18\uba74, \uc2a4\ud141\uc740 \ub2e8\uc21c \ubaa8\ubc29\ub9cc \ud55c\ub2e4."]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"TestDouble"}),(0,r.jsx)(t.th,{children:"Mock"}),(0,r.jsx)(t.th,{children:"Stub"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"\ud3ec\ud568 \uc720\ud615"}),(0,r.jsx)(t.td,{children:"\ubaa9, \uc2a4\ud30c\uc774"}),(0,r.jsx)(t.td,{children:"\uc2a4\ud141, \ub354\ubbf8, \ud398\uc774\ud06c"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"\uc6a9\ub3c4"}),(0,r.jsx)(t.td,{children:"\uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ub370 \uc0ac\uc6a9"}),(0,r.jsx)(t.td,{children:"\ub0b4\ubd80\ub85c \ub4e4\uc5b4\uc624\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\ub294 \ub370 \uc0ac\uc6a9"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"\uc124\uba85"}),(0,r.jsx)(t.td,{children:"SUT\uac00 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9"}),(0,r.jsx)(t.td,{children:"SUT\uac00 \uc785\ub825 \ub370\uc774\ud130\ub97c \uc5bb\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"\uc608\uc2dc"}),(0,r.jsx)(t.td,{children:"\uc774\uba54\uc77c \ubc1c\uc1a1"}),(0,r.jsx)(t.td,{children:"\ub370\uc774\ud130 \uac80\uc0c9"})]})]})]}),"\n",(0,r.jsx)(t.admonition,{title:"SUT(system under test)",type:"note",children:(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8 \ub300\uc0c1 \uc2dc\uc2a4\ud15c",(0,r.jsx)(t.br,{}),"\n","\ud14c\uc2a4\ud2b8\ub97c \ud558\ub824\ub294 \ub300\uc0c1"]})}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:["\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30 - 3\uc7a5 \uace0\uae09 \ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4",(0,r.jsx)(t.br,{}),"\n","\ub2e8\uc704 \ud14c\uc2a4\ud2b8 - 5\uc7a5 \ubaa9\uacfc \ud14c\uc2a4\ud2b8 \ucde8\uc57d\uc131, \ube14\ub77c\ub514\ubbf8\ub974 \ucf54\ub9ac\ucf54\ud504",(0,r.jsx)(t.br,{}),"\n","\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uc2dc\uc791\ud558\uae30 - 7\uc7a5 \ub300\uc5ed, \ucd5c\ubc94\uade0",(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://www.martinfowler.com/bliki/TestDouble.html",children:"\ud14c\uc2a4\ud2b8 \ub354\ube14, Martin Fowler"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://johngrib.github.io/wiki/test-terms/",children:"\ud14c\uc2a4\ud2b8 \uad00\ub828 \uc6a9\uc5b4 \uc815\ub9ac, Johngrib"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"http://xunitpatterns.com/Test%20Double.html",children:"Test Double, Gerard Meszaros"})]})]})}function h(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>o});var r=n(67294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var d=r.createContext({}),o=function(e){var t=r.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},a={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,d=e.parentName,h=c(e,["components","mdxType","originalType","parentName"]),j=o(n),x=s,u=j["".concat(d,".").concat(x)]||j[x]||a[x]||i;return n?r.createElement(u,l(l({ref:t},h),{},{components:n})):r.createElement(u,l({ref:t},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/24b9bc70.680ac376.js b/assets/js/24b9bc70.680ac376.js deleted file mode 100644 index 2e3aa2a68..000000000 --- a/assets/js/24b9bc70.680ac376.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5798],{3905:(t,e,n)=>{n.d(e,{Zo:()=>u,kt:()=>c});var r=n(67294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function p(t){for(var e=1;e=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var i=r.createContext({}),m=function(t){var e=r.useContext(i),n=e;return t&&(n="function"==typeof t?t(e):p(p({},e),t)),n},u=function(t){var e=m(t.components);return r.createElement(i.Provider,{value:e},t.children)},k={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},s=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,l=t.originalType,i=t.parentName,u=o(t,["components","mdxType","originalType","parentName"]),s=m(n),c=a,d=s["".concat(i,".").concat(c)]||s[c]||k[c]||l;return n?r.createElement(d,p(p({ref:e},u),{},{components:n})):r.createElement(d,p({ref:e},u))}));function c(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var l=n.length,p=new Array(l);p[0]=s;var o={};for(var i in e)hasOwnProperty.call(e,i)&&(o[i]=e[i]);o.originalType=t,o.mdxType="string"==typeof t?t:a,p[1]=o;for(var m=2;m{n.r(e),n.d(e,{assets:()=>i,contentTitle:()=>p,default:()=>k,frontMatter:()=>l,metadata:()=>o,toc:()=>m});var r=n(87462),a=(n(67294),n(3905));const l={title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",slug:"test-double",tags:["Test","Mock"]},p=void 0,o={permalink:"/test-double",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",source:"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",description:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?",date:"2023-04-04T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 4\uc77c",tags:[{label:"Test",permalink:"/tags/test"},{label:"Mock",permalink:"/tags/mock"}],readingTime:4.52,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",slug:"test-double",tags:["Test","Mock"]},prevItem:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",permalink:"/transaction-and-isolation"},nextItem:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",permalink:"/java-class-file"}},i={authorsImageUrls:[]},m=[{value:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?",id:"\ud14c\uc2a4\ud2b8-\ub300\uc5ed\uc774\ub780",level:3},{value:"\ub354\ubbf8(Dummy)",id:"\ub354\ubbf8dummy",level:3},{value:"\uc2a4\ud141(Stub)",id:"\uc2a4\ud141stub",level:3},{value:"\uc2a4\ud30c\uc774(Spy)",id:"\uc2a4\ud30c\uc774spy",level:3},{value:"\ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)",id:"\ubaa9-\ubaa8\uc758-\uac1d\uccb4mock",level:3},{value:"\uac00\uc9dc(Fake)",id:"\uac00\uc9dcfake",level:3},{value:"\uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84",id:"\uc0c1\ud638\uc791\uc6a9\uc5d0-\ub530\ub978-\ubaa9\uacfc-\uc2a4\ud141-\uad6c\ubd84",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:m};function k(t){let{components:e,...n}=t;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ud14c\uc2a4\ud2b8-\ub300\uc5ed\uc774\ub780"},"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?"),(0,a.kt)("p",null,"\ubaa8\ub4e0 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \uac00\uc9dc \uc758\uc874\uc131\uc744 \uc758\ubbf8\ud558\uace0, \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud589\ub420 \ub54c \ub2e4\ub978 \uac1d\uccb4\ub97c \ub300\uc2e0\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Gerard Meszaros\uc758 xUnit Test Patterns\ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ub2e4\uc12f \uac00\uc9c0(\ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774, \ubaa9, \ud398\uc774\ud06c)\ub85c \uad6c\ubd84\ud55c\ub2e4."),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \uae30\ubcf8 \uba54\ucee4\ub2c8\uc998\uc740 \ub2e4\ud615\uc131\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc678\ubd80 \uc11c\ube44\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uacbd\uc6b0, \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc815\uc758\ud558\uace0 \uc678\ubd80 \uc11c\ube44\uc2a4 \ub300\uc2e0 \ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\uc758 \uad6c\ud604\uccb4\ub97c \uc0dd\uc131\ud558\ub294 \uac83\uc774\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \ud0c0\uc785 \uacc4\uce35 \uad6c\uc870")),(0,a.kt)("mermaid",{value:"flowchart LR\n Mock --\x3e Spy --\x3e Stub --\x3e Dummy --\x3e TestDouble\n Fake --\x3e TestDouble"}),(0,a.kt)("h3",{id:"\ub354\ubbf8dummy"},"\ub354\ubbf8(Dummy)"),(0,a.kt)("p",null,"\uac00\uc7a5 \ub2e8\uc21c\ud558\uace0, \uc6d0\uc2dc\uc801\uc778 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c \uc544\ubb34 \uc77c\ub3c4 \ud558\uc9c0 \uc54a\ub294 \uad6c\ud604\uccb4\ub85c \uc778\uc2a4\ud134\uc2a4\ud654\uac00 \ud544\uc694\ud55c \uacbd\uc6b0 \uc0ac\uc6a9\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9cc\uc57d \uba54\uc11c\ub4dc\uac00 \ubb34\uc5b8\uac00 \ubc18\ud658\uc744 \ud574\uc57c\ud558\ub294 \uacbd\uc6b0 0, null\uacfc \uac19\uc740 \uac12\uc744 \ubc18\ud658\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc2a4\ud141stub"},"\uc2a4\ud141(Stub)"),(0,a.kt)("p",null,"\uc2dc\ub098\ub9ac\uc624\ub9c8\ub2e4 \ub2e4\ub978 \uac12(\ubbf8\ub9ac \uc900\ube44 \ub41c \uacb0\uacfc)\uc744 \ubc18\ud658\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c \ud1b5\ud574 \ud2b9\uc815 \uc870\uac74\uc5d0\uc11c \uba54\uc11c\ub4dc\uac00 \uc608\uc0c1\ud55c\ub300\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\uc2a4\ud30c\uc774spy"},"\uc2a4\ud30c\uc774(Spy)"),(0,a.kt)("p",null,"\uc2a4\ud141\uacfc \uc720\uc0ac\ud558\uc9c0\ub9cc \ud638\ucd9c \uc5ec\ubd80\ub97c \uae30\ub85d\ud558\uac70\ub098 \ud638\ucd9c\ud560 \ub54c \uc804\ub2ec\ud55c \uc778\uc790\uac12\uc744 \uae30\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608) \uba54\uc77c \uc804\uc1a1 \uae30\ub2a5\uc744 \uac00\uc9c4 \uac1d\uccb4\ub97c \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc73c\ub85c \uad6c\ud604\ud588\uc744 \ub54c \uba54\uc77c \uc804\uc1a1 \ud69f\uc218\ub97c \uae30\ub85d\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ubaa9-\ubaa8\uc758-\uac1d\uccb4mock"},"\ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)"),(0,a.kt)("p",null,"\ubaa9\uc740 \ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774\ub97c \ud3ec\ud568\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud638\ucd9c \uc2dc \uc0ac\uc804\uc5d0 \uc815\uc758\ub41c \uacb0\uacfc\ub97c \ubc18\ud658\ud558\uace0, \uc608\uc0c1\uce58 \ubabb\ud55c \ud638\ucd9c\uc774 \uc788\uc744 \uacbd\uc6b0 \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ud638\ucd9c\uc5d0 \ub300\ud55c \uac80\uc99d\uc744 \ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\uac00\uc9dcfake"},"\uac00\uc9dc(Fake)"),(0,a.kt)("p",null,"DOC\uc640 \ub3d9\uc77c\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\uc9c0\ub9cc, \ub354\uc6b1 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ub41c \uac83\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608) \uc2e4\uc81c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc720\uc0ac\ud558\uac8c \ub3d9\uc791\ud558\ub294 \uac00\uc9dc \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("admonition",{title:"DOC(depended-on component)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\uc758\uc874 \uad6c\uc131 \uc694\uc18c, DOC\ub97c \ud14c\uc2a4\ud2b8 \ub354\ube14\ub85c \ub300\uccb4\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc2a4\ud2b8 \ub354\ube14\uc740 DOC\uc640 \ub3d9\uc77c\ud55c API\ub97c \uc81c\uacf5\ud574\uc57c \ud55c\ub2e4. ")),(0,a.kt)("h3",{id:"\uc0c1\ud638\uc791\uc6a9\uc5d0-\ub530\ub978-\ubaa9\uacfc-\uc2a4\ud141-\uad6c\ubd84"},"\uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84"),(0,a.kt)("p",null,"\ub2e8\uc704 \ud14c\uc2a4\ud2b8 p.149 \uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ud06c\uac8c \ubaa9\uacfc \uc2a4\ud141\uc73c\ub85c \uad6c\ubd84\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubaa9\uc740 SUT\uc640 \uad00\ub828\ub41c \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ubc18\uba74, \uc2a4\ud141\uc740 \ub2e8\uc21c \ubaa8\ubc29\ub9cc \ud55c\ub2e4. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"TestDouble"),(0,a.kt)("th",{parentName:"tr",align:null},"Mock"),(0,a.kt)("th",{parentName:"tr",align:null},"Stub"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ud3ec\ud568 \uc720\ud615"),(0,a.kt)("td",{parentName:"tr",align:null},"\ubaa9, \uc2a4\ud30c\uc774"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc2a4\ud141, \ub354\ubbf8, \ud398\uc774\ud06c")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc6a9\ub3c4"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ub370 \uc0ac\uc6a9"),(0,a.kt)("td",{parentName:"tr",align:null},"\ub0b4\ubd80\ub85c \ub4e4\uc5b4\uc624\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\ub294 \ub370 \uc0ac\uc6a9")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc124\uba85"),(0,a.kt)("td",{parentName:"tr",align:null},"SUT\uac00 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9"),(0,a.kt)("td",{parentName:"tr",align:null},"SUT\uac00 \uc785\ub825 \ub370\uc774\ud130\ub97c \uc5bb\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc608\uc2dc"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc774\uba54\uc77c \ubc1c\uc1a1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ub370\uc774\ud130 \uac80\uc0c9")))),(0,a.kt)("admonition",{title:"SUT(system under test)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ud14c\uc2a4\ud2b8 \ub300\uc0c1 \uc2dc\uc2a4\ud15c",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc2a4\ud2b8\ub97c \ud558\ub824\ub294 \ub300\uc0c1")),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30 - 3\uc7a5 \uace0\uae09 \ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc704 \ud14c\uc2a4\ud2b8 - 5\uc7a5 \ubaa9\uacfc \ud14c\uc2a4\ud2b8 \ucde8\uc57d\uc131, \ube14\ub77c\ub514\ubbf8\ub974 \ucf54\ub9ac\ucf54\ud504",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uc2dc\uc791\ud558\uae30 - 7\uc7a5 \ub300\uc5ed, \ucd5c\ubc94\uade0",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.martinfowler.com/bliki/TestDouble.html"},"\ud14c\uc2a4\ud2b8 \ub354\ube14, Martin Fowler"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://johngrib.github.io/wiki/test-terms/"},"\ud14c\uc2a4\ud2b8 \uad00\ub828 \uc6a9\uc5b4 \uc815\ub9ac, Johngrib"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"http://xunitpatterns.com/Test%20Double.html"},"Test Double, Gerard Meszaros")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/254.da0a5da3.js b/assets/js/254.da0a5da3.js new file mode 100644 index 000000000..f4627d832 --- /dev/null +++ b/assets/js/254.da0a5da3.js @@ -0,0 +1,1227 @@ +"use strict"; +exports.id = 254; +exports.ids = [254]; +exports.modules = { + +/***/ 86254: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 3], $V1 = [1, 4], $V2 = [1, 5], $V3 = [1, 6], $V4 = [1, 7], $V5 = [1, 5, 13, 15, 17, 19, 20, 25, 27, 28, 29, 30, 31, 32, 33, 34, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], $V6 = [1, 5, 6, 13, 15, 17, 19, 20, 25, 27, 28, 29, 30, 31, 32, 33, 34, 37, 38, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], $V7 = [32, 33, 34], $V8 = [2, 7], $V9 = [1, 13], $Va = [1, 17], $Vb = [1, 18], $Vc = [1, 19], $Vd = [1, 20], $Ve = [1, 21], $Vf = [1, 22], $Vg = [1, 23], $Vh = [1, 24], $Vi = [1, 25], $Vj = [1, 26], $Vk = [1, 27], $Vl = [1, 30], $Vm = [1, 31], $Vn = [1, 32], $Vo = [1, 33], $Vp = [1, 34], $Vq = [1, 35], $Vr = [1, 36], $Vs = [1, 37], $Vt = [1, 38], $Vu = [1, 39], $Vv = [1, 40], $Vw = [1, 41], $Vx = [1, 42], $Vy = [1, 57], $Vz = [1, 58], $VA = [5, 22, 26, 32, 33, 34, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "eol": 4, "SPACE": 5, "QUADRANT": 6, "document": 7, "line": 8, "statement": 9, "axisDetails": 10, "quadrantDetails": 11, "points": 12, "title": 13, "title_value": 14, "acc_title": 15, "acc_title_value": 16, "acc_descr": 17, "acc_descr_value": 18, "acc_descr_multiline_value": 19, "section": 20, "text": 21, "point_start": 22, "point_x": 23, "point_y": 24, "X-AXIS": 25, "AXIS-TEXT-DELIMITER": 26, "Y-AXIS": 27, "QUADRANT_1": 28, "QUADRANT_2": 29, "QUADRANT_3": 30, "QUADRANT_4": 31, "NEWLINE": 32, "SEMI": 33, "EOF": 34, "alphaNumToken": 35, "textNoTagsToken": 36, "STR": 37, "MD_STR": 38, "alphaNum": 39, "PUNCTUATION": 40, "AMP": 41, "NUM": 42, "ALPHA": 43, "COMMA": 44, "PLUS": 45, "EQUALS": 46, "MULT": 47, "DOT": 48, "BRKT": 49, "UNDERSCORE": 50, "MINUS": 51, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "SPACE", 6: "QUADRANT", 13: "title", 14: "title_value", 15: "acc_title", 16: "acc_title_value", 17: "acc_descr", 18: "acc_descr_value", 19: "acc_descr_multiline_value", 20: "section", 22: "point_start", 23: "point_x", 24: "point_y", 25: "X-AXIS", 26: "AXIS-TEXT-DELIMITER", 27: "Y-AXIS", 28: "QUADRANT_1", 29: "QUADRANT_2", 30: "QUADRANT_3", 31: "QUADRANT_4", 32: "NEWLINE", 33: "SEMI", 34: "EOF", 37: "STR", 38: "MD_STR", 40: "PUNCTUATION", 41: "AMP", 42: "NUM", 43: "ALPHA", 44: "COMMA", 45: "PLUS", 46: "EQUALS", 47: "MULT", 48: "DOT", 49: "BRKT", 50: "UNDERSCORE", 51: "MINUS" }, + productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [9, 0], [9, 2], [9, 1], [9, 1], [9, 1], [9, 2], [9, 2], [9, 2], [9, 1], [9, 1], [12, 4], [10, 4], [10, 3], [10, 2], [10, 4], [10, 3], [10, 2], [11, 2], [11, 2], [11, 2], [11, 2], [4, 1], [4, 1], [4, 1], [21, 1], [21, 2], [21, 1], [21, 1], [39, 1], [39, 2], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [35, 1], [36, 1], [36, 1], [36, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 12: + this.$ = $$[$0].trim(); + yy.setDiagramTitle(this.$); + break; + case 13: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 14: + case 15: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 16: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 17: + yy.addPoint($$[$0 - 3], $$[$0 - 1], $$[$0]); + break; + case 18: + yy.setXAxisLeftText($$[$0 - 2]); + yy.setXAxisRightText($$[$0]); + break; + case 19: + $$[$0 - 1].text += " ⟶ "; + yy.setXAxisLeftText($$[$0 - 1]); + break; + case 20: + yy.setXAxisLeftText($$[$0]); + break; + case 21: + yy.setYAxisBottomText($$[$0 - 2]); + yy.setYAxisTopText($$[$0]); + break; + case 22: + $$[$0 - 1].text += " ⟶ "; + yy.setYAxisBottomText($$[$0 - 1]); + break; + case 23: + yy.setYAxisBottomText($$[$0]); + break; + case 24: + yy.setQuadrant1Text($$[$0]); + break; + case 25: + yy.setQuadrant2Text($$[$0]); + break; + case 26: + yy.setQuadrant3Text($$[$0]); + break; + case 27: + yy.setQuadrant4Text($$[$0]); + break; + case 31: + this.$ = { text: $$[$0], type: "text" }; + break; + case 32: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 33: + this.$ = { text: $$[$0], type: "text" }; + break; + case 34: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 35: + this.$ = $$[$0]; + break; + case 36: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: $V0, 6: $V1, 32: $V2, 33: $V3, 34: $V4 }, { 1: [3] }, { 3: 8, 4: 2, 5: $V0, 6: $V1, 32: $V2, 33: $V3, 34: $V4 }, { 3: 9, 4: 2, 5: $V0, 6: $V1, 32: $V2, 33: $V3, 34: $V4 }, o($V5, [2, 4], { 7: 10 }), o($V6, [2, 28]), o($V6, [2, 29]), o($V6, [2, 30]), { 1: [2, 1] }, { 1: [2, 2] }, o($V7, $V8, { 8: 11, 9: 12, 10: 14, 11: 15, 12: 16, 21: 28, 35: 29, 1: [2, 3], 5: $V9, 13: $Va, 15: $Vb, 17: $Vc, 19: $Vd, 20: $Ve, 25: $Vf, 27: $Vg, 28: $Vh, 29: $Vi, 30: $Vj, 31: $Vk, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }), o($V5, [2, 5]), { 4: 43, 32: $V2, 33: $V3, 34: $V4 }, o($V7, $V8, { 10: 14, 11: 15, 12: 16, 21: 28, 35: 29, 9: 44, 5: $V9, 13: $Va, 15: $Vb, 17: $Vc, 19: $Vd, 20: $Ve, 25: $Vf, 27: $Vg, 28: $Vh, 29: $Vi, 30: $Vj, 31: $Vk, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }), o($V7, [2, 9]), o($V7, [2, 10]), o($V7, [2, 11]), { 14: [1, 45] }, { 16: [1, 46] }, { 18: [1, 47] }, o($V7, [2, 15]), o($V7, [2, 16]), { 21: 48, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 49, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 50, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 51, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 52, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 21: 53, 35: 29, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }, { 5: $Vy, 22: [1, 54], 35: 56, 36: 55, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }, o($VA, [2, 31]), o($VA, [2, 33]), o($VA, [2, 34]), o($VA, [2, 37]), o($VA, [2, 38]), o($VA, [2, 39]), o($VA, [2, 40]), o($VA, [2, 41]), o($VA, [2, 42]), o($VA, [2, 43]), o($VA, [2, 44]), o($VA, [2, 45]), o($VA, [2, 46]), o($VA, [2, 47]), o($V5, [2, 6]), o($V7, [2, 8]), o($V7, [2, 12]), o($V7, [2, 13]), o($V7, [2, 14]), o($V7, [2, 20], { 36: 55, 35: 56, 5: $Vy, 26: [1, 59], 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 23], { 36: 55, 35: 56, 5: $Vy, 26: [1, 60], 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 24], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 25], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 26], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 27], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), { 23: [1, 61] }, o($VA, [2, 32]), o($VA, [2, 48]), o($VA, [2, 49]), o($VA, [2, 50]), o($V7, [2, 19], { 35: 29, 21: 62, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }), o($V7, [2, 22], { 35: 29, 21: 63, 37: $Vl, 38: $Vm, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx }), { 24: [1, 64] }, o($V7, [2, 18], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 21], { 36: 55, 35: 56, 5: $Vy, 40: $Vn, 41: $Vo, 42: $Vp, 43: $Vq, 44: $Vr, 45: $Vs, 46: $Vt, 47: $Vu, 48: $Vv, 49: $Vw, 50: $Vx, 51: $Vz }), o($V7, [2, 17])], + defaultActions: { 8: [2, 1], 9: [2, 2] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + return 32; + case 3: + break; + case 4: + this.begin("title"); + return 13; + case 5: + this.popState(); + return "title_value"; + case 6: + this.begin("acc_title"); + return 15; + case 7: + this.popState(); + return "acc_title_value"; + case 8: + this.begin("acc_descr"); + return 17; + case 9: + this.popState(); + return "acc_descr_value"; + case 10: + this.begin("acc_descr_multiline"); + break; + case 11: + this.popState(); + break; + case 12: + return "acc_descr_multiline_value"; + case 13: + return 25; + case 14: + return 27; + case 15: + return 26; + case 16: + return 28; + case 17: + return 29; + case 18: + return 30; + case 19: + return 31; + case 20: + this.begin("md_string"); + break; + case 21: + return "MD_STR"; + case 22: + this.popState(); + break; + case 23: + this.begin("string"); + break; + case 24: + this.popState(); + break; + case 25: + return "STR"; + case 26: + this.begin("point_start"); + return 22; + case 27: + this.begin("point_x"); + return 23; + case 28: + this.popState(); + break; + case 29: + this.popState(); + this.begin("point_y"); + break; + case 30: + this.popState(); + return 24; + case 31: + return 6; + case 32: + return 43; + case 33: + return "COLON"; + case 34: + return 45; + case 35: + return 44; + case 36: + return 46; + case 37: + return 46; + case 38: + return 47; + case 39: + return 49; + case 40: + return 50; + case 41: + return 48; + case 42: + return 41; + case 43: + return 51; + case 44: + return 42; + case 45: + return 5; + case 46: + return 33; + case 47: + return 40; + case 48: + return 34; + } + }, + rules: [/^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n\r]+)/i, /^(?:%%[^\n]*)/i, /^(?:title\b)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?: *x-axis *)/i, /^(?: *y-axis *)/i, /^(?: *--+> *)/i, /^(?: *quadrant-1 *)/i, /^(?: *quadrant-2 *)/i, /^(?: *quadrant-3 *)/i, /^(?: *quadrant-4 *)/i, /^(?:["][`])/i, /^(?:[^`"]+)/i, /^(?:[`]["])/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:\s*:\s*\[\s*)/i, /^(?:(1)|(0(.\d+)?))/i, /^(?:\s*\] *)/i, /^(?:\s*,\s*)/i, /^(?:(1)|(0(.\d+)?))/i, /^(?: *quadrantChart *)/i, /^(?:[A-Za-z]+)/i, /^(?::)/i, /^(?:\+)/i, /^(?:,)/i, /^(?:=)/i, /^(?:=)/i, /^(?:\*)/i, /^(?:#)/i, /^(?:[\_])/i, /^(?:\.)/i, /^(?:&)/i, /^(?:-)/i, /^(?:[0-9]+)/i, /^(?:\s)/i, /^(?:;)/i, /^(?:[!"#$%&'*+,-.`?\\_/])/i, /^(?:$)/i], + conditions: { "point_y": { "rules": [30], "inclusive": false }, "point_x": { "rules": [29], "inclusive": false }, "point_start": { "rules": [27, 28], "inclusive": false }, "acc_descr_multiline": { "rules": [11, 12], "inclusive": false }, "acc_descr": { "rules": [9], "inclusive": false }, "acc_title": { "rules": [7], "inclusive": false }, "title": { "rules": [5], "inclusive": false }, "md_string": { "rules": [21, 22], "inclusive": false }, "string": { "rules": [24, 25], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 6, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 23, 26, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const defaultThemeVariables = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.D)(); +class QuadrantBuilder { + constructor() { + this.config = this.getDefaultConfig(); + this.themeConfig = this.getDefaultThemeConfig(); + this.data = this.getDefaultData(); + } + getDefaultData() { + return { + titleText: "", + quadrant1Text: "", + quadrant2Text: "", + quadrant3Text: "", + quadrant4Text: "", + xAxisLeftText: "", + xAxisRightText: "", + yAxisBottomText: "", + yAxisTopText: "", + points: [] + }; + } + getDefaultConfig() { + var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r; + return { + showXAxis: true, + showYAxis: true, + showTitle: true, + chartHeight: ((_a = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _a.chartWidth) || 500, + chartWidth: ((_b = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _b.chartHeight) || 500, + titlePadding: ((_c = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _c.titlePadding) || 10, + titleFontSize: ((_d = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _d.titleFontSize) || 20, + quadrantPadding: ((_e = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _e.quadrantPadding) || 5, + xAxisLabelPadding: ((_f = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _f.xAxisLabelPadding) || 5, + yAxisLabelPadding: ((_g = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _g.yAxisLabelPadding) || 5, + xAxisLabelFontSize: ((_h = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _h.xAxisLabelFontSize) || 16, + yAxisLabelFontSize: ((_i = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _i.yAxisLabelFontSize) || 16, + quadrantLabelFontSize: ((_j = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _j.quadrantLabelFontSize) || 16, + quadrantTextTopPadding: ((_k = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _k.quadrantTextTopPadding) || 5, + pointTextPadding: ((_l = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _l.pointTextPadding) || 5, + pointLabelFontSize: ((_m = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _m.pointLabelFontSize) || 12, + pointRadius: ((_n = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _n.pointRadius) || 5, + xAxisPosition: ((_o = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _o.xAxisPosition) || "top", + yAxisPosition: ((_p = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _p.yAxisPosition) || "left", + quadrantInternalBorderStrokeWidth: ((_q = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _q.quadrantInternalBorderStrokeWidth) || 1, + quadrantExternalBorderStrokeWidth: ((_r = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.quadrantChart) == null ? void 0 : _r.quadrantExternalBorderStrokeWidth) || 2 + }; + } + getDefaultThemeConfig() { + return { + quadrant1Fill: defaultThemeVariables.quadrant1Fill, + quadrant2Fill: defaultThemeVariables.quadrant2Fill, + quadrant3Fill: defaultThemeVariables.quadrant3Fill, + quadrant4Fill: defaultThemeVariables.quadrant4Fill, + quadrant1TextFill: defaultThemeVariables.quadrant1TextFill, + quadrant2TextFill: defaultThemeVariables.quadrant2TextFill, + quadrant3TextFill: defaultThemeVariables.quadrant3TextFill, + quadrant4TextFill: defaultThemeVariables.quadrant4TextFill, + quadrantPointFill: defaultThemeVariables.quadrantPointFill, + quadrantPointTextFill: defaultThemeVariables.quadrantPointTextFill, + quadrantXAxisTextFill: defaultThemeVariables.quadrantXAxisTextFill, + quadrantYAxisTextFill: defaultThemeVariables.quadrantYAxisTextFill, + quadrantTitleFill: defaultThemeVariables.quadrantTitleFill, + quadrantInternalBorderStrokeFill: defaultThemeVariables.quadrantInternalBorderStrokeFill, + quadrantExternalBorderStrokeFill: defaultThemeVariables.quadrantExternalBorderStrokeFill + }; + } + clear() { + this.config = this.getDefaultConfig(); + this.themeConfig = this.getDefaultThemeConfig(); + this.data = this.getDefaultData(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("clear called"); + } + setData(data) { + this.data = { ...this.data, ...data }; + } + addPoints(points) { + this.data.points = [...points, ...this.data.points]; + } + setConfig(config2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("setConfig called with: ", config2); + this.config = { ...this.config, ...config2 }; + } + setThemeConfig(themeConfig) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("setThemeConfig called with: ", themeConfig); + this.themeConfig = { ...this.themeConfig, ...themeConfig }; + } + calculateSpace(xAxisPosition, showXAxis, showYAxis, showTitle) { + const xAxisSpaceCalculation = this.config.xAxisLabelPadding * 2 + this.config.xAxisLabelFontSize; + const xAxisSpace = { + top: xAxisPosition === "top" && showXAxis ? xAxisSpaceCalculation : 0, + bottom: xAxisPosition === "bottom" && showXAxis ? xAxisSpaceCalculation : 0 + }; + const yAxisSpaceCalculation = this.config.yAxisLabelPadding * 2 + this.config.yAxisLabelFontSize; + const yAxisSpace = { + left: this.config.yAxisPosition === "left" && showYAxis ? yAxisSpaceCalculation : 0, + right: this.config.yAxisPosition === "right" && showYAxis ? yAxisSpaceCalculation : 0 + }; + const titleSpaceCalculation = this.config.titleFontSize + this.config.titlePadding * 2; + const titleSpace = { + top: showTitle ? titleSpaceCalculation : 0 + }; + const quadrantLeft = this.config.quadrantPadding + yAxisSpace.left; + const quadrantTop = this.config.quadrantPadding + xAxisSpace.top + titleSpace.top; + const quadrantWidth = this.config.chartWidth - this.config.quadrantPadding * 2 - yAxisSpace.left - yAxisSpace.right; + const quadrantHeight = this.config.chartHeight - this.config.quadrantPadding * 2 - xAxisSpace.top - xAxisSpace.bottom - titleSpace.top; + const quadrantHalfWidth = quadrantWidth / 2; + const quadrantHalfHeight = quadrantHeight / 2; + const quadrantSpace = { + quadrantLeft, + quadrantTop, + quadrantWidth, + quadrantHalfWidth, + quadrantHeight, + quadrantHalfHeight + }; + return { + xAxisSpace, + yAxisSpace, + titleSpace, + quadrantSpace + }; + } + getAxisLabels(xAxisPosition, showXAxis, showYAxis, spaceData) { + const { quadrantSpace, titleSpace } = spaceData; + const { + quadrantHalfHeight, + quadrantHeight, + quadrantLeft, + quadrantHalfWidth, + quadrantTop, + quadrantWidth + } = quadrantSpace; + const drawXAxisLabelsInMiddle = Boolean(this.data.xAxisRightText); + const drawYAxisLabelsInMiddle = Boolean(this.data.yAxisTopText); + const axisLabels = []; + if (this.data.xAxisLeftText && showXAxis) { + axisLabels.push({ + text: this.data.xAxisLeftText, + fill: this.themeConfig.quadrantXAxisTextFill, + x: quadrantLeft + (drawXAxisLabelsInMiddle ? quadrantHalfWidth / 2 : 0), + y: xAxisPosition === "top" ? this.config.xAxisLabelPadding + titleSpace.top : this.config.xAxisLabelPadding + quadrantTop + quadrantHeight + this.config.quadrantPadding, + fontSize: this.config.xAxisLabelFontSize, + verticalPos: drawXAxisLabelsInMiddle ? "center" : "left", + horizontalPos: "top", + rotation: 0 + }); + } + if (this.data.xAxisRightText && showXAxis) { + axisLabels.push({ + text: this.data.xAxisRightText, + fill: this.themeConfig.quadrantXAxisTextFill, + x: quadrantLeft + quadrantHalfWidth + (drawXAxisLabelsInMiddle ? quadrantHalfWidth / 2 : 0), + y: xAxisPosition === "top" ? this.config.xAxisLabelPadding + titleSpace.top : this.config.xAxisLabelPadding + quadrantTop + quadrantHeight + this.config.quadrantPadding, + fontSize: this.config.xAxisLabelFontSize, + verticalPos: drawXAxisLabelsInMiddle ? "center" : "left", + horizontalPos: "top", + rotation: 0 + }); + } + if (this.data.yAxisBottomText && showYAxis) { + axisLabels.push({ + text: this.data.yAxisBottomText, + fill: this.themeConfig.quadrantYAxisTextFill, + x: this.config.yAxisPosition === "left" ? this.config.yAxisLabelPadding : this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth + this.config.quadrantPadding, + y: quadrantTop + quadrantHeight - (drawYAxisLabelsInMiddle ? quadrantHalfHeight / 2 : 0), + fontSize: this.config.yAxisLabelFontSize, + verticalPos: drawYAxisLabelsInMiddle ? "center" : "left", + horizontalPos: "top", + rotation: -90 + }); + } + if (this.data.yAxisTopText && showYAxis) { + axisLabels.push({ + text: this.data.yAxisTopText, + fill: this.themeConfig.quadrantYAxisTextFill, + x: this.config.yAxisPosition === "left" ? this.config.yAxisLabelPadding : this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth + this.config.quadrantPadding, + y: quadrantTop + quadrantHalfHeight - (drawYAxisLabelsInMiddle ? quadrantHalfHeight / 2 : 0), + fontSize: this.config.yAxisLabelFontSize, + verticalPos: drawYAxisLabelsInMiddle ? "center" : "left", + horizontalPos: "top", + rotation: -90 + }); + } + return axisLabels; + } + getQuadrants(spaceData) { + const { quadrantSpace } = spaceData; + const { quadrantHalfHeight, quadrantLeft, quadrantHalfWidth, quadrantTop } = quadrantSpace; + const quadrants = [ + { + text: { + text: this.data.quadrant1Text, + fill: this.themeConfig.quadrant1TextFill, + x: 0, + y: 0, + fontSize: this.config.quadrantLabelFontSize, + verticalPos: "center", + horizontalPos: "middle", + rotation: 0 + }, + x: quadrantLeft + quadrantHalfWidth, + y: quadrantTop, + width: quadrantHalfWidth, + height: quadrantHalfHeight, + fill: this.themeConfig.quadrant1Fill + }, + { + text: { + text: this.data.quadrant2Text, + fill: this.themeConfig.quadrant2TextFill, + x: 0, + y: 0, + fontSize: this.config.quadrantLabelFontSize, + verticalPos: "center", + horizontalPos: "middle", + rotation: 0 + }, + x: quadrantLeft, + y: quadrantTop, + width: quadrantHalfWidth, + height: quadrantHalfHeight, + fill: this.themeConfig.quadrant2Fill + }, + { + text: { + text: this.data.quadrant3Text, + fill: this.themeConfig.quadrant3TextFill, + x: 0, + y: 0, + fontSize: this.config.quadrantLabelFontSize, + verticalPos: "center", + horizontalPos: "middle", + rotation: 0 + }, + x: quadrantLeft, + y: quadrantTop + quadrantHalfHeight, + width: quadrantHalfWidth, + height: quadrantHalfHeight, + fill: this.themeConfig.quadrant3Fill + }, + { + text: { + text: this.data.quadrant4Text, + fill: this.themeConfig.quadrant4TextFill, + x: 0, + y: 0, + fontSize: this.config.quadrantLabelFontSize, + verticalPos: "center", + horizontalPos: "middle", + rotation: 0 + }, + x: quadrantLeft + quadrantHalfWidth, + y: quadrantTop + quadrantHalfHeight, + width: quadrantHalfWidth, + height: quadrantHalfHeight, + fill: this.themeConfig.quadrant4Fill + } + ]; + for (const quadrant of quadrants) { + quadrant.text.x = quadrant.x + quadrant.width / 2; + if (this.data.points.length === 0) { + quadrant.text.y = quadrant.y + quadrant.height / 2; + quadrant.text.horizontalPos = "middle"; + } else { + quadrant.text.y = quadrant.y + this.config.quadrantTextTopPadding; + quadrant.text.horizontalPos = "top"; + } + } + return quadrants; + } + getQuadrantPoints(spaceData) { + const { quadrantSpace } = spaceData; + const { quadrantHeight, quadrantLeft, quadrantTop, quadrantWidth } = quadrantSpace; + const xAxis = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleLinear */ .BYU)().domain([0, 1]).range([quadrantLeft, quadrantWidth + quadrantLeft]); + const yAxis = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleLinear */ .BYU)().domain([0, 1]).range([quadrantHeight + quadrantTop, quadrantTop]); + const points = this.data.points.map((point) => { + const props = { + x: xAxis(point.x), + y: yAxis(point.y), + fill: this.themeConfig.quadrantPointFill, + radius: this.config.pointRadius, + text: { + text: point.text, + fill: this.themeConfig.quadrantPointTextFill, + x: xAxis(point.x), + y: yAxis(point.y) + this.config.pointTextPadding, + verticalPos: "center", + horizontalPos: "top", + fontSize: this.config.pointLabelFontSize, + rotation: 0 + } + }; + return props; + }); + return points; + } + getBorders(spaceData) { + const halfExternalBorderWidth = this.config.quadrantExternalBorderStrokeWidth / 2; + const { quadrantSpace } = spaceData; + const { + quadrantHalfHeight, + quadrantHeight, + quadrantLeft, + quadrantHalfWidth, + quadrantTop, + quadrantWidth + } = quadrantSpace; + const borderLines = [ + // top border + { + strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill, + strokeWidth: this.config.quadrantExternalBorderStrokeWidth, + x1: quadrantLeft - halfExternalBorderWidth, + y1: quadrantTop, + x2: quadrantLeft + quadrantWidth + halfExternalBorderWidth, + y2: quadrantTop + }, + // right border + { + strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill, + strokeWidth: this.config.quadrantExternalBorderStrokeWidth, + x1: quadrantLeft + quadrantWidth, + y1: quadrantTop + halfExternalBorderWidth, + x2: quadrantLeft + quadrantWidth, + y2: quadrantTop + quadrantHeight - halfExternalBorderWidth + }, + // bottom border + { + strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill, + strokeWidth: this.config.quadrantExternalBorderStrokeWidth, + x1: quadrantLeft - halfExternalBorderWidth, + y1: quadrantTop + quadrantHeight, + x2: quadrantLeft + quadrantWidth + halfExternalBorderWidth, + y2: quadrantTop + quadrantHeight + }, + // left border + { + strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill, + strokeWidth: this.config.quadrantExternalBorderStrokeWidth, + x1: quadrantLeft, + y1: quadrantTop + halfExternalBorderWidth, + x2: quadrantLeft, + y2: quadrantTop + quadrantHeight - halfExternalBorderWidth + }, + // vertical inner border + { + strokeFill: this.themeConfig.quadrantInternalBorderStrokeFill, + strokeWidth: this.config.quadrantInternalBorderStrokeWidth, + x1: quadrantLeft + quadrantHalfWidth, + y1: quadrantTop + halfExternalBorderWidth, + x2: quadrantLeft + quadrantHalfWidth, + y2: quadrantTop + quadrantHeight - halfExternalBorderWidth + }, + // horizontal inner border + { + strokeFill: this.themeConfig.quadrantInternalBorderStrokeFill, + strokeWidth: this.config.quadrantInternalBorderStrokeWidth, + x1: quadrantLeft + halfExternalBorderWidth, + y1: quadrantTop + quadrantHalfHeight, + x2: quadrantLeft + quadrantWidth - halfExternalBorderWidth, + y2: quadrantTop + quadrantHalfHeight + } + ]; + return borderLines; + } + getTitle(showTitle) { + if (showTitle) { + return { + text: this.data.titleText, + fill: this.themeConfig.quadrantTitleFill, + fontSize: this.config.titleFontSize, + horizontalPos: "top", + verticalPos: "center", + rotation: 0, + y: this.config.titlePadding, + x: this.config.chartWidth / 2 + }; + } + return; + } + build() { + const showXAxis = this.config.showXAxis && !!(this.data.xAxisLeftText || this.data.xAxisRightText); + const showYAxis = this.config.showYAxis && !!(this.data.yAxisTopText || this.data.yAxisBottomText); + const showTitle = this.config.showTitle && !!this.data.titleText; + const xAxisPosition = this.data.points.length > 0 ? "bottom" : this.config.xAxisPosition; + const calculatedSpace = this.calculateSpace(xAxisPosition, showXAxis, showYAxis, showTitle); + return { + points: this.getQuadrantPoints(calculatedSpace), + quadrants: this.getQuadrants(calculatedSpace), + axisLabels: this.getAxisLabels(xAxisPosition, showXAxis, showYAxis, calculatedSpace), + borderLines: this.getBorders(calculatedSpace), + title: this.getTitle(showTitle) + }; + } +} +const config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)(); +function textSanitizer(text) { + return (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.d)(text.trim(), config); +} +const quadrantBuilder = new QuadrantBuilder(); +function setQuadrant1Text(textObj) { + quadrantBuilder.setData({ quadrant1Text: textSanitizer(textObj.text) }); +} +function setQuadrant2Text(textObj) { + quadrantBuilder.setData({ quadrant2Text: textSanitizer(textObj.text) }); +} +function setQuadrant3Text(textObj) { + quadrantBuilder.setData({ quadrant3Text: textSanitizer(textObj.text) }); +} +function setQuadrant4Text(textObj) { + quadrantBuilder.setData({ quadrant4Text: textSanitizer(textObj.text) }); +} +function setXAxisLeftText(textObj) { + quadrantBuilder.setData({ xAxisLeftText: textSanitizer(textObj.text) }); +} +function setXAxisRightText(textObj) { + quadrantBuilder.setData({ xAxisRightText: textSanitizer(textObj.text) }); +} +function setYAxisTopText(textObj) { + quadrantBuilder.setData({ yAxisTopText: textSanitizer(textObj.text) }); +} +function setYAxisBottomText(textObj) { + quadrantBuilder.setData({ yAxisBottomText: textSanitizer(textObj.text) }); +} +function addPoint(textObj, x, y) { + quadrantBuilder.addPoints([{ x, y, text: textSanitizer(textObj.text) }]); +} +function setWidth(width) { + quadrantBuilder.setConfig({ chartWidth: width }); +} +function setHeight(height) { + quadrantBuilder.setConfig({ chartHeight: height }); +} +function getQuadrantData() { + const config2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const { themeVariables, quadrantChart: quadrantChartConfig } = config2; + if (quadrantChartConfig) { + quadrantBuilder.setConfig(quadrantChartConfig); + } + quadrantBuilder.setThemeConfig({ + quadrant1Fill: themeVariables.quadrant1Fill, + quadrant2Fill: themeVariables.quadrant2Fill, + quadrant3Fill: themeVariables.quadrant3Fill, + quadrant4Fill: themeVariables.quadrant4Fill, + quadrant1TextFill: themeVariables.quadrant1TextFill, + quadrant2TextFill: themeVariables.quadrant2TextFill, + quadrant3TextFill: themeVariables.quadrant3TextFill, + quadrant4TextFill: themeVariables.quadrant4TextFill, + quadrantPointFill: themeVariables.quadrantPointFill, + quadrantPointTextFill: themeVariables.quadrantPointTextFill, + quadrantXAxisTextFill: themeVariables.quadrantXAxisTextFill, + quadrantYAxisTextFill: themeVariables.quadrantYAxisTextFill, + quadrantExternalBorderStrokeFill: themeVariables.quadrantExternalBorderStrokeFill, + quadrantInternalBorderStrokeFill: themeVariables.quadrantInternalBorderStrokeFill, + quadrantTitleFill: themeVariables.quadrantTitleFill + }); + quadrantBuilder.setData({ titleText: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.r)() }); + return quadrantBuilder.build(); +} +const clear = function() { + quadrantBuilder.clear(); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.t)(); +}; +const db = { + setWidth, + setHeight, + setQuadrant1Text, + setQuadrant2Text, + setQuadrant3Text, + setQuadrant4Text, + setXAxisLeftText, + setXAxisRightText, + setYAxisTopText, + setYAxisBottomText, + addPoint, + getQuadrantData, + clear, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.g, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.r, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.b +}; +const draw = (txt, id, _version, diagObj) => { + var _a, _b, _c; + function getDominantBaseLine(horizontalPos) { + return horizontalPos === "top" ? "hanging" : "middle"; + } + function getTextAnchor(verticalPos) { + return verticalPos === "left" ? "start" : "middle"; + } + function getTransformation(data) { + return `translate(${data.x}, ${data.y}) rotate(${data.rotation || 0})`; + } + const conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Rendering quadrant chart\n" + txt); + const securityLevel = conf.securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const svg = root.select(`[id="${id}"]`); + const group = svg.append("g").attr("class", "main"); + const width = ((_a = conf.quadrantChart) == null ? void 0 : _a.chartWidth) || 500; + const height = ((_b = conf.quadrantChart) == null ? void 0 : _b.chartHeight) || 500; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.i)(svg, height, width, ((_c = conf.quadrantChart) == null ? void 0 : _c.useMaxWidth) || true); + svg.attr("viewBox", "0 0 " + width + " " + height); + diagObj.db.setHeight(height); + diagObj.db.setWidth(width); + const quadrantData = diagObj.db.getQuadrantData(); + const quadrantsGroup = group.append("g").attr("class", "quadrants"); + const borderGroup = group.append("g").attr("class", "border"); + const dataPointGroup = group.append("g").attr("class", "data-points"); + const labelGroup = group.append("g").attr("class", "labels"); + const titleGroup = group.append("g").attr("class", "title"); + if (quadrantData.title) { + titleGroup.append("text").attr("x", 0).attr("y", 0).attr("fill", quadrantData.title.fill).attr("font-size", quadrantData.title.fontSize).attr("dominant-baseline", getDominantBaseLine(quadrantData.title.horizontalPos)).attr("text-anchor", getTextAnchor(quadrantData.title.verticalPos)).attr("transform", getTransformation(quadrantData.title)).text(quadrantData.title.text); + } + if (quadrantData.borderLines) { + borderGroup.selectAll("line").data(quadrantData.borderLines).enter().append("line").attr("x1", (data) => data.x1).attr("y1", (data) => data.y1).attr("x2", (data) => data.x2).attr("y2", (data) => data.y2).style("stroke", (data) => data.strokeFill).style("stroke-width", (data) => data.strokeWidth); + } + const quadrants = quadrantsGroup.selectAll("g.quadrant").data(quadrantData.quadrants).enter().append("g").attr("class", "quadrant"); + quadrants.append("rect").attr("x", (data) => data.x).attr("y", (data) => data.y).attr("width", (data) => data.width).attr("height", (data) => data.height).attr("fill", (data) => data.fill); + quadrants.append("text").attr("x", 0).attr("y", 0).attr("fill", (data) => data.text.fill).attr("font-size", (data) => data.text.fontSize).attr( + "dominant-baseline", + (data) => getDominantBaseLine(data.text.horizontalPos) + ).attr("text-anchor", (data) => getTextAnchor(data.text.verticalPos)).attr("transform", (data) => getTransformation(data.text)).text((data) => data.text.text); + const labels = labelGroup.selectAll("g.label").data(quadrantData.axisLabels).enter().append("g").attr("class", "label"); + labels.append("text").attr("x", 0).attr("y", 0).text((data) => data.text).attr("fill", (data) => data.fill).attr("font-size", (data) => data.fontSize).attr("dominant-baseline", (data) => getDominantBaseLine(data.horizontalPos)).attr("text-anchor", (data) => getTextAnchor(data.verticalPos)).attr("transform", (data) => getTransformation(data)); + const dataPoints = dataPointGroup.selectAll("g.data-point").data(quadrantData.points).enter().append("g").attr("class", "data-point"); + dataPoints.append("circle").attr("cx", (data) => data.x).attr("cy", (data) => data.y).attr("r", (data) => data.radius).attr("fill", (data) => data.fill); + dataPoints.append("text").attr("x", 0).attr("y", 0).text((data) => data.text.text).attr("fill", (data) => data.text.fill).attr("font-size", (data) => data.text.fontSize).attr( + "dominant-baseline", + (data) => getDominantBaseLine(data.text.horizontalPos) + ).attr("text-anchor", (data) => getTextAnchor(data.text.verticalPos)).attr("transform", (data) => getTransformation(data.text)); +}; +const renderer = { + draw +}; +const diagram = { + parser: parser$1, + db, + renderer, + styles: () => "" +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/255134d9.a1e74e37.js b/assets/js/255134d9.820e0db5.js similarity index 84% rename from assets/js/255134d9.a1e74e37.js rename to assets/js/255134d9.820e0db5.js index 4480f657d..670b614e6 100644 --- a/assets/js/255134d9.a1e74e37.js +++ b/assets/js/255134d9.820e0db5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8151],{30753:e=>{e.exports=JSON.parse('{"label":"Composite","permalink":"/tags/composite","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8151],{30753:e=>{e.exports=JSON.parse('{"label":"Composite","permalink":"/tags/composite","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/269a2f75.5474eea4.js b/assets/js/269a2f75.3f56a8b3.js similarity index 86% rename from assets/js/269a2f75.5474eea4.js rename to assets/js/269a2f75.3f56a8b3.js index 642f021fd..ee7368763 100644 --- a/assets/js/269a2f75.5474eea4.js +++ b/assets/js/269a2f75.3f56a8b3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1994],{52358:s=>{s.exports=JSON.parse('{"label":"static","permalink":"/tags/static","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1994],{52358:s=>{s.exports=JSON.parse('{"label":"static","permalink":"/tags/static","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/26dc40bf.31dfe6a6.js b/assets/js/26dc40bf.31dfe6a6.js deleted file mode 100644 index 07ca32a12..000000000 --- a/assets/js/26dc40bf.31dfe6a6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5237],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var o=n.createContext({}),s=function(e){var t=n.useContext(o),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},c=function(e){var t=s(e.components);return n.createElement(o.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,o=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),k=s(a),m=r,g=k["".concat(o,".").concat(m)]||k[m]||u[m]||l;return a?n.createElement(g,i(i({ref:t},c),{},{components:a})):n.createElement(g,i({ref:t},c))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,i=new Array(l);i[0]=k;var p={};for(var o in t)hasOwnProperty.call(t,o)&&(p[o]=t[o]);p.originalType=e,p.mdxType="string"==typeof e?e:r,i[1]=p;for(var s=2;s{a.r(t),a.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",slug:"java-spring-springboot",tags:["Java","Spring Boot","Spring"]},i=void 0,p={permalink:"/java-spring-springboot",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",source:"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",description:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",date:"2023-07-24T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 24\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Spring Boot",permalink:"/tags/spring-boot"},{label:"Spring",permalink:"/tags/spring"}],readingTime:4.725,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",slug:"java-spring-springboot",tags:["Java","Spring Boot","Spring"]},prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",permalink:"/route-image-intro"},nextItem:{title:"\uc6f9\uc18c\ucf13",permalink:"/websocket"}},o={authorsImageUrls:[]},s=[{value:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",id:"\uc790\ubc14-17-\uc2a4\ud504\ub9c1-60-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-31",level:2},{value:"\uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d",id:"\uc790\ubc14-\ubcc0\uacbd-\uc0ac\ud56d",level:2},{value:"Switch Expressions(Java 14)",id:"switch-expressionsjava-14",level:3},{value:"Text Block(Java 15)",id:"text-blockjava-15",level:3},{value:"NPE \uba54\uc2dc\uc9c0(Java 15)",id:"npe-\uba54\uc2dc\uc9c0java-15",level:3},{value:"Record(Java 16)",id:"recordjava-16",level:3},{value:"\ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d",id:"\ucd94\uac00\uc801\uc778-\ubcc0\uacbd\uc0ac\ud56d",level:3},{value:"\uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ubcc0\uacbd-\uc0ac\ud56d",level:2},{value:"\uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd",id:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4-\ubcc0\uacbd",level:3},{value:"PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c",id:"pathpatternparser---trailing-slash-\ud5c8\uc6a9\ud558\uc9c0-\uc54a\uc74c",level:3},{value:"HTTP interface client",id:"http-interface-client",level:3},{value:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ucd5c\uc18c-\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],c={toc:s};function u(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"\uc790\ubc14-17-\uc2a4\ud504\ub9c1-60-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-31"},"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1"),(0,r.kt)("p",null,"\ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1\uc744 \uc0ac\uc6a9\ud558\uac8c \ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","2.7 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud560 \uc218\ub3c4 \uc788\uc5c8\uc9c0\ub9cc LTS \uae30\uac04\uacfc \ucde8\uc57d\uc810 \ud328\uce58\ub85c \uc778\ud55c \ubc84\uc804\uc5c5 \ub4f1\uc744 \uace0\ub824\ud588\uc744 \ub54c 3.1\uacfc \uc790\ubc14 17\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \ub354 \ud6a8\uc728\uc801\uc774\ub77c\uace0 \ud310\ub2e8\ud588\ub2e4."),(0,r.kt)("h2",{id:"\uc790\ubc14-\ubcc0\uacbd-\uc0ac\ud56d"},"\uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d"),(0,r.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2\uae4c\uc9c0\ub294 \uc790\ubc14 11\uc744 \uc0ac\uc6a9\ud588\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc790\ubc14 11\ubd80\ud130 \uc790\ubc14 17\uae4c\uc9c0\uc758 \ubcc0\uacbd\uc0ac\ud56d\uc744 \uc815\uc2dd \ub9b4\ub9ac\uc988 \uae30\uc900\uc73c\ub85c \uc815\ub9ac\ud574\ubcf4\ub824\uace0 \ud55c\ub2e4."),(0,r.kt)("h3",{id:"switch-expressionsjava-14"},"Switch Expressions(Java 14)"),(0,r.kt)("p",null,"Java 14\uc5d0\uc11c\ub294 \uae30\uc874\uc758 Switch \ubb38\uc744 \uac04\uacb0\ud558\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub294 Switch \uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"enum RESULT {\n WIN, LOSE, DRAW\n}\n\nRESULT result = RESULT.WIN;\n\nint prize = switch (result) {\n case WIN -> 10_000_000;\n case LOSE, DRAW -> 5_000_000;\n default -> 0;\n};\n")),(0,r.kt)("p",null,"\uc8fc\uc694 \ud2b9\uc9d5\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"->")," \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 case\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc14\ub85c \ubc18\ud658\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"case\ub97c \ucf64\ub9c8(",(0,r.kt)("inlineCode",{parentName:"li"},","),")\ub85c \uc5f0\uacb0\ud558\uc5ec \ud558\ub098\uc758 case\uc5d0 \uc5ec\ub7ec \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"break \ubb38\uc774 \ud544\uc694 \uc5c6\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"default \ube14\ub85d\uc744 \ud1b5\ud574 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.")),(0,r.kt)("h3",{id:"text-blockjava-15"},"Text Block(Java 15)"),(0,r.kt)("p",null,"Java 15\uc5d0\ub294 \uc0c8\ub85c\uc6b4 \ubb38\uc790\uc5f4 \ud45c\ud604\ubc29\uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae34 \ubb38\uc790\uc5f4\uc744 + \uc5f0\uc0b0\uc790\uc758 \ub3c4\uc6c0 \uc5c6\uc774 \uac00\ub3c5\uc131\uc788\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},'@Repository\npublic interface PostRepository extends JpaRepository {\n @Query("""\n SELECT p FROM Post p\n WHERE p.title LIKE %:keyword%\n OR p.content LIKE %:keyword%\n """)\n List findPostsByTitleOrContentContainingKeyword(String keyword);\n}\n')),(0,r.kt)("h3",{id:"npe-\uba54\uc2dc\uc9c0java-15"},"NPE \uba54\uc2dc\uc9c0(Java 15)"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},'String name = null;\nname.chars();\n\n/** \n# before\njava.lang.NullPointerException\n at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)\n\n# after\nCannot invoke "String.chars()" because "name" is null\njava.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null\n*/\n')),(0,r.kt)("h3",{id:"recordjava-16"},"Record(Java 16)"),(0,r.kt)("p",null,"Lombok\uc758 ",(0,r.kt)("inlineCode",{parentName:"p"},"@Data"),", kotlin\uc758 data \ud074\ub798\uc2a4\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Record\ub97c \uc120\uc5b8\ud558\ub294 \uacbd\uc6b0 \uc811\uadfc\uc790, \uc0dd\uc131\uc790, equals & hashcode, toString\uc774 \uc81c\uacf5\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub370\uc774\ud130 \uc804\uc1a1 \uc6a9\ub3c4\ub85c \uc801\ud569\ud574 \ubcf4\uc778\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public record PostDto(String title, String content) {\n}\n")),(0,r.kt)("h3",{id:"\ucd94\uac00\uc801\uc778-\ubcc0\uacbd\uc0ac\ud56d"},"\ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d"),(0,r.kt)("p",null,"\uc774\uc678\uc5d0\ub3c4 stream\uc758 toList, \uc778\uc2a4\ud134\uc2a4\uc758 \ud0c0\uc785\uc744 \uac04\ud3b8\ud558\uac8c \uccb4\ud06c\ud558\ub294 Pattern Matching Instanceof, Sealed class \ub4f1\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. "),(0,r.kt)("h2",{id:"\uc2a4\ud504\ub9c1-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ubcc0\uacbd-\uc0ac\ud56d"},"\uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d"),(0,r.kt)("p",null,"\uc2a4\ud504\ub9c1\uacfc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\ub3c4 \ub9ce\uc740 \ubcc0\uacbd \uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ud544\uc694\ud574\ubcf4\uc774\ub294 \uba87\uac1c \uc815\ub3c4\ub9cc \uc815\ub9ac\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\uc2a4\ud504\ub9c1-\uc694\uad6c\uc0ac\ud56d"},"\uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d"),(0,r.kt)("p",null,"Java 17, Jakarta EE 9 \uc774\uc0c1\uc774\uc5b4\uc57c \ud55c\ub2e4."),(0,r.kt)("h3",{id:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4-\ubcc0\uacbd"},"\ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd"),(0,r.kt)("p",null,"Jakarta EE 9\uac00 \uc801\uc6a9\ub418\uba74\uc11c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub3c4 \uc804\ubc18\uc801\uc73c\ub85c javax -> jakarta\ub85c \ubcc0\uacbd\ub418\uc5c8\ub2e4. "),(0,r.kt)("h3",{id:"pathpatternparser---trailing-slash-\ud5c8\uc6a9\ud558\uc9c0-\uc54a\uc74c"},"PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c"),(0,r.kt)("p",null,"6.0 \uc774\uc804\uc758 \uacbd\uc6b0 \uae30\ubcf8 \uc124\uc815 \uae30\uc900\uc73c\ub85c ",(0,r.kt)("inlineCode",{parentName:"p"},'@GetMapping("/hello")'),"\uc640 ",(0,r.kt)("inlineCode",{parentName:"p"},'@GetMapping("/hello/")'),"\uac00 \ub3d9\uc77c\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","6.0 \uc774\ud6c4\uc758 PathPatternParser\uac00 \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\uace0, ",(0,r.kt)("inlineCode",{parentName:"p"},"/hello"),"\uc640 ",(0,r.kt)("inlineCode",{parentName:"p"},"/hello/"),"\ub294 \uc11c\ub85c \ub2e4\ub978 URL\ub85c \ub9e4\uce6d\ub41c\ub2e4. "),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"PathPatternParser used by default (with the ability to opt into PathMatcher). ")),(0,r.kt)("h3",{id:"http-interface-client"},"HTTP interface client"),(0,r.kt)("p",null,"\uc790\ubc14 \uc778\ud130\ud398\uc774\uc2a4\uc640 \uc5b4\ub178\ud14c\uc774\uc158\uc744 \uc774\uc6a9\ud558\uc5ec HTTP \uc694\uccad\uc744 \uc704\ud55c \uc11c\ube44\uc2a4\ub97c \uc815\uc758\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 ",(0,r.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=Kb37Q5GCyZs"},"\ud1a0\ube44\ub2d8\uc758 \uac15\uc758"),"\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4."),(0,r.kt)("h3",{id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ucd5c\uc18c-\uc694\uad6c\uc0ac\ud56d"},"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d"),(0,r.kt)("p",null,"Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\uc678\uc5d0\ub3c4 \uc11c\ub4dc\ud30c\ud2f0\ub4e4\uc758 \ucd5c\uc2e0 \ub9b4\ub9ac\uc988 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c, \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ud574\ub2f9 \ubc84\uc804\uc5d0 \ub9de\ub294 \ub9b4\ub9ac\uc988 \ub178\ud2b8\ub97c \ucc38\uace0\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. "),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=1WT6oxchM9M"},"\uc5b4\ub290\xa0\uc6d4\uae09\uc7c1\uc774\uac1c\ubc1c\uc790\xa0\uc758 \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ub530\ub77c\uc7a1\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=7SlDdzVk6GE"},"\uc790\ubc14 9-16 \uc8fc\uc694 \ud2b9\uc9d5 \ubcf5\uc2b5\ud558\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.samsungsds.com/kr/insights/java_jakarta.html"},"Java EE\uc5d0\uc11c Jakarta EE\ub85c\uc758 \uc804\ud658"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=Kb37Q5GCyZs"},"Spring 6\uc758 \uc0c8\ub85c\uc6b4 HTTP Interface\uc640 3 \uac00\uc9c0 REST Clients \ub77c\uc774\ube0c \ucf54\ub529"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x"},"What's New in Spring Framework 6.x"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes"},"Spring Boot 3.0 Release Notes"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes"},"Spring Boot 3.1 Release Notes")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/26dc40bf.bd9e249d.js b/assets/js/26dc40bf.bd9e249d.js new file mode 100644 index 000000000..bb7370294 --- /dev/null +++ b/assets/js/26dc40bf.bd9e249d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5237],{55338:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=t(85893),a=t(3905);const i={title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",slug:"java-spring-springboot",tags:["Java","Spring Boot","Spring"]},s=void 0,l={permalink:"/java-spring-springboot",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",source:"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",description:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",date:"2023-07-24T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 24\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Spring Boot",permalink:"/tags/spring-boot"},{label:"Spring",permalink:"/tags/spring"}],readingTime:4.725,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",slug:"java-spring-springboot",tags:["Java","Spring Boot","Spring"]},unlisted:!1,prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",permalink:"/route-image-intro"},nextItem:{title:"\uc6f9\uc18c\ucf13",permalink:"/websocket"}},o={authorsImageUrls:[]},c=[{value:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",id:"\uc790\ubc14-17-\uc2a4\ud504\ub9c1-60-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-31",level:2},{value:"\uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d",id:"\uc790\ubc14-\ubcc0\uacbd-\uc0ac\ud56d",level:2},{value:"Switch Expressions(Java 14)",id:"switch-expressionsjava-14",level:3},{value:"Text Block(Java 15)",id:"text-blockjava-15",level:3},{value:"NPE \uba54\uc2dc\uc9c0(Java 15)",id:"npe-\uba54\uc2dc\uc9c0java-15",level:3},{value:"Record(Java 16)",id:"recordjava-16",level:3},{value:"\ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d",id:"\ucd94\uac00\uc801\uc778-\ubcc0\uacbd\uc0ac\ud56d",level:3},{value:"\uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ubcc0\uacbd-\uc0ac\ud56d",level:2},{value:"\uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd",id:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4-\ubcc0\uacbd",level:3},{value:"PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c",id:"pathpatternparser---trailing-slash-\ud5c8\uc6a9\ud558\uc9c0-\uc54a\uc74c",level:3},{value:"HTTP interface client",id:"http-interface-client",level:3},{value:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ucd5c\uc18c-\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function h(e){const n={a:"a",blockquote:"blockquote",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"\uc790\ubc14-17-\uc2a4\ud504\ub9c1-60-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-31",children:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1"}),"\n",(0,r.jsxs)(n.p,{children:["\ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1\uc744 \uc0ac\uc6a9\ud558\uac8c \ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","2.7 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud560 \uc218\ub3c4 \uc788\uc5c8\uc9c0\ub9cc LTS \uae30\uac04\uacfc \ucde8\uc57d\uc810 \ud328\uce58\ub85c \uc778\ud55c \ubc84\uc804\uc5c5 \ub4f1\uc744 \uace0\ub824\ud588\uc744 \ub54c 3.1\uacfc \uc790\ubc14 17\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \ub354 \ud6a8\uc728\uc801\uc774\ub77c\uace0 \ud310\ub2e8\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\uc790\ubc14-\ubcc0\uacbd-\uc0ac\ud56d",children:"\uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d"}),"\n",(0,r.jsxs)(n.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2\uae4c\uc9c0\ub294 \uc790\ubc14 11\uc744 \uc0ac\uc6a9\ud588\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc790\ubc14 11\ubd80\ud130 \uc790\ubc14 17\uae4c\uc9c0\uc758 \ubcc0\uacbd\uc0ac\ud56d\uc744 \uc815\uc2dd \ub9b4\ub9ac\uc988 \uae30\uc900\uc73c\ub85c \uc815\ub9ac\ud574\ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"switch-expressionsjava-14",children:"Switch Expressions(Java 14)"}),"\n",(0,r.jsx)(n.p,{children:"Java 14\uc5d0\uc11c\ub294 \uae30\uc874\uc758 Switch \ubb38\uc744 \uac04\uacb0\ud558\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub294 Switch \uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"enum RESULT {\n WIN, LOSE, DRAW\n}\n\nRESULT result = RESULT.WIN;\n\nint prize = switch (result) {\n case WIN -> 10_000_000;\n case LOSE, DRAW -> 5_000_000;\n\tdefault -> 0;\n};\n"})}),"\n",(0,r.jsx)(n.p,{children:"\uc8fc\uc694 \ud2b9\uc9d5\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"->"})," \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 case\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc14\ub85c \ubc18\ud658\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsxs)(n.li,{children:["case\ub97c \ucf64\ub9c8(",(0,r.jsx)(n.code,{children:","}),")\ub85c \uc5f0\uacb0\ud558\uc5ec \ud558\ub098\uc758 case\uc5d0 \uc5ec\ub7ec \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.li,{children:"break \ubb38\uc774 \ud544\uc694 \uc5c6\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"default \ube14\ub85d\uc744 \ud1b5\ud574 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"text-blockjava-15",children:"Text Block(Java 15)"}),"\n",(0,r.jsxs)(n.p,{children:["Java 15\uc5d0\ub294 \uc0c8\ub85c\uc6b4 \ubb38\uc790\uc5f4 \ud45c\ud604\ubc29\uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uae34 \ubb38\uc790\uc5f4\uc744 + \uc5f0\uc0b0\uc790\uc758 \ub3c4\uc6c0 \uc5c6\uc774 \uac00\ub3c5\uc131\uc788\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@Repository\npublic interface PostRepository extends JpaRepository {\n @Query("""\n SELECT p FROM Post p\n WHERE p.title LIKE %:keyword%\n OR p.content LIKE %:keyword%\n """)\n List findPostsByTitleOrContentContainingKeyword(String keyword);\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"npe-\uba54\uc2dc\uc9c0java-15",children:"NPE \uba54\uc2dc\uc9c0(Java 15)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'String name = null;\nname.chars();\n\n/** \n# before\njava.lang.NullPointerException\n\tat com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)\n\n# after\nCannot invoke "String.chars()" because "name" is null\njava.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null\n*/\n'})}),"\n",(0,r.jsx)(n.h3,{id:"recordjava-16",children:"Record(Java 16)"}),"\n",(0,r.jsxs)(n.p,{children:["Lombok\uc758 ",(0,r.jsx)(n.code,{children:"@Data"}),", kotlin\uc758 data \ud074\ub798\uc2a4\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Record\ub97c \uc120\uc5b8\ud558\ub294 \uacbd\uc6b0 \uc811\uadfc\uc790, \uc0dd\uc131\uc790, equals & hashcode, toString\uc774 \uc81c\uacf5\ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub370\uc774\ud130 \uc804\uc1a1 \uc6a9\ub3c4\ub85c \uc801\ud569\ud574 \ubcf4\uc778\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public record PostDto(String title, String content) {\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\ucd94\uac00\uc801\uc778-\ubcc0\uacbd\uc0ac\ud56d",children:"\ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d"}),"\n",(0,r.jsx)(n.p,{children:"\uc774\uc678\uc5d0\ub3c4 stream\uc758 toList, \uc778\uc2a4\ud134\uc2a4\uc758 \ud0c0\uc785\uc744 \uac04\ud3b8\ud558\uac8c \uccb4\ud06c\ud558\ub294 Pattern Matching Instanceof, Sealed class \ub4f1\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.h2,{id:"\uc2a4\ud504\ub9c1-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ubcc0\uacbd-\uc0ac\ud56d",children:"\uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d"}),"\n",(0,r.jsxs)(n.p,{children:["\uc2a4\ud504\ub9c1\uacfc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\ub3c4 \ub9ce\uc740 \ubcc0\uacbd \uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ud544\uc694\ud574\ubcf4\uc774\ub294 \uba87\uac1c \uc815\ub3c4\ub9cc \uc815\ub9ac\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc2a4\ud504\ub9c1-\uc694\uad6c\uc0ac\ud56d",children:"\uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d"}),"\n",(0,r.jsx)(n.p,{children:"Java 17, Jakarta EE 9 \uc774\uc0c1\uc774\uc5b4\uc57c \ud55c\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4-\ubcc0\uacbd",children:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd"}),"\n",(0,r.jsx)(n.p,{children:"Jakarta EE 9\uac00 \uc801\uc6a9\ub418\uba74\uc11c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub3c4 \uc804\ubc18\uc801\uc73c\ub85c javax -> jakarta\ub85c \ubcc0\uacbd\ub418\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"pathpatternparser---trailing-slash-\ud5c8\uc6a9\ud558\uc9c0-\uc54a\uc74c",children:"PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c"}),"\n",(0,r.jsxs)(n.p,{children:["6.0 \uc774\uc804\uc758 \uacbd\uc6b0 \uae30\ubcf8 \uc124\uc815 \uae30\uc900\uc73c\ub85c ",(0,r.jsx)(n.code,{children:'@GetMapping("/hello")'}),"\uc640 ",(0,r.jsx)(n.code,{children:'@GetMapping("/hello/")'}),"\uac00 \ub3d9\uc77c\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","6.0 \uc774\ud6c4\uc758 PathPatternParser\uac00 \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\uace0, ",(0,r.jsx)(n.code,{children:"/hello"}),"\uc640 ",(0,r.jsx)(n.code,{children:"/hello/"}),"\ub294 \uc11c\ub85c \ub2e4\ub978 URL\ub85c \ub9e4\uce6d\ub41c\ub2e4."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"PathPatternParser used by default (with the ability to opt into PathMatcher)."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"http-interface-client",children:"HTTP interface client"}),"\n",(0,r.jsxs)(n.p,{children:["\uc790\ubc14 \uc778\ud130\ud398\uc774\uc2a4\uc640 \uc5b4\ub178\ud14c\uc774\uc158\uc744 \uc774\uc6a9\ud558\uc5ec HTTP \uc694\uccad\uc744 \uc704\ud55c \uc11c\ube44\uc2a4\ub97c \uc815\uc758\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 ",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=Kb37Q5GCyZs",children:"\ud1a0\ube44\ub2d8\uc758 \uac15\uc758"}),"\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ucd5c\uc18c-\uc694\uad6c\uc0ac\ud56d",children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d"}),"\n",(0,r.jsxs)(n.p,{children:["Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6",(0,r.jsx)(n.br,{}),"\n","\uc774\uc678\uc5d0\ub3c4 \uc11c\ub4dc\ud30c\ud2f0\ub4e4\uc758 \ucd5c\uc2e0 \ub9b4\ub9ac\uc988 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c, \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ud574\ub2f9 \ubc84\uc804\uc5d0 \ub9de\ub294 \ub9b4\ub9ac\uc988 \ub178\ud2b8\ub97c \ucc38\uace0\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=1WT6oxchM9M",children:"\uc5b4\ub290\xa0\uc6d4\uae09\uc7c1\uc774\uac1c\ubc1c\uc790\xa0\uc758 \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ub530\ub77c\uc7a1\uae30"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=7SlDdzVk6GE",children:"\uc790\ubc14 9-16 \uc8fc\uc694 \ud2b9\uc9d5 \ubcf5\uc2b5\ud558\uae30"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.samsungsds.com/kr/insights/java_jakarta.html",children:"Java EE\uc5d0\uc11c Jakarta EE\ub85c\uc758 \uc804\ud658"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=Kb37Q5GCyZs",children:"Spring 6\uc758 \uc0c8\ub85c\uc6b4 HTTP Interface\uc640 3 \uac00\uc9c0 REST Clients \ub77c\uc774\ube0c \ucf54\ub529"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x",children:"What's New in Spring Framework 6.x"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes",children:"Spring Boot 3.0 Release Notes"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes",children:"Spring Boot 3.1 Release Notes"})]})]})}function d(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>c});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var o=r.createContext({}),c=function(e){var n=r.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},h={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,o=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(t),j=a,u=p["".concat(o,".").concat(j)]||p[j]||h[j]||i;return t?r.createElement(u,s(s({ref:n},d),{},{components:t})):r.createElement(u,s({ref:n},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/27.96a4e28f.js b/assets/js/27.96a4e28f.js new file mode 100644 index 000000000..a49271a09 --- /dev/null +++ b/assets/js/27.96a4e28f.js @@ -0,0 +1,540 @@ +"use strict"; +exports.id = 27; +exports.ids = [27]; +exports.modules = { + +/***/ 42027: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17967); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(64218); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 9, 10]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "info": 4, "document": 5, "EOF": 6, "line": 7, "statement": 8, "NL": 9, "showInfo": 10, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "info", 6: "EOF", 9: "NL", 10: "showInfo" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 1], [7, 1], [8, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + $$.length - 1; + switch (yystate) { + case 1: + return yy; + case 4: + break; + case 6: + yy.setInfo(true); + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: 6, 9: [1, 7], 10: [1, 8] }, { 1: [2, 1] }, o($V0, [2, 3]), o($V0, [2, 4]), o($V0, [2, 5]), o($V0, [2, 6])], + defaultActions: { 4: [2, 1] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 4; + case 1: + return 9; + case 2: + return "space"; + case 3: + return 10; + case 4: + return 6; + case 5: + return "TXT"; + } + }, + rules: [/^(?:info\b)/i, /^(?:[\s\n\r]+)/i, /^(?:[\s]+)/i, /^(?:showInfo\b)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "INITIAL": { "rules": [0, 1, 2, 3, 4, 5], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const DEFAULT_INFO_DB = { + info: false +}; +let info = DEFAULT_INFO_DB.info; +const setInfo = (toggle) => { + info = toggle; +}; +const getInfo = () => info; +const clear = () => { + info = DEFAULT_INFO_DB.info; +}; +const db = { + clear, + setInfo, + getInfo +}; +const draw = (text, id, version) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("rendering info diagram\n" + text); + const svg = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.z)(id); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.i)(svg, 100, 400, true); + const group = svg.append("g"); + group.append("text").attr("x", 100).attr("y", 40).attr("class", "version").attr("font-size", 32).style("text-anchor", "middle").text(`v${version}`); +}; +const renderer = { draw }; +const diagram = { + parser: parser$1, + db, + renderer +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/274c9143.f313ce06.js b/assets/js/274c9143.5b1f6476.js similarity index 88% rename from assets/js/274c9143.f313ce06.js rename to assets/js/274c9143.5b1f6476.js index fa1b9aeee..e6b4b983e 100644 --- a/assets/js/274c9143.f313ce06.js +++ b/assets/js/274c9143.5b1f6476.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6984],{90058:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6984],{90058:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/278.c18a43f9.js b/assets/js/278.c18a43f9.js new file mode 100644 index 000000000..bc4a809cb --- /dev/null +++ b/assets/js/278.c18a43f9.js @@ -0,0 +1,1410 @@ +"use strict"; +exports.id = 278; +exports.ids = [278]; +exports.modules = { + +/***/ 36278: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + diagram: () => (/* binding */ diagram) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +// EXTERNAL MODULE: ./node_modules/d3/src/index.js + 197 modules +var src = __webpack_require__(64218); +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-array/src/min.js +function min(values, valueof) { + let min; + if (valueof === undefined) { + for (const value of values) { + if (value != null + && (min > value || (min === undefined && value >= value))) { + min = value; + } + } + } else { + let index = -1; + for (let value of values) { + if ((value = valueof(value, ++index, values)) != null + && (min > value || (min === undefined && value >= value))) { + min = value; + } + } + } + return min; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/src/align.js + + +function targetDepth(d) { + return d.target.depth; +} + +function left(node) { + return node.depth; +} + +function right(node, n) { + return n - 1 - node.height; +} + +function justify(node, n) { + return node.sourceLinks.length ? node.depth : n - 1; +} + +function center(node) { + return node.targetLinks.length ? node.depth + : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1 + : 0; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-array/src/sum.js +function sum(values, valueof) { + let sum = 0; + if (valueof === undefined) { + for (let value of values) { + if (value = +value) { + sum += value; + } + } + } else { + let index = -1; + for (let value of values) { + if (value = +valueof(value, ++index, values)) { + sum += value; + } + } + } + return sum; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-array/src/max.js +function max(values, valueof) { + let max; + if (valueof === undefined) { + for (const value of values) { + if (value != null + && (max < value || (max === undefined && value >= value))) { + max = value; + } + } + } else { + let index = -1; + for (let value of values) { + if ((value = valueof(value, ++index, values)) != null + && (max < value || (max === undefined && value >= value))) { + max = value; + } + } + } + return max; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/src/constant.js +function constant(x) { + return function() { + return x; + }; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/src/sankey.js + + + + +function ascendingSourceBreadth(a, b) { + return ascendingBreadth(a.source, b.source) || a.index - b.index; +} + +function ascendingTargetBreadth(a, b) { + return ascendingBreadth(a.target, b.target) || a.index - b.index; +} + +function ascendingBreadth(a, b) { + return a.y0 - b.y0; +} + +function value(d) { + return d.value; +} + +function defaultId(d) { + return d.index; +} + +function defaultNodes(graph) { + return graph.nodes; +} + +function defaultLinks(graph) { + return graph.links; +} + +function find(nodeById, id) { + const node = nodeById.get(id); + if (!node) throw new Error("missing: " + id); + return node; +} + +function computeLinkBreadths({nodes}) { + for (const node of nodes) { + let y0 = node.y0; + let y1 = y0; + for (const link of node.sourceLinks) { + link.y0 = y0 + link.width / 2; + y0 += link.width; + } + for (const link of node.targetLinks) { + link.y1 = y1 + link.width / 2; + y1 += link.width; + } + } +} + +function Sankey() { + let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent + let dx = 24; // nodeWidth + let dy = 8, py; // nodePadding + let id = defaultId; + let align = justify; + let sort; + let linkSort; + let nodes = defaultNodes; + let links = defaultLinks; + let iterations = 6; + + function sankey() { + const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)}; + computeNodeLinks(graph); + computeNodeValues(graph); + computeNodeDepths(graph); + computeNodeHeights(graph); + computeNodeBreadths(graph); + computeLinkBreadths(graph); + return graph; + } + + sankey.update = function(graph) { + computeLinkBreadths(graph); + return graph; + }; + + sankey.nodeId = function(_) { + return arguments.length ? (id = typeof _ === "function" ? _ : constant(_), sankey) : id; + }; + + sankey.nodeAlign = function(_) { + return arguments.length ? (align = typeof _ === "function" ? _ : constant(_), sankey) : align; + }; + + sankey.nodeSort = function(_) { + return arguments.length ? (sort = _, sankey) : sort; + }; + + sankey.nodeWidth = function(_) { + return arguments.length ? (dx = +_, sankey) : dx; + }; + + sankey.nodePadding = function(_) { + return arguments.length ? (dy = py = +_, sankey) : dy; + }; + + sankey.nodes = function(_) { + return arguments.length ? (nodes = typeof _ === "function" ? _ : constant(_), sankey) : nodes; + }; + + sankey.links = function(_) { + return arguments.length ? (links = typeof _ === "function" ? _ : constant(_), sankey) : links; + }; + + sankey.linkSort = function(_) { + return arguments.length ? (linkSort = _, sankey) : linkSort; + }; + + sankey.size = function(_) { + return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0]; + }; + + sankey.extent = function(_) { + return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]]; + }; + + sankey.iterations = function(_) { + return arguments.length ? (iterations = +_, sankey) : iterations; + }; + + function computeNodeLinks({nodes, links}) { + for (const [i, node] of nodes.entries()) { + node.index = i; + node.sourceLinks = []; + node.targetLinks = []; + } + const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d])); + for (const [i, link] of links.entries()) { + link.index = i; + let {source, target} = link; + if (typeof source !== "object") source = link.source = find(nodeById, source); + if (typeof target !== "object") target = link.target = find(nodeById, target); + source.sourceLinks.push(link); + target.targetLinks.push(link); + } + if (linkSort != null) { + for (const {sourceLinks, targetLinks} of nodes) { + sourceLinks.sort(linkSort); + targetLinks.sort(linkSort); + } + } + } + + function computeNodeValues({nodes}) { + for (const node of nodes) { + node.value = node.fixedValue === undefined + ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value)) + : node.fixedValue; + } + } + + function computeNodeDepths({nodes}) { + const n = nodes.length; + let current = new Set(nodes); + let next = new Set; + let x = 0; + while (current.size) { + for (const node of current) { + node.depth = x; + for (const {target} of node.sourceLinks) { + next.add(target); + } + } + if (++x > n) throw new Error("circular link"); + current = next; + next = new Set; + } + } + + function computeNodeHeights({nodes}) { + const n = nodes.length; + let current = new Set(nodes); + let next = new Set; + let x = 0; + while (current.size) { + for (const node of current) { + node.height = x; + for (const {source} of node.targetLinks) { + next.add(source); + } + } + if (++x > n) throw new Error("circular link"); + current = next; + next = new Set; + } + } + + function computeNodeLayers({nodes}) { + const x = max(nodes, d => d.depth) + 1; + const kx = (x1 - x0 - dx) / (x - 1); + const columns = new Array(x); + for (const node of nodes) { + const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x)))); + node.layer = i; + node.x0 = x0 + i * kx; + node.x1 = node.x0 + dx; + if (columns[i]) columns[i].push(node); + else columns[i] = [node]; + } + if (sort) for (const column of columns) { + column.sort(sort); + } + return columns; + } + + function initializeNodeBreadths(columns) { + const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value)); + for (const nodes of columns) { + let y = y0; + for (const node of nodes) { + node.y0 = y; + node.y1 = y + node.value * ky; + y = node.y1 + py; + for (const link of node.sourceLinks) { + link.width = link.value * ky; + } + } + y = (y1 - y + py) / (nodes.length + 1); + for (let i = 0; i < nodes.length; ++i) { + const node = nodes[i]; + node.y0 += y * (i + 1); + node.y1 += y * (i + 1); + } + reorderLinks(nodes); + } + } + + function computeNodeBreadths(graph) { + const columns = computeNodeLayers(graph); + py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1)); + initializeNodeBreadths(columns); + for (let i = 0; i < iterations; ++i) { + const alpha = Math.pow(0.99, i); + const beta = Math.max(1 - alpha, (i + 1) / iterations); + relaxRightToLeft(columns, alpha, beta); + relaxLeftToRight(columns, alpha, beta); + } + } + + // Reposition each node based on its incoming (target) links. + function relaxLeftToRight(columns, alpha, beta) { + for (let i = 1, n = columns.length; i < n; ++i) { + const column = columns[i]; + for (const target of column) { + let y = 0; + let w = 0; + for (const {source, value} of target.targetLinks) { + let v = value * (target.layer - source.layer); + y += targetTop(source, target) * v; + w += v; + } + if (!(w > 0)) continue; + let dy = (y / w - target.y0) * alpha; + target.y0 += dy; + target.y1 += dy; + reorderNodeLinks(target); + } + if (sort === undefined) column.sort(ascendingBreadth); + resolveCollisions(column, beta); + } + } + + // Reposition each node based on its outgoing (source) links. + function relaxRightToLeft(columns, alpha, beta) { + for (let n = columns.length, i = n - 2; i >= 0; --i) { + const column = columns[i]; + for (const source of column) { + let y = 0; + let w = 0; + for (const {target, value} of source.sourceLinks) { + let v = value * (target.layer - source.layer); + y += sourceTop(source, target) * v; + w += v; + } + if (!(w > 0)) continue; + let dy = (y / w - source.y0) * alpha; + source.y0 += dy; + source.y1 += dy; + reorderNodeLinks(source); + } + if (sort === undefined) column.sort(ascendingBreadth); + resolveCollisions(column, beta); + } + } + + function resolveCollisions(nodes, alpha) { + const i = nodes.length >> 1; + const subject = nodes[i]; + resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha); + resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha); + resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha); + resolveCollisionsTopToBottom(nodes, y0, 0, alpha); + } + + // Push any overlapping nodes down. + function resolveCollisionsTopToBottom(nodes, y, i, alpha) { + for (; i < nodes.length; ++i) { + const node = nodes[i]; + const dy = (y - node.y0) * alpha; + if (dy > 1e-6) node.y0 += dy, node.y1 += dy; + y = node.y1 + py; + } + } + + // Push any overlapping nodes up. + function resolveCollisionsBottomToTop(nodes, y, i, alpha) { + for (; i >= 0; --i) { + const node = nodes[i]; + const dy = (node.y1 - y) * alpha; + if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy; + y = node.y0 - py; + } + } + + function reorderNodeLinks({sourceLinks, targetLinks}) { + if (linkSort === undefined) { + for (const {source: {sourceLinks}} of targetLinks) { + sourceLinks.sort(ascendingTargetBreadth); + } + for (const {target: {targetLinks}} of sourceLinks) { + targetLinks.sort(ascendingSourceBreadth); + } + } + } + + function reorderLinks(nodes) { + if (linkSort === undefined) { + for (const {sourceLinks, targetLinks} of nodes) { + sourceLinks.sort(ascendingTargetBreadth); + targetLinks.sort(ascendingSourceBreadth); + } + } + } + + // Returns the target.y0 that would produce an ideal link from source to target. + function targetTop(source, target) { + let y = source.y0 - (source.sourceLinks.length - 1) * py / 2; + for (const {target: node, width} of source.sourceLinks) { + if (node === target) break; + y += width + py; + } + for (const {source: node, width} of target.targetLinks) { + if (node === source) break; + y -= width; + } + return y; + } + + // Returns the source.y0 that would produce an ideal link from source to target. + function sourceTop(source, target) { + let y = target.y0 - (target.targetLinks.length - 1) * py / 2; + for (const {source: node, width} of target.targetLinks) { + if (node === source) break; + y += width + py; + } + for (const {target: node, width} of source.sourceLinks) { + if (node === target) break; + y -= width; + } + return y; + } + + return sankey; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-path/src/path.js +var pi = Math.PI, + tau = 2 * pi, + epsilon = 1e-6, + tauEpsilon = tau - epsilon; + +function Path() { + this._x0 = this._y0 = // start of current subpath + this._x1 = this._y1 = null; // end of current subpath + this._ = ""; +} + +function path() { + return new Path; +} + +Path.prototype = path.prototype = { + constructor: Path, + moveTo: function(x, y) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); + }, + closePath: function() { + if (this._x1 !== null) { + this._x1 = this._x0, this._y1 = this._y0; + this._ += "Z"; + } + }, + lineTo: function(x, y) { + this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); + }, + quadraticCurveTo: function(x1, y1, x, y) { + this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + bezierCurveTo: function(x1, y1, x2, y2, x, y) { + this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + arcTo: function(x1, y1, x2, y2, r) { + x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; + var x0 = this._x1, + y0 = this._y1, + x21 = x2 - x1, + y21 = y2 - y1, + x01 = x0 - x1, + y01 = y0 - y1, + l01_2 = x01 * x01 + y01 * y01; + + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); + + // Is this path empty? Move to (x1,y1). + if (this._x1 === null) { + this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); + } + + // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. + else if (!(l01_2 > epsilon)); + + // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? + // Equivalently, is (x1,y1) coincident with (x2,y2)? + // Or, is the radius zero? Line to (x1,y1). + else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) { + this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); + } + + // Otherwise, draw an arc! + else { + var x20 = x2 - x0, + y20 = y2 - y0, + l21_2 = x21 * x21 + y21 * y21, + l20_2 = x20 * x20 + y20 * y20, + l21 = Math.sqrt(l21_2), + l01 = Math.sqrt(l01_2), + l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), + t01 = l / l01, + t21 = l / l21; + + // If the start tangent is not coincident with (x0,y0), line to. + if (Math.abs(t01 - 1) > epsilon) { + this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); + } + + this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); + } + }, + arc: function(x, y, r, a0, a1, ccw) { + x = +x, y = +y, r = +r, ccw = !!ccw; + var dx = r * Math.cos(a0), + dy = r * Math.sin(a0), + x0 = x + dx, + y0 = y + dy, + cw = 1 ^ ccw, + da = ccw ? a0 - a1 : a1 - a0; + + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); + + // Is this path empty? Move to (x0,y0). + if (this._x1 === null) { + this._ += "M" + x0 + "," + y0; + } + + // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). + else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) { + this._ += "L" + x0 + "," + y0; + } + + // Is this arc empty? We’re done. + if (!r) return; + + // Does the angle go the wrong way? Flip the direction. + if (da < 0) da = da % tau + tau; + + // Is this a complete circle? Draw two arcs to complete the circle. + if (da > tauEpsilon) { + this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); + } + + // Is this arc non-empty? Draw an arc! + else if (da > epsilon) { + this._ += "A" + r + "," + r + ",0," + (+(da >= pi)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); + } + }, + rect: function(x, y, w, h) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; + }, + toString: function() { + return this._; + } +}; + +/* harmony default export */ const src_path = (path); + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-shape/src/array.js +var slice = Array.prototype.slice; + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-shape/src/constant.js +/* harmony default export */ function src_constant(x) { + return function constant() { + return x; + }; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-shape/src/point.js +function point_x(p) { + return p[0]; +} + +function point_y(p) { + return p[1]; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/node_modules/d3-shape/src/link/index.js + + + + + + +function linkSource(d) { + return d.source; +} + +function linkTarget(d) { + return d.target; +} + +function link_link(curve) { + var source = linkSource, + target = linkTarget, + x = point_x, + y = point_y, + context = null; + + function link() { + var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv); + if (!context) context = buffer = src_path(); + curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv)); + if (buffer) return context = null, buffer + "" || null; + } + + link.source = function(_) { + return arguments.length ? (source = _, link) : source; + }; + + link.target = function(_) { + return arguments.length ? (target = _, link) : target; + }; + + link.x = function(_) { + return arguments.length ? (x = typeof _ === "function" ? _ : src_constant(+_), link) : x; + }; + + link.y = function(_) { + return arguments.length ? (y = typeof _ === "function" ? _ : src_constant(+_), link) : y; + }; + + link.context = function(_) { + return arguments.length ? ((context = _ == null ? null : _), link) : context; + }; + + return link; +} + +function curveHorizontal(context, x0, y0, x1, y1) { + context.moveTo(x0, y0); + context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1); +} + +function curveVertical(context, x0, y0, x1, y1) { + context.moveTo(x0, y0); + context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1); +} + +function curveRadial(context, x0, y0, x1, y1) { + var p0 = pointRadial(x0, y0), + p1 = pointRadial(x0, y0 = (y0 + y1) / 2), + p2 = pointRadial(x1, y0), + p3 = pointRadial(x1, y1); + context.moveTo(p0[0], p0[1]); + context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]); +} + +function linkHorizontal() { + return link_link(curveHorizontal); +} + +function linkVertical() { + return link_link(curveVertical); +} + +function linkRadial() { + var l = link_link(curveRadial); + l.angle = l.x, delete l.x; + l.radius = l.y, delete l.y; + return l; +} + +;// CONCATENATED MODULE: ./node_modules/d3-sankey/src/sankeyLinkHorizontal.js + + +function horizontalSource(d) { + return [d.source.x1, d.y0]; +} + +function horizontalTarget(d) { + return [d.target.x0, d.y1]; +} + +/* harmony default export */ function sankeyLinkHorizontal() { + return linkHorizontal() + .source(horizontalSource) + .target(horizontalTarget); +} + +// EXTERNAL MODULE: ./node_modules/dayjs/dayjs.min.js +var dayjs_min = __webpack_require__(27484); +// EXTERNAL MODULE: ./node_modules/@braintree/sanitize-url/dist/index.js +var dist = __webpack_require__(17967); +// EXTERNAL MODULE: ./node_modules/dompurify/dist/purify.es.js +var purify_es = __webpack_require__(20683); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/sankeyDiagram-8f13d901.js + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 9], $V1 = [1, 10], $V2 = [1, 5, 10, 12]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "SANKEY": 4, "NEWLINE": 5, "csv": 6, "opt_eof": 7, "record": 8, "csv_tail": 9, "EOF": 10, "field[source]": 11, "COMMA": 12, "field[target]": 13, "field[value]": 14, "field": 15, "escaped": 16, "non_escaped": 17, "DQUOTE": 18, "ESCAPED_TEXT": 19, "NON_ESCAPED_TEXT": 20, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SANKEY", 5: "NEWLINE", 10: "EOF", 11: "field[source]", 12: "COMMA", 13: "field[target]", 14: "field[value]", 18: "DQUOTE", 19: "ESCAPED_TEXT", 20: "NON_ESCAPED_TEXT" }, + productions_: [0, [3, 4], [6, 2], [9, 2], [9, 0], [7, 1], [7, 0], [8, 5], [15, 1], [15, 1], [16, 3], [17, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 7: + const source = yy.findOrCreateNode($$[$0 - 4].trim().replaceAll('""', '"')); + const target = yy.findOrCreateNode($$[$0 - 2].trim().replaceAll('""', '"')); + const value = parseFloat($$[$0].trim()); + yy.addLink(source, target, value); + break; + case 8: + case 9: + case 11: + this.$ = $$[$0]; + break; + case 10: + this.$ = $$[$0 - 1]; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, { 5: [1, 3] }, { 6: 4, 8: 5, 15: 6, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 1: [2, 6], 7: 11, 10: [1, 12] }, o($V1, [2, 4], { 9: 13, 5: [1, 14] }), { 12: [1, 15] }, o($V2, [2, 8]), o($V2, [2, 9]), { 19: [1, 16] }, o($V2, [2, 11]), { 1: [2, 1] }, { 1: [2, 5] }, o($V1, [2, 2]), { 6: 17, 8: 5, 15: 6, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 15: 18, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 18: [1, 19] }, o($V1, [2, 3]), { 12: [1, 20] }, o($V2, [2, 10]), { 15: 21, 16: 7, 17: 8, 18: $V0, 20: $V1 }, o([1, 5, 10], [2, 7])], + defaultActions: { 11: [2, 1], 12: [2, 5] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "easy_keword_rules": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.pushState("csv"); + return 4; + case 1: + return 10; + case 2: + return 5; + case 3: + return 12; + case 4: + this.pushState("escaped_text"); + return 18; + case 5: + return 20; + case 6: + this.popState("escaped_text"); + return 18; + case 7: + return 19; + } + }, + rules: [/^(?:sankey-beta\b)/, /^(?:$)/, /^(?:((\u000D\u000A)|(\u000A)))/, /^(?:(\u002C))/, /^(?:(\u0022))/, /^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/, /^(?:(\u0022)(?!(\u0022)))/, /^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/], + conditions: { "csv": { "rules": [1, 2, 3, 4, 5, 6, 7], "inclusive": false }, "escaped_text": { "rules": [6, 7], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let links = []; +let nodes = []; +let nodesMap = {}; +const clear = () => { + links = []; + nodes = []; + nodesMap = {}; + (0,mermaid_8af3addd.t)(); +}; +class SankeyLink { + constructor(source, target, value = 0) { + this.source = source; + this.target = target; + this.value = value; + } +} +const addLink = (source, target, value) => { + links.push(new SankeyLink(source, target, value)); +}; +class SankeyNode { + constructor(ID) { + this.ID = ID; + } +} +const findOrCreateNode = (ID) => { + ID = mermaid_8af3addd.e.sanitizeText(ID, (0,mermaid_8af3addd.c)()); + if (!nodesMap[ID]) { + nodesMap[ID] = new SankeyNode(ID); + nodes.push(nodesMap[ID]); + } + return nodesMap[ID]; +}; +const getNodes = () => nodes; +const getLinks = () => links; +const getGraph = () => ({ + nodes: nodes.map((node) => ({ id: node.ID })), + links: links.map((link) => ({ + source: link.source.ID, + target: link.target.ID, + value: link.value + })) +}); +const db = { + nodesMap, + getConfig: () => (0,mermaid_8af3addd.c)().sankey, + getNodes, + getLinks, + getGraph, + addLink, + findOrCreateNode, + getAccTitle: mermaid_8af3addd.g, + setAccTitle: mermaid_8af3addd.s, + getAccDescription: mermaid_8af3addd.a, + setAccDescription: mermaid_8af3addd.b, + getDiagramTitle: mermaid_8af3addd.r, + setDiagramTitle: mermaid_8af3addd.q, + clear +}; +const _Uid = class _Uid2 { + static next(name) { + return new _Uid2(name + ++_Uid2.count); + } + constructor(id) { + this.id = id; + this.href = `#${id}`; + } + toString() { + return "url(" + this.href + ")"; + } +}; +_Uid.count = 0; +let Uid = _Uid; +const alignmentsMap = { + left: left, + right: right, + center: center, + justify: justify +}; +const draw = function(text, id, _version, diagObj) { + const { securityLevel, sankey: conf } = (0,mermaid_8af3addd.c)(); + const defaultSankeyConfig = mermaid_8af3addd.I.sankey; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,src/* select */.Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,src/* select */.Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,src/* select */.Ys)("body"); + const svg = securityLevel === "sandbox" ? root.select(`[id="${id}"]`) : (0,src/* select */.Ys)(`[id="${id}"]`); + const width = (conf == null ? void 0 : conf.width) ?? defaultSankeyConfig.width; + const height = (conf == null ? void 0 : conf.height) ?? defaultSankeyConfig.width; + const useMaxWidth = (conf == null ? void 0 : conf.useMaxWidth) ?? defaultSankeyConfig.useMaxWidth; + const nodeAlignment = (conf == null ? void 0 : conf.nodeAlignment) ?? defaultSankeyConfig.nodeAlignment; + const prefix = (conf == null ? void 0 : conf.prefix) ?? defaultSankeyConfig.prefix; + const suffix = (conf == null ? void 0 : conf.suffix) ?? defaultSankeyConfig.suffix; + const showValues = (conf == null ? void 0 : conf.showValues) ?? defaultSankeyConfig.showValues; + (0,mermaid_8af3addd.i)(svg, height, width, useMaxWidth); + const graph = diagObj.db.getGraph(); + const nodeAlign = alignmentsMap[nodeAlignment]; + const nodeWidth = 10; + const sankey$1 = Sankey().nodeId((d) => d.id).nodeWidth(nodeWidth).nodePadding(10 + (showValues ? 15 : 0)).nodeAlign(nodeAlign).extent([ + [0, 0], + [width, height] + ]); + sankey$1(graph); + const colorScheme = (0,src/* scaleOrdinal */.PKp)(src/* schemeTableau10 */.K2I); + svg.append("g").attr("class", "nodes").selectAll(".node").data(graph.nodes).join("g").attr("class", "node").attr("id", (d) => (d.uid = Uid.next("node-")).id).attr("transform", function(d) { + return "translate(" + d.x0 + "," + d.y0 + ")"; + }).attr("x", (d) => d.x0).attr("y", (d) => d.y0).append("rect").attr("height", (d) => { + return d.y1 - d.y0; + }).attr("width", (d) => d.x1 - d.x0).attr("fill", (d) => colorScheme(d.id)); + const getText = ({ id: id2, value }) => { + if (!showValues) { + return id2; + } + return `${id2} +${prefix}${Math.round(value * 100) / 100}${suffix}`; + }; + svg.append("g").attr("class", "node-labels").attr("font-family", "sans-serif").attr("font-size", 14).selectAll("text").data(graph.nodes).join("text").attr("x", (d) => d.x0 < width / 2 ? d.x1 + 6 : d.x0 - 6).attr("y", (d) => (d.y1 + d.y0) / 2).attr("dy", `${showValues ? "0" : "0.35"}em`).attr("text-anchor", (d) => d.x0 < width / 2 ? "start" : "end").text(getText); + const link = svg.append("g").attr("class", "links").attr("fill", "none").attr("stroke-opacity", 0.5).selectAll(".link").data(graph.links).join("g").attr("class", "link").style("mix-blend-mode", "multiply"); + const linkColor = (conf == null ? void 0 : conf.linkColor) || "gradient"; + if (linkColor === "gradient") { + const gradient = link.append("linearGradient").attr("id", (d) => (d.uid = Uid.next("linearGradient-")).id).attr("gradientUnits", "userSpaceOnUse").attr("x1", (d) => d.source.x1).attr("x2", (d) => d.target.x0); + gradient.append("stop").attr("offset", "0%").attr("stop-color", (d) => colorScheme(d.source.id)); + gradient.append("stop").attr("offset", "100%").attr("stop-color", (d) => colorScheme(d.target.id)); + } + let coloring; + switch (linkColor) { + case "gradient": + coloring = (d) => d.uid; + break; + case "source": + coloring = (d) => colorScheme(d.source.id); + break; + case "target": + coloring = (d) => colorScheme(d.target.id); + break; + default: + coloring = linkColor; + } + link.append("path").attr("d", sankeyLinkHorizontal()).attr("stroke", coloring).attr("stroke-width", (d) => Math.max(1, d.width)); +}; +const renderer = { + draw +}; +const prepareTextForParsing = (text) => { + const textToParse = text.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g, "").replaceAll(/([\n\r])+/g, "\n").trim(); + return textToParse; +}; +const originalParse = parser$1.parse.bind(parser$1); +parser$1.parse = (text) => originalParse(prepareTextForParsing(text)); +const diagram = { + parser: parser$1, + db, + renderer +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/280572f1.e70297e6.js b/assets/js/280572f1.4d349f70.js similarity index 87% rename from assets/js/280572f1.e70297e6.js rename to assets/js/280572f1.4d349f70.js index a9375c88a..80f1b5b0b 100644 --- a/assets/js/280572f1.e70297e6.js +++ b/assets/js/280572f1.4d349f70.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[324],{77874:s=>{s.exports=JSON.parse('{"label":"mysql","permalink":"/tags/mysql","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[324],{77874:s=>{s.exports=JSON.parse('{"label":"mysql","permalink":"/tags/mysql","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/284.e5c25d54.js b/assets/js/284.e5c25d54.js new file mode 100644 index 000000000..981c45341 --- /dev/null +++ b/assets/js/284.e5c25d54.js @@ -0,0 +1,25959 @@ +"use strict"; +exports.id = 284; +exports.ids = [284]; +exports.modules = { + +/***/ 41644: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + bK: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.Z(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.Z( + map/* default */.Z(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.Z(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.Z(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.k(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.Z(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.Z(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.Z(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.Z(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.Z(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.Z('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.Z(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.Z(g.outEdges(v), function (e) { + if (has/* default */.Z(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.Z(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.Z(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(59236); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.Z)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(74752); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.Z)(iteratee, 3); + + (0,_baseForOwn/* default */.Z)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.Z)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(66092); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.Z.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.Z(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.k().setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.k({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.Z(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.Z(range/* default */.Z(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.Z(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.Z(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.Z(layers, function (vs, i) { + if (isUndefined/* default */.Z(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.Z(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.Z(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.Z(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.Z(children, dfs); + } + + if (has/* default */.Z(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.Z(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, reverseYOne); + if (has/* default */.Z(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, swapXYOne); + if (has/* default */.Z(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.Z(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.Z)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.Z(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.Z(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.Z(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.k({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.Z(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.Z(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.Z(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.Z)(collection)) { + var iteratee = (0,_baseIteratee/* default */.Z)(predicate, 3); + collection = (0,keys/* default */.Z)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.Z)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.Z)(array, (0,_baseIteratee/* default */.Z)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(39473); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(93589); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.Z)(value) && (0,isObjectLike/* default */.Z)(value) && (0,_baseGetTag/* default */.Z)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.Z)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.Z)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.Z)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.Z)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.Z(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.Z(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.Z(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.Z(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.Z(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.Z(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.Z(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.Z(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.Z(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.Z(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.Z(tree.neighbors(v), function (w) { + if (!has/* default */.Z(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.Z(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.Z(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.Z(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.Z(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.Z(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.Z(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.Z(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.Z(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.Z( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.Z(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.k({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.Z(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.Z(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.Z(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.Z('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.Z); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(21018); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.Z)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.Z)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + if ((0,isArray/* default */.Z)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.Z)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.Z]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.Z)(iteratees, (0,_baseUnary/* default */.Z)(_baseIteratee/* default */.Z)); + + var result = (0,_baseMap/* default */.Z)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.Z)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.Z)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.Z)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.Z)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.Z(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.Z( + map/* default */.Z(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.Z(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.Z(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.Z( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.Z(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.Z(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.Z(range/* default */.Z(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.Z(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.Z(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.Z(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.Z(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.Z( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.Z(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.Z(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.Z(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.Z(entryV) && !isUndefined/* default */.Z(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.Z(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.Z(uEntry.barycenter) || + isUndefined/* default */.Z(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.Z(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.Z(entry.out, handleOut(entry)); + } + + return map/* default */.Z( + filter/* default */.Z(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.Z(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.Z(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.Z(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.Z(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.Z(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.Z(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.Z(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.Z([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.Z(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.Z(entries, function (entry) { + entry.vs = flatten/* default */.Z( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.Z(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.Z(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.Z(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.Z(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.k(); + forEach/* default */.Z(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.Z(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.Z(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.Z(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(68882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(61395); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee), keysIn/* default */.Z); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.Z(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.Z(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.Z(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.Z(range/* default */.Z(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.Z(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.Z(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.Z(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.Z(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.Z(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.Z(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.k(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.Z(layering, function (layer) { + var u; + forEach/* default */.Z(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.Z(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.Z(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.Z(['u', 'd'], function (vert) { + forEach/* default */.Z(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.Z(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.Z(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.Z(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.Z(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.Z(layering).reverse(); + forEach/* default */.Z(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.Z(adjustedLayering, function (inner) { + return values/* default */.Z(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.Z(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.Z(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.Z(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.Z(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.Z(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.Z(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.k({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.Z({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.Z(graph, graphAttrs)) + ); + + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.Z(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.Z({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.Z(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.Z(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.Z(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.Z(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.Z(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.Z(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.Z(layers, function (layer) { + var orderShift = 0; + forEach/* default */.Z(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.Z(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.Z(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.Z(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 52544: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + k: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(73234); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(79697); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.Z)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(93203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.Z && (1 / (0,_setToArray/* default */.Z)(new _Set/* default */.Z([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.Z(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.Z)(set); + } + isCommon = false; + includes = _cacheHas/* default */.Z; + seen = new _SetCache/* default */.Z; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(836); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.Z)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.Z)(arrays, 1, isArrayLikeObject/* default */.Z, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.Z(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.Z(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.Z(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.Z(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.Z(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.Z(this._nodes); + } + sources() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.Z(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.Z(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.Z(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.Z(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.Z(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.Z(keys/* default */.Z(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.Z(keys/* default */.Z(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.Z(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.Z(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.Z(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.Z(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.Z(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.Z(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.Z(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.Z(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.Z(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.Z(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.Z(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.Z(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.Z(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.Z(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.Z(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.Z(inV); + if (!u) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.Z(outV); + if (!w) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.Z(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 45625: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ k: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.k) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52544); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 39354: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + c: () => (/* binding */ write) +}); + +// UNUSED EXPORTS: read + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/clone.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_clone = (clone); + +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/json.js + + + + + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound(), + }, + nodes: writeNodes(g), + edges: writeEdges(g), + }; + if (!isUndefined/* default */.Z(g.graph())) { + json.value = lodash_es_clone(g.graph()); + } + return json; +} + +function writeNodes(g) { + return map/* default */.Z(g.nodes(), function (v) { + var nodeValue = g.node(v); + var parent = g.parent(v); + var node = { v: v }; + if (!isUndefined/* default */.Z(nodeValue)) { + node.value = nodeValue; + } + if (!isUndefined/* default */.Z(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return map/* default */.Z(g.edges(), function (e) { + var edgeValue = g.edge(e); + var edge = { v: e.v, w: e.w }; + if (!isUndefined/* default */.Z(e.name)) { + edge.name = e.name; + } + if (!isUndefined/* default */.Z(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function (entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function (entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + + +/***/ }), + +/***/ 63001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(37834); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.Z; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 76579: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 68774: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 74073: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 58694: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 48451: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(76579); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(31899); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keys/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keysIn/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(91050); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(87215); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(95695); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.Z)(source, (0,_getSymbols/* default */.Z)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(12513); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(60532); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.Z : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.Z)(result, (0,_getSymbols/* default */.Z)(object)); + object = (0,_getPrototype/* default */.Z)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.Z)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(63327); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.Z)(object, keysIn/* default */.Z, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(41884); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.Z)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(12701); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.Z)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.Z)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(73658); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(98351); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.Z)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.Z)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.Z)(value)) { + return value; + } + var isArr = (0,isArray/* default */.Z)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.Z)(value, result); + } + } else { + var tag = (0,_getTag/* default */.Z)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.Z)(value)) { + return (0,_cloneBuffer/* default */.Z)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.Z)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.Z); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.Z) + : (isFlat ? keysIn/* default */.Z : keys/* default */.Z); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.Z)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.Z)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 49811: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.Z)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.Z); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 21692: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 10626: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(29169); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.Z ? _Symbol/* default */.Z.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.Z)(value) || (0,isArguments/* default */.Z)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.Z)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 2693: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61395); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 13317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 63327: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58694); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 74765: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.Z : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.Z)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(84073); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(79651); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.Z(object), new _Uint8Array/* default */.Z(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.Z)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.Z); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.Z)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.Z)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(18843); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.Z)(object), + othIsArr = (0,isArray/* default */.Z)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.Z)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.Z)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.Z)(object)) { + if (!(0,isBuffer/* default */.Z)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.Z); + return (objIsArr || (0,isTypedArray/* default */.Z)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.Z); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.Z); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.Z)(value) && !(0,isObjectLike/* default */.Z)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.Z; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.Z)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.Z)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.Z)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.Z)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.Z)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.Z)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.Z)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.Z)(path) ? (0,_baseProperty/* default */.Z)((0,_toKey/* default */.Z)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.Z; + } + if (typeof value == 'object') { + return (0,isArray/* default */.Z)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 21018: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49811); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 54193: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 59548: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 68882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69203); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 22823: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(42454); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.Z)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(50751); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.Z)(value)) { + return value; + } + return (0,_isKey/* default */.Z)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.Z)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 1808: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63327); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(95695); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 95695: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68774); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(60532); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 16174: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29169); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27771); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(56009); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1656); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 99365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72714); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 6545: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 62281: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72714); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 3688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69581); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(79651); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50439); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32957); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 13445: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(68774); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.Z)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayFilter/* default */.Z : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.Z)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 27961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10626); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 70870: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76579); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49811); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(68882); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 17452: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 75487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 72714: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93589); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18533); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 49360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 17179: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87668); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39473); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 43836: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74073); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74765); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21018); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 61666: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(22823); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(56009); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.Z)(object)) { + return object; + } + path = (0,_castPath/* default */.Z)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.Z)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.Z)(objValue) + ? objValue + : ((0,_isIndex/* default */.Z)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.Z)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.Z)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.Z)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.Z)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(81211); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(27227); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.Z)((0,_overRest/* default */.Z)(func, undefined, flatten/* default */.Z), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 74379: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.Z)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.Z)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.Z)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.Z)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 92344: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.Z)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.Z); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 60532: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 94099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.Z)(value)) { + return NAN; + } + if ((0,isObject/* default */.Z)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.Z)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 50751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.Z)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.Z)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.Z)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 66749: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50751); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 34148: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.Z)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.Z)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 64589: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record} */ + const left = maybe || (all[hook] = {}) + /** @type {Record | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array} existing + * @param {Array} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function micromark_util_chunked_splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function micromark_util_chunked_push(list, items) { + if (list.length > 0) { + micromark_util_chunked_splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array} */ + let parameters + /** @type {Array} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + micromark_util_chunked_splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array} events + * @param {number} eventIndex + * @returns {Record} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record} */ + const gaps = {} + /** @type {Array} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + micromark_util_chunked_splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record} */ + const columnStart = {} + /** @type {Array} */ + const resolveAllConstructs = [] + /** @type {Array} */ + let chunks = [] + /** @type {Array} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array} chunks + * @param {Pick} token + * @returns {Array} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * + * b> + * + * + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`` or `b`). + * @param {TokenType} literalType + * Type when enclosed (``). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * . + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After ` | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | &<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | + * ^^ + * > | + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > |
+ * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after ` | + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > |
+ * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + *

!^a

+ *

!^a

+ * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | ab + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a c + * ^ + * > | a c + * ^ + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * > | a c + * ^ + * > | a &<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after ` | a c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After ` | a &<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a &<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a
c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array} events + * @returns {Array} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract} Parent + * + * @typedef {Omit & {type: 'fragment', children: Array}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array} transforms + * Tree transforms. + * + * @typedef {Partial} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array} stack + * Stack of nodes. + * @property {Array} tokenStack + * Stack of tokens. + * @property {(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(18464); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-62fc7601.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.Z)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "
"); + } else if (node.type === "strong") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "emphasis") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "paragraph") { + return `

${node.children.map(output).join("")}

`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + " + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_8af3addd.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_8af3addd.J)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 27707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ insertEdge), +/* harmony export */ h: () => (/* binding */ positionEdgeLabel), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(64589); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '" + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "
"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + img.style.width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = bbox.width + node.padding; + const totalHeight = bbox.height + node.padding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("
") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc82", edge, edge.labelType); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Moving label abc78 ", edge.id, edge.label, edgeLabels[edge.id]); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc78" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundryNode) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 cutPathAtIntersect", _points, boundryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 checking point", point2, boundryNode); + if (!outsideNode(boundryNode, point2) && !isInside) { + const inter = intersection(boundryNode, lastPointOutside, point2); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 inside", point2, lastPointOutside, inter); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 intersection", inter); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 no intersect", inter, points); + } + isInside = true; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 outside", point2, lastPointOutside); + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 returning points", points); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 InsertEdge: ", edge); + if (head.intersect && tail.intersect) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Last point", + points[points.length - 1], + head, + head.intersect(points[points.length - 1]) + ); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .$0Z; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeStart", edge.arrowTypeStart); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeEnd", edge.arrowTypeEnd); + switch (edge.arrowTypeStart) { + case "arrow_cross": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-crossStart)" + ); + break; + case "arrow_point": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-pointStart)" + ); + break; + case "arrow_barb": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-barbStart)" + ); + break; + case "arrow_circle": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-circleStart)" + ); + break; + case "aggregation": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationStart)" + ); + break; + case "extension": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-extensionStart)" + ); + break; + case "composition": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-compositionStart)" + ); + break; + case "dependency": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyStart)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopStart)" + ); + break; + } + switch (edge.arrowTypeEnd) { + case "arrow_cross": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-crossEnd)"); + break; + case "arrow_point": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-pointEnd)"); + break; + case "arrow_barb": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-barbEnd)"); + break; + case "arrow_circle": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-circleEnd)"); + break; + case "aggregation": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationEnd)" + ); + break; + case "extension": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-extensionEnd)" + ); + break; + case "composition": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-compositionEnd)" + ); + break; + case "dependency": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyEnd)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopEnd)" + ); + break; + } + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 90360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ r: () => (/* binding */ render) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39354); +/* harmony import */ var _edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(27707); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(45625); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(64589); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(64218); + + + + + + + +let clusterDb = {}; +let descendants = {}; +let parents = {}; +const clear$1 = () => { + descendants = {}; + parents = {}; + clusterDb = {}; +}; +const isDescendant = (id, ancenstorId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("In isDecendant", ancenstorId, " ", id, " = ", descendants[ancenstorId].includes(id)); + if (descendants[ancenstorId].includes(id)) { + return true; + } + return false; +}; +const edgeInCluster = (edge, clusterId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Decendants of ", clusterId, " is ", descendants[clusterId]); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge is ", edge); + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } + if (!descendants[clusterId]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Tilt, ", clusterId, ",not in decendants"); + return false; + } + return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w); +}; +const copy = (clusterId, graph, newGraph, rootId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Copying children of ", + clusterId, + "root", + rootId, + "data", + graph.node(clusterId), + rootId + ); + const nodes = graph.children(clusterId) || []; + if (clusterId !== rootId) { + nodes.push(clusterId); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes); + nodes.forEach((node) => { + if (graph.children(node).length > 0) { + copy(node, graph, newGraph, rootId); + } else { + const data = graph.node(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("cp ", node, " to ", rootId, " with parent ", clusterId); + newGraph.setNode(node, data); + if (rootId !== graph.parent(node)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Setting parent", node, graph.parent(node)); + newGraph.setParent(node, graph.parent(node)); + } + if (clusterId !== rootId && node !== clusterId) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Setting parent", node, clusterId); + newGraph.setParent(node, clusterId); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Not Setting parent for node=", + node, + "cluster!==rootId", + clusterId !== rootId, + "node!==clusterId", + node !== clusterId + ); + } + const edges = graph.edges(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Copying Edges", edges); + edges.forEach((edge) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge", edge); + const data2 = graph.edge(edge.v, edge.w, edge.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge data", data2, rootId); + try { + if (edgeInCluster(edge, rootId)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Copying as ", edge.v, edge.w, data2, edge.name); + newGraph.setEdge(edge.v, edge.w, data2, edge.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0])); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Skipping copy of edge ", + edge.v, + "-->", + edge.w, + " rootId: ", + rootId, + " clusterId:", + clusterId + ); + } + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error(e); + } + }); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Removing node", node); + graph.removeNode(node); + }); +}; +const extractDescendants = (id, graph) => { + const children = graph.children(id); + let res = [...children]; + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; + } + return res; +}; +const findNonClusterChild = (id, graph) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching", id); + const children = graph.children(id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching children of id ", id, children); + if (children.length < 1) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("This is a valid node", id); + return id; + } + for (const child of children) { + const _id = findNonClusterChild(child, graph); + if (_id) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Found replacement for", id, " => ", _id); + return _id; + } + } +}; +const getAnchorId = (id) => { + if (!clusterDb[id]) { + return id; + } + if (!clusterDb[id].externalConnections) { + return id; + } + if (clusterDb[id]) { + return clusterDb[id].id; + } + return id; +}; +const adjustClustersAndEdges = (graph, depth) => { + if (!graph || depth > 10) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting out, no graph "); + return; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting in, graph "); + } + graph.nodes().forEach(function(id) { + const children = graph.children(id); + if (children.length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster identified", + id, + " Replacement id in edges: ", + findNonClusterChild(id, graph) + ); + descendants[id] = extractDescendants(id, graph); + clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; + } + }); + graph.nodes().forEach(function(id) { + const children = graph.children(id); + const edges = graph.edges(); + if (children.length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Cluster identified", id, descendants); + edges.forEach((edge) => { + if (edge.v !== id && edge.w !== id) { + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); + if (d1 ^ d2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge: ", edge, " leaves cluster ", id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Decendants of XXX ", id, ": ", descendants[id]); + clusterDb[id].externalConnections = true; + } + } + }); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster ", id, descendants); + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + let v = e.v; + let w = e.w; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Fix XXX", + clusterDb, + "ids:", + e.v, + e.w, + "Translating: ", + clusterDb[e.v], + " --- ", + clusterDb[e.w] + ); + if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + const specialId = e.w + "---" + e.v; + graph.setNode(specialId, { + domId: specialId, + id: specialId, + labelStyle: "", + labelText: edge.label, + padding: 0, + shape: "labelRect", + style: "" + }); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); + edge1.label = ""; + edge1.arrowTypeEnd = "none"; + edge2.label = ""; + edge1.fromCluster = e.v; + edge2.toCluster = e.v; + graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special"); + graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special"); + } else if (clusterDb[e.v] || clusterDb[e.w]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + if (v !== e.v) { + edge.fromCluster = e.v; + } + if (w !== e.w) { + edge.toCluster = e.w; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fix Replacing with XXX", v, w, e.name); + graph.setEdge(v, w, edge, e.name); + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Adjusted Graph", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + extractor(graph, 0); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace(clusterDb); +}; +const extractor = (graph, depth) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("extractor - ", depth, dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph), graph.children("D")); + if (depth > 10) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("Bailing out"); + return; + } + let nodes = graph.nodes(); + let hasChildren = false; + for (const node of nodes) { + const children = graph.children(node); + hasChildren = hasChildren || children.length > 0; + } + if (!hasChildren) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Done, no node has children", graph.nodes()); + return; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Nodes = ", nodes, depth); + for (const node of nodes) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Extracting node", + node, + clusterDb, + clusterDb[node] && !clusterDb[node].externalConnections, + !graph.parent(node), + graph.node(node), + graph.children("D"), + " Depth ", + depth + ); + if (!clusterDb[node]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster", node, depth); + } else if (!clusterDb[node].externalConnections && // !graph.parent(node) && + graph.children(node) && graph.children(node).length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster without external connections, without a parent and with children", + node, + depth + ); + const graphSettings = graph.graph(); + let dir = graphSettings.rankdir === "TB" ? "LR" : "TB"; + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing dir", clusterDb[node].clusterData.dir, dir); + } + const clusterGraph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + // Todo: set proper spacing + nodesep: 50, + ranksep: 50, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Old graph before copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + copy(node, graph, clusterGraph, node); + graph.setNode(node, { + clusterNode: true, + id: node, + clusterData: clusterDb[node].clusterData, + labelText: clusterDb[node].labelText, + graph: clusterGraph + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New graph after copy node: (", node, ")", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(clusterGraph)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Old graph after copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster ** ", + node, + " **not meeting the criteria !externalConnections:", + !clusterDb[node].externalConnections, + " no parent: ", + !graph.parent(node), + " children ", + graph.children(node) && graph.children(node).length > 0, + graph.children("D"), + depth + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(clusterDb); + } + } + nodes = graph.nodes(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New list of nodes", nodes); + for (const node of nodes) { + const data = graph.node(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn(" Now next level", node, data); + if (data.clusterNode) { + extractor(data.graph, depth + 1); + } + } +}; +const sorter = (graph, nodes) => { + if (nodes.length === 0) { + return []; + } + let result = Object.assign(nodes); + nodes.forEach((node) => { + const children = graph.children(node); + const sorted = sorter(graph, children); + result = [...result, ...sorted]; + }); + return result; +}; +const sortNodesByHierarchy = (graph) => sorter(graph, graph.children()); +const rect = (parent, node) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Creating subgraph rect for ", node.id, node); + const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const text = node.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_5__.a)(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild((0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width; + if (node.width <= bbox.width + padding) { + node.diff = (bbox.width - node.width) / 2 - node.padding / 2; + } else { + node.diff = -node.padding / 2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Data ", node, JSON.stringify(node)); + rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding); + if (useHtmlLabels) { + label.attr( + "transform", + // This puts the labal on top of the box instead of inside it + "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2) + ")" + ); + } else { + label.attr( + "transform", + // This puts the labal on top of the box instead of inside it + "translate(" + node.x + ", " + (node.y - node.height / 2) + ")" + ); + } + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const noteGroup = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none"); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const roundedWithTitle = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const innerRect = shapeSvg.append("rect"); + const text = label.node().appendChild((0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + bbox = text.getBBox(); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (bbox.width + node.padding * 0 - node.width) / 2; + } else { + node.diff = -node.padding / 2; + } + rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding); + innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3); + label.attr( + "transform", + "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2 - node.padding / 3 + ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels) ? 5 : 3)) + ")" + ); + const rectBox = rect2.node().getBBox(); + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const divider = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.diff = -node.padding / 2; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const shapes = { rect, roundedWithTitle, noteGroup, divider }; +let clusterElems = {}; +const insertCluster = (elem, node) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Inserting cluster"); + const shape = node.shape || "rect"; + clusterElems[node.id] = shapes[shape](elem, node); +}; +const clear = () => { + clusterElems = {}; +}; +const recursiveRender = async (_elem, graph, diagramtype, id, parentCluster) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph in recursive render: XXX", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph), parentCluster); + const dir = graph.graph().rankdir; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Dir in recursive render - dir:", dir); + const elem = _elem.insert("g").attr("class", "root"); + if (!graph.nodes()) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("No nodes found for", graph); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Recursive render XXX", graph.nodes()); + } + if (graph.edges().length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Recursive edges", graph.edge(graph.edges()[0])); + } + const clusters = elem.insert("g").attr("class", "clusters"); + const edgePaths = elem.insert("g").attr("class", "edgePaths"); + const edgeLabels = elem.insert("g").attr("class", "edgeLabels"); + const nodes = elem.insert("g").attr("class", "nodes"); + await Promise.all( + graph.nodes().map(async function(v) { + const node = graph.node(v); + if (parentCluster !== void 0) { + const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Setting data for cluster XXX (", v, ") ", data, parentCluster); + graph.setNode(parentCluster.id, data); + if (!graph.parent(v)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Setting parent", v, parentCluster.id); + graph.setParent(v, parentCluster.id, data); + } + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v))); + if (node && node.clusterNode) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster identified", v, node.width, graph.node(v)); + const o = await recursiveRender(nodes, node.graph, diagramtype, id, graph.node(v)); + const newEl = o.elem; + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.u)(node, newEl); + node.diff = o.diff || 0; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node bounds (abc123)", v, node, node.width, node.x, node.y); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.s)(newEl, node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Recursive render complete ", newEl, node); + } else { + if (graph.children(v).length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster - the non recursive path XXX", v, node.id, node, graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(findNonClusterChild(node.id, graph)); + clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node - the non recursive path", v, node.id, node); + await (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, graph.node(v), dir); + } + } + }) + ); + graph.edges().forEach(function(e) { + const edge = graph.edge(e.v, e.w, e.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e))); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Fix", clusterDb, "ids:", e.v, e.w, "Translateing: ", clusterDb[e.v], clusterDb[e.w]); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.f)(edgeLabels, edge); + }); + graph.edges().forEach(function(e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("### Layout ###"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(graph); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__/* .layout */ .bK)(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph after layout:", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + let diff = 0; + sortNodesByHierarchy(graph).forEach(function(v) { + const node = graph.node(v); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Position " + v + ": " + JSON.stringify(graph.node(v))); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Position " + v + ": (" + node.x, + "," + node.y, + ") width: ", + node.width, + " height: ", + node.height + ); + if (node && node.clusterNode) { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } else { + if (graph.children(v).length > 0) { + insertCluster(clusters, node); + clusterDb[node.id].node = node; + } else { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge); + const paths = (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.g)(edgePaths, e, edge, clusterDb, diagramtype, graph, id); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.h)(edge, paths); + }); + graph.nodes().forEach(function(v) { + const n = graph.node(v); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(v, n.type, n.diff); + if (n.type === "group") { + diff = n.diff; + } + }); + return { elem, diff }; +}; +const render = async (elem, graph, markers, diagramtype, id) => { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.a)(elem, markers, diagramtype, id); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.b)(); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.d)(); + clear(); + clear$1(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph at first:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph))); + adjustClustersAndEdges(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph after:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph))); + await recursiveRender(elem, graph, diagramtype, id); +}; + + + +/***/ }), + +/***/ 66284: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(52244); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(45625); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(64218); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(56363); +/* harmony import */ var _index_2c4b9a3b_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(90360); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20683); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(39354); + + + + + + + + + + + + + + + + + + + +const SHAPE_STATE = "rect"; +const SHAPE_STATE_WITH_DESC = "rectWithTitle"; +const SHAPE_START = "start"; +const SHAPE_END = "end"; +const SHAPE_DIVIDER = "divider"; +const SHAPE_GROUP = "roundedWithTitle"; +const SHAPE_NOTE = "note"; +const SHAPE_NOTEGROUP = "noteGroup"; +const CSS_DIAGRAM = "statediagram"; +const CSS_STATE = "state"; +const CSS_DIAGRAM_STATE = `${CSS_DIAGRAM}-${CSS_STATE}`; +const CSS_EDGE = "transition"; +const CSS_NOTE = "note"; +const CSS_NOTE_EDGE = "note-edge"; +const CSS_EDGE_NOTE_EDGE = `${CSS_EDGE} ${CSS_NOTE_EDGE}`; +const CSS_DIAGRAM_NOTE = `${CSS_DIAGRAM}-${CSS_NOTE}`; +const CSS_CLUSTER = "cluster"; +const CSS_DIAGRAM_CLUSTER = `${CSS_DIAGRAM}-${CSS_CLUSTER}`; +const CSS_CLUSTER_ALT = "cluster-alt"; +const CSS_DIAGRAM_CLUSTER_ALT = `${CSS_DIAGRAM}-${CSS_CLUSTER_ALT}`; +const PARENT = "parent"; +const NOTE = "note"; +const DOMID_STATE = "state"; +const DOMID_TYPE_SPACER = "----"; +const NOTE_ID = `${DOMID_TYPE_SPACER}${NOTE}`; +const PARENT_ID = `${DOMID_TYPE_SPACER}${PARENT}`; +const G_EDGE_STYLE = "fill:none"; +const G_EDGE_ARROWHEADSTYLE = "fill: #333"; +const G_EDGE_LABELPOS = "c"; +const G_EDGE_LABELTYPE = "text"; +const G_EDGE_THICKNESS = "normal"; +let nodeDb = {}; +let graphItemCount = 0; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + cnf[key]; + } +}; +const getClasses = function(text, diagramObj) { + diagramObj.db.extract(diagramObj.db.getRootDocV2()); + return diagramObj.db.getClasses(); +}; +function getClassesFromDbInfo(dbInfoItem) { + if (dbInfoItem === void 0 || dbInfoItem === null) { + return ""; + } else { + if (dbInfoItem.classes) { + return dbInfoItem.classes.join(" "); + } else { + return ""; + } + } +} +function stateDomId(itemId = "", counter = 0, type = "", typeSpacer = DOMID_TYPE_SPACER) { + const typeStr = type !== null && type.length > 0 ? `${typeSpacer}${type}` : ""; + return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`; +} +const setupNode = (g, parent, parsedItem, diagramStates, diagramDb, altFlag) => { + const itemId = parsedItem.id; + const classStr = getClassesFromDbInfo(diagramStates[itemId]); + if (itemId !== "root") { + let shape = SHAPE_STATE; + if (parsedItem.start === true) { + shape = SHAPE_START; + } + if (parsedItem.start === false) { + shape = SHAPE_END; + } + if (parsedItem.type !== _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.D) { + shape = parsedItem.type; + } + if (!nodeDb[itemId]) { + nodeDb[itemId] = { + id: itemId, + shape, + description: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.e.sanitizeText(itemId, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.c)()), + classes: `${classStr} ${CSS_DIAGRAM_STATE}` + }; + } + const newNode = nodeDb[itemId]; + if (parsedItem.description) { + if (Array.isArray(newNode.description)) { + newNode.shape = SHAPE_STATE_WITH_DESC; + newNode.description.push(parsedItem.description); + } else { + if (newNode.description.length > 0) { + newNode.shape = SHAPE_STATE_WITH_DESC; + if (newNode.description === itemId) { + newNode.description = [parsedItem.description]; + } else { + newNode.description = [newNode.description, parsedItem.description]; + } + } else { + newNode.shape = SHAPE_STATE; + newNode.description = parsedItem.description; + } + } + newNode.description = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.e.sanitizeTextOrArray(newNode.description, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.c)()); + } + if (newNode.description.length === 1 && newNode.shape === SHAPE_STATE_WITH_DESC) { + newNode.shape = SHAPE_STATE; + } + if (!newNode.type && parsedItem.doc) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.l.info("Setting cluster for ", itemId, getDir(parsedItem)); + newNode.type = "group"; + newNode.dir = getDir(parsedItem); + newNode.shape = parsedItem.type === _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.a ? SHAPE_DIVIDER : SHAPE_GROUP; + newNode.classes = newNode.classes + " " + CSS_DIAGRAM_CLUSTER + " " + (altFlag ? CSS_DIAGRAM_CLUSTER_ALT : ""); + } + const nodeData = { + labelStyle: "", + shape: newNode.shape, + labelText: newNode.description, + // typeof newNode.description === 'object' + // ? newNode.description[0] + // : newNode.description, + classes: newNode.classes, + style: "", + //styles.style, + id: itemId, + dir: newNode.dir, + domId: stateDomId(itemId, graphItemCount), + type: newNode.type, + padding: 15 + //getConfig().flowchart.padding + }; + nodeData.centerLabel = true; + if (parsedItem.note) { + const noteData = { + labelStyle: "", + shape: SHAPE_NOTE, + labelText: parsedItem.note.text, + classes: CSS_DIAGRAM_NOTE, + // useHtmlLabels: false, + style: "", + // styles.style, + id: itemId + NOTE_ID + "-" + graphItemCount, + domId: stateDomId(itemId, graphItemCount, NOTE), + type: newNode.type, + padding: 15 + //getConfig().flowchart.padding + }; + const groupData = { + labelStyle: "", + shape: SHAPE_NOTEGROUP, + labelText: parsedItem.note.text, + classes: newNode.classes, + style: "", + // styles.style, + id: itemId + PARENT_ID, + domId: stateDomId(itemId, graphItemCount, PARENT), + type: "group", + padding: 0 + //getConfig().flowchart.padding + }; + graphItemCount++; + const parentNodeId = itemId + PARENT_ID; + g.setNode(parentNodeId, groupData); + g.setNode(noteData.id, noteData); + g.setNode(itemId, nodeData); + g.setParent(itemId, parentNodeId); + g.setParent(noteData.id, parentNodeId); + let from = itemId; + let to = noteData.id; + if (parsedItem.note.position === "left of") { + from = noteData.id; + to = itemId; + } + g.setEdge(from, to, { + arrowhead: "none", + arrowType: "", + style: G_EDGE_STYLE, + labelStyle: "", + classes: CSS_EDGE_NOTE_EDGE, + arrowheadStyle: G_EDGE_ARROWHEADSTYLE, + labelpos: G_EDGE_LABELPOS, + labelType: G_EDGE_LABELTYPE, + thickness: G_EDGE_THICKNESS + }); + } else { + g.setNode(itemId, nodeData); + } + } + if (parent && parent.id !== "root") { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.l.trace("Setting node ", itemId, " to be child of its parent ", parent.id); + g.setParent(itemId, parent.id); + } + if (parsedItem.doc) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.l.trace("Adding nodes children "); + setupDoc(g, parsedItem, parsedItem.doc, diagramStates, diagramDb, !altFlag); + } +}; +const setupDoc = (g, parentParsedItem, doc, diagramStates, diagramDb, altFlag) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.l.trace("items", doc); + doc.forEach((item) => { + switch (item.stmt) { + case _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.b: + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); + break; + case _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.D: + setupNode(g, parentParsedItem, item, diagramStates, diagramDb, altFlag); + break; + case _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.S: + { + setupNode(g, parentParsedItem, item.state1, diagramStates, diagramDb, altFlag); + setupNode(g, parentParsedItem, item.state2, diagramStates, diagramDb, altFlag); + const edgeData = { + id: "edge" + graphItemCount, + arrowhead: "normal", + arrowTypeEnd: "arrow_barb", + style: G_EDGE_STYLE, + labelStyle: "", + label: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.e.sanitizeText(item.description, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.c)()), + arrowheadStyle: G_EDGE_ARROWHEADSTYLE, + labelpos: G_EDGE_LABELPOS, + labelType: G_EDGE_LABELTYPE, + thickness: G_EDGE_THICKNESS, + classes: CSS_EDGE + }; + g.setEdge(item.state1.id, item.state2.id, edgeData, graphItemCount); + graphItemCount++; + } + break; + } + }); +}; +const getDir = (parsedItem, defaultDir = _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.c) => { + let dir = defaultDir; + if (parsedItem.doc) { + for (let i = 0; i < parsedItem.doc.length; i++) { + const parsedItemDoc = parsedItem.doc[i]; + if (parsedItemDoc.stmt === "dir") { + dir = parsedItemDoc.value; + } + } + } + return dir; +}; +const draw = async function(text, id, _version, diag) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.l.info("Drawing state diagram (v2)", id); + nodeDb = {}; + diag.db.getDirection(); + const { securityLevel, state: conf } = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.c)(); + const nodeSpacing = conf.nodeSpacing || 50; + const rankSpacing = conf.rankSpacing || 50; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.l.info(diag.db.getRootDocV2()); + diag.db.extract(diag.db.getRootDocV2()); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.l.info(diag.db.getRootDocV2()); + const diagramStates = diag.db.getStates(); + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_0__/* .Graph */ .k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: getDir(diag.db.getRootDocV2()), + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + setupNode(g, void 0, diag.db.getRootDocV2(), diagramStates, diag.db, true); + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_1__/* .select */ .Ys)("body"); + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + await (0,_index_2c4b9a3b_js__WEBPACK_IMPORTED_MODULE_9__.r)(element, g, ["barb"], CSS_DIAGRAM, id); + const padding = 8; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.u.insertTitle(svg, "statediagramTitleText", conf.titleTopMargin, diag.db.getDiagramTitle()); + const bounds = svg.node().getBBox(); + const width = bounds.width + padding * 2; + const height = bounds.height + padding * 2; + svg.attr("class", CSS_DIAGRAM); + const svgBounds = svg.node().getBBox(); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.i)(svg, height, width, conf.useMaxWidth); + const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_8__.l.debug(`viewBox ${vBox}`); + svg.attr("viewBox", vBox); + const labels = document.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = document.createElementNS("http://www.w3.org/2000/svg", SHAPE_STATE); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } +}; +const renderer = { + setConf, + getClasses, + draw +}; +const diagram = { + parser: _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.p, + db: _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d, + renderer, + styles: _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.s, + init: (cnf) => { + if (!cnf.state) { + cnf.state = {}; + } + cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d.clear(); + } +}; + + + +/***/ }), + +/***/ 52244: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ D: () => (/* binding */ DEFAULT_STATE_TYPE), +/* harmony export */ S: () => (/* binding */ STMT_RELATION), +/* harmony export */ a: () => (/* binding */ DIVIDER_TYPE), +/* harmony export */ b: () => (/* binding */ STMT_STATE), +/* harmony export */ c: () => (/* binding */ DEFAULT_NESTED_DOC_DIR), +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ p: () => (/* binding */ parser$1), +/* harmony export */ s: () => (/* binding */ styles) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(56363); + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 2], $V1 = [1, 3], $V2 = [1, 4], $V3 = [2, 4], $V4 = [1, 9], $V5 = [1, 11], $V6 = [1, 15], $V7 = [1, 16], $V8 = [1, 17], $V9 = [1, 18], $Va = [1, 30], $Vb = [1, 19], $Vc = [1, 20], $Vd = [1, 21], $Ve = [1, 22], $Vf = [1, 23], $Vg = [1, 25], $Vh = [1, 26], $Vi = [1, 27], $Vj = [1, 28], $Vk = [1, 29], $Vl = [1, 32], $Vm = [1, 33], $Vn = [1, 34], $Vo = [1, 35], $Vp = [1, 31], $Vq = [1, 4, 5, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $Vr = [1, 4, 5, 13, 14, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $Vs = [4, 5, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "SPACE": 4, "NL": 5, "SD": 6, "document": 7, "line": 8, "statement": 9, "classDefStatement": 10, "cssClassStatement": 11, "idStatement": 12, "DESCR": 13, "-->": 14, "HIDE_EMPTY": 15, "scale": 16, "WIDTH": 17, "COMPOSIT_STATE": 18, "STRUCT_START": 19, "STRUCT_STOP": 20, "STATE_DESCR": 21, "AS": 22, "ID": 23, "FORK": 24, "JOIN": 25, "CHOICE": 26, "CONCURRENT": 27, "note": 28, "notePosition": 29, "NOTE_TEXT": 30, "direction": 31, "acc_title": 32, "acc_title_value": 33, "acc_descr": 34, "acc_descr_value": 35, "acc_descr_multiline_value": 36, "classDef": 37, "CLASSDEF_ID": 38, "CLASSDEF_STYLEOPTS": 39, "DEFAULT": 40, "class": 41, "CLASSENTITY_IDS": 42, "STYLECLASS": 43, "direction_tb": 44, "direction_bt": 45, "direction_rl": 46, "direction_lr": 47, "eol": 48, ";": 49, "EDGE_STATE": 50, "STYLE_SEPARATOR": 51, "left_of": 52, "right_of": 53, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SPACE", 5: "NL", 6: "SD", 13: "DESCR", 14: "-->", 15: "HIDE_EMPTY", 16: "scale", 17: "WIDTH", 18: "COMPOSIT_STATE", 19: "STRUCT_START", 20: "STRUCT_STOP", 21: "STATE_DESCR", 22: "AS", 23: "ID", 24: "FORK", 25: "JOIN", 26: "CHOICE", 27: "CONCURRENT", 28: "note", 30: "NOTE_TEXT", 32: "acc_title", 33: "acc_title_value", 34: "acc_descr", 35: "acc_descr_value", 36: "acc_descr_multiline_value", 37: "classDef", 38: "CLASSDEF_ID", 39: "CLASSDEF_STYLEOPTS", 40: "DEFAULT", 41: "class", 42: "CLASSENTITY_IDS", 43: "STYLECLASS", 44: "direction_tb", 45: "direction_bt", 46: "direction_rl", 47: "direction_lr", 49: ";", 50: "EDGE_STATE", 51: "STYLE_SEPARATOR", 52: "left_of", 53: "right_of" }, + productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [8, 1], [8, 1], [9, 1], [9, 1], [9, 1], [9, 2], [9, 3], [9, 4], [9, 1], [9, 2], [9, 1], [9, 4], [9, 3], [9, 6], [9, 1], [9, 1], [9, 1], [9, 1], [9, 4], [9, 4], [9, 1], [9, 2], [9, 2], [9, 1], [10, 3], [10, 3], [11, 3], [31, 1], [31, 1], [31, 1], [31, 1], [48, 1], [48, 1], [12, 1], [12, 1], [12, 3], [12, 3], [29, 1], [29, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.setRootDoc($$[$0]); + return $$[$0]; + case 4: + this.$ = []; + break; + case 5: + if ($$[$0] != "nl") { + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + } + break; + case 6: + case 7: + this.$ = $$[$0]; + break; + case 8: + this.$ = "nl"; + break; + case 11: + this.$ = $$[$0]; + break; + case 12: + const stateStmt = $$[$0 - 1]; + stateStmt.description = yy.trimColon($$[$0]); + this.$ = stateStmt; + break; + case 13: + this.$ = { stmt: "relation", state1: $$[$0 - 2], state2: $$[$0] }; + break; + case 14: + const relDescription = yy.trimColon($$[$0]); + this.$ = { stmt: "relation", state1: $$[$0 - 3], state2: $$[$0 - 1], description: relDescription }; + break; + case 18: + this.$ = { stmt: "state", id: $$[$0 - 3], type: "default", description: "", doc: $$[$0 - 1] }; + break; + case 19: + var id = $$[$0]; + var description = $$[$0 - 2].trim(); + if ($$[$0].match(":")) { + var parts = $$[$0].split(":"); + id = parts[0]; + description = [description, parts[1]]; + } + this.$ = { stmt: "state", id, type: "default", description }; + break; + case 20: + this.$ = { stmt: "state", id: $$[$0 - 3], type: "default", description: $$[$0 - 5], doc: $$[$0 - 1] }; + break; + case 21: + this.$ = { stmt: "state", id: $$[$0], type: "fork" }; + break; + case 22: + this.$ = { stmt: "state", id: $$[$0], type: "join" }; + break; + case 23: + this.$ = { stmt: "state", id: $$[$0], type: "choice" }; + break; + case 24: + this.$ = { stmt: "state", id: yy.getDividerId(), type: "divider" }; + break; + case 25: + this.$ = { stmt: "state", id: $$[$0 - 1].trim(), note: { position: $$[$0 - 2].trim(), text: $$[$0].trim() } }; + break; + case 28: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 29: + case 30: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 31: + case 32: + this.$ = { stmt: "classDef", id: $$[$0 - 1].trim(), classes: $$[$0].trim() }; + break; + case 33: + this.$ = { stmt: "applyClass", id: $$[$0 - 1].trim(), styleClass: $$[$0].trim() }; + break; + case 34: + yy.setDirection("TB"); + this.$ = { stmt: "dir", value: "TB" }; + break; + case 35: + yy.setDirection("BT"); + this.$ = { stmt: "dir", value: "BT" }; + break; + case 36: + yy.setDirection("RL"); + this.$ = { stmt: "dir", value: "RL" }; + break; + case 37: + yy.setDirection("LR"); + this.$ = { stmt: "dir", value: "LR" }; + break; + case 40: + case 41: + this.$ = { stmt: "state", id: $$[$0].trim(), type: "default", description: "" }; + break; + case 42: + this.$ = { stmt: "state", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: "default", description: "" }; + break; + case 43: + this.$ = { stmt: "state", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: "default", description: "" }; + break; + } + }, + table: [{ 3: 1, 4: $V0, 5: $V1, 6: $V2 }, { 1: [3] }, { 3: 5, 4: $V0, 5: $V1, 6: $V2 }, { 3: 6, 4: $V0, 5: $V1, 6: $V2 }, o([1, 4, 5, 15, 16, 18, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $V3, { 7: 7 }), { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3], 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 5]), { 9: 36, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 7]), o($Vq, [2, 8]), o($Vq, [2, 9]), o($Vq, [2, 10]), o($Vq, [2, 11], { 13: [1, 37], 14: [1, 38] }), o($Vq, [2, 15]), { 17: [1, 39] }, o($Vq, [2, 17], { 19: [1, 40] }), { 22: [1, 41] }, o($Vq, [2, 21]), o($Vq, [2, 22]), o($Vq, [2, 23]), o($Vq, [2, 24]), { 29: 42, 30: [1, 43], 52: [1, 44], 53: [1, 45] }, o($Vq, [2, 27]), { 33: [1, 46] }, { 35: [1, 47] }, o($Vq, [2, 30]), { 38: [1, 48], 40: [1, 49] }, { 42: [1, 50] }, o($Vr, [2, 40], { 51: [1, 51] }), o($Vr, [2, 41], { 51: [1, 52] }), o($Vq, [2, 34]), o($Vq, [2, 35]), o($Vq, [2, 36]), o($Vq, [2, 37]), o($Vq, [2, 6]), o($Vq, [2, 12]), { 12: 53, 23: $Va, 50: $Vp }, o($Vq, [2, 16]), o($Vs, $V3, { 7: 54 }), { 23: [1, 55] }, { 23: [1, 56] }, { 22: [1, 57] }, { 23: [2, 44] }, { 23: [2, 45] }, o($Vq, [2, 28]), o($Vq, [2, 29]), { 39: [1, 58] }, { 39: [1, 59] }, { 43: [1, 60] }, { 23: [1, 61] }, { 23: [1, 62] }, o($Vq, [2, 13], { 13: [1, 63] }), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 20: [1, 64], 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 19], { 19: [1, 65] }), { 30: [1, 66] }, { 23: [1, 67] }, o($Vq, [2, 31]), o($Vq, [2, 32]), o($Vq, [2, 33]), o($Vr, [2, 42]), o($Vr, [2, 43]), o($Vq, [2, 14]), o($Vq, [2, 18]), o($Vs, $V3, { 7: 68 }), o($Vq, [2, 25]), o($Vq, [2, 26]), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 20: [1, 69], 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 20])], + defaultActions: { 5: [2, 1], 6: [2, 2], 44: [2, 44], 45: [2, 45] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 40; + case 1: + return 44; + case 2: + return 45; + case 3: + return 46; + case 4: + return 47; + case 5: + break; + case 6: + break; + case 7: + return 5; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + this.pushState("SCALE"); + return 16; + case 13: + return 17; + case 14: + this.popState(); + break; + case 15: + this.begin("acc_title"); + return 32; + case 16: + this.popState(); + return "acc_title_value"; + case 17: + this.begin("acc_descr"); + return 34; + case 18: + this.popState(); + return "acc_descr_value"; + case 19: + this.begin("acc_descr_multiline"); + break; + case 20: + this.popState(); + break; + case 21: + return "acc_descr_multiline_value"; + case 22: + this.pushState("CLASSDEF"); + return 37; + case 23: + this.popState(); + this.pushState("CLASSDEFID"); + return "DEFAULT_CLASSDEF_ID"; + case 24: + this.popState(); + this.pushState("CLASSDEFID"); + return 38; + case 25: + this.popState(); + return 39; + case 26: + this.pushState("CLASS"); + return 41; + case 27: + this.popState(); + this.pushState("CLASS_STYLE"); + return 42; + case 28: + this.popState(); + return 43; + case 29: + this.pushState("SCALE"); + return 16; + case 30: + return 17; + case 31: + this.popState(); + break; + case 32: + this.pushState("STATE"); + break; + case 33: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 24; + case 34: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 25; + case 35: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -10).trim(); + return 26; + case 36: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 24; + case 37: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 25; + case 38: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -10).trim(); + return 26; + case 39: + return 44; + case 40: + return 45; + case 41: + return 46; + case 42: + return 47; + case 43: + this.pushState("STATE_STRING"); + break; + case 44: + this.pushState("STATE_ID"); + return "AS"; + case 45: + this.popState(); + return "ID"; + case 46: + this.popState(); + break; + case 47: + return "STATE_DESCR"; + case 48: + return 18; + case 49: + this.popState(); + break; + case 50: + this.popState(); + this.pushState("struct"); + return 19; + case 51: + break; + case 52: + this.popState(); + return 20; + case 53: + break; + case 54: + this.begin("NOTE"); + return 28; + case 55: + this.popState(); + this.pushState("NOTE_ID"); + return 52; + case 56: + this.popState(); + this.pushState("NOTE_ID"); + return 53; + case 57: + this.popState(); + this.pushState("FLOATING_NOTE"); + break; + case 58: + this.popState(); + this.pushState("FLOATING_NOTE_ID"); + return "AS"; + case 59: + break; + case 60: + return "NOTE_TEXT"; + case 61: + this.popState(); + return "ID"; + case 62: + this.popState(); + this.pushState("NOTE_TEXT"); + return 23; + case 63: + this.popState(); + yy_.yytext = yy_.yytext.substr(2).trim(); + return 30; + case 64: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 30; + case 65: + return 6; + case 66: + return 6; + case 67: + return 15; + case 68: + return 50; + case 69: + return 23; + case 70: + yy_.yytext = yy_.yytext.trim(); + return 13; + case 71: + return 14; + case 72: + return 27; + case 73: + return 51; + case 74: + return 5; + case 75: + return "INVALID"; + } + }, + rules: [/^(?:default\b)/i, /^(?:.*direction\s+TB[^\n]*)/i, /^(?:.*direction\s+BT[^\n]*)/i, /^(?:.*direction\s+RL[^\n]*)/i, /^(?:.*direction\s+LR[^\n]*)/i, /^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n]+)/i, /^(?:[\s]+)/i, /^(?:((?!\n)\s)+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:scale\s+)/i, /^(?:\d+)/i, /^(?:\s+width\b)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:classDef\s+)/i, /^(?:DEFAULT\s+)/i, /^(?:\w+\s+)/i, /^(?:[^\n]*)/i, /^(?:class\s+)/i, /^(?:(\w+)+((,\s*\w+)*))/i, /^(?:[^\n]*)/i, /^(?:scale\s+)/i, /^(?:\d+)/i, /^(?:\s+width\b)/i, /^(?:state\s+)/i, /^(?:.*<>)/i, /^(?:.*<>)/i, /^(?:.*<>)/i, /^(?:.*\[\[fork\]\])/i, /^(?:.*\[\[join\]\])/i, /^(?:.*\[\[choice\]\])/i, /^(?:.*direction\s+TB[^\n]*)/i, /^(?:.*direction\s+BT[^\n]*)/i, /^(?:.*direction\s+RL[^\n]*)/i, /^(?:.*direction\s+LR[^\n]*)/i, /^(?:["])/i, /^(?:\s*as\s+)/i, /^(?:[^\n\{]*)/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[^\n\s\{]+)/i, /^(?:\n)/i, /^(?:\{)/i, /^(?:%%(?!\{)[^\n]*)/i, /^(?:\})/i, /^(?:[\n])/i, /^(?:note\s+)/i, /^(?:left of\b)/i, /^(?:right of\b)/i, /^(?:")/i, /^(?:\s*as\s*)/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[^\n]*)/i, /^(?:\s*[^:\n\s\-]+)/i, /^(?:\s*:[^:\n;]+)/i, /^(?:[\s\S]*?end note\b)/i, /^(?:stateDiagram\s+)/i, /^(?:stateDiagram-v2\s+)/i, /^(?:hide empty description\b)/i, /^(?:\[\*\])/i, /^(?:[^:\n\s\-\{]+)/i, /^(?:\s*:[^:\n;]+)/i, /^(?:-->)/i, /^(?:--)/i, /^(?::::)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "LINE": { "rules": [9, 10], "inclusive": false }, "struct": { "rules": [9, 10, 22, 26, 32, 39, 40, 41, 42, 51, 52, 53, 54, 68, 69, 70, 71, 72], "inclusive": false }, "FLOATING_NOTE_ID": { "rules": [61], "inclusive": false }, "FLOATING_NOTE": { "rules": [58, 59, 60], "inclusive": false }, "NOTE_TEXT": { "rules": [63, 64], "inclusive": false }, "NOTE_ID": { "rules": [62], "inclusive": false }, "NOTE": { "rules": [55, 56, 57], "inclusive": false }, "CLASS_STYLE": { "rules": [28], "inclusive": false }, "CLASS": { "rules": [27], "inclusive": false }, "CLASSDEFID": { "rules": [25], "inclusive": false }, "CLASSDEF": { "rules": [23, 24], "inclusive": false }, "acc_descr_multiline": { "rules": [20, 21], "inclusive": false }, "acc_descr": { "rules": [18], "inclusive": false }, "acc_title": { "rules": [16], "inclusive": false }, "SCALE": { "rules": [13, 14, 30, 31], "inclusive": false }, "ALIAS": { "rules": [], "inclusive": false }, "STATE_ID": { "rules": [45], "inclusive": false }, "STATE_STRING": { "rules": [46, 47], "inclusive": false }, "FORK_STATE": { "rules": [], "inclusive": false }, "STATE": { "rules": [9, 10, 33, 34, 35, 36, 37, 38, 43, 44, 48, 49, 50], "inclusive": false }, "ID": { "rules": [9, 10], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 17, 19, 22, 26, 29, 32, 50, 54, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const DEFAULT_DIAGRAM_DIRECTION = "LR"; +const DEFAULT_NESTED_DOC_DIR = "TB"; +const STMT_STATE = "state"; +const STMT_RELATION = "relation"; +const STMT_CLASSDEF = "classDef"; +const STMT_APPLYCLASS = "applyClass"; +const DEFAULT_STATE_TYPE = "default"; +const DIVIDER_TYPE = "divider"; +const START_NODE = "[*]"; +const START_TYPE = "start"; +const END_NODE = START_NODE; +const END_TYPE = "end"; +const COLOR_KEYWORD = "color"; +const FILL_KEYWORD = "fill"; +const BG_FILL = "bgFill"; +const STYLECLASS_SEP = ","; +function newClassesList() { + return {}; +} +let direction = DEFAULT_DIAGRAM_DIRECTION; +let rootDoc = []; +let classes = newClassesList(); +const newDoc = () => { + return { + relations: [], + states: {}, + documents: {} + }; +}; +let documents = { + root: newDoc() +}; +let currentDocument = documents.root; +let startEndCount = 0; +let dividerCnt = 0; +const lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; +const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3 +}; +const clone = (o) => JSON.parse(JSON.stringify(o)); +const setRootDoc = (o) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting root doc", o); + rootDoc = o; +}; +const getRootDoc = () => rootDoc; +const docTranslator = (parent, node, first) => { + if (node.stmt === STMT_RELATION) { + docTranslator(parent, node.state1, true); + docTranslator(parent, node.state2, false); + } else { + if (node.stmt === STMT_STATE) { + if (node.id === "[*]") { + node.id = first ? parent.id + "_start" : parent.id + "_end"; + node.start = first; + } else { + node.id = node.id.trim(); + } + } + if (node.doc) { + const doc = []; + let currentDoc = []; + let i; + for (i = 0; i < node.doc.length; i++) { + if (node.doc[i].type === DIVIDER_TYPE) { + const newNode = clone(node.doc[i]); + newNode.doc = clone(currentDoc); + doc.push(newNode); + currentDoc = []; + } else { + currentDoc.push(node.doc[i]); + } + } + if (doc.length > 0 && currentDoc.length > 0) { + const newNode = { + stmt: STMT_STATE, + id: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.G)(), + type: "divider", + doc: clone(currentDoc) + }; + doc.push(clone(newNode)); + node.doc = doc; + } + node.doc.forEach((docNode) => docTranslator(node, docNode, true)); + } + } +}; +const getRootDocV2 = () => { + docTranslator({ id: "root" }, { id: "root", doc: rootDoc }, true); + return { id: "root", doc: rootDoc }; +}; +const extract = (_doc) => { + let doc; + if (_doc.doc) { + doc = _doc.doc; + } else { + doc = _doc; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info(doc); + clear(true); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Extract", doc); + doc.forEach((item) => { + switch (item.stmt) { + case STMT_STATE: + addState( + item.id.trim(), + item.type, + item.doc, + item.description, + item.note, + item.classes, + item.styles, + item.textStyles + ); + break; + case STMT_RELATION: + addRelation(item.state1, item.state2, item.description); + break; + case STMT_CLASSDEF: + addStyleClass(item.id.trim(), item.classes); + break; + case STMT_APPLYCLASS: + setCssClass(item.id.trim(), item.styleClass); + break; + } + }); +}; +const addState = function(id, type = DEFAULT_STATE_TYPE, doc = null, descr = null, note = null, classes2 = null, styles2 = null, textStyles = null) { + const trimmedId = id == null ? void 0 : id.trim(); + if (currentDocument.states[trimmedId] === void 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Adding state ", trimmedId, descr); + currentDocument.states[trimmedId] = { + id: trimmedId, + descriptions: [], + type, + doc, + note, + classes: [], + styles: [], + textStyles: [] + }; + } else { + if (!currentDocument.states[trimmedId].doc) { + currentDocument.states[trimmedId].doc = doc; + } + if (!currentDocument.states[trimmedId].type) { + currentDocument.states[trimmedId].type = type; + } + } + if (descr) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state description", trimmedId, descr); + if (typeof descr === "string") { + addDescription(trimmedId, descr.trim()); + } + if (typeof descr === "object") { + descr.forEach((des) => addDescription(trimmedId, des.trim())); + } + } + if (note) { + currentDocument.states[trimmedId].note = note; + currentDocument.states[trimmedId].note.text = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText( + currentDocument.states[trimmedId].note.text, + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)() + ); + } + if (classes2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state classes", trimmedId, classes2); + const classesList = typeof classes2 === "string" ? [classes2] : classes2; + classesList.forEach((klass) => setCssClass(trimmedId, klass.trim())); + } + if (styles2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state styles", trimmedId, styles2); + const stylesList = typeof styles2 === "string" ? [styles2] : styles2; + stylesList.forEach((style) => setStyle(trimmedId, style.trim())); + } + if (textStyles) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state styles", trimmedId, styles2); + const textStylesList = typeof textStyles === "string" ? [textStyles] : textStyles; + textStylesList.forEach((textStyle) => setTextStyle(trimmedId, textStyle.trim())); + } +}; +const clear = function(saveCommon) { + documents = { + root: newDoc() + }; + currentDocument = documents.root; + startEndCount = 0; + classes = newClassesList(); + if (!saveCommon) { + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.t)(); + } +}; +const getState = function(id) { + return currentDocument.states[id]; +}; +const getStates = function() { + return currentDocument.states; +}; +const logDocuments = function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Documents = ", documents); +}; +const getRelations = function() { + return currentDocument.relations; +}; +function startIdIfNeeded(id = "") { + let fixedId = id; + if (id === START_NODE) { + startEndCount++; + fixedId = `${START_TYPE}${startEndCount}`; + } + return fixedId; +} +function startTypeIfNeeded(id = "", type = DEFAULT_STATE_TYPE) { + return id === START_NODE ? START_TYPE : type; +} +function endIdIfNeeded(id = "") { + let fixedId = id; + if (id === END_NODE) { + startEndCount++; + fixedId = `${END_TYPE}${startEndCount}`; + } + return fixedId; +} +function endTypeIfNeeded(id = "", type = DEFAULT_STATE_TYPE) { + return id === END_NODE ? END_TYPE : type; +} +function addRelationObjs(item1, item2, relationTitle) { + let id1 = startIdIfNeeded(item1.id.trim()); + let type1 = startTypeIfNeeded(item1.id.trim(), item1.type); + let id2 = startIdIfNeeded(item2.id.trim()); + let type2 = startTypeIfNeeded(item2.id.trim(), item2.type); + addState( + id1, + type1, + item1.doc, + item1.description, + item1.note, + item1.classes, + item1.styles, + item1.textStyles + ); + addState( + id2, + type2, + item2.doc, + item2.description, + item2.note, + item2.classes, + item2.styles, + item2.textStyles + ); + currentDocument.relations.push({ + id1, + id2, + relationTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(relationTitle, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)()) + }); +} +const addRelation = function(item1, item2, title) { + if (typeof item1 === "object") { + addRelationObjs(item1, item2, title); + } else { + const id1 = startIdIfNeeded(item1.trim()); + const type1 = startTypeIfNeeded(item1); + const id2 = endIdIfNeeded(item2.trim()); + const type2 = endTypeIfNeeded(item2); + addState(id1, type1); + addState(id2, type2); + currentDocument.relations.push({ + id1, + id2, + title: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(title, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)()) + }); + } +}; +const addDescription = function(id, descr) { + const theState = currentDocument.states[id]; + const _descr = descr.startsWith(":") ? descr.replace(":", "").trim() : descr; + theState.descriptions.push(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(_descr, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)())); +}; +const cleanupLabel = function(label) { + if (label.substring(0, 1) === ":") { + return label.substr(2).trim(); + } else { + return label.trim(); + } +}; +const getDividerId = () => { + dividerCnt++; + return "divider-id-" + dividerCnt; +}; +const addStyleClass = function(id, styleAttributes = "") { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + const foundClass = classes[id]; + if (styleAttributes !== void 0 && styleAttributes !== null) { + styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => { + const fixedAttrib = attrib.replace(/([^;]*);/, "$1").trim(); + if (attrib.match(COLOR_KEYWORD)) { + const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL); + const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD); + foundClass.textStyles.push(newStyle2); + } + foundClass.styles.push(fixedAttrib); + }); + } +}; +const getClasses = function() { + return classes; +}; +const setCssClass = function(itemIds, cssClassName) { + itemIds.split(",").forEach(function(id) { + let foundState = getState(id); + if (foundState === void 0) { + const trimmedId = id.trim(); + addState(trimmedId); + foundState = getState(trimmedId); + } + foundState.classes.push(cssClassName); + }); +}; +const setStyle = function(itemId, styleText) { + const item = getState(itemId); + if (item !== void 0) { + item.textStyles.push(styleText); + } +}; +const setTextStyle = function(itemId, cssClassName) { + const item = getState(itemId); + if (item !== void 0) { + item.textStyles.push(cssClassName); + } +}; +const getDirection = () => direction; +const setDirection = (dir) => { + direction = dir; +}; +const trimColon = (str) => str && str[0] === ":" ? str.substr(1).trim() : str.trim(); +const db = { + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)().state, + addState, + clear, + getState, + getStates, + getRelations, + getClasses, + getDirection, + addRelation, + getDividerId, + setDirection, + cleanupLabel, + lineType, + relationType, + logDocuments, + getRootDoc, + setRootDoc, + getRootDocV2, + extract, + trimColon, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.g, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.s, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.b, + addStyleClass, + setCssClass, + addDescription, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.r +}; +const getStyles = (options) => ` +defs #statediagram-barbEnd { + fill: ${options.transitionColor}; + stroke: ${options.transitionColor}; + } +g.stateGroup text { + fill: ${options.nodeBorder}; + stroke: none; + font-size: 10px; +} +g.stateGroup text { + fill: ${options.textColor}; + stroke: none; + font-size: 10px; + +} +g.stateGroup .state-title { + font-weight: bolder; + fill: ${options.stateLabelColor}; +} + +g.stateGroup rect { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; +} + +g.stateGroup line { + stroke: ${options.lineColor}; + stroke-width: 1; +} + +.transition { + stroke: ${options.transitionColor}; + stroke-width: 1; + fill: none; +} + +.stateGroup .composit { + fill: ${options.background}; + border-bottom: 1px +} + +.stateGroup .alt-composit { + fill: #e0e0e0; + border-bottom: 1px +} + +.state-note { + stroke: ${options.noteBorderColor}; + fill: ${options.noteBkgColor}; + + text { + fill: ${options.noteTextColor}; + stroke: none; + font-size: 10px; + } +} + +.stateLabel .box { + stroke: none; + stroke-width: 0; + fill: ${options.mainBkg}; + opacity: 0.5; +} + +.edgeLabel .label rect { + fill: ${options.labelBackgroundColor}; + opacity: 0.5; +} +.edgeLabel .label text { + fill: ${options.transitionLabelColor || options.tertiaryTextColor}; +} +.label div .edgeLabel { + color: ${options.transitionLabelColor || options.tertiaryTextColor}; +} + +.stateLabel text { + fill: ${options.stateLabelColor}; + font-size: 10px; + font-weight: bold; +} + +.node circle.state-start { + fill: ${options.specialStateColor}; + stroke: ${options.specialStateColor}; +} + +.node .fork-join { + fill: ${options.specialStateColor}; + stroke: ${options.specialStateColor}; +} + +.node circle.state-end { + fill: ${options.innerEndBackground}; + stroke: ${options.background}; + stroke-width: 1.5 +} +.end-state-inner { + fill: ${options.compositeBackground || options.background}; + // stroke: ${options.background}; + stroke-width: 1.5 +} + +.node rect { + fill: ${options.stateBkg || options.mainBkg}; + stroke: ${options.stateBorder || options.nodeBorder}; + stroke-width: 1px; +} +.node polygon { + fill: ${options.mainBkg}; + stroke: ${options.stateBorder || options.nodeBorder};; + stroke-width: 1px; +} +#statediagram-barbEnd { + fill: ${options.lineColor}; +} + +.statediagram-cluster rect { + fill: ${options.compositeTitleBackground}; + stroke: ${options.stateBorder || options.nodeBorder}; + stroke-width: 1px; +} + +.cluster-label, .nodeLabel { + color: ${options.stateLabelColor}; +} + +.statediagram-cluster rect.outer { + rx: 5px; + ry: 5px; +} +.statediagram-state .divider { + stroke: ${options.stateBorder || options.nodeBorder}; +} + +.statediagram-state .title-state { + rx: 5px; + ry: 5px; +} +.statediagram-cluster.statediagram-cluster .inner { + fill: ${options.compositeBackground || options.background}; +} +.statediagram-cluster.statediagram-cluster-alt .inner { + fill: ${options.altBackground ? options.altBackground : "#efefef"}; +} + +.statediagram-cluster .inner { + rx:0; + ry:0; +} + +.statediagram-state rect.basic { + rx: 5px; + ry: 5px; +} +.statediagram-state rect.divider { + stroke-dasharray: 10,10; + fill: ${options.altBackground ? options.altBackground : "#efefef"}; +} + +.note-edge { + stroke-dasharray: 5; +} + +.statediagram-note rect { + fill: ${options.noteBkgColor}; + stroke: ${options.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} +.statediagram-note rect { + fill: ${options.noteBkgColor}; + stroke: ${options.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} + +.statediagram-note text { + fill: ${options.noteTextColor}; +} + +.statediagram-note .nodeLabel { + color: ${options.noteTextColor}; +} +.statediagram .edgeLabel { + color: red; // ${options.noteTextColor}; +} + +#dependencyStart, #dependencyEnd { + fill: ${options.lineColor}; + stroke: ${options.lineColor}; + stroke-width: 1; +} + +.statediagramTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} +`; +const styles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/28a1570f.0cae8263.js b/assets/js/28a1570f.97a380e8.js similarity index 52% rename from assets/js/28a1570f.0cae8263.js rename to assets/js/28a1570f.97a380e8.js index 3c3ee22e1..890b92a2b 100644 --- a/assets/js/28a1570f.0cae8263.js +++ b/assets/js/28a1570f.97a380e8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[448],{92252:a=>{a.exports=JSON.parse('{"label":"Elastic Beanstalk","permalink":"/tags/elastic-beanstalk","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[448],{92252:e=>{e.exports=JSON.parse('{"label":"Elastic Beanstalk","permalink":"/tags/elastic-beanstalk","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/290b0a56.35146abd.js b/assets/js/290b0a56.35146abd.js deleted file mode 100644 index 6932477b6..000000000 --- a/assets/js/290b0a56.35146abd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4212],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),s=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},d=function(e){var t=s(e.components);return r.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),p=s(n),m=a,v=p["".concat(i,".").concat(m)]||p[m]||u[m]||l;return n?r.createElement(v,c(c({ref:t},d),{},{components:n})):r.createElement(v,c({ref:t},d))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,c=new Array(l);c[0]=p;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o.mdxType="string"==typeof e?e:a,c[1]=o;for(var s=2;s{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var r=n(87462),a=(n(67294),n(3905));const l={title:"SequencedCollection",slug:"/java/sequenced-collection",last_update:{date:"2023/10/02"},tags:["java","collection","sequenced"]},c=void 0,o={unversionedId:"Java/SequencedCollection",id:"Java/SequencedCollection",title:"SequencedCollection",description:"JEP 431: Sequenced Collections",source:"@site/docs/Java/SequencedCollection.mdx",sourceDirName:"Java",slug:"/java/sequenced-collection",permalink:"/docs/java/sequenced-collection",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/Java/SequencedCollection.mdx",tags:[{label:"java",permalink:"/docs/tags/java"},{label:"collection",permalink:"/docs/tags/collection"},{label:"sequenced",permalink:"/docs/tags/sequenced"}],version:"current",lastUpdatedAt:1696204800,formattedLastUpdatedAt:"2023\ub144 10\uc6d4 2\uc77c",frontMatter:{title:"SequencedCollection",slug:"/java/sequenced-collection",last_update:{date:"2023/10/02"},tags:["java","collection","sequenced"]},sidebar:"tutorialSidebar",previous:{title:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",permalink:"/docs/jpa/key"},next:{title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",permalink:"/docs/mac/java"}},i={},s=[{value:"JEP 431: Sequenced Collections",id:"jep-431-sequenced-collections",level:3},{value:"SequencedCollection",id:"sequencedcollection",level:3},{value:"SequencedSet",id:"sequencedset",level:3},{value:"SequencedMaps",id:"sequencedmaps",level:3},{value:"\ucc38\uace0 \uc790\ub8cc \ubc0f \uc774\ubbf8\uc9c0 \ucd9c\ucc98",id:"\ucc38\uace0-\uc790\ub8cc-\ubc0f-\uc774\ubbf8\uc9c0-\ucd9c\ucc98",level:3}],d={toc:s};function u(e){let{components:t,...l}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,l,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"jep-431-sequenced-collections"},"JEP 431: Sequenced Collections"),(0,a.kt)("p",null,"\uccab \ubc88\uc9f8, \ub9c8\uc9c0\ub9c9 \uc6d0\uc18c\ub97c \uc811\uadfc\ud560 \ub54c \ubc88\uac70\ub85c\uc6b4 \ubd80\ubd84\uc774 \ud574\uacb0\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc758 \uc790\ubc14\uc758 \ub9ac\uc2a4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ",(0,a.kt)("inlineCode",{parentName:"p"},"list.get(0)"),"\uc774\ub098 ",(0,a.kt)("inlineCode",{parentName:"p"},"list.get(list.size() - 1)"),"\ub97c \uc0ac\uc6a9\ud588\uc5b4\uc57c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\ubc14 21\uc5d0\uc11c \ucd94\uac00\ub41c Sequenced Collections\uc744 \uc774\uc6a9\ud558\uba74 \uac04\ud3b8\ud558\uac8c \ud574\ub2f9 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./SequencedCollectionDiagram.png",src:n(86526).Z,width:"1512",height:"840"})),(0,a.kt)("h3",{id:"sequencedcollection"},"SequencedCollection"),(0,a.kt)("p",null,"\uae30\uc874\uc758 Deque\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83 \ucc98\ub7fc \ud3b8 \ud558\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","reversed\uc758 \uacbd\uc6b0 \uc21c\uc11c\ub9cc \ubc18\ub300\ub85c \uc81c\uacf5\ud558\ub294 \uceec\ub809\uc158\uc758 \ubdf0\ub97c \ubc18\ud658\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=SequencedCollection",title:"SequencedCollection"},"interface SequencedCollection extends Collection {\n SequencedCollection reversed();\n void addFirst(E);\n void addLast(E);\n E getFirst();\n E getLast();\n E removeFirst();\n E removeLast();\n}\n")),(0,a.kt)("h3",{id:"sequencedset"},"SequencedSet"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=SequencedSet",title:"SequencedSet"},"interface SequencedSet extends Set, SequencedCollection {\n SequencedSet reversed(); // covariant override\n}\n")),(0,a.kt)("h3",{id:"sequencedmaps"},"SequencedMaps"),(0,a.kt)("p",null,"firstEntry, lastEntry\uc758 \uacbd\uc6b0 \ud0a4 \uac12\uc744 \uae30\uc900\uc73c\ub85c \uacb0\uc815\ub41c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=SequencedMap",title:"SequencedMap"},"interface SequencedMap extends Map {\n SequencedMap reversed();\n SequencedSet sequencedKeySet();\n SequencedCollection sequencedValues();\n SequencedSet> sequencedEntrySet();\n V putFirst(K, V);\n V putLast(K, V);\n Entry firstEntry();\n Entry lastEntry();\n Entry pollFirstEntry();\n Entry pollLastEntry();\n}\n")),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc-\ubc0f-\uc774\ubbf8\uc9c0-\ucd9c\ucc98"},"\ucc38\uace0 \uc790\ub8cc \ubc0f \uc774\ubbf8\uc9c0 \ucd9c\ucc98"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://openjdk.org/jeps/431"},"SequencedCollection, openjdk")))}u.isMDXComponent=!0},86526:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/SequencedCollectionDiagram-c3b39e89bd475c2f70b02b60c544de1f.png"}}]); \ No newline at end of file diff --git a/assets/js/290b0a56.a6af2777.js b/assets/js/290b0a56.a6af2777.js new file mode 100644 index 000000000..14f809b0d --- /dev/null +++ b/assets/js/290b0a56.a6af2777.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4212],{37260:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>i});var c=t(85893),r=t(3905);const l={title:"SequencedCollection",slug:"/java/sequenced-collection",last_update:{date:"2023/10/02"},tags:["java","collection","sequenced"]},a=void 0,o={id:"Java/SequencedCollection",title:"SequencedCollection",description:"JEP 431: Sequenced Collections",source:"@site/docs/Java/SequencedCollection.mdx",sourceDirName:"Java",slug:"/java/sequenced-collection",permalink:"/docs/java/sequenced-collection",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/Java/SequencedCollection.mdx",tags:[{label:"java",permalink:"/docs/tags/java"},{label:"collection",permalink:"/docs/tags/collection"},{label:"sequenced",permalink:"/docs/tags/sequenced"}],version:"current",lastUpdatedAt:1696204800,formattedLastUpdatedAt:"2023\ub144 10\uc6d4 2\uc77c",frontMatter:{title:"SequencedCollection",slug:"/java/sequenced-collection",last_update:{date:"2023/10/02"},tags:["java","collection","sequenced"]},sidebar:"tutorialSidebar",previous:{title:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",permalink:"/docs/jpa/key"},next:{title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",permalink:"/docs/mac/java"}},s={},i=[{value:"JEP 431: Sequenced Collections",id:"jep-431-sequenced-collections",level:3},{value:"SequencedCollection",id:"sequencedcollection",level:3},{value:"SequencedSet",id:"sequencedset",level:3},{value:"SequencedMaps",id:"sequencedmaps",level:3},{value:"\ucc38\uace0 \uc790\ub8cc \ubc0f \uc774\ubbf8\uc9c0 \ucd9c\ucc98",id:"\ucc38\uace0-\uc790\ub8cc-\ubc0f-\uc774\ubbf8\uc9c0-\ucd9c\ucc98",level:3}];function d(e){const n={a:"a",br:"br",code:"code",h3:"h3",img:"img",p:"p",pre:"pre",...(0,r.ah)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.h3,{id:"jep-431-sequenced-collections",children:"JEP 431: Sequenced Collections"}),"\n",(0,c.jsxs)(n.p,{children:["\uccab \ubc88\uc9f8, \ub9c8\uc9c0\ub9c9 \uc6d0\uc18c\ub97c \uc811\uadfc\ud560 \ub54c \ubc88\uac70\ub85c\uc6b4 \ubd80\ubd84\uc774 \ud574\uacb0\ub418\uc5c8\ub2e4.",(0,c.jsx)(n.br,{}),"\n","\uae30\uc874\uc758 \uc790\ubc14\uc758 \ub9ac\uc2a4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ",(0,c.jsx)(n.code,{children:"list.get(0)"}),"\uc774\ub098 ",(0,c.jsx)(n.code,{children:"list.get(list.size() - 1)"}),"\ub97c \uc0ac\uc6a9\ud588\uc5b4\uc57c \ud588\ub2e4.",(0,c.jsx)(n.br,{}),"\n","\uc790\ubc14 21\uc5d0\uc11c \ucd94\uac00\ub41c Sequenced Collections\uc744 \uc774\uc6a9\ud558\uba74 \uac04\ud3b8\ud558\uac8c \ud574\ub2f9 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"./SequencedCollectionDiagram.png",src:t(86526).Z+"",width:"1512",height:"840"})}),"\n",(0,c.jsx)(n.h3,{id:"sequencedcollection",children:"SequencedCollection"}),"\n",(0,c.jsxs)(n.p,{children:["\uae30\uc874\uc758 Deque\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83 \ucc98\ub7fc \ud3b8 \ud558\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,c.jsx)(n.br,{}),"\n","reversed\uc758 \uacbd\uc6b0 \uc21c\uc11c\ub9cc \ubc18\ub300\ub85c \uc81c\uacf5\ud558\ub294 \uceec\ub809\uc158\uc758 \ubdf0\ub97c \ubc18\ud658\ud55c\ub2e4."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-java",metastring:"title=SequencedCollection",children:"interface SequencedCollection extends Collection {\n SequencedCollection reversed();\n void addFirst(E);\n void addLast(E);\n E getFirst();\n E getLast();\n E removeFirst();\n E removeLast();\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"sequencedset",children:"SequencedSet"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-java",metastring:"title=SequencedSet",children:"interface SequencedSet extends Set, SequencedCollection {\n SequencedSet reversed(); // covariant override\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"sequencedmaps",children:"SequencedMaps"}),"\n",(0,c.jsx)(n.p,{children:"firstEntry, lastEntry\uc758 \uacbd\uc6b0 \ud0a4 \uac12\uc744 \uae30\uc900\uc73c\ub85c \uacb0\uc815\ub41c\ub2e4."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-java",metastring:"title=SequencedMap",children:"interface SequencedMap extends Map {\n SequencedMap reversed();\n SequencedSet sequencedKeySet();\n SequencedCollection sequencedValues();\n SequencedSet> sequencedEntrySet();\n V putFirst(K, V);\n V putLast(K, V);\n Entry firstEntry();\n Entry lastEntry();\n Entry pollFirstEntry();\n Entry pollLastEntry();\n}\n"})}),"\n",(0,c.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc-\ubc0f-\uc774\ubbf8\uc9c0-\ucd9c\ucc98",children:"\ucc38\uace0 \uc790\ub8cc \ubc0f \uc774\ubbf8\uc9c0 \ucd9c\ucc98"}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"https://openjdk.org/jeps/431",children:"SequencedCollection, openjdk"})})]})}function u(e={}){const{wrapper:n}={...(0,r.ah)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>i});var c=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);n&&(c=c.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,c)}return t}function a(e){for(var n=1;n=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(c=0;c=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var s=c.createContext({}),i=function(e){var n=c.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},d={inlineCode:"code",wrapper:function(e){var n=e.children;return c.createElement(c.Fragment,{},n)}},u=c.forwardRef((function(e,n){var t=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),p=i(t),j=r,m=p["".concat(s,".").concat(j)]||p[j]||d[j]||l;return t?c.createElement(m,a(a({ref:n},u),{},{components:t})):c.createElement(m,a({ref:n},u))}));u.displayName="MDXCreateElement"},86526:(e,n,t)=>{t.d(n,{Z:()=>c});const c=t.p+"assets/images/SequencedCollectionDiagram-c3b39e89bd475c2f70b02b60c544de1f.png"}}]); \ No newline at end of file diff --git a/assets/js/2a8faff0.3559b72e.js b/assets/js/2a8faff0.bab1919e.js similarity index 88% rename from assets/js/2a8faff0.3559b72e.js rename to assets/js/2a8faff0.bab1919e.js index 69058e062..b2d2882db 100644 --- a/assets/js/2a8faff0.3559b72e.js +++ b/assets/js/2a8faff0.bab1919e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7901],{1150:e=>{e.exports=JSON.parse('{"label":"test","permalink":"/tags/test","allTagsPath":"/tags","count":2}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7901],{1150:e=>{e.exports=JSON.parse('{"label":"test","permalink":"/tags/test","allTagsPath":"/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/2bfe7c0b.417a3763.js b/assets/js/2bfe7c0b.2258198c.js similarity index 88% rename from assets/js/2bfe7c0b.417a3763.js rename to assets/js/2bfe7c0b.2258198c.js index 50e39e8f7..0335819d1 100644 --- a/assets/js/2bfe7c0b.417a3763.js +++ b/assets/js/2bfe7c0b.2258198c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1762],{82670:e=>{e.exports=JSON.parse('{"label":"Book","permalink":"/tags/book","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1762],{82670:e=>{e.exports=JSON.parse('{"label":"Book","permalink":"/tags/book","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/2c446262.794bbcbb.js b/assets/js/2c446262.5e6afa9d.js similarity index 78% rename from assets/js/2c446262.794bbcbb.js rename to assets/js/2c446262.5e6afa9d.js index 6173d9a13..fc4711ed6 100644 --- a/assets/js/2c446262.794bbcbb.js +++ b/assets/js/2c446262.5e6afa9d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7797],{16402:e=>{e.exports=JSON.parse('{"label":"collection","permalink":"/docs/tags/collection","allTagsPath":"/docs/tags","count":1,"items":[{"id":"Java/SequencedCollection","title":"SequencedCollection","description":"JEP 431: Sequenced Collections","permalink":"/docs/java/sequenced-collection"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7797],{16402:e=>{e.exports=JSON.parse('{"label":"collection","permalink":"/docs/tags/collection","allTagsPath":"/docs/tags","count":1,"items":[{"id":"Java/SequencedCollection","title":"SequencedCollection","description":"JEP 431: Sequenced Collections","permalink":"/docs/java/sequenced-collection"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/2c9f5501.313f53d8.js b/assets/js/2c9f5501.313f53d8.js new file mode 100644 index 000000000..2fc0dfa95 --- /dev/null +++ b/assets/js/2c9f5501.313f53d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7775],{75040:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=r(85893),l=r(3905);const i={title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",slug:"the-essence-of-object-orientation",tags:["Book"]},s=void 0,c={permalink:"/the-essence-of-object-orientation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",source:"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",description:"\ucc45 \uc815\ubcf4",date:"2023-01-07T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 7\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:5.415,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",slug:"the-essence-of-object-orientation",tags:["Book"]},unlisted:!1,prevItem:{title:"JSR-310",permalink:"/jsr-310"},nextItem:{title:"2022\ub144 \ud68c\uace0",permalink:"/2022-retrospective"}},o={authorsImageUrls:[]},a=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173",id:"\ucc45\uc784\uc758-\uc790\uc728\uc131\uc744-\uac15\uc870\ud558\ub294-\uc774\uc720-p173",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}];function p(e){const n={blockquote:"blockquote",br:"br",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,l.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\ucc45-\uc815\ubcf4",children:"\ucc45 \uc815\ubcf4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",(0,t.jsx)(n.br,{}),"\n","\uc870\uc601\ud638"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc77d\uace0-\ub098\uc11c",children:"\uc77d\uace0 \ub098\uc11c"}),"\n",(0,t.jsxs)(n.p,{children:["\uc870\uc601\ud638\ub2d8\uc758 \uc624\ube0c\uc81d\ud2b8\ub97c \uc77d\uace0 \ub098\uc11c \ub2e4\uc2dc \ud55c \ubc88 \uc77d\uc5b4\ubcf4\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc544\uc9c1 \uc774\ud574\uac00 \uc548\ub418\ub294 \ubd80\ubd84\uc774 \ub9ce\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ud56d\uc0c1 \uc0c8\ub85c\uc6c0\uc744 \ub290\ub080\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub354\ud560 \ub098\uc704 \uc5c6\uc774 \ud73c\ub96d\ud55c \uac1d\uccb4\uc9c0\ud5a5 \ucc45\uc774\uace0, \uc870\uae08 \ub354 \uacf5\ubd80\ud558\uace0 \ub2e4\uc2dc \uc77d\uc5b4\ubd10\uc57c\ub420 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\ucee4\ud53c \uc804\ubb38\uc810, \uc9c0\ud558\ucca0 \ub178\uc120\ub3c4, \uc774\uc0c1\ud55c \ub098\ub77c\uc758 \uc5d8\ub9ac\uc2a4\ub97c \uc608\uc2dc\ub85c \ub4e0 \uc124\uba85\uc774 \ub108\ubb34 \uc88b\uc558\uace0",(0,t.jsx)(n.br,{}),"\n","\uc88b\uc740 \ub0b4\uc6a9\uc744 \ub2f4\uace0 \uc788\uc9c0\ub9cc \uadf8\ub807\ub2e4\uace0 \ub108\ubb34 \ubb34\uac81\uc9c0 \uc54a\uc544 \uac00\ubccd\uac8c \uc77d\uae30\ub3c4 \uc88b\uc740 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ucc45\uc784\uc758-\uc790\uc728\uc131\uc744-\uac15\uc870\ud558\ub294-\uc774\uc720-p173",children:"\ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173"}),"\n",(0,t.jsx)(n.p,{children:"\ud611\ub825\uc744 \ub2e8\uc21c\ud558\uac8c \ub9cc\ub4e0\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc758\ub3c4\ub97c \uba85\ud655\ud558\uac8c \ud45c\ud604 \u2192 \ud611\ub825\uc758 \ubcf5\uc7a1\ud568 \uc800\ud558"}),"\n",(0,t.jsx)(n.li,{children:"\ucc45\uc784\uc758 \ucd94\uc0c1\ud654"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\uc678\ubd80\uc640 \ub0b4\ubd80\ub97c \uba85\ud655\ud558\uac8c \ubd84\ub9ac\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc694\uccad\ud558\ub294 \uac1d\uccb4\uac00 \ubab0\ub77c\ub3c4 \ub418\ub294 \ubd80\ubd84\uc774 \ucea1\uc290\ud654\ub428\uc73c\ub85c \uc778\ud130\ud398\uc774\uc2a4\uc640 \uad6c\ud604\uc758 \ubd84\ub9ac"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub0b4\ubd80\uc801\uc778 \ubc29\ubc95\uc744 \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 \uc678\ubd80\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub294\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\ubcc0\uacbd\uc758 \ud30c\uae09\ud6a8\uacfc\ub97c \uac1d\uccb4 \ub0b4\ubd80\ub85c \ucea1\uc290\ud654 \u2192 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \uac1d\uccb4\uc640\uc758 \uacb0\ud569\ub3c4 \uc800\ud558"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\ud611\ub825\uc758 \ub300\uc0c1\uc744 \ub2e4\uc591\ud558\uac8c \uc120\ud0dd\ud560 \uc218 \uc788\ub294 \uc720\uc5f0\uc131\uc744 \uc81c\uacf5\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc720\uc5f0\ud55c \uc124\uacc4 \u2192 \uc7ac\uc0ac\uc6a9\uc131 \uc99d\uac00"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\uc758 \uc5ed\ud560\uc744 \uc774\ud574\ud558\uae30 \uc26c\uc6cc\uc9c4\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc751\uc9d1\ub3c4\ub97c \ub192\uc740 \uc0c1\ud0dc\ub85c \uc720\uc9c0"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",children:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubaa9\ud45c\ub294 \uc2e4\uc138\uacc4\ub97c \ubaa8\ubc29\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\n\uc624\ud788\ub824 \uc0c8\ub85c\uc6b4 \uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uac1c\ubc1c\uc790\uc758 \uc5ed\ud560\uc740 \ub2e8\uc21c\ud788 \uc2e4\uc138\uacc4\ub97c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc548\uc73c\ub85c \uc62e\uaca8 \ub2f4\ub294 \uac83\uc774 \uc544\ub2c8\ub77c \uace0\uac1d\uacfc \uc0ac\uc6a9\uc790\ub97c \ub9cc\uc871\uc2dc\ud0ac \uc218 \uc788\ub294 \uc2e0\uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\np.21"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uacfc\uac70\uc758 \uc804\ud1b5\uc801\uc778 \uac1c\ubc1c \ubc29\ubc95\uc740 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uc5c4\uaca9\ud558\uac8c \uad6c\ubd84\ud55c\ub2e4.\n\uc774\uc5d0 \ubc18\ud574 \uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c\ub294 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uac1d\uccb4\ub77c\ub294 \ud558\ub098\uc758 \ud2c0 \uc548\uc5d0 \ud568\uaed8 \ubb36\uc5b4 \ub193\uc74c\uc73c\ub85c\uc368 \uac1d\uccb4\uc758 \uc790\uc728\uc131\uc744 \ubcf4\uc7a5\ud55c\ub2e4.\n\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub85c \uad6c\uc131\ub41c \uacf5\ub3d9\uccb4\ub294 \uc720\uc9c0 \ubcf4\uc218\uac00 \uc27d\uace0 \uc7ac\uc0ac\uc6a9\uc774 \uc6a9\uc774\ud55c \uc2dc\uc2a4\ud15c\uc744 \uad6c\ucd95\ud560 \uc218 \uc788\ub294 \uac00\ub2a5\uc131\uc744 \uc81c\uc2dc\ud55c\ub2e4.\np.33"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubcf8\uc9c8"})}),"\n",(0,t.jsx)(n.p,{children:"\uc2dc\uc2a4\ud15c\uc744 \uc0c1\ud638\uc791\uc6a9\ud558\ub294 \uc790\uc728\uc801\uc778 \uac1d\uccb4\ub4e4\uc758 \uacf5\ub3d9\uccb4\ub85c \ubc14\ub77c\ubcf4\uace0 \uac1d\uccb4\ub97c \uc774\uc6a9\ud574 \uc2dc\uc2a4\ud15c\uc744 \ubd84\ud560\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsx)(n.p,{children:"\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub780 \uc0c1\ud0dc\uc640 \ud589\uc704\ub97c \ud568\uaed8 \uc9c0\ub2c8\uba70 \uc2a4\uc2a4\ub85c \uc790\uae30 \uc790\uc2e0\uc744 \ucc45\uc784\uc9c0\ub294 \uac1d\uccb4\ub97c \uc758\ubbf8\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\ub294 \uc2dc\uc2a4\ud15c\uc758 \ud589\uc704\ub97c \uad6c\ud604\ud558\uae30 \uc704\ud574 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud55c\ub2e4. \uac01 \uac1d\uccb4\ub294 \ud611\ub825 \ub0b4\uc5d0\uc11c \uc815\ud574\uc9c4 \uc5ed\ud560\uc744 \uc218\ud589\ud558\uba70 \uc5ed\ud560\uc740 \uad00\ub828\ub41c \ucc45\uc784\uc758 \uc9d1\ud569\uc774\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\ub294 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud558\uae30 \uc704\ud574 \uba54\uc2dc\uc9c0\ub97c \uc804\uc1a1\ud558\uace0, \uba54\uc2dc\uc9c0\ub97c \uc218\uc2e0\ud55c \uac1d\uccb4\ub294 \uba54\uc2dc\uc9c0\ub97c \ucc98\ub9ac\ud558\ub294 \ub370 \uc801\ud569\ud55c \uba54\uc11c\ub4dc\ub97c \uc790\uc728\uc801\uc73c\ub85c \uc120\ud0dd\ud55c\ub2e4.\np.35"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ud074\ub798\uc2a4\uc758 \uad6c\uc870\uc640 \uba54\uc11c\ub4dc\uac00 \uc544\ub2c8\ub77c \uac1d\uccb4\uc758 \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc5d0 \uc9d1\uc911\ud558\ub77c.\n\uac1d\uccb4\uc9c0\ud5a5\uc740 \uac1d\uccb4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774\uc9c0 \ud074\ub798\uc2a4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\np.38"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c \uc911\uc694\ud55c \uac83\uc740 \ub3d9\uc801\uc73c\ub85c \ubcc0\ud558\ub294 \uac1d\uccb4\uc758 \u2018\uc0c1\ud0dc\u2019\uc640 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\ub294 \u2018\ud589\uc704\u2019\ub2e4.\n\ud074\ub798\uc2a4\ub294 \ud0c0\uc785\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud574 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uad6c\ud604 \uba54\ucee4\ub2c8\uc998\uc774\ub77c\ub294 \uc0ac\uc2e4\uc744 \uae30\uc5b5\ud558\ub77c.\np.105"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ucc45\uc784 \uc8fc\ub3c4 \uc124\uacc4\uc758 \ud575\uc2ec\uc740 \uc5b4\ub5a4 \ud589\uc704\uac00 \ud544\uc694\ud55c\uc9c0\ub97c \uba3c\uc800 \uacb0\uc815\ud55c \ud6c4\uc5d0 \uc774 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac1d\uccb4\ub97c \uacb0\uc815\ud558\ub294 \uac83\uc774\ub2e4.\n\uc774 \uacfc\uc815\uc744 \ud754\ud788 What/Who \uc0ac\uc774\ud074\uc774\ub77c\uace0 \ud55c\ub2e4.\n\u2019\uc5b4\ub5a4 \ud589\uc704(What)\u2019\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud55c \ud6c4 \u2018\ub204\uac00(who)\u2019 \uadf8 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud574\uc57c \ud55c\ub2e4.\n\uc5ec\uae30\uc11c \u2018\uc5b4\ub5a4 \ud589\uc704\u2019\uac00 \ubc14\ub85c \uba54\uc2dc\uc9c0\ub2e4.\np.158"}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,l.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function l(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n=0||(l[r]=e[r]);return l}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(l[r]=e[r])}return l}var o=t.createContext({}),a=function(e){var n=t.useContext(o),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,l=e.mdxType,i=e.originalType,o=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),h=a(r),u=l,j=h["".concat(o,".").concat(u)]||h[u]||p[u]||i;return r?t.createElement(j,s(s({ref:n},d),{},{components:r})):t.createElement(j,s({ref:n},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/2c9f5501.592c2549.js b/assets/js/2c9f5501.592c2549.js deleted file mode 100644 index 09e5a0ade..000000000 --- a/assets/js/2c9f5501.592c2549.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7775],{3905:(e,t,n)=>{n.d(t,{Zo:()=>i,kt:()=>s});var r=n(67294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},i=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},k={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,l=e.mdxType,o=e.originalType,u=e.parentName,i=p(e,["components","mdxType","originalType","parentName"]),m=c(n),s=l,b=m["".concat(u,".").concat(s)]||m[s]||k[s]||o;return n?r.createElement(b,a(a({ref:t},i),{},{components:n})):r.createElement(b,a({ref:t},i))}));function s(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var o=n.length,a=new Array(o);a[0]=m;var p={};for(var u in t)hasOwnProperty.call(t,u)&&(p[u]=t[u]);p.originalType=e,p.mdxType="string"==typeof e?e:l,a[1]=p;for(var c=2;c{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>k,frontMatter:()=>o,metadata:()=>p,toc:()=>c});var r=n(87462),l=(n(67294),n(3905));const o={title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",slug:"the-essence-of-object-orientation",tags:["Book"]},a=void 0,p={permalink:"/the-essence-of-object-orientation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",source:"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",description:"\ucc45 \uc815\ubcf4",date:"2023-01-07T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 7\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:5.415,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",slug:"the-essence-of-object-orientation",tags:["Book"]},prevItem:{title:"JSR-310",permalink:"/jsr-310"},nextItem:{title:"2022\ub144 \ud68c\uace0",permalink:"/2022-retrospective"}},u={authorsImageUrls:[]},c=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173",id:"\ucc45\uc784\uc758-\uc790\uc728\uc131\uc744-\uac15\uc870\ud558\ub294-\uc774\uc720-p173",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}],i={toc:c};function k(e){let{components:t,...n}=e;return(0,l.kt)("wrapper",(0,r.Z)({},i,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h3",{id:"\ucc45-\uc815\ubcf4"},"\ucc45 \uc815\ubcf4"),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",(0,l.kt)("br",{parentName:"p"}),"\n","\uc870\uc601\ud638")),(0,l.kt)("h3",{id:"\uc77d\uace0-\ub098\uc11c"},"\uc77d\uace0 \ub098\uc11c"),(0,l.kt)("p",null,"\uc870\uc601\ud638\ub2d8\uc758 \uc624\ube0c\uc81d\ud2b8\ub97c \uc77d\uace0 \ub098\uc11c \ub2e4\uc2dc \ud55c \ubc88 \uc77d\uc5b4\ubcf4\uc558\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\uc544\uc9c1 \uc774\ud574\uac00 \uc548\ub418\ub294 \ubd80\ubd84\uc774 \ub9ce\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ud56d\uc0c1 \uc0c8\ub85c\uc6c0\uc744 \ub290\ub080\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ub354\ud560 \ub098\uc704 \uc5c6\uc774 \ud73c\ub96d\ud55c \uac1d\uccb4\uc9c0\ud5a5 \ucc45\uc774\uace0, \uc870\uae08 \ub354 \uacf5\ubd80\ud558\uace0 \ub2e4\uc2dc \uc77d\uc5b4\ubd10\uc57c\ub420 \uac83 \uac19\ub2e4. "),(0,l.kt)("p",null,"\ucee4\ud53c \uc804\ubb38\uc810, \uc9c0\ud558\ucca0 \ub178\uc120\ub3c4, \uc774\uc0c1\ud55c \ub098\ub77c\uc758 \uc5d8\ub9ac\uc2a4\ub97c \uc608\uc2dc\ub85c \ub4e0 \uc124\uba85\uc774 \ub108\ubb34 \uc88b\uc558\uace0",(0,l.kt)("br",{parentName:"p"}),"\n","\uc88b\uc740 \ub0b4\uc6a9\uc744 \ub2f4\uace0 \uc788\uc9c0\ub9cc \uadf8\ub807\ub2e4\uace0 \ub108\ubb34 \ubb34\uac81\uc9c0 \uc54a\uc544 \uac00\ubccd\uac8c \uc77d\uae30\ub3c4 \uc88b\uc740 \uac83 \uac19\ub2e4."),(0,l.kt)("h3",{id:"\ucc45\uc784\uc758-\uc790\uc728\uc131\uc744-\uac15\uc870\ud558\ub294-\uc774\uc720-p173"},"\ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173"),(0,l.kt)("p",null,"\ud611\ub825\uc744 \ub2e8\uc21c\ud558\uac8c \ub9cc\ub4e0\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uc758\ub3c4\ub97c \uba85\ud655\ud558\uac8c \ud45c\ud604 \u2192 \ud611\ub825\uc758 \ubcf5\uc7a1\ud568 \uc800\ud558"),(0,l.kt)("li",{parentName:"ul"},"\ucc45\uc784\uc758 \ucd94\uc0c1\ud654")),(0,l.kt)("p",null,"\uc678\ubd80\uc640 \ub0b4\ubd80\ub97c \uba85\ud655\ud558\uac8c \ubd84\ub9ac\ud55c\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uc694\uccad\ud558\ub294 \uac1d\uccb4\uac00 \ubab0\ub77c\ub3c4 \ub418\ub294 \ubd80\ubd84\uc774 \ucea1\uc290\ud654\ub428\uc73c\ub85c \uc778\ud130\ud398\uc774\uc2a4\uc640 \uad6c\ud604\uc758 \ubd84\ub9ac")),(0,l.kt)("p",null,"\ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub0b4\ubd80\uc801\uc778 \ubc29\ubc95\uc744 \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 \uc678\ubd80\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub294\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\ubcc0\uacbd\uc758 \ud30c\uae09\ud6a8\uacfc\ub97c \uac1d\uccb4 \ub0b4\ubd80\ub85c \ucea1\uc290\ud654 \u2192 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \uac1d\uccb4\uc640\uc758 \uacb0\ud569\ub3c4 \uc800\ud558")),(0,l.kt)("p",null,"\ud611\ub825\uc758 \ub300\uc0c1\uc744 \ub2e4\uc591\ud558\uac8c \uc120\ud0dd\ud560 \uc218 \uc788\ub294 \uc720\uc5f0\uc131\uc744 \uc81c\uacf5\ud55c\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uc720\uc5f0\ud55c \uc124\uacc4 \u2192 \uc7ac\uc0ac\uc6a9\uc131 \uc99d\uac00")),(0,l.kt)("p",null,"\uac1d\uccb4\uc758 \uc5ed\ud560\uc744 \uc774\ud574\ud558\uae30 \uc26c\uc6cc\uc9c4\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uc751\uc9d1\ub3c4\ub97c \ub192\uc740 \uc0c1\ud0dc\ub85c \uc720\uc9c0")),(0,l.kt)("h3",{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4"},"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubaa9\ud45c\ub294 \uc2e4\uc138\uacc4\ub97c \ubaa8\ubc29\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\n\uc624\ud788\ub824 \uc0c8\ub85c\uc6b4 \uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uac1c\ubc1c\uc790\uc758 \uc5ed\ud560\uc740 \ub2e8\uc21c\ud788 \uc2e4\uc138\uacc4\ub97c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc548\uc73c\ub85c \uc62e\uaca8 \ub2f4\ub294 \uac83\uc774 \uc544\ub2c8\ub77c \uace0\uac1d\uacfc \uc0ac\uc6a9\uc790\ub97c \ub9cc\uc871\uc2dc\ud0ac \uc218 \uc788\ub294 \uc2e0\uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\np.21")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\uacfc\uac70\uc758 \uc804\ud1b5\uc801\uc778 \uac1c\ubc1c \ubc29\ubc95\uc740 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uc5c4\uaca9\ud558\uac8c \uad6c\ubd84\ud55c\ub2e4.\n\uc774\uc5d0 \ubc18\ud574 \uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c\ub294 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uac1d\uccb4\ub77c\ub294 \ud558\ub098\uc758 \ud2c0 \uc548\uc5d0 \ud568\uaed8 \ubb36\uc5b4 \ub193\uc74c\uc73c\ub85c\uc368 \uac1d\uccb4\uc758 \uc790\uc728\uc131\uc744 \ubcf4\uc7a5\ud55c\ub2e4.\n\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub85c \uad6c\uc131\ub41c \uacf5\ub3d9\uccb4\ub294 \uc720\uc9c0 \ubcf4\uc218\uac00 \uc27d\uace0 \uc7ac\uc0ac\uc6a9\uc774 \uc6a9\uc774\ud55c \uc2dc\uc2a4\ud15c\uc744 \uad6c\ucd95\ud560 \uc218 \uc788\ub294 \uac00\ub2a5\uc131\uc744 \uc81c\uc2dc\ud55c\ub2e4.\np.33")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},(0,l.kt)("strong",{parentName:"p"},"\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubcf8\uc9c8")),(0,l.kt)("p",{parentName:"blockquote"},"\uc2dc\uc2a4\ud15c\uc744 \uc0c1\ud638\uc791\uc6a9\ud558\ub294 \uc790\uc728\uc801\uc778 \uac1d\uccb4\ub4e4\uc758 \uacf5\ub3d9\uccb4\ub85c \ubc14\ub77c\ubcf4\uace0 \uac1d\uccb4\ub97c \uc774\uc6a9\ud574 \uc2dc\uc2a4\ud15c\uc744 \ubd84\ud560\ud558\ub294 \ubc29\ubc95"),(0,l.kt)("p",{parentName:"blockquote"},"\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub780 \uc0c1\ud0dc\uc640 \ud589\uc704\ub97c \ud568\uaed8 \uc9c0\ub2c8\uba70 \uc2a4\uc2a4\ub85c \uc790\uae30 \uc790\uc2e0\uc744 \ucc45\uc784\uc9c0\ub294 \uac1d\uccb4\ub97c \uc758\ubbf8\ud55c\ub2e4."),(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\ub294 \uc2dc\uc2a4\ud15c\uc758 \ud589\uc704\ub97c \uad6c\ud604\ud558\uae30 \uc704\ud574 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud55c\ub2e4. \uac01 \uac1d\uccb4\ub294 \ud611\ub825 \ub0b4\uc5d0\uc11c \uc815\ud574\uc9c4 \uc5ed\ud560\uc744 \uc218\ud589\ud558\uba70 \uc5ed\ud560\uc740 \uad00\ub828\ub41c \ucc45\uc784\uc758 \uc9d1\ud569\uc774\ub2e4."),(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\ub294 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud558\uae30 \uc704\ud574 \uba54\uc2dc\uc9c0\ub97c \uc804\uc1a1\ud558\uace0, \uba54\uc2dc\uc9c0\ub97c \uc218\uc2e0\ud55c \uac1d\uccb4\ub294 \uba54\uc2dc\uc9c0\ub97c \ucc98\ub9ac\ud558\ub294 \ub370 \uc801\ud569\ud55c \uba54\uc11c\ub4dc\ub97c \uc790\uc728\uc801\uc73c\ub85c \uc120\ud0dd\ud55c\ub2e4.\np.35")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\ud074\ub798\uc2a4\uc758 \uad6c\uc870\uc640 \uba54\uc11c\ub4dc\uac00 \uc544\ub2c8\ub77c \uac1d\uccb4\uc758 \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc5d0 \uc9d1\uc911\ud558\ub77c.\n\uac1d\uccb4\uc9c0\ud5a5\uc740 \uac1d\uccb4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774\uc9c0 \ud074\ub798\uc2a4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\np.38")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c \uc911\uc694\ud55c \uac83\uc740 \ub3d9\uc801\uc73c\ub85c \ubcc0\ud558\ub294 \uac1d\uccb4\uc758 \u2018\uc0c1\ud0dc\u2019\uc640 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\ub294 \u2018\ud589\uc704\u2019\ub2e4.\n\ud074\ub798\uc2a4\ub294 \ud0c0\uc785\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud574 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uad6c\ud604 \uba54\ucee4\ub2c8\uc998\uc774\ub77c\ub294 \uc0ac\uc2e4\uc744 \uae30\uc5b5\ud558\ub77c.\np.105")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\ucc45\uc784 \uc8fc\ub3c4 \uc124\uacc4\uc758 \ud575\uc2ec\uc740 \uc5b4\ub5a4 \ud589\uc704\uac00 \ud544\uc694\ud55c\uc9c0\ub97c \uba3c\uc800 \uacb0\uc815\ud55c \ud6c4\uc5d0 \uc774 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac1d\uccb4\ub97c \uacb0\uc815\ud558\ub294 \uac83\uc774\ub2e4.\n\uc774 \uacfc\uc815\uc744 \ud754\ud788 What/Who \uc0ac\uc774\ud074\uc774\ub77c\uace0 \ud55c\ub2e4.\n\u2019\uc5b4\ub5a4 \ud589\uc704(What)\u2019\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud55c \ud6c4 \u2018\ub204\uac00(who)\u2019 \uadf8 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud574\uc57c \ud55c\ub2e4.\n\uc5ec\uae30\uc11c \u2018\uc5b4\ub5a4 \ud589\uc704\u2019\uac00 \ubc14\ub85c \uba54\uc2dc\uc9c0\ub2e4.\np.158")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2d3b202f.fad40be0.js b/assets/js/2d3b202f.7ed7c756.js similarity index 88% rename from assets/js/2d3b202f.fad40be0.js rename to assets/js/2d3b202f.7ed7c756.js index d4f4f1386..c917f1d23 100644 --- a/assets/js/2d3b202f.fad40be0.js +++ b/assets/js/2d3b202f.7ed7c756.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1196],{42524:e=>{e.exports=JSON.parse('{"label":"Book","permalink":"/tags/book","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1196],{42524:e=>{e.exports=JSON.parse('{"label":"Book","permalink":"/tags/book","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/2d9296e4.a52c556a.js b/assets/js/2d9296e4.d46cb8ea.js similarity index 85% rename from assets/js/2d9296e4.a52c556a.js rename to assets/js/2d9296e4.d46cb8ea.js index 68894a521..8725221f0 100644 --- a/assets/js/2d9296e4.a52c556a.js +++ b/assets/js/2d9296e4.d46cb8ea.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3483],{89429:e=>{e.exports=JSON.parse('{"label":"Pattern","permalink":"/tags/pattern","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3483],{89429:e=>{e.exports=JSON.parse('{"label":"Pattern","permalink":"/tags/pattern","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/302370be.1897c05f.js b/assets/js/302370be.1897c05f.js deleted file mode 100644 index 668a773ac..000000000 --- a/assets/js/302370be.1897c05f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1883],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),s=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=s(e.components);return n.createElement(p.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,p=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),u=s(r),f=a,m=u["".concat(p,".").concat(f)]||u[f]||d[f]||l;return r?n.createElement(m,i(i({ref:t},c),{},{components:r})):n.createElement(m,i({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,i=new Array(l);i[0]=u;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o.mdxType="string"==typeof e?e:a,i[1]=o;for(var s=2;s{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const l={title:"FIRST",slug:"/test/first",last_update:{date:"2023/09/15"},tags:["test"]},i=void 0,o={unversionedId:"\ud14c\uc2a4\ud2b8/FIRST",id:"\ud14c\uc2a4\ud2b8/FIRST",title:"FIRST",description:"FIRST\ub780?",source:"@site/docs/\ud14c\uc2a4\ud2b8/FIRST.mdx",sourceDirName:"\ud14c\uc2a4\ud2b8",slug:"/test/first",permalink:"/docs/test/first",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ud14c\uc2a4\ud2b8/FIRST.mdx",tags:[{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1694736e3,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 15\uc77c",frontMatter:{title:"FIRST",slug:"/test/first",last_update:{date:"2023/09/15"},tags:["test"]},sidebar:"tutorialSidebar",previous:{title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",permalink:"/docs/architecture/virtical-slice-architecture"},next:{title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",permalink:"/docs/test/stairstep"}},p={},s=[{value:"FIRST\ub780?",id:"first\ub780",level:3},{value:"Fast(\ube60\ub974\uac8c)",id:"fast\ube60\ub974\uac8c",level:3},{value:"Independent(\ub3c5\ub9bd\uc801\uc73c\ub85c)",id:"independent\ub3c5\ub9bd\uc801\uc73c\ub85c",level:3},{value:"Repeatable(\ubc18\ubcf5 \uac00\ub2a5\ud55c)",id:"repeatable\ubc18\ubcf5-\uac00\ub2a5\ud55c",level:3},{value:"Self-Validating(\uc790\uac00 \uac80\uc99d\ud558\ub294)",id:"self-validating\uc790\uac00-\uac80\uc99d\ud558\ub294",level:3},{value:"Timely(\uc801\uc2dc\uc5d0)",id:"timely\uc801\uc2dc\uc5d0",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],c={toc:s};function d(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"first\ub780"},"FIRST\ub780?"),(0,a.kt)("p",null,"Fast, Independent, Repeatable, Self-Validating, Timely\uc758 \uc57d\uc790\ub85c \uc88b\uc740 \ub2e8\uc704 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub294\ub370 \ub3c4\uc6c0\uc774 \ub418\ub294 \uc6d0\uce59\ub4e4\uc774\ub2e4."),(0,a.kt)("h3",{id:"fast\ube60\ub974\uac8c"},"Fast(\ube60\ub974\uac8c)"),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\uac00 \ube60\ub974\uac8c \ub3cc\uc544\uac00\uc9c0 \uc54a\uc73c\uba74, \ud14c\uc2a4\ud2b8\ub97c \ub9e4 \uc21c\uac04 \uc2e4\ud589\ud558\uc9c0 \uc54a\uc744 \uac83\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc2a4\ud2b8\ub97c \uc790\uc8fc \uc2e4\ud589\ud558\uc9c0 \uc54a\uc73c\uba74, \ubc84\uadf8\ub97c \ub193\uce60 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ube60\ub974\uac8c \ud14c\uc2a4\ud2b8\ub97c \ub3cc\ub824 \ud53c\ub4dc\ubc31 \ubc1b\ub294 \uc8fc\uae30\ub97c \uc9e7\uac8c \ub9cc\ub4dc\ub294 \uac83\uc774 \uc88b\ub2e4. "),(0,a.kt)("h3",{id:"independent\ub3c5\ub9bd\uc801\uc73c\ub85c"},"Independent(\ub3c5\ub9bd\uc801\uc73c\ub85c)"),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\ub07c\ub9ac \uc11c\ub85c \uc758\uc874\ud558\uba74 \uc548\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc11c\ub85c \uc758\uc874\ud558\uac8c \ub41c\ub2e4\uba74 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \ub54c, \ub610 \ub2e4\ub978 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589 \uac00\ub2a5\ud55c \ud14c\uc2a4\ud2b8\uac00 \uc88b\uc740 \ud14c\uc2a4\ud2b8\ub2e4. "),(0,a.kt)("h3",{id:"repeatable\ubc18\ubcf5-\uac00\ub2a5\ud55c"},"Repeatable(\ubc18\ubcf5 \uac00\ub2a5\ud55c)"),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\ub294 \uc5b4\ub5a0\ud55c \ud658\uacbd\uc5d0\uc11c\ub77c\ub3c4 \ubc18\ubcf5 \uac00\ub2a5\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ubc18\ubcf5\uc801\uc73c\ub85c \uc218\ud589\ud574\ub3c4 \uac19\uc740 \uacb0\uacfc\ub97c \ub0bc \uc218 \uc788\uc5b4\uc57c \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"self-validating\uc790\uac00-\uac80\uc99d\ud558\ub294"},"Self-Validating(\uc790\uac00 \uac80\uc99d\ud558\ub294)"),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\ub294 \uc131\uacf5 \ub610\ub294 \uc2e4\ud328\ub85c bool \uac12\uc73c\ub85c \uacb0\uacfc\ub97c \ub0b4\uc5b4 \uc790\uccb4\uc801\uc73c\ub85c \uac80\uc99d\ud574\uc57c \ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","JUnit\uacfc \uac19\uc740 \uc790\ub3d9\ud654\ub41c \ud14c\uc2a4\ud2b8 \ub3c4\uad6c\ub97c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"timely\uc801\uc2dc\uc5d0"},"Timely(\uc801\uc2dc\uc5d0)"),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\ub294 \uc801\uc2dc\uc5d0 \uc791\uc131\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc704 \ud14c\uc2a4\ud2b8\ub294 \ud14c\uc2a4\ud2b8 \ud558\ub824\ub294 \uc2e4\uc81c \ucf54\ub4dc\ub97c \uad6c\ud604\ud558\uae30 \uc9c1\uc804\uc5d0 \uad6c\ud604\ud574\uc57c \ud55c\ub2e4.(TDD)",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2e4\uc81c \ucf54\ub4dc\ub97c \uad6c\ud604\ud55c \ub2e4\uc74c\uc5d0 \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud55c\ub2e4\uba74, \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc5b4\ub824\uc6b4 \ucf54\ub4dc\ub97c \uc791\uc131\ud588\ub2e4\ub294 \uac83\uc744 \ub4a4\ub2a6\uac8c \ubc1c\uacac\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://tddmanifesto.com/a-clean-test/"},"A clean test, TDD Manifasto"),(0,a.kt)("br",{parentName:"p"}),"\n","Clean Code 9\uc7a5 \ub2e8\uc704\ud14c\uc2a4\ud2b8, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4"))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/302370be.5f8295a8.js b/assets/js/302370be.5f8295a8.js new file mode 100644 index 000000000..85557e845 --- /dev/null +++ b/assets/js/302370be.5f8295a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1883],{21779:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>o});var r=n(85893),i=n(3905);const a={title:"FIRST",slug:"/test/first",last_update:{date:"2023/09/15"},tags:["test"]},s=void 0,l={id:"\ud14c\uc2a4\ud2b8/FIRST",title:"FIRST",description:"FIRST\ub780?",source:"@site/docs/\ud14c\uc2a4\ud2b8/FIRST.mdx",sourceDirName:"\ud14c\uc2a4\ud2b8",slug:"/test/first",permalink:"/docs/test/first",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ud14c\uc2a4\ud2b8/FIRST.mdx",tags:[{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1694736e3,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 15\uc77c",frontMatter:{title:"FIRST",slug:"/test/first",last_update:{date:"2023/09/15"},tags:["test"]},sidebar:"tutorialSidebar",previous:{title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",permalink:"/docs/architecture/virtical-slice-architecture"},next:{title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",permalink:"/docs/test/stairstep"}},c={},o=[{value:"FIRST\ub780?",id:"first\ub780",level:3},{value:"Fast(\ube60\ub974\uac8c)",id:"fast\ube60\ub974\uac8c",level:3},{value:"Independent(\ub3c5\ub9bd\uc801\uc73c\ub85c)",id:"independent\ub3c5\ub9bd\uc801\uc73c\ub85c",level:3},{value:"Repeatable(\ubc18\ubcf5 \uac00\ub2a5\ud55c)",id:"repeatable\ubc18\ubcf5-\uac00\ub2a5\ud55c",level:3},{value:"Self-Validating(\uc790\uac00 \uac80\uc99d\ud558\ub294)",id:"self-validating\uc790\uac00-\uac80\uc99d\ud558\ub294",level:3},{value:"Timely(\uc801\uc2dc\uc5d0)",id:"timely\uc801\uc2dc\uc5d0",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function d(e){const t={a:"a",br:"br",h2:"h2",h3:"h3",p:"p",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"first\ub780",children:"FIRST\ub780?"}),"\n",(0,r.jsx)(t.p,{children:"Fast, Independent, Repeatable, Self-Validating, Timely\uc758 \uc57d\uc790\ub85c \uc88b\uc740 \ub2e8\uc704 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub294\ub370 \ub3c4\uc6c0\uc774 \ub418\ub294 \uc6d0\uce59\ub4e4\uc774\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"fast\ube60\ub974\uac8c",children:"Fast(\ube60\ub974\uac8c)"}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\uac00 \ube60\ub974\uac8c \ub3cc\uc544\uac00\uc9c0 \uc54a\uc73c\uba74, \ud14c\uc2a4\ud2b8\ub97c \ub9e4 \uc21c\uac04 \uc2e4\ud589\ud558\uc9c0 \uc54a\uc744 \uac83\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud14c\uc2a4\ud2b8\ub97c \uc790\uc8fc \uc2e4\ud589\ud558\uc9c0 \uc54a\uc73c\uba74, \ubc84\uadf8\ub97c \ub193\uce60 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub530\ub77c\uc11c \ube60\ub974\uac8c \ud14c\uc2a4\ud2b8\ub97c \ub3cc\ub824 \ud53c\ub4dc\ubc31 \ubc1b\ub294 \uc8fc\uae30\ub97c \uc9e7\uac8c \ub9cc\ub4dc\ub294 \uac83\uc774 \uc88b\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"independent\ub3c5\ub9bd\uc801\uc73c\ub85c",children:"Independent(\ub3c5\ub9bd\uc801\uc73c\ub85c)"}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\ub07c\ub9ac \uc11c\ub85c \uc758\uc874\ud558\uba74 \uc548\ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc11c\ub85c \uc758\uc874\ud558\uac8c \ub41c\ub2e4\uba74 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \ub54c, \ub610 \ub2e4\ub978 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589 \uac00\ub2a5\ud55c \ud14c\uc2a4\ud2b8\uac00 \uc88b\uc740 \ud14c\uc2a4\ud2b8\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"repeatable\ubc18\ubcf5-\uac00\ub2a5\ud55c",children:"Repeatable(\ubc18\ubcf5 \uac00\ub2a5\ud55c)"}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\ub294 \uc5b4\ub5a0\ud55c \ud658\uacbd\uc5d0\uc11c\ub77c\ub3c4 \ubc18\ubcf5 \uac00\ub2a5\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub610\ud55c \ubc18\ubcf5\uc801\uc73c\ub85c \uc218\ud589\ud574\ub3c4 \uac19\uc740 \uacb0\uacfc\ub97c \ub0bc \uc218 \uc788\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"self-validating\uc790\uac00-\uac80\uc99d\ud558\ub294",children:"Self-Validating(\uc790\uac00 \uac80\uc99d\ud558\ub294)"}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\ub294 \uc131\uacf5 \ub610\ub294 \uc2e4\ud328\ub85c bool \uac12\uc73c\ub85c \uacb0\uacfc\ub97c \ub0b4\uc5b4 \uc790\uccb4\uc801\uc73c\ub85c \uac80\uc99d\ud574\uc57c \ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","JUnit\uacfc \uac19\uc740 \uc790\ub3d9\ud654\ub41c \ud14c\uc2a4\ud2b8 \ub3c4\uad6c\ub97c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"timely\uc801\uc2dc\uc5d0",children:"Timely(\uc801\uc2dc\uc5d0)"}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\ub294 \uc801\uc2dc\uc5d0 \uc791\uc131\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e8\uc704 \ud14c\uc2a4\ud2b8\ub294 \ud14c\uc2a4\ud2b8 \ud558\ub824\ub294 \uc2e4\uc81c \ucf54\ub4dc\ub97c \uad6c\ud604\ud558\uae30 \uc9c1\uc804\uc5d0 \uad6c\ud604\ud574\uc57c \ud55c\ub2e4.(TDD)",(0,r.jsx)(t.br,{}),"\n","\uc2e4\uc81c \ucf54\ub4dc\ub97c \uad6c\ud604\ud55c \ub2e4\uc74c\uc5d0 \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud55c\ub2e4\uba74, \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc5b4\ub824\uc6b4 \ucf54\ub4dc\ub97c \uc791\uc131\ud588\ub2e4\ub294 \uac83\uc744 \ub4a4\ub2a6\uac8c \ubc1c\uacac\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://tddmanifesto.com/a-clean-test/",children:"A clean test, TDD Manifasto"}),(0,r.jsx)(t.br,{}),"\n","Clean Code 9\uc7a5 \ub2e8\uc704\ud14c\uc2a4\ud2b8, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4"]})]})}function p(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>o});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),o=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=o(n),f=i,b=u["".concat(c,".").concat(f)]||u[f]||d[f]||a;return n?r.createElement(b,s(s({ref:t},p),{},{components:n})):r.createElement(b,s({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/303c1e60.9e56888d.js b/assets/js/303c1e60.650df522.js similarity index 81% rename from assets/js/303c1e60.9e56888d.js rename to assets/js/303c1e60.650df522.js index 2018cea7c..3e65647c6 100644 --- a/assets/js/303c1e60.9e56888d.js +++ b/assets/js/303c1e60.650df522.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2656],{39529:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2656],{39529:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/313.e71d3ee9.js b/assets/js/313.e71d3ee9.js new file mode 100644 index 000000000..eed441f54 --- /dev/null +++ b/assets/js/313.e71d3ee9.js @@ -0,0 +1,10323 @@ +"use strict"; +exports.id = 313; +exports.ids = [313]; +exports.modules = { + +/***/ 41644: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + bK: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.Z(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.Z( + map/* default */.Z(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.Z(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.Z(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.k(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.Z(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.Z(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.Z(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.Z(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.Z(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.Z('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.Z(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.Z(g.outEdges(v), function (e) { + if (has/* default */.Z(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.Z(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.Z(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(59236); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.Z)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(74752); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.Z)(iteratee, 3); + + (0,_baseForOwn/* default */.Z)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.Z)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(66092); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.Z.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.Z(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.k().setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.k({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.Z(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.Z(range/* default */.Z(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.Z(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.Z(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.Z(layers, function (vs, i) { + if (isUndefined/* default */.Z(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.Z(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.Z(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.Z(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.Z(children, dfs); + } + + if (has/* default */.Z(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.Z(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, reverseYOne); + if (has/* default */.Z(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, swapXYOne); + if (has/* default */.Z(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.Z(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.Z)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.Z(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.Z(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.Z(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.k({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.Z(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.Z(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.Z(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.Z)(collection)) { + var iteratee = (0,_baseIteratee/* default */.Z)(predicate, 3); + collection = (0,keys/* default */.Z)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.Z)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.Z)(array, (0,_baseIteratee/* default */.Z)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(39473); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(93589); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.Z)(value) && (0,isObjectLike/* default */.Z)(value) && (0,_baseGetTag/* default */.Z)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.Z)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.Z)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.Z)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.Z)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.Z(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.Z(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.Z(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.Z(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.Z(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.Z(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.Z(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.Z(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.Z(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.Z(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.Z(tree.neighbors(v), function (w) { + if (!has/* default */.Z(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.Z(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.Z(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.Z(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.Z(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.Z(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.Z(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.Z(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.Z(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.Z( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.Z(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.k({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.Z(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.Z(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.Z(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.Z('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.Z); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(21018); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.Z)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.Z)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + if ((0,isArray/* default */.Z)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.Z)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.Z]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.Z)(iteratees, (0,_baseUnary/* default */.Z)(_baseIteratee/* default */.Z)); + + var result = (0,_baseMap/* default */.Z)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.Z)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.Z)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.Z)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.Z)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.Z(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.Z( + map/* default */.Z(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.Z(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.Z(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.Z( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.Z(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.Z(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.Z(range/* default */.Z(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.Z(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.Z(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.Z(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.Z(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.Z( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.Z(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.Z(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.Z(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.Z(entryV) && !isUndefined/* default */.Z(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.Z(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.Z(uEntry.barycenter) || + isUndefined/* default */.Z(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.Z(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.Z(entry.out, handleOut(entry)); + } + + return map/* default */.Z( + filter/* default */.Z(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.Z(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.Z(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.Z(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.Z(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.Z(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.Z(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.Z(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.Z([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.Z(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.Z(entries, function (entry) { + entry.vs = flatten/* default */.Z( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.Z(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.Z(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.Z(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.Z(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.k(); + forEach/* default */.Z(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.Z(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.Z(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.Z(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(68882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(61395); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee), keysIn/* default */.Z); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.Z(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.Z(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.Z(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.Z(range/* default */.Z(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.Z(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.Z(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.Z(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.Z(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.Z(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.Z(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.k(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.Z(layering, function (layer) { + var u; + forEach/* default */.Z(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.Z(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.Z(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.Z(['u', 'd'], function (vert) { + forEach/* default */.Z(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.Z(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.Z(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.Z(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.Z(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.Z(layering).reverse(); + forEach/* default */.Z(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.Z(adjustedLayering, function (inner) { + return values/* default */.Z(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.Z(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.Z(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.Z(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.Z(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.Z(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.Z(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.k({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.Z({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.Z(graph, graphAttrs)) + ); + + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.Z(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.Z({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.Z(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.Z(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.Z(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.Z(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.Z(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.Z(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.Z(layers, function (layer) { + var orderShift = 0; + forEach/* default */.Z(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.Z(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.Z(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.Z(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 52544: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + k: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(73234); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(79697); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.Z)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(93203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.Z && (1 / (0,_setToArray/* default */.Z)(new _Set/* default */.Z([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.Z(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.Z)(set); + } + isCommon = false; + includes = _cacheHas/* default */.Z; + seen = new _SetCache/* default */.Z; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(836); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.Z)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.Z)(arrays, 1, isArrayLikeObject/* default */.Z, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.Z(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.Z(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.Z(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.Z(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.Z(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.Z(this._nodes); + } + sources() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.Z(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.Z(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.Z(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.Z(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.Z(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.Z(keys/* default */.Z(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.Z(keys/* default */.Z(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.Z(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.Z(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.Z(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.Z(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.Z(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.Z(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.Z(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.Z(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.Z(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.Z(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.Z(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.Z(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.Z(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.Z(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.Z(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.Z(inV); + if (!u) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.Z(outV); + if (!w) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.Z(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 45625: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ k: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.k) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52544); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 63001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(37834); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.Z; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 76579: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 68774: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 74073: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 58694: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 48451: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(76579); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(31899); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keys/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keysIn/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(91050); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(87215); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(95695); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.Z)(source, (0,_getSymbols/* default */.Z)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(12513); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(60532); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.Z : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.Z)(result, (0,_getSymbols/* default */.Z)(object)); + object = (0,_getPrototype/* default */.Z)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.Z)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(63327); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.Z)(object, keysIn/* default */.Z, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(41884); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.Z)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(12701); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.Z)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.Z)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(73658); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(98351); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.Z)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.Z)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.Z)(value)) { + return value; + } + var isArr = (0,isArray/* default */.Z)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.Z)(value, result); + } + } else { + var tag = (0,_getTag/* default */.Z)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.Z)(value)) { + return (0,_cloneBuffer/* default */.Z)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.Z)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.Z); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.Z) + : (isFlat ? keysIn/* default */.Z : keys/* default */.Z); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.Z)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.Z)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 49811: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.Z)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.Z); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 21692: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 10626: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(29169); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.Z ? _Symbol/* default */.Z.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.Z)(value) || (0,isArguments/* default */.Z)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.Z)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 2693: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61395); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 13317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 63327: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58694); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 74765: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.Z : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.Z)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(84073); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(79651); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.Z(object), new _Uint8Array/* default */.Z(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.Z)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.Z); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.Z)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.Z)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(18843); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.Z)(object), + othIsArr = (0,isArray/* default */.Z)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.Z)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.Z)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.Z)(object)) { + if (!(0,isBuffer/* default */.Z)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.Z); + return (objIsArr || (0,isTypedArray/* default */.Z)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.Z); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.Z); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.Z)(value) && !(0,isObjectLike/* default */.Z)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.Z; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.Z)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.Z)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.Z)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.Z)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.Z)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.Z)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.Z)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.Z)(path) ? (0,_baseProperty/* default */.Z)((0,_toKey/* default */.Z)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.Z; + } + if (typeof value == 'object') { + return (0,isArray/* default */.Z)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 21018: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49811); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 54193: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 59548: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 68882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69203); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 22823: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(42454); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.Z)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(50751); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.Z)(value)) { + return value; + } + return (0,_isKey/* default */.Z)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.Z)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 1808: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63327); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(95695); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 95695: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68774); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(60532); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 16174: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29169); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27771); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(56009); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1656); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 99365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72714); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 6545: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 62281: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72714); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 3688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69581); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(79651); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50439); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32957); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 13445: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(68774); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.Z)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayFilter/* default */.Z : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.Z)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 27961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10626); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 70870: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76579); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49811); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(68882); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 17452: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 75487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 72714: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93589); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18533); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 49360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 17179: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87668); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39473); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 43836: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74073); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74765); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21018); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 61666: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(22823); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(56009); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.Z)(object)) { + return object; + } + path = (0,_castPath/* default */.Z)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.Z)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.Z)(objValue) + ? objValue + : ((0,_isIndex/* default */.Z)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.Z)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.Z)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.Z)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.Z)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(81211); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(27227); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.Z)((0,_overRest/* default */.Z)(func, undefined, flatten/* default */.Z), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 74379: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.Z)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.Z)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.Z)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.Z)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 92344: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.Z)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.Z); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 60532: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 94099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.Z)(value)) { + return NAN; + } + if ((0,isObject/* default */.Z)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.Z)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 50751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.Z)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.Z)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.Z)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 66749: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50751); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 34148: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.Z)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.Z)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 36313: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + diagram: () => (/* binding */ diagram) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +// EXTERNAL MODULE: ./node_modules/d3/src/index.js + 197 modules +var src = __webpack_require__(64218); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + 64 modules +var dagre = __webpack_require__(41644); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/stringify.js + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ + +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).slice(1)); +} + +function unsafeStringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); +} + +function stringify(arr, offset = 0) { + const uuid = unsafeStringify(arr, offset); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!validate(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +/* harmony default export */ const esm_node_stringify = ((/* unused pure expression or super */ null && (stringify))); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/regex.js +/* harmony default export */ const regex = (/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/validate.js + + +function validate_validate(uuid) { + return typeof uuid === 'string' && regex.test(uuid); +} + +/* harmony default export */ const esm_node_validate = (validate_validate); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/parse.js + + +function parse(uuid) { + if (!esm_node_validate(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +/* harmony default export */ const esm_node_parse = (parse); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/v35.js + + + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +function v35(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + var _namespace; + + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = esm_node_parse(namespace); + } + + if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return unsafeStringify(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} +// EXTERNAL MODULE: external "crypto" +var external_crypto_ = __webpack_require__(6113); +var external_crypto_default = /*#__PURE__*/__webpack_require__.n(external_crypto_); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/sha1.js + + +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return external_crypto_default().createHash('sha1').update(bytes).digest(); +} + +/* harmony default export */ const esm_node_sha1 = (sha1); +;// CONCATENATED MODULE: ./node_modules/uuid/dist/esm-node/v5.js + + +const v5 = v35('v5', 0x50, esm_node_sha1); +/* harmony default export */ const esm_node_v5 = (v5); +// EXTERNAL MODULE: ./node_modules/dayjs/dayjs.min.js +var dayjs_min = __webpack_require__(27484); +// EXTERNAL MODULE: ./node_modules/@braintree/sanitize-url/dist/index.js +var dist = __webpack_require__(17967); +// EXTERNAL MODULE: ./node_modules/dompurify/dist/purify.es.js +var purify_es = __webpack_require__(20683); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/erDiagram-9d236eb7.js + + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 8, 10, 20, 22, 24, 26, 27, 28], $V1 = [1, 10], $V2 = [1, 11], $V3 = [1, 12], $V4 = [1, 13], $V5 = [1, 14], $V6 = [1, 15], $V7 = [1, 21], $V8 = [1, 22], $V9 = [1, 23], $Va = [1, 24], $Vb = [1, 25], $Vc = [6, 8, 10, 13, 15, 18, 19, 20, 22, 24, 26, 27, 28, 41, 42, 43, 44, 45], $Vd = [1, 34], $Ve = [27, 28, 46, 47], $Vf = [41, 42, 43, 44, 45], $Vg = [17, 34], $Vh = [1, 54], $Vi = [1, 53], $Vj = [17, 34, 36, 38]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "ER_DIAGRAM": 4, "document": 5, "EOF": 6, "line": 7, "SPACE": 8, "statement": 9, "NEWLINE": 10, "entityName": 11, "relSpec": 12, ":": 13, "role": 14, "BLOCK_START": 15, "attributes": 16, "BLOCK_STOP": 17, "SQS": 18, "SQE": 19, "title": 20, "title_value": 21, "acc_title": 22, "acc_title_value": 23, "acc_descr": 24, "acc_descr_value": 25, "acc_descr_multiline_value": 26, "ALPHANUM": 27, "ENTITY_NAME": 28, "attribute": 29, "attributeType": 30, "attributeName": 31, "attributeKeyTypeList": 32, "attributeComment": 33, "ATTRIBUTE_WORD": 34, "attributeKeyType": 35, "COMMA": 36, "ATTRIBUTE_KEY": 37, "COMMENT": 38, "cardinality": 39, "relType": 40, "ZERO_OR_ONE": 41, "ZERO_OR_MORE": 42, "ONE_OR_MORE": 43, "ONLY_ONE": 44, "MD_PARENT": 45, "NON_IDENTIFYING": 46, "IDENTIFYING": 47, "WORD": 48, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "ER_DIAGRAM", 6: "EOF", 8: "SPACE", 10: "NEWLINE", 13: ":", 15: "BLOCK_START", 17: "BLOCK_STOP", 18: "SQS", 19: "SQE", 20: "title", 21: "title_value", 22: "acc_title", 23: "acc_title_value", 24: "acc_descr", 25: "acc_descr_value", 26: "acc_descr_multiline_value", 27: "ALPHANUM", 28: "ENTITY_NAME", 34: "ATTRIBUTE_WORD", 36: "COMMA", 37: "ATTRIBUTE_KEY", 38: "COMMENT", 41: "ZERO_OR_ONE", 42: "ZERO_OR_MORE", 43: "ONE_OR_MORE", 44: "ONLY_ONE", 45: "MD_PARENT", 46: "NON_IDENTIFYING", 47: "IDENTIFYING", 48: "WORD" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [9, 5], [9, 4], [9, 3], [9, 1], [9, 7], [9, 6], [9, 4], [9, 2], [9, 2], [9, 2], [9, 1], [11, 1], [11, 1], [16, 1], [16, 2], [29, 2], [29, 3], [29, 3], [29, 4], [30, 1], [31, 1], [32, 1], [32, 3], [35, 1], [33, 1], [12, 3], [39, 1], [39, 1], [39, 1], [39, 1], [39, 1], [40, 1], [40, 1], [14, 1], [14, 1], [14, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 1: + break; + case 2: + this.$ = []; + break; + case 3: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 4: + case 5: + this.$ = $$[$0]; + break; + case 6: + case 7: + this.$ = []; + break; + case 8: + yy.addEntity($$[$0 - 4]); + yy.addEntity($$[$0 - 2]); + yy.addRelationship($$[$0 - 4], $$[$0], $$[$0 - 2], $$[$0 - 3]); + break; + case 9: + yy.addEntity($$[$0 - 3]); + yy.addAttributes($$[$0 - 3], $$[$0 - 1]); + break; + case 10: + yy.addEntity($$[$0 - 2]); + break; + case 11: + yy.addEntity($$[$0]); + break; + case 12: + yy.addEntity($$[$0 - 6], $$[$0 - 4]); + yy.addAttributes($$[$0 - 6], $$[$0 - 1]); + break; + case 13: + yy.addEntity($$[$0 - 5], $$[$0 - 3]); + break; + case 14: + yy.addEntity($$[$0 - 3], $$[$0 - 1]); + break; + case 15: + case 16: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 17: + case 18: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 19: + case 43: + this.$ = $$[$0]; + break; + case 20: + case 41: + case 42: + this.$ = $$[$0].replace(/"/g, ""); + break; + case 21: + case 29: + this.$ = [$$[$0]]; + break; + case 22: + $$[$0].push($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 23: + this.$ = { attributeType: $$[$0 - 1], attributeName: $$[$0] }; + break; + case 24: + this.$ = { attributeType: $$[$0 - 2], attributeName: $$[$0 - 1], attributeKeyTypeList: $$[$0] }; + break; + case 25: + this.$ = { attributeType: $$[$0 - 2], attributeName: $$[$0 - 1], attributeComment: $$[$0] }; + break; + case 26: + this.$ = { attributeType: $$[$0 - 3], attributeName: $$[$0 - 2], attributeKeyTypeList: $$[$0 - 1], attributeComment: $$[$0] }; + break; + case 27: + case 28: + case 31: + this.$ = $$[$0]; + break; + case 30: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 32: + this.$ = $$[$0].replace(/"/g, ""); + break; + case 33: + this.$ = { cardA: $$[$0], relType: $$[$0 - 1], cardB: $$[$0 - 2] }; + break; + case 34: + this.$ = yy.Cardinality.ZERO_OR_ONE; + break; + case 35: + this.$ = yy.Cardinality.ZERO_OR_MORE; + break; + case 36: + this.$ = yy.Cardinality.ONE_OR_MORE; + break; + case 37: + this.$ = yy.Cardinality.ONLY_ONE; + break; + case 38: + this.$ = yy.Cardinality.MD_PARENT; + break; + case 39: + this.$ = yy.Identification.NON_IDENTIFYING; + break; + case 40: + this.$ = yy.Identification.IDENTIFYING; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: 9, 20: $V1, 22: $V2, 24: $V3, 26: $V4, 27: $V5, 28: $V6 }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 16, 11: 9, 20: $V1, 22: $V2, 24: $V3, 26: $V4, 27: $V5, 28: $V6 }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 11], { 12: 17, 39: 20, 15: [1, 18], 18: [1, 19], 41: $V7, 42: $V8, 43: $V9, 44: $Va, 45: $Vb }), { 21: [1, 26] }, { 23: [1, 27] }, { 25: [1, 28] }, o($V0, [2, 18]), o($Vc, [2, 19]), o($Vc, [2, 20]), o($V0, [2, 4]), { 11: 29, 27: $V5, 28: $V6 }, { 16: 30, 17: [1, 31], 29: 32, 30: 33, 34: $Vd }, { 11: 35, 27: $V5, 28: $V6 }, { 40: 36, 46: [1, 37], 47: [1, 38] }, o($Ve, [2, 34]), o($Ve, [2, 35]), o($Ve, [2, 36]), o($Ve, [2, 37]), o($Ve, [2, 38]), o($V0, [2, 15]), o($V0, [2, 16]), o($V0, [2, 17]), { 13: [1, 39] }, { 17: [1, 40] }, o($V0, [2, 10]), { 16: 41, 17: [2, 21], 29: 32, 30: 33, 34: $Vd }, { 31: 42, 34: [1, 43] }, { 34: [2, 27] }, { 19: [1, 44] }, { 39: 45, 41: $V7, 42: $V8, 43: $V9, 44: $Va, 45: $Vb }, o($Vf, [2, 39]), o($Vf, [2, 40]), { 14: 46, 27: [1, 49], 28: [1, 48], 48: [1, 47] }, o($V0, [2, 9]), { 17: [2, 22] }, o($Vg, [2, 23], { 32: 50, 33: 51, 35: 52, 37: $Vh, 38: $Vi }), o([17, 34, 37, 38], [2, 28]), o($V0, [2, 14], { 15: [1, 55] }), o([27, 28], [2, 33]), o($V0, [2, 8]), o($V0, [2, 41]), o($V0, [2, 42]), o($V0, [2, 43]), o($Vg, [2, 24], { 33: 56, 36: [1, 57], 38: $Vi }), o($Vg, [2, 25]), o($Vj, [2, 29]), o($Vg, [2, 32]), o($Vj, [2, 31]), { 16: 58, 17: [1, 59], 29: 32, 30: 33, 34: $Vd }, o($Vg, [2, 26]), { 35: 60, 37: $Vh }, { 17: [1, 61] }, o($V0, [2, 13]), o($Vj, [2, 30]), o($V0, [2, 12])], + defaultActions: { 34: [2, 27], 41: [2, 22] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 22; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 24; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + return 10; + case 8: + break; + case 9: + return 8; + case 10: + return 28; + case 11: + return 48; + case 12: + return 4; + case 13: + this.begin("block"); + return 15; + case 14: + return 36; + case 15: + break; + case 16: + return 37; + case 17: + return 34; + case 18: + return 34; + case 19: + return 38; + case 20: + break; + case 21: + this.popState(); + return 17; + case 22: + return yy_.yytext[0]; + case 23: + return 18; + case 24: + return 19; + case 25: + return 41; + case 26: + return 43; + case 27: + return 43; + case 28: + return 43; + case 29: + return 41; + case 30: + return 41; + case 31: + return 42; + case 32: + return 42; + case 33: + return 42; + case 34: + return 42; + case 35: + return 42; + case 36: + return 43; + case 37: + return 42; + case 38: + return 43; + case 39: + return 44; + case 40: + return 44; + case 41: + return 44; + case 42: + return 44; + case 43: + return 41; + case 44: + return 42; + case 45: + return 43; + case 46: + return 45; + case 47: + return 46; + case 48: + return 47; + case 49: + return 47; + case 50: + return 46; + case 51: + return 46; + case 52: + return 46; + case 53: + return 27; + case 54: + return yy_.yytext[0]; + case 55: + return 6; + } + }, + rules: [/^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:[\s]+)/i, /^(?:"[^"%\r\n\v\b\\]+")/i, /^(?:"[^"]*")/i, /^(?:erDiagram\b)/i, /^(?:\{)/i, /^(?:,)/i, /^(?:\s+)/i, /^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i, /^(?:(.*?)[~](.*?)*[~])/i, /^(?:[\*A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i, /^(?:"[^"]*")/i, /^(?:[\n]+)/i, /^(?:\})/i, /^(?:.)/i, /^(?:\[)/i, /^(?:\])/i, /^(?:one or zero\b)/i, /^(?:one or more\b)/i, /^(?:one or many\b)/i, /^(?:1\+)/i, /^(?:\|o\b)/i, /^(?:zero or one\b)/i, /^(?:zero or more\b)/i, /^(?:zero or many\b)/i, /^(?:0\+)/i, /^(?:\}o\b)/i, /^(?:many\(0\))/i, /^(?:many\(1\))/i, /^(?:many\b)/i, /^(?:\}\|)/i, /^(?:one\b)/i, /^(?:only one\b)/i, /^(?:1\b)/i, /^(?:\|\|)/i, /^(?:o\|)/i, /^(?:o\{)/i, /^(?:\|\{)/i, /^(?:\s*u\b)/i, /^(?:\.\.)/i, /^(?:--)/i, /^(?:to\b)/i, /^(?:optionally to\b)/i, /^(?:\.-)/i, /^(?:-\.)/i, /^(?:[A-Za-z_][A-Za-z0-9\-_]*)/i, /^(?:.)/i, /^(?:$)/i], + conditions: { "acc_descr_multiline": { "rules": [5, 6], "inclusive": false }, "acc_descr": { "rules": [3], "inclusive": false }, "acc_title": { "rules": [1], "inclusive": false }, "block": { "rules": [14, 15, 16, 17, 18, 19, 20, 21, 22], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 8, 9, 10, 11, 12, 13, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const erParser = parser; +let entities = {}; +let relationships = []; +const Cardinality = { + ZERO_OR_ONE: "ZERO_OR_ONE", + ZERO_OR_MORE: "ZERO_OR_MORE", + ONE_OR_MORE: "ONE_OR_MORE", + ONLY_ONE: "ONLY_ONE", + MD_PARENT: "MD_PARENT" +}; +const Identification = { + NON_IDENTIFYING: "NON_IDENTIFYING", + IDENTIFYING: "IDENTIFYING" +}; +const addEntity = function(name, alias = void 0) { + if (entities[name] === void 0) { + entities[name] = { attributes: [], alias }; + mermaid_8af3addd.l.info("Added new entity :", name); + } else if (entities[name] && !entities[name].alias && alias) { + entities[name].alias = alias; + mermaid_8af3addd.l.info(`Add alias '${alias}' to entity '${name}'`); + } + return entities[name]; +}; +const getEntities = () => entities; +const addAttributes = function(entityName, attribs) { + let entity = addEntity(entityName); + let i; + for (i = attribs.length - 1; i >= 0; i--) { + entity.attributes.push(attribs[i]); + mermaid_8af3addd.l.debug("Added attribute ", attribs[i].attributeName); + } +}; +const addRelationship = function(entA, rolA, entB, rSpec) { + let rel = { + entityA: entA, + roleA: rolA, + entityB: entB, + relSpec: rSpec + }; + relationships.push(rel); + mermaid_8af3addd.l.debug("Added new relationship :", rel); +}; +const getRelationships = () => relationships; +const clear = function() { + entities = {}; + relationships = []; + (0,mermaid_8af3addd.t)(); +}; +const erDb = { + Cardinality, + Identification, + getConfig: () => (0,mermaid_8af3addd.c)().er, + addEntity, + addAttributes, + getEntities, + addRelationship, + getRelationships, + clear, + setAccTitle: mermaid_8af3addd.s, + getAccTitle: mermaid_8af3addd.g, + setAccDescription: mermaid_8af3addd.b, + getAccDescription: mermaid_8af3addd.a, + setDiagramTitle: mermaid_8af3addd.q, + getDiagramTitle: mermaid_8af3addd.r +}; +const ERMarkers = { + ONLY_ONE_START: "ONLY_ONE_START", + ONLY_ONE_END: "ONLY_ONE_END", + ZERO_OR_ONE_START: "ZERO_OR_ONE_START", + ZERO_OR_ONE_END: "ZERO_OR_ONE_END", + ONE_OR_MORE_START: "ONE_OR_MORE_START", + ONE_OR_MORE_END: "ONE_OR_MORE_END", + ZERO_OR_MORE_START: "ZERO_OR_MORE_START", + ZERO_OR_MORE_END: "ZERO_OR_MORE_END", + MD_PARENT_END: "MD_PARENT_END", + MD_PARENT_START: "MD_PARENT_START" +}; +const insertMarkers = function(elem, conf2) { + let marker; + elem.append("defs").append("marker").attr("id", ERMarkers.MD_PARENT_START).attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", ERMarkers.MD_PARENT_END).attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", ERMarkers.ONLY_ONE_START).attr("refX", 0).attr("refY", 9).attr("markerWidth", 18).attr("markerHeight", 18).attr("orient", "auto").append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M9,0 L9,18 M15,0 L15,18"); + elem.append("defs").append("marker").attr("id", ERMarkers.ONLY_ONE_END).attr("refX", 18).attr("refY", 9).attr("markerWidth", 18).attr("markerHeight", 18).attr("orient", "auto").append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M3,0 L3,18 M9,0 L9,18"); + marker = elem.append("defs").append("marker").attr("id", ERMarkers.ZERO_OR_ONE_START).attr("refX", 0).attr("refY", 9).attr("markerWidth", 30).attr("markerHeight", 18).attr("orient", "auto"); + marker.append("circle").attr("stroke", conf2.stroke).attr("fill", "white").attr("cx", 21).attr("cy", 9).attr("r", 6); + marker.append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M9,0 L9,18"); + marker = elem.append("defs").append("marker").attr("id", ERMarkers.ZERO_OR_ONE_END).attr("refX", 30).attr("refY", 9).attr("markerWidth", 30).attr("markerHeight", 18).attr("orient", "auto"); + marker.append("circle").attr("stroke", conf2.stroke).attr("fill", "white").attr("cx", 9).attr("cy", 9).attr("r", 6); + marker.append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M21,0 L21,18"); + elem.append("defs").append("marker").attr("id", ERMarkers.ONE_OR_MORE_START).attr("refX", 18).attr("refY", 18).attr("markerWidth", 45).attr("markerHeight", 36).attr("orient", "auto").append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"); + elem.append("defs").append("marker").attr("id", ERMarkers.ONE_OR_MORE_END).attr("refX", 27).attr("refY", 18).attr("markerWidth", 45).attr("markerHeight", 36).attr("orient", "auto").append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"); + marker = elem.append("defs").append("marker").attr("id", ERMarkers.ZERO_OR_MORE_START).attr("refX", 18).attr("refY", 18).attr("markerWidth", 57).attr("markerHeight", 36).attr("orient", "auto"); + marker.append("circle").attr("stroke", conf2.stroke).attr("fill", "white").attr("cx", 48).attr("cy", 18).attr("r", 6); + marker.append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M0,18 Q18,0 36,18 Q18,36 0,18"); + marker = elem.append("defs").append("marker").attr("id", ERMarkers.ZERO_OR_MORE_END).attr("refX", 39).attr("refY", 18).attr("markerWidth", 57).attr("markerHeight", 36).attr("orient", "auto"); + marker.append("circle").attr("stroke", conf2.stroke).attr("fill", "white").attr("cx", 9).attr("cy", 18).attr("r", 6); + marker.append("path").attr("stroke", conf2.stroke).attr("fill", "none").attr("d", "M21,18 Q39,0 57,18 Q39,36 21,18"); + return; +}; +const erMarkers = { + ERMarkers, + insertMarkers +}; +const BAD_ID_CHARS_REGEXP = /[^\dA-Za-z](\W)*/g; +let conf = {}; +let entityNameIds = /* @__PURE__ */ new Map(); +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + conf[key] = cnf[key]; + } +}; +const drawAttributes = (groupNode, entityTextNode, attributes) => { + const heightPadding = conf.entityPadding / 3; + const widthPadding = conf.entityPadding / 3; + const attrFontSize = conf.fontSize * 0.85; + const labelBBox = entityTextNode.node().getBBox(); + const attributeNodes = []; + let hasKeyType = false; + let hasComment = false; + let maxTypeWidth = 0; + let maxNameWidth = 0; + let maxKeyWidth = 0; + let maxCommentWidth = 0; + let cumulativeHeight = labelBBox.height + heightPadding * 2; + let attrNum = 1; + attributes.forEach((item) => { + if (item.attributeKeyTypeList !== void 0 && item.attributeKeyTypeList.length > 0) { + hasKeyType = true; + } + if (item.attributeComment !== void 0) { + hasComment = true; + } + }); + attributes.forEach((item) => { + const attrPrefix = `${entityTextNode.node().id}-attr-${attrNum}`; + let nodeHeight = 0; + const attributeType = (0,mermaid_8af3addd.v)(item.attributeType); + const typeNode = groupNode.append("text").classed("er entityLabel", true).attr("id", `${attrPrefix}-type`).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "left").style("font-family", (0,mermaid_8af3addd.c)().fontFamily).style("font-size", attrFontSize + "px").text(attributeType); + const nameNode = groupNode.append("text").classed("er entityLabel", true).attr("id", `${attrPrefix}-name`).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "left").style("font-family", (0,mermaid_8af3addd.c)().fontFamily).style("font-size", attrFontSize + "px").text(item.attributeName); + const attributeNode = {}; + attributeNode.tn = typeNode; + attributeNode.nn = nameNode; + const typeBBox = typeNode.node().getBBox(); + const nameBBox = nameNode.node().getBBox(); + maxTypeWidth = Math.max(maxTypeWidth, typeBBox.width); + maxNameWidth = Math.max(maxNameWidth, nameBBox.width); + nodeHeight = Math.max(typeBBox.height, nameBBox.height); + if (hasKeyType) { + const keyTypeNodeText = item.attributeKeyTypeList !== void 0 ? item.attributeKeyTypeList.join(",") : ""; + const keyTypeNode = groupNode.append("text").classed("er entityLabel", true).attr("id", `${attrPrefix}-key`).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "left").style("font-family", (0,mermaid_8af3addd.c)().fontFamily).style("font-size", attrFontSize + "px").text(keyTypeNodeText); + attributeNode.kn = keyTypeNode; + const keyTypeBBox = keyTypeNode.node().getBBox(); + maxKeyWidth = Math.max(maxKeyWidth, keyTypeBBox.width); + nodeHeight = Math.max(nodeHeight, keyTypeBBox.height); + } + if (hasComment) { + const commentNode = groupNode.append("text").classed("er entityLabel", true).attr("id", `${attrPrefix}-comment`).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "left").style("font-family", (0,mermaid_8af3addd.c)().fontFamily).style("font-size", attrFontSize + "px").text(item.attributeComment || ""); + attributeNode.cn = commentNode; + const commentNodeBBox = commentNode.node().getBBox(); + maxCommentWidth = Math.max(maxCommentWidth, commentNodeBBox.width); + nodeHeight = Math.max(nodeHeight, commentNodeBBox.height); + } + attributeNode.height = nodeHeight; + attributeNodes.push(attributeNode); + cumulativeHeight += nodeHeight + heightPadding * 2; + attrNum += 1; + }); + let widthPaddingFactor = 4; + if (hasKeyType) { + widthPaddingFactor += 2; + } + if (hasComment) { + widthPaddingFactor += 2; + } + const maxWidth = maxTypeWidth + maxNameWidth + maxKeyWidth + maxCommentWidth; + const bBox = { + width: Math.max( + conf.minEntityWidth, + Math.max( + labelBBox.width + conf.entityPadding * 2, + maxWidth + widthPadding * widthPaddingFactor + ) + ), + height: attributes.length > 0 ? cumulativeHeight : Math.max(conf.minEntityHeight, labelBBox.height + conf.entityPadding * 2) + }; + if (attributes.length > 0) { + const spareColumnWidth = Math.max( + 0, + (bBox.width - maxWidth - widthPadding * widthPaddingFactor) / (widthPaddingFactor / 2) + ); + entityTextNode.attr( + "transform", + "translate(" + bBox.width / 2 + "," + (heightPadding + labelBBox.height / 2) + ")" + ); + let heightOffset = labelBBox.height + heightPadding * 2; + let attribStyle = "attributeBoxOdd"; + attributeNodes.forEach((attributeNode) => { + const alignY = heightOffset + heightPadding + attributeNode.height / 2; + attributeNode.tn.attr("transform", "translate(" + widthPadding + "," + alignY + ")"); + const typeRect = groupNode.insert("rect", "#" + attributeNode.tn.node().id).classed(`er ${attribStyle}`, true).attr("x", 0).attr("y", heightOffset).attr("width", maxTypeWidth + widthPadding * 2 + spareColumnWidth).attr("height", attributeNode.height + heightPadding * 2); + const nameXOffset = parseFloat(typeRect.attr("x")) + parseFloat(typeRect.attr("width")); + attributeNode.nn.attr( + "transform", + "translate(" + (nameXOffset + widthPadding) + "," + alignY + ")" + ); + const nameRect = groupNode.insert("rect", "#" + attributeNode.nn.node().id).classed(`er ${attribStyle}`, true).attr("x", nameXOffset).attr("y", heightOffset).attr("width", maxNameWidth + widthPadding * 2 + spareColumnWidth).attr("height", attributeNode.height + heightPadding * 2); + let keyTypeAndCommentXOffset = parseFloat(nameRect.attr("x")) + parseFloat(nameRect.attr("width")); + if (hasKeyType) { + attributeNode.kn.attr( + "transform", + "translate(" + (keyTypeAndCommentXOffset + widthPadding) + "," + alignY + ")" + ); + const keyTypeRect = groupNode.insert("rect", "#" + attributeNode.kn.node().id).classed(`er ${attribStyle}`, true).attr("x", keyTypeAndCommentXOffset).attr("y", heightOffset).attr("width", maxKeyWidth + widthPadding * 2 + spareColumnWidth).attr("height", attributeNode.height + heightPadding * 2); + keyTypeAndCommentXOffset = parseFloat(keyTypeRect.attr("x")) + parseFloat(keyTypeRect.attr("width")); + } + if (hasComment) { + attributeNode.cn.attr( + "transform", + "translate(" + (keyTypeAndCommentXOffset + widthPadding) + "," + alignY + ")" + ); + groupNode.insert("rect", "#" + attributeNode.cn.node().id).classed(`er ${attribStyle}`, "true").attr("x", keyTypeAndCommentXOffset).attr("y", heightOffset).attr("width", maxCommentWidth + widthPadding * 2 + spareColumnWidth).attr("height", attributeNode.height + heightPadding * 2); + } + heightOffset += attributeNode.height + heightPadding * 2; + attribStyle = attribStyle === "attributeBoxOdd" ? "attributeBoxEven" : "attributeBoxOdd"; + }); + } else { + bBox.height = Math.max(conf.minEntityHeight, cumulativeHeight); + entityTextNode.attr("transform", "translate(" + bBox.width / 2 + "," + bBox.height / 2 + ")"); + } + return bBox; +}; +const drawEntities = function(svgNode, entities2, graph) { + const keys = Object.keys(entities2); + let firstOne; + keys.forEach(function(entityName) { + const entityId = generateId(entityName, "entity"); + entityNameIds.set(entityName, entityId); + const groupNode = svgNode.append("g").attr("id", entityId); + firstOne = firstOne === void 0 ? entityId : firstOne; + const textId = "text-" + entityId; + const textNode = groupNode.append("text").classed("er entityLabel", true).attr("id", textId).attr("x", 0).attr("y", 0).style("dominant-baseline", "middle").style("text-anchor", "middle").style("font-family", (0,mermaid_8af3addd.c)().fontFamily).style("font-size", conf.fontSize + "px").text(entities2[entityName].alias ?? entityName); + const { width: entityWidth, height: entityHeight } = drawAttributes( + groupNode, + textNode, + entities2[entityName].attributes + ); + const rectNode = groupNode.insert("rect", "#" + textId).classed("er entityBox", true).attr("x", 0).attr("y", 0).attr("width", entityWidth).attr("height", entityHeight); + const rectBBox = rectNode.node().getBBox(); + graph.setNode(entityId, { + width: rectBBox.width, + height: rectBBox.height, + shape: "rect", + id: entityId + }); + }); + return firstOne; +}; +const adjustEntities = function(svgNode, graph) { + graph.nodes().forEach(function(v) { + if (v !== void 0 && graph.node(v) !== void 0) { + svgNode.select("#" + v).attr( + "transform", + "translate(" + (graph.node(v).x - graph.node(v).width / 2) + "," + (graph.node(v).y - graph.node(v).height / 2) + " )" + ); + } + }); +}; +const getEdgeName = function(rel) { + return (rel.entityA + rel.roleA + rel.entityB).replace(/\s/g, ""); +}; +const addRelationships = function(relationships2, g) { + relationships2.forEach(function(r) { + g.setEdge( + entityNameIds.get(r.entityA), + entityNameIds.get(r.entityB), + { relationship: r }, + getEdgeName(r) + ); + }); + return relationships2; +}; +let relCnt = 0; +const drawRelationshipFromLayout = function(svg, rel, g, insert, diagObj) { + relCnt++; + const edge = g.edge( + entityNameIds.get(rel.entityA), + entityNameIds.get(rel.entityB), + getEdgeName(rel) + ); + const lineFunction = (0,src/* line */.jvg)().x(function(d) { + return d.x; + }).y(function(d) { + return d.y; + }).curve(src/* curveBasis */.$0Z); + const svgPath = svg.insert("path", "#" + insert).classed("er relationshipLine", true).attr("d", lineFunction(edge.points)).style("stroke", conf.stroke).style("fill", "none"); + if (rel.relSpec.relType === diagObj.db.Identification.NON_IDENTIFYING) { + svgPath.attr("stroke-dasharray", "8,8"); + } + let url = ""; + if (conf.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + switch (rel.relSpec.cardA) { + case diagObj.db.Cardinality.ZERO_OR_ONE: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.ZERO_OR_ONE_END + ")"); + break; + case diagObj.db.Cardinality.ZERO_OR_MORE: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.ZERO_OR_MORE_END + ")"); + break; + case diagObj.db.Cardinality.ONE_OR_MORE: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.ONE_OR_MORE_END + ")"); + break; + case diagObj.db.Cardinality.ONLY_ONE: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.ONLY_ONE_END + ")"); + break; + case diagObj.db.Cardinality.MD_PARENT: + svgPath.attr("marker-end", "url(" + url + "#" + erMarkers.ERMarkers.MD_PARENT_END + ")"); + break; + } + switch (rel.relSpec.cardB) { + case diagObj.db.Cardinality.ZERO_OR_ONE: + svgPath.attr( + "marker-start", + "url(" + url + "#" + erMarkers.ERMarkers.ZERO_OR_ONE_START + ")" + ); + break; + case diagObj.db.Cardinality.ZERO_OR_MORE: + svgPath.attr( + "marker-start", + "url(" + url + "#" + erMarkers.ERMarkers.ZERO_OR_MORE_START + ")" + ); + break; + case diagObj.db.Cardinality.ONE_OR_MORE: + svgPath.attr( + "marker-start", + "url(" + url + "#" + erMarkers.ERMarkers.ONE_OR_MORE_START + ")" + ); + break; + case diagObj.db.Cardinality.ONLY_ONE: + svgPath.attr("marker-start", "url(" + url + "#" + erMarkers.ERMarkers.ONLY_ONE_START + ")"); + break; + case diagObj.db.Cardinality.MD_PARENT: + svgPath.attr("marker-start", "url(" + url + "#" + erMarkers.ERMarkers.MD_PARENT_START + ")"); + break; + } + const len = svgPath.node().getTotalLength(); + const labelPoint = svgPath.node().getPointAtLength(len * 0.5); + const labelId = "rel" + relCnt; + const labelNode = svg.append("text").classed("er relationshipLabel", true).attr("id", labelId).attr("x", labelPoint.x).attr("y", labelPoint.y).style("text-anchor", "middle").style("dominant-baseline", "middle").style("font-family", (0,mermaid_8af3addd.c)().fontFamily).style("font-size", conf.fontSize + "px").text(rel.roleA); + const labelBBox = labelNode.node().getBBox(); + svg.insert("rect", "#" + labelId).classed("er relationshipLabelBox", true).attr("x", labelPoint.x - labelBBox.width / 2).attr("y", labelPoint.y - labelBBox.height / 2).attr("width", labelBBox.width).attr("height", labelBBox.height); +}; +const draw = function(text, id, _version, diagObj) { + conf = (0,mermaid_8af3addd.c)().er; + mermaid_8af3addd.l.info("Drawing ER diagram"); + const securityLevel = (0,mermaid_8af3addd.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,src/* select */.Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,src/* select */.Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,src/* select */.Ys)("body"); + const svg = root.select(`[id='${id}']`); + erMarkers.insertMarkers(svg, conf); + let g; + g = new graphlib/* Graph */.k({ + multigraph: true, + directed: true, + compound: false + }).setGraph({ + rankdir: conf.layoutDirection, + marginx: 20, + marginy: 20, + nodesep: 100, + edgesep: 100, + ranksep: 100 + }).setDefaultEdgeLabel(function() { + return {}; + }); + const firstEntity = drawEntities(svg, diagObj.db.getEntities(), g); + const relationships2 = addRelationships(diagObj.db.getRelationships(), g); + (0,dagre/* layout */.bK)(g); + adjustEntities(svg, g); + relationships2.forEach(function(rel) { + drawRelationshipFromLayout(svg, rel, g, firstEntity, diagObj); + }); + const padding = conf.diagramPadding; + mermaid_8af3addd.u.insertTitle(svg, "entityTitleText", conf.titleTopMargin, diagObj.db.getDiagramTitle()); + const svgBounds = svg.node().getBBox(); + const width = svgBounds.width + padding * 2; + const height = svgBounds.height + padding * 2; + (0,mermaid_8af3addd.i)(svg, height, width, conf.useMaxWidth); + svg.attr("viewBox", `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`); +}; +const MERMAID_ERDIAGRAM_UUID = "28e9f9db-3c8d-5aa5-9faf-44286ae5937c"; +function generateId(str = "", prefix = "") { + const simplifiedStr = str.replace(BAD_ID_CHARS_REGEXP, ""); + return `${strWithHyphen(prefix)}${strWithHyphen(simplifiedStr)}${esm_node_v5( + str, + MERMAID_ERDIAGRAM_UUID + )}`; +} +function strWithHyphen(str = "") { + return str.length > 0 ? `${str}-` : ""; +} +const erRenderer = { + setConf, + draw +}; +const getStyles = (options) => ` + .entityBox { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + } + + .attributeBoxOdd { + fill: ${options.attributeBackgroundColorOdd}; + stroke: ${options.nodeBorder}; + } + + .attributeBoxEven { + fill: ${options.attributeBackgroundColorEven}; + stroke: ${options.nodeBorder}; + } + + .relationshipLabelBox { + fill: ${options.tertiaryColor}; + opacity: 0.7; + background-color: ${options.tertiaryColor}; + rect { + opacity: 0.5; + } + } + + .relationshipLine { + stroke: ${options.lineColor}; + } + + .entityTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } + #MD_PARENT_START { + fill: #f5f5f5 !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; + } + #MD_PARENT_END { + fill: #f5f5f5 !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; + } + +`; +const erStyles = getStyles; +const diagram = { + parser: erParser, + db: erDb, + renderer: erRenderer, + styles: erStyles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/327fa616.f584e7ce.js b/assets/js/327fa616.f584e7ce.js new file mode 100644 index 000000000..fdd709c18 --- /dev/null +++ b/assets/js/327fa616.f584e7ce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3407],{79748:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>x,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var t=r(85893),a=r(3905);const s={title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",slug:"ladder-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,l={permalink:"/ladder-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-ladder/pull/97",date:"2023-02-26T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 26\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:10.285,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",slug:"ladder-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",permalink:"/blackjack-retrospective"},nextItem:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",permalink:"/racing-car-retrospective"}},o={authorsImageUrls:[]},d=[{value:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30",id:"\uc0ac\ub2e4\ub9ac-\ud0c0\uae30",level:3},{value:"Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95",id:"position-\uae30\uc900\uc73c\ub85c-\uc0ac\ub2e4\ub9ac-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",level:3},{value:"Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95",id:"player\uc5d0\uac8c-ladder\ub97c-\uc804\ub2ec\ud558\uc5ec-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function c(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",del:"del",h3:"h3",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(n.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/java-ladder/pull/97",children:"https://github.com/woowacourse/java-ladder/pull/97"}),(0,t.jsx)(n.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/java-ladder/pull/234",children:"https://github.com/woowacourse/java-ladder/pull/234"})]})}),"\n",(0,t.jsx)(n.h3,{id:"\uc0ac\ub2e4\ub9ac-\ud0c0\uae30",children:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30"}),"\n",(0,t.jsxs)(n.p,{children:["\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc6b0\uac00\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\uc804 \ubbf8\uc158\uacfc \ub2ec\ub9ac TDD\ub85c \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ud544\uc218\uc600\uae30 \ub54c\ubb38\uc5d0 \uc775\uc219\ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, \uc6b0\uac00\uc640 \ubbf8\uc158\uc5d0 \uad00\ud55c \uc18c\ud1b5\uc774 \uc798 \ub418\uc5b4\uc11c \ud070 \ubb38\uc81c \uc5c6\uc774 \ubbf8\uc158\uc744 \ub9c8\ubb34\ub9ac\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:"\uc6b0\uac00\uc640 \uc774\uc57c\uae30\uac00 \uc798 \ud1b5\ud574\uc11c \uadf8\ub7f0\uc9c0 1\ub2e8\uacc4\ub294 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub294\ub370, 2\ub2e8\uacc4\uc5d0\uc11c \ub9ce\uc774 \uace0\uc804\ud55c \uac83 \uac19\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:"2\ub2e8\uacc4\uc5d0\uc11c\ub294 2\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ud574\ubd24\ub2e4."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"LadderGame\uc5d0\uc11c Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsx)(n.li,{children:"Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c Ladder\uc5d0\uac8c Position\uc744 \ub118\uaca8\uc8fc\uba70 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"position-\uae30\uc900\uc73c\ub85c-\uc0ac\ub2e4\ub9ac-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",children:"Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsxs)(n.p,{children:["\uc0ac\uc2e4\uc0c1 index\ub97c Ladder\uc5d0\uac8c \ub118\uaca8\uc8fc\uace0, \ud574\ub2f9 index\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc1b\ub294 \ubc29\ubc95\uacfc \uc720\uc0ac\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uad6c\ud604\ud558\uace0 \ub098\ub2c8 \ub2e4\ub978 \ud074\ub798\uc2a4\ub4e4\uc774 Position\uc5d0 \ub300\ud55c \uc758\uc874\ub3c4\uac00 \ub108\ubb34 \ub192\uc740 \uac83 \uac19\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ud55c Players\uac00 \ubcc4\ub2e4\ub978 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uc9c0 \uc54a\ub2e4\uace0 \ub290\uaf08\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph TD\n\n LadderGameController --\x3e LadderGame\n LadderGame --\x3e Ladder\n LadderGame --\x3e Players\n LadderGame --\x3e Items\n\n Ladder --\x3e Line\n Line --\x3e LineStatus\n\n LadderGame --\x3e Position\n Ladder --\x3e Position\n Items --\x3e Position\n Line --\x3e Position\n Players --\x3e Position\n\n LadderGame --\x3e LadderGameResult\n\n Items --\x3e Item\n Players --\x3e Player\n\n LadderGameController --\x3e InputView\n LadderGameController --\x3e OutputView\n"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"public LadderGameResult play() {\n final Map result = new LinkedHashMap<>();\n // \uc0ac\uc6a9\uc790 \uc218\ub9cc\ud07c Position\uc744 \uac00\uc838\uc640\uc11c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4.\n for (Position position : Position.range(players.count())) {\n final Position resultPosition = ladder.play(position);\n result.put(players.get(position), items.get(resultPosition));\n }\n return new LadderGameResult(result);\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"player\uc5d0\uac8c-ladder\ub97c-\uc804\ub2ec\ud558\uc5ec-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",children:"Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsxs)(n.p,{children:["Position\uc5d0 \ub300\ud55c \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub294 Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c, Player\uac00 Ladder\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \ubc29\ubc95\uc774 \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc704\ud574\uc11c \uac1d\uccb4\ub4e4\uc774 \uae34\ubc00\ud558\uac8c \ud611\ub825\ud558\uace0, \uc870\uae08 \ub354 \ucc45\uc784\uc758 \ubd84\ubc30\uac00 \uc798 \ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\uc774 \ub418\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph TD\n\n LadderGameController --\x3e LadderGame\n LadderGame --\x3e Ladder\n LadderGame --\x3e Players\n LadderGame --\x3e Items\n\n Ladder --\x3e Line\n Line --\x3e LineStatus\n Line --\x3e Position\n\n Players --\x3e Ladder\n Player --\x3e Ladder\n\n Item --\x3e Position\n Player --\x3e Position\n\n\n LadderGame --\x3e LadderGameResult\n\n Items --\x3e Item --\x3e ItemName\n Players --\x3e Player --\x3e PlayerName\n\n LadderGameController --\x3e InputView\n LadderGameController --\x3e OutputView\n\n OutputView --\x3e LadderMessageGenerator"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"public LadderGameResult play() {\n // \ucc38\uac00\uc790\ub4e4\uc5d0\uac8c \uc0ac\ub2e4\ub9ac\ub97c \uc804\ub2ec\ud574\uc11c \uc0ac\ub2e4\ub9ac\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \ud55c\ub2e4.\n final Map playResult = players.play(ladder);\n\n final Map result = new LinkedHashMap<>();\n for (Player player : playResult.keySet()) {\n result.put(player, toItem(playResult.get(player)));\n }\n return new LadderGameResult(result);\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\uc5d0 \uc2dc\uac04\uc744 \ub4e4\uc774\uae30"}),(0,t.jsx)(n.br,{}),"\n","\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc815\ud558\ub294\ub370 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ub4e4\uc5ec\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc0ac\ub2e4\ub9ac \ud0c0\uae30\uc758 \uc2e4\ud589 \uacb0\uacfc\ub97c Item\uc73c\ub85c \uc9d3\ub2e4\ub2c8.. \ubb54\uac00 \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\uc804 \ubbf8\uc158\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c, \uba85\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \ubd80\uc871\ud568\uc744 \ub9ce\uc774 \ub290\uaf08\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\ud398\uc5b4\uc640 \uc870\uae08 \ub354 \uce5c\ud574\uc9c0\uae30"}),(0,t.jsx)(n.br,{}),"\n","\uccab\ub0a0\uc740 \ud398\uc5b4\uc640 \uce5c\ud574\uc9c0\ub294 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \uac00\uc838\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\uac00\ub791 \ud68c\uace0\ud560 \ub54c \ub0b4\uac00 \uc2dc\uc791\ud558\uc790\ub9c8\uc790 \ucee8\ubca4\uc158 \uc815\ud558\uc790\uace0 \ud574\uc11c \ub9ce\uc774 \ub2f9\ud669\uc2a4\ub7ec\uc6e0\ub2e4\uace0 \ud55c\ub2e4. \uc6b0\uac00 \ubbf8\uc548.. \ud83e\udd72"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"README\ub97c \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c"}),(0,t.jsx)(n.br,{}),"\n","\uc774\uc0c1\ud558\uac8c \ucf54\ub529\uc5d0 \uc9d1\uc911\ud558\uba74 README\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\uba74\uc11c \uac19\uc774 \ucee4\ubc0b \ud558\ub294 \uac78 \ud56d\uc0c1 \uae4c\uba39\ub294\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub2e4\uc74c \ubbf8\uc158\uc5d0\ub294 \uc870\uae08 \ub354 \uc2e0\uacbd \uc368\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uc88b\uc740 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud558\uae30"}),(0,t.jsx)(n.br,{}),"\n","\uccab PR\ub54c \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \uc9c8\ubb38\uc744 \ub0a8\uae30\uc9c0 \ubabb\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub9ac\ubdf0\uc5b4\uc640\uc758 \uc2dc\uac04\uc774 \uc18c\uc911\ud55c \uc2dc\uac04\uc774\ub77c\ub294 \uac83\uc744 \uae4c\uba39\uc9c0 \ub9d0\uace0, \ub098\uc758 \uc131\uc7a5\uc5d0 \ub3c4\uc6c0\uc774 \ub420 \uc218 \uc788\ub294 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"PR \ud6c4\uc5d0\ub3c4 \uaf3c\uaf3c\ud558\uac8c \ud655\uc778\ud558\uae30"}),(0,t.jsx)(n.br,{}),"\n","\ubd84\uba85 \uc54c\uace0 \uc788\ub294 \ubd80\ubd84\uc774\uc9c0\ub9cc, \ub193\uce5c \ubd80\ubd84\uc774 \ub9ce\uc740 \uac83 \uac19\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","PR \ud558\uae30 \uc804\uc5d0\ub3c4 \uacc4\uc18d \ud655\uc778\uc744 \ud588\uc9c0\ub9cc, \uc544\ubb34\ub798\ub3c4 IntelliJ\uc5d0\uc11c \ubcf4\ub2c8 \ucf54\ub4dc\uc5d0 \uc775\uc219\ud574\uc838\uc11c \uadf8\ub7f0\uc9c0 \ubcc0\uacbd\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc798 \uc548\ubcf4\uc600\ub2e4.",(0,t.jsx)(n.br,{}),"\n","github pr\uc5d0\uc11c\ub294 \uc804\uccb4 \ubcc0\uacbd\uc0ac\ud56d\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc73c\ub2c8 PR \ud6c4\uc5d0\ub3c4 \uaf2d \ud655\uc778\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uc801\uadf9\uc801\uc73c\ub85c \ub098\uc758 \uc758\uacac\uc744 \ub9d0\ud558\uae30"}),(0,t.jsx)(n.br,{}),"\n","\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ud398\uc5b4\uc758 \uc758\uacac\uc774 \uad1c\ucc2e\ub2e4\uace0 \uc0dd\uac01\ud558\uba74 \uc218\uc6a9 \ud6c4 \uac1c\uc120\uc744 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\uc5c8\ub294\ub370, \uc870\uae08 \ub354 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ud5a5\uc774 \uc788\ub2e4\uba74 \ub098\ub3c4 \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub9d0\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub098\ub3c4 \uc124\ub4dd\ud558\ub294 \ud798\uc744 \uae30\ub974\uace0, \ud398\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc744 \uc54c \uc218 \uc788\uace0, \uacb0\uacfc\ubb3c\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub098\uc624\uc9c0 \uc54a\uc744\uae4c? (\uace0\ubbfc \ub4e4\uc5b4\uc8fc\uc2e0 \ub9ac\ubdf0\uc5b4 \ud130\ud2c0\ud83d\udc22 \uac10\uc0ac\ud569\ub2c8\ub2e4.)"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784"}),(0,t.jsx)(n.br,{}),"\n","Players\uac00 Position\uc744 \uc0dd\uc131\ud558\uace0 Player\uc758 \uc0dd\uc131\uc790\uc5d0 \ub123\uc5b4\uc8fc\uc5c8\ub2e4. \ud558\uc9c0\ub9cc \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ub828\ub41c \ucf54\uba58\ud2b8\uac00 \ub2ec\ub838\ub2e4.\n\uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uc0dd\uac01\ud574 \ubcf4\ub2c8 Position\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uac74 Player\uae30 \ub54c\ubb38\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 Player\uac00 \ub2f4\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:"\uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud55c \ud328\ud134\uc73c\ub85c GRASP\uc758 Creator \ud328\ud134\uc774 \uc788\ub294\ub370 \ub2e4\uc74c\uc758 \uc694\uc18c\ub97c \ucd5c\ub300\ud55c \ub9cc\uc871\ud558\ub294 \ud074\ub798\uc2a4\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"B\uac00 A\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"B\uac00 A\uc758 \ucd08\uae43\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\uc2e4\uc81c\ub85c \uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud574\uc11c \uae4a\uc774 \uc0dd\uac01\ud558\uba74\uc11c \ucf54\ub529\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc2dc\uc57c\uac00 \ub113\uc5b4\uc9c4 \uac83 \uac19\ub2e4."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\ud328\ud0a4\uc9c0 \ubd84\ub9ac \uae30\uc900"}),(0,t.jsx)(n.br,{}),"\n","\ud328\ud0a4\uc9c0 \ubd84\ub9ac\uc5d0 \ub300\ud55c \ub098\ub9cc\uc758 \uae30\uc900\uc774 \uc544\uc9c1 \uba85\ud655\ud558\uc9c0 \uc54a\uc544 \uc9c8\ubb38\uc774 \ub4e4\uc5b4\uc640\ub3c4 \uba85\ud655\ud558\uac8c \ub2f5\ubcc0\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub9c8\uc9c0\ub9c9 \uc81c\ucd9c \uc804\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub97c \ubd84\ub9ac\ud574 \ubd24\ub294\ub370, \uae30\uc900\uc774 \uba85\ud655\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \uc88b\uc9c0 \uc54a\uc740 \uc120\ud0dd\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.\n\ud604\uc7ac \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud06c\uae30\uac00 \uadf8\ub807\uac8c \ud06c\uc9c0 \uc54a\uc73c\ub2c8, domain \ud328\ud0a4\uc9c0\uc5d0\uc11c \uc138\ubd80 \ud328\ud0a4\uc9c0\ub85c \ubd84\ub9ac\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub420 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uc0ac\uc6a9\ud558\ub294 \ucabd\uc5d0\uc11c \uc0dd\uac01\ud558\uae30 & \uc608\uce21\uac00\ub2a5\ud55c \ucf54\ub4dc \uc791\uc131\ud558\uae30"}),(0,t.jsx)(n.br,{}),"\n","Position\uc5d0\uc11c \ub2e4\uc74c \uc704\uce58\ub098 \uc774\uc804 \uc704\uce58\ub97c \ubc18\ud658\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud5c8\uc6a9 \ubc94\uc704(0",(0,t.jsxs)(n.del,{children:["19)\uac00 \ubc97\uc5b4\ub09c\ub2e4\uba74, \uc758\ubbf8 \uc5c6\ub294 \uac12\uc774 \ub4e4\uc5b4\uac04 Position\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\uac74 Position\uc744 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc744 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \ucf54\ub529\uc774\uc5c8\ub294\ub370, \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 0"]}),"19\uc758 \uac12\uc774 \ubcf4\uc7a5\ub418\uc5b4 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uac83\uc774\uae30 \ub54c\ubb38\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c hasNext, hasPrevious\ub77c\ub294 \uc774\uc804 \uac12, \uc774\ud6c4 \uac12\uc774 \ubc94\uc704 \ub0b4\uc5d0 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ucd94\uac00\ud558\uace0, \uae30\uc874\uc758 \uac12\uc744 \uac00\uc838\uc624\ub294 \uba54\uc11c\ub4dc\ub294 \ubc94\uc704\uac00 \ubc97\uc5b4\ub098\uba74 \uc608\uc678\ub97c \ub358\uc9c0\ub294 \ubc29\ud5a5\uc73c\ub85c \ud574\uacb0\ud558\uc600\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsxs)(n.p,{children:["\ubc1d\uc740 \uae30\uc6b4\uc744 \uac00\uc9c0\uace0 \uc788\uace0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \uce5c\ud654\ub825\uc774 \uc88b\uc740 \uac83 \uac19\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ubc88\uc5d0 \ud398\uc5b4 \ud560 \ub54c \ucee8\ub514\uc158 \uad00\ub9ac\ub97c \uc81c\ub300\ub85c \ubabb\ud574\uc11c \ub9ce\uc774 \ubbf8\uc548\ud588\ub2e4. \ub2e4\uc74c\uc5d0\ub294 \ucd5c\uc0c1\uc758 \ucee8\ub514\uc158\uc73c\ub85c \ud398\uc5b4\ub97c \uc900\ube44\ud574 \ubd10\uc57c\uaca0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\ub9ac\uace0 \uc6b0\uac00\ub791 \ud398\uc5b4\ub97c \ud558\uace0 \ub098\uc11c, \ub098\ub3c4 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \ub354 \uc798 \uc9c0\ub0b4\ubd10\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5b4 \uc870\uae08 \ub354 \uc6a9\uae30\ub97c \ub0b4 \uc7a1\ub2f4 \uc911\uc774\ub2e4!"]}),"\n",(0,t.jsxs)(n.p,{children:["\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589\uc774 \uc798 \ub418\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ud55c \ud398\uc5b4 \uc9c4\ud589\uc774 \ub290\ub9b0 \uac83 \uac19\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c \uc548\uc815\uc801\uc73c\ub85c \uc2dc\uac04 \uc548\uc5d0 \ubbf8\uc158\uc744 \uc644\ub8cc\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589 \uc18d\ub3c4\uc5d0 \ub300\ud574 \uc870\uae08 \ub354 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4!"]}),"\n",(0,t.jsxs)(n.p,{children:["\ud56d\uc0c1 \uc9c0\ub098\uac08 \ub54c\ub9c8\ub2e4 \uc6c3\uc5b4\uc8fc\ub294\ub370, \ub098\ub3c4 \uc790\uc8fc \uc6c3\uc5b4\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6c3\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uc0ac\ub78c\uc774 \ubc1d\uc544 \ubcf4\uc5ec\uc11c \ub108\ubb34 \uc88b\uc740 \uac83 \uac19\ub2e4!"]})]})}function x(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>d});var t=r(67294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var o=t.createContext({}),d=function(e){var n=t.useContext(o),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},x=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,s=e.originalType,o=e.parentName,x=l(e,["components","mdxType","originalType","parentName"]),p=d(r),u=a,j=p["".concat(o,".").concat(u)]||p[u]||c[u]||s;return r?t.createElement(j,i(i({ref:n},x),{},{components:r})):t.createElement(j,i({ref:n},x))}));x.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/327fa616.f65bd575.js b/assets/js/327fa616.f65bd575.js deleted file mode 100644 index 3b53b9831..000000000 --- a/assets/js/327fa616.f65bd575.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3407],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>c});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),s=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=s(e.components);return n.createElement(i.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=p(e,["components","mdxType","originalType","parentName"]),u=s(r),c=a,k=u["".concat(i,".").concat(c)]||u[c]||m[c]||l;return r?n.createElement(k,o(o({ref:t},d),{},{components:r})):n.createElement(k,o({ref:t},d))}));function c(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=u;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:a,o[1]=p;for(var s=2;s{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>p,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const l={title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",slug:"ladder-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,p={permalink:"/ladder-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-ladder/pull/97",date:"2023-02-26T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 26\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:10.285,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",slug:"ladder-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",permalink:"/blackjack-retrospective"},nextItem:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",permalink:"/racing-car-retrospective"}},i={authorsImageUrls:[]},s=[{value:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30",id:"\uc0ac\ub2e4\ub9ac-\ud0c0\uae30",level:3},{value:"Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95",id:"position-\uae30\uc900\uc73c\ub85c-\uc0ac\ub2e4\ub9ac-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",level:3},{value:"Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95",id:"player\uc5d0\uac8c-ladder\ub97c-\uc804\ub2ec\ud558\uc5ec-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],d={toc:s};function m(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-ladder/pull/97"},"https://github.com/woowacourse/java-ladder/pull/97"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-ladder/pull/234"},"https://github.com/woowacourse/java-ladder/pull/234")," ")),(0,a.kt)("h3",{id:"\uc0ac\ub2e4\ub9ac-\ud0c0\uae30"},"\uc0ac\ub2e4\ub9ac \ud0c0\uae30"),(0,a.kt)("p",null,"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc6b0\uac00\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804 \ubbf8\uc158\uacfc \ub2ec\ub9ac TDD\ub85c \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ud544\uc218\uc600\uae30 \ub54c\ubb38\uc5d0 \uc775\uc219\ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, \uc6b0\uac00\uc640 \ubbf8\uc158\uc5d0 \uad00\ud55c \uc18c\ud1b5\uc774 \uc798 \ub418\uc5b4\uc11c \ud070 \ubb38\uc81c \uc5c6\uc774 \ubbf8\uc158\uc744 \ub9c8\ubb34\ub9ac\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc6b0\uac00\uc640 \uc774\uc57c\uae30\uac00 \uc798 \ud1b5\ud574\uc11c \uadf8\ub7f0\uc9c0 1\ub2e8\uacc4\ub294 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub294\ub370, 2\ub2e8\uacc4\uc5d0\uc11c \ub9ce\uc774 \uace0\uc804\ud55c \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,"2\ub2e8\uacc4\uc5d0\uc11c\ub294 2\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ud574\ubd24\ub2e4."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"LadderGame\uc5d0\uc11c Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"),(0,a.kt)("li",{parentName:"ol"},"Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c Ladder\uc5d0\uac8c Position\uc744 \ub118\uaca8\uc8fc\uba70 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95")),(0,a.kt)("h3",{id:"position-\uae30\uc900\uc73c\ub85c-\uc0ac\ub2e4\ub9ac-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95"},"Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"),(0,a.kt)("p",null,"\uc0ac\uc2e4\uc0c1 index\ub97c Ladder\uc5d0\uac8c \ub118\uaca8\uc8fc\uace0, \ud574\ub2f9 index\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc1b\ub294 \ubc29\ubc95\uacfc \uc720\uc0ac\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uad6c\ud604\ud558\uace0 \ub098\ub2c8 \ub2e4\ub978 \ud074\ub798\uc2a4\ub4e4\uc774 Position\uc5d0 \ub300\ud55c \uc758\uc874\ub3c4\uac00 \ub108\ubb34 \ub192\uc740 \uac83 \uac19\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c Players\uac00 \ubcc4\ub2e4\ub978 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uc9c0 \uc54a\ub2e4\uace0 \ub290\uaf08\ub2e4. "),(0,a.kt)("mermaid",{value:"graph TD\n\n LadderGameController --\x3e LadderGame\n LadderGame --\x3e Ladder\n LadderGame --\x3e Players\n LadderGame --\x3e Items\n\n Ladder --\x3e Line\n Line --\x3e LineStatus\n\n LadderGame --\x3e Position\n Ladder --\x3e Position\n Items --\x3e Position\n Line --\x3e Position\n Players --\x3e Position\n\n LadderGame --\x3e LadderGameResult\n\n Items --\x3e Item\n Players --\x3e Player\n\n LadderGameController --\x3e InputView\n LadderGameController --\x3e OutputView\n"}),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public LadderGameResult play() {\n final Map result = new LinkedHashMap<>();\n // \uc0ac\uc6a9\uc790 \uc218\ub9cc\ud07c Position\uc744 \uac00\uc838\uc640\uc11c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4.\n for (Position position : Position.range(players.count())) {\n final Position resultPosition = ladder.play(position);\n result.put(players.get(position), items.get(resultPosition));\n }\n return new LadderGameResult(result);\n}\n")),(0,a.kt)("h3",{id:"player\uc5d0\uac8c-ladder\ub97c-\uc804\ub2ec\ud558\uc5ec-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95"},"Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"),(0,a.kt)("p",null,"Position\uc5d0 \ub300\ud55c \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub294 Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c, Player\uac00 Ladder\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ubc29\ubc95\uc774 \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc704\ud574\uc11c \uac1d\uccb4\ub4e4\uc774 \uae34\ubc00\ud558\uac8c \ud611\ub825\ud558\uace0, \uc870\uae08 \ub354 \ucc45\uc784\uc758 \ubd84\ubc30\uac00 \uc798 \ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\uc774 \ub418\uc5c8\ub2e4. "),(0,a.kt)("mermaid",{value:"graph TD\n\n LadderGameController --\x3e LadderGame\n LadderGame --\x3e Ladder\n LadderGame --\x3e Players\n LadderGame --\x3e Items\n\n Ladder --\x3e Line\n Line --\x3e LineStatus\n Line --\x3e Position\n\n Players --\x3e Ladder\n Player --\x3e Ladder\n\n Item --\x3e Position\n Player --\x3e Position\n\n\n LadderGame --\x3e LadderGameResult\n\n Items --\x3e Item --\x3e ItemName\n Players --\x3e Player --\x3e PlayerName\n\n LadderGameController --\x3e InputView\n LadderGameController --\x3e OutputView\n\n OutputView --\x3e LadderMessageGenerator"}),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public LadderGameResult play() {\n // \ucc38\uac00\uc790\ub4e4\uc5d0\uac8c \uc0ac\ub2e4\ub9ac\ub97c \uc804\ub2ec\ud574\uc11c \uc0ac\ub2e4\ub9ac\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \ud55c\ub2e4.\n final Map playResult = players.play(ladder);\n\n final Map result = new LinkedHashMap<>();\n for (Player player : playResult.keySet()) {\n result.put(player, toItem(playResult.get(player)));\n }\n return new LadderGameResult(result);\n}\n")),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\uc5d0 \uc2dc\uac04\uc744 \ub4e4\uc774\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc815\ud558\ub294\ub370 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ub4e4\uc5ec\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\ub2e4\ub9ac \ud0c0\uae30\uc758 \uc2e4\ud589 \uacb0\uacfc\ub97c Item\uc73c\ub85c \uc9d3\ub2e4\ub2c8.. \ubb54\uac00 \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804 \ubbf8\uc158\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c, \uba85\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \ubd80\uc871\ud568\uc744 \ub9ce\uc774 \ub290\uaf08\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud398\uc5b4\uc640 \uc870\uae08 \ub354 \uce5c\ud574\uc9c0\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uccab\ub0a0\uc740 \ud398\uc5b4\uc640 \uce5c\ud574\uc9c0\ub294 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \uac00\uc838\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\uac00\ub791 \ud68c\uace0\ud560 \ub54c \ub0b4\uac00 \uc2dc\uc791\ud558\uc790\ub9c8\uc790 \ucee8\ubca4\uc158 \uc815\ud558\uc790\uace0 \ud574\uc11c \ub9ce\uc774 \ub2f9\ud669\uc2a4\ub7ec\uc6e0\ub2e4\uace0 \ud55c\ub2e4. \uc6b0\uac00 \ubbf8\uc548.. \ud83e\udd72"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"README\ub97c \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc0c1\ud558\uac8c \ucf54\ub529\uc5d0 \uc9d1\uc911\ud558\uba74 README\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\uba74\uc11c \uac19\uc774 \ucee4\ubc0b \ud558\ub294 \uac78 \ud56d\uc0c1 \uae4c\uba39\ub294\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \ubbf8\uc158\uc5d0\ub294 \uc870\uae08 \ub354 \uc2e0\uacbd \uc368\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc88b\uc740 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uccab PR\ub54c \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \uc9c8\ubb38\uc744 \ub0a8\uae30\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ubdf0\uc5b4\uc640\uc758 \uc2dc\uac04\uc774 \uc18c\uc911\ud55c \uc2dc\uac04\uc774\ub77c\ub294 \uac83\uc744 \uae4c\uba39\uc9c0 \ub9d0\uace0, \ub098\uc758 \uc131\uc7a5\uc5d0 \ub3c4\uc6c0\uc774 \ub420 \uc218 \uc788\ub294 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud574\uc57c\uaca0\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"PR \ud6c4\uc5d0\ub3c4 \uaf3c\uaf3c\ud558\uac8c \ud655\uc778\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\ubd84\uba85 \uc54c\uace0 \uc788\ub294 \ubd80\ubd84\uc774\uc9c0\ub9cc, \ub193\uce5c \ubd80\ubd84\uc774 \ub9ce\uc740 \uac83 \uac19\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","PR \ud558\uae30 \uc804\uc5d0\ub3c4 \uacc4\uc18d \ud655\uc778\uc744 \ud588\uc9c0\ub9cc, \uc544\ubb34\ub798\ub3c4 IntelliJ\uc5d0\uc11c \ubcf4\ub2c8 \ucf54\ub4dc\uc5d0 \uc775\uc219\ud574\uc838\uc11c \uadf8\ub7f0\uc9c0 \ubcc0\uacbd\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc798 \uc548\ubcf4\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","github pr\uc5d0\uc11c\ub294 \uc804\uccb4 \ubcc0\uacbd\uc0ac\ud56d\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc73c\ub2c8 PR \ud6c4\uc5d0\ub3c4 \uaf2d \ud655\uc778\ud574\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc801\uadf9\uc801\uc73c\ub85c \ub098\uc758 \uc758\uacac\uc744 \ub9d0\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ud398\uc5b4\uc758 \uc758\uacac\uc774 \uad1c\ucc2e\ub2e4\uace0 \uc0dd\uac01\ud558\uba74 \uc218\uc6a9 \ud6c4 \uac1c\uc120\uc744 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\uc5c8\ub294\ub370, \uc870\uae08 \ub354 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ud5a5\uc774 \uc788\ub2e4\uba74 \ub098\ub3c4 \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub9d0\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 \uc124\ub4dd\ud558\ub294 \ud798\uc744 \uae30\ub974\uace0, \ud398\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc744 \uc54c \uc218 \uc788\uace0, \uacb0\uacfc\ubb3c\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub098\uc624\uc9c0 \uc54a\uc744\uae4c? (\uace0\ubbfc \ub4e4\uc5b4\uc8fc\uc2e0 \ub9ac\ubdf0\uc5b4 \ud130\ud2c0\ud83d\udc22 \uac10\uc0ac\ud569\ub2c8\ub2e4.)"),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784"),(0,a.kt)("br",{parentName:"p"}),"\n","Players\uac00 Position\uc744 \uc0dd\uc131\ud558\uace0 Player\uc758 \uc0dd\uc131\uc790\uc5d0 \ub123\uc5b4\uc8fc\uc5c8\ub2e4. \ud558\uc9c0\ub9cc \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ub828\ub41c \ucf54\uba58\ud2b8\uac00 \ub2ec\ub838\ub2e4.\n\uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uc0dd\uac01\ud574 \ubcf4\ub2c8 Position\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uac74 Player\uae30 \ub54c\ubb38\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 Player\uac00 \ub2f4\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud55c \ud328\ud134\uc73c\ub85c GRASP\uc758 Creator \ud328\ud134\uc774 \uc788\ub294\ub370 \ub2e4\uc74c\uc758 \uc694\uc18c\ub97c \ucd5c\ub300\ud55c \ub9cc\uc871\ud558\ub294 \ud074\ub798\uc2a4\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"B\uac00 A\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"B\uac00 A\uc758 \ucd08\uae43\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4. ")),(0,a.kt)("p",null,"\uc2e4\uc81c\ub85c \uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud574\uc11c \uae4a\uc774 \uc0dd\uac01\ud558\uba74\uc11c \ucf54\ub529\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc2dc\uc57c\uac00 \ub113\uc5b4\uc9c4 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud328\ud0a4\uc9c0 \ubd84\ub9ac \uae30\uc900"),(0,a.kt)("br",{parentName:"p"}),"\n","\ud328\ud0a4\uc9c0 \ubd84\ub9ac\uc5d0 \ub300\ud55c \ub098\ub9cc\uc758 \uae30\uc900\uc774 \uc544\uc9c1 \uba85\ud655\ud558\uc9c0 \uc54a\uc544 \uc9c8\ubb38\uc774 \ub4e4\uc5b4\uc640\ub3c4 \uba85\ud655\ud558\uac8c \ub2f5\ubcc0\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9c8\uc9c0\ub9c9 \uc81c\ucd9c \uc804\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub97c \ubd84\ub9ac\ud574 \ubd24\ub294\ub370, \uae30\uc900\uc774 \uba85\ud655\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \uc88b\uc9c0 \uc54a\uc740 \uc120\ud0dd\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.\n\ud604\uc7ac \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud06c\uae30\uac00 \uadf8\ub807\uac8c \ud06c\uc9c0 \uc54a\uc73c\ub2c8, domain \ud328\ud0a4\uc9c0\uc5d0\uc11c \uc138\ubd80 \ud328\ud0a4\uc9c0\ub85c \ubd84\ub9ac\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub420 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc0ac\uc6a9\ud558\ub294 \ucabd\uc5d0\uc11c \uc0dd\uac01\ud558\uae30 & \uc608\uce21\uac00\ub2a5\ud55c \ucf54\ub4dc \uc791\uc131\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","Position\uc5d0\uc11c \ub2e4\uc74c \uc704\uce58\ub098 \uc774\uc804 \uc704\uce58\ub97c \ubc18\ud658\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud5c8\uc6a9 \ubc94\uc704(0~19)\uac00 \ubc97\uc5b4\ub09c\ub2e4\uba74, \uc758\ubbf8 \uc5c6\ub294 \uac12\uc774 \ub4e4\uc5b4\uac04 Position\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uac74 Position\uc744 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc744 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \ucf54\ub529\uc774\uc5c8\ub294\ub370, \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 0~19\uc758 \uac12\uc774 \ubcf4\uc7a5\ub418\uc5b4 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uac83\uc774\uae30 \ub54c\ubb38\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c hasNext, hasPrevious\ub77c\ub294 \uc774\uc804 \uac12, \uc774\ud6c4 \uac12\uc774 \ubc94\uc704 \ub0b4\uc5d0 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ucd94\uac00\ud558\uace0, \uae30\uc874\uc758 \uac12\uc744 \uac00\uc838\uc624\ub294 \uba54\uc11c\ub4dc\ub294 \ubc94\uc704\uac00 \ubc97\uc5b4\ub098\uba74 \uc608\uc678\ub97c \ub358\uc9c0\ub294 \ubc29\ud5a5\uc73c\ub85c \ud574\uacb0\ud558\uc600\ub2e4. "),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,"\ubc1d\uc740 \uae30\uc6b4\uc744 \uac00\uc9c0\uace0 \uc788\uace0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \uce5c\ud654\ub825\uc774 \uc88b\uc740 \uac83 \uac19\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0 \ud398\uc5b4 \ud560 \ub54c \ucee8\ub514\uc158 \uad00\ub9ac\ub97c \uc81c\ub300\ub85c \ubabb\ud574\uc11c \ub9ce\uc774 \ubbf8\uc548\ud588\ub2e4. \ub2e4\uc74c\uc5d0\ub294 \ucd5c\uc0c1\uc758 \ucee8\ub514\uc158\uc73c\ub85c \ud398\uc5b4\ub97c \uc900\ube44\ud574 \ubd10\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub9ac\uace0 \uc6b0\uac00\ub791 \ud398\uc5b4\ub97c \ud558\uace0 \ub098\uc11c, \ub098\ub3c4 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \ub354 \uc798 \uc9c0\ub0b4\ubd10\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5b4 \uc870\uae08 \ub354 \uc6a9\uae30\ub97c \ub0b4 \uc7a1\ub2f4 \uc911\uc774\ub2e4! "),(0,a.kt)("p",null,"\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589\uc774 \uc798 \ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ud398\uc5b4 \uc9c4\ud589\uc774 \ub290\ub9b0 \uac83 \uac19\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c \uc548\uc815\uc801\uc73c\ub85c \uc2dc\uac04 \uc548\uc5d0 \ubbf8\uc158\uc744 \uc644\ub8cc\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589 \uc18d\ub3c4\uc5d0 \ub300\ud574 \uc870\uae08 \ub354 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4!"),(0,a.kt)("p",null,"\ud56d\uc0c1 \uc9c0\ub098\uac08 \ub54c\ub9c8\ub2e4 \uc6c3\uc5b4\uc8fc\ub294\ub370, \ub098\ub3c4 \uc790\uc8fc \uc6c3\uc5b4\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6c3\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uc0ac\ub78c\uc774 \ubc1d\uc544 \ubcf4\uc5ec\uc11c \ub108\ubb34 \uc88b\uc740 \uac83 \uac19\ub2e4!"))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/33736670.01b3f5e5.js b/assets/js/33736670.729098c7.js similarity index 87% rename from assets/js/33736670.01b3f5e5.js rename to assets/js/33736670.729098c7.js index f1986bc17..2218820a8 100644 --- a/assets/js/33736670.01b3f5e5.js +++ b/assets/js/33736670.729098c7.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2742],{80700:s=>{s.exports=JSON.parse('{"label":"Class","permalink":"/tags/class","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2742],{80700:s=>{s.exports=JSON.parse('{"label":"Class","permalink":"/tags/class","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3506.191c4e89.js b/assets/js/3506.191c4e89.js new file mode 100644 index 000000000..14ac37921 --- /dev/null +++ b/assets/js/3506.191c4e89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3506],{33506:(t,e,n)=>{n.d(e,{diagram:()=>j});var i=n(56363),s=n(64218),r=n(93799),a=(n(27484),n(17967),n(27856),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,11,12,14,16,17,18],n=[1,9],i=[1,10],s=[1,11],r=[1,12],a=[1,13],o=[1,14],l={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 13:i.addTask(r[o-1],r[o]),this.$="task"}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:s,16:r,17:a,18:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:n,12:i,14:s,16:r,17:a,18:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",l=0,c=0,h=r.slice.call(arguments,1),y=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);y.setInput(t,u.yy),u.yy.lexer=y,u.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var d=y.yylloc;r.push(d);var f=y.options&&y.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,x,m,k,_,b,v,$,w,M={};;){if(x=n[n.length-1],this.defaultActions[x]?m=this.defaultActions[x]:(null==g&&(w=void 0,"number"!=typeof(w=i.pop()||y.lex()||1)&&(w instanceof Array&&(w=(i=w).pop()),w=e.symbols_[w]||w),g=w),m=a[x]&&a[x][g]),void 0===m||!m.length||!m[0]){var E="";for(_ in $=[],a[x])this.terminals_[_]&&_>2&&$.push("'"+this.terminals_[_]+"'");E=y.showPosition?"Parse error on line "+(l+1)+":\n"+y.showPosition()+"\nExpecting "+$.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(E,{text:y.match,token:this.terminals_[g]||g,line:y.yylineno,loc:d,expected:$})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+g);switch(m[0]){case 1:n.push(g),s.push(y.yytext),r.push(y.yylloc),n.push(m[1]),g=null,c=y.yyleng,o=y.yytext,l=y.yylineno,d=y.yylloc;break;case 2:if(b=this.productions_[m[1]][1],M.$=s[s.length-b],M._$={first_line:r[r.length-(b||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(b||1)].first_column,last_column:r[r.length-1].last_column},f&&(M._$.range=[r[r.length-(b||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(M,[o,c,l,u.yy,m[1],s,r].concat(h))))return k;b&&(n=n.slice(0,-1*b*2),s=s.slice(0,-1*b),r=r.slice(0,-1*b)),n.push(this.productions_[m[1]][0]),s.push(M.$),r.push(M._$),v=a[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},c={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 18;case 16:return 19;case 17:return":";case 18:return 6;case 19:return"INVALID"}},rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18,19],inclusive:!0}}};function h(){this.yy={}}return l.lexer=c,h.prototype=l,l.Parser=h,new h}());a.parser=a;const o=a;let l="";const c=[],h=[],y=[],u=function(){let t=!0;for(const[e,n]of y.entries())y[e].processed,t=t&&n.processed;return t},p={getConfig:()=>(0,i.c)().journey,clear:function(){c.length=0,h.length=0,l="",y.length=0,(0,i.t)()},setDiagramTitle:i.q,getDiagramTitle:i.r,setAccTitle:i.s,getAccTitle:i.g,setAccDescription:i.b,getAccDescription:i.a,addSection:function(t){l=t,c.push(t)},getSections:function(){return c},getTasks:function(){let t=u();let e=0;for(;!t&&e<100;)t=u(),e++;return h.push(...y),h},addTask:function(t,e){const n=e.substr(1).split(":");let i=0,s=[];1===n.length?(i=Number(n[0]),s=[]):(i=Number(n[0]),s=n[1].split(","));const r=s.map((t=>t.trim())),a={section:l,type:l,people:r,task:t,score:i};y.push(a)},addTaskOrg:function(t){const e={section:l,type:l,description:t,task:t,classes:[]};h.push(e)},getActors:function(){return function(){const t=[];return h.forEach((e=>{e.people&&t.push(...e.people)})),[...new Set(t)].sort()}()}},d=t=>`.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n`,f=function(t,e){return(0,r.d)(t,e)},g=function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n},x=function(t,e){return(0,r.f)(t,e)};let m=-1;const k=function(){function t(t,e,n,s,r,a,o,l){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",l).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,l,c){const{taskFontSize:h,taskFontFamily:y}=l,u=t.split(//gi);for(let p=0;p3?function(t){const i=(0,s.Nb1)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}(r):e.score<3?function(t){const i=(0,s.Nb1)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}(r):r.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}(a,{cx:i,cy:300+30*(5-e.score),score:e.score});const o=(0,r.g)();o.x=e.x,o.y=e.y,o.fill=e.fill,o.width=n.width,o.height=n.height,o.class="task task-type-"+e.num,o.rx=3,o.ry=3,f(a,o);let l=e.x+14;e.people.forEach((t=>{const n=e.actors[t].color,i={cx:l,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};g(a,i),l+=10})),k(n)(e.task,a,o.x,o.y,o.width,o.height,{class:"task"},n,e.colour)},w=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},M={};const E=(0,i.c)().journey,T=E.leftMargin,S={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},updateBounds:function(t,e,n,s){const r=(0,i.c)().journey,a=this;let o=0;var l;this.sequenceItems.forEach((function(i){o++;const c=a.sequenceItems.length-o+1;a.updateVal(i,"starty",e-c*r.boxMargin,Math.min),a.updateVal(i,"stopy",s+c*r.boxMargin,Math.max),a.updateVal(S.data,"startx",t-c*r.boxMargin,Math.min),a.updateVal(S.data,"stopx",n+c*r.boxMargin,Math.max),"activation"!==l&&(a.updateVal(i,"startx",t-c*r.boxMargin,Math.min),a.updateVal(i,"stopx",n+c*r.boxMargin,Math.max),a.updateVal(S.data,"starty",e-c*r.boxMargin,Math.min),a.updateVal(S.data,"stopy",s+c*r.boxMargin,Math.max))}))},insert:function(t,e,n,i){const s=Math.min(t,n),r=Math.max(t,n),a=Math.min(e,i),o=Math.max(e,i);this.updateVal(S.data,"startx",s,Math.min),this.updateVal(S.data,"starty",a,Math.min),this.updateVal(S.data,"stopx",r,Math.max),this.updateVal(S.data,"stopy",o,Math.max),this.updateBounds(s,a,r,o)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},A=E.sectionFills,I=E.sectionColours,P=function(t,e,n){const s=(0,i.c)().journey;let r="";const a=n+(2*s.height+s.diagramMarginY);let o=0,l="#CCC",c="black",h=0;for(const[i,y]of e.entries()){if(r!==y.section){l=A[o%A.length],h=o%A.length,c=I[o%I.length];let n=0;const a=y.section;for(let t=i;t(M[e]&&(t[e]=M[e]),t)),{});y.x=i*s.taskMargin+i*s.width+T,y.y=a,y.width=s.diagramMarginX,y.height=s.diagramMarginY,y.colour=c,y.fill=l,y.num=h,y.actors=n,$(t,y,s),S.insert(y.x,y.y,y.x+y.width+s.taskMargin,450)}},C={setConf:function(t){Object.keys(t).forEach((function(e){E[e]=t[e]}))},draw:function(t,e,n,r){const a=(0,i.c)().journey,o=(0,i.c)().securityLevel;let l;"sandbox"===o&&(l=(0,s.Ys)("#i"+e));const c="sandbox"===o?(0,s.Ys)(l.nodes()[0].contentDocument.body):(0,s.Ys)("body");S.init();const h=c.select("#"+e);w(h);const y=r.db.getTasks(),u=r.db.getDiagramTitle(),p=r.db.getActors();for(const i in M)delete M[i];let d=0;p.forEach((t=>{M[t]={color:a.actorColours[d%a.actorColours.length],position:d},d++})),function(t){const e=(0,i.c)().journey;let n=60;Object.keys(M).forEach((i=>{const s=M[i].color,r={cx:20,cy:n,r:7,fill:s,stroke:"#000",pos:M[i].position};_(t,r);const a={x:40,y:n+7,fill:"#666",text:i,textMargin:5|e.boxTextMargin};v(t,a),n+=20}))}(h),S.insert(0,0,T,50*Object.keys(M).length),P(h,y,0);const f=S.getBounds();u&&h.append("text").text(u).attr("x",T).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const g=f.stopy-f.starty+2*a.diagramMarginY,x=T+f.stopx+2*a.diagramMarginX;(0,i.i)(h,g,x,a.useMaxWidth),h.append("line").attr("x1",T).attr("y1",4*a.height).attr("x2",x-T-4).attr("y2",4*a.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const m=u?70:0;h.attr("viewBox",`${f.startx} -25 ${x} ${g+m}`),h.attr("preserveAspectRatio","xMinYMin meet"),h.attr("height",g+m+25)}},j={parser:o,db:p,renderer:C,styles:d,init:t=>{C.setConf(t.journey),p.clear()}}},93799:(t,e,n)=>{n.d(e,{a:()=>a,b:()=>c,c:()=>l,d:()=>r,e:()=>y,f:()=>o,g:()=>h});var i=n(17967),s=n(56363);const r=(t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),void 0!==e.rx&&n.attr("rx",e.rx),void 0!==e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const i in e.attrs)n.attr(i,e.attrs[i]);return void 0!==e.class&&n.attr("class",e.class),n},a=(t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};r(t,n).lower()},o=(t,e)=>{const n=e.text.replace(s.H," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const r=i.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.text(n),i},l=(t,e,n,s)=>{const r=t.append("image");r.attr("x",e),r.attr("y",n);const a=(0,i.Nm)(s);r.attr("xlink:href",a)},c=(t,e,n,s)=>{const r=t.append("use");r.attr("x",e),r.attr("y",n);const a=(0,i.Nm)(s);r.attr("xlink:href",`#${a}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),y=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/360.c968878c.js b/assets/js/360.c968878c.js new file mode 100644 index 000000000..e93440829 --- /dev/null +++ b/assets/js/360.c968878c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[360],{39354:(e,t,n)=>{n.d(t,{c:()=>l});var r=n(49360),i=n(48451);const a=function(e){return(0,i.Z)(e,4)};var d=n(43836);n(52544);function l(e){var t={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:o(e),edges:s(e)};return r.Z(e.graph())||(t.value=a(e.graph())),t}function o(e){return d.Z(e.nodes(),(function(t){var n=e.node(t),i=e.parent(t),a={v:t};return r.Z(n)||(a.value=n),r.Z(i)||(a.parent=i),a}))}function s(e){return d.Z(e.edges(),(function(t){var n=e.edge(t),i={v:t.v,w:t.w};return r.Z(t.name)||(i.name=t.name),r.Z(n)||(i.value=n),i}))}},90360:(e,t,n)=>{n.d(t,{r:()=>X});var r=n(41644),i=n(39354),a=n(27707),d=n(56363),l=n(45625),o=n(74697),s=n(64218);let c={},h={},g={};const f=(e,t)=>(d.l.trace("In isDecendant",t," ",e," = ",h[t].includes(e)),!!h[t].includes(e)),u=(e,t,n,r)=>{d.l.warn("Copying children of ",e,"root",r,"data",t.node(e),r);const i=t.children(e)||[];e!==r&&i.push(e),d.l.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach((i=>{if(t.children(i).length>0)u(i,t,n,r);else{const a=t.node(i);d.l.info("cp ",i," to ",r," with parent ",e),n.setNode(i,a),r!==t.parent(i)&&(d.l.warn("Setting parent",i,t.parent(i)),n.setParent(i,t.parent(i))),e!==r&&i!==e?(d.l.debug("Setting parent",i,e),n.setParent(i,e)):(d.l.info("In copy ",e,"root",r,"data",t.node(e),r),d.l.debug("Not Setting parent for node=",i,"cluster!==rootId",e!==r,"node!==clusterId",i!==e));const l=t.edges(i);d.l.debug("Copying Edges",l),l.forEach((i=>{d.l.info("Edge",i);const a=t.edge(i.v,i.w,i.name);d.l.info("Edge data",a,r);try{((e,t)=>(d.l.info("Decendants of ",t," is ",h[t]),d.l.info("Edge is ",e),e.v!==t&&e.w!==t&&(h[t]?h[t].includes(e.v)||f(e.v,t)||f(e.w,t)||h[t].includes(e.w):(d.l.debug("Tilt, ",t,",not in decendants"),!1))))(i,r)?(d.l.info("Copying as ",i.v,i.w,a,i.name),n.setEdge(i.v,i.w,a,i.name),d.l.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):d.l.info("Skipping copy of edge ",i.v,"--\x3e",i.w," rootId: ",r," clusterId:",e)}catch(l){d.l.error(l)}}))}d.l.debug("Removing node",i),t.removeNode(i)}))},w=(e,t)=>{const n=t.children(e);let r=[...n];for(const i of n)g[i]=e,r=[...r,...w(i,t)];return r},p=(e,t)=>{d.l.trace("Searching",e);const n=t.children(e);if(d.l.trace("Searching children of id ",e,n),n.length<1)return d.l.trace("This is a valid node",e),e;for(const r of n){const n=p(r,t);if(n)return d.l.trace("Found replacement for",e," => ",n),n}},v=e=>c[e]&&c[e].externalConnections&&c[e]?c[e].id:e,y=(e,t)=>{if(d.l.warn("extractor - ",t,i.c(e),e.children("D")),t>10)return void d.l.error("Bailing out");let n=e.nodes(),r=!1;for(const i of n){const t=e.children(i);r=r||t.length>0}if(r){d.l.debug("Nodes = ",n,t);for(const r of n)if(d.l.debug("Extracting node",r,c,c[r]&&!c[r].externalConnections,!e.parent(r),e.node(r),e.children("D")," Depth ",t),c[r])if(!c[r].externalConnections&&e.children(r)&&e.children(r).length>0){d.l.warn("Cluster without external connections, without a parent and with children",r,t);let n="TB"===e.graph().rankdir?"LR":"TB";c[r]&&c[r].clusterData&&c[r].clusterData.dir&&(n=c[r].clusterData.dir,d.l.warn("Fixing dir",c[r].clusterData.dir,n));const a=new l.k({multigraph:!0,compound:!0}).setGraph({rankdir:n,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));d.l.warn("Old graph before copy",i.c(e)),u(r,e,a,r),e.setNode(r,{clusterNode:!0,id:r,clusterData:c[r].clusterData,labelText:c[r].labelText,graph:a}),d.l.warn("New graph after copy node: (",r,")",i.c(a)),d.l.debug("Old graph after copy",i.c(e))}else d.l.warn("Cluster ** ",r," **not meeting the criteria !externalConnections:",!c[r].externalConnections," no parent: ",!e.parent(r)," children ",e.children(r)&&e.children(r).length>0,e.children("D"),t),d.l.debug(c);else d.l.debug("Not a cluster",r,t);n=e.nodes(),d.l.warn("New list of nodes",n);for(const r of n){const n=e.node(r);d.l.warn(" Now next level",r,n),n.clusterNode&&y(n.graph,t+1)}}else d.l.debug("Done, no node has children",e.nodes())},m=(e,t)=>{if(0===t.length)return[];let n=Object.assign(t);return t.forEach((t=>{const r=e.children(t),i=m(e,r);n=[...n,...i]})),n},x={rect:(e,t)=>{d.l.info("Creating subgraph rect for ",t.id,t);const n=e.insert("g").attr("class","cluster"+(t.class?" "+t.class:"")).attr("id",t.id),r=n.insert("rect",":first-child"),i=(0,d.m)((0,d.c)().flowchart.htmlLabels),l=n.insert("g").attr("class","cluster-label"),c="markdown"===t.labelType?(0,o.a)(l,t.labelText,{style:t.labelStyle,useHtmlLabels:i}):l.node().appendChild((0,a.c)(t.labelText,t.labelStyle,void 0,!0));let h=c.getBBox();if((0,d.m)((0,d.c)().flowchart.htmlLabels)){const e=c.children[0],t=(0,s.Ys)(c);h=e.getBoundingClientRect(),t.attr("width",h.width),t.attr("height",h.height)}const g=0*t.padding,f=g/2,u=t.width<=h.width+g?h.width+g:t.width;t.width<=h.width+g?t.diff=(h.width-t.width)/2-t.padding/2:t.diff=-t.padding/2,d.l.trace("Data ",t,JSON.stringify(t)),r.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-u/2).attr("y",t.y-t.height/2-f).attr("width",u).attr("height",t.height+g),i?l.attr("transform","translate("+(t.x-h.width/2)+", "+(t.y-t.height/2)+")"):l.attr("transform","translate("+t.x+", "+(t.y-t.height/2)+")");const w=r.node().getBBox();return t.width=w.width,t.height=w.height,t.intersect=function(e){return(0,a.i)(t,e)},n},roundedWithTitle:(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=n.insert("g").attr("class","cluster-label"),l=n.append("rect"),o=i.node().appendChild((0,a.c)(t.labelText,t.labelStyle,void 0,!0));let c=o.getBBox();if((0,d.m)((0,d.c)().flowchart.htmlLabels)){const e=o.children[0],t=(0,s.Ys)(o);c=e.getBoundingClientRect(),t.attr("width",c.width),t.attr("height",c.height)}c=o.getBBox();const h=0*t.padding,g=h/2,f=t.width<=c.width+t.padding?c.width+t.padding:t.width;t.width<=c.width+t.padding?t.diff=(c.width+0*t.padding-t.width)/2:t.diff=-t.padding/2,r.attr("class","outer").attr("x",t.x-f/2-g).attr("y",t.y-t.height/2-g).attr("width",f+h).attr("height",t.height+h),l.attr("class","inner").attr("x",t.x-f/2-g).attr("y",t.y-t.height/2-g+c.height-1).attr("width",f+h).attr("height",t.height+h-c.height-3),i.attr("transform","translate("+(t.x-c.width/2)+", "+(t.y-t.height/2-t.padding/3+((0,d.m)((0,d.c)().flowchart.htmlLabels)?5:3))+")");const u=r.node().getBBox();return t.height=u.height,t.intersect=function(e){return(0,a.i)(t,e)},n},noteGroup:(e,t)=>{const n=e.insert("g").attr("class","note-cluster").attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,d=i/2;r.attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-t.width/2-d).attr("y",t.y-t.height/2-d).attr("width",t.width+i).attr("height",t.height+i).attr("fill","none");const l=r.node().getBBox();return t.width=l.width,t.height=l.height,t.intersect=function(e){return(0,a.i)(t,e)},n},divider:(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,d=i/2;r.attr("class","divider").attr("x",t.x-t.width/2-d).attr("y",t.y-t.height/2).attr("width",t.width+i).attr("height",t.height+i);const l=r.node().getBBox();return t.width=l.width,t.height=l.height,t.diff=-t.padding/2,t.intersect=function(e){return(0,a.i)(t,e)},n}};let b={};const N=async(e,t,n,l,o)=>{d.l.info("Graph in recursive render: XXX",i.c(t),o);const s=t.graph().rankdir;d.l.trace("Dir in recursive render - dir:",s);const h=e.insert("g").attr("class","root");t.nodes()?d.l.info("Recursive render XXX",t.nodes()):d.l.info("No nodes found for",t),t.edges().length>0&&d.l.trace("Recursive edges",t.edge(t.edges()[0]));const g=h.insert("g").attr("class","clusters"),f=h.insert("g").attr("class","edgePaths"),u=h.insert("g").attr("class","edgeLabels"),w=h.insert("g").attr("class","nodes");await Promise.all(t.nodes().map((async function(e){const r=t.node(e);if(void 0!==o){const n=JSON.parse(JSON.stringify(o.clusterData));d.l.info("Setting data for cluster XXX (",e,") ",n,o),t.setNode(o.id,n),t.parent(e)||(d.l.trace("Setting parent",e,o.id),t.setParent(e,o.id,n))}if(d.l.info("(Insert) Node XXX"+e+": "+JSON.stringify(t.node(e))),r&&r.clusterNode){d.l.info("Cluster identified",e,r.width,t.node(e));const i=await N(w,r.graph,n,l,t.node(e)),o=i.elem;(0,a.u)(r,o),r.diff=i.diff||0,d.l.info("Node bounds (abc123)",e,r,r.width,r.x,r.y),(0,a.s)(o,r),d.l.warn("Recursive render complete ",o,r)}else t.children(e).length>0?(d.l.info("Cluster - the non recursive path XXX",e,r.id,r,t),d.l.info(p(r.id,t)),c[r.id]={id:p(r.id,t),node:r}):(d.l.info("Node - the non recursive path",e,r.id,r),await(0,a.e)(w,t.node(e),s))}))),t.edges().forEach((function(e){const n=t.edge(e.v,e.w,e.name);d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),d.l.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(t.edge(e))),d.l.info("Fix",c,"ids:",e.v,e.w,"Translateing: ",c[e.v],c[e.w]),(0,a.f)(u,n)})),t.edges().forEach((function(e){d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e))})),d.l.info("#############################################"),d.l.info("### Layout ###"),d.l.info("#############################################"),d.l.info(t),(0,r.bK)(t),d.l.info("Graph after layout:",i.c(t));let v=0;return(e=>m(e,e.children()))(t).forEach((function(e){const n=t.node(e);d.l.info("Position "+e+": "+JSON.stringify(t.node(e))),d.l.info("Position "+e+": ("+n.x,","+n.y,") width: ",n.width," height: ",n.height),n&&n.clusterNode?(0,a.p)(n):t.children(e).length>0?(((e,t)=>{d.l.trace("Inserting cluster");const n=t.shape||"rect";b[t.id]=x[n](e,t)})(g,n),c[n.id].node=n):(0,a.p)(n)})),t.edges().forEach((function(e){const r=t.edge(e);d.l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(r),r);const i=(0,a.g)(f,e,r,c,n,t,l);(0,a.h)(r,i)})),t.nodes().forEach((function(e){const n=t.node(e);d.l.info(e,n.type,n.diff),"group"===n.type&&(v=n.diff)})),{elem:h,diff:v}},X=async(e,t,n,r,l)=>{(0,a.a)(e,n,r,l),(0,a.b)(),(0,a.d)(),b={},h={},g={},c={},d.l.warn("Graph at first:",JSON.stringify(i.c(t))),((e,t)=>{!e||t>10?d.l.debug("Opting out, no graph "):(d.l.debug("Opting in, graph "),e.nodes().forEach((function(t){e.children(t).length>0&&(d.l.warn("Cluster identified",t," Replacement id in edges: ",p(t,e)),h[t]=w(t,e),c[t]={id:p(t,e),clusterData:e.node(t)})})),e.nodes().forEach((function(t){const n=e.children(t),r=e.edges();n.length>0?(d.l.debug("Cluster identified",t,h),r.forEach((e=>{e.v!==t&&e.w!==t&&f(e.v,t)^f(e.w,t)&&(d.l.warn("Edge: ",e," leaves cluster ",t),d.l.warn("Decendants of XXX ",t,": ",h[t]),c[t].externalConnections=!0)}))):d.l.debug("Not a cluster ",t,h)})),e.edges().forEach((function(t){const n=e.edge(t);d.l.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t)),d.l.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(e.edge(t)));let r=t.v,i=t.w;if(d.l.warn("Fix XXX",c,"ids:",t.v,t.w,"Translating: ",c[t.v]," --- ",c[t.w]),c[t.v]&&c[t.w]&&c[t.v]===c[t.w]){d.l.warn("Fixing and trixing link to self - removing XXX",t.v,t.w,t.name),d.l.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=v(t.v),i=v(t.w),e.removeEdge(t.v,t.w,t.name);const a=t.w+"---"+t.v;e.setNode(a,{domId:a,id:a,labelStyle:"",labelText:n.label,padding:0,shape:"labelRect",style:""});const l=structuredClone(n),o=structuredClone(n);l.label="",l.arrowTypeEnd="none",o.label="",l.fromCluster=t.v,o.toCluster=t.v,e.setEdge(r,a,l,t.name+"-cyclic-special"),e.setEdge(a,i,o,t.name+"-cyclic-special")}else(c[t.v]||c[t.w])&&(d.l.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=v(t.v),i=v(t.w),e.removeEdge(t.v,t.w,t.name),r!==t.v&&(n.fromCluster=t.v),i!==t.w&&(n.toCluster=t.w),d.l.warn("Fix Replacing with XXX",r,i,t.name),e.setEdge(r,i,n,t.name))})),d.l.warn("Adjusted Graph",i.c(e)),y(e,0),d.l.trace(c))})(t),d.l.warn("Graph after:",JSON.stringify(i.c(t))),await N(e,t,r,l)}}}]); \ No newline at end of file diff --git a/assets/js/3601.e229da18.js b/assets/js/3601.e229da18.js new file mode 100644 index 000000000..fd32820a6 --- /dev/null +++ b/assets/js/3601.e229da18.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3601],{43601:(t,e,a)=>{a.d(e,{diagram:()=>nt});var r=a(56363),i=a(64218),s=a(93799),n=a(17967),o=(a(27484),a(27856),function(){var t=function(t,e,a,r){for(a=a||{},r=t.length;r--;a[t[r]]=e);return a},e=[1,2],a=[1,3],r=[1,4],i=[2,4],s=[1,9],n=[1,11],o=[1,13],c=[1,14],l=[1,16],h=[1,17],d=[1,18],p=[1,24],g=[1,25],u=[1,26],x=[1,27],y=[1,28],m=[1,29],f=[1,30],b=[1,31],T=[1,32],E=[1,33],w=[1,34],P=[1,35],_=[1,36],L=[1,37],k=[1,38],v=[1,39],I=[1,41],M=[1,42],N=[1,43],A=[1,44],S=[1,45],O=[1,46],D=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],R=[4,5,16,50,52,53],C=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],Y=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],$=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],B=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],V=[68,69,70],F=[1,120],W={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,DOTTED_ARROW:74,SOLID_CROSS:75,DOTTED_CROSS:76,SOLID_POINT:77,DOTTED_POINT:78,TXT:79,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"DOTTED_ARROW",75:"SOLID_CROSS",76:"DOTTED_CROSS",77:"SOLID_POINT",78:"DOTTED_POINT",79:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:function(t,e,a,r,i,s,n){var o=s.length-1;switch(i){case 3:return r.apply(s[o]),s[o];case 4:case 9:case 8:case 13:this.$=[];break;case 5:case 10:s[o-1].push(s[o]),this.$=s[o-1];break;case 6:case 7:case 11:case 12:case 62:this.$=s[o];break;case 15:s[o].type="createParticipant",this.$=s[o];break;case 16:s[o-1].unshift({type:"boxStart",boxData:r.parseBoxData(s[o-2])}),s[o-1].push({type:"boxEnd",boxText:s[o-2]}),this.$=s[o-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(s[o-2]),sequenceIndexStep:Number(s[o-1]),sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(s[o-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:r.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:s[o-1]};break;case 23:this.$={type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:s[o-1]};break;case 29:r.setDiagramTitle(s[o].substring(6)),this.$=s[o].substring(6);break;case 30:r.setDiagramTitle(s[o].substring(7)),this.$=s[o].substring(7);break;case 31:this.$=s[o].trim(),r.setAccTitle(this.$);break;case 32:case 33:this.$=s[o].trim(),r.setAccDescription(this.$);break;case 34:s[o-1].unshift({type:"loopStart",loopText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.LOOP_START}),s[o-1].push({type:"loopEnd",loopText:s[o-2],signalType:r.LINETYPE.LOOP_END}),this.$=s[o-1];break;case 35:s[o-1].unshift({type:"rectStart",color:r.parseMessage(s[o-2]),signalType:r.LINETYPE.RECT_START}),s[o-1].push({type:"rectEnd",color:r.parseMessage(s[o-2]),signalType:r.LINETYPE.RECT_END}),this.$=s[o-1];break;case 36:s[o-1].unshift({type:"optStart",optText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.OPT_START}),s[o-1].push({type:"optEnd",optText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.OPT_END}),this.$=s[o-1];break;case 37:s[o-1].unshift({type:"altStart",altText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.ALT_START}),s[o-1].push({type:"altEnd",signalType:r.LINETYPE.ALT_END}),this.$=s[o-1];break;case 38:s[o-1].unshift({type:"parStart",parText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.PAR_START}),s[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=s[o-1];break;case 39:s[o-1].unshift({type:"parStart",parText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.PAR_OVER_START}),s[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=s[o-1];break;case 40:s[o-1].unshift({type:"criticalStart",criticalText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.CRITICAL_START}),s[o-1].push({type:"criticalEnd",signalType:r.LINETYPE.CRITICAL_END}),this.$=s[o-1];break;case 41:s[o-1].unshift({type:"breakStart",breakText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.BREAK_START}),s[o-1].push({type:"breakEnd",optText:r.parseMessage(s[o-2]),signalType:r.LINETYPE.BREAK_END}),this.$=s[o-1];break;case 43:this.$=s[o-3].concat([{type:"option",optionText:r.parseMessage(s[o-1]),signalType:r.LINETYPE.CRITICAL_OPTION},s[o]]);break;case 45:this.$=s[o-3].concat([{type:"and",parText:r.parseMessage(s[o-1]),signalType:r.LINETYPE.PAR_AND},s[o]]);break;case 47:this.$=s[o-3].concat([{type:"else",altText:r.parseMessage(s[o-1]),signalType:r.LINETYPE.ALT_ELSE},s[o]]);break;case 48:s[o-3].draw="participant",s[o-3].type="addParticipant",s[o-3].description=r.parseMessage(s[o-1]),this.$=s[o-3];break;case 49:s[o-1].draw="participant",s[o-1].type="addParticipant",this.$=s[o-1];break;case 50:s[o-3].draw="actor",s[o-3].type="addParticipant",s[o-3].description=r.parseMessage(s[o-1]),this.$=s[o-3];break;case 51:s[o-1].draw="actor",s[o-1].type="addParticipant",this.$=s[o-1];break;case 52:s[o-1].type="destroyParticipant",this.$=s[o-1];break;case 53:this.$=[s[o-1],{type:"addNote",placement:s[o-2],actor:s[o-1].actor,text:s[o]}];break;case 54:s[o-2]=[].concat(s[o-1],s[o-1]).slice(0,2),s[o-2][0]=s[o-2][0].actor,s[o-2][1]=s[o-2][1].actor,this.$=[s[o-1],{type:"addNote",placement:r.PLACEMENT.OVER,actor:s[o-2].slice(0,2),text:s[o]}];break;case 55:this.$=[s[o-1],{type:"addLinks",actor:s[o-1].actor,text:s[o]}];break;case 56:this.$=[s[o-1],{type:"addALink",actor:s[o-1].actor,text:s[o]}];break;case 57:this.$=[s[o-1],{type:"addProperties",actor:s[o-1].actor,text:s[o]}];break;case 58:this.$=[s[o-1],{type:"addDetails",actor:s[o-1].actor,text:s[o]}];break;case 61:this.$=[s[o-2],s[o]];break;case 63:this.$=r.PLACEMENT.LEFTOF;break;case 64:this.$=r.PLACEMENT.RIGHTOF;break;case 65:this.$=[s[o-4],s[o-1],{type:"addMessage",from:s[o-4].actor,to:s[o-1].actor,signalType:s[o-3],msg:s[o],activate:!0},{type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:s[o-1]}];break;case 66:this.$=[s[o-4],s[o-1],{type:"addMessage",from:s[o-4].actor,to:s[o-1].actor,signalType:s[o-3],msg:s[o]},{type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:s[o-4]}];break;case 67:this.$=[s[o-3],s[o-1],{type:"addMessage",from:s[o-3].actor,to:s[o-1].actor,signalType:s[o-2],msg:s[o]}];break;case 68:this.$={type:"addParticipant",actor:s[o]};break;case 69:this.$=r.LINETYPE.SOLID_OPEN;break;case 70:this.$=r.LINETYPE.DOTTED_OPEN;break;case 71:this.$=r.LINETYPE.SOLID;break;case 72:this.$=r.LINETYPE.DOTTED;break;case 73:this.$=r.LINETYPE.SOLID_CROSS;break;case 74:this.$=r.LINETYPE.DOTTED_CROSS;break;case 75:this.$=r.LINETYPE.SOLID_POINT;break;case 76:this.$=r.LINETYPE.DOTTED_POINT;break;case 77:this.$=r.parseMessage(s[o].trim().substring(1))}},table:[{3:1,4:e,5:a,6:r},{1:[3]},{3:5,4:e,5:a,6:r},{3:6,4:e,5:a,6:r},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:s,5:n,8:8,9:10,12:12,13:o,14:c,17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},t(D,[2,5]),{9:47,12:12,13:o,14:c,17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},t(D,[2,7]),t(D,[2,8]),t(D,[2,14]),{12:48,50:L,52:k,53:v},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:O},{22:55,70:O},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(D,[2,29]),t(D,[2,30]),{32:[1,61]},{34:[1,62]},t(D,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:O},{22:72,70:O},{22:73,70:O},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82]},{55:83,57:[1,84],65:[1,85],66:[1,86]},{22:87,70:O},{22:88,70:O},{22:89,70:O},{22:90,70:O},t([5,51,64,71,72,73,74,75,76,77,78,79],[2,68]),t(D,[2,6]),t(D,[2,15]),t(R,[2,9],{10:91}),t(D,[2,17]),{5:[1,93],19:[1,92]},{5:[1,94]},t(D,[2,21]),{5:[1,95]},{5:[1,96]},t(D,[2,24]),t(D,[2,25]),t(D,[2,26]),t(D,[2,27]),t(D,[2,28]),t(D,[2,31]),t(D,[2,32]),t(C,i,{7:97}),t(C,i,{7:98}),t(C,i,{7:99}),t(Y,i,{40:100,7:101}),t($,i,{42:102,7:103}),t($,i,{7:103,42:104}),t(B,i,{45:105,7:106}),t(C,i,{7:107}),{5:[1,109],51:[1,108]},{5:[1,111],51:[1,110]},{5:[1,112]},{22:115,68:[1,113],69:[1,114],70:O},t(V,[2,69]),t(V,[2,70]),t(V,[2,71]),t(V,[2,72]),t(V,[2,73]),t(V,[2,74]),t(V,[2,75]),t(V,[2,76]),{22:116,70:O},{22:118,58:117,70:O},{70:[2,63]},{70:[2,64]},{56:119,79:F},{56:121,79:F},{56:122,79:F},{56:123,79:F},{4:[1,126],5:[1,128],11:125,12:127,16:[1,124],50:L,52:k,53:v},{5:[1,129]},t(D,[2,19]),t(D,[2,20]),t(D,[2,22]),t(D,[2,23]),{4:s,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,130],17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},{4:s,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,131],17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},{4:s,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,132],17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},{16:[1,133]},{4:s,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,46],17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,49:[1,134],50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},{16:[1,135]},{4:s,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,44],17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,48:[1,136],50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},{16:[1,137]},{16:[1,138]},{4:s,5:n,8:8,9:10,12:12,13:o,14:c,16:[2,42],17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,47:[1,139],50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},{4:s,5:n,8:8,9:10,12:12,13:o,14:c,16:[1,140],17:15,18:l,21:h,22:40,23:d,24:19,25:20,26:21,27:22,28:23,29:p,30:g,31:u,33:x,35:y,36:m,37:f,38:b,39:T,41:E,43:w,44:P,46:_,50:L,52:k,53:v,54:I,59:M,60:N,61:A,62:S,70:O},{15:[1,141]},t(D,[2,49]),{15:[1,142]},t(D,[2,51]),t(D,[2,52]),{22:143,70:O},{22:144,70:O},{56:145,79:F},{56:146,79:F},{56:147,79:F},{64:[1,148],79:[2,62]},{5:[2,55]},{5:[2,77]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(D,[2,16]),t(R,[2,10]),{12:149,50:L,52:k,53:v},t(R,[2,12]),t(R,[2,13]),t(D,[2,18]),t(D,[2,34]),t(D,[2,35]),t(D,[2,36]),t(D,[2,37]),{15:[1,150]},t(D,[2,38]),{15:[1,151]},t(D,[2,39]),t(D,[2,40]),{15:[1,152]},t(D,[2,41]),{5:[1,153]},{5:[1,154]},{56:155,79:F},{56:156,79:F},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:157,70:O},t(R,[2,11]),t(Y,i,{7:101,40:158}),t($,i,{7:103,42:159}),t(B,i,{7:106,45:160}),t(D,[2,48]),t(D,[2,50]),{5:[2,65]},{5:[2,66]},{79:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],85:[2,63],86:[2,64],119:[2,55],120:[2,77],121:[2,56],122:[2,57],123:[2,58],145:[2,67],146:[2,53],147:[2,54],155:[2,65],156:[2,66],157:[2,61],158:[2,47],159:[2,45],160:[2,43]},parseError:function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)},parse:function(t){var e=this,a=[0],r=[],i=[null],s=[],n=this.table,o="",c=0,l=0,h=s.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var u=d.yylloc;s.push(u);var x=d.options&&d.options.ranges;"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,m,f,b,T,E,w,P,_,L={};;){if(m=a[a.length-1],this.defaultActions[m]?f=this.defaultActions[m]:(null==y&&(_=void 0,"number"!=typeof(_=r.pop()||d.lex()||1)&&(_ instanceof Array&&(_=(r=_).pop()),_=e.symbols_[_]||_),y=_),f=n[m]&&n[m][y]),void 0===f||!f.length||!f[0]){var k="";for(T in P=[],n[m])this.terminals_[T]&&T>2&&P.push("'"+this.terminals_[T]+"'");k=d.showPosition?"Parse error on line "+(c+1)+":\n"+d.showPosition()+"\nExpecting "+P.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError(k,{text:d.match,token:this.terminals_[y]||y,line:d.yylineno,loc:u,expected:P})}if(f[0]instanceof Array&&f.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+y);switch(f[0]){case 1:a.push(y),i.push(d.yytext),s.push(d.yylloc),a.push(f[1]),y=null,l=d.yyleng,o=d.yytext,c=d.yylineno,u=d.yylloc;break;case 2:if(E=this.productions_[f[1]][1],L.$=i[i.length-E],L._$={first_line:s[s.length-(E||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(E||1)].first_column,last_column:s[s.length-1].last_column},x&&(L._$.range=[s[s.length-(E||1)].range[0],s[s.length-1].range[1]]),void 0!==(b=this.performAction.apply(L,[o,l,c,p.yy,f[1],i,s].concat(h))))return b;E&&(a=a.slice(0,-1*E*2),i=i.slice(0,-1*E),s=s.slice(0,-1*E)),a.push(this.productions_[f[1]][0]),i.push(L.$),s.push(L._$),w=n[a[a.length-2]][a[a.length-1]],a.push(w);break;case 3:return!0}}return!0}},q={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,a=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===r.length?this.yylloc.first_column:0)+r[r.length-a.length].length-a[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var a,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var s in i)this[s]=i[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,a,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),s=0;se[0].length)){if(e=a,r=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,i[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,a,r){switch(a){case 0:case 51:case 64:return 5;case 1:case 2:case 3:case 4:case 5:break;case 6:return 19;case 7:return this.begin("LINE"),14;case 8:return this.begin("ID"),50;case 9:return this.begin("ID"),52;case 10:return 13;case 11:return this.begin("ID"),53;case 12:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),70;case 13:return this.popState(),this.popState(),this.begin("LINE"),51;case 14:return this.popState(),this.popState(),5;case 15:return this.begin("LINE"),36;case 16:return this.begin("LINE"),37;case 17:return this.begin("LINE"),38;case 18:return this.begin("LINE"),39;case 19:return this.begin("LINE"),49;case 20:return this.begin("LINE"),41;case 21:return this.begin("LINE"),43;case 22:return this.begin("LINE"),48;case 23:return this.begin("LINE"),44;case 24:return this.begin("LINE"),47;case 25:return this.begin("LINE"),46;case 26:return this.popState(),15;case 27:return 16;case 28:return 65;case 29:return 66;case 30:return 59;case 31:return 60;case 32:return 61;case 33:return 62;case 34:return 57;case 35:return 54;case 36:return this.begin("ID"),21;case 37:return this.begin("ID"),23;case 38:return 29;case 39:return 30;case 40:return this.begin("acc_title"),31;case 41:return this.popState(),"acc_title_value";case 42:return this.begin("acc_descr"),33;case 43:return this.popState(),"acc_descr_value";case 44:this.begin("acc_descr_multiline");break;case 45:this.popState();break;case 46:return"acc_descr_multiline_value";case 47:return 6;case 48:return 18;case 49:return 20;case 50:return 64;case 52:return e.yytext=e.yytext.trim(),70;case 53:return 73;case 54:return 74;case 55:return 71;case 56:return 72;case 57:return 75;case 58:return 76;case 59:return 77;case 60:return 78;case 61:return 79;case 62:return 68;case 63:return 69;case 65:return"INVALID"}},rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[45,46],inclusive:!1},acc_descr:{rules:[43],inclusive:!1},acc_title:{rules:[41],inclusive:!1},ID:{rules:[2,3,12],inclusive:!1},ALIAS:{rules:[2,3,13,14],inclusive:!1},LINE:{rules:[2,3,26],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,6,7,8,9,10,11,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,44,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65],inclusive:!0}}};function z(){this.yy={}}return W.lexer=q,z.prototype=W,W.Parser=z,new z}());o.parser=o;const c=o;let l,h,d,p,g,u={},x={},y={},m=[],f=[],b=!1;const T=function(t,e,a,r){let i=d;const s=u[t];if(s){if(d&&s.box&&d!==s.box)throw new Error("A same participant should only be defined in one Box: "+s.name+" can't be in '"+s.box.name+"' and in '"+d.name+"' at the same time.");if(i=s.box?s.box:d,s.box=i,s&&e===s.name&&null==a)return}null!=a&&null!=a.text||(a={text:e,wrap:null,type:r}),null!=r&&null!=a.text||(a={text:e,wrap:null,type:r}),u[t]={box:i,name:e,description:a.text,wrap:void 0===a.wrap&&P()||!!a.wrap,prevActor:l,links:{},properties:{},actorCnt:null,rectData:null,type:r||"participant"},l&&u[l]&&(u[l].nextActor=t),d&&d.actorKeys.push(t),l=t},E=function(t,e,a={text:void 0,wrap:void 0},r,i=!1){if(r===_.ACTIVE_END){if((t=>{let e,a=0;for(e=0;e>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}}return f.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&P()||!!a.wrap,type:r,activate:i}),!0},w=function(t){return u[t]},P=()=>void 0!==h?h:(0,r.c)().sequence.wrap,_={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32},L=function(t,e,a){a.text,void 0===a.wrap&&P()||a.wrap;const r=[].concat(t,t);f.push({from:r[0],to:r[1],message:a.text,wrap:void 0===a.wrap&&P()||!!a.wrap,type:_.NOTE,placement:e})},k=function(t,e){const a=w(t);try{let t=(0,r.d)(e.text,(0,r.c)());t=t.replace(/&/g,"&"),t=t.replace(/=/g,"=");v(a,JSON.parse(t))}catch(i){r.l.error("error while parsing actor link text",i)}};function v(t,e){if(null==t.links)t.links=e;else for(let a in e)t.links[a]=e[a]}const I=function(t,e){const a=w(t);try{let t=(0,r.d)(e.text,(0,r.c)());M(a,JSON.parse(t))}catch(i){r.l.error("error while parsing actor properties text",i)}};function M(t,e){if(null==t.properties)t.properties=e;else for(let a in e)t.properties[a]=e[a]}const N=function(t,e){const a=w(t),i=document.getElementById(e.text);try{const t=i.innerHTML,e=JSON.parse(t);e.properties&&M(a,e.properties),e.links&&v(a,e.links)}catch(s){r.l.error("error while parsing actor details text",s)}},A=function(t){if(Array.isArray(t))t.forEach((function(t){A(t)}));else switch(t.type){case"sequenceIndex":f.push({from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":T(t.actor,t.actor,t.description,t.draw);break;case"createParticipant":if(u[t.actor])throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");p=t.actor,T(t.actor,t.actor,t.description,t.draw),x[t.actor]=f.length;break;case"destroyParticipant":g=t.actor,y[t.actor]=f.length;break;case"activeStart":case"activeEnd":E(t.actor,void 0,void 0,t.signalType);break;case"addNote":L(t.actor,t.placement,t.text);break;case"addLinks":k(t.actor,t.text);break;case"addALink":!function(t,e){const a=w(t);try{const t={};let o=(0,r.d)(e.text,(0,r.c)());var i=o.indexOf("@");o=o.replace(/&/g,"&"),o=o.replace(/=/g,"=");var s=o.slice(0,i-1).trim(),n=o.slice(i+1).trim();t[s]=n,v(a,t)}catch(o){r.l.error("error while parsing actor link text",o)}}(t.actor,t.text);break;case"addProperties":I(t.actor,t.text);break;case"addDetails":N(t.actor,t.text);break;case"addMessage":if(p){if(t.to!==p)throw new Error("The created participant "+p+" does not have an associated creating message after its declaration. Please check the sequence diagram.");p=void 0}else if(g){if(t.to!==g&&t.from!==g)throw new Error("The destroyed participant "+g+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");g=void 0}E(t.from,t.to,t.msg,t.signalType,t.activate);break;case"boxStart":e=t.boxData,m.push({name:e.text,wrap:void 0===e.wrap&&P()||!!e.wrap,fill:e.color,actorKeys:[]}),d=m.slice(-1)[0];break;case"boxEnd":d=void 0;break;case"loopStart":E(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":case"rectEnd":case"optEnd":case"altEnd":case"parEnd":case"criticalEnd":case"breakEnd":E(void 0,void 0,void 0,t.signalType);break;case"rectStart":E(void 0,void 0,t.color,t.signalType);break;case"optStart":E(void 0,void 0,t.optText,t.signalType);break;case"altStart":case"else":E(void 0,void 0,t.altText,t.signalType);break;case"setAccTitle":(0,r.s)(t.text);break;case"parStart":case"and":E(void 0,void 0,t.parText,t.signalType);break;case"criticalStart":E(void 0,void 0,t.criticalText,t.signalType);break;case"option":E(void 0,void 0,t.optionText,t.signalType);break;case"breakStart":E(void 0,void 0,t.breakText,t.signalType)}var e},S={addActor:T,addMessage:function(t,e,a,r){f.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&P()||!!a.wrap,answer:r})},addSignal:E,addLinks:k,addDetails:N,addProperties:I,autoWrap:P,setWrap:function(t){h=t},enableSequenceNumbers:function(){b=!0},disableSequenceNumbers:function(){b=!1},showSequenceNumbers:()=>b,getMessages:function(){return f},getActors:function(){return u},getCreatedActors:function(){return x},getDestroyedActors:function(){return y},getActor:w,getActorKeys:function(){return Object.keys(u)},getActorProperty:function(t,e){if(void 0!==t&&void 0!==t.properties)return t.properties[e]},getAccTitle:r.g,getBoxes:function(){return m},getDiagramTitle:r.r,setDiagramTitle:r.q,getConfig:()=>(0,r.c)().sequence,clear:function(){u={},x={},y={},m=[],f=[],b=!1,(0,r.t)()},parseMessage:function(t){const e=t.trim(),a={text:e.replace(/^:?(?:no)?wrap:/,"").trim(),wrap:null!==e.match(/^:?wrap:/)||null===e.match(/^:?nowrap:/)&&void 0};return r.l.debug("parseMessage:",a),a},parseBoxData:function(t){const e=t.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);let a=null!=e&&e[1]?e[1].trim():"transparent",i=null!=e&&e[2]?e[2].trim():void 0;if(window&&window.CSS)window.CSS.supports("color",a)||(a="transparent",i=t.trim());else{const e=(new Option).style;e.color=a,e.color!==a&&(a="transparent",i=t.trim())}return{color:a,text:void 0!==i?(0,r.d)(i.replace(/^:?(?:no)?wrap:/,""),(0,r.c)()):void 0,wrap:void 0!==i?null!==i.match(/^:?wrap:/)||null===i.match(/^:?nowrap:/)&&void 0:void 0}},LINETYPE:_,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:L,setAccTitle:r.s,apply:A,setAccDescription:r.b,getAccDescription:r.a,hasAtLeastOneBox:function(){return m.length>0},hasAtLeastOneBoxWithTitle:function(){return m.some((t=>t.name))}},O=t=>`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n`,D=function(t,e){return(0,s.d)(t,e)},R=(t,e)=>{(0,r.F)((()=>{const a=document.querySelectorAll(t);0!==a.length&&(a[0].addEventListener("mouseover",(function(){C("actor"+e+"_popup")})),a[0].addEventListener("mouseout",(function(){Y("actor"+e+"_popup")})))}))},C=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="block")},Y=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="none")},$=function(t,e){let a=0,i=0;const s=e.text.split(r.e.lineBreakRegex),[n,o]=(0,r.C)(e.fontSize);let c=[],l=0,h=()=>e.y;if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":h=()=>Math.round(e.y+e.textMargin);break;case"middle":case"center":h=()=>Math.round(e.y+(a+i+e.textMargin)/2);break;case"bottom":case"end":h=()=>Math.round(e.y+(a+i+2*e.textMargin)-e.textMargin)}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[d,p]of s.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==n&&(l=d*n);const s=t.append("text");s.attr("x",e.x),s.attr("y",h()),void 0!==e.anchor&&s.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&s.style("font-family",e.fontFamily),void 0!==o&&s.style("font-size",o),void 0!==e.fontWeight&&s.style("font-weight",e.fontWeight),void 0!==e.fill&&s.attr("fill",e.fill),void 0!==e.class&&s.attr("class",e.class),void 0!==e.dy?s.attr("dy",e.dy):0!==l&&s.attr("dy",l);const g=p||r.Z;if(e.tspan){const t=s.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(g)}else s.text(g);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(i+=(s._groups||s)[0][0].getBBox().height,a=i),c.push(s)}return c},B=function(t,e){const a=t.append("polygon");var r,i,s,n,o;return a.attr("points",(r=e.x,i=e.y,s=e.width,n=e.height,r+","+i+" "+(r+s)+","+i+" "+(r+s)+","+(i+n-(o=7))+" "+(r+s-1.2*o)+","+(i+n)+" "+r+","+(i+n))),a.attr("class","labelBox"),e.y=e.y+e.height/2,$(t,e),a};let V=-1;const F=(t,e,a,r)=>{t.select&&a.forEach((a=>{const i=e[a],s=t.select("#actor"+i.actorCnt);!r.mirrorActors&&i.stopy?s.attr("y2",i.stopy+i.height/2):r.mirrorActors&&s.attr("y2",i.stopy)}))},W=function(t,e){(0,s.a)(t,e)},q=function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},z=function(){function t(t,e,a,r,s,n,o){i(e.append("text").attr("x",a+s/2).attr("y",r+n/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,a,s,n,o,c,l){const{actorFontSize:h,actorFontFamily:d,actorFontWeight:p}=l,[g,u]=(0,r.C)(h),x=t.split(r.e.lineBreakRegex);for(let r=0;ra?c.width:a;const g=h.append("rect");if(g.attr("class","actorPopupMenuPanel"+d),g.attr("x",c.x),g.attr("y",c.height),g.attr("fill",c.fill),g.attr("stroke",c.stroke),g.attr("width",p),g.attr("height",c.height),g.attr("rx",c.rx),g.attr("ry",c.ry),null!=s){var u=20;for(let t in s){var x=h.append("a"),y=(0,n.Nm)(s[t]);x.attr("xlink:href",y),x.attr("target","_blank"),H(r)(t,x,c.x+10,c.height+u,p,20,{class:"actor"},r),u+=30}}return g.attr("height",u),{height:c.height+u,width:p}},anchorElement:function(t){return t.append("g")},drawActivation:function(t,e,a,r,i){const n=(0,s.g)(),o=e.anchored;n.x=e.startx,n.y=e.starty,n.class="activation"+i%3,n.width=e.stopx-e.startx,n.height=a-e.starty,D(o,n)},drawLoop:function(t,e,a,r){const{boxMargin:i,boxTextMargin:n,labelBoxHeight:o,labelBoxWidth:c,messageFontFamily:l,messageFontSize:h,messageFontWeight:d}=r,p=t.append("g"),g=function(t,e,a,r){return p.append("line").attr("x1",t).attr("y1",e).attr("x2",a).attr("y2",r).attr("class","loopLine")};g(e.startx,e.starty,e.stopx,e.starty),g(e.stopx,e.starty,e.stopx,e.stopy),g(e.startx,e.stopy,e.stopx,e.stopy),g(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach((function(t){g(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")}));let u=(0,s.e)();u.text=a,u.x=e.startx,u.y=e.starty,u.fontFamily=l,u.fontSize=h,u.fontWeight=d,u.anchor="middle",u.valign="middle",u.tspan=!1,u.width=c||50,u.height=o||20,u.textMargin=n,u.class="labelText",B(p,u),u=q(),u.text=e.title,u.x=e.startx+c/2+(e.stopx-e.startx)/2,u.y=e.starty+i+n,u.anchor="middle",u.valign="middle",u.textMargin=n,u.class="loopText",u.fontFamily=l,u.fontSize=h,u.fontWeight=d,u.wrap=!0;let x=$(p,u);return void 0!==e.sectionTitles&&e.sectionTitles.forEach((function(t,a){if(t.message){u.text=t.message,u.x=e.startx+(e.stopx-e.startx)/2,u.y=e.sections[a].y+i+n,u.class="loopText",u.anchor="middle",u.valign="middle",u.tspan=!1,u.fontFamily=l,u.fontSize=h,u.fontWeight=d,u.wrap=e.wrap,x=$(p,u);let r=Math.round(x.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));e.sections[a].height+=r-(i+n)}})),e.height=Math.round(e.stopy-e.starty),p},drawBackgroundRect:W,insertArrowHead:function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",7.9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},insertArrowFilledHead:function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",15.5).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},insertSequenceNumber:function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},insertArrowCrossHead:function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",4.5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},insertDatabaseIcon:function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},insertComputerIcon:function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},insertClockIcon:function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},getTextObj:q,getNoteRect:function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},popupMenu:function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = 'block'; }"},popdownMenu:function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = 'none'; }"},fixLifeLineHeights:F,sanitizeUrl:n.Nm};let j={};const K={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((t=>t.height||0)))+(0===this.loops.length?0:this.loops.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.messages.length?0:this.messages.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.notes.length?0:this.notes.map((t=>t.height||0)).reduce(((t,e)=>t+e)))},clear:function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},addBox:function(t){this.boxes.push(t)},addActor:function(t){this.actors.push(t)},addLoop:function(t){this.loops.push(t)},addMessage:function(t){this.messages.push(t)},addNote:function(t){this.notes.push(t)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],boxes:[],loops:[],messages:[],notes:[]},init:function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,tt((0,r.c)())},updateVal:function(t,e,a,r){void 0===t[e]?t[e]=a:t[e]=r(a,t[e])},updateBounds:function(t,e,a,r){const i=this;let s=0;function n(n){return function(o){s++;const c=i.sequenceItems.length-s+1;i.updateVal(o,"starty",e-c*j.boxMargin,Math.min),i.updateVal(o,"stopy",r+c*j.boxMargin,Math.max),i.updateVal(K.data,"startx",t-c*j.boxMargin,Math.min),i.updateVal(K.data,"stopx",a+c*j.boxMargin,Math.max),"activation"!==n&&(i.updateVal(o,"startx",t-c*j.boxMargin,Math.min),i.updateVal(o,"stopx",a+c*j.boxMargin,Math.max),i.updateVal(K.data,"starty",e-c*j.boxMargin,Math.min),i.updateVal(K.data,"stopy",r+c*j.boxMargin,Math.max))}}this.sequenceItems.forEach(n()),this.activations.forEach(n("activation"))},insert:function(t,e,a,i){const s=r.e.getMin(t,a),n=r.e.getMax(t,a),o=r.e.getMin(e,i),c=r.e.getMax(e,i);this.updateVal(K.data,"startx",s,Math.min),this.updateVal(K.data,"starty",o,Math.min),this.updateVal(K.data,"stopx",n,Math.max),this.updateVal(K.data,"stopy",c,Math.max),this.updateBounds(s,o,n,c)},newActivation:function(t,e,a){const r=a[t.from.actor],i=et(t.from.actor).length||0,s=r.x+r.width/2+(i-1)*j.activationWidth/2;this.activations.push({startx:s,starty:this.verticalPos+2,stopx:s+j.activationWidth,stopy:void 0,actor:t.from.actor,anchored:U.anchorElement(e)})},endActivation:function(t){const e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from.actor);return this.activations.splice(e,1)[0]},createLoop:function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},newLoop:function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},endLoop:function(){return this.sequenceItems.pop()},isLoopOverlap:function(){return!!this.sequenceItems.length&&this.sequenceItems[this.sequenceItems.length-1].overlap},addSectionToLoop:function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:K.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},saveVerticalPos:function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},resetVerticalPos:function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=r.e.getMax(this.data.stopy,this.verticalPos)},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},X=t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),G=t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),J=t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight});const Z=function(t,e,a,i){if(i){let i=0;K.bumpVerticalPos(2*j.boxMargin);for(const s of a){const a=e[s];a.stopy||(a.stopy=K.getVerticalPos());const n=U.drawActor(t,a,j,!0);i=r.e.getMax(i,n)}K.bumpVerticalPos(i+j.boxMargin)}else for(const r of a){const a=e[r];U.drawActor(t,a,j,!1)}},Q=function(t,e,a,r){let i=0,s=0;for(const n of a){const a=e[n],o=it(a),c=U.drawPopup(t,a,o,j,j.forceMenus,r);c.height>i&&(i=c.height),c.width+a.x>s&&(s=c.width+a.x)}return{maxHeight:i,maxWidth:s}},tt=function(t){(0,r.f)(j,t),t.fontFamily&&(j.actorFontFamily=j.noteFontFamily=j.messageFontFamily=t.fontFamily),t.fontSize&&(j.actorFontSize=j.noteFontSize=j.messageFontSize=t.fontSize),t.fontWeight&&(j.actorFontWeight=j.noteFontWeight=j.messageFontWeight=t.fontWeight)},et=function(t){return K.activations.filter((function(e){return e.actor===t}))},at=function(t,e){const a=e[t],i=et(t);return[i.reduce((function(t,e){return r.e.getMin(t,e.startx)}),a.x+a.width/2-1),i.reduce((function(t,e){return r.e.getMax(t,e.stopx)}),a.x+a.width/2+1)]};function rt(t,e,a,i,s){K.bumpVerticalPos(a);let n=i;if(e.id&&e.message&&t[e.id]){const a=t[e.id].width,s=X(j);e.message=r.u.wrapLabel(`[${e.message}]`,a-2*j.wrapPadding,s),e.width=a,e.wrap=!0;const o=r.u.calculateTextDimensions(e.message,s),c=r.e.getMax(o.height,j.labelBoxHeight);n=i+c,r.l.debug(`${c} - ${e.message}`)}s(e),K.bumpVerticalPos(n)}const it=function(t){let e=0;const a=J(j);for(const i in t.links){const t=r.u.calculateTextDimensions(i,a).width+2*j.wrapPadding+2*j.boxMargin;et.actor)).lastIndexOf(t.from.actor);delete K.activations.splice(e,1)[0]}}void 0!==t.placement?(c=function(t,e,a){const i=e[t.from].x,s=e[t.to].x,n=t.wrap&&t.message;let o=r.u.calculateTextDimensions(n?r.u.wrapLabel(t.message,j.width,G(j)):t.message,G(j));const c={width:n?j.width:r.e.getMax(j.width,o.width+2*j.noteMargin),height:0,startx:e[t.from].x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===a.db.PLACEMENT.RIGHTOF?(c.width=n?r.e.getMax(j.width,o.width):r.e.getMax(e[t.from].width/2+e[t.to].width/2,o.width+2*j.noteMargin),c.startx=i+(e[t.from].width+j.actorMargin)/2):t.placement===a.db.PLACEMENT.LEFTOF?(c.width=n?r.e.getMax(j.width,o.width+2*j.noteMargin):r.e.getMax(e[t.from].width/2+e[t.to].width/2,o.width+2*j.noteMargin),c.startx=i-c.width+(e[t.from].width-j.actorMargin)/2):t.to===t.from?(o=r.u.calculateTextDimensions(n?r.u.wrapLabel(t.message,r.e.getMax(j.width,e[t.from].width),G(j)):t.message,G(j)),c.width=n?r.e.getMax(j.width,e[t.from].width):r.e.getMax(e[t.from].width,j.width,o.width+2*j.noteMargin),c.startx=i+(e[t.from].width-c.width)/2):(c.width=Math.abs(i+e[t.from].width/2-(s+e[t.to].width/2))+j.actorMargin,c.startx=i{o=t,o.from=r.e.getMin(o.from,c.startx),o.to=r.e.getMax(o.to,c.startx+c.width),o.width=r.e.getMax(o.width,Math.abs(o.from-o.to))-j.labelBoxWidth}))):(l=function(t,e,a){if(![a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN,a.db.LINETYPE.SOLID,a.db.LINETYPE.DOTTED,a.db.LINETYPE.SOLID_CROSS,a.db.LINETYPE.DOTTED_CROSS,a.db.LINETYPE.SOLID_POINT,a.db.LINETYPE.DOTTED_POINT].includes(t.type))return{};const[i,s]=at(t.from,e),[n,o]=at(t.to,e),c=i<=n,l=c?s:i;let h=c?n:o;const d=Math.abs(n-o)>2,p=t=>c?-t:t;t.from===t.to?h=l:(t.activate&&!d&&(h+=p(j.activationWidth/2-1)),[a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN].includes(t.type)||(h+=p(3)));const g=[i,s,n,o],u=Math.abs(l-h);t.wrap&&t.message&&(t.message=r.u.wrapLabel(t.message,r.e.getMax(u+2*j.wrapPadding,j.width),X(j)));const x=r.u.calculateTextDimensions(t.message,X(j));return{width:r.e.getMax(t.wrap?0:x.width+2*j.wrapPadding,u+2*j.wrapPadding,j.width),height:0,startx:l,stopx:h,starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,g),toBounds:Math.max.apply(null,g)}}(t,e,i),t.msgModel=l,l.startx&&l.stopx&&n.length>0&&n.forEach((a=>{if(o=a,l.startx===l.stopx){const a=e[t.from],i=e[t.to];o.from=r.e.getMin(a.x-l.width/2,a.x-a.width/2,o.from),o.to=r.e.getMax(i.x+l.width/2,i.x+a.width/2,o.to),o.width=r.e.getMax(o.width,Math.abs(o.to-o.from))-j.labelBoxWidth}else o.from=r.e.getMin(l.startx,o.from),o.to=r.e.getMax(l.stopx,o.to),o.width=r.e.getMax(o.width,l.width)-j.labelBoxWidth})))})),K.activations=[],r.l.debug("Loop type widths:",s),s},nt={parser:c,db:S,renderer:{bounds:K,drawActors:Z,drawActorsPopup:Q,setConf:tt,draw:function(t,e,a,n){const{securityLevel:o,sequence:c}=(0,r.c)();let l;j=c,"sandbox"===o&&(l=(0,i.Ys)("#i"+e));const h="sandbox"===o?(0,i.Ys)(l.nodes()[0].contentDocument.body):(0,i.Ys)("body"),d="sandbox"===o?l.nodes()[0].contentDocument:document;K.init(),r.l.debug(n.db);const p="sandbox"===o?h.select(`[id="${e}"]`):(0,i.Ys)(`[id="${e}"]`),g=n.db.getActors(),u=n.db.getCreatedActors(),x=n.db.getDestroyedActors(),y=n.db.getBoxes();let m=n.db.getActorKeys();const f=n.db.getMessages(),b=n.db.getDiagramTitle(),T=n.db.hasAtLeastOneBox(),E=n.db.hasAtLeastOneBoxWithTitle(),w=function(t,e,a){const i={};return e.forEach((function(e){if(t[e.to]&&t[e.from]){const s=t[e.to];if(e.placement===a.db.PLACEMENT.LEFTOF&&!s.prevActor)return;if(e.placement===a.db.PLACEMENT.RIGHTOF&&!s.nextActor)return;const n=void 0!==e.placement,o=!n,c=n?G(j):X(j),l=e.wrap?r.u.wrapLabel(e.message,j.width-2*j.wrapPadding,c):e.message,h=r.u.calculateTextDimensions(l,c).width+2*j.wrapPadding;o&&e.from===s.nextActor?i[e.to]=r.e.getMax(i[e.to]||0,h):o&&e.from===s.prevActor?i[e.from]=r.e.getMax(i[e.from]||0,h):o&&e.from===e.to?(i[e.from]=r.e.getMax(i[e.from]||0,h/2),i[e.to]=r.e.getMax(i[e.to]||0,h/2)):e.placement===a.db.PLACEMENT.RIGHTOF?i[e.from]=r.e.getMax(i[e.from]||0,h):e.placement===a.db.PLACEMENT.LEFTOF?i[s.prevActor]=r.e.getMax(i[s.prevActor]||0,h):e.placement===a.db.PLACEMENT.OVER&&(s.prevActor&&(i[s.prevActor]=r.e.getMax(i[s.prevActor]||0,h/2)),s.nextActor&&(i[e.from]=r.e.getMax(i[e.from]||0,h/2)))}})),r.l.debug("maxMessageWidthPerActor:",i),i}(g,f,n);if(j.height=function(t,e,a){let i=0;Object.keys(t).forEach((e=>{const a=t[e];a.wrap&&(a.description=r.u.wrapLabel(a.description,j.width-2*j.wrapPadding,J(j)));const s=r.u.calculateTextDimensions(a.description,J(j));a.width=a.wrap?j.width:r.e.getMax(j.width,s.width+2*j.wrapPadding),a.height=a.wrap?r.e.getMax(s.height,j.height):j.height,i=r.e.getMax(i,a.height)}));for(const n in e){const a=t[n];if(!a)continue;const i=t[a.nextActor];if(!i){const t=e[n]+j.actorMargin-a.width/2;a.margin=r.e.getMax(t,j.actorMargin);continue}const s=e[n]+j.actorMargin-a.width/2-i.width/2;a.margin=r.e.getMax(s,j.actorMargin)}let s=0;return a.forEach((e=>{const a=X(j);let i=e.actorKeys.reduce(((e,a)=>e+(t[a].width+(t[a].margin||0))),0);i-=2*j.boxTextMargin,e.wrap&&(e.name=r.u.wrapLabel(e.name,i-2*j.wrapPadding,a));const n=r.u.calculateTextDimensions(e.name,a);s=r.e.getMax(n.height,s);const o=r.e.getMax(i,n.width+2*j.wrapPadding);if(e.margin=j.boxTextMargin,it.textMaxHeight=s)),r.e.getMax(i,j.height)}(g,w,y),U.insertComputerIcon(p),U.insertDatabaseIcon(p),U.insertClockIcon(p),T&&(K.bumpVerticalPos(j.boxMargin),E&&K.bumpVerticalPos(y[0].textMaxHeight)),!0===j.hideUnusedParticipants){const t=new Set;f.forEach((e=>{t.add(e.from),t.add(e.to)})),m=m.filter((e=>t.has(e)))}!function(t,e,a,i,s,n,o){let c,l=0,h=0,d=0;for(const p of i){const t=e[p],i=t.box;c&&c!=i&&(o||K.models.addBox(c),h+=j.boxMargin+c.margin),i&&i!=c&&(o||(i.x=l+h,i.y=s),h+=i.margin),t.width=t.width||j.width,t.height=r.e.getMax(t.height||j.height,j.height),t.margin=t.margin||j.actorMargin,d=r.e.getMax(d,t.height),a[t.name]&&(h+=t.width/2),t.x=l+h,t.starty=K.getVerticalPos(),K.insert(t.x,s,t.x+t.width,t.height),l+=t.width+h,t.box&&(t.box.width=l+i.margin-t.box.x),h=t.margin,c=t.box,K.models.addActor(t)}c&&!o&&K.models.addBox(c),K.bumpVerticalPos(d)}(0,g,u,m,0,0,!1);const P=st(f,g,w,n);U.insertArrowHead(p),U.insertArrowCrossHead(p),U.insertArrowFilledHead(p),U.insertSequenceNumber(p);let _=1,L=1;const k=[],v=[];f.forEach((function(t,e){let a,i,o;switch(t.type){case n.db.LINETYPE.NOTE:K.resetVerticalPos(),i=t.noteModel,function(t,e){K.bumpVerticalPos(j.boxMargin),e.height=j.boxMargin,e.starty=K.getVerticalPos();const a=(0,s.g)();a.x=e.startx,a.y=e.starty,a.width=e.width||j.width,a.class="note";const r=t.append("g"),i=U.drawRect(r,a),n=(0,s.e)();n.x=e.startx,n.y=e.starty,n.width=a.width,n.dy="1em",n.text=e.message,n.class="noteText",n.fontFamily=j.noteFontFamily,n.fontSize=j.noteFontSize,n.fontWeight=j.noteFontWeight,n.anchor=j.noteAlign,n.textMargin=j.noteMargin,n.valign="center";const o=$(r,n),c=Math.round(o.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));i.attr("height",c+2*j.noteMargin),e.height+=c+2*j.noteMargin,K.bumpVerticalPos(c+2*j.noteMargin),e.stopy=e.starty+c+2*j.noteMargin,e.stopx=e.startx+a.width,K.insert(e.startx,e.starty,e.stopx,e.stopy),K.models.addNote(e)}(p,i);break;case n.db.LINETYPE.ACTIVE_START:K.newActivation(t,p,g);break;case n.db.LINETYPE.ACTIVE_END:!function(t,e){const a=K.endActivation(t);a.starty+18>e&&(a.starty=e-6,e+=12),U.drawActivation(p,a,e,j,et(t.from.actor).length),K.insert(a.startx,e-10,a.stopx,e)}(t,K.getVerticalPos());break;case n.db.LINETYPE.LOOP_START:rt(P,t,j.boxMargin,j.boxMargin+j.boxTextMargin,(t=>K.newLoop(t)));break;case n.db.LINETYPE.LOOP_END:a=K.endLoop(),U.drawLoop(p,a,"loop",j),K.bumpVerticalPos(a.stopy-K.getVerticalPos()),K.models.addLoop(a);break;case n.db.LINETYPE.RECT_START:rt(P,t,j.boxMargin,j.boxMargin,(t=>K.newLoop(void 0,t.message)));break;case n.db.LINETYPE.RECT_END:a=K.endLoop(),v.push(a),K.models.addLoop(a),K.bumpVerticalPos(a.stopy-K.getVerticalPos());break;case n.db.LINETYPE.OPT_START:rt(P,t,j.boxMargin,j.boxMargin+j.boxTextMargin,(t=>K.newLoop(t)));break;case n.db.LINETYPE.OPT_END:a=K.endLoop(),U.drawLoop(p,a,"opt",j),K.bumpVerticalPos(a.stopy-K.getVerticalPos()),K.models.addLoop(a);break;case n.db.LINETYPE.ALT_START:rt(P,t,j.boxMargin,j.boxMargin+j.boxTextMargin,(t=>K.newLoop(t)));break;case n.db.LINETYPE.ALT_ELSE:rt(P,t,j.boxMargin+j.boxTextMargin,j.boxMargin,(t=>K.addSectionToLoop(t)));break;case n.db.LINETYPE.ALT_END:a=K.endLoop(),U.drawLoop(p,a,"alt",j),K.bumpVerticalPos(a.stopy-K.getVerticalPos()),K.models.addLoop(a);break;case n.db.LINETYPE.PAR_START:case n.db.LINETYPE.PAR_OVER_START:rt(P,t,j.boxMargin,j.boxMargin+j.boxTextMargin,(t=>K.newLoop(t))),K.saveVerticalPos();break;case n.db.LINETYPE.PAR_AND:rt(P,t,j.boxMargin+j.boxTextMargin,j.boxMargin,(t=>K.addSectionToLoop(t)));break;case n.db.LINETYPE.PAR_END:a=K.endLoop(),U.drawLoop(p,a,"par",j),K.bumpVerticalPos(a.stopy-K.getVerticalPos()),K.models.addLoop(a);break;case n.db.LINETYPE.AUTONUMBER:_=t.message.start||_,L=t.message.step||L,t.message.visible?n.db.enableSequenceNumbers():n.db.disableSequenceNumbers();break;case n.db.LINETYPE.CRITICAL_START:rt(P,t,j.boxMargin,j.boxMargin+j.boxTextMargin,(t=>K.newLoop(t)));break;case n.db.LINETYPE.CRITICAL_OPTION:rt(P,t,j.boxMargin+j.boxTextMargin,j.boxMargin,(t=>K.addSectionToLoop(t)));break;case n.db.LINETYPE.CRITICAL_END:a=K.endLoop(),U.drawLoop(p,a,"critical",j),K.bumpVerticalPos(a.stopy-K.getVerticalPos()),K.models.addLoop(a);break;case n.db.LINETYPE.BREAK_START:rt(P,t,j.boxMargin,j.boxMargin+j.boxTextMargin,(t=>K.newLoop(t)));break;case n.db.LINETYPE.BREAK_END:a=K.endLoop(),U.drawLoop(p,a,"break",j),K.bumpVerticalPos(a.stopy-K.getVerticalPos()),K.models.addLoop(a);break;default:try{o=t.msgModel,o.starty=K.getVerticalPos(),o.sequenceIndex=_,o.sequenceVisible=n.db.showSequenceNumbers();const a=function(t,e){K.bumpVerticalPos(10);const{startx:a,stopx:i,message:s}=e,n=r.e.splitBreaks(s).length,o=r.u.calculateTextDimensions(s,X(j)),c=o.height/n;let l;e.height+=c,K.bumpVerticalPos(c);let h=o.height-10;const d=o.width;if(a===i){l=K.getVerticalPos()+h,j.rightAngles||(h+=j.boxMargin,l=K.getVerticalPos()+h),h+=30;const t=r.e.getMax(d/2,j.width/2);K.insert(a-t,K.getVerticalPos()-10+h,i+t,K.getVerticalPos()+30+h)}else h+=j.boxMargin,l=K.getVerticalPos()+h,K.insert(a,l-10,i,l);return K.bumpVerticalPos(h),e.height+=h,e.stopy=e.starty+e.height,K.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),l}(0,o);!function(t,e,a,r,i,s,n){function o(a,r){a.xfunction(t,e,a,i){const{startx:n,stopx:o,starty:c,message:l,type:h,sequenceIndex:d,sequenceVisible:p}=e,g=r.u.calculateTextDimensions(l,X(j)),u=(0,s.e)();u.x=n,u.y=c+10,u.width=o-n,u.class="messageText",u.dy="1em",u.text=l,u.fontFamily=j.messageFontFamily,u.fontSize=j.messageFontSize,u.fontWeight=j.messageFontWeight,u.anchor=j.messageAlign,u.valign="center",u.textMargin=j.wrapPadding,u.tspan=!1,$(t,u);const x=g.width;let y;n===o?y=j.rightAngles?t.append("path").attr("d",`M ${n},${a} H ${n+r.e.getMax(j.width/2,x/2)} V ${a+25} H ${n}`):t.append("path").attr("d","M "+n+","+a+" C "+(n+60)+","+(a-10)+" "+(n+60)+","+(a+30)+" "+n+","+(a+20)):(y=t.append("line"),y.attr("x1",n),y.attr("y1",a),y.attr("x2",o),y.attr("y2",a)),h===i.db.LINETYPE.DOTTED||h===i.db.LINETYPE.DOTTED_CROSS||h===i.db.LINETYPE.DOTTED_POINT||h===i.db.LINETYPE.DOTTED_OPEN?(y.style("stroke-dasharray","3, 3"),y.attr("class","messageLine1")):y.attr("class","messageLine0");let m="";j.arrowMarkerAbsolute&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),y.attr("stroke-width",2),y.attr("stroke","none"),y.style("fill","none"),h!==i.db.LINETYPE.SOLID&&h!==i.db.LINETYPE.DOTTED||y.attr("marker-end","url("+m+"#arrowhead)"),h!==i.db.LINETYPE.SOLID_POINT&&h!==i.db.LINETYPE.DOTTED_POINT||y.attr("marker-end","url("+m+"#filled-head)"),h!==i.db.LINETYPE.SOLID_CROSS&&h!==i.db.LINETYPE.DOTTED_CROSS||y.attr("marker-end","url("+m+"#crosshead)"),(p||j.showSequenceNumbers)&&(y.attr("marker-start","url("+m+"#sequencenumber)"),t.append("text").attr("x",n).attr("y",a+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(d))}(p,t.messageModel,t.lineStartY,n))),j.mirrorActors&&Z(p,g,m,!0),v.forEach((t=>U.drawBackgroundRect(p,t))),F(p,g,m,j),K.models.boxes.forEach((function(t){t.height=K.getVerticalPos()-t.y,K.insert(t.x,t.y,t.x+t.width,t.height),t.startx=t.x,t.starty=t.y,t.stopx=t.startx+t.width,t.stopy=t.starty+t.height,t.stroke="rgb(0,0,0, 0.5)",U.drawBox(p,t,j)})),T&&K.bumpVerticalPos(j.boxMargin);const I=Q(p,g,m,d),{bounds:M}=K.getBounds();let N=M.stopy-M.starty;N{S.setWrap(t)}}},93799:(t,e,a)=>{a.d(e,{a:()=>n,b:()=>l,c:()=>c,d:()=>s,e:()=>d,f:()=>o,g:()=>h});var r=a(17967),i=a(56363);const s=(t,e)=>{const a=t.append("rect");if(a.attr("x",e.x),a.attr("y",e.y),a.attr("fill",e.fill),a.attr("stroke",e.stroke),a.attr("width",e.width),a.attr("height",e.height),void 0!==e.rx&&a.attr("rx",e.rx),void 0!==e.ry&&a.attr("ry",e.ry),void 0!==e.attrs)for(const r in e.attrs)a.attr(r,e.attrs[r]);return void 0!==e.class&&a.attr("class",e.class),a},n=(t,e)=>{const a={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};s(t,a).lower()},o=(t,e)=>{const a=e.text.replace(i.H," "),r=t.append("text");r.attr("x",e.x),r.attr("y",e.y),r.attr("class","legend"),r.style("text-anchor",e.anchor),void 0!==e.class&&r.attr("class",e.class);const s=r.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(a),r},c=(t,e,a,i)=>{const s=t.append("image");s.attr("x",e),s.attr("y",a);const n=(0,r.Nm)(i);s.attr("xlink:href",n)},l=(t,e,a,i)=>{const s=t.append("use");s.attr("x",e),s.attr("y",a);const n=(0,r.Nm)(i);s.attr("xlink:href",`#${n}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),d=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/365.da569cd3.js b/assets/js/365.da569cd3.js new file mode 100644 index 000000000..585309101 --- /dev/null +++ b/assets/js/365.da569cd3.js @@ -0,0 +1,739 @@ +"use strict"; +exports.id = 365; +exports.ids = [365]; +exports.modules = { + +/***/ 88365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 3], $V1 = [1, 4], $V2 = [1, 5], $V3 = [1, 6], $V4 = [1, 10, 12, 14, 16, 18, 19, 20, 21, 22], $V5 = [2, 4], $V6 = [1, 5, 10, 12, 14, 16, 18, 19, 20, 21, 22], $V7 = [20, 21, 22], $V8 = [2, 7], $V9 = [1, 12], $Va = [1, 13], $Vb = [1, 14], $Vc = [1, 15], $Vd = [1, 16], $Ve = [1, 17]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "eol": 4, "PIE": 5, "document": 6, "showData": 7, "line": 8, "statement": 9, "txt": 10, "value": 11, "title": 12, "title_value": 13, "acc_title": 14, "acc_title_value": 15, "acc_descr": 16, "acc_descr_value": 17, "acc_descr_multiline_value": 18, "section": 19, "NEWLINE": 20, ";": 21, "EOF": 22, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "PIE", 7: "showData", 10: "txt", 11: "value", 12: "title", 13: "title_value", 14: "acc_title", 15: "acc_title_value", 16: "acc_descr", 17: "acc_descr_value", 18: "acc_descr_multiline_value", 19: "section", 20: "NEWLINE", 21: ";", 22: "EOF" }, + productions_: [0, [3, 2], [3, 2], [3, 3], [6, 0], [6, 2], [8, 2], [9, 0], [9, 2], [9, 2], [9, 2], [9, 2], [9, 1], [9, 1], [4, 1], [4, 1], [4, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.setShowData(true); + break; + case 6: + this.$ = $$[$0 - 1]; + break; + case 8: + yy.addSection($$[$0 - 1], yy.cleanupValue($$[$0])); + break; + case 9: + this.$ = $$[$0].trim(); + yy.setDiagramTitle(this.$); + break; + case 10: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 11: + case 12: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 13: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + } + }, + table: [{ 3: 1, 4: 2, 5: $V0, 20: $V1, 21: $V2, 22: $V3 }, { 1: [3] }, { 3: 7, 4: 2, 5: $V0, 20: $V1, 21: $V2, 22: $V3 }, o($V4, $V5, { 6: 8, 7: [1, 9] }), o($V6, [2, 14]), o($V6, [2, 15]), o($V6, [2, 16]), { 1: [2, 1] }, o($V7, $V8, { 8: 10, 9: 11, 1: [2, 2], 10: $V9, 12: $Va, 14: $Vb, 16: $Vc, 18: $Vd, 19: $Ve }), o($V4, $V5, { 6: 18 }), o($V4, [2, 5]), { 4: 19, 20: $V1, 21: $V2, 22: $V3 }, { 11: [1, 20] }, { 13: [1, 21] }, { 15: [1, 22] }, { 17: [1, 23] }, o($V7, [2, 12]), o($V7, [2, 13]), o($V7, $V8, { 8: 10, 9: 11, 1: [2, 3], 10: $V9, 12: $Va, 14: $Vb, 16: $Vc, 18: $Vd, 19: $Ve }), o($V4, [2, 6]), o($V7, [2, 8]), o($V7, [2, 9]), o($V7, [2, 10]), o($V7, [2, 11])], + defaultActions: { 7: [2, 1] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + return 20; + case 3: + break; + case 4: + break; + case 5: + this.begin("title"); + return 12; + case 6: + this.popState(); + return "title_value"; + case 7: + this.begin("acc_title"); + return 14; + case 8: + this.popState(); + return "acc_title_value"; + case 9: + this.begin("acc_descr"); + return 16; + case 10: + this.popState(); + return "acc_descr_value"; + case 11: + this.begin("acc_descr_multiline"); + break; + case 12: + this.popState(); + break; + case 13: + return "acc_descr_multiline_value"; + case 14: + this.begin("string"); + break; + case 15: + this.popState(); + break; + case 16: + return "txt"; + case 17: + return 5; + case 18: + return 7; + case 19: + return "value"; + case 20: + return 22; + } + }, + rules: [/^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n\r]+)/i, /^(?:%%[^\n]*)/i, /^(?:[\s]+)/i, /^(?:title\b)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:pie\b)/i, /^(?:showData\b)/i, /^(?::[\s]*[\d]+(?:\.[\d]+)?)/i, /^(?:$)/i], + conditions: { "acc_descr_multiline": { "rules": [12, 13], "inclusive": false }, "acc_descr": { "rules": [10], "inclusive": false }, "acc_title": { "rules": [8], "inclusive": false }, "title": { "rules": [6], "inclusive": false }, "string": { "rules": [15, 16], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 7, 9, 11, 14, 17, 18, 19, 20], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const DEFAULT_PIE_CONFIG = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.A.pie; +const DEFAULT_PIE_DB = { + sections: {}, + showData: false, + config: DEFAULT_PIE_CONFIG +}; +let sections = DEFAULT_PIE_DB.sections; +let showData = DEFAULT_PIE_DB.showData; +const config = structuredClone(DEFAULT_PIE_CONFIG); +const getConfig = () => structuredClone(config); +const clear = () => { + sections = structuredClone(DEFAULT_PIE_DB.sections); + showData = DEFAULT_PIE_DB.showData; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.t)(); +}; +const addSection = (label, value) => { + label = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.d)(label, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + if (sections[label] === void 0) { + sections[label] = value; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`added new section: ${label}, with value: ${value}`); + } +}; +const getSections = () => sections; +const cleanupValue = (value) => { + if (value.substring(0, 1) === ":") { + value = value.substring(1).trim(); + } + return Number(value.trim()); +}; +const setShowData = (toggle) => { + showData = toggle; +}; +const getShowData = () => showData; +const db = { + getConfig, + clear, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.r, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.g, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.b, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.a, + addSection, + getSections, + cleanupValue, + setShowData, + getShowData +}; +const getStyles = (options) => ` + .pieCircle{ + stroke: ${options.pieStrokeColor}; + stroke-width : ${options.pieStrokeWidth}; + opacity : ${options.pieOpacity}; + } + .pieOuterCircle{ + stroke: ${options.pieOuterStrokeColor}; + stroke-width: ${options.pieOuterStrokeWidth}; + fill: none; + } + .pieTitleText { + text-anchor: middle; + font-size: ${options.pieTitleTextSize}; + fill: ${options.pieTitleTextColor}; + font-family: ${options.fontFamily}; + } + .slice { + font-family: ${options.fontFamily}; + fill: ${options.pieSectionTextColor}; + font-size:${options.pieSectionTextSize}; + // fill: white; + } + .legend text { + fill: ${options.pieLegendTextColor}; + font-family: ${options.fontFamily}; + font-size: ${options.pieLegendTextSize}; + } +`; +const styles = getStyles; +const createPieArcs = (sections2) => { + const pieData = Object.entries(sections2).map((element) => { + return { + label: element[0], + value: element[1] + }; + }).sort((a, b) => { + return b.value - a.value; + }); + const pie$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .pie */ .ve8)().value( + (d3Section) => d3Section.value + ); + return pie$1(pieData); +}; +const draw = (text, id, _version, diagObj) => { + var _a, _b; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("rendering pie chart\n" + text); + const db2 = diagObj.db; + const globalConfig = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const pieConfig = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.B)(db2.getConfig(), globalConfig.pie); + const height = 450; + const width = ((_b = (_a = document.getElementById(id)) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.offsetWidth) ?? pieConfig.useWidth; + const svg = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.z)(id); + svg.attr("viewBox", `0 0 ${width} ${height}`); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.i)(svg, height, width, pieConfig.useMaxWidth); + const MARGIN = 40; + const LEGEND_RECT_SIZE = 18; + const LEGEND_SPACING = 4; + const group = svg.append("g"); + group.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); + const { themeVariables } = globalConfig; + let [outerStrokeWidth] = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.C)(themeVariables.pieOuterStrokeWidth); + outerStrokeWidth ?? (outerStrokeWidth = 2); + const textPosition = pieConfig.textPosition; + const radius = Math.min(width, height) / 2 - MARGIN; + const arcGenerator = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .Nb1)().innerRadius(0).outerRadius(radius); + const labelArcGenerator = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .Nb1)().innerRadius(radius * textPosition).outerRadius(radius * textPosition); + group.append("circle").attr("cx", 0).attr("cy", 0).attr("r", radius + outerStrokeWidth / 2).attr("class", "pieOuterCircle"); + const sections2 = db2.getSections(); + const arcs = createPieArcs(sections2); + const myGeneratedColors = [ + themeVariables.pie1, + themeVariables.pie2, + themeVariables.pie3, + themeVariables.pie4, + themeVariables.pie5, + themeVariables.pie6, + themeVariables.pie7, + themeVariables.pie8, + themeVariables.pie9, + themeVariables.pie10, + themeVariables.pie11, + themeVariables.pie12 + ]; + const color = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleOrdinal */ .PKp)(myGeneratedColors); + group.selectAll("mySlices").data(arcs).enter().append("path").attr("d", arcGenerator).attr("fill", (datum) => { + return color(datum.data.label); + }).attr("class", "pieCircle"); + let sum = 0; + Object.keys(sections2).forEach((key) => { + sum += sections2[key]; + }); + group.selectAll("mySlices").data(arcs).enter().append("text").text((datum) => { + return (datum.data.value / sum * 100).toFixed(0) + "%"; + }).attr("transform", (datum) => { + return "translate(" + labelArcGenerator.centroid(datum) + ")"; + }).style("text-anchor", "middle").attr("class", "slice"); + group.append("text").text(db2.getDiagramTitle()).attr("x", 0).attr("y", -(height - 50) / 2).attr("class", "pieTitleText"); + const legend = group.selectAll(".legend").data(color.domain()).enter().append("g").attr("class", "legend").attr("transform", (_datum, index) => { + const height2 = LEGEND_RECT_SIZE + LEGEND_SPACING; + const offset = height2 * color.domain().length / 2; + const horizontal = 12 * LEGEND_RECT_SIZE; + const vertical = index * height2 - offset; + return "translate(" + horizontal + "," + vertical + ")"; + }); + legend.append("rect").attr("width", LEGEND_RECT_SIZE).attr("height", LEGEND_RECT_SIZE).style("fill", color).style("stroke", color); + legend.data(arcs).append("text").attr("x", LEGEND_RECT_SIZE + LEGEND_SPACING).attr("y", LEGEND_RECT_SIZE - LEGEND_SPACING).text((datum) => { + const { label, value } = datum.data; + if (db2.getShowData()) { + return `${label} [${value}]`; + } + return label; + }); +}; +const renderer = { draw }; +const diagram = { + parser: parser$1, + db, + renderer, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/366ddb85.8c709735.js b/assets/js/366ddb85.8c709735.js deleted file mode 100644 index 474d2a9a3..000000000 --- a/assets/js/366ddb85.8c709735.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3691],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,f=d["".concat(i,".").concat(m)]||d[m]||s[m]||p;return r?n.createElement(f,l(l({ref:t},u),{},{components:r})):n.createElement(f,l({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=d;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var c=2;c{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>s,frontMatter:()=>p,metadata:()=>o,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",slug:"/etc/develop-with-spring",last_update:{date:"2023/09/03"},tags:["etc"]},l=void 0,o={unversionedId:"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",id:"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",description:"\uc5b4\ub5a4 \uae30\uc220\uc744 \ud1b5\ud574\uc11c\ub3c4 \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4.",source:"@site/docs/\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30.mdx",sourceDirName:"\uae30\ud0c0",slug:"/etc/develop-with-spring",permalink:"/docs/etc/develop-with-spring",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30.mdx",tags:[{label:"etc",permalink:"/docs/tags/etc"}],version:"current",lastUpdatedAt:1693699200,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 3\uc77c",frontMatter:{title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",slug:"/etc/develop-with-spring",last_update:{date:"2023/09/03"},tags:["etc"]},sidebar:"tutorialSidebar",previous:{title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",permalink:"/docs/etc/healthful-growth"},next:{title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",permalink:"/docs/etc/experience-and-self-question"}},i={},c=[{value:"\uc2e4\uc804 \uc0ac\uc6a9",id:"\uc2e4\uc804-\uc0ac\uc6a9",level:3},{value:"\uc9c8\ubb38\uacfc \ud0d0\uad6c",id:"\uc9c8\ubb38\uacfc-\ud0d0\uad6c",level:3},{value:"\ud6c8\ub828\uacfc \uac1c\uc120",id:"\ud6c8\ub828\uacfc-\uac1c\uc120",level:3},{value:"\uacf5\uc720\uc640 \ub17c\uc7c1",id:"\uacf5\uc720\uc640-\ub17c\uc7c1",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uc5b4\ub5a4 \uae30\uc220\uc744 \ud1b5\ud574\uc11c\ub3c4 \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\uc2e4\uc804-\uc0ac\uc6a9"},"\uc2e4\uc804 \uc0ac\uc6a9"),(0,a.kt)("p",null,"\ub2e8\uc21c \uae30\uc220\uc758 \uc0ac\uc6a9\uc73c\ub85c\ub294 \uc131\uc7a5\uc774 \uc5b4\ub835\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2e4\uc804 \uc801\uc6a9\uc73c\ub85c \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\uc9c8\ubb38\uacfc-\ud0d0\uad6c"},"\uc9c8\ubb38\uacfc \ud0d0\uad6c"),(0,a.kt)("p",null,"\ub0b4\uac00 \uc0ac\uc6a9\ud558\ub294 \uae30\uc220\uc740 \uc65c \uc774\ub807\uac8c \ub9cc\ub4e4\uc5b4\uc84c\ub294\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub294 \uc65c \uc774\ub807\uac8c \uc124\uacc4\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud574\uc57c \ud558\ub294\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc7a5\ub2e8\uc810\uc740 \ubb34\uc5c7\uc778\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ub300\uc548\uc740 \uc5c6\uc744\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c0\uae08\ub3c4 \uc88b\uae34\ud55c\ub370 \ub2e4\uc74c\uc5d0\ub294 \uac1c\uc120\ud560 \ubd80\ubd84\uc774 \uc788\uc744\uae4c? "),(0,a.kt)("h3",{id:"\ud6c8\ub828\uacfc-\uac1c\uc120"},"\ud6c8\ub828\uacfc \uac1c\uc120"),(0,a.kt)("p",null,"\ubc30\uc6b4 \uac83\uc744 \uc751\uc6a9\ud574\ubcf4\ub294 \ucf54\ub529\uc744 \uafb8\uc900\ud788",(0,a.kt)("br",{parentName:"p"}),"\n","\ud29c\ud1a0\ub9ac\uc5bc \uc608\uc81c\ub97c \ubc18\ubcf5\ud574\uc11c \uc791\uc131",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0c8\ub85c\uc6b4 \uae30\ub2a5\uc744 \ucd94\uac00\ud558\uace0 \uc124\uacc4 \uad6c\uc870\ub97c \ubcc0\uacbd\ud574\ubcf4\ub294 \uc2dc\ub3c4",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2e4\ubb34\uc5d0\uc11c \uc0ac\uc6a9\ud558\uc9c0 \ubabb\ud588\ub358 \uae30\uc220 \ub3c4\uc785",(0,a.kt)("br",{parentName:"p"}),"\n","\uc5f0\uc2b5\uc6a9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\uc0c1\ud558\uace0 \uc124\uacc4",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd08\uae30 \uac1c\ubc1c \uc0dd\uc0b0\uc131, \ubcc0\uacbd \uc6a9\uc774\uc131 \ub4f1\uc744 \uad00\ucc30 "),(0,a.kt)("h3",{id:"\uacf5\uc720\uc640-\ub17c\uc7c1"},"\uacf5\uc720\uc640 \ub17c\uc7c1"),(0,a.kt)("p",null,"\ubb38\uc11c, \ubc1c\ud45c \uc790\ub8cc\ub85c \uc815\ub9ac",(0,a.kt)("br",{parentName:"p"}),"\n","\uc815\ub9ac\uc5d0 \uc2dc\uac04\uc744 \ub9ce\uc774 \ub4e4\uc774\uba74 \ud6a8\uc728\uc131\uc774 \ub5a8\uc5b4\uc9c0\uae30\uc5d0 \uc911\uc694\ud55c \ubd80\ubd84\ub9cc \uc815\ub9ac",(0,a.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud55c \uc791\uc131, \uac80\uc0c9\uc774 \uac00\ub2a5\ud55c \ub3c4\uad6c \ud65c\uc6a9",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub9cc\uc758 \uc815\uc758\uc640 \uc124\uba85\uc744 \ub9cc\ub4e4\uc5b4\uac00\uae30 -> \ud55c \ubb38\uc7a5, \ud55c \ubb38\ub2e8, 5\ubd84\uac04 \uc124\uba85, \uc810\uc810 \ub298\ub824\uac00\uba70"),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30 - \ud1a0\ube44, INFCON 2023"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/366ddb85.a5ba09fa.js b/assets/js/366ddb85.a5ba09fa.js new file mode 100644 index 000000000..0cc46248d --- /dev/null +++ b/assets/js/366ddb85.a5ba09fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3691],{33751:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>d,frontMatter:()=>s,metadata:()=>l,toc:()=>a});var n=r(85893),i=r(3905);const s={title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",slug:"/etc/develop-with-spring",last_update:{date:"2023/09/03"},tags:["etc"]},c=void 0,l={id:"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",description:"\uc5b4\ub5a4 \uae30\uc220\uc744 \ud1b5\ud574\uc11c\ub3c4 \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4.",source:"@site/docs/\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30.mdx",sourceDirName:"\uae30\ud0c0",slug:"/etc/develop-with-spring",permalink:"/docs/etc/develop-with-spring",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30.mdx",tags:[{label:"etc",permalink:"/docs/tags/etc"}],version:"current",lastUpdatedAt:1693699200,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 3\uc77c",frontMatter:{title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",slug:"/etc/develop-with-spring",last_update:{date:"2023/09/03"},tags:["etc"]},sidebar:"tutorialSidebar",previous:{title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",permalink:"/docs/etc/healthful-growth"},next:{title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",permalink:"/docs/etc/experience-and-self-question"}},o={},a=[{value:"\uc2e4\uc804 \uc0ac\uc6a9",id:"\uc2e4\uc804-\uc0ac\uc6a9",level:3},{value:"\uc9c8\ubb38\uacfc \ud0d0\uad6c",id:"\uc9c8\ubb38\uacfc-\ud0d0\uad6c",level:3},{value:"\ud6c8\ub828\uacfc \uac1c\uc120",id:"\ud6c8\ub828\uacfc-\uac1c\uc120",level:3},{value:"\uacf5\uc720\uc640 \ub17c\uc7c1",id:"\uacf5\uc720\uc640-\ub17c\uc7c1",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const t={br:"br",h3:"h3",p:"p",...(0,i.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"\uc5b4\ub5a4 \uae30\uc220\uc744 \ud1b5\ud574\uc11c\ub3c4 \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,n.jsx)(t.h3,{id:"\uc2e4\uc804-\uc0ac\uc6a9",children:"\uc2e4\uc804 \uc0ac\uc6a9"}),"\n",(0,n.jsxs)(t.p,{children:["\ub2e8\uc21c \uae30\uc220\uc758 \uc0ac\uc6a9\uc73c\ub85c\ub294 \uc131\uc7a5\uc774 \uc5b4\ub835\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc2e4\uc804 \uc801\uc6a9\uc73c\ub85c \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\uc9c8\ubb38\uacfc-\ud0d0\uad6c",children:"\uc9c8\ubb38\uacfc \ud0d0\uad6c"}),"\n",(0,n.jsxs)(t.p,{children:["\ub0b4\uac00 \uc0ac\uc6a9\ud558\ub294 \uae30\uc220\uc740 \uc65c \uc774\ub807\uac8c \ub9cc\ub4e4\uc5b4\uc84c\ub294\uac00?",(0,n.jsx)(t.br,{}),"\n","\ub098\ub294 \uc65c \uc774\ub807\uac8c \uc124\uacc4\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud574\uc57c \ud558\ub294\uac00?",(0,n.jsx)(t.br,{}),"\n","\uc7a5\ub2e8\uc810\uc740 \ubb34\uc5c7\uc778\uac00?",(0,n.jsx)(t.br,{}),"\n","\ub2e4\ub978 \ub300\uc548\uc740 \uc5c6\uc744\uae4c?",(0,n.jsx)(t.br,{}),"\n","\uc9c0\uae08\ub3c4 \uc88b\uae34\ud55c\ub370 \ub2e4\uc74c\uc5d0\ub294 \uac1c\uc120\ud560 \ubd80\ubd84\uc774 \uc788\uc744\uae4c?"]}),"\n",(0,n.jsx)(t.h3,{id:"\ud6c8\ub828\uacfc-\uac1c\uc120",children:"\ud6c8\ub828\uacfc \uac1c\uc120"}),"\n",(0,n.jsxs)(t.p,{children:["\ubc30\uc6b4 \uac83\uc744 \uc751\uc6a9\ud574\ubcf4\ub294 \ucf54\ub529\uc744 \uafb8\uc900\ud788",(0,n.jsx)(t.br,{}),"\n","\ud29c\ud1a0\ub9ac\uc5bc \uc608\uc81c\ub97c \ubc18\ubcf5\ud574\uc11c \uc791\uc131",(0,n.jsx)(t.br,{}),"\n","\uc0c8\ub85c\uc6b4 \uae30\ub2a5\uc744 \ucd94\uac00\ud558\uace0 \uc124\uacc4 \uad6c\uc870\ub97c \ubcc0\uacbd\ud574\ubcf4\ub294 \uc2dc\ub3c4",(0,n.jsx)(t.br,{}),"\n","\uc2e4\ubb34\uc5d0\uc11c \uc0ac\uc6a9\ud558\uc9c0 \ubabb\ud588\ub358 \uae30\uc220 \ub3c4\uc785",(0,n.jsx)(t.br,{}),"\n","\uc5f0\uc2b5\uc6a9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\uc0c1\ud558\uace0 \uc124\uacc4",(0,n.jsx)(t.br,{}),"\n","\ucd08\uae30 \uac1c\ubc1c \uc0dd\uc0b0\uc131, \ubcc0\uacbd \uc6a9\uc774\uc131 \ub4f1\uc744 \uad00\ucc30"]}),"\n",(0,n.jsx)(t.h3,{id:"\uacf5\uc720\uc640-\ub17c\uc7c1",children:"\uacf5\uc720\uc640 \ub17c\uc7c1"}),"\n",(0,n.jsxs)(t.p,{children:["\ubb38\uc11c, \ubc1c\ud45c \uc790\ub8cc\ub85c \uc815\ub9ac",(0,n.jsx)(t.br,{}),"\n","\uc815\ub9ac\uc5d0 \uc2dc\uac04\uc744 \ub9ce\uc774 \ub4e4\uc774\uba74 \ud6a8\uc728\uc131\uc774 \ub5a8\uc5b4\uc9c0\uae30\uc5d0 \uc911\uc694\ud55c \ubd80\ubd84\ub9cc \uc815\ub9ac",(0,n.jsx)(t.br,{}),"\n","\uac04\ub2e8\ud55c \uc791\uc131, \uac80\uc0c9\uc774 \uac00\ub2a5\ud55c \ub3c4\uad6c \ud65c\uc6a9",(0,n.jsx)(t.br,{}),"\n","\ub098\ub9cc\uc758 \uc815\uc758\uc640 \uc124\uba85\uc744 \ub9cc\ub4e4\uc5b4\uac00\uae30 -> \ud55c \ubb38\uc7a5, \ud55c \ubb38\ub2e8, 5\ubd84\uac04 \uc124\uba85, \uc810\uc810 \ub298\ub824\uac00\uba70"]}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsx)(t.p,{children:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30 - \ud1a0\ube44, INFCON 2023"})]})}function d(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>a});var n=r(67294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var o=n.createContext({}),a=function(e){var t=n.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,s=e.originalType,o=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),u=a(r),b=i,f=u["".concat(o,".").concat(b)]||u[b]||p[b]||s;return r?n.createElement(f,c(c({ref:t},d),{},{components:r})):n.createElement(f,c({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/3680bd07.a5c1fc21.js b/assets/js/3680bd07.43261a11.js similarity index 80% rename from assets/js/3680bd07.a5c1fc21.js rename to assets/js/3680bd07.43261a11.js index a98e22fc2..8008141cf 100644 --- a/assets/js/3680bd07.a5c1fc21.js +++ b/assets/js/3680bd07.43261a11.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5173],{2003:e=>{e.exports=JSON.parse('{"label":"web application","permalink":"/tags/web-application","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5173],{2003:e=>{e.exports=JSON.parse('{"label":"web application","permalink":"/tags/web-application","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/371.4e845673.js b/assets/js/371.4e845673.js new file mode 100644 index 000000000..046c4f869 --- /dev/null +++ b/assets/js/371.4e845673.js @@ -0,0 +1,26658 @@ +"use strict"; +exports.id = 371; +exports.ids = [371]; +exports.modules = { + +/***/ 43349: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ addHtmlLabel) +/* harmony export */ }); +/* harmony import */ var _util_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(96225); + + + + +function addHtmlLabel(root, node) { + var fo = root.append('foreignObject').attr('width', '100000'); + + var div = fo.append('xhtml:div'); + div.attr('xmlns', 'http://www.w3.org/1999/xhtml'); + + var label = node.label; + switch (typeof label) { + case 'function': + div.insert(label); + break; + case 'object': + // Currently we assume this is a DOM object. + div.insert(function () { + return label; + }); + break; + default: + div.html(label); + } + + _util_js__WEBPACK_IMPORTED_MODULE_0__/* .applyStyle */ .bg(div, node.labelStyle); + div.style('display', 'inline-block'); + // Fix for firefox + div.style('white-space', 'nowrap'); + + var client = div.node().getBoundingClientRect(); + fo.attr('width', client.width).attr('height', client.height); + + return fo; +} + + +/***/ }), + +/***/ 96225: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ $p: () => (/* binding */ applyClass), +/* harmony export */ O1: () => (/* binding */ edgeToId), +/* harmony export */ WR: () => (/* binding */ applyTransition), +/* harmony export */ bF: () => (/* binding */ isSubgraph), +/* harmony export */ bg: () => (/* binding */ applyStyle) +/* harmony export */ }); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(37514); +/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(73234); + + +// Public utility functions + + +/* + * Returns true if the specified node in the graph is a subgraph node. A + * subgraph node is one that contains other nodes. + */ +function isSubgraph(g, v) { + return !!g.children(v).length; +} + +function edgeToId(e) { + return escapeId(e.v) + ':' + escapeId(e.w) + ':' + escapeId(e.name); +} + +var ID_DELIM = /:/g; +function escapeId(str) { + return str ? String(str).replace(ID_DELIM, '\\:') : ''; +} + +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr('style', styleFn); + } +} + +function applyClass(dom, classFn, otherClasses) { + if (classFn) { + dom.attr('class', classFn).attr('class', otherClasses + ' ' + dom.attr('class')); + } +} + +function applyTransition(selection, g) { + var graph = g.graph(); + + if (lodash_es__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z(graph)) { + var transition = graph.transition; + if (lodash_es__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z(transition)) { + return transition(selection); + } + } + + return selection; +} + + +/***/ }), + +/***/ 41644: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + bK: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.Z(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.Z( + map/* default */.Z(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.Z(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.Z(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.k(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.Z(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.Z(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.Z(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.Z(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.Z(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.Z('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.Z(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.Z(g.outEdges(v), function (e) { + if (has/* default */.Z(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.Z(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.Z(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(59236); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.Z)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(74752); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.Z)(iteratee, 3); + + (0,_baseForOwn/* default */.Z)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.Z)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(66092); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.Z.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.Z(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.k().setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.k({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.Z(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.Z(range/* default */.Z(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.Z(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.Z(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.Z(layers, function (vs, i) { + if (isUndefined/* default */.Z(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.Z(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.Z(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.Z(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.Z(children, dfs); + } + + if (has/* default */.Z(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.Z(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, reverseYOne); + if (has/* default */.Z(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, swapXYOne); + if (has/* default */.Z(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.Z(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.Z)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.Z(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.Z(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.Z(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.k({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.Z(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.Z(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.Z(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.Z)(collection)) { + var iteratee = (0,_baseIteratee/* default */.Z)(predicate, 3); + collection = (0,keys/* default */.Z)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.Z)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.Z)(array, (0,_baseIteratee/* default */.Z)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(39473); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(93589); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.Z)(value) && (0,isObjectLike/* default */.Z)(value) && (0,_baseGetTag/* default */.Z)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.Z)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.Z)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.Z)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.Z)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.Z(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.Z(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.Z(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.Z(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.Z(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.Z(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.Z(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.Z(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.Z(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.Z(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.Z(tree.neighbors(v), function (w) { + if (!has/* default */.Z(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.Z(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.Z(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.Z(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.Z(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.Z(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.Z(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.Z(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.Z(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.Z( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.Z(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.k({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.Z(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.Z(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.Z(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.Z('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.Z); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(21018); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.Z)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.Z)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + if ((0,isArray/* default */.Z)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.Z)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.Z]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.Z)(iteratees, (0,_baseUnary/* default */.Z)(_baseIteratee/* default */.Z)); + + var result = (0,_baseMap/* default */.Z)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.Z)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.Z)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.Z)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.Z)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.Z(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.Z( + map/* default */.Z(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.Z(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.Z(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.Z( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.Z(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.Z(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.Z(range/* default */.Z(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.Z(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.Z(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.Z(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.Z(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.Z( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.Z(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.Z(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.Z(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.Z(entryV) && !isUndefined/* default */.Z(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.Z(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.Z(uEntry.barycenter) || + isUndefined/* default */.Z(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.Z(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.Z(entry.out, handleOut(entry)); + } + + return map/* default */.Z( + filter/* default */.Z(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.Z(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.Z(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.Z(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.Z(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.Z(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.Z(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.Z(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.Z([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.Z(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.Z(entries, function (entry) { + entry.vs = flatten/* default */.Z( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.Z(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.Z(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.Z(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.Z(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.k(); + forEach/* default */.Z(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.Z(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.Z(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.Z(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(68882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(61395); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee), keysIn/* default */.Z); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.Z(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.Z(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.Z(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.Z(range/* default */.Z(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.Z(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.Z(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.Z(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.Z(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.Z(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.Z(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.k(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.Z(layering, function (layer) { + var u; + forEach/* default */.Z(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.Z(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.Z(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.Z(['u', 'd'], function (vert) { + forEach/* default */.Z(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.Z(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.Z(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.Z(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.Z(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.Z(layering).reverse(); + forEach/* default */.Z(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.Z(adjustedLayering, function (inner) { + return values/* default */.Z(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.Z(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.Z(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.Z(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.Z(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.Z(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.Z(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.k({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.Z({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.Z(graph, graphAttrs)) + ); + + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.Z(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.Z({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.Z(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.Z(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.Z(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.Z(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.Z(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.Z(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.Z(layers, function (layer) { + var orderShift = 0; + forEach/* default */.Z(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.Z(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.Z(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.Z(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 52544: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + k: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(73234); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(79697); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.Z)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(93203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.Z && (1 / (0,_setToArray/* default */.Z)(new _Set/* default */.Z([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.Z(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.Z)(set); + } + isCommon = false; + includes = _cacheHas/* default */.Z; + seen = new _SetCache/* default */.Z; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(836); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.Z)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.Z)(arrays, 1, isArrayLikeObject/* default */.Z, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.Z(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.Z(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.Z(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.Z(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.Z(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.Z(this._nodes); + } + sources() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.Z(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.Z(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.Z(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.Z(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.Z(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.Z(keys/* default */.Z(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.Z(keys/* default */.Z(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.Z(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.Z(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.Z(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.Z(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.Z(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.Z(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.Z(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.Z(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.Z(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.Z(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.Z(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.Z(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.Z(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.Z(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.Z(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.Z(inV); + if (!u) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.Z(outV); + if (!w) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.Z(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 45625: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ k: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.k) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52544); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 39354: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + c: () => (/* binding */ write) +}); + +// UNUSED EXPORTS: read + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/clone.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_clone = (clone); + +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/json.js + + + + + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound(), + }, + nodes: writeNodes(g), + edges: writeEdges(g), + }; + if (!isUndefined/* default */.Z(g.graph())) { + json.value = lodash_es_clone(g.graph()); + } + return json; +} + +function writeNodes(g) { + return map/* default */.Z(g.nodes(), function (v) { + var nodeValue = g.node(v); + var parent = g.parent(v); + var node = { v: v }; + if (!isUndefined/* default */.Z(nodeValue)) { + node.value = nodeValue; + } + if (!isUndefined/* default */.Z(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return map/* default */.Z(g.edges(), function (e) { + var edgeValue = g.edge(e); + var edge = { v: e.v, w: e.w }; + if (!isUndefined/* default */.Z(e.name)) { + edge.name = e.name; + } + if (!isUndefined/* default */.Z(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function (entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function (entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + + +/***/ }), + +/***/ 63001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(37834); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.Z; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 76579: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 68774: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 74073: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 58694: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 48451: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(76579); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(31899); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keys/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keysIn/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(91050); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(87215); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(95695); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.Z)(source, (0,_getSymbols/* default */.Z)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(12513); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(60532); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.Z : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.Z)(result, (0,_getSymbols/* default */.Z)(object)); + object = (0,_getPrototype/* default */.Z)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.Z)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(63327); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.Z)(object, keysIn/* default */.Z, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(41884); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.Z)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(12701); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.Z)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.Z)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(73658); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(98351); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.Z)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.Z)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.Z)(value)) { + return value; + } + var isArr = (0,isArray/* default */.Z)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.Z)(value, result); + } + } else { + var tag = (0,_getTag/* default */.Z)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.Z)(value)) { + return (0,_cloneBuffer/* default */.Z)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.Z)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.Z); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.Z) + : (isFlat ? keysIn/* default */.Z : keys/* default */.Z); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.Z)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.Z)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 49811: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.Z)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.Z); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 21692: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 10626: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(29169); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.Z ? _Symbol/* default */.Z.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.Z)(value) || (0,isArguments/* default */.Z)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.Z)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 2693: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61395); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 13317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 63327: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58694); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 74765: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.Z : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.Z)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(84073); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(79651); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.Z(object), new _Uint8Array/* default */.Z(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.Z)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.Z); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.Z)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.Z)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(18843); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.Z)(object), + othIsArr = (0,isArray/* default */.Z)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.Z)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.Z)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.Z)(object)) { + if (!(0,isBuffer/* default */.Z)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.Z); + return (objIsArr || (0,isTypedArray/* default */.Z)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.Z); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.Z); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.Z)(value) && !(0,isObjectLike/* default */.Z)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.Z; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.Z)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.Z)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.Z)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.Z)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.Z)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.Z)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.Z)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.Z)(path) ? (0,_baseProperty/* default */.Z)((0,_toKey/* default */.Z)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.Z; + } + if (typeof value == 'object') { + return (0,isArray/* default */.Z)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 21018: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49811); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 54193: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 59548: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 68882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69203); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 22823: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(42454); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.Z)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(50751); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.Z)(value)) { + return value; + } + return (0,_isKey/* default */.Z)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.Z)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 1808: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63327); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(95695); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 95695: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68774); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(60532); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 16174: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29169); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27771); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(56009); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1656); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 99365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72714); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 6545: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 62281: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72714); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 3688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69581); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(79651); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50439); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32957); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 13445: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(68774); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.Z)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayFilter/* default */.Z : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.Z)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 27961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10626); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 70870: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76579); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49811); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(68882); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 17452: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 75487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 72714: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93589); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18533); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 49360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 17179: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87668); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39473); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 43836: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74073); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74765); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21018); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 61666: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(22823); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(56009); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.Z)(object)) { + return object; + } + path = (0,_castPath/* default */.Z)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.Z)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.Z)(objValue) + ? objValue + : ((0,_isIndex/* default */.Z)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.Z)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.Z)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.Z)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.Z)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(81211); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(27227); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.Z)((0,_overRest/* default */.Z)(func, undefined, flatten/* default */.Z), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 74379: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.Z)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.Z)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.Z)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.Z)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 92344: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.Z)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.Z); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 60532: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 94099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.Z)(value)) { + return NAN; + } + if ((0,isObject/* default */.Z)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.Z)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 50751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.Z)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.Z)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.Z)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 66749: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50751); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 34148: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.Z)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.Z)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 64589: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record} */ + const left = maybe || (all[hook] = {}) + /** @type {Record | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array} existing + * @param {Array} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function micromark_util_chunked_splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array} list + * List to operate on. + * @param {Array} items + * Items to add to `list`. + * @returns {Array} + * Either `list` or `items`. + */ +function micromark_util_chunked_push(list, items) { + if (list.length > 0) { + micromark_util_chunked_splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array} */ + let parameters + /** @type {Array} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + micromark_util_chunked_splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array} events + * @param {number} eventIndex + * @returns {Record} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record} */ + const gaps = {} + /** @type {Array} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + micromark_util_chunked_splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record} */ + const columnStart = {} + /** @type {Array} */ + const resolveAllConstructs = [] + /** @type {Array} */ + let chunks = [] + /** @type {Array} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array} chunks + * @param {Pick} token + * @returns {Array} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * + * b> + * + * + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`` or `b`). + * @param {TokenType} literalType + * Type when enclosed (``). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * . + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After ` | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After ` | &<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After ` | + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | + * ^^ + * > | + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > |
+ * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after ` | + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | + * ^ + * > | &<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > |
+ * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + *

!^a

+ *

!^a

+ * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | ab + * ^ + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | ab + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | ab + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a c + * ^ + * > | a c + * ^ + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * > | a c + * ^ + * > | a &<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after ` | a c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After ` | a &<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a &<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a &<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a
c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After ` | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array} events + * @returns {Array} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract} Parent + * + * @typedef {Omit & {type: 'fragment', children: Array}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array} transforms + * Tree transforms. + * + * @typedef {Partial} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array} stack + * Stack of nodes. + * @property {Array} tokenStack + * Stack of tokens. + * @property {(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(18464); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-62fc7601.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.Z)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "
"); + } else if (node.type === "strong") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "emphasis") { + return `${node.children.map(output).join("")}`; + } else if (node.type === "paragraph") { + return `

${node.children.map(output).join("")}

`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + " + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_8af3addd.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_8af3addd.J)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 27707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ insertEdge), +/* harmony export */ h: () => (/* binding */ positionEdgeLabel), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(64589); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '" + label + "" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "
"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + img.style.width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = bbox.width + node.padding; + const totalHeight = bbox.height + node.padding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("
") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(//g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc82", edge, edge.labelType); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Moving label abc78 ", edge.id, edge.label, edgeLabels[edge.id]); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc78" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundryNode) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 cutPathAtIntersect", _points, boundryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 checking point", point2, boundryNode); + if (!outsideNode(boundryNode, point2) && !isInside) { + const inter = intersection(boundryNode, lastPointOutside, point2); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 inside", point2, lastPointOutside, inter); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 intersection", inter); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 no intersect", inter, points); + } + isInside = true; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 outside", point2, lastPointOutside); + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 returning points", points); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 InsertEdge: ", edge); + if (head.intersect && tail.intersect) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Last point", + points[points.length - 1], + head, + head.intersect(points[points.length - 1]) + ); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .$0Z; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeStart", edge.arrowTypeStart); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeEnd", edge.arrowTypeEnd); + switch (edge.arrowTypeStart) { + case "arrow_cross": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-crossStart)" + ); + break; + case "arrow_point": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-pointStart)" + ); + break; + case "arrow_barb": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-barbStart)" + ); + break; + case "arrow_circle": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-circleStart)" + ); + break; + case "aggregation": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationStart)" + ); + break; + case "extension": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-extensionStart)" + ); + break; + case "composition": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-compositionStart)" + ); + break; + case "dependency": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyStart)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopStart)" + ); + break; + } + switch (edge.arrowTypeEnd) { + case "arrow_cross": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-crossEnd)"); + break; + case "arrow_point": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-pointEnd)"); + break; + case "arrow_barb": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-barbEnd)"); + break; + case "arrow_circle": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-circleEnd)"); + break; + case "aggregation": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationEnd)" + ); + break; + case "extension": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-extensionEnd)" + ); + break; + case "composition": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-compositionEnd)" + ); + break; + case "dependency": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyEnd)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopEnd)" + ); + break; + } + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 75254: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ f: () => (/* binding */ flowDb), +/* harmony export */ p: () => (/* binding */ parser$1) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 4], $V1 = [1, 3], $V2 = [1, 5], $V3 = [1, 8, 9, 10, 11, 27, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $V4 = [2, 2], $V5 = [1, 13], $V6 = [1, 14], $V7 = [1, 15], $V8 = [1, 16], $V9 = [1, 23], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 49], $Ve = [1, 48], $Vf = [1, 29], $Vg = [1, 30], $Vh = [1, 31], $Vi = [1, 32], $Vj = [1, 33], $Vk = [1, 44], $Vl = [1, 46], $Vm = [1, 42], $Vn = [1, 47], $Vo = [1, 43], $Vp = [1, 50], $Vq = [1, 45], $Vr = [1, 51], $Vs = [1, 52], $Vt = [1, 34], $Vu = [1, 35], $Vv = [1, 36], $Vw = [1, 37], $Vx = [1, 57], $Vy = [1, 8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vz = [1, 61], $VA = [1, 60], $VB = [1, 62], $VC = [8, 9, 11, 73, 75], $VD = [1, 88], $VE = [1, 93], $VF = [1, 92], $VG = [1, 89], $VH = [1, 85], $VI = [1, 91], $VJ = [1, 87], $VK = [1, 94], $VL = [1, 90], $VM = [1, 95], $VN = [1, 86], $VO = [8, 9, 10, 11, 73, 75], $VP = [8, 9, 10, 11, 44, 73, 75], $VQ = [8, 9, 10, 11, 29, 42, 44, 46, 48, 50, 52, 54, 56, 58, 61, 63, 65, 66, 68, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VR = [8, 9, 11, 42, 58, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VS = [42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VT = [1, 121], $VU = [1, 120], $VV = [1, 128], $VW = [1, 142], $VX = [1, 143], $VY = [1, 144], $VZ = [1, 145], $V_ = [1, 130], $V$ = [1, 132], $V01 = [1, 136], $V11 = [1, 137], $V21 = [1, 138], $V31 = [1, 139], $V41 = [1, 140], $V51 = [1, 141], $V61 = [1, 146], $V71 = [1, 147], $V81 = [1, 126], $V91 = [1, 127], $Va1 = [1, 134], $Vb1 = [1, 129], $Vc1 = [1, 133], $Vd1 = [1, 131], $Ve1 = [8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vf1 = [1, 149], $Vg1 = [8, 9, 11], $Vh1 = [8, 9, 10, 11, 14, 42, 58, 86, 102, 103, 106, 108, 111, 112, 113], $Vi1 = [1, 169], $Vj1 = [1, 165], $Vk1 = [1, 166], $Vl1 = [1, 170], $Vm1 = [1, 167], $Vn1 = [1, 168], $Vo1 = [75, 113, 116], $Vp1 = [8, 9, 10, 11, 12, 14, 27, 29, 32, 42, 58, 73, 81, 82, 83, 84, 85, 86, 87, 102, 106, 108, 111, 112, 113], $Vq1 = [10, 103], $Vr1 = [31, 47, 49, 51, 53, 55, 60, 62, 64, 65, 67, 69, 113, 114, 115], $Vs1 = [1, 235], $Vt1 = [1, 233], $Vu1 = [1, 237], $Vv1 = [1, 231], $Vw1 = [1, 232], $Vx1 = [1, 234], $Vy1 = [1, 236], $Vz1 = [1, 238], $VA1 = [1, 255], $VB1 = [8, 9, 11, 103], $VC1 = [8, 9, 10, 11, 58, 81, 102, 103, 106, 107, 108, 109]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "graphConfig": 4, "document": 5, "line": 6, "statement": 7, "SEMI": 8, "NEWLINE": 9, "SPACE": 10, "EOF": 11, "GRAPH": 12, "NODIR": 13, "DIR": 14, "FirstStmtSeperator": 15, "ending": 16, "endToken": 17, "spaceList": 18, "spaceListNewline": 19, "verticeStatement": 20, "separator": 21, "styleStatement": 22, "linkStyleStatement": 23, "classDefStatement": 24, "classStatement": 25, "clickStatement": 26, "subgraph": 27, "textNoTags": 28, "SQS": 29, "text": 30, "SQE": 31, "end": 32, "direction": 33, "acc_title": 34, "acc_title_value": 35, "acc_descr": 36, "acc_descr_value": 37, "acc_descr_multiline_value": 38, "link": 39, "node": 40, "styledVertex": 41, "AMP": 42, "vertex": 43, "STYLE_SEPARATOR": 44, "idString": 45, "DOUBLECIRCLESTART": 46, "DOUBLECIRCLEEND": 47, "PS": 48, "PE": 49, "(-": 50, "-)": 51, "STADIUMSTART": 52, "STADIUMEND": 53, "SUBROUTINESTART": 54, "SUBROUTINEEND": 55, "VERTEX_WITH_PROPS_START": 56, "NODE_STRING[field]": 57, "COLON": 58, "NODE_STRING[value]": 59, "PIPE": 60, "CYLINDERSTART": 61, "CYLINDEREND": 62, "DIAMOND_START": 63, "DIAMOND_STOP": 64, "TAGEND": 65, "TRAPSTART": 66, "TRAPEND": 67, "INVTRAPSTART": 68, "INVTRAPEND": 69, "linkStatement": 70, "arrowText": 71, "TESTSTR": 72, "START_LINK": 73, "edgeText": 74, "LINK": 75, "edgeTextToken": 76, "STR": 77, "MD_STR": 78, "textToken": 79, "keywords": 80, "STYLE": 81, "LINKSTYLE": 82, "CLASSDEF": 83, "CLASS": 84, "CLICK": 85, "DOWN": 86, "UP": 87, "textNoTagsToken": 88, "stylesOpt": 89, "idString[vertex]": 90, "idString[class]": 91, "CALLBACKNAME": 92, "CALLBACKARGS": 93, "HREF": 94, "LINK_TARGET": 95, "STR[link]": 96, "STR[tooltip]": 97, "alphaNum": 98, "DEFAULT": 99, "numList": 100, "INTERPOLATE": 101, "NUM": 102, "COMMA": 103, "style": 104, "styleComponent": 105, "NODE_STRING": 106, "UNIT": 107, "BRKT": 108, "PCT": 109, "idStringToken": 110, "MINUS": 111, "MULT": 112, "UNICODE_TEXT": 113, "TEXT": 114, "TAGSTART": 115, "EDGE_TEXT": 116, "alphaNumToken": 117, "direction_tb": 118, "direction_bt": 119, "direction_rl": 120, "direction_lr": 121, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 8: "SEMI", 9: "NEWLINE", 10: "SPACE", 11: "EOF", 12: "GRAPH", 13: "NODIR", 14: "DIR", 27: "subgraph", 29: "SQS", 31: "SQE", 32: "end", 34: "acc_title", 35: "acc_title_value", 36: "acc_descr", 37: "acc_descr_value", 38: "acc_descr_multiline_value", 42: "AMP", 44: "STYLE_SEPARATOR", 46: "DOUBLECIRCLESTART", 47: "DOUBLECIRCLEEND", 48: "PS", 49: "PE", 50: "(-", 51: "-)", 52: "STADIUMSTART", 53: "STADIUMEND", 54: "SUBROUTINESTART", 55: "SUBROUTINEEND", 56: "VERTEX_WITH_PROPS_START", 57: "NODE_STRING[field]", 58: "COLON", 59: "NODE_STRING[value]", 60: "PIPE", 61: "CYLINDERSTART", 62: "CYLINDEREND", 63: "DIAMOND_START", 64: "DIAMOND_STOP", 65: "TAGEND", 66: "TRAPSTART", 67: "TRAPEND", 68: "INVTRAPSTART", 69: "INVTRAPEND", 72: "TESTSTR", 73: "START_LINK", 75: "LINK", 77: "STR", 78: "MD_STR", 81: "STYLE", 82: "LINKSTYLE", 83: "CLASSDEF", 84: "CLASS", 85: "CLICK", 86: "DOWN", 87: "UP", 90: "idString[vertex]", 91: "idString[class]", 92: "CALLBACKNAME", 93: "CALLBACKARGS", 94: "HREF", 95: "LINK_TARGET", 96: "STR[link]", 97: "STR[tooltip]", 99: "DEFAULT", 101: "INTERPOLATE", 102: "NUM", 103: "COMMA", 106: "NODE_STRING", 107: "UNIT", 108: "BRKT", 109: "PCT", 111: "MINUS", 112: "MULT", 113: "UNICODE_TEXT", 114: "TEXT", 115: "TAGSTART", 116: "EDGE_TEXT", 118: "direction_tb", 119: "direction_bt", 120: "direction_rl", 121: "direction_lr" }, + productions_: [0, [3, 2], [5, 0], [5, 2], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [4, 2], [4, 2], [4, 2], [4, 3], [16, 2], [16, 1], [17, 1], [17, 1], [17, 1], [15, 1], [15, 1], [15, 2], [19, 2], [19, 2], [19, 1], [19, 1], [18, 2], [18, 1], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 9], [7, 6], [7, 4], [7, 1], [7, 2], [7, 2], [7, 1], [21, 1], [21, 1], [21, 1], [20, 3], [20, 4], [20, 2], [20, 1], [40, 1], [40, 5], [41, 1], [41, 3], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 8], [43, 4], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 4], [43, 4], [43, 1], [39, 2], [39, 3], [39, 3], [39, 1], [39, 3], [74, 1], [74, 2], [74, 1], [74, 1], [70, 1], [71, 3], [30, 1], [30, 2], [30, 1], [30, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [28, 1], [28, 2], [28, 1], [28, 1], [24, 5], [25, 5], [26, 2], [26, 4], [26, 3], [26, 5], [26, 3], [26, 5], [26, 5], [26, 7], [26, 2], [26, 4], [26, 2], [26, 4], [26, 4], [26, 6], [22, 5], [23, 5], [23, 5], [23, 9], [23, 9], [23, 7], [23, 7], [100, 1], [100, 3], [89, 1], [89, 3], [104, 1], [104, 2], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [79, 1], [79, 1], [79, 1], [79, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [76, 1], [76, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [45, 1], [45, 2], [98, 1], [98, 2], [33, 1], [33, 1], [33, 1], [33, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 2: + this.$ = []; + break; + case 3: + if (!Array.isArray($$[$0]) || $$[$0].length > 0) { + $$[$0 - 1].push($$[$0]); + } + this.$ = $$[$0 - 1]; + break; + case 4: + case 176: + this.$ = $$[$0]; + break; + case 11: + yy.setDirection("TB"); + this.$ = "TB"; + break; + case 12: + yy.setDirection($$[$0 - 1]); + this.$ = $$[$0 - 1]; + break; + case 27: + this.$ = $$[$0 - 1].nodes; + break; + case 28: + case 29: + case 30: + case 31: + case 32: + this.$ = []; + break; + case 33: + this.$ = yy.addSubGraph($$[$0 - 6], $$[$0 - 1], $$[$0 - 4]); + break; + case 34: + this.$ = yy.addSubGraph($$[$0 - 3], $$[$0 - 1], $$[$0 - 3]); + break; + case 35: + this.$ = yy.addSubGraph(void 0, $$[$0 - 1], void 0); + break; + case 37: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 38: + case 39: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 43: + yy.addLink($$[$0 - 2].stmt, $$[$0], $$[$0 - 1]); + this.$ = { stmt: $$[$0], nodes: $$[$0].concat($$[$0 - 2].nodes) }; + break; + case 44: + yy.addLink($$[$0 - 3].stmt, $$[$0 - 1], $$[$0 - 2]); + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1].concat($$[$0 - 3].nodes) }; + break; + case 45: + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1] }; + break; + case 46: + this.$ = { stmt: $$[$0], nodes: $$[$0] }; + break; + case 47: + this.$ = [$$[$0]]; + break; + case 48: + this.$ = $$[$0 - 4].concat($$[$0]); + break; + case 49: + this.$ = $$[$0]; + break; + case 50: + this.$ = $$[$0 - 2]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 51: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "square"); + break; + case 52: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "doublecircle"); + break; + case 53: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "circle"); + break; + case 54: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "ellipse"); + break; + case 55: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "stadium"); + break; + case 56: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "subroutine"); + break; + case 57: + this.$ = $$[$0 - 7]; + yy.addVertex($$[$0 - 7], $$[$0 - 1], "rect", void 0, void 0, void 0, Object.fromEntries([[$$[$0 - 5], $$[$0 - 3]]])); + break; + case 58: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "cylinder"); + break; + case 59: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "round"); + break; + case 60: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "diamond"); + break; + case 61: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "hexagon"); + break; + case 62: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "odd"); + break; + case 63: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "trapezoid"); + break; + case 64: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "inv_trapezoid"); + break; + case 65: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_right"); + break; + case 66: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_left"); + break; + case 67: + this.$ = $$[$0]; + yy.addVertex($$[$0]); + break; + case 68: + $$[$0 - 1].text = $$[$0]; + this.$ = $$[$0 - 1]; + break; + case 69: + case 70: + $$[$0 - 2].text = $$[$0 - 1]; + this.$ = $$[$0 - 2]; + break; + case 71: + this.$ = $$[$0]; + break; + case 72: + var inf = yy.destructLink($$[$0], $$[$0 - 2]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length, "text": $$[$0 - 1] }; + break; + case 73: + this.$ = { text: $$[$0], type: "text" }; + break; + case 74: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 75: + this.$ = { text: $$[$0], type: "string" }; + break; + case 76: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 77: + var inf = yy.destructLink($$[$0]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length }; + break; + case 78: + this.$ = $$[$0 - 1]; + break; + case 79: + this.$ = { text: $$[$0], type: "text" }; + break; + case 80: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 81: + this.$ = { text: $$[$0], type: "string" }; + break; + case 82: + case 97: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 94: + this.$ = { text: $$[$0], type: "text" }; + break; + case 95: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 96: + this.$ = { text: $$[$0], type: "text" }; + break; + case 98: + this.$ = $$[$0 - 4]; + yy.addClass($$[$0 - 2], $$[$0]); + break; + case 99: + this.$ = $$[$0 - 4]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 100: + case 108: + this.$ = $$[$0 - 1]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 101: + case 109: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 102: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 103: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 4], $$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 104: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 105: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 106: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 107: + this.$ = $$[$0 - 6]; + yy.setLink($$[$0 - 6], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 6], $$[$0 - 2]); + break; + case 110: + this.$ = $$[$0 - 1]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 111: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 112: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + break; + case 113: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 5], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 5], $$[$0 - 2]); + break; + case 114: + this.$ = $$[$0 - 4]; + yy.addVertex($$[$0 - 2], void 0, void 0, $$[$0]); + break; + case 115: + this.$ = $$[$0 - 4]; + yy.updateLink([$$[$0 - 2]], $$[$0]); + break; + case 116: + this.$ = $$[$0 - 4]; + yy.updateLink($$[$0 - 2], $$[$0]); + break; + case 117: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate([$$[$0 - 6]], $$[$0 - 2]); + yy.updateLink([$$[$0 - 6]], $$[$0]); + break; + case 118: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate($$[$0 - 6], $$[$0 - 2]); + yy.updateLink($$[$0 - 6], $$[$0]); + break; + case 119: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate([$$[$0 - 4]], $$[$0]); + break; + case 120: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate($$[$0 - 4], $$[$0]); + break; + case 121: + case 123: + this.$ = [$$[$0]]; + break; + case 122: + case 124: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 126: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 174: + this.$ = $$[$0]; + break; + case 175: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 177: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 178: + this.$ = { stmt: "dir", value: "TB" }; + break; + case 179: + this.$ = { stmt: "dir", value: "BT" }; + break; + case 180: + this.$ = { stmt: "dir", value: "RL" }; + break; + case 181: + this.$ = { stmt: "dir", value: "LR" }; + break; + } + }, + table: [{ 3: 1, 4: 2, 9: $V0, 10: $V1, 12: $V2 }, { 1: [3] }, o($V3, $V4, { 5: 6 }), { 4: 7, 9: $V0, 10: $V1, 12: $V2 }, { 4: 8, 9: $V0, 10: $V1, 12: $V2 }, { 13: [1, 9], 14: [1, 10] }, { 1: [2, 1], 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($V3, [2, 9]), o($V3, [2, 10]), o($V3, [2, 11]), { 8: [1, 54], 9: [1, 55], 10: $Vx, 15: 53, 18: 56 }, o($Vy, [2, 3]), o($Vy, [2, 4]), o($Vy, [2, 5]), o($Vy, [2, 6]), o($Vy, [2, 7]), o($Vy, [2, 8]), { 8: $Vz, 9: $VA, 11: $VB, 21: 58, 39: 59, 70: 63, 73: [1, 64], 75: [1, 65] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 66 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 67 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 68 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 69 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 70 }, { 8: $Vz, 9: $VA, 10: [1, 71], 11: $VB, 21: 72 }, o($Vy, [2, 36]), { 35: [1, 73] }, { 37: [1, 74] }, o($Vy, [2, 39]), o($VC, [2, 46], { 18: 75, 10: $Vx }), { 10: [1, 76] }, { 10: [1, 77] }, { 10: [1, 78] }, { 10: [1, 79] }, { 14: $VD, 42: $VE, 58: $VF, 77: [1, 83], 86: $VG, 92: [1, 80], 94: [1, 81], 98: 82, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, o($Vy, [2, 178]), o($Vy, [2, 179]), o($Vy, [2, 180]), o($Vy, [2, 181]), o($VO, [2, 47]), o($VO, [2, 49], { 44: [1, 96] }), o($VP, [2, 67], { 110: 109, 29: [1, 97], 42: $Vd, 46: [1, 98], 48: [1, 99], 50: [1, 100], 52: [1, 101], 54: [1, 102], 56: [1, 103], 58: $Ve, 61: [1, 104], 63: [1, 105], 65: [1, 106], 66: [1, 107], 68: [1, 108], 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($VQ, [2, 174]), o($VQ, [2, 135]), o($VQ, [2, 136]), o($VQ, [2, 137]), o($VQ, [2, 138]), o($VQ, [2, 139]), o($VQ, [2, 140]), o($VQ, [2, 141]), o($VQ, [2, 142]), o($VQ, [2, 143]), o($VQ, [2, 144]), o($VQ, [2, 145]), o($V3, [2, 12]), o($V3, [2, 18]), o($V3, [2, 19]), { 9: [1, 110] }, o($VR, [2, 26], { 18: 111, 10: $Vx }), o($Vy, [2, 27]), { 40: 112, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vy, [2, 40]), o($Vy, [2, 41]), o($Vy, [2, 42]), o($VS, [2, 71], { 71: 113, 60: [1, 115], 72: [1, 114] }), { 74: 116, 76: 117, 77: [1, 118], 78: [1, 119], 113: $VT, 116: $VU }, o([42, 58, 60, 72, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 77]), o($Vy, [2, 28]), o($Vy, [2, 29]), o($Vy, [2, 30]), o($Vy, [2, 31]), o($Vy, [2, 32]), { 10: $VV, 12: $VW, 14: $VX, 27: $VY, 28: 122, 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 77: [1, 124], 78: [1, 125], 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 123, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Ve1, $V4, { 5: 148 }), o($Vy, [2, 37]), o($Vy, [2, 38]), o($VC, [2, 45], { 42: $Vf1 }), { 42: $Vd, 45: 150, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 99: [1, 151], 100: 152, 102: [1, 153] }, { 42: $Vd, 45: 154, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 42: $Vd, 45: 155, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 100], { 10: [1, 156], 93: [1, 157] }), { 77: [1, 158] }, o($Vg1, [2, 108], { 117: 160, 10: [1, 159], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 110], { 10: [1, 161] }), o($Vh1, [2, 176]), o($Vh1, [2, 163]), o($Vh1, [2, 164]), o($Vh1, [2, 165]), o($Vh1, [2, 166]), o($Vh1, [2, 167]), o($Vh1, [2, 168]), o($Vh1, [2, 169]), o($Vh1, [2, 170]), o($Vh1, [2, 171]), o($Vh1, [2, 172]), o($Vh1, [2, 173]), { 42: $Vd, 45: 162, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 30: 163, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 171, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 173, 48: [1, 172], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 174, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 175, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 176, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 106: [1, 177] }, { 30: 178, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 179, 63: [1, 180], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 181, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 182, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 183, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VQ, [2, 175]), o($V3, [2, 20]), o($VR, [2, 25]), o($VC, [2, 43], { 18: 184, 10: $Vx }), o($VS, [2, 68], { 10: [1, 185] }), { 10: [1, 186] }, { 30: 187, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 75: [1, 188], 76: 189, 113: $VT, 116: $VU }, o($Vo1, [2, 73]), o($Vo1, [2, 75]), o($Vo1, [2, 76]), o($Vo1, [2, 161]), o($Vo1, [2, 162]), { 8: $Vz, 9: $VA, 10: $VV, 11: $VB, 12: $VW, 14: $VX, 21: 191, 27: $VY, 29: [1, 190], 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 192, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Vp1, [2, 94]), o($Vp1, [2, 96]), o($Vp1, [2, 97]), o($Vp1, [2, 150]), o($Vp1, [2, 151]), o($Vp1, [2, 152]), o($Vp1, [2, 153]), o($Vp1, [2, 154]), o($Vp1, [2, 155]), o($Vp1, [2, 156]), o($Vp1, [2, 157]), o($Vp1, [2, 158]), o($Vp1, [2, 159]), o($Vp1, [2, 160]), o($Vp1, [2, 83]), o($Vp1, [2, 84]), o($Vp1, [2, 85]), o($Vp1, [2, 86]), o($Vp1, [2, 87]), o($Vp1, [2, 88]), o($Vp1, [2, 89]), o($Vp1, [2, 90]), o($Vp1, [2, 91]), o($Vp1, [2, 92]), o($Vp1, [2, 93]), { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 193], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vx, 18: 194 }, { 10: [1, 195], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 196] }, { 10: [1, 197], 103: [1, 198] }, o($Vq1, [2, 121]), { 10: [1, 199], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 200], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 77: [1, 201] }, o($Vg1, [2, 102], { 10: [1, 202] }), o($Vg1, [2, 104], { 10: [1, 203] }), { 77: [1, 204] }, o($Vh1, [2, 177]), { 77: [1, 205], 95: [1, 206] }, o($VO, [2, 50], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), { 31: [1, 207], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Vr1, [2, 79]), o($Vr1, [2, 81]), o($Vr1, [2, 82]), o($Vr1, [2, 146]), o($Vr1, [2, 147]), o($Vr1, [2, 148]), o($Vr1, [2, 149]), { 47: [1, 209], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 210, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 49: [1, 211], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 51: [1, 212], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 53: [1, 213], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 55: [1, 214], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 58: [1, 215] }, { 62: [1, 216], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 64: [1, 217], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 218, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 31: [1, 219], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 220], 69: [1, 221], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 223], 69: [1, 222], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VC, [2, 44], { 42: $Vf1 }), o($VS, [2, 70]), o($VS, [2, 69]), { 60: [1, 224], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VS, [2, 72]), o($Vo1, [2, 74]), { 30: 225, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Ve1, $V4, { 5: 226 }), o($Vp1, [2, 95]), o($Vy, [2, 35]), { 41: 227, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 228, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 239, 101: [1, 240], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 241, 101: [1, 242], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 102: [1, 243] }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 244, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 42: $Vd, 45: 245, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 101]), { 77: [1, 246] }, { 77: [1, 247], 95: [1, 248] }, o($Vg1, [2, 109]), o($Vg1, [2, 111], { 10: [1, 249] }), o($Vg1, [2, 112]), o($VP, [2, 51]), o($Vr1, [2, 80]), o($VP, [2, 52]), { 49: [1, 250], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 59]), o($VP, [2, 54]), o($VP, [2, 55]), o($VP, [2, 56]), { 106: [1, 251] }, o($VP, [2, 58]), o($VP, [2, 60]), { 64: [1, 252], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 62]), o($VP, [2, 63]), o($VP, [2, 65]), o($VP, [2, 64]), o($VP, [2, 66]), o([10, 42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 78]), { 31: [1, 253], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 254], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($VO, [2, 48]), o($Vg1, [2, 114], { 103: $VA1 }), o($VB1, [2, 123], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($VC1, [2, 125]), o($VC1, [2, 127]), o($VC1, [2, 128]), o($VC1, [2, 129]), o($VC1, [2, 130]), o($VC1, [2, 131]), o($VC1, [2, 132]), o($VC1, [2, 133]), o($VC1, [2, 134]), o($Vg1, [2, 115], { 103: $VA1 }), { 10: [1, 257] }, o($Vg1, [2, 116], { 103: $VA1 }), { 10: [1, 258] }, o($Vq1, [2, 122]), o($Vg1, [2, 98], { 103: $VA1 }), o($Vg1, [2, 99], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($Vg1, [2, 103]), o($Vg1, [2, 105], { 10: [1, 259] }), o($Vg1, [2, 106]), { 95: [1, 260] }, { 49: [1, 261] }, { 60: [1, 262] }, { 64: [1, 263] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 264 }, o($Vy, [2, 34]), { 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 104: 265, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VC1, [2, 126]), { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 266, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 267, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 95: [1, 268] }, o($Vg1, [2, 113]), o($VP, [2, 53]), { 30: 269, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 61]), o($Ve1, $V4, { 5: 270 }), o($VB1, [2, 124], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($Vg1, [2, 119], { 117: 160, 10: [1, 271], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 120], { 117: 160, 10: [1, 272], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 107]), { 31: [1, 273], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 274], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 275, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 276, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VP, [2, 57]), o($Vy, [2, 33]), o($Vg1, [2, 117], { 103: $VA1 }), o($Vg1, [2, 118], { 103: $VA1 })], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex2() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex2(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex2() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 34; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 36; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + this.begin("callbackname"); + break; + case 8: + this.popState(); + break; + case 9: + this.popState(); + this.begin("callbackargs"); + break; + case 10: + return 92; + case 11: + this.popState(); + break; + case 12: + return 93; + case 13: + return "MD_STR"; + case 14: + this.popState(); + break; + case 15: + this.begin("md_string"); + break; + case 16: + return "STR"; + case 17: + this.popState(); + break; + case 18: + this.pushState("string"); + break; + case 19: + return 81; + case 20: + return 99; + case 21: + return 82; + case 22: + return 101; + case 23: + return 83; + case 24: + return 84; + case 25: + return 94; + case 26: + this.begin("click"); + break; + case 27: + this.popState(); + break; + case 28: + return 85; + case 29: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 30: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 31: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 32: + return 27; + case 33: + return 32; + case 34: + return 95; + case 35: + return 95; + case 36: + return 95; + case 37: + return 95; + case 38: + this.popState(); + return 13; + case 39: + this.popState(); + return 14; + case 40: + this.popState(); + return 14; + case 41: + this.popState(); + return 14; + case 42: + this.popState(); + return 14; + case 43: + this.popState(); + return 14; + case 44: + this.popState(); + return 14; + case 45: + this.popState(); + return 14; + case 46: + this.popState(); + return 14; + case 47: + this.popState(); + return 14; + case 48: + this.popState(); + return 14; + case 49: + return 118; + case 50: + return 119; + case 51: + return 120; + case 52: + return 121; + case 53: + return 102; + case 54: + return 108; + case 55: + return 44; + case 56: + return 58; + case 57: + return 42; + case 58: + return 8; + case 59: + return 103; + case 60: + return 112; + case 61: + this.popState(); + return 75; + case 62: + this.pushState("edgeText"); + return 73; + case 63: + return 116; + case 64: + this.popState(); + return 75; + case 65: + this.pushState("thickEdgeText"); + return 73; + case 66: + return 116; + case 67: + this.popState(); + return 75; + case 68: + this.pushState("dottedEdgeText"); + return 73; + case 69: + return 116; + case 70: + return 75; + case 71: + this.popState(); + return 51; + case 72: + return "TEXT"; + case 73: + this.pushState("ellipseText"); + return 50; + case 74: + this.popState(); + return 53; + case 75: + this.pushState("text"); + return 52; + case 76: + this.popState(); + return 55; + case 77: + this.pushState("text"); + return 54; + case 78: + return 56; + case 79: + this.pushState("text"); + return 65; + case 80: + this.popState(); + return 62; + case 81: + this.pushState("text"); + return 61; + case 82: + this.popState(); + return 47; + case 83: + this.pushState("text"); + return 46; + case 84: + this.popState(); + return 67; + case 85: + this.popState(); + return 69; + case 86: + return 114; + case 87: + this.pushState("trapText"); + return 66; + case 88: + this.pushState("trapText"); + return 68; + case 89: + return 115; + case 90: + return 65; + case 91: + return 87; + case 92: + return "SEP"; + case 93: + return 86; + case 94: + return 112; + case 95: + return 108; + case 96: + return 42; + case 97: + return 106; + case 98: + return 111; + case 99: + return 113; + case 100: + this.popState(); + return 60; + case 101: + this.pushState("text"); + return 60; + case 102: + this.popState(); + return 49; + case 103: + this.pushState("text"); + return 48; + case 104: + this.popState(); + return 31; + case 105: + this.pushState("text"); + return 29; + case 106: + this.popState(); + return 64; + case 107: + this.pushState("text"); + return 63; + case 108: + return "TEXT"; + case 109: + return "QUOTE"; + case 110: + return 9; + case 111: + return 10; + case 112: + return 11; + } + }, + rules: [/^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:[^`"]+)/, /^(?:[`]["])/, /^(?:["][`])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:["])/, /^(?:style\b)/, /^(?:default\b)/, /^(?:linkStyle\b)/, /^(?:interpolate\b)/, /^(?:classDef\b)/, /^(?:class\b)/, /^(?:href[\s])/, /^(?:click[\s]+)/, /^(?:[\s\n])/, /^(?:[^\s\n]*)/, /^(?:flowchart-elk\b)/, /^(?:graph\b)/, /^(?:flowchart\b)/, /^(?:subgraph\b)/, /^(?:end\b\s*)/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:(\r?\n)*\s*\n)/, /^(?:\s*LR\b)/, /^(?:\s*RL\b)/, /^(?:\s*TB\b)/, /^(?:\s*BT\b)/, /^(?:\s*TD\b)/, /^(?:\s*BR\b)/, /^(?:\s*<)/, /^(?:\s*>)/, /^(?:\s*\^)/, /^(?:\s*v\b)/, /^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:[0-9]+)/, /^(?:#)/, /^(?::::)/, /^(?::)/, /^(?:&)/, /^(?:;)/, /^(?:,)/, /^(?:\*)/, /^(?:\s*[xo<]?--+[-xo>]\s*)/, /^(?:\s*[xo<]?--\s*)/, /^(?:[^-]|-(?!-)+)/, /^(?:\s*[xo<]?==+[=xo>]\s*)/, /^(?:\s*[xo<]?==\s*)/, /^(?:[^=]|=(?!))/, /^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/, /^(?:\s*[xo<]?-\.\s*)/, /^(?:[^\.]|\.(?!))/, /^(?:\s*~~[\~]+\s*)/, /^(?:[-/\)][\)])/, /^(?:[^\(\)\[\]\{\}]|(?!\)+))/, /^(?:\(-)/, /^(?:\]\))/, /^(?:\(\[)/, /^(?:\]\])/, /^(?:\[\[)/, /^(?:\[\|)/, /^(?:>)/, /^(?:\)\])/, /^(?:\[\()/, /^(?:\)\)\))/, /^(?:\(\(\()/, /^(?:[\\(?=\])][\]])/, /^(?:\/(?=\])\])/, /^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/, /^(?:\[\/)/, /^(?:\[\\)/, /^(?:<)/, /^(?:>)/, /^(?:\^)/, /^(?:\\\|)/, /^(?:v\b)/, /^(?:\*)/, /^(?:#)/, /^(?:&)/, /^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/, /^(?:-)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\|)/, /^(?:\|)/, /^(?:\))/, /^(?:\()/, /^(?:\])/, /^(?:\[)/, /^(?:(\}))/, /^(?:\{)/, /^(?:[^\[\]\(\)\{\}\|\"]+)/, /^(?:")/, /^(?:(\r?\n)+)/, /^(?:\s)/, /^(?:$)/], + conditions: { "callbackargs": { "rules": [11, 12, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "callbackname": { "rules": [8, 9, 10, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "href": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "click": { "rules": [15, 18, 27, 28, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dottedEdgeText": { "rules": [15, 18, 67, 69, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "thickEdgeText": { "rules": [15, 18, 64, 66, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "edgeText": { "rules": [15, 18, 61, 63, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "trapText": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 84, 85, 86, 87, 88, 101, 103, 105, 107], "inclusive": false }, "ellipseText": { "rules": [15, 18, 70, 71, 72, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "text": { "rules": [15, 18, 70, 73, 74, 75, 76, 77, 80, 81, 82, 83, 87, 88, 100, 101, 102, 103, 104, 105, 106, 107, 108], "inclusive": false }, "vertex": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dir": { "rules": [15, 18, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr_multiline": { "rules": [5, 6, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr": { "rules": [3, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_title": { "rules": [1, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "md_string": { "rules": [13, 14, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "string": { "rules": [15, 16, 17, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 67, 68, 70, 73, 75, 77, 78, 79, 81, 83, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 101, 103, 105, 107, 109, 110, 111, 112], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const MERMAID_DOM_ID_PREFIX = "flowchart-"; +let vertexCounter = 0; +let config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); +let vertices = {}; +let edges = []; +let classes = {}; +let subGraphs = []; +let subGraphLookup = {}; +let tooltips = {}; +let subCount = 0; +let firstGraphFlag = true; +let direction; +let version; +let funs = []; +const sanitizeText = (txt) => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, config); +const lookUpDomId = function(id) { + const veritceKeys = Object.keys(vertices); + for (const veritceKey of veritceKeys) { + if (vertices[veritceKey].id === id) { + return vertices[veritceKey].domId; + } + } + return id; +}; +const addVertex = function(_id, textObj, type, style, classes2, dir, props = {}) { + let txt; + let id = _id; + if (id === void 0) { + return; + } + if (id.trim().length === 0) { + return; + } + if (vertices[id] === void 0) { + vertices[id] = { + id, + labelType: "text", + domId: MERMAID_DOM_ID_PREFIX + id + "-" + vertexCounter, + styles: [], + classes: [] + }; + } + vertexCounter++; + if (textObj !== void 0) { + config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + txt = sanitizeText(textObj.text.trim()); + vertices[id].labelType = textObj.type; + if (txt[0] === '"' && txt[txt.length - 1] === '"') { + txt = txt.substring(1, txt.length - 1); + } + vertices[id].text = txt; + } else { + if (vertices[id].text === void 0) { + vertices[id].text = _id; + } + } + if (type !== void 0) { + vertices[id].type = type; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + vertices[id].styles.push(s); + }); + } + if (classes2 !== void 0 && classes2 !== null) { + classes2.forEach(function(s) { + vertices[id].classes.push(s); + }); + } + if (dir !== void 0) { + vertices[id].dir = dir; + } + if (vertices[id].props === void 0) { + vertices[id].props = props; + } else if (props !== void 0) { + Object.assign(vertices[id].props, props); + } +}; +const addSingleLink = function(_start, _end, type) { + let start = _start; + let end = _end; + const edge = { start, end, type: void 0, text: "", labelType: "text" }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 Got edge...", edge); + const linkTextObj = type.text; + if (linkTextObj !== void 0) { + edge.text = sanitizeText(linkTextObj.text.trim()); + if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { + edge.text = edge.text.substring(1, edge.text.length - 1); + } + edge.labelType = linkTextObj.type; + } + if (type !== void 0) { + edge.type = type.type; + edge.stroke = type.stroke; + edge.length = type.length; + } + if ((edge == null ? void 0 : edge.length) > 10) { + edge.length = 10; + } + if (edges.length < 280) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 pushing edge..."); + edges.push(edge); + } else { + throw new Error("Too many edges"); + } +}; +const addLink = function(_start, _end, type) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("addLink (abc78)", _start, _end, type); + let i, j; + for (i = 0; i < _start.length; i++) { + for (j = 0; j < _end.length; j++) { + addSingleLink(_start[i], _end[j], type); + } + } +}; +const updateLinkInterpolate = function(positions, interp) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultInterpolate = interp; + } else { + edges[pos].interpolate = interp; + } + }); +}; +const updateLink = function(positions, style) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultStyle = style; + } else { + if (_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.isSubstringInArray("fill", style) === -1) { + style.push("fill:none"); + } + edges[pos].style = style; + } + }); +}; +const addClass = function(ids, style) { + ids.split(",").forEach(function(id) { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + if (s.match("color")) { + const newStyle = s.replace("fill", "bgFill").replace("color", "fill"); + classes[id].textStyles.push(newStyle); + } + classes[id].styles.push(s); + }); + } + }); +}; +const setDirection = function(dir) { + direction = dir; + if (direction.match(/.*/)) { + direction = "LR"; + } + if (direction.match(/.*v/)) { + direction = "TB"; + } + if (direction === "TD") { + direction = "TB"; + } +}; +const setClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (vertices[id] !== void 0) { + vertices[id].classes.push(className); + } + if (subGraphLookup[id] !== void 0) { + subGraphLookup[id].classes.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + tooltips[version === "gen-1" ? lookUpDomId(id) : id] = sanitizeText(tooltip); + } + }); +}; +const setClickFun = function(id, functionName, functionArgs) { + let domId = lookUpDomId(id); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(id); + } + if (vertices[id] !== void 0) { + vertices[id].haveCallback = true; + funs.push(function() { + const elem = document.querySelector(`[id="${domId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const setLink = function(ids, linkStr, target) { + ids.split(",").forEach(function(id) { + if (vertices[id] !== void 0) { + vertices[id].link = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + vertices[id].linkTarget = target; + } + }); + setClass(ids, "clickable"); +}; +const getTooltip = function(id) { + if (tooltips.hasOwnProperty(id)) { + return tooltips[id]; + } + return void 0; +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFun(id, functionName, functionArgs); + }); + setClass(ids, "clickable"); +}; +const bindFunctions = function(element) { + funs.forEach(function(fun) { + fun(element); + }); +}; +const getDirection = function() { + return direction.trim(); +}; +const getVertices = function() { + return vertices; +}; +const getEdges = function() { + return edges; +}; +const getClasses = function() { + return classes; +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.top - 14 + document.body.scrollTop + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "
")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + el.classed("hover", false); + }); +}; +funs.push(setupToolTips); +const clear = function(ver = "gen-1") { + vertices = {}; + classes = {}; + edges = []; + funs = [setupToolTips]; + subGraphs = []; + subGraphLookup = {}; + subCount = 0; + tooltips = {}; + firstGraphFlag = true; + version = ver; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.t)(); +}; +const setGen = (ver) => { + version = ver || "gen-2"; +}; +const defaultStyle = function() { + return "fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"; +}; +const addSubGraph = function(_id, list, _title) { + let id = _id.text.trim(); + let title = _title.text; + if (_id === _title && _title.text.match(/\s/)) { + id = void 0; + } + function uniq(a) { + const prims = { boolean: {}, number: {}, string: {} }; + const objs = []; + let dir2; + const nodeList2 = a.filter(function(item) { + const type = typeof item; + if (item.stmt && item.stmt === "dir") { + dir2 = item.value; + return false; + } + if (item.trim() === "") { + return false; + } + if (type in prims) { + return prims[type].hasOwnProperty(item) ? false : prims[type][item] = true; + } else { + return objs.includes(item) ? false : objs.push(item); + } + }); + return { nodeList: nodeList2, dir: dir2 }; + } + let nodeList = []; + const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list)); + nodeList = nl; + if (version === "gen-1") { + for (let i = 0; i < nodeList.length; i++) { + nodeList[i] = lookUpDomId(nodeList[i]); + } + } + id = id || "subGraph" + subCount; + title = title || ""; + title = sanitizeText(title); + subCount = subCount + 1; + const subGraph = { + id, + nodes: nodeList, + title: title.trim(), + classes: [], + dir, + labelType: _title.type + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Adding", subGraph.id, subGraph.nodes, subGraph.dir); + subGraph.nodes = makeUniq(subGraph, subGraphs).nodes; + subGraphs.push(subGraph); + subGraphLookup[id] = subGraph; + return id; +}; +const getPosForId = function(id) { + for (const [i, subGraph] of subGraphs.entries()) { + if (subGraph.id === id) { + return i; + } + } + return -1; +}; +let secCount = -1; +const posCrossRef = []; +const indexNodes2 = function(id, pos) { + const nodes = subGraphs[pos].nodes; + secCount = secCount + 1; + if (secCount > 2e3) { + return; + } + posCrossRef[secCount] = pos; + if (subGraphs[pos].id === id) { + return { + result: true, + count: 0 + }; + } + let count = 0; + let posCount = 1; + while (count < nodes.length) { + const childPos = getPosForId(nodes[count]); + if (childPos >= 0) { + const res = indexNodes2(id, childPos); + if (res.result) { + return { + result: true, + count: posCount + res.count + }; + } else { + posCount = posCount + res.count; + } + } + count = count + 1; + } + return { + result: false, + count: posCount + }; +}; +const getDepthFirstPos = function(pos) { + return posCrossRef[pos]; +}; +const indexNodes = function() { + secCount = -1; + if (subGraphs.length > 0) { + indexNodes2("none", subGraphs.length - 1); + } +}; +const getSubGraphs = function() { + return subGraphs; +}; +const firstGraph = () => { + if (firstGraphFlag) { + firstGraphFlag = false; + return true; + } + return false; +}; +const destructStartLink = (_str) => { + let str = _str.trim(); + let type = "arrow_open"; + switch (str[0]) { + case "<": + type = "arrow_point"; + str = str.slice(1); + break; + case "x": + type = "arrow_cross"; + str = str.slice(1); + break; + case "o": + type = "arrow_circle"; + str = str.slice(1); + break; + } + let stroke = "normal"; + if (str.includes("=")) { + stroke = "thick"; + } + if (str.includes(".")) { + stroke = "dotted"; + } + return { type, stroke }; +}; +const countChar = (char, str) => { + const length = str.length; + let count = 0; + for (let i = 0; i < length; ++i) { + if (str[i] === char) { + ++count; + } + } + return count; +}; +const destructEndLink = (_str) => { + const str = _str.trim(); + let line = str.slice(0, -1); + let type = "arrow_open"; + switch (str.slice(-1)) { + case "x": + type = "arrow_cross"; + if (str[0] === "x") { + type = "double_" + type; + line = line.slice(1); + } + break; + case ">": + type = "arrow_point"; + if (str[0] === "<") { + type = "double_" + type; + line = line.slice(1); + } + break; + case "o": + type = "arrow_circle"; + if (str[0] === "o") { + type = "double_" + type; + line = line.slice(1); + } + break; + } + let stroke = "normal"; + let length = line.length - 1; + if (line[0] === "=") { + stroke = "thick"; + } + if (line[0] === "~") { + stroke = "invisible"; + } + let dots = countChar(".", line); + if (dots) { + stroke = "dotted"; + length = dots; + } + return { type, stroke, length }; +}; +const destructLink = (_str, _startStr) => { + const info = destructEndLink(_str); + let startInfo; + if (_startStr) { + startInfo = destructStartLink(_startStr); + if (startInfo.stroke !== info.stroke) { + return { type: "INVALID", stroke: "INVALID" }; + } + if (startInfo.type === "arrow_open") { + startInfo.type = info.type; + } else { + if (startInfo.type !== info.type) { + return { type: "INVALID", stroke: "INVALID" }; + } + startInfo.type = "double_" + startInfo.type; + } + if (startInfo.type === "double_arrow") { + startInfo.type = "double_arrow_point"; + } + startInfo.length = info.length; + return startInfo; + } + return info; +}; +const exists = (allSgs, _id) => { + let res = false; + allSgs.forEach((sg) => { + const pos = sg.nodes.indexOf(_id); + if (pos >= 0) { + res = true; + } + }); + return res; +}; +const makeUniq = (sg, allSubgraphs) => { + const res = []; + sg.nodes.forEach((_id, pos) => { + if (!exists(allSubgraphs, _id)) { + res.push(sg.nodes[pos]); + } + }); + return { nodes: res }; +}; +const lex = { + firstGraph +}; +const flowDb = { + defaultConfig: () => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.I.flowchart, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.b, + addVertex, + lookUpDomId, + addLink, + updateLinkInterpolate, + updateLink, + addClass, + setDirection, + setClass, + setTooltip, + getTooltip, + setClickEvent, + setLink, + bindFunctions, + getDirection, + getVertices, + getEdges, + getClasses, + clear, + setGen, + defaultStyle, + addSubGraph, + getDepthFirstPos, + indexNodes, + getSubGraphs, + destructLink, + lex, + exists, + makeUniq, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.r +}; +const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addClass, + addLink, + addSingleLink, + addSubGraph, + addVertex, + bindFunctions, + clear, + default: flowDb, + defaultStyle, + destructLink, + firstGraph, + getClasses, + getDepthFirstPos, + getDirection, + getEdges, + getSubGraphs, + getTooltip, + getVertices, + indexNodes, + lex, + lookUpDomId, + setClass, + setClickEvent, + setDirection, + setGen, + setLink, + updateLink, + updateLinkInterpolate +}, Symbol.toStringTag, { value: "Module" })); + + + +/***/ }), + +/***/ 18371: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _flowDb_1972c806_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(75254); +/* harmony import */ var _styles_080da4f6_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(38621); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45625); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(39354); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(20683); + + + + + + + + + + + + + + + + + + + + + +const diagram = { + parser: _flowDb_1972c806_js__WEBPACK_IMPORTED_MODULE_7__.p, + db: _flowDb_1972c806_js__WEBPACK_IMPORTED_MODULE_7__.f, + renderer: _styles_080da4f6_js__WEBPACK_IMPORTED_MODULE_8__.f, + styles: _styles_080da4f6_js__WEBPACK_IMPORTED_MODULE_8__.a, + init: (cnf) => { + if (!cnf.flowchart) { + cnf.flowchart = {}; + } + cnf.flowchart.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_9__.p)({ flowchart: { arrowMarkerAbsolute: cnf.arrowMarkerAbsolute } }); + _styles_080da4f6_js__WEBPACK_IMPORTED_MODULE_8__.f.setConf(cnf.flowchart); + _flowDb_1972c806_js__WEBPACK_IMPORTED_MODULE_7__.f.clear(); + _flowDb_1972c806_js__WEBPACK_IMPORTED_MODULE_7__.f.setGen("gen-2"); + } +}; + + + +/***/ }), + +/***/ 90360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ r: () => (/* binding */ render) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39354); +/* harmony import */ var _edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(27707); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(45625); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(64589); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(64218); + + + + + + + +let clusterDb = {}; +let descendants = {}; +let parents = {}; +const clear$1 = () => { + descendants = {}; + parents = {}; + clusterDb = {}; +}; +const isDescendant = (id, ancenstorId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("In isDecendant", ancenstorId, " ", id, " = ", descendants[ancenstorId].includes(id)); + if (descendants[ancenstorId].includes(id)) { + return true; + } + return false; +}; +const edgeInCluster = (edge, clusterId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Decendants of ", clusterId, " is ", descendants[clusterId]); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge is ", edge); + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } + if (!descendants[clusterId]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Tilt, ", clusterId, ",not in decendants"); + return false; + } + return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w); +}; +const copy = (clusterId, graph, newGraph, rootId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Copying children of ", + clusterId, + "root", + rootId, + "data", + graph.node(clusterId), + rootId + ); + const nodes = graph.children(clusterId) || []; + if (clusterId !== rootId) { + nodes.push(clusterId); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes); + nodes.forEach((node) => { + if (graph.children(node).length > 0) { + copy(node, graph, newGraph, rootId); + } else { + const data = graph.node(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("cp ", node, " to ", rootId, " with parent ", clusterId); + newGraph.setNode(node, data); + if (rootId !== graph.parent(node)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Setting parent", node, graph.parent(node)); + newGraph.setParent(node, graph.parent(node)); + } + if (clusterId !== rootId && node !== clusterId) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Setting parent", node, clusterId); + newGraph.setParent(node, clusterId); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Not Setting parent for node=", + node, + "cluster!==rootId", + clusterId !== rootId, + "node!==clusterId", + node !== clusterId + ); + } + const edges = graph.edges(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Copying Edges", edges); + edges.forEach((edge) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge", edge); + const data2 = graph.edge(edge.v, edge.w, edge.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge data", data2, rootId); + try { + if (edgeInCluster(edge, rootId)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Copying as ", edge.v, edge.w, data2, edge.name); + newGraph.setEdge(edge.v, edge.w, data2, edge.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0])); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Skipping copy of edge ", + edge.v, + "-->", + edge.w, + " rootId: ", + rootId, + " clusterId:", + clusterId + ); + } + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error(e); + } + }); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Removing node", node); + graph.removeNode(node); + }); +}; +const extractDescendants = (id, graph) => { + const children = graph.children(id); + let res = [...children]; + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; + } + return res; +}; +const findNonClusterChild = (id, graph) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching", id); + const children = graph.children(id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching children of id ", id, children); + if (children.length < 1) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("This is a valid node", id); + return id; + } + for (const child of children) { + const _id = findNonClusterChild(child, graph); + if (_id) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Found replacement for", id, " => ", _id); + return _id; + } + } +}; +const getAnchorId = (id) => { + if (!clusterDb[id]) { + return id; + } + if (!clusterDb[id].externalConnections) { + return id; + } + if (clusterDb[id]) { + return clusterDb[id].id; + } + return id; +}; +const adjustClustersAndEdges = (graph, depth) => { + if (!graph || depth > 10) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting out, no graph "); + return; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting in, graph "); + } + graph.nodes().forEach(function(id) { + const children = graph.children(id); + if (children.length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster identified", + id, + " Replacement id in edges: ", + findNonClusterChild(id, graph) + ); + descendants[id] = extractDescendants(id, graph); + clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; + } + }); + graph.nodes().forEach(function(id) { + const children = graph.children(id); + const edges = graph.edges(); + if (children.length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Cluster identified", id, descendants); + edges.forEach((edge) => { + if (edge.v !== id && edge.w !== id) { + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); + if (d1 ^ d2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge: ", edge, " leaves cluster ", id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Decendants of XXX ", id, ": ", descendants[id]); + clusterDb[id].externalConnections = true; + } + } + }); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster ", id, descendants); + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + let v = e.v; + let w = e.w; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Fix XXX", + clusterDb, + "ids:", + e.v, + e.w, + "Translating: ", + clusterDb[e.v], + " --- ", + clusterDb[e.w] + ); + if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + const specialId = e.w + "---" + e.v; + graph.setNode(specialId, { + domId: specialId, + id: specialId, + labelStyle: "", + labelText: edge.label, + padding: 0, + shape: "labelRect", + style: "" + }); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); + edge1.label = ""; + edge1.arrowTypeEnd = "none"; + edge2.label = ""; + edge1.fromCluster = e.v; + edge2.toCluster = e.v; + graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special"); + graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special"); + } else if (clusterDb[e.v] || clusterDb[e.w]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + if (v !== e.v) { + edge.fromCluster = e.v; + } + if (w !== e.w) { + edge.toCluster = e.w; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fix Replacing with XXX", v, w, e.name); + graph.setEdge(v, w, edge, e.name); + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Adjusted Graph", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + extractor(graph, 0); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace(clusterDb); +}; +const extractor = (graph, depth) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("extractor - ", depth, dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph), graph.children("D")); + if (depth > 10) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("Bailing out"); + return; + } + let nodes = graph.nodes(); + let hasChildren = false; + for (const node of nodes) { + const children = graph.children(node); + hasChildren = hasChildren || children.length > 0; + } + if (!hasChildren) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Done, no node has children", graph.nodes()); + return; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Nodes = ", nodes, depth); + for (const node of nodes) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Extracting node", + node, + clusterDb, + clusterDb[node] && !clusterDb[node].externalConnections, + !graph.parent(node), + graph.node(node), + graph.children("D"), + " Depth ", + depth + ); + if (!clusterDb[node]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster", node, depth); + } else if (!clusterDb[node].externalConnections && // !graph.parent(node) && + graph.children(node) && graph.children(node).length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster without external connections, without a parent and with children", + node, + depth + ); + const graphSettings = graph.graph(); + let dir = graphSettings.rankdir === "TB" ? "LR" : "TB"; + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing dir", clusterDb[node].clusterData.dir, dir); + } + const clusterGraph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + // Todo: set proper spacing + nodesep: 50, + ranksep: 50, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Old graph before copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + copy(node, graph, clusterGraph, node); + graph.setNode(node, { + clusterNode: true, + id: node, + clusterData: clusterDb[node].clusterData, + labelText: clusterDb[node].labelText, + graph: clusterGraph + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New graph after copy node: (", node, ")", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(clusterGraph)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Old graph after copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster ** ", + node, + " **not meeting the criteria !externalConnections:", + !clusterDb[node].externalConnections, + " no parent: ", + !graph.parent(node), + " children ", + graph.children(node) && graph.children(node).length > 0, + graph.children("D"), + depth + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(clusterDb); + } + } + nodes = graph.nodes(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New list of nodes", nodes); + for (const node of nodes) { + const data = graph.node(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn(" Now next level", node, data); + if (data.clusterNode) { + extractor(data.graph, depth + 1); + } + } +}; +const sorter = (graph, nodes) => { + if (nodes.length === 0) { + return []; + } + let result = Object.assign(nodes); + nodes.forEach((node) => { + const children = graph.children(node); + const sorted = sorter(graph, children); + result = [...result, ...sorted]; + }); + return result; +}; +const sortNodesByHierarchy = (graph) => sorter(graph, graph.children()); +const rect = (parent, node) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Creating subgraph rect for ", node.id, node); + const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const text = node.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_5__.a)(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild((0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width; + if (node.width <= bbox.width + padding) { + node.diff = (bbox.width - node.width) / 2 - node.padding / 2; + } else { + node.diff = -node.padding / 2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Data ", node, JSON.stringify(node)); + rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding); + if (useHtmlLabels) { + label.attr( + "transform", + // This puts the labal on top of the box instead of inside it + "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2) + ")" + ); + } else { + label.attr( + "transform", + // This puts the labal on top of the box instead of inside it + "translate(" + node.x + ", " + (node.y - node.height / 2) + ")" + ); + } + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const noteGroup = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none"); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const roundedWithTitle = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const innerRect = shapeSvg.append("rect"); + const text = label.node().appendChild((0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + bbox = text.getBBox(); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (bbox.width + node.padding * 0 - node.width) / 2; + } else { + node.diff = -node.padding / 2; + } + rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding); + innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3); + label.attr( + "transform", + "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2 - node.padding / 3 + ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels) ? 5 : 3)) + ")" + ); + const rectBox = rect2.node().getBBox(); + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const divider = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.diff = -node.padding / 2; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const shapes = { rect, roundedWithTitle, noteGroup, divider }; +let clusterElems = {}; +const insertCluster = (elem, node) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Inserting cluster"); + const shape = node.shape || "rect"; + clusterElems[node.id] = shapes[shape](elem, node); +}; +const clear = () => { + clusterElems = {}; +}; +const recursiveRender = async (_elem, graph, diagramtype, id, parentCluster) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph in recursive render: XXX", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph), parentCluster); + const dir = graph.graph().rankdir; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Dir in recursive render - dir:", dir); + const elem = _elem.insert("g").attr("class", "root"); + if (!graph.nodes()) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("No nodes found for", graph); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Recursive render XXX", graph.nodes()); + } + if (graph.edges().length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Recursive edges", graph.edge(graph.edges()[0])); + } + const clusters = elem.insert("g").attr("class", "clusters"); + const edgePaths = elem.insert("g").attr("class", "edgePaths"); + const edgeLabels = elem.insert("g").attr("class", "edgeLabels"); + const nodes = elem.insert("g").attr("class", "nodes"); + await Promise.all( + graph.nodes().map(async function(v) { + const node = graph.node(v); + if (parentCluster !== void 0) { + const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Setting data for cluster XXX (", v, ") ", data, parentCluster); + graph.setNode(parentCluster.id, data); + if (!graph.parent(v)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Setting parent", v, parentCluster.id); + graph.setParent(v, parentCluster.id, data); + } + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v))); + if (node && node.clusterNode) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster identified", v, node.width, graph.node(v)); + const o = await recursiveRender(nodes, node.graph, diagramtype, id, graph.node(v)); + const newEl = o.elem; + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.u)(node, newEl); + node.diff = o.diff || 0; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node bounds (abc123)", v, node, node.width, node.x, node.y); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.s)(newEl, node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Recursive render complete ", newEl, node); + } else { + if (graph.children(v).length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster - the non recursive path XXX", v, node.id, node, graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(findNonClusterChild(node.id, graph)); + clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node - the non recursive path", v, node.id, node); + await (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, graph.node(v), dir); + } + } + }) + ); + graph.edges().forEach(function(e) { + const edge = graph.edge(e.v, e.w, e.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e))); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Fix", clusterDb, "ids:", e.v, e.w, "Translateing: ", clusterDb[e.v], clusterDb[e.w]); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.f)(edgeLabels, edge); + }); + graph.edges().forEach(function(e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("### Layout ###"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(graph); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__/* .layout */ .bK)(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph after layout:", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + let diff = 0; + sortNodesByHierarchy(graph).forEach(function(v) { + const node = graph.node(v); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Position " + v + ": " + JSON.stringify(graph.node(v))); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Position " + v + ": (" + node.x, + "," + node.y, + ") width: ", + node.width, + " height: ", + node.height + ); + if (node && node.clusterNode) { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } else { + if (graph.children(v).length > 0) { + insertCluster(clusters, node); + clusterDb[node.id].node = node; + } else { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge); + const paths = (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.g)(edgePaths, e, edge, clusterDb, diagramtype, graph, id); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.h)(edge, paths); + }); + graph.nodes().forEach(function(v) { + const n = graph.node(v); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(v, n.type, n.diff); + if (n.type === "group") { + diff = n.diff; + } + }); + return { elem, diff }; +}; +const render = async (elem, graph, markers, diagramtype, id) => { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.a)(elem, markers, diagramtype, id); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.b)(); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.d)(); + clear(); + clear$1(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph at first:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph))); + adjustClustersAndEdges(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph after:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph))); + await recursiveRender(elem, graph, diagramtype, id); +}; + + + +/***/ }), + +/***/ 38621: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ flowStyles), + f: () => (/* binding */ flowRendererV2) +}); + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +// EXTERNAL MODULE: ./node_modules/d3/src/index.js + 197 modules +var src = __webpack_require__(64218); +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +// EXTERNAL MODULE: ./node_modules/mermaid/dist/index-2c4b9a3b.js +var index_2c4b9a3b = __webpack_require__(90360); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/dagre-js/label/add-html-label.js +var add_html_label = __webpack_require__(43349); +// EXTERNAL MODULE: ./node_modules/khroma/dist/utils/index.js + 3 modules +var utils = __webpack_require__(61691); +// EXTERNAL MODULE: ./node_modules/khroma/dist/color/index.js + 4 modules +var dist_color = __webpack_require__(71610); +;// CONCATENATED MODULE: ./node_modules/khroma/dist/methods/channel.js +/* IMPORT */ + + +/* MAIN */ +const channel = (color, channel) => { + return utils/* default */.Z.lang.round(dist_color/* default */.Z.parse(color)[channel]); +}; +/* EXPORT */ +/* harmony default export */ const methods_channel = (channel); + +// EXTERNAL MODULE: ./node_modules/khroma/dist/methods/rgba.js +var rgba = __webpack_require__(51117); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/styles-080da4f6.js + + + + + + +const conf = {}; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + for (const key of keys) { + conf[key] = cnf[key]; + } +}; +const addVertices = function(vert, g, svgId, root, doc, diagObj) { + const svg = root.select(`[id="${svgId}"]`); + const keys = Object.keys(vert); + keys.forEach(function(id) { + const vertex = vert[id]; + let classStr = "default"; + if (vertex.classes.length > 0) { + classStr = vertex.classes.join(" "); + } + classStr = classStr + " flowchart-label"; + const styles = (0,mermaid_8af3addd.k)(vertex.styles); + let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; + let vertexNode; + mermaid_8af3addd.l.info("vertex", vertex, vertex.labelType); + if (vertex.labelType === "markdown") { + mermaid_8af3addd.l.info("vertex", vertex, vertex.labelType); + } else { + if ((0,mermaid_8af3addd.m)((0,mermaid_8af3addd.c)().flowchart.htmlLabels)) { + const node = { + label: vertexText.replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `` + ) + }; + vertexNode = (0,add_html_label/* addHtmlLabel */.a)(svg, node).node(); + vertexNode.parentNode.removeChild(vertexNode); + } else { + const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", styles.labelStyle.replace("color:", "fill:")); + const rows = vertexText.split(mermaid_8af3addd.e.lineBreakRegex); + for (const row of rows) { + const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "1"); + tspan.textContent = row; + svgLabel.appendChild(tspan); + } + vertexNode = svgLabel; + } + } + let radious = 0; + let _shape = ""; + switch (vertex.type) { + case "round": + radious = 5; + _shape = "rect"; + break; + case "square": + _shape = "rect"; + break; + case "diamond": + _shape = "question"; + break; + case "hexagon": + _shape = "hexagon"; + break; + case "odd": + _shape = "rect_left_inv_arrow"; + break; + case "lean_right": + _shape = "lean_right"; + break; + case "lean_left": + _shape = "lean_left"; + break; + case "trapezoid": + _shape = "trapezoid"; + break; + case "inv_trapezoid": + _shape = "inv_trapezoid"; + break; + case "odd_right": + _shape = "rect_left_inv_arrow"; + break; + case "circle": + _shape = "circle"; + break; + case "ellipse": + _shape = "ellipse"; + break; + case "stadium": + _shape = "stadium"; + break; + case "subroutine": + _shape = "subroutine"; + break; + case "cylinder": + _shape = "cylinder"; + break; + case "group": + _shape = "rect"; + break; + case "doublecircle": + _shape = "doublecircle"; + break; + default: + _shape = "rect"; + } + g.setNode(vertex.id, { + labelStyle: styles.labelStyle, + shape: _shape, + labelText: vertexText, + labelType: vertex.labelType, + rx: radious, + ry: radious, + class: classStr, + style: styles.style, + id: vertex.id, + link: vertex.link, + linkTarget: vertex.linkTarget, + tooltip: diagObj.db.getTooltip(vertex.id) || "", + domId: diagObj.db.lookUpDomId(vertex.id), + haveCallback: vertex.haveCallback, + width: vertex.type === "group" ? 500 : void 0, + dir: vertex.dir, + type: vertex.type, + props: vertex.props, + padding: (0,mermaid_8af3addd.c)().flowchart.padding + }); + mermaid_8af3addd.l.info("setNode", { + labelStyle: styles.labelStyle, + labelType: vertex.labelType, + shape: _shape, + labelText: vertexText, + rx: radious, + ry: radious, + class: classStr, + style: styles.style, + id: vertex.id, + domId: diagObj.db.lookUpDomId(vertex.id), + width: vertex.type === "group" ? 500 : void 0, + type: vertex.type, + dir: vertex.dir, + props: vertex.props, + padding: (0,mermaid_8af3addd.c)().flowchart.padding + }); + }); +}; +const addEdges = function(edges, g, diagObj) { + mermaid_8af3addd.l.info("abc78 edges = ", edges); + let cnt = 0; + let linkIdCnt = {}; + let defaultStyle; + let defaultLabelStyle; + if (edges.defaultStyle !== void 0) { + const defaultStyles = (0,mermaid_8af3addd.k)(edges.defaultStyle); + defaultStyle = defaultStyles.style; + defaultLabelStyle = defaultStyles.labelStyle; + } + edges.forEach(function(edge) { + cnt++; + const linkIdBase = "L-" + edge.start + "-" + edge.end; + if (linkIdCnt[linkIdBase] === void 0) { + linkIdCnt[linkIdBase] = 0; + mermaid_8af3addd.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } else { + linkIdCnt[linkIdBase]++; + mermaid_8af3addd.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } + let linkId = linkIdBase + "-" + linkIdCnt[linkIdBase]; + mermaid_8af3addd.l.info("abc78 new link id to be used is", linkIdBase, linkId, linkIdCnt[linkIdBase]); + const linkNameStart = "LS-" + edge.start; + const linkNameEnd = "LE-" + edge.end; + const edgeData = { style: "", labelStyle: "" }; + edgeData.minlen = edge.length || 1; + if (edge.type === "arrow_open") { + edgeData.arrowhead = "none"; + } else { + edgeData.arrowhead = "normal"; + } + edgeData.arrowTypeStart = "arrow_open"; + edgeData.arrowTypeEnd = "arrow_open"; + switch (edge.type) { + case "double_arrow_cross": + edgeData.arrowTypeStart = "arrow_cross"; + case "arrow_cross": + edgeData.arrowTypeEnd = "arrow_cross"; + break; + case "double_arrow_point": + edgeData.arrowTypeStart = "arrow_point"; + case "arrow_point": + edgeData.arrowTypeEnd = "arrow_point"; + break; + case "double_arrow_circle": + edgeData.arrowTypeStart = "arrow_circle"; + case "arrow_circle": + edgeData.arrowTypeEnd = "arrow_circle"; + break; + } + let style = ""; + let labelStyle = ""; + switch (edge.stroke) { + case "normal": + style = "fill:none;"; + if (defaultStyle !== void 0) { + style = defaultStyle; + } + if (defaultLabelStyle !== void 0) { + labelStyle = defaultLabelStyle; + } + edgeData.thickness = "normal"; + edgeData.pattern = "solid"; + break; + case "dotted": + edgeData.thickness = "normal"; + edgeData.pattern = "dotted"; + edgeData.style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; + break; + case "thick": + edgeData.thickness = "thick"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 3.5px;fill:none;"; + break; + case "invisible": + edgeData.thickness = "invisible"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 0;fill:none;"; + break; + } + if (edge.style !== void 0) { + const styles = (0,mermaid_8af3addd.k)(edge.style); + style = styles.style; + labelStyle = styles.labelStyle; + } + edgeData.style = edgeData.style += style; + edgeData.labelStyle = edgeData.labelStyle += labelStyle; + if (edge.interpolate !== void 0) { + edgeData.curve = (0,mermaid_8af3addd.n)(edge.interpolate, src/* curveLinear */.c_6); + } else if (edges.defaultInterpolate !== void 0) { + edgeData.curve = (0,mermaid_8af3addd.n)(edges.defaultInterpolate, src/* curveLinear */.c_6); + } else { + edgeData.curve = (0,mermaid_8af3addd.n)(conf.curve, src/* curveLinear */.c_6); + } + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + } + edgeData.labelType = edge.labelType; + edgeData.label = edge.text.replace(mermaid_8af3addd.e.lineBreakRegex, "\n"); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none;"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + edgeData.id = linkId; + edgeData.classes = "flowchart-link " + linkNameStart + " " + linkNameEnd; + g.setEdge(edge.start, edge.end, edgeData, cnt); + }); +}; +const getClasses = function(text, diagObj) { + return diagObj.db.getClasses(); +}; +const draw = async function(text, id, _version, diagObj) { + mermaid_8af3addd.l.info("Drawing flowchart"); + let dir = diagObj.db.getDirection(); + if (dir === void 0) { + dir = "TD"; + } + const { securityLevel, flowchart: conf2 } = (0,mermaid_8af3addd.c)(); + const nodeSpacing = conf2.nodeSpacing || 50; + const rankSpacing = conf2.rankSpacing || 50; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,src/* select */.Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,src/* select */.Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,src/* select */.Ys)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const g = new graphlib/* Graph */.k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 0, + marginy: 0 + }).setDefaultEdgeLabel(function() { + return {}; + }); + let subG; + const subGraphs = diagObj.db.getSubGraphs(); + mermaid_8af3addd.l.info("Subgraphs - ", subGraphs); + for (let i2 = subGraphs.length - 1; i2 >= 0; i2--) { + subG = subGraphs[i2]; + mermaid_8af3addd.l.info("Subgraph - ", subG); + diagObj.db.addVertex( + subG.id, + { text: subG.title, type: subG.labelType }, + "group", + void 0, + subG.classes, + subG.dir + ); + } + const vert = diagObj.db.getVertices(); + const edges = diagObj.db.getEdges(); + mermaid_8af3addd.l.info("Edges", edges); + let i = 0; + for (i = subGraphs.length - 1; i >= 0; i--) { + subG = subGraphs[i]; + (0,src/* selectAll */.td_)("cluster").append("text"); + for (let j = 0; j < subG.nodes.length; j++) { + mermaid_8af3addd.l.info("Setting up subgraphs", subG.nodes[j], subG.id); + g.setParent(subG.nodes[j], subG.id); + } + } + addVertices(vert, g, id, root, doc, diagObj); + addEdges(edges, g); + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + await (0,index_2c4b9a3b.r)(element, g, ["point", "circle", "cross"], "flowchart", id); + mermaid_8af3addd.u.insertTitle(svg, "flowchartTitleText", conf2.titleTopMargin, diagObj.db.getDiagramTitle()); + (0,mermaid_8af3addd.o)(g, svg, conf2.diagramPadding, conf2.useMaxWidth); + diagObj.db.indexNodes("subGraph" + i); + if (!conf2.htmlLabels) { + const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } + } + const keys = Object.keys(vert); + keys.forEach(function(key) { + const vertex = vert[key]; + if (vertex.link) { + const node = (0,src/* select */.Ys)("#" + id + ' [id="' + key + '"]'); + if (node) { + const link = doc.createElementNS("http://www.w3.org/2000/svg", "a"); + link.setAttributeNS("http://www.w3.org/2000/svg", "class", vertex.classes.join(" ")); + link.setAttributeNS("http://www.w3.org/2000/svg", "href", vertex.link); + link.setAttributeNS("http://www.w3.org/2000/svg", "rel", "noopener"); + if (securityLevel === "sandbox") { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", "_top"); + } else if (vertex.linkTarget) { + link.setAttributeNS("http://www.w3.org/2000/svg", "target", vertex.linkTarget); + } + const linkNode = node.insert(function() { + return link; + }, ":first-child"); + const shape = node.select(".label-container"); + if (shape) { + linkNode.append(function() { + return shape.node(); + }); + } + const label = node.select(".label"); + if (label) { + linkNode.append(function() { + return label.node(); + }); + } + } + } + }); +}; +const flowRendererV2 = { + setConf, + addVertices, + addEdges, + getClasses, + draw +}; +const fade = (color, opacity) => { + const channel = methods_channel; + const r = channel(color, "r"); + const g = channel(color, "g"); + const b = channel(color, "b"); + return rgba/* default */.Z(r, g, b, opacity); +}; +const getStyles = (options) => `.label { + font-family: ${options.fontFamily}; + color: ${options.nodeTextColor || options.textColor}; + } + .cluster-label text { + fill: ${options.titleColor}; + } + .cluster-label span,p { + color: ${options.titleColor}; + } + + .label text,span,p { + fill: ${options.nodeTextColor || options.textColor}; + color: ${options.nodeTextColor || options.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + .flowchart-label text { + text-anchor: middle; + } + // .flowchart-label .text-outer-tspan { + // text-anchor: middle; + // } + // .flowchart-label .text-inner-tspan { + // text-anchor: start; + // } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.5; + background-color: ${options.edgeLabelBackground}; + fill: ${options.edgeLabelBackground}; + } + text-align: center; + } + + /* For html labels only */ + .labelBkg { + background-color: ${fade(options.edgeLabelBackground, 0.5)}; + // background-color: + } + + .cluster rect { + fill: ${options.clusterBkg}; + stroke: ${options.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${options.titleColor}; + } + + .cluster span,p { + color: ${options.titleColor}; + } + /* .cluster div { + color: ${options.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${options.fontFamily}; + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } +`; +const flowStyles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/3720c009.0851b2e0.js b/assets/js/3720c009.0851b2e0.js deleted file mode 100644 index ff215ddf9..000000000 --- a/assets/js/3720c009.0851b2e0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3751],{10727:(e,t,a)=>{a.r(t),a.d(t,{default:()=>u});var l=a(67294),n=a(86010),r=a(35155),c=a(10833),s=a(35281),m=a(7452),o=a(26090),i=a(90197);function u(e){let{tags:t}=e;const a=(0,r.M)();return l.createElement(c.FG,{className:(0,n.Z)(s.k.wrapper.docsPages,s.k.page.docsTagsListPage)},l.createElement(c.d,{title:a}),l.createElement(i.Z,{tag:"doc_tags_list"}),l.createElement(m.Z,null,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement("main",{className:"col col--8 col--offset-2"},l.createElement("h1",null,a),l.createElement(o.Z,{tags:t}))))))}},13008:(e,t,a)=>{a.d(t,{Z:()=>o});var l=a(67294),n=a(86010),r=a(39960);const c="tag_zVej",s="tagRegular_sFm0",m="tagWithCount_h2kH";function o(e){let{permalink:t,label:a,count:o}=e;return l.createElement(r.Z,{href:t,className:(0,n.Z)(c,o?m:s)},a,o&&l.createElement("span",null,o))}},26090:(e,t,a)=>{a.d(t,{Z:()=>m});var l=a(67294),n=a(35155),r=a(13008);const c="tag_Nnez";function s(e){let{letterEntry:t}=e;return l.createElement("article",null,l.createElement("h2",null,t.letter),l.createElement("ul",{className:"padding--none"},t.tags.map((e=>l.createElement("li",{key:e.permalink,className:c},l.createElement(r.Z,e))))),l.createElement("hr",null))}function m(e){let{tags:t}=e;const a=(0,n.P)(t);return l.createElement("section",{className:"margin-vert--lg"},a.map((e=>l.createElement(s,{key:e.letter,letterEntry:e}))))}},35155:(e,t,a)=>{a.d(t,{M:()=>n,P:()=>r});var l=a(95999);const n=()=>(0,l.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});function r(e){const t={};return Object.values(e).forEach((e=>{const a=function(e){return e[0].toUpperCase()}(e.label);t[a]??=[],t[a].push(e)})),Object.entries(t).sort(((e,t)=>{let[a]=e,[l]=t;return a.localeCompare(l)})).map((e=>{let[t,a]=e;return{letter:t,tags:a.sort(((e,t)=>e.label.localeCompare(t.label)))}}))}}}]); \ No newline at end of file diff --git a/assets/js/3720c009.e6613bd8.js b/assets/js/3720c009.e6613bd8.js new file mode 100644 index 000000000..36f95fb2a --- /dev/null +++ b/assets/js/3720c009.e6613bd8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3751],{10727:(t,e,s)=>{s.r(e),s.d(e,{default:()=>d});s(67294);var a=s(86010),r=s(10833),l=s(35281),n=s(35155),c=s(26090),i=s(90197),g=s(92503),o=s(85893);function u(t){let{title:e}=t;return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(r.d,{title:e}),(0,o.jsx)(i.Z,{tag:"doc_tags_list"})]})}function h(t){let{tags:e,title:s}=t;return(0,o.jsx)(r.FG,{className:(0,a.Z)(l.k.page.docsTagsListPage),children:(0,o.jsx)("div",{className:"container margin-vert--lg",children:(0,o.jsx)("div",{className:"row",children:(0,o.jsxs)("main",{className:"col col--8 col--offset-2",children:[(0,o.jsx)(g.Z,{as:"h1",children:s}),(0,o.jsx)(c.Z,{tags:e})]})})})})}function d(t){const e=(0,n.M)();return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(u,{...t,title:e}),(0,o.jsx)(h,{...t,title:e})]})}},13008:(t,e,s)=>{s.d(e,{Z:()=>c});s(67294);var a=s(86010),r=s(39960);const l={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var n=s(85893);function c(t){let{permalink:e,label:s,count:c}=t;return(0,n.jsxs)(r.Z,{href:e,className:(0,a.Z)(l.tag,c?l.tagWithCount:l.tagRegular),children:[s,c&&(0,n.jsx)("span",{children:c})]})}},26090:(t,e,s)=>{s.d(e,{Z:()=>g});s(67294);var a=s(35155),r=s(13008),l=s(92503);const n={tag:"tag_Nnez"};var c=s(85893);function i(t){let{letterEntry:e}=t;return(0,c.jsxs)("article",{children:[(0,c.jsx)(l.Z,{as:"h2",id:e.letter,children:e.letter}),(0,c.jsx)("ul",{className:"padding--none",children:e.tags.map((t=>(0,c.jsx)("li",{className:n.tag,children:(0,c.jsx)(r.Z,{...t})},t.permalink)))}),(0,c.jsx)("hr",{})]})}function g(t){let{tags:e}=t;const s=(0,a.P)(e);return(0,c.jsx)("section",{className:"margin-vert--lg",children:s.map((t=>(0,c.jsx)(i,{letterEntry:t},t.letter)))})}},35155:(t,e,s)=>{s.d(e,{M:()=>r,P:()=>l});var a=s(95999);const r=()=>(0,a.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"});function l(t){const e={};return Object.values(t).forEach((t=>{const s=function(t){return t[0].toUpperCase()}(t.label);e[s]??=[],e[s].push(t)})),Object.entries(e).sort(((t,e)=>{let[s]=t,[a]=e;return s.localeCompare(a)})).map((t=>{let[e,s]=t;return{letter:e,tags:s.sort(((t,e)=>t.label.localeCompare(e.label)))}}))}}}]); \ No newline at end of file diff --git a/assets/js/372ccfe9.2d5d0a9f.js b/assets/js/372ccfe9.2d5d0a9f.js new file mode 100644 index 000000000..51cebaaeb --- /dev/null +++ b/assets/js/372ccfe9.2d5d0a9f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9111],{21063:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>l,toc:()=>a});var t=r(85893),o=r(3905);const c={title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",slug:"book-writer",tags:["Book"]},i=void 0,l={permalink:"/book-writer",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",source:"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",description:"\ucc45 \uc815\ubcf4",date:"2023-01-01T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 1\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:4.425,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",slug:"book-writer",tags:["Book"]},unlisted:!1,prevItem:{title:"2022\ub144 \ud68c\uace0",permalink:"/2022-retrospective"}},s={authorsImageUrls:[]},a=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}];function u(e){const n={blockquote:"blockquote",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\ucc45-\uc815\ubcf4",children:"\ucc45 \uc815\ubcf4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc15\uc194\ubbf8"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc77d\uace0-\ub098\uc11c",children:"\uc77d\uace0 \ub098\uc11c"}),"\n",(0,t.jsxs)(n.p,{children:["\uc800\uc790\uc758 \uacbd\ud5d8\uacfc \ud568\uaed8 \uae00\uc4f0\uae30\uc5d0 \ub300\ud55c \uac00\ubcbc\uc6b4 \uc870\uc5b8\uc774 \ub2f4\uaca8\uc788\uc5b4 \uac00\ubccd\uac8c \uc77d\uae30 \uc88b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae00\uc744 \uc798 \uc791\uc131\ud574 \ubcf4\uace0 \uc2f6\uc744 \ub54c \uc801\uc6a9\ud574 \ubcfc \uc218 \uc788\ub294 \uc815\ubcf4\uac00 \ub9ce\uc544\uc11c \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\uc758 \ud504\ub9ac\ucf54\uc2a4\ub97c \uc9c4\ud589\ud560 \ub54c \ud6c4\uae30\ub97c \uc791\uc131\ud558\uace0 \ub098\uba74 \ud56d\uc0c1 \uae00\uc774 \ub531\ub531\ud558\ub2e4\ub294 \ub290\ub08c\uc744 \ubc1b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub2e4\ub978 \uc9c0\uc6d0\uc790\ub4e4\uc758 \uc77d\uae30 \ud3b8\ud558\uace0, \ubc1d\uc740 \ub290\ub08c\uc744 \uc8fc\ub294 \uae00\uc744 \ubcf4\uba74 \ubd80\ub7ec\uc6b4 \ub9c8\uc74c\uc744 \uac00\uc9c0\uae30\ub3c4 \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \ucc45\uc744 \uc77d\uc5c8\uc73c\ub2c8 2023\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae00\uc744 \uc798 \uc801\uc5b4\ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",children:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ubb38\uc7a5\uc774 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74\n\ub0b4\uc6a9\uc744 \uc77c\ubaa9\uc694\uc5f0\ud558\uac8c \uc815\ub9ac\ud588\uace0, \uae00\uc758 \uc758\ub3c4\ub3c4 \uc090\ub6a4\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub3c4 \uc801\uc808\ud55c \uac83\uc73c\ub85c \uace8\ub790\ub294\ub370\u2026 \uadf8\ub7f0\ub370\ub3c4 \uc5b4\ub518\uac00\uac00 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74? \ucd95\ucd95 \ucc98\uc9c0\uace0 \ub530\ubd84\ud558\ub2e4\uba74? \ub9d0\uaf2c\ub9ac\ub97c \ubaa8\uc870\ub9ac \u2018~\ub2e4\u2019\ub85c \ud1b5\uc77c\ud55c \uac74 \uc544\ub2cc\uc9c0 \uc810\uac80\ud574 \ubcf4\uc138\uc694."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ub9d0\uaf2c\ub9ac\ub97c \uc798 \uac16\uace0 \ub180\uc544\uc57c \ud569\ub2c8\ub2e4. \ubb38\uc7a5\uc758 \ub9c8\uc9c0\ub9c9 \uae00\uc790\ub97c \ub9e4\ubc88 \ub2e4\ub974\uac8c \uace0\uccd0\uc4f0\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uae00\uc5d0 \ud65c\uae30\ub97c \ub354\ud560 \uc218 \uc788\uc8e0. \ub54c\ub860 \ubb38\uc7a5\uc744 \ub2e4 \ub9c8\uce58\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub85c\ub9cc \ub05d\ub9fa\ub294 \uac83\ub3c4 \ubc29\ubc95. \ubb38\uc7a5\uacfc \ubb38\uc7a5 \uc0ac\uc774\uc5d0 \uc27c\ud45c\uac00 \ub4e4\uc5b4\uc11c\uba70 \uae00 \uc804\uccb4\uc5d0 \ud65c\uae30\uac00 \ub3cc\uac8c \ub3fc\uc694. \ubb38\uc7a5\uc758 \uae38\uc774\ub3c4 \ub2e4\ucc44\ub85c\uc6cc\uc9c0\ub294 \ub355\ubd84\uc5d0 \ub364\uc73c\ub85c \uc5bb\uac8c \ub418\ub294 \uac83\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ubc14\ub85c, \uae00\uc758 \ub9ac\ub4ec."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uc774\uc804 \ubb38\uc7a5\uc5d0\uc11c \ub05d\ub09c \uae00\uc790\ub85c, \ub2e4\uc74c \ubb38\uc7a5\uc744 \ub05d\ub9fa\uc9c0 \uc54a\uae30. \ud55c\ub450 \ubb38\ub2e8\ub9c8\ub2e4 \ub2e8\uc5b4 \uc218\uc900\uc758 \uc544\uc8fc \uc9e7\uc740 \ubb38\uc7a5 \ubc30\uce58\ud558\uae30."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uae00\uc758 \uc9c4\uc9dc \uc774\uc720, \uae00\uc758 \uc9c4\uc9dc \ubaa9\uc801, \uae00\uc758 \uc9c4\uc9dc \ub300\uc0c1\uc744 \ucc3e\uc73c\ub824\uace0 \uc560\uc37c\uc2b5\ub2c8\ub2e4. \uc9c0\uae08\ucc98\ub7fc \ud2c0\uc744 \ub5a0\uc62c\ub9b0\ub2e4\uac70\ub098, \ub208\uce58\ub97c \ubcf8\ub2e4\uac70\ub098, \uc815\uce58\uc801\uc778 \uc148\ub3c4 \ud558\uc9c0 \uc54a\uc558\uc5b4\uc694."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uc81c\ubaa9\uc740 \uc9e7\uac8c, \ubcf4\uae30 \uc27d\uac8c, \uc77d\uae30 \uc27d\uac8c, \ubc1c\uc74c\uc774 \ube44\uc2b7\ud558\uac8c, \uc21c\uc11c\ub97c \ubc14\uafd4\uc11c"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uae00\uc744 \ub9c8\uc9c0\ub9c9\uc73c\ub85c \ub2e4\ub4ec\uc744 \ub54c, \ub178\ub798\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \ubc29\ubc95\uc740 \uc5c6\uc744\uc9c0 \uace0\ubbfc\ud574\ubd05\ub2c8\ub2e4. \uac10\ud788 \uac00 \ub2ff\uc744 \uc218 \uc5c6\ub294 \ubaa9\ud45c\uc774\uaca0\uc9c0\ub9cc, \ud560 \uc218 \uc788\ub294 \ucd5c\uc18c\ud55c\uc758 \ub9ac\ub4ec\uc774\ub77c\ub3c4 \ubd99\uc5ec\uc8fc\uace0 \uc2f6\uc5b4\uc694."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uc5ec\ub294 \ub9d0\uacfc \ub9c8\uc9c0\ub9c9 \ub9d0\uc5d0 \uc791\uc815\ud558\uace0 \ub9c8\uc74c\uc744 \ub2f4\ub294 \uc5f0\uc2b5\uc744 \ud574\ubd05\uc2dc\ub2e4. \uae00\uc758 \uc5b4\ub290 \uad6c\uc11d\uc774\ub77c\ub3c4 \ubed4\ud55c \uae00\uc790\ub294 \ub0a8\uae30\uc9c0 \uc54a\uaca0\ub178\ub77c \ub2e4\uc9d0\ud558\uba70 \uc368\ubcf4\ub294 \uac81\ub2c8\ub2e4. \ub098\ub9cc\uc774 \uac00\uc9c4 \uc720\uc77c\ud55c \uba54\uc2dc\uc9c0\uc5d0 \uc9d1\uc911\ud558\uba74\uc11c\uc694. \uadf8\ub7fc \uc0dd\uac01\uc774 \ub2ec\ub77c\uc9c0\uace0, \uace0\ub974\ub294 \ub2e8\uc5b4\ub3c4 \ub2ec\ub77c\uc9c0\uace0, \ub0a8\uae34 \ubb38\uc7a5\ub3c4 \ub2ec\ub77c\uc838\uc694. \uacb0\uad6d\uc5d0\ub294 \uae00\uc744 \uc4f4 \uc0ac\ub78c\uc778 \ub098 \uc790\uc2e0\ub3c4 \ub0a8\ub2ec\ub77c\uc9c8 \uac81\ub2c8\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ub9de\ucda4\ubc95\uc740 \uc911\uc694\ud569\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \ub9de\ucda4\ubc95\ubcf4\ub2e4 \ub354 \uc911\uc694\ud55c \uac74 \uac70\uae30\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc785\ub2c8\ub2e4. \ub0b4 \ub9c8\uc74c\uc744 \uae00\uc5d0 \ub2f4\uc544 \uc2e4\uc5b4 \ubcf4\ub0b4\uae30 \uc804, \ub9de\ucda4\ubc95\uc744 \uc810\uac80\ud558\ub294 \uc774\uc720 \uc5ed\uc2dc \uadf8\uac81\ub2c8\ub2e4. \uc624\uc9c1 \ub0b4 \ub9c8\uc74c\uc774 \ub0a8\uc5d0\uac8c \uc77d\ud788\ub294 \ub3d9\uc548 \ubc29\ud574\uac00 \ub418\uc9c0 \uc54a\uae30\ub97c \ubc14\ub77c\uae30 \ub54c\ubb38\uc774\uc8e0. \ub0b4\uac00 \uc4f4 \uae00\ub3c4, \ub0a8\uc774 \uc4f4 \uae00\ub3c4. \uc5b8\uc81c\ub098 \uadf8 \uc548\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc774 \uba3c\uc800\uc785\ub2c8\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uae00\uc744 \uc4f4\ub2e4\uace0 \uae00\uc774 \uc644\uc131\ub418\ub294 \uac8c \uc544\ub2c8\uc5d0\uc694. \uae00\uacfc \ub2ee\uc740 \ubaa8\uc2b5\uc73c\ub85c \uc0b4 \ub54c, \uae00\uc740 \ube44\ub85c\uc18c \uc644\uc131\ub429\ub2c8\ub2e4."}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,o.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function c(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=t.createContext({}),a=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},u={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,c=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=a(r),b=o,h=d["".concat(s,".").concat(b)]||d[b]||u[b]||c;return r?t.createElement(h,i(i({ref:n},p),{},{components:r})):t.createElement(h,i({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/372ccfe9.87b936b9.js b/assets/js/372ccfe9.87b936b9.js deleted file mode 100644 index f2a123277..000000000 --- a/assets/js/372ccfe9.87b936b9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9111],{3905:(e,t,r)=>{r.d(t,{Zo:()=>i,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),u=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},i=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},k={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,l=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),b=u(r),m=o,s=b["".concat(p,".").concat(m)]||b[m]||k[m]||l;return r?n.createElement(s,a(a({ref:t},i),{},{components:r})):n.createElement(s,a({ref:t},i))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var l=r.length,a=new Array(l);a[0]=b;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c.mdxType="string"==typeof e?e:o,a[1]=c;for(var u=2;u{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>k,frontMatter:()=>l,metadata:()=>c,toc:()=>u});var n=r(87462),o=(r(67294),r(3905));const l={title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",slug:"book-writer",tags:["Book"]},a=void 0,c={permalink:"/book-writer",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",source:"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",description:"\ucc45 \uc815\ubcf4",date:"2023-01-01T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 1\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:4.425,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",slug:"book-writer",tags:["Book"]},prevItem:{title:"2022\ub144 \ud68c\uace0",permalink:"/2022-retrospective"}},p={authorsImageUrls:[]},u=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}],i={toc:u};function k(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},i,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"\ucc45-\uc815\ubcf4"},"\ucc45 \uc815\ubcf4"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ubc15\uc194\ubbf8 ")),(0,o.kt)("h3",{id:"\uc77d\uace0-\ub098\uc11c"},"\uc77d\uace0 \ub098\uc11c"),(0,o.kt)("p",null,"\uc800\uc790\uc758 \uacbd\ud5d8\uacfc \ud568\uaed8 \uae00\uc4f0\uae30\uc5d0 \ub300\ud55c \uac00\ubcbc\uc6b4 \uc870\uc5b8\uc774 \ub2f4\uaca8\uc788\uc5b4 \uac00\ubccd\uac8c \uc77d\uae30 \uc88b\uc558\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uae00\uc744 \uc798 \uc791\uc131\ud574 \ubcf4\uace0 \uc2f6\uc744 \ub54c \uc801\uc6a9\ud574 \ubcfc \uc218 \uc788\ub294 \uc815\ubcf4\uac00 \ub9ce\uc544\uc11c \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub2e4. "),(0,o.kt)("p",null,"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\uc758 \ud504\ub9ac\ucf54\uc2a4\ub97c \uc9c4\ud589\ud560 \ub54c \ud6c4\uae30\ub97c \uc791\uc131\ud558\uace0 \ub098\uba74 \ud56d\uc0c1 \uae00\uc774 \ub531\ub531\ud558\ub2e4\ub294 \ub290\ub08c\uc744 \ubc1b\uc558\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \uc9c0\uc6d0\uc790\ub4e4\uc758 \uc77d\uae30 \ud3b8\ud558\uace0, \ubc1d\uc740 \ub290\ub08c\uc744 \uc8fc\ub294 \uae00\uc744 \ubcf4\uba74 \ubd80\ub7ec\uc6b4 \ub9c8\uc74c\uc744 \uac00\uc9c0\uae30\ub3c4 \ud588\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc774 \ucc45\uc744 \uc77d\uc5c8\uc73c\ub2c8 2023\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae00\uc744 \uc798 \uc801\uc5b4\ubcf4\ub824\uace0 \ud55c\ub2e4."),(0,o.kt)("h3",{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4"},"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\ubb38\uc7a5\uc774 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74\n\ub0b4\uc6a9\uc744 \uc77c\ubaa9\uc694\uc5f0\ud558\uac8c \uc815\ub9ac\ud588\uace0, \uae00\uc758 \uc758\ub3c4\ub3c4 \uc090\ub6a4\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub3c4 \uc801\uc808\ud55c \uac83\uc73c\ub85c \uace8\ub790\ub294\ub370\u2026 \uadf8\ub7f0\ub370\ub3c4 \uc5b4\ub518\uac00\uac00 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74? \ucd95\ucd95 \ucc98\uc9c0\uace0 \ub530\ubd84\ud558\ub2e4\uba74? \ub9d0\uaf2c\ub9ac\ub97c \ubaa8\uc870\ub9ac \u2018~\ub2e4\u2019\ub85c \ud1b5\uc77c\ud55c \uac74 \uc544\ub2cc\uc9c0 \uc810\uac80\ud574 \ubcf4\uc138\uc694.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\ub9d0\uaf2c\ub9ac\ub97c \uc798 \uac16\uace0 \ub180\uc544\uc57c \ud569\ub2c8\ub2e4. \ubb38\uc7a5\uc758 \ub9c8\uc9c0\ub9c9 \uae00\uc790\ub97c \ub9e4\ubc88 \ub2e4\ub974\uac8c \uace0\uccd0\uc4f0\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uae00\uc5d0 \ud65c\uae30\ub97c \ub354\ud560 \uc218 \uc788\uc8e0. \ub54c\ub860 \ubb38\uc7a5\uc744 \ub2e4 \ub9c8\uce58\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub85c\ub9cc \ub05d\ub9fa\ub294 \uac83\ub3c4 \ubc29\ubc95. \ubb38\uc7a5\uacfc \ubb38\uc7a5 \uc0ac\uc774\uc5d0 \uc27c\ud45c\uac00 \ub4e4\uc5b4\uc11c\uba70 \uae00 \uc804\uccb4\uc5d0 \ud65c\uae30\uac00 \ub3cc\uac8c \ub3fc\uc694. \ubb38\uc7a5\uc758 \uae38\uc774\ub3c4 \ub2e4\ucc44\ub85c\uc6cc\uc9c0\ub294 \ub355\ubd84\uc5d0 \ub364\uc73c\ub85c \uc5bb\uac8c \ub418\ub294 \uac83\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ubc14\ub85c, \uae00\uc758 \ub9ac\ub4ec.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uc774\uc804 \ubb38\uc7a5\uc5d0\uc11c \ub05d\ub09c \uae00\uc790\ub85c, \ub2e4\uc74c \ubb38\uc7a5\uc744 \ub05d\ub9fa\uc9c0 \uc54a\uae30. \ud55c\ub450 \ubb38\ub2e8\ub9c8\ub2e4 \ub2e8\uc5b4 \uc218\uc900\uc758 \uc544\uc8fc \uc9e7\uc740 \ubb38\uc7a5 \ubc30\uce58\ud558\uae30.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uae00\uc758 \uc9c4\uc9dc \uc774\uc720, \uae00\uc758 \uc9c4\uc9dc \ubaa9\uc801, \uae00\uc758 \uc9c4\uc9dc \ub300\uc0c1\uc744 \ucc3e\uc73c\ub824\uace0 \uc560\uc37c\uc2b5\ub2c8\ub2e4. \uc9c0\uae08\ucc98\ub7fc \ud2c0\uc744 \ub5a0\uc62c\ub9b0\ub2e4\uac70\ub098, \ub208\uce58\ub97c \ubcf8\ub2e4\uac70\ub098, \uc815\uce58\uc801\uc778 \uc148\ub3c4 \ud558\uc9c0 \uc54a\uc558\uc5b4\uc694.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uc81c\ubaa9\uc740 \uc9e7\uac8c, \ubcf4\uae30 \uc27d\uac8c, \uc77d\uae30 \uc27d\uac8c, \ubc1c\uc74c\uc774 \ube44\uc2b7\ud558\uac8c, \uc21c\uc11c\ub97c \ubc14\uafd4\uc11c")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uae00\uc744 \ub9c8\uc9c0\ub9c9\uc73c\ub85c \ub2e4\ub4ec\uc744 \ub54c, \ub178\ub798\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \ubc29\ubc95\uc740 \uc5c6\uc744\uc9c0 \uace0\ubbfc\ud574\ubd05\ub2c8\ub2e4. \uac10\ud788 \uac00 \ub2ff\uc744 \uc218 \uc5c6\ub294 \ubaa9\ud45c\uc774\uaca0\uc9c0\ub9cc, \ud560 \uc218 \uc788\ub294 \ucd5c\uc18c\ud55c\uc758 \ub9ac\ub4ec\uc774\ub77c\ub3c4 \ubd99\uc5ec\uc8fc\uace0 \uc2f6\uc5b4\uc694.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uc5ec\ub294 \ub9d0\uacfc \ub9c8\uc9c0\ub9c9 \ub9d0\uc5d0 \uc791\uc815\ud558\uace0 \ub9c8\uc74c\uc744 \ub2f4\ub294 \uc5f0\uc2b5\uc744 \ud574\ubd05\uc2dc\ub2e4. \uae00\uc758 \uc5b4\ub290 \uad6c\uc11d\uc774\ub77c\ub3c4 \ubed4\ud55c \uae00\uc790\ub294 \ub0a8\uae30\uc9c0 \uc54a\uaca0\ub178\ub77c \ub2e4\uc9d0\ud558\uba70 \uc368\ubcf4\ub294 \uac81\ub2c8\ub2e4. \ub098\ub9cc\uc774 \uac00\uc9c4 \uc720\uc77c\ud55c \uba54\uc2dc\uc9c0\uc5d0 \uc9d1\uc911\ud558\uba74\uc11c\uc694. \uadf8\ub7fc \uc0dd\uac01\uc774 \ub2ec\ub77c\uc9c0\uace0, \uace0\ub974\ub294 \ub2e8\uc5b4\ub3c4 \ub2ec\ub77c\uc9c0\uace0, \ub0a8\uae34 \ubb38\uc7a5\ub3c4 \ub2ec\ub77c\uc838\uc694. \uacb0\uad6d\uc5d0\ub294 \uae00\uc744 \uc4f4 \uc0ac\ub78c\uc778 \ub098 \uc790\uc2e0\ub3c4 \ub0a8\ub2ec\ub77c\uc9c8 \uac81\ub2c8\ub2e4.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\ub9de\ucda4\ubc95\uc740 \uc911\uc694\ud569\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \ub9de\ucda4\ubc95\ubcf4\ub2e4 \ub354 \uc911\uc694\ud55c \uac74 \uac70\uae30\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc785\ub2c8\ub2e4. \ub0b4 \ub9c8\uc74c\uc744 \uae00\uc5d0 \ub2f4\uc544 \uc2e4\uc5b4 \ubcf4\ub0b4\uae30 \uc804, \ub9de\ucda4\ubc95\uc744 \uc810\uac80\ud558\ub294 \uc774\uc720 \uc5ed\uc2dc \uadf8\uac81\ub2c8\ub2e4. \uc624\uc9c1 \ub0b4 \ub9c8\uc74c\uc774 \ub0a8\uc5d0\uac8c \uc77d\ud788\ub294 \ub3d9\uc548 \ubc29\ud574\uac00 \ub418\uc9c0 \uc54a\uae30\ub97c \ubc14\ub77c\uae30 \ub54c\ubb38\uc774\uc8e0. \ub0b4\uac00 \uc4f4 \uae00\ub3c4, \ub0a8\uc774 \uc4f4 \uae00\ub3c4. \uc5b8\uc81c\ub098 \uadf8 \uc548\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc774 \uba3c\uc800\uc785\ub2c8\ub2e4.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uae00\uc744 \uc4f4\ub2e4\uace0 \uae00\uc774 \uc644\uc131\ub418\ub294 \uac8c \uc544\ub2c8\uc5d0\uc694. \uae00\uacfc \ub2ee\uc740 \ubaa8\uc2b5\uc73c\ub85c \uc0b4 \ub54c, \uae00\uc740 \ube44\ub85c\uc18c \uc644\uc131\ub429\ub2c8\ub2e4.")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/38bf29ad.a6eb9d38.js b/assets/js/38bf29ad.bf7f6732.js similarity index 92% rename from assets/js/38bf29ad.a6eb9d38.js rename to assets/js/38bf29ad.bf7f6732.js index 82fb651d9..d14ec8bdf 100644 --- a/assets/js/38bf29ad.a6eb9d38.js +++ b/assets/js/38bf29ad.bf7f6732.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1285],{26514:a=>{a.exports=JSON.parse('{"label":"load balancing","permalink":"/docs/tags/load-balancing","allTagsPath":"/docs/tags","count":2,"items":[{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1","description":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?","permalink":"/docs/network/load-balancing"},{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","description":"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)","permalink":"/docs/network/load-balancing-algorithm"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1285],{26514:a=>{a.exports=JSON.parse('{"label":"load balancing","permalink":"/docs/tags/load-balancing","allTagsPath":"/docs/tags","count":2,"items":[{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1","description":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?","permalink":"/docs/network/load-balancing"},{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","description":"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)","permalink":"/docs/network/load-balancing-algorithm"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/39ee6679.149b515e.js b/assets/js/39ee6679.b0b1231d.js similarity index 77% rename from assets/js/39ee6679.149b515e.js rename to assets/js/39ee6679.b0b1231d.js index cb264cac0..05e350d10 100644 --- a/assets/js/39ee6679.149b515e.js +++ b/assets/js/39ee6679.b0b1231d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5717],{83636:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5717],{83636:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3b0f99e8.c4d5d643.js b/assets/js/3b0f99e8.a35b4fd0.js similarity index 85% rename from assets/js/3b0f99e8.c4d5d643.js rename to assets/js/3b0f99e8.a35b4fd0.js index 4d5d92a24..30d66bd07 100644 --- a/assets/js/3b0f99e8.c4d5d643.js +++ b/assets/js/3b0f99e8.a35b4fd0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3553],{20034:e=>{e.exports=JSON.parse('{"label":"Jenkins","permalink":"/tags/jenkins","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3553],{20034:e=>{e.exports=JSON.parse('{"label":"Jenkins","permalink":"/tags/jenkins","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3b12d42b.3312efb5.js b/assets/js/3b12d42b.95f13260.js similarity index 81% rename from assets/js/3b12d42b.3312efb5.js rename to assets/js/3b12d42b.95f13260.js index 31d9e1c4f..9f7e5859e 100644 --- a/assets/js/3b12d42b.3312efb5.js +++ b/assets/js/3b12d42b.95f13260.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8107],{50244:e=>{e.exports=JSON.parse('{"label":"java","permalink":"/docs/tags/java","allTagsPath":"/docs/tags","count":1,"items":[{"id":"Java/SequencedCollection","title":"SequencedCollection","description":"JEP 431: Sequenced Collections","permalink":"/docs/java/sequenced-collection"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8107],{50244:e=>{e.exports=JSON.parse('{"label":"java","permalink":"/docs/tags/java","allTagsPath":"/docs/tags","count":1,"items":[{"id":"Java/SequencedCollection","title":"SequencedCollection","description":"JEP 431: Sequenced Collections","permalink":"/docs/java/sequenced-collection"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3b18521e.c7777a60.js b/assets/js/3b18521e.28bc0b58.js similarity index 86% rename from assets/js/3b18521e.c7777a60.js rename to assets/js/3b18521e.28bc0b58.js index 9a6ab2c4c..f6a3987b6 100644 --- a/assets/js/3b18521e.c7777a60.js +++ b/assets/js/3b18521e.28bc0b58.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2773],{8086:e=>{e.exports=JSON.parse('{"label":"Mockito","permalink":"/tags/mockito","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2773],{8086:e=>{e.exports=JSON.parse('{"label":"Mockito","permalink":"/tags/mockito","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3c5aea38.116651cd.js b/assets/js/3c5aea38.34c3a378.js similarity index 81% rename from assets/js/3c5aea38.116651cd.js rename to assets/js/3c5aea38.34c3a378.js index 0271c1e39..c69966082 100644 --- a/assets/js/3c5aea38.116651cd.js +++ b/assets/js/3c5aea38.34c3a378.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6250],{56516:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6250],{56516:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3d6c40c1.6216fe06.js b/assets/js/3d6c40c1.145654ac.js similarity index 83% rename from assets/js/3d6c40c1.6216fe06.js rename to assets/js/3d6c40c1.145654ac.js index 532278c90..d9bbe853d 100644 --- a/assets/js/3d6c40c1.6216fe06.js +++ b/assets/js/3d6c40c1.145654ac.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8509],{3440:e=>{e.exports=JSON.parse('{"label":"monitoring","permalink":"/tags/monitoring","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8509],{3440:e=>{e.exports=JSON.parse('{"label":"monitoring","permalink":"/tags/monitoring","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3dd4d232.407474b2.js b/assets/js/3dd4d232.407474b2.js deleted file mode 100644 index 3c07a9015..000000000 --- a/assets/js/3dd4d232.407474b2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7727],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>s});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),i=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},m=function(e){var t=i(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,c=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),k=i(r),s=a,b=k["".concat(c,".").concat(s)]||k[s]||u[s]||p;return r?n.createElement(b,o(o({ref:t},m),{},{components:r})):n.createElement(b,o({ref:t},m))}));function s(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=k;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var i=2;i{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>p,metadata:()=>l,toc:()=>i});var n=r(87462),a=(r(67294),r(3905));const p={title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",slug:"blackjack-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,l={permalink:"/blackjack-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-blackjack/pull/427",date:"2023-03-14T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 14\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.17,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",slug:"blackjack-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",permalink:"/grasp"},nextItem:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",permalink:"/ladder-retrospective"}},c={authorsImageUrls:[]},i=[{value:"\ube14\ub799\uc7ad",id:"\ube14\ub799\uc7ad",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],m={toc:i};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-blackjack/pull/427"},"https://github.com/woowacourse/java-blackjack/pull/427"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-blackjack/pull/537"},"https://github.com/woowacourse/java-blackjack/pull/537")," ")),(0,a.kt)("h3",{id:"\ube14\ub799\uc7ad"},"\ube14\ub799\uc7ad"),(0,a.kt)("p",null,"\ube14\ub799\uc7ad \ubbf8\uc158\uc5d0\uc11c\ub294 \ud6c4\ucd94\uc640 \ud398\uc5b4(\uc870\ubbf8\ub8cc \ub4c0\uc624?)\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0\ub294 \uc2e4\uc218\ud558\uc9c0 \uc54a\uace0, \ubc14\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uc9c0 \uc54a\uace0 \uce5c\ud574\uc9c0\uae30 \ubd80\ud130 \uc2dc\uc791\ud588\ub2e4. "),(0,a.kt)("p",null,"\ube14\ub799\uc7ad\uc740 \uad6c\ud604\ud574\uc57c \ub420 \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud560 \uac83 \uac19\uc558\uc9c0\ub9cc",(0,a.kt)("br",{parentName:"p"}),"\n","\ud6c4\ucd94\uc640 \ud568\uaed8 \uc804\ub7b5\uc801(\uc0bc\uc77c\uc808\uc5d0 \ubbf8\uc158 \uc774\uc57c\uae30 \ub098\ub204\uae30)\uc73c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud574 \uc2dc\uac04 \ub0b4\uc5d0 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ubbf8\uc158\uc744 \ub05d\ub098\uace0 \ud68c\uace0\ub97c \ud588\uc744 \ub54c \ud6c4\ucd94\uac00 \uace0\ubbfc\uac70\ub9ac\ub97c \ud558\ub098 \ub0b4\uc92c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n",'"\ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \uc555\ubc15\uac10\uc744 \ub290\ub07c\ub294 \ud398\uc5b4\uac00 \uc788\ub2e4\uba74 \ud5c8\ube0c\uac00 \ud574\uc904 \uc218 \uc788\ub294\uac8c \ubb50\uac00 \uc788\uc744\uae4c?" '),(0,a.kt)("p",null,"\uacf0\uacf0\ud788 \uc0dd\uac01\ud574\ubd24\uc9c0\ub9cc \uc27d\uac8c \ub2f5\uc744 \ub0b4\ub9b4 \uc218 \uc5c6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04 \uc911\uac04 \ud68c\uace0\ub97c \ud558\uace0, \ub098\uc758 \uc18c\ud504\ud2b8\uc2a4\ud0ac\uc744 \ub192\ud788\ub294\uac8c \ub2f5\uc77c\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\ubd80\ub2f4\uac10\uc744 \ub290\ub07c\uc9c0 \uc54a\uace0 \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub420 \uc218 \uc788\ub3c4\ub85d \uacc4\uc18d \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4. "),(0,a.kt)("p",null,"\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc0dd\uac01\uc774 \ub9ce\uc544\uc838\uc11c \uc804 \ub9ac\ubdf0\uc5b4\uc778 \ud130\ud2c0\ud83d\udc22\uacfc\ub3c4 \ub300\ud654\ub97c \ub098\ub204\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud130\ud2c0\uc740 \uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84(\uad81\uadf9\uc801\uc778 \ubaa9\ud45c\uc778 \uc88b\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uac83)\uc5d0 \uc9d1\uc911\ud574\ubcf4\ub77c\uace0 \ud558\uc168\ub2e4. "),(0,a.kt)("p",null,"\uc88b\uc740 \ucf54\ub4dc, \uc88b\uc740 \ud398\uc5b4\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc77c\ub2e8 \uc9c0\uc18d\uc801\uc73c\ub85c \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4."),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud398\uc5b4 \uc2e0\uacbd\uc4f0\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \ud398\uc5b4\ud560 \ub54c \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub0b4\ubcf4\ub3c4\ub85d \ud588\ub2e4. \uadf8\ub807\uae30\uc5d0 \ub108\ubb34 \uc758\uacac\uc744 \uac15\ud558\uac8c \ubc00\uc5b4\ubd99\uc778 \ub290\ub08c\uc774 \ub4e4\uc5b4\uc11c \ubbf8\uc548\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud6c4\ucd94\uac00 \uc555\ubc15\uc744 \ub290\uaf08\uc744 \uc218\ub3c4 \uc788\uc744 \uac83 \uac19\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04 \uc911\uac04 \uc791\uc740 \ud68c\uace0\ub97c \uc9c4\ud589\ud574\ubcf4\ub294 \uac83\uc774 \uc88b\uc744\uae4c?"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uccb4\ub825 \uad00\ub9ac"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uc998 \uc798 \ubabb\uba39\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc0b4 \ub0a0\uc774 \ub9ce\uc740\ub370 \uc798 \ucc59\uaca8\uba39\uace0, \ud798\ub0b4\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc911\uac04 \uc911\uac04 \ub3cc\uc544\ubcf4\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \ubbf8\uc158\uacfc \uad00\ub828\ub41c \ub0b4\uc6a9\uc740 \uc544\ub2c8\uc9c0\ub9cc \uc6b0\ud14c\ucf54\ub97c \uc798 \ud65c\uc6a9 \ud558\uace0 \uc788\ub294\uc9c0 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \uc6b0\ud14c\ucf54\uc5d0 \uc9c0\uc6d0\ud55c \uc774\uc720\ub97c \ud56d\uc0c1 \uc78a\uc9c0 \uc54a\uc544\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc0c1\ud0dc \ud328\ud134"),(0,a.kt)("br",{parentName:"p"}),"\n","\uac1d\uccb4\uc758 \ub0b4\ubd80 \uc0c1\ud0dc\uc5d0 \ub530\ub77c \uc2a4\uc2a4\ub85c \ud589\ub3d9\uc744 \ubcc0\uacbd\ud558\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc73c\ub85c if/else/switch\uc640 \uac19\uc740 \uc870\uac74\ubb38\uc744 \ud6a8\uacfc\uc801\uc73c\ub85c \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube14\ub799\uc7ad \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc0c1\ud0dc \ud328\ud134\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ucc98\uc74c \uc801\uc6a9\ud574\ubcf4\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc98\uc74c \uc801\uc6a9\ud558\uae30 \uc804\uc5d0\ub294 \ubcc4\ub85c\ub77c\uace0 \uc0dd\uac01\ud588\ub294\ub370, \uc0dd\uac01\ubcf4\ub2e4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc77c\uad00\uc131, \uac00\ub3c5\uc131, \ucd94\uc0c1\ud654"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \ub9ac\ubdf0\uc5b4\ub294 \uac80\ud504\ud83c\udf6b \uc600\ub2e4!",(0,a.kt)("br",{parentName:"p"}),"\n","\uac80\ud504\uc758 \ub9ac\ubdf0\ub294 \uac04\uacb0\ud568\uc5d0 \uad00\ub828\ub41c \ub0b4\uc6a9\uc774 \ub9ce\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\uad00\uc131\uc774 \uc788\ub294 \ucf54\ub4dc, \uac00\ub3c5\uc131\uc774 \uc88b\uc740 \ucf54\ub4dc, \ucd94\uc0c1\ud654\uac00 \uc798 \ub418\uc5b4\uc788\ub294 \ucf54\ub4dc",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77d\uae30 \uc88b\uace0, \uac04\uacb0\ud55c \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \ubc29\ubc95\uc744 \ubc30\uc6b4 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucf54\ub4dc\ub97c \ubc14\ub77c\ubcf4\ub294 \uc2dc\uc810\uc774 \ud558\ub098 \ub298\uc5b4\ub09c \uae30\ubd84\uc774\ub2e4!(\uc55e\uc73c\ub85c \uc801\uc6a9\ud558\ub294 \uac83\uc740 \ub098\uc758 \ubaab\uc774\uc9c0\ub9cc) "),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc0dd\uac01 \uc815\ub9ac"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04 \uc911\uac04 \ud604\uc7ac \uc0c1\ud669\uc5d0 \ub300\ud574 \uadf8\ub9bc\uc744 \uadf8\ub9ac\uac70\ub098, \uae00\uc744 \uc801\uc73c\uba74\uc11c \uc815\ub9ac\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud398\uc5b4\uc640 \ub3d9\uc77c\ud55c \ubd80\ubd84\uc744 \uc774\ud574\ud558\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c4\ud589\ud558\ub294\ub370 \ub9e4\uc6b0 \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 \ub2e4\uc74c \ud398\uc5b4\ub54c\ubd80\ud130 \ud39c\uc774\ub791 \uc885\uc774\ub97c \uc900\ube44\ud574\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uac00\uac10\uc5c6\uc774 \uc758\uacac\uc744 \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c4\ud589 \uc0c1\ud669\uc5d0 \ub300\ud55c \ubd80\ubd84, \uc9c4\ud589 \uc18d\ub3c4, \uc9c0\uae08 \uc790\uc2e0\uc774 \uc774\ud574\ud558\uace0 \uc788\ub294 \ubd80\ubd84\uc744 \ub9d0\ud574\uc918\uc11c \ud3b8\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud68c\uace0\ub54c\ub3c4 \uc11c\ub85c \uc194\uc9c1\ud558\uac8c \uc758\uacac\uc744 \uc8fc\uace0 \ubc1b\uc544\uc11c \uc88b\uc558\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub3c4\uba54\uc778 \uc5b8\uc5b4\uc5d0 \uc2e0\uacbd\uc4f0\ub294 \ubd80\ubd84"),(0,a.kt)("br",{parentName:"p"}),"\n","\ud074\ub798\uc2a4\uba85, \ubcc0\uc218\uba85\uacfc \uac19\uc740 \uc5b8\uc5b4\ub97c \uc138\uc2ec\ud558\uac8c \uc2e0\uacbd\uc4f4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uad6c\uc0ac\ud56d \uc815\ub9ac\ub3c4 \uae54\ub054\ud558\uac8c \uc798\ud558\ub294 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\ud6c4\ucd94 \ucd5c\uace0 \ud83d\udc4d"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3dd4d232.a5b347e4.js b/assets/js/3dd4d232.a5b347e4.js new file mode 100644 index 000000000..1d7a30693 --- /dev/null +++ b/assets/js/3dd4d232.a5b347e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7727],{22195:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>o,default:()=>p,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var t=n(85893),s=n(3905);const c={title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",slug:"blackjack-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,a={permalink:"/blackjack-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-blackjack/pull/427",date:"2023-03-14T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 14\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.17,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",slug:"blackjack-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",permalink:"/grasp"},nextItem:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",permalink:"/ladder-retrospective"}},i={authorsImageUrls:[]},l=[{value:"\ube14\ub799\uc7ad",id:"\ube14\ub799\uc7ad",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function j(e){const r={a:"a",admonition:"admonition",br:"br",h3:"h3",p:"p",strong:"strong",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/java-blackjack/pull/427",children:"https://github.com/woowacourse/java-blackjack/pull/427"}),(0,t.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/java-blackjack/pull/537",children:"https://github.com/woowacourse/java-blackjack/pull/537"})]})}),"\n",(0,t.jsx)(r.h3,{id:"\ube14\ub799\uc7ad",children:"\ube14\ub799\uc7ad"}),"\n",(0,t.jsxs)(r.p,{children:["\ube14\ub799\uc7ad \ubbf8\uc158\uc5d0\uc11c\ub294 \ud6c4\ucd94\uc640 \ud398\uc5b4(\uc870\ubbf8\ub8cc \ub4c0\uc624?)\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\ubc88\uc5d0\ub294 \uc2e4\uc218\ud558\uc9c0 \uc54a\uace0, \ubc14\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uc9c0 \uc54a\uace0 \uce5c\ud574\uc9c0\uae30 \ubd80\ud130 \uc2dc\uc791\ud588\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ube14\ub799\uc7ad\uc740 \uad6c\ud604\ud574\uc57c \ub420 \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud560 \uac83 \uac19\uc558\uc9c0\ub9cc",(0,t.jsx)(r.br,{}),"\n","\ud6c4\ucd94\uc640 \ud568\uaed8 \uc804\ub7b5\uc801(\uc0bc\uc77c\uc808\uc5d0 \ubbf8\uc158 \uc774\uc57c\uae30 \ub098\ub204\uae30)\uc73c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud574 \uc2dc\uac04 \ub0b4\uc5d0 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ubbf8\uc158\uc744 \ub05d\ub098\uace0 \ud68c\uace0\ub97c \ud588\uc744 \ub54c \ud6c4\ucd94\uac00 \uace0\ubbfc\uac70\ub9ac\ub97c \ud558\ub098 \ub0b4\uc92c\ub2e4.",(0,t.jsx)(r.br,{}),"\n",'"\ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \uc555\ubc15\uac10\uc744 \ub290\ub07c\ub294 \ud398\uc5b4\uac00 \uc788\ub2e4\uba74 \ud5c8\ube0c\uac00 \ud574\uc904 \uc218 \uc788\ub294\uac8c \ubb50\uac00 \uc788\uc744\uae4c?"']}),"\n",(0,t.jsxs)(r.p,{children:["\uacf0\uacf0\ud788 \uc0dd\uac01\ud574\ubd24\uc9c0\ub9cc \uc27d\uac8c \ub2f5\uc744 \ub0b4\ub9b4 \uc218 \uc5c6\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc911\uac04 \uc911\uac04 \ud68c\uace0\ub97c \ud558\uace0, \ub098\uc758 \uc18c\ud504\ud2b8\uc2a4\ud0ac\uc744 \ub192\ud788\ub294\uac8c \ub2f5\uc77c\uae4c?",(0,t.jsx)(r.br,{}),"\n","\ubd80\ub2f4\uac10\uc744 \ub290\ub07c\uc9c0 \uc54a\uace0 \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub420 \uc218 \uc788\ub3c4\ub85d \uacc4\uc18d \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc0dd\uac01\uc774 \ub9ce\uc544\uc838\uc11c \uc804 \ub9ac\ubdf0\uc5b4\uc778 \ud130\ud2c0\ud83d\udc22\uacfc\ub3c4 \ub300\ud654\ub97c \ub098\ub204\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud130\ud2c0\uc740 \uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84(\uad81\uadf9\uc801\uc778 \ubaa9\ud45c\uc778 \uc88b\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uac83)\uc5d0 \uc9d1\uc911\ud574\ubcf4\ub77c\uace0 \ud558\uc168\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:"\uc88b\uc740 \ucf54\ub4dc, \uc88b\uc740 \ud398\uc5b4\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc77c\ub2e8 \uc9c0\uc18d\uc801\uc73c\ub85c \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ud398\uc5b4 \uc2e0\uacbd\uc4f0\uae30"}),(0,t.jsx)(r.br,{}),"\n","\uc774\ubc88 \ud398\uc5b4\ud560 \ub54c \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub0b4\ubcf4\ub3c4\ub85d \ud588\ub2e4. \uadf8\ub807\uae30\uc5d0 \ub108\ubb34 \uc758\uacac\uc744 \uac15\ud558\uac8c \ubc00\uc5b4\ubd99\uc778 \ub290\ub08c\uc774 \ub4e4\uc5b4\uc11c \ubbf8\uc548\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud6c4\ucd94\uac00 \uc555\ubc15\uc744 \ub290\uaf08\uc744 \uc218\ub3c4 \uc788\uc744 \uac83 \uac19\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc911\uac04 \uc911\uac04 \uc791\uc740 \ud68c\uace0\ub97c \uc9c4\ud589\ud574\ubcf4\ub294 \uac83\uc774 \uc88b\uc744\uae4c?"]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uccb4\ub825 \uad00\ub9ac"}),(0,t.jsx)(r.br,{}),"\n","\uc694\uc998 \uc798 \ubabb\uba39\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c \uc0b4 \ub0a0\uc774 \ub9ce\uc740\ub370 \uc798 \ucc59\uaca8\uba39\uace0, \ud798\ub0b4\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uc911\uac04 \uc911\uac04 \ub3cc\uc544\ubcf4\uae30"}),(0,t.jsx)(r.br,{}),"\n","\uc774\ubc88 \ubbf8\uc158\uacfc \uad00\ub828\ub41c \ub0b4\uc6a9\uc740 \uc544\ub2c8\uc9c0\ub9cc \uc6b0\ud14c\ucf54\ub97c \uc798 \ud65c\uc6a9 \ud558\uace0 \uc788\ub294\uc9c0 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub0b4\uac00 \uc6b0\ud14c\ucf54\uc5d0 \uc9c0\uc6d0\ud55c \uc774\uc720\ub97c \ud56d\uc0c1 \uc78a\uc9c0 \uc54a\uc544\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uc0c1\ud0dc \ud328\ud134"}),(0,t.jsx)(r.br,{}),"\n","\uac1d\uccb4\uc758 \ub0b4\ubd80 \uc0c1\ud0dc\uc5d0 \ub530\ub77c \uc2a4\uc2a4\ub85c \ud589\ub3d9\uc744 \ubcc0\uacbd\ud558\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc73c\ub85c if/else/switch\uc640 \uac19\uc740 \uc870\uac74\ubb38\uc744 \ud6a8\uacfc\uc801\uc73c\ub85c \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ube14\ub799\uc7ad \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc0c1\ud0dc \ud328\ud134\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ucc98\uc74c \uc801\uc6a9\ud574\ubcf4\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucc98\uc74c \uc801\uc6a9\ud558\uae30 \uc804\uc5d0\ub294 \ubcc4\ub85c\ub77c\uace0 \uc0dd\uac01\ud588\ub294\ub370, \uc0dd\uac01\ubcf4\ub2e4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uc77c\uad00\uc131, \uac00\ub3c5\uc131, \ucd94\uc0c1\ud654"}),(0,t.jsx)(r.br,{}),"\n","\uc774\ubc88 \ub9ac\ubdf0\uc5b4\ub294 \uac80\ud504\ud83c\udf6b \uc600\ub2e4!",(0,t.jsx)(r.br,{}),"\n","\uac80\ud504\uc758 \ub9ac\ubdf0\ub294 \uac04\uacb0\ud568\uc5d0 \uad00\ub828\ub41c \ub0b4\uc6a9\uc774 \ub9ce\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc77c\uad00\uc131\uc774 \uc788\ub294 \ucf54\ub4dc, \uac00\ub3c5\uc131\uc774 \uc88b\uc740 \ucf54\ub4dc, \ucd94\uc0c1\ud654\uac00 \uc798 \ub418\uc5b4\uc788\ub294 \ucf54\ub4dc",(0,t.jsx)(r.br,{}),"\n","\uc77d\uae30 \uc88b\uace0, \uac04\uacb0\ud55c \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \ubc29\ubc95\uc744 \ubc30\uc6b4 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucf54\ub4dc\ub97c \ubc14\ub77c\ubcf4\ub294 \uc2dc\uc810\uc774 \ud558\ub098 \ub298\uc5b4\ub09c \uae30\ubd84\uc774\ub2e4!(\uc55e\uc73c\ub85c \uc801\uc6a9\ud558\ub294 \uac83\uc740 \ub098\uc758 \ubaab\uc774\uc9c0\ub9cc)"]}),"\n",(0,t.jsx)(r.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uc0dd\uac01 \uc815\ub9ac"}),(0,t.jsx)(r.br,{}),"\n","\uc911\uac04 \uc911\uac04 \ud604\uc7ac \uc0c1\ud669\uc5d0 \ub300\ud574 \uadf8\ub9bc\uc744 \uadf8\ub9ac\uac70\ub098, \uae00\uc744 \uc801\uc73c\uba74\uc11c \uc815\ub9ac\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud398\uc5b4\uc640 \ub3d9\uc77c\ud55c \ubd80\ubd84\uc744 \uc774\ud574\ud558\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc9c4\ud589\ud558\ub294\ub370 \ub9e4\uc6b0 \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub098\ub3c4 \ub2e4\uc74c \ud398\uc5b4\ub54c\ubd80\ud130 \ud39c\uc774\ub791 \uc885\uc774\ub97c \uc900\ube44\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uac00\uac10\uc5c6\uc774 \uc758\uacac\uc744 \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84"}),(0,t.jsx)(r.br,{}),"\n","\uc9c4\ud589 \uc0c1\ud669\uc5d0 \ub300\ud55c \ubd80\ubd84, \uc9c4\ud589 \uc18d\ub3c4, \uc9c0\uae08 \uc790\uc2e0\uc774 \uc774\ud574\ud558\uace0 \uc788\ub294 \ubd80\ubd84\uc744 \ub9d0\ud574\uc918\uc11c \ud3b8\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud68c\uace0\ub54c\ub3c4 \uc11c\ub85c \uc194\uc9c1\ud558\uac8c \uc758\uacac\uc744 \uc8fc\uace0 \ubc1b\uc544\uc11c \uc88b\uc558\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ub3c4\uba54\uc778 \uc5b8\uc5b4\uc5d0 \uc2e0\uacbd\uc4f0\ub294 \ubd80\ubd84"}),(0,t.jsx)(r.br,{}),"\n","\ud074\ub798\uc2a4\uba85, \ubcc0\uc218\uba85\uacfc \uac19\uc740 \uc5b8\uc5b4\ub97c \uc138\uc2ec\ud558\uac8c \uc2e0\uacbd\uc4f4\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc694\uad6c\uc0ac\ud56d \uc815\ub9ac\ub3c4 \uae54\ub054\ud558\uac8c \uc798\ud558\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:"\ud6c4\ucd94 \ucd5c\uace0 \ud83d\udc4d"})]})}function p(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(j,{...e})}):j(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>l});var t=n(67294);function s(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function c(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var r=1;r=0||(s[n]=e[n]);return s}(e,r);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var i=t.createContext({}),l=function(e){var r=t.useContext(i),n=r;return e&&(n="function"==typeof e?e(r):o(o({},r),e)),n},j={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},p=t.forwardRef((function(e,r){var n=e.components,s=e.mdxType,c=e.originalType,i=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),b=l(n),h=s,u=b["".concat(i,".").concat(h)]||b[h]||j[h]||c;return n?t.createElement(u,o(o({ref:r},p),{},{components:n})):t.createElement(u,o({ref:r},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/3ed04b60.f8fa3b6d.js b/assets/js/3ed04b60.6fb6f83d.js similarity index 86% rename from assets/js/3ed04b60.f8fa3b6d.js rename to assets/js/3ed04b60.6fb6f83d.js index 35cdc6879..1c5b37f24 100644 --- a/assets/js/3ed04b60.f8fa3b6d.js +++ b/assets/js/3ed04b60.6fb6f83d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7157],{84792:e=>{e.exports=JSON.parse('{"label":"Spring","permalink":"/tags/spring","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7157],{84792:e=>{e.exports=JSON.parse('{"label":"Spring","permalink":"/tags/spring","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/3f6ea930.ae70e445.js b/assets/js/3f6ea930.ae70e445.js deleted file mode 100644 index d33d565c6..000000000 --- a/assets/js/3f6ea930.ae70e445.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5186],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function u(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),o=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):u(u({},t),e)),r},c=function(e){var t=o(e.components);return n.createElement(i.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),p=o(r),d=a,v=p["".concat(i,".").concat(d)]||p[d]||m[d]||l;return r?n.createElement(v,u(u({ref:t},c),{},{components:r})):n.createElement(v,u({ref:t},c))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,u=new Array(l);u[0]=p;var s={};for(var i in t)hasOwnProperty.call(t,i)&&(s[i]=t[i]);s.originalType=e,s.mdxType="string"==typeof e?e:a,u[1]=s;for(var o=2;o{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>u,default:()=>m,frontMatter:()=>l,metadata:()=>s,toc:()=>o});var n=r(87462),a=(r(67294),r(3905));const l={title:"Parameterized Tests",slug:"parameterized-tests",tags:["Java"]},u=void 0,s={permalink:"/parameterized-tests",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-12-Parameterized Tests.mdx",source:"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx",title:"Parameterized Tests",description:"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.",date:"2023-02-12T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 12\uc77c",tags:[{label:"Java",permalink:"/tags/java"}],readingTime:3.17,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Parameterized Tests",slug:"parameterized-tests",tags:["Java"]},prevItem:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",permalink:"/racing-car-retrospective"},nextItem:{title:"IntelliJ \uc124\uc815",permalink:"/intellij-settings"}},i={authorsImageUrls:[]},o=[{value:"Argument Sources",id:"argument-sources",level:2},{value:"Value Source",id:"value-source",level:3},{value:"Null & Empty Source",id:"null--empty-source",level:3},{value:"Enum Source",id:"enum-source",level:3},{value:"CSV Source",id:"csv-source",level:3},{value:"Method Source",id:"method-source",level:3},{value:"ETC.",id:"etc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],c={toc:o};function m(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c ",(0,a.kt)("inlineCode",{parentName:"p"},"@ParameterizedTest"),"\ub97c \uc0ac\uc6a9\ud558\uba74 \ub2e8\uc77c \ud14c\uc2a4\ud2b8\ub97c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc5ec\ub7ec \ubc88 \ubc18\ubcf5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("h2",{id:"argument-sources"},"Argument Sources"),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"@ParameterizedTest"),"\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \ucd5c\uc18c \ud558\ub098 \uc774\uc0c1\uc758 Source \uc560\ub178\ud14c\uc774\uc158\uc774 \ud544\uc694\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","JUnit\uc774 \uc81c\uacf5\ud558\ub294 \ub2e4\uc591\ud55c Source\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0, \ud14c\uc2a4\ud2b8\uc5d0 \ub9de\ucdb0 \ub2e4\uc591\ud558\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("h3",{id:"value-source"},"Value Source"),(0,a.kt)("p",null,"\uac12\uc744 \uc774\uc6a9\ud558\uc5ec \uc81c\uacf5\ud558\ub294 \ud615\ud0dc\ub85c, \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"short, int, long, float, double"),(0,a.kt)("li",{parentName:"ul"},"byte, char, boolean, String, Class ")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@ParameterizedTest\n@ValueSource(ints = {1, 100, Integer.MAX_VALUE})\nvoid valueTest(final int value) {\n Assertions.assertThat(value).isPositive();\n}\n")),(0,a.kt)("h3",{id:"null--empty-source"},"Null & Empty Source"),(0,a.kt)("p",null,"null \uac12, \ube48 \uac12\uc744 \uc81c\uacf5\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Empty Source\uc758 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc5d0 \ud55c\ud574 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"String"),(0,a.kt)("li",{parentName:"ul"},"java.util.List, java.util.Set, java.util.Map"),(0,a.kt)("li",{parentName:"ul"},"primitive arrays \u2014 ex) int[]"),(0,a.kt)("li",{parentName:"ul"},"object arrays \u2014 ex) String[]")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@ParameterizedTest\n@NullAndEmptySource\nvoid nullAndEmptyTest(final String value) {\n Assertions.assertThat(value).isNullOrEmpty();\n}\n")),(0,a.kt)("h3",{id:"enum-source"},"Enum Source"),(0,a.kt)("p",null,"EnumSource\ub97c \uc774\uc6a9\ud558\uc5ec Enum \ub610\ud55c \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"enum Day {\n MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n}\n\n@ParameterizedTest\n@EnumSource(Day.class)\nvoid enumTest(final Day day) {\n assertThat(day).isInstanceOf(Day.class);\n}\n")),(0,a.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 mode \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b9\uc9d5 Enum\uc744 \uc81c\uc678\ud558\uac70\ub098, \ud3ec\ud568\uc2dc\ud0ac \uc218 \uc788\ub2e4. (default: Mode.Include)"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@ParameterizedTest\n@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)\nvoid enumTest(final Day day) {\n // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY\n assertThat(day).isInstanceOf(Day.class);\n}\n')),(0,a.kt)("h3",{id:"csv-source"},"CSV Source"),(0,a.kt)("p",null,"csv \ud615\uc2dd\uc758 \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uad6c\ubd84\uc790\uc758 \uae30\ubcf8\uac12\uc740 \uc27c\ud45c(,)\ub85c \uad6c\ubd84\uc790\ub97c \ubcc0\uacbd\ud558\uace0 \uc2f6\uc744 \ub550 delimeter \uac12\uc744 \ub530\ub85c \uc804\ub2ec\ud558\uc5ec \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\n\uac1c\uc778\uc801\uc73c\ub85c 2\uac1c \uc815\ub3c4\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc804\ub2ec\ud558\ub294 \uacbd\uc6b0 CsvSource\ub97c \uc0ac\uc6a9\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@ParameterizedTest\n@CsvSource({"1,1", "2,4", "3,9", "4,16"})\nvoid csvTest(final int number, final int result) {\n assertThat(number * number).isEqualTo(result);\n}\n')),(0,a.kt)("h3",{id:"method-source"},"Method Source"),(0,a.kt)("p",null,"\ubcf5\uc7a1\ud55c \ud0c0\uc785\uc758 \uac12\uc744 \uc804\ub2ec\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uba54\uc11c\ub4dc\uba85\uc744 \uc785\ub825\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uba54\uc11c\ub4dc\uba85\uc744 \ub530\ub85c \uc785\ub825\ud558\uc9c0 \uc54a\uc73c\uba74 \ud14c\uc2a4\ud2b8\uba85\uacfc \ub3d9\uc77c\ud55c static \uba54\uc11c\ub4dc\uac00 \uc9c0\uc815\ub41c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@ParameterizedTest\n@MethodSource\nvoid methodTest(final List numbers, final int count) {\n assertThat(numbers).hasSize(count);\n}\n\nprivate static Stream methodTest() {\n return Stream.of(\n Arguments.of(List.of(1), 1),\n Arguments.of(List.of(1, 2), 2),\n Arguments.of(List.of(1, 2, 3), 3)\n );\n}\n")),(0,a.kt)("h3",{id:"etc"},"ETC."),(0,a.kt)("p",null,"\uc704\uc5d0\uc11c \uc5b8\uae09\ud55c \ubc29\ubc95 \uc774\uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ubc29\ubc95\uc73c\ub85c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"CSV \ud30c\uc77c\uc744 \uc774\uc6a9\ud55c CsvFileSource"),(0,a.kt)("li",{parentName:"ul"},"ArgumentsProvider \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \uc774\uc6a9\ud558\ub294 ArgumentsSource")),(0,a.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.baeldung.com/parameterized-tests-junit-5"},"Guide to JUnit 5 Parameterized Tests"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3f6ea930.c12b117e.js b/assets/js/3f6ea930.c12b117e.js new file mode 100644 index 000000000..e6417dff4 --- /dev/null +++ b/assets/js/3f6ea930.c12b117e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5186],{74818:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>l,toc:()=>u});var t=r(85893),s=r(3905);const a={title:"Parameterized Tests",slug:"parameterized-tests",tags:["Java"]},i=void 0,l={permalink:"/parameterized-tests",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-12-Parameterized Tests.mdx",source:"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx",title:"Parameterized Tests",description:"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.",date:"2023-02-12T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 12\uc77c",tags:[{label:"Java",permalink:"/tags/java"}],readingTime:3.17,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Parameterized Tests",slug:"parameterized-tests",tags:["Java"]},unlisted:!1,prevItem:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",permalink:"/racing-car-retrospective"},nextItem:{title:"IntelliJ \uc124\uc815",permalink:"/intellij-settings"}},c={authorsImageUrls:[]},u=[{value:"Argument Sources",id:"argument-sources",level:2},{value:"Value Source",id:"value-source",level:3},{value:"Null & Empty Source",id:"null--empty-source",level:3},{value:"Enum Source",id:"enum-source",level:3},{value:"CSV Source",id:"csv-source",level:3},{value:"Method Source",id:"method-source",level:3},{value:"ETC.",id:"etc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function o(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \ub54c ",(0,t.jsx)(n.code,{children:"@ParameterizedTest"}),"\ub97c \uc0ac\uc6a9\ud558\uba74 \ub2e8\uc77c \ud14c\uc2a4\ud2b8\ub97c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc5ec\ub7ec \ubc88 \ubc18\ubcf5\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.h2,{id:"argument-sources",children:"Argument Sources"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"@ParameterizedTest"}),"\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \ucd5c\uc18c \ud558\ub098 \uc774\uc0c1\uc758 Source \uc560\ub178\ud14c\uc774\uc158\uc774 \ud544\uc694\ud558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","JUnit\uc774 \uc81c\uacf5\ud558\ub294 \ub2e4\uc591\ud55c Source\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0, \ud14c\uc2a4\ud2b8\uc5d0 \ub9de\ucdb0 \ub2e4\uc591\ud558\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"value-source",children:"Value Source"}),"\n",(0,t.jsx)(n.p,{children:"\uac12\uc744 \uc774\uc6a9\ud558\uc5ec \uc81c\uacf5\ud558\ub294 \ud615\ud0dc\ub85c, \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"short, int, long, float, double"}),"\n",(0,t.jsx)(n.li,{children:"byte, char, boolean, String, Class"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"@ParameterizedTest\n@ValueSource(ints = {1, 100, Integer.MAX_VALUE})\nvoid valueTest(final int value) {\n Assertions.assertThat(value).isPositive();\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"null--empty-source",children:"Null & Empty Source"}),"\n",(0,t.jsxs)(n.p,{children:["null \uac12, \ube48 \uac12\uc744 \uc81c\uacf5\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Empty Source\uc758 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc5d0 \ud55c\ud574 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"String"}),"\n",(0,t.jsx)(n.li,{children:"java.util.List, java.util.Set, java.util.Map"}),"\n",(0,t.jsx)(n.li,{children:"primitive arrays \u2014 ex) int[]"}),"\n",(0,t.jsx)(n.li,{children:"object arrays \u2014 ex) String[]"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"@ParameterizedTest\n@NullAndEmptySource\nvoid nullAndEmptyTest(final String value) {\n Assertions.assertThat(value).isNullOrEmpty();\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"enum-source",children:"Enum Source"}),"\n",(0,t.jsx)(n.p,{children:"EnumSource\ub97c \uc774\uc6a9\ud558\uc5ec Enum \ub610\ud55c \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"enum Day {\n MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\n}\n\n@ParameterizedTest\n@EnumSource(Day.class)\nvoid enumTest(final Day day) {\n assertThat(day).isInstanceOf(Day.class);\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 mode \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b9\uc9d5 Enum\uc744 \uc81c\uc678\ud558\uac70\ub098, \ud3ec\ud568\uc2dc\ud0ac \uc218 \uc788\ub2e4. (default: Mode.Include)"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'@ParameterizedTest\n@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)\nvoid enumTest(final Day day) {\n // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY\n assertThat(day).isInstanceOf(Day.class);\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"csv-source",children:"CSV Source"}),"\n",(0,t.jsxs)(n.p,{children:["csv \ud615\uc2dd\uc758 \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uad6c\ubd84\uc790\uc758 \uae30\ubcf8\uac12\uc740 \uc27c\ud45c(,)\ub85c \uad6c\ubd84\uc790\ub97c \ubcc0\uacbd\ud558\uace0 \uc2f6\uc744 \ub550 delimeter \uac12\uc744 \ub530\ub85c \uc804\ub2ec\ud558\uc5ec \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\n\uac1c\uc778\uc801\uc73c\ub85c 2\uac1c \uc815\ub3c4\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc804\ub2ec\ud558\ub294 \uacbd\uc6b0 CsvSource\ub97c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'@ParameterizedTest\n@CsvSource({"1,1", "2,4", "3,9", "4,16"})\nvoid csvTest(final int number, final int result) {\n assertThat(number * number).isEqualTo(result);\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"method-source",children:"Method Source"}),"\n",(0,t.jsxs)(n.p,{children:["\ubcf5\uc7a1\ud55c \ud0c0\uc785\uc758 \uac12\uc744 \uc804\ub2ec\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba54\uc11c\ub4dc\uba85\uc744 \uc785\ub825\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba54\uc11c\ub4dc\uba85\uc744 \ub530\ub85c \uc785\ub825\ud558\uc9c0 \uc54a\uc73c\uba74 \ud14c\uc2a4\ud2b8\uba85\uacfc \ub3d9\uc77c\ud55c static \uba54\uc11c\ub4dc\uac00 \uc9c0\uc815\ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"@ParameterizedTest\n@MethodSource\nvoid methodTest(final List numbers, final int count) {\n assertThat(numbers).hasSize(count);\n}\n\nprivate static Stream methodTest() {\n return Stream.of(\n Arguments.of(List.of(1), 1),\n Arguments.of(List.of(1, 2), 2),\n Arguments.of(List.of(1, 2, 3), 3)\n );\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"etc",children:"ETC."}),"\n",(0,t.jsx)(n.p,{children:"\uc704\uc5d0\uc11c \uc5b8\uae09\ud55c \ubc29\ubc95 \uc774\uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ubc29\ubc95\uc73c\ub85c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"CSV \ud30c\uc77c\uc744 \uc774\uc6a9\ud55c CsvFileSource"}),"\n",(0,t.jsx)(n.li,{children:"ArgumentsProvider \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \uc774\uc6a9\ud558\ub294 ArgumentsSource"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.baeldung.com/parameterized-tests-junit-5",children:"Guide to JUnit 5 Parameterized Tests"})}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,s.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>u});var t=r(67294);function s(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n=0||(s[r]=e[r]);return s}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var c=t.createContext({}),u=function(e){var n=t.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},o={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,s=e.mdxType,a=e.originalType,c=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),m=u(r),h=s,p=m["".concat(c,".").concat(h)]||m[h]||o[h]||a;return r?t.createElement(p,i(i({ref:n},d),{},{components:r})):t.createElement(p,i({ref:n},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/4.4bc37b90.js b/assets/js/4.4bc37b90.js deleted file mode 100644 index ed1606ced..000000000 --- a/assets/js/4.4bc37b90.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see 4.4bc37b90.js.LICENSE.txt */ -(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4],{17967:(t,e)=>{"use strict";e.N=void 0;var n=/^([^\w]*)(javascript|data|vbscript)/im,i=/&#(\w+)(^\w|;)?/g,r=/&(newline|tab);/gi,a=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,s=/^.+(:|:)/gim,o=[".","/"];e.N=function(t){var e,c=(e=t||"",e.replace(i,(function(t,e){return String.fromCharCode(e)}))).replace(r,"").replace(a,"").trim();if(!c)return"about:blank";if(function(t){return o.indexOf(t[0])>-1}(c))return c;var l=c.match(s);if(!l)return c;var h=l[0];return n.test(h)?"about:blank":c}},3905:(t,e,n)=>{"use strict";n.d(e,{Zo:()=>h,kt:()=>p});var i=n(67294);function r(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function a(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function s(t){for(var e=1;e=0||(r[n]=t[n]);return r}(t,e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(t);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(r[n]=t[n])}return r}var c=i.createContext({}),l=function(t){var e=i.useContext(c),n=e;return t&&(n="function"==typeof t?t(e):s(s({},e),t)),n},h=function(t){var e=l(t.components);return i.createElement(c.Provider,{value:e},t.children)},u={inlineCode:"code",wrapper:function(t){var e=t.children;return i.createElement(i.Fragment,{},e)}},d=i.forwardRef((function(t,e){var n=t.components,r=t.mdxType,a=t.originalType,c=t.parentName,h=o(t,["components","mdxType","originalType","parentName"]),d=l(n),p=r,f=d["".concat(c,".").concat(p)]||d[p]||u[p]||a;return n?i.createElement(f,s(s({ref:e},h),{},{components:n})):i.createElement(f,s({ref:e},h))}));function p(t,e){var n=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var a=n.length,s=new Array(a);s[0]=d;var o={};for(var c in e)hasOwnProperty.call(e,c)&&(o[c]=e[c]);o.originalType=t,o.mdxType="string"==typeof t?t:r,s[1]=o;for(var l=2;l{"use strict";n.d(e,{Z:()=>h});var i=n(67294),r=n(95999),a=n(35281),s=n(87462),o=n(86010);const c="iconEdit_Z9Sw";function l(t){let{className:e,...n}=t;return i.createElement("svg",(0,s.Z)({fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,o.Z)(c,e),"aria-hidden":"true"},n),i.createElement("g",null,i.createElement("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})))}function h(t){let{editUrl:e}=t;return i.createElement("a",{href:e,target:"_blank",rel:"noreferrer noopener",className:a.k.common.editThisPage},i.createElement(l,null),i.createElement(r.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page"},"Edit this page"))}},92503:(t,e,n)=>{"use strict";n.d(e,{Z:()=>u});var i=n(87462),r=n(67294),a=n(86010),s=n(95999),o=n(86668),c=n(39960);const l="anchorWithStickyNavbar_LWe7",h="anchorWithHideOnScrollNavbar_WYt5";function u(t){let{as:e,id:n,...u}=t;const{navbar:{hideOnScroll:d}}=(0,o.L)();if("h1"===e||!n)return r.createElement(e,(0,i.Z)({},u,{id:void 0}));const p=(0,s.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return r.createElement(e,(0,i.Z)({},u,{className:(0,a.Z)("anchor",d?h:l,u.className),id:n}),u.children,r.createElement(c.Z,{className:"hash-link",to:`#${n}`,"aria-label":p,title:p},"\u200b"))}},38617:(t,e,n)=>{"use strict";n.d(e,{Z:()=>PL});var i=n(67294),r=n(3905),a=n(87462),s=n(35742);var o=n(72389),l=n(86010),h=n(92949),u=n(86668);function d(){const{prism:t}=(0,u.L)(),{colorMode:e}=(0,h.I)(),n=t.theme,i=t.darkTheme||n;return"dark"===e?i:n}var p=n(35281),f=n(87594),g=n.n(f);const y=/title=(?["'])(?.*?)\1/,m=/\{(?<range>[\d,-]+)\}/,b={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function _(t,e){const n=t.map((t=>{const{start:n,end:i}=b[t];return`(?:${n}\\s*(${e.flatMap((t=>[t.line,t.block?.start,t.block?.end].filter(Boolean))).join("|")})\\s*${i})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function x(t,e){let n=t.replace(/\n$/,"");const{language:i,magicComments:r,metastring:a}=e;if(a&&m.test(a)){const t=a.match(m).groups.range;if(0===r.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${a}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const e=r[0].className,i=g()(t).filter((t=>t>0)).map((t=>[t-1,[e]]));return{lineClassNames:Object.fromEntries(i),code:n}}if(void 0===i)return{lineClassNames:{},code:n};const s=function(t,e){switch(t){case"js":case"javascript":case"ts":case"typescript":return _(["js","jsBlock"],e);case"jsx":case"tsx":return _(["js","jsBlock","jsx"],e);case"html":return _(["js","jsBlock","html"],e);case"python":case"py":case"bash":return _(["bash"],e);case"markdown":case"md":return _(["html","jsx","bash"],e);default:return _(Object.keys(b),e)}}(i,r),o=n.split("\n"),c=Object.fromEntries(r.map((t=>[t.className,{start:0,range:""}]))),l=Object.fromEntries(r.filter((t=>t.line)).map((t=>{let{className:e,line:n}=t;return[n,e]}))),h=Object.fromEntries(r.filter((t=>t.block)).map((t=>{let{className:e,block:n}=t;return[n.start,e]}))),u=Object.fromEntries(r.filter((t=>t.block)).map((t=>{let{className:e,block:n}=t;return[n.end,e]})));for(let p=0;p<o.length;){const t=o[p].match(s);if(!t){p+=1;continue}const e=t.slice(1).find((t=>void 0!==t));l[e]?c[l[e]].range+=`${p},`:h[e]?c[h[e]].start=p:u[e]&&(c[u[e]].range+=`${c[u[e]].start}-${p-1},`),o.splice(p,1)}n=o.join("\n");const d={};return Object.entries(c).forEach((t=>{let[e,{range:n}]=t;g()(n).forEach((t=>{d[t]??=[],d[t].push(e)}))})),{lineClassNames:d,code:n}}const v="codeBlockContainer_Ckt0";function k(t){let{as:e,...n}=t;const r=function(t){const e={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(t.plain).forEach((t=>{let[i,r]=t;const a=e[i];a&&"string"==typeof r&&(n[a]=r)})),n}(d());return i.createElement(e,(0,a.Z)({},n,{style:r,className:(0,l.Z)(n.className,v,p.k.common.codeBlock)}))}const w={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function T(t){let{children:e,className:n}=t;return i.createElement(k,{as:"pre",tabIndex:0,className:(0,l.Z)(w.codeBlockStandalone,"thin-scrollbar",n)},i.createElement("code",{className:w.codeBlockLines},e))}var C=n(902);const E={attributes:!0,characterData:!0,childList:!0,subtree:!0};function S(t,e){const[n,r]=(0,i.useState)(),a=(0,i.useCallback)((()=>{r(t.current?.closest("[role=tabpanel][hidden]"))}),[t,r]);(0,i.useEffect)((()=>{a()}),[a]),function(t,e,n){void 0===n&&(n=E);const r=(0,C.zX)(e),a=(0,C.Ql)(n);(0,i.useEffect)((()=>{const e=new MutationObserver(r);return t&&e.observe(t,a),()=>e.disconnect()}),[t,r,a])}(n,(t=>{t.forEach((t=>{"attributes"===t.type&&"hidden"===t.attributeName&&(e(),a())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}const A={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]};var D={Prism:n(87410).Z,theme:A};function L(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function N(){return N=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},N.apply(this,arguments)}var O=/\r\n|\r|\n/,B=function(t){0===t.length?t.push({types:["plain"],content:"\n",empty:!0}):1===t.length&&""===t[0].content&&(t[0].content="\n",t[0].empty=!0)},M=function(t,e){var n=t.length;return n>0&&t[n-1]===e?t:t.concat(e)},I=function(t,e){var n=t.plain,i=Object.create(null),r=t.styles.reduce((function(t,n){var i=n.languages,r=n.style;return i&&!i.includes(e)||n.types.forEach((function(e){var n=N({},t[e],r);t[e]=n})),t}),i);return r.root=n,r.plain=N({},n,{backgroundColor:null}),r};function F(t,e){var n={};for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&-1===e.indexOf(i)&&(n[i]=t[i]);return n}var R=function(t){function e(){for(var e=this,n=[],i=arguments.length;i--;)n[i]=arguments[i];t.apply(this,n),L(this,"getThemeDict",(function(t){if(void 0!==e.themeDict&&t.theme===e.prevTheme&&t.language===e.prevLanguage)return e.themeDict;e.prevTheme=t.theme,e.prevLanguage=t.language;var n=t.theme?I(t.theme,t.language):void 0;return e.themeDict=n})),L(this,"getLineProps",(function(t){var n=t.key,i=t.className,r=t.style,a=N({},F(t,["key","className","style","line"]),{className:"token-line",style:void 0,key:void 0}),s=e.getThemeDict(e.props);return void 0!==s&&(a.style=s.plain),void 0!==r&&(a.style=void 0!==a.style?N({},a.style,r):r),void 0!==n&&(a.key=n),i&&(a.className+=" "+i),a})),L(this,"getStyleForToken",(function(t){var n=t.types,i=t.empty,r=n.length,a=e.getThemeDict(e.props);if(void 0!==a){if(1===r&&"plain"===n[0])return i?{display:"inline-block"}:void 0;if(1===r&&!i)return a[n[0]];var s=i?{display:"inline-block"}:{},o=n.map((function(t){return a[t]}));return Object.assign.apply(Object,[s].concat(o))}})),L(this,"getTokenProps",(function(t){var n=t.key,i=t.className,r=t.style,a=t.token,s=N({},F(t,["key","className","style","token"]),{className:"token "+a.types.join(" "),children:a.content,style:e.getStyleForToken(a),key:void 0});return void 0!==r&&(s.style=void 0!==s.style?N({},s.style,r):r),void 0!==n&&(s.key=n),i&&(s.className+=" "+i),s})),L(this,"tokenize",(function(t,e,n,i){var r={code:e,grammar:n,language:i,tokens:[]};t.hooks.run("before-tokenize",r);var a=r.tokens=t.tokenize(r.code,r.grammar,r.language);return t.hooks.run("after-tokenize",r),a}))}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.render=function(){var t=this.props,e=t.Prism,n=t.language,i=t.code,r=t.children,a=this.getThemeDict(this.props),s=e.languages[n],o=function(t){for(var e=[[]],n=[t],i=[0],r=[t.length],a=0,s=0,o=[],c=[o];s>-1;){for(;(a=i[s]++)<r[s];){var l=void 0,h=e[s],u=n[s][a];if("string"==typeof u?(h=s>0?h:["plain"],l=u):(h=M(h,u.type),u.alias&&(h=M(h,u.alias)),l=u.content),"string"==typeof l){var d=l.split(O),p=d.length;o.push({types:h,content:d[0]});for(var f=1;f<p;f++)B(o),c.push(o=[]),o.push({types:h,content:d[f]})}else s++,e.push(h),n.push(l),i.push(0),r.push(l.length)}s--,e.pop(),n.pop(),i.pop(),r.pop()}return B(o),c}(void 0!==s?this.tokenize(e,i,s,n):[i]);return r({tokens:o,className:"prism-code language-"+n,style:void 0!==a?a.root:{},getLineProps:this.getLineProps,getTokenProps:this.getTokenProps})},e}(i.Component);const $=R,P="codeLine_lJS_",j="codeLineNumber_Tfdd",Y="codeLineContent_feaV";function z(t){let{line:e,classNames:n,showLineNumbers:r,getLineProps:s,getTokenProps:o}=t;1===e.length&&"\n"===e[0].content&&(e[0].content="");const c=s({line:e,className:(0,l.Z)(n,r&&P)}),h=e.map(((t,e)=>i.createElement("span",(0,a.Z)({key:e},o({token:t,key:e})))));return i.createElement("span",c,r?i.createElement(i.Fragment,null,i.createElement("span",{className:j}),i.createElement("span",{className:Y},h)):h,i.createElement("br",null))}var U=n(95999);function W(t){return i.createElement("svg",(0,a.Z)({viewBox:"0 0 24 24"},t),i.createElement("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"}))}function H(t){return i.createElement("svg",(0,a.Z)({viewBox:"0 0 24 24"},t),i.createElement("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"}))}const q={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function V(t){let{code:e,className:n}=t;const[r,a]=(0,i.useState)(!1),s=(0,i.useRef)(void 0),o=(0,i.useCallback)((()=>{!function(t,e){let{target:n=document.body}=void 0===e?{}:e;const i=document.createElement("textarea"),r=document.activeElement;i.value=t,i.setAttribute("readonly",""),i.style.contain="strict",i.style.position="absolute",i.style.left="-9999px",i.style.fontSize="12pt";const a=document.getSelection();let s=!1;a.rangeCount>0&&(s=a.getRangeAt(0)),n.append(i),i.select(),i.selectionStart=0,i.selectionEnd=t.length;let o=!1;try{o=document.execCommand("copy")}catch{}i.remove(),s&&(a.removeAllRanges(),a.addRange(s)),r&&r.focus()}(e),a(!0),s.current=window.setTimeout((()=>{a(!1)}),1e3)}),[e]);return(0,i.useEffect)((()=>()=>window.clearTimeout(s.current)),[]),i.createElement("button",{type:"button","aria-label":r?(0,U.I)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,U.I)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,U.I)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,l.Z)("clean-btn",n,q.copyButton,r&&q.copyButtonCopied),onClick:o},i.createElement("span",{className:q.copyButtonIcons,"aria-hidden":"true"},i.createElement(W,{className:q.copyButtonIcon}),i.createElement(H,{className:q.copyButtonSuccessIcon})))}function G(t){return i.createElement("svg",(0,a.Z)({viewBox:"0 0 24 24"},t),i.createElement("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"}))}const X="wordWrapButtonIcon_Bwma",Z="wordWrapButtonEnabled_EoeP";function Q(t){let{className:e,onClick:n,isEnabled:r}=t;const a=(0,U.I)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return i.createElement("button",{type:"button",onClick:n,className:(0,l.Z)("clean-btn",e,r&&Z),"aria-label":a,title:a},i.createElement(G,{className:X,"aria-hidden":"true"}))}function K(t){let{children:e,className:n="",metastring:r,title:s,showLineNumbers:o,language:c}=t;const{prism:{defaultLanguage:h,magicComments:p}}=(0,u.L)(),f=c??function(t){const e=t.split(" ").find((t=>t.startsWith("language-")));return e?.replace(/language-/,"")}(n)??h,g=d(),m=function(){const[t,e]=(0,i.useState)(!1),[n,r]=(0,i.useState)(!1),a=(0,i.useRef)(null),s=(0,i.useCallback)((()=>{const n=a.current.querySelector("code");t?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),e((t=>!t))}),[a,t]),o=(0,i.useCallback)((()=>{const{scrollWidth:t,clientWidth:e}=a.current,n=t>e||a.current.querySelector("code").hasAttribute("style");r(n)}),[a]);return S(a,o),(0,i.useEffect)((()=>{o()}),[t,o]),(0,i.useEffect)((()=>(window.addEventListener("resize",o,{passive:!0}),()=>{window.removeEventListener("resize",o)})),[o]),{codeBlockRef:a,isEnabled:t,isCodeScrollable:n,toggle:s}}(),b=function(t){return t?.match(y)?.groups.title??""}(r)||s,{lineClassNames:_,code:v}=x(e,{metastring:r,language:f,magicComments:p}),T=o??function(t){return Boolean(t?.includes("showLineNumbers"))}(r);return i.createElement(k,{as:"div",className:(0,l.Z)(n,f&&!n.includes(`language-${f}`)&&`language-${f}`)},b&&i.createElement("div",{className:w.codeBlockTitle},b),i.createElement("div",{className:w.codeBlockContent},i.createElement($,(0,a.Z)({},D,{theme:g,code:v,language:f??"text"}),(t=>{let{className:e,tokens:n,getLineProps:r,getTokenProps:a}=t;return i.createElement("pre",{tabIndex:0,ref:m.codeBlockRef,className:(0,l.Z)(e,w.codeBlock,"thin-scrollbar")},i.createElement("code",{className:(0,l.Z)(w.codeBlockLines,T&&w.codeBlockLinesWithNumbering)},n.map(((t,e)=>i.createElement(z,{key:e,line:t,getLineProps:r,getTokenProps:a,classNames:_[e],showLineNumbers:T})))))})),i.createElement("div",{className:w.buttonGroup},(m.isEnabled||m.isCodeScrollable)&&i.createElement(Q,{className:w.codeButton,onClick:()=>m.toggle(),isEnabled:m.isEnabled}),i.createElement(V,{className:w.codeButton,code:v}))))}function J(t){let{children:e,...n}=t;const r=(0,o.Z)(),s=function(t){return i.Children.toArray(t).some((t=>(0,i.isValidElement)(t)))?t:Array.isArray(t)?t.join(""):t}(e),c="string"==typeof s?K:T;return i.createElement(c,(0,a.Z)({key:String(r)},n),s)}var tt=n(39960);var et=n(86043);const nt="details_lb9f",it="isBrowser_bmU9",rt="collapsibleContent_i85q";function at(t){return!!t&&("SUMMARY"===t.tagName||at(t.parentElement))}function st(t,e){return!!t&&(t===e||st(t.parentElement,e))}function ot(t){let{summary:e,children:n,...r}=t;const s=(0,o.Z)(),c=(0,i.useRef)(null),{collapsed:h,setCollapsed:u}=(0,et.u)({initialState:!r.open}),[d,p]=(0,i.useState)(r.open),f=i.isValidElement(e)?e:i.createElement("summary",null,e??"Details");return i.createElement("details",(0,a.Z)({},r,{ref:c,open:d,"data-collapsed":h,className:(0,l.Z)(nt,s&&it,r.className),onMouseDown:t=>{at(t.target)&&t.detail>1&&t.preventDefault()},onClick:t=>{t.stopPropagation();const e=t.target;at(e)&&st(e,c.current)&&(t.preventDefault(),h?(u(!1),p(!0)):u(!0))}}),f,i.createElement(et.z,{lazy:!1,collapsed:h,disableSSRStyle:!0,onCollapseTransitionEnd:t=>{u(t),p(!t)}},i.createElement("div",{className:rt},n)))}const ct="details_b_Ee";function lt(t){let{...e}=t;return i.createElement(ot,(0,a.Z)({},e,{className:(0,l.Z)("alert alert--info",ct,e.className)}))}var ht=n(92503);function ut(t){return i.createElement(ht.Z,t)}const dt="containsTaskList_mC6p";function pt(t){if(void 0!==t)return(0,l.Z)(t,t?.includes("contains-task-list")&&dt)}const ft="img_ev3q";const gt="admonition_LlT9",yt="admonitionHeading_tbUL",mt="admonitionIcon_kALy",bt="admonitionContent_S0QG";const _t={note:{infimaClassName:"secondary",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 14 16"},i.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:i.createElement(U.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 12 16"},i.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:i.createElement(U.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 12 16"},i.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:i.createElement(U.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 14 16"},i.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:i.createElement(U.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return i.createElement("svg",{viewBox:"0 0 16 16"},i.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:i.createElement(U.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},xt={secondary:"note",important:"info",success:"tip",warning:"danger"};function vt(t){const{mdxAdmonitionTitle:e,rest:n}=function(t){const e=i.Children.toArray(t),n=e.find((t=>i.isValidElement(t)&&"mdxAdmonitionTitle"===t.props?.mdxType)),r=i.createElement(i.Fragment,null,e.filter((t=>t!==n)));return{mdxAdmonitionTitle:n,rest:r}}(t.children);return{...t,title:t.title??e,children:n}}function kt(t){let{children:e,fallback:n}=t;return(0,o.Z)()?i.createElement(i.Fragment,null,e?.()):n??null}var wt=n(11941),Tt=n(17967);function Ct(t,e){let n;if(void 0===e)for(const i of t)null!=i&&(n<i||void 0===n&&i>=i)&&(n=i);else{let i=-1;for(let r of t)null!=(r=e(r,++i,t))&&(n<r||void 0===n&&r>=r)&&(n=r)}return n}function Et(t,e){let n;if(void 0===e)for(const i of t)null!=i&&(n>i||void 0===n&&i>=i)&&(n=i);else{let i=-1;for(let r of t)null!=(r=e(r,++i,t))&&(n>r||void 0===n&&r>=r)&&(n=r)}return n}function St(t){return t}var At=1e-6;function Dt(t){return"translate("+t+",0)"}function Lt(t){return"translate(0,"+t+")"}function Nt(t){return e=>+t(e)}function Ot(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),n=>+t(n)+e}function Bt(){return!this.__axis}function Mt(t,e){var n=[],i=null,r=null,a=6,s=6,o=3,c="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,l=1===t||4===t?-1:1,h=4===t||2===t?"x":"y",u=1===t||3===t?Dt:Lt;function d(d){var p=null==i?e.ticks?e.ticks.apply(e,n):e.domain():i,f=null==r?e.tickFormat?e.tickFormat.apply(e,n):St:r,g=Math.max(a,0)+o,y=e.range(),m=+y[0]+c,b=+y[y.length-1]+c,_=(e.bandwidth?Ot:Nt)(e.copy(),c),x=d.selection?d.selection():d,v=x.selectAll(".domain").data([null]),k=x.selectAll(".tick").data(p,e).order(),w=k.exit(),T=k.enter().append("g").attr("class","tick"),C=k.select("line"),E=k.select("text");v=v.merge(v.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),k=k.merge(T),C=C.merge(T.append("line").attr("stroke","currentColor").attr(h+"2",l*a)),E=E.merge(T.append("text").attr("fill","currentColor").attr(h,l*g).attr("dy",1===t?"0em":3===t?"0.71em":"0.32em")),d!==x&&(v=v.transition(d),k=k.transition(d),C=C.transition(d),E=E.transition(d),w=w.transition(d).attr("opacity",At).attr("transform",(function(t){return isFinite(t=_(t))?u(t+c):this.getAttribute("transform")})),T.attr("opacity",At).attr("transform",(function(t){var e=this.parentNode.__axis;return u((e&&isFinite(e=e(t))?e:_(t))+c)}))),w.remove(),v.attr("d",4===t||2===t?s?"M"+l*s+","+m+"H"+c+"V"+b+"H"+l*s:"M"+c+","+m+"V"+b:s?"M"+m+","+l*s+"V"+c+"H"+b+"V"+l*s:"M"+m+","+c+"H"+b),k.attr("opacity",1).attr("transform",(function(t){return u(_(t)+c)})),C.attr(h+"2",l*a),E.attr(h,l*g).text(f),x.filter(Bt).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",2===t?"start":4===t?"end":"middle"),x.each((function(){this.__axis=_}))}return d.scale=function(t){return arguments.length?(e=t,d):e},d.ticks=function(){return n=Array.from(arguments),d},d.tickArguments=function(t){return arguments.length?(n=null==t?[]:Array.from(t),d):n.slice()},d.tickValues=function(t){return arguments.length?(i=null==t?null:Array.from(t),d):i&&i.slice()},d.tickFormat=function(t){return arguments.length?(r=t,d):r},d.tickSize=function(t){return arguments.length?(a=s=+t,d):a},d.tickSizeInner=function(t){return arguments.length?(a=+t,d):a},d.tickSizeOuter=function(t){return arguments.length?(s=+t,d):s},d.tickPadding=function(t){return arguments.length?(o=+t,d):o},d.offset=function(t){return arguments.length?(c=+t,d):c},d}function It(){}function Ft(t){return null==t?It:function(){return this.querySelector(t)}}function Rt(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function $t(){return[]}function Pt(t){return null==t?$t:function(){return this.querySelectorAll(t)}}function jt(t){return function(){return this.matches(t)}}function Yt(t){return function(e){return e.matches(t)}}var zt=Array.prototype.find;function Ut(){return this.firstElementChild}var Wt=Array.prototype.filter;function Ht(){return Array.from(this.children)}function qt(t){return new Array(t.length)}function Vt(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function Gt(t){return function(){return t}}function Xt(t,e,n,i,r,a){for(var s,o=0,c=e.length,l=a.length;o<l;++o)(s=e[o])?(s.__data__=a[o],i[o]=s):n[o]=new Vt(t,a[o]);for(;o<c;++o)(s=e[o])&&(r[o]=s)}function Zt(t,e,n,i,r,a,s){var o,c,l,h=new Map,u=e.length,d=a.length,p=new Array(u);for(o=0;o<u;++o)(c=e[o])&&(p[o]=l=s.call(c,c.__data__,o,e)+"",h.has(l)?r[o]=c:h.set(l,c));for(o=0;o<d;++o)l=s.call(t,a[o],o,a)+"",(c=h.get(l))?(i[o]=c,c.__data__=a[o],h.delete(l)):n[o]=new Vt(t,a[o]);for(o=0;o<u;++o)(c=e[o])&&h.get(p[o])===c&&(r[o]=c)}function Qt(t){return t.__data__}function Kt(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function Jt(t,e){return t<e?-1:t>e?1:t>=e?0:NaN}Vt.prototype={constructor:Vt,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var te="http://www.w3.org/1999/xhtml";const ee={svg:"http://www.w3.org/2000/svg",xhtml:te,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function ne(t){var e=t+="",n=e.indexOf(":");return n>=0&&"xmlns"!==(e=t.slice(0,n))&&(t=t.slice(n+1)),ee.hasOwnProperty(e)?{space:ee[e],local:t}:t}function ie(t){return function(){this.removeAttribute(t)}}function re(t){return function(){this.removeAttributeNS(t.space,t.local)}}function ae(t,e){return function(){this.setAttribute(t,e)}}function se(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function oe(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttribute(t):this.setAttribute(t,n)}}function ce(t,e){return function(){var n=e.apply(this,arguments);null==n?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,n)}}function le(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function he(t){return function(){this.style.removeProperty(t)}}function ue(t,e,n){return function(){this.style.setProperty(t,e,n)}}function de(t,e,n){return function(){var i=e.apply(this,arguments);null==i?this.style.removeProperty(t):this.style.setProperty(t,i,n)}}function pe(t,e){return t.style.getPropertyValue(e)||le(t).getComputedStyle(t,null).getPropertyValue(e)}function fe(t){return function(){delete this[t]}}function ge(t,e){return function(){this[t]=e}}function ye(t,e){return function(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}}function me(t){return t.trim().split(/^|\s+/)}function be(t){return t.classList||new _e(t)}function _e(t){this._node=t,this._names=me(t.getAttribute("class")||"")}function xe(t,e){for(var n=be(t),i=-1,r=e.length;++i<r;)n.add(e[i])}function ve(t,e){for(var n=be(t),i=-1,r=e.length;++i<r;)n.remove(e[i])}function ke(t){return function(){xe(this,t)}}function we(t){return function(){ve(this,t)}}function Te(t,e){return function(){(e.apply(this,arguments)?xe:ve)(this,t)}}function Ce(){this.textContent=""}function Ee(t){return function(){this.textContent=t}}function Se(t){return function(){var e=t.apply(this,arguments);this.textContent=null==e?"":e}}function Ae(){this.innerHTML=""}function De(t){return function(){this.innerHTML=t}}function Le(t){return function(){var e=t.apply(this,arguments);this.innerHTML=null==e?"":e}}function Ne(){this.nextSibling&&this.parentNode.appendChild(this)}function Oe(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function Be(t){return function(){var e=this.ownerDocument,n=this.namespaceURI;return n===te&&e.documentElement.namespaceURI===te?e.createElement(t):e.createElementNS(n,t)}}function Me(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function Ie(t){var e=ne(t);return(e.local?Me:Be)(e)}function Fe(){return null}function Re(){var t=this.parentNode;t&&t.removeChild(this)}function $e(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function Pe(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function je(t){return t.trim().split(/^|\s+/).map((function(t){var e="",n=t.indexOf(".");return n>=0&&(e=t.slice(n+1),t=t.slice(0,n)),{type:t,name:e}}))}function Ye(t){return function(){var e=this.__on;if(e){for(var n,i=0,r=-1,a=e.length;i<a;++i)n=e[i],t.type&&n.type!==t.type||n.name!==t.name?e[++r]=n:this.removeEventListener(n.type,n.listener,n.options);++r?e.length=r:delete this.__on}}}function ze(t,e,n){return function(){var i,r=this.__on,a=function(t){return function(e){t.call(this,e,this.__data__)}}(e);if(r)for(var s=0,o=r.length;s<o;++s)if((i=r[s]).type===t.type&&i.name===t.name)return this.removeEventListener(i.type,i.listener,i.options),this.addEventListener(i.type,i.listener=a,i.options=n),void(i.value=e);this.addEventListener(t.type,a,n),i={type:t.type,name:t.name,value:e,listener:a,options:n},r?r.push(i):this.__on=[i]}}function Ue(t,e,n){var i=le(t),r=i.CustomEvent;"function"==typeof r?r=new r(e,n):(r=i.document.createEvent("Event"),n?(r.initEvent(e,n.bubbles,n.cancelable),r.detail=n.detail):r.initEvent(e,!1,!1)),t.dispatchEvent(r)}function We(t,e){return function(){return Ue(this,t,e)}}function He(t,e){return function(){return Ue(this,t,e.apply(this,arguments))}}_e.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var qe=[null];function Ve(t,e){this._groups=t,this._parents=e}function Ge(){return new Ve([[document.documentElement]],qe)}Ve.prototype=Ge.prototype={constructor:Ve,select:function(t){"function"!=typeof t&&(t=Ft(t));for(var e=this._groups,n=e.length,i=new Array(n),r=0;r<n;++r)for(var a,s,o=e[r],c=o.length,l=i[r]=new Array(c),h=0;h<c;++h)(a=o[h])&&(s=t.call(a,a.__data__,h,o))&&("__data__"in a&&(s.__data__=a.__data__),l[h]=s);return new Ve(i,this._parents)},selectAll:function(t){t="function"==typeof t?function(t){return function(){return Rt(t.apply(this,arguments))}}(t):Pt(t);for(var e=this._groups,n=e.length,i=[],r=[],a=0;a<n;++a)for(var s,o=e[a],c=o.length,l=0;l<c;++l)(s=o[l])&&(i.push(t.call(s,s.__data__,l,o)),r.push(s));return new Ve(i,r)},selectChild:function(t){return this.select(null==t?Ut:function(t){return function(){return zt.call(this.children,t)}}("function"==typeof t?t:Yt(t)))},selectChildren:function(t){return this.selectAll(null==t?Ht:function(t){return function(){return Wt.call(this.children,t)}}("function"==typeof t?t:Yt(t)))},filter:function(t){"function"!=typeof t&&(t=jt(t));for(var e=this._groups,n=e.length,i=new Array(n),r=0;r<n;++r)for(var a,s=e[r],o=s.length,c=i[r]=[],l=0;l<o;++l)(a=s[l])&&t.call(a,a.__data__,l,s)&&c.push(a);return new Ve(i,this._parents)},data:function(t,e){if(!arguments.length)return Array.from(this,Qt);var n=e?Zt:Xt,i=this._parents,r=this._groups;"function"!=typeof t&&(t=Gt(t));for(var a=r.length,s=new Array(a),o=new Array(a),c=new Array(a),l=0;l<a;++l){var h=i[l],u=r[l],d=u.length,p=Kt(t.call(h,h&&h.__data__,l,i)),f=p.length,g=o[l]=new Array(f),y=s[l]=new Array(f),m=c[l]=new Array(d);n(h,u,g,y,m,p,e);for(var b,_,x=0,v=0;x<f;++x)if(b=g[x]){for(x>=v&&(v=x+1);!(_=y[v])&&++v<f;);b._next=_||null}}return(s=new Ve(s,i))._enter=o,s._exit=c,s},enter:function(){return new Ve(this._enter||this._groups.map(qt),this._parents)},exit:function(){return new Ve(this._exit||this._groups.map(qt),this._parents)},join:function(t,e,n){var i=this.enter(),r=this,a=this.exit();return"function"==typeof t?(i=t(i))&&(i=i.selection()):i=i.append(t+""),null!=e&&(r=e(r))&&(r=r.selection()),null==n?a.remove():n(a),i&&r?i.merge(r).order():r},merge:function(t){for(var e=t.selection?t.selection():t,n=this._groups,i=e._groups,r=n.length,a=i.length,s=Math.min(r,a),o=new Array(r),c=0;c<s;++c)for(var l,h=n[c],u=i[c],d=h.length,p=o[c]=new Array(d),f=0;f<d;++f)(l=h[f]||u[f])&&(p[f]=l);for(;c<r;++c)o[c]=n[c];return new Ve(o,this._parents)},selection:function(){return this},order:function(){for(var t=this._groups,e=-1,n=t.length;++e<n;)for(var i,r=t[e],a=r.length-1,s=r[a];--a>=0;)(i=r[a])&&(s&&4^i.compareDocumentPosition(s)&&s.parentNode.insertBefore(i,s),s=i);return this},sort:function(t){function e(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}t||(t=Jt);for(var n=this._groups,i=n.length,r=new Array(i),a=0;a<i;++a){for(var s,o=n[a],c=o.length,l=r[a]=new Array(c),h=0;h<c;++h)(s=o[h])&&(l[h]=s);l.sort(e)}return new Ve(r,this._parents).order()},call:function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},nodes:function(){return Array.from(this)},node:function(){for(var t=this._groups,e=0,n=t.length;e<n;++e)for(var i=t[e],r=0,a=i.length;r<a;++r){var s=i[r];if(s)return s}return null},size:function(){let t=0;for(const e of this)++t;return t},empty:function(){return!this.node()},each:function(t){for(var e=this._groups,n=0,i=e.length;n<i;++n)for(var r,a=e[n],s=0,o=a.length;s<o;++s)(r=a[s])&&t.call(r,r.__data__,s,a);return this},attr:function(t,e){var n=ne(t);if(arguments.length<2){var i=this.node();return n.local?i.getAttributeNS(n.space,n.local):i.getAttribute(n)}return this.each((null==e?n.local?re:ie:"function"==typeof e?n.local?ce:oe:n.local?se:ae)(n,e))},style:function(t,e,n){return arguments.length>1?this.each((null==e?he:"function"==typeof e?de:ue)(t,e,null==n?"":n)):pe(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?fe:"function"==typeof e?ye:ge)(t,e)):this.node()[t]},classed:function(t,e){var n=me(t+"");if(arguments.length<2){for(var i=be(this.node()),r=-1,a=n.length;++r<a;)if(!i.contains(n[r]))return!1;return!0}return this.each(("function"==typeof e?Te:e?ke:we)(n,e))},text:function(t){return arguments.length?this.each(null==t?Ce:("function"==typeof t?Se:Ee)(t)):this.node().textContent},html:function(t){return arguments.length?this.each(null==t?Ae:("function"==typeof t?Le:De)(t)):this.node().innerHTML},raise:function(){return this.each(Ne)},lower:function(){return this.each(Oe)},append:function(t){var e="function"==typeof t?t:Ie(t);return this.select((function(){return this.appendChild(e.apply(this,arguments))}))},insert:function(t,e){var n="function"==typeof t?t:Ie(t),i=null==e?Fe:"function"==typeof e?e:Ft(e);return this.select((function(){return this.insertBefore(n.apply(this,arguments),i.apply(this,arguments)||null)}))},remove:function(){return this.each(Re)},clone:function(t){return this.select(t?Pe:$e)},datum:function(t){return arguments.length?this.property("__data__",t):this.node().__data__},on:function(t,e,n){var i,r,a=je(t+""),s=a.length;if(!(arguments.length<2)){for(o=e?ze:Ye,i=0;i<s;++i)this.each(o(a[i],e,n));return this}var o=this.node().__on;if(o)for(var c,l=0,h=o.length;l<h;++l)for(i=0,c=o[l];i<s;++i)if((r=a[i]).type===c.type&&r.name===c.name)return c.value},dispatch:function(t,e){return this.each(("function"==typeof e?He:We)(t,e))},[Symbol.iterator]:function*(){for(var t=this._groups,e=0,n=t.length;e<n;++e)for(var i,r=t[e],a=0,s=r.length;a<s;++a)(i=r[a])&&(yield i)}};const Xe=Ge;var Ze={value:()=>{}};function Qe(){for(var t,e=0,n=arguments.length,i={};e<n;++e){if(!(t=arguments[e]+"")||t in i||/[\s.]/.test(t))throw new Error("illegal type: "+t);i[t]=[]}return new Ke(i)}function Ke(t){this._=t}function Je(t,e){return t.trim().split(/^|\s+/).map((function(t){var n="",i=t.indexOf(".");if(i>=0&&(n=t.slice(i+1),t=t.slice(0,i)),t&&!e.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:n}}))}function tn(t,e){for(var n,i=0,r=t.length;i<r;++i)if((n=t[i]).name===e)return n.value}function en(t,e,n){for(var i=0,r=t.length;i<r;++i)if(t[i].name===e){t[i]=Ze,t=t.slice(0,i).concat(t.slice(i+1));break}return null!=n&&t.push({name:e,value:n}),t}Ke.prototype=Qe.prototype={constructor:Ke,on:function(t,e){var n,i=this._,r=Je(t+"",i),a=-1,s=r.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++a<s;)if(n=(t=r[a]).type)i[n]=en(i[n],t.name,e);else if(null==e)for(n in i)i[n]=en(i[n],t.name,null);return this}for(;++a<s;)if((n=(t=r[a]).type)&&(n=tn(i[n],t.name)))return n},copy:function(){var t={},e=this._;for(var n in e)t[n]=e[n].slice();return new Ke(t)},call:function(t,e){if((n=arguments.length-2)>0)for(var n,i,r=new Array(n),a=0;a<n;++a)r[a]=arguments[a+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(a=0,n=(i=this._[t]).length;a<n;++a)i[a].value.apply(e,r)},apply:function(t,e,n){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var i=this._[t],r=0,a=i.length;r<a;++r)i[r].value.apply(e,n)}};const nn=Qe;var rn,an,sn=0,on=0,cn=0,ln=0,hn=0,un=0,dn="object"==typeof performance&&performance.now?performance:Date,pn="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function fn(){return hn||(pn(gn),hn=dn.now()+un)}function gn(){hn=0}function yn(){this._call=this._time=this._next=null}function mn(t,e,n){var i=new yn;return i.restart(t,e,n),i}function bn(){hn=(ln=dn.now())+un,sn=on=0;try{!function(){fn(),++sn;for(var t,e=rn;e;)(t=hn-e._time)>=0&&e._call.call(void 0,t),e=e._next;--sn}()}finally{sn=0,function(){var t,e,n=rn,i=1/0;for(;n;)n._call?(i>n._time&&(i=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:rn=e);an=t,xn(i)}(),hn=0}}function _n(){var t=dn.now(),e=t-ln;e>1e3&&(un-=e,ln=t)}function xn(t){sn||(on&&(on=clearTimeout(on)),t-hn>24?(t<1/0&&(on=setTimeout(bn,t-dn.now()-un)),cn&&(cn=clearInterval(cn))):(cn||(ln=dn.now(),cn=setInterval(_n,1e3)),sn=1,pn(bn)))}function vn(t,e,n){var i=new yn;return e=null==e?0:+e,i.restart((n=>{i.stop(),t(n+e)}),e,n),i}yn.prototype=mn.prototype={constructor:yn,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?fn():+n)+(null==e?0:+e),this._next||an===this||(an?an._next=this:rn=this,an=this),this._call=t,this._time=n,xn()},stop:function(){this._call&&(this._call=null,this._time=1/0,xn())}};var kn=nn("start","end","cancel","interrupt"),wn=[];function Tn(t,e,n,i,r,a){var s=t.__transition;if(s){if(n in s)return}else t.__transition={};!function(t,e,n){var i,r=t.__transition;function a(t){n.state=1,n.timer.restart(s,n.delay,n.time),n.delay<=t&&s(t-n.delay)}function s(a){var l,h,u,d;if(1!==n.state)return c();for(l in r)if((d=r[l]).name===n.name){if(3===d.state)return vn(s);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",t,t.__data__,d.index,d.group),delete r[l]):+l<e&&(d.state=6,d.timer.stop(),d.on.call("cancel",t,t.__data__,d.index,d.group),delete r[l])}if(vn((function(){3===n.state&&(n.state=4,n.timer.restart(o,n.delay,n.time),o(a))})),n.state=2,n.on.call("start",t,t.__data__,n.index,n.group),2===n.state){for(n.state=3,i=new Array(u=n.tween.length),l=0,h=-1;l<u;++l)(d=n.tween[l].value.call(t,t.__data__,n.index,n.group))&&(i[++h]=d);i.length=h+1}}function o(e){for(var r=e<n.duration?n.ease.call(null,e/n.duration):(n.timer.restart(c),n.state=5,1),a=-1,s=i.length;++a<s;)i[a].call(t,r);5===n.state&&(n.on.call("end",t,t.__data__,n.index,n.group),c())}function c(){for(var i in n.state=6,n.timer.stop(),delete r[e],r)return;delete t.__transition}r[e]=n,n.timer=mn(a,0,n.time)}(t,n,{name:e,index:i,group:r,on:kn,tween:wn,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:0})}function Cn(t,e){var n=Sn(t,e);if(n.state>0)throw new Error("too late; already scheduled");return n}function En(t,e){var n=Sn(t,e);if(n.state>3)throw new Error("too late; already running");return n}function Sn(t,e){var n=t.__transition;if(!n||!(n=n[e]))throw new Error("transition not found");return n}function An(t,e){return t=+t,e=+e,function(n){return t*(1-n)+e*n}}var Dn,Ln=180/Math.PI,Nn={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function On(t,e,n,i,r,a){var s,o,c;return(s=Math.sqrt(t*t+e*e))&&(t/=s,e/=s),(c=t*n+e*i)&&(n-=t*c,i-=e*c),(o=Math.sqrt(n*n+i*i))&&(n/=o,i/=o,c/=o),t*i<e*n&&(t=-t,e=-e,c=-c,s=-s),{translateX:r,translateY:a,rotate:Math.atan2(e,t)*Ln,skewX:Math.atan(c)*Ln,scaleX:s,scaleY:o}}function Bn(t,e,n,i){function r(t){return t.length?t.pop()+" ":""}return function(a,s){var o=[],c=[];return a=t(a),s=t(s),function(t,i,r,a,s,o){if(t!==r||i!==a){var c=s.push("translate(",null,e,null,n);o.push({i:c-4,x:An(t,r)},{i:c-2,x:An(i,a)})}else(r||a)&&s.push("translate("+r+e+a+n)}(a.translateX,a.translateY,s.translateX,s.translateY,o,c),function(t,e,n,a){t!==e?(t-e>180?e+=360:e-t>180&&(t+=360),a.push({i:n.push(r(n)+"rotate(",null,i)-2,x:An(t,e)})):e&&n.push(r(n)+"rotate("+e+i)}(a.rotate,s.rotate,o,c),function(t,e,n,a){t!==e?a.push({i:n.push(r(n)+"skewX(",null,i)-2,x:An(t,e)}):e&&n.push(r(n)+"skewX("+e+i)}(a.skewX,s.skewX,o,c),function(t,e,n,i,a,s){if(t!==n||e!==i){var o=a.push(r(a)+"scale(",null,",",null,")");s.push({i:o-4,x:An(t,n)},{i:o-2,x:An(e,i)})}else 1===n&&1===i||a.push(r(a)+"scale("+n+","+i+")")}(a.scaleX,a.scaleY,s.scaleX,s.scaleY,o,c),a=s=null,function(t){for(var e,n=-1,i=c.length;++n<i;)o[(e=c[n]).i]=e.x(t);return o.join("")}}}var Mn=Bn((function(t){const e=new("function"==typeof DOMMatrix?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?Nn:On(e.a,e.b,e.c,e.d,e.e,e.f)}),"px, ","px)","deg)"),In=Bn((function(t){return null==t?Nn:(Dn||(Dn=document.createElementNS("http://www.w3.org/2000/svg","g")),Dn.setAttribute("transform",t),(t=Dn.transform.baseVal.consolidate())?On((t=t.matrix).a,t.b,t.c,t.d,t.e,t.f):Nn)}),", ",")",")");function Fn(t,e){var n,i;return function(){var r=En(this,t),a=r.tween;if(a!==n)for(var s=0,o=(i=n=a).length;s<o;++s)if(i[s].name===e){(i=i.slice()).splice(s,1);break}r.tween=i}}function Rn(t,e,n){var i,r;if("function"!=typeof n)throw new Error;return function(){var a=En(this,t),s=a.tween;if(s!==i){r=(i=s).slice();for(var o={name:e,value:n},c=0,l=r.length;c<l;++c)if(r[c].name===e){r[c]=o;break}c===l&&r.push(o)}a.tween=r}}function $n(t,e,n){var i=t._id;return t.each((function(){var t=En(this,i);(t.value||(t.value={}))[e]=n.apply(this,arguments)})),function(t){return Sn(t,i).value[e]}}function Pn(t,e,n){t.prototype=e.prototype=n,n.constructor=t}function jn(t,e){var n=Object.create(t.prototype);for(var i in e)n[i]=e[i];return n}function Yn(){}var zn=.7,Un=1/zn,Wn="\\s*([+-]?\\d+)\\s*",Hn="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",qn="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",Vn=/^#([0-9a-f]{3,8})$/,Gn=new RegExp(`^rgb\\(${Wn},${Wn},${Wn}\\)$`),Xn=new RegExp(`^rgb\\(${qn},${qn},${qn}\\)$`),Zn=new RegExp(`^rgba\\(${Wn},${Wn},${Wn},${Hn}\\)$`),Qn=new RegExp(`^rgba\\(${qn},${qn},${qn},${Hn}\\)$`),Kn=new RegExp(`^hsl\\(${Hn},${qn},${qn}\\)$`),Jn=new RegExp(`^hsla\\(${Hn},${qn},${qn},${Hn}\\)$`),ti={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};function ei(){return this.rgb().formatHex()}function ni(){return this.rgb().formatRgb()}function ii(t){var e,n;return t=(t+"").trim().toLowerCase(),(e=Vn.exec(t))?(n=e[1].length,e=parseInt(e[1],16),6===n?ri(e):3===n?new ci(e>>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===n?ai(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===n?ai(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Gn.exec(t))?new ci(e[1],e[2],e[3],1):(e=Xn.exec(t))?new ci(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=Zn.exec(t))?ai(e[1],e[2],e[3],e[4]):(e=Qn.exec(t))?ai(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=Kn.exec(t))?fi(e[1],e[2]/100,e[3]/100,1):(e=Jn.exec(t))?fi(e[1],e[2]/100,e[3]/100,e[4]):ti.hasOwnProperty(t)?ri(ti[t]):"transparent"===t?new ci(NaN,NaN,NaN,0):null}function ri(t){return new ci(t>>16&255,t>>8&255,255&t,1)}function ai(t,e,n,i){return i<=0&&(t=e=n=NaN),new ci(t,e,n,i)}function si(t){return t instanceof Yn||(t=ii(t)),t?new ci((t=t.rgb()).r,t.g,t.b,t.opacity):new ci}function oi(t,e,n,i){return 1===arguments.length?si(t):new ci(t,e,n,null==i?1:i)}function ci(t,e,n,i){this.r=+t,this.g=+e,this.b=+n,this.opacity=+i}function li(){return`#${pi(this.r)}${pi(this.g)}${pi(this.b)}`}function hi(){const t=ui(this.opacity);return`${1===t?"rgb(":"rgba("}${di(this.r)}, ${di(this.g)}, ${di(this.b)}${1===t?")":`, ${t})`}`}function ui(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function di(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function pi(t){return((t=di(t))<16?"0":"")+t.toString(16)}function fi(t,e,n,i){return i<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new yi(t,e,n,i)}function gi(t){if(t instanceof yi)return new yi(t.h,t.s,t.l,t.opacity);if(t instanceof Yn||(t=ii(t)),!t)return new yi;if(t instanceof yi)return t;var e=(t=t.rgb()).r/255,n=t.g/255,i=t.b/255,r=Math.min(e,n,i),a=Math.max(e,n,i),s=NaN,o=a-r,c=(a+r)/2;return o?(s=e===a?(n-i)/o+6*(n<i):n===a?(i-e)/o+2:(e-n)/o+4,o/=c<.5?a+r:2-a-r,s*=60):o=c>0&&c<1?0:s,new yi(s,o,c,t.opacity)}function yi(t,e,n,i){this.h=+t,this.s=+e,this.l=+n,this.opacity=+i}function mi(t){return(t=(t||0)%360)<0?t+360:t}function bi(t){return Math.max(0,Math.min(1,t||0))}function _i(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}function xi(t,e,n,i,r){var a=t*t,s=a*t;return((1-3*t+3*a-s)*e+(4-6*a+3*s)*n+(1+3*t+3*a-3*s)*i+s*r)/6}Pn(Yn,ii,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:ei,formatHex:ei,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return gi(this).formatHsl()},formatRgb:ni,toString:ni}),Pn(ci,oi,jn(Yn,{brighter(t){return t=null==t?Un:Math.pow(Un,t),new ci(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?zn:Math.pow(zn,t),new ci(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new ci(di(this.r),di(this.g),di(this.b),ui(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:li,formatHex:li,formatHex8:function(){return`#${pi(this.r)}${pi(this.g)}${pi(this.b)}${pi(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:hi,toString:hi})),Pn(yi,(function(t,e,n,i){return 1===arguments.length?gi(t):new yi(t,e,n,null==i?1:i)}),jn(Yn,{brighter(t){return t=null==t?Un:Math.pow(Un,t),new yi(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?zn:Math.pow(zn,t),new yi(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,i=n+(n<.5?n:1-n)*e,r=2*n-i;return new ci(_i(t>=240?t-240:t+120,r,i),_i(t,r,i),_i(t<120?t+240:t-120,r,i),this.opacity)},clamp(){return new yi(mi(this.h),bi(this.s),bi(this.l),ui(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=ui(this.opacity);return`${1===t?"hsl(":"hsla("}${mi(this.h)}, ${100*bi(this.s)}%, ${100*bi(this.l)}%${1===t?")":`, ${t})`}`}}));const vi=t=>()=>t;function ki(t,e){return function(n){return t+n*e}}function wi(t){return 1==(t=+t)?Ti:function(e,n){return n-e?function(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(i){return Math.pow(t+i*e,n)}}(e,n,t):vi(isNaN(e)?n:e)}}function Ti(t,e){var n=e-t;return n?ki(t,n):vi(isNaN(t)?e:t)}const Ci=function t(e){var n=wi(e);function i(t,e){var i=n((t=oi(t)).r,(e=oi(e)).r),r=n(t.g,e.g),a=n(t.b,e.b),s=Ti(t.opacity,e.opacity);return function(e){return t.r=i(e),t.g=r(e),t.b=a(e),t.opacity=s(e),t+""}}return i.gamma=t,i}(1);function Ei(t){return function(e){var n,i,r=e.length,a=new Array(r),s=new Array(r),o=new Array(r);for(n=0;n<r;++n)i=oi(e[n]),a[n]=i.r||0,s[n]=i.g||0,o[n]=i.b||0;return a=t(a),s=t(s),o=t(o),i.opacity=1,function(t){return i.r=a(t),i.g=s(t),i.b=o(t),i+""}}}Ei((function(t){var e=t.length-1;return function(n){var i=n<=0?n=0:n>=1?(n=1,e-1):Math.floor(n*e),r=t[i],a=t[i+1],s=i>0?t[i-1]:2*r-a,o=i<e-1?t[i+2]:2*a-r;return xi((n-i/e)*e,s,r,a,o)}})),Ei((function(t){var e=t.length;return function(n){var i=Math.floor(((n%=1)<0?++n:n)*e),r=t[(i+e-1)%e],a=t[i%e],s=t[(i+1)%e],o=t[(i+2)%e];return xi((n-i/e)*e,r,a,s,o)}}));var Si=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,Ai=new RegExp(Si.source,"g");function Di(t,e){var n,i,r,a=Si.lastIndex=Ai.lastIndex=0,s=-1,o=[],c=[];for(t+="",e+="";(n=Si.exec(t))&&(i=Ai.exec(e));)(r=i.index)>a&&(r=e.slice(a,r),o[s]?o[s]+=r:o[++s]=r),(n=n[0])===(i=i[0])?o[s]?o[s]+=i:o[++s]=i:(o[++s]=null,c.push({i:s,x:An(n,i)})),a=Ai.lastIndex;return a<e.length&&(r=e.slice(a),o[s]?o[s]+=r:o[++s]=r),o.length<2?c[0]?function(t){return function(e){return t(e)+""}}(c[0].x):function(t){return function(){return t}}(e):(e=c.length,function(t){for(var n,i=0;i<e;++i)o[(n=c[i]).i]=n.x(t);return o.join("")})}function Li(t,e){var n;return("number"==typeof e?An:e instanceof ii?Ci:(n=ii(e))?(e=n,Ci):Di)(t,e)}function Ni(t){return function(){this.removeAttribute(t)}}function Oi(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Bi(t,e,n){var i,r,a=n+"";return function(){var s=this.getAttribute(t);return s===a?null:s===i?r:r=e(i=s,n)}}function Mi(t,e,n){var i,r,a=n+"";return function(){var s=this.getAttributeNS(t.space,t.local);return s===a?null:s===i?r:r=e(i=s,n)}}function Ii(t,e,n){var i,r,a;return function(){var s,o,c=n(this);if(null!=c)return(s=this.getAttribute(t))===(o=c+"")?null:s===i&&o===r?a:(r=o,a=e(i=s,c));this.removeAttribute(t)}}function Fi(t,e,n){var i,r,a;return function(){var s,o,c=n(this);if(null!=c)return(s=this.getAttributeNS(t.space,t.local))===(o=c+"")?null:s===i&&o===r?a:(r=o,a=e(i=s,c));this.removeAttributeNS(t.space,t.local)}}function Ri(t,e){return function(n){this.setAttribute(t,e.call(this,n))}}function $i(t,e){return function(n){this.setAttributeNS(t.space,t.local,e.call(this,n))}}function Pi(t,e){var n,i;function r(){var r=e.apply(this,arguments);return r!==i&&(n=(i=r)&&$i(t,r)),n}return r._value=e,r}function ji(t,e){var n,i;function r(){var r=e.apply(this,arguments);return r!==i&&(n=(i=r)&&Ri(t,r)),n}return r._value=e,r}function Yi(t,e){return function(){Cn(this,t).delay=+e.apply(this,arguments)}}function zi(t,e){return e=+e,function(){Cn(this,t).delay=e}}function Ui(t,e){return function(){En(this,t).duration=+e.apply(this,arguments)}}function Wi(t,e){return e=+e,function(){En(this,t).duration=e}}function Hi(t,e){if("function"!=typeof e)throw new Error;return function(){En(this,t).ease=e}}function qi(t,e,n){var i,r,a=function(t){return(t+"").trim().split(/^|\s+/).every((function(t){var e=t.indexOf(".");return e>=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?Cn:En;return function(){var s=a(this,t),o=s.on;o!==i&&(r=(i=o).copy()).on(e,n),s.on=r}}var Vi=Xe.prototype.constructor;function Gi(t){return function(){this.style.removeProperty(t)}}function Xi(t,e,n){return function(i){this.style.setProperty(t,e.call(this,i),n)}}function Zi(t,e,n){var i,r;function a(){var a=e.apply(this,arguments);return a!==r&&(i=(r=a)&&Xi(t,a,n)),i}return a._value=e,a}function Qi(t){return function(e){this.textContent=t.call(this,e)}}function Ki(t){var e,n;function i(){var i=t.apply(this,arguments);return i!==n&&(e=(n=i)&&Qi(i)),e}return i._value=t,i}var Ji=0;function tr(t,e,n,i){this._groups=t,this._parents=e,this._name=n,this._id=i}function er(){return++Ji}var nr=Xe.prototype;tr.prototype=function(t){return Xe().transition(t)}.prototype={constructor:tr,select:function(t){var e=this._name,n=this._id;"function"!=typeof t&&(t=Ft(t));for(var i=this._groups,r=i.length,a=new Array(r),s=0;s<r;++s)for(var o,c,l=i[s],h=l.length,u=a[s]=new Array(h),d=0;d<h;++d)(o=l[d])&&(c=t.call(o,o.__data__,d,l))&&("__data__"in o&&(c.__data__=o.__data__),u[d]=c,Tn(u[d],e,n,d,u,Sn(o,n)));return new tr(a,this._parents,e,n)},selectAll:function(t){var e=this._name,n=this._id;"function"!=typeof t&&(t=Pt(t));for(var i=this._groups,r=i.length,a=[],s=[],o=0;o<r;++o)for(var c,l=i[o],h=l.length,u=0;u<h;++u)if(c=l[u]){for(var d,p=t.call(c,c.__data__,u,l),f=Sn(c,n),g=0,y=p.length;g<y;++g)(d=p[g])&&Tn(d,e,n,g,p,f);a.push(p),s.push(c)}return new tr(a,s,e,n)},selectChild:nr.selectChild,selectChildren:nr.selectChildren,filter:function(t){"function"!=typeof t&&(t=jt(t));for(var e=this._groups,n=e.length,i=new Array(n),r=0;r<n;++r)for(var a,s=e[r],o=s.length,c=i[r]=[],l=0;l<o;++l)(a=s[l])&&t.call(a,a.__data__,l,s)&&c.push(a);return new tr(i,this._parents,this._name,this._id)},merge:function(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,n=t._groups,i=e.length,r=n.length,a=Math.min(i,r),s=new Array(i),o=0;o<a;++o)for(var c,l=e[o],h=n[o],u=l.length,d=s[o]=new Array(u),p=0;p<u;++p)(c=l[p]||h[p])&&(d[p]=c);for(;o<i;++o)s[o]=e[o];return new tr(s,this._parents,this._name,this._id)},selection:function(){return new Vi(this._groups,this._parents)},transition:function(){for(var t=this._name,e=this._id,n=er(),i=this._groups,r=i.length,a=0;a<r;++a)for(var s,o=i[a],c=o.length,l=0;l<c;++l)if(s=o[l]){var h=Sn(s,e);Tn(s,t,n,l,o,{time:h.time+h.delay+h.duration,delay:0,duration:h.duration,ease:h.ease})}return new tr(i,this._parents,t,n)},call:nr.call,nodes:nr.nodes,node:nr.node,size:nr.size,empty:nr.empty,each:nr.each,on:function(t,e){var n=this._id;return arguments.length<2?Sn(this.node(),n).on.on(t):this.each(qi(n,t,e))},attr:function(t,e){var n=ne(t),i="transform"===n?In:Li;return this.attrTween(t,"function"==typeof e?(n.local?Fi:Ii)(n,i,$n(this,"attr."+t,e)):null==e?(n.local?Oi:Ni)(n):(n.local?Mi:Bi)(n,i,e))},attrTween:function(t,e){var n="attr."+t;if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==e)return this.tween(n,null);if("function"!=typeof e)throw new Error;var i=ne(t);return this.tween(n,(i.local?Pi:ji)(i,e))},style:function(t,e,n){var i="transform"==(t+="")?Mn:Li;return null==e?this.styleTween(t,function(t,e){var n,i,r;return function(){var a=pe(this,t),s=(this.style.removeProperty(t),pe(this,t));return a===s?null:a===n&&s===i?r:r=e(n=a,i=s)}}(t,i)).on("end.style."+t,Gi(t)):"function"==typeof e?this.styleTween(t,function(t,e,n){var i,r,a;return function(){var s=pe(this,t),o=n(this),c=o+"";return null==o&&(this.style.removeProperty(t),c=o=pe(this,t)),s===c?null:s===i&&c===r?a:(r=c,a=e(i=s,o))}}(t,i,$n(this,"style."+t,e))).each(function(t,e){var n,i,r,a,s="style."+e,o="end."+s;return function(){var c=En(this,t),l=c.on,h=null==c.value[s]?a||(a=Gi(e)):void 0;l===n&&r===h||(i=(n=l).copy()).on(o,r=h),c.on=i}}(this._id,t)):this.styleTween(t,function(t,e,n){var i,r,a=n+"";return function(){var s=pe(this,t);return s===a?null:s===i?r:r=e(i=s,n)}}(t,i,e),n).on("end.style."+t,null)},styleTween:function(t,e,n){var i="style."+(t+="");if(arguments.length<2)return(i=this.tween(i))&&i._value;if(null==e)return this.tween(i,null);if("function"!=typeof e)throw new Error;return this.tween(i,Zi(t,e,null==n?"":n))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var e=t(this);this.textContent=null==e?"":e}}($n(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},textTween:function(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(null==t)return this.tween(e,null);if("function"!=typeof t)throw new Error;return this.tween(e,Ki(t))},remove:function(){return this.on("end.remove",function(t){return function(){var e=this.parentNode;for(var n in this.__transition)if(+n!==t)return;e&&e.removeChild(this)}}(this._id))},tween:function(t,e){var n=this._id;if(t+="",arguments.length<2){for(var i,r=Sn(this.node(),n).tween,a=0,s=r.length;a<s;++a)if((i=r[a]).name===t)return i.value;return null}return this.each((null==e?Fn:Rn)(n,t,e))},delay:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Yi:zi)(e,t)):Sn(this.node(),e).delay},duration:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Ui:Wi)(e,t)):Sn(this.node(),e).duration},ease:function(t){var e=this._id;return arguments.length?this.each(Hi(e,t)):Sn(this.node(),e).ease},easeVarying:function(t){if("function"!=typeof t)throw new Error;return this.each(function(t,e){return function(){var n=e.apply(this,arguments);if("function"!=typeof n)throw new Error;En(this,t).ease=n}}(this._id,t))},end:function(){var t,e,n=this,i=n._id,r=n.size();return new Promise((function(a,s){var o={value:s},c={value:function(){0==--r&&a()}};n.each((function(){var n=En(this,i),r=n.on;r!==t&&((e=(t=r).copy())._.cancel.push(o),e._.interrupt.push(o),e._.end.push(c)),n.on=e})),0===r&&a()}))},[Symbol.iterator]:nr[Symbol.iterator]};var ir={time:null,delay:0,duration:250,ease:function(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}};function rr(t,e){for(var n;!(n=t.__transition)||!(n=n[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return n}Xe.prototype.interrupt=function(t){return this.each((function(){!function(t,e){var n,i,r,a=t.__transition,s=!0;if(a){for(r in e=null==e?null:e+"",a)(n=a[r]).name===e?(i=n.state>2&&n.state<5,n.state=6,n.timer.stop(),n.on.call(i?"interrupt":"cancel",t,t.__data__,n.index,n.group),delete a[r]):s=!1;s&&delete t.__transition}}(this,t)}))},Xe.prototype.transition=function(t){var e,n;t instanceof tr?(e=t._id,t=t._name):(e=er(),(n=ir).time=fn(),t=null==t?null:t+"");for(var i=this._groups,r=i.length,a=0;a<r;++a)for(var s,o=i[a],c=o.length,l=0;l<c;++l)(s=o[l])&&Tn(s,t,e,l,o,n||rr(s,e));return new tr(i,this._parents,t,e)};const{abs:ar,max:sr,min:or}=Math;function cr(t){return[+t[0],+t[1]]}function lr(t){return[cr(t[0]),cr(t[1])]}["w","e"].map(hr),["n","s"].map(hr),["n","w","e","s","nw","ne","sw","se"].map(hr);function hr(t){return{type:t}}function ur(t){if(!t.ok)throw new Error(t.status+" "+t.statusText);return t.text()}function dr(t){return(e,n)=>function(t,e){return fetch(t,e).then(ur)}(e,n).then((e=>(new DOMParser).parseFromString(e,t)))}dr("application/xml");dr("text/html"),dr("image/svg+xml");const pr=Math.PI/180,fr=180/Math.PI,gr=.96422,yr=.82521,mr=4/29,br=6/29,_r=3*br*br;function xr(t){if(t instanceof vr)return new vr(t.l,t.a,t.b,t.opacity);if(t instanceof Ar)return Dr(t);t instanceof ci||(t=si(t));var e,n,i=Cr(t.r),r=Cr(t.g),a=Cr(t.b),s=kr((.2225045*i+.7168786*r+.0606169*a)/1);return i===r&&r===a?e=n=s:(e=kr((.4360747*i+.3850649*r+.1430804*a)/gr),n=kr((.0139322*i+.0971045*r+.7141733*a)/yr)),new vr(116*s-16,500*(e-s),200*(s-n),t.opacity)}function vr(t,e,n,i){this.l=+t,this.a=+e,this.b=+n,this.opacity=+i}function kr(t){return t>.008856451679035631?Math.pow(t,1/3):t/_r+mr}function wr(t){return t>br?t*t*t:_r*(t-mr)}function Tr(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Cr(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Er(t){if(t instanceof Ar)return new Ar(t.h,t.c,t.l,t.opacity);if(t instanceof vr||(t=xr(t)),0===t.a&&0===t.b)return new Ar(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*fr;return new Ar(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function Sr(t,e,n,i){return 1===arguments.length?Er(t):new Ar(t,e,n,null==i?1:i)}function Ar(t,e,n,i){this.h=+t,this.c=+e,this.l=+n,this.opacity=+i}function Dr(t){if(isNaN(t.h))return new vr(t.l,0,0,t.opacity);var e=t.h*pr;return new vr(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}function Lr(t){return function(e,n){var i=t((e=Sr(e)).h,(n=Sr(n)).h),r=Ti(e.c,n.c),a=Ti(e.l,n.l),s=Ti(e.opacity,n.opacity);return function(t){return e.h=i(t),e.c=r(t),e.l=a(t),e.opacity=s(t),e+""}}}Pn(vr,(function(t,e,n,i){return 1===arguments.length?xr(t):new vr(t,e,n,null==i?1:i)}),jn(Yn,{brighter(t){return new vr(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker(t){return new vr(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,n=isNaN(this.b)?t:t-this.b/200;return new ci(Tr(3.1338561*(e=gr*wr(e))-1.6168667*(t=1*wr(t))-.4906146*(n=yr*wr(n))),Tr(-.9787684*e+1.9161415*t+.033454*n),Tr(.0719453*e-.2289914*t+1.4052427*n),this.opacity)}})),Pn(Ar,Sr,jn(Yn,{brighter(t){return new Ar(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker(t){return new Ar(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb(){return Dr(this).rgb()}}));const Nr=Lr((function(t,e){var n=e-t;return n?ki(t,n>180||n<-180?n-360*Math.round(n/360):n):vi(isNaN(t)?e:t)}));Lr(Ti);const Or=Math.sqrt(50),Br=Math.sqrt(10),Mr=Math.sqrt(2);function Ir(t,e,n){const i=(e-t)/Math.max(0,n),r=Math.floor(Math.log10(i)),a=i/Math.pow(10,r),s=a>=Or?10:a>=Br?5:a>=Mr?2:1;let o,c,l;return r<0?(l=Math.pow(10,-r)/s,o=Math.round(t*l),c=Math.round(e*l),o/l<t&&++o,c/l>e&&--c,l=-l):(l=Math.pow(10,r)*s,o=Math.round(t/l),c=Math.round(e/l),o*l<t&&++o,c*l>e&&--c),c<o&&.5<=n&&n<2?Ir(t,e,2*n):[o,c,l]}function Fr(t,e,n){return Ir(t=+t,e=+e,n=+n)[2]}function Rr(t,e,n){n=+n;const i=(e=+e)<(t=+t),r=i?Fr(e,t,n):Fr(t,e,n);return(i?-1:1)*(r<0?1/-r:r)}function $r(t,e){return null==t||null==e?NaN:t<e?-1:t>e?1:t>=e?0:NaN}function Pr(t,e){return null==t||null==e?NaN:e<t?-1:e>t?1:e>=t?0:NaN}function jr(t){let e,n,i;function r(t,i,r=0,a=t.length){if(r<a){if(0!==e(i,i))return a;do{const e=r+a>>>1;n(t[e],i)<0?r=e+1:a=e}while(r<a)}return r}return 2!==t.length?(e=$r,n=(e,n)=>$r(t(e),n),i=(e,n)=>t(e)-n):(e=t===$r||t===Pr?t:Yr,n=t,i=t),{left:r,center:function(t,e,n=0,a=t.length){const s=r(t,e,n,a-1);return s>n&&i(t[s-1],e)>-i(t[s],e)?s-1:s},right:function(t,i,r=0,a=t.length){if(r<a){if(0!==e(i,i))return a;do{const e=r+a>>>1;n(t[e],i)<=0?r=e+1:a=e}while(r<a)}return r}}}function Yr(){return 0}const zr=jr($r),Ur=zr.right,Wr=(zr.left,jr((function(t){return null===t?NaN:+t})).center,Ur);function Hr(t,e){var n,i=e?e.length:0,r=t?Math.min(i,t.length):0,a=new Array(r),s=new Array(i);for(n=0;n<r;++n)a[n]=Xr(t[n],e[n]);for(;n<i;++n)s[n]=e[n];return function(t){for(n=0;n<r;++n)s[n]=a[n](t);return s}}function qr(t,e){var n=new Date;return t=+t,e=+e,function(i){return n.setTime(t*(1-i)+e*i),n}}function Vr(t,e){var n,i={},r={};for(n in null!==t&&"object"==typeof t||(t={}),null!==e&&"object"==typeof e||(e={}),e)n in t?i[n]=Xr(t[n],e[n]):r[n]=e[n];return function(t){for(n in i)r[n]=i[n](t);return r}}function Gr(t,e){e||(e=[]);var n,i=t?Math.min(e.length,t.length):0,r=e.slice();return function(a){for(n=0;n<i;++n)r[n]=t[n]*(1-a)+e[n]*a;return r}}function Xr(t,e){var n,i,r=typeof e;return null==e||"boolean"===r?vi(e):("number"===r?An:"string"===r?(n=ii(e))?(e=n,Ci):Di:e instanceof ii?Ci:e instanceof Date?qr:(i=e,!ArrayBuffer.isView(i)||i instanceof DataView?Array.isArray(e)?Hr:"function"!=typeof e.valueOf&&"function"!=typeof e.toString||isNaN(e)?Vr:An:Gr))(t,e)}function Zr(t,e){return t=+t,e=+e,function(n){return Math.round(t*(1-n)+e*n)}}function Qr(t){return+t}var Kr=[0,1];function Jr(t){return t}function ta(t,e){return(e-=t=+t)?function(n){return(n-t)/e}:(n=isNaN(e)?NaN:.5,function(){return n});var n}function ea(t,e,n){var i=t[0],r=t[1],a=e[0],s=e[1];return r<i?(i=ta(r,i),a=n(s,a)):(i=ta(i,r),a=n(a,s)),function(t){return a(i(t))}}function na(t,e,n){var i=Math.min(t.length,e.length)-1,r=new Array(i),a=new Array(i),s=-1;for(t[i]<t[0]&&(t=t.slice().reverse(),e=e.slice().reverse());++s<i;)r[s]=ta(t[s],t[s+1]),a[s]=n(e[s],e[s+1]);return function(e){var n=Wr(t,e,1,i)-1;return a[n](r[n](e))}}function ia(t,e){return e.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp()).unknown(t.unknown())}function ra(){var t,e,n,i,r,a,s=Kr,o=Kr,c=Xr,l=Jr;function h(){var t,e,n,c=Math.min(s.length,o.length);return l!==Jr&&(t=s[0],e=s[c-1],t>e&&(n=t,t=e,e=n),l=function(n){return Math.max(t,Math.min(e,n))}),i=c>2?na:ea,r=a=null,u}function u(e){return null==e||isNaN(e=+e)?n:(r||(r=i(s.map(t),o,c)))(t(l(e)))}return u.invert=function(n){return l(e((a||(a=i(o,s.map(t),An)))(n)))},u.domain=function(t){return arguments.length?(s=Array.from(t,Qr),h()):s.slice()},u.range=function(t){return arguments.length?(o=Array.from(t),h()):o.slice()},u.rangeRound=function(t){return o=Array.from(t),c=Zr,h()},u.clamp=function(t){return arguments.length?(l=!!t||Jr,h()):l!==Jr},u.interpolate=function(t){return arguments.length?(c=t,h()):c},u.unknown=function(t){return arguments.length?(n=t,u):n},function(n,i){return t=n,e=i,h()}}function aa(){return ra()(Jr,Jr)}function sa(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t)}return this}var oa,ca=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function la(t){if(!(e=ca.exec(t)))throw new Error("invalid format: "+t);var e;return new ha({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function ha(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function ua(t,e){if((n=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var n,i=t.slice(0,n);return[i.length>1?i[0]+i.slice(2):i,+t.slice(n+1)]}function da(t){return(t=ua(Math.abs(t)))?t[1]:NaN}function pa(t,e){var n=ua(t,e);if(!n)return t+"";var i=n[0],r=n[1];return r<0?"0."+new Array(-r).join("0")+i:i.length>r+1?i.slice(0,r+1)+"."+i.slice(r+1):i+new Array(r-i.length+2).join("0")}la.prototype=ha.prototype,ha.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const fa={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>pa(100*t,e),r:pa,s:function(t,e){var n=ua(t,e);if(!n)return t+"";var i=n[0],r=n[1],a=r-(oa=3*Math.max(-8,Math.min(8,Math.floor(r/3))))+1,s=i.length;return a===s?i:a>s?i+new Array(a-s+1).join("0"):a>0?i.slice(0,a)+"."+i.slice(a):"0."+new Array(1-a).join("0")+ua(t,Math.max(0,e+a-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function ga(t){return t}var ya,ma,ba,_a=Array.prototype.map,xa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function va(t){var e,n,i=void 0===t.grouping||void 0===t.thousands?ga:(e=_a.call(t.grouping,Number),n=t.thousands+"",function(t,i){for(var r=t.length,a=[],s=0,o=e[0],c=0;r>0&&o>0&&(c+o+1>i&&(o=Math.max(1,i-c)),a.push(t.substring(r-=o,r+o)),!((c+=o+1)>i));)o=e[s=(s+1)%e.length];return a.reverse().join(n)}),r=void 0===t.currency?"":t.currency[0]+"",a=void 0===t.currency?"":t.currency[1]+"",s=void 0===t.decimal?".":t.decimal+"",o=void 0===t.numerals?ga:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(_a.call(t.numerals,String)),c=void 0===t.percent?"%":t.percent+"",l=void 0===t.minus?"\u2212":t.minus+"",h=void 0===t.nan?"NaN":t.nan+"";function u(t){var e=(t=la(t)).fill,n=t.align,u=t.sign,d=t.symbol,p=t.zero,f=t.width,g=t.comma,y=t.precision,m=t.trim,b=t.type;"n"===b?(g=!0,b="g"):fa[b]||(void 0===y&&(y=12),m=!0,b="g"),(p||"0"===e&&"="===n)&&(p=!0,e="0",n="=");var _="$"===d?r:"#"===d&&/[boxX]/.test(b)?"0"+b.toLowerCase():"",x="$"===d?a:/[%p]/.test(b)?c:"",v=fa[b],k=/[defgprs%]/.test(b);function w(t){var r,a,c,d=_,w=x;if("c"===b)w=v(t)+w,t="";else{var T=(t=+t)<0||1/t<0;if(t=isNaN(t)?h:v(Math.abs(t),y),m&&(t=function(t){t:for(var e,n=t.length,i=1,r=-1;i<n;++i)switch(t[i]){case".":r=e=i;break;case"0":0===r&&(r=i),e=i;break;default:if(!+t[i])break t;r>0&&(r=0)}return r>0?t.slice(0,r)+t.slice(e+1):t}(t)),T&&0==+t&&"+"!==u&&(T=!1),d=(T?"("===u?u:l:"-"===u||"("===u?"":u)+d,w=("s"===b?xa[8+oa/3]:"")+w+(T&&"("===u?")":""),k)for(r=-1,a=t.length;++r<a;)if(48>(c=t.charCodeAt(r))||c>57){w=(46===c?s+t.slice(r+1):t.slice(r))+w,t=t.slice(0,r);break}}g&&!p&&(t=i(t,1/0));var C=d.length+t.length+w.length,E=C<f?new Array(f-C+1).join(e):"";switch(g&&p&&(t=i(E+t,E.length?f-w.length:1/0),E=""),n){case"<":t=d+t+w+E;break;case"=":t=d+E+t+w;break;case"^":t=E.slice(0,C=E.length>>1)+d+t+w+E.slice(C);break;default:t=E+d+t+w}return o(t)}return y=void 0===y?6:/[gprs]/.test(b)?Math.max(1,Math.min(21,y)):Math.max(0,Math.min(20,y)),w.toString=function(){return t+""},w}return{format:u,formatPrefix:function(t,e){var n=u(((t=la(t)).type="f",t)),i=3*Math.max(-8,Math.min(8,Math.floor(da(e)/3))),r=Math.pow(10,-i),a=xa[8+i/3];return function(t){return n(r*t)+a}}}}function ka(t,e,n,i){var r,a=Rr(t,e,n);switch((i=la(null==i?",f":i)).type){case"s":var s=Math.max(Math.abs(t),Math.abs(e));return null!=i.precision||isNaN(r=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(da(e)/3)))-da(Math.abs(t)))}(a,s))||(i.precision=r),ba(i,s);case"":case"e":case"g":case"p":case"r":null!=i.precision||isNaN(r=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,da(e)-da(t))+1}(a,Math.max(Math.abs(t),Math.abs(e))))||(i.precision=r-("e"===i.type));break;case"f":case"%":null!=i.precision||isNaN(r=function(t){return Math.max(0,-da(Math.abs(t)))}(a))||(i.precision=r-2*("%"===i.type))}return ma(i)}function wa(t){var e=t.domain;return t.ticks=function(t){var n=e();return function(t,e,n){if(!((n=+n)>0))return[];if((t=+t)==(e=+e))return[t];const i=e<t,[r,a,s]=i?Ir(e,t,n):Ir(t,e,n);if(!(a>=r))return[];const o=a-r+1,c=new Array(o);if(i)if(s<0)for(let l=0;l<o;++l)c[l]=(a-l)/-s;else for(let l=0;l<o;++l)c[l]=(a-l)*s;else if(s<0)for(let l=0;l<o;++l)c[l]=(r+l)/-s;else for(let l=0;l<o;++l)c[l]=(r+l)*s;return c}(n[0],n[n.length-1],null==t?10:t)},t.tickFormat=function(t,n){var i=e();return ka(i[0],i[i.length-1],null==t?10:t,n)},t.nice=function(n){null==n&&(n=10);var i,r,a=e(),s=0,o=a.length-1,c=a[s],l=a[o],h=10;for(l<c&&(r=c,c=l,l=r,r=s,s=o,o=r);h-- >0;){if((r=Fr(c,l,n))===i)return a[s]=c,a[o]=l,e(a);if(r>0)c=Math.floor(c/r)*r,l=Math.ceil(l/r)*r;else{if(!(r<0))break;c=Math.ceil(c*r)/r,l=Math.floor(l*r)/r}i=r}return t},t}function Ta(){var t=aa();return t.copy=function(){return ia(t,Ta())},sa.apply(t,arguments),wa(t)}ya=va({thousands:",",grouping:[3],currency:["$",""]}),ma=ya.format,ba=ya.formatPrefix;class Ca extends Map{constructor(t,e=La){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[n,i]of t)this.set(n,i)}get(t){return super.get(Sa(this,t))}has(t){return super.has(Sa(this,t))}set(t,e){return super.set(Aa(this,t),e)}delete(t){return super.delete(Da(this,t))}}class Ea extends Set{constructor(t,e=La){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const n of t)this.add(n)}has(t){return super.has(Sa(this,t))}add(t){return super.add(Aa(this,t))}delete(t){return super.delete(Da(this,t))}}function Sa({_intern:t,_key:e},n){const i=e(n);return t.has(i)?t.get(i):n}function Aa({_intern:t,_key:e},n){const i=e(n);return t.has(i)?t.get(i):(t.set(i,n),n)}function Da({_intern:t,_key:e},n){const i=e(n);return t.has(i)&&(n=t.get(i),t.delete(i)),n}function La(t){return null!==t&&"object"==typeof t?t.valueOf():t}const Na=Symbol("implicit");function Oa(){var t=new Ca,e=[],n=[],i=Na;function r(r){let a=t.get(r);if(void 0===a){if(i!==Na)return i;t.set(r,a=e.push(r)-1)}return n[a%n.length]}return r.domain=function(n){if(!arguments.length)return e.slice();e=[],t=new Ca;for(const i of n)t.has(i)||t.set(i,e.push(i)-1);return r},r.range=function(t){return arguments.length?(n=Array.from(t),r):n.slice()},r.unknown=function(t){return arguments.length?(i=t,r):i},r.copy=function(){return Oa(e,n).unknown(i)},sa.apply(r,arguments),r}const Ba=1e3,Ma=6e4,Ia=36e5,Fa=864e5,Ra=6048e5,$a=2592e6,Pa=31536e6,ja=new Date,Ya=new Date;function za(t,e,n,i){function r(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return r.floor=e=>(t(e=new Date(+e)),e),r.ceil=n=>(t(n=new Date(n-1)),e(n,1),t(n),n),r.round=t=>{const e=r(t),n=r.ceil(t);return t-e<n-t?e:n},r.offset=(t,n)=>(e(t=new Date(+t),null==n?1:Math.floor(n)),t),r.range=(n,i,a)=>{const s=[];if(n=r.ceil(n),a=null==a?1:Math.floor(a),!(n<i&&a>0))return s;let o;do{s.push(o=new Date(+n)),e(n,a),t(n)}while(o<n&&n<i);return s},r.filter=n=>za((e=>{if(e>=e)for(;t(e),!n(e);)e.setTime(e-1)}),((t,i)=>{if(t>=t)if(i<0)for(;++i<=0;)for(;e(t,-1),!n(t););else for(;--i>=0;)for(;e(t,1),!n(t););})),n&&(r.count=(e,i)=>(ja.setTime(+e),Ya.setTime(+i),t(ja),t(Ya),Math.floor(n(ja,Ya))),r.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?r.filter(i?e=>i(e)%t==0:e=>r.count(0,e)%t==0):r:null)),r}const Ua=za((()=>{}),((t,e)=>{t.setTime(+t+e)}),((t,e)=>e-t));Ua.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?za((e=>{e.setTime(Math.floor(e/t)*t)}),((e,n)=>{e.setTime(+e+n*t)}),((e,n)=>(n-e)/t)):Ua:null);Ua.range;const Wa=za((t=>{t.setTime(t-t.getMilliseconds())}),((t,e)=>{t.setTime(+t+e*Ba)}),((t,e)=>(e-t)/Ba),(t=>t.getUTCSeconds())),Ha=(Wa.range,za((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*Ba)}),((t,e)=>{t.setTime(+t+e*Ma)}),((t,e)=>(e-t)/Ma),(t=>t.getMinutes()))),qa=(Ha.range,za((t=>{t.setUTCSeconds(0,0)}),((t,e)=>{t.setTime(+t+e*Ma)}),((t,e)=>(e-t)/Ma),(t=>t.getUTCMinutes()))),Va=(qa.range,za((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*Ba-t.getMinutes()*Ma)}),((t,e)=>{t.setTime(+t+e*Ia)}),((t,e)=>(e-t)/Ia),(t=>t.getHours()))),Ga=(Va.range,za((t=>{t.setUTCMinutes(0,0,0)}),((t,e)=>{t.setTime(+t+e*Ia)}),((t,e)=>(e-t)/Ia),(t=>t.getUTCHours()))),Xa=(Ga.range,za((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*Ma)/Fa),(t=>t.getDate()-1))),Za=(Xa.range,za((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/Fa),(t=>t.getUTCDate()-1))),Qa=(Za.range,za((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/Fa),(t=>Math.floor(t/Fa))));Qa.range;function Ka(t){return za((e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),((t,e)=>{t.setDate(t.getDate()+7*e)}),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*Ma)/Ra))}const Ja=Ka(0),ts=Ka(1),es=Ka(2),ns=Ka(3),is=Ka(4),rs=Ka(5),as=Ka(6);Ja.range,ts.range,es.range,ns.range,is.range,rs.range,as.range;function ss(t){return za((e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)}),((t,e)=>(e-t)/Ra))}const os=ss(0),cs=ss(1),ls=ss(2),hs=ss(3),us=ss(4),ds=ss(5),ps=ss(6),fs=(os.range,cs.range,ls.range,hs.range,us.range,ds.range,ps.range,za((t=>{t.setDate(1),t.setHours(0,0,0,0)}),((t,e)=>{t.setMonth(t.getMonth()+e)}),((t,e)=>e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())),(t=>t.getMonth()))),gs=(fs.range,za((t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)}),((t,e)=>e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear())),(t=>t.getUTCMonth()))),ys=(gs.range,za((t=>{t.setMonth(0,1),t.setHours(0,0,0,0)}),((t,e)=>{t.setFullYear(t.getFullYear()+e)}),((t,e)=>e.getFullYear()-t.getFullYear()),(t=>t.getFullYear())));ys.every=t=>isFinite(t=Math.floor(t))&&t>0?za((e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),((e,n)=>{e.setFullYear(e.getFullYear()+n*t)})):null;ys.range;const ms=za((t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)}),((t,e)=>e.getUTCFullYear()-t.getUTCFullYear()),(t=>t.getUTCFullYear()));ms.every=t=>isFinite(t=Math.floor(t))&&t>0?za((e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),((e,n)=>{e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null;ms.range;function bs(t,e,n,i,r,a){const s=[[Wa,1,Ba],[Wa,5,5e3],[Wa,15,15e3],[Wa,30,3e4],[a,1,Ma],[a,5,3e5],[a,15,9e5],[a,30,18e5],[r,1,Ia],[r,3,108e5],[r,6,216e5],[r,12,432e5],[i,1,Fa],[i,2,1728e5],[n,1,Ra],[e,1,$a],[e,3,7776e6],[t,1,Pa]];function o(e,n,i){const r=Math.abs(n-e)/i,a=jr((([,,t])=>t)).right(s,r);if(a===s.length)return t.every(Rr(e/Pa,n/Pa,i));if(0===a)return Ua.every(Math.max(Rr(e,n,i),1));const[o,c]=s[r/s[a-1][2]<s[a][2]/r?a-1:a];return o.every(c)}return[function(t,e,n){const i=e<t;i&&([t,e]=[e,t]);const r=n&&"function"==typeof n.range?n:o(t,e,n),a=r?r.range(t,+e+1):[];return i?a.reverse():a},o]}const[_s,xs]=bs(ms,gs,os,Qa,Ga,qa),[vs,ks]=bs(ys,fs,Ja,Xa,Va,Ha);function ws(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function Ts(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Cs(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}}var Es,Ss,As={"-":"",_:" ",0:"0"},Ds=/^\s*\d+/,Ls=/^%/,Ns=/[\\^$*+?|[\]().{}]/g;function Os(t,e,n){var i=t<0?"-":"",r=(i?-t:t)+"",a=r.length;return i+(a<n?new Array(n-a+1).join(e)+r:r)}function Bs(t){return t.replace(Ns,"\\$&")}function Ms(t){return new RegExp("^(?:"+t.map(Bs).join("|")+")","i")}function Is(t){return new Map(t.map(((t,e)=>[t.toLowerCase(),e])))}function Fs(t,e,n){var i=Ds.exec(e.slice(n,n+1));return i?(t.w=+i[0],n+i[0].length):-1}function Rs(t,e,n){var i=Ds.exec(e.slice(n,n+1));return i?(t.u=+i[0],n+i[0].length):-1}function $s(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.U=+i[0],n+i[0].length):-1}function Ps(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.V=+i[0],n+i[0].length):-1}function js(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.W=+i[0],n+i[0].length):-1}function Ys(t,e,n){var i=Ds.exec(e.slice(n,n+4));return i?(t.y=+i[0],n+i[0].length):-1}function zs(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.y=+i[0]+(+i[0]>68?1900:2e3),n+i[0].length):-1}function Us(t,e,n){var i=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return i?(t.Z=i[1]?0:-(i[2]+(i[3]||"00")),n+i[0].length):-1}function Ws(t,e,n){var i=Ds.exec(e.slice(n,n+1));return i?(t.q=3*i[0]-3,n+i[0].length):-1}function Hs(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.m=i[0]-1,n+i[0].length):-1}function qs(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.d=+i[0],n+i[0].length):-1}function Vs(t,e,n){var i=Ds.exec(e.slice(n,n+3));return i?(t.m=0,t.d=+i[0],n+i[0].length):-1}function Gs(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.H=+i[0],n+i[0].length):-1}function Xs(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.M=+i[0],n+i[0].length):-1}function Zs(t,e,n){var i=Ds.exec(e.slice(n,n+2));return i?(t.S=+i[0],n+i[0].length):-1}function Qs(t,e,n){var i=Ds.exec(e.slice(n,n+3));return i?(t.L=+i[0],n+i[0].length):-1}function Ks(t,e,n){var i=Ds.exec(e.slice(n,n+6));return i?(t.L=Math.floor(i[0]/1e3),n+i[0].length):-1}function Js(t,e,n){var i=Ls.exec(e.slice(n,n+1));return i?n+i[0].length:-1}function to(t,e,n){var i=Ds.exec(e.slice(n));return i?(t.Q=+i[0],n+i[0].length):-1}function eo(t,e,n){var i=Ds.exec(e.slice(n));return i?(t.s=+i[0],n+i[0].length):-1}function no(t,e){return Os(t.getDate(),e,2)}function io(t,e){return Os(t.getHours(),e,2)}function ro(t,e){return Os(t.getHours()%12||12,e,2)}function ao(t,e){return Os(1+Xa.count(ys(t),t),e,3)}function so(t,e){return Os(t.getMilliseconds(),e,3)}function oo(t,e){return so(t,e)+"000"}function co(t,e){return Os(t.getMonth()+1,e,2)}function lo(t,e){return Os(t.getMinutes(),e,2)}function ho(t,e){return Os(t.getSeconds(),e,2)}function uo(t){var e=t.getDay();return 0===e?7:e}function po(t,e){return Os(Ja.count(ys(t)-1,t),e,2)}function fo(t){var e=t.getDay();return e>=4||0===e?is(t):is.ceil(t)}function go(t,e){return t=fo(t),Os(is.count(ys(t),t)+(4===ys(t).getDay()),e,2)}function yo(t){return t.getDay()}function mo(t,e){return Os(ts.count(ys(t)-1,t),e,2)}function bo(t,e){return Os(t.getFullYear()%100,e,2)}function _o(t,e){return Os((t=fo(t)).getFullYear()%100,e,2)}function xo(t,e){return Os(t.getFullYear()%1e4,e,4)}function vo(t,e){var n=t.getDay();return Os((t=n>=4||0===n?is(t):is.ceil(t)).getFullYear()%1e4,e,4)}function ko(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Os(e/60|0,"0",2)+Os(e%60,"0",2)}function wo(t,e){return Os(t.getUTCDate(),e,2)}function To(t,e){return Os(t.getUTCHours(),e,2)}function Co(t,e){return Os(t.getUTCHours()%12||12,e,2)}function Eo(t,e){return Os(1+Za.count(ms(t),t),e,3)}function So(t,e){return Os(t.getUTCMilliseconds(),e,3)}function Ao(t,e){return So(t,e)+"000"}function Do(t,e){return Os(t.getUTCMonth()+1,e,2)}function Lo(t,e){return Os(t.getUTCMinutes(),e,2)}function No(t,e){return Os(t.getUTCSeconds(),e,2)}function Oo(t){var e=t.getUTCDay();return 0===e?7:e}function Bo(t,e){return Os(os.count(ms(t)-1,t),e,2)}function Mo(t){var e=t.getUTCDay();return e>=4||0===e?us(t):us.ceil(t)}function Io(t,e){return t=Mo(t),Os(us.count(ms(t),t)+(4===ms(t).getUTCDay()),e,2)}function Fo(t){return t.getUTCDay()}function Ro(t,e){return Os(cs.count(ms(t)-1,t),e,2)}function $o(t,e){return Os(t.getUTCFullYear()%100,e,2)}function Po(t,e){return Os((t=Mo(t)).getUTCFullYear()%100,e,2)}function jo(t,e){return Os(t.getUTCFullYear()%1e4,e,4)}function Yo(t,e){var n=t.getUTCDay();return Os((t=n>=4||0===n?us(t):us.ceil(t)).getUTCFullYear()%1e4,e,4)}function zo(){return"+0000"}function Uo(){return"%"}function Wo(t){return+t}function Ho(t){return Math.floor(+t/1e3)}function qo(t){return new Date(t)}function Vo(t){return t instanceof Date?+t:+new Date(+t)}function Go(t,e,n,i,r,a,s,o,c,l){var h=aa(),u=h.invert,d=h.domain,p=l(".%L"),f=l(":%S"),g=l("%I:%M"),y=l("%I %p"),m=l("%a %d"),b=l("%b %d"),_=l("%B"),x=l("%Y");function v(t){return(c(t)<t?p:o(t)<t?f:s(t)<t?g:a(t)<t?y:i(t)<t?r(t)<t?m:b:n(t)<t?_:x)(t)}return h.invert=function(t){return new Date(u(t))},h.domain=function(t){return arguments.length?d(Array.from(t,Vo)):d().map(qo)},h.ticks=function(e){var n=d();return t(n[0],n[n.length-1],null==e?10:e)},h.tickFormat=function(t,e){return null==e?v:l(e)},h.nice=function(t){var n=d();return t&&"function"==typeof t.range||(t=e(n[0],n[n.length-1],null==t?10:t)),t?d(function(t,e){var n,i=0,r=(t=t.slice()).length-1,a=t[i],s=t[r];return s<a&&(n=i,i=r,r=n,n=a,a=s,s=n),t[i]=e.floor(a),t[r]=e.ceil(s),t}(n,t)):h},h.copy=function(){return ia(h,Go(t,e,n,i,r,a,s,o,c,l))},h}function Xo(t){return"string"==typeof t?new Ve([[document.querySelector(t)]],[document.documentElement]):new Ve([[t]],qe)}function Zo(t){return"string"==typeof t?new Ve([document.querySelectorAll(t)],[document.documentElement]):new Ve([Rt(t)],qe)}function Qo(t){return function(){return t}}!function(t){Es=function(t){var e=t.dateTime,n=t.date,i=t.time,r=t.periods,a=t.days,s=t.shortDays,o=t.months,c=t.shortMonths,l=Ms(r),h=Is(r),u=Ms(a),d=Is(a),p=Ms(s),f=Is(s),g=Ms(o),y=Is(o),m=Ms(c),b=Is(c),_={a:function(t){return s[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return c[t.getMonth()]},B:function(t){return o[t.getMonth()]},c:null,d:no,e:no,f:oo,g:_o,G:vo,H:io,I:ro,j:ao,L:so,m:co,M:lo,p:function(t){return r[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Wo,s:Ho,S:ho,u:uo,U:po,V:go,w:yo,W:mo,x:null,X:null,y:bo,Y:xo,Z:ko,"%":Uo},x={a:function(t){return s[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return o[t.getUTCMonth()]},c:null,d:wo,e:wo,f:Ao,g:Po,G:Yo,H:To,I:Co,j:Eo,L:So,m:Do,M:Lo,p:function(t){return r[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Wo,s:Ho,S:No,u:Oo,U:Bo,V:Io,w:Fo,W:Ro,x:null,X:null,y:$o,Y:jo,Z:zo,"%":Uo},v={a:function(t,e,n){var i=p.exec(e.slice(n));return i?(t.w=f.get(i[0].toLowerCase()),n+i[0].length):-1},A:function(t,e,n){var i=u.exec(e.slice(n));return i?(t.w=d.get(i[0].toLowerCase()),n+i[0].length):-1},b:function(t,e,n){var i=m.exec(e.slice(n));return i?(t.m=b.get(i[0].toLowerCase()),n+i[0].length):-1},B:function(t,e,n){var i=g.exec(e.slice(n));return i?(t.m=y.get(i[0].toLowerCase()),n+i[0].length):-1},c:function(t,n,i){return T(t,e,n,i)},d:qs,e:qs,f:Ks,g:zs,G:Ys,H:Gs,I:Gs,j:Vs,L:Qs,m:Hs,M:Xs,p:function(t,e,n){var i=l.exec(e.slice(n));return i?(t.p=h.get(i[0].toLowerCase()),n+i[0].length):-1},q:Ws,Q:to,s:eo,S:Zs,u:Rs,U:$s,V:Ps,w:Fs,W:js,x:function(t,e,i){return T(t,n,e,i)},X:function(t,e,n){return T(t,i,e,n)},y:zs,Y:Ys,Z:Us,"%":Js};function k(t,e){return function(n){var i,r,a,s=[],o=-1,c=0,l=t.length;for(n instanceof Date||(n=new Date(+n));++o<l;)37===t.charCodeAt(o)&&(s.push(t.slice(c,o)),null!=(r=As[i=t.charAt(++o)])?i=t.charAt(++o):r="e"===i?" ":"0",(a=e[i])&&(i=a(n,r)),s.push(i),c=o+1);return s.push(t.slice(c,o)),s.join("")}}function w(t,e){return function(n){var i,r,a=Cs(1900,void 0,1);if(T(a,t,n+="",0)!=n.length)return null;if("Q"in a)return new Date(a.Q);if("s"in a)return new Date(1e3*a.s+("L"in a?a.L:0));if(e&&!("Z"in a)&&(a.Z=0),"p"in a&&(a.H=a.H%12+12*a.p),void 0===a.m&&(a.m="q"in a?a.q:0),"V"in a){if(a.V<1||a.V>53)return null;"w"in a||(a.w=1),"Z"in a?(r=(i=Ts(Cs(a.y,0,1))).getUTCDay(),i=r>4||0===r?cs.ceil(i):cs(i),i=Za.offset(i,7*(a.V-1)),a.y=i.getUTCFullYear(),a.m=i.getUTCMonth(),a.d=i.getUTCDate()+(a.w+6)%7):(r=(i=ws(Cs(a.y,0,1))).getDay(),i=r>4||0===r?ts.ceil(i):ts(i),i=Xa.offset(i,7*(a.V-1)),a.y=i.getFullYear(),a.m=i.getMonth(),a.d=i.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),r="Z"in a?Ts(Cs(a.y,0,1)).getUTCDay():ws(Cs(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(r+5)%7:a.w+7*a.U-(r+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,Ts(a)):ws(a)}}function T(t,e,n,i){for(var r,a,s=0,o=e.length,c=n.length;s<o;){if(i>=c)return-1;if(37===(r=e.charCodeAt(s++))){if(r=e.charAt(s++),!(a=v[r in As?e.charAt(s++):r])||(i=a(t,n,i))<0)return-1}else if(r!=n.charCodeAt(i++))return-1}return i}return _.x=k(n,_),_.X=k(i,_),_.c=k(e,_),x.x=k(n,x),x.X=k(i,x),x.c=k(e,x),{format:function(t){var e=k(t+="",_);return e.toString=function(){return t},e},parse:function(t){var e=w(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=k(t+="",x);return e.toString=function(){return t},e},utcParse:function(t){var e=w(t+="",!0);return e.toString=function(){return t},e}}}(t),Ss=Es.format,Es.parse,Es.utcFormat,Es.utcParse}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});const Ko=Math.abs,Jo=Math.atan2,tc=Math.cos,ec=Math.max,nc=Math.min,ic=Math.sin,rc=Math.sqrt,ac=1e-12,sc=Math.PI,oc=sc/2,cc=2*sc;function lc(t){return t>1?0:t<-1?sc:Math.acos(t)}function hc(t){return t>=1?oc:t<=-1?-oc:Math.asin(t)}const uc=Math.PI,dc=2*uc,pc=1e-6,fc=dc-pc;function gc(t){this._+=t[0];for(let e=1,n=t.length;e<n;++e)this._+=arguments[e]+t[e]}class yc{constructor(t){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=null==t?gc:function(t){let e=Math.floor(t);if(!(e>=0))throw new Error(`invalid digits: ${t}`);if(e>15)return gc;const n=10**e;return function(t){this._+=t[0];for(let e=1,i=t.length;e<i;++e)this._+=Math.round(arguments[e]*n)/n+t[e]}}(t)}moveTo(t,e){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}`}closePath(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(t,e){this._append`L${this._x1=+t},${this._y1=+e}`}quadraticCurveTo(t,e,n,i){this._append`Q${+t},${+e},${this._x1=+n},${this._y1=+i}`}bezierCurveTo(t,e,n,i,r,a){this._append`C${+t},${+e},${+n},${+i},${this._x1=+r},${this._y1=+a}`}arcTo(t,e,n,i,r){if(t=+t,e=+e,n=+n,i=+i,(r=+r)<0)throw new Error(`negative radius: ${r}`);let a=this._x1,s=this._y1,o=n-t,c=i-e,l=a-t,h=s-e,u=l*l+h*h;if(null===this._x1)this._append`M${this._x1=t},${this._y1=e}`;else if(u>pc)if(Math.abs(h*o-c*l)>pc&&r){let d=n-a,p=i-s,f=o*o+c*c,g=d*d+p*p,y=Math.sqrt(f),m=Math.sqrt(u),b=r*Math.tan((uc-Math.acos((f+u-g)/(2*y*m)))/2),_=b/m,x=b/y;Math.abs(_-1)>pc&&this._append`L${t+_*l},${e+_*h}`,this._append`A${r},${r},0,0,${+(h*d>l*p)},${this._x1=t+x*o},${this._y1=e+x*c}`}else this._append`L${this._x1=t},${this._y1=e}`;else;}arc(t,e,n,i,r,a){if(t=+t,e=+e,a=!!a,(n=+n)<0)throw new Error(`negative radius: ${n}`);let s=n*Math.cos(i),o=n*Math.sin(i),c=t+s,l=e+o,h=1^a,u=a?i-r:r-i;null===this._x1?this._append`M${c},${l}`:(Math.abs(this._x1-c)>pc||Math.abs(this._y1-l)>pc)&&this._append`L${c},${l}`,n&&(u<0&&(u=u%dc+dc),u>fc?this._append`A${n},${n},0,1,${h},${t-s},${e-o}A${n},${n},0,1,${h},${this._x1=c},${this._y1=l}`:u>pc&&this._append`A${n},${n},0,${+(u>=uc)},${h},${this._x1=t+n*Math.cos(r)},${this._y1=e+n*Math.sin(r)}`)}rect(t,e,n,i){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${n=+n}v${+i}h${-n}Z`}toString(){return this._}}function mc(t){let e=3;return t.digits=function(n){if(!arguments.length)return e;if(null==n)e=null;else{const t=Math.floor(n);if(!(t>=0))throw new RangeError(`invalid digits: ${n}`);e=t}return t},()=>new yc(e)}function bc(t){return t.innerRadius}function _c(t){return t.outerRadius}function xc(t){return t.startAngle}function vc(t){return t.endAngle}function kc(t){return t&&t.padAngle}function wc(t,e,n,i,r,a,s,o){var c=n-t,l=i-e,h=s-r,u=o-a,d=u*c-h*l;if(!(d*d<ac))return[t+(d=(h*(e-a)-u*(t-r))/d)*c,e+d*l]}function Tc(t,e,n,i,r,a,s){var o=t-n,c=e-i,l=(s?a:-a)/rc(o*o+c*c),h=l*c,u=-l*o,d=t+h,p=e+u,f=n+h,g=i+u,y=(d+f)/2,m=(p+g)/2,b=f-d,_=g-p,x=b*b+_*_,v=r-a,k=d*g-f*p,w=(_<0?-1:1)*rc(ec(0,v*v*x-k*k)),T=(k*_-b*w)/x,C=(-k*b-_*w)/x,E=(k*_+b*w)/x,S=(-k*b+_*w)/x,A=T-y,D=C-m,L=E-y,N=S-m;return A*A+D*D>L*L+N*N&&(T=E,C=S),{cx:T,cy:C,x01:-h,y01:-u,x11:T*(r/v-1),y11:C*(r/v-1)}}function Cc(){var t=bc,e=_c,n=Qo(0),i=null,r=xc,a=vc,s=kc,o=null,c=mc(l);function l(){var l,h,u=+t.apply(this,arguments),d=+e.apply(this,arguments),p=r.apply(this,arguments)-oc,f=a.apply(this,arguments)-oc,g=Ko(f-p),y=f>p;if(o||(o=l=c()),d<u&&(h=d,d=u,u=h),d>ac)if(g>cc-ac)o.moveTo(d*tc(p),d*ic(p)),o.arc(0,0,d,p,f,!y),u>ac&&(o.moveTo(u*tc(f),u*ic(f)),o.arc(0,0,u,f,p,y));else{var m,b,_=p,x=f,v=p,k=f,w=g,T=g,C=s.apply(this,arguments)/2,E=C>ac&&(i?+i.apply(this,arguments):rc(u*u+d*d)),S=nc(Ko(d-u)/2,+n.apply(this,arguments)),A=S,D=S;if(E>ac){var L=hc(E/u*ic(C)),N=hc(E/d*ic(C));(w-=2*L)>ac?(v+=L*=y?1:-1,k-=L):(w=0,v=k=(p+f)/2),(T-=2*N)>ac?(_+=N*=y?1:-1,x-=N):(T=0,_=x=(p+f)/2)}var O=d*tc(_),B=d*ic(_),M=u*tc(k),I=u*ic(k);if(S>ac){var F,R=d*tc(x),$=d*ic(x),P=u*tc(v),j=u*ic(v);if(g<sc)if(F=wc(O,B,P,j,R,$,M,I)){var Y=O-F[0],z=B-F[1],U=R-F[0],W=$-F[1],H=1/ic(lc((Y*U+z*W)/(rc(Y*Y+z*z)*rc(U*U+W*W)))/2),q=rc(F[0]*F[0]+F[1]*F[1]);A=nc(S,(u-q)/(H-1)),D=nc(S,(d-q)/(H+1))}else A=D=0}T>ac?D>ac?(m=Tc(P,j,O,B,d,D,y),b=Tc(R,$,M,I,d,D,y),o.moveTo(m.cx+m.x01,m.cy+m.y01),D<S?o.arc(m.cx,m.cy,D,Jo(m.y01,m.x01),Jo(b.y01,b.x01),!y):(o.arc(m.cx,m.cy,D,Jo(m.y01,m.x01),Jo(m.y11,m.x11),!y),o.arc(0,0,d,Jo(m.cy+m.y11,m.cx+m.x11),Jo(b.cy+b.y11,b.cx+b.x11),!y),o.arc(b.cx,b.cy,D,Jo(b.y11,b.x11),Jo(b.y01,b.x01),!y))):(o.moveTo(O,B),o.arc(0,0,d,_,x,!y)):o.moveTo(O,B),u>ac&&w>ac?A>ac?(m=Tc(M,I,R,$,u,-A,y),b=Tc(O,B,P,j,u,-A,y),o.lineTo(m.cx+m.x01,m.cy+m.y01),A<S?o.arc(m.cx,m.cy,A,Jo(m.y01,m.x01),Jo(b.y01,b.x01),!y):(o.arc(m.cx,m.cy,A,Jo(m.y01,m.x01),Jo(m.y11,m.x11),!y),o.arc(0,0,u,Jo(m.cy+m.y11,m.cx+m.x11),Jo(b.cy+b.y11,b.cx+b.x11),y),o.arc(b.cx,b.cy,A,Jo(b.y11,b.x11),Jo(b.y01,b.x01),!y))):o.arc(0,0,u,k,v,y):o.lineTo(M,I)}else o.moveTo(0,0);if(o.closePath(),l)return o=null,l+""||null}return l.centroid=function(){var n=(+t.apply(this,arguments)+ +e.apply(this,arguments))/2,i=(+r.apply(this,arguments)+ +a.apply(this,arguments))/2-sc/2;return[tc(i)*n,ic(i)*n]},l.innerRadius=function(e){return arguments.length?(t="function"==typeof e?e:Qo(+e),l):t},l.outerRadius=function(t){return arguments.length?(e="function"==typeof t?t:Qo(+t),l):e},l.cornerRadius=function(t){return arguments.length?(n="function"==typeof t?t:Qo(+t),l):n},l.padRadius=function(t){return arguments.length?(i=null==t?null:"function"==typeof t?t:Qo(+t),l):i},l.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:Qo(+t),l):r},l.endAngle=function(t){return arguments.length?(a="function"==typeof t?t:Qo(+t),l):a},l.padAngle=function(t){return arguments.length?(s="function"==typeof t?t:Qo(+t),l):s},l.context=function(t){return arguments.length?(o=null==t?null:t,l):o},l}Array.prototype.slice;function Ec(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function Sc(t){this._context=t}function Ac(t){return new Sc(t)}function Dc(t){return t[0]}function Lc(t){return t[1]}function Nc(t,e){var n=Qo(!0),i=null,r=Ac,a=null,s=mc(o);function o(o){var c,l,h,u=(o=Ec(o)).length,d=!1;for(null==i&&(a=r(h=s())),c=0;c<=u;++c)!(c<u&&n(l=o[c],c,o))===d&&((d=!d)?a.lineStart():a.lineEnd()),d&&a.point(+t(l,c,o),+e(l,c,o));if(h)return a=null,h+""||null}return t="function"==typeof t?t:void 0===t?Dc:Qo(t),e="function"==typeof e?e:void 0===e?Lc:Qo(e),o.x=function(e){return arguments.length?(t="function"==typeof e?e:Qo(+e),o):t},o.y=function(t){return arguments.length?(e="function"==typeof t?t:Qo(+t),o):e},o.defined=function(t){return arguments.length?(n="function"==typeof t?t:Qo(!!t),o):n},o.curve=function(t){return arguments.length?(r=t,null!=i&&(a=r(i)),o):r},o.context=function(t){return arguments.length?(null==t?i=a=null:a=r(i=t),o):i},o}function Oc(t,e){return e<t?-1:e>t?1:e>=t?0:NaN}function Bc(t){return t}function Mc(){}function Ic(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+n)/6)}function Fc(t){this._context=t}function Rc(t){return new Fc(t)}function $c(t){this._context=t}function Pc(t){this._context=t}function jc(t){this._context=t}function Yc(t){return t<0?-1:1}function zc(t,e,n){var i=t._x1-t._x0,r=e-t._x1,a=(t._y1-t._y0)/(i||r<0&&-0),s=(n-t._y1)/(r||i<0&&-0),o=(a*r+s*i)/(i+r);return(Yc(a)+Yc(s))*Math.min(Math.abs(a),Math.abs(s),.5*Math.abs(o))||0}function Uc(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function Wc(t,e,n){var i=t._x0,r=t._y0,a=t._x1,s=t._y1,o=(a-i)/3;t._context.bezierCurveTo(i+o,r+o*e,a-o,s-o*n,a,s)}function Hc(t){this._context=t}function qc(t){this._context=new Vc(t)}function Vc(t){this._context=t}function Gc(t){this._context=t}function Xc(t){var e,n,i=t.length-1,r=new Array(i),a=new Array(i),s=new Array(i);for(r[0]=0,a[0]=2,s[0]=t[0]+2*t[1],e=1;e<i-1;++e)r[e]=1,a[e]=4,s[e]=4*t[e]+2*t[e+1];for(r[i-1]=2,a[i-1]=7,s[i-1]=8*t[i-1]+t[i],e=1;e<i;++e)n=r[e]/a[e-1],a[e]-=n,s[e]-=n*s[e-1];for(r[i-1]=s[i-1]/a[i-1],e=i-2;e>=0;--e)r[e]=(s[e]-r[e+1])/a[e];for(a[i-1]=(t[i]+r[i-1])/2,e=0;e<i-1;++e)a[e]=2*t[e+1]-r[e+1];return[r,a]}function Zc(t,e){this._context=t,this._t=e}function Qc(t,e,n){this.k=t,this.x=e,this.y=n}Sc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}},Fc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Ic(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Ic(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},$c.prototype={areaStart:Mc,areaEnd:Mc,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:Ic(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},Pc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,i=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(n,i):this._context.moveTo(n,i);break;case 3:this._point=4;default:Ic(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},jc.prototype={areaStart:Mc,areaEnd:Mc,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}},Hc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Wc(this,this._t0,Uc(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var n=NaN;if(e=+e,(t=+t)!==this._x1||e!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Wc(this,Uc(this,n=zc(this,t,e)),n);break;default:Wc(this,this._t0,n=zc(this,t,e))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=n}}},(qc.prototype=Object.create(Hc.prototype)).point=function(t,e){Hc.prototype.point.call(this,e,t)},Vc.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,n,i,r,a){this._context.bezierCurveTo(e,t,i,n,a,r)}},Gc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,n=t.length;if(n)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),2===n)this._context.lineTo(t[1],e[1]);else for(var i=Xc(t),r=Xc(e),a=0,s=1;s<n;++a,++s)this._context.bezierCurveTo(i[0][a],r[0][a],i[1][a],r[1][a],t[s],e[s]);(this._line||0!==this._line&&1===n)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,e){this._x.push(+t),this._y.push(+e)}},Zc.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0<this._t&&this._t<1&&2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}}this._x=t,this._y=e}},Qc.prototype={constructor:Qc,scale:function(t){return 1===t?this:new Qc(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new Qc(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};new Qc(1,0,0);Qc.prototype;var Kc=n(27856);const Jc={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:t=>t>=255?255:t<0?0:t,g:t=>t>=255?255:t<0?0:t,b:t=>t>=255?255:t<0?0:t,h:t=>t%360,s:t=>t>=100?100:t<0?0:t,l:t=>t>=100?100:t<0?0:t,a:t=>t>=1?1:t<0?0:t},toLinear:t=>{const e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:(t,e,n)=>(n<0&&(n+=1),n>1&&(n-=1),n<1/6?t+6*(e-t)*n:n<.5?e:n<2/3?t+(e-t)*(2/3-n)*6:t),hsl2rgb:({h:t,s:e,l:n},i)=>{if(!e)return 2.55*n;t/=360,e/=100;const r=(n/=100)<.5?n*(1+e):n+e-n*e,a=2*n-r;switch(i){case"r":return 255*Jc.hue2rgb(a,r,t+1/3);case"g":return 255*Jc.hue2rgb(a,r,t);case"b":return 255*Jc.hue2rgb(a,r,t-1/3)}},rgb2hsl:({r:t,g:e,b:n},i)=>{t/=255,e/=255,n/=255;const r=Math.max(t,e,n),a=Math.min(t,e,n),s=(r+a)/2;if("l"===i)return 100*s;if(r===a)return 0;const o=r-a;if("s"===i)return 100*(s>.5?o/(2-r-a):o/(r+a));switch(r){case t:return 60*((e-n)/o+(e<n?6:0));case e:return 60*((n-t)/o+2);case n:return 60*((t-e)/o+4);default:return-1}}},tl={clamp:(t,e,n)=>e>n?Math.min(e,Math.max(n,t)):Math.min(n,Math.max(e,t)),round:t=>Math.round(1e10*t)/1e10},el={dec2hex:t=>{const e=Math.round(t).toString(16);return e.length>1?e:`0${e}`}},nl={channel:Jc,lang:tl,unit:el},il={};for(let c=0;c<=255;c++)il[c]=nl.unit.dec2hex(c);const rl=0,al=1,sl=2;const ol=class{constructor(){this.type=rl}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=rl}is(t){return this.type===t}};const cl=class{constructor(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new ol}set(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=rl,this}_ensureHSL(){const t=this.data,{h:e,s:n,l:i}=t;void 0===e&&(t.h=nl.channel.rgb2hsl(t,"h")),void 0===n&&(t.s=nl.channel.rgb2hsl(t,"s")),void 0===i&&(t.l=nl.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r:e,g:n,b:i}=t;void 0===e&&(t.r=nl.channel.hsl2rgb(t,"r")),void 0===n&&(t.g=nl.channel.hsl2rgb(t,"g")),void 0===i&&(t.b=nl.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,e=t.r;return this.type.is(sl)||void 0===e?(this._ensureHSL(),nl.channel.hsl2rgb(t,"r")):e}get g(){const t=this.data,e=t.g;return this.type.is(sl)||void 0===e?(this._ensureHSL(),nl.channel.hsl2rgb(t,"g")):e}get b(){const t=this.data,e=t.b;return this.type.is(sl)||void 0===e?(this._ensureHSL(),nl.channel.hsl2rgb(t,"b")):e}get h(){const t=this.data,e=t.h;return this.type.is(al)||void 0===e?(this._ensureRGB(),nl.channel.rgb2hsl(t,"h")):e}get s(){const t=this.data,e=t.s;return this.type.is(al)||void 0===e?(this._ensureRGB(),nl.channel.rgb2hsl(t,"s")):e}get l(){const t=this.data,e=t.l;return this.type.is(al)||void 0===e?(this._ensureRGB(),nl.channel.rgb2hsl(t,"l")):e}get a(){return this.data.a}set r(t){this.type.set(al),this.changed=!0,this.data.r=t}set g(t){this.type.set(al),this.changed=!0,this.data.g=t}set b(t){this.type.set(al),this.changed=!0,this.data.b=t}set h(t){this.type.set(sl),this.changed=!0,this.data.h=t}set s(t){this.type.set(sl),this.changed=!0,this.data.s=t}set l(t){this.type.set(sl),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}},ll=new cl({r:0,g:0,b:0,a:0},"transparent"),hl={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:t=>{if(35!==t.charCodeAt(0))return;const e=t.match(hl.re);if(!e)return;const n=e[1],i=parseInt(n,16),r=n.length,a=r%4==0,s=r>4,o=s?1:17,c=s?8:4,l=a?0:-1,h=s?255:15;return ll.set({r:(i>>c*(l+3)&h)*o,g:(i>>c*(l+2)&h)*o,b:(i>>c*(l+1)&h)*o,a:a?(i&h)*o/255:1},t)},stringify:t=>{const{r:e,g:n,b:i,a:r}=t;return r<1?`#${il[Math.round(e)]}${il[Math.round(n)]}${il[Math.round(i)]}${il[Math.round(255*r)]}`:`#${il[Math.round(e)]}${il[Math.round(n)]}${il[Math.round(i)]}`}},ul=hl,dl={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:t=>{const e=t.match(dl.hueRe);if(e){const[,t,n]=e;switch(n){case"grad":return nl.channel.clamp.h(.9*parseFloat(t));case"rad":return nl.channel.clamp.h(180*parseFloat(t)/Math.PI);case"turn":return nl.channel.clamp.h(360*parseFloat(t))}}return nl.channel.clamp.h(parseFloat(t))},parse:t=>{const e=t.charCodeAt(0);if(104!==e&&72!==e)return;const n=t.match(dl.re);if(!n)return;const[,i,r,a,s,o]=n;return ll.set({h:dl._hue2deg(i),s:nl.channel.clamp.s(parseFloat(r)),l:nl.channel.clamp.l(parseFloat(a)),a:s?nl.channel.clamp.a(o?parseFloat(s)/100:parseFloat(s)):1},t)},stringify:t=>{const{h:e,s:n,l:i,a:r}=t;return r<1?`hsla(${nl.lang.round(e)}, ${nl.lang.round(n)}%, ${nl.lang.round(i)}%, ${r})`:`hsl(${nl.lang.round(e)}, ${nl.lang.round(n)}%, ${nl.lang.round(i)}%)`}},pl=dl,fl={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:t=>{t=t.toLowerCase();const e=fl.colors[t];if(e)return ul.parse(e)},stringify:t=>{const e=ul.stringify(t);for(const n in fl.colors)if(fl.colors[n]===e)return n}},gl=fl,yl={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:t=>{const e=t.charCodeAt(0);if(114!==e&&82!==e)return;const n=t.match(yl.re);if(!n)return;const[,i,r,a,s,o,c,l,h]=n;return ll.set({r:nl.channel.clamp.r(r?2.55*parseFloat(i):parseFloat(i)),g:nl.channel.clamp.g(s?2.55*parseFloat(a):parseFloat(a)),b:nl.channel.clamp.b(c?2.55*parseFloat(o):parseFloat(o)),a:l?nl.channel.clamp.a(h?parseFloat(l)/100:parseFloat(l)):1},t)},stringify:t=>{const{r:e,g:n,b:i,a:r}=t;return r<1?`rgba(${nl.lang.round(e)}, ${nl.lang.round(n)}, ${nl.lang.round(i)}, ${nl.lang.round(r)})`:`rgb(${nl.lang.round(e)}, ${nl.lang.round(n)}, ${nl.lang.round(i)})`}},ml=yl,bl={format:{keyword:gl,hex:ul,rgb:ml,rgba:ml,hsl:pl,hsla:pl},parse:t=>{if("string"!=typeof t)return t;const e=ul.parse(t)||ml.parse(t)||pl.parse(t)||gl.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},stringify:t=>!t.changed&&t.color?t.color:t.type.is(sl)||void 0===t.data.r?pl.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?ml.stringify(t):ul.stringify(t)},_l=bl,xl=(t,e)=>{const n=_l.parse(t);for(const i in e)n[i]=nl.channel.clamp[i](e[i]);return _l.stringify(n)},vl=(t,e)=>{const n=_l.parse(t),i={};for(const r in e)e[r]&&(i[r]=n[r]+e[r]);return xl(t,i)},kl=(t,e,n=0,i=1)=>{if("number"!=typeof t)return xl(t,{a:e});const r=ll.set({r:nl.channel.clamp.r(t),g:nl.channel.clamp.g(e),b:nl.channel.clamp.b(n),a:nl.channel.clamp.a(i)});return _l.stringify(r)},wl=(t,e,n=50)=>{const{r:i,g:r,b:a,a:s}=_l.parse(t),{r:o,g:c,b:l,a:h}=_l.parse(e),u=n/100,d=2*u-1,p=s-h,f=((d*p==-1?d:(d+p)/(1+d*p))+1)/2,g=1-f;return kl(i*f+o*g,r*f+c*g,a*f+l*g,s*u+h*(1-u))},Tl=(t,e=100)=>{const n=_l.parse(t);return n.r=255-n.r,n.g=255-n.g,n.b=255-n.b,wl(n,t,e)},Cl=(t,e,n)=>{const i=_l.parse(t),r=i[e],a=nl.channel.clamp[e](r+n);return r!==a&&(i[e]=a),_l.stringify(i)},El=(t,e)=>Cl(t,"l",-e),Sl=(t,e)=>Cl(t,"l",e);const Al="object"==typeof global&&global&&global.Object===Object&&global;var Dl="object"==typeof self&&self&&self.Object===Object&&self;const Ll=Al||Dl||Function("return this")();const Nl=Ll.Symbol;var Ol=Object.prototype,Bl=Ol.hasOwnProperty,Ml=Ol.toString,Il=Nl?Nl.toStringTag:void 0;const Fl=function(t){var e=Bl.call(t,Il),n=t[Il];try{t[Il]=void 0;var i=!0}catch(a){}var r=Ml.call(t);return i&&(e?t[Il]=n:delete t[Il]),r};var Rl=Object.prototype.toString;const $l=function(t){return Rl.call(t)};var Pl=Nl?Nl.toStringTag:void 0;const jl=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":Pl&&Pl in Object(t)?Fl(t):$l(t)};const Yl=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)};const zl=function(t){if(!Yl(t))return!1;var e=jl(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e};const Ul=Ll["__core-js_shared__"];var Wl,Hl=(Wl=/[^.]+$/.exec(Ul&&Ul.keys&&Ul.keys.IE_PROTO||""))?"Symbol(src)_1."+Wl:"";const ql=function(t){return!!Hl&&Hl in t};var Vl=Function.prototype.toString;const Gl=function(t){if(null!=t){try{return Vl.call(t)}catch(e){}try{return t+""}catch(e){}}return""};var Xl=/^\[object .+?Constructor\]$/,Zl=Function.prototype,Ql=Object.prototype,Kl=Zl.toString,Jl=Ql.hasOwnProperty,th=RegExp("^"+Kl.call(Jl).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const eh=function(t){return!(!Yl(t)||ql(t))&&(zl(t)?th:Xl).test(Gl(t))};const nh=function(t,e){return null==t?void 0:t[e]};const ih=function(t,e){var n=nh(t,e);return eh(n)?n:void 0};const rh=ih(Object,"create");const ah=function(){this.__data__=rh?rh(null):{},this.size=0};const sh=function(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e};var oh=Object.prototype.hasOwnProperty;const ch=function(t){var e=this.__data__;if(rh){var n=e[t];return"__lodash_hash_undefined__"===n?void 0:n}return oh.call(e,t)?e[t]:void 0};var lh=Object.prototype.hasOwnProperty;const hh=function(t){var e=this.__data__;return rh?void 0!==e[t]:lh.call(e,t)};const uh=function(t,e){var n=this.__data__;return this.size+=this.has(t)?0:1,n[t]=rh&&void 0===e?"__lodash_hash_undefined__":e,this};function dh(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var i=t[e];this.set(i[0],i[1])}}dh.prototype.clear=ah,dh.prototype.delete=sh,dh.prototype.get=ch,dh.prototype.has=hh,dh.prototype.set=uh;const ph=dh;const fh=function(){this.__data__=[],this.size=0};const gh=function(t,e){return t===e||t!=t&&e!=e};const yh=function(t,e){for(var n=t.length;n--;)if(gh(t[n][0],e))return n;return-1};var mh=Array.prototype.splice;const bh=function(t){var e=this.__data__,n=yh(e,t);return!(n<0)&&(n==e.length-1?e.pop():mh.call(e,n,1),--this.size,!0)};const _h=function(t){var e=this.__data__,n=yh(e,t);return n<0?void 0:e[n][1]};const xh=function(t){return yh(this.__data__,t)>-1};const vh=function(t,e){var n=this.__data__,i=yh(n,t);return i<0?(++this.size,n.push([t,e])):n[i][1]=e,this};function kh(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var i=t[e];this.set(i[0],i[1])}}kh.prototype.clear=fh,kh.prototype.delete=bh,kh.prototype.get=_h,kh.prototype.has=xh,kh.prototype.set=vh;const wh=kh;const Th=ih(Ll,"Map");const Ch=function(){this.size=0,this.__data__={hash:new ph,map:new(Th||wh),string:new ph}};const Eh=function(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t};const Sh=function(t,e){var n=t.__data__;return Eh(e)?n["string"==typeof e?"string":"hash"]:n.map};const Ah=function(t){var e=Sh(this,t).delete(t);return this.size-=e?1:0,e};const Dh=function(t){return Sh(this,t).get(t)};const Lh=function(t){return Sh(this,t).has(t)};const Nh=function(t,e){var n=Sh(this,t),i=n.size;return n.set(t,e),this.size+=n.size==i?0:1,this};function Oh(t){var e=-1,n=null==t?0:t.length;for(this.clear();++e<n;){var i=t[e];this.set(i[0],i[1])}}Oh.prototype.clear=Ch,Oh.prototype.delete=Ah,Oh.prototype.get=Dh,Oh.prototype.has=Lh,Oh.prototype.set=Nh;const Bh=Oh;function Mh(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var n=function(){var i=arguments,r=e?e.apply(this,i):i[0],a=n.cache;if(a.has(r))return a.get(r);var s=t.apply(this,i);return n.cache=a.set(r,s)||a,s};return n.cache=new(Mh.Cache||Bh),n}Mh.Cache=Bh;const Ih=Mh;var Fh="comm",Rh="rule",$h="decl",Ph=Math.abs,jh=String.fromCharCode;Object.assign;function Yh(t){return t.trim()}function zh(t,e,n){return t.replace(e,n)}function Uh(t,e){return t.indexOf(e)}function Wh(t,e){return 0|t.charCodeAt(e)}function Hh(t,e,n){return t.slice(e,n)}function qh(t){return t.length}function Vh(t){return t.length}function Gh(t,e){return e.push(t),t}function Xh(t,e){for(var n="",i=Vh(t),r=0;r<i;r++)n+=e(t[r],r,t,e)||"";return n}function Zh(t,e,n,i){switch(t.type){case"@import":case $h:return t.return=t.return||t.value;case Fh:return"";case"@keyframes":return t.return=t.value+"{"+Xh(t.children,i)+"}";case Rh:t.value=t.props.join(",")}return qh(n=Xh(t.children,i))?t.return=t.value+"{"+n+"}":""}var Qh=1,Kh=1,Jh=0,tu=0,eu=0,nu="";function iu(t,e,n,i,r,a,s){return{value:t,root:e,parent:n,type:i,props:r,children:a,line:Qh,column:Kh,length:s,return:""}}function ru(){return eu=tu>0?Wh(nu,--tu):0,Kh--,10===eu&&(Kh=1,Qh--),eu}function au(){return eu=tu<Jh?Wh(nu,tu++):0,Kh++,10===eu&&(Kh=1,Qh++),eu}function su(){return Wh(nu,tu)}function ou(){return tu}function cu(t,e){return Hh(nu,t,e)}function lu(t){switch(t){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function hu(t){return Qh=Kh=1,Jh=qh(nu=t),tu=0,[]}function uu(t){return nu="",t}function du(t){return Yh(cu(tu-1,gu(91===t?t+2:40===t?t+1:t)))}function pu(t){for(;(eu=su())&&eu<33;)au();return lu(t)>2||lu(eu)>3?"":" "}function fu(t,e){for(;--e&&au()&&!(eu<48||eu>102||eu>57&&eu<65||eu>70&&eu<97););return cu(t,ou()+(e<6&&32==su()&&32==au()))}function gu(t){for(;au();)switch(eu){case t:return tu;case 34:case 39:34!==t&&39!==t&&gu(eu);break;case 40:41===t&&gu(t);break;case 92:au()}return tu}function yu(t,e){for(;au()&&t+eu!==57&&(t+eu!==84||47!==su()););return"/*"+cu(e,tu-1)+"*"+jh(47===t?t:au())}function mu(t){for(;!lu(su());)au();return cu(t,tu)}function bu(t){return uu(_u("",null,null,null,[""],t=hu(t),0,[0],t))}function _u(t,e,n,i,r,a,s,o,c){for(var l=0,h=0,u=s,d=0,p=0,f=0,g=1,y=1,m=1,b=0,_="",x=r,v=a,k=i,w=_;y;)switch(f=b,b=au()){case 40:if(108!=f&&58==Wh(w,u-1)){-1!=Uh(w+=zh(du(b),"&","&\f"),"&\f")&&(m=-1);break}case 34:case 39:case 91:w+=du(b);break;case 9:case 10:case 13:case 32:w+=pu(f);break;case 92:w+=fu(ou()-1,7);continue;case 47:switch(su()){case 42:case 47:Gh(vu(yu(au(),ou()),e,n),c);break;default:w+="/"}break;case 123*g:o[l++]=qh(w)*m;case 125*g:case 59:case 0:switch(b){case 0:case 125:y=0;case 59+h:p>0&&qh(w)-u&&Gh(p>32?ku(w+";",i,n,u-1):ku(zh(w," ","")+";",i,n,u-2),c);break;case 59:w+=";";default:if(Gh(k=xu(w,e,n,l,h,r,o,_,x=[],v=[],u),a),123===b)if(0===h)_u(w,e,k,k,x,a,u,o,v);else switch(99===d&&110===Wh(w,3)?100:d){case 100:case 109:case 115:_u(t,k,k,i&&Gh(xu(t,k,k,0,0,r,o,_,r,x=[],u),v),r,v,u,o,i?x:v);break;default:_u(w,k,k,k,[""],v,0,o,v)}}l=h=p=0,g=m=1,_=w="",u=s;break;case 58:u=1+qh(w),p=f;default:if(g<1)if(123==b)--g;else if(125==b&&0==g++&&125==ru())continue;switch(w+=jh(b),b*g){case 38:m=h>0?1:(w+="\f",-1);break;case 44:o[l++]=(qh(w)-1)*m,m=1;break;case 64:45===su()&&(w+=du(au())),d=su(),h=u=qh(_=w+=mu(ou())),b++;break;case 45:45===f&&2==qh(w)&&(g=0)}}return a}function xu(t,e,n,i,r,a,s,o,c,l,h){for(var u=r-1,d=0===r?a:[""],p=Vh(d),f=0,g=0,y=0;f<i;++f)for(var m=0,b=Hh(t,u+1,u=Ph(g=s[f])),_=t;m<p;++m)(_=Yh(g>0?d[m]+" "+b:zh(b,/&\f/g,d[m])))&&(c[y++]=_);return iu(t,e,n,0===r?Rh:o,c,l,h)}function vu(t,e,n){return iu(t,e,n,Fh,jh(eu),Hh(t,2,-2),0)}function ku(t,e,n,i){return iu(t,e,n,$h,Hh(t,0,i),Hh(t,i+1,-1),i)}const wu=function(t,e){for(var n=-1,i=null==t?0:t.length;++n<i&&!1!==e(t[n],n,t););return t};const Tu=function(t){return function(e,n,i){for(var r=-1,a=Object(e),s=i(e),o=s.length;o--;){var c=s[t?o:++r];if(!1===n(a[c],c,a))break}return e}};const Cu=Tu();const Eu=function(t,e){for(var n=-1,i=Array(t);++n<t;)i[n]=e(n);return i};const Su=function(t){return null!=t&&"object"==typeof t};const Au=function(t){return Su(t)&&"[object Arguments]"==jl(t)};var Du=Object.prototype,Lu=Du.hasOwnProperty,Nu=Du.propertyIsEnumerable,Ou=Au(function(){return arguments}())?Au:function(t){return Su(t)&&Lu.call(t,"callee")&&!Nu.call(t,"callee")};const Bu=Ou;const Mu=Array.isArray;const Iu=function(){return!1};var Fu="object"==typeof exports&&exports&&!exports.nodeType&&exports,Ru=Fu&&"object"==typeof module&&module&&!module.nodeType&&module,$u=Ru&&Ru.exports===Fu?Ll.Buffer:void 0;const Pu=($u?$u.isBuffer:void 0)||Iu;var ju=/^(?:0|[1-9]\d*)$/;const Yu=function(t,e){var n=typeof t;return!!(e=null==e?9007199254740991:e)&&("number"==n||"symbol"!=n&&ju.test(t))&&t>-1&&t%1==0&&t<e};const zu=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991};var Uu={};Uu["[object Float32Array]"]=Uu["[object Float64Array]"]=Uu["[object Int8Array]"]=Uu["[object Int16Array]"]=Uu["[object Int32Array]"]=Uu["[object Uint8Array]"]=Uu["[object Uint8ClampedArray]"]=Uu["[object Uint16Array]"]=Uu["[object Uint32Array]"]=!0,Uu["[object Arguments]"]=Uu["[object Array]"]=Uu["[object ArrayBuffer]"]=Uu["[object Boolean]"]=Uu["[object DataView]"]=Uu["[object Date]"]=Uu["[object Error]"]=Uu["[object Function]"]=Uu["[object Map]"]=Uu["[object Number]"]=Uu["[object Object]"]=Uu["[object RegExp]"]=Uu["[object Set]"]=Uu["[object String]"]=Uu["[object WeakMap]"]=!1;const Wu=function(t){return Su(t)&&zu(t.length)&&!!Uu[jl(t)]};const Hu=function(t){return function(e){return t(e)}};var qu="object"==typeof exports&&exports&&!exports.nodeType&&exports,Vu=qu&&"object"==typeof module&&module&&!module.nodeType&&module,Gu=Vu&&Vu.exports===qu&&Al.process,Xu=function(){try{var t=Vu&&Vu.require&&Vu.require("util").types;return t||Gu&&Gu.binding&&Gu.binding("util")}catch(e){}}();const Zu=Xu;var Qu=Zu&&Zu.isTypedArray;const Ku=Qu?Hu(Qu):Wu;var Ju=Object.prototype.hasOwnProperty;const td=function(t,e){var n=Mu(t),i=!n&&Bu(t),r=!n&&!i&&Pu(t),a=!n&&!i&&!r&&Ku(t),s=n||i||r||a,o=s?Eu(t.length,String):[],c=o.length;for(var l in t)!e&&!Ju.call(t,l)||s&&("length"==l||r&&("offset"==l||"parent"==l)||a&&("buffer"==l||"byteLength"==l||"byteOffset"==l)||Yu(l,c))||o.push(l);return o};var ed=Object.prototype;const nd=function(t){var e=t&&t.constructor;return t===("function"==typeof e&&e.prototype||ed)};const id=function(t,e){return function(n){return t(e(n))}};const rd=id(Object.keys,Object);var ad=Object.prototype.hasOwnProperty;const sd=function(t){if(!nd(t))return rd(t);var e=[];for(var n in Object(t))ad.call(t,n)&&"constructor"!=n&&e.push(n);return e};const od=function(t){return null!=t&&zu(t.length)&&!zl(t)};const cd=function(t){return od(t)?td(t):sd(t)};const ld=function(t,e){return t&&Cu(t,e,cd)};const hd=function(t,e){return function(n,i){if(null==n)return n;if(!od(n))return t(n,i);for(var r=n.length,a=e?r:-1,s=Object(n);(e?a--:++a<r)&&!1!==i(s[a],a,s););return n}}(ld);const ud=function(t){return t};const dd=function(t){return"function"==typeof t?t:ud};const pd=function(t,e){return(Mu(t)?wu:hd)(t,dd(e))};const fd=function(t,e){for(var n=-1,i=null==t?0:t.length,r=Array(i);++n<i;)r[n]=e(t[n],n,t);return r};const gd=function(t){return"symbol"==typeof t||Su(t)&&"[object Symbol]"==jl(t)};var yd=Nl?Nl.prototype:void 0,md=yd?yd.toString:void 0;const bd=function t(e){if("string"==typeof e)return e;if(Mu(e))return fd(e,t)+"";if(gd(e))return md?md.call(e):"";var n=e+"";return"0"==n&&1/e==-Infinity?"-0":n};const _d=function(t){return null==t?"":bd(t)};var xd=0;const vd=function(t){var e=++xd;return _d(t)+e};var kd=Object.prototype.hasOwnProperty;const wd=function(t,e){return null!=t&&kd.call(t,e)};var Td=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Cd=/^\w*$/;const Ed=function(t,e){if(Mu(t))return!1;var n=typeof t;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=t&&!gd(t))||(Cd.test(t)||!Td.test(t)||null!=e&&t in Object(e))};var Sd=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Ad=/\\(\\)?/g,Dd=function(t){var e=Ih(t,(function(t){return 500===n.size&&n.clear(),t})),n=e.cache;return e}((function(t){var e=[];return 46===t.charCodeAt(0)&&e.push(""),t.replace(Sd,(function(t,n,i,r){e.push(i?r.replace(Ad,"$1"):n||t)})),e}));const Ld=Dd;const Nd=function(t,e){return Mu(t)?t:Ed(t,e)?[t]:Ld(_d(t))};const Od=function(t){if("string"==typeof t||gd(t))return t;var e=t+"";return"0"==e&&1/t==-Infinity?"-0":e};const Bd=function(t,e,n){for(var i=-1,r=(e=Nd(e,t)).length,a=!1;++i<r;){var s=Od(e[i]);if(!(a=null!=t&&n(t,s)))break;t=t[s]}return a||++i!=r?a:!!(r=null==t?0:t.length)&&zu(r)&&Yu(s,r)&&(Mu(t)||Bu(t))};const Md=function(t,e){return null!=t&&Bd(t,e,wd)};const Id=function(t){return function(){return t}};const Fd=function(t,e){for(var n=-1,i=e.length,r=t.length;++n<i;)t[r+n]=e[n];return t};var Rd=Nl?Nl.isConcatSpreadable:void 0;const $d=function(t){return Mu(t)||Bu(t)||!!(Rd&&t&&t[Rd])};const Pd=function t(e,n,i,r,a){var s=-1,o=e.length;for(i||(i=$d),a||(a=[]);++s<o;){var c=e[s];n>0&&i(c)?n>1?t(c,n-1,i,r,a):Fd(a,c):r||(a[a.length]=c)}return a};const jd=function(t){return(null==t?0:t.length)?Pd(t,1):[]};const Yd=function(){this.__data__=new wh,this.size=0};const zd=function(t){var e=this.__data__,n=e.delete(t);return this.size=e.size,n};const Ud=function(t){return this.__data__.get(t)};const Wd=function(t){return this.__data__.has(t)};const Hd=function(t,e){var n=this.__data__;if(n instanceof wh){var i=n.__data__;if(!Th||i.length<199)return i.push([t,e]),this.size=++n.size,this;n=this.__data__=new Bh(i)}return n.set(t,e),this.size=n.size,this};function qd(t){var e=this.__data__=new wh(t);this.size=e.size}qd.prototype.clear=Yd,qd.prototype.delete=zd,qd.prototype.get=Ud,qd.prototype.has=Wd,qd.prototype.set=Hd;const Vd=qd;const Gd=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this};const Xd=function(t){return this.__data__.has(t)};function Zd(t){var e=-1,n=null==t?0:t.length;for(this.__data__=new Bh;++e<n;)this.add(t[e])}Zd.prototype.add=Zd.prototype.push=Gd,Zd.prototype.has=Xd;const Qd=Zd;const Kd=function(t,e){for(var n=-1,i=null==t?0:t.length;++n<i;)if(e(t[n],n,t))return!0;return!1};const Jd=function(t,e){return t.has(e)};const tp=function(t,e,n,i,r,a){var s=1&n,o=t.length,c=e.length;if(o!=c&&!(s&&c>o))return!1;var l=a.get(t),h=a.get(e);if(l&&h)return l==e&&h==t;var u=-1,d=!0,p=2&n?new Qd:void 0;for(a.set(t,e),a.set(e,t);++u<o;){var f=t[u],g=e[u];if(i)var y=s?i(g,f,u,e,t,a):i(f,g,u,t,e,a);if(void 0!==y){if(y)continue;d=!1;break}if(p){if(!Kd(e,(function(t,e){if(!Jd(p,e)&&(f===t||r(f,t,n,i,a)))return p.push(e)}))){d=!1;break}}else if(f!==g&&!r(f,g,n,i,a)){d=!1;break}}return a.delete(t),a.delete(e),d};const ep=Ll.Uint8Array;const np=function(t){var e=-1,n=Array(t.size);return t.forEach((function(t,i){n[++e]=[i,t]})),n};const ip=function(t){var e=-1,n=Array(t.size);return t.forEach((function(t){n[++e]=t})),n};var rp=Nl?Nl.prototype:void 0,ap=rp?rp.valueOf:void 0;const sp=function(t,e,n,i,r,a,s){switch(n){case"[object DataView]":if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case"[object ArrayBuffer]":return!(t.byteLength!=e.byteLength||!a(new ep(t),new ep(e)));case"[object Boolean]":case"[object Date]":case"[object Number]":return gh(+t,+e);case"[object Error]":return t.name==e.name&&t.message==e.message;case"[object RegExp]":case"[object String]":return t==e+"";case"[object Map]":var o=np;case"[object Set]":var c=1&i;if(o||(o=ip),t.size!=e.size&&!c)return!1;var l=s.get(t);if(l)return l==e;i|=2,s.set(t,e);var h=tp(o(t),o(e),i,r,a,s);return s.delete(t),h;case"[object Symbol]":if(ap)return ap.call(t)==ap.call(e)}return!1};const op=function(t,e,n){var i=e(t);return Mu(t)?i:Fd(i,n(t))};const cp=function(t,e){for(var n=-1,i=null==t?0:t.length,r=0,a=[];++n<i;){var s=t[n];e(s,n,t)&&(a[r++]=s)}return a};const lp=function(){return[]};var hp=Object.prototype.propertyIsEnumerable,up=Object.getOwnPropertySymbols,dp=up?function(t){return null==t?[]:(t=Object(t),cp(up(t),(function(e){return hp.call(t,e)})))}:lp;const pp=dp;const fp=function(t){return op(t,cd,pp)};var gp=Object.prototype.hasOwnProperty;const yp=function(t,e,n,i,r,a){var s=1&n,o=fp(t),c=o.length;if(c!=fp(e).length&&!s)return!1;for(var l=c;l--;){var h=o[l];if(!(s?h in e:gp.call(e,h)))return!1}var u=a.get(t),d=a.get(e);if(u&&d)return u==e&&d==t;var p=!0;a.set(t,e),a.set(e,t);for(var f=s;++l<c;){var g=t[h=o[l]],y=e[h];if(i)var m=s?i(y,g,h,e,t,a):i(g,y,h,t,e,a);if(!(void 0===m?g===y||r(g,y,n,i,a):m)){p=!1;break}f||(f="constructor"==h)}if(p&&!f){var b=t.constructor,_=e.constructor;b==_||!("constructor"in t)||!("constructor"in e)||"function"==typeof b&&b instanceof b&&"function"==typeof _&&_ instanceof _||(p=!1)}return a.delete(t),a.delete(e),p};const mp=ih(Ll,"DataView");const bp=ih(Ll,"Promise");const _p=ih(Ll,"Set");const xp=ih(Ll,"WeakMap");var vp="[object Map]",kp="[object Promise]",wp="[object Set]",Tp="[object WeakMap]",Cp="[object DataView]",Ep=Gl(mp),Sp=Gl(Th),Ap=Gl(bp),Dp=Gl(_p),Lp=Gl(xp),Np=jl;(mp&&Np(new mp(new ArrayBuffer(1)))!=Cp||Th&&Np(new Th)!=vp||bp&&Np(bp.resolve())!=kp||_p&&Np(new _p)!=wp||xp&&Np(new xp)!=Tp)&&(Np=function(t){var e=jl(t),n="[object Object]"==e?t.constructor:void 0,i=n?Gl(n):"";if(i)switch(i){case Ep:return Cp;case Sp:return vp;case Ap:return kp;case Dp:return wp;case Lp:return Tp}return e});const Op=Np;var Bp="[object Arguments]",Mp="[object Array]",Ip="[object Object]",Fp=Object.prototype.hasOwnProperty;const Rp=function(t,e,n,i,r,a){var s=Mu(t),o=Mu(e),c=s?Mp:Op(t),l=o?Mp:Op(e),h=(c=c==Bp?Ip:c)==Ip,u=(l=l==Bp?Ip:l)==Ip,d=c==l;if(d&&Pu(t)){if(!Pu(e))return!1;s=!0,h=!1}if(d&&!h)return a||(a=new Vd),s||Ku(t)?tp(t,e,n,i,r,a):sp(t,e,c,n,i,r,a);if(!(1&n)){var p=h&&Fp.call(t,"__wrapped__"),f=u&&Fp.call(e,"__wrapped__");if(p||f){var g=p?t.value():t,y=f?e.value():e;return a||(a=new Vd),r(g,y,n,i,a)}}return!!d&&(a||(a=new Vd),yp(t,e,n,i,r,a))};const $p=function t(e,n,i,r,a){return e===n||(null==e||null==n||!Su(e)&&!Su(n)?e!=e&&n!=n:Rp(e,n,i,r,t,a))};const Pp=function(t,e,n,i){var r=n.length,a=r,s=!i;if(null==t)return!a;for(t=Object(t);r--;){var o=n[r];if(s&&o[2]?o[1]!==t[o[0]]:!(o[0]in t))return!1}for(;++r<a;){var c=(o=n[r])[0],l=t[c],h=o[1];if(s&&o[2]){if(void 0===l&&!(c in t))return!1}else{var u=new Vd;if(i)var d=i(l,h,c,t,e,u);if(!(void 0===d?$p(h,l,3,i,u):d))return!1}}return!0};const jp=function(t){return t==t&&!Yl(t)};const Yp=function(t){for(var e=cd(t),n=e.length;n--;){var i=e[n],r=t[i];e[n]=[i,r,jp(r)]}return e};const zp=function(t,e){return function(n){return null!=n&&(n[t]===e&&(void 0!==e||t in Object(n)))}};const Up=function(t){var e=Yp(t);return 1==e.length&&e[0][2]?zp(e[0][0],e[0][1]):function(n){return n===t||Pp(n,t,e)}};const Wp=function(t,e){for(var n=0,i=(e=Nd(e,t)).length;null!=t&&n<i;)t=t[Od(e[n++])];return n&&n==i?t:void 0};const Hp=function(t,e,n){var i=null==t?void 0:Wp(t,e);return void 0===i?n:i};const qp=function(t,e){return null!=t&&e in Object(t)};const Vp=function(t,e){return null!=t&&Bd(t,e,qp)};const Gp=function(t,e){return Ed(t)&&jp(e)?zp(Od(t),e):function(n){var i=Hp(n,t);return void 0===i&&i===e?Vp(n,t):$p(e,i,3)}};const Xp=function(t){return function(e){return null==e?void 0:e[t]}};const Zp=function(t){return function(e){return Wp(e,t)}};const Qp=function(t){return Ed(t)?Xp(Od(t)):Zp(t)};const Kp=function(t){return"function"==typeof t?t:null==t?ud:"object"==typeof t?Mu(t)?Gp(t[0],t[1]):Up(t):Qp(t)};const Jp=function(t,e){var n=-1,i=od(t)?Array(t.length):[];return hd(t,(function(t,r,a){i[++n]=e(t,r,a)})),i};const tf=function(t,e){return(Mu(t)?fd:Jp)(t,Kp(e,3))};var ef=Math.ceil,nf=Math.max;const rf=function(t,e,n,i){for(var r=-1,a=nf(ef((e-t)/(n||1)),0),s=Array(a);a--;)s[i?a:++r]=t,t+=n;return s};const af=function(t,e,n){if(!Yl(n))return!1;var i=typeof e;return!!("number"==i?od(n)&&Yu(e,n.length):"string"==i&&e in n)&&gh(n[e],t)};var sf=/\s/;const of=function(t){for(var e=t.length;e--&&sf.test(t.charAt(e)););return e};var cf=/^\s+/;const lf=function(t){return t?t.slice(0,of(t)+1).replace(cf,""):t};var hf=/^[-+]0x[0-9a-f]+$/i,uf=/^0b[01]+$/i,df=/^0o[0-7]+$/i,pf=parseInt;const ff=function(t){if("number"==typeof t)return t;if(gd(t))return NaN;if(Yl(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=Yl(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=lf(t);var n=uf.test(t);return n||df.test(t)?pf(t.slice(2),n?2:8):hf.test(t)?NaN:+t};var gf=1/0;const yf=function(t){return t?(t=ff(t))===gf||t===-1/0?17976931348623157e292*(t<0?-1:1):t==t?t:0:0===t?t:0};const mf=function(t){return function(e,n,i){return i&&"number"!=typeof i&&af(e,n,i)&&(n=i=void 0),e=yf(e),void 0===n?(n=e,e=0):n=yf(n),i=void 0===i?e<n?1:-1:yf(i),rf(e,n,i,t)}};const bf=mf();const _f=function(t,e){var n=[];return hd(t,(function(t,i,r){e(t,i,r)&&n.push(t)})),n};const xf=function(t,e){return(Mu(t)?cp:_f)(t,Kp(e,3))};var vf=Object.prototype.hasOwnProperty;const kf=function(t){if(null==t)return!0;if(od(t)&&(Mu(t)||"string"==typeof t||"function"==typeof t.splice||Pu(t)||Ku(t)||Bu(t)))return!t.length;var e=Op(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if(nd(t))return!sd(t).length;for(var n in t)if(vf.call(t,n))return!1;return!0};const wf=function(t){return void 0===t};const Tf=function(t,e,n){switch(n.length){case 0:return t.call(e);case 1:return t.call(e,n[0]);case 2:return t.call(e,n[0],n[1]);case 3:return t.call(e,n[0],n[1],n[2])}return t.apply(e,n)};var Cf=Math.max;const Ef=function(t,e,n){return e=Cf(void 0===e?t.length-1:e,0),function(){for(var i=arguments,r=-1,a=Cf(i.length-e,0),s=Array(a);++r<a;)s[r]=i[e+r];r=-1;for(var o=Array(e+1);++r<e;)o[r]=i[r];return o[e]=n(s),Tf(t,this,o)}};const Sf=function(){try{var t=ih(Object,"defineProperty");return t({},"",{}),t}catch(e){}}();var Af=Sf?function(t,e){return Sf(t,"toString",{configurable:!0,enumerable:!1,value:Id(e),writable:!0})}:ud;const Df=Af;var Lf=Date.now;const Nf=function(t){var e=0,n=0;return function(){var i=Lf(),r=16-(i-n);if(n=i,r>0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(Df);const Of=function(t,e){return Nf(Ef(t,e,ud),t+"")};const Bf=function(t,e,n,i){for(var r=t.length,a=n+(i?1:-1);i?a--:++a<r;)if(e(t[a],a,t))return a;return-1};const Mf=function(t){return t!=t};const If=function(t,e,n){for(var i=n-1,r=t.length;++i<r;)if(t[i]===e)return i;return-1};const Ff=function(t,e,n){return e==e?If(t,e,n):Bf(t,Mf,n)};const Rf=function(t,e){return!!(null==t?0:t.length)&&Ff(t,e,0)>-1};const $f=function(t,e,n){for(var i=-1,r=null==t?0:t.length;++i<r;)if(n(e,t[i]))return!0;return!1};const Pf=function(){};var jf=_p&&1/ip(new _p([,-0]))[1]==1/0?function(t){return new _p(t)}:Pf;const Yf=jf;const zf=function(t,e,n){var i=-1,r=Rf,a=t.length,s=!0,o=[],c=o;if(n)s=!1,r=$f;else if(a>=200){var l=e?null:Yf(t);if(l)return ip(l);s=!1,r=Jd,c=new Qd}else c=e?[]:o;t:for(;++i<a;){var h=t[i],u=e?e(h):h;if(h=n||0!==h?h:0,s&&u==u){for(var d=c.length;d--;)if(c[d]===u)continue t;e&&c.push(u),o.push(h)}else r(c,u,n)||(c!==o&&c.push(u),o.push(h))}return o};const Uf=function(t){return Su(t)&&od(t)};const Wf=Of((function(t){return zf(Pd(t,1,Uf,!0))}));const Hf=function(t,e){return fd(e,(function(e){return t[e]}))};const qf=function(t){return null==t?[]:Hf(t,cd(t))};const Vf=function(t,e,n,i){var r=-1,a=null==t?0:t.length;for(i&&a&&(n=t[++r]);++r<a;)n=e(n,t[r],r,t);return n};const Gf=function(t,e,n,i,r){return r(t,(function(t,r,a){n=i?(i=!1,t):e(n,t,r,a)})),n};const Xf=function(t,e,n){var i=Mu(t)?Vf:Gf,r=arguments.length<3;return i(t,Kp(e,4),n,r,hd)};var Zf="\0";class Qf{constructor(t={}){this._isDirected=!Md(t,"directed")||t.directed,this._isMultigraph=!!Md(t,"multigraph")&&t.multigraph,this._isCompound=!!Md(t,"compound")&&t.compound,this._label=void 0,this._defaultNodeLabelFn=Id(void 0),this._defaultEdgeLabelFn=Id(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children["\0"]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(t){return this._label=t,this}graph(){return this._label}setDefaultNodeLabel(t){return zl(t)||(t=Id(t)),this._defaultNodeLabelFn=t,this}nodeCount(){return this._nodeCount}nodes(){return cd(this._nodes)}sources(){var t=this;return xf(this.nodes(),(function(e){return kf(t._in[e])}))}sinks(){var t=this;return xf(this.nodes(),(function(e){return kf(t._out[e])}))}setNodes(t,e){var n=arguments,i=this;return pd(t,(function(t){n.length>1?i.setNode(t,e):i.setNode(t)})),this}setNode(t,e){return Md(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=e),this):(this._nodes[t]=arguments.length>1?e:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=Zf,this._children[t]={},this._children["\0"][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)}node(t){return this._nodes[t]}hasNode(t){return Md(this._nodes,t)}removeNode(t){var e=this;if(Md(this._nodes,t)){var n=function(t){e.removeEdge(e._edgeObjs[t])};delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],pd(this.children(t),(function(t){e.setParent(t)})),delete this._children[t]),pd(cd(this._in[t]),n),delete this._in[t],delete this._preds[t],pd(cd(this._out[t]),n),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this}setParent(t,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(wf(e))e=Zf;else{for(var n=e+="";!wf(n);n=this.parent(n))if(n===t)throw new Error("Setting "+e+" as parent of "+t+" would create a cycle");this.setNode(e)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=e,this._children[e][t]=!0,this}_removeFromParentsChildList(t){delete this._children[this._parent[t]][t]}parent(t){if(this._isCompound){var e=this._parent[t];if(e!==Zf)return e}}children(t){if(wf(t)&&(t=Zf),this._isCompound){var e=this._children[t];if(e)return cd(e)}else{if(t===Zf)return this.nodes();if(this.hasNode(t))return[]}}predecessors(t){var e=this._preds[t];if(e)return cd(e)}successors(t){var e=this._sucs[t];if(e)return cd(e)}neighbors(t){var e=this.predecessors(t);if(e)return Wf(e,this.successors(t))}isLeaf(t){return 0===(this.isDirected()?this.successors(t):this.neighbors(t)).length}filterNodes(t){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var n=this;pd(this._nodes,(function(n,i){t(i)&&e.setNode(i,n)})),pd(this._edgeObjs,(function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,n.edge(t))}));var i={};function r(t){var a=n.parent(t);return void 0===a||e.hasNode(a)?(i[t]=a,a):a in i?i[a]:r(a)}return this._isCompound&&pd(e.nodes(),(function(t){e.setParent(t,r(t))})),e}setDefaultEdgeLabel(t){return zl(t)||(t=Id(t)),this._defaultEdgeLabelFn=t,this}edgeCount(){return this._edgeCount}edges(){return qf(this._edgeObjs)}setPath(t,e){var n=this,i=arguments;return Xf(t,(function(t,r){return i.length>1?n.setEdge(t,r,e):n.setEdge(t,r),r})),this}setEdge(){var t,e,n,i,r=!1,a=arguments[0];"object"==typeof a&&null!==a&&"v"in a?(t=a.v,e=a.w,n=a.name,2===arguments.length&&(i=arguments[1],r=!0)):(t=a,e=arguments[1],n=arguments[3],arguments.length>2&&(i=arguments[2],r=!0)),t=""+t,e=""+e,wf(n)||(n=""+n);var s=tg(this._isDirected,t,e,n);if(Md(this._edgeLabels,s))return r&&(this._edgeLabels[s]=i),this;if(!wf(n)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(e),this._edgeLabels[s]=r?i:this._defaultEdgeLabelFn(t,e,n);var o=function(t,e,n,i){var r=""+e,a=""+n;if(!t&&r>a){var s=r;r=a,a=s}var o={v:r,w:a};i&&(o.name=i);return o}(this._isDirected,t,e,n);return t=o.v,e=o.w,Object.freeze(o),this._edgeObjs[s]=o,Kf(this._preds[e],t),Kf(this._sucs[t],e),this._in[e][s]=o,this._out[t][s]=o,this._edgeCount++,this}edge(t,e,n){var i=1===arguments.length?eg(this._isDirected,arguments[0]):tg(this._isDirected,t,e,n);return this._edgeLabels[i]}hasEdge(t,e,n){var i=1===arguments.length?eg(this._isDirected,arguments[0]):tg(this._isDirected,t,e,n);return Md(this._edgeLabels,i)}removeEdge(t,e,n){var i=1===arguments.length?eg(this._isDirected,arguments[0]):tg(this._isDirected,t,e,n),r=this._edgeObjs[i];return r&&(t=r.v,e=r.w,delete this._edgeLabels[i],delete this._edgeObjs[i],Jf(this._preds[e],t),Jf(this._sucs[t],e),delete this._in[e][i],delete this._out[t][i],this._edgeCount--),this}inEdges(t,e){var n=this._in[t];if(n){var i=qf(n);return e?xf(i,(function(t){return t.v===e})):i}}outEdges(t,e){var n=this._out[t];if(n){var i=qf(n);return e?xf(i,(function(t){return t.w===e})):i}}nodeEdges(t,e){var n=this.inEdges(t,e);if(n)return n.concat(this.outEdges(t,e))}}function Kf(t,e){t[e]?t[e]++:t[e]=1}function Jf(t,e){--t[e]||delete t[e]}function tg(t,e,n,i){var r=""+e,a=""+n;if(!t&&r>a){var s=r;r=a,a=s}return r+"\x01"+a+"\x01"+(wf(i)?"\0":i)}function eg(t,e){return tg(t,e.v,e.w,e.name)}Qf.prototype._nodeCount=0,Qf.prototype._edgeCount=0;class ng{constructor(){var t={};t._next=t._prev=t,this._sentinel=t}dequeue(){var t=this._sentinel,e=t._prev;if(e!==t)return ig(e),e}enqueue(t){var e=this._sentinel;t._prev&&t._next&&ig(t),t._next=e._next,e._next._prev=t,e._next=t,t._prev=e}toString(){for(var t=[],e=this._sentinel,n=e._prev;n!==e;)t.push(JSON.stringify(n,rg)),n=n._prev;return"["+t.join(", ")+"]"}}function ig(t){t._prev._next=t._next,t._next._prev=t._prev,delete t._next,delete t._prev}function rg(t,e){if("_next"!==t&&"_prev"!==t)return e}var ag=Id(1);function sg(t,e){if(t.nodeCount()<=1)return[];var n=function(t,e){var n=new Qf,i=0,r=0;pd(t.nodes(),(function(t){n.setNode(t,{v:t,in:0,out:0})})),pd(t.edges(),(function(t){var a=n.edge(t.v,t.w)||0,s=e(t),o=a+s;n.setEdge(t.v,t.w,o),r=Math.max(r,n.node(t.v).out+=s),i=Math.max(i,n.node(t.w).in+=s)}));var a=bf(r+i+3).map((function(){return new ng})),s=i+1;return pd(n.nodes(),(function(t){cg(a,s,n.node(t))})),{graph:n,buckets:a,zeroIdx:s}}(t,e||ag),i=function(t,e,n){var i,r=[],a=e[e.length-1],s=e[0];for(;t.nodeCount();){for(;i=s.dequeue();)og(t,e,n,i);for(;i=a.dequeue();)og(t,e,n,i);if(t.nodeCount())for(var o=e.length-2;o>0;--o)if(i=e[o].dequeue()){r=r.concat(og(t,e,n,i,!0));break}}return r}(n.graph,n.buckets,n.zeroIdx);return jd(tf(i,(function(e){return t.outEdges(e.v,e.w)})),!0)}function og(t,e,n,i,r){var a=r?[]:void 0;return pd(t.inEdges(i.v),(function(i){var s=t.edge(i),o=t.node(i.v);r&&a.push({v:i.v,w:i.w}),o.out-=s,cg(e,n,o)})),pd(t.outEdges(i.v),(function(i){var r=t.edge(i),a=i.w,s=t.node(a);s.in-=r,cg(e,n,s)})),t.removeNode(i.v),a}function cg(t,e,n){n.out?n.in?t[n.out-n.in+e].enqueue(n):t[t.length-1].enqueue(n):t[0].enqueue(n)}function lg(t){var e="greedy"===t.graph().acyclicer?sg(t,function(t){return function(e){return t.edge(e).weight}}(t)):function(t){var e=[],n={},i={};function r(a){Md(i,a)||(i[a]=!0,n[a]=!0,pd(t.outEdges(a),(function(t){Md(n,t.w)?e.push(t):r(t.w)})),delete n[a])}return pd(t.nodes(),r),e}(t);pd(e,(function(e){var n=t.edge(e);t.removeEdge(e),n.forwardName=e.name,n.reversed=!0,t.setEdge(e.w,e.v,n,vd("rev"))}))}const hg=function(t,e,n){"__proto__"==e&&Sf?Sf(t,e,{configurable:!0,enumerable:!0,value:n,writable:!0}):t[e]=n};const ug=function(t,e,n){(void 0!==n&&!gh(t[e],n)||void 0===n&&!(e in t))&&hg(t,e,n)};var dg="object"==typeof exports&&exports&&!exports.nodeType&&exports,pg=dg&&"object"==typeof module&&module&&!module.nodeType&&module,fg=pg&&pg.exports===dg?Ll.Buffer:void 0,gg=fg?fg.allocUnsafe:void 0;const yg=function(t,e){if(e)return t.slice();var n=t.length,i=gg?gg(n):new t.constructor(n);return t.copy(i),i};const mg=function(t){var e=new t.constructor(t.byteLength);return new ep(e).set(new ep(t)),e};const bg=function(t,e){var n=e?mg(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.length)};const _g=function(t,e){var n=-1,i=t.length;for(e||(e=Array(i));++n<i;)e[n]=t[n];return e};var xg=Object.create,vg=function(){function t(){}return function(e){if(!Yl(e))return{};if(xg)return xg(e);t.prototype=e;var n=new t;return t.prototype=void 0,n}}();const kg=vg;const wg=id(Object.getPrototypeOf,Object);const Tg=function(t){return"function"!=typeof t.constructor||nd(t)?{}:kg(wg(t))};var Cg=Function.prototype,Eg=Object.prototype,Sg=Cg.toString,Ag=Eg.hasOwnProperty,Dg=Sg.call(Object);const Lg=function(t){if(!Su(t)||"[object Object]"!=jl(t))return!1;var e=wg(t);if(null===e)return!0;var n=Ag.call(e,"constructor")&&e.constructor;return"function"==typeof n&&n instanceof n&&Sg.call(n)==Dg};const Ng=function(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]};var Og=Object.prototype.hasOwnProperty;const Bg=function(t,e,n){var i=t[e];Og.call(t,e)&&gh(i,n)&&(void 0!==n||e in t)||hg(t,e,n)};const Mg=function(t,e,n,i){var r=!n;n||(n={});for(var a=-1,s=e.length;++a<s;){var o=e[a],c=i?i(n[o],t[o],o,n,t):void 0;void 0===c&&(c=t[o]),r?hg(n,o,c):Bg(n,o,c)}return n};const Ig=function(t){var e=[];if(null!=t)for(var n in Object(t))e.push(n);return e};var Fg=Object.prototype.hasOwnProperty;const Rg=function(t){if(!Yl(t))return Ig(t);var e=nd(t),n=[];for(var i in t)("constructor"!=i||!e&&Fg.call(t,i))&&n.push(i);return n};const $g=function(t){return od(t)?td(t,!0):Rg(t)};const Pg=function(t){return Mg(t,$g(t))};const jg=function(t,e,n,i,r,a,s){var o=Ng(t,n),c=Ng(e,n),l=s.get(c);if(l)ug(t,n,l);else{var h=a?a(o,c,n+"",t,e,s):void 0,u=void 0===h;if(u){var d=Mu(c),p=!d&&Pu(c),f=!d&&!p&&Ku(c);h=c,d||p||f?Mu(o)?h=o:Uf(o)?h=_g(o):p?(u=!1,h=yg(c,!0)):f?(u=!1,h=bg(c,!0)):h=[]:Lg(c)||Bu(c)?(h=o,Bu(o)?h=Pg(o):Yl(o)&&!zl(o)||(h=Tg(c))):u=!1}u&&(s.set(c,h),r(h,c,i,a,s),s.delete(c)),ug(t,n,h)}};const Yg=function t(e,n,i,r,a){e!==n&&Cu(n,(function(s,o){if(a||(a=new Vd),Yl(s))jg(e,n,o,i,t,r,a);else{var c=r?r(Ng(e,o),s,o+"",e,n,a):void 0;void 0===c&&(c=s),ug(e,o,c)}}),$g)};const zg=function(t){return Of((function(e,n){var i=-1,r=n.length,a=r>1?n[r-1]:void 0,s=r>2?n[2]:void 0;for(a=t.length>3&&"function"==typeof a?(r--,a):void 0,s&&af(n[0],n[1],s)&&(a=r<3?void 0:a,r=1),e=Object(e);++i<r;){var o=n[i];o&&t(e,o,i,a)}return e}))};var Ug=zg((function(t,e,n){Yg(t,e,n)}));const Wg=Ug;const Hg=function(t,e,n,i){if(!Yl(t))return t;for(var r=-1,a=(e=Nd(e,t)).length,s=a-1,o=t;null!=o&&++r<a;){var c=Od(e[r]),l=n;if("__proto__"===c||"constructor"===c||"prototype"===c)return t;if(r!=s){var h=o[c];void 0===(l=i?i(h,c,o):void 0)&&(l=Yl(h)?h:Yu(e[r+1])?[]:{})}Bg(o,c,l),o=o[c]}return t};const qg=function(t,e,n){for(var i=-1,r=e.length,a={};++i<r;){var s=e[i],o=Wp(t,s);n(o,s)&&Hg(a,Nd(s,t),o)}return a};const Vg=function(t,e){return qg(t,e,(function(e,n){return Vp(t,n)}))};var Gg=function(t){return Nf(Ef(t,void 0,jd),t+"")}((function(t,e){return null==t?{}:Vg(t,e)}));const Xg=Gg;var Zg=Object.prototype,Qg=Zg.hasOwnProperty,Kg=Of((function(t,e){t=Object(t);var n=-1,i=e.length,r=i>2?e[2]:void 0;for(r&&af(e[0],e[1],r)&&(i=1);++n<i;)for(var a=e[n],s=$g(a),o=-1,c=s.length;++o<c;){var l=s[o],h=t[l];(void 0===h||gh(h,Zg[l])&&!Qg.call(t,l))&&(t[l]=a[l])}return t}));const Jg=Kg;const ty=function(t,e,n){for(var i=-1,r=t.length;++i<r;){var a=t[i],s=e(a);if(null!=s&&(void 0===o?s==s&&!gd(s):n(s,o)))var o=s,c=a}return c};const ey=function(t,e){return t>e};const ny=function(t){return t&&t.length?ty(t,ud,ey):void 0};const iy=function(t){var e=null==t?0:t.length;return e?t[e-1]:void 0};const ry=function(t,e){var n={};return e=Kp(e,3),ld(t,(function(t,i,r){hg(n,i,e(t,i,r))})),n};const ay=function(t,e){return t<e};const sy=function(t){return t&&t.length?ty(t,ud,ay):void 0};const oy=function(){return Ll.Date.now()};function cy(t,e,n,i){var r;do{r=vd(i)}while(t.hasNode(r));return n.dummy=e,t.setNode(r,n),r}function ly(t){var e=new Qf({multigraph:t.isMultigraph()}).setGraph(t.graph());return pd(t.nodes(),(function(n){t.children(n).length||e.setNode(n,t.node(n))})),pd(t.edges(),(function(n){e.setEdge(n,t.edge(n))})),e}function hy(t,e){var n,i,r=t.x,a=t.y,s=e.x-r,o=e.y-a,c=t.width/2,l=t.height/2;if(!s&&!o)throw new Error("Not possible to find intersection inside of the rectangle");return Math.abs(o)*c>Math.abs(s)*l?(o<0&&(l=-l),n=l*s/o,i=l):(s<0&&(c=-c),n=c,i=c*o/s),{x:r+n,y:a+i}}function uy(t){var e=tf(bf(py(t)+1),(function(){return[]}));return pd(t.nodes(),(function(n){var i=t.node(n),r=i.rank;wf(r)||(e[r][i.order]=n)})),e}function dy(t,e,n,i){var r={width:0,height:0};return arguments.length>=4&&(r.rank=n,r.order=i),cy(t,"border",r,e)}function py(t){return ny(tf(t.nodes(),(function(e){var n=t.node(e).rank;if(!wf(n))return n})))}function fy(t,e){var n=oy();try{return e()}finally{console.log(t+" time: "+(oy()-n)+"ms")}}function gy(t,e){return e()}function yy(t,e,n,i,r,a){var s={width:0,height:0,rank:a,borderType:e},o=r[e][a-1],c=cy(t,"border",s,n);r[e][a]=c,t.setParent(c,i),o&&t.setEdge(o,c,{weight:1})}function my(t){var e=t.graph().rankdir.toLowerCase();"bt"!==e&&"rl"!==e||function(t){pd(t.nodes(),(function(e){xy(t.node(e))})),pd(t.edges(),(function(e){var n=t.edge(e);pd(n.points,xy),Md(n,"y")&&xy(n)}))}(t),"lr"!==e&&"rl"!==e||(!function(t){pd(t.nodes(),(function(e){vy(t.node(e))})),pd(t.edges(),(function(e){var n=t.edge(e);pd(n.points,vy),Md(n,"x")&&vy(n)}))}(t),by(t))}function by(t){pd(t.nodes(),(function(e){_y(t.node(e))})),pd(t.edges(),(function(e){_y(t.edge(e))}))}function _y(t){var e=t.width;t.width=t.height,t.height=e}function xy(t){t.y=-t.y}function vy(t){var e=t.x;t.x=t.y,t.y=e}function ky(t){var e=cy(t,"root",{},"_root"),n=function(t){var e={};function n(i,r){var a=t.children(i);a&&a.length&&pd(a,(function(t){n(t,r+1)})),e[i]=r}return pd(t.children(),(function(t){n(t,1)})),e}(t),i=ny(qf(n))-1,r=2*i+1;t.graph().nestingRoot=e,pd(t.edges(),(function(e){t.edge(e).minlen*=r}));var a=function(t){return Xf(t.edges(),(function(e,n){return e+t.edge(n).weight}),0)}(t)+1;pd(t.children(),(function(s){wy(t,e,r,a,i,n,s)})),t.graph().nodeRankFactor=r}function wy(t,e,n,i,r,a,s){var o=t.children(s);if(o.length){var c=dy(t,"_bt"),l=dy(t,"_bb"),h=t.node(s);t.setParent(c,s),h.borderTop=c,t.setParent(l,s),h.borderBottom=l,pd(o,(function(o){wy(t,e,n,i,r,a,o);var h=t.node(o),u=h.borderTop?h.borderTop:o,d=h.borderBottom?h.borderBottom:o,p=h.borderTop?i:2*i,f=u!==d?1:r-a[s]+1;t.setEdge(c,u,{weight:p,minlen:f,nestingEdge:!0}),t.setEdge(d,l,{weight:p,minlen:f,nestingEdge:!0})})),t.parent(s)||t.setEdge(e,c,{weight:0,minlen:r+a[s]})}else s!==e&&t.setEdge(e,s,{weight:0,minlen:n})}const Ty=function(t,e){return t&&Mg(e,cd(e),t)};const Cy=function(t,e){return t&&Mg(e,$g(e),t)};const Ey=function(t,e){return Mg(t,pp(t),e)};var Sy=Object.getOwnPropertySymbols?function(t){for(var e=[];t;)Fd(e,pp(t)),t=wg(t);return e}:lp;const Ay=Sy;const Dy=function(t,e){return Mg(t,Ay(t),e)};const Ly=function(t){return op(t,$g,Ay)};var Ny=Object.prototype.hasOwnProperty;const Oy=function(t){var e=t.length,n=new t.constructor(e);return e&&"string"==typeof t[0]&&Ny.call(t,"index")&&(n.index=t.index,n.input=t.input),n};const By=function(t,e){var n=e?mg(t.buffer):t.buffer;return new t.constructor(n,t.byteOffset,t.byteLength)};var My=/\w*$/;const Iy=function(t){var e=new t.constructor(t.source,My.exec(t));return e.lastIndex=t.lastIndex,e};var Fy=Nl?Nl.prototype:void 0,Ry=Fy?Fy.valueOf:void 0;const $y=function(t){return Ry?Object(Ry.call(t)):{}};const Py=function(t,e,n){var i=t.constructor;switch(e){case"[object ArrayBuffer]":return mg(t);case"[object Boolean]":case"[object Date]":return new i(+t);case"[object DataView]":return By(t,n);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return bg(t,n);case"[object Map]":case"[object Set]":return new i;case"[object Number]":case"[object String]":return new i(t);case"[object RegExp]":return Iy(t);case"[object Symbol]":return $y(t)}};const jy=function(t){return Su(t)&&"[object Map]"==Op(t)};var Yy=Zu&&Zu.isMap;const zy=Yy?Hu(Yy):jy;const Uy=function(t){return Su(t)&&"[object Set]"==Op(t)};var Wy=Zu&&Zu.isSet;const Hy=Wy?Hu(Wy):Uy;var qy="[object Arguments]",Vy="[object Function]",Gy="[object Object]",Xy={};Xy[qy]=Xy["[object Array]"]=Xy["[object ArrayBuffer]"]=Xy["[object DataView]"]=Xy["[object Boolean]"]=Xy["[object Date]"]=Xy["[object Float32Array]"]=Xy["[object Float64Array]"]=Xy["[object Int8Array]"]=Xy["[object Int16Array]"]=Xy["[object Int32Array]"]=Xy["[object Map]"]=Xy["[object Number]"]=Xy["[object Object]"]=Xy["[object RegExp]"]=Xy["[object Set]"]=Xy["[object String]"]=Xy["[object Symbol]"]=Xy["[object Uint8Array]"]=Xy["[object Uint8ClampedArray]"]=Xy["[object Uint16Array]"]=Xy["[object Uint32Array]"]=!0,Xy["[object Error]"]=Xy[Vy]=Xy["[object WeakMap]"]=!1;const Zy=function t(e,n,i,r,a,s){var o,c=1&n,l=2&n,h=4&n;if(i&&(o=a?i(e,r,a,s):i(e)),void 0!==o)return o;if(!Yl(e))return e;var u=Mu(e);if(u){if(o=Oy(e),!c)return _g(e,o)}else{var d=Op(e),p=d==Vy||"[object GeneratorFunction]"==d;if(Pu(e))return yg(e,c);if(d==Gy||d==qy||p&&!a){if(o=l||p?{}:Tg(e),!c)return l?Dy(e,Cy(o,e)):Ey(e,Ty(o,e))}else{if(!Xy[d])return a?e:{};o=Py(e,d,c)}}s||(s=new Vd);var f=s.get(e);if(f)return f;s.set(e,o),Hy(e)?e.forEach((function(r){o.add(t(r,n,i,r,e,s))})):zy(e)&&e.forEach((function(r,a){o.set(a,t(r,n,i,a,e,s))}));var g=u?void 0:(h?l?Ly:fp:l?$g:cd)(e);return wu(g||e,(function(r,a){g&&(r=e[a=r]),Bg(o,a,t(r,n,i,a,e,s))})),o};const Qy=function(t){return Zy(t,5)};function Ky(t,e,n){var i=function(t){var e;for(;t.hasNode(e=vd("_root")););return e}(t),r=new Qf({compound:!0}).setGraph({root:i}).setDefaultNodeLabel((function(e){return t.node(e)}));return pd(t.nodes(),(function(a){var s=t.node(a),o=t.parent(a);(s.rank===e||s.minRank<=e&&e<=s.maxRank)&&(r.setNode(a),r.setParent(a,o||i),pd(t[n](a),(function(e){var n=e.v===a?e.w:e.v,i=r.edge(n,a),s=wf(i)?0:i.weight;r.setEdge(n,a,{weight:t.edge(e).weight+s})})),Md(s,"minRank")&&r.setNode(a,{borderLeft:s.borderLeft[e],borderRight:s.borderRight[e]}))})),r}const Jy=function(t,e,n){for(var i=-1,r=t.length,a=e.length,s={};++i<r;){var o=i<a?e[i]:void 0;n(s,t[i],o)}return s};const tm=function(t,e){return Jy(t||[],e||[],Bg)};const em=function(t,e){var n=t.length;for(t.sort(e);n--;)t[n]=t[n].value;return t};const nm=function(t,e){if(t!==e){var n=void 0!==t,i=null===t,r=t==t,a=gd(t),s=void 0!==e,o=null===e,c=e==e,l=gd(e);if(!o&&!l&&!a&&t>e||a&&s&&c&&!o&&!l||i&&s&&c||!n&&c||!r)return 1;if(!i&&!a&&!l&&t<e||l&&n&&r&&!i&&!a||o&&n&&r||!s&&r||!c)return-1}return 0};const im=function(t,e,n){for(var i=-1,r=t.criteria,a=e.criteria,s=r.length,o=n.length;++i<s;){var c=nm(r[i],a[i]);if(c)return i>=o?c:c*("desc"==n[i]?-1:1)}return t.index-e.index};const rm=function(t,e,n){e=e.length?fd(e,(function(t){return Mu(t)?function(e){return Wp(e,1===t.length?t[0]:t)}:t})):[ud];var i=-1;e=fd(e,Hu(Kp));var r=Jp(t,(function(t,n,r){return{criteria:fd(e,(function(e){return e(t)})),index:++i,value:t}}));return em(r,(function(t,e){return im(t,e,n)}))};const am=Of((function(t,e){if(null==t)return[];var n=e.length;return n>1&&af(t,e[0],e[1])?e=[]:n>2&&af(e[0],e[1],e[2])&&(e=[e[0]]),rm(t,Pd(e,1),[])}));function sm(t,e){for(var n=0,i=1;i<e.length;++i)n+=om(t,e[i-1],e[i]);return n}function om(t,e,n){for(var i=tm(n,tf(n,(function(t,e){return e}))),r=jd(tf(e,(function(e){return am(tf(t.outEdges(e),(function(e){return{pos:i[e.w],weight:t.edge(e).weight}})),"pos")})),!0),a=1;a<n.length;)a<<=1;var s=2*a-1;a-=1;var o=tf(new Array(s),(function(){return 0})),c=0;return pd(r.forEach((function(t){var e=t.pos+a;o[e]+=t.weight;for(var n=0;e>0;)e%2&&(n+=o[e+1]),o[e=e-1>>1]+=t.weight;c+=t.weight*n}))),c}function cm(t,e){var n={};return pd(t,(function(t,e){var i=n[t.v]={indegree:0,in:[],out:[],vs:[t.v],i:e};wf(t.barycenter)||(i.barycenter=t.barycenter,i.weight=t.weight)})),pd(e.edges(),(function(t){var e=n[t.v],i=n[t.w];wf(e)||wf(i)||(i.indegree++,e.out.push(n[t.w]))})),function(t){var e=[];function n(t){return function(e){e.merged||(wf(e.barycenter)||wf(t.barycenter)||e.barycenter>=t.barycenter)&&function(t,e){var n=0,i=0;t.weight&&(n+=t.barycenter*t.weight,i+=t.weight);e.weight&&(n+=e.barycenter*e.weight,i+=e.weight);t.vs=e.vs.concat(t.vs),t.barycenter=n/i,t.weight=i,t.i=Math.min(e.i,t.i),e.merged=!0}(t,e)}}function i(e){return function(n){n.in.push(e),0==--n.indegree&&t.push(n)}}for(;t.length;){var r=t.pop();e.push(r),pd(r.in.reverse(),n(r)),pd(r.out,i(r))}return tf(xf(e,(function(t){return!t.merged})),(function(t){return Xg(t,["vs","i","barycenter","weight"])}))}(xf(n,(function(t){return!t.indegree})))}function lm(t,e){var n,i=function(t,e){var n={lhs:[],rhs:[]};return pd(t,(function(t){e(t)?n.lhs.push(t):n.rhs.push(t)})),n}(t,(function(t){return Md(t,"barycenter")})),r=i.lhs,a=am(i.rhs,(function(t){return-t.i})),s=[],o=0,c=0,l=0;r.sort((n=!!e,function(t,e){return t.barycenter<e.barycenter?-1:t.barycenter>e.barycenter?1:n?e.i-t.i:t.i-e.i})),l=hm(s,a,l),pd(r,(function(t){l+=t.vs.length,s.push(t.vs),o+=t.barycenter*t.weight,c+=t.weight,l=hm(s,a,l)}));var h={vs:jd(s,!0)};return c&&(h.barycenter=o/c,h.weight=c),h}function hm(t,e,n){for(var i;e.length&&(i=iy(e)).i<=n;)e.pop(),t.push(i.vs),n++;return n}function um(t,e,n,i){var r=t.children(e),a=t.node(e),s=a?a.borderLeft:void 0,o=a?a.borderRight:void 0,c={};s&&(r=xf(r,(function(t){return t!==s&&t!==o})));var l=function(t,e){return tf(e,(function(e){var n=t.inEdges(e);if(n.length){var i=Xf(n,(function(e,n){var i=t.edge(n),r=t.node(n.v);return{sum:e.sum+i.weight*r.order,weight:e.weight+i.weight}}),{sum:0,weight:0});return{v:e,barycenter:i.sum/i.weight,weight:i.weight}}return{v:e}}))}(t,r);pd(l,(function(e){if(t.children(e.v).length){var r=um(t,e.v,n,i);c[e.v]=r,Md(r,"barycenter")&&(s=r,wf((a=e).barycenter)?(a.barycenter=s.barycenter,a.weight=s.weight):(a.barycenter=(a.barycenter*a.weight+s.barycenter*s.weight)/(a.weight+s.weight),a.weight+=s.weight))}var a,s}));var h=cm(l,n);!function(t,e){pd(t,(function(t){t.vs=jd(t.vs.map((function(t){return e[t]?e[t].vs:t})),!0)}))}(h,c);var u=lm(h,i);if(s&&(u.vs=jd([s,u.vs,o],!0),t.predecessors(s).length)){var d=t.node(t.predecessors(s)[0]),p=t.node(t.predecessors(o)[0]);Md(u,"barycenter")||(u.barycenter=0,u.weight=0),u.barycenter=(u.barycenter*u.weight+d.order+p.order)/(u.weight+2),u.weight+=2}return u}function dm(t){var e=py(t),n=pm(t,bf(1,e+1),"inEdges"),i=pm(t,bf(e-1,-1,-1),"outEdges"),r=function(t){var e={},n=xf(t.nodes(),(function(e){return!t.children(e).length})),i=ny(tf(n,(function(e){return t.node(e).rank}))),r=tf(bf(i+1),(function(){return[]})),a=am(n,(function(e){return t.node(e).rank}));return pd(a,(function n(i){if(!Md(e,i)){e[i]=!0;var a=t.node(i);r[a.rank].push(i),pd(t.successors(i),n)}})),r}(t);gm(t,r);for(var a,s=Number.POSITIVE_INFINITY,o=0,c=0;c<4;++o,++c){fm(o%2?n:i,o%4>=2);var l=sm(t,r=uy(t));l<s&&(c=0,a=Qy(r),s=l)}gm(t,a)}function pm(t,e,n){return tf(e,(function(e){return Ky(t,e,n)}))}function fm(t,e){var n=new Qf;pd(t,(function(t){var i=t.graph().root,r=um(t,i,n,e);pd(r.vs,(function(e,n){t.node(e).order=n})),function(t,e,n){var i,r={};pd(n,(function(n){for(var a,s,o=t.parent(n);o;){if((a=t.parent(o))?(s=r[a],r[a]=o):(s=i,i=o),s&&s!==o)return void e.setEdge(s,o);o=a}}))}(t,n,r.vs)}))}function gm(t,e){pd(e,(function(e){pd(e,(function(e,n){t.node(e).order=n}))}))}function ym(t){var e=function(t){var e={},n=0;function i(r){var a=n;pd(t.children(r),i),e[r]={low:a,lim:n++}}return pd(t.children(),i),e}(t);pd(t.graph().dummyChains,(function(n){for(var i=t.node(n),r=i.edgeObj,a=function(t,e,n,i){var r,a,s=[],o=[],c=Math.min(e[n].low,e[i].low),l=Math.max(e[n].lim,e[i].lim);r=n;do{r=t.parent(r),s.push(r)}while(r&&(e[r].low>c||l>e[r].lim));a=r,r=i;for(;(r=t.parent(r))!==a;)o.push(r);return{path:s.concat(o.reverse()),lca:a}}(t,e,r.v,r.w),s=a.path,o=a.lca,c=0,l=s[c],h=!0;n!==r.w;){if(i=t.node(n),h){for(;(l=s[c])!==o&&t.node(l).maxRank<i.rank;)c++;l===o&&(h=!1)}if(!h){for(;c<s.length-1&&t.node(l=s[c+1]).minRank<=i.rank;)c++;l=s[c]}t.setParent(n,l),n=t.successors(n)[0]}}))}const mm=function(t){return function(e,n,i){var r=Object(e);if(!od(e)){var a=Kp(n,3);e=cd(e),n=function(t){return a(r[t],t,r)}}var s=t(e,n,i);return s>-1?r[a?e[s]:s]:void 0}};const bm=function(t){var e=yf(t),n=e%1;return e==e?n?e-n:e:0};var _m=Math.max;const xm=function(t,e,n){var i=null==t?0:t.length;if(!i)return-1;var r=null==n?0:bm(n);return r<0&&(r=_m(i+r,0)),Bf(t,Kp(e,3),r)};const vm=mm(xm);const km=function(t,e){return t&&t.length?ty(t,Kp(e,2),ay):void 0};const wm=function(t,e){return null==t?t:Cu(t,dd(e),$g)};function Tm(t,e){var n={};return Xf(e,(function(e,i){var r=0,a=0,s=e.length,o=iy(i);return pd(i,(function(e,c){var l=function(t,e){if(t.node(e).dummy)return vm(t.predecessors(e),(function(e){return t.node(e).dummy}))}(t,e),h=l?t.node(l).order:s;(l||e===o)&&(pd(i.slice(a,c+1),(function(e){pd(t.predecessors(e),(function(i){var a=t.node(i),s=a.order;!(s<r||h<s)||a.dummy&&t.node(e).dummy||Cm(n,i,e)}))})),a=c+1,r=h)})),i})),n}function Cm(t,e,n){if(e>n){var i=e;e=n,n=i}var r=t[e];r||(t[e]=r={}),r[n]=!0}function Em(t,e,n){if(e>n){var i=e;e=n,n=i}return Md(t[e],n)}function Sm(t,e,n,i,r){var a={},s=function(t,e,n,i){var r=new Qf,a=t.graph(),s=function(t,e,n){return function(i,r,a){var s,o=i.node(r),c=i.node(a),l=0;if(l+=o.width/2,Md(o,"labelpos"))switch(o.labelpos.toLowerCase()){case"l":s=-o.width/2;break;case"r":s=o.width/2}if(s&&(l+=n?s:-s),s=0,l+=(o.dummy?e:t)/2,l+=(c.dummy?e:t)/2,l+=c.width/2,Md(c,"labelpos"))switch(c.labelpos.toLowerCase()){case"l":s=c.width/2;break;case"r":s=-c.width/2}return s&&(l+=n?s:-s),s=0,l}}(a.nodesep,a.edgesep,i);return pd(e,(function(e){var i;pd(e,(function(e){var a=n[e];if(r.setNode(a),i){var o=n[i],c=r.edge(o,a);r.setEdge(o,a,Math.max(s(t,e,i),c||0))}i=e}))})),r}(t,e,n,r),o=r?"borderLeft":"borderRight";function c(t,e){for(var n=s.nodes(),i=n.pop(),r={};i;)r[i]?t(i):(r[i]=!0,n.push(i),n=n.concat(e(i))),i=n.pop()}return c((function(t){a[t]=s.inEdges(t).reduce((function(t,e){return Math.max(t,a[e.v]+s.edge(e))}),0)}),s.predecessors.bind(s)),c((function(e){var n=s.outEdges(e).reduce((function(t,e){return Math.min(t,a[e.w]-s.edge(e))}),Number.POSITIVE_INFINITY),i=t.node(e);n!==Number.POSITIVE_INFINITY&&i.borderType!==o&&(a[e]=Math.max(a[e],n))}),s.successors.bind(s)),pd(i,(function(t){a[t]=a[n[t]]})),a}function Am(t){var e,n=uy(t),i=Wg(Tm(t,n),function(t,e){var n={};function i(e,i,r,a,s){var o;pd(bf(i,r),(function(i){o=e[i],t.node(o).dummy&&pd(t.predecessors(o),(function(e){var i=t.node(e);i.dummy&&(i.order<a||i.order>s)&&Cm(n,e,o)}))}))}return Xf(e,(function(e,n){var r,a=-1,s=0;return pd(n,(function(o,c){if("border"===t.node(o).dummy){var l=t.predecessors(o);l.length&&(r=t.node(l[0]).order,i(n,s,c,a,r),s=c,a=r)}i(n,s,n.length,r,e.length)})),n})),n}(t,n)),r={};pd(["u","d"],(function(a){e="u"===a?n:qf(n).reverse(),pd(["l","r"],(function(n){"r"===n&&(e=tf(e,(function(t){return qf(t).reverse()})));var s=("u"===a?t.predecessors:t.successors).bind(t),o=function(t,e,n,i){var r={},a={},s={};return pd(e,(function(t){pd(t,(function(t,e){r[t]=t,a[t]=t,s[t]=e}))})),pd(e,(function(t){var e=-1;pd(t,(function(t){var o=i(t);if(o.length){o=am(o,(function(t){return s[t]}));for(var c=(o.length-1)/2,l=Math.floor(c),h=Math.ceil(c);l<=h;++l){var u=o[l];a[t]===t&&e<s[u]&&!Em(n,t,u)&&(a[u]=t,a[t]=r[t]=r[u],e=s[u])}}}))})),{root:r,align:a}}(0,e,i,s),c=Sm(t,e,o.root,o.align,"r"===n);"r"===n&&(c=ry(c,(function(t){return-t}))),r[a+n]=c}))}));var a=function(t,e){return km(qf(e),(function(e){var n=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY;return wm(e,(function(e,r){var a=function(t,e){return t.node(e).width}(t,r)/2;n=Math.max(e+a,n),i=Math.min(e-a,i)})),n-i}))}(t,r);return function(t,e){var n=qf(e),i=sy(n),r=ny(n);pd(["u","d"],(function(n){pd(["l","r"],(function(a){var s,o=n+a,c=t[o];if(c!==e){var l=qf(c);(s="l"===a?i-sy(l):r-ny(l))&&(t[o]=ry(c,(function(t){return t+s})))}}))}))}(r,a),function(t,e){return ry(t.ul,(function(n,i){if(e)return t[e.toLowerCase()][i];var r=am(tf(t,i));return(r[1]+r[2])/2}))}(r,t.graph().align)}function Dm(t){(function(t){var e=uy(t),n=t.graph().ranksep,i=0;pd(e,(function(e){var r=ny(tf(e,(function(e){return t.node(e).height})));pd(e,(function(e){t.node(e).y=i+r/2})),i+=r+n}))})(t=ly(t)),pd(Am(t),(function(e,n){t.node(n).x=e}))}function Lm(t,e){var n=e&&e.debugTiming?fy:gy;n("layout",(function(){var e=n(" buildLayoutGraph",(function(){return function(t){var e=new Qf({multigraph:!0,compound:!0}),n=jm(t.graph());return e.setGraph(Wg({},Om,Pm(n,Nm),Xg(n,Bm))),pd(t.nodes(),(function(n){var i=jm(t.node(n));e.setNode(n,Jg(Pm(i,Mm),Im)),e.setParent(n,t.parent(n))})),pd(t.edges(),(function(n){var i=jm(t.edge(n));e.setEdge(n,Wg({},Rm,Pm(i,Fm),Xg(i,$m)))})),e}(t)}));n(" runLayout",(function(){!function(t,e){e(" makeSpaceForEdgeLabels",(function(){!function(t){var e=t.graph();e.ranksep/=2,pd(t.edges(),(function(n){var i=t.edge(n);i.minlen*=2,"c"!==i.labelpos.toLowerCase()&&("TB"===e.rankdir||"BT"===e.rankdir?i.width+=i.labeloffset:i.height+=i.labeloffset)}))}(t)})),e(" removeSelfEdges",(function(){!function(t){pd(t.edges(),(function(e){if(e.v===e.w){var n=t.node(e.v);n.selfEdges||(n.selfEdges=[]),n.selfEdges.push({e:e,label:t.edge(e)}),t.removeEdge(e)}}))}(t)})),e(" acyclic",(function(){lg(t)})),e(" nestingGraph.run",(function(){ky(t)})),e(" rank",(function(){!function(t){switch(t.graph().ranker){case"network-simplex":default:yb(t);break;case"tight-tree":!function(t){Ym(t),Um(t)}(t);break;case"longest-path":gb(t)}}(ly(t))})),e(" injectEdgeLabelProxies",(function(){!function(t){pd(t.edges(),(function(e){var n=t.edge(e);if(n.width&&n.height){var i=t.node(e.v),r={rank:(t.node(e.w).rank-i.rank)/2+i.rank,e:e};cy(t,"edge-proxy",r,"_ep")}}))}(t)})),e(" removeEmptyRanks",(function(){!function(t){var e=sy(tf(t.nodes(),(function(e){return t.node(e).rank}))),n=[];pd(t.nodes(),(function(i){var r=t.node(i).rank-e;n[r]||(n[r]=[]),n[r].push(i)}));var i=0,r=t.graph().nodeRankFactor;pd(n,(function(e,n){wf(e)&&n%r!=0?--i:i&&pd(e,(function(e){t.node(e).rank+=i}))}))}(t)})),e(" nestingGraph.cleanup",(function(){!function(t){var e=t.graph();t.removeNode(e.nestingRoot),delete e.nestingRoot,pd(t.edges(),(function(e){t.edge(e).nestingEdge&&t.removeEdge(e)}))}(t)})),e(" normalizeRanks",(function(){!function(t){var e=sy(tf(t.nodes(),(function(e){return t.node(e).rank})));pd(t.nodes(),(function(n){var i=t.node(n);Md(i,"rank")&&(i.rank-=e)}))}(t)})),e(" assignRankMinMax",(function(){!function(t){var e=0;pd(t.nodes(),(function(n){var i=t.node(n);i.borderTop&&(i.minRank=t.node(i.borderTop).rank,i.maxRank=t.node(i.borderBottom).rank,e=ny(e,i.maxRank))})),t.graph().maxRank=e}(t)})),e(" removeEdgeLabelProxies",(function(){!function(t){pd(t.nodes(),(function(e){var n=t.node(e);"edge-proxy"===n.dummy&&(t.edge(n.e).labelRank=n.rank,t.removeNode(e))}))}(t)})),e(" normalize.run",(function(){!function(t){t.graph().dummyChains=[],pd(t.edges(),(function(e){!function(t,e){var n,i,r,a=e.v,s=t.node(a).rank,o=e.w,c=t.node(o).rank,l=e.name,h=t.edge(e),u=h.labelRank;if(c===s+1)return;for(t.removeEdge(e),r=0,++s;s<c;++r,++s)h.points=[],n=cy(t,"edge",i={width:0,height:0,edgeLabel:h,edgeObj:e,rank:s},"_d"),s===u&&(i.width=h.width,i.height=h.height,i.dummy="edge-label",i.labelpos=h.labelpos),t.setEdge(a,n,{weight:h.weight},l),0===r&&t.graph().dummyChains.push(n),a=n;t.setEdge(a,o,{weight:h.weight},l)}(t,e)}))}(t)})),e(" parentDummyChains",(function(){ym(t)})),e(" addBorderSegments",(function(){!function(t){pd(t.children(),(function e(n){var i=t.children(n),r=t.node(n);if(i.length&&pd(i,e),Md(r,"minRank")){r.borderLeft=[],r.borderRight=[];for(var a=r.minRank,s=r.maxRank+1;a<s;++a)yy(t,"borderLeft","_bl",n,r,a),yy(t,"borderRight","_br",n,r,a)}}))}(t)})),e(" order",(function(){dm(t)})),e(" insertSelfEdges",(function(){!function(t){var e=uy(t);pd(e,(function(e){var n=0;pd(e,(function(e,i){var r=t.node(e);r.order=i+n,pd(r.selfEdges,(function(e){cy(t,"selfedge",{width:e.label.width,height:e.label.height,rank:r.rank,order:i+ ++n,e:e.e,label:e.label},"_se")})),delete r.selfEdges}))}))}(t)})),e(" adjustCoordinateSystem",(function(){!function(t){var e=t.graph().rankdir.toLowerCase();"lr"!==e&&"rl"!==e||by(t)}(t)})),e(" position",(function(){Dm(t)})),e(" positionSelfEdges",(function(){!function(t){pd(t.nodes(),(function(e){var n=t.node(e);if("selfedge"===n.dummy){var i=t.node(n.e.v),r=i.x+i.width/2,a=i.y,s=n.x-r,o=i.height/2;t.setEdge(n.e,n.label),t.removeNode(e),n.label.points=[{x:r+2*s/3,y:a-o},{x:r+5*s/6,y:a-o},{x:r+s,y:a},{x:r+5*s/6,y:a+o},{x:r+2*s/3,y:a+o}],n.label.x=n.x,n.label.y=n.y}}))}(t)})),e(" removeBorderNodes",(function(){!function(t){pd(t.nodes(),(function(e){if(t.children(e).length){var n=t.node(e),i=t.node(n.borderTop),r=t.node(n.borderBottom),a=t.node(iy(n.borderLeft)),s=t.node(iy(n.borderRight));n.width=Math.abs(s.x-a.x),n.height=Math.abs(r.y-i.y),n.x=a.x+n.width/2,n.y=i.y+n.height/2}})),pd(t.nodes(),(function(e){"border"===t.node(e).dummy&&t.removeNode(e)}))}(t)})),e(" normalize.undo",(function(){!function(t){pd(t.graph().dummyChains,(function(e){var n,i=t.node(e),r=i.edgeLabel;for(t.setEdge(i.edgeObj,r);i.dummy;)n=t.successors(e)[0],t.removeNode(e),r.points.push({x:i.x,y:i.y}),"edge-label"===i.dummy&&(r.x=i.x,r.y=i.y,r.width=i.width,r.height=i.height),e=n,i=t.node(e)}))}(t)})),e(" fixupEdgeLabelCoords",(function(){!function(t){pd(t.edges(),(function(e){var n=t.edge(e);if(Md(n,"x"))switch("l"!==n.labelpos&&"r"!==n.labelpos||(n.width-=n.labeloffset),n.labelpos){case"l":n.x-=n.width/2+n.labeloffset;break;case"r":n.x+=n.width/2+n.labeloffset}}))}(t)})),e(" undoCoordinateSystem",(function(){my(t)})),e(" translateGraph",(function(){!function(t){var e=Number.POSITIVE_INFINITY,n=0,i=Number.POSITIVE_INFINITY,r=0,a=t.graph(),s=a.marginx||0,o=a.marginy||0;function c(t){var a=t.x,s=t.y,o=t.width,c=t.height;e=Math.min(e,a-o/2),n=Math.max(n,a+o/2),i=Math.min(i,s-c/2),r=Math.max(r,s+c/2)}pd(t.nodes(),(function(e){c(t.node(e))})),pd(t.edges(),(function(e){var n=t.edge(e);Md(n,"x")&&c(n)})),e-=s,i-=o,pd(t.nodes(),(function(n){var r=t.node(n);r.x-=e,r.y-=i})),pd(t.edges(),(function(n){var r=t.edge(n);pd(r.points,(function(t){t.x-=e,t.y-=i})),Md(r,"x")&&(r.x-=e),Md(r,"y")&&(r.y-=i)})),a.width=n-e+s,a.height=r-i+o}(t)})),e(" assignNodeIntersects",(function(){!function(t){pd(t.edges(),(function(e){var n,i,r=t.edge(e),a=t.node(e.v),s=t.node(e.w);r.points?(n=r.points[0],i=r.points[r.points.length-1]):(r.points=[],n=s,i=a),r.points.unshift(hy(a,n)),r.points.push(hy(s,i))}))}(t)})),e(" reversePoints",(function(){!function(t){pd(t.edges(),(function(e){var n=t.edge(e);n.reversed&&n.points.reverse()}))}(t)})),e(" acyclic.undo",(function(){!function(t){pd(t.edges(),(function(e){var n=t.edge(e);if(n.reversed){t.removeEdge(e);var i=n.forwardName;delete n.reversed,delete n.forwardName,t.setEdge(e.w,e.v,n,i)}}))}(t)}))}(e,n)})),n(" updateInputGraph",(function(){!function(t,e){pd(t.nodes(),(function(n){var i=t.node(n),r=e.node(n);i&&(i.x=r.x,i.y=r.y,e.children(n).length&&(i.width=r.width,i.height=r.height))})),pd(t.edges(),(function(n){var i=t.edge(n),r=e.edge(n);i.points=r.points,Md(r,"x")&&(i.x=r.x,i.y=r.y)})),t.graph().width=e.graph().width,t.graph().height=e.graph().height}(t,e)}))}))}var Nm=["nodesep","edgesep","ranksep","marginx","marginy"],Om={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},Bm=["acyclicer","ranker","rankdir","align"],Mm=["width","height"],Im={width:0,height:0},Fm=["minlen","weight","width","height","labeloffset"],Rm={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},$m=["labelpos"];function Pm(t,e){return ry(Xg(t,e),Number)}function jm(t){var e={};return pd(t,(function(t,n){e[n.toLowerCase()]=t})),e}function Ym(t){var e={};pd(t.sources(),(function n(i){var r=t.node(i);if(Md(e,i))return r.rank;e[i]=!0;var a=sy(tf(t.outEdges(i),(function(e){return n(e.w)-t.edge(e).minlen})));return a!==Number.POSITIVE_INFINITY&&null!=a||(a=0),r.rank=a}))}function zm(t,e){return t.node(e.w).rank-t.node(e.v).rank-t.edge(e).minlen}function Um(t){var e,n,i=new Qf({directed:!1}),r=t.nodes()[0],a=t.nodeCount();for(i.setNode(r,{});Wm(i,t)<a;)e=Hm(i,t),n=i.hasNode(e.v)?zm(t,e):-zm(t,e),qm(i,t,n);return i}function Wm(t,e){return pd(t.nodes(),(function n(i){pd(e.nodeEdges(i),(function(r){var a=r.v,s=i===a?r.w:a;t.hasNode(s)||zm(e,r)||(t.setNode(s,{}),t.setEdge(i,s,{}),n(s))}))})),t.nodeCount()}function Hm(t,e){return km(e.edges(),(function(n){if(t.hasNode(n.v)!==t.hasNode(n.w))return zm(e,n)}))}function qm(t,e,n){pd(t.nodes(),(function(t){e.node(t).rank+=n}))}Id(1);Id(1);Xp("length");RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");var Vm="[\\ud800-\\udfff]",Gm="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",Xm="\\ud83c[\\udffb-\\udfff]",Zm="[^\\ud800-\\udfff]",Qm="(?:\\ud83c[\\udde6-\\uddff]){2}",Km="[\\ud800-\\udbff][\\udc00-\\udfff]",Jm="(?:"+Gm+"|"+Xm+")"+"?",tb="[\\ufe0e\\ufe0f]?",eb=tb+Jm+("(?:\\u200d(?:"+[Zm,Qm,Km].join("|")+")"+tb+Jm+")*"),nb="(?:"+[Zm+Gm+"?",Gm,Qm,Km,Vm].join("|")+")";RegExp(Xm+"(?="+Xm+")|"+nb+eb,"g");function ib(){}function rb(t,e,n){Mu(e)||(e=[e]);var i=(t.isDirected()?t.successors:t.neighbors).bind(t),r=[],a={};return pd(e,(function(e){if(!t.hasNode(e))throw new Error("Graph does not have node: "+e);ab(t,e,"post"===n,a,i,r)})),r}function ab(t,e,n,i,r,a){Md(i,e)||(i[e]=!0,n||a.push(e),pd(r(e),(function(e){ab(t,e,n,i,r,a)})),n&&a.push(e))}function sb(t){t=function(t){var e=(new Qf).setGraph(t.graph());return pd(t.nodes(),(function(n){e.setNode(n,t.node(n))})),pd(t.edges(),(function(n){var i=e.edge(n.v,n.w)||{weight:0,minlen:1},r=t.edge(n);e.setEdge(n.v,n.w,{weight:i.weight+r.weight,minlen:Math.max(i.minlen,r.minlen)})})),e}(t),Ym(t);var e,n=Um(t);for(lb(n),ob(n,t);e=ub(n);)pb(n,t,e,db(n,t,e))}function ob(t,e){var n=function(t,e){return rb(t,e,"post")}(t,t.nodes());n=n.slice(0,n.length-1),pd(n,(function(n){!function(t,e,n){var i=t.node(n).parent;t.edge(n,i).cutvalue=cb(t,e,n)}(t,e,n)}))}function cb(t,e,n){var i=t.node(n).parent,r=!0,a=e.edge(n,i),s=0;return a||(r=!1,a=e.edge(i,n)),s=a.weight,pd(e.nodeEdges(n),(function(a){var o,c,l=a.v===n,h=l?a.w:a.v;if(h!==i){var u=l===r,d=e.edge(a).weight;if(s+=u?d:-d,o=n,c=h,t.hasEdge(o,c)){var p=t.edge(n,h).cutvalue;s+=u?-p:p}}})),s}function lb(t,e){arguments.length<2&&(e=t.nodes()[0]),hb(t,{},1,e)}function hb(t,e,n,i,r){var a=n,s=t.node(i);return e[i]=!0,pd(t.neighbors(i),(function(r){Md(e,r)||(n=hb(t,e,n,r,i))})),s.low=a,s.lim=n++,r?s.parent=r:delete s.parent,n}function ub(t){return vm(t.edges(),(function(e){return t.edge(e).cutvalue<0}))}function db(t,e,n){var i=n.v,r=n.w;e.hasEdge(i,r)||(i=n.w,r=n.v);var a=t.node(i),s=t.node(r),o=a,c=!1;a.lim>s.lim&&(o=s,c=!0);var l=xf(e.edges(),(function(e){return c===fb(t,t.node(e.v),o)&&c!==fb(t,t.node(e.w),o)}));return km(l,(function(t){return zm(e,t)}))}function pb(t,e,n,i){var r=n.v,a=n.w;t.removeEdge(r,a),t.setEdge(i.v,i.w,{}),lb(t),ob(t,e),function(t,e){var n=vm(t.nodes(),(function(t){return!e.node(t).parent})),i=function(t,e){return rb(t,e,"pre")}(t,n);i=i.slice(1),pd(i,(function(n){var i=t.node(n).parent,r=e.edge(n,i),a=!1;r||(r=e.edge(i,n),a=!0),e.node(n).rank=e.node(i).rank+(a?r.minlen:-r.minlen)}))}(t,e)}function fb(t,e,n){return n.low<=e.lim&&e.lim<=n.lim}ib.prototype=new Error,sb.initLowLimValues=lb,sb.initCutValues=ob,sb.calcCutValue=cb,sb.leaveEdge=ub,sb.enterEdge=db,sb.exchangeEdges=pb;var gb=Ym;function yb(t){sb(t)}const mb=function(t){return Zy(t,4)};function bb(t){var e={options:{directed:t.isDirected(),multigraph:t.isMultigraph(),compound:t.isCompound()},nodes:_b(t),edges:xb(t)};return wf(t.graph())||(e.value=mb(t.graph())),e}function _b(t){return tf(t.nodes(),(function(e){var n=t.node(e),i=t.parent(e),r={v:e};return wf(n)||(r.value=n),wf(i)||(r.parent=i),r}))}function xb(t){return tf(t.edges(),(function(e){var n=t.edge(e),i={v:e.v,w:e.w};return wf(e.name)||(i.name=e.name),wf(n)||(i.value=n),i}))}const vb={randomUUID:"undefined"!=typeof crypto&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};let kb;const wb=new Uint8Array(16);function Tb(){if(!kb&&(kb="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!kb))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return kb(wb)}const Cb=[];for(let c=0;c<256;++c)Cb.push((c+256).toString(16).slice(1));function Eb(t,e=0){return(Cb[t[e+0]]+Cb[t[e+1]]+Cb[t[e+2]]+Cb[t[e+3]]+"-"+Cb[t[e+4]]+Cb[t[e+5]]+"-"+Cb[t[e+6]]+Cb[t[e+7]]+"-"+Cb[t[e+8]]+Cb[t[e+9]]+"-"+Cb[t[e+10]]+Cb[t[e+11]]+Cb[t[e+12]]+Cb[t[e+13]]+Cb[t[e+14]]+Cb[t[e+15]]).toLowerCase()}const Sb=function(t,e,n){if(vb.randomUUID&&!e&&!t)return vb.randomUUID();const i=(t=t||{}).random||(t.rng||Tb)();if(i[6]=15&i[6]|64,i[8]=63&i[8]|128,e){n=n||0;for(let t=0;t<16;++t)e[n+t]=i[t];return e}return Eb(i)};function Ab(t,e){e&&t.attr("style",e)}function Db(t,e){var n=t.append("foreignObject").attr("width","100000"),i=n.append("xhtml:div");i.attr("xmlns","http://www.w3.org/1999/xhtml");var r=e.label;switch(typeof r){case"function":i.insert(r);break;case"object":i.insert((function(){return r}));break;default:i.html(r)}Ab(i,e.labelStyle),i.style("display","inline-block"),i.style("white-space","nowrap");var a=i.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}var Lb=Object.defineProperty,Nb=(t,e,n)=>(((t,e,n)=>{e in t?Lb(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n})(t,"symbol"!=typeof e?e+"":e,n),n);const Ob={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},Bb={trace:(...t)=>{},debug:(...t)=>{},info:(...t)=>{},warn:(...t)=>{},error:(...t)=>{},fatal:(...t)=>{}},Mb=function(t="fatal"){let e=Ob.fatal;"string"==typeof t?(t=t.toLowerCase())in Ob&&(e=Ob[t]):"number"==typeof t&&(e=t),Bb.trace=()=>{},Bb.debug=()=>{},Bb.info=()=>{},Bb.warn=()=>{},Bb.error=()=>{},Bb.fatal=()=>{},e<=Ob.fatal&&(Bb.fatal=console.error?console.error.bind(console,Ib("FATAL"),"color: orange"):console.log.bind(console,"\x1b[35m",Ib("FATAL"))),e<=Ob.error&&(Bb.error=console.error?console.error.bind(console,Ib("ERROR"),"color: orange"):console.log.bind(console,"\x1b[31m",Ib("ERROR"))),e<=Ob.warn&&(Bb.warn=console.warn?console.warn.bind(console,Ib("WARN"),"color: orange"):console.log.bind(console,"\x1b[33m",Ib("WARN"))),e<=Ob.info&&(Bb.info=console.info?console.info.bind(console,Ib("INFO"),"color: lightblue"):console.log.bind(console,"\x1b[34m",Ib("INFO"))),e<=Ob.debug&&(Bb.debug=console.debug?console.debug.bind(console,Ib("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",Ib("DEBUG"))),e<=Ob.trace&&(Bb.trace=console.debug?console.debug.bind(console,Ib("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",Ib("TRACE")))},Ib=t=>`%c${wt().format("ss.SSS")} : ${t} : `,Fb=t=>Kc.sanitize(t),Rb=(t,e)=>{var n;if(!1!==(null==(n=e.flowchart)?void 0:n.htmlLabels)){const n=e.securityLevel;"antiscript"===n||"strict"===n?t=Fb(t):"loose"!==n&&(t=(t=(t=Yb(t)).replace(/</g,"<").replace(/>/g,">")).replace(/=/g,"="),t=jb(t))}return t},$b=(t,e)=>t?t=e.dompurifyConfig?Kc.sanitize(Rb(t,e),e.dompurifyConfig).toString():Kc.sanitize(Rb(t,e),{FORBID_TAGS:["style"]}).toString():t,Pb=/<br\s*\/?>/gi,jb=t=>t.replace(/#br#/g,"<br/>"),Yb=t=>t.replace(Pb,"#br#"),zb=t=>!1!==t&&!["false","null","0"].includes(String(t).trim().toLowerCase()),Ub=function(t){let e=t;return t.includes("~")?(e=e.replace(/~([^~].*)/,"<$1"),e=e.replace(/~([^~]*)$/,">$1"),Ub(e)):e},Wb={getRows:t=>{if(!t)return[""];return Yb(t).replace(/\\n/g,"#br#").split("#br#")},sanitizeText:$b,sanitizeTextOrArray:(t,e)=>"string"==typeof t?$b(t,e):t.flat().map((t=>$b(t,e))),hasBreaks:t=>Pb.test(t),splitBreaks:t=>t.split(Pb),lineBreakRegex:Pb,removeScript:Fb,getUrl:t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=e.replaceAll(/\(/g,"\\("),e=e.replaceAll(/\)/g,"\\)")),e},evaluate:zb},Hb=(t,e)=>vl(t,e?{s:-40,l:10}:{s:-40,l:-10}),qb="#ffffff",Vb="#f2f2f2";class Gb{constructor(){this.background="#f4f4f4",this.darkMode=!1,this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||vl(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||vl(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||Hb(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||Hb(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||Hb(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||Hb(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||Tl(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||Tl(this.tertiaryColor),this.lineColor=this.lineColor||Tl(this.background),this.textColor=this.textColor||this.primaryTextColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?El(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||"grey",this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||El(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||Tl(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||Sl(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||vl(this.primaryColor,{h:30}),this.cScale4=this.cScale4||vl(this.primaryColor,{h:60}),this.cScale5=this.cScale5||vl(this.primaryColor,{h:90}),this.cScale6=this.cScale6||vl(this.primaryColor,{h:120}),this.cScale7=this.cScale7||vl(this.primaryColor,{h:150}),this.cScale8=this.cScale8||vl(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||vl(this.primaryColor,{h:270}),this.cScale10=this.cScale10||vl(this.primaryColor,{h:300}),this.cScale11=this.cScale11||vl(this.primaryColor,{h:330}),this.darkMode)for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=El(this["cScale"+t],75);else for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=El(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||Tl(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this.darkMode?this["cScalePeer"+t]=this["cScalePeer"+t]||Sl(this["cScale"+t],10):this["cScalePeer"+t]=this["cScalePeer"+t]||El(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||vl(this.primaryColor,{h:64}),this.fillType3=this.fillType3||vl(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||vl(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||vl(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||vl(this.primaryColor,{h:128}),this.fillType7=this.fillType7||vl(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||vl(this.primaryColor,{l:-10}),this.pie5=this.pie5||vl(this.secondaryColor,{l:-10}),this.pie6=this.pie6||vl(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||vl(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||vl(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||vl(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||vl(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||vl(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||vl(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOpacity=this.pieOpacity||"0.7",this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||this.primaryBorderColor,this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?El(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||vl(this.primaryColor,{h:-30}),this.git4=this.git4||vl(this.primaryColor,{h:-60}),this.git5=this.git5||vl(this.primaryColor,{h:-90}),this.git6=this.git6||vl(this.primaryColor,{h:60}),this.git7=this.git7||vl(this.primaryColor,{h:120}),this.darkMode?(this.git0=Sl(this.git0,25),this.git1=Sl(this.git1,25),this.git2=Sl(this.git2,25),this.git3=Sl(this.git3,25),this.git4=Sl(this.git4,25),this.git5=Sl(this.git5,25),this.git6=Sl(this.git6,25),this.git7=Sl(this.git7,25)):(this.git0=El(this.git0,25),this.git1=El(this.git1,25),this.git2=El(this.git2,25),this.git3=El(this.git3,25),this.git4=El(this.git4,25),this.git5=El(this.git5,25),this.git6=El(this.git6,25),this.git7=El(this.git7,25)),this.gitInv0=this.gitInv0||Tl(this.git0),this.gitInv1=this.gitInv1||Tl(this.git1),this.gitInv2=this.gitInv2||Tl(this.git2),this.gitInv3=this.gitInv3||Tl(this.git3),this.gitInv4=this.gitInv4||Tl(this.git4),this.gitInv5=this.gitInv5||Tl(this.git5),this.gitInv6=this.gitInv6||Tl(this.git6),this.gitInv7=this.gitInv7||Tl(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||qb,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Vb}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}class Xb{constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=Sl(this.primaryColor,16),this.tertiaryColor=vl(this.primaryColor,{h:-160}),this.primaryBorderColor=Tl(this.background),this.secondaryBorderColor=Hb(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Hb(this.tertiaryColor,this.darkMode),this.primaryTextColor=Tl(this.primaryColor),this.secondaryTextColor=Tl(this.secondaryColor),this.tertiaryTextColor=Tl(this.tertiaryColor),this.lineColor=Tl(this.background),this.textColor=Tl(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=Sl(Tl("#323D47"),10),this.lineColor="calculated",this.border1="#81B1DB",this.border2=kl(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=El("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.taskBorderColor=kl(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=kl(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.personBorder="calculated",this.personBkg="calculated",this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){this.secondBkg=Sl(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=Sl(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.mainContrastColor,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=Sl(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=vl(this.primaryColor,{h:64}),this.fillType3=vl(this.secondaryColor,{h:64}),this.fillType4=vl(this.primaryColor,{h:-64}),this.fillType5=vl(this.secondaryColor,{h:-64}),this.fillType6=vl(this.primaryColor,{h:128}),this.fillType7=vl(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||vl(this.primaryColor,{h:30}),this.cScale4=this.cScale4||vl(this.primaryColor,{h:60}),this.cScale5=this.cScale5||vl(this.primaryColor,{h:90}),this.cScale6=this.cScale6||vl(this.primaryColor,{h:120}),this.cScale7=this.cScale7||vl(this.primaryColor,{h:150}),this.cScale8=this.cScale8||vl(this.primaryColor,{h:210}),this.cScale9=this.cScale9||vl(this.primaryColor,{h:270}),this.cScale10=this.cScale10||vl(this.primaryColor,{h:300}),this.cScale11=this.cScale11||vl(this.primaryColor,{h:330});for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||Tl(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScalePeer"+t]=this["cScalePeer"+t]||Sl(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["pie"+t]=this["cScale"+t];this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOpacity=this.pieOpacity||"0.7",this.classText=this.primaryTextColor,this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||this.primaryBorderColor,this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?El(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=Sl(this.secondaryColor,20),this.git1=Sl(this.pie2||this.secondaryColor,20),this.git2=Sl(this.pie3||this.tertiaryColor,20),this.git3=Sl(this.pie4||vl(this.primaryColor,{h:-30}),20),this.git4=Sl(this.pie5||vl(this.primaryColor,{h:-60}),20),this.git5=Sl(this.pie6||vl(this.primaryColor,{h:-90}),10),this.git6=Sl(this.pie7||vl(this.primaryColor,{h:60}),10),this.git7=Sl(this.pie8||vl(this.primaryColor,{h:120}),20),this.gitInv0=this.gitInv0||Tl(this.git0),this.gitInv1=this.gitInv1||Tl(this.git1),this.gitInv2=this.gitInv2||Tl(this.git2),this.gitInv3=this.gitInv3||Tl(this.git3),this.gitInv4=this.gitInv4||Tl(this.git4),this.gitInv5=this.gitInv5||Tl(this.git5),this.gitInv6=this.gitInv6||Tl(this.git6),this.gitInv7=this.gitInv7||Tl(this.git7),this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||Sl(this.background,12),this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Sl(this.background,2)}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}class Zb{constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=vl(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=vl(this.primaryColor,{h:-160}),this.primaryBorderColor=Hb(this.primaryColor,this.darkMode),this.secondaryBorderColor=Hb(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Hb(this.tertiaryColor,this.darkMode),this.primaryTextColor=Tl(this.primaryColor),this.secondaryTextColor=Tl(this.secondaryColor),this.tertiaryTextColor=Tl(this.tertiaryColor),this.lineColor=Tl(this.background),this.textColor=Tl(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#e8e8e8",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.sectionBkgColor=kl(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder="calculated",this.personBkg="calculated",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||vl(this.primaryColor,{h:30}),this.cScale4=this.cScale4||vl(this.primaryColor,{h:60}),this.cScale5=this.cScale5||vl(this.primaryColor,{h:90}),this.cScale6=this.cScale6||vl(this.primaryColor,{h:120}),this.cScale7=this.cScale7||vl(this.primaryColor,{h:150}),this.cScale8=this.cScale8||vl(this.primaryColor,{h:210}),this.cScale9=this.cScale9||vl(this.primaryColor,{h:270}),this.cScale10=this.cScale10||vl(this.primaryColor,{h:300}),this.cScale11=this.cScale11||vl(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||El(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||El(this.tertiaryColor,40);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=El(this["cScale"+t],10),this["cScalePeer"+t]=this["cScalePeer"+t]||El(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||vl(this["cScale"+t],{h:180});if(this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor,"calculated"!==this.labelTextColor){this.cScaleLabel0=this.cScaleLabel0||Tl(this.labelTextColor),this.cScaleLabel3=this.cScaleLabel3||Tl(this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.labelTextColor}this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.textColor,this.edgeLabelBackground=this.labelBackground,this.actorBorder=Sl(this.border1,23),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.signalColor=this.textColor,this.signalTextColor=this.textColor,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=vl(this.primaryColor,{h:64}),this.fillType3=vl(this.secondaryColor,{h:64}),this.fillType4=vl(this.primaryColor,{h:-64}),this.fillType5=vl(this.secondaryColor,{h:-64}),this.fillType6=vl(this.primaryColor,{h:128}),this.fillType7=vl(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||vl(this.tertiaryColor,{l:-40}),this.pie4=this.pie4||vl(this.primaryColor,{l:-10}),this.pie5=this.pie5||vl(this.secondaryColor,{l:-30}),this.pie6=this.pie6||vl(this.tertiaryColor,{l:-20}),this.pie7=this.pie7||vl(this.primaryColor,{h:60,l:-20}),this.pie8=this.pie8||vl(this.primaryColor,{h:-60,l:-40}),this.pie9=this.pie9||vl(this.primaryColor,{h:120,l:-40}),this.pie10=this.pie10||vl(this.primaryColor,{h:60,l:-40}),this.pie11=this.pie11||vl(this.primaryColor,{h:-90,l:-40}),this.pie12=this.pie12||vl(this.primaryColor,{h:120,l:-30}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOpacity=this.pieOpacity||"0.7",this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||this.primaryBorderColor,this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.labelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||vl(this.primaryColor,{h:-30}),this.git4=this.git4||vl(this.primaryColor,{h:-60}),this.git5=this.git5||vl(this.primaryColor,{h:-90}),this.git6=this.git6||vl(this.primaryColor,{h:60}),this.git7=this.git7||vl(this.primaryColor,{h:120}),this.darkMode?(this.git0=Sl(this.git0,25),this.git1=Sl(this.git1,25),this.git2=Sl(this.git2,25),this.git3=Sl(this.git3,25),this.git4=Sl(this.git4,25),this.git5=Sl(this.git5,25),this.git6=Sl(this.git6,25),this.git7=Sl(this.git7,25)):(this.git0=El(this.git0,25),this.git1=El(this.git1,25),this.git2=El(this.git2,25),this.git3=El(this.git3,25),this.git4=El(this.git4,25),this.git5=El(this.git5,25),this.git6=El(this.git6,25),this.git7=El(this.git7,25)),this.gitInv0=this.gitInv0||El(Tl(this.git0),25),this.gitInv1=this.gitInv1||Tl(this.git1),this.gitInv2=this.gitInv2||Tl(this.git2),this.gitInv3=this.gitInv3||Tl(this.git3),this.gitInv4=this.gitInv4||Tl(this.git4),this.gitInv5=this.gitInv5||Tl(this.git5),this.gitInv6=this.gitInv6||Tl(this.git6),this.gitInv7=this.gitInv7||Tl(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||Tl(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||Tl(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||qb,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Vb}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}class Qb{constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=Sl("#cde498",10),this.primaryBorderColor=Hb(this.primaryColor,this.darkMode),this.secondaryBorderColor=Hb(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Hb(this.tertiaryColor,this.darkMode),this.primaryTextColor=Tl(this.primaryColor),this.secondaryTextColor=Tl(this.secondaryColor),this.tertiaryTextColor=Tl(this.primaryColor),this.lineColor=Tl(this.background),this.textColor=Tl(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder="calculated",this.personBkg="calculated",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||vl(this.primaryColor,{h:30}),this.cScale4=this.cScale4||vl(this.primaryColor,{h:60}),this.cScale5=this.cScale5||vl(this.primaryColor,{h:90}),this.cScale6=this.cScale6||vl(this.primaryColor,{h:120}),this.cScale7=this.cScale7||vl(this.primaryColor,{h:150}),this.cScale8=this.cScale8||vl(this.primaryColor,{h:210}),this.cScale9=this.cScale9||vl(this.primaryColor,{h:270}),this.cScale10=this.cScale10||vl(this.primaryColor,{h:300}),this.cScale11=this.cScale11||vl(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||El(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||El(this.tertiaryColor,40);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=El(this["cScale"+t],10),this["cScalePeer"+t]=this["cScalePeer"+t]||El(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||vl(this["cScale"+t],{h:180});this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.actorBorder=El(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.taskBorderColor=this.border1,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=vl(this.primaryColor,{h:64}),this.fillType3=vl(this.secondaryColor,{h:64}),this.fillType4=vl(this.primaryColor,{h:-64}),this.fillType5=vl(this.secondaryColor,{h:-64}),this.fillType6=vl(this.primaryColor,{h:128}),this.fillType7=vl(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||vl(this.primaryColor,{l:-30}),this.pie5=this.pie5||vl(this.secondaryColor,{l:-30}),this.pie6=this.pie6||vl(this.tertiaryColor,{h:40,l:-40}),this.pie7=this.pie7||vl(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||vl(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||vl(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||vl(this.primaryColor,{h:60,l:-50}),this.pie11=this.pie11||vl(this.primaryColor,{h:-60,l:-50}),this.pie12=this.pie12||vl(this.primaryColor,{h:120,l:-50}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOpacity=this.pieOpacity||"0.7",this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||this.primaryBorderColor,this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||vl(this.primaryColor,{h:-30}),this.git4=this.git4||vl(this.primaryColor,{h:-60}),this.git5=this.git5||vl(this.primaryColor,{h:-90}),this.git6=this.git6||vl(this.primaryColor,{h:60}),this.git7=this.git7||vl(this.primaryColor,{h:120}),this.darkMode?(this.git0=Sl(this.git0,25),this.git1=Sl(this.git1,25),this.git2=Sl(this.git2,25),this.git3=Sl(this.git3,25),this.git4=Sl(this.git4,25),this.git5=Sl(this.git5,25),this.git6=Sl(this.git6,25),this.git7=Sl(this.git7,25)):(this.git0=El(this.git0,25),this.git1=El(this.git1,25),this.git2=El(this.git2,25),this.git3=El(this.git3,25),this.git4=El(this.git4,25),this.git5=El(this.git5,25),this.git6=El(this.git6,25),this.git7=El(this.git7,25)),this.gitInv0=this.gitInv0||Tl(this.git0),this.gitInv1=this.gitInv1||Tl(this.git1),this.gitInv2=this.gitInv2||Tl(this.git2),this.gitInv3=this.gitInv3||Tl(this.git3),this.gitInv4=this.gitInv4||Tl(this.git4),this.gitInv5=this.gitInv5||Tl(this.git5),this.gitInv6=this.gitInv6||Tl(this.git6),this.gitInv7=this.gitInv7||Tl(this.git7),this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||qb,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Vb}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}class Kb{constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=Sl(this.contrast,55),this.background="#ffffff",this.tertiaryColor=vl(this.primaryColor,{h:-160}),this.primaryBorderColor=Hb(this.primaryColor,this.darkMode),this.secondaryBorderColor=Hb(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=Hb(this.tertiaryColor,this.darkMode),this.primaryTextColor=Tl(this.primaryColor),this.secondaryTextColor=Tl(this.secondaryColor),this.tertiaryTextColor=Tl(this.tertiaryColor),this.lineColor=Tl(this.background),this.textColor=Tl(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.personBorder="calculated",this.personBkg="calculated",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.secondBkg=Sl(this.contrast,55),this.border2=this.contrast,this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||Tl(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this.darkMode?this["cScalePeer"+t]=this["cScalePeer"+t]||Sl(this["cScale"+t],10):this["cScalePeer"+t]=this["cScalePeer"+t]||El(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor),this.cScaleLabel0=this.cScaleLabel0||this.cScale1,this.cScaleLabel2=this.cScaleLabel2||this.cScale1;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.text,this.actorBorder=Sl(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.lineColor,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.sectionBkgColor=Sl(this.contrast,30),this.sectionBkgColor2=Sl(this.contrast,30),this.taskBorderColor=El(this.contrast,10),this.taskBkgColor=this.contrast,this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor=this.text,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.gridColor=Sl(this.border1,30),this.doneTaskBkgColor=this.done,this.doneTaskBorderColor=this.lineColor,this.critBkgColor=this.critical,this.critBorderColor=El(this.critBkgColor,10),this.todayLineColor=this.critBkgColor,this.transitionColor=this.transitionColor||"#000",this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f4f4f4",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.stateBorder=this.stateBorder||"#000",this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#222",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=vl(this.primaryColor,{h:64}),this.fillType3=vl(this.secondaryColor,{h:64}),this.fillType4=vl(this.primaryColor,{h:-64}),this.fillType5=vl(this.secondaryColor,{h:-64}),this.fillType6=vl(this.primaryColor,{h:128}),this.fillType7=vl(this.secondaryColor,{h:128});for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["pie"+t]=this["cScale"+t];this.pie12=this.pie0,this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOpacity=this.pieOpacity||"0.7",this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||this.primaryBorderColor,this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=El(this.pie1,25)||this.primaryColor,this.git1=this.pie2||this.secondaryColor,this.git2=this.pie3||this.tertiaryColor,this.git3=this.pie4||vl(this.primaryColor,{h:-30}),this.git4=this.pie5||vl(this.primaryColor,{h:-60}),this.git5=this.pie6||vl(this.primaryColor,{h:-90}),this.git6=this.pie7||vl(this.primaryColor,{h:60}),this.git7=this.pie8||vl(this.primaryColor,{h:120}),this.gitInv0=this.gitInv0||Tl(this.git0),this.gitInv1=this.gitInv1||Tl(this.git1),this.gitInv2=this.gitInv2||Tl(this.git2),this.gitInv3=this.gitInv3||Tl(this.git3),this.gitInv4=this.gitInv4||Tl(this.git4),this.gitInv5=this.gitInv5||Tl(this.git5),this.gitInv6=this.gitInv6||Tl(this.git6),this.gitInv7=this.gitInv7||Tl(this.git7),this.branchLabelColor=this.branchLabelColor||this.labelTextColor,this.gitBranchLabel0=this.branchLabelColor,this.gitBranchLabel1="white",this.gitBranchLabel2=this.branchLabelColor,this.gitBranchLabel3="white",this.gitBranchLabel4=this.branchLabelColor,this.gitBranchLabel5=this.branchLabelColor,this.gitBranchLabel6=this.branchLabelColor,this.gitBranchLabel7=this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||qb,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Vb}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}const Jb={base:{getThemeVariables:t=>{const e=new Gb;return e.calculate(t),e}},dark:{getThemeVariables:t=>{const e=new Xb;return e.calculate(t),e}},default:{getThemeVariables:t=>{const e=new Zb;return e.calculate(t),e}},forest:{getThemeVariables:t=>{const e=new Qb;return e.calculate(t),e}},neutral:{getThemeVariables:t=>{const e=new Kb;return e.calculate(t),e}}},t_={theme:"default",themeVariables:Jb.default.getThemeVariables(),themeCSS:void 0,maxTextSize:5e4,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize"],deterministicIds:!1,deterministicIDSeed:void 0,flowchart:{titleTopMargin:25,diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,useMaxWidth:!0,defaultRenderer:"dagre-wrapper"},sequence:{hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,useMaxWidth:!0,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20,messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},noteFont:function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},actorFont:function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}}},gantt:{titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",tickInterval:void 0,useMaxWidth:!0,topAxis:!1,useWidth:void 0},journey:{diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,useMaxWidth:!0,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},class:{titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,useMaxWidth:!0,defaultRenderer:"dagre-wrapper"},state:{titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,useMaxWidth:!0,defaultRenderer:"dagre-wrapper"},er:{titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:"gray",fill:"honeydew",fontSize:12,useMaxWidth:!0},pie:{useWidth:void 0,useMaxWidth:!0},requirement:{useWidth:void 0,useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},gitGraph:{titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0},c4:{useWidth:void 0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,useMaxWidth:!0,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,personFont:function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},external_personFont:function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},systemFont:function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},external_systemFont:function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},system_dbFont:function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},external_system_dbFont:function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},system_queueFont:function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},external_system_queueFont:function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},containerFont:function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},external_containerFont:function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},container_dbFont:function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},external_container_dbFont:function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},container_queueFont:function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},external_container_queueFont:function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},componentFont:function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},external_componentFont:function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},component_dbFont:function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},external_component_dbFont:function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},component_queueFont:function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},external_component_queueFont:function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},boundaryFont:function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},fontSize:16};t_.class&&(t_.class.arrowMarkerAbsolute=t_.arrowMarkerAbsolute),t_.gitGraph&&(t_.gitGraph.arrowMarkerAbsolute=t_.arrowMarkerAbsolute);const e_=(t,e="")=>Object.keys(t).reduce(((n,i)=>Array.isArray(t[i])?n:"object"==typeof t[i]&&null!==t[i]?[...n,e+i,...e_(t[i],"")]:[...n,e+i]),[]),n_=e_(t_,""),i_=t_;function r_(t){return null==t}var a_=function(t,e){var n,i="";for(n=0;n<e;n+=1)i+=t;return i},s_=function(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t},o_={isNothing:r_,isObject:function(t){return"object"==typeof t&&null!==t},toArray:function(t){return Array.isArray(t)?t:r_(t)?[]:[t]},repeat:a_,isNegativeZero:s_,extend:function(t,e){var n,i,r,a;if(e)for(n=0,i=(a=Object.keys(e)).length;n<i;n+=1)t[r=a[n]]=e[r];return t}};function c_(t,e){var n="",i=t.reason||"(unknown reason)";return t.mark?(t.mark.name&&(n+='in "'+t.mark.name+'" '),n+="("+(t.mark.line+1)+":"+(t.mark.column+1)+")",!e&&t.mark.snippet&&(n+="\n\n"+t.mark.snippet),i+" "+n):i}function l_(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=c_(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}l_.prototype=Object.create(Error.prototype),l_.prototype.constructor=l_,l_.prototype.toString=function(t){return this.name+": "+c_(this,t)};var h_=l_;function u_(t,e,n,i,r){var a="",s="",o=Math.floor(r/2)-1;return i-e>o&&(e=i-o+(a=" ... ").length),n-i>o&&(n=i+o-(s=" ...").length),{str:a+t.slice(e,n).replace(/\t/g,"\u2192")+s,pos:i-e+a.length}}function d_(t,e){return o_.repeat(" ",e-t.length)+t}var p_=function(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var n,i=/\r?\n|\r|\0/g,r=[0],a=[],s=-1;n=i.exec(t.buffer);)a.push(n.index),r.push(n.index+n[0].length),t.position<=n.index&&s<0&&(s=r.length-2);s<0&&(s=r.length-1);var o,c,l="",h=Math.min(t.line+e.linesAfter,a.length).toString().length,u=e.maxLength-(e.indent+h+3);for(o=1;o<=e.linesBefore&&!(s-o<0);o++)c=u_(t.buffer,r[s-o],a[s-o],t.position-(r[s]-r[s-o]),u),l=o_.repeat(" ",e.indent)+d_((t.line-o+1).toString(),h)+" | "+c.str+"\n"+l;for(c=u_(t.buffer,r[s],a[s],t.position,u),l+=o_.repeat(" ",e.indent)+d_((t.line+1).toString(),h)+" | "+c.str+"\n",l+=o_.repeat("-",e.indent+h+3+c.pos)+"^\n",o=1;o<=e.linesAfter&&!(s+o>=a.length);o++)c=u_(t.buffer,r[s+o],a[s+o],t.position-(r[s]-r[s+o]),u),l+=o_.repeat(" ",e.indent)+d_((t.line+o+1).toString(),h)+" | "+c.str+"\n";return l.replace(/\n$/,"")},f_=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],g_=["scalar","sequence","mapping"];var y_=function(t,e){var n,i;if(e=e||{},Object.keys(e).forEach((function(e){if(-1===f_.indexOf(e))throw new h_('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=(n=e.styleAliases||null,i={},null!==n&&Object.keys(n).forEach((function(t){n[t].forEach((function(e){i[String(e)]=t}))})),i),-1===g_.indexOf(this.kind))throw new h_('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')};function m_(t,e){var n=[];return t[e].forEach((function(t){var e=n.length;n.forEach((function(n,i){n.tag===t.tag&&n.kind===t.kind&&n.multi===t.multi&&(e=i)})),n[e]=t})),n}function b_(t){return this.extend(t)}b_.prototype.extend=function(t){var e=[],n=[];if(t instanceof y_)n.push(t);else if(Array.isArray(t))n=n.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new h_("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(n=n.concat(t.explicit))}e.forEach((function(t){if(!(t instanceof y_))throw new h_("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new h_("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new h_("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),n.forEach((function(t){if(!(t instanceof y_))throw new h_("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var i=Object.create(b_.prototype);return i.implicit=(this.implicit||[]).concat(e),i.explicit=(this.explicit||[]).concat(n),i.compiledImplicit=m_(i,"implicit"),i.compiledExplicit=m_(i,"explicit"),i.compiledTypeMap=function(){var t,e,n={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function i(t){t.multi?(n.multi[t.kind].push(t),n.multi.fallback.push(t)):n[t.kind][t.tag]=n.fallback[t.tag]=t}for(t=0,e=arguments.length;t<e;t+=1)arguments[t].forEach(i);return n}(i.compiledImplicit,i.compiledExplicit),i};var __=b_,x_=new y_("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return null!==t?t:""}}),v_=new y_("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return null!==t?t:[]}}),k_=new y_("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return null!==t?t:{}}}),w_=new __({explicit:[x_,v_,k_]});var T_=new y_("tag:yaml.org,2002:null",{kind:"scalar",resolve:function(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)},construct:function(){return null},predicate:function(t){return null===t},represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"},empty:function(){return""}},defaultStyle:"lowercase"});var C_=new y_("tag:yaml.org,2002:bool",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)},construct:function(t){return"true"===t||"True"===t||"TRUE"===t},predicate:function(t){return"[object Boolean]"===Object.prototype.toString.call(t)},represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"});function E_(t){return 48<=t&&t<=55}function S_(t){return 48<=t&&t<=57}var A_=new y_("tag:yaml.org,2002:int",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,n,i=t.length,r=0,a=!1;if(!i)return!1;if("-"!==(e=t[r])&&"+"!==e||(e=t[++r]),"0"===e){if(r+1===i)return!0;if("b"===(e=t[++r])){for(r++;r<i;r++)if("_"!==(e=t[r])){if("0"!==e&&"1"!==e)return!1;a=!0}return a&&"_"!==e}if("x"===e){for(r++;r<i;r++)if("_"!==(e=t[r])){if(!(48<=(n=t.charCodeAt(r))&&n<=57||65<=n&&n<=70||97<=n&&n<=102))return!1;a=!0}return a&&"_"!==e}if("o"===e){for(r++;r<i;r++)if("_"!==(e=t[r])){if(!E_(t.charCodeAt(r)))return!1;a=!0}return a&&"_"!==e}}if("_"===e)return!1;for(;r<i;r++)if("_"!==(e=t[r])){if(!S_(t.charCodeAt(r)))return!1;a=!0}return!(!a||"_"===e)},construct:function(t){var e,n=t,i=1;if(-1!==n.indexOf("_")&&(n=n.replace(/_/g,"")),"-"!==(e=n[0])&&"+"!==e||("-"===e&&(i=-1),e=(n=n.slice(1))[0]),"0"===n)return 0;if("0"===e){if("b"===n[1])return i*parseInt(n.slice(2),2);if("x"===n[1])return i*parseInt(n.slice(2),16);if("o"===n[1])return i*parseInt(n.slice(2),8)}return i*parseInt(n,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&t%1==0&&!o_.isNegativeZero(t)},represent:{binary:function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),D_=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");var L_=/^[-+]?[0-9]+e/;var N_=new y_("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(t){return null!==t&&!(!D_.test(t)||"_"===t[t.length-1])},construct:function(t){var e,n;return n="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===n?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:n*parseFloat(e,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||o_.isNegativeZero(t))},represent:function(t,e){var n;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(o_.isNegativeZero(t))return"-0.0";return n=t.toString(10),L_.test(n)?n.replace("e",".e"):n},defaultStyle:"lowercase"}),O_=w_.extend({implicit:[T_,C_,A_,N_]}),B_=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),M_=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");var I_=new y_("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(t){return null!==t&&(null!==B_.exec(t)||null!==M_.exec(t))},construct:function(t){var e,n,i,r,a,s,o,c,l=0,h=null;if(null===(e=B_.exec(t))&&(e=M_.exec(t)),null===e)throw new Error("Date resolve error");if(n=+e[1],i=+e[2]-1,r=+e[3],!e[4])return new Date(Date.UTC(n,i,r));if(a=+e[4],s=+e[5],o=+e[6],e[7]){for(l=e[7].slice(0,3);l.length<3;)l+="0";l=+l}return e[9]&&(h=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(h=-h)),c=new Date(Date.UTC(n,i,r,a,s,o,l)),h&&c.setTime(c.getTime()-h),c},instanceOf:Date,represent:function(t){return t.toISOString()}});var F_=new y_("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(t){return"<<"===t||null===t}}),R_="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";var $_=new y_("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,n,i=0,r=t.length,a=R_;for(n=0;n<r;n++)if(!((e=a.indexOf(t.charAt(n)))>64)){if(e<0)return!1;i+=6}return i%8==0},construct:function(t){var e,n,i=t.replace(/[\r\n=]/g,""),r=i.length,a=R_,s=0,o=[];for(e=0;e<r;e++)e%4==0&&e&&(o.push(s>>16&255),o.push(s>>8&255),o.push(255&s)),s=s<<6|a.indexOf(i.charAt(e));return 0===(n=r%4*6)?(o.push(s>>16&255),o.push(s>>8&255),o.push(255&s)):18===n?(o.push(s>>10&255),o.push(s>>2&255)):12===n&&o.push(s>>4&255),new Uint8Array(o)},predicate:function(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)},represent:function(t){var e,n,i="",r=0,a=t.length,s=R_;for(e=0;e<a;e++)e%3==0&&e&&(i+=s[r>>18&63],i+=s[r>>12&63],i+=s[r>>6&63],i+=s[63&r]),r=(r<<8)+t[e];return 0===(n=a%3)?(i+=s[r>>18&63],i+=s[r>>12&63],i+=s[r>>6&63],i+=s[63&r]):2===n?(i+=s[r>>10&63],i+=s[r>>4&63],i+=s[r<<2&63],i+=s[64]):1===n&&(i+=s[r>>2&63],i+=s[r<<4&63],i+=s[64],i+=s[64]),i}}),P_=Object.prototype.hasOwnProperty,j_=Object.prototype.toString;var Y_=new y_("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,n,i,r,a,s=[],o=t;for(e=0,n=o.length;e<n;e+=1){if(i=o[e],a=!1,"[object Object]"!==j_.call(i))return!1;for(r in i)if(P_.call(i,r)){if(a)return!1;a=!0}if(!a)return!1;if(-1!==s.indexOf(r))return!1;s.push(r)}return!0},construct:function(t){return null!==t?t:[]}}),z_=Object.prototype.toString;var U_=new y_("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,n,i,r,a,s=t;for(a=new Array(s.length),e=0,n=s.length;e<n;e+=1){if(i=s[e],"[object Object]"!==z_.call(i))return!1;if(1!==(r=Object.keys(i)).length)return!1;a[e]=[r[0],i[r[0]]]}return!0},construct:function(t){if(null===t)return[];var e,n,i,r,a,s=t;for(a=new Array(s.length),e=0,n=s.length;e<n;e+=1)i=s[e],r=Object.keys(i),a[e]=[r[0],i[r[0]]];return a}}),W_=Object.prototype.hasOwnProperty;var H_=new y_("tag:yaml.org,2002:set",{kind:"mapping",resolve:function(t){if(null===t)return!0;var e,n=t;for(e in n)if(W_.call(n,e)&&null!==n[e])return!1;return!0},construct:function(t){return null!==t?t:{}}}),q_=O_.extend({implicit:[I_,F_],explicit:[$_,Y_,U_,H_]}),V_=Object.prototype.hasOwnProperty,G_=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,X_=/[\x85\u2028\u2029]/,Z_=/[,\[\]\{\}]/,Q_=/^(?:!|!!|![a-z\-]+!)$/i,K_=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function J_(t){return Object.prototype.toString.call(t)}function tx(t){return 10===t||13===t}function ex(t){return 9===t||32===t}function nx(t){return 9===t||32===t||10===t||13===t}function ix(t){return 44===t||91===t||93===t||123===t||125===t}function rx(t){var e;return 48<=t&&t<=57?t-48:97<=(e=32|t)&&e<=102?e-97+10:-1}function ax(t){return 48===t?"\0":97===t?"\x07":98===t?"\b":116===t||9===t?"\t":110===t?"\n":118===t?"\v":102===t?"\f":114===t?"\r":101===t?"\x1b":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"\x85":95===t?"\xa0":76===t?"\u2028":80===t?"\u2029":""}function sx(t){return t<=65535?String.fromCharCode(t):String.fromCharCode(55296+(t-65536>>10),56320+(t-65536&1023))}for(var ox=new Array(256),cx=new Array(256),lx=0;lx<256;lx++)ox[lx]=ax(lx)?1:0,cx[lx]=ax(lx);function hx(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||q_,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function ux(t,e){var n={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return n.snippet=p_(n),new h_(e,n)}function dx(t,e){throw ux(t,e)}function px(t,e){t.onWarning&&t.onWarning.call(null,ux(t,e))}var fx={YAML:function(t,e,n){var i,r,a;null!==t.version&&dx(t,"duplication of %YAML directive"),1!==n.length&&dx(t,"YAML directive accepts exactly one argument"),null===(i=/^([0-9]+)\.([0-9]+)$/.exec(n[0]))&&dx(t,"ill-formed argument of the YAML directive"),r=parseInt(i[1],10),a=parseInt(i[2],10),1!==r&&dx(t,"unacceptable YAML version of the document"),t.version=n[0],t.checkLineBreaks=a<2,1!==a&&2!==a&&px(t,"unsupported YAML version of the document")},TAG:function(t,e,n){var i,r;2!==n.length&&dx(t,"TAG directive accepts exactly two arguments"),i=n[0],r=n[1],Q_.test(i)||dx(t,"ill-formed tag handle (first argument) of the TAG directive"),V_.call(t.tagMap,i)&&dx(t,'there is a previously declared suffix for "'+i+'" tag handle'),K_.test(r)||dx(t,"ill-formed tag prefix (second argument) of the TAG directive");try{r=decodeURIComponent(r)}catch(a){dx(t,"tag prefix is malformed: "+r)}t.tagMap[i]=r}};function gx(t,e,n,i){var r,a,s,o;if(e<n){if(o=t.input.slice(e,n),i)for(r=0,a=o.length;r<a;r+=1)9===(s=o.charCodeAt(r))||32<=s&&s<=1114111||dx(t,"expected valid JSON character");else G_.test(o)&&dx(t,"the stream contains non-printable characters");t.result+=o}}function yx(t,e,n,i){var r,a,s,o;for(o_.isObject(n)||dx(t,"cannot merge mappings; the provided source object is unacceptable"),s=0,o=(r=Object.keys(n)).length;s<o;s+=1)a=r[s],V_.call(e,a)||(e[a]=n[a],i[a]=!0)}function mx(t,e,n,i,r,a,s,o,c){var l,h;if(Array.isArray(r))for(l=0,h=(r=Array.prototype.slice.call(r)).length;l<h;l+=1)Array.isArray(r[l])&&dx(t,"nested arrays are not supported inside keys"),"object"==typeof r&&"[object Object]"===J_(r[l])&&(r[l]="[object Object]");if("object"==typeof r&&"[object Object]"===J_(r)&&(r="[object Object]"),r=String(r),null===e&&(e={}),"tag:yaml.org,2002:merge"===i)if(Array.isArray(a))for(l=0,h=a.length;l<h;l+=1)yx(t,e,a[l],n);else yx(t,e,a,n);else t.json||V_.call(n,r)||!V_.call(e,r)||(t.line=s||t.line,t.lineStart=o||t.lineStart,t.position=c||t.position,dx(t,"duplicated mapping key")),"__proto__"===r?Object.defineProperty(e,r,{configurable:!0,enumerable:!0,writable:!0,value:a}):e[r]=a,delete n[r];return e}function bx(t){var e;10===(e=t.input.charCodeAt(t.position))?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):dx(t,"a line break is expected"),t.line+=1,t.lineStart=t.position,t.firstTabInLine=-1}function _x(t,e,n){for(var i=0,r=t.input.charCodeAt(t.position);0!==r;){for(;ex(r);)9===r&&-1===t.firstTabInLine&&(t.firstTabInLine=t.position),r=t.input.charCodeAt(++t.position);if(e&&35===r)do{r=t.input.charCodeAt(++t.position)}while(10!==r&&13!==r&&0!==r);if(!tx(r))break;for(bx(t),r=t.input.charCodeAt(t.position),i++,t.lineIndent=0;32===r;)t.lineIndent++,r=t.input.charCodeAt(++t.position)}return-1!==n&&0!==i&&t.lineIndent<n&&px(t,"deficient indentation"),i}function xx(t){var e,n=t.position;return!(45!==(e=t.input.charCodeAt(n))&&46!==e||e!==t.input.charCodeAt(n+1)||e!==t.input.charCodeAt(n+2)||(n+=3,0!==(e=t.input.charCodeAt(n))&&!nx(e)))}function vx(t,e){1===e?t.result+=" ":e>1&&(t.result+=o_.repeat("\n",e-1))}function kx(t,e){var n,i,r=t.tag,a=t.anchor,s=[],o=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=s),i=t.input.charCodeAt(t.position);0!==i&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,dx(t,"tab characters must not be used in indentation")),45===i)&&nx(t.input.charCodeAt(t.position+1));)if(o=!0,t.position++,_x(t,!0,-1)&&t.lineIndent<=e)s.push(null),i=t.input.charCodeAt(t.position);else if(n=t.line,Cx(t,e,3,!1,!0),s.push(t.result),_x(t,!0,-1),i=t.input.charCodeAt(t.position),(t.line===n||t.lineIndent>e)&&0!==i)dx(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return!!o&&(t.tag=r,t.anchor=a,t.kind="sequence",t.result=s,!0)}function wx(t){var e,n,i,r,a=!1,s=!1;if(33!==(r=t.input.charCodeAt(t.position)))return!1;if(null!==t.tag&&dx(t,"duplication of a tag property"),60===(r=t.input.charCodeAt(++t.position))?(a=!0,r=t.input.charCodeAt(++t.position)):33===r?(s=!0,n="!!",r=t.input.charCodeAt(++t.position)):n="!",e=t.position,a){do{r=t.input.charCodeAt(++t.position)}while(0!==r&&62!==r);t.position<t.length?(i=t.input.slice(e,t.position),r=t.input.charCodeAt(++t.position)):dx(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==r&&!nx(r);)33===r&&(s?dx(t,"tag suffix cannot contain exclamation marks"):(n=t.input.slice(e-1,t.position+1),Q_.test(n)||dx(t,"named tag handle cannot contain such characters"),s=!0,e=t.position+1)),r=t.input.charCodeAt(++t.position);i=t.input.slice(e,t.position),Z_.test(i)&&dx(t,"tag suffix cannot contain flow indicator characters")}i&&!K_.test(i)&&dx(t,"tag name cannot contain such characters: "+i);try{i=decodeURIComponent(i)}catch(o){dx(t,"tag name is malformed: "+i)}return a?t.tag=i:V_.call(t.tagMap,n)?t.tag=t.tagMap[n]+i:"!"===n?t.tag="!"+i:"!!"===n?t.tag="tag:yaml.org,2002:"+i:dx(t,'undeclared tag handle "'+n+'"'),!0}function Tx(t){var e,n;if(38!==(n=t.input.charCodeAt(t.position)))return!1;for(null!==t.anchor&&dx(t,"duplication of an anchor property"),n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!nx(n)&&!ix(n);)n=t.input.charCodeAt(++t.position);return t.position===e&&dx(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function Cx(t,e,n,i,r){var a,s,o,c,l,h,u,d,p,f=1,g=!1,y=!1;if(null!==t.listener&&t.listener("open",t),t.tag=null,t.anchor=null,t.kind=null,t.result=null,a=s=o=4===n||3===n,i&&_x(t,!0,-1)&&(g=!0,t.lineIndent>e?f=1:t.lineIndent===e?f=0:t.lineIndent<e&&(f=-1)),1===f)for(;wx(t)||Tx(t);)_x(t,!0,-1)?(g=!0,o=a,t.lineIndent>e?f=1:t.lineIndent===e?f=0:t.lineIndent<e&&(f=-1)):o=!1;if(o&&(o=g||r),1!==f&&4!==n||(d=1===n||2===n?e:e+1,p=t.position-t.lineStart,1===f?o&&(kx(t,p)||function(t,e,n){var i,r,a,s,o,c,l,h=t.tag,u=t.anchor,d={},p=Object.create(null),f=null,g=null,y=null,m=!1,b=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=d),l=t.input.charCodeAt(t.position);0!==l;){if(m||-1===t.firstTabInLine||(t.position=t.firstTabInLine,dx(t,"tab characters must not be used in indentation")),i=t.input.charCodeAt(t.position+1),a=t.line,63!==l&&58!==l||!nx(i)){if(s=t.line,o=t.lineStart,c=t.position,!Cx(t,n,2,!1,!0))break;if(t.line===a){for(l=t.input.charCodeAt(t.position);ex(l);)l=t.input.charCodeAt(++t.position);if(58===l)nx(l=t.input.charCodeAt(++t.position))||dx(t,"a whitespace character is expected after the key-value separator within a block mapping"),m&&(mx(t,d,p,f,g,null,s,o,c),f=g=y=null),b=!0,m=!1,r=!1,f=t.tag,g=t.result;else{if(!b)return t.tag=h,t.anchor=u,!0;dx(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!b)return t.tag=h,t.anchor=u,!0;dx(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===l?(m&&(mx(t,d,p,f,g,null,s,o,c),f=g=y=null),b=!0,m=!0,r=!0):m?(m=!1,r=!0):dx(t,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),t.position+=1,l=i;if((t.line===a||t.lineIndent>e)&&(m&&(s=t.line,o=t.lineStart,c=t.position),Cx(t,e,4,!0,r)&&(m?g=t.result:y=t.result),m||(mx(t,d,p,f,g,y,s,o,c),f=g=y=null),_x(t,!0,-1),l=t.input.charCodeAt(t.position)),(t.line===a||t.lineIndent>e)&&0!==l)dx(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return m&&mx(t,d,p,f,g,null,s,o,c),b&&(t.tag=h,t.anchor=u,t.kind="mapping",t.result=d),b}(t,p,d))||function(t,e){var n,i,r,a,s,o,c,l,h,u,d,p,f=!0,g=t.tag,y=t.anchor,m=Object.create(null);if(91===(p=t.input.charCodeAt(t.position)))s=93,l=!1,a=[];else{if(123!==p)return!1;s=125,l=!0,a={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),p=t.input.charCodeAt(++t.position);0!==p;){if(_x(t,!0,e),(p=t.input.charCodeAt(t.position))===s)return t.position++,t.tag=g,t.anchor=y,t.kind=l?"mapping":"sequence",t.result=a,!0;f?44===p&&dx(t,"expected the node content, but found ','"):dx(t,"missed comma between flow collection entries"),d=null,o=c=!1,63===p&&nx(t.input.charCodeAt(t.position+1))&&(o=c=!0,t.position++,_x(t,!0,e)),n=t.line,i=t.lineStart,r=t.position,Cx(t,e,1,!1,!0),u=t.tag,h=t.result,_x(t,!0,e),p=t.input.charCodeAt(t.position),!c&&t.line!==n||58!==p||(o=!0,p=t.input.charCodeAt(++t.position),_x(t,!0,e),Cx(t,e,1,!1,!0),d=t.result),l?mx(t,a,m,u,h,d,n,i,r):o?a.push(mx(t,null,m,u,h,d,n,i,r)):a.push(h),_x(t,!0,e),44===(p=t.input.charCodeAt(t.position))?(f=!0,p=t.input.charCodeAt(++t.position)):f=!1}dx(t,"unexpected end of the stream within a flow collection")}(t,d)?y=!0:(s&&function(t,e){var n,i,r,a,s,o=1,c=!1,l=!1,h=e,u=0,d=!1;if(124===(a=t.input.charCodeAt(t.position)))i=!1;else{if(62!==a)return!1;i=!0}for(t.kind="scalar",t.result="";0!==a;)if(43===(a=t.input.charCodeAt(++t.position))||45===a)1===o?o=43===a?3:2:dx(t,"repeat of a chomping mode identifier");else{if(!((r=48<=(s=a)&&s<=57?s-48:-1)>=0))break;0===r?dx(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):l?dx(t,"repeat of an indentation width identifier"):(h=e+r-1,l=!0)}if(ex(a)){do{a=t.input.charCodeAt(++t.position)}while(ex(a));if(35===a)do{a=t.input.charCodeAt(++t.position)}while(!tx(a)&&0!==a)}for(;0!==a;){for(bx(t),t.lineIndent=0,a=t.input.charCodeAt(t.position);(!l||t.lineIndent<h)&&32===a;)t.lineIndent++,a=t.input.charCodeAt(++t.position);if(!l&&t.lineIndent>h&&(h=t.lineIndent),tx(a))u++;else{if(t.lineIndent<h){3===o?t.result+=o_.repeat("\n",c?1+u:u):1===o&&c&&(t.result+="\n");break}for(i?ex(a)?(d=!0,t.result+=o_.repeat("\n",c?1+u:u)):d?(d=!1,t.result+=o_.repeat("\n",u+1)):0===u?c&&(t.result+=" "):t.result+=o_.repeat("\n",u):t.result+=o_.repeat("\n",c?1+u:u),c=!0,l=!0,u=0,n=t.position;!tx(a)&&0!==a;)a=t.input.charCodeAt(++t.position);gx(t,n,t.position,!1)}}return!0}(t,d)||function(t,e){var n,i,r;if(39!==(n=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,i=r=t.position;0!==(n=t.input.charCodeAt(t.position));)if(39===n){if(gx(t,i,t.position,!0),39!==(n=t.input.charCodeAt(++t.position)))return!0;i=t.position,t.position++,r=t.position}else tx(n)?(gx(t,i,r,!0),vx(t,_x(t,!1,e)),i=r=t.position):t.position===t.lineStart&&xx(t)?dx(t,"unexpected end of the document within a single quoted scalar"):(t.position++,r=t.position);dx(t,"unexpected end of the stream within a single quoted scalar")}(t,d)||function(t,e){var n,i,r,a,s,o,c;if(34!==(o=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,n=i=t.position;0!==(o=t.input.charCodeAt(t.position));){if(34===o)return gx(t,n,t.position,!0),t.position++,!0;if(92===o){if(gx(t,n,t.position,!0),tx(o=t.input.charCodeAt(++t.position)))_x(t,!1,e);else if(o<256&&ox[o])t.result+=cx[o],t.position++;else if((s=120===(c=o)?2:117===c?4:85===c?8:0)>0){for(r=s,a=0;r>0;r--)(s=rx(o=t.input.charCodeAt(++t.position)))>=0?a=(a<<4)+s:dx(t,"expected hexadecimal character");t.result+=sx(a),t.position++}else dx(t,"unknown escape sequence");n=i=t.position}else tx(o)?(gx(t,n,i,!0),vx(t,_x(t,!1,e)),n=i=t.position):t.position===t.lineStart&&xx(t)?dx(t,"unexpected end of the document within a double quoted scalar"):(t.position++,i=t.position)}dx(t,"unexpected end of the stream within a double quoted scalar")}(t,d)?y=!0:!function(t){var e,n,i;if(42!==(i=t.input.charCodeAt(t.position)))return!1;for(i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!nx(i)&&!ix(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&dx(t,"name of an alias node must contain at least one character"),n=t.input.slice(e,t.position),V_.call(t.anchorMap,n)||dx(t,'unidentified alias "'+n+'"'),t.result=t.anchorMap[n],_x(t,!0,-1),!0}(t)?function(t,e,n){var i,r,a,s,o,c,l,h,u=t.kind,d=t.result;if(nx(h=t.input.charCodeAt(t.position))||ix(h)||35===h||38===h||42===h||33===h||124===h||62===h||39===h||34===h||37===h||64===h||96===h)return!1;if((63===h||45===h)&&(nx(i=t.input.charCodeAt(t.position+1))||n&&ix(i)))return!1;for(t.kind="scalar",t.result="",r=a=t.position,s=!1;0!==h;){if(58===h){if(nx(i=t.input.charCodeAt(t.position+1))||n&&ix(i))break}else if(35===h){if(nx(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&xx(t)||n&&ix(h))break;if(tx(h)){if(o=t.line,c=t.lineStart,l=t.lineIndent,_x(t,!1,-1),t.lineIndent>=e){s=!0,h=t.input.charCodeAt(t.position);continue}t.position=a,t.line=o,t.lineStart=c,t.lineIndent=l;break}}s&&(gx(t,r,a,!1),vx(t,t.line-o),r=a=t.position,s=!1),ex(h)||(a=t.position+1),h=t.input.charCodeAt(++t.position)}return gx(t,r,a,!1),!!t.result||(t.kind=u,t.result=d,!1)}(t,d,1===n)&&(y=!0,null===t.tag&&(t.tag="?")):(y=!0,null===t.tag&&null===t.anchor||dx(t,"alias node should not have any properties")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===f&&(y=o&&kx(t,p))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&dx(t,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+t.kind+'"'),c=0,l=t.implicitTypes.length;c<l;c+=1)if((u=t.implicitTypes[c]).resolve(t.result)){t.result=u.construct(t.result),t.tag=u.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else if("!"!==t.tag){if(V_.call(t.typeMap[t.kind||"fallback"],t.tag))u=t.typeMap[t.kind||"fallback"][t.tag];else for(u=null,c=0,l=(h=t.typeMap.multi[t.kind||"fallback"]).length;c<l;c+=1)if(t.tag.slice(0,h[c].tag.length)===h[c].tag){u=h[c];break}u||dx(t,"unknown tag !<"+t.tag+">"),null!==t.result&&u.kind!==t.kind&&dx(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):dx(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||y}function Ex(t){var e,n,i,r,a=t.position,s=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(r=t.input.charCodeAt(t.position))&&(_x(t,!0,-1),r=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==r));){for(s=!0,r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!nx(r);)r=t.input.charCodeAt(++t.position);for(i=[],(n=t.input.slice(e,t.position)).length<1&&dx(t,"directive name must not be less than one character in length");0!==r;){for(;ex(r);)r=t.input.charCodeAt(++t.position);if(35===r){do{r=t.input.charCodeAt(++t.position)}while(0!==r&&!tx(r));break}if(tx(r))break;for(e=t.position;0!==r&&!nx(r);)r=t.input.charCodeAt(++t.position);i.push(t.input.slice(e,t.position))}0!==r&&bx(t),V_.call(fx,n)?fx[n](t,n,i):px(t,'unknown document directive "'+n+'"')}_x(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,_x(t,!0,-1)):s&&dx(t,"directives end mark is expected"),Cx(t,t.lineIndent-1,4,!1,!0),_x(t,!0,-1),t.checkLineBreaks&&X_.test(t.input.slice(a,t.position))&&px(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&xx(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,_x(t,!0,-1)):t.position<t.length-1&&dx(t,"end of the stream or a document separator is expected")}function Sx(t,e){e=e||{},0!==(t=String(t)).length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var n=new hx(t,e),i=t.indexOf("\0");for(-1!==i&&(n.position=i,dx(n,"null byte is not allowed in input")),n.input+="\0";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.position<n.length-1;)Ex(n);return n.documents}var Ax=w_,Dx={loadAll:function(t,e,n){null!==e&&"object"==typeof e&&void 0===n&&(n=e,e=null);var i=Sx(t,n);if("function"!=typeof e)return i;for(var r=0,a=i.length;r<a;r+=1)e(i[r])},load:function(t,e){var n=Sx(t,e);if(0!==n.length){if(1===n.length)return n[0];throw new h_("expected a single document in the stream, but found more")}}}.load;const Lx=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s;const Nx=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,Ox=/\s*%%.*\n/gm,Bx={},Mx=function(t,e){t=t.replace(Lx,"").replace(Nx,"").replace(Ox,"\n");for(const[n,{detector:i}]of Object.entries(Bx)){if(i(t,e))return n}throw new Error(`No diagram type detected for text: ${t}`)},Ix=(t,e,n)=>{if(Bx[t])throw new Error(`Detector with key ${t} already exists`);Bx[t]={detector:e,loader:n},Bb.debug(`Detector with key ${t} added${n?" with loader":""}`)},Fx=function(t,e,n){const{depth:i,clobber:r}=Object.assign({depth:2,clobber:!1},n);return Array.isArray(e)&&!Array.isArray(t)?(e.forEach((e=>Fx(t,e,n))),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach((e=>{t.includes(e)||t.push(e)})),t):void 0===t||i<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach((n=>{"object"!=typeof e[n]||void 0!==t[n]&&"object"!=typeof t[n]?(r||"object"!=typeof t[n]&&"object"!=typeof e[n])&&(t[n]=e[n]):(void 0===t[n]&&(t[n]=Array.isArray(e[n])?[]:{}),t[n]=Fx(t[n],e[n],{depth:i-1,clobber:r}))})),t)},Rx=Fx,$x={curveBasis:Rc,curveBasisClosed:function(t){return new $c(t)},curveBasisOpen:function(t){return new Pc(t)},curveLinear:Ac,curveLinearClosed:function(t){return new jc(t)},curveMonotoneX:function(t){return new Hc(t)},curveMonotoneY:function(t){return new qc(t)},curveNatural:function(t){return new Gc(t)},curveStep:function(t){return new Zc(t,.5)},curveStepAfter:function(t){return new Zc(t,1)},curveStepBefore:function(t){return new Zc(t,0)}},Px=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,jx=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,Yx=function(t,e=null){try{const n=new RegExp(`[%]{2}(?![{]${jx.source})(?=[}][%]{2}).*\n`,"ig");let i;t=t.trim().replace(n,"").replace(/'/gm,'"'),Bb.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const r=[];for(;null!==(i=Px.exec(t));)if(i.index===Px.lastIndex&&Px.lastIndex++,i&&!e||e&&i[1]&&i[1].match(e)||e&&i[2]&&i[2].match(e)){const t=i[1]?i[1]:i[2],e=i[3]?i[3].trim():i[4]?JSON.parse(i[4].trim()):null;r.push({type:t,args:e})}return 0===r.length&&r.push({type:t,args:null}),1===r.length?r[0]:r}catch(n){return Bb.error(`ERROR: ${n.message} - Unable to parse directive\n ${null!==e?" type:"+e:""} based on the text:${t}`),{type:null,args:null}}};function zx(t,e){if(!t)return e;const n=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return $x[n]||e}function Ux(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}function Wx(t){let e="",n="";for(const i of t)void 0!==i&&(i.startsWith("color:")||i.startsWith("text-align:")?n=n+i+";":e=e+i+";");return{style:e,labelStyle:n}}let Hx=0;const qx=()=>(Hx++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Hx);const Vx=t=>function(t){let e="";const n="0123456789abcdef",i=n.length;for(let r=0;r<t;r++)e+=n.charAt(Math.floor(Math.random()*i));return e}(t.length),Gx=function(t,e){const n=e.text.replace(Wb.lineBreakRegex," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.style("text-anchor",e.anchor),i.style("font-family",e.fontFamily),i.style("font-size",e.fontSize),i.style("font-weight",e.fontWeight),i.attr("fill",e.fill),void 0!==e.class&&i.attr("class",e.class);const r=i.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.attr("fill",e.fill),r.text(n),i},Xx=Ih(((t,e,n)=>{if(!t)return t;if(n=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"<br/>"},n),Wb.lineBreakRegex.test(t))return t;const i=t.split(" "),r=[];let a="";return i.forEach(((t,s)=>{const o=Kx(`${t} `,n),c=Kx(a,n);if(o>e){const{hyphenatedStrings:i,remainingWord:s}=Zx(t,e,"-",n);r.push(a,...i),a=s}else c+o>=e?(r.push(a),a=t):a=[a,t].filter(Boolean).join(" ");s+1===i.length&&r.push(a)})),r.filter((t=>""!==t)).join(n.joinWith)}),((t,e,n)=>`${t}${e}${n.fontSize}${n.fontWeight}${n.fontFamily}${n.joinWith}`)),Zx=Ih(((t,e,n="-",i)=>{i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},i);const r=[...t],a=[];let s="";return r.forEach(((t,o)=>{const c=`${s}${t}`;if(Kx(c,i)>=e){const t=o+1,e=r.length===t,i=`${c}${n}`;a.push(e?c:i),s=""}else s=c})),{hyphenatedStrings:a,remainingWord:s}}),((t,e,n="-",i)=>`${t}${e}${n}${i.fontSize}${i.fontWeight}${i.fontFamily}`));function Qx(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:15},e),Jx(t,e).height}function Kx(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e),Jx(t,e).width}const Jx=Ih(((t,e)=>{e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e);const{fontSize:n,fontFamily:i,fontWeight:r}=e;if(!t)return{width:0,height:0};const a=["sans-serif",i],s=t.split(Wb.lineBreakRegex),o=[],c=Xo("body");if(!c.remove)return{width:0,height:0,lineHeight:0};const l=c.append("svg");for(const h of a){let t=0;const e={width:0,height:0,lineHeight:0};for(const i of s){const a={x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0};a.text=i;const s=Gx(l,a).style("font-size",n).style("font-weight",r).style("font-family",h),o=(s._groups||s)[0][0].getBBox();e.width=Math.round(Math.max(e.width,o.width)),t=Math.round(o.height),e.height+=t,e.lineHeight=Math.round(Math.max(e.lineHeight,t))}o.push(e)}l.remove();return o[isNaN(o[1].height)||isNaN(o[1].width)||isNaN(o[1].lineHeight)||o[0].height>o[1].height&&o[0].width>o[1].width&&o[0].lineHeight>o[1].lineHeight?0:1]}),((t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`));let tv;const ev=t=>{if(Bb.debug("directiveSanitizer called with",t),"object"==typeof t&&(t.length?t.forEach((t=>ev(t))):Object.keys(t).forEach((e=>{Bb.debug("Checking key",e),e.startsWith("__")&&(Bb.debug("sanitize deleting __ option",e),delete t[e]),e.includes("proto")&&(Bb.debug("sanitize deleting proto option",e),delete t[e]),e.includes("constr")&&(Bb.debug("sanitize deleting constr option",e),delete t[e]),e.includes("themeCSS")&&(Bb.debug("sanitizing themeCss option"),t[e]=nv(t[e])),e.includes("fontFamily")&&(Bb.debug("sanitizing fontFamily option"),t[e]=nv(t[e])),e.includes("altFontFamily")&&(Bb.debug("sanitizing altFontFamily option"),t[e]=nv(t[e])),n_.includes(e)?"object"==typeof t[e]&&(Bb.debug("sanitize deleting object",e),ev(t[e])):(Bb.debug("sanitize deleting option",e),delete t[e])}))),t.themeVariables){const e=Object.keys(t.themeVariables);for(const n of e){const e=t.themeVariables[n];e&&e.match&&!e.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[n]="")}}Bb.debug("After sanitization",t)},nv=t=>{let e=0,n=0;for(const i of t){if(e<n)return"{ /* ERROR: Unbalanced CSS */ }";"{"===i?e++:"}"===i&&n++}return e!==n?"{ /* ERROR: Unbalanced CSS */ }":t};function iv(t){return"str"in t}const rv={assignWithDepth:Rx,wrapLabel:Xx,calculateTextHeight:Qx,calculateTextWidth:Kx,calculateTextDimensions:Jx,detectInit:function(t,e){const n=Yx(t,/(?:init\b)|(?:initialize\b)/);let i={};if(Array.isArray(n)){const t=n.map((t=>t.args));ev(t),i=Rx(i,[...t])}else i=n.args;if(i){let n=Mx(t,e);["config"].forEach((t=>{void 0!==i[t]&&("flowchart-v2"===n&&(n="flowchart"),i[n]=i[t],delete i[t])}))}return i},detectDirective:Yx,isSubstringInArray:function(t,e){for(const[n,i]of e.entries())if(i.match(t))return n;return-1},interpolateToCurve:zx,calcLabelPosition:function(t){return 1===t.length?t[0]:function(t){let e,n=0;t.forEach((t=>{n+=Ux(t,e),e=t}));let i,r=n/2;return e=void 0,t.forEach((t=>{if(e&&!i){const n=Ux(t,e);if(n<r)r-=n;else{const a=r/n;a<=0&&(i=e),a>=1&&(i={x:t.x,y:t.y}),a>0&&a<1&&(i={x:(1-a)*e.x+a*t.x,y:(1-a)*e.y+a*t.y})}}e=t})),i}(t)},calcCardinalityPosition:(t,e,n)=>{let i;Bb.info(`our points ${JSON.stringify(e)}`),e[0]!==n&&(e=e.reverse());let r,a=25;i=void 0,e.forEach((t=>{if(i&&!r){const e=Ux(t,i);if(e<a)a-=e;else{const n=a/e;n<=0&&(r=i),n>=1&&(r={x:t.x,y:t.y}),n>0&&n<1&&(r={x:(1-n)*i.x+n*t.x,y:(1-n)*i.y+n*t.y})}}i=t}));const s=t?10:5,o=Math.atan2(e[0].y-r.y,e[0].x-r.x),c={x:0,y:0};return c.x=Math.sin(o)*s+(e[0].x+r.x)/2,c.y=-Math.cos(o)*s+(e[0].y+r.y)/2,c},calcTerminalLabelPosition:function(t,e,n){let i,r=JSON.parse(JSON.stringify(n));Bb.info("our points",r),"start_left"!==e&&"start_right"!==e&&(r=r.reverse()),r.forEach((t=>{i=t}));let a,s=25+t;i=void 0,r.forEach((t=>{if(i&&!a){const e=Ux(t,i);if(e<s)s-=e;else{const n=s/e;n<=0&&(a=i),n>=1&&(a={x:t.x,y:t.y}),n>0&&n<1&&(a={x:(1-n)*i.x+n*t.x,y:(1-n)*i.y+n*t.y})}}i=t}));const o=10+.5*t,c=Math.atan2(r[0].y-a.y,r[0].x-a.x),l={x:0,y:0};return l.x=Math.sin(c)*o+(r[0].x+a.x)/2,l.y=-Math.cos(c)*o+(r[0].y+a.y)/2,"start_left"===e&&(l.x=Math.sin(c+Math.PI)*o+(r[0].x+a.x)/2,l.y=-Math.cos(c+Math.PI)*o+(r[0].y+a.y)/2),"end_right"===e&&(l.x=Math.sin(c-Math.PI)*o+(r[0].x+a.x)/2-5,l.y=-Math.cos(c-Math.PI)*o+(r[0].y+a.y)/2-5),"end_left"===e&&(l.x=Math.sin(c)*o+(r[0].x+a.x)/2-5,l.y=-Math.cos(c)*o+(r[0].y+a.y)/2-5),l},formatUrl:function(t,e){const n=t.trim();if(n)return"loose"!==e.securityLevel?(0,Tt.N)(n):n},getStylesFromArray:Wx,generateId:qx,random:Vx,runFunc:(t,...e)=>{const n=t.split("."),i=n.length-1,r=n[i];let a=window;for(let s=0;s<i;s++)if(a=a[n[s]],!a)return;a[r](...e)},entityDecode:function(t){return tv=tv||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),tv.innerHTML=t,unescape(tv.textContent)},initIdGenerator:class{constructor(t,e){this.deterministic=t,this.seed=e,this.count=e?e.length:0}next(){return this.deterministic?this.count++:Date.now()}},directiveSanitizer:ev,sanitizeCss:nv,insertTitle:(t,e,n,i)=>{if(!i)return;const r=t.node().getBBox();t.append("text").text(i).attr("x",r.x+r.width/2).attr("y",-n).attr("class",e)}},av="9.3.0",sv=Object.freeze(i_);let ov,cv=Rx({},sv),lv=[],hv=Rx({},sv);const uv=(t,e)=>{let n=Rx({},t),i={};for(const r of e)gv(r),i=Rx(i,r);if(n=Rx(n,i),i.theme&&i.theme in Jb){const t=Rx({},ov),e=Rx(t.themeVariables||{},i.themeVariables);n.theme&&n.theme in Jb&&(n.themeVariables=Jb[n.theme].getThemeVariables(e))}return hv=n,xv(hv),hv},dv=()=>Rx({},cv),pv=t=>(xv(t),Rx(hv,t),fv()),fv=()=>Rx({},hv),gv=t=>{var e;["secure",...null!=(e=cv.secure)?e:[]].forEach((e=>{void 0!==t[e]&&(Bb.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])})),Object.keys(t).forEach((e=>{0===e.indexOf("__")&&delete t[e]})),Object.keys(t).forEach((e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&gv(t[e])}))},yv=t=>{t.fontFamily&&(t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily})),lv.push(t),uv(cv,lv)},mv=(t=cv)=>{lv=[],uv(t,lv)};var bv=(t=>(t.LAZY_LOAD_DEPRECATED="The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead.",t))(bv||{});const _v={},xv=t=>{var e;t&&((t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&(_v[e="LAZY_LOAD_DEPRECATED"]||(Bb.warn(bv[e]),_v[e]=!0)))},vv=function(t,e,n,i){const r=function(t,e,n){let i=new Map;return n?(i.set("width","100%"),i.set("style",`max-width: ${e}px;`)):(i.set("height",t),i.set("width",e)),i}(e,n,i);!function(t,e){for(let n of e)t.attr(n[0],n[1])}(t,r)},kv=function(t,e,n,i){const r=e.node().getBBox(),a=r.width,s=r.height;Bb.info(`SVG bounds: ${a}x${s}`,r);let o=0,c=0;Bb.info(`Graph bounds: ${o}x${c}`,t),o=a+2*n,c=s+2*n,Bb.info(`Calculated bounds: ${o}x${c}`),vv(e,c,o,i);const l=`${r.x-n} ${r.y-n} ${r.width+2*n} ${r.height+2*n}`;e.attr("viewBox",l)},wv=t=>`g.classGroup text {\n fill: ${t.nodeBorder};\n fill: ${t.classText};\n stroke: none;\n font-family: ${t.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${t.classText};\n}\n.edgeLabel .label rect {\n fill: ${t.mainBkg};\n}\n.label text {\n fill: ${t.classText};\n}\n.edgeLabel .label span {\n background: ${t.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${t.nodeBorder};\n stroke: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${t.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${t.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`,Tv=t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxOdd {\n fill: ${t.attributeBackgroundColorOdd};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxEven {\n fill: ${t.attributeBackgroundColorEven};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n }\n\n .entityTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n } \n`,Cv=()=>"",Ev=t=>`.label {\n font-family: ${t.fontFamily};\n color: ${t.nodeTextColor||t.textColor};\n }\n .cluster-label text {\n fill: ${t.titleColor};\n }\n .cluster-label span {\n color: ${t.titleColor};\n }\n\n .label text,span {\n fill: ${t.nodeTextColor||t.textColor};\n color: ${t.nodeTextColor||t.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ${t.clusterBkg};\n stroke: ${t.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n .cluster span {\n color: ${t.titleColor};\n }\n /* .cluster div {\n color: ${t.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${t.fontFamily};\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`,Sv=t=>`\n .mermaid-main-font {\n font-family: "trebuchet ms", verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n // text-height: 14px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n\n // .taskText:not([font-size]) {\n // font-size: ${t.ganttFontSize};\n // }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n // font-size: ${t.ganttFontSize};\n }\n\n /* Special case clickable */\n .task.clickable {\n cursor: pointer;\n }\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor} ;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n`,Av=()=>"",Dv=t=>`\n .pieCircle{\n stroke: ${t.pieStrokeColor};\n stroke-width : ${t.pieStrokeWidth};\n opacity : ${t.pieOpacity};\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${t.pieTitleTextSize};\n fill: ${t.pieTitleTextColor};\n font-family: ${t.fontFamily};\n }\n .slice {\n font-family: ${t.fontFamily};\n fill: ${t.pieSectionTextColor};\n font-size:${t.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${t.pieLegendTextColor};\n font-family: ${t.fontFamily};\n font-size: ${t.pieLegendTextSize};\n }\n`,Lv=t=>`\n\n marker {\n fill: ${t.relationColor};\n stroke: ${t.relationColor};\n }\n\n marker.cross {\n stroke: ${t.lineColor};\n }\n\n svg {\n font-family: ${t.fontFamily};\n font-size: ${t.fontSize};\n }\n\n .reqBox {\n fill: ${t.requirementBackground};\n fill-opacity: 100%;\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${t.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${t.relationLabelBackground};\n fill-opacity: 100%;\n }\n\n .req-title-line {\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${t.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${t.relationLabelColor};\n }\n\n`,Nv=t=>`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n`,Ov=t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`,Bv=t=>`.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n`,Mv=t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`,Iv={flowchart:Ev,"flowchart-v2":Ev,sequence:Nv,gantt:Sv,classDiagram:wv,"classDiagram-v2":wv,class:wv,stateDiagram:Ov,state:Ov,info:Av,pie:Dv,er:Tv,error:Cv,journey:Bv,requirement:Lv,c4:Mv},Fv=(t,e,n)=>{let i="";return t in Iv&&Iv[t]?i=Iv[t](n):Bb.warn(`No theme found for ${t}`),` & {\n font-family: ${n.fontFamily};\n font-size: ${n.fontSize};\n fill: ${n.textColor}\n }\n\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${n.errorBkgColor};\n }\n & .error-text {\n fill: ${n.errorTextColor};\n stroke: ${n.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 2px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${n.lineColor};\n stroke: ${n.lineColor};\n }\n & .marker.cross {\n stroke: ${n.lineColor};\n }\n\n & svg {\n font-family: ${n.fontFamily};\n font-size: ${n.fontSize};\n }\n\n ${i}\n\n ${e}\n`},Rv=Bb,$v=Mb,Pv=fv,jv=t=>$b(t,Pv()),Yv=kv,zv={},Uv=(t,e,n)=>{if(zv[t])throw new Error(`Diagram ${t} already registered.`);var i,r;zv[t]=e,n&&Ix(t,n),i=t,r=e.styles,Iv[i]=r,e.injectUtils&&e.injectUtils(Rv,$v,Pv,jv,Yv)},Wv=t=>{if(t in zv)return zv[t];throw new Error(`Diagram ${t} not found.`)};var Hv=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,4],i=[1,7],r=[1,5],a=[1,9],s=[1,6],o=[2,6],c=[1,16],l=[6,8,14,20,22,24,25,27,29,32,37,40,50,55],h=[8,14,20,22,24,25,27,29,32,37,40],u=[8,13,14,20,22,24,25,27,29,32,37,40],d=[1,26],p=[6,8,14,50,55],f=[8,14,55],g=[1,53],y=[1,52],m=[8,14,30,33,35,38,55],b=[1,67],_=[1,68],x=[1,69],v=[8,14,33,35,42,55],k={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,GG:6,document:7,EOF:8,":":9,DIR:10,options:11,body:12,OPT:13,NL:14,line:15,statement:16,commitStatement:17,mergeStatement:18,cherryPickStatement:19,acc_title:20,acc_title_value:21,acc_descr:22,acc_descr_value:23,acc_descr_multiline_value:24,section:25,branchStatement:26,CHECKOUT:27,ref:28,BRANCH:29,ORDER:30,NUM:31,CHERRY_PICK:32,COMMIT_ID:33,STR:34,COMMIT_TAG:35,EMPTYSTR:36,MERGE:37,COMMIT_TYPE:38,commitType:39,COMMIT:40,commit_arg:41,COMMIT_MSG:42,NORMAL:43,REVERSE:44,HIGHLIGHT:45,openDirective:46,typeDirective:47,closeDirective:48,argDirective:49,open_directive:50,type_directive:51,arg_directive:52,close_directive:53,ID:54,";":55,$accept:0,$end:1},terminals_:{2:"error",6:"GG",8:"EOF",9:":",10:"DIR",13:"OPT",14:"NL",20:"acc_title",21:"acc_title_value",22:"acc_descr",23:"acc_descr_value",24:"acc_descr_multiline_value",25:"section",27:"CHECKOUT",29:"BRANCH",30:"ORDER",31:"NUM",32:"CHERRY_PICK",33:"COMMIT_ID",34:"STR",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",50:"open_directive",51:"type_directive",52:"arg_directive",53:"close_directive",54:"ID",55:";"},productions_:[0,[3,2],[3,2],[3,3],[3,4],[3,5],[7,0],[7,2],[11,2],[11,1],[12,0],[12,2],[15,2],[15,1],[16,1],[16,1],[16,1],[16,2],[16,2],[16,1],[16,1],[16,1],[16,2],[26,2],[26,4],[19,3],[19,5],[19,5],[19,5],[19,5],[18,2],[18,4],[18,4],[18,4],[18,6],[18,6],[18,6],[18,6],[18,6],[18,6],[18,8],[18,8],[18,8],[18,8],[18,8],[18,8],[17,2],[17,3],[17,3],[17,5],[17,5],[17,3],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,3],[17,5],[17,5],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[41,0],[41,1],[39,1],[39,1],[39,1],[5,3],[5,5],[46,1],[47,1],[49,1],[48,1],[28,1],[28,1],[4,1],[4,1],[4,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 3:return a[o];case 4:return a[o-1];case 5:return i.setDirection(a[o-3]),a[o-1];case 7:i.setOptions(a[o-1]),this.$=a[o];break;case 8:a[o-1]+=a[o],this.$=a[o-1];break;case 10:this.$=[];break;case 11:a[o-1].push(a[o]),this.$=a[o-1];break;case 12:this.$=a[o-1];break;case 17:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 18:case 19:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 20:i.addSection(a[o].substr(8)),this.$=a[o].substr(8);break;case 22:i.checkout(a[o]);break;case 23:i.branch(a[o]);break;case 24:i.branch(a[o-2],a[o]);break;case 25:i.cherryPick(a[o],"",void 0);break;case 26:i.cherryPick(a[o-2],"",a[o]);break;case 27:case 29:i.cherryPick(a[o-2],"","");break;case 28:i.cherryPick(a[o],"",a[o-2]);break;case 30:i.merge(a[o],"","","");break;case 31:i.merge(a[o-2],a[o],"","");break;case 32:i.merge(a[o-2],"",a[o],"");break;case 33:i.merge(a[o-2],"","",a[o]);break;case 34:i.merge(a[o-4],a[o],"",a[o-2]);break;case 35:i.merge(a[o-4],"",a[o],a[o-2]);break;case 36:i.merge(a[o-4],"",a[o-2],a[o]);break;case 37:i.merge(a[o-4],a[o-2],a[o],"");break;case 38:i.merge(a[o-4],a[o-2],"",a[o]);break;case 39:i.merge(a[o-4],a[o],a[o-2],"");break;case 40:i.merge(a[o-6],a[o-4],a[o-2],a[o]);break;case 41:i.merge(a[o-6],a[o],a[o-4],a[o-2]);break;case 42:i.merge(a[o-6],a[o-4],a[o],a[o-2]);break;case 43:i.merge(a[o-6],a[o-2],a[o-4],a[o]);break;case 44:i.merge(a[o-6],a[o],a[o-2],a[o-4]);break;case 45:i.merge(a[o-6],a[o-2],a[o],a[o-4]);break;case 46:i.commit(a[o]);break;case 47:i.commit("","",i.commitType.NORMAL,a[o]);break;case 48:i.commit("","",a[o],"");break;case 49:i.commit("","",a[o],a[o-2]);break;case 50:i.commit("","",a[o-2],a[o]);break;case 51:i.commit("",a[o],i.commitType.NORMAL,"");break;case 52:i.commit("",a[o-2],i.commitType.NORMAL,a[o]);break;case 53:i.commit("",a[o],i.commitType.NORMAL,a[o-2]);break;case 54:i.commit("",a[o-2],a[o],"");break;case 55:i.commit("",a[o],a[o-2],"");break;case 56:i.commit("",a[o-4],a[o-2],a[o]);break;case 57:i.commit("",a[o-4],a[o],a[o-2]);break;case 58:i.commit("",a[o-2],a[o-4],a[o]);break;case 59:i.commit("",a[o],a[o-4],a[o-2]);break;case 60:i.commit("",a[o],a[o-2],a[o-4]);break;case 61:i.commit("",a[o-2],a[o],a[o-4]);break;case 62:i.commit(a[o],"",i.commitType.NORMAL,"");break;case 63:i.commit(a[o],"",i.commitType.NORMAL,a[o-2]);break;case 64:i.commit(a[o-2],"",i.commitType.NORMAL,a[o]);break;case 65:i.commit(a[o-2],"",a[o],"");break;case 66:i.commit(a[o],"",a[o-2],"");break;case 67:i.commit(a[o],a[o-2],i.commitType.NORMAL,"");break;case 68:i.commit(a[o-2],a[o],i.commitType.NORMAL,"");break;case 69:i.commit(a[o-4],"",a[o-2],a[o]);break;case 70:i.commit(a[o-4],"",a[o],a[o-2]);break;case 71:i.commit(a[o-2],"",a[o-4],a[o]);break;case 72:i.commit(a[o],"",a[o-4],a[o-2]);break;case 73:i.commit(a[o],"",a[o-2],a[o-4]);break;case 74:i.commit(a[o-2],"",a[o],a[o-4]);break;case 75:i.commit(a[o-4],a[o],a[o-2],"");break;case 76:i.commit(a[o-4],a[o-2],a[o],"");break;case 77:i.commit(a[o-2],a[o],a[o-4],"");break;case 78:i.commit(a[o],a[o-2],a[o-4],"");break;case 79:i.commit(a[o],a[o-4],a[o-2],"");break;case 80:i.commit(a[o-2],a[o-4],a[o],"");break;case 81:i.commit(a[o-4],a[o],i.commitType.NORMAL,a[o-2]);break;case 82:i.commit(a[o-4],a[o-2],i.commitType.NORMAL,a[o]);break;case 83:i.commit(a[o-2],a[o],i.commitType.NORMAL,a[o-4]);break;case 84:i.commit(a[o],a[o-2],i.commitType.NORMAL,a[o-4]);break;case 85:i.commit(a[o],a[o-4],i.commitType.NORMAL,a[o-2]);break;case 86:i.commit(a[o-2],a[o-4],i.commitType.NORMAL,a[o]);break;case 87:i.commit(a[o-6],a[o-4],a[o-2],a[o]);break;case 88:i.commit(a[o-6],a[o-4],a[o],a[o-2]);break;case 89:i.commit(a[o-6],a[o-2],a[o-4],a[o]);break;case 90:i.commit(a[o-6],a[o],a[o-4],a[o-2]);break;case 91:i.commit(a[o-6],a[o-2],a[o],a[o-4]);break;case 92:i.commit(a[o-6],a[o],a[o-2],a[o-4]);break;case 93:i.commit(a[o-4],a[o-6],a[o-2],a[o]);break;case 94:i.commit(a[o-4],a[o-6],a[o],a[o-2]);break;case 95:i.commit(a[o-2],a[o-6],a[o-4],a[o]);break;case 96:i.commit(a[o],a[o-6],a[o-4],a[o-2]);break;case 97:i.commit(a[o-2],a[o-6],a[o],a[o-4]);break;case 98:i.commit(a[o],a[o-6],a[o-2],a[o-4]);break;case 99:i.commit(a[o],a[o-4],a[o-2],a[o-6]);break;case 100:i.commit(a[o-2],a[o-4],a[o],a[o-6]);break;case 101:i.commit(a[o],a[o-2],a[o-4],a[o-6]);break;case 102:i.commit(a[o-2],a[o],a[o-4],a[o-6]);break;case 103:i.commit(a[o-4],a[o-2],a[o],a[o-6]);break;case 104:i.commit(a[o-4],a[o],a[o-2],a[o-6]);break;case 105:i.commit(a[o-2],a[o-4],a[o-6],a[o]);break;case 106:i.commit(a[o],a[o-4],a[o-6],a[o-2]);break;case 107:i.commit(a[o-2],a[o],a[o-6],a[o-4]);break;case 108:i.commit(a[o],a[o-2],a[o-6],a[o-4]);break;case 109:i.commit(a[o-4],a[o-2],a[o-6],a[o]);break;case 110:i.commit(a[o-4],a[o],a[o-6],a[o-2]);break;case 111:this.$="";break;case 112:this.$=a[o];break;case 113:this.$=i.commitType.NORMAL;break;case 114:this.$=i.commitType.REVERSE;break;case 115:this.$=i.commitType.HIGHLIGHT;break;case 118:i.parseDirective("%%{","open_directive");break;case 119:i.parseDirective(a[o],"type_directive");break;case 120:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 121:i.parseDirective("}%%","close_directive","gitGraph")}},table:[{3:1,4:2,5:3,6:n,8:i,14:r,46:8,50:a,55:s},{1:[3]},{3:10,4:2,5:3,6:n,8:i,14:r,46:8,50:a,55:s},{3:11,4:2,5:3,6:n,8:i,14:r,46:8,50:a,55:s},{7:12,8:o,9:[1,13],10:[1,14],11:15,14:c},e(l,[2,124]),e(l,[2,125]),e(l,[2,126]),{47:17,51:[1,18]},{51:[2,118]},{1:[2,1]},{1:[2,2]},{8:[1,19]},{7:20,8:o,11:15,14:c},{9:[1,21]},e(h,[2,10],{12:22,13:[1,23]}),e(u,[2,9]),{9:[1,25],48:24,53:d},e([9,53],[2,119]),{1:[2,3]},{8:[1,27]},{7:28,8:o,11:15,14:c},{8:[2,7],14:[1,31],15:29,16:30,17:32,18:33,19:34,20:[1,35],22:[1,36],24:[1,37],25:[1,38],26:39,27:[1,40],29:[1,44],32:[1,43],37:[1,42],40:[1,41]},e(u,[2,8]),e(p,[2,116]),{49:45,52:[1,46]},e(p,[2,121]),{1:[2,4]},{8:[1,47]},e(h,[2,11]),{4:48,8:i,14:r,55:s},e(h,[2,13]),e(f,[2,14]),e(f,[2,15]),e(f,[2,16]),{21:[1,49]},{23:[1,50]},e(f,[2,19]),e(f,[2,20]),e(f,[2,21]),{28:51,34:g,54:y},e(f,[2,111],{41:54,33:[1,57],34:[1,59],35:[1,55],38:[1,56],42:[1,58]}),{28:60,34:g,54:y},{33:[1,61],35:[1,62]},{28:63,34:g,54:y},{48:64,53:d},{53:[2,120]},{1:[2,5]},e(h,[2,12]),e(f,[2,17]),e(f,[2,18]),e(f,[2,22]),e(m,[2,122]),e(m,[2,123]),e(f,[2,46]),{34:[1,65]},{39:66,43:b,44:_,45:x},{34:[1,70]},{34:[1,71]},e(f,[2,112]),e(f,[2,30],{33:[1,72],35:[1,74],38:[1,73]}),{34:[1,75]},{34:[1,76],36:[1,77]},e(f,[2,23],{30:[1,78]}),e(p,[2,117]),e(f,[2,47],{33:[1,80],38:[1,79],42:[1,81]}),e(f,[2,48],{33:[1,83],35:[1,82],42:[1,84]}),e(v,[2,113]),e(v,[2,114]),e(v,[2,115]),e(f,[2,51],{35:[1,85],38:[1,86],42:[1,87]}),e(f,[2,62],{33:[1,90],35:[1,88],38:[1,89]}),{34:[1,91]},{39:92,43:b,44:_,45:x},{34:[1,93]},e(f,[2,25],{35:[1,94]}),{33:[1,95]},{33:[1,96]},{31:[1,97]},{39:98,43:b,44:_,45:x},{34:[1,99]},{34:[1,100]},{34:[1,101]},{34:[1,102]},{34:[1,103]},{34:[1,104]},{39:105,43:b,44:_,45:x},{34:[1,106]},{34:[1,107]},{39:108,43:b,44:_,45:x},{34:[1,109]},e(f,[2,31],{35:[1,111],38:[1,110]}),e(f,[2,32],{33:[1,113],35:[1,112]}),e(f,[2,33],{33:[1,114],38:[1,115]}),{34:[1,116],36:[1,117]},{34:[1,118]},{34:[1,119]},e(f,[2,24]),e(f,[2,49],{33:[1,120],42:[1,121]}),e(f,[2,53],{38:[1,122],42:[1,123]}),e(f,[2,63],{33:[1,125],38:[1,124]}),e(f,[2,50],{33:[1,126],42:[1,127]}),e(f,[2,55],{35:[1,128],42:[1,129]}),e(f,[2,66],{33:[1,131],35:[1,130]}),e(f,[2,52],{38:[1,132],42:[1,133]}),e(f,[2,54],{35:[1,134],42:[1,135]}),e(f,[2,67],{35:[1,137],38:[1,136]}),e(f,[2,64],{33:[1,139],38:[1,138]}),e(f,[2,65],{33:[1,141],35:[1,140]}),e(f,[2,68],{35:[1,143],38:[1,142]}),{39:144,43:b,44:_,45:x},{34:[1,145]},{34:[1,146]},{34:[1,147]},{34:[1,148]},{39:149,43:b,44:_,45:x},e(f,[2,26]),e(f,[2,27]),e(f,[2,28]),e(f,[2,29]),{34:[1,150]},{34:[1,151]},{39:152,43:b,44:_,45:x},{34:[1,153]},{39:154,43:b,44:_,45:x},{34:[1,155]},{34:[1,156]},{34:[1,157]},{34:[1,158]},{34:[1,159]},{34:[1,160]},{34:[1,161]},{39:162,43:b,44:_,45:x},{34:[1,163]},{34:[1,164]},{34:[1,165]},{39:166,43:b,44:_,45:x},{34:[1,167]},{39:168,43:b,44:_,45:x},{34:[1,169]},{34:[1,170]},{34:[1,171]},{39:172,43:b,44:_,45:x},{34:[1,173]},e(f,[2,37],{35:[1,174]}),e(f,[2,38],{38:[1,175]}),e(f,[2,36],{33:[1,176]}),e(f,[2,39],{35:[1,177]}),e(f,[2,34],{38:[1,178]}),e(f,[2,35],{33:[1,179]}),e(f,[2,60],{42:[1,180]}),e(f,[2,73],{33:[1,181]}),e(f,[2,61],{42:[1,182]}),e(f,[2,84],{38:[1,183]}),e(f,[2,74],{33:[1,184]}),e(f,[2,83],{38:[1,185]}),e(f,[2,59],{42:[1,186]}),e(f,[2,72],{33:[1,187]}),e(f,[2,58],{42:[1,188]}),e(f,[2,78],{35:[1,189]}),e(f,[2,71],{33:[1,190]}),e(f,[2,77],{35:[1,191]}),e(f,[2,57],{42:[1,192]}),e(f,[2,85],{38:[1,193]}),e(f,[2,56],{42:[1,194]}),e(f,[2,79],{35:[1,195]}),e(f,[2,80],{35:[1,196]}),e(f,[2,86],{38:[1,197]}),e(f,[2,70],{33:[1,198]}),e(f,[2,81],{38:[1,199]}),e(f,[2,69],{33:[1,200]}),e(f,[2,75],{35:[1,201]}),e(f,[2,76],{35:[1,202]}),e(f,[2,82],{38:[1,203]}),{34:[1,204]},{39:205,43:b,44:_,45:x},{34:[1,206]},{34:[1,207]},{39:208,43:b,44:_,45:x},{34:[1,209]},{34:[1,210]},{34:[1,211]},{34:[1,212]},{39:213,43:b,44:_,45:x},{34:[1,214]},{39:215,43:b,44:_,45:x},{34:[1,216]},{34:[1,217]},{34:[1,218]},{34:[1,219]},{34:[1,220]},{34:[1,221]},{34:[1,222]},{39:223,43:b,44:_,45:x},{34:[1,224]},{34:[1,225]},{34:[1,226]},{39:227,43:b,44:_,45:x},{34:[1,228]},{39:229,43:b,44:_,45:x},{34:[1,230]},{34:[1,231]},{34:[1,232]},{39:233,43:b,44:_,45:x},e(f,[2,40]),e(f,[2,42]),e(f,[2,41]),e(f,[2,43]),e(f,[2,45]),e(f,[2,44]),e(f,[2,101]),e(f,[2,102]),e(f,[2,99]),e(f,[2,100]),e(f,[2,104]),e(f,[2,103]),e(f,[2,108]),e(f,[2,107]),e(f,[2,106]),e(f,[2,105]),e(f,[2,110]),e(f,[2,109]),e(f,[2,98]),e(f,[2,97]),e(f,[2,96]),e(f,[2,95]),e(f,[2,93]),e(f,[2,94]),e(f,[2,92]),e(f,[2,91]),e(f,[2,90]),e(f,[2,89]),e(f,[2,87]),e(f,[2,88])],defaultActions:{9:[2,118],10:[2,1],11:[2,2],19:[2,3],27:[2,4],46:[2,120],47:[2,5]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},w=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),50;case 1:return this.begin("type_directive"),51;case 2:return this.popState(),this.begin("arg_directive"),9;case 3:return this.popState(),this.popState(),53;case 4:return 52;case 5:return this.begin("acc_title"),20;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),22;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:case 34:case 38:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:return 14;case 13:case 14:break;case 15:return 6;case 16:return 40;case 17:return 33;case 18:return 38;case 19:return 42;case 20:return 43;case 21:return 44;case 22:return 45;case 23:return 35;case 24:return 29;case 25:return 30;case 26:return 37;case 27:return 32;case 28:return 27;case 29:case 30:return 10;case 31:return 9;case 32:return"CARET";case 33:this.begin("options");break;case 35:return 13;case 36:return 36;case 37:this.begin("string");break;case 39:return 34;case 40:return 31;case 41:return 54;case 42:return 8}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit(?=\s|$))/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch(?=\s|$))/i,/^(?:order:)/i,/^(?:merge(?=\s|$))/i,/^(?:cherry-pick(?=\s|$))/i,/^(?:checkout(?=\s|$))/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+(?=\s|$))/i,/^(?:\w([-\./\w]*[-\w])?)/i,/^(?:$)/i,/^(?:\s+)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},options:{rules:[34,35],inclusive:!1},string:{rules:[38,39],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,36,37,40,41,42,43],inclusive:!0}}},t);function T(){this.yy={}}return k.lexer=w,T.prototype=k,k.Parser=T,new T}();Hv.parser=Hv;const qv=Hv,Vv=t=>null!==t.match(/^\s*gitGraph/);let Gv="",Xv="",Zv="";const Qv=t=>$b(t,fv()),Kv=function(){Gv="",Zv="",Xv=""},Jv=function(t){Gv=Qv(t).replace(/^\s+/g,"")},tk=function(){return Gv||Xv},ek=function(t){Zv=Qv(t).replace(/\n\s+/g,"\n")},nk=function(){return Zv},ik=function(t){Xv=Qv(t)},rk=function(){return Xv};let ak=fv().gitGraph.mainBranchName,sk=fv().gitGraph.mainBranchOrder,ok={},ck=null,lk={};lk[ak]={name:ak,order:sk};let hk={};hk[ak]=ck;let uk=ak,dk="LR",pk=0;function fk(){return Vx({length:7})}let gk={};const yk=function(t){if(t=Wb.sanitizeText(t,fv()),void 0===hk[t]){let e=new Error('Trying to checkout branch which is not yet created. (Help try using "branch '+t+'")');throw e.hash={text:"checkout "+t,token:"checkout "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"branch '+t+'"']},e}{uk=t;const e=hk[uk];ck=ok[e]}};function mk(t,e,n){const i=t.indexOf(e);-1===i?t.push(n):t.splice(i,1,n)}function bk(t){const e=t.reduce(((t,e)=>t.seq>e.seq?t:e),t[0]);let n="";t.forEach((function(t){n+=t===e?"\t*":"\t|"}));const i=[n,e.id,e.seq];for(let r in hk)hk[r]===e.id&&i.push(r);if(Bb.debug(i.join(" ")),e.parents&&2==e.parents.length){const n=ok[e.parents[0]];mk(t,e,n),t.push(ok[e.parents[1]])}else{if(0==e.parents.length)return;{const n=ok[e.parents];mk(t,e,n)}}bk(t=function(t,e){const n=Object.create(null);return t.reduce(((t,i)=>{const r=e(i);return n[r]||(n[r]=!0,t.push(i)),t}),[])}(t,(t=>t.id)))}const _k=function(){const t=Object.keys(ok).map((function(t){return ok[t]}));return t.forEach((function(t){Bb.debug(t.id)})),t.sort(((t,e)=>t.seq-e.seq)),t},xk={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},vk={parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().gitGraph,setDirection:function(t){dk=t},setOptions:function(t){Bb.debug("options str",t),t=(t=t&&t.trim())||"{}";try{gk=JSON.parse(t)}catch(e){Bb.error("error while parsing gitGraph options",e.message)}},getOptions:function(){return gk},commit:function(t,e,n,i){Bb.debug("Entering commit:",t,e,n,i),e=Wb.sanitizeText(e,fv()),t=Wb.sanitizeText(t,fv()),i=Wb.sanitizeText(i,fv());const r={id:e||pk+"-"+fk(),message:t,seq:pk++,type:n||xk.NORMAL,tag:i||"",parents:null==ck?[]:[ck.id],branch:uk};ck=r,ok[r.id]=r,hk[uk]=r.id,Bb.debug("in pushCommit "+r.id)},branch:function(t,e){if(t=Wb.sanitizeText(t,fv()),void 0!==hk[t]){let e=new Error('Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout '+t+'")');throw e.hash={text:"branch "+t,token:"branch "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+t+'"']},e}hk[t]=null!=ck?ck.id:null,lk[t]={name:t,order:e?parseInt(e,10):null},yk(t),Bb.debug("in createBranch")},merge:function(t,e,n,i){t=Wb.sanitizeText(t,fv()),e=Wb.sanitizeText(e,fv());const r=ok[hk[uk]],a=ok[hk[t]];if(uk===t){let e=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(void 0===r||!r){let e=new Error('Incorrect usage of "merge". Current branch ('+uk+")has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["commit"]},e}if(void 0===hk[t]){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") does not exist");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch "+t]},e}if(void 0===a||!a){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"commit"']},e}if(r===a){let e=new Error('Incorrect usage of "merge". Both branches have same head');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(e&&void 0!==ok[e]){let r=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom Id");throw r.hash={text:"merge "+t+e+n+i,token:"merge "+t+e+n+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["merge "+t+" "+e+"_UNIQUE "+n+" "+i]},r}const s={id:e||pk+"-"+fk(),message:"merged branch "+t+" into "+uk,seq:pk++,parents:[null==ck?null:ck.id,hk[t]],branch:uk,type:xk.MERGE,customType:n,customId:!!e,tag:i||""};ck=s,ok[s.id]=s,hk[uk]=s.id,Bb.debug(hk),Bb.debug("in mergeBranch")},cherryPick:function(t,e,n){if(Bb.debug("Entering cherryPick:",t,e,n),t=Wb.sanitizeText(t,fv()),e=Wb.sanitizeText(e,fv()),n=Wb.sanitizeText(n,fv()),!t||void 0===ok[t]){let n=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw n.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},n}let i=ok[t],r=i.branch;if(i.type===xk.MERGE){let n=new Error('Incorrect usage of "cherryPick". Source commit should not be a merge commit');throw n.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},n}if(!e||void 0===ok[e]){if(r===uk){let n=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw n.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},n}const a=ok[hk[uk]];if(void 0===a||!a){let n=new Error('Incorrect usage of "cherry-pick". Current branch ('+uk+")has no commits");throw n.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},n}const s={id:pk+"-"+fk(),message:"cherry-picked "+i+" into "+uk,seq:pk++,parents:[null==ck?null:ck.id,i.id],branch:uk,type:xk.CHERRY_PICK,tag:null!=n?n:"cherry-pick:"+i.id};ck=s,ok[s.id]=s,hk[uk]=s.id,Bb.debug(hk),Bb.debug("in cherryPick")}},checkout:yk,prettyPrint:function(){Bb.debug(ok);bk([_k()[0]])},clear:function(){ok={},ck=null;let t=fv().gitGraph.mainBranchName,e=fv().gitGraph.mainBranchOrder;hk={},hk[t]=null,lk={},lk[t]={name:t,order:e},uk=t,pk=0,Kv()},getBranchesAsObjArray:function(){const t=Object.values(lk).map(((t,e)=>null!==t.order?t:{...t,order:parseFloat(`0.${e}`,10)})).sort(((t,e)=>t.order-e.order)).map((({name:t})=>({name:t})));return t},getBranches:function(){return hk},getCommits:function(){return ok},getCommitsArray:_k,getCurrentBranch:function(){return uk},getDirection:function(){return dk},getHead:function(){return ck},setAccTitle:Jv,getAccTitle:tk,getAccDescription:nk,setAccDescription:ek,setDiagramTitle:ik,getDiagramTitle:rk,commitType:xk};let kk={};const wk=0,Tk=1,Ck=2,Ek=3,Sk=4;let Ak={},Dk={},Lk=[],Nk=0;const Ok=(t,e,n)=>{const i=Pv().gitGraph,r=t.append("g").attr("class","commit-bullets"),a=t.append("g").attr("class","commit-labels");let s=0;Object.keys(e).sort(((t,n)=>e[t].seq-e[n].seq)).forEach((t=>{const o=e[t],c=Ak[o.branch].pos,l=s+10;if(n){let t,e=void 0!==o.customType&&""!==o.customType?o.customType:o.type;switch(e){case wk:t="commit-normal";break;case Tk:t="commit-reverse";break;case Ck:t="commit-highlight";break;case Ek:t="commit-merge";break;case Sk:t="commit-cherry-pick";break;default:t="commit-normal"}if(e===Ck){const e=r.append("rect");e.attr("x",l-10),e.attr("y",c-10),e.attr("height",20),e.attr("width",20),e.attr("class",`commit ${o.id} commit-highlight${Ak[o.branch].index%8} ${t}-outer`),r.append("rect").attr("x",l-6).attr("y",c-6).attr("height",12).attr("width",12).attr("class",`commit ${o.id} commit${Ak[o.branch].index%8} ${t}-inner`)}else if(e===Sk)r.append("circle").attr("cx",l).attr("cy",c).attr("r",10).attr("class",`commit ${o.id} ${t}`),r.append("circle").attr("cx",l-3).attr("cy",c+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${o.id} ${t}`),r.append("circle").attr("cx",l+3).attr("cy",c+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${o.id} ${t}`),r.append("line").attr("x1",l+3).attr("y1",c+1).attr("x2",l).attr("y2",c-5).attr("stroke","#fff").attr("class",`commit ${o.id} ${t}`),r.append("line").attr("x1",l-3).attr("y1",c+1).attr("x2",l).attr("y2",c-5).attr("stroke","#fff").attr("class",`commit ${o.id} ${t}`);else{const n=r.append("circle");if(n.attr("cx",l),n.attr("cy",c),n.attr("r",o.type===Ek?9:10),n.attr("class",`commit ${o.id} commit${Ak[o.branch].index%8}`),e===Ek){const e=r.append("circle");e.attr("cx",l),e.attr("cy",c),e.attr("r",6),e.attr("class",`commit ${t} ${o.id} commit${Ak[o.branch].index%8}`)}if(e===Tk){r.append("path").attr("d",`M ${l-5},${c-5}L${l+5},${c+5}M${l-5},${c+5}L${l+5},${c-5}`).attr("class",`commit ${t} ${o.id} commit${Ak[o.branch].index%8}`)}}}if(Dk[o.id]={x:s+10,y:c},n){const t=4,e=2;if(o.type!==Sk&&(o.customId&&o.type===Ek||o.type!==Ek)&&i.showCommitLabel){const t=a.append("g"),n=t.insert("rect").attr("class","commit-label-bkg"),r=t.append("text").attr("x",s).attr("y",c+25).attr("class","commit-label").text(o.id);let l=r.node().getBBox();if(n.attr("x",s+10-l.width/2-e).attr("y",c+13.5).attr("width",l.width+2*e).attr("height",l.height+2*e),r.attr("x",s+10-l.width/2),i.rotateCommitLabel){let e=-7.5-(l.width+10)/25*9.5,n=10+l.width/25*8.5;t.attr("transform","translate("+e+", "+n+") rotate("+"-45, "+s+", "+c+")")}}if(o.tag){const n=a.insert("polygon"),i=a.append("circle"),r=a.append("text").attr("y",c-16).attr("class","tag-label").text(o.tag);let l=r.node().getBBox();r.attr("x",s+10-l.width/2);const h=l.height/2,u=c-19.2;n.attr("class","tag-label-bkg").attr("points",`\n ${s-l.width/2-t/2},${u+e}\n ${s-l.width/2-t/2},${u-e}\n ${s+10-l.width/2-t},${u-h-e}\n ${s+10+l.width/2+t},${u-h-e}\n ${s+10+l.width/2+t},${u+h+e}\n ${s+10-l.width/2-t},${u+h+e}`),i.attr("cx",s-l.width/2+t/2).attr("cy",u).attr("r",1.5).attr("class","tag-hole")}}s+=50,s>Nk&&(Nk=s)}))},Bk=(t,e,n=0)=>{const i=t+Math.abs(t-e)/2;if(n>5)return i;if(Lk.every((t=>Math.abs(t-i)>=10)))return Lk.push(i),i;const r=Math.abs(t-e);return Bk(t,e-r/5,n+1)},Mk=(t,e,n,i)=>{const r=Dk[e.id],a=Dk[n.id],s=((t,e,n)=>Object.keys(n).filter((i=>n[i].branch===e.branch&&n[i].seq>t.seq&&n[i].seq<e.seq)).length>0)(e,n,i);let o,c="",l="",h=0,u=0,d=Ak[n.branch].index;if(s){c="A 10 10, 0, 0, 0,",l="A 10 10, 0, 0, 1,",h=10,u=10,d=Ak[n.branch].index;const t=r.y<a.y?Bk(r.y,a.y):Bk(a.y,r.y);o=r.y<a.y?`M ${r.x} ${r.y} L ${r.x} ${t-h} ${c} ${r.x+u} ${t} L ${a.x-h} ${t} ${l} ${a.x} ${t+u} L ${a.x} ${a.y}`:`M ${r.x} ${r.y} L ${r.x} ${t+h} ${l} ${r.x+u} ${t} L ${a.x-h} ${t} ${c} ${a.x} ${t-u} L ${a.x} ${a.y}`}else r.y<a.y&&(c="A 20 20, 0, 0, 0,",h=20,u=20,d=Ak[n.branch].index,o=`M ${r.x} ${r.y} L ${r.x} ${a.y-h} ${c} ${r.x+u} ${a.y} L ${a.x} ${a.y}`),r.y>a.y&&(c="A 20 20, 0, 0, 0,",h=20,u=20,d=Ak[e.branch].index,o=`M ${r.x} ${r.y} L ${a.x-h} ${r.y} ${c} ${a.x} ${r.y-u} L ${a.x} ${a.y}`),r.y===a.y&&(d=Ak[e.branch].index,o=`M ${r.x} ${r.y} L ${r.x} ${a.y-h} ${c} ${r.x+u} ${a.y} L ${a.x} ${a.y}`);t.append("path").attr("d",o).attr("class","arrow arrow"+d%8)},Ik=(t,e)=>{const n=Pv().gitGraph,i=t.append("g");e.forEach(((t,e)=>{const r=e%8,a=Ak[t.name].pos,s=i.append("line");s.attr("x1",0),s.attr("y1",a),s.attr("x2",Nk),s.attr("y2",a),s.attr("class","branch branch"+r),Lk.push(a);const o=(t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","text");let n=[];n="string"==typeof t?t.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(t)?t:[];for(const i of n){const t=document.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","0"),t.setAttribute("class","row"),t.textContent=i.trim(),e.appendChild(t)}return e})(t.name),c=i.insert("rect"),l=i.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+r);l.node().appendChild(o);let h=o.getBBox();c.attr("class","branchLabelBkg label"+r).attr("rx",4).attr("ry",4).attr("x",-h.width-4-(!0===n.rotateCommitLabel?30:0)).attr("y",-h.height/2+8).attr("width",h.width+18).attr("height",h.height+4),l.attr("transform","translate("+(-h.width-14-(!0===n.rotateCommitLabel?30:0))+", "+(a-h.height/2-1)+")"),c.attr("transform","translate(-19, "+(a-h.height/2)+")")}))},Fk={draw:function(t,e,n,i){var r;Ak={},Dk={},kk={},Nk=0,Lk=[];const a=Pv(),s=a.gitGraph;Bb.debug("in gitgraph renderer",t+"\n","id:",e,n),kk=i.db.getCommits();const o=i.db.getBranchesAsObjArray();let c=0;o.forEach(((t,e)=>{Ak[t.name]={pos:c,index:e},c+=50+(s.rotateCommitLabel?40:0)}));const l=Xo(`[id="${e}"]`);Ok(l,kk,!1),s.showBranches&&Ik(l,o),((t,e)=>{const n=t.append("g").attr("class","commit-arrows");Object.keys(e).forEach((t=>{const i=e[t];i.parents&&i.parents.length>0&&i.parents.forEach((t=>{Mk(n,e[t],i,e)}))}))})(l,kk),Ok(l,kk,!0),rv.insertTitle(l,"gitTitleText",s.titleTopMargin,i.db.getDiagramTitle()),Yv(void 0,l,s.diagramPadding,null!=(r=s.useMaxWidth)?r:a.useMaxWidth)}},Rk=t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map((e=>`\n .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; }\n .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; }\n .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; }\n .label${e} { fill: ${t["git"+e]}; }\n .arrow${e} { stroke: ${t["git"+e]}; }\n `)).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n }\n`;var $k=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,6],i=[1,7],r=[1,8],a=[1,9],s=[1,16],o=[1,11],l=[1,12],h=[1,13],u=[1,14],d=[1,15],p=[1,27],f=[1,33],g=[1,34],y=[1,35],m=[1,36],b=[1,37],_=[1,72],x=[1,73],v=[1,74],k=[1,75],w=[1,76],T=[1,77],C=[1,78],E=[1,38],S=[1,39],A=[1,40],D=[1,41],L=[1,42],N=[1,43],O=[1,44],B=[1,45],M=[1,46],I=[1,47],F=[1,48],R=[1,49],$=[1,50],P=[1,51],j=[1,52],Y=[1,53],z=[1,54],U=[1,55],W=[1,56],H=[1,57],q=[1,59],V=[1,60],G=[1,61],X=[1,62],Z=[1,63],Q=[1,64],K=[1,65],J=[1,66],tt=[1,67],et=[1,68],nt=[1,69],it=[24,52],rt=[24,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],at=[15,24,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],st=[1,94],ot=[1,95],ct=[1,96],lt=[1,97],ht=[15,24,52],ut=[7,8,9,10,18,22,25,26,27,28],dt=[15,24,43,52],pt=[15,24,43,52,86,87,89,90],ft=[15,43],gt=[44,46,47,48,49,50,51,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],yt={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,directive:6,direction_tb:7,direction_bt:8,direction_rl:9,direction_lr:10,graphConfig:11,openDirective:12,typeDirective:13,closeDirective:14,NEWLINE:15,":":16,argDirective:17,open_directive:18,type_directive:19,arg_directive:20,close_directive:21,C4_CONTEXT:22,statements:23,EOF:24,C4_CONTAINER:25,C4_COMPONENT:26,C4_DYNAMIC:27,C4_DEPLOYMENT:28,otherStatements:29,diagramStatements:30,otherStatement:31,title:32,accDescription:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,boundaryStatement:39,boundaryStartStatement:40,boundaryStopStatement:41,boundaryStart:42,LBRACE:43,ENTERPRISE_BOUNDARY:44,attributes:45,SYSTEM_BOUNDARY:46,BOUNDARY:47,CONTAINER_BOUNDARY:48,NODE:49,NODE_L:50,NODE_R:51,RBRACE:52,diagramStatement:53,PERSON:54,PERSON_EXT:55,SYSTEM:56,SYSTEM_DB:57,SYSTEM_QUEUE:58,SYSTEM_EXT:59,SYSTEM_EXT_DB:60,SYSTEM_EXT_QUEUE:61,CONTAINER:62,CONTAINER_DB:63,CONTAINER_QUEUE:64,CONTAINER_EXT:65,CONTAINER_EXT_DB:66,CONTAINER_EXT_QUEUE:67,COMPONENT:68,COMPONENT_DB:69,COMPONENT_QUEUE:70,COMPONENT_EXT:71,COMPONENT_EXT_DB:72,COMPONENT_EXT_QUEUE:73,REL:74,BIREL:75,REL_U:76,REL_D:77,REL_L:78,REL_R:79,REL_B:80,REL_INDEX:81,UPDATE_EL_STYLE:82,UPDATE_REL_STYLE:83,UPDATE_LAYOUT_CONFIG:84,attribute:85,STR:86,STR_KEY:87,STR_VALUE:88,ATTRIBUTE:89,ATTRIBUTE_EMPTY:90,$accept:0,$end:1},terminals_:{2:"error",7:"direction_tb",8:"direction_bt",9:"direction_rl",10:"direction_lr",15:"NEWLINE",16:":",18:"open_directive",19:"type_directive",20:"arg_directive",21:"close_directive",22:"C4_CONTEXT",24:"EOF",25:"C4_CONTAINER",26:"C4_COMPONENT",27:"C4_DYNAMIC",28:"C4_DEPLOYMENT",32:"title",33:"accDescription",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",43:"LBRACE",44:"ENTERPRISE_BOUNDARY",46:"SYSTEM_BOUNDARY",47:"BOUNDARY",48:"CONTAINER_BOUNDARY",49:"NODE",50:"NODE_L",51:"NODE_R",52:"RBRACE",54:"PERSON",55:"PERSON_EXT",56:"SYSTEM",57:"SYSTEM_DB",58:"SYSTEM_QUEUE",59:"SYSTEM_EXT",60:"SYSTEM_EXT_DB",61:"SYSTEM_EXT_QUEUE",62:"CONTAINER",63:"CONTAINER_DB",64:"CONTAINER_QUEUE",65:"CONTAINER_EXT",66:"CONTAINER_EXT_DB",67:"CONTAINER_EXT_QUEUE",68:"COMPONENT",69:"COMPONENT_DB",70:"COMPONENT_QUEUE",71:"COMPONENT_EXT",72:"COMPONENT_EXT_DB",73:"COMPONENT_EXT_QUEUE",74:"REL",75:"BIREL",76:"REL_U",77:"REL_D",78:"REL_L",79:"REL_R",80:"REL_B",81:"REL_INDEX",82:"UPDATE_EL_STYLE",83:"UPDATE_REL_STYLE",84:"UPDATE_LAYOUT_CONFIG",86:"STR",87:"STR_KEY",88:"STR_VALUE",89:"ATTRIBUTE",90:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[3,2],[5,1],[5,1],[5,1],[5,1],[4,1],[6,4],[6,6],[12,1],[13,1],[17,1],[14,1],[11,4],[11,4],[11,4],[11,4],[11,4],[23,1],[23,1],[23,2],[29,1],[29,2],[29,3],[31,1],[31,1],[31,2],[31,2],[31,1],[39,3],[40,3],[40,3],[40,4],[42,2],[42,2],[42,2],[42,2],[42,2],[42,2],[42,2],[41,1],[30,1],[30,2],[30,3],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,1],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[45,1],[45,2],[85,1],[85,2],[85,1],[85,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 4:i.setDirection("TB");break;case 5:i.setDirection("BT");break;case 6:i.setDirection("RL");break;case 7:i.setDirection("LR");break;case 11:i.parseDirective("%%{","open_directive");break;case 12:break;case 13:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 14:i.parseDirective("}%%","close_directive","c4Context");break;case 15:case 16:case 17:case 18:case 19:i.setC4Type(a[o-3]);break;case 26:i.setTitle(a[o].substring(6)),this.$=a[o].substring(6);break;case 27:i.setAccDescription(a[o].substring(15)),this.$=a[o].substring(15);break;case 28:this.$=a[o].trim(),i.setTitle(this.$);break;case 29:case 30:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 35:case 36:a[o].splice(2,0,"ENTERPRISE"),i.addPersonOrSystemBoundary(...a[o]),this.$=a[o];break;case 37:i.addPersonOrSystemBoundary(...a[o]),this.$=a[o];break;case 38:a[o].splice(2,0,"CONTAINER"),i.addContainerBoundary(...a[o]),this.$=a[o];break;case 39:i.addDeploymentNode("node",...a[o]),this.$=a[o];break;case 40:i.addDeploymentNode("nodeL",...a[o]),this.$=a[o];break;case 41:i.addDeploymentNode("nodeR",...a[o]),this.$=a[o];break;case 42:i.popBoundaryParseStack();break;case 46:i.addPersonOrSystem("person",...a[o]),this.$=a[o];break;case 47:i.addPersonOrSystem("external_person",...a[o]),this.$=a[o];break;case 48:i.addPersonOrSystem("system",...a[o]),this.$=a[o];break;case 49:i.addPersonOrSystem("system_db",...a[o]),this.$=a[o];break;case 50:i.addPersonOrSystem("system_queue",...a[o]),this.$=a[o];break;case 51:i.addPersonOrSystem("external_system",...a[o]),this.$=a[o];break;case 52:i.addPersonOrSystem("external_system_db",...a[o]),this.$=a[o];break;case 53:i.addPersonOrSystem("external_system_queue",...a[o]),this.$=a[o];break;case 54:i.addContainer("container",...a[o]),this.$=a[o];break;case 55:i.addContainer("container_db",...a[o]),this.$=a[o];break;case 56:i.addContainer("container_queue",...a[o]),this.$=a[o];break;case 57:i.addContainer("external_container",...a[o]),this.$=a[o];break;case 58:i.addContainer("external_container_db",...a[o]),this.$=a[o];break;case 59:i.addContainer("external_container_queue",...a[o]),this.$=a[o];break;case 60:i.addComponent("component",...a[o]),this.$=a[o];break;case 61:i.addComponent("component_db",...a[o]),this.$=a[o];break;case 62:i.addComponent("component_queue",...a[o]),this.$=a[o];break;case 63:i.addComponent("external_component",...a[o]),this.$=a[o];break;case 64:i.addComponent("external_component_db",...a[o]),this.$=a[o];break;case 65:i.addComponent("external_component_queue",...a[o]),this.$=a[o];break;case 67:i.addRel("rel",...a[o]),this.$=a[o];break;case 68:i.addRel("birel",...a[o]),this.$=a[o];break;case 69:i.addRel("rel_u",...a[o]),this.$=a[o];break;case 70:i.addRel("rel_d",...a[o]),this.$=a[o];break;case 71:i.addRel("rel_l",...a[o]),this.$=a[o];break;case 72:i.addRel("rel_r",...a[o]),this.$=a[o];break;case 73:i.addRel("rel_b",...a[o]),this.$=a[o];break;case 74:a[o].splice(0,1),i.addRel("rel",...a[o]),this.$=a[o];break;case 75:i.updateElStyle("update_el_style",...a[o]),this.$=a[o];break;case 76:i.updateRelStyle("update_rel_style",...a[o]),this.$=a[o];break;case 77:i.updateLayoutConfig("update_layout_config",...a[o]),this.$=a[o];break;case 78:this.$=[a[o]];break;case 79:a[o].unshift(a[o-1]),this.$=a[o];break;case 80:case 82:this.$=a[o].trim();break;case 81:let t={};t[a[o-1].trim()]=a[o].trim(),this.$=t;break;case 83:this.$=""}},table:[{3:1,4:2,5:3,6:4,7:n,8:i,9:r,10:a,11:5,12:10,18:s,22:o,25:l,26:h,27:u,28:d},{1:[3]},{1:[2,1]},{1:[2,2]},{3:17,4:2,5:3,6:4,7:n,8:i,9:r,10:a,11:5,12:10,18:s,22:o,25:l,26:h,27:u,28:d},{1:[2,8]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{1:[2,7]},{13:18,19:[1,19]},{15:[1,20]},{15:[1,21]},{15:[1,22]},{15:[1,23]},{15:[1,24]},{19:[2,11]},{1:[2,3]},{14:25,16:[1,26],21:p},e([16,21],[2,12]),{23:28,29:29,30:30,31:31,32:f,33:g,34:y,36:m,38:b,39:58,40:70,42:71,44:_,46:x,47:v,48:k,49:w,50:T,51:C,53:32,54:E,55:S,56:A,57:D,58:L,59:N,60:O,61:B,62:M,63:I,64:F,65:R,66:$,67:P,68:j,69:Y,70:z,71:U,72:W,73:H,74:q,75:V,76:G,77:X,78:Z,79:Q,80:K,81:J,82:tt,83:et,84:nt},{23:79,29:29,30:30,31:31,32:f,33:g,34:y,36:m,38:b,39:58,40:70,42:71,44:_,46:x,47:v,48:k,49:w,50:T,51:C,53:32,54:E,55:S,56:A,57:D,58:L,59:N,60:O,61:B,62:M,63:I,64:F,65:R,66:$,67:P,68:j,69:Y,70:z,71:U,72:W,73:H,74:q,75:V,76:G,77:X,78:Z,79:Q,80:K,81:J,82:tt,83:et,84:nt},{23:80,29:29,30:30,31:31,32:f,33:g,34:y,36:m,38:b,39:58,40:70,42:71,44:_,46:x,47:v,48:k,49:w,50:T,51:C,53:32,54:E,55:S,56:A,57:D,58:L,59:N,60:O,61:B,62:M,63:I,64:F,65:R,66:$,67:P,68:j,69:Y,70:z,71:U,72:W,73:H,74:q,75:V,76:G,77:X,78:Z,79:Q,80:K,81:J,82:tt,83:et,84:nt},{23:81,29:29,30:30,31:31,32:f,33:g,34:y,36:m,38:b,39:58,40:70,42:71,44:_,46:x,47:v,48:k,49:w,50:T,51:C,53:32,54:E,55:S,56:A,57:D,58:L,59:N,60:O,61:B,62:M,63:I,64:F,65:R,66:$,67:P,68:j,69:Y,70:z,71:U,72:W,73:H,74:q,75:V,76:G,77:X,78:Z,79:Q,80:K,81:J,82:tt,83:et,84:nt},{23:82,29:29,30:30,31:31,32:f,33:g,34:y,36:m,38:b,39:58,40:70,42:71,44:_,46:x,47:v,48:k,49:w,50:T,51:C,53:32,54:E,55:S,56:A,57:D,58:L,59:N,60:O,61:B,62:M,63:I,64:F,65:R,66:$,67:P,68:j,69:Y,70:z,71:U,72:W,73:H,74:q,75:V,76:G,77:X,78:Z,79:Q,80:K,81:J,82:tt,83:et,84:nt},{15:[1,83]},{17:84,20:[1,85]},{15:[2,14]},{24:[1,86]},e(it,[2,20],{53:32,39:58,40:70,42:71,30:87,44:_,46:x,47:v,48:k,49:w,50:T,51:C,54:E,55:S,56:A,57:D,58:L,59:N,60:O,61:B,62:M,63:I,64:F,65:R,66:$,67:P,68:j,69:Y,70:z,71:U,72:W,73:H,74:q,75:V,76:G,77:X,78:Z,79:Q,80:K,81:J,82:tt,83:et,84:nt}),e(it,[2,21]),e(rt,[2,23],{15:[1,88]}),e(it,[2,43],{15:[1,89]}),e(at,[2,26]),e(at,[2,27]),{35:[1,90]},{37:[1,91]},e(at,[2,30]),{45:92,85:93,86:st,87:ot,89:ct,90:lt},{45:98,85:93,86:st,87:ot,89:ct,90:lt},{45:99,85:93,86:st,87:ot,89:ct,90:lt},{45:100,85:93,86:st,87:ot,89:ct,90:lt},{45:101,85:93,86:st,87:ot,89:ct,90:lt},{45:102,85:93,86:st,87:ot,89:ct,90:lt},{45:103,85:93,86:st,87:ot,89:ct,90:lt},{45:104,85:93,86:st,87:ot,89:ct,90:lt},{45:105,85:93,86:st,87:ot,89:ct,90:lt},{45:106,85:93,86:st,87:ot,89:ct,90:lt},{45:107,85:93,86:st,87:ot,89:ct,90:lt},{45:108,85:93,86:st,87:ot,89:ct,90:lt},{45:109,85:93,86:st,87:ot,89:ct,90:lt},{45:110,85:93,86:st,87:ot,89:ct,90:lt},{45:111,85:93,86:st,87:ot,89:ct,90:lt},{45:112,85:93,86:st,87:ot,89:ct,90:lt},{45:113,85:93,86:st,87:ot,89:ct,90:lt},{45:114,85:93,86:st,87:ot,89:ct,90:lt},{45:115,85:93,86:st,87:ot,89:ct,90:lt},{45:116,85:93,86:st,87:ot,89:ct,90:lt},e(ht,[2,66]),{45:117,85:93,86:st,87:ot,89:ct,90:lt},{45:118,85:93,86:st,87:ot,89:ct,90:lt},{45:119,85:93,86:st,87:ot,89:ct,90:lt},{45:120,85:93,86:st,87:ot,89:ct,90:lt},{45:121,85:93,86:st,87:ot,89:ct,90:lt},{45:122,85:93,86:st,87:ot,89:ct,90:lt},{45:123,85:93,86:st,87:ot,89:ct,90:lt},{45:124,85:93,86:st,87:ot,89:ct,90:lt},{45:125,85:93,86:st,87:ot,89:ct,90:lt},{45:126,85:93,86:st,87:ot,89:ct,90:lt},{45:127,85:93,86:st,87:ot,89:ct,90:lt},{30:128,39:58,40:70,42:71,44:_,46:x,47:v,48:k,49:w,50:T,51:C,53:32,54:E,55:S,56:A,57:D,58:L,59:N,60:O,61:B,62:M,63:I,64:F,65:R,66:$,67:P,68:j,69:Y,70:z,71:U,72:W,73:H,74:q,75:V,76:G,77:X,78:Z,79:Q,80:K,81:J,82:tt,83:et,84:nt},{15:[1,130],43:[1,129]},{45:131,85:93,86:st,87:ot,89:ct,90:lt},{45:132,85:93,86:st,87:ot,89:ct,90:lt},{45:133,85:93,86:st,87:ot,89:ct,90:lt},{45:134,85:93,86:st,87:ot,89:ct,90:lt},{45:135,85:93,86:st,87:ot,89:ct,90:lt},{45:136,85:93,86:st,87:ot,89:ct,90:lt},{45:137,85:93,86:st,87:ot,89:ct,90:lt},{24:[1,138]},{24:[1,139]},{24:[1,140]},{24:[1,141]},e(ut,[2,9]),{14:142,21:p},{21:[2,13]},{1:[2,15]},e(it,[2,22]),e(rt,[2,24],{31:31,29:143,32:f,33:g,34:y,36:m,38:b}),e(it,[2,44],{29:29,30:30,31:31,53:32,39:58,40:70,42:71,23:144,32:f,33:g,34:y,36:m,38:b,44:_,46:x,47:v,48:k,49:w,50:T,51:C,54:E,55:S,56:A,57:D,58:L,59:N,60:O,61:B,62:M,63:I,64:F,65:R,66:$,67:P,68:j,69:Y,70:z,71:U,72:W,73:H,74:q,75:V,76:G,77:X,78:Z,79:Q,80:K,81:J,82:tt,83:et,84:nt}),e(at,[2,28]),e(at,[2,29]),e(ht,[2,46]),e(dt,[2,78],{85:93,45:145,86:st,87:ot,89:ct,90:lt}),e(pt,[2,80]),{88:[1,146]},e(pt,[2,82]),e(pt,[2,83]),e(ht,[2,47]),e(ht,[2,48]),e(ht,[2,49]),e(ht,[2,50]),e(ht,[2,51]),e(ht,[2,52]),e(ht,[2,53]),e(ht,[2,54]),e(ht,[2,55]),e(ht,[2,56]),e(ht,[2,57]),e(ht,[2,58]),e(ht,[2,59]),e(ht,[2,60]),e(ht,[2,61]),e(ht,[2,62]),e(ht,[2,63]),e(ht,[2,64]),e(ht,[2,65]),e(ht,[2,67]),e(ht,[2,68]),e(ht,[2,69]),e(ht,[2,70]),e(ht,[2,71]),e(ht,[2,72]),e(ht,[2,73]),e(ht,[2,74]),e(ht,[2,75]),e(ht,[2,76]),e(ht,[2,77]),{41:147,52:[1,148]},{15:[1,149]},{43:[1,150]},e(ft,[2,35]),e(ft,[2,36]),e(ft,[2,37]),e(ft,[2,38]),e(ft,[2,39]),e(ft,[2,40]),e(ft,[2,41]),{1:[2,16]},{1:[2,17]},{1:[2,18]},{1:[2,19]},{15:[1,151]},e(rt,[2,25]),e(it,[2,45]),e(dt,[2,79]),e(pt,[2,81]),e(ht,[2,31]),e(ht,[2,42]),e(gt,[2,32]),e(gt,[2,33],{15:[1,152]}),e(ut,[2,10]),e(gt,[2,34])],defaultActions:{2:[2,1],3:[2,2],5:[2,8],6:[2,4],7:[2,5],8:[2,6],9:[2,7],16:[2,11],17:[2,3],27:[2,14],85:[2,13],86:[2,15],138:[2,16],139:[2,17],140:[2,18],141:[2,19]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},mt=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),18;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 10;case 5:return this.begin("type_directive"),19;case 6:return this.popState(),this.begin("arg_directive"),16;case 7:return this.popState(),this.popState(),21;case 8:return 20;case 9:return 32;case 10:return 33;case 11:return this.begin("acc_title"),34;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),36;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:case 78:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:case 21:case 75:break;case 19:c;break;case 20:return 15;case 22:return 22;case 23:return 25;case 24:return 26;case 25:return 27;case 26:return 28;case 27:return this.begin("person_ext"),55;case 28:return this.begin("person"),54;case 29:return this.begin("system_ext_queue"),61;case 30:return this.begin("system_ext_db"),60;case 31:return this.begin("system_ext"),59;case 32:return this.begin("system_queue"),58;case 33:return this.begin("system_db"),57;case 34:return this.begin("system"),56;case 35:return this.begin("boundary"),47;case 36:return this.begin("enterprise_boundary"),44;case 37:return this.begin("system_boundary"),46;case 38:return this.begin("container_ext_queue"),67;case 39:return this.begin("container_ext_db"),66;case 40:return this.begin("container_ext"),65;case 41:return this.begin("container_queue"),64;case 42:return this.begin("container_db"),63;case 43:return this.begin("container"),62;case 44:return this.begin("container_boundary"),48;case 45:return this.begin("component_ext_queue"),73;case 46:return this.begin("component_ext_db"),72;case 47:return this.begin("component_ext"),71;case 48:return this.begin("component_queue"),70;case 49:return this.begin("component_db"),69;case 50:return this.begin("component"),68;case 51:case 52:return this.begin("node"),49;case 53:return this.begin("node_l"),50;case 54:return this.begin("node_r"),51;case 55:return this.begin("rel"),74;case 56:return this.begin("birel"),75;case 57:case 58:return this.begin("rel_u"),76;case 59:case 60:return this.begin("rel_d"),77;case 61:case 62:return this.begin("rel_l"),78;case 63:case 64:return this.begin("rel_r"),79;case 65:return this.begin("rel_b"),80;case 66:return this.begin("rel_index"),81;case 67:return this.begin("update_el_style"),82;case 68:return this.begin("update_rel_style"),83;case 69:return this.begin("update_layout_config"),84;case 70:return"EOF_IN_STRUCT";case 71:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 72:this.begin("attribute");break;case 73:case 84:this.popState(),this.popState();break;case 74:case 76:return 90;case 77:this.begin("string");break;case 79:case 85:return"STR";case 80:this.begin("string_kv");break;case 81:return this.begin("string_kv_key"),"STR_KEY";case 82:this.popState(),this.begin("string_kv_value");break;case 83:return"STR_VALUE";case 86:return"LBRACE";case 87:return"RBRACE";case 88:return"SPACE";case 89:return"EOL";case 90:return 24}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[7,8],inclusive:!1},type_directive:{rules:[6,7],inclusive:!1},open_directive:{rules:[5],inclusive:!1},string_kv_value:{rules:[83,84],inclusive:!1},string_kv_key:{rules:[82],inclusive:!1},string_kv:{rules:[81],inclusive:!1},string:{rules:[78,79],inclusive:!1},attribute:{rules:[73,74,75,76,77,80,85],inclusive:!1},update_layout_config:{rules:[70,71,72,73],inclusive:!1},update_rel_style:{rules:[70,71,72,73],inclusive:!1},update_el_style:{rules:[70,71,72,73],inclusive:!1},rel_b:{rules:[70,71,72,73],inclusive:!1},rel_r:{rules:[70,71,72,73],inclusive:!1},rel_l:{rules:[70,71,72,73],inclusive:!1},rel_d:{rules:[70,71,72,73],inclusive:!1},rel_u:{rules:[70,71,72,73],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[70,71,72,73],inclusive:!1},node_r:{rules:[70,71,72,73],inclusive:!1},node_l:{rules:[70,71,72,73],inclusive:!1},node:{rules:[70,71,72,73],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[70,71,72,73],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[70,71,72,73],inclusive:!1},component_ext:{rules:[70,71,72,73],inclusive:!1},component_queue:{rules:[70,71,72,73],inclusive:!1},component_db:{rules:[70,71,72,73],inclusive:!1},component:{rules:[70,71,72,73],inclusive:!1},container_boundary:{rules:[70,71,72,73],inclusive:!1},container_ext_queue:{rules:[],inclusive:!1},container_ext_db:{rules:[70,71,72,73],inclusive:!1},container_ext:{rules:[70,71,72,73],inclusive:!1},container_queue:{rules:[70,71,72,73],inclusive:!1},container_db:{rules:[70,71,72,73],inclusive:!1},container:{rules:[70,71,72,73],inclusive:!1},birel:{rules:[70,71,72,73],inclusive:!1},system_boundary:{rules:[70,71,72,73],inclusive:!1},enterprise_boundary:{rules:[70,71,72,73],inclusive:!1},boundary:{rules:[70,71,72,73],inclusive:!1},system_ext_queue:{rules:[70,71,72,73],inclusive:!1},system_ext_db:{rules:[70,71,72,73],inclusive:!1},system_ext:{rules:[70,71,72,73],inclusive:!1},system_queue:{rules:[70,71,72,73],inclusive:!1},system_db:{rules:[70,71,72,73],inclusive:!1},system:{rules:[70,71,72,73],inclusive:!1},person_ext:{rules:[70,71,72,73],inclusive:!1},person:{rules:[70,71,72,73],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,86,87,88,89,90],inclusive:!0}}},t);function bt(){this.yy={}}return yt.lexer=mt,bt.prototype=yt,yt.Parser=bt,new bt}();$k.parser=$k;const Pk=$k,jk=t=>null!==t.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/);let Yk=[],zk=[""],Uk="global",Wk="",Hk=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],qk=[],Vk="",Gk=!1,Xk=4,Zk=2;var Qk;const Kk=function(t){return null==t?Yk:Yk.filter((e=>e.parentBoundary===t))},Jk=function(){return Gk},tw={addPersonOrSystem:function(t,e,n,i,r,a,s){if(null===e||null===n)return;let o={};const c=Yk.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,Yk.push(o)),o.label=null==n?{text:""}:{text:n},null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.sprite=r;if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]=e}else o.tags=a;if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.link=s;o.typeC4Shape={text:t},o.parentBoundary=Uk,o.wrap=Jk()},addPersonOrSystemBoundary:function(t,e,n,i,r){if(null===t||null===e)return;let a={};const s=Hk.find((e=>e.alias===t));if(s&&t===s.alias?a=s:(a.alias=t,Hk.push(a)),a.label=null==e?{text:""}:{text:e},null==n)a.type={text:"system"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];a[t]={text:e}}else a.type={text:n};if("object"==typeof i){let[t,e]=Object.entries(i)[0];a[t]=e}else a.tags=i;if("object"==typeof r){let[t,e]=Object.entries(r)[0];a[t]=e}else a.link=r;a.parentBoundary=Uk,a.wrap=Jk(),Wk=Uk,Uk=t,zk.push(Wk)},addContainer:function(t,e,n,i,r,a,s,o){if(null===e||null===n)return;let c={};const l=Yk.find((t=>t.alias===e));if(l&&e===l.alias?c=l:(c.alias=e,Yk.push(c)),c.label=null==n?{text:""}:{text:n},null==i)c.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];c[t]={text:e}}else c.techn={text:i};if(null==r)c.descr={text:""};else if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]={text:e}}else c.descr={text:r};if("object"==typeof a){let[t,e]=Object.entries(a)[0];c[t]=e}else c.sprite=a;if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]=e}else c.tags=s;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=Jk(),c.typeC4Shape={text:t},c.parentBoundary=Uk},addContainerBoundary:function(t,e,n,i,r){if(null===t||null===e)return;let a={};const s=Hk.find((e=>e.alias===t));if(s&&t===s.alias?a=s:(a.alias=t,Hk.push(a)),a.label=null==e?{text:""}:{text:e},null==n)a.type={text:"container"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];a[t]={text:e}}else a.type={text:n};if("object"==typeof i){let[t,e]=Object.entries(i)[0];a[t]=e}else a.tags=i;if("object"==typeof r){let[t,e]=Object.entries(r)[0];a[t]=e}else a.link=r;a.parentBoundary=Uk,a.wrap=Jk(),Wk=Uk,Uk=t,zk.push(Wk)},addComponent:function(t,e,n,i,r,a,s,o){if(null===e||null===n)return;let c={};const l=Yk.find((t=>t.alias===e));if(l&&e===l.alias?c=l:(c.alias=e,Yk.push(c)),c.label=null==n?{text:""}:{text:n},null==i)c.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];c[t]={text:e}}else c.techn={text:i};if(null==r)c.descr={text:""};else if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]={text:e}}else c.descr={text:r};if("object"==typeof a){let[t,e]=Object.entries(a)[0];c[t]=e}else c.sprite=a;if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]=e}else c.tags=s;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=Jk(),c.typeC4Shape={text:t},c.parentBoundary=Uk},addDeploymentNode:function(t,e,n,i,r,a,s,o){if(null===e||null===n)return;let c={};const l=Hk.find((t=>t.alias===e));if(l&&e===l.alias?c=l:(c.alias=e,Hk.push(c)),c.label=null==n?{text:""}:{text:n},null==i)c.type={text:"node"};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];c[t]={text:e}}else c.type={text:i};if(null==r)c.descr={text:""};else if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]={text:e}}else c.descr={text:r};if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]=e}else c.tags=s;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.nodeType=t,c.parentBoundary=Uk,c.wrap=Jk(),Wk=Uk,Uk=e,zk.push(Wk)},popBoundaryParseStack:function(){Uk=Wk,zk.pop(),Wk=zk.pop(),zk.push(Wk)},addRel:function(t,e,n,i,r,a,s,o,c){if(null==t||null==e||null==n||null==i)return;let l={};const h=qk.find((t=>t.from===e&&t.to===n));if(h?l=h:qk.push(l),l.type=t,l.from=e,l.to=n,l.label={text:i},null==r)l.techn={text:""};else if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]={text:e}}else l.techn={text:r};if(null==a)l.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]={text:e}}else l.descr={text:a};if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.sprite=s;if("object"==typeof o){let[t,e]=Object.entries(o)[0];l[t]=e}else l.tags=o;if("object"==typeof c){let[t,e]=Object.entries(c)[0];l[t]=e}else l.link=c;l.wrap=Jk()},updateElStyle:function(t,e,n,i,r,a,s,o,c,l,h){let u=Yk.find((t=>t.alias===e));if(void 0!==u||(u=Hk.find((t=>t.alias===e)),void 0!==u)){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];u[t]=e}else u.bgColor=n;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];u[t]=e}else u.fontColor=i;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];u[t]=e}else u.borderColor=r;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];u[t]=e}else u.shadowing=a;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];u[t]=e}else u.shape=s;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];u[t]=e}else u.sprite=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];u[t]=e}else u.techn=c;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];u[t]=e}else u.legendText=l;if(null!=h)if("object"==typeof h){let[t,e]=Object.entries(h)[0];u[t]=e}else u.legendSprite=h}},updateRelStyle:function(t,e,n,i,r,a,s){const o=qk.find((t=>t.from===e&&t.to===n));if(void 0!==o){if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]=e}else o.textColor=i;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.lineColor=r;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]=parseInt(e)}else o.offsetX=parseInt(a);if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=parseInt(e)}else o.offsetY=parseInt(s)}},updateLayoutConfig:function(t,e,n){let i=Xk,r=Zk;if("object"==typeof e){const t=Object.values(e)[0];i=parseInt(t)}else i=parseInt(e);if("object"==typeof n){const t=Object.values(n)[0];r=parseInt(t)}else r=parseInt(n);i>=1&&(Xk=i),r>=1&&(Zk=r)},autoWrap:Jk,setWrap:function(t){Gk=t},getC4ShapeArray:Kk,getC4Shape:function(t){return Yk.find((e=>e.alias===t))},getC4ShapeKeys:function(t){return Object.keys(Kk(t))},getBoundarys:function(t){return null==t?Hk:Hk.filter((e=>e.parentBoundary===t))},getCurrentBoundaryParse:function(){return Uk},getParentBoundaryParse:function(){return Wk},getRels:function(){return qk},getTitle:function(){return Vk},getC4Type:function(){return Qk},getC4ShapeInRow:function(){return Xk},getC4BoundaryInRow:function(){return Zk},setAccTitle:Jv,getAccTitle:tk,getAccDescription:nk,setAccDescription:ek,parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().c4,clear:function(){Yk=[],Hk=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],Wk="",Uk="global",zk=[""],qk=[],zk=[""],Vk="",Gk=!1,Xk=4,Zk=2},LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:function(t){let e=$b(t,fv());Vk=e},setC4Type:function(t){let e=$b(t,fv());Qk=e}},ew=function(t,e){const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),n.attr("rx",e.rx),n.attr("ry",e.ry),"undefined"!==e.attrs&&null!==e.attrs)for(let i in e.attrs)n.attr(i,e.attrs[i]);return"undefined"!==e.class&&n.attr("class",e.class),n},nw=function(t,e,n,i,r,a){const s=t.append("image");s.attr("width",e),s.attr("height",n),s.attr("x",i),s.attr("y",r);let o=a.startsWith("data:image/png;base64")?a:(0,Tt.N)(a);s.attr("xlink:href",o)},iw=function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},rw=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),aw=function(){function t(t,e,n,r,a,s,o){i(e.append("text").attr("x",n+a/2).attr("y",r+s/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,n,r,a,s,o,c){const{fontSize:l,fontFamily:h,fontWeight:u}=c,d=t.split(Wb.lineBreakRegex);for(let p=0;p<d.length;p++){const t=p*l-l*(d.length-1)/2,s=e.append("text").attr("x",n+a/2).attr("y",r).style("text-anchor","middle").attr("dominant-baseline","middle").style("font-size",l).style("font-weight",u).style("font-family",h);s.append("tspan").attr("dy",t).text(d[p]).attr("alignment-baseline","mathematical"),i(s,o)}}function n(t,n,r,a,s,o,c,l){const h=n.append("switch"),u=h.append("foreignObject").attr("x",r).attr("y",a).attr("width",s).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");u.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,r,a,s,0,c,l),i(u,c)}function i(t,e){for(const n in e)e.hasOwnProperty(n)&&t.attr(n,e[n])}return function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),sw=function(t,e,n){const i=t.append("g");let r=e.bgColor?e.bgColor:"none",a=e.borderColor?e.borderColor:"#444444",s=e.fontColor?e.fontColor:"black",o={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(o={"stroke-width":1});let c={x:e.x,y:e.y,fill:r,stroke:a,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:o};ew(i,c);let l=n.boundaryFont();l.fontWeight="bold",l.fontSize=l.fontSize+2,l.fontColor=s,aw(n)(e.label.text,i,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},l),e.type&&""!==e.type.text&&(l=n.boundaryFont(),l.fontColor=s,aw(n)(e.type.text,i,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},l)),e.descr&&""!==e.descr.text&&(l=n.boundaryFont(),l.fontSize=l.fontSize-2,l.fontColor=s,aw(n)(e.descr.text,i,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},l))},ow=function(t,e,n){let i=e.bgColor?e.bgColor:n[e.typeC4Shape.text+"_bg_color"],r=e.borderColor?e.borderColor:n[e.typeC4Shape.text+"_border_color"],a=e.fontColor?e.fontColor:"#FFFFFF",s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":s="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII="}const o=t.append("g");o.attr("class","person-man");const c=iw();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":c.x=e.x,c.y=e.y,c.fill=i,c.width=e.width,c.height=e.height,c.style="stroke:"+r+";stroke-width:0.5;",c.rx=2.5,c.ry=2.5,ew(o,c);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":o.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),o.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":o.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),o.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2))}let l=rw(n,e.typeC4Shape.text);switch(o.append("text").attr("fill",a).attr("font-family",l.fontFamily).attr("font-size",l.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":nw(o,48,48,e.x+e.width/2-24,e.y+e.image.Y,s)}let h=n[e.typeC4Shape.text+"Font"]();return h.fontWeight="bold",h.fontSize=h.fontSize+2,h.fontColor=a,aw(n)(e.label.text,o,e.x,e.y+e.label.Y,e.width,e.height,{fill:a},h),h=n[e.typeC4Shape.text+"Font"](),h.fontColor=a,e.thchn&&""!==e.thchn.text?aw(n)(e.thchn.text,o,e.x,e.y+e.thchn.Y,e.width,e.height,{fill:a,"font-style":"italic"},h):e.type&&""!==e.type.text&&aw(n)(e.type.text,o,e.x,e.y+e.type.Y,e.width,e.height,{fill:a,"font-style":"italic"},h),e.descr&&""!==e.descr.text&&(h=n.personFont(),h.fontColor=a,aw(n)(e.descr.text,o,e.x,e.y+e.descr.Y,e.width,e.height,{fill:a},h)),e.height},cw=(t,e,n)=>{const i=t.append("g");let r=0;for(let a of e){let t=a.textColor?a.textColor:"#444444",e=a.lineColor?a.lineColor:"#444444",s=a.offsetX?parseInt(a.offsetX):0,o=a.offsetY?parseInt(a.offsetY):0,c="";if(0===r){let t=i.append("line");t.attr("x1",a.startPoint.x),t.attr("y1",a.startPoint.y),t.attr("x2",a.endPoint.x),t.attr("y2",a.endPoint.y),t.attr("stroke-width","1"),t.attr("stroke",e),t.style("fill","none"),"rel_b"!==a.type&&t.attr("marker-end","url("+c+"#arrowhead)"),"birel"!==a.type&&"rel_b"!==a.type||t.attr("marker-start","url("+c+"#arrowend)"),r=-1}else{let t=i.append("path");t.attr("fill","none").attr("stroke-width","1").attr("stroke",e).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",a.startPoint.x).replaceAll("starty",a.startPoint.y).replaceAll("controlx",a.startPoint.x+(a.endPoint.x-a.startPoint.x)/2-(a.endPoint.x-a.startPoint.x)/4).replaceAll("controly",a.startPoint.y+(a.endPoint.y-a.startPoint.y)/2).replaceAll("stopx",a.endPoint.x).replaceAll("stopy",a.endPoint.y)),"rel_b"!==a.type&&t.attr("marker-end","url("+c+"#arrowhead)"),"birel"!==a.type&&"rel_b"!==a.type||t.attr("marker-start","url("+c+"#arrowend)")}let l=n.messageFont();aw(n)(a.label.text,i,Math.min(a.startPoint.x,a.endPoint.x)+Math.abs(a.endPoint.x-a.startPoint.x)/2+s,Math.min(a.startPoint.y,a.endPoint.y)+Math.abs(a.endPoint.y-a.startPoint.y)/2+o,a.label.width,a.label.height,{fill:t},l),a.techn&&""!==a.techn.text&&(l=n.messageFont(),aw(n)("["+a.techn.text+"]",i,Math.min(a.startPoint.x,a.endPoint.x)+Math.abs(a.endPoint.x-a.startPoint.x)/2+s,Math.min(a.startPoint.y,a.endPoint.y)+Math.abs(a.endPoint.y-a.startPoint.y)/2+n.messageFontSize+5+o,Math.max(a.label.width,a.techn.width),a.techn.height,{fill:t,"font-style":"italic"},l))}},lw=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},hw=function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},uw=function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},dw=function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},pw=function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},fw=function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},gw=function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")};Tt.N;let yw=0,mw=0,bw=4,_w=2;$k.yy=tw;let xw={};class vw{constructor(t){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,kw(t.db.getConfig())}setData(t,e,n,i){this.nextData.startx=this.data.startx=t,this.nextData.stopx=this.data.stopx=e,this.nextData.starty=this.data.starty=n,this.nextData.stopy=this.data.stopy=i}updateVal(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])}insert(t){this.nextData.cnt=this.nextData.cnt+1;let e=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+t.margin:this.nextData.stopx+2*t.margin,n=e+t.width,i=this.nextData.starty+2*t.margin,r=i+t.height;(e>=this.data.widthLimit||n>=this.data.widthLimit||this.nextData.cnt>bw)&&(e=this.nextData.startx+t.margin+xw.nextLinePaddingX,i=this.nextData.stopy+2*t.margin,this.nextData.stopx=n=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=r=i+t.height,this.nextData.cnt=1),t.x=e,t.y=i,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",i,Math.min),this.updateVal(this.data,"stopx",n,Math.max),this.updateVal(this.data,"stopy",r,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",i,Math.min),this.updateVal(this.nextData,"stopx",n,Math.max),this.updateVal(this.nextData,"stopy",r,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},kw(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}}const kw=function(t){Rx(xw,t),t.fontFamily&&(xw.personFontFamily=xw.systemFontFamily=xw.messageFontFamily=t.fontFamily),t.fontSize&&(xw.personFontSize=xw.systemFontSize=xw.messageFontSize=t.fontSize),t.fontWeight&&(xw.personFontWeight=xw.systemFontWeight=xw.messageFontWeight=t.fontWeight)},ww=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),Tw=t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight});function Cw(t,e,n,i,r){if(!e[t].width)if(n)e[t].text=Xx(e[t].text,r,i),e[t].textLines=e[t].text.split(Wb.lineBreakRegex).length,e[t].width=r,e[t].height=Qx(e[t].text,i);else{let n=e[t].text.split(Wb.lineBreakRegex);e[t].textLines=n.length;let r=0;e[t].height=0,e[t].width=0;for(const a of n)e[t].width=Math.max(Kx(a,i),e[t].width),r=Qx(a,i),e[t].height=e[t].height+r}}const Ew=function(t,e,n){e.x=n.data.startx,e.y=n.data.starty,e.width=n.data.stopx-n.data.startx,e.height=n.data.stopy-n.data.starty,e.label.y=xw.c4ShapeMargin-35;let i=e.wrap&&xw.wrap,r=Tw(xw);r.fontSize=r.fontSize+2,r.fontWeight="bold",Cw("label",e,i,r,Kx(e.label.text,r)),sw(t,e,xw)},Sw=function(t,e,n,i){let r=0;for(const a of i){r=0;const i=n[a];let s=ww(xw,i.typeC4Shape.text);switch(s.fontSize=s.fontSize-2,i.typeC4Shape.width=Kx("<<"+i.typeC4Shape.text+">>",s),i.typeC4Shape.height=s.fontSize+2,i.typeC4Shape.Y=xw.c4ShapePadding,r=i.typeC4Shape.Y+i.typeC4Shape.height-4,i.image={width:0,height:0,Y:0},i.typeC4Shape.text){case"person":case"external_person":i.image.width=48,i.image.height=48,i.image.Y=r,r=i.image.Y+i.image.height}i.sprite&&(i.image.width=48,i.image.height=48,i.image.Y=r,r=i.image.Y+i.image.height);let o=i.wrap&&xw.wrap,c=xw.width-2*xw.c4ShapePadding,l=ww(xw,i.typeC4Shape.text);if(l.fontSize=l.fontSize+2,l.fontWeight="bold",Cw("label",i,o,l,c),i.label.Y=r+8,r=i.label.Y+i.label.height,i.type&&""!==i.type.text){i.type.text="["+i.type.text+"]",Cw("type",i,o,ww(xw,i.typeC4Shape.text),c),i.type.Y=r+5,r=i.type.Y+i.type.height}else if(i.techn&&""!==i.techn.text){i.techn.text="["+i.techn.text+"]",Cw("techn",i,o,ww(xw,i.techn.text),c),i.techn.Y=r+5,r=i.techn.Y+i.techn.height}let h=r,u=i.label.width;if(i.descr&&""!==i.descr.text){Cw("descr",i,o,ww(xw,i.typeC4Shape.text),c),i.descr.Y=r+20,r=i.descr.Y+i.descr.height,u=Math.max(i.label.width,i.descr.width),h=r-5*i.descr.textLines}u+=xw.c4ShapePadding,i.width=Math.max(i.width||xw.width,u,xw.width),i.height=Math.max(i.height||xw.height,h,xw.height),i.margin=i.margin||xw.c4ShapeMargin,t.insert(i),ow(e,i,xw)}t.bumpLastMargin(xw.c4ShapeMargin)};class Aw{constructor(t,e){this.x=t,this.y=e}}let Dw=function(t,e){let n=t.x,i=t.y,r=e.x,a=e.y,s=n+t.width/2,o=i+t.height/2,c=Math.abs(n-r),l=Math.abs(i-a),h=l/c,u=t.height/t.width,d=null;return i==a&&n<r?d=new Aw(n+t.width,o):i==a&&n>r?d=new Aw(n,o):n==r&&i<a?d=new Aw(s,i+t.height):n==r&&i>a&&(d=new Aw(s,i)),n>r&&i<a?d=u>=h?new Aw(n,o+h*t.width/2):new Aw(s-c/l*t.height/2,i+t.height):n<r&&i<a?d=u>=h?new Aw(n+t.width,o+h*t.width/2):new Aw(s+c/l*t.height/2,i+t.height):n<r&&i>a?d=u>=h?new Aw(n+t.width,o-h*t.width/2):new Aw(s+t.height/2*c/l,i):n>r&&i>a&&(d=u>=h?new Aw(n,o-t.width/2*h):new Aw(s-t.height/2*c/l,i)),d},Lw=function(t,e){let n={x:0,y:0};n.x=e.x+e.width/2,n.y=e.y+e.height/2;let i=Dw(t,n);return n.x=t.x+t.width/2,n.y=t.y+t.height/2,{startPoint:i,endPoint:Dw(e,n)}};function Nw(t,e,n,i,r){let a=new vw(r);a.data.widthLimit=n.data.widthLimit/Math.min(_w,i.length);for(let[s,o]of i.entries()){let i=0;o.image={width:0,height:0,Y:0},o.sprite&&(o.image.width=48,o.image.height=48,o.image.Y=i,i=o.image.Y+o.image.height);let c=o.wrap&&xw.wrap,l=Tw(xw);if(l.fontSize=l.fontSize+2,l.fontWeight="bold",Cw("label",o,c,l,a.data.widthLimit),o.label.Y=i+8,i=o.label.Y+o.label.height,o.type&&""!==o.type.text){o.type.text="["+o.type.text+"]",Cw("type",o,c,Tw(xw),a.data.widthLimit),o.type.Y=i+5,i=o.type.Y+o.type.height}if(o.descr&&""!==o.descr.text){let t=Tw(xw);t.fontSize=t.fontSize-2,Cw("descr",o,c,t,a.data.widthLimit),o.descr.Y=i+20,i=o.descr.Y+o.descr.height}if(0==s||s%_w==0){let t=n.data.startx+xw.diagramMarginX,e=n.data.stopy+xw.diagramMarginY+i;a.setData(t,t,e,e)}else{let t=a.data.stopx!==a.data.startx?a.data.stopx+xw.diagramMarginX:a.data.startx,e=a.data.starty;a.setData(t,t,e,e)}a.name=o.alias;let h=r.db.getC4ShapeArray(o.alias),u=r.db.getC4ShapeKeys(o.alias);u.length>0&&Sw(a,t,h,u),e=o.alias;let d=r.db.getBoundarys(e);d.length>0&&Nw(t,e,a,d,r),"global"!==o.alias&&Ew(t,o,a),n.data.stopy=Math.max(a.data.stopy+xw.c4ShapeMargin,n.data.stopy),n.data.stopx=Math.max(a.data.stopx+xw.c4ShapeMargin,n.data.stopx),yw=Math.max(yw,n.data.stopx),mw=Math.max(mw,n.data.stopy)}}const Ow={drawPersonOrSystemArray:Sw,drawBoundary:Ew,setConf:kw,draw:function(t,e,n,i){xw=fv().c4;const r=fv().securityLevel;let a;"sandbox"===r&&(a=Xo("#i"+e));const s=Xo("sandbox"===r?a.nodes()[0].contentDocument.body:"body");let o=i.db;i.db.setWrap(xw.wrap),bw=o.getC4ShapeInRow(),_w=o.getC4BoundaryInRow(),Bb.debug(`C:${JSON.stringify(xw,null,2)}`);const c="sandbox"===r?s.select(`[id="${e}"]`):Xo(`[id="${e}"]`);fw(c),pw(c),gw(c);let l=new vw(i);l.setData(xw.diagramMarginX,xw.diagramMarginX,xw.diagramMarginY,xw.diagramMarginY),l.data.widthLimit=screen.availWidth,yw=xw.diagramMarginX,mw=xw.diagramMarginY;const h=i.db.getTitle();Nw(c,"",l,i.db.getBoundarys(""),i),lw(c),hw(c),dw(c),uw(c),function(t,e,n,i){let r=0;for(let s of e){r+=1;let t=s.wrap&&xw.wrap,e={fontFamily:(a=xw).messageFontFamily,fontSize:a.messageFontSize,fontWeight:a.messageFontWeight};"C4Dynamic"===i.db.getC4Type()&&(s.label.text=r+": "+s.label.text);let o=Kx(s.label.text,e);Cw("label",s,t,e,o),s.techn&&""!==s.techn.text&&(o=Kx(s.techn.text,e),Cw("techn",s,t,e,o)),s.descr&&""!==s.descr.text&&(o=Kx(s.descr.text,e),Cw("descr",s,t,e,o));let c=n(s.from),l=n(s.to),h=Lw(c,l);s.startPoint=h.startPoint,s.endPoint=h.endPoint}var a;cw(t,e,xw)}(c,i.db.getRels(),i.db.getC4Shape,i),l.data.stopx=yw,l.data.stopy=mw;const u=l.data;let d=u.stopy-u.starty+2*xw.diagramMarginY;const p=u.stopx-u.startx+2*xw.diagramMarginX;h&&c.append("text").text(h).attr("x",(u.stopx-u.startx)/2-4*xw.diagramMarginX).attr("y",u.starty+xw.diagramMarginY),vv(c,d,p,xw.useMaxWidth);const f=h?60:0;c.attr("viewBox",u.startx-xw.diagramMarginX+" -"+(xw.diagramMarginY+f)+" "+p+" "+(d+f)),Bb.debug("models:",u)}};var Bw=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,3],i=[1,7],r=[1,8],a=[1,9],s=[1,10],o=[1,13],c=[1,12],l=[1,16,25],h=[1,20],u=[1,32],d=[1,33],p=[1,34],f=[1,36],g=[1,39],y=[1,37],m=[1,38],b=[1,44],_=[1,45],x=[1,40],v=[1,41],k=[1,42],w=[1,43],T=[1,48],C=[1,49],E=[1,50],S=[1,51],A=[16,25],D=[1,65],L=[1,66],N=[1,67],O=[1,68],B=[1,69],M=[1,70],I=[1,71],F=[1,80],R=[16,25,32,45,46,54,60,61,62,63,64,65,66,71,73],$=[16,25,30,32,45,46,50,54,60,61,62,63,64,65,66,71,73,88,89,90,91],P=[5,8,9,10,11,16,19,23,25],j=[54,88,89,90,91],Y=[54,65,66,88,89,90,91],z=[54,60,61,62,63,64,88,89,90,91],U=[16,25,32],W=[1,107],H={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statments:5,direction:6,directive:7,direction_tb:8,direction_bt:9,direction_rl:10,direction_lr:11,graphConfig:12,openDirective:13,typeDirective:14,closeDirective:15,NEWLINE:16,":":17,argDirective:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,CLASS_DIAGRAM:23,statements:24,EOF:25,statement:26,className:27,alphaNumToken:28,classLiteralName:29,GENERICTYPE:30,relationStatement:31,LABEL:32,classStatement:33,methodStatement:34,annotationStatement:35,clickStatement:36,cssClassStatement:37,noteStatement:38,acc_title:39,acc_title_value:40,acc_descr:41,acc_descr_value:42,acc_descr_multiline_value:43,CLASS:44,STYLE_SEPARATOR:45,STRUCT_START:46,members:47,STRUCT_STOP:48,ANNOTATION_START:49,ANNOTATION_END:50,MEMBER:51,SEPARATOR:52,relation:53,STR:54,NOTE_FOR:55,noteText:56,NOTE:57,relationType:58,lineType:59,AGGREGATION:60,EXTENSION:61,COMPOSITION:62,DEPENDENCY:63,LOLLIPOP:64,LINE:65,DOTTED_LINE:66,CALLBACK:67,LINK:68,LINK_TARGET:69,CLICK:70,CALLBACK_NAME:71,CALLBACK_ARGS:72,HREF:73,CSSCLASS:74,commentToken:75,textToken:76,graphCodeTokens:77,textNoTagsToken:78,TAGSTART:79,TAGEND:80,"==":81,"--":82,PCT:83,DEFAULT:84,SPACE:85,MINUS:86,keywords:87,UNICODE_TEXT:88,NUM:89,ALPHA:90,BQUOTE_STR:91,$accept:0,$end:1},terminals_:{2:"error",5:"statments",8:"direction_tb",9:"direction_bt",10:"direction_rl",11:"direction_lr",16:"NEWLINE",17:":",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",23:"CLASS_DIAGRAM",25:"EOF",30:"GENERICTYPE",32:"LABEL",39:"acc_title",40:"acc_title_value",41:"acc_descr",42:"acc_descr_value",43:"acc_descr_multiline_value",44:"CLASS",45:"STYLE_SEPARATOR",46:"STRUCT_START",48:"STRUCT_STOP",49:"ANNOTATION_START",50:"ANNOTATION_END",51:"MEMBER",52:"SEPARATOR",54:"STR",55:"NOTE_FOR",57:"NOTE",60:"AGGREGATION",61:"EXTENSION",62:"COMPOSITION",63:"DEPENDENCY",64:"LOLLIPOP",65:"LINE",66:"DOTTED_LINE",67:"CALLBACK",68:"LINK",69:"LINK_TARGET",70:"CLICK",71:"CALLBACK_NAME",72:"CALLBACK_ARGS",73:"HREF",74:"CSSCLASS",77:"graphCodeTokens",79:"TAGSTART",80:"TAGEND",81:"==",82:"--",83:"PCT",84:"DEFAULT",85:"SPACE",86:"MINUS",87:"keywords",88:"UNICODE_TEXT",89:"NUM",90:"ALPHA",91:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[3,1],[3,2],[6,1],[6,1],[6,1],[6,1],[4,1],[7,4],[7,6],[13,1],[14,1],[18,1],[15,1],[12,4],[24,1],[24,2],[24,3],[27,1],[27,1],[27,2],[27,2],[27,2],[26,1],[26,2],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,2],[26,2],[26,1],[33,2],[33,4],[33,5],[33,7],[35,4],[47,1],[47,2],[34,1],[34,2],[34,1],[34,1],[31,3],[31,4],[31,4],[31,5],[38,3],[38,2],[53,3],[53,2],[53,2],[53,1],[58,1],[58,1],[58,1],[58,1],[58,1],[59,1],[59,1],[36,3],[36,4],[36,3],[36,4],[36,4],[36,5],[36,3],[36,4],[36,4],[36,5],[36,3],[36,4],[36,4],[36,5],[37,3],[75,1],[75,1],[76,1],[76,1],[76,1],[76,1],[76,1],[76,1],[76,1],[78,1],[78,1],[78,1],[78,1],[28,1],[28,1],[28,1],[29,1],[56,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 5:i.setDirection("TB");break;case 6:i.setDirection("BT");break;case 7:i.setDirection("RL");break;case 8:i.setDirection("LR");break;case 12:i.parseDirective("%%{","open_directive");break;case 13:i.parseDirective(a[o],"type_directive");break;case 14:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 15:i.parseDirective("}%%","close_directive","class");break;case 20:case 21:this.$=a[o];break;case 22:this.$=a[o-1]+a[o];break;case 23:case 24:this.$=a[o-1]+"~"+a[o];break;case 25:i.addRelation(a[o]);break;case 26:a[o-1].title=i.cleanupLabel(a[o]),i.addRelation(a[o-1]);break;case 35:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 36:case 37:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 38:i.addClass(a[o]);break;case 39:i.addClass(a[o-2]),i.setCssClass(a[o-2],a[o]);break;case 40:i.addClass(a[o-3]),i.addMembers(a[o-3],a[o-1]);break;case 41:i.addClass(a[o-5]),i.setCssClass(a[o-5],a[o-3]),i.addMembers(a[o-5],a[o-1]);break;case 42:i.addAnnotation(a[o],a[o-2]);break;case 43:this.$=[a[o]];break;case 44:a[o].push(a[o-1]),this.$=a[o];break;case 45:case 47:case 48:break;case 46:i.addMember(a[o-1],i.cleanupLabel(a[o]));break;case 49:this.$={id1:a[o-2],id2:a[o],relation:a[o-1],relationTitle1:"none",relationTitle2:"none"};break;case 50:this.$={id1:a[o-3],id2:a[o],relation:a[o-1],relationTitle1:a[o-2],relationTitle2:"none"};break;case 51:this.$={id1:a[o-3],id2:a[o],relation:a[o-2],relationTitle1:"none",relationTitle2:a[o-1]};break;case 52:this.$={id1:a[o-4],id2:a[o],relation:a[o-2],relationTitle1:a[o-3],relationTitle2:a[o-1]};break;case 53:i.addNote(a[o],a[o-1]);break;case 54:i.addNote(a[o]);break;case 55:this.$={type1:a[o-2],type2:a[o],lineType:a[o-1]};break;case 56:this.$={type1:"none",type2:a[o],lineType:a[o-1]};break;case 57:this.$={type1:a[o-1],type2:"none",lineType:a[o]};break;case 58:this.$={type1:"none",type2:"none",lineType:a[o]};break;case 59:this.$=i.relationType.AGGREGATION;break;case 60:this.$=i.relationType.EXTENSION;break;case 61:this.$=i.relationType.COMPOSITION;break;case 62:this.$=i.relationType.DEPENDENCY;break;case 63:this.$=i.relationType.LOLLIPOP;break;case 64:this.$=i.lineType.LINE;break;case 65:this.$=i.lineType.DOTTED_LINE;break;case 66:case 72:this.$=a[o-2],i.setClickEvent(a[o-1],a[o]);break;case 67:case 73:this.$=a[o-3],i.setClickEvent(a[o-2],a[o-1]),i.setTooltip(a[o-2],a[o]);break;case 68:case 76:this.$=a[o-2],i.setLink(a[o-1],a[o]);break;case 69:case 77:this.$=a[o-3],i.setLink(a[o-2],a[o-1],a[o]);break;case 70:case 78:this.$=a[o-3],i.setLink(a[o-2],a[o-1]),i.setTooltip(a[o-2],a[o]);break;case 71:case 79:this.$=a[o-4],i.setLink(a[o-3],a[o-2],a[o]),i.setTooltip(a[o-3],a[o-1]);break;case 74:this.$=a[o-3],i.setClickEvent(a[o-2],a[o-1],a[o]);break;case 75:this.$=a[o-4],i.setClickEvent(a[o-3],a[o-2],a[o-1]),i.setTooltip(a[o-3],a[o]);break;case 80:i.setCssClass(a[o-1],a[o])}},table:[{3:1,4:2,5:n,6:4,7:5,8:i,9:r,10:a,11:s,12:6,13:11,19:o,23:c},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{3:14,4:2,5:n,6:4,7:5,8:i,9:r,10:a,11:s,12:6,13:11,19:o,23:c},{1:[2,9]},e(l,[2,5]),e(l,[2,6]),e(l,[2,7]),e(l,[2,8]),{14:15,20:[1,16]},{16:[1,17]},{20:[2,12]},{1:[2,4]},{15:18,17:[1,19],22:h},e([17,22],[2,13]),{6:31,7:30,8:i,9:r,10:a,11:s,13:11,19:o,24:21,26:22,27:35,28:46,29:47,31:23,33:24,34:25,35:26,36:27,37:28,38:29,39:u,41:d,43:p,44:f,49:g,51:y,52:m,55:b,57:_,67:x,68:v,70:k,74:w,88:T,89:C,90:E,91:S},{16:[1,52]},{18:53,21:[1,54]},{16:[2,15]},{25:[1,55]},{16:[1,56],25:[2,17]},e(A,[2,25],{32:[1,57]}),e(A,[2,27]),e(A,[2,28]),e(A,[2,29]),e(A,[2,30]),e(A,[2,31]),e(A,[2,32]),e(A,[2,33]),e(A,[2,34]),{40:[1,58]},{42:[1,59]},e(A,[2,37]),e(A,[2,45],{53:60,58:63,59:64,32:[1,62],54:[1,61],60:D,61:L,62:N,63:O,64:B,65:M,66:I}),{27:72,28:46,29:47,88:T,89:C,90:E,91:S},e(A,[2,47]),e(A,[2,48]),{28:73,88:T,89:C,90:E},{27:74,28:46,29:47,88:T,89:C,90:E,91:S},{27:75,28:46,29:47,88:T,89:C,90:E,91:S},{27:76,28:46,29:47,88:T,89:C,90:E,91:S},{54:[1,77]},{27:78,28:46,29:47,88:T,89:C,90:E,91:S},{54:F,56:79},e(R,[2,20],{28:46,29:47,27:81,30:[1,82],88:T,89:C,90:E,91:S}),e(R,[2,21],{30:[1,83]}),e($,[2,94]),e($,[2,95]),e($,[2,96]),e([16,25,30,32,45,46,54,60,61,62,63,64,65,66,71,73],[2,97]),e(P,[2,10]),{15:84,22:h},{22:[2,14]},{1:[2,16]},{6:31,7:30,8:i,9:r,10:a,11:s,13:11,19:o,24:85,25:[2,18],26:22,27:35,28:46,29:47,31:23,33:24,34:25,35:26,36:27,37:28,38:29,39:u,41:d,43:p,44:f,49:g,51:y,52:m,55:b,57:_,67:x,68:v,70:k,74:w,88:T,89:C,90:E,91:S},e(A,[2,26]),e(A,[2,35]),e(A,[2,36]),{27:86,28:46,29:47,54:[1,87],88:T,89:C,90:E,91:S},{53:88,58:63,59:64,60:D,61:L,62:N,63:O,64:B,65:M,66:I},e(A,[2,46]),{59:89,65:M,66:I},e(j,[2,58],{58:90,60:D,61:L,62:N,63:O,64:B}),e(Y,[2,59]),e(Y,[2,60]),e(Y,[2,61]),e(Y,[2,62]),e(Y,[2,63]),e(z,[2,64]),e(z,[2,65]),e(A,[2,38],{45:[1,91],46:[1,92]}),{50:[1,93]},{54:[1,94]},{54:[1,95]},{71:[1,96],73:[1,97]},{28:98,88:T,89:C,90:E},{54:F,56:99},e(A,[2,54]),e(A,[2,98]),e(R,[2,22]),e(R,[2,23]),e(R,[2,24]),{16:[1,100]},{25:[2,19]},e(U,[2,49]),{27:101,28:46,29:47,88:T,89:C,90:E,91:S},{27:102,28:46,29:47,54:[1,103],88:T,89:C,90:E,91:S},e(j,[2,57],{58:104,60:D,61:L,62:N,63:O,64:B}),e(j,[2,56]),{28:105,88:T,89:C,90:E},{47:106,51:W},{27:108,28:46,29:47,88:T,89:C,90:E,91:S},e(A,[2,66],{54:[1,109]}),e(A,[2,68],{54:[1,111],69:[1,110]}),e(A,[2,72],{54:[1,112],72:[1,113]}),e(A,[2,76],{54:[1,115],69:[1,114]}),e(A,[2,80]),e(A,[2,53]),e(P,[2,11]),e(U,[2,51]),e(U,[2,50]),{27:116,28:46,29:47,88:T,89:C,90:E,91:S},e(j,[2,55]),e(A,[2,39],{46:[1,117]}),{48:[1,118]},{47:119,48:[2,43],51:W},e(A,[2,42]),e(A,[2,67]),e(A,[2,69]),e(A,[2,70],{69:[1,120]}),e(A,[2,73]),e(A,[2,74],{54:[1,121]}),e(A,[2,77]),e(A,[2,78],{69:[1,122]}),e(U,[2,52]),{47:123,51:W},e(A,[2,40]),{48:[2,44]},e(A,[2,71]),e(A,[2,75]),e(A,[2,79]),{48:[1,124]},e(A,[2,41])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],6:[2,9],13:[2,12],14:[2,4],20:[2,15],54:[2,14],55:[2,16],85:[2,19],119:[2,44]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},q=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),19;case 1:return 8;case 2:return 9;case 3:return 10;case 4:return 11;case 5:return this.begin("type_directive"),20;case 6:return this.popState(),this.begin("arg_directive"),17;case 7:return this.popState(),this.popState(),22;case 8:return 21;case 9:case 10:case 19:case 27:break;case 11:return this.begin("acc_title"),39;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),41;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:case 39:case 42:case 45:case 48:case 51:case 54:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:return 16;case 20:case 21:return 23;case 22:return this.begin("struct"),46;case 23:return"EDGE_STATE";case 24:return"EOF_IN_STRUCT";case 25:return"OPEN_IN_STRUCT";case 26:return this.popState(),48;case 28:return"MEMBER";case 29:return 44;case 30:return 74;case 31:return 67;case 32:return 68;case 33:return 70;case 34:return 55;case 35:return 57;case 36:return 49;case 37:return 50;case 38:this.begin("generic");break;case 40:return"GENERICTYPE";case 41:this.begin("string");break;case 43:return"STR";case 44:this.begin("bqstring");break;case 46:return"BQUOTE_STR";case 47:this.begin("href");break;case 49:return 73;case 50:this.begin("callback_name");break;case 52:this.popState(),this.begin("callback_args");break;case 53:return 71;case 55:return 72;case 56:case 57:case 58:case 59:return 69;case 60:case 61:return 61;case 62:case 63:return 63;case 64:return 62;case 65:return 60;case 66:return 64;case 67:return 65;case 68:return 66;case 69:return 32;case 70:return 45;case 71:return 86;case 72:return"DOT";case 73:return"PLUS";case 74:return 83;case 75:case 76:return"EQUALS";case 77:return 90;case 78:return"PUNCTUATION";case 79:return 89;case 80:return 88;case 81:return 85;case 82:return 25}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:[{])/,/^(?:\[\*\])/,/^(?:$)/,/^(?:[{])/,/^(?:[}])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:class\b)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:[~])/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[`])/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:href[\s]+["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},arg_directive:{rules:[7,8],inclusive:!1},type_directive:{rules:[6,7],inclusive:!1},open_directive:{rules:[5],inclusive:!1},callback_args:{rules:[54,55],inclusive:!1},callback_name:{rules:[51,52,53],inclusive:!1},href:{rules:[48,49],inclusive:!1},struct:{rules:[23,24,25,26,27,28],inclusive:!1},generic:{rules:[39,40],inclusive:!1},bqstring:{rules:[45,46],inclusive:!1},string:{rules:[42,43],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,23,29,30,31,32,33,34,35,36,37,38,41,44,47,50,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82],inclusive:!0}}},t);function V(){this.yy={}}return H.lexer=q,V.prototype=H,H.Parser=V,new V}();Bw.parser=Bw;const Mw=Bw,Iw=(t,e)=>{var n;return"dagre-wrapper"!==(null==(n=null==e?void 0:e.class)?void 0:n.defaultRenderer)&&null!==t.match(/^\s*classDiagram/)},Fw=(t,e)=>{var n;return null!==t.match(/^\s*classDiagram/)&&"dagre-wrapper"===(null==(n=null==e?void 0:e.class)?void 0:n.defaultRenderer)||null!==t.match(/^\s*classDiagram-v2/)},Rw="classid-";let $w=[],Pw={},jw=[],Yw=0,zw=[];const Uw=t=>Wb.sanitizeText(t,fv()),Ww=function(t){let e="",n=t;if(t.indexOf("~")>0){let i=t.split("~");n=i[0],e=Wb.sanitizeText(i[1],fv())}return{className:n,type:e}},Hw=function(t){let e=Ww(t);void 0===Pw[e.className]&&(Pw[e.className]={id:e.className,type:e.type,cssClasses:[],methods:[],members:[],annotations:[],domId:Rw+e.className+"-"+Yw},Yw++)},qw=function(t){const e=Object.keys(Pw);for(const n of e)if(Pw[n].id===t)return Pw[n].domId},Vw=function(t,e){const n=Ww(t).className,i=Pw[n];if("string"==typeof e){const t=e.trim();t.startsWith("<<")&&t.endsWith(">>")?i.annotations.push(Uw(t.substring(2,t.length-2))):t.indexOf(")")>0?i.methods.push(Uw(t)):t&&i.members.push(Uw(t))}},Gw=function(t,e){t.split(",").forEach((function(t){let n=t;t[0].match(/\d/)&&(n=Rw+n),void 0!==Pw[n]&&Pw[n].cssClasses.push(e)}))},Xw=function(t,e,n){const i=fv();let r=t,a=qw(r);if("loose"===i.securityLevel&&void 0!==e&&void 0!==Pw[r]){let t=[];if("string"==typeof n){t=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let e=0;e<t.length;e++){let n=t[e].trim();'"'===n.charAt(0)&&'"'===n.charAt(n.length-1)&&(n=n.substr(1,n.length-2)),t[e]=n}}0===t.length&&t.push(a),zw.push((function(){const n=document.querySelector(`[id="${a}"]`);null!==n&&n.addEventListener("click",(function(){rv.runFunc(e,...t)}),!1)}))}},Zw=function(t){let e=Xo(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=Xo("body").append("div").attr("class","mermaidTooltip").style("opacity",0));Xo(t).select("svg").selectAll("g.node").on("mouseover",(function(){const t=Xo(this);if(null===t.attr("title"))return;const n=this.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.text(t.attr("title")).style("left",window.scrollX+n.left+(n.right-n.left)/2+"px").style("top",window.scrollY+n.top-14+document.body.scrollTop+"px"),e.html(e.html().replace(/<br\/>/g,"<br/>")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);Xo(this).classed("hover",!1)}))};zw.push(Zw);let Qw="TB";const Kw={parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},setAccTitle:Jv,getAccTitle:tk,getAccDescription:nk,setAccDescription:ek,getConfig:()=>fv().class,addClass:Hw,bindFunctions:function(t){zw.forEach((function(e){e(t)}))},clear:function(){$w=[],Pw={},jw=[],zw=[],zw.push(Zw),Kv()},getClass:function(t){return Pw[t]},getClasses:function(){return Pw},getNotes:function(){return jw},addAnnotation:function(t,e){const n=Ww(t).className;Pw[n].annotations.push(e)},addNote:function(t,e){const n={id:`note${jw.length}`,class:e,text:t};jw.push(n)},getRelations:function(){return $w},addRelation:function(t){Bb.debug("Adding relation: "+JSON.stringify(t)),Hw(t.id1),Hw(t.id2),t.id1=Ww(t.id1).className,t.id2=Ww(t.id2).className,t.relationTitle1=Wb.sanitizeText(t.relationTitle1.trim(),fv()),t.relationTitle2=Wb.sanitizeText(t.relationTitle2.trim(),fv()),$w.push(t)},getDirection:()=>Qw,setDirection:t=>{Qw=t},addMember:Vw,addMembers:function(t,e){Array.isArray(e)&&(e.reverse(),e.forEach((e=>Vw(t,e))))},cleanupLabel:function(t){return":"===t.substring(0,1)?Wb.sanitizeText(t.substr(1).trim(),fv()):Uw(t.trim())},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},setClickEvent:function(t,e,n){t.split(",").forEach((function(t){Xw(t,e,n),Pw[t].haveCallback=!0})),Gw(t,"clickable")},setCssClass:Gw,setLink:function(t,e,n){const i=fv();t.split(",").forEach((function(t){let r=t;t[0].match(/\d/)&&(r=Rw+r),void 0!==Pw[r]&&(Pw[r].link=rv.formatUrl(e,i),"sandbox"===i.securityLevel?Pw[r].linkTarget="_top":Pw[r].linkTarget="string"==typeof n?Uw(n):"_blank")})),Gw(t,"clickable")},getTooltip:function(t){return Pw[t].tooltip},setTooltip:function(t,e){const n=fv();t.split(",").forEach((function(t){void 0!==e&&(Pw[t].tooltip=Wb.sanitizeText(e,n))}))},lookUpDomId:qw,setDiagramTitle:ik,getDiagramTitle:rk};let Jw=0;const tT=function(t){let e=t.match(/^([#+~-])?(\w+)(~\w+~|\[])?\s+(\w+) *([$*])?$/),n=t.match(/^([#+|~-])?(\w+) *\( *(.*)\) *([$*])? *(\w*[[\]|~]*\s*\w*~?)$/);return e&&!n?eT(e):n?nT(n):iT(t)},eT=function(t){let e="",n="";try{let i=t[1]?t[1].trim():"",r=t[2]?t[2].trim():"",a=t[3]?Ub(t[3].trim()):"",s=t[4]?t[4].trim():"",o=t[5]?t[5].trim():"";n=i+r+a+" "+s,e=aT(o)}catch(i){n=t}return{displayText:n,cssStyle:e}},nT=function(t){let e="",n="";try{let i=t[1]?t[1].trim():"",r=t[2]?t[2].trim():"",a=t[3]?Ub(t[3].trim()):"",s=t[4]?t[4].trim():"";n=i+r+"("+a+")"+(t[5]?" : "+Ub(t[5]).trim():""),e=aT(s)}catch(i){n=t}return{displayText:n,cssStyle:e}},iT=function(t){let e="",n="",i="",r=t.indexOf("("),a=t.indexOf(")");if(r>1&&a>r&&a<=t.length){let s="",o="",c=t.substring(0,1);c.match(/\w/)?o=t.substring(0,r).trim():(c.match(/[#+~-]/)&&(s=c),o=t.substring(1,r).trim());const l=t.substring(r+1,a);t.substring(a+1,1),n=aT(t.substring(a+1,a+2)),e=s+o+"("+Ub(l.trim())+")",a<t.length&&(i=t.substring(a+2).trim(),""!==i&&(i=" : "+Ub(i),e+=i))}else e=Ub(t);return{displayText:e,cssStyle:n}},rT=function(t,e,n,i){let r=tT(e);const a=t.append("tspan").attr("x",i.padding).text(r.displayText);""!==r.cssStyle&&a.attr("style",r.cssStyle),n||a.attr("dy",i.textHeight)},aT=function(t){switch(t){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}},sT=function(t,e,n,i){Bb.debug("Rendering class ",e,n);const r=e.id,a={id:r,label:e.id,width:0,height:0},s=t.append("g").attr("id",i.db.lookUpDomId(r)).attr("class","classGroup");let o;o=e.link?s.append("svg:a").attr("xlink:href",e.link).attr("target",e.linkTarget).append("text").attr("y",n.textHeight+n.padding).attr("x",0):s.append("text").attr("y",n.textHeight+n.padding).attr("x",0);let c=!0;e.annotations.forEach((function(t){const e=o.append("tspan").text("\xab"+t+"\xbb");c||e.attr("dy",n.textHeight),c=!1}));let l=e.id;void 0!==e.type&&""!==e.type&&(l+="<"+e.type+">");const h=o.append("tspan").text(l).attr("class","title");c||h.attr("dy",n.textHeight);const u=o.node().getBBox().height,d=s.append("line").attr("x1",0).attr("y1",n.padding+u+n.dividerMargin/2).attr("y2",n.padding+u+n.dividerMargin/2),p=s.append("text").attr("x",n.padding).attr("y",u+n.dividerMargin+n.textHeight).attr("fill","white").attr("class","classText");c=!0,e.members.forEach((function(t){rT(p,t,c,n),c=!1}));const f=p.node().getBBox(),g=s.append("line").attr("x1",0).attr("y1",n.padding+u+n.dividerMargin+f.height).attr("y2",n.padding+u+n.dividerMargin+f.height),y=s.append("text").attr("x",n.padding).attr("y",u+2*n.dividerMargin+f.height+n.textHeight).attr("fill","white").attr("class","classText");c=!0,e.methods.forEach((function(t){rT(y,t,c,n),c=!1}));const m=s.node().getBBox();var b=" ";e.cssClasses.length>0&&(b+=e.cssClasses.join(" "));const _=s.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",m.width+2*n.padding).attr("height",m.height+n.padding+.5*n.dividerMargin).attr("class",b).node().getBBox().width;return o.node().childNodes.forEach((function(t){t.setAttribute("x",(_-t.getBBox().width)/2)})),e.tooltip&&o.insert("title").text(e.tooltip),d.attr("x2",_),g.attr("x2",_),a.width=_,a.height=m.height+n.padding+.5*n.dividerMargin,a},oT=function(t,e,n,i,r){const a=function(t){switch(t){case r.db.relationType.AGGREGATION:return"aggregation";case r.db.relationType.EXTENSION:return"extension";case r.db.relationType.COMPOSITION:return"composition";case r.db.relationType.DEPENDENCY:return"dependency";case r.db.relationType.LOLLIPOP:return"lollipop"}};e.points=e.points.filter((t=>!Number.isNaN(t.y)));const s=e.points,o=Nc().x((function(t){return t.x})).y((function(t){return t.y})).curve(Rc),c=t.append("path").attr("d",o(s)).attr("id","edge"+Jw).attr("class","relation");let l,h,u="";i.arrowMarkerAbsolute&&(u=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,u=u.replace(/\(/g,"\\("),u=u.replace(/\)/g,"\\)")),1==n.relation.lineType&&c.attr("class","relation dashed-line"),10==n.relation.lineType&&c.attr("class","relation dotted-line"),"none"!==n.relation.type1&&c.attr("marker-start","url("+u+"#"+a(n.relation.type1)+"Start)"),"none"!==n.relation.type2&&c.attr("marker-end","url("+u+"#"+a(n.relation.type2)+"End)");const d=e.points.length;let p,f,g,y,m=rv.calcLabelPosition(e.points);if(l=m.x,h=m.y,d%2!=0&&d>1){let t=rv.calcCardinalityPosition("none"!==n.relation.type1,e.points,e.points[0]),i=rv.calcCardinalityPosition("none"!==n.relation.type2,e.points,e.points[d-1]);Bb.debug("cardinality_1_point "+JSON.stringify(t)),Bb.debug("cardinality_2_point "+JSON.stringify(i)),p=t.x,f=t.y,g=i.x,y=i.y}if(void 0!==n.title){const e=t.append("g").attr("class","classLabel"),r=e.append("text").attr("class","label").attr("x",l).attr("y",h).attr("fill","red").attr("text-anchor","middle").text(n.title);window.label=r;const a=r.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",a.x-i.padding/2).attr("y",a.y-i.padding/2).attr("width",a.width+i.padding).attr("height",a.height+i.padding)}if(Bb.info("Rendering relation "+JSON.stringify(n)),void 0!==n.relationTitle1&&"none"!==n.relationTitle1){t.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",p).attr("y",f).attr("fill","black").attr("font-size","6").text(n.relationTitle1)}if(void 0!==n.relationTitle2&&"none"!==n.relationTitle2){t.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",g).attr("y",y).attr("fill","black").attr("font-size","6").text(n.relationTitle2)}Jw++},cT=function(t,e,n,i){Bb.debug("Rendering note ",e,n);const r=e.id,a={id:r,text:e.text,width:0,height:0},s=t.append("g").attr("id",r).attr("class","classGroup");let o=s.append("text").attr("y",n.textHeight+n.padding).attr("x",0);const c=JSON.parse(`"${e.text}"`).split("\n");c.forEach((function(t){Bb.debug(`Adding line: ${t}`),o.append("tspan").text(t).attr("class","title").attr("dy",n.textHeight)}));const l=s.node().getBBox(),h=s.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",l.width+2*n.padding).attr("height",l.height+c.length*n.textHeight+n.padding+.5*n.dividerMargin).node().getBBox().width;return o.node().childNodes.forEach((function(t){t.setAttribute("x",(h-t.getBBox().width)/2)})),a.width=h,a.height=l.height+c.length*n.textHeight+n.padding+.5*n.dividerMargin,a};let lT={};const hT=function(t){const e=Object.entries(lT).find((e=>e[1].label===t));if(e)return e[0]},uT={draw:function(t,e,n,i){const r=fv().class;lT={},Bb.info("Rendering diagram "+t);const a=fv().securityLevel;let s;"sandbox"===a&&(s=Xo("#i"+e));const o=Xo("sandbox"===a?s.nodes()[0].contentDocument.body:"body"),c=o.select(`[id='${e}']`);var l;(l=c).append("defs").append("marker").attr("id","extensionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),l.append("defs").append("marker").attr("id","extensionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z"),l.append("defs").append("marker").attr("id","compositionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),l.append("defs").append("marker").attr("id","compositionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),l.append("defs").append("marker").attr("id","aggregationStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),l.append("defs").append("marker").attr("id","aggregationEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),l.append("defs").append("marker").attr("id","dependencyStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),l.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z");const h=new Qf({multigraph:!0});h.setGraph({isMultiGraph:!0}),h.setDefaultEdgeLabel((function(){return{}}));const u=i.db.getClasses(),d=Object.keys(u);for(const m of d){const t=u[m],e=sT(c,t,r,i);lT[e.id]=e,h.setNode(e.id,e),Bb.info("Org height: "+e.height)}i.db.getRelations().forEach((function(t){Bb.info("tjoho"+hT(t.id1)+hT(t.id2)+JSON.stringify(t)),h.setEdge(hT(t.id1),hT(t.id2),{relation:t},t.title||"DEFAULT")}));i.db.getNotes().forEach((function(t){Bb.debug(`Adding note: ${JSON.stringify(t)}`);const e=cT(c,t,r,i);lT[e.id]=e,h.setNode(e.id,e),t.class&&t.class in u&&h.setEdge(t.id,hT(t.class),{relation:{id1:t.id,id2:t.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")})),Lm(h),h.nodes().forEach((function(t){void 0!==t&&void 0!==h.node(t)&&(Bb.debug("Node "+t+": "+JSON.stringify(h.node(t))),o.select("#"+(i.db.lookUpDomId(t)||t)).attr("transform","translate("+(h.node(t).x-h.node(t).width/2)+","+(h.node(t).y-h.node(t).height/2)+" )"))})),h.edges().forEach((function(t){void 0!==t&&void 0!==h.edge(t)&&(Bb.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(h.edge(t))),oT(c,h.edge(t),h.edge(t).relation,r,i))}));const p=c.node().getBBox(),f=p.width+40,g=p.height+40;vv(c,g,f,r.useMaxWidth);const y=`${p.x-20} ${p.y-20} ${f} ${g}`;Bb.debug(`viewBox ${y}`),c.attr("viewBox",y)}},dT={extension:(t,e,n)=>{Bb.trace("Making markers for ",n),t.append("defs").append("marker").attr("id",e+"-extensionStart").attr("class","marker extension "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},composition:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-compositionStart").attr("class","marker composition "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},aggregation:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},dependency:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},lollipop:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","white").attr("cx",6).attr("cy",7).attr("r",6)},point:(t,e)=>{t.append("marker").attr("id",e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",10).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",0).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},circle:(t,e)=>{t.append("marker").attr("id",e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},cross:(t,e)=>{t.append("marker").attr("id",e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},barb:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")}},pT=(t,e,n,i)=>{e.forEach((e=>{dT[e](t,n,i)}))};const fT=(t,e,n,i)=>{let r=t||"";if("object"==typeof r&&(r=r[0]),zb(fv().flowchart.htmlLabels)){r=r.replace(/\\n|\n/g,"<br />"),Bb.info("vertexText"+r);let t=function(t){const e=Xo(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),n=e.append("xhtml:div"),i=t.label,r=t.isNode?"nodeLabel":"edgeLabel";var a,s;return n.html('<span class="'+r+'" '+(t.labelStyle?'style="'+t.labelStyle+'"':"")+">"+i+"</span>"),a=n,(s=t.labelStyle)&&a.attr("style",s),n.style("display","inline-block"),n.style("white-space","nowrap"),n.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}({isNode:i,label:pL(r).replace(/fa[blrs]?:fa-[\w-]+/g,(t=>`<i class='${t.replace(":"," ")}'></i>`)),labelStyle:e.replace("fill:","color:")});return t}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let i=[];i="string"==typeof r?r.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(r)?r:[];for(const e of i){const i=document.createElementNS("http://www.w3.org/2000/svg","tspan");i.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),i.setAttribute("dy","1em"),i.setAttribute("x","0"),n?i.setAttribute("class","title-row"):i.setAttribute("class","row"),i.textContent=e.trim(),t.appendChild(i)}return t}},gT=(t,e,n,i)=>{let r;r=n||"node default";const a=t.insert("g").attr("class",r).attr("id",e.domId||e.id),s=a.insert("g").attr("class","label").attr("style",e.labelStyle);let o;o=void 0===e.labelText?"":"string"==typeof e.labelText?e.labelText:e.labelText[0];const c=s.node().appendChild(fT($b(pL(o),fv()),e.labelStyle,!1,i));let l=c.getBBox();if(zb(fv().flowchart.htmlLabels)){const t=c.children[0],e=Xo(c);l=t.getBoundingClientRect(),e.attr("width",l.width),e.attr("height",l.height)}const h=e.padding/2;return s.attr("transform","translate("+-l.width/2+", "+-l.height/2+")"),{shapeSvg:a,bbox:l,halfPadding:h,label:s}},yT=(t,e)=>{const n=e.node().getBBox();t.width=n.width,t.height=n.height};function mT(t,e,n,i){return t.insert("polygon",":first-child").attr("points",i.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+n/2+")")}let bT={},_T={},xT={};const vT=(t,e)=>(Bb.trace("In isDecendant",e," ",t," = ",_T[e].includes(t)),!!_T[e].includes(t)),kT=(t,e,n,i)=>{Bb.warn("Copying children of ",t,"root",i,"data",e.node(t),i);const r=e.children(t)||[];t!==i&&r.push(t),Bb.warn("Copying (nodes) clusterId",t,"nodes",r),r.forEach((r=>{if(e.children(r).length>0)kT(r,e,n,i);else{const a=e.node(r);Bb.info("cp ",r," to ",i," with parent ",t),n.setNode(r,a),i!==e.parent(r)&&(Bb.warn("Setting parent",r,e.parent(r)),n.setParent(r,e.parent(r))),t!==i&&r!==t?(Bb.debug("Setting parent",r,t),n.setParent(r,t)):(Bb.info("In copy ",t,"root",i,"data",e.node(t),i),Bb.debug("Not Setting parent for node=",r,"cluster!==rootId",t!==i,"node!==clusterId",r!==t));const s=e.edges(r);Bb.debug("Copying Edges",s),s.forEach((r=>{Bb.info("Edge",r);const a=e.edge(r.v,r.w,r.name);Bb.info("Edge data",a,i);try{((t,e)=>(Bb.info("Decendants of ",e," is ",_T[e]),Bb.info("Edge is ",t),t.v!==e&&t.w!==e&&(_T[e]?_T[e].includes(t.v)||vT(t.v,e)||vT(t.w,e)||_T[e].includes(t.w):(Bb.debug("Tilt, ",e,",not in decendants"),!1))))(r,i)?(Bb.info("Copying as ",r.v,r.w,a,r.name),n.setEdge(r.v,r.w,a,r.name),Bb.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):Bb.info("Skipping copy of edge ",r.v,"--\x3e",r.w," rootId: ",i," clusterId:",t)}catch(s){Bb.error(s)}}))}Bb.debug("Removing node",r),e.removeNode(r)}))},wT=(t,e)=>{const n=e.children(t);let i=[...n];for(const r of n)xT[r]=t,i=[...i,...wT(r,e)];return i},TT=(t,e)=>{Bb.trace("Searching",t);const n=e.children(t);if(Bb.trace("Searching children of id ",t,n),n.length<1)return Bb.trace("This is a valid node",t),t;for(const i of n){const n=TT(i,e);if(n)return Bb.trace("Found replacement for",t," => ",n),n}},CT=t=>bT[t]&&bT[t].externalConnections&&bT[t]?bT[t].id:t,ET=(t,e)=>{if(Bb.warn("extractor - ",e,bb(t),t.children("D")),e>10)return void Bb.error("Bailing out");let n=t.nodes(),i=!1;for(const r of n){const e=t.children(r);i=i||e.length>0}if(i){Bb.debug("Nodes = ",n,e);for(const i of n)if(Bb.debug("Extracting node",i,bT,bT[i]&&!bT[i].externalConnections,!t.parent(i),t.node(i),t.children("D")," Depth ",e),bT[i])if(!bT[i].externalConnections&&t.children(i)&&t.children(i).length>0){Bb.warn("Cluster without external connections, without a parent and with children",i,e);let n="TB"===t.graph().rankdir?"LR":"TB";bT[i]&&bT[i].clusterData&&bT[i].clusterData.dir&&(n=bT[i].clusterData.dir,Bb.warn("Fixing dir",bT[i].clusterData.dir,n));const r=new Qf({multigraph:!0,compound:!0}).setGraph({rankdir:n,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));Bb.warn("Old graph before copy",bb(t)),kT(i,t,r,i),t.setNode(i,{clusterNode:!0,id:i,clusterData:bT[i].clusterData,labelText:bT[i].labelText,graph:r}),Bb.warn("New graph after copy node: (",i,")",bb(r)),Bb.debug("Old graph after copy",bb(t))}else Bb.warn("Cluster ** ",i," **not meeting the criteria !externalConnections:",!bT[i].externalConnections," no parent: ",!t.parent(i)," children ",t.children(i)&&t.children(i).length>0,t.children("D"),e),Bb.debug(bT);else Bb.debug("Not a cluster",i,e);n=t.nodes(),Bb.warn("New list of nodes",n);for(const i of n){const n=t.node(i);Bb.warn(" Now next level",i,n),n.clusterNode&&ET(n.graph,e+1)}}else Bb.debug("Done, no node has children",t.nodes())},ST=(t,e)=>{if(0===e.length)return[];let n=Object.assign(e);return e.forEach((e=>{const i=t.children(e),r=ST(t,i);n=[...n,...r]})),n};function AT(t,e,n,i){var r=t.x,a=t.y,s=r-i.x,o=a-i.y,c=Math.sqrt(e*e*o*o+n*n*s*s),l=Math.abs(e*n*s/c);i.x<r&&(l=-l);var h=Math.abs(e*n*o/c);return i.y<a&&(h=-h),{x:r+l,y:a+h}}function DT(t,e,n,i){var r,a,s,o,c,l,h,u,d,p,f,g,y;if(r=e.y-t.y,s=t.x-e.x,c=e.x*t.y-t.x*e.y,d=r*n.x+s*n.y+c,p=r*i.x+s*i.y+c,!(0!==d&&0!==p&<(d,p)||(a=i.y-n.y,o=n.x-i.x,l=i.x*n.y-n.x*i.y,h=a*t.x+o*t.y+l,u=a*e.x+o*e.y+l,0!==h&&0!==u&<(h,u)||0==(f=r*o-a*s))))return g=Math.abs(f/2),{x:(y=s*l-o*c)<0?(y-g)/f:(y+g)/f,y:(y=a*c-r*l)<0?(y-g)/f:(y+g)/f}}function LT(t,e){return t*e>0}const NT=(t,e)=>{var n,i,r=t.x,a=t.y,s=e.x-r,o=e.y-a,c=t.width/2,l=t.height/2;return Math.abs(o)*c>Math.abs(s)*l?(o<0&&(l=-l),n=0===o?0:l*s/o,i=l):(s<0&&(c=-c),n=c,i=0===s?0:c*o/s),{x:r+n,y:a+i}},OT={node:function(t,e){return t.intersect(e)},circle:function(t,e,n){return AT(t,e,e,n)},ellipse:AT,polygon:function(t,e,n){var i=t.x,r=t.y,a=[],s=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){s=Math.min(s,t.x),o=Math.min(o,t.y)})):(s=Math.min(s,e.x),o=Math.min(o,e.y));for(var c=i-t.width/2-s,l=r-t.height/2-o,h=0;h<e.length;h++){var u=e[h],d=e[h<e.length-1?h+1:0],p=DT(t,n,{x:c+u.x,y:l+u.y},{x:c+d.x,y:l+d.y});p&&a.push(p)}return a.length?(a.length>1&&a.sort((function(t,e){var i=t.x-n.x,r=t.y-n.y,a=Math.sqrt(i*i+r*r),s=e.x-n.x,o=e.y-n.y,c=Math.sqrt(s*s+o*o);return a<c?-1:a===c?0:1})),a[0]):t},rect:NT},BT=(t,e)=>{const{shapeSvg:n,bbox:i,halfPadding:r}=gT(t,e,"node "+e.classes,!0);Bb.info("Classes = ",e.classes);const a=n.insert("rect",":first-child");return a.attr("rx",e.rx).attr("ry",e.ry).attr("x",-i.width/2-r).attr("y",-i.height/2-r).attr("width",i.width+e.padding).attr("height",i.height+e.padding),yT(e,a),e.intersect=function(t){return OT.rect(e,t)},n};function MT(t,e,n,i){const r=[],a=t=>{r.push(t,0)},s=t=>{r.push(0,t)};e.includes("t")?(Bb.debug("add top border"),a(n)):s(n),e.includes("r")?(Bb.debug("add right border"),a(i)):s(i),e.includes("b")?(Bb.debug("add bottom border"),a(n)):s(n),e.includes("l")?(Bb.debug("add left border"),a(i)):s(i),t.attr("stroke-dasharray",r.join(" "))}const IT=(t,e,n)=>{const i=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let r=70,a=10;"LR"===n&&(r=10,a=70);const s=i.append("rect").attr("x",-1*r/2).attr("y",-1*a/2).attr("width",r).attr("height",a).attr("class","fork-join");return yT(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return OT.rect(e,t)},i},FT={question:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding+(i.height+e.padding),a=[{x:r/2,y:0},{x:r,y:-r/2},{x:r/2,y:-r},{x:0,y:-r/2}];Bb.info("Question main (Circle)");const s=mT(n,r,r,a);return s.attr("style",e.style),yT(e,s),e.intersect=function(t){return Bb.warn("Intersect called"),OT.polygon(e,a,t)},n},rect:(t,e)=>{const{shapeSvg:n,bbox:i,halfPadding:r}=gT(t,e,"node "+e.classes,!0);Bb.trace("Classes = ",e.classes);const a=n.insert("rect",":first-child"),s=i.width+e.padding,o=i.height+e.padding;if(a.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",-i.width/2-r).attr("y",-i.height/2-r).attr("width",s).attr("height",o),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(MT(a,e.props.borders,s,o),t.delete("borders")),t.forEach((t=>{Bb.warn(`Unknown node property ${t}`)}))}return yT(e,a),e.intersect=function(t){return OT.rect(e,t)},n},labelRect:(t,e)=>{const{shapeSvg:n}=gT(t,e,"label",!0);Bb.trace("Classes = ",e.classes);const i=n.insert("rect",":first-child");if(i.attr("width",0).attr("height",0),n.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(MT(i,e.props.borders,0,0),t.delete("borders")),t.forEach((t=>{Bb.warn(`Unknown node property ${t}`)}))}return yT(e,i),e.intersect=function(t){return OT.rect(e,t)},n},rectWithTitle:(t,e)=>{let n;n=e.classes?"node "+e.classes:"node default";const i=t.insert("g").attr("class",n).attr("id",e.domId||e.id),r=i.insert("rect",":first-child"),a=i.insert("line"),s=i.insert("g").attr("class","label"),o=e.labelText.flat?e.labelText.flat():e.labelText;let c="";c="object"==typeof o?o[0]:o,Bb.info("Label text abc79",c,o,"object"==typeof o);const l=s.node().appendChild(fT(c,e.labelStyle,!0,!0));let h={width:0,height:0};if(zb(fv().flowchart.htmlLabels)){const t=l.children[0],e=Xo(l);h=t.getBoundingClientRect(),e.attr("width",h.width),e.attr("height",h.height)}Bb.info("Text 2",o);const u=o.slice(1,o.length);let d=l.getBBox();const p=s.node().appendChild(fT(u.join?u.join("<br/>"):u,e.labelStyle,!0,!0));if(zb(fv().flowchart.htmlLabels)){const t=p.children[0],e=Xo(p);h=t.getBoundingClientRect(),e.attr("width",h.width),e.attr("height",h.height)}const f=e.padding/2;return Xo(p).attr("transform","translate( "+(h.width>d.width?0:(d.width-h.width)/2)+", "+(d.height+f+5)+")"),Xo(l).attr("transform","translate( "+(h.width<d.width?0:-(d.width-h.width)/2)+", 0)"),h=s.node().getBBox(),s.attr("transform","translate("+-h.width/2+", "+(-h.height/2-f+3)+")"),r.attr("class","outer title-state").attr("x",-h.width/2-f).attr("y",-h.height/2-f).attr("width",h.width+e.padding).attr("height",h.height+e.padding),a.attr("class","divider").attr("x1",-h.width/2-f).attr("x2",h.width/2+f).attr("y1",-h.height/2-f+d.height+f).attr("y2",-h.height/2-f+d.height+f),yT(e,r),e.intersect=function(t){return OT.rect(e,t)},i},choice:(t,e)=>{const n=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),i=[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}];return n.insert("polygon",":first-child").attr("points",i.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return OT.circle(e,14,t)},n},circle:(t,e)=>{const{shapeSvg:n,bbox:i,halfPadding:r}=gT(t,e,void 0,!0),a=n.insert("circle",":first-child");return a.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",i.width/2+r).attr("width",i.width+e.padding).attr("height",i.height+e.padding),Bb.info("Circle main"),yT(e,a),e.intersect=function(t){return Bb.info("Circle intersect",e,i.width/2+r,t),OT.circle(e,i.width/2+r,t)},n},doublecircle:(t,e)=>{const{shapeSvg:n,bbox:i,halfPadding:r}=gT(t,e,void 0,!0),a=n.insert("g",":first-child"),s=a.insert("circle"),o=a.insert("circle");return s.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",i.width/2+r+5).attr("width",i.width+e.padding+10).attr("height",i.height+e.padding+10),o.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",i.width/2+r).attr("width",i.width+e.padding).attr("height",i.height+e.padding),Bb.info("DoubleCircle main"),yT(e,s),e.intersect=function(t){return Bb.info("DoubleCircle intersect",e,i.width/2+r+5,t),OT.circle(e,i.width/2+r+5,t)},n},stadium:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.height+e.padding,a=i.width+r/4+e.padding,s=n.insert("rect",":first-child").attr("style",e.style).attr("rx",r/2).attr("ry",r/2).attr("x",-a/2).attr("y",-r/2).attr("width",a).attr("height",r);return yT(e,s),e.intersect=function(t){return OT.rect(e,t)},n},hexagon:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.height+e.padding,a=r/4,s=i.width+2*a+e.padding,o=[{x:a,y:0},{x:s-a,y:0},{x:s,y:-r/2},{x:s-a,y:-r},{x:a,y:-r},{x:0,y:-r/2}],c=mT(n,s,r,o);return c.attr("style",e.style),yT(e,c),e.intersect=function(t){return OT.polygon(e,o,t)},n},rect_left_inv_arrow:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding,a=i.height+e.padding,s=[{x:-a/2,y:0},{x:r,y:0},{x:r,y:-a},{x:-a/2,y:-a},{x:0,y:-a/2}];return mT(n,r,a,s).attr("style",e.style),e.width=r+a,e.height=a,e.intersect=function(t){return OT.polygon(e,s,t)},n},lean_right:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding,a=i.height+e.padding,s=[{x:-2*a/6,y:0},{x:r-a/6,y:0},{x:r+2*a/6,y:-a},{x:a/6,y:-a}],o=mT(n,r,a,s);return o.attr("style",e.style),yT(e,o),e.intersect=function(t){return OT.polygon(e,s,t)},n},lean_left:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding,a=i.height+e.padding,s=[{x:2*a/6,y:0},{x:r+a/6,y:0},{x:r-2*a/6,y:-a},{x:-a/6,y:-a}],o=mT(n,r,a,s);return o.attr("style",e.style),yT(e,o),e.intersect=function(t){return OT.polygon(e,s,t)},n},trapezoid:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding,a=i.height+e.padding,s=[{x:-2*a/6,y:0},{x:r+2*a/6,y:0},{x:r-a/6,y:-a},{x:a/6,y:-a}],o=mT(n,r,a,s);return o.attr("style",e.style),yT(e,o),e.intersect=function(t){return OT.polygon(e,s,t)},n},inv_trapezoid:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding,a=i.height+e.padding,s=[{x:a/6,y:0},{x:r-a/6,y:0},{x:r+2*a/6,y:-a},{x:-2*a/6,y:-a}],o=mT(n,r,a,s);return o.attr("style",e.style),yT(e,o),e.intersect=function(t){return OT.polygon(e,s,t)},n},rect_right_inv_arrow:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding,a=i.height+e.padding,s=[{x:0,y:0},{x:r+a/2,y:0},{x:r,y:-a/2},{x:r+a/2,y:-a},{x:0,y:-a}],o=mT(n,r,a,s);return o.attr("style",e.style),yT(e,o),e.intersect=function(t){return OT.polygon(e,s,t)},n},cylinder:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding,a=r/2,s=a/(2.5+r/50),o=i.height+s+e.padding,c="M 0,"+s+" a "+a+","+s+" 0,0,0 "+r+" 0 a "+a+","+s+" 0,0,0 "+-r+" 0 l 0,"+o+" a "+a+","+s+" 0,0,0 "+r+" 0 l 0,"+-o,l=n.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",c).attr("transform","translate("+-r/2+","+-(o/2+s)+")");return yT(e,l),e.intersect=function(t){const n=OT.rect(e,t),i=n.x-e.x;if(0!=a&&(Math.abs(i)<e.width/2||Math.abs(i)==e.width/2&&Math.abs(n.y-e.y)>e.height/2-s)){let r=s*s*(1-i*i/(a*a));0!=r&&(r=Math.sqrt(r)),r=s-r,t.y-e.y>0&&(r=-r),n.y+=r}return n},n},start:(t,e)=>{const n=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),i=n.insert("circle",":first-child");return i.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),yT(e,i),e.intersect=function(t){return OT.circle(e,7,t)},n},end:(t,e)=>{const n=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),i=n.insert("circle",":first-child"),r=n.insert("circle",":first-child");return r.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),i.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),yT(e,r),e.intersect=function(t){return OT.circle(e,7,t)},n},note:BT,subroutine:(t,e)=>{const{shapeSvg:n,bbox:i}=gT(t,e,void 0,!0),r=i.width+e.padding,a=i.height+e.padding,s=[{x:0,y:0},{x:r,y:0},{x:r,y:-a},{x:0,y:-a},{x:0,y:0},{x:-8,y:0},{x:r+8,y:0},{x:r+8,y:-a},{x:-8,y:-a},{x:-8,y:0}],o=mT(n,r,a,s);return o.attr("style",e.style),yT(e,o),e.intersect=function(t){return OT.polygon(e,s,t)},n},fork:IT,join:IT,class_box:(t,e)=>{const n=e.padding/2;let i;i=e.classes?"node "+e.classes:"node default";const r=t.insert("g").attr("class",i).attr("id",e.domId||e.id),a=r.insert("rect",":first-child"),s=r.insert("line"),o=r.insert("line");let c=0,l=4;const h=r.insert("g").attr("class","label");let u=0;const d=e.classData.annotations&&e.classData.annotations[0],p=e.classData.annotations[0]?"\xab"+e.classData.annotations[0]+"\xbb":"",f=h.node().appendChild(fT(p,e.labelStyle,!0,!0));let g=f.getBBox();if(zb(fv().flowchart.htmlLabels)){const t=f.children[0],e=Xo(f);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}e.classData.annotations[0]&&(l+=g.height+4,c+=g.width);let y=e.classData.id;void 0!==e.classData.type&&""!==e.classData.type&&(fv().flowchart.htmlLabels?y+="<"+e.classData.type+">":y+="<"+e.classData.type+">");const m=h.node().appendChild(fT(y,e.labelStyle,!0,!0));Xo(m).attr("class","classTitle");let b=m.getBBox();if(zb(fv().flowchart.htmlLabels)){const t=m.children[0],e=Xo(m);b=t.getBoundingClientRect(),e.attr("width",b.width),e.attr("height",b.height)}l+=b.height+4,b.width>c&&(c=b.width);const _=[];e.classData.members.forEach((t=>{const n=tT(t);let i=n.displayText;fv().flowchart.htmlLabels&&(i=i.replace(/</g,"<").replace(/>/g,">"));const r=h.node().appendChild(fT(i,n.cssStyle?n.cssStyle:e.labelStyle,!0,!0));let a=r.getBBox();if(zb(fv().flowchart.htmlLabels)){const t=r.children[0],e=Xo(r);a=t.getBoundingClientRect(),e.attr("width",a.width),e.attr("height",a.height)}a.width>c&&(c=a.width),l+=a.height+4,_.push(r)})),l+=8;const x=[];if(e.classData.methods.forEach((t=>{const n=tT(t);let i=n.displayText;fv().flowchart.htmlLabels&&(i=i.replace(/</g,"<").replace(/>/g,">"));const r=h.node().appendChild(fT(i,n.cssStyle?n.cssStyle:e.labelStyle,!0,!0));let a=r.getBBox();if(zb(fv().flowchart.htmlLabels)){const t=r.children[0],e=Xo(r);a=t.getBoundingClientRect(),e.attr("width",a.width),e.attr("height",a.height)}a.width>c&&(c=a.width),l+=a.height+4,x.push(r)})),l+=8,d){let t=(c-g.width)/2;Xo(f).attr("transform","translate( "+(-1*c/2+t)+", "+-1*l/2+")"),u=g.height+4}let v=(c-b.width)/2;return Xo(m).attr("transform","translate( "+(-1*c/2+v)+", "+(-1*l/2+u)+")"),u+=b.height+4,s.attr("class","divider").attr("x1",-c/2-n).attr("x2",c/2+n).attr("y1",-l/2-n+8+u).attr("y2",-l/2-n+8+u),u+=8,_.forEach((t=>{Xo(t).attr("transform","translate( "+-c/2+", "+(-1*l/2+u+4)+")"),u+=b.height+4})),u+=8,o.attr("class","divider").attr("x1",-c/2-n).attr("x2",c/2+n).attr("y1",-l/2-n+8+u).attr("y2",-l/2-n+8+u),u+=8,x.forEach((t=>{Xo(t).attr("transform","translate( "+-c/2+", "+(-1*l/2+u)+")"),u+=b.height+4})),a.attr("class","outer title-state").attr("x",-c/2-n).attr("y",-l/2-n).attr("width",c+e.padding).attr("height",l+e.padding),yT(e,a),e.intersect=function(t){return OT.rect(e,t)},r}};let RT={};const $T=t=>{const e=RT[t.id];Bb.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const n=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+n-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),n},PT={rect:(t,e)=>{Bb.trace("Creating subgraph rect for ",e.id,e);const n=t.insert("g").attr("class","cluster"+(e.class?" "+e.class:"")).attr("id",e.id),i=n.insert("rect",":first-child"),r=n.insert("g").attr("class","cluster-label"),a=r.node().appendChild(fT(e.labelText,e.labelStyle,void 0,!0));let s=a.getBBox();if(zb(fv().flowchart.htmlLabels)){const t=a.children[0],e=Xo(a);s=t.getBoundingClientRect(),e.attr("width",s.width),e.attr("height",s.height)}const o=0*e.padding,c=o/2,l=e.width<=s.width+o?s.width+o:e.width;e.width<=s.width+o?e.diff=(s.width-e.width)/2-e.padding/2:e.diff=-e.padding/2,Bb.trace("Data ",e,JSON.stringify(e)),i.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-l/2).attr("y",e.y-e.height/2-c).attr("width",l).attr("height",e.height+o),r.attr("transform","translate("+(e.x-s.width/2)+", "+(e.y-e.height/2)+")");const h=i.node().getBBox();return e.width=h.width,e.height=h.height,e.intersect=function(t){return NT(e,t)},n},roundedWithTitle:(t,e)=>{const n=t.insert("g").attr("class",e.classes).attr("id",e.id),i=n.insert("rect",":first-child"),r=n.insert("g").attr("class","cluster-label"),a=n.append("rect"),s=r.node().appendChild(fT(e.labelText,e.labelStyle,void 0,!0));let o=s.getBBox();if(zb(fv().flowchart.htmlLabels)){const t=s.children[0],e=Xo(s);o=t.getBoundingClientRect(),e.attr("width",o.width),e.attr("height",o.height)}o=s.getBBox();const c=0*e.padding,l=c/2,h=e.width<=o.width+e.padding?o.width+e.padding:e.width;e.width<=o.width+e.padding?e.diff=(o.width+0*e.padding-e.width)/2:e.diff=-e.padding/2,i.attr("class","outer").attr("x",e.x-h/2-l).attr("y",e.y-e.height/2-l).attr("width",h+c).attr("height",e.height+c),a.attr("class","inner").attr("x",e.x-h/2-l).attr("y",e.y-e.height/2-l+o.height-1).attr("width",h+c).attr("height",e.height+c-o.height-3),r.attr("transform","translate("+(e.x-o.width/2)+", "+(e.y-e.height/2-e.padding/3+(zb(fv().flowchart.htmlLabels)?5:3))+")");const u=i.node().getBBox();return e.height=u.height,e.intersect=function(t){return NT(e,t)},n},noteGroup:(t,e)=>{const n=t.insert("g").attr("class","note-cluster").attr("id",e.id),i=n.insert("rect",":first-child"),r=0*e.padding,a=r/2;i.attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2-a).attr("width",e.width+r).attr("height",e.height+r).attr("fill","none");const s=i.node().getBBox();return e.width=s.width,e.height=s.height,e.intersect=function(t){return NT(e,t)},n},divider:(t,e)=>{const n=t.insert("g").attr("class",e.classes).attr("id",e.id),i=n.insert("rect",":first-child"),r=0*e.padding,a=r/2;i.attr("class","divider").attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2).attr("width",e.width+r).attr("height",e.height+r);const s=i.node().getBBox();return e.width=s.width,e.height=s.height,e.diff=-e.padding/2,e.intersect=function(t){return NT(e,t)},n}};let jT={};let YT={},zT={};function UT(t,e){fv().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}const WT=(t,e)=>{Bb.warn("abc88 cutPathAtIntersect",t,e);let n=[],i=t[0],r=!1;return t.forEach((t=>{if(Bb.info("abc88 checking point",t,e),((t,e)=>{const n=t.x,i=t.y,r=Math.abs(e.x-n),a=Math.abs(e.y-i),s=t.width/2,o=t.height/2;return r>=s||a>=o})(e,t)||r)Bb.warn("abc88 outside",t,i),i=t,r||n.push(t);else{const a=((t,e,n)=>{Bb.warn(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(n)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const i=t.x,r=t.y,a=Math.abs(i-n.x),s=t.width/2;let o=n.x<e.x?s-a:s+a;const c=t.height/2,l=Math.abs(e.y-n.y),h=Math.abs(e.x-n.x);if(Math.abs(r-e.y)*s>Math.abs(i-e.x)*c){let t=n.y<e.y?e.y-c-r:r-c-e.y;o=h*t/l;const i={x:n.x<e.x?n.x+o:n.x-h+o,y:n.y<e.y?n.y+l-t:n.y-l+t};return 0===o&&(i.x=e.x,i.y=e.y),0===h&&(i.x=e.x),0===l&&(i.y=e.y),Bb.warn(`abc89 topp/bott calc, Q ${l}, q ${t}, R ${h}, r ${o}`,i),i}{o=n.x<e.x?e.x-s-i:i-s-e.x;let t=l*o/h,r=n.x<e.x?n.x+h-o:n.x-h+o,a=n.y<e.y?n.y+t:n.y-t;return Bb.warn(`sides calc abc89, Q ${l}, q ${t}, R ${h}, r ${o}`,{_x:r,_y:a}),0===o&&(r=e.x,a=e.y),0===h&&(r=e.x),0===l&&(a=e.y),{x:r,y:a}}})(e,i,t);Bb.warn("abc88 inside",t,i,a),Bb.warn("abc88 intersection",a);let s=!1;n.forEach((t=>{s=s||t.x===a.x&&t.y===a.y})),n.some((t=>t.x===a.x&&t.y===a.y))?Bb.warn("abc88 no intersect",a,n):n.push(a),r=!0}})),Bb.warn("abc88 returning points",n),n},HT=(t,e,n,i)=>{Bb.info("Graph in recursive render: XXX",bb(e),i);const r=e.graph().rankdir;Bb.trace("Dir in recursive render - dir:",r);const a=t.insert("g").attr("class","root");e.nodes()?Bb.info("Recursive render XXX",e.nodes()):Bb.info("No nodes found for",e),e.edges().length>0&&Bb.trace("Recursive edges",e.edge(e.edges()[0]));const s=a.insert("g").attr("class","clusters"),o=a.insert("g").attr("class","edgePaths"),c=a.insert("g").attr("class","edgeLabels"),l=a.insert("g").attr("class","nodes");e.nodes().forEach((function(t){const a=e.node(t);if(void 0!==i){const n=JSON.parse(JSON.stringify(i.clusterData));Bb.info("Setting data for cluster XXX (",t,") ",n,i),e.setNode(i.id,n),e.parent(t)||(Bb.trace("Setting parent",t,i.id),e.setParent(t,i.id,n))}if(Bb.info("(Insert) Node XXX"+t+": "+JSON.stringify(e.node(t))),a&&a.clusterNode){Bb.info("Cluster identified",t,a.width,e.node(t));const i=HT(l,a.graph,n,e.node(t)),r=i.elem;yT(a,r),a.diff=i.diff||0,Bb.info("Node bounds (abc123)",t,a,a.width,a.x,a.y),((t,e)=>{RT[e.id]=t})(r,a),Bb.warn("Recursive render complete ",r,a)}else e.children(t).length>0?(Bb.info("Cluster - the non recursive path XXX",t,a.id,a,e),Bb.info(TT(a.id,e)),bT[a.id]={id:TT(a.id,e),node:a}):(Bb.info("Node - the non recursive path",t,a.id,a),((t,e,n)=>{let i,r;if(e.link){let a;"sandbox"===fv().securityLevel?a="_top":e.linkTarget&&(a=e.linkTarget||"_blank"),i=t.insert("svg:a").attr("xlink:href",e.link).attr("target",a),r=FT[e.shape](i,e,n)}else r=FT[e.shape](t,e,n),i=r;e.tooltip&&r.attr("title",e.tooltip),e.class&&r.attr("class","node default "+e.class),RT[e.id]=i,e.haveCallback&&RT[e.id].attr("class",RT[e.id].attr("class")+" clickable")})(l,e.node(t),r))})),e.edges().forEach((function(t){const n=e.edge(t.v,t.w,t.name);Bb.info("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t)),Bb.info("Edge "+t.v+" -> "+t.w+": ",t," ",JSON.stringify(e.edge(t))),Bb.info("Fix",bT,"ids:",t.v,t.w,"Translateing: ",bT[t.v],bT[t.w]),((t,e)=>{const n=fT(e.label,e.labelStyle),i=t.insert("g").attr("class","edgeLabel"),r=i.insert("g").attr("class","label");r.node().appendChild(n);let a,s=n.getBBox();if(zb(fv().flowchart.htmlLabels)){const t=n.children[0],e=Xo(n);s=t.getBoundingClientRect(),e.attr("width",s.width),e.attr("height",s.height)}if(r.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),YT[e.id]=i,e.width=s.width,e.height=s.height,e.startLabelLeft){const n=fT(e.startLabelLeft,e.labelStyle),i=t.insert("g").attr("class","edgeTerminals"),r=i.insert("g").attr("class","inner");a=r.node().appendChild(n);const s=n.getBBox();r.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),zT[e.id]||(zT[e.id]={}),zT[e.id].startLeft=i,UT(a,e.startLabelLeft)}if(e.startLabelRight){const n=fT(e.startLabelRight,e.labelStyle),i=t.insert("g").attr("class","edgeTerminals"),r=i.insert("g").attr("class","inner");a=i.node().appendChild(n),r.node().appendChild(n);const s=n.getBBox();r.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),zT[e.id]||(zT[e.id]={}),zT[e.id].startRight=i,UT(a,e.startLabelRight)}if(e.endLabelLeft){const n=fT(e.endLabelLeft,e.labelStyle),i=t.insert("g").attr("class","edgeTerminals"),r=i.insert("g").attr("class","inner");a=r.node().appendChild(n);const s=n.getBBox();r.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),i.node().appendChild(n),zT[e.id]||(zT[e.id]={}),zT[e.id].endLeft=i,UT(a,e.endLabelLeft)}if(e.endLabelRight){const n=fT(e.endLabelRight,e.labelStyle),i=t.insert("g").attr("class","edgeTerminals"),r=i.insert("g").attr("class","inner");a=r.node().appendChild(n);const s=n.getBBox();r.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),i.node().appendChild(n),zT[e.id]||(zT[e.id]={}),zT[e.id].endRight=i,UT(a,e.endLabelRight)}})(c,n)})),e.edges().forEach((function(t){Bb.info("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t))})),Bb.info("#############################################"),Bb.info("### Layout ###"),Bb.info("#############################################"),Bb.info(e),Lm(e),Bb.info("Graph after layout:",bb(e));let h=0;return(t=>ST(t,t.children()))(e).forEach((function(t){const n=e.node(t);Bb.info("Position "+t+": "+JSON.stringify(e.node(t))),Bb.info("Position "+t+": ("+n.x,","+n.y,") width: ",n.width," height: ",n.height),n&&n.clusterNode?$T(n):e.children(t).length>0?(((t,e)=>{Bb.trace("Inserting cluster");const n=e.shape||"rect";jT[e.id]=PT[n](t,e)})(s,n),bT[n.id].node=n):$T(n)})),e.edges().forEach((function(t){const i=e.edge(t);Bb.info("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(i),i);const r=function(t,e,n,i,r,a){let s=n.points,o=!1;const c=a.node(e.v);var l=a.node(e.w);Bb.info("abc88 InsertEdge: ",n),l.intersect&&c.intersect&&(s=s.slice(1,n.points.length-1),s.unshift(c.intersect(s[0])),Bb.info("Last point",s[s.length-1],l,l.intersect(s[s.length-1])),s.push(l.intersect(s[s.length-1]))),n.toCluster&&(Bb.info("to cluster abc88",i[n.toCluster]),s=WT(n.points,i[n.toCluster].node),o=!0),n.fromCluster&&(Bb.info("from cluster abc88",i[n.fromCluster]),s=WT(s.reverse(),i[n.fromCluster].node).reverse(),o=!0);const h=s.filter((t=>!Number.isNaN(t.y)));let u;u=("graph"===r||"flowchart"===r)&&n.curve||Rc;const d=Nc().x((function(t){return t.x})).y((function(t){return t.y})).curve(u);let p;switch(n.thickness){case"normal":p="edge-thickness-normal";break;case"thick":p="edge-thickness-thick";break;default:p=""}switch(n.pattern){case"solid":p+=" edge-pattern-solid";break;case"dotted":p+=" edge-pattern-dotted";break;case"dashed":p+=" edge-pattern-dashed"}const f=t.append("path").attr("d",d(h)).attr("id",n.id).attr("class"," "+p+(n.classes?" "+n.classes:"")).attr("style",n.style);let g="";switch((fv().flowchart.arrowMarkerAbsolute||fv().state.arrowMarkerAbsolute)&&(g=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,g=g.replace(/\(/g,"\\("),g=g.replace(/\)/g,"\\)")),Bb.info("arrowTypeStart",n.arrowTypeStart),Bb.info("arrowTypeEnd",n.arrowTypeEnd),n.arrowTypeStart){case"arrow_cross":f.attr("marker-start","url("+g+"#"+r+"-crossStart)");break;case"arrow_point":f.attr("marker-start","url("+g+"#"+r+"-pointStart)");break;case"arrow_barb":f.attr("marker-start","url("+g+"#"+r+"-barbStart)");break;case"arrow_circle":f.attr("marker-start","url("+g+"#"+r+"-circleStart)");break;case"aggregation":f.attr("marker-start","url("+g+"#"+r+"-aggregationStart)");break;case"extension":f.attr("marker-start","url("+g+"#"+r+"-extensionStart)");break;case"composition":f.attr("marker-start","url("+g+"#"+r+"-compositionStart)");break;case"dependency":f.attr("marker-start","url("+g+"#"+r+"-dependencyStart)");break;case"lollipop":f.attr("marker-start","url("+g+"#"+r+"-lollipopStart)")}switch(n.arrowTypeEnd){case"arrow_cross":f.attr("marker-end","url("+g+"#"+r+"-crossEnd)");break;case"arrow_point":f.attr("marker-end","url("+g+"#"+r+"-pointEnd)");break;case"arrow_barb":f.attr("marker-end","url("+g+"#"+r+"-barbEnd)");break;case"arrow_circle":f.attr("marker-end","url("+g+"#"+r+"-circleEnd)");break;case"aggregation":f.attr("marker-end","url("+g+"#"+r+"-aggregationEnd)");break;case"extension":f.attr("marker-end","url("+g+"#"+r+"-extensionEnd)");break;case"composition":f.attr("marker-end","url("+g+"#"+r+"-compositionEnd)");break;case"dependency":f.attr("marker-end","url("+g+"#"+r+"-dependencyEnd)");break;case"lollipop":f.attr("marker-end","url("+g+"#"+r+"-lollipopEnd)")}let y={};return o&&(y.updatedPath=s),y.originalPath=n.points,y}(o,t,i,bT,n,e);((t,e)=>{Bb.info("Moving label abc78 ",t.id,t.label,YT[t.id]);let n=e.updatedPath?e.updatedPath:e.originalPath;if(t.label){const i=YT[t.id];let r=t.x,a=t.y;if(n){const i=rv.calcLabelPosition(n);Bb.info("Moving label "+t.label+" from (",r,",",a,") to (",i.x,",",i.y,") abc78"),e.updatedPath&&(r=i.x,a=i.y)}i.attr("transform","translate("+r+", "+a+")")}if(t.startLabelLeft){const e=zT[t.id].startLeft;let i=t.x,r=t.y;if(n){const e=rv.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",n);i=e.x,r=e.y}e.attr("transform","translate("+i+", "+r+")")}if(t.startLabelRight){const e=zT[t.id].startRight;let i=t.x,r=t.y;if(n){const e=rv.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",n);i=e.x,r=e.y}e.attr("transform","translate("+i+", "+r+")")}if(t.endLabelLeft){const e=zT[t.id].endLeft;let i=t.x,r=t.y;if(n){const e=rv.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",n);i=e.x,r=e.y}e.attr("transform","translate("+i+", "+r+")")}if(t.endLabelRight){const e=zT[t.id].endRight;let i=t.x,r=t.y;if(n){const e=rv.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",n);i=e.x,r=e.y}e.attr("transform","translate("+i+", "+r+")")}})(i,r)})),e.nodes().forEach((function(t){const n=e.node(t);Bb.info(t,n.type,n.diff),"group"===n.type&&(h=n.diff)})),{elem:a,diff:h}},qT=(t,e,n,i,r)=>{pT(t,n,i,r),RT={},YT={},zT={},jT={},_T={},xT={},bT={},Bb.warn("Graph at first:",bb(e)),((t,e)=>{!t||e>10?Bb.debug("Opting out, no graph "):(Bb.debug("Opting in, graph "),t.nodes().forEach((function(e){t.children(e).length>0&&(Bb.warn("Cluster identified",e," Replacement id in edges: ",TT(e,t)),_T[e]=wT(e,t),bT[e]={id:TT(e,t),clusterData:t.node(e)})})),t.nodes().forEach((function(e){const n=t.children(e),i=t.edges();n.length>0?(Bb.debug("Cluster identified",e,_T),i.forEach((t=>{t.v!==e&&t.w!==e&&vT(t.v,e)^vT(t.w,e)&&(Bb.warn("Edge: ",t," leaves cluster ",e),Bb.warn("Decendants of XXX ",e,": ",_T[e]),bT[e].externalConnections=!0)}))):Bb.debug("Not a cluster ",e,_T)})),t.edges().forEach((function(e){const n=t.edge(e);Bb.warn("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),Bb.warn("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(t.edge(e)));let i=e.v,r=e.w;if(Bb.warn("Fix XXX",bT,"ids:",e.v,e.w,"Translating: ",bT[e.v]," --- ",bT[e.w]),bT[e.v]&&bT[e.w]&&bT[e.v]===bT[e.w]){Bb.warn("Fixing and trixing link to self - removing XXX",e.v,e.w,e.name),Bb.warn("Fixing and trixing - removing XXX",e.v,e.w,e.name),i=CT(e.v),r=CT(e.w),t.removeEdge(e.v,e.w,e.name);const a=e.w+"---"+e.v;t.setNode(a,{domId:a,id:a,labelStyle:"",labelText:n.label,padding:0,shape:"labelRect",style:""});const s=JSON.parse(JSON.stringify(n)),o=JSON.parse(JSON.stringify(n));s.label="",s.arrowTypeEnd="none",o.label="",s.fromCluster=e.v,o.toCluster=e.v,t.setEdge(i,a,s,e.name+"-cyclic-special"),t.setEdge(a,r,o,e.name+"-cyclic-special")}else(bT[e.v]||bT[e.w])&&(Bb.warn("Fixing and trixing - removing XXX",e.v,e.w,e.name),i=CT(e.v),r=CT(e.w),t.removeEdge(e.v,e.w,e.name),i!==e.v&&(n.fromCluster=e.v),r!==e.w&&(n.toCluster=e.w),Bb.warn("Fix Replacing with XXX",i,r,e.name),t.setEdge(i,r,n,e.name))})),Bb.warn("Adjusted Graph",bb(t)),ET(t,0),Bb.trace(bT))})(e),Bb.warn("Graph after:",bb(e)),HT(t,e,i)},VT=t=>Wb.sanitizeText(t,fv());let GT={dividerMargin:10,padding:5,textHeight:10};function XT(t){let e;switch(t){case 0:e="aggregation";break;case 1:e="extension";break;case 2:e="composition";break;case 3:e="dependency";break;case 4:e="lollipop";break;default:e="none"}return e}const ZT={setConf:function(t){Object.keys(t).forEach((function(e){GT[e]=t[e]}))},draw:function(t,e,n,i){Bb.info("Drawing class - ",e);const r=fv().flowchart,a=fv().securityLevel;Bb.info("config:",r);const s=r.nodeSpacing||50,o=r.rankSpacing||50,c=new Qf({multigraph:!0,compound:!0}).setGraph({rankdir:i.db.getDirection(),nodesep:s,ranksep:o,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),l=i.db.getClasses(),h=i.db.getRelations(),u=i.db.getNotes();let d;Bb.info(h),function(t,e,n,i){const r=Object.keys(t);Bb.info("keys:",r),Bb.info(t),r.forEach((function(n){const r=t[n];let a="";r.cssClasses.length>0&&(a=a+" "+r.cssClasses.join(" "));const s={labelStyle:""};let o=void 0!==r.text?r.text:r.id,c="";r.type,c="class_box",e.setNode(r.id,{labelStyle:s.labelStyle,shape:c,labelText:VT(o),classData:r,rx:0,ry:0,class:a,style:s.style,id:r.id,domId:r.domId,tooltip:i.db.getTooltip(r.id)||"",haveCallback:r.haveCallback,link:r.link,width:"group"===r.type?500:void 0,type:r.type,padding:fv().flowchart.padding}),Bb.info("setNode",{labelStyle:s.labelStyle,shape:c,labelText:o,rx:0,ry:0,class:a,style:s.style,id:r.id,width:"group"===r.type?500:void 0,type:r.type,padding:fv().flowchart.padding})}))}(l,c,0,i),function(t,e){const n=fv().flowchart;let i=0;t.forEach((function(r){i++;const a={classes:"relation"};a.pattern=1==r.relation.lineType?"dashed":"solid",a.id="id"+i,"arrow_open"===r.type?a.arrowhead="none":a.arrowhead="normal",Bb.info(a,r),a.startLabelRight="none"===r.relationTitle1?"":r.relationTitle1,a.endLabelLeft="none"===r.relationTitle2?"":r.relationTitle2,a.arrowTypeStart=XT(r.relation.type1),a.arrowTypeEnd=XT(r.relation.type2);let s="",o="";if(void 0!==r.style){const t=Wx(r.style);s=t.style,o=t.labelStyle}else s="fill:none";a.style=s,a.labelStyle=o,void 0!==r.interpolate?a.curve=zx(r.interpolate,Ac):void 0!==t.defaultInterpolate?a.curve=zx(t.defaultInterpolate,Ac):a.curve=zx(n.curve,Ac),r.text=r.title,void 0===r.text?void 0!==r.style&&(a.arrowheadStyle="fill: #333"):(a.arrowheadStyle="fill: #333",a.labelpos="c",fv().flowchart.htmlLabels?(a.labelType="html",a.label='<span class="edgeLabel">'+r.text+"</span>"):(a.labelType="text",a.label=r.text.replace(Wb.lineBreakRegex,"\n"),void 0===r.style&&(a.style=a.style||"stroke: #333; stroke-width: 1.5px;fill:none"),a.labelStyle=a.labelStyle.replace("color:","fill:"))),e.setEdge(r.id1,r.id2,a,i)}))}(h,c),function(t,e,n,i){Bb.info(t),t.forEach((function(t,r){const a=t,s="",o="";let c=a.text,l="note";if(e.setNode(a.id,{labelStyle:s,shape:l,labelText:VT(c),noteData:a,rx:0,ry:0,class:"",style:o,id:a.id,domId:a.id,tooltip:"",type:"note",padding:fv().flowchart.padding}),Bb.info("setNode",{labelStyle:s,shape:l,labelText:c,rx:0,ry:0,style:o,id:a.id,type:"note",padding:fv().flowchart.padding}),!a.class||!(a.class in i))return;const h=n+r,u={classes:"relation",pattern:"dotted"};u.id=`edgeNote${h}`,u.arrowhead="none",Bb.info(`Note edge: ${JSON.stringify(u)}, ${JSON.stringify(a)}`),u.startLabelRight="",u.endLabelLeft="",u.arrowTypeStart="none",u.arrowTypeEnd="none",u.style="fill:none",u.labelStyle="",u.curve=zx(GT.curve,Ac),e.setEdge(a.id,a.class,u,h)}))}(u,c,h.length+1,l),"sandbox"===a&&(d=Xo("#i"+e));const p=Xo("sandbox"===a?d.nodes()[0].contentDocument.body:"body"),f=p.select(`[id="${e}"]`),g=p.select("#"+e+" g");if(qT(g,c,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",e),rv.insertTitle(f,"classTitleText",r.titleTopMargin,i.db.getDiagramTitle()),kv(c,f,r.diagramPadding,r.useMaxWidth),!r.htmlLabels){const t="sandbox"===a?d.nodes()[0].contentDocument:document,n=t.querySelectorAll('[id="'+e+'"] .edgeLabel .label');for(const e of n){const n=e.getBBox(),i=t.createElementNS("http://www.w3.org/2000/svg","rect");i.setAttribute("rx",0),i.setAttribute("ry",0),i.setAttribute("width",n.width),i.setAttribute("height",n.height),e.insertBefore(i,e.firstChild)}}}};var QT=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,2],i=[1,5],r=[6,9,11,23,25,27,29,30,31,49],a=[1,17],s=[1,18],o=[1,19],c=[1,20],l=[1,21],h=[1,22],u=[1,25],d=[1,30],p=[1,31],f=[1,32],g=[1,33],y=[6,9,11,15,20,23,25,27,29,30,31,42,43,44,45,49],m=[1,45],b=[30,31,46,47],_=[4,6,9,11,23,25,27,29,30,31,49],x=[42,43,44,45],v=[22,37],k=[1,64],w={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,entityName:17,relSpec:18,role:19,BLOCK_START:20,attributes:21,BLOCK_STOP:22,title:23,title_value:24,acc_title:25,acc_title_value:26,acc_descr:27,acc_descr_value:28,acc_descr_multiline_value:29,ALPHANUM:30,ENTITY_NAME:31,attribute:32,attributeType:33,attributeName:34,attributeKeyType:35,attributeComment:36,ATTRIBUTE_WORD:37,ATTRIBUTE_KEY:38,COMMENT:39,cardinality:40,relType:41,ZERO_OR_ONE:42,ZERO_OR_MORE:43,ONE_OR_MORE:44,ONLY_ONE:45,NON_IDENTIFYING:46,IDENTIFYING:47,WORD:48,open_directive:49,type_directive:50,arg_directive:51,close_directive:52,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",20:"BLOCK_START",22:"BLOCK_STOP",23:"title",24:"title_value",25:"acc_title",26:"acc_title_value",27:"acc_descr",28:"acc_descr_value",29:"acc_descr_multiline_value",30:"ALPHANUM",31:"ENTITY_NAME",37:"ATTRIBUTE_WORD",38:"ATTRIBUTE_KEY",39:"COMMENT",42:"ZERO_OR_ONE",43:"ZERO_OR_MORE",44:"ONE_OR_MORE",45:"ONLY_ONE",46:"NON_IDENTIFYING",47:"IDENTIFYING",48:"WORD",49:"open_directive",50:"type_directive",51:"arg_directive",52:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,5],[10,4],[10,3],[10,1],[10,2],[10,2],[10,2],[10,1],[17,1],[17,1],[21,1],[21,2],[32,2],[32,3],[32,3],[32,4],[33,1],[34,1],[35,1],[36,1],[18,3],[40,1],[40,1],[40,1],[40,1],[41,1],[41,1],[19,1],[19,1],[19,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 1:break;case 3:case 7:case 8:this.$=[];break;case 4:a[o-1].push(a[o]),this.$=a[o-1];break;case 5:case 6:case 20:case 41:case 28:case 29:case 30:this.$=a[o];break;case 12:i.addEntity(a[o-4]),i.addEntity(a[o-2]),i.addRelationship(a[o-4],a[o],a[o-2],a[o-3]);break;case 13:i.addEntity(a[o-3]),i.addAttributes(a[o-3],a[o-1]);break;case 14:i.addEntity(a[o-2]);break;case 15:i.addEntity(a[o]);break;case 16:case 17:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 18:case 19:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 21:case 39:case 40:case 31:this.$=a[o].replace(/"/g,"");break;case 22:this.$=[a[o]];break;case 23:a[o].push(a[o-1]),this.$=a[o];break;case 24:this.$={attributeType:a[o-1],attributeName:a[o]};break;case 25:this.$={attributeType:a[o-2],attributeName:a[o-1],attributeKeyType:a[o]};break;case 26:this.$={attributeType:a[o-2],attributeName:a[o-1],attributeComment:a[o]};break;case 27:this.$={attributeType:a[o-3],attributeName:a[o-2],attributeKeyType:a[o-1],attributeComment:a[o]};break;case 32:this.$={cardA:a[o],relType:a[o-1],cardB:a[o-2]};break;case 33:this.$=i.Cardinality.ZERO_OR_ONE;break;case 34:this.$=i.Cardinality.ZERO_OR_MORE;break;case 35:this.$=i.Cardinality.ONE_OR_MORE;break;case 36:this.$=i.Cardinality.ONLY_ONE;break;case 37:this.$=i.Identification.NON_IDENTIFYING;break;case 38:this.$=i.Identification.IDENTIFYING;break;case 42:i.parseDirective("%%{","open_directive");break;case 43:i.parseDirective(a[o],"type_directive");break;case 44:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 45:i.parseDirective("}%%","close_directive","er")}},table:[{3:1,4:n,7:3,12:4,49:i},{1:[3]},e(r,[2,3],{5:6}),{3:7,4:n,7:3,12:4,49:i},{13:8,50:[1,9]},{50:[2,42]},{6:[1,10],7:15,8:11,9:[1,12],10:13,11:[1,14],12:4,17:16,23:a,25:s,27:o,29:c,30:l,31:h,49:i},{1:[2,2]},{14:23,15:[1,24],52:u},e([15,52],[2,43]),e(r,[2,8],{1:[2,1]}),e(r,[2,4]),{7:15,10:26,12:4,17:16,23:a,25:s,27:o,29:c,30:l,31:h,49:i},e(r,[2,6]),e(r,[2,7]),e(r,[2,11]),e(r,[2,15],{18:27,40:29,20:[1,28],42:d,43:p,44:f,45:g}),{24:[1,34]},{26:[1,35]},{28:[1,36]},e(r,[2,19]),e(y,[2,20]),e(y,[2,21]),{11:[1,37]},{16:38,51:[1,39]},{11:[2,45]},e(r,[2,5]),{17:40,30:l,31:h},{21:41,22:[1,42],32:43,33:44,37:m},{41:46,46:[1,47],47:[1,48]},e(b,[2,33]),e(b,[2,34]),e(b,[2,35]),e(b,[2,36]),e(r,[2,16]),e(r,[2,17]),e(r,[2,18]),e(_,[2,9]),{14:49,52:u},{52:[2,44]},{15:[1,50]},{22:[1,51]},e(r,[2,14]),{21:52,22:[2,22],32:43,33:44,37:m},{34:53,37:[1,54]},{37:[2,28]},{40:55,42:d,43:p,44:f,45:g},e(x,[2,37]),e(x,[2,38]),{11:[1,56]},{19:57,30:[1,60],31:[1,59],48:[1,58]},e(r,[2,13]),{22:[2,23]},e(v,[2,24],{35:61,36:62,38:[1,63],39:k}),e([22,37,38,39],[2,29]),e([30,31],[2,32]),e(_,[2,10]),e(r,[2,12]),e(r,[2,39]),e(r,[2,40]),e(r,[2,41]),e(v,[2,25],{36:65,39:k}),e(v,[2,26]),e([22,37,39],[2,30]),e(v,[2,31]),e(v,[2,27])],defaultActions:{5:[2,42],7:[2,2],25:[2,45],39:[2,44],45:[2,28],52:[2,23]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},T=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("acc_title"),25;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),27;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.begin("open_directive"),49;case 8:return this.begin("type_directive"),50;case 9:return this.popState(),this.begin("arg_directive"),15;case 10:return this.popState(),this.popState(),52;case 11:return 51;case 12:case 13:case 15:case 21:case 26:break;case 14:return 11;case 16:return 9;case 17:return 31;case 18:return 48;case 19:return 4;case 20:return this.begin("block"),20;case 22:return 38;case 23:case 24:return 37;case 25:return 39;case 27:return this.popState(),22;case 28:case 57:return e.yytext[0];case 29:case 33:case 34:case 47:return 42;case 30:case 31:case 32:case 40:case 42:case 49:return 44;case 35:case 36:case 37:case 38:case 39:case 41:case 48:return 43;case 43:case 44:case 45:case 46:return 45;case 50:case 53:case 54:case 55:return 46;case 51:case 52:return 47;case 56:return 30;case 58:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[A-Za-z][A-Za-z0-9\-_\[\]]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},open_directive:{rules:[8],inclusive:!1},type_directive:{rules:[9,10],inclusive:!1},arg_directive:{rules:[10,11],inclusive:!1},block:{rules:[21,22,23,24,25,26,27,28],inclusive:!1},INITIAL:{rules:[0,2,4,7,12,13,14,15,16,17,18,19,20,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58],inclusive:!0}}},t);function C(){this.yy={}}return w.lexer=T,C.prototype=w,w.Parser=C,new C}();QT.parser=QT;const KT=QT,JT=t=>null!==t.match(/^\s*erDiagram/);let tC={},eC=[];const nC=function(t){return void 0===tC[t]&&(tC[t]={attributes:[]},Bb.info("Added new entity :",t)),tC[t]},iC={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().er,addEntity:nC,addAttributes:function(t,e){let n,i=nC(t);for(n=e.length-1;n>=0;n--)i.attributes.push(e[n]),Bb.debug("Added attribute ",e[n].attributeName)},getEntities:()=>tC,addRelationship:function(t,e,n,i){let r={entityA:t,roleA:e,entityB:n,relSpec:i};eC.push(r),Bb.debug("Added new relationship :",r)},getRelationships:()=>eC,clear:function(){tC={},eC=[],Kv()},setAccTitle:Jv,getAccTitle:tk,setAccDescription:ek,getAccDescription:nk,setDiagramTitle:ik,getDiagramTitle:rk},rC={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END"},aC=rC,sC=function(t,e){let n;t.append("defs").append("marker").attr("id",rC.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",rC.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),n=t.append("defs").append("marker").attr("id",rC.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),n.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),n.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),n=t.append("defs").append("marker").attr("id",rC.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),n.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),n.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",rC.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",rC.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),n=t.append("defs").append("marker").attr("id",rC.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),n.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),n.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),n=t.append("defs").append("marker").attr("id",rC.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),n.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),n.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},oC=/[^\dA-Za-z](\W)*/g;let cC={},lC=new Map;const hC=function(t,e,n){let i;return Object.keys(e).forEach((function(r){const a=function(t="",e=""){const n=t.replace(oC,"");return`${pC(e)}${pC(n)}${Sb()}`}(r,"entity");lC.set(r,a);const s=t.append("g").attr("id",a);i=void 0===i?a:i;const o="text-"+a,c=s.append("text").classed("er entityLabel",!0).attr("id",o).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",fv().fontFamily).style("font-size",cC.fontSize+"px").text(r),{width:l,height:h}=((t,e,n)=>{const i=cC.entityPadding/3,r=cC.entityPadding/3,a=.85*cC.fontSize,s=e.node().getBBox(),o=[];let c=!1,l=!1,h=0,u=0,d=0,p=0,f=s.height+2*i,g=1;n.forEach((t=>{void 0!==t.attributeKeyType&&(c=!0),void 0!==t.attributeComment&&(l=!0)})),n.forEach((n=>{const r=`${e.node().id}-attr-${g}`;let s=0;const y=Ub(n.attributeType),m=t.append("text").classed("er entityLabel",!0).attr("id",`${r}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",fv().fontFamily).style("font-size",a+"px").text(y),b=t.append("text").classed("er entityLabel",!0).attr("id",`${r}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",fv().fontFamily).style("font-size",a+"px").text(n.attributeName),_={};_.tn=m,_.nn=b;const x=m.node().getBBox(),v=b.node().getBBox();if(h=Math.max(h,x.width),u=Math.max(u,v.width),s=Math.max(x.height,v.height),c){const e=t.append("text").classed("er entityLabel",!0).attr("id",`${r}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",fv().fontFamily).style("font-size",a+"px").text(n.attributeKeyType||"");_.kn=e;const i=e.node().getBBox();d=Math.max(d,i.width),s=Math.max(s,i.height)}if(l){const e=t.append("text").classed("er entityLabel",!0).attr("id",`${r}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",fv().fontFamily).style("font-size",a+"px").text(n.attributeComment||"");_.cn=e;const i=e.node().getBBox();p=Math.max(p,i.width),s=Math.max(s,i.height)}_.height=s,o.push(_),f+=s+2*i,g+=1}));let y=4;c&&(y+=2),l&&(y+=2);const m=h+u+d+p,b={width:Math.max(cC.minEntityWidth,Math.max(s.width+2*cC.entityPadding,m+r*y)),height:n.length>0?f:Math.max(cC.minEntityHeight,s.height+2*cC.entityPadding)};if(n.length>0){const n=Math.max(0,(b.width-m-r*y)/(y/2));e.attr("transform","translate("+b.width/2+","+(i+s.height/2)+")");let a=s.height+2*i,f="attributeBoxOdd";o.forEach((e=>{const s=a+i+e.height/2;e.tn.attr("transform","translate("+r+","+s+")");const o=t.insert("rect","#"+e.tn.node().id).classed(`er ${f}`,!0).attr("x",0).attr("y",a).attr("width",h+2*r+n).attr("height",e.height+2*i),g=parseFloat(o.attr("x"))+parseFloat(o.attr("width"));e.nn.attr("transform","translate("+(g+r)+","+s+")");const y=t.insert("rect","#"+e.nn.node().id).classed(`er ${f}`,!0).attr("x",g).attr("y",a).attr("width",u+2*r+n).attr("height",e.height+2*i);let m=parseFloat(y.attr("x"))+parseFloat(y.attr("width"));if(c){e.kn.attr("transform","translate("+(m+r)+","+s+")");const o=t.insert("rect","#"+e.kn.node().id).classed(`er ${f}`,!0).attr("x",m).attr("y",a).attr("width",d+2*r+n).attr("height",e.height+2*i);m=parseFloat(o.attr("x"))+parseFloat(o.attr("width"))}l&&(e.cn.attr("transform","translate("+(m+r)+","+s+")"),t.insert("rect","#"+e.cn.node().id).classed(`er ${f}`,"true").attr("x",m).attr("y",a).attr("width",p+2*r+n).attr("height",e.height+2*i)),a+=e.height+2*i,f="attributeBoxOdd"===f?"attributeBoxEven":"attributeBoxOdd"}))}else b.height=Math.max(cC.minEntityHeight,f),e.attr("transform","translate("+b.width/2+","+b.height/2+")");return b})(s,c,e[r].attributes),u=s.insert("rect","#"+o).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",l).attr("height",h).node().getBBox();n.setNode(a,{width:u.width,height:u.height,shape:"rect",id:a})})),i},uC=function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")};let dC=0;function pC(t=""){return t.length>0?`${t}-`:""}const fC={setConf:function(t){const e=Object.keys(t);for(const n of e)cC[n]=t[n]},draw:function(t,e,n,i){cC=fv().er,Bb.info("Drawing ER diagram");const r=fv().securityLevel;let a;"sandbox"===r&&(a=Xo("#i"+e));const s=Xo("sandbox"===r?a.nodes()[0].contentDocument.body:"body").select(`[id='${e}']`);let o;sC(s,cC),o=new Qf({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:cC.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));const c=hC(s,i.db.getEntities(),o),l=function(t,e){return t.forEach((function(t){e.setEdge(lC.get(t.entityA),lC.get(t.entityB),{relationship:t},uC(t))})),t}(i.db.getRelationships(),o);Lm(o),function(t,e){e.nodes().forEach((function(n){void 0!==n&&void 0!==e.node(n)&&t.select("#"+n).attr("transform","translate("+(e.node(n).x-e.node(n).width/2)+","+(e.node(n).y-e.node(n).height/2)+" )")}))}(s,o),l.forEach((function(t){!function(t,e,n,i,r){dC++;const a=n.edge(lC.get(e.entityA),lC.get(e.entityB),uC(e)),s=Nc().x((function(t){return t.x})).y((function(t){return t.y})).curve(Rc),o=t.insert("path","#"+i).classed("er relationshipLine",!0).attr("d",s(a.points)).style("stroke",cC.stroke).style("fill","none");e.relSpec.relType===r.db.Identification.NON_IDENTIFYING&&o.attr("stroke-dasharray","8,8");let c="";switch(cC.arrowMarkerAbsolute&&(c=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,c=c.replace(/\(/g,"\\("),c=c.replace(/\)/g,"\\)")),e.relSpec.cardA){case r.db.Cardinality.ZERO_OR_ONE:o.attr("marker-end","url("+c+"#"+aC.ZERO_OR_ONE_END+")");break;case r.db.Cardinality.ZERO_OR_MORE:o.attr("marker-end","url("+c+"#"+aC.ZERO_OR_MORE_END+")");break;case r.db.Cardinality.ONE_OR_MORE:o.attr("marker-end","url("+c+"#"+aC.ONE_OR_MORE_END+")");break;case r.db.Cardinality.ONLY_ONE:o.attr("marker-end","url("+c+"#"+aC.ONLY_ONE_END+")")}switch(e.relSpec.cardB){case r.db.Cardinality.ZERO_OR_ONE:o.attr("marker-start","url("+c+"#"+aC.ZERO_OR_ONE_START+")");break;case r.db.Cardinality.ZERO_OR_MORE:o.attr("marker-start","url("+c+"#"+aC.ZERO_OR_MORE_START+")");break;case r.db.Cardinality.ONE_OR_MORE:o.attr("marker-start","url("+c+"#"+aC.ONE_OR_MORE_START+")");break;case r.db.Cardinality.ONLY_ONE:o.attr("marker-start","url("+c+"#"+aC.ONLY_ONE_START+")")}const l=o.node().getTotalLength(),h=o.node().getPointAtLength(.5*l),u="rel"+dC,d=t.append("text").classed("er relationshipLabel",!0).attr("id",u).attr("x",h.x).attr("y",h.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",fv().fontFamily).style("font-size",cC.fontSize+"px").text(e.roleA).node().getBBox();t.insert("rect","#"+u).classed("er relationshipLabelBox",!0).attr("x",h.x-d.width/2).attr("y",h.y-d.height/2).attr("width",d.width).attr("height",d.height)}(s,t,o,c,i)}));const h=cC.diagramPadding;rv.insertTitle(s,"entityTitleText",cC.titleTopMargin,i.db.getDiagramTitle());const u=s.node().getBBox(),d=u.width+2*h,p=u.height+2*h;vv(s,p,d,cC.useMaxWidth),s.attr("viewBox",`${u.x-h} ${u.y-h} ${d} ${p}`)}};var gC=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,9],i=[1,7],r=[1,6],a=[1,8],s=[1,20,21,22,23,38,44,46,48,52,66,67,86,87,88,89,90,91,95,105,106,109,111,112,118,119,120,121,122,123,124,125,126,127],o=[2,10],c=[1,20],l=[1,21],h=[1,22],u=[1,23],d=[1,30],p=[1,32],f=[1,33],g=[1,34],y=[1,62],m=[1,48],b=[1,52],_=[1,36],x=[1,37],v=[1,38],k=[1,39],w=[1,40],T=[1,56],C=[1,63],E=[1,51],S=[1,53],A=[1,55],D=[1,59],L=[1,60],N=[1,41],O=[1,42],B=[1,43],M=[1,44],I=[1,61],F=[1,50],R=[1,54],$=[1,57],P=[1,58],j=[1,49],Y=[1,66],z=[1,71],U=[1,20,21,22,23,38,42,44,46,48,52,66,67,86,87,88,89,90,91,95,105,106,109,111,112,118,119,120,121,122,123,124,125,126,127],W=[1,75],H=[1,74],q=[1,76],V=[20,21,23,81,82],G=[1,99],X=[1,104],Z=[1,107],Q=[1,108],K=[1,101],J=[1,106],tt=[1,109],et=[1,102],nt=[1,114],it=[1,113],rt=[1,103],at=[1,105],st=[1,110],ot=[1,111],ct=[1,112],lt=[1,115],ht=[20,21,22,23,81,82],ut=[20,21,22,23,53,81,82],dt=[20,21,22,23,40,52,53,55,57,59,61,63,65,66,67,69,71,73,74,76,81,82,91,95,105,106,109,111,112,122,123,124,125,126,127],pt=[20,21,23],ft=[20,21,23,52,66,67,81,82,91,95,105,106,109,111,112,122,123,124,125,126,127],gt=[1,12,20,21,22,23,24,38,42,44,46,48,52,66,67,86,87,88,89,90,91,95,105,106,109,111,112,118,119,120,121,122,123,124,125,126,127],yt=[52,66,67,91,95,105,106,109,111,112,122,123,124,125,126,127],mt=[1,149],bt=[1,157],_t=[1,158],xt=[1,159],vt=[1,160],kt=[1,144],wt=[1,145],Tt=[1,141],Ct=[1,152],Et=[1,153],St=[1,154],At=[1,155],Dt=[1,156],Lt=[1,161],Nt=[1,162],Ot=[1,147],Bt=[1,150],Mt=[1,146],It=[1,143],Ft=[20,21,22,23,38,42,44,46,48,52,66,67,86,87,88,89,90,91,95,105,106,109,111,112,118,119,120,121,122,123,124,125,126,127],Rt=[1,165],$t=[20,21,22,23,26,52,66,67,91,105,106,109,111,112,122,123,124,125,126,127],Pt=[20,21,22,23,24,26,38,40,41,42,52,56,58,60,62,64,66,67,68,70,72,73,75,77,81,82,86,87,88,89,90,91,92,95,105,106,109,111,112,113,114,122,123,124,125,126,127],jt=[12,21,22,24],Yt=[22,106],zt=[1,250],Ut=[1,245],Wt=[1,246],Ht=[1,254],qt=[1,251],Vt=[1,248],Gt=[1,247],Xt=[1,249],Zt=[1,252],Qt=[1,253],Kt=[1,255],Jt=[1,273],te=[20,21,23,106],ee=[20,21,22,23,66,67,86,102,105,106,109,110,111,112,113],ne={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,openDirective:6,typeDirective:7,closeDirective:8,separator:9,":":10,argDirective:11,open_directive:12,type_directive:13,arg_directive:14,close_directive:15,graphConfig:16,document:17,line:18,statement:19,SEMI:20,NEWLINE:21,SPACE:22,EOF:23,GRAPH:24,NODIR:25,DIR:26,FirstStmtSeperator:27,ending:28,endToken:29,spaceList:30,spaceListNewline:31,verticeStatement:32,styleStatement:33,linkStyleStatement:34,classDefStatement:35,classStatement:36,clickStatement:37,subgraph:38,text:39,SQS:40,SQE:41,end:42,direction:43,acc_title:44,acc_title_value:45,acc_descr:46,acc_descr_value:47,acc_descr_multiline_value:48,link:49,node:50,vertex:51,AMP:52,STYLE_SEPARATOR:53,idString:54,DOUBLECIRCLESTART:55,DOUBLECIRCLEEND:56,PS:57,PE:58,"(-":59,"-)":60,STADIUMSTART:61,STADIUMEND:62,SUBROUTINESTART:63,SUBROUTINEEND:64,VERTEX_WITH_PROPS_START:65,ALPHA:66,COLON:67,PIPE:68,CYLINDERSTART:69,CYLINDEREND:70,DIAMOND_START:71,DIAMOND_STOP:72,TAGEND:73,TRAPSTART:74,TRAPEND:75,INVTRAPSTART:76,INVTRAPEND:77,linkStatement:78,arrowText:79,TESTSTR:80,START_LINK:81,LINK:82,textToken:83,STR:84,keywords:85,STYLE:86,LINKSTYLE:87,CLASSDEF:88,CLASS:89,CLICK:90,DOWN:91,UP:92,textNoTags:93,textNoTagsToken:94,DEFAULT:95,stylesOpt:96,alphaNum:97,CALLBACKNAME:98,CALLBACKARGS:99,HREF:100,LINK_TARGET:101,HEX:102,numList:103,INTERPOLATE:104,NUM:105,COMMA:106,style:107,styleComponent:108,MINUS:109,UNIT:110,BRKT:111,DOT:112,PCT:113,TAGSTART:114,alphaNumToken:115,idStringToken:116,alphaNumStatement:117,direction_tb:118,direction_bt:119,direction_rl:120,direction_lr:121,PUNCTUATION:122,UNICODE_TEXT:123,PLUS:124,EQUALS:125,MULT:126,UNDERSCORE:127,graphCodeTokens:128,ARROW_CROSS:129,ARROW_POINT:130,ARROW_CIRCLE:131,ARROW_OPEN:132,QUOTE:133,$accept:0,$end:1},terminals_:{2:"error",10:":",12:"open_directive",13:"type_directive",14:"arg_directive",15:"close_directive",20:"SEMI",21:"NEWLINE",22:"SPACE",23:"EOF",24:"GRAPH",25:"NODIR",26:"DIR",38:"subgraph",40:"SQS",41:"SQE",42:"end",44:"acc_title",45:"acc_title_value",46:"acc_descr",47:"acc_descr_value",48:"acc_descr_multiline_value",52:"AMP",53:"STYLE_SEPARATOR",55:"DOUBLECIRCLESTART",56:"DOUBLECIRCLEEND",57:"PS",58:"PE",59:"(-",60:"-)",61:"STADIUMSTART",62:"STADIUMEND",63:"SUBROUTINESTART",64:"SUBROUTINEEND",65:"VERTEX_WITH_PROPS_START",66:"ALPHA",67:"COLON",68:"PIPE",69:"CYLINDERSTART",70:"CYLINDEREND",71:"DIAMOND_START",72:"DIAMOND_STOP",73:"TAGEND",74:"TRAPSTART",75:"TRAPEND",76:"INVTRAPSTART",77:"INVTRAPEND",80:"TESTSTR",81:"START_LINK",82:"LINK",84:"STR",86:"STYLE",87:"LINKSTYLE",88:"CLASSDEF",89:"CLASS",90:"CLICK",91:"DOWN",92:"UP",95:"DEFAULT",98:"CALLBACKNAME",99:"CALLBACKARGS",100:"HREF",101:"LINK_TARGET",102:"HEX",104:"INTERPOLATE",105:"NUM",106:"COMMA",109:"MINUS",110:"UNIT",111:"BRKT",112:"DOT",113:"PCT",114:"TAGSTART",118:"direction_tb",119:"direction_bt",120:"direction_rl",121:"direction_lr",122:"PUNCTUATION",123:"UNICODE_TEXT",124:"PLUS",125:"EQUALS",126:"MULT",127:"UNDERSCORE",129:"ARROW_CROSS",130:"ARROW_POINT",131:"ARROW_CIRCLE",132:"ARROW_OPEN",133:"QUOTE"},productions_:[0,[3,1],[3,2],[5,4],[5,6],[6,1],[7,1],[11,1],[8,1],[4,2],[17,0],[17,2],[18,1],[18,1],[18,1],[18,1],[18,1],[16,2],[16,2],[16,2],[16,3],[28,2],[28,1],[29,1],[29,1],[29,1],[27,1],[27,1],[27,2],[31,2],[31,2],[31,1],[31,1],[30,2],[30,1],[19,2],[19,2],[19,2],[19,2],[19,2],[19,2],[19,9],[19,6],[19,4],[19,1],[19,2],[19,2],[19,1],[9,1],[9,1],[9,1],[32,3],[32,4],[32,2],[32,1],[50,1],[50,5],[50,3],[51,4],[51,4],[51,6],[51,4],[51,4],[51,4],[51,8],[51,4],[51,4],[51,4],[51,6],[51,4],[51,4],[51,4],[51,4],[51,4],[51,1],[49,2],[49,3],[49,3],[49,1],[49,3],[78,1],[79,3],[39,1],[39,2],[39,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[93,1],[93,2],[35,5],[35,5],[36,5],[37,2],[37,4],[37,3],[37,5],[37,2],[37,4],[37,4],[37,6],[37,2],[37,4],[37,2],[37,4],[37,4],[37,6],[33,5],[33,5],[34,5],[34,5],[34,9],[34,9],[34,7],[34,7],[103,1],[103,3],[96,1],[96,3],[107,1],[107,2],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[108,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[94,1],[94,1],[94,1],[94,1],[54,1],[54,2],[97,1],[97,2],[117,1],[117,1],[117,1],[117,1],[43,1],[43,1],[43,1],[43,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[115,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1],[128,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 5:i.parseDirective("%%{","open_directive");break;case 6:i.parseDirective(a[o],"type_directive");break;case 7:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 8:i.parseDirective("}%%","close_directive","flowchart");break;case 10:case 36:case 37:case 38:case 39:case 40:this.$=[];break;case 11:(!Array.isArray(a[o])||a[o].length>0)&&a[o-1].push(a[o]),this.$=a[o-1];break;case 12:case 82:case 84:case 96:case 152:case 154:case 155:case 78:case 150:this.$=a[o];break;case 19:i.setDirection("TB"),this.$="TB";break;case 20:i.setDirection(a[o-1]),this.$=a[o-1];break;case 35:this.$=a[o-1].nodes;break;case 41:this.$=i.addSubGraph(a[o-6],a[o-1],a[o-4]);break;case 42:this.$=i.addSubGraph(a[o-3],a[o-1],a[o-3]);break;case 43:this.$=i.addSubGraph(void 0,a[o-1],void 0);break;case 45:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 46:case 47:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 51:i.addLink(a[o-2].stmt,a[o],a[o-1]),this.$={stmt:a[o],nodes:a[o].concat(a[o-2].nodes)};break;case 52:i.addLink(a[o-3].stmt,a[o-1],a[o-2]),this.$={stmt:a[o-1],nodes:a[o-1].concat(a[o-3].nodes)};break;case 53:this.$={stmt:a[o-1],nodes:a[o-1]};break;case 54:this.$={stmt:a[o],nodes:a[o]};break;case 55:case 123:case 125:this.$=[a[o]];break;case 56:this.$=a[o-4].concat(a[o]);break;case 57:this.$=[a[o-2]],i.setClass(a[o-2],a[o]);break;case 58:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"square");break;case 59:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"doublecircle");break;case 60:this.$=a[o-5],i.addVertex(a[o-5],a[o-2],"circle");break;case 61:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"ellipse");break;case 62:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"stadium");break;case 63:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"subroutine");break;case 64:this.$=a[o-7],i.addVertex(a[o-7],a[o-1],"rect",void 0,void 0,void 0,Object.fromEntries([[a[o-5],a[o-3]]]));break;case 65:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"cylinder");break;case 66:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"round");break;case 67:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"diamond");break;case 68:this.$=a[o-5],i.addVertex(a[o-5],a[o-2],"hexagon");break;case 69:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"odd");break;case 70:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"trapezoid");break;case 71:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"inv_trapezoid");break;case 72:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"lean_right");break;case 73:this.$=a[o-3],i.addVertex(a[o-3],a[o-1],"lean_left");break;case 74:this.$=a[o],i.addVertex(a[o]);break;case 75:a[o-1].text=a[o],this.$=a[o-1];break;case 76:case 77:a[o-2].text=a[o-1],this.$=a[o-2];break;case 79:var c=i.destructLink(a[o],a[o-2]);this.$={type:c.type,stroke:c.stroke,length:c.length,text:a[o-1]};break;case 80:c=i.destructLink(a[o]);this.$={type:c.type,stroke:c.stroke,length:c.length};break;case 81:this.$=a[o-1];break;case 83:case 97:case 153:case 151:this.$=a[o-1]+""+a[o];break;case 98:case 99:this.$=a[o-4],i.addClass(a[o-2],a[o]);break;case 100:this.$=a[o-4],i.setClass(a[o-2],a[o]);break;case 101:case 109:this.$=a[o-1],i.setClickEvent(a[o-1],a[o]);break;case 102:case 110:this.$=a[o-3],i.setClickEvent(a[o-3],a[o-2]),i.setTooltip(a[o-3],a[o]);break;case 103:this.$=a[o-2],i.setClickEvent(a[o-2],a[o-1],a[o]);break;case 104:this.$=a[o-4],i.setClickEvent(a[o-4],a[o-3],a[o-2]),i.setTooltip(a[o-4],a[o]);break;case 105:case 111:this.$=a[o-1],i.setLink(a[o-1],a[o]);break;case 106:case 112:this.$=a[o-3],i.setLink(a[o-3],a[o-2]),i.setTooltip(a[o-3],a[o]);break;case 107:case 113:this.$=a[o-3],i.setLink(a[o-3],a[o-2],a[o]);break;case 108:case 114:this.$=a[o-5],i.setLink(a[o-5],a[o-4],a[o]),i.setTooltip(a[o-5],a[o-2]);break;case 115:this.$=a[o-4],i.addVertex(a[o-2],void 0,void 0,a[o]);break;case 116:case 118:this.$=a[o-4],i.updateLink(a[o-2],a[o]);break;case 117:this.$=a[o-4],i.updateLink([a[o-2]],a[o]);break;case 119:this.$=a[o-8],i.updateLinkInterpolate([a[o-6]],a[o-2]),i.updateLink([a[o-6]],a[o]);break;case 120:this.$=a[o-8],i.updateLinkInterpolate(a[o-6],a[o-2]),i.updateLink(a[o-6],a[o]);break;case 121:this.$=a[o-6],i.updateLinkInterpolate([a[o-4]],a[o]);break;case 122:this.$=a[o-6],i.updateLinkInterpolate(a[o-4],a[o]);break;case 124:case 126:a[o-2].push(a[o]),this.$=a[o-2];break;case 128:this.$=a[o-1]+a[o];break;case 156:this.$="v";break;case 157:this.$="-";break;case 158:this.$={stmt:"dir",value:"TB"};break;case 159:this.$={stmt:"dir",value:"BT"};break;case 160:this.$={stmt:"dir",value:"RL"};break;case 161:this.$={stmt:"dir",value:"LR"}}},table:[{3:1,4:2,5:3,6:5,12:n,16:4,21:i,22:r,24:a},{1:[3]},{1:[2,1]},{3:10,4:2,5:3,6:5,12:n,16:4,21:i,22:r,24:a},e(s,o,{17:11}),{7:12,13:[1,13]},{16:14,21:i,22:r,24:a},{16:15,21:i,22:r,24:a},{25:[1,16],26:[1,17]},{13:[2,5]},{1:[2,2]},{1:[2,9],18:18,19:19,20:c,21:l,22:h,23:u,32:24,33:25,34:26,35:27,36:28,37:29,38:d,43:31,44:p,46:f,48:g,50:35,51:45,52:y,54:46,66:m,67:b,86:_,87:x,88:v,89:k,90:w,91:T,95:C,105:E,106:S,109:A,111:D,112:L,116:47,118:N,119:O,120:B,121:M,122:I,123:F,124:R,125:$,126:P,127:j},{8:64,10:[1,65],15:Y},e([10,15],[2,6]),e(s,[2,17]),e(s,[2,18]),e(s,[2,19]),{20:[1,68],21:[1,69],22:z,27:67,30:70},e(U,[2,11]),e(U,[2,12]),e(U,[2,13]),e(U,[2,14]),e(U,[2,15]),e(U,[2,16]),{9:72,20:W,21:H,23:q,49:73,78:77,81:[1,78],82:[1,79]},{9:80,20:W,21:H,23:q},{9:81,20:W,21:H,23:q},{9:82,20:W,21:H,23:q},{9:83,20:W,21:H,23:q},{9:84,20:W,21:H,23:q},{9:86,20:W,21:H,22:[1,85],23:q},e(U,[2,44]),{45:[1,87]},{47:[1,88]},e(U,[2,47]),e(V,[2,54],{30:89,22:z}),{22:[1,90]},{22:[1,91]},{22:[1,92]},{22:[1,93]},{26:G,52:X,66:Z,67:Q,84:[1,97],91:K,97:96,98:[1,94],100:[1,95],105:J,106:tt,109:et,111:nt,112:it,115:100,117:98,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(U,[2,158]),e(U,[2,159]),e(U,[2,160]),e(U,[2,161]),e(ht,[2,55],{53:[1,116]}),e(ut,[2,74],{116:129,40:[1,117],52:y,55:[1,118],57:[1,119],59:[1,120],61:[1,121],63:[1,122],65:[1,123],66:m,67:b,69:[1,124],71:[1,125],73:[1,126],74:[1,127],76:[1,128],91:T,95:C,105:E,106:S,109:A,111:D,112:L,122:I,123:F,124:R,125:$,126:P,127:j}),e(dt,[2,150]),e(dt,[2,175]),e(dt,[2,176]),e(dt,[2,177]),e(dt,[2,178]),e(dt,[2,179]),e(dt,[2,180]),e(dt,[2,181]),e(dt,[2,182]),e(dt,[2,183]),e(dt,[2,184]),e(dt,[2,185]),e(dt,[2,186]),e(dt,[2,187]),e(dt,[2,188]),e(dt,[2,189]),e(dt,[2,190]),{9:130,20:W,21:H,23:q},{11:131,14:[1,132]},e(pt,[2,8]),e(s,[2,20]),e(s,[2,26]),e(s,[2,27]),{21:[1,133]},e(ft,[2,34],{30:134,22:z}),e(U,[2,35]),{50:135,51:45,52:y,54:46,66:m,67:b,91:T,95:C,105:E,106:S,109:A,111:D,112:L,116:47,122:I,123:F,124:R,125:$,126:P,127:j},e(gt,[2,48]),e(gt,[2,49]),e(gt,[2,50]),e(yt,[2,78],{79:136,68:[1,138],80:[1,137]}),{22:mt,24:bt,26:_t,38:xt,39:139,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e([52,66,67,68,80,91,95,105,106,109,111,112,122,123,124,125,126,127],[2,80]),e(U,[2,36]),e(U,[2,37]),e(U,[2,38]),e(U,[2,39]),e(U,[2,40]),{22:mt,24:bt,26:_t,38:xt,39:163,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(Ft,o,{17:164}),e(U,[2,45]),e(U,[2,46]),e(V,[2,53],{52:Rt}),{26:G,52:X,66:Z,67:Q,91:K,97:166,102:[1,167],105:J,106:tt,109:et,111:nt,112:it,115:100,117:98,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{95:[1,168],103:169,105:[1,170]},{26:G,52:X,66:Z,67:Q,91:K,95:[1,171],97:172,105:J,106:tt,109:et,111:nt,112:it,115:100,117:98,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{26:G,52:X,66:Z,67:Q,91:K,97:173,105:J,106:tt,109:et,111:nt,112:it,115:100,117:98,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(pt,[2,101],{22:[1,174],99:[1,175]}),e(pt,[2,105],{22:[1,176]}),e(pt,[2,109],{115:100,117:178,22:[1,177],26:G,52:X,66:Z,67:Q,91:K,105:J,106:tt,109:et,111:nt,112:it,122:rt,123:at,124:st,125:ot,126:ct,127:lt}),e(pt,[2,111],{22:[1,179]}),e($t,[2,152]),e($t,[2,154]),e($t,[2,155]),e($t,[2,156]),e($t,[2,157]),e(Pt,[2,162]),e(Pt,[2,163]),e(Pt,[2,164]),e(Pt,[2,165]),e(Pt,[2,166]),e(Pt,[2,167]),e(Pt,[2,168]),e(Pt,[2,169]),e(Pt,[2,170]),e(Pt,[2,171]),e(Pt,[2,172]),e(Pt,[2,173]),e(Pt,[2,174]),{52:y,54:180,66:m,67:b,91:T,95:C,105:E,106:S,109:A,111:D,112:L,116:47,122:I,123:F,124:R,125:$,126:P,127:j},{22:mt,24:bt,26:_t,38:xt,39:181,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:182,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:184,42:vt,52:X,57:[1,183],66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:185,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:186,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:187,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{66:[1,188]},{22:mt,24:bt,26:_t,38:xt,39:189,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:190,42:vt,52:X,66:Z,67:Q,71:[1,191],73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:192,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:193,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:194,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(dt,[2,151]),e(jt,[2,3]),{8:195,15:Y},{15:[2,7]},e(s,[2,28]),e(ft,[2,33]),e(V,[2,51],{30:196,22:z}),e(yt,[2,75],{22:[1,197]}),{22:[1,198]},{22:mt,24:bt,26:_t,38:xt,39:199,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,82:[1,200],83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(Pt,[2,82]),e(Pt,[2,84]),e(Pt,[2,140]),e(Pt,[2,141]),e(Pt,[2,142]),e(Pt,[2,143]),e(Pt,[2,144]),e(Pt,[2,145]),e(Pt,[2,146]),e(Pt,[2,147]),e(Pt,[2,148]),e(Pt,[2,149]),e(Pt,[2,85]),e(Pt,[2,86]),e(Pt,[2,87]),e(Pt,[2,88]),e(Pt,[2,89]),e(Pt,[2,90]),e(Pt,[2,91]),e(Pt,[2,92]),e(Pt,[2,93]),e(Pt,[2,94]),e(Pt,[2,95]),{9:203,20:W,21:H,22:mt,23:q,24:bt,26:_t,38:xt,40:[1,202],42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{18:18,19:19,20:c,21:l,22:h,23:u,32:24,33:25,34:26,35:27,36:28,37:29,38:d,42:[1,204],43:31,44:p,46:f,48:g,50:35,51:45,52:y,54:46,66:m,67:b,86:_,87:x,88:v,89:k,90:w,91:T,95:C,105:E,106:S,109:A,111:D,112:L,116:47,118:N,119:O,120:B,121:M,122:I,123:F,124:R,125:$,126:P,127:j},{22:z,30:205},{22:[1,206],26:G,52:X,66:Z,67:Q,91:K,105:J,106:tt,109:et,111:nt,112:it,115:100,117:178,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:[1,207]},{22:[1,208]},{22:[1,209],106:[1,210]},e(Yt,[2,123]),{22:[1,211]},{22:[1,212],26:G,52:X,66:Z,67:Q,91:K,105:J,106:tt,109:et,111:nt,112:it,115:100,117:178,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:[1,213],26:G,52:X,66:Z,67:Q,91:K,105:J,106:tt,109:et,111:nt,112:it,115:100,117:178,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{84:[1,214]},e(pt,[2,103],{22:[1,215]}),{84:[1,216],101:[1,217]},{84:[1,218]},e($t,[2,153]),{84:[1,219],101:[1,220]},e(ht,[2,57],{116:129,52:y,66:m,67:b,91:T,95:C,105:E,106:S,109:A,111:D,112:L,122:I,123:F,124:R,125:$,126:P,127:j}),{22:mt,24:bt,26:_t,38:xt,41:[1,221],42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,56:[1,222],66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:223,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,58:[1,224],66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,60:[1,225],66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,62:[1,226],66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,64:[1,227],66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{67:[1,228]},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,66:Z,67:Q,70:[1,229],73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,66:Z,67:Q,72:[1,230],73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,39:231,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,41:[1,232],42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,66:Z,67:Q,73:kt,75:[1,233],77:[1,234],81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,66:Z,67:Q,73:kt,75:[1,236],77:[1,235],81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{9:237,20:W,21:H,23:q},e(V,[2,52],{52:Rt}),e(yt,[2,77]),e(yt,[2,76]),{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,66:Z,67:Q,68:[1,238],73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(yt,[2,79]),e(Pt,[2,83]),{22:mt,24:bt,26:_t,38:xt,39:239,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(Ft,o,{17:240}),e(U,[2,43]),{51:241,52:y,54:46,66:m,67:b,91:T,95:C,105:E,106:S,109:A,111:D,112:L,116:47,122:I,123:F,124:R,125:$,126:P,127:j},{22:zt,66:Ut,67:Wt,86:Ht,96:242,102:qt,105:Vt,107:243,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},{22:zt,66:Ut,67:Wt,86:Ht,96:256,102:qt,105:Vt,107:243,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},{22:zt,66:Ut,67:Wt,86:Ht,96:257,102:qt,104:[1,258],105:Vt,107:243,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},{22:zt,66:Ut,67:Wt,86:Ht,96:259,102:qt,104:[1,260],105:Vt,107:243,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},{105:[1,261]},{22:zt,66:Ut,67:Wt,86:Ht,96:262,102:qt,105:Vt,107:243,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},{22:zt,66:Ut,67:Wt,86:Ht,96:263,102:qt,105:Vt,107:243,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},{26:G,52:X,66:Z,67:Q,91:K,97:264,105:J,106:tt,109:et,111:nt,112:it,115:100,117:98,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(pt,[2,102]),{84:[1,265]},e(pt,[2,106],{22:[1,266]}),e(pt,[2,107]),e(pt,[2,110]),e(pt,[2,112],{22:[1,267]}),e(pt,[2,113]),e(ut,[2,58]),e(ut,[2,59]),{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,58:[1,268],66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(ut,[2,66]),e(ut,[2,61]),e(ut,[2,62]),e(ut,[2,63]),{66:[1,269]},e(ut,[2,65]),e(ut,[2,67]),{22:mt,24:bt,26:_t,38:xt,42:vt,52:X,66:Z,67:Q,72:[1,270],73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(ut,[2,69]),e(ut,[2,70]),e(ut,[2,72]),e(ut,[2,71]),e(ut,[2,73]),e(jt,[2,4]),e([22,52,66,67,91,95,105,106,109,111,112,122,123,124,125,126,127],[2,81]),{22:mt,24:bt,26:_t,38:xt,41:[1,271],42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{18:18,19:19,20:c,21:l,22:h,23:u,32:24,33:25,34:26,35:27,36:28,37:29,38:d,42:[1,272],43:31,44:p,46:f,48:g,50:35,51:45,52:y,54:46,66:m,67:b,86:_,87:x,88:v,89:k,90:w,91:T,95:C,105:E,106:S,109:A,111:D,112:L,116:47,118:N,119:O,120:B,121:M,122:I,123:F,124:R,125:$,126:P,127:j},e(ht,[2,56]),e(pt,[2,115],{106:Jt}),e(te,[2,125],{108:274,22:zt,66:Ut,67:Wt,86:Ht,102:qt,105:Vt,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt}),e(ee,[2,127]),e(ee,[2,129]),e(ee,[2,130]),e(ee,[2,131]),e(ee,[2,132]),e(ee,[2,133]),e(ee,[2,134]),e(ee,[2,135]),e(ee,[2,136]),e(ee,[2,137]),e(ee,[2,138]),e(ee,[2,139]),e(pt,[2,116],{106:Jt}),e(pt,[2,117],{106:Jt}),{22:[1,275]},e(pt,[2,118],{106:Jt}),{22:[1,276]},e(Yt,[2,124]),e(pt,[2,98],{106:Jt}),e(pt,[2,99],{106:Jt}),e(pt,[2,100],{115:100,117:178,26:G,52:X,66:Z,67:Q,91:K,105:J,106:tt,109:et,111:nt,112:it,122:rt,123:at,124:st,125:ot,126:ct,127:lt}),e(pt,[2,104]),{101:[1,277]},{101:[1,278]},{58:[1,279]},{68:[1,280]},{72:[1,281]},{9:282,20:W,21:H,23:q},e(U,[2,42]),{22:zt,66:Ut,67:Wt,86:Ht,102:qt,105:Vt,107:283,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},e(ee,[2,128]),{26:G,52:X,66:Z,67:Q,91:K,97:284,105:J,106:tt,109:et,111:nt,112:it,115:100,117:98,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{26:G,52:X,66:Z,67:Q,91:K,97:285,105:J,106:tt,109:et,111:nt,112:it,115:100,117:98,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(pt,[2,108]),e(pt,[2,114]),e(ut,[2,60]),{22:mt,24:bt,26:_t,38:xt,39:286,42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:140,84:Tt,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},e(ut,[2,68]),e(Ft,o,{17:287}),e(te,[2,126],{108:274,22:zt,66:Ut,67:Wt,86:Ht,102:qt,105:Vt,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt}),e(pt,[2,121],{115:100,117:178,22:[1,288],26:G,52:X,66:Z,67:Q,91:K,105:J,106:tt,109:et,111:nt,112:it,122:rt,123:at,124:st,125:ot,126:ct,127:lt}),e(pt,[2,122],{115:100,117:178,22:[1,289],26:G,52:X,66:Z,67:Q,91:K,105:J,106:tt,109:et,111:nt,112:it,122:rt,123:at,124:st,125:ot,126:ct,127:lt}),{22:mt,24:bt,26:_t,38:xt,41:[1,290],42:vt,52:X,66:Z,67:Q,73:kt,81:wt,83:201,85:151,86:Ct,87:Et,88:St,89:At,90:Dt,91:Lt,92:Nt,94:142,95:Ot,105:J,106:tt,109:Bt,111:nt,112:it,113:Mt,114:It,115:148,122:rt,123:at,124:st,125:ot,126:ct,127:lt},{18:18,19:19,20:c,21:l,22:h,23:u,32:24,33:25,34:26,35:27,36:28,37:29,38:d,42:[1,291],43:31,44:p,46:f,48:g,50:35,51:45,52:y,54:46,66:m,67:b,86:_,87:x,88:v,89:k,90:w,91:T,95:C,105:E,106:S,109:A,111:D,112:L,116:47,118:N,119:O,120:B,121:M,122:I,123:F,124:R,125:$,126:P,127:j},{22:zt,66:Ut,67:Wt,86:Ht,96:292,102:qt,105:Vt,107:243,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},{22:zt,66:Ut,67:Wt,86:Ht,96:293,102:qt,105:Vt,107:243,108:244,109:Gt,110:Xt,111:Zt,112:Qt,113:Kt},e(ut,[2,64]),e(U,[2,41]),e(pt,[2,119],{106:Jt}),e(pt,[2,120],{106:Jt})],defaultActions:{2:[2,1],9:[2,5],10:[2,2],132:[2,7]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},ie=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),12;case 1:return this.begin("type_directive"),13;case 2:return this.popState(),this.begin("arg_directive"),10;case 3:return this.popState(),this.popState(),15;case 4:return 14;case 5:case 6:break;case 7:return this.begin("acc_title"),44;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),46;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:case 15:case 24:case 27:case 30:case 33:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:this.begin("string");break;case 16:return"STR";case 17:return 86;case 18:return 95;case 19:return 87;case 20:return 104;case 21:return 88;case 22:return 89;case 23:this.begin("href");break;case 25:return 100;case 26:this.begin("callbackname");break;case 28:this.popState(),this.begin("callbackargs");break;case 29:return 98;case 31:return 99;case 32:this.begin("click");break;case 34:return 90;case 35:case 36:return t.lex.firstGraph()&&this.begin("dir"),24;case 37:return 38;case 38:return 42;case 39:case 40:case 41:case 42:return 101;case 43:return this.popState(),25;case 44:case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:return this.popState(),26;case 54:return 118;case 55:return 119;case 56:return 120;case 57:return 121;case 58:return 105;case 59:return 111;case 60:return 53;case 61:return 67;case 62:return 52;case 63:return 20;case 64:return 106;case 65:return 126;case 66:case 67:case 68:return 82;case 69:case 70:case 71:return 81;case 72:return 59;case 73:return 60;case 74:return 61;case 75:return 62;case 76:return 63;case 77:return 64;case 78:return 65;case 79:return 69;case 80:return 70;case 81:return 55;case 82:return 56;case 83:return 109;case 84:return 112;case 85:return 127;case 86:return 124;case 87:return 113;case 88:case 89:return 125;case 90:return 114;case 91:return 73;case 92:return 92;case 93:return"SEP";case 94:return 91;case 95:return 66;case 96:return 75;case 97:return 74;case 98:return 77;case 99:return 76;case 100:return 122;case 101:return 123;case 102:return 68;case 103:return 57;case 104:return 58;case 105:return 40;case 106:return 41;case 107:return 71;case 108:return 72;case 109:return 133;case 110:return 21;case 111:return 22;case 112:return 23}},rules:[/^(?:%%\{)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)[^\n]*)/,/^(?:[^\}]%%[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s]+["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\[)/,/^(?:\]\))/,/^(?:\[\[)/,/^(?:\]\])/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\])/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:-)/,/^(?:\.)/,/^(?:[\_])/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:[A-Za-z]+)/,/^(?:\\\])/,/^(?:\[\/)/,/^(?:\/\])/,/^(?:\[\\)/,/^(?:[!"#$%&'*+,-.`?\\_/])/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[30,31],inclusive:!1},callbackname:{rules:[27,28,29],inclusive:!1},href:{rules:[24,25],inclusive:!1},click:{rules:[33,34],inclusive:!1},vertex:{rules:[],inclusive:!1},dir:{rules:[43,44,45,46,47,48,49,50,51,52,53],inclusive:!1},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},string:{rules:[15,16],inclusive:!1},INITIAL:{rules:[0,5,6,7,9,11,14,17,18,19,20,21,22,23,26,32,35,36,37,38,39,40,41,42,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112],inclusive:!0}}},t);function re(){this.yy={}}return ne.lexer=ie,re.prototype=ne,ne.Parser=re,new re}();gC.parser=gC;const yC=gC,mC=(t,e)=>{var n;return"dagre-wrapper"!==(null==(n=null==e?void 0:e.flowchart)?void 0:n.defaultRenderer)&&null!==t.match(/^\s*graph/)},bC=(t,e)=>{var n;return"dagre-wrapper"===(null==(n=null==e?void 0:e.flowchart)?void 0:n.defaultRenderer)&&null!==t.match(/^\s*graph/)||null!==t.match(/^\s*flowchart/)};let _C,xC,vC=0,kC=fv(),wC={},TC=[],CC={},EC=[],SC={},AC={},DC=0,LC=!0,NC=[];const OC=t=>Wb.sanitizeText(t,kC),BC=function(t){const e=Object.keys(wC);for(const n of e)if(wC[n].id===t)return wC[n].domId;return t},MC=function(t,e,n,i){const r={start:t,end:e,type:void 0,text:""};void 0!==(i=n.text)&&(r.text=OC(i.trim()),'"'===r.text[0]&&'"'===r.text[r.text.length-1]&&(r.text=r.text.substring(1,r.text.length-1))),void 0!==n&&(r.type=n.type,r.stroke=n.stroke,r.length=n.length),TC.push(r)},IC=function(t,e){t.split(",").forEach((function(t){let n=t;void 0!==wC[n]&&wC[n].classes.push(e),void 0!==SC[n]&&SC[n].classes.push(e)}))},FC=function(t){let e=Xo(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=Xo("body").append("div").attr("class","mermaidTooltip").style("opacity",0));Xo(t).select("svg").selectAll("g.node").on("mouseover",(function(){const t=Xo(this);if(null===t.attr("title"))return;const n=this.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.text(t.attr("title")).style("left",window.scrollX+n.left+(n.right-n.left)/2+"px").style("top",window.scrollY+n.top-14+document.body.scrollTop+"px"),e.html(e.html().replace(/<br\/>/g,"<br/>")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);Xo(this).classed("hover",!1)}))};NC.push(FC);const RC=function(t){for(const[e,n]of EC.entries())if(n.id===t)return e;return-1};let $C=-1;const PC=[],jC=function(t,e){const n=EC[e].nodes;if($C+=1,$C>2e3)return;if(PC[$C]=e,EC[e].id===t)return{result:!0,count:0};let i=0,r=1;for(;i<n.length;){const e=RC(n[i]);if(e>=0){const n=jC(t,e);if(n.result)return{result:!0,count:r+n.count};r+=n.count}i+=1}return{result:!1,count:r}},YC=(t,e)=>{let n=!1;return t.forEach((t=>{t.nodes.indexOf(e)>=0&&(n=!0)})),n},zC=(t,e)=>{const n=[];return t.nodes.forEach(((i,r)=>{YC(e,i)||n.push(t.nodes[r])})),{nodes:n}},UC={parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},defaultConfig:()=>sv.flowchart,setAccTitle:Jv,getAccTitle:tk,getAccDescription:nk,setAccDescription:ek,addVertex:function(t,e,n,i,r,a,s={}){let o,c=t;void 0!==c&&0!==c.trim().length&&(void 0===wC[c]&&(wC[c]={id:c,domId:"flowchart-"+c+"-"+vC,styles:[],classes:[]}),vC++,void 0!==e?(kC=fv(),o=OC(e.trim()),'"'===o[0]&&'"'===o[o.length-1]&&(o=o.substring(1,o.length-1)),wC[c].text=o):void 0===wC[c].text&&(wC[c].text=t),void 0!==n&&(wC[c].type=n),null!=i&&i.forEach((function(t){wC[c].styles.push(t)})),null!=r&&r.forEach((function(t){wC[c].classes.push(t)})),void 0!==a&&(wC[c].dir=a),void 0===wC[c].props?wC[c].props=s:void 0!==s&&Object.assign(wC[c].props,s))},lookUpDomId:BC,addLink:function(t,e,n,i){let r,a;for(r=0;r<t.length;r++)for(a=0;a<e.length;a++)MC(t[r],e[a],n,i)},updateLinkInterpolate:function(t,e){t.forEach((function(t){"default"===t?TC.defaultInterpolate=e:TC[t].interpolate=e}))},updateLink:function(t,e){t.forEach((function(t){"default"===t?TC.defaultStyle=e:(-1===rv.isSubstringInArray("fill",e)&&e.push("fill:none"),TC[t].style=e)}))},addClass:function(t,e){void 0===CC[t]&&(CC[t]={id:t,styles:[],textStyles:[]}),null!=e&&e.forEach((function(e){if(e.match("color")){const n=e.replace("fill","bgFill").replace("color","fill");CC[t].textStyles.push(n)}CC[t].styles.push(e)}))},setDirection:function(t){_C=t,_C.match(/.*</)&&(_C="RL"),_C.match(/.*\^/)&&(_C="BT"),_C.match(/.*>/)&&(_C="LR"),_C.match(/.*v/)&&(_C="TB")},setClass:IC,setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(AC["gen-1"===xC?BC(t):t]=OC(e))}))},getTooltip:function(t){return AC[t]},setClickEvent:function(t,e,n){t.split(",").forEach((function(t){!function(t,e,n){let i=BC(t);if("loose"!==fv().securityLevel)return;if(void 0===e)return;let r=[];if("string"==typeof n){r=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<r.length;t++){let e=r[t].trim();'"'===e.charAt(0)&&'"'===e.charAt(e.length-1)&&(e=e.substr(1,e.length-2)),r[t]=e}}0===r.length&&r.push(t),void 0!==wC[t]&&(wC[t].haveCallback=!0,NC.push((function(){const t=document.querySelector(`[id="${i}"]`);null!==t&&t.addEventListener("click",(function(){rv.runFunc(e,...r)}),!1)})))}(t,e,n)})),IC(t,"clickable")},setLink:function(t,e,n){t.split(",").forEach((function(t){void 0!==wC[t]&&(wC[t].link=rv.formatUrl(e,kC),wC[t].linkTarget=n)})),IC(t,"clickable")},bindFunctions:function(t){NC.forEach((function(e){e(t)}))},getDirection:function(){return _C.trim()},getVertices:function(){return wC},getEdges:function(){return TC},getClasses:function(){return CC},clear:function(t="gen-1"){wC={},CC={},TC=[],NC=[FC],EC=[],SC={},DC=0,AC=[],LC=!0,xC=t,Kv()},setGen:t=>{xC=t||"gen-1"},defaultStyle:function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},addSubGraph:function(t,e,n){let i=t.trim(),r=n;t===n&&n.match(/\s/)&&(i=void 0);let a=[];const{nodeList:s,dir:o}=function(t){const e={boolean:{},number:{},string:{}},n=[];let i;return{nodeList:t.filter((function(t){const r=typeof t;return t.stmt&&"dir"===t.stmt?(i=t.value,!1):""!==t.trim()&&(r in e?!e[r].hasOwnProperty(t)&&(e[r][t]=!0):!n.includes(t)&&n.push(t))})),dir:i}}(a.concat.apply(a,e));if(a=s,"gen-1"===xC)for(let l=0;l<a.length;l++)a[l]=BC(a[l]);i=i||"subGraph"+DC,r=r||"",r=OC(r),DC+=1;const c={id:i,nodes:a,title:r.trim(),classes:[],dir:o};return Bb.info("Adding",c.id,c.nodes,c.dir),c.nodes=zC(c,EC).nodes,EC.push(c),SC[i]=c,i},getDepthFirstPos:function(t){return PC[t]},indexNodes:function(){$C=-1,EC.length>0&&jC("none",EC.length-1)},getSubGraphs:function(){return EC},destructLink:(t,e)=>{const n=(t=>{const e=t.trim();let n=e.slice(0,-1),i="arrow_open";switch(e.slice(-1)){case"x":i="arrow_cross","x"===e[0]&&(i="double_"+i,n=n.slice(1));break;case">":i="arrow_point","<"===e[0]&&(i="double_"+i,n=n.slice(1));break;case"o":i="arrow_circle","o"===e[0]&&(i="double_"+i,n=n.slice(1))}let r="normal",a=n.length-1;"="===n[0]&&(r="thick");let s=((t,e)=>{const n=e.length;let i=0;for(let r=0;r<n;++r)e[r]===t&&++i;return i})(".",n);return s&&(r="dotted",a=s),{type:i,stroke:r,length:a}})(t);let i;if(e){if(i=(t=>{let e=t.trim(),n="arrow_open";switch(e[0]){case"<":n="arrow_point",e=e.slice(1);break;case"x":n="arrow_cross",e=e.slice(1);break;case"o":n="arrow_circle",e=e.slice(1)}let i="normal";return e.includes("=")&&(i="thick"),e.includes(".")&&(i="dotted"),{type:n,stroke:i}})(e),i.stroke!==n.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===i.type)i.type=n.type;else{if(i.type!==n.type)return{type:"INVALID",stroke:"INVALID"};i.type="double_"+i.type}return"double_arrow"===i.type&&(i.type="double_arrow_point"),i.length=n.length,i}return n},lex:{firstGraph:()=>!!LC&&(LC=!1,!0)},exists:YC,makeUniq:zC,setDiagramTitle:ik,getDiagramTitle:rk};const WC={},HC=function(t){const e=Object.keys(t);for(const n of e)WC[n]=t[n]},qC={},VC=function(t,e,n,i,r,a){const s=i.select(`[id="${n}"]`);Object.keys(t).forEach((function(n){const i=t[n];let o="default";i.classes.length>0&&(o=i.classes.join(" "));const c=Wx(i.styles);let l,h=void 0!==i.text?i.text:i.id;if(zb(fv().flowchart.htmlLabels)){const t={label:h.replace(/fa[blrs]?:fa-[\w-]+/g,(t=>`<i class='${t.replace(":"," ")}'></i>`))};l=Db(s,t).node(),l.parentNode.removeChild(l)}else{const t=r.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",c.labelStyle.replace("color:","fill:"));const e=h.split(Wb.lineBreakRegex);for(const n of e){const e=r.createElementNS("http://www.w3.org/2000/svg","tspan");e.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),e.setAttribute("dy","1em"),e.setAttribute("x","1"),e.textContent=n,t.appendChild(e)}l=t}let u=0,d="";switch(i.type){case"round":u=5,d="rect";break;case"square":case"group":default:d="rect";break;case"diamond":d="question";break;case"hexagon":d="hexagon";break;case"odd":case"odd_right":d="rect_left_inv_arrow";break;case"lean_right":d="lean_right";break;case"lean_left":d="lean_left";break;case"trapezoid":d="trapezoid";break;case"inv_trapezoid":d="inv_trapezoid";break;case"circle":d="circle";break;case"ellipse":d="ellipse";break;case"stadium":d="stadium";break;case"subroutine":d="subroutine";break;case"cylinder":d="cylinder";break;case"doublecircle":d="doublecircle"}e.setNode(i.id,{labelStyle:c.labelStyle,shape:d,labelText:h,rx:u,ry:u,class:o,style:c.style,id:i.id,link:i.link,linkTarget:i.linkTarget,tooltip:a.db.getTooltip(i.id)||"",domId:a.db.lookUpDomId(i.id),haveCallback:i.haveCallback,width:"group"===i.type?500:void 0,dir:i.dir,type:i.type,props:i.props,padding:fv().flowchart.padding}),Bb.info("setNode",{labelStyle:c.labelStyle,shape:d,labelText:h,rx:u,ry:u,class:o,style:c.style,id:i.id,domId:a.db.lookUpDomId(i.id),width:"group"===i.type?500:void 0,type:i.type,dir:i.dir,props:i.props,padding:fv().flowchart.padding})}))},GC=function(t,e,n){Bb.info("abc78 edges = ",t);let i,r,a=0,s={};if(void 0!==t.defaultStyle){const e=Wx(t.defaultStyle);i=e.style,r=e.labelStyle}t.forEach((function(n){a++;var o="L-"+n.start+"-"+n.end;void 0===s[o]?(s[o]=0,Bb.info("abc78 new entry",o,s[o])):(s[o]++,Bb.info("abc78 new entry",o,s[o]));let c=o+"-"+s[o];Bb.info("abc78 new link id to be used is",o,c,s[o]);var l="LS-"+n.start,h="LE-"+n.end;const u={style:"",labelStyle:""};switch(u.minlen=n.length||1,"arrow_open"===n.type?u.arrowhead="none":u.arrowhead="normal",u.arrowTypeStart="arrow_open",u.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":u.arrowTypeStart="arrow_cross";case"arrow_cross":u.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":u.arrowTypeStart="arrow_point";case"arrow_point":u.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":u.arrowTypeStart="arrow_circle";case"arrow_circle":u.arrowTypeEnd="arrow_circle"}let d="",p="";switch(n.stroke){case"normal":d="fill:none;",void 0!==i&&(d=i),void 0!==r&&(p=r),u.thickness="normal",u.pattern="solid";break;case"dotted":u.thickness="normal",u.pattern="dotted",u.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":u.thickness="thick",u.pattern="solid",u.style="stroke-width: 3.5px;fill:none;"}if(void 0!==n.style){const t=Wx(n.style);d=t.style,p=t.labelStyle}u.style=u.style+=d,u.labelStyle=u.labelStyle+=p,void 0!==n.interpolate?u.curve=zx(n.interpolate,Ac):void 0!==t.defaultInterpolate?u.curve=zx(t.defaultInterpolate,Ac):u.curve=zx(qC.curve,Ac),void 0===n.text?void 0!==n.style&&(u.arrowheadStyle="fill: #333"):(u.arrowheadStyle="fill: #333",u.labelpos="c"),u.labelType="text",u.label=n.text.replace(Wb.lineBreakRegex,"\n"),void 0===n.style&&(u.style=u.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),u.labelStyle=u.labelStyle.replace("color:","fill:"),u.id=c,u.classes="flowchart-link "+l+" "+h,e.setEdge(n.start,n.end,u,a)}))},XC={setConf:function(t){const e=Object.keys(t);for(const n of e)qC[n]=t[n]},addVertices:VC,addEdges:GC,getClasses:function(t,e){Bb.info("Extracting classes"),e.db.clear();try{return e.parse(t),e.db.getClasses()}catch(n){return}},draw:function(t,e,n,i){Bb.info("Drawing flowchart"),i.db.clear(),UC.setGen("gen-2"),i.parser.parse(t);let r=i.db.getDirection();void 0===r&&(r="TD");const{securityLevel:a,flowchart:s}=fv(),o=s.nodeSpacing||50,c=s.rankSpacing||50;let l;"sandbox"===a&&(l=Xo("#i"+e));const h=Xo("sandbox"===a?l.nodes()[0].contentDocument.body:"body"),u="sandbox"===a?l.nodes()[0].contentDocument:document,d=new Qf({multigraph:!0,compound:!0}).setGraph({rankdir:r,nodesep:o,ranksep:c,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let p;const f=i.db.getSubGraphs();Bb.info("Subgraphs - ",f);for(let x=f.length-1;x>=0;x--)p=f[x],Bb.info("Subgraph - ",p),i.db.addVertex(p.id,p.title,"group",void 0,p.classes,p.dir);const g=i.db.getVertices(),y=i.db.getEdges();Bb.info(y);let m=0;for(m=f.length-1;m>=0;m--){p=f[m],Zo("cluster").append("text");for(let t=0;t<p.nodes.length;t++)Bb.info("Setting up subgraphs",p.nodes[t],p.id),d.setParent(p.nodes[t],p.id)}VC(g,d,e,h,u,i),GC(y,d);const b=h.select(`[id="${e}"]`),_=h.select("#"+e+" g");if(qT(_,d,["point","circle","cross"],"flowchart",e),rv.insertTitle(b,"flowchartTitleText",s.titleTopMargin,i.db.getDiagramTitle()),kv(d,b,s.diagramPadding,s.useMaxWidth),i.db.indexNodes("subGraph"+m),!s.htmlLabels){const t=u.querySelectorAll('[id="'+e+'"] .edgeLabel .label');for(const e of t){const t=e.getBBox(),n=u.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("rx",0),n.setAttribute("ry",0),n.setAttribute("width",t.width),n.setAttribute("height",t.height),e.insertBefore(n,e.firstChild)}}Object.keys(g).forEach((function(t){const n=g[t];if(n.link){const i=Xo("#"+e+' [id="'+t+'"]');if(i){const t=u.createElementNS("http://www.w3.org/2000/svg","a");t.setAttributeNS("http://www.w3.org/2000/svg","class",n.classes.join(" ")),t.setAttributeNS("http://www.w3.org/2000/svg","href",n.link),t.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),"sandbox"===a?t.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):n.linkTarget&&t.setAttributeNS("http://www.w3.org/2000/svg","target",n.linkTarget);const e=i.insert((function(){return t}),":first-child"),r=i.select(".label-container");r&&e.append((function(){return r.node()}));const s=i.select(".label");s&&e.append((function(){return s.node()}))}}}))}};var ZC=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,3],i=[1,5],r=[7,9,11,12,13,14,15,16,17,18,19,20,21,23,25,26,28,35,40],a=[1,15],s=[1,16],o=[1,17],c=[1,18],l=[1,19],h=[1,20],u=[1,21],d=[1,22],p=[1,23],f=[1,24],g=[1,25],y=[1,26],m=[1,27],b=[1,29],_=[1,31],x=[1,34],v=[5,7,9,11,12,13,14,15,16,17,18,19,20,21,23,25,26,28,35,40],k={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,gantt:5,document:6,EOF:7,line:8,SPACE:9,statement:10,NL:11,dateFormat:12,inclusiveEndDates:13,topAxis:14,axisFormat:15,tickInterval:16,excludes:17,includes:18,todayMarker:19,title:20,acc_title:21,acc_title_value:22,acc_descr:23,acc_descr_value:24,acc_descr_multiline_value:25,section:26,clickStatement:27,taskTxt:28,taskData:29,openDirective:30,typeDirective:31,closeDirective:32,":":33,argDirective:34,click:35,callbackname:36,callbackargs:37,href:38,clickStatementDebug:39,open_directive:40,type_directive:41,arg_directive:42,close_directive:43,$accept:0,$end:1},terminals_:{2:"error",5:"gantt",7:"EOF",9:"SPACE",11:"NL",12:"dateFormat",13:"inclusiveEndDates",14:"topAxis",15:"axisFormat",16:"tickInterval",17:"excludes",18:"includes",19:"todayMarker",20:"title",21:"acc_title",22:"acc_title_value",23:"acc_descr",24:"acc_descr_value",25:"acc_descr_multiline_value",26:"section",28:"taskTxt",29:"taskData",33:":",35:"click",36:"callbackname",37:"callbackargs",38:"href",40:"open_directive",41:"type_directive",42:"arg_directive",43:"close_directive"},productions_:[0,[3,2],[3,3],[6,0],[6,2],[8,2],[8,1],[8,1],[8,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[10,1],[10,1],[10,2],[10,1],[4,4],[4,6],[27,2],[27,3],[27,3],[27,4],[27,3],[27,4],[27,2],[39,2],[39,3],[39,3],[39,4],[39,3],[39,4],[39,2],[30,1],[31,1],[34,1],[32,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 2:return a[o-1];case 3:case 7:case 8:this.$=[];break;case 4:a[o-1].push(a[o]),this.$=a[o-1];break;case 5:case 6:this.$=a[o];break;case 9:i.setDateFormat(a[o].substr(11)),this.$=a[o].substr(11);break;case 10:i.enableInclusiveEndDates(),this.$=a[o].substr(18);break;case 11:i.TopAxis(),this.$=a[o].substr(8);break;case 12:i.setAxisFormat(a[o].substr(11)),this.$=a[o].substr(11);break;case 13:i.setTickInterval(a[o].substr(13)),this.$=a[o].substr(13);break;case 14:i.setExcludes(a[o].substr(9)),this.$=a[o].substr(9);break;case 15:i.setIncludes(a[o].substr(9)),this.$=a[o].substr(9);break;case 16:i.setTodayMarker(a[o].substr(12)),this.$=a[o].substr(12);break;case 17:i.setDiagramTitle(a[o].substr(6)),this.$=a[o].substr(6);break;case 18:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 19:case 20:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 21:i.addSection(a[o].substr(8)),this.$=a[o].substr(8);break;case 23:i.addTask(a[o-1],a[o]),this.$="task";break;case 27:this.$=a[o-1],i.setClickEvent(a[o-1],a[o],null);break;case 28:this.$=a[o-2],i.setClickEvent(a[o-2],a[o-1],a[o]);break;case 29:this.$=a[o-2],i.setClickEvent(a[o-2],a[o-1],null),i.setLink(a[o-2],a[o]);break;case 30:this.$=a[o-3],i.setClickEvent(a[o-3],a[o-2],a[o-1]),i.setLink(a[o-3],a[o]);break;case 31:this.$=a[o-2],i.setClickEvent(a[o-2],a[o],null),i.setLink(a[o-2],a[o-1]);break;case 32:this.$=a[o-3],i.setClickEvent(a[o-3],a[o-1],a[o]),i.setLink(a[o-3],a[o-2]);break;case 33:this.$=a[o-1],i.setLink(a[o-1],a[o]);break;case 34:case 40:this.$=a[o-1]+" "+a[o];break;case 35:case 36:case 38:this.$=a[o-2]+" "+a[o-1]+" "+a[o];break;case 37:case 39:this.$=a[o-3]+" "+a[o-2]+" "+a[o-1]+" "+a[o];break;case 41:i.parseDirective("%%{","open_directive");break;case 42:i.parseDirective(a[o],"type_directive");break;case 43:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 44:i.parseDirective("}%%","close_directive","gantt")}},table:[{3:1,4:2,5:n,30:4,40:i},{1:[3]},{3:6,4:2,5:n,30:4,40:i},e(r,[2,3],{6:7}),{31:8,41:[1,9]},{41:[2,41]},{1:[2,1]},{4:30,7:[1,10],8:11,9:[1,12],10:13,11:[1,14],12:a,13:s,14:o,15:c,16:l,17:h,18:u,19:d,20:p,21:f,23:g,25:y,26:m,27:28,28:b,30:4,35:_,40:i},{32:32,33:[1,33],43:x},e([33,43],[2,42]),e(r,[2,8],{1:[2,2]}),e(r,[2,4]),{4:30,10:35,12:a,13:s,14:o,15:c,16:l,17:h,18:u,19:d,20:p,21:f,23:g,25:y,26:m,27:28,28:b,30:4,35:_,40:i},e(r,[2,6]),e(r,[2,7]),e(r,[2,9]),e(r,[2,10]),e(r,[2,11]),e(r,[2,12]),e(r,[2,13]),e(r,[2,14]),e(r,[2,15]),e(r,[2,16]),e(r,[2,17]),{22:[1,36]},{24:[1,37]},e(r,[2,20]),e(r,[2,21]),e(r,[2,22]),{29:[1,38]},e(r,[2,24]),{36:[1,39],38:[1,40]},{11:[1,41]},{34:42,42:[1,43]},{11:[2,44]},e(r,[2,5]),e(r,[2,18]),e(r,[2,19]),e(r,[2,23]),e(r,[2,27],{37:[1,44],38:[1,45]}),e(r,[2,33],{36:[1,46]}),e(v,[2,25]),{32:47,43:x},{43:[2,43]},e(r,[2,28],{38:[1,48]}),e(r,[2,29]),e(r,[2,31],{37:[1,49]}),{11:[1,50]},e(r,[2,30]),e(r,[2,32]),e(v,[2,26])],defaultActions:{5:[2,41],6:[2,1],34:[2,44],43:[2,43]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},w=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),40;case 1:return this.begin("type_directive"),41;case 2:return this.popState(),this.begin("arg_directive"),33;case 3:return this.popState(),this.popState(),43;case 4:return 42;case 5:return this.begin("acc_title"),21;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),23;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:case 20:case 23:case 26:case 29:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:case 13:case 14:case 16:case 17:case 18:break;case 15:return 11;case 19:this.begin("href");break;case 21:return 38;case 22:this.begin("callbackname");break;case 24:this.popState(),this.begin("callbackargs");break;case 25:return 36;case 27:return 37;case 28:this.begin("click");break;case 30:return 35;case 31:return 5;case 32:return 12;case 33:return 13;case 34:return 14;case 35:return 15;case 36:return 16;case 37:return 18;case 38:return 17;case 39:return 19;case 40:return"date";case 41:return 20;case 42:return"accDescription";case 43:return 26;case 44:return 28;case 45:return 29;case 46:return 33;case 47:return 7;case 48:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[26,27],inclusive:!1},callbackname:{rules:[23,24,25],inclusive:!1},href:{rules:[20,21],inclusive:!1},click:{rules:[29,30],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,22,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],inclusive:!0}}},t);function T(){this.yy={}}return k.lexer=w,T.prototype=k,k.Parser=T,new T}();ZC.parser=ZC;const QC=ZC,KC=t=>null!==t.match(/^\s*gantt/);let JC,tE="",eE="",nE="",iE=[],rE=[],aE={},sE=[],oE=[],cE="";const lE=["active","done","crit","milestone"];let hE=[],uE=!1,dE=!1,pE=0;const fE=function(t,e,n,i){return!i.includes(t.format(e.trim()))&&(!!(t.isoWeekday()>=6&&n.includes("weekends"))||(!!n.includes(t.format("dddd").toLowerCase())||n.includes(t.format(e.trim()))))},gE=function(t,e,n,i){if(!n.length||t.manualEndTime)return;let r=wt(t.startTime,e,!0);r.add(1,"d");let a=wt(t.endTime,e,!0),s=yE(r,a,e,n,i);t.endTime=a.toDate(),t.renderEndTime=s},yE=function(t,e,n,i,r){let a=!1,s=null;for(;t<=e;)a||(s=e.toDate()),a=fE(t,n,i,r),a&&e.add(1,"d"),t.add(1,"d");return s},mE=function(t,e,n){n=n.trim();const i=/^after\s+([\d\w- ]+)/.exec(n.trim());if(null!==i){let t=null;if(i[1].split(" ").forEach((function(e){let n=EE(e);void 0!==n&&(t?n.endTime>t.endTime&&(t=n):t=n)})),t)return t.endTime;{const t=new Date;return t.setHours(0,0,0,0),t}}let r=wt(n,e.trim(),!0);if(r.isValid())return r.toDate();{Bb.debug("Invalid date:"+n),Bb.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime()))throw new Error("Invalid date:"+n);return t}},bE=function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?wt.duration(Number.parseFloat(e[1]),e[2]):wt.duration.invalid()},_E=function(t,e,n,i=!1){n=n.trim();let r=wt(n,e.trim(),!0);if(r.isValid())return i&&r.add(1,"d"),r.toDate();const a=wt(t),s=bE(n);return s.isValid()&&a.add(s),a.toDate()};let xE=0;const vE=function(t){return void 0===t?(xE+=1,"task"+xE):t};let kE,wE,TE=[];const CE={},EE=function(t){const e=CE[t];return TE[e]},SE=function(){const t=function(t){const e=TE[t];let n="";switch(TE[t].raw.startTime.type){case"prevTaskEnd":{const t=EE(e.prevTaskId);e.startTime=t.endTime;break}case"getStartDate":n=mE(0,tE,TE[t].raw.startTime.startData),n&&(TE[t].startTime=n)}return TE[t].startTime&&(TE[t].endTime=_E(TE[t].startTime,tE,TE[t].raw.endTime.data,uE),TE[t].endTime&&(TE[t].processed=!0,TE[t].manualEndTime=wt(TE[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),gE(TE[t],tE,rE,iE))),TE[t].processed};let e=!0;for(const[n,i]of TE.entries())t(n),e=e&&i.processed;return e},AE=function(t,e){t.split(",").forEach((function(t){let n=EE(t);void 0!==n&&n.classes.push(e)}))},DE=function(t,e){hE.push((function(){const n=document.querySelector(`[id="${t}"]`);null!==n&&n.addEventListener("click",(function(){e()}))}),(function(){const n=document.querySelector(`[id="${t}-text"]`);null!==n&&n.addEventListener("click",(function(){e()}))}))},LE={parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().gantt,clear:function(){sE=[],oE=[],cE="",hE=[],xE=0,kE=void 0,wE=void 0,TE=[],tE="",eE="",JC=void 0,nE="",iE=[],rE=[],uE=!1,dE=!1,pE=0,aE={},Kv()},setDateFormat:function(t){tE=t},getDateFormat:function(){return tE},enableInclusiveEndDates:function(){uE=!0},endDatesAreInclusive:function(){return uE},enableTopAxis:function(){dE=!0},topAxisEnabled:function(){return dE},setAxisFormat:function(t){eE=t},getAxisFormat:function(){return eE},setTickInterval:function(t){JC=t},getTickInterval:function(){return JC},setTodayMarker:function(t){nE=t},getTodayMarker:function(){return nE},setAccTitle:Jv,getAccTitle:tk,setDiagramTitle:ik,getDiagramTitle:rk,setAccDescription:ek,getAccDescription:nk,addSection:function(t){cE=t,sE.push(t)},getSections:function(){return sE},getTasks:function(){let t=SE();let e=0;for(;!t&&e<10;)t=SE(),e++;return oE=TE,oE},addTask:function(t,e){const n={section:cE,type:cE,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},i=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),r={};NE(i,r,lE);for(let a=0;a<i.length;a++)i[a]=i[a].trim();switch(i.length){case 1:r.id=vE(),r.startTime={type:"prevTaskEnd",id:t},r.endTime={data:i[0]};break;case 2:r.id=vE(),r.startTime={type:"getStartDate",startData:i[0]},r.endTime={data:i[1]};break;case 3:r.id=vE(i[0]),r.startTime={type:"getStartDate",startData:i[1]},r.endTime={data:i[2]}}return r}(wE,e);n.raw.startTime=i.startTime,n.raw.endTime=i.endTime,n.id=i.id,n.prevTaskId=wE,n.active=i.active,n.done=i.done,n.crit=i.crit,n.milestone=i.milestone,n.order=pE,pE++;const r=TE.push(n);wE=n.id,CE[n.id]=r-1},findTaskById:EE,addTaskOrg:function(t,e){const n={section:cE,type:cE,description:t,task:t,classes:[]},i=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),r={};NE(i,r,lE);for(let s=0;s<i.length;s++)i[s]=i[s].trim();let a="";switch(i.length){case 1:r.id=vE(),r.startTime=t.endTime,a=i[0];break;case 2:r.id=vE(),r.startTime=mE(0,tE,i[0]),a=i[1];break;case 3:r.id=vE(i[0]),r.startTime=mE(0,tE,i[1]),a=i[2]}return a&&(r.endTime=_E(r.startTime,tE,a,uE),r.manualEndTime=wt(a,"YYYY-MM-DD",!0).isValid(),gE(r,tE,rE,iE)),r}(kE,e);n.startTime=i.startTime,n.endTime=i.endTime,n.id=i.id,n.active=i.active,n.done=i.done,n.crit=i.crit,n.milestone=i.milestone,kE=n,oE.push(n)},setIncludes:function(t){iE=t.toLowerCase().split(/[\s,]+/)},getIncludes:function(){return iE},setExcludes:function(t){rE=t.toLowerCase().split(/[\s,]+/)},getExcludes:function(){return rE},setClickEvent:function(t,e,n){t.split(",").forEach((function(t){!function(t,e,n){if("loose"!==fv().securityLevel)return;if(void 0===e)return;let i=[];if("string"==typeof n){i=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<i.length;t++){let e=i[t].trim();'"'===e.charAt(0)&&'"'===e.charAt(e.length-1)&&(e=e.substr(1,e.length-2)),i[t]=e}}0===i.length&&i.push(t),void 0!==EE(t)&&DE(t,(()=>{rv.runFunc(e,...i)}))}(t,e,n)})),AE(t,"clickable")},setLink:function(t,e){let n=e;"loose"!==fv().securityLevel&&(n=(0,Tt.N)(e)),t.split(",").forEach((function(t){void 0!==EE(t)&&(DE(t,(()=>{window.open(n,"_self")})),aE[t]=n)})),AE(t,"clickable")},getLinks:function(){return aE},bindFunctions:function(t){hE.forEach((function(e){e(t)}))},parseDuration:bE,isInvalidDate:fE};function NE(t,e,n){let i=!0;for(;i;)i=!1,n.forEach((function(n){const r=new RegExp("^\\s*"+n+"\\s*$");t[0].match(r)&&(e[n]=!0,t.shift(1),i=!0)}))}let OE;const BE={setConf:function(){Bb.debug("Something is calling, setConf, remove the call")},draw:function(t,e,n,i){const r=fv().gantt,a=fv().securityLevel;let s;"sandbox"===a&&(s=Xo("#i"+e));const o=Xo("sandbox"===a?s.nodes()[0].contentDocument.body:"body"),c="sandbox"===a?s.nodes()[0].contentDocument:document,l=c.getElementById(e);OE=l.parentElement.offsetWidth,void 0===OE&&(OE=1200),void 0!==r.useWidth&&(OE=r.useWidth);const h=i.db.getTasks(),u=h.length*(r.barHeight+r.barGap)+2*r.topPadding;l.setAttribute("viewBox","0 0 "+OE+" "+u);const d=o.select(`[id="${e}"]`),p=function(){return sa.apply(Go(vs,ks,ys,fs,Ja,Xa,Va,Ha,Wa,Ss).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}().domain([Et(h,(function(t){return t.startTime})),Ct(h,(function(t){return t.endTime}))]).rangeRound([0,OE-r.leftPadding-r.rightPadding]);let f=[];for(const m of h)f.push(m.type);const g=f;function y(t,e){return function(t){let e=t.length;const n={};for(;e;)n[t[--e]]=(n[t[e]]||0)+1;return n}(e)[t]||0}f=function(t){const e={},n=[];for(let i=0,r=t.length;i<r;++i)Object.prototype.hasOwnProperty.call(e,t[i])||(e[t[i]]=!0,n.push(t[i]));return n}(f),h.sort((function(t,e){const n=t.startTime,i=e.startTime;let r=0;return n>i?r=1:n<i&&(r=-1),r})),function(t,n,a){const s=r.barHeight,o=s+r.barGap,l=r.topPadding,h=r.leftPadding;Ta().domain([0,f.length]).range(["#00B9FA","#F95002"]).interpolate(Nr);(function(t,e,n,a,s,o,c,l){const h=o.reduce(((t,{startTime:e})=>t?Math.min(t,e):e),0),u=o.reduce(((t,{endTime:e})=>t?Math.max(t,e):e),0),f=i.db.getDateFormat();if(!h||!u)return;const g=[];let y=null,m=wt(h);for(;m.valueOf()<=u;)i.db.isInvalidDate(m,f,c,l)?y?y.end=m.clone():y={start:m.clone(),end:m.clone()}:y&&(g.push(y),y=null),m.add(1,"d");d.append("g").selectAll("rect").data(g).enter().append("rect").attr("id",(function(t){return"exclude-"+t.start.format("YYYY-MM-DD")})).attr("x",(function(t){return p(t.start)+n})).attr("y",r.gridLineStartPadding).attr("width",(function(t){const e=t.end.clone().add(1,"day");return p(e)-p(t.start)})).attr("height",s-e-r.gridLineStartPadding).attr("transform-origin",(function(e,i){return(p(e.start)+n+.5*(p(e.end)-p(e.start))).toString()+"px "+(i*t+.5*s).toString()+"px"})).attr("class","exclude-range")})(o,l,h,0,a,t,i.db.getExcludes(),i.db.getIncludes()),function(t,e,n,a){let s=(o=p,Mt(3,o)).tickSize(-a+e+r.gridLineStartPadding).tickFormat(Ss(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));var o;const c=/^([1-9]\d*)(minute|hour|day|week|month)$/.exec(i.db.getTickInterval()||r.tickInterval);if(null!==c){const t=c[1];switch(c[2]){case"minute":s.ticks(Ha.every(t));break;case"hour":s.ticks(Va.every(t));break;case"day":s.ticks(Xa.every(t));break;case"week":s.ticks(Ja.every(t));break;case"month":s.ticks(fs.every(t))}}if(d.append("g").attr("class","grid").attr("transform","translate("+t+", "+(a-50)+")").call(s).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),i.db.topAxisEnabled()||r.topAxis){let n=function(t){return Mt(1,t)}(p).tickSize(-a+e+r.gridLineStartPadding).tickFormat(Ss(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));if(null!==c){const t=c[1];switch(c[2]){case"minute":n.ticks(Ha.every(t));break;case"hour":n.ticks(Va.every(t));break;case"day":n.ticks(Xa.every(t));break;case"week":n.ticks(Ja.every(t));break;case"month":n.ticks(fs.every(t))}}d.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}(h,l,0,a),function(t,n,a,s,o,c,l){d.append("g").selectAll("rect").data(t).enter().append("rect").attr("x",0).attr("y",(function(t,e){return t.order*n+a-2})).attr("width",(function(){return l-r.rightPadding/2})).attr("height",n).attr("class",(function(t){for(const[e,n]of f.entries())if(t.type===n)return"section section"+e%r.numberSectionStyles;return"section section0"}));const h=d.append("g").selectAll("rect").data(t).enter(),u=i.db.getLinks();h.append("rect").attr("id",(function(t){return t.id})).attr("rx",3).attr("ry",3).attr("x",(function(t){return t.milestone?p(t.startTime)+s+.5*(p(t.endTime)-p(t.startTime))-.5*o:p(t.startTime)+s})).attr("y",(function(t,e){return t.order*n+a})).attr("width",(function(t){return t.milestone?o:p(t.renderEndTime||t.endTime)-p(t.startTime)})).attr("height",o).attr("transform-origin",(function(t,e){return e=t.order,(p(t.startTime)+s+.5*(p(t.endTime)-p(t.startTime))).toString()+"px "+(e*n+a+.5*o).toString()+"px"})).attr("class",(function(t){const e="task";let n="";t.classes.length>0&&(n=t.classes.join(" "));let i=0;for(const[s,o]of f.entries())t.type===o&&(i=s%r.numberSectionStyles);let a="";return t.active?t.crit?a+=" activeCrit":a=" active":t.done?a=t.crit?" doneCrit":" done":t.crit&&(a+=" crit"),0===a.length&&(a=" task"),t.milestone&&(a=" milestone "+a),a+=i,a+=" "+n,e+a})),h.append("text").attr("id",(function(t){return t.id+"-text"})).text((function(t){return t.task})).attr("font-size",r.fontSize).attr("x",(function(t){let e=p(t.startTime),n=p(t.renderEndTime||t.endTime);t.milestone&&(e+=.5*(p(t.endTime)-p(t.startTime))-.5*o),t.milestone&&(n=e+o);const i=this.getBBox().width;return i>n-e?n+i+1.5*r.leftPadding>l?e+s-5:n+s+5:(n-e)/2+e+s})).attr("y",(function(t,e){return t.order*n+r.barHeight/2+(r.fontSize/2-2)+a})).attr("text-height",o).attr("class",(function(t){const e=p(t.startTime);let n=p(t.endTime);t.milestone&&(n=e+o);const i=this.getBBox().width;let a="";t.classes.length>0&&(a=t.classes.join(" "));let s=0;for(const[o,l]of f.entries())t.type===l&&(s=o%r.numberSectionStyles);let c="";return t.active&&(c=t.crit?"activeCritText"+s:"activeText"+s),t.done?c=t.crit?c+" doneCritText"+s:c+" doneText"+s:t.crit&&(c=c+" critText"+s),t.milestone&&(c+=" milestoneText"),i>n-e?n+i+1.5*r.leftPadding>l?a+" taskTextOutsideLeft taskTextOutside"+s+" "+c:a+" taskTextOutsideRight taskTextOutside"+s+" "+c+" width-"+i:a+" taskText taskText"+s+" "+c+" width-"+i}));if("sandbox"===fv().securityLevel){let t;t=Xo("#i"+e);const n=t.nodes()[0].contentDocument;h.filter((function(t){return void 0!==u[t.id]})).each((function(t){var e=n.querySelector("#"+t.id),i=n.querySelector("#"+t.id+"-text");const r=e.parentNode;var a=n.createElement("a");a.setAttribute("xlink:href",u[t.id]),a.setAttribute("target","_top"),r.appendChild(a),a.appendChild(e),a.appendChild(i)}))}}(t,o,l,h,s,0,n),function(t,e){const n=[];let i=0;for(const[r,a]of f.entries())n[r]=[a,y(a,g)];d.append("g").selectAll("text").data(n).enter().append((function(t){const e=t[0].split(Wb.lineBreakRegex),n=-(e.length-1)/2,i=c.createElementNS("http://www.w3.org/2000/svg","text");i.setAttribute("dy",n+"em");for(const[r,a]of e.entries()){const t=c.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttribute("alignment-baseline","central"),t.setAttribute("x","10"),r>0&&t.setAttribute("dy","1em"),t.textContent=a,i.appendChild(t)}return i})).attr("x",10).attr("y",(function(r,a){if(!(a>0))return r[1]*t/2+e;for(let s=0;s<a;s++)return i+=n[a-1][1],r[1]*t/2+i*t+e})).attr("font-size",r.sectionFontSize).attr("font-size",r.sectionFontSize).attr("class",(function(t){for(const[e,n]of f.entries())if(t[0]===n)return"sectionTitle sectionTitle"+e%r.numberSectionStyles;return"sectionTitle"}))}(o,l),function(t,e,n,a){const s=i.db.getTodayMarker();if("off"===s)return;const o=d.append("g").attr("class","today"),c=new Date,l=o.append("line");l.attr("x1",p(c)+t).attr("x2",p(c)+t).attr("y1",r.titleTopMargin).attr("y2",a-r.titleTopMargin).attr("class","today"),""!==s&&l.attr("style",s.replace(/,/g,";"))}(h,0,0,a)}(h,OE,u),vv(d,u,OE,r.useMaxWidth),d.append("text").text(i.db.getDiagramTitle()).attr("x",OE/2).attr("y",r.titleTopMargin).attr("class","titleText")}};var ME=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[6,9,10],i={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,e,n,i,r,a,s){switch(a.length,r){case 1:return i;case 4:break;case 6:i.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},e(n,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},e(n,[2,3]),e(n,[2,4]),e(n,[2,5]),e(n,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},r=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}},t);function a(){this.yy={}}return i.lexer=r,a.prototype=i,i.Parser=a,new a}();ME.parser=ME;const IE=ME;var FE="",RE=!1;const $E={setMessage:t=>{Bb.debug("Setting message to: "+t),FE=t},getMessage:()=>FE,setInfo:t=>{RE=t},getInfo:()=>RE,clear:Kv},PE={draw:(t,e,n)=>{try{Bb.debug("Rendering info diagram\n"+t);const i=fv().securityLevel;let r;"sandbox"===i&&(r=Xo("#i"+e));const a=Xo("sandbox"===i?r.nodes()[0].contentDocument.body:"body").select("#"+e);a.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size","32px").style("text-anchor","middle").text("v "+n),a.attr("height",100),a.attr("width",400)}catch(i){Bb.error("Error while rendering info diagram"),Bb.error(i.message)}}},jE=t=>null!==t.match(/^\s*info/);var YE=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,4],i=[1,5],r=[1,6],a=[1,7],s=[1,9],o=[1,11,13,15,17,19,20,26,27,28,29],c=[2,5],l=[1,6,11,13,15,17,19,20,26,27,28,29],h=[26,27,28],u=[2,8],d=[1,18],p=[1,19],f=[1,20],g=[1,21],y=[1,22],m=[1,23],b=[1,28],_=[6,26,27,28,29],x={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,PIE:6,document:7,showData:8,line:9,statement:10,txt:11,value:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,openDirective:21,typeDirective:22,closeDirective:23,":":24,argDirective:25,NEWLINE:26,";":27,EOF:28,open_directive:29,type_directive:30,arg_directive:31,close_directive:32,$accept:0,$end:1},terminals_:{2:"error",6:"PIE",8:"showData",11:"txt",12:"value",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",24:":",26:"NEWLINE",27:";",28:"EOF",29:"open_directive",30:"type_directive",31:"arg_directive",32:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,3],[7,0],[7,2],[9,2],[10,0],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,1],[5,3],[5,5],[4,1],[4,1],[4,1],[21,1],[22,1],[25,1],[23,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 4:i.setShowData(!0);break;case 7:this.$=a[o-1];break;case 9:i.addSection(a[o-1],i.cleanupValue(a[o]));break;case 10:this.$=a[o].trim(),i.setDiagramTitle(this.$);break;case 11:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 12:case 13:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 14:i.addSection(a[o].substr(8)),this.$=a[o].substr(8);break;case 21:i.parseDirective("%%{","open_directive");break;case 22:i.parseDirective(a[o],"type_directive");break;case 23:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 24:i.parseDirective("}%%","close_directive","pie")}},table:[{3:1,4:2,5:3,6:n,21:8,26:i,27:r,28:a,29:s},{1:[3]},{3:10,4:2,5:3,6:n,21:8,26:i,27:r,28:a,29:s},{3:11,4:2,5:3,6:n,21:8,26:i,27:r,28:a,29:s},e(o,c,{7:12,8:[1,13]}),e(l,[2,18]),e(l,[2,19]),e(l,[2,20]),{22:14,30:[1,15]},{30:[2,21]},{1:[2,1]},{1:[2,2]},e(h,u,{21:8,9:16,10:17,5:24,1:[2,3],11:d,13:p,15:f,17:g,19:y,20:m,29:s}),e(o,c,{7:25}),{23:26,24:[1,27],32:b},e([24,32],[2,22]),e(o,[2,6]),{4:29,26:i,27:r,28:a},{12:[1,30]},{14:[1,31]},{16:[1,32]},{18:[1,33]},e(h,[2,13]),e(h,[2,14]),e(h,[2,15]),e(h,u,{21:8,9:16,10:17,5:24,1:[2,4],11:d,13:p,15:f,17:g,19:y,20:m,29:s}),e(_,[2,16]),{25:34,31:[1,35]},e(_,[2,24]),e(o,[2,7]),e(h,[2,9]),e(h,[2,10]),e(h,[2,11]),e(h,[2,12]),{23:36,32:b},{32:[2,23]},e(_,[2,17])],defaultActions:{9:[2,21],10:[2,1],11:[2,2],35:[2,23]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},v=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),29;case 1:return this.begin("type_directive"),30;case 2:return this.popState(),this.begin("arg_directive"),24;case 3:return this.popState(),this.popState(),32;case 4:return 31;case 5:case 6:case 8:case 9:break;case 7:return 26;case 10:return this.begin("title"),13;case 11:return this.popState(),"title_value";case 12:return this.begin("acc_title"),15;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),17;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:case 20:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:this.begin("string");break;case 21:return"txt";case 22:return 6;case 23:return 8;case 24:return"value";case 25:return 28}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[11],inclusive:!1},string:{rules:[20,21],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,12,14,16,19,22,23,24,25],inclusive:!0}}},t);function k(){this.yy={}}return x.lexer=v,k.prototype=x,x.Parser=k,new k}();YE.parser=YE;const zE=YE,UE=t=>null!==t.match(/^\s*pie/)||null!==t.match(/^\s*bar/);let WE={},HE=!1;const qE={parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().pie,addSection:function(t,e){t=Wb.sanitizeText(t,fv()),void 0===WE[t]&&(WE[t]=e,Bb.debug("Added new section :",t))},getSections:()=>WE,cleanupValue:function(t){return":"===t.substring(0,1)?(t=t.substring(1).trim(),Number(t.trim())):Number(t.trim())},clear:function(){WE={},HE=!1,Kv()},setAccTitle:Jv,getAccTitle:tk,setDiagramTitle:ik,getDiagramTitle:rk,setShowData:function(t){HE=t},getShowData:function(){return HE},getAccDescription:nk,setAccDescription:ek};let VE,GE=fv();const XE=450,ZE={draw:(t,e,n,i)=>{try{GE=fv(),Bb.debug("Rendering info diagram\n"+t);const n=fv().securityLevel;let y;"sandbox"===n&&(y=Xo("#i"+e));const m=Xo("sandbox"===n?y.nodes()[0].contentDocument.body:"body"),b="sandbox"===n?y.nodes()[0].contentDocument:document;i.db.clear(),i.parser.parse(t),Bb.debug("Parsed info diagram");const _=b.getElementById(e);VE=_.parentElement.offsetWidth,void 0===VE&&(VE=1200),void 0!==GE.useWidth&&(VE=GE.useWidth),void 0!==GE.pie.useWidth&&(VE=GE.pie.useWidth);const x=m.select("#"+e);vv(x,XE,VE,GE.pie.useMaxWidth),_.setAttribute("viewBox","0 0 "+VE+" "+XE);var r=18,a=Math.min(VE,XE)/2-40,s=x.append("g").attr("transform","translate("+VE/2+",225)"),o=i.db.getSections(),c=0;Object.keys(o).forEach((function(t){c+=o[t]}));const v=GE.themeVariables;var l=[v.pie1,v.pie2,v.pie3,v.pie4,v.pie5,v.pie6,v.pie7,v.pie8,v.pie9,v.pie10,v.pie11,v.pie12],h=Oa().range(l),u=Object.entries(o).map((function(t,e){return{order:e,name:t[0],value:t[1]}})),d=function(){var t=Bc,e=Oc,n=null,i=Qo(0),r=Qo(cc),a=Qo(0);function s(s){var o,c,l,h,u,d=(s=Ec(s)).length,p=0,f=new Array(d),g=new Array(d),y=+i.apply(this,arguments),m=Math.min(cc,Math.max(-cc,r.apply(this,arguments)-y)),b=Math.min(Math.abs(m)/d,a.apply(this,arguments)),_=b*(m<0?-1:1);for(o=0;o<d;++o)(u=g[f[o]=o]=+t(s[o],o,s))>0&&(p+=u);for(null!=e?f.sort((function(t,n){return e(g[t],g[n])})):null!=n&&f.sort((function(t,e){return n(s[t],s[e])})),o=0,l=p?(m-d*_)/p:0;o<d;++o,y=h)c=f[o],h=y+((u=g[c])>0?u*l:0)+_,g[c]={data:s[c],index:o,value:u,startAngle:y,endAngle:h,padAngle:b};return g}return s.value=function(e){return arguments.length?(t="function"==typeof e?e:Qo(+e),s):t},s.sortValues=function(t){return arguments.length?(e=t,n=null,s):e},s.sort=function(t){return arguments.length?(n=t,e=null,s):n},s.startAngle=function(t){return arguments.length?(i="function"==typeof t?t:Qo(+t),s):i},s.endAngle=function(t){return arguments.length?(r="function"==typeof t?t:Qo(+t),s):r},s.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:Qo(+t),s):a},s}().value((function(t){return t.value})).sort((function(t,e){return t.order-e.order})),p=d(u),f=Cc().innerRadius(0).outerRadius(a);s.selectAll("mySlices").data(p).enter().append("path").attr("d",f).attr("fill",(function(t){return h(t.data.name)})).attr("class","pieCircle"),s.selectAll("mySlices").data(p).enter().append("text").text((function(t){return(t.data.value/c*100).toFixed(0)+"%"})).attr("transform",(function(t){return"translate("+f.centroid(t)+")"})).style("text-anchor","middle").attr("class","slice"),s.append("text").text(i.db.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");var g=s.selectAll(".legend").data(h.domain()).enter().append("g").attr("class","legend").attr("transform",(function(t,e){return"translate(216,"+(22*e-22*h.domain().length/2)+")"}));g.append("rect").attr("width",r).attr("height",r).style("fill",h).style("stroke",h),g.data(p).append("text").attr("x",22).attr("y",14).text((function(t){return i.db.getShowData()||GE.showData||GE.pie.showData?t.data.name+" ["+t.data.value+"]":t.data.name}))}catch(y){Bb.error("Error while rendering info diagram"),Bb.error(y)}}};var QE=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,3],i=[1,5],r=[1,6],a=[1,7],s=[1,8],o=[5,6,8,14,16,18,19,40,41,42,43,44,45,53,71,72],c=[1,22],l=[2,13],h=[1,26],u=[1,27],d=[1,28],p=[1,29],f=[1,30],g=[1,31],y=[1,24],m=[1,32],b=[1,33],_=[1,36],x=[71,72],v=[5,8,14,16,18,19,40,41,42,43,44,45,53,60,62,71,72],k=[1,56],w=[1,57],T=[1,58],C=[1,59],E=[1,60],S=[1,61],A=[1,62],D=[62,63],L=[1,74],N=[1,70],O=[1,71],B=[1,72],M=[1,73],I=[1,75],F=[1,79],R=[1,80],$=[1,77],P=[1,78],j=[5,8,14,16,18,19,40,41,42,43,44,45,53,71,72],Y={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,openDirective:9,typeDirective:10,closeDirective:11,":":12,argDirective:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,requirementDef:23,elementDef:24,relationshipDef:25,requirementType:26,requirementName:27,STRUCT_START:28,requirementBody:29,ID:30,COLONSEP:31,id:32,TEXT:33,text:34,RISK:35,riskLevel:36,VERIFYMTHD:37,verifyType:38,STRUCT_STOP:39,REQUIREMENT:40,FUNCTIONAL_REQUIREMENT:41,INTERFACE_REQUIREMENT:42,PERFORMANCE_REQUIREMENT:43,PHYSICAL_REQUIREMENT:44,DESIGN_CONSTRAINT:45,LOW_RISK:46,MED_RISK:47,HIGH_RISK:48,VERIFY_ANALYSIS:49,VERIFY_DEMONSTRATION:50,VERIFY_INSPECTION:51,VERIFY_TEST:52,ELEMENT:53,elementName:54,elementBody:55,TYPE:56,type:57,DOCREF:58,ref:59,END_ARROW_L:60,relationship:61,LINE:62,END_ARROW_R:63,CONTAINS:64,COPIES:65,DERIVES:66,SATISFIES:67,VERIFIES:68,REFINES:69,TRACES:70,unqString:71,qString:72,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",12:":",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",28:"STRUCT_START",30:"ID",31:"COLONSEP",33:"TEXT",35:"RISK",37:"VERIFYMTHD",39:"STRUCT_STOP",40:"REQUIREMENT",41:"FUNCTIONAL_REQUIREMENT",42:"INTERFACE_REQUIREMENT",43:"PERFORMANCE_REQUIREMENT",44:"PHYSICAL_REQUIREMENT",45:"DESIGN_CONSTRAINT",46:"LOW_RISK",47:"MED_RISK",48:"HIGH_RISK",49:"VERIFY_ANALYSIS",50:"VERIFY_DEMONSTRATION",51:"VERIFY_INSPECTION",52:"VERIFY_TEST",53:"ELEMENT",56:"TYPE",58:"DOCREF",60:"END_ARROW_L",62:"LINE",63:"END_ARROW_R",64:"CONTAINS",65:"COPIES",66:"DERIVES",67:"SATISFIES",68:"VERIFIES",69:"REFINES",70:"TRACES",71:"unqString",72:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,3],[4,5],[4,2],[4,2],[4,1],[9,1],[10,1],[13,1],[11,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[23,5],[29,5],[29,5],[29,5],[29,5],[29,2],[29,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[36,1],[36,1],[36,1],[38,1],[38,1],[38,1],[38,1],[24,5],[55,5],[55,5],[55,2],[55,1],[25,5],[25,5],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[27,1],[27,1],[32,1],[32,1],[34,1],[34,1],[54,1],[54,1],[57,1],[57,1],[59,1],[59,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 6:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 7:case 8:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 9:i.parseDirective("%%{","open_directive");break;case 10:i.parseDirective(a[o],"type_directive");break;case 11:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 12:i.parseDirective("}%%","close_directive","pie");break;case 13:this.$=[];break;case 19:i.addRequirement(a[o-3],a[o-4]);break;case 20:i.setNewReqId(a[o-2]);break;case 21:i.setNewReqText(a[o-2]);break;case 22:i.setNewReqRisk(a[o-2]);break;case 23:i.setNewReqVerifyMethod(a[o-2]);break;case 26:this.$=i.RequirementType.REQUIREMENT;break;case 27:this.$=i.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 28:this.$=i.RequirementType.INTERFACE_REQUIREMENT;break;case 29:this.$=i.RequirementType.PERFORMANCE_REQUIREMENT;break;case 30:this.$=i.RequirementType.PHYSICAL_REQUIREMENT;break;case 31:this.$=i.RequirementType.DESIGN_CONSTRAINT;break;case 32:this.$=i.RiskLevel.LOW_RISK;break;case 33:this.$=i.RiskLevel.MED_RISK;break;case 34:this.$=i.RiskLevel.HIGH_RISK;break;case 35:this.$=i.VerifyType.VERIFY_ANALYSIS;break;case 36:this.$=i.VerifyType.VERIFY_DEMONSTRATION;break;case 37:this.$=i.VerifyType.VERIFY_INSPECTION;break;case 38:this.$=i.VerifyType.VERIFY_TEST;break;case 39:i.addElement(a[o-3]);break;case 40:i.setNewElementType(a[o-2]);break;case 41:i.setNewElementDocRef(a[o-2]);break;case 44:i.addRelationship(a[o-2],a[o],a[o-4]);break;case 45:i.addRelationship(a[o-2],a[o-4],a[o]);break;case 46:this.$=i.Relationships.CONTAINS;break;case 47:this.$=i.Relationships.COPIES;break;case 48:this.$=i.Relationships.DERIVES;break;case 49:this.$=i.Relationships.SATISFIES;break;case 50:this.$=i.Relationships.VERIFIES;break;case 51:this.$=i.Relationships.REFINES;break;case 52:this.$=i.Relationships.TRACES}},table:[{3:1,4:2,6:n,9:4,14:i,16:r,18:a,19:s},{1:[3]},{3:10,4:2,5:[1,9],6:n,9:4,14:i,16:r,18:a,19:s},{5:[1,11]},{10:12,20:[1,13]},{15:[1,14]},{17:[1,15]},e(o,[2,8]),{20:[2,9]},{3:16,4:2,6:n,9:4,14:i,16:r,18:a,19:s},{1:[2,2]},{4:21,5:c,7:17,8:l,9:4,14:i,16:r,18:a,19:s,23:18,24:19,25:20,26:23,32:25,40:h,41:u,42:d,43:p,44:f,45:g,53:y,71:m,72:b},{11:34,12:[1,35],22:_},e([12,22],[2,10]),e(o,[2,6]),e(o,[2,7]),{1:[2,1]},{8:[1,37]},{4:21,5:c,7:38,8:l,9:4,14:i,16:r,18:a,19:s,23:18,24:19,25:20,26:23,32:25,40:h,41:u,42:d,43:p,44:f,45:g,53:y,71:m,72:b},{4:21,5:c,7:39,8:l,9:4,14:i,16:r,18:a,19:s,23:18,24:19,25:20,26:23,32:25,40:h,41:u,42:d,43:p,44:f,45:g,53:y,71:m,72:b},{4:21,5:c,7:40,8:l,9:4,14:i,16:r,18:a,19:s,23:18,24:19,25:20,26:23,32:25,40:h,41:u,42:d,43:p,44:f,45:g,53:y,71:m,72:b},{4:21,5:c,7:41,8:l,9:4,14:i,16:r,18:a,19:s,23:18,24:19,25:20,26:23,32:25,40:h,41:u,42:d,43:p,44:f,45:g,53:y,71:m,72:b},{4:21,5:c,7:42,8:l,9:4,14:i,16:r,18:a,19:s,23:18,24:19,25:20,26:23,32:25,40:h,41:u,42:d,43:p,44:f,45:g,53:y,71:m,72:b},{27:43,71:[1,44],72:[1,45]},{54:46,71:[1,47],72:[1,48]},{60:[1,49],62:[1,50]},e(x,[2,26]),e(x,[2,27]),e(x,[2,28]),e(x,[2,29]),e(x,[2,30]),e(x,[2,31]),e(v,[2,55]),e(v,[2,56]),e(o,[2,4]),{13:51,21:[1,52]},e(o,[2,12]),{1:[2,3]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{8:[2,17]},{8:[2,18]},{28:[1,53]},{28:[2,53]},{28:[2,54]},{28:[1,54]},{28:[2,59]},{28:[2,60]},{61:55,64:k,65:w,66:T,67:C,68:E,69:S,70:A},{61:63,64:k,65:w,66:T,67:C,68:E,69:S,70:A},{11:64,22:_},{22:[2,11]},{5:[1,65]},{5:[1,66]},{62:[1,67]},e(D,[2,46]),e(D,[2,47]),e(D,[2,48]),e(D,[2,49]),e(D,[2,50]),e(D,[2,51]),e(D,[2,52]),{63:[1,68]},e(o,[2,5]),{5:L,29:69,30:N,33:O,35:B,37:M,39:I},{5:F,39:R,55:76,56:$,58:P},{32:81,71:m,72:b},{32:82,71:m,72:b},e(j,[2,19]),{31:[1,83]},{31:[1,84]},{31:[1,85]},{31:[1,86]},{5:L,29:87,30:N,33:O,35:B,37:M,39:I},e(j,[2,25]),e(j,[2,39]),{31:[1,88]},{31:[1,89]},{5:F,39:R,55:90,56:$,58:P},e(j,[2,43]),e(j,[2,44]),e(j,[2,45]),{32:91,71:m,72:b},{34:92,71:[1,93],72:[1,94]},{36:95,46:[1,96],47:[1,97],48:[1,98]},{38:99,49:[1,100],50:[1,101],51:[1,102],52:[1,103]},e(j,[2,24]),{57:104,71:[1,105],72:[1,106]},{59:107,71:[1,108],72:[1,109]},e(j,[2,42]),{5:[1,110]},{5:[1,111]},{5:[2,57]},{5:[2,58]},{5:[1,112]},{5:[2,32]},{5:[2,33]},{5:[2,34]},{5:[1,113]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[2,38]},{5:[1,114]},{5:[2,61]},{5:[2,62]},{5:[1,115]},{5:[2,63]},{5:[2,64]},{5:L,29:116,30:N,33:O,35:B,37:M,39:I},{5:L,29:117,30:N,33:O,35:B,37:M,39:I},{5:L,29:118,30:N,33:O,35:B,37:M,39:I},{5:L,29:119,30:N,33:O,35:B,37:M,39:I},{5:F,39:R,55:120,56:$,58:P},{5:F,39:R,55:121,56:$,58:P},e(j,[2,20]),e(j,[2,21]),e(j,[2,22]),e(j,[2,23]),e(j,[2,40]),e(j,[2,41])],defaultActions:{8:[2,9],10:[2,2],16:[2,1],37:[2,3],38:[2,14],39:[2,15],40:[2,16],41:[2,17],42:[2,18],44:[2,53],45:[2,54],47:[2,59],48:[2,60],52:[2,11],93:[2,57],94:[2,58],96:[2,32],97:[2,33],98:[2,34],100:[2,35],101:[2,36],102:[2,37],103:[2,38],105:[2,61],106:[2,62],108:[2,63],109:[2,64]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},z=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),19;case 1:return this.begin("type_directive"),20;case 2:return this.popState(),this.begin("arg_directive"),12;case 3:return this.popState(),this.popState(),22;case 4:return 21;case 5:return"title";case 6:return this.begin("acc_title"),14;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),16;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 53:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 5;case 14:case 15:case 16:break;case 17:return 8;case 18:return 6;case 19:return 28;case 20:return 39;case 21:return 31;case 22:return 30;case 23:return 33;case 24:return 35;case 25:return 37;case 26:return 40;case 27:return 41;case 28:return 42;case 29:return 43;case 30:return 44;case 31:return 45;case 32:return 46;case 33:return 47;case 34:return 48;case 35:return 49;case 36:return 50;case 37:return 51;case 38:return 52;case 39:return 53;case 40:return 64;case 41:return 65;case 42:return 66;case 43:return 67;case 44:return 68;case 45:return 69;case 46:return 70;case 47:return 56;case 48:return 58;case 49:return 60;case 50:return 63;case 51:return 62;case 52:this.begin("string");break;case 54:return"qString";case 55:return e.yytext=e.yytext.trim(),71}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[53,54],inclusive:!1},INITIAL:{rules:[0,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,55],inclusive:!0}}},t);function U(){this.yy={}}return Y.lexer=z,U.prototype=Y,Y.Parser=U,new U}();QE.parser=QE;const KE=QE,JE=t=>null!==t.match(/^\s*requirement(Diagram)?/);let tS=[],eS={},nS={},iS={},rS={};const aS={RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().req,addRequirement:(t,e)=>(void 0===nS[t]&&(nS[t]={name:t,type:e,id:eS.id,text:eS.text,risk:eS.risk,verifyMethod:eS.verifyMethod}),eS={},nS[t]),getRequirements:()=>nS,setNewReqId:t=>{void 0!==eS&&(eS.id=t)},setNewReqText:t=>{void 0!==eS&&(eS.text=t)},setNewReqRisk:t=>{void 0!==eS&&(eS.risk=t)},setNewReqVerifyMethod:t=>{void 0!==eS&&(eS.verifyMethod=t)},setAccTitle:Jv,getAccTitle:tk,setAccDescription:ek,getAccDescription:nk,addElement:t=>(void 0===rS[t]&&(rS[t]={name:t,type:iS.type,docRef:iS.docRef},Bb.info("Added new requirement: ",t)),iS={},rS[t]),getElements:()=>rS,setNewElementType:t=>{void 0!==iS&&(iS.type=t)},setNewElementDocRef:t=>{void 0!==iS&&(iS.docRef=t)},addRelationship:(t,e,n)=>{tS.push({type:t,src:e,dst:n})},getRelationships:()=>tS,clear:()=>{tS=[],eS={},nS={},iS={},rS={},Kv()}},sS={CONTAINS:"contains",ARROW:"arrow"},oS=sS,cS=(t,e)=>{let n=t.append("defs").append("marker").attr("id",sS.CONTAINS+"_line_ending").attr("refX",0).attr("refY",e.line_height/2).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("g");n.append("circle").attr("cx",e.line_height/2).attr("cy",e.line_height/2).attr("r",e.line_height/2).attr("fill","none"),n.append("line").attr("x1",0).attr("x2",e.line_height).attr("y1",e.line_height/2).attr("y2",e.line_height/2).attr("stroke-width",1),n.append("line").attr("y1",0).attr("y2",e.line_height).attr("x1",e.line_height/2).attr("x2",e.line_height/2).attr("stroke-width",1),t.append("defs").append("marker").attr("id",sS.ARROW+"_line_ending").attr("refX",e.line_height).attr("refY",.5*e.line_height).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("path").attr("d",`M0,0\n L${e.line_height},${e.line_height/2}\n M${e.line_height},${e.line_height/2}\n L0,${e.line_height}`).attr("stroke-width",1)};let lS={},hS=0;const uS=(t,e)=>t.insert("rect","#"+e).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",lS.rect_min_width+"px").attr("height",lS.rect_min_height+"px"),dS=(t,e,n)=>{let i=lS.rect_min_width/2,r=t.append("text").attr("class","req reqLabel reqTitle").attr("id",e).attr("x",i).attr("y",lS.rect_padding).attr("dominant-baseline","hanging"),a=0;n.forEach((t=>{0==a?r.append("tspan").attr("text-anchor","middle").attr("x",lS.rect_min_width/2).attr("dy",0).text(t):r.append("tspan").attr("text-anchor","middle").attr("x",lS.rect_min_width/2).attr("dy",.75*lS.line_height).text(t),a++}));let s=1.5*lS.rect_padding+a*lS.line_height*.75;return t.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",lS.rect_min_width).attr("y1",s).attr("y2",s),{titleNode:r,y:s}},pS=(t,e,n,i)=>{let r=t.append("text").attr("class","req reqLabel").attr("id",e).attr("x",lS.rect_padding).attr("y",i).attr("dominant-baseline","hanging"),a=0;let s=[];return n.forEach((t=>{let e=t.length;for(;e>30&&a<3;){let n=t.substring(0,30);e=(t=t.substring(30,t.length)).length,s[s.length]=n,a++}if(3==a){let t=s[s.length-1];s[s.length-1]=t.substring(0,t.length-4)+"..."}else s[s.length]=t;a=0})),s.forEach((t=>{r.append("tspan").attr("x",lS.rect_padding).attr("dy",lS.line_height).text(t)})),r},fS=function(t,e,n,i,r){const a=n.edge(gS(e.src),gS(e.dst)),s=Nc().x((function(t){return t.x})).y((function(t){return t.y})),o=t.insert("path","#"+i).attr("class","er relationshipLine").attr("d",s(a.points)).attr("fill","none");e.type==r.db.Relationships.CONTAINS?o.attr("marker-start","url("+Wb.getUrl(lS.arrowMarkerAbsolute)+"#"+e.type+"_line_ending)"):(o.attr("stroke-dasharray","10,7"),o.attr("marker-end","url("+Wb.getUrl(lS.arrowMarkerAbsolute)+"#"+oS.ARROW+"_line_ending)")),((t,e,n,i)=>{const r=e.node().getTotalLength(),a=e.node().getPointAtLength(.5*r),s="rel"+hS;hS++;const o=t.append("text").attr("class","req relationshipLabel").attr("id",s).attr("x",a.x).attr("y",a.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(i).node().getBBox();t.insert("rect","#"+s).attr("class","req reqLabelBox").attr("x",a.x-o.width/2).attr("y",a.y-o.height/2).attr("width",o.width).attr("height",o.height).attr("fill","white").attr("fill-opacity","85%")})(t,o,0,`<<${e.type}>>`)},gS=t=>t.replace(/\s/g,"").replace(/\./g,"_"),yS={draw:(t,e,n,i)=>{lS=fv().requirement,i.db.clear(),i.parser.parse(t);const r=lS.securityLevel;let a;"sandbox"===r&&(a=Xo("#i"+e));const s=Xo("sandbox"===r?a.nodes()[0].contentDocument.body:"body").select(`[id='${e}']`);cS(s,lS);const o=new Qf({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:lS.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));let c=i.db.getRequirements(),l=i.db.getElements(),h=i.db.getRelationships();((t,e,n)=>{Object.keys(t).forEach((i=>{let r=t[i];i=gS(i),Bb.info("Added new requirement: ",i);const a=n.append("g").attr("id",i),s=uS(a,"req-"+i);let o=dS(a,i+"_title",[`<<${r.type}>>`,`${r.name}`]);pS(a,i+"_body",[`Id: ${r.id}`,`Text: ${r.text}`,`Risk: ${r.risk}`,`Verification: ${r.verifyMethod}`],o.y);const c=s.node().getBBox();e.setNode(i,{width:c.width,height:c.height,shape:"rect",id:i})}))})(c,o,s),((t,e,n)=>{Object.keys(t).forEach((i=>{let r=t[i];const a=gS(i),s=n.append("g").attr("id",a),o="element-"+a,c=uS(s,o);let l=dS(s,o+"_title",["<<Element>>",`${i}`]);pS(s,o+"_body",[`Type: ${r.type||"Not Specified"}`,`Doc Ref: ${r.docRef||"None"}`],l.y);const h=c.node().getBBox();e.setNode(a,{width:h.width,height:h.height,shape:"rect",id:a})}))})(l,o,s),((t,e)=>{t.forEach((function(t){let n=gS(t.src),i=gS(t.dst);e.setEdge(n,i,{relationship:t})}))})(h,o),Lm(o),function(t,e){e.nodes().forEach((function(n){void 0!==n&&void 0!==e.node(n)&&(t.select("#"+n),t.select("#"+n).attr("transform","translate("+(e.node(n).x-e.node(n).width/2)+","+(e.node(n).y-e.node(n).height/2)+" )"))}))}(s,o),h.forEach((function(t){fS(s,t,o,e,i)}));const u=lS.rect_padding,d=s.node().getBBox(),p=d.width+2*u,f=d.height+2*u;vv(s,f,p,lS.useMaxWidth),s.attr("viewBox",`${d.x-u} ${d.y-u} ${p} ${f}`)}};var mS=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,2],i=[1,3],r=[1,5],a=[1,7],s=[2,5],o=[1,15],c=[1,17],l=[1,18],h=[1,19],u=[1,21],d=[1,22],p=[1,23],f=[1,29],g=[1,30],y=[1,31],m=[1,32],b=[1,33],_=[1,34],x=[1,35],v=[1,36],k=[1,37],w=[1,38],T=[1,39],C=[1,40],E=[1,43],S=[1,44],A=[1,45],D=[1,46],L=[1,47],N=[1,48],O=[1,51],B=[1,4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,49,50,51,52,53,58,59,60,61,69,79],M=[4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,49,53,58,59,60,61,69,79],I=[4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,49,52,53,58,59,60,61,69,79],F=[4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,49,51,53,58,59,60,61,69,79],R=[4,5,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,49,50,53,58,59,60,61,69,79],$=[67,68,69],P=[1,121],j=[1,4,5,7,16,20,22,25,26,32,33,34,36,38,39,40,41,42,43,45,47,49,50,51,52,53,58,59,60,61,69,79],Y={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,directive:6,SD:7,document:8,line:9,statement:10,openDirective:11,typeDirective:12,closeDirective:13,":":14,argDirective:15,participant:16,actor:17,AS:18,restOfLine:19,participant_actor:20,signal:21,autonumber:22,NUM:23,off:24,activate:25,deactivate:26,note_statement:27,links_statement:28,link_statement:29,properties_statement:30,details_statement:31,title:32,legacy_title:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,loop:39,end:40,rect:41,opt:42,alt:43,else_sections:44,par:45,par_sections:46,critical:47,option_sections:48,break:49,option:50,and:51,else:52,note:53,placement:54,text2:55,over:56,actor_pair:57,links:58,link:59,properties:60,details:61,spaceList:62,",":63,left_of:64,right_of:65,signaltype:66,"+":67,"-":68,ACTOR:69,SOLID_OPEN_ARROW:70,DOTTED_OPEN_ARROW:71,SOLID_ARROW:72,DOTTED_ARROW:73,SOLID_CROSS:74,DOTTED_CROSS:75,SOLID_POINT:76,DOTTED_POINT:77,TXT:78,open_directive:79,type_directive:80,arg_directive:81,close_directive:82,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",7:"SD",14:":",16:"participant",18:"AS",19:"restOfLine",20:"participant_actor",22:"autonumber",23:"NUM",24:"off",25:"activate",26:"deactivate",32:"title",33:"legacy_title",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",39:"loop",40:"end",41:"rect",42:"opt",43:"alt",45:"par",47:"critical",49:"break",50:"option",51:"and",52:"else",53:"note",56:"over",58:"links",59:"link",60:"properties",61:"details",63:",",64:"left_of",65:"right_of",67:"+",68:"-",69:"ACTOR",70:"SOLID_OPEN_ARROW",71:"DOTTED_OPEN_ARROW",72:"SOLID_ARROW",73:"DOTTED_ARROW",74:"SOLID_CROSS",75:"DOTTED_CROSS",76:"SOLID_POINT",77:"DOTTED_POINT",78:"TXT",79:"open_directive",80:"type_directive",81:"arg_directive",82:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[6,4],[6,6],[10,5],[10,3],[10,5],[10,3],[10,2],[10,4],[10,3],[10,3],[10,2],[10,3],[10,3],[10,2],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,2],[10,2],[10,1],[10,4],[10,4],[10,4],[10,4],[10,4],[10,4],[10,4],[10,1],[48,1],[48,4],[46,1],[46,4],[44,1],[44,4],[27,4],[27,4],[28,3],[29,3],[30,3],[31,3],[62,2],[62,1],[57,3],[57,1],[54,1],[54,1],[21,5],[21,5],[21,4],[17,1],[66,1],[66,1],[66,1],[66,1],[66,1],[66,1],[66,1],[66,1],[55,1],[11,1],[12,1],[15,1],[13,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 4:return i.apply(a[o]),a[o];case 5:case 9:this.$=[];break;case 6:a[o-1].push(a[o]),this.$=a[o-1];break;case 7:case 8:case 56:this.$=a[o];break;case 12:a[o-3].type="addParticipant",a[o-3].description=i.parseMessage(a[o-1]),this.$=a[o-3];break;case 13:a[o-1].type="addParticipant",this.$=a[o-1];break;case 14:a[o-3].type="addActor",a[o-3].description=i.parseMessage(a[o-1]),this.$=a[o-3];break;case 15:a[o-1].type="addActor",this.$=a[o-1];break;case 17:this.$={type:"sequenceIndex",sequenceIndex:Number(a[o-2]),sequenceIndexStep:Number(a[o-1]),sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(a[o-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:i.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"activeStart",signalType:i.LINETYPE.ACTIVE_START,actor:a[o-1]};break;case 22:this.$={type:"activeEnd",signalType:i.LINETYPE.ACTIVE_END,actor:a[o-1]};break;case 28:i.setDiagramTitle(a[o].substring(6)),this.$=a[o].substring(6);break;case 29:i.setDiagramTitle(a[o].substring(7)),this.$=a[o].substring(7);break;case 30:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 31:case 32:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 33:a[o-1].unshift({type:"loopStart",loopText:i.parseMessage(a[o-2]),signalType:i.LINETYPE.LOOP_START}),a[o-1].push({type:"loopEnd",loopText:a[o-2],signalType:i.LINETYPE.LOOP_END}),this.$=a[o-1];break;case 34:a[o-1].unshift({type:"rectStart",color:i.parseMessage(a[o-2]),signalType:i.LINETYPE.RECT_START}),a[o-1].push({type:"rectEnd",color:i.parseMessage(a[o-2]),signalType:i.LINETYPE.RECT_END}),this.$=a[o-1];break;case 35:a[o-1].unshift({type:"optStart",optText:i.parseMessage(a[o-2]),signalType:i.LINETYPE.OPT_START}),a[o-1].push({type:"optEnd",optText:i.parseMessage(a[o-2]),signalType:i.LINETYPE.OPT_END}),this.$=a[o-1];break;case 36:a[o-1].unshift({type:"altStart",altText:i.parseMessage(a[o-2]),signalType:i.LINETYPE.ALT_START}),a[o-1].push({type:"altEnd",signalType:i.LINETYPE.ALT_END}),this.$=a[o-1];break;case 37:a[o-1].unshift({type:"parStart",parText:i.parseMessage(a[o-2]),signalType:i.LINETYPE.PAR_START}),a[o-1].push({type:"parEnd",signalType:i.LINETYPE.PAR_END}),this.$=a[o-1];break;case 38:a[o-1].unshift({type:"criticalStart",criticalText:i.parseMessage(a[o-2]),signalType:i.LINETYPE.CRITICAL_START}),a[o-1].push({type:"criticalEnd",signalType:i.LINETYPE.CRITICAL_END}),this.$=a[o-1];break;case 39:a[o-1].unshift({type:"breakStart",breakText:i.parseMessage(a[o-2]),signalType:i.LINETYPE.BREAK_START}),a[o-1].push({type:"breakEnd",optText:i.parseMessage(a[o-2]),signalType:i.LINETYPE.BREAK_END}),this.$=a[o-1];break;case 42:this.$=a[o-3].concat([{type:"option",optionText:i.parseMessage(a[o-1]),signalType:i.LINETYPE.CRITICAL_OPTION},a[o]]);break;case 44:this.$=a[o-3].concat([{type:"and",parText:i.parseMessage(a[o-1]),signalType:i.LINETYPE.PAR_AND},a[o]]);break;case 46:this.$=a[o-3].concat([{type:"else",altText:i.parseMessage(a[o-1]),signalType:i.LINETYPE.ALT_ELSE},a[o]]);break;case 47:this.$=[a[o-1],{type:"addNote",placement:a[o-2],actor:a[o-1].actor,text:a[o]}];break;case 48:a[o-2]=[].concat(a[o-1],a[o-1]).slice(0,2),a[o-2][0]=a[o-2][0].actor,a[o-2][1]=a[o-2][1].actor,this.$=[a[o-1],{type:"addNote",placement:i.PLACEMENT.OVER,actor:a[o-2].slice(0,2),text:a[o]}];break;case 49:this.$=[a[o-1],{type:"addLinks",actor:a[o-1].actor,text:a[o]}];break;case 50:this.$=[a[o-1],{type:"addALink",actor:a[o-1].actor,text:a[o]}];break;case 51:this.$=[a[o-1],{type:"addProperties",actor:a[o-1].actor,text:a[o]}];break;case 52:this.$=[a[o-1],{type:"addDetails",actor:a[o-1].actor,text:a[o]}];break;case 55:this.$=[a[o-2],a[o]];break;case 57:this.$=i.PLACEMENT.LEFTOF;break;case 58:this.$=i.PLACEMENT.RIGHTOF;break;case 59:this.$=[a[o-4],a[o-1],{type:"addMessage",from:a[o-4].actor,to:a[o-1].actor,signalType:a[o-3],msg:a[o]},{type:"activeStart",signalType:i.LINETYPE.ACTIVE_START,actor:a[o-1]}];break;case 60:this.$=[a[o-4],a[o-1],{type:"addMessage",from:a[o-4].actor,to:a[o-1].actor,signalType:a[o-3],msg:a[o]},{type:"activeEnd",signalType:i.LINETYPE.ACTIVE_END,actor:a[o-4]}];break;case 61:this.$=[a[o-3],a[o-1],{type:"addMessage",from:a[o-3].actor,to:a[o-1].actor,signalType:a[o-2],msg:a[o]}];break;case 62:this.$={type:"addParticipant",actor:a[o]};break;case 63:this.$=i.LINETYPE.SOLID_OPEN;break;case 64:this.$=i.LINETYPE.DOTTED_OPEN;break;case 65:this.$=i.LINETYPE.SOLID;break;case 66:this.$=i.LINETYPE.DOTTED;break;case 67:this.$=i.LINETYPE.SOLID_CROSS;break;case 68:this.$=i.LINETYPE.DOTTED_CROSS;break;case 69:this.$=i.LINETYPE.SOLID_POINT;break;case 70:this.$=i.LINETYPE.DOTTED_POINT;break;case 71:this.$=i.parseMessage(a[o].trim().substring(1));break;case 72:i.parseDirective("%%{","open_directive");break;case 73:i.parseDirective(a[o],"type_directive");break;case 74:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 75:i.parseDirective("}%%","close_directive","sequence")}},table:[{3:1,4:n,5:i,6:4,7:r,11:6,79:a},{1:[3]},{3:8,4:n,5:i,6:4,7:r,11:6,79:a},{3:9,4:n,5:i,6:4,7:r,11:6,79:a},{3:10,4:n,5:i,6:4,7:r,11:6,79:a},e([1,4,5,16,20,22,25,26,32,33,34,36,38,39,41,42,43,45,47,49,53,58,59,60,61,69,79],s,{8:11}),{12:12,80:[1,13]},{80:[2,72]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:o,5:c,6:41,9:14,10:16,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,41:x,42:v,43:k,45:w,47:T,49:C,53:E,58:S,59:A,60:D,61:L,69:N,79:a},{13:49,14:[1,50],82:O},e([14,82],[2,73]),e(B,[2,6]),{6:41,10:52,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,41:x,42:v,43:k,45:w,47:T,49:C,53:E,58:S,59:A,60:D,61:L,69:N,79:a},e(B,[2,8]),e(B,[2,9]),{17:53,69:N},{17:54,69:N},{5:[1,55]},{5:[1,58],23:[1,56],24:[1,57]},{17:59,69:N},{17:60,69:N},{5:[1,61]},{5:[1,62]},{5:[1,63]},{5:[1,64]},{5:[1,65]},e(B,[2,28]),e(B,[2,29]),{35:[1,66]},{37:[1,67]},e(B,[2,32]),{19:[1,68]},{19:[1,69]},{19:[1,70]},{19:[1,71]},{19:[1,72]},{19:[1,73]},{19:[1,74]},e(B,[2,40]),{66:75,70:[1,76],71:[1,77],72:[1,78],73:[1,79],74:[1,80],75:[1,81],76:[1,82],77:[1,83]},{54:84,56:[1,85],64:[1,86],65:[1,87]},{17:88,69:N},{17:89,69:N},{17:90,69:N},{17:91,69:N},e([5,18,63,70,71,72,73,74,75,76,77,78],[2,62]),{5:[1,92]},{15:93,81:[1,94]},{5:[2,75]},e(B,[2,7]),{5:[1,96],18:[1,95]},{5:[1,98],18:[1,97]},e(B,[2,16]),{5:[1,100],23:[1,99]},{5:[1,101]},e(B,[2,20]),{5:[1,102]},{5:[1,103]},e(B,[2,23]),e(B,[2,24]),e(B,[2,25]),e(B,[2,26]),e(B,[2,27]),e(B,[2,30]),e(B,[2,31]),e(M,s,{8:104}),e(M,s,{8:105}),e(M,s,{8:106}),e(I,s,{44:107,8:108}),e(F,s,{46:109,8:110}),e(R,s,{48:111,8:112}),e(M,s,{8:113}),{17:116,67:[1,114],68:[1,115],69:N},e($,[2,63]),e($,[2,64]),e($,[2,65]),e($,[2,66]),e($,[2,67]),e($,[2,68]),e($,[2,69]),e($,[2,70]),{17:117,69:N},{17:119,57:118,69:N},{69:[2,57]},{69:[2,58]},{55:120,78:P},{55:122,78:P},{55:123,78:P},{55:124,78:P},e(j,[2,10]),{13:125,82:O},{82:[2,74]},{19:[1,126]},e(B,[2,13]),{19:[1,127]},e(B,[2,15]),{5:[1,128]},e(B,[2,18]),e(B,[2,19]),e(B,[2,21]),e(B,[2,22]),{4:o,5:c,6:41,9:14,10:16,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,40:[1,129],41:x,42:v,43:k,45:w,47:T,49:C,53:E,58:S,59:A,60:D,61:L,69:N,79:a},{4:o,5:c,6:41,9:14,10:16,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,40:[1,130],41:x,42:v,43:k,45:w,47:T,49:C,53:E,58:S,59:A,60:D,61:L,69:N,79:a},{4:o,5:c,6:41,9:14,10:16,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,40:[1,131],41:x,42:v,43:k,45:w,47:T,49:C,53:E,58:S,59:A,60:D,61:L,69:N,79:a},{40:[1,132]},{4:o,5:c,6:41,9:14,10:16,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,40:[2,45],41:x,42:v,43:k,45:w,47:T,49:C,52:[1,133],53:E,58:S,59:A,60:D,61:L,69:N,79:a},{40:[1,134]},{4:o,5:c,6:41,9:14,10:16,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,40:[2,43],41:x,42:v,43:k,45:w,47:T,49:C,51:[1,135],53:E,58:S,59:A,60:D,61:L,69:N,79:a},{40:[1,136]},{4:o,5:c,6:41,9:14,10:16,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,40:[2,41],41:x,42:v,43:k,45:w,47:T,49:C,50:[1,137],53:E,58:S,59:A,60:D,61:L,69:N,79:a},{4:o,5:c,6:41,9:14,10:16,11:6,16:l,17:42,20:h,21:20,22:u,25:d,26:p,27:24,28:25,29:26,30:27,31:28,32:f,33:g,34:y,36:m,38:b,39:_,40:[1,138],41:x,42:v,43:k,45:w,47:T,49:C,53:E,58:S,59:A,60:D,61:L,69:N,79:a},{17:139,69:N},{17:140,69:N},{55:141,78:P},{55:142,78:P},{55:143,78:P},{63:[1,144],78:[2,56]},{5:[2,49]},{5:[2,71]},{5:[2,50]},{5:[2,51]},{5:[2,52]},{5:[1,145]},{5:[1,146]},{5:[1,147]},e(B,[2,17]),e(B,[2,33]),e(B,[2,34]),e(B,[2,35]),e(B,[2,36]),{19:[1,148]},e(B,[2,37]),{19:[1,149]},e(B,[2,38]),{19:[1,150]},e(B,[2,39]),{55:151,78:P},{55:152,78:P},{5:[2,61]},{5:[2,47]},{5:[2,48]},{17:153,69:N},e(j,[2,11]),e(B,[2,12]),e(B,[2,14]),e(I,s,{8:108,44:154}),e(F,s,{8:110,46:155}),e(R,s,{8:112,48:156}),{5:[2,59]},{5:[2,60]},{78:[2,55]},{40:[2,46]},{40:[2,44]},{40:[2,42]}],defaultActions:{7:[2,72],8:[2,1],9:[2,2],10:[2,3],51:[2,75],86:[2,57],87:[2,58],94:[2,74],120:[2,49],121:[2,71],122:[2,50],123:[2,51],124:[2,52],141:[2,61],142:[2,47],143:[2,48],151:[2,59],152:[2,60],153:[2,55],154:[2,46],155:[2,44],156:[2,42]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},z=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),79;case 1:return this.begin("type_directive"),80;case 2:return this.popState(),this.begin("arg_directive"),14;case 3:return this.popState(),this.popState(),82;case 4:return 81;case 5:case 52:case 65:return 5;case 6:case 7:case 8:case 9:case 10:break;case 11:return 23;case 12:return this.begin("ID"),16;case 13:return this.begin("ID"),20;case 14:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),69;case 15:return this.popState(),this.popState(),this.begin("LINE"),18;case 16:return this.popState(),this.popState(),5;case 17:return this.begin("LINE"),39;case 18:return this.begin("LINE"),41;case 19:return this.begin("LINE"),42;case 20:return this.begin("LINE"),43;case 21:return this.begin("LINE"),52;case 22:return this.begin("LINE"),45;case 23:return this.begin("LINE"),51;case 24:return this.begin("LINE"),47;case 25:return this.begin("LINE"),50;case 26:return this.begin("LINE"),49;case 27:return this.popState(),19;case 28:return 40;case 29:return 64;case 30:return 65;case 31:return 58;case 32:return 59;case 33:return 60;case 34:return 61;case 35:return 56;case 36:return 53;case 37:return this.begin("ID"),25;case 38:return this.begin("ID"),26;case 39:return 32;case 40:return 33;case 41:return this.begin("acc_title"),34;case 42:return this.popState(),"acc_title_value";case 43:return this.begin("acc_descr"),36;case 44:return this.popState(),"acc_descr_value";case 45:this.begin("acc_descr_multiline");break;case 46:this.popState();break;case 47:return"acc_descr_multiline_value";case 48:return 7;case 49:return 22;case 50:return 24;case 51:return 63;case 53:return e.yytext=e.yytext.trim(),69;case 54:return 72;case 55:return 73;case 56:return 70;case 57:return 71;case 58:return 74;case 59:return 75;case 60:return 76;case 61:return 77;case 62:return 78;case 63:return 67;case 64:return 68;case 66:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[46,47],inclusive:!1},acc_descr:{rules:[44],inclusive:!1},acc_title:{rules:[42],inclusive:!1},open_directive:{rules:[1,8],inclusive:!1},type_directive:{rules:[2,3,8],inclusive:!1},arg_directive:{rules:[3,4,8],inclusive:!1},ID:{rules:[7,8,14],inclusive:!1},ALIAS:{rules:[7,8,15,16],inclusive:!1},LINE:{rules:[7,8,27],inclusive:!1},INITIAL:{rules:[0,5,6,8,9,10,11,12,13,17,18,19,20,21,22,23,24,25,26,28,29,30,31,32,33,34,35,36,37,38,39,40,41,43,45,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66],inclusive:!0}}},t);function U(){this.yy={}}return Y.lexer=z,U.prototype=Y,Y.Parser=U,new U}();mS.parser=mS;const bS=mS,_S=t=>null!==t.match(/^\s*sequenceDiagram/);let xS,vS,kS={},wS=[],TS=!1;const CS=function(t,e,n,i){const r=kS[t];r&&e===r.name&&null==n||(null!=n&&null!=n.text||(n={text:e,wrap:null,type:i}),null!=i&&null!=n.text||(n={text:e,wrap:null,type:i}),kS[t]={name:e,description:n.text,wrap:void 0===n.wrap&&AS()||!!n.wrap,prevActor:xS,links:{},properties:{},actorCnt:null,rectData:null,type:i||"participant"},xS&&kS[xS]&&(kS[xS].nextActor=t),xS=t)},ES=function(t,e,n={text:void 0,wrap:void 0},i){if(i===DS.ACTIVE_END){const e=(t=>{let e,n=0;for(e=0;e<wS.length;e++)wS[e].type===DS.ACTIVE_START&&wS[e].from.actor===t&&n++,wS[e].type===DS.ACTIVE_END&&wS[e].from.actor===t&&n--;return n})(t.actor);if(e<1){let e=new Error("Trying to inactivate an inactive participant ("+t.actor+")");throw e.hash={text:"->>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}}return wS.push({from:t,to:e,message:n.text,wrap:void 0===n.wrap&&AS()||!!n.wrap,type:i}),!0},SS=function(t){return kS[t]},AS=()=>void 0!==vS?vS:fv().sequence.wrap,DS={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31},LS=function(t,e,n){n.text,void 0===n.wrap&&AS()||n.wrap;const i=[].concat(t,t);wS.push({from:i[0],to:i[1],message:n.text,wrap:void 0===n.wrap&&AS()||!!n.wrap,type:DS.NOTE,placement:e})},NS=function(t,e){const n=SS(t);try{let t=$b(e.text,fv());t=t.replace(/&/g,"&"),t=t.replace(/=/g,"=");OS(n,JSON.parse(t))}catch(i){Bb.error("error while parsing actor link text",i)}};function OS(t,e){if(null==t.links)t.links=e;else for(let n in e)t.links[n]=e[n]}const BS=function(t,e){const n=SS(t);try{let t=$b(e.text,fv());MS(n,JSON.parse(t))}catch(i){Bb.error("error while parsing actor properties text",i)}};function MS(t,e){if(null==t.properties)t.properties=e;else for(let n in e)t.properties[n]=e[n]}const IS=function(t,e){const n=SS(t),i=document.getElementById(e.text);try{const t=i.innerHTML,e=JSON.parse(t);e.properties&&MS(n,e.properties),e.links&&OS(n,e.links)}catch(r){Bb.error("error while parsing actor details text",r)}},FS=function(t){if(Array.isArray(t))t.forEach((function(t){FS(t)}));else switch(t.type){case"sequenceIndex":wS.push({from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":CS(t.actor,t.actor,t.description,"participant");break;case"addActor":CS(t.actor,t.actor,t.description,"actor");break;case"activeStart":case"activeEnd":ES(t.actor,void 0,void 0,t.signalType);break;case"addNote":LS(t.actor,t.placement,t.text);break;case"addLinks":NS(t.actor,t.text);break;case"addALink":!function(t,e){const n=SS(t);try{const t={};let s=$b(e.text,fv());var i=s.indexOf("@");s=s.replace(/&/g,"&"),s=s.replace(/=/g,"=");var r=s.slice(0,i-1).trim(),a=s.slice(i+1).trim();t[r]=a,OS(n,t)}catch(s){Bb.error("error while parsing actor link text",s)}}(t.actor,t.text);break;case"addProperties":BS(t.actor,t.text);break;case"addDetails":IS(t.actor,t.text);break;case"addMessage":ES(t.from,t.to,t.msg,t.signalType);break;case"loopStart":ES(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":case"rectEnd":case"optEnd":case"altEnd":case"parEnd":case"criticalEnd":case"breakEnd":ES(void 0,void 0,void 0,t.signalType);break;case"rectStart":ES(void 0,void 0,t.color,t.signalType);break;case"optStart":ES(void 0,void 0,t.optText,t.signalType);break;case"altStart":case"else":ES(void 0,void 0,t.altText,t.signalType);break;case"setAccTitle":Jv(t.text);break;case"parStart":case"and":ES(void 0,void 0,t.parText,t.signalType);break;case"criticalStart":ES(void 0,void 0,t.criticalText,t.signalType);break;case"option":ES(void 0,void 0,t.optionText,t.signalType);break;case"breakStart":ES(void 0,void 0,t.breakText,t.signalType)}},RS={addActor:CS,addMessage:function(t,e,n,i){wS.push({from:t,to:e,message:n.text,wrap:void 0===n.wrap&&AS()||!!n.wrap,answer:i})},addSignal:ES,addLinks:NS,addDetails:IS,addProperties:BS,autoWrap:AS,setWrap:function(t){vS=t},enableSequenceNumbers:function(){TS=!0},disableSequenceNumbers:function(){TS=!1},showSequenceNumbers:()=>TS,getMessages:function(){return wS},getActors:function(){return kS},getActor:SS,getActorKeys:function(){return Object.keys(kS)},getActorProperty:function(t,e){if(void 0!==t&&void 0!==t.properties)return t.properties[e]},getAccTitle:tk,getDiagramTitle:rk,setDiagramTitle:ik,parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().sequence,clear:function(){kS={},wS=[],TS=!1,Kv()},parseMessage:function(t){const e=t.trim(),n={text:e.replace(/^:?(?:no)?wrap:/,"").trim(),wrap:null!==e.match(/^:?wrap:/)||null===e.match(/^:?nowrap:/)&&void 0};return Bb.debug("parseMessage:",n),n},LINETYPE:DS,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:LS,setAccTitle:Jv,apply:FS,setAccDescription:ek,getAccDescription:nk};let $S=[];const PS=()=>{$S.forEach((t=>{t()})),$S=[]},jS=function(t,e){const n=t.append("rect");return n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),n.attr("rx",e.rx),n.attr("ry",e.ry),void 0!==e.class&&n.attr("class",e.class),n},YS=(t,e)=>{var n;n=()=>{const n=document.querySelectorAll(t);0!==n.length&&(n[0].addEventListener("mouseover",(function(){WS("actor"+e+"_popup")})),n[0].addEventListener("mouseout",(function(){HS("actor"+e+"_popup")})))},$S.push(n)},zS=function(t,e,n,i){const r=t.append("image");r.attr("x",e),r.attr("y",n);var a=(0,Tt.N)(i);r.attr("xlink:href",a)},US=function(t,e,n,i){const r=t.append("use");r.attr("x",e),r.attr("y",n);var a=(0,Tt.N)(i);r.attr("xlink:href","#"+a)},WS=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="block")},HS=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="none")},qS=function(t,e){let n=0,i=0;const r=e.text.split(Wb.lineBreakRegex);let a=[],s=0,o=()=>e.y;if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":o=()=>Math.round(e.y+e.textMargin);break;case"middle":case"center":o=()=>Math.round(e.y+(n+i+e.textMargin)/2);break;case"bottom":case"end":o=()=>Math.round(e.y+(n+i+2*e.textMargin)-e.textMargin)}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[c,l]of r.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==e.fontSize&&(s=c*e.fontSize);const r=t.append("text");if(r.attr("x",e.x),r.attr("y",o()),void 0!==e.anchor&&r.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&r.style("font-family",e.fontFamily),void 0!==e.fontSize&&r.style("font-size",e.fontSize),void 0!==e.fontWeight&&r.style("font-weight",e.fontWeight),void 0!==e.fill&&r.attr("fill",e.fill),void 0!==e.class&&r.attr("class",e.class),void 0!==e.dy?r.attr("dy",e.dy):0!==s&&r.attr("dy",s),e.tspan){const t=r.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(l)}else r.text(l);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(i+=(r._groups||r)[0][0].getBBox().height,n=i),a.push(r)}return a},VS=function(t,e){const n=t.append("polygon");var i,r,a,s,o;return n.attr("points",(i=e.x,r=e.y,a=e.width,s=e.height,i+","+r+" "+(i+a)+","+r+" "+(i+a)+","+(r+s-(o=7))+" "+(i+a-1.2*o)+","+(r+s)+" "+i+","+(r+s))),n.attr("class","labelBox"),e.y=e.y+e.height/2,qS(t,e),n};let GS=-1;const XS=(t,e)=>{t.selectAll&&t.selectAll(".actor-line").attr("class","200").attr("y2",e-55)},ZS=function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},QS=function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},KS=function(){function t(t,e,n,r,a,s,o){i(e.append("text").attr("x",n+a/2).attr("y",r+s/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,n,r,a,s,o,c){const{actorFontSize:l,actorFontFamily:h,actorFontWeight:u}=c;let d=l&&l.replace?l.replace("px",""):l;const p=t.split(Wb.lineBreakRegex);for(let f=0;f<p.length;f++){const t=f*d-d*(p.length-1)/2,c=e.append("text").attr("x",n+a/2).attr("y",r).style("text-anchor","middle").style("font-size",l).style("font-weight",u).style("font-family",h);c.append("tspan").attr("x",n+a/2).attr("dy",t).text(p[f]),c.attr("y",r+s/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(c,o)}}function n(t,n,r,a,s,o,c,l){const h=n.append("switch"),u=h.append("foreignObject").attr("x",r).attr("y",a).attr("width",s).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");u.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,r,a,s,o,c,l),i(u,c)}function i(t,e){for(const n in e)e.hasOwnProperty(n)&&t.attr(n,e[n])}return function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),JS=function(){function t(t,e,n,r,a,s,o){i(e.append("text").attr("x",n).attr("y",r).style("text-anchor","start").text(t),o)}function e(t,e,n,r,a,s,o,c){const{actorFontSize:l,actorFontFamily:h,actorFontWeight:u}=c,d=t.split(Wb.lineBreakRegex);for(let p=0;p<d.length;p++){const t=p*l-l*(d.length-1)/2,a=e.append("text").attr("x",n).attr("y",r).style("text-anchor","start").style("font-size",l).style("font-weight",u).style("font-family",h);a.append("tspan").attr("x",n).attr("dy",t).text(d[p]),a.attr("y",r+s/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(a,o)}}function n(t,n,r,a,s,o,c,l){const h=n.append("switch"),u=h.append("foreignObject").attr("x",r).attr("y",a).attr("width",s).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");u.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,r,a,0,o,c,l),i(u,c)}function i(t,e){for(const n in e)e.hasOwnProperty(n)&&t.attr(n,e[n])}return function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),tA={drawRect:jS,drawText:qS,drawLabel:VS,drawActor:function(t,e,n){switch(e.type){case"actor":return function(t,e,n){const i=e.x+e.width/2;0===e.y&&(GS++,t.append("line").attr("id","actor"+GS).attr("x1",i).attr("y1",80).attr("x2",i).attr("y2",2e3).attr("class","actor-line").attr("stroke-width","0.5px").attr("stroke","#999"));const r=t.append("g");r.attr("class","actor-man");const a=QS();a.x=e.x,a.y=e.y,a.fill="#eaeaea",a.width=e.width,a.height=e.height,a.class="actor",a.rx=3,a.ry=3,r.append("line").attr("id","actor-man-torso"+GS).attr("x1",i).attr("y1",e.y+25).attr("x2",i).attr("y2",e.y+45),r.append("line").attr("id","actor-man-arms"+GS).attr("x1",i-18).attr("y1",e.y+33).attr("x2",i+18).attr("y2",e.y+33),r.append("line").attr("x1",i-18).attr("y1",e.y+60).attr("x2",i).attr("y2",e.y+45),r.append("line").attr("x1",i).attr("y1",e.y+45).attr("x2",i+16).attr("y2",e.y+60);const s=r.append("circle");s.attr("cx",e.x+e.width/2),s.attr("cy",e.y+10),s.attr("r",15),s.attr("width",e.width),s.attr("height",e.height);const o=r.node().getBBox();return e.height=o.height,KS(n)(e.description,r,a.x,a.y+35,a.width,a.height,{class:"actor"},n),e.height}(t,e,n);case"participant":return function(t,e,n){const i=e.x+e.width/2,r=t.append("g");var a=r;0===e.y&&(GS++,a.append("line").attr("id","actor"+GS).attr("x1",i).attr("y1",5).attr("x2",i).attr("y2",2e3).attr("class","actor-line").attr("stroke-width","0.5px").attr("stroke","#999"),a=r.append("g"),e.actorCnt=GS,null!=e.links&&(a.attr("id","root-"+GS),YS("#root-"+GS,GS)));const s=QS();var o="actor";null!=e.properties&&e.properties.class?o=e.properties.class:s.fill="#eaeaea",s.x=e.x,s.y=e.y,s.width=e.width,s.height=e.height,s.class=o,s.rx=3,s.ry=3;const c=jS(a,s);if(e.rectData=s,null!=e.properties&&e.properties.icon){const t=e.properties.icon.trim();"@"===t.charAt(0)?US(a,s.x+s.width-20,s.y+10,t.substr(1)):zS(a,s.x+s.width-20,s.y+10,t)}KS(n)(e.description,a,s.x,s.y,s.width,s.height,{class:"actor"},n);let l=e.height;if(c.node){const t=c.node().getBBox();e.height=t.height,l=t.height}return l}(t,e,n)}},drawPopup:function(t,e,n,i,r){if(void 0===e.links||null===e.links||0===Object.keys(e.links).length)return{height:0,width:0};const a=e.links,s=e.actorCnt,o=e.rectData;var c="none";r&&(c="block !important");const l=t.append("g");l.attr("id","actor"+s+"_popup"),l.attr("class","actorPopupMenu"),l.attr("display",c),YS("#actor"+s+"_popup",s);var h="";void 0!==o.class&&(h=" "+o.class);let u=o.width>n?o.width:n;const d=l.append("rect");if(d.attr("class","actorPopupMenuPanel"+h),d.attr("x",o.x),d.attr("y",o.height),d.attr("fill",o.fill),d.attr("stroke",o.stroke),d.attr("width",u),d.attr("height",o.height),d.attr("rx",o.rx),d.attr("ry",o.ry),null!=a){var p=20;for(let t in a){var f=l.append("a"),g=(0,Tt.N)(a[t]);f.attr("xlink:href",g),f.attr("target","_blank"),JS(i)(t,f,o.x+10,o.height+p,u,20,{class:"actor"},i),p+=30}}return d.attr("height",p),{height:o.height+p,width:u}},drawImage:zS,drawEmbeddedImage:US,anchorElement:function(t){return t.append("g")},drawActivation:function(t,e,n,i,r){const a=QS(),s=e.anchored;a.x=e.startx,a.y=e.starty,a.class="activation"+r%3,a.width=e.stopx-e.startx,a.height=n-e.starty,jS(s,a)},drawLoop:function(t,e,n,i){const{boxMargin:r,boxTextMargin:a,labelBoxHeight:s,labelBoxWidth:o,messageFontFamily:c,messageFontSize:l,messageFontWeight:h}=i,u=t.append("g"),d=function(t,e,n,i){return u.append("line").attr("x1",t).attr("y1",e).attr("x2",n).attr("y2",i).attr("class","loopLine")};d(e.startx,e.starty,e.stopx,e.starty),d(e.stopx,e.starty,e.stopx,e.stopy),d(e.startx,e.stopy,e.stopx,e.stopy),d(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach((function(t){d(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")}));let p=ZS();p.text=n,p.x=e.startx,p.y=e.starty,p.fontFamily=c,p.fontSize=l,p.fontWeight=h,p.anchor="middle",p.valign="middle",p.tspan=!1,p.width=o||50,p.height=s||20,p.textMargin=a,p.class="labelText",VS(u,p),p=ZS(),p.text=e.title,p.x=e.startx+o/2+(e.stopx-e.startx)/2,p.y=e.starty+r+a,p.anchor="middle",p.valign="middle",p.textMargin=a,p.class="loopText",p.fontFamily=c,p.fontSize=l,p.fontWeight=h,p.wrap=!0;let f=qS(u,p);return void 0!==e.sectionTitles&&e.sectionTitles.forEach((function(t,n){if(t.message){p.text=t.message,p.x=e.startx+(e.stopx-e.startx)/2,p.y=e.sections[n].y+r+a,p.class="loopText",p.anchor="middle",p.valign="middle",p.tspan=!1,p.fontFamily=c,p.fontSize=l,p.fontWeight=h,p.wrap=e.wrap,f=qS(u,p);let i=Math.round(f.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));e.sections[n].height+=i-(r+a)}})),e.height=Math.round(e.stopy-e.starty),u},drawBackgroundRect:function(t,e){jS(t,{x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,class:"rect"}).lower()},insertArrowHead:function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},insertArrowFilledHead:function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},insertSequenceNumber:function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},insertArrowCrossHead:function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},insertDatabaseIcon:function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},insertComputerIcon:function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},insertClockIcon:function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},getTextObj:ZS,getNoteRect:QS,popupMenu:function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = 'block'; }"},popdownMenu:function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = 'none'; }"},fixLifeLineHeights:XS,sanitizeUrl:Tt.N};let eA={};const nA={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((t=>t.height||0)))+(0===this.loops.length?0:this.loops.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.messages.length?0:this.messages.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.notes.length?0:this.notes.map((t=>t.height||0)).reduce(((t,e)=>t+e)))},clear:function(){this.actors=[],this.loops=[],this.messages=[],this.notes=[]},addActor:function(t){this.actors.push(t)},addLoop:function(t){this.loops.push(t)},addMessage:function(t){this.messages.push(t)},addNote:function(t){this.notes.push(t)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],loops:[],messages:[],notes:[]},init:function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,cA(fv())},updateVal:function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},updateBounds:function(t,e,n,i){const r=this;let a=0;function s(s){return function(o){a++;const c=r.sequenceItems.length-a+1;r.updateVal(o,"starty",e-c*eA.boxMargin,Math.min),r.updateVal(o,"stopy",i+c*eA.boxMargin,Math.max),r.updateVal(nA.data,"startx",t-c*eA.boxMargin,Math.min),r.updateVal(nA.data,"stopx",n+c*eA.boxMargin,Math.max),"activation"!==s&&(r.updateVal(o,"startx",t-c*eA.boxMargin,Math.min),r.updateVal(o,"stopx",n+c*eA.boxMargin,Math.max),r.updateVal(nA.data,"starty",e-c*eA.boxMargin,Math.min),r.updateVal(nA.data,"stopy",i+c*eA.boxMargin,Math.max))}}this.sequenceItems.forEach(s()),this.activations.forEach(s("activation"))},insert:function(t,e,n,i){const r=Math.min(t,n),a=Math.max(t,n),s=Math.min(e,i),o=Math.max(e,i);this.updateVal(nA.data,"startx",r,Math.min),this.updateVal(nA.data,"starty",s,Math.min),this.updateVal(nA.data,"stopx",a,Math.max),this.updateVal(nA.data,"stopy",o,Math.max),this.updateBounds(r,s,a,o)},newActivation:function(t,e,n){const i=n[t.from.actor],r=lA(t.from.actor).length||0,a=i.x+i.width/2+(r-1)*eA.activationWidth/2;this.activations.push({startx:a,starty:this.verticalPos+2,stopx:a+eA.activationWidth,stopy:void 0,actor:t.from.actor,anchored:tA.anchorElement(e)})},endActivation:function(t){const e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from.actor);return this.activations.splice(e,1)[0]},createLoop:function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},newLoop:function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},endLoop:function(){return this.sequenceItems.pop()},addSectionToLoop:function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:nA.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},iA=t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),rA=t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),aA=t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight});const sA=function(t,e,n,i,r,a){if(!0===r.hideUnusedParticipants){const t=new Set;a.forEach((e=>{t.add(e.from),t.add(e.to)})),n=n.filter((e=>t.has(e)))}let s=0,o=0,c=0;for(const l of n){const n=e[l];n.width=n.width||eA.width,n.height=Math.max(n.height||eA.height,eA.height),n.margin=n.margin||eA.actorMargin,n.x=s+o,n.y=i;const r=tA.drawActor(t,n,eA);c=Math.max(c,r),nA.insert(n.x,i,n.x+n.width,n.height),s+=n.width,o+=n.margin,nA.models.addActor(n)}nA.bumpVerticalPos(c)},oA=function(t,e,n,i){let r=0,a=0;for(const s of n){const n=e[s],o=dA(n),c=tA.drawPopup(t,n,o,eA,eA.forceMenus,i);c.height>r&&(r=c.height),c.width+n.x>a&&(a=c.width+n.x)}return{maxHeight:r,maxWidth:a}},cA=function(t){Rx(eA,t),t.fontFamily&&(eA.actorFontFamily=eA.noteFontFamily=eA.messageFontFamily=t.fontFamily),t.fontSize&&(eA.actorFontSize=eA.noteFontSize=eA.messageFontSize=t.fontSize),t.fontWeight&&(eA.actorFontWeight=eA.noteFontWeight=eA.messageFontWeight=t.fontWeight)},lA=function(t){return nA.activations.filter((function(e){return e.actor===t}))},hA=function(t,e){const n=e[t],i=lA(t);return[i.reduce((function(t,e){return Math.min(t,e.startx)}),n.x+n.width/2),i.reduce((function(t,e){return Math.max(t,e.stopx)}),n.x+n.width/2)]};function uA(t,e,n,i,r){nA.bumpVerticalPos(n);let a=i;if(e.id&&e.message&&t[e.id]){const n=t[e.id].width,r=iA(eA);e.message=rv.wrapLabel(`[${e.message}]`,n-2*eA.wrapPadding,r),e.width=n,e.wrap=!0;const s=rv.calculateTextDimensions(e.message,r),o=Math.max(s.height,eA.labelBoxHeight);a=i+o,Bb.debug(`${o} - ${e.message}`)}r(e),nA.bumpVerticalPos(a)}const dA=function(t){let e=0;const n=aA(eA);for(const i in t.links){const t=rv.calculateTextDimensions(i,n).width+2*eA.wrapPadding+2*eA.boxMargin;e<t&&(e=t)}return e};const pA=function(t,e,n,i){const r={},a=[];let s,o,c;return t.forEach((function(t){switch(t.id=rv.random({length:10}),t.type){case i.db.LINETYPE.LOOP_START:case i.db.LINETYPE.ALT_START:case i.db.LINETYPE.OPT_START:case i.db.LINETYPE.PAR_START:case i.db.LINETYPE.CRITICAL_START:case i.db.LINETYPE.BREAK_START:a.push({id:t.id,msg:t.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case i.db.LINETYPE.ALT_ELSE:case i.db.LINETYPE.PAR_AND:case i.db.LINETYPE.CRITICAL_OPTION:t.message&&(s=a.pop(),r[s.id]=s,r[t.id]=s,a.push(s));break;case i.db.LINETYPE.LOOP_END:case i.db.LINETYPE.ALT_END:case i.db.LINETYPE.OPT_END:case i.db.LINETYPE.PAR_END:case i.db.LINETYPE.CRITICAL_END:case i.db.LINETYPE.BREAK_END:s=a.pop(),r[s.id]=s;break;case i.db.LINETYPE.ACTIVE_START:{const n=e[t.from?t.from.actor:t.to.actor],i=lA(t.from?t.from.actor:t.to.actor).length,r=n.x+n.width/2+(i-1)*eA.activationWidth/2,a={startx:r,stopx:r+eA.activationWidth,actor:t.from.actor,enabled:!0};nA.activations.push(a)}break;case i.db.LINETYPE.ACTIVE_END:{const e=nA.activations.map((t=>t.actor)).lastIndexOf(t.from.actor);delete nA.activations.splice(e,1)[0]}}void 0!==t.placement?(o=function(t,e,n){const i=e[t.from].x,r=e[t.to].x,a=t.wrap&&t.message;let s=rv.calculateTextDimensions(a?rv.wrapLabel(t.message,eA.width,rA(eA)):t.message,rA(eA));const o={width:a?eA.width:Math.max(eA.width,s.width+2*eA.noteMargin),height:0,startx:e[t.from].x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===n.db.PLACEMENT.RIGHTOF?(o.width=a?Math.max(eA.width,s.width):Math.max(e[t.from].width/2+e[t.to].width/2,s.width+2*eA.noteMargin),o.startx=i+(e[t.from].width+eA.actorMargin)/2):t.placement===n.db.PLACEMENT.LEFTOF?(o.width=a?Math.max(eA.width,s.width+2*eA.noteMargin):Math.max(e[t.from].width/2+e[t.to].width/2,s.width+2*eA.noteMargin),o.startx=i-o.width+(e[t.from].width-eA.actorMargin)/2):t.to===t.from?(s=rv.calculateTextDimensions(a?rv.wrapLabel(t.message,Math.max(eA.width,e[t.from].width),rA(eA)):t.message,rA(eA)),o.width=a?Math.max(eA.width,e[t.from].width):Math.max(e[t.from].width,eA.width,s.width+2*eA.noteMargin),o.startx=i+(e[t.from].width-o.width)/2):(o.width=Math.abs(i+e[t.from].width/2-(r+e[t.to].width/2))+eA.actorMargin,o.startx=i<r?i+e[t.from].width/2-eA.actorMargin/2:r+e[t.to].width/2-eA.actorMargin/2),a&&(o.message=rv.wrapLabel(t.message,o.width-2*eA.wrapPadding,rA(eA))),Bb.debug(`NM:[${o.startx},${o.stopx},${o.starty},${o.stopy}:${o.width},${o.height}=${t.message}]`),o}(t,e,i),t.noteModel=o,a.forEach((t=>{s=t,s.from=Math.min(s.from,o.startx),s.to=Math.max(s.to,o.startx+o.width),s.width=Math.max(s.width,Math.abs(s.from-s.to))-eA.labelBoxWidth}))):(c=function(t,e,n){let i=!1;if([n.db.LINETYPE.SOLID_OPEN,n.db.LINETYPE.DOTTED_OPEN,n.db.LINETYPE.SOLID,n.db.LINETYPE.DOTTED,n.db.LINETYPE.SOLID_CROSS,n.db.LINETYPE.DOTTED_CROSS,n.db.LINETYPE.SOLID_POINT,n.db.LINETYPE.DOTTED_POINT].includes(t.type)&&(i=!0),!i)return{};const r=hA(t.from,e),a=hA(t.to,e),s=r[0]<=a[0]?1:0,o=r[0]<a[0]?0:1,c=[...r,...a],l=Math.abs(a[o]-r[s]);t.wrap&&t.message&&(t.message=rv.wrapLabel(t.message,Math.max(l+2*eA.wrapPadding,eA.width),iA(eA)));const h=rv.calculateTextDimensions(t.message,iA(eA));return{width:Math.max(t.wrap?0:h.width+2*eA.wrapPadding,l+2*eA.wrapPadding,eA.width),height:0,startx:r[s],stopx:a[o],starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,c),toBounds:Math.max.apply(null,c)}}(t,e,i),t.msgModel=c,c.startx&&c.stopx&&a.length>0&&a.forEach((n=>{if(s=n,c.startx===c.stopx){const n=e[t.from],i=e[t.to];s.from=Math.min(n.x-c.width/2,n.x-n.width/2,s.from),s.to=Math.max(i.x+c.width/2,i.x+n.width/2,s.to),s.width=Math.max(s.width,Math.abs(s.to-s.from))-eA.labelBoxWidth}else s.from=Math.min(c.startx,s.from),s.to=Math.max(c.stopx,s.to),s.width=Math.max(s.width,c.width)-eA.labelBoxWidth})))})),nA.activations=[],Bb.debug("Loop type widths:",r),r},fA={bounds:nA,drawActors:sA,drawActorsPopup:oA,setConf:cA,draw:function(t,e,n,i){const{securityLevel:r,sequence:a}=fv();let s;eA=a,"sandbox"===r&&(s=Xo("#i"+e));const o=Xo("sandbox"===r?s.nodes()[0].contentDocument.body:"body"),c="sandbox"===r?s.nodes()[0].contentDocument:document;nA.init(),Bb.debug(i.db);const l="sandbox"===r?o.select(`[id="${e}"]`):Xo(`[id="${e}"]`),h=i.db.getActors(),u=i.db.getActorKeys(),d=i.db.getMessages(),p=i.db.getDiagramTitle(),f=function(t,e,n){const i={};return e.forEach((function(e){if(t[e.to]&&t[e.from]){const r=t[e.to];if(e.placement===n.db.PLACEMENT.LEFTOF&&!r.prevActor)return;if(e.placement===n.db.PLACEMENT.RIGHTOF&&!r.nextActor)return;const a=void 0!==e.placement,s=!a,o=a?rA(eA):iA(eA),c=e.wrap?rv.wrapLabel(e.message,eA.width-2*eA.wrapPadding,o):e.message,l=rv.calculateTextDimensions(c,o).width+2*eA.wrapPadding;s&&e.from===r.nextActor?i[e.to]=Math.max(i[e.to]||0,l):s&&e.from===r.prevActor?i[e.from]=Math.max(i[e.from]||0,l):s&&e.from===e.to?(i[e.from]=Math.max(i[e.from]||0,l/2),i[e.to]=Math.max(i[e.to]||0,l/2)):e.placement===n.db.PLACEMENT.RIGHTOF?i[e.from]=Math.max(i[e.from]||0,l):e.placement===n.db.PLACEMENT.LEFTOF?i[r.prevActor]=Math.max(i[r.prevActor]||0,l):e.placement===n.db.PLACEMENT.OVER&&(r.prevActor&&(i[r.prevActor]=Math.max(i[r.prevActor]||0,l/2)),r.nextActor&&(i[e.from]=Math.max(i[e.from]||0,l/2)))}})),Bb.debug("maxMessageWidthPerActor:",i),i}(h,d,i);eA.height=function(t,e){let n=0;Object.keys(t).forEach((e=>{const i=t[e];i.wrap&&(i.description=rv.wrapLabel(i.description,eA.width-2*eA.wrapPadding,aA(eA)));const r=rv.calculateTextDimensions(i.description,aA(eA));i.width=i.wrap?eA.width:Math.max(eA.width,r.width+2*eA.wrapPadding),i.height=i.wrap?Math.max(r.height,eA.height):eA.height,n=Math.max(n,i.height)}));for(const i in e){const n=t[i];if(!n)continue;const r=t[n.nextActor];if(!r)continue;const a=e[i]+eA.actorMargin-n.width/2-r.width/2;n.margin=Math.max(a,eA.actorMargin)}return Math.max(n,eA.height)}(h,f),tA.insertComputerIcon(l),tA.insertDatabaseIcon(l),tA.insertClockIcon(l),sA(l,h,u,0,eA,d);const g=pA(d,h,f,i);tA.insertArrowHead(l),tA.insertArrowCrossHead(l),tA.insertArrowFilledHead(l),tA.insertSequenceNumber(l);let y=1,m=1;const b=[];d.forEach((function(t){let e,n,r;switch(t.type){case i.db.LINETYPE.NOTE:n=t.noteModel,function(t,e){nA.bumpVerticalPos(eA.boxMargin),e.height=eA.boxMargin,e.starty=nA.getVerticalPos();const n=tA.getNoteRect();n.x=e.startx,n.y=e.starty,n.width=e.width||eA.width,n.class="note";const i=t.append("g"),r=tA.drawRect(i,n),a=tA.getTextObj();a.x=e.startx,a.y=e.starty,a.width=n.width,a.dy="1em",a.text=e.message,a.class="noteText",a.fontFamily=eA.noteFontFamily,a.fontSize=eA.noteFontSize,a.fontWeight=eA.noteFontWeight,a.anchor=eA.noteAlign,a.textMargin=eA.noteMargin,a.valign="center";const s=qS(i,a),o=Math.round(s.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));r.attr("height",o+2*eA.noteMargin),e.height+=o+2*eA.noteMargin,nA.bumpVerticalPos(o+2*eA.noteMargin),e.stopy=e.starty+o+2*eA.noteMargin,e.stopx=e.startx+n.width,nA.insert(e.startx,e.starty,e.stopx,e.stopy),nA.models.addNote(e)}(l,n);break;case i.db.LINETYPE.ACTIVE_START:nA.newActivation(t,l,h);break;case i.db.LINETYPE.ACTIVE_END:!function(t,e){const n=nA.endActivation(t);n.starty+18>e&&(n.starty=e-6,e+=12),tA.drawActivation(l,n,e,eA,lA(t.from.actor).length),nA.insert(n.startx,e-10,n.stopx,e)}(t,nA.getVerticalPos());break;case i.db.LINETYPE.LOOP_START:uA(g,t,eA.boxMargin,eA.boxMargin+eA.boxTextMargin,(t=>nA.newLoop(t)));break;case i.db.LINETYPE.LOOP_END:e=nA.endLoop(),tA.drawLoop(l,e,"loop",eA),nA.bumpVerticalPos(e.stopy-nA.getVerticalPos()),nA.models.addLoop(e);break;case i.db.LINETYPE.RECT_START:uA(g,t,eA.boxMargin,eA.boxMargin,(t=>nA.newLoop(void 0,t.message)));break;case i.db.LINETYPE.RECT_END:e=nA.endLoop(),tA.drawBackgroundRect(l,e),nA.models.addLoop(e),nA.bumpVerticalPos(e.stopy-nA.getVerticalPos());break;case i.db.LINETYPE.OPT_START:uA(g,t,eA.boxMargin,eA.boxMargin+eA.boxTextMargin,(t=>nA.newLoop(t)));break;case i.db.LINETYPE.OPT_END:e=nA.endLoop(),tA.drawLoop(l,e,"opt",eA),nA.bumpVerticalPos(e.stopy-nA.getVerticalPos()),nA.models.addLoop(e);break;case i.db.LINETYPE.ALT_START:uA(g,t,eA.boxMargin,eA.boxMargin+eA.boxTextMargin,(t=>nA.newLoop(t)));break;case i.db.LINETYPE.ALT_ELSE:uA(g,t,eA.boxMargin+eA.boxTextMargin,eA.boxMargin,(t=>nA.addSectionToLoop(t)));break;case i.db.LINETYPE.ALT_END:e=nA.endLoop(),tA.drawLoop(l,e,"alt",eA),nA.bumpVerticalPos(e.stopy-nA.getVerticalPos()),nA.models.addLoop(e);break;case i.db.LINETYPE.PAR_START:uA(g,t,eA.boxMargin,eA.boxMargin+eA.boxTextMargin,(t=>nA.newLoop(t)));break;case i.db.LINETYPE.PAR_AND:uA(g,t,eA.boxMargin+eA.boxTextMargin,eA.boxMargin,(t=>nA.addSectionToLoop(t)));break;case i.db.LINETYPE.PAR_END:e=nA.endLoop(),tA.drawLoop(l,e,"par",eA),nA.bumpVerticalPos(e.stopy-nA.getVerticalPos()),nA.models.addLoop(e);break;case i.db.LINETYPE.AUTONUMBER:y=t.message.start||y,m=t.message.step||m,t.message.visible?i.db.enableSequenceNumbers():i.db.disableSequenceNumbers();break;case i.db.LINETYPE.CRITICAL_START:uA(g,t,eA.boxMargin,eA.boxMargin+eA.boxTextMargin,(t=>nA.newLoop(t)));break;case i.db.LINETYPE.CRITICAL_OPTION:uA(g,t,eA.boxMargin+eA.boxTextMargin,eA.boxMargin,(t=>nA.addSectionToLoop(t)));break;case i.db.LINETYPE.CRITICAL_END:e=nA.endLoop(),tA.drawLoop(l,e,"critical",eA),nA.bumpVerticalPos(e.stopy-nA.getVerticalPos()),nA.models.addLoop(e);break;case i.db.LINETYPE.BREAK_START:uA(g,t,eA.boxMargin,eA.boxMargin+eA.boxTextMargin,(t=>nA.newLoop(t)));break;case i.db.LINETYPE.BREAK_END:e=nA.endLoop(),tA.drawLoop(l,e,"break",eA),nA.bumpVerticalPos(e.stopy-nA.getVerticalPos()),nA.models.addLoop(e);break;default:try{r=t.msgModel,r.starty=nA.getVerticalPos(),r.sequenceIndex=y,r.sequenceVisible=i.db.showSequenceNumbers();const e=function(t,e){nA.bumpVerticalPos(10);const{startx:n,stopx:i,message:r}=e,a=Wb.splitBreaks(r).length,s=rv.calculateTextDimensions(r,iA(eA)),o=s.height/a;let c;e.height+=o,nA.bumpVerticalPos(o);let l=s.height-10;const h=s.width;if(n===i){c=nA.getVerticalPos()+l,eA.rightAngles||(l+=eA.boxMargin,c=nA.getVerticalPos()+l),l+=30;const t=Math.max(h/2,eA.width/2);nA.insert(n-t,nA.getVerticalPos()-10+l,i+t,nA.getVerticalPos()+30+l)}else l+=eA.boxMargin,c=nA.getVerticalPos()+l,nA.insert(n,c-10,i,c);return nA.bumpVerticalPos(l),e.height+=l,e.stopy=e.starty+e.height,nA.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),c}(0,r);b.push({messageModel:r,lineStartY:e}),nA.models.addMessage(r)}catch(a){Bb.error("error while drawing message",a)}}[i.db.LINETYPE.SOLID_OPEN,i.db.LINETYPE.DOTTED_OPEN,i.db.LINETYPE.SOLID,i.db.LINETYPE.DOTTED,i.db.LINETYPE.SOLID_CROSS,i.db.LINETYPE.DOTTED_CROSS,i.db.LINETYPE.SOLID_POINT,i.db.LINETYPE.DOTTED_POINT].includes(t.type)&&(y+=m)})),b.forEach((t=>function(t,e,n,i){const{startx:r,stopx:a,starty:s,message:o,type:c,sequenceIndex:l,sequenceVisible:h}=e,u=rv.calculateTextDimensions(o,iA(eA)),d=tA.getTextObj();d.x=r,d.y=s+10,d.width=a-r,d.class="messageText",d.dy="1em",d.text=o,d.fontFamily=eA.messageFontFamily,d.fontSize=eA.messageFontSize,d.fontWeight=eA.messageFontWeight,d.anchor=eA.messageAlign,d.valign="center",d.textMargin=eA.wrapPadding,d.tspan=!1,qS(t,d);const p=u.width;let f;r===a?f=eA.rightAngles?t.append("path").attr("d",`M ${r},${n} H ${r+Math.max(eA.width/2,p/2)} V ${n+25} H ${r}`):t.append("path").attr("d","M "+r+","+n+" C "+(r+60)+","+(n-10)+" "+(r+60)+","+(n+30)+" "+r+","+(n+20)):(f=t.append("line"),f.attr("x1",r),f.attr("y1",n),f.attr("x2",a),f.attr("y2",n)),c===i.db.LINETYPE.DOTTED||c===i.db.LINETYPE.DOTTED_CROSS||c===i.db.LINETYPE.DOTTED_POINT||c===i.db.LINETYPE.DOTTED_OPEN?(f.style("stroke-dasharray","3, 3"),f.attr("class","messageLine1")):f.attr("class","messageLine0");let g="";eA.arrowMarkerAbsolute&&(g=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,g=g.replace(/\(/g,"\\("),g=g.replace(/\)/g,"\\)")),f.attr("stroke-width",2),f.attr("stroke","none"),f.style("fill","none"),c!==i.db.LINETYPE.SOLID&&c!==i.db.LINETYPE.DOTTED||f.attr("marker-end","url("+g+"#arrowhead)"),c!==i.db.LINETYPE.SOLID_POINT&&c!==i.db.LINETYPE.DOTTED_POINT||f.attr("marker-end","url("+g+"#filled-head)"),c!==i.db.LINETYPE.SOLID_CROSS&&c!==i.db.LINETYPE.DOTTED_CROSS||f.attr("marker-end","url("+g+"#crosshead)"),(h||eA.showSequenceNumbers)&&(f.attr("marker-start","url("+g+"#sequencenumber)"),t.append("text").attr("x",r).attr("y",n+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(l))}(l,t.messageModel,t.lineStartY,i))),eA.mirrorActors&&(nA.bumpVerticalPos(2*eA.boxMargin),sA(l,h,u,nA.getVerticalPos(),eA,d),nA.bumpVerticalPos(eA.boxMargin),XS(l,nA.getVerticalPos()));const _=oA(l,h,u,c),{bounds:x}=nA.getBounds();Bb.debug("For line height fix Querying: #"+e+" .actor-line");Zo("#"+e+" .actor-line").attr("y2",x.stopy);let v=x.stopy-x.starty;v<_.maxHeight&&(v=_.maxHeight);let k=v+2*eA.diagramMarginY;eA.mirrorActors&&(k=k-eA.boxMargin+eA.bottomMarginAdj);let w=x.stopx-x.startx;w<_.maxWidth&&(w=_.maxWidth);const T=w+2*eA.diagramMarginX;p&&l.append("text").text(p).attr("x",(x.stopx-x.startx)/2-2*eA.diagramMarginX).attr("y",-25),vv(l,k,T,eA.useMaxWidth);const C=p?40:0;l.attr("viewBox",x.startx-eA.diagramMarginX+" -"+(eA.diagramMarginY+C)+" "+T+" "+(k+C)),Bb.debug("models:",nA.models)}};var gA=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,2],i=[1,3],r=[1,5],a=[1,7],s=[2,5],o=[1,15],c=[1,17],l=[1,21],h=[1,22],u=[1,23],d=[1,24],p=[1,37],f=[1,25],g=[1,26],y=[1,27],m=[1,28],b=[1,29],_=[1,32],x=[1,33],v=[1,34],k=[1,35],w=[1,36],T=[1,39],C=[1,40],E=[1,41],S=[1,42],A=[1,38],D=[1,45],L=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],N=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],O=[1,4,5,7,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],B=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],M={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,directive:6,SD:7,document:8,line:9,statement:10,classDefStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"--\x3e":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,classDef:38,CLASSDEF_ID:39,CLASSDEF_STYLEOPTS:40,DEFAULT:41,class:42,CLASSENTITY_IDS:43,STYLECLASS:44,openDirective:45,typeDirective:46,closeDirective:47,":":48,argDirective:49,direction_tb:50,direction_bt:51,direction_rl:52,direction_lr:53,eol:54,";":55,EDGE_STATE:56,STYLE_SEPARATOR:57,left_of:58,right_of:59,open_directive:60,type_directive:61,arg_directive:62,close_directive:63,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",7:"SD",14:"DESCR",15:"--\x3e",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"classDef",39:"CLASSDEF_ID",40:"CLASSDEF_STYLEOPTS",41:"DEFAULT",42:"class",43:"CLASSENTITY_IDS",44:"STYLECLASS",48:":",50:"direction_tb",51:"direction_bt",52:"direction_rl",53:"direction_lr",55:";",56:"EDGE_STATE",57:"STYLE_SEPARATOR",58:"left_of",59:"right_of",60:"open_directive",61:"type_directive",62:"arg_directive",63:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[10,1],[10,1],[10,1],[10,2],[10,3],[10,4],[10,1],[10,2],[10,1],[10,4],[10,3],[10,6],[10,1],[10,1],[10,1],[10,1],[10,4],[10,4],[10,1],[10,1],[10,2],[10,2],[10,1],[11,3],[11,3],[12,3],[6,3],[6,5],[32,1],[32,1],[32,1],[32,1],[54,1],[54,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1],[45,1],[46,1],[49,1],[47,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 4:return i.setRootDoc(a[o]),a[o];case 5:this.$=[];break;case 6:"nl"!=a[o]&&(a[o-1].push(a[o]),this.$=a[o-1]);break;case 7:case 8:case 12:this.$=a[o];break;case 9:this.$="nl";break;case 13:const t=a[o-1];t.description=i.trimColon(a[o]),this.$=t;break;case 14:this.$={stmt:"relation",state1:a[o-2],state2:a[o]};break;case 15:const e=i.trimColon(a[o]);this.$={stmt:"relation",state1:a[o-3],state2:a[o-1],description:e};break;case 19:this.$={stmt:"state",id:a[o-3],type:"default",description:"",doc:a[o-1]};break;case 20:var c=a[o],l=a[o-2].trim();if(a[o].match(":")){var h=a[o].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 21:this.$={stmt:"state",id:a[o-3],type:"default",description:a[o-5],doc:a[o-1]};break;case 22:this.$={stmt:"state",id:a[o],type:"fork"};break;case 23:this.$={stmt:"state",id:a[o],type:"join"};break;case 24:this.$={stmt:"state",id:a[o],type:"choice"};break;case 25:this.$={stmt:"state",id:i.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:a[o-1].trim(),note:{position:a[o-2].trim(),text:a[o].trim()}};break;case 30:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 31:case 32:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 33:case 34:this.$={stmt:"classDef",id:a[o-1].trim(),classes:a[o].trim()};break;case 35:this.$={stmt:"applyClass",id:a[o-1].trim(),styleClass:a[o].trim()};break;case 38:i.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:i.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:i.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:i.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:a[o].trim(),type:"default",description:""};break;case 46:case 47:this.$={stmt:"state",id:a[o-2].trim(),classes:[a[o].trim()],type:"default",description:""};break;case 50:i.parseDirective("%%{","open_directive");break;case 51:i.parseDirective(a[o],"type_directive");break;case 52:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 53:i.parseDirective("}%%","close_directive","state")}},table:[{3:1,4:n,5:i,6:4,7:r,45:6,60:a},{1:[3]},{3:8,4:n,5:i,6:4,7:r,45:6,60:a},{3:9,4:n,5:i,6:4,7:r,45:6,60:a},{3:10,4:n,5:i,6:4,7:r,45:6,60:a},e([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],s,{8:11}),{46:12,61:[1,13]},{61:[2,50]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:o,5:c,6:30,9:14,10:16,11:18,12:19,13:20,16:l,17:h,19:u,22:d,24:p,25:f,26:g,27:y,28:m,29:b,32:31,33:_,35:x,37:v,38:k,42:w,45:6,50:T,51:C,52:E,53:S,56:A,60:a},{47:43,48:[1,44],63:D},e([48,63],[2,51]),e(L,[2,6]),{6:30,10:46,11:18,12:19,13:20,16:l,17:h,19:u,22:d,24:p,25:f,26:g,27:y,28:m,29:b,32:31,33:_,35:x,37:v,38:k,42:w,45:6,50:T,51:C,52:E,53:S,56:A,60:a},e(L,[2,8]),e(L,[2,9]),e(L,[2,10]),e(L,[2,11]),e(L,[2,12],{14:[1,47],15:[1,48]}),e(L,[2,16]),{18:[1,49]},e(L,[2,18],{20:[1,50]}),{23:[1,51]},e(L,[2,22]),e(L,[2,23]),e(L,[2,24]),e(L,[2,25]),{30:52,31:[1,53],58:[1,54],59:[1,55]},e(L,[2,28]),e(L,[2,29]),{34:[1,56]},{36:[1,57]},e(L,[2,32]),{39:[1,58],41:[1,59]},{43:[1,60]},e(N,[2,44],{57:[1,61]}),e(N,[2,45],{57:[1,62]}),e(L,[2,38]),e(L,[2,39]),e(L,[2,40]),e(L,[2,41]),e(O,[2,36]),{49:63,62:[1,64]},e(O,[2,53]),e(L,[2,7]),e(L,[2,13]),{13:65,24:p,56:A},e(L,[2,17]),e(B,s,{8:66}),{24:[1,67]},{24:[1,68]},{23:[1,69]},{24:[2,48]},{24:[2,49]},e(L,[2,30]),e(L,[2,31]),{40:[1,70]},{40:[1,71]},{44:[1,72]},{24:[1,73]},{24:[1,74]},{47:75,63:D},{63:[2,52]},e(L,[2,14],{14:[1,76]}),{4:o,5:c,6:30,9:14,10:16,11:18,12:19,13:20,16:l,17:h,19:u,21:[1,77],22:d,24:p,25:f,26:g,27:y,28:m,29:b,32:31,33:_,35:x,37:v,38:k,42:w,45:6,50:T,51:C,52:E,53:S,56:A,60:a},e(L,[2,20],{20:[1,78]}),{31:[1,79]},{24:[1,80]},e(L,[2,33]),e(L,[2,34]),e(L,[2,35]),e(N,[2,46]),e(N,[2,47]),e(O,[2,37]),e(L,[2,15]),e(L,[2,19]),e(B,s,{8:81}),e(L,[2,26]),e(L,[2,27]),{4:o,5:c,6:30,9:14,10:16,11:18,12:19,13:20,16:l,17:h,19:u,21:[1,82],22:d,24:p,25:f,26:g,27:y,28:m,29:b,32:31,33:_,35:x,37:v,38:k,42:w,45:6,50:T,51:C,52:E,53:S,56:A,60:a},e(L,[2,21])],defaultActions:{7:[2,50],8:[2,1],9:[2,2],10:[2,3],54:[2,48],55:[2,49],64:[2,52]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},I=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return 41;case 1:case 44:return 50;case 2:case 45:return 51;case 3:case 46:return 52;case 4:case 47:return 53;case 5:return this.begin("open_directive"),60;case 6:return this.begin("type_directive"),61;case 7:return this.popState(),this.begin("arg_directive"),48;case 8:return this.popState(),this.popState(),63;case 9:return 62;case 10:case 11:case 13:case 14:case 15:case 16:case 56:case 58:case 64:break;case 12:case 79:return 5;case 17:case 34:return this.pushState("SCALE"),17;case 18:case 35:return 18;case 19:case 25:case 36:case 51:case 54:this.popState();break;case 20:return this.begin("acc_title"),33;case 21:return this.popState(),"acc_title_value";case 22:return this.begin("acc_descr"),35;case 23:return this.popState(),"acc_descr_value";case 24:this.begin("acc_descr_multiline");break;case 26:return"acc_descr_multiline_value";case 27:return this.pushState("CLASSDEF"),38;case 28:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 29:return this.popState(),this.pushState("CLASSDEFID"),39;case 30:return this.popState(),40;case 31:return this.pushState("CLASS"),42;case 32:return this.popState(),this.pushState("CLASS_STYLE"),43;case 33:return this.popState(),44;case 37:this.pushState("STATE");break;case 38:case 41:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 39:case 42:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),26;case 40:case 43:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),27;case 48:this.begin("STATE_STRING");break;case 49:return this.popState(),this.pushState("STATE_ID"),"AS";case 50:case 66:return this.popState(),"ID";case 52:return"STATE_DESCR";case 53:return 19;case 55:return this.popState(),this.pushState("struct"),20;case 57:return this.popState(),21;case 59:return this.begin("NOTE"),29;case 60:return this.popState(),this.pushState("NOTE_ID"),58;case 61:return this.popState(),this.pushState("NOTE_ID"),59;case 62:this.popState(),this.pushState("FLOATING_NOTE");break;case 63:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 65:return"NOTE_TEXT";case 67:return this.popState(),this.pushState("NOTE_TEXT"),24;case 68:return this.popState(),e.yytext=e.yytext.substr(2).trim(),31;case 69:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),31;case 70:case 71:return 7;case 72:return 16;case 73:return 56;case 74:return 24;case 75:return e.yytext=e.yytext.trim(),14;case 76:return 15;case 77:return 28;case 78:return 57;case 80:return"INVALID"}},rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<<fork>>)/i,/^(?:.*<<join>>)/i,/^(?:.*<<choice>>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[14,15],inclusive:!1},close_directive:{rules:[14,15],inclusive:!1},arg_directive:{rules:[8,9,14,15],inclusive:!1},type_directive:{rules:[7,8,14,15],inclusive:!1},open_directive:{rules:[6,14,15],inclusive:!1},struct:{rules:[14,15,27,31,37,44,45,46,47,56,57,58,59,73,74,75,76,77],inclusive:!1},FLOATING_NOTE_ID:{rules:[66],inclusive:!1},FLOATING_NOTE:{rules:[63,64,65],inclusive:!1},NOTE_TEXT:{rules:[68,69],inclusive:!1},NOTE_ID:{rules:[67],inclusive:!1},NOTE:{rules:[60,61,62],inclusive:!1},CLASS_STYLE:{rules:[33],inclusive:!1},CLASS:{rules:[32],inclusive:!1},CLASSDEFID:{rules:[30],inclusive:!1},CLASSDEF:{rules:[28,29],inclusive:!1},acc_descr_multiline:{rules:[25,26],inclusive:!1},acc_descr:{rules:[23],inclusive:!1},acc_title:{rules:[21],inclusive:!1},SCALE:{rules:[18,19,35,36],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[50],inclusive:!1},STATE_STRING:{rules:[51,52],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[14,15,38,39,40,41,42,43,48,49,53,54,55],inclusive:!1},ID:{rules:[14,15],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,10,11,12,13,15,16,17,20,22,24,27,31,34,37,55,59,70,71,72,73,74,75,76,78,79,80],inclusive:!0}}},t);function F(){this.yy={}}return M.lexer=I,F.prototype=M,M.Parser=F,new F}();gA.parser=gA;const yA=gA,mA=(t,e)=>{var n;return"dagre-wrapper"!==(null==(n=null==e?void 0:e.state)?void 0:n.defaultRenderer)&&null!==t.match(/^\s*stateDiagram/)},bA=(t,e)=>{var n;return null!==t.match(/^\s*stateDiagram-v2/)||!(!t.match(/^\s*stateDiagram/)||"dagre-wrapper"!==(null==(n=null==e?void 0:e.state)?void 0:n.defaultRenderer))},_A="state",xA="relation",vA="default",kA="divider",wA="[*]",TA="start",CA="color",EA="fill";let SA="LR",AA=[],DA={};let LA={root:{relations:[],states:{},documents:{}}},NA=LA.root,OA=0,BA=0;const MA=t=>JSON.parse(JSON.stringify(t)),IA=(t,e,n)=>{if(e.stmt===xA)IA(t,e.state1,!0),IA(t,e.state2,!1);else if(e.stmt===_A&&"[*]"===e.id&&(e.id=n?t.id+"_start":t.id+"_end",e.start=n),e.doc){const t=[];let n,i=[];for(n=0;n<e.doc.length;n++)if(e.doc[n].type===kA){const r=MA(e.doc[n]);r.doc=MA(i),t.push(r),i=[]}else i.push(e.doc[n]);if(t.length>0&&i.length>0){const n={stmt:_A,id:qx(),type:"divider",doc:MA(i)};t.push(MA(n)),e.doc=t}e.doc.forEach((t=>IA(e,t,!0)))}},FA=function(t,e="default",n=null,i=null,r=null,a=null,s=null,o=null){if(void 0===NA.states[t]?(Bb.info("Adding state ",t,i),NA.states[t]={id:t,descriptions:[],type:e,doc:n,note:r,classes:[],styles:[],textStyles:[]}):(NA.states[t].doc||(NA.states[t].doc=n),NA.states[t].type||(NA.states[t].type=e)),i&&(Bb.info("Setting state description",t,i),"string"==typeof i&&zA(t,i.trim()),"object"==typeof i&&i.forEach((e=>zA(t,e.trim())))),r&&(NA.states[t].note=r,NA.states[t].note.text=Wb.sanitizeText(NA.states[t].note.text,fv())),a){Bb.info("Setting state classes",t,a);("string"==typeof a?[a]:a).forEach((e=>WA(t,e.trim())))}if(s){Bb.info("Setting state styles",t,s);("string"==typeof s?[s]:s).forEach((e=>HA(t,e.trim())))}if(o){Bb.info("Setting state styles",t,s);("string"==typeof o?[o]:o).forEach((e=>qA(t,e.trim())))}},RA=function(t){LA={root:{relations:[],states:{},documents:{}}},NA=LA.root,OA=0,DA={},t||Kv()},$A=function(t){return NA.states[t]};function PA(t=""){let e=t;return t===wA&&(OA++,e=`start${OA}`),e}function jA(t="",e="default"){return t===wA?TA:e}const YA=function(t,e,n){if("object"==typeof t)!function(t,e,n){let i=PA(t.id),r=jA(t.id,t.type),a=PA(e.id),s=jA(e.id,e.type);FA(i,r,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles),FA(a,s,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),NA.relations.push({id1:i,id2:a,relationTitle:Wb.sanitizeText(n,fv())})}(t,e,n);else{const i=PA(t),r=jA(t),a=function(t=""){let e=t;return"[*]"===t&&(OA++,e=`end${OA}`),e}(e),s=function(t="",e="default"){return"[*]"===t?"end":e}(e);FA(i,r),FA(a,s),NA.relations.push({id1:i,id2:a,title:Wb.sanitizeText(n,fv())})}},zA=function(t,e){const n=NA.states[t],i=e.startsWith(":")?e.replace(":","").trim():e;n.descriptions.push(Wb.sanitizeText(i,fv()))},UA=function(t,e=""){void 0===DA[t]&&(DA[t]={id:t,styles:[],textStyles:[]});const n=DA[t];null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(t.match(CA)){const t=e.replace(EA,"bgFill").replace(CA,EA);n.textStyles.push(t)}n.styles.push(e)}))},WA=function(t,e){t.split(",").forEach((function(t){let n=$A(t);if(void 0===n){const e=t.trim();FA(e),n=$A(e)}n.classes.push(e)}))},HA=function(t,e){const n=$A(t);void 0!==n&&n.textStyles.push(e)},qA=function(t,e){const n=$A(t);void 0!==n&&n.textStyles.push(e)},VA={parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().state,addState:FA,clear:RA,getState:$A,getStates:function(){return NA.states},getRelations:function(){return NA.relations},getClasses:function(){return DA},getDirection:()=>SA,addRelation:YA,getDividerId:()=>(BA++,"divider-id-"+BA),setDirection:t=>{SA=t},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:function(){Bb.info("Documents = ",LA)},getRootDoc:()=>AA,setRootDoc:t=>{Bb.info("Setting root doc",t),AA=t},getRootDocV2:()=>(IA({id:"root"},{id:"root",doc:AA},!0),{id:"root",doc:AA}),extract:t=>{let e;e=t.doc?t.doc:t,Bb.info(e),RA(!0),Bb.info("Extract",e),e.forEach((t=>{switch(t.stmt){case _A:FA(t.id,t.type,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles);break;case xA:YA(t.state1,t.state2,t.description);break;case"classDef":UA(t.id,t.classes);break;case"applyClass":WA(t.id,t.styleClass)}}))},trimColon:t=>t&&":"===t[0]?t.substr(1).trim():t.trim(),getAccTitle:tk,setAccTitle:Jv,getAccDescription:nk,setAccDescription:ek,addStyleClass:UA,setCssClass:WA,addDescription:zA,setDiagramTitle:ik,getDiagramTitle:rk},GA={},XA=(t,e)=>{GA[t]=e},ZA=(t,e)=>{const n=t.append("text").attr("x",2*fv().state.padding).attr("y",fv().state.textHeight+1.3*fv().state.padding).attr("font-size",fv().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),i=n.height,r=t.append("text").attr("x",fv().state.padding).attr("y",i+.4*fv().state.padding+fv().state.dividerMargin+fv().state.textHeight).attr("class","state-description");let a=!0,s=!0;e.descriptions.forEach((function(t){a||(!function(t,e,n){const i=t.append("tspan").attr("x",2*fv().state.padding).text(e);n||i.attr("dy",fv().state.textHeight)}(r,t,s),s=!1),a=!1}));const o=t.append("line").attr("x1",fv().state.padding).attr("y1",fv().state.padding+i+fv().state.dividerMargin/2).attr("y2",fv().state.padding+i+fv().state.dividerMargin/2).attr("class","descr-divider"),c=r.node().getBBox(),l=Math.max(c.width,n.width);return o.attr("x2",l+3*fv().state.padding),t.insert("rect",":first-child").attr("x",fv().state.padding).attr("y",fv().state.padding).attr("width",l+2*fv().state.padding).attr("height",c.height+i+2*fv().state.padding).attr("rx",fv().state.radius),t},QA=(t,e,n)=>{const i=fv().state.padding,r=2*fv().state.padding,a=t.node().getBBox(),s=a.width,o=a.x,c=t.append("text").attr("x",0).attr("y",fv().state.titleShift).attr("font-size",fv().state.fontSize).attr("class","state-title").text(e.id),l=c.node().getBBox().width+r;let h,u=Math.max(l,s);u===s&&(u+=r);const d=t.node().getBBox();e.doc,h=o-i,l>s&&(h=(s-u)/2+i),Math.abs(o-d.x)<i&&l>s&&(h=o-(l-s)/2);const p=1-fv().state.textHeight;return t.insert("rect",":first-child").attr("x",h).attr("y",p).attr("class",n?"alt-composit":"composit").attr("width",u).attr("height",d.height+fv().state.textHeight+fv().state.titleShift+1).attr("rx","0"),c.attr("x",h+i),l<=s&&c.attr("x",o+(u-r)/2-l/2+i),t.insert("rect",":first-child").attr("x",h).attr("y",fv().state.titleShift-fv().state.textHeight-fv().state.padding).attr("width",u).attr("height",3*fv().state.textHeight).attr("rx",fv().state.radius),t.insert("rect",":first-child").attr("x",h).attr("y",fv().state.titleShift-fv().state.textHeight-fv().state.padding).attr("width",u).attr("height",d.height+3+2*fv().state.textHeight).attr("rx",fv().state.radius),t},KA=(t,e)=>{e.attr("class","state-note");const n=e.append("rect").attr("x",0).attr("y",fv().state.padding),i=e.append("g"),{textWidth:r,textHeight:a}=((t,e,n,i)=>{let r=0;const a=i.append("text");a.style("text-anchor","start"),a.attr("class","noteText");let s=t.replace(/\r\n/g,"<br/>");s=s.replace(/\n/g,"<br/>");const o=s.split(Wb.lineBreakRegex);let c=1.25*fv().state.noteMargin;for(const l of o){const t=l.trim();if(t.length>0){const i=a.append("tspan");i.text(t),0===c&&(c+=i.node().getBBox().height),r+=c,i.attr("x",e+fv().state.noteMargin),i.attr("y",n+r+1.25*fv().state.noteMargin)}}return{textWidth:a.node().getBBox().width,textHeight:r}})(t,0,0,i);return n.attr("height",a+2*fv().state.noteMargin),n.attr("width",r+2*fv().state.noteMargin),n},JA=function(t,e){const n=e.id,i={id:n,label:e.id,width:0,height:0},r=t.append("g").attr("id",n).attr("class","stateGroup");"start"===e.type&&(t=>{t.append("circle").attr("class","start-state").attr("r",fv().state.sizeUnit).attr("cx",fv().state.padding+fv().state.sizeUnit).attr("cy",fv().state.padding+fv().state.sizeUnit)})(r),"end"===e.type&&(t=>{t.append("circle").attr("class","end-state-outer").attr("r",fv().state.sizeUnit+fv().state.miniPadding).attr("cx",fv().state.padding+fv().state.sizeUnit+fv().state.miniPadding).attr("cy",fv().state.padding+fv().state.sizeUnit+fv().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",fv().state.sizeUnit).attr("cx",fv().state.padding+fv().state.sizeUnit+2).attr("cy",fv().state.padding+fv().state.sizeUnit+2)})(r),"fork"!==e.type&&"join"!==e.type||((t,e)=>{let n=fv().state.forkWidth,i=fv().state.forkHeight;if(e.parentId){let t=n;n=i,i=t}t.append("rect").style("stroke","black").style("fill","black").attr("width",n).attr("height",i).attr("x",fv().state.padding).attr("y",fv().state.padding)})(r,e),"note"===e.type&&KA(e.note.text,r),"divider"===e.type&&(t=>{t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",fv().state.textHeight).attr("class","divider").attr("x2",2*fv().state.textHeight).attr("y1",0).attr("y2",0)})(r),"default"===e.type&&0===e.descriptions.length&&((t,e)=>{const n=t.append("text").attr("x",2*fv().state.padding).attr("y",fv().state.textHeight+2*fv().state.padding).attr("font-size",fv().state.fontSize).attr("class","state-title").text(e.id),i=n.node().getBBox();t.insert("rect",":first-child").attr("x",fv().state.padding).attr("y",fv().state.padding).attr("width",i.width+2*fv().state.padding).attr("height",i.height+2*fv().state.padding).attr("rx",fv().state.radius)})(r,e),"default"===e.type&&e.descriptions.length>0&&ZA(r,e);const a=r.node().getBBox();return i.width=a.width+2*fv().state.padding,i.height=a.height+2*fv().state.padding,XA(n,i),i};let tD=0;let eD;const nD={},iD=(t,e,n,i,r,a,s)=>{const o=new Qf({compound:!0,multigraph:!0});let c,l=!0;for(c=0;c<t.length;c++)if("relation"===t[c].stmt){l=!1;break}n?o.setGraph({rankdir:"LR",multigraph:!0,compound:!0,ranker:"tight-tree",ranksep:l?1:eD.edgeLengthFactor,nodeSep:l?1:50,isMultiGraph:!0}):o.setGraph({rankdir:"TB",multigraph:!0,compound:!0,ranksep:l?1:eD.edgeLengthFactor,nodeSep:l?1:50,ranker:"tight-tree",isMultiGraph:!0}),o.setDefaultEdgeLabel((function(){return{}})),s.db.extract(t);const h=s.db.getStates(),u=s.db.getRelations(),d=Object.keys(h);for(const m of d){const t=h[m];let c;if(n&&(t.parentId=n),t.doc){let n=e.append("g").attr("id",t.id).attr("class","stateGroup");c=iD(t.doc,n,t.id,!i,r,a,s);{n=QA(n,t,i);let e=n.node().getBBox();c.width=e.width,c.height=e.height+eD.padding/2,nD[t.id]={y:eD.compositTitleSize}}}else c=JA(e,t);if(t.note){const n={descriptions:[],id:t.id+"-note",note:t.note,type:"note"},i=JA(e,n);"left of"===t.note.position?(o.setNode(c.id+"-note",i),o.setNode(c.id,c)):(o.setNode(c.id,c),o.setNode(c.id+"-note",i)),o.setParent(c.id,c.id+"-group"),o.setParent(c.id+"-note",c.id+"-group")}else o.setNode(c.id,c)}Bb.debug("Count=",o.nodeCount(),o);let p=0;u.forEach((function(t){var e;p++,Bb.debug("Setting edge",t),o.setEdge(t.id1,t.id2,{relation:t,width:(e=t.title,e?e.length*eD.fontSizeFactor:1),height:eD.labelHeight*Wb.getRows(t.title).length,labelpos:"c"},"id"+p)})),Lm(o),Bb.debug("Graph after layout",o.nodes());const f=e.node();o.nodes().forEach((function(t){if(void 0!==t&&void 0!==o.node(t)){Bb.warn("Node "+t+": "+JSON.stringify(o.node(t))),r.select("#"+f.id+" #"+t).attr("transform","translate("+(o.node(t).x-o.node(t).width/2)+","+(o.node(t).y+(nD[t]?nD[t].y:0)-o.node(t).height/2)+" )"),r.select("#"+f.id+" #"+t).attr("data-x-shift",o.node(t).x-o.node(t).width/2);a.querySelectorAll("#"+f.id+" #"+t+" .divider").forEach((t=>{const e=t.parentElement;let n=0,i=0;e&&(e.parentElement&&(n=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",n-i-8)}))}else Bb.debug("No Node "+t+": "+JSON.stringify(o.node(t)))}));let g=f.getBBox();o.edges().forEach((function(t){void 0!==t&&void 0!==o.edge(t)&&(Bb.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(o.edge(t))),function(t,e,n){e.points=e.points.filter((t=>!Number.isNaN(t.y)));const i=e.points,r=Nc().x((function(t){return t.x})).y((function(t){return t.y})).curve(Rc),a=t.append("path").attr("d",r(i)).attr("id","edge"+tD).attr("class","transition");let s="";if(fv().state.arrowMarkerAbsolute&&(s=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,s=s.replace(/\(/g,"\\("),s=s.replace(/\)/g,"\\)")),a.attr("marker-end","url("+s+"#"+function(t){switch(t){case VA.relationType.AGGREGATION:return"aggregation";case VA.relationType.EXTENSION:return"extension";case VA.relationType.COMPOSITION:return"composition";case VA.relationType.DEPENDENCY:return"dependency"}}(VA.relationType.DEPENDENCY)+"End)"),void 0!==n.title){const i=t.append("g").attr("class","stateLabel"),{x:r,y:a}=rv.calcLabelPosition(e.points),s=Wb.getRows(n.title);let o=0;const c=[];let l=0,h=0;for(let t=0;t<=s.length;t++){const e=i.append("text").attr("text-anchor","middle").text(s[t]).attr("x",r).attr("y",a+o),n=e.node().getBBox();if(l=Math.max(l,n.width),h=Math.min(h,n.x),Bb.info(n.x,r,a+o),0===o){const t=e.node().getBBox();o=t.height,Bb.info("Title height",o,a)}c.push(e)}let u=o*s.length;if(s.length>1){const t=(s.length-1)*o*.5;c.forEach(((e,n)=>e.attr("y",a+n*o-t))),u=o*s.length}const d=i.node().getBBox();i.insert("rect",":first-child").attr("class","box").attr("x",r-l/2-fv().state.padding/2).attr("y",a-u/2-fv().state.padding/2-3.5).attr("width",l+fv().state.padding).attr("height",u+fv().state.padding),Bb.info(d)}tD++}(e,o.edge(t),o.edge(t).relation))})),g=f.getBBox();const y={id:n||"root",label:n||"root",width:0,height:0};return y.width=g.width+2*eD.padding,y.height=g.height+2*eD.padding,Bb.debug("Doc rendered",y,o),y},rD={setConf:function(){},draw:function(t,e,n,i){eD=fv().state;const r=fv().securityLevel;let a;"sandbox"===r&&(a=Xo("#i"+e));const s=Xo("sandbox"===r?a.nodes()[0].contentDocument.body:"body"),o="sandbox"===r?a.nodes()[0].contentDocument:document;Bb.debug("Rendering diagram "+t);const c=s.select(`[id='${e}']`);c.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z");new Qf({multigraph:!0,compound:!0,rankdir:"RL"}).setDefaultEdgeLabel((function(){return{}}));const l=i.db.getRootDoc();iD(l,c,void 0,!1,s,o,i);const h=eD.padding,u=c.node().getBBox(),d=u.width+2*h,p=u.height+2*h;vv(c,p,1.75*d,eD.useMaxWidth),c.attr("viewBox",`${u.x-eD.padding} ${u.y-eD.padding} `+d+" "+p)}},aD="rect",sD="rectWithTitle",oD="statediagram",cD="transition",lD="parent",hD="note",uD="----parent",dD="fill:none",pD="fill: #333",fD="text",gD="normal";let yD={},mD=0;function bD(t="",e=0,n="",i="----"){return`state-${t}${null!==n&&n.length>0?`${i}${n}`:""}-${e}`}const _D=(t,e,n,i,r,a)=>{const s=n.id,o=null==(c=i[s])?"":c.classes?c.classes.join(" "):"";var c;if("root"!==s){let e=aD;!0===n.start&&(e="start"),!1===n.start&&(e="end"),n.type!==vA&&(e=n.type),yD[s]||(yD[s]={id:s,shape:e,description:Wb.sanitizeText(s,fv()),classes:`${o} statediagram-state`});const i=yD[s];n.description&&(Array.isArray(i.description)?(i.shape=sD,i.description.push(n.description)):i.description.length>0?(i.shape=sD,i.description===s?i.description=[n.description]:i.description=[i.description,n.description]):(i.shape=aD,i.description=n.description),i.description=Wb.sanitizeTextOrArray(i.description,fv())),1===i.description.length&&i.shape===sD&&(i.shape=aD),!i.type&&n.doc&&(Bb.info("Setting cluster for ",s,vD(n)),i.type="group",i.dir=vD(n),i.shape=n.type===kA?"divider":"roundedWithTitle",i.classes=i.classes+" statediagram-cluster "+(a?"statediagram-cluster-alt":""));const r={labelStyle:"",shape:i.shape,labelText:i.description,classes:i.classes,style:"",id:s,dir:i.dir,domId:bD(s,mD),type:i.type,padding:15};if(n.note){const e={labelStyle:"",shape:"note",labelText:n.note.text,classes:"statediagram-note",style:"",id:s+"----note-"+mD,domId:bD(s,mD,hD),type:i.type,padding:15},a={labelStyle:"",shape:"noteGroup",labelText:n.note.text,classes:i.classes,style:"",id:s+uD,domId:bD(s,mD,lD),type:"group",padding:0};mD++;const o=s+uD;t.setNode(o,a),t.setNode(e.id,e),t.setNode(s,r),t.setParent(s,o),t.setParent(e.id,o);let c=s,l=e.id;"left of"===n.note.position&&(c=e.id,l=s),t.setEdge(c,l,{arrowhead:"none",arrowType:"",style:dD,labelStyle:"",classes:"transition note-edge",arrowheadStyle:pD,labelpos:"c",labelType:fD,thickness:gD})}else t.setNode(s,r)}e&&"root"!==e.id&&(Bb.trace("Setting node ",s," to be child of its parent ",e.id),t.setParent(s,e.id)),n.doc&&(Bb.trace("Adding nodes children "),xD(t,n,n.doc,i,r,!a))},xD=(t,e,n,i,r,a)=>{Bb.trace("items",n),n.forEach((n=>{switch(n.stmt){case _A:case vA:_D(t,e,n,i,r,a);break;case xA:{_D(t,e,n.state1,i,r,a),_D(t,e,n.state2,i,r,a);const s={id:"edge"+mD,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:dD,labelStyle:"",label:Wb.sanitizeText(n.description,fv()),arrowheadStyle:pD,labelpos:"c",labelType:fD,thickness:gD,classes:cD};t.setEdge(n.state1.id,n.state2.id,s,mD),mD++}}}))},vD=(t,e="TB")=>{let n=e;if(t.doc)for(let i=0;i<t.doc.length;i++){const e=t.doc[i];"dir"===e.stmt&&(n=e.value)}return n},kD={setConf:function(t){const e=Object.keys(t);for(const n of e)t[n]},getClasses:function(t,e){Bb.trace("Extracting classes"),e.db.clear();try{return e.parser.parse(t),e.db.extract(e.db.getRootDocV2()),e.db.getClasses()}catch(n){return n}},draw:function(t,e,n,i){Bb.info("Drawing state diagram (v2)",e),yD={};let r=i.db.getDirection();void 0===r&&(r="LR");const{securityLevel:a,state:s}=fv(),o=s.nodeSpacing||50,c=s.rankSpacing||50;Bb.info(i.db.getRootDocV2()),i.db.extract(i.db.getRootDocV2()),Bb.info(i.db.getRootDocV2());const l=i.db.getStates(),h=new Qf({multigraph:!0,compound:!0}).setGraph({rankdir:vD(i.db.getRootDocV2()),nodesep:o,ranksep:c,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));let u;_D(h,void 0,i.db.getRootDocV2(),l,i.db,!0),"sandbox"===a&&(u=Xo("#i"+e));const d=Xo("sandbox"===a?u.nodes()[0].contentDocument.body:"body"),p=d.select(`[id="${e}"]`),f=d.select("#"+e+" g");qT(f,h,["barb"],oD,e);rv.insertTitle(p,"statediagramTitleText",s.titleTopMargin,i.db.getDiagramTitle());const g=p.node().getBBox(),y=g.width+16,m=g.height+16;p.attr("class",oD);const b=p.node().getBBox();vv(p,m,y,s.useMaxWidth);const _=`${b.x-8} ${b.y-8} ${y} ${m}`;Bb.debug(`viewBox ${_}`),p.attr("viewBox",_);const x=document.querySelectorAll('[id="'+e+'"] .edgeLabel .label');for(const v of x){const t=v.getBBox(),e=document.createElementNS("http://www.w3.org/2000/svg",aD);e.setAttribute("rx",0),e.setAttribute("ry",0),e.setAttribute("width",t.width),e.setAttribute("height",t.height),v.insertBefore(e,v.firstChild)}}};var wD=function(){var t,e=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},n=[1,2],i=[1,5],r=[6,9,11,17,18,20,22,23,24,26],a=[1,15],s=[1,16],o=[1,17],c=[1,18],l=[1,19],h=[1,20],u=[1,24],d=[4,6,9,11,17,18,20,22,23,24,26],p={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,title:17,acc_title:18,acc_title_value:19,acc_descr:20,acc_descr_value:21,acc_descr_multiline_value:22,section:23,taskName:24,taskData:25,open_directive:26,type_directive:27,arg_directive:28,close_directive:29,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",17:"title",18:"acc_title",19:"acc_title_value",20:"acc_descr",21:"acc_descr_value",22:"acc_descr_multiline_value",23:"section",24:"taskName",25:"taskData",26:"open_directive",27:"type_directive",28:"arg_directive",29:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,2],[10,2],[10,1],[10,1],[10,2],[10,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,i,r,a,s){var o=a.length-1;switch(r){case 1:return a[o-1];case 3:case 7:case 8:this.$=[];break;case 4:a[o-1].push(a[o]),this.$=a[o-1];break;case 5:case 6:this.$=a[o];break;case 11:i.setDiagramTitle(a[o].substr(6)),this.$=a[o].substr(6);break;case 12:this.$=a[o].trim(),i.setAccTitle(this.$);break;case 13:case 14:this.$=a[o].trim(),i.setAccDescription(this.$);break;case 15:i.addSection(a[o].substr(8)),this.$=a[o].substr(8);break;case 16:i.addTask(a[o-1],a[o]),this.$="task";break;case 18:i.parseDirective("%%{","open_directive");break;case 19:i.parseDirective(a[o],"type_directive");break;case 20:a[o]=a[o].trim().replace(/'/g,'"'),i.parseDirective(a[o],"arg_directive");break;case 21:i.parseDirective("}%%","close_directive","journey")}},table:[{3:1,4:n,7:3,12:4,26:i},{1:[3]},e(r,[2,3],{5:6}),{3:7,4:n,7:3,12:4,26:i},{13:8,27:[1,9]},{27:[2,18]},{6:[1,10],7:21,8:11,9:[1,12],10:13,11:[1,14],12:4,17:a,18:s,20:o,22:c,23:l,24:h,26:i},{1:[2,2]},{14:22,15:[1,23],29:u},e([15,29],[2,19]),e(r,[2,8],{1:[2,1]}),e(r,[2,4]),{7:21,10:25,12:4,17:a,18:s,20:o,22:c,23:l,24:h,26:i},e(r,[2,6]),e(r,[2,7]),e(r,[2,11]),{19:[1,26]},{21:[1,27]},e(r,[2,14]),e(r,[2,15]),{25:[1,28]},e(r,[2,17]),{11:[1,29]},{16:30,28:[1,31]},{11:[2,21]},e(r,[2,5]),e(r,[2,12]),e(r,[2,13]),e(r,[2,16]),e(d,[2,9]),{14:32,29:u},{29:[2,20]},{11:[1,33]},e(d,[2,10])],defaultActions:{5:[2,18],7:[2,2],24:[2,21],31:[2,20]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],r=[null],a=[],s=this.table,o="",c=0,l=0,h=2,u=1,d=a.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;a.push(y);var m=p.options&&p.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,x,v,k,w,T,C,E,S={};;){if(x=n[n.length-1],this.defaultActions[x]?v=this.defaultActions[x]:(null==_&&(_=b()),v=s[x]&&s[x][_]),void 0===v||!v.length||!v[0]){var A="";for(w in E=[],s[x])this.terminals_[w]&&w>h&&E.push("'"+this.terminals_[w]+"'");A=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(A,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:y,expected:E})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+_);switch(v[0]){case 1:n.push(_),r.push(p.yytext),a.push(p.yylloc),n.push(v[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(T=this.productions_[v[1]][1],S.$=r[r.length-T],S._$={first_line:a[a.length-(T||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(T||1)].first_column,last_column:a[a.length-1].last_column},m&&(S._$.range=[a[a.length-(T||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(S,[o,l,c,f.yy,v[1],r,a].concat(d))))return k;T&&(n=n.slice(0,-1*T*2),r=r.slice(0,-1*T),a=a.slice(0,-1*T)),n.push(this.productions_[v[1]][0]),r.push(S.$),a.push(S._$),C=s[n[n.length-2]][n[n.length-1]],n.push(C);break;case 3:return!0}}return!0}},f=(t={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in r)this[a]=r[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),a=0;a<r.length;a++)if((n=this._input.match(this.rules[r[a]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,r[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),26;case 1:return this.begin("type_directive"),27;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),29;case 4:return 28;case 5:case 6:case 8:case 9:break;case 7:return 11;case 10:return 4;case 11:return 17;case 12:return this.begin("acc_title"),18;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),20;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:return 23;case 20:return 24;case 21:return 25;case 22:return 15;case 23:return 6;case 24:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,14,16,19,20,21,22,23,24],inclusive:!0}}},t);function g(){this.yy={}}return p.lexer=f,g.prototype=p,p.Parser=g,new g}();wD.parser=wD;const TD=wD,CD=t=>null!==t.match(/^\s*journey/);let ED="";const SD=[],AD=[],DD=[],LD=function(){let t=!0;for(const[e,n]of DD.entries())DD[e].processed,t=t&&n.processed;return t},ND={parseDirective:function(t,e,n){TL.parseDirective(this,t,e,n)},getConfig:()=>fv().journey,clear:function(){SD.length=0,AD.length=0,ED="",DD.length=0,Kv()},setDiagramTitle:ik,getDiagramTitle:rk,setAccTitle:Jv,getAccTitle:tk,setAccDescription:ek,getAccDescription:nk,addSection:function(t){ED=t,SD.push(t)},getSections:function(){return SD},getTasks:function(){let t=LD();let e=0;for(;!t&&e<100;)t=LD(),e++;return AD.push(...DD),AD},addTask:function(t,e){const n=e.substr(1).split(":");let i=0,r=[];1===n.length?(i=Number(n[0]),r=[]):(i=Number(n[0]),r=n[1].split(","));const a=r.map((t=>t.trim())),s={section:ED,type:ED,people:a,task:t,score:i};DD.push(s)},addTaskOrg:function(t){const e={section:ED,type:ED,description:t,task:t,classes:[]};AD.push(e)},getActors:function(){return function(){const t=[];return AD.forEach((e=>{e.people&&t.push(...e.people)})),[...new Set(t)].sort()}()}},OD=function(t,e){const n=t.append("rect");return n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),n.attr("rx",e.rx),n.attr("ry",e.ry),void 0!==e.class&&n.attr("class",e.class),n},BD=function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n},MD=function(t,e){const n=e.text.replace(/<br\s*\/?>/gi," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const r=i.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.text(n),i};let ID=-1;const FD=function(){return{x:0,y:0,width:100,anchor:"start",height:100,rx:0,ry:0}},RD=function(){function t(t,e,n,r,a,s,o,c){i(e.append("text").attr("x",n+a/2).attr("y",r+s/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,r,a,s,o,c,l){const{taskFontSize:h,taskFontFamily:u}=c,d=t.split(/<br\s*\/?>/gi);for(let p=0;p<d.length;p++){const t=p*h-h*(d.length-1)/2,c=e.append("text").attr("x",n+a/2).attr("y",r).attr("fill",l).style("text-anchor","middle").style("font-size",h).style("font-family",u);c.append("tspan").attr("x",n+a/2).attr("dy",t).text(d[p]),c.attr("y",r+s/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(c,o)}}function n(t,n,r,a,s,o,c,l){const h=n.append("switch"),u=h.append("foreignObject").attr("x",r).attr("y",a).attr("width",s).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");u.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,r,a,s,o,c,l),i(u,c)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}return function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),$D=BD,PD=function(t,e,n){const i=t.append("g"),r=FD();r.x=e.x,r.y=e.y,r.fill=e.fill,r.width=n.width,r.height=n.height,r.class="journey-section section-type-"+e.num,r.rx=3,r.ry=3,OD(i,r),RD(n)(e.text,i,r.x,r.y,r.width,r.height,{class:"journey-section section-type-"+e.num},n,e.colour)},jD=MD,YD=function(t,e,n){const i=e.x+n.width/2,r=t.append("g");ID++;r.append("line").attr("id","task"+ID).attr("x1",i).attr("y1",e.y).attr("x2",i).attr("y2",450).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),function(t,e){const n=15,i=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",n).attr("stroke-width",2).attr("overflow","visible"),r=t.append("g");r.append("circle").attr("cx",e.cx-5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),r.append("circle").attr("cx",e.cx+5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),e.score>3?function(t){const i=Cc().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}(r):e.score<3?function(t){const i=Cc().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}(r):r.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}(r,{cx:i,cy:300+30*(5-e.score),score:e.score});const a=FD();a.x=e.x,a.y=e.y,a.fill=e.fill,a.width=n.width,a.height=n.height,a.class="task task-type-"+e.num,a.rx=3,a.ry=3,OD(r,a);let s=e.x+14;e.people.forEach((t=>{const n=e.actors[t].color,i={cx:s,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};BD(r,i),s+=10})),RD(n)(e.task,r,a.x,a.y,a.width,a.height,{class:"task"},n,e.colour)},zD=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},UD={};const WD=fv().journey,HD=WD.leftMargin,qD={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},updateBounds:function(t,e,n,i){const r=fv().journey,a=this;let s=0;var o;this.sequenceItems.forEach((function(c){s++;const l=a.sequenceItems.length-s+1;a.updateVal(c,"starty",e-l*r.boxMargin,Math.min),a.updateVal(c,"stopy",i+l*r.boxMargin,Math.max),a.updateVal(qD.data,"startx",t-l*r.boxMargin,Math.min),a.updateVal(qD.data,"stopx",n+l*r.boxMargin,Math.max),"activation"!==o&&(a.updateVal(c,"startx",t-l*r.boxMargin,Math.min),a.updateVal(c,"stopx",n+l*r.boxMargin,Math.max),a.updateVal(qD.data,"starty",e-l*r.boxMargin,Math.min),a.updateVal(qD.data,"stopy",i+l*r.boxMargin,Math.max))}))},insert:function(t,e,n,i){const r=Math.min(t,n),a=Math.max(t,n),s=Math.min(e,i),o=Math.max(e,i);this.updateVal(qD.data,"startx",r,Math.min),this.updateVal(qD.data,"starty",s,Math.min),this.updateVal(qD.data,"stopx",a,Math.max),this.updateVal(qD.data,"stopy",o,Math.max),this.updateBounds(r,s,a,o)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},VD=WD.sectionFills,GD=WD.sectionColours,XD=function(t,e,n){const i=fv().journey;let r="";const a=n+(2*i.height+i.diagramMarginY);let s=0,o="#CCC",c="black",l=0;for(const[h,u]of e.entries()){if(r!==u.section){o=VD[s%VD.length],l=s%VD.length,c=GD[s%GD.length];const e={x:h*i.taskMargin+h*i.width+HD,y:50,text:u.section,fill:o,num:l,colour:c};PD(t,e,i),r=u.section,s++}const e=u.people.reduce(((t,e)=>(UD[e]&&(t[e]=UD[e]),t)),{});u.x=h*i.taskMargin+h*i.width+HD,u.y=a,u.width=i.diagramMarginX,u.height=i.diagramMarginY,u.colour=c,u.fill=o,u.num=l,u.actors=e,YD(t,u,i),qD.insert(u.x,u.y,u.x+u.width+i.taskMargin,450)}},ZD={setConf:function(t){Object.keys(t).forEach((function(e){WD[e]=t[e]}))},draw:function(t,e,n,i){const r=fv().journey;i.db.clear(),i.parser.parse(t+"\n");const a=fv().securityLevel;let s;"sandbox"===a&&(s=Xo("#i"+e));const o=Xo("sandbox"===a?s.nodes()[0].contentDocument.body:"body");qD.init();const c=o.select("#"+e);zD(c);const l=i.db.getTasks(),h=i.db.getDiagramTitle(),u=i.db.getActors();for(const m in UD)delete UD[m];let d=0;u.forEach((t=>{UD[t]={color:r.actorColours[d%r.actorColours.length],position:d},d++})),function(t){const e=fv().journey;let n=60;Object.keys(UD).forEach((i=>{const r=UD[i].color,a={cx:20,cy:n,r:7,fill:r,stroke:"#000",pos:UD[i].position};$D(t,a);const s={x:40,y:n+7,fill:"#666",text:i,textMargin:5|e.boxTextMargin};jD(t,s),n+=20}))}(c),qD.insert(0,0,HD,50*Object.keys(UD).length),XD(c,l,0);const p=qD.getBounds();h&&c.append("text").text(h).attr("x",HD).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const f=p.stopy-p.starty+2*r.diagramMarginY,g=HD+p.stopx+2*r.diagramMarginX;vv(c,f,g,r.useMaxWidth),c.append("line").attr("x1",HD).attr("y1",4*r.height).attr("x2",g-HD-4).attr("y2",4*r.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const y=h?70:0;c.attr("viewBox",`${p.startx} -25 ${g} ${f+y}`),c.attr("preserveAspectRatio","xMinYMin meet"),c.attr("height",f+y+25)}};let QD={};const KD={setConf:function(t){QD={...QD,...t}},draw:(t,e,n)=>{try{Bb.debug("Renering svg for syntax error\n");const t=Xo("#"+e),i=t.append("g");i.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),i.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),i.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),i.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),i.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),i.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),i.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in graph"),i.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text("mermaid version "+n),t.attr("height",100),t.attr("width",500),t.attr("viewBox","768 0 912 512")}catch(r){Bb.error("Error while rendering info diagram"),Bb.error((i=r)instanceof Error?i.message:String(i))}var i}};let JD=!1;const tL=()=>{JD||(JD=!0,Uv("error",{db:{clear:()=>{}},styles:Cv,renderer:KD,parser:{parser:{yy:{}},parse:()=>{}},init:()=>{}},(t=>"error"===t.toLowerCase().trim())),Uv("c4",{parser:Pk,db:tw,renderer:Ow,styles:Mv,init:t=>{Ow.setConf(t.c4)}},jk),Uv("class",{parser:Mw,db:Kw,renderer:uT,styles:wv,init:t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute,Kw.clear()}},Iw),Uv("classDiagram",{parser:Mw,db:Kw,renderer:ZT,styles:wv,init:t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute,Kw.clear()}},Fw),Uv("er",{parser:KT,db:iC,renderer:fC,styles:Tv},JT),Uv("gantt",{parser:QC,db:LE,renderer:BE,styles:Sv},KC),Uv("info",{parser:IE,db:$E,renderer:PE,styles:Av},jE),Uv("pie",{parser:zE,db:qE,renderer:ZE,styles:Dv},UE),Uv("requirement",{parser:KE,db:aS,renderer:yS,styles:Lv},JE),Uv("sequence",{parser:bS,db:RS,renderer:fA,styles:Nv,init:t=>{if(t.sequence||(t.sequence={}),t.sequence.arrowMarkerAbsolute=t.arrowMarkerAbsolute,"sequenceDiagram"in t)throw new Error("`mermaid config.sequenceDiagram` has been renamed to `config.sequence`. Please update your mermaid config.");RS.setWrap(t.wrap),fA.setConf(t.sequence)}},_S),Uv("state",{parser:yA,db:VA,renderer:rD,styles:Ov,init:t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,VA.clear()}},mA),Uv("stateDiagram",{parser:yA,db:VA,renderer:kD,styles:Ov,init:t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,VA.clear()}},bA),Uv("journey",{parser:TD,db:ND,renderer:ZD,styles:Bv,init:t=>{ZD.setConf(t.journey),ND.clear()}},CD),Uv("flowchart",{parser:yC,db:UC,renderer:XC,styles:Ev,init:t=>{t.flowchart||(t.flowchart={}),t.flowchart.arrowMarkerAbsolute=t.arrowMarkerAbsolute,HC(t.flowchart),UC.clear(),UC.setGen("gen-1")}},mC),Uv("flowchart-v2",{parser:yC,db:UC,renderer:XC,styles:Ev,init:t=>{t.flowchart||(t.flowchart={}),t.flowchart.arrowMarkerAbsolute=t.arrowMarkerAbsolute,pv({flowchart:{arrowMarkerAbsolute:t.arrowMarkerAbsolute}}),XC.setConf(t.flowchart),UC.clear(),UC.setGen("gen-2")}},bC),Uv("gitGraph",{parser:qv,db:vk,renderer:Fk,styles:Rk},Vv))};class eL{constructor(t,e){var n,i;Nb(this,"type","graph"),Nb(this,"parser"),Nb(this,"renderer"),Nb(this,"db"),Nb(this,"detectTypeFailed",!1),this.txt=t;const r=fv();this.txt=t;try{this.type=Mx(t,r)}catch(o){this.handleError(o,e),this.type="error",this.detectTypeFailed=!0}const a=Wv(this.type);Bb.debug("Type "+this.type),this.db=a.db,null==(i=(n=this.db).clear)||i.call(n),this.renderer=a.renderer,this.parser=a.parser;const s=this.parser.parse.bind(this.parser);this.parser.parse=t=>s(function(t,e){var n;const i=t.match(Lx);if(i){const r=Dx(i[1],{schema:Ax});return(null==r?void 0:r.title)&&(null==(n=e.setDiagramTitle)||n.call(e,r.title)),t.slice(i[0].length)}return t}(t,this.db)),this.parser.parser.yy=this.db,a.init&&(a.init(r),Bb.debug("Initialized diagram "+this.type,r)),this.txt+="\n",this.parse(this.txt,e)}parse(t,e){var n,i;if(this.detectTypeFailed)return!1;try{return t+="\n",null==(i=(n=this.db).clear)||i.call(n),this.parser.parse(t),!0}catch(r){this.handleError(r,e)}return!1}handleError(t,e){if(void 0===e)throw t;iv(t)?e(t.str,t.hash):e(t)}getParser(){return this.parser}getType(){return this.type}}const nL=(t,e)=>{const n=Mx(t,fv());try{Wv(n)}catch(i){const r=Bx[n].loader;if(!r)throw new Error(`Diagram ${n} not found.`);return r().then((({diagram:i})=>(Uv(n,i,void 0),new eL(t,e))))}return new eL(t,e)},iL=eL;const rL=["graph","flowchart","flowchart-v2","stateDiagram","stateDiagram-v2"],aL="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa",sL="sandbox",oL="loose",cL="http://www.w3.org/1999/xlink",lL="http://www.w3.org/1999/xhtml",hL=["foreignobject"],uL=["dominant-baseline"];const dL=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/#\w+;/g,(function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"\ufb02\xb0\xb0"+e+"\xb6\xdf":"\ufb02\xb0"+e+"\xb6\xdf"})),e},pL=function(t){let e=t;return e=e.replace(/\ufb02\xb0\xb0/g,"&#"),e=e.replace(/\ufb02\xb0/g,"&"),e=e.replace(/\xb6\xdf/g,";"),e},fL=(t,e,n=[])=>`\n.${t} ${e} { ${n.join(" !important; ")} !important; }`,gL=(t,e,n,i)=>{const r=((t,e,n={})=>{var i;let r="";if(void 0!==t.themeCSS&&(r+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(r+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(r+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),!kf(n)&&rL.includes(e)){const e=["> *","span"],a=["rect","polygon","ellipse","circle","path"],s=t.htmlLabels||(null==(i=t.flowchart)?void 0:i.htmlLabels)?e:a;for(const t in n){const e=n[t];kf(e.styles)||s.forEach((t=>{r+=fL(e.id,t,e.styles)})),kf(e.textStyles)||(r+=fL(e.id,"tspan",e.textStyles))}}return r})(t,e,n);return Xh(bu(`${i}{${Fv(e,r,t.themeVariables)}}`),Zh)},yL=(t="",e,n)=>{let i=t;return n||e||(i=i.replace(/marker-end="url\(.*?#/g,'marker-end="url(#')),i=pL(i),i=i.replace(/<br>/g,"<br/>"),i},mL=(t="",e)=>`<iframe style="width:100%;height:${e?e.viewBox.baseVal.height+"px":"100%"};border:0;margin:0;" src="data:text/html;base64,${btoa('<body style="margin:0">'+t+"</body>")}" sandbox="allow-top-navigation-by-user-activation allow-popups">\n The "iframe" tag is not supported by your browser.\n</iframe>`,bL=(t,e,n,i,r)=>{const a=t.append("div");a.attr("id",n),i&&a.attr("style",i);const s=a.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return r&&s.attr("xmlns:xlink",r),s.append("g"),t};function _L(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}const xL=(t,e,n,i)=>{var r,a,s;null==(r=t.getElementById(e))||r.remove(),null==(a=t.getElementById(n))||a.remove(),null==(s=t.getElementById(i))||s.remove()};let vL={};const kL=function(t,e,n){switch(Bb.debug(`Directive type=${e.type} with args:`,e.args),e.type){case"init":case"initialize":["config"].forEach((t=>{void 0!==e.args[t]&&("flowchart-v2"===n&&(n="flowchart"),e.args[n]=e.args[t],delete e.args[t])})),Bb.debug("sanitize in handleDirective",e.args),ev(e.args),Bb.debug("sanitize in handleDirective (done)",e.args),yv(e.args);break;case"wrap":case"nowrap":t&&t.setWrap&&t.setWrap("wrap"===e.type);break;case"themeCss":Bb.warn("themeCss encountered");break;default:Bb.warn(`Unhandled directive: source: '%%{${e.type}: ${JSON.stringify(e.args?e.args:{})}}%%`,e)}};function wL(t,e,n,i){!function(t,e){kf(e)||t.attr("aria-roledescription",e)}(e,t),function(t,e,n,i){if(void 0!==t.insert&&(e||n)){if(n){const e="chart-desc-"+i;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(n)}if(e){const n="chart-title-"+i;t.attr("aria-labelledby",n),t.insert("title",":first-child").attr("id",n).text(e)}}}(e,n,i,e.attr("id"))}const TL=Object.freeze({render:function(t,e,n,i){var r,a,s,o,c;tL(),mv();const l=rv.detectInit(e);l&&(ev(l),yv(l));const h=fv();Bb.debug(h),e.length>(null!=(r=null==h?void 0:h.maxTextSize)?r:5e4)&&(e=aL),e=e.replace(/\r\n?/g,"\n");const u="#"+t,d="i"+t,p="#"+d,f="d"+t,g="#"+f;let y=Xo("body");const m=h.securityLevel===sL,b=h.securityLevel===oL,_=h.fontFamily;if(void 0!==i){if(i&&(i.innerHTML=""),m){const t=_L(Xo(i),d);y=Xo(t.nodes()[0].contentDocument.body),y.node().style.margin=0}else y=Xo(i);bL(y,t,f,`font-family: ${_}`,cL)}else{if(xL(document,t,f,d),m){const t=_L(Xo("body"),d);y=Xo(t.nodes()[0].contentDocument.body),y.node().style.margin=0}else y=Xo("body");bL(y,t,f)}let x,v;e=dL(e);try{if(x=nL(e),"then"in x)throw new Error("Diagram is a promise. Use renderAsync.")}catch(N){x=new iL("error"),v=N}const k=y.select(g).node(),w=x.type,T=k.firstChild,C=T.firstChild,E=rL.includes(w)?x.renderer.getClasses(e,x):{},S=gL(h,w,E,u),A=document.createElement("style");A.innerHTML=S,T.insertBefore(A,C);try{x.renderer.draw(e,t,av,x)}catch(O){throw KD.draw(e,t,av),O}wL(w,y.select(`${g} svg`),null==(s=(a=x.db).getAccTitle)?void 0:s.call(a),null==(c=(o=x.db).getAccDescription)?void 0:c.call(o)),y.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns",lL);let D=y.select(g).node().innerHTML;if(Bb.debug("config.arrowMarkerAbsolute",h.arrowMarkerAbsolute),D=yL(D,m,zb(h.arrowMarkerAbsolute)),m){const t=y.select(g+" svg").node();D=mL(D,t)}else b||(D=Kc.sanitize(D,{ADD_TAGS:hL,ADD_ATTR:uL}));if(void 0!==n)switch(w){case"flowchart":case"flowchart-v2":n(D,UC.bindFunctions);break;case"gantt":n(D,LE.bindFunctions);break;case"class":case"classDiagram":n(D,Kw.bindFunctions);break;default:n(D)}else Bb.debug("CB = undefined!");PS();const L=Xo(m?p:g).node();if(L&&"remove"in L&&L.remove(),v)throw v;return D},renderAsync:async function(t,e,n,i){var r,a,s,o,c;tL(),mv();const l=rv.detectInit(e);l&&(ev(l),yv(l));const h=fv();Bb.debug(h),e.length>(null!=(r=null==h?void 0:h.maxTextSize)?r:5e4)&&(e=aL),e=e.replace(/\r\n?/g,"\n");const u="#"+t,d="i"+t,p="#"+d,f="d"+t,g="#"+f;let y=Xo("body");const m=h.securityLevel===sL,b=h.securityLevel===oL,_=h.fontFamily;if(void 0!==i){if(i&&(i.innerHTML=""),m){const t=_L(Xo(i),d);y=Xo(t.nodes()[0].contentDocument.body),y.node().style.margin=0}else y=Xo(i);bL(y,t,f,`font-family: ${_}`,cL)}else{if(xL(document,t,f,d),m){const t=_L(Xo("body"),d);y=Xo(t.nodes()[0].contentDocument.body),y.node().style.margin=0}else y=Xo("body");bL(y,t,f)}let x,v;e=dL(e);try{x=await nL(e)}catch(N){x=new iL("error"),v=N}const k=y.select(g).node(),w=x.type,T=k.firstChild,C=T.firstChild,E=rL.includes(w)?x.renderer.getClasses(e,x):{},S=gL(h,w,E,u),A=document.createElement("style");A.innerHTML=S,T.insertBefore(A,C);try{await x.renderer.draw(e,t,av,x)}catch(O){throw KD.draw(e,t,av),O}wL(w,y.select(`${g} svg`),null==(s=(a=x.db).getAccTitle)?void 0:s.call(a),null==(c=(o=x.db).getAccDescription)?void 0:c.call(o)),y.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns",lL);let D=y.select(g).node().innerHTML;if(Bb.debug("config.arrowMarkerAbsolute",h.arrowMarkerAbsolute),D=yL(D,m,zb(h.arrowMarkerAbsolute)),m){const t=y.select(g+" svg").node();D=mL(D,t)}else b||(D=Kc.sanitize(D,{ADD_TAGS:hL,ADD_ATTR:uL}));if(void 0!==n)switch(w){case"flowchart":case"flowchart-v2":n(D,UC.bindFunctions);break;case"gantt":n(D,LE.bindFunctions);break;case"class":case"classDiagram":n(D,Kw.bindFunctions);break;default:n(D)}else Bb.debug("CB = undefined!");PS();const L=Xo(m?p:g).node();if(L&&"remove"in L&&L.remove(),v)throw v;return D},parse:function(t,e){return tL(),new iL(t,e).parse(t,e)},parseAsync:async function(t,e){return tL(),(await nL(t,e)).parse(t,e)},parseDirective:function(t,e,n,i){try{if(void 0!==e)switch(e=e.trim(),n){case"open_directive":vL={};break;case"type_directive":if(!vL)throw new Error("currentDirective is undefined");vL.type=e.toLowerCase();break;case"arg_directive":if(!vL)throw new Error("currentDirective is undefined");vL.args=JSON.parse(e);break;case"close_directive":kL(t,vL,i),vL=void 0}}catch(r){Bb.error(`Error while rendering sequenceDiagram directive: ${e} jison context: ${n}`),Bb.error(r.message)}},initialize:function(t={}){var e;(null==t?void 0:t.fontFamily)&&!(null==(e=t.themeVariables)?void 0:e.fontFamily)&&(t.themeVariables={fontFamily:t.fontFamily}),ov=Rx({},t),(null==t?void 0:t.theme)&&t.theme in Jb?t.themeVariables=Jb[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=Jb.default.getThemeVariables(t.themeVariables));const n="object"==typeof t?(t=>(cv=Rx({},sv),cv=Rx(cv,t),t.theme&&Jb[t.theme]&&(cv.themeVariables=Jb[t.theme].getThemeVariables(t.themeVariables)),uv(cv,lv),cv))(t):dv();Mb(n.logLevel),tL()},getConfig:fv,setConfig:pv,getSiteConfig:dv,updateSiteConfig:t=>(cv=Rx(cv,t),uv(cv,lv),cv),reset:()=>{mv()},globalReset:()=>{mv(sv)},defaultConfig:sv});Mb(fv().logLevel),mv(fv());let CL=!1;const EL=(t,e,n)=>{Bb.warn(t),iv(t)?(n&&n(t.str,t.hash),e.push({...t,message:t.str,error:t})):(n&&n(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},SL=function(t,e,n){const i=TL.getConfig();let r;if(t&&(BL.sequenceConfig=t),Bb.debug((n?"":"No ")+"Callback function found"),void 0===e)r=document.querySelectorAll(".mermaid");else if("string"==typeof e)r=document.querySelectorAll(e);else if(e instanceof HTMLElement)r=[e];else{if(!(e instanceof NodeList))throw new Error("Invalid argument nodes for mermaid.init");r=e}Bb.debug(`Found ${r.length} diagrams`),void 0!==(null==t?void 0:t.startOnLoad)&&(Bb.debug("Start On Load: "+(null==t?void 0:t.startOnLoad)),TL.updateSiteConfig({startOnLoad:null==t?void 0:t.startOnLoad}));const a=new rv.initIdGenerator(i.deterministicIds,i.deterministicIDSeed);let s;const o=[];for(const l of Array.from(r)){if(Bb.info("Rendering diagram: "+l.id),l.getAttribute("data-processed"))continue;l.setAttribute("data-processed","true");const t=`mermaid-${a.next()}`;s=l.innerHTML,s=rv.entityDecode(s).trim().replace(/<br\s*\/?>/gi,"<br/>");const e=rv.detectInit(s);e&&Bb.debug("Detected early reinit: ",e);try{TL.render(t,s,((e,i)=>{l.innerHTML=e,void 0!==n&&n(t),i&&i(l)}),l)}catch(c){EL(c,o,BL.parseError)}}if(o.length>0)throw o[0]},AL=async function(t,e,n){const i=TL.getConfig();let r;if(t&&(BL.sequenceConfig=t),Bb.debug((n?"":"No ")+"Callback function found"),void 0===e)r=document.querySelectorAll(".mermaid");else if("string"==typeof e)r=document.querySelectorAll(e);else if(e instanceof HTMLElement)r=[e];else{if(!(e instanceof NodeList))throw new Error("Invalid argument nodes for mermaid.init");r=e}Bb.debug(`Found ${r.length} diagrams`),void 0!==(null==t?void 0:t.startOnLoad)&&(Bb.debug("Start On Load: "+(null==t?void 0:t.startOnLoad)),TL.updateSiteConfig({startOnLoad:null==t?void 0:t.startOnLoad}));const a=new rv.initIdGenerator(i.deterministicIds,i.deterministicIDSeed);let s;const o=[];for(const l of Array.from(r)){if(Bb.info("Rendering diagram: "+l.id),l.getAttribute("data-processed"))continue;l.setAttribute("data-processed","true");const t=`mermaid-${a.next()}`;s=l.innerHTML,s=rv.entityDecode(s).trim().replace(/<br\s*\/?>/gi,"<br/>");const e=rv.detectInit(s);e&&Bb.debug("Detected early reinit: ",e);try{await TL.renderAsync(t,s,((e,i)=>{l.innerHTML=e,void 0!==n&&n(t),i&&i(l)}),l)}catch(c){EL(c,o,BL.parseError)}}if(o.length>0)throw o[0]},DL=function(){if(BL.startOnLoad){const{startOnLoad:t}=TL.getConfig();t&&BL.init()}};"undefined"!=typeof document&&window.addEventListener("load",DL,!1);const LL=[];let NL=!1;const OL=async()=>{if(!NL){for(NL=!0;LL.length>0;){const e=LL.shift();if(e)try{await e()}catch(t){Bb.error("Error executing queue",t)}}NL=!1}},BL={startOnLoad:!0,diagrams:{},mermaidAPI:TL,parse:t=>TL.parse(t,BL.parseError),parseAsync:t=>new Promise(((e,n)=>{LL.push((()=>new Promise(((i,r)=>{TL.parseAsync(t,BL.parseError).then((t=>{i(t),e(t)}),(t=>{Bb.error("Error parsing",t),r(t),n(t)}))})))),OL()})),render:TL.render,renderAsync:(t,e,n,i)=>new Promise(((r,a)=>{LL.push((()=>new Promise(((s,o)=>{TL.renderAsync(t,e,n,i).then((t=>{s(t),r(t)}),(t=>{Bb.error("Error parsing",t),o(t),a(t)}))})))),OL()})),init:async function(t,e,n){try{CL?await AL(t,e,n):SL(t,e,n)}catch(i){Bb.warn("Syntax Error rendering"),iv(i)&&Bb.warn(i.str),BL.parseError&&BL.parseError(i)}},initThrowsErrors:SL,initThrowsErrorsAsync:AL,registerExternalDiagrams:async(t,{lazyLoad:e=!0}={})=>{e?(t=>{for(const{id:e,detector:n,loader:i}of t)Ix(e,n,i)})(t):await(async t=>{Bb.debug(`Loading ${t.length} external diagrams`);const e=await Promise.allSettled(t.map((async({id:t,detector:e,loader:n})=>{const{diagram:i}=await n();Uv(t,i,e)}))),n=e.filter((t=>"rejected"===t.status));if(n.length>0){Bb.error(`Failed to load ${n.length} external diagrams`);for(const t of n)Bb.error(t);throw new Error(`Failed to load ${n.length} external diagrams`)}})(t),CL=!0},initialize:function(t){TL.initialize(t)},parseError:void 0,contentLoaded:DL,setParseErrorHandler:function(t){BL.parseError=t}};function ML(){const{colorMode:t}=(0,h.I)(),e=(0,u.L)().mermaid,n=e.theme[t],{options:r}=e;return(0,i.useMemo)((()=>({startOnLoad:!1,...r,theme:n})),[n,r])}const IL="container_lyt7";function FL(t){let{value:e}=t;const n=function(t,e){const n=ML(),r=e??n;return(0,i.useMemo)((()=>{BL.mermaidAPI.initialize(r);const e=`mermaid-svg-${Math.round(1e7*Math.random())}`;return BL.render(e,t)}),[t,r])}(e);return i.createElement("div",{className:`docusaurus-mermaid-container ${IL}`,dangerouslySetInnerHTML:{__html:n}})}const RL={head:function(t){const e=i.Children.map(t.children,(t=>i.isValidElement(t)?function(t){if(t.props?.mdxType&&t.props.originalType){const{mdxType:e,originalType:n,...r}=t.props;return i.createElement(t.props.originalType,r)}return t}(t):t));return i.createElement(s.Z,t,e)},code:function(t){const e=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return i.Children.toArray(t.children).every((t=>"string"==typeof t&&!t.includes("\n")||(0,i.isValidElement)(t)&&e.includes(t.props?.mdxType)))?i.createElement("code",t):i.createElement(J,t)},a:function(t){return i.createElement(tt.Z,t)},pre:function(t){return i.createElement(J,(0,i.isValidElement)(t.children)&&"code"===t.children.props?.originalType?t.children.props:{...t})},details:function(t){const e=i.Children.toArray(t.children),n=e.find((t=>i.isValidElement(t)&&"summary"===t.props?.mdxType)),r=i.createElement(i.Fragment,null,e.filter((t=>t!==n)));return i.createElement(lt,(0,a.Z)({},t,{summary:n}),r)},ul:function(t){return i.createElement("ul",(0,a.Z)({},t,{className:pt(t.className)}))},img:function(t){return i.createElement("img",(0,a.Z)({loading:"lazy"},t,{className:(e=t.className,(0,l.Z)(e,ft))}));var e},h1:t=>i.createElement(ut,(0,a.Z)({as:"h1"},t)),h2:t=>i.createElement(ut,(0,a.Z)({as:"h2"},t)),h3:t=>i.createElement(ut,(0,a.Z)({as:"h3"},t)),h4:t=>i.createElement(ut,(0,a.Z)({as:"h4"},t)),h5:t=>i.createElement(ut,(0,a.Z)({as:"h5"},t)),h6:t=>i.createElement(ut,(0,a.Z)({as:"h6"},t)),admonition:function(t){const{children:e,type:n,title:r,icon:a}=vt(t),s=function(t){const e=xt[t]??t;return _t[e]||(console.warn(`No admonition config found for admonition type "${e}". Using Info as fallback.`),_t.info)}(n),o=r??s.label,{iconComponent:c}=s,h=a??i.createElement(c,null);return i.createElement("div",{className:(0,l.Z)(p.k.common.admonition,p.k.common.admonitionType(t.type),"alert",`alert--${s.infimaClassName}`,gt)},i.createElement("div",{className:yt},i.createElement("span",{className:mt},h),o),i.createElement("div",{className:bt},e))},mermaid:function(t){return i.createElement(kt,null,(()=>i.createElement(FL,t)))}},$L=RL;function PL(t){let{children:e}=t;return i.createElement(r.Zo,{components:$L},e)}},32244:(t,e,n)=>{"use strict";n.d(e,{Z:()=>s});var i=n(67294),r=n(86010),a=n(39960);function s(t){const{permalink:e,title:n,subLabel:s,isNext:o}=t;return i.createElement(a.Z,{className:(0,r.Z)("pagination-nav__link",o?"pagination-nav__link--next":"pagination-nav__link--prev"),to:e},s&&i.createElement("div",{className:"pagination-nav__sublabel"},s),i.createElement("div",{className:"pagination-nav__label"},n))}},13008:(t,e,n)=>{"use strict";n.d(e,{Z:()=>l});var i=n(67294),r=n(86010),a=n(39960);const s="tag_zVej",o="tagRegular_sFm0",c="tagWithCount_h2kH";function l(t){let{permalink:e,label:n,count:l}=t;return i.createElement(a.Z,{href:e,className:(0,r.Z)(s,l?c:o)},n,l&&i.createElement("span",null,l))}},71526:(t,e,n)=>{"use strict";n.d(e,{Z:()=>l});var i=n(67294),r=n(86010),a=n(95999),s=n(13008);const o="tags_jXut",c="tag_QGVx";function l(t){let{tags:e}=t;return i.createElement(i.Fragment,null,i.createElement("b",null,i.createElement(a.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list"},"Tags:")),i.createElement("ul",{className:(0,r.Z)(o,"padding--none","margin-left--sm")},e.map((t=>{let{label:e,permalink:n}=t;return i.createElement("li",{key:n,className:c},i.createElement(s.Z,{label:e,permalink:n}))}))))}},27856:function(t){t.exports=function(){"use strict";function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,n){return e=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},e(t,n)}function n(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}function i(t,r,a){return i=n()?Reflect.construct:function(t,n,i){var r=[null];r.push.apply(r,n);var a=new(Function.bind.apply(t,r));return i&&e(a,i.prototype),a},i.apply(null,arguments)}function r(t){return a(t)||s(t)||o(t)||l()}function a(t){if(Array.isArray(t))return c(t)}function s(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}function o(t,e){if(t){if("string"==typeof t)return c(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(t,e):void 0}}function c(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,i=new Array(e);n<e;n++)i[n]=t[n];return i}function l(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var h=Object.hasOwnProperty,u=Object.setPrototypeOf,d=Object.isFrozen,p=Object.getPrototypeOf,f=Object.getOwnPropertyDescriptor,g=Object.freeze,y=Object.seal,m=Object.create,b="undefined"!=typeof Reflect&&Reflect,_=b.apply,x=b.construct;_||(_=function(t,e,n){return t.apply(e,n)}),g||(g=function(t){return t}),y||(y=function(t){return t}),x||(x=function(t,e){return i(t,r(e))});var v=O(Array.prototype.forEach),k=O(Array.prototype.pop),w=O(Array.prototype.push),T=O(String.prototype.toLowerCase),C=O(String.prototype.toString),E=O(String.prototype.match),S=O(String.prototype.replace),A=O(String.prototype.indexOf),D=O(String.prototype.trim),L=O(RegExp.prototype.test),N=B(TypeError);function O(t){return function(e){for(var n=arguments.length,i=new Array(n>1?n-1:0),r=1;r<n;r++)i[r-1]=arguments[r];return _(t,e,i)}}function B(t){return function(){for(var e=arguments.length,n=new Array(e),i=0;i<e;i++)n[i]=arguments[i];return x(t,n)}}function M(t,e,n){n=n||T,u&&u(t,null);for(var i=e.length;i--;){var r=e[i];if("string"==typeof r){var a=n(r);a!==r&&(d(e)||(e[i]=a),r=a)}t[r]=!0}return t}function I(t){var e,n=m(null);for(e in t)_(h,t,[e])&&(n[e]=t[e]);return n}function F(t,e){for(;null!==t;){var n=f(t,e);if(n){if(n.get)return O(n.get);if("function"==typeof n.value)return O(n.value)}t=p(t)}function i(t){return console.warn("fallback value for",t),null}return i}var R=g(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),$=g(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),P=g(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),j=g(["animate","color-profile","cursor","discard","fedropshadow","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),Y=g(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover"]),z=g(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),U=g(["#text"]),W=g(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","xmlns","slot"]),H=g(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),q=g(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),V=g(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),G=y(/\{\{[\w\W]*|[\w\W]*\}\}/gm),X=y(/<%[\w\W]*|[\w\W]*%>/gm),Z=y(/\${[\w\W]*}/gm),Q=y(/^data-[\-\w.\u00B7-\uFFFF]/),K=y(/^aria-[\-\w]+$/),J=y(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),tt=y(/^(?:\w+script|data):/i),et=y(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),nt=y(/^html$/i),it=function(){return"undefined"==typeof window?null:window},rt=function(e,n){if("object"!==t(e)||"function"!=typeof e.createPolicy)return null;var i=null,r="data-tt-policy-suffix";n.currentScript&&n.currentScript.hasAttribute(r)&&(i=n.currentScript.getAttribute(r));var a="dompurify"+(i?"#"+i:"");try{return e.createPolicy(a,{createHTML:function(t){return t},createScriptURL:function(t){return t}})}catch(s){return console.warn("TrustedTypes policy "+a+" could not be created."),null}};function at(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:it(),n=function(t){return at(t)};if(n.version="2.4.1",n.removed=[],!e||!e.document||9!==e.document.nodeType)return n.isSupported=!1,n;var i=e.document,a=e.document,s=e.DocumentFragment,o=e.HTMLTemplateElement,c=e.Node,l=e.Element,h=e.NodeFilter,u=e.NamedNodeMap,d=void 0===u?e.NamedNodeMap||e.MozNamedAttrMap:u,p=e.HTMLFormElement,f=e.DOMParser,y=e.trustedTypes,m=l.prototype,b=F(m,"cloneNode"),_=F(m,"nextSibling"),x=F(m,"childNodes"),O=F(m,"parentNode");if("function"==typeof o){var B=a.createElement("template");B.content&&B.content.ownerDocument&&(a=B.content.ownerDocument)}var st=rt(y,i),ot=st?st.createHTML(""):"",ct=a,lt=ct.implementation,ht=ct.createNodeIterator,ut=ct.createDocumentFragment,dt=ct.getElementsByTagName,pt=i.importNode,ft={};try{ft=I(a).documentMode?a.documentMode:{}}catch(Oe){}var gt={};n.isSupported="function"==typeof O&<&&void 0!==lt.createHTMLDocument&&9!==ft;var yt,mt,bt=G,_t=X,xt=Z,vt=Q,kt=K,wt=tt,Tt=et,Ct=J,Et=null,St=M({},[].concat(r(R),r($),r(P),r(Y),r(U))),At=null,Dt=M({},[].concat(r(W),r(H),r(q),r(V))),Lt=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Nt=null,Ot=null,Bt=!0,Mt=!0,It=!1,Ft=!1,Rt=!1,$t=!1,Pt=!1,jt=!1,Yt=!1,zt=!1,Ut=!0,Wt=!1,Ht="user-content-",qt=!0,Vt=!1,Gt={},Xt=null,Zt=M({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),Qt=null,Kt=M({},["audio","video","img","source","image","track"]),Jt=null,te=M({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),ee="http://www.w3.org/1998/Math/MathML",ne="http://www.w3.org/2000/svg",ie="http://www.w3.org/1999/xhtml",re=ie,ae=!1,se=null,oe=M({},[ee,ne,ie],C),ce=["application/xhtml+xml","text/html"],le="text/html",he=null,ue=a.createElement("form"),de=function(t){return t instanceof RegExp||t instanceof Function},pe=function(e){he&&he===e||(e&&"object"===t(e)||(e={}),e=I(e),yt=yt=-1===ce.indexOf(e.PARSER_MEDIA_TYPE)?le:e.PARSER_MEDIA_TYPE,mt="application/xhtml+xml"===yt?C:T,Et="ALLOWED_TAGS"in e?M({},e.ALLOWED_TAGS,mt):St,At="ALLOWED_ATTR"in e?M({},e.ALLOWED_ATTR,mt):Dt,se="ALLOWED_NAMESPACES"in e?M({},e.ALLOWED_NAMESPACES,C):oe,Jt="ADD_URI_SAFE_ATTR"in e?M(I(te),e.ADD_URI_SAFE_ATTR,mt):te,Qt="ADD_DATA_URI_TAGS"in e?M(I(Kt),e.ADD_DATA_URI_TAGS,mt):Kt,Xt="FORBID_CONTENTS"in e?M({},e.FORBID_CONTENTS,mt):Zt,Nt="FORBID_TAGS"in e?M({},e.FORBID_TAGS,mt):{},Ot="FORBID_ATTR"in e?M({},e.FORBID_ATTR,mt):{},Gt="USE_PROFILES"in e&&e.USE_PROFILES,Bt=!1!==e.ALLOW_ARIA_ATTR,Mt=!1!==e.ALLOW_DATA_ATTR,It=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Ft=e.SAFE_FOR_TEMPLATES||!1,Rt=e.WHOLE_DOCUMENT||!1,jt=e.RETURN_DOM||!1,Yt=e.RETURN_DOM_FRAGMENT||!1,zt=e.RETURN_TRUSTED_TYPE||!1,Pt=e.FORCE_BODY||!1,Ut=!1!==e.SANITIZE_DOM,Wt=e.SANITIZE_NAMED_PROPS||!1,qt=!1!==e.KEEP_CONTENT,Vt=e.IN_PLACE||!1,Ct=e.ALLOWED_URI_REGEXP||Ct,re=e.NAMESPACE||ie,e.CUSTOM_ELEMENT_HANDLING&&de(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Lt.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&de(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Lt.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Lt.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Ft&&(Mt=!1),Yt&&(jt=!0),Gt&&(Et=M({},r(U)),At=[],!0===Gt.html&&(M(Et,R),M(At,W)),!0===Gt.svg&&(M(Et,$),M(At,H),M(At,V)),!0===Gt.svgFilters&&(M(Et,P),M(At,H),M(At,V)),!0===Gt.mathMl&&(M(Et,Y),M(At,q),M(At,V))),e.ADD_TAGS&&(Et===St&&(Et=I(Et)),M(Et,e.ADD_TAGS,mt)),e.ADD_ATTR&&(At===Dt&&(At=I(At)),M(At,e.ADD_ATTR,mt)),e.ADD_URI_SAFE_ATTR&&M(Jt,e.ADD_URI_SAFE_ATTR,mt),e.FORBID_CONTENTS&&(Xt===Zt&&(Xt=I(Xt)),M(Xt,e.FORBID_CONTENTS,mt)),qt&&(Et["#text"]=!0),Rt&&M(Et,["html","head","body"]),Et.table&&(M(Et,["tbody"]),delete Nt.tbody),g&&g(e),he=e)},fe=M({},["mi","mo","mn","ms","mtext"]),ge=M({},["foreignobject","desc","title","annotation-xml"]),ye=M({},["title","style","font","a","script"]),me=M({},$);M(me,P),M(me,j);var be=M({},Y);M(be,z);var _e=function(t){var e=O(t);e&&e.tagName||(e={namespaceURI:re,tagName:"template"});var n=T(t.tagName),i=T(e.tagName);return!!se[t.namespaceURI]&&(t.namespaceURI===ne?e.namespaceURI===ie?"svg"===n:e.namespaceURI===ee?"svg"===n&&("annotation-xml"===i||fe[i]):Boolean(me[n]):t.namespaceURI===ee?e.namespaceURI===ie?"math"===n:e.namespaceURI===ne?"math"===n&&ge[i]:Boolean(be[n]):t.namespaceURI===ie?!(e.namespaceURI===ne&&!ge[i])&&!(e.namespaceURI===ee&&!fe[i])&&!be[n]&&(ye[n]||!me[n]):!("application/xhtml+xml"!==yt||!se[t.namespaceURI]))},xe=function(t){w(n.removed,{element:t});try{t.parentNode.removeChild(t)}catch(Oe){try{t.outerHTML=ot}catch(Oe){t.remove()}}},ve=function(t,e){try{w(n.removed,{attribute:e.getAttributeNode(t),from:e})}catch(Oe){w(n.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t&&!At[t])if(jt||Yt)try{xe(e)}catch(Oe){}else try{e.setAttribute(t,"")}catch(Oe){}},ke=function(t){var e,n;if(Pt)t="<remove></remove>"+t;else{var i=E(t,/^[\r\n\t ]+/);n=i&&i[0]}"application/xhtml+xml"===yt&&re===ie&&(t='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+t+"</body></html>");var r=st?st.createHTML(t):t;if(re===ie)try{e=(new f).parseFromString(r,yt)}catch(Oe){}if(!e||!e.documentElement){e=lt.createDocument(re,"template",null);try{e.documentElement.innerHTML=ae?"":r}catch(Oe){}}var s=e.body||e.documentElement;return t&&n&&s.insertBefore(a.createTextNode(n),s.childNodes[0]||null),re===ie?dt.call(e,Rt?"html":"body")[0]:Rt?e.documentElement:s},we=function(t){return ht.call(t.ownerDocument||t,t,h.SHOW_ELEMENT|h.SHOW_COMMENT|h.SHOW_TEXT,null,!1)},Te=function(t){return t instanceof p&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof d)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore||"function"!=typeof t.hasChildNodes)},Ce=function(e){return"object"===t(c)?e instanceof c:e&&"object"===t(e)&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName},Ee=function(t,e,i){gt[t]&&v(gt[t],(function(t){t.call(n,e,i,he)}))},Se=function(t){var e;if(Ee("beforeSanitizeElements",t,null),Te(t))return xe(t),!0;if(L(/[\u0080-\uFFFF]/,t.nodeName))return xe(t),!0;var i=mt(t.nodeName);if(Ee("uponSanitizeElement",t,{tagName:i,allowedTags:Et}),t.hasChildNodes()&&!Ce(t.firstElementChild)&&(!Ce(t.content)||!Ce(t.content.firstElementChild))&&L(/<[/\w]/g,t.innerHTML)&&L(/<[/\w]/g,t.textContent))return xe(t),!0;if("select"===i&&L(/<template/i,t.innerHTML))return xe(t),!0;if(!Et[i]||Nt[i]){if(!Nt[i]&&De(i)){if(Lt.tagNameCheck instanceof RegExp&&L(Lt.tagNameCheck,i))return!1;if(Lt.tagNameCheck instanceof Function&&Lt.tagNameCheck(i))return!1}if(qt&&!Xt[i]){var r=O(t)||t.parentNode,a=x(t)||t.childNodes;if(a&&r)for(var s=a.length-1;s>=0;--s)r.insertBefore(b(a[s],!0),_(t))}return xe(t),!0}return t instanceof l&&!_e(t)?(xe(t),!0):"noscript"!==i&&"noembed"!==i||!L(/<\/no(script|embed)/i,t.innerHTML)?(Ft&&3===t.nodeType&&(e=t.textContent,e=S(e,bt," "),e=S(e,_t," "),e=S(e,xt," "),t.textContent!==e&&(w(n.removed,{element:t.cloneNode()}),t.textContent=e)),Ee("afterSanitizeElements",t,null),!1):(xe(t),!0)},Ae=function(t,e,n){if(Ut&&("id"===e||"name"===e)&&(n in a||n in ue))return!1;if(Mt&&!Ot[e]&&L(vt,e));else if(Bt&&L(kt,e));else if(!At[e]||Ot[e]){if(!(De(t)&&(Lt.tagNameCheck instanceof RegExp&&L(Lt.tagNameCheck,t)||Lt.tagNameCheck instanceof Function&&Lt.tagNameCheck(t))&&(Lt.attributeNameCheck instanceof RegExp&&L(Lt.attributeNameCheck,e)||Lt.attributeNameCheck instanceof Function&&Lt.attributeNameCheck(e))||"is"===e&&Lt.allowCustomizedBuiltInElements&&(Lt.tagNameCheck instanceof RegExp&&L(Lt.tagNameCheck,n)||Lt.tagNameCheck instanceof Function&&Lt.tagNameCheck(n))))return!1}else if(Jt[e]);else if(L(Ct,S(n,Tt,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==A(n,"data:")||!Qt[t])if(It&&!L(wt,S(n,Tt,"")));else if(n)return!1;return!0},De=function(t){return t.indexOf("-")>0},Le=function(e){var i,r,a,s;Ee("beforeSanitizeAttributes",e,null);var o=e.attributes;if(o){var c={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:At};for(s=o.length;s--;){var l=i=o[s],h=l.name,u=l.namespaceURI;if(r="value"===h?i.value:D(i.value),a=mt(h),c.attrName=a,c.attrValue=r,c.keepAttr=!0,c.forceKeepAttr=void 0,Ee("uponSanitizeAttribute",e,c),r=c.attrValue,!c.forceKeepAttr&&(ve(h,e),c.keepAttr))if(L(/\/>/i,r))ve(h,e);else{Ft&&(r=S(r,bt," "),r=S(r,_t," "),r=S(r,xt," "));var d=mt(e.nodeName);if(Ae(d,a,r)){if(!Wt||"id"!==a&&"name"!==a||(ve(h,e),r=Ht+r),st&&"object"===t(y)&&"function"==typeof y.getAttributeType)if(u);else switch(y.getAttributeType(d,a)){case"TrustedHTML":r=st.createHTML(r);break;case"TrustedScriptURL":r=st.createScriptURL(r)}try{u?e.setAttributeNS(u,h,r):e.setAttribute(h,r),k(n.removed)}catch(Oe){}}}}Ee("afterSanitizeAttributes",e,null)}},Ne=function t(e){var n,i=we(e);for(Ee("beforeSanitizeShadowDOM",e,null);n=i.nextNode();)Ee("uponSanitizeShadowNode",n,null),Se(n)||(n.content instanceof s&&t(n.content),Le(n));Ee("afterSanitizeShadowDOM",e,null)};return n.sanitize=function(r){var a,o,l,h,u,d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if((ae=!r)&&(r="\x3c!--\x3e"),"string"!=typeof r&&!Ce(r)){if("function"!=typeof r.toString)throw N("toString is not a function");if("string"!=typeof(r=r.toString()))throw N("dirty is not a string, aborting")}if(!n.isSupported){if("object"===t(e.toStaticHTML)||"function"==typeof e.toStaticHTML){if("string"==typeof r)return e.toStaticHTML(r);if(Ce(r))return e.toStaticHTML(r.outerHTML)}return r}if($t||pe(d),n.removed=[],"string"==typeof r&&(Vt=!1),Vt){if(r.nodeName){var p=mt(r.nodeName);if(!Et[p]||Nt[p])throw N("root node is forbidden and cannot be sanitized in-place")}}else if(r instanceof c)1===(o=(a=ke("\x3c!----\x3e")).ownerDocument.importNode(r,!0)).nodeType&&"BODY"===o.nodeName||"HTML"===o.nodeName?a=o:a.appendChild(o);else{if(!jt&&!Ft&&!Rt&&-1===r.indexOf("<"))return st&&zt?st.createHTML(r):r;if(!(a=ke(r)))return jt?null:zt?ot:""}a&&Pt&&xe(a.firstChild);for(var f=we(Vt?r:a);l=f.nextNode();)3===l.nodeType&&l===h||Se(l)||(l.content instanceof s&&Ne(l.content),Le(l),h=l);if(h=null,Vt)return r;if(jt){if(Yt)for(u=ut.call(a.ownerDocument);a.firstChild;)u.appendChild(a.firstChild);else u=a;return At.shadowroot&&(u=pt.call(i,u,!0)),u}var g=Rt?a.outerHTML:a.innerHTML;return Rt&&Et["!doctype"]&&a.ownerDocument&&a.ownerDocument.doctype&&a.ownerDocument.doctype.name&&L(nt,a.ownerDocument.doctype.name)&&(g="<!DOCTYPE "+a.ownerDocument.doctype.name+">\n"+g),Ft&&(g=S(g,bt," "),g=S(g,_t," "),g=S(g,xt," ")),st&&zt?st.createHTML(g):g},n.setConfig=function(t){pe(t),$t=!0},n.clearConfig=function(){he=null,$t=!1},n.isValidAttribute=function(t,e,n){he||pe({});var i=mt(t),r=mt(e);return Ae(i,r,n)},n.addHook=function(t,e){"function"==typeof e&&(gt[t]=gt[t]||[],w(gt[t],e))},n.removeHook=function(t){if(gt[t])return k(gt[t])},n.removeHooks=function(t){gt[t]&&(gt[t]=[])},n.removeAllHooks=function(){gt={}},n}return at()}()},89234:()=>{},11941:function(t,e,n){(t=n.nmd(t)).exports=function(){"use strict";var e;function i(){return e.apply(null,arguments)}function r(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function a(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function s(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function o(t){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(t).length;for(var e in t)if(s(t,e))return;return 1}function c(t){return void 0===t}function l(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function h(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function u(t,e){for(var n=[],i=t.length,r=0;r<i;++r)n.push(e(t[r],r));return n}function d(t,e){for(var n in e)s(e,n)&&(t[n]=e[n]);return s(e,"toString")&&(t.toString=e.toString),s(e,"valueOf")&&(t.valueOf=e.valueOf),t}function p(t,e,n,i){return Le(t,e,n,i,!0).utc()}function f(t){return null==t._pf&&(t._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidEra:null,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],era:null,meridiem:null,rfc2822:!1,weekdayMismatch:!1}),t._pf}function g(t){if(null==t._isValid){var e=f(t),n=m.call(e.parsedDateParts,(function(t){return null!=t}));if(n=!isNaN(t._d.getTime())&&e.overflow<0&&!e.empty&&!e.invalidEra&&!e.invalidMonth&&!e.invalidWeekday&&!e.weekdayMismatch&&!e.nullInput&&!e.invalidFormat&&!e.userInvalidated&&(!e.meridiem||e.meridiem&&n),t._strict&&(n=n&&0===e.charsLeftOver&&0===e.unusedTokens.length&&void 0===e.bigHour),null!=Object.isFrozen&&Object.isFrozen(t))return n;t._isValid=n}return t._isValid}function y(t){var e=p(NaN);return null!=t?d(f(e),t):f(e).userInvalidated=!0,e}var m=Array.prototype.some||function(t){for(var e=Object(this),n=e.length>>>0,i=0;i<n;i++)if(i in e&&t.call(this,e[i],i,e))return!0;return!1},b=i.momentProperties=[],_=!1;function x(t,e){var n,i,r,a=b.length;if(c(e._isAMomentObject)||(t._isAMomentObject=e._isAMomentObject),c(e._i)||(t._i=e._i),c(e._f)||(t._f=e._f),c(e._l)||(t._l=e._l),c(e._strict)||(t._strict=e._strict),c(e._tzm)||(t._tzm=e._tzm),c(e._isUTC)||(t._isUTC=e._isUTC),c(e._offset)||(t._offset=e._offset),c(e._pf)||(t._pf=f(e)),c(e._locale)||(t._locale=e._locale),0<a)for(n=0;n<a;n++)c(r=e[i=b[n]])||(t[i]=r);return t}function v(t){x(this,t),this._d=new Date(null!=t._d?t._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===_&&(_=!0,i.updateOffset(this),_=!1)}function k(t){return t instanceof v||null!=t&&null!=t._isAMomentObject}function w(t){!1===i.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+t)}function T(t,e){var n=!0;return d((function(){if(null!=i.deprecationHandler&&i.deprecationHandler(null,t),n){for(var r,a,o=[],c=arguments.length,l=0;l<c;l++){if(r="","object"==typeof arguments[l]){for(a in r+="\n["+l+"] ",arguments[0])s(arguments[0],a)&&(r+=a+": "+arguments[0][a]+", ");r=r.slice(0,-2)}else r=arguments[l];o.push(r)}w(t+"\nArguments: "+Array.prototype.slice.call(o).join("")+"\n"+(new Error).stack),n=!1}return e.apply(this,arguments)}),e)}var C={};function E(t,e){null!=i.deprecationHandler&&i.deprecationHandler(t,e),C[t]||(w(e),C[t]=!0)}function S(t){return"undefined"!=typeof Function&&t instanceof Function||"[object Function]"===Object.prototype.toString.call(t)}function A(t,e){var n,i=d({},t);for(n in e)s(e,n)&&(a(t[n])&&a(e[n])?(i[n]={},d(i[n],t[n]),d(i[n],e[n])):null!=e[n]?i[n]=e[n]:delete i[n]);for(n in t)s(t,n)&&!s(e,n)&&a(t[n])&&(i[n]=d({},i[n]));return i}function D(t){null!=t&&this.set(t)}i.suppressDeprecationWarnings=!1,i.deprecationHandler=null;var L=Object.keys||function(t){var e,n=[];for(e in t)s(t,e)&&n.push(e);return n};function N(t,e,n){var i=""+Math.abs(t);return(0<=t?n?"+":"":"-")+Math.pow(10,Math.max(0,e-i.length)).toString().substr(1)+i}var O=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,B=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,M={},I={};function F(t,e,n,i){var r="string"==typeof i?function(){return this[i]()}:i;t&&(I[t]=r),e&&(I[e[0]]=function(){return N(r.apply(this,arguments),e[1],e[2])}),n&&(I[n]=function(){return this.localeData().ordinal(r.apply(this,arguments),t)})}function R(t,e){return t.isValid()?(e=$(e,t.localeData()),M[e]=M[e]||function(t){for(var e,n=t.match(O),i=0,r=n.length;i<r;i++)I[n[i]]?n[i]=I[n[i]]:n[i]=(e=n[i]).match(/\[[\s\S]/)?e.replace(/^\[|\]$/g,""):e.replace(/\\/g,"");return function(e){for(var i="",a=0;a<r;a++)i+=S(n[a])?n[a].call(e,t):n[a];return i}}(e),M[e](t)):t.localeData().invalidDate()}function $(t,e){var n=5;function i(t){return e.longDateFormat(t)||t}for(B.lastIndex=0;0<=n&&B.test(t);)t=t.replace(B,i),B.lastIndex=0,--n;return t}var P={};function j(t,e){var n=t.toLowerCase();P[n]=P[n+"s"]=P[e]=t}function Y(t){return"string"==typeof t?P[t]||P[t.toLowerCase()]:void 0}function z(t){var e,n,i={};for(n in t)s(t,n)&&(e=Y(n))&&(i[e]=t[n]);return i}var U={};function W(t,e){U[t]=e}function H(t){return t%4==0&&t%100!=0||t%400==0}function q(t){return t<0?Math.ceil(t)||0:Math.floor(t)}function V(t){var e=0;return 0!=(t=+t)&&isFinite(t)?q(t):e}function G(t,e){return function(n){return null!=n?(Z(this,t,n),i.updateOffset(this,e),this):X(this,t)}}function X(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function Z(t,e,n){t.isValid()&&!isNaN(n)&&("FullYear"===e&&H(t.year())&&1===t.month()&&29===t.date()?(n=V(n),t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),Lt(n,t.month()))):t._d["set"+(t._isUTC?"UTC":"")+e](n))}var Q=/\d/,K=/\d\d/,J=/\d{3}/,tt=/\d{4}/,et=/[+-]?\d{6}/,nt=/\d\d?/,it=/\d\d\d\d?/,rt=/\d\d\d\d\d\d?/,at=/\d{1,3}/,st=/\d{1,4}/,ot=/[+-]?\d{1,6}/,ct=/\d+/,lt=/[+-]?\d+/,ht=/Z|[+-]\d\d:?\d\d/gi,ut=/Z|[+-]\d\d(?::?\d\d)?/gi,dt=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;function pt(t,e,n){yt[t]=S(e)?e:function(t,i){return t&&n?n:e}}function ft(t,e){return s(yt,t)?yt[t](e._strict,e._locale):new RegExp(gt(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(t,e,n,i,r){return e||n||i||r}))))}function gt(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var yt={},mt={};function bt(t,e){var n,i,r=e;for("string"==typeof t&&(t=[t]),l(e)&&(r=function(t,n){n[e]=V(t)}),i=t.length,n=0;n<i;n++)mt[t[n]]=r}function _t(t,e){bt(t,(function(t,n,i,r){i._w=i._w||{},e(t,i._w,i,r)}))}var xt,vt=0,kt=1,wt=2,Tt=3,Ct=4,Et=5,St=6,At=7,Dt=8;function Lt(t,e){if(isNaN(t)||isNaN(e))return NaN;var n=(e%(n=12)+n)%n;return t+=(e-n)/12,1==n?H(t)?29:28:31-n%7%2}xt=Array.prototype.indexOf||function(t){for(var e=0;e<this.length;++e)if(this[e]===t)return e;return-1},F("M",["MM",2],"Mo",(function(){return this.month()+1})),F("MMM",0,0,(function(t){return this.localeData().monthsShort(this,t)})),F("MMMM",0,0,(function(t){return this.localeData().months(this,t)})),j("month","M"),W("month",8),pt("M",nt),pt("MM",nt,K),pt("MMM",(function(t,e){return e.monthsShortRegex(t)})),pt("MMMM",(function(t,e){return e.monthsRegex(t)})),bt(["M","MM"],(function(t,e){e[kt]=V(t)-1})),bt(["MMM","MMMM"],(function(t,e,n,i){null!=(i=n._locale.monthsParse(t,i,n._strict))?e[kt]=i:f(n).invalidMonth=t}));var Nt="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Ot="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Bt=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,Mt=dt,It=dt;function Ft(t,e){var n;if(t.isValid()){if("string"==typeof e)if(/^\d+$/.test(e))e=V(e);else if(!l(e=t.localeData().monthsParse(e)))return;n=Math.min(t.date(),Lt(t.year(),e)),t._d["set"+(t._isUTC?"UTC":"")+"Month"](e,n)}}function Rt(t){return null!=t?(Ft(this,t),i.updateOffset(this,!0),this):X(this,"Month")}function $t(){function t(t,e){return e.length-t.length}for(var e,n=[],i=[],r=[],a=0;a<12;a++)e=p([2e3,a]),n.push(this.monthsShort(e,"")),i.push(this.months(e,"")),r.push(this.months(e,"")),r.push(this.monthsShort(e,""));for(n.sort(t),i.sort(t),r.sort(t),a=0;a<12;a++)n[a]=gt(n[a]),i[a]=gt(i[a]);for(a=0;a<24;a++)r[a]=gt(r[a]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+n.join("|")+")","i")}function Pt(t){return H(t)?366:365}F("Y",0,0,(function(){var t=this.year();return t<=9999?N(t,4):"+"+t})),F(0,["YY",2],0,(function(){return this.year()%100})),F(0,["YYYY",4],0,"year"),F(0,["YYYYY",5],0,"year"),F(0,["YYYYYY",6,!0],0,"year"),j("year","y"),W("year",1),pt("Y",lt),pt("YY",nt,K),pt("YYYY",st,tt),pt("YYYYY",ot,et),pt("YYYYYY",ot,et),bt(["YYYYY","YYYYYY"],vt),bt("YYYY",(function(t,e){e[vt]=2===t.length?i.parseTwoDigitYear(t):V(t)})),bt("YY",(function(t,e){e[vt]=i.parseTwoDigitYear(t)})),bt("Y",(function(t,e){e[vt]=parseInt(t,10)})),i.parseTwoDigitYear=function(t){return V(t)+(68<V(t)?1900:2e3)};var jt=G("FullYear",!0);function Yt(t,e,n,i,r,a,s){var o;return t<100&&0<=t?(o=new Date(t+400,e,n,i,r,a,s),isFinite(o.getFullYear())&&o.setFullYear(t)):o=new Date(t,e,n,i,r,a,s),o}function zt(t){var e;return t<100&&0<=t?((e=Array.prototype.slice.call(arguments))[0]=t+400,e=new Date(Date.UTC.apply(null,e)),isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t)):e=new Date(Date.UTC.apply(null,arguments)),e}function Ut(t,e,n){return(n=7+e-n)-(7+zt(t,0,n).getUTCDay()-e)%7-1}function Wt(t,e,n,i,r){var a;return n=(e=1+7*(e-1)+(7+n-i)%7+Ut(t,i,r))<=0?Pt(a=t-1)+e:e>Pt(t)?(a=t+1,e-Pt(t)):(a=t,e),{year:a,dayOfYear:n}}function Ht(t,e,n){var i,r,a=Ut(t.year(),e,n);return(a=Math.floor((t.dayOfYear()-a-1)/7)+1)<1?i=a+qt(r=t.year()-1,e,n):a>qt(t.year(),e,n)?(i=a-qt(t.year(),e,n),r=t.year()+1):(r=t.year(),i=a),{week:i,year:r}}function qt(t,e,n){var i=Ut(t,e,n);return e=Ut(t+1,e,n),(Pt(t)-i+e)/7}function Vt(t,e){return t.slice(e,7).concat(t.slice(0,e))}F("w",["ww",2],"wo","week"),F("W",["WW",2],"Wo","isoWeek"),j("week","w"),j("isoWeek","W"),W("week",5),W("isoWeek",5),pt("w",nt),pt("ww",nt,K),pt("W",nt),pt("WW",nt,K),_t(["w","ww","W","WW"],(function(t,e,n,i){e[i.substr(0,1)]=V(t)})),F("d",0,"do","day"),F("dd",0,0,(function(t){return this.localeData().weekdaysMin(this,t)})),F("ddd",0,0,(function(t){return this.localeData().weekdaysShort(this,t)})),F("dddd",0,0,(function(t){return this.localeData().weekdays(this,t)})),F("e",0,0,"weekday"),F("E",0,0,"isoWeekday"),j("day","d"),j("weekday","e"),j("isoWeekday","E"),W("day",11),W("weekday",11),W("isoWeekday",11),pt("d",nt),pt("e",nt),pt("E",nt),pt("dd",(function(t,e){return e.weekdaysMinRegex(t)})),pt("ddd",(function(t,e){return e.weekdaysShortRegex(t)})),pt("dddd",(function(t,e){return e.weekdaysRegex(t)})),_t(["dd","ddd","dddd"],(function(t,e,n,i){null!=(i=n._locale.weekdaysParse(t,i,n._strict))?e.d=i:f(n).invalidWeekday=t})),_t(["d","e","E"],(function(t,e,n,i){e[i]=V(t)}));var Gt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Xt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Zt="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),Qt=dt,Kt=dt,Jt=dt;function te(){function t(t,e){return e.length-t.length}for(var e,n,i,r=[],a=[],s=[],o=[],c=0;c<7;c++)i=p([2e3,1]).day(c),e=gt(this.weekdaysMin(i,"")),n=gt(this.weekdaysShort(i,"")),i=gt(this.weekdays(i,"")),r.push(e),a.push(n),s.push(i),o.push(e),o.push(n),o.push(i);r.sort(t),a.sort(t),s.sort(t),o.sort(t),this._weekdaysRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function ee(){return this.hours()%12||12}function ne(t,e){F(t,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)}))}function ie(t,e){return e._meridiemParse}F("H",["HH",2],0,"hour"),F("h",["hh",2],0,ee),F("k",["kk",2],0,(function(){return this.hours()||24})),F("hmm",0,0,(function(){return""+ee.apply(this)+N(this.minutes(),2)})),F("hmmss",0,0,(function(){return""+ee.apply(this)+N(this.minutes(),2)+N(this.seconds(),2)})),F("Hmm",0,0,(function(){return""+this.hours()+N(this.minutes(),2)})),F("Hmmss",0,0,(function(){return""+this.hours()+N(this.minutes(),2)+N(this.seconds(),2)})),ne("a",!0),ne("A",!1),j("hour","h"),W("hour",13),pt("a",ie),pt("A",ie),pt("H",nt),pt("h",nt),pt("k",nt),pt("HH",nt,K),pt("hh",nt,K),pt("kk",nt,K),pt("hmm",it),pt("hmmss",rt),pt("Hmm",it),pt("Hmmss",rt),bt(["H","HH"],Tt),bt(["k","kk"],(function(t,e,n){t=V(t),e[Tt]=24===t?0:t})),bt(["a","A"],(function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t})),bt(["h","hh"],(function(t,e,n){e[Tt]=V(t),f(n).bigHour=!0})),bt("hmm",(function(t,e,n){var i=t.length-2;e[Tt]=V(t.substr(0,i)),e[Ct]=V(t.substr(i)),f(n).bigHour=!0})),bt("hmmss",(function(t,e,n){var i=t.length-4,r=t.length-2;e[Tt]=V(t.substr(0,i)),e[Ct]=V(t.substr(i,2)),e[Et]=V(t.substr(r)),f(n).bigHour=!0})),bt("Hmm",(function(t,e,n){var i=t.length-2;e[Tt]=V(t.substr(0,i)),e[Ct]=V(t.substr(i))})),bt("Hmmss",(function(t,e,n){var i=t.length-4,r=t.length-2;e[Tt]=V(t.substr(0,i)),e[Ct]=V(t.substr(i,2)),e[Et]=V(t.substr(r))})),dt=G("Hours",!0);var re,ae={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Nt,monthsShort:Ot,week:{dow:0,doy:6},weekdays:Gt,weekdaysMin:Zt,weekdaysShort:Xt,meridiemParse:/[ap]\.?m?\.?/i},se={},oe={};function ce(t){return t&&t.toLowerCase().replace("_","-")}function le(t){for(var e,n,i,r,a=0;a<t.length;){for(e=(r=ce(t[a]).split("-")).length,n=(n=ce(t[a+1]))?n.split("-"):null;0<e;){if(i=he(r.slice(0,e).join("-")))return i;if(n&&n.length>=e&&function(t,e){for(var n=Math.min(t.length,e.length),i=0;i<n;i+=1)if(t[i]!==e[i])return i;return n}(r,n)>=e-1)break;e--}a++}return re}function he(e){var i;if(void 0===se[e]&&t&&t.exports&&null!=e.match("^[^/\\\\]*$"))try{i=re._abbr,n(11748)("./"+e),ue(i)}catch(i){se[e]=null}return se[e]}function ue(t,e){return t&&((e=c(e)?pe(t):de(t,e))?re=e:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),re._abbr}function de(t,e){if(null===e)return delete se[t],null;var n,i=ae;if(e.abbr=t,null!=se[t])E("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=se[t]._config;else if(null!=e.parentLocale)if(null!=se[e.parentLocale])i=se[e.parentLocale]._config;else{if(null==(n=he(e.parentLocale)))return oe[e.parentLocale]||(oe[e.parentLocale]=[]),oe[e.parentLocale].push({name:t,config:e}),null;i=n._config}return se[t]=new D(A(i,e)),oe[t]&&oe[t].forEach((function(t){de(t.name,t.config)})),ue(t),se[t]}function pe(t){var e;if(!(t=t&&t._locale&&t._locale._abbr?t._locale._abbr:t))return re;if(!r(t)){if(e=he(t))return e;t=[t]}return le(t)}function fe(t){var e=t._a;return e&&-2===f(t).overflow&&(e=e[kt]<0||11<e[kt]?kt:e[wt]<1||e[wt]>Lt(e[vt],e[kt])?wt:e[Tt]<0||24<e[Tt]||24===e[Tt]&&(0!==e[Ct]||0!==e[Et]||0!==e[St])?Tt:e[Ct]<0||59<e[Ct]?Ct:e[Et]<0||59<e[Et]?Et:e[St]<0||999<e[St]?St:-1,f(t)._overflowDayOfYear&&(e<vt||wt<e)&&(e=wt),f(t)._overflowWeeks&&-1===e&&(e=At),f(t)._overflowWeekday&&-1===e&&(e=Dt),f(t).overflow=e),t}var ge=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,ye=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,me=/Z|[+-]\d\d(?::?\d\d)?/,be=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,!1],["YYYY",/\d{4}/,!1]],_e=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],xe=/^\/?Date\((-?\d+)/i,ve=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,ke={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function we(t){var e,n,i,r,a,s,o=t._i,c=ge.exec(o)||ye.exec(o),l=(o=be.length,_e.length);if(c){for(f(t).iso=!0,e=0,n=o;e<n;e++)if(be[e][1].exec(c[1])){r=be[e][0],i=!1!==be[e][2];break}if(null==r)t._isValid=!1;else{if(c[3]){for(e=0,n=l;e<n;e++)if(_e[e][1].exec(c[3])){a=(c[2]||" ")+_e[e][0];break}if(null==a)return void(t._isValid=!1)}if(i||null==a){if(c[4]){if(!me.exec(c[4]))return void(t._isValid=!1);s="Z"}t._f=r+(a||"")+(s||""),Ae(t)}else t._isValid=!1}}else t._isValid=!1}function Te(t,e,n,i,r,a){return t=[function(t){return(t=parseInt(t,10))<=49?2e3+t:t<=999?1900+t:t}(t),Ot.indexOf(e),parseInt(n,10),parseInt(i,10),parseInt(r,10)],a&&t.push(parseInt(a,10)),t}function Ce(t){var e,n,i,r,a=ve.exec(t._i.replace(/\([^()]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""));a?(i=e=Te(a[4],a[3],a[2],a[5],a[6],a[7]),r=t,(n=a[1])&&Xt.indexOf(n)!==new Date(i[0],i[1],i[2]).getDay()?(f(r).weekdayMismatch=!0,r._isValid=!1):(t._a=e,t._tzm=(n=a[8],i=a[9],r=a[10],n?ke[n]:i?0:((n=parseInt(r,10))-(i=n%100))/100*60+i),t._d=zt.apply(null,t._a),t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),f(t).rfc2822=!0)):t._isValid=!1}function Ee(t,e,n){return null!=t?t:null!=e?e:n}function Se(t){var e,n,r,a,s,o,c,l,h,u,d,p=[];if(!t._d){for(r=t,a=new Date(i.now()),n=r._useUTC?[a.getUTCFullYear(),a.getUTCMonth(),a.getUTCDate()]:[a.getFullYear(),a.getMonth(),a.getDate()],t._w&&null==t._a[wt]&&null==t._a[kt]&&(null!=(a=(r=t)._w).GG||null!=a.W||null!=a.E?(l=1,h=4,s=Ee(a.GG,r._a[vt],Ht(Ne(),1,4).year),o=Ee(a.W,1),((c=Ee(a.E,1))<1||7<c)&&(u=!0)):(l=r._locale._week.dow,h=r._locale._week.doy,d=Ht(Ne(),l,h),s=Ee(a.gg,r._a[vt],d.year),o=Ee(a.w,d.week),null!=a.d?((c=a.d)<0||6<c)&&(u=!0):null!=a.e?(c=a.e+l,(a.e<0||6<a.e)&&(u=!0)):c=l),o<1||o>qt(s,l,h)?f(r)._overflowWeeks=!0:null!=u?f(r)._overflowWeekday=!0:(d=Wt(s,o,c,l,h),r._a[vt]=d.year,r._dayOfYear=d.dayOfYear)),null!=t._dayOfYear&&(a=Ee(t._a[vt],n[vt]),(t._dayOfYear>Pt(a)||0===t._dayOfYear)&&(f(t)._overflowDayOfYear=!0),u=zt(a,0,t._dayOfYear),t._a[kt]=u.getUTCMonth(),t._a[wt]=u.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=p[e]=n[e];for(;e<7;e++)t._a[e]=p[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[Tt]&&0===t._a[Ct]&&0===t._a[Et]&&0===t._a[St]&&(t._nextDay=!0,t._a[Tt]=0),t._d=(t._useUTC?zt:Yt).apply(null,p),s=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[Tt]=24),t._w&&void 0!==t._w.d&&t._w.d!==s&&(f(t).weekdayMismatch=!0)}}function Ae(t){if(t._f===i.ISO_8601)we(t);else if(t._f===i.RFC_2822)Ce(t);else{t._a=[],f(t).empty=!0;for(var e,n,r,a,o,c=""+t._i,l=c.length,h=0,u=$(t._f,t._locale).match(O)||[],d=u.length,p=0;p<d;p++)n=u[p],(e=(c.match(ft(n,t))||[])[0])&&(0<(r=c.substr(0,c.indexOf(e))).length&&f(t).unusedInput.push(r),c=c.slice(c.indexOf(e)+e.length),h+=e.length),I[n]?(e?f(t).empty=!1:f(t).unusedTokens.push(n),r=n,o=t,null!=(a=e)&&s(mt,r)&&mt[r](a,o._a,o,r)):t._strict&&!e&&f(t).unusedTokens.push(n);f(t).charsLeftOver=l-h,0<c.length&&f(t).unusedInput.push(c),t._a[Tt]<=12&&!0===f(t).bigHour&&0<t._a[Tt]&&(f(t).bigHour=void 0),f(t).parsedDateParts=t._a.slice(0),f(t).meridiem=t._meridiem,t._a[Tt]=function(t,e,n){return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?((t=t.isPM(n))&&e<12&&(e+=12),e=t||12!==e?e:0):e}(t._locale,t._a[Tt],t._meridiem),null!==(l=f(t).era)&&(t._a[vt]=t._locale.erasConvertYear(l,t._a[vt])),Se(t),fe(t)}}function De(t){var e,n,s,o=t._i,p=t._f;return t._locale=t._locale||pe(t._l),null===o||void 0===p&&""===o?y({nullInput:!0}):("string"==typeof o&&(t._i=o=t._locale.preparse(o)),k(o)?new v(fe(o)):(h(o)?t._d=o:r(p)?function(t){var e,n,i,r,a,s,o=!1,c=t._f.length;if(0===c)return f(t).invalidFormat=!0,t._d=new Date(NaN);for(r=0;r<c;r++)a=0,s=!1,e=x({},t),null!=t._useUTC&&(e._useUTC=t._useUTC),e._f=t._f[r],Ae(e),g(e)&&(s=!0),a=(a+=f(e).charsLeftOver)+10*f(e).unusedTokens.length,f(e).score=a,o?a<i&&(i=a,n=e):(null==i||a<i||s)&&(i=a,n=e,s&&(o=!0));d(t,n||e)}(t):p?Ae(t):c(p=(o=t)._i)?o._d=new Date(i.now()):h(p)?o._d=new Date(p.valueOf()):"string"==typeof p?(n=o,null!==(e=xe.exec(n._i))?n._d=new Date(+e[1]):(we(n),!1===n._isValid&&(delete n._isValid,Ce(n),!1===n._isValid&&(delete n._isValid,n._strict?n._isValid=!1:i.createFromInputFallback(n))))):r(p)?(o._a=u(p.slice(0),(function(t){return parseInt(t,10)})),Se(o)):a(p)?(e=o)._d||(s=void 0===(n=z(e._i)).day?n.date:n.day,e._a=u([n.year,n.month,s,n.hour,n.minute,n.second,n.millisecond],(function(t){return t&&parseInt(t,10)})),Se(e)):l(p)?o._d=new Date(p):i.createFromInputFallback(o),g(t)||(t._d=null),t))}function Le(t,e,n,i,s){var c={};return!0!==e&&!1!==e||(i=e,e=void 0),!0!==n&&!1!==n||(i=n,n=void 0),(a(t)&&o(t)||r(t)&&0===t.length)&&(t=void 0),c._isAMomentObject=!0,c._useUTC=c._isUTC=s,c._l=n,c._i=t,c._f=e,c._strict=i,(s=new v(fe(De(s=c))))._nextDay&&(s.add(1,"d"),s._nextDay=void 0),s}function Ne(t,e,n,i){return Le(t,e,n,i,!1)}function Oe(t,e){var n,i;if(!(e=1===e.length&&r(e[0])?e[0]:e).length)return Ne();for(n=e[0],i=1;i<e.length;++i)e[i].isValid()&&!e[i][t](n)||(n=e[i]);return n}i.createFromInputFallback=T("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",(function(t){t._d=new Date(t._i+(t._useUTC?" UTC":""))})),i.ISO_8601=function(){},i.RFC_2822=function(){},it=T("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",(function(){var t=Ne.apply(null,arguments);return this.isValid()&&t.isValid()?t<this?this:t:y()})),rt=T("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",(function(){var t=Ne.apply(null,arguments);return this.isValid()&&t.isValid()?this<t?this:t:y()}));var Be=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Me(t){var e=(t=z(t)).year||0,n=t.quarter||0,i=t.month||0,r=t.week||t.isoWeek||0,a=t.day||0,o=t.hour||0,c=t.minute||0,l=t.second||0,h=t.millisecond||0;this._isValid=function(t){var e,n,i=!1,r=Be.length;for(e in t)if(s(t,e)&&(-1===xt.call(Be,e)||null!=t[e]&&isNaN(t[e])))return!1;for(n=0;n<r;++n)if(t[Be[n]]){if(i)return!1;parseFloat(t[Be[n]])!==V(t[Be[n]])&&(i=!0)}return!0}(t),this._milliseconds=+h+1e3*l+6e4*c+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*n+12*e,this._data={},this._locale=pe(),this._bubble()}function Ie(t){return t instanceof Me}function Fe(t){return t<0?-1*Math.round(-1*t):Math.round(t)}function Re(t,e){F(t,0,0,(function(){var t=this.utcOffset(),n="+";return t<0&&(t=-t,n="-"),n+N(~~(t/60),2)+e+N(~~t%60,2)}))}Re("Z",":"),Re("ZZ",""),pt("Z",ut),pt("ZZ",ut),bt(["Z","ZZ"],(function(t,e,n){n._useUTC=!0,n._tzm=Pe(ut,t)}));var $e=/([\+\-]|\d\d)/gi;function Pe(t,e){return null===(e=(e||"").match(t))?null:0===(e=60*(t=((e[e.length-1]||[])+"").match($e)||["-",0,0])[1]+V(t[2]))?0:"+"===t[0]?e:-e}function je(t,e){var n;return e._isUTC?(e=e.clone(),n=(k(t)||h(t)?t:Ne(t)).valueOf()-e.valueOf(),e._d.setTime(e._d.valueOf()+n),i.updateOffset(e,!1),e):Ne(t).local()}function Ye(t){return-Math.round(t._d.getTimezoneOffset())}function ze(){return!!this.isValid()&&this._isUTC&&0===this._offset}i.updateOffset=function(){};var Ue=/^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,We=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function He(t,e){var n,i=t,r=null;return Ie(t)?i={ms:t._milliseconds,d:t._days,M:t._months}:l(t)||!isNaN(+t)?(i={},e?i[e]=+t:i.milliseconds=+t):(r=Ue.exec(t))?(n="-"===r[1]?-1:1,i={y:0,d:V(r[wt])*n,h:V(r[Tt])*n,m:V(r[Ct])*n,s:V(r[Et])*n,ms:V(Fe(1e3*r[St]))*n}):(r=We.exec(t))?(n="-"===r[1]?-1:1,i={y:qe(r[2],n),M:qe(r[3],n),w:qe(r[4],n),d:qe(r[5],n),h:qe(r[6],n),m:qe(r[7],n),s:qe(r[8],n)}):null==i?i={}:"object"==typeof i&&("from"in i||"to"in i)&&(e=function(t,e){var n;return t.isValid()&&e.isValid()?(e=je(e,t),t.isBefore(e)?n=Ve(t,e):((n=Ve(e,t)).milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}(Ne(i.from),Ne(i.to)),(i={}).ms=e.milliseconds,i.M=e.months),r=new Me(i),Ie(t)&&s(t,"_locale")&&(r._locale=t._locale),Ie(t)&&s(t,"_isValid")&&(r._isValid=t._isValid),r}function qe(t,e){return t=t&&parseFloat(t.replace(",",".")),(isNaN(t)?0:t)*e}function Ve(t,e){var n={};return n.months=e.month()-t.month()+12*(e.year()-t.year()),t.clone().add(n.months,"M").isAfter(e)&&--n.months,n.milliseconds=+e-+t.clone().add(n.months,"M"),n}function Ge(t,e){return function(n,i){var r;return null===i||isNaN(+i)||(E(e,"moment()."+e+"(period, number) is deprecated. Please use moment()."+e+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),r=n,n=i,i=r),Xe(this,He(n,i),t),this}}function Xe(t,e,n,r){var a=e._milliseconds,s=Fe(e._days);e=Fe(e._months),t.isValid()&&(r=null==r||r,e&&Ft(t,X(t,"Month")+e*n),s&&Z(t,"Date",X(t,"Date")+s*n),a&&t._d.setTime(t._d.valueOf()+a*n),r&&i.updateOffset(t,s||e))}function Ze(t){return"string"==typeof t||t instanceof String}function Qe(t){return k(t)||h(t)||Ze(t)||l(t)||function(t){var e=r(t),n=!1;return e&&(n=0===t.filter((function(e){return!l(e)&&Ze(t)})).length),e&&n}(t)||function(t){var e,n,i=a(t)&&!o(t),r=!1,c=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"],l=c.length;for(e=0;e<l;e+=1)n=c[e],r=r||s(t,n);return i&&r}(t)||null==t}function Ke(t,e){if(t.date()<e.date())return-Ke(e,t);var n=12*(e.year()-t.year())+(e.month()-t.month()),i=t.clone().add(n,"months");return-(n+(e=e-i<0?(e-i)/(i-t.clone().add(n-1,"months")):(e-i)/(t.clone().add(1+n,"months")-i)))||0}function Je(t){return void 0===t?this._locale._abbr:(null!=(t=pe(t))&&(this._locale=t),this)}function tn(){return this._locale}He.fn=Me.prototype,He.invalid=function(){return He(NaN)},Nt=Ge(1,"add"),Gt=Ge(-1,"subtract"),i.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",i.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]",Zt=T("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",(function(t){return void 0===t?this.localeData():this.locale(t)}));var en,nn=126227808e5;function rn(t,e){return(t%e+e)%e}function an(t,e,n){return t<100&&0<=t?new Date(t+400,e,n)-nn:new Date(t,e,n).valueOf()}function sn(t,e,n){return t<100&&0<=t?Date.UTC(t+400,e,n)-nn:Date.UTC(t,e,n)}function on(t,e){return e.erasAbbrRegex(t)}function cn(){for(var t=[],e=[],n=[],i=[],r=this.eras(),a=0,s=r.length;a<s;++a)e.push(gt(r[a].name)),t.push(gt(r[a].abbr)),n.push(gt(r[a].narrow)),i.push(gt(r[a].name)),i.push(gt(r[a].abbr)),i.push(gt(r[a].narrow));this._erasRegex=new RegExp("^("+i.join("|")+")","i"),this._erasNameRegex=new RegExp("^("+e.join("|")+")","i"),this._erasAbbrRegex=new RegExp("^("+t.join("|")+")","i"),this._erasNarrowRegex=new RegExp("^("+n.join("|")+")","i")}function ln(t,e){F(0,[t,t.length],0,e)}function hn(t,e,n,i,r){var a;return null==t?Ht(this,i,r).year:(a=qt(t,i,r),function(t,e,n,i,r){return e=zt((t=Wt(t,e,n,i,r)).year,0,t.dayOfYear),this.year(e.getUTCFullYear()),this.month(e.getUTCMonth()),this.date(e.getUTCDate()),this}.call(this,t,e=a<e?a:e,n,i,r))}for(F("N",0,0,"eraAbbr"),F("NN",0,0,"eraAbbr"),F("NNN",0,0,"eraAbbr"),F("NNNN",0,0,"eraName"),F("NNNNN",0,0,"eraNarrow"),F("y",["y",1],"yo","eraYear"),F("y",["yy",2],0,"eraYear"),F("y",["yyy",3],0,"eraYear"),F("y",["yyyy",4],0,"eraYear"),pt("N",on),pt("NN",on),pt("NNN",on),pt("NNNN",(function(t,e){return e.erasNameRegex(t)})),pt("NNNNN",(function(t,e){return e.erasNarrowRegex(t)})),bt(["N","NN","NNN","NNNN","NNNNN"],(function(t,e,n,i){(i=n._locale.erasParse(t,i,n._strict))?f(n).era=i:f(n).invalidEra=t})),pt("y",ct),pt("yy",ct),pt("yyy",ct),pt("yyyy",ct),pt("yo",(function(t,e){return e._eraYearOrdinalRegex||ct})),bt(["y","yy","yyy","yyyy"],vt),bt(["yo"],(function(t,e,n,i){var r;n._locale._eraYearOrdinalRegex&&(r=t.match(n._locale._eraYearOrdinalRegex)),n._locale.eraYearOrdinalParse?e[vt]=n._locale.eraYearOrdinalParse(t,r):e[vt]=parseInt(t,10)})),F(0,["gg",2],0,(function(){return this.weekYear()%100})),F(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),ln("gggg","weekYear"),ln("ggggg","weekYear"),ln("GGGG","isoWeekYear"),ln("GGGGG","isoWeekYear"),j("weekYear","gg"),j("isoWeekYear","GG"),W("weekYear",1),W("isoWeekYear",1),pt("G",lt),pt("g",lt),pt("GG",nt,K),pt("gg",nt,K),pt("GGGG",st,tt),pt("gggg",st,tt),pt("GGGGG",ot,et),pt("ggggg",ot,et),_t(["gggg","ggggg","GGGG","GGGGG"],(function(t,e,n,i){e[i.substr(0,2)]=V(t)})),_t(["gg","GG"],(function(t,e,n,r){e[r]=i.parseTwoDigitYear(t)})),F("Q",0,"Qo","quarter"),j("quarter","Q"),W("quarter",7),pt("Q",Q),bt("Q",(function(t,e){e[kt]=3*(V(t)-1)})),F("D",["DD",2],"Do","date"),j("date","D"),W("date",9),pt("D",nt),pt("DD",nt,K),pt("Do",(function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient})),bt(["D","DD"],wt),bt("Do",(function(t,e){e[wt]=V(t.match(nt)[0])})),st=G("Date",!0),F("DDD",["DDDD",3],"DDDo","dayOfYear"),j("dayOfYear","DDD"),W("dayOfYear",4),pt("DDD",at),pt("DDDD",J),bt(["DDD","DDDD"],(function(t,e,n){n._dayOfYear=V(t)})),F("m",["mm",2],0,"minute"),j("minute","m"),W("minute",14),pt("m",nt),pt("mm",nt,K),bt(["m","mm"],Ct),tt=G("Minutes",!1),F("s",["ss",2],0,"second"),j("second","s"),W("second",15),pt("s",nt),pt("ss",nt,K),bt(["s","ss"],Et),ot=G("Seconds",!1),F("S",0,0,(function(){return~~(this.millisecond()/100)})),F(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),F(0,["SSS",3],0,"millisecond"),F(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),F(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),F(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),F(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),F(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),F(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),j("millisecond","ms"),W("millisecond",16),pt("S",at,Q),pt("SS",at,K),pt("SSS",at,J),en="SSSS";en.length<=9;en+="S")pt(en,ct);function un(t,e){e[St]=V(1e3*("0."+t))}for(en="S";en.length<=9;en+="S")bt(en,un);function dn(t){return t}function pn(t,e,n,i){var r=pe();return i=p().set(i,e),r[n](i,t)}function fn(t,e,n){if(l(t)&&(e=t,t=void 0),t=t||"",null!=e)return pn(t,e,n,"month");for(var i=[],r=0;r<12;r++)i[r]=pn(t,r,n,"month");return i}function gn(t,e,n,i){"boolean"==typeof t?l(e)&&(n=e,e=void 0):(e=t,t=!1,l(n=e)&&(n=e,e=void 0)),e=e||"";var r,a=pe(),s=t?a._week.dow:0,o=[];if(null!=n)return pn(e,(n+s)%7,i,"day");for(r=0;r<7;r++)o[r]=pn(e,(r+s)%7,i,"day");return o}et=G("Milliseconds",!1),F("z",0,0,"zoneAbbr"),F("zz",0,0,"zoneName"),(Q=v.prototype).add=Nt,Q.calendar=function(t,e){1===arguments.length&&(arguments[0]?Qe(arguments[0])?(t=arguments[0],e=void 0):function(t){for(var e=a(t)&&!o(t),n=!1,i=["sameDay","nextDay","lastDay","nextWeek","lastWeek","sameElse"],r=0;r<i.length;r+=1)n=n||s(t,i[r]);return e&&n}(arguments[0])&&(e=arguments[0],t=void 0):e=t=void 0);var n=je(t=t||Ne(),this).startOf("day");return n=i.calendarFormat(this,n)||"sameElse",e=e&&(S(e[n])?e[n].call(this,t):e[n]),this.format(e||this.localeData().calendar(n,this,Ne(t)))},Q.clone=function(){return new v(this)},Q.diff=function(t,e,n){var i,r,a;if(!this.isValid())return NaN;if(!(i=je(t,this)).isValid())return NaN;switch(r=6e4*(i.utcOffset()-this.utcOffset()),e=Y(e)){case"year":a=Ke(this,i)/12;break;case"month":a=Ke(this,i);break;case"quarter":a=Ke(this,i)/3;break;case"second":a=(this-i)/1e3;break;case"minute":a=(this-i)/6e4;break;case"hour":a=(this-i)/36e5;break;case"day":a=(this-i-r)/864e5;break;case"week":a=(this-i-r)/6048e5;break;default:a=this-i}return n?a:q(a)},Q.endOf=function(t){var e,n;if(void 0===(t=Y(t))||"millisecond"===t||!this.isValid())return this;switch(n=this._isUTC?sn:an,t){case"year":e=n(this.year()+1,0,1)-1;break;case"quarter":e=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":e=n(this.year(),this.month()+1,1)-1;break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":e=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":e=this._d.valueOf(),e+=36e5-rn(e+(this._isUTC?0:6e4*this.utcOffset()),36e5)-1;break;case"minute":e=this._d.valueOf(),e+=6e4-rn(e,6e4)-1;break;case"second":e=this._d.valueOf(),e+=1e3-rn(e,1e3)-1}return this._d.setTime(e),i.updateOffset(this,!0),this},Q.format=function(t){return t=R(this,t=t||(this.isUtc()?i.defaultFormatUtc:i.defaultFormat)),this.localeData().postformat(t)},Q.from=function(t,e){return this.isValid()&&(k(t)&&t.isValid()||Ne(t).isValid())?He({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},Q.fromNow=function(t){return this.from(Ne(),t)},Q.to=function(t,e){return this.isValid()&&(k(t)&&t.isValid()||Ne(t).isValid())?He({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},Q.toNow=function(t){return this.to(Ne(),t)},Q.get=function(t){return S(this[t=Y(t)])?this[t]():this},Q.invalidAt=function(){return f(this).overflow},Q.isAfter=function(t,e){return t=k(t)?t:Ne(t),!(!this.isValid()||!t.isValid())&&("millisecond"===(e=Y(e)||"millisecond")?this.valueOf()>t.valueOf():t.valueOf()<this.clone().startOf(e).valueOf())},Q.isBefore=function(t,e){return t=k(t)?t:Ne(t),!(!this.isValid()||!t.isValid())&&("millisecond"===(e=Y(e)||"millisecond")?this.valueOf()<t.valueOf():this.clone().endOf(e).valueOf()<t.valueOf())},Q.isBetween=function(t,e,n,i){return t=k(t)?t:Ne(t),e=k(e)?e:Ne(e),!!(this.isValid()&&t.isValid()&&e.isValid())&&("("===(i=i||"()")[0]?this.isAfter(t,n):!this.isBefore(t,n))&&(")"===i[1]?this.isBefore(e,n):!this.isAfter(e,n))},Q.isSame=function(t,e){return t=k(t)?t:Ne(t),!(!this.isValid()||!t.isValid())&&("millisecond"===(e=Y(e)||"millisecond")?this.valueOf()===t.valueOf():(t=t.valueOf(),this.clone().startOf(e).valueOf()<=t&&t<=this.clone().endOf(e).valueOf()))},Q.isSameOrAfter=function(t,e){return this.isSame(t,e)||this.isAfter(t,e)},Q.isSameOrBefore=function(t,e){return this.isSame(t,e)||this.isBefore(t,e)},Q.isValid=function(){return g(this)},Q.lang=Zt,Q.locale=Je,Q.localeData=tn,Q.max=rt,Q.min=it,Q.parsingFlags=function(){return d({},f(this))},Q.set=function(t,e){if("object"==typeof t)for(var n=function(t){var e,n=[];for(e in t)s(t,e)&&n.push({unit:e,priority:U[e]});return n.sort((function(t,e){return t.priority-e.priority})),n}(t=z(t)),i=n.length,r=0;r<i;r++)this[n[r].unit](t[n[r].unit]);else if(S(this[t=Y(t)]))return this[t](e);return this},Q.startOf=function(t){var e,n;if(void 0===(t=Y(t))||"millisecond"===t||!this.isValid())return this;switch(n=this._isUTC?sn:an,t){case"year":e=n(this.year(),0,1);break;case"quarter":e=n(this.year(),this.month()-this.month()%3,1);break;case"month":e=n(this.year(),this.month(),1);break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":e=n(this.year(),this.month(),this.date());break;case"hour":e=this._d.valueOf(),e-=rn(e+(this._isUTC?0:6e4*this.utcOffset()),36e5);break;case"minute":e=this._d.valueOf(),e-=rn(e,6e4);break;case"second":e=this._d.valueOf(),e-=rn(e,1e3)}return this._d.setTime(e),i.updateOffset(this,!0),this},Q.subtract=Gt,Q.toArray=function(){var t=this;return[t.year(),t.month(),t.date(),t.hour(),t.minute(),t.second(),t.millisecond()]},Q.toObject=function(){var t=this;return{years:t.year(),months:t.month(),date:t.date(),hours:t.hours(),minutes:t.minutes(),seconds:t.seconds(),milliseconds:t.milliseconds()}},Q.toDate=function(){return new Date(this.valueOf())},Q.toISOString=function(t){if(!this.isValid())return null;var e=(t=!0!==t)?this.clone().utc():this;return e.year()<0||9999<e.year()?R(e,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):S(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",R(e,"Z")):R(e,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},Q.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t,e="moment",n="";return this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",n="Z"),e="["+e+'("]',t=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",this.format(e+t+"-MM-DD[T]HH:mm:ss.SSS"+n+'[")]')},"undefined"!=typeof Symbol&&null!=Symbol.for&&(Q[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"}),Q.toJSON=function(){return this.isValid()?this.toISOString():null},Q.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},Q.unix=function(){return Math.floor(this.valueOf()/1e3)},Q.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},Q.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},Q.eraName=function(){for(var t,e=this.localeData().eras(),n=0,i=e.length;n<i;++n){if(t=this.clone().startOf("day").valueOf(),e[n].since<=t&&t<=e[n].until)return e[n].name;if(e[n].until<=t&&t<=e[n].since)return e[n].name}return""},Q.eraNarrow=function(){for(var t,e=this.localeData().eras(),n=0,i=e.length;n<i;++n){if(t=this.clone().startOf("day").valueOf(),e[n].since<=t&&t<=e[n].until)return e[n].narrow;if(e[n].until<=t&&t<=e[n].since)return e[n].narrow}return""},Q.eraAbbr=function(){for(var t,e=this.localeData().eras(),n=0,i=e.length;n<i;++n){if(t=this.clone().startOf("day").valueOf(),e[n].since<=t&&t<=e[n].until)return e[n].abbr;if(e[n].until<=t&&t<=e[n].since)return e[n].abbr}return""},Q.eraYear=function(){for(var t,e,n=this.localeData().eras(),r=0,a=n.length;r<a;++r)if(t=n[r].since<=n[r].until?1:-1,e=this.clone().startOf("day").valueOf(),n[r].since<=e&&e<=n[r].until||n[r].until<=e&&e<=n[r].since)return(this.year()-i(n[r].since).year())*t+n[r].offset;return this.year()},Q.year=jt,Q.isLeapYear=function(){return H(this.year())},Q.weekYear=function(t){return hn.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},Q.isoWeekYear=function(t){return hn.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},Q.quarter=Q.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},Q.month=Rt,Q.daysInMonth=function(){return Lt(this.year(),this.month())},Q.week=Q.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},Q.isoWeek=Q.isoWeeks=function(t){var e=Ht(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},Q.weeksInYear=function(){var t=this.localeData()._week;return qt(this.year(),t.dow,t.doy)},Q.weeksInWeekYear=function(){var t=this.localeData()._week;return qt(this.weekYear(),t.dow,t.doy)},Q.isoWeeksInYear=function(){return qt(this.year(),1,4)},Q.isoWeeksInISOWeekYear=function(){return qt(this.isoWeekYear(),1,4)},Q.date=st,Q.day=Q.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e,n,i=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(e=t,n=this.localeData(),t="string"!=typeof e?e:isNaN(e)?"number"==typeof(e=n.weekdaysParse(e))?e:null:parseInt(e,10),this.add(t-i,"d")):i},Q.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},Q.isoWeekday=function(t){return this.isValid()?null!=t?(e=t,n=this.localeData(),n="string"==typeof e?n.weekdaysParse(e)%7||7:isNaN(e)?null:e,this.day(this.day()%7?n:n-7)):this.day()||7:null!=t?this:NaN;var e,n},Q.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},Q.hour=Q.hours=dt,Q.minute=Q.minutes=tt,Q.second=Q.seconds=ot,Q.millisecond=Q.milliseconds=et,Q.utcOffset=function(t,e,n){var r,a=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null==t)return this._isUTC?a:Ye(this);if("string"==typeof t){if(null===(t=Pe(ut,t)))return this}else Math.abs(t)<16&&!n&&(t*=60);return!this._isUTC&&e&&(r=Ye(this)),this._offset=t,this._isUTC=!0,null!=r&&this.add(r,"m"),a!==t&&(!e||this._changeInProgress?Xe(this,He(t-a,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,i.updateOffset(this,!0),this._changeInProgress=null)),this},Q.utc=function(t){return this.utcOffset(0,t)},Q.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ye(this),"m")),this},Q.parseZone=function(){var t;return null!=this._tzm?this.utcOffset(this._tzm,!1,!0):"string"==typeof this._i&&(null!=(t=Pe(ht,this._i))?this.utcOffset(t):this.utcOffset(0,!0)),this},Q.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Ne(t).utcOffset():0,(this.utcOffset()-t)%60==0)},Q.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},Q.isLocal=function(){return!!this.isValid()&&!this._isUTC},Q.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},Q.isUtc=ze,Q.isUTC=ze,Q.zoneAbbr=function(){return this._isUTC?"UTC":""},Q.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},Q.dates=T("dates accessor is deprecated. Use date instead.",st),Q.months=T("months accessor is deprecated. Use month instead",Rt),Q.years=T("years accessor is deprecated. Use year instead",jt),Q.zone=T("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(t,e){return null!=t?(this.utcOffset(t="string"!=typeof t?-t:t,e),this):-this.utcOffset()})),Q.isDSTShifted=T("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!c(this._isDSTShifted))return this._isDSTShifted;var t,e={};return x(e,this),(e=De(e))._a?(t=(e._isUTC?p:Ne)(e._a),this._isDSTShifted=this.isValid()&&0<function(t,e,n){for(var i=Math.min(t.length,e.length),r=Math.abs(t.length-e.length),a=0,s=0;s<i;s++)(n&&t[s]!==e[s]||!n&&V(t[s])!==V(e[s]))&&a++;return a+r}(e._a,t.toArray())):this._isDSTShifted=!1,this._isDSTShifted})),(K=D.prototype).calendar=function(t,e,n){return S(t=this._calendar[t]||this._calendar.sameElse)?t.call(e,n):t},K.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.match(O).map((function(t){return"MMMM"===t||"MM"===t||"DD"===t||"dddd"===t?t.slice(1):t})).join(""),this._longDateFormat[t])},K.invalidDate=function(){return this._invalidDate},K.ordinal=function(t){return this._ordinal.replace("%d",t)},K.preparse=dn,K.postformat=dn,K.relativeTime=function(t,e,n,i){var r=this._relativeTime[n];return S(r)?r(t,e,n,i):r.replace(/%d/i,t)},K.pastFuture=function(t,e){return S(t=this._relativeTime[0<t?"future":"past"])?t(e):t.replace(/%s/i,e)},K.set=function(t){var e,n;for(n in t)s(t,n)&&(S(e=t[n])?this[n]=e:this["_"+n]=e);this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},K.eras=function(t,e){for(var n,r=this._eras||pe("en")._eras,a=0,s=r.length;a<s;++a)switch("string"==typeof r[a].since&&(n=i(r[a].since).startOf("day"),r[a].since=n.valueOf()),typeof r[a].until){case"undefined":r[a].until=1/0;break;case"string":n=i(r[a].until).startOf("day").valueOf(),r[a].until=n.valueOf()}return r},K.erasParse=function(t,e,n){var i,r,a,s,o,c=this.eras();for(t=t.toUpperCase(),i=0,r=c.length;i<r;++i)if(a=c[i].name.toUpperCase(),s=c[i].abbr.toUpperCase(),o=c[i].narrow.toUpperCase(),n)switch(e){case"N":case"NN":case"NNN":if(s===t)return c[i];break;case"NNNN":if(a===t)return c[i];break;case"NNNNN":if(o===t)return c[i]}else if(0<=[a,s,o].indexOf(t))return c[i]},K.erasConvertYear=function(t,e){var n=t.since<=t.until?1:-1;return void 0===e?i(t.since).year():i(t.since).year()+(e-t.offset)*n},K.erasAbbrRegex=function(t){return s(this,"_erasAbbrRegex")||cn.call(this),t?this._erasAbbrRegex:this._erasRegex},K.erasNameRegex=function(t){return s(this,"_erasNameRegex")||cn.call(this),t?this._erasNameRegex:this._erasRegex},K.erasNarrowRegex=function(t){return s(this,"_erasNarrowRegex")||cn.call(this),t?this._erasNarrowRegex:this._erasRegex},K.months=function(t,e){return t?(r(this._months)?this._months:this._months[(this._months.isFormat||Bt).test(e)?"format":"standalone"])[t.month()]:r(this._months)?this._months:this._months.standalone},K.monthsShort=function(t,e){return t?(r(this._monthsShort)?this._monthsShort:this._monthsShort[Bt.test(e)?"format":"standalone"])[t.month()]:r(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},K.monthsParse=function(t,e,n){var i,r;if(this._monthsParseExact)return function(t,e,n){var i,r,a;if(t=t.toLocaleLowerCase(),!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],i=0;i<12;++i)a=p([2e3,i]),this._shortMonthsParse[i]=this.monthsShort(a,"").toLocaleLowerCase(),this._longMonthsParse[i]=this.months(a,"").toLocaleLowerCase();return n?"MMM"===e?-1!==(r=xt.call(this._shortMonthsParse,t))?r:null:-1!==(r=xt.call(this._longMonthsParse,t))?r:null:"MMM"===e?-1!==(r=xt.call(this._shortMonthsParse,t))||-1!==(r=xt.call(this._longMonthsParse,t))?r:null:-1!==(r=xt.call(this._longMonthsParse,t))||-1!==(r=xt.call(this._shortMonthsParse,t))?r:null}.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(r=p([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(r,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(r,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(r,"")+"|^"+this.monthsShort(r,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}},K.monthsRegex=function(t){return this._monthsParseExact?(s(this,"_monthsRegex")||$t.call(this),t?this._monthsStrictRegex:this._monthsRegex):(s(this,"_monthsRegex")||(this._monthsRegex=It),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},K.monthsShortRegex=function(t){return this._monthsParseExact?(s(this,"_monthsRegex")||$t.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(s(this,"_monthsShortRegex")||(this._monthsShortRegex=Mt),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},K.week=function(t){return Ht(t,this._week.dow,this._week.doy).week},K.firstDayOfYear=function(){return this._week.doy},K.firstDayOfWeek=function(){return this._week.dow},K.weekdays=function(t,e){return e=r(this._weekdays)?this._weekdays:this._weekdays[t&&!0!==t&&this._weekdays.isFormat.test(e)?"format":"standalone"],!0===t?Vt(e,this._week.dow):t?e[t.day()]:e},K.weekdaysMin=function(t){return!0===t?Vt(this._weekdaysMin,this._week.dow):t?this._weekdaysMin[t.day()]:this._weekdaysMin},K.weekdaysShort=function(t){return!0===t?Vt(this._weekdaysShort,this._week.dow):t?this._weekdaysShort[t.day()]:this._weekdaysShort},K.weekdaysParse=function(t,e,n){var i,r;if(this._weekdaysParseExact)return function(t,e,n){var i,r,a;if(t=t.toLocaleLowerCase(),!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)a=p([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(a,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(a,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(a,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(r=xt.call(this._weekdaysParse,t))?r:null:"ddd"===e?-1!==(r=xt.call(this._shortWeekdaysParse,t))?r:null:-1!==(r=xt.call(this._minWeekdaysParse,t))?r:null:"dddd"===e?-1!==(r=xt.call(this._weekdaysParse,t))||-1!==(r=xt.call(this._shortWeekdaysParse,t))||-1!==(r=xt.call(this._minWeekdaysParse,t))?r:null:"ddd"===e?-1!==(r=xt.call(this._shortWeekdaysParse,t))||-1!==(r=xt.call(this._weekdaysParse,t))||-1!==(r=xt.call(this._minWeekdaysParse,t))?r:null:-1!==(r=xt.call(this._minWeekdaysParse,t))||-1!==(r=xt.call(this._weekdaysParse,t))||-1!==(r=xt.call(this._shortWeekdaysParse,t))?r:null}.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(r=p([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(r,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(r,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(r,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(r,"")+"|^"+this.weekdaysShort(r,"")+"|^"+this.weekdaysMin(r,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}},K.weekdaysRegex=function(t){return this._weekdaysParseExact?(s(this,"_weekdaysRegex")||te.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(s(this,"_weekdaysRegex")||(this._weekdaysRegex=Qt),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},K.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(s(this,"_weekdaysRegex")||te.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(s(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Kt),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},K.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(s(this,"_weekdaysRegex")||te.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(s(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Jt),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},K.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},K.meridiem=function(t,e,n){return 11<t?n?"pm":"PM":n?"am":"AM"},ue("en",{eras:[{since:"0001-01-01",until:1/0,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===V(t%100/10)?"th":1==e?"st":2==e?"nd":3==e?"rd":"th")}}),i.lang=T("moment.lang is deprecated. Use moment.locale instead.",ue),i.langData=T("moment.langData is deprecated. Use moment.localeData instead.",pe);var yn=Math.abs;function mn(t,e,n,i){return e=He(e,n),t._milliseconds+=i*e._milliseconds,t._days+=i*e._days,t._months+=i*e._months,t._bubble()}function bn(t){return t<0?Math.floor(t):Math.ceil(t)}function _n(t){return 4800*t/146097}function xn(t){return 146097*t/4800}function vn(t){return function(){return this.as(t)}}function kn(t){return function(){return this.isValid()?this._data[t]:NaN}}at=vn("ms"),J=vn("s"),Nt=vn("m"),rt=vn("h"),it=vn("d"),Gt=vn("w"),dt=vn("M"),tt=vn("Q"),ot=vn("y"),et=kn("milliseconds"),st=kn("seconds"),jt=kn("minutes"),K=kn("hours");var wn=kn("days"),Tn=kn("months"),Cn=kn("years"),En=Math.round,Sn={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function An(t,e,n,i){var r=He(t).abs(),a=En(r.as("s")),s=En(r.as("m")),o=En(r.as("h")),c=En(r.as("d")),l=En(r.as("M")),h=En(r.as("w"));return r=En(r.as("y")),a=(a<=n.ss?["s",a]:a<n.s&&["ss",a])||s<=1&&["m"]||s<n.m&&["mm",s]||o<=1&&["h"]||o<n.h&&["hh",o]||c<=1&&["d"]||c<n.d&&["dd",c],(a=(a=null!=n.w?a||h<=1&&["w"]||h<n.w&&["ww",h]:a)||l<=1&&["M"]||l<n.M&&["MM",l]||r<=1&&["y"]||["yy",r])[2]=e,a[3]=0<+t,a[4]=i,function(t,e,n,i,r){return r.relativeTime(e||1,!!n,t,i)}.apply(null,a)}var Dn=Math.abs;function Ln(t){return(0<t)-(t<0)||+t}function Nn(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n,i,r,a,s,o=Dn(this._milliseconds)/1e3,c=Dn(this._days),l=Dn(this._months),h=this.asSeconds();return h?(t=q(o/60),e=q(t/60),o%=60,t%=60,n=q(l/12),l%=12,i=o?o.toFixed(3).replace(/\.?0+$/,""):"",r=Ln(this._months)!==Ln(h)?"-":"",a=Ln(this._days)!==Ln(h)?"-":"",s=Ln(this._milliseconds)!==Ln(h)?"-":"",(h<0?"-":"")+"P"+(n?r+n+"Y":"")+(l?r+l+"M":"")+(c?a+c+"D":"")+(e||t||o?"T":"")+(e?s+e+"H":"")+(t?s+t+"M":"")+(o?s+i+"S":"")):"P0D"}var On=Me.prototype;return On.isValid=function(){return this._isValid},On.abs=function(){var t=this._data;return this._milliseconds=yn(this._milliseconds),this._days=yn(this._days),this._months=yn(this._months),t.milliseconds=yn(t.milliseconds),t.seconds=yn(t.seconds),t.minutes=yn(t.minutes),t.hours=yn(t.hours),t.months=yn(t.months),t.years=yn(t.years),this},On.add=function(t,e){return mn(this,t,e,1)},On.subtract=function(t,e){return mn(this,t,e,-1)},On.as=function(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=Y(t))||"quarter"===t||"year"===t)switch(e=this._days+i/864e5,n=this._months+_n(e),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(xn(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}},On.asMilliseconds=at,On.asSeconds=J,On.asMinutes=Nt,On.asHours=rt,On.asDays=it,On.asWeeks=Gt,On.asMonths=dt,On.asQuarters=tt,On.asYears=ot,On.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*V(this._months/12):NaN},On._bubble=function(){var t=this._milliseconds,e=this._days,n=this._months,i=this._data;return 0<=t&&0<=e&&0<=n||t<=0&&e<=0&&n<=0||(t+=864e5*bn(xn(n)+e),n=e=0),i.milliseconds=t%1e3,t=q(t/1e3),i.seconds=t%60,t=q(t/60),i.minutes=t%60,t=q(t/60),i.hours=t%24,e+=q(t/24),n+=t=q(_n(e)),e-=bn(xn(t)),t=q(n/12),n%=12,i.days=e,i.months=n,i.years=t,this},On.clone=function(){return He(this)},On.get=function(t){return t=Y(t),this.isValid()?this[t+"s"]():NaN},On.milliseconds=et,On.seconds=st,On.minutes=jt,On.hours=K,On.days=wn,On.weeks=function(){return q(this.days()/7)},On.months=Tn,On.years=Cn,On.humanize=function(t,e){if(!this.isValid())return this.localeData().invalidDate();var n=!1,i=Sn;return"object"==typeof t&&(e=t,t=!1),"boolean"==typeof t&&(n=t),"object"==typeof e&&(i=Object.assign({},Sn,e),null!=e.s&&null==e.ss&&(i.ss=e.s-1)),e=An(this,!n,i,t=this.localeData()),n&&(e=t.pastFuture(+this,e)),t.postformat(e)},On.toISOString=Nn,On.toString=Nn,On.toJSON=Nn,On.locale=Je,On.localeData=tn,On.toIsoString=T("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Nn),On.lang=Zt,F("X",0,0,"unix"),F("x",0,0,"valueOf"),pt("x",lt),pt("X",/[+-]?\d+(\.\d{1,3})?/),bt("X",(function(t,e,n){n._d=new Date(1e3*parseFloat(t))})),bt("x",(function(t,e,n){n._d=new Date(V(t))})),i.version="2.29.4",e=Ne,i.fn=Q,i.min=function(){return Oe("isBefore",[].slice.call(arguments,0))},i.max=function(){return Oe("isAfter",[].slice.call(arguments,0))},i.now=function(){return Date.now?Date.now():+new Date},i.utc=p,i.unix=function(t){return Ne(1e3*t)},i.months=function(t,e){return fn(t,e,"months")},i.isDate=h,i.locale=ue,i.invalid=y,i.duration=He,i.isMoment=k,i.weekdays=function(t,e,n){return gn(t,e,n,"weekdays")},i.parseZone=function(){return Ne.apply(null,arguments).parseZone()},i.localeData=pe,i.isDuration=Ie,i.monthsShort=function(t,e){return fn(t,e,"monthsShort")},i.weekdaysMin=function(t,e,n){return gn(t,e,n,"weekdaysMin")},i.defineLocale=de,i.updateLocale=function(t,e){var n,i;return null!=e?(i=ae,null!=se[t]&&null!=se[t].parentLocale?se[t].set(A(se[t]._config,e)):(e=A(i=null!=(n=he(t))?n._config:i,e),null==n&&(e.abbr=t),(i=new D(e)).parentLocale=se[t],se[t]=i),ue(t)):null!=se[t]&&(null!=se[t].parentLocale?(se[t]=se[t].parentLocale,t===ue()&&ue(t)):null!=se[t]&&delete se[t]),se[t]},i.locales=function(){return L(se)},i.weekdaysShort=function(t,e,n){return gn(t,e,n,"weekdaysShort")},i.normalizeUnits=Y,i.relativeTimeRounding=function(t){return void 0===t?En:"function"==typeof t&&(En=t,!0)},i.relativeTimeThreshold=function(t,e){return void 0!==Sn[t]&&(void 0===e?Sn[t]:(Sn[t]=e,"s"===t&&(Sn.ss=e-1),!0))},i.calendarFormat=function(t,e){return(t=t.diff(e,"days",!0))<-6?"sameElse":t<-1?"lastWeek":t<0?"lastDay":t<1?"sameDay":t<2?"nextDay":t<7?"nextWeek":"sameElse"},i.prototype=Q,i.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},i}()},87594:(t,e)=>{function n(t){let e,n=[];for(let i of t.split(",").map((t=>t.trim())))if(/^-?\d+$/.test(i))n.push(parseInt(i,10));else if(e=i.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[t,i,r,a]=e;if(i&&a){i=parseInt(i),a=parseInt(a);const t=i<a?1:-1;"-"!==r&&".."!==r&&"\u2025"!==r||(a+=t);for(let e=i;e!==a;e+=t)n.push(e)}}return n}e.default=n,t.exports=n}}]); \ No newline at end of file diff --git a/assets/js/41c44b28.32755fc9.js b/assets/js/41c44b28.32755fc9.js new file mode 100644 index 000000000..fd25ede57 --- /dev/null +++ b/assets/js/41c44b28.32755fc9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8106],{8819:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>l,toc:()=>o});var n=r(85893),i=r(3905);const s={title:"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",slug:"/test/benefit",last_update:{date:"2023/06/30"},tags:["test"]},c=void 0,l={id:"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",title:"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",description:"\ub514\ubc84\uae45 \uac10\uc18c",source:"@site/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd.mdx",sourceDirName:"\ud14c\uc2a4\ud2b8",slug:"/test/benefit",permalink:"/docs/test/benefit",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd.mdx",tags:[{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1688083200,formattedLastUpdatedAt:"2023\ub144 6\uc6d4 30\uc77c",frontMatter:{title:"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",slug:"/test/benefit",last_update:{date:"2023/06/30"},tags:["test"]},sidebar:"tutorialSidebar",previous:{title:"TDD heuristics",permalink:"/docs/test/heuristics"}},a={},o=[{value:"\ub514\ubc84\uae45 \uac10\uc18c",id:"\ub514\ubc84\uae45-\uac10\uc18c",level:3},{value:"\uc790\uc2e0 \uc788\uac8c \ubcc0\uacbd",id:"\uc790\uc2e0-\uc788\uac8c-\ubcc0\uacbd",level:3},{value:"\ub354 \ub098\uc740 \ubb38\uc11c \uc790\ub8cc",id:"\ub354-\ub098\uc740-\ubb38\uc11c-\uc790\ub8cc",level:3},{value:"\ub354 \ub2e8\uc21c\ud55c \ub9ac\ubdf0",id:"\ub354-\ub2e8\uc21c\ud55c-\ub9ac\ubdf0",level:3},{value:"\uc0ac\ub824 \uae4a\uc740 \uc124\uacc4",id:"\uc0ac\ub824-\uae4a\uc740-\uc124\uacc4",level:3},{value:"\uace0\ud488\uc9c8\uc758 \ub9b4\ub9ac\uc2a4\ub97c \ube60\ub974\uac8c",id:"\uace0\ud488\uc9c8\uc758-\ub9b4\ub9ac\uc2a4\ub97c-\ube60\ub974\uac8c",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={br:"br",code:"code",h3:"h3",p:"p",...(0,i.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\ub514\ubc84\uae45-\uac10\uc18c",children:"\ub514\ubc84\uae45 \uac10\uc18c"}),"\n",(0,n.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\ub97c \ud55c \ubc88 \uc791\uc131\ud574\ub450\uba74 \ud504\ub85c\uc81d\ud2b8\uc758 \uc0dd\uc874 \uc8fc\uae30\ub3d9\uc548 \uac12\ube44\uc2fc \uacb0\ud568\uc744 \uc608\ubc29\ud574 \uc900\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub610\ud55c \uc804\uccb4\uc801\uc778 \uacb0\ud568\uc774 \ud574\uacb0\ub418\uc5b4 \ub514\ubc84\uae45\uc5d0\uc11c \ud574\ubc29\uc2dc\ucf1c\uc900\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30\uc5d0\uc11c \uc5b8\uae09\ub41c ",(0,n.jsx)(t.code,{children:"TDD heuristics 15. \ub514\ubc84\uac70 \uc0ac\uc6a9\uc744 \ud53c\ud558\ub77c"})," \uc640 \uc5f0\uacb0\ub418\ub294 \ub0b4\uc6a9\uc774\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\uc790\uc2e0-\uc788\uac8c-\ubcc0\uacbd",children:"\uc790\uc2e0 \uc788\uac8c \ubcc0\uacbd"}),"\n",(0,n.jsxs)(t.p,{children:["\uc18c\ud504\ud2b8\uc6e8\uc5b4\ub294 \ud56d\uc0c1 \ubcc0\uacbd\ub41c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub9ac\ud329\ud130\ub9c1\ud560 \ub54c \uc790\uc2e0\uac10\uc744 \uac00\uc9c0\uace0 \ubcc0\uacbd \uc0ac\ud56d\uc744 \ubc18\uc601\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ub354-\ub098\uc740-\ubb38\uc11c-\uc790\ub8cc",children:"\ub354 \ub098\uc740 \ubb38\uc11c \uc790\ub8cc"}),"\n",(0,n.jsxs)(t.p,{children:["\ud558\ub098\uc758 \ud589\uc704\ub9cc \uc9d1\uc911\ud574 \uac80\uc99d\ud558\ub294 \ud14c\uc2a4\ud2b8\ub294 \uc2e4\ud589 \uac00\ub2a5\ud55c \ubb38\uc11c\uc640 \uac19\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc774 \ub54c \ud14c\uc2a4\ud2b8\ub294 \uba85\ud655\ud558\uace0 \uac04\uacb0\ud574\uc57c\uc9c0\ub9cc \ubb38\uc11c \uc790\ub8cc\ub85c\uc11c\uc758 \uc5ed\ud560\uc744 \ud6cc\ub96d\ud788 \uc218\ud589\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ub354-\ub2e8\uc21c\ud55c-\ub9ac\ubdf0",children:"\ub354 \ub2e8\uc21c\ud55c \ub9ac\ubdf0"}),"\n",(0,n.jsx)(t.p,{children:"\uc815\ud655\uc131, \uadf9\ub2e8 \uc0c1\ud669, \uc624\ub958 \uc0c1\ud669 \ub4f1\uc758 \ub2e4\uc591\ud55c \uce21\uba74\uc5d0\uc11c \ucf54\ub4dc\ub97c \uac80\uc0ac\ud574\uc8fc\ub294 \ud14c\uc2a4\ud2b8\uac00 \uc900\ube44\ub418\uc5b4 \uc788\ub2e4\uba74 \ub9ac\ubdf0\uc5b4\uac00 \uac80\uc99d\ud558\ub294 \uc2dc\uac04\uc744 \ud06c\uac8c \uc904\uc5ec\uc900\ub2e4."}),"\n",(0,n.jsx)(t.h3,{id:"\uc0ac\ub824-\uae4a\uc740-\uc124\uacc4",children:"\uc0ac\ub824 \uae4a\uc740 \uc124\uacc4"}),"\n",(0,n.jsxs)(t.p,{children:["\uc0c8\ub85c \uc791\uc131\ud55c \ucf54\ub4dc\uc758 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub294 \uc77c\uc740 \uc2e4\uc9c8\uc801\uc73c\ub85c \ud574\ub2f9 \ucf54\ub4dc\uc758 API\uac00 \uc798 \uc124\uacc4\ub418\uc5b4 \uc788\ub294\uc9c0\ub97c \uc2dc\ud5d8\ud558\ub294 \ud589\uc704\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud14c\uc2a4\ud2b8\ud558\uae30 \uc5b4\ub824\uc6b4 \ucf54\ub4dc\ub294 \ub108\ubb34 \ub9ce\uc740 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uac70\ub098, \uc758\uc874\uc131\uc774 \ubcf5\uc7a1\ud55c \uacbd\uc6b0\uac00 \ub9ce\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc798 \uc124\uacc4\ub41c \ucf54\ub4dc\ub77c\uba74 \ubaa8\ub4c8\ud654\uac00 \uc798 \ub418\uc5b4\uc788\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\uace0\ud488\uc9c8\uc758-\ub9b4\ub9ac\uc2a4\ub97c-\ube60\ub974\uac8c",children:"\uace0\ud488\uc9c8\uc758 \ub9b4\ub9ac\uc2a4\ub97c \ube60\ub974\uac8c"}),"\n",(0,n.jsx)(t.p,{children:"\uc790\ub3d9\ud654\ub41c \ud14c\uc2a4\ud2b8\ub97c \uac16\ucd98\ub2e4\uba74 \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc744 \ub9b4\ub9ac\uc2a4\ud560 \ub54c \ubd88\uc548\uc5d0 \ub5a8\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4."}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsx)(t.p,{children:"\uad6c\uae00 \uc5d4\uc9c0\ub2c8\uc5b4\ub294 \uc774\ub807\uac8c \uc77c\ud55c\ub2e4, \ud0c0\uc774\ud130\uc2a4 \uc708\ud130\uc2a4, \ud1b0 \ub9e8\uc26c\ub809, \ud558\uc774\ub7fc \ub77c\uc774\ud2b8 p.288"})]})}function u(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>o});var n=r(67294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?s(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var a=n.createContext({}),o=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,s=e.originalType,a=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=o(r),b=i,f=p["".concat(a,".").concat(b)]||p[b]||d[b]||s;return r?n.createElement(f,c(c({ref:t},u),{},{components:r})):n.createElement(f,c({ref:t},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/41c44b28.8fc30aac.js b/assets/js/41c44b28.8fc30aac.js deleted file mode 100644 index 599d4a5cf..000000000 --- a/assets/js/41c44b28.8fc30aac.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8106],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>f});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},l=Object.keys(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,p=e.parentName,s=o(e,["components","mdxType","originalType","parentName"]),d=c(r),f=a,m=d["".concat(p,".").concat(f)]||d[f]||u[f]||l;return r?n.createElement(m,i(i({ref:t},s),{},{components:r})):n.createElement(m,i({ref:t},s))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,i=new Array(l);i[0]=d;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o.mdxType="string"==typeof e?e:a,i[1]=o;for(var c=2;c<l;c++)i[c]=r[c];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},48272:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={title:"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",slug:"/test/benefit",last_update:{date:"2023/06/30"},tags:["test"]},i=void 0,o={unversionedId:"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",id:"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",title:"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",description:"\ub514\ubc84\uae45 \uac10\uc18c",source:"@site/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd.mdx",sourceDirName:"\ud14c\uc2a4\ud2b8",slug:"/test/benefit",permalink:"/docs/test/benefit",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd.mdx",tags:[{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1688083200,formattedLastUpdatedAt:"2023\ub144 6\uc6d4 30\uc77c",frontMatter:{title:"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",slug:"/test/benefit",last_update:{date:"2023/06/30"},tags:["test"]},sidebar:"tutorialSidebar",previous:{title:"TDD heuristics",permalink:"/docs/test/heuristics"}},p={},c=[{value:"\ub514\ubc84\uae45 \uac10\uc18c",id:"\ub514\ubc84\uae45-\uac10\uc18c",level:3},{value:"\uc790\uc2e0 \uc788\uac8c \ubcc0\uacbd",id:"\uc790\uc2e0-\uc788\uac8c-\ubcc0\uacbd",level:3},{value:"\ub354 \ub098\uc740 \ubb38\uc11c \uc790\ub8cc",id:"\ub354-\ub098\uc740-\ubb38\uc11c-\uc790\ub8cc",level:3},{value:"\ub354 \ub2e8\uc21c\ud55c \ub9ac\ubdf0",id:"\ub354-\ub2e8\uc21c\ud55c-\ub9ac\ubdf0",level:3},{value:"\uc0ac\ub824 \uae4a\uc740 \uc124\uacc4",id:"\uc0ac\ub824-\uae4a\uc740-\uc124\uacc4",level:3},{value:"\uace0\ud488\uc9c8\uc758 \ub9b4\ub9ac\uc2a4\ub97c \ube60\ub974\uac8c",id:"\uace0\ud488\uc9c8\uc758-\ub9b4\ub9ac\uc2a4\ub97c-\ube60\ub974\uac8c",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ub514\ubc84\uae45-\uac10\uc18c"},"\ub514\ubc84\uae45 \uac10\uc18c"),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\ub97c \ud55c \ubc88 \uc791\uc131\ud574\ub450\uba74 \ud504\ub85c\uc81d\ud2b8\uc758 \uc0dd\uc874 \uc8fc\uae30\ub3d9\uc548 \uac12\ube44\uc2fc \uacb0\ud568\uc744 \uc608\ubc29\ud574 \uc900\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \uc804\uccb4\uc801\uc778 \uacb0\ud568\uc774 \ud574\uacb0\ub418\uc5b4 \ub514\ubc84\uae45\uc5d0\uc11c \ud574\ubc29\uc2dc\ucf1c\uc900\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30\uc5d0\uc11c \uc5b8\uae09\ub41c ",(0,a.kt)("inlineCode",{parentName:"p"},"TDD heuristics 15. \ub514\ubc84\uac70 \uc0ac\uc6a9\uc744 \ud53c\ud558\ub77c")," \uc640 \uc5f0\uacb0\ub418\ub294 \ub0b4\uc6a9\uc774\ub2e4."),(0,a.kt)("h3",{id:"\uc790\uc2e0-\uc788\uac8c-\ubcc0\uacbd"},"\uc790\uc2e0 \uc788\uac8c \ubcc0\uacbd"),(0,a.kt)("p",null,"\uc18c\ud504\ud2b8\uc6e8\uc5b4\ub294 \ud56d\uc0c1 \ubcc0\uacbd\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ud329\ud130\ub9c1\ud560 \ub54c \uc790\uc2e0\uac10\uc744 \uac00\uc9c0\uace0 \ubcc0\uacbd \uc0ac\ud56d\uc744 \ubc18\uc601\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\ub354-\ub098\uc740-\ubb38\uc11c-\uc790\ub8cc"},"\ub354 \ub098\uc740 \ubb38\uc11c \uc790\ub8cc"),(0,a.kt)("p",null,"\ud558\ub098\uc758 \ud589\uc704\ub9cc \uc9d1\uc911\ud574 \uac80\uc99d\ud558\ub294 \ud14c\uc2a4\ud2b8\ub294 \uc2e4\ud589 \uac00\ub2a5\ud55c \ubb38\uc11c\uc640 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c \ud14c\uc2a4\ud2b8\ub294 \uba85\ud655\ud558\uace0 \uac04\uacb0\ud574\uc57c\uc9c0\ub9cc \ubb38\uc11c \uc790\ub8cc\ub85c\uc11c\uc758 \uc5ed\ud560\uc744 \ud6cc\ub96d\ud788 \uc218\ud589\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\ub354-\ub2e8\uc21c\ud55c-\ub9ac\ubdf0"},"\ub354 \ub2e8\uc21c\ud55c \ub9ac\ubdf0"),(0,a.kt)("p",null,"\uc815\ud655\uc131, \uadf9\ub2e8 \uc0c1\ud669, \uc624\ub958 \uc0c1\ud669 \ub4f1\uc758 \ub2e4\uc591\ud55c \uce21\uba74\uc5d0\uc11c \ucf54\ub4dc\ub97c \uac80\uc0ac\ud574\uc8fc\ub294 \ud14c\uc2a4\ud2b8\uac00 \uc900\ube44\ub418\uc5b4 \uc788\ub2e4\uba74 \ub9ac\ubdf0\uc5b4\uac00 \uac80\uc99d\ud558\ub294 \uc2dc\uac04\uc744 \ud06c\uac8c \uc904\uc5ec\uc900\ub2e4. "),(0,a.kt)("h3",{id:"\uc0ac\ub824-\uae4a\uc740-\uc124\uacc4"},"\uc0ac\ub824 \uae4a\uc740 \uc124\uacc4"),(0,a.kt)("p",null,"\uc0c8\ub85c \uc791\uc131\ud55c \ucf54\ub4dc\uc758 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub294 \uc77c\uc740 \uc2e4\uc9c8\uc801\uc73c\ub85c \ud574\ub2f9 \ucf54\ub4dc\uc758 API\uac00 \uc798 \uc124\uacc4\ub418\uc5b4 \uc788\ub294\uc9c0\ub97c \uc2dc\ud5d8\ud558\ub294 \ud589\uc704\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc2a4\ud2b8\ud558\uae30 \uc5b4\ub824\uc6b4 \ucf54\ub4dc\ub294 \ub108\ubb34 \ub9ce\uc740 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uac70\ub098, \uc758\uc874\uc131\uc774 \ubcf5\uc7a1\ud55c \uacbd\uc6b0\uac00 \ub9ce\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc798 \uc124\uacc4\ub41c \ucf54\ub4dc\ub77c\uba74 \ubaa8\ub4c8\ud654\uac00 \uc798 \ub418\uc5b4\uc788\uc5b4\uc57c \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uace0\ud488\uc9c8\uc758-\ub9b4\ub9ac\uc2a4\ub97c-\ube60\ub974\uac8c"},"\uace0\ud488\uc9c8\uc758 \ub9b4\ub9ac\uc2a4\ub97c \ube60\ub974\uac8c"),(0,a.kt)("p",null,"\uc790\ub3d9\ud654\ub41c \ud14c\uc2a4\ud2b8\ub97c \uac16\ucd98\ub2e4\uba74 \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc744 \ub9b4\ub9ac\uc2a4\ud560 \ub54c \ubd88\uc548\uc5d0 \ub5a8\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uad6c\uae00 \uc5d4\uc9c0\ub2c8\uc5b4\ub294 \uc774\ub807\uac8c \uc77c\ud55c\ub2e4, \ud0c0\uc774\ud130\uc2a4 \uc708\ud130\uc2a4, \ud1b0 \ub9e8\uc26c\ub809, \ud558\uc774\ub7fc \ub77c\uc774\ud2b8 p.288"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/42957a8d.205e0091.js b/assets/js/42957a8d.205e0091.js new file mode 100644 index 000000000..85c1e9490 --- /dev/null +++ b/assets/js/42957a8d.205e0091.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9312],{62206:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var n=r(85893),o=r(3905);const c={title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",slug:"mock-static-method",tags:["Mockito","static"]},i=void 0,a={permalink:"/mock-static-method",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",source:"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",description:"\uac1c\uc694",date:"2023-07-30T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 30\uc77c",tags:[{label:"Mockito",permalink:"/tags/mockito"},{label:"static",permalink:"/tags/static"}],readingTime:2.635,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",slug:"mock-static-method",tags:["Mockito","static"]},unlisted:!1,prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",permalink:"/route-image-python"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",permalink:"/route-image-intro"}},s={authorsImageUrls:[]},l=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"Mocking static methods",id:"mocking-static-methods",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function m(e){const t={a:"a",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",...(0,o.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,n.jsxs)(t.p,{children:["\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud55c\ub2e4\ub294 \uac83\uc740 \uac1d\uccb4\uc9c0\ud5a5\uc801\uc778 \uad00\uc810\uc5d0\uc11c \ubcfc \ub54c \uc548\ud2f0\ud328\ud134\uc774\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud558\uc9c0\ub9cc \ud2b9\uc218\ud55c \uacbd\uc6b0\uc5d0\ub294 \uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc774 \ud544\uc694\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.p,{children:"\uc608\ub97c \ub4e4\uc5b4 \ub808\uac70\uc2dc \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud55c\ub2e4\ub358\uc9c0, IO \uad00\ub828\ud55c \ubd80\ubd84\uc744 \ud14c\uc2a4\ud2b8 \ud560 \ub54c \uc815\ub9d0 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\ub9cc \uc801\uc6a9\ud560 \uc218 \uc788\uc744 \uac83\uc774\ub2e4."}),"\n",(0,n.jsxs)(t.p,{children:["\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba70 ImageIo.write \uba54\uc11c\ub4dc\uac00 \ud638\ucd9c\ub418\ub294 \uc9c0 \uac80\uc99d\uc774 \ud544\uc694\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud574\ub2f9 static \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294 \ubd80\ubd84\uc744 \ub530\ub85c RouteImageUploader \ud074\ub798\uc2a4\ub85c \ucd5c\ub300\ud55c \ubd84\ub9ac\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc800\uc7a5 \uae30\ub2a5 \uc790\uccb4\uac00 \uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc774\uace0, \ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc0ac\ud558\ub294\ub370\ub294 mock\uc744 \uc0ac\uc6a9\ud558\ub294\uac8c \uc801\uc808\ud558\ub2e4\uace0 \ud310\ub2e8\ud588\ub2e4."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-java",children:"public void upload(BufferedImage bufferedImage) {\n File file = new File(\ud30c\uc77c\uacbd\ub85c);\n try {\n ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);\n } catch (IOException e) {\n throw new DrawException(IMAGE_SAVE_FAIL);\n }\n}\n"})}),"\n",(0,n.jsx)(t.h3,{id:"mocking-static-methods",children:"Mocking static methods"}),"\n",(0,n.jsxs)(t.p,{children:["Mockito 3.4.0 \uc774\ud6c4\uc5d0\ub294 static method\ub97c \ubaa8\ud0b9\ud560 \uc218 \uc788\ub294 Mockito.mockStatic \uba54\uc11c\ub4dc\ub97c \uc9c0\uc6d0\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","mockStatic\uc744 \uc0ac\uc6a9\ud558\uba74 ",(0,n.jsx)(t.code,{children:"MockedStatic<T>"}),"\uc774 \ubc18\ud658\ub418\ub294\ub370 \uc0ac\uc6a9 \ud6c4 \uaf2d close\ub97c \ud574\uc918\uc57c \ud55c\ub2e4."]}),"\n",(0,n.jsxs)(t.p,{children:["JUnit\uc758 @BeforeAll\ub85c \uc124\uc815\ud558\uace0 @AfterAll \uba54\uc11c\ub4dc\ub85c \uc885\ub8cc\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\uc9c0\ub9cc ",(0,n.jsx)(t.code,{children:"MockedStatic<T>"}),"\uc758 \uc0c1\uc704 \uc778\ud130\ud398\uc774\uc2a4\uc778 ScopedMock\uc774 AutoCloseable\uc744 \uad6c\ud604\ud558\uace0 \uc788\uae30\uc5d0 try-with-resources\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \ub354\uc6b1 \uc88b\uc740 \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-java",children:"// given\nBufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);\nRouteImageUploader routeImageUploader = new RouteImageUploader();\n\n// expect\ntry (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {\n routeImageUploader.upload(bufferedImage);\n imageIO.verify(\n () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),\n times(1)\n );\n}\n"})}),"\n",(0,n.jsx)(t.h3,{id:"\ub9c8\uce58\uba70",children:"\ub9c8\uce58\uba70"}),"\n",(0,n.jsxs)(t.p,{children:["\uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc740 \uc548\ud2f0\ud328\ud134\uc774\uc73c\ub85c \uc801\uc808\ud55c \ucd94\uc0c1\ud654\ub97c \uc774\uc6a9\ud574 \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc88b\uc740 \ucf54\ub4dc\ub97c \ub9cc\ub4dc\ub294 \uc5f0\uc2b5\uc744 \ud558\uc790.",(0,n.jsx)(t.br,{}),"\n","\ud558\uc9c0\ub9cc \ucd94\uc0c1\ud654\ub97c \ud558\uba74 \ud560 \uc218\ub85d \ucf54\ub4dc\uc758 \ubcf5\uc7a1\ub3c4\ub294 \uc99d\uac00\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud56d\uc0c1 \uc0c1\ud669\uc744 \uace0\ub824\ud558\uace0 \uac04\uacb0\ud568\uc744 \ud3ec\uae30\ud560 \ub9cc\ud07c \uc911\uc694\ud55c \ubd80\ubd84\uc778\uc9c0 \uc801\uc808\ud55c \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uace0\ub824\ud558\uc790."]}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks",children:"Mocking static methods"}),(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.a,{href:"https://www.baeldung.com/mockito-mock-static-methods",children:"Mockito mock static methods"}),(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.a,{href:"https://github.com/mockito/mockito/issues/1013",children:"Enable mocking static methods in Mockito"})]})]})}function d(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(m,{...e})}):m(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?c(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):c(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},c=Object.keys(e);for(n=0;n<c.length;n++)r=c[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(n=0;n<c.length;n++)r=c[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,c=e.originalType,s=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),u=l(r),p=o,g=u["".concat(s,".").concat(p)]||u[p]||m[p]||c;return r?n.createElement(g,i(i({ref:t},d),{},{components:r})):n.createElement(g,i({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/42957a8d.eb9b613e.js b/assets/js/42957a8d.eb9b613e.js deleted file mode 100644 index f25f6fcb0..000000000 --- a/assets/js/42957a8d.eb9b613e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9312],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>k});var a=r(67294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,a,n=function(e,t){if(null==e)return{};var r,a,n={},o=Object.keys(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),m=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=m(e.components);return a.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=m(r),k=n,d=u["".concat(l,".").concat(k)]||u[k]||s[k]||o;return r?a.createElement(d,i(i({ref:t},p),{},{components:r})):a.createElement(d,i({ref:t},p))}));function k(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=u;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:n,i[1]=c;for(var m=2;m<o;m++)i[m]=r[m];return a.createElement.apply(null,i)}return a.createElement.apply(null,r)}u.displayName="MDXCreateElement"},1335:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>s,frontMatter:()=>o,metadata:()=>c,toc:()=>m});var a=r(87462),n=(r(67294),r(3905));const o={title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",slug:"mock-static-method",tags:["Mockito","static"]},i=void 0,c={permalink:"/mock-static-method",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",source:"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",description:"\uac1c\uc694",date:"2023-07-30T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 30\uc77c",tags:[{label:"Mockito",permalink:"/tags/mockito"},{label:"static",permalink:"/tags/static"}],readingTime:2.635,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",slug:"mock-static-method",tags:["Mockito","static"]},prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",permalink:"/route-image-python"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",permalink:"/route-image-intro"}},l={authorsImageUrls:[]},m=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"Mocking static methods",id:"mocking-static-methods",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],p={toc:m};function s(e){let{components:t,...r}=e;return(0,n.kt)("wrapper",(0,a.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h3",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,n.kt)("p",null,"\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud55c\ub2e4\ub294 \uac83\uc740 \uac1d\uccb4\uc9c0\ud5a5\uc801\uc778 \uad00\uc810\uc5d0\uc11c \ubcfc \ub54c \uc548\ud2f0\ud328\ud134\uc774\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ud2b9\uc218\ud55c \uacbd\uc6b0\uc5d0\ub294 \uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc774 \ud544\uc694\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,n.kt)("p",null,"\uc608\ub97c \ub4e4\uc5b4 \ub808\uac70\uc2dc \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud55c\ub2e4\ub358\uc9c0, IO \uad00\ub828\ud55c \ubd80\ubd84\uc744 \ud14c\uc2a4\ud2b8 \ud560 \ub54c \uc815\ub9d0 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\ub9cc \uc801\uc6a9\ud560 \uc218 \uc788\uc744 \uac83\uc774\ub2e4. "),(0,n.kt)("p",null,"\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba70 ImageIo.write \uba54\uc11c\ub4dc\uac00 \ud638\ucd9c\ub418\ub294 \uc9c0 \uac80\uc99d\uc774 \ud544\uc694\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 static \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294 \ubd80\ubd84\uc744 \ub530\ub85c RouteImageUploader \ud074\ub798\uc2a4\ub85c \ucd5c\ub300\ud55c \ubd84\ub9ac\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc800\uc7a5 \uae30\ub2a5 \uc790\uccb4\uac00 \uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc774\uace0, \ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc0ac\ud558\ub294\ub370\ub294 mock\uc744 \uc0ac\uc6a9\ud558\ub294\uac8c \uc801\uc808\ud558\ub2e4\uace0 \ud310\ub2e8\ud588\ub2e4. "),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},"public void upload(BufferedImage bufferedImage) {\n File file = new File(\ud30c\uc77c\uacbd\ub85c);\n try {\n ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);\n } catch (IOException e) {\n throw new DrawException(IMAGE_SAVE_FAIL);\n }\n}\n")),(0,n.kt)("h3",{id:"mocking-static-methods"},"Mocking static methods"),(0,n.kt)("p",null,"Mockito 3.4.0 \uc774\ud6c4\uc5d0\ub294 static method\ub97c \ubaa8\ud0b9\ud560 \uc218 \uc788\ub294 Mockito.mockStatic \uba54\uc11c\ub4dc\ub97c \uc9c0\uc6d0\ud55c\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","mockStatic\uc744 \uc0ac\uc6a9\ud558\uba74 ",(0,n.kt)("inlineCode",{parentName:"p"},"MockedStatic<T>"),"\uc774 \ubc18\ud658\ub418\ub294\ub370 \uc0ac\uc6a9 \ud6c4 \uaf2d close\ub97c \ud574\uc918\uc57c \ud55c\ub2e4. "),(0,n.kt)("p",null,"JUnit\uc758 @BeforeAll\ub85c \uc124\uc815\ud558\uace0 @AfterAll \uba54\uc11c\ub4dc\ub85c \uc885\ub8cc\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\uc9c0\ub9cc ",(0,n.kt)("inlineCode",{parentName:"p"},"MockedStatic<T>"),"\uc758 \uc0c1\uc704 \uc778\ud130\ud398\uc774\uc2a4\uc778 ScopedMock\uc774 AutoCloseable\uc744 \uad6c\ud604\ud558\uace0 \uc788\uae30\uc5d0 try-with-resources\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \ub354\uc6b1 \uc88b\uc740 \uac83 \uac19\ub2e4. "),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},"// given\nBufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);\nRouteImageUploader routeImageUploader = new RouteImageUploader();\n\n// expect\ntry (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {\n routeImageUploader.upload(bufferedImage);\n imageIO.verify(\n () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),\n times(1)\n );\n}\n")),(0,n.kt)("h3",{id:"\ub9c8\uce58\uba70"},"\ub9c8\uce58\uba70"),(0,n.kt)("p",null,"\uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc740 \uc548\ud2f0\ud328\ud134\uc774\uc73c\ub85c \uc801\uc808\ud55c \ucd94\uc0c1\ud654\ub97c \uc774\uc6a9\ud574 \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc88b\uc740 \ucf54\ub4dc\ub97c \ub9cc\ub4dc\ub294 \uc5f0\uc2b5\uc744 \ud558\uc790.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ucd94\uc0c1\ud654\ub97c \ud558\uba74 \ud560 \uc218\ub85d \ucf54\ub4dc\uc758 \ubcf5\uc7a1\ub3c4\ub294 \uc99d\uac00\ud55c\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \uc0c1\ud669\uc744 \uace0\ub824\ud558\uace0 \uac04\uacb0\ud568\uc744 \ud3ec\uae30\ud560 \ub9cc\ud07c \uc911\uc694\ud55c \ubd80\ubd84\uc778\uc9c0 \uc801\uc808\ud55c \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uace0\ub824\ud558\uc790. "),(0,n.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks"},"Mocking static methods"),(0,n.kt)("br",{parentName:"p"}),"\n",(0,n.kt)("a",{parentName:"p",href:"https://www.baeldung.com/mockito-mock-static-methods"},"Mockito mock static methods"),(0,n.kt)("br",{parentName:"p"}),"\n",(0,n.kt)("a",{parentName:"p",href:"https://github.com/mockito/mockito/issues/1013"},"Enable mocking static methods in Mockito")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/43fcf0e9.f85c5112.js b/assets/js/43fcf0e9.37211ee7.js similarity index 77% rename from assets/js/43fcf0e9.f85c5112.js rename to assets/js/43fcf0e9.37211ee7.js index 238d11bd0..7392b5c8d 100644 --- a/assets/js/43fcf0e9.f85c5112.js +++ b/assets/js/43fcf0e9.37211ee7.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6468],{94822:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6468],{94822:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/4430ab79.4a43f845.js b/assets/js/4430ab79.91bf9599.js similarity index 87% rename from assets/js/4430ab79.4a43f845.js rename to assets/js/4430ab79.91bf9599.js index 773660066..9d61f10b3 100644 --- a/assets/js/4430ab79.4a43f845.js +++ b/assets/js/4430ab79.91bf9599.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5553],{2750:e=>{e.exports=JSON.parse('{"label":"zero-downtime","permalink":"/docs/tags/zero-downtime","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","title":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","description":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","permalink":"/docs/deploy/zero-downtime"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5553],{2750:e=>{e.exports=JSON.parse('{"label":"zero-downtime","permalink":"/docs/tags/zero-downtime","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","title":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","description":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","permalink":"/docs/deploy/zero-downtime"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/4485017c.833a8ee1.js b/assets/js/4485017c.833a8ee1.js deleted file mode 100644 index c1a6c38eb..000000000 --- a/assets/js/4485017c.833a8ee1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1906],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>s});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),i=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},m=function(e){var t=i(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,c=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),k=i(r),s=a,b=k["".concat(c,".").concat(s)]||k[s]||u[s]||p;return r?n.createElement(b,o(o({ref:t},m),{},{components:r})):n.createElement(b,o({ref:t},m))}));function s(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=k;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var i=2;i<p;i++)o[i]=r[i];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}k.displayName="MDXCreateElement"},23224:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>p,metadata:()=>l,toc:()=>i});var n=r(87462),a=(r(67294),r(3905));const p={title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",slug:"blackjack-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,l={permalink:"/blackjack-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-blackjack/pull/427",date:"2023-03-14T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 14\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.17,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",slug:"blackjack-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",permalink:"/grasp"},nextItem:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",permalink:"/ladder-retrospective"}},c={authorsImageUrls:[]},i=[{value:"\ube14\ub799\uc7ad",id:"\ube14\ub799\uc7ad",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],m={toc:i};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-blackjack/pull/427"},"https://github.com/woowacourse/java-blackjack/pull/427"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-blackjack/pull/537"},"https://github.com/woowacourse/java-blackjack/pull/537")," ")),(0,a.kt)("h3",{id:"\ube14\ub799\uc7ad"},"\ube14\ub799\uc7ad"),(0,a.kt)("p",null,"\ube14\ub799\uc7ad \ubbf8\uc158\uc5d0\uc11c\ub294 \ud6c4\ucd94\uc640 \ud398\uc5b4(\uc870\ubbf8\ub8cc \ub4c0\uc624?)\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0\ub294 \uc2e4\uc218\ud558\uc9c0 \uc54a\uace0, \ubc14\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uc9c0 \uc54a\uace0 \uce5c\ud574\uc9c0\uae30 \ubd80\ud130 \uc2dc\uc791\ud588\ub2e4. "),(0,a.kt)("p",null,"\ube14\ub799\uc7ad\uc740 \uad6c\ud604\ud574\uc57c \ub420 \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud560 \uac83 \uac19\uc558\uc9c0\ub9cc",(0,a.kt)("br",{parentName:"p"}),"\n","\ud6c4\ucd94\uc640 \ud568\uaed8 \uc804\ub7b5\uc801(\uc0bc\uc77c\uc808\uc5d0 \ubbf8\uc158 \uc774\uc57c\uae30 \ub098\ub204\uae30)\uc73c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud574 \uc2dc\uac04 \ub0b4\uc5d0 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ubbf8\uc158\uc744 \ub05d\ub098\uace0 \ud68c\uace0\ub97c \ud588\uc744 \ub54c \ud6c4\ucd94\uac00 \uace0\ubbfc\uac70\ub9ac\ub97c \ud558\ub098 \ub0b4\uc92c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n",'"\ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \uc555\ubc15\uac10\uc744 \ub290\ub07c\ub294 \ud398\uc5b4\uac00 \uc788\ub2e4\uba74 \ud5c8\ube0c\uac00 \ud574\uc904 \uc218 \uc788\ub294\uac8c \ubb50\uac00 \uc788\uc744\uae4c?" '),(0,a.kt)("p",null,"\uacf0\uacf0\ud788 \uc0dd\uac01\ud574\ubd24\uc9c0\ub9cc \uc27d\uac8c \ub2f5\uc744 \ub0b4\ub9b4 \uc218 \uc5c6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04 \uc911\uac04 \ud68c\uace0\ub97c \ud558\uace0, \ub098\uc758 \uc18c\ud504\ud2b8\uc2a4\ud0ac\uc744 \ub192\ud788\ub294\uac8c \ub2f5\uc77c\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\ubd80\ub2f4\uac10\uc744 \ub290\ub07c\uc9c0 \uc54a\uace0 \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub420 \uc218 \uc788\ub3c4\ub85d \uacc4\uc18d \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4. "),(0,a.kt)("p",null,"\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc0dd\uac01\uc774 \ub9ce\uc544\uc838\uc11c \uc804 \ub9ac\ubdf0\uc5b4\uc778 \ud130\ud2c0\ud83d\udc22\uacfc\ub3c4 \ub300\ud654\ub97c \ub098\ub204\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud130\ud2c0\uc740 \uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84(\uad81\uadf9\uc801\uc778 \ubaa9\ud45c\uc778 \uc88b\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uac83)\uc5d0 \uc9d1\uc911\ud574\ubcf4\ub77c\uace0 \ud558\uc168\ub2e4. "),(0,a.kt)("p",null,"\uc88b\uc740 \ucf54\ub4dc, \uc88b\uc740 \ud398\uc5b4\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc77c\ub2e8 \uc9c0\uc18d\uc801\uc73c\ub85c \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4."),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud398\uc5b4 \uc2e0\uacbd\uc4f0\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \ud398\uc5b4\ud560 \ub54c \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub0b4\ubcf4\ub3c4\ub85d \ud588\ub2e4. \uadf8\ub807\uae30\uc5d0 \ub108\ubb34 \uc758\uacac\uc744 \uac15\ud558\uac8c \ubc00\uc5b4\ubd99\uc778 \ub290\ub08c\uc774 \ub4e4\uc5b4\uc11c \ubbf8\uc548\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud6c4\ucd94\uac00 \uc555\ubc15\uc744 \ub290\uaf08\uc744 \uc218\ub3c4 \uc788\uc744 \uac83 \uac19\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04 \uc911\uac04 \uc791\uc740 \ud68c\uace0\ub97c \uc9c4\ud589\ud574\ubcf4\ub294 \uac83\uc774 \uc88b\uc744\uae4c?"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uccb4\ub825 \uad00\ub9ac"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uc998 \uc798 \ubabb\uba39\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc0b4 \ub0a0\uc774 \ub9ce\uc740\ub370 \uc798 \ucc59\uaca8\uba39\uace0, \ud798\ub0b4\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc911\uac04 \uc911\uac04 \ub3cc\uc544\ubcf4\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \ubbf8\uc158\uacfc \uad00\ub828\ub41c \ub0b4\uc6a9\uc740 \uc544\ub2c8\uc9c0\ub9cc \uc6b0\ud14c\ucf54\ub97c \uc798 \ud65c\uc6a9 \ud558\uace0 \uc788\ub294\uc9c0 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \uc6b0\ud14c\ucf54\uc5d0 \uc9c0\uc6d0\ud55c \uc774\uc720\ub97c \ud56d\uc0c1 \uc78a\uc9c0 \uc54a\uc544\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc0c1\ud0dc \ud328\ud134"),(0,a.kt)("br",{parentName:"p"}),"\n","\uac1d\uccb4\uc758 \ub0b4\ubd80 \uc0c1\ud0dc\uc5d0 \ub530\ub77c \uc2a4\uc2a4\ub85c \ud589\ub3d9\uc744 \ubcc0\uacbd\ud558\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc73c\ub85c if/else/switch\uc640 \uac19\uc740 \uc870\uac74\ubb38\uc744 \ud6a8\uacfc\uc801\uc73c\ub85c \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube14\ub799\uc7ad \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc0c1\ud0dc \ud328\ud134\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ucc98\uc74c \uc801\uc6a9\ud574\ubcf4\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc98\uc74c \uc801\uc6a9\ud558\uae30 \uc804\uc5d0\ub294 \ubcc4\ub85c\ub77c\uace0 \uc0dd\uac01\ud588\ub294\ub370, \uc0dd\uac01\ubcf4\ub2e4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc77c\uad00\uc131, \uac00\ub3c5\uc131, \ucd94\uc0c1\ud654"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \ub9ac\ubdf0\uc5b4\ub294 \uac80\ud504\ud83c\udf6b \uc600\ub2e4!",(0,a.kt)("br",{parentName:"p"}),"\n","\uac80\ud504\uc758 \ub9ac\ubdf0\ub294 \uac04\uacb0\ud568\uc5d0 \uad00\ub828\ub41c \ub0b4\uc6a9\uc774 \ub9ce\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\uad00\uc131\uc774 \uc788\ub294 \ucf54\ub4dc, \uac00\ub3c5\uc131\uc774 \uc88b\uc740 \ucf54\ub4dc, \ucd94\uc0c1\ud654\uac00 \uc798 \ub418\uc5b4\uc788\ub294 \ucf54\ub4dc",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77d\uae30 \uc88b\uace0, \uac04\uacb0\ud55c \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \ubc29\ubc95\uc744 \ubc30\uc6b4 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucf54\ub4dc\ub97c \ubc14\ub77c\ubcf4\ub294 \uc2dc\uc810\uc774 \ud558\ub098 \ub298\uc5b4\ub09c \uae30\ubd84\uc774\ub2e4!(\uc55e\uc73c\ub85c \uc801\uc6a9\ud558\ub294 \uac83\uc740 \ub098\uc758 \ubaab\uc774\uc9c0\ub9cc) "),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc0dd\uac01 \uc815\ub9ac"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04 \uc911\uac04 \ud604\uc7ac \uc0c1\ud669\uc5d0 \ub300\ud574 \uadf8\ub9bc\uc744 \uadf8\ub9ac\uac70\ub098, \uae00\uc744 \uc801\uc73c\uba74\uc11c \uc815\ub9ac\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud398\uc5b4\uc640 \ub3d9\uc77c\ud55c \ubd80\ubd84\uc744 \uc774\ud574\ud558\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c4\ud589\ud558\ub294\ub370 \ub9e4\uc6b0 \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 \ub2e4\uc74c \ud398\uc5b4\ub54c\ubd80\ud130 \ud39c\uc774\ub791 \uc885\uc774\ub97c \uc900\ube44\ud574\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uac00\uac10\uc5c6\uc774 \uc758\uacac\uc744 \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c4\ud589 \uc0c1\ud669\uc5d0 \ub300\ud55c \ubd80\ubd84, \uc9c4\ud589 \uc18d\ub3c4, \uc9c0\uae08 \uc790\uc2e0\uc774 \uc774\ud574\ud558\uace0 \uc788\ub294 \ubd80\ubd84\uc744 \ub9d0\ud574\uc918\uc11c \ud3b8\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud68c\uace0\ub54c\ub3c4 \uc11c\ub85c \uc194\uc9c1\ud558\uac8c \uc758\uacac\uc744 \uc8fc\uace0 \ubc1b\uc544\uc11c \uc88b\uc558\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub3c4\uba54\uc778 \uc5b8\uc5b4\uc5d0 \uc2e0\uacbd\uc4f0\ub294 \ubd80\ubd84"),(0,a.kt)("br",{parentName:"p"}),"\n","\ud074\ub798\uc2a4\uba85, \ubcc0\uc218\uba85\uacfc \uac19\uc740 \uc5b8\uc5b4\ub97c \uc138\uc2ec\ud558\uac8c \uc2e0\uacbd\uc4f4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uad6c\uc0ac\ud56d \uc815\ub9ac\ub3c4 \uae54\ub054\ud558\uac8c \uc798\ud558\ub294 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\ud6c4\ucd94 \ucd5c\uace0 \ud83d\udc4d"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/4485017c.9559a624.js b/assets/js/4485017c.9559a624.js new file mode 100644 index 000000000..04cbb7def --- /dev/null +++ b/assets/js/4485017c.9559a624.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1906],{36169:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>o,default:()=>p,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var t=n(85893),s=n(3905);const c={title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",slug:"blackjack-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,a={permalink:"/blackjack-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-blackjack/pull/427",date:"2023-03-14T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 14\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.17,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",slug:"blackjack-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",permalink:"/grasp"},nextItem:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",permalink:"/ladder-retrospective"}},i={authorsImageUrls:[]},l=[{value:"\ube14\ub799\uc7ad",id:"\ube14\ub799\uc7ad",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function j(e){const r={a:"a",admonition:"admonition",br:"br",h3:"h3",p:"p",strong:"strong",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/java-blackjack/pull/427",children:"https://github.com/woowacourse/java-blackjack/pull/427"}),(0,t.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/java-blackjack/pull/537",children:"https://github.com/woowacourse/java-blackjack/pull/537"})]})}),"\n",(0,t.jsx)(r.h3,{id:"\ube14\ub799\uc7ad",children:"\ube14\ub799\uc7ad"}),"\n",(0,t.jsxs)(r.p,{children:["\ube14\ub799\uc7ad \ubbf8\uc158\uc5d0\uc11c\ub294 \ud6c4\ucd94\uc640 \ud398\uc5b4(\uc870\ubbf8\ub8cc \ub4c0\uc624?)\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\ubc88\uc5d0\ub294 \uc2e4\uc218\ud558\uc9c0 \uc54a\uace0, \ubc14\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uc9c0 \uc54a\uace0 \uce5c\ud574\uc9c0\uae30 \ubd80\ud130 \uc2dc\uc791\ud588\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ube14\ub799\uc7ad\uc740 \uad6c\ud604\ud574\uc57c \ub420 \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud560 \uac83 \uac19\uc558\uc9c0\ub9cc",(0,t.jsx)(r.br,{}),"\n","\ud6c4\ucd94\uc640 \ud568\uaed8 \uc804\ub7b5\uc801(\uc0bc\uc77c\uc808\uc5d0 \ubbf8\uc158 \uc774\uc57c\uae30 \ub098\ub204\uae30)\uc73c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud574 \uc2dc\uac04 \ub0b4\uc5d0 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ubbf8\uc158\uc744 \ub05d\ub098\uace0 \ud68c\uace0\ub97c \ud588\uc744 \ub54c \ud6c4\ucd94\uac00 \uace0\ubbfc\uac70\ub9ac\ub97c \ud558\ub098 \ub0b4\uc92c\ub2e4.",(0,t.jsx)(r.br,{}),"\n",'"\ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \uc555\ubc15\uac10\uc744 \ub290\ub07c\ub294 \ud398\uc5b4\uac00 \uc788\ub2e4\uba74 \ud5c8\ube0c\uac00 \ud574\uc904 \uc218 \uc788\ub294\uac8c \ubb50\uac00 \uc788\uc744\uae4c?"']}),"\n",(0,t.jsxs)(r.p,{children:["\uacf0\uacf0\ud788 \uc0dd\uac01\ud574\ubd24\uc9c0\ub9cc \uc27d\uac8c \ub2f5\uc744 \ub0b4\ub9b4 \uc218 \uc5c6\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc911\uac04 \uc911\uac04 \ud68c\uace0\ub97c \ud558\uace0, \ub098\uc758 \uc18c\ud504\ud2b8\uc2a4\ud0ac\uc744 \ub192\ud788\ub294\uac8c \ub2f5\uc77c\uae4c?",(0,t.jsx)(r.br,{}),"\n","\ubd80\ub2f4\uac10\uc744 \ub290\ub07c\uc9c0 \uc54a\uace0 \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub420 \uc218 \uc788\ub3c4\ub85d \uacc4\uc18d \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc0dd\uac01\uc774 \ub9ce\uc544\uc838\uc11c \uc804 \ub9ac\ubdf0\uc5b4\uc778 \ud130\ud2c0\ud83d\udc22\uacfc\ub3c4 \ub300\ud654\ub97c \ub098\ub204\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud130\ud2c0\uc740 \uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84(\uad81\uadf9\uc801\uc778 \ubaa9\ud45c\uc778 \uc88b\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uac83)\uc5d0 \uc9d1\uc911\ud574\ubcf4\ub77c\uace0 \ud558\uc168\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:"\uc88b\uc740 \ucf54\ub4dc, \uc88b\uc740 \ud398\uc5b4\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc77c\ub2e8 \uc9c0\uc18d\uc801\uc73c\ub85c \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ud398\uc5b4 \uc2e0\uacbd\uc4f0\uae30"}),(0,t.jsx)(r.br,{}),"\n","\uc774\ubc88 \ud398\uc5b4\ud560 \ub54c \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub0b4\ubcf4\ub3c4\ub85d \ud588\ub2e4. \uadf8\ub807\uae30\uc5d0 \ub108\ubb34 \uc758\uacac\uc744 \uac15\ud558\uac8c \ubc00\uc5b4\ubd99\uc778 \ub290\ub08c\uc774 \ub4e4\uc5b4\uc11c \ubbf8\uc548\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud6c4\ucd94\uac00 \uc555\ubc15\uc744 \ub290\uaf08\uc744 \uc218\ub3c4 \uc788\uc744 \uac83 \uac19\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc911\uac04 \uc911\uac04 \uc791\uc740 \ud68c\uace0\ub97c \uc9c4\ud589\ud574\ubcf4\ub294 \uac83\uc774 \uc88b\uc744\uae4c?"]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uccb4\ub825 \uad00\ub9ac"}),(0,t.jsx)(r.br,{}),"\n","\uc694\uc998 \uc798 \ubabb\uba39\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c \uc0b4 \ub0a0\uc774 \ub9ce\uc740\ub370 \uc798 \ucc59\uaca8\uba39\uace0, \ud798\ub0b4\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uc911\uac04 \uc911\uac04 \ub3cc\uc544\ubcf4\uae30"}),(0,t.jsx)(r.br,{}),"\n","\uc774\ubc88 \ubbf8\uc158\uacfc \uad00\ub828\ub41c \ub0b4\uc6a9\uc740 \uc544\ub2c8\uc9c0\ub9cc \uc6b0\ud14c\ucf54\ub97c \uc798 \ud65c\uc6a9 \ud558\uace0 \uc788\ub294\uc9c0 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub0b4\uac00 \uc6b0\ud14c\ucf54\uc5d0 \uc9c0\uc6d0\ud55c \uc774\uc720\ub97c \ud56d\uc0c1 \uc78a\uc9c0 \uc54a\uc544\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uc0c1\ud0dc \ud328\ud134"}),(0,t.jsx)(r.br,{}),"\n","\uac1d\uccb4\uc758 \ub0b4\ubd80 \uc0c1\ud0dc\uc5d0 \ub530\ub77c \uc2a4\uc2a4\ub85c \ud589\ub3d9\uc744 \ubcc0\uacbd\ud558\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc73c\ub85c if/else/switch\uc640 \uac19\uc740 \uc870\uac74\ubb38\uc744 \ud6a8\uacfc\uc801\uc73c\ub85c \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ube14\ub799\uc7ad \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc0c1\ud0dc \ud328\ud134\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ucc98\uc74c \uc801\uc6a9\ud574\ubcf4\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucc98\uc74c \uc801\uc6a9\ud558\uae30 \uc804\uc5d0\ub294 \ubcc4\ub85c\ub77c\uace0 \uc0dd\uac01\ud588\ub294\ub370, \uc0dd\uac01\ubcf4\ub2e4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uc77c\uad00\uc131, \uac00\ub3c5\uc131, \ucd94\uc0c1\ud654"}),(0,t.jsx)(r.br,{}),"\n","\uc774\ubc88 \ub9ac\ubdf0\uc5b4\ub294 \uac80\ud504\ud83c\udf6b \uc600\ub2e4!",(0,t.jsx)(r.br,{}),"\n","\uac80\ud504\uc758 \ub9ac\ubdf0\ub294 \uac04\uacb0\ud568\uc5d0 \uad00\ub828\ub41c \ub0b4\uc6a9\uc774 \ub9ce\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc77c\uad00\uc131\uc774 \uc788\ub294 \ucf54\ub4dc, \uac00\ub3c5\uc131\uc774 \uc88b\uc740 \ucf54\ub4dc, \ucd94\uc0c1\ud654\uac00 \uc798 \ub418\uc5b4\uc788\ub294 \ucf54\ub4dc",(0,t.jsx)(r.br,{}),"\n","\uc77d\uae30 \uc88b\uace0, \uac04\uacb0\ud55c \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \ubc29\ubc95\uc744 \ubc30\uc6b4 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucf54\ub4dc\ub97c \ubc14\ub77c\ubcf4\ub294 \uc2dc\uc810\uc774 \ud558\ub098 \ub298\uc5b4\ub09c \uae30\ubd84\uc774\ub2e4!(\uc55e\uc73c\ub85c \uc801\uc6a9\ud558\ub294 \uac83\uc740 \ub098\uc758 \ubaab\uc774\uc9c0\ub9cc)"]}),"\n",(0,t.jsx)(r.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uc0dd\uac01 \uc815\ub9ac"}),(0,t.jsx)(r.br,{}),"\n","\uc911\uac04 \uc911\uac04 \ud604\uc7ac \uc0c1\ud669\uc5d0 \ub300\ud574 \uadf8\ub9bc\uc744 \uadf8\ub9ac\uac70\ub098, \uae00\uc744 \uc801\uc73c\uba74\uc11c \uc815\ub9ac\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud398\uc5b4\uc640 \ub3d9\uc77c\ud55c \ubd80\ubd84\uc744 \uc774\ud574\ud558\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc9c4\ud589\ud558\ub294\ub370 \ub9e4\uc6b0 \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub098\ub3c4 \ub2e4\uc74c \ud398\uc5b4\ub54c\ubd80\ud130 \ud39c\uc774\ub791 \uc885\uc774\ub97c \uc900\ube44\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\uac00\uac10\uc5c6\uc774 \uc758\uacac\uc744 \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84"}),(0,t.jsx)(r.br,{}),"\n","\uc9c4\ud589 \uc0c1\ud669\uc5d0 \ub300\ud55c \ubd80\ubd84, \uc9c4\ud589 \uc18d\ub3c4, \uc9c0\uae08 \uc790\uc2e0\uc774 \uc774\ud574\ud558\uace0 \uc788\ub294 \ubd80\ubd84\uc744 \ub9d0\ud574\uc918\uc11c \ud3b8\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud68c\uace0\ub54c\ub3c4 \uc11c\ub85c \uc194\uc9c1\ud558\uac8c \uc758\uacac\uc744 \uc8fc\uace0 \ubc1b\uc544\uc11c \uc88b\uc558\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ub3c4\uba54\uc778 \uc5b8\uc5b4\uc5d0 \uc2e0\uacbd\uc4f0\ub294 \ubd80\ubd84"}),(0,t.jsx)(r.br,{}),"\n","\ud074\ub798\uc2a4\uba85, \ubcc0\uc218\uba85\uacfc \uac19\uc740 \uc5b8\uc5b4\ub97c \uc138\uc2ec\ud558\uac8c \uc2e0\uacbd\uc4f4\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc694\uad6c\uc0ac\ud56d \uc815\ub9ac\ub3c4 \uae54\ub054\ud558\uac8c \uc798\ud558\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:"\ud6c4\ucd94 \ucd5c\uace0 \ud83d\udc4d"})]})}function p(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(j,{...e})}):j(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>l});var t=n(67294);function s(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function c(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?c(Object(n),!0).forEach((function(r){s(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function a(e,r){if(null==e)return{};var n,t,s=function(e,r){if(null==e)return{};var n,t,s={},c=Object.keys(e);for(t=0;t<c.length;t++)n=c[t],r.indexOf(n)>=0||(s[n]=e[n]);return s}(e,r);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t<c.length;t++)n=c[t],r.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var i=t.createContext({}),l=function(e){var r=t.useContext(i),n=r;return e&&(n="function"==typeof e?e(r):o(o({},r),e)),n},j={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},p=t.forwardRef((function(e,r){var n=e.components,s=e.mdxType,c=e.originalType,i=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),b=l(n),h=s,u=b["".concat(i,".").concat(h)]||b[h]||j[h]||c;return n?t.createElement(u,o(o({ref:r},p),{},{components:n})):t.createElement(u,o({ref:r},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/448c20a0.1a72b6ca.js b/assets/js/448c20a0.1a72b6ca.js new file mode 100644 index 000000000..227192c91 --- /dev/null +++ b/assets/js/448c20a0.1a72b6ca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7680],{14079:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var r=n(85893),s=n(3905);const i={title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",slug:"spring-test-isolation",tags:["test"]},a=void 0,o={permalink:"/spring-test-isolation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",source:"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",description:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac",date:"2023-10-03T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 3\uc77c",tags:[{label:"test",permalink:"/tags/test"}],readingTime:4.315,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",slug:"spring-test-isolation",tags:["test"]},unlisted:!1,prevItem:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/mvc-retrospective"},nextItem:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",permalink:"/web-application-evolution"}},c={authorsImageUrls:[]},l=[{value:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac",id:"\ud14c\uc2a4\ud2b8-\uaca9\ub9ac",level:3},{value:"TestExecutionListener",id:"testexecutionlistener",level:3},{value:"AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604",id:"abstracttestexecutionlistener-\uc0c1\uc18d\ud558\uc5ec-\uad6c\ud604",level:3},{value:"Listener \ub4f1\ub85d",id:"listener-\ub4f1\ub85d",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",...(0,s.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"\ud14c\uc2a4\ud2b8-\uaca9\ub9ac",children:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac"}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\uc758 \uc21c\uc11c\uc5d0 \ub530\ub77c \uc131\uacf5 \uc2e4\ud328 \uc5ec\ubd80\uac00 \uacb0\uc815\ub418\ub294 \ube44\uacb0\uc815\uc801\uc778(non-determinism) \ud14c\uc2a4\ud2b8\uac00 \ub418\uc5b4\uc11c\ub294 \uc548\ub418\uace0, \ud14c\uc2a4\ud2b8\ub294 \ud56d\uc0c1 \uc21c\uc11c\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc218\ud589\ub418\ub3c4\ub85d \ubcf4\uc7a5\ub418\uc5b4\uc57c \ud55c\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \uc790\uc6d0\uc758 \uacf5\uc720, \uc678\ubd80 API, \uc2dc\uac04 \ub4f1\uc73c\ub85c \ube44\uacb0\uc815\uc801\uc778 \ud14c\uc2a4\ud2b8\uac00 \ub41c\ub2e4. \uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \uc0ac\uc6a9\ud558\uac70\ub098, \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc7ac\uc2e4\ud589\ud558\ub294 ",(0,r.jsx)(t.code,{children:"@DirtiesContext"}),", \uc790\uc6d0\uc744 \ucd08\uae30\ud654\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uc774\ud6c4\uc5d0 \ud14c\uc774\ube14\uc744 \ub864\ubc31 \ud558\ub294 ",(0,r.jsx)(t.code,{children:"@Transactional"}),"\ub4f1 \ub2e4\uc591\ud55c \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud574\ub2f9 \uae00\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc5d0\uc11c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc790\uc6d0\uc758 \uacf5\uc720\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc218\ud589\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc124\uba85\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.admonition,{title:"Independent - FIRST",type:"note",children:(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\ub07c\ub9ac \uc11c\ub85c \uc758\uc874\ud558\uba74 \uc548 \ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc11c\ub85c \uc758\uc874\ud558\uac8c \ub41c\ub2e4\uba74 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \ub54c, \ub610 \ub2e4\ub978 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589 \uac00\ub2a5\ud55c \ud14c\uc2a4\ud2b8\uac00 \uc88b\uc740 \ud14c\uc2a4\ud2b8\ub2e4."]})}),"\n",(0,r.jsx)(t.h3,{id:"testexecutionlistener",children:"TestExecutionListener"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 TextExecutionListner\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 \ud14c\uc2a4\ud2b8 \uc2e4\ud589 \ub2e8\uacc4\uc5d0\uc11c \uc774\ubca4\ud2b8\ub97c \uc218\uc2e0\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub97c \uc774\uc6a9\ud558\uba74 JUnit\uc758 @BeforeEach\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uacfc \uc720\uc0ac\ud558\uac8c, \ud14c\uc2a4\ud2b8\uc758 \uc0dd\uba85\uc8fc\uae30 \uc774\uc804 \ub610\ub294 \uc774\ud6c4\uc5d0 \ud544\uc694\ud55c \uc791\uc5c5\uc744 \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",metastring:"title=TextExecutionListner",children:"public interface TestExecutionListener {\n default void beforeTestClass(TestContext testContext) throws Exception {}\n default void prepareTestInstance(TestContext testContext) throws Exception {}\n default void beforeTestMethod(TestContext testContext) throws Exception {}\n default void beforeTestExecution(TestContext testContext) throws Exception {}\n default void afterTestExecution(TestContext testContext) throws Exception {}\n default void afterTestMethod(TestContext testContext) throws Exception {}\n default void afterTestClass(TestContext testContext) throws Exception {}\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"abstracttestexecutionlistener-\uc0c1\uc18d\ud558\uc5ec-\uad6c\ud604",children:"AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604"}),"\n",(0,r.jsxs)(t.p,{children:["AbstractTestExecutionListener\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac \ud658\uacbd\uc744 \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \ud074\ub798\uc2a4\ub85c, \uc778\ud130\ud398\uc774\uc2a4\uc778 TextExecutionListner\uc640 \ub2ec\ub9ac Ordered\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc5b4 \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ubc1b\uc544 \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub294 \ud504\ub808\uc784\uc6cc\ud06c\uac00 \uc81c\uacf5\ud558\ub294 \ub9ac\uc2a4\ub108 \ub2e4\uc74c\uc5d0 \uc2e4\ud589\uc2dc\ud0a4\ub3c4\ub85d \ud574\uc900\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\uc74c\uacfc \uac19\uc774 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac01\uac01\uc758 \ud14c\uc774\ube14\uc5d0 \ud574\ub2f9\ud558\ub294 Truncate \ucffc\ub9ac\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc870\ud68c\ud558\uace0, Test \uba54\uc11c\ub4dc\uac00 \ub05d\ub0a0\ub54c \ub9c8\ub2e4 \ud574\ub2f9 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uc5ec \ud14c\uc774\ube14\uc744 \ucd08\uae30\ud654\uc2dc\ud0a4\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",metastring:"title=DatabaseCleaner",children:'\npublic class DatabaseCleaner extends AbstractTestExecutionListener {\n\n private static final String TRUNCATE_TABLE_QUERY = """\n SELECT Concat(\'TRUNCATE TABLE \', TABLE_NAME, \';\') \n FROM INFORMATION_SCHEMA.TABLES\n WHERE TABLE_SCHEMA = \'PUBLIC\'\n """;\n\n @Override\n public void afterTestMethod(TestContext testContext) {\n JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);\n List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);\n truncateTables(jdbcTemplate, truncateTableQueries);\n }\n\n private JdbcTemplate getJdbcTemplate(TestContext testContext) {\n return testContext.getApplicationContext().getBean(JdbcTemplate.class);\n }\n\n private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {\n return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);\n }\n\n private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {\n jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");\n truncateTableQueries.forEach(jdbcTemplate::execute);\n jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");\n }\n}\n\n'})}),"\n",(0,r.jsx)(t.h3,{id:"listener-\ub4f1\ub85d",children:"Listener \ub4f1\ub85d"}),"\n",(0,r.jsxs)(t.p,{children:["@TestExecutionListeners\ub97c \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790 \uc815\uc758 \ub9ac\uc2a4\ub108\ub97c \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","mergeMode\uc758 \uae30\ubcf8\uac12\uc740 REPLACE_DEFAULTS\ub85c \ub9ac\uc2a4\ub108\uac00 \uc774\ubbf8 \uc874\uc7ac\ud558\ub294 \uacbd\uc6b0 \ub4f1\ub85d\ub41c \ub9ac\uc2a4\ub108\ub85c \ubcc0\uacbd\ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","MERGE_WITH_DEFAULTS\ub85c \uc124\uc815\ud55c\ub2e4\uba74 Ordered \uae30\uc900\uc73c\ub85c \uc21c\uc11c\uac00 \uacb0\uc815\ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ud6c4 \uaca9\ub9ac\uac00 \ud544\uc694\ud55c \ud14c\uc2a4\ud2b8\ub4e4\uc740 \ub2e4\uc74c\uc758 \ucd94\uc0c1 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ud558\uc5ec \uc0ac\uc6a9\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",metastring:"title=AcceptanceTest",children:"\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\n@TestExecutionListeners(\n value = DatabaseCleaner.class,\n mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS\n)\npublic abstract class AcceptanceTest {\n\n @LocalServerPort\n private int port;\n\n @BeforeEach\n public void setUp() {\n RestAssured.port = port;\n }\n}\n\n"})}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://www.baeldung.com/spring-testexecutionlistener",children:"The Spring TestExecutionListener, Baeldung"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://tecoble.techcourse.co.kr/post/2020-09-15-test-isolation/",children:"\uc778\uc218\ud14c\uc2a4\ud2b8\uc5d0\uc11c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ud558\uae30, \ud14c\ucf54\ube14"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://martinfowler.com/articles/nonDeterminism.html",children:"Eradicating Non-Determinism in Tests, martin fowler"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://mangkyu.tistory.com/264",children:"@SpringBootTest\uc758 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\uc2dc\ud0a4\uae30, MangKyu"})]})]})}function p(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>l});var r=n(67294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,s=function(e,t){if(null==e)return{};var n,r,s={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(n),T=s,x=u["".concat(c,".").concat(T)]||u[T]||d[T]||i;return n?r.createElement(x,a(a({ref:t},p),{},{components:n})):r.createElement(x,a({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/448c20a0.95c05821.js b/assets/js/448c20a0.95c05821.js deleted file mode 100644 index 4e382a0a1..000000000 --- a/assets/js/448c20a0.95c05821.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7680],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},T=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),T=c(n),m=a,d=T["".concat(l,".").concat(m)]||T[m]||u[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=T;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var c=2;c<i;c++)o[c]=n[c];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}T.displayName="MDXCreateElement"},64586:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const i={title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",slug:"spring-test-isolation",tags:["test"]},o=void 0,s={permalink:"/spring-test-isolation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",source:"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",description:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac",date:"2023-10-03T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 3\uc77c",tags:[{label:"test",permalink:"/tags/test"}],readingTime:4.315,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",slug:"spring-test-isolation",tags:["test"]},prevItem:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/mvc-retrospective"},nextItem:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",permalink:"/web-application-evolution"}},l={authorsImageUrls:[]},c=[{value:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac",id:"\ud14c\uc2a4\ud2b8-\uaca9\ub9ac",level:3},{value:"TestExecutionListener",id:"testexecutionlistener",level:3},{value:"AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604",id:"abstracttestexecutionlistener-\uc0c1\uc18d\ud558\uc5ec-\uad6c\ud604",level:3},{value:"Listener \ub4f1\ub85d",id:"listener-\ub4f1\ub85d",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ud14c\uc2a4\ud2b8-\uaca9\ub9ac"},"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac"),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\uc758 \uc21c\uc11c\uc5d0 \ub530\ub77c \uc131\uacf5 \uc2e4\ud328 \uc5ec\ubd80\uac00 \uacb0\uc815\ub418\ub294 \ube44\uacb0\uc815\uc801\uc778(non-determinism) \ud14c\uc2a4\ud2b8\uac00 \ub418\uc5b4\uc11c\ub294 \uc548\ub418\uace0, \ud14c\uc2a4\ud2b8\ub294 \ud56d\uc0c1 \uc21c\uc11c\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc218\ud589\ub418\ub3c4\ub85d \ubcf4\uc7a5\ub418\uc5b4\uc57c \ud55c\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \uc790\uc6d0\uc758 \uacf5\uc720, \uc678\ubd80 API, \uc2dc\uac04 \ub4f1\uc73c\ub85c \ube44\uacb0\uc815\uc801\uc778 \ud14c\uc2a4\ud2b8\uac00 \ub41c\ub2e4. \uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \uc0ac\uc6a9\ud558\uac70\ub098, \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc7ac\uc2e4\ud589\ud558\ub294 ",(0,a.kt)("inlineCode",{parentName:"p"},"@DirtiesContext"),", \uc790\uc6d0\uc744 \ucd08\uae30\ud654\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uc774\ud6c4\uc5d0 \ud14c\uc774\ube14\uc744 \ub864\ubc31 \ud558\ub294 ",(0,a.kt)("inlineCode",{parentName:"p"},"@Transactional"),"\ub4f1 \ub2e4\uc591\ud55c \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uae00\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc5d0\uc11c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc790\uc6d0\uc758 \uacf5\uc720\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc218\ud589\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc124\uba85\ud55c\ub2e4. "),(0,a.kt)("admonition",{title:"Independent - FIRST",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ud14c\uc2a4\ud2b8\ub07c\ub9ac \uc11c\ub85c \uc758\uc874\ud558\uba74 \uc548 \ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc11c\ub85c \uc758\uc874\ud558\uac8c \ub41c\ub2e4\uba74 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \ub54c, \ub610 \ub2e4\ub978 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589 \uac00\ub2a5\ud55c \ud14c\uc2a4\ud2b8\uac00 \uc88b\uc740 \ud14c\uc2a4\ud2b8\ub2e4. ")),(0,a.kt)("h3",{id:"testexecutionlistener"},"TestExecutionListener"),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 TextExecutionListner\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 \ud14c\uc2a4\ud2b8 \uc2e4\ud589 \ub2e8\uacc4\uc5d0\uc11c \uc774\ubca4\ud2b8\ub97c \uc218\uc2e0\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c \uc774\uc6a9\ud558\uba74 JUnit\uc758 @BeforeEach\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uacfc \uc720\uc0ac\ud558\uac8c, \ud14c\uc2a4\ud2b8\uc758 \uc0dd\uba85\uc8fc\uae30 \uc774\uc804 \ub610\ub294 \uc774\ud6c4\uc5d0 \ud544\uc694\ud55c \uc791\uc5c5\uc744 \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=TextExecutionListner",title:"TextExecutionListner"},"public interface TestExecutionListener {\n default void beforeTestClass(TestContext testContext) throws Exception {}\n default void prepareTestInstance(TestContext testContext) throws Exception {}\n default void beforeTestMethod(TestContext testContext) throws Exception {}\n default void beforeTestExecution(TestContext testContext) throws Exception {}\n default void afterTestExecution(TestContext testContext) throws Exception {}\n default void afterTestMethod(TestContext testContext) throws Exception {}\n default void afterTestClass(TestContext testContext) throws Exception {}\n}\n")),(0,a.kt)("h3",{id:"abstracttestexecutionlistener-\uc0c1\uc18d\ud558\uc5ec-\uad6c\ud604"},"AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604"),(0,a.kt)("p",null,"AbstractTestExecutionListener\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac \ud658\uacbd\uc744 \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \ud074\ub798\uc2a4\ub85c, \uc778\ud130\ud398\uc774\uc2a4\uc778 TextExecutionListner\uc640 \ub2ec\ub9ac Ordered\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc5b4 \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ubc1b\uc544 \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub294 \ud504\ub808\uc784\uc6cc\ud06c\uac00 \uc81c\uacf5\ud558\ub294 \ub9ac\uc2a4\ub108 \ub2e4\uc74c\uc5d0 \uc2e4\ud589\uc2dc\ud0a4\ub3c4\ub85d \ud574\uc900\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c\uacfc \uac19\uc774 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac01\uac01\uc758 \ud14c\uc774\ube14\uc5d0 \ud574\ub2f9\ud558\ub294 Truncate \ucffc\ub9ac\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc870\ud68c\ud558\uace0, Test \uba54\uc11c\ub4dc\uac00 \ub05d\ub0a0\ub54c \ub9c8\ub2e4 \ud574\ub2f9 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uc5ec \ud14c\uc774\ube14\uc744 \ucd08\uae30\ud654\uc2dc\ud0a4\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=DatabaseCleaner",title:"DatabaseCleaner"},'\npublic class DatabaseCleaner extends AbstractTestExecutionListener {\n\n private static final String TRUNCATE_TABLE_QUERY = """\n SELECT Concat(\'TRUNCATE TABLE \', TABLE_NAME, \';\') \n FROM INFORMATION_SCHEMA.TABLES\n WHERE TABLE_SCHEMA = \'PUBLIC\'\n """;\n\n @Override\n public void afterTestMethod(TestContext testContext) {\n JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);\n List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);\n truncateTables(jdbcTemplate, truncateTableQueries);\n }\n\n private JdbcTemplate getJdbcTemplate(TestContext testContext) {\n return testContext.getApplicationContext().getBean(JdbcTemplate.class);\n }\n\n private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {\n return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);\n }\n\n private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {\n jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");\n truncateTableQueries.forEach(jdbcTemplate::execute);\n jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");\n }\n}\n\n')),(0,a.kt)("h3",{id:"listener-\ub4f1\ub85d"},"Listener \ub4f1\ub85d"),(0,a.kt)("p",null,"@TestExecutionListeners\ub97c \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790 \uc815\uc758 \ub9ac\uc2a4\ub108\ub97c \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","mergeMode\uc758 \uae30\ubcf8\uac12\uc740 REPLACE_DEFAULTS\ub85c \ub9ac\uc2a4\ub108\uac00 \uc774\ubbf8 \uc874\uc7ac\ud558\ub294 \uacbd\uc6b0 \ub4f1\ub85d\ub41c \ub9ac\uc2a4\ub108\ub85c \ubcc0\uacbd\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","MERGE_WITH_DEFAULTS\ub85c \uc124\uc815\ud55c\ub2e4\uba74 Ordered \uae30\uc900\uc73c\ub85c \uc21c\uc11c\uac00 \uacb0\uc815\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ud6c4 \uaca9\ub9ac\uac00 \ud544\uc694\ud55c \ud14c\uc2a4\ud2b8\ub4e4\uc740 \ub2e4\uc74c\uc758 \ucd94\uc0c1 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ud558\uc5ec \uc0ac\uc6a9\ud558\uba74 \ub41c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AcceptanceTest",title:"AcceptanceTest"},"\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\n@TestExecutionListeners(\n value = DatabaseCleaner.class,\n mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS\n)\npublic abstract class AcceptanceTest {\n\n @LocalServerPort\n private int port;\n\n @BeforeEach\n public void setUp() {\n RestAssured.port = port;\n }\n}\n\n")),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.baeldung.com/spring-testexecutionlistener"},"The Spring TestExecutionListener, Baeldung"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://tecoble.techcourse.co.kr/post/2020-09-15-test-isolation/"},"\uc778\uc218\ud14c\uc2a4\ud2b8\uc5d0\uc11c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ud558\uae30, \ud14c\ucf54\ube14"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://martinfowler.com/articles/nonDeterminism.html"},"Eradicating Non-Determinism in Tests, martin fowler"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://mangkyu.tistory.com/264"},"@SpringBootTest\uc758 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\uc2dc\ud0a4\uae30, MangKyu")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/451db21d.8bc6a551.js b/assets/js/451db21d.8bc6a551.js new file mode 100644 index 000000000..c09071e6c --- /dev/null +++ b/assets/js/451db21d.8bc6a551.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1475],{71904:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>l,toc:()=>a});var n=r(85893),i=r(3905);const s={title:"TDD heuristics",slug:"/test/heuristics",last_update:{date:"2023/04/04"},tags:["test"]},c=void 0,l={id:"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59",title:"TDD heuristics",description:"TDD heuristics",source:"@site/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59.mdx",sourceDirName:"\ud14c\uc2a4\ud2b8",slug:"/test/heuristics",permalink:"/docs/test/heuristics",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59.mdx",tags:[{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1680566400,formattedLastUpdatedAt:"2023\ub144 4\uc6d4 4\uc77c",frontMatter:{title:"TDD heuristics",slug:"/test/heuristics",last_update:{date:"2023/04/04"},tags:["test"]},sidebar:"tutorialSidebar",previous:{title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",permalink:"/docs/test/stairstep"},next:{title:"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",permalink:"/docs/test/benefit"}},o={},a=[{value:"TDD heuristics",id:"tdd-heuristics",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={h3:"h3",li:"li",ol:"ol",p:"p",...(0,i.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"tdd-heuristics",children:"TDD heuristics"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"\uc5ec\ub7ec\ubd84\uc774 \uc791\uc131\ud558\uace0 \uc2f6\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub3c4\ub85d \ub9cc\ub4dc\ub294 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\uc2e4\ud328\uc2dc\ucf1c\ub77c. \ud1b5\uacfc\uc2dc\ucf1c\ub77c. \uadf8\ub9ac\uace0 \uc815\ub9ac\ud558\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ucd5c\uc0c1\uc758 \uacb0\uacfc\ub97c \ucd94\uad6c\ud558\uc9c0 \ub9d0\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\uc2e4\ud328\ud558\ub294 \uac00\uc7a5 \uac04\ub2e8\ud558\uace0, \uac00\uc7a5 \uad6c\uccb4\uc801\uc774\uba70, \uac00\uc7a5 \ud1f4\ud654\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\uac00\ub2a5\ud558\uba74 \uc77c\ubc18\ud654\ud558\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ucf54\ub4dc\uac00 \ud2c0\ub838\ub2e4\uace0 \ub290\uaef4\uc9c0\uba74 \uc7a0\uc2dc \uba48\ucdb0\uc11c \uc124\uacc4\ub97c \uace0\uccd0\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ub354 \ubcf5\uc7a1\ud55c \ub2e4\uc74c \uacbd\uc6b0\ub85c \ub118\uc5b4\uac00\uae30 \uc804, \uc9c0\uae08 \ub2e4\ub8e8\uace0 \uc788\ub294 \ub354 \ub2e8\uc21c\ud55c \uacbd\uc6b0\ub97c \ubaa8\uc870\ub9ac \ud14c\uc2a4\ud2b8\ud558\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ud604\uc7ac \ud14c\uc2a4\ud2b8\ub97c \ud1b5\uacfc\uc2dc\ud0a4\uae30 \uc704\ud574 \ub108\ubb34 \ub9ce\uc740 \uad6c\ud604\uc744 \ud574\uc57c \ud55c\ub2e4\uba74, \ud14c\uc2a4\ud2b8\ub97c \uc9c0\uc6b0\uace0 \ub354 \uc27d\uac8c \ud1b5\uacfc\ud560 \uc218 \uc788\ub294 \ub354 \ub2e8\uc21c\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ud14c\uc2a4\ud2b8 \uacf5\uac04(test space)\uc744 \uc804\ubd80 \ud3ec\uad04\ud558\ub294 \uc2e0\uc911\ud558\uace0 \uc810\uc9c4\uc801\uc778 \ud328\ud134\uc744 \ub530\ub974\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ud544\uc694 \uc5c6\ub294 \uac83\uc744 \uc5ec\ub7ec\ubd84\uc758 \ud14c\uc2a4\ud2b8\uc5d0 \ub123\uc9c0 \ub9d0\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ud14c\uc2a4\ud2b8\uc5d0 \uc2e4\uc81c \uc11c\ube44\uc2a4 \ub370\uc774\ud130\ub97c \uc0ac\uc6a9\ud558\uc9c0 \ub9d0\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ud14c\uc2a4\ud2b8 \uad6c\uc870\ub97c \uc81c\ud488 \ucf54\ub4dc \uad6c\uc870\ub85c\ubd80\ud130 \ubd84\ub9ac\ud558\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ud14c\uc2a4\ud2b8\uac00 \uad6c\uccb4\uc801(specific)\uc774 \ub420\uc218\ub85d \ucf54\ub4dc\ub294 \uc77c\ubc18\uc801(generic)\uc774 \ub41c\ub2e4."}),"\n",(0,n.jsx)(t.li,{children:"\ubcc0\ud658\uc744 \uc801\uc6a9\ud55c \uacb0\uacfc \ucd5c\uc801\uc774 \uc544\ub2cc \ud574\ub2f5\uc5d0 \ub3c4\ub2ec\ud588\ub2e4\uba74 \ub2e4\ub978 \ubcc0\ud658\uc744 \uc2dc\ub3c4\ud574\ubcf4\ub77c."}),"\n",(0,n.jsx)(t.li,{children:"\ub514\ubc84\uac70 \uc0ac\uc6a9\uc744 \ud53c\ud558\ub77c"}),"\n"]}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsx)(t.p,{children:"\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 p.44 ~ p.209"})]})}function u(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>a});var n=r(67294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?s(Object(r),!0).forEach((function(t){i(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var o=n.createContext({}),a=function(e){var t=n.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,s=e.originalType,o=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=a(r),h=i,f=p["".concat(o,".").concat(h)]||p[h]||d[h]||s;return r?n.createElement(f,c(c({ref:t},u),{},{components:r})):n.createElement(f,c({ref:t},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/451db21d.c94c80d0.js b/assets/js/451db21d.c94c80d0.js deleted file mode 100644 index 7654d294b..000000000 --- a/assets/js/451db21d.c94c80d0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1475],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),m=c(r),d=a,f=m["".concat(s,".").concat(d)]||m[d]||u[d]||i;return r?n.createElement(f,o(o({ref:t},p),{},{components:r})):n.createElement(f,o({ref:t},p))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,o=new Array(i);o[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var c=2;c<i;c++)o[c]=r[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},48193:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const i={title:"TDD heuristics",slug:"/test/heuristics",last_update:{date:"2023/04/04"},tags:["test"]},o=void 0,l={unversionedId:"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59",id:"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59",title:"TDD heuristics",description:"TDD heuristics",source:"@site/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59.mdx",sourceDirName:"\ud14c\uc2a4\ud2b8",slug:"/test/heuristics",permalink:"/docs/test/heuristics",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59.mdx",tags:[{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1680566400,formattedLastUpdatedAt:"2023\ub144 4\uc6d4 4\uc77c",frontMatter:{title:"TDD heuristics",slug:"/test/heuristics",last_update:{date:"2023/04/04"},tags:["test"]},sidebar:"tutorialSidebar",previous:{title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",permalink:"/docs/test/stairstep"},next:{title:"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd",permalink:"/docs/test/benefit"}},s={},c=[{value:"TDD heuristics",id:"tdd-heuristics",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],p={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"tdd-heuristics"},"TDD heuristics"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"\uc5ec\ub7ec\ubd84\uc774 \uc791\uc131\ud558\uace0 \uc2f6\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub3c4\ub85d \ub9cc\ub4dc\ub294 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\uc2e4\ud328\uc2dc\ucf1c\ub77c. \ud1b5\uacfc\uc2dc\ucf1c\ub77c. \uadf8\ub9ac\uace0 \uc815\ub9ac\ud558\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ucd5c\uc0c1\uc758 \uacb0\uacfc\ub97c \ucd94\uad6c\ud558\uc9c0 \ub9d0\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\uc2e4\ud328\ud558\ub294 \uac00\uc7a5 \uac04\ub2e8\ud558\uace0, \uac00\uc7a5 \uad6c\uccb4\uc801\uc774\uba70, \uac00\uc7a5 \ud1f4\ud654\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\uac00\ub2a5\ud558\uba74 \uc77c\ubc18\ud654\ud558\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ucf54\ub4dc\uac00 \ud2c0\ub838\ub2e4\uace0 \ub290\uaef4\uc9c0\uba74 \uc7a0\uc2dc \uba48\ucdb0\uc11c \uc124\uacc4\ub97c \uace0\uccd0\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ub354 \ubcf5\uc7a1\ud55c \ub2e4\uc74c \uacbd\uc6b0\ub85c \ub118\uc5b4\uac00\uae30 \uc804, \uc9c0\uae08 \ub2e4\ub8e8\uace0 \uc788\ub294 \ub354 \ub2e8\uc21c\ud55c \uacbd\uc6b0\ub97c \ubaa8\uc870\ub9ac \ud14c\uc2a4\ud2b8\ud558\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ud604\uc7ac \ud14c\uc2a4\ud2b8\ub97c \ud1b5\uacfc\uc2dc\ud0a4\uae30 \uc704\ud574 \ub108\ubb34 \ub9ce\uc740 \uad6c\ud604\uc744 \ud574\uc57c \ud55c\ub2e4\uba74, \ud14c\uc2a4\ud2b8\ub97c \uc9c0\uc6b0\uace0 \ub354 \uc27d\uac8c \ud1b5\uacfc\ud560 \uc218 \uc788\ub294 \ub354 \ub2e8\uc21c\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ud14c\uc2a4\ud2b8 \uacf5\uac04(test space)\uc744 \uc804\ubd80 \ud3ec\uad04\ud558\ub294 \uc2e0\uc911\ud558\uace0 \uc810\uc9c4\uc801\uc778 \ud328\ud134\uc744 \ub530\ub974\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ud544\uc694 \uc5c6\ub294 \uac83\uc744 \uc5ec\ub7ec\ubd84\uc758 \ud14c\uc2a4\ud2b8\uc5d0 \ub123\uc9c0 \ub9d0\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ud14c\uc2a4\ud2b8\uc5d0 \uc2e4\uc81c \uc11c\ube44\uc2a4 \ub370\uc774\ud130\ub97c \uc0ac\uc6a9\ud558\uc9c0 \ub9d0\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ud14c\uc2a4\ud2b8 \uad6c\uc870\ub97c \uc81c\ud488 \ucf54\ub4dc \uad6c\uc870\ub85c\ubd80\ud130 \ubd84\ub9ac\ud558\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ud14c\uc2a4\ud2b8\uac00 \uad6c\uccb4\uc801(specific)\uc774 \ub420\uc218\ub85d \ucf54\ub4dc\ub294 \uc77c\ubc18\uc801(generic)\uc774 \ub41c\ub2e4."),(0,a.kt)("li",{parentName:"ol"},"\ubcc0\ud658\uc744 \uc801\uc6a9\ud55c \uacb0\uacfc \ucd5c\uc801\uc774 \uc544\ub2cc \ud574\ub2f5\uc5d0 \ub3c4\ub2ec\ud588\ub2e4\uba74 \ub2e4\ub978 \ubcc0\ud658\uc744 \uc2dc\ub3c4\ud574\ubcf4\ub77c."),(0,a.kt)("li",{parentName:"ol"},"\ub514\ubc84\uac70 \uc0ac\uc6a9\uc744 \ud53c\ud558\ub77c")),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 p.44 ~ p.209"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/454a6d0d.64dcde7c.js b/assets/js/454a6d0d.64dcde7c.js new file mode 100644 index 000000000..85e7bd2d9 --- /dev/null +++ b/assets/js/454a6d0d.64dcde7c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4104],{98592:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>s,metadata:()=>i,toc:()=>o});var r=t(85893),a=t(3905);const s={title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",slug:"tecochat-retrospective-2",tags:["TecoChat","Retrospective"]},l=void 0,i={permalink:"/tecochat-retrospective-2",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",source:"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",description:"\ud504\ub860\ud2b8\uc5d4\ud2b8",date:"2023-05-01T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 1\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.67,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",slug:"tecochat-retrospective-2",tags:["TecoChat","Retrospective"]},unlisted:!1,prevItem:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",permalink:"/web-racing-car-retrospective"},nextItem:{title:"Jenkins\ub85c CI/CD \uc124\uc815",permalink:"/jenkins"}},c={authorsImageUrls:[]},o=[{value:"\ud504\ub860\ud2b8\uc5d4\ud2b8",id:"\ud504\ub860\ud2b8\uc5d4\ud2b8",level:3},{value:"\ubc31\uc5d4\ub4dc",id:"\ubc31\uc5d4\ub4dc",level:3},{value:"Http Request Header",id:"http-request-header",level:3},{value:"Elastic Beanstalk",id:"elastic-beanstalk",level:3},{value:"Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac",id:"elastic-beanstalk-rds-\uc124\uc815-\ud6c4-\ubd84\ub9ac",level:3},{value:"Elastic Beanstalk nginx \uc124\uc815",id:"elastic-beanstalk-nginx-\uc124\uc815",level:3},{value:"Jenkins",id:"jenkins",level:3},{value:"Jenkins Blue Ocean",id:"jenkins-blue-ocean",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"\ud504\ub860\ud2b8\uc5d4\ud2b8",children:"\ud504\ub860\ud2b8\uc5d4\ud2b8"}),"\n",(0,r.jsxs)(n.p,{children:["\ub2c9\ub124\uc784\uc744 \uc785\ub825\ud558\uc5ec \uac04\ub2e8\ud788 \ub85c\uadf8\uc778\ud558\ub294 \ud654\uba74, \ucc44\ud305 \ubaa9\ub85d\uc744 \ubcf4\uc5ec\uc8fc\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\uace0 \ub2e8\uc77c \ucc44\ud305\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ucc44\ud305\uc744 \uc774\uc5b4\ub098\uac08 \uc218 \uc788\uac8c \ud558\ub294 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc790\uc798\ud558\uac8c \uc2e0\uacbd \uc4f8 \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c, \ud504\ub860\ud2b8\uc5d4\ub4dc \ud558\ub294 \uc0ac\ub78c\ub4e4\uc774 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc5ec\uc720\uac00 \ub41c\ub2e4\uba74 \uc790\uc2e0\uc758 \ucc44\ud305\uc744 \ubcfc \uc218 \uc788\ub294 \uae30\ub2a5\uc774\ub098, \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub294 \uae30\ub2a5, \ub313\uae00 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud560 \uc608\uc815\uc774\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ubc31\uc5d4\ub4dc",children:"\ubc31\uc5d4\ub4dc"}),"\n",(0,r.jsxs)(n.p,{children:["\ucd5c\ub300\ud55c \ube68\ub9ac \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uae30\ub85c \uc815\ud574\uc11c, \ubc31\uc5d4\ub4dc\ub294 \ub9d0\ub791\uc774 \uc77c\ub2e8 \ub2e4 \ub9cc\ub4e4\uace0 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub9d0\ub791\uc774 \ud55c \ubd80\ubd84\uc774 \ub108\ubb34 \ub9ce\uc544\uc11c \ub0b4\uac00 \ubabb \ub530\ub77c\uac00\ub294 \uac83 \uac19\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub098\uc911\uc5d0 \ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc774\ud574\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"http-request-header",children:"Http Request Header"}),"\n",(0,r.jsxs)(n.p,{children:["\uc544\uc9c1 \uc778\uc99d\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ud558\uc9c0 \uc54a\uc544\uc11c \uc694\uccad \ud5e4\ub354\uc5d0 \uc774\ub984\uc744 \ubcf4\ub0b4\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub9d0\ub791\uc774 \ud55c\uae00\uc740 \uc548\ub41c\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c Base64\ub85c \uc778\ucf54\ub529\ud558\uace0, \ubc31\uc5d4\ub4dc\uc5d0\uc11c \ub514\ucf54\ub529 \ud558\uc5ec \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc544\ub798\ub294 pinia\uc5d0 \uc788\ub294 name \uac12\uc744 \uc778\ucf54\ub529 \ud558\ub294 \ucf54\ub4dc\ub2e4. deprecated \ub418\uc5c8\ub2e4\ub294\ub370, \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560 \uc904 \ubab0\ub77c\uc11c \uc77c\ub2e8 \uc774\uac78 \uc0ac\uc6a9\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const encodedName = () => {\n const uriComponent = unescape(encodeURIComponent(name.value));\n return btoa(uriComponent);\n};\n"})}),"\n",(0,r.jsx)(n.h3,{id:"elastic-beanstalk",children:"Elastic Beanstalk"}),"\n",(0,r.jsxs)(n.p,{children:["\uac00\uc7a5 \ube60\ub974\uac8c \ubc31\uc5d4\ub4dc\ub97c \ubc30\ud3ec\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ubb58\uc9c0 \uace0\ubbfc\ud558\ub2e4\uac00 Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uba74 \uc778\ud504\ub77c\uc5d0 \ub300\ud574 \uc798 \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ube60\ub974\uac8c \ubc30\ud3ec\ud558\uace0 \uad00\ub9ac\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubaa8\ub2c8\ud130\ub9c1, \ub85c\uae45, \ub85c\ub4dc \ubc38\ub7f0\uc2f1 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"elastic-beanstalk-rds-\uc124\uc815-\ud6c4-\ubd84\ub9ac",children:"Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac"}),"\n",(0,r.jsxs)(n.p,{children:["\ucd08\uae30 \uc124\uc815 \uc2dc RDS\ub97c \uc5f0\uacb0\ud558\uace0 \uc124\uc815 \uc644\ub8cc \ud6c4 \ubd84\ub9ac\ud55c\ub2e4\uba74, Beanstalk \uc778\uc2a4\ud134\uc2a4 -> RDS \uc694\uccad \uc2dc \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc744 \uc548 \ud574\ub3c4 \ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","RDS \ubd84\ub9ac \uc2dc Beanstalk\uc5d0 \uae30\ubcf8\uc801\uc73c\ub85c \uc124\uc815\ub418\uc5b4 \uc788\ub294 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD\uc640 \uac19\uc740 \ud658\uacbd \ubcc0\uc218\uac00 \uac19\uc774 \uc81c\uac70\ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c Elastic Beanstalk\ub85c RDS\ub97c \uc124\uc815\ud558\uba74 \uae30\ubcf8 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uba85\uc740 ebdb\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"elastic-beanstalk-nginx-\uc124\uc815",children:"Elastic Beanstalk nginx \uc124\uc815"}),"\n",(0,r.jsxs)(n.p,{children:["\uc5c5\ub85c\ub4dc\ud558\ub294 zip \ud30c\uc77c \ub0b4\ubd80\uc5d0 ",(0,r.jsx)(n.code,{children:".platform/nginx/conf.d/"})," \uacbd\ub85c\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ucd94\uac00\ud558\uba74 nginx \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"jenkins",children:"Jenkins"}),"\n",(0,r.jsxs)(n.p,{children:["\ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc77c\uc77c\ud788 \ubc30\ud3ec\ud558\uae30 \ubd88\ud3b8\ud574\uc11c Jenkins\ub97c \uc774\uc6a9\ud558\uc5ec Repository\uc5d0 \ucf54\ub4dc\ub97c push \ud560 \ub54c \uc790\ub3d9\uc73c\ub85c \ubc30\ud3ec\uac00 \ub418\uac8c \uc124\uc815\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc791\ub144\uc5d0 \ud655\uc778\ud588\uc744 \ub550 2022\ub144 12\uc6d4 31\uc77c\uae4c\uc9c0 EC2 ARM \uae30\ubc18 t4g.small\uc774 \ubb34\ub8cc\uc600\ub294\ub370, \ub2e4\uc2dc \ub4e4\uc5b4\uac00 \ubcf4\ub2c8 2023\ub144\uae4c\uc9c0 12\uc6d4 31\uc77c\uae4c\uc9c0 t4g.small\uc744 \ubb34\ub8cc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","t4g.small\uc740 \ub7a8\uc774 2G\uc778\ub370, \uc608\uc804\uc5d0\ub294 \ubd80\uc871\ud558\uc9c0 \uc54a\uc558\ub2e4\uace0 \uc0dd\uac01\ud588\ub294\ub370 Java 17\uc744 \uc368\uc11c \uadf8\ub7f0\uac00 \ube4c\ub4dc \ud560 \ub54c \ub7a8\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\uc544\uc11c Swap \uba54\ubaa8\ub9ac 2\uae30\uac00\ub97c \ucd94\uac00\ub85c \uc124\uc815\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c build.gradle\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8 \uc2dc \uc0ac\uc6a9\ud558\ub294 \ub7a8\uc744 \ub298\ub9b4 \uc218 \uc788\ub2e4. \uae30\ubcf8\uac12\uc740 512MB\ub77c\uace0 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-groovy",children:'test {\n maxHeapSize = "1024m"\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"jenkins-blue-ocean",children:"Jenkins Blue Ocean"}),"\n",(0,r.jsxs)(n.p,{children:["Blue Ocean\uc740 Jenkins Pipeline\uc744 \uad6c\uc131\ud558\ub294 \ub370\uc5d0 \uc788\uc5b4 \ud3b8\ub9ac\ud558\uac8c \ud574\uc8fc\ub294 \ub3c4\uad6c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc2dc\uac01\ud654\ub3c4 \uc798 \ub418\uc5b4\uc788\uace0, \uc124\uc815\ub3c4 \ud3b8\ub9ac\ud55c \uac83 \uac19\ub2e4.",(0,r.jsx)(n.br,{}),"\n",'\uc624\ub298 \uc801\uc6a9\ud574 \ubcf4\ub2c8 \ub7a8\uc774 \ubd80\uc871\ud558\uc5ec \uc911\uac04\uc5d0 \uc798 \uc548\ub418\uae30\ub3c4 \ud558\uace0 \uadf8\ub798\uc11c \uadf8\ub0e5 "Pipeline\ub9cc \uc0ac\uc6a9\ud560 \uac78 \uadf8\ub7ac\ub098?" \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.']}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/Welcome.html",children:"Elastic Beanstalk, AWS"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://aws.amazon.com/ko/ec2/graviton/",children:"EC2 AWS Graviton, AWS"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://docs.gradle.org/current/userguide/upgrading_version_4.html#rel5.0:default_memory_settings",children:"Default Memory Settings, AWS"})]})]})}function p(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>o});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function l(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?s(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function i(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},s=Object.keys(e);for(r=0;r<s.length;r++)t=s[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)t=s[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=r.createContext({}),o=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},p=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=o(t),h=a,b=u["".concat(c,".").concat(h)]||u[h]||d[h]||s;return t?r.createElement(b,l(l({ref:n},p),{},{components:t})):r.createElement(b,l({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/454a6d0d.f73eccad.js b/assets/js/454a6d0d.f73eccad.js deleted file mode 100644 index bda866150..000000000 --- a/assets/js/454a6d0d.f73eccad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4104],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>k});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),o=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=o(e.components);return a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),m=o(n),k=r,d=m["".concat(s,".").concat(k)]||m[k]||u[k]||l;return n?a.createElement(d,i(i({ref:t},c),{},{components:n})):a.createElement(d,i({ref:t},c))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p.mdxType="string"==typeof e?e:r,i[1]=p;for(var o=2;o<l;o++)i[o]=n[o];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"},33482:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>o});var a=n(87462),r=(n(67294),n(3905));const l={title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",slug:"tecochat-retrospective-2",tags:["TecoChat","Retrospective"]},i=void 0,p={permalink:"/tecochat-retrospective-2",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",source:"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",description:"\ud504\ub860\ud2b8\uc5d4\ud2b8",date:"2023-05-01T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 1\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.67,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",slug:"tecochat-retrospective-2",tags:["TecoChat","Retrospective"]},prevItem:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",permalink:"/web-racing-car-retrospective"},nextItem:{title:"Jenkins\ub85c CI/CD \uc124\uc815",permalink:"/jenkins"}},s={authorsImageUrls:[]},o=[{value:"\ud504\ub860\ud2b8\uc5d4\ud2b8",id:"\ud504\ub860\ud2b8\uc5d4\ud2b8",level:3},{value:"\ubc31\uc5d4\ub4dc",id:"\ubc31\uc5d4\ub4dc",level:3},{value:"Http Request Header",id:"http-request-header",level:3},{value:"Elastic Beanstalk",id:"elastic-beanstalk",level:3},{value:"Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac",id:"elastic-beanstalk-rds-\uc124\uc815-\ud6c4-\ubd84\ub9ac",level:3},{value:"Elastic Beanstalk nginx \uc124\uc815",id:"elastic-beanstalk-nginx-\uc124\uc815",level:3},{value:"Jenkins",id:"jenkins",level:3},{value:"Jenkins Blue Ocean",id:"jenkins-blue-ocean",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:o};function u(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"\ud504\ub860\ud2b8\uc5d4\ud2b8"},"\ud504\ub860\ud2b8\uc5d4\ud2b8"),(0,r.kt)("p",null,"\ub2c9\ub124\uc784\uc744 \uc785\ub825\ud558\uc5ec \uac04\ub2e8\ud788 \ub85c\uadf8\uc778\ud558\ub294 \ud654\uba74, \ucc44\ud305 \ubaa9\ub85d\uc744 \ubcf4\uc5ec\uc8fc\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\uace0 \ub2e8\uc77c \ucc44\ud305\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ucc44\ud305\uc744 \uc774\uc5b4\ub098\uac08 \uc218 \uc788\uac8c \ud558\ub294 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc790\uc798\ud558\uac8c \uc2e0\uacbd \uc4f8 \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c, \ud504\ub860\ud2b8\uc5d4\ub4dc \ud558\ub294 \uc0ac\ub78c\ub4e4\uc774 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc5ec\uc720\uac00 \ub41c\ub2e4\uba74 \uc790\uc2e0\uc758 \ucc44\ud305\uc744 \ubcfc \uc218 \uc788\ub294 \uae30\ub2a5\uc774\ub098, \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub294 \uae30\ub2a5, \ub313\uae00 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud560 \uc608\uc815\uc774\ub2e4. "),(0,r.kt)("h3",{id:"\ubc31\uc5d4\ub4dc"},"\ubc31\uc5d4\ub4dc"),(0,r.kt)("p",null,"\ucd5c\ub300\ud55c \ube68\ub9ac \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uae30\ub85c \uc815\ud574\uc11c, \ubc31\uc5d4\ub4dc\ub294 \ub9d0\ub791\uc774 \uc77c\ub2e8 \ub2e4 \ub9cc\ub4e4\uace0 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub9d0\ub791\uc774 \ud55c \ubd80\ubd84\uc774 \ub108\ubb34 \ub9ce\uc544\uc11c \ub0b4\uac00 \ubabb \ub530\ub77c\uac00\ub294 \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub098\uc911\uc5d0 \ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc774\ud574\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. "),(0,r.kt)("h3",{id:"http-request-header"},"Http Request Header"),(0,r.kt)("p",null,"\uc544\uc9c1 \uc778\uc99d\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ud558\uc9c0 \uc54a\uc544\uc11c \uc694\uccad \ud5e4\ub354\uc5d0 \uc774\ub984\uc744 \ubcf4\ub0b4\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub9d0\ub791\uc774 \ud55c\uae00\uc740 \uc548\ub41c\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c Base64\ub85c \uc778\ucf54\ub529\ud558\uace0, \ubc31\uc5d4\ub4dc\uc5d0\uc11c \ub514\ucf54\ub529 \ud558\uc5ec \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\ub294 pinia\uc5d0 \uc788\ub294 name \uac12\uc744 \uc778\ucf54\ub529 \ud558\ub294 \ucf54\ub4dc\ub2e4. deprecated \ub418\uc5c8\ub2e4\ub294\ub370, \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560 \uc904 \ubab0\ub77c\uc11c \uc77c\ub2e8 \uc774\uac78 \uc0ac\uc6a9\ud588\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const encodedName = () => {\n const uriComponent = unescape(encodeURIComponent(name.value));\n return btoa(uriComponent);\n};\n")),(0,r.kt)("h3",{id:"elastic-beanstalk"},"Elastic Beanstalk"),(0,r.kt)("p",null,"\uac00\uc7a5 \ube60\ub974\uac8c \ubc31\uc5d4\ub4dc\ub97c \ubc30\ud3ec\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ubb58\uc9c0 \uace0\ubbfc\ud558\ub2e4\uac00 Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uba74 \uc778\ud504\ub77c\uc5d0 \ub300\ud574 \uc798 \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ube60\ub974\uac8c \ubc30\ud3ec\ud558\uace0 \uad00\ub9ac\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubaa8\ub2c8\ud130\ub9c1, \ub85c\uae45, \ub85c\ub4dc \ubc38\ub7f0\uc2f1 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4. "),(0,r.kt)("h3",{id:"elastic-beanstalk-rds-\uc124\uc815-\ud6c4-\ubd84\ub9ac"},"Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac"),(0,r.kt)("p",null,"\ucd08\uae30 \uc124\uc815 \uc2dc RDS\ub97c \uc5f0\uacb0\ud558\uace0 \uc124\uc815 \uc644\ub8cc \ud6c4 \ubd84\ub9ac\ud55c\ub2e4\uba74, Beanstalk \uc778\uc2a4\ud134\uc2a4 -> RDS \uc694\uccad \uc2dc \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc744 \uc548 \ud574\ub3c4 \ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","RDS \ubd84\ub9ac \uc2dc Beanstalk\uc5d0 \uae30\ubcf8\uc801\uc73c\ub85c \uc124\uc815\ub418\uc5b4 \uc788\ub294 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD\uc640 \uac19\uc740 \ud658\uacbd \ubcc0\uc218\uac00 \uac19\uc774 \uc81c\uac70\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c Elastic Beanstalk\ub85c RDS\ub97c \uc124\uc815\ud558\uba74 \uae30\ubcf8 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uba85\uc740 ebdb\ub2e4. "),(0,r.kt)("h3",{id:"elastic-beanstalk-nginx-\uc124\uc815"},"Elastic Beanstalk nginx \uc124\uc815"),(0,r.kt)("p",null,"\uc5c5\ub85c\ub4dc\ud558\ub294 zip \ud30c\uc77c \ub0b4\ubd80\uc5d0 ",(0,r.kt)("inlineCode",{parentName:"p"},".platform/nginx/conf.d/")," \uacbd\ub85c\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ucd94\uac00\ud558\uba74 nginx \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("h3",{id:"jenkins"},"Jenkins"),(0,r.kt)("p",null,"\ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc77c\uc77c\ud788 \ubc30\ud3ec\ud558\uae30 \ubd88\ud3b8\ud574\uc11c Jenkins\ub97c \uc774\uc6a9\ud558\uc5ec Repository\uc5d0 \ucf54\ub4dc\ub97c push \ud560 \ub54c \uc790\ub3d9\uc73c\ub85c \ubc30\ud3ec\uac00 \ub418\uac8c \uc124\uc815\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc791\ub144\uc5d0 \ud655\uc778\ud588\uc744 \ub550 2022\ub144 12\uc6d4 31\uc77c\uae4c\uc9c0 EC2 ARM \uae30\ubc18 t4g.small\uc774 \ubb34\ub8cc\uc600\ub294\ub370, \ub2e4\uc2dc \ub4e4\uc5b4\uac00 \ubcf4\ub2c8 2023\ub144\uae4c\uc9c0 12\uc6d4 31\uc77c\uae4c\uc9c0 t4g.small\uc744 \ubb34\ub8cc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","t4g.small\uc740 \ub7a8\uc774 2G\uc778\ub370, \uc608\uc804\uc5d0\ub294 \ubd80\uc871\ud558\uc9c0 \uc54a\uc558\ub2e4\uace0 \uc0dd\uac01\ud588\ub294\ub370 Java 17\uc744 \uc368\uc11c \uadf8\ub7f0\uac00 \ube4c\ub4dc \ud560 \ub54c \ub7a8\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\uc544\uc11c Swap \uba54\ubaa8\ub9ac 2\uae30\uac00\ub97c \ucd94\uac00\ub85c \uc124\uc815\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c build.gradle\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8 \uc2dc \uc0ac\uc6a9\ud558\ub294 \ub7a8\uc744 \ub298\ub9b4 \uc218 \uc788\ub2e4. \uae30\ubcf8\uac12\uc740 512MB\ub77c\uace0 \ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-groovy"},'test {\n maxHeapSize = "1024m"\n}\n')),(0,r.kt)("h3",{id:"jenkins-blue-ocean"},"Jenkins Blue Ocean"),(0,r.kt)("p",null,"Blue Ocean\uc740 Jenkins Pipeline\uc744 \uad6c\uc131\ud558\ub294 \ub370\uc5d0 \uc788\uc5b4 \ud3b8\ub9ac\ud558\uac8c \ud574\uc8fc\ub294 \ub3c4\uad6c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc2dc\uac01\ud654\ub3c4 \uc798 \ub418\uc5b4\uc788\uace0, \uc124\uc815\ub3c4 \ud3b8\ub9ac\ud55c \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",'\uc624\ub298 \uc801\uc6a9\ud574 \ubcf4\ub2c8 \ub7a8\uc774 \ubd80\uc871\ud558\uc5ec \uc911\uac04\uc5d0 \uc798 \uc548\ub418\uae30\ub3c4 \ud558\uace0 \uadf8\ub798\uc11c \uadf8\ub0e5 "Pipeline\ub9cc \uc0ac\uc6a9\ud560 \uac78 \uadf8\ub7ac\ub098?" \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4. '),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/Welcome.html"},"Elastic Beanstalk, AWS"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/ec2/graviton/"},"EC2 AWS Graviton, AWS"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.gradle.org/current/userguide/upgrading_version_4.html#rel5.0:default_memory_settings"},"Default Memory Settings, AWS")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/46.53124cb6.js b/assets/js/46.53124cb6.js new file mode 100644 index 000000000..2f44e1313 --- /dev/null +++ b/assets/js/46.53124cb6.js @@ -0,0 +1,10780 @@ +"use strict"; +exports.id = 46; +exports.ids = [46]; +exports.modules = { + +/***/ 41644: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + bK: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.Z(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.Z( + map/* default */.Z(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.Z(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.Z(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.k(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.Z(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.Z(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.Z(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.Z(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.Z(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.Z('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.Z(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.Z(g.outEdges(v), function (e) { + if (has/* default */.Z(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.Z(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.Z(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(59236); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.Z)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(74752); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.Z)(iteratee, 3); + + (0,_baseForOwn/* default */.Z)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.Z)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(66092); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.Z.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.Z(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.k().setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.k({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.Z(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.Z(range/* default */.Z(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.Z(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.Z(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.Z(layers, function (vs, i) { + if (isUndefined/* default */.Z(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.Z(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.Z(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.Z(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.Z(children, dfs); + } + + if (has/* default */.Z(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.Z(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, reverseYOne); + if (has/* default */.Z(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, swapXYOne); + if (has/* default */.Z(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.Z(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.Z)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.Z(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.Z(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.Z(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.k({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.Z(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.Z(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.Z(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.Z)(collection)) { + var iteratee = (0,_baseIteratee/* default */.Z)(predicate, 3); + collection = (0,keys/* default */.Z)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.Z)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.Z)(array, (0,_baseIteratee/* default */.Z)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(39473); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(93589); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.Z)(value) && (0,isObjectLike/* default */.Z)(value) && (0,_baseGetTag/* default */.Z)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.Z)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.Z)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.Z)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.Z)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.Z(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.Z(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.Z(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.Z(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.Z(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.Z(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.Z(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.Z(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.Z(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.Z(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.Z(tree.neighbors(v), function (w) { + if (!has/* default */.Z(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.Z(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.Z(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.Z(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.Z(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.Z(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.Z(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.Z(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.Z(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.Z( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.Z(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.k({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.Z(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.Z(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.Z(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.Z('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.Z); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(21018); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.Z)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.Z)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + if ((0,isArray/* default */.Z)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.Z)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.Z]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.Z)(iteratees, (0,_baseUnary/* default */.Z)(_baseIteratee/* default */.Z)); + + var result = (0,_baseMap/* default */.Z)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.Z)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.Z)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.Z)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.Z)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.Z(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.Z( + map/* default */.Z(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.Z(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.Z(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.Z( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.Z(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.Z(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.Z(range/* default */.Z(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.Z(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.Z(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.Z(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.Z(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.Z( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.Z(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.Z(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.Z(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.Z(entryV) && !isUndefined/* default */.Z(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.Z(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.Z(uEntry.barycenter) || + isUndefined/* default */.Z(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.Z(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.Z(entry.out, handleOut(entry)); + } + + return map/* default */.Z( + filter/* default */.Z(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.Z(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.Z(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.Z(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.Z(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.Z(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.Z(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.Z(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.Z([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.Z(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.Z(entries, function (entry) { + entry.vs = flatten/* default */.Z( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.Z(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.Z(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.Z(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.Z(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.k(); + forEach/* default */.Z(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.Z(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.Z(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.Z(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(68882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(61395); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee), keysIn/* default */.Z); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.Z(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.Z(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.Z(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.Z(range/* default */.Z(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.Z(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.Z(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.Z(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.Z(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.Z(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.Z(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.k(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.Z(layering, function (layer) { + var u; + forEach/* default */.Z(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.Z(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.Z(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.Z(['u', 'd'], function (vert) { + forEach/* default */.Z(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.Z(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.Z(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.Z(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.Z(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.Z(layering).reverse(); + forEach/* default */.Z(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.Z(adjustedLayering, function (inner) { + return values/* default */.Z(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.Z(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.Z(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.Z(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.Z(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.Z(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.Z(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.k({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.Z({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.Z(graph, graphAttrs)) + ); + + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.Z(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.Z({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.Z(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.Z(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.Z(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.Z(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.Z(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.Z(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.Z(layers, function (layer) { + var orderShift = 0; + forEach/* default */.Z(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.Z(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.Z(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.Z(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 52544: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + k: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(73234); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(79697); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.Z)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(93203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.Z && (1 / (0,_setToArray/* default */.Z)(new _Set/* default */.Z([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.Z(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.Z)(set); + } + isCommon = false; + includes = _cacheHas/* default */.Z; + seen = new _SetCache/* default */.Z; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(836); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.Z)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.Z)(arrays, 1, isArrayLikeObject/* default */.Z, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.Z(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.Z(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.Z(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.Z(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.Z(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.Z(this._nodes); + } + sources() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.Z(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.Z(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.Z(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.Z(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.Z(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.Z(keys/* default */.Z(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.Z(keys/* default */.Z(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.Z(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.Z(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.Z(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.Z(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.Z(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.Z(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.Z(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.Z(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.Z(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.Z(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.Z(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.Z(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.Z(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.Z(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.Z(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.Z(inV); + if (!u) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.Z(outV); + if (!w) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.Z(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 45625: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ k: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.k) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52544); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 63001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(37834); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.Z; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 76579: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 68774: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 74073: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 58694: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 48451: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(76579); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(31899); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keys/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keysIn/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(91050); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(87215); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(95695); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.Z)(source, (0,_getSymbols/* default */.Z)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(12513); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(60532); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.Z : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.Z)(result, (0,_getSymbols/* default */.Z)(object)); + object = (0,_getPrototype/* default */.Z)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.Z)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(63327); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.Z)(object, keysIn/* default */.Z, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(41884); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.Z)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(12701); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.Z)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.Z)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(73658); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(98351); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.Z)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.Z)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.Z)(value)) { + return value; + } + var isArr = (0,isArray/* default */.Z)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.Z)(value, result); + } + } else { + var tag = (0,_getTag/* default */.Z)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.Z)(value)) { + return (0,_cloneBuffer/* default */.Z)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.Z)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.Z); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.Z) + : (isFlat ? keysIn/* default */.Z : keys/* default */.Z); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.Z)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.Z)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 49811: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.Z)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.Z); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 21692: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 10626: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(29169); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.Z ? _Symbol/* default */.Z.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.Z)(value) || (0,isArguments/* default */.Z)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.Z)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 2693: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61395); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 13317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 63327: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58694); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 74765: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.Z : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.Z)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(84073); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(79651); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.Z(object), new _Uint8Array/* default */.Z(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.Z)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.Z); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.Z)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.Z)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(18843); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.Z)(object), + othIsArr = (0,isArray/* default */.Z)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.Z)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.Z)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.Z)(object)) { + if (!(0,isBuffer/* default */.Z)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.Z); + return (objIsArr || (0,isTypedArray/* default */.Z)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.Z); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.Z); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.Z)(value) && !(0,isObjectLike/* default */.Z)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.Z; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.Z)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.Z)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.Z)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.Z)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.Z)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.Z)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.Z)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.Z)(path) ? (0,_baseProperty/* default */.Z)((0,_toKey/* default */.Z)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.Z; + } + if (typeof value == 'object') { + return (0,isArray/* default */.Z)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 21018: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49811); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 54193: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 59548: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 68882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69203); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 22823: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(42454); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.Z)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(50751); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.Z)(value)) { + return value; + } + return (0,_isKey/* default */.Z)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.Z)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 1808: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63327); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(95695); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 95695: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68774); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(60532); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 16174: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29169); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27771); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(56009); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1656); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 99365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72714); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 6545: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 62281: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72714); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 3688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69581); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(79651); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50439); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32957); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 13445: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(68774); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.Z)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayFilter/* default */.Z : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.Z)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 27961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10626); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 70870: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76579); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49811); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(68882); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 17452: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 75487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 72714: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93589); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18533); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 49360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 17179: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87668); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39473); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 43836: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74073); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74765); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21018); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 61666: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(22823); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(56009); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.Z)(object)) { + return object; + } + path = (0,_castPath/* default */.Z)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.Z)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.Z)(objValue) + ? objValue + : ((0,_isIndex/* default */.Z)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.Z)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.Z)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.Z)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.Z)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(81211); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(27227); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.Z)((0,_overRest/* default */.Z)(func, undefined, flatten/* default */.Z), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 74379: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.Z)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.Z)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.Z)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.Z)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 92344: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.Z)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.Z); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 60532: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 94099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.Z)(value)) { + return NAN; + } + if ((0,isObject/* default */.Z)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.Z)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 50751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.Z)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.Z)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.Z)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 66749: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50751); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 34148: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.Z)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.Z)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 76046: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(82127); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(45625); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(56363); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(20683); + + + + + + + + + + + + + + +let edgeCount = 0; +const drawEdge = function(elem, path, relation, conf, diagObj) { + const getRelationType = function(type) { + switch (type) { + case diagObj.db.relationType.AGGREGATION: + return "aggregation"; + case diagObj.db.relationType.EXTENSION: + return "extension"; + case diagObj.db.relationType.COMPOSITION: + return "composition"; + case diagObj.db.relationType.DEPENDENCY: + return "dependency"; + case diagObj.db.relationType.LOLLIPOP: + return "lollipop"; + } + }; + path.points = path.points.filter((p) => !Number.isNaN(p.y)); + const lineData = path.points; + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(function(d) { + return d.x; + }).y(function(d) { + return d.y; + }).curve(d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .$0Z); + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", "edge" + edgeCount).attr("class", "relation"); + let url = ""; + if (conf.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + if (relation.relation.lineType == 1) { + svgPath.attr("class", "relation dashed-line"); + } + if (relation.relation.lineType == 10) { + svgPath.attr("class", "relation dotted-line"); + } + if (relation.relation.type1 !== "none") { + svgPath.attr( + "marker-start", + "url(" + url + "#" + getRelationType(relation.relation.type1) + "Start)" + ); + } + if (relation.relation.type2 !== "none") { + svgPath.attr( + "marker-end", + "url(" + url + "#" + getRelationType(relation.relation.type2) + "End)" + ); + } + let x, y; + const l = path.points.length; + let labelPosition = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.u.calcLabelPosition(path.points); + x = labelPosition.x; + y = labelPosition.y; + let p1_card_x, p1_card_y; + let p2_card_x, p2_card_y; + if (l % 2 !== 0 && l > 1) { + let cardinality_1_point = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.u.calcCardinalityPosition( + relation.relation.type1 !== "none", + path.points, + path.points[0] + ); + let cardinality_2_point = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.u.calcCardinalityPosition( + relation.relation.type2 !== "none", + path.points, + path.points[l - 1] + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("cardinality_1_point " + JSON.stringify(cardinality_1_point)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("cardinality_2_point " + JSON.stringify(cardinality_2_point)); + p1_card_x = cardinality_1_point.x; + p1_card_y = cardinality_1_point.y; + p2_card_x = cardinality_2_point.x; + p2_card_y = cardinality_2_point.y; + } + if (relation.title !== void 0) { + const g = elem.append("g").attr("class", "classLabel"); + const label = g.append("text").attr("class", "label").attr("x", x).attr("y", y).attr("fill", "red").attr("text-anchor", "middle").text(relation.title); + window.label = label; + const bounds = label.node().getBBox(); + g.insert("rect", ":first-child").attr("class", "box").attr("x", bounds.x - conf.padding / 2).attr("y", bounds.y - conf.padding / 2).attr("width", bounds.width + conf.padding).attr("height", bounds.height + conf.padding); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Rendering relation " + JSON.stringify(relation)); + if (relation.relationTitle1 !== void 0 && relation.relationTitle1 !== "none") { + const g = elem.append("g").attr("class", "cardinality"); + g.append("text").attr("class", "type1").attr("x", p1_card_x).attr("y", p1_card_y).attr("fill", "black").attr("font-size", "6").text(relation.relationTitle1); + } + if (relation.relationTitle2 !== void 0 && relation.relationTitle2 !== "none") { + const g = elem.append("g").attr("class", "cardinality"); + g.append("text").attr("class", "type2").attr("x", p2_card_x).attr("y", p2_card_y).attr("fill", "black").attr("font-size", "6").text(relation.relationTitle2); + } + edgeCount++; +}; +const drawClass = function(elem, classDef, conf, diagObj) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Rendering class ", classDef, conf); + const id = classDef.id; + const classInfo = { + id, + label: classDef.id, + width: 0, + height: 0 + }; + const g = elem.append("g").attr("id", diagObj.db.lookUpDomId(id)).attr("class", "classGroup"); + let title; + if (classDef.link) { + title = g.append("svg:a").attr("xlink:href", classDef.link).attr("target", classDef.linkTarget).append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0); + } else { + title = g.append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0); + } + let isFirst = true; + classDef.annotations.forEach(function(member) { + const titleText2 = title.append("tspan").text("«" + member + "»"); + if (!isFirst) { + titleText2.attr("dy", conf.textHeight); + } + isFirst = false; + }); + let classTitleString = getClassTitleString(classDef); + const classTitle = title.append("tspan").text(classTitleString).attr("class", "title"); + if (!isFirst) { + classTitle.attr("dy", conf.textHeight); + } + const titleHeight = title.node().getBBox().height; + let membersLine; + let membersBox; + let methodsLine; + if (classDef.members.length > 0) { + membersLine = g.append("line").attr("x1", 0).attr("y1", conf.padding + titleHeight + conf.dividerMargin / 2).attr("y2", conf.padding + titleHeight + conf.dividerMargin / 2); + const members = g.append("text").attr("x", conf.padding).attr("y", titleHeight + conf.dividerMargin + conf.textHeight).attr("fill", "white").attr("class", "classText"); + isFirst = true; + classDef.members.forEach(function(member) { + addTspan(members, member, isFirst, conf); + isFirst = false; + }); + membersBox = members.node().getBBox(); + } + if (classDef.methods.length > 0) { + methodsLine = g.append("line").attr("x1", 0).attr("y1", conf.padding + titleHeight + conf.dividerMargin + membersBox.height).attr("y2", conf.padding + titleHeight + conf.dividerMargin + membersBox.height); + const methods = g.append("text").attr("x", conf.padding).attr("y", titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight).attr("fill", "white").attr("class", "classText"); + isFirst = true; + classDef.methods.forEach(function(method) { + addTspan(methods, method, isFirst, conf); + isFirst = false; + }); + } + const classBox = g.node().getBBox(); + var cssClassStr = " "; + if (classDef.cssClasses.length > 0) { + cssClassStr = cssClassStr + classDef.cssClasses.join(" "); + } + const rect = g.insert("rect", ":first-child").attr("x", 0).attr("y", 0).attr("width", classBox.width + 2 * conf.padding).attr("height", classBox.height + conf.padding + 0.5 * conf.dividerMargin).attr("class", cssClassStr); + const rectWidth = rect.node().getBBox().width; + title.node().childNodes.forEach(function(x) { + x.setAttribute("x", (rectWidth - x.getBBox().width) / 2); + }); + if (classDef.tooltip) { + title.insert("title").text(classDef.tooltip); + } + if (membersLine) { + membersLine.attr("x2", rectWidth); + } + if (methodsLine) { + methodsLine.attr("x2", rectWidth); + } + classInfo.width = rectWidth; + classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin; + return classInfo; +}; +const getClassTitleString = function(classDef) { + let classTitleString = classDef.id; + if (classDef.type) { + classTitleString += "<" + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.v)(classDef.type) + ">"; + } + return classTitleString; +}; +const drawNote = function(elem, note, conf, diagObj) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Rendering note ", note, conf); + const id = note.id; + const noteInfo = { + id, + text: note.text, + width: 0, + height: 0 + }; + const g = elem.append("g").attr("id", id).attr("class", "classGroup"); + let text = g.append("text").attr("y", conf.textHeight + conf.padding).attr("x", 0); + const lines = JSON.parse(`"${note.text}"`).split("\n"); + lines.forEach(function(line2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug(`Adding line: ${line2}`); + text.append("tspan").text(line2).attr("class", "title").attr("dy", conf.textHeight); + }); + const noteBox = g.node().getBBox(); + const rect = g.insert("rect", ":first-child").attr("x", 0).attr("y", 0).attr("width", noteBox.width + 2 * conf.padding).attr( + "height", + noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin + ); + const rectWidth = rect.node().getBBox().width; + text.node().childNodes.forEach(function(x) { + x.setAttribute("x", (rectWidth - x.getBBox().width) / 2); + }); + noteInfo.width = rectWidth; + noteInfo.height = noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin; + return noteInfo; +}; +const addTspan = function(textEl, member, isFirst, conf) { + const { displayText, cssStyle } = member.getDisplayDetails(); + const tSpan = textEl.append("tspan").attr("x", conf.padding).text(displayText); + if (cssStyle !== "") { + tSpan.attr("style", member.cssStyle); + } + if (!isFirst) { + tSpan.attr("dy", conf.textHeight); + } +}; +const svgDraw = { + getClassTitleString, + drawClass, + drawEdge, + drawNote +}; +let idCache = {}; +const padding = 20; +const getGraphId = function(label) { + const foundEntry = Object.entries(idCache).find((entry) => entry[1].label === label); + if (foundEntry) { + return foundEntry[0]; + } +}; +const insertMarkers = function(elem) { + elem.append("defs").append("marker").attr("id", "extensionStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", "extensionEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); + elem.append("defs").append("marker").attr("id", "compositionStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "compositionEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "aggregationStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "aggregationEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "dependencyStart").attr("class", "extension").attr("refX", 0).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", "dependencyEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const draw = function(text, id, _version, diagObj) { + const conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().class; + idCache = {}; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Rendering diagram " + text); + const securityLevel = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const diagram2 = root.select(`[id='${id}']`); + insertMarkers(diagram2); + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .k({ + multigraph: true + }); + g.setGraph({ + isMultiGraph: true + }); + g.setDefaultEdgeLabel(function() { + return {}; + }); + const classes = diagObj.db.getClasses(); + const keys = Object.keys(classes); + for (const key of keys) { + const classDef = classes[key]; + const node = svgDraw.drawClass(diagram2, classDef, conf, diagObj); + idCache[node.id] = node; + g.setNode(node.id, node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Org height: " + node.height); + } + const relations = diagObj.db.getRelations(); + relations.forEach(function(relation) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info( + "tjoho" + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation) + ); + g.setEdge( + getGraphId(relation.id1), + getGraphId(relation.id2), + { + relation + }, + relation.title || "DEFAULT" + ); + }); + const notes = diagObj.db.getNotes(); + notes.forEach(function(note) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug(`Adding note: ${JSON.stringify(note)}`); + const node = svgDraw.drawNote(diagram2, note, conf, diagObj); + idCache[node.id] = node; + g.setNode(node.id, node); + if (note.class && note.class in classes) { + g.setEdge( + note.id, + getGraphId(note.class), + { + relation: { + id1: note.id, + id2: note.class, + relation: { + type1: "none", + type2: "none", + lineType: 10 + } + } + }, + "DEFAULT" + ); + } + }); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__/* .layout */ .bK)(g); + g.nodes().forEach(function(v) { + if (v !== void 0 && g.node(v) !== void 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Node " + v + ": " + JSON.stringify(g.node(v))); + root.select("#" + (diagObj.db.lookUpDomId(v) || v)).attr( + "transform", + "translate(" + (g.node(v).x - g.node(v).width / 2) + "," + (g.node(v).y - g.node(v).height / 2) + " )" + ); + } + }); + g.edges().forEach(function(e) { + if (e !== void 0 && g.edge(e) !== void 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(g.edge(e))); + svgDraw.drawEdge(diagram2, g.edge(e), g.edge(e).relation, conf, diagObj); + } + }); + const svgBounds = diagram2.node().getBBox(); + const width = svgBounds.width + padding * 2; + const height = svgBounds.height + padding * 2; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.i)(diagram2, height, width, conf.useMaxWidth); + const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug(`viewBox ${vBox}`); + diagram2.attr("viewBox", vBox); +}; +const renderer = { + draw +}; +const diagram = { + parser: _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_7__.p, + db: _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_7__.d, + renderer, + styles: _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_7__.s, + init: (cnf) => { + if (!cnf.class) { + cnf.class = {}; + } + cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_7__.d.clear(); + } +}; + + + +/***/ }), + +/***/ 82127: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ p: () => (/* binding */ parser$1), +/* harmony export */ s: () => (/* binding */ styles) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 16], $V1 = [1, 17], $V2 = [1, 18], $V3 = [1, 37], $V4 = [1, 38], $V5 = [1, 24], $V6 = [1, 22], $V7 = [1, 23], $V8 = [1, 29], $V9 = [1, 30], $Va = [1, 31], $Vb = [1, 32], $Vc = [1, 33], $Vd = [1, 34], $Ve = [1, 25], $Vf = [1, 26], $Vg = [1, 27], $Vh = [1, 28], $Vi = [1, 42], $Vj = [1, 39], $Vk = [1, 40], $Vl = [1, 41], $Vm = [1, 43], $Vn = [1, 9], $Vo = [1, 8, 9], $Vp = [1, 54], $Vq = [1, 55], $Vr = [1, 56], $Vs = [1, 57], $Vt = [1, 58], $Vu = [1, 59], $Vv = [1, 60], $Vw = [1, 8, 9, 38], $Vx = [1, 71], $Vy = [1, 8, 9, 12, 13, 21, 36, 38, 41, 58, 59, 60, 61, 62, 63, 64, 69, 71], $Vz = [1, 8, 9, 12, 13, 19, 21, 36, 38, 41, 45, 58, 59, 60, 61, 62, 63, 64, 69, 71, 84, 86, 87, 88, 89], $VA = [13, 84, 86, 87, 88, 89], $VB = [13, 63, 64, 84, 86, 87, 88, 89], $VC = [13, 58, 59, 60, 61, 62, 84, 86, 87, 88, 89], $VD = [1, 90], $VE = [1, 8, 9, 36, 38, 41], $VF = [1, 8, 9, 21]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "mermaidDoc": 4, "statements": 5, "graphConfig": 6, "CLASS_DIAGRAM": 7, "NEWLINE": 8, "EOF": 9, "statement": 10, "classLabel": 11, "SQS": 12, "STR": 13, "SQE": 14, "namespaceName": 15, "alphaNumToken": 16, "className": 17, "classLiteralName": 18, "GENERICTYPE": 19, "relationStatement": 20, "LABEL": 21, "namespaceStatement": 22, "classStatement": 23, "memberStatement": 24, "annotationStatement": 25, "clickStatement": 26, "cssClassStatement": 27, "noteStatement": 28, "direction": 29, "acc_title": 30, "acc_title_value": 31, "acc_descr": 32, "acc_descr_value": 33, "acc_descr_multiline_value": 34, "namespaceIdentifier": 35, "STRUCT_START": 36, "classStatements": 37, "STRUCT_STOP": 38, "NAMESPACE": 39, "classIdentifier": 40, "STYLE_SEPARATOR": 41, "members": 42, "CLASS": 43, "ANNOTATION_START": 44, "ANNOTATION_END": 45, "MEMBER": 46, "SEPARATOR": 47, "relation": 48, "NOTE_FOR": 49, "noteText": 50, "NOTE": 51, "direction_tb": 52, "direction_bt": 53, "direction_rl": 54, "direction_lr": 55, "relationType": 56, "lineType": 57, "AGGREGATION": 58, "EXTENSION": 59, "COMPOSITION": 60, "DEPENDENCY": 61, "LOLLIPOP": 62, "LINE": 63, "DOTTED_LINE": 64, "CALLBACK": 65, "LINK": 66, "LINK_TARGET": 67, "CLICK": 68, "CALLBACK_NAME": 69, "CALLBACK_ARGS": 70, "HREF": 71, "CSSCLASS": 72, "commentToken": 73, "textToken": 74, "graphCodeTokens": 75, "textNoTagsToken": 76, "TAGSTART": 77, "TAGEND": 78, "==": 79, "--": 80, "PCT": 81, "DEFAULT": 82, "SPACE": 83, "MINUS": 84, "keywords": 85, "UNICODE_TEXT": 86, "NUM": 87, "ALPHA": 88, "BQUOTE_STR": 89, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 7: "CLASS_DIAGRAM", 8: "NEWLINE", 9: "EOF", 12: "SQS", 13: "STR", 14: "SQE", 19: "GENERICTYPE", 21: "LABEL", 30: "acc_title", 31: "acc_title_value", 32: "acc_descr", 33: "acc_descr_value", 34: "acc_descr_multiline_value", 36: "STRUCT_START", 38: "STRUCT_STOP", 39: "NAMESPACE", 41: "STYLE_SEPARATOR", 43: "CLASS", 44: "ANNOTATION_START", 45: "ANNOTATION_END", 46: "MEMBER", 47: "SEPARATOR", 49: "NOTE_FOR", 51: "NOTE", 52: "direction_tb", 53: "direction_bt", 54: "direction_rl", 55: "direction_lr", 58: "AGGREGATION", 59: "EXTENSION", 60: "COMPOSITION", 61: "DEPENDENCY", 62: "LOLLIPOP", 63: "LINE", 64: "DOTTED_LINE", 65: "CALLBACK", 66: "LINK", 67: "LINK_TARGET", 68: "CLICK", 69: "CALLBACK_NAME", 70: "CALLBACK_ARGS", 71: "HREF", 72: "CSSCLASS", 75: "graphCodeTokens", 77: "TAGSTART", 78: "TAGEND", 79: "==", 80: "--", 81: "PCT", 82: "DEFAULT", 83: "SPACE", 84: "MINUS", 85: "keywords", 86: "UNICODE_TEXT", 87: "NUM", 88: "ALPHA", 89: "BQUOTE_STR" }, + productions_: [0, [3, 1], [3, 1], [4, 1], [6, 4], [5, 1], [5, 2], [5, 3], [11, 3], [15, 1], [15, 2], [17, 1], [17, 1], [17, 2], [17, 2], [17, 2], [10, 1], [10, 2], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [10, 1], [22, 4], [22, 5], [35, 2], [37, 1], [37, 2], [37, 3], [23, 1], [23, 3], [23, 4], [23, 6], [40, 2], [40, 3], [25, 4], [42, 1], [42, 2], [24, 1], [24, 2], [24, 1], [24, 1], [20, 3], [20, 4], [20, 4], [20, 5], [28, 3], [28, 2], [29, 1], [29, 1], [29, 1], [29, 1], [48, 3], [48, 2], [48, 2], [48, 1], [56, 1], [56, 1], [56, 1], [56, 1], [56, 1], [57, 1], [57, 1], [26, 3], [26, 4], [26, 3], [26, 4], [26, 4], [26, 5], [26, 3], [26, 4], [26, 4], [26, 5], [26, 4], [26, 5], [26, 5], [26, 6], [27, 3], [73, 1], [73, 1], [74, 1], [74, 1], [74, 1], [74, 1], [74, 1], [74, 1], [74, 1], [76, 1], [76, 1], [76, 1], [76, 1], [16, 1], [16, 1], [16, 1], [16, 1], [18, 1], [50, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 8: + this.$ = $$[$0 - 1]; + break; + case 9: + case 11: + case 12: + this.$ = $$[$0]; + break; + case 10: + case 13: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 14: + case 15: + this.$ = $$[$0 - 1] + "~" + $$[$0] + "~"; + break; + case 16: + yy.addRelation($$[$0]); + break; + case 17: + $$[$0 - 1].title = yy.cleanupLabel($$[$0]); + yy.addRelation($$[$0 - 1]); + break; + case 26: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 27: + case 28: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 29: + yy.addClassesToNamespace($$[$0 - 3], $$[$0 - 1]); + break; + case 30: + yy.addClassesToNamespace($$[$0 - 4], $$[$0 - 1]); + break; + case 31: + this.$ = $$[$0]; + yy.addNamespace($$[$0]); + break; + case 32: + this.$ = [$$[$0]]; + break; + case 33: + this.$ = [$$[$0 - 1]]; + break; + case 34: + $$[$0].unshift($$[$0 - 2]); + this.$ = $$[$0]; + break; + case 36: + yy.setCssClass($$[$0 - 2], $$[$0]); + break; + case 37: + yy.addMembers($$[$0 - 3], $$[$0 - 1]); + break; + case 38: + yy.setCssClass($$[$0 - 5], $$[$0 - 3]); + yy.addMembers($$[$0 - 5], $$[$0 - 1]); + break; + case 39: + this.$ = $$[$0]; + yy.addClass($$[$0]); + break; + case 40: + this.$ = $$[$0 - 1]; + yy.addClass($$[$0 - 1]); + yy.setClassLabel($$[$0 - 1], $$[$0]); + break; + case 41: + yy.addAnnotation($$[$0], $$[$0 - 2]); + break; + case 42: + this.$ = [$$[$0]]; + break; + case 43: + $$[$0].push($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 44: + break; + case 45: + yy.addMember($$[$0 - 1], yy.cleanupLabel($$[$0])); + break; + case 46: + break; + case 47: + break; + case 48: + this.$ = { "id1": $$[$0 - 2], "id2": $$[$0], relation: $$[$0 - 1], relationTitle1: "none", relationTitle2: "none" }; + break; + case 49: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 1], relationTitle1: $$[$0 - 2], relationTitle2: "none" }; + break; + case 50: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: "none", relationTitle2: $$[$0 - 1] }; + break; + case 51: + this.$ = { id1: $$[$0 - 4], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: $$[$0 - 3], relationTitle2: $$[$0 - 1] }; + break; + case 52: + yy.addNote($$[$0], $$[$0 - 1]); + break; + case 53: + yy.addNote($$[$0]); + break; + case 54: + yy.setDirection("TB"); + break; + case 55: + yy.setDirection("BT"); + break; + case 56: + yy.setDirection("RL"); + break; + case 57: + yy.setDirection("LR"); + break; + case 58: + this.$ = { type1: $$[$0 - 2], type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 59: + this.$ = { type1: "none", type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 60: + this.$ = { type1: $$[$0 - 1], type2: "none", lineType: $$[$0] }; + break; + case 61: + this.$ = { type1: "none", type2: "none", lineType: $$[$0] }; + break; + case 62: + this.$ = yy.relationType.AGGREGATION; + break; + case 63: + this.$ = yy.relationType.EXTENSION; + break; + case 64: + this.$ = yy.relationType.COMPOSITION; + break; + case 65: + this.$ = yy.relationType.DEPENDENCY; + break; + case 66: + this.$ = yy.relationType.LOLLIPOP; + break; + case 67: + this.$ = yy.lineType.LINE; + break; + case 68: + this.$ = yy.lineType.DOTTED_LINE; + break; + case 69: + case 75: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 70: + case 76: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 2], $$[$0]); + break; + case 71: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 72: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 73: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 2], $$[$0]); + break; + case 74: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + yy.setTooltip($$[$0 - 3], $$[$0 - 1]); + break; + case 77: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 78: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 79: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 80: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 1], $$[$0]); + break; + case 81: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 1]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 82: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + yy.setTooltip($$[$0 - 4], $$[$0 - 1]); + break; + case 83: + yy.setCssClass($$[$0 - 1], $$[$0]); + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: 4, 7: [1, 6], 10: 5, 16: 35, 17: 19, 18: 36, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: $V0, 32: $V1, 34: $V2, 35: 20, 39: $V3, 40: 21, 43: $V4, 44: $V5, 46: $V6, 47: $V7, 49: $V8, 51: $V9, 52: $Va, 53: $Vb, 54: $Vc, 55: $Vd, 65: $Ve, 66: $Vf, 68: $Vg, 72: $Vh, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 1: [3] }, { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3] }, o($Vn, [2, 5], { 8: [1, 44] }), { 8: [1, 45] }, o($Vo, [2, 16], { 21: [1, 46] }), o($Vo, [2, 18]), o($Vo, [2, 19]), o($Vo, [2, 20]), o($Vo, [2, 21]), o($Vo, [2, 22]), o($Vo, [2, 23]), o($Vo, [2, 24]), o($Vo, [2, 25]), { 31: [1, 47] }, { 33: [1, 48] }, o($Vo, [2, 28]), o($Vo, [2, 44], { 48: 49, 56: 52, 57: 53, 13: [1, 50], 21: [1, 51], 58: $Vp, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv }), { 36: [1, 61] }, o($Vw, [2, 35], { 36: [1, 63], 41: [1, 62] }), o($Vo, [2, 46]), o($Vo, [2, 47]), { 16: 64, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, { 16: 35, 17: 65, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 16: 35, 17: 66, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 16: 35, 17: 67, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 13: [1, 68] }, { 16: 35, 17: 69, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 13: $Vx, 50: 70 }, o($Vo, [2, 54]), o($Vo, [2, 55]), o($Vo, [2, 56]), o($Vo, [2, 57]), o($Vy, [2, 11], { 16: 35, 18: 36, 17: 72, 19: [1, 73], 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }), o($Vy, [2, 12], { 19: [1, 74] }), { 15: 75, 16: 76, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, { 16: 35, 17: 77, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($Vz, [2, 97]), o($Vz, [2, 98]), o($Vz, [2, 99]), o($Vz, [2, 100]), o([1, 8, 9, 12, 13, 19, 21, 36, 38, 41, 58, 59, 60, 61, 62, 63, 64, 69, 71], [2, 101]), o($Vn, [2, 6], { 10: 5, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 17: 19, 35: 20, 40: 21, 16: 35, 18: 36, 5: 78, 30: $V0, 32: $V1, 34: $V2, 39: $V3, 43: $V4, 44: $V5, 46: $V6, 47: $V7, 49: $V8, 51: $V9, 52: $Va, 53: $Vb, 54: $Vc, 55: $Vd, 65: $Ve, 66: $Vf, 68: $Vg, 72: $Vh, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }), { 5: 79, 10: 5, 16: 35, 17: 19, 18: 36, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: $V0, 32: $V1, 34: $V2, 35: 20, 39: $V3, 40: 21, 43: $V4, 44: $V5, 46: $V6, 47: $V7, 49: $V8, 51: $V9, 52: $Va, 53: $Vb, 54: $Vc, 55: $Vd, 65: $Ve, 66: $Vf, 68: $Vg, 72: $Vh, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($Vo, [2, 17]), o($Vo, [2, 26]), o($Vo, [2, 27]), { 13: [1, 81], 16: 35, 17: 80, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 48: 82, 56: 52, 57: 53, 58: $Vp, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv }, o($Vo, [2, 45]), { 57: 83, 63: $Vu, 64: $Vv }, o($VA, [2, 61], { 56: 84, 58: $Vp, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt }), o($VB, [2, 62]), o($VB, [2, 63]), o($VB, [2, 64]), o($VB, [2, 65]), o($VB, [2, 66]), o($VC, [2, 67]), o($VC, [2, 68]), { 8: [1, 86], 23: 87, 37: 85, 40: 21, 43: $V4 }, { 16: 88, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, { 42: 89, 46: $VD }, { 45: [1, 91] }, { 13: [1, 92] }, { 13: [1, 93] }, { 69: [1, 94], 71: [1, 95] }, { 16: 96, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, { 13: $Vx, 50: 97 }, o($Vo, [2, 53]), o($Vo, [2, 102]), o($Vy, [2, 13]), o($Vy, [2, 14]), o($Vy, [2, 15]), { 36: [2, 31] }, { 15: 98, 16: 76, 36: [2, 9], 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, o($VE, [2, 39], { 11: 99, 12: [1, 100] }), o($Vn, [2, 7]), { 9: [1, 101] }, o($VF, [2, 48]), { 16: 35, 17: 102, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 13: [1, 104], 16: 35, 17: 103, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($VA, [2, 60], { 56: 105, 58: $Vp, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt }), o($VA, [2, 59]), { 38: [1, 106] }, { 23: 87, 37: 107, 40: 21, 43: $V4 }, { 8: [1, 108], 38: [2, 32] }, o($Vw, [2, 36], { 36: [1, 109] }), { 38: [1, 110] }, { 38: [2, 42], 42: 111, 46: $VD }, { 16: 35, 17: 112, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($Vo, [2, 69], { 13: [1, 113] }), o($Vo, [2, 71], { 13: [1, 115], 67: [1, 114] }), o($Vo, [2, 75], { 13: [1, 116], 70: [1, 117] }), { 13: [1, 118] }, o($Vo, [2, 83]), o($Vo, [2, 52]), { 36: [2, 10] }, o($VE, [2, 40]), { 13: [1, 119] }, { 1: [2, 4] }, o($VF, [2, 50]), o($VF, [2, 49]), { 16: 35, 17: 120, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($VA, [2, 58]), o($Vo, [2, 29]), { 38: [1, 121] }, { 23: 87, 37: 122, 38: [2, 33], 40: 21, 43: $V4 }, { 42: 123, 46: $VD }, o($Vw, [2, 37]), { 38: [2, 43] }, o($Vo, [2, 41]), o($Vo, [2, 70]), o($Vo, [2, 72]), o($Vo, [2, 73], { 67: [1, 124] }), o($Vo, [2, 76]), o($Vo, [2, 77], { 13: [1, 125] }), o($Vo, [2, 79], { 13: [1, 127], 67: [1, 126] }), { 14: [1, 128] }, o($VF, [2, 51]), o($Vo, [2, 30]), { 38: [2, 34] }, { 38: [1, 129] }, o($Vo, [2, 74]), o($Vo, [2, 78]), o($Vo, [2, 80]), o($Vo, [2, 81], { 67: [1, 130] }), o($VE, [2, 8]), o($Vw, [2, 38]), o($Vo, [2, 82])], + defaultActions: { 2: [2, 1], 3: [2, 2], 4: [2, 3], 75: [2, 31], 98: [2, 10], 101: [2, 4], 111: [2, 43], 122: [2, 34] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 52; + case 1: + return 53; + case 2: + return 54; + case 3: + return 55; + case 4: + break; + case 5: + break; + case 6: + this.begin("acc_title"); + return 30; + case 7: + this.popState(); + return "acc_title_value"; + case 8: + this.begin("acc_descr"); + return 32; + case 9: + this.popState(); + return "acc_descr_value"; + case 10: + this.begin("acc_descr_multiline"); + break; + case 11: + this.popState(); + break; + case 12: + return "acc_descr_multiline_value"; + case 13: + return 8; + case 14: + break; + case 15: + return 7; + case 16: + return 7; + case 17: + return "EDGE_STATE"; + case 18: + this.begin("callback_name"); + break; + case 19: + this.popState(); + break; + case 20: + this.popState(); + this.begin("callback_args"); + break; + case 21: + return 69; + case 22: + this.popState(); + break; + case 23: + return 70; + case 24: + this.popState(); + break; + case 25: + return "STR"; + case 26: + this.begin("string"); + break; + case 27: + this.begin("namespace"); + return 39; + case 28: + this.popState(); + return 8; + case 29: + break; + case 30: + this.begin("namespace-body"); + return 36; + case 31: + this.popState(); + return 38; + case 32: + return "EOF_IN_STRUCT"; + case 33: + return 8; + case 34: + break; + case 35: + return "EDGE_STATE"; + case 36: + this.begin("class"); + return 43; + case 37: + this.popState(); + return 8; + case 38: + break; + case 39: + this.popState(); + this.popState(); + return 38; + case 40: + this.begin("class-body"); + return 36; + case 41: + this.popState(); + return 38; + case 42: + return "EOF_IN_STRUCT"; + case 43: + return "EDGE_STATE"; + case 44: + return "OPEN_IN_STRUCT"; + case 45: + break; + case 46: + return "MEMBER"; + case 47: + return 72; + case 48: + return 65; + case 49: + return 66; + case 50: + return 68; + case 51: + return 49; + case 52: + return 51; + case 53: + return 44; + case 54: + return 45; + case 55: + return 71; + case 56: + this.popState(); + break; + case 57: + return "GENERICTYPE"; + case 58: + this.begin("generic"); + break; + case 59: + this.popState(); + break; + case 60: + return "BQUOTE_STR"; + case 61: + this.begin("bqstring"); + break; + case 62: + return 67; + case 63: + return 67; + case 64: + return 67; + case 65: + return 67; + case 66: + return 59; + case 67: + return 59; + case 68: + return 61; + case 69: + return 61; + case 70: + return 60; + case 71: + return 58; + case 72: + return 62; + case 73: + return 63; + case 74: + return 64; + case 75: + return 21; + case 76: + return 41; + case 77: + return 84; + case 78: + return "DOT"; + case 79: + return "PLUS"; + case 80: + return 81; + case 81: + return "EQUALS"; + case 82: + return "EQUALS"; + case 83: + return 88; + case 84: + return 12; + case 85: + return 14; + case 86: + return "PUNCTUATION"; + case 87: + return 87; + case 88: + return 86; + case 89: + return 83; + case 90: + return 9; + } + }, + rules: [/^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/, /^(?:%%[^\n]*(\r?\n)*)/, /^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:classDiagram-v2\b)/, /^(?:classDiagram\b)/, /^(?:\[\*\])/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:["])/, /^(?:[^"]*)/, /^(?:["])/, /^(?:namespace\b)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:\[\*\])/, /^(?:class\b)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:[}])/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\[\*\])/, /^(?:[{])/, /^(?:[\n])/, /^(?:[^{}\n]*)/, /^(?:cssClass\b)/, /^(?:callback\b)/, /^(?:link\b)/, /^(?:click\b)/, /^(?:note for\b)/, /^(?:note\b)/, /^(?:<<)/, /^(?:>>)/, /^(?:href\b)/, /^(?:[~])/, /^(?:[^~]*)/, /^(?:~)/, /^(?:[`])/, /^(?:[^`]+)/, /^(?:[`])/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:\s*<\|)/, /^(?:\s*\|>)/, /^(?:\s*>)/, /^(?:\s*<)/, /^(?:\s*\*)/, /^(?:\s*o\b)/, /^(?:\s*\(\))/, /^(?:--)/, /^(?:\.\.)/, /^(?::{1}[^:\n;]+)/, /^(?::{3})/, /^(?:-)/, /^(?:\.)/, /^(?:\+)/, /^(?:%)/, /^(?:=)/, /^(?:=)/, /^(?:\w+)/, /^(?:\[)/, /^(?:\])/, /^(?:[!"#$%&'*+,-.`?\\/])/, /^(?:[0-9]+)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\s)/, /^(?:$)/], + conditions: { "namespace-body": { "rules": [26, 31, 32, 33, 34, 35, 36, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "namespace": { "rules": [26, 27, 28, 29, 30, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "class-body": { "rules": [26, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "class": { "rules": [26, 37, 38, 39, 40, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "acc_descr_multiline": { "rules": [11, 12, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "acc_descr": { "rules": [9, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "acc_title": { "rules": [7, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "callback_args": { "rules": [22, 23, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "callback_name": { "rules": [19, 20, 21, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "href": { "rules": [26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "struct": { "rules": [26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "generic": { "rules": [26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "bqstring": { "rules": [26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "string": { "rules": [24, 25, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 14, 15, 16, 17, 18, 26, 27, 36, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const visibilityValues = ["#", "+", "~", "-", ""]; +class ClassMember { + constructor(input, memberType) { + this.memberType = memberType; + this.visibility = ""; + this.classifier = ""; + const sanitizedInput = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)(input, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + this.parseMember(sanitizedInput); + } + getDisplayDetails() { + let displayText = this.visibility + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.v)(this.id); + if (this.memberType === "method") { + displayText += `(${(0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.v)(this.parameters.trim())})`; + if (this.returnType) { + displayText += " : " + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.v)(this.returnType); + } + } + displayText = displayText.trim(); + const cssStyle = this.parseClassifier(); + return { + displayText, + cssStyle + }; + } + parseMember(input) { + let potentialClassifier = ""; + if (this.memberType === "method") { + const methodRegEx = /([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/; + const match = input.match(methodRegEx); + if (match) { + const detectedVisibility = match[1] ? match[1].trim() : ""; + if (visibilityValues.includes(detectedVisibility)) { + this.visibility = detectedVisibility; + } + this.id = match[2].trim(); + this.parameters = match[3] ? match[3].trim() : ""; + potentialClassifier = match[4] ? match[4].trim() : ""; + this.returnType = match[5] ? match[5].trim() : ""; + if (potentialClassifier === "") { + const lastChar = this.returnType.substring(this.returnType.length - 1); + if (lastChar.match(/[$*]/)) { + potentialClassifier = lastChar; + this.returnType = this.returnType.substring(0, this.returnType.length - 1); + } + } + } + } else { + const length = input.length; + const firstChar = input.substring(0, 1); + const lastChar = input.substring(length - 1); + if (visibilityValues.includes(firstChar)) { + this.visibility = firstChar; + } + if (lastChar.match(/[*?]/)) { + potentialClassifier = lastChar; + } + this.id = input.substring( + this.visibility === "" ? 0 : 1, + potentialClassifier === "" ? length : length - 1 + ); + } + this.classifier = potentialClassifier; + } + parseClassifier() { + switch (this.classifier) { + case "*": + return "font-style:italic;"; + case "$": + return "text-decoration:underline;"; + default: + return ""; + } + } +} +const MERMAID_DOM_ID_PREFIX = "classId-"; +let relations = []; +let classes = {}; +let notes = []; +let classCounter = 0; +let namespaces = {}; +let namespaceCounter = 0; +let functions = []; +const sanitizeText = (txt) => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); +const splitClassNameAndType = function(_id) { + const id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + let genericType = ""; + let className = id; + if (id.indexOf("~") > 0) { + const split = id.split("~"); + className = sanitizeText(split[0]); + genericType = sanitizeText(split[1]); + } + return { className, type: genericType }; +}; +const setClassLabel = function(_id, label) { + const id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + if (label) { + label = sanitizeText(label); + } + const { className } = splitClassNameAndType(id); + classes[className].label = label; +}; +const addClass = function(_id) { + const id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + const { className, type } = splitClassNameAndType(id); + if (Object.hasOwn(classes, className)) { + return; + } + const name = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(className, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + classes[name] = { + id: name, + type, + label: name, + cssClasses: [], + methods: [], + members: [], + annotations: [], + domId: MERMAID_DOM_ID_PREFIX + name + "-" + classCounter + }; + classCounter++; +}; +const lookUpDomId = function(_id) { + const id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + if (id in classes) { + return classes[id].domId; + } + throw new Error("Class not found: " + id); +}; +const clear = function() { + relations = []; + classes = {}; + notes = []; + functions = []; + functions.push(setupToolTips); + namespaces = {}; + namespaceCounter = 0; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.t)(); +}; +const getClass = function(id) { + return classes[id]; +}; +const getClasses = function() { + return classes; +}; +const getRelations = function() { + return relations; +}; +const getNotes = function() { + return notes; +}; +const addRelation = function(relation) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Adding relation: " + JSON.stringify(relation)); + addClass(relation.id1); + addClass(relation.id2); + relation.id1 = splitClassNameAndType(relation.id1).className; + relation.id2 = splitClassNameAndType(relation.id2).className; + relation.relationTitle1 = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(relation.relationTitle1.trim(), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + relation.relationTitle2 = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(relation.relationTitle2.trim(), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + relations.push(relation); +}; +const addAnnotation = function(className, annotation) { + const validatedClassName = splitClassNameAndType(className).className; + classes[validatedClassName].annotations.push(annotation); +}; +const addMember = function(className, member) { + addClass(className); + const validatedClassName = splitClassNameAndType(className).className; + const theClass = classes[validatedClassName]; + if (typeof member === "string") { + const memberString = member.trim(); + if (memberString.startsWith("<<") && memberString.endsWith(">>")) { + theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2))); + } else if (memberString.indexOf(")") > 0) { + theClass.methods.push(new ClassMember(memberString, "method")); + } else if (memberString) { + theClass.members.push(new ClassMember(memberString, "attribute")); + } + } +}; +const addMembers = function(className, members) { + if (Array.isArray(members)) { + members.reverse(); + members.forEach((member) => addMember(className, member)); + } +}; +const addNote = function(text, className) { + const note = { + id: `note${notes.length}`, + class: className, + text + }; + notes.push(note); +}; +const cleanupLabel = function(label) { + if (label.startsWith(":")) { + label = label.substring(1); + } + return sanitizeText(label.trim()); +}; +const setCssClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== void 0) { + classes[id].cssClasses.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + classes[id].tooltip = sanitizeText(tooltip); + } + }); +}; +const getTooltip = function(id, namespace) { + if (namespace) { + return namespaces[namespace].classes[id].tooltip; + } + return classes[id].tooltip; +}; +const setLink = function(ids, linkStr, target) { + const config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + ids.split(",").forEach(function(_id) { + let id = _id; + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== void 0) { + classes[id].link = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + if (config.securityLevel === "sandbox") { + classes[id].linkTarget = "_top"; + } else if (typeof target === "string") { + classes[id].linkTarget = sanitizeText(target); + } else { + classes[id].linkTarget = "_blank"; + } + } + }); + setCssClass(ids, "clickable"); +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFunc(id, functionName, functionArgs); + classes[id].haveCallback = true; + }); + setCssClass(ids, "clickable"); +}; +const setClickFunc = function(_domId, functionName, functionArgs) { + const domId = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_domId, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + const config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + if (config.securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + const id = domId; + if (classes[id] !== void 0) { + const elemId = lookUpDomId(id); + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(elemId); + } + functions.push(function() { + const elem = document.querySelector(`[id="${elemId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const bindFunctions = function(element) { + functions.forEach(function(fun) { + fun(element); + }); +}; +const lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; +const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3, + LOLLIPOP: 4 +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.top - 14 + document.body.scrollTop + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "<br/>")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + el.classed("hover", false); + }); +}; +functions.push(setupToolTips); +let direction = "TB"; +const getDirection = () => direction; +const setDirection = (dir) => { + direction = dir; +}; +const addNamespace = function(id) { + if (namespaces[id] !== void 0) { + return; + } + namespaces[id] = { + id, + classes: {}, + children: {}, + domId: MERMAID_DOM_ID_PREFIX + id + "-" + namespaceCounter + }; + namespaceCounter++; +}; +const getNamespace = function(name) { + return namespaces[name]; +}; +const getNamespaces = function() { + return namespaces; +}; +const addClassesToNamespace = function(id, classNames) { + if (namespaces[id] !== void 0) { + classNames.map((className) => { + classes[className].parent = id; + namespaces[id].classes[className] = classes[className]; + }); + } +}; +const db = { + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.b, + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().class, + addClass, + bindFunctions, + clear, + getClass, + getClasses, + getNotes, + addAnnotation, + addNote, + getRelations, + addRelation, + getDirection, + setDirection, + addMember, + addMembers, + cleanupLabel, + lineType, + relationType, + setClickEvent, + setCssClass, + setLink, + getTooltip, + setTooltip, + lookUpDomId, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.r, + setClassLabel, + addNamespace, + addClassesToNamespace, + getNamespace, + getNamespaces +}; +const getStyles = (options) => `g.classGroup text { + fill: ${options.nodeBorder || options.classText}; + stroke: none; + font-family: ${options.fontFamily}; + font-size: 10px; + + .title { + font-weight: bolder; + } + +} + +.nodeLabel, .edgeLabel { + color: ${options.classText}; +} +.edgeLabel .label rect { + fill: ${options.mainBkg}; +} +.label text { + fill: ${options.classText}; +} +.edgeLabel .label span { + background: ${options.mainBkg}; +} + +.classTitle { + font-weight: bolder; +} +.node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + +.divider { + stroke: ${options.nodeBorder}; + stroke-width: 1; +} + +g.clickable { + cursor: pointer; +} + +g.classGroup rect { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; +} + +g.classGroup line { + stroke: ${options.nodeBorder}; + stroke-width: 1; +} + +.classLabel .box { + stroke: none; + stroke-width: 0; + fill: ${options.mainBkg}; + opacity: 0.5; +} + +.classLabel .label { + fill: ${options.nodeBorder}; + font-size: 10px; +} + +.relation { + stroke: ${options.lineColor}; + stroke-width: 1; + fill: none; +} + +.dashed-line{ + stroke-dasharray: 3; +} + +.dotted-line{ + stroke-dasharray: 1 2; +} + +#compositionStart, .composition { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#compositionEnd, .composition { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#extensionStart, .extension { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#extensionEnd, .extension { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#aggregationStart, .aggregation { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#aggregationEnd, .aggregation { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#lollipopStart, .lollipop { + fill: ${options.mainBkg} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#lollipopEnd, .lollipop { + fill: ${options.mainBkg} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +.edgeTerminals { + font-size: 11px; +} + +.classTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} +`; +const styles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/469.66086d5a.js b/assets/js/469.66086d5a.js new file mode 100644 index 000000000..2736f47da --- /dev/null +++ b/assets/js/469.66086d5a.js @@ -0,0 +1,1242 @@ +"use strict"; +exports.id = 469; +exports.ids = [469]; +exports.modules = { + +/***/ 9469: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(91619); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(12281); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(7201); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 8, 10, 11, 12, 14, 16, 17, 20, 21], $V1 = [1, 9], $V2 = [1, 10], $V3 = [1, 11], $V4 = [1, 12], $V5 = [1, 13], $V6 = [1, 16], $V7 = [1, 17]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "timeline": 4, "document": 5, "EOF": 6, "line": 7, "SPACE": 8, "statement": 9, "NEWLINE": 10, "title": 11, "acc_title": 12, "acc_title_value": 13, "acc_descr": 14, "acc_descr_value": 15, "acc_descr_multiline_value": 16, "section": 17, "period_statement": 18, "event_statement": 19, "period": 20, "event": 21, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "timeline", 6: "EOF", 8: "SPACE", 10: "NEWLINE", 11: "title", 12: "acc_title", 13: "acc_title_value", 14: "acc_descr", 15: "acc_descr_value", 16: "acc_descr_multiline_value", 17: "section", 20: "period", 21: "event" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 1], [9, 1], [18, 1], [19, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 1: + return $$[$0 - 1]; + case 2: + this.$ = []; + break; + case 3: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 4: + case 5: + this.$ = $$[$0]; + break; + case 6: + case 7: + this.$ = []; + break; + case 8: + yy.getCommonDb().setDiagramTitle($$[$0].substr(6)); + this.$ = $$[$0].substr(6); + break; + case 9: + this.$ = $$[$0].trim(); + yy.getCommonDb().setAccTitle(this.$); + break; + case 10: + case 11: + this.$ = $$[$0].trim(); + yy.getCommonDb().setAccDescription(this.$); + break; + case 12: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 15: + yy.addTask($$[$0], 0, ""); + this.$ = $$[$0]; + break; + case 16: + yy.addEvent($$[$0].substr(2)); + this.$ = $$[$0]; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: 14, 19: 15, 20: $V6, 21: $V7 }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 18, 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: 14, 19: 15, 20: $V6, 21: $V7 }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 8]), { 13: [1, 19] }, { 15: [1, 20] }, o($V0, [2, 11]), o($V0, [2, 12]), o($V0, [2, 13]), o($V0, [2, 14]), o($V0, [2, 15]), o($V0, [2, 16]), o($V0, [2, 4]), o($V0, [2, 9]), o($V0, [2, 10])], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + return 10; + case 3: + break; + case 4: + break; + case 5: + return 4; + case 6: + return 11; + case 7: + this.begin("acc_title"); + return 12; + case 8: + this.popState(); + return "acc_title_value"; + case 9: + this.begin("acc_descr"); + return 14; + case 10: + this.popState(); + return "acc_descr_value"; + case 11: + this.begin("acc_descr_multiline"); + break; + case 12: + this.popState(); + break; + case 13: + return "acc_descr_multiline_value"; + case 14: + return 17; + case 15: + return 21; + case 16: + return 20; + case 17: + return 6; + case 18: + return "INVALID"; + } + }, + rules: [/^(?:%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:#[^\n]*)/i, /^(?:timeline\b)/i, /^(?:title\s[^#\n;]+)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:section\s[^#:\n;]+)/i, /^(?::\s[^#:\n;]+)/i, /^(?:[^#:\n;]+)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "acc_descr_multiline": { "rules": [12, 13], "inclusive": false }, "acc_descr": { "rules": [10], "inclusive": false }, "acc_title": { "rules": [8], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let currentSection = ""; +let currentTaskId = 0; +const sections = []; +const tasks = []; +const rawTasks = []; +const getCommonDb = () => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.K; +const clear = function() { + sections.length = 0; + tasks.length = 0; + currentSection = ""; + rawTasks.length = 0; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.t)(); +}; +const addSection = function(txt) { + currentSection = txt; + sections.push(txt); +}; +const getSections = function() { + return sections; +}; +const getTasks = function() { + let allItemsProcessed = compileTasks(); + const maxDepth = 100; + let iterationCount = 0; + while (!allItemsProcessed && iterationCount < maxDepth) { + allItemsProcessed = compileTasks(); + iterationCount++; + } + tasks.push(...rawTasks); + return tasks; +}; +const addTask = function(period, length, event) { + const rawTask = { + id: currentTaskId++, + section: currentSection, + type: currentSection, + task: period, + score: length ? length : 0, + //if event is defined, then add it the events array + events: event ? [event] : [] + }; + rawTasks.push(rawTask); +}; +const addEvent = function(event) { + const currentTask = rawTasks.find((task) => task.id === currentTaskId - 1); + currentTask.events.push(event); +}; +const addTaskOrg = function(descr) { + const newTask = { + section: currentSection, + type: currentSection, + description: descr, + task: descr, + classes: [] + }; + tasks.push(newTask); +}; +const compileTasks = function() { + const compileTask = function(pos) { + return rawTasks[pos].processed; + }; + let allProcessed = true; + for (const [i, rawTask] of rawTasks.entries()) { + compileTask(i); + allProcessed = allProcessed && rawTask.processed; + } + return allProcessed; +}; +const timelineDb = { + clear, + getCommonDb, + addSection, + getSections, + getTasks, + addTask, + addTaskOrg, + addEvent +}; +const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addEvent, + addSection, + addTask, + addTaskOrg, + clear, + default: timelineDb, + getCommonDb, + getSections, + getTasks +}, Symbol.toStringTag, { value: "Module" })); +const MAX_SECTIONS = 12; +const drawRect = function(elem, rectData) { + const rectElem = elem.append("rect"); + rectElem.attr("x", rectData.x); + rectElem.attr("y", rectData.y); + rectElem.attr("fill", rectData.fill); + rectElem.attr("stroke", rectData.stroke); + rectElem.attr("width", rectData.width); + rectElem.attr("height", rectData.height); + rectElem.attr("rx", rectData.rx); + rectElem.attr("ry", rectData.ry); + if (rectData.class !== void 0) { + rectElem.attr("class", rectData.class); + } + return rectElem; +}; +const drawFace = function(element, faceData) { + const radius = 15; + const circleElement = element.append("circle").attr("cx", faceData.cx).attr("cy", faceData.cy).attr("class", "face").attr("r", radius).attr("stroke-width", 2).attr("overflow", "visible"); + const face = element.append("g"); + face.append("circle").attr("cx", faceData.cx - radius / 3).attr("cy", faceData.cy - radius / 3).attr("r", 1.5).attr("stroke-width", 2).attr("fill", "#666").attr("stroke", "#666"); + face.append("circle").attr("cx", faceData.cx + radius / 3).attr("cy", faceData.cy - radius / 3).attr("r", 1.5).attr("stroke-width", 2).attr("fill", "#666").attr("stroke", "#666"); + function smile(face2) { + const arc$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .Nb1)().startAngle(Math.PI / 2).endAngle(3 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2); + face2.append("path").attr("class", "mouth").attr("d", arc$1).attr("transform", "translate(" + faceData.cx + "," + (faceData.cy + 2) + ")"); + } + function sad(face2) { + const arc$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .Nb1)().startAngle(3 * Math.PI / 2).endAngle(5 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2); + face2.append("path").attr("class", "mouth").attr("d", arc$1).attr("transform", "translate(" + faceData.cx + "," + (faceData.cy + 7) + ")"); + } + function ambivalent(face2) { + face2.append("line").attr("class", "mouth").attr("stroke", 2).attr("x1", faceData.cx - 5).attr("y1", faceData.cy + 7).attr("x2", faceData.cx + 5).attr("y2", faceData.cy + 7).attr("class", "mouth").attr("stroke-width", "1px").attr("stroke", "#666"); + } + if (faceData.score > 3) { + smile(face); + } else if (faceData.score < 3) { + sad(face); + } else { + ambivalent(face); + } + return circleElement; +}; +const drawCircle = function(element, circleData) { + const circleElement = element.append("circle"); + circleElement.attr("cx", circleData.cx); + circleElement.attr("cy", circleData.cy); + circleElement.attr("class", "actor-" + circleData.pos); + circleElement.attr("fill", circleData.fill); + circleElement.attr("stroke", circleData.stroke); + circleElement.attr("r", circleData.r); + if (circleElement.class !== void 0) { + circleElement.attr("class", circleElement.class); + } + if (circleData.title !== void 0) { + circleElement.append("title").text(circleData.title); + } + return circleElement; +}; +const drawText = function(elem, textData) { + const nText = textData.text.replace(/<br\s*\/?>/gi, " "); + const textElem = elem.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", textData.y); + textElem.attr("class", "legend"); + textElem.style("text-anchor", textData.anchor); + if (textData.class !== void 0) { + textElem.attr("class", textData.class); + } + const span = textElem.append("tspan"); + span.attr("x", textData.x + textData.textMargin * 2); + span.text(nText); + return textElem; +}; +const drawLabel = function(elem, txtObject) { + function genPoints(x, y, width, height, cut) { + return x + "," + y + " " + (x + width) + "," + y + " " + (x + width) + "," + (y + height - cut) + " " + (x + width - cut * 1.2) + "," + (y + height) + " " + x + "," + (y + height); + } + const polygon = elem.append("polygon"); + polygon.attr("points", genPoints(txtObject.x, txtObject.y, 50, 20, 7)); + polygon.attr("class", "labelBox"); + txtObject.y = txtObject.y + txtObject.labelMargin; + txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin; + drawText(elem, txtObject); +}; +const drawSection = function(elem, section, conf) { + const g = elem.append("g"); + const rect = getNoteRect(); + rect.x = section.x; + rect.y = section.y; + rect.fill = section.fill; + rect.width = conf.width; + rect.height = conf.height; + rect.class = "journey-section section-type-" + section.num; + rect.rx = 3; + rect.ry = 3; + drawRect(g, rect); + _drawTextCandidateFunc(conf)( + section.text, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "journey-section section-type-" + section.num }, + conf, + section.colour + ); +}; +let taskCount = -1; +const drawTask = function(elem, task, conf) { + const center = task.x + conf.width / 2; + const g = elem.append("g"); + taskCount++; + const maxHeight = 300 + 5 * 30; + g.append("line").attr("id", "task" + taskCount).attr("x1", center).attr("y1", task.y).attr("x2", center).attr("y2", maxHeight).attr("class", "task-line").attr("stroke-width", "1px").attr("stroke-dasharray", "4 2").attr("stroke", "#666"); + drawFace(g, { + cx: center, + cy: 300 + (5 - task.score) * 30, + score: task.score + }); + const rect = getNoteRect(); + rect.x = task.x; + rect.y = task.y; + rect.fill = task.fill; + rect.width = conf.width; + rect.height = conf.height; + rect.class = "task task-type-" + task.num; + rect.rx = 3; + rect.ry = 3; + drawRect(g, rect); + task.x + 14; + _drawTextCandidateFunc(conf)( + task.task, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "task" }, + conf, + task.colour + ); +}; +const drawBackgroundRect = function(elem, bounds) { + const rectElem = drawRect(elem, { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + class: "rect" + }); + rectElem.lower(); +}; +const getTextObj = function() { + return { + x: 0, + y: 0, + fill: void 0, + "text-anchor": "start", + width: 100, + height: 100, + textMargin: 0, + rx: 0, + ry: 0 + }; +}; +const getNoteRect = function() { + return { + x: 0, + y: 0, + width: 100, + anchor: "start", + height: 100, + rx: 0, + ry: 0 + }; +}; +const _drawTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs, colour) { + const text = g.append("text").attr("x", x + width / 2).attr("y", y + height / 2 + 5).style("font-color", colour).style("text-anchor", "middle").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf, colour) { + const { taskFontSize, taskFontFamily } = conf; + const lines = content.split(/<br\s*\/?>/gi); + for (let i = 0; i < lines.length; i++) { + const dy = i * taskFontSize - taskFontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x + width / 2).attr("y", y).attr("fill", colour).style("text-anchor", "middle").style("font-size", taskFontSize).style("font-family", taskFontFamily); + text.append("tspan").attr("x", x + width / 2).attr("dy", dy).text(lines[i]); + text.attr("y", y + height / 2).attr("dominant-baseline", "central").attr("alignment-baseline", "central"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf) { + const body = g.append("switch"); + const f = body.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("position", "fixed"); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").attr("class", "label").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, body, x, y, width, height, textAttrs, conf); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (key in fromTextAttrsDict) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf) { + return conf.textPlacement === "fo" ? byFo : conf.textPlacement === "old" ? byText : byTspan; + }; +}(); +const initGraphics = function(graphics) { + graphics.append("defs").append("marker").attr("id", "arrowhead").attr("refX", 5).attr("refY", 2).attr("markerWidth", 6).attr("markerHeight", 4).attr("orient", "auto").append("path").attr("d", "M 0,0 V 4 L6,2 Z"); +}; +function wrap(text, width) { + text.each(function() { + var text2 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this), words = text2.text().split(/(\s+|<br>)/).reverse(), word, line = [], lineHeight = 1.1, y = text2.attr("y"), dy = parseFloat(text2.attr("dy")), tspan = text2.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em"); + for (let j = 0; j < words.length; j++) { + word = words[words.length - 1 - j]; + line.push(word); + tspan.text(line.join(" ").trim()); + if (tspan.node().getComputedTextLength() > width || word === "<br>") { + line.pop(); + tspan.text(line.join(" ").trim()); + if (word === "<br>") { + line = [""]; + } else { + line = [word]; + } + tspan = text2.append("tspan").attr("x", 0).attr("y", y).attr("dy", lineHeight + "em").text(word); + } + } + }); +} +const drawNode = function(elem, node, fullSection, conf) { + const section = fullSection % MAX_SECTIONS - 1; + const nodeElem = elem.append("g"); + node.section = section; + nodeElem.attr( + "class", + (node.class ? node.class + " " : "") + "timeline-node " + ("section-" + section) + ); + const bkgElem = nodeElem.append("g"); + const textElem = nodeElem.append("g"); + const txt = textElem.append("text").text(node.descr).attr("dy", "1em").attr("alignment-baseline", "middle").attr("dominant-baseline", "middle").attr("text-anchor", "middle").call(wrap, node.width); + const bbox = txt.node().getBBox(); + const fontSize = conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace("px", "") : conf.fontSize; + node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding; + node.height = Math.max(node.height, node.maxHeight); + node.width = node.width + 2 * node.padding; + textElem.attr("transform", "translate(" + node.width / 2 + ", " + node.padding / 2 + ")"); + defaultBkg(bkgElem, node, section); + return node; +}; +const getVirtualNodeHeight = function(elem, node, conf) { + const textElem = elem.append("g"); + const txt = textElem.append("text").text(node.descr).attr("dy", "1em").attr("alignment-baseline", "middle").attr("dominant-baseline", "middle").attr("text-anchor", "middle").call(wrap, node.width); + const bbox = txt.node().getBBox(); + const fontSize = conf.fontSize && conf.fontSize.replace ? conf.fontSize.replace("px", "") : conf.fontSize; + textElem.remove(); + return bbox.height + fontSize * 1.1 * 0.5 + node.padding; +}; +const defaultBkg = function(elem, node, section) { + const rd = 5; + elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + node.type).attr( + "d", + `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd} q5,0 5,5 v${node.height - rd} H0 Z` + ); + elem.append("line").attr("class", "node-line-" + section).attr("x1", 0).attr("y1", node.height).attr("x2", node.width).attr("y2", node.height); +}; +const svgDraw = { + drawRect, + drawCircle, + drawSection, + drawText, + drawLabel, + drawTask, + drawBackgroundRect, + getTextObj, + getNoteRect, + initGraphics, + drawNode, + getVirtualNodeHeight +}; +const draw = function(text, id, version, diagObj) { + var _a, _b; + const conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const LEFT_MARGIN = conf.leftMargin ?? 50; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("timeline", diagObj.db); + const securityLevel = conf.securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const svg = root.select("#" + id); + svg.append("g"); + const tasks2 = diagObj.db.getTasks(); + const title = diagObj.db.getCommonDb().getDiagramTitle(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("task", tasks2); + svgDraw.initGraphics(svg); + const sections2 = diagObj.db.getSections(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("sections", sections2); + let maxSectionHeight = 0; + let maxTaskHeight = 0; + let depthY = 0; + let sectionBeginY = 0; + let masterX = 50 + LEFT_MARGIN; + let masterY = 50; + sectionBeginY = 50; + let sectionNumber = 0; + let hasSections = true; + sections2.forEach(function(section) { + const sectionNode = { + number: sectionNumber, + descr: section, + section: sectionNumber, + width: 150, + padding: 20, + maxHeight: maxSectionHeight + }; + const sectionHeight = svgDraw.getVirtualNodeHeight(svg, sectionNode, conf); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("sectionHeight before draw", sectionHeight); + maxSectionHeight = Math.max(maxSectionHeight, sectionHeight + 20); + }); + let maxEventCount = 0; + let maxEventLineLength = 0; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("tasks.length", tasks2.length); + for (const [i, task] of tasks2.entries()) { + const taskNode = { + number: i, + descr: task, + section: task.section, + width: 150, + padding: 20, + maxHeight: maxTaskHeight + }; + const taskHeight = svgDraw.getVirtualNodeHeight(svg, taskNode, conf); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("taskHeight before draw", taskHeight); + maxTaskHeight = Math.max(maxTaskHeight, taskHeight + 20); + maxEventCount = Math.max(maxEventCount, task.events.length); + let maxEventLineLengthTemp = 0; + for (let j = 0; j < task.events.length; j++) { + const event = task.events[j]; + const eventNode = { + descr: event, + section: task.section, + number: task.section, + width: 150, + padding: 20, + maxHeight: 50 + }; + maxEventLineLengthTemp += svgDraw.getVirtualNodeHeight(svg, eventNode, conf); + } + maxEventLineLength = Math.max(maxEventLineLength, maxEventLineLengthTemp); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("maxSectionHeight before draw", maxSectionHeight); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("maxTaskHeight before draw", maxTaskHeight); + if (sections2 && sections2.length > 0) { + sections2.forEach((section) => { + const tasksForSection = tasks2.filter((task) => task.section === section); + const sectionNode = { + number: sectionNumber, + descr: section, + section: sectionNumber, + width: 200 * Math.max(tasksForSection.length, 1) - 50, + padding: 20, + maxHeight: maxSectionHeight + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("sectionNode", sectionNode); + const sectionNodeWrapper = svg.append("g"); + const node = svgDraw.drawNode(sectionNodeWrapper, sectionNode, sectionNumber, conf); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("sectionNode output", node); + sectionNodeWrapper.attr("transform", `translate(${masterX}, ${sectionBeginY})`); + masterY += maxSectionHeight + 50; + if (tasksForSection.length > 0) { + drawTasks( + svg, + tasksForSection, + sectionNumber, + masterX, + masterY, + maxTaskHeight, + conf, + maxEventCount, + maxEventLineLength, + maxSectionHeight, + false + ); + } + masterX += 200 * Math.max(tasksForSection.length, 1); + masterY = sectionBeginY; + sectionNumber++; + }); + } else { + hasSections = false; + drawTasks( + svg, + tasks2, + sectionNumber, + masterX, + masterY, + maxTaskHeight, + conf, + maxEventCount, + maxEventLineLength, + maxSectionHeight, + true + ); + } + const box = svg.node().getBBox(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("bounds", box); + if (title) { + svg.append("text").text(title).attr("x", box.width / 2 - LEFT_MARGIN).attr("font-size", "4ex").attr("font-weight", "bold").attr("y", 20); + } + depthY = hasSections ? maxSectionHeight + maxTaskHeight + 150 : maxTaskHeight + 100; + const lineWrapper = svg.append("g").attr("class", "lineWrapper"); + lineWrapper.append("line").attr("x1", LEFT_MARGIN).attr("y1", depthY).attr("x2", box.width + 3 * LEFT_MARGIN).attr("y2", depthY).attr("stroke-width", 4).attr("stroke", "black").attr("marker-end", "url(#arrowhead)"); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.o)( + void 0, + svg, + ((_a = conf.timeline) == null ? void 0 : _a.padding) ?? 50, + ((_b = conf.timeline) == null ? void 0 : _b.useMaxWidth) ?? false + ); +}; +const drawTasks = function(diagram2, tasks2, sectionColor, masterX, masterY, maxTaskHeight, conf, maxEventCount, maxEventLineLength, maxSectionHeight, isWithoutSections) { + var _a; + for (const task of tasks2) { + const taskNode = { + descr: task.task, + section: sectionColor, + number: sectionColor, + width: 150, + padding: 20, + maxHeight: maxTaskHeight + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("taskNode", taskNode); + const taskWrapper = diagram2.append("g").attr("class", "taskWrapper"); + const node = svgDraw.drawNode(taskWrapper, taskNode, sectionColor, conf); + const taskHeight = node.height; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("taskHeight after draw", taskHeight); + taskWrapper.attr("transform", `translate(${masterX}, ${masterY})`); + maxTaskHeight = Math.max(maxTaskHeight, taskHeight); + if (task.events) { + const lineWrapper = diagram2.append("g").attr("class", "lineWrapper"); + let lineLength = maxTaskHeight; + masterY += 100; + lineLength = lineLength + drawEvents(diagram2, task.events, sectionColor, masterX, masterY, conf); + masterY -= 100; + lineWrapper.append("line").attr("x1", masterX + 190 / 2).attr("y1", masterY + maxTaskHeight).attr("x2", masterX + 190 / 2).attr( + "y2", + masterY + maxTaskHeight + (isWithoutSections ? maxTaskHeight : maxSectionHeight) + maxEventLineLength + 120 + ).attr("stroke-width", 2).attr("stroke", "black").attr("marker-end", "url(#arrowhead)").attr("stroke-dasharray", "5,5"); + } + masterX = masterX + 200; + if (isWithoutSections && !((_a = conf.timeline) == null ? void 0 : _a.disableMulticolor)) { + sectionColor++; + } + } + masterY = masterY - 10; +}; +const drawEvents = function(diagram2, events, sectionColor, masterX, masterY, conf) { + let maxEventHeight = 0; + const eventBeginY = masterY; + masterY = masterY + 100; + for (const event of events) { + const eventNode = { + descr: event, + section: sectionColor, + number: sectionColor, + width: 150, + padding: 20, + maxHeight: 50 + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("eventNode", eventNode); + const eventWrapper = diagram2.append("g").attr("class", "eventWrapper"); + const node = svgDraw.drawNode(eventWrapper, eventNode, sectionColor, conf); + const eventHeight = node.height; + maxEventHeight = maxEventHeight + eventHeight; + eventWrapper.attr("transform", `translate(${masterX}, ${masterY})`); + masterY = masterY + 10 + eventHeight; + } + masterY = eventBeginY; + return maxEventHeight; +}; +const renderer = { + setConf: () => { + }, + draw +}; +const genSections = (options) => { + let sections2 = ""; + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + options["lineColor" + i] = options["lineColor" + i] || options["cScaleInv" + i]; + if ((0,khroma__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(options["lineColor" + i])) { + options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .Z)(options["lineColor" + i], 20); + } else { + options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_7__/* ["default"] */ .Z)(options["lineColor" + i], 20); + } + } + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + const sw = "" + (17 - 3 * i); + sections2 += ` + .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} path { + fill: ${options["cScale" + i]}; + } + .section-${i - 1} text { + fill: ${options["cScaleLabel" + i]}; + } + .node-icon-${i - 1} { + font-size: 40px; + color: ${options["cScaleLabel" + i]}; + } + .section-edge-${i - 1}{ + stroke: ${options["cScale" + i]}; + } + .edge-depth-${i - 1}{ + stroke-width: ${sw}; + } + .section-${i - 1} line { + stroke: ${options["cScaleInv" + i]} ; + stroke-width: 3; + } + + .lineWrapper line{ + stroke: ${options["cScaleLabel" + i]} ; + } + + .disabled, .disabled circle, .disabled text { + fill: lightgray; + } + .disabled text { + fill: #efefef; + } + `; + } + return sections2; +}; +const getStyles = (options) => ` + .edge { + stroke-width: 3; + } + ${genSections(options)} + .section-root rect, .section-root path, .section-root circle { + fill: ${options.git0}; + } + .section-root text { + fill: ${options.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .eventWrapper { + filter: brightness(120%); + } +`; +const styles = getStyles; +const diagram = { + db, + renderer, + parser: parser$1, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/4697.d30ed957.js b/assets/js/4697.d30ed957.js new file mode 100644 index 000000000..99e6be7e5 --- /dev/null +++ b/assets/js/4697.d30ed957.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4697],{74697:(e,n,t)=>{t.d(n,{a:()=>ln,c:()=>cn});var r={};t.r(r),t.d(r,{attentionMarkers:()=>Me,contentInitial:()=>Te,disable:()=>Pe,document:()=>Ce,flow:()=>De,flowInitial:()=>ze,insideSpan:()=>Le,string:()=>Be,text:()=>_e});var i=t(56363);const u={};function o(e,n,t){if(function(e){return Boolean(e&&"object"==typeof e)}(e)){if("value"in e)return"html"!==e.type||t?e.value:"";if(n&&"alt"in e&&e.alt)return e.alt;if("children"in e)return c(e.children,n,t)}return Array.isArray(e)?c(e,n,t):""}function c(e,n,t){const r=[];let i=-1;for(;++i<e.length;)r[i]=o(e[i],n,t);return r.join("")}function s(e,n,t,r){const i=e.length;let u,o=0;if(n=n<0?-n>i?0:i+n:n>i?i:n,t=t>0?t:0,r.length<1e4)u=Array.from(r),u.unshift(n,t),e.splice(...u);else for(t&&e.splice(n,t);o<r.length;)u=r.slice(o,o+1e4),u.unshift(n,0),e.splice(...u),o+=1e4,n+=1e4}function l(e,n){return e.length>0?(s(e,e.length,0,n),e):n}const a={}.hasOwnProperty;function f(e,n){let t;for(t in n){const r=(a.call(e,t)?e[t]:void 0)||(e[t]={}),i=n[t];let u;if(i)for(u in i){a.call(r,u)||(r[u]=[]);const e=i[u];d(r[u],Array.isArray(e)?e:e?[e]:[])}}}function d(e,n){let t=-1;const r=[];for(;++t<n.length;)("after"===n[t].add?e:r).push(n[t]);s(e,0,0,r)}const h=A(/[A-Za-z]/),p=A(/[\dA-Za-z]/),m=A(/[#-'*+\--9=?A-Z^-~]/);function g(e){return null!==e&&(e<32||127===e)}const x=A(/\d/),k=A(/[\dA-Fa-f]/),y=A(/[!-/:-@[-`{-~]/);function F(e){return null!==e&&e<-2}function v(e){return null!==e&&(e<0||32===e)}function b(e){return-2===e||-1===e||32===e}const S=A(/[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/),E=A(/\s/);function A(e){return function(n){return null!==n&&e.test(String.fromCharCode(n))}}function w(e,n,t,r){const i=r?r-1:Number.POSITIVE_INFINITY;let u=0;return function(r){if(b(r))return e.enter(t),o(r);return n(r)};function o(r){return b(r)&&u++<i?(e.consume(r),o):(e.exit(t),n(r))}}const I={tokenize:function(e){const n=e.attempt(this.parser.constructs.contentInitial,(function(t){if(null===t)return void e.consume(t);return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),w(e,n,"linePrefix")}),(function(n){return e.enter("paragraph"),r(n)}));let t;return n;function r(n){const r=e.enter("chunkText",{contentType:"text",previous:t});return t&&(t.next=r),t=r,i(n)}function i(n){return null===n?(e.exit("chunkText"),e.exit("paragraph"),void e.consume(n)):F(n)?(e.consume(n),e.exit("chunkText"),r):(e.consume(n),i)}}};const C={tokenize:function(e){const n=this,t=[];let r,i,u,o=0;return c;function c(r){if(o<t.length){const i=t[o];return n.containerState=i[1],e.attempt(i[0].continuation,l,a)(r)}return a(r)}function l(e){if(o++,n.containerState._closeFlow){n.containerState._closeFlow=void 0,r&&y();const t=n.events.length;let i,u=t;for(;u--;)if("exit"===n.events[u][0]&&"chunkFlow"===n.events[u][1].type){i=n.events[u][1].end;break}k(o);let c=t;for(;c<n.events.length;)n.events[c][1].end=Object.assign({},i),c++;return s(n.events,u+1,0,n.events.slice(t)),n.events.length=c,a(e)}return c(e)}function a(i){if(o===t.length){if(!r)return h(i);if(r.currentConstruct&&r.currentConstruct.concrete)return m(i);n.interrupt=Boolean(r.currentConstruct&&!r._gfmTableDynamicInterruptHack)}return n.containerState={},e.check(T,f,d)(i)}function f(e){return r&&y(),k(o),h(e)}function d(e){return n.parser.lazy[n.now().line]=o!==t.length,u=n.now().offset,m(e)}function h(t){return n.containerState={},e.attempt(T,p,m)(t)}function p(e){return o++,t.push([n.currentConstruct,n.containerState]),h(e)}function m(t){return null===t?(r&&y(),k(0),void e.consume(t)):(r=r||n.parser.flow(n.now()),e.enter("chunkFlow",{contentType:"flow",previous:i,_tokenizer:r}),g(t))}function g(t){return null===t?(x(e.exit("chunkFlow"),!0),k(0),void e.consume(t)):F(t)?(e.consume(t),x(e.exit("chunkFlow")),o=0,n.interrupt=void 0,c):(e.consume(t),g)}function x(e,t){const c=n.sliceStream(e);if(t&&c.push(null),e.previous=i,i&&(i.next=e),i=e,r.defineSkip(e.start),r.write(c),n.parser.lazy[e.start.line]){let e=r.events.length;for(;e--;)if(r.events[e][1].start.offset<u&&(!r.events[e][1].end||r.events[e][1].end.offset>u))return;const t=n.events.length;let i,c,l=t;for(;l--;)if("exit"===n.events[l][0]&&"chunkFlow"===n.events[l][1].type){if(i){c=n.events[l][1].end;break}i=!0}for(k(o),e=t;e<n.events.length;)n.events[e][1].end=Object.assign({},c),e++;s(n.events,l+1,0,n.events.slice(t)),n.events.length=e}}function k(r){let i=t.length;for(;i-- >r;){const r=t[i];n.containerState=r[1],r[0].exit.call(n,e)}t.length=r}function y(){r.write([null]),i=void 0,r=void 0,n.containerState._closeFlow=void 0}}},T={tokenize:function(e,n,t){return w(e,e.attempt(this.parser.constructs.document,n,t),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}};const z={tokenize:function(e,n,t){return function(n){return b(n)?w(e,r,"linePrefix")(n):r(n)};function r(e){return null===e||F(e)?n(e):t(e)}},partial:!0};function D(e,n,t,r){const i=e.length;let u,o=0;if(n=n<0?-n>i?0:i+n:n>i?i:n,t=t>0?t:0,r.length<1e4)u=Array.from(r),u.unshift(n,t),e.splice(...u);else for(t&&e.splice(n,t);o<r.length;)u=r.slice(o,o+1e4),u.unshift(n,0),e.splice(...u),o+=1e4,n+=1e4}function B(e){const n={};let t,r,i,u,o,c,s,l=-1;for(;++l<e.length;){for(;l in n;)l=n[l];if(t=e[l],l&&"chunkFlow"===t[1].type&&"listItemPrefix"===e[l-1][1].type&&(c=t[1]._tokenizer.events,i=0,i<c.length&&"lineEndingBlank"===c[i][1].type&&(i+=2),i<c.length&&"content"===c[i][1].type))for(;++i<c.length&&"content"!==c[i][1].type;)"chunkText"===c[i][1].type&&(c[i][1]._isInFirstContentOfListItem=!0,i++);if("enter"===t[0])t[1].contentType&&(Object.assign(n,_(e,l)),l=n[l],s=!0);else if(t[1]._container){for(i=l,r=void 0;i--&&(u=e[i],"lineEnding"===u[1].type||"lineEndingBlank"===u[1].type);)"enter"===u[0]&&(r&&(e[r][1].type="lineEndingBlank"),u[1].type="lineEnding",r=i);r&&(t[1].end=Object.assign({},e[r][1].start),o=e.slice(r,l),o.unshift(t),D(e,r,l-r+1,o))}}return!s}function _(e,n){const t=e[n][1],r=e[n][2];let i=n-1;const u=[],o=t._tokenizer||r.parser[t.contentType](t.start),c=o.events,s=[],l={};let a,f,d=-1,h=t,p=0,m=0;const g=[m];for(;h;){for(;e[++i][1]!==h;);u.push(i),h._tokenizer||(a=r.sliceStream(h),h.next||a.push(null),f&&o.defineSkip(h.start),h._isInFirstContentOfListItem&&(o._gfmTasklistFirstContentOfListItem=!0),o.write(a),h._isInFirstContentOfListItem&&(o._gfmTasklistFirstContentOfListItem=void 0)),f=h,h=h.next}for(h=t;++d<c.length;)"exit"===c[d][0]&&"enter"===c[d-1][0]&&c[d][1].type===c[d-1][1].type&&c[d][1].start.line!==c[d][1].end.line&&(m=d+1,g.push(m),h._tokenizer=void 0,h.previous=void 0,h=h.next);for(o.events=[],h?(h._tokenizer=void 0,h.previous=void 0):g.pop(),d=g.length;d--;){const n=c.slice(g[d],g[d+1]),t=u.pop();s.unshift([t,t+n.length-1]),D(e,t,2,n)}for(d=-1;++d<s.length;)l[p+s[d][0]]=p+s[d][1],p+=s[d][1]-s[d][0]-1;return l}const L={tokenize:function(e,n){let t;return function(n){return e.enter("content"),t=e.enter("chunkContent",{contentType:"content"}),r(n)};function r(n){return null===n?i(n):F(n)?e.check(M,u,i)(n):(e.consume(n),r)}function i(t){return e.exit("chunkContent"),e.exit("content"),n(t)}function u(n){return e.consume(n),e.exit("chunkContent"),t.next=e.enter("chunkContent",{contentType:"content",previous:t}),t=t.next,r}},resolve:function(e){return B(e),e}},M={tokenize:function(e,n,t){const r=this;return function(n){return e.exit("chunkContent"),e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),w(e,i,"linePrefix")};function i(i){if(null===i||F(i))return t(i);const u=r.events[r.events.length-1];return!r.parser.constructs.disable.null.includes("codeIndented")&&u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?n(i):e.interrupt(r.parser.constructs.flow,t,n)(i)}},partial:!0};const P={tokenize:function(e){const n=this,t=e.attempt(z,(function(r){if(null===r)return void e.consume(r);return e.enter("lineEndingBlank"),e.consume(r),e.exit("lineEndingBlank"),n.currentConstruct=void 0,t}),e.attempt(this.parser.constructs.flowInitial,r,w(e,e.attempt(this.parser.constructs.flow,r,e.attempt(L,r)),"linePrefix")));return t;function r(r){if(null!==r)return e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),n.currentConstruct=void 0,t;e.consume(r)}}};const O={resolveAll:q()},j=R("string"),H=R("text");function R(e){return{tokenize:function(n){const t=this,r=this.parser.constructs[e],i=n.attempt(r,u,o);return u;function u(e){return s(e)?i(e):o(e)}function o(e){if(null!==e)return n.enter("data"),n.consume(e),c;n.consume(e)}function c(e){return s(e)?(n.exit("data"),i(e)):(n.consume(e),c)}function s(e){if(null===e)return!0;const n=r[e];let i=-1;if(n)for(;++i<n.length;){const e=n[i];if(!e.previous||e.previous.call(t,t.previous))return!0}return!1}},resolveAll:q("text"===e?V:void 0)}}function q(e){return function(n,t){let r,i=-1;for(;++i<=n.length;)void 0===r?n[i]&&"data"===n[i][1].type&&(r=i,i++):n[i]&&"data"===n[i][1].type||(i!==r+2&&(n[r][1].end=n[i-1][1].end,n.splice(r+2,i-r-2),i=r+2),r=void 0);return e?e(n,t):n}}function V(e,n){let t=0;for(;++t<=e.length;)if((t===e.length||"lineEnding"===e[t][1].type)&&"data"===e[t-1][1].type){const r=e[t-1][1],i=n.sliceStream(r);let u,o=i.length,c=-1,s=0;for(;o--;){const e=i[o];if("string"==typeof e){for(c=e.length;32===e.charCodeAt(c-1);)s++,c--;if(c)break;c=-1}else if(-2===e)u=!0,s++;else if(-1!==e){o++;break}}if(s){const i={type:t===e.length||u||s<2?"lineSuffix":"hardBreakTrailing",start:{line:r.end.line,column:r.end.column-s,offset:r.end.offset-s,_index:r.start._index+o,_bufferIndex:o?c:r.start._bufferIndex+c},end:Object.assign({},r.end)};r.end=Object.assign({},i.start),r.start.offset===r.end.offset?Object.assign(r,i):(e.splice(t,0,["enter",i,n],["exit",i,n]),t+=2)}t++}return e}function Q(e,n,t){const r=[];let i=-1;for(;++i<e.length;){const u=e[i].resolveAll;u&&!r.includes(u)&&(n=u(n,t),r.push(u))}return n}function N(e,n,t){let r=Object.assign(t?Object.assign({},t):{line:1,column:1,offset:0},{_index:0,_bufferIndex:-1});const i={},u=[];let o=[],c=[],a=!0;const f={consume:function(e){F(e)?(r.line++,r.column=1,r.offset+=-3===e?2:1,S()):-1!==e&&(r.column++,r.offset++);r._bufferIndex<0?r._index++:(r._bufferIndex++,r._bufferIndex===o[r._index].length&&(r._bufferIndex=-1,r._index++));d.previous=e,a=!0},enter:function(e,n){const t=n||{};return t.type=e,t.start=g(),d.events.push(["enter",t,d]),c.push(t),t},exit:function(e){const n=c.pop();return n.end=g(),d.events.push(["exit",n,d]),n},attempt:v((function(e,n){b(e,n.from)})),check:v(y),interrupt:v(y,{interrupt:!0})},d={previous:null,code:null,containerState:{},events:[],parser:e,sliceStream:m,sliceSerialize:function(e,n){return function(e,n){let t=-1;const r=[];let i;for(;++t<e.length;){const u=e[t];let o;if("string"==typeof u)o=u;else switch(u){case-5:o="\r";break;case-4:o="\n";break;case-3:o="\r\n";break;case-2:o=n?" ":"\t";break;case-1:if(!n&&i)continue;o=" ";break;default:o=String.fromCharCode(u)}i=-2===u,r.push(o)}return r.join("")}(m(e),n)},now:g,defineSkip:function(e){i[e.line]=e.column,S()},write:function(e){if(o=l(o,e),x(),null!==o[o.length-1])return[];return b(n,0),d.events=Q(u,d.events,d),d.events}};let h,p=n.tokenize.call(d,f);return n.resolveAll&&u.push(n),d;function m(e){return function(e,n){const t=n.start._index,r=n.start._bufferIndex,i=n.end._index,u=n.end._bufferIndex;let o;if(t===i)o=[e[t].slice(r,u)];else{if(o=e.slice(t,i),r>-1){const e=o[0];"string"==typeof e?o[0]=e.slice(r):o.shift()}u>0&&o.push(e[i].slice(0,u))}return o}(o,e)}function g(){const{line:e,column:n,offset:t,_index:i,_bufferIndex:u}=r;return{line:e,column:n,offset:t,_index:i,_bufferIndex:u}}function x(){let e;for(;r._index<o.length;){const n=o[r._index];if("string"==typeof n)for(e=r._index,r._bufferIndex<0&&(r._bufferIndex=0);r._index===e&&r._bufferIndex<n.length;)k(n.charCodeAt(r._bufferIndex));else k(n)}}function k(e){a=void 0,h=e,p=p(e)}function y(e,n){n.restore()}function v(e,n){return function(t,i,u){let o,s,l,h;return Array.isArray(t)?p(t):"tokenize"in t?p([t]):function(e){return n;function n(n){const t=null!==n&&e[n],r=null!==n&&e.null;return p([...Array.isArray(t)?t:t?[t]:[],...Array.isArray(r)?r:r?[r]:[]])(n)}}(t);function p(e){return o=e,s=0,0===e.length?u:m(e[s])}function m(e){return function(t){h=function(){const e=g(),n=d.previous,t=d.currentConstruct,i=d.events.length,u=Array.from(c);return{restore:o,from:i};function o(){r=e,d.previous=n,d.currentConstruct=t,d.events.length=i,c=u,S()}}(),l=e,e.partial||(d.currentConstruct=e);if(e.name&&d.parser.constructs.disable.null.includes(e.name))return k(t);return e.tokenize.call(n?Object.assign(Object.create(d),n):d,f,x,k)(t)}}function x(n){return a=!0,e(l,h),i}function k(e){return a=!0,h.restore(),++s<o.length?m(o[s]):u}}}function b(e,n){e.resolveAll&&!u.includes(e)&&u.push(e),e.resolve&&s(d.events,n,d.events.length-n,e.resolve(d.events.slice(n),d)),e.resolveTo&&(d.events=e.resolveTo(d.events,d))}function S(){r.line in i&&r.column<2&&(r.column=i[r.line],r.offset+=i[r.line]-1)}}const U={name:"thematicBreak",tokenize:function(e,n,t){let r,i=0;return function(n){return e.enter("thematicBreak"),function(e){return r=e,u(e)}(n)};function u(u){return u===r?(e.enter("thematicBreakSequence"),o(u)):i>=3&&(null===u||F(u))?(e.exit("thematicBreak"),n(u)):t(u)}function o(n){return n===r?(e.consume(n),i++,o):(e.exit("thematicBreakSequence"),b(n)?w(e,u,"whitespace")(n):u(n))}}};const $={name:"list",tokenize:function(e,n,t){const r=this,i=r.events[r.events.length-1];let u=i&&"linePrefix"===i[1].type?i[2].sliceSerialize(i[1],!0).length:0,o=0;return function(n){const i=r.containerState.type||(42===n||43===n||45===n?"listUnordered":"listOrdered");if("listUnordered"===i?!r.containerState.marker||n===r.containerState.marker:x(n)){if(r.containerState.type||(r.containerState.type=i,e.enter(i,{_container:!0})),"listUnordered"===i)return e.enter("listItemPrefix"),42===n||45===n?e.check(U,t,s)(n):s(n);if(!r.interrupt||49===n)return e.enter("listItemPrefix"),e.enter("listItemValue"),c(n)}return t(n)};function c(n){return x(n)&&++o<10?(e.consume(n),c):(!r.interrupt||o<2)&&(r.containerState.marker?n===r.containerState.marker:41===n||46===n)?(e.exit("listItemValue"),s(n)):t(n)}function s(n){return e.enter("listItemMarker"),e.consume(n),e.exit("listItemMarker"),r.containerState.marker=r.containerState.marker||n,e.check(z,r.interrupt?t:l,e.attempt(W,f,a))}function l(e){return r.containerState.initialBlankLine=!0,u++,f(e)}function a(n){return b(n)?(e.enter("listItemPrefixWhitespace"),e.consume(n),e.exit("listItemPrefixWhitespace"),f):t(n)}function f(t){return r.containerState.size=u+r.sliceSerialize(e.exit("listItemPrefix"),!0).length,n(t)}},continuation:{tokenize:function(e,n,t){const r=this;return r.containerState._closeFlow=void 0,e.check(z,(function(t){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,w(e,n,"listItemIndent",r.containerState.size+1)(t)}),(function(t){if(r.containerState.furtherBlankLines||!b(t))return r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,i(t);return r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,e.attempt(Z,n,i)(t)}));function i(i){return r.containerState._closeFlow=!0,r.interrupt=void 0,w(e,e.attempt($,n,t),"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(i)}}},exit:function(e){e.exit(this.containerState.type)}},W={tokenize:function(e,n,t){const r=this;return w(e,(function(e){const i=r.events[r.events.length-1];return!b(e)&&i&&"listItemPrefixWhitespace"===i[1].type?n(e):t(e)}),"listItemPrefixWhitespace",r.parser.constructs.disable.null.includes("codeIndented")?void 0:5)},partial:!0},Z={tokenize:function(e,n,t){const r=this;return w(e,(function(e){const i=r.events[r.events.length-1];return i&&"listItemIndent"===i[1].type&&i[2].sliceSerialize(i[1],!0).length===r.containerState.size?n(e):t(e)}),"listItemIndent",r.containerState.size+1)},partial:!0};const Y={name:"blockQuote",tokenize:function(e,n,t){const r=this;return function(n){if(62===n){const t=r.containerState;return t.open||(e.enter("blockQuote",{_container:!0}),t.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(n),e.exit("blockQuoteMarker"),i}return t(n)};function i(t){return b(t)?(e.enter("blockQuotePrefixWhitespace"),e.consume(t),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),n):(e.exit("blockQuotePrefix"),n(t))}},continuation:{tokenize:function(e,n,t){const r=this;return function(n){if(b(n))return w(e,i,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n);return i(n)};function i(r){return e.attempt(Y,n,t)(r)}}},exit:function(e){e.exit("blockQuote")}};function J(e,n,t,r,i,u,o,c,s){const l=s||Number.POSITIVE_INFINITY;let a=0;return function(n){if(60===n)return e.enter(r),e.enter(i),e.enter(u),e.consume(n),e.exit(u),f;if(null===n||32===n||41===n||g(n))return t(n);return e.enter(r),e.enter(o),e.enter(c),e.enter("chunkString",{contentType:"string"}),p(n)};function f(t){return 62===t?(e.enter(u),e.consume(t),e.exit(u),e.exit(i),e.exit(r),n):(e.enter(c),e.enter("chunkString",{contentType:"string"}),d(t))}function d(n){return 62===n?(e.exit("chunkString"),e.exit(c),f(n)):null===n||60===n||F(n)?t(n):(e.consume(n),92===n?h:d)}function h(n){return 60===n||62===n||92===n?(e.consume(n),d):d(n)}function p(i){return a||null!==i&&41!==i&&!v(i)?a<l&&40===i?(e.consume(i),a++,p):41===i?(e.consume(i),a--,p):null===i||32===i||40===i||g(i)?t(i):(e.consume(i),92===i?m:p):(e.exit("chunkString"),e.exit(c),e.exit(o),e.exit(r),n(i))}function m(n){return 40===n||41===n||92===n?(e.consume(n),p):p(n)}}function G(e,n,t,r,i,u){const o=this;let c,s=0;return function(n){return e.enter(r),e.enter(i),e.consume(n),e.exit(i),e.enter(u),l};function l(f){return s>999||null===f||91===f||93===f&&!c||94===f&&!s&&"_hiddenFootnoteSupport"in o.parser.constructs?t(f):93===f?(e.exit(u),e.enter(i),e.consume(f),e.exit(i),e.exit(r),n):F(f)?(e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),l):(e.enter("chunkString",{contentType:"string"}),a(f))}function a(n){return null===n||91===n||93===n||F(n)||s++>999?(e.exit("chunkString"),l(n)):(e.consume(n),c||(c=!b(n)),92===n?f:a)}function f(n){return 91===n||92===n||93===n?(e.consume(n),s++,a):a(n)}}function K(e,n,t,r,i,u){let o;return function(n){if(34===n||39===n||40===n)return e.enter(r),e.enter(i),e.consume(n),e.exit(i),o=40===n?41:n,c;return t(n)};function c(t){return t===o?(e.enter(i),e.consume(t),e.exit(i),e.exit(r),n):(e.enter(u),s(t))}function s(n){return n===o?(e.exit(u),c(o)):null===n?t(n):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),w(e,s,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),l(n))}function l(n){return n===o||null===n||F(n)?(e.exit("chunkString"),s(n)):(e.consume(n),92===n?a:l)}function a(n){return n===o||92===n?(e.consume(n),l):l(n)}}function X(e,n){let t;return function r(i){if(F(i))return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),t=!0,r;if(b(i))return w(e,r,t?"linePrefix":"lineSuffix")(i);return n(i)}}function ee(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const ne={name:"definition",tokenize:function(e,n,t){const r=this;let i;return function(n){return e.enter("definition"),function(n){return G.call(r,e,u,t,"definitionLabel","definitionLabelMarker","definitionLabelString")(n)}(n)};function u(n){return i=ee(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),58===n?(e.enter("definitionMarker"),e.consume(n),e.exit("definitionMarker"),o):t(n)}function o(n){return v(n)?X(e,c)(n):c(n)}function c(n){return J(e,s,t,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(n)}function s(n){return e.attempt(te,l,l)(n)}function l(n){return b(n)?w(e,a,"whitespace")(n):a(n)}function a(u){return null===u||F(u)?(e.exit("definition"),r.parser.defined.push(i),n(u)):t(u)}}},te={tokenize:function(e,n,t){return function(n){return v(n)?X(e,r)(n):t(n)};function r(n){return K(e,i,t,"definitionTitle","definitionTitleMarker","definitionTitleString")(n)}function i(n){return b(n)?w(e,u,"whitespace")(n):u(n)}function u(e){return null===e||F(e)?n(e):t(e)}},partial:!0};const re={name:"codeIndented",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("codeIndented"),w(e,i,"linePrefix",5)(n)};function i(e){const n=r.events[r.events.length-1];return n&&"linePrefix"===n[1].type&&n[2].sliceSerialize(n[1],!0).length>=4?u(e):t(e)}function u(n){return null===n?c(n):F(n)?e.attempt(ie,u,c)(n):(e.enter("codeFlowValue"),o(n))}function o(n){return null===n||F(n)?(e.exit("codeFlowValue"),u(n)):(e.consume(n),o)}function c(t){return e.exit("codeIndented"),n(t)}}},ie={tokenize:function(e,n,t){const r=this;return i;function i(n){return r.parser.lazy[r.now().line]?t(n):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i):w(e,u,"linePrefix",5)(n)}function u(e){const u=r.events[r.events.length-1];return u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?n(e):F(e)?i(e):t(e)}},partial:!0};const ue={name:"headingAtx",tokenize:function(e,n,t){let r=0;return function(n){return e.enter("atxHeading"),function(n){return e.enter("atxHeadingSequence"),i(n)}(n)};function i(n){return 35===n&&r++<6?(e.consume(n),i):null===n||v(n)?(e.exit("atxHeadingSequence"),u(n)):t(n)}function u(t){return 35===t?(e.enter("atxHeadingSequence"),o(t)):null===t||F(t)?(e.exit("atxHeading"),n(t)):b(t)?w(e,u,"whitespace")(t):(e.enter("atxHeadingText"),c(t))}function o(n){return 35===n?(e.consume(n),o):(e.exit("atxHeadingSequence"),u(n))}function c(n){return null===n||35===n||v(n)?(e.exit("atxHeadingText"),u(n)):(e.consume(n),c)}},resolve:function(e,n){let t,r,i=e.length-2,u=3;"whitespace"===e[u][1].type&&(u+=2);i-2>u&&"whitespace"===e[i][1].type&&(i-=2);"atxHeadingSequence"===e[i][1].type&&(u===i-1||i-4>u&&"whitespace"===e[i-2][1].type)&&(i-=u+1===i?2:4);i>u&&(t={type:"atxHeadingText",start:e[u][1].start,end:e[i][1].end},r={type:"chunkText",start:e[u][1].start,end:e[i][1].end,contentType:"text"},s(e,u,i-u+1,[["enter",t,n],["enter",r,n],["exit",r,n],["exit",t,n]]));return e}};const oe={name:"setextUnderline",tokenize:function(e,n,t){const r=this;let i;return function(n){let o,c=r.events.length;for(;c--;)if("lineEnding"!==r.events[c][1].type&&"linePrefix"!==r.events[c][1].type&&"content"!==r.events[c][1].type){o="paragraph"===r.events[c][1].type;break}if(!r.parser.lazy[r.now().line]&&(r.interrupt||o))return e.enter("setextHeadingLine"),i=n,function(n){return e.enter("setextHeadingLineSequence"),u(n)}(n);return t(n)};function u(n){return n===i?(e.consume(n),u):(e.exit("setextHeadingLineSequence"),b(n)?w(e,o,"lineSuffix")(n):o(n))}function o(r){return null===r||F(r)?(e.exit("setextHeadingLine"),n(r)):t(r)}},resolveTo:function(e,n){let t,r,i,u=e.length;for(;u--;)if("enter"===e[u][0]){if("content"===e[u][1].type){t=u;break}"paragraph"===e[u][1].type&&(r=u)}else"content"===e[u][1].type&&e.splice(u,1),i||"definition"!==e[u][1].type||(i=u);const o={type:"setextHeading",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)};e[r][1].type="setextHeadingText",i?(e.splice(r,0,["enter",o,n]),e.splice(i+1,0,["exit",e[t][1],n]),e[t][1].end=Object.assign({},e[i][1].end)):e[t][1]=o;return e.push(["exit",o,n]),e}};const ce=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],se=["pre","script","style","textarea"],le={name:"htmlFlow",tokenize:function(e,n,t){const r=this;let i,u,o,c,s;return function(n){return function(n){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(n),l}(n)};function l(c){return 33===c?(e.consume(c),a):47===c?(e.consume(c),u=!0,m):63===c?(e.consume(c),i=3,r.interrupt?n:H):h(c)?(e.consume(c),o=String.fromCharCode(c),g):t(c)}function a(u){return 45===u?(e.consume(u),i=2,f):91===u?(e.consume(u),i=5,c=0,d):h(u)?(e.consume(u),i=4,r.interrupt?n:H):t(u)}function f(i){return 45===i?(e.consume(i),r.interrupt?n:H):t(i)}function d(i){const u="CDATA[";return i===u.charCodeAt(c++)?(e.consume(i),6===c?r.interrupt?n:D:d):t(i)}function m(n){return h(n)?(e.consume(n),o=String.fromCharCode(n),g):t(n)}function g(c){if(null===c||47===c||62===c||v(c)){const s=47===c,l=o.toLowerCase();return s||u||!se.includes(l)?ce.includes(o.toLowerCase())?(i=6,s?(e.consume(c),x):r.interrupt?n(c):D(c)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?t(c):u?k(c):y(c)):(i=1,r.interrupt?n(c):D(c))}return 45===c||p(c)?(e.consume(c),o+=String.fromCharCode(c),g):t(c)}function x(i){return 62===i?(e.consume(i),r.interrupt?n:D):t(i)}function k(n){return b(n)?(e.consume(n),k):T(n)}function y(n){return 47===n?(e.consume(n),T):58===n||95===n||h(n)?(e.consume(n),S):b(n)?(e.consume(n),y):T(n)}function S(n){return 45===n||46===n||58===n||95===n||p(n)?(e.consume(n),S):E(n)}function E(n){return 61===n?(e.consume(n),A):b(n)?(e.consume(n),E):y(n)}function A(n){return null===n||60===n||61===n||62===n||96===n?t(n):34===n||39===n?(e.consume(n),s=n,w):b(n)?(e.consume(n),A):I(n)}function w(n){return n===s?(e.consume(n),s=null,C):null===n||F(n)?t(n):(e.consume(n),w)}function I(n){return null===n||34===n||39===n||47===n||60===n||61===n||62===n||96===n||v(n)?E(n):(e.consume(n),I)}function C(e){return 47===e||62===e||b(e)?y(e):t(e)}function T(n){return 62===n?(e.consume(n),z):t(n)}function z(n){return null===n||F(n)?D(n):b(n)?(e.consume(n),z):t(n)}function D(n){return 45===n&&2===i?(e.consume(n),M):60===n&&1===i?(e.consume(n),P):62===n&&4===i?(e.consume(n),R):63===n&&3===i?(e.consume(n),H):93===n&&5===i?(e.consume(n),j):!F(n)||6!==i&&7!==i?null===n||F(n)?(e.exit("htmlFlowData"),B(n)):(e.consume(n),D):(e.exit("htmlFlowData"),e.check(ae,q,B)(n))}function B(n){return e.check(fe,_,q)(n)}function _(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),L}function L(n){return null===n||F(n)?B(n):(e.enter("htmlFlowData"),D(n))}function M(n){return 45===n?(e.consume(n),H):D(n)}function P(n){return 47===n?(e.consume(n),o="",O):D(n)}function O(n){if(62===n){const t=o.toLowerCase();return se.includes(t)?(e.consume(n),R):D(n)}return h(n)&&o.length<8?(e.consume(n),o+=String.fromCharCode(n),O):D(n)}function j(n){return 93===n?(e.consume(n),H):D(n)}function H(n){return 62===n?(e.consume(n),R):45===n&&2===i?(e.consume(n),H):D(n)}function R(n){return null===n||F(n)?(e.exit("htmlFlowData"),q(n)):(e.consume(n),R)}function q(t){return e.exit("htmlFlow"),n(t)}},resolveTo:function(e){let n=e.length;for(;n--&&("enter"!==e[n][0]||"htmlFlow"!==e[n][1].type););n>1&&"linePrefix"===e[n-2][1].type&&(e[n][1].start=e[n-2][1].start,e[n+1][1].start=e[n-2][1].start,e.splice(n-2,2));return e},concrete:!0},ae={tokenize:function(e,n,t){return function(r){return e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),e.attempt(z,n,t)}},partial:!0},fe={tokenize:function(e,n,t){const r=this;return function(n){if(F(n))return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i;return t(n)};function i(e){return r.parser.lazy[r.now().line]?t(e):n(e)}},partial:!0};const de={tokenize:function(e,n,t){const r=this;return function(n){if(null===n)return t(n);return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),i};function i(e){return r.parser.lazy[r.now().line]?t(e):n(e)}},partial:!0},he={name:"codeFenced",tokenize:function(e,n,t){const r=this,i={tokenize:function(e,n,t){let i=0;return o;function o(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),s}function s(n){return e.enter("codeFencedFence"),b(n)?w(e,l,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n):l(n)}function l(n){return n===u?(e.enter("codeFencedFenceSequence"),a(n)):t(n)}function a(n){return n===u?(i++,e.consume(n),a):i>=c?(e.exit("codeFencedFenceSequence"),b(n)?w(e,f,"whitespace")(n):f(n)):t(n)}function f(r){return null===r||F(r)?(e.exit("codeFencedFence"),n(r)):t(r)}},partial:!0};let u,o=0,c=0;return function(n){return function(n){const t=r.events[r.events.length-1];return o=t&&"linePrefix"===t[1].type?t[2].sliceSerialize(t[1],!0).length:0,u=n,e.enter("codeFenced"),e.enter("codeFencedFence"),e.enter("codeFencedFenceSequence"),s(n)}(n)};function s(n){return n===u?(c++,e.consume(n),s):c<3?t(n):(e.exit("codeFencedFenceSequence"),b(n)?w(e,l,"whitespace")(n):l(n))}function l(t){return null===t||F(t)?(e.exit("codeFencedFence"),r.interrupt?n(t):e.check(de,h,k)(t)):(e.enter("codeFencedFenceInfo"),e.enter("chunkString",{contentType:"string"}),a(t))}function a(n){return null===n||F(n)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),l(n)):b(n)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),w(e,f,"whitespace")(n)):96===n&&n===u?t(n):(e.consume(n),a)}function f(n){return null===n||F(n)?l(n):(e.enter("codeFencedFenceMeta"),e.enter("chunkString",{contentType:"string"}),d(n))}function d(n){return null===n||F(n)?(e.exit("chunkString"),e.exit("codeFencedFenceMeta"),l(n)):96===n&&n===u?t(n):(e.consume(n),d)}function h(n){return e.attempt(i,k,p)(n)}function p(n){return e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),m}function m(n){return o>0&&b(n)?w(e,g,"linePrefix",o+1)(n):g(n)}function g(n){return null===n||F(n)?e.check(de,h,k)(n):(e.enter("codeFlowValue"),x(n))}function x(n){return null===n||F(n)?(e.exit("codeFlowValue"),g(n)):(e.consume(n),x)}function k(t){return e.exit("codeFenced"),n(t)}},concrete:!0};const pe=document.createElement("i");function me(e){const n="&"+e+";";pe.innerHTML=n;const t=pe.textContent;return(59!==t.charCodeAt(t.length-1)||"semi"===e)&&(t!==n&&t)}const ge={name:"characterReference",tokenize:function(e,n,t){const r=this;let i,u,o=0;return function(n){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(n),e.exit("characterReferenceMarker"),c};function c(n){return 35===n?(e.enter("characterReferenceMarkerNumeric"),e.consume(n),e.exit("characterReferenceMarkerNumeric"),s):(e.enter("characterReferenceValue"),i=31,u=p,l(n))}function s(n){return 88===n||120===n?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(n),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),i=6,u=k,l):(e.enter("characterReferenceValue"),i=7,u=x,l(n))}function l(c){if(59===c&&o){const i=e.exit("characterReferenceValue");return u!==p||me(r.sliceSerialize(i))?(e.enter("characterReferenceMarker"),e.consume(c),e.exit("characterReferenceMarker"),e.exit("characterReference"),n):t(c)}return u(c)&&o++<i?(e.consume(c),l):t(c)}}};const xe={name:"characterEscape",tokenize:function(e,n,t){return function(n){return e.enter("characterEscape"),e.enter("escapeMarker"),e.consume(n),e.exit("escapeMarker"),r};function r(r){return y(r)?(e.enter("characterEscapeValue"),e.consume(r),e.exit("characterEscapeValue"),e.exit("characterEscape"),n):t(r)}}};const ke={name:"lineEnding",tokenize:function(e,n){return function(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),w(e,n,"linePrefix")}}};const ye={name:"labelEnd",tokenize:function(e,n,t){const r=this;let i,u,o=r.events.length;for(;o--;)if(("labelImage"===r.events[o][1].type||"labelLink"===r.events[o][1].type)&&!r.events[o][1]._balanced){i=r.events[o][1];break}return function(n){if(!i)return t(n);if(i._inactive)return a(n);return u=r.parser.defined.includes(ee(r.sliceSerialize({start:i.end,end:r.now()}))),e.enter("labelEnd"),e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelEnd"),c};function c(n){return 40===n?e.attempt(Fe,l,u?l:a)(n):91===n?e.attempt(ve,l,u?s:a)(n):u?l(n):a(n)}function s(n){return e.attempt(be,l,a)(n)}function l(e){return n(e)}function a(e){return i._balanced=!0,t(e)}},resolveTo:function(e,n){let t,r,i,u,o=e.length,c=0;for(;o--;)if(t=e[o][1],r){if("link"===t.type||"labelLink"===t.type&&t._inactive)break;"enter"===e[o][0]&&"labelLink"===t.type&&(t._inactive=!0)}else if(i){if("enter"===e[o][0]&&("labelImage"===t.type||"labelLink"===t.type)&&!t._balanced&&(r=o,"labelLink"!==t.type)){c=2;break}}else"labelEnd"===t.type&&(i=o);const a={type:"labelLink"===e[r][1].type?"link":"image",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)},f={type:"label",start:Object.assign({},e[r][1].start),end:Object.assign({},e[i][1].end)},d={type:"labelText",start:Object.assign({},e[r+c+2][1].end),end:Object.assign({},e[i-2][1].start)};return u=[["enter",a,n],["enter",f,n]],u=l(u,e.slice(r+1,r+c+3)),u=l(u,[["enter",d,n]]),u=l(u,Q(n.parser.constructs.insideSpan.null,e.slice(r+c+4,i-3),n)),u=l(u,[["exit",d,n],e[i-2],e[i-1],["exit",f,n]]),u=l(u,e.slice(i+1)),u=l(u,[["exit",a,n]]),s(e,r,e.length,u),e},resolveAll:function(e){let n=-1;for(;++n<e.length;){const t=e[n][1];"labelImage"!==t.type&&"labelLink"!==t.type&&"labelEnd"!==t.type||(e.splice(n+1,"labelImage"===t.type?4:2),t.type="data",n++)}return e}},Fe={tokenize:function(e,n,t){return function(n){return e.enter("resource"),e.enter("resourceMarker"),e.consume(n),e.exit("resourceMarker"),r};function r(n){return v(n)?X(e,i)(n):i(n)}function i(n){return 41===n?l(n):J(e,u,o,"resourceDestination","resourceDestinationLiteral","resourceDestinationLiteralMarker","resourceDestinationRaw","resourceDestinationString",32)(n)}function u(n){return v(n)?X(e,c)(n):l(n)}function o(e){return t(e)}function c(n){return 34===n||39===n||40===n?K(e,s,t,"resourceTitle","resourceTitleMarker","resourceTitleString")(n):l(n)}function s(n){return v(n)?X(e,l)(n):l(n)}function l(r){return 41===r?(e.enter("resourceMarker"),e.consume(r),e.exit("resourceMarker"),e.exit("resource"),n):t(r)}}},ve={tokenize:function(e,n,t){const r=this;return function(n){return G.call(r,e,i,u,"reference","referenceMarker","referenceString")(n)};function i(e){return r.parser.defined.includes(ee(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)))?n(e):t(e)}function u(e){return t(e)}}},be={tokenize:function(e,n,t){return function(n){return e.enter("reference"),e.enter("referenceMarker"),e.consume(n),e.exit("referenceMarker"),r};function r(r){return 93===r?(e.enter("referenceMarker"),e.consume(r),e.exit("referenceMarker"),e.exit("reference"),n):t(r)}}};function Se(e){return null===e||v(e)||E(e)?1:S(e)?2:void 0}const Ee={name:"attention",tokenize:function(e,n){const t=this.parser.constructs.attentionMarkers.null,r=this.previous,i=Se(r);let u;return function(n){return u=n,e.enter("attentionSequence"),o(n)};function o(c){if(c===u)return e.consume(c),o;const s=e.exit("attentionSequence"),l=Se(c),a=!l||2===l&&i||t.includes(c),f=!i||2===i&&l||t.includes(r);return s._open=Boolean(42===u?a:a&&(i||!f)),s._close=Boolean(42===u?f:f&&(l||!a)),n(c)}},resolveAll:function(e,n){let t,r,i,u,o,c,a,f,d=-1;for(;++d<e.length;)if("enter"===e[d][0]&&"attentionSequence"===e[d][1].type&&e[d][1]._close)for(t=d;t--;)if("exit"===e[t][0]&&"attentionSequence"===e[t][1].type&&e[t][1]._open&&n.sliceSerialize(e[t][1]).charCodeAt(0)===n.sliceSerialize(e[d][1]).charCodeAt(0)){if((e[t][1]._close||e[d][1]._open)&&(e[d][1].end.offset-e[d][1].start.offset)%3&&!((e[t][1].end.offset-e[t][1].start.offset+e[d][1].end.offset-e[d][1].start.offset)%3))continue;c=e[t][1].end.offset-e[t][1].start.offset>1&&e[d][1].end.offset-e[d][1].start.offset>1?2:1;const h=Object.assign({},e[t][1].end),p=Object.assign({},e[d][1].start);Ae(h,-c),Ae(p,c),u={type:c>1?"strongSequence":"emphasisSequence",start:h,end:Object.assign({},e[t][1].end)},o={type:c>1?"strongSequence":"emphasisSequence",start:Object.assign({},e[d][1].start),end:p},i={type:c>1?"strongText":"emphasisText",start:Object.assign({},e[t][1].end),end:Object.assign({},e[d][1].start)},r={type:c>1?"strong":"emphasis",start:Object.assign({},u.start),end:Object.assign({},o.end)},e[t][1].end=Object.assign({},u.start),e[d][1].start=Object.assign({},o.end),a=[],e[t][1].end.offset-e[t][1].start.offset&&(a=l(a,[["enter",e[t][1],n],["exit",e[t][1],n]])),a=l(a,[["enter",r,n],["enter",u,n],["exit",u,n],["enter",i,n]]),a=l(a,Q(n.parser.constructs.insideSpan.null,e.slice(t+1,d),n)),a=l(a,[["exit",i,n],["enter",o,n],["exit",o,n],["exit",r,n]]),e[d][1].end.offset-e[d][1].start.offset?(f=2,a=l(a,[["enter",e[d][1],n],["exit",e[d][1],n]])):f=0,s(e,t-1,d-t+3,a),d=t+a.length-f-2;break}d=-1;for(;++d<e.length;)"attentionSequence"===e[d][1].type&&(e[d][1].type="data");return e}};function Ae(e,n){e.column+=n,e.offset+=n,e._bufferIndex+=n}const we={name:"htmlText",tokenize:function(e,n,t){const r=this;let i,u,o;return function(n){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(n),c};function c(n){return 33===n?(e.consume(n),s):47===n?(e.consume(n),A):63===n?(e.consume(n),S):h(n)?(e.consume(n),T):t(n)}function s(n){return 45===n?(e.consume(n),l):91===n?(e.consume(n),u=0,m):h(n)?(e.consume(n),y):t(n)}function l(n){return 45===n?(e.consume(n),d):t(n)}function a(n){return null===n?t(n):45===n?(e.consume(n),f):F(n)?(o=a,j(n)):(e.consume(n),a)}function f(n){return 45===n?(e.consume(n),d):a(n)}function d(e){return 62===e?O(e):45===e?f(e):a(e)}function m(n){const r="CDATA[";return n===r.charCodeAt(u++)?(e.consume(n),6===u?g:m):t(n)}function g(n){return null===n?t(n):93===n?(e.consume(n),x):F(n)?(o=g,j(n)):(e.consume(n),g)}function x(n){return 93===n?(e.consume(n),k):g(n)}function k(n){return 62===n?O(n):93===n?(e.consume(n),k):g(n)}function y(n){return null===n||62===n?O(n):F(n)?(o=y,j(n)):(e.consume(n),y)}function S(n){return null===n?t(n):63===n?(e.consume(n),E):F(n)?(o=S,j(n)):(e.consume(n),S)}function E(e){return 62===e?O(e):S(e)}function A(n){return h(n)?(e.consume(n),I):t(n)}function I(n){return 45===n||p(n)?(e.consume(n),I):C(n)}function C(n){return F(n)?(o=C,j(n)):b(n)?(e.consume(n),C):O(n)}function T(n){return 45===n||p(n)?(e.consume(n),T):47===n||62===n||v(n)?z(n):t(n)}function z(n){return 47===n?(e.consume(n),O):58===n||95===n||h(n)?(e.consume(n),D):F(n)?(o=z,j(n)):b(n)?(e.consume(n),z):O(n)}function D(n){return 45===n||46===n||58===n||95===n||p(n)?(e.consume(n),D):B(n)}function B(n){return 61===n?(e.consume(n),_):F(n)?(o=B,j(n)):b(n)?(e.consume(n),B):z(n)}function _(n){return null===n||60===n||61===n||62===n||96===n?t(n):34===n||39===n?(e.consume(n),i=n,L):F(n)?(o=_,j(n)):b(n)?(e.consume(n),_):(e.consume(n),M)}function L(n){return n===i?(e.consume(n),i=void 0,P):null===n?t(n):F(n)?(o=L,j(n)):(e.consume(n),L)}function M(n){return null===n||34===n||39===n||60===n||61===n||96===n?t(n):47===n||62===n||v(n)?z(n):(e.consume(n),M)}function P(e){return 47===e||62===e||v(e)?z(e):t(e)}function O(r){return 62===r?(e.consume(r),e.exit("htmlTextData"),e.exit("htmlText"),n):t(r)}function j(n){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),H}function H(n){return b(n)?w(e,R,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(n):R(n)}function R(n){return e.enter("htmlTextData"),o(n)}}};const Ie={name:"codeText",tokenize:function(e,n,t){let r,i,u=0;return function(n){return e.enter("codeText"),e.enter("codeTextSequence"),o(n)};function o(n){return 96===n?(e.consume(n),u++,o):(e.exit("codeTextSequence"),c(n))}function c(n){return null===n?t(n):32===n?(e.enter("space"),e.consume(n),e.exit("space"),c):96===n?(i=e.enter("codeTextSequence"),r=0,l(n)):F(n)?(e.enter("lineEnding"),e.consume(n),e.exit("lineEnding"),c):(e.enter("codeTextData"),s(n))}function s(n){return null===n||32===n||96===n||F(n)?(e.exit("codeTextData"),c(n)):(e.consume(n),s)}function l(t){return 96===t?(e.consume(t),r++,l):r===u?(e.exit("codeTextSequence"),e.exit("codeText"),n(t)):(i.type="codeTextData",s(t))}},resolve:function(e){let n,t,r=e.length-4,i=3;if(!("lineEnding"!==e[i][1].type&&"space"!==e[i][1].type||"lineEnding"!==e[r][1].type&&"space"!==e[r][1].type))for(n=i;++n<r;)if("codeTextData"===e[n][1].type){e[i][1].type="codeTextPadding",e[r][1].type="codeTextPadding",i+=2,r-=2;break}n=i-1,r++;for(;++n<=r;)void 0===t?n!==r&&"lineEnding"!==e[n][1].type&&(t=n):n!==r&&"lineEnding"!==e[n][1].type||(e[t][1].type="codeTextData",n!==t+2&&(e[t][1].end=e[n-1][1].end,e.splice(t+2,n-t-2),r-=n-t-2,n=t+2),t=void 0);return e},previous:function(e){return 96!==e||"characterEscape"===this.events[this.events.length-1][1].type}};const Ce={42:$,43:$,45:$,48:$,49:$,50:$,51:$,52:$,53:$,54:$,55:$,56:$,57:$,62:Y},Te={91:ne},ze={[-2]:re,[-1]:re,32:re},De={35:ue,42:U,45:[oe,U],60:le,61:oe,95:U,96:he,126:he},Be={38:ge,92:xe},_e={[-5]:ke,[-4]:ke,[-3]:ke,33:{name:"labelStartImage",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("labelImage"),e.enter("labelImageMarker"),e.consume(n),e.exit("labelImageMarker"),i};function i(n){return 91===n?(e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelImage"),u):t(n)}function u(e){return 94===e&&"_hiddenFootnoteSupport"in r.parser.constructs?t(e):n(e)}},resolveAll:ye.resolveAll},38:ge,42:Ee,60:[{name:"autolink",tokenize:function(e,n,t){let r=0;return function(n){return e.enter("autolink"),e.enter("autolinkMarker"),e.consume(n),e.exit("autolinkMarker"),e.enter("autolinkProtocol"),i};function i(n){return h(n)?(e.consume(n),u):s(n)}function u(e){return 43===e||45===e||46===e||p(e)?(r=1,o(e)):s(e)}function o(n){return 58===n?(e.consume(n),r=0,c):(43===n||45===n||46===n||p(n))&&r++<32?(e.consume(n),o):(r=0,s(n))}function c(r){return 62===r?(e.exit("autolinkProtocol"),e.enter("autolinkMarker"),e.consume(r),e.exit("autolinkMarker"),e.exit("autolink"),n):null===r||32===r||60===r||g(r)?t(r):(e.consume(r),c)}function s(n){return 64===n?(e.consume(n),l):m(n)?(e.consume(n),s):t(n)}function l(e){return p(e)?a(e):t(e)}function a(t){return 46===t?(e.consume(t),r=0,l):62===t?(e.exit("autolinkProtocol").type="autolinkEmail",e.enter("autolinkMarker"),e.consume(t),e.exit("autolinkMarker"),e.exit("autolink"),n):f(t)}function f(n){if((45===n||p(n))&&r++<63){const t=45===n?f:a;return e.consume(n),t}return t(n)}}},we],91:{name:"labelStartLink",tokenize:function(e,n,t){const r=this;return function(n){return e.enter("labelLink"),e.enter("labelMarker"),e.consume(n),e.exit("labelMarker"),e.exit("labelLink"),i};function i(e){return 94===e&&"_hiddenFootnoteSupport"in r.parser.constructs?t(e):n(e)}},resolveAll:ye.resolveAll},92:[{name:"hardBreakEscape",tokenize:function(e,n,t){return function(n){return e.enter("hardBreakEscape"),e.consume(n),r};function r(r){return F(r)?(e.exit("hardBreakEscape"),n(r)):t(r)}}},xe],93:ye,95:Ee,96:Ie},Le={null:[Ee,O]},Me={null:[42,95]},Pe={null:[]};function Oe(e){const n=function(e){const n={};let t=-1;for(;++t<e.length;)f(n,e[t]);return n}([r,...(e||{}).extensions||[]]),t={defined:[],lazy:{},constructs:n,content:i(I),document:i(C),flow:i(P),string:i(j),text:i(H)};return t;function i(e){return function(n){return N(t,e,n)}}}const je=/[\0\t\n\r]/g;function He(e,n){const t=Number.parseInt(e,n);return t<9||11===t||t>13&&t<32||t>126&&t<160||t>55295&&t<57344||t>64975&&t<65008||65535==(65535&t)||65534==(65535&t)||t>1114111?"\ufffd":String.fromCharCode(t)}const Re=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function qe(e,n,t){if(n)return n;if(35===t.charCodeAt(0)){const e=t.charCodeAt(1),n=120===e||88===e;return He(t.slice(n?2:1),n?16:10)}return me(t)||e}function Ve(e){return e&&"object"==typeof e?"position"in e||"type"in e?Ne(e.position):"start"in e||"end"in e?Ne(e):"line"in e||"column"in e?Qe(e):"":""}function Qe(e){return Ue(e&&e.line)+":"+Ue(e&&e.column)}function Ne(e){return Qe(e&&e.start)+"-"+Qe(e&&e.end)}function Ue(e){return e&&"number"==typeof e?e:1}const $e={}.hasOwnProperty,We=function(e,n,t){return"string"!=typeof n&&(t=n,n=void 0),function(e){const n={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:l(ue),autolinkProtocol:T,autolinkEmail:T,atxHeading:l(ne),blockQuote:l(Y),characterEscape:T,characterReference:T,codeFenced:l(J),codeFencedFenceInfo:a,codeFencedFenceMeta:a,codeIndented:l(J,a),codeText:l(G,a),codeTextData:T,data:T,codeFlowValue:T,definition:l(K),definitionDestinationString:a,definitionLabelString:a,definitionTitleString:a,emphasis:l(X),hardBreakEscape:l(te),hardBreakTrailing:l(te),htmlFlow:l(re,a),htmlFlowData:T,htmlText:l(re,a),htmlTextData:T,image:l(ie),label:a,link:l(ue),listItem:l(ce),listItemValue:g,listOrdered:l(oe,m),listUnordered:l(oe),paragraph:l(se),reference:Q,referenceString:a,resourceDestinationString:a,resourceTitleString:a,setextHeading:l(ne),strong:l(le),thematicBreak:l(fe)},exit:{atxHeading:d(),atxHeadingSequence:A,autolink:d(),autolinkEmail:Z,autolinkProtocol:W,blockQuote:d(),characterEscapeValue:z,characterReferenceMarkerHexadecimal:U,characterReferenceMarkerNumeric:U,characterReferenceValue:$,codeFenced:d(F),codeFencedFence:y,codeFencedFenceInfo:x,codeFencedFenceMeta:k,codeFlowValue:z,codeIndented:d(v),codeText:d(M),codeTextData:z,data:z,definition:d(),definitionDestinationString:E,definitionLabelString:b,definitionTitleString:S,emphasis:d(),hardBreakEscape:d(B),hardBreakTrailing:d(B),htmlFlow:d(_),htmlFlowData:z,htmlText:d(L),htmlTextData:z,image:d(O),label:H,labelText:j,lineEnding:D,link:d(P),listItem:d(),listOrdered:d(),listUnordered:d(),paragraph:d(),referenceString:N,resourceDestinationString:R,resourceTitleString:q,resource:V,setextHeading:d(C),setextHeadingLineSequence:I,setextHeadingText:w,strong:d(),thematicBreak:d()}};Ye(n,(e||{}).mdastExtensions||[]);const t={};return r;function r(e){let t={type:"root",children:[]};const r={stack:[t],tokenStack:[],config:n,enter:f,exit:h,buffer:a,resume:p,setData:c,getData:s},u=[];let o=-1;for(;++o<e.length;)if("listOrdered"===e[o][1].type||"listUnordered"===e[o][1].type)if("enter"===e[o][0])u.push(o);else{o=i(e,u.pop(),o)}for(o=-1;++o<e.length;){const t=n[e[o][0]];$e.call(t,e[o][1].type)&&t[e[o][1].type].call(Object.assign({sliceSerialize:e[o][2].sliceSerialize},r),e[o][1])}if(r.tokenStack.length>0){const e=r.tokenStack[r.tokenStack.length-1];(e[1]||Ge).call(r,void 0,e[0])}for(t.position={start:Ze(e.length>0?e[0][1].start:{line:1,column:1,offset:0}),end:Ze(e.length>0?e[e.length-2][1].end:{line:1,column:1,offset:0})},o=-1;++o<n.transforms.length;)t=n.transforms[o](t)||t;return t}function i(e,n,t){let r,i,u,o,c=n-1,s=-1,l=!1;for(;++c<=t;){const n=e[c];if("listUnordered"===n[1].type||"listOrdered"===n[1].type||"blockQuote"===n[1].type?("enter"===n[0]?s++:s--,o=void 0):"lineEndingBlank"===n[1].type?"enter"===n[0]&&(!r||o||s||u||(u=c),o=void 0):"linePrefix"===n[1].type||"listItemValue"===n[1].type||"listItemMarker"===n[1].type||"listItemPrefix"===n[1].type||"listItemPrefixWhitespace"===n[1].type||(o=void 0),!s&&"enter"===n[0]&&"listItemPrefix"===n[1].type||-1===s&&"exit"===n[0]&&("listUnordered"===n[1].type||"listOrdered"===n[1].type)){if(r){let o=c;for(i=void 0;o--;){const n=e[o];if("lineEnding"===n[1].type||"lineEndingBlank"===n[1].type){if("exit"===n[0])continue;i&&(e[i][1].type="lineEndingBlank",l=!0),n[1].type="lineEnding",i=o}else if("linePrefix"!==n[1].type&&"blockQuotePrefix"!==n[1].type&&"blockQuotePrefixWhitespace"!==n[1].type&&"blockQuoteMarker"!==n[1].type&&"listItemIndent"!==n[1].type)break}u&&(!i||u<i)&&(r._spread=!0),r.end=Object.assign({},i?e[i][1].start:n[1].end),e.splice(i||c,0,["exit",r,n[2]]),c++,t++}"listItemPrefix"===n[1].type&&(r={type:"listItem",_spread:!1,start:Object.assign({},n[1].start),end:void 0},e.splice(c,0,["enter",r,n[2]]),c++,t++,u=void 0,o=!0)}}return e[n][1]._spread=l,t}function c(e,n){t[e]=n}function s(e){return t[e]}function l(e,n){return t;function t(t){f.call(this,e(t),t),n&&n.call(this,t)}}function a(){this.stack.push({type:"fragment",children:[]})}function f(e,n,t){return this.stack[this.stack.length-1].children.push(e),this.stack.push(e),this.tokenStack.push([n,t]),e.position={start:Ze(n.start)},e}function d(e){return n;function n(n){e&&e.call(this,n),h.call(this,n)}}function h(e,n){const t=this.stack.pop(),r=this.tokenStack.pop();if(!r)throw new Error("Cannot close `"+e.type+"` ("+Ve({start:e.start,end:e.end})+"): it\u2019s not open");if(r[0].type!==e.type)if(n)n.call(this,e,r[0]);else{(r[1]||Ge).call(this,e,r[0])}return t.position.end=Ze(e.end),t}function p(){return function(e,n){const t=n||u;return o(e,"boolean"!=typeof t.includeImageAlt||t.includeImageAlt,"boolean"!=typeof t.includeHtml||t.includeHtml)}(this.stack.pop())}function m(){c("expectingFirstListItemValue",!0)}function g(e){if(s("expectingFirstListItemValue")){this.stack[this.stack.length-2].start=Number.parseInt(this.sliceSerialize(e),10),c("expectingFirstListItemValue")}}function x(){const e=this.resume();this.stack[this.stack.length-1].lang=e}function k(){const e=this.resume();this.stack[this.stack.length-1].meta=e}function y(){s("flowCodeInside")||(this.buffer(),c("flowCodeInside",!0))}function F(){const e=this.resume();this.stack[this.stack.length-1].value=e.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g,""),c("flowCodeInside")}function v(){const e=this.resume();this.stack[this.stack.length-1].value=e.replace(/(\r?\n|\r)$/g,"")}function b(e){const n=this.resume(),t=this.stack[this.stack.length-1];t.label=n,t.identifier=ee(this.sliceSerialize(e)).toLowerCase()}function S(){const e=this.resume();this.stack[this.stack.length-1].title=e}function E(){const e=this.resume();this.stack[this.stack.length-1].url=e}function A(e){const n=this.stack[this.stack.length-1];if(!n.depth){const t=this.sliceSerialize(e).length;n.depth=t}}function w(){c("setextHeadingSlurpLineEnding",!0)}function I(e){this.stack[this.stack.length-1].depth=61===this.sliceSerialize(e).charCodeAt(0)?1:2}function C(){c("setextHeadingSlurpLineEnding")}function T(e){const n=this.stack[this.stack.length-1];let t=n.children[n.children.length-1];t&&"text"===t.type||(t=ae(),t.position={start:Ze(e.start)},n.children.push(t)),this.stack.push(t)}function z(e){const n=this.stack.pop();n.value+=this.sliceSerialize(e),n.position.end=Ze(e.end)}function D(e){const t=this.stack[this.stack.length-1];if(s("atHardBreak")){return t.children[t.children.length-1].position.end=Ze(e.end),void c("atHardBreak")}!s("setextHeadingSlurpLineEnding")&&n.canContainEols.includes(t.type)&&(T.call(this,e),z.call(this,e))}function B(){c("atHardBreak",!0)}function _(){const e=this.resume();this.stack[this.stack.length-1].value=e}function L(){const e=this.resume();this.stack[this.stack.length-1].value=e}function M(){const e=this.resume();this.stack[this.stack.length-1].value=e}function P(){const e=this.stack[this.stack.length-1];if(s("inReference")){const n=s("referenceType")||"shortcut";e.type+="Reference",e.referenceType=n,delete e.url,delete e.title}else delete e.identifier,delete e.label;c("referenceType")}function O(){const e=this.stack[this.stack.length-1];if(s("inReference")){const n=s("referenceType")||"shortcut";e.type+="Reference",e.referenceType=n,delete e.url,delete e.title}else delete e.identifier,delete e.label;c("referenceType")}function j(e){const n=this.sliceSerialize(e),t=this.stack[this.stack.length-2];t.label=function(e){return e.replace(Re,qe)}(n),t.identifier=ee(n).toLowerCase()}function H(){const e=this.stack[this.stack.length-1],n=this.resume(),t=this.stack[this.stack.length-1];if(c("inReference",!0),"link"===t.type){const n=e.children;t.children=n}else t.alt=n}function R(){const e=this.resume();this.stack[this.stack.length-1].url=e}function q(){const e=this.resume();this.stack[this.stack.length-1].title=e}function V(){c("inReference")}function Q(){c("referenceType","collapsed")}function N(e){const n=this.resume(),t=this.stack[this.stack.length-1];t.label=n,t.identifier=ee(this.sliceSerialize(e)).toLowerCase(),c("referenceType","full")}function U(e){c("characterReferenceType",e.type)}function $(e){const n=this.sliceSerialize(e),t=s("characterReferenceType");let r;if(t)r=He(n,"characterReferenceMarkerNumeric"===t?10:16),c("characterReferenceType");else{r=me(n)}const i=this.stack.pop();i.value+=r,i.position.end=Ze(e.end)}function W(e){z.call(this,e);this.stack[this.stack.length-1].url=this.sliceSerialize(e)}function Z(e){z.call(this,e);this.stack[this.stack.length-1].url="mailto:"+this.sliceSerialize(e)}function Y(){return{type:"blockquote",children:[]}}function J(){return{type:"code",lang:null,meta:null,value:""}}function G(){return{type:"inlineCode",value:""}}function K(){return{type:"definition",identifier:"",label:null,title:null,url:""}}function X(){return{type:"emphasis",children:[]}}function ne(){return{type:"heading",depth:void 0,children:[]}}function te(){return{type:"break"}}function re(){return{type:"html",value:""}}function ie(){return{type:"image",title:null,url:"",alt:null}}function ue(){return{type:"link",title:null,url:"",children:[]}}function oe(e){return{type:"list",ordered:"listOrdered"===e.type,start:null,spread:e._spread,children:[]}}function ce(e){return{type:"listItem",spread:e._spread,checked:null,children:[]}}function se(){return{type:"paragraph",children:[]}}function le(){return{type:"strong",children:[]}}function ae(){return{type:"text",value:""}}function fe(){return{type:"thematicBreak"}}}(t)(function(e){for(;!B(e););return e}(Oe(t).document().write(function(){let e,n=1,t="",r=!0;return function(i,u,o){const c=[];let s,l,a,f,d;for(i=t+i.toString(u),a=0,t="",r&&(65279===i.charCodeAt(0)&&a++,r=void 0);a<i.length;){if(je.lastIndex=a,s=je.exec(i),f=s&&void 0!==s.index?s.index:i.length,d=i.charCodeAt(f),!s){t=i.slice(a);break}if(10===d&&a===f&&e)c.push(-3),e=void 0;else switch(e&&(c.push(-5),e=void 0),a<f&&(c.push(i.slice(a,f)),n+=f-a),d){case 0:c.push(65533),n++;break;case 9:for(l=4*Math.ceil(n/4),c.push(-2);n++<l;)c.push(-1);break;case 10:c.push(-4),n=1;break;default:e=!0,n=1}a=f+1}return o&&(e&&c.push(-5),t&&c.push(t),c.push(null)),c}}()(e,n,!0))))};function Ze(e){return{line:e.line,column:e.column,offset:e.offset}}function Ye(e,n){let t=-1;for(;++t<n.length;){const r=n[t];Array.isArray(r)?Ye(e,r):Je(e,r)}}function Je(e,n){let t;for(t in n)if($e.call(n,t))if("canContainEols"===t){const r=n[t];r&&e[t].push(...r)}else if("transforms"===t){const r=n[t];r&&e[t].push(...r)}else if("enter"===t||"exit"===t){const r=n[t];r&&Object.assign(e[t],r)}}function Ge(e,n){throw e?new Error("Cannot close `"+e.type+"` ("+Ve({start:e.start,end:e.end})+"): a different token (`"+n.type+"`, "+Ve({start:n.start,end:n.end})+") is open"):new Error("Cannot close document, a token (`"+n.type+"`, "+Ve({start:n.start,end:n.end})+") is still open")}var Ke=t(18464);function Xe(e){const n=function(e){const n=e.replace(/\n{2,}/g,"\n");return(0,Ke.Z)(n)}(e),{children:t}=We(n),r=[[]];let i=0;function u(e,n="normal"){if("text"===e.type){e.value.split("\n").forEach(((e,t)=>{0!==t&&(i++,r.push([])),e.split(" ").forEach((e=>{e&&r[i].push({content:e,type:n})}))}))}else"strong"!==e.type&&"emphasis"!==e.type||e.children.forEach((n=>{u(n,e.type)}))}return t.forEach((e=>{"paragraph"===e.type&&e.children.forEach((e=>{u(e)}))})),r}function en(e,n){var t;return nn(e,[],(t=n.content,Intl.Segmenter?[...(new Intl.Segmenter).segment(t)].map((e=>e.segment)):[...t]),n.type)}function nn(e,n,t,r){if(0===t.length)return[{content:n.join(""),type:r},{content:"",type:r}];const[i,...u]=t,o=[...n,i];return e([{content:o.join(""),type:r}])?nn(e,o,u,r):(0===n.length&&i&&(n.push(i),t.shift()),[{content:n.join(""),type:r},{content:t.join(""),type:r}])}function tn(e,n){if(e.some((({content:e})=>e.includes("\n"))))throw new Error("splitLineToFitWidth does not support newlines in the line");return rn(e,n)}function rn(e,n,t=[],r=[]){if(0===e.length)return r.length>0&&t.push(r),t.length>0?t:[];let i="";" "===e[0].content&&(i=" ",e.shift());const u=e.shift()??{content:" ",type:"normal"},o=[...r];if(""!==i&&o.push({content:i,type:"normal"}),o.push(u),n(o))return rn(e,n,t,o);if(r.length>0)t.push(r),e.unshift(u);else if(u.content){const[r,i]=en(n,u);t.push([r]),i.content&&e.unshift(i)}return rn(e,n,t)}function un(e,n,t){return e.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",n*t-.1+"em").attr("dy",t+"em")}function on(e,n,t){const r=e.append("text"),i=un(r,1,n);sn(i,t);const u=i.node().getComputedTextLength();return r.remove(),u}function cn(e,n,t){var r;const i=e.append("text"),u=un(i,1,n);sn(u,[{content:t,type:"normal"}]);const o=null==(r=u.node())?void 0:r.getBoundingClientRect();return o&&i.remove(),o}function sn(e,n){e.text(""),n.forEach(((n,t)=>{const r=e.append("tspan").attr("font-style","emphasis"===n.type?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight","strong"===n.type?"bold":"normal");0===t?r.text(n.content):r.text(" "+n.content)}))}const ln=(e,n="",{style:t="",isTitle:r=!1,classes:u="",useHtmlLabels:o=!0,isNode:c=!0,width:s=200,addSvgBackground:l=!1}={})=>{if(i.l.info("createText",n,t,r,u,o,c,l),o){const r=function(e){const{children:n}=We(e);return n.map((function e(n){return"text"===n.type?n.value.replace(/\n/g,"<br/>"):"strong"===n.type?`<strong>${n.children.map(e).join("")}</strong>`:"emphasis"===n.type?`<em>${n.children.map(e).join("")}</em>`:"paragraph"===n.type?`<p>${n.children.map(e).join("")}</p>`:`Unsupported markdown: ${n.type}`})).join("")}(n),o=function(e,n,t,r,i=!1){const u=e.append("foreignObject"),o=u.append("xhtml:div"),c=n.label,s=n.isNode?"nodeLabel":"edgeLabel";var l,a;o.html(`\n <span class="${s} ${r}" `+(n.labelStyle?'style="'+n.labelStyle+'"':"")+">"+c+"</span>"),l=o,(a=n.labelStyle)&&l.attr("style",a),o.style("display","table-cell"),o.style("white-space","nowrap"),o.style("max-width",t+"px"),o.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&o.attr("class","labelBkg");let f=o.node().getBoundingClientRect();return f.width===t&&(o.style("display","table"),o.style("white-space","break-spaces"),o.style("width",t+"px"),f=o.node().getBoundingClientRect()),u.style("width",f.width),u.style("height",f.height),u.node()}(e,{isNode:c,label:(0,i.J)(r).replace(/fa[blrs]?:fa-[\w-]+/g,(e=>`<i class='${e.replace(":"," ")}'></i>`)),labelStyle:t.replace("fill:","color:")},s,u,l);return o}{const t=function(e,n,t,r=!1){const i=n.append("g"),u=i.insert("rect").attr("class","background"),o=i.append("text").attr("y","-10.1");let c=0;for(const s of t){const n=n=>on(i,1.1,n)<=e,t=n(s)?[s]:tn(s,n);for(const e of t)sn(un(o,c,1.1),e),c++}if(r){const e=o.node().getBBox(),n=2;return u.attr("x",-n).attr("y",-n).attr("width",e.width+2*n).attr("height",e.height+2*n),i.node()}return o.node()}(s,e,Xe(n),l);return t}}}}]); \ No newline at end of file diff --git a/assets/js/489347ff.b84e267c.js b/assets/js/489347ff.8a3de8e4.js similarity index 83% rename from assets/js/489347ff.b84e267c.js rename to assets/js/489347ff.8a3de8e4.js index 1be0ed5ef..930afd9b0 100644 --- a/assets/js/489347ff.b84e267c.js +++ b/assets/js/489347ff.8a3de8e4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2793],{40526:e=>{e.exports=JSON.parse('{"label":"WebSocket","permalink":"/tags/web-socket","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2793],{40526:e=>{e.exports=JSON.parse('{"label":"WebSocket","permalink":"/tags/web-socket","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/48faf148.251b0554.js b/assets/js/48faf148.251b0554.js new file mode 100644 index 000000000..ccbb35572 --- /dev/null +++ b/assets/js/48faf148.251b0554.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7328],{50973:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var n=r(85893),c=r(3905);const s={title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",slug:"tecochat-retrospective-3",tags:["TecoChat","Retrospective"]},i=void 0,a={permalink:"/tecochat-retrospective-3",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",source:"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",description:"\uac1c\uc694",date:"2023-06-01T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 1\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.005,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",slug:"tecochat-retrospective-3",tags:["TecoChat","Retrospective"]},unlisted:!1,prevItem:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",permalink:"/order-retrospective"},nextItem:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",permalink:"/composite"}},o={authorsImageUrls:[]},l=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5",id:"\ub098\uc758-\ucc44\ud305-\ud655\uc778\ud558\uace0-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",level:3},{value:"\uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5",id:"\uc88b\uc544\uc694\uc640-\ub313\uae00-\uae30\ub2a5",level:3},{value:"\ud0a4\uc6cc\ub4dc \ucd94\ucd9c",id:"\ud0a4\uc6cc\ub4dc-\ucd94\ucd9c",level:3},{value:"\ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5",id:"\ub2e4\ub978-\ud06c\ub8e8\uc758-\ucc44\ud305-\ubcf5\uc0ac\ud574\uc11c-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",level:3},{value:"\uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30",id:"\uc0ac\uc6a9\uc131-\uace0\ub824\ud558\uae30",level:3},{value:"\ud5a5\ud6c4 \uacc4\ud68d",id:"\ud5a5\ud6c4-\uacc4\ud68d",level:3}];function p(e){const t={br:"br",code:"code",h3:"h3",img:"img",p:"p",...(0,c.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,n.jsxs)(t.p,{children:["\uc6d0\ub798 \ubaa9\uc801\uc778 ",(0,n.jsx)(t.code,{children:"\ud06c\ub8e8\ub4e4\uc758 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0"}),"\uc744 \uc8fc\uae30 \uc704\ud574 \uc5b4\ub5a4 \uae30\ub2a5\uc744 \ucd94\uac00\ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub808\ubca8 2\uac00 \uac70\uc758 \ub05d\ub098\uac00\ub294 \uc2dc\uc810, \uadf8\ub3d9\uc548 \ud588\ub358 \uac83\uc744 \uc815\ub9ac\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ub098\uc758-\ucc44\ud305-\ud655\uc778\ud558\uace0-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",children:"\ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5"}),"\n",(0,n.jsxs)(t.p,{children:["GPT\uc5d0\ub3c4 \uc788\ub294 \uae30\ub2a5\uc778\ub370, \ub0b4\uac00 \uc774\uc804\uc5d0 \ud588\ub358 \ucc44\ud305\uc744 \uc774\uc5b4\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc608\uc804\uc5d0 \uc5b4\ub5a4 \uc9c8\ubb38\uc744 \ub0a8\uacbc\ub294\uc9c0, \ub610\ud55c \ud574\ub2f9 \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"chat1",src:r(49483).Z+"",width:"2878",height:"1316"})}),"\n",(0,n.jsx)(t.h3,{id:"\uc88b\uc544\uc694\uc640-\ub313\uae00-\uae30\ub2a5",children:"\uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5"}),"\n",(0,n.jsxs)(t.p,{children:["\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc5d0 \ubc18\uc751\ud560 \uc218 \uc788\ub294 \ubb34\uc5b8\uac00\uac00 \uc788\uc5c8\uc73c\uba74 \uc88b\uaca0\ub2e4\ub294 \uc758\uacac\ub4e4\uc774 \ub9ce\uc558\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub204\uac00 \uc88b\uc544\uc694\ub97c \ub20c\ub800\ub294\uc9c0, \uc5b4\ub5a4 \ucc44\ud305\uc774 \uc88b\uc544\uc694\ub97c \uac00\uc7a5 \ub9ce\uc774 \ubc1b\uc558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub610\ud55c \ub313\uae00 \ucd94\uac00 \ubc0f \uc0ad\uc81c \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ud0a4\uc6cc\ub4dc-\ucd94\ucd9c",children:"\ud0a4\uc6cc\ub4dc \ucd94\ucd9c"}),"\n",(0,n.jsxs)(t.p,{children:["\uc5b4\ub5bb\uac8c \ud0a4\uc6cc\ub4dc \ucd94\ucd9c\uc744 \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub294\ub370, \uc77c\ub2e8 GPT\ub97c \uc774\uc6a9\ud574\uc11c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\uae30\ub85c \ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud574\ub2f9 \ubd80\ubd84\uc740 \uccab \uc9c8\ubb38\uc5d0 \ub300\ud55c \ud0a4\uc6cc\ub4dc\ub9cc \ucd94\ucd9c\ud558\ub3c4\ub85d \ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ubc31\uc5d4\ub4dc\uc5d0\uc120 \ub9d0\ub791\uc774 \uc774\ubca4\ud2b8 \uc774\uc6a9\ud574\uc11c \uccab \ucc44\ud305 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c0\uba74, \ube44\ub3d9\uae30\ub85c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\ub294 \uc9c8\ubb38\uc744 \ucd94\uac00\ub85c \ub0a0\ub9ac\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4.",(0,n.jsx)(t.br,{}),"\n","CSV \ud615\uc2dd\uc73c\ub85c GPT\uc5d0\uac8c \ub2f5\ubcc0\uc744 \uc785\ub825\ud574\ub2ec\ub77c\uace0 \uc694\uccad\ubc1b\ub294\ub370, \uc774 \ubd80\ubd84\uc774 \ubb38\uc81c(\ud504\ub86c\ud504\ud2b8 \uc5d4\uc9c0\ub2c8\uc5b4\ub9c1 \ubd80\ubd84\uc774 \ubc18\ud658\ub41c\ub2e4.)\uac00 \uc880 \uc788\ub294 \uac83 \uac19\uc544\uc11c \uac1c\uc120\uc774 \ud544\uc694\ud55c \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"chat2",src:r(50885).Z+"",width:"2394",height:"1048"})}),"\n",(0,n.jsx)(t.h3,{id:"\ub2e4\ub978-\ud06c\ub8e8\uc758-\ucc44\ud305-\ubcf5\uc0ac\ud574\uc11c-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",children:"\ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5"}),"\n",(0,n.jsxs)(t.p,{children:["\ub2e4\ub978 \ud06c\ub8e8\ub4e4\uc758 \ucc44\ud305\uc744 \uc77d\ub2e4\uac00 \uad81\uae08\ud55c \uc810\uc774 \uc788\ub2e4\uba74 \ubcf5\uc0ac\ud574\uc11c \ubc14\ub85c \uc9c8\ubb38\uc744 \ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ucc44\ud305\uc774 \ubcf5\uc0ac\ub41c \ud6c4 \ubc14\ub85c GPT\uc640 \ub300\ud654\ub97c \ud560 \uc218 \uc788\ub294 \uba54\uc778 \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\uc0ac\uc6a9\uc131-\uace0\ub824\ud558\uae30",children:"\uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"chat3",src:r(15153).Z+"",width:"1668",height:"718"})}),"\n",(0,n.jsxs)(t.p,{children:["\uc704 \ud654\uba74\uc740 \ud68c\uc6d0\uac00\uc785 \ucc3d\uc774\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc0ac\uc2e4 \uac00\uc7a5 \ub9c8\uc74c\uc5d0 \ub4dc\ub294 \ubd80\ubd84\uc774\uace0, \ud68c\uc6d0\uac00\uc785(\ub2c9\ub124\uc784\ub9cc \uc785\ub825\ud558\uc9c0\ub9cc)\ud560 \ub54c \uc775\uba85\uc744 \uc6d0\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uace0\ubbfc\uc744 \ub3c4\uc640\uc8fc\uac8c \ub054 \uc74c\uc2dd, \uacfc\uc77c, \uacfc\uc790 \ub4f1\uc758 \uc694\uc18c\ub4e4\uc744 \uc785\ub825\ud558\ub3c4\ub85d \uc720\ub3c4\ud588\ub2e4!\n\ucd94\uac00\ub85c GPT\uc758 \ub2f5\ubcc0\uc774 \uc624\uba74 \uc790\ub3d9\uc73c\ub85c \ud654\uba74\uc744 \uc2a4\ud06c\ub864 \ud574\uc8fc\ub294 \uac83\uacfc \uac19\uc774 \uc0ac\uc6a9\uc131\uc744 \uac1c\uc120\ud574 \ubcf4\ub824\uace0 \ub178\ub825\ud588\uc9c0\ub9cc \uc27d\uc9c0 \uc54a\uc558\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc81c\uc77c \ud558\uace0 \uc2f6\uc740 \uac83\uc740 \uc2e4\uc81c GPT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ucc98\ub7fc stream/text \uac12\uc744 \ucc98\ub9ac\ud558\uace0 \uc2f6\uc740\ub370 \uc774 \ubd80\ubd84\uc740 \ubc29\ud559 \ub54c \uae30\ud68c\uac00 \ub418\uba74 \ub3c4\uc804\ud574 \ubd10\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ud5a5\ud6c4-\uacc4\ud68d",children:"\ud5a5\ud6c4 \uacc4\ud68d"}),"\n",(0,n.jsxs)(t.p,{children:["\uc2e4\uc81c \ud06c\ub8e8\ub4e4\uc774 \uc0ac\uc6a9\ud574 \uc8fc\ub294 \uc11c\ube44\uc2a4\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\ubcf4\uba74\uc11c \uc0ac\uc6a9\uc790\uc758 \uc785\uc7a5\uc5d0\uc11c \uace0\ubbfc\ub3c4 \ud558\uac8c \ub418\ub294 \uac83 \uac19\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud06c\ub8e8\ub4e4\uc774 \uc9c1\uc811 \uc0ac\uc6a9\ud574 \uc8fc\ub2c8\uae4c \ub108\ubb34 \uace0\ub9d9\uace0, \ud55c\ud3b8\uc73c\ub85c\ub294 \uc2e0\uae30\ud558\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc77c\ub2e8 \ubc29\ud559 \ub54c stream/text \uad00\ub828\ub41c \ubd80\ubd84 \ub3d9\uc791\ub418\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\ub824\uace0 \ud558\uace0, \uadf8 \uc678\uc758 \ubd80\ubd84\uc740 \uc870\uae08 \ub354 \uace0\ubbfc\ud574\uc57c\ub420 \uac83 \uac19\ub2e4."]})]})}function d(e={}){const{wrapper:t}={...(0,c.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?s(Object(r),!0).forEach((function(t){c(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,c=function(e,t){if(null==e)return{};var r,n,c={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(c[r]=e[r]);return c}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var o=n.createContext({}),l=function(e){var t=n.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,c=e.mdxType,s=e.originalType,o=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),h=l(r),b=c,u=h["".concat(o,".").concat(b)]||h[b]||p[b]||s;return r?n.createElement(u,i(i({ref:t},d),{},{components:r})):n.createElement(u,i({ref:t},d))}));d.displayName="MDXCreateElement"},49483:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat1-e9408e2e2f13bb192541de194ffccc6a.png"},50885:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat2-4b3b653eb2b23b88f19e8cb4177a786c.png"},15153:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat3-12a510067e4d210c13e46b7b99313307.png"}}]); \ No newline at end of file diff --git a/assets/js/48faf148.36080fd6.js b/assets/js/48faf148.36080fd6.js deleted file mode 100644 index 70fbc5b84..000000000 --- a/assets/js/48faf148.36080fd6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7328],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>b});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},l=Object.keys(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),m=c(r),b=a,d=m["".concat(i,".").concat(b)]||m[b]||u[b]||l;return r?n.createElement(d,o(o({ref:t},s),{},{components:r})):n.createElement(d,o({ref:t},s))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=m;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:a,o[1]=p;for(var c=2;c<l;c++)o[c]=r[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},59455:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",slug:"tecochat-retrospective-3",tags:["TecoChat","Retrospective"]},o=void 0,p={permalink:"/tecochat-retrospective-3",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",source:"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",description:"\uac1c\uc694",date:"2023-06-01T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 1\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.005,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",slug:"tecochat-retrospective-3",tags:["TecoChat","Retrospective"]},prevItem:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",permalink:"/order-retrospective"},nextItem:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",permalink:"/composite"}},i={authorsImageUrls:[]},c=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5",id:"\ub098\uc758-\ucc44\ud305-\ud655\uc778\ud558\uace0-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",level:3},{value:"\uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5",id:"\uc88b\uc544\uc694\uc640-\ub313\uae00-\uae30\ub2a5",level:3},{value:"\ud0a4\uc6cc\ub4dc \ucd94\ucd9c",id:"\ud0a4\uc6cc\ub4dc-\ucd94\ucd9c",level:3},{value:"\ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5",id:"\ub2e4\ub978-\ud06c\ub8e8\uc758-\ucc44\ud305-\ubcf5\uc0ac\ud574\uc11c-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",level:3},{value:"\uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30",id:"\uc0ac\uc6a9\uc131-\uace0\ub824\ud558\uae30",level:3},{value:"\ud5a5\ud6c4 \uacc4\ud68d",id:"\ud5a5\ud6c4-\uacc4\ud68d",level:3}],s={toc:c};function u(e){let{components:t,...l}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,l,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,a.kt)("p",null,"\uc6d0\ub798 \ubaa9\uc801\uc778 ",(0,a.kt)("inlineCode",{parentName:"p"},"\ud06c\ub8e8\ub4e4\uc758 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0"),"\uc744 \uc8fc\uae30 \uc704\ud574 \uc5b4\ub5a4 \uae30\ub2a5\uc744 \ucd94\uac00\ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 2\uac00 \uac70\uc758 \ub05d\ub098\uac00\ub294 \uc2dc\uc810, \uadf8\ub3d9\uc548 \ud588\ub358 \uac83\uc744 \uc815\ub9ac\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ub098\uc758-\ucc44\ud305-\ud655\uc778\ud558\uace0-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5"},"\ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5"),(0,a.kt)("p",null,"GPT\uc5d0\ub3c4 \uc788\ub294 \uae30\ub2a5\uc778\ub370, \ub0b4\uac00 \uc774\uc804\uc5d0 \ud588\ub358 \ucc44\ud305\uc744 \uc774\uc5b4\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\uc804\uc5d0 \uc5b4\ub5a4 \uc9c8\ubb38\uc744 \ub0a8\uacbc\ub294\uc9c0, \ub610\ud55c \ud574\ub2f9 \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"chat1",src:r(49483).Z,width:"2878",height:"1316"})),(0,a.kt)("h3",{id:"\uc88b\uc544\uc694\uc640-\ub313\uae00-\uae30\ub2a5"},"\uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5"),(0,a.kt)("p",null,"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc5d0 \ubc18\uc751\ud560 \uc218 \uc788\ub294 \ubb34\uc5b8\uac00\uac00 \uc788\uc5c8\uc73c\uba74 \uc88b\uaca0\ub2e4\ub294 \uc758\uacac\ub4e4\uc774 \ub9ce\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub204\uac00 \uc88b\uc544\uc694\ub97c \ub20c\ub800\ub294\uc9c0, \uc5b4\ub5a4 \ucc44\ud305\uc774 \uc88b\uc544\uc694\ub97c \uac00\uc7a5 \ub9ce\uc774 \ubc1b\uc558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ub313\uae00 \ucd94\uac00 \ubc0f \uc0ad\uc81c \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4."),(0,a.kt)("h3",{id:"\ud0a4\uc6cc\ub4dc-\ucd94\ucd9c"},"\ud0a4\uc6cc\ub4dc \ucd94\ucd9c"),(0,a.kt)("p",null,"\uc5b4\ub5bb\uac8c \ud0a4\uc6cc\ub4dc \ucd94\ucd9c\uc744 \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub294\ub370, \uc77c\ub2e8 GPT\ub97c \uc774\uc6a9\ud574\uc11c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\uae30\ub85c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \ubd80\ubd84\uc740 \uccab \uc9c8\ubb38\uc5d0 \ub300\ud55c \ud0a4\uc6cc\ub4dc\ub9cc \ucd94\ucd9c\ud558\ub3c4\ub85d \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc31\uc5d4\ub4dc\uc5d0\uc120 \ub9d0\ub791\uc774 \uc774\ubca4\ud2b8 \uc774\uc6a9\ud574\uc11c \uccab \ucc44\ud305 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c0\uba74, \ube44\ub3d9\uae30\ub85c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\ub294 \uc9c8\ubb38\uc744 \ucd94\uac00\ub85c \ub0a0\ub9ac\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","CSV \ud615\uc2dd\uc73c\ub85c GPT\uc5d0\uac8c \ub2f5\ubcc0\uc744 \uc785\ub825\ud574\ub2ec\ub77c\uace0 \uc694\uccad\ubc1b\ub294\ub370, \uc774 \ubd80\ubd84\uc774 \ubb38\uc81c(\ud504\ub86c\ud504\ud2b8 \uc5d4\uc9c0\ub2c8\uc5b4\ub9c1 \ubd80\ubd84\uc774 \ubc18\ud658\ub41c\ub2e4.)\uac00 \uc880 \uc788\ub294 \uac83 \uac19\uc544\uc11c \uac1c\uc120\uc774 \ud544\uc694\ud55c \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"chat2",src:r(50885).Z,width:"2394",height:"1048"})),(0,a.kt)("h3",{id:"\ub2e4\ub978-\ud06c\ub8e8\uc758-\ucc44\ud305-\ubcf5\uc0ac\ud574\uc11c-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5"},"\ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5"),(0,a.kt)("p",null,"\ub2e4\ub978 \ud06c\ub8e8\ub4e4\uc758 \ucc44\ud305\uc744 \uc77d\ub2e4\uac00 \uad81\uae08\ud55c \uc810\uc774 \uc788\ub2e4\uba74 \ubcf5\uc0ac\ud574\uc11c \ubc14\ub85c \uc9c8\ubb38\uc744 \ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc44\ud305\uc774 \ubcf5\uc0ac\ub41c \ud6c4 \ubc14\ub85c GPT\uc640 \ub300\ud654\ub97c \ud560 \uc218 \uc788\ub294 \uba54\uc778 \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc0ac\uc6a9\uc131-\uace0\ub824\ud558\uae30"},"\uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"chat3",src:r(15153).Z,width:"1668",height:"718"})),(0,a.kt)("p",null,"\uc704 \ud654\uba74\uc740 \ud68c\uc6d0\uac00\uc785 \ucc3d\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc2e4 \uac00\uc7a5 \ub9c8\uc74c\uc5d0 \ub4dc\ub294 \ubd80\ubd84\uc774\uace0, \ud68c\uc6d0\uac00\uc785(\ub2c9\ub124\uc784\ub9cc \uc785\ub825\ud558\uc9c0\ub9cc)\ud560 \ub54c \uc775\uba85\uc744 \uc6d0\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uace0\ubbfc\uc744 \ub3c4\uc640\uc8fc\uac8c \ub054 \uc74c\uc2dd, \uacfc\uc77c, \uacfc\uc790 \ub4f1\uc758 \uc694\uc18c\ub4e4\uc744 \uc785\ub825\ud558\ub3c4\ub85d \uc720\ub3c4\ud588\ub2e4!\n\ucd94\uac00\ub85c GPT\uc758 \ub2f5\ubcc0\uc774 \uc624\uba74 \uc790\ub3d9\uc73c\ub85c \ud654\uba74\uc744 \uc2a4\ud06c\ub864 \ud574\uc8fc\ub294 \uac83\uacfc \uac19\uc774 \uc0ac\uc6a9\uc131\uc744 \uac1c\uc120\ud574 \ubcf4\ub824\uace0 \ub178\ub825\ud588\uc9c0\ub9cc \uc27d\uc9c0 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc81c\uc77c \ud558\uace0 \uc2f6\uc740 \uac83\uc740 \uc2e4\uc81c GPT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ucc98\ub7fc stream/text \uac12\uc744 \ucc98\ub9ac\ud558\uace0 \uc2f6\uc740\ub370 \uc774 \ubd80\ubd84\uc740 \ubc29\ud559 \ub54c \uae30\ud68c\uac00 \ub418\uba74 \ub3c4\uc804\ud574 \ubd10\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\ud5a5\ud6c4-\uacc4\ud68d"},"\ud5a5\ud6c4 \uacc4\ud68d"),(0,a.kt)("p",null,"\uc2e4\uc81c \ud06c\ub8e8\ub4e4\uc774 \uc0ac\uc6a9\ud574 \uc8fc\ub294 \uc11c\ube44\uc2a4\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\ubcf4\uba74\uc11c \uc0ac\uc6a9\uc790\uc758 \uc785\uc7a5\uc5d0\uc11c \uace0\ubbfc\ub3c4 \ud558\uac8c \ub418\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud06c\ub8e8\ub4e4\uc774 \uc9c1\uc811 \uc0ac\uc6a9\ud574 \uc8fc\ub2c8\uae4c \ub108\ubb34 \uace0\ub9d9\uace0, \ud55c\ud3b8\uc73c\ub85c\ub294 \uc2e0\uae30\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ub2e8 \ubc29\ud559 \ub54c stream/text \uad00\ub828\ub41c \ubd80\ubd84 \ub3d9\uc791\ub418\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\ub824\uace0 \ud558\uace0, \uadf8 \uc678\uc758 \ubd80\ubd84\uc740 \uc870\uae08 \ub354 \uace0\ubbfc\ud574\uc57c\ub420 \uac83 \uac19\ub2e4."))}u.isMDXComponent=!0},49483:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat1-e9408e2e2f13bb192541de194ffccc6a.png"},50885:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat2-4b3b653eb2b23b88f19e8cb4177a786c.png"},15153:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat3-12a510067e4d210c13e46b7b99313307.png"}}]); \ No newline at end of file diff --git a/assets/js/4926.50b7d3b0.js b/assets/js/4926.50b7d3b0.js new file mode 100644 index 000000000..df6067cf6 --- /dev/null +++ b/assets/js/4926.50b7d3b0.js @@ -0,0 +1,2 @@ +/*! For license information please see 4926.50b7d3b0.js.LICENSE.txt */ +(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4926],{17967:(t,e)=>{"use strict";e.Nm=e.Rq=void 0;var i=/^([^\w]*)(javascript|data|vbscript)/im,r=/&#(\w+)(^\w|;)?/g,n=/&(newline|tab);/gi,o=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,a=/^.+(:|:)/gim,s=[".","/"];e.Rq="about:blank",e.Nm=function(t){if(!t)return e.Rq;var l,c=(l=t,l.replace(o,"").replace(r,(function(t,e){return String.fromCharCode(e)}))).replace(n,"").replace(o,"").trim();if(!c)return e.Rq;if(function(t){return s.indexOf(t[0])>-1}(c))return c;var h=c.match(a);if(!h)return c;var u=h[0];return i.test(u)?e.Rq:c}},59047:(t,e,i)=>{"use strict";i.d(e,{Z:()=>A});var r=i(67294),n=i(85893);function o(t){const{mdxAdmonitionTitle:e,rest:i}=function(t){const e=r.Children.toArray(t),i=e.find((t=>r.isValidElement(t)&&"mdxAdmonitionTitle"===t.type)),o=e.filter((t=>t!==i)),a=i?.props.children;return{mdxAdmonitionTitle:a,rest:o.length>0?(0,n.jsx)(n.Fragment,{children:o}):null}}(t.children),o=t.title??e;return{...t,...o&&{title:o},children:i}}var a=i(86010),s=i(95999),l=i(35281);const c={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function h(t){let{type:e,className:i,children:r}=t;return(0,n.jsx)("div",{className:(0,a.Z)(l.k.common.admonition,l.k.common.admonitionType(e),c.admonition,i),children:r})}function u(t){let{icon:e,title:i}=t;return(0,n.jsxs)("div",{className:c.admonitionHeading,children:[(0,n.jsx)("span",{className:c.admonitionIcon,children:e}),i]})}function d(t){let{children:e}=t;return e?(0,n.jsx)("div",{className:c.admonitionContent,children:e}):null}function f(t){const{type:e,icon:i,title:r,children:o,className:a}=t;return(0,n.jsxs)(h,{type:e,className:a,children:[(0,n.jsx)(u,{title:r,icon:i}),(0,n.jsx)(d,{children:o})]})}function p(t){return(0,n.jsx)("svg",{viewBox:"0 0 14 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const g={icon:(0,n.jsx)(p,{}),title:(0,n.jsx)(s.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function m(t){return(0,n.jsx)(f,{...g,...t,className:(0,a.Z)("alert alert--secondary",t.className),children:t.children})}function y(t){return(0,n.jsx)("svg",{viewBox:"0 0 12 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const x={icon:(0,n.jsx)(y,{}),title:(0,n.jsx)(s.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function C(t){return(0,n.jsx)(f,{...x,...t,className:(0,a.Z)("alert alert--success",t.className),children:t.children})}function b(t){return(0,n.jsx)("svg",{viewBox:"0 0 14 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const _={icon:(0,n.jsx)(b,{}),title:(0,n.jsx)(s.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function v(t){return(0,n.jsx)(f,{..._,...t,className:(0,a.Z)("alert alert--info",t.className),children:t.children})}function k(t){return(0,n.jsx)("svg",{viewBox:"0 0 16 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const T={icon:(0,n.jsx)(k,{}),title:(0,n.jsx)(s.Z,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function w(t){return(0,n.jsx)("svg",{viewBox:"0 0 12 16",...t,children:(0,n.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const S={icon:(0,n.jsx)(w,{}),title:(0,n.jsx)(s.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const B={icon:(0,n.jsx)(k,{}),title:(0,n.jsx)(s.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const F={...{note:m,tip:C,info:v,warning:function(t){return(0,n.jsx)(f,{...T,...t,className:(0,a.Z)("alert alert--warning",t.className),children:t.children})},danger:function(t){return(0,n.jsx)(f,{...S,...t,className:(0,a.Z)("alert alert--danger",t.className),children:t.children})}},...{secondary:t=>(0,n.jsx)(m,{title:"secondary",...t}),important:t=>(0,n.jsx)(v,{title:"important",...t}),success:t=>(0,n.jsx)(C,{title:"success",...t}),caution:function(t){return(0,n.jsx)(f,{...B,...t,className:(0,a.Z)("alert alert--warning",t.className),children:t.children})}}};function A(t){const e=o(t),i=(r=e.type,F[r]||(console.warn(`No admonition component found for admonition type "${r}". Using Info as fallback.`),F.info));var r;return(0,n.jsx)(i,{...e})}},84881:(t,e,i)=>{"use strict";i.d(e,{Z:()=>h});i(67294);var r=i(95999),n=i(35281),o=i(39960),a=i(86010);const s={iconEdit:"iconEdit_Z9Sw"};var l=i(85893);function c(t){let{className:e,...i}=t;return(0,l.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,a.Z)(s.iconEdit,e),"aria-hidden":"true",...i,children:(0,l.jsx)("g",{children:(0,l.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function h(t){let{editUrl:e}=t;return(0,l.jsxs)(o.Z,{to:e,className:n.k.common.editThisPage,children:[(0,l.jsx)(c,{}),(0,l.jsx)(r.Z,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}},76643:(t,e,i)=>{"use strict";i.d(e,{Z:()=>pt});var r=i(67294);const n={},o=r.createContext(n);function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:function(t){const e=r.useContext(o);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}(t.components),r.createElement(o.Provider,{value:e},t.children)}var s=i(35742),l=i(72389),c=i(86010),h=i(92949),u=i(86668);function d(){const{prism:t}=(0,u.L)(),{colorMode:e}=(0,h.I)(),i=t.theme,r=t.darkTheme||i;return"dark"===e?r:i}var f=i(35281),p=i(87594),g=i.n(p);const m=/title=(?<quote>["'])(?<title>.*?)\1/,y=/\{(?<range>[\d,-]+)\}/,x={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"},lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""}};function C(t,e){const i=t.map((t=>{const{start:i,end:r}=x[t];return`(?:${i}\\s*(${e.flatMap((t=>[t.line,t.block?.start,t.block?.end].filter(Boolean))).join("|")})\\s*${r})`})).join("|");return new RegExp(`^\\s*(?:${i})\\s*$`)}function b(t,e){let i=t.replace(/\n$/,"");const{language:r,magicComments:n,metastring:o}=e;if(o&&y.test(o)){const t=o.match(y).groups.range;if(0===n.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const e=n[0].className,r=g()(t).filter((t=>t>0)).map((t=>[t-1,[e]]));return{lineClassNames:Object.fromEntries(r),code:i}}if(void 0===r)return{lineClassNames:{},code:i};const a=function(t,e){switch(t){case"js":case"javascript":case"ts":case"typescript":return C(["js","jsBlock"],e);case"jsx":case"tsx":return C(["js","jsBlock","jsx"],e);case"html":return C(["js","jsBlock","html"],e);case"python":case"py":case"bash":return C(["bash"],e);case"markdown":case"md":return C(["html","jsx","bash"],e);case"tex":case"latex":case"matlab":return C(["tex"],e);case"lua":case"haskell":case"sql":return C(["lua"],e);case"wasm":return C(["wasm"],e);default:return C(Object.keys(x).filter((t=>!["lua","wasm","tex","latex","matlab"].includes(t))),e)}}(r,n),s=i.split("\n"),l=Object.fromEntries(n.map((t=>[t.className,{start:0,range:""}]))),c=Object.fromEntries(n.filter((t=>t.line)).map((t=>{let{className:e,line:i}=t;return[i,e]}))),h=Object.fromEntries(n.filter((t=>t.block)).map((t=>{let{className:e,block:i}=t;return[i.start,e]}))),u=Object.fromEntries(n.filter((t=>t.block)).map((t=>{let{className:e,block:i}=t;return[i.end,e]})));for(let f=0;f<s.length;){const t=s[f].match(a);if(!t){f+=1;continue}const e=t.slice(1).find((t=>void 0!==t));c[e]?l[c[e]].range+=`${f},`:h[e]?l[h[e]].start=f:u[e]&&(l[u[e]].range+=`${l[u[e]].start}-${f-1},`),s.splice(f,1)}i=s.join("\n");const d={};return Object.entries(l).forEach((t=>{let[e,{range:i}]=t;g()(i).forEach((t=>{d[t]??=[],d[t].push(e)}))})),{lineClassNames:d,code:i}}const _={codeBlockContainer:"codeBlockContainer_Ckt0"};var v=i(85893);function k(t){let{as:e,...i}=t;const r=function(t){const e={color:"--prism-color",backgroundColor:"--prism-background-color"},i={};return Object.entries(t.plain).forEach((t=>{let[r,n]=t;const o=e[r];o&&"string"==typeof n&&(i[o]=n)})),i}(d());return(0,v.jsx)(e,{...i,style:r,className:(0,c.Z)(i.className,_.codeBlockContainer,f.k.common.codeBlock)})}const T={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function w(t){let{children:e,className:i}=t;return(0,v.jsx)(k,{as:"pre",tabIndex:0,className:(0,c.Z)(T.codeBlockStandalone,"thin-scrollbar",i),children:(0,v.jsx)("code",{className:T.codeBlockLines,children:e})})}var S=i(902);const B={attributes:!0,characterData:!0,childList:!0,subtree:!0};function F(t,e){const[i,n]=(0,r.useState)(),o=(0,r.useCallback)((()=>{n(t.current?.closest("[role=tabpanel][hidden]"))}),[t,n]);(0,r.useEffect)((()=>{o()}),[o]),function(t,e,i){void 0===i&&(i=B);const n=(0,S.zX)(e),o=(0,S.Ql)(i);(0,r.useEffect)((()=>{const e=new MutationObserver(n);return t&&e.observe(t,o),()=>e.disconnect()}),[t,n,o])}(i,(t=>{t.forEach((t=>{"attributes"===t.type&&"hidden"===t.attributeName&&(e(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var A=i(34798);const L={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function M(t){let{line:e,classNames:i,showLineNumbers:r,getLineProps:n,getTokenProps:o}=t;1===e.length&&"\n"===e[0].content&&(e[0].content="");const a=n({line:e,className:(0,c.Z)(i,r&&L.codeLine)}),s=e.map(((t,e)=>(0,v.jsx)("span",{...o({token:t,key:e})},e)));return(0,v.jsxs)("span",{...a,children:[r?(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)("span",{className:L.codeLineNumber}),(0,v.jsx)("span",{className:L.codeLineContent,children:s})]}):s,(0,v.jsx)("br",{})]})}var E=i(95999);function Z(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function N(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const O={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function I(t){let{code:e,className:i}=t;const[n,o]=(0,r.useState)(!1),a=(0,r.useRef)(void 0),s=(0,r.useCallback)((()=>{!function(t,e){let{target:i=document.body}=void 0===e?{}:e;if("string"!=typeof t)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof t}\`.`);const r=document.createElement("textarea"),n=document.activeElement;r.value=t,r.setAttribute("readonly",""),r.style.contain="strict",r.style.position="absolute",r.style.left="-9999px",r.style.fontSize="12pt";const o=document.getSelection(),a=o.rangeCount>0&&o.getRangeAt(0);i.append(r),r.select(),r.selectionStart=0,r.selectionEnd=t.length;let s=!1;try{s=document.execCommand("copy")}catch{}r.remove(),a&&(o.removeAllRanges(),o.addRange(a)),n&&n.focus()}(e),o(!0),a.current=window.setTimeout((()=>{o(!1)}),1e3)}),[e]);return(0,r.useEffect)((()=>()=>window.clearTimeout(a.current)),[]),(0,v.jsx)("button",{type:"button","aria-label":n?(0,E.I)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,E.I)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,E.I)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,c.Z)("clean-btn",i,O.copyButton,n&&O.copyButtonCopied),onClick:s,children:(0,v.jsxs)("span",{className:O.copyButtonIcons,"aria-hidden":"true",children:[(0,v.jsx)(Z,{className:O.copyButtonIcon}),(0,v.jsx)(N,{className:O.copyButtonSuccessIcon})]})})}function j(t){return(0,v.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,v.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const q={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function D(t){let{className:e,onClick:i,isEnabled:r}=t;const n=(0,E.I)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,v.jsx)("button",{type:"button",onClick:i,className:(0,c.Z)("clean-btn",e,r&&q.wordWrapButtonEnabled),"aria-label":n,title:n,children:(0,v.jsx)(j,{className:q.wordWrapButtonIcon,"aria-hidden":"true"})})}function $(t){let{children:e,className:i="",metastring:n,title:o,showLineNumbers:a,language:s}=t;const{prism:{defaultLanguage:l,magicComments:h}}=(0,u.L)(),f=function(t){return t?.toLowerCase()}(s??function(t){const e=t.split(" ").find((t=>t.startsWith("language-")));return e?.replace(/language-/,"")}(i)??l),p=d(),g=function(){const[t,e]=(0,r.useState)(!1),[i,n]=(0,r.useState)(!1),o=(0,r.useRef)(null),a=(0,r.useCallback)((()=>{const i=o.current.querySelector("code");t?i.removeAttribute("style"):(i.style.whiteSpace="pre-wrap",i.style.overflowWrap="anywhere"),e((t=>!t))}),[o,t]),s=(0,r.useCallback)((()=>{const{scrollWidth:t,clientWidth:e}=o.current,i=t>e||o.current.querySelector("code").hasAttribute("style");n(i)}),[o]);return F(o,s),(0,r.useEffect)((()=>{s()}),[t,s]),(0,r.useEffect)((()=>(window.addEventListener("resize",s,{passive:!0}),()=>{window.removeEventListener("resize",s)})),[s]),{codeBlockRef:o,isEnabled:t,isCodeScrollable:i,toggle:a}}(),y=function(t){return t?.match(m)?.groups.title??""}(n)||o,{lineClassNames:x,code:C}=b(e,{metastring:n,language:f,magicComments:h}),_=a??function(t){return Boolean(t?.includes("showLineNumbers"))}(n);return(0,v.jsxs)(k,{as:"div",className:(0,c.Z)(i,f&&!i.includes(`language-${f}`)&&`language-${f}`),children:[y&&(0,v.jsx)("div",{className:T.codeBlockTitle,children:y}),(0,v.jsxs)("div",{className:T.codeBlockContent,children:[(0,v.jsx)(A.y$,{theme:p,code:C,language:f??"text",children:t=>{let{className:e,style:i,tokens:r,getLineProps:n,getTokenProps:o}=t;return(0,v.jsx)("pre",{tabIndex:0,ref:g.codeBlockRef,className:(0,c.Z)(e,T.codeBlock,"thin-scrollbar"),style:i,children:(0,v.jsx)("code",{className:(0,c.Z)(T.codeBlockLines,_&&T.codeBlockLinesWithNumbering),children:r.map(((t,e)=>(0,v.jsx)(M,{line:t,getLineProps:n,getTokenProps:o,classNames:x[e],showLineNumbers:_},e)))})})}}),(0,v.jsxs)("div",{className:T.buttonGroup,children:[(g.isEnabled||g.isCodeScrollable)&&(0,v.jsx)(D,{className:T.codeButton,onClick:()=>g.toggle(),isEnabled:g.isEnabled}),(0,v.jsx)(I,{className:T.codeButton,code:C})]})]})]})}function z(t){let{children:e,...i}=t;const n=(0,l.Z)(),o=function(t){return r.Children.toArray(t).some((t=>(0,r.isValidElement)(t)))?t:Array.isArray(t)?t.join(""):t}(e),a="string"==typeof o?$:w;return(0,v.jsx)(a,{...i,children:o},String(n))}var P=i(39960);var R=i(86043);const W={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function H(t){return!!t&&("SUMMARY"===t.tagName||H(t.parentElement))}function U(t,e){return!!t&&(t===e||U(t.parentElement,e))}function Y(t){let{summary:e,children:i,...n}=t;const o=(0,l.Z)(),a=(0,r.useRef)(null),{collapsed:s,setCollapsed:h}=(0,R.u)({initialState:!n.open}),[u,d]=(0,r.useState)(n.open),f=r.isValidElement(e)?e:(0,v.jsx)("summary",{children:e??"Details"});return(0,v.jsxs)("details",{...n,ref:a,open:u,"data-collapsed":s,className:(0,c.Z)(W.details,o&&W.isBrowser,n.className),onMouseDown:t=>{H(t.target)&&t.detail>1&&t.preventDefault()},onClick:t=>{t.stopPropagation();const e=t.target;H(e)&&U(e,a.current)&&(t.preventDefault(),s?(h(!1),d(!0)):h(!0))},children:[f,(0,v.jsx)(R.z,{lazy:!1,collapsed:s,disableSSRStyle:!0,onCollapseTransitionEnd:t=>{h(t),d(!t)},children:(0,v.jsx)("div",{className:W.collapsibleContent,children:i})})]})}const V={details:"details_b_Ee"},G="alert alert--info";function X(t){let{...e}=t;return(0,v.jsx)(Y,{...e,className:(0,c.Z)(G,V.details,e.className)})}function Q(t){const e=r.Children.toArray(t.children),i=e.find((t=>r.isValidElement(t)&&"summary"===t.type)),n=(0,v.jsx)(v.Fragment,{children:e.filter((t=>t!==i))});return(0,v.jsx)(X,{...t,summary:i,children:n})}var J=i(92503);function K(t){return(0,v.jsx)(J.Z,{...t})}const tt={containsTaskList:"containsTaskList_mC6p"};function et(t){if(void 0!==t)return(0,c.Z)(t,t?.includes("contains-task-list")&&tt.containsTaskList)}const it={img:"img_ev3q"};var rt=i(59047),nt=i(44763),ot=i(69690),at=i(56363);const st="docusaurus-mermaid-container";function lt(){const{colorMode:t}=(0,h.I)(),e=(0,u.L)().mermaid,i=e.theme[t],{options:n}=e;return(0,r.useMemo)((()=>({startOnLoad:!1,...n,theme:i})),[i,n])}function ct(t){let{text:e,config:i}=t;const[n,o]=(0,r.useState)(null),a=(0,r.useRef)(`mermaid-svg-${Math.round(1e7*Math.random())}`).current,s=lt(),l=i??s;return(0,r.useEffect)((()=>{(async function(t){let{id:e,text:i,config:r}=t;at.L.mermaidAPI.initialize(r);try{return await at.L.render(e,i)}catch(n){throw document.querySelector(`#d${e}`)?.remove(),n}})({id:a,text:e,config:l}).then(o).catch((t=>{o((()=>{throw t}))}))}),[a,e,l]),n}const ht={container:"container_lyt7"};function ut(t){let{renderResult:e}=t;const i=(0,r.useRef)(null);return(0,r.useEffect)((()=>{const t=i.current;e.bindFunctions?.(t)}),[e]),(0,v.jsx)("div",{ref:i,className:`${st} ${ht.container}`,dangerouslySetInnerHTML:{__html:e.svg}})}function dt(t){let{value:e}=t;const i=ct({text:e});return null===i?null:(0,v.jsx)(ut,{renderResult:i})}const ft={Head:s.Z,details:Q,Details:Q,code:function(t){return r.Children.toArray(t.children).every((t=>"string"==typeof t&&!t.includes("\n")))?(0,v.jsx)("code",{...t}):(0,v.jsx)(z,{...t})},a:function(t){return(0,v.jsx)(P.Z,{...t})},pre:function(t){return(0,v.jsx)(v.Fragment,{children:t.children})},ul:function(t){return(0,v.jsx)("ul",{...t,className:et(t.className)})},img:function(t){return(0,v.jsx)("img",{loading:"lazy",...t,className:(e=t.className,(0,c.Z)(e,it.img))});var e},h1:t=>(0,v.jsx)(K,{as:"h1",...t}),h2:t=>(0,v.jsx)(K,{as:"h2",...t}),h3:t=>(0,v.jsx)(K,{as:"h3",...t}),h4:t=>(0,v.jsx)(K,{as:"h4",...t}),h5:t=>(0,v.jsx)(K,{as:"h5",...t}),h6:t=>(0,v.jsx)(K,{as:"h6",...t}),admonition:rt.Z,mermaid:function(t){return(0,v.jsx)(nt.Z,{fallback:t=>(0,v.jsx)(ot.Ac,{...t}),children:(0,v.jsx)(dt,{...t})})}};function pt(t){let{children:e}=t;return(0,v.jsx)(a,{components:ft,children:e})}},32244:(t,e,i)=>{"use strict";i.d(e,{Z:()=>a});i(67294);var r=i(86010),n=i(39960),o=i(85893);function a(t){const{permalink:e,title:i,subLabel:a,isNext:s}=t;return(0,o.jsxs)(n.Z,{className:(0,r.Z)("pagination-nav__link",s?"pagination-nav__link--next":"pagination-nav__link--prev"),to:e,children:[a&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:a}),(0,o.jsx)("div",{className:"pagination-nav__label",children:i})]})}},13008:(t,e,i)=>{"use strict";i.d(e,{Z:()=>s});i(67294);var r=i(86010),n=i(39960);const o={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var a=i(85893);function s(t){let{permalink:e,label:i,count:s}=t;return(0,a.jsxs)(n.Z,{href:e,className:(0,r.Z)(o.tag,s?o.tagWithCount:o.tagRegular),children:[i,s&&(0,a.jsx)("span",{children:s})]})}},71526:(t,e,i)=>{"use strict";i.d(e,{Z:()=>l});i(67294);var r=i(86010),n=i(95999),o=i(13008);const a={tags:"tags_jXut",tag:"tag_QGVx"};var s=i(85893);function l(t){let{tags:e}=t;return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("b",{children:(0,s.jsx)(n.Z,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,s.jsx)("ul",{className:(0,r.Z)(a.tags,"padding--none","margin-left--sm"),children:e.map((t=>{let{label:e,permalink:i}=t;return(0,s.jsx)("li",{className:a.tag,children:(0,s.jsx)(o.Z,{label:e,permalink:i})},i)}))})]})}},27484:function(t){t.exports=function(){"use strict";var t=1e3,e=6e4,i=36e5,r="millisecond",n="second",o="minute",a="hour",s="day",l="week",c="month",h="quarter",u="year",d="date",f="Invalid Date",p=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,g=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],i=t%100;return"["+t+(e[(i-20)%10]||e[i]||e[0])+"]"}},y=function(t,e,i){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(i)+t},x={s:y,z:function(t){var e=-t.utcOffset(),i=Math.abs(e),r=Math.floor(i/60),n=i%60;return(e<=0?"+":"-")+y(r,2,"0")+":"+y(n,2,"0")},m:function t(e,i){if(e.date()<i.date())return-t(i,e);var r=12*(i.year()-e.year())+(i.month()-e.month()),n=e.clone().add(r,c),o=i-n<0,a=e.clone().add(r+(o?-1:1),c);return+(-(r+(i-n)/(o?n-a:a-n))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:u,w:l,d:s,D:d,h:a,m:o,s:n,ms:r,Q:h}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},C="en",b={};b[C]=m;var _="$isDayjsObject",v=function(t){return t instanceof S||!(!t||!t[_])},k=function t(e,i,r){var n;if(!e)return C;if("string"==typeof e){var o=e.toLowerCase();b[o]&&(n=o),i&&(b[o]=i,n=o);var a=e.split("-");if(!n&&a.length>1)return t(a[0])}else{var s=e.name;b[s]=e,n=s}return!r&&n&&(C=n),n||!r&&C},T=function(t,e){if(v(t))return t.clone();var i="object"==typeof e?e:{};return i.date=t,i.args=arguments,new S(i)},w=x;w.l=k,w.i=v,w.w=function(t,e){return T(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var S=function(){function m(t){this.$L=k(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[_]=!0}var y=m.prototype;return y.parse=function(t){this.$d=function(t){var e=t.date,i=t.utc;if(null===e)return new Date(NaN);if(w.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(p);if(r){var n=r[2]-1||0,o=(r[7]||"0").substring(0,3);return i?new Date(Date.UTC(r[1],n,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)):new Date(r[1],n,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)}}return new Date(e)}(t),this.init()},y.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},y.$utils=function(){return w},y.isValid=function(){return!(this.$d.toString()===f)},y.isSame=function(t,e){var i=T(t);return this.startOf(e)<=i&&i<=this.endOf(e)},y.isAfter=function(t,e){return T(t)<this.startOf(e)},y.isBefore=function(t,e){return this.endOf(e)<T(t)},y.$g=function(t,e,i){return w.u(t)?this[e]:this.set(i,t)},y.unix=function(){return Math.floor(this.valueOf()/1e3)},y.valueOf=function(){return this.$d.getTime()},y.startOf=function(t,e){var i=this,r=!!w.u(e)||e,h=w.p(t),f=function(t,e){var n=w.w(i.$u?Date.UTC(i.$y,e,t):new Date(i.$y,e,t),i);return r?n:n.endOf(s)},p=function(t,e){return w.w(i.toDate()[t].apply(i.toDate("s"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),i)},g=this.$W,m=this.$M,y=this.$D,x="set"+(this.$u?"UTC":"");switch(h){case u:return r?f(1,0):f(31,11);case c:return r?f(1,m):f(0,m+1);case l:var C=this.$locale().weekStart||0,b=(g<C?g+7:g)-C;return f(r?y-b:y+(6-b),m);case s:case d:return p(x+"Hours",0);case a:return p(x+"Minutes",1);case o:return p(x+"Seconds",2);case n:return p(x+"Milliseconds",3);default:return this.clone()}},y.endOf=function(t){return this.startOf(t,!1)},y.$set=function(t,e){var i,l=w.p(t),h="set"+(this.$u?"UTC":""),f=(i={},i[s]=h+"Date",i[d]=h+"Date",i[c]=h+"Month",i[u]=h+"FullYear",i[a]=h+"Hours",i[o]=h+"Minutes",i[n]=h+"Seconds",i[r]=h+"Milliseconds",i)[l],p=l===s?this.$D+(e-this.$W):e;if(l===c||l===u){var g=this.clone().set(d,1);g.$d[f](p),g.init(),this.$d=g.set(d,Math.min(this.$D,g.daysInMonth())).$d}else f&&this.$d[f](p);return this.init(),this},y.set=function(t,e){return this.clone().$set(t,e)},y.get=function(t){return this[w.p(t)]()},y.add=function(r,h){var d,f=this;r=Number(r);var p=w.p(h),g=function(t){var e=T(f);return w.w(e.date(e.date()+Math.round(t*r)),f)};if(p===c)return this.set(c,this.$M+r);if(p===u)return this.set(u,this.$y+r);if(p===s)return g(1);if(p===l)return g(7);var m=(d={},d[o]=e,d[a]=i,d[n]=t,d)[p]||1,y=this.$d.getTime()+r*m;return w.w(y,this)},y.subtract=function(t,e){return this.add(-1*t,e)},y.format=function(t){var e=this,i=this.$locale();if(!this.isValid())return i.invalidDate||f;var r=t||"YYYY-MM-DDTHH:mm:ssZ",n=w.z(this),o=this.$H,a=this.$m,s=this.$M,l=i.weekdays,c=i.months,h=i.meridiem,u=function(t,i,n,o){return t&&(t[i]||t(e,r))||n[i].slice(0,o)},d=function(t){return w.s(o%12||12,t,"0")},p=h||function(t,e,i){var r=t<12?"AM":"PM";return i?r.toLowerCase():r};return r.replace(g,(function(t,r){return r||function(t){switch(t){case"YY":return String(e.$y).slice(-2);case"YYYY":return w.s(e.$y,4,"0");case"M":return s+1;case"MM":return w.s(s+1,2,"0");case"MMM":return u(i.monthsShort,s,c,3);case"MMMM":return u(c,s);case"D":return e.$D;case"DD":return w.s(e.$D,2,"0");case"d":return String(e.$W);case"dd":return u(i.weekdaysMin,e.$W,l,2);case"ddd":return u(i.weekdaysShort,e.$W,l,3);case"dddd":return l[e.$W];case"H":return String(o);case"HH":return w.s(o,2,"0");case"h":return d(1);case"hh":return d(2);case"a":return p(o,a,!0);case"A":return p(o,a,!1);case"m":return String(a);case"mm":return w.s(a,2,"0");case"s":return String(e.$s);case"ss":return w.s(e.$s,2,"0");case"SSS":return w.s(e.$ms,3,"0");case"Z":return n}return null}(t)||n.replace(":","")}))},y.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},y.diff=function(r,d,f){var p,g=this,m=w.p(d),y=T(r),x=(y.utcOffset()-this.utcOffset())*e,C=this-y,b=function(){return w.m(g,y)};switch(m){case u:p=b()/12;break;case c:p=b();break;case h:p=b()/3;break;case l:p=(C-x)/6048e5;break;case s:p=(C-x)/864e5;break;case a:p=C/i;break;case o:p=C/e;break;case n:p=C/t;break;default:p=C}return f?p:w.a(p)},y.daysInMonth=function(){return this.endOf(c).$D},y.$locale=function(){return b[this.$L]},y.locale=function(t,e){if(!t)return this.$L;var i=this.clone(),r=k(t,e,!0);return r&&(i.$L=r),i},y.clone=function(){return w.w(this.$d,this)},y.toDate=function(){return new Date(this.valueOf())},y.toJSON=function(){return this.isValid()?this.toISOString():null},y.toISOString=function(){return this.$d.toISOString()},y.toString=function(){return this.$d.toUTCString()},m}(),B=S.prototype;return T.prototype=B,[["$ms",r],["$s",n],["$m",o],["$H",a],["$W",s],["$M",c],["$y",u],["$D",d]].forEach((function(t){B[t[1]]=function(e){return this.$g(e,t[0],t[1])}})),T.extend=function(t,e){return t.$i||(t(e,S,T),t.$i=!0),T},T.locale=k,T.isDayjs=v,T.unix=function(t){return T(1e3*t)},T.en=b[C],T.Ls=b,T.p={},T}()},27856:function(t){t.exports=function(){"use strict";const{entries:t,setPrototypeOf:e,isFrozen:i,getPrototypeOf:r,getOwnPropertyDescriptor:n}=Object;let{freeze:o,seal:a,create:s}=Object,{apply:l,construct:c}="undefined"!=typeof Reflect&&Reflect;o||(o=function(t){return t}),a||(a=function(t){return t}),l||(l=function(t,e,i){return t.apply(e,i)}),c||(c=function(t,e){return new t(...e)});const h=_(Array.prototype.forEach),u=_(Array.prototype.pop),d=_(Array.prototype.push),f=_(String.prototype.toLowerCase),p=_(String.prototype.toString),g=_(String.prototype.match),m=_(String.prototype.replace),y=_(String.prototype.indexOf),x=_(String.prototype.trim),C=_(RegExp.prototype.test),b=v(TypeError);function _(t){return function(e){for(var i=arguments.length,r=new Array(i>1?i-1:0),n=1;n<i;n++)r[n-1]=arguments[n];return l(t,e,r)}}function v(t){return function(){for(var e=arguments.length,i=new Array(e),r=0;r<e;r++)i[r]=arguments[r];return c(t,i)}}function k(t,r){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:f;e&&e(t,null);let o=r.length;for(;o--;){let e=r[o];if("string"==typeof e){const t=n(e);t!==e&&(i(r)||(r[o]=t),e=t)}t[e]=!0}return t}function T(e){const i=s(null);for(const[r,o]of t(e))void 0!==n(e,r)&&(i[r]=o);return i}function w(t,e){for(;null!==t;){const i=n(t,e);if(i){if(i.get)return _(i.get);if("function"==typeof i.value)return _(i.value)}t=r(t)}function i(t){return console.warn("fallback value for",t),null}return i}const S=o(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),B=o(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),F=o(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),A=o(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),L=o(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),M=o(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),E=o(["#text"]),Z=o(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","xmlns","slot"]),N=o(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),O=o(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),I=o(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),j=a(/\{\{[\w\W]*|[\w\W]*\}\}/gm),q=a(/<%[\w\W]*|[\w\W]*%>/gm),D=a(/\${[\w\W]*}/gm),$=a(/^data-[\-\w.\u00B7-\uFFFF]/),z=a(/^aria-[\-\w]+$/),P=a(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),R=a(/^(?:\w+script|data):/i),W=a(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),H=a(/^html$/i);var U=Object.freeze({__proto__:null,MUSTACHE_EXPR:j,ERB_EXPR:q,TMPLIT_EXPR:D,DATA_ATTR:$,ARIA_ATTR:z,IS_ALLOWED_URI:P,IS_SCRIPT_OR_DATA:R,ATTR_WHITESPACE:W,DOCTYPE_NAME:H});const Y=function(){return"undefined"==typeof window?null:window},V=function(t,e){if("object"!=typeof t||"function"!=typeof t.createPolicy)return null;let i=null;const r="data-tt-policy-suffix";e&&e.hasAttribute(r)&&(i=e.getAttribute(r));const n="dompurify"+(i?"#"+i:"");try{return t.createPolicy(n,{createHTML:t=>t,createScriptURL:t=>t})}catch(o){return console.warn("TrustedTypes policy "+n+" could not be created."),null}};function G(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Y();const i=t=>G(t);if(i.version="3.0.6",i.removed=[],!e||!e.document||9!==e.document.nodeType)return i.isSupported=!1,i;let{document:r}=e;const n=r,a=n.currentScript,{DocumentFragment:l,HTMLTemplateElement:c,Node:_,Element:v,NodeFilter:j,NamedNodeMap:q=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:D,DOMParser:$,trustedTypes:z}=e,R=v.prototype,W=w(R,"cloneNode"),X=w(R,"nextSibling"),Q=w(R,"childNodes"),J=w(R,"parentNode");if("function"==typeof c){const t=r.createElement("template");t.content&&t.content.ownerDocument&&(r=t.content.ownerDocument)}let K,tt="";const{implementation:et,createNodeIterator:it,createDocumentFragment:rt,getElementsByTagName:nt}=r,{importNode:ot}=n;let at={};i.isSupported="function"==typeof t&&"function"==typeof J&&et&&void 0!==et.createHTMLDocument;const{MUSTACHE_EXPR:st,ERB_EXPR:lt,TMPLIT_EXPR:ct,DATA_ATTR:ht,ARIA_ATTR:ut,IS_SCRIPT_OR_DATA:dt,ATTR_WHITESPACE:ft}=U;let{IS_ALLOWED_URI:pt}=U,gt=null;const mt=k({},[...S,...B,...F,...L,...E]);let yt=null;const xt=k({},[...Z,...N,...O,...I]);let Ct=Object.seal(s(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),bt=null,_t=null,vt=!0,kt=!0,Tt=!1,wt=!0,St=!1,Bt=!1,Ft=!1,At=!1,Lt=!1,Mt=!1,Et=!1,Zt=!0,Nt=!1;const Ot="user-content-";let It=!0,jt=!1,qt={},Dt=null;const $t=k({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let zt=null;const Pt=k({},["audio","video","img","source","image","track"]);let Rt=null;const Wt=k({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Ht="http://www.w3.org/1998/Math/MathML",Ut="http://www.w3.org/2000/svg",Yt="http://www.w3.org/1999/xhtml";let Vt=Yt,Gt=!1,Xt=null;const Qt=k({},[Ht,Ut,Yt],p);let Jt=null;const Kt=["application/xhtml+xml","text/html"],te="text/html";let ee=null,ie=null;const re=r.createElement("form"),ne=function(t){return t instanceof RegExp||t instanceof Function},oe=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!ie||ie!==t){if(t&&"object"==typeof t||(t={}),t=T(t),Jt=Jt=-1===Kt.indexOf(t.PARSER_MEDIA_TYPE)?te:t.PARSER_MEDIA_TYPE,ee="application/xhtml+xml"===Jt?p:f,gt="ALLOWED_TAGS"in t?k({},t.ALLOWED_TAGS,ee):mt,yt="ALLOWED_ATTR"in t?k({},t.ALLOWED_ATTR,ee):xt,Xt="ALLOWED_NAMESPACES"in t?k({},t.ALLOWED_NAMESPACES,p):Qt,Rt="ADD_URI_SAFE_ATTR"in t?k(T(Wt),t.ADD_URI_SAFE_ATTR,ee):Wt,zt="ADD_DATA_URI_TAGS"in t?k(T(Pt),t.ADD_DATA_URI_TAGS,ee):Pt,Dt="FORBID_CONTENTS"in t?k({},t.FORBID_CONTENTS,ee):$t,bt="FORBID_TAGS"in t?k({},t.FORBID_TAGS,ee):{},_t="FORBID_ATTR"in t?k({},t.FORBID_ATTR,ee):{},qt="USE_PROFILES"in t&&t.USE_PROFILES,vt=!1!==t.ALLOW_ARIA_ATTR,kt=!1!==t.ALLOW_DATA_ATTR,Tt=t.ALLOW_UNKNOWN_PROTOCOLS||!1,wt=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,St=t.SAFE_FOR_TEMPLATES||!1,Bt=t.WHOLE_DOCUMENT||!1,Lt=t.RETURN_DOM||!1,Mt=t.RETURN_DOM_FRAGMENT||!1,Et=t.RETURN_TRUSTED_TYPE||!1,At=t.FORCE_BODY||!1,Zt=!1!==t.SANITIZE_DOM,Nt=t.SANITIZE_NAMED_PROPS||!1,It=!1!==t.KEEP_CONTENT,jt=t.IN_PLACE||!1,pt=t.ALLOWED_URI_REGEXP||P,Vt=t.NAMESPACE||Yt,Ct=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&ne(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Ct.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&ne(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Ct.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Ct.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),St&&(kt=!1),Mt&&(Lt=!0),qt&&(gt=k({},[...E]),yt=[],!0===qt.html&&(k(gt,S),k(yt,Z)),!0===qt.svg&&(k(gt,B),k(yt,N),k(yt,I)),!0===qt.svgFilters&&(k(gt,F),k(yt,N),k(yt,I)),!0===qt.mathMl&&(k(gt,L),k(yt,O),k(yt,I))),t.ADD_TAGS&&(gt===mt&&(gt=T(gt)),k(gt,t.ADD_TAGS,ee)),t.ADD_ATTR&&(yt===xt&&(yt=T(yt)),k(yt,t.ADD_ATTR,ee)),t.ADD_URI_SAFE_ATTR&&k(Rt,t.ADD_URI_SAFE_ATTR,ee),t.FORBID_CONTENTS&&(Dt===$t&&(Dt=T(Dt)),k(Dt,t.FORBID_CONTENTS,ee)),It&&(gt["#text"]=!0),Bt&&k(gt,["html","head","body"]),gt.table&&(k(gt,["tbody"]),delete bt.tbody),t.TRUSTED_TYPES_POLICY){if("function"!=typeof t.TRUSTED_TYPES_POLICY.createHTML)throw b('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw b('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');K=t.TRUSTED_TYPES_POLICY,tt=K.createHTML("")}else void 0===K&&(K=V(z,a)),null!==K&&"string"==typeof tt&&(tt=K.createHTML(""));o&&o(t),ie=t}},ae=k({},["mi","mo","mn","ms","mtext"]),se=k({},["foreignobject","desc","title","annotation-xml"]),le=k({},["title","style","font","a","script"]),ce=k({},B);k(ce,F),k(ce,A);const he=k({},L);k(he,M);const ue=function(t){let e=J(t);e&&e.tagName||(e={namespaceURI:Vt,tagName:"template"});const i=f(t.tagName),r=f(e.tagName);return!!Xt[t.namespaceURI]&&(t.namespaceURI===Ut?e.namespaceURI===Yt?"svg"===i:e.namespaceURI===Ht?"svg"===i&&("annotation-xml"===r||ae[r]):Boolean(ce[i]):t.namespaceURI===Ht?e.namespaceURI===Yt?"math"===i:e.namespaceURI===Ut?"math"===i&&se[r]:Boolean(he[i]):t.namespaceURI===Yt?!(e.namespaceURI===Ut&&!se[r])&&!(e.namespaceURI===Ht&&!ae[r])&&!he[i]&&(le[i]||!ce[i]):!("application/xhtml+xml"!==Jt||!Xt[t.namespaceURI]))},de=function(t){d(i.removed,{element:t});try{t.parentNode.removeChild(t)}catch(e){t.remove()}},fe=function(t,e){try{d(i.removed,{attribute:e.getAttributeNode(t),from:e})}catch(r){d(i.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t&&!yt[t])if(Lt||Mt)try{de(e)}catch(r){}else try{e.setAttribute(t,"")}catch(r){}},pe=function(t){let e=null,i=null;if(At)t="<remove></remove>"+t;else{const e=g(t,/^[\r\n\t ]+/);i=e&&e[0]}"application/xhtml+xml"===Jt&&Vt===Yt&&(t='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+t+"</body></html>");const n=K?K.createHTML(t):t;if(Vt===Yt)try{e=(new $).parseFromString(n,Jt)}catch(a){}if(!e||!e.documentElement){e=et.createDocument(Vt,"template",null);try{e.documentElement.innerHTML=Gt?tt:n}catch(a){}}const o=e.body||e.documentElement;return t&&i&&o.insertBefore(r.createTextNode(i),o.childNodes[0]||null),Vt===Yt?nt.call(e,Bt?"html":"body")[0]:Bt?e.documentElement:o},ge=function(t){return it.call(t.ownerDocument||t,t,j.SHOW_ELEMENT|j.SHOW_COMMENT|j.SHOW_TEXT,null)},me=function(t){return t instanceof D&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof q)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore||"function"!=typeof t.hasChildNodes)},ye=function(t){return"function"==typeof _&&t instanceof _},xe=function(t,e,r){at[t]&&h(at[t],(t=>{t.call(i,e,r,ie)}))},Ce=function(t){let e=null;if(xe("beforeSanitizeElements",t,null),me(t))return de(t),!0;const r=ee(t.nodeName);if(xe("uponSanitizeElement",t,{tagName:r,allowedTags:gt}),t.hasChildNodes()&&!ye(t.firstElementChild)&&C(/<[/\w]/g,t.innerHTML)&&C(/<[/\w]/g,t.textContent))return de(t),!0;if(!gt[r]||bt[r]){if(!bt[r]&&_e(r)){if(Ct.tagNameCheck instanceof RegExp&&C(Ct.tagNameCheck,r))return!1;if(Ct.tagNameCheck instanceof Function&&Ct.tagNameCheck(r))return!1}if(It&&!Dt[r]){const e=J(t)||t.parentNode,i=Q(t)||t.childNodes;if(i&&e)for(let r=i.length-1;r>=0;--r)e.insertBefore(W(i[r],!0),X(t))}return de(t),!0}return t instanceof v&&!ue(t)?(de(t),!0):"noscript"!==r&&"noembed"!==r&&"noframes"!==r||!C(/<\/no(script|embed|frames)/i,t.innerHTML)?(St&&3===t.nodeType&&(e=t.textContent,h([st,lt,ct],(t=>{e=m(e,t," ")})),t.textContent!==e&&(d(i.removed,{element:t.cloneNode()}),t.textContent=e)),xe("afterSanitizeElements",t,null),!1):(de(t),!0)},be=function(t,e,i){if(Zt&&("id"===e||"name"===e)&&(i in r||i in re))return!1;if(kt&&!_t[e]&&C(ht,e));else if(vt&&C(ut,e));else if(!yt[e]||_t[e]){if(!(_e(t)&&(Ct.tagNameCheck instanceof RegExp&&C(Ct.tagNameCheck,t)||Ct.tagNameCheck instanceof Function&&Ct.tagNameCheck(t))&&(Ct.attributeNameCheck instanceof RegExp&&C(Ct.attributeNameCheck,e)||Ct.attributeNameCheck instanceof Function&&Ct.attributeNameCheck(e))||"is"===e&&Ct.allowCustomizedBuiltInElements&&(Ct.tagNameCheck instanceof RegExp&&C(Ct.tagNameCheck,i)||Ct.tagNameCheck instanceof Function&&Ct.tagNameCheck(i))))return!1}else if(Rt[e]);else if(C(pt,m(i,ft,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==y(i,"data:")||!zt[t])if(Tt&&!C(dt,m(i,ft,"")));else if(i)return!1;return!0},_e=function(t){return t.indexOf("-")>0},ve=function(t){xe("beforeSanitizeAttributes",t,null);const{attributes:e}=t;if(!e)return;const r={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:yt};let n=e.length;for(;n--;){const a=e[n],{name:s,namespaceURI:l,value:c}=a,d=ee(s);let f="value"===s?c:x(c);if(r.attrName=d,r.attrValue=f,r.keepAttr=!0,r.forceKeepAttr=void 0,xe("uponSanitizeAttribute",t,r),f=r.attrValue,r.forceKeepAttr)continue;if(fe(s,t),!r.keepAttr)continue;if(!wt&&C(/\/>/i,f)){fe(s,t);continue}St&&h([st,lt,ct],(t=>{f=m(f,t," ")}));const p=ee(t.nodeName);if(be(p,d,f)){if(!Nt||"id"!==d&&"name"!==d||(fe(s,t),f=Ot+f),K&&"object"==typeof z&&"function"==typeof z.getAttributeType)if(l);else switch(z.getAttributeType(p,d)){case"TrustedHTML":f=K.createHTML(f);break;case"TrustedScriptURL":f=K.createScriptURL(f)}try{l?t.setAttributeNS(l,s,f):t.setAttribute(s,f),u(i.removed)}catch(o){}}}xe("afterSanitizeAttributes",t,null)},ke=function t(e){let i=null;const r=ge(e);for(xe("beforeSanitizeShadowDOM",e,null);i=r.nextNode();)xe("uponSanitizeShadowNode",i,null),Ce(i)||(i.content instanceof l&&t(i.content),ve(i));xe("afterSanitizeShadowDOM",e,null)};return i.sanitize=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=null,o=null,a=null,s=null;if(Gt=!t,Gt&&(t="\x3c!--\x3e"),"string"!=typeof t&&!ye(t)){if("function"!=typeof t.toString)throw b("toString is not a function");if("string"!=typeof(t=t.toString()))throw b("dirty is not a string, aborting")}if(!i.isSupported)return t;if(Ft||oe(e),i.removed=[],"string"==typeof t&&(jt=!1),jt){if(t.nodeName){const e=ee(t.nodeName);if(!gt[e]||bt[e])throw b("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof _)r=pe("\x3c!----\x3e"),o=r.ownerDocument.importNode(t,!0),1===o.nodeType&&"BODY"===o.nodeName||"HTML"===o.nodeName?r=o:r.appendChild(o);else{if(!Lt&&!St&&!Bt&&-1===t.indexOf("<"))return K&&Et?K.createHTML(t):t;if(r=pe(t),!r)return Lt?null:Et?tt:""}r&&At&&de(r.firstChild);const c=ge(jt?t:r);for(;a=c.nextNode();)Ce(a)||(a.content instanceof l&&ke(a.content),ve(a));if(jt)return t;if(Lt){if(Mt)for(s=rt.call(r.ownerDocument);r.firstChild;)s.appendChild(r.firstChild);else s=r;return(yt.shadowroot||yt.shadowrootmode)&&(s=ot.call(n,s,!0)),s}let u=Bt?r.outerHTML:r.innerHTML;return Bt&>["!doctype"]&&r.ownerDocument&&r.ownerDocument.doctype&&r.ownerDocument.doctype.name&&C(H,r.ownerDocument.doctype.name)&&(u="<!DOCTYPE "+r.ownerDocument.doctype.name+">\n"+u),St&&h([st,lt,ct],(t=>{u=m(u,t," ")})),K&&Et?K.createHTML(u):u},i.setConfig=function(){oe(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Ft=!0},i.clearConfig=function(){ie=null,Ft=!1},i.isValidAttribute=function(t,e,i){ie||oe({});const r=ee(t),n=ee(e);return be(r,n,i)},i.addHook=function(t,e){"function"==typeof e&&(at[t]=at[t]||[],d(at[t],e))},i.removeHook=function(t){if(at[t])return u(at[t])},i.removeHooks=function(t){at[t]&&(at[t]=[])},i.removeAllHooks=function(){at={}},i}return G()}()},87594:(t,e)=>{function i(t){let e,i=[];for(let r of t.split(",").map((t=>t.trim())))if(/^-?\d+$/.test(r))i.push(parseInt(r,10));else if(e=r.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[t,r,n,o]=e;if(r&&o){r=parseInt(r),o=parseInt(o);const t=r<o?1:-1;"-"!==n&&".."!==n&&"\u2025"!==n||(o+=t);for(let e=r;e!==o;e+=t)i.push(e)}}return i}e.default=i,t.exports=i},18464:(t,e,i)=>{"use strict";function r(t){for(var e=[],i=1;i<arguments.length;i++)e[i-1]=arguments[i];var r=Array.from("string"==typeof t?[t]:t);r[r.length-1]=r[r.length-1].replace(/\r?\n([\t ]*)$/,"");var n=r.reduce((function(t,e){var i=e.match(/\n([\t ]+|(?!\s).)/g);return i?t.concat(i.map((function(t){var e,i;return null!==(i=null===(e=t.match(/[\t ]/g))||void 0===e?void 0:e.length)&&void 0!==i?i:0}))):t}),[]);if(n.length){var o=new RegExp("\n[\t ]{"+Math.min.apply(Math,n)+"}","g");r=r.map((function(t){return t.replace(o,"\n")}))}r[0]=r[0].replace(/^\r?\n/,"");var a=r[0];return e.forEach((function(t,e){var i=a.match(/(?:^|\n)( *)$/),n=i?i[1]:"",o=t;"string"==typeof t&&t.includes("\n")&&(o=String(t).split("\n").map((function(t,e){return 0===e?t:""+n+t})).join("\n")),a+=o+r[e+1]})),a}i.d(e,{Z:()=>r})},64218:(t,e,i)=>{"use strict";function r(t,e){let i;if(void 0===e)for(const r of t)null!=r&&(i<r||void 0===i&&r>=r)&&(i=r);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(i<n||void 0===i&&n>=n)&&(i=n)}return i}function n(t,e){let i;if(void 0===e)for(const r of t)null!=r&&(i>r||void 0===i&&r>=r)&&(i=r);else{let r=-1;for(let n of t)null!=(n=e(n,++r,t))&&(i>n||void 0===i&&n>=n)&&(i=n)}return i}function o(t){return t}i.d(e,{Nb1:()=>cs,LLu:()=>x,F5q:()=>y,$0Z:()=>vs,Dts:()=>Ts,WQY:()=>Ss,qpX:()=>Fs,u93:()=>As,tFB:()=>Ms,YY7:()=>Ns,OvA:()=>Is,dCK:()=>qs,zgE:()=>zs,fGX:()=>Rs,$m7:()=>Hs,c_6:()=>ds,fxm:()=>Ys,FdL:()=>el,ak_:()=>il,SxZ:()=>ol,eA_:()=>sl,jsv:()=>cl,iJ:()=>ll,JHv:()=>pr,jvg:()=>gs,Fp7:()=>r,VV$:()=>n,ve8:()=>xs,tiA:()=>kr,BYU:()=>mn,PKp:()=>vr,Xf:()=>Za,K2I:()=>Na,Ys:()=>Oa,td_:()=>Ia,YPS:()=>Yi,rr1:()=>Zn,i$Z:()=>uo,y2j:()=>Pn,WQD:()=>Mn,U8T:()=>Bn,Z_i:()=>An,Ox9:()=>qn,F0B:()=>Jn,LqH:()=>Rn,S1K:()=>Fn,Zyz:()=>jn,Igq:()=>zn,YDX:()=>Dn,EFj:()=>$n});var a=1,s=2,l=3,c=4,h=1e-6;function u(t){return"translate("+t+",0)"}function d(t){return"translate(0,"+t+")"}function f(t){return e=>+t(e)}function p(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),i=>+t(i)+e}function g(){return!this.__axis}function m(t,e){var i=[],r=null,n=null,m=6,y=6,x=3,C="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,b=t===a||t===c?-1:1,_=t===c||t===s?"x":"y",v=t===a||t===l?u:d;function k(u){var d=null==r?e.ticks?e.ticks.apply(e,i):e.domain():r,k=null==n?e.tickFormat?e.tickFormat.apply(e,i):o:n,T=Math.max(m,0)+x,w=e.range(),S=+w[0]+C,B=+w[w.length-1]+C,F=(e.bandwidth?p:f)(e.copy(),C),A=u.selection?u.selection():u,L=A.selectAll(".domain").data([null]),M=A.selectAll(".tick").data(d,e).order(),E=M.exit(),Z=M.enter().append("g").attr("class","tick"),N=M.select("line"),O=M.select("text");L=L.merge(L.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),M=M.merge(Z),N=N.merge(Z.append("line").attr("stroke","currentColor").attr(_+"2",b*m)),O=O.merge(Z.append("text").attr("fill","currentColor").attr(_,b*T).attr("dy",t===a?"0em":t===l?"0.71em":"0.32em")),u!==A&&(L=L.transition(u),M=M.transition(u),N=N.transition(u),O=O.transition(u),E=E.transition(u).attr("opacity",h).attr("transform",(function(t){return isFinite(t=F(t))?v(t+C):this.getAttribute("transform")})),Z.attr("opacity",h).attr("transform",(function(t){var e=this.parentNode.__axis;return v((e&&isFinite(e=e(t))?e:F(t))+C)}))),E.remove(),L.attr("d",t===c||t===s?y?"M"+b*y+","+S+"H"+C+"V"+B+"H"+b*y:"M"+C+","+S+"V"+B:y?"M"+S+","+b*y+"V"+C+"H"+B+"V"+b*y:"M"+S+","+C+"H"+B),M.attr("opacity",1).attr("transform",(function(t){return v(F(t)+C)})),N.attr(_+"2",b*m),O.attr(_,b*T).text(k),A.filter(g).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===s?"start":t===c?"end":"middle"),A.each((function(){this.__axis=F}))}return k.scale=function(t){return arguments.length?(e=t,k):e},k.ticks=function(){return i=Array.from(arguments),k},k.tickArguments=function(t){return arguments.length?(i=null==t?[]:Array.from(t),k):i.slice()},k.tickValues=function(t){return arguments.length?(r=null==t?null:Array.from(t),k):r&&r.slice()},k.tickFormat=function(t){return arguments.length?(n=t,k):n},k.tickSize=function(t){return arguments.length?(m=y=+t,k):m},k.tickSizeInner=function(t){return arguments.length?(m=+t,k):m},k.tickSizeOuter=function(t){return arguments.length?(y=+t,k):y},k.tickPadding=function(t){return arguments.length?(x=+t,k):x},k.offset=function(t){return arguments.length?(C=+t,k):C},k}function y(t){return m(a,t)}function x(t){return m(l,t)}function C(){}function b(t){return null==t?C:function(){return this.querySelector(t)}}function _(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function v(){return[]}function k(t){return null==t?v:function(){return this.querySelectorAll(t)}}function T(t){return function(){return this.matches(t)}}function w(t){return function(e){return e.matches(t)}}var S=Array.prototype.find;function B(){return this.firstElementChild}var F=Array.prototype.filter;function A(){return Array.from(this.children)}function L(t){return new Array(t.length)}function M(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function E(t,e,i,r,n,o){for(var a,s=0,l=e.length,c=o.length;s<c;++s)(a=e[s])?(a.__data__=o[s],r[s]=a):i[s]=new M(t,o[s]);for(;s<l;++s)(a=e[s])&&(n[s]=a)}function Z(t,e,i,r,n,o,a){var s,l,c,h=new Map,u=e.length,d=o.length,f=new Array(u);for(s=0;s<u;++s)(l=e[s])&&(f[s]=c=a.call(l,l.__data__,s,e)+"",h.has(c)?n[s]=l:h.set(c,l));for(s=0;s<d;++s)c=a.call(t,o[s],s,o)+"",(l=h.get(c))?(r[s]=l,l.__data__=o[s],h.delete(c)):i[s]=new M(t,o[s]);for(s=0;s<u;++s)(l=e[s])&&h.get(f[s])===l&&(n[s]=l)}function N(t){return t.__data__}function O(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function I(t,e){return t<e?-1:t>e?1:t>=e?0:NaN}M.prototype={constructor:M,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var j="http://www.w3.org/1999/xhtml";const q={svg:"http://www.w3.org/2000/svg",xhtml:j,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function D(t){var e=t+="",i=e.indexOf(":");return i>=0&&"xmlns"!==(e=t.slice(0,i))&&(t=t.slice(i+1)),q.hasOwnProperty(e)?{space:q[e],local:t}:t}function $(t){return function(){this.removeAttribute(t)}}function z(t){return function(){this.removeAttributeNS(t.space,t.local)}}function P(t,e){return function(){this.setAttribute(t,e)}}function R(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function W(t,e){return function(){var i=e.apply(this,arguments);null==i?this.removeAttribute(t):this.setAttribute(t,i)}}function H(t,e){return function(){var i=e.apply(this,arguments);null==i?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,i)}}function U(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function Y(t){return function(){this.style.removeProperty(t)}}function V(t,e,i){return function(){this.style.setProperty(t,e,i)}}function G(t,e,i){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,i)}}function X(t,e){return t.style.getPropertyValue(e)||U(t).getComputedStyle(t,null).getPropertyValue(e)}function Q(t){return function(){delete this[t]}}function J(t,e){return function(){this[t]=e}}function K(t,e){return function(){var i=e.apply(this,arguments);null==i?delete this[t]:this[t]=i}}function tt(t){return t.trim().split(/^|\s+/)}function et(t){return t.classList||new it(t)}function it(t){this._node=t,this._names=tt(t.getAttribute("class")||"")}function rt(t,e){for(var i=et(t),r=-1,n=e.length;++r<n;)i.add(e[r])}function nt(t,e){for(var i=et(t),r=-1,n=e.length;++r<n;)i.remove(e[r])}function ot(t){return function(){rt(this,t)}}function at(t){return function(){nt(this,t)}}function st(t,e){return function(){(e.apply(this,arguments)?rt:nt)(this,t)}}function lt(){this.textContent=""}function ct(t){return function(){this.textContent=t}}function ht(t){return function(){var e=t.apply(this,arguments);this.textContent=null==e?"":e}}function ut(){this.innerHTML=""}function dt(t){return function(){this.innerHTML=t}}function ft(t){return function(){var e=t.apply(this,arguments);this.innerHTML=null==e?"":e}}function pt(){this.nextSibling&&this.parentNode.appendChild(this)}function gt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function mt(t){return function(){var e=this.ownerDocument,i=this.namespaceURI;return i===j&&e.documentElement.namespaceURI===j?e.createElement(t):e.createElementNS(i,t)}}function yt(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function xt(t){var e=D(t);return(e.local?yt:mt)(e)}function Ct(){return null}function bt(){var t=this.parentNode;t&&t.removeChild(this)}function _t(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function vt(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function kt(t){return function(){var e=this.__on;if(e){for(var i,r=0,n=-1,o=e.length;r<o;++r)i=e[r],t.type&&i.type!==t.type||i.name!==t.name?e[++n]=i:this.removeEventListener(i.type,i.listener,i.options);++n?e.length=n:delete this.__on}}}function Tt(t,e,i){return function(){var r,n=this.__on,o=function(t){return function(e){t.call(this,e,this.__data__)}}(e);if(n)for(var a=0,s=n.length;a<s;++a)if((r=n[a]).type===t.type&&r.name===t.name)return this.removeEventListener(r.type,r.listener,r.options),this.addEventListener(r.type,r.listener=o,r.options=i),void(r.value=e);this.addEventListener(t.type,o,i),r={type:t.type,name:t.name,value:e,listener:o,options:i},n?n.push(r):this.__on=[r]}}function wt(t,e,i){var r=U(t),n=r.CustomEvent;"function"==typeof n?n=new n(e,i):(n=r.document.createEvent("Event"),i?(n.initEvent(e,i.bubbles,i.cancelable),n.detail=i.detail):n.initEvent(e,!1,!1)),t.dispatchEvent(n)}function St(t,e){return function(){return wt(this,t,e)}}function Bt(t,e){return function(){return wt(this,t,e.apply(this,arguments))}}it.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Ft=[null];function At(t,e){this._groups=t,this._parents=e}function Lt(){return new At([[document.documentElement]],Ft)}At.prototype=Lt.prototype={constructor:At,select:function(t){"function"!=typeof t&&(t=b(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a,s=e[n],l=s.length,c=r[n]=new Array(l),h=0;h<l;++h)(o=s[h])&&(a=t.call(o,o.__data__,h,s))&&("__data__"in o&&(a.__data__=o.__data__),c[h]=a);return new At(r,this._parents)},selectAll:function(t){t="function"==typeof t?function(t){return function(){return _(t.apply(this,arguments))}}(t):k(t);for(var e=this._groups,i=e.length,r=[],n=[],o=0;o<i;++o)for(var a,s=e[o],l=s.length,c=0;c<l;++c)(a=s[c])&&(r.push(t.call(a,a.__data__,c,s)),n.push(a));return new At(r,n)},selectChild:function(t){return this.select(null==t?B:function(t){return function(){return S.call(this.children,t)}}("function"==typeof t?t:w(t)))},selectChildren:function(t){return this.selectAll(null==t?A:function(t){return function(){return F.call(this.children,t)}}("function"==typeof t?t:w(t)))},filter:function(t){"function"!=typeof t&&(t=T(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a=e[n],s=a.length,l=r[n]=[],c=0;c<s;++c)(o=a[c])&&t.call(o,o.__data__,c,a)&&l.push(o);return new At(r,this._parents)},data:function(t,e){if(!arguments.length)return Array.from(this,N);var i,r=e?Z:E,n=this._parents,o=this._groups;"function"!=typeof t&&(i=t,t=function(){return i});for(var a=o.length,s=new Array(a),l=new Array(a),c=new Array(a),h=0;h<a;++h){var u=n[h],d=o[h],f=d.length,p=O(t.call(u,u&&u.__data__,h,n)),g=p.length,m=l[h]=new Array(g),y=s[h]=new Array(g);r(u,d,m,y,c[h]=new Array(f),p,e);for(var x,C,b=0,_=0;b<g;++b)if(x=m[b]){for(b>=_&&(_=b+1);!(C=y[_])&&++_<g;);x._next=C||null}}return(s=new At(s,n))._enter=l,s._exit=c,s},enter:function(){return new At(this._enter||this._groups.map(L),this._parents)},exit:function(){return new At(this._exit||this._groups.map(L),this._parents)},join:function(t,e,i){var r=this.enter(),n=this,o=this.exit();return"function"==typeof t?(r=t(r))&&(r=r.selection()):r=r.append(t+""),null!=e&&(n=e(n))&&(n=n.selection()),null==i?o.remove():i(o),r&&n?r.merge(n).order():n},merge:function(t){for(var e=t.selection?t.selection():t,i=this._groups,r=e._groups,n=i.length,o=r.length,a=Math.min(n,o),s=new Array(n),l=0;l<a;++l)for(var c,h=i[l],u=r[l],d=h.length,f=s[l]=new Array(d),p=0;p<d;++p)(c=h[p]||u[p])&&(f[p]=c);for(;l<n;++l)s[l]=i[l];return new At(s,this._parents)},selection:function(){return this},order:function(){for(var t=this._groups,e=-1,i=t.length;++e<i;)for(var r,n=t[e],o=n.length-1,a=n[o];--o>=0;)(r=n[o])&&(a&&4^r.compareDocumentPosition(a)&&a.parentNode.insertBefore(r,a),a=r);return this},sort:function(t){function e(e,i){return e&&i?t(e.__data__,i.__data__):!e-!i}t||(t=I);for(var i=this._groups,r=i.length,n=new Array(r),o=0;o<r;++o){for(var a,s=i[o],l=s.length,c=n[o]=new Array(l),h=0;h<l;++h)(a=s[h])&&(c[h]=a);c.sort(e)}return new At(n,this._parents).order()},call:function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},nodes:function(){return Array.from(this)},node:function(){for(var t=this._groups,e=0,i=t.length;e<i;++e)for(var r=t[e],n=0,o=r.length;n<o;++n){var a=r[n];if(a)return a}return null},size:function(){let t=0;for(const e of this)++t;return t},empty:function(){return!this.node()},each:function(t){for(var e=this._groups,i=0,r=e.length;i<r;++i)for(var n,o=e[i],a=0,s=o.length;a<s;++a)(n=o[a])&&t.call(n,n.__data__,a,o);return this},attr:function(t,e){var i=D(t);if(arguments.length<2){var r=this.node();return i.local?r.getAttributeNS(i.space,i.local):r.getAttribute(i)}return this.each((null==e?i.local?z:$:"function"==typeof e?i.local?H:W:i.local?R:P)(i,e))},style:function(t,e,i){return arguments.length>1?this.each((null==e?Y:"function"==typeof e?G:V)(t,e,null==i?"":i)):X(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?Q:"function"==typeof e?K:J)(t,e)):this.node()[t]},classed:function(t,e){var i=tt(t+"");if(arguments.length<2){for(var r=et(this.node()),n=-1,o=i.length;++n<o;)if(!r.contains(i[n]))return!1;return!0}return this.each(("function"==typeof e?st:e?ot:at)(i,e))},text:function(t){return arguments.length?this.each(null==t?lt:("function"==typeof t?ht:ct)(t)):this.node().textContent},html:function(t){return arguments.length?this.each(null==t?ut:("function"==typeof t?ft:dt)(t)):this.node().innerHTML},raise:function(){return this.each(pt)},lower:function(){return this.each(gt)},append:function(t){var e="function"==typeof t?t:xt(t);return this.select((function(){return this.appendChild(e.apply(this,arguments))}))},insert:function(t,e){var i="function"==typeof t?t:xt(t),r=null==e?Ct:"function"==typeof e?e:b(e);return this.select((function(){return this.insertBefore(i.apply(this,arguments),r.apply(this,arguments)||null)}))},remove:function(){return this.each(bt)},clone:function(t){return this.select(t?vt:_t)},datum:function(t){return arguments.length?this.property("__data__",t):this.node().__data__},on:function(t,e,i){var r,n,o=function(t){return t.trim().split(/^|\s+/).map((function(t){var e="",i=t.indexOf(".");return i>=0&&(e=t.slice(i+1),t=t.slice(0,i)),{type:t,name:e}}))}(t+""),a=o.length;if(!(arguments.length<2)){for(s=e?Tt:kt,r=0;r<a;++r)this.each(s(o[r],e,i));return this}var s=this.node().__on;if(s)for(var l,c=0,h=s.length;c<h;++c)for(r=0,l=s[c];r<a;++r)if((n=o[r]).type===l.type&&n.name===l.name)return l.value},dispatch:function(t,e){return this.each(("function"==typeof e?Bt:St)(t,e))},[Symbol.iterator]:function*(){for(var t=this._groups,e=0,i=t.length;e<i;++e)for(var r,n=t[e],o=0,a=n.length;o<a;++o)(r=n[o])&&(yield r)}};const Mt=Lt;var Et={value:()=>{}};function Zt(){for(var t,e=0,i=arguments.length,r={};e<i;++e){if(!(t=arguments[e]+"")||t in r||/[\s.]/.test(t))throw new Error("illegal type: "+t);r[t]=[]}return new Nt(r)}function Nt(t){this._=t}function Ot(t,e){for(var i,r=0,n=t.length;r<n;++r)if((i=t[r]).name===e)return i.value}function It(t,e,i){for(var r=0,n=t.length;r<n;++r)if(t[r].name===e){t[r]=Et,t=t.slice(0,r).concat(t.slice(r+1));break}return null!=i&&t.push({name:e,value:i}),t}Nt.prototype=Zt.prototype={constructor:Nt,on:function(t,e){var i,r,n=this._,o=(r=n,(t+"").trim().split(/^|\s+/).map((function(t){var e="",i=t.indexOf(".");if(i>=0&&(e=t.slice(i+1),t=t.slice(0,i)),t&&!r.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}}))),a=-1,s=o.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++a<s;)if(i=(t=o[a]).type)n[i]=It(n[i],t.name,e);else if(null==e)for(i in n)n[i]=It(n[i],t.name,null);return this}for(;++a<s;)if((i=(t=o[a]).type)&&(i=Ot(n[i],t.name)))return i},copy:function(){var t={},e=this._;for(var i in e)t[i]=e[i].slice();return new Nt(t)},call:function(t,e){if((i=arguments.length-2)>0)for(var i,r,n=new Array(i),o=0;o<i;++o)n[o]=arguments[o+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(o=0,i=(r=this._[t]).length;o<i;++o)r[o].value.apply(e,n)},apply:function(t,e,i){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var r=this._[t],n=0,o=r.length;n<o;++n)r[n].value.apply(e,i)}};const jt=Zt;var qt,Dt,$t=0,zt=0,Pt=0,Rt=1e3,Wt=0,Ht=0,Ut=0,Yt="object"==typeof performance&&performance.now?performance:Date,Vt="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function Gt(){return Ht||(Vt(Xt),Ht=Yt.now()+Ut)}function Xt(){Ht=0}function Qt(){this._call=this._time=this._next=null}function Jt(t,e,i){var r=new Qt;return r.restart(t,e,i),r}function Kt(){Ht=(Wt=Yt.now())+Ut,$t=zt=0;try{!function(){Gt(),++$t;for(var t,e=qt;e;)(t=Ht-e._time)>=0&&e._call.call(void 0,t),e=e._next;--$t}()}finally{$t=0,function(){var t,e,i=qt,r=1/0;for(;i;)i._call?(r>i._time&&(r=i._time),t=i,i=i._next):(e=i._next,i._next=null,i=t?t._next=e:qt=e);Dt=t,ee(r)}(),Ht=0}}function te(){var t=Yt.now(),e=t-Wt;e>Rt&&(Ut-=e,Wt=t)}function ee(t){$t||(zt&&(zt=clearTimeout(zt)),t-Ht>24?(t<1/0&&(zt=setTimeout(Kt,t-Yt.now()-Ut)),Pt&&(Pt=clearInterval(Pt))):(Pt||(Wt=Yt.now(),Pt=setInterval(te,Rt)),$t=1,Vt(Kt)))}function ie(t,e,i){var r=new Qt;return e=null==e?0:+e,r.restart((i=>{r.stop(),t(i+e)}),e,i),r}Qt.prototype=Jt.prototype={constructor:Qt,restart:function(t,e,i){if("function"!=typeof t)throw new TypeError("callback is not a function");i=(null==i?Gt():+i)+(null==e?0:+e),this._next||Dt===this||(Dt?Dt._next=this:qt=this,Dt=this),this._call=t,this._time=i,ee()},stop:function(){this._call&&(this._call=null,this._time=1/0,ee())}};var re=jt("start","end","cancel","interrupt"),ne=[],oe=0,ae=1,se=2,le=3,ce=4,he=5,ue=6;function de(t,e,i,r,n,o){var a=t.__transition;if(a){if(i in a)return}else t.__transition={};!function(t,e,i){var r,n=t.__transition;function o(t){i.state=ae,i.timer.restart(a,i.delay,i.time),i.delay<=t&&a(t-i.delay)}function a(o){var c,h,u,d;if(i.state!==ae)return l();for(c in n)if((d=n[c]).name===i.name){if(d.state===le)return ie(a);d.state===ce?(d.state=ue,d.timer.stop(),d.on.call("interrupt",t,t.__data__,d.index,d.group),delete n[c]):+c<e&&(d.state=ue,d.timer.stop(),d.on.call("cancel",t,t.__data__,d.index,d.group),delete n[c])}if(ie((function(){i.state===le&&(i.state=ce,i.timer.restart(s,i.delay,i.time),s(o))})),i.state=se,i.on.call("start",t,t.__data__,i.index,i.group),i.state===se){for(i.state=le,r=new Array(u=i.tween.length),c=0,h=-1;c<u;++c)(d=i.tween[c].value.call(t,t.__data__,i.index,i.group))&&(r[++h]=d);r.length=h+1}}function s(e){for(var n=e<i.duration?i.ease.call(null,e/i.duration):(i.timer.restart(l),i.state=he,1),o=-1,a=r.length;++o<a;)r[o].call(t,n);i.state===he&&(i.on.call("end",t,t.__data__,i.index,i.group),l())}function l(){for(var r in i.state=ue,i.timer.stop(),delete n[e],n)return;delete t.__transition}n[e]=i,i.timer=Jt(o,0,i.time)}(t,i,{name:e,index:r,group:n,on:re,tween:ne,time:o.time,delay:o.delay,duration:o.duration,ease:o.ease,timer:null,state:oe})}function fe(t,e){var i=ge(t,e);if(i.state>oe)throw new Error("too late; already scheduled");return i}function pe(t,e){var i=ge(t,e);if(i.state>le)throw new Error("too late; already running");return i}function ge(t,e){var i=t.__transition;if(!i||!(i=i[e]))throw new Error("transition not found");return i}function me(t,e){return t=+t,e=+e,function(i){return t*(1-i)+e*i}}var ye,xe=180/Math.PI,Ce={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function be(t,e,i,r,n,o){var a,s,l;return(a=Math.sqrt(t*t+e*e))&&(t/=a,e/=a),(l=t*i+e*r)&&(i-=t*l,r-=e*l),(s=Math.sqrt(i*i+r*r))&&(i/=s,r/=s,l/=s),t*r<e*i&&(t=-t,e=-e,l=-l,a=-a),{translateX:n,translateY:o,rotate:Math.atan2(e,t)*xe,skewX:Math.atan(l)*xe,scaleX:a,scaleY:s}}function _e(t,e,i,r){function n(t){return t.length?t.pop()+" ":""}return function(o,a){var s=[],l=[];return o=t(o),a=t(a),function(t,r,n,o,a,s){if(t!==n||r!==o){var l=a.push("translate(",null,e,null,i);s.push({i:l-4,x:me(t,n)},{i:l-2,x:me(r,o)})}else(n||o)&&a.push("translate("+n+e+o+i)}(o.translateX,o.translateY,a.translateX,a.translateY,s,l),function(t,e,i,o){t!==e?(t-e>180?e+=360:e-t>180&&(t+=360),o.push({i:i.push(n(i)+"rotate(",null,r)-2,x:me(t,e)})):e&&i.push(n(i)+"rotate("+e+r)}(o.rotate,a.rotate,s,l),function(t,e,i,o){t!==e?o.push({i:i.push(n(i)+"skewX(",null,r)-2,x:me(t,e)}):e&&i.push(n(i)+"skewX("+e+r)}(o.skewX,a.skewX,s,l),function(t,e,i,r,o,a){if(t!==i||e!==r){var s=o.push(n(o)+"scale(",null,",",null,")");a.push({i:s-4,x:me(t,i)},{i:s-2,x:me(e,r)})}else 1===i&&1===r||o.push(n(o)+"scale("+i+","+r+")")}(o.scaleX,o.scaleY,a.scaleX,a.scaleY,s,l),o=a=null,function(t){for(var e,i=-1,r=l.length;++i<r;)s[(e=l[i]).i]=e.x(t);return s.join("")}}}var ve=_e((function(t){const e=new("function"==typeof DOMMatrix?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?Ce:be(e.a,e.b,e.c,e.d,e.e,e.f)}),"px, ","px)","deg)"),ke=_e((function(t){return null==t?Ce:(ye||(ye=document.createElementNS("http://www.w3.org/2000/svg","g")),ye.setAttribute("transform",t),(t=ye.transform.baseVal.consolidate())?be((t=t.matrix).a,t.b,t.c,t.d,t.e,t.f):Ce)}),", ",")",")");function Te(t,e){var i,r;return function(){var n=pe(this,t),o=n.tween;if(o!==i)for(var a=0,s=(r=i=o).length;a<s;++a)if(r[a].name===e){(r=r.slice()).splice(a,1);break}n.tween=r}}function we(t,e,i){var r,n;if("function"!=typeof i)throw new Error;return function(){var o=pe(this,t),a=o.tween;if(a!==r){n=(r=a).slice();for(var s={name:e,value:i},l=0,c=n.length;l<c;++l)if(n[l].name===e){n[l]=s;break}l===c&&n.push(s)}o.tween=n}}function Se(t,e,i){var r=t._id;return t.each((function(){var t=pe(this,r);(t.value||(t.value={}))[e]=i.apply(this,arguments)})),function(t){return ge(t,r).value[e]}}function Be(t,e,i){t.prototype=e.prototype=i,i.constructor=t}function Fe(t,e){var i=Object.create(t.prototype);for(var r in e)i[r]=e[r];return i}function Ae(){}var Le=.7,Me=1/Le,Ee="\\s*([+-]?\\d+)\\s*",Ze="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",Ne="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",Oe=/^#([0-9a-f]{3,8})$/,Ie=new RegExp(`^rgb\\(${Ee},${Ee},${Ee}\\)$`),je=new RegExp(`^rgb\\(${Ne},${Ne},${Ne}\\)$`),qe=new RegExp(`^rgba\\(${Ee},${Ee},${Ee},${Ze}\\)$`),De=new RegExp(`^rgba\\(${Ne},${Ne},${Ne},${Ze}\\)$`),$e=new RegExp(`^hsl\\(${Ze},${Ne},${Ne}\\)$`),ze=new RegExp(`^hsla\\(${Ze},${Ne},${Ne},${Ze}\\)$`),Pe={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};function Re(){return this.rgb().formatHex()}function We(){return this.rgb().formatRgb()}function He(t){var e,i;return t=(t+"").trim().toLowerCase(),(e=Oe.exec(t))?(i=e[1].length,e=parseInt(e[1],16),6===i?Ue(e):3===i?new Xe(e>>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===i?Ye(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===i?Ye(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=Ie.exec(t))?new Xe(e[1],e[2],e[3],1):(e=je.exec(t))?new Xe(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=qe.exec(t))?Ye(e[1],e[2],e[3],e[4]):(e=De.exec(t))?Ye(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=$e.exec(t))?ii(e[1],e[2]/100,e[3]/100,1):(e=ze.exec(t))?ii(e[1],e[2]/100,e[3]/100,e[4]):Pe.hasOwnProperty(t)?Ue(Pe[t]):"transparent"===t?new Xe(NaN,NaN,NaN,0):null}function Ue(t){return new Xe(t>>16&255,t>>8&255,255&t,1)}function Ye(t,e,i,r){return r<=0&&(t=e=i=NaN),new Xe(t,e,i,r)}function Ve(t){return t instanceof Ae||(t=He(t)),t?new Xe((t=t.rgb()).r,t.g,t.b,t.opacity):new Xe}function Ge(t,e,i,r){return 1===arguments.length?Ve(t):new Xe(t,e,i,null==r?1:r)}function Xe(t,e,i,r){this.r=+t,this.g=+e,this.b=+i,this.opacity=+r}function Qe(){return`#${ei(this.r)}${ei(this.g)}${ei(this.b)}`}function Je(){const t=Ke(this.opacity);return`${1===t?"rgb(":"rgba("}${ti(this.r)}, ${ti(this.g)}, ${ti(this.b)}${1===t?")":`, ${t})`}`}function Ke(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function ti(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function ei(t){return((t=ti(t))<16?"0":"")+t.toString(16)}function ii(t,e,i,r){return r<=0?t=e=i=NaN:i<=0||i>=1?t=e=NaN:e<=0&&(t=NaN),new ni(t,e,i,r)}function ri(t){if(t instanceof ni)return new ni(t.h,t.s,t.l,t.opacity);if(t instanceof Ae||(t=He(t)),!t)return new ni;if(t instanceof ni)return t;var e=(t=t.rgb()).r/255,i=t.g/255,r=t.b/255,n=Math.min(e,i,r),o=Math.max(e,i,r),a=NaN,s=o-n,l=(o+n)/2;return s?(a=e===o?(i-r)/s+6*(i<r):i===o?(r-e)/s+2:(e-i)/s+4,s/=l<.5?o+n:2-o-n,a*=60):s=l>0&&l<1?0:a,new ni(a,s,l,t.opacity)}function ni(t,e,i,r){this.h=+t,this.s=+e,this.l=+i,this.opacity=+r}function oi(t){return(t=(t||0)%360)<0?t+360:t}function ai(t){return Math.max(0,Math.min(1,t||0))}function si(t,e,i){return 255*(t<60?e+(i-e)*t/60:t<180?i:t<240?e+(i-e)*(240-t)/60:e)}function li(t,e,i,r,n){var o=t*t,a=o*t;return((1-3*t+3*o-a)*e+(4-6*o+3*a)*i+(1+3*t+3*o-3*a)*r+a*n)/6}Be(Ae,He,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:Re,formatHex:Re,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return ri(this).formatHsl()},formatRgb:We,toString:We}),Be(Xe,Ge,Fe(Ae,{brighter(t){return t=null==t?Me:Math.pow(Me,t),new Xe(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?Le:Math.pow(Le,t),new Xe(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Xe(ti(this.r),ti(this.g),ti(this.b),Ke(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Qe,formatHex:Qe,formatHex8:function(){return`#${ei(this.r)}${ei(this.g)}${ei(this.b)}${ei(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Je,toString:Je})),Be(ni,(function(t,e,i,r){return 1===arguments.length?ri(t):new ni(t,e,i,null==r?1:r)}),Fe(Ae,{brighter(t){return t=null==t?Me:Math.pow(Me,t),new ni(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?Le:Math.pow(Le,t),new ni(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,i=this.l,r=i+(i<.5?i:1-i)*e,n=2*i-r;return new Xe(si(t>=240?t-240:t+120,n,r),si(t,n,r),si(t<120?t+240:t-120,n,r),this.opacity)},clamp(){return new ni(oi(this.h),ai(this.s),ai(this.l),Ke(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Ke(this.opacity);return`${1===t?"hsl(":"hsla("}${oi(this.h)}, ${100*ai(this.s)}%, ${100*ai(this.l)}%${1===t?")":`, ${t})`}`}}));const ci=t=>()=>t;function hi(t,e){return function(i){return t+i*e}}function ui(t){return 1==(t=+t)?di:function(e,i){return i-e?function(t,e,i){return t=Math.pow(t,i),e=Math.pow(e,i)-t,i=1/i,function(r){return Math.pow(t+r*e,i)}}(e,i,t):ci(isNaN(e)?i:e)}}function di(t,e){var i=e-t;return i?hi(t,i):ci(isNaN(t)?e:t)}const fi=function t(e){var i=ui(e);function r(t,e){var r=i((t=Ge(t)).r,(e=Ge(e)).r),n=i(t.g,e.g),o=i(t.b,e.b),a=di(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=n(e),t.b=o(e),t.opacity=a(e),t+""}}return r.gamma=t,r}(1);function pi(t){return function(e){var i,r,n=e.length,o=new Array(n),a=new Array(n),s=new Array(n);for(i=0;i<n;++i)r=Ge(e[i]),o[i]=r.r||0,a[i]=r.g||0,s[i]=r.b||0;return o=t(o),a=t(a),s=t(s),r.opacity=1,function(t){return r.r=o(t),r.g=a(t),r.b=s(t),r+""}}}pi((function(t){var e=t.length-1;return function(i){var r=i<=0?i=0:i>=1?(i=1,e-1):Math.floor(i*e),n=t[r],o=t[r+1],a=r>0?t[r-1]:2*n-o,s=r<e-1?t[r+2]:2*o-n;return li((i-r/e)*e,a,n,o,s)}})),pi((function(t){var e=t.length;return function(i){var r=Math.floor(((i%=1)<0?++i:i)*e),n=t[(r+e-1)%e],o=t[r%e],a=t[(r+1)%e],s=t[(r+2)%e];return li((i-r/e)*e,n,o,a,s)}}));var gi=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,mi=new RegExp(gi.source,"g");function yi(t,e){var i,r,n,o=gi.lastIndex=mi.lastIndex=0,a=-1,s=[],l=[];for(t+="",e+="";(i=gi.exec(t))&&(r=mi.exec(e));)(n=r.index)>o&&(n=e.slice(o,n),s[a]?s[a]+=n:s[++a]=n),(i=i[0])===(r=r[0])?s[a]?s[a]+=r:s[++a]=r:(s[++a]=null,l.push({i:a,x:me(i,r)})),o=mi.lastIndex;return o<e.length&&(n=e.slice(o),s[a]?s[a]+=n:s[++a]=n),s.length<2?l[0]?function(t){return function(e){return t(e)+""}}(l[0].x):function(t){return function(){return t}}(e):(e=l.length,function(t){for(var i,r=0;r<e;++r)s[(i=l[r]).i]=i.x(t);return s.join("")})}function xi(t,e){var i;return("number"==typeof e?me:e instanceof He?fi:(i=He(e))?(e=i,fi):yi)(t,e)}function Ci(t){return function(){this.removeAttribute(t)}}function bi(t){return function(){this.removeAttributeNS(t.space,t.local)}}function _i(t,e,i){var r,n,o=i+"";return function(){var a=this.getAttribute(t);return a===o?null:a===r?n:n=e(r=a,i)}}function vi(t,e,i){var r,n,o=i+"";return function(){var a=this.getAttributeNS(t.space,t.local);return a===o?null:a===r?n:n=e(r=a,i)}}function ki(t,e,i){var r,n,o;return function(){var a,s,l=i(this);if(null!=l)return(a=this.getAttribute(t))===(s=l+"")?null:a===r&&s===n?o:(n=s,o=e(r=a,l));this.removeAttribute(t)}}function Ti(t,e,i){var r,n,o;return function(){var a,s,l=i(this);if(null!=l)return(a=this.getAttributeNS(t.space,t.local))===(s=l+"")?null:a===r&&s===n?o:(n=s,o=e(r=a,l));this.removeAttributeNS(t.space,t.local)}}function wi(t,e){var i,r;function n(){var n=e.apply(this,arguments);return n!==r&&(i=(r=n)&&function(t,e){return function(i){this.setAttributeNS(t.space,t.local,e.call(this,i))}}(t,n)),i}return n._value=e,n}function Si(t,e){var i,r;function n(){var n=e.apply(this,arguments);return n!==r&&(i=(r=n)&&function(t,e){return function(i){this.setAttribute(t,e.call(this,i))}}(t,n)),i}return n._value=e,n}function Bi(t,e){return function(){fe(this,t).delay=+e.apply(this,arguments)}}function Fi(t,e){return e=+e,function(){fe(this,t).delay=e}}function Ai(t,e){return function(){pe(this,t).duration=+e.apply(this,arguments)}}function Li(t,e){return e=+e,function(){pe(this,t).duration=e}}var Mi=Mt.prototype.constructor;function Ei(t){return function(){this.style.removeProperty(t)}}var Zi=0;function Ni(t,e,i,r){this._groups=t,this._parents=e,this._name=i,this._id=r}function Oi(){return++Zi}var Ii=Mt.prototype;Ni.prototype=function(t){return Mt().transition(t)}.prototype={constructor:Ni,select:function(t){var e=this._name,i=this._id;"function"!=typeof t&&(t=b(t));for(var r=this._groups,n=r.length,o=new Array(n),a=0;a<n;++a)for(var s,l,c=r[a],h=c.length,u=o[a]=new Array(h),d=0;d<h;++d)(s=c[d])&&(l=t.call(s,s.__data__,d,c))&&("__data__"in s&&(l.__data__=s.__data__),u[d]=l,de(u[d],e,i,d,u,ge(s,i)));return new Ni(o,this._parents,e,i)},selectAll:function(t){var e=this._name,i=this._id;"function"!=typeof t&&(t=k(t));for(var r=this._groups,n=r.length,o=[],a=[],s=0;s<n;++s)for(var l,c=r[s],h=c.length,u=0;u<h;++u)if(l=c[u]){for(var d,f=t.call(l,l.__data__,u,c),p=ge(l,i),g=0,m=f.length;g<m;++g)(d=f[g])&&de(d,e,i,g,f,p);o.push(f),a.push(l)}return new Ni(o,a,e,i)},selectChild:Ii.selectChild,selectChildren:Ii.selectChildren,filter:function(t){"function"!=typeof t&&(t=T(t));for(var e=this._groups,i=e.length,r=new Array(i),n=0;n<i;++n)for(var o,a=e[n],s=a.length,l=r[n]=[],c=0;c<s;++c)(o=a[c])&&t.call(o,o.__data__,c,a)&&l.push(o);return new Ni(r,this._parents,this._name,this._id)},merge:function(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,i=t._groups,r=e.length,n=i.length,o=Math.min(r,n),a=new Array(r),s=0;s<o;++s)for(var l,c=e[s],h=i[s],u=c.length,d=a[s]=new Array(u),f=0;f<u;++f)(l=c[f]||h[f])&&(d[f]=l);for(;s<r;++s)a[s]=e[s];return new Ni(a,this._parents,this._name,this._id)},selection:function(){return new Mi(this._groups,this._parents)},transition:function(){for(var t=this._name,e=this._id,i=Oi(),r=this._groups,n=r.length,o=0;o<n;++o)for(var a,s=r[o],l=s.length,c=0;c<l;++c)if(a=s[c]){var h=ge(a,e);de(a,t,i,c,s,{time:h.time+h.delay+h.duration,delay:0,duration:h.duration,ease:h.ease})}return new Ni(r,this._parents,t,i)},call:Ii.call,nodes:Ii.nodes,node:Ii.node,size:Ii.size,empty:Ii.empty,each:Ii.each,on:function(t,e){var i=this._id;return arguments.length<2?ge(this.node(),i).on.on(t):this.each(function(t,e,i){var r,n,o=function(t){return(t+"").trim().split(/^|\s+/).every((function(t){var e=t.indexOf(".");return e>=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?fe:pe;return function(){var a=o(this,t),s=a.on;s!==r&&(n=(r=s).copy()).on(e,i),a.on=n}}(i,t,e))},attr:function(t,e){var i=D(t),r="transform"===i?ke:xi;return this.attrTween(t,"function"==typeof e?(i.local?Ti:ki)(i,r,Se(this,"attr."+t,e)):null==e?(i.local?bi:Ci)(i):(i.local?vi:_i)(i,r,e))},attrTween:function(t,e){var i="attr."+t;if(arguments.length<2)return(i=this.tween(i))&&i._value;if(null==e)return this.tween(i,null);if("function"!=typeof e)throw new Error;var r=D(t);return this.tween(i,(r.local?wi:Si)(r,e))},style:function(t,e,i){var r="transform"==(t+="")?ve:xi;return null==e?this.styleTween(t,function(t,e){var i,r,n;return function(){var o=X(this,t),a=(this.style.removeProperty(t),X(this,t));return o===a?null:o===i&&a===r?n:n=e(i=o,r=a)}}(t,r)).on("end.style."+t,Ei(t)):"function"==typeof e?this.styleTween(t,function(t,e,i){var r,n,o;return function(){var a=X(this,t),s=i(this),l=s+"";return null==s&&(this.style.removeProperty(t),l=s=X(this,t)),a===l?null:a===r&&l===n?o:(n=l,o=e(r=a,s))}}(t,r,Se(this,"style."+t,e))).each(function(t,e){var i,r,n,o,a="style."+e,s="end."+a;return function(){var l=pe(this,t),c=l.on,h=null==l.value[a]?o||(o=Ei(e)):void 0;c===i&&n===h||(r=(i=c).copy()).on(s,n=h),l.on=r}}(this._id,t)):this.styleTween(t,function(t,e,i){var r,n,o=i+"";return function(){var a=X(this,t);return a===o?null:a===r?n:n=e(r=a,i)}}(t,r,e),i).on("end.style."+t,null)},styleTween:function(t,e,i){var r="style."+(t+="");if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==e)return this.tween(r,null);if("function"!=typeof e)throw new Error;return this.tween(r,function(t,e,i){var r,n;function o(){var o=e.apply(this,arguments);return o!==n&&(r=(n=o)&&function(t,e,i){return function(r){this.style.setProperty(t,e.call(this,r),i)}}(t,o,i)),r}return o._value=e,o}(t,e,null==i?"":i))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var e=t(this);this.textContent=null==e?"":e}}(Se(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},textTween:function(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(null==t)return this.tween(e,null);if("function"!=typeof t)throw new Error;return this.tween(e,function(t){var e,i;function r(){var r=t.apply(this,arguments);return r!==i&&(e=(i=r)&&function(t){return function(e){this.textContent=t.call(this,e)}}(r)),e}return r._value=t,r}(t))},remove:function(){return this.on("end.remove",function(t){return function(){var e=this.parentNode;for(var i in this.__transition)if(+i!==t)return;e&&e.removeChild(this)}}(this._id))},tween:function(t,e){var i=this._id;if(t+="",arguments.length<2){for(var r,n=ge(this.node(),i).tween,o=0,a=n.length;o<a;++o)if((r=n[o]).name===t)return r.value;return null}return this.each((null==e?Te:we)(i,t,e))},delay:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Bi:Fi)(e,t)):ge(this.node(),e).delay},duration:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Ai:Li)(e,t)):ge(this.node(),e).duration},ease:function(t){var e=this._id;return arguments.length?this.each(function(t,e){if("function"!=typeof e)throw new Error;return function(){pe(this,t).ease=e}}(e,t)):ge(this.node(),e).ease},easeVarying:function(t){if("function"!=typeof t)throw new Error;return this.each(function(t,e){return function(){var i=e.apply(this,arguments);if("function"!=typeof i)throw new Error;pe(this,t).ease=i}}(this._id,t))},end:function(){var t,e,i=this,r=i._id,n=i.size();return new Promise((function(o,a){var s={value:a},l={value:function(){0==--n&&o()}};i.each((function(){var i=pe(this,r),n=i.on;n!==t&&((e=(t=n).copy())._.cancel.push(s),e._.interrupt.push(s),e._.end.push(l)),i.on=e})),0===n&&o()}))},[Symbol.iterator]:Ii[Symbol.iterator]};var ji={time:null,delay:0,duration:250,ease:function(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}};function qi(t,e){for(var i;!(i=t.__transition)||!(i=i[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return i}Mt.prototype.interrupt=function(t){return this.each((function(){!function(t,e){var i,r,n,o=t.__transition,a=!0;if(o){for(n in e=null==e?null:e+"",o)(i=o[n]).name===e?(r=i.state>se&&i.state<he,i.state=ue,i.timer.stop(),i.on.call(r?"interrupt":"cancel",t,t.__data__,i.index,i.group),delete o[n]):a=!1;a&&delete t.__transition}}(this,t)}))},Mt.prototype.transition=function(t){var e,i;t instanceof Ni?(e=t._id,t=t._name):(e=Oi(),(i=ji).time=Gt(),t=null==t?null:t+"");for(var r=this._groups,n=r.length,o=0;o<n;++o)for(var a,s=r[o],l=s.length,c=0;c<l;++c)(a=s[c])&&de(a,t,e,c,s,i||qi(a,e));return new Ni(r,this._parents,t,e)};const{abs:Di,max:$i,min:zi}=Math;function Pi(t){return[+t[0],+t[1]]}function Ri(t){return[Pi(t[0]),Pi(t[1])]}["w","e"].map(Wi),["n","s"].map(Wi),["n","w","e","s","nw","ne","sw","se"].map(Wi);function Wi(t){return{type:t}}function Hi(t){if(!t.ok)throw new Error(t.status+" "+t.statusText);return t.text()}function Ui(t){return(e,i)=>function(t,e){return fetch(t,e).then(Hi)}(e,i).then((e=>(new DOMParser).parseFromString(e,t)))}Ui("application/xml");Ui("text/html");var Yi=Ui("image/svg+xml");const Vi=Math.PI/180,Gi=180/Math.PI,Xi=.96422,Qi=1,Ji=.82521,Ki=4/29,tr=6/29,er=3*tr*tr,ir=tr*tr*tr;function rr(t){if(t instanceof nr)return new nr(t.l,t.a,t.b,t.opacity);if(t instanceof ur)return dr(t);t instanceof Xe||(t=Ve(t));var e,i,r=lr(t.r),n=lr(t.g),o=lr(t.b),a=or((.2225045*r+.7168786*n+.0606169*o)/Qi);return r===n&&n===o?e=i=a:(e=or((.4360747*r+.3850649*n+.1430804*o)/Xi),i=or((.0139322*r+.0971045*n+.7141733*o)/Ji)),new nr(116*a-16,500*(e-a),200*(a-i),t.opacity)}function nr(t,e,i,r){this.l=+t,this.a=+e,this.b=+i,this.opacity=+r}function or(t){return t>ir?Math.pow(t,1/3):t/er+Ki}function ar(t){return t>tr?t*t*t:er*(t-Ki)}function sr(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function lr(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function cr(t){if(t instanceof ur)return new ur(t.h,t.c,t.l,t.opacity);if(t instanceof nr||(t=rr(t)),0===t.a&&0===t.b)return new ur(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*Gi;return new ur(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function hr(t,e,i,r){return 1===arguments.length?cr(t):new ur(t,e,i,null==r?1:r)}function ur(t,e,i,r){this.h=+t,this.c=+e,this.l=+i,this.opacity=+r}function dr(t){if(isNaN(t.h))return new nr(t.l,0,0,t.opacity);var e=t.h*Vi;return new nr(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}function fr(t){return function(e,i){var r=t((e=hr(e)).h,(i=hr(i)).h),n=di(e.c,i.c),o=di(e.l,i.l),a=di(e.opacity,i.opacity);return function(t){return e.h=r(t),e.c=n(t),e.l=o(t),e.opacity=a(t),e+""}}}Be(nr,(function(t,e,i,r){return 1===arguments.length?rr(t):new nr(t,e,i,null==r?1:r)}),Fe(Ae,{brighter(t){return new nr(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker(t){return new nr(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,i=isNaN(this.b)?t:t-this.b/200;return new Xe(sr(3.1338561*(e=Xi*ar(e))-1.6168667*(t=Qi*ar(t))-.4906146*(i=Ji*ar(i))),sr(-.9787684*e+1.9161415*t+.033454*i),sr(.0719453*e-.2289914*t+1.4052427*i),this.opacity)}})),Be(ur,hr,Fe(Ae,{brighter(t){return new ur(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker(t){return new ur(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb(){return dr(this).rgb()}}));const pr=fr((function(t,e){var i=e-t;return i?hi(t,i>180||i<-180?i-360*Math.round(i/360):i):ci(isNaN(t)?e:t)}));fr(di);function gr(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t)}return this}class mr extends Map{constructor(t,e=br){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[i,r]of t)this.set(i,r)}get(t){return super.get(yr(this,t))}has(t){return super.has(yr(this,t))}set(t,e){return super.set(xr(this,t),e)}delete(t){return super.delete(Cr(this,t))}}function yr({_intern:t,_key:e},i){const r=e(i);return t.has(r)?t.get(r):i}function xr({_intern:t,_key:e},i){const r=e(i);return t.has(r)?t.get(r):(t.set(r,i),i)}function Cr({_intern:t,_key:e},i){const r=e(i);return t.has(r)&&(i=t.get(r),t.delete(r)),i}function br(t){return null!==t&&"object"==typeof t?t.valueOf():t}const _r=Symbol("implicit");function vr(){var t=new mr,e=[],i=[],r=_r;function n(n){let o=t.get(n);if(void 0===o){if(r!==_r)return r;t.set(n,o=e.push(n)-1)}return i[o%i.length]}return n.domain=function(i){if(!arguments.length)return e.slice();e=[],t=new mr;for(const r of i)t.has(r)||t.set(r,e.push(r)-1);return n},n.range=function(t){return arguments.length?(i=Array.from(t),n):i.slice()},n.unknown=function(t){return arguments.length?(r=t,n):r},n.copy=function(){return vr(e,i).unknown(r)},gr.apply(n,arguments),n}function kr(){var t,e,i=vr().unknown(void 0),r=i.domain,n=i.range,o=0,a=1,s=!1,l=0,c=0,h=.5;function u(){var i=r().length,u=a<o,d=u?a:o,f=u?o:a;t=(f-d)/Math.max(1,i-l+2*c),s&&(t=Math.floor(t)),d+=(f-d-t*(i-l))*h,e=t*(1-l),s&&(d=Math.round(d),e=Math.round(e));var p=function(t,e,i){t=+t,e=+e,i=(n=arguments.length)<2?(e=t,t=0,1):n<3?1:+i;for(var r=-1,n=0|Math.max(0,Math.ceil((e-t)/i)),o=new Array(n);++r<n;)o[r]=t+r*i;return o}(i).map((function(e){return d+t*e}));return n(u?p.reverse():p)}return delete i.unknown,i.domain=function(t){return arguments.length?(r(t),u()):r()},i.range=function(t){return arguments.length?([o,a]=t,o=+o,a=+a,u()):[o,a]},i.rangeRound=function(t){return[o,a]=t,o=+o,a=+a,s=!0,u()},i.bandwidth=function(){return e},i.step=function(){return t},i.round=function(t){return arguments.length?(s=!!t,u()):s},i.padding=function(t){return arguments.length?(l=Math.min(1,c=+t),u()):l},i.paddingInner=function(t){return arguments.length?(l=Math.min(1,t),u()):l},i.paddingOuter=function(t){return arguments.length?(c=+t,u()):c},i.align=function(t){return arguments.length?(h=Math.max(0,Math.min(1,t)),u()):h},i.copy=function(){return kr(r(),[o,a]).round(s).paddingInner(l).paddingOuter(c).align(h)},gr.apply(u(),arguments)}const Tr=Math.sqrt(50),wr=Math.sqrt(10),Sr=Math.sqrt(2);function Br(t,e,i){const r=(e-t)/Math.max(0,i),n=Math.floor(Math.log10(r)),o=r/Math.pow(10,n),a=o>=Tr?10:o>=wr?5:o>=Sr?2:1;let s,l,c;return n<0?(c=Math.pow(10,-n)/a,s=Math.round(t*c),l=Math.round(e*c),s/c<t&&++s,l/c>e&&--l,c=-c):(c=Math.pow(10,n)*a,s=Math.round(t/c),l=Math.round(e/c),s*c<t&&++s,l*c>e&&--l),l<s&&.5<=i&&i<2?Br(t,e,2*i):[s,l,c]}function Fr(t,e,i){return Br(t=+t,e=+e,i=+i)[2]}function Ar(t,e,i){i=+i;const r=(e=+e)<(t=+t),n=r?Fr(e,t,i):Fr(t,e,i);return(r?-1:1)*(n<0?1/-n:n)}function Lr(t,e){return null==t||null==e?NaN:t<e?-1:t>e?1:t>=e?0:NaN}function Mr(t,e){return null==t||null==e?NaN:e<t?-1:e>t?1:e>=t?0:NaN}function Er(t){let e,i,r;function n(t,r,n=0,o=t.length){if(n<o){if(0!==e(r,r))return o;do{const e=n+o>>>1;i(t[e],r)<0?n=e+1:o=e}while(n<o)}return n}return 2!==t.length?(e=Lr,i=(e,i)=>Lr(t(e),i),r=(e,i)=>t(e)-i):(e=t===Lr||t===Mr?t:Zr,i=t,r=t),{left:n,center:function(t,e,i=0,o=t.length){const a=n(t,e,i,o-1);return a>i&&r(t[a-1],e)>-r(t[a],e)?a-1:a},right:function(t,r,n=0,o=t.length){if(n<o){if(0!==e(r,r))return o;do{const e=n+o>>>1;i(t[e],r)<=0?n=e+1:o=e}while(n<o)}return n}}}function Zr(){return 0}const Nr=Er(Lr),Or=Nr.right,Ir=(Nr.left,Er((function(t){return null===t?NaN:+t})).center,Or);function jr(t,e){var i,r=e?e.length:0,n=t?Math.min(r,t.length):0,o=new Array(n),a=new Array(r);for(i=0;i<n;++i)o[i]=zr(t[i],e[i]);for(;i<r;++i)a[i]=e[i];return function(t){for(i=0;i<n;++i)a[i]=o[i](t);return a}}function qr(t,e){var i=new Date;return t=+t,e=+e,function(r){return i.setTime(t*(1-r)+e*r),i}}function Dr(t,e){var i,r={},n={};for(i in null!==t&&"object"==typeof t||(t={}),null!==e&&"object"==typeof e||(e={}),e)i in t?r[i]=zr(t[i],e[i]):n[i]=e[i];return function(t){for(i in r)n[i]=r[i](t);return n}}function $r(t,e){e||(e=[]);var i,r=t?Math.min(e.length,t.length):0,n=e.slice();return function(o){for(i=0;i<r;++i)n[i]=t[i]*(1-o)+e[i]*o;return n}}function zr(t,e){var i,r,n=typeof e;return null==e||"boolean"===n?ci(e):("number"===n?me:"string"===n?(i=He(e))?(e=i,fi):yi:e instanceof He?fi:e instanceof Date?qr:(r=e,!ArrayBuffer.isView(r)||r instanceof DataView?Array.isArray(e)?jr:"function"!=typeof e.valueOf&&"function"!=typeof e.toString||isNaN(e)?Dr:me:$r))(t,e)}function Pr(t,e){return t=+t,e=+e,function(i){return Math.round(t*(1-i)+e*i)}}function Rr(t){return+t}var Wr=[0,1];function Hr(t){return t}function Ur(t,e){return(e-=t=+t)?function(i){return(i-t)/e}:(i=isNaN(e)?NaN:.5,function(){return i});var i}function Yr(t,e,i){var r=t[0],n=t[1],o=e[0],a=e[1];return n<r?(r=Ur(n,r),o=i(a,o)):(r=Ur(r,n),o=i(o,a)),function(t){return o(r(t))}}function Vr(t,e,i){var r=Math.min(t.length,e.length)-1,n=new Array(r),o=new Array(r),a=-1;for(t[r]<t[0]&&(t=t.slice().reverse(),e=e.slice().reverse());++a<r;)n[a]=Ur(t[a],t[a+1]),o[a]=i(e[a],e[a+1]);return function(e){var i=Ir(t,e,1,r)-1;return o[i](n[i](e))}}function Gr(t,e){return e.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp()).unknown(t.unknown())}function Xr(){var t,e,i,r,n,o,a=Wr,s=Wr,l=zr,c=Hr;function h(){var t,e,i,l=Math.min(a.length,s.length);return c!==Hr&&(t=a[0],e=a[l-1],t>e&&(i=t,t=e,e=i),c=function(i){return Math.max(t,Math.min(e,i))}),r=l>2?Vr:Yr,n=o=null,u}function u(e){return null==e||isNaN(e=+e)?i:(n||(n=r(a.map(t),s,l)))(t(c(e)))}return u.invert=function(i){return c(e((o||(o=r(s,a.map(t),me)))(i)))},u.domain=function(t){return arguments.length?(a=Array.from(t,Rr),h()):a.slice()},u.range=function(t){return arguments.length?(s=Array.from(t),h()):s.slice()},u.rangeRound=function(t){return s=Array.from(t),l=Pr,h()},u.clamp=function(t){return arguments.length?(c=!!t||Hr,h()):c!==Hr},u.interpolate=function(t){return arguments.length?(l=t,h()):l},u.unknown=function(t){return arguments.length?(i=t,u):i},function(i,r){return t=i,e=r,h()}}function Qr(){return Xr()(Hr,Hr)}var Jr,Kr=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function tn(t){if(!(e=Kr.exec(t)))throw new Error("invalid format: "+t);var e;return new en({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function en(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function rn(t,e){if((i=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var i,r=t.slice(0,i);return[r.length>1?r[0]+r.slice(2):r,+t.slice(i+1)]}function nn(t){return(t=rn(Math.abs(t)))?t[1]:NaN}function on(t,e){var i=rn(t,e);if(!i)return t+"";var r=i[0],n=i[1];return n<0?"0."+new Array(-n).join("0")+r:r.length>n+1?r.slice(0,n+1)+"."+r.slice(n+1):r+new Array(n-r.length+2).join("0")}tn.prototype=en.prototype,en.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const an={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>on(100*t,e),r:on,s:function(t,e){var i=rn(t,e);if(!i)return t+"";var r=i[0],n=i[1],o=n-(Jr=3*Math.max(-8,Math.min(8,Math.floor(n/3))))+1,a=r.length;return o===a?r:o>a?r+new Array(o-a+1).join("0"):o>0?r.slice(0,o)+"."+r.slice(o):"0."+new Array(1-o).join("0")+rn(t,Math.max(0,e+o-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function sn(t){return t}var ln,cn,hn,un=Array.prototype.map,dn=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function fn(t){var e,i,r=void 0===t.grouping||void 0===t.thousands?sn:(e=un.call(t.grouping,Number),i=t.thousands+"",function(t,r){for(var n=t.length,o=[],a=0,s=e[0],l=0;n>0&&s>0&&(l+s+1>r&&(s=Math.max(1,r-l)),o.push(t.substring(n-=s,n+s)),!((l+=s+1)>r));)s=e[a=(a+1)%e.length];return o.reverse().join(i)}),n=void 0===t.currency?"":t.currency[0]+"",o=void 0===t.currency?"":t.currency[1]+"",a=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?sn:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(un.call(t.numerals,String)),l=void 0===t.percent?"%":t.percent+"",c=void 0===t.minus?"\u2212":t.minus+"",h=void 0===t.nan?"NaN":t.nan+"";function u(t){var e=(t=tn(t)).fill,i=t.align,u=t.sign,d=t.symbol,f=t.zero,p=t.width,g=t.comma,m=t.precision,y=t.trim,x=t.type;"n"===x?(g=!0,x="g"):an[x]||(void 0===m&&(m=12),y=!0,x="g"),(f||"0"===e&&"="===i)&&(f=!0,e="0",i="=");var C="$"===d?n:"#"===d&&/[boxX]/.test(x)?"0"+x.toLowerCase():"",b="$"===d?o:/[%p]/.test(x)?l:"",_=an[x],v=/[defgprs%]/.test(x);function k(t){var n,o,l,d=C,k=b;if("c"===x)k=_(t)+k,t="";else{var T=(t=+t)<0||1/t<0;if(t=isNaN(t)?h:_(Math.abs(t),m),y&&(t=function(t){t:for(var e,i=t.length,r=1,n=-1;r<i;++r)switch(t[r]){case".":n=e=r;break;case"0":0===n&&(n=r),e=r;break;default:if(!+t[r])break t;n>0&&(n=0)}return n>0?t.slice(0,n)+t.slice(e+1):t}(t)),T&&0==+t&&"+"!==u&&(T=!1),d=(T?"("===u?u:c:"-"===u||"("===u?"":u)+d,k=("s"===x?dn[8+Jr/3]:"")+k+(T&&"("===u?")":""),v)for(n=-1,o=t.length;++n<o;)if(48>(l=t.charCodeAt(n))||l>57){k=(46===l?a+t.slice(n+1):t.slice(n))+k,t=t.slice(0,n);break}}g&&!f&&(t=r(t,1/0));var w=d.length+t.length+k.length,S=w<p?new Array(p-w+1).join(e):"";switch(g&&f&&(t=r(S+t,S.length?p-k.length:1/0),S=""),i){case"<":t=d+t+k+S;break;case"=":t=d+S+t+k;break;case"^":t=S.slice(0,w=S.length>>1)+d+t+k+S.slice(w);break;default:t=S+d+t+k}return s(t)}return m=void 0===m?6:/[gprs]/.test(x)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),k.toString=function(){return t+""},k}return{format:u,formatPrefix:function(t,e){var i=u(((t=tn(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(nn(e)/3))),n=Math.pow(10,-r),o=dn[8+r/3];return function(t){return i(n*t)+o}}}}function pn(t,e,i,r){var n,o=Ar(t,e,i);switch((r=tn(null==r?",f":r)).type){case"s":var a=Math.max(Math.abs(t),Math.abs(e));return null!=r.precision||isNaN(n=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(nn(e)/3)))-nn(Math.abs(t)))}(o,a))||(r.precision=n),hn(r,a);case"":case"e":case"g":case"p":case"r":null!=r.precision||isNaN(n=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,nn(e)-nn(t))+1}(o,Math.max(Math.abs(t),Math.abs(e))))||(r.precision=n-("e"===r.type));break;case"f":case"%":null!=r.precision||isNaN(n=function(t){return Math.max(0,-nn(Math.abs(t)))}(o))||(r.precision=n-2*("%"===r.type))}return cn(r)}function gn(t){var e=t.domain;return t.ticks=function(t){var i=e();return function(t,e,i){if(!((i=+i)>0))return[];if((t=+t)==(e=+e))return[t];const r=e<t,[n,o,a]=r?Br(e,t,i):Br(t,e,i);if(!(o>=n))return[];const s=o-n+1,l=new Array(s);if(r)if(a<0)for(let c=0;c<s;++c)l[c]=(o-c)/-a;else for(let c=0;c<s;++c)l[c]=(o-c)*a;else if(a<0)for(let c=0;c<s;++c)l[c]=(n+c)/-a;else for(let c=0;c<s;++c)l[c]=(n+c)*a;return l}(i[0],i[i.length-1],null==t?10:t)},t.tickFormat=function(t,i){var r=e();return pn(r[0],r[r.length-1],null==t?10:t,i)},t.nice=function(i){null==i&&(i=10);var r,n,o=e(),a=0,s=o.length-1,l=o[a],c=o[s],h=10;for(c<l&&(n=l,l=c,c=n,n=a,a=s,s=n);h-- >0;){if((n=Fr(l,c,i))===r)return o[a]=l,o[s]=c,e(o);if(n>0)l=Math.floor(l/n)*n,c=Math.ceil(c/n)*n;else{if(!(n<0))break;l=Math.ceil(l*n)/n,c=Math.floor(c*n)/n}r=n}return t},t}function mn(){var t=Qr();return t.copy=function(){return Gr(t,mn())},gr.apply(t,arguments),gn(t)}ln=fn({thousands:",",grouping:[3],currency:["$",""]}),cn=ln.format,hn=ln.formatPrefix;const yn=1e3,xn=6e4,Cn=36e5,bn=864e5,_n=6048e5,vn=2592e6,kn=31536e6,Tn=new Date,wn=new Date;function Sn(t,e,i,r){function n(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return n.floor=e=>(t(e=new Date(+e)),e),n.ceil=i=>(t(i=new Date(i-1)),e(i,1),t(i),i),n.round=t=>{const e=n(t),i=n.ceil(t);return t-e<i-t?e:i},n.offset=(t,i)=>(e(t=new Date(+t),null==i?1:Math.floor(i)),t),n.range=(i,r,o)=>{const a=[];if(i=n.ceil(i),o=null==o?1:Math.floor(o),!(i<r&&o>0))return a;let s;do{a.push(s=new Date(+i)),e(i,o),t(i)}while(s<i&&i<r);return a},n.filter=i=>Sn((e=>{if(e>=e)for(;t(e),!i(e);)e.setTime(e-1)}),((t,r)=>{if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!i(t););else for(;--r>=0;)for(;e(t,1),!i(t););})),i&&(n.count=(e,r)=>(Tn.setTime(+e),wn.setTime(+r),t(Tn),t(wn),Math.floor(i(Tn,wn))),n.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?n.filter(r?e=>r(e)%t==0:e=>n.count(0,e)%t==0):n:null)),n}const Bn=Sn((()=>{}),((t,e)=>{t.setTime(+t+e)}),((t,e)=>e-t));Bn.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?Sn((e=>{e.setTime(Math.floor(e/t)*t)}),((e,i)=>{e.setTime(+e+i*t)}),((e,i)=>(i-e)/t)):Bn:null);Bn.range;const Fn=Sn((t=>{t.setTime(t-t.getMilliseconds())}),((t,e)=>{t.setTime(+t+e*yn)}),((t,e)=>(e-t)/yn),(t=>t.getUTCSeconds())),An=(Fn.range,Sn((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*yn)}),((t,e)=>{t.setTime(+t+e*xn)}),((t,e)=>(e-t)/xn),(t=>t.getMinutes()))),Ln=(An.range,Sn((t=>{t.setUTCSeconds(0,0)}),((t,e)=>{t.setTime(+t+e*xn)}),((t,e)=>(e-t)/xn),(t=>t.getUTCMinutes()))),Mn=(Ln.range,Sn((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*yn-t.getMinutes()*xn)}),((t,e)=>{t.setTime(+t+e*Cn)}),((t,e)=>(e-t)/Cn),(t=>t.getHours()))),En=(Mn.range,Sn((t=>{t.setUTCMinutes(0,0,0)}),((t,e)=>{t.setTime(+t+e*Cn)}),((t,e)=>(e-t)/Cn),(t=>t.getUTCHours()))),Zn=(En.range,Sn((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*xn)/bn),(t=>t.getDate()-1))),Nn=(Zn.range,Sn((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/bn),(t=>t.getUTCDate()-1))),On=(Nn.range,Sn((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/bn),(t=>Math.floor(t/bn))));On.range;function In(t){return Sn((e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),((t,e)=>{t.setDate(t.getDate()+7*e)}),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*xn)/_n))}const jn=In(0),qn=In(1),Dn=In(2),$n=In(3),zn=In(4),Pn=In(5),Rn=In(6);jn.range,qn.range,Dn.range,$n.range,zn.range,Pn.range,Rn.range;function Wn(t){return Sn((e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)}),((t,e)=>(e-t)/_n))}const Hn=Wn(0),Un=Wn(1),Yn=Wn(2),Vn=Wn(3),Gn=Wn(4),Xn=Wn(5),Qn=Wn(6),Jn=(Hn.range,Un.range,Yn.range,Vn.range,Gn.range,Xn.range,Qn.range,Sn((t=>{t.setDate(1),t.setHours(0,0,0,0)}),((t,e)=>{t.setMonth(t.getMonth()+e)}),((t,e)=>e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())),(t=>t.getMonth()))),Kn=(Jn.range,Sn((t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)}),((t,e)=>e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear())),(t=>t.getUTCMonth()))),to=(Kn.range,Sn((t=>{t.setMonth(0,1),t.setHours(0,0,0,0)}),((t,e)=>{t.setFullYear(t.getFullYear()+e)}),((t,e)=>e.getFullYear()-t.getFullYear()),(t=>t.getFullYear())));to.every=t=>isFinite(t=Math.floor(t))&&t>0?Sn((e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),((e,i)=>{e.setFullYear(e.getFullYear()+i*t)})):null;to.range;const eo=Sn((t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)}),((t,e)=>e.getUTCFullYear()-t.getUTCFullYear()),(t=>t.getUTCFullYear()));eo.every=t=>isFinite(t=Math.floor(t))&&t>0?Sn((e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),((e,i)=>{e.setUTCFullYear(e.getUTCFullYear()+i*t)})):null;eo.range;function io(t,e,i,r,n,o){const a=[[Fn,1,yn],[Fn,5,5e3],[Fn,15,15e3],[Fn,30,3e4],[o,1,xn],[o,5,3e5],[o,15,9e5],[o,30,18e5],[n,1,Cn],[n,3,108e5],[n,6,216e5],[n,12,432e5],[r,1,bn],[r,2,1728e5],[i,1,_n],[e,1,vn],[e,3,7776e6],[t,1,kn]];function s(e,i,r){const n=Math.abs(i-e)/r,o=Er((([,,t])=>t)).right(a,n);if(o===a.length)return t.every(Ar(e/kn,i/kn,r));if(0===o)return Bn.every(Math.max(Ar(e,i,r),1));const[s,l]=a[n/a[o-1][2]<a[o][2]/n?o-1:o];return s.every(l)}return[function(t,e,i){const r=e<t;r&&([t,e]=[e,t]);const n=i&&"function"==typeof i.range?i:s(t,e,i),o=n?n.range(t,+e+1):[];return r?o.reverse():o},s]}const[ro,no]=io(eo,Kn,Hn,On,En,Ln),[oo,ao]=io(to,Jn,jn,Zn,Mn,An);function so(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function lo(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function co(t,e,i){return{y:t,m:e,d:i,H:0,M:0,S:0,L:0}}var ho,uo,fo={"-":"",_:" ",0:"0"},po=/^\s*\d+/,go=/^%/,mo=/[\\^$*+?|[\]().{}]/g;function yo(t,e,i){var r=t<0?"-":"",n=(r?-t:t)+"",o=n.length;return r+(o<i?new Array(i-o+1).join(e)+n:n)}function xo(t){return t.replace(mo,"\\$&")}function Co(t){return new RegExp("^(?:"+t.map(xo).join("|")+")","i")}function bo(t){return new Map(t.map(((t,e)=>[t.toLowerCase(),e])))}function _o(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.w=+r[0],i+r[0].length):-1}function vo(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.u=+r[0],i+r[0].length):-1}function ko(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.U=+r[0],i+r[0].length):-1}function To(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.V=+r[0],i+r[0].length):-1}function wo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.W=+r[0],i+r[0].length):-1}function So(t,e,i){var r=po.exec(e.slice(i,i+4));return r?(t.y=+r[0],i+r[0].length):-1}function Bo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),i+r[0].length):-1}function Fo(t,e,i){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(i,i+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),i+r[0].length):-1}function Ao(t,e,i){var r=po.exec(e.slice(i,i+1));return r?(t.q=3*r[0]-3,i+r[0].length):-1}function Lo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.m=r[0]-1,i+r[0].length):-1}function Mo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.d=+r[0],i+r[0].length):-1}function Eo(t,e,i){var r=po.exec(e.slice(i,i+3));return r?(t.m=0,t.d=+r[0],i+r[0].length):-1}function Zo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.H=+r[0],i+r[0].length):-1}function No(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.M=+r[0],i+r[0].length):-1}function Oo(t,e,i){var r=po.exec(e.slice(i,i+2));return r?(t.S=+r[0],i+r[0].length):-1}function Io(t,e,i){var r=po.exec(e.slice(i,i+3));return r?(t.L=+r[0],i+r[0].length):-1}function jo(t,e,i){var r=po.exec(e.slice(i,i+6));return r?(t.L=Math.floor(r[0]/1e3),i+r[0].length):-1}function qo(t,e,i){var r=go.exec(e.slice(i,i+1));return r?i+r[0].length:-1}function Do(t,e,i){var r=po.exec(e.slice(i));return r?(t.Q=+r[0],i+r[0].length):-1}function $o(t,e,i){var r=po.exec(e.slice(i));return r?(t.s=+r[0],i+r[0].length):-1}function zo(t,e){return yo(t.getDate(),e,2)}function Po(t,e){return yo(t.getHours(),e,2)}function Ro(t,e){return yo(t.getHours()%12||12,e,2)}function Wo(t,e){return yo(1+Zn.count(to(t),t),e,3)}function Ho(t,e){return yo(t.getMilliseconds(),e,3)}function Uo(t,e){return Ho(t,e)+"000"}function Yo(t,e){return yo(t.getMonth()+1,e,2)}function Vo(t,e){return yo(t.getMinutes(),e,2)}function Go(t,e){return yo(t.getSeconds(),e,2)}function Xo(t){var e=t.getDay();return 0===e?7:e}function Qo(t,e){return yo(jn.count(to(t)-1,t),e,2)}function Jo(t){var e=t.getDay();return e>=4||0===e?zn(t):zn.ceil(t)}function Ko(t,e){return t=Jo(t),yo(zn.count(to(t),t)+(4===to(t).getDay()),e,2)}function ta(t){return t.getDay()}function ea(t,e){return yo(qn.count(to(t)-1,t),e,2)}function ia(t,e){return yo(t.getFullYear()%100,e,2)}function ra(t,e){return yo((t=Jo(t)).getFullYear()%100,e,2)}function na(t,e){return yo(t.getFullYear()%1e4,e,4)}function oa(t,e){var i=t.getDay();return yo((t=i>=4||0===i?zn(t):zn.ceil(t)).getFullYear()%1e4,e,4)}function aa(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+yo(e/60|0,"0",2)+yo(e%60,"0",2)}function sa(t,e){return yo(t.getUTCDate(),e,2)}function la(t,e){return yo(t.getUTCHours(),e,2)}function ca(t,e){return yo(t.getUTCHours()%12||12,e,2)}function ha(t,e){return yo(1+Nn.count(eo(t),t),e,3)}function ua(t,e){return yo(t.getUTCMilliseconds(),e,3)}function da(t,e){return ua(t,e)+"000"}function fa(t,e){return yo(t.getUTCMonth()+1,e,2)}function pa(t,e){return yo(t.getUTCMinutes(),e,2)}function ga(t,e){return yo(t.getUTCSeconds(),e,2)}function ma(t){var e=t.getUTCDay();return 0===e?7:e}function ya(t,e){return yo(Hn.count(eo(t)-1,t),e,2)}function xa(t){var e=t.getUTCDay();return e>=4||0===e?Gn(t):Gn.ceil(t)}function Ca(t,e){return t=xa(t),yo(Gn.count(eo(t),t)+(4===eo(t).getUTCDay()),e,2)}function ba(t){return t.getUTCDay()}function _a(t,e){return yo(Un.count(eo(t)-1,t),e,2)}function va(t,e){return yo(t.getUTCFullYear()%100,e,2)}function ka(t,e){return yo((t=xa(t)).getUTCFullYear()%100,e,2)}function Ta(t,e){return yo(t.getUTCFullYear()%1e4,e,4)}function wa(t,e){var i=t.getUTCDay();return yo((t=i>=4||0===i?Gn(t):Gn.ceil(t)).getUTCFullYear()%1e4,e,4)}function Sa(){return"+0000"}function Ba(){return"%"}function Fa(t){return+t}function Aa(t){return Math.floor(+t/1e3)}function La(t){return new Date(t)}function Ma(t){return t instanceof Date?+t:+new Date(+t)}function Ea(t,e,i,r,n,o,a,s,l,c){var h=Qr(),u=h.invert,d=h.domain,f=c(".%L"),p=c(":%S"),g=c("%I:%M"),m=c("%I %p"),y=c("%a %d"),x=c("%b %d"),C=c("%B"),b=c("%Y");function _(t){return(l(t)<t?f:s(t)<t?p:a(t)<t?g:o(t)<t?m:r(t)<t?n(t)<t?y:x:i(t)<t?C:b)(t)}return h.invert=function(t){return new Date(u(t))},h.domain=function(t){return arguments.length?d(Array.from(t,Ma)):d().map(La)},h.ticks=function(e){var i=d();return t(i[0],i[i.length-1],null==e?10:e)},h.tickFormat=function(t,e){return null==e?_:c(e)},h.nice=function(t){var i=d();return t&&"function"==typeof t.range||(t=e(i[0],i[i.length-1],null==t?10:t)),t?d(function(t,e){var i,r=0,n=(t=t.slice()).length-1,o=t[r],a=t[n];return a<o&&(i=r,r=n,n=i,i=o,o=a,a=i),t[r]=e.floor(o),t[n]=e.ceil(a),t}(i,t)):h},h.copy=function(){return Gr(h,Ea(t,e,i,r,n,o,a,s,l,c))},h}function Za(){return gr.apply(Ea(oo,ao,to,Jn,jn,Zn,Mn,An,Fn,uo).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}!function(t){ho=function(t){var e=t.dateTime,i=t.date,r=t.time,n=t.periods,o=t.days,a=t.shortDays,s=t.months,l=t.shortMonths,c=Co(n),h=bo(n),u=Co(o),d=bo(o),f=Co(a),p=bo(a),g=Co(s),m=bo(s),y=Co(l),x=bo(l),C={a:function(t){return a[t.getDay()]},A:function(t){return o[t.getDay()]},b:function(t){return l[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:zo,e:zo,f:Uo,g:ra,G:oa,H:Po,I:Ro,j:Wo,L:Ho,m:Yo,M:Vo,p:function(t){return n[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Fa,s:Aa,S:Go,u:Xo,U:Qo,V:Ko,w:ta,W:ea,x:null,X:null,y:ia,Y:na,Z:aa,"%":Ba},b={a:function(t){return a[t.getUTCDay()]},A:function(t){return o[t.getUTCDay()]},b:function(t){return l[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:sa,e:sa,f:da,g:ka,G:wa,H:la,I:ca,j:ha,L:ua,m:fa,M:pa,p:function(t){return n[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Fa,s:Aa,S:ga,u:ma,U:ya,V:Ca,w:ba,W:_a,x:null,X:null,y:va,Y:Ta,Z:Sa,"%":Ba},_={a:function(t,e,i){var r=f.exec(e.slice(i));return r?(t.w=p.get(r[0].toLowerCase()),i+r[0].length):-1},A:function(t,e,i){var r=u.exec(e.slice(i));return r?(t.w=d.get(r[0].toLowerCase()),i+r[0].length):-1},b:function(t,e,i){var r=y.exec(e.slice(i));return r?(t.m=x.get(r[0].toLowerCase()),i+r[0].length):-1},B:function(t,e,i){var r=g.exec(e.slice(i));return r?(t.m=m.get(r[0].toLowerCase()),i+r[0].length):-1},c:function(t,i,r){return T(t,e,i,r)},d:Mo,e:Mo,f:jo,g:Bo,G:So,H:Zo,I:Zo,j:Eo,L:Io,m:Lo,M:No,p:function(t,e,i){var r=c.exec(e.slice(i));return r?(t.p=h.get(r[0].toLowerCase()),i+r[0].length):-1},q:Ao,Q:Do,s:$o,S:Oo,u:vo,U:ko,V:To,w:_o,W:wo,x:function(t,e,r){return T(t,i,e,r)},X:function(t,e,i){return T(t,r,e,i)},y:Bo,Y:So,Z:Fo,"%":qo};function v(t,e){return function(i){var r,n,o,a=[],s=-1,l=0,c=t.length;for(i instanceof Date||(i=new Date(+i));++s<c;)37===t.charCodeAt(s)&&(a.push(t.slice(l,s)),null!=(n=fo[r=t.charAt(++s)])?r=t.charAt(++s):n="e"===r?" ":"0",(o=e[r])&&(r=o(i,n)),a.push(r),l=s+1);return a.push(t.slice(l,s)),a.join("")}}function k(t,e){return function(i){var r,n,o=co(1900,void 0,1);if(T(o,t,i+="",0)!=i.length)return null;if("Q"in o)return new Date(o.Q);if("s"in o)return new Date(1e3*o.s+("L"in o?o.L:0));if(e&&!("Z"in o)&&(o.Z=0),"p"in o&&(o.H=o.H%12+12*o.p),void 0===o.m&&(o.m="q"in o?o.q:0),"V"in o){if(o.V<1||o.V>53)return null;"w"in o||(o.w=1),"Z"in o?(n=(r=lo(co(o.y,0,1))).getUTCDay(),r=n>4||0===n?Un.ceil(r):Un(r),r=Nn.offset(r,7*(o.V-1)),o.y=r.getUTCFullYear(),o.m=r.getUTCMonth(),o.d=r.getUTCDate()+(o.w+6)%7):(n=(r=so(co(o.y,0,1))).getDay(),r=n>4||0===n?qn.ceil(r):qn(r),r=Zn.offset(r,7*(o.V-1)),o.y=r.getFullYear(),o.m=r.getMonth(),o.d=r.getDate()+(o.w+6)%7)}else("W"in o||"U"in o)&&("w"in o||(o.w="u"in o?o.u%7:"W"in o?1:0),n="Z"in o?lo(co(o.y,0,1)).getUTCDay():so(co(o.y,0,1)).getDay(),o.m=0,o.d="W"in o?(o.w+6)%7+7*o.W-(n+5)%7:o.w+7*o.U-(n+6)%7);return"Z"in o?(o.H+=o.Z/100|0,o.M+=o.Z%100,lo(o)):so(o)}}function T(t,e,i,r){for(var n,o,a=0,s=e.length,l=i.length;a<s;){if(r>=l)return-1;if(37===(n=e.charCodeAt(a++))){if(n=e.charAt(a++),!(o=_[n in fo?e.charAt(a++):n])||(r=o(t,i,r))<0)return-1}else if(n!=i.charCodeAt(r++))return-1}return r}return C.x=v(i,C),C.X=v(r,C),C.c=v(e,C),b.x=v(i,b),b.X=v(r,b),b.c=v(e,b),{format:function(t){var e=v(t+="",C);return e.toString=function(){return t},e},parse:function(t){var e=k(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=v(t+="",b);return e.toString=function(){return t},e},utcParse:function(t){var e=k(t+="",!0);return e.toString=function(){return t},e}}}(t),uo=ho.format,ho.parse,ho.utcFormat,ho.utcParse}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});const Na=function(t){for(var e=t.length/6|0,i=new Array(e),r=0;r<e;)i[r]="#"+t.slice(6*r,6*++r);return i}("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");function Oa(t){return"string"==typeof t?new At([[document.querySelector(t)]],[document.documentElement]):new At([[t]],Ft)}function Ia(t){return"string"==typeof t?new At([document.querySelectorAll(t)],[document.documentElement]):new At([_(t)],Ft)}function ja(t){return function(){return t}}const qa=Math.abs,Da=Math.atan2,$a=Math.cos,za=Math.max,Pa=Math.min,Ra=Math.sin,Wa=Math.sqrt,Ha=1e-12,Ua=Math.PI,Ya=Ua/2,Va=2*Ua;function Ga(t){return t>=1?Ya:t<=-1?-Ya:Math.asin(t)}const Xa=Math.PI,Qa=2*Xa,Ja=1e-6,Ka=Qa-Ja;function ts(t){this._+=t[0];for(let e=1,i=t.length;e<i;++e)this._+=arguments[e]+t[e]}class es{constructor(t){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=null==t?ts:function(t){let e=Math.floor(t);if(!(e>=0))throw new Error(`invalid digits: ${t}`);if(e>15)return ts;const i=10**e;return function(t){this._+=t[0];for(let e=1,r=t.length;e<r;++e)this._+=Math.round(arguments[e]*i)/i+t[e]}}(t)}moveTo(t,e){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}`}closePath(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(t,e){this._append`L${this._x1=+t},${this._y1=+e}`}quadraticCurveTo(t,e,i,r){this._append`Q${+t},${+e},${this._x1=+i},${this._y1=+r}`}bezierCurveTo(t,e,i,r,n,o){this._append`C${+t},${+e},${+i},${+r},${this._x1=+n},${this._y1=+o}`}arcTo(t,e,i,r,n){if(t=+t,e=+e,i=+i,r=+r,(n=+n)<0)throw new Error(`negative radius: ${n}`);let o=this._x1,a=this._y1,s=i-t,l=r-e,c=o-t,h=a-e,u=c*c+h*h;if(null===this._x1)this._append`M${this._x1=t},${this._y1=e}`;else if(u>Ja)if(Math.abs(h*s-l*c)>Ja&&n){let d=i-o,f=r-a,p=s*s+l*l,g=d*d+f*f,m=Math.sqrt(p),y=Math.sqrt(u),x=n*Math.tan((Xa-Math.acos((p+u-g)/(2*m*y)))/2),C=x/y,b=x/m;Math.abs(C-1)>Ja&&this._append`L${t+C*c},${e+C*h}`,this._append`A${n},${n},0,0,${+(h*d>c*f)},${this._x1=t+b*s},${this._y1=e+b*l}`}else this._append`L${this._x1=t},${this._y1=e}`;else;}arc(t,e,i,r,n,o){if(t=+t,e=+e,o=!!o,(i=+i)<0)throw new Error(`negative radius: ${i}`);let a=i*Math.cos(r),s=i*Math.sin(r),l=t+a,c=e+s,h=1^o,u=o?r-n:n-r;null===this._x1?this._append`M${l},${c}`:(Math.abs(this._x1-l)>Ja||Math.abs(this._y1-c)>Ja)&&this._append`L${l},${c}`,i&&(u<0&&(u=u%Qa+Qa),u>Ka?this._append`A${i},${i},0,1,${h},${t-a},${e-s}A${i},${i},0,1,${h},${this._x1=l},${this._y1=c}`:u>Ja&&this._append`A${i},${i},0,${+(u>=Xa)},${h},${this._x1=t+i*Math.cos(n)},${this._y1=e+i*Math.sin(n)}`)}rect(t,e,i,r){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${i=+i}v${+r}h${-i}Z`}toString(){return this._}}function is(t){let e=3;return t.digits=function(i){if(!arguments.length)return e;if(null==i)e=null;else{const t=Math.floor(i);if(!(t>=0))throw new RangeError(`invalid digits: ${i}`);e=t}return t},()=>new es(e)}function rs(t){return t.innerRadius}function ns(t){return t.outerRadius}function os(t){return t.startAngle}function as(t){return t.endAngle}function ss(t){return t&&t.padAngle}function ls(t,e,i,r,n,o,a){var s=t-i,l=e-r,c=(a?o:-o)/Wa(s*s+l*l),h=c*l,u=-c*s,d=t+h,f=e+u,p=i+h,g=r+u,m=(d+p)/2,y=(f+g)/2,x=p-d,C=g-f,b=x*x+C*C,_=n-o,v=d*g-p*f,k=(C<0?-1:1)*Wa(za(0,_*_*b-v*v)),T=(v*C-x*k)/b,w=(-v*x-C*k)/b,S=(v*C+x*k)/b,B=(-v*x+C*k)/b,F=T-m,A=w-y,L=S-m,M=B-y;return F*F+A*A>L*L+M*M&&(T=S,w=B),{cx:T,cy:w,x01:-h,y01:-u,x11:T*(n/_-1),y11:w*(n/_-1)}}function cs(){var t=rs,e=ns,i=ja(0),r=null,n=os,o=as,a=ss,s=null,l=is(c);function c(){var c,h,u,d=+t.apply(this,arguments),f=+e.apply(this,arguments),p=n.apply(this,arguments)-Ya,g=o.apply(this,arguments)-Ya,m=qa(g-p),y=g>p;if(s||(s=c=l()),f<d&&(h=f,f=d,d=h),f>Ha)if(m>Va-Ha)s.moveTo(f*$a(p),f*Ra(p)),s.arc(0,0,f,p,g,!y),d>Ha&&(s.moveTo(d*$a(g),d*Ra(g)),s.arc(0,0,d,g,p,y));else{var x,C,b=p,_=g,v=p,k=g,T=m,w=m,S=a.apply(this,arguments)/2,B=S>Ha&&(r?+r.apply(this,arguments):Wa(d*d+f*f)),F=Pa(qa(f-d)/2,+i.apply(this,arguments)),A=F,L=F;if(B>Ha){var M=Ga(B/d*Ra(S)),E=Ga(B/f*Ra(S));(T-=2*M)>Ha?(v+=M*=y?1:-1,k-=M):(T=0,v=k=(p+g)/2),(w-=2*E)>Ha?(b+=E*=y?1:-1,_-=E):(w=0,b=_=(p+g)/2)}var Z=f*$a(b),N=f*Ra(b),O=d*$a(k),I=d*Ra(k);if(F>Ha){var j,q=f*$a(_),D=f*Ra(_),$=d*$a(v),z=d*Ra(v);if(m<Ua)if(j=function(t,e,i,r,n,o,a,s){var l=i-t,c=r-e,h=a-n,u=s-o,d=u*l-h*c;if(!(d*d<Ha))return[t+(d=(h*(e-o)-u*(t-n))/d)*l,e+d*c]}(Z,N,$,z,q,D,O,I)){var P=Z-j[0],R=N-j[1],W=q-j[0],H=D-j[1],U=1/Ra(((u=(P*W+R*H)/(Wa(P*P+R*R)*Wa(W*W+H*H)))>1?0:u<-1?Ua:Math.acos(u))/2),Y=Wa(j[0]*j[0]+j[1]*j[1]);A=Pa(F,(d-Y)/(U-1)),L=Pa(F,(f-Y)/(U+1))}else A=L=0}w>Ha?L>Ha?(x=ls($,z,Z,N,f,L,y),C=ls(q,D,O,I,f,L,y),s.moveTo(x.cx+x.x01,x.cy+x.y01),L<F?s.arc(x.cx,x.cy,L,Da(x.y01,x.x01),Da(C.y01,C.x01),!y):(s.arc(x.cx,x.cy,L,Da(x.y01,x.x01),Da(x.y11,x.x11),!y),s.arc(0,0,f,Da(x.cy+x.y11,x.cx+x.x11),Da(C.cy+C.y11,C.cx+C.x11),!y),s.arc(C.cx,C.cy,L,Da(C.y11,C.x11),Da(C.y01,C.x01),!y))):(s.moveTo(Z,N),s.arc(0,0,f,b,_,!y)):s.moveTo(Z,N),d>Ha&&T>Ha?A>Ha?(x=ls(O,I,q,D,d,-A,y),C=ls(Z,N,$,z,d,-A,y),s.lineTo(x.cx+x.x01,x.cy+x.y01),A<F?s.arc(x.cx,x.cy,A,Da(x.y01,x.x01),Da(C.y01,C.x01),!y):(s.arc(x.cx,x.cy,A,Da(x.y01,x.x01),Da(x.y11,x.x11),!y),s.arc(0,0,d,Da(x.cy+x.y11,x.cx+x.x11),Da(C.cy+C.y11,C.cx+C.x11),y),s.arc(C.cx,C.cy,A,Da(C.y11,C.x11),Da(C.y01,C.x01),!y))):s.arc(0,0,d,k,v,y):s.lineTo(O,I)}else s.moveTo(0,0);if(s.closePath(),c)return s=null,c+""||null}return c.centroid=function(){var i=(+t.apply(this,arguments)+ +e.apply(this,arguments))/2,r=(+n.apply(this,arguments)+ +o.apply(this,arguments))/2-Ua/2;return[$a(r)*i,Ra(r)*i]},c.innerRadius=function(e){return arguments.length?(t="function"==typeof e?e:ja(+e),c):t},c.outerRadius=function(t){return arguments.length?(e="function"==typeof t?t:ja(+t),c):e},c.cornerRadius=function(t){return arguments.length?(i="function"==typeof t?t:ja(+t),c):i},c.padRadius=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:ja(+t),c):r},c.startAngle=function(t){return arguments.length?(n="function"==typeof t?t:ja(+t),c):n},c.endAngle=function(t){return arguments.length?(o="function"==typeof t?t:ja(+t),c):o},c.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:ja(+t),c):a},c.context=function(t){return arguments.length?(s=null==t?null:t,c):s},c}es.prototype;Array.prototype.slice;function hs(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function us(t){this._context=t}function ds(t){return new us(t)}function fs(t){return t[0]}function ps(t){return t[1]}function gs(t,e){var i=ja(!0),r=null,n=ds,o=null,a=is(s);function s(s){var l,c,h,u=(s=hs(s)).length,d=!1;for(null==r&&(o=n(h=a())),l=0;l<=u;++l)!(l<u&&i(c=s[l],l,s))===d&&((d=!d)?o.lineStart():o.lineEnd()),d&&o.point(+t(c,l,s),+e(c,l,s));if(h)return o=null,h+""||null}return t="function"==typeof t?t:void 0===t?fs:ja(t),e="function"==typeof e?e:void 0===e?ps:ja(e),s.x=function(e){return arguments.length?(t="function"==typeof e?e:ja(+e),s):t},s.y=function(t){return arguments.length?(e="function"==typeof t?t:ja(+t),s):e},s.defined=function(t){return arguments.length?(i="function"==typeof t?t:ja(!!t),s):i},s.curve=function(t){return arguments.length?(n=t,null!=r&&(o=n(r)),s):n},s.context=function(t){return arguments.length?(null==t?r=o=null:o=n(r=t),s):r},s}function ms(t,e){return e<t?-1:e>t?1:e>=t?0:NaN}function ys(t){return t}function xs(){var t=ys,e=ms,i=null,r=ja(0),n=ja(Va),o=ja(0);function a(a){var s,l,c,h,u,d=(a=hs(a)).length,f=0,p=new Array(d),g=new Array(d),m=+r.apply(this,arguments),y=Math.min(Va,Math.max(-Va,n.apply(this,arguments)-m)),x=Math.min(Math.abs(y)/d,o.apply(this,arguments)),C=x*(y<0?-1:1);for(s=0;s<d;++s)(u=g[p[s]=s]=+t(a[s],s,a))>0&&(f+=u);for(null!=e?p.sort((function(t,i){return e(g[t],g[i])})):null!=i&&p.sort((function(t,e){return i(a[t],a[e])})),s=0,c=f?(y-d*C)/f:0;s<d;++s,m=h)l=p[s],h=m+((u=g[l])>0?u*c:0)+C,g[l]={data:a[l],index:s,value:u,startAngle:m,endAngle:h,padAngle:x};return g}return a.value=function(e){return arguments.length?(t="function"==typeof e?e:ja(+e),a):t},a.sortValues=function(t){return arguments.length?(e=t,i=null,a):e},a.sort=function(t){return arguments.length?(i=t,e=null,a):i},a.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:ja(+t),a):r},a.endAngle=function(t){return arguments.length?(n="function"==typeof t?t:ja(+t),a):n},a.padAngle=function(t){return arguments.length?(o="function"==typeof t?t:ja(+t),a):o},a}function Cs(){}function bs(t,e,i){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+i)/6)}function _s(t){this._context=t}function vs(t){return new _s(t)}function ks(t){this._context=t}function Ts(t){return new ks(t)}function ws(t){this._context=t}function Ss(t){return new ws(t)}us.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}},_s.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:bs(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},ks.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},ws.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var i=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(i,r):this._context.moveTo(i,r);break;case 3:this._point=4;default:bs(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};class Bs{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e)}this._x0=t,this._y0=e}}function Fs(t){return new Bs(t,!0)}function As(t){return new Bs(t,!1)}function Ls(t,e){this._basis=new _s(t),this._beta=e}Ls.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,i=t.length-1;if(i>0)for(var r,n=t[0],o=e[0],a=t[i]-n,s=e[i]-o,l=-1;++l<=i;)r=l/i,this._basis.point(this._beta*t[l]+(1-this._beta)*(n+r*a),this._beta*e[l]+(1-this._beta)*(o+r*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const Ms=function t(e){function i(t){return 1===e?new _s(t):new Ls(t,e)}return i.beta=function(e){return t(+e)},i}(.85);function Es(t,e,i){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-i),t._x2,t._y2)}function Zs(t,e){this._context=t,this._k=(1-e)/6}Zs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Es(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Ns=function t(e){function i(t){return new Zs(t,e)}return i.tension=function(e){return t(+e)},i}(0);function Os(t,e){this._context=t,this._k=(1-e)/6}Os.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Is=function t(e){function i(t){return new Os(t,e)}return i.tension=function(e){return t(+e)},i}(0);function js(t,e){this._context=t,this._k=(1-e)/6}js.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Es(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const qs=function t(e){function i(t){return new js(t,e)}return i.tension=function(e){return t(+e)},i}(0);function Ds(t,e,i){var r=t._x1,n=t._y1,o=t._x2,a=t._y2;if(t._l01_a>Ha){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,l=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/l,n=(n*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/l}if(t._l23_a>Ha){var c=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,h=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*c+t._x1*t._l23_2a-e*t._l12_2a)/h,a=(a*c+t._y1*t._l23_2a-i*t._l12_2a)/h}t._context.bezierCurveTo(r,n,o,a,t._x2,t._y2)}function $s(t,e){this._context=t,this._alpha=e}$s.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Ds(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const zs=function t(e){function i(t){return e?new $s(t,e):new Zs(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Ps(t,e){this._context=t,this._alpha=e}Ps.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Ds(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Rs=function t(e){function i(t){return e?new Ps(t,e):new Os(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Ws(t,e){this._context=t,this._alpha=e}Ws.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var i=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ds(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Hs=function t(e){function i(t){return e?new Ws(t,e):new js(t,0)}return i.alpha=function(e){return t(+e)},i}(.5);function Us(t){this._context=t}function Ys(t){return new Us(t)}function Vs(t){return t<0?-1:1}function Gs(t,e,i){var r=t._x1-t._x0,n=e-t._x1,o=(t._y1-t._y0)/(r||n<0&&-0),a=(i-t._y1)/(n||r<0&&-0),s=(o*n+a*r)/(r+n);return(Vs(o)+Vs(a))*Math.min(Math.abs(o),Math.abs(a),.5*Math.abs(s))||0}function Xs(t,e){var i=t._x1-t._x0;return i?(3*(t._y1-t._y0)/i-e)/2:e}function Qs(t,e,i){var r=t._x0,n=t._y0,o=t._x1,a=t._y1,s=(o-r)/3;t._context.bezierCurveTo(r+s,n+s*e,o-s,a-s*i,o,a)}function Js(t){this._context=t}function Ks(t){this._context=new tl(t)}function tl(t){this._context=t}function el(t){return new Js(t)}function il(t){return new Ks(t)}function rl(t){this._context=t}function nl(t){var e,i,r=t.length-1,n=new Array(r),o=new Array(r),a=new Array(r);for(n[0]=0,o[0]=2,a[0]=t[0]+2*t[1],e=1;e<r-1;++e)n[e]=1,o[e]=4,a[e]=4*t[e]+2*t[e+1];for(n[r-1]=2,o[r-1]=7,a[r-1]=8*t[r-1]+t[r],e=1;e<r;++e)i=n[e]/o[e-1],o[e]-=i,a[e]-=i*a[e-1];for(n[r-1]=a[r-1]/o[r-1],e=r-2;e>=0;--e)n[e]=(a[e]-n[e+1])/o[e];for(o[r-1]=(t[r]+n[r-1])/2,e=0;e<r-1;++e)o[e]=2*t[e+1]-n[e+1];return[n,o]}function ol(t){return new rl(t)}function al(t,e){this._context=t,this._t=e}function sl(t){return new al(t,.5)}function ll(t){return new al(t,0)}function cl(t){return new al(t,1)}function hl(t,e,i){this.k=t,this.x=e,this.y=i}Us.prototype={areaStart:Cs,areaEnd:Cs,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}},Js.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Qs(this,this._t0,Xs(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var i=NaN;if(e=+e,(t=+t)!==this._x1||e!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Qs(this,Xs(this,i=Gs(this,t,e)),i);break;default:Qs(this,this._t0,i=Gs(this,t,e))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=i}}},(Ks.prototype=Object.create(Js.prototype)).point=function(t,e){Js.prototype.point.call(this,e,t)},tl.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,i,r,n,o){this._context.bezierCurveTo(e,t,r,i,o,n)}},rl.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,i=t.length;if(i)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),2===i)this._context.lineTo(t[1],e[1]);else for(var r=nl(t),n=nl(e),o=0,a=1;a<i;++o,++a)this._context.bezierCurveTo(r[0][o],n[0][o],r[1][o],n[1][o],t[a],e[a]);(this._line||0!==this._line&&1===i)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,e){this._x.push(+t),this._y.push(+e)}},al.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0<this._t&&this._t<1&&2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var i=this._x*(1-this._t)+t*this._t;this._context.lineTo(i,this._y),this._context.lineTo(i,e)}}this._x=t,this._y=e}},hl.prototype={constructor:hl,scale:function(t){return 1===t?this:new hl(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new hl(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};new hl(1,0,0);hl.prototype},21883:(t,e,i)=>{"use strict";i.d(e,{Z:()=>a});var r=i(61691),n=i(82142);const o=class{constructor(){this.type=n.w.ALL}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=n.w.ALL}is(t){return this.type===t}};const a=new class{constructor(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new o}set(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=n.w.ALL,this}_ensureHSL(){const t=this.data,{h:e,s:i,l:n}=t;void 0===e&&(t.h=r.Z.channel.rgb2hsl(t,"h")),void 0===i&&(t.s=r.Z.channel.rgb2hsl(t,"s")),void 0===n&&(t.l=r.Z.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r:e,g:i,b:n}=t;void 0===e&&(t.r=r.Z.channel.hsl2rgb(t,"r")),void 0===i&&(t.g=r.Z.channel.hsl2rgb(t,"g")),void 0===n&&(t.b=r.Z.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,e=t.r;return this.type.is(n.w.HSL)||void 0===e?(this._ensureHSL(),r.Z.channel.hsl2rgb(t,"r")):e}get g(){const t=this.data,e=t.g;return this.type.is(n.w.HSL)||void 0===e?(this._ensureHSL(),r.Z.channel.hsl2rgb(t,"g")):e}get b(){const t=this.data,e=t.b;return this.type.is(n.w.HSL)||void 0===e?(this._ensureHSL(),r.Z.channel.hsl2rgb(t,"b")):e}get h(){const t=this.data,e=t.h;return this.type.is(n.w.RGB)||void 0===e?(this._ensureRGB(),r.Z.channel.rgb2hsl(t,"h")):e}get s(){const t=this.data,e=t.s;return this.type.is(n.w.RGB)||void 0===e?(this._ensureRGB(),r.Z.channel.rgb2hsl(t,"s")):e}get l(){const t=this.data,e=t.l;return this.type.is(n.w.RGB)||void 0===e?(this._ensureRGB(),r.Z.channel.rgb2hsl(t,"l")):e}get a(){return this.data.a}set r(t){this.type.set(n.w.RGB),this.changed=!0,this.data.r=t}set g(t){this.type.set(n.w.RGB),this.changed=!0,this.data.g=t}set b(t){this.type.set(n.w.RGB),this.changed=!0,this.data.b=t}set h(t){this.type.set(n.w.HSL),this.changed=!0,this.data.h=t}set s(t){this.type.set(n.w.HSL),this.changed=!0,this.data.s=t}set l(t){this.type.set(n.w.HSL),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}({r:0,g:0,b:0,a:0},"transparent")},71610:(t,e,i)=>{"use strict";i.d(e,{Z:()=>g});var r=i(21883),n=i(82142);const o={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:t=>{if(35!==t.charCodeAt(0))return;const e=t.match(o.re);if(!e)return;const i=e[1],n=parseInt(i,16),a=i.length,s=a%4==0,l=a>4,c=l?1:17,h=l?8:4,u=s?0:-1,d=l?255:15;return r.Z.set({r:(n>>h*(u+3)&d)*c,g:(n>>h*(u+2)&d)*c,b:(n>>h*(u+1)&d)*c,a:s?(n&d)*c/255:1},t)},stringify:t=>{const{r:e,g:i,b:r,a:o}=t;return o<1?`#${n.Q[Math.round(e)]}${n.Q[Math.round(i)]}${n.Q[Math.round(r)]}${n.Q[Math.round(255*o)]}`:`#${n.Q[Math.round(e)]}${n.Q[Math.round(i)]}${n.Q[Math.round(r)]}`}},a=o;var s=i(61691);const l={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:t=>{const e=t.match(l.hueRe);if(e){const[,t,i]=e;switch(i){case"grad":return s.Z.channel.clamp.h(.9*parseFloat(t));case"rad":return s.Z.channel.clamp.h(180*parseFloat(t)/Math.PI);case"turn":return s.Z.channel.clamp.h(360*parseFloat(t))}}return s.Z.channel.clamp.h(parseFloat(t))},parse:t=>{const e=t.charCodeAt(0);if(104!==e&&72!==e)return;const i=t.match(l.re);if(!i)return;const[,n,o,a,c,h]=i;return r.Z.set({h:l._hue2deg(n),s:s.Z.channel.clamp.s(parseFloat(o)),l:s.Z.channel.clamp.l(parseFloat(a)),a:c?s.Z.channel.clamp.a(h?parseFloat(c)/100:parseFloat(c)):1},t)},stringify:t=>{const{h:e,s:i,l:r,a:n}=t;return n<1?`hsla(${s.Z.lang.round(e)}, ${s.Z.lang.round(i)}%, ${s.Z.lang.round(r)}%, ${n})`:`hsl(${s.Z.lang.round(e)}, ${s.Z.lang.round(i)}%, ${s.Z.lang.round(r)}%)`}},c=l,h={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:t=>{t=t.toLowerCase();const e=h.colors[t];if(e)return a.parse(e)},stringify:t=>{const e=a.stringify(t);for(const i in h.colors)if(h.colors[i]===e)return i}},u=h,d={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:t=>{const e=t.charCodeAt(0);if(114!==e&&82!==e)return;const i=t.match(d.re);if(!i)return;const[,n,o,a,l,c,h,u,f]=i;return r.Z.set({r:s.Z.channel.clamp.r(o?2.55*parseFloat(n):parseFloat(n)),g:s.Z.channel.clamp.g(l?2.55*parseFloat(a):parseFloat(a)),b:s.Z.channel.clamp.b(h?2.55*parseFloat(c):parseFloat(c)),a:u?s.Z.channel.clamp.a(f?parseFloat(u)/100:parseFloat(u)):1},t)},stringify:t=>{const{r:e,g:i,b:r,a:n}=t;return n<1?`rgba(${s.Z.lang.round(e)}, ${s.Z.lang.round(i)}, ${s.Z.lang.round(r)}, ${s.Z.lang.round(n)})`:`rgb(${s.Z.lang.round(e)}, ${s.Z.lang.round(i)}, ${s.Z.lang.round(r)})`}},f=d,p={format:{keyword:h,hex:a,rgb:d,rgba:d,hsl:l,hsla:l},parse:t=>{if("string"!=typeof t)return t;const e=a.parse(t)||f.parse(t)||c.parse(t)||u.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},stringify:t=>!t.changed&&t.color?t.color:t.type.is(n.w.HSL)||void 0===t.data.r?c.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?f.stringify(t):a.stringify(t)},g=p},82142:(t,e,i)=>{"use strict";i.d(e,{Q:()=>n,w:()=>o});var r=i(61691);const n={};for(let a=0;a<=255;a++)n[a]=r.Z.unit.dec2hex(a);const o={ALL:0,RGB:1,HSL:2}},26174:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(61691),n=i(71610);const o=(t,e,i)=>{const o=n.Z.parse(t),a=o[e],s=r.Z.channel.clamp[e](a+i);return a!==s&&(o[e]=s),n.Z.stringify(o)}},49807:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(61691),n=i(71610);const o=(t,e)=>{const i=n.Z.parse(t);for(const n in e)i[n]=r.Z.channel.clamp[n](e[n]);return n.Z.stringify(i)}},7201:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=i(26174);const n=(t,e)=>(0,r.Z)(t,"l",-e)},91619:(t,e,i)=>{"use strict";i.d(e,{Z:()=>s});var r=i(61691),n=i(71610);const o=t=>{const{r:e,g:i,b:o}=n.Z.parse(t),a=.2126*r.Z.channel.toLinear(e)+.7152*r.Z.channel.toLinear(i)+.0722*r.Z.channel.toLinear(o);return r.Z.lang.round(a)},a=t=>o(t)>=.5,s=t=>!a(t)},12281:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=i(26174);const n=(t,e)=>(0,r.Z)(t,"l",e)},51117:(t,e,i)=>{"use strict";i.d(e,{Z:()=>s});var r=i(61691),n=i(21883),o=i(71610),a=i(49807);const s=(t,e,i=0,s=1)=>{if("number"!=typeof t)return(0,a.Z)(t,{a:e});const l=n.Z.set({r:r.Z.channel.clamp.r(t),g:r.Z.channel.clamp.g(e),b:r.Z.channel.clamp.b(i),a:r.Z.channel.clamp.a(s)});return o.Z.stringify(l)}},61691:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});const r={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:t=>t>=255?255:t<0?0:t,g:t=>t>=255?255:t<0?0:t,b:t=>t>=255?255:t<0?0:t,h:t=>t%360,s:t=>t>=100?100:t<0?0:t,l:t=>t>=100?100:t<0?0:t,a:t=>t>=1?1:t<0?0:t},toLinear:t=>{const e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:(t,e,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t),hsl2rgb:({h:t,s:e,l:i},n)=>{if(!e)return 2.55*i;t/=360,e/=100;const o=(i/=100)<.5?i*(1+e):i+e-i*e,a=2*i-o;switch(n){case"r":return 255*r.hue2rgb(a,o,t+1/3);case"g":return 255*r.hue2rgb(a,o,t);case"b":return 255*r.hue2rgb(a,o,t-1/3)}},rgb2hsl:({r:t,g:e,b:i},r)=>{t/=255,e/=255,i/=255;const n=Math.max(t,e,i),o=Math.min(t,e,i),a=(n+o)/2;if("l"===r)return 100*a;if(n===o)return 0;const s=n-o;if("s"===r)return 100*(a>.5?s/(2-n-o):s/(n+o));switch(n){case t:return 60*((e-i)/s+(e<i?6:0));case e:return 60*((i-t)/s+2);case i:return 60*((t-e)/s+4);default:return-1}}},n={channel:r,lang:{clamp:(t,e,i)=>e>i?Math.min(e,Math.max(i,t)):Math.min(i,Math.max(e,t)),round:t=>Math.round(1e10*t)/1e10},unit:{dec2hex:t=>{const e=Math.round(t).toString(16);return e.length>1?e:`0${e}`}}}},67308:(t,e,i)=>{"use strict";i.d(e,{Z:()=>d});const r=function(){this.__data__=[],this.size=0};var n=i(79651);const o=function(t,e){for(var i=t.length;i--;)if((0,n.Z)(t[i][0],e))return i;return-1};var a=Array.prototype.splice;const s=function(t){var e=this.__data__,i=o(e,t);return!(i<0)&&(i==e.length-1?e.pop():a.call(e,i,1),--this.size,!0)};const l=function(t){var e=this.__data__,i=o(e,t);return i<0?void 0:e[i][1]};const c=function(t){return o(this.__data__,t)>-1};const h=function(t,e){var i=this.__data__,r=o(i,t);return r<0?(++this.size,i.push([t,e])):i[r][1]=e,this};function u(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}u.prototype.clear=r,u.prototype.delete=s,u.prototype.get=l,u.prototype.has=c,u.prototype.set=h;const d=u},86183:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(62508),n=i(66092);const o=(0,r.Z)(n.Z,"Map")},37834:(t,e,i)=>{"use strict";i.d(e,{Z:()=>k});const r=(0,i(62508).Z)(Object,"create");const n=function(){this.__data__=r?r(null):{},this.size=0};const o=function(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e};var a=Object.prototype.hasOwnProperty;const s=function(t){var e=this.__data__;if(r){var i=e[t];return"__lodash_hash_undefined__"===i?void 0:i}return a.call(e,t)?e[t]:void 0};var l=Object.prototype.hasOwnProperty;const c=function(t){var e=this.__data__;return r?void 0!==e[t]:l.call(e,t)};const h=function(t,e){var i=this.__data__;return this.size+=this.has(t)?0:1,i[t]=r&&void 0===e?"__lodash_hash_undefined__":e,this};function u(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}u.prototype.clear=n,u.prototype.delete=o,u.prototype.get=s,u.prototype.has=c,u.prototype.set=h;const d=u;var f=i(67308),p=i(86183);const g=function(){this.size=0,this.__data__={hash:new d,map:new(p.Z||f.Z),string:new d}};const m=function(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t};const y=function(t,e){var i=t.__data__;return m(e)?i["string"==typeof e?"string":"hash"]:i.map};const x=function(t){var e=y(this,t).delete(t);return this.size-=e?1:0,e};const C=function(t){return y(this,t).get(t)};const b=function(t){return y(this,t).has(t)};const _=function(t,e){var i=y(this,t),r=i.size;return i.set(t,e),this.size+=i.size==r?0:1,this};function v(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e<i;){var r=t[e];this.set(r[0],r[1])}}v.prototype.clear=g,v.prototype.delete=x,v.prototype.get=C,v.prototype.has=b,v.prototype.set=_;const k=v},93203:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(62508),n=i(66092);const o=(0,r.Z)(n.Z,"Set")},31667:(t,e,i)=>{"use strict";i.d(e,{Z:()=>d});var r=i(67308);const n=function(){this.__data__=new r.Z,this.size=0};const o=function(t){var e=this.__data__,i=e.delete(t);return this.size=e.size,i};const a=function(t){return this.__data__.get(t)};const s=function(t){return this.__data__.has(t)};var l=i(86183),c=i(37834);const h=function(t,e){var i=this.__data__;if(i instanceof r.Z){var n=i.__data__;if(!l.Z||n.length<199)return n.push([t,e]),this.size=++i.size,this;i=this.__data__=new c.Z(n)}return i.set(t,e),this.size=i.size,this};function u(t){var e=this.__data__=new r.Z(t);this.size=e.size}u.prototype.clear=n,u.prototype.delete=o,u.prototype.get=a,u.prototype.has=s,u.prototype.set=h;const d=u},17685:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=i(66092).Z.Symbol},84073:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=i(66092).Z.Uint8Array},87668:(t,e,i)=>{"use strict";i.d(e,{Z:()=>h});const r=function(t,e){for(var i=-1,r=Array(t);++i<t;)r[i]=e(i);return r};var n=i(29169),o=i(27771),a=i(77008),s=i(56009),l=i(18843),c=Object.prototype.hasOwnProperty;const h=function(t,e){var i=(0,o.Z)(t),h=!i&&(0,n.Z)(t),u=!i&&!h&&(0,a.Z)(t),d=!i&&!h&&!u&&(0,l.Z)(t),f=i||h||u||d,p=f?r(t.length,String):[],g=p.length;for(var m in t)!e&&!c.call(t,m)||f&&("length"==m||u&&("offset"==m||"parent"==m)||d&&("buffer"==m||"byteLength"==m||"byteOffset"==m)||(0,s.Z)(m,g))||p.push(m);return p}},72954:(t,e,i)=>{"use strict";i.d(e,{Z:()=>a});var r=i(74752),n=i(79651),o=Object.prototype.hasOwnProperty;const a=function(t,e,i){var a=t[e];o.call(t,e)&&(0,n.Z)(a,i)&&(void 0!==i||e in t)||(0,r.Z)(t,e,i)}},74752:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=i(77904);const n=function(t,e,i){"__proto__"==e&&r.Z?(0,r.Z)(t,e,{configurable:!0,enumerable:!0,value:i,writable:!0}):t[e]=i}},61395:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t){return function(e,i,r){for(var n=-1,o=Object(e),a=r(e),s=a.length;s--;){var l=a[t?s:++n];if(!1===i(o[l],l,o))break}return e}}()},93589:(t,e,i)=>{"use strict";i.d(e,{Z:()=>d});var r=i(17685),n=Object.prototype,o=n.hasOwnProperty,a=n.toString,s=r.Z?r.Z.toStringTag:void 0;const l=function(t){var e=o.call(t,s),i=t[s];try{t[s]=void 0;var r=!0}catch(l){}var n=a.call(t);return r&&(e?t[s]=i:delete t[s]),n};var c=Object.prototype.toString;const h=function(t){return c.call(t)};var u=r.Z?r.Z.toStringTag:void 0;const d=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":u&&u in Object(t)?l(t):h(t)}},39473:(t,e,i)=>{"use strict";i.d(e,{Z:()=>a});var r=i(72764);const n=(0,i(1851).Z)(Object.keys,Object);var o=Object.prototype.hasOwnProperty;const a=function(t){if(!(0,r.Z)(t))return n(t);var e=[];for(var i in Object(t))o.call(t,i)&&"constructor"!=i&&e.push(i);return e}},69581:(t,e,i)=>{"use strict";i.d(e,{Z:()=>a});var r=i(69203),n=i(81211),o=i(27227);const a=function(t,e){return(0,o.Z)((0,n.Z)(t,e,r.Z),t+"")}},21162:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t){return function(e){return t(e)}}},41884:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=i(84073);const n=function(t){var e=new t.constructor(t.byteLength);return new r.Z(e).set(new r.Z(t)),e}},91050:(t,e,i)=>{"use strict";i.d(e,{Z:()=>l});var r=i(66092),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=n&&"object"==typeof module&&module&&!module.nodeType&&module,a=o&&o.exports===n?r.Z.Buffer:void 0,s=a?a.allocUnsafe:void 0;const l=function(t,e){if(e)return t.slice();var i=t.length,r=s?s(i):new t.constructor(i);return t.copy(r),r}},12701:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=i(41884);const n=function(t,e){var i=e?(0,r.Z)(t.buffer):t.buffer;return new t.constructor(i,t.byteOffset,t.length)}},87215:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t,e){var i=-1,r=t.length;for(e||(e=Array(r));++i<r;)e[i]=t[i];return e}},31899:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(72954),n=i(74752);const o=function(t,e,i,o){var a=!i;i||(i={});for(var s=-1,l=e.length;++s<l;){var c=e[s],h=o?o(i[c],t[c],c,i,t):void 0;void 0===h&&(h=t[c]),a?(0,n.Z)(i,c,h):(0,r.Z)(i,c,h)}return i}},77904:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=i(62508);const n=function(){try{var t=(0,r.Z)(Object,"defineProperty");return t({},"",{}),t}catch(e){}}()},13413:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r="object"==typeof global&&global&&global.Object===Object&&global},62508:(t,e,i)=>{"use strict";i.d(e,{Z:()=>x});var r=i(73234);const n=i(66092).Z["__core-js_shared__"];var o,a=(o=/[^.]+$/.exec(n&&n.keys&&n.keys.IE_PROTO||""))?"Symbol(src)_1."+o:"";const s=function(t){return!!a&&a in t};var l=i(77226),c=i(90019),h=/^\[object .+?Constructor\]$/,u=Function.prototype,d=Object.prototype,f=u.toString,p=d.hasOwnProperty,g=RegExp("^"+f.call(p).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const m=function(t){return!(!(0,l.Z)(t)||s(t))&&((0,r.Z)(t)?g:h).test((0,c.Z)(t))};const y=function(t,e){return null==t?void 0:t[e]};const x=function(t,e){var i=y(t,e);return m(i)?i:void 0}},12513:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=(0,i(1851).Z)(Object.getPrototypeOf,Object)},83970:(t,e,i)=>{"use strict";i.d(e,{Z:()=>k});var r=i(62508),n=i(66092);const o=(0,r.Z)(n.Z,"DataView");var a=i(86183);const s=(0,r.Z)(n.Z,"Promise");var l=i(93203);const c=(0,r.Z)(n.Z,"WeakMap");var h=i(93589),u=i(90019),d="[object Map]",f="[object Promise]",p="[object Set]",g="[object WeakMap]",m="[object DataView]",y=(0,u.Z)(o),x=(0,u.Z)(a.Z),C=(0,u.Z)(s),b=(0,u.Z)(l.Z),_=(0,u.Z)(c),v=h.Z;(o&&v(new o(new ArrayBuffer(1)))!=m||a.Z&&v(new a.Z)!=d||s&&v(s.resolve())!=f||l.Z&&v(new l.Z)!=p||c&&v(new c)!=g)&&(v=function(t){var e=(0,h.Z)(t),i="[object Object]"==e?t.constructor:void 0,r=i?(0,u.Z)(i):"";if(r)switch(r){case y:return m;case x:return d;case C:return f;case b:return p;case _:return g}return e});const k=v},73658:(t,e,i)=>{"use strict";i.d(e,{Z:()=>l});var r=i(77226),n=Object.create;const o=function(){function t(){}return function(e){if(!(0,r.Z)(e))return{};if(n)return n(e);t.prototype=e;var i=new t;return t.prototype=void 0,i}}();var a=i(12513),s=i(72764);const l=function(t){return"function"!=typeof t.constructor||(0,s.Z)(t)?{}:o((0,a.Z)(t))}},56009:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=/^(?:0|[1-9]\d*)$/;const n=function(t,e){var i=typeof t;return!!(e=null==e?9007199254740991:e)&&("number"==i||"symbol"!=i&&r.test(t))&&t>-1&&t%1==0&&t<e}},50439:(t,e,i)=>{"use strict";i.d(e,{Z:()=>s});var r=i(79651),n=i(50585),o=i(56009),a=i(77226);const s=function(t,e,i){if(!(0,a.Z)(i))return!1;var s=typeof e;return!!("number"==s?(0,n.Z)(i)&&(0,o.Z)(e,i.length):"string"==s&&e in i)&&(0,r.Z)(i[e],t)}},72764:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=Object.prototype;const n=function(t){var e=t&&t.constructor;return t===("function"==typeof e&&e.prototype||r)}},98351:(t,e,i)=>{"use strict";i.d(e,{Z:()=>s});var r=i(13413),n="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=n&&"object"==typeof module&&module&&!module.nodeType&&module,a=o&&o.exports===n&&r.Z.process;const s=function(){try{var t=o&&o.require&&o.require("util").types;return t||a&&a.binding&&a.binding("util")}catch(e){}}()},1851:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t,e){return function(i){return t(e(i))}}},81211:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});const r=function(t,e,i){switch(i.length){case 0:return t.call(e);case 1:return t.call(e,i[0]);case 2:return t.call(e,i[0],i[1]);case 3:return t.call(e,i[0],i[1],i[2])}return t.apply(e,i)};var n=Math.max;const o=function(t,e,i){return e=n(void 0===e?t.length-1:e,0),function(){for(var o=arguments,a=-1,s=n(o.length-e,0),l=Array(s);++a<s;)l[a]=o[e+a];a=-1;for(var c=Array(e+1);++a<e;)c[a]=o[a];return c[e]=i(l),r(t,this,c)}}},66092:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(13413),n="object"==typeof self&&self&&self.Object===Object&&self;const o=r.Z||n||Function("return this")()},27227:(t,e,i)=>{"use strict";i.d(e,{Z:()=>l});var r=i(62002),n=i(77904),o=i(69203);const a=n.Z?function(t,e){return(0,n.Z)(t,"toString",{configurable:!0,enumerable:!1,value:(0,r.Z)(e),writable:!0})}:o.Z;var s=Date.now;const l=function(t){var e=0,i=0;return function(){var r=s(),n=16-(r-i);if(i=r,n>0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(a)},90019:(t,e,i)=>{"use strict";i.d(e,{Z:()=>n});var r=Function.prototype.toString;const n=function(t){if(null!=t){try{return r.call(t)}catch(e){}try{return t+""}catch(e){}}return""}},62002:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t){return function(){return t}}},79651:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t,e){return t===e||t!=t&&e!=e}},69203:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t){return t}},29169:(t,e,i)=>{"use strict";i.d(e,{Z:()=>c});var r=i(93589),n=i(18533);const o=function(t){return(0,n.Z)(t)&&"[object Arguments]"==(0,r.Z)(t)};var a=Object.prototype,s=a.hasOwnProperty,l=a.propertyIsEnumerable;const c=o(function(){return arguments}())?o:function(t){return(0,n.Z)(t)&&s.call(t,"callee")&&!l.call(t,"callee")}},27771:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=Array.isArray},50585:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(73234),n=i(1656);const o=function(t){return null!=t&&(0,n.Z)(t.length)&&!(0,r.Z)(t)}},836:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(50585),n=i(18533);const o=function(t){return(0,n.Z)(t)&&(0,r.Z)(t)}},77008:(t,e,i)=>{"use strict";i.d(e,{Z:()=>l});var r=i(66092);const n=function(){return!1};var o="object"==typeof exports&&exports&&!exports.nodeType&&exports,a=o&&"object"==typeof module&&module&&!module.nodeType&&module,s=a&&a.exports===o?r.Z.Buffer:void 0;const l=(s?s.isBuffer:void 0)||n},79697:(t,e,i)=>{"use strict";i.d(e,{Z:()=>d});var r=i(39473),n=i(83970),o=i(29169),a=i(27771),s=i(50585),l=i(77008),c=i(72764),h=i(18843),u=Object.prototype.hasOwnProperty;const d=function(t){if(null==t)return!0;if((0,s.Z)(t)&&((0,a.Z)(t)||"string"==typeof t||"function"==typeof t.splice||(0,l.Z)(t)||(0,h.Z)(t)||(0,o.Z)(t)))return!t.length;var e=(0,n.Z)(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if((0,c.Z)(t))return!(0,r.Z)(t).length;for(var i in t)if(u.call(t,i))return!1;return!0}},73234:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(93589),n=i(77226);const o=function(t){if(!(0,n.Z)(t))return!1;var e=(0,r.Z)(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},1656:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}},77226:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},18533:(t,e,i)=>{"use strict";i.d(e,{Z:()=>r});const r=function(t){return null!=t&&"object"==typeof t}},37514:(t,e,i)=>{"use strict";i.d(e,{Z:()=>u});var r=i(93589),n=i(12513),o=i(18533),a=Function.prototype,s=Object.prototype,l=a.toString,c=s.hasOwnProperty,h=l.call(Object);const u=function(t){if(!(0,o.Z)(t)||"[object Object]"!=(0,r.Z)(t))return!1;var e=(0,n.Z)(t);if(null===e)return!0;var i=c.call(e,"constructor")&&e.constructor;return"function"==typeof i&&i instanceof i&&l.call(i)==h}},18843:(t,e,i)=>{"use strict";i.d(e,{Z:()=>u});var r=i(93589),n=i(1656),o=i(18533),a={};a["[object Float32Array]"]=a["[object Float64Array]"]=a["[object Int8Array]"]=a["[object Int16Array]"]=a["[object Int32Array]"]=a["[object Uint8Array]"]=a["[object Uint8ClampedArray]"]=a["[object Uint16Array]"]=a["[object Uint32Array]"]=!0,a["[object Arguments]"]=a["[object Array]"]=a["[object ArrayBuffer]"]=a["[object Boolean]"]=a["[object DataView]"]=a["[object Date]"]=a["[object Error]"]=a["[object Function]"]=a["[object Map]"]=a["[object Number]"]=a["[object Object]"]=a["[object RegExp]"]=a["[object Set]"]=a["[object String]"]=a["[object WeakMap]"]=!1;const s=function(t){return(0,o.Z)(t)&&(0,n.Z)(t.length)&&!!a[(0,r.Z)(t)]};var l=i(21162),c=i(98351),h=c.Z&&c.Z.isTypedArray;const u=h?(0,l.Z)(h):s},32957:(t,e,i)=>{"use strict";i.d(e,{Z:()=>h});var r=i(87668),n=i(77226),o=i(72764);const a=function(t){var e=[];if(null!=t)for(var i in Object(t))e.push(i);return e};var s=Object.prototype.hasOwnProperty;const l=function(t){if(!(0,n.Z)(t))return a(t);var e=(0,o.Z)(t),i=[];for(var r in t)("constructor"!=r||!e&&s.call(t,r))&&i.push(r);return i};var c=i(50585);const h=function(t){return(0,c.Z)(t)?(0,r.Z)(t,!0):l(t)}},42454:(t,e,i)=>{"use strict";i.d(e,{Z:()=>o});var r=i(37834);function n(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var i=function(){var r=arguments,n=e?e.apply(this,r):r[0],o=i.cache;if(o.has(n))return o.get(n);var a=t.apply(this,r);return i.cache=o.set(n,a)||o,a};return i.cache=new(n.Cache||r.Z),i}n.Cache=r.Z;const o=n},59236:(t,e,i)=>{"use strict";i.d(e,{Z:()=>F});var r=i(31667),n=i(74752),o=i(79651);const a=function(t,e,i){(void 0!==i&&!(0,o.Z)(t[e],i)||void 0===i&&!(e in t))&&(0,n.Z)(t,e,i)};var s=i(61395),l=i(91050),c=i(12701),h=i(87215),u=i(73658),d=i(29169),f=i(27771),p=i(836),g=i(77008),m=i(73234),y=i(77226),x=i(37514),C=i(18843);const b=function(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]};var _=i(31899),v=i(32957);const k=function(t){return(0,_.Z)(t,(0,v.Z)(t))};const T=function(t,e,i,r,n,o,s){var _=b(t,i),v=b(e,i),T=s.get(v);if(T)a(t,i,T);else{var w=o?o(_,v,i+"",t,e,s):void 0,S=void 0===w;if(S){var B=(0,f.Z)(v),F=!B&&(0,g.Z)(v),A=!B&&!F&&(0,C.Z)(v);w=v,B||F||A?(0,f.Z)(_)?w=_:(0,p.Z)(_)?w=(0,h.Z)(_):F?(S=!1,w=(0,l.Z)(v,!0)):A?(S=!1,w=(0,c.Z)(v,!0)):w=[]:(0,x.Z)(v)||(0,d.Z)(v)?(w=_,(0,d.Z)(_)?w=k(_):(0,y.Z)(_)&&!(0,m.Z)(_)||(w=(0,u.Z)(v))):S=!1}S&&(s.set(v,w),n(w,v,r,o,s),s.delete(v)),a(t,i,w)}};const w=function t(e,i,n,o,l){e!==i&&(0,s.Z)(i,(function(s,c){if(l||(l=new r.Z),(0,y.Z)(s))T(e,i,c,n,t,o,l);else{var h=o?o(b(e,c),s,c+"",e,i,l):void 0;void 0===h&&(h=s),a(e,c,h)}}),v.Z)};var S=i(69581),B=i(50439);const F=function(t){return(0,S.Z)((function(e,i){var r=-1,n=i.length,o=n>1?i[n-1]:void 0,a=n>2?i[2]:void 0;for(o=t.length>3&&"function"==typeof o?(n--,o):void 0,a&&(0,B.Z)(i[0],i[1],a)&&(o=n<3?void 0:o,n=1),e=Object(e);++r<n;){var s=i[r];s&&t(e,s,r,o)}return e}))}((function(t,e,i){w(t,e,i)}))},56363:(t,e,i)=>{"use strict";i.d(e,{A:()=>It,B:()=>me,C:()=>ge,D:()=>Ft,E:()=>Be,F:()=>er,G:()=>oe,H:()=>ht,I:()=>Mi,J:()=>Dn,K:()=>Si,L:()=>to,Z:()=>Gt,a:()=>ki,b:()=>vi,c:()=>Ai,d:()=>ft,e:()=>_t,f:()=>Vt,g:()=>_i,h:()=>ue,i:()=>ui,j:()=>he,k:()=>re,l:()=>st,m:()=>mt,n:()=>Kt,o:()=>di,p:()=>Li,q:()=>Ti,r:()=>wi,s:()=>bi,t:()=>Ci,u:()=>ye,v:()=>yt,w:()=>le,x:()=>ae,y:()=>Zi,z:()=>qi});var r=i(18464),n=i(27484),o=i(17967),a=i(64218),s=i(27856),l=i(71610),c=i(49807);const h=(t,e)=>{const i=l.Z.parse(t),r={};for(const n in e)e[n]&&(r[n]=i[n]+e[n]);return(0,c.Z)(t,r)};var u=i(51117);const d=(t,e,i=50)=>{const{r:r,g:n,b:o,a:a}=l.Z.parse(t),{r:s,g:c,b:h,a:d}=l.Z.parse(e),f=i/100,p=2*f-1,g=a-d,m=((p*g==-1?p:(p+g)/(1+p*g))+1)/2,y=1-m,x=r*m+s*y,C=n*m+c*y,b=o*m+h*y,_=a*f+d*(1-f);return(0,u.Z)(x,C,b,_)},f=(t,e=100)=>{const i=l.Z.parse(t);return i.r=255-i.r,i.g=255-i.g,i.b=255-i.b,d(i,t,e)};var p=i(7201),g=i(12281),m=i(91619),y=i(42454),x=i(59236),C="comm",b="rule",_="decl",v=Math.abs,k=String.fromCharCode;Object.assign;function T(t){return t.trim()}function w(t,e,i){return t.replace(e,i)}function S(t,e){return t.indexOf(e)}function B(t,e){return 0|t.charCodeAt(e)}function F(t,e,i){return t.slice(e,i)}function A(t){return t.length}function L(t,e){return e.push(t),t}function M(t,e){for(var i="",r=0;r<t.length;r++)i+=e(t[r],r,t,e)||"";return i}function E(t,e,i,r){switch(t.type){case"@layer":if(t.children.length)break;case"@import":case _:return t.return=t.return||t.value;case C:return"";case"@keyframes":return t.return=t.value+"{"+M(t.children,r)+"}";case b:if(!A(t.value=t.props.join(",")))return""}return A(i=M(t.children,r))?t.return=t.value+"{"+i+"}":""}var Z=1,N=1,O=0,I=0,j=0,q="";function D(t,e,i,r,n,o,a,s){return{value:t,root:e,parent:i,type:r,props:n,children:o,line:Z,column:N,length:a,return:"",siblings:s}}function $(){return j=I>0?B(q,--I):0,N--,10===j&&(N=1,Z--),j}function z(){return j=I<O?B(q,I++):0,N++,10===j&&(N=1,Z++),j}function P(){return B(q,I)}function R(){return I}function W(t,e){return F(q,t,e)}function H(t){switch(t){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function U(t){return Z=N=1,O=A(q=t),I=0,[]}function Y(t){return q="",t}function V(t){return T(W(I-1,Q(91===t?t+2:40===t?t+1:t)))}function G(t){for(;(j=P())&&j<33;)z();return H(t)>2||H(j)>3?"":" "}function X(t,e){for(;--e&&z()&&!(j<48||j>102||j>57&&j<65||j>70&&j<97););return W(t,R()+(e<6&&32==P()&&32==z()))}function Q(t){for(;z();)switch(j){case t:return I;case 34:case 39:34!==t&&39!==t&&Q(j);break;case 40:41===t&&Q(t);break;case 92:z()}return I}function J(t,e){for(;z()&&t+j!==57&&(t+j!==84||47!==P()););return"/*"+W(e,I-1)+"*"+k(47===t?t:z())}function K(t){for(;!H(P());)z();return W(t,I)}function tt(t){return Y(et("",null,null,null,[""],t=U(t),0,[0],t))}function et(t,e,i,r,n,o,a,s,l){for(var c=0,h=0,u=a,d=0,f=0,p=0,g=1,m=1,y=1,x=0,C="",b=n,_=o,v=r,T=C;m;)switch(p=x,x=z()){case 40:if(108!=p&&58==B(T,u-1)){-1!=S(T+=w(V(x),"&","&\f"),"&\f")&&(y=-1);break}case 34:case 39:case 91:T+=V(x);break;case 9:case 10:case 13:case 32:T+=G(p);break;case 92:T+=X(R()-1,7);continue;case 47:switch(P()){case 42:case 47:L(rt(J(z(),R()),e,i,l),l);break;default:T+="/"}break;case 123*g:s[c++]=A(T)*y;case 125*g:case 59:case 0:switch(x){case 0:case 125:m=0;case 59+h:-1==y&&(T=w(T,/\f/g,"")),f>0&&A(T)-u&&L(f>32?nt(T+";",r,i,u-1,l):nt(w(T," ","")+";",r,i,u-2,l),l);break;case 59:T+=";";default:if(L(v=it(T,e,i,c,h,n,s,C,b=[],_=[],u,o),o),123===x)if(0===h)et(T,e,v,v,b,o,u,s,_);else switch(99===d&&110===B(T,3)?100:d){case 100:case 108:case 109:case 115:et(t,v,v,r&&L(it(t,v,v,0,0,n,s,C,n,b=[],u,_),_),n,_,u,s,r?b:_);break;default:et(T,v,v,v,[""],_,0,s,_)}}c=h=f=0,g=y=1,C=T="",u=a;break;case 58:u=1+A(T),f=p;default:if(g<1)if(123==x)--g;else if(125==x&&0==g++&&125==$())continue;switch(T+=k(x),x*g){case 38:y=h>0?1:(T+="\f",-1);break;case 44:s[c++]=(A(T)-1)*y,y=1;break;case 64:45===P()&&(T+=V(z())),d=P(),h=u=A(C=T+=K(R())),x++;break;case 45:45===p&&2==A(T)&&(g=0)}}return o}function it(t,e,i,r,n,o,a,s,l,c,h,u){for(var d=n-1,f=0===n?o:[""],p=function(t){return t.length}(f),g=0,m=0,y=0;g<r;++g)for(var x=0,C=F(t,d+1,d=v(m=a[g])),_=t;x<p;++x)(_=T(m>0?f[x]+" "+C:w(C,/&\f/g,f[x])))&&(l[y++]=_);return D(t,e,i,0===n?b:s,l,c,h,u)}function rt(t,e,i,r){return D(t,e,i,C,k(j),F(t,2,-2),0,r)}function nt(t,e,i,r,n){return D(t,e,i,_,F(t,0,r),F(t,r+1,-1),r,n)}var ot=i(79697);const at={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},st={trace:(...t)=>{},debug:(...t)=>{},info:(...t)=>{},warn:(...t)=>{},error:(...t)=>{},fatal:(...t)=>{}},lt=function(t="fatal"){let e=at.fatal;"string"==typeof t?(t=t.toLowerCase())in at&&(e=at[t]):"number"==typeof t&&(e=t),st.trace=()=>{},st.debug=()=>{},st.info=()=>{},st.warn=()=>{},st.error=()=>{},st.fatal=()=>{},e<=at.fatal&&(st.fatal=console.error?console.error.bind(console,ct("FATAL"),"color: orange"):console.log.bind(console,"\x1b[35m",ct("FATAL"))),e<=at.error&&(st.error=console.error?console.error.bind(console,ct("ERROR"),"color: orange"):console.log.bind(console,"\x1b[31m",ct("ERROR"))),e<=at.warn&&(st.warn=console.warn?console.warn.bind(console,ct("WARN"),"color: orange"):console.log.bind(console,"\x1b[33m",ct("WARN"))),e<=at.info&&(st.info=console.info?console.info.bind(console,ct("INFO"),"color: lightblue"):console.log.bind(console,"\x1b[34m",ct("INFO"))),e<=at.debug&&(st.debug=console.debug?console.debug.bind(console,ct("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",ct("DEBUG"))),e<=at.trace&&(st.trace=console.debug?console.debug.bind(console,ct("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",ct("TRACE")))},ct=t=>`%c${n().format("ss.SSS")} : ${t} : `,ht=/<br\s*\/?>/gi,ut=t=>s.sanitize(t),dt=(t,e)=>{var i;if(!1!==(null==(i=e.flowchart)?void 0:i.htmlLabels)){const i=e.securityLevel;"antiscript"===i||"strict"===i?t=ut(t):"loose"!==i&&(t=(t=(t=gt(t)).replace(/</g,"<").replace(/>/g,">")).replace(/=/g,"="),t=pt(t))}return t},ft=(t,e)=>t?t=e.dompurifyConfig?s.sanitize(dt(t,e),e.dompurifyConfig).toString():s.sanitize(dt(t,e),{FORBID_TAGS:["style"]}).toString():t,pt=t=>t.replace(/#br#/g,"<br/>"),gt=t=>t.replace(ht,"#br#"),mt=t=>!1!==t&&!["false","null","0"].includes(String(t).trim().toLowerCase()),yt=function(t){const e=t.split(/(,)/),i=[];for(let r=0;r<e.length;r++){let t=e[r];if(","===t&&r>0&&r+1<e.length){const n=e[r-1],o=e[r+1];Ct(n,o)&&(t=n+","+o,r++,i.pop())}i.push(bt(t))}return i.join("")},xt=(t,e)=>Math.max(0,t.split(e).length-1),Ct=(t,e)=>{const i=xt(t,"~"),r=xt(e,"~");return 1===i&&1===r},bt=t=>{const e=xt(t,"~");let i=!1;if(e<=1)return t;e%2!=0&&t.startsWith("~")&&(t=t.substring(1),i=!0);const r=[...t];let n=r.indexOf("~"),o=r.lastIndexOf("~");for(;-1!==n&&-1!==o&&n!==o;)r[n]="<",r[o]=">",n=r.indexOf("~"),o=r.lastIndexOf("~");return i&&r.unshift("~"),r.join("")},_t={getRows:t=>{if(!t)return[""];return gt(t).replace(/\\n/g,"#br#").split("#br#")},sanitizeText:ft,sanitizeTextOrArray:(t,e)=>"string"==typeof t?ft(t,e):t.flat().map((t=>ft(t,e))),hasBreaks:t=>ht.test(t),splitBreaks:t=>t.split(ht),lineBreakRegex:ht,removeScript:ut,getUrl:t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=e.replaceAll(/\(/g,"\\("),e=e.replaceAll(/\)/g,"\\)")),e},evaluate:mt,getMax:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.max(...e)},getMin:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.min(...e)}},vt=(t,e)=>h(t,e?{s:-40,l:10}:{s:-40,l:-10}),kt="#ffffff",Tt="#f2f2f2";let wt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||h(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||h(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||vt(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||vt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||vt(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||vt(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||f(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||f(this.tertiaryColor),this.lineColor=this.lineColor||f(this.background),this.arrowheadColor=this.arrowheadColor||f(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?(0,p.Z)(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||"grey",this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||(0,p.Z)(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||f(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||(0,g.Z)(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.darkMode)for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.Z)(this["cScale"+h],75);else for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.Z)(this["cScale"+h],25);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this.darkMode?this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.Z)(this["cScale"+h],10):this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.Z)(this["cScale"+h],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;const d=this.darkMode?-4:-1;for(let f=0;f<5;f++)this["surface"+f]=this["surface"+f]||h(this.mainBkg,{h:180,s:-15,l:d*(5+3*f)}),this["surfacePeer"+f]=this["surfacePeer"+f]||h(this.mainBkg,{h:180,s:-15,l:d*(8+3*f)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||h(this.primaryColor,{h:64}),this.fillType3=this.fillType3||h(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||h(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||h(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||h(this.primaryColor,{h:128}),this.fillType7=this.fillType7||h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||h(this.primaryColor,{l:-10}),this.pie5=this.pie5||h(this.secondaryColor,{l:-10}),this.pie6=this.pie6||h(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||h(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.Z)(this.quadrant1Fill)?(0,g.Z)(this.quadrant1Fill):(0,p.Z)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,p.Z)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.Z)(this.git0,25),this.git1=(0,g.Z)(this.git1,25),this.git2=(0,g.Z)(this.git2,25),this.git3=(0,g.Z)(this.git3,25),this.git4=(0,g.Z)(this.git4,25),this.git5=(0,g.Z)(this.git5,25),this.git6=(0,g.Z)(this.git6,25),this.git7=(0,g.Z)(this.git7,25)):(this.git0=(0,p.Z)(this.git0,25),this.git1=(0,p.Z)(this.git1,25),this.git2=(0,p.Z)(this.git2,25),this.git3=(0,p.Z)(this.git3,25),this.git4=(0,p.Z)(this.git4,25),this.git5=(0,p.Z)(this.git5,25),this.git6=(0,p.Z)(this.git6,25),this.git7=(0,p.Z)(this.git7,25)),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||kt,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Tt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};let St=class{constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=(0,g.Z)(this.primaryColor,16),this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=f(this.background),this.secondaryBorderColor=vt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=vt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=(0,g.Z)(f("#323D47"),10),this.lineColor="calculated",this.border1="#81B1DB",this.border2=(0,u.Z)(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=(0,p.Z)("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=(0,p.Z)(this.sectionBkgColor,10),this.taskBorderColor=(0,u.Z)(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=(0,u.Z)(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.secondBkg=(0,g.Z)(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=(0,g.Z)(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.mainContrastColor,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=(0,g.Z)(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330});for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.Z)(this["cScale"+h],10);for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,s:-30,l:-(4*d-10)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,s:-30,l:-(4*d-7)});this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["pie"+h]=this["cScale"+h];this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.Z)(this.quadrant1Fill)?(0,g.Z)(this.quadrant1Fill):(0,p.Z)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#3498db,#2ecc71,#e74c3c,#f1c40f,#bdc3c7,#ffffff,#34495e,#9b59b6,#1abc9c,#e67e22"},this.classText=this.primaryTextColor,this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,p.Z)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,g.Z)(this.secondaryColor,20),this.git1=(0,g.Z)(this.pie2||this.secondaryColor,20),this.git2=(0,g.Z)(this.pie3||this.tertiaryColor,20),this.git3=(0,g.Z)(this.pie4||h(this.primaryColor,{h:-30}),20),this.git4=(0,g.Z)(this.pie5||h(this.primaryColor,{h:-60}),20),this.git5=(0,g.Z)(this.pie6||h(this.primaryColor,{h:-90}),10),this.git6=(0,g.Z)(this.pie7||h(this.primaryColor,{h:60}),10),this.git7=(0,g.Z)(this.pie8||h(this.primaryColor,{h:120}),20),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||(0,g.Z)(this.background,12),this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||(0,g.Z)(this.background,2)}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};let Bt=class{constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=h(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=vt(this.primaryColor,this.darkMode),this.secondaryBorderColor=vt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=vt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#e8e8e8",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.sectionBkgColor=(0,u.Z)(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,p.Z)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,p.Z)(this.tertiaryColor,40);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.Z)(this["cScale"+h],10),this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.Z)(this["cScale"+h],25);for(let d=0;d<this.THEME_COLOR_LIMIT;d++)this["cScaleInv"+d]=this["cScaleInv"+d]||h(this["cScale"+d],{h:180});for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,l:-(7+5*d)});if(this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor,"calculated"!==this.labelTextColor){this.cScaleLabel0=this.cScaleLabel0||f(this.labelTextColor),this.cScaleLabel3=this.cScaleLabel3||f(this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.labelTextColor}this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.textColor,this.edgeLabelBackground=this.labelBackground,this.actorBorder=(0,g.Z)(this.border1,23),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.signalColor=this.textColor,this.signalTextColor=this.textColor,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||h(this.tertiaryColor,{l:-40}),this.pie4=this.pie4||h(this.primaryColor,{l:-10}),this.pie5=this.pie5||h(this.secondaryColor,{l:-30}),this.pie6=this.pie6||h(this.tertiaryColor,{l:-20}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-20}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-40}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:-40}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-40}),this.pie11=this.pie11||h(this.primaryColor,{h:-90,l:-40}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-30}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.Z)(this.quadrant1Fill)?(0,g.Z)(this.quadrant1Fill):(0,p.Z)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#ECECFF,#8493A6,#FFC3A0,#DCDDE1,#B8E994,#D1A36F,#C3CDE6,#FFB6C1,#496078,#F8F3E3"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.labelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.Z)(this.git0,25),this.git1=(0,g.Z)(this.git1,25),this.git2=(0,g.Z)(this.git2,25),this.git3=(0,g.Z)(this.git3,25),this.git4=(0,g.Z)(this.git4,25),this.git5=(0,g.Z)(this.git5,25),this.git6=(0,g.Z)(this.git6,25),this.git7=(0,g.Z)(this.git7,25)):(this.git0=(0,p.Z)(this.git0,25),this.git1=(0,p.Z)(this.git1,25),this.git2=(0,p.Z)(this.git2,25),this.git3=(0,p.Z)(this.git3,25),this.git4=(0,p.Z)(this.git4,25),this.git5=(0,p.Z)(this.git5,25),this.git6=(0,p.Z)(this.git6,25),this.git7=(0,p.Z)(this.git7,25)),this.gitInv0=this.gitInv0||(0,p.Z)(f(this.git0),25),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||kt,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Tt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};const Ft=t=>{const e=new Bt;return e.calculate(t),e};let At=class{constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=(0,g.Z)("#cde498",10),this.primaryBorderColor=vt(this.primaryColor,this.darkMode),this.secondaryBorderColor=vt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=vt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.primaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.actorBorder=(0,p.Z)(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||h(this.primaryColor,{h:30}),this.cScale4=this.cScale4||h(this.primaryColor,{h:60}),this.cScale5=this.cScale5||h(this.primaryColor,{h:90}),this.cScale6=this.cScale6||h(this.primaryColor,{h:120}),this.cScale7=this.cScale7||h(this.primaryColor,{h:150}),this.cScale8=this.cScale8||h(this.primaryColor,{h:210}),this.cScale9=this.cScale9||h(this.primaryColor,{h:270}),this.cScale10=this.cScale10||h(this.primaryColor,{h:300}),this.cScale11=this.cScale11||h(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,p.Z)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,p.Z)(this.tertiaryColor,40);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScale"+h]=(0,p.Z)(this["cScale"+h],10),this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.Z)(this["cScale"+h],25);for(let d=0;d<this.THEME_COLOR_LIMIT;d++)this["cScaleInv"+d]=this["cScaleInv"+d]||h(this["cScale"+d],{h:180});this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{h:30,s:-30,l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{h:30,s:-30,l:-(8+5*d)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.taskBorderColor=this.border1,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||h(this.primaryColor,{l:-30}),this.pie5=this.pie5||h(this.secondaryColor,{l:-30}),this.pie6=this.pie6||h(this.tertiaryColor,{h:40,l:-40}),this.pie7=this.pie7||h(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||h(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||h(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||h(this.primaryColor,{h:60,l:-50}),this.pie11=this.pie11||h(this.primaryColor,{h:-60,l:-50}),this.pie12=this.pie12||h(this.primaryColor,{h:120,l:-50}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.Z)(this.quadrant1Fill)?(0,g.Z)(this.quadrant1Fill):(0,p.Z)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#CDE498,#FF6B6B,#A0D2DB,#D7BDE2,#F0F0F0,#FFC3A0,#7FD8BE,#FF9A8B,#FAF3E0,#FFF176"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||h(this.primaryColor,{h:-30}),this.git4=this.git4||h(this.primaryColor,{h:-60}),this.git5=this.git5||h(this.primaryColor,{h:-90}),this.git6=this.git6||h(this.primaryColor,{h:60}),this.git7=this.git7||h(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,g.Z)(this.git0,25),this.git1=(0,g.Z)(this.git1,25),this.git2=(0,g.Z)(this.git2,25),this.git3=(0,g.Z)(this.git3,25),this.git4=(0,g.Z)(this.git4,25),this.git5=(0,g.Z)(this.git5,25),this.git6=(0,g.Z)(this.git6,25),this.git7=(0,g.Z)(this.git7,25)):(this.git0=(0,p.Z)(this.git0,25),this.git1=(0,p.Z)(this.git1,25),this.git2=(0,p.Z)(this.git2,25),this.git3=(0,p.Z)(this.git3,25),this.git4=(0,p.Z)(this.git4,25),this.git5=(0,p.Z)(this.git5,25),this.git6=(0,p.Z)(this.git6,25),this.git7=(0,p.Z)(this.git7,25)),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||f(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||f(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||kt,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Tt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};class Lt{constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=(0,g.Z)(this.contrast,55),this.background="#ffffff",this.tertiaryColor=h(this.primaryColor,{h:-160}),this.primaryBorderColor=vt(this.primaryColor,this.darkMode),this.secondaryBorderColor=vt(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=vt(this.tertiaryColor,this.darkMode),this.primaryTextColor=f(this.primaryColor),this.secondaryTextColor=f(this.secondaryColor),this.tertiaryTextColor=f(this.tertiaryColor),this.lineColor=f(this.background),this.textColor=f(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var t,e,i,r,n,o,a,s,l,c,u;this.secondBkg=(0,g.Z)(this.contrast,55),this.border2=this.contrast,this.actorBorder=(0,g.Z)(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.lineColor,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleInv"+h]=this["cScaleInv"+h]||f(this["cScale"+h]);for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this.darkMode?this["cScalePeer"+h]=this["cScalePeer"+h]||(0,g.Z)(this["cScale"+h],10):this["cScalePeer"+h]=this["cScalePeer"+h]||(0,p.Z)(this["cScale"+h],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor),this.cScaleLabel0=this.cScaleLabel0||this.cScale1,this.cScaleLabel2=this.cScaleLabel2||this.cScale1;for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["cScaleLabel"+h]=this["cScaleLabel"+h]||this.scaleLabelColor;for(let d=0;d<5;d++)this["surface"+d]=this["surface"+d]||h(this.mainBkg,{l:-(5+5*d)}),this["surfacePeer"+d]=this["surfacePeer"+d]||h(this.mainBkg,{l:-(8+5*d)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.text,this.sectionBkgColor=(0,g.Z)(this.contrast,30),this.sectionBkgColor2=(0,g.Z)(this.contrast,30),this.taskBorderColor=(0,p.Z)(this.contrast,10),this.taskBkgColor=this.contrast,this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor=this.text,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.gridColor=(0,g.Z)(this.border1,30),this.doneTaskBkgColor=this.done,this.doneTaskBorderColor=this.lineColor,this.critBkgColor=this.critical,this.critBorderColor=(0,p.Z)(this.critBkgColor,10),this.todayLineColor=this.critBkgColor,this.transitionColor=this.transitionColor||"#000",this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f4f4f4",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.stateBorder=this.stateBorder||"#000",this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#222",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=h(this.primaryColor,{h:64}),this.fillType3=h(this.secondaryColor,{h:64}),this.fillType4=h(this.primaryColor,{h:-64}),this.fillType5=h(this.secondaryColor,{h:-64}),this.fillType6=h(this.primaryColor,{h:128}),this.fillType7=h(this.secondaryColor,{h:128});for(let h=0;h<this.THEME_COLOR_LIMIT;h++)this["pie"+h]=this["cScale"+h];this.pie12=this.pie0,this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||h(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||h(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||h(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||h(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||h(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||h(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,m.Z)(this.quadrant1Fill)?(0,g.Z)(this.quadrant1Fill):(0,p.Z)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:(null==(t=this.xyChart)?void 0:t.backgroundColor)||this.background,titleColor:(null==(e=this.xyChart)?void 0:e.titleColor)||this.primaryTextColor,xAxisTitleColor:(null==(i=this.xyChart)?void 0:i.xAxisTitleColor)||this.primaryTextColor,xAxisLabelColor:(null==(r=this.xyChart)?void 0:r.xAxisLabelColor)||this.primaryTextColor,xAxisTickColor:(null==(n=this.xyChart)?void 0:n.xAxisTickColor)||this.primaryTextColor,xAxisLineColor:(null==(o=this.xyChart)?void 0:o.xAxisLineColor)||this.primaryTextColor,yAxisTitleColor:(null==(a=this.xyChart)?void 0:a.yAxisTitleColor)||this.primaryTextColor,yAxisLabelColor:(null==(s=this.xyChart)?void 0:s.yAxisLabelColor)||this.primaryTextColor,yAxisTickColor:(null==(l=this.xyChart)?void 0:l.yAxisTickColor)||this.primaryTextColor,yAxisLineColor:(null==(c=this.xyChart)?void 0:c.yAxisLineColor)||this.primaryTextColor,plotColorPalette:(null==(u=this.xyChart)?void 0:u.plotColorPalette)||"#EEE,#6BB8E4,#8ACB88,#C7ACD6,#E8DCC2,#FFB2A8,#FFF380,#7E8D91,#FFD8B1,#FAF3E0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,p.Z)(this.pie1,25)||this.primaryColor,this.git1=this.pie2||this.secondaryColor,this.git2=this.pie3||this.tertiaryColor,this.git3=this.pie4||h(this.primaryColor,{h:-30}),this.git4=this.pie5||h(this.primaryColor,{h:-60}),this.git5=this.pie6||h(this.primaryColor,{h:-90}),this.git6=this.pie7||h(this.primaryColor,{h:60}),this.git7=this.pie8||h(this.primaryColor,{h:120}),this.gitInv0=this.gitInv0||f(this.git0),this.gitInv1=this.gitInv1||f(this.git1),this.gitInv2=this.gitInv2||f(this.git2),this.gitInv3=this.gitInv3||f(this.git3),this.gitInv4=this.gitInv4||f(this.git4),this.gitInv5=this.gitInv5||f(this.git5),this.gitInv6=this.gitInv6||f(this.git6),this.gitInv7=this.gitInv7||f(this.git7),this.branchLabelColor=this.branchLabelColor||this.labelTextColor,this.gitBranchLabel0=this.branchLabelColor,this.gitBranchLabel1="white",this.gitBranchLabel2=this.branchLabelColor,this.gitBranchLabel3="white",this.gitBranchLabel4=this.branchLabelColor,this.gitBranchLabel5=this.branchLabelColor,this.gitBranchLabel6=this.branchLabelColor,this.gitBranchLabel7=this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||kt,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Tt}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}const Mt={base:{getThemeVariables:t=>{const e=new wt;return e.calculate(t),e}},dark:{getThemeVariables:t=>{const e=new St;return e.calculate(t),e}},default:{getThemeVariables:Ft},forest:{getThemeVariables:t=>{const e=new At;return e.calculate(t),e}},neutral:{getThemeVariables:t=>{const e=new Lt;return e.calculate(t),e}}},Et={flowchart:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},theme:"default",maxTextSize:5e4,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize"],deterministicIds:!1,fontSize:16},Zt={...Et,deterministicIDSeed:void 0,themeCSS:void 0,themeVariables:Mt.default.getThemeVariables(),sequence:{...Et.sequence,messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},noteFont:function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},actorFont:function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}}},gantt:{...Et.gantt,tickInterval:void 0,useWidth:void 0},c4:{...Et.c4,useWidth:void 0,personFont:function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},external_personFont:function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},systemFont:function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},external_systemFont:function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},system_dbFont:function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},external_system_dbFont:function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},system_queueFont:function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},external_system_queueFont:function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},containerFont:function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},external_containerFont:function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},container_dbFont:function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},external_container_dbFont:function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},container_queueFont:function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},external_container_queueFont:function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},componentFont:function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},external_componentFont:function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},component_dbFont:function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},external_component_dbFont:function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},component_queueFont:function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},external_component_queueFont:function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},boundaryFont:function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}}},pie:{...Et.pie,useWidth:984},xyChart:{...Et.xyChart,useWidth:void 0},requirement:{...Et.requirement,useWidth:void 0},gitGraph:{...Et.gitGraph,useMaxWidth:!1},sankey:{...Et.sankey,useMaxWidth:!1}},Nt=(t,e="")=>Object.keys(t).reduce(((i,r)=>Array.isArray(t[r])?i:"object"==typeof t[r]&&null!==t[r]?[...i,e+r,...Nt(t[r],"")]:[...i,e+r]),[]),Ot=new Set(Nt(Zt,"")),It=Zt,jt=t=>{if(st.debug("sanitizeDirective called with",t),"object"==typeof t&&null!=t)if(Array.isArray(t))t.forEach((t=>jt(t)));else{for(const e of Object.keys(t)){if(st.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!Ot.has(e)||null==t[e]){st.debug("sanitize deleting key: ",e),delete t[e];continue}if("object"==typeof t[e]){st.debug("sanitizing object",e),jt(t[e]);continue}const i=["themeCSS","fontFamily","altFontFamily"];for(const r of i)e.includes(r)&&(st.debug("sanitizing css option",e),t[e]=qt(t[e]))}if(t.themeVariables)for(const e of Object.keys(t.themeVariables)){const i=t.themeVariables[e];(null==i?void 0:i.match)&&!i.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}st.debug("After sanitization",t)}},qt=t=>{let e=0,i=0;for(const r of t){if(e<i)return"{ /* ERROR: Unbalanced CSS */ }";"{"===r?e++:"}"===r&&i++}return e!==i?"{ /* ERROR: Unbalanced CSS */ }":t},Dt=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,$t=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,zt=/\s*%%.*\n/gm;class Pt extends Error{constructor(t){super(t),this.name="UnknownDiagramError"}}const Rt={},Wt=function(t,e){t=t.replace(Dt,"").replace($t,"").replace(zt,"\n");for(const[i,{detector:r}]of Object.entries(Rt)){if(r(t,e))return i}throw new Pt(`No diagram type detected matching given configuration for text: ${t}`)},Ht=(...t)=>{for(const{id:e,detector:i,loader:r}of t)Ut(e,i,r)},Ut=(t,e,i)=>{Rt[t]?st.error(`Detector with key ${t} already exists`):Rt[t]={detector:e,loader:i},st.debug(`Detector with key ${t} added${i?" with loader":""}`)},Yt=(t,e,{depth:i=2,clobber:r=!1}={})=>{const n={depth:i,clobber:r};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach((e=>Yt(t,e,n))),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach((e=>{t.includes(e)||t.push(e)})),t):void 0===t||i<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach((n=>{"object"!=typeof e[n]||void 0!==t[n]&&"object"!=typeof t[n]?(r||"object"!=typeof t[n]&&"object"!=typeof e[n])&&(t[n]=e[n]):(void 0===t[n]&&(t[n]=Array.isArray(e[n])?[]:{}),t[n]=Yt(t[n],e[n],{depth:i-1,clobber:r}))})),t)},Vt=Yt,Gt="\u200b",Xt={curveBasis:a.$0Z,curveBasisClosed:a.Dts,curveBasisOpen:a.WQY,curveBumpX:a.qpX,curveBumpY:a.u93,curveBundle:a.tFB,curveCardinalClosed:a.OvA,curveCardinalOpen:a.dCK,curveCardinal:a.YY7,curveCatmullRomClosed:a.fGX,curveCatmullRomOpen:a.$m7,curveCatmullRom:a.zgE,curveLinear:a.c_6,curveLinearClosed:a.fxm,curveMonotoneX:a.FdL,curveMonotoneY:a.ak_,curveNatural:a.SxZ,curveStep:a.eA_,curveStepAfter:a.jsv,curveStepBefore:a.iJ},Qt=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,Jt=function(t,e=null){try{const i=new RegExp(`[%]{2}(?![{]${Qt.source})(?=[}][%]{2}).*\n`,"ig");let r;t=t.trim().replace(i,"").replace(/'/gm,'"'),st.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const n=[];for(;null!==(r=$t.exec(t));)if(r.index===$t.lastIndex&&$t.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){const t=r[1]?r[1]:r[2],e=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;n.push({type:t,args:e})}return 0===n.length?{type:t,args:null}:1===n.length?n[0]:n}catch(i){return st.error(`ERROR: ${i.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}};function Kt(t,e){if(!t)return e;const i=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return Xt[i]??e}function te(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}const ee=(t,e=2)=>{const i=Math.pow(10,e);return Math.round(t*i)/i},ie=(t,e)=>{let i,r=e;for(const n of t){if(i){const t=te(n,i);if(t<r)r-=t;else{const e=r/t;if(e<=0)return i;if(e>=1)return{x:n.x,y:n.y};if(e>0&&e<1)return{x:ee((1-e)*i.x+e*n.x,5),y:ee((1-e)*i.y+e*n.y,5)}}}i=n}throw new Error("Could not find a suitable point for the given distance")};function re(t){let e="",i="";for(const r of t)void 0!==r&&(r.startsWith("color:")||r.startsWith("text-align:")?i=i+r+";":e=e+r+";");return{style:e,labelStyle:i}}let ne=0;const oe=()=>(ne++,"id-"+Math.random().toString(36).substr(2,12)+"-"+ne);const ae=t=>function(t){let e="";const i="0123456789abcdef";for(let r=0;r<t;r++)e+=i.charAt(Math.floor(16*Math.random()));return e}(t.length),se=function(t,e){const i=e.text.replace(_t.lineBreakRegex," "),[,r]=ge(e.fontSize),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.style("text-anchor",e.anchor),n.style("font-family",e.fontFamily),n.style("font-size",r),n.style("font-weight",e.fontWeight),n.attr("fill",e.fill),void 0!==e.class&&n.attr("class",e.class);const o=n.append("tspan");return o.attr("x",e.x+2*e.textMargin),o.attr("fill",e.fill),o.text(i),n},le=(0,y.Z)(((t,e,i)=>{if(!t)return t;if(i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"<br/>"},i),_t.lineBreakRegex.test(t))return t;const r=t.split(" "),n=[];let o="";return r.forEach(((t,a)=>{const s=ue(`${t} `,i),l=ue(o,i);if(s>e){const{hyphenatedStrings:r,remainingWord:a}=ce(t,e,"-",i);n.push(o,...r),o=a}else l+s>=e?(n.push(o),o=t):o=[o,t].filter(Boolean).join(" ");a+1===r.length&&n.push(o)})),n.filter((t=>""!==t)).join(i.joinWith)}),((t,e,i)=>`${t}${e}${i.fontSize}${i.fontWeight}${i.fontFamily}${i.joinWith}`)),ce=(0,y.Z)(((t,e,i="-",r)=>{r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);const n=[...t],o=[];let a="";return n.forEach(((t,s)=>{const l=`${a}${t}`;if(ue(l,r)>=e){const t=s+1,e=n.length===t,r=`${l}${i}`;o.push(e?l:r),a=""}else a=l})),{hyphenatedStrings:o,remainingWord:a}}),((t,e,i="-",r)=>`${t}${e}${i}${r.fontSize}${r.fontWeight}${r.fontFamily}`));function he(t,e){return de(t,e).height}function ue(t,e){return de(t,e).width}const de=(0,y.Z)(((t,e)=>{const{fontSize:i=12,fontFamily:r="Arial",fontWeight:n=400}=e;if(!t)return{width:0,height:0};const[,o]=ge(i),s=["sans-serif",r],l=t.split(_t.lineBreakRegex),c=[],h=(0,a.Ys)("body");if(!h.remove)return{width:0,height:0,lineHeight:0};const u=h.append("svg");for(const a of s){let t=0;const e={width:0,height:0,lineHeight:0};for(const i of l){const r={x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""};r.text=i||Gt;const s=se(u,r).style("font-size",o).style("font-weight",n).style("font-family",a),l=(s._groups||s)[0][0].getBBox();if(0===l.width&&0===l.height)throw new Error("svg element not in render tree");e.width=Math.round(Math.max(e.width,l.width)),t=Math.round(l.height),e.height+=t,e.lineHeight=Math.round(Math.max(e.lineHeight,t))}c.push(e)}u.remove();return c[isNaN(c[1].height)||isNaN(c[1].width)||isNaN(c[1].lineHeight)||c[0].height>c[1].height&&c[0].width>c[1].width&&c[0].lineHeight>c[1].lineHeight?0:1]}),((t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`));let fe;function pe(t){return"str"in t}const ge=t=>{if("number"==typeof t)return[t,t+"px"];const e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]};function me(t,e){return(0,x.Z)({},t,e)}const ye={assignWithDepth:Vt,wrapLabel:le,calculateTextHeight:he,calculateTextWidth:ue,calculateTextDimensions:de,cleanAndMerge:me,detectInit:function(t,e){const i=Jt(t,/(?:init\b)|(?:initialize\b)/);let r={};if(Array.isArray(i)){const t=i.map((t=>t.args));jt(t),r=Vt(r,[...t])}else r=i.args;if(!r)return;let n=Wt(t,e);const o="config";return void 0!==r[o]&&("flowchart-v2"===n&&(n="flowchart"),r[n]=r[o],delete r[o]),r},detectDirective:Jt,isSubstringInArray:function(t,e){for(const[i,r]of e.entries())if(r.match(t))return i;return-1},interpolateToCurve:Kt,calcLabelPosition:function(t){return 1===t.length?t[0]:function(t){let e,i=0;return t.forEach((t=>{i+=te(t,e),e=t})),ie(t,i/2)}(t)},calcCardinalityPosition:(t,e,i)=>{st.info(`our points ${JSON.stringify(e)}`),e[0]!==i&&(e=e.reverse());const r=ie(e,25),n=t?10:5,o=Math.atan2(e[0].y-r.y,e[0].x-r.x),a={x:0,y:0};return a.x=Math.sin(o)*n+(e[0].x+r.x)/2,a.y=-Math.cos(o)*n+(e[0].y+r.y)/2,a},calcTerminalLabelPosition:function(t,e,i){const r=structuredClone(i);st.info("our points",r),"start_left"!==e&&"start_right"!==e&&r.reverse();const n=ie(r,25+t),o=10+.5*t,a=Math.atan2(r[0].y-n.y,r[0].x-n.x),s={x:0,y:0};return"start_left"===e?(s.x=Math.sin(a+Math.PI)*o+(r[0].x+n.x)/2,s.y=-Math.cos(a+Math.PI)*o+(r[0].y+n.y)/2):"end_right"===e?(s.x=Math.sin(a-Math.PI)*o+(r[0].x+n.x)/2-5,s.y=-Math.cos(a-Math.PI)*o+(r[0].y+n.y)/2-5):"end_left"===e?(s.x=Math.sin(a)*o+(r[0].x+n.x)/2-5,s.y=-Math.cos(a)*o+(r[0].y+n.y)/2-5):(s.x=Math.sin(a)*o+(r[0].x+n.x)/2,s.y=-Math.cos(a)*o+(r[0].y+n.y)/2),s},formatUrl:function(t,e){const i=t.trim();if(i)return"loose"!==e.securityLevel?(0,o.Nm)(i):i},getStylesFromArray:re,generateId:oe,random:ae,runFunc:(t,...e)=>{const i=t.split("."),r=i.length-1,n=i[r];let o=window;for(let a=0;a<r;a++)if(o=o[i[a]],!o)return void st.error(`Function name: ${t} not found in window`);o[n](...e)},entityDecode:function(t){return fe=fe||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),fe.innerHTML=t,unescape(fe.textContent)},insertTitle:(t,e,i,r)=>{var n;if(!r)return;const o=null==(n=t.node())?void 0:n.getBBox();o&&t.append("text").text(r).attr("x",o.x+o.width/2).attr("y",-i).attr("class",e)},parseFontSize:ge,InitIDGenerator:class{constructor(t=!1,e){this.count=0,this.count=e?e.length:0,this.next=t?()=>this.count++:()=>Date.now()}}},xe="10.6.0",Ce=Object.freeze(It);let be,_e=Vt({},Ce),ve=[],ke=Vt({},Ce);const Te=(t,e)=>{let i=Vt({},t),r={};for(const n of e)Fe(n),r=Vt(r,n);if(i=Vt(i,r),r.theme&&r.theme in Mt){const t=Vt({},be),e=Vt(t.themeVariables||{},r.themeVariables);i.theme&&i.theme in Mt&&(i.themeVariables=Mt[i.theme].getThemeVariables(e))}return ke=i,Ze(ke),ke},we=()=>Vt({},_e),Se=t=>(Ze(t),Vt(ke,t),Be()),Be=()=>Vt({},ke),Fe=t=>{t&&(["secure",..._e.secure??[]].forEach((e=>{Object.hasOwn(t,e)&&(st.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])})),Object.keys(t).forEach((e=>{e.startsWith("__")&&delete t[e]})),Object.keys(t).forEach((e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&Fe(t[e])})))},Ae=t=>{jt(t),!t.fontFamily||t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily}),ve.push(t),Te(_e,ve)},Le=(t=_e)=>{ve=[],Te(t,ve)},Me={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},Ee={},Ze=t=>{var e;t&&((t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&(Ee[e="LAZY_LOAD_DEPRECATED"]||(st.warn(Me[e]),Ee[e]=!0)))},Ne={id:"c4",detector:t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),loader:async()=>{const{diagram:t}=await i.e(7111).then(i.bind(i,67111));return{id:"c4",diagram:t}}},Oe="flowchart",Ie={id:Oe,detector:(t,e)=>{var i,r;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&/^\s*graph/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1644),i.e(4697),i.e(7707),i.e(360),i.e(5254),i.e(9205)]).then(i.bind(i,69205));return{id:Oe,diagram:t}}},je="flowchart-v2",qe={id:je,detector:(t,e)=>{var i,r,n;return"dagre-d3"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&(!(!/^\s*graph/.test(t)||"dagre-wrapper"!==(null==(n=null==e?void 0:e.flowchart)?void 0:n.defaultRenderer))||/^\s*flowchart/.test(t))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1644),i.e(4697),i.e(7707),i.e(360),i.e(5254),i.e(8371)]).then(i.bind(i,18371));return{id:je,diagram:t}}},De={id:"er",detector:t=>/^\s*erDiagram/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(1644),i.e(5373)]).then(i.bind(i,45373));return{id:"er",diagram:t}}},$e="gitGraph",ze={id:$e,detector:t=>/^\s*gitGraph/.test(t),loader:async()=>{const{diagram:t}=await i.e(6715).then(i.bind(i,46715));return{id:$e,diagram:t}}},Pe="gantt",Re={id:Pe,detector:t=>/^\s*gantt/.test(t),loader:async()=>{const{diagram:t}=await i.e(762).then(i.bind(i,80762));return{id:Pe,diagram:t}}},We="info",He={id:We,detector:t=>/^\s*info/.test(t),loader:async()=>{const{diagram:t}=await i.e(2027).then(i.bind(i,42027));return{id:We,diagram:t}}},Ue={id:"pie",detector:t=>/^\s*pie/.test(t),loader:async()=>{const{diagram:t}=await i.e(8365).then(i.bind(i,88365));return{id:"pie",diagram:t}}},Ye="quadrantChart",Ve={id:Ye,detector:t=>/^\s*quadrantChart/.test(t),loader:async()=>{const{diagram:t}=await i.e(6254).then(i.bind(i,86254));return{id:Ye,diagram:t}}},Ge="xychart",Xe={id:Ge,detector:t=>/^\s*xychart-beta/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(4697),i.e(8687)]).then(i.bind(i,78687));return{id:Ge,diagram:t}}},Qe="requirement",Je={id:Qe,detector:t=>/^\s*requirement(Diagram)?/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(1644),i.e(8189)]).then(i.bind(i,18189));return{id:Qe,diagram:t}}},Ke="sequence",ti={id:Ke,detector:t=>/^\s*sequenceDiagram/.test(t),loader:async()=>{const{diagram:t}=await i.e(3601).then(i.bind(i,43601));return{id:Ke,diagram:t}}},ei="class",ii={id:ei,detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer)&&/^\s*classDiagram/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1644),i.e(2127),i.e(6046)]).then(i.bind(i,76046));return{id:ei,diagram:t}}},ri="classDiagram",ni={id:ri,detector:(t,e)=>{var i;return!(!/^\s*classDiagram/.test(t)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer))||/^\s*classDiagram-v2/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1644),i.e(4697),i.e(7707),i.e(360),i.e(2127),i.e(1688)]).then(i.bind(i,11688));return{id:ri,diagram:t}}},oi="state",ai={id:oi,detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer)&&/^\s*stateDiagram/.test(t)},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1644),i.e(2244),i.e(9816)]).then(i.bind(i,9816));return{id:oi,diagram:t}}},si="stateDiagram",li={id:si,detector:(t,e)=>{var i;return!!/^\s*stateDiagram-v2/.test(t)||!(!/^\s*stateDiagram/.test(t)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(1644),i.e(4697),i.e(7707),i.e(360),i.e(2244),i.e(6284)]).then(i.bind(i,66284));return{id:si,diagram:t}}},ci="journey",hi={id:ci,detector:t=>/^\s*journey/.test(t),loader:async()=>{const{diagram:t}=await i.e(3506).then(i.bind(i,33506));return{id:ci,diagram:t}}},ui=function(t,e,i,r){const n=function(t,e,i){let r=new Map;return i?(r.set("width","100%"),r.set("style",`max-width: ${e}px;`)):(r.set("height",t),r.set("width",e)),r}(e,i,r);!function(t,e){for(let i of e)t.attr(i[0],i[1])}(t,n)},di=function(t,e,i,r){const n=e.node().getBBox(),o=n.width,a=n.height;st.info(`SVG bounds: ${o}x${a}`,n);let s=0,l=0;st.info(`Graph bounds: ${s}x${l}`,t),s=o+2*i,l=a+2*i,st.info(`Calculated bounds: ${s}x${l}`),ui(e,l,s,r);const c=`${n.x-i} ${n.y-i} ${n.width+2*i} ${n.height+2*i}`;e.attr("viewBox",c)},fi={},pi=(t,e,i)=>{let r="";return t in fi&&fi[t]?r=fi[t](i):st.warn(`No theme found for ${t}`),` & {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n fill: ${i.textColor}\n }\n\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${i.errorBkgColor};\n }\n & .error-text {\n fill: ${i.errorTextColor};\n stroke: ${i.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 2px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${i.lineColor};\n stroke: ${i.lineColor};\n }\n & .marker.cross {\n stroke: ${i.lineColor};\n }\n\n & svg {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n }\n\n ${r}\n\n ${e}\n`};let gi="",mi="",yi="";const xi=t=>ft(t,Be()),Ci=()=>{gi="",yi="",mi=""},bi=t=>{gi=xi(t).replace(/^\s+/g,"")},_i=()=>gi,vi=t=>{yi=xi(t).replace(/\n\s+/g,"\n")},ki=()=>yi,Ti=t=>{mi=xi(t)},wi=()=>mi,Si=Object.freeze(Object.defineProperty({__proto__:null,clear:Ci,getAccDescription:ki,getAccTitle:_i,getDiagramTitle:wi,setAccDescription:vi,setAccTitle:bi,setDiagramTitle:Ti},Symbol.toStringTag,{value:"Module"})),Bi=st,Fi=lt,Ai=Be,Li=Se,Mi=Ce,Ei=t=>ft(t,Ai()),Zi=di,Ni={},Oi=(t,e,i)=>{var r,n,o;if(Ni[t])throw new Error(`Diagram ${t} already registered.`);Ni[t]=e,i&&Ut(t,i),n=t,void 0!==(o=e.styles)&&(fi[n]=o),null==(r=e.injectUtils)||r.call(e,Bi,Fi,Ai,Ei,Zi,Si,(()=>{}))},Ii=t=>{if(t in Ni)return Ni[t];throw new ji(t)};class ji extends Error{constructor(t){super(`Diagram ${t} not found.`)}}const qi=t=>{var e;const{securityLevel:i}=Ai();let r=(0,a.Ys)("body");if("sandbox"===i){const i=(null==(e=(0,a.Ys)(`#i${t}`).node())?void 0:e.contentDocument)??document;r=(0,a.Ys)(i.body)}return r.select(`#${t}`)},Di={draw:(t,e,i)=>{st.debug("renering svg for syntax error\n");const r=qi(e);r.attr("viewBox","0 0 2412 512"),ui(r,100,512,!0);const n=r.append("g");n.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),n.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),n.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),n.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),n.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),n.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),n.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),n.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${i}`)}},$i=Di,zi={db:{},renderer:Di,parser:{parser:{yy:{}},parse:()=>{}}},Pi="flowchart-elk",Ri={id:Pi,detector:(t,e)=>{var i;return!!(/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&"elk"===(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await Promise.all([i.e(4697),i.e(7707),i.e(5254),i.e(5705)]).then(i.bind(i,47740));return{id:Pi,diagram:t}}},Wi="timeline",Hi={id:Wi,detector:t=>/^\s*timeline/.test(t),loader:async()=>{const{diagram:t}=await i.e(9469).then(i.bind(i,9469));return{id:Wi,diagram:t}}},Ui="mindmap",Yi={id:Ui,detector:t=>/^\s*mindmap/.test(t),loader:async()=>{const{diagram:t}=await Promise.all([i.e(4697),i.e(7807)]).then(i.bind(i,87807));return{id:Ui,diagram:t}}},Vi="sankey",Gi={id:Vi,detector:t=>/^\s*sankey-beta/.test(t),loader:async()=>{const{diagram:t}=await i.e(6278).then(i.bind(i,36278));return{id:Vi,diagram:t}}};let Xi=!1;const Qi=()=>{Xi||(Xi=!0,Oi("error",zi,(t=>"error"===t.toLowerCase().trim())),Oi("---",{db:{clear:()=>{}},styles:{},renderer:{draw:()=>{}},parser:{parser:{yy:{}},parse:()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")}},init:()=>null},(t=>t.toLowerCase().trimStart().startsWith("---"))),Ht(Ne,ni,ii,De,Re,He,Ue,Je,ti,Ri,qe,Ie,Yi,Hi,ze,li,ai,hi,Ve,Gi,Xe))};class Ji{constructor(t,e={}){this.text=t,this.metadata=e,this.type="graph",this.text+="\n";const i=Be();try{this.type=Wt(t,i)}catch(n){this.type="error",this.detectError=n}const r=Ii(this.type);st.debug("Type "+this.type),this.db=r.db,this.renderer=r.renderer,this.parser=r.parser,this.parser.parser.yy=this.db,this.init=r.init,this.parse()}parse(){var t,e,i,r,n;if(this.detectError)throw this.detectError;null==(e=(t=this.db).clear)||e.call(t);const o=Be();null==(i=this.init)||i.call(this,o),this.metadata.title&&(null==(n=(r=this.db).setDiagramTitle)||n.call(r,this.metadata.title)),this.parser.parse(this.text)}async render(t,e){await this.renderer.draw(this.text,t,e,this)}getParser(){return this.parser}getType(){return this.type}}const Ki=async(t,e={})=>{const i=Wt(t,Be());try{Ii(i)}catch(r){const t=Rt[i].loader;if(!t)throw new Pt(`Diagram ${i} not found.`);const{id:e,diagram:n}=await t();Oi(e,n)}return new Ji(t,e)};let tr=[];const er=t=>{tr.push(t)},ir="graphics-document document";const rr=t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart();function nr(t){return null==t}var or={isNothing:nr,isObject:function(t){return"object"==typeof t&&null!==t},toArray:function(t){return Array.isArray(t)?t:nr(t)?[]:[t]},repeat:function(t,e){var i,r="";for(i=0;i<e;i+=1)r+=t;return r},isNegativeZero:function(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t},extend:function(t,e){var i,r,n,o;if(e)for(i=0,r=(o=Object.keys(e)).length;i<r;i+=1)t[n=o[i]]=e[n];return t}};function ar(t,e){var i="",r=t.reason||"(unknown reason)";return t.mark?(t.mark.name&&(i+='in "'+t.mark.name+'" '),i+="("+(t.mark.line+1)+":"+(t.mark.column+1)+")",!e&&t.mark.snippet&&(i+="\n\n"+t.mark.snippet),r+" "+i):r}function sr(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=ar(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}sr.prototype=Object.create(Error.prototype),sr.prototype.constructor=sr,sr.prototype.toString=function(t){return this.name+": "+ar(this,t)};var lr=sr;function cr(t,e,i,r,n){var o="",a="",s=Math.floor(n/2)-1;return r-e>s&&(e=r-s+(o=" ... ").length),i-r>s&&(i=r+s-(a=" ...").length),{str:o+t.slice(e,i).replace(/\t/g,"\u2192")+a,pos:r-e+o.length}}function hr(t,e){return or.repeat(" ",e-t.length)+t}var ur=function(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var i,r=/\r?\n|\r|\0/g,n=[0],o=[],a=-1;i=r.exec(t.buffer);)o.push(i.index),n.push(i.index+i[0].length),t.position<=i.index&&a<0&&(a=n.length-2);a<0&&(a=n.length-1);var s,l,c="",h=Math.min(t.line+e.linesAfter,o.length).toString().length,u=e.maxLength-(e.indent+h+3);for(s=1;s<=e.linesBefore&&!(a-s<0);s++)l=cr(t.buffer,n[a-s],o[a-s],t.position-(n[a]-n[a-s]),u),c=or.repeat(" ",e.indent)+hr((t.line-s+1).toString(),h)+" | "+l.str+"\n"+c;for(l=cr(t.buffer,n[a],o[a],t.position,u),c+=or.repeat(" ",e.indent)+hr((t.line+1).toString(),h)+" | "+l.str+"\n",c+=or.repeat("-",e.indent+h+3+l.pos)+"^\n",s=1;s<=e.linesAfter&&!(a+s>=o.length);s++)l=cr(t.buffer,n[a+s],o[a+s],t.position-(n[a]-n[a+s]),u),c+=or.repeat(" ",e.indent)+hr((t.line+s+1).toString(),h)+" | "+l.str+"\n";return c.replace(/\n$/,"")},dr=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],fr=["scalar","sequence","mapping"];var pr=function(t,e){var i,r;if(e=e||{},Object.keys(e).forEach((function(e){if(-1===dr.indexOf(e))throw new lr('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=(i=e.styleAliases||null,r={},null!==i&&Object.keys(i).forEach((function(t){i[t].forEach((function(e){r[String(e)]=t}))})),r),-1===fr.indexOf(this.kind))throw new lr('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')};function gr(t,e){var i=[];return t[e].forEach((function(t){var e=i.length;i.forEach((function(i,r){i.tag===t.tag&&i.kind===t.kind&&i.multi===t.multi&&(e=r)})),i[e]=t})),i}function mr(t){return this.extend(t)}mr.prototype.extend=function(t){var e=[],i=[];if(t instanceof pr)i.push(t);else if(Array.isArray(t))i=i.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new lr("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(i=i.concat(t.explicit))}e.forEach((function(t){if(!(t instanceof pr))throw new lr("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new lr("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new lr("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),i.forEach((function(t){if(!(t instanceof pr))throw new lr("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var r=Object.create(mr.prototype);return r.implicit=(this.implicit||[]).concat(e),r.explicit=(this.explicit||[]).concat(i),r.compiledImplicit=gr(r,"implicit"),r.compiledExplicit=gr(r,"explicit"),r.compiledTypeMap=function(){var t,e,i={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function r(t){t.multi?(i.multi[t.kind].push(t),i.multi.fallback.push(t)):i[t.kind][t.tag]=i.fallback[t.tag]=t}for(t=0,e=arguments.length;t<e;t+=1)arguments[t].forEach(r);return i}(r.compiledImplicit,r.compiledExplicit),r};var yr=new mr({explicit:[new pr("tag:yaml.org,2002:str",{kind:"scalar",construct:function(t){return null!==t?t:""}}),new pr("tag:yaml.org,2002:seq",{kind:"sequence",construct:function(t){return null!==t?t:[]}}),new pr("tag:yaml.org,2002:map",{kind:"mapping",construct:function(t){return null!==t?t:{}}})]});var xr=new pr("tag:yaml.org,2002:null",{kind:"scalar",resolve:function(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)},construct:function(){return null},predicate:function(t){return null===t},represent:{canonical:function(){return"~"},lowercase:function(){return"null"},uppercase:function(){return"NULL"},camelcase:function(){return"Null"},empty:function(){return""}},defaultStyle:"lowercase"});var Cr=new pr("tag:yaml.org,2002:bool",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)},construct:function(t){return"true"===t||"True"===t||"TRUE"===t},predicate:function(t){return"[object Boolean]"===Object.prototype.toString.call(t)},represent:{lowercase:function(t){return t?"true":"false"},uppercase:function(t){return t?"TRUE":"FALSE"},camelcase:function(t){return t?"True":"False"}},defaultStyle:"lowercase"});function br(t){return 48<=t&&t<=55}function _r(t){return 48<=t&&t<=57}var vr=new pr("tag:yaml.org,2002:int",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=t.length,n=0,o=!1;if(!r)return!1;if("-"!==(e=t[n])&&"+"!==e||(e=t[++n]),"0"===e){if(n+1===r)return!0;if("b"===(e=t[++n])){for(n++;n<r;n++)if("_"!==(e=t[n])){if("0"!==e&&"1"!==e)return!1;o=!0}return o&&"_"!==e}if("x"===e){for(n++;n<r;n++)if("_"!==(e=t[n])){if(!(48<=(i=t.charCodeAt(n))&&i<=57||65<=i&&i<=70||97<=i&&i<=102))return!1;o=!0}return o&&"_"!==e}if("o"===e){for(n++;n<r;n++)if("_"!==(e=t[n])){if(!br(t.charCodeAt(n)))return!1;o=!0}return o&&"_"!==e}}if("_"===e)return!1;for(;n<r;n++)if("_"!==(e=t[n])){if(!_r(t.charCodeAt(n)))return!1;o=!0}return!(!o||"_"===e)},construct:function(t){var e,i=t,r=1;if(-1!==i.indexOf("_")&&(i=i.replace(/_/g,"")),"-"!==(e=i[0])&&"+"!==e||("-"===e&&(r=-1),e=(i=i.slice(1))[0]),"0"===i)return 0;if("0"===e){if("b"===i[1])return r*parseInt(i.slice(2),2);if("x"===i[1])return r*parseInt(i.slice(2),16);if("o"===i[1])return r*parseInt(i.slice(2),8)}return r*parseInt(i,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&t%1==0&&!or.isNegativeZero(t)},represent:{binary:function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),kr=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");var Tr=/^[-+]?[0-9]+e/;var wr=new pr("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(t){return null!==t&&!(!kr.test(t)||"_"===t[t.length-1])},construct:function(t){var e,i;return i="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===i?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:i*parseFloat(e,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||or.isNegativeZero(t))},represent:function(t,e){var i;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(or.isNegativeZero(t))return"-0.0";return i=t.toString(10),Tr.test(i)?i.replace("e",".e"):i},defaultStyle:"lowercase"}),Sr=yr.extend({implicit:[xr,Cr,vr,wr]}),Br=Sr,Fr=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),Ar=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");var Lr=new pr("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(t){return null!==t&&(null!==Fr.exec(t)||null!==Ar.exec(t))},construct:function(t){var e,i,r,n,o,a,s,l,c=0,h=null;if(null===(e=Fr.exec(t))&&(e=Ar.exec(t)),null===e)throw new Error("Date resolve error");if(i=+e[1],r=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(i,r,n));if(o=+e[4],a=+e[5],s=+e[6],e[7]){for(c=e[7].slice(0,3);c.length<3;)c+="0";c=+c}return e[9]&&(h=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(h=-h)),l=new Date(Date.UTC(i,r,n,o,a,s,c)),h&&l.setTime(l.getTime()-h),l},instanceOf:Date,represent:function(t){return t.toISOString()}});var Mr=new pr("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(t){return"<<"===t||null===t}}),Er="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";var Zr=new pr("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=0,n=t.length,o=Er;for(i=0;i<n;i++)if(!((e=o.indexOf(t.charAt(i)))>64)){if(e<0)return!1;r+=6}return r%8==0},construct:function(t){var e,i,r=t.replace(/[\r\n=]/g,""),n=r.length,o=Er,a=0,s=[];for(e=0;e<n;e++)e%4==0&&e&&(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)),a=a<<6|o.indexOf(r.charAt(e));return 0===(i=n%4*6)?(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)):18===i?(s.push(a>>10&255),s.push(a>>2&255)):12===i&&s.push(a>>4&255),new Uint8Array(s)},predicate:function(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)},represent:function(t){var e,i,r="",n=0,o=t.length,a=Er;for(e=0;e<o;e++)e%3==0&&e&&(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]),n=(n<<8)+t[e];return 0===(i=o%3)?(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]):2===i?(r+=a[n>>10&63],r+=a[n>>4&63],r+=a[n<<2&63],r+=a[64]):1===i&&(r+=a[n>>2&63],r+=a[n<<4&63],r+=a[64],r+=a[64]),r}}),Nr=Object.prototype.hasOwnProperty,Or=Object.prototype.toString;var Ir=new pr("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=[],s=t;for(e=0,i=s.length;e<i;e+=1){if(r=s[e],o=!1,"[object Object]"!==Or.call(r))return!1;for(n in r)if(Nr.call(r,n)){if(o)return!1;o=!0}if(!o)return!1;if(-1!==a.indexOf(n))return!1;a.push(n)}return!0},construct:function(t){return null!==t?t:[]}}),jr=Object.prototype.toString;var qr=new pr("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=t;for(o=new Array(a.length),e=0,i=a.length;e<i;e+=1){if(r=a[e],"[object Object]"!==jr.call(r))return!1;if(1!==(n=Object.keys(r)).length)return!1;o[e]=[n[0],r[n[0]]]}return!0},construct:function(t){if(null===t)return[];var e,i,r,n,o,a=t;for(o=new Array(a.length),e=0,i=a.length;e<i;e+=1)r=a[e],n=Object.keys(r),o[e]=[n[0],r[n[0]]];return o}}),Dr=Object.prototype.hasOwnProperty;var $r=new pr("tag:yaml.org,2002:set",{kind:"mapping",resolve:function(t){if(null===t)return!0;var e,i=t;for(e in i)if(Dr.call(i,e)&&null!==i[e])return!1;return!0},construct:function(t){return null!==t?t:{}}}),zr=Br.extend({implicit:[Lr,Mr],explicit:[Zr,Ir,qr,$r]}),Pr=Object.prototype.hasOwnProperty,Rr=1,Wr=2,Hr=3,Ur=4,Yr=1,Vr=2,Gr=3,Xr=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,Qr=/[\x85\u2028\u2029]/,Jr=/[,\[\]\{\}]/,Kr=/^(?:!|!!|![a-z\-]+!)$/i,tn=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function en(t){return Object.prototype.toString.call(t)}function rn(t){return 10===t||13===t}function nn(t){return 9===t||32===t}function on(t){return 9===t||32===t||10===t||13===t}function an(t){return 44===t||91===t||93===t||123===t||125===t}function sn(t){var e;return 48<=t&&t<=57?t-48:97<=(e=32|t)&&e<=102?e-97+10:-1}function ln(t){return 48===t?"\0":97===t?"\x07":98===t?"\b":116===t||9===t?"\t":110===t?"\n":118===t?"\v":102===t?"\f":114===t?"\r":101===t?"\x1b":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"\x85":95===t?"\xa0":76===t?"\u2028":80===t?"\u2029":""}function cn(t){return t<=65535?String.fromCharCode(t):String.fromCharCode(55296+(t-65536>>10),56320+(t-65536&1023))}for(var hn=new Array(256),un=new Array(256),dn=0;dn<256;dn++)hn[dn]=ln(dn)?1:0,un[dn]=ln(dn);function fn(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||zr,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function pn(t,e){var i={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return i.snippet=ur(i),new lr(e,i)}function gn(t,e){throw pn(t,e)}function mn(t,e){t.onWarning&&t.onWarning.call(null,pn(t,e))}var yn={YAML:function(t,e,i){var r,n,o;null!==t.version&&gn(t,"duplication of %YAML directive"),1!==i.length&&gn(t,"YAML directive accepts exactly one argument"),null===(r=/^([0-9]+)\.([0-9]+)$/.exec(i[0]))&&gn(t,"ill-formed argument of the YAML directive"),n=parseInt(r[1],10),o=parseInt(r[2],10),1!==n&&gn(t,"unacceptable YAML version of the document"),t.version=i[0],t.checkLineBreaks=o<2,1!==o&&2!==o&&mn(t,"unsupported YAML version of the document")},TAG:function(t,e,i){var r,n;2!==i.length&&gn(t,"TAG directive accepts exactly two arguments"),r=i[0],n=i[1],Kr.test(r)||gn(t,"ill-formed tag handle (first argument) of the TAG directive"),Pr.call(t.tagMap,r)&&gn(t,'there is a previously declared suffix for "'+r+'" tag handle'),tn.test(n)||gn(t,"ill-formed tag prefix (second argument) of the TAG directive");try{n=decodeURIComponent(n)}catch(o){gn(t,"tag prefix is malformed: "+n)}t.tagMap[r]=n}};function xn(t,e,i,r){var n,o,a,s;if(e<i){if(s=t.input.slice(e,i),r)for(n=0,o=s.length;n<o;n+=1)9===(a=s.charCodeAt(n))||32<=a&&a<=1114111||gn(t,"expected valid JSON character");else Xr.test(s)&&gn(t,"the stream contains non-printable characters");t.result+=s}}function Cn(t,e,i,r){var n,o,a,s;for(or.isObject(i)||gn(t,"cannot merge mappings; the provided source object is unacceptable"),a=0,s=(n=Object.keys(i)).length;a<s;a+=1)o=n[a],Pr.call(e,o)||(e[o]=i[o],r[o]=!0)}function bn(t,e,i,r,n,o,a,s,l){var c,h;if(Array.isArray(n))for(c=0,h=(n=Array.prototype.slice.call(n)).length;c<h;c+=1)Array.isArray(n[c])&&gn(t,"nested arrays are not supported inside keys"),"object"==typeof n&&"[object Object]"===en(n[c])&&(n[c]="[object Object]");if("object"==typeof n&&"[object Object]"===en(n)&&(n="[object Object]"),n=String(n),null===e&&(e={}),"tag:yaml.org,2002:merge"===r)if(Array.isArray(o))for(c=0,h=o.length;c<h;c+=1)Cn(t,e,o[c],i);else Cn(t,e,o,i);else t.json||Pr.call(i,n)||!Pr.call(e,n)||(t.line=a||t.line,t.lineStart=s||t.lineStart,t.position=l||t.position,gn(t,"duplicated mapping key")),"__proto__"===n?Object.defineProperty(e,n,{configurable:!0,enumerable:!0,writable:!0,value:o}):e[n]=o,delete i[n];return e}function _n(t){var e;10===(e=t.input.charCodeAt(t.position))?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):gn(t,"a line break is expected"),t.line+=1,t.lineStart=t.position,t.firstTabInLine=-1}function vn(t,e,i){for(var r=0,n=t.input.charCodeAt(t.position);0!==n;){for(;nn(n);)9===n&&-1===t.firstTabInLine&&(t.firstTabInLine=t.position),n=t.input.charCodeAt(++t.position);if(e&&35===n)do{n=t.input.charCodeAt(++t.position)}while(10!==n&&13!==n&&0!==n);if(!rn(n))break;for(_n(t),n=t.input.charCodeAt(t.position),r++,t.lineIndent=0;32===n;)t.lineIndent++,n=t.input.charCodeAt(++t.position)}return-1!==i&&0!==r&&t.lineIndent<i&&mn(t,"deficient indentation"),r}function kn(t){var e,i=t.position;return!(45!==(e=t.input.charCodeAt(i))&&46!==e||e!==t.input.charCodeAt(i+1)||e!==t.input.charCodeAt(i+2)||(i+=3,0!==(e=t.input.charCodeAt(i))&&!on(e)))}function Tn(t,e){1===e?t.result+=" ":e>1&&(t.result+=or.repeat("\n",e-1))}function wn(t,e){var i,r,n=t.tag,o=t.anchor,a=[],s=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),r=t.input.charCodeAt(t.position);0!==r&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,gn(t,"tab characters must not be used in indentation")),45===r)&&on(t.input.charCodeAt(t.position+1));)if(s=!0,t.position++,vn(t,!0,-1)&&t.lineIndent<=e)a.push(null),r=t.input.charCodeAt(t.position);else if(i=t.line,Fn(t,e,Hr,!1,!0),a.push(t.result),vn(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===i||t.lineIndent>e)&&0!==r)gn(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return!!s&&(t.tag=n,t.anchor=o,t.kind="sequence",t.result=a,!0)}function Sn(t){var e,i,r,n,o=!1,a=!1;if(33!==(n=t.input.charCodeAt(t.position)))return!1;if(null!==t.tag&&gn(t,"duplication of a tag property"),60===(n=t.input.charCodeAt(++t.position))?(o=!0,n=t.input.charCodeAt(++t.position)):33===n?(a=!0,i="!!",n=t.input.charCodeAt(++t.position)):i="!",e=t.position,o){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&62!==n);t.position<t.length?(r=t.input.slice(e,t.position),n=t.input.charCodeAt(++t.position)):gn(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==n&&!on(n);)33===n&&(a?gn(t,"tag suffix cannot contain exclamation marks"):(i=t.input.slice(e-1,t.position+1),Kr.test(i)||gn(t,"named tag handle cannot contain such characters"),a=!0,e=t.position+1)),n=t.input.charCodeAt(++t.position);r=t.input.slice(e,t.position),Jr.test(r)&&gn(t,"tag suffix cannot contain flow indicator characters")}r&&!tn.test(r)&&gn(t,"tag name cannot contain such characters: "+r);try{r=decodeURIComponent(r)}catch(s){gn(t,"tag name is malformed: "+r)}return o?t.tag=r:Pr.call(t.tagMap,i)?t.tag=t.tagMap[i]+r:"!"===i?t.tag="!"+r:"!!"===i?t.tag="tag:yaml.org,2002:"+r:gn(t,'undeclared tag handle "'+i+'"'),!0}function Bn(t){var e,i;if(38!==(i=t.input.charCodeAt(t.position)))return!1;for(null!==t.anchor&&gn(t,"duplication of an anchor property"),i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!on(i)&&!an(i);)i=t.input.charCodeAt(++t.position);return t.position===e&&gn(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function Fn(t,e,i,r,n){var o,a,s,l,c,h,u,d,f,p=1,g=!1,m=!1;if(null!==t.listener&&t.listener("open",t),t.tag=null,t.anchor=null,t.kind=null,t.result=null,o=a=s=Ur===i||Hr===i,r&&vn(t,!0,-1)&&(g=!0,t.lineIndent>e?p=1:t.lineIndent===e?p=0:t.lineIndent<e&&(p=-1)),1===p)for(;Sn(t)||Bn(t);)vn(t,!0,-1)?(g=!0,s=o,t.lineIndent>e?p=1:t.lineIndent===e?p=0:t.lineIndent<e&&(p=-1)):s=!1;if(s&&(s=g||n),1!==p&&Ur!==i||(d=Rr===i||Wr===i?e:e+1,f=t.position-t.lineStart,1===p?s&&(wn(t,f)||function(t,e,i){var r,n,o,a,s,l,c,h=t.tag,u=t.anchor,d={},f=Object.create(null),p=null,g=null,m=null,y=!1,x=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=d),c=t.input.charCodeAt(t.position);0!==c;){if(y||-1===t.firstTabInLine||(t.position=t.firstTabInLine,gn(t,"tab characters must not be used in indentation")),r=t.input.charCodeAt(t.position+1),o=t.line,63!==c&&58!==c||!on(r)){if(a=t.line,s=t.lineStart,l=t.position,!Fn(t,i,Wr,!1,!0))break;if(t.line===o){for(c=t.input.charCodeAt(t.position);nn(c);)c=t.input.charCodeAt(++t.position);if(58===c)on(c=t.input.charCodeAt(++t.position))||gn(t,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(bn(t,d,f,p,g,null,a,s,l),p=g=m=null),x=!0,y=!1,n=!1,p=t.tag,g=t.result;else{if(!x)return t.tag=h,t.anchor=u,!0;gn(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!x)return t.tag=h,t.anchor=u,!0;gn(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(y&&(bn(t,d,f,p,g,null,a,s,l),p=g=m=null),x=!0,y=!0,n=!0):y?(y=!1,n=!0):gn(t,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),t.position+=1,c=r;if((t.line===o||t.lineIndent>e)&&(y&&(a=t.line,s=t.lineStart,l=t.position),Fn(t,e,Ur,!0,n)&&(y?g=t.result:m=t.result),y||(bn(t,d,f,p,g,m,a,s,l),p=g=m=null),vn(t,!0,-1),c=t.input.charCodeAt(t.position)),(t.line===o||t.lineIndent>e)&&0!==c)gn(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return y&&bn(t,d,f,p,g,null,a,s,l),x&&(t.tag=h,t.anchor=u,t.kind="mapping",t.result=d),x}(t,f,d))||function(t,e){var i,r,n,o,a,s,l,c,h,u,d,f,p=!0,g=t.tag,m=t.anchor,y=Object.create(null);if(91===(f=t.input.charCodeAt(t.position)))a=93,c=!1,o=[];else{if(123!==f)return!1;a=125,c=!0,o={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=o),f=t.input.charCodeAt(++t.position);0!==f;){if(vn(t,!0,e),(f=t.input.charCodeAt(t.position))===a)return t.position++,t.tag=g,t.anchor=m,t.kind=c?"mapping":"sequence",t.result=o,!0;p?44===f&&gn(t,"expected the node content, but found ','"):gn(t,"missed comma between flow collection entries"),d=null,s=l=!1,63===f&&on(t.input.charCodeAt(t.position+1))&&(s=l=!0,t.position++,vn(t,!0,e)),i=t.line,r=t.lineStart,n=t.position,Fn(t,e,Rr,!1,!0),u=t.tag,h=t.result,vn(t,!0,e),f=t.input.charCodeAt(t.position),!l&&t.line!==i||58!==f||(s=!0,f=t.input.charCodeAt(++t.position),vn(t,!0,e),Fn(t,e,Rr,!1,!0),d=t.result),c?bn(t,o,y,u,h,d,i,r,n):s?o.push(bn(t,null,y,u,h,d,i,r,n)):o.push(h),vn(t,!0,e),44===(f=t.input.charCodeAt(t.position))?(p=!0,f=t.input.charCodeAt(++t.position)):p=!1}gn(t,"unexpected end of the stream within a flow collection")}(t,d)?m=!0:(a&&function(t,e){var i,r,n,o,a,s=Yr,l=!1,c=!1,h=e,u=0,d=!1;if(124===(o=t.input.charCodeAt(t.position)))r=!1;else{if(62!==o)return!1;r=!0}for(t.kind="scalar",t.result="";0!==o;)if(43===(o=t.input.charCodeAt(++t.position))||45===o)Yr===s?s=43===o?Gr:Vr:gn(t,"repeat of a chomping mode identifier");else{if(!((n=48<=(a=o)&&a<=57?a-48:-1)>=0))break;0===n?gn(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):c?gn(t,"repeat of an indentation width identifier"):(h=e+n-1,c=!0)}if(nn(o)){do{o=t.input.charCodeAt(++t.position)}while(nn(o));if(35===o)do{o=t.input.charCodeAt(++t.position)}while(!rn(o)&&0!==o)}for(;0!==o;){for(_n(t),t.lineIndent=0,o=t.input.charCodeAt(t.position);(!c||t.lineIndent<h)&&32===o;)t.lineIndent++,o=t.input.charCodeAt(++t.position);if(!c&&t.lineIndent>h&&(h=t.lineIndent),rn(o))u++;else{if(t.lineIndent<h){s===Gr?t.result+=or.repeat("\n",l?1+u:u):s===Yr&&l&&(t.result+="\n");break}for(r?nn(o)?(d=!0,t.result+=or.repeat("\n",l?1+u:u)):d?(d=!1,t.result+=or.repeat("\n",u+1)):0===u?l&&(t.result+=" "):t.result+=or.repeat("\n",u):t.result+=or.repeat("\n",l?1+u:u),l=!0,c=!0,u=0,i=t.position;!rn(o)&&0!==o;)o=t.input.charCodeAt(++t.position);xn(t,i,t.position,!1)}}return!0}(t,d)||function(t,e){var i,r,n;if(39!==(i=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,r=n=t.position;0!==(i=t.input.charCodeAt(t.position));)if(39===i){if(xn(t,r,t.position,!0),39!==(i=t.input.charCodeAt(++t.position)))return!0;r=t.position,t.position++,n=t.position}else rn(i)?(xn(t,r,n,!0),Tn(t,vn(t,!1,e)),r=n=t.position):t.position===t.lineStart&&kn(t)?gn(t,"unexpected end of the document within a single quoted scalar"):(t.position++,n=t.position);gn(t,"unexpected end of the stream within a single quoted scalar")}(t,d)||function(t,e){var i,r,n,o,a,s,l;if(34!==(s=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,i=r=t.position;0!==(s=t.input.charCodeAt(t.position));){if(34===s)return xn(t,i,t.position,!0),t.position++,!0;if(92===s){if(xn(t,i,t.position,!0),rn(s=t.input.charCodeAt(++t.position)))vn(t,!1,e);else if(s<256&&hn[s])t.result+=un[s],t.position++;else if((a=120===(l=s)?2:117===l?4:85===l?8:0)>0){for(n=a,o=0;n>0;n--)(a=sn(s=t.input.charCodeAt(++t.position)))>=0?o=(o<<4)+a:gn(t,"expected hexadecimal character");t.result+=cn(o),t.position++}else gn(t,"unknown escape sequence");i=r=t.position}else rn(s)?(xn(t,i,r,!0),Tn(t,vn(t,!1,e)),i=r=t.position):t.position===t.lineStart&&kn(t)?gn(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}gn(t,"unexpected end of the stream within a double quoted scalar")}(t,d)?m=!0:!function(t){var e,i,r;if(42!==(r=t.input.charCodeAt(t.position)))return!1;for(r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!on(r)&&!an(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&gn(t,"name of an alias node must contain at least one character"),i=t.input.slice(e,t.position),Pr.call(t.anchorMap,i)||gn(t,'unidentified alias "'+i+'"'),t.result=t.anchorMap[i],vn(t,!0,-1),!0}(t)?function(t,e,i){var r,n,o,a,s,l,c,h,u=t.kind,d=t.result;if(on(h=t.input.charCodeAt(t.position))||an(h)||35===h||38===h||42===h||33===h||124===h||62===h||39===h||34===h||37===h||64===h||96===h)return!1;if((63===h||45===h)&&(on(r=t.input.charCodeAt(t.position+1))||i&&an(r)))return!1;for(t.kind="scalar",t.result="",n=o=t.position,a=!1;0!==h;){if(58===h){if(on(r=t.input.charCodeAt(t.position+1))||i&&an(r))break}else if(35===h){if(on(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&kn(t)||i&&an(h))break;if(rn(h)){if(s=t.line,l=t.lineStart,c=t.lineIndent,vn(t,!1,-1),t.lineIndent>=e){a=!0,h=t.input.charCodeAt(t.position);continue}t.position=o,t.line=s,t.lineStart=l,t.lineIndent=c;break}}a&&(xn(t,n,o,!1),Tn(t,t.line-s),n=o=t.position,a=!1),nn(h)||(o=t.position+1),h=t.input.charCodeAt(++t.position)}return xn(t,n,o,!1),!!t.result||(t.kind=u,t.result=d,!1)}(t,d,Rr===i)&&(m=!0,null===t.tag&&(t.tag="?")):(m=!0,null===t.tag&&null===t.anchor||gn(t,"alias node should not have any properties")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===p&&(m=s&&wn(t,f))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&gn(t,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+t.kind+'"'),l=0,c=t.implicitTypes.length;l<c;l+=1)if((u=t.implicitTypes[l]).resolve(t.result)){t.result=u.construct(t.result),t.tag=u.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else if("!"!==t.tag){if(Pr.call(t.typeMap[t.kind||"fallback"],t.tag))u=t.typeMap[t.kind||"fallback"][t.tag];else for(u=null,l=0,c=(h=t.typeMap.multi[t.kind||"fallback"]).length;l<c;l+=1)if(t.tag.slice(0,h[l].tag.length)===h[l].tag){u=h[l];break}u||gn(t,"unknown tag !<"+t.tag+">"),null!==t.result&&u.kind!==t.kind&&gn(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):gn(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||m}function An(t){var e,i,r,n,o=t.position,a=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(n=t.input.charCodeAt(t.position))&&(vn(t,!0,-1),n=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==n));){for(a=!0,n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!on(n);)n=t.input.charCodeAt(++t.position);for(r=[],(i=t.input.slice(e,t.position)).length<1&&gn(t,"directive name must not be less than one character in length");0!==n;){for(;nn(n);)n=t.input.charCodeAt(++t.position);if(35===n){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&!rn(n));break}if(rn(n))break;for(e=t.position;0!==n&&!on(n);)n=t.input.charCodeAt(++t.position);r.push(t.input.slice(e,t.position))}0!==n&&_n(t),Pr.call(yn,i)?yn[i](t,i,r):mn(t,'unknown document directive "'+i+'"')}vn(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,vn(t,!0,-1)):a&&gn(t,"directives end mark is expected"),Fn(t,t.lineIndent-1,Ur,!1,!0),vn(t,!0,-1),t.checkLineBreaks&&Qr.test(t.input.slice(o,t.position))&&mn(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&kn(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,vn(t,!0,-1)):t.position<t.length-1&&gn(t,"end of the stream or a document separator is expected")}function Ln(t,e){e=e||{},0!==(t=String(t)).length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var i=new fn(t,e),r=t.indexOf("\0");for(-1!==r&&(i.position=r,gn(i,"null byte is not allowed in input")),i.input+="\0";32===i.input.charCodeAt(i.position);)i.lineIndent+=1,i.position+=1;for(;i.position<i.length-1;)An(i);return i.documents}var Mn=Sr,En={loadAll:function(t,e,i){null!==e&&"object"==typeof e&&void 0===i&&(i=e,e=null);var r=Ln(t,i);if("function"!=typeof e)return r;for(var n=0,o=r.length;n<o;n+=1)e(r[n])},load:function(t,e){var i=Ln(t,e);if(0!==i.length){if(1===i.length)return i[0];throw new lr("expected a single document in the stream, but found more")}}}.load;const Zn=t=>t.replace(/\r\n?/g,"\n").replace(/<(\w+)([^>]*)>/g,((t,e,i)=>"<"+e+i.replace(/="([^"]*)"/g,"='$1'")+">")),Nn=t=>{const{text:e,metadata:i}=function(t){const e=t.match(Dt);if(!e)return{text:t,metadata:{}};let i=En(e[1],{schema:Mn})??{};i="object"!=typeof i||Array.isArray(i)?{}:i;const r={};return i.displayMode&&(r.displayMode=i.displayMode.toString()),i.title&&(r.title=i.title.toString()),i.config&&(r.config=i.config),{text:t.slice(e[0].length),metadata:r}}(t),{displayMode:r,title:n,config:o={}}=i;return r&&(o.gantt||(o.gantt={}),o.gantt.displayMode=r),{title:n,config:o,text:e}},On=t=>{const e=ye.detectInit(t)??{},i=ye.detectDirective(t,"wrap");return Array.isArray(i)?e.wrap=i.some((({type:t})=>{})):"wrap"===(null==i?void 0:i.type)&&(e.wrap=!0),{text:(r=t,r.replace($t,"")),directive:e};var r};const In=["foreignobject"],jn=["dominant-baseline"];function qn(t){const e=function(t){const e=Zn(t),i=Nn(e),r=On(i.text),n=me(i.config,r.directive);return{code:t=rr(r.text),title:i.title,config:n}}(t);return Le(),Ae(e.config??{}),e}const Dn=function(t){return t.replace(/\ufb02\xb0\xb0/g,"&#").replace(/\ufb02\xb0/g,"&").replace(/\xb6\xdf/g,";")},$n=(t,e,i=[])=>`\n.${t} ${e} { ${i.join(" !important; ")} !important; }`,zn=(t,e,i,r)=>{const n=((t,e={})=>{var i;let r="";if(void 0!==t.themeCSS&&(r+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(r+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(r+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),!(0,ot.Z)(e)){const n=t.htmlLabels||(null==(i=t.flowchart)?void 0:i.htmlLabels)?["> *","span"]:["rect","polygon","ellipse","circle","path"];for(const t in e){const i=e[t];(0,ot.Z)(i.styles)||n.forEach((t=>{r+=$n(i.id,t,i.styles)})),(0,ot.Z)(i.textStyles)||(r+=$n(i.id,"tspan",i.textStyles))}}return r})(t,i);return M(tt(`${r}{${pi(e,n,t.themeVariables)}}`),E)},Pn=(t,e,i,r,n)=>{const o=t.append("div");o.attr("id",i),r&&o.attr("style",r);const a=o.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return n&&a.attr("xmlns:xlink",n),a.append("g"),t};function Rn(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}const Wn=Object.freeze({render:async function(t,e,i){var r,n,o,l,c,h;Qi();const u=qn(e);e=u.code;const d=Be();st.debug(d),e.length>((null==d?void 0:d.maxTextSize)??5e4)&&(e="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa");const f="#"+t,p="i"+t,g="#"+p,m="d"+t,y="#"+m;let x=(0,a.Ys)("body");const C="sandbox"===d.securityLevel,b="loose"===d.securityLevel,_=d.fontFamily;if(void 0!==i){if(i&&(i.innerHTML=""),C){const t=Rn((0,a.Ys)(i),p);x=(0,a.Ys)(t.nodes()[0].contentDocument.body),x.node().style.margin=0}else x=(0,a.Ys)(i);Pn(x,t,m,`font-family: ${_}`,"http://www.w3.org/1999/xlink")}else{if(((t,e,i,r)=>{var n,o,a;null==(n=t.getElementById(e))||n.remove(),null==(o=t.getElementById(i))||o.remove(),null==(a=t.getElementById(r))||a.remove()})(document,t,m,p),C){const t=Rn((0,a.Ys)("body"),p);x=(0,a.Ys)(t.nodes()[0].contentDocument.body),x.node().style.margin=0}else x=(0,a.Ys)("body");Pn(x,t,m)}let v,k;e=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/#\w+;/g,(function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"\ufb02\xb0\xb0"+e+"\xb6\xdf":"\ufb02\xb0"+e+"\xb6\xdf"})),e}(e);try{v=await Ki(e,{title:u.title})}catch(N){v=new Ji("error"),k=N}const T=x.select(y).node(),w=v.type,S=T.firstChild,B=S.firstChild,F=null==(n=(r=v.renderer).getClasses)?void 0:n.call(r,e,v),A=zn(d,w,F,f),L=document.createElement("style");L.innerHTML=A,S.insertBefore(L,B);try{await v.renderer.draw(e,t,xe,v)}catch(O){throw $i.draw(e,t,xe),O}!function(t,e,i,r){(function(t,e){t.attr("role",ir),""!==e&&t.attr("aria-roledescription",e)})(e,t),function(t,e,i,r){if(void 0!==t.insert){if(i){const e=`chart-desc-${r}`;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(i)}if(e){const i=`chart-title-${r}`;t.attr("aria-labelledby",i),t.insert("title",":first-child").attr("id",i).text(e)}}}(e,i,r,e.attr("id"))}(w,x.select(`${y} svg`),null==(l=(o=v.db).getAccTitle)?void 0:l.call(o),null==(h=(c=v.db).getAccDescription)?void 0:h.call(c)),x.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let M=x.select(y).node().innerHTML;if(st.debug("config.arrowMarkerAbsolute",d.arrowMarkerAbsolute),M=((t="",e,i)=>{let r=t;return i||e||(r=r.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),r=Dn(r),r=r.replace(/<br>/g,"<br/>"),r})(M,C,mt(d.arrowMarkerAbsolute)),C){M=((t="",e)=>{var i,r;return`<iframe style="width:100%;height:${(null==(r=null==(i=null==e?void 0:e.viewBox)?void 0:i.baseVal)?void 0:r.height)?e.viewBox.baseVal.height+"px":"100%"};border:0;margin:0;" src="data:text/html;base64,${btoa('<body style="margin:0">'+t+"</body>")}" sandbox="allow-top-navigation-by-user-activation allow-popups">\n The "iframe" tag is not supported by your browser.\n</iframe>`})(M,x.select(y+" svg").node())}else b||(M=s.sanitize(M,{ADD_TAGS:In,ADD_ATTR:jn}));if(tr.forEach((t=>{t()})),tr=[],k)throw k;const E=C?g:y,Z=(0,a.Ys)(E).node();return Z&&"remove"in Z&&Z.remove(),{svg:M,bindFunctions:v.db.bindFunctions}},parse:async function(t,e){Qi(),t=qn(t).code;try{await Ki(t)}catch(i){if(null==e?void 0:e.suppressErrors)return!1;throw i}return!0},getDiagramFromText:Ki,initialize:function(t={}){var e;(null==t?void 0:t.fontFamily)&&!(null==(e=t.themeVariables)?void 0:e.fontFamily)&&(t.themeVariables||(t.themeVariables={}),t.themeVariables.fontFamily=t.fontFamily),be=Vt({},t),(null==t?void 0:t.theme)&&t.theme in Mt?t.themeVariables=Mt[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=Mt.default.getThemeVariables(t.themeVariables));const i="object"==typeof t?(t=>(_e=Vt({},Ce),_e=Vt(_e,t),t.theme&&Mt[t.theme]&&(_e.themeVariables=Mt[t.theme].getThemeVariables(t.themeVariables)),Te(_e,ve),_e))(t):we();lt(i.logLevel),Qi()},getConfig:Be,setConfig:Se,getSiteConfig:we,updateSiteConfig:t=>(_e=Vt(_e,t),Te(_e,ve),_e),reset:()=>{Le()},globalReset:()=>{Le(Ce)},defaultConfig:Ce});lt(Be().logLevel),Le(Be());const Hn=(t,e,i)=>{st.warn(t),pe(t)?(i&&i(t.str,t.hash),e.push({...t,message:t.str,error:t})):(i&&i(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))},Un=async function(t={querySelector:".mermaid"}){try{await Yn(t)}catch(e){if(pe(e)&&st.error(e.str),to.parseError&&to.parseError(e),!t.suppressErrors)throw st.error("Use the suppressErrors option to suppress these errors"),e}},Yn=async function({postRenderCallback:t,querySelector:e,nodes:i}={querySelector:".mermaid"}){const n=Wn.getConfig();let o;if(st.debug((t?"":"No ")+"Callback function found"),i)o=i;else{if(!e)throw new Error("Nodes and querySelector are both undefined");o=document.querySelectorAll(e)}st.debug(`Found ${o.length} diagrams`),void 0!==(null==n?void 0:n.startOnLoad)&&(st.debug("Start On Load: "+(null==n?void 0:n.startOnLoad)),Wn.updateSiteConfig({startOnLoad:null==n?void 0:n.startOnLoad}));const a=new ye.InitIDGenerator(n.deterministicIds,n.deterministicIDSeed);let s;const l=[];for(const h of Array.from(o)){if(st.info("Rendering diagram: "+h.id),h.getAttribute("data-processed"))continue;h.setAttribute("data-processed","true");const e=`mermaid-${a.next()}`;s=h.innerHTML,s=(0,r.Z)(ye.entityDecode(s)).trim().replace(/<br\s*\/?>/gi,"<br/>");const i=ye.detectInit(s);i&&st.debug("Detected early reinit: ",i);try{const{svg:i,bindFunctions:r}=await Kn(e,s,h);h.innerHTML=i,t&&await t(e),r&&r(h)}catch(c){Hn(c,l,to.parseError)}}if(l.length>0)throw l[0]},Vn=function(t){Wn.initialize(t)},Gn=function(){if(to.startOnLoad){const{startOnLoad:t}=Wn.getConfig();t&&to.run().catch((t=>st.error("Mermaid failed to initialize",t)))}};"undefined"!=typeof document&&window.addEventListener("load",Gn,!1);const Xn=[];let Qn=!1;const Jn=async()=>{if(!Qn){for(Qn=!0;Xn.length>0;){const e=Xn.shift();if(e)try{await e()}catch(t){st.error("Error executing queue",t)}}Qn=!1}},Kn=(t,e,i)=>new Promise(((r,n)=>{Xn.push((()=>new Promise(((o,a)=>{Wn.render(t,e,i).then((t=>{o(t),r(t)}),(t=>{var e;st.error("Error parsing",t),null==(e=to.parseError)||e.call(to,t),a(t),n(t)}))})))),Jn().catch(n)})),to={startOnLoad:!0,mermaidAPI:Wn,parse:async(t,e)=>new Promise(((i,r)=>{Xn.push((()=>new Promise(((n,o)=>{Wn.parse(t,e).then((t=>{n(t),i(t)}),(t=>{var e;st.error("Error parsing",t),null==(e=to.parseError)||e.call(to,t),o(t),r(t)}))})))),Jn().catch(r)})),render:Kn,init:async function(t,e,i){st.warn("mermaid.init is deprecated. Please use run instead."),t&&Vn(t);const r={postRenderCallback:i,querySelector:".mermaid"};"string"==typeof e?r.querySelector=e:e&&(e instanceof HTMLElement?r.nodes=[e]:r.nodes=e),await Un(r)},run:Un,registerExternalDiagrams:async(t,{lazyLoad:e=!0}={})=>{Ht(...t),!1===e&&await(async()=>{st.debug("Loading registered diagrams");const t=(await Promise.allSettled(Object.entries(Rt).map((async([t,{detector:e,loader:i}])=>{if(i)try{Ii(t)}catch(r){try{const{diagram:t,id:r}=await i();Oi(r,t,e)}catch(n){throw st.error(`Failed to load external diagram with key ${t}. Removing from detectors.`),delete Rt[t],n}}})))).filter((t=>"rejected"===t.status));if(t.length>0){st.error(`Failed to load ${t.length} external diagrams`);for(const e of t)st.error(e);throw new Error(`Failed to load ${t.length} external diagrams`)}})()},initialize:Vn,parseError:void 0,contentLoaded:Gn,setParseErrorHandler:function(t){to.parseError=t},detectType:Wt}}}]); \ No newline at end of file diff --git a/assets/js/4.4bc37b90.js.LICENSE.txt b/assets/js/4926.50b7d3b0.js.LICENSE.txt similarity index 66% rename from assets/js/4.4bc37b90.js.LICENSE.txt rename to assets/js/4926.50b7d3b0.js.LICENSE.txt index 062dad4ca..4106d6a54 100644 --- a/assets/js/4.4bc37b90.js.LICENSE.txt +++ b/assets/js/4926.50b7d3b0.js.LICENSE.txt @@ -2,7 +2,7 @@ * Wait for document loaded before starting the execution */ -/*! @license DOMPurify 2.4.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.4.1/LICENSE */ +/*! @license DOMPurify 3.0.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.6/LICENSE */ /*! Check if previously processed */ diff --git a/assets/js/4972.46e01c40.js b/assets/js/4972.46e01c40.js deleted file mode 100644 index 49deec960..000000000 --- a/assets/js/4972.46e01c40.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4972],{4972:(e,t,n)=>{n.r(t),n.d(t,{default:()=>i});var a=n(67294),l=n(95999),o=n(10833),r=n(7452);function i(){return a.createElement(a.Fragment,null,a.createElement(o.d,{title:(0,l.I)({id:"theme.NotFound.title",message:"Page Not Found"})}),a.createElement(r.Z,null,a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(l.Z,{id:"theme.NotFound.title",description:"The title of the 404 page"},"Page Not Found")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page"},"We could not find what you were looking for.")),a.createElement("p",null,a.createElement(l.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page"},"Please contact the owner of the site that linked you to the original URL and let them know their link is broken.")))))))}}}]); \ No newline at end of file diff --git a/assets/js/49b8d9dd.ce03beac.js b/assets/js/49b8d9dd.3c966f04.js similarity index 86% rename from assets/js/49b8d9dd.ce03beac.js rename to assets/js/49b8d9dd.3c966f04.js index 720ecf54e..07de09344 100644 --- a/assets/js/49b8d9dd.ce03beac.js +++ b/assets/js/49b8d9dd.3c966f04.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1103],{64420:e=>{e.exports=JSON.parse('{"label":"InnoDB","permalink":"/tags/inno-db","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1103],{64420:e=>{e.exports=JSON.parse('{"label":"InnoDB","permalink":"/tags/inno-db","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/49f0f498.c7f15397.js b/assets/js/49f0f498.452bd2f4.js similarity index 81% rename from assets/js/49f0f498.c7f15397.js rename to assets/js/49f0f498.452bd2f4.js index 7ff2ce3ab..f4b116f37 100644 --- a/assets/js/49f0f498.c7f15397.js +++ b/assets/js/49f0f498.452bd2f4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4433],{40719:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4433],{40719:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/4a1c8300.99f9cdad.js b/assets/js/4a1c8300.99f9cdad.js deleted file mode 100644 index 4a49046d3..000000000 --- a/assets/js/4a1c8300.99f9cdad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3324],{3905:(A,e,t)=>{t.d(e,{Zo:()=>w,kt:()=>c});var r=t(67294);function n(A,e,t){return e in A?Object.defineProperty(A,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):A[e]=t,A}function p(A,e){var t=Object.keys(A);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(A);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(A,e).enumerable}))),t.push.apply(t,r)}return t}function E(A){for(var e=1;e<arguments.length;e++){var t=null!=arguments[e]?arguments[e]:{};e%2?p(Object(t),!0).forEach((function(e){n(A,e,t[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(A,Object.getOwnPropertyDescriptors(t)):p(Object(t)).forEach((function(e){Object.defineProperty(A,e,Object.getOwnPropertyDescriptor(t,e))}))}return A}function a(A,e){if(null==A)return{};var t,r,n=function(A,e){if(null==A)return{};var t,r,n={},p=Object.keys(A);for(r=0;r<p.length;r++)t=p[r],e.indexOf(t)>=0||(n[t]=A[t]);return n}(A,e);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(A);for(r=0;r<p.length;r++)t=p[r],e.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(A,t)&&(n[t]=A[t])}return n}var I=r.createContext({}),l=function(A){var e=r.useContext(I),t=e;return A&&(t="function"==typeof A?A(e):E(E({},e),A)),t},w=function(A){var e=l(A.components);return r.createElement(I.Provider,{value:e},A.children)},o={inlineCode:"code",wrapper:function(A){var e=A.children;return r.createElement(r.Fragment,{},e)}},u=r.forwardRef((function(A,e){var t=A.components,n=A.mdxType,p=A.originalType,I=A.parentName,w=a(A,["components","mdxType","originalType","parentName"]),u=l(t),c=n,C=u["".concat(I,".").concat(c)]||u[c]||o[c]||p;return t?r.createElement(C,E(E({ref:e},w),{},{components:t})):r.createElement(C,E({ref:e},w))}));function c(A,e){var t=arguments,n=e&&e.mdxType;if("string"==typeof A||n){var p=t.length,E=new Array(p);E[0]=u;var a={};for(var I in e)hasOwnProperty.call(e,I)&&(a[I]=e[I]);a.originalType=A,a.mdxType="string"==typeof A?A:n,E[1]=a;for(var l=2;l<p;l++)E[l]=t[l];return r.createElement.apply(null,E)}return r.createElement.apply(null,t)}u.displayName="MDXCreateElement"},37750:(A,e,t)=>{t.r(e),t.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>E,metadata:()=>I,toc:()=>w});var r=t(87462),n=(t(67294),t(3905)),p=t(17779);const E={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",slug:"woowacourse-level3-retrospective",tags:["Woowahan Techcourse","Retrospective"]},a=void 0,I={permalink:"/woowacourse-level3-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",source:"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",description:"\ud68c\uace0",date:"2023-08-19T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 19\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.945,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",slug:"woowacourse-level3-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",permalink:"/db-replication"},nextItem:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/cloudwatch"}},l={authorsImageUrls:[]},w=[{value:"\ud68c\uace0",id:"\ud68c\uace0",level:3},{value:"\uc544\uc26c\uc6b4 \uc810",id:"\uc544\uc26c\uc6b4-\uc810",level:3},{value:"\uc88b\uc558\ub358 \uc810",id:"\uc88b\uc558\ub358-\uc810",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3}],o={toc:w};function u(A){let{components:e,...t}=A;return(0,n.kt)("wrapper",(0,r.Z)({},o,t,{components:e,mdxType:"MDXLayout"}),(0,n.kt)("h3",{id:"\ud68c\uace0"},"\ud68c\uace0"),(0,n.kt)("p",null,"\uc9c0\ub09c 8\uc8fc\ub294 \ub808\ubca8 1, 2 \ub54c\ubcf4\ub2e4 5\ubc30 \uc815\ub3c4 \ube60\ub974\uac8c \uc9c0\ub098\uac04 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 3\uc5d0\ub294 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4, \uae30\uc220 \uc678\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4 \ubd80\uc871\ud568\uc774 \ub9ce\uc774 \ubcf4\uc600\ub358 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ubd80\uc871\ud55c \ubd80\ubd84\uc744 \uc54c\uc558\uae30\uc5d0, \uc55e\uc73c\ub85c \ub354\uc6b1 \uc131\uc7a5\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \ud300\uc6d0\ub4e4\uc774 \uc798 \ubcf4\ucda9\ud574 \uc918\uc11c \ub4e0\ub4e0\ud588\ub2e4. "),(0,n.kt)("h3",{id:"\uc544\uc26c\uc6b4-\uc810"},"\uc544\uc26c\uc6b4 \uc810"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\ubb38\uc11c\ud654")),(0,n.kt)("p",null,"\uac1c\uc778\uc801\uc73c\ub85c\ub294 \uae30\uc220 \uc678\uc801\uc73c\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ub0b4\uac00 \ud55c \ubd80\ubd84\uc744 \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c, \uc774\ud574\ud558\uae30 \uc27d\uac8c \ubb38\uc11c\ud654\ub97c \ud588\ub354\ub77c\uba74 \ud300\uc6d0\ub4e4\uc5d0\uac8c \ub354\uc6b1 \ub3c4\uc6c0\uc774 \ub418\uc5c8\uc744 \ud150\ub370 \uc774 \ubd80\ubd84\uc5d0 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ud22c\uc790\ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc5d0\uc11c \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ubc29\ud559 \uae30\uac04 \ub3d9\uc548 \ubb38\uc11c\ud654\ub97c \ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc778 \ube14\ub85c\uadf8 \uc62c\ub9ac\uba74\uc11c \uc870\uae08 \ub354 \ucc44\uc6cc\ubcf4\ub824\uace0 \ud55c\ub2e4. "),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\ub0b4\uac00 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc774\uc790")),(0,n.kt)("p",null,"\uc798 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc5ec\uc11c\ub77c\ub3c4 \uc911\uac04\uc740 \uac00\ub3c4\ub85d \ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ub9d0\uc744 \ud558\uae30 \uc804\uc5d0 \uc815\ub9ac\ud574\uc11c \uc758\uacac\uc744 \ub0b4\ub294 \uac83, \ubc1c\ud45c \uc900\ube44, \uac10\uc815 \uc870\uc808 \ub4f1\ub4f1\n\ubabb\ud558\ub294 \ubd80\ubd84\uc744 \uc778\uc9c0\ud558\uace0, \uac1c\uc120\ud558\uc790. "),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\ucef4\ud3ec\ud2b8 \uc874 \ubc97\uc5b4\ub098\uae30")),(0,n.kt)("p",null,"\uc870\uae08 \ub354 \ub3c4\uc804\uc801\uc73c\ub85c \ubaa9\ud45c\ub97c \uc7a1\uc558\uc73c\uba74 \uc88b\uc558\uc744 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ub9e4\ubc88 \uadfc\uac70\ub97c \uac00\uc9c0\uace0 \uae30\uc220\uc744 \ub3c4\uc785\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uc9c0\uc18d\uc801\uc73c\ub85c \uac1c\uc120\ud558\ub824\uace0 \ud558\ub294 \ubd80\ubd84\uc774 \ub2e4\uc18c \ubd80\uc871\ud588\ub2e4. "),(0,n.kt)("h3",{id:"\uc88b\uc558\ub358-\uc810"},"\uc88b\uc558\ub358 \uc810"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\uc88b\uc558\ub358 \uc810\ub3c4 \ubb38\uc11c\ud654")),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://tripdraw.blog"},"\ud300 \ube14\ub85c\uadf8"),"\ub3c4 \uba3c\uc800 \ub3c4\uc785\ud558\uc790\uace0 \uc81c\uc548\ud558\uace0, \ub0b4\uac00 \ud588\ub358 \ubd80\ubd84\uc740 \ubb38\uc11c\ud654\ub97c \uaf64 \ub9ce\uc774 \ud574\uc11c \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ubc31\uc5d4\ub4dc \ud06c\ub8e8 4\uba85\uc774\uc11c \uac19\uc774 \ud55c \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c\ub294 \uae30\ub2a5 \uad6c\ud604\ud55c\ub2e4\uace0 \ubb38\uc11c\ud654\uac00 \uc870\uae08 \ubbf8\ud761\ud574\uc11c \ubcf4\ucda9\uc744 \ud574\uc57c\uaca0\ub2e4. "),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\ub0b4\uac00 \ub514\uc790\uc778\ud55c \ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0")),(0,n.kt)("img",{src:p.Z,width:"100"}),(0,n.kt)("p",null,"\ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud300\uc6d0\ub4e4\uc774 \ub300\ud45c \uc0c9\uc0c1(\ud30c\ub780\uc0c9)\uc744 \uc815\ud574\uc92c\uace0, \uc8fc\ub9d0 \ub3d9\uc548 \uc2e0\ub098\uac8c \ub85c\uace0 \ub514\uc790\uc778\uc744 \ud588\ub358 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc758 D \ubd80\ubd84\uc740 \uc720\ud29c\ube0c \uac15\uc758 \ub4e4\uc73c\uba74\uc11c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\uc11c \ubfcc\ub4ef\ud558\ub2e4. "),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\uae30\uc220 \uc120\ud0dd\uc758 \uc774\uc720")),(0,n.kt)("p",null,"\uae30\uc220\uc758 \ud559\uc2b5 \ube44\uc6a9, \ud604\uc7ac \uad6c\uc870\uc5d0 \uc801\ud569\ud55c\uc9c0, \uc2e4\uc81c \uac00\uc9c0\uace0 \uc788\ub294 \ub9ac\uc18c\uc2a4\ub97c \uace0\ub824\ud574\uc11c \uae30\uc220 \uc120\ud0dd\uc744 \ud558\uace0, \ub3c4\uc785\ud588\ub358 \ubd80\ubd84\uc774 \uc88b\uc558\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","100% \uc88b\uc740 \uc120\ud0dd\uc77c \uc21c \uc5c6\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \uc120\ud0dd\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \uc874\uc7ac\ud55c\ub2e4\uba74 \ud655\ub960\uc744 \ub192\ud600\uc8fc\ub294 \uac83 \uac19\ub2e4. "),(0,n.kt)("h3",{id:"\ub9c8\uce58\uba70"},"\ub9c8\uce58\uba70"),(0,n.kt)("p",null,"\ud50c\ub808\uc774\uc2a4\ud1a0\uc5b4\uc5d0 \uc571\uc774 \uc62c\ub77c\uac00 \uc788\ub294 \uac70 \ub108\ubb34 \uc2e0\uae30\ud558\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc548\ub4dc\ub85c\uc774\ub4dc \ube0c\ub808\uba58 \uc74c\uc545\ub300(\uba67\ub3fc\uc9c0, \uc218\ub2ec, \ud551\uad6c), \uadf8\ub9ac\uace0 \ubc31\uc5d4\ub4dc \ud300\uc6d0\ub4e4(\uccb4\uc778\uc800, \ud6c4\ucd94, \ub9ac\uc624) \ub108\ubb34 \uace0\uc0dd\uc774 \ub9ce\uc558\ub2e4."))}u.isMDXComponent=!0},17779:(A,e,t)=>{t.d(e,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAGwCAYAAADITjAqAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAABauSURBVHgB7d1viF3lncDx59yJsZpWU6wxoqmjLthGS2vBP4u7dEqb7FIXVKIFX9Qa3xTqiyisfWeNyEKphWZgLesbxyqLi4m0wiprXHCWIlUD1bKaRljt1CjGfzSmjdaYzNn73Dg2f5wkk8w95/nd+/nANCaZ0HHM3O/8nuc551SpRYvHJhYvXLhgrJquR+sqfblK9WiqqtGPfns0AdC6uk7bq6qaSvX09jpVU52q/kOanp78y+703PbJ1dtTS6rUoI+DVU2Ppbq6IokUQHRT3QFksvua/vCuXbsnmwxaIwFb+s2JsbozsqZb8W680uIEwEDqxuzeHLM3N37nl6nP+hawj6atNd3Z8ybRAhg6U1Wdbk8f7pncNrl6KvXBvAdMuADYx1R33+ze7kR2e5pn8xqwpSvuu747Pt6W7G0BsL/eRLbt8evuTfNkXgK2dGxitD5uwUSq6rEEALP7ZbVrz83zsazYScfotBX3r5k+buRZ8QLgCFxZLxx5Nq/YpWN01BNY3us6fuFIXi68KQHAXFVp3RuPXXdzOkpHFbDekuHCkXxE8ssJAI5a9Vy1a/dVR7OkOOeAfRSvJ5KDGgDMj6nuvtjX5xqxOQVMvADokzlH7IgDJl4A9NmcInZEARMvABpyxBE7omP0Hx3YGE0A0F/dgWnBL/JJ98O942EDdtrK+36anDYEoDH1V44/vneZ1iGNHOo3exeaVelHCQCademn/+aqd3e+9IunZnuHWffA8r5XvsOGG/IC0JLt3f2wC2fbD5t1CbG77/VT8QKgRYvr4zsTs/3mJwbso3tUXZkAoE11NTbbfRM7n/z+6bCbZwDQhNykTzqVeFDAlqy83/O8ACjJ6KcWdg66cfx+hzhcsAxAobZ/sGvP2dsnV2+f+YX9J7DjRsaSeAFQnsUHTmH7BczeFwClqlO1Zt+ffxywJd+4P586HE0AUKbFS785MTbzk79OYCPTjs0DULS6M/LxFNY7xJGPJx6/cOSPCQDK9vFhjt4EtnBkwVgCgPItPmHh3mbtXUK0fAhAENNVGss/9gJWpeprCQAiqOsr8g+V/S8Aounug32286kF6SsJAALJ+2Cd1OmMJQAIZLqqR/Me2GgCgECqlL7cqevOWQkAAqmnuxNYnTx1GYBgqiovIdajCQCC6VSVCQyAcEY7CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQlqQAPrkzCUnpi+edXI6adFx3X8+IZ104nHp5EULP/F93925K+1478P0p50fps1TO9KO3o/vJpiNgLUkf0FfPbYsrbjo9HTmqSf2vtCJ49U33+u9uD6+6fW0YXJrIqVLz/9cWj56Uvdtcbpk+Snz9nc6f57z5/vpzW/3wvbUC28nyKrTVt5XJxqVv7AfWHtZL1zEl19gv3fnM70X2WGS/x6vvGhp75uw5aN7p6ym5Ijlbx42bto2dJ93/krAGiZegym/oF679sk06PLf31VfW9ZdPfh8MasG+RuIiUdeSk9tfkfMhowlxIb1llbEa+Dk5bM8jeSJYNDsu9yd/z1Lk6e/O2/8au+fNz6zd0k3T2cMPgFr2DVjZyUG06ruVDJIAcvhWv2tc9INl5/b6PLgsVh58em9t1ffei+NP7jF/uSAE7CGfbG7yc1gWn72yWkQ5KXBNdec11smjCqvcuSpbM23vyBkA8weWMN+v/6KxOA6+5qHU1SDEK7Z5InslruedYJxwJjAYMhFXCqcqzyR5cNTeRIbX7/FYY8BIWAwxFaNLUs/vP5LAxuuA+XDKJeef4plxQEhYDCE8nLhnd+/sMhThf02sz92yfmnmsaCcy9EGDJ5qfCRH48NZbz2laex3jWZ7oITloDBkMjLhLdef0HvbViWDA8nT2O/umtFbw+QeCwhwhDIU8bdt1zcu+iXg/1w9d59wPH1LybiMIHBgMvRyktl4nVoN337C929sQsTcZjAYIDNxMuS4ZHJ18DlR77ka8byo10omwkMBpR4HZ18K6oHbr+sFzLKJmAwgMTr2OTP362rL0iUTcBgwMw8ske8jk1eTrQnVjYBgwEiXvMrRyzfH5IyCRgMiBwtD0udf/l04iDe4HgQCBgMiHyBsnj1R/7cugyhPAIGA+Cma0wJ/ZSn27t/cLGTiYURMAiu9xyvb9un6bc83eYHZFIOAYPg8r4Xzbjh8nPSiotOT5RBwCCwvHRo36tZP7nxQkuJhRAwCMrSYTvyfpilxDIIGARl6bA9eSlx2J+nVgIBg4DyQyktHbbLBc7tEzAIJi8drr7cAxjblicwU1i7BAyCyd/5m77K4F6J7RIwCCRPXy5YLkf+RuLqsWWJdggYBGLfpTyrfEPRGgGDebJjZ3+f4Gv6KpO9sPYIWMNefeu9xGDq939b01e5/Ldpx4JEozZPvWsDfkBtntqR+iXy9JUn0xz3P+3cvd+vf2bRgoG5w3uewPLdOXa8198pnP0JWMMemtyaVrqX2kAaf3BL6pdI3+HnYG2YfCU9vfmd3jdsr7556Mk0RywHIH9dXHL+KSmq1f90TvfvwIuJ5lSnrbyvTjTqP9b+XegvVA52zyMvpTvufT71Q56+fnXXilS6p154O42vf7H349HKqxM5ZvkWWdFWKvKU+ffffzzRnJFPn3vV2kSj8hd4vp+aB+TFl6eNf3v4/9KP/31z6pcVFy1NKy8ud2rfuGlbuv5ffp0mHn35mPcB8xJcntomHnk5vfbW+2n52Sf3vlYiyB9nnjrtczfHBNai/B1m/gL94uhJadmpi1IbzlhyQrp0ecwTVE9tfju99ub7qQ1b39rZXRp7Pz3+zOt93/f41c9WFDmN5BfqW+569pgmrsPZ+wyu88Ls/61bv8UyYoPsgbUovwDkt43dF8G2rBpbFjZgG554pbenOMjyclqJ8cp7XHdMPN/3eM9E8ndTO9Kt11+QSpe/lsaTgDXFMXoo2KoC7/KQp4wclSZP3OU9xstvmez7tXbHauY0Is0QMChUiUfn21wiy3tj1659sviIrbh4aaIZAgaFumR5WSdVS9jfyRH73p3PpJI5nNUcAYNCXTN2VipFXsIr5XBCPjTSr0sW5kPJJ0YHjYBBgfLyYSnXCuaDFKUFIwf16RfeSSXKh27sgzVDwKBAJd2t5drbnkwl+ue7flPsflj+BoT+EzAoUCkBy/tepV6Ymz+ufPF0ifK1nfSfgEFhSlk+zIF46Imyr7PLS4klTmEOcjRDwKAwpZw+zIc2Sr8tUo5XiVOYJ040Q8CgMKWcPuznLaLmU57CSmMPrBkCBgXJN4QtYflww+TWMDelzVNYaScSTWDNEDAoSCl7J4+3eH/Oo5Fv7FySKHfQj07AoCCl3IZo46ZgAStwudMU1n8CBgUp4ckAUfa+9pVvMcXwETAoRN74L2EJMWIM8j6YB0kOHwGDQpRy8WvUELT1cNPZOInYfwIGhSjl7hv54ZER5adkM1wEDArh7g0wNwIGBcjHrksJ2Ktv2ksiBgGDApi+jt2yUxelkvhGoP8EDApQyrO/MocPiELAoAB/u/zUVIqoD2Ms7REmjvX3n4BBAUp68T1jyQkpmjw1un3T8BEwaFlpL74R9+NMX8NJwKBlpb34Xnp++7ezmqtSrqGb4QBHMwQMWlbaxJNvQhttH6y06JrAmiFg0LISl+xWfX1ZiiLHq7Q7vwtYMwQMWlbiYzdKW5I7lFVj5cX2d7+PeTuuaAQMWlbiBJanmgh7YfkAzNVjn0+lMYE1Q8CgRcvPLvfE35przkulK/Vj9HyyZggYtOiMU8u95qr0KSxPriVOXxEfCBqVgEGLSr/mquQp7O4fXJxKZPpqjoBBi0oPWJ7AVn/rnFSaW6+/oMjDL9nTL7yTaIaAQYtOPnFhKt0PV3+pqKXEGy4/t/dWKhNYcwQMWlTaXThmc/ctFxdxl/q855Wnr1LleDmB2BwBg5bk+x9GuQFt/jgfWHtZqxHL8brzxgtTyRzgaJaAQUuiPXcr7znliLWxb5eXDEuPV/b4pm2J5ggYtCTic7dyxB65c6yxgx158rvz+xcWvWw4Iy8dmsCatSABrYj42JIZ+WDH8rMXp/H1W/p25/V8cCRPXaWeNjzQU04fNk7AoCWfWRT7y+/qsWW9t3seeSlNPPryvIUshytffxbtsS7jD25JNEvAoCWRJ7B9zRxr3zC5NT00+cpRLaPlpcIcwxUXnR7yeWT539npw+YJGLQkwjVgczEzke3Y+WHvBf3pzW+nzVM7ej/f8d6H+71vXhY8o/u2fPSkXrCix3x8/YuJ5gkYtCT6EuJs8jS18uLTe2/DwOGN9jiFCC2JcjiBQxt/0PTVFgGDFkS6iJnZ5elrQ3ffj3YIGLQg4jVgHOyWu55NtEfAoAXR7sLBwfKpS3tf7RIwgDnKJytd99U+AYMWlPwkZg7vnkdfct1XAQQMWmAJMa4cLicPyyBgAEcoLx1ee9uTiTIIGLTANWAx5TtuWDosh4ABHIF80+L8RjkEDFqw7NRFiTjse5VJwAAOIccr73sdeENi2idg0IJBvZHvIPrej5+x71UoAYMWuA9iDLf87Nm0eerdRJkEDOATrFu/JW14wo16SyZg0ALH6MuW4+XQRvkEDGAf4hWHgAF8RLxiETCAJF4ROcsLDbP/VZ477n3eXTYCEjBgaOWb8+anKm/c9HoiHgEDhlK+ODlfpOw6r7gEDBg6OVrusBGfgAFDZcPkK+mOiefd23AACBgwNBzWGCwCBgy8vFSYD2s89cLbicEhYMBA27hpW7rlX39jyXAACRg07MwlrgNrQj4iP77+RUuGA0zAoGEmgf7LS4V5ydApw8EmYNCwHX8WsH7KU9e6B7ckBp+AAQPB1DV8BAwIzV7X8BIwIKx8wvCOif81dQ0pAQPCcV0XmYABYeTlwolHX3ZIgx4BA0LIe1z5gZMuQ2CGgAFFc7qQ2QgYNMwL8ZHJ4cqnC+1zMRsBA4oiXBwpAQOKIFzMlYABrRIujpaAQQvyPtiZpw73XemFi2MlYECjNkxuTQ9NviJcHDMBA/pu5gLke/7zJddxMW8EDFrw2pvvD8US4uapd7vT1ta04YlXhIt5J2DAvLO/RRMEDFqw9a2d6ZJ0ShoklglpmoABx8S0RVsEDFoQfULJe1uPb9pm2qJVAgYtyMtt0eSPecPkK71wmbYogYBBC/60c3eKIEcrT1t5iXDz7981bVEUAYMWvLtzVypZnrDypOX4OyUTMGhBiVEQLaIRMGjBa2+9n9o2szwoWkQlYNCCHX9uJxY5WjlYv87T1jOvixahCRhhlTDFHK18N/qm7kj/6pvvpY2bXnd6kIEjYEPu6RfeSVHlU3GR5XsErrnmvDTf9l0azOHKAYNBJGBDLk8B+QXvpEXHpUjyJBF9+eueR15Kq8aWzcsUloM1cwjDcXeGhYDRu8bn1usvSJHk6SW6/I3Dtbc9mR64/bI5R2xmWXDz1A57WQyt6rSV99WJoXfr6gvSDd86N0Wwbv2WNP7gi2lQ5Hj95MavpkvOn/3mvjlYT29+p3f44unNb1sWhCRg7OPS8z/XW9JaPnpy70W1lGXFPKnkpc6ZJbJBPYiQP/8rLlqali1Z1Pv51jd3mrDgEAQMgJA6CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAELKAZtKABDLdhMYAAFVU51UV1MJACKpp7d3qmr6DwkAAqk63Qmsnq6eSwAQSV3/oVNbQgQgmunpyc6uPbsnEwAE8pfd6bnO9snV25Oj9ABEUaWp3K69x+jr+uEEAAFUKU3mH3sBq6c7kwkAAqjqqjd09QKW98HqOm1PAFC493ftPbvRC1heS6yq+n8SABSsqtK9H53d+OvNfKvp6XUJAAo2s3zY++d9f2PJivv+2K3b4gQApanS1BuPXXf2zE/3u5lvp6rHEwAUqJpOt+/78/0C9pdd0+sc5gCgON3pK43smdz3l/YLWO/CMFMYAIWp6vrn2/5r9dS+v3bQ88DyFNYrHQCUoNukbRu/u/bAXz4oYL0j9QesMwJAW2ZrUjXbHzjtH+5/ItX1WAKA1lS/fGPjd676pN/pzPpHqt2rHegAoC11d1Gw6uy+ebbfnzVgebOsqi0lAtCOTp1uPvDgxr5GDvWHd778i6c+fc6Vn+2OY5cmAGhKVY2/sfG6Hx3qXTrpMD74cHptnarnEgA047dvPPadmw73TocNWO/asM7uqxytB6Dvuq2pOnuuPLJ3PUJL/3FitK5Hnujuqo0mAJhvOV7Vnq8fat9r/3efAxEDoC/mGK+9f2SORAyAeXUU8coOuwd2oN7x+u7/kYMdAMyD3x5NvLI5T2D7Om3Fz9elqlqTAGCuqmr8gw92r515wvKc/3g6RktX3Hf9dEo/9SBMAI5E7w4bVbr9jceuW5eOwTEHLOvti013uh9IdUUCgNnU1WQ1snv10SwZHmheAjYjT2N1J93mgAcA+8kHNabT7dsev+7eNE/mNWAzlq78+dq6qr4rZADDLS8XdlI9np81ebR7XbPpS8CyvKyY9oyMmcgAhk8/wzWjbwHb15JvTFzZGelcWafuVAbAQOodzkjdPa7p3ePb/nv1ZOqzRgI2Y/HYxOKFI2msF7Oq+prJDCC8qVTVD9e7pyd37UmT/Zq2PkmjATtQDtqnFqSvpE5nbLquzuqWe7Rb8MXdT8ZolRzLByjEVO9/62qqTnV+VuRv63rPVNPBOtD/A6oeNVega6lDAAAAAElFTkSuQmCC"}}]); \ No newline at end of file diff --git a/assets/js/4a1c8300.cdb79bf0.js b/assets/js/4a1c8300.cdb79bf0.js new file mode 100644 index 000000000..665badcd2 --- /dev/null +++ b/assets/js/4a1c8300.cdb79bf0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3324],{74122:(A,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>s,default:()=>o,frontMatter:()=>I,metadata:()=>j,toc:()=>w});var r=n(85893),t=n(3905),E=n(17779);const I={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",slug:"woowacourse-level3-retrospective",tags:["Woowahan Techcourse","Retrospective"]},s=void 0,j={permalink:"/woowacourse-level3-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",source:"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",description:"\ud68c\uace0",date:"2023-08-19T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 19\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.945,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",slug:"woowacourse-level3-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",permalink:"/db-replication"},nextItem:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/cloudwatch"}},c={authorsImageUrls:[]},w=[{value:"\ud68c\uace0",id:"\ud68c\uace0",level:3},{value:"\uc544\uc26c\uc6b4 \uc810",id:"\uc544\uc26c\uc6b4-\uc810",level:3},{value:"\uc88b\uc558\ub358 \uc810",id:"\uc88b\uc558\ub358-\uc810",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3}];function l(A){const e={a:"a",br:"br",h3:"h3",p:"p",strong:"strong",...(0,t.ah)(),...A.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h3,{id:"\ud68c\uace0",children:"\ud68c\uace0"}),"\n",(0,r.jsxs)(e.p,{children:["\uc9c0\ub09c 8\uc8fc\ub294 \ub808\ubca8 1, 2 \ub54c\ubcf4\ub2e4 5\ubc30 \uc815\ub3c4 \ube60\ub974\uac8c \uc9c0\ub098\uac04 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub808\ubca8 3\uc5d0\ub294 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4, \uae30\uc220 \uc678\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4 \ubd80\uc871\ud568\uc774 \ub9ce\uc774 \ubcf4\uc600\ub358 \uac83 \uac19\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ubd80\uc871\ud55c \ubd80\ubd84\uc744 \uc54c\uc558\uae30\uc5d0, \uc55e\uc73c\ub85c \ub354\uc6b1 \uc131\uc7a5\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub0b4\uac00 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \ud300\uc6d0\ub4e4\uc774 \uc798 \ubcf4\ucda9\ud574 \uc918\uc11c \ub4e0\ub4e0\ud588\ub2e4."]}),"\n",(0,r.jsx)(e.h3,{id:"\uc544\uc26c\uc6b4-\uc810",children:"\uc544\uc26c\uc6b4 \uc810"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\ubb38\uc11c\ud654"})}),"\n",(0,r.jsxs)(e.p,{children:["\uac1c\uc778\uc801\uc73c\ub85c\ub294 \uae30\uc220 \uc678\uc801\uc73c\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ub0b4\uac00 \ud55c \ubd80\ubd84\uc744 \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c, \uc774\ud574\ud558\uae30 \uc27d\uac8c \ubb38\uc11c\ud654\ub97c \ud588\ub354\ub77c\uba74 \ud300\uc6d0\ub4e4\uc5d0\uac8c \ub354\uc6b1 \ub3c4\uc6c0\uc774 \ub418\uc5c8\uc744 \ud150\ub370 \uc774 \ubd80\ubd84\uc5d0 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ud22c\uc790\ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc5d0\uc11c \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ubc29\ud559 \uae30\uac04 \ub3d9\uc548 \ubb38\uc11c\ud654\ub97c \ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc778 \ube14\ub85c\uadf8 \uc62c\ub9ac\uba74\uc11c \uc870\uae08 \ub354 \ucc44\uc6cc\ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\ub0b4\uac00 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc774\uc790"})}),"\n",(0,r.jsxs)(e.p,{children:["\uc798 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc5ec\uc11c\ub77c\ub3c4 \uc911\uac04\uc740 \uac00\ub3c4\ub85d \ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub9d0\uc744 \ud558\uae30 \uc804\uc5d0 \uc815\ub9ac\ud574\uc11c \uc758\uacac\uc744 \ub0b4\ub294 \uac83, \ubc1c\ud45c \uc900\ube44, \uac10\uc815 \uc870\uc808 \ub4f1\ub4f1\n\ubabb\ud558\ub294 \ubd80\ubd84\uc744 \uc778\uc9c0\ud558\uace0, \uac1c\uc120\ud558\uc790."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\ucef4\ud3ec\ud2b8 \uc874 \ubc97\uc5b4\ub098\uae30"})}),"\n",(0,r.jsxs)(e.p,{children:["\uc870\uae08 \ub354 \ub3c4\uc804\uc801\uc73c\ub85c \ubaa9\ud45c\ub97c \uc7a1\uc558\uc73c\uba74 \uc88b\uc558\uc744 \uac83 \uac19\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub9e4\ubc88 \uadfc\uac70\ub97c \uac00\uc9c0\uace0 \uae30\uc220\uc744 \ub3c4\uc785\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ud558\uc9c0\ub9cc \uc9c0\uc18d\uc801\uc73c\ub85c \uac1c\uc120\ud558\ub824\uace0 \ud558\ub294 \ubd80\ubd84\uc774 \ub2e4\uc18c \ubd80\uc871\ud588\ub2e4."]}),"\n",(0,r.jsx)(e.h3,{id:"\uc88b\uc558\ub358-\uc810",children:"\uc88b\uc558\ub358 \uc810"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\uc88b\uc558\ub358 \uc810\ub3c4 \ubb38\uc11c\ud654"})}),"\n",(0,r.jsxs)(e.p,{children:[(0,r.jsx)(e.a,{href:"https://tripdraw.blog",children:"\ud300 \ube14\ub85c\uadf8"}),"\ub3c4 \uba3c\uc800 \ub3c4\uc785\ud558\uc790\uace0 \uc81c\uc548\ud558\uace0, \ub0b4\uac00 \ud588\ub358 \ubd80\ubd84\uc740 \ubb38\uc11c\ud654\ub97c \uaf64 \ub9ce\uc774 \ud574\uc11c \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ubc31\uc5d4\ub4dc \ud06c\ub8e8 4\uba85\uc774\uc11c \uac19\uc774 \ud55c \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c\ub294 \uae30\ub2a5 \uad6c\ud604\ud55c\ub2e4\uace0 \ubb38\uc11c\ud654\uac00 \uc870\uae08 \ubbf8\ud761\ud574\uc11c \ubcf4\ucda9\uc744 \ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\ub0b4\uac00 \ub514\uc790\uc778\ud55c \ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0"})}),"\n",(0,r.jsx)("img",{src:E.Z,width:"100"}),"\n",(0,r.jsxs)(e.p,{children:["\ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ud300\uc6d0\ub4e4\uc774 \ub300\ud45c \uc0c9\uc0c1(\ud30c\ub780\uc0c9)\uc744 \uc815\ud574\uc92c\uace0, \uc8fc\ub9d0 \ub3d9\uc548 \uc2e0\ub098\uac8c \ub85c\uace0 \ub514\uc790\uc778\uc744 \ud588\ub358 \uac83 \uac19\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\uc544\ub798\uc758 D \ubd80\ubd84\uc740 \uc720\ud29c\ube0c \uac15\uc758 \ub4e4\uc73c\uba74\uc11c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\uc11c \ubfcc\ub4ef\ud558\ub2e4."]}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.strong,{children:"\uae30\uc220 \uc120\ud0dd\uc758 \uc774\uc720"})}),"\n",(0,r.jsxs)(e.p,{children:["\uae30\uc220\uc758 \ud559\uc2b5 \ube44\uc6a9, \ud604\uc7ac \uad6c\uc870\uc5d0 \uc801\ud569\ud55c\uc9c0, \uc2e4\uc81c \uac00\uc9c0\uace0 \uc788\ub294 \ub9ac\uc18c\uc2a4\ub97c \uace0\ub824\ud574\uc11c \uae30\uc220 \uc120\ud0dd\uc744 \ud558\uace0, \ub3c4\uc785\ud588\ub358 \ubd80\ubd84\uc774 \uc88b\uc558\ub2e4.",(0,r.jsx)(e.br,{}),"\n","100% \uc88b\uc740 \uc120\ud0dd\uc77c \uc21c \uc5c6\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \uc120\ud0dd\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \uc874\uc7ac\ud55c\ub2e4\uba74 \ud655\ub960\uc744 \ub192\ud600\uc8fc\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsx)(e.h3,{id:"\ub9c8\uce58\uba70",children:"\ub9c8\uce58\uba70"}),"\n",(0,r.jsxs)(e.p,{children:["\ud50c\ub808\uc774\uc2a4\ud1a0\uc5b4\uc5d0 \uc571\uc774 \uc62c\ub77c\uac00 \uc788\ub294 \uac70 \ub108\ubb34 \uc2e0\uae30\ud558\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\uc548\ub4dc\ub85c\uc774\ub4dc \ube0c\ub808\uba58 \uc74c\uc545\ub300(\uba67\ub3fc\uc9c0, \uc218\ub2ec, \ud551\uad6c), \uadf8\ub9ac\uace0 \ubc31\uc5d4\ub4dc \ud300\uc6d0\ub4e4(\uccb4\uc778\uc800, \ud6c4\ucd94, \ub9ac\uc624) \ub108\ubb34 \uace0\uc0dd\uc774 \ub9ce\uc558\ub2e4."]})]})}function o(A={}){const{wrapper:e}={...(0,t.ah)(),...A.components};return e?(0,r.jsx)(e,{...A,children:(0,r.jsx)(l,{...A})}):l(A)}},3905:(A,e,n)=>{n.d(e,{ah:()=>c});var r=n(67294);function t(A,e,n){return e in A?Object.defineProperty(A,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):A[e]=n,A}function E(A,e){var n=Object.keys(A);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(A);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(A,e).enumerable}))),n.push.apply(n,r)}return n}function I(A){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?E(Object(n),!0).forEach((function(e){t(A,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(A,Object.getOwnPropertyDescriptors(n)):E(Object(n)).forEach((function(e){Object.defineProperty(A,e,Object.getOwnPropertyDescriptor(n,e))}))}return A}function s(A,e){if(null==A)return{};var n,r,t=function(A,e){if(null==A)return{};var n,r,t={},E=Object.keys(A);for(r=0;r<E.length;r++)n=E[r],e.indexOf(n)>=0||(t[n]=A[n]);return t}(A,e);if(Object.getOwnPropertySymbols){var E=Object.getOwnPropertySymbols(A);for(r=0;r<E.length;r++)n=E[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(A,n)&&(t[n]=A[n])}return t}var j=r.createContext({}),c=function(A){var e=r.useContext(j),n=e;return A&&(n="function"==typeof A?A(e):I(I({},e),A)),n},w={inlineCode:"code",wrapper:function(A){var e=A.children;return r.createElement(r.Fragment,{},e)}},l=r.forwardRef((function(A,e){var n=A.components,t=A.mdxType,E=A.originalType,j=A.parentName,l=s(A,["components","mdxType","originalType","parentName"]),o=c(n),i=t,h=o["".concat(j,".").concat(i)]||o[i]||w[i]||E;return n?r.createElement(h,I(I({ref:e},l),{},{components:n})):r.createElement(h,I({ref:e},l))}));l.displayName="MDXCreateElement"},17779:(A,e,n)=>{n.d(e,{Z:()=>r});const r="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAGwCAYAAADITjAqAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAABauSURBVHgB7d1viF3lncDx59yJsZpWU6wxoqmjLthGS2vBP4u7dEqb7FIXVKIFX9Qa3xTqiyisfWeNyEKphWZgLesbxyqLi4m0wiprXHCWIlUD1bKaRljt1CjGfzSmjdaYzNn73Dg2f5wkk8w95/nd+/nANCaZ0HHM3O/8nuc551SpRYvHJhYvXLhgrJquR+sqfblK9WiqqtGPfns0AdC6uk7bq6qaSvX09jpVU52q/kOanp78y+703PbJ1dtTS6rUoI+DVU2Ppbq6IokUQHRT3QFksvua/vCuXbsnmwxaIwFb+s2JsbozsqZb8W680uIEwEDqxuzeHLM3N37nl6nP+hawj6atNd3Z8ybRAhg6U1Wdbk8f7pncNrl6KvXBvAdMuADYx1R33+ze7kR2e5pn8xqwpSvuu747Pt6W7G0BsL/eRLbt8evuTfNkXgK2dGxitD5uwUSq6rEEALP7ZbVrz83zsazYScfotBX3r5k+buRZ8QLgCFxZLxx5Nq/YpWN01BNY3us6fuFIXi68KQHAXFVp3RuPXXdzOkpHFbDekuHCkXxE8ssJAI5a9Vy1a/dVR7OkOOeAfRSvJ5KDGgDMj6nuvtjX5xqxOQVMvADokzlH7IgDJl4A9NmcInZEARMvABpyxBE7omP0Hx3YGE0A0F/dgWnBL/JJ98O942EDdtrK+36anDYEoDH1V44/vneZ1iGNHOo3exeaVelHCQCademn/+aqd3e+9IunZnuHWffA8r5XvsOGG/IC0JLt3f2wC2fbD5t1CbG77/VT8QKgRYvr4zsTs/3mJwbso3tUXZkAoE11NTbbfRM7n/z+6bCbZwDQhNykTzqVeFDAlqy83/O8ACjJ6KcWdg66cfx+hzhcsAxAobZ/sGvP2dsnV2+f+YX9J7DjRsaSeAFQnsUHTmH7BczeFwClqlO1Zt+ffxywJd+4P586HE0AUKbFS785MTbzk79OYCPTjs0DULS6M/LxFNY7xJGPJx6/cOSPCQDK9vFhjt4EtnBkwVgCgPItPmHh3mbtXUK0fAhAENNVGss/9gJWpeprCQAiqOsr8g+V/S8Aounug32286kF6SsJAALJ+2Cd1OmMJQAIZLqqR/Me2GgCgECqlL7cqevOWQkAAqmnuxNYnTx1GYBgqiovIdajCQCC6VSVCQyAcEY7CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQlqQAPrkzCUnpi+edXI6adFx3X8+IZ104nHp5EULP/F93925K+1478P0p50fps1TO9KO3o/vJpiNgLUkf0FfPbYsrbjo9HTmqSf2vtCJ49U33+u9uD6+6fW0YXJrIqVLz/9cWj56Uvdtcbpk+Snz9nc6f57z5/vpzW/3wvbUC28nyKrTVt5XJxqVv7AfWHtZL1zEl19gv3fnM70X2WGS/x6vvGhp75uw5aN7p6ym5Ijlbx42bto2dJ93/krAGiZegym/oF679sk06PLf31VfW9ZdPfh8MasG+RuIiUdeSk9tfkfMhowlxIb1llbEa+Dk5bM8jeSJYNDsu9yd/z1Lk6e/O2/8au+fNz6zd0k3T2cMPgFr2DVjZyUG06ruVDJIAcvhWv2tc9INl5/b6PLgsVh58em9t1ffei+NP7jF/uSAE7CGfbG7yc1gWn72yWkQ5KXBNdec11smjCqvcuSpbM23vyBkA8weWMN+v/6KxOA6+5qHU1SDEK7Z5InslruedYJxwJjAYMhFXCqcqzyR5cNTeRIbX7/FYY8BIWAwxFaNLUs/vP5LAxuuA+XDKJeef4plxQEhYDCE8nLhnd+/sMhThf02sz92yfmnmsaCcy9EGDJ5qfCRH48NZbz2laex3jWZ7oITloDBkMjLhLdef0HvbViWDA8nT2O/umtFbw+QeCwhwhDIU8bdt1zcu+iXg/1w9d59wPH1LybiMIHBgMvRyktl4nVoN337C929sQsTcZjAYIDNxMuS4ZHJ18DlR77ka8byo10omwkMBpR4HZ18K6oHbr+sFzLKJmAwgMTr2OTP362rL0iUTcBgwMw8ske8jk1eTrQnVjYBgwEiXvMrRyzfH5IyCRgMiBwtD0udf/l04iDe4HgQCBgMiHyBsnj1R/7cugyhPAIGA+Cma0wJ/ZSn27t/cLGTiYURMAiu9xyvb9un6bc83eYHZFIOAYPg8r4Xzbjh8nPSiotOT5RBwCCwvHRo36tZP7nxQkuJhRAwCMrSYTvyfpilxDIIGARl6bA9eSlx2J+nVgIBg4DyQyktHbbLBc7tEzAIJi8drr7cAxjblicwU1i7BAyCyd/5m77K4F6J7RIwCCRPXy5YLkf+RuLqsWWJdggYBGLfpTyrfEPRGgGDebJjZ3+f4Gv6KpO9sPYIWMNefeu9xGDq939b01e5/Ldpx4JEozZPvWsDfkBtntqR+iXy9JUn0xz3P+3cvd+vf2bRgoG5w3uewPLdOXa8198pnP0JWMMemtyaVrqX2kAaf3BL6pdI3+HnYG2YfCU9vfmd3jdsr7556Mk0RywHIH9dXHL+KSmq1f90TvfvwIuJ5lSnrbyvTjTqP9b+XegvVA52zyMvpTvufT71Q56+fnXXilS6p154O42vf7H349HKqxM5ZvkWWdFWKvKU+ffffzzRnJFPn3vV2kSj8hd4vp+aB+TFl6eNf3v4/9KP/31z6pcVFy1NKy8ud2rfuGlbuv5ffp0mHn35mPcB8xJcntomHnk5vfbW+2n52Sf3vlYiyB9nnjrtczfHBNai/B1m/gL94uhJadmpi1IbzlhyQrp0ecwTVE9tfju99ub7qQ1b39rZXRp7Pz3+zOt93/f41c9WFDmN5BfqW+569pgmrsPZ+wyu88Ls/61bv8UyYoPsgbUovwDkt43dF8G2rBpbFjZgG554pbenOMjyclqJ8cp7XHdMPN/3eM9E8ndTO9Kt11+QSpe/lsaTgDXFMXoo2KoC7/KQp4wclSZP3OU9xstvmez7tXbHauY0Is0QMChUiUfn21wiy3tj1659sviIrbh4aaIZAgaFumR5WSdVS9jfyRH73p3PpJI5nNUcAYNCXTN2VipFXsIr5XBCPjTSr0sW5kPJJ0YHjYBBgfLyYSnXCuaDFKUFIwf16RfeSSXKh27sgzVDwKBAJd2t5drbnkwl+ue7flPsflj+BoT+EzAoUCkBy/tepV6Ymz+ufPF0ifK1nfSfgEFhSlk+zIF46Imyr7PLS4klTmEOcjRDwKAwpZw+zIc2Sr8tUo5XiVOYJ040Q8CgMKWcPuznLaLmU57CSmMPrBkCBgXJN4QtYflww+TWMDelzVNYaScSTWDNEDAoSCl7J4+3eH/Oo5Fv7FySKHfQj07AoCCl3IZo46ZgAStwudMU1n8CBgUp4ckAUfa+9pVvMcXwETAoRN74L2EJMWIM8j6YB0kOHwGDQpRy8WvUELT1cNPZOInYfwIGhSjl7hv54ZER5adkM1wEDArh7g0wNwIGBcjHrksJ2Ktv2ksiBgGDApi+jt2yUxelkvhGoP8EDApQyrO/MocPiELAoAB/u/zUVIqoD2Ms7REmjvX3n4BBAUp68T1jyQkpmjw1un3T8BEwaFlpL74R9+NMX8NJwKBlpb34Xnp++7ezmqtSrqGb4QBHMwQMWlbaxJNvQhttH6y06JrAmiFg0LISl+xWfX1ZiiLHq7Q7vwtYMwQMWlbiYzdKW5I7lFVj5cX2d7+PeTuuaAQMWlbiBJanmgh7YfkAzNVjn0+lMYE1Q8CgRcvPLvfE35przkulK/Vj9HyyZggYtOiMU8u95qr0KSxPriVOXxEfCBqVgEGLSr/mquQp7O4fXJxKZPpqjoBBi0oPWJ7AVn/rnFSaW6+/oMjDL9nTL7yTaIaAQYtOPnFhKt0PV3+pqKXEGy4/t/dWKhNYcwQMWlTaXThmc/ctFxdxl/q855Wnr1LleDmB2BwBg5bk+x9GuQFt/jgfWHtZqxHL8brzxgtTyRzgaJaAQUuiPXcr7znliLWxb5eXDEuPV/b4pm2J5ggYtCTic7dyxB65c6yxgx158rvz+xcWvWw4Iy8dmsCatSABrYj42JIZ+WDH8rMXp/H1W/p25/V8cCRPXaWeNjzQU04fNk7AoCWfWRT7y+/qsWW9t3seeSlNPPryvIUshytffxbtsS7jD25JNEvAoCWRJ7B9zRxr3zC5NT00+cpRLaPlpcIcwxUXnR7yeWT539npw+YJGLQkwjVgczEzke3Y+WHvBf3pzW+nzVM7ej/f8d6H+71vXhY8o/u2fPSkXrCix3x8/YuJ5gkYtCT6EuJs8jS18uLTe2/DwOGN9jiFCC2JcjiBQxt/0PTVFgGDFkS6iJnZ5elrQ3ffj3YIGLQg4jVgHOyWu55NtEfAoAXR7sLBwfKpS3tf7RIwgDnKJytd99U+AYMWlPwkZg7vnkdfct1XAQQMWmAJMa4cLicPyyBgAEcoLx1ee9uTiTIIGLTANWAx5TtuWDosh4ABHIF80+L8RjkEDFqw7NRFiTjse5VJwAAOIccr73sdeENi2idg0IJBvZHvIPrej5+x71UoAYMWuA9iDLf87Nm0eerdRJkEDOATrFu/JW14wo16SyZg0ALH6MuW4+XQRvkEDGAf4hWHgAF8RLxiETCAJF4ROcsLDbP/VZ477n3eXTYCEjBgaOWb8+anKm/c9HoiHgEDhlK+ODlfpOw6r7gEDBg6OVrusBGfgAFDZcPkK+mOiefd23AACBgwNBzWGCwCBgy8vFSYD2s89cLbicEhYMBA27hpW7rlX39jyXAACRg07MwlrgNrQj4iP77+RUuGA0zAoGEmgf7LS4V5ydApw8EmYNCwHX8WsH7KU9e6B7ckBp+AAQPB1DV8BAwIzV7X8BIwIKx8wvCOif81dQ0pAQPCcV0XmYABYeTlwolHX3ZIgx4BA0LIe1z5gZMuQ2CGgAFFc7qQ2QgYNMwL8ZHJ4cqnC+1zMRsBA4oiXBwpAQOKIFzMlYABrRIujpaAQQvyPtiZpw73XemFi2MlYECjNkxuTQ9NviJcHDMBA/pu5gLke/7zJddxMW8EDFrw2pvvD8US4uapd7vT1ta04YlXhIt5J2DAvLO/RRMEDFqw9a2d6ZJ0ShoklglpmoABx8S0RVsEDFoQfULJe1uPb9pm2qJVAgYtyMtt0eSPecPkK71wmbYogYBBC/60c3eKIEcrT1t5iXDz7981bVEUAYMWvLtzVypZnrDypOX4OyUTMGhBiVEQLaIRMGjBa2+9n9o2szwoWkQlYNCCHX9uJxY5WjlYv87T1jOvixahCRhhlTDFHK18N/qm7kj/6pvvpY2bXnd6kIEjYEPu6RfeSVHlU3GR5XsErrnmvDTf9l0azOHKAYNBJGBDLk8B+QXvpEXHpUjyJBF9+eueR15Kq8aWzcsUloM1cwjDcXeGhYDRu8bn1usvSJHk6SW6/I3Dtbc9mR64/bI5R2xmWXDz1A57WQyt6rSV99WJoXfr6gvSDd86N0Wwbv2WNP7gi2lQ5Hj95MavpkvOn/3mvjlYT29+p3f44unNb1sWhCRg7OPS8z/XW9JaPnpy70W1lGXFPKnkpc6ZJbJBPYiQP/8rLlqali1Z1Pv51jd3mrDgEAQMgJA6CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAELKAZtKABDLdhMYAAFVU51UV1MJACKpp7d3qmr6DwkAAqk63Qmsnq6eSwAQSV3/oVNbQgQgmunpyc6uPbsnEwAE8pfd6bnO9snV25Oj9ABEUaWp3K69x+jr+uEEAAFUKU3mH3sBq6c7kwkAAqjqqjd09QKW98HqOm1PAFC493ftPbvRC1heS6yq+n8SABSsqtK9H53d+OvNfKvp6XUJAAo2s3zY++d9f2PJivv+2K3b4gQApanS1BuPXXf2zE/3u5lvp6rHEwAUqJpOt+/78/0C9pdd0+sc5gCgON3pK43smdz3l/YLWO/CMFMYAIWp6vrn2/5r9dS+v3bQ88DyFNYrHQCUoNukbRu/u/bAXz4oYL0j9QesMwJAW2ZrUjXbHzjtH+5/ItX1WAKA1lS/fGPjd676pN/pzPpHqt2rHegAoC11d1Gw6uy+ebbfnzVgebOsqi0lAtCOTp1uPvDgxr5GDvWHd778i6c+fc6Vn+2OY5cmAGhKVY2/sfG6Hx3qXTrpMD74cHptnarnEgA047dvPPadmw73TocNWO/asM7uqxytB6Dvuq2pOnuuPLJ3PUJL/3FitK5Hnujuqo0mAJhvOV7Vnq8fat9r/3efAxEDoC/mGK+9f2SORAyAeXUU8coOuwd2oN7x+u7/kYMdAMyD3x5NvLI5T2D7Om3Fz9elqlqTAGCuqmr8gw92r515wvKc/3g6RktX3Hf9dEo/9SBMAI5E7w4bVbr9jceuW5eOwTEHLOvti013uh9IdUUCgNnU1WQ1snv10SwZHmheAjYjT2N1J93mgAcA+8kHNabT7dsev+7eNE/mNWAzlq78+dq6qr4rZADDLS8XdlI9np81ebR7XbPpS8CyvKyY9oyMmcgAhk8/wzWjbwHb15JvTFzZGelcWafuVAbAQOodzkjdPa7p3ePb/nv1ZOqzRgI2Y/HYxOKFI2msF7Oq+prJDCC8qVTVD9e7pyd37UmT/Zq2PkmjATtQDtqnFqSvpE5nbLquzuqWe7Rb8MXdT8ZolRzLByjEVO9/62qqTnV+VuRv63rPVNPBOtD/A6oeNVega6lDAAAAAElFTkSuQmCC"}}]); \ No newline at end of file diff --git a/assets/js/4b79a3c9.061deffc.js b/assets/js/4b79a3c9.061deffc.js deleted file mode 100644 index e0977f4fa..000000000 --- a/assets/js/4b79a3c9.061deffc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5838],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),u=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=u(e.components);return r.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),d=u(n),m=a,g=d["".concat(p,".").concat(m)]||d[m]||c[m]||i;return n?r.createElement(g,o(o({ref:t},s),{},{components:n})):r.createElement(g,o({ref:t},s))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var u=2;u<i;u++)o[u]=n[u];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}d.displayName="MDXCreateElement"},85162:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(67294),a=n(86010);const i="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(i,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>E});var r=n(87462),a=n(67294),i=n(86010),o=n(12466),l=n(16550),p=n(91980),u=n(67392),s=n(50012);function c(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,u.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function g(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.k6)(),i=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,p._X)(i),(0,a.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(r.location.search);t.set(i,e),r.replace({...r.location,search:t.toString()})}),[i,r])]}function v(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,i=d(e),[o,l]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:i}))),[p,u]=g({queryString:n,groupId:r}),[c,v]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,i]=(0,s.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:r}),b=(()=>{const e=p??c;return m({value:e,tabValues:i})?e:null})();(0,a.useLayoutEffect)((()=>{b&&l(b)}),[b]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),v(e)}),[u,v,i]),tabValues:i}}var b=n(72389);const h="tabList__CuJ",k="tabItem_LNqP";function f(e){let{className:t,block:n,selectedValue:l,selectValue:p,tabValues:u}=e;const s=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=s.indexOf(t),r=u[n].value;r!==l&&(c(t),p(r))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=s.indexOf(e.currentTarget)+1;t=s[n]??s[0];break}case"ArrowLeft":{const n=s.indexOf(e.currentTarget)-1;t=s[n]??s[s.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>s.push(e),onKeyDown:m,onClick:d},o,{className:(0,i.Z)("tabs__item",k,o?.className,{"tabs__item--active":l===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const i=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=i.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},i.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function T(e){const t=v(e);return a.createElement("div",{className:(0,i.Z)("tabs-container",h)},a.createElement(f,(0,r.Z)({},e,t)),a.createElement(y,(0,r.Z)({},e,t)))}function E(e){const t=(0,b.Z)();return a.createElement(T,(0,r.Z)({key:String(t)},e))}},60036:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>p,default:()=>m,frontMatter:()=>l,metadata:()=>u,toc:()=>c});var r=n(87462),a=(n(67294),n(3905)),i=n(74866),o=n(85162);const l={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",slug:"route-image-async-with-event",tags:["async","event"]},p=void 0,u={permalink:"/route-image-async-with-event",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",source:"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",description:"\uc774\uc804 \uae00",date:"2023-08-13T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 13\uc77c",tags:[{label:"async",permalink:"/tags/async"},{label:"event",permalink:"/tags/event"}],readingTime:11.2,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",slug:"route-image-async-with-event",tags:["async","event"]},prevItem:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/cloudwatch"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",permalink:"/route-image-implementation"}},s={authorsImageUrls:[]},c=[{value:"\uc774\uc804 \uae00",id:"\uc774\uc804-\uae00",level:2},{value:"\uac1c\uc694",id:"\uac1c\uc694",level:2},{value:"\uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120",id:"\uc8fc\uae30\ub2a5\uc758-\uc751\ub2f5\uc18d\ub3c4-\uac1c\uc120",level:3},{value:"\ud655\uc7a5\uc131 \ub300\ube44",id:"\ud655\uc7a5\uc131-\ub300\ube44",level:3},{value:"\ube44\ub3d9\uae30 \ucc98\ub9ac",id:"\ube44\ub3d9\uae30-\ucc98\ub9ac",level:2},{value:"\ube44\ub3d9\uae30 \uc124\uc815",id:"\ube44\ub3d9\uae30-\uc124\uc815",level:3},{value:"@Async \uc801\uc6a9",id:"async-\uc801\uc6a9",level:3},{value:"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810",id:"\ube44\ub3d9\uae30-\ucc98\ub9ac\uc2dc-\ubb38\uc81c\uc810",level:3},{value:"\uc774\ubca4\ud2b8 \uc0ac\uc6a9",id:"\uc774\ubca4\ud2b8-\uc0ac\uc6a9",level:2},{value:"\uc774\ubca4\ud2b8 \ubc1c\ud589",id:"\uc774\ubca4\ud2b8-\ubc1c\ud589",level:3},{value:"\uc774\ubca4\ud2b8 \uad6c\ub3c5",id:"\uc774\ubca4\ud2b8-\uad6c\ub3c5",level:3},{value:"\ud14c\uc2a4\ud2b8",id:"\ud14c\uc2a4\ud2b8",level:3},{value:"\uacb0\uacfc",id:"\uacb0\uacfc",level:2},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],d={toc:c};function m(e){let{components:t,...l}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,l,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\uc774\uc804-\uae00"},"\uc774\uc804 \uae00"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"./route-image-intro"},"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"./route-image-implementation"},"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604")),(0,a.kt)("h2",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,a.kt)("p",null,"\ud604\uc7ac \uc5ec\ud589\uc744 \ub9c8\uce58\ub294 \uacbd\uc6b0, \uac10\uc0c1\uc744 \uc0dd\uc131\ud558\ub294 \uacbd\uc6b0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \uc704\uce58 \uc815\ubcf4\uc758 \uac1c\uc218\uc5d0 \uc815\ube44\ub840\ud558\uc5ec \uc0dd\uc131 \uc2dc\uac04\uc774 \uc99d\uac00\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ube44\ub3d9\uae30\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\uc5ec \uc0ac\uc6a9\uc790\uc758 \uacbd\ud5d8\uc744 \uac1c\uc120\uc2dc\ud0ac \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("h3",{id:"\uc8fc\uae30\ub2a5\uc758-\uc751\ub2f5\uc18d\ub3c4-\uac1c\uc120"},"\uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120"),(0,a.kt)("p",null,"\uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc774 \uc8fc\uae30\ub2a5\uc774\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ubd80\uae30\ub2a5\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ud604\uc7ac \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc758 \uc751\ub2f5 \uc18d\ub3c4\uac00 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uc5ec\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\uc694 \uc2dc\uac04\uc774 1\ucd08 \uc774\uc0c1 \uac78\ub9ac\ub294 \uacbd\uc6b0\uac00 \uc874\uc7ac\ud558\uae30\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uace0 \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131 \uae30\ub2a5\uc758 \uc751\ub2f5 \uc2dc\uac04\uc744 \uac1c\uc120\ud558\ub294 \uac83\uc774 \ub354 \uc911\uc694\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\ud655\uc7a5\uc131-\ub300\ube44"},"\ud655\uc7a5\uc131 \ub300\ube44"),(0,a.kt)("p",null,"\ud604\uc7ac 10\ubd84 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc11c\ubc84\uc5d0 \uc800\uc7a5\ud558\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc870\uae08 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uadf8\ub9ac\ub294 \uacbd\uc6b0 \ud558\ub098\uc758 \uc5ec\ud589\uc5d0 \ub9ce\uc740 \uc704\uce58 \uc815\ubcf4\uac00 \uc800\uc7a5\ub420 \uc218\ubc16\uc5d0 \uc5c6\uace0 \ub530\ub77c\uc11c \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uac78\ub9ac\ub294 \uc2dc\uac04\uc774 \ub354 \uae38\uc5b4\uc9c8 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ucd94\ud6c4\uc5d0 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \uacbd\uc6b0\ub97c \ub300\ube44\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\ub294 \uac83\uc774 \ud569\ub2f9\ud558\ub2e4. "),(0,a.kt)("h2",{id:"\ube44\ub3d9\uae30-\ucc98\ub9ac"},"\ube44\ub3d9\uae30 \ucc98\ub9ac"),(0,a.kt)("p",null,"@Async\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uba54\uc11c\ub4dc\ub97c \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ub9cc\ub4e4 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\ube44\ub3d9\uae30-\uc124\uc815"},"\ube44\ub3d9\uae30 \uc124\uc815"),(0,a.kt)("p",null,"\uc0ac\uc6a9\ud558\uae30 \uc804\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c EnableAsync \uc124\uc815\uc744 \ud574\uc57c\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uc124\uc815\uc744 \uc801\uc6a9\ud558\uba74 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc\uc5d0 @Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec\uc8fc\uae30\ub9cc \ud558\uba74 \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="AsyncConfig"',title:'"AsyncConfig"'},"@EnableAsync\n@Configuration\npublic class AsyncConfig {\n}\n")),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \ud560 \ub54c \ub9e4\ubc88 \uc0c8\ub85c\uc6b4 \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ub808\ub4dc \ud480 \uc124\uc815\uc744 \ub530\ub85c \ud574\uc918\uc57c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ThreadPoolTaskExecutor\ub97c \ub530\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc544\ub3c4 \uae30\ubcf8\uc801\uc73c\ub85c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uac00 \uc0dd\uc131\uc744 \ub3c4\uc640\uc900\ub2e4. "),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing.\n7.7. Task Execution and Scheduling, Spring Boot Docs")),(0,a.kt)("h3",{id:"async-\uc801\uc6a9"},"@Async \uc801\uc6a9"),(0,a.kt)("p",null,"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\uc5d0 Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="RouteImageGenerator"',title:'"RouteImageGenerator"'},"@Async\npublic void generate(\n List<Double> latitudes,\n List<Double> longitudes,\n List<Double> pointedLatitudes,\n List<Double> pointedLongitudes,\n Long tripId\n) {\n // \uc774\ubbf8\uc9c0 \uc0dd\uc131\n RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);\n Coordinates coordinates = Coordinates.of(latitudes, longitudes);\n Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);\n drawImage(coordinates, routeImageDrawer, pointedCoordinates);\n\n // \uc774\ubbf8\uc9c0 \uc800\uc7a5\n String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());\n\n // \uc790\uc6d0 \ud560\ub2f9 \ud574\uc81c\n routeImageDrawer.dispose();\n\n // \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac12 \ubcc0\uacbd\n Trip trip = tripRepository.findById(tripId)\n .orElseThrow();\n trip.changeRouteImageUrl(imageUrl);\n tripRepository.save(trip);\n}\n")),(0,a.kt)("h3",{id:"\ube44\ub3d9\uae30-\ucc98\ub9ac\uc2dc-\ubb38\uc81c\uc810"},"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810"),(0,a.kt)("p",null,"\ud604\uc7ac \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uace0 \uc800\uc7a5 \ud6c4, \uc800\uc7a5 \uacbd\ub85c\ub97c DB\uc5d0 \ubc18\uc601\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ud615\ud0dc\uac00 \ub418\uba70 \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \ubb38\uc81c\uac00 \uc0dd\uae34\ub2e4. "),(0,a.kt)("mermaid",{value:"graph LR\n trip[trip: \uc5ec\ud589 \uad00\ub828 \ud328\ud0a4\uc9c0] --\x3e draw[draw: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294 \ud328\ud0a4\uc9c0]\n draw --\x3e trip"}),(0,a.kt)("p",null,"\uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uacfc \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4. "),(0,a.kt)("mermaid",{value:"graph LR\n\tsubgraph draw\n\t\tdirection LR\n\t\tRG[RouteImageGenerator] -- DB \ubc18\uc601 \uc694\uccad --\x3e ILR[ImageLinkTripRepository]\n\tend\n subgraph trip\n\t\tdirection LR\n\t\tTS[TripService] -- \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e RG\n\t\tILRI[ImageLinkTripRepositoryImpl] -- \uad6c\ud604 --\x3e ILR\n\tend\n\n\ttrip --\x3e draw"}),(0,a.kt)("p",null,"\ud328\ud0a4\uc9c0 \uac04 \uc758\uc874\uc131\uc740 \ud574\uacb0\ub418\uc5c8\uc9c0\ub9cc, \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5\uc744 \uc704\ud574 tripId\ub97c \ubc1b\uc544\uc57c\ud558\ub294 \ub4f1\uc758 \ub17c\ub9ac\uc801\uc778 \uc758\uc874\uc131\uc740 \uc544\uc9c1 \ud574\uacb0\ub418\uc9c0 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4. "),(0,a.kt)("h2",{id:"\uc774\ubca4\ud2b8-\uc0ac\uc6a9"},"\uc774\ubca4\ud2b8 \uc0ac\uc6a9"),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uba74 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc758 \ube44\uad00\uc2ec\uc0ac(ex. \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131)\uc744 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("h3",{id:"\uc774\ubca4\ud2b8-\ubc1c\ud589"},"\uc774\ubca4\ud2b8 \ubc1c\ud589"),(0,a.kt)("p",null,"\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \uba3c\uc800 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 ApplicationEventPublisher \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c ApplicationContext\uac00 \uad6c\ud604\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="TripService & TripUpdateEvent"',title:'"TripService',"&":!0,'TripUpdateEvent"':!0},"public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {\n ...\n\n // \uc774\ubca4\ud2b8 \ubc1c\ud589\n applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));\n}\n\npublic record TripUpdateEvent(Long tripId) {\n}\n")),(0,a.kt)("p",null,"\uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \ub54c \ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc774 \uc911\uc694\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\ub294 \ub3c4\uba54\uc778\uc758 \ud589\uc704\ub97c \ub2f4\uace0 \uc788\ub294 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589(ex. RouteImageGenerateEvent)\ud55c\ub2e4\uba74 \ub17c\ub9ac\uc801\uc778 \uc758\uc874 \uad00\uacc4\uac00 \ub0a8\uc544\uc788\uae30\uc5d0 \uc774\ubca4\ud2b8\ub97c \uc801\uc808\ud788 \uc0ac\uc6a9\ud588\ub2e4\uace0 \ubcf4\uae30 \uc5b4\ub835\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc740 \uc8fc\uae30\ub2a5\uc774 \uc5b4\ub5a4 \ud589\uc704(ex. TripUpdateEvent)\ub97c \ud588\ub294\uc9c0\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \ub2f4\uaca8\uc788\ub294 \uc774\ubca4\ud2b8\uba85\uc73c\ub85c \ubc1c\ud589\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\uc774\ubca4\ud2b8-\uad6c\ub3c5"},"\uc774\ubca4\ud2b8 \uad6c\ub3c5"),(0,a.kt)("p",null,"\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc2e4\ud589\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\uae30 \uc704\ud558\uc5ec ",(0,a.kt)("inlineCode",{parentName:"p"},"@Async")," \uc560\ub108\ud14c\uc774\uc158\uc744 \uc801\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubca4\ud2b8\uc758 \uad6c\ub3c5\uc740 \uc5ec\ud589\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \uc885\ub8cc\ub420 \ub54c \uc5ec\ud589\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \uac00\uc9c0\uace0 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud574 ",(0,a.kt)("inlineCode",{parentName:"p"},"@TransactionalEventListener"),"\ub97c \uc0ac\uc6a9\ud588\ub2e4. "),(0,a.kt)("admonition",{title:"TransactionPhase \uc124\uc815",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"TransactionPhase\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \uc774\ubca4\ud2b8\ub97c \uc5b4\ub5a4 \ub2e8\uacc4\uc5d0\uc11c \uc218\uc2e0\ud558\uace0 \ucc98\ub9ac\ud560\uc9c0\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("p",{parentName:"admonition"},"AFTER_COMMIT(\uae30\ubcf8\uac12): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ucee4\ubc0b \ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,a.kt)("br",{parentName:"p"}),"\n","AFTER_ROLLBACK: \ud2b8\ub79c\uc7ad\uc158\uc774 \ub864\ubc31\ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,a.kt)("br",{parentName:"p"}),"\n","AFTER_COMPLETION: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub610\ub294 \ub864\ubc31 \ub418\uc5c8\uc744 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,a.kt)("br",{parentName:"p"}),"\n","BEFORE_COMMIT: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub418\uae30 \uc804 \uc774\ubca4\ud2b8 \uc2e4\ud589 ")),(0,a.kt)("p",null,"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uae30 \uc704\ud574 @Transactional \uc560\ub108\ud14c\uc774\uc158\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="TripUpdateEventHandler"',title:'"TripUpdateEventHandler"'},"@Component\npublic class TripUpdateEventHandler {\n\n private final RouteImageGenerator routeImageGenerator;\n private final TripRepository tripRepository;\n\n public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {\n this.routeImageGenerator = routeImageGenerator;\n this.tripRepository = tripRepository;\n }\n\n @Async\n @TransactionalEventListener(phase = AFTER_COMMIT)\n public void handle(TripUpdateEvent tripUpdateEvent) {\n Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());\n\n String imageUrl = routeImageGenerator.generate(\n trip.getLatitudes(),\n trip.getLongitudes(),\n trip.getPointedLatitudes(),\n trip.getPointedLongitudes()\n );\n\n trip.changeRouteImageUrl(imageUrl);\n tripRepository.save(trip);\n }\n}\n")),(0,a.kt)("p",null,"\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c\uc368 \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ubb38\uc81c\uac00 \ub2e4\uc74c\uacfc \uac19\uc774 \ud574\uacb0\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \uc8fc\uae30\ub2a5\uacfc \ubd80\uae30\ub2a5\uc744 \ubd84\ub9ac\ud568\uc73c\ub85c\uc368 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc5d0 \ub300\ud55c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uc5c8\ub2e4."),(0,a.kt)("mermaid",{value:"graph LR\n subgraph trip\n TripServcie -- \ubc1c\ud589 --\x3e TripUpdateEvent\n TripRepository\n end\n\n subgraph draw\n TripUpdateEventHandler -- \uad6c\ub3c5 \ud6c4 \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e TripUpdateEvent\n TripUpdateEventHandler -- \uc0dd\uc131\ub41c \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5 --\x3e TripRepository\n end"}),(0,a.kt)("h3",{id:"\ud14c\uc2a4\ud2b8"},"\ud14c\uc2a4\ud2b8"),(0,a.kt)("p",null,"\ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud14c\uc2a4\ud2b8\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \ubc29\ubc95\uc774 \uc788\ub2e4. "),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d",label:"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@SpringBootTest\npublic class TripUpdateEventHandlerIntegrationTest {\n\n ...\n\n @Test\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\n // given\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\n .willReturn(\uc5ec\ud589());\n\n // when\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\n\n // then\n then(routeImageGenerator)\n .should(Mockito.timeout(5000).times(1))\n .generate(any(), any(), any(), any());\n }\n}\n"))),(0,a.kt)(o.Z,{value:"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d",label:"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@ContextConfiguration(classes = TestSyncConfig.class)\n@SpringBootTest\npublic class TripUpdateEventHandlerIntegrationTest {\n\n ...\n\n @Test\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\n // given\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\n .willReturn(\uc5ec\ud589());\n\n // when\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\n\n // then\n then(routeImageGenerator)\n .should(times(1))\n .generate(any(), any(), any(), any());\n }\n}\n")))),(0,a.kt)("p",null,"\ucc98\uc74c\uc5d0\ub294 \ud14c\uc2a4\ud2b8\uc5d0\uc11c\ub9cc \ub3d9\uae30\ub85c \uc124\uc815 \ud6c4 \uac80\uc99d\ud558\ub824\uace0 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud1b5\ud569 \ud14c\uc2a4\ud2b8\uc5d0\uc120 ",(0,a.kt)("inlineCode",{parentName:"p"},"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1 \uc885\ub8cc\ub418\uc5c8\uc744 \ub54c \ube44\ub3d9\uae30\ub85c \uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0")," \uac80\uc99d\uc774 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 \ucd5c\uc885\uc801\uc73c\ub85c ",(0,a.kt)("inlineCode",{parentName:"p"},"Mockito.timeout")," \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \ud1b5\uacfc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4. "),(0,a.kt)("h2",{id:"\uacb0\uacfc"},"\uacb0\uacfc"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./time.png",src:n(89297).Z,width:"1682",height:"678"})),(0,a.kt)("p",null,"\uc704 \uc751\ub2f5 \uc2dc\uac04\uc740 \uc704\uce58 \uc815\ubcf4 1000\uac1c\ub97c \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ud55c \uac12\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc751\ub2f5 \uc2dc\uac04\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ud3ec\ud568\ub418\uc9c0 \uc54a\uc544\uc11c \uc131\ub2a5\uc774 \uac1c\uc120\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. "),(0,a.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.task-execution-and-scheduling"},"7.7. Task Execution and Scheduling, Spring Boot Docs"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.baeldung.com/spring-events"},"Spring Events, Baeldung"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/7835/"},"\ud68c\uc6d0\uc2dc\uc2a4\ud15c \uc774\ubca4\ud2b8\uae30\ubc18 \uc544\ud0a4\ud14d\ucc98 \uad6c\ucd95\ud558\uae30")))}m.isMDXComponent=!0},89297:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/time-8bef9a6cf2dcace85f12ae5624da94f5.png"}}]); \ No newline at end of file diff --git a/assets/js/4b79a3c9.c3ac845d.js b/assets/js/4b79a3c9.c3ac845d.js new file mode 100644 index 000000000..314e430b1 --- /dev/null +++ b/assets/js/4b79a3c9.c3ac845d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5838],{261:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=t(85893),a=t(3905),i=t(74866),s=t(85162);const o={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",slug:"route-image-async-with-event",tags:["async","event"]},l=void 0,c={permalink:"/route-image-async-with-event",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",source:"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",description:"\uc774\uc804 \uae00",date:"2023-08-13T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 13\uc77c",tags:[{label:"async",permalink:"/tags/async"},{label:"event",permalink:"/tags/event"}],readingTime:11.2,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",slug:"route-image-async-with-event",tags:["async","event"]},unlisted:!1,prevItem:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/cloudwatch"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",permalink:"/route-image-implementation"}},u={authorsImageUrls:[]},d=[{value:"\uc774\uc804 \uae00",id:"\uc774\uc804-\uae00",level:2},{value:"\uac1c\uc694",id:"\uac1c\uc694",level:2},{value:"\uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120",id:"\uc8fc\uae30\ub2a5\uc758-\uc751\ub2f5\uc18d\ub3c4-\uac1c\uc120",level:3},{value:"\ud655\uc7a5\uc131 \ub300\ube44",id:"\ud655\uc7a5\uc131-\ub300\ube44",level:3},{value:"\ube44\ub3d9\uae30 \ucc98\ub9ac",id:"\ube44\ub3d9\uae30-\ucc98\ub9ac",level:2},{value:"\ube44\ub3d9\uae30 \uc124\uc815",id:"\ube44\ub3d9\uae30-\uc124\uc815",level:3},{value:"@Async \uc801\uc6a9",id:"async-\uc801\uc6a9",level:3},{value:"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810",id:"\ube44\ub3d9\uae30-\ucc98\ub9ac\uc2dc-\ubb38\uc81c\uc810",level:3},{value:"\uc774\ubca4\ud2b8 \uc0ac\uc6a9",id:"\uc774\ubca4\ud2b8-\uc0ac\uc6a9",level:2},{value:"\uc774\ubca4\ud2b8 \ubc1c\ud589",id:"\uc774\ubca4\ud2b8-\ubc1c\ud589",level:3},{value:"\uc774\ubca4\ud2b8 \uad6c\ub3c5",id:"\uc774\ubca4\ud2b8-\uad6c\ub3c5",level:3},{value:"\ud14c\uc2a4\ud2b8",id:"\ud14c\uc2a4\ud2b8",level:3},{value:"\uacb0\uacfc",id:"\uacb0\uacfc",level:2},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function p(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",mermaid:"mermaid",p:"p",pre:"pre",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"\uc774\uc804-\uae00",children:"\uc774\uc804 \uae00"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"./route-image-intro",children:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"./route-image-implementation",children:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604"})]}),"\n",(0,r.jsx)(n.h2,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,r.jsxs)(n.p,{children:["\ud604\uc7ac \uc5ec\ud589\uc744 \ub9c8\uce58\ub294 \uacbd\uc6b0, \uac10\uc0c1\uc744 \uc0dd\uc131\ud558\ub294 \uacbd\uc6b0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \uc704\uce58 \uc815\ubcf4\uc758 \uac1c\uc218\uc5d0 \uc815\ube44\ub840\ud558\uc5ec \uc0dd\uc131 \uc2dc\uac04\uc774 \uc99d\uac00\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ube44\ub3d9\uae30\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\uc5ec \uc0ac\uc6a9\uc790\uc758 \uacbd\ud5d8\uc744 \uac1c\uc120\uc2dc\ud0ac \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc8fc\uae30\ub2a5\uc758-\uc751\ub2f5\uc18d\ub3c4-\uac1c\uc120",children:"\uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120"}),"\n",(0,r.jsxs)(n.p,{children:["\uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc774 \uc8fc\uae30\ub2a5\uc774\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ubd80\uae30\ub2a5\uc774\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \ud604\uc7ac \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc758 \uc751\ub2f5 \uc18d\ub3c4\uac00 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uace0 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uc5ec\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc18c\uc694 \uc2dc\uac04\uc774 1\ucd08 \uc774\uc0c1 \uac78\ub9ac\ub294 \uacbd\uc6b0\uac00 \uc874\uc7ac\ud558\uae30\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uace0 \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131 \uae30\ub2a5\uc758 \uc751\ub2f5 \uc2dc\uac04\uc744 \uac1c\uc120\ud558\ub294 \uac83\uc774 \ub354 \uc911\uc694\ud558\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ud655\uc7a5\uc131-\ub300\ube44",children:"\ud655\uc7a5\uc131 \ub300\ube44"}),"\n",(0,r.jsxs)(n.p,{children:["\ud604\uc7ac 10\ubd84 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc11c\ubc84\uc5d0 \uc800\uc7a5\ud558\uace0 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc870\uae08 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uadf8\ub9ac\ub294 \uacbd\uc6b0 \ud558\ub098\uc758 \uc5ec\ud589\uc5d0 \ub9ce\uc740 \uc704\uce58 \uc815\ubcf4\uac00 \uc800\uc7a5\ub420 \uc218\ubc16\uc5d0 \uc5c6\uace0 \ub530\ub77c\uc11c \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uac78\ub9ac\ub294 \uc2dc\uac04\uc774 \ub354 \uae38\uc5b4\uc9c8 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ucd94\ud6c4\uc5d0 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \uacbd\uc6b0\ub97c \ub300\ube44\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\ub294 \uac83\uc774 \ud569\ub2f9\ud558\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\ube44\ub3d9\uae30-\ucc98\ub9ac",children:"\ube44\ub3d9\uae30 \ucc98\ub9ac"}),"\n",(0,r.jsx)(n.p,{children:"@Async\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uba54\uc11c\ub4dc\ub97c \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ub9cc\ub4e4 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"\ube44\ub3d9\uae30-\uc124\uc815",children:"\ube44\ub3d9\uae30 \uc124\uc815"}),"\n",(0,r.jsxs)(n.p,{children:["\uc0ac\uc6a9\ud558\uae30 \uc804\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c EnableAsync \uc124\uc815\uc744 \ud574\uc57c\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud574\ub2f9 \uc124\uc815\uc744 \uc801\uc6a9\ud558\uba74 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc\uc5d0 @Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec\uc8fc\uae30\ub9cc \ud558\uba74 \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",metastring:'title="AsyncConfig"',children:"@EnableAsync\n@Configuration\npublic class AsyncConfig {\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \ud560 \ub54c \ub9e4\ubc88 \uc0c8\ub85c\uc6b4 \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ub808\ub4dc \ud480 \uc124\uc815\uc744 \ub530\ub85c \ud574\uc918\uc57c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ThreadPoolTaskExecutor\ub97c \ub530\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc544\ub3c4 \uae30\ubcf8\uc801\uc73c\ub85c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uac00 \uc0dd\uc131\uc744 \ub3c4\uc640\uc900\ub2e4."}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing.\n7.7. Task Execution and Scheduling, Spring Boot Docs"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"async-\uc801\uc6a9",children:"@Async \uc801\uc6a9"}),"\n",(0,r.jsx)(n.p,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\uc5d0 Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ud55c\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",metastring:'title="RouteImageGenerator"',children:"@Async\npublic void generate(\n List<Double> latitudes,\n List<Double> longitudes,\n List<Double> pointedLatitudes,\n List<Double> pointedLongitudes,\n Long tripId\n) {\n // \uc774\ubbf8\uc9c0 \uc0dd\uc131\n RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);\n Coordinates coordinates = Coordinates.of(latitudes, longitudes);\n Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);\n drawImage(coordinates, routeImageDrawer, pointedCoordinates);\n\n // \uc774\ubbf8\uc9c0 \uc800\uc7a5\n String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());\n\n // \uc790\uc6d0 \ud560\ub2f9 \ud574\uc81c\n routeImageDrawer.dispose();\n\n // \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac12 \ubcc0\uacbd\n Trip trip = tripRepository.findById(tripId)\n .orElseThrow();\n trip.changeRouteImageUrl(imageUrl);\n tripRepository.save(trip);\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\ube44\ub3d9\uae30-\ucc98\ub9ac\uc2dc-\ubb38\uc81c\uc810",children:"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810"}),"\n",(0,r.jsxs)(n.p,{children:["\ud604\uc7ac \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uace0 \uc800\uc7a5 \ud6c4, \uc800\uc7a5 \uacbd\ub85c\ub97c DB\uc5d0 \ubc18\uc601\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ud615\ud0dc\uac00 \ub418\uba70 \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \ubb38\uc81c\uac00 \uc0dd\uae34\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n trip[trip: \uc5ec\ud589 \uad00\ub828 \ud328\ud0a4\uc9c0] --\x3e draw[draw: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294 \ud328\ud0a4\uc9c0]\n draw --\x3e trip"}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uacfc \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n\tsubgraph draw\n\t\tdirection LR\n\t\tRG[RouteImageGenerator] -- DB \ubc18\uc601 \uc694\uccad --\x3e ILR[ImageLinkTripRepository]\n\tend\n subgraph trip\n\t\tdirection LR\n\t\tTS[TripService] -- \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e RG\n\t\tILRI[ImageLinkTripRepositoryImpl] -- \uad6c\ud604 --\x3e ILR\n\tend\n\n\ttrip --\x3e draw"}),"\n",(0,r.jsxs)(n.p,{children:["\ud328\ud0a4\uc9c0 \uac04 \uc758\uc874\uc131\uc740 \ud574\uacb0\ub418\uc5c8\uc9c0\ub9cc, \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5\uc744 \uc704\ud574 tripId\ub97c \ubc1b\uc544\uc57c\ud558\ub294 \ub4f1\uc758 \ub17c\ub9ac\uc801\uc778 \uc758\uc874\uc131\uc740 \uc544\uc9c1 \ud574\uacb0\ub418\uc9c0 \uc54a\uc558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\uc774\ubca4\ud2b8-\uc0ac\uc6a9",children:"\uc774\ubca4\ud2b8 \uc0ac\uc6a9"}),"\n",(0,r.jsx)(n.p,{children:"\uc2a4\ud504\ub9c1\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uba74 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc758 \ube44\uad00\uc2ec\uc0ac(ex. \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131)\uc744 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"\uc774\ubca4\ud2b8-\ubc1c\ud589",children:"\uc774\ubca4\ud2b8 \ubc1c\ud589"}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \uba3c\uc800 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 ApplicationEventPublisher \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c ApplicationContext\uac00 \uad6c\ud604\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",metastring:'title="TripService & TripUpdateEvent"',children:"public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {\n ...\n\n // \uc774\ubca4\ud2b8 \ubc1c\ud589\n applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));\n}\n\npublic record TripUpdateEvent(Long tripId) {\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \ub54c \ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc774 \uc911\uc694\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\ub294 \ub3c4\uba54\uc778\uc758 \ud589\uc704\ub97c \ub2f4\uace0 \uc788\ub294 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589(ex. RouteImageGenerateEvent)\ud55c\ub2e4\uba74 \ub17c\ub9ac\uc801\uc778 \uc758\uc874 \uad00\uacc4\uac00 \ub0a8\uc544\uc788\uae30\uc5d0 \uc774\ubca4\ud2b8\ub97c \uc801\uc808\ud788 \uc0ac\uc6a9\ud588\ub2e4\uace0 \ubcf4\uae30 \uc5b4\ub835\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc740 \uc8fc\uae30\ub2a5\uc774 \uc5b4\ub5a4 \ud589\uc704(ex. TripUpdateEvent)\ub97c \ud588\ub294\uc9c0\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \ub2f4\uaca8\uc788\ub294 \uc774\ubca4\ud2b8\uba85\uc73c\ub85c \ubc1c\ud589\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc774\ubca4\ud2b8-\uad6c\ub3c5",children:"\uc774\ubca4\ud2b8 \uad6c\ub3c5"}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc2e4\ud589\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\uae30 \uc704\ud558\uc5ec ",(0,r.jsx)(n.code,{children:"@Async"})," \uc560\ub108\ud14c\uc774\uc158\uc744 \uc801\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ubca4\ud2b8\uc758 \uad6c\ub3c5\uc740 \uc5ec\ud589\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \uc885\ub8cc\ub420 \ub54c \uc5ec\ud589\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \uac00\uc9c0\uace0 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud574 ",(0,r.jsx)(n.code,{children:"@TransactionalEventListener"}),"\ub97c \uc0ac\uc6a9\ud588\ub2e4."]}),"\n",(0,r.jsxs)(n.admonition,{title:"TransactionPhase \uc124\uc815",type:"note",children:[(0,r.jsx)(n.p,{children:"TransactionPhase\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \uc774\ubca4\ud2b8\ub97c \uc5b4\ub5a4 \ub2e8\uacc4\uc5d0\uc11c \uc218\uc2e0\ud558\uace0 \ucc98\ub9ac\ud560\uc9c0\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."}),(0,r.jsxs)(n.p,{children:["AFTER_COMMIT(\uae30\ubcf8\uac12): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ucee4\ubc0b \ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,r.jsx)(n.br,{}),"\n","AFTER_ROLLBACK: \ud2b8\ub79c\uc7ad\uc158\uc774 \ub864\ubc31\ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,r.jsx)(n.br,{}),"\n","AFTER_COMPLETION: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub610\ub294 \ub864\ubc31 \ub418\uc5c8\uc744 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,r.jsx)(n.br,{}),"\n","BEFORE_COMMIT: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub418\uae30 \uc804 \uc774\ubca4\ud2b8 \uc2e4\ud589"]})]}),"\n",(0,r.jsx)(n.p,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uae30 \uc704\ud574 @Transactional \uc560\ub108\ud14c\uc774\uc158\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",metastring:'title="TripUpdateEventHandler"',children:"@Component\npublic class TripUpdateEventHandler {\n\n private final RouteImageGenerator routeImageGenerator;\n private final TripRepository tripRepository;\n\n public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {\n this.routeImageGenerator = routeImageGenerator;\n this.tripRepository = tripRepository;\n }\n\n @Async\n @TransactionalEventListener(phase = AFTER_COMMIT)\n public void handle(TripUpdateEvent tripUpdateEvent) {\n Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());\n\n String imageUrl = routeImageGenerator.generate(\n trip.getLatitudes(),\n trip.getLongitudes(),\n trip.getPointedLatitudes(),\n trip.getPointedLongitudes()\n );\n\n trip.changeRouteImageUrl(imageUrl);\n tripRepository.save(trip);\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c\uc368 \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ubb38\uc81c\uac00 \ub2e4\uc74c\uacfc \uac19\uc774 \ud574\uacb0\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub610\ud55c \uc8fc\uae30\ub2a5\uacfc \ubd80\uae30\ub2a5\uc744 \ubd84\ub9ac\ud568\uc73c\ub85c\uc368 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc5d0 \ub300\ud55c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uc5c8\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n subgraph trip\n TripServcie -- \ubc1c\ud589 --\x3e TripUpdateEvent\n TripRepository\n end\n\n subgraph draw\n TripUpdateEventHandler -- \uad6c\ub3c5 \ud6c4 \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e TripUpdateEvent\n TripUpdateEventHandler -- \uc0dd\uc131\ub41c \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5 --\x3e TripRepository\n end"}),"\n",(0,r.jsx)(n.h3,{id:"\ud14c\uc2a4\ud2b8",children:"\ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsx)(n.p,{children:"\ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud14c\uc2a4\ud2b8\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \ubc29\ubc95\uc774 \uc788\ub2e4."}),"\n","\n","\n",(0,r.jsxs)(i.Z,{children:[(0,r.jsx)(s.Z,{value:"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d",label:"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@SpringBootTest\npublic class TripUpdateEventHandlerIntegrationTest {\n\n ...\n\n @Test\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\n // given\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\n .willReturn(\uc5ec\ud589());\n\n // when\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\n\n // then\n then(routeImageGenerator)\n .should(Mockito.timeout(5000).times(1))\n .generate(any(), any(), any(), any());\n }\n}\n"})})}),(0,r.jsx)(s.Z,{value:"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d",label:"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@ContextConfiguration(classes = TestSyncConfig.class)\n@SpringBootTest\npublic class TripUpdateEventHandlerIntegrationTest {\n\n ...\n\n @Test\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\n // given\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\n .willReturn(\uc5ec\ud589());\n\n // when\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\n\n // then\n then(routeImageGenerator)\n .should(times(1))\n .generate(any(), any(), any(), any());\n }\n}\n"})})})]}),"\n",(0,r.jsxs)(n.p,{children:["\ucc98\uc74c\uc5d0\ub294 \ud14c\uc2a4\ud2b8\uc5d0\uc11c\ub9cc \ub3d9\uae30\ub85c \uc124\uc815 \ud6c4 \uac80\uc99d\ud558\ub824\uace0 \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud1b5\ud569 \ud14c\uc2a4\ud2b8\uc5d0\uc120 ",(0,r.jsx)(n.code,{children:"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1 \uc885\ub8cc\ub418\uc5c8\uc744 \ub54c \ube44\ub3d9\uae30\ub85c \uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0"})," \uac80\uc99d\uc774 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 \ucd5c\uc885\uc801\uc73c\ub85c ",(0,r.jsx)(n.code,{children:"Mockito.timeout"})," \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \ud1b5\uacfc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\uacb0\uacfc",children:"\uacb0\uacfc"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"./time.png",src:t(89297).Z+"",width:"1682",height:"678"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc704 \uc751\ub2f5 \uc2dc\uac04\uc740 \uc704\uce58 \uc815\ubcf4 1000\uac1c\ub97c \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ud55c \uac12\uc774\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc751\ub2f5 \uc2dc\uac04\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ud3ec\ud568\ub418\uc9c0 \uc54a\uc544\uc11c \uc131\ub2a5\uc774 \uac1c\uc120\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.task-execution-and-scheduling",children:"7.7. Task Execution and Scheduling, Spring Boot Docs"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.baeldung.com/spring-events",children:"Spring Events, Baeldung"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://techblog.woowahan.com/7835/",children:"\ud68c\uc6d0\uc2dc\uc2a4\ud15c \uc774\ubca4\ud2b8\uae30\ubc18 \uc544\ud0a4\ud14d\ucc98 \uad6c\ucd95\ud558\uae30"})]})]})}function h(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>c});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?i(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),p=c(t),h=a,g=p["".concat(l,".").concat(h)]||p[h]||u[h]||i;return t?r.createElement(g,s(s({ref:n},d),{},{components:t})):r.createElement(g,s({ref:n},d))}));d.displayName="MDXCreateElement"},85162:(e,n,t)=>{t.d(n,{Z:()=>s});t(67294);var r=t(86010);const a={tabItem:"tabItem_Ymn6"};var i=t(85893);function s(e){let{children:n,hidden:t,className:s}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,r.Z)(a.tabItem,s),hidden:t,children:n})}},74866:(e,n,t)=>{t.d(n,{Z:()=>T});var r=t(67294),a=t(86010),i=t(12466),s=t(16550),o=t(20469),l=t(91980),c=t(67392),u=t(50012);function d(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:a}}=e;return{value:n,label:t,attributes:r,default:a}}))}(t);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function h(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function g(e){let{queryString:n=!1,groupId:t}=e;const a=(0,s.k6)(),i=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function m(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=p(e),[s,l]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!h({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:i}))),[c,d]=g({queryString:t,groupId:a}),[m,b]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,u.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),v=(()=>{const e=c??m;return h({value:e,tabValues:i})?e:null})();(0,o.Z)((()=>{v&&l(v)}),[v]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!h({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),b(e)}),[d,b,i]),tabValues:i}}var b=t(72389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=t(85893);function j(e){let{className:n,block:t,selectedValue:r,selectValue:s,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.o5)(),u=e=>{const n=e.currentTarget,t=l.indexOf(n),a=o[t].value;a!==r&&(c(n),s(a))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.Z)("tabs",{"tabs--block":t},n),children:o.map((e=>{let{value:n,label:t,attributes:i}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>l.push(e),onKeyDown:d,onClick:u,...i,className:(0,a.Z)("tabs__item",v.tabItem,i?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function f(e){let{lazy:n,children:t,selectedValue:a}=e;const i=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a})))})}function y(e){const n=m(e);return(0,x.jsxs)("div",{className:(0,a.Z)("tabs-container",v.tabList),children:[(0,x.jsx)(j,{...e,...n}),(0,x.jsx)(f,{...e,...n})]})}function T(e){const n=(0,b.Z)();return(0,x.jsx)(y,{...e,children:d(e.children)},String(n))}},89297:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/time-8bef9a6cf2dcace85f12ae5624da94f5.png"}}]); \ No newline at end of file diff --git a/assets/js/4d43abad.3e067cc0.js b/assets/js/4d43abad.3e067cc0.js new file mode 100644 index 000000000..1f82893a2 --- /dev/null +++ b/assets/js/4d43abad.3e067cc0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3365],{79766:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>o});var r=n(85893),i=n(3905);const l={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",slug:"route-image-intro",tags:["image","awt"]},a=void 0,s={permalink:"/route-image-intro",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",source:"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",description:"./route.png",date:"2023-07-27T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 27\uc77c",tags:[{label:"image",permalink:"/tags/image"},{label:"awt",permalink:"/tags/awt"}],readingTime:5.865,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",slug:"route-image-intro",tags:["image","awt"]},unlisted:!1,prevItem:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",permalink:"/mock-static-method"},nextItem:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",permalink:"/java-spring-springboot"}},c={authorsImageUrls:[]},o=[{value:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784",id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc758-\ucc45\uc784",level:3},{value:"\uace0\ub824\ud55c \uae30\uc220",id:"\uace0\ub824\ud55c-\uae30\uc220",level:3},{value:"Python & Matplotlib",id:"python--matplotlib",level:2},{value:"Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac",id:"java-awt-\uc774\uc678\uc758-\ub77c\uc774\ube0c\ub7ec\ub9ac",level:3},{value:"Java & AWT(Abstract Window Toolkit)",id:"java--awtabstract-window-toolkit",level:3},{value:"\uae30\uc220 \uc120\ud0dd",id:"\uae30\uc220-\uc120\ud0dd",level:3},{value:"\uc720\uc9c0 \ubcf4\uc218",id:"\uc720\uc9c0-\ubcf4\uc218",level:3},{value:"\ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00",id:"\ub808\ubca8-3\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70-\ub0b4\uc6a9-\ucd94\uac00",level:3}];function d(e){const t={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"./route.png",src:n(29632).Z+"",width:"1014",height:"902"})}),"\n",(0,r.jsx)(t.h3,{id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc758-\ucc45\uc784",children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784"}),"\n",(0,r.jsxs)(t.p,{children:["\uc704 \uc640\uc774\uc5b4 \ud504\ub808\uc784\uc5d0\uc11c ",(0,r.jsx)(t.code,{children:"\uc5ec\ud589 \ud788\uc2a4\ud1a0\ub9ac"}),"\uc640 ",(0,r.jsx)(t.code,{children:"\uc5ec\ud589\uc5d0 \ub300\ud55c \uac10\uc0c1\uc744 \uc704\ud55c \uacbd\ub85c \uc774\ubbf8\uc9c0"}),"\uc758 \uacbd\uc6b0 \ub124\uc774\ubc84 \uc9c0\ub3c4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\ub2f9 \uae30\ub2a5\uc744 \uad6c\ud604\ud560 \uc218 \uc5c6\uc73c\ub2c8 \ub2f9\uc5f0\ud788 \ub9f5 API\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub3c4\ud615 \uadf8\ub9ac\uae30 API(\ub124\uc774\ubc84 \ub9f5 API \uae30\uc900 Polyline)\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub530\ub77c\uc11c \uc774\ubbf8\uc9c0\ub97c \uc9c1\uc811 \uc0dd\uc131\ud558\uac70\ub098, \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uc11c \uc9c1\uc811 \uc704\uacbd\ub3c4\ub97c \uc774\uc6a9\ud558\uc5ec \uadf8\ub824\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:"\ud574\ub2f9 \uc694\uad6c\uc0ac\ud56d\uc744 \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uae30\ub2a5\uc744 \uac00\uc9c4 \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 \ud544\uc694\ud558\ub2e4."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131"}),"\n",(0,r.jsx)(t.li,{children:"\uc120\uacfc \uc810 \ud45c\ud604"}),"\n",(0,r.jsx)(t.li,{children:"\ud22c\uba85\ud55c \ubc30\uacbd\uc0c9"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"\ud604\uc7ac \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \ubc14\uc05c \uc77c\uc815\uacfc \uae30\ub2a5 \uad6c\ud604\uc5d0 \uc788\uc5b4 \uc57d\uac04\uc758 \uc5f0\uc0b0\uc774 \ub4e4\uc5b4\uac04\ub2e4\ub294 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uc5ec \ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30\ub85c \uacb0\uc815\uc744 \ub0b4\ub838\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"\uace0\ub824\ud55c-\uae30\uc220",children:"\uace0\ub824\ud55c \uae30\uc220"}),"\n",(0,r.jsx)(t.p,{children:"\ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uae30 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub610\ub294 \uae30\uc220\ub4e4\uc744 \ud655\uc778\ud574 \ubcf4\uc558\ub2e4."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Python\uc758 Matplotlib"}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.strong,{children:"AWT(Abstract Window Toolkit) [\ucd5c\uc885 \uc120\ud0dd]"})}),"\n",(0,r.jsx)(t.li,{children:"\uc774\ubbf8\uc9c0 \ucc98\ub9ac \ub77c\uc774\ube0c\ub7ec\ub9ac \ubc0f Java\uc5d0\uc11c \ub0b4\ubd80\uc801\uc73c\ub85c Matplotlib \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac (\uc6d0\ud558\ub294 \uae30\ub2a5 \uc5c6\uc74c)"}),"\n",(0,r.jsx)(t.li,{children:"Java Swing, Java FX (\ub2e8\uc21c\ud55c \uc120 \uadf8\ub9ac\uae30 + \uc810 \ucc0d\uae30\ub77c \ubd88\ud544\uc694)"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"python--matplotlib",children:"Python & Matplotlib"}),"\n",(0,r.jsxs)(t.p,{children:["\ub370\uc774\ud130 \uc2dc\uac01\ud654 \ub77c\uc774\ube0c\ub7ec\ub9ac",(0,r.jsx)(t.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 0.2\ucd08"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\ucf54\ub4dc\uac00 \uac04\ub2e8\ud574\uc11c \uc720\uc9c0 \ubcf4\uc218\uc131\uc774 \uc88b\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"AWS Lambda \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ucef4\ud4e8\ud305 \uc11c\ube44\uc2a4\ub098 FastAPI\uc640 \uac19\uc740 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\ub85c \ucd94\uac00\uc801\uc778 API\ub97c \uad6c\ud604\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"Spring Boot\uc5d0\uc11c \ucd94\uac00\uc801\uc778 API \ud638\ucd9c\uc744 \ud574\uc57c\ud558\uace0, \ud655\uc7a5\uc131\uacfc \ube44\ub3d9\uae30 \ucc98\ub9ac \ub4f1 \uace0\ub824 \ud574\uc57c \ud560 \ubd80\ubd84\uc774 \ub9ce\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"java-awt-\uc774\uc678\uc758-\ub77c\uc774\ube0c\ub7ec\ub9ac",children:"Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac"}),"\n",(0,r.jsx)(t.p,{children:"Python\uc774 \uc544\ub2cc Java\uc5d0\uc11c\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub3c4 \uace0\ub824\ub97c \ud574\ubd24\uc9c0\ub9cc \uc694\uad6c\uc0ac\ud56d\uc5d0 \uc801\ud569\ud558\uc9c0 \uc54a\uac70\ub098, \uc801\uc740 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac70\uc6b4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc774 \ub9ce\uc544\uc11c \uc81c\uc678\ud588\ub2e4."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"\ub77c\uc774\ube0c\ub7ec\ub9ac"}),(0,r.jsx)(t.th,{children:"\uc124\uba85"}),(0,r.jsx)(t.th,{children:"\uc81c\uc678 \uc774\uc720"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Swing"}),(0,r.jsx)(t.td,{children:"AWT \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, \ub124\uc774\ud2f0\ube0c UI\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 \ubaa8\ub4e0 \uc6b4\uc601\uccb4\uc81c \uc0c1\uc5d0\uc11c \ub3d9\uc77c\ud55c UI\ub97c \uac00\uc9c0\ub3c4\ub85d \ud568"}),(0,r.jsx)(t.td,{children:"\uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"JavaFX"}),(0,r.jsx)(t.td,{children:"Swing \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, 3\ucc28\uc6d0 \uadf8\ub798\ud53d\uc744 \uc9c0\uc6d0\ud568"}),(0,r.jsx)(t.td,{children:"\uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://github.com/yuriy-g/simple-java-plot",children:"simple-java-plot"})}),(0,r.jsx)(t.td,{children:"AWT\ub85c \uad6c\ud604\ub41c \ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac"}),(0,r.jsx)(t.td,{children:"AWT \uae30\ubc18\uc774\uae34 \ud558\uc9c0\ub9cc \uc9c1\uc811 AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc5d0 \ube44\ud574 \uba54\ub9ac\ud2b8\uac00 \uc5c6\uc74c, \ucee4\uc2a4\ud140 \uc124\uc815 \uae30\ub2a5\uc774 \uc5c6\uc74c"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://github.com/sh0nk/matplotlib4j",children:"matplotlib4j"})}),(0,r.jsx)(t.td,{children:"Matplotlib\ub97c Java\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uac8c \ud558\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac"}),(0,r.jsx)(t.td,{children:"\ub0b4\ubd80\uc801\uc73c\ub85c \ud30c\uc774\uc36c \uc0ac\uc6a9\ud558\uae30\uc5d0 \ubb34\uac70\uc6c0, \ubc30\uacbd \ud22c\uba85\ud654 \uae30\ub2a5 \uc5c6\uc74c"})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"java--awtabstract-window-toolkit",children:"Java & AWT(Abstract Window Toolkit)"}),"\n",(0,r.jsxs)(t.p,{children:["\uadf8\ub798\ud53d\uacfc \uc774\ubbf8\uc9c0\ub97c \uadf8\ub9ac\uae30 \uc704\ud55c \ub3c4\uad6c",(0,r.jsx)(t.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 1.75\ucd08"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ubcf4\ub2e4 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc874\uc7ac\ud55c\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub2e4\uc18c \uc18c\uc694\ub418\uae30 \ub54c\ubb38\uc5d0 \ube60\ub978 \uc751\ub2f5 \ubc18\ud658\uc744 \uc704\ud574 \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \uace0\ub824\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"\ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"\uae30\uc220-\uc120\ud0dd",children:"\uae30\uc220 \uc120\ud0dd"}),"\n",(0,r.jsxs)(t.p,{children:["AWT\uc758 \uacbd\uc6b0 Matplotlib\uc5d0 \ube44\ud574 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc788\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub354 \ub9ce\uc774 \uac78\ub9ac\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud558\uc9c0\ub9cc \ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub418\ub294 \ubd80\ubd84, Python\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc778 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uace0\ub824\ud558\uc5ec AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uc720\uc9c0-\ubcf4\uc218",children:"\uc720\uc9c0 \ubcf4\uc218"}),"\n",(0,r.jsxs)(t.p,{children:["AWT\ub77c\ub294 \uc0dd\uc18c\ud55c \uae30\uc220\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc720\uc9c0 \ubcf4\uc218\uc131\uc744 \uc704\ud574 \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub530\ub77c\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ubc29\ubc95\uc73c\ub85c \uacf5\uc720\ud558\uae30\ub85c \ud588\ub2e4."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"\ucf54\ub4dc \ub9ac\ubdf0\uc640 PR\uc744 \ud1b5\ud574 \uc791\uc131\ud55c AWT \ucf54\ub4dc\uc5d0 \ub300\ud55c \uc124\uba85 \ubc0f \ub9ac\ubdf0 \ubc1b\ub294\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"AWT\ub97c \uc0ac\uc6a9\ud55c \ubd80\ubd84\uc744 \ubb38\uc11c\ud654\ud558\uc5ec \uacf5\uc720\ud55c\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"\ub808\ubca8-3\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70-\ub0b4\uc6a9-\ucd94\uac00",children:"\ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00"}),"\n",(0,r.jsxs)(t.p,{children:["\uae30\uc220 \uc120\ud0dd\uc744 \ud558\uae30 \uc704\ud55c \uc2e4\ud589 \uc2dc\uac04 \uce21\uc815\uc5d0 \uc624\ub958\uac00 \uc788\uc5c8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc2e4\ud589 \uc2dc\uac04\uc744 \uc81c\uc678\ud558\uba74 \ud30c\uc774\uc36c\uacfc \ube44\uc2b7\ud55c \uc2dc\uac04\uc548\uc5d0 \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud560 \uc218 \uc788\uc5c8\ub2e4."]})]})}function h(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>o});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),o=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,l=e.originalType,c=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),j=o(n),p=i,x=j["".concat(c,".").concat(p)]||j[p]||d[p]||l;return n?r.createElement(x,a(a({ref:t},h),{},{components:n})):r.createElement(x,a({ref:t},h))}));h.displayName="MDXCreateElement"},29632:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png"}}]); \ No newline at end of file diff --git a/assets/js/4d43abad.89ba9d9c.js b/assets/js/4d43abad.89ba9d9c.js deleted file mode 100644 index 8f7401287..000000000 --- a/assets/js/4d43abad.89ba9d9c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3365],{3905:(t,e,a)=>{a.d(e,{Zo:()=>m,kt:()=>d});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?l(Object(a),!0).forEach((function(e){r(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function p(t,e){if(null==t)return{};var a,n,r=function(t,e){if(null==t)return{};var a,n,r={},l=Object.keys(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var o=n.createContext({}),u=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},m=function(t){var e=u(t.components);return n.createElement(o.Provider,{value:e},t.children)},k={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},c=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,o=t.parentName,m=p(t,["components","mdxType","originalType","parentName"]),c=u(a),d=r,s=c["".concat(o,".").concat(d)]||c[d]||k[d]||l;return a?n.createElement(s,i(i({ref:e},m),{},{components:a})):n.createElement(s,i({ref:e},m))}));function d(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=c;var p={};for(var o in e)hasOwnProperty.call(e,o)&&(p[o]=e[o]);p.originalType=t,p.mdxType="string"==typeof t?t:r,i[1]=p;for(var u=2;u<l;u++)i[u]=a[u];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}c.displayName="MDXCreateElement"},4859:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>o,contentTitle:()=>i,default:()=>k,frontMatter:()=>l,metadata:()=>p,toc:()=>u});var n=a(87462),r=(a(67294),a(3905));const l={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",slug:"route-image-intro",tags:["image","awt"]},i=void 0,p={permalink:"/route-image-intro",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",source:"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",description:"./route.png",date:"2023-07-27T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 27\uc77c",tags:[{label:"image",permalink:"/tags/image"},{label:"awt",permalink:"/tags/awt"}],readingTime:5.865,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",slug:"route-image-intro",tags:["image","awt"]},prevItem:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",permalink:"/mock-static-method"},nextItem:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",permalink:"/java-spring-springboot"}},o={authorsImageUrls:[]},u=[{value:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784",id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc758-\ucc45\uc784",level:3},{value:"\uace0\ub824\ud55c \uae30\uc220",id:"\uace0\ub824\ud55c-\uae30\uc220",level:3},{value:"Python & Matplotlib",id:"python--matplotlib",level:2},{value:"Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac",id:"java-awt-\uc774\uc678\uc758-\ub77c\uc774\ube0c\ub7ec\ub9ac",level:3},{value:"Java & AWT(Abstract Window Toolkit)",id:"java--awtabstract-window-toolkit",level:3},{value:"\uae30\uc220 \uc120\ud0dd",id:"\uae30\uc220-\uc120\ud0dd",level:3},{value:"\uc720\uc9c0 \ubcf4\uc218",id:"\uc720\uc9c0-\ubcf4\uc218",level:3},{value:"\ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00",id:"\ub808\ubca8-3\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70-\ub0b4\uc6a9-\ucd94\uac00",level:3}],m={toc:u};function k(t){let{components:e,...l}=t;return(0,r.kt)("wrapper",(0,n.Z)({},m,l,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./route.png",src:a(29632).Z,width:"1014",height:"902"})),(0,r.kt)("h3",{id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc758-\ucc45\uc784"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784"),(0,r.kt)("p",null,"\uc704 \uc640\uc774\uc5b4 \ud504\ub808\uc784\uc5d0\uc11c ",(0,r.kt)("inlineCode",{parentName:"p"},"\uc5ec\ud589 \ud788\uc2a4\ud1a0\ub9ac"),"\uc640 ",(0,r.kt)("inlineCode",{parentName:"p"},"\uc5ec\ud589\uc5d0 \ub300\ud55c \uac10\uc0c1\uc744 \uc704\ud55c \uacbd\ub85c \uc774\ubbf8\uc9c0"),"\uc758 \uacbd\uc6b0 \ub124\uc774\ubc84 \uc9c0\ub3c4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\ub2f9 \uae30\ub2a5\uc744 \uad6c\ud604\ud560 \uc218 \uc5c6\uc73c\ub2c8 \ub2f9\uc5f0\ud788 \ub9f5 API\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub3c4\ud615 \uadf8\ub9ac\uae30 API(\ub124\uc774\ubc84 \ub9f5 API \uae30\uc900 Polyline)\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc774\ubbf8\uc9c0\ub97c \uc9c1\uc811 \uc0dd\uc131\ud558\uac70\ub098, \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uc11c \uc9c1\uc811 \uc704\uacbd\ub3c4\ub97c \uc774\uc6a9\ud558\uc5ec \uadf8\ub824\uc57c \ud55c\ub2e4."),(0,r.kt)("p",null,"\ud574\ub2f9 \uc694\uad6c\uc0ac\ud56d\uc744 \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uae30\ub2a5\uc744 \uac00\uc9c4 \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 \ud544\uc694\ud558\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131"),(0,r.kt)("li",{parentName:"ul"},"\uc120\uacfc \uc810 \ud45c\ud604"),(0,r.kt)("li",{parentName:"ul"},"\ud22c\uba85\ud55c \ubc30\uacbd\uc0c9")),(0,r.kt)("p",null,"\ud604\uc7ac \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \ubc14\uc05c \uc77c\uc815\uacfc \uae30\ub2a5 \uad6c\ud604\uc5d0 \uc788\uc5b4 \uc57d\uac04\uc758 \uc5f0\uc0b0\uc774 \ub4e4\uc5b4\uac04\ub2e4\ub294 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uc5ec \ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30\ub85c \uacb0\uc815\uc744 \ub0b4\ub838\ub2e4."),(0,r.kt)("h3",{id:"\uace0\ub824\ud55c-\uae30\uc220"},"\uace0\ub824\ud55c \uae30\uc220"),(0,r.kt)("p",null,"\ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uae30 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub610\ub294 \uae30\uc220\ub4e4\uc744 \ud655\uc778\ud574 \ubcf4\uc558\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Python\uc758 Matplotlib"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"AWT(Abstract Window Toolkit) ","[\ucd5c\uc885 \uc120\ud0dd]")),(0,r.kt)("li",{parentName:"ul"},"\uc774\ubbf8\uc9c0 \ucc98\ub9ac \ub77c\uc774\ube0c\ub7ec\ub9ac \ubc0f Java\uc5d0\uc11c \ub0b4\ubd80\uc801\uc73c\ub85c Matplotlib \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac (\uc6d0\ud558\ub294 \uae30\ub2a5 \uc5c6\uc74c)"),(0,r.kt)("li",{parentName:"ul"},"Java Swing, Java FX (\ub2e8\uc21c\ud55c \uc120 \uadf8\ub9ac\uae30 + \uc810 \ucc0d\uae30\ub77c \ubd88\ud544\uc694)")),(0,r.kt)("h2",{id:"python--matplotlib"},"Python & Matplotlib"),(0,r.kt)("p",null,"\ub370\uc774\ud130 \uc2dc\uac01\ud654 \ub77c\uc774\ube0c\ub7ec\ub9ac",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 0.2\ucd08 "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ucf54\ub4dc\uac00 \uac04\ub2e8\ud574\uc11c \uc720\uc9c0 \ubcf4\uc218\uc131\uc774 \uc88b\ub2e4. "),(0,r.kt)("li",{parentName:"ul"},"AWS Lambda \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ucef4\ud4e8\ud305 \uc11c\ube44\uc2a4\ub098 FastAPI\uc640 \uac19\uc740 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\ub85c \ucd94\uac00\uc801\uc778 API\ub97c \uad6c\ud604\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"Spring Boot\uc5d0\uc11c \ucd94\uac00\uc801\uc778 API \ud638\ucd9c\uc744 \ud574\uc57c\ud558\uace0, \ud655\uc7a5\uc131\uacfc \ube44\ub3d9\uae30 \ucc98\ub9ac \ub4f1 \uace0\ub824 \ud574\uc57c \ud560 \ubd80\ubd84\uc774 \ub9ce\ub2e4.")),(0,r.kt)("h3",{id:"java-awt-\uc774\uc678\uc758-\ub77c\uc774\ube0c\ub7ec\ub9ac"},"Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac"),(0,r.kt)("p",null,"Python\uc774 \uc544\ub2cc Java\uc5d0\uc11c\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub3c4 \uace0\ub824\ub97c \ud574\ubd24\uc9c0\ub9cc \uc694\uad6c\uc0ac\ud56d\uc5d0 \uc801\ud569\ud558\uc9c0 \uc54a\uac70\ub098, \uc801\uc740 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac70\uc6b4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc774 \ub9ce\uc544\uc11c \uc81c\uc678\ud588\ub2e4."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\ub77c\uc774\ube0c\ub7ec\ub9ac"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc81c\uc678 \uc774\uc720"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Swing"),(0,r.kt)("td",{parentName:"tr",align:null},"AWT \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, \ub124\uc774\ud2f0\ube0c UI\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 \ubaa8\ub4e0 \uc6b4\uc601\uccb4\uc81c \uc0c1\uc5d0\uc11c \ub3d9\uc77c\ud55c UI\ub97c \uac00\uc9c0\ub3c4\ub85d \ud568"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"JavaFX"),(0,r.kt)("td",{parentName:"tr",align:null},"Swing \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, 3\ucc28\uc6d0 \uadf8\ub798\ud53d\uc744 \uc9c0\uc6d0\ud568"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://github.com/yuriy-g/simple-java-plot"},"simple-java-plot")),(0,r.kt)("td",{parentName:"tr",align:null},"AWT\ub85c \uad6c\ud604\ub41c \ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac"),(0,r.kt)("td",{parentName:"tr",align:null},"AWT \uae30\ubc18\uc774\uae34 \ud558\uc9c0\ub9cc \uc9c1\uc811 AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc5d0 \ube44\ud574 \uba54\ub9ac\ud2b8\uac00 \uc5c6\uc74c, \ucee4\uc2a4\ud140 \uc124\uc815 \uae30\ub2a5\uc774 \uc5c6\uc74c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://github.com/sh0nk/matplotlib4j"},"matplotlib4j")),(0,r.kt)("td",{parentName:"tr",align:null},"Matplotlib\ub97c Java\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uac8c \ud558\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac"),(0,r.kt)("td",{parentName:"tr",align:null},"\ub0b4\ubd80\uc801\uc73c\ub85c \ud30c\uc774\uc36c \uc0ac\uc6a9\ud558\uae30\uc5d0 \ubb34\uac70\uc6c0, \ubc30\uacbd \ud22c\uba85\ud654 \uae30\ub2a5 \uc5c6\uc74c")))),(0,r.kt)("h3",{id:"java--awtabstract-window-toolkit"},"Java & AWT(Abstract Window Toolkit)"),(0,r.kt)("p",null,"\uadf8\ub798\ud53d\uacfc \uc774\ubbf8\uc9c0\ub97c \uadf8\ub9ac\uae30 \uc704\ud55c \ub3c4\uad6c",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 1.75\ucd08 "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ubcf4\ub2e4 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub2e4\uc18c \uc18c\uc694\ub418\uae30 \ub54c\ubb38\uc5d0 \ube60\ub978 \uc751\ub2f5 \ubc18\ud658\uc744 \uc704\ud574 \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \uace0\ub824\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4.")),(0,r.kt)("h3",{id:"\uae30\uc220-\uc120\ud0dd"},"\uae30\uc220 \uc120\ud0dd"),(0,r.kt)("p",null,"AWT\uc758 \uacbd\uc6b0 Matplotlib\uc5d0 \ube44\ud574 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc788\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub354 \ub9ce\uc774 \uac78\ub9ac\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub418\ub294 \ubd80\ubd84, Python\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc778 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uace0\ub824\ud558\uc5ec AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4."),(0,r.kt)("h3",{id:"\uc720\uc9c0-\ubcf4\uc218"},"\uc720\uc9c0 \ubcf4\uc218"),(0,r.kt)("p",null,"AWT\ub77c\ub294 \uc0dd\uc18c\ud55c \uae30\uc220\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc720\uc9c0 \ubcf4\uc218\uc131\uc744 \uc704\ud574 \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ubc29\ubc95\uc73c\ub85c \uacf5\uc720\ud558\uae30\ub85c \ud588\ub2e4. "),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"\ucf54\ub4dc \ub9ac\ubdf0\uc640 PR\uc744 \ud1b5\ud574 \uc791\uc131\ud55c AWT \ucf54\ub4dc\uc5d0 \ub300\ud55c \uc124\uba85 \ubc0f \ub9ac\ubdf0 \ubc1b\ub294\ub2e4. "),(0,r.kt)("li",{parentName:"ol"},"AWT\ub97c \uc0ac\uc6a9\ud55c \ubd80\ubd84\uc744 \ubb38\uc11c\ud654\ud558\uc5ec \uacf5\uc720\ud55c\ub2e4.")),(0,r.kt)("h3",{id:"\ub808\ubca8-3\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70-\ub0b4\uc6a9-\ucd94\uac00"},"\ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00"),(0,r.kt)("p",null,"\uae30\uc220 \uc120\ud0dd\uc744 \ud558\uae30 \uc704\ud55c \uc2e4\ud589 \uc2dc\uac04 \uce21\uc815\uc5d0 \uc624\ub958\uac00 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc2e4\ud589 \uc2dc\uac04\uc744 \uc81c\uc678\ud558\uba74 \ud30c\uc774\uc36c\uacfc \ube44\uc2b7\ud55c \uc2dc\uac04\uc548\uc5d0 \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud560 \uc218 \uc788\uc5c8\ub2e4."))}k.isMDXComponent=!0},29632:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png"}}]); \ No newline at end of file diff --git a/assets/js/506.17e673b8.js b/assets/js/506.17e673b8.js new file mode 100644 index 000000000..7d199d3b1 --- /dev/null +++ b/assets/js/506.17e673b8.js @@ -0,0 +1,1320 @@ +"use strict"; +exports.id = 506; +exports.ids = [506]; +exports.modules = { + +/***/ 33506: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(93799); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 8, 10, 11, 12, 14, 16, 17, 18], $V1 = [1, 9], $V2 = [1, 10], $V3 = [1, 11], $V4 = [1, 12], $V5 = [1, 13], $V6 = [1, 14]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "journey": 4, "document": 5, "EOF": 6, "line": 7, "SPACE": 8, "statement": 9, "NEWLINE": 10, "title": 11, "acc_title": 12, "acc_title_value": 13, "acc_descr": 14, "acc_descr_value": 15, "acc_descr_multiline_value": 16, "section": 17, "taskName": 18, "taskData": 19, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "journey", 6: "EOF", 8: "SPACE", 10: "NEWLINE", 11: "title", 12: "acc_title", 13: "acc_title_value", 14: "acc_descr", 15: "acc_descr_value", 16: "acc_descr_multiline_value", 17: "section", 18: "taskName", 19: "taskData" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 2]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 1: + return $$[$0 - 1]; + case 2: + this.$ = []; + break; + case 3: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 4: + case 5: + this.$ = $$[$0]; + break; + case 6: + case 7: + this.$ = []; + break; + case 8: + yy.setDiagramTitle($$[$0].substr(6)); + this.$ = $$[$0].substr(6); + break; + case 9: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 10: + case 11: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 12: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 13: + yy.addTask($$[$0 - 1], $$[$0]); + this.$ = "task"; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: $V6 }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 15, 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: $V6 }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 8]), { 13: [1, 16] }, { 15: [1, 17] }, o($V0, [2, 11]), o($V0, [2, 12]), { 19: [1, 18] }, o($V0, [2, 4]), o($V0, [2, 9]), o($V0, [2, 10]), o($V0, [2, 13])], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + return 10; + case 3: + break; + case 4: + break; + case 5: + return 4; + case 6: + return 11; + case 7: + this.begin("acc_title"); + return 12; + case 8: + this.popState(); + return "acc_title_value"; + case 9: + this.begin("acc_descr"); + return 14; + case 10: + this.popState(); + return "acc_descr_value"; + case 11: + this.begin("acc_descr_multiline"); + break; + case 12: + this.popState(); + break; + case 13: + return "acc_descr_multiline_value"; + case 14: + return 17; + case 15: + return 18; + case 16: + return 19; + case 17: + return ":"; + case 18: + return 6; + case 19: + return "INVALID"; + } + }, + rules: [/^(?:%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:#[^\n]*)/i, /^(?:journey\b)/i, /^(?:title\s[^#\n;]+)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:section\s[^#:\n;]+)/i, /^(?:[^#:\n;]+)/i, /^(?::[^#\n;]+)/i, /^(?::)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "acc_descr_multiline": { "rules": [12, 13], "inclusive": false }, "acc_descr": { "rules": [10], "inclusive": false }, "acc_title": { "rules": [8], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18, 19], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let currentSection = ""; +const sections = []; +const tasks = []; +const rawTasks = []; +const clear = function() { + sections.length = 0; + tasks.length = 0; + currentSection = ""; + rawTasks.length = 0; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.t)(); +}; +const addSection = function(txt) { + currentSection = txt; + sections.push(txt); +}; +const getSections = function() { + return sections; +}; +const getTasks = function() { + let allItemsProcessed = compileTasks(); + const maxDepth = 100; + let iterationCount = 0; + while (!allItemsProcessed && iterationCount < maxDepth) { + allItemsProcessed = compileTasks(); + iterationCount++; + } + tasks.push(...rawTasks); + return tasks; +}; +const updateActors = function() { + const tempActors = []; + tasks.forEach((task) => { + if (task.people) { + tempActors.push(...task.people); + } + }); + const unique = new Set(tempActors); + return [...unique].sort(); +}; +const addTask = function(descr, taskData) { + const pieces = taskData.substr(1).split(":"); + let score = 0; + let peeps = []; + if (pieces.length === 1) { + score = Number(pieces[0]); + peeps = []; + } else { + score = Number(pieces[0]); + peeps = pieces[1].split(","); + } + const peopleList = peeps.map((s) => s.trim()); + const rawTask = { + section: currentSection, + type: currentSection, + people: peopleList, + task: descr, + score + }; + rawTasks.push(rawTask); +}; +const addTaskOrg = function(descr) { + const newTask = { + section: currentSection, + type: currentSection, + description: descr, + task: descr, + classes: [] + }; + tasks.push(newTask); +}; +const compileTasks = function() { + const compileTask = function(pos) { + return rawTasks[pos].processed; + }; + let allProcessed = true; + for (const [i, rawTask] of rawTasks.entries()) { + compileTask(i); + allProcessed = allProcessed && rawTask.processed; + } + return allProcessed; +}; +const getActors = function() { + return updateActors(); +}; +const db = { + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey, + clear, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.r, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.g, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.b, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.a, + addSection, + getSections, + getTasks, + addTask, + addTaskOrg, + getActors +}; +const getStyles = (options) => `.label { + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + color: ${options.textColor}; + } + .mouth { + stroke: #666; + } + + line { + stroke: ${options.textColor} + } + + .legend { + fill: ${options.textColor}; + } + + .label text { + fill: #333; + } + .label { + color: ${options.textColor} + } + + .face { + ${options.faceColor ? `fill: ${options.faceColor}` : "fill: #FFF8DC"}; + stroke: #999; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 1.5px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.5; + } + text-align: center; + } + + .cluster rect { + } + + .cluster text { + fill: ${options.titleColor}; + } + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .task-type-0, .section-type-0 { + ${options.fillType0 ? `fill: ${options.fillType0}` : ""}; + } + .task-type-1, .section-type-1 { + ${options.fillType0 ? `fill: ${options.fillType1}` : ""}; + } + .task-type-2, .section-type-2 { + ${options.fillType0 ? `fill: ${options.fillType2}` : ""}; + } + .task-type-3, .section-type-3 { + ${options.fillType0 ? `fill: ${options.fillType3}` : ""}; + } + .task-type-4, .section-type-4 { + ${options.fillType0 ? `fill: ${options.fillType4}` : ""}; + } + .task-type-5, .section-type-5 { + ${options.fillType0 ? `fill: ${options.fillType5}` : ""}; + } + .task-type-6, .section-type-6 { + ${options.fillType0 ? `fill: ${options.fillType6}` : ""}; + } + .task-type-7, .section-type-7 { + ${options.fillType0 ? `fill: ${options.fillType7}` : ""}; + } + + .actor-0 { + ${options.actor0 ? `fill: ${options.actor0}` : ""}; + } + .actor-1 { + ${options.actor1 ? `fill: ${options.actor1}` : ""}; + } + .actor-2 { + ${options.actor2 ? `fill: ${options.actor2}` : ""}; + } + .actor-3 { + ${options.actor3 ? `fill: ${options.actor3}` : ""}; + } + .actor-4 { + ${options.actor4 ? `fill: ${options.actor4}` : ""}; + } + .actor-5 { + ${options.actor5 ? `fill: ${options.actor5}` : ""}; + } +`; +const styles = getStyles; +const drawRect = function(elem, rectData) { + return (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.d)(elem, rectData); +}; +const drawFace = function(element, faceData) { + const radius = 15; + const circleElement = element.append("circle").attr("cx", faceData.cx).attr("cy", faceData.cy).attr("class", "face").attr("r", radius).attr("stroke-width", 2).attr("overflow", "visible"); + const face = element.append("g"); + face.append("circle").attr("cx", faceData.cx - radius / 3).attr("cy", faceData.cy - radius / 3).attr("r", 1.5).attr("stroke-width", 2).attr("fill", "#666").attr("stroke", "#666"); + face.append("circle").attr("cx", faceData.cx + radius / 3).attr("cy", faceData.cy - radius / 3).attr("r", 1.5).attr("stroke-width", 2).attr("fill", "#666").attr("stroke", "#666"); + function smile(face2) { + const arc$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .Nb1)().startAngle(Math.PI / 2).endAngle(3 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2); + face2.append("path").attr("class", "mouth").attr("d", arc$1).attr("transform", "translate(" + faceData.cx + "," + (faceData.cy + 2) + ")"); + } + function sad(face2) { + const arc$1 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .arc */ .Nb1)().startAngle(3 * Math.PI / 2).endAngle(5 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2); + face2.append("path").attr("class", "mouth").attr("d", arc$1).attr("transform", "translate(" + faceData.cx + "," + (faceData.cy + 7) + ")"); + } + function ambivalent(face2) { + face2.append("line").attr("class", "mouth").attr("stroke", 2).attr("x1", faceData.cx - 5).attr("y1", faceData.cy + 7).attr("x2", faceData.cx + 5).attr("y2", faceData.cy + 7).attr("class", "mouth").attr("stroke-width", "1px").attr("stroke", "#666"); + } + if (faceData.score > 3) { + smile(face); + } else if (faceData.score < 3) { + sad(face); + } else { + ambivalent(face); + } + return circleElement; +}; +const drawCircle = function(element, circleData) { + const circleElement = element.append("circle"); + circleElement.attr("cx", circleData.cx); + circleElement.attr("cy", circleData.cy); + circleElement.attr("class", "actor-" + circleData.pos); + circleElement.attr("fill", circleData.fill); + circleElement.attr("stroke", circleData.stroke); + circleElement.attr("r", circleData.r); + if (circleElement.class !== void 0) { + circleElement.attr("class", circleElement.class); + } + if (circleData.title !== void 0) { + circleElement.append("title").text(circleData.title); + } + return circleElement; +}; +const drawText = function(elem, textData) { + return (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.f)(elem, textData); +}; +const drawLabel = function(elem, txtObject) { + function genPoints(x, y, width, height, cut) { + return x + "," + y + " " + (x + width) + "," + y + " " + (x + width) + "," + (y + height - cut) + " " + (x + width - cut * 1.2) + "," + (y + height) + " " + x + "," + (y + height); + } + const polygon = elem.append("polygon"); + polygon.attr("points", genPoints(txtObject.x, txtObject.y, 50, 20, 7)); + polygon.attr("class", "labelBox"); + txtObject.y = txtObject.y + txtObject.labelMargin; + txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin; + drawText(elem, txtObject); +}; +const drawSection = function(elem, section, conf2) { + const g = elem.append("g"); + const rect = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + rect.x = section.x; + rect.y = section.y; + rect.fill = section.fill; + rect.width = conf2.width * section.taskCount + // width of the tasks + conf2.diagramMarginX * (section.taskCount - 1); + rect.height = conf2.height; + rect.class = "journey-section section-type-" + section.num; + rect.rx = 3; + rect.ry = 3; + drawRect(g, rect); + _drawTextCandidateFunc(conf2)( + section.text, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "journey-section section-type-" + section.num }, + conf2, + section.colour + ); +}; +let taskCount = -1; +const drawTask = function(elem, task, conf2) { + const center = task.x + conf2.width / 2; + const g = elem.append("g"); + taskCount++; + const maxHeight = 300 + 5 * 30; + g.append("line").attr("id", "task" + taskCount).attr("x1", center).attr("y1", task.y).attr("x2", center).attr("y2", maxHeight).attr("class", "task-line").attr("stroke-width", "1px").attr("stroke-dasharray", "4 2").attr("stroke", "#666"); + drawFace(g, { + cx: center, + cy: 300 + (5 - task.score) * 30, + score: task.score + }); + const rect = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + rect.x = task.x; + rect.y = task.y; + rect.fill = task.fill; + rect.width = conf2.width; + rect.height = conf2.height; + rect.class = "task task-type-" + task.num; + rect.rx = 3; + rect.ry = 3; + drawRect(g, rect); + let xPos = task.x + 14; + task.people.forEach((person) => { + const colour = task.actors[person].color; + const circle = { + cx: xPos, + cy: task.y, + r: 7, + fill: colour, + stroke: "#000", + title: person, + pos: task.actors[person].position + }; + drawCircle(g, circle); + xPos += 10; + }); + _drawTextCandidateFunc(conf2)( + task.task, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "task" }, + conf2, + task.colour + ); +}; +const drawBackgroundRect = function(elem, bounds2) { + (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.a)(elem, bounds2); +}; +const _drawTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs, colour) { + const text = g.append("text").attr("x", x + width / 2).attr("y", y + height / 2 + 5).style("font-color", colour).style("text-anchor", "middle").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf2, colour) { + const { taskFontSize, taskFontFamily } = conf2; + const lines = content.split(/<br\s*\/?>/gi); + for (let i = 0; i < lines.length; i++) { + const dy = i * taskFontSize - taskFontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x + width / 2).attr("y", y).attr("fill", colour).style("text-anchor", "middle").style("font-size", taskFontSize).style("font-family", taskFontFamily); + text.append("tspan").attr("x", x + width / 2).attr("dy", dy).text(lines[i]); + text.attr("y", y + height / 2).attr("dominant-baseline", "central").attr("alignment-baseline", "central"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf2) { + const body = g.append("switch"); + const f = body.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height).attr("position", "fixed"); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").attr("class", "label").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, body, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (key in fromTextAttrsDict) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf2) { + return conf2.textPlacement === "fo" ? byFo : conf2.textPlacement === "old" ? byText : byTspan; + }; +}(); +const initGraphics = function(graphics) { + graphics.append("defs").append("marker").attr("id", "arrowhead").attr("refX", 5).attr("refY", 2).attr("markerWidth", 6).attr("markerHeight", 4).attr("orient", "auto").append("path").attr("d", "M 0,0 V 4 L6,2 Z"); +}; +const svgDraw = { + drawRect, + drawCircle, + drawSection, + drawText, + drawLabel, + drawTask, + drawBackgroundRect, + initGraphics +}; +const setConf = function(cnf) { + const keys = Object.keys(cnf); + keys.forEach(function(key) { + conf[key] = cnf[key]; + }); +}; +const actors = {}; +function drawActorLegend(diagram2) { + const conf2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; + let yPos = 60; + Object.keys(actors).forEach((person) => { + const colour = actors[person].color; + const circleData = { + cx: 20, + cy: yPos, + r: 7, + fill: colour, + stroke: "#000", + pos: actors[person].position + }; + svgDraw.drawCircle(diagram2, circleData); + const labelData = { + x: 40, + y: yPos + 7, + fill: "#666", + text: person, + textMargin: conf2.boxTextMargin | 5 + }; + svgDraw.drawText(diagram2, labelData); + yPos += 20; + }); +} +const conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; +const LEFT_MARGIN = conf.leftMargin; +const draw = function(text, id, version, diagObj) { + const conf2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; + const securityLevel = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + bounds.init(); + const diagram2 = root.select("#" + id); + svgDraw.initGraphics(diagram2); + const tasks2 = diagObj.db.getTasks(); + const title = diagObj.db.getDiagramTitle(); + const actorNames = diagObj.db.getActors(); + for (const member in actors) { + delete actors[member]; + } + let actorPos = 0; + actorNames.forEach((actorName) => { + actors[actorName] = { + color: conf2.actorColours[actorPos % conf2.actorColours.length], + position: actorPos + }; + actorPos++; + }); + drawActorLegend(diagram2); + bounds.insert(0, 0, LEFT_MARGIN, Object.keys(actors).length * 50); + drawTasks(diagram2, tasks2, 0); + const box = bounds.getBounds(); + if (title) { + diagram2.append("text").text(title).attr("x", LEFT_MARGIN).attr("font-size", "4ex").attr("font-weight", "bold").attr("y", 25); + } + const height = box.stopy - box.starty + 2 * conf2.diagramMarginY; + const width = LEFT_MARGIN + box.stopx + 2 * conf2.diagramMarginX; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.i)(diagram2, height, width, conf2.useMaxWidth); + diagram2.append("line").attr("x1", LEFT_MARGIN).attr("y1", conf2.height * 4).attr("x2", width - LEFT_MARGIN - 4).attr("y2", conf2.height * 4).attr("stroke-width", 4).attr("stroke", "black").attr("marker-end", "url(#arrowhead)"); + const extraVertForTitle = title ? 70 : 0; + diagram2.attr("viewBox", `${box.startx} -25 ${width} ${height + extraVertForTitle}`); + diagram2.attr("preserveAspectRatio", "xMinYMin meet"); + diagram2.attr("height", height + extraVertForTitle + 25); +}; +const bounds = { + data: { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0 + }, + verticalPos: 0, + sequenceItems: [], + init: function() { + this.sequenceItems = []; + this.data = { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0 + }; + this.verticalPos = 0; + }, + updateVal: function(obj, key, val, fun) { + if (obj[key] === void 0) { + obj[key] = val; + } else { + obj[key] = fun(val, obj[key]); + } + }, + updateBounds: function(startx, starty, stopx, stopy) { + const conf2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; + const _self = this; + let cnt = 0; + function updateFn(type) { + return function updateItemBounds(item) { + cnt++; + const n = _self.sequenceItems.length - cnt + 1; + _self.updateVal(item, "starty", starty - n * conf2.boxMargin, Math.min); + _self.updateVal(item, "stopy", stopy + n * conf2.boxMargin, Math.max); + _self.updateVal(bounds.data, "startx", startx - n * conf2.boxMargin, Math.min); + _self.updateVal(bounds.data, "stopx", stopx + n * conf2.boxMargin, Math.max); + if (!(type === "activation")) { + _self.updateVal(item, "startx", startx - n * conf2.boxMargin, Math.min); + _self.updateVal(item, "stopx", stopx + n * conf2.boxMargin, Math.max); + _self.updateVal(bounds.data, "starty", starty - n * conf2.boxMargin, Math.min); + _self.updateVal(bounds.data, "stopy", stopy + n * conf2.boxMargin, Math.max); + } + }; + } + this.sequenceItems.forEach(updateFn()); + }, + insert: function(startx, starty, stopx, stopy) { + const _startx = Math.min(startx, stopx); + const _stopx = Math.max(startx, stopx); + const _starty = Math.min(starty, stopy); + const _stopy = Math.max(starty, stopy); + this.updateVal(bounds.data, "startx", _startx, Math.min); + this.updateVal(bounds.data, "starty", _starty, Math.min); + this.updateVal(bounds.data, "stopx", _stopx, Math.max); + this.updateVal(bounds.data, "stopy", _stopy, Math.max); + this.updateBounds(_startx, _starty, _stopx, _stopy); + }, + bumpVerticalPos: function(bump) { + this.verticalPos = this.verticalPos + bump; + this.data.stopy = this.verticalPos; + }, + getVerticalPos: function() { + return this.verticalPos; + }, + getBounds: function() { + return this.data; + } +}; +const fills = conf.sectionFills; +const textColours = conf.sectionColours; +const drawTasks = function(diagram2, tasks2, verticalPos) { + const conf2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().journey; + let lastSection = ""; + const sectionVHeight = conf2.height * 2 + conf2.diagramMarginY; + const taskPos = verticalPos + sectionVHeight; + let sectionNumber = 0; + let fill = "#CCC"; + let colour = "black"; + let num = 0; + for (const [i, task] of tasks2.entries()) { + if (lastSection !== task.section) { + fill = fills[sectionNumber % fills.length]; + num = sectionNumber % fills.length; + colour = textColours[sectionNumber % textColours.length]; + let taskInSectionCount = 0; + const currentSection2 = task.section; + for (let taskIndex = i; taskIndex < tasks2.length; taskIndex++) { + if (tasks2[taskIndex].section == currentSection2) { + taskInSectionCount = taskInSectionCount + 1; + } else { + break; + } + } + const section = { + x: i * conf2.taskMargin + i * conf2.width + LEFT_MARGIN, + y: 50, + text: task.section, + fill, + num, + colour, + taskCount: taskInSectionCount + }; + svgDraw.drawSection(diagram2, section, conf2); + lastSection = task.section; + sectionNumber++; + } + const taskActors = task.people.reduce((acc, actorName) => { + if (actors[actorName]) { + acc[actorName] = actors[actorName]; + } + return acc; + }, {}); + task.x = i * conf2.taskMargin + i * conf2.width + LEFT_MARGIN; + task.y = taskPos; + task.width = conf2.diagramMarginX; + task.height = conf2.diagramMarginY; + task.colour = colour; + task.fill = fill; + task.num = num; + task.actors = taskActors; + svgDraw.drawTask(diagram2, task, conf2); + bounds.insert(task.x, task.y, task.x + task.width + conf2.taskMargin, 300 + 5 * 30); + } +}; +const renderer = { + setConf, + draw +}; +const diagram = { + parser: parser$1, + db, + renderer, + styles, + init: (cnf) => { + renderer.setConf(cnf.journey); + db.clear(); + } +}; + + + +/***/ }), + +/***/ 93799: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ drawBackgroundRect), +/* harmony export */ b: () => (/* binding */ drawEmbeddedImage), +/* harmony export */ c: () => (/* binding */ drawImage), +/* harmony export */ d: () => (/* binding */ drawRect), +/* harmony export */ e: () => (/* binding */ getTextObj), +/* harmony export */ f: () => (/* binding */ drawText), +/* harmony export */ g: () => (/* binding */ getNoteRect) +/* harmony export */ }); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(17967); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); + + +const drawRect = (element, rectData) => { + const rectElement = element.append("rect"); + rectElement.attr("x", rectData.x); + rectElement.attr("y", rectData.y); + rectElement.attr("fill", rectData.fill); + rectElement.attr("stroke", rectData.stroke); + rectElement.attr("width", rectData.width); + rectElement.attr("height", rectData.height); + rectData.rx !== void 0 && rectElement.attr("rx", rectData.rx); + rectData.ry !== void 0 && rectElement.attr("ry", rectData.ry); + if (rectData.attrs !== void 0) { + for (const attrKey in rectData.attrs) { + rectElement.attr(attrKey, rectData.attrs[attrKey]); + } + } + rectData.class !== void 0 && rectElement.attr("class", rectData.class); + return rectElement; +}; +const drawBackgroundRect = (element, bounds) => { + const rectData = { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + stroke: bounds.stroke, + class: "rect" + }; + const rectElement = drawRect(element, rectData); + rectElement.lower(); +}; +const drawText = (element, textData) => { + const nText = textData.text.replace(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.H, " "); + const textElem = element.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", textData.y); + textElem.attr("class", "legend"); + textElem.style("text-anchor", textData.anchor); + textData.class !== void 0 && textElem.attr("class", textData.class); + const tspan = textElem.append("tspan"); + tspan.attr("x", textData.x + textData.textMargin * 2); + tspan.text(nText); + return textElem; +}; +const drawImage = (elem, x, y, link) => { + const imageElement = elem.append("image"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Nm)(link); + imageElement.attr("xlink:href", sanitizedLink); +}; +const drawEmbeddedImage = (element, x, y, link) => { + const imageElement = element.append("use"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Nm)(link); + imageElement.attr("xlink:href", `#${sanitizedLink}`); +}; +const getNoteRect = () => { + const noteRectData = { + x: 0, + y: 0, + width: 100, + height: 100, + fill: "#EDF2AE", + stroke: "#666", + anchor: "start", + rx: 0, + ry: 0 + }; + return noteRectData; +}; +const getTextObj = () => { + const testObject = { + x: 0, + y: 0, + width: 100, + height: 100, + "text-anchor": "start", + style: "#666", + textMargin: 0, + rx: 0, + ry: 0, + tspan: true + }; + return testObject; +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/52106a5f.17a5eda6.js b/assets/js/52106a5f.17a5eda6.js new file mode 100644 index 000000000..bc9eb1799 --- /dev/null +++ b/assets/js/52106a5f.17a5eda6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9396],{68973:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var r=n(85893),i=n(3905);const l={title:"IntelliJ \uc124\uc815",slug:"intellij-settings",tags:["IntelliJ"]},a=void 0,o={permalink:"/intellij-settings",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",source:"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",title:"IntelliJ \uc124\uc815",description:"Import \uc790\ub3d9 \uc801\uc6a9",date:"2023-01-30T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 30\uc77c",tags:[{label:"IntelliJ",permalink:"/tags/intelli-j"}],readingTime:.465,hasTruncateMarker:!1,authors:[],frontMatter:{title:"IntelliJ \uc124\uc815",slug:"intellij-settings",tags:["IntelliJ"]},unlisted:!1,prevItem:{title:"Parameterized Tests",permalink:"/parameterized-tests"},nextItem:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",permalink:"/kotlin-null"}},s={authorsImageUrls:[]},c=[{value:"Import \uc790\ub3d9 \uc801\uc6a9",id:"import-\uc790\ub3d9-\uc801\uc6a9",level:3},{value:"\uc800\uc7a5\uc2dc \ub3d9\uc791",id:"\uc800\uc7a5\uc2dc-\ub3d9\uc791",level:3},{value:"\uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9",id:"\uba54\uc18c\ub4dc-\ucd94\ucd9c-\ubcc0\uc218-\ucd94\ucd9c\uc2dc-final-\uc801\uc6a9",level:3}];function p(e){const t={h3:"h3",img:"img",p:"p",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"import-\uc790\ub3d9-\uc801\uc6a9",children:"Import \uc790\ub3d9 \uc801\uc6a9"}),"\n",(0,r.jsx)(t.p,{children:"Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"auto-import",src:n(41394).Z+"",width:"2558",height:"1656"})}),"\n",(0,r.jsx)(t.h3,{id:"\uc800\uc7a5\uc2dc-\ub3d9\uc791",children:"\uc800\uc7a5\uc2dc \ub3d9\uc791"}),"\n",(0,r.jsx)(t.p,{children:"Prefrences > Tools > Actions on Save"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"actions-on-save",src:n(24927).Z+"",width:"2558",height:"1656"})}),"\n",(0,r.jsx)(t.p,{children:"Reformat Code: Code Reformmating"}),"\n",(0,r.jsx)(t.p,{children:"Optimize imports: \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 Import \uc81c\uac70"}),"\n",(0,r.jsx)(t.p,{children:"Rearrange: Code Style > Arrangement \uc124\uc815 \uae30\ubc18 \ucf54\ub4dc \uc7ac\uc815\ub82c"}),"\n",(0,r.jsx)(t.h3,{id:"\uba54\uc18c\ub4dc-\ucd94\ucd9c-\ubcc0\uc218-\ucd94\ucd9c\uc2dc-final-\uc801\uc6a9",children:"\uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9"}),"\n",(0,r.jsx)(t.p,{children:"Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"final-modifier",src:n(21796).Z+"",width:"2558",height:"1656"})})]})}function d(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>c});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),m=c(n),u=i,f=m["".concat(s,".").concat(u)]||m[u]||p[u]||l;return n?r.createElement(f,a(a({ref:t},d),{},{components:n})):r.createElement(f,a({ref:t},d))}));d.displayName="MDXCreateElement"},24927:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/actions-on-save-6c1203027c28ff08919e045812c7d456.png"},41394:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/auto-import-3dbe46f0109af17296039d52d498225e.png"},21796:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/final-modifier-1dd2aea35979423a30869a7b0ebe501a.png"}}]); \ No newline at end of file diff --git a/assets/js/52106a5f.e7405ebf.js b/assets/js/52106a5f.e7405ebf.js deleted file mode 100644 index 2cdefa64b..000000000 --- a/assets/js/52106a5f.e7405ebf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9396],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>f});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=r.createContext({}),p=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},c=function(e){var t=p(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),m=p(n),f=i,d=m["".concat(s,".").concat(f)]||m[f]||u[f]||l;return n?r.createElement(d,a(a({ref:t},c),{},{components:n})):r.createElement(d,a({ref:t},c))}));function f(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var l=n.length,a=new Array(l);a[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o.mdxType="string"==typeof e?e:i,a[1]=o;for(var p=2;p<l;p++)a[p]=n[p];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},63338:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>u,frontMatter:()=>l,metadata:()=>o,toc:()=>p});var r=n(87462),i=(n(67294),n(3905));const l={title:"IntelliJ \uc124\uc815",slug:"intellij-settings",tags:["IntelliJ"]},a=void 0,o={permalink:"/intellij-settings",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",source:"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",title:"IntelliJ \uc124\uc815",description:"Import \uc790\ub3d9 \uc801\uc6a9",date:"2023-01-30T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 30\uc77c",tags:[{label:"IntelliJ",permalink:"/tags/intelli-j"}],readingTime:.465,hasTruncateMarker:!1,authors:[],frontMatter:{title:"IntelliJ \uc124\uc815",slug:"intellij-settings",tags:["IntelliJ"]},prevItem:{title:"Parameterized Tests",permalink:"/parameterized-tests"},nextItem:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",permalink:"/kotlin-null"}},s={authorsImageUrls:[]},p=[{value:"Import \uc790\ub3d9 \uc801\uc6a9",id:"import-\uc790\ub3d9-\uc801\uc6a9",level:3},{value:"\uc800\uc7a5\uc2dc \ub3d9\uc791",id:"\uc800\uc7a5\uc2dc-\ub3d9\uc791",level:3},{value:"\uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9",id:"\uba54\uc18c\ub4dc-\ucd94\ucd9c-\ubcc0\uc218-\ucd94\ucd9c\uc2dc-final-\uc801\uc6a9",level:3}],c={toc:p};function u(e){let{components:t,...l}=e;return(0,i.kt)("wrapper",(0,r.Z)({},c,l,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h3",{id:"import-\uc790\ub3d9-\uc801\uc6a9"},"Import \uc790\ub3d9 \uc801\uc6a9"),(0,i.kt)("p",null,"Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"auto-import",src:n(41394).Z,width:"2558",height:"1656"})),(0,i.kt)("h3",{id:"\uc800\uc7a5\uc2dc-\ub3d9\uc791"},"\uc800\uc7a5\uc2dc \ub3d9\uc791"),(0,i.kt)("p",null,"Prefrences > Tools > Actions on Save"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"actions-on-save",src:n(24927).Z,width:"2558",height:"1656"})),(0,i.kt)("p",null,"Reformat Code: Code Reformmating"),(0,i.kt)("p",null,"Optimize imports: \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 Import \uc81c\uac70"),(0,i.kt)("p",null,"Rearrange: Code Style > Arrangement \uc124\uc815 \uae30\ubc18 \ucf54\ub4dc \uc7ac\uc815\ub82c"),(0,i.kt)("h3",{id:"\uba54\uc18c\ub4dc-\ucd94\ucd9c-\ubcc0\uc218-\ucd94\ucd9c\uc2dc-final-\uc801\uc6a9"},"\uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9"),(0,i.kt)("p",null,"Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"final-modifier",src:n(21796).Z,width:"2558",height:"1656"})))}u.isMDXComponent=!0},24927:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/actions-on-save-6c1203027c28ff08919e045812c7d456.png"},41394:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/auto-import-3dbe46f0109af17296039d52d498225e.png"},21796:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/final-modifier-1dd2aea35979423a30869a7b0ebe501a.png"}}]); \ No newline at end of file diff --git a/assets/js/5254.19cc10bc.js b/assets/js/5254.19cc10bc.js new file mode 100644 index 000000000..6c31d34a1 --- /dev/null +++ b/assets/js/5254.19cc10bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5254],{75254:(t,e,s)=>{s.d(e,{d:()=>st,f:()=>et,p:()=>r});var u=s(64218),i=s(56363),n=function(){var t=function(t,e,s,u){for(s=s||{},u=t.length;u--;s[t[u]]=e);return s},e=[1,4],s=[1,3],u=[1,5],i=[1,8,9,10,11,27,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],n=[2,2],r=[1,13],a=[1,14],c=[1,15],o=[1,16],l=[1,23],h=[1,25],A=[1,26],d=[1,27],p=[1,49],y=[1,48],E=[1,29],f=[1,30],k=[1,31],D=[1,32],g=[1,33],b=[1,44],F=[1,46],T=[1,42],C=[1,47],_=[1,43],B=[1,50],S=[1,45],m=[1,51],x=[1,52],v=[1,34],L=[1,35],I=[1,36],R=[1,37],N=[1,57],$=[1,8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],O=[1,61],P=[1,60],w=[1,62],U=[8,9,11,73,75],V=[1,88],G=[1,93],M=[1,92],Y=[1,89],K=[1,85],j=[1,91],X=[1,87],z=[1,94],H=[1,90],W=[1,95],Q=[1,86],q=[8,9,10,11,73,75],Z=[8,9,10,11,44,73,75],J=[8,9,10,11,29,42,44,46,48,50,52,54,56,58,61,63,65,66,68,73,75,86,99,102,103,106,108,111,112,113],tt=[8,9,11,42,58,73,75,86,99,102,103,106,108,111,112,113],et=[42,58,86,99,102,103,106,108,111,112,113],st=[1,121],ut=[1,120],it=[1,128],nt=[1,142],rt=[1,143],at=[1,144],ct=[1,145],ot=[1,130],lt=[1,132],ht=[1,136],At=[1,137],dt=[1,138],pt=[1,139],yt=[1,140],Et=[1,141],ft=[1,146],kt=[1,147],Dt=[1,126],gt=[1,127],bt=[1,134],Ft=[1,129],Tt=[1,133],Ct=[1,131],_t=[8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],Bt=[1,149],St=[8,9,11],mt=[8,9,10,11,14,42,58,86,102,103,106,108,111,112,113],xt=[1,169],vt=[1,165],Lt=[1,166],It=[1,170],Rt=[1,167],Nt=[1,168],$t=[75,113,116],Ot=[8,9,10,11,12,14,27,29,32,42,58,73,81,82,83,84,85,86,87,102,106,108,111,112,113],Pt=[10,103],wt=[31,47,49,51,53,55,60,62,64,65,67,69,113,114,115],Ut=[1,235],Vt=[1,233],Gt=[1,237],Mt=[1,231],Yt=[1,232],Kt=[1,234],jt=[1,236],Xt=[1,238],zt=[1,255],Ht=[8,9,11,103],Wt=[8,9,10,11,58,81,102,103,106,107,108,109],Qt={trace:function(){},yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeperator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,verticeStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,link:39,node:40,styledVertex:41,AMP:42,vertex:43,STYLE_SEPARATOR:44,idString:45,DOUBLECIRCLESTART:46,DOUBLECIRCLEEND:47,PS:48,PE:49,"(-":50,"-)":51,STADIUMSTART:52,STADIUMEND:53,SUBROUTINESTART:54,SUBROUTINEEND:55,VERTEX_WITH_PROPS_START:56,"NODE_STRING[field]":57,COLON:58,"NODE_STRING[value]":59,PIPE:60,CYLINDERSTART:61,CYLINDEREND:62,DIAMOND_START:63,DIAMOND_STOP:64,TAGEND:65,TRAPSTART:66,TRAPEND:67,INVTRAPSTART:68,INVTRAPEND:69,linkStatement:70,arrowText:71,TESTSTR:72,START_LINK:73,edgeText:74,LINK:75,edgeTextToken:76,STR:77,MD_STR:78,textToken:79,keywords:80,STYLE:81,LINKSTYLE:82,CLASSDEF:83,CLASS:84,CLICK:85,DOWN:86,UP:87,textNoTagsToken:88,stylesOpt:89,"idString[vertex]":90,"idString[class]":91,CALLBACKNAME:92,CALLBACKARGS:93,HREF:94,LINK_TARGET:95,"STR[link]":96,"STR[tooltip]":97,alphaNum:98,DEFAULT:99,numList:100,INTERPOLATE:101,NUM:102,COMMA:103,style:104,styleComponent:105,NODE_STRING:106,UNIT:107,BRKT:108,PCT:109,idStringToken:110,MINUS:111,MULT:112,UNICODE_TEXT:113,TEXT:114,TAGSTART:115,EDGE_TEXT:116,alphaNumToken:117,direction_tb:118,direction_bt:119,direction_rl:120,direction_lr:121,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",42:"AMP",44:"STYLE_SEPARATOR",46:"DOUBLECIRCLESTART",47:"DOUBLECIRCLEEND",48:"PS",49:"PE",50:"(-",51:"-)",52:"STADIUMSTART",53:"STADIUMEND",54:"SUBROUTINESTART",55:"SUBROUTINEEND",56:"VERTEX_WITH_PROPS_START",57:"NODE_STRING[field]",58:"COLON",59:"NODE_STRING[value]",60:"PIPE",61:"CYLINDERSTART",62:"CYLINDEREND",63:"DIAMOND_START",64:"DIAMOND_STOP",65:"TAGEND",66:"TRAPSTART",67:"TRAPEND",68:"INVTRAPSTART",69:"INVTRAPEND",72:"TESTSTR",73:"START_LINK",75:"LINK",77:"STR",78:"MD_STR",81:"STYLE",82:"LINKSTYLE",83:"CLASSDEF",84:"CLASS",85:"CLICK",86:"DOWN",87:"UP",90:"idString[vertex]",91:"idString[class]",92:"CALLBACKNAME",93:"CALLBACKARGS",94:"HREF",95:"LINK_TARGET",96:"STR[link]",97:"STR[tooltip]",99:"DEFAULT",101:"INTERPOLATE",102:"NUM",103:"COMMA",106:"NODE_STRING",107:"UNIT",108:"BRKT",109:"PCT",111:"MINUS",112:"MULT",113:"UNICODE_TEXT",114:"TEXT",115:"TAGSTART",116:"EDGE_TEXT",118:"direction_tb",119:"direction_bt",120:"direction_rl",121:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[20,3],[20,4],[20,2],[20,1],[40,1],[40,5],[41,1],[41,3],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,8],[43,4],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,4],[43,4],[43,1],[39,2],[39,3],[39,3],[39,1],[39,3],[74,1],[74,2],[74,1],[74,1],[70,1],[71,3],[30,1],[30,2],[30,1],[30,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[100,1],[100,3],[89,1],[89,3],[104,1],[104,2],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[79,1],[79,1],[79,1],[79,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[76,1],[76,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[45,1],[45,2],[98,1],[98,2],[33,1],[33,1],[33,1],[33,1]],performAction:function(t,e,s,u,i,n,r){var a=n.length-1;switch(i){case 2:case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 3:(!Array.isArray(n[a])||n[a].length>0)&&n[a-1].push(n[a]),this.$=n[a-1];break;case 4:case 176:case 49:case 71:case 174:this.$=n[a];break;case 11:u.setDirection("TB"),this.$="TB";break;case 12:u.setDirection(n[a-1]),this.$=n[a-1];break;case 27:this.$=n[a-1].nodes;break;case 33:this.$=u.addSubGraph(n[a-6],n[a-1],n[a-4]);break;case 34:this.$=u.addSubGraph(n[a-3],n[a-1],n[a-3]);break;case 35:this.$=u.addSubGraph(void 0,n[a-1],void 0);break;case 37:this.$=n[a].trim(),u.setAccTitle(this.$);break;case 38:case 39:this.$=n[a].trim(),u.setAccDescription(this.$);break;case 43:u.addLink(n[a-2].stmt,n[a],n[a-1]),this.$={stmt:n[a],nodes:n[a].concat(n[a-2].nodes)};break;case 44:u.addLink(n[a-3].stmt,n[a-1],n[a-2]),this.$={stmt:n[a-1],nodes:n[a-1].concat(n[a-3].nodes)};break;case 45:this.$={stmt:n[a-1],nodes:n[a-1]};break;case 46:this.$={stmt:n[a],nodes:n[a]};break;case 47:case 121:case 123:this.$=[n[a]];break;case 48:this.$=n[a-4].concat(n[a]);break;case 50:this.$=n[a-2],u.setClass(n[a-2],n[a]);break;case 51:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"square");break;case 52:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"doublecircle");break;case 53:this.$=n[a-5],u.addVertex(n[a-5],n[a-2],"circle");break;case 54:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"ellipse");break;case 55:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"stadium");break;case 56:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"subroutine");break;case 57:this.$=n[a-7],u.addVertex(n[a-7],n[a-1],"rect",void 0,void 0,void 0,Object.fromEntries([[n[a-5],n[a-3]]]));break;case 58:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"cylinder");break;case 59:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"round");break;case 60:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"diamond");break;case 61:this.$=n[a-5],u.addVertex(n[a-5],n[a-2],"hexagon");break;case 62:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"odd");break;case 63:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"trapezoid");break;case 64:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"inv_trapezoid");break;case 65:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"lean_right");break;case 66:this.$=n[a-3],u.addVertex(n[a-3],n[a-1],"lean_left");break;case 67:this.$=n[a],u.addVertex(n[a]);break;case 68:n[a-1].text=n[a],this.$=n[a-1];break;case 69:case 70:n[a-2].text=n[a-1],this.$=n[a-2];break;case 72:var c=u.destructLink(n[a],n[a-2]);this.$={type:c.type,stroke:c.stroke,length:c.length,text:n[a-1]};break;case 73:case 79:case 94:case 96:this.$={text:n[a],type:"text"};break;case 74:case 80:case 95:this.$={text:n[a-1].text+""+n[a],type:n[a-1].type};break;case 75:case 81:this.$={text:n[a],type:"string"};break;case 76:case 82:case 97:this.$={text:n[a],type:"markdown"};break;case 77:c=u.destructLink(n[a]);this.$={type:c.type,stroke:c.stroke,length:c.length};break;case 78:this.$=n[a-1];break;case 98:this.$=n[a-4],u.addClass(n[a-2],n[a]);break;case 99:this.$=n[a-4],u.setClass(n[a-2],n[a]);break;case 100:case 108:this.$=n[a-1],u.setClickEvent(n[a-1],n[a]);break;case 101:case 109:this.$=n[a-3],u.setClickEvent(n[a-3],n[a-2]),u.setTooltip(n[a-3],n[a]);break;case 102:this.$=n[a-2],u.setClickEvent(n[a-2],n[a-1],n[a]);break;case 103:this.$=n[a-4],u.setClickEvent(n[a-4],n[a-3],n[a-2]),u.setTooltip(n[a-4],n[a]);break;case 104:this.$=n[a-2],u.setLink(n[a-2],n[a]);break;case 105:this.$=n[a-4],u.setLink(n[a-4],n[a-2]),u.setTooltip(n[a-4],n[a]);break;case 106:this.$=n[a-4],u.setLink(n[a-4],n[a-2],n[a]);break;case 107:this.$=n[a-6],u.setLink(n[a-6],n[a-4],n[a]),u.setTooltip(n[a-6],n[a-2]);break;case 110:this.$=n[a-1],u.setLink(n[a-1],n[a]);break;case 111:this.$=n[a-3],u.setLink(n[a-3],n[a-2]),u.setTooltip(n[a-3],n[a]);break;case 112:this.$=n[a-3],u.setLink(n[a-3],n[a-2],n[a]);break;case 113:this.$=n[a-5],u.setLink(n[a-5],n[a-4],n[a]),u.setTooltip(n[a-5],n[a-2]);break;case 114:this.$=n[a-4],u.addVertex(n[a-2],void 0,void 0,n[a]);break;case 115:this.$=n[a-4],u.updateLink([n[a-2]],n[a]);break;case 116:this.$=n[a-4],u.updateLink(n[a-2],n[a]);break;case 117:this.$=n[a-8],u.updateLinkInterpolate([n[a-6]],n[a-2]),u.updateLink([n[a-6]],n[a]);break;case 118:this.$=n[a-8],u.updateLinkInterpolate(n[a-6],n[a-2]),u.updateLink(n[a-6],n[a]);break;case 119:this.$=n[a-6],u.updateLinkInterpolate([n[a-4]],n[a]);break;case 120:this.$=n[a-6],u.updateLinkInterpolate(n[a-4],n[a]);break;case 122:case 124:n[a-2].push(n[a]),this.$=n[a-2];break;case 126:this.$=n[a-1]+n[a];break;case 175:case 177:this.$=n[a-1]+""+n[a];break;case 178:this.$={stmt:"dir",value:"TB"};break;case 179:this.$={stmt:"dir",value:"BT"};break;case 180:this.$={stmt:"dir",value:"RL"};break;case 181:this.$={stmt:"dir",value:"LR"}}},table:[{3:1,4:2,9:e,10:s,12:u},{1:[3]},t(i,n,{5:6}),{4:7,9:e,10:s,12:u},{4:8,9:e,10:s,12:u},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:k,84:D,85:g,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},t(i,[2,9]),t(i,[2,10]),t(i,[2,11]),{8:[1,54],9:[1,55],10:N,15:53,18:56},t($,[2,3]),t($,[2,4]),t($,[2,5]),t($,[2,6]),t($,[2,7]),t($,[2,8]),{8:O,9:P,11:w,21:58,39:59,70:63,73:[1,64],75:[1,65]},{8:O,9:P,11:w,21:66},{8:O,9:P,11:w,21:67},{8:O,9:P,11:w,21:68},{8:O,9:P,11:w,21:69},{8:O,9:P,11:w,21:70},{8:O,9:P,10:[1,71],11:w,21:72},t($,[2,36]),{35:[1,73]},{37:[1,74]},t($,[2,39]),t(U,[2,46],{18:75,10:N}),{10:[1,76]},{10:[1,77]},{10:[1,78]},{10:[1,79]},{14:V,42:G,58:M,77:[1,83],86:Y,92:[1,80],94:[1,81],98:82,102:K,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},t($,[2,178]),t($,[2,179]),t($,[2,180]),t($,[2,181]),t(q,[2,47]),t(q,[2,49],{44:[1,96]}),t(Z,[2,67],{110:109,29:[1,97],42:p,46:[1,98],48:[1,99],50:[1,100],52:[1,101],54:[1,102],56:[1,103],58:y,61:[1,104],63:[1,105],65:[1,106],66:[1,107],68:[1,108],86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),t(J,[2,174]),t(J,[2,135]),t(J,[2,136]),t(J,[2,137]),t(J,[2,138]),t(J,[2,139]),t(J,[2,140]),t(J,[2,141]),t(J,[2,142]),t(J,[2,143]),t(J,[2,144]),t(J,[2,145]),t(i,[2,12]),t(i,[2,18]),t(i,[2,19]),{9:[1,110]},t(tt,[2,26],{18:111,10:N}),t($,[2,27]),{40:112,41:38,42:p,43:39,45:40,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t($,[2,40]),t($,[2,41]),t($,[2,42]),t(et,[2,71],{71:113,60:[1,115],72:[1,114]}),{74:116,76:117,77:[1,118],78:[1,119],113:st,116:ut},t([42,58,60,72,86,99,102,103,106,108,111,112,113],[2,77]),t($,[2,28]),t($,[2,29]),t($,[2,30]),t($,[2,31]),t($,[2,32]),{10:it,12:nt,14:rt,27:at,28:122,32:ct,42:ot,58:lt,73:ht,77:[1,124],78:[1,125],80:135,81:At,82:dt,83:pt,84:yt,85:Et,86:ft,87:kt,88:123,102:Dt,106:gt,108:bt,111:Ft,112:Tt,113:Ct},t(_t,n,{5:148}),t($,[2,37]),t($,[2,38]),t(U,[2,45],{42:Bt}),{42:p,45:150,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{99:[1,151],100:152,102:[1,153]},{42:p,45:154,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{42:p,45:155,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t(St,[2,100],{10:[1,156],93:[1,157]}),{77:[1,158]},t(St,[2,108],{117:160,10:[1,159],14:V,42:G,58:M,86:Y,102:K,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,110],{10:[1,161]}),t(mt,[2,176]),t(mt,[2,163]),t(mt,[2,164]),t(mt,[2,165]),t(mt,[2,166]),t(mt,[2,167]),t(mt,[2,168]),t(mt,[2,169]),t(mt,[2,170]),t(mt,[2,171]),t(mt,[2,172]),t(mt,[2,173]),{42:p,45:162,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{30:163,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:171,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:173,48:[1,172],65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:174,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:175,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:176,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{106:[1,177]},{30:178,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:179,63:[1,180],65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:181,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:182,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{30:183,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},t(J,[2,175]),t(i,[2,20]),t(tt,[2,25]),t(U,[2,43],{18:184,10:N}),t(et,[2,68],{10:[1,185]}),{10:[1,186]},{30:187,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{75:[1,188],76:189,113:st,116:ut},t($t,[2,73]),t($t,[2,75]),t($t,[2,76]),t($t,[2,161]),t($t,[2,162]),{8:O,9:P,10:it,11:w,12:nt,14:rt,21:191,27:at,29:[1,190],32:ct,42:ot,58:lt,73:ht,80:135,81:At,82:dt,83:pt,84:yt,85:Et,86:ft,87:kt,88:192,102:Dt,106:gt,108:bt,111:Ft,112:Tt,113:Ct},t(Ot,[2,94]),t(Ot,[2,96]),t(Ot,[2,97]),t(Ot,[2,150]),t(Ot,[2,151]),t(Ot,[2,152]),t(Ot,[2,153]),t(Ot,[2,154]),t(Ot,[2,155]),t(Ot,[2,156]),t(Ot,[2,157]),t(Ot,[2,158]),t(Ot,[2,159]),t(Ot,[2,160]),t(Ot,[2,83]),t(Ot,[2,84]),t(Ot,[2,85]),t(Ot,[2,86]),t(Ot,[2,87]),t(Ot,[2,88]),t(Ot,[2,89]),t(Ot,[2,90]),t(Ot,[2,91]),t(Ot,[2,92]),t(Ot,[2,93]),{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,193],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:k,84:D,85:g,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},{10:N,18:194},{10:[1,195],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{10:[1,196]},{10:[1,197],103:[1,198]},t(Pt,[2,121]),{10:[1,199],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{10:[1,200],42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:109,111:S,112:m,113:x},{77:[1,201]},t(St,[2,102],{10:[1,202]}),t(St,[2,104],{10:[1,203]}),{77:[1,204]},t(mt,[2,177]),{77:[1,205],95:[1,206]},t(q,[2,50],{110:109,42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),{31:[1,207],65:xt,79:208,113:It,114:Rt,115:Nt},t(wt,[2,79]),t(wt,[2,81]),t(wt,[2,82]),t(wt,[2,146]),t(wt,[2,147]),t(wt,[2,148]),t(wt,[2,149]),{47:[1,209],65:xt,79:208,113:It,114:Rt,115:Nt},{30:210,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{49:[1,211],65:xt,79:208,113:It,114:Rt,115:Nt},{51:[1,212],65:xt,79:208,113:It,114:Rt,115:Nt},{53:[1,213],65:xt,79:208,113:It,114:Rt,115:Nt},{55:[1,214],65:xt,79:208,113:It,114:Rt,115:Nt},{58:[1,215]},{62:[1,216],65:xt,79:208,113:It,114:Rt,115:Nt},{64:[1,217],65:xt,79:208,113:It,114:Rt,115:Nt},{30:218,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},{31:[1,219],65:xt,79:208,113:It,114:Rt,115:Nt},{65:xt,67:[1,220],69:[1,221],79:208,113:It,114:Rt,115:Nt},{65:xt,67:[1,223],69:[1,222],79:208,113:It,114:Rt,115:Nt},t(U,[2,44],{42:Bt}),t(et,[2,70]),t(et,[2,69]),{60:[1,224],65:xt,79:208,113:It,114:Rt,115:Nt},t(et,[2,72]),t($t,[2,74]),{30:225,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},t(_t,n,{5:226}),t(Ot,[2,95]),t($,[2,35]),{41:227,42:p,43:39,45:40,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},{10:Ut,58:Vt,81:Gt,89:228,102:Mt,104:229,105:230,106:Yt,107:Kt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:239,101:[1,240],102:Mt,104:229,105:230,106:Yt,107:Kt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:241,101:[1,242],102:Mt,104:229,105:230,106:Yt,107:Kt,108:jt,109:Xt},{102:[1,243]},{10:Ut,58:Vt,81:Gt,89:244,102:Mt,104:229,105:230,106:Yt,107:Kt,108:jt,109:Xt},{42:p,45:245,58:y,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x},t(St,[2,101]),{77:[1,246]},{77:[1,247],95:[1,248]},t(St,[2,109]),t(St,[2,111],{10:[1,249]}),t(St,[2,112]),t(Z,[2,51]),t(wt,[2,80]),t(Z,[2,52]),{49:[1,250],65:xt,79:208,113:It,114:Rt,115:Nt},t(Z,[2,59]),t(Z,[2,54]),t(Z,[2,55]),t(Z,[2,56]),{106:[1,251]},t(Z,[2,58]),t(Z,[2,60]),{64:[1,252],65:xt,79:208,113:It,114:Rt,115:Nt},t(Z,[2,62]),t(Z,[2,63]),t(Z,[2,65]),t(Z,[2,64]),t(Z,[2,66]),t([10,42,58,86,99,102,103,106,108,111,112,113],[2,78]),{31:[1,253],65:xt,79:208,113:It,114:Rt,115:Nt},{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,254],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:k,84:D,85:g,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},t(q,[2,48]),t(St,[2,114],{103:zt}),t(Ht,[2,123],{105:256,10:Ut,58:Vt,81:Gt,102:Mt,106:Yt,107:Kt,108:jt,109:Xt}),t(Wt,[2,125]),t(Wt,[2,127]),t(Wt,[2,128]),t(Wt,[2,129]),t(Wt,[2,130]),t(Wt,[2,131]),t(Wt,[2,132]),t(Wt,[2,133]),t(Wt,[2,134]),t(St,[2,115],{103:zt}),{10:[1,257]},t(St,[2,116],{103:zt}),{10:[1,258]},t(Pt,[2,122]),t(St,[2,98],{103:zt}),t(St,[2,99],{110:109,42:p,58:y,86:b,99:F,102:T,103:C,106:_,108:B,111:S,112:m,113:x}),t(St,[2,103]),t(St,[2,105],{10:[1,259]}),t(St,[2,106]),{95:[1,260]},{49:[1,261]},{60:[1,262]},{64:[1,263]},{8:O,9:P,11:w,21:264},t($,[2,34]),{10:Ut,58:Vt,81:Gt,102:Mt,104:265,105:230,106:Yt,107:Kt,108:jt,109:Xt},t(Wt,[2,126]),{14:V,42:G,58:M,86:Y,98:266,102:K,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},{14:V,42:G,58:M,86:Y,98:267,102:K,103:j,106:X,108:z,111:H,112:W,113:Q,117:84},{95:[1,268]},t(St,[2,113]),t(Z,[2,53]),{30:269,65:xt,77:vt,78:Lt,79:164,113:It,114:Rt,115:Nt},t(Z,[2,61]),t(_t,n,{5:270}),t(Ht,[2,124],{105:256,10:Ut,58:Vt,81:Gt,102:Mt,106:Yt,107:Kt,108:jt,109:Xt}),t(St,[2,119],{117:160,10:[1,271],14:V,42:G,58:M,86:Y,102:K,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,120],{117:160,10:[1,272],14:V,42:G,58:M,86:Y,102:K,103:j,106:X,108:z,111:H,112:W,113:Q}),t(St,[2,107]),{31:[1,273],65:xt,79:208,113:It,114:Rt,115:Nt},{6:11,7:12,8:r,9:a,10:c,11:o,20:17,22:18,23:19,24:20,25:21,26:22,27:l,32:[1,274],33:24,34:h,36:A,38:d,40:28,41:38,42:p,43:39,45:40,58:y,81:E,82:f,83:k,84:D,85:g,86:b,99:F,102:T,103:C,106:_,108:B,110:41,111:S,112:m,113:x,118:v,119:L,120:I,121:R},{10:Ut,58:Vt,81:Gt,89:275,102:Mt,104:229,105:230,106:Yt,107:Kt,108:jt,109:Xt},{10:Ut,58:Vt,81:Gt,89:276,102:Mt,104:229,105:230,106:Yt,107:Kt,108:jt,109:Xt},t(Z,[2,57]),t($,[2,33]),t(St,[2,117],{103:zt}),t(St,[2,118],{103:zt})],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],u=[],i=[null],n=[],r=this.table,a="",c=0,o=0,l=n.slice.call(arguments,1),h=Object.create(this.lexer),A={yy:{}};for(var d in this.yy)Object.prototype.hasOwnProperty.call(this.yy,d)&&(A.yy[d]=this.yy[d]);h.setInput(t,A.yy),A.yy.lexer=h,A.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var p=h.yylloc;n.push(p);var y=h.options&&h.options.ranges;"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,f,k,D,g,b,F,T,C,_={};;){if(f=s[s.length-1],this.defaultActions[f]?k=this.defaultActions[f]:(null==E&&(C=void 0,"number"!=typeof(C=u.pop()||h.lex()||1)&&(C instanceof Array&&(C=(u=C).pop()),C=e.symbols_[C]||C),E=C),k=r[f]&&r[f][E]),void 0===k||!k.length||!k[0]){var B="";for(g in T=[],r[f])this.terminals_[g]&&g>2&&T.push("'"+this.terminals_[g]+"'");B=h.showPosition?"Parse error on line "+(c+1)+":\n"+h.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(B,{text:h.match,token:this.terminals_[E]||E,line:h.yylineno,loc:p,expected:T})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+f+", token: "+E);switch(k[0]){case 1:s.push(E),i.push(h.yytext),n.push(h.yylloc),s.push(k[1]),E=null,o=h.yyleng,a=h.yytext,c=h.yylineno,p=h.yylloc;break;case 2:if(b=this.productions_[k[1]][1],_.$=i[i.length-b],_._$={first_line:n[n.length-(b||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(b||1)].first_column,last_column:n[n.length-1].last_column},y&&(_._$.range=[n[n.length-(b||1)].range[0],n[n.length-1].range[1]]),void 0!==(D=this.performAction.apply(_,[a,o,c,A.yy,k[1],i,n].concat(l))))return D;b&&(s=s.slice(0,-1*b*2),i=i.slice(0,-1*b),n=n.slice(0,-1*b)),s.push(this.productions_[k[1]][0]),i.push(_.$),n.push(_._$),F=r[s[s.length-2]][s[s.length-1]],s.push(F);break;case 3:return!0}}return!0}},qt={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var u=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===u.length?this.yylloc.first_column:0)+u[u.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var s,u,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(u=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=u.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:u?u[u.length-1].length-u[u.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var n in i)this[n]=i[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,u;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),n=0;n<i.length;n++)if((s=this._input.match(this.rules[i[n]]))&&(!e||s[0].length>e[0].length)){if(e=s,u=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[u]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,s,u){switch(s){case 0:return this.begin("acc_title"),34;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),36;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:case 8:case 11:case 14:case 17:case 27:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:this.begin("callbackname");break;case 9:this.popState(),this.begin("callbackargs");break;case 10:return 92;case 12:return 93;case 13:return"MD_STR";case 15:this.begin("md_string");break;case 16:return"STR";case 18:this.pushState("string");break;case 19:return 81;case 20:return 99;case 21:return 82;case 22:return 101;case 23:return 83;case 24:return 84;case 25:return 94;case 26:this.begin("click");break;case 28:return 85;case 29:case 30:case 31:return t.lex.firstGraph()&&this.begin("dir"),12;case 32:return 27;case 33:return 32;case 34:case 35:case 36:case 37:return 95;case 38:return this.popState(),13;case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 48:return this.popState(),14;case 49:return 118;case 50:return 119;case 51:return 120;case 52:return 121;case 53:return 102;case 54:case 95:return 108;case 55:return 44;case 56:return 58;case 57:case 96:return 42;case 58:return 8;case 59:return 103;case 60:case 94:return 112;case 61:case 64:case 67:return this.popState(),75;case 62:return this.pushState("edgeText"),73;case 63:case 66:case 69:return 116;case 65:return this.pushState("thickEdgeText"),73;case 68:return this.pushState("dottedEdgeText"),73;case 70:return 75;case 71:return this.popState(),51;case 72:case 108:return"TEXT";case 73:return this.pushState("ellipseText"),50;case 74:return this.popState(),53;case 75:return this.pushState("text"),52;case 76:return this.popState(),55;case 77:return this.pushState("text"),54;case 78:return 56;case 79:return this.pushState("text"),65;case 80:return this.popState(),62;case 81:return this.pushState("text"),61;case 82:return this.popState(),47;case 83:return this.pushState("text"),46;case 84:return this.popState(),67;case 85:return this.popState(),69;case 86:return 114;case 87:return this.pushState("trapText"),66;case 88:return this.pushState("trapText"),68;case 89:return 115;case 90:return 65;case 91:return 87;case 92:return"SEP";case 93:return 86;case 97:return 106;case 98:return 111;case 99:return 113;case 100:return this.popState(),60;case 101:return this.pushState("text"),60;case 102:return this.popState(),49;case 103:return this.pushState("text"),48;case 104:return this.popState(),31;case 105:return this.pushState("text"),29;case 106:return this.popState(),64;case 107:return this.pushState("text"),63;case 109:return"QUOTE";case 110:return 9;case 111:return 10;case 112:return 11}},rules:[/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|(?!\)+))/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{callbackargs:{rules:[11,12,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},callbackname:{rules:[8,9,10,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},href:{rules:[15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},click:{rules:[15,18,27,28,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},dottedEdgeText:{rules:[15,18,67,69,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},thickEdgeText:{rules:[15,18,64,66,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},edgeText:{rules:[15,18,61,63,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},trapText:{rules:[15,18,70,73,75,77,81,83,84,85,86,87,88,101,103,105,107],inclusive:!1},ellipseText:{rules:[15,18,70,71,72,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},text:{rules:[15,18,70,73,74,75,76,77,80,81,82,83,87,88,100,101,102,103,104,105,106,107,108],inclusive:!1},vertex:{rules:[15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},dir:{rules:[15,18,38,39,40,41,42,43,44,45,46,47,48,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_descr_multiline:{rules:[5,6,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_descr:{rules:[3,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},acc_title:{rules:[1,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},md_string:{rules:[13,14,15,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},string:{rules:[15,16,17,18,70,73,75,77,81,83,87,88,101,103,105,107],inclusive:!1},INITIAL:{rules:[0,2,4,7,15,18,19,20,21,22,23,24,25,26,29,30,31,32,33,34,35,36,37,49,50,51,52,53,54,55,56,57,58,59,60,61,62,64,65,67,68,70,73,75,77,78,79,81,83,87,88,89,90,91,92,93,94,95,96,97,98,99,101,103,105,107,109,110,111,112],inclusive:!0}}};function Zt(){this.yy={}}return Qt.lexer=qt,Zt.prototype=Qt,Qt.Parser=Zt,new Zt}();n.parser=n;const r=n;let a,c,o=0,l=(0,i.c)(),h={},A=[],d={},p=[],y={},E={},f=0,k=!0,D=[];const g=t=>i.e.sanitizeText(t,l),b=function(t){const e=Object.keys(h);for(const s of e)if(h[s].id===t)return h[s].domId;return t},F=function(t,e,s,u,n,r,a={}){let c,A=t;void 0!==A&&0!==A.trim().length&&(void 0===h[A]&&(h[A]={id:A,labelType:"text",domId:"flowchart-"+A+"-"+o,styles:[],classes:[]}),o++,void 0!==e?(l=(0,i.c)(),c=g(e.text.trim()),h[A].labelType=e.type,'"'===c[0]&&'"'===c[c.length-1]&&(c=c.substring(1,c.length-1)),h[A].text=c):void 0===h[A].text&&(h[A].text=t),void 0!==s&&(h[A].type=s),null!=u&&u.forEach((function(t){h[A].styles.push(t)})),null!=n&&n.forEach((function(t){h[A].classes.push(t)})),void 0!==r&&(h[A].dir=r),void 0===h[A].props?h[A].props=a:void 0!==a&&Object.assign(h[A].props,a))},T=function(t,e,s){const u={start:t,end:e,type:void 0,text:"",labelType:"text"};i.l.info("abc78 Got edge...",u);const n=s.text;if(void 0!==n&&(u.text=g(n.text.trim()),'"'===u.text[0]&&'"'===u.text[u.text.length-1]&&(u.text=u.text.substring(1,u.text.length-1)),u.labelType=n.type),void 0!==s&&(u.type=s.type,u.stroke=s.stroke,u.length=s.length),(null==u?void 0:u.length)>10&&(u.length=10),!(A.length<280))throw new Error("Too many edges");i.l.info("abc78 pushing edge..."),A.push(u)},C=function(t,e,s){let u,n;for(i.l.info("addLink (abc78)",t,e,s),u=0;u<t.length;u++)for(n=0;n<e.length;n++)T(t[u],e[n],s)},_=function(t,e){t.forEach((function(t){"default"===t?A.defaultInterpolate=e:A[t].interpolate=e}))},B=function(t,e){t.forEach((function(t){"default"===t?A.defaultStyle=e:(-1===i.u.isSubstringInArray("fill",e)&&e.push("fill:none"),A[t].style=e)}))},S=function(t,e){t.split(",").forEach((function(t){void 0===d[t]&&(d[t]={id:t,styles:[],textStyles:[]}),null!=e&&e.forEach((function(e){if(e.match("color")){const s=e.replace("fill","bgFill").replace("color","fill");d[t].textStyles.push(s)}d[t].styles.push(e)}))}))},m=function(t){a=t,a.match(/.*</)&&(a="RL"),a.match(/.*\^/)&&(a="BT"),a.match(/.*>/)&&(a="LR"),a.match(/.*v/)&&(a="TB"),"TD"===a&&(a="TB")},x=function(t,e){t.split(",").forEach((function(t){let s=t;void 0!==h[s]&&h[s].classes.push(e),void 0!==y[s]&&y[s].classes.push(e)}))},v=function(t,e,s){t.split(",").forEach((function(t){void 0!==h[t]&&(h[t].link=i.u.formatUrl(e,l),h[t].linkTarget=s)})),x(t,"clickable")},L=function(t){if(E.hasOwnProperty(t))return E[t]},I=function(t,e,s){t.split(",").forEach((function(t){!function(t,e,s){let u=b(t);if("loose"!==(0,i.c)().securityLevel)return;if(void 0===e)return;let n=[];if("string"==typeof s){n=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<n.length;t++){let e=n[t].trim();'"'===e.charAt(0)&&'"'===e.charAt(e.length-1)&&(e=e.substr(1,e.length-2)),n[t]=e}}0===n.length&&n.push(t),void 0!==h[t]&&(h[t].haveCallback=!0,D.push((function(){const t=document.querySelector(`[id="${u}"]`);null!==t&&t.addEventListener("click",(function(){i.u.runFunc(e,...n)}),!1)})))}(t,e,s)})),x(t,"clickable")},R=function(t){D.forEach((function(e){e(t)}))},N=function(){return a.trim()},$=function(){return h},O=function(){return A},P=function(){return d},w=function(t){let e=(0,u.Ys)(".mermaidTooltip");null===(e._groups||e)[0][0]&&(e=(0,u.Ys)("body").append("div").attr("class","mermaidTooltip").style("opacity",0));(0,u.Ys)(t).select("svg").selectAll("g.node").on("mouseover",(function(){const t=(0,u.Ys)(this);if(null===t.attr("title"))return;const s=this.getBoundingClientRect();e.transition().duration(200).style("opacity",".9"),e.text(t.attr("title")).style("left",window.scrollX+s.left+(s.right-s.left)/2+"px").style("top",window.scrollY+s.top-14+document.body.scrollTop+"px"),e.html(e.html().replace(/<br\/>/g,"<br/>")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);(0,u.Ys)(this).classed("hover",!1)}))};D.push(w);const U=function(t="gen-1"){h={},d={},A=[],D=[w],p=[],y={},f=0,E={},k=!0,c=t,(0,i.t)()},V=t=>{c=t||"gen-2"},G=function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},M=function(t,e,s){let u=t.text.trim(),n=s.text;t===s&&s.text.match(/\s/)&&(u=void 0);let r=[];const{nodeList:a,dir:o}=function(t){const e={boolean:{},number:{},string:{}},s=[];let u;return{nodeList:t.filter((function(t){const i=typeof t;return t.stmt&&"dir"===t.stmt?(u=t.value,!1):""!==t.trim()&&(i in e?!e[i].hasOwnProperty(t)&&(e[i][t]=!0):!s.includes(t)&&s.push(t))})),dir:u}}(r.concat.apply(r,e));if(r=a,"gen-1"===c)for(let i=0;i<r.length;i++)r[i]=b(r[i]);u=u||"subGraph"+f,n=n||"",n=g(n),f+=1;const l={id:u,nodes:r,title:n.trim(),classes:[],dir:o,labelType:s.type};return i.l.info("Adding",l.id,l.nodes,l.dir),l.nodes=J(l,p).nodes,p.push(l),y[u]=l,u},Y=function(t){for(const[e,s]of p.entries())if(s.id===t)return e;return-1};let K=-1;const j=[],X=function(t,e){const s=p[e].nodes;if(K+=1,K>2e3)return;if(j[K]=e,p[e].id===t)return{result:!0,count:0};let u=0,i=1;for(;u<s.length;){const e=Y(s[u]);if(e>=0){const s=X(t,e);if(s.result)return{result:!0,count:i+s.count};i+=s.count}u+=1}return{result:!1,count:i}},z=function(t){return j[t]},H=function(){K=-1,p.length>0&&X("none",p.length-1)},W=function(){return p},Q=()=>!!k&&(k=!1,!0),q=(t,e)=>{const s=(t=>{const e=t.trim();let s=e.slice(0,-1),u="arrow_open";switch(e.slice(-1)){case"x":u="arrow_cross","x"===e[0]&&(u="double_"+u,s=s.slice(1));break;case">":u="arrow_point","<"===e[0]&&(u="double_"+u,s=s.slice(1));break;case"o":u="arrow_circle","o"===e[0]&&(u="double_"+u,s=s.slice(1))}let i="normal",n=s.length-1;"="===s[0]&&(i="thick"),"~"===s[0]&&(i="invisible");let r=((t,e)=>{const s=e.length;let u=0;for(let i=0;i<s;++i)e[i]===t&&++u;return u})(".",s);return r&&(i="dotted",n=r),{type:u,stroke:i,length:n}})(t);let u;if(e){if(u=(t=>{let e=t.trim(),s="arrow_open";switch(e[0]){case"<":s="arrow_point",e=e.slice(1);break;case"x":s="arrow_cross",e=e.slice(1);break;case"o":s="arrow_circle",e=e.slice(1)}let u="normal";return e.includes("=")&&(u="thick"),e.includes(".")&&(u="dotted"),{type:s,stroke:u}})(e),u.stroke!==s.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===u.type)u.type=s.type;else{if(u.type!==s.type)return{type:"INVALID",stroke:"INVALID"};u.type="double_"+u.type}return"double_arrow"===u.type&&(u.type="double_arrow_point"),u.length=s.length,u}return s},Z=(t,e)=>{let s=!1;return t.forEach((t=>{t.nodes.indexOf(e)>=0&&(s=!0)})),s},J=(t,e)=>{const s=[];return t.nodes.forEach(((u,i)=>{Z(e,u)||s.push(t.nodes[i])})),{nodes:s}},tt={firstGraph:Q},et={defaultConfig:()=>i.I.flowchart,setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,addVertex:F,lookUpDomId:b,addLink:C,updateLinkInterpolate:_,updateLink:B,addClass:S,setDirection:m,setClass:x,setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(E["gen-1"===c?b(t):t]=g(e))}))},getTooltip:L,setClickEvent:I,setLink:v,bindFunctions:R,getDirection:N,getVertices:$,getEdges:O,getClasses:P,clear:U,setGen:V,defaultStyle:G,addSubGraph:M,getDepthFirstPos:z,indexNodes:H,getSubGraphs:W,destructLink:q,lex:tt,exists:Z,makeUniq:J,setDiagramTitle:i.q,getDiagramTitle:i.r},st=Object.freeze(Object.defineProperty({__proto__:null,addClass:S,addLink:C,addSingleLink:T,addSubGraph:M,addVertex:F,bindFunctions:R,clear:U,default:et,defaultStyle:G,destructLink:q,firstGraph:Q,getClasses:P,getDepthFirstPos:z,getDirection:N,getEdges:O,getSubGraphs:W,getTooltip:L,getVertices:$,indexNodes:H,lex:tt,lookUpDomId:b,setClass:x,setClickEvent:I,setDirection:m,setGen:V,setLink:v,updateLink:B,updateLinkInterpolate:_},Symbol.toStringTag,{value:"Module"}))}}]); \ No newline at end of file diff --git a/assets/js/530ffa4f.2cf34794.js b/assets/js/530ffa4f.2cf34794.js new file mode 100644 index 000000000..5bdf89a11 --- /dev/null +++ b/assets/js/530ffa4f.2cf34794.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4818],{17804:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>a});var n=t(85893),s=t(3905);const i={title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",slug:"refactoring-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,o={permalink:"/refactoring-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-refactoring/pull/465",date:"2023-10-31T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 31\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:8.095,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",slug:"refactoring-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,nextItem:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/jdbc-retrospective"}},l={authorsImageUrls:[]},a=[{value:"\ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158",id:"\ub9ac\ud329\ud130\ub9c1-\ubbf8\uc158",level:3},{value:"1, 2\ub2e8\uacc4",id:"1-2\ub2e8\uacc4",level:3},{value:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c",id:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758-\ubcf5\uc7a1\uc131\uc744-\ub2e4\ub8e8\ub294-\uc9c0\ud61c",level:3},{value:"3, 4\ub2e8\uacc4",id:"3-4\ub2e8\uacc4",level:3},{value:"\ub9c8\ubb34\ub9ac",id:"\ub9c8\ubb34\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const r={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",mermaid:"mermaid",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,n.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-refactoring/pull/465",children:"https://github.com/woowacourse/jwp-refactoring/pull/465"}),(0,n.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-refactoring/pull/547",children:"https://github.com/woowacourse/jwp-refactoring/pull/547"}),(0,n.jsx)(r.br,{}),"\n","3\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-refactoring/pull/610",children:"https://github.com/woowacourse/jwp-refactoring/pull/610"}),(0,n.jsx)(r.br,{}),"\n","4\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-refactoring/pull/721",children:"https://github.com/woowacourse/jwp-refactoring/pull/721"})]})}),"\n",(0,n.jsx)(r.h3,{id:"\ub9ac\ud329\ud130\ub9c1-\ubbf8\uc158",children:"\ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158"}),"\n",(0,n.jsxs)(r.p,{children:["\uc694\uad6c\uc0ac\ud56d \uc791\uc131 \u2192 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud55c \ucf54\ub4dc \ubcf4\ud638 \u2192 \ub9ac\ud329\ud130\ub9c1 \u2192 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1 \u2192 \uba40\ud2f0\ubaa8\ub4c8 \uc21c\uc11c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc5d0 \uc628\uc804\ud788 \uc9d1\uc911\ud558\uace0 \uc2f6\uc5c8\uc9c0\ub9cc, \ud504\ub85c\uc81d\ud2b8\uc640 \ubcd1\ud589\ud558\uba74\uc11c \uc9c4\ud589\ud588\uae30\uc5d0 \uc5b4\ub290\uc815\ub3c4 \ud0c0\ud611\ubcf4\uace0 \uc9c4\ud589\ud55c \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c \uc544\uc26c\uc6e0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"1-2\ub2e8\uacc4",children:"1, 2\ub2e8\uacc4"}),"\n",(0,n.jsx)(r.p,{children:"1\ub2e8\uacc4\ub294 \uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud558\uace0, \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ucd94\ud6c4\uc5d0 \ub9ac\ud329\ud130\ub9c1 \ud560 \ub54c \uc548\uc815\uac10 \uc788\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\ub3c4\ub85d \uc900\ube44\ud558\ub294 \uacfc\uc815\uc774\uc5c8\ub2e4.\n\uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud560 \ub54c \uc81c\uacf5\ub41c \uc6a9\uc5b4 \uc0ac\uc804\uc744 \ucd5c\ub300\ud55c \ud65c\uc6a9\ud558\uba74\uc11c \uae30\uc874\uc758 \ucf54\ub4dc\ub97c \ubcf4\uba74\uc11c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud588\ub2e4.\n\ud14c\uc2a4\ud2b8\ub294 \uc2dc\uac04 \uad00\uacc4\uc0c1 API, \uc11c\ube44\uc2a4 \ub458 \uc911 \ud558\ub098\ub9cc \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4."}),"\n",(0,n.jsxs)(r.p,{children:["\ucd5c\uc885\uc801\uc73c\ub85c \uc11c\ube44\uc2a4 \uae30\uc900\uc73c\ub85c \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud588\ub294\ub370 \uc57d\uac04 \ud6c4\ud68c\ub418\ub294 \uacb0\uc815\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub9ac\ud329\ud130\ub9c1 \uacfc\uc815\uc5d0\uc11c API \uba85\uc138\uac00 \ubc14\ub00c\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4\ub294 \uac83\uc744 \uae30\uc900\uc744 \uc7a1\uace0 \uc774\ubc88 \ubbf8\uc158\uc744 \ud55c\ub2e4\uace0 \uac00\uc815\ud588\uc744 \ub54c API \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\uace0, \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ub354 \uc548\uc815\uac10 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["2\ub2e8\uacc4\ub294 \uc791\uc131\ub41c \ud14c\uc2a4\ud2b8 \uae30\ubc18\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc11c\ube44\uc2a4\uc5d0\uc11c \ub3c4\uba54\uc778\uc744 \uc9c1\uc811 \ubc18\ud658\ud558\ub294 \uad6c\uc870\uc600\ub294\ub370, \ub3c4\uba54\uc778\uc5d0 JPA\ub97c \uc801\uc6a9\ud558\uba74 \uae30\uc874 \uba85\uc138\uc640 \ub2ec\ub77c\uc9c8 \uac83\uc744 \uc6b0\ub824\ud574\uc11c DTO\ub85c \uc218\uc815\ud558\ub294 \uc791\uc5c5\uc744 \uba3c\uc800 \uc9c4\ud589\ud588\ub2e4.\nDTO \uc774\ud6c4\uc5d0 \uc11c\ube44\uc2a4\uc5d0 \uc788\ub294 \ub85c\uc9c1\uc744 \ub3c4\uba54\uc778\uc73c\ub85c \uc774\ub3d9\uc2dc\ud0a4\uace0, \ucd5c\uc885\uc801\uc73c\ub85c JPA\ub97c \uc801\uc6a9\ud558\ub294 \uc21c\uc11c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud588\ub2e4.\n\uc774 \uacfc\uc815\uc5d0\uc11c \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \uc591\ubc29\ud5a5\uc778 \ubd80\ubd84\ub3c4 \uc0dd\uaca8\ub0ac\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758-\ubcf5\uc7a1\uc131\uc744-\ub2e4\ub8e8\ub294-\uc9c0\ud61c",children:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c"}),"\n",(0,n.jsxs)(r.p,{children:["\uc911\uac04\uc5d0 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\uc5d0 \uad00\ud55c \uc81c\uc774\uc2a8\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\ub294 \uc5d0\ub9ad \uc5d0\ubc18\uc2a4\uc758 \uc800\uc11c ",(0,n.jsx)(r.code,{children:"\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4"}),"\uc758 \ubd80\uc81c\uc774\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\ub294 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4, \uc804\uc220\uc801 \uc124\uacc4\uac00 \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4\uac00 \uc804\uccb4\uc758 90%\uc5d0 \ud574\ub2f9\ud560 \uc815\ub3c4\ub85c \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4. \ub610\ud55c \uc804\uc220\uc801 \uc124\uacc4\ub9cc \ud558\ub294 \uacbd\uc6b0\ub97c DDD Lite \ub77c\uace0 \ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:"\uac04\ub2e8\ud788 \ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\uc5d0\uc11c \ub098\uc624\ub294 \ub2e8\uc5b4\ub97c \uc815\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,n.jsxs)(r.table,{children:[(0,n.jsx)(r.thead,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.th,{children:"\ub2e8\uc5b4"}),(0,n.jsx)(r.th,{children:"\uc124\uba85"})]})}),(0,n.jsxs)(r.tbody,{children:[(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\ub3c4\uba54\uc778"}),(0,n.jsx)(r.td,{children:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\ub85c \ud574\uacb0\ud558\uace0\uc790 \ud558\ub294 \ubb38\uc81c \uc601\uc5ed"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8"}),(0,n.jsx)(r.td,{children:"\ud574\uacb0 \uc601\uc5ed, \uad00\uc2ec\uc0ac\ub97c \ubd84\ub9ac\ud558\uace0 \uaca9\ub9ac\ud558\uc5ec \ubb38\uc81c \ud574\uacb0\uc5d0 \uc9d1\uc911\ud560 \ubc94\uc704"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4"}),(0,n.jsx)(r.td,{children:"\ud504\ub85c\uc81d\ud2b8\uc5d0 \uc774\ud574\uad00\uacc4\uc790\ub4e4\uc758 \uacf5\ud1b5\ub41c \uc5b8\uc5b4\ub85c, \uc11c\ub85c\uc758 \uc758\uc0ac\uc18c\ud1b5 \ube44\uc6a9\uc744 \uc904\uc774\uae30 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 \uc5b8\uc5b4"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\uc804\ub7b5\uc801 \uc124\uacc4"}),(0,n.jsx)(r.td,{children:"\ub3c4\uba54\uc778 \uc804\ubb38\uac00\uc640 \uac1c\ubc1c\uc790\uac00 \ud568\uaed8 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec \ub3c4\uba54\uc778\uacfc \uad00\ub828\ub41c \uc9c0\uc2dd\uc744 \uc774\ud574\ud558\uace0 \uc774\ub97c \ubc14\ud0d5\uc73c\ub85c \uacbd\uacc4\ub97c \ub098\ub220 \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc815\uc758\ud558\uace0, \ucee8\ud14d\uc2a4\ud2b8 \ub9f5\uc744 \uc0dd\uc131\ud558\ub294 \uac83\uc744 \ud3ec\ud568\ud558\ub294 \uacfc\uc815"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:"\uc804\uc220\uc801 \uc124\uacc4"}),(0,n.jsx)(r.td,{children:"\uc804\ub7b5\uc801 \uc124\uacc4\uc5d0\uc11c \uc815\uc758\ud55c \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\uc640 \ub3c4\uba54\uc778\uc744 \uc774\uc6a9\ud558\uc5ec \uc560\uadf8\ub9ac\uac70\ud2b8, Entity\uc640 VO, Repository \ub4f1\uc744 \uad6c\ud604\ud558\ub294 \uacfc\uc815"})]})]})]}),"\n",(0,n.jsx)(r.p,{children:"\uc774 \uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ub0b4\uc6a9\ub4e4\uc774 \ub098\uc654\uc9c0\ub9cc, \uc9c0\uc2dd\uc744 \uc81c\ub300\ub85c \ud761\uc218\ud558\uc9c0\ub294 \ubabb\ud588\ub2e4."}),"\n",(0,n.jsx)(r.h3,{id:"3-4\ub2e8\uacc4",children:"3, 4\ub2e8\uacc4"}),"\n",(0,n.jsx)(r.p,{children:"\uc81c\uc774\uc2a8\uc758 \uac15\uc758\ub97c \ub4e3\uace0, \uc870\uc601\ud638\ub2d8\uc758 \uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5 \uc720\ud29c\ube0c \uc601\uc0c1\uc744 \ubcf8 \ub2e4\uc74c 3, 4\ub2e8\uacc4\ub97c \uc9c4\ud589\ud588\ub2e4."}),"\n",(0,n.jsx)(r.p,{children:"3\ub2e8\uacc4\ub294 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1\uc5d0 \uad00\ud55c \ub0b4\uc6a9\uc774\uc5c8\ub2e4. \ud074\ub798\uc2a4 \uac04 \ubc29\ud5a5, \ud328\ud0a4\uc9c0 \uac04 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc774 \ub418\ub3c4\ub85d \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud574\uc57c \ud588\uc5c8\ub2e4.\n\ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4\ub4e4\uc744 \ubb36\uace0, \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uae30 \uc704\ud574 \uc0dd\uba85\uc8fc\uae30\uac00 \ub2e4\ub974\ub2e4\uba74 id\ub97c \uc774\uc6a9\ud558\uc5ec \ucc38\uc870\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4."}),"\n",(0,n.jsx)(r.p,{children:"\uc758\uc874\uc131\uc744 \ubd84\ub9ac\ud558\uae30 \uc704\ud574 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. \uc774\ubca4\ud2b8\ub294 \ud604\uc7ac \uae30\uc900\uc73c\ub85c \uacfc\uac70\uc5d0 \ubc8c\uc5b4\uc9c4 \uac83\uc744 \ud45c\ud604\ud558\uae30 \ub54c\ubb38\uc5d0 \uc774\ubca4\ud2b8\uba85\uc740 \uacfc\uac70 \uc2dc\uc81c\uac00 \ub418\uc5b4\uc57c\ud558\ub294 \uac83\uc744 \uc54c\uc558\ub2e4.\n\ucc98\uc74c\uc5d0\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud588\uc9c0\ub9cc, \uc11c\ube44\uc2a4 \ub85c\uc9c1\uc744 \ucd5c\ub300\ud55c \uac04\ub2e8\ud558\uac8c \ud558\uae30 \uc704\ud574 \ub3c4\uba54\uc778 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4."}),"\n",(0,n.jsxs)(r.p,{children:["4\ub2e8\uacc4\ub294 \uba40\ud2f0\ubaa8\ub4c8\ub85c \ubd84\ub9ac\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub294\ub370 3\ub2e8\uacc4\uc5d0\uc11c \ubd84\ub9ac\ud574\ub454 \ud328\ud0a4\uc9c0 \uadf8\ub300\ub85c \ubd84\ub9ac\ud558\uc9c0\ub294 \uc54a\uc558\ub2e4.",(0,n.jsx)(r.br,{}),"\n","3\ub2e8\uacc4\uc5d0\uc11c\ub294 \ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4 \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ud588\ub2e4. 4\ub2e8\uacc4\uc5d0\uc11c\ub294 \ub0b4\uac00 \uc778\uc2dd\ud558\uae30 \ud3b8\ud55c \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ub97c \ud588\ub2e4.\n\uc544\uc9c1 \ubd84\ub9ac\ud55c \uae30\uc900\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \ubaa8\ud638\ud588\uace0, \uc774\uc5d0 \ub300\ud55c \uacf5\ubd80\ub97c \uc870\uae08 \ub354 \ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,n.jsx)(r.mermaid,{value:"graph LR\n\tsubgraph Table\n\t\tOrderTable --\x3e TableGroup\n\tend\n\tsubgraph Order\n\t\tO\n\tend\n O[Order] --\x3e OrderTable\n\tsubgraph Menu\n\t\tM[Menu] --\x3e MenuGroup\n\t\tM --\x3e Product\n\tend\n\tO --\x3e M"}),"\n",(0,n.jsxs)(r.p,{children:["\ucd94\uac00\ub85c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc704\ud55c \uc9c1\uc811 \uc791\uc131\ud55c ",(0,n.jsx)(r.code,{children:"@ServiceTest"})," \ucee4\uc2a4\ud140 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc788\uc5c8\ub294\ub370, \uc0c1\uc704 \ubaa8\ub4c8\uc758 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \ub9cc\ub4e0 \ud074\ub798\uc2a4\ub97c \ud558\uc704 \ubaa8\ub4c8\uc5d0\uc11c\ub294 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4.\n\ub530\ub77c\uc11c TestFixtures\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\uacb0\ud588\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ub9c8\ubb34\ub9ac",children:"\ub9c8\ubb34\ub9ac"}),"\n",(0,n.jsxs)(r.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc758 \ub9c8\uc9c0\ub9c9 \ubbf8\uc158\uc774\ub2c8 \ub9cc\ud07c, \uac00\uc7a5 \ud765\ubbf8\ub85c\uc6b4 \ubbf8\uc158\uc774\uc5c8\uace0 \ubc30\uc6b8\uc810\ub3c4 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubc14\uc05c \uae30\uac04\uc774\ub77c \ub9ce\uc740 \ub9ac\ubdf0\ub97c \ub0a8\uae30\uc9c0 \ubabb\ud588\ub358 \ub9ac\ubdf0\uc774 \ud638\uc774\uc5d0\uac8c \ubbf8\uc548\ud558\uace0, \ucf54\uba58\ud2b8 \uaf3c\uaf3c\ud558\uac8c \ub2ec\uc544\uc8fc\uace0 \ubbf8\uc158\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub3c4 \uc624\ud504\ub77c\uc778\uc73c\ub85c \ub9ce\uc774 \ub098\ub208 \ub9ac\ubdf0\uc5b4 \ud14c\uc624\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsxs)(r.p,{children:[(0,n.jsx)(r.a,{href:"https://www.youtube.com/watch?v=kmUneexSxk0",children:"\ub3c4\uba54\uc778 \uc6d0\uc815\ub300, \uc6b0\uc544\ucf58 2021"}),(0,n.jsx)(r.br,{}),"\n",(0,n.jsx)(r.a,{href:"https://www.youtube.com/watch?v=dJ5C4qRqAgA",children:"\uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5, \uc6b0\uc544\ud55c\ud14c\ud06c\uc138\ubbf8\ub098"}),(0,n.jsx)(r.br,{}),"\n",(0,n.jsx)(r.a,{href:"https://kwonnam.pe.kr/wiki/gradle/testfixtures",children:"TestFixtures, \uad8c\ub0a8\ub2d8"})]})]})}function h(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>a});var n=t(67294);function s(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function c(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){s(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function o(e,r){if(null==e)return{};var t,n,s=function(e,r){if(null==e)return{};var t,n,s={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(s[t]=e[t]);return s}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var l=n.createContext({}),a=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},d={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},h=n.forwardRef((function(e,r){var t=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,h=o(e,["components","mdxType","originalType","parentName"]),p=a(t),u=s,j=p["".concat(l,".").concat(u)]||p[u]||d[u]||i;return t?n.createElement(j,c(c({ref:r},h),{},{components:t})):n.createElement(j,c({ref:r},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/530ffa4f.8ee384a9.js b/assets/js/530ffa4f.8ee384a9.js deleted file mode 100644 index 69c507edc..000000000 --- a/assets/js/530ffa4f.8ee384a9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4818],{3905:(t,e,r)=>{r.d(e,{Zo:()=>c,kt:()=>k});var n=r(67294);function a(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function l(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function p(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?l(Object(r),!0).forEach((function(e){a(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}function o(t,e){if(null==t)return{};var r,n,a=function(t,e){if(null==t)return{};var r,n,a={},l=Object.keys(t);for(n=0;n<l.length;n++)r=l[n],e.indexOf(r)>=0||(a[r]=t[r]);return a}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)r=l[n],e.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(a[r]=t[r])}return a}var i=n.createContext({}),u=function(t){var e=n.useContext(i),r=e;return t&&(r="function"==typeof t?t(e):p(p({},e),t)),r},c=function(t){var e=u(t.components);return n.createElement(i.Provider,{value:e},t.children)},m={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},s=n.forwardRef((function(t,e){var r=t.components,a=t.mdxType,l=t.originalType,i=t.parentName,c=o(t,["components","mdxType","originalType","parentName"]),s=u(r),k=a,d=s["".concat(i,".").concat(k)]||s[k]||m[k]||l;return r?n.createElement(d,p(p({ref:e},c),{},{components:r})):n.createElement(d,p({ref:e},c))}));function k(t,e){var r=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var l=r.length,p=new Array(l);p[0]=s;var o={};for(var i in e)hasOwnProperty.call(e,i)&&(o[i]=e[i]);o.originalType=t,o.mdxType="string"==typeof t?t:a,p[1]=o;for(var u=2;u<l;u++)p[u]=r[u];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}s.displayName="MDXCreateElement"},17105:(t,e,r)=>{r.r(e),r.d(e,{assets:()=>i,contentTitle:()=>p,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const l={title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",slug:"refactoring-retrospective",tags:["Woowahan Techcourse","Retrospective"]},p=void 0,o={permalink:"/refactoring-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-refactoring/pull/465",date:"2023-10-31T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 31\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:8.055,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",slug:"refactoring-retrospective",tags:["Woowahan Techcourse","Retrospective"]},nextItem:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/jdbc-retrospective"}},i={authorsImageUrls:[]},u=[{value:"\ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158",id:"\ub9ac\ud329\ud130\ub9c1-\ubbf8\uc158",level:3},{value:"1, 2\ub2e8\uacc4",id:"1-2\ub2e8\uacc4",level:3},{value:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c",id:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758-\ubcf5\uc7a1\uc131\uc744-\ub2e4\ub8e8\ub294-\uc9c0\ud61c",level:3},{value:"3, 4\ub2e8\uacc4",id:"3-4\ub2e8\uacc4",level:3},{value:"\ub9c8\ubb34\ub9ac",id:"\ub9c8\ubb34\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:u};function m(t){let{components:e,...r}=t;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-refactoring/pull/465"},"https://github.com/woowacourse/jwp-refactoring/pull/465"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-refactoring/pull/547"},"https://github.com/woowacourse/jwp-refactoring/pull/547"),(0,a.kt)("br",{parentName:"p"}),"\n","3\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-refactoring/pull/610"},"https://github.com/woowacourse/jwp-refactoring/pull/610"),(0,a.kt)("br",{parentName:"p"}),"\n","4\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-refactoring/pull/721"},"https://github.com/woowacourse/jwp-refactoring/pull/721")," ")),(0,a.kt)("h3",{id:"\ub9ac\ud329\ud130\ub9c1-\ubbf8\uc158"},"\ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158"),(0,a.kt)("p",null,"\uc694\uad6c\uc0ac\ud56d \uc791\uc131 \u2192 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud55c \ucf54\ub4dc \ubcf4\ud638 \u2192 \ub9ac\ud329\ud130\ub9c1 \u2192 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1 \u2192 \uba40\ud2f0\ubaa8\ub4c8 \uc21c\uc11c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc5d0 \uc628\uc804\ud788 \uc9d1\uc911\ud558\uace0 \uc2f6\uc5c8\uc9c0\ub9cc, \ud504\ub85c\uc81d\ud2b8\uc640 \ubcd1\ud589\ud558\uba74\uc11c \uc9c4\ud589\ud588\uae30\uc5d0 \uc5b4\ub290\uc815\ub3c4 \ud0c0\ud611\ubcf4\uace0 \uc9c4\ud589\ud55c \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c \uc544\uc26c\uc6e0\ub2e4. "),(0,a.kt)("h3",{id:"1-2\ub2e8\uacc4"},"1, 2\ub2e8\uacc4"),(0,a.kt)("p",null,"1\ub2e8\uacc4\ub294 \uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud558\uace0, \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ucd94\ud6c4\uc5d0 \ub9ac\ud329\ud130\ub9c1 \ud560 \ub54c \uc548\uc815\uac10 \uc788\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\ub3c4\ub85d \uc900\ube44\ud558\ub294 \uacfc\uc815\uc774\uc5c8\ub2e4.\n\uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud560 \ub54c \uc81c\uacf5\ub41c \uc6a9\uc5b4 \uc0ac\uc804\uc744 \ucd5c\ub300\ud55c \ud65c\uc6a9\ud558\uba74\uc11c \uae30\uc874\uc758 \ucf54\ub4dc\ub97c \ubcf4\uba74\uc11c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud588\ub2e4.\n\ud14c\uc2a4\ud2b8\ub294 \uc2dc\uac04 \uad00\uacc4\uc0c1 API, \uc11c\ube44\uc2a4 \ub458 \uc911 \ud558\ub098\ub9cc \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ucd5c\uc885\uc801\uc73c\ub85c \uc11c\ube44\uc2a4 \uae30\uc900\uc73c\ub85c \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud588\ub294\ub370 \uc57d\uac04 \ud6c4\ud68c\ub418\ub294 \uacb0\uc815\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ud329\ud130\ub9c1 \uacfc\uc815\uc5d0\uc11c API \uba85\uc138\uac00 \ubc14\ub00c\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4\ub294 \uac83\uc744 \uae30\uc900\uc744 \uc7a1\uace0 \uc774\ubc88 \ubbf8\uc158\uc744 \ud55c\ub2e4\uace0 \uac00\uc815\ud588\uc744 \ub54c API \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\uace0, \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ub354 \uc548\uc815\uac10 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,a.kt)("p",null,"2\ub2e8\uacc4\ub294 \uc791\uc131\ub41c \ud14c\uc2a4\ud2b8 \uae30\ubc18\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc11c\ube44\uc2a4\uc5d0\uc11c \ub3c4\uba54\uc778\uc744 \uc9c1\uc811 \ubc18\ud658\ud558\ub294 \uad6c\uc870\uc600\ub294\ub370, \ub3c4\uba54\uc778\uc5d0 JPA\ub97c \uc801\uc6a9\ud558\uba74 \uae30\uc874 \uba85\uc138\uc640 \ub2ec\ub77c\uc9c8 \uac83\uc744 \uc6b0\ub824\ud574\uc11c DTO\ub85c \uc218\uc815\ud558\ub294 \uc791\uc5c5\uc744 \uba3c\uc800 \uc9c4\ud589\ud588\ub2e4.\nDTO \uc774\ud6c4\uc5d0 \uc11c\ube44\uc2a4\uc5d0 \uc788\ub294 \ub85c\uc9c1\uc744 \ub3c4\uba54\uc778\uc73c\ub85c \uc774\ub3d9\uc2dc\ud0a4\uace0, \ucd5c\uc885\uc801\uc73c\ub85c JPA\ub97c \uc801\uc6a9\ud558\ub294 \uc21c\uc11c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud588\ub2e4.\n\uc774 \uacfc\uc815\uc5d0\uc11c \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \uc591\ubc29\ud5a5\uc778 \ubd80\ubd84\ub3c4 \uc0dd\uaca8\ub0ac\ub2e4. "),(0,a.kt)("h3",{id:"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758-\ubcf5\uc7a1\uc131\uc744-\ub2e4\ub8e8\ub294-\uc9c0\ud61c"},"\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c"),(0,a.kt)("p",null,"\uc911\uac04\uc5d0 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\uc5d0 \uad00\ud55c \uc81c\uc774\uc2a8\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\ub294 \uc5d0\ub9ad \uc5d0\ubc18\uc2a4\uc758 \uc800\uc11c ",(0,a.kt)("inlineCode",{parentName:"p"},"\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4"),"\uc758 \ubd80\uc81c\uc774\ub2e4. "),(0,a.kt)("p",null,"\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\ub294 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4, \uc804\uc220\uc801 \uc124\uacc4\uac00 \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4\uac00 \uc804\uccb4\uc758 90%\uc5d0 \ud574\ub2f9\ud560 \uc815\ub3c4\ub85c \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4. \ub610\ud55c \uc804\uc220\uc801 \uc124\uacc4\ub9cc \ud558\ub294 \uacbd\uc6b0\ub97c DDD Lite \ub77c\uace0 \ud55c\ub2e4. "),(0,a.kt)("p",null,"\uac04\ub2e8\ud788 \ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\uc5d0\uc11c \ub098\uc624\ub294 \ub2e8\uc5b4\ub97c \uc815\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"\ub2e8\uc5b4"),(0,a.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ub3c4\uba54\uc778"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc18c\ud504\ud2b8\uc6e8\uc5b4\ub85c \ud574\uacb0\ud558\uace0\uc790 \ud558\ub294 \ubb38\uc81c \uc601\uc5ed")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud574\uacb0 \uc601\uc5ed, \uad00\uc2ec\uc0ac\ub97c \ubd84\ub9ac\ud558\uace0 \uaca9\ub9ac\ud558\uc5ec \ubb38\uc81c \ud574\uacb0\uc5d0 \uc9d1\uc911\ud560 \ubc94\uc704")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4"),(0,a.kt)("td",{parentName:"tr",align:null},"\ud504\ub85c\uc81d\ud2b8\uc5d0 \uc774\ud574\uad00\uacc4\uc790\ub4e4\uc758 \uacf5\ud1b5\ub41c \uc5b8\uc5b4\ub85c, \uc11c\ub85c\uc758 \uc758\uc0ac\uc18c\ud1b5 \ube44\uc6a9\uc744 \uc904\uc774\uae30 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 \uc5b8\uc5b4")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc804\ub7b5\uc801 \uc124\uacc4"),(0,a.kt)("td",{parentName:"tr",align:null},"\ub3c4\uba54\uc778 \uc804\ubb38\uac00\uc640 \uac1c\ubc1c\uc790\uac00 \ud568\uaed8 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec \ub3c4\uba54\uc778\uacfc \uad00\ub828\ub41c \uc9c0\uc2dd\uc744 \uc774\ud574\ud558\uace0 \uc774\ub97c \ubc14\ud0d5\uc73c\ub85c \uacbd\uacc4\ub97c \ub098\ub220 \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc815\uc758\ud558\uace0, \ucee8\ud14d\uc2a4\ud2b8 \ub9f5\uc744 \uc0dd\uc131\ud558\ub294 \uac83\uc744 \ud3ec\ud568\ud558\ub294 \uacfc\uc815")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc804\uc220\uc801 \uc124\uacc4"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc804\ub7b5\uc801 \uc124\uacc4\uc5d0\uc11c \uc815\uc758\ud55c \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\uc640 \ub3c4\uba54\uc778\uc744 \uc774\uc6a9\ud558\uc5ec \uc560\uadf8\ub9ac\uac70\ud2b8, Entity\uc640 VO, Repository \ub4f1\uc744 \uad6c\ud604\ud558\ub294 \uacfc\uc815")))),(0,a.kt)("p",null,"\uc774 \uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ub0b4\uc6a9\ub4e4\uc774 \ub098\uc654\uc9c0\ub9cc, \uc9c0\uc2dd\uc744 \uc81c\ub300\ub85c \ud761\uc218\ud558\uc9c0\ub294 \ubabb\ud588\ub2e4. "),(0,a.kt)("h3",{id:"3-4\ub2e8\uacc4"},"3, 4\ub2e8\uacc4"),(0,a.kt)("p",null,"\uc81c\uc774\uc2a8\uc758 \uac15\uc758\ub97c \ub4e3\uace0, \uc870\uc601\ud638\ub2d8\uc758 \uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5 \uc720\ud29c\ube0c \uc601\uc0c1\uc744 \ubcf8 \ub2e4\uc74c 3, 4\ub2e8\uacc4\ub97c \uc9c4\ud589\ud588\ub2e4. "),(0,a.kt)("p",null,"3\ub2e8\uacc4\ub294 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1\uc5d0 \uad00\ud55c \ub0b4\uc6a9\uc774\uc5c8\ub2e4. \ud074\ub798\uc2a4 \uac04 \ubc29\ud5a5, \ud328\ud0a4\uc9c0 \uac04 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc774 \ub418\ub3c4\ub85d \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud574\uc57c \ud588\uc5c8\ub2e4.\n\ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4\ub4e4\uc744 \ubb36\uace0, \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uae30 \uc704\ud574 \uc0dd\uba85\uc8fc\uae30\uac00 \ub2e4\ub974\ub2e4\uba74 id\ub97c \uc774\uc6a9\ud558\uc5ec \ucc38\uc870\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4. "),(0,a.kt)("p",null,"\uc758\uc874\uc131\uc744 \ubd84\ub9ac\ud558\uae30 \uc704\ud574 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. \uc774\ubca4\ud2b8\ub294 \ud604\uc7ac \uae30\uc900\uc73c\ub85c \uacfc\uac70\uc5d0 \ubc8c\uc5b4\uc9c4 \uac83\uc744 \ud45c\ud604\ud558\uae30 \ub54c\ubb38\uc5d0 \uc774\ubca4\ud2b8\uba85\uc740 \uacfc\uac70 \uc2dc\uc81c\uac00 \ub418\uc5b4\uc57c\ud558\ub294 \uac83\uc744 \uc54c\uc558\ub2e4.\n\ucc98\uc74c\uc5d0\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud588\uc9c0\ub9cc, \uc11c\ube44\uc2a4 \ub85c\uc9c1\uc744 \ucd5c\ub300\ud55c \uac04\ub2e8\ud558\uac8c \ud558\uae30 \uc704\ud574 \ub3c4\uba54\uc778 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. "),(0,a.kt)("p",null,"4\ub2e8\uacc4\ub294 \uba40\ud2f0\ubaa8\ub4c8\ub85c \ubd84\ub9ac\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub294\ub370 3\ub2e8\uacc4\uc5d0\uc11c \ubd84\ub9ac\ud574\ub454 \ud328\ud0a4\uc9c0 \uadf8\ub300\ub85c \ubd84\ub9ac\ud558\uc9c0\ub294 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","3\ub2e8\uacc4\uc5d0\uc11c\ub294 \ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4 \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ud588\ub2e4. 4\ub2e8\uacc4\uc5d0\uc11c\ub294 \ub0b4\uac00 \uc778\uc2dd\ud558\uae30 \ud3b8\ud55c \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ub97c \ud588\ub2e4.\n\uc544\uc9c1 \ubd84\ub9ac\ud55c \uae30\uc900\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \ubaa8\ud638\ud588\uace0, \uc774\uc5d0 \ub300\ud55c \uacf5\ubd80\ub97c \uc870\uae08 \ub354 \ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("mermaid",{value:"graph LR\n\tsubgraph Table\n\t\tOrderTable --\x3e TableGroup\n\tend\n\tsubgraph Order\n\t\tO\n\tend\n O[Order] --\x3e OrderTable\n\tsubgraph Menu\n\t\tM[Menu] --\x3e MenuGroup\n\t\tM --\x3e Product\n\tend\n\tO --\x3e M"}),(0,a.kt)("p",null,"\ucd94\uac00\ub85c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc704\ud55c ",(0,a.kt)("inlineCode",{parentName:"p"},"@ServiceTest")," \uc560\ub108\ud14c\uc774\uc158\uc774 \uc788\uc5c8\ub294\ub370, \uc0c1\uc704 \ubaa8\ub4c8\uc758 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \ub9cc\ub4e0 \ud074\ub798\uc2a4\ub97c \ud558\uc704 \ubaa8\ub4c8\uc5d0\uc11c\ub294 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4.\n\ub530\ub77c\uc11c TestFixtures\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\uacb0\ud588\ub2e4. "),(0,a.kt)("h3",{id:"\ub9c8\ubb34\ub9ac"},"\ub9c8\ubb34\ub9ac"),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc758 \ub9c8\uc9c0\ub9c9 \ubbf8\uc158\uc774\ub2c8 \ub9cc\ud07c, \uac00\uc7a5 \ud765\ubbf8\ub85c\uc6b4 \ubbf8\uc158\uc774\uc5c8\uace0 \ubc30\uc6b8\uc810\ub3c4 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc14\uc05c \uae30\uac04\uc774\ub77c \ub9ce\uc740 \ub9ac\ubdf0\ub97c \ub0a8\uae30\uc9c0 \ubabb\ud588\ub358 \ub9ac\ubdf0\uc774 \ud638\uc774\uc5d0\uac8c \ubbf8\uc548\ud558\uace0, \ucf54\uba58\ud2b8 \uaf3c\uaf3c\ud558\uac8c \ub2ec\uc544\uc8fc\uace0 \ubbf8\uc158\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub3c4 \uc624\ud504\ub77c\uc778\uc73c\ub85c \ub9ce\uc774 \ub098\ub208 \ub9ac\ubdf0\uc5b4 \ud14c\uc624\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=kmUneexSxk0"},"\ub3c4\uba54\uc778 \uc6d0\uc815\ub300, \uc6b0\uc544\ucf58 2021"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=dJ5C4qRqAgA"},"\uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5, \uc6b0\uc544\ud55c\ud14c\ud06c\uc138\ubbf8\ub098"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://kwonnam.pe.kr/wiki/gradle/testfixtures"},"TestFixtures, \uad8c\ub0a8\ub2d8")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5373.41b31afd.js b/assets/js/5373.41b31afd.js new file mode 100644 index 000000000..28bd65b03 --- /dev/null +++ b/assets/js/5373.41b31afd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5373],{45373:(t,e,r)=>{r.d(e,{diagram:()=>D});var i=r(56363),a=r(45625),n=r(64218),s=r(41644);const o=[];for(let S=0;S<256;++S)o.push((S+256).toString(16).slice(1));function c(t,e=0){return(o[t[e+0]]+o[t[e+1]]+o[t[e+2]]+o[t[e+3]]+"-"+o[t[e+4]]+o[t[e+5]]+"-"+o[t[e+6]]+o[t[e+7]]+"-"+o[t[e+8]]+o[t[e+9]]+"-"+o[t[e+10]]+o[t[e+11]]+o[t[e+12]]+o[t[e+13]]+o[t[e+14]]+o[t[e+15]]).toLowerCase()}const l=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;const h=function(t){return"string"==typeof t&&l.test(t)};const d=function(t){if(!h(t))throw TypeError("Invalid UUID");let e;const r=new Uint8Array(16);return r[0]=(e=parseInt(t.slice(0,8),16))>>>24,r[1]=e>>>16&255,r[2]=e>>>8&255,r[3]=255&e,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=255&e,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=255&e,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=255&e,r[10]=(e=parseInt(t.slice(24,36),16))/1099511627776&255,r[11]=e/4294967296&255,r[12]=e>>>24&255,r[13]=e>>>16&255,r[14]=e>>>8&255,r[15]=255&e,r};function y(t,e,r,i){switch(t){case 0:return e&r^~e&i;case 1:case 3:return e^r^i;case 2:return e&r^e&i^r&i}}function u(t,e){return t<<e|t>>>32-e}const p=function(t,e,r){function i(t,i,a,n){var s;if("string"==typeof t&&(t=function(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r<t.length;++r)e.push(t.charCodeAt(r));return e}(t)),"string"==typeof i&&(i=d(i)),16!==(null===(s=i)||void 0===s?void 0:s.length))throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let o=new Uint8Array(16+t.length);if(o.set(i),o.set(t,i.length),o=r(o),o[6]=15&o[6]|e,o[8]=63&o[8]|128,a){n=n||0;for(let t=0;t<16;++t)a[n+t]=o[t];return a}return c(o)}try{i.name=t}catch(a){}return i.DNS="6ba7b810-9dad-11d1-80b4-00c04fd430c8",i.URL="6ba7b811-9dad-11d1-80b4-00c04fd430c8",i}("v5",80,(function(t){const e=[1518500249,1859775393,2400959708,3395469782],r=[1732584193,4023233417,2562383102,271733878,3285377520];if("string"==typeof t){const e=unescape(encodeURIComponent(t));t=[];for(let r=0;r<e.length;++r)t.push(e.charCodeAt(r))}else Array.isArray(t)||(t=Array.prototype.slice.call(t));t.push(128);const i=t.length/4+2,a=Math.ceil(i/16),n=new Array(a);for(let s=0;s<a;++s){const e=new Uint32Array(16);for(let r=0;r<16;++r)e[r]=t[64*s+4*r]<<24|t[64*s+4*r+1]<<16|t[64*s+4*r+2]<<8|t[64*s+4*r+3];n[s]=e}n[a-1][14]=8*(t.length-1)/Math.pow(2,32),n[a-1][14]=Math.floor(n[a-1][14]),n[a-1][15]=8*(t.length-1)&4294967295;for(let s=0;s<a;++s){const t=new Uint32Array(80);for(let e=0;e<16;++e)t[e]=n[s][e];for(let e=16;e<80;++e)t[e]=u(t[e-3]^t[e-8]^t[e-14]^t[e-16],1);let i=r[0],a=r[1],o=r[2],c=r[3],l=r[4];for(let r=0;r<80;++r){const n=Math.floor(r/20),s=u(i,5)+y(n,a,o,c)+l+e[n]+t[r]>>>0;l=c,c=o,o=u(a,30)>>>0,a=i,i=s}r[0]=r[0]+i>>>0,r[1]=r[1]+a>>>0,r[2]=r[2]+o>>>0,r[3]=r[3]+c>>>0,r[4]=r[4]+l>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]}));r(27484),r(17967),r(27856);var _=function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[6,8,10,20,22,24,26,27,28],r=[1,10],i=[1,11],a=[1,12],n=[1,13],s=[1,14],o=[1,15],c=[1,21],l=[1,22],h=[1,23],d=[1,24],y=[1,25],u=[6,8,10,13,15,18,19,20,22,24,26,27,28,41,42,43,44,45],p=[1,34],_=[27,28,46,47],f=[41,42,43,44,45],m=[17,34],E=[1,54],g=[1,53],O=[17,34,36,38],b={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,":":13,role:14,BLOCK_START:15,attributes:16,BLOCK_STOP:17,SQS:18,SQE:19,title:20,title_value:21,acc_title:22,acc_title_value:23,acc_descr:24,acc_descr_value:25,acc_descr_multiline_value:26,ALPHANUM:27,ENTITY_NAME:28,attribute:29,attributeType:30,attributeName:31,attributeKeyTypeList:32,attributeComment:33,ATTRIBUTE_WORD:34,attributeKeyType:35,COMMA:36,ATTRIBUTE_KEY:37,COMMENT:38,cardinality:39,relType:40,ZERO_OR_ONE:41,ZERO_OR_MORE:42,ONE_OR_MORE:43,ONLY_ONE:44,MD_PARENT:45,NON_IDENTIFYING:46,IDENTIFYING:47,WORD:48,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:":",15:"BLOCK_START",17:"BLOCK_STOP",18:"SQS",19:"SQE",20:"title",21:"title_value",22:"acc_title",23:"acc_title_value",24:"acc_descr",25:"acc_descr_value",26:"acc_descr_multiline_value",27:"ALPHANUM",28:"ENTITY_NAME",34:"ATTRIBUTE_WORD",36:"COMMA",37:"ATTRIBUTE_KEY",38:"COMMENT",41:"ZERO_OR_ONE",42:"ZERO_OR_MORE",43:"ONE_OR_MORE",44:"ONLY_ONE",45:"MD_PARENT",46:"NON_IDENTIFYING",47:"IDENTIFYING",48:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,4],[9,3],[9,1],[9,7],[9,6],[9,4],[9,2],[9,2],[9,2],[9,1],[11,1],[11,1],[16,1],[16,2],[29,2],[29,3],[29,3],[29,4],[30,1],[31,1],[32,1],[32,3],[35,1],[33,1],[12,3],[39,1],[39,1],[39,1],[39,1],[39,1],[40,1],[40,1],[14,1],[14,1],[14,1]],performAction:function(t,e,r,i,a,n,s){var o=n.length-1;switch(a){case 1:break;case 2:case 6:case 7:this.$=[];break;case 3:n[o-1].push(n[o]),this.$=n[o-1];break;case 4:case 5:case 19:case 43:case 27:case 28:case 31:this.$=n[o];break;case 8:i.addEntity(n[o-4]),i.addEntity(n[o-2]),i.addRelationship(n[o-4],n[o],n[o-2],n[o-3]);break;case 9:i.addEntity(n[o-3]),i.addAttributes(n[o-3],n[o-1]);break;case 10:i.addEntity(n[o-2]);break;case 11:i.addEntity(n[o]);break;case 12:i.addEntity(n[o-6],n[o-4]),i.addAttributes(n[o-6],n[o-1]);break;case 13:i.addEntity(n[o-5],n[o-3]);break;case 14:i.addEntity(n[o-3],n[o-1]);break;case 15:case 16:this.$=n[o].trim(),i.setAccTitle(this.$);break;case 17:case 18:this.$=n[o].trim(),i.setAccDescription(this.$);break;case 20:case 41:case 42:case 32:this.$=n[o].replace(/"/g,"");break;case 21:case 29:this.$=[n[o]];break;case 22:n[o].push(n[o-1]),this.$=n[o];break;case 23:this.$={attributeType:n[o-1],attributeName:n[o]};break;case 24:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeKeyTypeList:n[o]};break;case 25:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeComment:n[o]};break;case 26:this.$={attributeType:n[o-3],attributeName:n[o-2],attributeKeyTypeList:n[o-1],attributeComment:n[o]};break;case 30:n[o-2].push(n[o]),this.$=n[o-2];break;case 33:this.$={cardA:n[o],relType:n[o-1],cardB:n[o-2]};break;case 34:this.$=i.Cardinality.ZERO_OR_ONE;break;case 35:this.$=i.Cardinality.ZERO_OR_MORE;break;case 36:this.$=i.Cardinality.ONE_OR_MORE;break;case 37:this.$=i.Cardinality.ONLY_ONE;break;case 38:this.$=i.Cardinality.MD_PARENT;break;case 39:this.$=i.Identification.NON_IDENTIFYING;break;case 40:this.$=i.Identification.IDENTIFYING}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,20:r,22:i,24:a,26:n,27:s,28:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:16,11:9,20:r,22:i,24:a,26:n,27:s,28:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,11],{12:17,39:20,15:[1,18],18:[1,19],41:c,42:l,43:h,44:d,45:y}),{21:[1,26]},{23:[1,27]},{25:[1,28]},t(e,[2,18]),t(u,[2,19]),t(u,[2,20]),t(e,[2,4]),{11:29,27:s,28:o},{16:30,17:[1,31],29:32,30:33,34:p},{11:35,27:s,28:o},{40:36,46:[1,37],47:[1,38]},t(_,[2,34]),t(_,[2,35]),t(_,[2,36]),t(_,[2,37]),t(_,[2,38]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),{13:[1,39]},{17:[1,40]},t(e,[2,10]),{16:41,17:[2,21],29:32,30:33,34:p},{31:42,34:[1,43]},{34:[2,27]},{19:[1,44]},{39:45,41:c,42:l,43:h,44:d,45:y},t(f,[2,39]),t(f,[2,40]),{14:46,27:[1,49],28:[1,48],48:[1,47]},t(e,[2,9]),{17:[2,22]},t(m,[2,23],{32:50,33:51,35:52,37:E,38:g}),t([17,34,37,38],[2,28]),t(e,[2,14],{15:[1,55]}),t([27,28],[2,33]),t(e,[2,8]),t(e,[2,41]),t(e,[2,42]),t(e,[2,43]),t(m,[2,24],{33:56,36:[1,57],38:g}),t(m,[2,25]),t(O,[2,29]),t(m,[2,32]),t(O,[2,31]),{16:58,17:[1,59],29:32,30:33,34:p},t(m,[2,26]),{35:60,37:E},{17:[1,61]},t(e,[2,13]),t(O,[2,30]),t(e,[2,12])],defaultActions:{34:[2,27],41:[2,22]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],a=[null],n=[],s=this.table,o="",c=0,l=0,h=n.slice.call(arguments,1),d=Object.create(this.lexer),y={yy:{}};for(var u in this.yy)Object.prototype.hasOwnProperty.call(this.yy,u)&&(y.yy[u]=this.yy[u]);d.setInput(t,y.yy),y.yy.lexer=d,y.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var p=d.yylloc;n.push(p);var _=d.options&&d.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,m,E,g,O,b,k,R,N,T={};;){if(m=r[r.length-1],this.defaultActions[m]?E=this.defaultActions[m]:(null==f&&(N=void 0,"number"!=typeof(N=i.pop()||d.lex()||1)&&(N instanceof Array&&(N=(i=N).pop()),N=e.symbols_[N]||N),f=N),E=s[m]&&s[m][f]),void 0===E||!E.length||!E[0]){var x="";for(O in R=[],s[m])this.terminals_[O]&&O>2&&R.push("'"+this.terminals_[O]+"'");x=d.showPosition?"Parse error on line "+(c+1)+":\n"+d.showPosition()+"\nExpecting "+R.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(x,{text:d.match,token:this.terminals_[f]||f,line:d.yylineno,loc:p,expected:R})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+f);switch(E[0]){case 1:r.push(f),a.push(d.yytext),n.push(d.yylloc),r.push(E[1]),f=null,l=d.yyleng,o=d.yytext,c=d.yylineno,p=d.yylloc;break;case 2:if(b=this.productions_[E[1]][1],T.$=a[a.length-b],T._$={first_line:n[n.length-(b||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(b||1)].first_column,last_column:n[n.length-1].last_column},_&&(T._$.range=[n[n.length-(b||1)].range[0],n[n.length-1].range[1]]),void 0!==(g=this.performAction.apply(T,[o,l,c,y.yy,E[1],a,n].concat(h))))return g;b&&(r=r.slice(0,-1*b*2),a=a.slice(0,-1*b),n=n.slice(0,-1*b)),r.push(this.productions_[E[1]][0]),a.push(T.$),n.push(T._$),k=s[r[r.length-2]][r[r.length-1]],r.push(k);break;case 3:return!0}}return!0}},k={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var r,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;n<a.length;n++)if((r=this._input.match(this.rules[a[n]]))&&(!e||r[0].length>e[0].length)){if(e=r,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),22;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),24;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 10;case 8:case 15:case 20:break;case 9:return 8;case 10:return 28;case 11:return 48;case 12:return 4;case 13:return this.begin("block"),15;case 14:return 36;case 16:return 37;case 17:case 18:return 34;case 19:return 38;case 21:return this.popState(),17;case 22:case 54:return e.yytext[0];case 23:return 18;case 24:return 19;case 25:case 29:case 30:case 43:return 41;case 26:case 27:case 28:case 36:case 38:case 45:return 43;case 31:case 32:case 33:case 34:case 35:case 37:case 44:return 42;case 39:case 40:case 41:case 42:return 44;case 46:return 45;case 47:case 50:case 51:case 52:return 46;case 48:case 49:return 47;case 53:return 27;case 55:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:,)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[\*A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z_][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[14,15,16,17,18,19,20,21,22],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55],inclusive:!0}}};function R(){this.yy={}}return b.lexer=k,R.prototype=b,b.Parser=R,new R}();_.parser=_;const f=_;let m={},E=[];const g=function(t,e=void 0){return void 0===m[t]?(m[t]={attributes:[],alias:e},i.l.info("Added new entity :",t)):m[t]&&!m[t].alias&&e&&(m[t].alias=e,i.l.info(`Add alias '${e}' to entity '${t}'`)),m[t]},O={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},getConfig:()=>(0,i.c)().er,addEntity:g,addAttributes:function(t,e){let r,a=g(t);for(r=e.length-1;r>=0;r--)a.attributes.push(e[r]),i.l.debug("Added attribute ",e[r].attributeName)},getEntities:()=>m,addRelationship:function(t,e,r,a){let n={entityA:t,roleA:e,entityB:r,relSpec:a};E.push(n),i.l.debug("Added new relationship :",n)},getRelationships:()=>E,clear:function(){m={},E=[],(0,i.t)()},setAccTitle:i.s,getAccTitle:i.g,setAccDescription:i.b,getAccDescription:i.a,setDiagramTitle:i.q,getDiagramTitle:i.r},b={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END",MD_PARENT_END:"MD_PARENT_END",MD_PARENT_START:"MD_PARENT_START"},k=b,R=function(t,e){let r;t.append("defs").append("marker").attr("id",b.MD_PARENT_START).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",b.MD_PARENT_END).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",b.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",b.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",b.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",b.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),r=t.append("defs").append("marker").attr("id",b.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},N=/[^\dA-Za-z](\W)*/g;let T={},x=new Map;const A=function(t,e,r){let a;return Object.keys(e).forEach((function(n){const s=function(t="",e=""){const r=t.replace(N,"");return`${v(e)}${v(r)}${p(t,I)}`}(n,"entity");x.set(n,s);const o=t.append("g").attr("id",s);a=void 0===a?s:a;const c="text-"+s,l=o.append("text").classed("er entityLabel",!0).attr("id",c).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",(0,i.c)().fontFamily).style("font-size",T.fontSize+"px").text(e[n].alias??n),{width:h,height:d}=((t,e,r)=>{const a=T.entityPadding/3,n=T.entityPadding/3,s=.85*T.fontSize,o=e.node().getBBox(),c=[];let l=!1,h=!1,d=0,y=0,u=0,p=0,_=o.height+2*a,f=1;r.forEach((t=>{void 0!==t.attributeKeyTypeList&&t.attributeKeyTypeList.length>0&&(l=!0),void 0!==t.attributeComment&&(h=!0)})),r.forEach((r=>{const n=`${e.node().id}-attr-${f}`;let o=0;const m=(0,i.v)(r.attributeType),E=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(m),g=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(r.attributeName),O={};O.tn=E,O.nn=g;const b=E.node().getBBox(),k=g.node().getBBox();if(d=Math.max(d,b.width),y=Math.max(y,k.width),o=Math.max(b.height,k.height),l){const e=void 0!==r.attributeKeyTypeList?r.attributeKeyTypeList.join(","):"",a=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(e);O.kn=a;const c=a.node().getBBox();u=Math.max(u,c.width),o=Math.max(o,c.height)}if(h){const e=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.c)().fontFamily).style("font-size",s+"px").text(r.attributeComment||"");O.cn=e;const a=e.node().getBBox();p=Math.max(p,a.width),o=Math.max(o,a.height)}O.height=o,c.push(O),_+=o+2*a,f+=1}));let m=4;l&&(m+=2),h&&(m+=2);const E=d+y+u+p,g={width:Math.max(T.minEntityWidth,Math.max(o.width+2*T.entityPadding,E+n*m)),height:r.length>0?_:Math.max(T.minEntityHeight,o.height+2*T.entityPadding)};if(r.length>0){const r=Math.max(0,(g.width-E-n*m)/(m/2));e.attr("transform","translate("+g.width/2+","+(a+o.height/2)+")");let i=o.height+2*a,s="attributeBoxOdd";c.forEach((e=>{const o=i+a+e.height/2;e.tn.attr("transform","translate("+n+","+o+")");const c=t.insert("rect","#"+e.tn.node().id).classed(`er ${s}`,!0).attr("x",0).attr("y",i).attr("width",d+2*n+r).attr("height",e.height+2*a),_=parseFloat(c.attr("x"))+parseFloat(c.attr("width"));e.nn.attr("transform","translate("+(_+n)+","+o+")");const f=t.insert("rect","#"+e.nn.node().id).classed(`er ${s}`,!0).attr("x",_).attr("y",i).attr("width",y+2*n+r).attr("height",e.height+2*a);let m=parseFloat(f.attr("x"))+parseFloat(f.attr("width"));if(l){e.kn.attr("transform","translate("+(m+n)+","+o+")");const c=t.insert("rect","#"+e.kn.node().id).classed(`er ${s}`,!0).attr("x",m).attr("y",i).attr("width",u+2*n+r).attr("height",e.height+2*a);m=parseFloat(c.attr("x"))+parseFloat(c.attr("width"))}h&&(e.cn.attr("transform","translate("+(m+n)+","+o+")"),t.insert("rect","#"+e.cn.node().id).classed(`er ${s}`,"true").attr("x",m).attr("y",i).attr("width",p+2*n+r).attr("height",e.height+2*a)),i+=e.height+2*a,s="attributeBoxOdd"===s?"attributeBoxEven":"attributeBoxOdd"}))}else g.height=Math.max(T.minEntityHeight,_),e.attr("transform","translate("+g.width/2+","+g.height/2+")");return g})(o,l,e[n].attributes),y=o.insert("rect","#"+c).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",h).attr("height",d).node().getBBox();r.setNode(s,{width:y.width,height:y.height,shape:"rect",id:s})})),a},M=function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")};let w=0;const I="28e9f9db-3c8d-5aa5-9faf-44286ae5937c";function v(t=""){return t.length>0?`${t}-`:""}const D={parser:f,db:O,renderer:{setConf:function(t){const e=Object.keys(t);for(const r of e)T[r]=t[r]},draw:function(t,e,r,o){T=(0,i.c)().er,i.l.info("Drawing ER diagram");const c=(0,i.c)().securityLevel;let l;"sandbox"===c&&(l=(0,n.Ys)("#i"+e));const h=("sandbox"===c?(0,n.Ys)(l.nodes()[0].contentDocument.body):(0,n.Ys)("body")).select(`[id='${e}']`);let d;R(h,T),d=new a.k({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:T.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));const y=A(h,o.db.getEntities(),d),u=function(t,e){return t.forEach((function(t){e.setEdge(x.get(t.entityA),x.get(t.entityB),{relationship:t},M(t))})),t}(o.db.getRelationships(),d);var p,_;(0,s.bK)(d),p=h,(_=d).nodes().forEach((function(t){void 0!==t&&void 0!==_.node(t)&&p.select("#"+t).attr("transform","translate("+(_.node(t).x-_.node(t).width/2)+","+(_.node(t).y-_.node(t).height/2)+" )")})),u.forEach((function(t){!function(t,e,r,a,s){w++;const o=r.edge(x.get(e.entityA),x.get(e.entityB),M(e)),c=(0,n.jvg)().x((function(t){return t.x})).y((function(t){return t.y})).curve(n.$0Z),l=t.insert("path","#"+a).classed("er relationshipLine",!0).attr("d",c(o.points)).style("stroke",T.stroke).style("fill","none");e.relSpec.relType===s.db.Identification.NON_IDENTIFYING&&l.attr("stroke-dasharray","8,8");let h="";switch(T.arrowMarkerAbsolute&&(h=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,h=h.replace(/\(/g,"\\("),h=h.replace(/\)/g,"\\)")),e.relSpec.cardA){case s.db.Cardinality.ZERO_OR_ONE:l.attr("marker-end","url("+h+"#"+k.ZERO_OR_ONE_END+")");break;case s.db.Cardinality.ZERO_OR_MORE:l.attr("marker-end","url("+h+"#"+k.ZERO_OR_MORE_END+")");break;case s.db.Cardinality.ONE_OR_MORE:l.attr("marker-end","url("+h+"#"+k.ONE_OR_MORE_END+")");break;case s.db.Cardinality.ONLY_ONE:l.attr("marker-end","url("+h+"#"+k.ONLY_ONE_END+")");break;case s.db.Cardinality.MD_PARENT:l.attr("marker-end","url("+h+"#"+k.MD_PARENT_END+")")}switch(e.relSpec.cardB){case s.db.Cardinality.ZERO_OR_ONE:l.attr("marker-start","url("+h+"#"+k.ZERO_OR_ONE_START+")");break;case s.db.Cardinality.ZERO_OR_MORE:l.attr("marker-start","url("+h+"#"+k.ZERO_OR_MORE_START+")");break;case s.db.Cardinality.ONE_OR_MORE:l.attr("marker-start","url("+h+"#"+k.ONE_OR_MORE_START+")");break;case s.db.Cardinality.ONLY_ONE:l.attr("marker-start","url("+h+"#"+k.ONLY_ONE_START+")");break;case s.db.Cardinality.MD_PARENT:l.attr("marker-start","url("+h+"#"+k.MD_PARENT_START+")")}const d=l.node().getTotalLength(),y=l.node().getPointAtLength(.5*d),u="rel"+w,p=t.append("text").classed("er relationshipLabel",!0).attr("id",u).attr("x",y.x).attr("y",y.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",(0,i.c)().fontFamily).style("font-size",T.fontSize+"px").text(e.roleA).node().getBBox();t.insert("rect","#"+u).classed("er relationshipLabelBox",!0).attr("x",y.x-p.width/2).attr("y",y.y-p.height/2).attr("width",p.width).attr("height",p.height)}(h,t,d,y,o)}));const f=T.diagramPadding;i.u.insertTitle(h,"entityTitleText",T.titleTopMargin,o.db.getDiagramTitle());const m=h.node().getBBox(),E=m.width+2*f,g=m.height+2*f;(0,i.i)(h,g,E,T.useMaxWidth),h.attr("viewBox",`${m.x-f} ${m.y-f} ${E} ${g}`)}},styles:t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxOdd {\n fill: ${t.attributeBackgroundColorOdd};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxEven {\n fill: ${t.attributeBackgroundColorEven};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n }\n\n .entityTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n } \n #MD_PARENT_START {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n #MD_PARENT_END {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n \n`}}}]); \ No newline at end of file diff --git a/assets/js/537817cb.65f6a412.js b/assets/js/537817cb.65f6a412.js new file mode 100644 index 000000000..6baef2c16 --- /dev/null +++ b/assets/js/537817cb.65f6a412.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3457],{75088:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var r=n(85893),a=n(3905);const l={title:"JSR-310",slug:"jsr-310",tags:["Java","Time"]},i=void 0,o={permalink:"/jsr-310",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-08-JSR-310.mdx",source:"@site/blog/2023-1/2023-01-08-JSR-310.mdx",title:"JSR-310",description:"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API",date:"2023-01-08T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 8\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Time",permalink:"/tags/time"}],readingTime:1.685,hasTruncateMarker:!1,authors:[],frontMatter:{title:"JSR-310",slug:"jsr-310",tags:["Java","Time"]},unlisted:!1,prevItem:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",permalink:"/kotlin-null"},nextItem:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",permalink:"/the-essence-of-object-orientation"}},s={authorsImageUrls:[]},c=[{value:"LocalDate, LocalTime, LocalDateTime",id:"localdate-localtime-localdatetime",level:3},{value:"Instant",id:"instant",level:3},{value:"Duration, Period",id:"duration-period",level:3},{value:"TemporalAdjusters",id:"temporaladjusters",level:3},{value:"DateTimeFormatter",id:"datetimeformatter",level:3},{value:"ZoneId, ZoneOffset",id:"zoneid-zoneoffset",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(t.p,{children:["\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API",(0,r.jsx)(t.br,{}),"\n","ISO-8601\uc744 \uae30\ubc18\uc73c\ub85c \uc791\uc131",(0,r.jsx)(t.br,{}),"\n","\uc124\uacc4 \ubaa9\ud45c \u2192 \ubd88\ubcc0, Fluent API, \uba85\ud655\ud558\uace0 \uba85\uc2dc\uc801, \ud655\uc7a5 \uac00\ub2a5\uc131"]}),"\n",(0,r.jsx)(t.admonition,{title:"ISO-8601",type:"note",children:(0,r.jsx)(t.p,{children:"\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc5d0 \uad00\ub828\ub41c \ub370\uc774\ud130\ub97c \ub2e4\ub8e8\ub294 \uad6d\uc81c \ud45c\uc900"})}),"\n",(0,r.jsx)(t.h3,{id:"localdate-localtime-localdatetime",children:"LocalDate, LocalTime, LocalDateTime"}),"\n",(0,r.jsx)(t.p,{children:"\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4"}),"\n",(0,r.jsx)(t.h3,{id:"instant",children:"Instant"}),"\n",(0,r.jsxs)(t.p,{children:["\uc720\ub2c9\uc2a4 \uc2dc\uac04(1970-01-01, 00:00:00 UTC) \uae30\uc900\uc73c\ub85c \ud2b9\uc815 \uc9c0\uc810\uae4c\uc9c0\uc758 \uc2dc\uac04\uc744 \ucd08\ub85c \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4",(0,r.jsx)(t.br,{}),"\n","\uae30\uacc4\uc758 \uad00\uc810\uc5d0\uc11c \uc2dc\uac04 \ud45c\ud604"]}),"\n",(0,r.jsx)(t.h3,{id:"duration-period",children:"Duration, Period"}),"\n",(0,r.jsx)(t.p,{children:"\uac04\uaca9\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4"}),"\n",(0,r.jsx)(t.h3,{id:"temporaladjusters",children:"TemporalAdjusters"}),"\n",(0,r.jsxs)(t.p,{children:["\ubcf5\uc7a1\ud55c \ub0a0\uc9dc \uc870\uc815\uc774 \ud544\uc694\ud560 \ub54c \uc0ac\uc6a9",(0,r.jsx)(t.br,{}),"\n","\ud544\uc694\ud55c \uacbd\uc6b0 \ub2e4\uc74c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\uc5ec \ucee4\uc2a4\ud140 TemporalAdjuster\ub97c \uad6c\ud604 \uac00\ub2a5"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",children:"@FunctionalInterface\npublic interface TemporalAdjuster {\n Temporal adjustInto(Temporal temporal);\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"datetimeformatter",children:"DateTimeFormatter"}),"\n",(0,r.jsxs)(t.p,{children:["\ub0a0\uc9dc\uc640 \uc2dc\uac04 \ud3ec\ub9f7 \ud074\ub798\uc2a4",(0,r.jsx)(t.br,{}),"\n","\ud2b9\uc815 \ub0a0\uc9dc \ud328\ud134\uc774\ub098, DateTimeFormatterBuilder\ub97c \uc774\uc6a9\ud574\uc11c \ucee4\uc2a4\ud140\ud55c \ud3ec\ub9f7\uc744 \uc0dd\uc131 \uac00\ub2a5"]}),"\n",(0,r.jsx)(t.h3,{id:"zoneid-zoneoffset",children:"ZoneId, ZoneOffset"}),"\n",(0,r.jsxs)(t.p,{children:["ZoneId\ub294 \uc9c0\uc5ed ID\ub294 ",(0,r.jsx)(t.code,{children:"\u2018\uc9c0\uc5ed/\ub3c4\uc2dc\u2019"})," \ud615\uc2dd, ZoneOffset\uc740 \uc2dc\ucc28 UTC \uae30\uc900 \uace0\uc815\ub41c \uc2dc\uac04 \ucc28\uc774 \uc774\uc6a9",(0,r.jsx)(t.br,{}),"\n","ZoneId\uc758 \uacbd\uc6b0 IANA Time Zone Database\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc9c0\uc5ed \uc9d1\ud569 \uc815\ubcf4 \uc0ac\uc6a9"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",children:"Instant instant = Instant.now();\nLocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);\n"})}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://product.kyobobook.co.kr/detail/S000001810171",children:"\ubaa8\ub358 \uc790\ubc14 \uc778 \uc561\uc158"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://d2.naver.com/helloworld/645609",children:"Java\uc758 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://www.w3.org/TR/NOTE-datetime",children:"ISO-8601"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://download.oracle.com/otn-pub/jcp/date_time-0.2-edr-oth-JSpec/date_time-0_2-edr-spec.pdf?AuthParam=1673171124_74a718be92efe4911c6977c02965aff4",children:"JSR-310 Spec"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://www.baeldung.com/java-temporal-adjuster",children:"Temporal Adjuster"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html",children:"DateTimeFormatter"})}),"\n"]})]})}function m(e={}){const{wrapper:t}={...(0,a.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>c});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),p=c(n),u=a,h=p["".concat(s,".").concat(u)]||p[u]||d[u]||l;return n?r.createElement(h,i(i({ref:t},m),{},{components:n})):r.createElement(h,i({ref:t},m))}));m.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/537817cb.b44a0ebf.js b/assets/js/537817cb.b44a0ebf.js deleted file mode 100644 index fc19813f5..000000000 --- a/assets/js/537817cb.b44a0ebf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3457],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>d});var r=a(67294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?l(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function i(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},l=Object.keys(e);for(r=0;r<l.length;r++)a=l[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)a=l[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var p=r.createContext({}),m=function(e){var t=r.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},c=function(e){var t=m(e.components);return r.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},s=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,l=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),s=m(a),d=n,f=s["".concat(p,".").concat(d)]||s[d]||u[d]||l;return a?r.createElement(f,o(o({ref:t},c),{},{components:a})):r.createElement(f,o({ref:t},c))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var l=a.length,o=new Array(l);o[0]=s;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:n,o[1]=i;for(var m=2;m<l;m++)o[m]=a[m];return r.createElement.apply(null,o)}return r.createElement.apply(null,a)}s.displayName="MDXCreateElement"},49577:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>i,toc:()=>m});var r=a(87462),n=(a(67294),a(3905));const l={title:"JSR-310",slug:"jsr-310",tags:["Java","Time"]},o=void 0,i={permalink:"/jsr-310",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-08-JSR-310.mdx",source:"@site/blog/2023-1/2023-01-08-JSR-310.mdx",title:"JSR-310",description:"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API",date:"2023-01-08T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 8\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Time",permalink:"/tags/time"}],readingTime:1.685,hasTruncateMarker:!1,authors:[],frontMatter:{title:"JSR-310",slug:"jsr-310",tags:["Java","Time"]},prevItem:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",permalink:"/kotlin-null"},nextItem:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",permalink:"/the-essence-of-object-orientation"}},p={authorsImageUrls:[]},m=[{value:"LocalDate, LocalTime, LocalDateTime",id:"localdate-localtime-localdatetime",level:3},{value:"Instant",id:"instant",level:3},{value:"Duration, Period",id:"duration-period",level:3},{value:"TemporalAdjusters",id:"temporaladjusters",level:3},{value:"DateTimeFormatter",id:"datetimeformatter",level:3},{value:"ZoneId, ZoneOffset",id:"zoneid-zoneoffset",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:m};function u(e){let{components:t,...a}=e;return(0,n.kt)("wrapper",(0,r.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API",(0,n.kt)("br",{parentName:"p"}),"\n","ISO-8601\uc744 \uae30\ubc18\uc73c\ub85c \uc791\uc131",(0,n.kt)("br",{parentName:"p"}),"\n","\uc124\uacc4 \ubaa9\ud45c \u2192 \ubd88\ubcc0, Fluent API, \uba85\ud655\ud558\uace0 \uba85\uc2dc\uc801, \ud655\uc7a5 \uac00\ub2a5\uc131"),(0,n.kt)("admonition",{title:"ISO-8601",type:"note"},(0,n.kt)("p",{parentName:"admonition"},"\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc5d0 \uad00\ub828\ub41c \ub370\uc774\ud130\ub97c \ub2e4\ub8e8\ub294 \uad6d\uc81c \ud45c\uc900")),(0,n.kt)("h3",{id:"localdate-localtime-localdatetime"},"LocalDate, LocalTime, LocalDateTime"),(0,n.kt)("p",null,"\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4"),(0,n.kt)("h3",{id:"instant"},"Instant"),(0,n.kt)("p",null,"\uc720\ub2c9\uc2a4 \uc2dc\uac04(1970-01-01, 00:00:00 UTC) \uae30\uc900\uc73c\ub85c \ud2b9\uc815 \uc9c0\uc810\uae4c\uc9c0\uc758 \uc2dc\uac04\uc744 \ucd08\ub85c \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4",(0,n.kt)("br",{parentName:"p"}),"\n","\uae30\uacc4\uc758 \uad00\uc810\uc5d0\uc11c \uc2dc\uac04 \ud45c\ud604"),(0,n.kt)("h3",{id:"duration-period"},"Duration, Period"),(0,n.kt)("p",null,"\uac04\uaca9\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4"),(0,n.kt)("h3",{id:"temporaladjusters"},"TemporalAdjusters"),(0,n.kt)("p",null,"\ubcf5\uc7a1\ud55c \ub0a0\uc9dc \uc870\uc815\uc774 \ud544\uc694\ud560 \ub54c \uc0ac\uc6a9",(0,n.kt)("br",{parentName:"p"}),"\n","\ud544\uc694\ud55c \uacbd\uc6b0 \ub2e4\uc74c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\uc5ec \ucee4\uc2a4\ud140 TemporalAdjuster\ub97c \uad6c\ud604 \uac00\ub2a5"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},"@FunctionalInterface\npublic interface TemporalAdjuster {\n Temporal adjustInto(Temporal temporal);\n}\n")),(0,n.kt)("h3",{id:"datetimeformatter"},"DateTimeFormatter"),(0,n.kt)("p",null,"\ub0a0\uc9dc\uc640 \uc2dc\uac04 \ud3ec\ub9f7 \ud074\ub798\uc2a4",(0,n.kt)("br",{parentName:"p"}),"\n","\ud2b9\uc815 \ub0a0\uc9dc \ud328\ud134\uc774\ub098, DateTimeFormatterBuilder\ub97c \uc774\uc6a9\ud574\uc11c \ucee4\uc2a4\ud140\ud55c \ud3ec\ub9f7\uc744 \uc0dd\uc131 \uac00\ub2a5"),(0,n.kt)("h3",{id:"zoneid-zoneoffset"},"ZoneId, ZoneOffset"),(0,n.kt)("p",null,"ZoneId\ub294 \uc9c0\uc5ed ID\ub294 ",(0,n.kt)("inlineCode",{parentName:"p"},"\u2018\uc9c0\uc5ed/\ub3c4\uc2dc\u2019")," \ud615\uc2dd, ZoneOffset\uc740 \uc2dc\ucc28 UTC \uae30\uc900 \uace0\uc815\ub41c \uc2dc\uac04 \ucc28\uc774 \uc774\uc6a9",(0,n.kt)("br",{parentName:"p"}),"\n","ZoneId\uc758 \uacbd\uc6b0 IANA Time Zone Database\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc9c0\uc5ed \uc9d1\ud569 \uc815\ubcf4 \uc0ac\uc6a9"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},"Instant instant = Instant.now();\nLocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);\n")),(0,n.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://product.kyobobook.co.kr/detail/S000001810171"},"\ubaa8\ub358 \uc790\ubc14 \uc778 \uc561\uc158")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://d2.naver.com/helloworld/645609"},"Java\uc758 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.w3.org/TR/NOTE-datetime"},"ISO-8601")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://download.oracle.com/otn-pub/jcp/date_time-0.2-edr-oth-JSpec/date_time-0_2-edr-spec.pdf?AuthParam=1673171124_74a718be92efe4911c6977c02965aff4"},"JSR-310 Spec")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.baeldung.com/java-temporal-adjuster"},"Temporal Adjuster")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html"},"DateTimeFormatter"))))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/546ec22f.01a1fc0a.js b/assets/js/546ec22f.826c8fef.js similarity index 79% rename from assets/js/546ec22f.01a1fc0a.js rename to assets/js/546ec22f.826c8fef.js index 3552ea9d8..23c936568 100644 --- a/assets/js/546ec22f.01a1fc0a.js +++ b/assets/js/546ec22f.826c8fef.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5635],{34223:e=>{e.exports=JSON.parse('{"label":"performance test","permalink":"/tags/performance-test","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5635],{34223:e=>{e.exports=JSON.parse('{"label":"performance test","permalink":"/tags/performance-test","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/562496aa.a42c37e7.js b/assets/js/562496aa.6fbd6e7b.js similarity index 87% rename from assets/js/562496aa.a42c37e7.js rename to assets/js/562496aa.6fbd6e7b.js index e40ccb831..b3db4d520 100644 --- a/assets/js/562496aa.a42c37e7.js +++ b/assets/js/562496aa.6fbd6e7b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6161],{68146:e=>{e.exports=JSON.parse('{"label":"image","permalink":"/tags/image","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6161],{68146:e=>{e.exports=JSON.parse('{"label":"image","permalink":"/tags/image","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/5705.d5718783.js b/assets/js/5705.d5718783.js new file mode 100644 index 000000000..5c5baa5f9 --- /dev/null +++ b/assets/js/5705.d5718783.js @@ -0,0 +1 @@ +(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5705],{17295:(n,t,e)=>{n.exports=function(){function n(t,e,i){function r(a,u){if(!e[a]){if(!t[a]){if(c)return c(a,!0);var o=new Error("Cannot find module '"+a+"'");throw o.code="MODULE_NOT_FOUND",o}var s=e[a]={exports:{}};t[a][0].call(s.exports,(function(n){return r(t[a][1][n]||n)}),s,s.exports,n,t,e,i)}return e[a].exports}for(var c=void 0,a=0;a<i.length;a++)r(i[a]);return r}return n}()({1:[function(n,t,e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=function(){function n(n,t){for(var e=0;e<t.length;e++){var i=t[e];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(n,i.key,i)}}return function(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}}();function r(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}var c=function(){function n(){var t=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=e.defaultLayoutOptions,c=void 0===i?{}:i,u=e.algorithms,o=void 0===u?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:u,s=e.workerFactory,h=e.workerUrl;if(r(this,n),this.defaultLayoutOptions=c,this.initialized=!1,void 0===h&&void 0===s)throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var f=s;void 0!==h&&void 0===s&&(f=function(n){return new Worker(n)});var l=f(h);if("function"!=typeof l.postMessage)throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new a(l),this.worker.postMessage({cmd:"register",algorithms:o}).then((function(n){return t.initialized=!0})).catch(console.err)}return i(n,[{key:"layout",value:function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=t.layoutOptions,i=void 0===e?this.defaultLayoutOptions:e,r=t.logging,c=void 0!==r&&r,a=t.measureExecutionTime,u=void 0!==a&&a;return n?this.worker.postMessage({cmd:"layout",graph:n,layoutOptions:i,options:{logging:c,measureExecutionTime:u}}):Promise.reject(new Error("Missing mandatory parameter 'graph'."))}},{key:"knownLayoutAlgorithms",value:function(){return this.worker.postMessage({cmd:"algorithms"})}},{key:"knownLayoutOptions",value:function(){return this.worker.postMessage({cmd:"options"})}},{key:"knownLayoutCategories",value:function(){return this.worker.postMessage({cmd:"categories"})}},{key:"terminateWorker",value:function(){this.worker.terminate()}}]),n}();e.default=c;var a=function(){function n(t){var e=this;if(r(this,n),void 0===t)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=t,this.worker.onmessage=function(n){setTimeout((function(){e.receive(e,n)}),0)}}return i(n,[{key:"postMessage",value:function(n){var t=this.id||0;this.id=t+1,n.id=t;var e=this;return new Promise((function(i,r){e.resolvers[t]=function(n,t){n?(e.convertGwtStyleError(n),r(n)):i(t)},e.worker.postMessage(n)}))}},{key:"receive",value:function(n,t){var e=t.data,i=n.resolvers[e.id];i&&(delete n.resolvers[e.id],e.error?i(e.error):i(null,e.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(n){if(n){var t=n.__java$exception;t&&(t.cause&&t.cause.backingJsObject&&(n.cause=t.cause.backingJsObject,this.convertGwtStyleError(n.cause)),delete n.__java$exception)}}}]),n}()},{}],2:[function(n,t,i){(function(n){(function(){"use strict";var e;function r(){}function c(){}function a(){}function u(){}function o(){}function s(){}function h(){}function f(){}function l(){}function b(){}function w(){}function d(){}function g(){}function p(){}function v(){}function m(){}function y(){}function k(){}function j(){}function E(){}function T(){}function M(){}function S(){}function P(){}function I(){}function C(){}function O(){}function A(){}function $(){}function L(){}function N(){}function x(){}function D(){}function R(){}function _(){}function K(){}function F(){}function B(){}function H(){}function q(){}function G(){}function z(){}function U(){}function X(){}function W(){}function V(){}function Q(){}function Y(){}function J(){}function Z(){}function nn(){}function tn(){}function en(){}function rn(){}function cn(){}function an(){}function un(){}function on(){}function sn(){}function hn(){}function fn(){}function ln(){}function bn(){}function wn(){}function dn(){}function gn(){}function pn(){}function vn(){}function mn(){}function yn(){}function kn(){}function jn(){}function En(){}function Tn(){}function Mn(){}function Sn(){}function Pn(){}function In(){}function Cn(){}function On(){}function An(){}function $n(){}function Ln(){}function Nn(){}function xn(){}function Dn(){}function Rn(){}function _n(){}function Kn(){}function Fn(){}function Bn(){}function Hn(){}function qn(){}function Gn(){}function zn(){}function Un(){}function Xn(){}function Wn(){}function Vn(){}function Qn(){}function Yn(){}function Jn(){}function Zn(){}function nt(){}function tt(){}function et(){}function it(){}function rt(){}function ct(){}function at(){}function ut(){}function ot(){}function st(){}function ht(){}function ft(){}function lt(){}function bt(){}function wt(){}function dt(){}function gt(){}function pt(){}function vt(){}function mt(){}function yt(){}function kt(){}function jt(){}function Et(){}function Tt(){}function Mt(){}function St(){}function Pt(){}function It(){}function Ct(){}function Ot(){}function At(){}function $t(){}function Lt(){}function Nt(){}function xt(){}function Dt(){}function Rt(){}function _t(){}function Kt(){}function Ft(){}function Bt(){}function Ht(){}function qt(){}function Gt(){}function zt(){}function Ut(){}function Xt(){}function Wt(){}function Vt(){}function Qt(){}function Yt(){}function Jt(){}function Zt(){}function ne(){}function te(){}function ee(){}function ie(){}function re(){}function ce(){}function ae(){}function ue(){}function oe(){}function se(){}function he(){}function fe(){}function le(){}function be(){}function we(){}function de(){}function ge(){}function pe(){}function ve(){}function me(){}function ye(){}function ke(){}function je(){}function Ee(){}function Te(){}function Me(){}function Se(){}function Pe(){}function Ie(){}function Ce(){}function Oe(){}function Ae(){}function $e(){}function Le(){}function Ne(){}function xe(){}function De(){}function Re(){}function _e(){}function Ke(){}function Fe(){}function Be(){}function He(){}function qe(){}function Ge(){}function ze(){}function Ue(){}function Xe(){}function We(){}function Ve(){}function Qe(){}function Ye(){}function Je(){}function Ze(){}function ni(){}function ti(){}function ei(){}function ii(){}function ri(){}function ci(){}function ai(){}function ui(){}function oi(){}function si(){}function hi(){}function fi(){}function li(){}function bi(){}function wi(){}function di(){}function gi(){}function pi(){}function vi(){}function mi(){}function yi(){}function ki(){}function ji(){}function Ei(){}function Ti(){}function Mi(){}function Si(){}function Pi(){}function Ii(){}function Ci(){}function Oi(){}function Ai(){}function $i(){}function Li(){}function Ni(){}function xi(){}function Di(){}function Ri(){}function _i(){}function Ki(){}function Fi(){}function Bi(){}function Hi(){}function qi(){}function Gi(){}function zi(){}function Ui(){}function Xi(){}function Wi(){}function Vi(){}function Qi(){}function Yi(){}function Ji(){}function Zi(){}function nr(){}function tr(){}function er(){}function ir(){}function rr(){}function cr(){}function ar(){}function ur(){}function or(){}function sr(){}function hr(){}function fr(){}function lr(){}function br(){}function wr(){}function dr(){}function gr(){}function pr(){}function vr(){}function mr(){}function yr(){}function kr(){}function jr(){}function Er(){}function Tr(){}function Mr(){}function Sr(){}function Pr(){}function Ir(){}function Cr(){}function Or(){}function Ar(){}function $r(){}function Lr(){}function Nr(){}function xr(){}function Dr(){}function Rr(){}function _r(){}function Kr(){}function Fr(){}function Br(){}function Hr(){}function qr(){}function Gr(){}function zr(){}function Ur(){}function Xr(){}function Wr(){}function Vr(){}function Qr(){}function Yr(){}function Jr(){}function Zr(){}function nc(){}function tc(){}function ec(){}function ic(){}function rc(){}function cc(){}function ac(){}function uc(){}function oc(){}function sc(){}function hc(){}function fc(){}function lc(){}function bc(){}function wc(){}function dc(){}function gc(){}function pc(){}function vc(){}function mc(){}function yc(){}function kc(){}function jc(){}function Ec(){}function Tc(){}function Mc(){}function Sc(){}function Pc(){}function Ic(){}function Cc(){}function Oc(){}function Ac(){}function $c(){}function Lc(){}function Nc(){}function xc(){}function Dc(){}function Rc(){}function _c(){}function Kc(){}function Fc(){}function Bc(){}function Hc(){}function qc(){}function Gc(){}function zc(){}function Uc(){}function Xc(){}function Wc(){}function Vc(){}function Qc(){}function Yc(){}function Jc(){}function Zc(){}function na(){}function ta(){}function ea(){}function ia(){}function ra(){}function ca(){}function aa(){}function ua(){}function oa(){}function sa(){}function ha(){}function fa(){}function la(){}function ba(){}function wa(){}function da(){}function ga(){}function pa(){}function va(){}function ma(){}function ya(){}function ka(){}function ja(){}function Ea(){}function Ta(){}function Ma(){}function Sa(){}function Pa(){}function Ia(){}function Ca(){}function Oa(){}function Aa(){}function $a(){}function La(){}function Na(){}function xa(){}function Da(){}function Ra(){}function _a(){}function Ka(){}function Fa(){}function Ba(){}function Ha(){}function qa(){}function Ga(){}function za(){}function Ua(){}function Xa(){}function Wa(){}function Va(){}function Qa(){}function Ya(){}function Ja(){}function Za(){}function nu(){}function tu(){}function eu(){}function iu(){}function ru(){}function cu(){}function au(){}function uu(){}function ou(){}function su(){}function hu(){}function fu(){}function lu(){}function bu(){}function wu(){}function du(){}function gu(){}function pu(){}function vu(){}function mu(){}function yu(){}function ku(){}function ju(){}function Eu(){}function Tu(){}function Mu(){}function Su(){}function Pu(){}function Iu(){}function Cu(){}function Ou(){}function Au(){}function $u(){}function Lu(){}function Nu(){}function xu(){}function Du(){}function Ru(){}function _u(){}function Ku(){}function Fu(){}function Bu(){}function Hu(){}function qu(){}function Gu(){}function zu(){}function Uu(){}function Xu(){}function Wu(){}function Vu(){}function Qu(){}function Yu(){}function Ju(){}function Zu(){}function no(){}function to(){}function eo(){}function io(){}function ro(){}function co(){}function ao(){}function uo(){}function oo(){}function so(){}function ho(){}function fo(){}function lo(){}function bo(){}function wo(){}function go(){}function po(){}function vo(){}function mo(){}function yo(){}function ko(){}function jo(){}function Eo(){}function To(){}function Mo(){}function So(){}function Po(){}function Io(){}function Co(){}function Oo(){}function Ao(){}function $o(){}function Lo(){}function No(){}function xo(){}function Do(){}function Ro(){}function _o(){}function Ko(){}function Fo(){}function Bo(){}function Ho(){}function qo(){}function Go(){}function zo(){}function Uo(){}function Xo(){}function Wo(){}function Vo(){}function Qo(){}function Yo(){}function Jo(){}function Zo(){}function ns(){}function ts(){}function es(){}function is(){}function rs(){}function cs(){}function as(){}function us(){}function os(){}function ss(){}function hs(){}function fs(){}function ls(){}function bs(){}function ws(){}function ds(){}function gs(){}function ps(){}function vs(){}function ms(){}function ys(){}function ks(){}function js(){}function Es(){}function Ts(){}function Ms(){}function Ss(){}function Ps(){}function Is(){}function Cs(){}function Os(){}function As(){}function $s(){}function Ls(){}function Ns(){}function xs(){}function Ds(){}function Rs(){}function _s(){}function Ks(){}function Fs(){}function Bs(){}function Hs(){}function qs(){}function Gs(){}function zs(){}function Us(){}function Xs(){}function Ws(){}function Vs(){}function Qs(){}function Ys(){}function Js(){}function Zs(){}function nh(){}function th(){}function eh(){}function ih(){}function rh(){}function ch(){}function ah(){}function uh(){}function oh(){}function sh(){}function hh(){}function fh(){}function lh(){}function bh(){}function wh(){}function dh(){}function gh(){}function ph(){}function vh(){}function mh(){}function yh(){}function kh(){}function jh(){}function Eh(){}function Th(){}function Mh(){}function Sh(){}function Ph(){}function Ih(){}function Ch(){}function Oh(){}function Ah(){}function $h(){}function Lh(){}function Nh(){}function xh(){}function Dh(){}function Rh(){}function _h(){}function Kh(n){}function Fh(n){}function Bh(){iy()}function Hh(){Gsn()}function qh(){Epn()}function Gh(){Kkn()}function zh(){jSn()}function Uh(){fRn()}function Xh(){_yn()}function Wh(){rkn()}function Vh(){EM()}function Qh(){mM()}function Yh(){qK()}function Jh(){TM()}function Zh(){Crn()}function nf(){SM()}function tf(){C6()}function ef(){Pin()}function rf(){Q8()}function cf(){KZ()}function af(){zsn()}function uf(){KMn()}function of(){Iin()}function sf(){U2()}function hf(){fWn()}function ff(){Gyn()}function lf(){FZ()}function bf(){HXn()}function wf(){RZ()}function df(){Cin()}function gf(){Yun()}function pf(){GZ()}function vf(){I9()}function mf(){PM()}function yf(){_An()}function kf(){Uyn()}function jf(){Fcn()}function Ef(){MMn()}function Tf(){bRn()}function Mf(){Bvn()}function Sf(){IAn()}function Pf(){Ran()}function If(){HZ()}function Cf(){sKn()}function Of(){$An()}function Af(){W$n()}function $f(){x9()}function Lf(){SMn()}function Nf(){sWn()}function xf(){Xsn()}function Df(){vdn()}function Rf(){qBn()}function _f(){uK()}function Kf(){wcn()}function Ff(){fFn()}function Bf(n){kW(n)}function Hf(n){this.a=n}function qf(n){this.a=n}function Gf(n){this.a=n}function zf(n){this.a=n}function Uf(n){this.a=n}function Xf(n){this.a=n}function Wf(n){this.a=n}function Vf(n){this.a=n}function Qf(n){this.a=n}function Yf(n){this.a=n}function Jf(n){this.a=n}function Zf(n){this.a=n}function nl(n){this.a=n}function tl(n){this.a=n}function el(n){this.a=n}function il(n){this.a=n}function rl(n){this.a=n}function cl(n){this.a=n}function al(n){this.a=n}function ul(n){this.a=n}function ol(n){this.a=n}function sl(n){this.b=n}function hl(n){this.c=n}function fl(n){this.a=n}function ll(n){this.a=n}function bl(n){this.a=n}function wl(n){this.a=n}function dl(n){this.a=n}function gl(n){this.a=n}function pl(n){this.a=n}function vl(n){this.a=n}function ml(n){this.a=n}function yl(n){this.a=n}function kl(n){this.a=n}function jl(n){this.a=n}function El(n){this.a=n}function Tl(n){this.a=n}function Ml(n){this.a=n}function Sl(n){this.a=n}function Pl(n){this.a=n}function Il(){this.a=[]}function Cl(n,t){n.a=t}function Ol(n,t){n.a=t}function Al(n,t){n.b=t}function $l(n,t){n.b=t}function Ll(n,t){n.b=t}function Nl(n,t){n.j=t}function xl(n,t){n.g=t}function Dl(n,t){n.i=t}function Rl(n,t){n.c=t}function _l(n,t){n.d=t}function Kl(n,t){n.d=t}function Fl(n,t){n.c=t}function Bl(n,t){n.k=t}function Hl(n,t){n.c=t}function ql(n,t){n.c=t}function Gl(n,t){n.a=t}function zl(n,t){n.a=t}function Ul(n,t){n.f=t}function Xl(n,t){n.a=t}function Wl(n,t){n.b=t}function Vl(n,t){n.d=t}function Ql(n,t){n.i=t}function Yl(n,t){n.o=t}function Jl(n,t){n.r=t}function Zl(n,t){n.a=t}function nb(n,t){n.b=t}function tb(n,t){n.e=t}function eb(n,t){n.f=t}function ib(n,t){n.g=t}function rb(n,t){n.e=t}function cb(n,t){n.f=t}function ab(n,t){n.f=t}function ub(n,t){n.n=t}function ob(n,t){n.a=t}function sb(n,t){n.a=t}function hb(n,t){n.c=t}function fb(n,t){n.c=t}function lb(n,t){n.d=t}function bb(n,t){n.e=t}function wb(n,t){n.g=t}function db(n,t){n.a=t}function gb(n,t){n.c=t}function pb(n,t){n.d=t}function vb(n,t){n.e=t}function mb(n,t){n.f=t}function yb(n,t){n.j=t}function kb(n,t){n.a=t}function jb(n,t){n.b=t}function Eb(n,t){n.a=t}function Tb(n){n.b=n.a}function Mb(n){n.c=n.d.d}function Sb(n){this.d=n}function Pb(n){this.a=n}function Ib(n){this.a=n}function Cb(n){this.a=n}function Ob(n){this.a=n}function Ab(n){this.a=n}function $b(n){this.a=n}function Lb(n){this.a=n}function Nb(n){this.a=n}function xb(n){this.a=n}function Db(n){this.a=n}function Rb(n){this.a=n}function _b(n){this.a=n}function Kb(n){this.a=n}function Fb(n){this.a=n}function Bb(n){this.b=n}function Hb(n){this.b=n}function qb(n){this.b=n}function Gb(n){this.a=n}function zb(n){this.a=n}function Ub(n){this.a=n}function Xb(n){this.c=n}function Wb(n){this.c=n}function Vb(n){this.c=n}function Qb(n){this.a=n}function Yb(n){this.a=n}function Jb(n){this.a=n}function Zb(n){this.a=n}function nw(n){this.a=n}function tw(n){this.a=n}function ew(n){this.a=n}function iw(n){this.a=n}function rw(n){this.a=n}function cw(n){this.a=n}function aw(n){this.a=n}function uw(n){this.a=n}function ow(n){this.a=n}function sw(n){this.a=n}function hw(n){this.a=n}function fw(n){this.a=n}function lw(n){this.a=n}function bw(n){this.a=n}function ww(n){this.a=n}function dw(n){this.a=n}function gw(n){this.a=n}function pw(n){this.a=n}function vw(n){this.a=n}function mw(n){this.a=n}function yw(n){this.a=n}function kw(n){this.a=n}function jw(n){this.a=n}function Ew(n){this.a=n}function Tw(n){this.a=n}function Mw(n){this.a=n}function Sw(n){this.a=n}function Pw(n){this.a=n}function Iw(n){this.a=n}function Cw(n){this.a=n}function Ow(n){this.a=n}function Aw(n){this.a=n}function $w(n){this.a=n}function Lw(n){this.a=n}function Nw(n){this.a=n}function xw(n){this.a=n}function Dw(n){this.a=n}function Rw(n){this.a=n}function _w(n){this.a=n}function Kw(n){this.a=n}function Fw(n){this.a=n}function Bw(n){this.e=n}function Hw(n){this.a=n}function qw(n){this.a=n}function Gw(n){this.a=n}function zw(n){this.a=n}function Uw(n){this.a=n}function Xw(n){this.a=n}function Ww(n){this.a=n}function Vw(n){this.a=n}function Qw(n){this.a=n}function Yw(n){this.a=n}function Jw(n){this.a=n}function Zw(n){this.a=n}function nd(n){this.a=n}function td(n){this.a=n}function ed(n){this.a=n}function id(n){this.a=n}function rd(n){this.a=n}function cd(n){this.a=n}function ad(n){this.a=n}function ud(n){this.a=n}function od(n){this.a=n}function sd(n){this.a=n}function hd(n){this.a=n}function fd(n){this.a=n}function ld(n){this.a=n}function bd(n){this.a=n}function wd(n){this.a=n}function dd(n){this.a=n}function gd(n){this.a=n}function pd(n){this.a=n}function vd(n){this.a=n}function md(n){this.a=n}function yd(n){this.a=n}function kd(n){this.a=n}function jd(n){this.a=n}function Ed(n){this.a=n}function Td(n){this.a=n}function Md(n){this.a=n}function Sd(n){this.a=n}function Pd(n){this.a=n}function Id(n){this.a=n}function Cd(n){this.a=n}function Od(n){this.a=n}function Ad(n){this.a=n}function $d(n){this.a=n}function Ld(n){this.a=n}function Nd(n){this.a=n}function xd(n){this.a=n}function Dd(n){this.a=n}function Rd(n){this.a=n}function _d(n){this.a=n}function Kd(n){this.a=n}function Fd(n){this.a=n}function Bd(n){this.c=n}function Hd(n){this.b=n}function qd(n){this.a=n}function Gd(n){this.a=n}function zd(n){this.a=n}function Ud(n){this.a=n}function Xd(n){this.a=n}function Wd(n){this.a=n}function Vd(n){this.a=n}function Qd(n){this.a=n}function Yd(n){this.a=n}function Jd(n){this.a=n}function Zd(n){this.a=n}function ng(n){this.a=n}function tg(n){this.a=n}function eg(n){this.a=n}function ig(n){this.a=n}function rg(n){this.a=n}function cg(n){this.a=n}function ag(n){this.a=n}function ug(n){this.a=n}function og(n){this.a=n}function sg(n){this.a=n}function hg(n){this.a=n}function fg(n){this.a=n}function lg(n){this.a=n}function bg(n){this.a=n}function wg(n){this.a=n}function dg(n){this.a=n}function gg(n){this.a=n}function pg(n){this.a=n}function vg(n){this.a=n}function mg(n){this.a=n}function yg(n){this.a=n}function kg(n){this.a=n}function jg(n){this.a=n}function Eg(n){this.a=n}function Tg(n){this.a=n}function Mg(n){this.a=n}function Sg(n){this.a=n}function Pg(n){this.a=n}function Ig(n){this.a=n}function Cg(n){this.a=n}function Og(n){this.a=n}function Ag(n){this.a=n}function $g(n){this.a=n}function Lg(n){this.a=n}function Ng(n){this.a=n}function xg(n){this.a=n}function Dg(n){this.a=n}function Rg(n){this.a=n}function _g(n){this.a=n}function Kg(n){this.a=n}function Fg(n){this.a=n}function Bg(n){this.a=n}function Hg(n){this.a=n}function qg(n){this.a=n}function Gg(n){this.a=n}function zg(n){this.a=n}function Ug(n){this.a=n}function Xg(n){this.a=n}function Wg(n){this.a=n}function Vg(n){this.a=n}function Qg(n){this.a=n}function Yg(n){this.a=n}function Jg(n){this.a=n}function Zg(n){this.a=n}function np(n){this.a=n}function tp(n){this.a=n}function ep(n){this.a=n}function ip(n){this.a=n}function rp(n){this.a=n}function cp(n){this.a=n}function ap(n){this.a=n}function up(n){this.b=n}function op(n){this.f=n}function sp(n){this.a=n}function hp(n){this.a=n}function fp(n){this.a=n}function lp(n){this.a=n}function bp(n){this.a=n}function wp(n){this.a=n}function dp(n){this.a=n}function gp(n){this.a=n}function pp(n){this.a=n}function vp(n){this.a=n}function mp(n){this.a=n}function yp(n){this.b=n}function kp(n){this.c=n}function jp(n){this.e=n}function Ep(n){this.a=n}function Tp(n){this.a=n}function Mp(n){this.a=n}function Sp(n){this.a=n}function Pp(n){this.a=n}function Ip(n){this.d=n}function Cp(n){this.a=n}function Op(n){this.a=n}function Ap(n){this.e=n}function $p(){this.a=0}function Lp(){DA(this)}function Np(){xA(this)}function xp(){$U(this)}function Dp(){wV(this)}function Rp(){Kh(this)}function _p(){this.c=L$t}function Kp(n,t){t.Wb(n)}function Fp(n,t){n.b+=t}function Bp(n){n.b=new ok}function Hp(n){return n.e}function qp(n){return n.a}function Gp(n){return n.a}function zp(n){return n.a}function Up(n){return n.a}function Xp(n){return n.a}function Wp(){return null}function Vp(){return null}function Qp(){aE(),dXn()}function Yp(n){n.b.tf(n.e)}function Jp(n,t){n.b=t-n.b}function Zp(n,t){n.a=t-n.a}function nv(n,t){t.ad(n.a)}function tv(n,t){qIn(t,n)}function ev(n,t,e){n.Od(e,t)}function iv(n,t){n.e=t,t.b=n}function rv(n){sK(),this.a=n}function cv(n){sK(),this.a=n}function av(n){sK(),this.a=n}function uv(n){WX(),this.a=n}function ov(n){PY(),ett.be(n)}function sv(){gN.call(this)}function hv(){gN.call(this)}function fv(){sv.call(this)}function lv(){sv.call(this)}function bv(){sv.call(this)}function wv(){sv.call(this)}function dv(){sv.call(this)}function gv(){sv.call(this)}function pv(){sv.call(this)}function vv(){sv.call(this)}function mv(){sv.call(this)}function yv(){sv.call(this)}function kv(){sv.call(this)}function jv(){this.a=this}function Ev(){this.Bb|=256}function Tv(){this.b=new PO}function Mv(){Mv=O,new xp}function Sv(){fv.call(this)}function Pv(n,t){n.length=t}function Iv(n,t){WB(n.a,t)}function Cv(n,t){USn(n.c,t)}function Ov(n,t){TU(n.b,t)}function Av(n,t){Cvn(n.a,t)}function $v(n,t){Oln(n.a,t)}function Lv(n,t){ban(n.e,t)}function Nv(n){AOn(n.c,n.b)}function xv(n,t){n.kc().Nb(t)}function Dv(n){this.a=gbn(n)}function Rv(){this.a=new xp}function _v(){this.a=new xp}function Kv(){this.a=new Np}function Fv(){this.a=new Np}function Bv(){this.a=new Np}function Hv(){this.a=new kn}function qv(){this.a=new k6}function Gv(){this.a=new bt}function zv(){this.a=new WT}function Uv(){this.a=new D0}function Xv(){this.a=new cZ}function Wv(){this.a=new AR}function Vv(){this.a=new Np}function Qv(){this.a=new Np}function Yv(){this.a=new Np}function Jv(){this.a=new Np}function Zv(){this.d=new Np}function nm(){this.a=new Rv}function tm(){this.a=new xp}function em(){this.b=new xp}function im(){this.b=new Np}function rm(){this.e=new Np}function cm(){this.d=new Np}function am(){this.a=new uf}function um(){Np.call(this)}function om(){Kv.call(this)}function sm(){NR.call(this)}function hm(){Qv.call(this)}function fm(){lm.call(this)}function lm(){Rp.call(this)}function bm(){Rp.call(this)}function wm(){bm.call(this)}function dm(){dY.call(this)}function gm(){dY.call(this)}function pm(){Wm.call(this)}function vm(){Wm.call(this)}function mm(){Wm.call(this)}function ym(){Vm.call(this)}function km(){YT.call(this)}function jm(){eo.call(this)}function Em(){eo.call(this)}function Tm(){ny.call(this)}function Mm(){ny.call(this)}function Sm(){xp.call(this)}function Pm(){xp.call(this)}function Im(){xp.call(this)}function Cm(){Rv.call(this)}function Om(){jin.call(this)}function Am(){Ev.call(this)}function $m(){OL.call(this)}function Lm(){OL.call(this)}function Nm(){xp.call(this)}function xm(){xp.call(this)}function Dm(){xp.call(this)}function Rm(){yo.call(this)}function _m(){yo.call(this)}function Km(){Rm.call(this)}function Fm(){Dh.call(this)}function Bm(n){dtn.call(this,n)}function Hm(n){dtn.call(this,n)}function qm(n){Qf.call(this,n)}function Gm(n){MT.call(this,n)}function zm(n){Gm.call(this,n)}function Um(n){MT.call(this,n)}function Xm(){this.a=new YT}function Wm(){this.a=new Rv}function Vm(){this.a=new xp}function Qm(){this.a=new Np}function Ym(){this.j=new Np}function Jm(){this.a=new Xa}function Zm(){this.a=new LE}function ny(){this.a=new mo}function ty(){ty=O,Knt=new xk}function ey(){ey=O,_nt=new Nk}function iy(){iy=O,Ont=new c}function ry(){ry=O,znt=new cN}function cy(n){Gm.call(this,n)}function ay(n){Gm.call(this,n)}function uy(n){d4.call(this,n)}function oy(n){d4.call(this,n)}function sy(n){V_.call(this,n)}function hy(n){ySn.call(this,n)}function fy(n){IT.call(this,n)}function ly(n){OT.call(this,n)}function by(n){OT.call(this,n)}function wy(n){OT.call(this,n)}function dy(n){fz.call(this,n)}function gy(n){dy.call(this,n)}function py(){Pl.call(this,{})}function vy(n){IL(),this.a=n}function my(n){n.b=null,n.c=0}function yy(n,t){n.e=t,Ixn(n,t)}function ky(n,t){n.a=t,aIn(n)}function jy(n,t,e){n.a[t.g]=e}function Ey(n,t,e){wjn(e,n,t)}function Ty(n,t){ZR(t.i,n.n)}function My(n,t){ssn(n).td(t)}function Sy(n,t){return n*n/t}function Py(n,t){return n.g-t.g}function Iy(n){return new Sl(n)}function Cy(n){return new GX(n)}function Oy(n){dy.call(this,n)}function Ay(n){dy.call(this,n)}function $y(n){dy.call(this,n)}function Ly(n){fz.call(this,n)}function Ny(n){Kcn(),this.a=n}function xy(n){aK(),this.a=n}function Dy(n){FG(),this.f=n}function Ry(n){FG(),this.f=n}function _y(n){dy.call(this,n)}function Ky(n){dy.call(this,n)}function Fy(n){dy.call(this,n)}function By(n){dy.call(this,n)}function Hy(n){dy.call(this,n)}function qy(n){return kW(n),n}function Gy(n){return kW(n),n}function zy(n){return kW(n),n}function Uy(n){return kW(n),n}function Xy(n){return kW(n),n}function Wy(n){return n.b==n.c}function Vy(n){return!!n&&n.b}function Qy(n){return!!n&&n.k}function Yy(n){return!!n&&n.j}function Jy(n){kW(n),this.a=n}function Zy(n){return Zon(n),n}function nk(n){vU(n,n.length)}function tk(n){dy.call(this,n)}function ek(n){dy.call(this,n)}function ik(n){dy.call(this,n)}function rk(n){dy.call(this,n)}function ck(n){dy.call(this,n)}function ak(n){dy.call(this,n)}function uk(n){ZN.call(this,n,0)}function ok(){o1.call(this,12,3)}function sk(){sk=O,ttt=new j}function hk(){hk=O,Ynt=new r}function fk(){fk=O,rtt=new g}function lk(){lk=O,htt=new v}function bk(){throw Hp(new pv)}function wk(){throw Hp(new pv)}function dk(){throw Hp(new pv)}function gk(){throw Hp(new pv)}function pk(){throw Hp(new pv)}function vk(){throw Hp(new pv)}function mk(){this.a=SD(yX(FWn))}function yk(n){sK(),this.a=yX(n)}function kk(n,t){n.Td(t),t.Sd(n)}function jk(n,t){n.a.ec().Mc(t)}function Ek(n,t,e){n.c.lf(t,e)}function Tk(n){Ay.call(this,n)}function Mk(n){Ky.call(this,n)}function Sk(){Ab.call(this,"")}function Pk(){Ab.call(this,"")}function Ik(){Ab.call(this,"")}function Ck(){Ab.call(this,"")}function Ok(n){Ay.call(this,n)}function Ak(n){Hb.call(this,n)}function $k(n){bN.call(this,n)}function Lk(n){Ak.call(this,n)}function Nk(){tl.call(this,null)}function xk(){tl.call(this,null)}function Dk(){Dk=O,PY()}function Rk(){Rk=O,ket=mEn()}function _k(n){return n.a?n.b:0}function Kk(n){return n.a?n.b:0}function Fk(n,t){return n.a-t.a}function Bk(n,t){return n.a-t.a}function Hk(n,t){return n.a-t.a}function qk(n,t){return m7(n,t)}function Gk(n,t){return gZ(n,t)}function zk(n,t){return t in n.a}function Uk(n,t){return n.f=t,n}function Xk(n,t){return n.b=t,n}function Wk(n,t){return n.c=t,n}function Vk(n,t){return n.g=t,n}function Qk(n,t){return n.a=t,n}function Yk(n,t){return n.f=t,n}function Jk(n,t){return n.k=t,n}function Zk(n,t){return n.a=t,n}function nj(n,t){return n.e=t,n}function tj(n,t){return n.e=t,n}function ej(n,t){return n.f=t,n}function ij(n,t){n.b=!0,n.d=t}function rj(n,t){n.b=new wA(t)}function cj(n,t,e){t.td(n.a[e])}function aj(n,t,e){t.we(n.a[e])}function uj(n,t){return n.b-t.b}function oj(n,t){return n.g-t.g}function sj(n,t){return n.s-t.s}function hj(n,t){return n?0:t-1}function fj(n,t){return n?0:t-1}function lj(n,t){return n?t-1:0}function bj(n,t){return t.Yf(n)}function wj(n,t){return n.b=t,n}function dj(n,t){return n.a=t,n}function gj(n,t){return n.c=t,n}function pj(n,t){return n.d=t,n}function vj(n,t){return n.e=t,n}function mj(n,t){return n.f=t,n}function yj(n,t){return n.a=t,n}function kj(n,t){return n.b=t,n}function jj(n,t){return n.c=t,n}function Ej(n,t){return n.c=t,n}function Tj(n,t){return n.b=t,n}function Mj(n,t){return n.d=t,n}function Sj(n,t){return n.e=t,n}function Pj(n,t){return n.f=t,n}function Ij(n,t){return n.g=t,n}function Cj(n,t){return n.a=t,n}function Oj(n,t){return n.i=t,n}function Aj(n,t){return n.j=t,n}function $j(n,t){return n.k=t,n}function Lj(n,t){return n.j=t,n}function Nj(n,t){KMn(),IZ(t,n)}function xj(n,t,e){GG(n.a,t,e)}function Dj(n){BV.call(this,n)}function Rj(n){BV.call(this,n)}function _j(n){nK.call(this,n)}function Kj(n){qbn.call(this,n)}function Fj(n){gtn.call(this,n)}function Bj(n){pQ.call(this,n)}function Hj(n){pQ.call(this,n)}function qj(){O$.call(this,"")}function Gj(){this.a=0,this.b=0}function zj(){this.b=0,this.a=0}function Uj(n,t){n.b=0,Nen(n,t)}function Xj(n,t){n.c=t,n.b=!0}function Wj(n,t){return n.c._b(t)}function Vj(n){return n.e&&n.e()}function Qj(n){return n?n.d:null}function Yj(n,t){return gfn(n.b,t)}function Jj(n){return n?n.g:null}function Zj(n){return n?n.i:null}function nE(n){return ED(n),n.o}function tE(){tE=O,dOt=Xkn()}function eE(){eE=O,gOt=oTn()}function iE(){iE=O,n$t=Vkn()}function rE(){rE=O,dLt=Wkn()}function cE(){cE=O,gLt=iIn()}function aE(){aE=O,lAt=cin()}function uE(){throw Hp(new pv)}function oE(){throw Hp(new pv)}function sE(){throw Hp(new pv)}function hE(){throw Hp(new pv)}function fE(){throw Hp(new pv)}function lE(){throw Hp(new pv)}function bE(n){this.a=new XT(n)}function wE(n){lUn(),DXn(this,n)}function dE(n){this.a=new Wz(n)}function gE(n,t){for(;n.ye(t););}function pE(n,t){for(;n.sd(t););}function vE(n,t){return n.a+=t,n}function mE(n,t){return n.a+=t,n}function yE(n,t){return n.a+=t,n}function kE(n,t){return n.a+=t,n}function jE(n){return EW(n),n.a}function EE(n){return n.b!=n.d.c}function TE(n){return n.l|n.m<<22}function ME(n,t){return n.d[t.p]}function SE(n,t){return Sxn(n,t)}function PE(n,t,e){n.splice(t,e)}function IE(n){n.c?NDn(n):xDn(n)}function CE(n){this.a=0,this.b=n}function OE(){this.a=new INn(ijt)}function AE(){this.b=new INn(qyt)}function $E(){this.b=new INn(WEt)}function LE(){this.b=new INn(WEt)}function NE(){throw Hp(new pv)}function xE(){throw Hp(new pv)}function DE(){throw Hp(new pv)}function RE(){throw Hp(new pv)}function _E(){throw Hp(new pv)}function KE(){throw Hp(new pv)}function FE(){throw Hp(new pv)}function BE(){throw Hp(new pv)}function HE(){throw Hp(new pv)}function qE(){throw Hp(new pv)}function GE(){throw Hp(new yv)}function zE(){throw Hp(new yv)}function UE(n){this.a=new XE(n)}function XE(n){Gin(this,n,OEn())}function WE(n){return!n||pW(n)}function VE(n){return-1!=WLt[n]}function QE(){0!=ctt&&(ctt=0),utt=-1}function YE(){null==PWn&&(PWn=[])}function JE(n,t){tAn(QQ(n.a),t)}function ZE(n,t){tAn(QQ(n.a),t)}function nT(n,t){HL.call(this,n,t)}function tT(n,t){nT.call(this,n,t)}function eT(n,t){this.b=n,this.c=t}function iT(n,t){this.b=n,this.a=t}function rT(n,t){this.a=n,this.b=t}function cT(n,t){this.a=n,this.b=t}function aT(n,t){this.a=n,this.b=t}function uT(n,t){this.a=n,this.b=t}function oT(n,t){this.a=n,this.b=t}function sT(n,t){this.a=n,this.b=t}function hT(n,t){this.a=n,this.b=t}function fT(n,t){this.a=n,this.b=t}function lT(n,t){this.b=n,this.a=t}function bT(n,t){this.b=n,this.a=t}function wT(n,t){this.b=n,this.a=t}function dT(n,t){this.b=n,this.a=t}function gT(n,t){this.f=n,this.g=t}function pT(n,t){this.e=n,this.d=t}function vT(n,t){this.g=n,this.i=t}function mT(n,t){this.a=n,this.b=t}function yT(n,t){this.a=n,this.f=t}function kT(n,t){this.b=n,this.c=t}function jT(n,t){this.a=n,this.b=t}function ET(n,t){this.a=n,this.b=t}function TT(n,t){this.a=n,this.b=t}function MT(n){aN(n.dc()),this.c=n}function ST(n){this.b=BB(yX(n),83)}function PT(n){this.a=BB(yX(n),83)}function IT(n){this.a=BB(yX(n),15)}function CT(n){this.a=BB(yX(n),15)}function OT(n){this.b=BB(yX(n),47)}function AT(){this.q=new e.Date}function $T(){$T=O,Btt=new A}function LT(){LT=O,bet=new P}function NT(n){return n.f.c+n.g.c}function xT(n,t){return n.b.Hc(t)}function DT(n,t){return n.b.Ic(t)}function RT(n,t){return n.b.Qc(t)}function _T(n,t){return n.b.Hc(t)}function KT(n,t){return n.c.uc(t)}function FT(n,t){return n.a._b(t)}function BT(n,t){return Nfn(n.c,t)}function HT(n,t){return hU(n.b,t)}function qT(n,t){return n>t&&t<OVn}function GT(n,t){return n.Gc(t),n}function zT(n,t){return Frn(n,t),n}function UT(n){return XX(),n?stt:ott}function XT(n){non.call(this,n,0)}function WT(){Wz.call(this,null)}function VT(){B8.call(this,null)}function QT(n){this.c=n,Ann(this)}function YT(){P$(this),yQ(this)}function JT(n,t){EW(n),n.a.Nb(t)}function ZT(n,t){return n.Gc(t),n}function nM(n,t){return n.a.f=t,n}function tM(n,t){return n.a.d=t,n}function eM(n,t){return n.a.g=t,n}function iM(n,t){return n.a.j=t,n}function rM(n,t){return n.a.a=t,n}function cM(n,t){return n.a.d=t,n}function aM(n,t){return n.a.e=t,n}function uM(n,t){return n.a.g=t,n}function oM(n,t){return n.a.f=t,n}function sM(n){return n.b=!1,n}function hM(){hM=O,Pet=new IO}function fM(){fM=O,Iet=new CO}function lM(){lM=O,Het=new U}function bM(){bM=O,vut=new _t}function wM(){wM=O,rct=new Cx}function dM(){dM=O,tit=new hn}function gM(){gM=O,kut=new Kt}function pM(){pM=O,sit=new dn}function vM(){vM=O,Gat=new yt}function mM(){mM=O,Fut=new Gj}function yM(){yM=O,zat=new Pt}function kM(){kM=O,Vat=new DG}function jM(){jM=O,hut=new Mt}function EM(){EM=O,But=new be}function TM(){TM=O,nst=new Ye}function MM(){MM=O,wst=new Lr}function SM(){SM=O,Qst=new rc}function PM(){PM=O,Wkt=new B2}function IM(){IM=O,XEt=new LM}function CM(){CM=O,QEt=new vD}function OM(){OM=O,GTt=new XW}function AM(){AM=O,Wpt=new Wu}function $M(){Sin(),this.c=new ok}function LM(){gT.call(this,H1n,0)}function NM(n,t){Jgn(n.c.b,t.c,t)}function xM(n,t){Jgn(n.c.c,t.b,t)}function DM(n,t,e){mZ(n.d,t.f,e)}function RM(n,t,e,i){Jpn(n,i,t,e)}function _M(n,t,e,i){uNn(i,n,t,e)}function KM(n,t,e,i){oUn(i,n,t,e)}function FM(n,t){return n.a=t.g,n}function BM(n,t){return ekn(n.a,t)}function HM(n){return n.b?n.b:n.a}function qM(n){return(n.c+n.a)/2}function GM(){GM=O,lOt=new to}function zM(){zM=O,IOt=new ho}function UM(){UM=O,RAt=new Pm}function XM(){XM=O,UAt=new Im}function WM(){WM=O,zAt=new Nm}function VM(){VM=O,ZAt=new Dm}function QM(){QM=O,N$t=new z$}function YM(){YM=O,x$t=new U$}function JM(){JM=O,rLt=new Ns}function ZM(){ZM=O,aLt=new xs}function nS(){nS=O,mAt=new xp}function tS(){tS=O,V$t=new Np}function eS(){eS=O,MNt=new _h}function iS(n){e.clearTimeout(n)}function rS(n){this.a=BB(yX(n),224)}function cS(n){return BB(n,42).cd()}function aS(n){return n.b<n.d.gc()}function uS(n,t){return IG(n.a,t)}function oS(n,t){return Vhn(n,t)>0}function sS(n,t){return Vhn(n,t)<0}function hS(n,t){return n.a.get(t)}function fS(n,t){return t.split(n)}function lS(n,t){return hU(n.e,t)}function bS(n){return kW(n),!1}function wS(n){w1.call(this,n,21)}function dS(n,t){KJ.call(this,n,t)}function gS(n,t){gT.call(this,n,t)}function pS(n,t){gT.call(this,n,t)}function vS(n){VX(),V_.call(this,n)}function mS(n,t){jG(n,n.length,t)}function yS(n,t){QU(n,n.length,t)}function kS(n,t,e){t.ud(n.a.Ge(e))}function jS(n,t,e){t.we(n.a.Fe(e))}function ES(n,t,e){t.td(n.a.Kb(e))}function TS(n,t,e){n.Mb(e)&&t.td(e)}function MS(n,t,e){n.splice(t,0,e)}function SS(n,t){return SN(n.e,t)}function PS(n,t){this.d=n,this.e=t}function IS(n,t){this.b=n,this.a=t}function CS(n,t){this.b=n,this.a=t}function OS(n,t){this.b=n,this.a=t}function AS(n,t){this.a=n,this.b=t}function $S(n,t){this.a=n,this.b=t}function LS(n,t){this.a=n,this.b=t}function NS(n,t){this.a=n,this.b=t}function xS(n,t){this.a=n,this.b=t}function DS(n,t){this.b=n,this.a=t}function RS(n,t){this.b=n,this.a=t}function _S(n,t){gT.call(this,n,t)}function KS(n,t){gT.call(this,n,t)}function FS(n,t){gT.call(this,n,t)}function BS(n,t){gT.call(this,n,t)}function HS(n,t){gT.call(this,n,t)}function qS(n,t){gT.call(this,n,t)}function GS(n,t){gT.call(this,n,t)}function zS(n,t){gT.call(this,n,t)}function US(n,t){gT.call(this,n,t)}function XS(n,t){gT.call(this,n,t)}function WS(n,t){gT.call(this,n,t)}function VS(n,t){gT.call(this,n,t)}function QS(n,t){gT.call(this,n,t)}function YS(n,t){gT.call(this,n,t)}function JS(n,t){gT.call(this,n,t)}function ZS(n,t){gT.call(this,n,t)}function nP(n,t){gT.call(this,n,t)}function tP(n,t){gT.call(this,n,t)}function eP(n,t){this.a=n,this.b=t}function iP(n,t){this.a=n,this.b=t}function rP(n,t){this.a=n,this.b=t}function cP(n,t){this.a=n,this.b=t}function aP(n,t){this.a=n,this.b=t}function uP(n,t){this.a=n,this.b=t}function oP(n,t){this.a=n,this.b=t}function sP(n,t){this.a=n,this.b=t}function hP(n,t){this.a=n,this.b=t}function fP(n,t){this.b=n,this.a=t}function lP(n,t){this.b=n,this.a=t}function bP(n,t){this.b=n,this.a=t}function wP(n,t){this.b=n,this.a=t}function dP(n,t){this.c=n,this.d=t}function gP(n,t){this.e=n,this.d=t}function pP(n,t){this.a=n,this.b=t}function vP(n,t){this.b=t,this.c=n}function mP(n,t){gT.call(this,n,t)}function yP(n,t){gT.call(this,n,t)}function kP(n,t){gT.call(this,n,t)}function jP(n,t){gT.call(this,n,t)}function EP(n,t){gT.call(this,n,t)}function TP(n,t){gT.call(this,n,t)}function MP(n,t){gT.call(this,n,t)}function SP(n,t){gT.call(this,n,t)}function PP(n,t){gT.call(this,n,t)}function IP(n,t){gT.call(this,n,t)}function CP(n,t){gT.call(this,n,t)}function OP(n,t){gT.call(this,n,t)}function AP(n,t){gT.call(this,n,t)}function $P(n,t){gT.call(this,n,t)}function LP(n,t){gT.call(this,n,t)}function NP(n,t){gT.call(this,n,t)}function xP(n,t){gT.call(this,n,t)}function DP(n,t){gT.call(this,n,t)}function RP(n,t){gT.call(this,n,t)}function _P(n,t){gT.call(this,n,t)}function KP(n,t){gT.call(this,n,t)}function FP(n,t){gT.call(this,n,t)}function BP(n,t){gT.call(this,n,t)}function HP(n,t){gT.call(this,n,t)}function qP(n,t){gT.call(this,n,t)}function GP(n,t){gT.call(this,n,t)}function zP(n,t){gT.call(this,n,t)}function UP(n,t){gT.call(this,n,t)}function XP(n,t){gT.call(this,n,t)}function WP(n,t){gT.call(this,n,t)}function VP(n,t){gT.call(this,n,t)}function QP(n,t){gT.call(this,n,t)}function YP(n,t){gT.call(this,n,t)}function JP(n,t){gT.call(this,n,t)}function ZP(n,t){this.b=n,this.a=t}function nI(n,t){this.a=n,this.b=t}function tI(n,t){this.a=n,this.b=t}function eI(n,t){this.a=n,this.b=t}function iI(n,t){this.a=n,this.b=t}function rI(n,t){gT.call(this,n,t)}function cI(n,t){gT.call(this,n,t)}function aI(n,t){this.b=n,this.d=t}function uI(n,t){gT.call(this,n,t)}function oI(n,t){gT.call(this,n,t)}function sI(n,t){this.a=n,this.b=t}function hI(n,t){this.a=n,this.b=t}function fI(n,t){gT.call(this,n,t)}function lI(n,t){gT.call(this,n,t)}function bI(n,t){gT.call(this,n,t)}function wI(n,t){gT.call(this,n,t)}function dI(n,t){gT.call(this,n,t)}function gI(n,t){gT.call(this,n,t)}function pI(n,t){gT.call(this,n,t)}function vI(n,t){gT.call(this,n,t)}function mI(n,t){gT.call(this,n,t)}function yI(n,t){gT.call(this,n,t)}function kI(n,t){gT.call(this,n,t)}function jI(n,t){gT.call(this,n,t)}function EI(n,t){gT.call(this,n,t)}function TI(n,t){gT.call(this,n,t)}function MI(n,t){gT.call(this,n,t)}function SI(n,t){gT.call(this,n,t)}function PI(n,t){return SN(n.c,t)}function II(n,t){return SN(t.b,n)}function CI(n,t){return-n.b.Je(t)}function OI(n,t){return SN(n.g,t)}function AI(n,t){gT.call(this,n,t)}function $I(n,t){gT.call(this,n,t)}function LI(n,t){this.a=n,this.b=t}function NI(n,t){this.a=n,this.b=t}function xI(n,t){this.a=n,this.b=t}function DI(n,t){gT.call(this,n,t)}function RI(n,t){gT.call(this,n,t)}function _I(n,t){gT.call(this,n,t)}function KI(n,t){gT.call(this,n,t)}function FI(n,t){gT.call(this,n,t)}function BI(n,t){gT.call(this,n,t)}function HI(n,t){gT.call(this,n,t)}function qI(n,t){gT.call(this,n,t)}function GI(n,t){gT.call(this,n,t)}function zI(n,t){gT.call(this,n,t)}function UI(n,t){gT.call(this,n,t)}function XI(n,t){gT.call(this,n,t)}function WI(n,t){gT.call(this,n,t)}function VI(n,t){gT.call(this,n,t)}function QI(n,t){gT.call(this,n,t)}function YI(n,t){gT.call(this,n,t)}function JI(n,t){this.a=n,this.b=t}function ZI(n,t){this.a=n,this.b=t}function nC(n,t){this.a=n,this.b=t}function tC(n,t){this.a=n,this.b=t}function eC(n,t){this.a=n,this.b=t}function iC(n,t){this.a=n,this.b=t}function rC(n,t){this.a=n,this.b=t}function cC(n,t){gT.call(this,n,t)}function aC(n,t){this.a=n,this.b=t}function uC(n,t){this.a=n,this.b=t}function oC(n,t){this.a=n,this.b=t}function sC(n,t){this.a=n,this.b=t}function hC(n,t){this.a=n,this.b=t}function fC(n,t){this.a=n,this.b=t}function lC(n,t){this.b=n,this.a=t}function bC(n,t){this.b=n,this.a=t}function wC(n,t){this.b=n,this.a=t}function dC(n,t){this.b=n,this.a=t}function gC(n,t){this.a=n,this.b=t}function pC(n,t){this.a=n,this.b=t}function vC(n,t){JLn(n.a,BB(t,56))}function mC(n,t){v7(n.a,BB(t,11))}function yC(n,t){return hH(),t!=n}function kC(){return Rk(),new ket}function jC(){qZ(),this.b=new Rv}function EC(){dxn(),this.a=new Rv}function TC(){_Z(),_G.call(this)}function MC(n,t){gT.call(this,n,t)}function SC(n,t){this.a=n,this.b=t}function PC(n,t){this.a=n,this.b=t}function IC(n,t){this.a=n,this.b=t}function CC(n,t){this.a=n,this.b=t}function OC(n,t){this.a=n,this.b=t}function AC(n,t){this.a=n,this.b=t}function $C(n,t){this.d=n,this.b=t}function LC(n,t){this.d=n,this.e=t}function NC(n,t){this.f=n,this.c=t}function xC(n,t){this.b=n,this.c=t}function DC(n,t){this.i=n,this.g=t}function RC(n,t){this.e=n,this.a=t}function _C(n,t){this.a=n,this.b=t}function KC(n,t){n.i=null,arn(n,t)}function FC(n,t){n&&VW(hAt,n,t)}function BC(n,t){return rdn(n.a,t)}function HC(n){return adn(n.c,n.b)}function qC(n){return n?n.dd():null}function GC(n){return null==n?null:n}function zC(n){return typeof n===$Wn}function UC(n){return typeof n===LWn}function XC(n){return typeof n===NWn}function WC(n,t){return n.Hd().Xb(t)}function VC(n,t){return Qcn(n.Kc(),t)}function QC(n,t){return 0==Vhn(n,t)}function YC(n,t){return Vhn(n,t)>=0}function JC(n,t){return 0!=Vhn(n,t)}function ZC(n){return""+(kW(n),n)}function nO(n,t){return n.substr(t)}function tO(n){return zbn(n),n.d.gc()}function eO(n){return zOn(n,n.c),n}function iO(n){return JH(null==n),n}function rO(n,t){return n.a+=""+t,n}function cO(n,t){return n.a+=""+t,n}function aO(n,t){return n.a+=""+t,n}function uO(n,t){return n.a+=""+t,n}function oO(n,t){return n.a+=""+t,n}function sO(n,t){return n.a+=""+t,n}function hO(n,t){r5(n,t,n.a,n.a.a)}function fO(n,t){r5(n,t,n.c.b,n.c)}function lO(n,t,e){_jn(t,RPn(n,e))}function bO(n,t,e){_jn(t,RPn(n,e))}function wO(n,t){Tnn(new AL(n),t)}function dO(n,t){n.q.setTime(j2(t))}function gO(n,t){zz.call(this,n,t)}function pO(n,t){zz.call(this,n,t)}function vO(n,t){zz.call(this,n,t)}function mO(n){$U(this),Tcn(this,n)}function yO(n){return l1(n,0),null}function kO(n){return n.a=0,n.b=0,n}function jO(n,t){return n.a=t.g+1,n}function EO(n,t){return 2==n.j[t.p]}function TO(n){return sX(BB(n,79))}function MO(){MO=O,Art=lhn(tpn())}function SO(){SO=O,Zot=lhn(ENn())}function PO(){this.b=new XT(etn(12))}function IO(){this.b=0,this.a=!1}function CO(){this.b=0,this.a=!1}function OO(n){this.a=n,Bh.call(this)}function AO(n){this.a=n,Bh.call(this)}function $O(n,t){iR.call(this,n,t)}function LO(n,t){t_.call(this,n,t)}function NO(n,t){DC.call(this,n,t)}function xO(n,t){Aan.call(this,n,t)}function DO(n,t){QN.call(this,n,t)}function RO(n,t){nS(),VW(mAt,n,t)}function _O(n,t){return fx(n.a,0,t)}function KO(n,t){return n.a.a.a.cc(t)}function FO(n,t){return GC(n)===GC(t)}function BO(n,t){return Pln(n.a,t.a)}function HO(n,t){return E$(n.a,t.a)}function qO(n,t){return FU(n.a,t.a)}function GO(n,t){return n.indexOf(t)}function zO(n,t){return n==t?0:n?1:-1}function UO(n){return n<10?"0"+n:""+n}function XO(n){return yX(n),new OO(n)}function WO(n){return M$(n.l,n.m,n.h)}function VO(n){return IJ((kW(n),n))}function QO(n){return IJ((kW(n),n))}function YO(n,t){return E$(n.g,t.g)}function JO(n){return typeof n===LWn}function ZO(n){return n==Zat||n==eut}function nA(n){return n==Zat||n==nut}function tA(n){return E7(n.b.b,n,0)}function eA(n){this.a=kC(),this.b=n}function iA(n){this.a=kC(),this.b=n}function rA(n,t){return WB(n.a,t),t}function cA(n,t){return WB(n.c,t),n}function aA(n,t){return Jcn(n.a,t),n}function uA(n,t){return GK(),t.a+=n}function oA(n,t){return GK(),t.a+=n}function sA(n,t){return GK(),t.c+=n}function hA(n,t){z9(n,0,n.length,t)}function fA(){ew.call(this,new v4)}function lA(){uG.call(this,0,0,0,0)}function bA(){UV.call(this,0,0,0,0)}function wA(n){this.a=n.a,this.b=n.b}function dA(n){return n==KPt||n==FPt}function gA(n){return n==HPt||n==_Pt}function pA(n){return n==fvt||n==hvt}function vA(n){return n!=QIt&&n!=YIt}function mA(n){return n.Lg()&&n.Mg()}function yA(n){return mV(BB(n,118))}function kA(n){return Jcn(new B2,n)}function jA(n,t){return new Aan(t,n)}function EA(n,t){return new Aan(t,n)}function TA(n,t,e){jen(n,t),Een(n,e)}function MA(n,t,e){Sen(n,t),Men(n,e)}function SA(n,t,e){Pen(n,t),Ien(n,e)}function PA(n,t,e){Ten(n,t),Oen(n,e)}function IA(n,t,e){Cen(n,t),Aen(n,e)}function CA(n,t){Dsn(n,t),xen(n,n.D)}function OA(n){NC.call(this,n,!0)}function AA(n,t,e){ND.call(this,n,t,e)}function $A(n){ODn(),san.call(this,n)}function LA(){gS.call(this,"Head",1)}function NA(){gS.call(this,"Tail",3)}function xA(n){n.c=x8(Ant,HWn,1,0,5,1)}function DA(n){n.a=x8(Ant,HWn,1,8,5,1)}function RA(n){Otn(n.xf(),new Sw(n))}function _A(n){return null!=n?nsn(n):0}function KA(n,t){return Itn(t,WJ(n))}function FA(n,t){return Itn(t,WJ(n))}function BA(n,t){return n[n.length]=t}function HA(n,t){return n[n.length]=t}function qA(n){return FB(n.b.Kc(),n.a)}function GA(n,t){return Uin(PX(n.d),t)}function zA(n,t){return Uin(PX(n.g),t)}function UA(n,t){return Uin(PX(n.j),t)}function XA(n,t){iR.call(this,n.b,t)}function WA(n){uG.call(this,n,n,n,n)}function VA(n){return n.b&&VBn(n),n.a}function QA(n){return n.b&&VBn(n),n.c}function YA(n,t){Qet||(n.b=t)}function JA(n,t,e){return $X(n,t,e),e}function ZA(n,t,e){$X(n.c[t.g],t.g,e)}function n$(n,t,e){BB(n.c,69).Xh(t,e)}function t$(n,t,e){SA(e,e.i+n,e.j+t)}function e$(n,t){f9(a4(n.a),e1(t))}function i$(n,t){f9(H7(n.a),i1(t))}function r$(n){wWn(),Ap.call(this,n)}function c$(n){return null==n?0:nsn(n)}function a$(){a$=O,syt=new Hbn(oIt)}function u$(){u$=O,new o$,new Np}function o$(){new xp,new xp,new xp}function s$(){s$=O,Mv(),itt=new xp}function h$(){h$=O,e.Math.log(2)}function f$(){f$=O,zM(),R$t=IOt}function l$(){throw Hp(new tk(Tnt))}function b$(){throw Hp(new tk(Tnt))}function w$(){throw Hp(new tk(Mnt))}function d$(){throw Hp(new tk(Mnt))}function g$(n){this.a=n,QB.call(this,n)}function p$(n){this.a=n,ST.call(this,n)}function v$(n){this.a=n,ST.call(this,n)}function m$(n,t){yG(n.c,n.c.length,t)}function y$(n){return n.a<n.c.c.length}function k$(n){return n.a<n.c.a.length}function j$(n,t){return n.a?n.b:t.De()}function E$(n,t){return n<t?-1:n>t?1:0}function T$(n,t){return Vhn(n,t)>0?n:t}function M$(n,t,e){return{l:n,m:t,h:e}}function S$(n,t){null!=n.a&&mC(t,n.a)}function P$(n){n.a=new $,n.c=new $}function I$(n){this.b=n,this.a=new Np}function C$(n){this.b=new et,this.a=n}function O$(n){LR.call(this),this.a=n}function A$(){gS.call(this,"Range",2)}function $$(){tjn(),this.a=new INn(Uat)}function L$(n,t){yX(t),EV(n).Jc(new b)}function N$(n,t){return BZ(),t.n.b+=n}function x$(n,t,e){return VW(n.g,e,t)}function D$(n,t,e){return VW(n.k,e,t)}function R$(n,t){return VW(n.a,t.a,t)}function _$(n,t,e){return Cdn(t,e,n.c)}function K$(n){return new xI(n.c,n.d)}function F$(n){return new xI(n.c,n.d)}function B$(n){return new xI(n.a,n.b)}function H$(n,t){return tzn(n.a,t,null)}function q$(n){SZ(n,null),MZ(n,null)}function G$(n){WZ(n,null),VZ(n,null)}function z$(){QN.call(this,null,null)}function U$(){YN.call(this,null,null)}function X$(n){this.a=n,xp.call(this)}function W$(n){this.b=(SQ(),new Xb(n))}function V$(n){n.j=x8(Ftt,sVn,310,0,0,1)}function Q$(n,t,e){n.c.Vc(t,BB(e,133))}function Y$(n,t,e){n.c.ji(t,BB(e,133))}function J$(n,t){sqn(n),n.Gc(BB(t,15))}function Z$(n,t){return Bqn(n.c,n.b,t)}function nL(n,t){return new pN(n.Kc(),t)}function tL(n,t){return-1!=Fun(n.Kc(),t)}function eL(n,t){return null!=n.a.Bc(t)}function iL(n){return n.Ob()?n.Pb():null}function rL(n){return Bdn(n,0,n.length)}function cL(n,t){return null!=n&&Qpn(n,t)}function aL(n,t){n.q.setHours(t),lBn(n,t)}function uL(n,t){n.c&&(RH(t),kJ(t))}function oL(n,t,e){BB(n.Kb(e),164).Nb(t)}function sL(n,t,e){return HGn(n,t,e),e}function hL(n,t,e){n.a=1502^t,n.b=e^aYn}function fL(n,t,e){return n.a[t.g][e.g]}function lL(n,t){return n.a[t.c.p][t.p]}function bL(n,t){return n.e[t.c.p][t.p]}function wL(n,t){return n.c[t.c.p][t.p]}function dL(n,t){return n.j[t.p]=pLn(t)}function gL(n,t){return f6(n.f,t.tg())}function pL(n,t){return f6(n.b,t.tg())}function vL(n,t){return n.a<X_(t)?-1:1}function mL(n,t,e){return e?0!=t:t!=n-1}function yL(n,t,e){return n.a=t,n.b=e,n}function kL(n,t){return n.a*=t,n.b*=t,n}function jL(n,t,e){return $X(n.g,t,e),e}function EL(n,t,e,i){$X(n.a[t.g],e.g,i)}function TL(n,t){Kx(t,n.a.a.a,n.a.a.b)}function ML(n){n.a=BB(yan(n.b.a,4),126)}function SL(n){n.a=BB(yan(n.b.a,4),126)}function PL(n){OY(n,i8n),HLn(n,CUn(n))}function IL(){IL=O,Set=new vy(null)}function CL(){(CL=O)(),$et=new z}function OL(){this.Bb|=256,this.Bb|=512}function AL(n){this.i=n,this.f=this.i.j}function $L(n,t,e){yH.call(this,n,t,e)}function LL(n,t,e){$L.call(this,n,t,e)}function NL(n,t,e){$L.call(this,n,t,e)}function xL(n,t,e){LL.call(this,n,t,e)}function DL(n,t,e){yH.call(this,n,t,e)}function RL(n,t,e){yH.call(this,n,t,e)}function _L(n,t,e){MH.call(this,n,t,e)}function KL(n,t,e){MH.call(this,n,t,e)}function FL(n,t,e){_L.call(this,n,t,e)}function BL(n,t,e){DL.call(this,n,t,e)}function HL(n,t){this.a=n,ST.call(this,t)}function qL(n,t){this.a=n,uk.call(this,t)}function GL(n,t){this.a=n,uk.call(this,t)}function zL(n,t){this.a=n,uk.call(this,t)}function UL(n){this.a=n,hl.call(this,n.d)}function XL(n){this.c=n,this.a=this.c.a}function WL(n,t){this.a=t,uk.call(this,n)}function VL(n,t){this.a=t,d4.call(this,n)}function QL(n,t){this.a=n,d4.call(this,t)}function YL(n,t){return wz(bz(n.c)).Xb(t)}function JL(n,t){return ebn(n,new Ik,t).a}function ZL(n,t){return yX(t),new nN(n,t)}function nN(n,t){this.a=t,OT.call(this,n)}function tN(n){this.b=n,this.a=this.b.a.e}function eN(n){n.b.Qb(),--n.d.f.d,$G(n.d)}function iN(n){tl.call(this,BB(yX(n),35))}function rN(n){tl.call(this,BB(yX(n),35))}function cN(){gT.call(this,"INSTANCE",0)}function aN(n){if(!n)throw Hp(new wv)}function uN(n){if(!n)throw Hp(new dv)}function oN(n){if(!n)throw Hp(new yv)}function sN(){sN=O,JM(),cLt=new Ff}function hN(){hN=O,ptt=!1,vtt=!0}function fN(n){Ab.call(this,(kW(n),n))}function lN(n){Ab.call(this,(kW(n),n))}function bN(n){Hb.call(this,n),this.a=n}function wN(n){qb.call(this,n),this.a=n}function dN(n){Ak.call(this,n),this.a=n}function gN(){V$(this),jQ(this),this._d()}function pN(n,t){this.a=t,OT.call(this,n)}function vN(n,t){return new _Pn(n.a,n.b,t)}function mN(n,t){return n.lastIndexOf(t)}function yN(n,t,e){return n.indexOf(t,e)}function kN(n){return null==n?zWn:Bbn(n)}function jN(n){return null==n?null:n.name}function EN(n){return null!=n.a?n.a:null}function TN(n){return EE(n.a)?u1(n):null}function MN(n,t){return null!=$J(n.a,t)}function SN(n,t){return!!t&&n.b[t.g]==t}function PN(n){return n.$H||(n.$H=++cit)}function IN(n){return n.l+n.m*CQn+n.h*OQn}function CN(n,t){return WB(t.a,n.a),n.a}function ON(n,t){return WB(t.b,n.a),n.a}function AN(n,t){return WB(t.a,n.a),n.a}function $N(n){return Px(null!=n.a),n.a}function LN(n){ew.call(this,new q8(n))}function NN(n,t){Sgn.call(this,n,t,null)}function xN(n){this.a=n,Bb.call(this,n)}function DN(){DN=O,Lrt=new iR(dJn,0)}function RN(n,t){return++n.b,WB(n.a,t)}function _N(n,t){return++n.b,y7(n.a,t)}function KN(n,t){return Pln(n.n.a,t.n.a)}function FN(n,t){return Pln(n.c.d,t.c.d)}function BN(n,t){return Pln(n.c.c,t.c.c)}function HN(n,t){return BB(h6(n.b,t),15)}function qN(n,t){return n.n.b=(kW(t),t)}function GN(n,t){return n.n.b=(kW(t),t)}function zN(n){return y$(n.a)||y$(n.b)}function UN(n,t,e){return p3(n,t,e,n.b)}function XN(n,t,e){return p3(n,t,e,n.c)}function WN(n,t,e){BB(D7(n,t),21).Fc(e)}function VN(n,t,e){Oln(n.a,e),Cvn(n.a,t)}function QN(n,t){QM(),this.a=n,this.b=t}function YN(n,t){YM(),this.b=n,this.c=t}function JN(n,t){FG(),this.f=t,this.d=n}function ZN(n,t){w6(t,n),this.d=n,this.c=t}function nx(n){var t;t=n.a,n.a=n.b,n.b=t}function tx(n){return GK(),!!n&&!n.dc()}function ex(n){return new h4(3,n)}function ix(n,t){return new b_(n,n.gc(),t)}function rx(n){return ry(),Inn((DZ(),Xnt),n)}function cx(n){this.d=n,AL.call(this,n)}function ax(n){this.c=n,AL.call(this,n)}function ux(n){this.c=n,cx.call(this,n)}function ox(){MM(),this.b=new yd(this)}function sx(n){return lin(n,AVn),new J6(n)}function hx(n){return PY(),parseInt(n)||-1}function fx(n,t,e){return n.substr(t,e-t)}function lx(n,t,e){return yN(n,YTn(t),e)}function bx(n){return VU(n.c,n.c.length)}function wx(n){return null!=n.f?n.f:""+n.g}function dx(n){return null!=n.f?n.f:""+n.g}function gx(n){return Px(0!=n.b),n.a.a.c}function px(n){return Px(0!=n.b),n.c.b.c}function vx(n){cL(n,150)&&BB(n,150).Gh()}function mx(n){return n.b=BB(mQ(n.a),42)}function yx(n){hM(),this.b=n,this.a=!0}function kx(n){fM(),this.b=n,this.a=!0}function jx(n){n.d=new Ix(n),n.e=new xp}function Ex(n){if(!n)throw Hp(new vv)}function Tx(n){if(!n)throw Hp(new wv)}function Mx(n){if(!n)throw Hp(new dv)}function Sx(n){if(!n)throw Hp(new lv)}function Px(n){if(!n)throw Hp(new yv)}function Ix(n){nH.call(this,n,null,null)}function Cx(){gT.call(this,"POLYOMINO",0)}function Ox(n,t,e,i){sz.call(this,n,t,e,i)}function Ax(n,t){return KMn(),JCn(n,t.e,t)}function $x(n,t,e){return AM(),e.qg(n,t)}function Lx(n,t){return!!n.q&&hU(n.q,t)}function Nx(n,t){return n>0?t*t/n:t*t*100}function xx(n,t){return n>0?t/(n*n):100*t}function Dx(n,t,e){return WB(t,own(n,e))}function Rx(n,t,e){x9(),n.Xe(t)&&e.td(n)}function _x(n,t,e){n.Zc(t).Rb(e)}function Kx(n,t,e){return n.a+=t,n.b+=e,n}function Fx(n,t,e){return n.a*=t,n.b*=e,n}function Bx(n,t,e){return n.a-=t,n.b-=e,n}function Hx(n,t){return n.a=t.a,n.b=t.b,n}function qx(n){return n.a=-n.a,n.b=-n.b,n}function Gx(n){this.c=n,this.a=1,this.b=1}function zx(n){this.c=n,Pen(n,0),Ien(n,0)}function Ux(n){YT.call(this),nin(this,n)}function Xx(n){RXn(),Bp(this),this.mf(n)}function Wx(n,t){QM(),QN.call(this,n,t)}function Vx(n,t){YM(),YN.call(this,n,t)}function Qx(n,t){YM(),YN.call(this,n,t)}function Yx(n,t){YM(),Vx.call(this,n,t)}function Jx(n,t,e){y9.call(this,n,t,e,2)}function Zx(n,t){f$(),cG.call(this,n,t)}function nD(n,t){f$(),Zx.call(this,n,t)}function tD(n,t){f$(),Zx.call(this,n,t)}function eD(n,t){f$(),tD.call(this,n,t)}function iD(n,t){f$(),cG.call(this,n,t)}function rD(n,t){f$(),iD.call(this,n,t)}function cD(n,t){f$(),cG.call(this,n,t)}function aD(n,t){return n.c.Fc(BB(t,133))}function uD(n,t,e){return NHn(F7(n,t),e)}function oD(n,t,e){return t.Qk(n.e,n.c,e)}function sD(n,t,e){return t.Rk(n.e,n.c,e)}function hD(n,t){return tfn(n.e,BB(t,49))}function fD(n,t,e){sln(H7(n.a),t,i1(e))}function lD(n,t,e){sln(a4(n.a),t,e1(e))}function bD(n,t){t.$modCount=n.$modCount}function wD(){wD=O,Vkt=new up("root")}function dD(){dD=O,pAt=new Tm,new Mm}function gD(){this.a=new pJ,this.b=new pJ}function pD(){jin.call(this),this.Bb|=BQn}function vD(){gT.call(this,"GROW_TREE",0)}function mD(n){return null==n?null:wUn(n)}function yD(n){return null==n?null:LSn(n)}function kD(n){return null==n?null:Bbn(n)}function jD(n){return null==n?null:Bbn(n)}function ED(n){null==n.o&&g$n(n)}function TD(n){return JH(null==n||zC(n)),n}function MD(n){return JH(null==n||UC(n)),n}function SD(n){return JH(null==n||XC(n)),n}function PD(n){this.q=new e.Date(j2(n))}function ID(n,t){this.c=n,pT.call(this,n,t)}function CD(n,t){this.a=n,ID.call(this,n,t)}function OD(n,t){this.d=n,Mb(this),this.b=t}function AD(n,t){B8.call(this,n),this.a=t}function $D(n,t){B8.call(this,n),this.a=t}function LD(n){qwn.call(this,0,0),this.f=n}function ND(n,t,e){W6.call(this,n,t,e,null)}function xD(n,t,e){W6.call(this,n,t,e,null)}function DD(n,t,e){return n.ue(t,e)<=0?e:t}function RD(n,t,e){return n.ue(t,e)<=0?t:e}function _D(n,t){return BB(lnn(n.b,t),149)}function KD(n,t){return BB(lnn(n.c,t),229)}function FD(n){return BB(xq(n.a,n.b),287)}function BD(n){return new xI(n.c,n.d+n.a)}function HD(n){return BZ(),pA(BB(n,197))}function qD(){qD=O,$rt=nbn((mdn(),KCt))}function GD(n,t){t.a?Fxn(n,t):MN(n.a,t.b)}function zD(n,t){Qet||WB(n.a,t)}function UD(n,t){return mM(),wan(t.d.i,n)}function XD(n,t){return Crn(),new c_n(t,n)}function WD(n,t){return OY(t,uJn),n.f=t,n}function VD(n,t,e){return e=TKn(n,t,3,e)}function QD(n,t,e){return e=TKn(n,t,6,e)}function YD(n,t,e){return e=TKn(n,t,9,e)}function JD(n,t,e){++n.j,n.Ki(),L8(n,t,e)}function ZD(n,t,e){++n.j,n.Hi(t,n.oi(t,e))}function nR(n,t,e){n.Zc(t).Rb(e)}function tR(n,t,e){return ZBn(n.c,n.b,t,e)}function eR(n,t){return(t&DWn)%n.d.length}function iR(n,t){up.call(this,n),this.a=t}function rR(n,t){kp.call(this,n),this.a=t}function cR(n,t){kp.call(this,n),this.a=t}function aR(n,t){this.c=n,gtn.call(this,t)}function uR(n,t){this.a=n,yp.call(this,t)}function oR(n,t){this.a=n,yp.call(this,t)}function sR(n){this.a=(lin(n,AVn),new J6(n))}function hR(n){this.a=(lin(n,AVn),new J6(n))}function fR(n){return!n.a&&(n.a=new w),n.a}function lR(n){return n>8?0:n+1}function bR(n,t){return hN(),n==t?0:n?1:-1}function wR(n,t,e){return mG(n,BB(t,22),e)}function dR(n,t,e){return n.apply(t,e)}function gR(n,t,e){return n.a+=Bdn(t,0,e),n}function pR(n,t){var e;return e=n.e,n.e=t,e}function vR(n,t){n[iYn].call(n,t)}function mR(n,t){n[iYn].call(n,t)}function yR(n,t){n.a.Vc(n.b,t),++n.b,n.c=-1}function kR(n){$U(n.e),n.d.b=n.d,n.d.a=n.d}function jR(n){n.b?jR(n.b):n.f.c.zc(n.e,n.d)}function ER(n,t,e){dM(),Cl(n,t.Ce(n.a,e))}function TR(n,t){return Qj(Mdn(n.a,t,!0))}function MR(n,t){return Qj(Sdn(n.a,t,!0))}function SR(n,t){return qk(new Array(t),n)}function PR(n){return String.fromCharCode(n)}function IR(n){return null==n?null:n.message}function CR(){this.a=new Np,this.b=new Np}function OR(){this.a=new bt,this.b=new Tv}function AR(){this.b=new Gj,this.c=new Np}function $R(){this.d=new Gj,this.e=new Gj}function LR(){this.n=new Gj,this.o=new Gj}function NR(){this.n=new bm,this.i=new bA}function xR(){this.a=new nf,this.b=new uc}function DR(){this.a=new Np,this.d=new Np}function RR(){this.b=new Rv,this.a=new Rv}function _R(){this.b=new xp,this.a=new xp}function KR(){this.b=new AE,this.a=new da}function FR(){NR.call(this),this.a=new Gj}function BR(n){Oan.call(this,n,(Z9(),Net))}function HR(n,t,e,i){uG.call(this,n,t,e,i)}function qR(n,t,e){null!=e&&Lin(t,Amn(n,e))}function GR(n,t,e){null!=e&&Nin(t,Amn(n,e))}function zR(n,t,e){return e=TKn(n,t,11,e)}function UR(n,t){return n.a+=t.a,n.b+=t.b,n}function XR(n,t){return n.a-=t.a,n.b-=t.b,n}function WR(n,t){return n.n.a=(kW(t),t+10)}function VR(n,t){return n.n.a=(kW(t),t+10)}function QR(n,t){return t==n||Sjn(ILn(t),n)}function YR(n,t){return null==VW(n.a,t,"")}function JR(n,t){return mM(),!wan(t.d.i,n)}function ZR(n,t){dA(n.f)?c$n(n,t):CTn(n,t)}function n_(n,t){return t.Hh(n.a)}function t_(n,t){Ay.call(this,e9n+n+o8n+t)}function e_(n,t,e,i){eU.call(this,n,t,e,i)}function i_(n,t,e,i){eU.call(this,n,t,e,i)}function r_(n,t,e,i){i_.call(this,n,t,e,i)}function c_(n,t,e,i){iU.call(this,n,t,e,i)}function a_(n,t,e,i){iU.call(this,n,t,e,i)}function u_(n,t,e,i){iU.call(this,n,t,e,i)}function o_(n,t,e,i){a_.call(this,n,t,e,i)}function s_(n,t,e,i){a_.call(this,n,t,e,i)}function h_(n,t,e,i){u_.call(this,n,t,e,i)}function f_(n,t,e,i){s_.call(this,n,t,e,i)}function l_(n,t,e,i){Zz.call(this,n,t,e,i)}function b_(n,t,e){this.a=n,ZN.call(this,t,e)}function w_(n,t,e){this.c=t,this.b=e,this.a=n}function d_(n,t,e){return n.d=BB(t.Kb(e),164)}function g_(n,t){return n.Aj().Nh().Kh(n,t)}function p_(n,t){return n.Aj().Nh().Ih(n,t)}function v_(n,t){return kW(n),GC(n)===GC(t)}function m_(n,t){return kW(n),GC(n)===GC(t)}function y_(n,t){return Qj(Mdn(n.a,t,!1))}function k_(n,t){return Qj(Sdn(n.a,t,!1))}function j_(n,t){return n.b.sd(new $S(n,t))}function E_(n,t){return n.b.sd(new LS(n,t))}function T_(n,t){return n.b.sd(new NS(n,t))}function M_(n,t,e){return n.lastIndexOf(t,e)}function S_(n,t,e){return Pln(n[t.b],n[e.b])}function P_(n,t){return hon(t,(HXn(),Rdt),n)}function I_(n,t){return E$(t.a.d.p,n.a.d.p)}function C_(n,t){return E$(n.a.d.p,t.a.d.p)}function O_(n,t){return Pln(n.c-n.s,t.c-t.s)}function A_(n){return n.c?E7(n.c.a,n,0):-1}function $_(n){return n<100?null:new Fj(n)}function L_(n){return n==UIt||n==WIt||n==XIt}function N_(n,t){return cL(t,15)&&QDn(n.c,t)}function x_(n,t){Qet||t&&(n.d=t)}function D_(n,t){return!!lsn(n,t)}function R_(n,t){this.c=n,GU.call(this,n,t)}function __(n){this.c=n,vO.call(this,bVn,0)}function K_(n,t){JB.call(this,n,n.length,t)}function F_(n,t,e){return BB(n.c,69).lk(t,e)}function B_(n,t,e){return BB(n.c,69).mk(t,e)}function H_(n,t,e){return oD(n,BB(t,332),e)}function q_(n,t,e){return sD(n,BB(t,332),e)}function G_(n,t,e){return CEn(n,BB(t,332),e)}function z_(n,t,e){return QTn(n,BB(t,332),e)}function U_(n,t){return null==t?null:lfn(n.b,t)}function X_(n){return UC(n)?(kW(n),n):n.ke()}function W_(n){return!isNaN(n)&&!isFinite(n)}function V_(n){sK(),this.a=(SQ(),new Ak(n))}function Q_(n){hH(),this.d=n,this.a=new Lp}function Y_(n,t,e){this.a=n,this.b=t,this.c=e}function J_(n,t,e){this.a=n,this.b=t,this.c=e}function Z_(n,t,e){this.d=n,this.b=e,this.a=t}function nK(n){P$(this),yQ(this),Frn(this,n)}function tK(n){xA(this),tH(this.c,0,n.Pc())}function eK(n){fW(n.a),z8(n.c,n.b),n.b=null}function iK(n){this.a=n,$T(),fan(Date.now())}function rK(){rK=O,iit=new r,rit=new r}function cK(){cK=O,Tet=new L,Met=new N}function aK(){aK=O,wAt=x8(Ant,HWn,1,0,5,1)}function uK(){uK=O,M$t=x8(Ant,HWn,1,0,5,1)}function oK(){oK=O,S$t=x8(Ant,HWn,1,0,5,1)}function sK(){sK=O,new rv((SQ(),SQ(),set))}function hK(n){return Z9(),Inn((n7(),Ket),n)}function fK(n){return qsn(),Inn((e8(),Zet),n)}function lK(n){return hpn(),Inn((C4(),pit),n)}function bK(n){return Rnn(),Inn((O4(),kit),n)}function wK(n){return tRn(),Inn((xan(),Fit),n)}function dK(n){return Dtn(),Inn((Z6(),Wit),n)}function gK(n){return J9(),Inn((n8(),trt),n)}function pK(n){return G7(),Inn((t8(),urt),n)}function vK(n){return dWn(),Inn((MO(),Art),n)}function mK(n){return Dan(),Inn((e7(),Krt),n)}function yK(n){return Hpn(),Inn((i7(),zrt),n)}function kK(n){return qpn(),Inn((r7(),ict),n)}function jK(n){return wM(),Inn((Q2(),act),n)}function EK(n){return _nn(),Inn((A4(),Kct),n)}function TK(n){return q7(),Inn((i8(),Lat),n)}function MK(n){return yMn(),Inn((Xnn(),qat),n)}function SK(n){return Aun(),Inn((t7(),rut),n)}function PK(n){return Bfn(),Inn((r8(),gut),n)}function IK(n,t){if(!n)throw Hp(new Ky(t))}function CK(n){return uSn(),Inn((hen(),Aut),n)}function OK(n){uG.call(this,n.d,n.c,n.a,n.b)}function AK(n){uG.call(this,n.d,n.c,n.a,n.b)}function $K(n,t,e){this.b=n,this.c=t,this.a=e}function LK(n,t,e){this.b=n,this.a=t,this.c=e}function NK(n,t,e){this.a=n,this.b=t,this.c=e}function xK(n,t,e){this.a=n,this.b=t,this.c=e}function DK(n,t,e){this.a=n,this.b=t,this.c=e}function RK(n,t,e){this.a=n,this.b=t,this.c=e}function _K(n,t,e){this.b=n,this.a=t,this.c=e}function KK(n,t,e){this.e=t,this.b=n,this.d=e}function FK(n,t,e){return dM(),n.a.Od(t,e),t}function BK(n){var t;return(t=new jn).e=n,t}function HK(n){var t;return(t=new Zv).b=n,t}function qK(){qK=O,Uut=new Ne,Xut=new xe}function GK(){GK=O,dst=new vr,gst=new mr}function zK(n){return Cun(),Inn((a7(),ost),n)}function UK(n){return Oun(),Inn((o7(),Est),n)}function XK(n){return kDn(),Inn((Gcn(),Vst),n)}function WK(n){return $Pn(),Inn((ben(),rht),n)}function VK(n){return V8(),Inn((R4(),oht),n)}function QK(n){return Oin(),Inn((c8(),bht),n)}function YK(n){return LEn(),Inn((Hnn(),Ost),n)}function JK(n){return Irn(),Inn((o8(),Kst),n)}function ZK(n){return uin(),Inn((a8(),vht),n)}function nF(n){return Vvn(),Inn((Fnn(),Mht),n)}function tF(n){return Knn(),Inn((L4(),Cht),n)}function eF(n){return Jun(),Inn((u8(),Nht),n)}function iF(n){return gSn(),Inn((pen(),Hht),n)}function rF(n){return g7(),Inn((N4(),Uht),n)}function cF(n){return Bjn(),Inn((den(),nft),n)}function aF(n){return JMn(),Inn((wen(),oft),n)}function uF(n){return bDn(),Inn((Vun(),yft),n)}function oF(n){return _an(),Inn((h8(),Mft),n)}function sF(n){return z7(),Inn((s8(),Oft),n)}function hF(n){return z2(),Inn((_4(),Nft),n)}function fF(n){return Tbn(),Inn((qnn(),zlt),n)}function lF(n){return TTn(),Inn((gen(),rvt),n)}function bF(n){return Mhn(),Inn((f8(),svt),n)}function wF(n){return bvn(),Inn((s7(),dvt),n)}function dF(n){return ain(),Inn((w8(),Uvt),n)}function gF(n){return sNn(),Inn((qcn(),$vt),n)}function pF(n){return mon(),Inn((b8(),Rvt),n)}function vF(n){return U7(),Inn((D4(),Bvt),n)}function mF(n){return Hcn(),Inn((l8(),Yvt),n)}function yF(n){return Nvn(),Inn((Bnn(),jvt),n)}function kF(n){return A6(),Inn((x4(),tmt),n)}function jF(n){return Usn(),Inn((g8(),amt),n)}function EF(n){return dcn(),Inn((p8(),fmt),n)}function TF(n){return $un(),Inn((d8(),gmt),n)}function MF(n){return oin(),Inn((v8(),Nmt),n)}function SF(n){return Q4(),Inn((F4(),Gmt),n)}function PF(n){return gJ(),Inn((B4(),iyt),n)}function IF(n){return oZ(),Inn((H4(),uyt),n)}function CF(n){return O6(),Inn((K4(),Pyt),n)}function OF(n){return dJ(),Inn((q4(),Dyt),n)}function AF(n){return zyn(),Inn((c7(),Hyt),n)}function $F(n){return DPn(),Inn((ven(),Jyt),n)}function LF(n){return sZ(),Inn((U4(),Fkt),n)}function NF(n){return Prn(),Inn((z4(),Zkt),n)}function xF(n){return B0(),Inn((G4(),Gkt),n)}function DF(n){return Ibn(),Inn((m8(),rjt),n)}function RF(n){return D9(),Inn((X4(),ojt),n)}function _F(n){return Hsn(),Inn((y8(),bjt),n)}function KF(n){return Omn(),Inn((u7(),zjt),n)}function FF(n){return Bcn(),Inn((j8(),Qjt),n)}function BF(n){return Sbn(),Inn((k8(),eEt),n)}function HF(n){return YLn(),Inn((Unn(),BEt),n)}function qF(n){return Pbn(),Inn((E8(),UEt),n)}function GF(n){return IM(),Inn((W2(),VEt),n)}function zF(n){return CM(),Inn((X2(),JEt),n)}function UF(n){return $6(),Inn((V4(),eTt),n)}function XF(n){return $Sn(),Inn((Gnn(),sTt),n)}function WF(n){return OM(),Inn((V2(),UTt),n)}function VF(n){return Lun(),Inn((W4(),QTt),n)}function QF(n){return rpn(),Inn((znn(),bMt),n)}function YF(n){return PPn(),Inn((zcn(),EMt),n)}function JF(n){return wvn(),Inn((len(),xMt),n)}function ZF(n){return wEn(),Inn((fen(),tSt),n)}function nB(n){return lWn(),Inn((SO(),Zot),n)}function tB(n){return Srn(),Inn(($4(),zut),n)}function eB(n){return Ffn(),Inn((Wnn(),GPt),n)}function iB(n){return Rtn(),Inn((M8(),VPt),n)}function rB(n){return Mbn(),Inn((l7(),tIt),n)}function cB(n){return nMn(),Inn((yen(),sIt),n)}function aB(n){return ufn(),Inn((T8(),kIt),n)}function uB(n){return Xyn(),Inn((f7(),PIt),n)}function oB(n){return n$n(),Inn((Nan(),_It),n)}function sB(n){return cpn(),Inn((Vnn(),zIt),n)}function hB(n){return QEn(),Inn((Htn(),ZIt),n)}function fB(n){return lCn(),Inn((men(),uCt),n)}function lB(n){return mdn(),Inn((w7(),BCt),n)}function bB(n){return nKn(),Inn((Qun(),JCt),n)}function wB(n){return kUn(),Inn((Qnn(),OCt),n)}function dB(n){return Fwn(),Inn((b7(),rOt),n)}function gB(n){return Bsn(),Inn((h7(),fOt),n)}function pB(n){return hAn(),Inn((Ucn(),cAt),n)}function vB(n,t){return kW(n),n+(kW(t),t)}function mB(n,t){return $T(),f9(QQ(n.a),t)}function yB(n,t){return $T(),f9(QQ(n.a),t)}function kB(n,t){this.c=n,this.a=t,this.b=t-n}function jB(n,t,e){this.a=n,this.b=t,this.c=e}function EB(n,t,e){this.a=n,this.b=t,this.c=e}function TB(n,t,e){this.a=n,this.b=t,this.c=e}function MB(n,t,e){this.a=n,this.b=t,this.c=e}function SB(n,t,e){this.a=n,this.b=t,this.c=e}function PB(n,t,e){this.e=n,this.a=t,this.c=e}function IB(n,t,e){f$(),mJ.call(this,n,t,e)}function CB(n,t,e){f$(),rW.call(this,n,t,e)}function OB(n,t,e){f$(),rW.call(this,n,t,e)}function AB(n,t,e){f$(),rW.call(this,n,t,e)}function $B(n,t,e){f$(),CB.call(this,n,t,e)}function LB(n,t,e){f$(),CB.call(this,n,t,e)}function NB(n,t,e){f$(),LB.call(this,n,t,e)}function xB(n,t,e){f$(),OB.call(this,n,t,e)}function DB(n,t,e){f$(),AB.call(this,n,t,e)}function RB(n,t){return yX(n),yX(t),new hT(n,t)}function _B(n,t){return yX(n),yX(t),new KH(n,t)}function KB(n,t){return yX(n),yX(t),new FH(n,t)}function FB(n,t){return yX(n),yX(t),new lT(n,t)}function BB(n,t){return JH(null==n||Qpn(n,t)),n}function HB(n){var t;return fnn(t=new Np,n),t}function qB(n){var t;return fnn(t=new Rv,n),t}function GB(n){var t;return qrn(t=new zv,n),t}function zB(n){var t;return qrn(t=new YT,n),t}function UB(n){return!n.e&&(n.e=new Np),n.e}function XB(n){return!n.c&&(n.c=new Bo),n.c}function WB(n,t){return n.c[n.c.length]=t,!0}function VB(n,t){this.c=n,this.b=t,this.a=!1}function QB(n){this.d=n,Mb(this),this.b=rz(n.d)}function YB(){this.a=";,;",this.b="",this.c=""}function JB(n,t,e){Uz.call(this,t,e),this.a=n}function ZB(n,t,e){this.b=n,gO.call(this,t,e)}function nH(n,t,e){this.c=n,PS.call(this,t,e)}function tH(n,t,e){KIn(e,0,n,t,e.length,!1)}function eH(n,t,e,i,r){n.b=t,n.c=e,n.d=i,n.a=r}function iH(n,t){t&&(n.b=t,n.a=(EW(t),t.a))}function rH(n,t,e,i,r){n.d=t,n.c=e,n.a=i,n.b=r}function cH(n){var t,e;t=n.b,e=n.c,n.b=e,n.c=t}function aH(n){var t,e;e=n.d,t=n.a,n.d=t,n.a=e}function uH(n){return uan(xU(JO(n)?Pan(n):n))}function oH(n,t){return E$(oq(n.d),oq(t.d))}function sH(n,t){return t==(kUn(),ICt)?n.c:n.d}function hH(){hH=O,kUn(),Rmt=ICt,_mt=oCt}function fH(){this.b=Gy(MD(mpn((fRn(),aat))))}function lH(n){return dM(),x8(Ant,HWn,1,n,5,1)}function bH(n){return new xI(n.c+n.b,n.d+n.a)}function wH(n,t){return SM(),E$(n.d.p,t.d.p)}function dH(n){return Px(0!=n.b),Atn(n,n.a.a)}function gH(n){return Px(0!=n.b),Atn(n,n.c.b)}function pH(n,t){if(!n)throw Hp(new $y(t))}function vH(n,t){if(!n)throw Hp(new Ky(t))}function mH(n,t,e){dP.call(this,n,t),this.b=e}function yH(n,t,e){LC.call(this,n,t),this.c=e}function kH(n,t,e){btn.call(this,t,e),this.d=n}function jH(n){oK(),yo.call(this),this.th(n)}function EH(n,t,e){this.a=n,NO.call(this,t,e)}function TH(n,t,e){this.a=n,NO.call(this,t,e)}function MH(n,t,e){LC.call(this,n,t),this.c=e}function SH(){R5(),oW.call(this,(WM(),zAt))}function PH(n){return null!=n&&!Xbn(n,LAt,NAt)}function IH(n,t){return(Wfn(n)<<4|Wfn(t))&QVn}function CH(n,t){return nV(),zvn(n,t),new GW(n,t)}function OH(n,t){var e;n.n&&(e=t,WB(n.f,e))}function AH(n,t,e){rtn(n,t,new GX(e))}function $H(n,t){var e;return e=n.c,_in(n,t),e}function LH(n,t){return n.g=t<0?-1:t,n}function NH(n,t){return ztn(n),n.a*=t,n.b*=t,n}function xH(n,t,e,i,r){n.c=t,n.d=e,n.b=i,n.a=r}function DH(n,t){return r5(n,t,n.c.b,n.c),!0}function RH(n){n.a.b=n.b,n.b.a=n.a,n.a=n.b=null}function _H(n){this.b=n,this.a=lz(this.b.a).Ed()}function KH(n,t){this.b=n,this.a=t,Bh.call(this)}function FH(n,t){this.a=n,this.b=t,Bh.call(this)}function BH(n,t){Uz.call(this,t,1040),this.a=n}function HH(n){return 0==n||isNaN(n)?n:n<0?-1:1}function qH(n){return MQ(),PMn(n)==JJ(OMn(n))}function GH(n){return MQ(),OMn(n)==JJ(PMn(n))}function zH(n,t){return Yjn(n,new dP(t.a,t.b))}function UH(n){return!b5(n)&&n.c.i.c==n.d.i.c}function XH(n){var t;return t=n.n,n.a.b+t.d+t.a}function WH(n){var t;return t=n.n,n.e.b+t.d+t.a}function VH(n){var t;return t=n.n,n.e.a+t.b+t.c}function QH(n){return wWn(),new oG(0,n)}function YH(n){return n.a?n.a:eQ(n)}function JH(n){if(!n)throw Hp(new _y(null))}function ZH(){ZH=O,SQ(),uLt=new Gb(P7n)}function nq(){nq=O,new svn((ty(),Knt),(ey(),_nt))}function tq(){tq=O,Ctt=x8(Att,sVn,19,256,0,1)}function eq(n,t,e,i){awn.call(this,n,t,e,i,0,0)}function iq(n,t,e){return VW(n.b,BB(e.b,17),t)}function rq(n,t,e){return VW(n.b,BB(e.b,17),t)}function cq(n,t){return WB(n,new xI(t.a,t.b))}function aq(n,t){return n.c<t.c?-1:n.c==t.c?0:1}function uq(n){return n.e.c.length+n.g.c.length}function oq(n){return n.e.c.length-n.g.c.length}function sq(n){return n.b.c.length-n.e.c.length}function hq(n){return BZ(),(kUn(),bCt).Hc(n.j)}function fq(n){oK(),jH.call(this,n),this.a=-1}function lq(n,t){xC.call(this,n,t),this.a=this}function bq(n,t){var e;return(e=mX(n,t)).i=2,e}function wq(n,t){return++n.j,n.Ti(t)}function dq(n,t,e){return n.a=-1,WN(n,t.g,e),n}function gq(n,t,e){_zn(n.a,n.b,n.c,BB(t,202),e)}function pq(n,t){Bin(n,null==t?null:(kW(t),t))}function vq(n,t){Rin(n,null==t?null:(kW(t),t))}function mq(n,t){Rin(n,null==t?null:(kW(t),t))}function yq(n,t,e){return new w_(dW(n).Ie(),e,t)}function kq(n,t,e,i,r,c){return Vjn(n,t,e,i,r,0,c)}function jq(){jq=O,jtt=x8(Ttt,sVn,217,256,0,1)}function Eq(){Eq=O,$tt=x8(Rtt,sVn,162,256,0,1)}function Tq(){Tq=O,_tt=x8(Ktt,sVn,184,256,0,1)}function Mq(){Mq=O,Mtt=x8(Stt,sVn,172,128,0,1)}function Sq(){eH(this,!1,!1,!1,!1)}function Pq(n){WX(),this.a=(SQ(),new Gb(yX(n)))}function Iq(n){for(yX(n);n.Ob();)n.Pb(),n.Qb()}function Cq(n){n.a.cd(),BB(n.a.dd(),14).gc(),wk()}function Oq(n){this.c=n,this.b=this.c.d.vc().Kc()}function Aq(n){this.c=n,this.a=new QT(this.c.a)}function $q(n){this.a=new XT(n.gc()),Frn(this,n)}function Lq(n){ew.call(this,new v4),Frn(this,n)}function Nq(n,t){return n.a+=Bdn(t,0,t.length),n}function xq(n,t){return l1(t,n.c.length),n.c[t]}function Dq(n,t){return l1(t,n.a.length),n.a[t]}function Rq(n,t){dM(),B8.call(this,n),this.a=t}function _q(n,t){return jgn(rbn(jgn(n.a).a,t.a))}function Kq(n,t){return kW(n),Ncn(n,(kW(t),t))}function Fq(n,t){return kW(t),Ncn(t,(kW(n),n))}function Bq(n,t){return $X(t,0,Hq(t[0],jgn(1)))}function Hq(n,t){return _q(BB(n,162),BB(t,162))}function qq(n){return n.c-BB(xq(n.a,n.b),287).b}function Gq(n){return n.q?n.q:(SQ(),SQ(),het)}function zq(n){return n.e.Hd().gc()*n.c.Hd().gc()}function Uq(n,t,e){return E$(t.d[n.g],e.d[n.g])}function Xq(n,t,e){return E$(n.d[t.p],n.d[e.p])}function Wq(n,t,e){return E$(n.d[t.p],n.d[e.p])}function Vq(n,t,e){return E$(n.d[t.p],n.d[e.p])}function Qq(n,t,e){return E$(n.d[t.p],n.d[e.p])}function Yq(n,t,i){return e.Math.min(i/n,1/t)}function Jq(n,t){return n?0:e.Math.max(0,t-1)}function Zq(n,t){var e;for(e=0;e<t;++e)n[e]=-1}function nG(n){var t;return(t=uEn(n))?nG(t):n}function tG(n,t){return null==n.a&&wRn(n),n.a[t]}function eG(n){return n.c?n.c.f:n.e.b}function iG(n){return n.c?n.c.g:n.e.a}function rG(n){gtn.call(this,n.gc()),pX(this,n)}function cG(n,t){f$(),jp.call(this,t),this.a=n}function aG(n,t,e){this.a=n,$L.call(this,t,e,2)}function uG(n,t,e,i){Kh(this),rH(this,n,t,e,i)}function oG(n,t){wWn(),Ap.call(this,n),this.a=t}function sG(n){this.b=new YT,this.a=n,this.c=-1}function hG(){this.d=new xI(0,0),this.e=new Rv}function fG(n){ZN.call(this,0,0),this.a=n,this.b=0}function lG(n){this.a=n,this.c=new xp,ron(this)}function bG(n){if(n.e.c!=n.b)throw Hp(new vv)}function wG(n){if(n.c.e!=n.a)throw Hp(new vv)}function dG(n){return JO(n)?0|n:TE(n)}function gG(n,t){return wWn(),new UU(n,t)}function pG(n,t){return null==n?null==t:m_(n,t)}function vG(n,t){return null==n?null==t:mgn(n,t)}function mG(n,t,e){return orn(n.a,t),EU(n,t.g,e)}function yG(n,t,e){ihn(0,t,n.length),z9(n,0,t,e)}function kG(n,t,e){LZ(t,n.c.length),MS(n.c,t,e)}function jG(n,t,e){var i;for(i=0;i<t;++i)n[i]=e}function EG(n,t){var e;return $on(e=nbn(n),t),e}function TG(n,t){return!n&&(n=[]),n[n.length]=t,n}function MG(n,t){return!(void 0===n.a.get(t))}function SG(n,t){return Xin(new nn,new uw(n),t)}function PG(n){return null==n?Set:new vy(kW(n))}function IG(n,t){return cL(t,22)&&SN(n,BB(t,22))}function CG(n,t){return cL(t,22)&&$tn(n,BB(t,22))}function OG(n){return H$n(n,26)*rYn+H$n(n,27)*cYn}function AG(n){return Array.isArray(n)&&n.im===C}function $G(n){n.b?$G(n.b):n.d.dc()&&n.f.c.Bc(n.e)}function LG(n,t){UR(n.c,t),n.b.c+=t.a,n.b.d+=t.b}function NG(n,t){LG(n,XR(new xI(t.a,t.b),n.c))}function xG(n,t){this.b=new YT,this.a=n,this.c=t}function DG(){this.b=new Ot,this.c=new lY(this)}function RG(){this.d=new mn,this.e=new fY(this)}function _G(){_Z(),this.f=new YT,this.e=new YT}function KG(){BZ(),this.k=new xp,this.d=new Rv}function FG(){FG=O,bOt=new XA((sWn(),aPt),0)}function BG(){BG=O,qnt=new fG(x8(Ant,HWn,1,0,5,1))}function HG(n,t,e){VAn(e,n,1),WB(t,new cP(e,n))}function qG(n,t,e){Fkn(e,n,1),WB(t,new bP(e,n))}function GG(n,t,e){return TU(n,new xS(t.a,e.a))}function zG(n,t,e){return-E$(n.f[t.p],n.f[e.p])}function UG(n,t,e){var i;n&&((i=n.i).c=t,i.b=e)}function XG(n,t,e){var i;n&&((i=n.i).d=t,i.a=e)}function WG(n,t,e){return n.a=-1,WN(n,t.g+1,e),n}function VG(n,t,e){return e=TKn(n,BB(t,49),7,e)}function QG(n,t,e){return e=TKn(n,BB(t,49),3,e)}function YG(n,t,e){this.a=n,LL.call(this,t,e,22)}function JG(n,t,e){this.a=n,LL.call(this,t,e,14)}function ZG(n,t,e,i){f$(),N0.call(this,n,t,e,i)}function nz(n,t,e,i){f$(),N0.call(this,n,t,e,i)}function tz(n,t){0!=(t.Bb&h6n)&&!n.a.o&&(n.a.o=t)}function ez(n){return null!=n&&DU(n)&&!(n.im===C)}function iz(n){return!Array.isArray(n)&&n.im===C}function rz(n){return cL(n,15)?BB(n,15).Yc():n.Kc()}function cz(n){return n.Qc(x8(Ant,HWn,1,n.gc(),5,1))}function az(n,t){return lgn(F7(n,t))?t.Qh():null}function uz(n){n?Fmn(n,($T(),Btt),""):$T()}function oz(n){this.a=(BG(),qnt),this.d=BB(yX(n),47)}function sz(n,t,e,i){this.a=n,W6.call(this,n,t,e,i)}function hz(n){eS(),this.a=0,this.b=n-1,this.c=1}function fz(n){V$(this),this.g=n,jQ(this),this._d()}function lz(n){return n.c?n.c:n.c=n.Id()}function bz(n){return n.d?n.d:n.d=n.Jd()}function wz(n){return n.c||(n.c=n.Dd())}function dz(n){return n.f||(n.f=n.Dc())}function gz(n){return n.i||(n.i=n.bc())}function pz(n){return wWn(),new vJ(10,n,0)}function vz(n){return JO(n)?""+n:GDn(n)}function mz(n){if(n.e.j!=n.d)throw Hp(new vv)}function yz(n,t){return uan(lSn(JO(n)?Pan(n):n,t))}function kz(n,t){return uan(jAn(JO(n)?Pan(n):n,t))}function jz(n,t){return uan(JSn(JO(n)?Pan(n):n,t))}function Ez(n,t){return bR((kW(n),n),(kW(t),t))}function Tz(n,t){return Pln((kW(n),n),(kW(t),t))}function Mz(n,t){return yX(t),n.a.Ad(t)&&!n.b.Ad(t)}function Sz(n,t){return M$(n.l&t.l,n.m&t.m,n.h&t.h)}function Pz(n,t){return M$(n.l|t.l,n.m|t.m,n.h|t.h)}function Iz(n,t){return M$(n.l^t.l,n.m^t.m,n.h^t.h)}function Cz(n,t){return $fn(n,(kW(t),new rw(t)))}function Oz(n,t){return $fn(n,(kW(t),new cw(t)))}function Az(n){return gcn(),0!=BB(n,11).e.c.length}function $z(n){return gcn(),0!=BB(n,11).g.c.length}function Lz(n,t){return Crn(),Pln(t.a.o.a,n.a.o.a)}function Nz(n,t,e){return TUn(n,BB(t,11),BB(e,11))}function xz(n){return n.e?D6(n.e):null}function Dz(n){n.d||(n.d=n.b.Kc(),n.c=n.b.gc())}function Rz(n,t,e){n.a.Mb(e)&&(n.b=!0,t.td(e))}function _z(n,t){if(n<0||n>=t)throw Hp(new Sv)}function Kz(n,t,e){return $X(t,0,Hq(t[0],e[0])),t}function Fz(n,t,e){t.Ye(e,Gy(MD(RX(n.b,e)))*n.a)}function Bz(n,t,e){return jDn(),Dcn(n,t)&&Dcn(n,e)}function Hz(n){return lCn(),!n.Hc(eCt)&&!n.Hc(rCt)}function qz(n){return new xI(n.c+n.b/2,n.d+n.a/2)}function Gz(n,t){return t.kh()?tfn(n.b,BB(t,49)):t}function zz(n,t){this.e=n,this.d=0!=(64&t)?t|hVn:t}function Uz(n,t){this.c=0,this.d=n,this.b=64|t|hVn}function Xz(n){this.b=new J6(11),this.a=(PQ(),n)}function Wz(n){this.b=null,this.a=(PQ(),n||wet)}function Vz(n){this.a=rvn(n.a),this.b=new tK(n.b)}function Qz(n){this.b=n,cx.call(this,n),ML(this)}function Yz(n){this.b=n,ux.call(this,n),SL(this)}function Jz(n,t,e){this.a=n,e_.call(this,t,e,5,6)}function Zz(n,t,e,i){this.b=n,$L.call(this,t,e,i)}function nU(n,t,e,i,r){k9.call(this,n,t,e,i,r,-1)}function tU(n,t,e,i,r){j9.call(this,n,t,e,i,r,-1)}function eU(n,t,e,i){$L.call(this,n,t,e),this.b=i}function iU(n,t,e,i){yH.call(this,n,t,e),this.b=i}function rU(n){NC.call(this,n,!1),this.a=!1}function cU(n,t){this.b=n,hl.call(this,n.b),this.a=t}function aU(n,t){WX(),jT.call(this,n,sfn(new Jy(t)))}function uU(n,t){return wWn(),new cW(n,t,0)}function oU(n,t){return wWn(),new cW(6,n,t)}function sU(n,t){return m_(n.substr(0,t.length),t)}function hU(n,t){return XC(t)?eY(n,t):!!AY(n.f,t)}function fU(n,t){for(kW(t);n.Ob();)t.td(n.Pb())}function lU(n,t,e){ODn(),this.e=n,this.d=t,this.a=e}function bU(n,t,e,i){var r;(r=n.i).i=t,r.a=e,r.b=i}function wU(n){var t;for(t=n;t.f;)t=t.f;return t}function dU(n){var t;return Px(null!=(t=Eon(n))),t}function gU(n){var t;return Px(null!=(t=mln(n))),t}function pU(n,t){var e;return w6(t,e=n.a.gc()),e-t}function vU(n,t){var e;for(e=0;e<t;++e)n[e]=!1}function mU(n,t,e,i){var r;for(r=t;r<e;++r)n[r]=i}function yU(n,t,e,i){ihn(t,e,n.length),mU(n,t,e,i)}function kU(n,t,e){_z(e,n.a.c.length),c5(n.a,e,t)}function jU(n,t,e){this.c=n,this.a=t,SQ(),this.b=e}function EU(n,t,e){var i;return i=n.b[t],n.b[t]=e,i}function TU(n,t){return null==n.a.zc(t,n)}function MU(n){if(!n)throw Hp(new yv);return n.d}function SU(n,t){if(null==n)throw Hp(new Hy(t))}function PU(n,t){return!!t&&Frn(n,t)}function IU(n,t,e){return ehn(n,t.g,e),orn(n.c,t),n}function CU(n){return Mzn(n,(Ffn(),KPt)),n.d=!0,n}function OU(n){return!n.j&&yb(n,F_n(n.g,n.b)),n.j}function AU(n){Mx(-1!=n.b),s6(n.c,n.a=n.b),n.b=-1}function $U(n){n.f=new eA(n),n.g=new iA(n),oY(n)}function LU(n){return new Rq(null,qU(n,n.length))}function NU(n){return new oz(new WL(n.a.length,n.a))}function xU(n){return M$(~n.l&SQn,~n.m&SQn,~n.h&PQn)}function DU(n){return typeof n===AWn||typeof n===xWn}function RU(n){return n==RQn?x7n:n==_Qn?"-INF":""+n}function _U(n){return n==RQn?x7n:n==_Qn?"-INF":""+n}function KU(n,t){return n>0?e.Math.log(n/t):-100}function FU(n,t){return Vhn(n,t)<0?-1:Vhn(n,t)>0?1:0}function BU(n,t,e){return SHn(n,BB(t,46),BB(e,167))}function HU(n,t){return BB(wz(lz(n.a)).Xb(t),42).cd()}function qU(n,t){return ptn(t,n.length),new BH(n,t)}function GU(n,t){this.d=n,AL.call(this,n),this.e=t}function zU(n){this.d=(kW(n),n),this.a=0,this.c=bVn}function UU(n,t){Ap.call(this,1),this.a=n,this.b=t}function XU(n,t){return n.c?XU(n.c,t):WB(n.b,t),n}function WU(n,t,e){var i;return i=dnn(n,t),r4(n,t,e),i}function VU(n,t){return m7(n.slice(0,t),n)}function QU(n,t,e){var i;for(i=0;i<t;++i)$X(n,i,e)}function YU(n,t,e,i,r){for(;t<e;)i[r++]=fV(n,t++)}function JU(n,t){return Pln(n.c.c+n.c.b,t.c.c+t.c.b)}function ZU(n,t){return null==Mon(n.a,t,(hN(),ptt))}function nX(n,t){r5(n.d,t,n.b.b,n.b),++n.a,n.c=null}function tX(n,t){J$(n,cL(t,153)?t:BB(t,1937).gl())}function eX(n,t){JT($V(n.Oc(),new Yr),new Cd(t))}function iX(n,t,e,i,r){NEn(n,BB(h6(t.k,e),15),e,i,r)}function rX(n){n.s=NaN,n.c=NaN,ZOn(n,n.e),ZOn(n,n.j)}function cX(n){n.a=null,n.e=null,$U(n.b),n.d=0,++n.c}function aX(n){return e.Math.abs(n.d.e-n.e.e)-n.a}function uX(n,t,e){return BB(n.c._c(t,BB(e,133)),42)}function oX(){return ry(),Pun(Gk(Wnt,1),$Vn,538,0,[znt])}function sX(n){return MQ(),JJ(PMn(n))==JJ(OMn(n))}function hX(n){$R.call(this),this.a=n,WB(n.a,this)}function fX(n,t){this.d=Sln(n),this.c=t,this.a=.5*t}function lX(){v4.call(this),this.a=!0,this.b=!0}function bX(n){return(null==n.i&&qFn(n),n.i).length}function wX(n){return cL(n,99)&&0!=(BB(n,18).Bb&h6n)}function dX(n,t){++n.j,sTn(n,n.i,t),zCn(n,BB(t,332))}function gX(n,t){return t=n.nk(null,t),$Tn(n,null,t)}function pX(n,t){return n.hi()&&(t=nZ(n,t)),n.Wh(t)}function vX(n,t,e){var i;return Qen(e,i=mX(n,t)),i}function mX(n,t){var e;return(e=new pon).j=n,e.d=t,e}function yX(n){if(null==n)throw Hp(new gv);return n}function kX(n){return n.j||(n.j=new wl(n))}function jX(n){return n.f||(n.f=new UL(n))}function EX(n){return n.k||(n.k=new Yf(n))}function TX(n){return n.k||(n.k=new Yf(n))}function MX(n){return n.g||(n.g=new Qf(n))}function SX(n){return n.i||(n.i=new nl(n))}function PX(n){return n.d||(n.d=new il(n))}function IX(n){return yX(n),cL(n,475)?BB(n,475):Bbn(n)}function CX(n){return cL(n,607)?n:new bJ(n)}function OX(n,t){return w2(t,n.c.b.c.gc()),new sT(n,t)}function AX(n,t,e){return wWn(),new T0(n,t,e)}function $X(n,t,e){return Sx(null==e||QKn(n,e)),n[t]=e}function LX(n,t){var e;return w2(t,e=n.a.gc()),e-1-t}function NX(n,t){return n.a+=String.fromCharCode(t),n}function xX(n,t){return n.a+=String.fromCharCode(t),n}function DX(n,t){for(kW(t);n.c<n.d;)n.ze(t,n.c++)}function RX(n,t){return XC(t)?SJ(n,t):qC(AY(n.f,t))}function _X(n,t){return MQ(),n==PMn(t)?OMn(t):PMn(t)}function KX(n,t){nW(n,new GX(null!=t.f?t.f:""+t.g))}function FX(n,t){nW(n,new GX(null!=t.f?t.f:""+t.g))}function BX(n){this.b=new Np,this.a=new Np,this.c=n}function HX(n){this.c=new Gj,this.a=new Np,this.b=n}function qX(n){$R.call(this),this.a=new Gj,this.c=n}function GX(n){if(null==n)throw Hp(new gv);this.a=n}function zX(n){Mv(),this.b=new Np,this.a=n,vGn(this,n)}function UX(n){this.c=n,this.a=new YT,this.b=new YT}function XX(){XX=O,ott=new Ml(!1),stt=new Ml(!0)}function WX(){WX=O,sK(),Fnt=new SY((SQ(),SQ(),set))}function VX(){VX=O,sK(),Vnt=new vS((SQ(),SQ(),fet))}function QX(){QX=O,t$t=GCn(),gWn(),i$t&&Rkn()}function YX(n,t){return Crn(),BB(oV(n,t.d),15).Fc(t)}function JX(n,t,e,i){return 0==e||(e-i)/e<n.e||t>=n.g}function ZX(n,t,e){return NRn(n,yrn(n,t,e))}function nW(n,t){var e;dnn(n,e=n.a.length),r4(n,e,t)}function tW(n,t){console[n].call(console,t)}function eW(n,t){var e;++n.j,e=n.Vi(),n.Ii(n.oi(e,t))}function iW(n,t,e){BB(t.b,65),Otn(t.a,new EB(n,e,t))}function rW(n,t,e){jp.call(this,t),this.a=n,this.b=e}function cW(n,t,e){Ap.call(this,n),this.a=t,this.b=e}function aW(n,t,e){this.a=n,kp.call(this,t),this.b=e}function uW(n,t,e){this.a=n,H2.call(this,8,t,null,e)}function oW(n){this.a=(kW(K9n),K9n),this.b=n,new Nm}function sW(n){this.c=n,this.b=this.c.a,this.a=this.c.e}function hW(n){this.c=n,this.b=n.a.d.a,bD(n.a.e,this)}function fW(n){Mx(-1!=n.c),n.d.$c(n.c),n.b=n.c,n.c=-1}function lW(n){return e.Math.sqrt(n.a*n.a+n.b*n.b)}function bW(n,t){return _z(t,n.a.c.length),xq(n.a,t)}function wW(n,t){return GC(n)===GC(t)||null!=n&&Nfn(n,t)}function dW(n){return 0>=n?new VT:Win(n-1)}function gW(n){return!!SNt&&eY(SNt,n)}function pW(n){return n?n.dc():!n.Kc().Ob()}function vW(n){return!n.a&&n.c?n.c.b:n.a}function mW(n){return!n.a&&(n.a=new $L(LOt,n,4)),n.a}function yW(n){return!n.d&&(n.d=new $L(VAt,n,1)),n.d}function kW(n){if(null==n)throw Hp(new gv);return n}function jW(n){n.c?n.c.He():(n.d=!0,QNn(n))}function EW(n){n.c?EW(n.c):(Qln(n),n.d=!0)}function TW(n){TV(n.a),n.b=x8(Ant,HWn,1,n.b.length,5,1)}function MW(n,t){return E$(t.j.c.length,n.j.c.length)}function SW(n,t){n.c<0||n.b.b<n.c?fO(n.b,t):n.a._e(t)}function PW(n,t){var e;(e=n.Yg(t))>=0?n.Bh(e):cCn(n,t)}function IW(n){return n.c.i.c==n.d.i.c}function CW(n){if(4!=n.p)throw Hp(new dv);return n.e}function OW(n){if(3!=n.p)throw Hp(new dv);return n.e}function AW(n){if(6!=n.p)throw Hp(new dv);return n.f}function $W(n){if(6!=n.p)throw Hp(new dv);return n.k}function LW(n){if(3!=n.p)throw Hp(new dv);return n.j}function NW(n){if(4!=n.p)throw Hp(new dv);return n.j}function xW(n){return!n.b&&(n.b=new Tp(new xm)),n.b}function DW(n){return-2==n.c&&gb(n,uMn(n.g,n.b)),n.c}function RW(n,t){var e;return(e=mX("",n)).n=t,e.i=1,e}function _W(n,t){LG(BB(t.b,65),n),Otn(t.a,new Aw(n))}function KW(n,t){f9((!n.a&&(n.a=new oR(n,n)),n.a),t)}function FW(n,t){this.b=n,GU.call(this,n,t),ML(this)}function BW(n,t){this.b=n,R_.call(this,n,t),SL(this)}function HW(n,t,e,i){vT.call(this,n,t),this.d=e,this.a=i}function qW(n,t,e,i){vT.call(this,n,e),this.a=t,this.f=i}function GW(n,t){W$.call(this,Vin(yX(n),yX(t))),this.a=t}function zW(){dMn.call(this,S7n,(rE(),dLt)),Wqn(this)}function UW(){dMn.call(this,V9n,(iE(),n$t)),OHn(this)}function XW(){gT.call(this,"DELAUNAY_TRIANGULATION",0)}function WW(n){return String.fromCharCode.apply(null,n)}function VW(n,t,e){return XC(t)?mZ(n,t,e):jIn(n.f,t,e)}function QW(n){return SQ(),n?n.ve():(PQ(),PQ(),get)}function YW(n,t,e){return Nun(),e.pg(n,BB(t.cd(),146))}function JW(n,t){return nq(),new svn(new rN(n),new iN(t))}function ZW(n){return lin(n,NVn),ttn(rbn(rbn(5,n),n/10|0))}function nV(){nV=O,Bnt=new hy(Pun(Gk(Hnt,1),kVn,42,0,[]))}function tV(n){return!n.d&&(n.d=new Hb(n.c.Cc())),n.d}function eV(n){return!n.a&&(n.a=new Lk(n.c.vc())),n.a}function iV(n){return!n.b&&(n.b=new Ak(n.c.ec())),n.b}function rV(n,t){for(;t-- >0;)n=n<<1|(n<0?1:0);return n}function cV(n,t){return GC(n)===GC(t)||null!=n&&Nfn(n,t)}function aV(n,t){return hN(),BB(t.b,19).a<n}function uV(n,t){return hN(),BB(t.a,19).a<n}function oV(n,t){return IG(n.a,t)?n.b[BB(t,22).g]:null}function sV(n,t,e,i){n.a=fx(n.a,0,t)+""+i+nO(n.a,e)}function hV(n,t){n.u.Hc((lCn(),eCt))&&PCn(n,t),z6(n,t)}function fV(n,t){return b1(t,n.length),n.charCodeAt(t)}function lV(){dy.call(this,"There is no more element.")}function bV(n){this.d=n,this.a=this.d.b,this.b=this.d.c}function wV(n){n.b=!1,n.c=!1,n.d=!1,n.a=!1}function dV(n,t,e,i){return Rcn(n,t,e,!1),Zfn(n,i),n}function gV(n){return n.j.c=x8(Ant,HWn,1,0,5,1),n.a=-1,n}function pV(n){return!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c}function vV(n){return!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b}function mV(n){return!n.n&&(n.n=new eU(zOt,n,1,7)),n.n}function yV(n){return!n.c&&(n.c=new eU(XOt,n,9,9)),n.c}function kV(n){return n.e==I7n&&vb(n,Tgn(n.g,n.b)),n.e}function jV(n){return n.f==I7n&&mb(n,pkn(n.g,n.b)),n.f}function EV(n){var t;return!(t=n.b)&&(n.b=t=new Jf(n)),t}function TV(n){var t;for(t=n.Kc();t.Ob();)t.Pb(),t.Qb()}function MV(n){if(zbn(n.d),n.d.d!=n.c)throw Hp(new vv)}function SV(n,t){this.b=n,this.c=t,this.a=new QT(this.b)}function PV(n,t,e){this.a=XVn,this.d=n,this.b=t,this.c=e}function IV(n,t){this.d=(kW(n),n),this.a=16449,this.c=t}function CV(n,t){Jln(n,Gy(Ren(t,"x")),Gy(Ren(t,"y")))}function OV(n,t){Jln(n,Gy(Ren(t,"x")),Gy(Ren(t,"y")))}function AV(n,t){return Qln(n),new Rq(n,new Q9(t,n.a))}function $V(n,t){return Qln(n),new Rq(n,new M6(t,n.a))}function LV(n,t){return Qln(n),new AD(n,new E6(t,n.a))}function NV(n,t){return Qln(n),new $D(n,new T6(t,n.a))}function xV(n,t){return new pY(BB(yX(n),62),BB(yX(t),62))}function DV(n,t){return jM(),Pln((kW(n),n),(kW(t),t))}function RV(){return wM(),Pun(Gk(Pct,1),$Vn,481,0,[rct])}function _V(){return IM(),Pun(Gk(YEt,1),$Vn,482,0,[XEt])}function KV(){return CM(),Pun(Gk(tTt,1),$Vn,551,0,[QEt])}function FV(){return OM(),Pun(Gk(VTt,1),$Vn,530,0,[GTt])}function BV(n){this.a=new Np,this.e=x8(ANt,sVn,48,n,0,2)}function HV(n,t,e,i){this.a=n,this.e=t,this.d=e,this.c=i}function qV(n,t,e,i){this.a=n,this.c=t,this.b=e,this.d=i}function GV(n,t,e,i){this.c=n,this.b=t,this.a=e,this.d=i}function zV(n,t,e,i){this.c=n,this.b=t,this.d=e,this.a=i}function UV(n,t,e,i){this.c=n,this.d=t,this.b=e,this.a=i}function XV(n,t,e,i){this.a=n,this.d=t,this.c=e,this.b=i}function WV(n,t,e,i){gT.call(this,n,t),this.a=e,this.b=i}function VV(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function QV(n,t,e){EHn(n.a,e),nun(e),AAn(n.b,e),rqn(t,e)}function YV(n,t,e){var i;return i=$Un(n),t.Kh(e,i)}function JV(n,t){var e,i;return(e=n/t)>(i=IJ(e))&&++i,i}function ZV(n){var t;return cen(t=new _p,n),t}function nQ(n){var t;return DMn(t=new _p,n),t}function tQ(n,t){return _cn(t,RX(n.f,t)),null}function eQ(n){return Yin(n)||null}function iQ(n){return!n.b&&(n.b=new eU(KOt,n,12,3)),n.b}function rQ(n){return null!=n&&xT(jAt,n.toLowerCase())}function cQ(n,t){return Pln(iG(n)*eG(n),iG(t)*eG(t))}function aQ(n,t){return Pln(iG(n)*eG(n),iG(t)*eG(t))}function uQ(n,t){return Pln(n.d.c+n.d.b/2,t.d.c+t.d.b/2)}function oQ(n,t){return Pln(n.g.c+n.g.b/2,t.g.c+t.g.b/2)}function sQ(n,t,e){e.a?Ien(n,t.b-n.f/2):Pen(n,t.a-n.g/2)}function hQ(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function fQ(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function lQ(n,t,e,i){this.e=n,this.a=t,this.c=e,this.d=i}function bQ(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function wQ(n,t,e,i){f$(),e6.call(this,t,e,i),this.a=n}function dQ(n,t,e,i){f$(),e6.call(this,t,e,i),this.a=n}function gQ(n,t){this.a=n,OD.call(this,n,BB(n.d,15).Zc(t))}function pQ(n){this.f=n,this.c=this.f.e,n.f>0&&ujn(this)}function vQ(n,t,e,i){this.b=n,this.c=i,vO.call(this,t,e)}function mQ(n){return Px(n.b<n.d.gc()),n.d.Xb(n.c=n.b++)}function yQ(n){n.a.a=n.c,n.c.b=n.a,n.a.b=n.c.a=null,n.b=0}function kQ(n,t){return n.b=t.b,n.c=t.c,n.d=t.d,n.a=t.a,n}function jQ(n){return n.n&&(n.e!==FVn&&n._d(),n.j=null),n}function EQ(n){return JH(null==n||DU(n)&&!(n.im===C)),n}function TQ(n){this.b=new Np,gun(this.b,this.b),this.a=n}function MQ(){MQ=O,Sct=new Np,Mct=new xp,Tct=new Np}function SQ(){SQ=O,set=new S,het=new I,fet=new M}function PQ(){PQ=O,wet=new R,det=new R,get=new _}function IQ(){IQ=O,hit=new gn,lit=new RG,fit=new pn}function CQ(){256==ait&&(iit=rit,rit=new r,ait=0),++ait}function OQ(n){return n.f||(n.f=new pT(n,n.c))}function AQ(n){return QCn(n)&&qy(TD(ZAn(n,(HXn(),dgt))))}function $Q(n,t){return JCn(n,BB(mMn(t,(HXn(),Wgt)),19),t)}function LQ(n,t){return Tfn(n.j,t.s,t.c)+Tfn(t.e,n.s,n.c)}function NQ(n,t){n.e&&!n.e.a&&(Fp(n.e,t),NQ(n.e,t))}function xQ(n,t){n.d&&!n.d.a&&(Fp(n.d,t),xQ(n.d,t))}function DQ(n,t){return-Pln(iG(n)*eG(n),iG(t)*eG(t))}function RQ(n){return BB(n.cd(),146).tg()+":"+Bbn(n.dd())}function _Q(n){var t;GK(),(t=BB(n.g,10)).n.a=n.d.c+t.d.b}function KQ(n,t,e){return MM(),xbn(BB(RX(n.e,t),522),e)}function FQ(n,t){return tsn(n),tsn(t),Py(BB(n,22),BB(t,22))}function BQ(n,t,e){n.i=0,n.e=0,t!=e&&Xon(n,t,e)}function HQ(n,t,e){n.i=0,n.e=0,t!=e&&Won(n,t,e)}function qQ(n,t,e){rtn(n,t,new Sl(X_(e)))}function GQ(n,t,e,i,r,c){j9.call(this,n,t,e,i,r,c?-2:-1)}function zQ(n,t,e,i){LC.call(this,t,e),this.b=n,this.a=i}function UQ(n,t){new YT,this.a=new km,this.b=n,this.c=t}function XQ(n,t){return BB(mMn(n,(hWn(),clt)),15).Fc(t),t}function WQ(n,t){if(null==n)throw Hp(new Hy(t));return n}function VQ(n){return!n.q&&(n.q=new eU(QAt,n,11,10)),n.q}function QQ(n){return!n.s&&(n.s=new eU(FAt,n,21,17)),n.s}function YQ(n){return!n.a&&(n.a=new eU(UOt,n,10,11)),n.a}function JQ(n){return cL(n,14)?new $q(BB(n,14)):qB(n.Kc())}function ZQ(n){return new qL(n,n.e.Hd().gc()*n.c.Hd().gc())}function nY(n){return new GL(n,n.e.Hd().gc()*n.c.Hd().gc())}function tY(n){return n&&n.hashCode?n.hashCode():PN(n)}function eY(n,t){return null==t?!!AY(n.f,null):MG(n.g,t)}function iY(n){return yX(n),emn(new oz(ZL(n.a.Kc(),new h)))}function rY(n){return SQ(),cL(n,54)?new $k(n):new bN(n)}function cY(n,t,e){return!!n.f&&n.f.Ne(t,e)}function aY(n,t){return n.a=fx(n.a,0,t)+""+nO(n.a,t+1),n}function uY(n,t){var e;return(e=eL(n.a,t))&&(t.d=null),e}function oY(n){var t,e;t=0|(e=n).$modCount,e.$modCount=t+1}function sY(n){this.b=n,this.c=n,n.e=null,n.c=null,this.a=1}function hY(n){this.b=n,this.a=new dE(BB(yX(new tt),62))}function fY(n){this.c=n,this.b=new dE(BB(yX(new vn),62))}function lY(n){this.c=n,this.b=new dE(BB(yX(new Ct),62))}function bY(){this.a=new Qv,this.b=new hm,this.d=new Dt}function wY(){this.a=new km,this.b=(lin(3,AVn),new J6(3))}function dY(){this.b=new Rv,this.d=new YT,this.e=new om}function gY(n){this.c=n.c,this.d=n.d,this.b=n.b,this.a=n.a}function pY(n,t){zm.call(this,new Wz(n)),this.a=n,this.b=t}function vY(){iSn(this,new Rf),this.wb=(QX(),t$t),iE()}function mY(n){OTn(n,"No crossing minimization",1),HSn(n)}function yY(n){Dk(),e.setTimeout((function(){throw n}),0)}function kY(n){return n.u||(P5(n),n.u=new uR(n,n)),n.u}function jY(n){return BB(yan(n,16),26)||n.zh()}function EY(n,t){return cL(t,146)&&m_(n.b,BB(t,146).tg())}function TY(n,t){return n.a?t.Wg().Kc():BB(t.Wg(),69).Zh()}function MY(n){return n.k==(uSn(),Iut)&&Lx(n,(hWn(),zft))}function SY(n){this.a=(SQ(),cL(n,54)?new $k(n):new bN(n))}function PY(){var n,t;PY=O,t=!Ddn(),n=new d,ett=t?new E:n}function IY(n,t){var e;return e=nE(n.gm),null==t?e:e+": "+t}function CY(n,t){var e;return j4(e=n.b.Qc(t),n.b.gc()),e}function OY(n,t){if(null==n)throw Hp(new Hy(t));return n}function AY(n,t){return hhn(n,t,pZ(n,null==t?0:n.b.se(t)))}function $Y(n,t,e){return e>=0&&m_(n.substr(e,t.length),t)}function LY(n,t,e,i,r,c,a){return new b4(n.e,t,e,i,r,c,a)}function NY(n,t,e,i,r,c){this.a=n,kin.call(this,t,e,i,r,c)}function xY(n,t,e,i,r,c){this.a=n,kin.call(this,t,e,i,r,c)}function DY(n,t){this.g=n,this.d=Pun(Gk(Out,1),a1n,10,0,[t])}function RY(n,t){this.e=n,this.a=Ant,this.b=ARn(t),this.c=t}function _Y(n,t){NR.call(this),xtn(this),this.a=n,this.c=t}function KY(n,t,e,i){$X(n.c[t.g],e.g,i),$X(n.c[e.g],t.g,i)}function FY(n,t,e,i){$X(n.c[t.g],t.g,e),$X(n.b[t.g],t.g,i)}function BY(){return A6(),Pun(Gk(cmt,1),$Vn,376,0,[Zvt,Jvt])}function HY(){return g7(),Pun(Gk(Zht,1),$Vn,479,0,[Ght,qht])}function qY(){return Knn(),Pun(Gk(Lht,1),$Vn,419,0,[Sht,Pht])}function GY(){return V8(),Pun(Gk(lht,1),$Vn,422,0,[cht,aht])}function zY(){return z2(),Pun(Gk(Glt,1),$Vn,420,0,[Aft,$ft])}function UY(){return U7(),Pun(Gk(zvt,1),$Vn,421,0,[_vt,Kvt])}function XY(){return Q4(),Pun(Gk(Vmt,1),$Vn,523,0,[Hmt,Bmt])}function WY(){return O6(),Pun(Gk(xyt,1),$Vn,520,0,[Myt,Tyt])}function VY(){return gJ(),Pun(Gk(ayt,1),$Vn,516,0,[tyt,nyt])}function QY(){return oZ(),Pun(Gk(Syt,1),$Vn,515,0,[ryt,cyt])}function YY(){return dJ(),Pun(Gk(Byt,1),$Vn,455,0,[Lyt,Nyt])}function JY(){return B0(),Pun(Gk(Jkt,1),$Vn,425,0,[Hkt,Bkt])}function ZY(){return sZ(),Pun(Gk(qkt,1),$Vn,480,0,[Rkt,_kt])}function nJ(){return Prn(),Pun(Gk(ijt,1),$Vn,495,0,[Qkt,Ykt])}function tJ(){return D9(),Pun(Gk(ljt,1),$Vn,426,0,[cjt,ajt])}function eJ(){return Lun(),Pun(Gk(YTt,1),$Vn,429,0,[WTt,XTt])}function iJ(){return $6(),Pun(Gk(oTt,1),$Vn,430,0,[nTt,ZEt])}function rJ(){return hpn(),Pun(Gk(yit,1),$Vn,428,0,[dit,wit])}function cJ(){return Rnn(),Pun(Gk(_it,1),$Vn,427,0,[vit,mit])}function aJ(){return _nn(),Pun(Gk($at,1),$Vn,424,0,[Dct,Rct])}function uJ(){return Srn(),Pun(Gk(Wut,1),$Vn,511,0,[qut,Hut])}function oJ(n,t,e,i){return e>=0?n.jh(t,e,i):n.Sg(null,e,i)}function sJ(n){return 0==n.b.b?n.a.$e():dH(n.b)}function hJ(n){if(5!=n.p)throw Hp(new dv);return dG(n.f)}function fJ(n){if(5!=n.p)throw Hp(new dv);return dG(n.k)}function lJ(n){return GC(n.a)===GC((wcn(),C$t))&&Rqn(n),n.a}function bJ(n){this.a=BB(yX(n),271),this.b=(SQ(),new dN(n))}function wJ(n,t){Zl(this,new xI(n.a,n.b)),nb(this,zB(t))}function dJ(){dJ=O,Lyt=new oI(cJn,0),Nyt=new oI(aJn,1)}function gJ(){gJ=O,tyt=new cI(aJn,0),nyt=new cI(cJn,1)}function pJ(){ay.call(this,new XT(etn(12))),aN(!0),this.a=2}function vJ(n,t,e){wWn(),Ap.call(this,n),this.b=t,this.a=e}function mJ(n,t,e){f$(),jp.call(this,t),this.a=n,this.b=e}function yJ(n){NR.call(this),xtn(this),this.a=n,this.c=!0}function kJ(n){var t;t=n.c.d.b,n.b=t,n.a=n.c.d,t.a=n.c.d.b=n}function jJ(n){pin(n.a),RA(n.a),twn(new Pw(n.a))}function EJ(n,t){oRn(n,!0),Otn(n.e.wf(),new $K(n,!0,t))}function TJ(n,t){return c4(t),Yen(n,x8(ANt,hQn,25,t,15,1),t)}function MJ(n,t){return MQ(),n==JJ(PMn(t))||n==JJ(OMn(t))}function SJ(n,t){return null==t?qC(AY(n.f,null)):hS(n.g,t)}function PJ(n){return 0==n.b?null:(Px(0!=n.b),Atn(n,n.a.a))}function IJ(n){return 0|Math.max(Math.min(n,DWn),-2147483648)}function CJ(n,t){var e=Znt[n.charCodeAt(0)];return null==e?n:e}function OJ(n,t){return WQ(n,"set1"),WQ(t,"set2"),new ET(n,t)}function AJ(n,t){return UR(qx(nen(n.f,t)),n.f.d)}function $J(n,t){var e;return YGn(n,t,e=new q),e.d}function LJ(n,t,e,i){var r;r=new FR,t.a[e.g]=r,mG(n.b,i,r)}function NJ(n,t,e){var i;(i=n.Yg(t))>=0?n.sh(i,e):TLn(n,t,e)}function xJ(n,t,e){hZ(),n&&VW(fAt,n,t),n&&VW(hAt,n,e)}function DJ(n,t,e){this.i=new Np,this.b=n,this.g=t,this.a=e}function RJ(n,t,e){this.c=new Np,this.e=n,this.f=t,this.b=e}function _J(n,t,e){this.a=new Np,this.e=n,this.f=t,this.c=e}function KJ(n,t){V$(this),this.f=t,this.g=n,jQ(this),this._d()}function FJ(n,t){var e;e=n.q.getHours(),n.q.setDate(t),lBn(n,e)}function BJ(n,t){var e;for(yX(t),e=n.a;e;e=e.c)t.Od(e.g,e.i)}function HJ(n){var t;return $on(t=new bE(etn(n.length)),n),t}function qJ(n){function t(){}return t.prototype=n||{},new t}function GJ(n,t){return!!wun(n,t)&&(ein(n),!0)}function zJ(n,t){if(null==t)throw Hp(new gv);return ugn(n,t)}function UJ(n){if(n.qe())return null;var t=n.n;return SWn[t]}function XJ(n){return n.Db>>16!=3?null:BB(n.Cb,33)}function WJ(n){return n.Db>>16!=9?null:BB(n.Cb,33)}function VJ(n){return n.Db>>16!=6?null:BB(n.Cb,79)}function QJ(n){return n.Db>>16!=7?null:BB(n.Cb,235)}function YJ(n){return n.Db>>16!=7?null:BB(n.Cb,160)}function JJ(n){return n.Db>>16!=11?null:BB(n.Cb,33)}function ZJ(n,t){var e;return(e=n.Yg(t))>=0?n.lh(e):qCn(n,t)}function nZ(n,t){var e;return oMn(e=new Lq(t),n),new tK(e)}function tZ(n){var t;return t=n.d,t=n.si(n.f),f9(n,t),t.Ob()}function eZ(n,t){return n.b+=t.b,n.c+=t.c,n.d+=t.d,n.a+=t.a,n}function iZ(n,t){return e.Math.abs(n)<e.Math.abs(t)?n:t}function rZ(n){return!n.a&&(n.a=new eU(UOt,n,10,11)),n.a.i>0}function cZ(){this.a=new fA,this.e=new Rv,this.g=0,this.i=0}function aZ(n){this.a=n,this.b=x8(Kmt,sVn,1944,n.e.length,0,2)}function uZ(n,t,e){var i;i=Non(n,t,e),n.b=new mrn(i.c.length)}function oZ(){oZ=O,ryt=new rI(pJn,0),cyt=new rI("UP",1)}function sZ(){sZ=O,Rkt=new bI(U3n,0),_kt=new bI("FAN",1)}function hZ(){hZ=O,fAt=new xp,hAt=new xp,FC(yet,new wo)}function fZ(n){if(0!=n.p)throw Hp(new dv);return JC(n.f,0)}function lZ(n){if(0!=n.p)throw Hp(new dv);return JC(n.k,0)}function bZ(n){return n.Db>>16!=3?null:BB(n.Cb,147)}function wZ(n){return n.Db>>16!=6?null:BB(n.Cb,235)}function dZ(n){return n.Db>>16!=17?null:BB(n.Cb,26)}function gZ(n,t){var e=n.a=n.a||[];return e[t]||(e[t]=n.le(t))}function pZ(n,t){var e;return null==(e=n.a.get(t))?new Array:e}function vZ(n,t){var e;e=n.q.getHours(),n.q.setMonth(t),lBn(n,e)}function mZ(n,t,e){return null==t?jIn(n.f,null,e):ubn(n.g,t,e)}function yZ(n,t,e,i,r,c){return new N7(n.e,t,n.aj(),e,i,r,c)}function kZ(n,t,e){return n.a=fx(n.a,0,t)+""+e+nO(n.a,t),n}function jZ(n,t,e){return WB(n.a,(nV(),zvn(t,e),new vT(t,e))),n}function EZ(n){return oN(n.c),n.e=n.a=n.c,n.c=n.c.c,++n.d,n.a.f}function TZ(n){return oN(n.e),n.c=n.a=n.e,n.e=n.e.e,--n.d,n.a.f}function MZ(n,t){n.d&&y7(n.d.e,n),n.d=t,n.d&&WB(n.d.e,n)}function SZ(n,t){n.c&&y7(n.c.g,n),n.c=t,n.c&&WB(n.c.g,n)}function PZ(n,t){n.c&&y7(n.c.a,n),n.c=t,n.c&&WB(n.c.a,n)}function IZ(n,t){n.i&&y7(n.i.j,n),n.i=t,n.i&&WB(n.i.j,n)}function CZ(n,t,e){this.a=t,this.c=n,this.b=(yX(e),new tK(e))}function OZ(n,t,e){this.a=t,this.c=n,this.b=(yX(e),new tK(e))}function AZ(n,t){this.a=n,this.c=B$(this.a),this.b=new gY(t)}function $Z(n){return Qln(n),AV(n,new vw(new Rv))}function LZ(n,t){if(n<0||n>t)throw Hp(new Ay(jYn+n+EYn+t))}function NZ(n,t){return CG(n.a,t)?EU(n,BB(t,22).g,null):null}function xZ(n){return Shn(),hN(),0!=BB(n.a,81).d.e}function DZ(){DZ=O,Xnt=lhn((ry(),Pun(Gk(Wnt,1),$Vn,538,0,[znt])))}function RZ(){RZ=O,pmt=WG(new B2,(yMn(),Bat),(lWn(),qot))}function _Z(){_Z=O,vmt=WG(new B2,(yMn(),Bat),(lWn(),qot))}function KZ(){KZ=O,ymt=WG(new B2,(yMn(),Bat),(lWn(),qot))}function FZ(){FZ=O,zmt=dq(new B2,(yMn(),Bat),(lWn(),dot))}function BZ(){BZ=O,Qmt=dq(new B2,(yMn(),Bat),(lWn(),dot))}function HZ(){HZ=O,Zmt=dq(new B2,(yMn(),Bat),(lWn(),dot))}function qZ(){qZ=O,oyt=dq(new B2,(yMn(),Bat),(lWn(),dot))}function GZ(){GZ=O,zkt=WG(new B2,(zyn(),Fyt),(DPn(),zyt))}function zZ(n,t,e,i){this.c=n,this.d=i,WZ(this,t),VZ(this,e)}function UZ(n){this.c=new YT,this.b=n.b,this.d=n.c,this.a=n.a}function XZ(n){this.a=e.Math.cos(n),this.b=e.Math.sin(n)}function WZ(n,t){n.a&&y7(n.a.k,n),n.a=t,n.a&&WB(n.a.k,n)}function VZ(n,t){n.b&&y7(n.b.f,n),n.b=t,n.b&&WB(n.b.f,n)}function QZ(n,t){iW(n,n.b,n.c),BB(n.b.b,65),t&&BB(t.b,65).b}function YZ(n,t){zln(n,t),cL(n.Cb,88)&&AIn(P5(BB(n.Cb,88)),2)}function JZ(n,t){cL(n.Cb,88)&&AIn(P5(BB(n.Cb,88)),4),Nrn(n,t)}function ZZ(n,t){cL(n.Cb,179)&&(BB(n.Cb,179).tb=null),Nrn(n,t)}function n1(n,t){return ZM(),hnn(t)?new lq(t,n):new xC(t,n)}function t1(n,t){null!=t.c&&nW(n,new GX(t.c))}function e1(n){var t;return iE(),cen(t=new _p,n),t}function i1(n){var t;return iE(),cen(t=new _p,n),t}function r1(n,t){var e;return e=new HX(n),t.c[t.c.length]=e,e}function c1(n,t){var e;return(e=BB(lfn(OQ(n.a),t),14))?e.gc():0}function a1(n){return Qln(n),PQ(),PQ(),ytn(n,det)}function u1(n){for(var t;;)if(t=n.Pb(),!n.Ob())return t}function o1(n,t){Um.call(this,new XT(etn(n))),lin(t,oVn),this.a=t}function s1(n,t,e){Hfn(t,e,n.gc()),this.c=n,this.a=t,this.b=e-t}function h1(n,t,e){var i;Hfn(t,e,n.c.length),i=e-t,PE(n.c,t,i)}function f1(n,t){hL(n,dG(e0(kz(t,24),sYn)),dG(e0(t,sYn)))}function l1(n,t){if(n<0||n>=t)throw Hp(new Ay(jYn+n+EYn+t))}function b1(n,t){if(n<0||n>=t)throw Hp(new Ok(jYn+n+EYn+t))}function w1(n,t){this.b=(kW(n),n),this.a=0==(t&KQn)?64|t|hVn:t}function d1(n){DA(this),Pv(this.a,kon(e.Math.max(8,n))<<1)}function g1(n){return Aon(Pun(Gk(PMt,1),sVn,8,0,[n.i.n,n.n,n.a]))}function p1(){return qsn(),Pun(Gk(nit,1),$Vn,132,0,[zet,Uet,Xet])}function v1(){return Dtn(),Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])}function m1(){return J9(),Pun(Gk(ert,1),$Vn,461,0,[Yit,Qit,Jit])}function y1(){return G7(),Pun(Gk(Ort,1),$Vn,462,0,[crt,rrt,irt])}function k1(){return Bfn(),Pun(Gk(mut,1),$Vn,423,0,[wut,but,lut])}function j1(){return q7(),Pun(Gk(Hat,1),$Vn,379,0,[Oat,Cat,Aat])}function E1(){return Mhn(),Pun(Gk(wvt,1),$Vn,378,0,[cvt,avt,uvt])}function T1(){return Oin(),Pun(Gk(pht,1),$Vn,314,0,[hht,sht,fht])}function M1(){return uin(),Pun(Gk(Tht,1),$Vn,337,0,[wht,ght,dht])}function S1(){return Jun(),Pun(Gk(Bht,1),$Vn,450,0,[Aht,Oht,$ht])}function P1(){return Irn(),Pun(Gk(Wst,1),$Vn,361,0,[Rst,Dst,xst])}function I1(){return z7(),Pun(Gk(Lft,1),$Vn,303,0,[Pft,Ift,Sft])}function C1(){return _an(),Pun(Gk(Cft,1),$Vn,292,0,[jft,Eft,kft])}function O1(){return ain(),Pun(Gk(Qvt,1),$Vn,452,0,[Gvt,Hvt,qvt])}function A1(){return mon(),Pun(Gk(Fvt,1),$Vn,339,0,[Nvt,Lvt,xvt])}function $1(){return Hcn(),Pun(Gk(nmt,1),$Vn,375,0,[Xvt,Wvt,Vvt])}function L1(){return $un(),Pun(Gk(Smt,1),$Vn,377,0,[bmt,wmt,lmt])}function N1(){return Usn(),Pun(Gk(hmt,1),$Vn,336,0,[emt,imt,rmt])}function x1(){return dcn(),Pun(Gk(dmt,1),$Vn,338,0,[smt,umt,omt])}function D1(){return oin(),Pun(Gk(xmt,1),$Vn,454,0,[Omt,Amt,$mt])}function R1(){return Ibn(),Pun(Gk(ujt,1),$Vn,442,0,[ejt,njt,tjt])}function _1(){return Hsn(),Pun(Gk(Gjt,1),$Vn,380,0,[sjt,hjt,fjt])}function K1(){return Sbn(),Pun(Gk(NEt,1),$Vn,381,0,[Zjt,nEt,Jjt])}function F1(){return Bcn(),Pun(Gk(Yjt,1),$Vn,293,0,[Xjt,Wjt,Ujt])}function B1(){return Pbn(),Pun(Gk(WEt,1),$Vn,437,0,[HEt,qEt,GEt])}function H1(){return ufn(),Pun(Gk(SIt,1),$Vn,334,0,[vIt,pIt,mIt])}function q1(){return Rtn(),Pun(Gk(nIt,1),$Vn,272,0,[zPt,UPt,XPt])}function G1(n,t){return k$n(n,t,cL(t,99)&&0!=(BB(t,18).Bb&BQn))}function z1(n,t,e){var i;return(i=cHn(n,t,!1)).b<=t&&i.a<=e}function U1(n,t,e){var i;(i=new ca).b=t,i.a=e,++t.b,WB(n.d,i)}function X1(n,t){var e;return Tx(!!(e=(kW(n),n).g)),kW(t),e(t)}function W1(n,t){var e,i;return i=pU(n,t),e=n.a.Zc(i),new kT(n,e)}function V1(n){return n.Db>>16!=6?null:BB(cAn(n),235)}function Q1(n){if(2!=n.p)throw Hp(new dv);return dG(n.f)&QVn}function Y1(n){if(2!=n.p)throw Hp(new dv);return dG(n.k)&QVn}function J1(n){return n.a==(R5(),eLt)&&db(n,eLn(n.g,n.b)),n.a}function Z1(n){return n.d==(R5(),eLt)&&pb(n,N_n(n.g,n.b)),n.d}function n0(n){return Px(n.a<n.c.c.length),n.b=n.a++,n.c.c[n.b]}function t0(n,t){n.b=n.b|t.b,n.c=n.c|t.c,n.d=n.d|t.d,n.a=n.a|t.a}function e0(n,t){return uan(Sz(JO(n)?Pan(n):n,JO(t)?Pan(t):t))}function i0(n,t){return uan(Pz(JO(n)?Pan(n):n,JO(t)?Pan(t):t))}function r0(n,t){return uan(Iz(JO(n)?Pan(n):n,JO(t)?Pan(t):t))}function c0(n){return rbn(yz(fan(H$n(n,32)),32),fan(H$n(n,32)))}function a0(n){return yX(n),cL(n,14)?new tK(BB(n,14)):HB(n.Kc())}function u0(n,t){return Dnn(),n.c==t.c?Pln(t.d,n.d):Pln(n.c,t.c)}function o0(n,t){return Dnn(),n.c==t.c?Pln(n.d,t.d):Pln(n.c,t.c)}function s0(n,t){return Dnn(),n.c==t.c?Pln(n.d,t.d):Pln(t.c,n.c)}function h0(n,t){return Dnn(),n.c==t.c?Pln(t.d,n.d):Pln(t.c,n.c)}function f0(n,t){var e;e=Gy(MD(n.a.We((sWn(),OPt)))),VUn(n,t,e)}function l0(n,t){var e;e=BB(RX(n.g,t),57),Otn(t.d,new oP(n,e))}function b0(n,t){var e,i;return(e=oyn(n))<(i=oyn(t))?-1:e>i?1:0}function w0(n,t){var e;return e=S7(t),BB(RX(n.c,e),19).a}function d0(n,t){var e;for(e=n+"";e.length<t;)e="0"+e;return e}function g0(n){return null==n.c||0==n.c.length?"n_"+n.g:"n_"+n.c}function p0(n){return null==n.c||0==n.c.length?"n_"+n.b:"n_"+n.c}function v0(n,t){return n&&n.equals?n.equals(t):GC(n)===GC(t)}function m0(n,t){return 0==t?!!n.o&&0!=n.o.f:vpn(n,t)}function y0(n,t,e){var i;n.n&&t&&e&&(i=new Zu,WB(n.e,i))}function k0(n,t,e){var i;i=n.d[t.p],n.d[t.p]=n.d[e.p],n.d[e.p]=i}function j0(n,t,e){this.d=n,this.j=t,this.e=e,this.o=-1,this.p=3}function E0(n,t,e){this.d=n,this.k=t,this.f=e,this.o=-1,this.p=5}function T0(n,t,e){Ap.call(this,25),this.b=n,this.a=t,this.c=e}function M0(n){wWn(),Ap.call(this,n),this.c=!1,this.a=!1}function S0(n,t,e,i,r,c){Hen.call(this,n,t,e,i,r),c&&(this.o=-2)}function P0(n,t,e,i,r,c){qen.call(this,n,t,e,i,r),c&&(this.o=-2)}function I0(n,t,e,i,r,c){J5.call(this,n,t,e,i,r),c&&(this.o=-2)}function C0(n,t,e,i,r,c){Uen.call(this,n,t,e,i,r),c&&(this.o=-2)}function O0(n,t,e,i,r,c){Z5.call(this,n,t,e,i,r),c&&(this.o=-2)}function A0(n,t,e,i,r,c){Gen.call(this,n,t,e,i,r),c&&(this.o=-2)}function $0(n,t,e,i,r,c){zen.call(this,n,t,e,i,r),c&&(this.o=-2)}function L0(n,t,e,i,r,c){n6.call(this,n,t,e,i,r),c&&(this.o=-2)}function N0(n,t,e,i){jp.call(this,e),this.b=n,this.c=t,this.d=i}function x0(n,t){this.a=new Np,this.d=new Np,this.f=n,this.c=t}function D0(){this.c=new $$,this.a=new bY,this.b=new em,bM()}function R0(){Nun(),this.b=new xp,this.a=new xp,this.c=new Np}function _0(n,t){this.g=n,this.d=(R5(),eLt),this.a=eLt,this.b=t}function K0(n,t){this.f=n,this.a=(R5(),tLt),this.c=tLt,this.b=t}function F0(n,t){!n.c&&(n.c=new Ecn(n,0)),MHn(n.c,(Uqn(),LLt),t)}function B0(){B0=O,Hkt=new wI("DFS",0),Bkt=new wI("BFS",1)}function H0(n,t,e){var i;return!!(i=BB(n.Zb().xc(t),14))&&i.Hc(e)}function q0(n,t,e){var i;return!!(i=BB(n.Zb().xc(t),14))&&i.Mc(e)}function G0(n,t,e,i){return n.a+=""+fx(null==t?zWn:Bbn(t),e,i),n}function z0(n,t,e,i,r,c){return Rcn(n,t,e,c),Jfn(n,i),tln(n,r),n}function U0(n){return Px(n.b.b!=n.d.a),n.c=n.b=n.b.b,--n.a,n.c.c}function X0(n){for(;n.d>0&&0==n.a[--n.d];);0==n.a[n.d++]&&(n.e=0)}function W0(n){return n.a?0==n.e.length?n.a.a:n.a.a+""+n.e:n.c}function V0(n){return!(!n.a||0==H7(n.a.a).i||n.b&&_vn(n.b))}function Q0(n){return!(!n.u||0==a4(n.u.a).i||n.n&&Rvn(n.n))}function Y0(n){return yq(n.e.Hd().gc()*n.c.Hd().gc(),16,new zf(n))}function J0(n,t){return FU(fan(n.q.getTime()),fan(t.q.getTime()))}function Z0(n){return BB(Qgn(n,x8(yut,c1n,17,n.c.length,0,1)),474)}function n2(n){return BB(Qgn(n,x8(Out,a1n,10,n.c.length,0,1)),193)}function t2(n){return BZ(),!(b5(n)||!b5(n)&&n.c.i.c==n.d.i.c)}function e2(n,t,e){yX(n),xyn(new CZ(new tK(n),t,e))}function i2(n,t,e){yX(n),Dyn(new OZ(new tK(n),t,e))}function r2(n,t){var e;return e=1-t,n.a[e]=wrn(n.a[e],e),wrn(n,t)}function c2(n,t){var e;n.e=new Jm,m$(e=wDn(t),n.c),CDn(n,e,0)}function a2(n,t,e,i){var r;(r=new vu).a=t,r.b=e,r.c=i,DH(n.a,r)}function u2(n,t,e,i){var r;(r=new vu).a=t,r.b=e,r.c=i,DH(n.b,r)}function o2(n){var t,e;return e=tKn(t=new lX,n),yzn(t),e}function s2(){var n,t;return n=new _p,WB(V$t,t=n),t}function h2(n){return n.j.c=x8(Ant,HWn,1,0,5,1),TV(n.c),gV(n.a),n}function f2(n){return MM(),cL(n.g,10)?BB(n.g,10):null}function l2(n){return!EV(n).dc()&&(L$(n,new m),!0)}function b2(n){if(!("stack"in n))try{throw n}catch(t){}return n}function w2(n,t){if(n<0||n>=t)throw Hp(new Ay(LIn(n,t)));return n}function d2(n,t,e){if(n<0||t<n||t>e)throw Hp(new Ay(oPn(n,t,e)))}function g2(n,t){if(TU(n.a,t),t.d)throw Hp(new dy(CYn));t.d=n}function p2(n,t){if(t.$modCount!=n.$modCount)throw Hp(new vv)}function v2(n,t){return!!cL(t,42)&&Mmn(n.a,BB(t,42))}function m2(n,t){return!!cL(t,42)&&Mmn(n.a,BB(t,42))}function y2(n,t){return!!cL(t,42)&&Mmn(n.a,BB(t,42))}function k2(n,t){return n.a<=n.b&&(t.ud(n.a++),!0)}function j2(n){var t;return JO(n)?-0==(t=n)?0:t:pnn(n)}function E2(n){var t;return EW(n),t=new F,gE(n.a,new gw(t)),t}function T2(n){var t;return EW(n),t=new K,gE(n.a,new dw(t)),t}function M2(n,t){this.a=n,Sb.call(this,n),LZ(t,n.gc()),this.b=t}function S2(n){this.e=n,this.b=this.e.a.entries(),this.a=new Array}function P2(n){return yq(n.e.Hd().gc()*n.c.Hd().gc(),273,new Gf(n))}function I2(n){return new J6((lin(n,NVn),ttn(rbn(rbn(5,n),n/10|0))))}function C2(n){return BB(Qgn(n,x8(Gut,u1n,11,n.c.length,0,1)),1943)}function O2(n,t,e){return e.f.c.length>0?BU(n.a,t,e):BU(n.b,t,e)}function A2(n,t,e){n.d&&y7(n.d.e,n),n.d=t,n.d&&kG(n.d.e,e,n)}function $2(n,t){vXn(t,n),aH(n.d),aH(BB(mMn(n,(HXn(),Agt)),207))}function L2(n,t){pXn(t,n),cH(n.d),cH(BB(mMn(n,(HXn(),Agt)),207))}function N2(n,t){var e,i;return i=null,(e=zJ(n,t))&&(i=e.fe()),i}function x2(n,t){var e,i;return i=null,(e=dnn(n,t))&&(i=e.ie()),i}function D2(n,t){var e,i;return i=null,(e=zJ(n,t))&&(i=e.ie()),i}function R2(n,t){var e,i;return i=null,(e=zJ(n,t))&&(i=yPn(e)),i}function _2(n,t,e){var i;return i=Qdn(e),w_n(n.g,i,t),w_n(n.i,t,e),t}function K2(n,t,e){var i;i=Ldn();try{return dR(n,t,e)}finally{y3(i)}}function F2(n){var t;t=n.Wg(),this.a=cL(t,69)?BB(t,69).Zh():t.Kc()}function B2(){Ym.call(this),this.j.c=x8(Ant,HWn,1,0,5,1),this.a=-1}function H2(n,t,e,i){this.d=n,this.n=t,this.g=e,this.o=i,this.p=-1}function q2(n,t,e,i){this.e=i,this.d=null,this.c=n,this.a=t,this.b=e}function G2(n,t,e){this.d=new Fd(this),this.e=n,this.i=t,this.f=e}function z2(){z2=O,Aft=new DP(eJn,0),$ft=new DP("TOP_LEFT",1)}function U2(){U2=O,Tmt=JW(iln(1),iln(4)),Emt=JW(iln(1),iln(2))}function X2(){X2=O,JEt=lhn((CM(),Pun(Gk(tTt,1),$Vn,551,0,[QEt])))}function W2(){W2=O,VEt=lhn((IM(),Pun(Gk(YEt,1),$Vn,482,0,[XEt])))}function V2(){V2=O,UTt=lhn((OM(),Pun(Gk(VTt,1),$Vn,530,0,[GTt])))}function Q2(){Q2=O,act=lhn((wM(),Pun(Gk(Pct,1),$Vn,481,0,[rct])))}function Y2(){return Dan(),Pun(Gk(Grt,1),$Vn,406,0,[Rrt,Nrt,xrt,Drt])}function J2(){return Z9(),Pun(Gk(Fet,1),$Vn,297,0,[Net,xet,Det,Ret])}function Z2(){return qpn(),Pun(Gk(cct,1),$Vn,394,0,[Zrt,Jrt,nct,tct])}function n3(){return Hpn(),Pun(Gk(Urt,1),$Vn,323,0,[Brt,Frt,Hrt,qrt])}function t3(){return Aun(),Pun(Gk(dut,1),$Vn,405,0,[Zat,eut,nut,tut])}function e3(){return Cun(),Pun(Gk(pst,1),$Vn,360,0,[ast,rst,cst,ist])}function i3(n,t,e,i){return cL(e,54)?new Ox(n,t,e,i):new sz(n,t,e,i)}function r3(){return Oun(),Pun(Gk(Cst,1),$Vn,411,0,[vst,mst,yst,kst])}function c3(n){return n.j==(kUn(),SCt)&&SN(UOn(n),oCt)}function a3(n,t){var e;SZ(e=t.a,t.c.d),MZ(e,t.d.d),Ztn(e.a,n.n)}function u3(n,t){return BB($N(Cz(BB(h6(n.k,t),15).Oc(),Qst)),113)}function o3(n,t){return BB($N(Oz(BB(h6(n.k,t),15).Oc(),Qst)),113)}function s3(n){return new w1(tcn(BB(n.a.dd(),14).gc(),n.a.cd()),16)}function h3(n){return cL(n,14)?BB(n,14).dc():!n.Kc().Ob()}function f3(n){return MM(),cL(n.g,145)?BB(n.g,145):null}function l3(n){if(n.e.g!=n.b)throw Hp(new vv);return!!n.c&&n.d>0}function b3(n){return Px(n.b!=n.d.c),n.c=n.b,n.b=n.b.a,++n.a,n.c.c}function w3(n,t){kW(t),$X(n.a,n.c,t),n.c=n.c+1&n.a.length-1,wyn(n)}function d3(n,t){kW(t),n.b=n.b-1&n.a.length-1,$X(n.a,n.b,t),wyn(n)}function g3(n,t){var e;for(e=n.j.c.length;e<t;e++)WB(n.j,n.rg())}function p3(n,t,e,i){var r;return r=i[t.g][e.g],Gy(MD(mMn(n.a,r)))}function v3(n,t,e,i,r){this.i=n,this.a=t,this.e=e,this.j=i,this.f=r}function m3(n,t,e,i,r){this.a=n,this.e=t,this.f=e,this.b=i,this.g=r}function y3(n){n&&Cnn((sk(),ttt)),--ctt,n&&-1!=utt&&(iS(utt),utt=-1)}function k3(){return bvn(),Pun(Gk(kvt,1),$Vn,197,0,[lvt,bvt,fvt,hvt])}function j3(){return zyn(),Pun(Gk(qyt,1),$Vn,393,0,[Ryt,_yt,Kyt,Fyt])}function E3(){return Omn(),Pun(Gk(Vjt,1),$Vn,340,0,[qjt,Bjt,Hjt,Fjt])}function T3(){return mdn(),Pun(Gk(YCt,1),$Vn,374,0,[_Ct,KCt,RCt,DCt])}function M3(){return Xyn(),Pun(Gk(RIt,1),$Vn,285,0,[MIt,jIt,EIt,TIt])}function S3(){return Mbn(),Pun(Gk(oIt,1),$Vn,218,0,[ZPt,YPt,QPt,JPt])}function P3(){return Fwn(),Pun(Gk(cOt,1),$Vn,311,0,[eOt,ZCt,tOt,nOt])}function I3(){return Bsn(),Pun(Gk(wOt,1),$Vn,396,0,[uOt,oOt,aOt,sOt])}function C3(n){return hZ(),hU(fAt,n)?BB(RX(fAt,n),331).ug():null}function O3(n,t,e){return t<0?qCn(n,e):BB(e,66).Nj().Sj(n,n.yh(),t)}function A3(n,t,e){var i;return i=Qdn(e),w_n(n.d,i,t),VW(n.e,t,e),t}function $3(n,t,e){var i;return i=Qdn(e),w_n(n.j,i,t),VW(n.k,t,e),t}function L3(n){var t;return tE(),t=new io,n&&HLn(t,n),t}function N3(n){var t;return t=n.ri(n.i),n.i>0&&aHn(n.g,0,t,0,n.i),t}function x3(n,t){var e;return nS(),!(e=BB(RX(mAt,n),55))||e.wj(t)}function D3(n){if(1!=n.p)throw Hp(new dv);return dG(n.f)<<24>>24}function R3(n){if(1!=n.p)throw Hp(new dv);return dG(n.k)<<24>>24}function _3(n){if(7!=n.p)throw Hp(new dv);return dG(n.k)<<16>>16}function K3(n){if(7!=n.p)throw Hp(new dv);return dG(n.f)<<16>>16}function F3(n){var t;for(t=0;n.Ob();)n.Pb(),t=rbn(t,1);return ttn(t)}function B3(n,t){var e;return e=new Ck,n.xd(e),e.a+="..",t.yd(e),e.a}function H3(n,t,e){var i;i=BB(RX(n.g,e),57),WB(n.a.c,new rC(t,i))}function q3(n,t,e){return Tz(MD(qC(AY(n.f,t))),MD(qC(AY(n.f,e))))}function G3(n,t,e){return UFn(n,t,e,cL(t,99)&&0!=(BB(t,18).Bb&BQn))}function z3(n,t,e){return pBn(n,t,e,cL(t,99)&&0!=(BB(t,18).Bb&BQn))}function U3(n,t,e){return x$n(n,t,e,cL(t,99)&&0!=(BB(t,18).Bb&BQn))}function X3(n,t){return n==(uSn(),Iut)&&t==Iut?4:n==Iut||t==Iut?8:32}function W3(n,t){return GC(t)===GC(n)?"(this Map)":null==t?zWn:Bbn(t)}function V3(n,t){return BB(null==t?qC(AY(n.f,null)):hS(n.g,t),281)}function Q3(n,t,e){var i;return i=Qdn(e),VW(n.b,i,t),VW(n.c,t,e),t}function Y3(n,t){var e;for(e=t;e;)Kx(n,e.i,e.j),e=JJ(e);return n}function J3(n,t){var e;return e=rY(HB(new I7(n,t))),Iq(new I7(n,t)),e}function Z3(n,t){var e;return ZM(),TSn(e=BB(n,66).Mj(),t),e.Ok(t)}function n4(n,t,e,i,r){WB(t,mIn(r,X$n(r,e,i))),UMn(n,r,t)}function t4(n,t,e){n.i=0,n.e=0,t!=e&&(Won(n,t,e),Xon(n,t,e))}function e4(n,t){var e;e=n.q.getHours(),n.q.setFullYear(t+sQn),lBn(n,e)}function i4(n,t,e){if(e){var i=e.ee();n.a[t]=i(e)}else delete n.a[t]}function r4(n,t,e){if(e){var i=e.ee();e=i(e)}else e=void 0;n.a[t]=e}function c4(n){if(n<0)throw Hp(new By("Negative array size: "+n))}function a4(n){return n.n||(P5(n),n.n=new YG(n,VAt,n),kY(n)),n.n}function u4(n){return Px(n.a<n.c.a.length),n.b=n.a,Ann(n),n.c.b[n.b]}function o4(n){n.b!=n.c&&(n.a=x8(Ant,HWn,1,8,5,1),n.b=0,n.c=0)}function s4(n){this.b=new xp,this.c=new xp,this.d=new xp,this.a=n}function h4(n,t){wWn(),Ap.call(this,n),this.a=t,this.c=-1,this.b=-1}function f4(n,t,e,i){j0.call(this,1,e,i),Fh(this),this.c=n,this.b=t}function l4(n,t,e,i){E0.call(this,1,e,i),Fh(this),this.c=n,this.b=t}function b4(n,t,e,i,r,c,a){kin.call(this,t,i,r,c,a),this.c=n,this.a=e}function w4(n,t,e){this.e=n,this.a=Ant,this.b=ARn(t),this.c=t,this.d=e}function d4(n){this.e=n,this.c=this.e.a,this.b=this.e.g,this.d=this.e.i}function g4(n){this.c=n,this.a=BB(Ckn(n),148),this.b=this.a.Aj().Nh()}function p4(n){this.d=n,this.b=this.d.a.entries(),this.a=this.b.next()}function v4(){xp.call(this),jx(this),this.d.b=this.d,this.d.a=this.d}function m4(n,t){$R.call(this),this.a=n,this.b=t,WB(this.a.b,this)}function y4(n,t){return iO(null!=t?SJ(n,t):qC(AY(n.f,t)))}function k4(n,t){return iO(null!=t?SJ(n,t):qC(AY(n.f,t)))}function j4(n,t){var e;for(e=0;e<t;++e)$X(n,e,new Ub(BB(n[e],42)))}function E4(n,t){var e;for(e=n.d-1;e>=0&&n.a[e]===t[e];e--);return e<0}function T4(n,t){var e;return zsn(),0!=(e=n.j.g-t.j.g)?e:0}function M4(n,t){return kW(t),null!=n.a?PG(t.Kb(n.a)):Set}function S4(n){var t;return n?new Lq(n):(qrn(t=new fA,n),t)}function P4(n,t){return t.b.Kb(T7(n,t.c.Ee(),new yw(t)))}function I4(n){yTn(),hL(this,dG(e0(kz(n,24),sYn)),dG(e0(n,sYn)))}function C4(){C4=O,pit=lhn((hpn(),Pun(Gk(yit,1),$Vn,428,0,[dit,wit])))}function O4(){O4=O,kit=lhn((Rnn(),Pun(Gk(_it,1),$Vn,427,0,[vit,mit])))}function A4(){A4=O,Kct=lhn((_nn(),Pun(Gk($at,1),$Vn,424,0,[Dct,Rct])))}function $4(){$4=O,zut=lhn((Srn(),Pun(Gk(Wut,1),$Vn,511,0,[qut,Hut])))}function L4(){L4=O,Cht=lhn((Knn(),Pun(Gk(Lht,1),$Vn,419,0,[Sht,Pht])))}function N4(){N4=O,Uht=lhn((g7(),Pun(Gk(Zht,1),$Vn,479,0,[Ght,qht])))}function x4(){x4=O,tmt=lhn((A6(),Pun(Gk(cmt,1),$Vn,376,0,[Zvt,Jvt])))}function D4(){D4=O,Bvt=lhn((U7(),Pun(Gk(zvt,1),$Vn,421,0,[_vt,Kvt])))}function R4(){R4=O,oht=lhn((V8(),Pun(Gk(lht,1),$Vn,422,0,[cht,aht])))}function _4(){_4=O,Nft=lhn((z2(),Pun(Gk(Glt,1),$Vn,420,0,[Aft,$ft])))}function K4(){K4=O,Pyt=lhn((O6(),Pun(Gk(xyt,1),$Vn,520,0,[Myt,Tyt])))}function F4(){F4=O,Gmt=lhn((Q4(),Pun(Gk(Vmt,1),$Vn,523,0,[Hmt,Bmt])))}function B4(){B4=O,iyt=lhn((gJ(),Pun(Gk(ayt,1),$Vn,516,0,[tyt,nyt])))}function H4(){H4=O,uyt=lhn((oZ(),Pun(Gk(Syt,1),$Vn,515,0,[ryt,cyt])))}function q4(){q4=O,Dyt=lhn((dJ(),Pun(Gk(Byt,1),$Vn,455,0,[Lyt,Nyt])))}function G4(){G4=O,Gkt=lhn((B0(),Pun(Gk(Jkt,1),$Vn,425,0,[Hkt,Bkt])))}function z4(){z4=O,Zkt=lhn((Prn(),Pun(Gk(ijt,1),$Vn,495,0,[Qkt,Ykt])))}function U4(){U4=O,Fkt=lhn((sZ(),Pun(Gk(qkt,1),$Vn,480,0,[Rkt,_kt])))}function X4(){X4=O,ojt=lhn((D9(),Pun(Gk(ljt,1),$Vn,426,0,[cjt,ajt])))}function W4(){W4=O,QTt=lhn((Lun(),Pun(Gk(YTt,1),$Vn,429,0,[WTt,XTt])))}function V4(){V4=O,eTt=lhn(($6(),Pun(Gk(oTt,1),$Vn,430,0,[nTt,ZEt])))}function Q4(){Q4=O,Hmt=new JP("UPPER",0),Bmt=new JP("LOWER",1)}function Y4(n,t){var e;qQ(e=new py,"x",t.a),qQ(e,"y",t.b),nW(n,e)}function J4(n,t){var e;qQ(e=new py,"x",t.a),qQ(e,"y",t.b),nW(n,e)}function Z4(n,t){var e,i;i=!1;do{i|=e=bon(n,t)}while(e);return i}function n5(n,t){var e,i;for(e=t,i=0;e>0;)i+=n.a[e],e-=e&-e;return i}function t5(n,t){var e;for(e=t;e;)Kx(n,-e.i,-e.j),e=JJ(e);return n}function e5(n,t){var e,i;for(kW(t),i=n.Kc();i.Ob();)e=i.Pb(),t.td(e)}function i5(n,t){var e;return new vT(e=t.cd(),n.e.pc(e,BB(t.dd(),14)))}function r5(n,t,e,i){var r;(r=new $).c=t,r.b=e,r.a=i,i.b=e.a=r,++n.b}function c5(n,t,e){var i;return l1(t,n.c.length),i=n.c[t],n.c[t]=e,i}function a5(n,t,e){return BB(null==t?jIn(n.f,null,e):ubn(n.g,t,e),281)}function u5(n){return n.c&&n.d?p0(n.c)+"->"+p0(n.d):"e_"+PN(n)}function o5(n,t){return(Qln(n),jE(new Rq(n,new Q9(t,n.a)))).sd(tit)}function s5(){return yMn(),Pun(Gk(Uat,1),$Vn,356,0,[Rat,_at,Kat,Fat,Bat])}function h5(){return kUn(),Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])}function f5(n){return Dk(),function(){return K2(n,this,arguments)}}function l5(){return Date.now?Date.now():(new Date).getTime()}function b5(n){return!(!n.c||!n.d||!n.c.i||n.c.i!=n.d.i)}function w5(n){if(!n.c.Sb())throw Hp(new yv);return n.a=!0,n.c.Ub()}function d5(n){n.i=0,yS(n.b,null),yS(n.c,null),n.a=null,n.e=null,++n.g}function g5(n){dS.call(this,null==n?zWn:Bbn(n),cL(n,78)?BB(n,78):null)}function p5(n){eWn(),Bp(this),this.a=new YT,dsn(this,n),DH(this.a,n)}function v5(){xA(this),this.b=new xI(RQn,RQn),this.a=new xI(_Qn,_Qn)}function m5(n,t){this.c=0,this.b=t,pO.call(this,n,17493),this.a=this.c}function y5(n){k5(),Qet||(this.c=n,this.e=!0,this.a=new Np)}function k5(){k5=O,Qet=!0,Wet=!1,Vet=!1,Jet=!1,Yet=!1}function j5(n,t){return!!cL(t,149)&&m_(n.c,BB(t,149).c)}function E5(n,t){var e;return e=0,n&&(e+=n.f.a/2),t&&(e+=t.f.a/2),e}function T5(n,t){return BB(lnn(n.d,t),23)||BB(lnn(n.e,t),23)}function M5(n){this.b=n,AL.call(this,n),this.a=BB(yan(this.b.a,4),126)}function S5(n){this.b=n,ax.call(this,n),this.a=BB(yan(this.b.a,4),126)}function P5(n){return n.t||(n.t=new dp(n),sln(new xy(n),0,n.t)),n.t}function I5(){return Ffn(),Pun(Gk(WPt,1),$Vn,103,0,[BPt,FPt,KPt,_Pt,HPt])}function C5(){return cpn(),Pun(Gk(JIt,1),$Vn,249,0,[BIt,qIt,KIt,FIt,HIt])}function O5(){return rpn(),Pun(Gk(jMt,1),$Vn,175,0,[hMt,sMt,uMt,fMt,oMt])}function A5(){return $Sn(),Pun(Gk(zTt,1),$Vn,316,0,[iTt,rTt,uTt,cTt,aTt])}function $5(){return Nvn(),Pun(Gk(Avt,1),$Vn,315,0,[yvt,pvt,vvt,gvt,mvt])}function L5(){return Vvn(),Pun(Gk(Iht,1),$Vn,335,0,[yht,mht,jht,Eht,kht])}function N5(){return YLn(),Pun(Gk(zEt,1),$Vn,355,0,[DEt,xEt,_Et,REt,KEt])}function x5(){return LEn(),Pun(Gk(_st,1),$Vn,363,0,[Mst,Pst,Ist,Sst,Tst])}function D5(){return Tbn(),Pun(Gk(ivt,1),$Vn,163,0,[qlt,Klt,Flt,Blt,Hlt])}function R5(){var n,t;R5=O,iE(),t=new Ev,tLt=t,n=new Om,eLt=n}function _5(n){var t;return n.c||cL(t=n.r,88)&&(n.c=BB(t,26)),n.c}function K5(n){return n.e=3,n.d=n.Yb(),2!=n.e&&(n.e=0,!0)}function F5(n){return M$(n&SQn,n>>22&SQn,n<0?PQn:0)}function B5(n){var t,e,i;for(e=0,i=(t=n).length;e<i;++e)jW(t[e])}function H5(n,t){var e,i;(e=BB(bfn(n.c,t),14))&&(i=e.gc(),e.$b(),n.d-=i)}function q5(n,t){var e;return!!(e=lsn(n,t.cd()))&&cV(e.e,t.dd())}function G5(n,t){return 0==t||0==n.e?n:t>0?Edn(n,t):Cxn(n,-t)}function z5(n,t){return 0==t||0==n.e?n:t>0?Cxn(n,t):Edn(n,-t)}function U5(n){if(dAn(n))return n.c=n.a,n.a.Pb();throw Hp(new yv)}function X5(n){var t,e;return t=n.c.i,e=n.d.i,t.k==(uSn(),Mut)&&e.k==Mut}function W5(n){var t;return qan(t=new wY,n),hon(t,(HXn(),vgt),null),t}function V5(n,t,e){var i;return(i=n.Yg(t))>=0?n._g(i,e,!0):cOn(n,t,e)}function Q5(n,t,e,i){var r;for(r=0;r<Zit;r++)XG(n.a[t.g][r],e,i[t.g])}function Y5(n,t,e,i){var r;for(r=0;r<nrt;r++)UG(n.a[r][t.g],e,i[t.g])}function J5(n,t,e,i,r){j0.call(this,t,i,r),Fh(this),this.c=n,this.a=e}function Z5(n,t,e,i,r){E0.call(this,t,i,r),Fh(this),this.c=n,this.a=e}function n6(n,t,e,i,r){i6.call(this,t,i,r),Fh(this),this.c=n,this.a=e}function t6(n,t,e,i,r){i6.call(this,t,i,r),Fh(this),this.c=n,this.b=e}function e6(n,t,e){jp.call(this,e),this.b=n,this.c=t,this.d=(Bwn(),z$t)}function i6(n,t,e){this.d=n,this.k=t?1:0,this.f=e?1:0,this.o=-1,this.p=0}function r6(n,t,e){var i;Tcn(i=new X$(n.a),n.a.a),jIn(i.f,t,e),n.a.a=i}function c6(n,t){n.qi(n.i+1),jL(n,n.i,n.oi(n.i,t)),n.bi(n.i++,t),n.ci()}function a6(n){var t,e;++n.j,t=n.g,e=n.i,n.g=null,n.i=0,n.di(e,t),n.ci()}function u6(n){var t;return yX(n),$on(t=new J6(ZW(n.length)),n),t}function o6(n){var t;return yX(n),JPn(t=n?new tK(n):HB(n.Kc())),sfn(t)}function s6(n,t){var e;return l1(t,n.c.length),e=n.c[t],PE(n.c,t,1),e}function h6(n,t){var e;return!(e=BB(n.c.xc(t),14))&&(e=n.ic(t)),n.pc(t,e)}function f6(n,t){var e,i;return kW(n),e=n,kW(t),e==(i=t)?0:e<i?-1:1}function l6(n){var t;return t=n.e+n.f,isNaN(t)&&W_(n.d)?n.d:t}function b6(n,t){return n.a?oO(n.a,n.b):n.a=new lN(n.d),aO(n.a,t),n}function w6(n,t){if(n<0||n>t)throw Hp(new Ay(dIn(n,t,"index")));return n}function d6(n,t,e,i){var r;return vTn(r=x8(ANt,hQn,25,t,15,1),n,t,e,i),r}function g6(n,t){var e;e=n.q.getHours()+(t/60|0),n.q.setMinutes(t),lBn(n,e)}function p6(n,t){return e.Math.min(W8(t.a,n.d.d.c),W8(t.b,n.d.d.c))}function v6(n,t){return XC(t)?null==t?gAn(n.f,null):Gan(n.g,t):gAn(n.f,t)}function m6(n){this.c=n,this.a=new Wb(this.c.a),this.b=new Wb(this.c.b)}function y6(){this.e=new Np,this.c=new Np,this.d=new Np,this.b=new Np}function k6(){this.g=new Bv,this.b=new Bv,this.a=new Np,this.k=new Np}function j6(n,t,e){this.a=n,this.c=t,this.d=e,WB(t.e,this),WB(e.b,this)}function E6(n,t){gO.call(this,t.rd(),-6&t.qd()),kW(n),this.a=n,this.b=t}function T6(n,t){pO.call(this,t.rd(),-6&t.qd()),kW(n),this.a=n,this.b=t}function M6(n,t){vO.call(this,t.rd(),-6&t.qd()),kW(n),this.a=n,this.b=t}function S6(n,t,e){this.a=n,this.b=t,this.c=e,WB(n.t,this),WB(t.i,this)}function P6(){this.b=new YT,this.a=new YT,this.b=new YT,this.a=new YT}function I6(){I6=O,TMt=new up("org.eclipse.elk.labels.labelManager")}function C6(){C6=O,est=new iR("separateLayerConnections",(Cun(),ast))}function O6(){O6=O,Myt=new uI("REGULAR",0),Tyt=new uI("CRITICAL",1)}function A6(){A6=O,Zvt=new XP("STACKED",0),Jvt=new XP("SEQUENCED",1)}function $6(){$6=O,nTt=new TI("FIXED",0),ZEt=new TI("CENTER_NODE",1)}function L6(n,t){var e;return e=xGn(n,t),n.b=new mrn(e.c.length),yqn(n,e)}function N6(n,t,e){return++n.e,--n.f,BB(n.d[t].$c(e),133).dd()}function x6(n){var t;return n.a||cL(t=n.r,148)&&(n.a=BB(t,148)),n.a}function D6(n){return n.a?n.e?D6(n.e):null:n}function R6(n,t){return n.p<t.p?1:n.p>t.p?-1:0}function _6(n,t){return kW(t),n.c<n.d&&(n.ze(t,n.c++),!0)}function K6(n,t){return!!hU(n.a,t)&&(v6(n.a,t),!0)}function F6(n){var t;return t=n.cd(),RB(BB(n.dd(),14).Nc(),new Vf(t))}function B6(n){var t;return t=BB(VU(n.b,n.b.length),9),new Y_(n.a,t,n.c)}function H6(n){return Qln(n),new AD(n,new ZB(n,n.a.e,4|n.a.d))}function q6(n){var t;for(EW(n),t=0;n.a.sd(new fn);)t=rbn(t,1);return t}function G6(n,t,e){var i,r;for(i=0,r=0;r<t.length;r++)i+=n.$f(t[r],i,e)}function z6(n,t){var e;n.C&&((e=BB(oV(n.b,t),124).n).d=n.C.d,e.a=n.C.a)}function U6(n,t,e){return w2(t,n.e.Hd().gc()),w2(e,n.c.Hd().gc()),n.a[t][e]}function X6(n,t){ODn(),this.e=n,this.d=1,this.a=Pun(Gk(ANt,1),hQn,25,15,[t])}function W6(n,t,e,i){this.f=n,this.e=t,this.d=e,this.b=i,this.c=i?i.d:null}function V6(n){var t,e,i,r;r=n.d,t=n.a,e=n.b,i=n.c,n.d=e,n.a=i,n.b=r,n.c=t}function Q6(n,t,e,i){mFn(n,t,e,pBn(n,t,i,cL(t,99)&&0!=(BB(t,18).Bb&BQn)))}function Y6(n,t){OTn(t,"Label management",1),iO(mMn(n,(I6(),TMt))),HSn(t)}function J6(n){xA(this),vH(n>=0,"Initial capacity must not be negative")}function Z6(){Z6=O,Wit=lhn((Dtn(),Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])))}function n8(){n8=O,trt=lhn((J9(),Pun(Gk(ert,1),$Vn,461,0,[Yit,Qit,Jit])))}function t8(){t8=O,urt=lhn((G7(),Pun(Gk(Ort,1),$Vn,462,0,[crt,rrt,irt])))}function e8(){e8=O,Zet=lhn((qsn(),Pun(Gk(nit,1),$Vn,132,0,[zet,Uet,Xet])))}function i8(){i8=O,Lat=lhn((q7(),Pun(Gk(Hat,1),$Vn,379,0,[Oat,Cat,Aat])))}function r8(){r8=O,gut=lhn((Bfn(),Pun(Gk(mut,1),$Vn,423,0,[wut,but,lut])))}function c8(){c8=O,bht=lhn((Oin(),Pun(Gk(pht,1),$Vn,314,0,[hht,sht,fht])))}function a8(){a8=O,vht=lhn((uin(),Pun(Gk(Tht,1),$Vn,337,0,[wht,ght,dht])))}function u8(){u8=O,Nht=lhn((Jun(),Pun(Gk(Bht,1),$Vn,450,0,[Aht,Oht,$ht])))}function o8(){o8=O,Kst=lhn((Irn(),Pun(Gk(Wst,1),$Vn,361,0,[Rst,Dst,xst])))}function s8(){s8=O,Oft=lhn((z7(),Pun(Gk(Lft,1),$Vn,303,0,[Pft,Ift,Sft])))}function h8(){h8=O,Mft=lhn((_an(),Pun(Gk(Cft,1),$Vn,292,0,[jft,Eft,kft])))}function f8(){f8=O,svt=lhn((Mhn(),Pun(Gk(wvt,1),$Vn,378,0,[cvt,avt,uvt])))}function l8(){l8=O,Yvt=lhn((Hcn(),Pun(Gk(nmt,1),$Vn,375,0,[Xvt,Wvt,Vvt])))}function b8(){b8=O,Rvt=lhn((mon(),Pun(Gk(Fvt,1),$Vn,339,0,[Nvt,Lvt,xvt])))}function w8(){w8=O,Uvt=lhn((ain(),Pun(Gk(Qvt,1),$Vn,452,0,[Gvt,Hvt,qvt])))}function d8(){d8=O,gmt=lhn(($un(),Pun(Gk(Smt,1),$Vn,377,0,[bmt,wmt,lmt])))}function g8(){g8=O,amt=lhn((Usn(),Pun(Gk(hmt,1),$Vn,336,0,[emt,imt,rmt])))}function p8(){p8=O,fmt=lhn((dcn(),Pun(Gk(dmt,1),$Vn,338,0,[smt,umt,omt])))}function v8(){v8=O,Nmt=lhn((oin(),Pun(Gk(xmt,1),$Vn,454,0,[Omt,Amt,$mt])))}function m8(){m8=O,rjt=lhn((Ibn(),Pun(Gk(ujt,1),$Vn,442,0,[ejt,njt,tjt])))}function y8(){y8=O,bjt=lhn((Hsn(),Pun(Gk(Gjt,1),$Vn,380,0,[sjt,hjt,fjt])))}function k8(){k8=O,eEt=lhn((Sbn(),Pun(Gk(NEt,1),$Vn,381,0,[Zjt,nEt,Jjt])))}function j8(){j8=O,Qjt=lhn((Bcn(),Pun(Gk(Yjt,1),$Vn,293,0,[Xjt,Wjt,Ujt])))}function E8(){E8=O,UEt=lhn((Pbn(),Pun(Gk(WEt,1),$Vn,437,0,[HEt,qEt,GEt])))}function T8(){T8=O,kIt=lhn((ufn(),Pun(Gk(SIt,1),$Vn,334,0,[vIt,pIt,mIt])))}function M8(){M8=O,VPt=lhn((Rtn(),Pun(Gk(nIt,1),$Vn,272,0,[zPt,UPt,XPt])))}function S8(){return QEn(),Pun(Gk(aCt,1),$Vn,98,0,[YIt,QIt,VIt,UIt,WIt,XIt])}function P8(n,t){return!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),rdn(n.o,t)}function I8(n){return!n.g&&(n.g=new oo),!n.g.d&&(n.g.d=new lp(n)),n.g.d}function C8(n){return!n.g&&(n.g=new oo),!n.g.a&&(n.g.a=new bp(n)),n.g.a}function O8(n){return!n.g&&(n.g=new oo),!n.g.b&&(n.g.b=new fp(n)),n.g.b}function A8(n){return!n.g&&(n.g=new oo),!n.g.c&&(n.g.c=new wp(n)),n.g.c}function $8(n,t,e){var i,r;for(r=new Aan(t,n),i=0;i<e;++i)cvn(r);return r}function L8(n,t,e){var i,r;if(null!=e)for(i=0;i<t;++i)r=e[i],n.fi(i,r)}function N8(n,t,e,i){var r;return AFn(r=x8(ANt,hQn,25,t+1,15,1),n,t,e,i),r}function x8(n,t,e,i,r,c){var a;return a=Bmn(r,i),10!=r&&Pun(Gk(n,c),t,e,r,a),a}function D8(n,t,e,i){return e&&(i=e.gh(t,Awn(e.Tg(),n.c.Lj()),null,i)),i}function R8(n,t,e,i){return e&&(i=e.ih(t,Awn(e.Tg(),n.c.Lj()),null,i)),i}function _8(n,t,e){BB(n.b,65),BB(n.b,65),BB(n.b,65),Otn(n.a,new NK(e,t,n))}function K8(n,t,e){if(n<0||t>e||t<n)throw Hp(new Ok(mYn+n+kYn+t+hYn+e))}function F8(n){if(!n)throw Hp(new Fy("Unable to add element to queue"))}function B8(n){n?(this.c=n,this.b=null):(this.c=null,this.b=new Np)}function H8(n,t){PS.call(this,n,t),this.a=x8(_et,kVn,436,2,0,1),this.b=!0}function q8(n){non.call(this,n,0),jx(this),this.d.b=this.d,this.d.a=this.d}function G8(n){var t;return 0==(t=n.b).b?null:BB(Dpn(t,0),188).b}function z8(n,t){var e;return(e=new q).c=!0,e.d=t.dd(),YGn(n,t.cd(),e)}function U8(n,t){var e;e=n.q.getHours()+(t/3600|0),n.q.setSeconds(t),lBn(n,e)}function X8(n,t,e){var i;(i=n.b[e.c.p][e.p]).b+=t.b,i.c+=t.c,i.a+=t.a,++i.a}function W8(n,t){var i,r;return i=n.a-t.a,r=n.b-t.b,e.Math.sqrt(i*i+r*r)}function V8(){V8=O,cht=new EP("QUADRATIC",0),aht=new EP("SCANLINE",1)}function Q8(){Q8=O,mmt=WG(dq(new B2,(yMn(),Rat),(lWn(),kot)),Bat,qot)}function Y8(){return wEn(),Pun(Gk(qPt,1),$Vn,291,0,[ZMt,JMt,YMt,VMt,WMt,QMt])}function J8(){return wvn(),Pun(Gk(nSt,1),$Vn,248,0,[IMt,AMt,$Mt,LMt,CMt,OMt])}function Z8(){return $Pn(),Pun(Gk(uht,1),$Vn,227,0,[Zst,tht,Jst,nht,eht,Yst])}function n9(){return JMn(),Pun(Gk(mft,1),$Vn,275,0,[cft,eft,aft,rft,ift,tft])}function t9(){return Bjn(),Pun(Gk(uft,1),$Vn,274,0,[Qht,Vht,Jht,Wht,Yht,Xht])}function e9(){return TTn(),Pun(Gk(ovt,1),$Vn,313,0,[tvt,Zpt,Ypt,Jpt,evt,nvt])}function i9(){return gSn(),Pun(Gk(zht,1),$Vn,276,0,[Dht,xht,_ht,Rht,Fht,Kht])}function r9(){return DPn(),Pun(Gk(Kkt,1),$Vn,327,0,[Qyt,Uyt,Wyt,Xyt,Vyt,zyt])}function c9(){return lCn(),Pun(Gk(CCt,1),$Vn,273,0,[rCt,eCt,iCt,tCt,nCt,cCt])}function a9(){return nMn(),Pun(Gk(yIt,1),$Vn,312,0,[aIt,rIt,uIt,eIt,cIt,iIt])}function u9(){return uSn(),Pun(Gk($ut,1),$Vn,267,0,[Iut,Put,Mut,Cut,Sut,Tut])}function o9(n){Mx(!!n.c),p2(n.e,n),n.c.Qb(),n.c=null,n.b=dun(n),bD(n.e,n)}function s9(n){return p2(n.c.a.e,n),Px(n.b!=n.c.a.d),n.a=n.b,n.b=n.b.a,n.a}function h9(n){var t;return n.a||-1==n.b||(t=n.c.Tg(),n.a=itn(t,n.b)),n.a}function f9(n,t){return!(n.hi()&&n.Hc(t)||(n.Yh(t),0))}function l9(n,t){return OY(t,"Horizontal alignment cannot be null"),n.b=t,n}function b9(n,t,e){var i;return wWn(),i=ZUn(n,t),e&&i&&gW(n)&&(i=null),i}function w9(n,t,e){var i;for(i=n.Kc();i.Ob();)ZRn(BB(i.Pb(),37),t,e)}function d9(n,t){var e;for(e=t.Kc();e.Ob();)$_n(n,BB(e.Pb(),37),0,0)}function g9(n,t,i){var r;n.d[t.g]=i,(r=n.g.c)[t.g]=e.Math.max(r[t.g],i+1)}function p9(n,t){var e,i,r;return r=n.r,i=n.d,(e=cHn(n,t,!0)).b!=r||e.a!=i}function v9(n,t){return lS(n.e,t)||Jgn(n.e,t,new ipn(t)),BB(lnn(n.e,t),113)}function m9(n,t,e,i){return kW(n),kW(t),kW(e),kW(i),new jU(n,t,new G)}function y9(n,t,e,i){this.rj(),this.a=t,this.b=n,this.c=new Zz(this,t,e,i)}function k9(n,t,e,i,r,c){H2.call(this,t,i,r,c),Fh(this),this.c=n,this.b=e}function j9(n,t,e,i,r,c){H2.call(this,t,i,r,c),Fh(this),this.c=n,this.a=e}function E9(n,t,e){var i,r;r=null,(i=zJ(n,e))&&(r=yPn(i)),Xgn(t,e,r)}function T9(n,t,e){var i,r;r=null,(i=zJ(n,e))&&(r=yPn(i)),Xgn(t,e,r)}function M9(n,t,e){var i;return(i=$$n(n.b,t))?NHn(F7(n,i),e):null}function S9(n,t){var e;return(e=n.Yg(t))>=0?n._g(e,!0,!0):cOn(n,t,!0)}function P9(n,t){return Pln(Gy(MD(mMn(n,(hWn(),Tlt)))),Gy(MD(mMn(t,Tlt))))}function I9(){I9=O,Ukt=ogn(ogn(FM(new B2,(zyn(),_yt)),(DPn(),Qyt)),Uyt)}function C9(n,t,e){var i;return i=Non(n,t,e),n.b=new mrn(i.c.length),sDn(n,i)}function O9(n){if(n.b<=0)throw Hp(new yv);return--n.b,n.a-=n.c.c,iln(n.a)}function A9(n){var t;if(!n.a)throw Hp(new lV);return t=n.a,n.a=JJ(n.a),t}function $9(n){for(;!n.a;)if(!T_(n.c,new pw(n)))return!1;return!0}function L9(n){return yX(n),cL(n,198)?BB(n,198):new ol(n)}function N9(n){x9(),BB(n.We((sWn(),fPt)),174).Fc((lCn(),iCt)),n.Ye(hPt,null)}function x9(){x9=O,tMt=new bu,iMt=new wu,eMt=vsn((sWn(),hPt),tMt,qSt,iMt)}function D9(){D9=O,cjt=new pI("LEAF_NUMBER",0),ajt=new pI("NODE_SIZE",1)}function R9(n,t,e){n.a=t,n.c=e,n.b.a.$b(),yQ(n.d),n.e.a.c=x8(Ant,HWn,1,0,5,1)}function _9(n){n.a=x8(ANt,hQn,25,n.b+1,15,1),n.c=x8(ANt,hQn,25,n.b,15,1),n.d=0}function K9(n,t){n.a.ue(t.d,n.b)>0&&(WB(n.c,new mH(t.c,t.d,n.d)),n.b=t.d)}function F9(n,t){if(null==n.g||t>=n.i)throw Hp(new LO(t,n.i));return n.g[t]}function B9(n,t,e){if(xsn(n,e),null!=e&&!n.wj(e))throw Hp(new lv);return e}function H9(n){var t;if(n.Ek())for(t=n.i-1;t>=0;--t)Wtn(n,t);return N3(n)}function q9(n){var t,e;if(!n.b)return null;for(e=n.b;t=e.a[0];)e=t;return e}function G9(n,t){var e;return c4(t),(e=m7(n.slice(0,t),n)).length=t,e}function z9(n,t,e,i){PQ(),i=i||wet,gIn(n.slice(t,e),n,t,e,-t,i)}function U9(n,t,e,i,r){return t<0?cOn(n,e,i):BB(e,66).Nj().Pj(n,n.yh(),t,i,r)}function X9(n){return cL(n,172)?""+BB(n,172).a:null==n?null:Bbn(n)}function W9(n){return cL(n,172)?""+BB(n,172).a:null==n?null:Bbn(n)}function V9(n,t){if(t.a)throw Hp(new dy(CYn));TU(n.a,t),t.a=n,!n.j&&(n.j=t)}function Q9(n,t){vO.call(this,t.rd(),-16449&t.qd()),kW(n),this.a=n,this.c=t}function Y9(n,t){var e,i;return i=t/n.c.Hd().gc()|0,e=t%n.c.Hd().gc(),U6(n,i,e)}function J9(){J9=O,Yit=new GS(cJn,0),Qit=new GS(eJn,1),Jit=new GS(aJn,2)}function Z9(){Z9=O,Net=new gS("All",0),xet=new LA,Det=new A$,Ret=new NA}function n7(){n7=O,Ket=lhn((Z9(),Pun(Gk(Fet,1),$Vn,297,0,[Net,xet,Det,Ret])))}function t7(){t7=O,rut=lhn((Aun(),Pun(Gk(dut,1),$Vn,405,0,[Zat,eut,nut,tut])))}function e7(){e7=O,Krt=lhn((Dan(),Pun(Gk(Grt,1),$Vn,406,0,[Rrt,Nrt,xrt,Drt])))}function i7(){i7=O,zrt=lhn((Hpn(),Pun(Gk(Urt,1),$Vn,323,0,[Brt,Frt,Hrt,qrt])))}function r7(){r7=O,ict=lhn((qpn(),Pun(Gk(cct,1),$Vn,394,0,[Zrt,Jrt,nct,tct])))}function c7(){c7=O,Hyt=lhn((zyn(),Pun(Gk(qyt,1),$Vn,393,0,[Ryt,_yt,Kyt,Fyt])))}function a7(){a7=O,ost=lhn((Cun(),Pun(Gk(pst,1),$Vn,360,0,[ast,rst,cst,ist])))}function u7(){u7=O,zjt=lhn((Omn(),Pun(Gk(Vjt,1),$Vn,340,0,[qjt,Bjt,Hjt,Fjt])))}function o7(){o7=O,Est=lhn((Oun(),Pun(Gk(Cst,1),$Vn,411,0,[vst,mst,yst,kst])))}function s7(){s7=O,dvt=lhn((bvn(),Pun(Gk(kvt,1),$Vn,197,0,[lvt,bvt,fvt,hvt])))}function h7(){h7=O,fOt=lhn((Bsn(),Pun(Gk(wOt,1),$Vn,396,0,[uOt,oOt,aOt,sOt])))}function f7(){f7=O,PIt=lhn((Xyn(),Pun(Gk(RIt,1),$Vn,285,0,[MIt,jIt,EIt,TIt])))}function l7(){l7=O,tIt=lhn((Mbn(),Pun(Gk(oIt,1),$Vn,218,0,[ZPt,YPt,QPt,JPt])))}function b7(){b7=O,rOt=lhn((Fwn(),Pun(Gk(cOt,1),$Vn,311,0,[eOt,ZCt,tOt,nOt])))}function w7(){w7=O,BCt=lhn((mdn(),Pun(Gk(YCt,1),$Vn,374,0,[_Ct,KCt,RCt,DCt])))}function d7(){d7=O,qBn(),HLt=RQn,BLt=_Qn,GLt=new Nb(RQn),qLt=new Nb(_Qn)}function g7(){g7=O,Ght=new OP(QZn,0),qht=new OP("IMPROVE_STRAIGHTNESS",1)}function p7(n,t){return hH(),WB(n,new rC(t,iln(t.e.c.length+t.g.c.length)))}function v7(n,t){return hH(),WB(n,new rC(t,iln(t.e.c.length+t.g.c.length)))}function m7(n,t){return 10!=vnn(t)&&Pun(tsn(t),t.hm,t.__elementTypeId$,vnn(t),n),n}function y7(n,t){var e;return-1!=(e=E7(n,t,0))&&(s6(n,e),!0)}function k7(n,t){var e;return(e=BB(v6(n.e,t),387))?(RH(e),e.e):null}function j7(n){var t;return JO(n)&&(t=0-n,!isNaN(t))?t:uan(aon(n))}function E7(n,t,e){for(;e<n.c.length;++e)if(cV(t,n.c[e]))return e;return-1}function T7(n,t,e){var i;return EW(n),(i=new sn).a=t,n.a.Nb(new CS(i,e)),i.a}function M7(n){var t;return EW(n),t=x8(xNt,qQn,25,0,15,1),gE(n.a,new ww(t)),t}function S7(n){var t;return t=BB(xq(n.j,0),11),BB(mMn(t,(hWn(),dlt)),11)}function P7(n){var t;if(!Zin(n))throw Hp(new yv);return n.e=1,t=n.d,n.d=null,t}function I7(n,t){var e;this.f=n,this.b=t,e=BB(RX(n.b,t),283),this.c=e?e.b:null}function C7(){GK(),this.b=new xp,this.f=new xp,this.g=new xp,this.e=new xp}function O7(n,t){this.a=x8(Out,a1n,10,n.a.c.length,0,1),Qgn(n.a,this.a),this.b=t}function A7(n){var t;for(t=n.p+1;t<n.c.a.c.length;++t)--BB(xq(n.c.a,t),10).p}function $7(n){var t;null!=(t=n.Ai())&&-1!=n.d&&BB(t,92).Ng(n),n.i&&n.i.Fi()}function L7(n){V$(this),this.g=n?IY(n,n.$d()):null,this.f=n,jQ(this),this._d()}function N7(n,t,e,i,r,c,a){kin.call(this,t,i,r,c,a),Fh(this),this.c=n,this.b=e}function x7(n,t,e,i,r){return kW(n),kW(t),kW(e),kW(i),kW(r),new jU(n,t,i)}function D7(n,t){if(t<0)throw Hp(new Ay(n5n+t));return g3(n,t+1),xq(n.j,t)}function R7(n,t,e,i){if(!n)throw Hp(new Ky($Rn(t,Pun(Gk(Ant,1),HWn,1,5,[e,i]))))}function _7(n,t){return cV(t,xq(n.f,0))||cV(t,xq(n.f,1))||cV(t,xq(n.f,2))}function K7(n,t){L_(BB(BB(n.f,33).We((sWn(),uPt)),98))&&Qbn(yV(BB(n.f,33)),t)}function F7(n,t){var e,i;return!(i=(e=BB(t,675)).Oh())&&e.Rh(i=new RC(n,t)),i}function B7(n,t){var e,i;return!(i=(e=BB(t,677)).pk())&&e.tk(i=new _0(n,t)),i}function H7(n){return n.b||(n.b=new JG(n,VAt,n),!n.a&&(n.a=new oR(n,n))),n.b}function q7(){q7=O,Oat=new WS("XY",0),Cat=new WS("X",1),Aat=new WS("Y",2)}function G7(){G7=O,crt=new zS("TOP",0),rrt=new zS(eJn,1),irt=new zS(oJn,2)}function z7(){z7=O,Pft=new xP(QZn,0),Ift=new xP("TOP",1),Sft=new xP(oJn,2)}function U7(){U7=O,_vt=new GP("INPUT_ORDER",0),Kvt=new GP("PORT_DEGREE",1)}function X7(){X7=O,btt=M$(SQn,SQn,524287),wtt=M$(0,0,IQn),dtt=F5(1),F5(2),gtt=F5(0)}function W7(n,t,e){n.a.c=x8(Ant,HWn,1,0,5,1),Xqn(n,t,e),0==n.a.c.length||fKn(n,t)}function V7(n){var t,e;return YU(n,0,e=n.length,t=x8(ONt,WVn,25,e,15,1),0),t}function Q7(n){var t;return n.dh()||(t=bX(n.Tg())-n.Ah(),n.ph().bk(t)),n.Pg()}function Y7(n){var t;return null==(t=een(yan(n,32)))&&(fgn(n),t=een(yan(n,32))),t}function J7(n,t){var e;return(e=Awn(n.d,t))>=0?Zpn(n,e,!0,!0):cOn(n,t,!0)}function Z7(n,t){var e,i;return MM(),e=f3(n),i=f3(t),!!e&&!!i&&!_pn(e.k,i.k)}function nnn(n,t){Pen(n,null==t||W_((kW(t),t))||isNaN((kW(t),t))?0:(kW(t),t))}function tnn(n,t){Ien(n,null==t||W_((kW(t),t))||isNaN((kW(t),t))?0:(kW(t),t))}function enn(n,t){Sen(n,null==t||W_((kW(t),t))||isNaN((kW(t),t))?0:(kW(t),t))}function inn(n,t){Men(n,null==t||W_((kW(t),t))||isNaN((kW(t),t))?0:(kW(t),t))}function rnn(n){(this.q?this.q:(SQ(),SQ(),het)).Ac(n.q?n.q:(SQ(),SQ(),het))}function cnn(n,t){return cL(t,99)&&0!=(BB(t,18).Bb&BQn)?new xO(t,n):new Aan(t,n)}function ann(n,t){return cL(t,99)&&0!=(BB(t,18).Bb&BQn)?new xO(t,n):new Aan(t,n)}function unn(n,t){Vrt=new it,ect=t,BB((Wrt=n).b,65),_8(Wrt,Vrt,null),uqn(Wrt)}function onn(n,t,e){var i;return i=n.g[t],jL(n,t,n.oi(t,e)),n.gi(t,e,i),n.ci(),i}function snn(n,t){var e;return(e=n.Xc(t))>=0&&(n.$c(e),!0)}function hnn(n){var t;return n.d!=n.r&&(t=Ckn(n),n.e=!!t&&t.Cj()==E9n,n.d=t),n.e}function fnn(n,t){var e;for(yX(n),yX(t),e=!1;t.Ob();)e|=n.Fc(t.Pb());return e}function lnn(n,t){var e;return(e=BB(RX(n.e,t),387))?(uL(n,e),e.e):null}function bnn(n){var t,e;return t=n/60|0,0==(e=n%60)?""+t:t+":"+e}function wnn(n,t){return Qln(n),new Rq(n,new __(new M6(t,n.a)))}function dnn(n,t){var e=n.a[t],i=(Zun(),ftt)[typeof e];return i?i(e):khn(typeof e)}function gnn(n){switch(n.g){case 0:return DWn;case 1:return-1;default:return 0}}function pnn(n){return _kn(n,(X7(),gtt))<0?-IN(aon(n)):n.l+n.m*CQn+n.h*OQn}function vnn(n){return null==n.__elementTypeCategory$?10:n.__elementTypeCategory$}function mnn(n){var t;return null!=(t=0==n.b.c.length?null:xq(n.b,0))&&hrn(n,0),t}function ynn(n,t){for(;t[0]<n.length&&GO(" \t\r\n",YTn(fV(n,t[0])))>=0;)++t[0]}function knn(n,t){this.e=t,this.a=Van(n),this.a<54?this.f=j2(n):this.c=npn(n)}function jnn(n,t,e,i){wWn(),Ap.call(this,26),this.c=n,this.a=t,this.d=e,this.b=i}function Enn(n,t,e){var i,r;for(i=10,r=0;r<e-1;r++)t<i&&(n.a+="0"),i*=10;n.a+=t}function Tnn(n,t){var e;for(e=0;n.e!=n.i.gc();)gq(t,kpn(n),iln(e)),e!=DWn&&++e}function Mnn(n,t){var e;for(++n.d,++n.c[t],e=t+1;e<n.a.length;)++n.a[e],e+=e&-e}function Snn(n,t){var e,i,r;r=t.c.i,i=(e=BB(RX(n.f,r),57)).d.c-e.e.c,Yrn(t.a,i,0)}function Pnn(n){var t,e;return t=n+128,!(e=(jq(),jtt)[t])&&(e=jtt[t]=new $b(n)),e}function Inn(n,t){var e;return kW(t),xnn(!!(e=n[":"+t]),Pun(Gk(Ant,1),HWn,1,5,[t])),e}function Cnn(n){var t,e;if(n.b){e=null;do{t=n.b,n.b=null,e=sPn(t,e)}while(n.b);n.b=e}}function Onn(n){var t,e;if(n.a){e=null;do{t=n.a,n.a=null,e=sPn(t,e)}while(n.a);n.a=e}}function Ann(n){var t;for(++n.a,t=n.c.a.length;n.a<t;++n.a)if(n.c.b[n.a])return}function $nn(n,t){var e,i;for(e=(i=t.c)+1;e<=t.f;e++)n.a[e]>n.a[i]&&(i=e);return i}function Lnn(n,t){var e;return 0==(e=Cbn(n.e.c,t.e.c))?Pln(n.e.d,t.e.d):e}function Nnn(n,t){return 0==t.e||0==n.e?eet:($On(),ANn(n,t))}function xnn(n,t){if(!n)throw Hp(new Ky(YNn("Enum constant undefined: %s",t)))}function Dnn(){Dnn=O,uut=new St,out=new Tt,cut=new At,aut=new $t,sut=new Lt}function Rnn(){Rnn=O,vit=new BS("BY_SIZE",0),mit=new BS("BY_SIZE_AND_SHAPE",1)}function _nn(){_nn=O,Dct=new XS("EADES",0),Rct=new XS("FRUCHTERMAN_REINGOLD",1)}function Knn(){Knn=O,Sht=new PP("READING_DIRECTION",0),Pht=new PP("ROTATION",1)}function Fnn(){Fnn=O,Mht=lhn((Vvn(),Pun(Gk(Iht,1),$Vn,335,0,[yht,mht,jht,Eht,kht])))}function Bnn(){Bnn=O,jvt=lhn((Nvn(),Pun(Gk(Avt,1),$Vn,315,0,[yvt,pvt,vvt,gvt,mvt])))}function Hnn(){Hnn=O,Ost=lhn((LEn(),Pun(Gk(_st,1),$Vn,363,0,[Mst,Pst,Ist,Sst,Tst])))}function qnn(){qnn=O,zlt=lhn((Tbn(),Pun(Gk(ivt,1),$Vn,163,0,[qlt,Klt,Flt,Blt,Hlt])))}function Gnn(){Gnn=O,sTt=lhn(($Sn(),Pun(Gk(zTt,1),$Vn,316,0,[iTt,rTt,uTt,cTt,aTt])))}function znn(){znn=O,bMt=lhn((rpn(),Pun(Gk(jMt,1),$Vn,175,0,[hMt,sMt,uMt,fMt,oMt])))}function Unn(){Unn=O,BEt=lhn((YLn(),Pun(Gk(zEt,1),$Vn,355,0,[DEt,xEt,_Et,REt,KEt])))}function Xnn(){Xnn=O,qat=lhn((yMn(),Pun(Gk(Uat,1),$Vn,356,0,[Rat,_at,Kat,Fat,Bat])))}function Wnn(){Wnn=O,GPt=lhn((Ffn(),Pun(Gk(WPt,1),$Vn,103,0,[BPt,FPt,KPt,_Pt,HPt])))}function Vnn(){Vnn=O,zIt=lhn((cpn(),Pun(Gk(JIt,1),$Vn,249,0,[BIt,qIt,KIt,FIt,HIt])))}function Qnn(){Qnn=O,OCt=lhn((kUn(),Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])))}function Ynn(n,t){var e;return(e=BB(RX(n.a,t),134))||(e=new Zn,VW(n.a,t,e)),e}function Jnn(n){var t;return!!(t=BB(mMn(n,(hWn(),Rft)),305))&&t.a==n}function Znn(n){var t;return!!(t=BB(mMn(n,(hWn(),Rft)),305))&&t.i==n}function ntn(n,t){return kW(t),Dz(n),!!n.d.Ob()&&(t.td(n.d.Pb()),!0)}function ttn(n){return Vhn(n,DWn)>0?DWn:Vhn(n,KVn)<0?KVn:dG(n)}function etn(n){return n<3?(lin(n,CVn),n+1):n<OVn?IJ(n/.75+1):DWn}function itn(n,t){var e;return null==n.i&&qFn(n),e=n.i,t>=0&&t<e.length?e[t]:null}function rtn(n,t,e){var i;if(null==t)throw Hp(new gv);return i=zJ(n,t),i4(n,t,e),i}function ctn(n){return n.a>=-.01&&n.a<=fJn&&(n.a=0),n.b>=-.01&&n.b<=fJn&&(n.b=0),n}function atn(n,t){return t==(cK(),cK(),Met)?n.toLocaleLowerCase():n.toLowerCase()}function utn(n){return(0!=(2&n.i)?"interface ":0!=(1&n.i)?"":"class ")+(ED(n),n.o)}function otn(n){var t;t=new $m,f9((!n.q&&(n.q=new eU(QAt,n,11,10)),n.q),t)}function stn(n,t){var e;return e=t>0?t-1:t,$j(Lj(Fen(LH(new Xm,e),n.n),n.j),n.k)}function htn(n,t,e,i){n.j=-1,qOn(n,EPn(n,t,e),(ZM(),BB(t,66).Mj().Ok(i)))}function ftn(n){this.g=n,this.f=new Np,this.a=e.Math.min(this.g.c.c,this.g.d.c)}function ltn(n){this.b=new Np,this.a=new Np,this.c=new Np,this.d=new Np,this.e=n}function btn(n,t){this.a=new xp,this.e=new xp,this.b=(Mhn(),uvt),this.c=n,this.b=t}function wtn(n,t,e){NR.call(this),xtn(this),this.a=n,this.c=e,this.b=t.d,this.f=t.e}function dtn(n){this.d=n,this.c=n.c.vc().Kc(),this.b=null,this.a=null,this.e=(ry(),znt)}function gtn(n){if(n<0)throw Hp(new Ky("Illegal Capacity: "+n));this.g=this.ri(n)}function ptn(n,t){if(0>n||n>t)throw Hp(new Tk("fromIndex: 0, toIndex: "+n+hYn+t))}function vtn(n){var t;if(n.a==n.b.a)throw Hp(new yv);return t=n.a,n.c=t,n.a=n.a.e,t}function mtn(n){var t;Mx(!!n.c),t=n.c.a,Atn(n.d,n.c),n.b==n.c?n.b=t:--n.a,n.c=null}function ytn(n,t){var e;return Qln(n),e=new vQ(n,n.a.rd(),4|n.a.qd(),t),new Rq(n,e)}function ktn(n,t){var e,i;return(e=BB(lfn(n.d,t),14))?(i=t,n.e.pc(i,e)):null}function jtn(n,t){var e;for(e=n.Kc();e.Ob();)hon(BB(e.Pb(),70),(hWn(),ult),t)}function Etn(n){var t;return(t=Gy(MD(mMn(n,(HXn(),agt)))))<0&&hon(n,agt,t=0),t}function Ttn(n,t,i){var r;Fkn(i,r=e.Math.max(0,n.b/2-.5),1),WB(t,new iP(i,r))}function Mtn(n,t,e){return IJ(HH(n.a.e[BB(t.a,10).p]-n.a.e[BB(e.a,10).p]))}function Stn(n,t,e,i,r,c){var a;SZ(a=W5(i),r),MZ(a,c),JCn(n.a,i,new LK(a,t,e.f))}function Ptn(n,t){var e;if(!(e=NNn(n.Tg(),t)))throw Hp(new Ky(r6n+t+u6n));return e}function Itn(n,t){var e;for(e=n;JJ(e);)if((e=JJ(e))==t)return!0;return!1}function Ctn(n,t){var e,i,r;for(i=t.a.cd(),e=BB(t.a.dd(),14).gc(),r=0;r<e;r++)n.td(i)}function Otn(n,t){var e,i,r,c;for(kW(t),r=0,c=(i=n.c).length;r<c;++r)e=i[r],t.td(e)}function Atn(n,t){var e;return e=t.c,t.a.b=t.b,t.b.a=t.a,t.a=t.b=null,t.c=null,--n.b,e}function $tn(n,t){return!(!t||n.b[t.g]!=t||($X(n.b,t.g,null),--n.c,0))}function Ltn(n,t){return!!Zrn(n,t,dG(cbn(SVn,rV(dG(cbn(null==t?0:nsn(t),PVn)),15))))}function Ntn(n,t){L_(BB(mMn(BB(n.e,10),(HXn(),ept)),98))&&(SQ(),m$(BB(n.e,10).j,t))}function xtn(n){n.b=(J9(),Qit),n.f=(G7(),rrt),n.d=(lin(2,AVn),new J6(2)),n.e=new Gj}function Dtn(){Dtn=O,Git=new qS("BEGIN",0),zit=new qS(eJn,1),Uit=new qS("END",2)}function Rtn(){Rtn=O,zPt=new KI(eJn,0),UPt=new KI("HEAD",1),XPt=new KI("TAIL",2)}function _tn(){return hAn(),Pun(Gk(aAt,1),$Vn,237,0,[iAt,nAt,tAt,ZOt,eAt,YOt,QOt,JOt])}function Ktn(){return PPn(),Pun(Gk(SMt,1),$Vn,277,0,[kMt,wMt,vMt,yMt,dMt,gMt,pMt,mMt])}function Ftn(){return kDn(),Pun(Gk(iht,1),$Vn,270,0,[Bst,Gst,Fst,Xst,qst,Hst,Ust,zst])}function Btn(){return sNn(),Pun(Gk(Dvt,1),$Vn,260,0,[Cvt,Tvt,Pvt,Mvt,Svt,Evt,Ivt,Ovt])}function Htn(){Htn=O,ZIt=lhn((QEn(),Pun(Gk(aCt,1),$Vn,98,0,[YIt,QIt,VIt,UIt,WIt,XIt])))}function qtn(){qtn=O,nrt=(Dtn(),Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length,Zit=nrt}function Gtn(n){this.b=(yX(n),new tK(n)),this.a=new Np,this.d=new Np,this.e=new Gj}function ztn(n){var t;return(t=e.Math.sqrt(n.a*n.a+n.b*n.b))>0&&(n.a/=t,n.b/=t),n}function Utn(n){var t;return n.w?n.w:((t=V1(n))&&!t.kh()&&(n.w=t),t)}function Xtn(n){var t;return null==n?null:VTn(t=BB(n,190),t.length)}function Wtn(n,t){if(null==n.g||t>=n.i)throw Hp(new LO(t,n.i));return n.li(t,n.g[t])}function Vtn(n){var t,e;for(t=n.a.d.j,e=n.c.d.j;t!=e;)orn(n.b,t),t=Mln(t);orn(n.b,t)}function Qtn(n){var t;for(t=0;t<n.c.length;t++)(l1(t,n.c.length),BB(n.c[t],11)).p=t}function Ytn(n,t,e){var i,r,c;for(r=t[e],i=0;i<r.length;i++)c=r[i],n.e[c.c.p][c.p]=i}function Jtn(n,t){var e,i,r,c;for(r=0,c=(i=n.d).length;r<c;++r)e=i[r],lL(n.g,e).a=t}function Ztn(n,t){var e;for(e=spn(n,0);e.b!=e.d.c;)UR(BB(b3(e),8),t);return n}function nen(n,t){return XR(B$(BB(RX(n.g,t),8)),K$(BB(RX(n.f,t),460).b))}function ten(n){var t;return p2(n.e,n),Px(n.b),n.c=n.a,t=BB(n.a.Pb(),42),n.b=dun(n),t}function een(n){var t;return JH(null==n||Array.isArray(n)&&!((t=vnn(n))>=14&&t<=16)),n}function ien(n,t,e){var i=function(){return n.apply(i,arguments)};return t.apply(i,e),i}function ren(n,t,e){var i,r;i=t;do{r=Gy(n.p[i.p])+e,n.p[i.p]=r,i=n.a[i.p]}while(i!=t)}function cen(n,t){var e,i;i=n.a,e=Qfn(n,t,null),i!=t&&!n.e&&(e=azn(n,t,e)),e&&e.Fi()}function aen(n,t){return h$(),rin(_Vn),e.Math.abs(n-t)<=_Vn||n==t||isNaN(n)&&isNaN(t)}function uen(n,t){return h$(),rin(_Vn),e.Math.abs(n-t)<=_Vn||n==t||isNaN(n)&&isNaN(t)}function oen(n,t){return KMn(),E$(n.b.c.length-n.e.c.length,t.b.c.length-t.e.c.length)}function sen(n,t){return Zj(Jrn(n,t,dG(cbn(SVn,rV(dG(cbn(null==t?0:nsn(t),PVn)),15)))))}function hen(){hen=O,Aut=lhn((uSn(),Pun(Gk($ut,1),$Vn,267,0,[Iut,Put,Mut,Cut,Sut,Tut])))}function fen(){fen=O,tSt=lhn((wEn(),Pun(Gk(qPt,1),$Vn,291,0,[ZMt,JMt,YMt,VMt,WMt,QMt])))}function len(){len=O,xMt=lhn((wvn(),Pun(Gk(nSt,1),$Vn,248,0,[IMt,AMt,$Mt,LMt,CMt,OMt])))}function ben(){ben=O,rht=lhn(($Pn(),Pun(Gk(uht,1),$Vn,227,0,[Zst,tht,Jst,nht,eht,Yst])))}function wen(){wen=O,oft=lhn((JMn(),Pun(Gk(mft,1),$Vn,275,0,[cft,eft,aft,rft,ift,tft])))}function den(){den=O,nft=lhn((Bjn(),Pun(Gk(uft,1),$Vn,274,0,[Qht,Vht,Jht,Wht,Yht,Xht])))}function gen(){gen=O,rvt=lhn((TTn(),Pun(Gk(ovt,1),$Vn,313,0,[tvt,Zpt,Ypt,Jpt,evt,nvt])))}function pen(){pen=O,Hht=lhn((gSn(),Pun(Gk(zht,1),$Vn,276,0,[Dht,xht,_ht,Rht,Fht,Kht])))}function ven(){ven=O,Jyt=lhn((DPn(),Pun(Gk(Kkt,1),$Vn,327,0,[Qyt,Uyt,Wyt,Xyt,Vyt,zyt])))}function men(){men=O,uCt=lhn((lCn(),Pun(Gk(CCt,1),$Vn,273,0,[rCt,eCt,iCt,tCt,nCt,cCt])))}function yen(){yen=O,sIt=lhn((nMn(),Pun(Gk(yIt,1),$Vn,312,0,[aIt,rIt,uIt,eIt,cIt,iIt])))}function ken(){return n$n(),Pun(Gk(GIt,1),$Vn,93,0,[CIt,IIt,AIt,DIt,xIt,NIt,$It,LIt,OIt])}function jen(n,t){var e;e=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,0,e,n.a))}function Een(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,1,e,n.b))}function Ten(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,3,e,n.b))}function Men(n,t){var e;e=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,3,e,n.f))}function Sen(n,t){var e;e=n.g,n.g=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,4,e,n.g))}function Pen(n,t){var e;e=n.i,n.i=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,5,e,n.i))}function Ien(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,6,e,n.j))}function Cen(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,1,e,n.j))}function Oen(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,4,e,n.c))}function Aen(n,t){var e;e=n.k,n.k=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new f4(n,2,e,n.k))}function $en(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new l4(n,2,e,n.d))}function Len(n,t){var e;e=n.s,n.s=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new l4(n,4,e,n.s))}function Nen(n,t){var e;e=n.t,n.t=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new l4(n,5,e,n.t))}function xen(n,t){var e;e=n.F,n.F=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,5,e,t))}function Den(n,t){var e;return(e=BB(RX((nS(),mAt),n),55))?e.xj(t):x8(Ant,HWn,1,t,5,1)}function Ren(n,t){var e;return t in n.a&&(e=zJ(n,t).he())?e.a:null}function _en(n,t){var e,i;return tE(),i=new uo,!!t&&CNn(i,t),xin(e=i,n),e}function Ken(n,t,e){if(xsn(n,e),!n.Bk()&&null!=e&&!n.wj(e))throw Hp(new lv);return e}function Fen(n,t){return n.n=t,n.n?(n.f=new Np,n.e=new Np):(n.f=null,n.e=null),n}function Ben(n,t,e,i,r,c){var a;return Qen(e,a=mX(n,t)),a.i=r?8:0,a.f=i,a.e=r,a.g=c,a}function Hen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=1,this.c=n,this.a=e}function qen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=2,this.c=n,this.a=e}function Gen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=6,this.c=n,this.a=e}function zen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=7,this.c=n,this.a=e}function Uen(n,t,e,i,r){this.d=t,this.j=i,this.e=r,this.o=-1,this.p=4,this.c=n,this.a=e}function Xen(n,t){var e,i,r,c;for(r=0,c=(i=t).length;r<c;++r)e=i[r],V9(n.a,e);return n}function Wen(n){var t,e,i;for(e=0,i=(t=n).length;e<i;++e)yX(t[e]);return new AO(n)}function Ven(n){var t=/function(?:\s+([\w$]+))?\s*\(/.exec(n);return t&&t[1]||zVn}function Qen(n,t){if(n){t.n=n;var e=UJ(t);e?e.gm=t:SWn[n]=[t]}}function Yen(n,t,i){var r;return r=n.length,KIn(n,0,t,0,e.Math.min(i,r),!0),t}function Jen(n,t,e){var i,r;for(r=t.Kc();r.Ob();)i=BB(r.Pb(),79),TU(n,BB(e.Kb(i),33))}function Zen(){YE();for(var n=PWn,t=0;t<arguments.length;t++)n.push(arguments[t])}function nin(n,t){var e,i,r;for(i=0,r=(e=t).length;i<r;++i)r5(n,e[i],n.c.b,n.c)}function tin(n,t){n.b=e.Math.max(n.b,t.d),n.e+=t.r+(0==n.a.c.length?0:n.c),WB(n.a,t)}function ein(n){Mx(n.c>=0),rgn(n.d,n.c)<0&&(n.a=n.a-1&n.d.a.length-1,n.b=n.d.c),n.c=-1}function iin(n){return n.a<54?n.f<0?-1:n.f>0?1:0:(!n.c&&(n.c=yhn(n.f)),n.c).e}function rin(n){if(!(n>=0))throw Hp(new Ky("tolerance ("+n+") must be >= 0"));return n}function cin(){return cMt||ksn(cMt=new ORn,Pun(Gk(Kit,1),HWn,130,0,[new Nf])),cMt}function ain(){ain=O,Gvt=new zP(hJn,0),Hvt=new zP("INPUT",1),qvt=new zP("OUTPUT",2)}function uin(){uin=O,wht=new MP("ARD",0),ght=new MP("MSD",1),dht=new MP("MANUAL",2)}function oin(){oin=O,Omt=new YP("BARYCENTER",0),Amt=new YP(E1n,1),$mt=new YP(T1n,2)}function sin(n,t){var e;if(e=n.gc(),t<0||t>e)throw Hp(new t_(t,e));return new R_(n,t)}function hin(n,t){var e;return cL(t,42)?n.c.Mc(t):(e=rdn(n,t),Wdn(n,t),e)}function fin(n,t,e){return Chn(n,t),Nrn(n,e),Len(n,0),Nen(n,1),nln(n,!0),Yfn(n,!0),n}function lin(n,t){if(n<0)throw Hp(new Ky(t+" cannot be negative but was: "+n));return n}function bin(n,t){var e,i;for(e=0,i=n.gc();e<i;++e)if(cV(t,n.Xb(e)))return e;return-1}function win(n){var t;for(t=n.c.Cc().Kc();t.Ob();)BB(t.Pb(),14).$b();n.c.$b(),n.d=0}function din(n){var t,e,i,r;for(i=0,r=(e=n.a).length;i<r;++i)QU(t=e[i],t.length,null)}function gin(n){var t,e;if(0==n)return 32;for(e=0,t=1;0==(t&n);t<<=1)++e;return e}function pin(n){var t;for(t=new Wb(eyn(n));t.a<t.c.c.length;)BB(n0(t),680).Gf()}function vin(n){vM(),this.g=new xp,this.f=new xp,this.b=new xp,this.c=new pJ,this.i=n}function min(){this.f=new Gj,this.d=new wm,this.c=new Gj,this.a=new Np,this.b=new Np}function yin(n,t,e,i){this.rj(),this.a=t,this.b=n,this.c=null,this.c=new l_(this,t,e,i)}function kin(n,t,e,i,r){this.d=n,this.n=t,this.g=e,this.o=i,this.p=-1,r||(this.o=-2-i-1)}function jin(){OL.call(this),this.n=-1,this.g=null,this.i=null,this.j=null,this.Bb|=k6n}function Ein(){return nKn(),Pun(Gk(iOt,1),$Vn,259,0,[GCt,UCt,qCt,XCt,WCt,QCt,VCt,zCt,HCt])}function Tin(){return tRn(),Pun(Gk(Bit,1),$Vn,250,0,[Rit,$it,Lit,Ait,xit,Dit,Nit,Oit,Cit])}function Min(){Min=O,Ott=Pun(Gk(ANt,1),hQn,25,15,[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15])}function Sin(){Sin=O,kmt=dq(dq(dq(new B2,(yMn(),Rat),(lWn(),cot)),_at,Oot),Kat,Cot)}function Pin(){Pin=O,jmt=dq(dq(dq(new B2,(yMn(),Rat),(lWn(),cot)),_at,Oot),Kat,Cot)}function Iin(){Iin=O,Mmt=dq(dq(dq(new B2,(yMn(),Rat),(lWn(),cot)),_at,Oot),Kat,Cot)}function Cin(){Cin=O,Imt=WG(dq(dq(new B2,(yMn(),Kat),(lWn(),Lot)),Fat,Eot),Bat,$ot)}function Oin(){Oin=O,hht=new TP("LAYER_SWEEP",0),sht=new TP(B1n,1),fht=new TP(QZn,2)}function Ain(n,t){var e,i;return e=n.c,(i=t.e[n.p])>0?BB(xq(e.a,i-1),10):null}function $in(n,t){var e;e=n.k,n.k=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,2,e,n.k))}function Lin(n,t){var e;e=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,8,e,n.f))}function Nin(n,t){var e;e=n.i,n.i=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,7,e,n.i))}function xin(n,t){var e;e=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,8,e,n.a))}function Din(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,0,e,n.b))}function Rin(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,0,e,n.b))}function _in(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,1,e,n.c))}function Kin(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,1,e,n.c))}function Fin(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,4,e,n.c))}function Bin(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,1,e,n.d))}function Hin(n,t){var e;e=n.D,n.D=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,2,e,n.D))}function qin(n,t){n.r>0&&n.c<n.r&&(n.c+=t,n.i&&n.i.d>0&&0!=n.g&&qin(n.i,t/n.r*n.i.d))}function Gin(n,t,e){var i;n.b=t,n.a=e,i=512==(512&n.a)?new Fm:new Dh,n.c=MDn(i,n.b,n.a)}function zin(n,t){return $xn(n.e,t)?(ZM(),hnn(t)?new lq(t,n):new xC(t,n)):new _C(t,n)}function Uin(n,t){return Jj(Zrn(n.a,t,dG(cbn(SVn,rV(dG(cbn(null==t?0:nsn(t),PVn)),15)))))}function Xin(n,t,e){return x7(n,new fw(t),new un,new lw(e),Pun(Gk(nit,1),$Vn,132,0,[]))}function Win(n){return 0>n?new VT:new $D(null,new m5(n+1,n))}function Vin(n,t){var e;return SQ(),e=new XT(1),XC(n)?mZ(e,n,t):jIn(e.f,n,t),new Xb(e)}function Qin(n,t){var e,i;return(e=n.o+n.p)<(i=t.o+t.p)?-1:e==i?0:1}function Yin(n){var t;return cL(t=mMn(n,(hWn(),dlt)),160)?mwn(BB(t,160)):null}function Jin(n){var t;return(n=e.Math.max(n,2))>(t=kon(n))?(t<<=1)>0?t:OVn:t}function Zin(n){switch(uN(3!=n.e),n.e){case 2:return!1;case 0:return!0}return K5(n)}function nrn(n,t){var e;return!!cL(t,8)&&(e=BB(t,8),n.a==e.a&&n.b==e.b)}function trn(n,t,e){var i,r;return r=t>>5,i=31&t,e0(jz(n.n[e][r],dG(yz(i,1))),3)}function ern(n,t){var e,i;for(i=t.vc().Kc();i.Ob();)vjn(n,(e=BB(i.Pb(),42)).cd(),e.dd())}function irn(n,t){var e;e=new it,BB(t.b,65),BB(t.b,65),BB(t.b,65),Otn(t.a,new TB(n,e,t))}function rrn(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,21,e,n.b))}function crn(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,11,e,n.d))}function arn(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,13,e,n.j))}function urn(n,t,e){var i,r,c;for(c=n.a.length-1,r=n.b,i=0;i<e;r=r+1&c,++i)$X(t,i,n.a[r])}function orn(n,t){var e;return kW(t),e=t.g,!n.b[e]&&($X(n.b,e,t),++n.c,!0)}function srn(n,t){var e;return!((e=null==t?-1:E7(n.b,t,0))<0||(hrn(n,e),0))}function hrn(n,t){var e;e=s6(n.b,n.b.c.length-1),t<n.b.c.length&&(c5(n.b,t,e),_In(n,t))}function frn(n,t){0==(k5(),Qet?null:t.c).length&&zD(t,new X),mZ(n.a,Qet?null:t.c,t)}function lrn(n,t){OTn(t,"Hierarchical port constraint processing",1),bpn(n),YXn(n),HSn(t)}function brn(n,t){var e,i;for(i=t.Kc();i.Ob();)e=BB(i.Pb(),266),n.b=!0,TU(n.e,e),e.b=n}function wrn(n,t){var e,i;return e=1-t,i=n.a[e],n.a[e]=i.a[t],i.a[t]=n,n.b=!0,i.b=!1,i}function drn(n,t){var e,i;return e=BB(mMn(n,(HXn(),spt)),8),i=BB(mMn(t,spt),8),Pln(e.b,i.b)}function grn(n){RG.call(this),this.b=Gy(MD(mMn(n,(HXn(),ypt)))),this.a=BB(mMn(n,Zdt),218)}function prn(n,t,e){G2.call(this,n,t,e),this.a=new xp,this.b=new xp,this.d=new Wd(this)}function vrn(n){this.e=n,this.d=new bE(etn(gz(this.e).gc())),this.c=this.e.a,this.b=this.e.c}function mrn(n){this.b=n,this.a=x8(ANt,hQn,25,n+1,15,1),this.c=x8(ANt,hQn,25,n,15,1),this.d=0}function yrn(n,t,e){var i;return jxn(n,t,i=new Np,e,!0,!0),n.b=new mrn(i.c.length),i}function krn(n,t){var e;return(e=BB(RX(n.c,t),458))||((e=new cm).c=t,VW(n.c,e.c,e)),e}function jrn(n,t){var e=n.a,i=0;for(var r in e)e.hasOwnProperty(r)&&(t[i++]=r);return t}function Ern(n){return null==n.b?(YM(),YM(),x$t):n.Lk()?n.Kk():n.Jk()}function Trn(n){var t,e;for(e=new AL(n);e.e!=e.i.gc();)Pen(t=BB(kpn(e),33),0),Ien(t,0)}function Mrn(){Mrn=O,sat=new up(OZn),hat=new up(AZn),oat=new up($Zn),uat=new up(LZn)}function Srn(){Srn=O,qut=new ZS("TO_INTERNAL_LTR",0),Hut=new ZS("TO_INPUT_DIRECTION",1)}function Prn(){Prn=O,Qkt=new dI("P1_NODE_PLACEMENT",0),Ykt=new dI("P2_EDGE_ROUTING",1)}function Irn(){Irn=O,Rst=new kP("START",0),Dst=new kP("MIDDLE",1),xst=new kP("END",2)}function Crn(){Crn=O,tst=new iR("edgelabelcenterednessanalysis.includelabel",(hN(),ptt))}function Orn(n,t){JT(AV(new Rq(null,new w1(new Ib(n.b),1)),new JI(n,t)),new nC(n,t))}function Arn(){this.c=new CE(0),this.b=new CE(B3n),this.d=new CE(F3n),this.a=new CE(JJn)}function $rn(n){var t,e;for(e=n.c.a.ec().Kc();e.Ob();)Ul(t=BB(e.Pb(),214),new HMn(t.e))}function Lrn(n){var t,e;for(e=n.c.a.ec().Kc();e.Ob();)zl(t=BB(e.Pb(),214),new Vz(t.f))}function Nrn(n,t){var e;e=n.zb,n.zb=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,1,e,n.zb))}function xrn(n,t){var e;e=n.xb,n.xb=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,3,e,n.xb))}function Drn(n,t){var e;e=n.yb,n.yb=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,2,e,n.yb))}function Rrn(n,t){var e;(e=new Om).n=t,f9((!n.s&&(n.s=new eU(FAt,n,21,17)),n.s),e)}function _rn(n,t){var e;(e=new pD).n=t,f9((!n.s&&(n.s=new eU(FAt,n,21,17)),n.s),e)}function Krn(n,t){var e,i;for(z9(e=n.Pc(),0,e.length,t),i=0;i<e.length;i++)n._c(i,e[i])}function Frn(n,t){var e,i,r;for(kW(t),e=!1,r=t.Kc();r.Ob();)i=r.Pb(),e|=n.Fc(i);return e}function Brn(n){var t,e,i;for(t=0,i=n.Kc();i.Ob();)t=~~(t+=null!=(e=i.Pb())?nsn(e):0);return t}function Hrn(n){var t;return 0==n?"UTC":(n<0?(n=-n,t="UTC+"):t="UTC-",t+bnn(n))}function qrn(n,t){var e;return cL(t,14)?(e=BB(t,14),n.Gc(e)):fnn(n,BB(yX(t),20).Kc())}function Grn(n,t,e){btn.call(this,t,e),this.d=x8(Out,a1n,10,n.a.c.length,0,1),Qgn(n.a,this.d)}function zrn(n){n.a=null,n.e=null,n.b.c=x8(Ant,HWn,1,0,5,1),n.f.c=x8(Ant,HWn,1,0,5,1),n.c=null}function Urn(n,t){t?null==n.B&&(n.B=n.D,n.D=null):null!=n.B&&(n.D=n.B,n.B=null)}function Xrn(n,t){return Gy(MD($N($fn($V(new Rq(null,new w1(n.c.b,16)),new xd(n)),t))))}function Wrn(n,t){return Gy(MD($N($fn($V(new Rq(null,new w1(n.c.b,16)),new Nd(n)),t))))}function Vrn(n,t){OTn(t,k1n,1),JT(wnn(new Rq(null,new w1(n.b,16)),new Zt),new ne),HSn(t)}function Qrn(n,t){var e,i;return e=BB(ZAn(n,(Uyn(),Ljt)),19),i=BB(ZAn(t,Ljt),19),E$(e.a,i.a)}function Yrn(n,t,e){var i,r;for(r=spn(n,0);r.b!=r.d.c;)(i=BB(b3(r),8)).a+=t,i.b+=e;return n}function Jrn(n,t,e){var i;for(i=n.b[e&n.f];i;i=i.b)if(e==i.a&&wW(t,i.g))return i;return null}function Zrn(n,t,e){var i;for(i=n.c[e&n.f];i;i=i.d)if(e==i.f&&wW(t,i.i))return i;return null}function ncn(n,t,e){var i,r,c;for(i=0,r=0;r<e;r++)c=t[r],n[r]=c<<1|i,i=c>>>31;0!=i&&(n[e]=i)}function tcn(n,t){var e,i;for(SQ(),i=new Np,e=0;e<n;++e)i.c[i.c.length]=t;return new $k(i)}function ecn(n){var t;return QC((t=T2(n)).a,0)?(hM(),hM(),Pet):(hM(),new yx(t.b))}function icn(n){var t;return QC((t=T2(n)).a,0)?(hM(),hM(),Pet):(hM(),new yx(t.c))}function rcn(n){var t;return QC((t=E2(n)).a,0)?(fM(),fM(),Iet):(fM(),new kx(t.b))}function ccn(n){return n.b.c.i.k==(uSn(),Mut)?BB(mMn(n.b.c.i,(hWn(),dlt)),11):n.b.c}function acn(n){return n.b.d.i.k==(uSn(),Mut)?BB(mMn(n.b.d.i,(hWn(),dlt)),11):n.b.d}function ucn(n,t,e,i,r,c,a,u,o,s,h,f,l){return bIn(n,t,e,i,r,c,a,u,o,s,h,f,l),Gln(n,!1),n}function ocn(n,t,e,i,r,c,a){gT.call(this,n,t),this.d=e,this.e=i,this.c=r,this.b=c,this.a=u6(a)}function scn(n,t){typeof window===AWn&&typeof window.$gwt===AWn&&(window.$gwt[n]=t)}function hcn(n,t){return Aun(),n==Zat&&t==eut||n==eut&&t==Zat||n==tut&&t==nut||n==nut&&t==tut}function fcn(n,t){return Aun(),n==Zat&&t==nut||n==Zat&&t==tut||n==eut&&t==tut||n==eut&&t==nut}function lcn(n,t){return h$(),rin(fJn),e.Math.abs(0-t)<=fJn||0==t||isNaN(0)&&isNaN(t)?0:n/t}function bcn(){return bDn(),Pun(Gk(Tft,1),$Vn,256,0,[hft,lft,bft,wft,dft,gft,vft,sft,fft,pft])}function wcn(){wcn=O,P$t=new Cm,C$t=Pun(Gk(FAt,1),N9n,170,0,[]),I$t=Pun(Gk(QAt,1),x9n,59,0,[])}function dcn(){dcn=O,smt=new VP("NO",0),umt=new VP("GREEDY",1),omt=new VP("LOOK_BACK",2)}function gcn(){gcn=O,Dut=new Ht,Nut=new Bt,xut=new qt,Lut=new Gt,Rut=new zt,_ut=new Ut}function pcn(n){var t,e;for(e=0,t=new Wb(n.b);t.a<t.c.c.length;)BB(n0(t),29).p=e,++e}function vcn(n,t){var e;return $Cn(new xI((e=KTn(n)).c,e.d),new xI(e.b,e.a),n.rf(),t,n.Hf())}function mcn(n,t){var e;return n.b?null:(e=stn(n,n.g),DH(n.a,e),e.i=n,n.d=t,e)}function ycn(n,t,e){OTn(e,"DFS Treeifying phase",1),jdn(n,t),cxn(n,t),n.a=null,n.b=null,HSn(e)}function kcn(n,t,e){this.g=n,this.d=t,this.e=e,this.a=new Np,UIn(this),SQ(),m$(this.a,null)}function jcn(n){this.i=n.gc(),this.i>0&&(this.g=this.ri(this.i+(this.i/8|0)+1),n.Qc(this.g))}function Ecn(n,t){MH.call(this,W$t,n,t),this.b=this,this.a=axn(n.Tg(),itn(this.e.Tg(),this.c))}function Tcn(n,t){var e,i;for(kW(t),i=t.vc().Kc();i.Ob();)e=BB(i.Pb(),42),n.zc(e.cd(),e.dd())}function Mcn(n,t,e){var i;for(i=e.Kc();i.Ob();)if(!G3(n,t,i.Pb()))return!1;return!0}function Scn(n,t,e,i,r){var c;return e&&(c=Awn(t.Tg(),n.c),r=e.gh(t,-1-(-1==c?i:c),null,r)),r}function Pcn(n,t,e,i,r){var c;return e&&(c=Awn(t.Tg(),n.c),r=e.ih(t,-1-(-1==c?i:c),null,r)),r}function Icn(n){var t;if(-2==n.b){if(0==n.e)t=-1;else for(t=0;0==n.a[t];t++);n.b=t}return n.b}function Ccn(n){switch(n.g){case 2:return kUn(),ICt;case 4:return kUn(),oCt;default:return n}}function Ocn(n){switch(n.g){case 1:return kUn(),SCt;case 3:return kUn(),sCt;default:return n}}function Acn(n){var t,e,i;return n.j==(kUn(),sCt)&&(e=SN(t=UOn(n),oCt),(i=SN(t,ICt))||i&&e)}function $cn(n){var t;return new Y_(t=BB(n.e&&n.e(),9),BB(VU(t,t.length),9),t.length)}function Lcn(n,t){OTn(t,k1n,1),twn(sM(new Pw((gM(),new HV(n,!1,!1,new Ft))))),HSn(t)}function Ncn(n,t){return hN(),XC(n)?f6(n,SD(t)):UC(n)?Tz(n,MD(t)):zC(n)?Ez(n,TD(t)):n.wd(t)}function xcn(n,t){t.q=n,n.d=e.Math.max(n.d,t.r),n.b+=t.d+(0==n.a.c.length?0:n.c),WB(n.a,t)}function Dcn(n,t){var e,i,r,c;return r=n.c,e=n.c+n.b,c=n.d,i=n.d+n.a,t.a>r&&t.a<e&&t.b>c&&t.b<i}function Rcn(n,t,e,i){cL(n.Cb,179)&&(BB(n.Cb,179).tb=null),Nrn(n,e),t&&KCn(n,t),i&&n.xk(!0)}function _cn(n,t){var e;qQ(e=BB(t,183),"x",n.i),qQ(e,"y",n.j),qQ(e,I6n,n.g),qQ(e,P6n,n.f)}function Kcn(){Kcn=O,Cmt=ogn(jO(dq(dq(new B2,(yMn(),Kat),(lWn(),Lot)),Fat,Eot),Bat),$ot)}function Fcn(){Fcn=O,Dmt=ogn(jO(dq(dq(new B2,(yMn(),Kat),(lWn(),Lot)),Fat,Eot),Bat),$ot)}function Bcn(){Bcn=O,Xjt=new yI(QZn,0),Wjt=new yI("POLAR_COORDINATE",1),Ujt=new yI("ID",2)}function Hcn(){Hcn=O,Xvt=new UP("EQUALLY",0),Wvt=new UP(mJn,1),Vvt=new UP("NORTH_SOUTH",2)}function qcn(){qcn=O,$vt=lhn((sNn(),Pun(Gk(Dvt,1),$Vn,260,0,[Cvt,Tvt,Pvt,Mvt,Svt,Evt,Ivt,Ovt])))}function Gcn(){Gcn=O,Vst=lhn((kDn(),Pun(Gk(iht,1),$Vn,270,0,[Bst,Gst,Fst,Xst,qst,Hst,Ust,zst])))}function zcn(){zcn=O,EMt=lhn((PPn(),Pun(Gk(SMt,1),$Vn,277,0,[kMt,wMt,vMt,yMt,dMt,gMt,pMt,mMt])))}function Ucn(){Ucn=O,cAt=lhn((hAn(),Pun(Gk(aAt,1),$Vn,237,0,[iAt,nAt,tAt,ZOt,eAt,YOt,QOt,JOt])))}function Xcn(){Xcn=O,Qrt=new iR("debugSVG",(hN(),!1)),Yrt=new iR("overlapsExisted",!0)}function Wcn(n,t){return x7(new ow(n),new sw(t),new hw(t),new tn,Pun(Gk(nit,1),$Vn,132,0,[]))}function Vcn(){var n;return qet||(qet=new _v,YA(n=new y5(""),(lM(),Het)),frn(qet,n)),qet}function Qcn(n,t){for(yX(t);n.Ob();)if(!Qan(BB(n.Pb(),10)))return!1;return!0}function Ycn(n,t){var e;return!!(e=XRn(cin(),n))&&(Ypn(t,(sWn(),mPt),e),!0)}function Jcn(n,t){var e;for(e=0;e<t.j.c.length;e++)BB(D7(n,e),21).Gc(BB(D7(t,e),14));return n}function Zcn(n,t){var e,i;for(i=new Wb(t.b);i.a<i.c.c.length;)e=BB(n0(i),29),n.a[e.p]=QMn(e)}function nan(n,t){var e,i;for(kW(t),i=n.vc().Kc();i.Ob();)e=BB(i.Pb(),42),t.Od(e.cd(),e.dd())}function tan(n,t){cL(t,83)?(BB(n.c,76).Xj(),ern(n,BB(t,83))):BB(n.c,76).Wb(t)}function ean(n){return cL(n,152)?o6(BB(n,152)):cL(n,131)?BB(n,131).a:cL(n,54)?new fy(n):new IT(n)}function ian(n,t){return t<n.b.gc()?BB(n.b.Xb(t),10):t==n.b.gc()?n.a:BB(xq(n.e,t-n.b.gc()-1),10)}function ran(n,t){n.a=rbn(n.a,1),n.c=e.Math.min(n.c,t),n.b=e.Math.max(n.b,t),n.d=rbn(n.d,t)}function can(n,t){OTn(t,"Edge and layer constraint edge reversal",1),Fzn(LRn(n)),HSn(t)}function aan(n){var t;null==n.d?(++n.e,n.f=0,rfn(null)):(++n.e,t=n.d,n.d=null,n.f=0,rfn(t))}function uan(n){var t;return 0==(t=n.h)?n.l+n.m*CQn:t==PQn?n.l+n.m*CQn-OQn:n}function oan(n){return qD(),n.A.Hc((mdn(),DCt))&&!n.B.Hc((nKn(),UCt))?ndn(n):null}function san(n){if(kW(n),0==n.length)throw Hp(new Mk("Zero length BigInteger"));i_n(this,n)}function han(n){if(!n)throw Hp(new Fy("no calls to next() since the last call to remove()"))}function fan(n){return $Qn<n&&n<OQn?n<0?e.Math.ceil(n):e.Math.floor(n):uan(gNn(n))}function lan(n,t){var e,i,r;for(e=n.c.Ee(),r=t.Kc();r.Ob();)i=r.Pb(),n.a.Od(e,i);return n.b.Kb(e)}function ban(n,t){var e,i,r;if(null!=(e=n.Jg())&&n.Mg())for(i=0,r=e.length;i<r;++i)e[i].ui(t)}function wan(n,t){var e,i;for(i=vW(e=n).e;i;){if((e=i)==t)return!0;i=vW(e).e}return!1}function dan(n,t,e){var i,r;return(i=n.a.f[t.p])<(r=n.a.f[e.p])?-1:i==r?0:1}function gan(n,t,e){var i,r;return r=BB(U_(n.d,t),19),i=BB(U_(n.b,e),19),r&&i?U6(n,r.a,i.a):null}function pan(n,t){var e,i;for(i=new AL(n);i.e!=i.i.gc();)SA(e=BB(kpn(i),33),e.i+t.b,e.j+t.d)}function van(n,t){var e,i;for(i=new Wb(t);i.a<i.c.c.length;)e=BB(n0(i),70),WB(n.d,e),_Mn(n,e)}function man(n,t){var e,i;i=new Np,e=t;do{i.c[i.c.length]=e,e=BB(RX(n.k,e),17)}while(e);return i}function yan(n,t){var e;return 0!=(n.Db&t)?-1==(e=Rmn(n,t))?n.Eb:een(n.Eb)[e]:null}function kan(n,t){var e;return(e=new Kf).G=t,!n.rb&&(n.rb=new Jz(n,HAt,n)),f9(n.rb,e),e}function jan(n,t){var e;return(e=new Ev).G=t,!n.rb&&(n.rb=new Jz(n,HAt,n)),f9(n.rb,e),e}function Ean(n,t){switch(t){case 1:return!!n.n&&0!=n.n.i;case 2:return null!=n.k}return m0(n,t)}function Tan(n){switch(n.a.g){case 1:return new EC;case 3:return new hyn;default:return new Cf}}function Man(n){var t;if(n.g>1||n.Ob())return++n.a,n.g=0,t=n.i,n.Ob(),t;throw Hp(new yv)}function San(n){var t;return a$(),uS(syt,n)||((t=new ua).a=n,wR(syt,n,t)),BB(oV(syt,n),635)}function Pan(n){var t,e,i;return e=0,(i=n)<0&&(i+=OQn,e=PQn),t=IJ(i/CQn),M$(IJ(i-t*CQn),t,e)}function Ian(n){var t,e,i;for(i=0,e=new QT(n.a);e.a<e.c.a.length;)t=u4(e),n.b.Hc(t)&&++i;return i}function Can(n){var t,e,i;for(t=1,i=n.Kc();i.Ob();)t=~~(t=31*t+(null==(e=i.Pb())?0:nsn(e)));return t}function Oan(n,t){var e;this.c=n,gmn(n,e=new Np,t,n.b,null,!1,null,!1),this.a=new M2(e,0)}function Aan(n,t){this.b=n,this.e=t,this.d=t.j,this.f=(ZM(),BB(n,66).Oj()),this.k=axn(t.e.Tg(),n)}function $an(n,t,e){this.b=(kW(n),n),this.d=(kW(t),t),this.e=(kW(e),e),this.c=this.d+""+this.e}function Lan(){this.a=BB(mpn((fRn(),qct)),19).a,this.c=Gy(MD(mpn(cat))),this.b=Gy(MD(mpn(tat)))}function Nan(){Nan=O,_It=lhn((n$n(),Pun(Gk(GIt,1),$Vn,93,0,[CIt,IIt,AIt,DIt,xIt,NIt,$It,LIt,OIt])))}function xan(){xan=O,Fit=lhn((tRn(),Pun(Gk(Bit,1),$Vn,250,0,[Rit,$it,Lit,Ait,xit,Dit,Nit,Oit,Cit])))}function Dan(){Dan=O,Rrt=new US("UP",0),Nrt=new US(pJn,1),xrt=new US(cJn,2),Drt=new US(aJn,3)}function Ran(){Ran=O,sZ(),ykt=new $O(X3n,kkt=Rkt),B0(),vkt=new $O(W3n,mkt=Hkt)}function _an(){_an=O,jft=new NP("ONE_SIDED",0),Eft=new NP("TWO_SIDED",1),kft=new NP("OFF",2)}function Kan(n){n.r=new Rv,n.w=new Rv,n.t=new Np,n.i=new Np,n.d=new Rv,n.a=new bA,n.c=new xp}function Fan(n){this.n=new Np,this.e=new YT,this.j=new YT,this.k=new Np,this.f=new Np,this.p=n}function Ban(n,t){n.c&&(J_n(n,t,!0),JT(new Rq(null,new w1(t,16)),new qd(n))),J_n(n,t,!1)}function Han(n,t,e){return n==(oin(),$mt)?new Pc:0!=H$n(t,1)?new Rj(e.length):new Dj(e.length)}function qan(n,t){var e;return t?((e=t.Ve()).dc()||(n.q?Tcn(n.q,e):n.q=new mO(e)),n):n}function Gan(n,t){var e;return void 0===(e=n.a.get(t))?++n.d:(mR(n.a,t),--n.c,oY(n.b)),e}function zan(n,t){var e;return 0==(e=t.p-n.p)?Pln(n.f.a*n.f.b,t.f.a*t.f.b):e}function Uan(n,t){var e,i;return(e=n.f.c.length)<(i=t.f.c.length)?-1:e==i?0:1}function Xan(n){return 0!=n.b.c.length&&BB(xq(n.b,0),70).a?BB(xq(n.b,0),70).a:eQ(n)}function Wan(n){var t;if(n){if((t=n).dc())throw Hp(new yv);return t.Xb(t.gc()-1)}return u1(n.Kc())}function Van(n){var t;return Vhn(n,0)<0&&(n=uH(n)),64-(0!=(t=dG(kz(n,32)))?ZCn(t):ZCn(dG(n))+32)}function Qan(n){var t;return t=BB(mMn(n,(hWn(),Qft)),61),n.k==(uSn(),Mut)&&(t==(kUn(),ICt)||t==oCt)}function Yan(n,t,e){var i,r;(r=BB(mMn(n,(HXn(),vgt)),74))&&(Wsn(i=new km,0,r),Ztn(i,e),Frn(t,i))}function Jan(n,t,e){var i,r,c,a;i=(a=vW(n)).d,r=a.c,c=n.n,t&&(c.a=c.a-i.b-r.a),e&&(c.b=c.b-i.d-r.b)}function Zan(n,t){var e,i;return(e=n.j)!=(i=t.j)?e.g-i.g:n.p==t.p?0:e==(kUn(),sCt)?n.p-t.p:t.p-n.p}function nun(n){var t,e;for(PUn(n),e=new Wb(n.d);e.a<e.c.c.length;)(t=BB(n0(e),101)).i&&XSn(t)}function tun(n,t,e,i,r){$X(n.c[t.g],e.g,i),$X(n.c[e.g],t.g,i),$X(n.b[t.g],e.g,r),$X(n.b[e.g],t.g,r)}function eun(n,t,e,i){BB(e.b,65),BB(e.b,65),BB(i.b,65),BB(i.b,65),BB(i.b,65),Otn(i.a,new EB(n,t,i))}function iun(n,t){n.d==(Ffn(),KPt)||n.d==HPt?BB(t.a,57).c.Fc(BB(t.b,57)):BB(t.b,57).c.Fc(BB(t.a,57))}function run(n,t,e,i){return 1==e?(!n.n&&(n.n=new eU(zOt,n,1,7)),Kpn(n.n,t,i)):eSn(n,t,e,i)}function cun(n,t){var e;return Nrn(e=new Ho,t),f9((!n.A&&(n.A=new NL(O$t,n,7)),n.A),e),e}function aun(n,t,e){var i,r;return r=N2(t,A6n),pjn((i=new aC(n,e)).a,i.b,r),r}function uun(n){var t;return(!n.a||0==(1&n.Bb)&&n.a.kh())&&cL(t=Ckn(n),148)&&(n.a=BB(t,148)),n.a}function oun(n,t){var e,i;for(kW(t),i=t.Kc();i.Ob();)if(e=i.Pb(),!n.Hc(e))return!1;return!0}function sun(n,t){var e,i,r;return e=n.l+t.l,i=n.m+t.m+(e>>22),r=n.h+t.h+(i>>22),M$(e&SQn,i&SQn,r&PQn)}function hun(n,t){var e,i,r;return e=n.l-t.l,i=n.m-t.m+(e>>22),r=n.h-t.h+(i>>22),M$(e&SQn,i&SQn,r&PQn)}function fun(n){var t;return n<128?(!(t=(Mq(),Mtt)[n])&&(t=Mtt[n]=new Lb(n)),t):new Lb(n)}function lun(n){var t;return cL(n,78)?n:((t=n&&n.__java$exception)||ov(t=new jhn(n)),t)}function bun(n){if(cL(n,186))return BB(n,118);if(n)return null;throw Hp(new Hy(e8n))}function wun(n,t){if(null==t)return!1;for(;n.a!=n.b;)if(Nfn(t,Khn(n)))return!0;return!1}function dun(n){return!!n.a.Ob()||n.a==n.d&&(n.a=new S2(n.e.f),n.a.Ob())}function gun(n,t){var e;return 0!=(e=t.Pc()).length&&(tH(n.c,n.c.length,e),!0)}function pun(n,t,e){var i,r;for(r=t.vc().Kc();r.Ob();)i=BB(r.Pb(),42),n.yc(i.cd(),i.dd(),e);return n}function vun(n,t){var e;for(e=new Wb(n.b);e.a<e.c.c.length;)hon(BB(n0(e),70),(hWn(),ult),t)}function mun(n,t,e){var i,r;for(r=new Wb(n.b);r.a<r.c.c.length;)SA(i=BB(n0(r),33),i.i+t,i.j+e)}function yun(n,t){if(!n)throw Hp(new Ky($Rn("value already present: %s",Pun(Gk(Ant,1),HWn,1,5,[t]))))}function kun(n,t){return!(!n||!t||n==t)&&Kdn(n.d.c,t.d.c+t.d.b)&&Kdn(t.d.c,n.d.c+n.d.b)}function jun(){return k5(),Qet?new y5(null):FOn(Vcn(),"com.google.common.base.Strings")}function Eun(n,t){var e;return e=sx(t.a.gc()),JT(ytn(new Rq(null,new w1(t,1)),n.i),new NI(n,e)),e}function Tun(n){var t;return Nrn(t=new Ho,"T"),f9((!n.d&&(n.d=new NL(O$t,n,11)),n.d),t),t}function Mun(n){var t,e,i,r;for(t=1,e=0,r=n.gc();e<r;++e)t=31*t+(null==(i=n.ki(e))?0:nsn(i));return t}function Sun(n,t,e,i){var r;return w2(t,n.e.Hd().gc()),w2(e,n.c.Hd().gc()),r=n.a[t][e],$X(n.a[t],e,i),r}function Pun(n,t,e,i,r){return r.gm=n,r.hm=t,r.im=C,r.__elementTypeId$=e,r.__elementTypeCategory$=i,r}function Iun(n,t,i,r,c){return jDn(),e.Math.min(zGn(n,t,i,r,c),zGn(i,r,n,t,qx(new xI(c.a,c.b))))}function Cun(){Cun=O,ast=new tP(QZn,0),rst=new tP(I1n,1),cst=new tP(C1n,2),ist=new tP("BOTH",3)}function Oun(){Oun=O,vst=new mP(eJn,0),mst=new mP(cJn,1),yst=new mP(aJn,2),kst=new mP("TOP",3)}function Aun(){Aun=O,Zat=new QS("Q1",0),eut=new QS("Q4",1),nut=new QS("Q2",2),tut=new QS("Q3",3)}function $un(){$un=O,bmt=new QP("OFF",0),wmt=new QP("SINGLE_EDGE",1),lmt=new QP("MULTI_EDGE",2)}function Lun(){Lun=O,WTt=new SI("MINIMUM_SPANNING_TREE",0),XTt=new SI("MAXIMUM_SPANNING_TREE",1)}function Nun(){Nun=O,new up("org.eclipse.elk.addLayoutConfig"),ZTt=new ou,JTt=new au,new uu}function xun(n){var t,e;for(t=new YT,e=spn(n.d,0);e.b!=e.d.c;)DH(t,BB(b3(e),188).c);return t}function Dun(n){var t,e;for(e=new Np,t=n.Kc();t.Ob();)gun(e,wDn(BB(t.Pb(),33)));return e}function Run(n){var t;tBn(n,!0),t=VVn,Lx(n,(HXn(),fpt))&&(t+=BB(mMn(n,fpt),19).a),hon(n,fpt,iln(t))}function _un(n,t,e){var i;$U(n.a),Otn(e.i,new jg(n)),kgn(n,i=new I$(BB(RX(n.a,t.b),65)),t),e.f=i}function Kun(n,t){var e,i;return e=n.c,(i=t.e[n.p])<e.a.c.length-1?BB(xq(e.a,i+1),10):null}function Fun(n,t){var e,i;for(WQ(t,"predicate"),i=0;n.Ob();i++)if(e=n.Pb(),t.Lb(e))return i;return-1}function Bun(n,t){var e,i;if(i=0,n<64&&n<=t)for(t=t<64?t:63,e=n;e<=t;e++)i=i0(i,yz(1,e));return i}function Hun(n){var t,e,i;for(SQ(),i=0,e=n.Kc();e.Ob();)i+=null!=(t=e.Pb())?nsn(t):0,i|=0;return i}function qun(n){var t;return tE(),t=new co,n&&f9((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a),t),t}function Gun(n){var t;return(t=new p).a=n,t.b=yon(n),t.c=x8(Qtt,sVn,2,2,6,1),t.c[0]=Hrn(n),t.c[1]=Hrn(n),t}function zun(n,t){if(0===t)return!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),void n.o.c.$b();mPn(n,t)}function Uun(n,t,e){switch(e.g){case 2:n.b=t;break;case 1:n.c=t;break;case 4:n.d=t;break;case 3:n.a=t}}function Xun(n){switch(n.g){case 1:return EIt;case 2:return jIt;case 3:return TIt;default:return MIt}}function Wun(n){switch(BB(mMn(n,(HXn(),kgt)),163).g){case 2:case 4:return!0;default:return!1}}function Vun(){Vun=O,yft=lhn((bDn(),Pun(Gk(Tft,1),$Vn,256,0,[hft,lft,bft,wft,dft,gft,vft,sft,fft,pft])))}function Qun(){Qun=O,JCt=lhn((nKn(),Pun(Gk(iOt,1),$Vn,259,0,[GCt,UCt,qCt,XCt,WCt,QCt,VCt,zCt,HCt])))}function Yun(){Yun=O,Xkt=dq(ogn(ogn(FM(dq(new B2,(zyn(),_yt),(DPn(),Qyt)),Kyt),Xyt),Wyt),Fyt,Vyt)}function Jun(){Jun=O,Aht=new IP(QZn,0),Oht=new IP("INCOMING_ONLY",1),$ht=new IP("OUTGOING_ONLY",2)}function Zun(){Zun=O,ftt={boolean:UT,number:Iy,string:Cy,object:TIn,function:TIn,undefined:Wp}}function non(n,t){vH(n>=0,"Negative initial capacity"),vH(t>=0,"Non-positive load factor"),$U(this)}function ton(n,t,e){return!(n>=128)&&JC(n<64?e0(yz(1,n),e):e0(yz(1,n-64),t),0)}function eon(n,t){return!(!n||!t||n==t)&&Cbn(n.b.c,t.b.c+t.b.b)<0&&Cbn(t.b.c,n.b.c+n.b.b)<0}function ion(n){var t,e,i;return e=n.n,i=n.o,t=n.d,new UV(e.a-t.b,e.b-t.d,i.a+(t.b+t.c),i.b+(t.d+t.a))}function ron(n){var t,e,i,r;for(i=0,r=(e=n.a).length;i<r;++i)Son(n,t=e[i],(kUn(),SCt)),Son(n,t,sCt)}function con(n){var t,e;for(null==n.j&&(n.j=(PY(),Cjn(ett.ce(n)))),t=0,e=n.j.length;t<e;++t);}function aon(n){var t,e;return M$(t=1+~n.l&SQn,e=~n.m+(0==t?1:0)&SQn,~n.h+(0==t&&0==e?1:0)&PQn)}function uon(n,t){return TFn(BB(BB(RX(n.g,t.a),46).a,65),BB(BB(RX(n.g,t.b),46).a,65))}function oon(n,t,e){var i;if(t>(i=n.gc()))throw Hp(new t_(t,i));return n.hi()&&(e=nZ(n,e)),n.Vh(t,e)}function son(n,t,e){return null==e?(!n.q&&(n.q=new xp),v6(n.q,t)):(!n.q&&(n.q=new xp),VW(n.q,t,e)),n}function hon(n,t,e){return null==e?(!n.q&&(n.q=new xp),v6(n.q,t)):(!n.q&&(n.q=new xp),VW(n.q,t,e)),n}function fon(n){var t,e;return qan(e=new y6,n),hon(e,(Mrn(),sat),n),eBn(n,e,t=new xp),Szn(n,e,t),e}function lon(n){var t,e,i;for(jDn(),e=x8(PMt,sVn,8,2,0,1),i=0,t=0;t<2;t++)i+=.5,e[t]=lmn(i,n);return e}function bon(n,t){var e,i,r;for(e=!1,i=n.a[t].length,r=0;r<i-1;r++)e|=Pdn(n,t,r,r+1);return e}function won(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)vmn(n,c,a)||FRn(n,c,a,!0,!1)}function don(n,t){this.b=n,NO.call(this,(BB(Wtn(QQ((QX(),t$t).o),10),18),t.i),t.g),this.a=(wcn(),C$t)}function gon(n,t){this.c=n,this.d=t,this.b=this.d/this.c.c.Hd().gc()|0,this.a=this.d%this.c.c.Hd().gc()}function pon(){this.o=null,this.k=null,this.j=null,this.d=null,this.b=null,this.n=null,this.a=null}function von(n,t,i){this.q=new e.Date,this.q.setFullYear(n+sQn,t,i),this.q.setHours(0,0,0,0),lBn(this,0)}function mon(){mon=O,Nvt=new qP(QZn,0),Lvt=new qP("NODES_AND_EDGES",1),xvt=new qP("PREFER_EDGES",2)}function yon(n){var t;return 0==n?"Etc/GMT":(n<0?(n=-n,t="Etc/GMT-"):t="Etc/GMT+",t+bnn(n))}function kon(n){var t;if(n<0)return KVn;if(0==n)return 0;for(t=OVn;0==(t&n);t>>=1);return t}function jon(n){var t,e;return 32==(e=ZCn(n.h))?32==(t=ZCn(n.m))?ZCn(n.l)+32:t+20-10:e-12}function Eon(n){var t;return null==(t=n.a[n.b])?null:($X(n.a,n.b,null),n.b=n.b+1&n.a.length-1,t)}function Ton(n){var t,e;return t=n.t-n.k[n.o.p]*n.d+n.j[n.o.p]>n.f,e=n.u+n.e[n.o.p]*n.d>n.f*n.s*n.d,t||e}function Mon(n,t,e){var i,r;return i=new H8(t,e),r=new q,n.b=Wxn(n,n.b,i,r),r.b||++n.c,n.b.b=!1,r.d}function Son(n,t,e){var i,r,c;for(c=0,r=Lfn(t,e).Kc();r.Ob();)i=BB(r.Pb(),11),VW(n.c,i,iln(c++))}function Pon(n){var t,e;for(e=new Wb(n.a.b);e.a<e.c.c.length;)(t=BB(n0(e),81)).g.c=-t.g.c-t.g.b;kNn(n)}function Ion(n){var t,e;for(e=new Wb(n.a.b);e.a<e.c.c.length;)(t=BB(n0(e),57)).d.c=-t.d.c-t.d.b;yNn(n)}function Con(n){var t;return(!n.c||0==(1&n.Bb)&&0!=(64&n.c.Db))&&cL(t=Ckn(n),88)&&(n.c=BB(t,26)),n.c}function Oon(n){var t,e,i;t=1+~n.l&SQn,e=~n.m+(0==t?1:0)&SQn,i=~n.h+(0==t&&0==e?1:0)&PQn,n.l=t,n.m=e,n.h=i}function Aon(n){var t,e,i,r,c;for(t=new Gj,r=0,c=(i=n).length;r<c;++r)e=i[r],t.a+=e.a,t.b+=e.b;return t}function $on(n,t){var e,i,r,c,a;for(SQ(),a=!1,r=0,c=(i=t).length;r<c;++r)e=i[r],a|=n.Fc(e);return a}function Lon(n){var t,e;for(jDn(),e=-17976931348623157e292,t=0;t<n.length;t++)n[t]>e&&(e=n[t]);return e}function Non(n,t,e){var i;return jxn(n,t,i=new Np,(kUn(),oCt),!0,!1),jxn(n,e,i,ICt,!1,!1),i}function xon(n,t,e){var i,r;return r=N2(t,"labels"),XAn((i=new gC(n,e)).a,i.b,r),r}function Don(n,t,e,i){var r;return(r=m$n(n,t,e,i))||!(r=aln(n,e,i))||Fqn(n,t,r)?r:null}function Ron(n,t,e,i){var r;return(r=y$n(n,t,e,i))||!(r=uln(n,e,i))||Fqn(n,t,r)?r:null}function _on(n,t){var e;for(e=0;e<n.a.a.length;e++)if(!BB(Dq(n.a,e),169).Lb(t))return!1;return!0}function Kon(n,t,e){if(yX(t),e.Ob())for(sO(t,IX(e.Pb()));e.Ob();)sO(t,n.a),sO(t,IX(e.Pb()));return t}function Fon(n){var t,e,i;for(SQ(),i=1,e=n.Kc();e.Ob();)i=31*i+(null!=(t=e.Pb())?nsn(t):0),i|=0;return i}function Bon(n,t,e,i,r){var c;return c=jAn(n,t),e&&Oon(c),r&&(n=Smn(n,t),ltt=i?aon(n):M$(n.l,n.m,n.h)),c}function Hon(n,t){var e;try{t.Vd()}catch(i){if(!cL(i=lun(i),78))throw Hp(i);e=i,n.c[n.c.length]=e}}function qon(n,t,e){var i,r;return cL(t,144)&&e?(i=BB(t,144),r=e,n.a[i.b][r.b]+n.a[r.b][i.b]):0}function Gon(n,t){switch(t){case 7:return!!n.e&&0!=n.e.i;case 8:return!!n.d&&0!=n.d.i}return fwn(n,t)}function zon(n,t){switch(t.g){case 0:cL(n.b,631)||(n.b=new Lan);break;case 1:cL(n.b,632)||(n.b=new fH)}}function Uon(n,t){for(;null!=n.g||n.c?null==n.g||0!=n.i&&BB(n.g[n.i-1],47).Ob():tZ(n);)vC(t,aLn(n))}function Xon(n,t,e){n.g=APn(n,t,(kUn(),oCt),n.b),n.d=APn(n,e,oCt,n.b),0!=n.g.c&&0!=n.d.c&&zMn(n)}function Won(n,t,e){n.g=APn(n,t,(kUn(),ICt),n.j),n.d=APn(n,e,ICt,n.j),0!=n.g.c&&0!=n.d.c&&zMn(n)}function Von(n,t,e){return!jE(AV(new Rq(null,new w1(n.c,16)),new aw(new ZI(t,e)))).sd((dM(),tit))}function Qon(n){var t;return EW(n),t=new sn,n.a.sd(t)?(IL(),new vy(kW(t.a))):(IL(),IL(),Set)}function Yon(n){var t;return!(n.b<=0)&&((t=GO("MLydhHmsSDkK",YTn(fV(n.c,0))))>1||t>=0&&n.b<3)}function Jon(n){var t,e;for(t=new km,e=spn(n,0);e.b!=e.d.c;)_x(t,0,new wA(BB(b3(e),8)));return t}function Zon(n){var t;for(t=new Wb(n.a.b);t.a<t.c.c.length;)BB(n0(t),81).f.$b();ky(n.b,n),BNn(n)}function nsn(n){return XC(n)?vvn(n):UC(n)?VO(n):zC(n)?(kW(n),n?1231:1237):iz(n)?n.Hb():AG(n)?PN(n):tY(n)}function tsn(n){return XC(n)?Qtt:UC(n)?Ptt:zC(n)?ktt:iz(n)||AG(n)?n.gm:n.gm||Array.isArray(n)&&Gk(ntt,1)||ntt}function esn(n){if(0===n.g)return new cu;throw Hp(new Ky(N4n+(null!=n.f?n.f:""+n.g)))}function isn(n){if(0===n.g)return new iu;throw Hp(new Ky(N4n+(null!=n.f?n.f:""+n.g)))}function rsn(n,t,e){if(0===t)return!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),void tan(n.o,e);yIn(n,t,e)}function csn(n,t,e){this.g=n,this.e=new Gj,this.f=new Gj,this.d=new YT,this.b=new YT,this.a=t,this.c=e}function asn(n,t,e,i){this.b=new Np,this.n=new Np,this.i=i,this.j=e,this.s=n,this.t=t,this.r=0,this.d=0}function usn(n){this.e=n,this.d=new p4(this.e.g),this.a=this.d,this.b=dun(this),this.$modCount=n.$modCount}function osn(n){for(;!n.d||!n.d.Ob();){if(!n.b||Wy(n.b))return null;n.d=BB(dU(n.b),47)}return n.d}function ssn(n){return WB(n.c,(Nun(),ZTt)),uen(n.a,Gy(MD(mpn((Rwn(),Vpt)))))?new qu:new Ig(n)}function hsn(n){switch(n.g){case 1:return F3n;default:case 2:return 0;case 3:return JJn;case 4:return B3n}}function fsn(){var n;return wWn(),PNt||(n=ex(ZUn("M",!0)),n=gG(ZUn("M",!1),n),PNt=n)}function lsn(n,t){var e,i,r;for(r=n.b;r;){if(0==(e=n.a.ue(t,r.d)))return r;i=e<0?0:1,r=r.a[i]}return null}function bsn(n,t,e){var i,r;hN(),i=!!TO(e),(r=BB(t.xc(i),15))||(r=new Np,t.zc(i,r)),r.Fc(e)}function wsn(n,t){var e,i;return(e=BB(ZAn(n,(W$n(),dEt)),19).a)==(i=BB(ZAn(t,dEt),19).a)||e<i?-1:e>i?1:0}function dsn(n,t){return!!bNn(n,t)&&(JCn(n.b,BB(mMn(t,(hWn(),Xft)),21),t),DH(n.a,t),!0)}function gsn(n){var t,e;(t=BB(mMn(n,(hWn(),Elt)),10))&&(y7((e=t.c).a,t),0==e.a.c.length&&y7(vW(t).b,e))}function psn(n){return Qet?x8(Get,dYn,572,0,0,1):BB(Qgn(n.a,x8(Get,dYn,572,n.a.c.length,0,1)),842)}function vsn(n,t,e,i){return nV(),new hy(Pun(Gk(Hnt,1),kVn,42,0,[(zvn(n,t),new vT(n,t)),(zvn(e,i),new vT(e,i))]))}function msn(n,t,e){var i;return fin(i=new $m,t,e),f9((!n.q&&(n.q=new eU(QAt,n,11,10)),n.q),i),i}function ysn(n){var t,e,i,r;for(e=(r=fS(AOt,n)).length,i=x8(Qtt,sVn,2,e,6,1),t=0;t<e;++t)i[t]=r[t];return i}function ksn(n,t){var e,i,r,c,a;for(r=0,c=(i=t).length;r<c;++r)e=i[r],a=new UX(n),e.Qe(a),NBn(a);$U(n.f)}function jsn(n,t){var e;return t===n||!!cL(t,224)&&(e=BB(t,224),Nfn(n.Zb(),e.Zb()))}function Esn(n,t){var e;2*t+1>=n.b.c.length||(Esn(n,2*t+1),(e=2*t+2)<n.b.c.length&&Esn(n,e),_In(n,t))}function Tsn(n,t,e){var i,r;this.g=n,this.c=t,this.a=this,this.d=this,r=Jin(e),i=x8(Qnt,IVn,330,r,0,1),this.b=i}function Msn(n,t,e){var i;for(i=e-1;i>=0&&n[i]===t[i];i--);return i<0?0:sS(e0(n[i],UQn),e0(t[i],UQn))?-1:1}function Ssn(n,t){var e,i;for(i=spn(n,0);i.b!=i.d.c;)(e=BB(b3(i),214)).e.length>0&&(t.td(e),e.i&&pln(e))}function Psn(n,t){var e,i;return i=BB(yan(n.a,4),126),e=x8(dAt,i9n,415,t,0,1),null!=i&&aHn(i,0,e,0,i.length),e}function Isn(n,t){var e;return e=new rRn(0!=(256&n.f),n.i,n.a,n.d,0!=(16&n.f),n.j,n.g,t),null!=n.e||(e.c=n),e}function Csn(n,t){var e;for(e=n.Zb().Cc().Kc();e.Ob();)if(BB(e.Pb(),14).Hc(t))return!0;return!1}function Osn(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)if(vmn(n,c,a))return!0;return!1}function Asn(n,t,e){var i,r,c,a;for(kW(e),a=!1,c=n.Zc(t),r=e.Kc();r.Ob();)i=r.Pb(),c.Rb(i),a=!0;return a}function $sn(n,t){var e;return n===t||!!cL(t,83)&&(e=BB(t,83),zSn(lz(n),e.vc()))}function Lsn(n,t,e){var i,r;for(r=e.Kc();r.Ob();)if(i=BB(r.Pb(),42),n.re(t,i.dd()))return!0;return!1}function Nsn(n,t,e){return n.d[t.p][e.p]||(ivn(n,t,e),n.d[t.p][e.p]=!0,n.d[e.p][t.p]=!0),n.a[t.p][e.p]}function xsn(n,t){if(!n.ai()&&null==t)throw Hp(new Ky("The 'no null' constraint is violated"));return t}function Dsn(n,t){null==n.D&&null!=n.B&&(n.D=n.B,n.B=null),Hin(n,null==t?null:(kW(t),t)),n.C&&n.yk(null)}function Rsn(n,t){return!(!n||n==t||!Lx(t,(hWn(),rlt)))&&BB(mMn(t,(hWn(),rlt)),10)!=n}function _sn(n){switch(n.i){case 2:return!0;case 1:return!1;case-1:++n.c;default:return n.pl()}}function Ksn(n){switch(n.i){case-2:return!0;case-1:return!1;case 1:--n.c;default:return n.ql()}}function Fsn(n){KJ.call(this,"The given string does not match the expected format for individual spacings.",n)}function Bsn(){Bsn=O,uOt=new cC("ELK",0),oOt=new cC("JSON",1),aOt=new cC("DOT",2),sOt=new cC("SVG",3)}function Hsn(){Hsn=O,sjt=new vI(QZn,0),hjt=new vI("RADIAL_COMPACTION",1),fjt=new vI("WEDGE_COMPACTION",2)}function qsn(){qsn=O,zet=new pS("CONCURRENT",0),Uet=new pS("IDENTITY_FINISH",1),Xet=new pS("UNORDERED",2)}function Gsn(){Gsn=O,wM(),oct=new $O(BJn,sct=rct),uct=new up(HJn),hct=new up(qJn),fct=new up(GJn)}function zsn(){zsn=O,lst=new ji,bst=new Ei,fst=new Ti,hst=new Mi,kW(new Si),sst=new D}function Usn(){Usn=O,emt=new WP("CONSERVATIVE",0),imt=new WP("CONSERVATIVE_SOFT",1),rmt=new WP("SLOPPY",2)}function Xsn(){Xsn=O,dIt=new WA(15),wIt=new XA((sWn(),XSt),dIt),gIt=gPt,hIt=aSt,fIt=_St,bIt=BSt,lIt=FSt}function Wsn(n,t,e){var i,r;for(i=new YT,r=spn(e,0);r.b!=r.d.c;)DH(i,new wA(BB(b3(r),8)));Asn(n,t,i)}function Vsn(n){var t,e,i;for(t=0,i=x8(PMt,sVn,8,n.b,0,1),e=spn(n,0);e.b!=e.d.c;)i[t++]=BB(b3(e),8);return i}function Qsn(n){var t;return!n.a&&(n.a=new eU(WAt,n,9,5)),0!=(t=n.a).i?HM(BB(Wtn(t,0),678)):null}function Ysn(n,t){var e;return e=rbn(n,t),sS(r0(n,t),0)|YC(r0(n,e),0)?e:rbn(bVn,r0(jz(e,63),1))}function Jsn(n,t){var e;e=null!=mpn((Rwn(),Vpt))&&null!=t.wg()?Gy(MD(t.wg()))/Gy(MD(mpn(Vpt))):1,VW(n.b,t,e)}function Zsn(n,t){var e,i;return(e=BB(n.d.Bc(t),14))?((i=n.e.hc()).Gc(e),n.e.d-=e.gc(),e.$b(),i):null}function nhn(n,t){var e,i;if(0!=(i=n.c[t]))for(n.c[t]=0,n.d-=i,e=t+1;e<n.a.length;)n.a[e]-=i,e+=e&-e}function thn(n){var t;if((t=n.a.c.length)>0)return _z(t-1,n.a.c.length),s6(n.a,t-1);throw Hp(new mv)}function ehn(n,t,e){if(t<0)throw Hp(new Ay(n5n+t));t<n.j.c.length?c5(n.j,t,e):(g3(n,t),WB(n.j,e))}function ihn(n,t,e){if(n>t)throw Hp(new Ky(mYn+n+yYn+t));if(n<0||t>e)throw Hp(new Tk(mYn+n+kYn+t+hYn+e))}function rhn(n){if(!n.a||0==(8&n.a.i))throw Hp(new Fy("Enumeration class expected for layout option "+n.f))}function chn(n){var t;++n.j,0==n.i?n.g=null:n.i<n.g.length&&(t=n.g,n.g=n.ri(n.i),aHn(t,0,n.g,0,n.i))}function ahn(n,t){var e,i;for(e=n.a.length-1,n.c=n.c-1&e;t!=n.c;)i=t+1&e,$X(n.a,t,n.a[i]),t=i;$X(n.a,n.c,null)}function uhn(n,t){var e,i;for(e=n.a.length-1;t!=n.b;)i=t-1&e,$X(n.a,t,n.a[i]),t=i;$X(n.a,n.b,null),n.b=n.b+1&e}function ohn(n,t,e){var i;return LZ(t,n.c.length),0!=(i=e.Pc()).length&&(tH(n.c,t,i),!0)}function shn(n){var t,e;if(null==n)return null;for(t=0,e=n.length;t<e;t++)if(!PH(n[t]))return n[t];return null}function hhn(n,t,e){var i,r,c,a;for(c=0,a=(r=e).length;c<a;++c)if(i=r[c],n.b.re(t,i.cd()))return i;return null}function fhn(n){var t,e,i,r,c;for(c=1,i=0,r=(e=n).length;i<r;++i)c=31*c+(null!=(t=e[i])?nsn(t):0),c|=0;return c}function lhn(n){var t,e,i,r,c;for(t={},r=0,c=(i=n).length;r<c;++r)t[":"+(null!=(e=i[r]).f?e.f:""+e.g)]=e;return t}function bhn(n){var t;for(yX(n),IK(!0,"numberToAdvance must be nonnegative"),t=0;t<0&&dAn(n);t++)U5(n);return t}function whn(n){var t,e,i;for(i=0,e=new oz(ZL(n.a.Kc(),new h));dAn(e);)(t=BB(U5(e),17)).c.i==t.d.i||++i;return i}function dhn(n,t){var e,i,r;for(e=n,r=0;;){if(e==t)return r;if(!(i=e.e))throw Hp(new wv);e=vW(i),++r}}function ghn(n,t){var e,i,r;for(r=t-n.f,i=new Wb(n.d);i.a<i.c.c.length;)kdn(e=BB(n0(i),443),e.e,e.f+r);n.f=t}function phn(n,t,i){return e.Math.abs(t-n)<K3n||e.Math.abs(i-n)<K3n||(t-n>K3n?n-i>K3n:i-n>K3n)}function vhn(n,t){return n?t&&!n.j||cL(n,124)&&0==BB(n,124).a.b?0:n.Re():0}function mhn(n,t){return n?t&&!n.k||cL(n,124)&&0==BB(n,124).a.a?0:n.Se():0}function yhn(n){return ODn(),n<0?-1!=n?new Rpn(-1,-n):Ytt:n<=10?Ztt[IJ(n)]:new Rpn(1,n)}function khn(n){throw Zun(),Hp(new gy("Unexpected typeof result '"+n+"'; please report this bug to the GWT team"))}function jhn(n){hk(),V$(this),jQ(this),this.e=n,Ixn(this,n),this.g=null==n?zWn:Bbn(n),this.a="",this.b=n,this.a=""}function Ehn(){this.a=new nu,this.f=new dg(this),this.b=new gg(this),this.i=new pg(this),this.e=new vg(this)}function Thn(){cy.call(this,new q8(etn(16))),lin(2,oVn),this.b=2,this.a=new HW(null,null,0,null),iv(this.a,this.a)}function Mhn(){Mhn=O,cvt=new _P("DUMMY_NODE_OVER",0),avt=new _P("DUMMY_NODE_UNDER",1),uvt=new _P("EQUAL",2)}function Shn(){Shn=O,Xat=HJ(Pun(Gk(WPt,1),$Vn,103,0,[(Ffn(),KPt),FPt])),Wat=HJ(Pun(Gk(WPt,1),$Vn,103,0,[HPt,_Pt]))}function Phn(n){return(kUn(),yCt).Hc(n.j)?Gy(MD(mMn(n,(hWn(),Llt)))):Aon(Pun(Gk(PMt,1),sVn,8,0,[n.i.n,n.n,n.a])).b}function Ihn(n){var t,e;for(t=n.b.a.a.ec().Kc();t.Ob();)e=new Q$n(BB(t.Pb(),561),n.e,n.f),WB(n.g,e)}function Chn(n,t){var e,i;e=n.nk(t,null),i=null,t&&(iE(),cen(i=new _p,n.r)),(e=HTn(n,i,e))&&e.Fi()}function Ohn(n,t){var e,i;for(i=0!=H$n(n.d,1),e=!0;e;)e=!1,e=t.c.Tf(t.e,i),e|=DNn(n,t,i,!1),i=!i;$rn(n)}function Ahn(n,t){var e,i,r;return i=!1,e=t.q.d,t.d<n.b&&(r=dNn(t.q,n.b),t.q.d>r&&(aEn(t.q,r),i=e!=t.q.d)),i}function $hn(n,t){var i,r,c,a,u;return a=t.i,u=t.j,r=a-(i=n.f).i,c=u-i.j,e.Math.sqrt(r*r+c*c)}function Lhn(n,t){var e;return(e=Ydn(n))||(!$Ot&&($Ot=new Oo),RHn(),f9((e=new Ip(YPn(t))).Vk(),n)),e}function Nhn(n,t){var e,i;return(e=BB(n.c.Bc(t),14))?((i=n.hc()).Gc(e),n.d-=e.gc(),e.$b(),n.mc(i)):n.jc()}function xhn(n,t){var e;for(e=0;e<t.length;e++)if(n==(b1(e,t.length),t.charCodeAt(e)))return!0;return!1}function Dhn(n,t){var e;for(e=0;e<t.length;e++)if(n==(b1(e,t.length),t.charCodeAt(e)))return!0;return!1}function Rhn(n){var t,e;if(null==n)return!1;for(t=0,e=n.length;t<e;t++)if(!PH(n[t]))return!1;return!0}function _hn(n){var t;if(0!=n.c)return n.c;for(t=0;t<n.a.length;t++)n.c=33*n.c+(-1&n.a[t]);return n.c=n.c*n.e,n.c}function Khn(n){var t;return Px(n.a!=n.b),t=n.d.a[n.a],Ex(n.b==n.d.c&&null!=t),n.c=n.a,n.a=n.a+1&n.d.a.length-1,t}function Fhn(n){var t;if(!(n.c.c<0?n.a>=n.c.b:n.a<=n.c.b))throw Hp(new yv);return t=n.a,n.a+=n.c.c,++n.b,iln(t)}function Bhn(n){var t;return t=new ftn(n),i2(n.a,sut,new Jy(Pun(Gk(Jat,1),HWn,369,0,[t]))),t.d&&WB(t.f,t.d),t.f}function Hhn(n){var t;return qan(t=new O$(n.a),n),hon(t,(hWn(),dlt),n),t.o.a=n.g,t.o.b=n.f,t.n.a=n.i,t.n.b=n.j,t}function qhn(n,t,e,i){var r,c;for(c=n.Kc();c.Ob();)(r=BB(c.Pb(),70)).n.a=t.a+(i.a-r.o.a)/2,r.n.b=t.b,t.b+=r.o.b+e}function Ghn(n,t,e){var i;for(i=t.a.a.ec().Kc();i.Ob();)if(cY(n,BB(i.Pb(),57),e))return!0;return!1}function zhn(n){var t,e;for(e=new Wb(n.r);e.a<e.c.c.length;)if(t=BB(n0(e),10),n.n[t.p]<=0)return t;return null}function Uhn(n){var t,e;for(e=new Rv,t=new Wb(n);t.a<t.c.c.length;)Frn(e,dDn(BB(n0(t),33)));return e}function Xhn(n){var t;return t=kA(Imt),BB(mMn(n,(hWn(),Zft)),21).Hc((bDn(),dft))&&dq(t,(yMn(),Kat),(lWn(),Bot)),t}function Whn(n,t,e){var i;i=new MOn(n,t),JCn(n.r,t.Hf(),i),e&&!Hz(n.u)&&(i.c=new yJ(n.d),Otn(t.wf(),new Iw(i)))}function Vhn(n,t){var e;return JO(n)&&JO(t)&&(e=n-t,!isNaN(e))?e:_kn(JO(n)?Pan(n):n,JO(t)?Pan(t):t)}function Qhn(n,t){return t<n.length&&(b1(t,n.length),63!=n.charCodeAt(t))&&(b1(t,n.length),35!=n.charCodeAt(t))}function Yhn(n,t,e,i){var r,c;n.a=t,c=i?0:1,n.f=(r=new ZSn(n.c,n.a,e,c),new uRn(e,n.a,r,n.e,n.b,n.c==(oin(),Amt)))}function Jhn(n,t,e){var i,r;return r=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new nU(n,1,1,r,t),e?e.Ei(i):e=i),e}function Zhn(n,t,e){var i,r;return r=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new nU(n,1,3,r,t),e?e.Ei(i):e=i),e}function nfn(n,t,e){var i,r;return r=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new nU(n,1,0,r,t),e?e.Ei(i):e=i),e}function tfn(n,t){var e,i,r,c;return(c=kIn((i=t,(r=n?Ydn(n):null)&&r.Xk(),i)))==t&&(e=Ydn(n))&&e.Xk(),c}function efn(n,t){var e,i,r;for(r=1,e=n,i=t>=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function ifn(n,t){var e,i,r;for(r=1,e=n,i=t>=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function rfn(n){var t,e,i,r;if(null!=n)for(e=0;e<n.length;++e)if(t=n[e])for(BB(t.g,367),r=t.i,i=0;i<r;++i);}function cfn(n){var t,i,r;for(r=0,i=new Wb(n.a);i.a<i.c.c.length;)t=BB(n0(i),187),r=e.Math.max(r,t.g);return r}function afn(n){var t,e,i;for(i=new Wb(n.b);i.a<i.c.c.length;)(t=(e=BB(n0(i),214)).c.Rf()?e.f:e.a)&&wqn(t,e.j)}function ufn(){ufn=O,vIt=new HI("INHERIT",0),pIt=new HI("INCLUDE_CHILDREN",1),mIt=new HI("SEPARATE_CHILDREN",2)}function ofn(n,t){switch(t){case 1:return!n.n&&(n.n=new eU(zOt,n,1,7)),void sqn(n.n);case 2:return void $in(n,null)}zun(n,t)}function sfn(n){switch(n.gc()){case 0:return Fnt;case 1:return new Pq(yX(n.Xb(0)));default:return new SY(n)}}function hfn(n){switch(sK(),n.gc()){case 0:return VX(),Vnt;case 1:return new yk(n.Kc().Pb());default:return new vS(n)}}function ffn(n){switch(sK(),n.c){case 0:return VX(),Vnt;case 1:return new yk(JIn(new QT(n)));default:return new sy(n)}}function lfn(n,t){yX(n);try{return n.xc(t)}catch(e){if(cL(e=lun(e),205)||cL(e,173))return null;throw Hp(e)}}function bfn(n,t){yX(n);try{return n.Bc(t)}catch(e){if(cL(e=lun(e),205)||cL(e,173))return null;throw Hp(e)}}function wfn(n,t){yX(n);try{return n.Hc(t)}catch(e){if(cL(e=lun(e),205)||cL(e,173))return!1;throw Hp(e)}}function dfn(n,t){yX(n);try{return n.Mc(t)}catch(e){if(cL(e=lun(e),205)||cL(e,173))return!1;throw Hp(e)}}function gfn(n,t){yX(n);try{return n._b(t)}catch(e){if(cL(e=lun(e),205)||cL(e,173))return!1;throw Hp(e)}}function pfn(n,t){n.a.c.length>0&&dsn(BB(xq(n.a,n.a.c.length-1),570),t)||WB(n.a,new p5(t))}function vfn(n){var t,e;GK(),t=n.d.c-n.e.c,Otn((e=BB(n.g,145)).b,new jd(t)),Otn(e.c,new Ed(t)),e5(e.i,new Td(t))}function mfn(n){var t;return(t=new Ik).a+="VerticalSegment ",uO(t,n.e),t.a+=" ",oO(t,JL(new mk,new Wb(n.k))),t.a}function yfn(n){var t;return(t=BB(lnn(n.c.c,""),229))||(t=new UZ(jj(kj(new pu,""),"Other")),Jgn(n.c.c,"",t)),t}function kfn(n){var t;return 0!=(64&n.Db)?P$n(n):((t=new fN(P$n(n))).a+=" (name: ",cO(t,n.zb),t.a+=")",t.a)}function jfn(n,t,e){var i,r;return r=n.sb,n.sb=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new nU(n,1,4,r,t),e?e.Ei(i):e=i),e}function Efn(n,t){var e,i;for(e=0,i=abn(n,t).Kc();i.Ob();)e+=null!=mMn(BB(i.Pb(),11),(hWn(),Elt))?1:0;return e}function Tfn(n,t,e){var i,r,c;for(i=0,c=spn(n,0);c.b!=c.d.c&&!((r=Gy(MD(b3(c))))>e);)r>=t&&++i;return i}function Mfn(n,t,e){var i;return i=new N7(n.e,3,13,null,t.c||(gWn(),l$t),uvn(n,t),!1),e?e.Ei(i):e=i,e}function Sfn(n,t,e){var i;return i=new N7(n.e,4,13,t.c||(gWn(),l$t),null,uvn(n,t),!1),e?e.Ei(i):e=i,e}function Pfn(n,t,e){var i,r;return r=n.r,n.r=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new nU(n,1,8,r,n.r),e?e.Ei(i):e=i),e}function Ifn(n,t){var e,i;return!(i=(e=BB(t,676)).vk())&&e.wk(i=cL(t,88)?new $C(n,BB(t,26)):new K0(n,BB(t,148))),i}function Cfn(n,t,e){var i;n.qi(n.i+1),i=n.oi(t,e),t!=n.i&&aHn(n.g,t,n.g,t+1,n.i-t),$X(n.g,t,i),++n.i,n.bi(t,e),n.ci()}function Ofn(n,t){var e;return t.a&&(e=t.a.a.length,n.a?oO(n.a,n.b):n.a=new lN(n.d),G0(n.a,t.a,t.d.length,e)),n}function Afn(n,t){var e,i,r;if(t.vi(n.a),null!=(r=BB(yan(n.a,8),1936)))for(e=0,i=r.length;e<i;++e)null.jm()}function $fn(n,t){var e;return e=new sn,n.a.sd(e)?(IL(),new vy(kW(T7(n,e.a,t)))):(EW(n),IL(),IL(),Set)}function Lfn(n,t){switch(t.g){case 2:case 1:return abn(n,t);case 3:case 4:return ean(abn(n,t))}return SQ(),SQ(),set}function Nfn(n,t){return XC(n)?m_(n,t):UC(n)?v_(n,t):zC(n)?(kW(n),GC(n)===GC(t)):iz(n)?n.Fb(t):AG(n)?FO(n,t):v0(n,t)}function xfn(n){return n?0!=(1&n.i)?n==$Nt?ktt:n==ANt?Att:n==DNt?Itt:n==xNt?Ptt:n==LNt?Rtt:n==RNt?Ktt:n==NNt?Ttt:Stt:n:null}function Dfn(n,t,e,i,r){0!=t&&0!=i&&(1==t?r[i]=dvn(r,e,i,n[0]):1==i?r[t]=dvn(r,n,t,e[0]):YOn(n,e,r,t,i))}function Rfn(n,t){var e;0!=n.c.length&&(hA(e=BB(Qgn(n,x8(Out,a1n,10,n.c.length,0,1)),193),new Oe),eOn(e,t))}function _fn(n,t){var e;0!=n.c.length&&(hA(e=BB(Qgn(n,x8(Out,a1n,10,n.c.length,0,1)),193),new Ae),eOn(e,t))}function Kfn(n,t,e,i){switch(t){case 1:return!n.n&&(n.n=new eU(zOt,n,1,7)),n.n;case 2:return n.k}return Eyn(n,t,e,i)}function Ffn(){Ffn=O,BPt=new _I(hJn,0),FPt=new _I(aJn,1),KPt=new _I(cJn,2),_Pt=new _I(pJn,3),HPt=new _I("UP",4)}function Bfn(){Bfn=O,wut=new YS(QZn,0),but=new YS("INSIDE_PORT_SIDE_GROUPS",1),lut=new YS("FORCE_MODEL_ORDER",2)}function Hfn(n,t,e){if(n<0||t>e)throw Hp(new Ay(mYn+n+kYn+t+", size: "+e));if(n>t)throw Hp(new Ky(mYn+n+yYn+t))}function qfn(n,t,e){if(t<0)cCn(n,e);else{if(!e.Ij())throw Hp(new Ky(r6n+e.ne()+c6n));BB(e,66).Nj().Vj(n,n.yh(),t)}}function Gfn(n,t,e,i,r,c,a,u){var o;for(o=e;c<a;)o>=i||t<e&&u.ue(n[t],n[o])<=0?$X(r,c++,n[t++]):$X(r,c++,n[o++])}function zfn(n,t,e,i,r,c){this.e=new Np,this.f=(ain(),Gvt),WB(this.e,n),this.d=t,this.a=e,this.b=i,this.f=r,this.c=c}function Ufn(n,t){var e,i;for(i=new AL(n);i.e!=i.i.gc();)if(e=BB(kpn(i),26),GC(t)===GC(e))return!0;return!1}function Xfn(n){var t,e,i,r;for(dWn(),i=0,r=(e=tpn()).length;i<r;++i)if(-1!=E7((t=e[i]).a,n,0))return t;return Crt}function Wfn(n){return n>=65&&n<=70?n-65+10:n>=97&&n<=102?n-97+10:n>=48&&n<=57?n-48:0}function Vfn(n){var t;return 0!=(64&n.Db)?P$n(n):((t=new fN(P$n(n))).a+=" (source: ",cO(t,n.d),t.a+=")",t.a)}function Qfn(n,t,e){var i,r;return r=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new nU(n,1,5,r,n.a),e?_En(e,i):e=i),e}function Yfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,2,e,t))}function Jfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,8,e,t))}function Zfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,8,e,t))}function nln(n,t){var e;e=0!=(512&n.Bb),t?n.Bb|=512:n.Bb&=-513,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,3,e,t))}function tln(n,t){var e;e=0!=(512&n.Bb),t?n.Bb|=512:n.Bb&=-513,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,9,e,t))}function eln(n,t){var e;return-1==n.b&&n.a&&(e=n.a.Gj(),n.b=e?n.c.Xg(n.a.aj(),e):Awn(n.c.Tg(),n.a)),n.c.Og(n.b,t)}function iln(n){var t,e;return n>-129&&n<128?(t=n+128,!(e=(tq(),Ctt)[t])&&(e=Ctt[t]=new xb(n)),e):new xb(n)}function rln(n){var t,e;return n>-129&&n<128?(t=n+128,!(e=(Tq(),_tt)[t])&&(e=_tt[t]=new Rb(n)),e):new Rb(n)}function cln(n){var t;return n.k==(uSn(),Mut)&&((t=BB(mMn(n,(hWn(),Qft)),61))==(kUn(),sCt)||t==SCt)}function aln(n,t,e){var i,r;return(r=$$n(n.b,t))&&(i=BB(NHn(F7(n,r),""),26))?m$n(n,i,t,e):null}function uln(n,t,e){var i,r;return(r=$$n(n.b,t))&&(i=BB(NHn(F7(n,r),""),26))?y$n(n,i,t,e):null}function oln(n,t){var e,i;for(i=new AL(n);i.e!=i.i.gc();)if(e=BB(kpn(i),138),GC(t)===GC(e))return!0;return!1}function sln(n,t,e){var i;if(t>(i=n.gc()))throw Hp(new t_(t,i));if(n.hi()&&n.Hc(e))throw Hp(new Ky(a8n));n.Xh(t,e)}function hln(n,t){var e;if(null==(e=sen(n.i,t)))throw Hp(new ek("Node did not exist in input."));return _cn(t,e),null}function fln(n,t){var e;if(cL(e=NNn(n,t),322))return BB(e,34);throw Hp(new Ky(r6n+t+"' is not a valid attribute"))}function lln(n,t,e){var i,r;for(r=cL(t,99)&&0!=(BB(t,18).Bb&BQn)?new xO(t,n):new Aan(t,n),i=0;i<e;++i)cvn(r);return r}function bln(n){var t,e,i;for(i=0,e=n.length,t=0;t<e;t++)32==n[t]||13==n[t]||10==n[t]||9==n[t]||(n[i++]=n[t]);return i}function wln(n){var t,e,i;for(t=new Np,i=new Wb(n.b);i.a<i.c.c.length;)e=BB(n0(i),594),gun(t,BB(e.jf(),14));return t}function dln(n){var t,e;for(e=BB(mMn(n,(qqn(),lkt)),15).Kc();e.Ob();)DH((t=BB(e.Pb(),188)).b.d,t),DH(t.c.b,t)}function gln(n){switch(BB(mMn(n,(hWn(),ilt)),303).g){case 1:hon(n,ilt,(z7(),Sft));break;case 2:hon(n,ilt,(z7(),Ift))}}function pln(n){var t;n.g&&(xxn((t=n.c.Rf()?n.f:n.a).a,n.o,!0),xxn(t.a,n.o,!1),hon(n.o,(HXn(),ept),(QEn(),UIt)))}function vln(n){var t;if(!n.a)throw Hp(new Fy("Cannot offset an unassigned cut."));t=n.c-n.b,n.b+=t,xQ(n,t),NQ(n,t)}function mln(n){var t;return null==(t=n.a[n.c-1&n.a.length-1])?null:(n.c=n.c-1&n.a.length-1,$X(n.a,n.c,null),t)}function yln(n){var t,e;for(e=n.p.a.ec().Kc();e.Ob();)if((t=BB(e.Pb(),213)).f&&n.b[t.c]<-1e-10)return t;return null}function kln(n,t){switch(n.b.g){case 0:case 1:return t;case 2:case 3:return new UV(t.d,0,t.a,t.b);default:return null}}function jln(n){switch(n.g){case 2:return FPt;case 1:return KPt;case 4:return _Pt;case 3:return HPt;default:return BPt}}function Eln(n){switch(n.g){case 1:return ICt;case 2:return sCt;case 3:return oCt;case 4:return SCt;default:return PCt}}function Tln(n){switch(n.g){case 1:return SCt;case 2:return ICt;case 3:return sCt;case 4:return oCt;default:return PCt}}function Mln(n){switch(n.g){case 1:return oCt;case 2:return SCt;case 3:return ICt;case 4:return sCt;default:return PCt}}function Sln(n){switch(n){case 0:return new mm;case 1:return new pm;case 2:return new vm;default:throw Hp(new wv)}}function Pln(n,t){return n<t?-1:n>t?1:n==t?0==n?Pln(1/n,1/t):0:isNaN(n)?isNaN(t)?0:1:-1}function Iln(n,t){OTn(t,"Sort end labels",1),JT(AV(wnn(new Rq(null,new w1(n.b,16)),new we),new de),new ge),HSn(t)}function Cln(n,t,e){var i,r;return n.ej()?(r=n.fj(),i=YCn(n,t,e),n.$i(n.Zi(7,iln(e),i,t,r)),i):YCn(n,t,e)}function Oln(n,t){var e,i,r;null==n.d?(++n.e,--n.f):(r=t.cd(),N6(n,i=((e=t.Sh())&DWn)%n.d.length,A$n(n,i,e,r)))}function Aln(n,t){var e;e=0!=(n.Bb&k6n),t?n.Bb|=k6n:n.Bb&=-1025,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,10,e,t))}function $ln(n,t){var e;e=0!=(n.Bb&KQn),t?n.Bb|=KQn:n.Bb&=-4097,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,12,e,t))}function Lln(n,t){var e;e=0!=(n.Bb&T9n),t?n.Bb|=T9n:n.Bb&=-8193,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,15,e,t))}function Nln(n,t){var e;e=0!=(n.Bb&M9n),t?n.Bb|=M9n:n.Bb&=-2049,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,11,e,t))}function xln(n,t){var e;return 0!=(e=Pln(n.b.c,t.b.c))||0!=(e=Pln(n.a.a,t.a.a))?e:Pln(n.a.b,t.a.b)}function Dln(n,t){var e;if(null==(e=RX(n.k,t)))throw Hp(new ek("Port did not exist in input."));return _cn(t,e),null}function Rln(n){var t,e;for(e=G$n(Utn(n)).Kc();e.Ob();)if(NKn(n,t=SD(e.Pb())))return y4((UM(),RAt),t);return null}function _ln(n,t){var e,i,r,c,a;for(a=axn(n.e.Tg(),t),c=0,e=BB(n.g,119),r=0;r<n.i;++r)i=e[r],a.rl(i.ak())&&++c;return c}function Kln(n,t,e){var i,r;return i=BB(t.We(n.a),35),r=BB(e.We(n.a),35),null!=i&&null!=r?Ncn(i,r):null!=i?-1:null!=r?1:0}function Fln(n,t,e){var i;if(n.c)lMn(n.c,t,e);else for(i=new Wb(n.b);i.a<i.c.c.length;)Fln(BB(n0(i),157),t,e)}function Bln(n,t){var e,i;for(i=new Wb(t);i.a<i.c.c.length;)e=BB(n0(i),46),y7(n.b.b,e.b),uY(BB(e.a,189),BB(e.b,81))}function Hln(n){var t,e;for(e=xX(new Ik,91),t=!0;n.Ob();)t||(e.a+=FWn),t=!1,uO(e,n.Pb());return(e.a+="]",e).a}function qln(n,t){var e;e=0!=(n.Bb&hVn),t?n.Bb|=hVn:n.Bb&=-16385,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,16,e,t))}function Gln(n,t){var e;e=0!=(n.Bb&h6n),t?n.Bb|=h6n:n.Bb&=-32769,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,18,e,t))}function zln(n,t){var e;e=0!=(n.Bb&h6n),t?n.Bb|=h6n:n.Bb&=-32769,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,18,e,t))}function Uln(n,t){var e;e=0!=(n.Bb&BQn),t?n.Bb|=BQn:n.Bb&=-65537,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new t6(n,1,20,e,t))}function Xln(n){var t;return t=x8(ONt,WVn,25,2,15,1),n-=BQn,t[0]=(n>>10)+HQn&QVn,t[1]=56320+(1023&n)&QVn,Bdn(t,0,t.length)}function Wln(n){var t;return(t=BB(mMn(n,(HXn(),Udt)),103))==(Ffn(),BPt)?Gy(MD(mMn(n,Edt)))>=1?FPt:_Pt:t}function Vln(n){switch(BB(mMn(n,(HXn(),Zdt)),218).g){case 1:return new ic;case 3:return new oc;default:return new ec}}function Qln(n){if(n.c)Qln(n.c);else if(n.d)throw Hp(new Fy("Stream already terminated, can't be modified or used"))}function Yln(n){var t;return 0!=(64&n.Db)?P$n(n):((t=new fN(P$n(n))).a+=" (identifier: ",cO(t,n.k),t.a+=")",t.a)}function Jln(n,t,e){var i;return tE(),jen(i=new ro,t),Een(i,e),n&&f9((!n.a&&(n.a=new $L(xOt,n,5)),n.a),i),i}function Zln(n,t,e,i){var r,c;return kW(i),kW(e),null==(c=null==(r=n.xc(t))?e:ZT(BB(r,15),BB(e,14)))?n.Bc(t):n.zc(t,c),c}function nbn(n){var t,e,i,r;return orn(e=new Y_(t=BB(Vj((r=(i=n.gm).f)==Unt?i:r),9),BB(SR(t,t.length),9),0),n),e}function tbn(n,t,e){var i,r;for(r=n.a.ec().Kc();r.Ob();)if(i=BB(r.Pb(),10),oun(e,BB(xq(t,i.p),14)))return i;return null}function ebn(n,t,e){try{Kon(n,t,e)}catch(i){throw cL(i=lun(i),597)?Hp(new g5(i)):Hp(i)}return t}function ibn(n,t){var e;return JO(n)&&JO(t)&&$Qn<(e=n-t)&&e<OQn?e:uan(hun(JO(n)?Pan(n):n,JO(t)?Pan(t):t))}function rbn(n,t){var e;return JO(n)&&JO(t)&&$Qn<(e=n+t)&&e<OQn?e:uan(sun(JO(n)?Pan(n):n,JO(t)?Pan(t):t))}function cbn(n,t){var e;return JO(n)&&JO(t)&&$Qn<(e=n*t)&&e<OQn?e:uan(fqn(JO(n)?Pan(n):n,JO(t)?Pan(t):t))}function abn(n,t){var e;return n.i||eCn(n),(e=BB(oV(n.g,t),46))?new s1(n.j,BB(e.a,19).a,BB(e.b,19).a):(SQ(),SQ(),set)}function ubn(n,t,e){var i;return i=n.a.get(t),n.a.set(t,void 0===e?null:e),void 0===i?(++n.c,oY(n.b)):++n.d,i}function obn(n,t,i){n.n=kq(LNt,[sVn,FQn],[364,25],14,[i,IJ(e.Math.ceil(t/32))],2),n.o=t,n.p=i,n.j=t-1>>1,n.k=i-1>>1}function sbn(){var n,t,i;yTn(),i=Let+++Date.now(),n=IJ(e.Math.floor(i*uYn))&sYn,t=IJ(i-n*oYn),this.a=1502^n,this.b=t^aYn}function hbn(n){var t,e;for(t=new Np,e=new Wb(n.j);e.a<e.c.c.length;)WB(t,BB(n0(e),11).b);return yX(t),new OO(t)}function fbn(n){var t,e;for(t=new Np,e=new Wb(n.j);e.a<e.c.c.length;)WB(t,BB(n0(e),11).e);return yX(t),new OO(t)}function lbn(n){var t,e;for(t=new Np,e=new Wb(n.j);e.a<e.c.c.length;)WB(t,BB(n0(e),11).g);return yX(t),new OO(t)}function bbn(n){var t,e;for(e=t$n(Utn(dZ(n))).Kc();e.Ob();)if(NKn(n,t=SD(e.Pb())))return k4((XM(),UAt),t);return null}function wbn(n){var t,e;for(t=0,e=n.length;t<e;t++)if(null==n[t])throw Hp(new Hy("at index "+t));return new Jy(n)}function dbn(n,t){var e;if(cL(e=NNn(n.Tg(),t),99))return BB(e,18);throw Hp(new Ky(r6n+t+"' is not a valid reference"))}function gbn(n){var t;return(t=bSn(n))>34028234663852886e22?RQn:t<-34028234663852886e22?_Qn:t}function pbn(n){return n=((n=((n-=n>>1&1431655765)>>2&858993459)+(858993459&n))>>4)+n&252645135,n+=n>>8,63&(n+=n>>16)}function vbn(n){var t,e,i;for(t=new hR(n.Hd().gc()),i=0,e=L9(n.Hd().Kc());e.Ob();)jZ(t,e.Pb(),iln(i++));return NSn(t.a)}function mbn(n,t){var e,i,r;for(r=new xp,i=t.vc().Kc();i.Ob();)VW(r,(e=BB(i.Pb(),42)).cd(),lan(n,BB(e.dd(),15)));return r}function ybn(n,t){0==n.n.c.length&&WB(n.n,new RJ(n.s,n.t,n.i)),WB(n.b,t),smn(BB(xq(n.n,n.n.c.length-1),211),t),BFn(n,t)}function kbn(n){return n.c==n.b.b&&n.i==n.g.b||(n.a.c=x8(Ant,HWn,1,0,5,1),gun(n.a,n.b),gun(n.a,n.g),n.c=n.b.b,n.i=n.g.b),n.a}function jbn(n,t){var e,i;for(i=0,e=BB(t.Kb(n),20).Kc();e.Ob();)qy(TD(mMn(BB(e.Pb(),17),(hWn(),Ilt))))||++i;return i}function Ebn(n,t){var i,r;r=Gy(MD(edn(f2(t),(HXn(),ypt)))),Fkn(t,i=e.Math.max(0,r/2-.5),1),WB(n,new lP(t,i))}function Tbn(){Tbn=O,qlt=new BP(QZn,0),Klt=new BP("FIRST",1),Flt=new BP(I1n,2),Blt=new BP("LAST",3),Hlt=new BP(C1n,4)}function Mbn(){Mbn=O,ZPt=new FI(hJn,0),YPt=new FI("POLYLINE",1),QPt=new FI("ORTHOGONAL",2),JPt=new FI("SPLINES",3)}function Sbn(){Sbn=O,Zjt=new kI("ASPECT_RATIO_DRIVEN",0),nEt=new kI("MAX_SCALE_DRIVEN",1),Jjt=new kI("AREA_DRIVEN",2)}function Pbn(){Pbn=O,HEt=new EI("P1_STRUCTURE",0),qEt=new EI("P2_PROCESSING_ORDER",1),GEt=new EI("P3_EXECUTION",2)}function Ibn(){Ibn=O,ejt=new gI("OVERLAP_REMOVAL",0),njt=new gI("COMPACTION",1),tjt=new gI("GRAPH_SIZE_CALCULATION",2)}function Cbn(n,t){return h$(),rin(_Vn),e.Math.abs(n-t)<=_Vn||n==t||isNaN(n)&&isNaN(t)?0:n<t?-1:n>t?1:zO(isNaN(n),isNaN(t))}function Obn(n,t){var e,i;for(e=spn(n,0);e.b!=e.d.c;){if((i=zy(MD(b3(e))))==t)return;if(i>t){U0(e);break}}nX(e,t)}function Abn(n,t){var e,i,r,c,a;if(e=t.f,Jgn(n.c.d,e,t),null!=t.g)for(c=0,a=(r=t.g).length;c<a;++c)i=r[c],Jgn(n.c.e,i,t)}function $bn(n,t,e,i){var r,c,a;for(r=t+1;r<e;++r)for(c=r;c>t&&i.ue(n[c-1],n[c])>0;--c)a=n[c],$X(n,c,n[c-1]),$X(n,c-1,a)}function Lbn(n,t,e,i){if(t<0)TLn(n,e,i);else{if(!e.Ij())throw Hp(new Ky(r6n+e.ne()+c6n));BB(e,66).Nj().Tj(n,n.yh(),t,i)}}function Nbn(n,t){if(t==n.d)return n.e;if(t==n.e)return n.d;throw Hp(new Ky("Node "+t+" not part of edge "+n))}function xbn(n,t){switch(t.g){case 2:return n.b;case 1:return n.c;case 4:return n.d;case 3:return n.a;default:return!1}}function Dbn(n,t){switch(t.g){case 2:return n.b;case 1:return n.c;case 4:return n.d;case 3:return n.a;default:return!1}}function Rbn(n,t,e,i){switch(t){case 3:return n.f;case 4:return n.g;case 5:return n.i;case 6:return n.j}return Kfn(n,t,e,i)}function _bn(n){return n.k==(uSn(),Iut)&&o5(new Rq(null,new zU(new oz(ZL(lbn(n).a.Kc(),new h)))),new qr)}function Kbn(n){return null==n.e?n:(!n.c&&(n.c=new rRn(0!=(256&n.f),n.i,n.a,n.d,0!=(16&n.f),n.j,n.g,null)),n.c)}function Fbn(n,t){return n.h==IQn&&0==n.m&&0==n.l?(t&&(ltt=M$(0,0,0)),WO((X7(),dtt))):(t&&(ltt=M$(n.l,n.m,n.h)),M$(0,0,0))}function Bbn(n){return Array.isArray(n)&&n.im===C?nE(tsn(n))+"@"+(nsn(n)>>>0).toString(16):n.toString()}function Hbn(n){var t;this.a=new Y_(t=BB(n.e&&n.e(),9),BB(SR(t,t.length),9),0),this.b=x8(Ant,HWn,1,this.a.a.length,5,1)}function qbn(n){var t,e,i;for(this.a=new fA,i=new Wb(n);i.a<i.c.c.length;)e=BB(n0(i),14),brn(t=new hG,e),TU(this.a,t)}function Gbn(n){var t,e;for(qD(),t=n.o.b,e=BB(BB(h6(n.r,(kUn(),SCt)),21),84).Kc();e.Ob();)BB(e.Pb(),111).e.b+=t}function zbn(n){var t;if(n.b){if(zbn(n.b),n.b.d!=n.c)throw Hp(new vv)}else n.d.dc()&&(t=BB(n.f.c.xc(n.e),14))&&(n.d=t)}function Ubn(n){var t;return null==n||(t=n.length)>0&&(b1(t-1,n.length),58==n.charCodeAt(t-1))&&!Xbn(n,LAt,NAt)}function Xbn(n,t,e){var i,r;for(i=0,r=n.length;i<r;i++)if(ton((b1(i,n.length),n.charCodeAt(i)),t,e))return!0;return!1}function Wbn(n,t){var e,i;for(i=n.e.a.ec().Kc();i.Ob();)if(tSn(t,(e=BB(i.Pb(),266)).d)||CIn(t,e.d))return!0;return!1}function Vbn(n,t){var e,i,r;for(r=(i=HRn(n,t))[i.length-1]/2,e=0;e<i.length;e++)if(i[e]>=r)return t.c+e;return t.c+t.b.gc()}function Qbn(n,t){var e,i,r,c;for(dD(),r=t,z9(i=H9(n),0,i.length,r),e=0;e<i.length;e++)e!=(c=gkn(n,i[e],e))&&Cln(n,e,c)}function Ybn(n,t){var e,i,r,c,a,u;for(i=0,e=0,a=0,u=(c=t).length;a<u;++a)(r=c[a])>0&&(i+=r,++e);return e>1&&(i+=n.d*(e-1)),i}function Jbn(n){var t,e,i;for((i=new Sk).a+="[",t=0,e=n.gc();t<e;)cO(i,kN(n.ki(t))),++t<e&&(i.a+=FWn);return i.a+="]",i.a}function Zbn(n){var t,e,i;return i=ATn(n),!WE(n.c)&&(rtn(i,"knownLayouters",e=new Il),t=new rp(e),e5(n.c,t)),i}function nwn(n,t){var e,i;for(kW(t),e=!1,i=new Wb(n);i.a<i.c.c.length;)ywn(t,n0(i),!1)&&(AU(i),e=!0);return e}function twn(n){var t,e;for(e=Gy(MD(n.a.We((sWn(),OPt)))),t=new Wb(n.a.xf());t.a<t.c.c.length;)VUn(n,BB(n0(t),680),e)}function ewn(n,t){var e,i;for(i=new Wb(t);i.a<i.c.c.length;)e=BB(n0(i),46),WB(n.b.b,BB(e.b,81)),g2(BB(e.a,189),BB(e.b,81))}function iwn(n,t,e){var i,r;for(i=(r=n.a.b).c.length;i<e;i++)kG(r,0,new HX(n.a));PZ(t,BB(xq(r,r.c.length-e),29)),n.b[t.p]=e}function rwn(n,t,e){var i;!(i=e)&&(i=LH(new Xm,0)),OTn(i,qZn,2),mvn(n.b,t,mcn(i,1)),_qn(n,t,mcn(i,1)),qUn(t,mcn(i,1)),HSn(i)}function cwn(n,t,e,i,r){BZ(),UNn(aM(cM(rM(uM(new Hv,0),r.d.e-n),t),r.d)),UNn(aM(cM(rM(uM(new Hv,0),e-r.a.e),r.a),i))}function awn(n,t,e,i,r,c){this.a=n,this.c=t,this.b=e,this.f=i,this.d=r,this.e=c,this.c>0&&this.b>0&&Yq(this.c,this.b,this.a)}function uwn(n){Rwn(),this.c=u6(Pun(Gk(rMt,1),HWn,831,0,[Wpt])),this.b=new xp,this.a=n,VW(this.b,Vpt,1),Otn(Qpt,new Pg(this))}function own(n,t){var e;return n.d?hU(n.b,t)?BB(RX(n.b,t),51):(e=t.Kf(),VW(n.b,t,e),e):t.Kf()}function swn(n,t){var e;return GC(n)===GC(t)||!!cL(t,91)&&(e=BB(t,91),n.e==e.e&&n.d==e.d&&E4(n,e.a))}function hwn(n){switch(kUn(),n.g){case 4:return sCt;case 1:return oCt;case 3:return SCt;case 2:return ICt;default:return PCt}}function fwn(n,t){switch(t){case 3:return 0!=n.f;case 4:return 0!=n.g;case 5:return 0!=n.i;case 6:return 0!=n.j}return Ean(n,t)}function lwn(n){switch(n.g){case 0:return new Ga;case 1:return new za;default:throw Hp(new Ky(c4n+(null!=n.f?n.f:""+n.g)))}}function bwn(n){switch(n.g){case 0:return new qa;case 1:return new Ua;default:throw Hp(new Ky(M1n+(null!=n.f?n.f:""+n.g)))}}function wwn(n){switch(n.g){case 0:return new Vm;case 1:return new ym;default:throw Hp(new Ky(N4n+(null!=n.f?n.f:""+n.g)))}}function dwn(n){switch(n.g){case 1:return new Ra;case 2:return new gD;default:throw Hp(new Ky(c4n+(null!=n.f?n.f:""+n.g)))}}function gwn(n){var t,e;if(n.b)return n.b;for(e=Qet?null:n.d;e;){if(t=Qet?null:e.b)return t;e=Qet?null:e.d}return lM(),Het}function pwn(n){var t,e;return 0==n.e?0:(t=n.d<<5,e=n.a[n.d-1],n.e<0&&Icn(n)==n.d-1&&(--e,e|=0),t-=ZCn(e))}function vwn(n){var t,e,i;return n<tet.length?tet[n]:(t=31&n,(i=x8(ANt,hQn,25,1+(e=n>>5),15,1))[e]=1<<t,new lU(1,e+1,i))}function mwn(n){var t,e,i;return(e=n.zg())?cL(t=n.Ug(),160)&&null!=(i=mwn(BB(t,160)))?i+"."+e:e:null}function ywn(n,t,e){var i,r;for(r=n.Kc();r.Ob();)if(i=r.Pb(),GC(t)===GC(i)||null!=t&&Nfn(t,i))return e&&r.Qb(),!0;return!1}function kwn(n,t,e){var i,r;if(++n.j,e.dc())return!1;for(r=e.Kc();r.Ob();)i=r.Pb(),n.Hi(t,n.oi(t,i)),++t;return!0}function jwn(n,t,e,i){var r,c;if((c=e-t)<3)for(;c<3;)n*=10,++c;else{for(r=1;c>3;)r*=10,--c;n=(n+(r>>1))/r|0}return i.i=n,!0}function Ewn(n){return Shn(),hN(),!!(Dbn(BB(n.a,81).j,BB(n.b,103))||0!=BB(n.a,81).d.e&&Dbn(BB(n.a,81).j,BB(n.b,103)))}function Twn(n){x9(),BB(n.We((sWn(),qSt)),174).Hc((nKn(),VCt))&&(BB(n.We(fPt),174).Fc((lCn(),cCt)),BB(n.We(qSt),174).Mc(VCt))}function Mwn(n,t){var e;if(t){for(e=0;e<n.i;++e)if(BB(n.g[e],366).Di(t))return!1;return f9(n,t)}return!1}function Swn(n){var t,e,i;for(t=new Il,i=new qb(n.b.Kc());i.b.Ob();)e=VSn(BB(i.b.Pb(),686)),WU(t,t.a.length,e);return t.a}function Pwn(n){var t;return!n.c&&(n.c=new Nn),m$(n.d,new Dn),Y_n(n),t=lDn(n),JT(new Rq(null,new w1(n.d,16)),new Cw(n)),t}function Iwn(n){var t;return 0!=(64&n.Db)?kfn(n):((t=new fN(kfn(n))).a+=" (instanceClassName: ",cO(t,n.D),t.a+=")",t.a)}function Cwn(n,t){var e,i;t&&(e=Ren(t,"x"),Ten(new Zg(n).a,(kW(e),e)),i=Ren(t,"y"),Oen(new np(n).a,(kW(i),i)))}function Own(n,t){var e,i;t&&(e=Ren(t,"x"),Cen(new Vg(n).a,(kW(e),e)),i=Ren(t,"y"),Aen(new Yg(n).a,(kW(i),i)))}function Awn(n,t){var e,i,r;if(null==n.i&&qFn(n),e=n.i,-1!=(i=t.aj()))for(r=e.length;i<r;++i)if(e[i]==t)return i;return-1}function $wn(n){var t,e,i,r;for(e=BB(n.g,674),i=n.i-1;i>=0;--i)for(t=e[i],r=0;r<i;++r)if(vFn(n,t,e[r])){Lyn(n,i);break}}function Lwn(n){var t=n.e;function e(n){return n&&0!=n.length?"\t"+n.join("\n\t"):""}return t&&(t.stack||e(n[UVn]))}function Nwn(n){var t;switch(WX(),(t=n.Pc()).length){case 0:return Fnt;case 1:return new Pq(yX(t[0]));default:return new SY(wbn(t))}}function xwn(n,t){switch(t.g){case 1:return _B(n.j,(gcn(),Nut));case 2:return _B(n.j,(gcn(),Dut));default:return SQ(),SQ(),set}}function Dwn(n,t){switch(t){case 3:return void Men(n,0);case 4:return void Sen(n,0);case 5:return void Pen(n,0);case 6:return void Ien(n,0)}ofn(n,t)}function Rwn(){Rwn=O,AM(),HXn(),Vpt=Opt,Qpt=u6(Pun(Gk(lMt,1),k3n,146,0,[mpt,ypt,jpt,Ept,Spt,Ppt,Ipt,Cpt,$pt,Npt,kpt,Tpt,Apt]))}function _wn(n){var t,e;t=n.d==($Pn(),Jst),e=$En(n),hon(n.a,(HXn(),kdt),t&&!e||!t&&e?(wvn(),$Mt):(wvn(),AMt))}function Kwn(n,t){var e;return(e=BB(P4(n,m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15)).Qc(lH(e.gc()))}function Fwn(){Fwn=O,eOt=new YI("SIMPLE",0),ZCt=new YI("GROUP_DEC",1),tOt=new YI("GROUP_MIXED",2),nOt=new YI("GROUP_INC",3)}function Bwn(){Bwn=O,z$t=new $o,_$t=new Lo,K$t=new No,F$t=new xo,B$t=new Do,H$t=new Ro,q$t=new _o,G$t=new Ko,U$t=new Fo}function Hwn(n,t,e){qtn(),sm.call(this),this.a=kq(Xit,[sVn,rJn],[595,212],0,[nrt,Zit],2),this.c=new bA,this.g=n,this.f=t,this.d=e}function qwn(n,t){this.n=kq(LNt,[sVn,FQn],[364,25],14,[t,IJ(e.Math.ceil(n/32))],2),this.o=n,this.p=t,this.j=n-1>>1,this.k=t-1>>1}function Gwn(n,t){OTn(t,"End label post-processing",1),JT(AV(wnn(new Rq(null,new w1(n.b,16)),new ae),new ue),new oe),HSn(t)}function zwn(n,t,e){var i;return i=Gy(n.p[t.i.p])+Gy(n.d[t.i.p])+t.n.b+t.a.b,Gy(n.p[e.i.p])+Gy(n.d[e.i.p])+e.n.b+e.a.b-i}function Uwn(n,t,e){var i,r;for(i=e0(e,UQn),r=0;0!=Vhn(i,0)&&r<t;r++)i=rbn(i,e0(n[r],UQn)),n[r]=dG(i),i=kz(i,32);return dG(i)}function Xwn(n){var t,e,i,r;for(r=0,e=0,i=n.length;e<i;e++)b1(e,n.length),(t=n.charCodeAt(e))<64&&(r=i0(r,yz(1,t)));return r}function Wwn(n){var t;return null==n?null:new $A((t=FBn(n,!0)).length>0&&(b1(0,t.length),43==t.charCodeAt(0))?t.substr(1):t)}function Vwn(n){var t;return null==n?null:new $A((t=FBn(n,!0)).length>0&&(b1(0,t.length),43==t.charCodeAt(0))?t.substr(1):t)}function Qwn(n,t){return n.i>0&&(t.length<n.i&&(t=Den(tsn(t).c,n.i)),aHn(n.g,0,t,0,n.i)),t.length>n.i&&$X(t,n.i,null),t}function Ywn(n,t,e){var i,r,c;return n.ej()?(i=n.i,c=n.fj(),Cfn(n,i,t),r=n.Zi(3,null,t,i,c),e?e.Ei(r):e=r):Cfn(n,n.i,t),e}function Jwn(n,t,e){var i,r;return i=new N7(n.e,4,10,cL(r=t.c,88)?BB(r,26):(gWn(),d$t),null,uvn(n,t),!1),e?e.Ei(i):e=i,e}function Zwn(n,t,e){var i,r;return i=new N7(n.e,3,10,null,cL(r=t.c,88)?BB(r,26):(gWn(),d$t),uvn(n,t),!1),e?e.Ei(i):e=i,e}function ndn(n){var t;return qD(),t=new wA(BB(n.e.We((sWn(),BSt)),8)),n.B.Hc((nKn(),GCt))&&(t.a<=0&&(t.a=20),t.b<=0&&(t.b=20)),t}function tdn(n){return bvn(),(n.q?n.q:(SQ(),SQ(),het))._b((HXn(),Rgt))?BB(mMn(n,Rgt),197):BB(mMn(vW(n),_gt),197)}function edn(n,t){var e,i;return i=null,Lx(n,(HXn(),Mpt))&&(e=BB(mMn(n,Mpt),94)).Xe(t)&&(i=e.We(t)),null==i&&(i=mMn(vW(n),t)),i}function idn(n,t){var e,i,r;return!!cL(t,42)&&(i=(e=BB(t,42)).cd(),wW(r=lfn(n.Rc(),i),e.dd())&&(null!=r||n.Rc()._b(i)))}function rdn(n,t){var e;return n.f>0&&(n.qj(),-1!=A$n(n,((e=null==t?0:nsn(t))&DWn)%n.d.length,e,t))}function cdn(n,t){var e,i;return n.f>0&&(n.qj(),e=aOn(n,((i=null==t?0:nsn(t))&DWn)%n.d.length,i,t))?e.dd():null}function adn(n,t){var e,i,r,c;for(c=axn(n.e.Tg(),t),e=BB(n.g,119),r=0;r<n.i;++r)if(i=e[r],c.rl(i.ak()))return!1;return!0}function udn(n){if(null==n.b){for(;n.a.Ob();)if(n.b=n.a.Pb(),!BB(n.b,49).Zg())return!0;return n.b=null,!1}return!0}function odn(n,t){n.mj();try{n.d.Vc(n.e++,t),n.f=n.d.j,n.g=-1}catch(e){throw cL(e=lun(e),73)?Hp(new vv):Hp(e)}}function sdn(n,t){var e,i;return s$(),i=null,t==(e=fR((fk(),fk(),rtt)))&&(i=BB(SJ(itt,n),615)),i||(i=new zX(n),t==e&&mZ(itt,n,i)),i}function hdn(n,t){var i,r;n.a=rbn(n.a,1),n.c=e.Math.min(n.c,t),n.b=e.Math.max(n.b,t),n.d+=t,i=t-n.f,r=n.e+i,n.f=r-n.e-i,n.e=r}function fdn(n,t){var e;n.c=t,n.a=pwn(t),n.a<54&&(n.f=(e=t.d>1?i0(yz(t.a[1],32),e0(t.a[0],UQn)):e0(t.a[0],UQn),j2(cbn(t.e,e))))}function ldn(n,t){var e;return JO(n)&&JO(t)&&$Qn<(e=n%t)&&e<OQn?e:uan((Aqn(JO(n)?Pan(n):n,JO(t)?Pan(t):t,!0),ltt))}function bdn(n,t){var e;Dzn(t),(e=BB(mMn(n,(HXn(),Jdt)),276))&&hon(n,Jdt,Ayn(e)),nx(n.c),nx(n.f),V6(n.d),V6(BB(mMn(n,Agt),207))}function wdn(n){this.e=x8(ANt,hQn,25,n.length,15,1),this.c=x8($Nt,ZYn,25,n.length,16,1),this.b=x8($Nt,ZYn,25,n.length,16,1),this.f=0}function ddn(n){var t,e;for(n.j=x8(xNt,qQn,25,n.p.c.length,15,1),e=new Wb(n.p);e.a<e.c.c.length;)t=BB(n0(e),10),n.j[t.p]=t.o.b/n.i}function gdn(n){var t;0!=n.c&&(1==(t=BB(xq(n.a,n.b),287)).b?(++n.b,n.b<n.a.c.length&&Tb(BB(xq(n.a,n.b),287))):--t.b,--n.c)}function pdn(n){var t;t=n.a;do{(t=BB(U5(new oz(ZL(lbn(t).a.Kc(),new h))),17).d.i).k==(uSn(),Put)&&WB(n.e,t)}while(t.k==(uSn(),Put))}function vdn(){vdn=O,LCt=new WA(15),$Ct=new XA((sWn(),XSt),LCt),xCt=new XA(LPt,15),NCt=new XA(vPt,iln(0)),ACt=new XA(cSt,dZn)}function mdn(){mdn=O,_Ct=new VI("PORTS",0),KCt=new VI("PORT_LABELS",1),RCt=new VI("NODE_LABELS",2),DCt=new VI("MINIMUM_SIZE",3)}function ydn(n,t){var e,i;for(i=t.length,e=0;e<i;e+=2)Yxn(n,(b1(e,t.length),t.charCodeAt(e)),(b1(e+1,t.length),t.charCodeAt(e+1)))}function kdn(n,t,e){var i,r,c,a;for(c=t-n.e,a=e-n.f,r=new Wb(n.a);r.a<r.c.c.length;)Tvn(i=BB(n0(r),187),i.s+c,i.t+a);n.e=t,n.f=e}function jdn(n,t){var e,i,r;for(r=t.b.b,n.a=new YT,n.b=x8(ANt,hQn,25,r,15,1),e=0,i=spn(t.b,0);i.b!=i.d.c;)BB(b3(i),86).g=e++}function Edn(n,t){var e,i,r,c;return e=t>>5,t&=31,r=n.d+e+(0==t?0:1),xTn(i=x8(ANt,hQn,25,r,15,1),n.a,e,t),X0(c=new lU(n.e,r,i)),c}function Tdn(n,t,e){var i,r;i=BB(SJ(iNt,t),117),r=BB(SJ(rNt,t),117),e?(mZ(iNt,n,i),mZ(rNt,n,r)):(mZ(rNt,n,i),mZ(iNt,n,r))}function Mdn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.ue(t,c.d),e&&0==i)return c;i>=0?c=c.a[1]:(r=c,c=c.a[0])}return r}function Sdn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.ue(t,c.d),e&&0==i)return c;i<=0?c=c.a[0]:(r=c,c=c.a[1])}return r}function Pdn(n,t,e,i){var r,c,a;return r=!1,LGn(n.f,e,i)&&(xgn(n.f,n.a[t][e],n.a[t][i]),a=(c=n.a[t])[i],c[i]=c[e],c[e]=a,r=!0),r}function Idn(n,t,e,i,r){var c,a,u;for(a=r;t.b!=t.c;)c=BB(dU(t),10),u=BB(abn(c,i).Xb(0),11),n.d[u.p]=a++,e.c[e.c.length]=u;return a}function Cdn(n,t,i){var r,c,a,u,o;return u=n.k,o=t.k,c=MD(edn(n,r=i[u.g][o.g])),a=MD(edn(t,r)),e.Math.max((kW(c),c),(kW(a),a))}function Odn(n,t,e){var i,r,c,a;for(i=e/n.c.length,r=0,a=new Wb(n);a.a<a.c.c.length;)ghn(c=BB(n0(a),200),c.f+i*r),ajn(c,t,i),++r}function Adn(n,t,e){var i,r,c;for(r=BB(RX(n.b,e),177),i=0,c=new Wb(t.j);c.a<c.c.c.length;)r[BB(n0(c),113).d.p]&&++i;return i}function $dn(n){var t,e;return null!=(t=BB(yan(n.a,4),126))?(aHn(t,0,e=x8(dAt,i9n,415,t.length,0,1),0,t.length),e):wAt}function Ldn(){var n;return 0!=ctt&&(n=l5())-att>2e3&&(att=n,utt=e.setTimeout(QE,10)),0==ctt++&&(Onn((sk(),ttt)),!0)}function Ndn(n,t){var e;for(e=new oz(ZL(lbn(n).a.Kc(),new h));dAn(e);)if(BB(U5(e),17).d.i.c==t)return!1;return!0}function xdn(n,t){var e;if(cL(t,245)){e=BB(t,245);try{return 0==n.vd(e)}catch(i){if(!cL(i=lun(i),205))throw Hp(i)}}return!1}function Ddn(){return Error.stackTraceLimit>0?(e.Error.stackTraceLimit=Error.stackTraceLimit=64,!0):"stack"in new Error}function Rdn(n,t){return h$(),h$(),rin(_Vn),(e.Math.abs(n-t)<=_Vn||n==t||isNaN(n)&&isNaN(t)?0:n<t?-1:n>t?1:zO(isNaN(n),isNaN(t)))>0}function _dn(n,t){return h$(),h$(),rin(_Vn),(e.Math.abs(n-t)<=_Vn||n==t||isNaN(n)&&isNaN(t)?0:n<t?-1:n>t?1:zO(isNaN(n),isNaN(t)))<0}function Kdn(n,t){return h$(),h$(),rin(_Vn),(e.Math.abs(n-t)<=_Vn||n==t||isNaN(n)&&isNaN(t)?0:n<t?-1:n>t?1:zO(isNaN(n),isNaN(t)))<=0}function Fdn(n,t){for(var e=0;!t[e]||""==t[e];)e++;for(var i=t[e++];e<t.length;e++)t[e]&&""!=t[e]&&(i+=n+t[e]);return i}function Bdn(n,t,i){var r,c,a,u;for(K8(t,a=t+i,n.length),u="",c=t;c<a;)r=e.Math.min(c+1e4,a),u+=WW(n.slice(c,r)),c=r;return u}function Hdn(n){var t,e,i,r;if(null==n)return null;for(r=new Np,e=0,i=(t=ysn(n)).length;e<i;++e)WB(r,FBn(t[e],!0));return r}function qdn(n){var t,e,i,r;if(null==n)return null;for(r=new Np,e=0,i=(t=ysn(n)).length;e<i;++e)WB(r,FBn(t[e],!0));return r}function Gdn(n){var t,e,i,r;if(null==n)return null;for(r=new Np,e=0,i=(t=ysn(n)).length;e<i;++e)WB(r,FBn(t[e],!0));return r}function zdn(n,t){var e,i,r;if(n.c)Sen(n.c,t);else for(e=t-iG(n),r=new Wb(n.d);r.a<r.c.c.length;)zdn(i=BB(n0(r),157),iG(i)+e)}function Udn(n,t){var e,i,r;if(n.c)Men(n.c,t);else for(e=t-eG(n),r=new Wb(n.a);r.a<r.c.c.length;)Udn(i=BB(n0(r),157),eG(i)+e)}function Xdn(n,t){var e,i,r;for(i=new J6(t.gc()),e=t.Kc();e.Ob();)(r=tKn(n,BB(e.Pb(),56)))&&(i.c[i.c.length]=r);return i}function Wdn(n,t){var e,i;return n.qj(),(e=aOn(n,((i=null==t?0:nsn(t))&DWn)%n.d.length,i,t))?(hin(n,e),e.dd()):null}function Vdn(n){var t,e;for(e=uPn(n),t=null;2==n.c;)QXn(n),t||(wWn(),wWn(),tqn(t=new r$(2),e),e=t),e.$l(uPn(n));return e}function Qdn(n){if(!(q6n in n.a))throw Hp(new ek("Every element must have an id."));return kCn(zJ(n,q6n))}function Ydn(n){var t,e,i;if(!(i=n.Zg()))for(t=0,e=n.eh();e;e=e.eh()){if(++t>GQn)return e.fh();if((i=e.Zg())||e==n)break}return i}function Jdn(n){return hZ(),cL(n,156)?BB(RX(hAt,yet),288).vg(n):hU(hAt,tsn(n))?BB(RX(hAt,tsn(n)),288).vg(n):null}function Zdn(n){if(mgn(a5n,n))return hN(),vtt;if(mgn(u5n,n))return hN(),ptt;throw Hp(new Ky("Expecting true or false"))}function ngn(n,t){if(t.c==n)return t.d;if(t.d==n)return t.c;throw Hp(new Ky("Input edge is not connected to the input port."))}function tgn(n,t){return n.e>t.e?1:n.e<t.e?-1:n.d>t.d?n.e:n.d<t.d?-t.e:n.e*Msn(n.a,t.a,n.d)}function egn(n){return n>=48&&n<48+e.Math.min(10,10)?n-48:n>=97&&n<97?n-97+10:n>=65&&n<65?n-65+10:-1}function ign(n,t){var e;return GC(t)===GC(n)||!!cL(t,21)&&(e=BB(t,21)).gc()==n.gc()&&n.Ic(e)}function rgn(n,t){var e,i,r;return i=n.a.length-1,e=t-n.b&i,r=n.c-t&i,Ex(e<(n.c-n.b&i)),e>=r?(ahn(n,t),-1):(uhn(n,t),1)}function cgn(n,t){var e,i;for(b1(t,n.length),e=n.charCodeAt(t),i=t+1;i<n.length&&(b1(i,n.length),n.charCodeAt(i)==e);)++i;return i-t}function agn(n){switch(n.g){case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:return!0;default:return!1}}function ugn(n,t){var e,i=n.a;t=String(t),i.hasOwnProperty(t)&&(e=i[t]);var r=(Zun(),ftt)[typeof e];return r?r(e):khn(typeof e)}function ogn(n,t){if(n.a<0)throw Hp(new Fy("Did not call before(...) or after(...) before calling add(...)."));return WN(n,n.a,t),n}function sgn(n,t,e,i){var r;0!=t.c.length&&(r=MLn(e,i),JT(ytn(new Rq(null,new w1(uCn(t),1)),new ja),new XV(n,e,r,i)))}function hgn(n,t,e){var i;0!=(n.Db&t)?null==e?WOn(n,t):-1==(i=Rmn(n,t))?n.Eb=e:$X(een(n.Eb),i,e):null!=e&&mxn(n,t,e)}function fgn(n){var t;return 0==(32&n.Db)&&0!=(t=bX(BB(yan(n,16),26)||n.zh())-bX(n.zh()))&&hgn(n,32,x8(Ant,HWn,1,t,5,1)),n}function lgn(n){var t;return n.b||Xj(n,!(t=n_(n.e,n.a))||!m_(u5n,cdn((!t.b&&(t.b=new Jx((gWn(),k$t),X$t,t)),t.b),"qualified"))),n.c}function bgn(n,t,e){var i,r;return((r=(i=BB(Wtn(H7(n.a),t),87)).c||(gWn(),l$t)).kh()?tfn(n.b,BB(r,49)):r)==e?lFn(i):cen(i,e),r}function wgn(n,t){(t||null==console.groupCollapsed?null!=console.group?console.group:console.log:console.groupCollapsed).call(console,n)}function dgn(n,t,e,i){BB(e.b,65),BB(e.b,65),BB(i.b,65),BB(i.b,65).c.b,_8(i,t,n)}function ggn(n){var t,e;for(t=new Wb(n.g);t.a<t.c.c.length;)BB(n0(t),562);zzn(e=new yxn(n.g,Gy(n.a),n.c)),n.g=e.b,n.d=e.a}function pgn(n,t,i){t.b=e.Math.max(t.b,-i.a),t.c=e.Math.max(t.c,i.a-n.a),t.d=e.Math.max(t.d,-i.b),t.a=e.Math.max(t.a,i.b-n.b)}function vgn(n,t){return n.e<t.e?-1:n.e>t.e?1:n.f<t.f?-1:n.f>t.f?1:nsn(n)-nsn(t)}function mgn(n,t){return kW(n),null!=t&&(!!m_(n,t)||n.length==t.length&&m_(n.toLowerCase(),t.toLowerCase()))}function ygn(n,t){var e,i,r,c;for(i=0,r=t.gc();i<r;++i)cL(e=t.il(i),99)&&0!=(BB(e,18).Bb&h6n)&&null!=(c=t.jl(i))&&tKn(n,BB(c,56))}function kgn(n,t,e){var i,r,c;for(c=new Wb(e.a);c.a<c.c.c.length;)r=BB(n0(c),221),i=new I$(BB(RX(n.a,r.b),65)),WB(t.a,i),kgn(n,i,r)}function jgn(n){var t,e;return Vhn(n,-129)>0&&Vhn(n,128)<0?(t=dG(n)+128,!(e=(Eq(),$tt)[t])&&(e=$tt[t]=new Db(n)),e):new Db(n)}function Egn(n,t){var e,i;return(e=t.Hh(n.a))&&null!=(i=SD(cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),t8n)))?i:t.ne()}function Tgn(n,t){var e,i;return(e=t.Hh(n.a))&&null!=(i=SD(cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),t8n)))?i:t.ne()}function Mgn(n,t){var e,i;for(qZ(),i=new oz(ZL(hbn(n).a.Kc(),new h));dAn(i);)if((e=BB(U5(i),17)).d.i==t||e.c.i==t)return e;return null}function Sgn(n,t,e){this.c=n,this.f=new Np,this.e=new Gj,this.j=new Sq,this.n=new Sq,this.b=t,this.g=new UV(t.c,t.d,t.b,t.a),this.a=e}function Pgn(n){var t,e,i,r;for(this.a=new fA,this.d=new Rv,this.e=0,i=0,r=(e=n).length;i<r;++i)t=e[i],!this.f&&(this.f=t),g2(this,t)}function Ign(n){ODn(),0==n.length?(this.e=0,this.d=1,this.a=Pun(Gk(ANt,1),hQn,25,15,[0])):(this.e=1,this.d=n.length,this.a=n,X0(this))}function Cgn(n,t,e){sm.call(this),this.a=x8(Xit,rJn,212,(Dtn(),Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length,0,1),this.b=n,this.d=t,this.c=e}function Ogn(n){this.d=new Np,this.e=new v4,this.c=x8(ANt,hQn,25,(kUn(),Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])).length,15,1),this.b=n}function Agn(n){var t,e,i,r;for(hon(r=BB(mMn(n,(hWn(),dlt)),11),Llt,n.i.n.b),e=0,i=(t=Z0(n.e)).length;e<i;++e)MZ(t[e],r)}function $gn(n){var t,e,i,r;for(hon(t=BB(mMn(n,(hWn(),dlt)),11),Llt,n.i.n.b),i=0,r=(e=Z0(n.g)).length;i<r;++i)SZ(e[i],t)}function Lgn(n){var t,e;return!!Lx(n.d.i,(HXn(),Wgt))&&(t=BB(mMn(n.c.i,Wgt),19),e=BB(mMn(n.d.i,Wgt),19),E$(t.a,e.a)>0)}function Ngn(n){var t;GC(ZAn(n,(sWn(),ESt)))===GC((ufn(),vIt))&&(JJ(n)?(t=BB(ZAn(JJ(n),ESt),334),Ypn(n,ESt,t)):Ypn(n,ESt,mIt))}function xgn(n,t,e){var i,r;fMn(n.e,t,e,(kUn(),ICt)),fMn(n.i,t,e,oCt),n.a&&(r=BB(mMn(t,(hWn(),dlt)),11),i=BB(mMn(e,dlt),11),k0(n.g,r,i))}function Dgn(n,t,e){var i,r,c;i=t.c.p,c=t.p,n.b[i][c]=new DY(n,t),e&&(n.a[i][c]=new Bd(t),(r=BB(mMn(t,(hWn(),rlt)),10))&&JCn(n.d,r,t))}function Rgn(n,t){var e,i,r;if(WB(Sct,n),t.Fc(n),e=BB(RX(Mct,n),21))for(r=e.Kc();r.Ob();)i=BB(r.Pb(),33),-1!=E7(Sct,i,0)||Rgn(i,t)}function _gn(n,t,e){var i;(Wet?(gwn(n),1):Vet||Jet?(lM(),1):Yet&&(lM(),0))&&((i=new iK(t)).b=e,aSn(n,i))}function Kgn(n,t){var e;e=!n.A.Hc((mdn(),KCt))||n.q==(QEn(),XIt),n.u.Hc((lCn(),eCt))?e?NUn(n,t):aUn(n,t):n.u.Hc(rCt)&&(e?Azn(n,t):JUn(n,t))}function Fgn(n,t){var e,i;++n.j,null!=t&&oOn(t,e=cL(i=n.a.Cb,97)?BB(i,97).Jg():null)?hgn(n.a,4,e):hgn(n.a,4,BB(t,126))}function Bgn(n,t,i){return new UV(e.Math.min(n.a,t.a)-i/2,e.Math.min(n.b,t.b)-i/2,e.Math.abs(n.a-t.a)+i,e.Math.abs(n.b-t.b)+i)}function Hgn(n,t){var e,i;return 0!=(e=E$(n.a.c.p,t.a.c.p))?e:0!=(i=E$(n.a.d.i.p,t.a.d.i.p))?i:E$(t.a.d.p,n.a.d.p)}function qgn(n,t,e){var i,r,c,a;return(c=t.j)!=(a=e.j)?c.g-a.g:(i=n.f[t.p],r=n.f[e.p],0==i&&0==r?0:0==i?-1:0==r?1:Pln(i,r))}function Ggn(n,t,e){var i;if(!e[t.d])for(e[t.d]=!0,i=new Wb(kbn(t));i.a<i.c.c.length;)Ggn(n,Nbn(BB(n0(i),213),t),e)}function zgn(n,t,e){var i;switch(i=e[n.g][t],n.g){case 1:case 3:return new xI(0,i);case 2:case 4:return new xI(i,0);default:return null}}function Ugn(n,t,e){var i;i=BB(sJ(t.f),209);try{i.Ze(n,e),SW(t.f,i)}catch(r){throw cL(r=lun(r),102),Hp(r)}}function Xgn(n,t,e){var i,r,c,a;return i=null,(c=pGn(cin(),t))&&(r=null,null!=(a=Zqn(c,e))&&(r=n.Ye(c,a)),i=r),i}function Wgn(n,t,e,i){var r;return r=new N7(n.e,1,13,t.c||(gWn(),l$t),e.c||(gWn(),l$t),uvn(n,t),!1),i?i.Ei(r):i=r,i}function Vgn(n,t,e,i){var r;if(t>=(r=n.length))return r;for(t=t>0?t:0;t<r&&!ton((b1(t,n.length),n.charCodeAt(t)),e,i);t++);return t}function Qgn(n,t){var e,i;for(i=n.c.length,t.length<i&&(t=qk(new Array(i),t)),e=0;e<i;++e)$X(t,e,n.c[e]);return t.length>i&&$X(t,i,null),t}function Ygn(n,t){var e,i;for(i=n.a.length,t.length<i&&(t=qk(new Array(i),t)),e=0;e<i;++e)$X(t,e,n.a[e]);return t.length>i&&$X(t,i,null),t}function Jgn(n,t,e){var i,r,c;return(r=BB(RX(n.e,t),387))?(c=pR(r,e),uL(n,r),c):(i=new nH(n,t,e),VW(n.e,t,i),kJ(i),null)}function Zgn(n){var t;if(null==n)return null;if(null==(t=L$n(FBn(n,!0))))throw Hp(new ik("Invalid hexBinary value: '"+n+"'"));return t}function npn(n){return ODn(),Vhn(n,0)<0?0!=Vhn(n,-1)?new vEn(-1,j7(n)):Ytt:Vhn(n,10)<=0?Ztt[dG(n)]:new vEn(1,n)}function tpn(){return dWn(),Pun(Gk(_rt,1),$Vn,159,0,[Prt,Srt,Irt,vrt,prt,mrt,jrt,krt,yrt,Mrt,Trt,Ert,drt,wrt,grt,lrt,frt,brt,srt,ort,hrt,Crt])}function epn(n){var t;this.d=new Np,this.j=new Gj,this.g=new Gj,t=n.g.b,this.f=BB(mMn(vW(t),(HXn(),Udt)),103),this.e=Gy(MD(gpn(t,Spt)))}function ipn(n){this.b=new Np,this.e=new Np,this.d=n,this.a=!jE(AV(new Rq(null,new zU(new m6(n.b))),new aw(new Gr))).sd((dM(),tit))}function rpn(){rpn=O,hMt=new AI("PARENTS",0),sMt=new AI("NODES",1),uMt=new AI("EDGES",2),fMt=new AI("PORTS",3),oMt=new AI("LABELS",4)}function cpn(){cpn=O,BIt=new zI("DISTRIBUTED",0),qIt=new zI("JUSTIFIED",1),KIt=new zI("BEGIN",2),FIt=new zI(eJn,3),HIt=new zI("END",4)}function apn(n){switch(n.yi(null)){case 10:return 0;case 15:return 1;case 14:return 2;case 11:return 3;case 21:return 4}return-1}function upn(n){switch(n.g){case 1:return Ffn(),HPt;case 4:return Ffn(),KPt;case 2:return Ffn(),FPt;case 3:return Ffn(),_Pt}return Ffn(),BPt}function opn(n,t,e){var i;switch((i=e.q.getFullYear()-sQn+sQn)<0&&(i=-i),t){case 1:n.a+=i;break;case 2:Enn(n,i%100,2);break;default:Enn(n,i,t)}}function spn(n,t){var e,i;if(LZ(t,n.b),t>=n.b>>1)for(i=n.c,e=n.b;e>t;--e)i=i.b;else for(i=n.a.a,e=0;e<t;++e)i=i.a;return new Z_(n,t,i)}function hpn(){hpn=O,dit=new FS("NUM_OF_EXTERNAL_SIDES_THAN_NUM_OF_EXTENSIONS_LAST",0),wit=new FS("CORNER_CASES_THAN_SINGLE_SIDE_LAST",1)}function fpn(n){var t,e,i;for(m$(e=uIn(n),But),(i=n.d).c=x8(Ant,HWn,1,0,5,1),t=new Wb(e);t.a<t.c.c.length;)gun(i,BB(n0(t),456).b)}function lpn(n){var t,e;for(!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),t=(e=n.o).c.Kc();t.e!=t.i.gc();)BB(t.nj(),42).dd();return A8(e)}function bpn(n){var t;L_(BB(mMn(n,(HXn(),ept)),98))&&(fOn((l1(0,(t=n.b).c.length),BB(t.c[0],29))),fOn(BB(xq(t,t.c.length-1),29)))}function wpn(n,t){var i,r,c,a;for(i=0,c=new Wb(t.a);c.a<c.c.c.length;)a=(r=BB(n0(c),10)).o.a+r.d.c+r.d.b+n.j,i=e.Math.max(i,a);return i}function dpn(n){var t,e,i,r;for(r=0,e=0,i=n.length;e<i;e++)b1(e,n.length),(t=n.charCodeAt(e))>=64&&t<128&&(r=i0(r,yz(1,t-64)));return r}function gpn(n,t){var e,i;return i=null,Lx(n,(sWn(),IPt))&&(e=BB(mMn(n,IPt),94)).Xe(t)&&(i=e.We(t)),null==i&&vW(n)&&(i=mMn(vW(n),t)),i}function ppn(n,t){var e,i,r;(i=(r=t.d.i).k)!=(uSn(),Iut)&&i!=Tut&&dAn(e=new oz(ZL(lbn(r).a.Kc(),new h)))&&VW(n.k,t,BB(U5(e),17))}function vpn(n,t){var e,i,r;return i=itn(n.Tg(),t),(e=t-n.Ah())<0?(r=n.Yg(i))>=0?n.lh(r):qCn(n,i):e<0?qCn(n,i):BB(i,66).Nj().Sj(n,n.yh(),e)}function mpn(n){var t;if(cL(n.a,4)){if(null==(t=Jdn(n.a)))throw Hp(new Fy(o5n+n.b+"'. "+r5n+(ED(bAt),bAt.k)+c5n));return t}return n.a}function ypn(n){var t;if(null==n)return null;if(null==(t=UUn(FBn(n,!0))))throw Hp(new ik("Invalid base64Binary value: '"+n+"'"));return t}function kpn(n){var t;try{return t=n.i.Xb(n.e),n.mj(),n.g=n.e++,t}catch(e){throw cL(e=lun(e),73)?(n.mj(),Hp(new yv)):Hp(e)}}function jpn(n){var t;try{return t=n.c.ki(n.e),n.mj(),n.g=n.e++,t}catch(e){throw cL(e=lun(e),73)?(n.mj(),Hp(new yv)):Hp(e)}}function Epn(){Epn=O,sWn(),Ect=TPt,pct=ySt,lct=cSt,vct=XSt,Kkn(),kct=Mit,yct=Eit,jct=Pit,mct=jit,Gsn(),wct=oct,bct=uct,dct=hct,gct=fct}function Tpn(n){switch(jM(),this.c=new Np,this.d=n,n.g){case 0:case 2:this.a=QW(hut),this.b=RQn;break;case 3:case 1:this.a=hut,this.b=_Qn}}function Mpn(n,t,e){var i;if(n.c)Pen(n.c,n.c.i+t),Ien(n.c,n.c.j+e);else for(i=new Wb(n.b);i.a<i.c.c.length;)Mpn(BB(n0(i),157),t,e)}function Spn(n,t){var e,i;if(n.j.length!=t.j.length)return!1;for(e=0,i=n.j.length;e<i;e++)if(!m_(n.j[e],t.j[e]))return!1;return!0}function Ppn(n,t,e){var i;t.a.length>0&&(WB(n.b,new VB(t.a,e)),0<(i=t.a.length)?t.a=t.a.substr(0,0):0>i&&(t.a+=rL(x8(ONt,WVn,25,-i,15,1))))}function Ipn(n,t){var e,i,r;for(e=n.o,r=BB(BB(h6(n.r,t),21),84).Kc();r.Ob();)(i=BB(r.Pb(),111)).e.a=dyn(i,e.a),i.e.b=e.b*Gy(MD(i.b.We(Lrt)))}function Cpn(n,t){var e,i,r,c;return r=n.k,e=Gy(MD(mMn(n,(hWn(),Tlt)))),c=t.k,i=Gy(MD(mMn(t,Tlt))),c!=(uSn(),Mut)?-1:r!=Mut?1:e==i?0:e<i?-1:1}function Opn(n,t){var e,i;return e=BB(BB(RX(n.g,t.a),46).a,65),i=BB(BB(RX(n.g,t.b),46).a,65),W8(t.a,t.b)-W8(t.a,K$(e.b))-W8(t.b,K$(i.b))}function Apn(n,t){var e;return e=BB(mMn(n,(HXn(),vgt)),74),tL(t,vut)?e?yQ(e):(e=new km,hon(n,vgt,e)):e&&hon(n,vgt,null),e}function $pn(n){var t;return(t=new Ik).a+="n",n.k!=(uSn(),Iut)&&oO(oO((t.a+="(",t),dx(n.k).toLowerCase()),")"),oO((t.a+="_",t),gyn(n)),t.a}function Lpn(n,t){OTn(t,"Self-Loop post-processing",1),JT(AV(AV(wnn(new Rq(null,new w1(n.b,16)),new xi),new Di),new Ri),new _i),HSn(t)}function Npn(n,t,e,i){var r;return e>=0?n.hh(t,e,i):(n.eh()&&(i=(r=n.Vg())>=0?n.Qg(i):n.eh().ih(n,-1-r,null,i)),n.Sg(t,e,i))}function xpn(n,t){switch(t){case 7:return!n.e&&(n.e=new h_(KOt,n,7,4)),void sqn(n.e);case 8:return!n.d&&(n.d=new h_(KOt,n,8,5)),void sqn(n.d)}Dwn(n,t)}function Dpn(n,t){var e;e=n.Zc(t);try{return e.Pb()}catch(i){throw cL(i=lun(i),109)?Hp(new Ay("Can't get element "+t)):Hp(i)}}function Rpn(n,t){this.e=n,t<XQn?(this.d=1,this.a=Pun(Gk(ANt,1),hQn,25,15,[0|t])):(this.d=2,this.a=Pun(Gk(ANt,1),hQn,25,15,[t%XQn|0,t/XQn|0]))}function _pn(n,t){var e,i,r,c;for(SQ(),e=n,c=t,cL(n,21)&&!cL(t,21)&&(e=t,c=n),r=e.Kc();r.Ob();)if(i=r.Pb(),c.Hc(i))return!1;return!0}function Kpn(n,t,e){var i,r,c,a;return-1!=(i=n.Xc(t))&&(n.ej()?(c=n.fj(),a=Lyn(n,i),r=n.Zi(4,a,null,i,c),e?e.Ei(r):e=r):Lyn(n,i)),e}function Fpn(n,t,e){var i,r,c,a;return-1!=(i=n.Xc(t))&&(n.ej()?(c=n.fj(),a=wq(n,i),r=n.Zi(4,a,null,i,c),e?e.Ei(r):e=r):wq(n,i)),e}function Bpn(n,t){var e;switch(e=BB(oV(n.b,t),124).n,t.g){case 1:n.t>=0&&(e.d=n.t);break;case 3:n.t>=0&&(e.a=n.t)}n.C&&(e.b=n.C.b,e.c=n.C.c)}function Hpn(){Hpn=O,Brt=new KS(mJn,0),Frt=new KS(yJn,1),Hrt=new KS(kJn,2),qrt=new KS(jJn,3),Brt.a=!1,Frt.a=!0,Hrt.a=!1,qrt.a=!0}function qpn(){qpn=O,Zrt=new _S(mJn,0),Jrt=new _S(yJn,1),nct=new _S(kJn,2),tct=new _S(jJn,3),Zrt.a=!1,Jrt.a=!0,nct.a=!1,tct.a=!0}function Gpn(n){var t;t=n.a;do{(t=BB(U5(new oz(ZL(fbn(t).a.Kc(),new h))),17).c.i).k==(uSn(),Put)&&n.b.Fc(t)}while(t.k==(uSn(),Put));n.b=ean(n.b)}function zpn(n){var t,e,i;for(i=n.c.a,n.p=(yX(i),new tK(i)),e=new Wb(i);e.a<e.c.c.length;)(t=BB(n0(e),10)).p=hIn(t).a;SQ(),m$(n.p,new Oc)}function Upn(n){var t,e,i;if(e=0,0==(i=wDn(n)).c.length)return 1;for(t=new Wb(i);t.a<t.c.c.length;)e+=Upn(BB(n0(t),33));return e}function Xpn(n,t){var e,i,r;for(r=0,i=BB(BB(h6(n.r,t),21),84).Kc();i.Ob();)r+=(e=BB(i.Pb(),111)).d.b+e.b.rf().a+e.d.c,i.Ob()&&(r+=n.w);return r}function Wpn(n,t){var e,i,r;for(r=0,i=BB(BB(h6(n.r,t),21),84).Kc();i.Ob();)r+=(e=BB(i.Pb(),111)).d.d+e.b.rf().b+e.d.a,i.Ob()&&(r+=n.w);return r}function Vpn(n,t,e,i){if(t.a<i.a)return!0;if(t.a==i.a){if(t.b<i.b)return!0;if(t.b==i.b&&n.b>e.b)return!0}return!1}function Qpn(n,t){return XC(n)?!!OWn[t]:n.hm?!!n.hm[t]:UC(n)?!!CWn[t]:!!zC(n)&&!!IWn[t]}function Ypn(n,t,e){return null==e?(!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),Wdn(n.o,t)):(!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),vjn(n.o,t,e)),n}function Jpn(n,t,e,i){var r;(r=Xfn(t.Xe((sWn(),DSt))?BB(t.We(DSt),21):n.j))!=(dWn(),Crt)&&(e&&!agn(r)||USn(N$n(n,r,i),t))}function Zpn(n,t,e,i){var r,c,a;return c=itn(n.Tg(),t),(r=t-n.Ah())<0?(a=n.Yg(c))>=0?n._g(a,e,!0):cOn(n,c,e):BB(c,66).Nj().Pj(n,n.yh(),r,e,i)}function nvn(n,t,e,i){var r,c;e.mh(t)&&(ZM(),hnn(t)?ygn(n,BB(e.ah(t),153)):(r=(c=t)?BB(i,49).xh(c):null)&&Kp(e.ah(t),r))}function tvn(n){switch(n.g){case 1:return Dan(),Rrt;case 3:return Dan(),Nrt;case 2:return Dan(),Drt;case 4:return Dan(),xrt;default:return null}}function evn(n){switch(typeof n){case NWn:return vvn(n);case LWn:return IJ(n);case $Wn:return hN(),n?1231:1237;default:return null==n?0:PN(n)}}function ivn(n,t,e){if(n.e)switch(n.b){case 1:BQ(n.c,t,e);break;case 0:HQ(n.c,t,e)}else t4(n.c,t,e);n.a[t.p][e.p]=n.c.i,n.a[e.p][t.p]=n.c.e}function rvn(n){var t,e;if(null==n)return null;for(e=x8(Out,sVn,193,n.length,0,2),t=0;t<e.length;t++)e[t]=BB(G9(n[t],n[t].length),193);return e}function cvn(n){var t;if(_sn(n))return mz(n),n.Lk()&&(t=FCn(n.e,n.b,n.c,n.a,n.j),n.j=t),n.g=n.a,++n.a,++n.c,n.i=0,n.j;throw Hp(new yv)}function avn(n,t){var e,i,r,c;return(c=n.o)<(e=n.p)?c*=c:e*=e,i=c+e,(c=t.o)<(e=t.p)?c*=c:e*=e,i<(r=c+e)?-1:i==r?0:1}function uvn(n,t){var e,i;if((i=Wyn(n,t))>=0)return i;if(n.Fk())for(e=0;e<n.i;++e)if(GC(n.Gk(BB(n.g[e],56)))===GC(t))return e;return-1}function ovn(n,t,e){var i,r;if(t>=(r=n.gc()))throw Hp(new t_(t,r));if(n.hi()&&(i=n.Xc(e))>=0&&i!=t)throw Hp(new Ky(a8n));return n.mi(t,e)}function svn(n,t){if(this.a=BB(yX(n),245),this.b=BB(yX(t),245),n.vd(t)>0||n==(ey(),_nt)||t==(ty(),Knt))throw Hp(new Ky("Invalid range: "+B3(n,t)))}function hvn(n){var t,e;for(this.b=new Np,this.c=n,this.a=!1,e=new Wb(n.a);e.a<e.c.c.length;)t=BB(n0(e),10),this.a=this.a|t.k==(uSn(),Iut)}function fvn(n,t){var e,i,r;for(e=AN(new qv,n),r=new Wb(t);r.a<r.c.c.length;)i=BB(n0(r),121),UNn(aM(cM(uM(rM(new Hv,0),0),e),i));return e}function lvn(n,t,e){var i,r,c;for(r=new oz(ZL((t?fbn(n):lbn(n)).a.Kc(),new h));dAn(r);)i=BB(U5(r),17),(c=t?i.c.i:i.d.i).k==(uSn(),Sut)&&PZ(c,e)}function bvn(){bvn=O,lvt=new KP(QZn,0),bvt=new KP("PORT_POSITION",1),fvt=new KP("NODE_SIZE_WHERE_SPACE_PERMITS",2),hvt=new KP("NODE_SIZE",3)}function wvn(){wvn=O,IMt=new DI("AUTOMATIC",0),AMt=new DI(cJn,1),$Mt=new DI(aJn,2),LMt=new DI("TOP",3),CMt=new DI(oJn,4),OMt=new DI(eJn,5)}function dvn(n,t,e,i){var r,c;for($On(),r=0,c=0;c<e;c++)r=rbn(cbn(e0(t[c],UQn),e0(i,UQn)),e0(dG(r),UQn)),n[c]=dG(r),r=jz(r,32);return dG(r)}function gvn(n,t,i){var r,c;for(c=0,r=0;r<Zit;r++)c=e.Math.max(c,vhn(n.a[t.g][r],i));return t==(Dtn(),zit)&&n.b&&(c=e.Math.max(c,n.b.b)),c}function pvn(n,t){var e,i;if(Tx(t>0),(t&-t)==t)return IJ(t*H$n(n,31)*4.656612873077393e-10);do{i=(e=H$n(n,31))%t}while(e-i+(t-1)<0);return IJ(i)}function vvn(n){var t,e,i;return rK(),null!=(i=rit[e=":"+n])?IJ((kW(i),i)):(t=null==(i=iit[e])?JNn(n):IJ((kW(i),i)),CQ(),rit[e]=t,t)}function mvn(n,t,e){OTn(e,"Compound graph preprocessor",1),n.a=new pJ,Nzn(n,t,null),GHn(n,t),tNn(n),hon(t,(hWn(),Hft),n.a),n.a=null,$U(n.b),HSn(e)}function yvn(n,t,e){switch(e.g){case 1:n.a=t.a/2,n.b=0;break;case 2:n.a=t.a,n.b=t.b/2;break;case 3:n.a=t.a/2,n.b=t.b;break;case 4:n.a=0,n.b=t.b/2}}function kvn(n){var t,e,i;for(i=BB(h6(n.a,(LEn(),Pst)),15).Kc();i.Ob();)iX(n,e=BB(i.Pb(),101),(t=Hyn(e))[0],(Irn(),xst),0),iX(n,e,t[1],Rst,1)}function jvn(n){var t,e,i;for(i=BB(h6(n.a,(LEn(),Ist)),15).Kc();i.Ob();)iX(n,e=BB(i.Pb(),101),(t=Hyn(e))[0],(Irn(),xst),0),iX(n,e,t[1],Rst,1)}function Evn(n){switch(n.g){case 0:return null;case 1:return new Arn;case 2:return new Jm;default:throw Hp(new Ky(c4n+(null!=n.f?n.f:""+n.g)))}}function Tvn(n,t,e){var i,r;for(mun(n,t-n.s,e-n.t),r=new Wb(n.n);r.a<r.c.c.length;)rb(i=BB(n0(r),211),i.e+t-n.s),cb(i,i.f+e-n.t);n.s=t,n.t=e}function Mvn(n){var t,e,i,r;for(e=0,i=new Wb(n.a);i.a<i.c.c.length;)BB(n0(i),121).d=e++;return r=null,(t=wSn(n)).c.length>1&&(r=fvn(n,t)),r}function Svn(n){var t;return n.f&&n.f.kh()&&(t=BB(n.f,49),n.f=BB(tfn(n,t),82),n.f!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,9,8,t,n.f))),n.f}function Pvn(n){var t;return n.i&&n.i.kh()&&(t=BB(n.i,49),n.i=BB(tfn(n,t),82),n.i!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,9,7,t,n.i))),n.i}function Ivn(n){var t;return n.b&&0!=(64&n.b.Db)&&(t=n.b,n.b=BB(tfn(n,t),18),n.b!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,9,21,t,n.b))),n.b}function Cvn(n,t){var e,i,r;null==n.d?(++n.e,++n.f):(i=t.Sh(),fNn(n,n.f+1),r=(i&DWn)%n.d.length,!(e=n.d[r])&&(e=n.d[r]=n.uj()),e.Fc(t),++n.f)}function Ovn(n,t,e){var i;return!t.Kj()&&(-2!=t.Zj()?null==(i=t.zj())?null==e:Nfn(i,e):t.Hj()==n.e.Tg()&&null==e)}function Avn(){var n;lin(16,CVn),n=Jin(16),this.b=x8(Gnt,IVn,317,n,0,1),this.c=x8(Gnt,IVn,317,n,0,1),this.a=null,this.e=null,this.i=0,this.f=n-1,this.g=0}function $vn(n){LR.call(this),this.k=(uSn(),Iut),this.j=(lin(6,AVn),new J6(6)),this.b=(lin(2,AVn),new J6(2)),this.d=new fm,this.f=new wm,this.a=n}function Lvn(n){var t,e;n.c.length<=1||(dPn(n,BB((t=EDn(n,(kUn(),SCt))).a,19).a,BB(t.b,19).a),dPn(n,BB((e=EDn(n,ICt)).a,19).a,BB(e.b,19).a))}function Nvn(){Nvn=O,yvt=new FP("SIMPLE",0),pvt=new FP(B1n,1),vvt=new FP("LINEAR_SEGMENTS",2),gvt=new FP("BRANDES_KOEPF",3),mvt=new FP(j3n,4)}function xvn(n,t,e){L_(BB(mMn(t,(HXn(),ept)),98))||(W7(n,t,DSn(t,e)),W7(n,t,DSn(t,(kUn(),SCt))),W7(n,t,DSn(t,sCt)),SQ(),m$(t.j,new Kd(n)))}function Dvn(n,t,e,i){var r;for(r=BB(h6(i?n.a:n.b,t),21).Kc();r.Ob();)if(KDn(n,e,BB(r.Pb(),33)))return!0;return!1}function Rvn(n){var t,e;for(e=new AL(n);e.e!=e.i.gc();)if((t=BB(kpn(e),87)).e||0!=(!t.d&&(t.d=new $L(VAt,t,1)),t.d).i)return!0;return!1}function _vn(n){var t,e;for(e=new AL(n);e.e!=e.i.gc();)if((t=BB(kpn(e),87)).e||0!=(!t.d&&(t.d=new $L(VAt,t,1)),t.d).i)return!0;return!1}function Kvn(n){var t,e;for(t=0,e=new Wb(n.c.a);e.a<e.c.c.length;)t+=F3(new oz(ZL(lbn(BB(n0(e),10)).a.Kc(),new h)));return t/n.c.a.c.length}function Fvn(n){var t,e;for(n.c||zqn(n),e=new km,n0(t=new Wb(n.a));t.a<t.c.c.length;)DH(e,BB(n0(t),407).a);return Px(0!=e.b),Atn(e,e.c.b),e}function Bvn(){Bvn=O,bRn(),qTt=RTt,BTt=new WA(8),new XA((sWn(),XSt),BTt),new XA(LPt,8),HTt=xTt,KTt=MTt,FTt=STt,_Tt=new XA(lSt,(hN(),!1))}function Hvn(n,t,e,i){switch(t){case 7:return!n.e&&(n.e=new h_(KOt,n,7,4)),n.e;case 8:return!n.d&&(n.d=new h_(KOt,n,8,5)),n.d}return Rbn(n,t,e,i)}function qvn(n){var t;return n.a&&n.a.kh()&&(t=BB(n.a,49),n.a=BB(tfn(n,t),138),n.a!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,9,5,t,n.a))),n.a}function Gvn(n){return n<48||n>102?-1:n<=57?n-48:n<65?-1:n<=70?n-65+10:n<97?-1:n-97+10}function zvn(n,t){if(null==n)throw Hp(new Hy("null key in entry: null="+t));if(null==t)throw Hp(new Hy("null value in entry: "+n+"=null"))}function Uvn(n,t){for(var e,i;n.Ob();){if(!t.Ob())return!1;if(e=n.Pb(),i=t.Pb(),!(GC(e)===GC(i)||null!=e&&Nfn(e,i)))return!1}return!t.Ob()}function Xvn(n,t){var i;return i=Pun(Gk(xNt,1),qQn,25,15,[vhn(n.a[0],t),vhn(n.a[1],t),vhn(n.a[2],t)]),n.d&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function Wvn(n,t){var i;return i=Pun(Gk(xNt,1),qQn,25,15,[mhn(n.a[0],t),mhn(n.a[1],t),mhn(n.a[2],t)]),n.d&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function Vvn(){Vvn=O,yht=new SP("GREEDY",0),mht=new SP(H1n,1),jht=new SP(B1n,2),Eht=new SP("MODEL_ORDER",3),kht=new SP("GREEDY_MODEL_ORDER",4)}function Qvn(n,t){var e,i,r;for(n.b[t.g]=1,i=spn(t.d,0);i.b!=i.d.c;)r=(e=BB(b3(i),188)).c,1==n.b[r.g]?DH(n.a,e):2==n.b[r.g]?n.b[r.g]=1:Qvn(n,r)}function Yvn(n,t){var e,i,r;for(r=new J6(t.gc()),i=t.Kc();i.Ob();)(e=BB(i.Pb(),286)).c==e.f?hPn(n,e,e.c):rPn(n,e)||(r.c[r.c.length]=e);return r}function Jvn(n,t,e){var i,r,c,a;for(a=n.r+t,n.r+=t,n.d+=e,i=e/n.n.c.length,r=0,c=new Wb(n.n);c.a<c.c.c.length;)w$n(BB(n0(c),211),a,i,r),++r}function Zvn(n){var t,e;for(my(n.b.a),n.a=x8(bit,HWn,57,n.c.c.a.b.c.length,0,1),t=0,e=new Wb(n.c.c.a.b);e.a<e.c.c.length;)BB(n0(e),57).f=t++}function nmn(n){var t,e;for(my(n.b.a),n.a=x8(Qat,HWn,81,n.c.a.a.b.c.length,0,1),t=0,e=new Wb(n.c.a.a.b);e.a<e.c.c.length;)BB(n0(e),81).i=t++}function tmn(n,t,e){OTn(e,"Shrinking tree compaction",1),qy(TD(mMn(t,(Xcn(),Qrt))))?(irn(n,t.f),unn(t.f,t.c)):unn(t.f,t.c),HSn(e)}function emn(n){var t;if(t=bhn(n),!dAn(n))throw Hp(new Ay("position (0) must be less than the number of elements that remained ("+t+")"));return U5(n)}function imn(n,t,e){try{return vmn(n,t+n.j,e+n.k)}catch(i){throw cL(i=lun(i),73)?Hp(new Ay(i.g+IJn+t+FWn+e+").")):Hp(i)}}function rmn(n,t,e){try{return mmn(n,t+n.j,e+n.k)}catch(i){throw cL(i=lun(i),73)?Hp(new Ay(i.g+IJn+t+FWn+e+").")):Hp(i)}}function cmn(n,t,e){try{return ymn(n,t+n.j,e+n.k)}catch(i){throw cL(i=lun(i),73)?Hp(new Ay(i.g+IJn+t+FWn+e+").")):Hp(i)}}function amn(n){switch(n.g){case 1:return kUn(),ICt;case 4:return kUn(),sCt;case 3:return kUn(),oCt;case 2:return kUn(),SCt;default:return kUn(),PCt}}function umn(n,t,e){t.k==(uSn(),Iut)&&e.k==Put&&(n.d=Efn(t,(kUn(),SCt)),n.b=Efn(t,sCt)),e.k==Iut&&t.k==Put&&(n.d=Efn(e,(kUn(),sCt)),n.b=Efn(e,SCt))}function omn(n,t){var e,i;for(i=abn(n,t).Kc();i.Ob();)if(null!=mMn(e=BB(i.Pb(),11),(hWn(),Elt))||zN(new m6(e.b)))return!0;return!1}function smn(n,t){return Pen(t,n.e+n.d+(0==n.c.c.length?0:n.b)),Ien(t,n.f),n.a=e.Math.max(n.a,t.f),n.d+=t.g+(0==n.c.c.length?0:n.b),WB(n.c,t),!0}function hmn(n,t,e){var i,r,c,a;for(a=0,i=e/n.a.c.length,c=new Wb(n.a);c.a<c.c.c.length;)Tvn(r=BB(n0(c),187),r.s,r.t+a*i),Jvn(r,n.d-r.r+t,i),++a}function fmn(n){var t,e,i;for(e=new Wb(n.b);e.a<e.c.c.length;)for(t=0,i=new Wb(BB(n0(e),29).a);i.a<i.c.c.length;)BB(n0(i),10).p=t++}function lmn(n,t){var e,i,r,c,a,u;for(r=t.length-1,a=0,u=0,i=0;i<=r;i++)c=t[i],e=pSn(r,i)*efn(1-n,r-i)*efn(n,i),a+=c.a*e,u+=c.b*e;return new xI(a,u)}function bmn(n,t){var e,i,r,c,a;for(e=t.gc(),n.qi(n.i+e),c=t.Kc(),a=n.i,n.i+=e,i=a;i<n.i;++i)r=c.Pb(),jL(n,i,n.oi(i,r)),n.bi(i,r),n.ci();return 0!=e}function wmn(n,t,e){var i,r,c;return n.ej()?(i=n.Vi(),c=n.fj(),++n.j,n.Hi(i,n.oi(i,t)),r=n.Zi(3,null,t,i,c),e?e.Ei(r):e=r):ZD(n,n.Vi(),t),e}function dmn(n,t,e){var i,r,c;return(0!=(64&(c=cL(r=(i=BB(Wtn(a4(n.a),t),87)).c,88)?BB(r,26):(gWn(),d$t)).Db)?tfn(n.b,c):c)==e?lFn(i):cen(i,e),c}function gmn(n,t,e,i,r,c,a,u){var o,s;i&&((o=i.a[0])&&gmn(n,t,e,o,r,c,a,u),Cyn(n,e,i.d,r,c,a,u)&&t.Fc(i),(s=i.a[1])&&gmn(n,t,e,s,r,c,a,u))}function pmn(n,t){var e;return n.a||(e=x8(xNt,qQn,25,0,15,1),gE(n.b.a,new bw(e)),e.sort(ien(T.prototype.te,T,[])),n.a=new K_(e,n.d)),_6(n.a,t)}function vmn(n,t,e){try{return QC(trn(n,t,e),1)}catch(i){throw cL(i=lun(i),320)?Hp(new Ay(MJn+n.o+"*"+n.p+SJn+t+FWn+e+PJn)):Hp(i)}}function mmn(n,t,e){try{return QC(trn(n,t,e),0)}catch(i){throw cL(i=lun(i),320)?Hp(new Ay(MJn+n.o+"*"+n.p+SJn+t+FWn+e+PJn)):Hp(i)}}function ymn(n,t,e){try{return QC(trn(n,t,e),2)}catch(i){throw cL(i=lun(i),320)?Hp(new Ay(MJn+n.o+"*"+n.p+SJn+t+FWn+e+PJn)):Hp(i)}}function kmn(n,t){if(-1==n.g)throw Hp(new dv);n.mj();try{n.d._c(n.g,t),n.f=n.d.j}catch(e){throw cL(e=lun(e),73)?Hp(new vv):Hp(e)}}function jmn(n,t,e){OTn(e,"Linear segments node placement",1),n.b=BB(mMn(t,(hWn(),Alt)),304),VXn(n,t),vHn(n,t),QHn(n,t),hXn(n),n.a=null,n.b=null,HSn(e)}function Emn(n,t){var e,i,r,c;for(c=n.gc(),t.length<c&&(t=qk(new Array(c),t)),r=t,i=n.Kc(),e=0;e<c;++e)$X(r,e,i.Pb());return t.length>c&&$X(t,c,null),t}function Tmn(n,t){var e,i;if(i=n.gc(),null==t){for(e=0;e<i;e++)if(null==n.Xb(e))return e}else for(e=0;e<i;e++)if(Nfn(t,n.Xb(e)))return e;return-1}function Mmn(n,t){var e,i,r;return e=t.cd(),r=t.dd(),i=n.xc(e),!(!(GC(r)===GC(i)||null!=r&&Nfn(r,i))||null==i&&!n._b(e))}function Smn(n,t){var e,i,r;return t<=22?(e=n.l&(1<<t)-1,i=r=0):t<=44?(e=n.l,i=n.m&(1<<t-22)-1,r=0):(e=n.l,i=n.m,r=n.h&(1<<t-44)-1),M$(e,i,r)}function Pmn(n,t){switch(t.g){case 1:return n.f.n.d+n.t;case 3:return n.f.n.a+n.t;case 2:return n.f.n.c+n.s;case 4:return n.f.n.b+n.s;default:return 0}}function Imn(n,t){var e,i;switch(i=t.c,e=t.a,n.b.g){case 0:e.d=n.e-i.a-i.d;break;case 1:e.d+=n.e;break;case 2:e.c=n.e-i.a-i.d;break;case 3:e.c=n.e+i.d}}function Cmn(n,t,e,i){var r,c;this.a=t,this.c=i,$l(this,new xI(-(r=n.a).c,-r.d)),UR(this.b,e),c=i/2,t.a?Bx(this.b,0,c):Bx(this.b,c,0),WB(n.c,this)}function Omn(){Omn=O,qjt=new mI(QZn,0),Bjt=new mI(q1n,1),Hjt=new mI("EDGE_LENGTH_BY_POSITION",2),Fjt=new mI("CROSSING_MINIMIZATION_BY_POSITION",3)}function Amn(n,t){var e,i;if(e=BB(sen(n.g,t),33))return e;if(i=BB(sen(n.j,t),118))return i;throw Hp(new ek("Referenced shape does not exist: "+t))}function $mn(n,t){if(n.c==t)return n.d;if(n.d==t)return n.c;throw Hp(new Ky("Node 'one' must be either source or target of edge 'edge'."))}function Lmn(n,t){if(n.c.i==t)return n.d.i;if(n.d.i==t)return n.c.i;throw Hp(new Ky("Node "+t+" is neither source nor target of edge "+n))}function Nmn(n,t){var e;switch(t.g){case 2:case 4:e=n.a,n.c.d.n.b<e.d.n.b&&(e=n.c),bU(n,t,(Oun(),kst),e);break;case 1:case 3:bU(n,t,(Oun(),vst),null)}}function xmn(n,t,e,i,r,c){var a,u,o,s,h;for(a=ijn(t,e,c),u=e==(kUn(),sCt)||e==ICt?-1:1,s=n[e.g],h=0;h<s.length;h++)(o=s[h])>0&&(o+=r),s[h]=a,a+=u*(o+i)}function Dmn(n){var t,e,i;for(i=n.f,n.n=x8(xNt,qQn,25,i,15,1),n.d=x8(xNt,qQn,25,i,15,1),t=0;t<i;t++)e=BB(xq(n.c.b,t),29),n.n[t]=wpn(n,e),n.d[t]=VLn(n,e)}function Rmn(n,t){var e,i,r;for(r=0,i=2;i<t;i<<=1)0!=(n.Db&i)&&++r;if(0==r){for(e=t<<=1;e<=128;e<<=1)if(0!=(n.Db&e))return 0;return-1}return r}function _mn(n,t){var e,i,r,c,a;for(a=axn(n.e.Tg(),t),c=null,e=BB(n.g,119),r=0;r<n.i;++r)i=e[r],a.rl(i.ak())&&(!c&&(c=new go),f9(c,i));c&&aXn(n,c)}function Kmn(n){var t,e;if(!n)return null;if(n.dc())return"";for(e=new Sk,t=n.Kc();t.Ob();)cO(e,SD(t.Pb())),e.a+=" ";return _O(e,e.a.length-1)}function Fmn(n,t,e){var i,r,c,a;for(con(n),null==n.k&&(n.k=x8(Jnt,sVn,78,0,0,1)),r=0,c=(i=n.k).length;r<c;++r)Fmn(i[r],t,"\t"+e);(a=n.f)&&Fmn(a,t,e)}function Bmn(n,t){var e,i=new Array(t);switch(n){case 14:case 15:e=0;break;case 16:e=!1;break;default:return i}for(var r=0;r<t;++r)i[r]=e;return i}function Hmn(n){var t;for(t=new Wb(n.a.b);t.a<t.c.c.length;)BB(n0(t),57).c.$b();Otn(dA(n.d)?n.a.c:n.a.d,new Mw(n)),n.c.Me(n),Kxn(n)}function qmn(n){var t,e,i;for(e=new Wb(n.e.c);e.a<e.c.c.length;){for(i=new Wb((t=BB(n0(e),282)).b);i.a<i.c.c.length;)KBn(BB(n0(i),447));BIn(t)}}function Gmn(n){var t,i,r,c,a;for(r=0,a=0,c=0,i=new Wb(n.a);i.a<i.c.c.length;)t=BB(n0(i),187),a=e.Math.max(a,t.r),r+=t.d+(c>0?n.c:0),++c;n.b=r,n.d=a}function zmn(n,t){var i,r,c,a,u;for(r=0,c=0,i=0,u=new Wb(t);u.a<u.c.c.length;)a=BB(n0(u),200),r=e.Math.max(r,a.e),c+=a.b+(i>0?n.g:0),++i;n.c=c,n.d=r}function Umn(n,t){var i;return i=Pun(Gk(xNt,1),qQn,25,15,[gvn(n,(Dtn(),Git),t),gvn(n,zit,t),gvn(n,Uit,t)]),n.f&&(i[0]=e.Math.max(i[0],i[2]),i[2]=i[0]),i}function Xmn(n,t,e){try{FRn(n,t+n.j,e+n.k,!1,!0)}catch(i){throw cL(i=lun(i),73)?Hp(new Ay(i.g+IJn+t+FWn+e+").")):Hp(i)}}function Wmn(n,t,e){try{FRn(n,t+n.j,e+n.k,!0,!1)}catch(i){throw cL(i=lun(i),73)?Hp(new Ay(i.g+IJn+t+FWn+e+").")):Hp(i)}}function Vmn(n){var t;Lx(n,(HXn(),$gt))&&((t=BB(mMn(n,$gt),21)).Hc((n$n(),CIt))?(t.Mc(CIt),t.Fc(AIt)):t.Hc(AIt)&&(t.Mc(AIt),t.Fc(CIt)))}function Qmn(n){var t;Lx(n,(HXn(),$gt))&&((t=BB(mMn(n,$gt),21)).Hc((n$n(),DIt))?(t.Mc(DIt),t.Fc(NIt)):t.Hc(NIt)&&(t.Mc(NIt),t.Fc(DIt)))}function Ymn(n,t,e){OTn(e,"Self-Loop ordering",1),JT($V(AV(AV(wnn(new Rq(null,new w1(t.b,16)),new Ci),new Oi),new Ai),new $i),new bd(n)),HSn(e)}function Jmn(n,t,e,i){var r,c;for(r=t;r<n.c.length;r++){if(l1(r,n.c.length),c=BB(n.c[r],11),!e.Mb(c))return r;i.c[i.c.length]=c}return n.c.length}function Zmn(n,t,e,i){var r,c,a;return null==n.a&&dSn(n,t),a=t.b.j.c.length,c=e.d.p,(r=i.d.p-1)<0&&(r=a-1),c<=r?n.a[r]-n.a[c]:n.a[a-1]-n.a[c]+n.a[r]}function nyn(n){var t,e;if(!n.b)for(n.b=I2(BB(n.f,33).Ag().i),e=new AL(BB(n.f,33).Ag());e.e!=e.i.gc();)t=BB(kpn(e),137),WB(n.b,new Ry(t));return n.b}function tyn(n){var t,e;if(!n.e)for(n.e=I2(yV(BB(n.f,33)).i),e=new AL(yV(BB(n.f,33)));e.e!=e.i.gc();)t=BB(kpn(e),118),WB(n.e,new op(t));return n.e}function eyn(n){var t,e;if(!n.a)for(n.a=I2(YQ(BB(n.f,33)).i),e=new AL(YQ(BB(n.f,33)));e.e!=e.i.gc();)t=BB(kpn(e),33),WB(n.a,new JN(n,t));return n.a}function iyn(n){var t;if(!n.C&&(null!=n.D||null!=n.B))if(t=bzn(n))n.yk(t);else try{n.yk(null)}catch(e){if(!cL(e=lun(e),60))throw Hp(e)}return n.C}function ryn(n){switch(n.q.g){case 5:kjn(n,(kUn(),sCt)),kjn(n,SCt);break;case 4:cGn(n,(kUn(),sCt)),cGn(n,SCt);break;default:FPn(n,(kUn(),sCt)),FPn(n,SCt)}}function cyn(n){switch(n.q.g){case 5:jjn(n,(kUn(),oCt)),jjn(n,ICt);break;case 4:aGn(n,(kUn(),oCt)),aGn(n,ICt);break;default:BPn(n,(kUn(),oCt)),BPn(n,ICt)}}function ayn(n,t){var i,r,c;for(c=new Gj,r=n.Kc();r.Ob();)ZRn(i=BB(r.Pb(),37),c.a,0),c.a+=i.f.a+t,c.b=e.Math.max(c.b,i.f.b);return c.b>0&&(c.b+=t),c}function uyn(n,t){var i,r,c;for(c=new Gj,r=n.Kc();r.Ob();)ZRn(i=BB(r.Pb(),37),0,c.b),c.b+=i.f.b+t,c.a=e.Math.max(c.a,i.f.a);return c.a>0&&(c.a+=t),c}function oyn(n){var t,i,r;for(r=DWn,i=new Wb(n.a);i.a<i.c.c.length;)Lx(t=BB(n0(i),10),(hWn(),wlt))&&(r=e.Math.min(r,BB(mMn(t,wlt),19).a));return r}function syn(n,t){var e,i;if(0==t.length)return 0;for(e=ZX(n.a,t[0],(kUn(),ICt)),e+=ZX(n.a,t[t.length-1],oCt),i=0;i<t.length;i++)e+=qMn(n,i,t);return e}function hyn(){gxn(),this.c=new Np,this.i=new Np,this.e=new fA,this.f=new fA,this.g=new fA,this.j=new Np,this.a=new Np,this.b=new xp,this.k=new xp}function fyn(n,t){var e;return n.Db>>16==6?n.Cb.ih(n,5,GOt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||n.zh(),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function lyn(n){PY();var t=n.e;if(t&&t.stack){var e=t.stack,i=t+"\n";return e.substring(0,i.length)==i&&(e=e.substring(i.length)),e.split("\n")}return[]}function byn(n){var t;return Min(),(t=Ott)[n>>>28]|t[n>>24&15]<<4|t[n>>20&15]<<8|t[n>>16&15]<<12|t[n>>12&15]<<16|t[n>>8&15]<<20|t[n>>4&15]<<24|t[15&n]<<28}function wyn(n){var t,i,r;n.b==n.c&&(r=n.a.length,i=kon(e.Math.max(8,r))<<1,0!=n.b?(urn(n,t=SR(n.a,i),r),n.a=t,n.b=0):Pv(n.a,i),n.c=r)}function dyn(n,t){var e;return(e=n.b).Xe((sWn(),aPt))?e.Hf()==(kUn(),ICt)?-e.rf().a-Gy(MD(e.We(aPt))):t+Gy(MD(e.We(aPt))):e.Hf()==(kUn(),ICt)?-e.rf().a:t}function gyn(n){var t;return 0!=n.b.c.length&&BB(xq(n.b,0),70).a?BB(xq(n.b,0),70).a:null!=(t=eQ(n))?t:""+(n.c?E7(n.c.a,n,0):-1)}function pyn(n){var t;return 0!=n.f.c.length&&BB(xq(n.f,0),70).a?BB(xq(n.f,0),70).a:null!=(t=eQ(n))?t:""+(n.i?E7(n.i.j,n,0):-1)}function vyn(n,t){var e,i;if(t<0||t>=n.gc())return null;for(e=t;e<n.gc();++e)if(i=BB(n.Xb(e),128),e==n.gc()-1||!i.o)return new rC(iln(e),i);return null}function myn(n,t,e){var i,r,c,a;for(c=n.c,i=e?n:t,r=(e?t:n).p+1;r<i.p;++r)if((a=BB(xq(c.a,r),10)).k!=(uSn(),Tut)&&!Lkn(a))return!1;return!0}function yyn(n){var t,i,r,c,a;for(a=0,c=_Qn,r=0,i=new Wb(n.a);i.a<i.c.c.length;)a+=(t=BB(n0(i),187)).r+(r>0?n.c:0),c=e.Math.max(c,t.d),++r;n.e=a,n.b=c}function kyn(n){var t,e;if(!n.b)for(n.b=I2(BB(n.f,118).Ag().i),e=new AL(BB(n.f,118).Ag());e.e!=e.i.gc();)t=BB(kpn(e),137),WB(n.b,new Ry(t));return n.b}function jyn(n,t){var e,i,r;if(t.dc())return dD(),dD(),pAt;for(e=new aR(n,t.gc()),r=new AL(n);r.e!=r.i.gc();)i=kpn(r),t.Hc(i)&&f9(e,i);return e}function Eyn(n,t,e,i){return 0==t?i?(!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),n.o):(!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),A8(n.o)):Zpn(n,t,e,i)}function Tyn(n){var t,e;if(n.rb)for(t=0,e=n.rb.i;t<e;++t)vx(Wtn(n.rb,t));if(n.vb)for(t=0,e=n.vb.i;t<e;++t)vx(Wtn(n.vb,t));az((CPn(),Z$t),n),n.Bb|=1}function Myn(n,t,e,i,r,c,a,u,o,s,h,f,l,b){return bIn(n,t,i,null,r,c,a,u,o,s,l,!0,b),zln(n,h),cL(n.Cb,88)&&AIn(P5(BB(n.Cb,88)),2),e&&rrn(n,e),Uln(n,f),n}function Syn(n){var t;if(null==n)return null;t=0;try{t=lKn(n,KVn,DWn)&QVn}catch(e){if(!cL(e=lun(e),127))throw Hp(e);t=V7(n)[0]}return fun(t)}function Pyn(n){var t;if(null==n)return null;t=0;try{t=lKn(n,KVn,DWn)&QVn}catch(e){if(!cL(e=lun(e),127))throw Hp(e);t=V7(n)[0]}return fun(t)}function Iyn(n,t){var e,i,r;return!((r=n.h-t.h)<0||(e=n.l-t.l,(r+=(i=n.m-t.m+(e>>22))>>22)<0||(n.l=e&SQn,n.m=i&SQn,n.h=r&PQn,0)))}function Cyn(n,t,e,i,r,c,a){var u,o;return!(t.Ae()&&(o=n.a.ue(e,i),o<0||!r&&0==o)||t.Be()&&(u=n.a.ue(e,c),u>0||!a&&0==u))}function Oyn(n,t){if(zsn(),0!=n.j.g-t.j.g)return 0;switch(n.j.g){case 2:return jbn(t,bst)-jbn(n,bst);case 4:return jbn(n,lst)-jbn(t,lst)}return 0}function Ayn(n){switch(n.g){case 0:return xht;case 1:return Dht;case 2:return Rht;case 3:return _ht;case 4:return Kht;case 5:return Fht;default:return null}}function $yn(n,t,e){var i,r;return Chn(r=new Lm,t),Nrn(r,e),f9((!n.c&&(n.c=new eU(YAt,n,12,10)),n.c),r),Len(i=r,0),Nen(i,1),nln(i,!0),Yfn(i,!0),i}function Lyn(n,t){var e,i;if(t>=n.i)throw Hp(new LO(t,n.i));return++n.j,e=n.g[t],(i=n.i-t-1)>0&&aHn(n.g,t+1,n.g,t,i),$X(n.g,--n.i,null),n.fi(t,e),n.ci(),e}function Nyn(n,t){var e;return n.Db>>16==17?n.Cb.ih(n,21,qAt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||n.zh(),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function xyn(n){var t,e,i;for(SQ(),m$(n.c,n.a),i=new Wb(n.c);i.a<i.c.c.length;)for(e=n0(i),t=new Wb(n.b);t.a<t.c.c.length;)BB(n0(t),679).Ke(e)}function Dyn(n){var t,e,i;for(SQ(),m$(n.c,n.a),i=new Wb(n.c);i.a<i.c.c.length;)for(e=n0(i),t=new Wb(n.b);t.a<t.c.c.length;)BB(n0(t),369).Ke(e)}function Ryn(n){var t,e,i,r,c;for(r=DWn,c=null,i=new Wb(n.d);i.a<i.c.c.length;)(e=BB(n0(i),213)).d.j^e.e.j&&(t=e.e.e-e.d.e-e.a)<r&&(r=t,c=e);return c}function _yn(){_yn=O,dat=new $O(NZn,(hN(),!1)),fat=new $O(xZn,100),q7(),lat=new $O(DZn,bat=Oat),wat=new $O(RZn,lZn),gat=new $O(_Zn,iln(DWn))}function Kyn(n,t,e){var i,r,c,a,u,o;for(o=0,r=0,c=(i=n.a[t]).length;r<c;++r)for(u=Lfn(i[r],e).Kc();u.Ob();)a=BB(u.Pb(),11),VW(n.f,a,iln(o++))}function Fyn(n,t,e){var i,r;if(e)for(r=((i=new hz(e.a.length)).b-i.a)*i.c<0?(eS(),MNt):new XL(i);r.Ob();)JCn(n,t,kCn(dnn(e,BB(r.Pb(),19).a)))}function Byn(n,t,e){var i,r;if(e)for(r=((i=new hz(e.a.length)).b-i.a)*i.c<0?(eS(),MNt):new XL(i);r.Ob();)JCn(n,t,kCn(dnn(e,BB(r.Pb(),19).a)))}function Hyn(n){var t;return KMn(),z9(t=BB(Emn(gz(n.k),x8(FCt,YZn,61,2,0,1)),122),0,t.length,null),t[0]==(kUn(),sCt)&&t[1]==ICt&&($X(t,0,ICt),$X(t,1,sCt)),t}function qyn(n,t,e){var i,r,c;return c=sDn(n,r=XNn(n,t,e)),_9(n.b),k0(n,t,e),SQ(),m$(r,new Vd(n)),i=sDn(n,r),_9(n.b),k0(n,e,t),new rC(iln(c),iln(i))}function Gyn(){Gyn=O,Umt=dq(new B2,(yMn(),Bat),(lWn(),dot)),Xmt=new iR("linearSegments.inputPrio",iln(0)),Wmt=new iR("linearSegments.outputPrio",iln(0))}function zyn(){zyn=O,Ryt=new fI("P1_TREEIFICATION",0),_yt=new fI("P2_NODE_ORDERING",1),Kyt=new fI("P3_NODE_PLACEMENT",2),Fyt=new fI("P4_EDGE_ROUTING",3)}function Uyn(){Uyn=O,sWn(),xjt=gPt,_jt=LPt,Ijt=_St,Cjt=BSt,Ojt=qSt,Pjt=DSt,Ajt=USt,Njt=fPt,_An(),Mjt=wjt,Sjt=djt,$jt=pjt,Ljt=mjt,Djt=yjt,Rjt=kjt,Kjt=Ejt}function Xyn(){Xyn=O,MIt=new qI("UNKNOWN",0),jIt=new qI("ABOVE",1),EIt=new qI("BELOW",2),TIt=new qI("INLINE",3),new iR("org.eclipse.elk.labelSide",MIt)}function Wyn(n,t){var e;if(n.ni()&&null!=t){for(e=0;e<n.i;++e)if(Nfn(t,n.g[e]))return e}else for(e=0;e<n.i;++e)if(GC(n.g[e])===GC(t))return e;return-1}function Vyn(n,t,e){var i,r;return t.c==(ain(),qvt)&&e.c==Hvt?-1:t.c==Hvt&&e.c==qvt?1:(i=dhn(t.a,n.a),r=dhn(e.a,n.a),t.c==qvt?r-i:i-r)}function Qyn(n,t,e){if(e&&(t<0||t>e.a.c.length))throw Hp(new Ky("index must be >= 0 and <= layer node count"));n.c&&y7(n.c.a,n),n.c=e,e&&kG(e.a,t,n)}function Yyn(n,t){var e,i,r;for(i=new oz(ZL(hbn(n).a.Kc(),new h));dAn(i);)return e=BB(U5(i),17),new qf(yX((r=BB(t.Kb(e),10)).n.b+r.o.b/2));return iy(),iy(),Ont}function Jyn(n,t){this.c=new xp,this.a=n,this.b=t,this.d=BB(mMn(n,(hWn(),Alt)),304),GC(mMn(n,(HXn(),Lgt)))===GC((g7(),qht))?this.e=new gm:this.e=new dm}function Zyn(n,t){var i,r,c;for(c=0,r=new Wb(n);r.a<r.c.c.length;)i=BB(n0(r),33),c+=e.Math.pow(i.g*i.f-t,2);return e.Math.sqrt(c/(n.c.length-1))}function nkn(n,t){var e,i;return i=null,n.Xe((sWn(),IPt))&&(e=BB(n.We(IPt),94)).Xe(t)&&(i=e.We(t)),null==i&&n.yf()&&(i=n.yf().We(t)),null==i&&(i=mpn(t)),i}function tkn(n,t){var e,i;e=n.Zc(t);try{return i=e.Pb(),e.Qb(),i}catch(r){throw cL(r=lun(r),109)?Hp(new Ay("Can't remove element "+t)):Hp(r)}}function ekn(n,t){var e,i,r;if(0==(e=DBn(n,t,r=new von((i=new AT).q.getFullYear()-sQn,i.q.getMonth(),i.q.getDate())))||e<t.length)throw Hp(new Ky(t));return r}function ikn(n,t){var e,i,r;for(kW(t),Tx(t!=n),r=n.b.c.length,i=t.Kc();i.Ob();)e=i.Pb(),WB(n.b,kW(e));return r!=n.b.c.length&&(Esn(n,0),!0)}function rkn(){rkn=O,sWn(),kat=ISt,new XA(dSt,(hN(),!0)),Tat=_St,Mat=BSt,Sat=qSt,Eat=DSt,Pat=USt,Iat=fPt,_yn(),yat=dat,vat=lat,mat=wat,jat=gat,pat=fat}function ckn(n,t){if(t==n.c)return n.d;if(t==n.d)return n.c;throw Hp(new Ky("'port' must be either the source port or target port of the edge."))}function akn(n,t,e){var i,r;switch(r=n.o,i=n.d,t.g){case 1:return-i.d-e;case 3:return r.b+i.a+e;case 2:return r.a+i.c+e;case 4:return-i.b-e;default:return 0}}function ukn(n,t,e,i){var r,c,a;for(PZ(t,BB(i.Xb(0),29)),a=i.bd(1,i.gc()),c=BB(e.Kb(t),20).Kc();c.Ob();)ukn(n,(r=BB(c.Pb(),17)).c.i==t?r.d.i:r.c.i,e,a)}function okn(n){var t;return t=new xp,Lx(n,(hWn(),Dlt))?BB(mMn(n,Dlt),83):(JT(AV(new Rq(null,new w1(n.j,16)),new tr),new gd(t)),hon(n,Dlt,t),t)}function skn(n,t){var e;return n.Db>>16==6?n.Cb.ih(n,6,KOt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(IXn(),yOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function hkn(n,t){var e;return n.Db>>16==7?n.Cb.ih(n,1,DOt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(IXn(),jOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function fkn(n,t){var e;return n.Db>>16==9?n.Cb.ih(n,9,UOt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(IXn(),TOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function lkn(n,t){var e;return n.Db>>16==5?n.Cb.ih(n,9,XAt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(gWn(),s$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function bkn(n,t){var e;return n.Db>>16==3?n.Cb.ih(n,0,BOt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(gWn(),e$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function wkn(n,t){var e;return n.Db>>16==7?n.Cb.ih(n,6,GOt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(gWn(),v$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function dkn(){this.a=new lo,this.g=new Avn,this.j=new Avn,this.b=new xp,this.d=new Avn,this.i=new Avn,this.k=new xp,this.c=new xp,this.e=new xp,this.f=new xp}function gkn(n,t,e){var i,r,c;for(e<0&&(e=0),c=n.i,r=e;r<c;r++)if(i=Wtn(n,r),null==t){if(null==i)return r}else if(GC(t)===GC(i)||Nfn(t,i))return r;return-1}function pkn(n,t){var e,i;return(e=t.Hh(n.a))?(i=SD(cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),j7n)),m_(E7n,i)?az(n,Utn(t.Hj())):i):null}function vkn(n,t){var e,i;if(t){if(t==n)return!0;for(e=0,i=BB(t,49).eh();i&&i!=t;i=i.eh()){if(++e>GQn)return vkn(n,i);if(i==n)return!0}}return!1}function mkn(n){switch(DN(),n.q.g){case 5:vCn(n,(kUn(),sCt)),vCn(n,SCt);break;case 4:z$n(n,(kUn(),sCt)),z$n(n,SCt);break;default:vUn(n,(kUn(),sCt)),vUn(n,SCt)}}function ykn(n){switch(DN(),n.q.g){case 5:SOn(n,(kUn(),oCt)),SOn(n,ICt);break;case 4:Ipn(n,(kUn(),oCt)),Ipn(n,ICt);break;default:mUn(n,(kUn(),oCt)),mUn(n,ICt)}}function kkn(n){var t,e;(t=BB(mMn(n,(fRn(),nat)),19))?(e=t.a,hon(n,(Mrn(),hat),0==e?new sbn:new I4(e))):hon(n,(Mrn(),hat),new I4(1))}function jkn(n,t){var e;switch(e=n.i,t.g){case 1:return-(n.n.b+n.o.b);case 2:return n.n.a-e.o.a;case 3:return n.n.b-e.o.b;case 4:return-(n.n.a+n.o.a)}return 0}function Ekn(n,t){switch(n.g){case 0:return t==(Tbn(),Flt)?rst:cst;case 1:return t==(Tbn(),Flt)?rst:ist;case 2:return t==(Tbn(),Flt)?ist:cst;default:return ist}}function Tkn(n,t){var i,r,c;for(y7(n.a,t),n.e-=t.r+(0==n.a.c.length?0:n.c),c=n4n,r=new Wb(n.a);r.a<r.c.c.length;)i=BB(n0(r),187),c=e.Math.max(c,i.d);n.b=c}function Mkn(n,t){var e;return n.Db>>16==3?n.Cb.ih(n,12,UOt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(IXn(),mOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Skn(n,t){var e;return n.Db>>16==11?n.Cb.ih(n,10,UOt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(IXn(),EOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Pkn(n,t){var e;return n.Db>>16==10?n.Cb.ih(n,11,qAt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(gWn(),g$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Ikn(n,t){var e;return n.Db>>16==10?n.Cb.ih(n,12,QAt,t):(e=Ivn(BB(itn(BB(yan(n,16),26)||(gWn(),m$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Ckn(n){var t;return 0==(1&n.Bb)&&n.r&&n.r.kh()&&(t=BB(n.r,49),n.r=BB(tfn(n,t),138),n.r!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,9,8,t,n.r))),n.r}function Okn(n,t,i){var r;return r=Pun(Gk(xNt,1),qQn,25,15,[iMn(n,(Dtn(),Git),t,i),iMn(n,zit,t,i),iMn(n,Uit,t,i)]),n.f&&(r[0]=e.Math.max(r[0],r[2]),r[2]=r[0]),r}function Akn(n,t){var e,i,r;if(0!=(r=Yvn(n,t)).c.length)for(m$(r,new ti),e=r.c.length,i=0;i<e;i++)hPn(n,(l1(i,r.c.length),BB(r.c[i],286)),TDn(n,r,i))}function $kn(n){var t,e,i;for(i=BB(h6(n.a,(LEn(),Tst)),15).Kc();i.Ob();)for(t=gz((e=BB(i.Pb(),101)).k).Kc();t.Ob();)iX(n,e,BB(t.Pb(),61),(Irn(),Dst),1)}function Lkn(n){var t,e;if(n.k==(uSn(),Put))for(e=new oz(ZL(hbn(n).a.Kc(),new h));dAn(e);)if(!b5(t=BB(U5(e),17))&&n.c==Ajn(t,n).c)return!0;return!1}function Nkn(n){var t,e;if(n.k==(uSn(),Put))for(e=new oz(ZL(hbn(n).a.Kc(),new h));dAn(e);)if(!b5(t=BB(U5(e),17))&&t.c.i.c==t.d.i.c)return!0;return!1}function xkn(n,t){var e,i;for(OTn(t,"Dull edge routing",1),i=spn(n.b,0);i.b!=i.d.c;)for(e=spn(BB(b3(i),86).d,0);e.b!=e.d.c;)yQ(BB(b3(e),188).a)}function Dkn(n,t){var e,i,r;if(t)for(r=((e=new hz(t.a.length)).b-e.a)*e.c<0?(eS(),MNt):new XL(e);r.Ob();)(i=x2(t,BB(r.Pb(),19).a))&&O$n(n,i)}function Rkn(){var n;for(tS(),nWn((QX(),t$t)),KXn(t$t),Tyn(t$t),gWn(),L$t=l$t,n=new Wb(V$t);n.a<n.c.c.length;)azn(BB(n0(n),241),l$t,null);return!0}function _kn(n,t){var e,i,r,c,a,u;return(a=n.h>>19)!=(u=t.h>>19)?u-a:(i=n.h)!=(c=t.h)?i-c:(e=n.m)!=(r=t.m)?e-r:n.l-t.l}function Kkn(){Kkn=O,tRn(),Pit=new $O(UYn,Iit=xit),Rnn(),Mit=new $O(XYn,Sit=mit),hpn(),Eit=new $O(WYn,Tit=dit),jit=new $O(VYn,(hN(),!0))}function Fkn(n,t,e){var i,r;i=t*e,cL(n.g,145)?(r=f3(n)).f.d?r.f.a||(n.d.a+=i+fJn):(n.d.d-=i+fJn,n.d.a+=i+fJn):cL(n.g,10)&&(n.d.d-=i,n.d.a+=2*i)}function Bkn(n,t,i){var r,c,a,u,o;for(c=n[i.g],o=new Wb(t.d);o.a<o.c.c.length;)(a=(u=BB(n0(o),101)).i)&&a.i==i&&(c[r=u.d[i.g]]=e.Math.max(c[r],a.j.b))}function Hkn(n,t){var i,r,c,a,u;for(r=0,c=0,i=0,u=new Wb(t.d);u.a<u.c.c.length;)Gmn(a=BB(n0(u),443)),r=e.Math.max(r,a.b),c+=a.d+(i>0?n.g:0),++i;t.b=r,t.e=c}function qkn(n){var t,e,i;if(i=n.b,qT(n.i,i.length)){for(e=2*i.length,n.b=x8(Gnt,IVn,317,e,0,1),n.c=x8(Gnt,IVn,317,e,0,1),n.f=e-1,n.i=0,t=n.a;t;t=t.c)YIn(n,t,t);++n.g}}function Gkn(n,t,e,i){var r,c,a,u;for(r=0;r<t.o;r++)for(c=r-t.j+e,a=0;a<t.p;a++)u=a-t.k+i,vmn(t,r,a)?cmn(n,c,u)||Xmn(n,c,u):ymn(t,r,a)&&(imn(n,c,u)||Wmn(n,c,u))}function zkn(n,t,e){var i;(i=t.c.i).k==(uSn(),Put)?(hon(n,(hWn(),hlt),BB(mMn(i,hlt),11)),hon(n,flt,BB(mMn(i,flt),11))):(hon(n,(hWn(),hlt),t.c),hon(n,flt,e.d))}function Ukn(n,t,i){var r,c,a,u,o,s;return jDn(),u=t/2,a=i/2,o=1,s=1,(r=e.Math.abs(n.a))>u&&(o=u/r),(c=e.Math.abs(n.b))>a&&(s=a/c),kL(n,e.Math.min(o,s)),n}function Xkn(){var n,t;qBn();try{if(t=BB(Xjn((WM(),zAt),y6n),2014))return t}catch(e){if(!cL(e=lun(e),102))throw Hp(e);n=e,uz((u$(),n))}return new ao}function Wkn(){var n,t;d7();try{if(t=BB(Xjn((WM(),zAt),S7n),2024))return t}catch(e){if(!cL(e=lun(e),102))throw Hp(e);n=e,uz((u$(),n))}return new Ds}function Vkn(){var n,t;qBn();try{if(t=BB(Xjn((WM(),zAt),V9n),1941))return t}catch(e){if(!cL(e=lun(e),102))throw Hp(e);n=e,uz((u$(),n))}return new qo}function Qkn(n,t,e){var i,r;return r=n.e,n.e=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new nU(n,1,4,r,t),e?e.Ei(i):e=i),r!=t&&(e=azn(n,t?kLn(n,t):n.a,e)),e}function Ykn(){AT.call(this),this.e=-1,this.a=!1,this.p=KVn,this.k=-1,this.c=-1,this.b=-1,this.g=!1,this.f=-1,this.j=-1,this.n=-1,this.i=-1,this.d=-1,this.o=KVn}function Jkn(n,t){var e,i,r;if(i=n.b.d.d,n.a||(i+=n.b.d.a),r=t.b.d.d,t.a||(r+=t.b.d.a),0==(e=Pln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function Zkn(n,t){var e,i,r;if(i=n.b.b.d,n.a||(i+=n.b.b.a),r=t.b.b.d,t.a||(r+=t.b.b.a),0==(e=Pln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function njn(n,t){var e,i,r;if(i=n.b.g.d,n.a||(i+=n.b.g.a),r=t.b.g.d,t.a||(r+=t.b.g.a),0==(e=Pln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function tjn(){tjn=O,Nat=WG(dq(dq(dq(new B2,(yMn(),Fat),(lWn(),yot)),Fat,Tot),Bat,Aot),Bat,oot),Dat=dq(dq(new B2,Fat,Jut),Fat,sot),xat=WG(new B2,Bat,fot)}function ejn(n){var t,e,i,r,c;for(t=BB(mMn(n,(hWn(),zft)),83),c=n.n,i=t.Cc().Kc();i.Ob();)(r=(e=BB(i.Pb(),306)).i).c+=c.a,r.d+=c.b,e.c?NDn(e):xDn(e);hon(n,zft,null)}function ijn(n,t,e){var i,r;switch(i=(r=n.b).d,t.g){case 1:return-i.d-e;case 2:return r.o.a+i.c+e;case 3:return r.o.b+i.a+e;case 4:return-i.b-e;default:return-1}}function rjn(n){var t,e,i,r,c;if(i=0,r=ZJn,n.b)for(t=0;t<360;t++)e=.017453292519943295*t,U_n(n,n.d,0,0,Z3n,e),(c=n.b.ig(n.d))<r&&(i=e,r=c);U_n(n,n.d,0,0,Z3n,i)}function cjn(n,t){var e,i,r,c;for(c=new xp,t.e=null,t.f=null,i=new Wb(t.i);i.a<i.c.c.length;)e=BB(n0(i),65),r=BB(RX(n.g,e.a),46),e.a=qz(e.b),VW(c,e.a,r);n.g=c}function ajn(n,t,e){var i,r,c,a,u;for(r=(t-n.e)/n.d.c.length,c=0,u=new Wb(n.d);u.a<u.c.c.length;)a=BB(n0(u),443),i=n.b-a.b+e,kdn(a,a.e+c*r,a.f),hmn(a,r,i),++c}function ujn(n){var t;if(n.f.qj(),-1!=n.b){if(++n.b,t=n.f.d[n.a],n.b<t.i)return;++n.a}for(;n.a<n.f.d.length;++n.a)if((t=n.f.d[n.a])&&0!=t.i)return void(n.b=0);n.b=-1}function ojn(n,t){var e,i,r;for(e=$In(n,0==(r=t.c.length)?"":(l1(0,t.c.length),SD(t.c[0]))),i=1;i<r&&e;++i)e=BB(e,49).oh((l1(i,t.c.length),SD(t.c[i])));return e}function sjn(n,t){var e,i;for(i=new Wb(t);i.a<i.c.c.length;)e=BB(n0(i),10),n.c[e.c.p][e.p].a=OG(n.i),n.c[e.c.p][e.p].d=Gy(n.c[e.c.p][e.p].a),n.c[e.c.p][e.p].b=1}function hjn(n,t){var i,r,c;for(c=0,r=new Wb(n);r.a<r.c.c.length;)i=BB(n0(r),157),c+=e.Math.pow(iG(i)*eG(i)-t,2);return e.Math.sqrt(c/(n.c.length-1))}function fjn(n,t,e,i){var r,c,a;return a=NRn(n,c=qRn(n,t,e,i)),fMn(n,t,e,i),_9(n.b),SQ(),m$(c,new Qd(n)),r=NRn(n,c),fMn(n,e,t,i),_9(n.b),new rC(iln(a),iln(r))}function ljn(n,t,e){var i;for(OTn(e,"Interactive node placement",1),n.a=BB(mMn(t,(hWn(),Alt)),304),i=new Wb(t.b);i.a<i.c.c.length;)nDn(n,BB(n0(i),29));HSn(e)}function bjn(n,t){OTn(t,"General Compactor",1),t.n&&n&&y0(t,o2(n),(Bsn(),uOt)),dwn(BB(ZAn(n,(Uyn(),Sjt)),380)).hg(n),t.n&&n&&y0(t,o2(n),(Bsn(),uOt))}function wjn(n,t,e){var i,r;for(IA(n,n.j+t,n.k+e),r=new AL((!n.a&&(n.a=new $L(xOt,n,5)),n.a));r.e!=r.i.gc();)TA(i=BB(kpn(r),469),i.a+t,i.b+e);PA(n,n.b+t,n.c+e)}function djn(n,t,e,i){switch(e){case 7:return!n.e&&(n.e=new h_(KOt,n,7,4)),Ywn(n.e,t,i);case 8:return!n.d&&(n.d=new h_(KOt,n,8,5)),Ywn(n.d,t,i)}return FTn(n,t,e,i)}function gjn(n,t,e,i){switch(e){case 7:return!n.e&&(n.e=new h_(KOt,n,7,4)),Kpn(n.e,t,i);case 8:return!n.d&&(n.d=new h_(KOt,n,8,5)),Kpn(n.d,t,i)}return run(n,t,e,i)}function pjn(n,t,e){var i,r,c;if(e)for(c=((i=new hz(e.a.length)).b-i.a)*i.c<0?(eS(),MNt):new XL(i);c.Ob();)(r=x2(e,BB(c.Pb(),19).a))&&bCn(n,r,t)}function vjn(n,t,e){var i,r,c;return n.qj(),c=null==t?0:nsn(t),n.f>0&&(r=aOn(n,(c&DWn)%n.d.length,c,t))?r.ed(e):(i=n.tj(c,t,e),n.c.Fc(i),null)}function mjn(n,t){var e,i,r,c;switch(Ifn(n,t)._k()){case 3:case 2:for(r=0,c=(e=YBn(t)).i;r<c;++r)if(5==DW(B7(n,i=BB(Wtn(e,r),34))))return i}return null}function yjn(n){var t,e,i,r,c;if(qT(n.f,n.b.length))for(i=x8(Qnt,IVn,330,2*n.b.length,0,1),n.b=i,r=i.length-1,e=n.a;e!=n;e=e.Rd())t=(c=BB(e,330)).d&r,c.a=i[t],i[t]=c}function kjn(n,t){var i,r,c,a;for(a=0,c=BB(BB(h6(n.r,t),21),84).Kc();c.Ob();)r=BB(c.Pb(),111),a=e.Math.max(a,r.e.a+r.b.rf().a);(i=BB(oV(n.b,t),124)).n.b=0,i.a.a=a}function jjn(n,t){var i,r,c,a;for(i=0,a=BB(BB(h6(n.r,t),21),84).Kc();a.Ob();)c=BB(a.Pb(),111),i=e.Math.max(i,c.e.b+c.b.rf().b);(r=BB(oV(n.b,t),124)).n.d=0,r.a.b=i}function Ejn(n){var t,e;return e=BB(mMn(n,(hWn(),Zft)),21),t=kA(vyt),e.Hc((bDn(),gft))&&Jcn(t,kyt),e.Hc(vft)&&Jcn(t,Eyt),e.Hc(sft)&&Jcn(t,myt),e.Hc(fft)&&Jcn(t,yyt),t}function Tjn(n,t){var e;OTn(t,"Delaunay triangulation",1),e=new Np,Otn(n.i,new yg(e)),qy(TD(mMn(n,(Xcn(),Qrt)))),n.e?Frn(n.e,$Xn(e)):n.e=$Xn(e),HSn(t)}function Mjn(n){if(n<0)throw Hp(new Ky("The input must be positive"));return n<MMt.length?j2(MMt[n]):e.Math.sqrt(Z3n*n)*(ifn(n,n)/efn(2.718281828459045,n))}function Sjn(n,t){var e;if(n.ni()&&null!=t){for(e=0;e<n.i;++e)if(Nfn(t,n.g[e]))return!0}else for(e=0;e<n.i;++e)if(GC(n.g[e])===GC(t))return!0;return!1}function Pjn(n,t){if(null==t){for(;n.a.Ob();)if(null==BB(n.a.Pb(),42).dd())return!0}else for(;n.a.Ob();)if(Nfn(t,BB(n.a.Pb(),42).dd()))return!0;return!1}function Ijn(n,t){var e;return t===n||!!cL(t,664)&&(e=BB(t,1947),ign(n.g||(n.g=new Zf(n)),e.g||(e.g=new Zf(e))))}function Cjn(n){var t,i,r;for(t="Sz",i="ez",r=e.Math.min(n.length,5)-1;r>=0;r--)if(m_(n[r].d,t)||m_(n[r].d,i)){n.length>=r+1&&n.splice(0,r+1);break}return n}function Ojn(n,t){var i;return JO(n)&&JO(t)&&$Qn<(i=n/t)&&i<OQn?i<0?e.Math.ceil(i):e.Math.floor(i):uan(Aqn(JO(n)?Pan(n):n,JO(t)?Pan(t):t,!1))}function Ajn(n,t){if(t==n.c.i)return n.d.i;if(t==n.d.i)return n.c.i;throw Hp(new Ky("'node' must either be the source node or target node of the edge."))}function $jn(n){var t,e,i,r;if(r=BB(mMn(n,(hWn(),Fft)),37)){for(i=new Gj,t=vW(n.c.i);t!=r;)t=vW(e=t.e),Kx(UR(UR(i,e.n),t.c),t.d.b,t.d.d);return i}return Fut}function Ljn(n){var t;JT(wnn(new Rq(null,new w1((t=BB(mMn(n,(hWn(),Olt)),403)).d,16)),new Ki),new wd(n)),JT(AV(new Rq(null,new w1(t.d,16)),new Fi),new dd(n))}function Njn(n,t){var e,i;for(e=new oz(ZL((t?lbn(n):fbn(n)).a.Kc(),new h));dAn(e);)if((i=Ajn(BB(U5(e),17),n)).k==(uSn(),Put)&&i.c!=n.c)return i;return null}function xjn(n){var t,i,r;for(i=new Wb(n.p);i.a<i.c.c.length;)(t=BB(n0(i),10)).k==(uSn(),Iut)&&(r=t.o.b,n.i=e.Math.min(n.i,r),n.g=e.Math.max(n.g,r))}function Djn(n,t,e){var i,r,c;for(c=new Wb(t);c.a<c.c.c.length;)i=BB(n0(c),10),n.c[i.c.p][i.p].e=!1;for(r=new Wb(t);r.a<r.c.c.length;)xzn(n,i=BB(n0(r),10),e)}function Rjn(n,t,i){var r,c;(r=Tfn(t.j,i.s,i.c)+Tfn(i.e,t.s,t.c))==(c=Tfn(i.j,t.s,t.c)+Tfn(t.e,i.s,i.c))?r>0&&(n.b+=2,n.a+=r):(n.b+=1,n.a+=e.Math.min(r,c))}function _jn(n,t){var e;if(e=!1,XC(t)&&(e=!0,nW(n,new GX(SD(t)))),e||cL(t,236)&&(e=!0,nW(n,new Sl(X_(BB(t,236))))),!e)throw Hp(new Ly(H6n))}function Kjn(n,t,e,i){var r,c,a;return r=new N7(n.e,1,10,cL(a=t.c,88)?BB(a,26):(gWn(),d$t),cL(c=e.c,88)?BB(c,26):(gWn(),d$t),uvn(n,t),!1),i?i.Ei(r):i=r,i}function Fjn(n){var t,e;switch(BB(mMn(vW(n),(HXn(),pgt)),420).g){case 0:return t=n.n,e=n.o,new xI(t.a+e.a/2,t.b+e.b/2);case 1:return new wA(n.n);default:return null}}function Bjn(){Bjn=O,Qht=new AP(QZn,0),Vht=new AP("LEFTUP",1),Jht=new AP("RIGHTUP",2),Wht=new AP("LEFTDOWN",3),Yht=new AP("RIGHTDOWN",4),Xht=new AP("BALANCED",5)}function Hjn(n,t,e){var i,r,c;if(0==(i=Pln(n.a[t.p],n.a[e.p]))){if(r=BB(mMn(t,(hWn(),clt)),15),c=BB(mMn(e,clt),15),r.Hc(e))return-1;if(c.Hc(t))return 1}return i}function qjn(n){switch(n.g){case 1:return new Ka;case 2:return new Fa;case 3:return new _a;case 0:return null;default:throw Hp(new Ky(c4n+(null!=n.f?n.f:""+n.g)))}}function Gjn(n,t,e){switch(t){case 1:return!n.n&&(n.n=new eU(zOt,n,1,7)),sqn(n.n),!n.n&&(n.n=new eU(zOt,n,1,7)),void pX(n.n,BB(e,14));case 2:return void $in(n,SD(e))}rsn(n,t,e)}function zjn(n,t,e){switch(t){case 3:return void Men(n,Gy(MD(e)));case 4:return void Sen(n,Gy(MD(e)));case 5:return void Pen(n,Gy(MD(e)));case 6:return void Ien(n,Gy(MD(e)))}Gjn(n,t,e)}function Ujn(n,t,e){var i,r;(i=HTn(r=new Lm,t,null))&&i.Fi(),Nrn(r,e),f9((!n.c&&(n.c=new eU(YAt,n,12,10)),n.c),r),Len(r,0),Nen(r,1),nln(r,!0),Yfn(r,!0)}function Xjn(n,t){var e,i;return cL(e=hS(n.g,t),235)?((i=BB(e,235)).Qh(),i.Nh()):cL(e,498)?i=BB(e,1938).b:null}function Wjn(n,t,e,i){var r,c;return yX(t),yX(e),R7(!!(c=BB(U_(n.d,t),19)),"Row %s not in %s",t,n.e),R7(!!(r=BB(U_(n.b,e),19)),"Column %s not in %s",e,n.c),Sun(n,c.a,r.a,i)}function Vjn(n,t,e,i,r,c,a){var u,o,s,h,f;if(f=Bmn(u=(s=c==a-1)?i:0,h=r[c]),10!=i&&Pun(Gk(n,a-c),t[c],e[c],u,f),!s)for(++c,o=0;o<h;++o)f[o]=Vjn(n,t,e,i,r,c,a);return f}function Qjn(n){if(-1==n.g)throw Hp(new dv);n.mj();try{n.i.$c(n.g),n.f=n.i.j,n.g<n.e&&--n.e,n.g=-1}catch(t){throw cL(t=lun(t),73)?Hp(new vv):Hp(t)}}function Yjn(n,t){return n.b.a=e.Math.min(n.b.a,t.c),n.b.b=e.Math.min(n.b.b,t.d),n.a.a=e.Math.max(n.a.a,t.c),n.a.b=e.Math.max(n.a.b,t.d),n.c[n.c.length]=t,!0}function Jjn(n){var t,e,i;for(i=-1,e=0,t=new Wb(n);t.a<t.c.c.length;){if(BB(n0(t),243).c==(ain(),Hvt)){i=0==e?0:e-1;break}e==n.c.length-1&&(i=e),e+=1}return i}function Zjn(n){var t,i,r,c;for(c=0,t=0,r=new Wb(n.c);r.a<r.c.c.length;)Pen(i=BB(n0(r),33),n.e+c),Ien(i,n.f),c+=i.g+n.b,t=e.Math.max(t,i.f+n.b);n.d=c-n.b,n.a=t-n.b}function nEn(n){var t,e,i;for(e=new Wb(n.a.b);e.a<e.c.c.length;)i=(t=BB(n0(e),57)).d.c,t.d.c=t.d.d,t.d.d=i,i=t.d.b,t.d.b=t.d.a,t.d.a=i,i=t.b.a,t.b.a=t.b.b,t.b.b=i;yNn(n)}function tEn(n){var t,e,i;for(e=new Wb(n.a.b);e.a<e.c.c.length;)i=(t=BB(n0(e),81)).g.c,t.g.c=t.g.d,t.g.d=i,i=t.g.b,t.g.b=t.g.a,t.g.a=i,i=t.e.a,t.e.a=t.e.b,t.e.b=i;kNn(n)}function eEn(n){var t,e,i,r,c;for(c=gz(n.k),kUn(),i=0,r=(e=Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])).length;i<r;++i)if((t=e[i])!=PCt&&!c.Hc(t))return t;return null}function iEn(n,t){var e,i;return(i=BB(EN(Qon(AV(new Rq(null,new w1(t.j,16)),new bc))),11))&&(e=BB(xq(i.e,0),17))?BB(mMn(e,(hWn(),wlt)),19).a:gnn(n.b)}function rEn(n,t){var e,i,r;for(r=new Wb(t.a);r.a<r.c.c.length;)for(i=BB(n0(r),10),nk(n.d),e=new oz(ZL(lbn(i).a.Kc(),new h));dAn(e);)XOn(n,i,BB(U5(e),17).d.i)}function cEn(n,t){var e,i;for(y7(n.b,t),i=new Wb(n.n);i.a<i.c.c.length;)if(-1!=E7((e=BB(n0(i),211)).c,t,0)){y7(e.c,t),Zjn(e),0==e.c.c.length&&y7(n.n,e);break}fHn(n)}function aEn(n,t){var i,r,c,a,u;for(u=n.f,c=0,a=0,r=new Wb(n.a);r.a<r.c.c.length;)Tvn(i=BB(n0(r),187),n.e,u),p9(i,t),a=e.Math.max(a,i.r),c=u+=i.d+n.c;n.d=a,n.b=c}function uEn(n){var t,e;return h3(e=wLn(n))?null:(yX(e),t=BB(emn(new oz(ZL(e.a.Kc(),new h))),79),PTn(BB(Wtn((!t.b&&(t.b=new h_(_Ot,t,4,7)),t.b),0),82)))}function oEn(n){return n.o||(n.Lj()?n.o=new aW(n,n,null):n.rk()?n.o=new rR(n,null):1==DW(B7((CPn(),Z$t),n))?n.o=new g4(n):n.o=new cR(n,null)),n.o}function sEn(n,t,e,i){var r,c,a,u,o;e.mh(t)&&(r=(a=t)?BB(i,49).xh(a):null)&&(o=e.ah(t),(u=t.t)>1||-1==u?(c=BB(o,15),r.Wb(Xdn(n,c))):r.Wb(tKn(n,BB(o,56))))}function hEn(n,t,e,i){YE();var r=PWn;function c(){for(var n=0;n<r.length;n++)r[n]()}if(n)try{HNt(c)()}catch(a){n(t,a)}else HNt(c)()}function fEn(n){var t,e,i,r,c;for(i=new usn(new Pb(n.b).a);i.b;)t=BB((e=ten(i)).cd(),10),c=BB(BB(e.dd(),46).a,10),r=BB(BB(e.dd(),46).b,8),UR(kO(t.n),UR(B$(c.n),r))}function lEn(n){switch(BB(mMn(n.b,(HXn(),egt)),375).g){case 1:JT($V(wnn(new Rq(null,new w1(n.d,16)),new Kr),new Fr),new Br);break;case 2:vRn(n);break;case 0:IIn(n)}}function bEn(n,t,e){OTn(e,"Straight Line Edge Routing",1),e.n&&t&&y0(e,o2(t),(Bsn(),uOt)),mHn(n,BB(ZAn(t,(wD(),Vkt)),33)),e.n&&t&&y0(e,o2(t),(Bsn(),uOt))}function wEn(){wEn=O,ZMt=new RI("V_TOP",0),JMt=new RI("V_CENTER",1),YMt=new RI("V_BOTTOM",2),VMt=new RI("H_LEFT",3),WMt=new RI("H_CENTER",4),QMt=new RI("H_RIGHT",5)}function dEn(n){var t;return 0!=(64&n.Db)?Iwn(n):((t=new fN(Iwn(n))).a+=" (abstract: ",yE(t,0!=(256&n.Bb)),t.a+=", interface: ",yE(t,0!=(512&n.Bb)),t.a+=")",t.a)}function gEn(n,t,e,i){var r,c,a;return mA(n.e)&&(a=LY(n,1,r=t.ak(),t.dd(),c=e.dd(),r.$j()?pBn(n,r,c,cL(r,99)&&0!=(BB(r,18).Bb&BQn)):-1,!0),i?i.Ei(a):i=a),i}function pEn(n){var t;null==n.c&&(t=GC(n.b)===GC(Ynt)?null:n.b,n.d=null==t?zWn:ez(t)?jN(EQ(t)):XC(t)?qVn:nE(tsn(t)),n.a=n.a+": "+(ez(t)?IR(EQ(t)):t+""),n.c="("+n.d+") "+n.a)}function vEn(n,t){this.e=n,QC(e0(t,-4294967296),0)?(this.d=1,this.a=Pun(Gk(ANt,1),hQn,25,15,[dG(t)])):(this.d=2,this.a=Pun(Gk(ANt,1),hQn,25,15,[dG(t),dG(kz(t,32))]))}function mEn(){function n(){try{return(new Map).entries().next().done}catch(n){return!1}}return typeof Map===xWn&&Map.prototype.entries&&n()?Map:bUn()}function yEn(n,t){var e,i,r;for(r=new M2(n.e,0),e=0;r.b<r.d.gc();){if((i=Gy((Px(r.b<r.d.gc()),MD(r.d.Xb(r.c=r.b++))))-t)>D3n)return e;i>-1e-6&&++e}return e}function kEn(n,t){var e;t!=n.b?(e=null,n.b&&(e=oJ(n.b,n,-4,e)),t&&(e=Npn(t,n,-4,e)),(e=Zhn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,3,t,t))}function jEn(n,t){var e;t!=n.f?(e=null,n.f&&(e=oJ(n.f,n,-1,e)),t&&(e=Npn(t,n,-1,e)),(e=nfn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,0,t,t))}function EEn(n){var t,e,i;if(null==n)return null;if((e=BB(n,15)).dc())return"";for(i=new Sk,t=e.Kc();t.Ob();)cO(i,(Uqn(),SD(t.Pb()))),i.a+=" ";return _O(i,i.a.length-1)}function TEn(n){var t,e,i;if(null==n)return null;if((e=BB(n,15)).dc())return"";for(i=new Sk,t=e.Kc();t.Ob();)cO(i,(Uqn(),SD(t.Pb()))),i.a+=" ";return _O(i,i.a.length-1)}function MEn(n,t,e){var i,r;return i=n.c[t.c.p][t.p],r=n.c[e.c.p][e.p],null!=i.a&&null!=r.a?Tz(i.a,r.a):null!=i.a?-1:null!=r.a?1:0}function SEn(n,t){var e,i,r;if(t)for(r=((e=new hz(t.a.length)).b-e.a)*e.c<0?(eS(),MNt):new XL(e);r.Ob();)i=x2(t,BB(r.Pb(),19).a),OV(new Bg(n).a,i)}function PEn(n,t){var e,i,r;if(t)for(r=((e=new hz(t.a.length)).b-e.a)*e.c<0?(eS(),MNt):new XL(e);r.Ob();)i=x2(t,BB(r.Pb(),19).a),CV(new $g(n).a,i)}function IEn(n){if(null!=n&&n.length>0&&33==fV(n,n.length-1))try{return null==YPn(fx(n,0,n.length-1)).e}catch(t){if(!cL(t=lun(t),32))throw Hp(t)}return!1}function CEn(n,t,e){var i,r,c;return i=t.ak(),c=t.dd(),r=i.$j()?LY(n,3,i,null,c,pBn(n,i,c,cL(i,99)&&0!=(BB(i,18).Bb&BQn)),!0):LY(n,1,i,i.zj(),c,-1,!0),e?e.Ei(r):e=r,e}function OEn(){var n,t,e;for(t=0,n=0;n<1;n++){if(0==(e=QOn((b1(n,1),"X".charCodeAt(n)))))throw Hp(new ak("Unknown Option: "+"X".substr(n)));t|=e}return t}function AEn(n,t,e){var i,r;switch(i=Wln(vW(t)),IZ(r=new ISn,t),e.g){case 1:qIn(r,Tln(hwn(i)));break;case 2:qIn(r,hwn(i))}return hon(r,(HXn(),tpt),MD(mMn(n,tpt))),r}function $En(n){var t,e;return t=BB(U5(new oz(ZL(fbn(n.a).a.Kc(),new h))),17),e=BB(U5(new oz(ZL(lbn(n.a).a.Kc(),new h))),17),qy(TD(mMn(t,(hWn(),Ilt))))||qy(TD(mMn(e,Ilt)))}function LEn(){LEn=O,Mst=new yP("ONE_SIDE",0),Pst=new yP("TWO_SIDES_CORNER",1),Ist=new yP("TWO_SIDES_OPPOSING",2),Sst=new yP("THREE_SIDES",3),Tst=new yP("FOUR_SIDES",4)}function NEn(n,t,e,i,r){var c,a;c=BB(P4(AV(t.Oc(),new Zr),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15),a=BB(gan(n.b,e,i),15),0==r?a.Wc(0,c):a.Gc(c)}function xEn(n,t){var e,i,r;for(i=new Wb(t.a);i.a<i.c.c.length;)for(e=new oz(ZL(fbn(BB(n0(i),10)).a.Kc(),new h));dAn(e);)r=BB(U5(e),17).c.i.p,n.n[r]=n.n[r]-1}function DEn(n,t){var e,i,r,c;for(r=new Wb(t.d);r.a<r.c.c.length;)for(i=BB(n0(r),101),c=BB(RX(n.c,i),112).o,e=new QT(i.b);e.a<e.c.a.length;)g9(i,BB(u4(e),61),c)}function REn(n){var t;for(t=new Wb(n.e.b);t.a<t.c.c.length;)hzn(n,BB(n0(t),29));JT(AV(wnn(wnn(new Rq(null,new w1(n.e.b,16)),new Xc),new Zc),new na),new hg(n))}function _En(n,t){return!!t&&!n.Di(t)&&(n.i?n.i.Ei(t):cL(t,143)?(n.i=BB(t,143),!0):(n.i=new po,n.i.Ei(t)))}function KEn(n){if(n=FBn(n,!0),m_(a5n,n)||m_("1",n))return hN(),vtt;if(m_(u5n,n)||m_("0",n))return hN(),ptt;throw Hp(new ik("Invalid boolean value: '"+n+"'"))}function FEn(n,t,e){var i,r,c;for(r=n.vc().Kc();r.Ob();)if(c=(i=BB(r.Pb(),42)).cd(),GC(t)===GC(c)||null!=t&&Nfn(t,c))return e&&(i=new PS(i.cd(),i.dd()),r.Qb()),i;return null}function BEn(n){var t,e,i;qD(),n.B.Hc((nKn(),qCt))&&(i=n.f.i,t=new gY(n.a.c),(e=new bm).b=t.c-i.c,e.d=t.d-i.d,e.c=i.c+i.b-(t.c+t.b),e.a=i.d+i.a-(t.d+t.a),n.e.Ff(e))}function HEn(n,t,i,r){var c,a,u;for(u=e.Math.min(i,WFn(BB(n.b,65),t,i,r)),a=new Wb(n.a);a.a<a.c.c.length;)(c=BB(n0(a),221))!=t&&(u=e.Math.min(u,HEn(c,t,u,r)));return u}function qEn(n){var t,e,i;for(i=x8(Out,sVn,193,n.b.c.length,0,2),e=new M2(n.b,0);e.b<e.d.gc();)Px(e.b<e.d.gc()),t=BB(e.d.Xb(e.c=e.b++),29),i[e.b-1]=n2(t.a);return i}function GEn(n,t,e,i,r){var c,a,u,o;for(a=nj(Zk(HK(tvn(e)),i),akn(n,e,r)),o=DSn(n,e).Kc();o.Ob();)t[(u=BB(o.Pb(),11)).p]&&(c=t[u.p].i,WB(a.d,new xG(c,kln(a,c))));Pwn(a)}function zEn(n,t){this.f=new xp,this.b=new xp,this.j=new xp,this.a=n,this.c=t,this.c>0&&Kyn(this,this.c-1,(kUn(),oCt)),this.c<this.a.length-1&&Kyn(this,this.c+1,(kUn(),ICt))}function UEn(n){n.length>0&&n[0].length>0&&(this.c=qy(TD(mMn(vW(n[0][0]),(hWn(),alt))))),this.a=x8(Pmt,sVn,2018,n.length,0,2),this.b=x8(Lmt,sVn,2019,n.length,0,2),this.d=new Thn}function XEn(n){return 0!=n.c.length&&((l1(0,n.c.length),BB(n.c[0],17)).c.i.k==(uSn(),Put)||o5($V(new Rq(null,new w1(n,16)),new _c),new Kc))}function WEn(n,t,e){return OTn(e,"Tree layout",1),h2(n.b),IU(n.b,(zyn(),Ryt),Ryt),IU(n.b,_yt,_yt),IU(n.b,Kyt,Kyt),IU(n.b,Fyt,Fyt),n.a=$qn(n.b,t),lxn(n,t,mcn(e,1)),HSn(e),t}function VEn(n,t){var i,r,c,a,u,o;for(u=wDn(t),c=t.f,o=t.g,a=e.Math.sqrt(c*c+o*o),r=0,i=new Wb(u);i.a<i.c.c.length;)r+=VEn(n,BB(n0(i),33));return e.Math.max(r,a)}function QEn(){QEn=O,YIt=new UI(hJn,0),QIt=new UI("FREE",1),VIt=new UI("FIXED_SIDE",2),UIt=new UI("FIXED_ORDER",3),WIt=new UI("FIXED_RATIO",4),XIt=new UI("FIXED_POS",5)}function YEn(n,t){var e,i,r;if(e=t.Hh(n.a))for(r=SD(cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),T7n)),i=1;i<(CPn(),nLt).length;++i)if(m_(nLt[i],r))return i;return 0}function JEn(n){var t,e,i,r;if(null==n)return zWn;for(r=new $an(FWn,"[","]"),e=0,i=(t=n).length;e<i;++e)b6(r,""+t[e]);return r.a?0==r.e.length?r.a.a:r.a.a+""+r.e:r.c}function ZEn(n){var t,e,i,r;if(null==n)return zWn;for(r=new $an(FWn,"[","]"),e=0,i=(t=n).length;e<i;++e)b6(r,""+t[e]);return r.a?0==r.e.length?r.a.a:r.a.a+""+r.e:r.c}function nTn(n){var t,e,i;for(i=new $an(FWn,"{","}"),e=n.vc().Kc();e.Ob();)b6(i,W3(n,(t=BB(e.Pb(),42)).cd())+"="+W3(n,t.dd()));return i.a?0==i.e.length?i.a.a:i.a.a+""+i.e:i.c}function tTn(n){for(var t,e,i,r;!Wy(n.o);)e=BB(dU(n.o),46),i=BB(e.a,121),r=Nbn(t=BB(e.b,213),i),t.e==i?(RN(r.g,t),i.e=r.e+t.a):(RN(r.b,t),i.e=r.e-t.a),WB(n.e.a,i)}function eTn(n,t){var e,i,r;for(e=null,r=BB(t.Kb(n),20).Kc();r.Ob();)if(i=BB(r.Pb(),17),e){if((i.c.i==n?i.d.i:i.c.i)!=e)return!1}else e=i.c.i==n?i.d.i:i.c.i;return!0}function iTn(n,t){var e,i,r;for(i=new Wb(QLn(n,!1,t));i.a<i.c.c.length;)0==(e=BB(n0(i),129)).d?(WZ(e,null),VZ(e,null)):(r=e.a,WZ(e,e.b),VZ(e,r))}function rTn(n){var t,e;return Jcn(t=new B2,Iyt),(e=BB(mMn(n,(hWn(),Zft)),21)).Hc((bDn(),vft))&&Jcn(t,$yt),e.Hc(sft)&&Jcn(t,Cyt),e.Hc(gft)&&Jcn(t,Ayt),e.Hc(fft)&&Jcn(t,Oyt),t}function cTn(n){var t,e,i,r;for(Sqn(n),e=new oz(ZL(hbn(n).a.Kc(),new h));dAn(e);)r=(i=(t=BB(U5(e),17)).c.i==n)?t.d:t.c,i?MZ(t,null):SZ(t,null),hon(t,(hWn(),mlt),r),uAn(n,r.i)}function aTn(n,t,e,i){var r,c;switch(r=e[(c=t.i).g][n.d[c.g]],c.g){case 1:r-=i+t.j.b,t.g.b=r;break;case 3:r+=i,t.g.b=r;break;case 4:r-=i+t.j.a,t.g.a=r;break;case 2:r+=i,t.g.a=r}}function uTn(n){var t,e;for(e=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));e.e!=e.i.gc();)if(!dAn(new oz(ZL(wLn(t=BB(kpn(e),33)).a.Kc(),new h))))return t;return null}function oTn(){var n;return WOt?BB($$n((WM(),zAt),y6n),2016):(n=BB(cL(SJ((WM(),zAt),y6n),555)?SJ(zAt,y6n):new sAn,555),WOt=!0,KGn(n),jWn(n),Tyn(n),mZ(zAt,y6n,n),n)}function sTn(n,t,e){var i,r;if(0==n.j)return e;if(r=BB(Ken(n,t,e),72),!(i=e.ak()).Ij()||!n.a.rl(i))throw Hp(new dy("Invalid entry feature '"+i.Hj().zb+"."+i.ne()+"'"));return r}function hTn(n,t){var e,i,r,c,a,u,o;for(u=0,o=(a=n.a).length;u<o;++u)for(r=0,c=(i=a[u]).length;r<c;++r)if(e=i[r],GC(t)===GC(e)||null!=t&&Nfn(t,e))return!0;return!1}function fTn(n){var t,e,i;return Vhn(n,0)>=0?(e=Ojn(n,AQn),i=ldn(n,AQn)):(e=Ojn(t=jz(n,1),5e8),i=rbn(yz(i=ldn(t,5e8),1),e0(n,1))),i0(yz(i,32),e0(e,UQn))}function lTn(n,t,e){var i;switch(Px(0!=t.b),i=BB(Atn(t,t.a.a),8),e.g){case 0:i.b=0;break;case 2:i.b=n.f;break;case 3:i.a=0;break;default:i.a=n.g}return nX(spn(t,0),i),t}function bTn(n,t,e,i){var r,c,a,u,o;switch(o=n.b,u=zgn(a=(c=t.d).j,o.d[a.g],e),r=UR(B$(c.n),c.a),c.j.g){case 1:case 3:u.a+=r.a;break;case 2:case 4:u.b+=r.b}r5(i,u,i.c.b,i.c)}function wTn(n,t,e){var i,r,c,a;for(a=E7(n.e,t,0),(c=new rm).b=e,i=new M2(n.e,a);i.b<i.d.gc();)Px(i.b<i.d.gc()),(r=BB(i.d.Xb(i.c=i.b++),10)).p=e,WB(c.e,r),fW(i);return c}function dTn(n,t,e,i){var r,c,a,u,o;for(r=null,c=0,u=new Wb(t);u.a<u.c.c.length;)o=(a=BB(n0(u),33)).i+a.g,n<a.j+a.f+i&&(r?e.i-o<e.i-c&&(r=a):r=a,c=r.i+r.g);return r?c+i:0}function gTn(n,t,e,i){var r,c,a,u,o;for(c=null,r=0,u=new Wb(t);u.a<u.c.c.length;)o=(a=BB(n0(u),33)).j+a.f,n<a.i+a.g+i&&(c?e.j-o<e.j-r&&(c=a):c=a,r=c.j+c.f);return c?r+i:0}function pTn(n){var t,e,i;for(t=!1,i=n.b.c.length,e=0;e<i;e++)Yon(BB(xq(n.b,e),434))?!t&&e+1<i&&Yon(BB(xq(n.b,e+1),434))&&(t=!0,BB(xq(n.b,e),434).a=!0):t=!1}function vTn(n,t,e,i,r){var c,a;for(c=0,a=0;a<r;a++)c=rbn(c,ibn(e0(t[a],UQn),e0(i[a],UQn))),n[a]=dG(c),c=kz(c,32);for(;a<e;a++)c=rbn(c,e0(t[a],UQn)),n[a]=dG(c),c=kz(c,32)}function mTn(n,t){var e,i;for($On(),ODn(),i=Jtt,e=n;t>1;t>>=1)0!=(1&t)&&(i=Nnn(i,e)),e=1==e.d?Nnn(e,e):new Ign(CKn(e.a,e.d,x8(ANt,hQn,25,e.d<<1,15,1)));return i=Nnn(i,e)}function yTn(){var n,t,e,i;for(yTn=O,Oet=x8(xNt,qQn,25,25,15,1),Aet=x8(xNt,qQn,25,33,15,1),i=152587890625e-16,t=32;t>=0;t--)Aet[t]=i,i*=.5;for(e=1,n=24;n>=0;n--)Oet[n]=e,e*=.5}function kTn(n){var t,e;if(qy(TD(ZAn(n,(HXn(),wgt)))))for(e=new oz(ZL(dLn(n).a.Kc(),new h));dAn(e);)if(QCn(t=BB(U5(e),79))&&qy(TD(ZAn(t,dgt))))return!0;return!1}function jTn(n,t){var e,i,r;TU(n.f,t)&&(t.b=n,i=t.c,-1!=E7(n.j,i,0)||WB(n.j,i),r=t.d,-1!=E7(n.j,r,0)||WB(n.j,r),0!=(e=t.a.b).c.length&&(!n.i&&(n.i=new epn(n)),van(n.i,e)))}function ETn(n){var t,e,i,r;return(e=(t=n.c.d).j)==(r=(i=n.d.d).j)?t.p<i.p?0:1:Mln(e)==r?0:Eln(e)==r?1:SN(n.b.b,Mln(e))?0:1}function TTn(){TTn=O,tvt=new RP(j3n,0),Zpt=new RP("LONGEST_PATH",1),Ypt=new RP("COFFMAN_GRAHAM",2),Jpt=new RP(B1n,3),evt=new RP("STRETCH_WIDTH",4),nvt=new RP("MIN_WIDTH",5)}function MTn(n){var t;this.d=new xp,this.c=n.c,this.e=n.d,this.b=n.b,this.f=new sG(n.e),this.a=n.a,n.f?this.g=n.f:this.g=new Y_(t=BB(Vj(aAt),9),BB(SR(t,t.length),9),0)}function STn(n,t){var e,i,r,c;!(r=D2(i=n,"layoutOptions"))&&(r=D2(i,M6n)),r&&(e=null,(c=r)&&(e=new TT(c,jrn(c,x8(Qtt,sVn,2,0,6,1)))),e&&e5(e,new wC(c,t)))}function PTn(n){if(cL(n,239))return BB(n,33);if(cL(n,186))return WJ(BB(n,118));throw Hp(n?new tk("Only support nodes and ports."):new Hy(e8n))}function ITn(n,t,e,i){return t>=0&&m_(n.substr(t,3),"GMT")||t>=0&&m_(n.substr(t,3),"UTC")?(e[0]=t+3,yKn(n,e,i)):yKn(n,e,i)}function CTn(n,t){var e,i,r,c,a;for(c=n.g.a,a=n.g.b,i=new Wb(n.d);i.a<i.c.c.length;)(r=(e=BB(n0(i),70)).n).a=c,n.i==(kUn(),sCt)?r.b=a+n.j.b-e.o.b:r.b=a,UR(r,t),c+=e.o.a+n.e}function OTn(n,t,e){if(n.b)throw Hp(new Fy("The task is already done."));return null==n.p&&(n.p=t,n.r=e,n.k&&(n.o=($T(),cbn(fan(Date.now()),VVn))),!0)}function ATn(n){var t;return t=new py,null!=n.tg()&&AH(t,q6n,n.tg()),null!=n.ne()&&AH(t,t8n,n.ne()),null!=n.sg()&&AH(t,"description",n.sg()),t}function $Tn(n,t,e){var i,r,c;return c=n.q,n.q=t,0!=(4&n.Db)&&0==(1&n.Db)&&(r=new nU(n,1,9,c,t),e?e.Ei(r):e=r),t?(i=t.c)!=n.r&&(e=n.nk(i,e)):n.r&&(e=n.nk(null,e)),e}function LTn(n,t,e){var i,r;for(e=Npn(t,n.e,-1-n.c,e),r=new Mp(new usn(new Pb(xW(n.a).a).a));r.a.b;)e=azn(i=BB(ten(r.a).cd(),87),kLn(i,n.a),e);return e}function NTn(n,t,e){var i,r;for(e=oJ(t,n.e,-1-n.c,e),r=new Mp(new usn(new Pb(xW(n.a).a).a));r.a.b;)e=azn(i=BB(ten(r.a).cd(),87),kLn(i,n.a),e);return e}function xTn(n,t,e,i){var r,c,a;if(0==i)aHn(t,0,n,e,n.length-e);else for(a=32-i,n[n.length-1]=0,c=n.length-1;c>e;c--)n[c]|=t[c-e-1]>>>a,n[c-1]=t[c-e-1]<<i;for(r=0;r<e;r++)n[r]=0}function DTn(n){var t,i,r,c,a;for(t=0,i=0,a=n.Kc();a.Ob();)r=BB(a.Pb(),111),t=e.Math.max(t,r.d.b),i=e.Math.max(i,r.d.c);for(c=n.Kc();c.Ob();)(r=BB(c.Pb(),111)).d.b=t,r.d.c=i}function RTn(n){var t,i,r,c,a;for(i=0,t=0,a=n.Kc();a.Ob();)r=BB(a.Pb(),111),i=e.Math.max(i,r.d.d),t=e.Math.max(t,r.d.a);for(c=n.Kc();c.Ob();)(r=BB(c.Pb(),111)).d.d=i,r.d.a=t}function _Tn(n,t){var e,i,r,c;for(c=new Np,r=0,i=t.Kc();i.Ob();){for(e=iln(BB(i.Pb(),19).a+r);e.a<n.f&&!tG(n,e.a);)e=iln(e.a+1),++r;if(e.a>=n.f)break;c.c[c.c.length]=e}return c}function KTn(n){var t,e,i,r;for(t=null,r=new Wb(n.wf());r.a<r.c.c.length;)e=new UV((i=BB(n0(r),181)).qf().a,i.qf().b,i.rf().a,i.rf().b),t?IPn(t,e):t=e;return!t&&(t=new bA),t}function FTn(n,t,e,i){return 1==e?(!n.n&&(n.n=new eU(zOt,n,1,7)),Ywn(n.n,t,i)):BB(itn(BB(yan(n,16),26)||n.zh(),e),66).Nj().Qj(n,fgn(n),e-bX(n.zh()),t,i)}function BTn(n,t,e){var i,r,c,a,u;for(i=e.gc(),n.qi(n.i+i),(u=n.i-t)>0&&aHn(n.g,t,n.g,t+i,u),a=e.Kc(),n.i+=i,r=0;r<i;++r)c=a.Pb(),jL(n,t,n.oi(t,c)),n.bi(t,c),n.ci(),++t;return 0!=i}function HTn(n,t,e){var i;return t!=n.q?(n.q&&(e=oJ(n.q,n,-10,e)),t&&(e=Npn(t,n,-10,e)),e=$Tn(n,t,e)):0!=(4&n.Db)&&0==(1&n.Db)&&(i=new nU(n,1,9,t,t),e?e.Ei(i):e=i),e}function qTn(n,t,e,i){return IK(0==(e&hVn),"flatMap does not support SUBSIZED characteristic"),IK(0==(4&e),"flatMap does not support SORTED characteristic"),yX(n),yX(t),new q2(n,e,i,t)}function GTn(n,t){SU(t,"Cannot suppress a null exception."),vH(t!=n,"Exception can not suppress itself."),n.i||(null==n.k?n.k=Pun(Gk(Jnt,1),sVn,78,0,[t]):n.k[n.k.length]=t)}function zTn(n,t,e,i){var r,c,a,u,o,s;for(a=e.length,c=0,r=-1,s=atn(n.substr(t),(cK(),Tet)),u=0;u<a;++u)(o=e[u].length)>c&&sU(s,atn(e[u],Tet))&&(r=u,c=o);return r>=0&&(i[0]=t+c),r}function UTn(n,t){var e;if(0!=(e=YO(n.b.Hf(),t.b.Hf())))return e;switch(n.b.Hf().g){case 1:case 2:return E$(n.b.sf(),t.b.sf());case 3:case 4:return E$(t.b.sf(),n.b.sf())}return 0}function XTn(n){var t,e,i;for(i=n.e.c.length,n.a=kq(ANt,[sVn,hQn],[48,25],15,[i,i],2),e=new Wb(n.c);e.a<e.c.c.length;)t=BB(n0(e),282),n.a[t.c.b][t.d.b]+=BB(mMn(t,(fRn(),Zct)),19).a}function WTn(n,t,e){OTn(e,"Grow Tree",1),n.b=t.f,qy(TD(mMn(t,(Xcn(),Qrt))))?(n.c=new it,QZ(n,null)):n.c=new it,n.a=!1,FNn(n,t.f),hon(t,Yrt,(hN(),!!n.a)),HSn(e)}function VTn(n,t){var e,i,r,c,a;if(null==n)return null;for(a=x8(ONt,WVn,25,2*t,15,1),i=0,r=0;i<t;++i)e=n[i]>>4&15,c=15&n[i],a[r++]=OOt[e],a[r++]=OOt[c];return Bdn(a,0,a.length)}function QTn(n,t,e){var i,r,c;return i=t.ak(),c=t.dd(),r=i.$j()?LY(n,4,i,c,null,pBn(n,i,c,cL(i,99)&&0!=(BB(i,18).Bb&BQn)),!0):LY(n,i.Kj()?2:1,i,c,i.zj(),-1,!0),e?e.Ei(r):e=r,e}function YTn(n){var t,e;return n>=BQn?(t=HQn+(n-BQn>>10&1023)&QVn,e=56320+(n-BQn&1023)&QVn,String.fromCharCode(t)+""+String.fromCharCode(e)):String.fromCharCode(n&QVn)}function JTn(n,t){var e,i,r,c;return qD(),(r=BB(BB(h6(n.r,t),21),84)).gc()>=2&&(i=BB(r.Kc().Pb(),111),e=n.u.Hc((lCn(),tCt)),c=n.u.Hc(cCt),!i.a&&!e&&(2==r.gc()||c))}function ZTn(n,t,e,i,r){var c,a,u;for(c=eDn(n,t,e,i,r),u=!1;!c;)E$n(n,r,!0),u=!0,c=eDn(n,t,e,i,r);u&&E$n(n,r,!1),0!=(a=Dun(r)).c.length&&(n.d&&n.d.lg(a),ZTn(n,r,e,i,a))}function nMn(){nMn=O,aIt=new BI(QZn,0),rIt=new BI("DIRECTED",1),uIt=new BI("UNDIRECTED",2),eIt=new BI("ASSOCIATION",3),cIt=new BI("GENERALIZATION",4),iIt=new BI("DEPENDENCY",5)}function tMn(n,t){var e;if(!WJ(n))throw Hp(new Fy(F5n));switch(e=WJ(n),t.g){case 1:return-(n.j+n.f);case 2:return n.i-e.g;case 3:return n.j-e.f;case 4:return-(n.i+n.g)}return 0}function eMn(n,t){var e,i;for(kW(t),i=n.b.c.length,WB(n.b,t);i>0;){if(e=i,i=(i-1)/2|0,n.a.ue(xq(n.b,i),t)<=0)return c5(n.b,e,t),!0;c5(n.b,e,xq(n.b,i))}return c5(n.b,i,t),!0}function iMn(n,t,i,r){var c,a;if(c=0,i)c=mhn(n.a[i.g][t.g],r);else for(a=0;a<nrt;a++)c=e.Math.max(c,mhn(n.a[a][t.g],r));return t==(Dtn(),zit)&&n.b&&(c=e.Math.max(c,n.b.a)),c}function rMn(n,t){var e,i,r,c,a;return i=n.i,r=t.i,!(!i||!r)&&i.i==r.i&&i.i!=(kUn(),oCt)&&i.i!=(kUn(),ICt)&&(e=(c=i.g.a)+i.j.a,c<=(a=r.g.a)+r.j.a&&e>=a)}function cMn(n,t,e,i){var r;if(r=!1,XC(i)&&(r=!0,AH(t,e,SD(i))),r||zC(i)&&(r=!0,cMn(n,t,e,i)),r||cL(i,236)&&(r=!0,qQ(t,e,BB(i,236))),!r)throw Hp(new Ly(H6n))}function aMn(n,t){var e,i,r;if((e=t.Hh(n.a))&&null!=(r=cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),F9n)))for(i=1;i<(CPn(),Y$t).length;++i)if(m_(Y$t[i],r))return i;return 0}function uMn(n,t){var e,i,r;if((e=t.Hh(n.a))&&null!=(r=cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),F9n)))for(i=1;i<(CPn(),J$t).length;++i)if(m_(J$t[i],r))return i;return 0}function oMn(n,t){var e,i,r,c;if(kW(t),(c=n.a.gc())<t.gc())for(e=n.a.ec().Kc();e.Ob();)i=e.Pb(),t.Hc(i)&&e.Qb();else for(r=t.Kc();r.Ob();)i=r.Pb(),n.a.Bc(i);return c!=n.a.gc()}function sMn(n){var t,e;switch(e=B$(Aon(Pun(Gk(PMt,1),sVn,8,0,[n.i.n,n.n,n.a]))),t=n.i.d,n.j.g){case 1:e.b-=t.d;break;case 2:e.a+=t.c;break;case 3:e.b+=t.a;break;case 4:e.a-=t.b}return e}function hMn(n){var t;for(Crn(),t=BB(U5(new oz(ZL(fbn(n).a.Kc(),new h))),17).c.i;t.k==(uSn(),Put);)hon(t,(hWn(),olt),(hN(),!0)),t=BB(U5(new oz(ZL(fbn(t).a.Kc(),new h))),17).c.i}function fMn(n,t,e,i){var r,c,a;for(a=Lfn(t,i).Kc();a.Ob();)r=BB(a.Pb(),11),n.d[r.p]=n.d[r.p]+n.c[e.p];for(c=Lfn(e,i).Kc();c.Ob();)r=BB(c.Pb(),11),n.d[r.p]=n.d[r.p]-n.c[t.p]}function lMn(n,t,e){var i,r;for(r=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));r.e!=r.i.gc();)SA(i=BB(kpn(r),33),i.i+t,i.j+e);e5((!n.b&&(n.b=new eU(KOt,n,12,3)),n.b),new tC(t,e))}function bMn(n,t,e,i){var r,c;for(r=null==(c=t).d||n.a.ue(e.d,c.d)>0?1:0;c.a[r]!=e;)c=c.a[r],r=n.a.ue(e.d,c.d)>0?1:0;c.a[r]=i,i.b=e.b,i.a[0]=e.a[0],i.a[1]=e.a[1],e.a[0]=null,e.a[1]=null}function wMn(n){return lCn(),!(Ian(OJ(EG(eCt,Pun(Gk(CCt,1),$Vn,273,0,[rCt])),n))>1||Ian(OJ(EG(tCt,Pun(Gk(CCt,1),$Vn,273,0,[nCt,cCt])),n))>1)}function dMn(n,t){cL(SJ((WM(),zAt),n),498)?mZ(zAt,n,new OC(this,t)):mZ(zAt,n,this),iSn(this,t),t==(iE(),n$t)?(this.wb=BB(this,1939),BB(t,1941)):this.wb=(QX(),t$t)}function gMn(n){var t,e;if(null==n)return null;for(t=null,e=0;e<COt.length;++e)try{return BM(COt[e],n)}catch(i){if(!cL(i=lun(i),32))throw Hp(i);t=i}throw Hp(new L7(t))}function pMn(){pMn=O,pet=Pun(Gk(Qtt,1),sVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]),vet=Pun(Gk(Qtt,1),sVn,2,6,["Jan","Feb","Mar","Apr",tQn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])}function vMn(n){var t,e,i;(t=m_(typeof t,gYn)?null:new ln)&&(lM(),tW(e=(i=900)>=VVn?"error":i>=900?"warn":i>=800?"info":"log",n.a),n.b&&xNn(t,e,n.b,"Exception: ",!0))}function mMn(n,t){var e,i;return!n.q&&(n.q=new xp),null!=(i=RX(n.q,t))?i:(cL(e=t.wg(),4)&&(null==e?(!n.q&&(n.q=new xp),v6(n.q,t)):(!n.q&&(n.q=new xp),VW(n.q,t,e))),e)}function yMn(){yMn=O,Rat=new VS("P1_CYCLE_BREAKING",0),_at=new VS("P2_LAYERING",1),Kat=new VS("P3_NODE_ORDERING",2),Fat=new VS("P4_NODE_PLACEMENT",3),Bat=new VS("P5_EDGE_ROUTING",4)}function kMn(n,t){var e,i,r,c;for(i=(1==t?Wat:Xat).a.ec().Kc();i.Ob();)for(e=BB(i.Pb(),103),c=BB(h6(n.f.c,e),21).Kc();c.Ob();)r=BB(c.Pb(),46),y7(n.b.b,r.b),y7(n.b.a,BB(r.b,81).d)}function jMn(n,t){var e;if(Dnn(),n.c==t.c){if(n.b==t.b||hcn(n.b,t.b)){if(e=ZO(n.b)?1:-1,n.a&&!t.a)return e;if(!n.a&&t.a)return-e}return E$(n.b.g,t.b.g)}return Pln(n.c,t.c)}function EMn(n,t){var e;OTn(t,"Hierarchical port position processing",1),(e=n.b).c.length>0&&iKn((l1(0,e.c.length),BB(e.c[0],29)),n),e.c.length>1&&iKn(BB(xq(e,e.c.length-1),29),n),HSn(t)}function TMn(n,t){var e,i;if(NMn(n,t))return!0;for(i=new Wb(t);i.a<i.c.c.length;){if(KDn(n,e=BB(n0(i),33),uEn(e)))return!0;if($hn(n,e)-n.g<=n.a)return!0}return!1}function MMn(){MMn=O,bRn(),kTt=RTt,vTt=LTt,pTt=ATt,dTt=PTt,gTt=CTt,wTt=new WA(8),bTt=new XA((sWn(),XSt),wTt),mTt=new XA(LPt,8),yTt=xTt,hTt=jTt,fTt=TTt,lTt=new XA(lSt,(hN(),!1))}function SMn(){SMn=O,zMt=new WA(15),GMt=new XA((sWn(),XSt),zMt),XMt=new XA(LPt,15),UMt=new XA(pPt,iln(0)),KMt=jSt,BMt=_St,qMt=qSt,DMt=new XA(cSt,f5n),FMt=ISt,HMt=BSt,RMt=uSt,_Mt=hSt}function PMn(n){if(1!=(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b).i||1!=(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c).i)throw Hp(new Ky(r8n));return PTn(BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82))}function IMn(n){if(1!=(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b).i||1!=(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c).i)throw Hp(new Ky(r8n));return bun(BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82))}function CMn(n){if(1!=(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b).i||1!=(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c).i)throw Hp(new Ky(r8n));return bun(BB(Wtn((!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c),0),82))}function OMn(n){if(1!=(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b).i||1!=(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c).i)throw Hp(new Ky(r8n));return PTn(BB(Wtn((!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c),0),82))}function AMn(n,t,e){var i,r,c;if(++n.j,t>=(r=n.Vi())||t<0)throw Hp(new Ay(u8n+t+o8n+r));if(e>=r||e<0)throw Hp(new Ay(s8n+e+o8n+r));return t!=e?(c=n.Ti(e),n.Hi(t,c),i=c):i=n.Oi(e),i}function $Mn(n){var t,e,i;if(i=n,n)for(t=0,e=n.Ug();e;e=e.Ug()){if(++t>GQn)return $Mn(e);if(i=e,e==n)throw Hp(new Fy("There is a cycle in the containment hierarchy of "+n))}return i}function LMn(n){var t,e,i;for(i=new $an(FWn,"[","]"),e=n.Kc();e.Ob();)b6(i,GC(t=e.Pb())===GC(n)?"(this Collection)":null==t?zWn:Bbn(t));return i.a?0==i.e.length?i.a.a:i.a.a+""+i.e:i.c}function NMn(n,t){var e,i;if(i=!1,t.gc()<2)return!1;for(e=0;e<t.gc();e++)e<t.gc()-1?i|=KDn(n,BB(t.Xb(e),33),BB(t.Xb(e+1),33)):i|=KDn(n,BB(t.Xb(e),33),BB(t.Xb(0),33));return i}function xMn(n,t){var e;t!=n.a?(e=null,n.a&&(e=BB(n.a,49).ih(n,4,GOt,e)),t&&(e=BB(t,49).gh(n,4,GOt,e)),(e=Jhn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,1,t,t))}function DMn(n,t){var e;t!=n.e?(n.e&&K6(xW(n.e),n),t&&(!t.b&&(t.b=new Tp(new xm)),YR(t.b,n)),(e=Qkn(n,t,null))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,4,t,t))}function RMn(n){var t,e,i;for(e=n.length,i=0;i<e&&(b1(i,n.length),n.charCodeAt(i)<=32);)++i;for(t=e;t>i&&(b1(t-1,n.length),n.charCodeAt(t-1)<=32);)--t;return i>0||t<e?n.substr(i,t-i):n}function _Mn(n,t){var i;i=t.o,dA(n.f)?(n.j.a=e.Math.max(n.j.a,i.a),n.j.b+=i.b,n.d.c.length>1&&(n.j.b+=n.e)):(n.j.a+=i.a,n.j.b=e.Math.max(n.j.b,i.b),n.d.c.length>1&&(n.j.a+=n.e))}function KMn(){KMn=O,$st=Pun(Gk(FCt,1),YZn,61,0,[(kUn(),sCt),oCt,SCt]),Ast=Pun(Gk(FCt,1),YZn,61,0,[oCt,SCt,ICt]),Lst=Pun(Gk(FCt,1),YZn,61,0,[SCt,ICt,sCt]),Nst=Pun(Gk(FCt,1),YZn,61,0,[ICt,sCt,oCt])}function FMn(n,t,e,i){var r,c,a,u,o;if(c=n.c.d,a=n.d.d,c.j!=a.j)for(o=n.b,r=c.j,u=null;r!=a.j;)u=0==t?Mln(r):Eln(r),DH(i,UR(zgn(r,o.d[r.g],e),zgn(u,o.d[u.g],e))),r=u}function BMn(n,t,e,i){var r,c,a,u,o;return u=BB((a=qyn(n.a,t,e)).a,19).a,c=BB(a.b,19).a,i&&(o=BB(mMn(t,(hWn(),Elt)),10),r=BB(mMn(e,Elt),10),o&&r&&(t4(n.b,o,r),u+=n.b.i,c+=n.b.e)),u>c}function HMn(n){var t,e,i,r,c,a,u,o;for(this.a=rvn(n),this.b=new Np,i=0,r=(e=n).length;i<r;++i)for(t=e[i],c=new Np,WB(this.b,c),u=0,o=(a=t).length;u<o;++u)WB(c,new tK(a[u].j))}function qMn(n,t,e){var i,r,c;return c=0,i=e[t],t<e.length-1&&(r=e[t+1],n.b[t]?(c=bWn(n.d,i,r),c+=ZX(n.a,i,(kUn(),oCt)),c+=ZX(n.a,r,ICt)):c=C9(n.a,i,r)),n.c[t]&&(c+=L6(n.a,i)),c}function GMn(n,t,e,i,r){var c,a,u,o;for(o=null,u=new Wb(i);u.a<u.c.c.length;)if((a=BB(n0(u),441))!=e&&-1!=E7(a.e,r,0)){o=a;break}SZ(c=W5(r),e.b),MZ(c,o.b),JCn(n.a,r,new LK(c,t,e.f))}function zMn(n){for(;0!=n.g.c&&0!=n.d.c;)FD(n.g).c>FD(n.d).c?(n.i+=n.g.c,gdn(n.d)):FD(n.d).c>FD(n.g).c?(n.e+=n.d.c,gdn(n.g)):(n.i+=qq(n.g),n.e+=qq(n.d),gdn(n.g),gdn(n.d))}function UMn(n,t,e){var i,r,c,a;for(c=t.q,a=t.r,new zZ((O6(),Tyt),t,c,1),new zZ(Tyt,c,a,1),r=new Wb(e);r.a<r.c.c.length;)(i=BB(n0(r),112))!=c&&i!=t&&i!=a&&(gHn(n.a,i,t),gHn(n.a,i,a))}function XMn(n,t,i,r){n.a.d=e.Math.min(t,i),n.a.a=e.Math.max(t,r)-n.a.d,t<i?(n.b=.5*(t+i),n.g=_3n*n.b+.9*t,n.f=_3n*n.b+.9*i):(n.b=.5*(t+r),n.g=_3n*n.b+.9*r,n.f=_3n*n.b+.9*t)}function WMn(){function n(){return(new Date).getTime()}SWn={},!Array.isArray&&(Array.isArray=function(n){return"[object Array]"===Object.prototype.toString.call(n)}),!Date.now&&(Date.now=n)}function VMn(n,t){var e,i;i=BB(mMn(t,(HXn(),ept)),98),hon(t,(hWn(),ylt),i),(e=t.e)&&(JT(new Rq(null,new w1(e.a,16)),new Rw(n)),JT(wnn(new Rq(null,new w1(e.b,16)),new mt),new _w(n)))}function QMn(n){var t,i,r,c;if(gA(BB(mMn(n.b,(HXn(),Udt)),103)))return 0;for(t=0,r=new Wb(n.a);r.a<r.c.c.length;)(i=BB(n0(r),10)).k==(uSn(),Iut)&&(c=i.o.a,t=e.Math.max(t,c));return t}function YMn(n){switch(BB(mMn(n,(HXn(),kgt)),163).g){case 1:hon(n,kgt,(Tbn(),Blt));break;case 2:hon(n,kgt,(Tbn(),Hlt));break;case 3:hon(n,kgt,(Tbn(),Klt));break;case 4:hon(n,kgt,(Tbn(),Flt))}}function JMn(){JMn=O,cft=new $P(QZn,0),eft=new $P(cJn,1),aft=new $P(aJn,2),rft=new $P("LEFT_RIGHT_CONSTRAINT_LOCKING",3),ift=new $P("LEFT_RIGHT_CONNECTION_LOCKING",4),tft=new $P(q1n,5)}function ZMn(n,t,i){var r,c,a,u,o,s,h;o=i.a/2,a=i.b/2,s=1,h=1,(r=e.Math.abs(t.a-n.a))>o&&(s=o/r),(c=e.Math.abs(t.b-n.b))>a&&(h=a/c),u=e.Math.min(s,h),n.a+=u*(t.a-n.a),n.b+=u*(t.b-n.b)}function nSn(n,t,e,i,r){var c,a;for(a=!1,c=BB(xq(e.b,0),33);hBn(n,t,c,i,r)&&(a=!0,cEn(e,c),0!=e.b.c.length);)c=BB(xq(e.b,0),33);return 0==e.b.c.length&&Tkn(e.j,e),a&&Gmn(t.q),a}function tSn(n,t){var e,i,r,c;if(jDn(),t.b<2)return!1;for(i=e=BB(b3(c=spn(t,0)),8);c.b!=c.d.c;){if(cNn(n,i,r=BB(b3(c),8)))return!0;i=r}return!!cNn(n,i,e)}function eSn(n,t,e,i){return 0==e?(!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),B_(n.o,t,i)):BB(itn(BB(yan(n,16),26)||n.zh(),e),66).Nj().Rj(n,fgn(n),e-bX(n.zh()),t,i)}function iSn(n,t){var e;t!=n.sb?(e=null,n.sb&&(e=BB(n.sb,49).ih(n,1,HOt,e)),t&&(e=BB(t,49).gh(n,1,HOt,e)),(e=jfn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,4,t,t))}function rSn(n,t){var e,i;if(!t)throw Hp(new ek("All edge sections need an end point."));e=Ren(t,"x"),Ten(new _g(n).a,(kW(e),e)),i=Ren(t,"y"),Oen(new Kg(n).a,(kW(i),i))}function cSn(n,t){var e,i;if(!t)throw Hp(new ek("All edge sections need a start point."));e=Ren(t,"x"),Cen(new xg(n).a,(kW(e),e)),i=Ren(t,"y"),Aen(new Dg(n).a,(kW(i),i))}function aSn(n,t){var e,i,r,c,a;for(i=0,c=psn(n).length;i<c;++i)vMn(t);for(a=!Qet&&n.e?Qet?null:n.d:null;a;){for(e=0,r=psn(a).length;e<r;++e)vMn(t);a=!Qet&&a.e?Qet?null:a.d:null}}function uSn(){uSn=O,Iut=new JS("NORMAL",0),Put=new JS("LONG_EDGE",1),Mut=new JS("EXTERNAL_PORT",2),Cut=new JS("NORTH_SOUTH_PORT",3),Sut=new JS("LABEL",4),Tut=new JS("BREAKING_POINT",5)}function oSn(n){var t,e,i,r;if(t=!1,Lx(n,(hWn(),zft)))for(e=BB(mMn(n,zft),83),r=new Wb(n.j);r.a<r.c.c.length;)J$n(i=BB(n0(r),11))&&(t||(iCn(vW(n)),t=!0),fpn(BB(e.xc(i),306)))}function sSn(n,t,e){var i;OTn(e,"Self-Loop routing",1),i=Vln(t),iO(mMn(t,(I6(),TMt))),JT($V(AV(AV(wnn(new Rq(null,new w1(t.b,16)),new zi),new Ui),new Xi),new Wi),new eP(n,i)),HSn(e)}function hSn(n){var t,e,i;return i=ATn(n),null!=n.e&&AH(i,n8n,n.e),!!n.k&&AH(i,"type",dx(n.k)),!WE(n.j)&&(e=new Il,rtn(i,N6n,e),t=new cp(e),e5(n.j,t)),i}function fSn(n){var t,e,i,r;for(r=xX((lin(n.gc(),"size"),new Ck),123),i=!0,e=lz(n).Kc();e.Ob();)t=BB(e.Pb(),42),i||(r.a+=FWn),i=!1,uO(xX(uO(r,t.cd()),61),t.dd());return(r.a+="}",r).a}function lSn(n,t){var e,i,r;return(t&=63)<22?(e=n.l<<t,i=n.m<<t|n.l>>22-t,r=n.h<<t|n.m>>22-t):t<44?(e=0,i=n.l<<t-22,r=n.m<<t-22|n.l>>44-t):(e=0,i=0,r=n.l<<t-44),M$(e&SQn,i&SQn,r&PQn)}function bSn(n){if(null==ytt&&(ytt=new RegExp("^\\s*[+-]?(NaN|Infinity|((\\d+\\.?\\d*)|(\\.\\d+))([eE][+-]?\\d+)?[dDfF]?)\\s*$")),!ytt.test(n))throw Hp(new Mk(DQn+n+'"'));return parseFloat(n)}function wSn(n){var t,e,i,r;for(t=new Np,vU(e=x8($Nt,ZYn,25,n.a.c.length,16,1),e.length),r=new Wb(n.a);r.a<r.c.c.length;)e[(i=BB(n0(r),121)).d]||(t.c[t.c.length]=i,Ggn(n,i,e));return t}function dSn(n,t){var e,i,r,c;for(c=t.b.j,n.a=x8(ANt,hQn,25,c.c.length,15,1),r=0,i=0;i<c.c.length;i++)l1(i,c.c.length),0==(e=BB(c.c[i],11)).e.c.length&&0==e.g.c.length?r+=1:r+=3,n.a[i]=r}function gSn(){gSn=O,Dht=new CP("ALWAYS_UP",0),xht=new CP("ALWAYS_DOWN",1),_ht=new CP("DIRECTION_UP",2),Rht=new CP("DIRECTION_DOWN",3),Fht=new CP("SMART_UP",4),Kht=new CP("SMART_DOWN",5)}function pSn(n,t){if(n<0||t<0)throw Hp(new Ky("k and n must be positive"));if(t>n)throw Hp(new Ky("k must be smaller than n"));return 0==t||t==n?1:0==n?0:Mjn(n)/(Mjn(t)*Mjn(n-t))}function vSn(n,t){var e,i,r,c;for(e=new OA(n);null!=e.g||e.c?null==e.g||0!=e.i&&BB(e.g[e.i-1],47).Ob():tZ(e);)if(cL(c=BB(aLn(e),56),160))for(i=BB(c,160),r=0;r<t.length;r++)t[r].og(i)}function mSn(n){var t;return 0!=(64&n.Db)?Yln(n):((t=new fN(Yln(n))).a+=" (height: ",vE(t,n.f),t.a+=", width: ",vE(t,n.g),t.a+=", x: ",vE(t,n.i),t.a+=", y: ",vE(t,n.j),t.a+=")",t.a)}function ySn(n){var t,e,i,r,c,a;for(t=new v4,r=0,c=(i=n).length;r<c;++r)if(null!=Jgn(t,a=yX((e=i[r]).cd()),yX(e.dd())))throw Hp(new Ky("duplicate key: "+a));this.b=(SQ(),new Xb(t))}function kSn(n){var t,e,i,r,c;if(null==n)return zWn;for(c=new $an(FWn,"[","]"),i=0,r=(e=n).length;i<r;++i)t=e[i],b6(c,String.fromCharCode(t));return c.a?0==c.e.length?c.a.a:c.a.a+""+c.e:c.c}function jSn(){jSn=O,_nn(),Cct=new $O(oZn,Oct=Rct),iln(1),Ict=new $O(sZn,iln(300)),iln(0),Lct=new $O(hZn,iln(0)),new $p,Nct=new $O(fZn,lZn),new $p,Act=new $O(bZn,5),xct=Rct,$ct=Dct}function ESn(n,t){var e,i,r,c;for(i=(1==t?Wat:Xat).a.ec().Kc();i.Ob();)for(e=BB(i.Pb(),103),c=BB(h6(n.f.c,e),21).Kc();c.Ob();)r=BB(c.Pb(),46),WB(n.b.b,BB(r.b,81)),WB(n.b.a,BB(r.b,81).d)}function TSn(n,t){var e;if(null!=t&&!n.c.Yj().wj(t))throw e=cL(t,56)?BB(t,56).Tg().zb:nE(tsn(t)),Hp(new _y(r6n+n.c.ne()+"'s type '"+n.c.Yj().ne()+"' does not permit a value of type '"+e+"'"))}function MSn(n,t,e){var i,r;for(r=new M2(n.b,0);r.b<r.d.gc();)Px(r.b<r.d.gc()),GC(mMn(i=BB(r.d.Xb(r.c=r.b++),70),(hWn(),vlt)))===GC(t)&&(OPn(i.n,vW(n.c.i),e),fW(r),WB(t.b,i))}function SSn(n,t){if(t.a)switch(BB(mMn(t.b,(hWn(),ylt)),98).g){case 0:case 1:lEn(t);case 2:JT(new Rq(null,new w1(t.d,16)),new Li),oAn(n.a,t)}else JT(new Rq(null,new w1(t.d,16)),new Li)}function PSn(n){var t,i;return i=e.Math.sqrt((null==n.k&&(n.k=Wrn(n,new Ec)),Gy(n.k)/(n.b*(null==n.g&&(n.g=Xrn(n,new jc)),Gy(n.g))))),t=dG(fan(e.Math.round(i))),t=e.Math.min(t,n.f)}function ISn(){gcn(),LR.call(this),this.j=(kUn(),PCt),this.a=new Gj,new fm,this.f=(lin(2,AVn),new J6(2)),this.e=(lin(4,AVn),new J6(4)),this.g=(lin(4,AVn),new J6(4)),this.b=new hP(this.e,this.g)}function CSn(n,t){var e;return!qy(TD(mMn(t,(hWn(),Ilt))))&&(e=t.c.i,(n!=(Tbn(),Klt)||e.k!=(uSn(),Sut))&&BB(mMn(e,(HXn(),kgt)),163)!=Flt)}function OSn(n,t){var e;return!qy(TD(mMn(t,(hWn(),Ilt))))&&(e=t.d.i,(n!=(Tbn(),Blt)||e.k!=(uSn(),Sut))&&BB(mMn(e,(HXn(),kgt)),163)!=Hlt)}function ASn(n,t){var e,i,r,c,a,u,o;for(a=n.d,o=n.o,u=new UV(-a.b,-a.d,a.b+o.a+a.c,a.d+o.b+a.a),r=0,c=(i=t).length;r<c;++r)(e=i[r])&&IPn(u,e.i);a.b=-u.c,a.d=-u.d,a.c=u.b-a.b-o.a,a.a=u.a-a.d-o.b}function $Sn(){$Sn=O,iTt=new MI("CENTER_DISTANCE",0),rTt=new MI("CIRCLE_UNDERLAP",1),uTt=new MI("RECTANGLE_UNDERLAP",2),cTt=new MI("INVERTED_OVERLAP",3),aTt=new MI("MINIMUM_ROOT_DISTANCE",4)}function LSn(n){var t,e,i,r;if(_Dn(),null==n)return null;for(i=n.length,t=x8(ONt,WVn,25,2*i,15,1),e=0;e<i;e++)(r=n[e])<0&&(r+=256),t[2*e]=YLt[r>>4],t[2*e+1]=YLt[15&r];return Bdn(t,0,t.length)}function NSn(n){var t;switch(nV(),n.c.length){case 0:return Bnt;case 1:return CH((t=BB(JIn(new Wb(n)),42)).cd(),t.dd());default:return new hy(BB(Qgn(n,x8(Hnt,kVn,42,n.c.length,0,1)),165))}}function xSn(n){var t,e,i,r,c;for(t=new Lp,e=new Lp,d3(t,n),d3(e,n);e.b!=e.c;)for(c=new Wb(BB(dU(e),37).a);c.a<c.c.c.length;)(r=BB(n0(c),10)).e&&(d3(t,i=r.e),d3(e,i));return t}function DSn(n,t){switch(t.g){case 1:return _B(n.j,(gcn(),xut));case 2:return _B(n.j,(gcn(),Lut));case 3:return _B(n.j,(gcn(),Rut));case 4:return _B(n.j,(gcn(),_ut));default:return SQ(),SQ(),set}}function RSn(n,t){var e,i,r;e=sH(t,n.e),i=BB(RX(n.g.f,e),19).a,r=n.a.c.length-1,0!=n.a.c.length&&BB(xq(n.a,r),287).c==i?(++BB(xq(n.a,r),287).a,++BB(xq(n.a,r),287).b):WB(n.a,new Gx(i))}function _Sn(n,t,e){var i,r;return 0!=(i=SRn(n,t,e))?i:Lx(t,(hWn(),wlt))&&Lx(e,wlt)?((r=E$(BB(mMn(t,wlt),19).a,BB(mMn(e,wlt),19).a))<0?u_n(n,t,e):r>0&&u_n(n,e,t),r):COn(n,t,e)}function KSn(n,t,e){var i,r,c,a;if(0!=t.b){for(i=new YT,a=spn(t,0);a.b!=a.d.c;)Frn(i,xun(c=BB(b3(a),86))),(r=c.e).a=BB(mMn(c,(qqn(),gkt)),19).a,r.b=BB(mMn(c,pkt),19).a;KSn(n,i,mcn(e,i.b/n.a|0))}}function FSn(n,t){var e,i,r,c,a;if(n.e<=t)return n.g;if(z1(n,n.g,t))return n.g;for(c=n.r,i=n.g,a=n.r,r=(c-i)/2+i;i+1<c;)(e=cHn(n,r,!1)).b<=r&&e.a<=t?(a=r,c=r):i=r,r=(c-i)/2+i;return a}function BSn(n,t,e){OTn(e,"Recursive Graph Layout",hDn(n,t,!0)),vSn(t,Pun(Gk(nMt,1),HWn,527,0,[new $f])),P8(t,(sWn(),mPt))||vSn(t,Pun(Gk(nMt,1),HWn,527,0,[new gu])),lXn(n,t,null,e),HSn(e)}function HSn(n){var t;if(null==n.p)throw Hp(new Fy("The task has not begun yet."));n.b||(n.k&&($T(),t=cbn(fan(Date.now()),VVn),n.q=1e-9*j2(ibn(t,n.o))),n.c<n.r&&qin(n,n.r-n.c),n.b=!0)}function qSn(n){var t,e,i;for(DH(i=new km,new xI(n.j,n.k)),e=new AL((!n.a&&(n.a=new $L(xOt,n,5)),n.a));e.e!=e.i.gc();)DH(i,new xI((t=BB(kpn(e),469)).a,t.b));return DH(i,new xI(n.b,n.c)),i}function GSn(n,t,e,i,r){var c,a,u,o;if(r)for(o=((c=new hz(r.a.length)).b-c.a)*c.c<0?(eS(),MNt):new XL(c);o.Ob();)u=x2(r,BB(o.Pb(),19).a),DKn((a=new hQ(n,t,e,i)).a,a.b,a.c,a.d,u)}function zSn(n,t){var e;if(GC(n)===GC(t))return!0;if(cL(t,21)){e=BB(t,21);try{return n.gc()==e.gc()&&n.Ic(e)}catch(i){if(cL(i=lun(i),173)||cL(i,205))return!1;throw Hp(i)}}return!1}function USn(n,t){var i;WB(n.d,t),i=t.rf(),n.c?(n.e.a=e.Math.max(n.e.a,i.a),n.e.b+=i.b,n.d.c.length>1&&(n.e.b+=n.a)):(n.e.a+=i.a,n.e.b=e.Math.max(n.e.b,i.b),n.d.c.length>1&&(n.e.a+=n.a))}function XSn(n){var t,e,i,r;switch(t=(r=n.i).b,i=r.j,e=r.g,r.a.g){case 0:e.a=(n.g.b.o.a-i.a)/2;break;case 1:e.a=t.d.n.a+t.d.a.a;break;case 2:e.a=t.d.n.a+t.d.a.a-i.a;break;case 3:e.b=t.d.n.b+t.d.a.b}}function WSn(n,t,e,i,r){if(i<t||r<e)throw Hp(new Ky("The highx must be bigger then lowx and the highy must be bigger then lowy"));return n.a<t?n.a=t:n.a>i&&(n.a=i),n.b<e?n.b=e:n.b>r&&(n.b=r),n}function VSn(n){if(cL(n,149))return MNn(BB(n,149));if(cL(n,229))return Zbn(BB(n,229));if(cL(n,23))return hSn(BB(n,23));throw Hp(new Ky(z6n+LMn(new Jy(Pun(Gk(Ant,1),HWn,1,5,[n])))))}function QSn(n,t,e,i,r){var c,a,u;for(c=!0,a=0;a<i;a++)c&=0==e[a];if(0==r)aHn(e,i,n,0,t),a=t;else{for(u=32-r,c&=e[a]<<u==0,a=0;a<t-1;a++)n[a]=e[a+i]>>>r|e[a+i+1]<<u;n[a]=e[a+i]>>>r,++a}return c}function YSn(n,t,e,i){var r,c;if(t.k==(uSn(),Put))for(c=new oz(ZL(fbn(t).a.Kc(),new h));dAn(c);)if((r=BB(U5(c),17)).c.i.k==Put&&n.c.a[r.c.i.c.p]==i&&n.c.a[t.c.p]==e)return!0;return!1}function JSn(n,t){var e,i,r,c;return t&=63,e=n.h&PQn,t<22?(c=e>>>t,r=n.m>>t|e<<22-t,i=n.l>>t|n.m<<22-t):t<44?(c=0,r=e>>>t-22,i=n.m>>t-22|n.h<<44-t):(c=0,r=0,i=e>>>t-44),M$(i&SQn,r&SQn,c&PQn)}function ZSn(n,t,e,i){var r;this.b=i,this.e=n==(oin(),Amt),r=t[e],this.d=kq($Nt,[sVn,ZYn],[177,25],16,[r.length,r.length],2),this.a=kq(ANt,[sVn,hQn],[48,25],15,[r.length,r.length],2),this.c=new zEn(t,e)}function nPn(n){var t,e,i;for(n.k=new o1((kUn(),Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])).length,n.j.c.length),i=new Wb(n.j);i.a<i.c.c.length;)t=(e=BB(n0(i),113)).d.j,JCn(n.k,t,e);n.e=iNn(gz(n.k))}function tPn(n,t){var e,i,r;TU(n.d,t),e=new ka,VW(n.c,t,e),e.f=Phn(t.c),e.a=Phn(t.d),e.d=(gxn(),(r=t.c.i.k)==(uSn(),Iut)||r==Tut),e.e=(i=t.d.i.k)==Iut||i==Tut,e.b=t.c.j==(kUn(),ICt),e.c=t.d.j==oCt}function ePn(n){var t,e,i,r,c;for(c=DWn,r=DWn,i=new Wb(kbn(n));i.a<i.c.c.length;)t=(e=BB(n0(i),213)).e.e-e.d.e,e.e==n&&t<r?r=t:t<c&&(c=t);return r==DWn&&(r=-1),c==DWn&&(c=-1),new rC(iln(r),iln(c))}function iPn(n,t){var i,r,c;return c=ZJn,qpn(),r=Zrt,c=e.Math.abs(n.b),(i=e.Math.abs(t.f-n.b))<c&&(c=i,r=nct),(i=e.Math.abs(n.a))<c&&(c=i,r=tct),(i=e.Math.abs(t.g-n.a))<c&&(c=i,r=Jrt),r}function rPn(n,t){var e,i,r;for(e=t.a.o.a,r=new Sb(new s1(vW(t.a).b,t.c,t.f+1));r.b<r.d.gc();)if(Px(r.b<r.d.gc()),(i=BB(r.d.Xb(r.c=r.b++),29)).c.a>=e)return hPn(n,t,i.p),!0;return!1}function cPn(n){var t;return 0!=(64&n.Db)?mSn(n):(t=new lN(Z5n),!n.a||oO(oO((t.a+=' "',t),n.a),'"'),oO(kE(oO(kE(oO(kE(oO(kE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function aPn(n,t,e){var i,r,c,a,u;for(u=axn(n.e.Tg(),t),r=BB(n.g,119),i=0,a=0;a<n.i;++a)if(c=r[a],u.rl(c.ak())){if(i==e)return fDn(n,a),ZM(),BB(t,66).Oj()?c:c.dd();++i}throw Hp(new Ay(e9n+e+o8n+i))}function uPn(n){var t,e,i;if(2==(t=n.c)||7==t||1==t)return wWn(),wWn(),sNt;for(i=OXn(n),e=null;2!=(t=n.c)&&7!=t&&1!=t;)e||(wWn(),wWn(),tqn(e=new r$(1),i),i=e),tqn(e,OXn(n));return i}function oPn(n,t,e){return n<0||n>e?dIn(n,e,"start index"):t<0||t>e?dIn(t,e,"end index"):$Rn("end index (%s) must not be less than start index (%s)",Pun(Gk(Ant,1),HWn,1,5,[iln(t),iln(n)]))}function sPn(n,t){var e,i,r,c;for(i=0,r=n.length;i<r;i++){c=n[i];try{c[1]?c[0].jm()&&(t=TG(t,c)):c[0].jm()}catch(a){if(!cL(a=lun(a),78))throw Hp(a);e=a,Dk(),yY(cL(e,477)?BB(e,477).ae():e)}}return t}function hPn(n,t,i){var r,c;for(i!=t.c+t.b.gc()&&wHn(t.a,ian(t,i-t.c)),c=t.a.c.p,n.a[c]=e.Math.max(n.a[c],t.a.o.a),r=BB(mMn(t.a,(hWn(),Plt)),15).Kc();r.Ob();)hon(BB(r.Pb(),70),tst,(hN(),!0))}function fPn(n,t){var i,r,c;c=qNn(t),hon(t,(hWn(),llt),c),c&&(r=DWn,AY(n.f,c)&&(r=BB(qC(AY(n.f,c)),19).a),qy(TD(mMn(i=BB(xq(t.g,0),17),Ilt)))||VW(n,c,iln(e.Math.min(BB(mMn(i,wlt),19).a,r))))}function lPn(n,t,e){var i,r,c,a;for(t.p=-1,a=xwn(t,(ain(),qvt)).Kc();a.Ob();)for(r=new Wb(BB(a.Pb(),11).g);r.a<r.c.c.length;)t!=(c=(i=BB(n0(r),17)).d.i)&&(c.p<0?e.Fc(i):c.p>0&&lPn(n,c,e));t.p=0}function bPn(n){var t;this.c=new YT,this.f=n.e,this.e=n.d,this.i=n.g,this.d=n.c,this.b=n.b,this.k=n.j,this.a=n.a,n.i?this.j=n.i:this.j=new Y_(t=BB(Vj(jMt),9),BB(SR(t,t.length),9),0),this.g=n.f}function wPn(n){var t,e,i,r;for(t=xX(oO(new lN("Predicates."),"and"),40),e=!0,r=new Sb(n);r.b<r.d.gc();)Px(r.b<r.d.gc()),i=r.d.Xb(r.c=r.b++),e||(t.a+=","),t.a+=""+i,e=!1;return(t.a+=")",t).a}function dPn(n,t,e){var i,r,c;if(!(e<=t+2))for(r=(e-t)/2|0,i=0;i<r;++i)l1(t+i,n.c.length),c=BB(n.c[t+i],11),c5(n,t+i,(l1(e-i-1,n.c.length),BB(n.c[e-i-1],11))),l1(e-i-1,n.c.length),n.c[e-i-1]=c}function gPn(n,t,e){var i,r,c,a,u,o,s;u=(c=n.d.p).e,o=c.r,n.g=new Q_(o),i=(a=n.d.o.c.p)>0?u[a-1]:x8(Out,a1n,10,0,0,1),r=u[a],s=a<u.length-1?u[a+1]:x8(Out,a1n,10,0,0,1),t==e-1?uZ(n.g,r,s):uZ(n.g,i,r)}function pPn(n){var t;this.j=new Np,this.f=new Rv,this.b=new Y_(t=BB(Vj(FCt),9),BB(SR(t,t.length),9),0),this.d=x8(ANt,hQn,25,(kUn(),Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])).length,15,1),this.g=n}function vPn(n,t){var e,i,r;if(0!=t.c.length){for(e=TMn(n,t),r=!1;!e;)E$n(n,t,!0),r=!0,e=TMn(n,t);r&&E$n(n,t,!1),i=Dun(t),n.b&&n.b.lg(i),n.a=$hn(n,(l1(0,t.c.length),BB(t.c[0],33))),vPn(n,i)}}function mPn(n,t){var e,i,r;if(i=itn(n.Tg(),t),(e=t-n.Ah())<0){if(!i)throw Hp(new Ky(o6n+t+s6n));if(!i.Ij())throw Hp(new Ky(r6n+i.ne()+c6n));(r=n.Yg(i))>=0?n.Bh(r):cCn(n,i)}else qfn(n,e,i)}function yPn(n){var t,e;if(e=null,t=!1,cL(n,204)&&(t=!0,e=BB(n,204).a),t||cL(n,258)&&(t=!0,e=""+BB(n,258).a),t||cL(n,483)&&(t=!0,e=""+BB(n,483).a),!t)throw Hp(new Ly(H6n));return e}function kPn(n,t){var e,i;if(n.f){for(;t.Ob();)if(cL(i=(e=BB(t.Pb(),72)).ak(),99)&&0!=(BB(i,18).Bb&h6n)&&(!n.e||i.Gj()!=NOt||0!=i.aj())&&null!=e.dd())return t.Ub(),!0;return!1}return t.Ob()}function jPn(n,t){var e,i;if(n.f){for(;t.Sb();)if(cL(i=(e=BB(t.Ub(),72)).ak(),99)&&0!=(BB(i,18).Bb&h6n)&&(!n.e||i.Gj()!=NOt||0!=i.aj())&&null!=e.dd())return t.Pb(),!0;return!1}return t.Sb()}function EPn(n,t,e){var i,r,c,a,u,o;for(o=axn(n.e.Tg(),t),i=0,u=n.i,r=BB(n.g,119),a=0;a<n.i;++a)if(c=r[a],o.rl(c.ak())){if(e==i)return a;++i,u=a+1}if(e==i)return u;throw Hp(new Ay(e9n+e+o8n+i))}function TPn(n,t){var i,r,c;if(0==n.f.c.length)return null;for(c=new bA,i=new Wb(n.f);i.a<i.c.c.length;)r=BB(n0(i),70).o,c.b=e.Math.max(c.b,r.a),c.a+=r.b;return c.a+=(n.f.c.length-1)*t,c}function MPn(n,t,e){var i,r,c;for(r=new oz(ZL(hbn(e).a.Kc(),new h));dAn(r);)b5(i=BB(U5(r),17))||!b5(i)&&i.c.i.c==i.d.i.c||(c=zLn(n,i,e,new um)).c.length>1&&(t.c[t.c.length]=c)}function SPn(n){var t,e,i;for(Frn(e=new YT,n.o),i=new om;0!=e.b;)WUn(n,t=BB(0==e.b?null:(Px(0!=e.b),Atn(e,e.a.a)),508),!0)&&WB(i.a,t);for(;0!=i.a.c.length;)WUn(n,t=BB(thn(i),508),!1)}function PPn(){PPn=O,kMt=new $I(hJn,0),wMt=new $I("BOOLEAN",1),vMt=new $I("INT",2),yMt=new $I("STRING",3),dMt=new $I("DOUBLE",4),gMt=new $I("ENUM",5),pMt=new $I("ENUMSET",6),mMt=new $I("OBJECT",7)}function IPn(n,t){var i,r,c,a,u;r=e.Math.min(n.c,t.c),a=e.Math.min(n.d,t.d),(c=e.Math.max(n.c+n.b,t.c+t.b))<r&&(i=r,r=c,c=i),(u=e.Math.max(n.d+n.a,t.d+t.a))<a&&(i=a,a=u,u=i),xH(n,r,a,c-r,u-a)}function CPn(){CPn=O,J$t=Pun(Gk(Qtt,1),sVn,2,6,[w7n,d7n,g7n,p7n,v7n,m7n,n8n]),Y$t=Pun(Gk(Qtt,1),sVn,2,6,[w7n,"empty",d7n,_9n,"elementOnly"]),nLt=Pun(Gk(Qtt,1),sVn,2,6,[w7n,"preserve","replace",y7n]),Z$t=new SH}function OPn(n,t,e){var i,r,c;if(t!=e){i=t;do{UR(n,i.c),(r=i.e)&&(Kx(n,(c=i.d).b,c.d),UR(n,r.n),i=vW(r))}while(r);i=e;do{XR(n,i.c),(r=i.e)&&(Bx(n,(c=i.d).b,c.d),XR(n,r.n),i=vW(r))}while(r)}}function APn(n,t,e,i){var r,c,a,u,o;if(i.f.c+i.g.c==0)for(u=0,o=(a=n.a[n.c]).length;u<o;++u)VW(i,c=a[u],new kcn(n,c,e));return(r=BB(qC(AY(i.f,t)),663)).b=0,r.c=r.f,0==r.c||Tb(BB(xq(r.a,r.b),287)),r}function $Pn(){$Pn=O,Zst=new jP("MEDIAN_LAYER",0),tht=new jP("TAIL_LAYER",1),Jst=new jP("HEAD_LAYER",2),nht=new jP("SPACE_EFFICIENT_LAYER",3),eht=new jP("WIDEST_LAYER",4),Yst=new jP("CENTER_LAYER",5)}function LPn(n){switch(n.g){case 0:case 1:case 2:return kUn(),sCt;case 3:case 4:case 5:return kUn(),SCt;case 6:case 7:case 8:return kUn(),ICt;case 9:case 10:case 11:return kUn(),oCt;default:return kUn(),PCt}}function NPn(n,t){var e;return 0!=n.c.length&&(e=tdn((l1(0,n.c.length),BB(n.c[0],17)).c.i),BZ(),e==(bvn(),fvt)||e==hvt||o5($V(new Rq(null,new w1(n,16)),new Fc),new ig(t)))}function xPn(n,t,e){var i,r,c;if(!n.b[t.g]){for(n.b[t.g]=!0,!(i=e)&&(i=new P6),DH(i.b,t),c=n.a[t.g].Kc();c.Ob();)(r=BB(c.Pb(),188)).b!=t&&xPn(n,r.b,i),r.c!=t&&xPn(n,r.c,i),DH(i.a,r);return i}return null}function DPn(){DPn=O,Qyt=new lI("ROOT_PROC",0),Uyt=new lI("FAN_PROC",1),Wyt=new lI("NEIGHBORS_PROC",2),Xyt=new lI("LEVEL_HEIGHT",3),Vyt=new lI("NODE_POSITION_PROC",4),zyt=new lI("DETREEIFYING_PROC",5)}function RPn(n,t){if(cL(t,239))return zA(n,BB(t,33));if(cL(t,186))return UA(n,BB(t,118));if(cL(t,439))return GA(n,BB(t,202));throw Hp(new Ky(z6n+LMn(new Jy(Pun(Gk(Ant,1),HWn,1,5,[t])))))}function _Pn(n,t,e){var i,r;if(this.f=n,w6(e,r=(i=BB(RX(n.b,t),283))?i.a:0),e>=(r/2|0))for(this.e=i?i.c:null,this.d=r;e++<r;)TZ(this);else for(this.c=i?i.b:null;e-- >0;)EZ(this);this.b=t,this.a=null}function KPn(n,t){var e,i;t.a?zNn(n,t):(!!(e=BB(k_(n.b,t.b),57))&&e==n.a[t.b.f]&&!!e.a&&e.a!=t.b.a&&e.c.Fc(t.b),!!(i=BB(y_(n.b,t.b),57))&&n.a[i.f]==t.b&&!!i.a&&i.a!=t.b.a&&t.b.c.Fc(i),MN(n.b,t.b))}function FPn(n,t){var e,i;if(e=BB(oV(n.b,t),124),BB(BB(h6(n.r,t),21),84).dc())return e.n.b=0,void(e.n.c=0);e.n.b=n.C.b,e.n.c=n.C.c,n.A.Hc((mdn(),KCt))&&yRn(n,t),i=Xpn(n,t),PDn(n,t)==(cpn(),BIt)&&(i+=2*n.w),e.a.a=i}function BPn(n,t){var e,i;if(e=BB(oV(n.b,t),124),BB(BB(h6(n.r,t),21),84).dc())return e.n.d=0,void(e.n.a=0);e.n.d=n.C.d,e.n.a=n.C.a,n.A.Hc((mdn(),KCt))&&kRn(n,t),i=Wpn(n,t),PDn(n,t)==(cpn(),BIt)&&(i+=2*n.w),e.a.b=i}function HPn(n,t){var e,i,r,c;for(c=new Np,i=new Wb(t);i.a<i.c.c.length;)WB(c,new RS(e=BB(n0(i),65),!0)),WB(c,new RS(e,!1));my((r=new hY(n)).a.a),e2(c,n.b,new Jy(Pun(Gk(oit,1),HWn,679,0,[r])))}function qPn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w;return u=n.a,f=n.b,o=t.a,l=t.b,s=e.a,b=e.b,new xI(((c=u*l-f*o)*(s-(h=i.a))-(a=s*(w=i.b)-b*h)*(u-o))/(r=(u-o)*(b-w)-(f-l)*(s-h)),(c*(b-w)-a*(f-l))/r)}function GPn(n,t){var e,i,r;if(!n.d[t.p]){for(n.d[t.p]=!0,n.a[t.p]=!0,i=new oz(ZL(lbn(t).a.Kc(),new h));dAn(i);)b5(e=BB(U5(i),17))||(r=e.d.i,n.a[r.p]?WB(n.b,e):GPn(n,r));n.a[t.p]=!1}}function zPn(n,t,e){var i;switch(i=0,BB(mMn(t,(HXn(),kgt)),163).g){case 2:i=2*-e+n.a,++n.a;break;case 1:i=-e;break;case 3:i=e;break;case 4:i=2*e+n.b,++n.b}return Lx(t,(hWn(),wlt))&&(i+=BB(mMn(t,wlt),19).a),i}function UPn(n,t,e){var i,r,c;for(e.zc(t,n),WB(n.n,t),c=n.p.eg(t),t.j==n.p.fg()?Obn(n.e,c):Obn(n.j,c),rX(n),r=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[new Hw(t),new Gw(t)])));dAn(r);)i=BB(U5(r),11),e._b(i)||UPn(n,i,e)}function XPn(n){var t,e;return BB(ZAn(n,(sWn(),_St)),21).Hc((mdn(),DCt))?(e=BB(ZAn(n,qSt),21),t=new wA(BB(ZAn(n,BSt),8)),e.Hc((nKn(),GCt))&&(t.a<=0&&(t.a=20),t.b<=0&&(t.b=20)),t):new Gj}function WPn(n){var t,e,i;if(!n.b){for(i=new Io,e=new ax(RBn(n));e.e!=e.i.gc();)0!=((t=BB(jpn(e),18)).Bb&h6n)&&f9(i,t);chn(i),n.b=new NO((BB(Wtn(QQ((QX(),t$t).o),8),18),i.i),i.g),P5(n).b&=-9}return n.b}function VPn(n,t){var e,i,r,c,a,u;a=BB(Emn(gz(t.k),x8(FCt,YZn,61,2,0,1)),122),Zmn(n,u=t.g,e=o3(t,a[0]),i=u3(t,a[1]))<=Zmn(n,u,r=o3(t,a[1]),c=u3(t,a[0]))?(t.a=e,t.c=i):(t.a=r,t.c=c)}function QPn(n,t,e){var i,r,c;for(OTn(e,"Processor set neighbors",1),n.a=0==t.b.b?1:t.b.b,r=null,i=spn(t.b,0);!r&&i.b!=i.d.c;)qy(TD(mMn(c=BB(b3(i),86),(qqn(),dkt))))&&(r=c);r&&LDn(n,new bg(r),e),HSn(e)}function YPn(n){var t,e,i,r;return RHn(),t=-1==(i=GO(n,YTn(35)))?n:n.substr(0,i),e=-1==i?null:n.substr(i+1),(r=V3(EAt,t))?null!=e&&(r=Isn(r,(kW(e),e))):(r=WXn(t),a5(EAt,t,r),null!=e&&(r=Isn(r,e))),r}function JPn(n){var t,e,i,r,c,a,u;if(SQ(),cL(n,54))for(c=0,r=n.gc()-1;c<r;++c,--r)t=n.Xb(c),n._c(c,n.Xb(r)),n._c(r,t);else for(e=n.Yc(),a=n.Zc(n.gc());e.Tb()<a.Vb();)i=e.Pb(),u=a.Ub(),e.Wb(u),a.Wb(i)}function ZPn(n,t){var e,i,r;OTn(t,"End label pre-processing",1),e=Gy(MD(mMn(n,(HXn(),jpt)))),i=Gy(MD(mMn(n,Spt))),r=gA(BB(mMn(n,Udt),103)),JT(wnn(new Rq(null,new w1(n.b,16)),new he),new DK(e,i,r)),HSn(t)}function nIn(n,t){var e,i,r,c,a,u;for(u=0,d3(c=new Lp,t);c.b!=c.c;)for(u+=syn((a=BB(dU(c),214)).d,a.e),r=new Wb(a.b);r.a<r.c.c.length;)i=BB(n0(r),37),(e=BB(xq(n.b,i.p),214)).s||(u+=nIn(n,e));return u}function tIn(n,t,i){var r,c;Kan(this),t==(dJ(),Lyt)?TU(this.r,n.c):TU(this.w,n.c),TU(i==Lyt?this.r:this.w,n.d),tPn(this,n),XMn(this,r=Phn(n.c),c=Phn(n.d),c),this.o=(gxn(),e.Math.abs(r-c)<.2)}function eIn(n,t,e){var i,r,c,a,u;if(null!=(a=BB(yan(n.a,8),1936)))for(r=0,c=a.length;r<c;++r)null.jm();i=e,0==(1&n.a.Db)&&(u=new uW(n,e,t),i.ui(u)),cL(i,672)?BB(i,672).wi(n.a):i.ti()==n.a&&i.vi(null)}function iIn(){var n;return ZLt?BB($$n((WM(),zAt),S7n),1945):(sUn(),n=BB(cL(SJ((WM(),zAt),S7n),586)?SJ(zAt,S7n):new zW,586),ZLt=!0,gXn(n),pWn(n),VW((VM(),ZAt),n,new _s),Tyn(n),mZ(zAt,S7n,n),n)}function rIn(n,t,e,i){var r;return(r=zTn(n,e,Pun(Gk(Qtt,1),sVn,2,6,[bQn,wQn,dQn,gQn,pQn,vQn,mQn]),t))<0&&(r=zTn(n,e,Pun(Gk(Qtt,1),sVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]),t)),!(r<0||(i.d=r,0))}function cIn(n,t,e,i){var r;return(r=zTn(n,e,Pun(Gk(Qtt,1),sVn,2,6,[bQn,wQn,dQn,gQn,pQn,vQn,mQn]),t))<0&&(r=zTn(n,e,Pun(Gk(Qtt,1),sVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]),t)),!(r<0||(i.d=r,0))}function aIn(n){var t,e,i;for(K$n(n),i=new Np,e=new Wb(n.a.a.b);e.a<e.c.c.length;)WB(i,new fP(t=BB(n0(e),81),!0)),WB(i,new fP(t,!1));nmn(n.c),i2(i,n.b,new Jy(Pun(Gk(Jat,1),HWn,369,0,[n.c]))),vAn(n)}function uIn(n){var t,e,i,r;for(e=new xp,r=new Wb(n.d);r.a<r.c.c.length;)i=BB(n0(r),181),t=BB(i.We((hWn(),Uft)),17),AY(e.f,t)||VW(e,t,new TQ(t)),WB(BB(qC(AY(e.f,t)),456).b,i);return new tK(new Ob(e))}function oIn(n,t){var e,i,r,c,a;for(i=new d1(n.j.c.length),e=null,c=new Wb(n.j);c.a<c.c.c.length;)(r=BB(n0(c),11)).j!=e&&(i.b==i.c||F$n(i,e,t),o4(i),e=r.j),(a=mAn(r))&&w3(i,a);i.b==i.c||F$n(i,e,t)}function sIn(n,t){var e,i;for(i=new M2(n.b,0);i.b<i.d.gc();)Px(i.b<i.d.gc()),e=BB(i.d.Xb(i.c=i.b++),70),BB(mMn(e,(HXn(),Ydt)),272)==(Rtn(),UPt)&&(fW(i),WB(t.b,e),Lx(e,(hWn(),Uft))||hon(e,Uft,n))}function hIn(n){var t,i,r;for(t=F3(new oz(ZL(lbn(n).a.Kc(),new h))),i=new oz(ZL(fbn(n).a.Kc(),new h));dAn(i);)r=F3(new oz(ZL(lbn(BB(U5(i),17).c.i).a.Kc(),new h))),t=e.Math.max(t,r);return iln(t)}function fIn(n,t,e){var i,r,c,a;for(OTn(e,"Processor arrange node",1),r=null,c=new YT,i=spn(t.b,0);!r&&i.b!=i.d.c;)qy(TD(mMn(a=BB(b3(i),86),(qqn(),dkt))))&&(r=a);r5(c,r,c.c.b,c.c),Yzn(n,c,mcn(e,1)),HSn(e)}function lIn(n,t,e){var i,r,c;i=BB(ZAn(n,(sWn(),hSt)),21),r=0,c=0,t.a>e.a&&(i.Hc((wEn(),WMt))?r=(t.a-e.a)/2:i.Hc(QMt)&&(r=t.a-e.a)),t.b>e.b&&(i.Hc((wEn(),JMt))?c=(t.b-e.b)/2:i.Hc(YMt)&&(c=t.b-e.b)),lMn(n,r,c)}function bIn(n,t,e,i,r,c,a,u,o,s,h,f,l){cL(n.Cb,88)&&AIn(P5(BB(n.Cb,88)),4),Nrn(n,e),n.f=a,$ln(n,u),Nln(n,o),Aln(n,s),Lln(n,h),nln(n,f),qln(n,l),Yfn(n,!0),Len(n,r),n.ok(c),Chn(n,t),null!=i&&(n.i=null,arn(n,i))}function wIn(n){var t,e;if(n.f){for(;n.n>0;){if(cL(e=(t=BB(n.k.Xb(n.n-1),72)).ak(),99)&&0!=(BB(e,18).Bb&h6n)&&(!n.e||e.Gj()!=NOt||0!=e.aj())&&null!=t.dd())return!0;--n.n}return!1}return n.n>0}function dIn(n,t,e){if(n<0)return $Rn(BWn,Pun(Gk(Ant,1),HWn,1,5,[e,iln(n)]));if(t<0)throw Hp(new Ky(qWn+t));return $Rn("%s (%s) must not be greater than size (%s)",Pun(Gk(Ant,1),HWn,1,5,[e,iln(n),iln(t)]))}function gIn(n,t,e,i,r,c){var a,u,o;if(i-e<7)$bn(t,e,i,c);else if(gIn(t,n,u=e+r,o=u+((a=i+r)-u>>1),-r,c),gIn(t,n,o,a,-r,c),c.ue(n[o-1],n[o])<=0)for(;e<i;)$X(t,e++,n[u++]);else Gfn(n,u,o,a,t,e,i,c)}function pIn(n,t){var e,i,r;for(r=new Np,i=new Wb(n.c.a.b);i.a<i.c.c.length;)e=BB(n0(i),57),t.Lb(e)&&(WB(r,new OS(e,!0)),WB(r,new OS(e,!1)));Zvn(n.e),e2(r,n.d,new Jy(Pun(Gk(oit,1),HWn,679,0,[n.e])))}function vIn(n,t){var e,i,r,c,a,u,o;for(o=t.d,r=t.b.j,u=new Wb(o);u.a<u.c.c.length;)for(a=BB(n0(u),101),c=x8($Nt,ZYn,25,r.c.length,16,1),VW(n.b,a,c),e=a.a.d.p-1,i=a.c.d.p;e!=i;)c[e=(e+1)%r.c.length]=!0}function mIn(n,t){for(n.r=new Fan(n.p),Jl(n.r,n),Frn(n.r.j,n.j),yQ(n.j),DH(n.j,t),DH(n.r.e,t),rX(n),rX(n.r);0!=n.f.c.length;)G$(BB(xq(n.f,0),129));for(;0!=n.k.c.length;)G$(BB(xq(n.k,0),129));return n.r}function yIn(n,t,e){var i,r,c;if(r=itn(n.Tg(),t),(i=t-n.Ah())<0){if(!r)throw Hp(new Ky(o6n+t+s6n));if(!r.Ij())throw Hp(new Ky(r6n+r.ne()+c6n));(c=n.Yg(r))>=0?n.sh(c,e):TLn(n,r,e)}else Lbn(n,i,r,e)}function kIn(n){var t,e,i,r;if(e=BB(n,49).qh())try{if(i=null,(t=$$n((WM(),zAt),MKn(Kbn(e))))&&(r=t.rh())&&(i=r.Wk(Xy(e.e))),i&&i!=n)return kIn(i)}catch(c){if(!cL(c=lun(c),60))throw Hp(c)}return n}function jIn(n,t,e){var i,r,c,a;if(a=null==t?0:n.b.se(t),0==(r=null==(i=n.a.get(a))?new Array:i).length)n.a.set(a,r);else if(c=hhn(n,t,r))return c.ed(e);return $X(r,r.length,new PS(t,e)),++n.c,oY(n.b),null}function EIn(n,t){var e;return h2(n.a),IU(n.a,(Prn(),Qkt),Qkt),IU(n.a,Ykt,Ykt),dq(e=new B2,Ykt,(Ibn(),ejt)),GC(ZAn(t,(Uyn(),Sjt)))!==GC((Hsn(),sjt))&&dq(e,Ykt,njt),dq(e,Ykt,tjt),aA(n.a,e),$qn(n.a,t)}function TIn(n){if(!n)return lk(),htt;var t=n.valueOf?n.valueOf():n;if(t!==n){var i=ftt[typeof t];return i?i(t):khn(typeof t)}return n instanceof Array||n instanceof e.Array?new Tl(n):new Pl(n)}function MIn(n,t,i){var r,c,a;switch(a=n.o,(c=(r=BB(oV(n.p,i),244)).i).b=SCn(r),c.a=MCn(r),c.b=e.Math.max(c.b,a.a),c.b>a.a&&!t&&(c.b=a.a),c.c=-(c.b-a.a)/2,i.g){case 1:c.d=-c.a;break;case 3:c.d=a.b}KFn(r),GFn(r)}function SIn(n,t,i){var r,c,a;switch(a=n.o,(c=(r=BB(oV(n.p,i),244)).i).b=SCn(r),c.a=MCn(r),c.a=e.Math.max(c.a,a.b),c.a>a.b&&!t&&(c.a=a.b),c.d=-(c.a-a.b)/2,i.g){case 4:c.c=-c.b;break;case 2:c.c=a.a}KFn(r),GFn(r)}function PIn(n,t){var e,i,r,c,a;if(!t.dc())if(r=BB(t.Xb(0),128),1!=t.gc())for(e=1;e<t.gc();)!r.j&&r.o||(c=vyn(t,e))&&(i=BB(c.a,19).a,kxn(n,r,a=BB(c.b,128),e,i,t),e=i+1,r=a);else kxn(n,r,r,1,0,t)}function IIn(n){var t,e,i,r;for(m$(r=new tK(n.d),new zr),kDn(),t=Pun(Gk(iht,1),$Vn,270,0,[Bst,Gst,Fst,Xst,qst,Hst,Ust,zst]),e=0,i=new Wb(r);i.a<i.c.c.length;)IOn(BB(n0(i),101),t[e%t.length]),++e}function CIn(n,t){var e,i,r,c;if(jDn(),t.b<2)return!1;for(i=e=BB(b3(c=spn(t,0)),8);c.b!=c.d.c;){if(r=BB(b3(c),8),!Dcn(n,i)||!Dcn(n,r))return!1;i=r}return!(!Dcn(n,i)||!Dcn(n,e))}function OIn(n,t){var e,i,r,c,a;return e=Ren(a=n,"x"),nnn(new qg(t).a,e),i=Ren(a,"y"),tnn(new Gg(t).a,i),r=Ren(a,I6n),enn(new zg(t).a,r),c=Ren(a,P6n),inn(new Ug(t).a,c),c}function AIn(n,t){dRn(n,t),0!=(1&n.b)&&(n.a.a=null),0!=(2&n.b)&&(n.a.f=null),0!=(4&n.b)&&(n.a.g=null,n.a.i=null),0!=(16&n.b)&&(n.a.d=null,n.a.e=null),0!=(8&n.b)&&(n.a.b=null),0!=(32&n.b)&&(n.a.j=null,n.a.c=null)}function $In(n,t){var e,i;if(i=0,t.length>0)try{i=lKn(t,KVn,DWn)}catch(r){throw cL(r=lun(r),127)?Hp(new L7(r)):Hp(r)}return!n.a&&(n.a=new Sp(n)),i<(e=n.a).i&&i>=0?BB(Wtn(e,i),56):null}function LIn(n,t){if(n<0)return $Rn(BWn,Pun(Gk(Ant,1),HWn,1,5,["index",iln(n)]));if(t<0)throw Hp(new Ky(qWn+t));return $Rn("%s (%s) must be less than size (%s)",Pun(Gk(Ant,1),HWn,1,5,["index",iln(n),iln(t)]))}function NIn(n){var t,e,i,r,c;if(null==n)return zWn;for(c=new $an(FWn,"[","]"),i=0,r=(e=n).length;i<r;++i)t=e[i],c.a?oO(c.a,c.b):c.a=new lN(c.d),aO(c.a,""+t);return c.a?0==c.e.length?c.a.a:c.a.a+""+c.e:c.c}function xIn(n){var t,e,i,r,c;if(null==n)return zWn;for(c=new $an(FWn,"[","]"),i=0,r=(e=n).length;i<r;++i)t=e[i],c.a?oO(c.a,c.b):c.a=new lN(c.d),aO(c.a,""+t);return c.a?0==c.e.length?c.a.a:c.a.a+""+c.e:c.c}function DIn(n){var t,e,i,r,c;if(null==n)return zWn;for(c=new $an(FWn,"[","]"),i=0,r=(e=n).length;i<r;++i)t=e[i],c.a?oO(c.a,c.b):c.a=new lN(c.d),aO(c.a,""+t);return c.a?0==c.e.length?c.a.a:c.a.a+""+c.e:c.c}function RIn(n){var t,e,i,r,c;if(null==n)return zWn;for(c=new $an(FWn,"[","]"),i=0,r=(e=n).length;i<r;++i)t=e[i],c.a?oO(c.a,c.b):c.a=new lN(c.d),aO(c.a,""+t);return c.a?0==c.e.length?c.a.a:c.a.a+""+c.e:c.c}function _In(n,t){var e,i,r,c,a,u;for(e=n.b.c.length,r=xq(n.b,t);2*t+1<e&&(u=c=2*t+1,(a=c+1)<e&&n.a.ue(xq(n.b,a),xq(n.b,c))<0&&(u=a),i=u,!(n.a.ue(r,xq(n.b,i))<0));)c5(n.b,t,xq(n.b,i)),t=i;c5(n.b,t,r)}function KIn(n,t,i,r,c,a){var u,o,s,h,f;for(GC(n)===GC(i)&&(n=n.slice(t,t+c),t=0),s=i,o=t,h=t+c;o<h;)c=(u=e.Math.min(o+1e4,h))-o,(f=n.slice(o,u)).splice(0,0,r,a?c:0),Array.prototype.splice.apply(s,f),o=u,r+=c}function FIn(n,t,e){var i,r;return i=e.d,r=e.e,n.g[i.d]<=n.i[t.d]&&n.i[t.d]<=n.i[i.d]&&n.g[r.d]<=n.i[t.d]&&n.i[t.d]<=n.i[r.d]?!(n.i[i.d]<n.i[r.d]):n.i[i.d]<n.i[r.d]}function BIn(n){var t,e,i,r,c,a,u;if((i=n.a.c.length)>0)for(a=n.c.d,r=kL(XR(new xI((u=n.d.d).a,u.b),a),1/(i+1)),c=new xI(a.a,a.b),e=new Wb(n.a);e.a<e.c.c.length;)(t=BB(n0(e),559)).d.a=c.a,t.d.b=c.b,UR(c,r)}function HIn(n,t,i){var r,c,a,u,o,s;for(s=RQn,a=new Wb(GLn(n.b));a.a<a.c.c.length;)for(c=BB(n0(a),168),o=new Wb(GLn(t.b));o.a<o.c.c.length;)u=BB(n0(o),168),r=Iun(c.a,c.b,u.a,u.b,i),s=e.Math.min(s,r);return s}function qIn(n,t){if(!t)throw Hp(new gv);if(n.j=t,!n.d)switch(n.j.g){case 1:n.a.a=n.o.a/2,n.a.b=0;break;case 2:n.a.a=n.o.a,n.a.b=n.o.b/2;break;case 3:n.a.a=n.o.a/2,n.a.b=n.o.b;break;case 4:n.a.a=0,n.a.b=n.o.b/2}}function GIn(n,t){var i,r;return cL(t.g,10)&&BB(t.g,10).k==(uSn(),Mut)?RQn:f3(t)?e.Math.max(0,n.b/2-.5):(i=f2(t))?(r=Gy(MD(edn(i,(HXn(),Opt)))),e.Math.max(0,r/2-.5)):RQn}function zIn(n,t){var i,r;return cL(t.g,10)&&BB(t.g,10).k==(uSn(),Mut)?RQn:f3(t)?e.Math.max(0,n.b/2-.5):(i=f2(t))?(r=Gy(MD(edn(i,(HXn(),Opt)))),e.Math.max(0,r/2-.5)):RQn}function UIn(n){var t,e,i,r;for(r=Lfn(n.d,n.e).Kc();r.Ob();)for(i=BB(r.Pb(),11),e=new Wb(n.e==(kUn(),ICt)?i.e:i.g);e.a<e.c.c.length;)b5(t=BB(n0(e),17))||t.c.i.c==t.d.i.c||(RSn(n,t),++n.f,++n.c)}function XIn(n,t){var e,i;if(t.dc())return SQ(),SQ(),set;for(WB(i=new Np,iln(KVn)),e=1;e<n.f;++e)null==n.a&&wRn(n),n.a[e]&&WB(i,iln(e));return 1==i.c.length?(SQ(),SQ(),set):(WB(i,iln(DWn)),dBn(t,i))}function WIn(n,t){var e,i,r,c,a,u;e=ckn(t,u=t.c.i.k!=(uSn(),Iut)?t.d:t.c).i,r=BB(RX(n.k,u),121),i=n.i[e.p].a,A_(u.i)<(e.c?E7(e.c.a,e,0):-1)?(c=r,a=i):(c=i,a=r),UNn(aM(cM(uM(rM(new Hv,0),4),c),a))}function VIn(n,t,e){var i,r,c;if(e)for(r=((i=new hz(e.a.length)).b-i.a)*i.c<0?(eS(),MNt):new XL(i);r.Ob();)(c=Amn(n,kCn(dnn(e,BB(r.Pb(),19).a))))&&(!t.b&&(t.b=new h_(_Ot,t,4,7)),f9(t.b,c))}function QIn(n,t,e){var i,r,c;if(e)for(r=((i=new hz(e.a.length)).b-i.a)*i.c<0?(eS(),MNt):new XL(i);r.Ob();)(c=Amn(n,kCn(dnn(e,BB(r.Pb(),19).a))))&&(!t.c&&(t.c=new h_(_Ot,t,5,8)),f9(t.c,c))}function YIn(n,t,e){var i,r;i=t.a&n.f,t.b=n.b[i],n.b[i]=t,r=t.f&n.f,t.d=n.c[r],n.c[r]=t,e?(t.e=e.e,t.e?t.e.c=t:n.a=t,t.c=e.c,t.c?t.c.e=t:n.e=t):(t.e=n.e,t.c=null,n.e?n.e.c=t:n.a=t,n.e=t),++n.i,++n.g}function JIn(n){var t,e,i;if(t=n.Pb(),!n.Ob())return t;for(i=uO(oO(new Ik,"expected one element but was: <"),t),e=0;e<4&&n.Ob();e++)uO((i.a+=FWn,i),n.Pb());throw n.Ob()&&(i.a+=", ..."),i.a+=">",Hp(new Ky(i.a))}function ZIn(n,t){var e;t.d?t.d.b=t.b:n.a=t.b,t.b?t.b.d=t.d:n.e=t.d,t.e||t.c?(--(e=BB(RX(n.b,t.a),283)).a,t.e?t.e.c=t.c:e.b=t.c,t.c?t.c.e=t.e:e.c=t.e):((e=BB(v6(n.b,t.a),283)).a=0,++n.c),--n.d}function nCn(n){var t,e;return e=-n.a,t=Pun(Gk(ONt,1),WVn,25,15,[43,48,48,48,48]),e<0&&(t[0]=45,e=-e),t[1]=t[1]+((e/60|0)/10|0)&QVn,t[2]=t[2]+(e/60|0)%10&QVn,t[3]=t[3]+(e%60/10|0)&QVn,t[4]=t[4]+e%10&QVn,Bdn(t,0,t.length)}function tCn(n,t,e){var i,r;for(i=t.d,r=e.d;i.a-r.a==0&&i.b-r.b==0;)i.a+=H$n(n,26)*rYn+H$n(n,27)*cYn-.5,i.b+=H$n(n,26)*rYn+H$n(n,27)*cYn-.5,r.a+=H$n(n,26)*rYn+H$n(n,27)*cYn-.5,r.b+=H$n(n,26)*rYn+H$n(n,27)*cYn-.5}function eCn(n){var t,e,i,r;for(n.g=new Hbn(BB(yX(FCt),290)),i=0,kUn(),e=sCt,t=0;t<n.j.c.length;t++)(r=BB(xq(n.j,t),11)).j!=e&&(i!=t&&mG(n.g,e,new rC(iln(i),iln(t))),e=r.j,i=t);mG(n.g,e,new rC(iln(i),iln(t)))}function iCn(n){var t,e,i,r,c;for(e=0,t=new Wb(n.b);t.a<t.c.c.length;)for(r=new Wb(BB(n0(t),29).a);r.a<r.c.c.length;)for((i=BB(n0(r),10)).p=e++,c=new Wb(i.j);c.a<c.c.c.length;)BB(n0(c),11).p=e++}function rCn(n,t,e,i,r){var c,a,u,o;if(t)for(a=t.Kc();a.Ob();)for(o=cRn(BB(a.Pb(),10),(ain(),qvt),e).Kc();o.Ob();)u=BB(o.Pb(),11),(c=BB(qC(AY(r.f,u)),112))||(c=new Fan(n.d),i.c[i.c.length]=c,UPn(c,u,r))}function cCn(n,t){var e,i,r;if(!(r=Fqn((CPn(),Z$t),n.Tg(),t)))throw Hp(new Ky(r6n+t.ne()+c6n));ZM(),BB(r,66).Oj()||(r=Z1(B7(Z$t,r))),i=BB((e=n.Yg(r))>=0?n._g(e,!0,!0):cOn(n,r,!0),153),BB(i,215).ol(t)}function aCn(n){var t,i;return n>-0x800000000000&&n<0x800000000000?0==n?0:((t=n<0)&&(n=-n),i=IJ(e.Math.floor(e.Math.log(n)/.6931471805599453)),(!t||n!=e.Math.pow(2,i))&&++i,i):Van(fan(n))}function uCn(n){var t,e,i,r,c,a,u;for(c=new fA,e=new Wb(n);e.a<e.c.c.length;)a=(t=BB(n0(e),129)).a,u=t.b,c.a._b(a)||c.a._b(u)||(r=a,i=u,a.e.b+a.j.b>2&&u.e.b+u.j.b<=2&&(r=u,i=a),c.a.zc(r,c),r.q=i);return c}function oCn(n,t){var e,i,r;return qan(i=new $vn(n),t),hon(i,(hWn(),Vft),t),hon(i,(HXn(),ept),(QEn(),XIt)),hon(i,kdt,(wvn(),OMt)),Bl(i,(uSn(),Mut)),IZ(e=new ISn,i),qIn(e,(kUn(),ICt)),IZ(r=new ISn,i),qIn(r,oCt),i}function sCn(n){switch(n.g){case 0:return new Ny((oin(),Omt));case 1:return new df;case 2:return new jf;default:throw Hp(new Ky("No implementation is available for the crossing minimizer "+(null!=n.f?n.f:""+n.g)))}}function hCn(n,t){var e,i,r,c;for(n.c[t.p]=!0,WB(n.a,t),c=new Wb(t.j);c.a<c.c.c.length;)for(e=new m6((r=BB(n0(c),11)).b);y$(e.a)||y$(e.b);)i=ngn(r,BB(y$(e.a)?n0(e.a):n0(e.b),17)).i,n.c[i.p]||hCn(n,i)}function fCn(n){var t,i,r,c,a,u,o;for(u=0,i=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));i.e!=i.i.gc();)o=(t=BB(kpn(i),33)).g,c=t.f,r=e.Math.sqrt(o*o+c*c),u=e.Math.max(r,u),a=fCn(t),u=e.Math.max(a,u);return u}function lCn(){lCn=O,rCt=new XI("OUTSIDE",0),eCt=new XI("INSIDE",1),iCt=new XI("NEXT_TO_PORT_IF_POSSIBLE",2),tCt=new XI("ALWAYS_SAME_SIDE",3),nCt=new XI("ALWAYS_OTHER_SAME_SIDE",4),cCt=new XI("SPACE_EFFICIENT",5)}function bCn(n,t,e){var i,r,c,a;return $in(i=_2(n,(tE(),r=new jm,!!e&&nNn(r,e),r),t),R2(t,q6n)),STn(t,i),o$n(t,i),OIn(t,i),c=N2(t,"ports"),PLn((a=new pC(n,i)).a,a.b,c),xon(n,t,i),aun(n,t,i),i}function wCn(n){var t,e;return e=-n.a,t=Pun(Gk(ONt,1),WVn,25,15,[43,48,48,58,48,48]),e<0&&(t[0]=45,e=-e),t[1]=t[1]+((e/60|0)/10|0)&QVn,t[2]=t[2]+(e/60|0)%10&QVn,t[4]=t[4]+(e%60/10|0)&QVn,t[5]=t[5]+e%10&QVn,Bdn(t,0,t.length)}function dCn(n){var t;return t=Pun(Gk(ONt,1),WVn,25,15,[71,77,84,45,48,48,58,48,48]),n<=0&&(t[3]=43,n=-n),t[4]=t[4]+((n/60|0)/10|0)&QVn,t[5]=t[5]+(n/60|0)%10&QVn,t[7]=t[7]+(n%60/10|0)&QVn,t[8]=t[8]+n%10&QVn,Bdn(t,0,t.length)}function gCn(n){var t,e,i,r,c;if(null==n)return zWn;for(c=new $an(FWn,"[","]"),i=0,r=(e=n).length;i<r;++i)t=e[i],c.a?oO(c.a,c.b):c.a=new lN(c.d),aO(c.a,""+vz(t));return c.a?0==c.e.length?c.a.a:c.a.a+""+c.e:c.c}function pCn(n,t){var i,r,c;for(c=DWn,r=new Wb(kbn(t));r.a<r.c.c.length;)(i=BB(n0(r),213)).f&&!n.c[i.c]&&(n.c[i.c]=!0,c=e.Math.min(c,pCn(n,Nbn(i,t))));return n.i[t.d]=n.j,n.g[t.d]=e.Math.min(c,n.j++),n.g[t.d]}function vCn(n,t){var e,i,r;for(r=BB(BB(h6(n.r,t),21),84).Kc();r.Ob();)(i=BB(r.Pb(),111)).e.b=(e=i.b).Xe((sWn(),aPt))?e.Hf()==(kUn(),sCt)?-e.rf().b-Gy(MD(e.We(aPt))):Gy(MD(e.We(aPt))):e.Hf()==(kUn(),sCt)?-e.rf().b:0}function mCn(n){var t,e,i,r,c,a,u;for(e=QA(n.e),c=kL(Bx(B$(VA(n.e)),n.d*n.a,n.c*n.b),-.5),t=e.a-c.a,r=e.b-c.b,u=0;u<n.c;u++){for(i=t,a=0;a<n.d;a++)Wbn(n.e,new UV(i,r,n.a,n.b))&&FRn(n,a,u,!1,!0),i+=n.a;r+=n.b}}function yCn(n){var t,e,i;if(qy(TD(ZAn(n,(sWn(),SSt))))){for(i=new Np,e=new oz(ZL(dLn(n).a.Kc(),new h));dAn(e);)QCn(t=BB(U5(e),79))&&qy(TD(ZAn(t,PSt)))&&(i.c[i.c.length]=t);return i}return SQ(),SQ(),set}function kCn(n){var t;if(t=!1,cL(n,204))return t=!0,BB(n,204).a;if(!t&&cL(n,258)&&BB(n,258).a%1==0)return t=!0,iln(QO(BB(n,258).a));throw Hp(new ek("Id must be a string or an integer: '"+n+"'."))}function jCn(n,t){var e,i,r,c,a,u;for(c=null,r=new rU((!n.a&&(n.a=new Sp(n)),n.a));bOn(r);)if(YBn(a=(e=BB(aLn(r),56)).Tg()),null!=(i=(u=a.o)&&e.mh(u)?p_(uun(u),e.ah(u)):null)&&m_(i,t)){c=e;break}return c}function ECn(n,t,e){var i,r,c,a,u;if(lin(e,"occurrences"),0==e)return(u=BB(lfn(OQ(n.a),t),14))?u.gc():0;if(!(a=BB(lfn(OQ(n.a),t),14)))return 0;if(e>=(c=a.gc()))a.$b();else for(r=a.Kc(),i=0;i<e;i++)r.Pb(),r.Qb();return c}function TCn(n,t,e){var i,r,c;return lin(e,"oldCount"),lin(0,"newCount"),((i=BB(lfn(OQ(n.a),t),14))?i.gc():0)==e&&(lin(0,"count"),(c=-((r=BB(lfn(OQ(n.a),t),14))?r.gc():0))>0?wk():c<0&&ECn(n,t,-c),!0)}function MCn(n){var t,e,i,r,c,a;if(a=0,0==n.b){for(t=0,r=0,c=(i=Xvn(n,!0)).length;r<c;++r)(e=i[r])>0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}else a=_k(ecn(LV(AV(LU(n.a),new Mn),new Sn)));return a>0?a+n.n.d+n.n.a:0}function SCn(n){var t,e,i,r,c,a;if(a=0,0==n.b)a=_k(ecn(LV(AV(LU(n.a),new En),new Tn)));else{for(t=0,r=0,c=(i=Wvn(n,!0)).length;r<c;++r)(e=i[r])>0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}return a>0?a+n.n.b+n.n.c:0}function PCn(n,t){var i,r,c,a;for(i=(a=BB(oV(n.b,t),124)).a,c=BB(BB(h6(n.r,t),21),84).Kc();c.Ob();)(r=BB(c.Pb(),111)).c&&(i.a=e.Math.max(i.a,VH(r.c)));if(i.a>0)switch(t.g){case 2:a.n.c=n.s;break;case 4:a.n.b=n.s}}function ICn(n,t){var e,i,r;return 0==(e=BB(mMn(t,(fRn(),Zct)),19).a-BB(mMn(n,Zct),19).a)?(i=XR(B$(BB(mMn(n,(Mrn(),uat)),8)),BB(mMn(n,oat),8)),r=XR(B$(BB(mMn(t,uat),8)),BB(mMn(t,oat),8)),Pln(i.a*i.b,r.a*r.b)):e}function CCn(n,t){var e,i,r;return 0==(e=BB(mMn(t,(IAn(),$kt)),19).a-BB(mMn(n,$kt),19).a)?(i=XR(B$(BB(mMn(n,(qqn(),Zyt)),8)),BB(mMn(n,nkt),8)),r=XR(B$(BB(mMn(t,Zyt),8)),BB(mMn(t,nkt),8)),Pln(i.a*i.b,r.a*r.b)):e}function OCn(n){var t,e;return(e=new Ik).a+="e_",null!=(t=Xan(n))&&(e.a+=""+t),n.c&&n.d&&(oO((e.a+=" ",e),pyn(n.c)),oO(uO((e.a+="[",e),n.c.i),"]"),oO((e.a+=e1n,e),pyn(n.d)),oO(uO((e.a+="[",e),n.d.i),"]")),e.a}function ACn(n){switch(n.g){case 0:return new pf;case 1:return new vf;case 2:return new gf;case 3:return new mf;default:throw Hp(new Ky("No implementation is available for the layout phase "+(null!=n.f?n.f:""+n.g)))}}function $Cn(n,t,i,r,c){var a;switch(a=0,c.g){case 1:a=e.Math.max(0,t.b+n.b-(i.b+r));break;case 3:a=e.Math.max(0,-n.b-r);break;case 2:a=e.Math.max(0,-n.a-r);break;case 4:a=e.Math.max(0,t.a+n.a-(i.a+r))}return a}function LCn(n,t,e){var i,r,c;if(e)for(c=((i=new hz(e.a.length)).b-i.a)*i.c<0?(eS(),MNt):new XL(i);c.Ob();)r=x2(e,BB(c.Pb(),19).a),L6n in r.a||N6n in r.a?s_n(n,r,t):EXn(n,r,t),PL(BB(RX(n.b,Qdn(r)),79))}function NCn(n){var t,e;switch(n.b){case-1:return!0;case 0:return(e=n.t)>1||-1==e||(t=Ckn(n))&&(ZM(),t.Cj()==E9n)?(n.b=-1,!0):(n.b=1,!1);default:return!1}}function xCn(n,t){var e,i,r,c,a;for(!t.s&&(t.s=new eU(FAt,t,21,17)),c=null,r=0,a=(i=t.s).i;r<a;++r)switch(DW(B7(n,e=BB(Wtn(i,r),170)))){case 2:case 3:!c&&(c=new Np),c.c[c.c.length]=e}return c||(SQ(),SQ(),set)}function DCn(n,t){var e,i,r,c;if(QXn(n),0!=n.c||123!=n.a)throw Hp(new ak(kWn((u$(),P8n))));if(c=112==t,i=n.d,(e=lx(n.i,125,i))<0)throw Hp(new ak(kWn((u$(),I8n))));return r=fx(n.i,i,e),n.d=e+1,b9(r,c,512==(512&n.e))}function RCn(n){var t;if((t=BB(mMn(n,(HXn(),qdt)),314))==(Oin(),hht))throw Hp(new ck("The hierarchy aware processor "+t+" in child node "+n+" is only allowed if the root node specifies the same hierarchical processor."))}function _Cn(n,t){var e,i,r,c;for(GK(),e=null,r=t.Kc();r.Ob();)(i=BB(r.Pb(),128)).o||(WB((c=new PBn(F$(i.a),bH(i.a),null,BB(i.d.a.ec().Kc().Pb(),17))).c,i.a),n.c[n.c.length]=c,e&&WB(e.d,c),e=c)}function KCn(n,t){var e,i,r;if(t)if(0!=(4&t.i))for(i="[]",e=t.c;;e=e.c){if(0==(4&e.i)){Hin(n,r=Uy((ED(e),e.o+i))),xen(n,r);break}i+="[]"}else Hin(n,r=Uy((ED(t),t.o))),xen(n,r);else Hin(n,null),xen(n,null);n.yk(t)}function FCn(n,t,e,i,r){var c,a,u,o;return GC(o=hD(n,BB(r,56)))!==GC(r)?(u=BB(n.g[e],72),jL(n,e,sTn(n,e,c=Z3(t,o))),mA(n.e)&&(_En(a=LY(n,9,c.ak(),r,o,i,!1),new N7(n.e,9,n.c,u,c,i,!1)),$7(a)),o):r}function BCn(n,t,e){var i,r,c,a,u,o;for(i=BB(h6(n.c,t),15),r=BB(h6(n.c,e),15),c=i.Zc(i.gc()),a=r.Zc(r.gc());c.Sb()&&a.Sb();)if((u=BB(c.Ub(),19))!=(o=BB(a.Ub(),19)))return E$(u.a,o.a);return c.Ob()||a.Ob()?c.Ob()?1:-1:0}function HCn(n,t){var e,i;try{return X1(n.a,t)}catch(r){if(cL(r=lun(r),32)){try{if(i=lKn(t,KVn,DWn),e=Vj(n.a),i>=0&&i<e.length)return e[i]}catch(c){if(!cL(c=lun(c),127))throw Hp(c)}return null}throw Hp(r)}}function qCn(n,t){var e,i,r;if(r=Fqn((CPn(),Z$t),n.Tg(),t))return ZM(),BB(r,66).Oj()||(r=Z1(B7(Z$t,r))),i=BB((e=n.Yg(r))>=0?n._g(e,!0,!0):cOn(n,r,!0),153),BB(i,215).ll(t);throw Hp(new Ky(r6n+t.ne()+u6n))}function GCn(){var n;return tS(),Q$t?BB($$n((WM(),zAt),V9n),1939):(RO(Hnt,new Is),nzn(),n=BB(cL(SJ((WM(),zAt),V9n),547)?SJ(zAt,V9n):new UW,547),Q$t=!0,oWn(n),TWn(n),VW((VM(),ZAt),n,new Go),mZ(zAt,V9n,n),n)}function zCn(n,t){var e,i,r,c;n.j=-1,mA(n.e)?(e=n.i,c=0!=n.i,c6(n,t),i=new N7(n.e,3,n.c,null,t,e,c),r=t.Qk(n.e,n.c,null),(r=CEn(n,t,r))?(r.Ei(i),r.Fi()):ban(n.e,i)):(c6(n,t),(r=t.Qk(n.e,n.c,null))&&r.Fi())}function UCn(n,t){var e,i,r;if(r=0,(i=t[0])>=n.length)return-1;for(b1(i,n.length),e=n.charCodeAt(i);e>=48&&e<=57&&(r=10*r+(e-48),!(++i>=n.length));)b1(i,n.length),e=n.charCodeAt(i);return i>t[0]?t[0]=i:r=-1,r}function XCn(n){var t,i,r,c,a;return i=c=BB(n.a,19).a,r=a=BB(n.b,19).a,t=e.Math.max(e.Math.abs(c),e.Math.abs(a)),c<=0&&c==a?(i=0,r=a-1):c==-t&&a!=t?(i=a,r=c,a>=0&&++i):(i=-a,r=c),new rC(iln(i),iln(r))}function WCn(n,t,e,i){var r,c,a,u,o,s;for(r=0;r<t.o;r++)for(c=r-t.j+e,a=0;a<t.p;a++)if(o=c,s=u=a-t.k+i,o+=n.j,s+=n.k,o>=0&&s>=0&&o<n.o&&s<n.p&&(!mmn(t,r,a)&&imn(n,c,u)||vmn(t,r,a)&&!rmn(n,c,u)))return!0;return!1}function VCn(n,t,e){var i,r,c,a;c=n.c,a=n.d,r=(Aon(Pun(Gk(PMt,1),sVn,8,0,[c.i.n,c.n,c.a])).b+Aon(Pun(Gk(PMt,1),sVn,8,0,[a.i.n,a.n,a.a])).b)/2,i=null,i=c.j==(kUn(),oCt)?new xI(t+c.i.c.c.a+e,r):new xI(t-e,r),_x(n.a,0,i)}function QCn(n){var t,e,i;for(t=null,e=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c)])));dAn(e);)if(i=PTn(BB(U5(e),82)),t){if(t!=i)return!1}else t=i;return!0}function YCn(n,t,e){var i;if(++n.j,t>=n.i)throw Hp(new Ay(u8n+t+o8n+n.i));if(e>=n.i)throw Hp(new Ay(s8n+e+o8n+n.i));return i=n.g[e],t!=e&&(t<e?aHn(n.g,t,n.g,t+1,e-t):aHn(n.g,e+1,n.g,e,t-e),$X(n.g,t,i),n.ei(t,i,e),n.ci()),i}function JCn(n,t,e){var i;if(i=BB(n.c.xc(t),14))return!!i.Fc(e)&&(++n.d,!0);if((i=n.ic(t)).Fc(e))return++n.d,n.c.zc(t,i),!0;throw Hp(new g5("New Collection violated the Collection spec"))}function ZCn(n){var t,e,i;return n<0?0:0==n?32:(e=16-(t=(i=-(n>>16))>>16&16),e+=t=(i=(n>>=t)-256)>>16&8,e+=t=(i=(n<<=t)-KQn)>>16&4,(e+=t=(i=(n<<=t)-hVn)>>16&2)+2-(t=(i=(n<<=t)>>14)&~(i>>1)))}function nOn(n){var t,e,i,r;for(MQ(),Sct=new Np,Mct=new xp,Tct=new Np,!n.a&&(n.a=new eU(UOt,n,10,11)),xUn(t=n.a),r=new AL(t);r.e!=r.i.gc();)i=BB(kpn(r),33),-1==E7(Sct,i,0)&&(e=new Np,WB(Tct,e),Rgn(i,e));return Tct}function tOn(n,t,e){var i,r,c,a;n.a=e.b.d,cL(t,352)?(e5(c=qSn(r=cDn(BB(t,79),!1,!1)),i=new Nw(n)),VFn(c,r),null!=t.We((sWn(),OSt))&&e5(BB(t.We(OSt),74),i)):((a=BB(t,470)).Hg(a.Dg()+n.a.a),a.Ig(a.Eg()+n.a.b))}function eOn(n,t){var i,r,c,a,u,o,s,h;for(h=Gy(MD(mMn(t,(HXn(),Npt)))),s=n[0].n.a+n[0].o.a+n[0].d.c+h,o=1;o<n.length;o++)r=n[o].n,c=n[o].o,i=n[o].d,(a=r.a-i.b-s)<0&&(r.a-=a),(u=t.f).a=e.Math.max(u.a,r.a+c.a),s=r.a+c.a+i.c+h}function iOn(n,t){var e,i,r,c,a,u;return i=BB(BB(RX(n.g,t.a),46).a,65),r=BB(BB(RX(n.g,t.b),46).a,65),(e=nqn(c=i.b,a=r.b))>=0?e:(u=lW(XR(new xI(a.c+a.b/2,a.d+a.a/2),new xI(c.c+c.b/2,c.d+c.a/2))),-(YKn(c,a)-1)*u)}function rOn(n,t,e){var i;JT(new Rq(null,(!e.a&&(e.a=new eU(FOt,e,6,6)),new w1(e.a,16))),new eC(n,t)),JT(new Rq(null,(!e.n&&(e.n=new eU(zOt,e,1,7)),new w1(e.n,16))),new iC(n,t)),(i=BB(ZAn(e,(sWn(),OSt)),74))&&Yrn(i,n,t)}function cOn(n,t,e){var i,r,c;if(c=Fqn((CPn(),Z$t),n.Tg(),t))return ZM(),BB(c,66).Oj()||(c=Z1(B7(Z$t,c))),r=BB((i=n.Yg(c))>=0?n._g(i,!0,!0):cOn(n,c,!0),153),BB(r,215).hl(t,e);throw Hp(new Ky(r6n+t.ne()+u6n))}function aOn(n,t,e,i){var r,c,a,u,o;if(r=n.d[t])if(c=r.g,o=r.i,null!=i){for(u=0;u<o;++u)if((a=BB(c[u],133)).Sh()==e&&Nfn(i,a.cd()))return a}else for(u=0;u<o;++u)if(GC((a=BB(c[u],133)).cd())===GC(i))return a;return null}function uOn(n,t){var e;if(t<0)throw Hp(new Oy("Negative exponent"));if(0==t)return Jtt;if(1==t||swn(n,Jtt)||swn(n,eet))return n;if(!fAn(n,0)){for(e=1;!fAn(n,e);)++e;return Nnn(vwn(e*t),uOn(z5(n,e),t))}return mTn(n,t)}function oOn(n,t){var e,i,r;if(GC(n)===GC(t))return!0;if(null==n||null==t)return!1;if(n.length!=t.length)return!1;for(e=0;e<n.length;++e)if(i=n[e],r=t[e],!(GC(i)===GC(r)||null!=i&&Nfn(i,r)))return!1;return!0}function sOn(n){var t,e,i;for(kM(),this.b=Vat,this.c=(Ffn(),BPt),this.f=(yM(),zat),this.a=n,tj(this,new It),kNn(this),i=new Wb(n.b);i.a<i.c.c.length;)(e=BB(n0(i),81)).d||(t=new Pgn(Pun(Gk(Qat,1),HWn,81,0,[e])),WB(n.a,t))}function hOn(n,t,e){var i,r,c,a,u,o;if(!n||0==n.c.length)return null;for(c=new _Y(t,!e),r=new Wb(n);r.a<r.c.c.length;)i=BB(n0(r),70),USn(c,(gM(),new Bw(i)));return(a=c.i).a=(o=c.n,c.e.b+o.d+o.a),a.b=(u=c.n,c.e.a+u.b+u.c),c}function fOn(n){var t,e,i,r,c,a,u;for(hA(u=n2(n.a),new Pe),e=null,c=0,a=(r=u).length;c<a&&(i=r[c]).k==(uSn(),Mut);++c)(t=BB(mMn(i,(hWn(),Qft)),61))!=(kUn(),ICt)&&t!=oCt||(e&&BB(mMn(e,clt),15).Fc(i),e=i)}function lOn(n,t,e){var i,r,c,a,u,o;l1(t,n.c.length),u=BB(n.c[t],329),s6(n,t),u.b/2>=e&&(i=t,c=(o=(u.c+u.a)/2)-e,u.c<=o-e&&kG(n,i++,new kB(u.c,c)),(a=o+e)<=u.a&&(r=new kB(a,u.a),LZ(i,n.c.length),MS(n.c,i,r)))}function bOn(n){var t;if(n.c||null!=n.g){if(null==n.g)return!0;if(0==n.i)return!1;t=BB(n.g[n.i-1],47)}else n.d=n.si(n.f),f9(n,n.d),t=n.d;return t==n.b&&null.km>=null.jm()?(aLn(n),bOn(n)):t.Ob()}function wOn(n,t,e){var i,r,c,a;if(!(a=e)&&(a=LH(new Xm,0)),OTn(a,qZn,1),$Gn(n.c,t),1==(c=RGn(n.a,t)).gc())VHn(BB(c.Xb(0),37),a);else for(r=1/c.gc(),i=c.Kc();i.Ob();)VHn(BB(i.Pb(),37),mcn(a,r));Ek(n.a,c,t),FDn(t),HSn(a)}function dOn(n){if(this.a=n,n.c.i.k==(uSn(),Mut))this.c=n.c,this.d=BB(mMn(n.c.i,(hWn(),Qft)),61);else{if(n.d.i.k!=Mut)throw Hp(new Ky("Edge "+n+" is not an external edge."));this.c=n.d,this.d=BB(mMn(n.d.i,(hWn(),Qft)),61)}}function gOn(n,t){var e,i,r;r=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,3,r,n.b)),t?t!=n&&(Nrn(n,t.zb),$en(n,t.d),Fin(n,null==(e=null==(i=t.c)?t.zb:i)||m_(e,t.zb)?null:e)):(Nrn(n,null),$en(n,0),Fin(n,null))}function pOn(n){var t,e;if(n.f){for(;n.n<n.o;){if(cL(e=(t=BB(n.j?n.j.pi(n.n):n.k.Xb(n.n),72)).ak(),99)&&0!=(BB(e,18).Bb&h6n)&&(!n.e||e.Gj()!=NOt||0!=e.aj())&&null!=t.dd())return!0;++n.n}return!1}return n.n<n.o}function vOn(n,t){var e;this.e=(WX(),yX(n),WX(),Nwn(n)),this.c=(yX(t),Nwn(t)),aN(this.e.Hd().dc()==this.c.Hd().dc()),this.d=vbn(this.e),this.b=vbn(this.c),e=kq(Ant,[sVn,HWn],[5,1],5,[this.e.Hd().gc(),this.c.Hd().gc()],2),this.a=e,din(this)}function mOn(n){var t=(!Znt&&(Znt=QUn()),Znt);return'"'+n.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g,(function(n){return CJ(n,t)}))+'"'}function yOn(n){var t,e;for(IQ(),this.b=hit,this.c=lit,this.g=(pM(),sit),this.d=(Ffn(),BPt),this.a=n,yNn(this),e=new Wb(n.b);e.a<e.c.c.length;)!(t=BB(n0(e),57)).a&&CN(Xen(new Xv,Pun(Gk(bit,1),HWn,57,0,[t])),n),t.e=new gY(t.d)}function kOn(n){var t,e,i,r,c;for(r=n.e.c.length,i=x8(Rnt,nZn,15,r,0,1),c=new Wb(n.e);c.a<c.c.c.length;)i[BB(n0(c),144).b]=new YT;for(e=new Wb(n.c);e.a<e.c.c.length;)i[(t=BB(n0(e),282)).c.b].Fc(t),i[t.d.b].Fc(t);return i}function jOn(n){var t,e,i,r,c,a;for(a=sx(n.c.length),r=new Wb(n);r.a<r.c.c.length;){for(i=BB(n0(r),10),c=new Rv,e=new oz(ZL(lbn(i).a.Kc(),new h));dAn(e);)(t=BB(U5(e),17)).c.i==t.d.i||TU(c,t.d.i);a.c[a.c.length]=c}return a}function EOn(n,t){var e,i,r,c,a;if(t>=(a=null==(e=BB(yan(n.a,4),126))?0:e.length))throw Hp(new t_(t,a));return r=e[t],1==a?i=null:(aHn(e,0,i=x8(dAt,i9n,415,a-1,0,1),0,t),(c=a-t-1)>0&&aHn(e,t+1,i,t,c)),Fgn(n,i),eIn(n,t,r),r}function TOn(){TOn=O,lLt=BB(Wtn(QQ((cE(),gLt).qb),6),34),sLt=BB(Wtn(QQ(gLt.qb),3),34),hLt=BB(Wtn(QQ(gLt.qb),4),34),fLt=BB(Wtn(QQ(gLt.qb),5),18),oEn(lLt),oEn(sLt),oEn(hLt),oEn(fLt),bLt=new Jy(Pun(Gk(FAt,1),N9n,170,0,[lLt,sLt]))}function MOn(n,t){var e;this.d=new lm,this.b=t,this.e=new wA(t.qf()),e=n.u.Hc((lCn(),iCt)),n.u.Hc(eCt)?n.D?this.a=e&&!t.If():this.a=!0:n.u.Hc(rCt)?this.a=!!e&&!(t.zf().Kc().Ob()||t.Bf().Kc().Ob()):this.a=!1}function SOn(n,t){var e,i,r,c;for(e=n.o.a,c=BB(BB(h6(n.r,t),21),84).Kc();c.Ob();)(r=BB(c.Pb(),111)).e.a=(i=r.b).Xe((sWn(),aPt))?i.Hf()==(kUn(),ICt)?-i.rf().a-Gy(MD(i.We(aPt))):e+Gy(MD(i.We(aPt))):i.Hf()==(kUn(),ICt)?-i.rf().a:e}function POn(n,t){var e,i,r;e=BB(mMn(n,(HXn(),Udt)),103),r=BB(ZAn(t,upt),61),(i=BB(mMn(n,ept),98))!=(QEn(),QIt)&&i!=YIt?r==(kUn(),PCt)&&(r=OFn(t,e))==PCt&&(r=hwn(e)):r=XHn(t)>0?hwn(e):Tln(hwn(e)),Ypn(t,upt,r)}function IOn(n,t){var e,i,r,c,a;for(a=n.j,t.a!=t.b&&m$(a,new Ur),r=a.c.length/2|0,i=0;i<r;i++)l1(i,a.c.length),(c=BB(a.c[i],113)).c&&qIn(c.d,t.a);for(e=r;e<a.c.length;e++)l1(e,a.c.length),(c=BB(a.c[e],113)).c&&qIn(c.d,t.b)}function COn(n,t,e){var i,r,c;return i=n.c[t.c.p][t.p],r=n.c[e.c.p][e.p],null!=i.a&&null!=r.a?((c=Tz(i.a,r.a))<0?u_n(n,t,e):c>0&&u_n(n,e,t),c):null!=i.a?(u_n(n,t,e),-1):null!=r.a?(u_n(n,e,t),1):0}function OOn(n,t){var e,i,r,c;n.ej()?(e=n.Vi(),c=n.fj(),++n.j,n.Hi(e,n.oi(e,t)),i=n.Zi(3,null,t,e,c),n.bj()&&(r=n.cj(t,null))?(r.Ei(i),r.Fi()):n.$i(i)):(eW(n,t),n.bj()&&(r=n.cj(t,null))&&r.Fi())}function AOn(n,t){var e,i,r,c,a;for(a=axn(n.e.Tg(),t),r=new go,e=BB(n.g,119),c=n.i;--c>=0;)i=e[c],a.rl(i.ak())&&f9(r,i);!aXn(n,r)&&mA(n.e)&&Lv(n,t.$j()?LY(n,6,t,(SQ(),set),null,-1,!1):LY(n,t.Kj()?2:1,t,null,null,-1,!1))}function $On(){var n,t;for($On=O,aet=x8(oet,sVn,91,32,0,1),uet=x8(oet,sVn,91,32,0,1),n=1,t=0;t<=18;t++)aet[t]=npn(n),uet[t]=npn(yz(n,t)),n=cbn(n,5);for(;t<uet.length;t++)aet[t]=Nnn(aet[t-1],aet[1]),uet[t]=Nnn(uet[t-1],(ODn(),net))}function LOn(n,t){var e,i,r,c;return n.a==(JMn(),cft)||(r=t.a.c,e=t.a.c+t.a.b,!(t.j&&(c=(i=t.A).c.c.a-i.o.a/2,r-(i.n.a+i.o.a)>c)||t.q&&(c=(i=t.C).c.c.a-i.o.a/2,i.n.a-e>c)))}function NOn(n,t){OTn(t,"Partition preprocessing",1),JT(BB(P4(AV(wnn(AV(new Rq(null,new w1(n.a,16)),new vi),new mi),new yi),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15).Oc(),new ki),HSn(t)}function xOn(n){var t,e,i,r,c,a;for(qZ(),e=new v4,i=new Wb(n.e.b);i.a<i.c.c.length;)for(c=new Wb(BB(n0(i),29).a);c.a<c.c.c.length;)r=BB(n0(c),10),(t=BB(lnn(e,a=n.g[r.p]),15))||Jgn(e,a,t=new Np),t.Fc(r);return e}function DOn(n,t){var e,i,r,c,a;for(r=t.b.b,n.a=x8(Rnt,nZn,15,r,0,1),n.b=x8($Nt,ZYn,25,r,16,1),a=spn(t.b,0);a.b!=a.d.c;)c=BB(b3(a),86),n.a[c.g]=new YT;for(i=spn(t.a,0);i.b!=i.d.c;)e=BB(b3(i),188),n.a[e.b.g].Fc(e),n.a[e.c.g].Fc(e)}function ROn(n){var t;return 0!=(64&n.Db)?P$n(n):((t=new fN(P$n(n))).a+=" (startX: ",vE(t,n.j),t.a+=", startY: ",vE(t,n.k),t.a+=", endX: ",vE(t,n.b),t.a+=", endY: ",vE(t,n.c),t.a+=", identifier: ",cO(t,n.d),t.a+=")",t.a)}function _On(n){var t;return 0!=(64&n.Db)?kfn(n):((t=new fN(kfn(n))).a+=" (ordered: ",yE(t,0!=(256&n.Bb)),t.a+=", unique: ",yE(t,0!=(512&n.Bb)),t.a+=", lowerBound: ",mE(t,n.s),t.a+=", upperBound: ",mE(t,n.t),t.a+=")",t.a)}function KOn(n,t,e,i,r,c,a,u){var o;return cL(n.Cb,88)&&AIn(P5(BB(n.Cb,88)),4),Nrn(n,e),n.f=i,$ln(n,r),Nln(n,c),Aln(n,a),Lln(n,!1),nln(n,!0),qln(n,u),Yfn(n,!0),Len(n,0),n.b=0,Nen(n,1),(o=HTn(n,t,null))&&o.Fi(),Gln(n,!1),n}function FOn(n,t){var i,r;return BB(SJ(n.a,t),512)||(i=new y5(t),k5(),x_(i,FOn(n,fx(r=Qet?null:i.c,0,e.Math.max(0,mN(r,YTn(46)))))),0==(Qet?null:i.c).length&&zD(i,new X),mZ(n.a,Qet?null:i.c,i),i)}function BOn(n,t){var e;n.b=t,n.g=new Np,e=JOn(n.b),n.e=e,n.f=e,n.c=qy(TD(mMn(n.b,(Kkn(),jit)))),n.a=MD(mMn(n.b,(sWn(),cSt))),null==n.a&&(n.a=1),Gy(n.a)>1?n.e*=Gy(n.a):n.f/=Gy(n.a),Ihn(n),ggn(n),TRn(n),hon(n.b,(Epn(),gct),n.g)}function HOn(n,t,e){var i,r,c,a,u;for(i=0,u=e,t||(i=e*(n.c.length-1),u*=-1),c=new Wb(n);c.a<c.c.c.length;){for(hon(r=BB(n0(c),10),(HXn(),kdt),(wvn(),OMt)),r.o.a=i,a=DSn(r,(kUn(),oCt)).Kc();a.Ob();)BB(a.Pb(),11).n.a=i;i+=u}}function qOn(n,t,e){var i,r,c;n.ej()?(c=n.fj(),Cfn(n,t,e),i=n.Zi(3,null,e,t,c),n.bj()?(r=n.cj(e,null),n.ij()&&(r=n.jj(e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)):n.$i(i)):(Cfn(n,t,e),n.bj()&&(r=n.cj(e,null))&&r.Fi())}function GOn(n,t,e){var i,r,c,a,u,o;return(u=n.Gk(e))!=e?(a=n.g[t],o=u,jL(n,t,n.oi(t,o)),c=a,n.gi(t,o,c),n.rk()&&(i=e,r=n.dj(i,null),!BB(u,49).eh()&&(r=n.cj(o,r)),r&&r.Fi()),mA(n.e)&&Lv(n,n.Zi(9,e,u,t,!1)),u):e}function zOn(n,t){var e,i,r;for(e=new Wb(n.a.a);e.a<e.c.c.length;)BB(n0(e),189).g=!0;for(r=new Wb(n.a.b);r.a<r.c.c.length;)(i=BB(n0(r),81)).k=qy(TD(n.e.Kb(new rC(i,t)))),i.d.g=i.d.g&qy(TD(n.e.Kb(new rC(i,t))));return n}function UOn(n){var t,e,i,r,c;if(e=new Y_(t=BB(Vj(FCt),9),BB(SR(t,t.length),9),0),c=BB(mMn(n,(hWn(),Elt)),10))for(r=new Wb(c.j);r.a<r.c.c.length;)GC(mMn(i=BB(n0(r),11),dlt))===GC(n)&&zN(new m6(i.b))&&orn(e,i.j);return e}function XOn(n,t,e){var i,r,c,a;if(!n.d[e.p]){for(i=new oz(ZL(lbn(e).a.Kc(),new h));dAn(i);){for(c=new oz(ZL(fbn(a=BB(U5(i),17).d.i).a.Kc(),new h));dAn(c);)(r=BB(U5(c),17)).c.i==t&&(n.a[r.p]=!0);XOn(n,t,a)}n.d[e.p]=!0}}function WOn(n,t){var e,i,r,c,a,u,o;if(1==(i=pbn(254&n.Db)))n.Eb=null;else if(c=een(n.Eb),2==i)r=Rmn(n,t),n.Eb=c[0==r?1:0];else{for(a=x8(Ant,HWn,1,i-1,5,1),e=2,u=0,o=0;e<=128;e<<=1)e==t?++u:0!=(n.Db&e)&&(a[o++]=c[u++]);n.Eb=a}n.Db&=~t}function VOn(n,t){var e,i,r,c,a;for(!t.s&&(t.s=new eU(FAt,t,21,17)),c=null,r=0,a=(i=t.s).i;r<a;++r)switch(DW(B7(n,e=BB(Wtn(i,r),170)))){case 4:case 5:case 6:!c&&(c=new Np),c.c[c.c.length]=e}return c||(SQ(),SQ(),set)}function QOn(n){var t;switch(t=0,n){case 105:t=2;break;case 109:t=8;break;case 115:t=4;break;case 120:t=16;break;case 117:t=32;break;case 119:t=64;break;case 70:t=256;break;case 72:t=128;break;case 88:t=512;break;case 44:t=k6n}return t}function YOn(n,t,e,i,r){var c,a,u,o;if(GC(n)!==GC(t)||i!=r)for(u=0;u<i;u++){for(a=0,c=n[u],o=0;o<r;o++)a=rbn(rbn(cbn(e0(c,UQn),e0(t[o],UQn)),e0(e[u+o],UQn)),e0(dG(a),UQn)),e[u+o]=dG(a),a=jz(a,32);e[u+r]=dG(a)}else CKn(n,i,e)}function JOn(n){var t,i,r,c,a,u,o,s,h,f,l;for(f=0,h=0,o=(c=n.a).a.gc(),r=c.a.ec().Kc();r.Ob();)(i=BB(r.Pb(),561)).b&&VBn(i),f+=(l=(t=i.a).a)+(u=t.b),h+=l*u;return s=e.Math.sqrt(400*o*h-4*h+f*f)+f,0==(a=2*(100*o-1))?s:s/a}function ZOn(n,t){0!=t.b&&(isNaN(n.s)?n.s=Gy((Px(0!=t.b),MD(t.a.a.c))):n.s=e.Math.min(n.s,Gy((Px(0!=t.b),MD(t.a.a.c)))),isNaN(n.c)?n.c=Gy((Px(0!=t.b),MD(t.c.b.c))):n.c=e.Math.max(n.c,Gy((Px(0!=t.b),MD(t.c.b.c)))))}function nAn(n){var t,e,i;for(t=null,e=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c)])));dAn(e);)if(i=PTn(BB(U5(e),82)),t){if(t!=JJ(i))return!0}else t=JJ(i);return!1}function tAn(n,t){var e,i,r,c;n.ej()?(e=n.i,c=n.fj(),c6(n,t),i=n.Zi(3,null,t,e,c),n.bj()?(r=n.cj(t,null),n.ij()&&(r=n.jj(t,r)),r?(r.Ei(i),r.Fi()):n.$i(i)):n.$i(i)):(c6(n,t),n.bj()&&(r=n.cj(t,null))&&r.Fi())}function eAn(n,t,e){var i,r,c;n.ej()?(c=n.fj(),++n.j,n.Hi(t,n.oi(t,e)),i=n.Zi(3,null,e,t,c),n.bj()&&(r=n.cj(e,null))?(r.Ei(i),r.Fi()):n.$i(i)):(++n.j,n.Hi(t,n.oi(t,e)),n.bj()&&(r=n.cj(e,null))&&r.Fi())}function iAn(n){var t,e,i,r;for(r=n.length,t=null,i=0;i<r;i++)b1(i,n.length),GO(".*+?{[()|\\^$",YTn(e=n.charCodeAt(i)))>=0?(t||(t=new Pk,i>0&&cO(t,n.substr(0,i))),t.a+="\\",NX(t,e&QVn)):t&&NX(t,e&QVn);return t?t.a:n}function rAn(n){var t;if(!n.a)throw Hp(new Fy("IDataType class expected for layout option "+n.f));if(null==(t=C3(n.a)))throw Hp(new Fy("Couldn't create new instance of property '"+n.f+"'. "+r5n+(ED(bAt),bAt.k)+c5n));return BB(t,414)}function cAn(n){var t,e,i,r,c;return(c=n.eh())&&c.kh()&&(r=tfn(n,c))!=c?(e=n.Vg(),i=(t=n.Vg())>=0?n.Qg(null):n.eh().ih(n,-1-t,null,null),n.Rg(BB(r,49),e),i&&i.Fi(),n.Lg()&&n.Mg()&&e>-1&&ban(n,new nU(n,9,e,c,r)),r):c}function aAn(n){var t,e,i,r,c,a,u;for(c=0,r=n.f.e,e=0;e<r.c.length;++e)for(l1(e,r.c.length),a=BB(r.c[e],144),i=e+1;i<r.c.length;++i)l1(i,r.c.length),u=BB(r.c[i],144),t=W8(a.d,u.d)-n.a[a.b][u.b],c+=n.i[a.b][u.b]*t*t;return c}function uAn(n,t){var e;if(!Lx(t,(HXn(),kgt))&&(e=Ekn(BB(mMn(t,est),360),BB(mMn(n,kgt),163)),hon(t,est,e),!dAn(new oz(ZL(hbn(t).a.Kc(),new h)))))switch(e.g){case 1:hon(t,kgt,(Tbn(),Klt));break;case 2:hon(t,kgt,(Tbn(),Blt))}}function oAn(n,t){var e;mRn(n),n.a=(e=new ok,JT(new Rq(null,new w1(t.d,16)),new Od(e)),e),Mxn(n,BB(mMn(t.b,(HXn(),igt)),376)),kvn(n),OAn(n),$kn(n),jvn(n),jqn(n,t),JT(wnn(new Rq(null,Y0(SX(n.b).a)),new Wr),new Vr),t.a=!1,n.a=null}function sAn(){dMn.call(this,y6n,(tE(),dOt)),this.p=null,this.a=null,this.f=null,this.n=null,this.g=null,this.c=null,this.i=null,this.j=null,this.d=null,this.b=null,this.e=null,this.k=null,this.o=null,this.s=null,this.q=!1,this.r=!1}function hAn(){hAn=O,iAt=new MC(G1n,0),nAt=new MC("INSIDE_SELF_LOOPS",1),tAt=new MC("MULTI_EDGES",2),ZOt=new MC("EDGE_LABELS",3),eAt=new MC("PORTS",4),YOt=new MC("COMPOUND",5),QOt=new MC("CLUSTERS",6),JOt=new MC("DISCONNECTED",7)}function fAn(n,t){var e,i,r;if(0==t)return 0!=(1&n.a[0]);if(t<0)throw Hp(new Oy("Negative bit address"));if((r=t>>5)>=n.d)return n.e<0;if(e=n.a[r],t=1<<(31&t),n.e<0){if(r<(i=Icn(n)))return!1;e=i==r?-e:~e}return 0!=(e&t)}function lAn(n,t,e,i){var r;BB(e.b,65),BB(e.b,65),BB(i.b,65),BB(i.b,65),NH(r=XR(B$(BB(e.b,65).c),BB(i.b,65).c),HIn(BB(e.b,65),BB(i.b,65),r)),BB(i.b,65),BB(i.b,65),BB(i.b,65).c.a,r.a,BB(i.b,65).c.b,r.b,BB(i.b,65),Otn(i.a,new TB(n,t,i))}function bAn(n,t){var e,i,r,c,a,u,o;if(c=t.e)for(e=cAn(c),i=BB(n.g,674),a=0;a<n.i;++a)if(qvn(o=i[a])==e&&(!o.d&&(o.d=new $L(VAt,o,1)),r=o.d,(u=BB(e.ah(g_n(c,c.Cb,c.Db>>16)),15).Xc(c))<r.i))return bAn(n,BB(Wtn(r,u),87));return t}function wAn(n,t,e){var i,r=SWn,c=r[n],a=c instanceof Array?c[0]:null;c&&!a?MWn=c:(!(i=t&&t.prototype)&&(i=SWn[t]),(MWn=qJ(i)).hm=e,!t&&(MWn.im=C),r[n]=MWn);for(var u=3;u<arguments.length;++u)arguments[u].prototype=MWn;a&&(MWn.gm=a)}function dAn(n){for(var t;!BB(yX(n.a),47).Ob();){if(n.d=osn(n),!n.d)return!1;if(n.a=BB(n.d.Pb(),47),cL(n.a,39)){if(t=BB(n.a,39),n.a=t.a,!n.b&&(n.b=new Lp),d3(n.b,n.d),t.b)for(;!Wy(t.b);)d3(n.b,BB(gU(t.b),47));n.d=t.d}}return!0}function gAn(n,t){var e,i,r,c,a;for(c=null==t?0:n.b.se(t),i=null==(e=n.a.get(c))?new Array:e,a=0;a<i.length;a++)if(r=i[a],n.b.re(t,r.cd()))return 1==i.length?(i.length=0,vR(n.a,c)):i.splice(a,1),--n.c,oY(n.b),r.dd();return null}function pAn(n,t){var e,i,r,c;for(r=1,t.j=!0,c=null,i=new Wb(kbn(t));i.a<i.c.c.length;)e=BB(n0(i),213),n.c[e.c]||(n.c[e.c]=!0,c=Nbn(e,t),e.f?r+=pAn(n,c):c.j||e.a!=e.e.e-e.d.e||(e.f=!0,TU(n.p,e),r+=pAn(n,c)));return r}function vAn(n){var t,i,r;for(i=new Wb(n.a.a.b);i.a<i.c.c.length;)t=BB(n0(i),81),kW(0),(r=0)>0&&((!dA(n.a.c)||!t.n.d)&&(!gA(n.a.c)||!t.n.b)&&(t.g.d+=e.Math.max(0,r/2-.5)),(!dA(n.a.c)||!t.n.a)&&(!gA(n.a.c)||!t.n.c)&&(t.g.a-=r-1))}function mAn(n){var t,i,r,c,a;if(a=_Kn(n,c=new Np),t=BB(mMn(n,(hWn(),Elt)),10))for(r=new Wb(t.j);r.a<r.c.c.length;)GC(mMn(i=BB(n0(r),11),dlt))===GC(n)&&(a=e.Math.max(a,_Kn(i,c)));return 0==c.c.length||hon(n,blt,a),-1!=a?c:null}function yAn(n,t,e){var i,r,c,a,u,o;r=(i=(c=BB(xq(t.e,0),17).c).i).k,u=(a=(o=BB(xq(e.g,0),17).d).i).k,r==(uSn(),Put)?hon(n,(hWn(),hlt),BB(mMn(i,hlt),11)):hon(n,(hWn(),hlt),c),hon(n,(hWn(),flt),u==Put?BB(mMn(a,flt),11):o)}function kAn(n,t){var e,i,r,c;for(e=(c=dG(cbn(SVn,rV(dG(cbn(null==t?0:nsn(t),PVn)),15))))&n.b.length-1,r=null,i=n.b[e];i;r=i,i=i.a)if(i.d==c&&wW(i.i,t))return r?r.a=i.a:n.b[e]=i.a,kk(i.c,i.f),iv(i.b,i.e),--n.f,++n.e,!0;return!1}function jAn(n,t){var e,i,r,c,a;return t&=63,(i=0!=((e=n.h)&IQn))&&(e|=-1048576),t<22?(a=e>>t,c=n.m>>t|e<<22-t,r=n.l>>t|n.m<<22-t):t<44?(a=i?PQn:0,c=e>>t-22,r=n.m>>t-22|e<<44-t):(a=i?PQn:0,c=i?SQn:0,r=e>>t-44),M$(r&SQn,c&SQn,a&PQn)}function EAn(n){var t,i,r,c,a,u;for(this.c=new Np,this.d=n,r=RQn,c=RQn,t=_Qn,i=_Qn,u=spn(n,0);u.b!=u.d.c;)a=BB(b3(u),8),r=e.Math.min(r,a.a),c=e.Math.min(c,a.b),t=e.Math.max(t,a.a),i=e.Math.max(i,a.b);this.a=new UV(r,c,t-r,i-c)}function TAn(n,t){var e,i,r,c;for(i=new Wb(n.b);i.a<i.c.c.length;)for(c=new Wb(BB(n0(i),29).a);c.a<c.c.c.length;)for((r=BB(n0(c),10)).k==(uSn(),Sut)&&hFn(r,t),e=new oz(ZL(lbn(r).a.Kc(),new h));dAn(e);)vun(BB(U5(e),17),t)}function MAn(n){var t,e,i;this.c=n,i=BB(mMn(n,(HXn(),Udt)),103),t=Gy(MD(mMn(n,Edt))),e=Gy(MD(mMn(n,_pt))),i==(Ffn(),KPt)||i==FPt||i==BPt?this.b=t*e:this.b=1/(t*e),this.j=Gy(MD(mMn(n,Apt))),this.e=Gy(MD(mMn(n,Opt))),this.f=n.b.c.length}function SAn(n){var t,e;for(n.e=x8(ANt,hQn,25,n.p.c.length,15,1),n.k=x8(ANt,hQn,25,n.p.c.length,15,1),e=new Wb(n.p);e.a<e.c.c.length;)t=BB(n0(e),10),n.e[t.p]=F3(new oz(ZL(fbn(t).a.Kc(),new h))),n.k[t.p]=F3(new oz(ZL(lbn(t).a.Kc(),new h)))}function PAn(n){var t,e,i,r,c;for(i=0,n.q=new Np,t=new Rv,c=new Wb(n.p);c.a<c.c.c.length;){for((r=BB(n0(c),10)).p=i,e=new oz(ZL(lbn(r).a.Kc(),new h));dAn(e);)TU(t,BB(U5(e),17).d.i);t.a.Bc(r),WB(n.q,new $q(t)),t.a.$b(),++i}}function IAn(){IAn=O,Okt=new WA(20),Ckt=new XA((sWn(),XSt),Okt),xkt=new XA(LPt,20),jkt=new XA(cSt,dZn),$kt=new XA(pPt,iln(1)),Nkt=new XA(kPt,(hN(),!0)),Ekt=lSt,Mkt=_St,Skt=BSt,Pkt=qSt,Tkt=DSt,Ikt=USt,Akt=fPt,Ran(),Dkt=ykt,Lkt=vkt}function CAn(n,t){var e,i,r,c,a,u,o,s,h;if(n.a.f>0&&cL(t,42)&&(n.a.qj(),c=null==(o=(s=BB(t,42)).cd())?0:nsn(o),a=eR(n.a,c),e=n.a.d[a]))for(i=BB(e.g,367),h=e.i,u=0;u<h;++u)if((r=i[u]).Sh()==c&&r.Fb(s))return CAn(n,s),!0;return!1}function OAn(n){var t,e,i,r;for(r=BB(h6(n.a,(LEn(),Sst)),15).Kc();r.Ob();)iX(n,i=BB(r.Pb(),101),(e=(t=gz(i.k)).Hc((kUn(),sCt))?t.Hc(oCt)?t.Hc(SCt)?t.Hc(ICt)?null:$st:Nst:Lst:Ast)[0],(Irn(),xst),0),iX(n,i,e[1],Dst,1),iX(n,i,e[2],Rst,1)}function AAn(n,t){var e,i;Jxn(n,t,e=m_n(t)),iTn(n.a,BB(mMn(vW(t.b),(hWn(),Slt)),230)),bKn(n),DEn(n,t),i=x8(ANt,hQn,25,t.b.j.c.length,15,1),szn(n,t,(kUn(),sCt),i,e),szn(n,t,oCt,i,e),szn(n,t,SCt,i,e),szn(n,t,ICt,i,e),n.a=null,n.c=null,n.b=null}function $An(){$An=O,Sbn(),oEt=new $O(E4n,sEt=nEt),aEt=new $O(T4n,(hN(),!0)),iln(-1),iEt=new $O(M4n,iln(-1)),iln(-1),rEt=new $O(S4n,iln(-1)),uEt=new $O(P4n,!1),hEt=new $O(I4n,!0),cEt=new $O(C4n,!1),fEt=new $O(O4n,-1)}function LAn(n,t,e){switch(t){case 7:return!n.e&&(n.e=new h_(KOt,n,7,4)),sqn(n.e),!n.e&&(n.e=new h_(KOt,n,7,4)),void pX(n.e,BB(e,14));case 8:return!n.d&&(n.d=new h_(KOt,n,8,5)),sqn(n.d),!n.d&&(n.d=new h_(KOt,n,8,5)),void pX(n.d,BB(e,14))}zjn(n,t,e)}function NAn(n,t){var e,i,r,c,a;if(GC(t)===GC(n))return!0;if(!cL(t,15))return!1;if(a=BB(t,15),n.gc()!=a.gc())return!1;for(c=a.Kc(),i=n.Kc();i.Ob();)if(e=i.Pb(),r=c.Pb(),!(GC(e)===GC(r)||null!=e&&Nfn(e,r)))return!1;return!0}function xAn(n,t){var e,i,r,c;for((c=BB(P4(wnn(wnn(new Rq(null,new w1(t.b,16)),new Re),new _e),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15)).Jc(new Ke),e=0,r=c.Kc();r.Ob();)-1==(i=BB(r.Pb(),11)).p&&FAn(n,i,e++)}function DAn(n){switch(n.g){case 0:return new If;case 1:return new lf;case 2:return new ff;case 3:return new jC;case 4:return new KG;default:throw Hp(new Ky("No implementation is available for the node placer "+(null!=n.f?n.f:""+n.g)))}}function RAn(n){switch(n.g){case 0:return new _G;case 1:return new wf;case 2:return new rf;case 3:return new cf;case 4:return new TC;default:throw Hp(new Ky("No implementation is available for the cycle breaker "+(null!=n.f?n.f:""+n.g)))}}function _An(){_An=O,mjt=new $O(u4n,iln(0)),yjt=new $O(o4n,0),Hsn(),djt=new $O(s4n,gjt=sjt),iln(0),wjt=new $O(h4n,iln(1)),Bcn(),kjt=new $O(f4n,jjt=Xjt),D9(),Ejt=new $O(l4n,Tjt=ajt),Omn(),pjt=new $O(b4n,vjt=qjt)}function KAn(n,t,e){var i;i=null,t&&(i=t.d),Yjn(n,new dP(t.n.a-i.b+e.a,t.n.b-i.d+e.b)),Yjn(n,new dP(t.n.a-i.b+e.a,t.n.b+t.o.b+i.a+e.b)),Yjn(n,new dP(t.n.a+t.o.a+i.c+e.a,t.n.b-i.d+e.b)),Yjn(n,new dP(t.n.a+t.o.a+i.c+e.a,t.n.b+t.o.b+i.a+e.b))}function FAn(n,t,e){var i,r,c;for(t.p=e,c=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[new Hw(t),new Gw(t)])));dAn(c);)-1==(i=BB(U5(c),11)).p&&FAn(n,i,e);if(t.i.k==(uSn(),Put))for(r=new Wb(t.i.j);r.a<r.c.c.length;)(i=BB(n0(r),11))!=t&&-1==i.p&&FAn(n,i,e)}function BAn(n){var t,i,r,c,a;if(c=BB(P4($Z(a1(n)),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15),r=ZJn,c.gc()>=2)for(t=MD((i=c.Kc()).Pb());i.Ob();)a=t,t=MD(i.Pb()),r=e.Math.min(r,(kW(t),t-(kW(a),a)));return r}function HAn(n,t){var e,i,r,c,a;r5(i=new YT,t,i.c.b,i.c);do{for(Px(0!=i.b),e=BB(Atn(i,i.a.a),86),n.b[e.g]=1,c=spn(e.d,0);c.b!=c.d.c;)a=(r=BB(b3(c),188)).c,1==n.b[a.g]?DH(n.a,r):2==n.b[a.g]?n.b[a.g]=1:r5(i,a,i.c.b,i.c)}while(0!=i.b)}function qAn(n,t){var e,i,r;if(GC(t)===GC(yX(n)))return!0;if(!cL(t,15))return!1;if(i=BB(t,15),(r=n.gc())!=i.gc())return!1;if(cL(i,54)){for(e=0;e<r;e++)if(!wW(n.Xb(e),i.Xb(e)))return!1;return!0}return Uvn(n.Kc(),i.Kc())}function GAn(n,t){var e;if(0!=n.c.length){if(2==n.c.length)hFn((l1(0,n.c.length),BB(n.c[0],10)),(Xyn(),jIt)),hFn((l1(1,n.c.length),BB(n.c[1],10)),EIt);else for(e=new Wb(n);e.a<e.c.c.length;)hFn(BB(n0(e),10),t);n.c=x8(Ant,HWn,1,0,5,1)}}function zAn(n){var t,e;if(2!=n.c.length)throw Hp(new Fy("Order only allowed for two paths."));l1(0,n.c.length),t=BB(n.c[0],17),l1(1,n.c.length),e=BB(n.c[1],17),t.d.i!=e.c.i&&(n.c=x8(Ant,HWn,1,0,5,1),n.c[n.c.length]=e,n.c[n.c.length]=t)}function UAn(n,t){var e,i,r,c,a;for(i=new v4,c=S4(new Jy(n.g)).a.ec().Kc();c.Ob();){if(!(r=BB(c.Pb(),10))){OH(t,"There are no classes in a balanced layout.");break}(e=BB(lnn(i,a=n.j[r.p]),15))||Jgn(i,a,e=new Np),e.Fc(r)}return i}function XAn(n,t,e){var i,r,c,a;if(e)for(r=((i=new hz(e.a.length)).b-i.a)*i.c<0?(eS(),MNt):new XL(i);r.Ob();)(c=x2(e,BB(r.Pb(),19).a))&&(a=_en(R2(c,O6n),t),VW(n.f,a,c),q6n in c.a&&$in(a,R2(c,q6n)),STn(c,a),OIn(c,a))}function WAn(n,t){var e,i,r;for(OTn(t,"Port side processing",1),r=new Wb(n.a);r.a<r.c.c.length;)cBn(BB(n0(r),10));for(e=new Wb(n.b);e.a<e.c.c.length;)for(i=new Wb(BB(n0(e),29).a);i.a<i.c.c.length;)cBn(BB(n0(i),10));HSn(t)}function VAn(n,t,e){var i,r,c,a,u;if(!(r=n.f)&&(r=BB(n.a.a.ec().Kc().Pb(),57)),Fkn(r,t,e),1!=n.a.a.gc())for(i=t*e,a=n.a.a.ec().Kc();a.Ob();)(c=BB(a.Pb(),57))!=r&&((u=f3(c)).f.d?(c.d.d+=i+fJn,c.d.a-=i+fJn):u.f.a&&(c.d.a-=i+fJn))}function QAn(n,t,i,r,c){var a,u,o,s,h,f,l,b,w;return u=i-n,o=r-t,s=(a=e.Math.atan2(u,o))+JJn,h=a-JJn,f=c*e.Math.sin(s)+n,b=c*e.Math.cos(s)+t,l=c*e.Math.sin(h)+n,w=c*e.Math.cos(h)+t,u6(Pun(Gk(PMt,1),sVn,8,0,[new xI(f,b),new xI(l,w)]))}function YAn(n,t,i,r){var c,a,u,o,s,h,f,l;c=i,a=f=t;do{a=n.a[a.p],l=n.g[a.p],o=Gy(n.p[l.p])+Gy(n.d[a.p])-a.d.d,(s=Ain(a,r))&&(h=n.g[s.p],u=Gy(n.p[h.p])+Gy(n.d[s.p])+s.o.b+s.d.a,c=e.Math.min(c,o-(u+_$(n.k,a,s))))}while(f!=a);return c}function JAn(n,t,i,r){var c,a,u,o,s,h,f,l;c=i,a=f=t;do{a=n.a[a.p],l=n.g[a.p],u=Gy(n.p[l.p])+Gy(n.d[a.p])+a.o.b+a.d.a,(s=Kun(a,r))&&(h=n.g[s.p],o=Gy(n.p[h.p])+Gy(n.d[s.p])-s.d.d,c=e.Math.min(c,o-(u+_$(n.k,a,s))))}while(f!=a);return c}function ZAn(n,t){var e,i;return!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),null!=(i=cdn(n.o,t))?i:(cL(e=t.wg(),4)&&(null==e?(!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),Wdn(n.o,t)):(!n.o&&(n.o=new y9((IXn(),MOt),rAt,n,0)),vjn(n.o,t,e))),e)}function n$n(){n$n=O,CIt=new GI("H_LEFT",0),IIt=new GI("H_CENTER",1),AIt=new GI("H_RIGHT",2),DIt=new GI("V_TOP",3),xIt=new GI("V_CENTER",4),NIt=new GI("V_BOTTOM",5),$It=new GI("INSIDE",6),LIt=new GI("OUTSIDE",7),OIt=new GI("H_PRIORITY",8)}function t$n(n){var t,e,i,r,c,a,u;if((t=n.Hh(V9n))&&null!=(u=SD(cdn((!t.b&&(t.b=new Jx((gWn(),k$t),X$t,t)),t.b),"settingDelegates")))){for(e=new Np,c=0,a=(r=k_n(u,"\\w+")).length;c<a;++c)i=r[c],e.c[e.c.length]=i;return e}return SQ(),SQ(),set}function e$n(n,t){var e,i,r,c,a,u,o;if(!t.f)throw Hp(new Ky("The input edge is not a tree edge."));for(c=null,r=DWn,i=new Wb(n.d);i.a<i.c.c.length;)u=(e=BB(n0(i),213)).d,o=e.e,FIn(n,u,t)&&!FIn(n,o,t)&&(a=o.e-u.e-e.a)<r&&(r=a,c=e);return c}function i$n(n){var t,e,i,r,c,a;if(!(n.f.e.c.length<=1)){t=0,r=aAn(n),e=RQn;do{for(t>0&&(r=e),a=new Wb(n.f.e);a.a<a.c.c.length;)qy(TD(mMn(c=BB(n0(a),144),(rkn(),yat))))||(i=ZKn(n,c),UR(kO(c.d),i));e=aAn(n)}while(!JX(n,t++,r,e))}}function r$n(n,t){var e,i,r;for(OTn(t,"Layer constraint preprocessing",1),e=new Np,r=new M2(n.a,0);r.b<r.d.gc();)Px(r.b<r.d.gc()),Wun(i=BB(r.d.Xb(r.c=r.b++),10))&&(cTn(i),e.c[e.c.length]=i,fW(r));0==e.c.length||hon(n,(hWn(),nlt),e),HSn(t)}function c$n(n,t){var e,i,r,c,a;for(c=n.g.a,a=n.g.b,i=new Wb(n.d);i.a<i.c.c.length;)r=(e=BB(n0(i),70)).n,n.a==(Oun(),mst)||n.i==(kUn(),oCt)?r.a=c:n.a==yst||n.i==(kUn(),ICt)?r.a=c+n.j.a-e.o.a:r.a=c+(n.j.a-e.o.a)/2,r.b=a,UR(r,t),a+=e.o.b+n.e}function a$n(n,t,e){var i,r,c,a;for(OTn(e,"Processor set coordinates",1),n.a=0==t.b.b?1:t.b.b,c=null,i=spn(t.b,0);!c&&i.b!=i.d.c;)qy(TD(mMn(a=BB(b3(i),86),(qqn(),dkt))))&&(c=a,(r=a.e).a=BB(mMn(a,gkt),19).a,r.b=0);KSn(n,xun(c),mcn(e,1)),HSn(e)}function u$n(n,t,e){var i,r,c;for(OTn(e,"Processor determine the height for each level",1),n.a=0==t.b.b?1:t.b.b,r=null,i=spn(t.b,0);!r&&i.b!=i.d.c;)qy(TD(mMn(c=BB(b3(i),86),(qqn(),dkt))))&&(r=c);r&&Zxn(n,u6(Pun(Gk(Yyt,1),tZn,86,0,[r])),e),HSn(e)}function o$n(n,t){var e,i,r,c,a;(c=D2(n,"individualSpacings"))&&(!P8(t,(sWn(),IPt))&&(e=new Yu,Ypn(t,IPt,e)),r=BB(ZAn(t,IPt),373),i=null,(a=c)&&(i=new TT(a,jrn(a,x8(Qtt,sVn,2,0,6,1)))),i&&e5(i,new dC(a,r)))}function s$n(n,t){var e,i,r,c,a,u;return c=null,(J6n in(a=n).a||Z6n in a.a||D6n in a.a)&&(u=qun(t),i=D2(a,J6n),Own(new Hg(u).a,i),r=D2(a,Z6n),Cwn(new Jg(u).a,r),e=N2(a,D6n),PEn(new tp(u).a,e),c=e),c}function h$n(n,t){var e,i,r;if(t===n)return!0;if(cL(t,543)){if(r=BB(t,835),n.a.d!=r.a.d||EV(n).gc()!=EV(r).gc())return!1;for(i=EV(r).Kc();i.Ob();)if(c1(n,(e=BB(i.Pb(),416)).a.cd())!=BB(e.a.dd(),14).gc())return!1;return!0}return!1}function f$n(n){var t,e,i,r;return t=i=BB(n.a,19).a,e=r=BB(n.b,19).a,0==i&&0==r?e-=1:-1==i&&r<=0?(t=0,e-=2):i<=0&&r>0?(t-=1,e-=1):i>=0&&r<0?(t+=1,e+=1):i>0&&r>=0?(t-=1,e+=1):(t+=1,e-=1),new rC(iln(t),iln(e))}function l$n(n,t){return n.c<t.c?-1:n.c>t.c?1:n.b<t.b?-1:n.b>t.b?1:n.a!=t.a?nsn(n.a)-nsn(t.a):n.d==(Q4(),Hmt)&&t.d==Bmt?-1:n.d==Bmt&&t.d==Hmt?1:0}function b$n(n,t){var e,i,r,c,a;return a=(c=t.a).c.i==t.b?c.d:c.c,i=c.c.i==t.b?c.c:c.d,(r=zwn(n.a,a,i))>0&&r<ZJn?(e=YAn(n.a,i.i,r,n.c),ren(n.a,i.i,-e),e>0):r<0&&-r<ZJn&&(e=JAn(n.a,i.i,-r,n.c),ren(n.a,i.i,e),e>0)}function w$n(n,t,e,i){var r,c,a,u,o,s;for(r=(t-n.d)/n.c.c.length,c=0,n.a+=e,n.d=t,s=new Wb(n.c);s.a<s.c.c.length;)u=(o=BB(n0(s),33)).g,a=o.f,Pen(o,o.i+c*r),Ien(o,o.j+i*e),Sen(o,o.g+r),Men(o,n.a),++c,lIn(o,new xI(o.g,o.f),new xI(u,a))}function d$n(n){var t,e,i,r,c,a,u;if(null==n)return null;for(u=n.length,a=x8(NNt,v6n,25,r=(u+1)/2|0,15,1),u%2!=0&&(a[--r]=ZDn((b1(u-1,n.length),n.charCodeAt(u-1)))),e=0,i=0;e<r;++e)t=ZDn(fV(n,i++)),c=ZDn(fV(n,i++)),a[e]=(t<<4|c)<<24>>24;return a}function g$n(n){if(n.pe()){var t=n.c;return t.qe()?n.o="["+t.n:t.pe()?n.o="["+t.ne():n.o="[L"+t.ne()+";",n.b=t.me()+"[]",void(n.k=t.oe()+"[]")}var e=n.j,i=n.d;i=i.split("/"),n.o=Fdn(".",[e,Fdn("$",i)]),n.b=Fdn(".",[e,Fdn(".",i)]),n.k=i[i.length-1]}function p$n(n,t){var e,i,r,c,a;for(a=null,c=new Wb(n.e.a);c.a<c.c.c.length;)if((r=BB(n0(c),121)).b.a.c.length==r.g.a.c.length){for(i=r.e,a=ePn(r),e=r.e-BB(a.a,19).a+1;e<r.e+BB(a.b,19).a;e++)t[e]<t[i]&&(i=e);t[i]<t[r.e]&&(--t[r.e],++t[i],r.e=i)}}function v$n(n){var t,i,r,c,a,u,o;for(r=RQn,i=_Qn,t=new Wb(n.e.b);t.a<t.c.c.length;)for(a=new Wb(BB(n0(t),29).a);a.a<a.c.c.length;)c=BB(n0(a),10),u=(o=Gy(n.p[c.p]))+Gy(n.b[n.g[c.p].p]),r=e.Math.min(r,o),i=e.Math.max(i,u);return i-r}function m$n(n,t,e,i){var r,c,a,u,o,s;for(o=null,u=0,s=(r=j_n(n,t)).gc();u<s;++u)if(m_(i,kV(B7(n,c=BB(r.Xb(u),170)))))if(a=jV(B7(n,c)),null==e){if(null==a)return c;!o&&(o=c)}else{if(m_(e,a))return c;null==a&&!o&&(o=c)}return null}function y$n(n,t,e,i){var r,c,a,u,o,s;for(o=null,u=0,s=(r=E_n(n,t)).gc();u<s;++u)if(m_(i,kV(B7(n,c=BB(r.Xb(u),170)))))if(a=jV(B7(n,c)),null==e){if(null==a)return c;!o&&(o=c)}else{if(m_(e,a))return c;null==a&&!o&&(o=c)}return null}function k$n(n,t,e){var i,r,c,a,u,o;if(a=new go,u=axn(n.e.Tg(),t),i=BB(n.g,119),ZM(),BB(t,66).Oj())for(c=0;c<n.i;++c)r=i[c],u.rl(r.ak())&&f9(a,r);else for(c=0;c<n.i;++c)r=i[c],u.rl(r.ak())&&(o=r.dd(),f9(a,e?FCn(n,t,c,a.i,o):o));return N3(a)}function j$n(n,t){var e,i,r,c;for(e=new Hbn(uht),$Pn(),r=0,c=(i=Pun(Gk(uht,1),$Vn,227,0,[Zst,tht,Jst,nht,eht,Yst])).length;r<c;++r)wR(e,i[r],new Np);return JT($V(AV(wnn(new Rq(null,new w1(n.b,16)),new Ze),new ni),new hd(t)),new fd(e)),e}function E$n(n,t,i){var r,c,a,u,o,s,h,f;for(a=t.Kc();a.Ob();)s=(c=BB(a.Pb(),33)).i+c.g/2,f=c.j+c.f/2,o=s-((u=n.f).i+u.g/2),h=f-(u.j+u.f/2),r=e.Math.sqrt(o*o+h*h),o*=n.e/r,h*=n.e/r,i?(s-=o,f-=h):(s+=o,f+=h),Pen(c,s-c.g/2),Ien(c,f-c.f/2)}function T$n(n){var t,e,i;if(!n.c&&null!=n.b){for(t=n.b.length-4;t>=0;t-=2)for(e=0;e<=t;e+=2)(n.b[e]>n.b[e+2]||n.b[e]===n.b[e+2]&&n.b[e+1]>n.b[e+3])&&(i=n.b[e+2],n.b[e+2]=n.b[e],n.b[e]=i,i=n.b[e+3],n.b[e+3]=n.b[e+1],n.b[e+1]=i);n.c=!0}}function M$n(n,t){var e,i,r,c,a,u;for(c=(1==t?Wat:Xat).a.ec().Kc();c.Ob();)for(r=BB(c.Pb(),103),u=BB(h6(n.f.c,r),21).Kc();u.Ob();)switch(a=BB(u.Pb(),46),i=BB(a.b,81),e=BB(a.a,189).c,r.g){case 2:case 1:i.g.d+=e;break;case 4:case 3:i.g.c+=e}}function S$n(n,t){var e,i,r,c,a,u,o,s,h;for(s=-1,h=0,u=0,o=(a=n).length;u<o;++u){for(c=a[u],e=new kH(-1==s?n[0]:n[s],t,(Mhn(),uvt)),i=0;i<c.length;i++)for(r=i+1;r<c.length;r++)Lx(c[i],(hWn(),wlt))&&Lx(c[r],wlt)&&fXn(e,c[i],c[r])>0&&++h;++s}return h}function P$n(n){var t;return(t=new lN(nE(n.gm))).a+="@",oO(t,(nsn(n)>>>0).toString(16)),n.kh()?(t.a+=" (eProxyURI: ",uO(t,n.qh()),n.$g()&&(t.a+=" eClass: ",uO(t,n.$g())),t.a+=")"):n.$g()&&(t.a+=" (eClass: ",uO(t,n.$g()),t.a+=")"),t.a}function I$n(n){var t,e,i;if(n.e)throw Hp(new Fy((ED(git),AYn+git.k+$Yn)));for(n.d==(Ffn(),BPt)&&Tzn(n,KPt),e=new Wb(n.a.a);e.a<e.c.c.length;)(t=BB(n0(e),307)).g=t.i;for(i=new Wb(n.a.b);i.a<i.c.c.length;)BB(n0(i),57).i=_Qn;return n.b.Le(n),n}function C$n(n,t){var e,i,r,c,a;if(t<2*n.b)throw Hp(new Ky("The knot vector must have at least two time the dimension elements."));for(n.f=1,r=0;r<n.b;r++)WB(n.e,0);for(e=a=t+1-2*n.b,c=1;c<a;c++)WB(n.e,c/e);if(n.d)for(i=0;i<n.b;i++)WB(n.e,1)}function O$n(n,t){var e,i,r,c,a;if(c=t,!(a=BB(Uin(PX(n.i),c),33)))throw Hp(new ek("Unable to find elk node for json object '"+R2(c,q6n)+"' Panic!"));i=N2(c,"edges"),LCn((e=new uC(n,a)).a,e.b,i),r=N2(c,A6n),Dkn(new Ng(n).a,r)}function A$n(n,t,e,i){var r,c,a,u,o;if(null!=i){if(r=n.d[t])for(c=r.g,o=r.i,u=0;u<o;++u)if((a=BB(c[u],133)).Sh()==e&&Nfn(i,a.cd()))return u}else if(r=n.d[t])for(c=r.g,o=r.i,u=0;u<o;++u)if(GC((a=BB(c[u],133)).cd())===GC(i))return u;return-1}function $$n(n,t){var e,i;return cL(e=null==t?qC(AY(n.f,null)):hS(n.g,t),235)?((i=BB(e,235)).Qh(),i):cL(e,498)?((i=BB(e,1938).a)&&(null==i.yb||(null==t?jIn(n.f,null,i):ubn(n.g,t,i))),i):null}function L$n(n){var t,e,i,r,c,a,u;if(_Dn(),null==n)return null;if((r=n.length)%2!=0)return null;for(t=V7(n),e=x8(NNt,v6n,25,c=r/2|0,15,1),i=0;i<c;i++){if(-1==(a=QLt[t[2*i]]))return null;if(-1==(u=QLt[t[2*i+1]]))return null;e[i]=(a<<4|u)<<24>>24}return e}function N$n(n,t,e){var i,r,c;if(!(r=BB(oV(n.i,t),306)))if(r=new wtn(n.d,t,e),mG(n.i,t,r),agn(t))EL(n.a,t.c,t.b,r);else switch(c=LPn(t),i=BB(oV(n.p,c),244),c.g){case 1:case 3:r.j=!0,jy(i,t.b,r);break;case 4:case 2:r.k=!0,jy(i,t.c,r)}return r}function x$n(n,t,e,i){var r,c,a,u,o,s;if(u=new go,o=axn(n.e.Tg(),t),r=BB(n.g,119),ZM(),BB(t,66).Oj())for(a=0;a<n.i;++a)c=r[a],o.rl(c.ak())&&f9(u,c);else for(a=0;a<n.i;++a)c=r[a],o.rl(c.ak())&&(s=c.dd(),f9(u,i?FCn(n,t,a,u.i,s):s));return Qwn(u,e)}function D$n(n,t){var i,r,c,a,u,o;if((r=n.b[t.p])>=0)return r;for(c=1,a=new Wb(t.j);a.a<a.c.c.length;)for(i=new Wb(BB(n0(a),11).g);i.a<i.c.c.length;)t!=(o=BB(n0(i),17).d.i)&&(u=D$n(n,o),c=e.Math.max(c,u+1));return iwn(n,t,c),c}function R$n(n,t,e){var i,r,c;for(i=1;i<n.c.length;i++){for(l1(i,n.c.length),c=BB(n.c[i],10),r=i;r>0&&t.ue((l1(r-1,n.c.length),BB(n.c[r-1],10)),c)>0;)c5(n,r,(l1(r-1,n.c.length),BB(n.c[r-1],10))),--r;l1(r,n.c.length),n.c[r]=c}e.a=new xp,e.b=new xp}function _$n(n,t,e){var i,r,c,a,u,o,s;for(s=new Y_(i=BB(t.e&&t.e(),9),BB(SR(i,i.length),9),0),a=0,u=(c=k_n(e,"[\\[\\]\\s,]+")).length;a<u;++a)if(0!=RMn(r=c[a]).length){if(null==(o=HCn(n,r)))return null;orn(s,BB(o,22))}return s}function K$n(n){var t,i,r;for(i=new Wb(n.a.a.b);i.a<i.c.c.length;)t=BB(n0(i),81),kW(0),(r=0)>0&&((!dA(n.a.c)||!t.n.d)&&(!gA(n.a.c)||!t.n.b)&&(t.g.d-=e.Math.max(0,r/2-.5)),(!dA(n.a.c)||!t.n.a)&&(!gA(n.a.c)||!t.n.c)&&(t.g.a+=e.Math.max(0,r-1)))}function F$n(n,t,e){var i;if(2==(n.c-n.b&n.a.length-1))t==(kUn(),sCt)||t==oCt?(jtn(BB(Eon(n),15),(Xyn(),jIt)),jtn(BB(Eon(n),15),EIt)):(jtn(BB(Eon(n),15),(Xyn(),EIt)),jtn(BB(Eon(n),15),jIt));else for(i=new bV(n);i.a!=i.b;)jtn(BB(Khn(i),15),e)}function B$n(n,t){var e,i,r,c,a,u;for(a=new M2(i=HB(new sp(n)),i.c.length),u=new M2(r=HB(new sp(t)),r.c.length),c=null;a.b>0&&u.b>0&&(Px(a.b>0),e=BB(a.a.Xb(a.c=--a.b),33),Px(u.b>0),e==BB(u.a.Xb(u.c=--u.b),33));)c=e;return c}function H$n(n,t){var i,r,c,a;return c=n.a*aYn+1502*n.b,a=n.b*aYn+11,c+=i=e.Math.floor(a*uYn),a-=i*oYn,c%=oYn,n.a=c,n.b=a,t<=24?e.Math.floor(n.a*Oet[t]):((r=n.a*(1<<t-24)+e.Math.floor(n.b*Aet[t]))>=2147483648&&(r-=XQn),r)}function q$n(n,t,e){var i,r,c,a;w0(n,t)>w0(n,e)?(i=abn(e,(kUn(),oCt)),n.d=i.dc()?0:uq(BB(i.Xb(0),11)),a=abn(t,ICt),n.b=a.dc()?0:uq(BB(a.Xb(0),11))):(r=abn(e,(kUn(),ICt)),n.d=r.dc()?0:uq(BB(r.Xb(0),11)),c=abn(t,oCt),n.b=c.dc()?0:uq(BB(c.Xb(0),11)))}function G$n(n){var t,e,i,r,c,a,u;if(n&&(t=n.Hh(V9n))&&null!=(a=SD(cdn((!t.b&&(t.b=new Jx((gWn(),k$t),X$t,t)),t.b),"conversionDelegates")))){for(u=new Np,r=0,c=(i=k_n(a,"\\w+")).length;r<c;++r)e=i[r],u.c[u.c.length]=e;return u}return SQ(),SQ(),set}function z$n(n,t){var e,i,r,c;for(e=n.o.a,c=BB(BB(h6(n.r,t),21),84).Kc();c.Ob();)(r=BB(c.Pb(),111)).e.a=e*Gy(MD(r.b.We(Lrt))),r.e.b=(i=r.b).Xe((sWn(),aPt))?i.Hf()==(kUn(),sCt)?-i.rf().b-Gy(MD(i.We(aPt))):Gy(MD(i.We(aPt))):i.Hf()==(kUn(),sCt)?-i.rf().b:0}function U$n(n){var t,e,i,r,c,a,u,o;t=!0,r=null,c=null;n:for(o=new Wb(n.a);o.a<o.c.c.length;)for(i=new oz(ZL(fbn(u=BB(n0(o),10)).a.Kc(),new h));dAn(i);){if(e=BB(U5(i),17),r&&r!=u){t=!1;break n}if(r=u,a=e.c.i,c&&c!=a){t=!1;break n}c=a}return t}function X$n(n,t,e){var i,r,c,a,u,o;for(c=-1,u=-1,a=0;a<t.c.length&&(l1(a,t.c.length),!((r=BB(t.c[a],329)).c>n.c));a++)r.a>=n.s&&(c<0&&(c=a),u=a);return o=(n.s+n.c)/2,c>=0&&(o=qM((l1(i=YRn(n,t,c,u),t.c.length),BB(t.c[i],329))),lOn(t,i,e)),o}function W$n(){W$n=O,lEt=new XA((sWn(),cSt),1.3),gEt=jSt,CEt=new WA(15),IEt=new XA(XSt,CEt),$Et=new XA(LPt,15),bEt=hSt,jEt=_St,EEt=BSt,TEt=qSt,kEt=DSt,MEt=USt,OEt=fPt,$An(),PEt=oEt,yEt=aEt,SEt=uEt,AEt=hEt,pEt=cEt,vEt=ISt,mEt=CSt,dEt=rEt,wEt=iEt,LEt=fEt}function V$n(n,t,e){var i,r,c,a,u;for(Bin(r=new jo,(kW(t),t)),!r.b&&(r.b=new Jx((gWn(),k$t),X$t,r)),u=r.b,a=1;a<e.length;a+=2)vjn(u,e[a-1],e[a]);for(!n.Ab&&(n.Ab=new eU(_At,n,0,3)),i=n.Ab,c=0;c<0;++c)i=mW(BB(Wtn(i,i.i-1),590));f9(i,r)}function Q$n(n,t,e){var i,r,c;for(LD.call(this,new Np),this.a=t,this.b=e,this.e=n,n.b&&VBn(n),i=n.a,this.d=JV(i.a,this.a),this.c=JV(i.b,this.b),obn(this,this.d,this.c),mCn(this),c=this.e.e.a.ec().Kc();c.Ob();)(r=BB(c.Pb(),266)).c.c.length>0&&xqn(this,r)}function Y$n(n,t,e,i,r,c){var a,u,o;if(!r[t.b]){for(r[t.b]=!0,!(a=i)&&(a=new y6),WB(a.e,t),o=c[t.b].Kc();o.Ob();)(u=BB(o.Pb(),282)).d!=e&&u.c!=e&&(u.c!=t&&Y$n(n,u.c,t,a,r,c),u.d!=t&&Y$n(n,u.d,t,a,r,c),WB(a.c,u),gun(a.d,u.b));return a}return null}function J$n(n){var t,e,i;for(t=0,e=new Wb(n.e);e.a<e.c.c.length;)o5(new Rq(null,new w1(BB(n0(e),17).b,16)),new pe)&&++t;for(i=new Wb(n.g);i.a<i.c.c.length;)o5(new Rq(null,new w1(BB(n0(i),17).b,16)),new ve)&&++t;return t>=2}function Z$n(n,t){var e,i,r,c;for(OTn(t,"Self-Loop pre-processing",1),i=new Wb(n.a);i.a<i.c.c.length;)_bn(e=BB(n0(i),10))&&(c=new Ogn(e),hon(e,(hWn(),Olt),c),kKn(c),JT($V(wnn(new Rq(null,new w1((r=c).d,16)),new Hi),new qi),new Gi),ixn(r));HSn(t)}function nLn(n,t,e,i,r){var c,a,u,o,s;for(c=n.c.d.j,a=BB(Dpn(e,0),8),s=1;s<e.b;s++)o=BB(Dpn(e,s),8),r5(i,a,i.c.b,i.c),u=kL(UR(new wA(a),o),.5),UR(u,kL(new XZ(hsn(c)),r)),r5(i,u,i.c.b,i.c),a=o,c=0==t?Mln(c):Eln(c);DH(i,(Px(0!=e.b),BB(e.c.b.c,8)))}function tLn(n){return n$n(),!(Ian(OJ(EG($It,Pun(Gk(GIt,1),$Vn,93,0,[LIt])),n))>1||Ian(OJ(EG(CIt,Pun(Gk(GIt,1),$Vn,93,0,[IIt,AIt])),n))>1||Ian(OJ(EG(DIt,Pun(Gk(GIt,1),$Vn,93,0,[xIt,NIt])),n))>1)}function eLn(n,t){var e,i,r;return(e=t.Hh(n.a))&&null!=(r=SD(cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),"affiliation")))?-1==(i=mN(r,YTn(35)))?uln(n,az(n,Utn(t.Hj())),r):0==i?uln(n,null,r.substr(1)):uln(n,r.substr(0,i),r.substr(i+1)):null}function iLn(n){var t,e;try{return null==n?zWn:Bbn(n)}catch(i){if(cL(i=lun(i),102))return t=i,e=nE(tsn(n))+"@"+($T(),(evn(n)>>>0).toString(16)),_gn(jun(),(lM(),"Exception during lenientFormat for "+e),t),"<"+e+" threw "+nE(t.gm)+">";throw Hp(i)}}function rLn(n){switch(n.g){case 0:return new of;case 1:return new ef;case 2:return new $M;case 3:return new Cc;case 4:return new RR;case 5:return new sf;default:throw Hp(new Ky("No implementation is available for the layerer "+(null!=n.f?n.f:""+n.g)))}}function cLn(n,t,e){var i,r,c;for(c=new Wb(n.t);c.a<c.c.c.length;)(i=BB(n0(c),268)).b.s<0&&i.c>0&&(i.b.n-=i.c,i.b.n<=0&&i.b.u>0&&DH(t,i.b));for(r=new Wb(n.i);r.a<r.c.c.length;)(i=BB(n0(r),268)).a.s<0&&i.c>0&&(i.a.u-=i.c,i.a.u<=0&&i.a.n>0&&DH(e,i.a))}function aLn(n){var t,e,i;if(null==n.g&&(n.d=n.si(n.f),f9(n,n.d),n.c))return n.f;if(i=(t=BB(n.g[n.i-1],47)).Pb(),n.e=t,(e=n.si(i)).Ob())n.d=e,f9(n,e);else for(n.d=null;!t.Ob()&&($X(n.g,--n.i,null),0!=n.i);)t=BB(n.g[n.i-1],47);return i}function uLn(n,t){var e,i,r,c,a,u;if(r=(i=t).ak(),$xn(n.e,r)){if(r.hi()&&G3(n,r,i.dd()))return!1}else for(u=axn(n.e.Tg(),r),e=BB(n.g,119),c=0;c<n.i;++c)if(a=e[c],u.rl(a.ak()))return!Nfn(a,i)&&(BB(ovn(n,c,t),72),!0);return f9(n,t)}function oLn(n,t,i,r){var c,a,u;for(Bl(c=new $vn(n),(uSn(),Sut)),hon(c,(hWn(),dlt),t),hon(c,Plt,r),hon(c,(HXn(),ept),(QEn(),XIt)),hon(c,hlt,t.c),hon(c,flt,t.d),zxn(t,c),u=e.Math.floor(i/2),a=new Wb(c.j);a.a<a.c.c.length;)BB(n0(a),11).n.b=u;return c}function sLn(n,t){var e,i,r,c,a,u,o,s,h;for(o=sx(n.c-n.b&n.a.length-1),s=null,h=null,c=new bV(n);c.a!=c.b;)r=BB(Khn(c),10),e=(u=BB(mMn(r,(hWn(),hlt)),11))?u.i:null,i=(a=BB(mMn(r,flt),11))?a.i:null,s==e&&h==i||(GAn(o,t),s=e,h=i),o.c[o.c.length]=r;GAn(o,t)}function hLn(n){var t,i,r,c,a,u;for(t=0,i=new Wb(n.a);i.a<i.c.c.length;)for(c=new oz(ZL(lbn(BB(n0(i),10)).a.Kc(),new h));dAn(c);)n==(r=BB(U5(c),17)).d.i.c&&r.c.j==(kUn(),ICt)&&(a=g1(r.c).b,u=g1(r.d).b,t=e.Math.max(t,e.Math.abs(u-a)));return t}function fLn(n,t,e){var i,r;OTn(e,"Remove overlaps",1),e.n&&t&&y0(e,o2(t),(Bsn(),uOt)),i=BB(ZAn(t,(wD(),Vkt)),33),n.f=i,n.a=Evn(BB(ZAn(t,(Uyn(),Rjt)),293)),ib(n,(kW(r=MD(ZAn(t,(sWn(),LPt)))),r)),Xzn(n,t,wDn(i),e),e.n&&t&&y0(e,o2(t),(Bsn(),uOt))}function lLn(n,t,i){switch(i.g){case 1:return new xI(t.a,e.Math.min(n.d.b,t.b));case 2:return new xI(e.Math.max(n.c.a,t.a),t.b);case 3:return new xI(t.a,e.Math.max(n.c.b,t.b));case 4:return new xI(e.Math.min(t.a,n.d.a),t.b)}return new xI(t.a,t.b)}function bLn(n,t,e,i){var r,c,a,u,o,s,h,f,l;for(f=i?(kUn(),ICt):(kUn(),oCt),r=!1,s=0,h=(o=t[e]).length;s<h;++s)L_(BB(mMn(u=o[s],(HXn(),ept)),98))||(a=u.e,(l=!abn(u,f).dc()&&!!a)&&(c=qEn(a),n.b=new zEn(c,i?0:c.length-1)),r|=cKn(n,u,f,l));return r}function wLn(n){var t,e,i;for(WB(t=sx(1+(!n.c&&(n.c=new eU(XOt,n,9,9)),n.c).i),(!n.d&&(n.d=new h_(KOt,n,8,5)),n.d)),i=new AL((!n.c&&(n.c=new eU(XOt,n,9,9)),n.c));i.e!=i.i.gc();)WB(t,(!(e=BB(kpn(i),118)).d&&(e.d=new h_(KOt,e,8,5)),e.d));return yX(t),new OO(t)}function dLn(n){var t,e,i;for(WB(t=sx(1+(!n.c&&(n.c=new eU(XOt,n,9,9)),n.c).i),(!n.e&&(n.e=new h_(KOt,n,7,4)),n.e)),i=new AL((!n.c&&(n.c=new eU(XOt,n,9,9)),n.c));i.e!=i.i.gc();)WB(t,(!(e=BB(kpn(i),118)).e&&(e.e=new h_(KOt,e,7,4)),e.e));return yX(t),new OO(t)}function gLn(n){var t,e,i,r;if(null==n)return null;if(i=FBn(n,!0),r=x7n.length,m_(i.substr(i.length-r,r),x7n))if(4==(e=i.length)){if(b1(0,i.length),43==(t=i.charCodeAt(0)))return HLt;if(45==t)return BLt}else if(3==e)return HLt;return bSn(i)}function pLn(n){var t,e,i,r;for(t=0,e=0,r=new Wb(n.j);r.a<r.c.c.length;)if(t=dG(rbn(t,q6(AV(new Rq(null,new w1((i=BB(n0(r),11)).e,16)),new Yc)))),e=dG(rbn(e,q6(AV(new Rq(null,new w1(i.g,16)),new Jc)))),t>1||e>1)return 2;return t+e==1?2:0}function vLn(n,t,e){var i,r,c,a;for(OTn(e,"ELK Force",1),qy(TD(ZAn(t,(fRn(),Wct))))||jJ(new Tw((GM(),new Dy(t)))),kkn(a=fon(t)),zon(n,BB(mMn(a,Gct),424)),r=(c=HFn(n.a,a)).Kc();r.Ob();)i=BB(r.Pb(),231),P_n(n.b,i,mcn(e,1/c.gc()));SUn(a=GUn(c)),HSn(e)}function mLn(n,t){var e,i,r;if(OTn(t,"Breaking Point Processor",1),Ozn(n),qy(TD(mMn(n,(HXn(),Gpt))))){for(i=new Wb(n.b);i.a<i.c.c.length;)for(e=0,r=new Wb(BB(n0(i),29).a);r.a<r.c.c.length;)BB(n0(r),10).p=e++;oHn(n),Hxn(n,!0),Hxn(n,!1)}HSn(t)}function yLn(n,t,e){var i,r,c,a,u;for(a=n.c,c=(e.q?e.q:(SQ(),SQ(),het)).vc().Kc();c.Ob();)r=BB(c.Pb(),42),!jE(AV(new Rq(null,new w1(a,16)),new aw(new LI(t,r)))).sd((dM(),tit))&&(cL(u=r.dd(),4)&&null!=(i=Jdn(u))&&(u=i),t.Ye(BB(r.cd(),146),u))}function kLn(n,t){var e,i,r,c;if(t){for(c=!(r=cL(n.Cb,88)||cL(n.Cb,99))&&cL(n.Cb,322),e=new AL((!t.a&&(t.a=new aG(t,VAt,t)),t.a));e.e!=e.i.gc();)if(i=lFn(BB(kpn(e),87)),r?cL(i,88):c?cL(i,148):i)return i;return r?(gWn(),d$t):(gWn(),l$t)}return null}function jLn(n,t){var e,i,r,c,a;for(OTn(t,"Constraints Postprocessor",1),c=0,r=new Wb(n.b);r.a<r.c.c.length;){for(a=0,i=new Wb(BB(n0(r),29).a);i.a<i.c.c.length;)(e=BB(n0(i),10)).k==(uSn(),Iut)&&(hon(e,(HXn(),jgt),iln(c)),hon(e,Bdt,iln(a)),++a);++c}HSn(t)}function ELn(n,t,e,i){var r,c,a,u,o,s;for(XR(u=new xI(e,i),BB(mMn(t,(qqn(),nkt)),8)),s=spn(t.b,0);s.b!=s.d.c;)UR((o=BB(b3(s),86)).e,u),DH(n.b,o);for(a=spn(t.a,0);a.b!=a.d.c;){for(r=spn((c=BB(b3(a),188)).a,0);r.b!=r.d.c;)UR(BB(b3(r),8),u);DH(n.a,c)}}function TLn(n,t,e){var i,r,c;if(!(c=Fqn((CPn(),Z$t),n.Tg(),t)))throw Hp(new Ky(r6n+t.ne()+c6n));if(ZM(),!BB(c,66).Oj()&&!(c=Z1(B7(Z$t,c))))throw Hp(new Ky(r6n+t.ne()+c6n));r=BB((i=n.Yg(c))>=0?n._g(i,!0,!0):cOn(n,c,!0),153),BB(r,215).ml(t,e)}function MLn(n,t){var e,i,r,c,a;for(e=new Np,r=wnn(new Rq(null,new w1(n,16)),new Ea),c=wnn(new Rq(null,new w1(n,16)),new Ta),a=M7(H6(LV(SNn(Pun(Gk(eit,1),HWn,833,0,[r,c])),new Ma))),i=1;i<a.length;i++)a[i]-a[i-1]>=2*t&&WB(e,new kB(a[i-1]+t,a[i]-t));return e}function SLn(n,t,e){OTn(e,"Eades radial",1),e.n&&t&&y0(e,o2(t),(Bsn(),uOt)),n.d=BB(ZAn(t,(wD(),Vkt)),33),n.c=Gy(MD(ZAn(t,(Uyn(),Djt)))),n.e=Evn(BB(ZAn(t,Rjt),293)),n.a=lwn(BB(ZAn(t,Kjt),426)),n.b=qjn(BB(ZAn(t,$jt),340)),rjn(n),e.n&&t&&y0(e,o2(t),(Bsn(),uOt))}function PLn(n,t,e){var i,r,c,a,u;if(e)for(c=((i=new hz(e.a.length)).b-i.a)*i.c<0?(eS(),MNt):new XL(i);c.Ob();)(r=x2(e,BB(c.Pb(),19).a))&&($in(a=$3(n,(tE(),u=new Em,!!t&&BLn(u,t),u),r),R2(r,q6n)),STn(r,a),OIn(r,a),xon(n,r,a))}function ILn(n){var t,e,i,r;if(!n.j){if(r=new Co,null==(t=P$t).a.zc(n,t)){for(i=new AL(kY(n));i.e!=i.i.gc();)pX(r,ILn(e=BB(kpn(i),26))),f9(r,e);t.a.Bc(n)}chn(r),n.j=new NO((BB(Wtn(QQ((QX(),t$t).o),11),18),r.i),r.g),P5(n).b&=-33}return n.j}function CLn(n){var t,e,i,r;if(null==n)return null;if(i=FBn(n,!0),r=x7n.length,m_(i.substr(i.length-r,r),x7n))if(4==(e=i.length)){if(b1(0,i.length),43==(t=i.charCodeAt(0)))return GLt;if(45==t)return qLt}else if(3==e)return GLt;return new Dv(i)}function OLn(n){var t,e,i;return 0!=((e=n.l)&e-1)||0!=((i=n.m)&i-1)||0!=((t=n.h)&t-1)||0==t&&0==i&&0==e?-1:0==t&&0==i&&0!=e?gin(e):0==t&&0!=i&&0==e?gin(i)+22:0!=t&&0==i&&0==e?gin(t)+44:-1}function ALn(n,t){var e,i,r,c;for(OTn(t,"Edge joining",1),e=qy(TD(mMn(n,(HXn(),Dpt)))),i=new Wb(n.b);i.a<i.c.c.length;)for(c=new M2(BB(n0(i),29).a,0);c.b<c.d.gc();)Px(c.b<c.d.gc()),(r=BB(c.d.Xb(c.c=c.b++),10)).k==(uSn(),Put)&&(rGn(r,e),fW(c));HSn(t)}function $Ln(n,t,e){var i;if(h2(n.b),IU(n.b,(Pbn(),HEt),(OM(),GTt)),IU(n.b,qEt,t.g),IU(n.b,GEt,t.a),n.a=$qn(n.b,t),OTn(e,"Compaction by shrinking a tree",n.a.c.length),t.i.c.length>1)for(i=new Wb(n.a);i.a<i.c.c.length;)BB(n0(i),51).pf(t,mcn(e,1));HSn(e)}function LLn(n,t){var e,i,r,c,a;for(r=t.a&n.f,c=null,i=n.b[r];;i=i.b){if(i==t){c?c.b=t.b:n.b[r]=t.b;break}c=i}for(a=t.f&n.f,c=null,e=n.c[a];;e=e.d){if(e==t){c?c.d=t.d:n.c[a]=t.d;break}c=e}t.e?t.e.c=t.c:n.a=t.c,t.c?t.c.e=t.e:n.e=t.e,--n.i,++n.g}function NLn(n){var t,i,r,c,a,u,o,s,h,f;for(i=n.o,t=n.p,u=DWn,c=KVn,o=DWn,a=KVn,h=0;h<i;++h)for(f=0;f<t;++f)vmn(n,h,f)&&(u=e.Math.min(u,h),c=e.Math.max(c,h),o=e.Math.min(o,f),a=e.Math.max(a,f));return s=c-u+1,r=a-o+1,new VV(iln(u),iln(o),iln(s),iln(r))}function xLn(n,t){var e,i,r,c;for(Px((c=new M2(n,0)).b<c.d.gc()),e=BB(c.d.Xb(c.c=c.b++),140);c.b<c.d.gc();)Px(c.b<c.d.gc()),r=new mH((i=BB(c.d.Xb(c.c=c.b++),140)).c,e.d,t),Px(c.b>0),c.a.Xb(c.c=--c.b),yR(c,r),Px(c.b<c.d.gc()),c.d.Xb(c.c=c.b++),r.a=!1,e=i}function DLn(n){var t,e,i,r,c;for(i=BB(mMn(n,(hWn(),_ft)),11),c=new Wb(n.j);c.a<c.c.c.length;){for(e=new Wb((r=BB(n0(c),11)).g);e.a<e.c.c.length;)return MZ(BB(n0(e),17),i),r;for(t=new Wb(r.e);t.a<t.c.c.length;)return SZ(BB(n0(t),17),i),r}return null}function RLn(n,t,i){var r,c;Vhn(r=fan(i.q.getTime()),0)<0?(c=VVn-dG(ldn(j7(r),VVn)))==VVn&&(c=0):c=dG(ldn(r,VVn)),1==t?xX(n,48+(c=e.Math.min((c+50)/100|0,9))&QVn):2==t?Enn(n,c=e.Math.min((c+5)/10|0,99),2):(Enn(n,c,3),t>3&&Enn(n,0,t-3))}function _Ln(n){var t,e,i,r;return GC(mMn(n,(HXn(),sgt)))===GC((ufn(),pIt))?!n.e&&GC(mMn(n,Rdt))!==GC((_an(),kft)):(i=BB(mMn(n,_dt),292),r=qy(TD(mMn(n,Hdt)))||GC(mMn(n,qdt))===GC((Oin(),sht)),t=BB(mMn(n,Ddt),19).a,e=n.a.c.length,!r&&i!=(_an(),kft)&&(0==t||t>e))}function KLn(n){var t,e;for(e=0;e<n.c.length&&!(sq((l1(e,n.c.length),BB(n.c[e],113)))>0);e++);if(e>0&&e<n.c.length-1)return e;for(t=0;t<n.c.length&&!(sq((l1(t,n.c.length),BB(n.c[t],113)))>0);t++);return t>0&&e<n.c.length-1?t:n.c.length/2|0}function FLn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=6&&t){if(vkn(n,t))throw Hp(new Ky(w6n+ROn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?skn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=Npn(t,n,6,i)),(i=QD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,6,t,t))}function BLn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=9&&t){if(vkn(n,t))throw Hp(new Ky(w6n+URn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?fkn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=Npn(t,n,9,i)),(i=YD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,9,t,t))}function HLn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(vkn(n,t))throw Hp(new Ky(w6n+lHn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Mkn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=Npn(t,n,12,i)),(i=VD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,3,t,t))}function qLn(n){var t,e,i,r,c;if(i=Ckn(n),null==(c=n.j)&&i)return n.$j()?null:i.zj();if(cL(i,148)){if((e=i.Aj())&&(r=e.Nh())!=n.i){if((t=BB(i,148)).Ej())try{n.g=r.Kh(t,c)}catch(a){if(!cL(a=lun(a),78))throw Hp(a);n.g=null}n.i=r}return n.g}return null}function GLn(n){var t;return WB(t=new Np,new xS(new xI(n.c,n.d),new xI(n.c+n.b,n.d))),WB(t,new xS(new xI(n.c,n.d),new xI(n.c,n.d+n.a))),WB(t,new xS(new xI(n.c+n.b,n.d+n.a),new xI(n.c+n.b,n.d))),WB(t,new xS(new xI(n.c+n.b,n.d+n.a),new xI(n.c,n.d+n.a))),t}function zLn(n,t,e,i){var r,c,a;if(a=Ajn(t,e),i.c[i.c.length]=t,-1==n.j[a.p]||2==n.j[a.p]||n.a[t.p])return i;for(n.j[a.p]=-1,c=new oz(ZL(hbn(a).a.Kc(),new h));dAn(c);)if(!b5(r=BB(U5(c),17))&&(b5(r)||r.c.i.c!=r.d.i.c)&&r!=t)return zLn(n,r,a,i);return i}function ULn(n,t,e){var i,r;for(r=t.a.ec().Kc();r.Ob();)i=BB(r.Pb(),79),!BB(RX(n.b,i),266)&&(JJ(PMn(i))==JJ(OMn(i))?tDn(n,i,e):PMn(i)==JJ(OMn(i))?null==RX(n.c,i)&&null!=RX(n.b,OMn(i))&&rzn(n,i,e,!1):null==RX(n.d,i)&&null!=RX(n.b,PMn(i))&&rzn(n,i,e,!0))}function XLn(n,t){var e,i,r,c,a,u,o;for(r=n.Kc();r.Ob();)for(i=BB(r.Pb(),10),IZ(u=new ISn,i),qIn(u,(kUn(),oCt)),hon(u,(hWn(),jlt),(hN(),!0)),a=t.Kc();a.Ob();)c=BB(a.Pb(),10),IZ(o=new ISn,c),qIn(o,ICt),hon(o,jlt,!0),hon(e=new wY,jlt,!0),SZ(e,u),MZ(e,o)}function WLn(n,t,e,i){var r,c,a,u;r=Adn(n,t,e),c=Adn(n,e,t),a=BB(RX(n.c,t),112),u=BB(RX(n.c,e),112),r<c?new zZ((O6(),Myt),a,u,c-r):c<r?new zZ((O6(),Myt),u,a,r-c):(0!=r||t.i&&e.i&&i[t.i.c][e.i.c])&&(new zZ((O6(),Myt),a,u,0),new zZ(Myt,u,a,0))}function VLn(n,t){var e,i,r,c,a,u;for(r=0,a=new Wb(t.a);a.a<a.c.c.length;)for(r+=(c=BB(n0(a),10)).o.b+c.d.a+c.d.d+n.e,i=new oz(ZL(fbn(c).a.Kc(),new h));dAn(i);)(e=BB(U5(i),17)).c.i.k==(uSn(),Cut)&&(r+=(u=BB(mMn(e.c.i,(hWn(),dlt)),10)).o.b+u.d.a+u.d.d);return r}function QLn(n,t,e){var i,r,c,a,u,o,s;for(c=new Np,OBn(n,s=new YT,a=new YT,t),Ezn(n,s,a,t,e),o=new Wb(n);o.a<o.c.c.length;)for(r=new Wb((u=BB(n0(o),112)).k);r.a<r.c.c.length;)i=BB(n0(r),129),(!t||i.c==(O6(),Tyt))&&u.g>i.b.g&&(c.c[c.c.length]=i);return c}function YLn(){YLn=O,DEt=new jI("CANDIDATE_POSITION_LAST_PLACED_RIGHT",0),xEt=new jI("CANDIDATE_POSITION_LAST_PLACED_BELOW",1),_Et=new jI("CANDIDATE_POSITION_WHOLE_DRAWING_RIGHT",2),REt=new jI("CANDIDATE_POSITION_WHOLE_DRAWING_BELOW",3),KEt=new jI("WHOLE_DRAWING",4)}function JLn(n,t){if(cL(t,239))return hln(n,BB(t,33));if(cL(t,186))return Dln(n,BB(t,118));if(cL(t,354))return tQ(n,BB(t,137));if(cL(t,352))return JFn(n,BB(t,79));if(t)return null;throw Hp(new Ky(z6n+LMn(new Jy(Pun(Gk(Ant,1),HWn,1,5,[t])))))}function ZLn(n){var t,e,i,r,c,a,u;for(c=new YT,r=new Wb(n.d.a);r.a<r.c.c.length;)0==(i=BB(n0(r),121)).b.a.c.length&&r5(c,i,c.c.b,c.c);if(c.b>1)for(t=AN((e=new qv,++n.b,e),n.d),u=spn(c,0);u.b!=u.d.c;)a=BB(b3(u),121),UNn(aM(cM(uM(rM(new Hv,1),0),t),a))}function nNn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=11&&t){if(vkn(n,t))throw Hp(new Ky(w6n+zRn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Skn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=Npn(t,n,10,i)),(i=zR(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,11,t,t))}function tNn(n){var t,e,i,r;for(i=new usn(new Pb(n.b).a);i.b;)r=BB((e=ten(i)).cd(),11),hon(t=BB(e.dd(),10),(hWn(),dlt),r),hon(r,Elt,t),hon(r,elt,(hN(),!0)),qIn(r,BB(mMn(t,Qft),61)),mMn(t,Qft),hon(r.i,(HXn(),ept),(QEn(),VIt)),BB(mMn(vW(r.i),Zft),21).Fc((bDn(),dft))}function eNn(n,t,e){var i,r,c;if(i=0,r=0,n.c)for(c=new Wb(n.d.i.j);c.a<c.c.c.length;)i+=BB(n0(c),11).e.c.length;else i=1;if(n.d)for(c=new Wb(n.c.i.j);c.a<c.c.c.length;)r+=BB(n0(c),11).g.c.length;else r=1;return(e+t)/2+.4*IJ(HH(r-i))*(e-t)}function iNn(n){var t,e;if(LEn(),n.Hc((kUn(),PCt)))throw Hp(new Ky("Port sides must not contain UNDEFINED"));switch(n.gc()){case 1:return Mst;case 2:return t=n.Hc(oCt)&&n.Hc(ICt),e=n.Hc(sCt)&&n.Hc(SCt),t||e?Ist:Pst;case 3:return Sst;case 4:return Tst;default:return null}}function rNn(n,t,e){var i,r,c,a;for(OTn(e,"Breaking Point Removing",1),n.a=BB(mMn(t,(HXn(),Zdt)),218),r=new Wb(t.b);r.a<r.c.c.length;)for(a=new Wb(a0(BB(n0(r),29).a));a.a<a.c.c.length;)Jnn(c=BB(n0(a),10))&&!(i=BB(mMn(c,(hWn(),Rft)),305)).d&&zUn(n,i);HSn(e)}function cNn(n,t,e){return jDn(),(!Dcn(n,t)||!Dcn(n,e))&&(mzn(new xI(n.c,n.d),new xI(n.c+n.b,n.d),t,e)||mzn(new xI(n.c+n.b,n.d),new xI(n.c+n.b,n.d+n.a),t,e)||mzn(new xI(n.c+n.b,n.d+n.a),new xI(n.c,n.d+n.a),t,e)||mzn(new xI(n.c,n.d+n.a),new xI(n.c,n.d),t,e))}function aNn(n,t){var e,i,r,c;if(!n.dc())for(e=0,i=n.gc();e<i;++e)if(null==(c=SD(n.Xb(e)))?null==t:m_(c.substr(0,3),"!##")?null!=t&&(r=t.length,!m_(c.substr(c.length-r,r),t)||c.length!=t.length+3)&&!m_(S7n,t):m_(c,P7n)&&!m_(S7n,t)||m_(c,t))return!0;return!1}function uNn(n,t,e,i){var r,c,a,u,o,s;for(a=n.j.c.length,o=x8(art,rJn,306,a,0,1),u=0;u<a;u++)(c=BB(xq(n.j,u),11)).p=u,o[u]=hOn(mAn(c),e,i);for(VNn(n,o,e,t,i),s=new xp,r=0;r<o.length;r++)o[r]&&VW(s,BB(xq(n.j,r),11),o[r]);s.f.c+s.g.c!=0&&(hon(n,(hWn(),zft),s),ASn(n,o))}function oNn(n,t,e){var i,r;for(i=new Wb(n.a.b);i.a<i.c.c.length;)if((r=f2(BB(n0(i),57)))&&r.k==(uSn(),Mut))switch(BB(mMn(r,(hWn(),Qft)),61).g){case 4:r.n.a=t.a;break;case 2:r.n.a=e.a-(r.o.a+r.d.c);break;case 1:r.n.b=t.b;break;case 3:r.n.b=e.b-(r.o.b+r.d.a)}}function sNn(){sNn=O,Cvt=new HP(QZn,0),Tvt=new HP("NIKOLOV",1),Pvt=new HP("NIKOLOV_PIXEL",2),Mvt=new HP("NIKOLOV_IMPROVED",3),Svt=new HP("NIKOLOV_IMPROVED_PIXEL",4),Evt=new HP("DUMMYNODE_PERCENTAGE",5),Ivt=new HP("NODECOUNT_PERCENTAGE",6),Ovt=new HP("NO_BOUNDARY",7)}function hNn(n,t,e){var i,r,c;if(!(r=BB(ZAn(t,(SMn(),UMt)),19))&&(r=iln(0)),!(c=BB(ZAn(e,UMt),19))&&(c=iln(0)),r.a>c.a)return-1;if(r.a<c.a)return 1;if(n.a){if(0!=(i=Pln(t.j,e.j)))return i;if(0!=(i=Pln(t.i,e.i)))return i}return Pln(t.g*t.f,e.g*e.f)}function fNn(n,t){var e,i,r,c,a,u,o,s,h,f;if(++n.e,t>(o=null==n.d?0:n.d.length)){for(h=n.d,n.d=x8(oAt,c9n,63,2*o+4,0,1),c=0;c<o;++c)if(s=h[c])for(i=s.g,f=s.i,u=0;u<f;++u)a=eR(n,(r=BB(i[u],133)).Sh()),!(e=n.d[a])&&(e=n.d[a]=n.uj()),e.Fc(r);return!0}return!1}function lNn(n,t,e){var i,r,c,a,u,o;if(c=(r=e).ak(),$xn(n.e,c)){if(c.hi())for(i=BB(n.g,119),a=0;a<n.i;++a)if(Nfn(u=i[a],r)&&a!=t)throw Hp(new Ky(a8n))}else for(o=axn(n.e.Tg(),c),i=BB(n.g,119),a=0;a<n.i;++a)if(u=i[a],o.rl(u.ak()))throw Hp(new Ky(C7n));sln(n,t,e)}function bNn(n,t){var e,i,r,c,a,u;for(e=BB(mMn(t,(hWn(),Xft)),21),a=BB(h6((RXn(),fut),e),21),u=BB(h6(put,e),21),c=a.Kc();c.Ob();)if(i=BB(c.Pb(),21),!BB(h6(n.b,i),15).dc())return!1;for(r=u.Kc();r.Ob();)if(i=BB(r.Pb(),21),!BB(h6(n.b,i),15).dc())return!1;return!0}function wNn(n,t){var e,i,r;for(OTn(t,"Partition postprocessing",1),e=new Wb(n.b);e.a<e.c.c.length;)for(i=new Wb(BB(n0(e),29).a);i.a<i.c.c.length;)for(r=new Wb(BB(n0(i),10).j);r.a<r.c.c.length;)qy(TD(mMn(BB(n0(r),11),(hWn(),jlt))))&&AU(r);HSn(t)}function dNn(n,t){var e,i,r,c,a,u,o;if(1==n.a.c.length)return FSn(BB(xq(n.a,0),187),t);for(r=cfn(n),a=0,u=n.d,i=r,o=n.d,c=(u-i)/2+i;i+1<u;){for(a=0,e=new Wb(n.a);e.a<e.c.c.length;)a+=cHn(BB(n0(e),187),c,!1).a;a<t?(o=c,u=c):i=c,c=(u-i)/2+i}return o}function gNn(n){var t,e,i,r;return isNaN(n)?(X7(),gtt):n<-0x8000000000000000?(X7(),wtt):n>=0x8000000000000000?(X7(),btt):(i=!1,n<0&&(i=!0,n=-n),e=0,n>=OQn&&(n-=(e=IJ(n/OQn))*OQn),t=0,n>=CQn&&(n-=(t=IJ(n/CQn))*CQn),r=M$(IJ(n),t,e),i&&Oon(r),r)}function pNn(n,t){var e,i,r,c;for(e=!t||!n.u.Hc((lCn(),eCt)),c=0,r=new Wb(n.e.Cf());r.a<r.c.c.length;){if((i=BB(n0(r),838)).Hf()==(kUn(),PCt))throw Hp(new Ky("Label and node size calculator can only be used with ports that have port sides assigned."));i.vf(c++),Whn(n,i,e)}}function vNn(n,t){var e,i,r,c;return(i=t.Hh(n.a))&&(!i.b&&(i.b=new Jx((gWn(),k$t),X$t,i)),null!=(e=SD(cdn(i.b,J9n)))&&cL(c=-1==(r=e.lastIndexOf("#"))?uD(n,t.Aj(),e):0==r?M9(n,null,e.substr(1)):M9(n,e.substr(0,r),e.substr(r+1)),148))?BB(c,148):null}function mNn(n,t){var e,i,r,c;return(e=t.Hh(n.a))&&(!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),null!=(r=SD(cdn(e.b,k7n)))&&cL(c=-1==(i=r.lastIndexOf("#"))?uD(n,t.Aj(),r):0==i?M9(n,null,r.substr(1)):M9(n,r.substr(0,i),r.substr(i+1)),148))?BB(c,148):null}function yNn(n){var t,e,i,r,c;for(e=new Wb(n.a.a);e.a<e.c.c.length;){for((t=BB(n0(e),307)).j=null,c=t.a.a.ec().Kc();c.Ob();)kO((i=BB(c.Pb(),57)).b),(!t.j||i.d.c<t.j.d.c)&&(t.j=i);for(r=t.a.a.ec().Kc();r.Ob();)(i=BB(r.Pb(),57)).b.a=i.d.c-t.j.d.c,i.b.b=i.d.d-t.j.d.d}return n}function kNn(n){var t,e,i,r,c;for(e=new Wb(n.a.a);e.a<e.c.c.length;){for((t=BB(n0(e),189)).f=null,c=t.a.a.ec().Kc();c.Ob();)kO((i=BB(c.Pb(),81)).e),(!t.f||i.g.c<t.f.g.c)&&(t.f=i);for(r=t.a.a.ec().Kc();r.Ob();)(i=BB(r.Pb(),81)).e.a=i.g.c-t.f.g.c,i.e.b=i.g.d-t.f.g.d}return n}function jNn(n){var t,i,r;return i=BB(n.a,19).a,r=BB(n.b,19).a,i<(t=e.Math.max(e.Math.abs(i),e.Math.abs(r)))&&r==-t?new rC(iln(i+1),iln(r)):i==t&&r<t?new rC(iln(i),iln(r+1)):i>=-t&&r==t?new rC(iln(i-1),iln(r)):new rC(iln(i),iln(r-1))}function ENn(){return lWn(),Pun(Gk(ust,1),$Vn,77,0,[rot,tot,cot,kot,Fot,Mot,Uot,Oot,_ot,got,Not,Cot,Kot,lot,Wot,Vut,Lot,Hot,jot,Bot,Qot,Dot,Qut,Rot,Yot,Got,Vot,Eot,sot,Tot,yot,Xot,Zut,uot,Pot,Jut,Iot,vot,bot,Aot,dot,eot,not,mot,wot,$ot,zot,Yut,xot,pot,Sot,hot,oot,qot,aot,fot,iot])}function TNn(n,t,e){n.d=0,n.b=0,t.k==(uSn(),Cut)&&e.k==Cut&&BB(mMn(t,(hWn(),dlt)),10)==BB(mMn(e,dlt),10)&&(S7(t).j==(kUn(),sCt)?q$n(n,t,e):q$n(n,e,t)),t.k==Cut&&e.k==Put?S7(t).j==(kUn(),sCt)?n.d=1:n.b=1:e.k==Cut&&t.k==Put&&(S7(e).j==(kUn(),sCt)?n.b=1:n.d=1),umn(n,t,e)}function MNn(n){var t,e,i,r,c;return c=ATn(n),null!=n.a&&AH(c,"category",n.a),!WE(new Ib(n.d))&&(rtn(c,"knownOptions",i=new Il),t=new ep(i),e5(new Ib(n.d),t)),!WE(n.g)&&(rtn(c,"supportedFeatures",r=new Il),e=new ip(r),e5(n.g,e)),c}function SNn(n){var t,e,i,r,c,a,u,o;for(t=336,e=0,r=new sR(n.length),u=0,o=(a=n).length;u<o;++u)Qln(c=a[u]),EW(c),i=c.a,WB(r.a,yX(i)),t&=i.qd(),e=Ysn(e,i.rd());return BB(BB(XU(new Rq(null,qTn(new w1((WX(),Nwn(r.a)),16),new k,t,e)),new El(n)),670),833)}function PNn(n,t){var e;n.d&&(t.c!=n.e.c||fcn(n.e.b,t.b))&&(WB(n.f,n.d),n.a=n.d.c+n.d.b,n.d=null,n.e=null),nA(t.b)?n.c=t:n.b=t,(t.b==(Aun(),Zat)&&!t.a||t.b==nut&&t.a||t.b==tut&&t.a||t.b==eut&&!t.a)&&n.c&&n.b&&(e=new UV(n.a,n.c.d,t.c-n.a,n.b.d-n.c.d),n.d=e,n.e=t)}function INn(n){var t;if(Ym.call(this),this.i=new lu,this.g=n,this.f=BB(n.e&&n.e(),9).length,0==this.f)throw Hp(new Ky("There must be at least one phase in the phase enumeration."));this.c=new Y_(t=BB(Vj(this.g),9),BB(SR(t,t.length),9),0),this.a=new B2,this.b=new xp}function CNn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=7&&t){if(vkn(n,t))throw Hp(new Ky(w6n+cPn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?hkn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=BB(t,49).gh(n,1,DOt,i)),(i=VG(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,7,t,t))}function ONn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(vkn(n,t))throw Hp(new Ky(w6n+Vfn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?bkn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=BB(t,49).gh(n,0,BOt,i)),(i=QG(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,3,t,t))}function ANn(n,t){var e,i,r,c,a,u,o,s,h;return $On(),t.d>n.d&&(u=n,n=t,t=u),t.d<63?Xxn(n,t):(s=z5(n,a=(-2&n.d)<<4),h=z5(t,a),i=uBn(n,G5(s,a)),r=uBn(t,G5(h,a)),o=ANn(s,h),e=ANn(i,r),c=G5(c=$Hn($Hn(c=ANn(uBn(s,i),uBn(r,h)),o),e),a),$Hn($Hn(o=G5(o,a<<1),c),e))}function $Nn(n,t,e){var i,r,c,a,u;for(a=Lfn(n,e),u=x8(Out,a1n,10,t.length,0,1),i=0,c=a.Kc();c.Ob();)qy(TD(mMn(r=BB(c.Pb(),11),(hWn(),elt))))&&(u[i++]=BB(mMn(r,Elt),10));if(i<t.length)throw Hp(new Fy("Expected "+t.length+" hierarchical ports, but found only "+i+"."));return u}function LNn(n,t){var e,i,r,c,a,u;if(!n.tb){for(!n.rb&&(n.rb=new Jz(n,HAt,n)),u=new XT((c=n.rb).i),r=new AL(c);r.e!=r.i.gc();)i=BB(kpn(r),138),(e=BB(null==(a=i.ne())?jIn(u.f,null,i):ubn(u.g,a,i),138))&&(null==a?jIn(u.f,null,e):ubn(u.g,a,e));n.tb=u}return BB(SJ(n.tb,t),138)}function NNn(n,t){var e,i,r,c,a;if((null==n.i&&qFn(n),n.i).length,!n.p){for(a=new XT(1+(3*n.g.i/2|0)),r=new ax(n.g);r.e!=r.i.gc();)i=BB(jpn(r),170),(e=BB(null==(c=i.ne())?jIn(a.f,null,i):ubn(a.g,c,i),170))&&(null==c?jIn(a.f,null,e):ubn(a.g,c,e));n.p=a}return BB(SJ(n.p,t),170)}function xNn(n,t,e,i,r){var c,a,u,o;for(wgn(i+IY(e,e.$d()),r),tW(t,Lwn(e)),(c=e.f)&&xNn(n,t,c,"Caused by: ",!1),null==e.k&&(e.k=x8(Jnt,sVn,78,0,0,1)),u=0,o=(a=e.k).length;u<o;++u)xNn(n,t,a[u],"Suppressed: ",!1);null!=console.groupEnd&&console.groupEnd.call(console)}function DNn(n,t,e,i){var r,c,a,u;for(a=(u=t.e).length,c=t.q._f(u,e?0:a-1,e),c|=gRn(n,u[e?0:a-1],e,i),r=e?1:a-2;e?r<a:r>=0;r+=e?1:-1)c|=t.c.Sf(u,r,e,i&&!qy(TD(mMn(t.j,(hWn(),Jft))))&&!qy(TD(mMn(t.j,(hWn(),Clt))))),c|=t.q._f(u,r,e),c|=gRn(n,u[r],e,i);return TU(n.c,t),c}function RNn(n,t,e){var i,r,c,a,u,o,s,h;for(s=0,h=(o=C2(n.j)).length;s<h;++s){if(u=o[s],e==(ain(),Hvt)||e==Gvt)for(c=0,a=(r=Z0(u.g)).length;c<a;++c)OSn(t,i=r[c])&&tBn(i,!0);if(e==qvt||e==Gvt)for(c=0,a=(r=Z0(u.e)).length;c<a;++c)CSn(t,i=r[c])&&tBn(i,!0)}}function _Nn(n){var t,e;switch(t=null,e=null,eEn(n).g){case 1:kUn(),t=oCt,e=ICt;break;case 2:kUn(),t=SCt,e=sCt;break;case 3:kUn(),t=ICt,e=oCt;break;case 4:kUn(),t=sCt,e=SCt}Gl(n,BB($N(Oz(BB(h6(n.k,t),15).Oc(),Qst)),113)),ql(n,BB($N(Cz(BB(h6(n.k,e),15).Oc(),Qst)),113))}function KNn(n){var t,e,i,r,c,a;if((r=BB(xq(n.j,0),11)).e.c.length+r.g.c.length==0)n.n.a=0;else{for(a=0,i=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[new Hw(r),new Gw(r)])));dAn(i);)a+=(e=BB(U5(i),11)).i.n.a+e.n.a+e.a.a;c=(t=BB(mMn(n,(HXn(),npt)),8))?t.a:0,n.n.a=a/(r.e.c.length+r.g.c.length)-c}}function FNn(n,t){var e,i,r;for(i=new Wb(t.a);i.a<i.c.c.length;)e=BB(n0(i),221),LG(BB(e.b,65),XR(B$(BB(t.b,65).c),BB(t.b,65).a)),(r=YKn(BB(t.b,65).b,BB(e.b,65).b))>1&&(n.a=!0),NG(BB(e.b,65),UR(B$(BB(t.b,65).c),kL(XR(B$(BB(e.b,65).a),BB(t.b,65).a),r))),QZ(n,t),FNn(n,e)}function BNn(n){var t,e,i,r,c,a;for(r=new Wb(n.a.a);r.a<r.c.c.length;)(e=BB(n0(r),189)).e=0,e.d.a.$b();for(i=new Wb(n.a.a);i.a<i.c.c.length;)for(t=(e=BB(n0(i),189)).a.a.ec().Kc();t.Ob();)for(a=BB(t.Pb(),81).f.Kc();a.Ob();)(c=BB(a.Pb(),81)).d!=e&&(TU(e.d,c),++c.d.e)}function HNn(n){var t,e,i,r,c,a,u,o;for(e=0,t=o=n.j.c.length,r=2*o,u=new Wb(n.j);u.a<u.c.c.length;)switch((a=BB(n0(u),11)).j.g){case 2:case 4:a.p=-1;break;case 1:case 3:i=a.e.c.length,c=a.g.c.length,a.p=i>0&&c>0?t++:i>0?e++:c>0?r++:e++}SQ(),m$(n.j,new bi)}function qNn(n){var t,e;e=null,t=BB(xq(n.g,0),17);do{if(Lx(e=t.d.i,(hWn(),flt)))return BB(mMn(e,flt),11).i;if(e.k!=(uSn(),Iut)&&dAn(new oz(ZL(lbn(e).a.Kc(),new h))))t=BB(U5(new oz(ZL(lbn(e).a.Kc(),new h))),17);else if(e.k!=Iut)return null}while(e&&e.k!=(uSn(),Iut));return e}function GNn(n,t){var e,i,r,c,a,u,o,s,h;for(u=t.j,a=t.g,o=BB(xq(u,u.c.length-1),113),l1(0,u.c.length),s=Zmn(n,a,o,h=BB(u.c[0],113)),c=1;c<u.c.length;c++)l1(c-1,u.c.length),e=BB(u.c[c-1],113),l1(c,u.c.length),(i=Zmn(n,a,e,r=BB(u.c[c],113)))>s&&(o=e,h=r,s=i);t.a=h,t.c=o}function zNn(n,t){var e;if(!ZU(n.b,t.b))throw Hp(new Fy("Invalid hitboxes for scanline constraint calculation."));(kun(t.b,BB(MR(n.b,t.b),57))||kun(t.b,BB(TR(n.b,t.b),57)))&&($T(),t.b),n.a[t.b.f]=BB(k_(n.b,t.b),57),(e=BB(y_(n.b,t.b),57))&&(n.a[e.f]=t.b)}function UNn(n){if(!n.a.d||!n.a.e)throw Hp(new Fy((ED(Hit),Hit.k+" must have a source and target "+(ED(qit),qit.k+" specified."))));if(n.a.d==n.a.e)throw Hp(new Fy("Network simplex does not support self-loops: "+n.a+" "+n.a.d+" "+n.a.e));return RN(n.a.d.g,n.a),RN(n.a.e.b,n.a),n.a}function XNn(n,t,e){var i,r,c,a,u,o,s;for(s=new dE(new Jd(n)),u=0,o=(a=Pun(Gk(Gut,1),u1n,11,0,[t,e])).length;u<o;++u)for(c=a[u],Mon(s.a,c,(hN(),ptt)),r=new m6(c.b);y$(r.a)||y$(r.b);)(i=BB(y$(r.a)?n0(r.a):n0(r.b),17)).c==i.d||ZU(s,c==i.c?i.d:i.c);return yX(s),new tK(s)}function WNn(n,t,e){var i,r,c,a,u,o;if(i=0,0!=t.b&&0!=e.b){c=spn(t,0),a=spn(e,0),u=Gy(MD(b3(c))),o=Gy(MD(b3(a))),r=!0;do{if(u>o-n.b&&u<o+n.b)return-1;u>o-n.a&&u<o+n.a&&++i,u<=o&&c.b!=c.d.c?u=Gy(MD(b3(c))):o<=u&&a.b!=a.d.c?o=Gy(MD(b3(a))):r=!1}while(r)}return i}function VNn(n,t,e,i,r){var c,a,u,o;for(o=new Y_(c=BB(Vj(FCt),9),BB(SR(c,c.length),9),0),u=new Wb(n.j);u.a<u.c.c.length;)t[(a=BB(n0(u),11)).p]&&(BUn(a,t[a.p],i),orn(o,a.j));r?(GEn(n,t,(kUn(),oCt),2*e,i),GEn(n,t,ICt,2*e,i)):(GEn(n,t,(kUn(),sCt),2*e,i),GEn(n,t,SCt,2*e,i))}function QNn(n){var t,e,i,r,c;if(c=new Np,Otn(n.b,new kw(c)),n.b.c=x8(Ant,HWn,1,0,5,1),0!=c.c.length){for(l1(0,c.c.length),t=BB(c.c[0],78),e=1,i=c.c.length;e<i;++e)l1(e,c.c.length),(r=BB(c.c[e],78))!=t&>n(t,r);if(cL(t,60))throw Hp(BB(t,60));if(cL(t,289))throw Hp(BB(t,289))}}function YNn(n,t){var e,i,r,c;for(n=null==n?zWn:(kW(n),n),e=new Ck,c=0,i=0;i<t.length&&-1!=(r=n.indexOf("%s",c));)oO(e,n.substr(c,r-c)),uO(e,t[i++]),c=r+2;if(oO(e,n.substr(c)),i<t.length){for(e.a+=" [",uO(e,t[i++]);i<t.length;)e.a+=FWn,uO(e,t[i++]);e.a+="]"}return e.a}function JNn(n){var t,e,i,r;for(t=0,r=(i=n.length)-4,e=0;e<r;)b1(e+3,n.length),t=n.charCodeAt(e+3)+(b1(e+2,n.length),31*(n.charCodeAt(e+2)+(b1(e+1,n.length),31*(n.charCodeAt(e+1)+(b1(e,n.length),31*(n.charCodeAt(e)+31*t)))))),t|=0,e+=4;for(;e<i;)t=31*t+fV(n,e++);return t|=0}function ZNn(n){var t;for(t=new oz(ZL(lbn(n).a.Kc(),new h));dAn(t);)if(BB(U5(t),17).d.i.k!=(uSn(),Sut))throw Hp(new rk(P1n+gyn(n)+"' has its layer constraint set to LAST, but has at least one outgoing edge that does not go to a LAST_SEPARATE node. That must not happen."))}function nxn(n,t,i,r){var c,a,u,o,s,f,l;for(o=0,s=new Wb(n.a);s.a<s.c.c.length;){for(u=0,a=new oz(ZL(fbn(BB(n0(s),10)).a.Kc(),new h));dAn(a);)f=g1((c=BB(U5(a),17)).c).b,l=g1(c.d).b,u=e.Math.max(u,e.Math.abs(l-f));o=e.Math.max(o,u)}return r*e.Math.min(1,t/i)*o}function txn(n){var t;return t=new Pk,0!=(256&n)&&(t.a+="F"),0!=(128&n)&&(t.a+="H"),0!=(512&n)&&(t.a+="X"),0!=(2&n)&&(t.a+="i"),0!=(8&n)&&(t.a+="m"),0!=(4&n)&&(t.a+="s"),0!=(32&n)&&(t.a+="u"),0!=(64&n)&&(t.a+="w"),0!=(16&n)&&(t.a+="x"),0!=(n&k6n)&&(t.a+=","),Uy(t.a)}function exn(n,t){var e,i,r;for(OTn(t,"Resize child graph to fit parent.",1),i=new Wb(n.b);i.a<i.c.c.length;)e=BB(n0(i),29),gun(n.a,e.a),e.a.c=x8(Ant,HWn,1,0,5,1);for(r=new Wb(n.a);r.a<r.c.c.length;)PZ(BB(n0(r),10),null);n.b.c=x8(Ant,HWn,1,0,5,1),Bxn(n),n.e&&SKn(n.e,n),HSn(t)}function ixn(n){var t,e,i,r,c,a,u;if(r=(i=n.b).e,c=L_(BB(mMn(i,(HXn(),ept)),98)),e=!!r&&BB(mMn(r,(hWn(),Zft)),21).Hc((bDn(),lft)),!c&&!e)for(u=new _b(new Ob(n.e).a.vc().Kc());u.a.Ob();)t=BB(u.a.Pb(),42),(a=BB(t.dd(),113)).a&&(IZ(a.d,null),a.c=!0,n.a=!0)}function rxn(n){var t,e,i,r,c,a,u,o,s,h,f,l;for(f=-1,l=0,s=0,h=(o=n).length;s<h;++s){for(a=0,u=(c=o[s]).length;a<u;++a)for(r=c[a],t=new pP(-1==f?n[0]:n[f],okn(r)),e=0;e<r.j.c.length;e++)for(i=e+1;i<r.j.c.length;i++)Nz(t,BB(xq(r.j,e),11),BB(xq(r.j,i),11))>0&&++l;++f}return l}function cxn(n,t){var e,i,r,c,a;for(a=BB(mMn(t,(IAn(),Lkt)),425),c=spn(t.b,0);c.b!=c.d.c;)if(r=BB(b3(c),86),0==n.b[r.g]){switch(a.g){case 0:Qvn(n,r);break;case 1:HAn(n,r)}n.b[r.g]=2}for(i=spn(n.a,0);i.b!=i.d.c;)ywn((e=BB(b3(i),188)).b.d,e,!0),ywn(e.c.b,e,!0);hon(t,(qqn(),lkt),n.a)}function axn(n,t){var e,i,r,c;return ZM(),t?t==(Uqn(),_Lt)||(t==yLt||t==vLt||t==mLt)&&n!=pLt?new cUn(n,t):((e=(i=BB(t,677)).pk())||(kV(B7((CPn(),Z$t),t)),e=i.pk()),!e.i&&(e.i=new xp),!(r=BB(qC(AY((c=e.i).f,n)),1942))&&VW(c,n,r=new cUn(n,t)),r):aLt}function uxn(n,t){var e,i,r,c,a,u,o,s;for(u=BB(mMn(n,(hWn(),dlt)),11),o=Aon(Pun(Gk(PMt,1),sVn,8,0,[u.i.n,u.n,u.a])).a,s=n.i.n.b,r=0,c=(i=Z0(n.e)).length;r<c;++r)MZ(e=i[r],u),fO(e.a,new xI(o,s)),t&&((a=BB(mMn(e,(HXn(),vgt)),74))||(a=new km,hon(e,vgt,a)),DH(a,new xI(o,s)))}function oxn(n,t){var e,i,r,c,a,u,o,s;for(i=BB(mMn(n,(hWn(),dlt)),11),o=Aon(Pun(Gk(PMt,1),sVn,8,0,[i.i.n,i.n,i.a])).a,s=n.i.n.b,a=0,u=(c=Z0(n.g)).length;a<u;++a)SZ(r=c[a],i),hO(r.a,new xI(o,s)),t&&((e=BB(mMn(r,(HXn(),vgt)),74))||(e=new km,hon(r,vgt,e)),DH(e,new xI(o,s)))}function sxn(n,t){var e,i,r,c,a;for(n.b=new Np,n.d=BB(mMn(t,(hWn(),Slt)),230),n.e=c0(n.d),c=new YT,r=u6(Pun(Gk(jut,1),JZn,37,0,[t])),a=0;a<r.c.length;)l1(a,r.c.length),(i=BB(r.c[a],37)).p=a++,gun(r,(e=new IGn(i,n.a,n.b)).b),WB(n.b,e),e.s&&nX(spn(c,0),e);return n.c=new Rv,c}function hxn(n,t){var e,i,r,c,a,u;for(a=BB(BB(h6(n.r,t),21),84).Kc();a.Ob();)(e=(c=BB(a.Pb(),111)).c?VH(c.c):0)>0?c.a?e>(u=c.b.rf().a)&&(r=(e-u)/2,c.d.b=r,c.d.c=r):c.d.c=n.s+e:Hz(n.u)&&((i=KTn(c.b)).c<0&&(c.d.b=-i.c),i.c+i.b>c.b.rf().a&&(c.d.c=i.c+i.b-c.b.rf().a))}function fxn(n,t){var e,i;for(OTn(t,"Semi-Interactive Crossing Minimization Processor",1),e=!1,i=new Wb(n.b);i.a<i.c.c.length;)e|=null!=$fn(ytn(AV(AV(new Rq(null,new w1(BB(n0(i),29).a,16)),new Qi),new Yi),new Ji),new Zi).a;e&&hon(n,(hWn(),alt),(hN(),!0)),HSn(t)}function lxn(n,t,e){var i,r,c;if(!(r=e)&&(r=new Xm),OTn(r,"Layout",n.a.c.length),qy(TD(mMn(t,(IAn(),Ekt)))))for($T(),i=0;i<n.a.c.length;i++)i++,nE(tsn(BB(xq(n.a,i),51)));for(c=new Wb(n.a);c.a<c.c.c.length;)BB(n0(c),51).pf(t,mcn(r,1));HSn(r)}function bxn(n){var t,i;if(t=BB(n.a,19).a,i=BB(n.b,19).a,t>=0){if(t==i)return new rC(iln(-t-1),iln(-t-1));if(t==-i)return new rC(iln(-t),iln(i+1))}return e.Math.abs(t)>e.Math.abs(i)?new rC(iln(-t),iln(t<0?i:i+1)):new rC(iln(t+1),iln(i))}function wxn(n){var t,e;e=BB(mMn(n,(HXn(),kgt)),163),t=BB(mMn(n,(hWn(),ilt)),303),e==(Tbn(),Flt)?(hon(n,kgt,qlt),hon(n,ilt,(z7(),Ift))):e==Hlt?(hon(n,kgt,qlt),hon(n,ilt,(z7(),Sft))):t==(z7(),Ift)?(hon(n,kgt,Flt),hon(n,ilt,Pft)):t==Sft&&(hon(n,kgt,Hlt),hon(n,ilt,Pft))}function dxn(){dxn=O,jyt=new oa,vyt=dq(new B2,(yMn(),Kat),(lWn(),jot)),kyt=WG(dq(new B2,Kat,Dot),Bat,xot),Eyt=ogn(ogn(FM(WG(dq(new B2,Rat,Uot),Bat,zot),Fat),Got),Xot),myt=WG(dq(dq(dq(new B2,_at,Mot),Fat,Pot),Fat,Iot),Bat,Sot),yyt=WG(dq(dq(new B2,Fat,Iot),Fat,uot),Bat,aot)}function gxn(){gxn=O,Iyt=dq(WG(new B2,(yMn(),Bat),(lWn(),hot)),Kat,jot),$yt=ogn(ogn(FM(WG(dq(new B2,Rat,Uot),Bat,zot),Fat),Got),Xot),Cyt=WG(dq(dq(dq(new B2,_at,Mot),Fat,Pot),Fat,Iot),Bat,Sot),Ayt=dq(dq(new B2,Kat,Dot),Bat,xot),Oyt=WG(dq(dq(new B2,Fat,Iot),Fat,uot),Bat,aot)}function pxn(n,t,e,i,r){var c,a;(b5(t)||t.c.i.c!=t.d.i.c)&&nrn(Aon(Pun(Gk(PMt,1),sVn,8,0,[r.i.n,r.n,r.a])),e)||b5(t)||(t.c==r?_x(t.a,0,new wA(e)):DH(t.a,new wA(e)),i&&!FT(n.a,e)&&((a=BB(mMn(t,(HXn(),vgt)),74))||(a=new km,hon(t,vgt,a)),r5(a,c=new wA(e),a.c.b,a.c),TU(n.a,c)))}function vxn(n){var t;for(t=new oz(ZL(fbn(n).a.Kc(),new h));dAn(t);)if(BB(U5(t),17).c.i.k!=(uSn(),Sut))throw Hp(new rk(P1n+gyn(n)+"' has its layer constraint set to FIRST, but has at least one incoming edge that does not come from a FIRST_SEPARATE node. That must not happen."))}function mxn(n,t,e){var i,r,c,a,u,o;if(0==(r=pbn(254&n.Db)))n.Eb=e;else{if(1==r)a=x8(Ant,HWn,1,2,5,1),0==Rmn(n,t)?(a[0]=e,a[1]=n.Eb):(a[0]=n.Eb,a[1]=e);else for(a=x8(Ant,HWn,1,r+1,5,1),c=een(n.Eb),i=2,u=0,o=0;i<=128;i<<=1)i==t?a[o++]=e:0!=(n.Db&i)&&(a[o++]=c[u++]);n.Eb=a}n.Db|=t}function yxn(n,t,i){var r,c,a,u;for(this.b=new Np,c=0,r=0,u=new Wb(n);u.a<u.c.c.length;)a=BB(n0(u),167),i&&_Bn(a),WB(this.b,a),c+=a.o,r+=a.p;this.b.c.length>0&&(c+=(a=BB(xq(this.b,0),167)).o,r+=a.p),c*=2,r*=2,t>1?c=IJ(e.Math.ceil(c*t)):r=IJ(e.Math.ceil(r/t)),this.a=new qwn(c,r)}function kxn(n,t,i,r,c,a){var u,o,s,h,f,l,b,w,d,g;for(h=r,t.j&&t.o?(d=(b=BB(RX(n.f,t.A),57)).d.c+b.d.b,--h):d=t.a.c+t.a.b,f=c,i.q&&i.o?(s=(b=BB(RX(n.f,i.C),57)).d.c,++f):s=i.a.c,w=d+(o=(s-d)/e.Math.max(2,f-h)),l=h;l<f;++l)g=(u=BB(a.Xb(l),128)).a.b,u.a.c=w-g/2,w+=o}function jxn(n,t,e,i,r,c){var a,u,o,s,h,f;for(s=e.c.length,c&&(n.c=x8(ANt,hQn,25,t.length,15,1)),a=r?0:t.length-1;r?a<t.length:a>=0;a+=r?1:-1){for(u=t[a],o=i==(kUn(),oCt)?r?abn(u,i):ean(abn(u,i)):r?ean(abn(u,i)):abn(u,i),c&&(n.c[u.p]=o.gc()),f=o.Kc();f.Ob();)h=BB(f.Pb(),11),n.d[h.p]=s++;gun(e,o)}}function Exn(n,t,e){var i,r,c,a,u,o,s,h;for(c=Gy(MD(n.b.Kc().Pb())),s=Gy(MD(Wan(t.b))),i=kL(B$(n.a),s-e),r=kL(B$(t.a),e-c),kL(h=UR(i,r),1/(s-c)),this.a=h,this.b=new Np,u=!0,(a=n.b.Kc()).Pb();a.Ob();)o=Gy(MD(a.Pb())),u&&o-e>D3n&&(this.b.Fc(e),u=!1),this.b.Fc(o);u&&this.b.Fc(e)}function Txn(n){var t,e,i,r;if(h_n(n,n.n),n.d.c.length>0){for(nk(n.c);pAn(n,BB(n0(new Wb(n.e.a)),121))<n.e.a.c.length;){for(r=(t=Ryn(n)).e.e-t.d.e-t.a,t.e.j&&(r=-r),i=new Wb(n.e.a);i.a<i.c.c.length;)(e=BB(n0(i),121)).j&&(e.e+=r);nk(n.c)}nk(n.c),pCn(n,BB(n0(new Wb(n.e.a)),121)),gGn(n)}}function Mxn(n,t){var e,i,r,c,a;for(r=BB(h6(n.a,(LEn(),Mst)),15).Kc();r.Ob();)switch(i=BB(r.Pb(),101),e=BB(xq(i.j,0),113).d.j,m$(c=new tK(i.j),new Jr),t.g){case 1:NEn(n,c,e,(Irn(),Dst),1);break;case 0:NEn(n,new s1(c,0,a=KLn(c)),e,(Irn(),Dst),0),NEn(n,new s1(c,a,c.c.length),e,Dst,1)}}function Sxn(n,t){var e,i;if(Nun(),e=T5(cin(),t.tg())){if(i=e.j,cL(n,239))return rZ(BB(n,33))?SN(i,(rpn(),sMt))||SN(i,hMt):SN(i,(rpn(),sMt));if(cL(n,352))return SN(i,(rpn(),uMt));if(cL(n,186))return SN(i,(rpn(),fMt));if(cL(n,354))return SN(i,(rpn(),oMt))}return!0}function Pxn(n,t,e){var i,r,c,a,u,o;if(c=(r=e).ak(),$xn(n.e,c)){if(c.hi())for(i=BB(n.g,119),a=0;a<n.i;++a)if(Nfn(u=i[a],r)&&a!=t)throw Hp(new Ky(a8n))}else for(o=axn(n.e.Tg(),c),i=BB(n.g,119),a=0;a<n.i;++a)if(u=i[a],o.rl(u.ak())&&a!=t)throw Hp(new Ky(C7n));return BB(ovn(n,t,e),72)}function Ixn(n,t){if(t instanceof Object)try{if(t.__java$exception=n,-1!=navigator.userAgent.toLowerCase().indexOf("msie")&&$doc.documentMode<9)return;var e=n;Object.defineProperties(t,{cause:{get:function(){var n=e.Zd();return n&&n.Xd()}},suppressed:{get:function(){return e.Yd()}}})}catch(i){}}function Cxn(n,t){var e,i,r,c,a;if(i=t>>5,t&=31,i>=n.d)return n.e<0?(ODn(),Ytt):(ODn(),eet);if(c=n.d-i,QSn(r=x8(ANt,hQn,25,c+1,15,1),c,n.a,i,t),n.e<0){for(e=0;e<i&&0==n.a[e];e++);if(e<i||t>0&&n.a[e]<<32-t!=0){for(e=0;e<c&&-1==r[e];e++)r[e]=0;e==c&&++c,++r[e]}}return X0(a=new lU(n.e,c,r)),a}function Oxn(n){var t,e,i,r;return e=new $w(r=WJ(n)),i=new Lw(r),gun(t=new Np,(!n.d&&(n.d=new h_(KOt,n,8,5)),n.d)),gun(t,(!n.e&&(n.e=new h_(KOt,n,7,4)),n.e)),BB(P4($V(AV(new Rq(null,new w1(t,16)),e),i),x7(new Q,new Y,new cn,new an,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Xet),Uet]))),21)}function Axn(n,t,e,i){var r,c,a,u,o;if(ZM(),u=BB(t,66).Oj(),$xn(n.e,t)){if(t.hi()&&UFn(n,t,i,cL(t,99)&&0!=(BB(t,18).Bb&BQn)))throw Hp(new Ky(a8n))}else for(o=axn(n.e.Tg(),t),r=BB(n.g,119),a=0;a<n.i;++a)if(c=r[a],o.rl(c.ak()))throw Hp(new Ky(C7n));sln(n,EPn(n,t,e),u?BB(i,72):Z3(t,i))}function $xn(n,t){var e,i,r;return ZM(),!!t.$j()||-2==t.Zj()&&(t==(TOn(),lLt)||t==sLt||t==hLt||t==fLt||!(Awn(r=n.Tg(),t)>=0)&&(!(e=Fqn((CPn(),Z$t),r,t))||((i=e.Zj())>1||-1==i)&&3!=DW(B7(Z$t,e))))}function Lxn(n,t,e,i){var r,c,a,u,o;return u=PTn(BB(Wtn((!t.b&&(t.b=new h_(_Ot,t,4,7)),t.b),0),82)),o=PTn(BB(Wtn((!t.c&&(t.c=new h_(_Ot,t,5,8)),t.c),0),82)),JJ(u)==JJ(o)||Itn(o,u)?null:(a=XJ(t))==e?i:(c=BB(RX(n.a,a),10))&&(r=c.e)?r:null}function Nxn(n,t){var e;switch(OTn(t,"Label side selection ("+(e=BB(mMn(n,(HXn(),Jdt)),276))+")",1),e.g){case 0:TAn(n,(Xyn(),jIt));break;case 1:TAn(n,(Xyn(),EIt));break;case 2:sBn(n,(Xyn(),jIt));break;case 3:sBn(n,(Xyn(),EIt));break;case 4:uDn(n,(Xyn(),jIt));break;case 5:uDn(n,(Xyn(),EIt))}HSn(t)}function xxn(n,t,e){var i,r,c,a,u;if((c=n[lj(e,n.length)])[0].k==(uSn(),Mut))for(r=fj(e,c.length),u=t.j,i=0;i<u.c.length;i++)l1(i,u.c.length),a=BB(u.c[i],11),(e?a.j==(kUn(),oCt):a.j==(kUn(),ICt))&&qy(TD(mMn(a,(hWn(),elt))))&&(c5(u,i,BB(mMn(c[r],(hWn(),dlt)),11)),r+=e?1:-1)}function Dxn(n,t){var e,i,r,c,a;a=new Np,e=t;do{(c=BB(RX(n.b,e),128)).B=e.c,c.D=e.d,a.c[a.c.length]=c,e=BB(RX(n.k,e),17)}while(e);return l1(0,a.c.length),(i=BB(a.c[0],128)).j=!0,i.A=BB(i.d.a.ec().Kc().Pb(),17).c.i,(r=BB(xq(a,a.c.length-1),128)).q=!0,r.C=BB(r.d.a.ec().Kc().Pb(),17).d.i,a}function Rxn(n){if(null==n.g)switch(n.p){case 0:n.g=fZ(n)?(hN(),vtt):(hN(),ptt);break;case 1:n.g=Pnn(D3(n));break;case 2:n.g=fun(Q1(n));break;case 3:n.g=OW(n);break;case 4:n.g=new Nb(CW(n));break;case 6:n.g=jgn(AW(n));break;case 5:n.g=iln(hJ(n));break;case 7:n.g=rln(K3(n))}return n.g}function _xn(n){if(null==n.n)switch(n.p){case 0:n.n=lZ(n)?(hN(),vtt):(hN(),ptt);break;case 1:n.n=Pnn(R3(n));break;case 2:n.n=fun(Y1(n));break;case 3:n.n=LW(n);break;case 4:n.n=new Nb(NW(n));break;case 6:n.n=jgn($W(n));break;case 5:n.n=iln(fJ(n));break;case 7:n.n=rln(_3(n))}return n.n}function Kxn(n){var t,e,i,r,c,a;for(r=new Wb(n.a.a);r.a<r.c.c.length;)(e=BB(n0(r),307)).g=0,e.i=0,e.e.a.$b();for(i=new Wb(n.a.a);i.a<i.c.c.length;)for(t=(e=BB(n0(i),307)).a.a.ec().Kc();t.Ob();)for(a=BB(t.Pb(),57).c.Kc();a.Ob();)(c=BB(a.Pb(),57)).a!=e&&(TU(e.e,c),++c.a.g,++c.a.i)}function Fxn(n,t){var e,i,r;if(!ZU(n.a,t.b))throw Hp(new Fy("Invalid hitboxes for scanline overlap calculation."));for(r=!1,i=new Fb(new BR(new xN(new Kb(n.a.a).a).b));aS(i.a.a);)if(e=BB(mx(i.a).cd(),65),eon(t.b,e))xj(n.b.a,t.b,e),r=!0;else if(r)break}function Bxn(n){var t,i,r,c,a;c=BB(mMn(n,(HXn(),Fgt)),21),a=BB(mMn(n,qgt),21),t=new wA(i=new xI(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a)),c.Hc((mdn(),DCt))&&(r=BB(mMn(n,Hgt),8),a.Hc((nKn(),GCt))&&(r.a<=0&&(r.a=20),r.b<=0&&(r.b=20)),t.a=e.Math.max(i.a,r.a),t.b=e.Math.max(i.b,r.b)),XBn(n,i,t)}function Hxn(n,t){var e,i,r,c,a,u,o,s;r=t?new pc:new vc,c=!1;do{for(c=!1,a=(t?ean(n.b):n.b).Kc();a.Ob();)for(s=a0(BB(a.Pb(),29).a),t||new fy(s),o=new Wb(s);o.a<o.c.c.length;)u=BB(n0(o),10),r.Mb(u)&&(i=u,e=BB(mMn(u,(hWn(),Rft)),305),c=eRn(i,t?e.b:e.k,t,!1))}while(c)}function qxn(n,t,e){var i,r,c,a;for(OTn(e,"Longest path layering",1),n.a=t,a=n.a.a,n.b=x8(ANt,hQn,25,a.c.length,15,1),i=0,c=new Wb(a);c.a<c.c.c.length;)BB(n0(c),10).p=i,n.b[i]=-1,++i;for(r=new Wb(a);r.a<r.c.c.length;)D$n(n,BB(n0(r),10));a.c=x8(Ant,HWn,1,0,5,1),n.a=null,n.b=null,HSn(e)}function Gxn(n,t){var e,i,r;t.a?(ZU(n.b,t.b),n.a[t.b.i]=BB(k_(n.b,t.b),81),(e=BB(y_(n.b,t.b),81))&&(n.a[e.i]=t.b)):(!!(i=BB(k_(n.b,t.b),81))&&i==n.a[t.b.i]&&!!i.d&&i.d!=t.b.d&&i.f.Fc(t.b),!!(r=BB(y_(n.b,t.b),81))&&n.a[r.i]==t.b&&!!r.d&&r.d!=t.b.d&&t.b.f.Fc(r),MN(n.b,t.b))}function zxn(n,t){var i,r,c,a,u,o;return a=n.d,(o=Gy(MD(mMn(n,(HXn(),agt)))))<0&&hon(n,agt,o=0),t.o.b=o,u=e.Math.floor(o/2),qIn(r=new ISn,(kUn(),ICt)),IZ(r,t),r.n.b=u,qIn(c=new ISn,oCt),IZ(c,t),c.n.b=u,MZ(n,r),qan(i=new wY,n),hon(i,vgt,null),SZ(i,c),MZ(i,a),jFn(t,n,i),sIn(n,i),i}function Uxn(n){var t,e;return e=BB(mMn(n,(hWn(),Zft)),21),t=new B2,e.Hc((bDn(),bft))&&(Jcn(t,byt),Jcn(t,dyt)),(e.Hc(dft)||qy(TD(mMn(n,(HXn(),ugt)))))&&(Jcn(t,dyt),e.Hc(gft)&&Jcn(t,gyt)),e.Hc(lft)&&Jcn(t,lyt),e.Hc(vft)&&Jcn(t,pyt),e.Hc(wft)&&Jcn(t,wyt),e.Hc(sft)&&Jcn(t,hyt),e.Hc(fft)&&Jcn(t,fyt),t}function Xxn(n,t){var e,i,r,c,a,u,o,s,h;return c=(e=n.d)+(i=t.d),a=n.e!=t.e?-1:1,2==c?(h=dG(o=cbn(e0(n.a[0],UQn),e0(t.a[0],UQn))),0==(s=dG(jz(o,32)))?new X6(a,h):new lU(a,2,Pun(Gk(ANt,1),hQn,25,15,[h,s]))):(Dfn(n.a,e,t.a,i,r=x8(ANt,hQn,25,c,15,1)),X0(u=new lU(a,c,r)),u)}function Wxn(n,t,e,i){var r,c;return t?0==(r=n.a.ue(e.d,t.d))?(i.d=pR(t,e.e),i.b=!0,t):(c=r<0?0:1,t.a[c]=Wxn(n,t.a[c],e,i),Vy(t.a[c])&&(Vy(t.a[1-c])?(t.b=!0,t.a[0].b=!1,t.a[1].b=!1):Vy(t.a[c].a[c])?t=wrn(t,1-c):Vy(t.a[c].a[1-c])&&(t=r2(t,1-c))),t):e}function Vxn(n,t,i){var r,c,a,u;c=n.i,r=n.n,Y5(n,(Dtn(),Git),c.c+r.b,i),Y5(n,Uit,c.c+c.b-r.c-i[2],i),u=c.b-r.b-r.c,i[0]>0&&(i[0]+=n.d,u-=i[0]),i[2]>0&&(i[2]+=n.d,u-=i[2]),a=e.Math.max(0,u),i[1]=e.Math.max(i[1],u),Y5(n,zit,c.c+r.b+i[0]-(i[1]-u)/2,i),t==zit&&(n.c.b=a,n.c.c=c.c+r.b+(a-u)/2)}function Qxn(){this.c=x8(xNt,qQn,25,(kUn(),Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])).length,15,1),this.b=x8(xNt,qQn,25,Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt]).length,15,1),this.a=x8(xNt,qQn,25,Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt]).length,15,1),mS(this.c,RQn),mS(this.b,_Qn),mS(this.a,_Qn)}function Yxn(n,t,e){var i,r,c,a;if(t<=e?(r=t,c=e):(r=e,c=t),i=0,null==n.b)n.b=x8(ANt,hQn,25,2,15,1),n.b[0]=r,n.b[1]=c,n.c=!0;else{if(i=n.b.length,n.b[i-1]+1==r)return void(n.b[i-1]=c);a=x8(ANt,hQn,25,i+2,15,1),aHn(n.b,0,a,0,i),n.b=a,n.b[i-1]>=r&&(n.c=!1,n.a=!1),n.b[i++]=r,n.b[i]=c,n.c||T$n(n)}}function Jxn(n,t,e){var i,r,c,a,u,o,s;for(s=t.d,n.a=new J6(s.c.length),n.c=new xp,u=new Wb(s);u.a<u.c.c.length;)a=BB(n0(u),101),c=new Fan(null),WB(n.a,c),VW(n.c,a,c);for(n.b=new xp,vIn(n,t),i=0;i<s.c.length-1;i++)for(o=BB(xq(t.d,i),101),r=i+1;r<s.c.length;r++)WLn(n,o,BB(xq(t.d,r),101),e)}function Zxn(n,t,e){var i,r,c,a,u,o;if(!h3(t)){for(OTn(o=mcn(e,(cL(t,14)?BB(t,14).gc():F3(t.Kc()))/n.a|0),z3n,1),u=new Ca,a=0,c=t.Kc();c.Ob();)i=BB(c.Pb(),86),u=Wen(Pun(Gk(xnt,1),HWn,20,0,[u,new bg(i)])),a<i.f.b&&(a=i.f.b);for(r=t.Kc();r.Ob();)hon(i=BB(r.Pb(),86),(qqn(),ukt),a);HSn(o),Zxn(n,u,e)}}function nDn(n,t){var i,r,c,a,u,o,s;for(i=_Qn,uSn(),o=Iut,c=new Wb(t.a);c.a<c.c.c.length;)(a=(r=BB(n0(c),10)).k)!=Iut&&(null==(u=MD(mMn(r,(hWn(),plt))))?(i=e.Math.max(i,0),r.n.b=i+XN(n.a,a,o)):r.n.b=(kW(u),u)),s=XN(n.a,a,o),r.n.b<i+s+r.d.d&&(r.n.b=i+s+r.d.d),i=r.n.b+r.o.b+r.d.a,o=a}function tDn(n,t,e){var i,r,c;for(qan(c=new EAn(XXn(qSn(cDn(t,!1,!1)),Gy(MD(ZAn(t,(Epn(),pct))))+n.a)),t),VW(n.b,t,c),e.c[e.c.length]=c,!t.n&&(t.n=new eU(zOt,t,1,7)),r=new AL(t.n);r.e!=r.i.gc();)i=JRn(n,BB(kpn(r),137),!0,0,0),e.c[e.c.length]=i;return c}function eDn(n,t,e,i,r){var c,a,u;if(n.d&&n.d.lg(r),Dvn(n,e,BB(r.Xb(0),33),!1))return!0;if(Dvn(n,i,BB(r.Xb(r.gc()-1),33),!0))return!0;if(NMn(n,r))return!0;for(u=r.Kc();u.Ob();)for(a=BB(u.Pb(),33),c=t.Kc();c.Ob();)if(KDn(n,a,BB(c.Pb(),33)))return!0;return!1}function iDn(n,t,e){var i,r,c,a,u,o,s,h,f;f=t.c.length;n:for(c=BB((s=n.Yg(e))>=0?n._g(s,!1,!0):cOn(n,e,!1),58).Kc();c.Ob();){for(r=BB(c.Pb(),56),h=0;h<f;++h)if(l1(h,t.c.length),o=(a=BB(t.c[h],72)).dd(),u=a.ak(),i=r.bh(u,!1),null==o?null!=i:!Nfn(o,i))continue n;return r}return null}function rDn(n,t,e,i){var r,c,a,u;for(r=BB(DSn(t,(kUn(),ICt)).Kc().Pb(),11),c=BB(DSn(t,oCt).Kc().Pb(),11),u=new Wb(n.j);u.a<u.c.c.length;){for(a=BB(n0(u),11);0!=a.e.c.length;)MZ(BB(xq(a.e,0),17),r);for(;0!=a.g.c.length;)SZ(BB(xq(a.g,0),17),c)}e||hon(t,(hWn(),hlt),null),i||hon(t,(hWn(),flt),null)}function cDn(n,t,e){var i,r;if(0==(!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i)return qun(n);if(i=BB(Wtn((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a),0),202),t&&(sqn((!i.a&&(i.a=new $L(xOt,i,5)),i.a)),Cen(i,0),Aen(i,0),Ten(i,0),Oen(i,0)),e)for(!n.a&&(n.a=new eU(FOt,n,6,6)),r=n.a;r.i>1;)fDn(r,r.i-1);return i}function aDn(n,t){var e,i,r,c,a,u,o;for(OTn(t,"Comment post-processing",1),c=new Wb(n.b);c.a<c.c.c.length;){for(r=BB(n0(c),29),i=new Np,u=new Wb(r.a);u.a<u.c.c.length;)a=BB(n0(u),10),o=BB(mMn(a,(hWn(),_lt)),15),e=BB(mMn(a,Dft),15),(o||e)&&(Wzn(a,o,e),o&&gun(i,o),e&&gun(i,e));gun(r.a,i)}HSn(t)}function uDn(n,t){var e,i,r,c,a,u;for(e=new Lp,r=new Wb(n.b);r.a<r.c.c.length;){for(u=!0,i=0,a=new Wb(BB(n0(r),29).a);a.a<a.c.c.length;)switch((c=BB(n0(a),10)).k.g){case 4:++i;case 1:w3(e,c);break;case 0:oIn(c,t);default:e.b==e.c||pKn(e,i,u,!1,t),u=!1,i=0}e.b==e.c||pKn(e,i,u,!0,t)}}function oDn(n,t){var e,i,r,c,a,u;for(r=new Np,e=0;e<=n.i;e++)(i=new HX(t)).p=n.i-e,r.c[r.c.length]=i;for(u=new Wb(n.o);u.a<u.c.c.length;)PZ(a=BB(n0(u),10),BB(xq(r,n.i-n.f[a.p]),29));for(c=new Wb(r);c.a<c.c.c.length;)0==BB(n0(c),29).a.c.length&&AU(c);t.b.c=x8(Ant,HWn,1,0,5,1),gun(t.b,r)}function sDn(n,t){var e,i,r,c,a,u;for(e=0,u=new Wb(t);u.a<u.c.c.length;){for(a=BB(n0(u),11),nhn(n.b,n.d[a.p]),r=new m6(a.b);y$(r.a)||y$(r.b);)(c=ME(n,a==(i=BB(y$(r.a)?n0(r.a):n0(r.b),17)).c?i.d:i.c))>n.d[a.p]&&(e+=n5(n.b,c),d3(n.a,iln(c)));for(;!Wy(n.a);)Mnn(n.b,BB(dU(n.a),19).a)}return e}function hDn(n,t,e){var i,r,c,a;for(c=(!t.a&&(t.a=new eU(UOt,t,10,11)),t.a).i,r=new AL((!t.a&&(t.a=new eU(UOt,t,10,11)),t.a));r.e!=r.i.gc();)0==(!(i=BB(kpn(r),33)).a&&(i.a=new eU(UOt,i,10,11)),i.a).i||(c+=hDn(n,i,!1));if(e)for(a=JJ(t);a;)c+=(!a.a&&(a.a=new eU(UOt,a,10,11)),a.a).i,a=JJ(a);return c}function fDn(n,t){var e,i,r,c;return n.ej()?(i=null,r=n.fj(),n.ij()&&(i=n.kj(n.pi(t),null)),e=n.Zi(4,c=Lyn(n,t),null,t,r),n.bj()&&null!=c?(i=n.dj(c,i))?(i.Ei(e),i.Fi()):n.$i(e):i?(i.Ei(e),i.Fi()):n.$i(e),c):(c=Lyn(n,t),n.bj()&&null!=c&&(i=n.dj(c,null))&&i.Fi(),c)}function lDn(n){var t,i,r,c,a,u,o,s,h,f;for(h=n.a,t=new Rv,s=0,r=new Wb(n.d);r.a<r.c.c.length;){for(f=0,Krn((i=BB(n0(r),222)).b,new $n),u=spn(i.b,0);u.b!=u.d.c;)a=BB(b3(u),222),t.a._b(a)&&(c=i.c,f<(o=a.c).d+o.a+h&&f+c.a+h>o.d&&(f=o.d+o.a+h));i.c.d=f,t.a.zc(i,t),s=e.Math.max(s,i.c.d+i.c.a)}return s}function bDn(){bDn=O,hft=new LP("COMMENTS",0),lft=new LP("EXTERNAL_PORTS",1),bft=new LP("HYPEREDGES",2),wft=new LP("HYPERNODES",3),dft=new LP("NON_FREE_PORTS",4),gft=new LP("NORTH_SOUTH_PORTS",5),vft=new LP(G1n,6),sft=new LP("CENTER_LABELS",7),fft=new LP("END_LABELS",8),pft=new LP("PARTITIONS",9)}function wDn(n){var t,e,i,r,c;for(r=new Np,t=new $q((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a)),i=new oz(ZL(dLn(n).a.Kc(),new h));dAn(i);)cL(Wtn((!(e=BB(U5(i),79)).b&&(e.b=new h_(_Ot,e,4,7)),e.b),0),186)||(c=PTn(BB(Wtn((!e.c&&(e.c=new h_(_Ot,e,5,8)),e.c),0),82)),t.a._b(c)||(r.c[r.c.length]=c));return r}function dDn(n){var t,e,i,r,c;for(r=new Rv,t=new $q((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a)),i=new oz(ZL(dLn(n).a.Kc(),new h));dAn(i);)cL(Wtn((!(e=BB(U5(i),79)).b&&(e.b=new h_(_Ot,e,4,7)),e.b),0),186)||(c=PTn(BB(Wtn((!e.c&&(e.c=new h_(_Ot,e,5,8)),e.c),0),82)),t.a._b(c)||r.a.zc(c,r));return r}function gDn(n,t,e,i,r){return i<0?((i=zTn(n,r,Pun(Gk(Qtt,1),sVn,2,6,[YVn,JVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn,uQn,oQn]),t))<0&&(i=zTn(n,r,Pun(Gk(Qtt,1),sVn,2,6,["Jan","Feb","Mar","Apr",tQn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function pDn(n,t,e,i,r){return i<0?((i=zTn(n,r,Pun(Gk(Qtt,1),sVn,2,6,[YVn,JVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn,uQn,oQn]),t))<0&&(i=zTn(n,r,Pun(Gk(Qtt,1),sVn,2,6,["Jan","Feb","Mar","Apr",tQn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function vDn(n,t,e,i,r,c){var a,u,o;if(u=32,i<0){if(t[0]>=n.length)return!1;if(43!=(u=fV(n,t[0]))&&45!=u)return!1;if(++t[0],(i=UCn(n,t))<0)return!1;45==u&&(i=-i)}return 32==u&&t[0]-e==2&&2==r.b&&(a=(o=(new AT).q.getFullYear()-sQn+sQn-80)%100,c.a=i==a,i+=100*(o/100|0)+(i<a?100:0)),c.p=i,!0}function mDn(n,t){var i,r,c;JJ(n)&&(c=BB(mMn(t,(HXn(),Fgt)),174),GC(ZAn(n,ept))===GC((QEn(),YIt))&&Ypn(n,ept,QIt),GM(),r=qzn(new Dy(JJ(n)),new JN(JJ(n)?new Dy(JJ(n)):null,n),!1,!0),orn(c,(mdn(),DCt)),(i=BB(mMn(t,Hgt),8)).a=e.Math.max(r.a,i.a),i.b=e.Math.max(r.b,i.b))}function yDn(n,t,e){var i,r,c,a,u,o;for(a=BB(mMn(n,(hWn(),nlt)),15).Kc();a.Ob();){switch(c=BB(a.Pb(),10),BB(mMn(c,(HXn(),kgt)),163).g){case 2:PZ(c,t);break;case 4:PZ(c,e)}for(r=new oz(ZL(hbn(c).a.Kc(),new h));dAn(r);)(i=BB(U5(r),17)).c&&i.d||(u=!i.d,o=BB(mMn(i,mlt),11),u?MZ(i,o):SZ(i,o))}}function kDn(){kDn=O,Bst=new WV(mJn,0,(kUn(),sCt),sCt),Gst=new WV(kJn,1,SCt,SCt),Fst=new WV(yJn,2,oCt,oCt),Xst=new WV(jJn,3,ICt,ICt),qst=new WV("NORTH_WEST_CORNER",4,ICt,sCt),Hst=new WV("NORTH_EAST_CORNER",5,sCt,oCt),Ust=new WV("SOUTH_WEST_CORNER",6,SCt,ICt),zst=new WV("SOUTH_EAST_CORNER",7,oCt,SCt)}function jDn(){jDn=O,MMt=Pun(Gk(LNt,1),FQn,25,14,[1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,87178291200,1307674368e3,{l:3506176,m:794077,h:1},{l:884736,m:916411,h:20},{l:3342336,m:3912489,h:363},{l:589824,m:3034138,h:6914},{l:3407872,m:1962506,h:138294}]),e.Math.pow(2,-65)}function EDn(n,t){var e,i,r,c,a;if(0==n.c.length)return new rC(iln(0),iln(0));for(e=(l1(0,n.c.length),BB(n.c[0],11)).j,a=0,c=t.g,i=t.g+1;a<n.c.length-1&&e.g<c;)e=(l1(++a,n.c.length),BB(n.c[a],11)).j;for(r=a;r<n.c.length-1&&e.g<i;)++r,e=(l1(a,n.c.length),BB(n.c[a],11)).j;return new rC(iln(a),iln(r))}function TDn(n,t,i){var r,c,a,u,o,s,h,f,l,b;for(a=t.c.length,l1(i,t.c.length),o=(u=BB(t.c[i],286)).a.o.a,l=u.c,b=0,h=u.c;h<=u.f;h++){if(o<=n.a[h])return h;for(f=n.a[h],s=null,c=i+1;c<a;c++)l1(c,t.c.length),(r=BB(t.c[c],286)).c<=h&&r.f>=h&&(s=r);s&&(f=e.Math.max(f,s.a.o.a)),f>b&&(l=h,b=f)}return l}function MDn(n,t,e){var i,r,c;if(n.e=e,n.d=0,n.b=0,n.f=1,n.i=t,16==(16&n.e)&&(n.i=p_n(n.i)),n.j=n.i.length,QXn(n),c=Vdn(n),n.d!=n.j)throw Hp(new ak(kWn((u$(),w8n))));if(n.g){for(i=0;i<n.g.a.c.length;i++)if(r=BB(bW(n.g,i),584),n.f<=r.a)throw Hp(new ak(kWn((u$(),d8n))));n.g.a.c=x8(Ant,HWn,1,0,5,1)}return c}function SDn(n,t){var e,i,r;if(null==t){for(!n.a&&(n.a=new eU(WAt,n,9,5)),i=new AL(n.a);i.e!=i.i.gc();)if(null==(null==(r=(e=BB(kpn(i),678)).c)?e.zb:r))return e}else for(!n.a&&(n.a=new eU(WAt,n,9,5)),i=new AL(n.a);i.e!=i.i.gc();)if(m_(t,null==(r=(e=BB(kpn(i),678)).c)?e.zb:r))return e;return null}function PDn(n,t){var e;switch(e=null,t.g){case 1:n.e.Xe((sWn(),ePt))&&(e=BB(n.e.We(ePt),249));break;case 3:n.e.Xe((sWn(),iPt))&&(e=BB(n.e.We(iPt),249));break;case 2:n.e.Xe((sWn(),tPt))&&(e=BB(n.e.We(tPt),249));break;case 4:n.e.Xe((sWn(),rPt))&&(e=BB(n.e.We(rPt),249))}return!e&&(e=BB(n.e.We((sWn(),ZSt)),249)),e}function IDn(n,t,e){var i,r,c,a,u,o;for(t.p=1,r=t.c,o=xwn(t,(ain(),qvt)).Kc();o.Ob();)for(i=new Wb(BB(o.Pb(),11).g);i.a<i.c.c.length;)t!=(u=BB(n0(i),17).d.i)&&u.c.p<=r.p&&((c=r.p+1)==e.b.c.length?((a=new HX(e)).p=c,WB(e.b,a),PZ(u,a)):PZ(u,a=BB(xq(e.b,c),29)),IDn(n,u,e))}function CDn(n,t,i){var r,c,a,u,o,s;for(c=i,a=0,o=new Wb(t);o.a<o.c.c.length;)Ypn(u=BB(n0(o),33),(Uyn(),Ljt),iln(c++)),s=wDn(u),r=e.Math.atan2(u.j+u.f/2,u.i+u.g/2),(r+=r<0?Z3n:0)<.7853981633974483||r>p4n?m$(s,n.b):r<=p4n&&r>v4n?m$(s,n.d):r<=v4n&&r>m4n?m$(s,n.c):r<=m4n&&m$(s,n.a),a=CDn(n,s,a);return c}function ODn(){var n;for(ODn=O,Jtt=new X6(1,1),net=new X6(1,10),eet=new X6(0,0),Ytt=new X6(-1,1),Ztt=Pun(Gk(oet,1),sVn,91,0,[eet,Jtt,new X6(1,2),new X6(1,3),new X6(1,4),new X6(1,5),new X6(1,6),new X6(1,7),new X6(1,8),new X6(1,9),net]),tet=x8(oet,sVn,91,32,0,1),n=0;n<tet.length;n++)tet[n]=npn(yz(1,n))}function ADn(n,t,e,i,r,c){var a,u,o,s;for(u=!jE(AV(n.Oc(),new aw(new Je))).sd((dM(),tit)),a=n,c==(Ffn(),HPt)&&(a=cL(a,152)?o6(BB(a,152)):cL(a,131)?BB(a,131).a:cL(a,54)?new fy(a):new IT(a)),s=a.Kc();s.Ob();)(o=BB(s.Pb(),70)).n.a=t.a,o.n.b=u?t.b+(i.b-o.o.b)/2:r?t.b:t.b+i.b-o.o.b,t.a+=o.o.a+e}function $Dn(n,t,e,i){var r,c,a,u,o;for(r=(i.c+i.a)/2,yQ(t.j),DH(t.j,r),yQ(e.e),DH(e.e,r),o=new zj,a=new Wb(n.f);a.a<a.c.c.length;)Rjn(o,t,u=BB(n0(a),129).a),Rjn(o,e,u);for(c=new Wb(n.k);c.a<c.c.c.length;)Rjn(o,t,u=BB(n0(c),129).b),Rjn(o,e,u);return o.b+=2,o.a+=LQ(t,n.q),o.a+=LQ(n.q,e),o}function LDn(n,t,e){var i,r,c,a,u;if(!h3(t)){for(OTn(u=mcn(e,(cL(t,14)?BB(t,14).gc():F3(t.Kc()))/n.a|0),z3n,1),a=new Aa,c=null,r=t.Kc();r.Ob();)i=BB(r.Pb(),86),a=Wen(Pun(Gk(xnt,1),HWn,20,0,[a,new bg(i)])),c&&(hon(c,(qqn(),bkt),i),hon(i,ckt,c),G8(i)==G8(c)&&(hon(c,wkt,i),hon(i,akt,c))),c=i;HSn(u),LDn(n,a,e)}}function NDn(n){var t,e,i,r,c,a,u;for(e=n.i,t=n.n,u=e.d,n.f==(G7(),rrt)?u+=(e.a-n.e.b)/2:n.f==irt&&(u+=e.a-n.e.b),r=new Wb(n.d);r.a<r.c.c.length;){switch(a=(i=BB(n0(r),181)).rf(),(c=new Gj).b=u,u+=a.b+n.a,n.b.g){case 0:c.a=e.c+t.b;break;case 1:c.a=e.c+t.b+(e.b-a.a)/2;break;case 2:c.a=e.c+e.b-t.c-a.a}i.tf(c)}}function xDn(n){var t,e,i,r,c,a,u;for(e=n.i,t=n.n,u=e.c,n.b==(J9(),Qit)?u+=(e.b-n.e.a)/2:n.b==Jit&&(u+=e.b-n.e.a),r=new Wb(n.d);r.a<r.c.c.length;){switch(a=(i=BB(n0(r),181)).rf(),(c=new Gj).a=u,u+=a.a+n.a,n.f.g){case 0:c.b=e.d+t.d;break;case 1:c.b=e.d+t.d+(e.a-a.b)/2;break;case 2:c.b=e.d+e.a-t.a-a.b}i.tf(c)}}function DDn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;s=e.a.c,a=e.a.c+e.a.b,l=(c=BB(RX(e.c,t),459)).f,b=c.a,u=new xI(s,l),h=new xI(a,b),r=s,e.p||(r+=n.c),o=new xI(r+=e.F+e.v*n.b,l),f=new xI(r,b),nin(t.a,Pun(Gk(PMt,1),sVn,8,0,[u,o])),e.d.a.gc()>1&&(i=new xI(r,e.b),DH(t.a,i)),nin(t.a,Pun(Gk(PMt,1),sVn,8,0,[f,h]))}function RDn(n){NM(n,new MTn(vj(wj(pj(gj(new du,K5n),"ELK Randomizer"),'Distributes the nodes randomly on the plane, leading to very obfuscating layouts. Can be useful to demonstrate the power of "real" layout algorithms.'),new Qu))),u2(n,K5n,QJn,LCt),u2(n,K5n,vZn,15),u2(n,K5n,yZn,iln(0)),u2(n,K5n,VJn,dZn)}function _Dn(){var n,t,e,i,r,c;for(_Dn=O,QLt=x8(NNt,v6n,25,255,15,1),YLt=x8(ONt,WVn,25,16,15,1),t=0;t<255;t++)QLt[t]=-1;for(e=57;e>=48;e--)QLt[e]=e-48<<24>>24;for(i=70;i>=65;i--)QLt[i]=i-65+10<<24>>24;for(r=102;r>=97;r--)QLt[r]=r-97+10<<24>>24;for(c=0;c<10;c++)YLt[c]=48+c&QVn;for(n=10;n<=15;n++)YLt[n]=65+n-10&QVn}function KDn(n,t,e){var i,r,c,a,u,o,s,h;return u=t.i-n.g/2,o=e.i-n.g/2,s=t.j-n.g/2,h=e.j-n.g/2,c=t.g+n.g/2,a=e.g+n.g/2,i=t.f+n.g/2,r=e.f+n.g/2,u<o+a&&o<u&&s<h+r&&h<s||o<u+c&&u<o&&h<s+i&&s<h||u<o+a&&o<u&&s<h&&h<s+i||o<u+c&&u<o&&s<h+r&&h<s}function FDn(n){var t,i,r,c,a;c=BB(mMn(n,(HXn(),Fgt)),21),a=BB(mMn(n,qgt),21),t=new wA(i=new xI(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a)),c.Hc((mdn(),DCt))&&(r=BB(mMn(n,Hgt),8),a.Hc((nKn(),GCt))&&(r.a<=0&&(r.a=20),r.b<=0&&(r.b=20)),t.a=e.Math.max(i.a,r.a),t.b=e.Math.max(i.b,r.b)),qy(TD(mMn(n,Bgt)))||UBn(n,i,t)}function BDn(n,t){var e,i,r,c;for(c=abn(t,(kUn(),SCt)).Kc();c.Ob();)i=BB(c.Pb(),11),(e=BB(mMn(i,(hWn(),Elt)),10))&&UNn(aM(cM(uM(rM(new Hv,0),.1),n.i[t.p].d),n.i[e.p].a));for(r=abn(t,sCt).Kc();r.Ob();)i=BB(r.Pb(),11),(e=BB(mMn(i,(hWn(),Elt)),10))&&UNn(aM(cM(uM(rM(new Hv,0),.1),n.i[e.p].d),n.i[t.p].a))}function HDn(n){var t,e,i,r,c;if(!n.c){if(c=new Eo,null==(t=P$t).a.zc(n,t)){for(i=new AL(a4(n));i.e!=i.i.gc();)cL(r=lFn(e=BB(kpn(i),87)),88)&&pX(c,HDn(BB(r,26))),f9(c,e);t.a.Bc(n),t.a.gc()}$wn(c),chn(c),n.c=new NO((BB(Wtn(QQ((QX(),t$t).o),15),18),c.i),c.g),P5(n).b&=-33}return n.c}function qDn(n){var t;if(10!=n.c)throw Hp(new ak(kWn((u$(),g8n))));switch(t=n.a){case 110:t=10;break;case 114:t=13;break;case 116:t=9;break;case 92:case 124:case 46:case 94:case 45:case 63:case 42:case 43:case 123:case 125:case 40:case 41:case 91:case 93:break;default:throw Hp(new ak(kWn((u$(),U8n))))}return t}function GDn(n){var t,e,i,r;if(0==n.l&&0==n.m&&0==n.h)return"0";if(n.h==IQn&&0==n.m&&0==n.l)return"-9223372036854775808";if(n.h>>19!=0)return"-"+GDn(aon(n));for(e=n,i="";0!=e.l||0!=e.m||0!=e.h;){if(e=Aqn(e,F5(AQn),!0),t=""+TE(ltt),0!=e.l||0!=e.m||0!=e.h)for(r=9-t.length;r>0;r--)t="0"+t;i=t+i}return i}function zDn(){if(!Object.create||!Object.getOwnPropertyNames)return!1;var n="__proto__",t=Object.create(null);return void 0===t[n]&&0==Object.getOwnPropertyNames(t).length&&(t[n]=42,42===t[n]&&0!=Object.getOwnPropertyNames(t).length)}function UDn(n){var t,e,i,r,c,a,u;for(t=!1,e=0,r=new Wb(n.d.b);r.a<r.c.c.length;)for((i=BB(n0(r),29)).p=e++,a=new Wb(i.a);a.a<a.c.c.length;)c=BB(n0(a),10),!t&&!h3(hbn(c))&&(t=!0);u=EG((Ffn(),BPt),Pun(Gk(WPt,1),$Vn,103,0,[KPt,FPt])),t||(orn(u,HPt),orn(u,_Pt)),n.a=new ltn(u),$U(n.f),$U(n.b),$U(n.e),$U(n.g)}function XDn(n,t,e){var i,r,c,a,u,o,s,h,f;for(i=e.c,r=e.d,u=g1(t.c),o=g1(t.d),i==t.c?(u=lLn(n,u,r),o=sMn(t.d)):(u=sMn(t.c),o=lLn(n,o,r)),r5(s=new _j(t.a),u,s.a,s.a.a),r5(s,o,s.c.b,s.c),a=t.c==i,f=new Jv,c=0;c<s.b-1;++c)h=new rC(BB(Dpn(s,c),8),BB(Dpn(s,c+1),8)),a&&0==c||!a&&c==s.b-2?f.b=h:WB(f.a,h);return f}function WDn(n,t){var e,i,r,c;if(0!=(c=n.j.g-t.j.g))return c;if(e=BB(mMn(n,(HXn(),ipt)),19),i=BB(mMn(t,ipt),19),e&&i&&0!=(r=e.a-i.a))return r;switch(n.j.g){case 1:return Pln(n.n.a,t.n.a);case 2:return Pln(n.n.b,t.n.b);case 3:return Pln(t.n.a,n.n.a);case 4:return Pln(t.n.b,n.n.b);default:throw Hp(new Fy(r1n))}}function VDn(n,t,i,r){var c,a,u,o;if(F3((qK(),new oz(ZL(hbn(t).a.Kc(),new h))))>=n.a)return-1;if(!eTn(t,i))return-1;if(h3(BB(r.Kb(t),20)))return 1;for(c=0,u=BB(r.Kb(t),20).Kc();u.Ob();){if(-1==(o=VDn(n,(a=BB(u.Pb(),17)).c.i==t?a.d.i:a.c.i,i,r)))return-1;if((c=e.Math.max(c,o))>n.c-1)return-1}return c+1}function QDn(n,t){var e,i,r,c,a,u;if(GC(t)===GC(n))return!0;if(!cL(t,15))return!1;if(i=BB(t,15),u=n.gc(),i.gc()!=u)return!1;if(a=i.Kc(),n.ni()){for(e=0;e<u;++e)if(r=n.ki(e),c=a.Pb(),null==r?null!=c:!Nfn(r,c))return!1}else for(e=0;e<u;++e)if(r=n.ki(e),c=a.Pb(),GC(r)!==GC(c))return!1;return!0}function YDn(n,t){var e,i,r,c,a,u;if(n.f>0)if(n.qj(),null!=t){for(c=0;c<n.d.length;++c)if(e=n.d[c])for(i=BB(e.g,367),u=e.i,a=0;a<u;++a)if(Nfn(t,(r=i[a]).dd()))return!0}else for(c=0;c<n.d.length;++c)if(e=n.d[c])for(i=BB(e.g,367),u=e.i,a=0;a<u;++a)if(r=i[a],GC(t)===GC(r.dd()))return!0;return!1}function JDn(n,t,e){var i,r,c,a;OTn(e,"Orthogonally routing hierarchical port edges",1),n.a=0,NGn(t,i=UHn(t)),Qqn(n,t,i),fUn(t),r=BB(mMn(t,(HXn(),ept)),98),Izn((l1(0,(c=t.b).c.length),BB(c.c[0],29)),r,t),Izn(BB(xq(c,c.c.length-1),29),r,t),TBn((l1(0,(a=t.b).c.length),BB(a.c[0],29))),TBn(BB(xq(a,a.c.length-1),29)),HSn(e)}function ZDn(n){switch(n){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return n-48<<24>>24;case 97:case 98:case 99:case 100:case 101:case 102:return n-97+10<<24>>24;case 65:case 66:case 67:case 68:case 69:case 70:return n-65+10<<24>>24;default:throw Hp(new Mk("Invalid hexadecimal"))}}function nRn(n,t,e){var i,r,c,a;for(OTn(e,"Processor order nodes",2),n.a=Gy(MD(mMn(t,(IAn(),xkt)))),r=new YT,a=spn(t.b,0);a.b!=a.d.c;)qy(TD(mMn(c=BB(b3(a),86),(qqn(),dkt))))&&r5(r,c,r.c.b,r.c);Px(0!=r.b),_Hn(n,i=BB(r.a.a.c,86)),!e.b&&qin(e,1),BRn(n,i,0-Gy(MD(mMn(i,(qqn(),ukt))))/2,0),!e.b&&qin(e,1),HSn(e)}function tRn(){tRn=O,Rit=new HS("SPIRAL",0),$it=new HS("LINE_BY_LINE",1),Lit=new HS("MANHATTAN",2),Ait=new HS("JITTER",3),xit=new HS("QUADRANTS_LINE_BY_LINE",4),Dit=new HS("QUADRANTS_MANHATTAN",5),Nit=new HS("QUADRANTS_JITTER",6),Oit=new HS("COMBINE_LINE_BY_LINE_MANHATTAN",7),Cit=new HS("COMBINE_JITTER_MANHATTAN",8)}function eRn(n,t,e,i){var r,c,a,u,o,s;for(o=Njn(n,e),s=Njn(t,e),r=!1;o&&s&&(i||myn(o,s,e));)a=Njn(o,e),u=Njn(s,e),A7(t),A7(n),c=o.c,rGn(o,!1),rGn(s,!1),e?(Qyn(t,s.p,c),t.p=s.p,Qyn(n,o.p+1,c),n.p=o.p):(Qyn(n,o.p,c),n.p=o.p,Qyn(t,s.p+1,c),t.p=s.p),PZ(o,null),PZ(s,null),o=a,s=u,r=!0;return r}function iRn(n,t,e,i){var r,c,a,u,o;for(r=!1,c=!1,u=new Wb(i.j);u.a<u.c.c.length;)GC(mMn(a=BB(n0(u),11),(hWn(),dlt)))===GC(e)&&(0==a.g.c.length?0==a.e.c.length||(r=!0):c=!0);return o=0,r&&r^c?o=e.j==(kUn(),sCt)?-n.e[i.c.p][i.p]:t-n.e[i.c.p][i.p]:c&&r^c?o=n.e[i.c.p][i.p]+1:r&&c&&(o=e.j==(kUn(),sCt)?0:t/2),o}function rRn(n,t,e,i,r,c,a,u){var o,s,h;for(o=0,null!=t&&(o^=vvn(t.toLowerCase())),null!=e&&(o^=vvn(e)),null!=i&&(o^=vvn(i)),null!=a&&(o^=vvn(a)),null!=u&&(o^=vvn(u)),s=0,h=c.length;s<h;s++)o^=vvn(c[s]);n?o|=256:o&=-257,r?o|=16:o&=-17,this.f=o,this.i=null==t?null:(kW(t),t),this.a=e,this.d=i,this.j=c,this.g=a,this.e=u}function cRn(n,t,e){var i,r;switch(r=null,t.g){case 1:gcn(),r=Nut;break;case 2:gcn(),r=Dut}switch(i=null,e.g){case 1:gcn(),i=xut;break;case 2:gcn(),i=Lut;break;case 3:gcn(),i=Rut;break;case 4:gcn(),i=_ut}return r&&i?_B(n.j,new Hf(new Jy(Pun(Gk(Lnt,1),HWn,169,0,[BB(yX(r),169),BB(yX(i),169)])))):(SQ(),SQ(),set)}function aRn(n){var t,e,i;switch(t=BB(mMn(n,(HXn(),Hgt)),8),hon(n,Hgt,new xI(t.b,t.a)),BB(mMn(n,kdt),248).g){case 1:hon(n,kdt,(wvn(),LMt));break;case 2:hon(n,kdt,(wvn(),CMt));break;case 3:hon(n,kdt,(wvn(),AMt));break;case 4:hon(n,kdt,(wvn(),$Mt))}(n.q?n.q:(SQ(),SQ(),het))._b(spt)&&(i=(e=BB(mMn(n,spt),8)).a,e.a=e.b,e.b=i)}function uRn(n,t,e,i,r,c){if(this.b=e,this.d=r,n>=t.length)throw Hp(new Ay("Greedy SwitchDecider: Free layer not in graph."));this.c=t[n],this.e=new Q_(i),yrn(this.e,this.c,(kUn(),ICt)),this.i=new Q_(i),yrn(this.i,this.c,oCt),this.f=new lG(this.c),this.a=!c&&r.i&&!r.s&&this.c[0].k==(uSn(),Mut),this.a&&gPn(this,n,t.length)}function oRn(n,t){var e,i,r,c,a,u;c=!n.B.Hc((nKn(),HCt)),a=n.B.Hc(zCt),n.a=new Hwn(a,c,n.c),n.n&&kQ(n.a.n,n.n),jy(n.g,(Dtn(),zit),n.a),t||((i=new Cgn(1,c,n.c)).n.a=n.k,mG(n.p,(kUn(),sCt),i),(r=new Cgn(1,c,n.c)).n.d=n.k,mG(n.p,SCt,r),(u=new Cgn(0,c,n.c)).n.c=n.k,mG(n.p,ICt,u),(e=new Cgn(0,c,n.c)).n.b=n.k,mG(n.p,oCt,e))}function sRn(n){var t,e,i;switch((t=BB(mMn(n.d,(HXn(),Zdt)),218)).g){case 2:e=MXn(n);break;case 3:i=new Np,JT(AV($V(wnn(wnn(new Rq(null,new w1(n.d.b,16)),new Or),new Ar),new $r),new pr),new Id(i)),e=i;break;default:throw Hp(new Fy("Compaction not supported for "+t+" edges."))}gqn(n,e),e5(new Ib(n.g),new Sd(n))}function hRn(n,t){var e;return e=new Zn,t&&qan(e,BB(RX(n.a,DOt),94)),cL(t,470)&&qan(e,BB(RX(n.a,ROt),94)),cL(t,354)?(qan(e,BB(RX(n.a,zOt),94)),e):(cL(t,82)&&qan(e,BB(RX(n.a,_Ot),94)),cL(t,239)?(qan(e,BB(RX(n.a,UOt),94)),e):cL(t,186)?(qan(e,BB(RX(n.a,XOt),94)),e):(cL(t,352)&&qan(e,BB(RX(n.a,KOt),94)),e))}function fRn(){fRn=O,Zct=new XA((sWn(),pPt),iln(1)),cat=new XA(LPt,80),rat=new XA(SPt,5),Fct=new XA(cSt,dZn),nat=new XA(vPt,iln(1)),iat=new XA(kPt,(hN(),!0)),Qct=new WA(50),Vct=new XA(XSt,Qct),Hct=ISt,Yct=uPt,Bct=new XA(dSt,!1),Wct=USt,Xct=qSt,Uct=_St,zct=DSt,Jct=fPt,jSn(),Gct=Cct,aat=Nct,qct=Ict,tat=Act,eat=Lct}function lRn(n){var t,e,i,r,c,a,u;for(u=new v5,a=new Wb(n.a);a.a<a.c.c.length;)if((c=BB(n0(a),10)).k!=(uSn(),Mut))for(KAn(u,c,new Gj),r=new oz(ZL(lbn(c).a.Kc(),new h));dAn(r);)if((i=BB(U5(r),17)).c.i.k!=Mut&&i.d.i.k!=Mut)for(e=spn(i.a,0);e.b!=e.d.c;)Yjn(u,new dP((t=BB(b3(e),8)).a,t.b));return u}function bRn(){bRn=O,RTt=new up(_4n),OM(),xTt=new $O(q4n,DTt=GTt),Lun(),LTt=new $O(K4n,NTt=WTt),$Sn(),ATt=new $O(F4n,$Tt=rTt),PTt=new $O(B4n,null),$6(),CTt=new $O(H4n,OTt=ZEt),IM(),jTt=new $O(G4n,ETt=XEt),TTt=new $O(z4n,(hN(),!1)),MTt=new $O(U4n,iln(64)),STt=new $O(X4n,!0),ITt=nTt}function wRn(n){var t,e,i,r,c;if(null==n.a)if(n.a=x8($Nt,ZYn,25,n.c.b.c.length,16,1),n.a[0]=!1,Lx(n.c,(HXn(),Upt)))for(e=BB(mMn(n.c,Upt),15).Kc();e.Ob();)(t=BB(e.Pb(),19).a)>0&&t<n.a.length&&(n.a[t]=!1);else for((c=new Wb(n.c.b)).a<c.c.c.length&&n0(c),i=1;c.a<c.c.c.length;)r=BB(n0(c),29),n.a[i++]=U$n(r)}function dRn(n,t){var e,i;switch(i=n.b,t){case 1:n.b|=1,n.b|=4,n.b|=8;break;case 2:n.b|=2,n.b|=4,n.b|=8;break;case 4:n.b|=1,n.b|=2,n.b|=4,n.b|=8;break;case 3:n.b|=16,n.b|=8;break;case 0:n.b|=32,n.b|=16,n.b|=8,n.b|=1,n.b|=2,n.b|=4}if(n.b!=i&&n.c)for(e=new AL(n.c);e.e!=e.i.gc();)AIn(P5(BB(kpn(e),473)),t)}function gRn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b;for(r=!1,u=0,o=(a=t).length;u<o;++u)c=a[u],qy((hN(),!!c.e))&&!BB(xq(n.b,c.e.p),214).s&&(r|=(s=c.e,(f=(h=BB(xq(n.b,s.p),214)).e)[l=fj(e,f.length)][0].k==(uSn(),Mut)?f[l]=$Nn(c,f[l],e?(kUn(),ICt):(kUn(),oCt)):h.c.Tf(f,e),b=DNn(n,h,e,i),xxn(h.e,h.o,e),b));return r}function pRn(n,t){var e,i,r,c,a;for(c=(!t.a&&(t.a=new eU(UOt,t,10,11)),t.a).i,r=new AL((!t.a&&(t.a=new eU(UOt,t,10,11)),t.a));r.e!=r.i.gc();)GC(ZAn(i=BB(kpn(r),33),(sWn(),ESt)))!==GC((ufn(),mIt))&&((a=BB(ZAn(t,mPt),149))==(e=BB(ZAn(i,mPt),149))||a&&j5(a,e))&&0!=(!i.a&&(i.a=new eU(UOt,i,10,11)),i.a).i&&(c+=pRn(n,i));return c}function vRn(n){var t,e,i,r,c,a,u;for(i=0,u=0,a=new Wb(n.d);a.a<a.c.c.length;)c=BB(n0(a),101),r=BB(P4(AV(new Rq(null,new w1(c.j,16)),new Xr),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15),e=null,i<=u?(kUn(),e=sCt,i+=r.gc()):u<i&&(kUn(),e=SCt,u+=r.gc()),t=e,JT($V(r.Oc(),new Hr),new Ad(t))}function mRn(n){var t,e,i,r,c,a,u,o;for(n.b=new vOn(new Jy((kUn(),Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt]))),new Jy((Irn(),Pun(Gk(Wst,1),$Vn,361,0,[Rst,Dst,xst])))),u=0,o=(a=Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])).length;u<o;++u)for(c=a[u],i=0,r=(e=Pun(Gk(Wst,1),$Vn,361,0,[Rst,Dst,xst])).length;i<r;++i)t=e[i],Wjn(n.b,c,t,new Np)}function yRn(n,t){var e,i,r,c,a,u,o,s,h,f;if(a=BB(BB(h6(n.r,t),21),84),u=n.u.Hc((lCn(),rCt)),e=n.u.Hc(tCt),i=n.u.Hc(nCt),s=n.u.Hc(cCt),f=n.B.Hc((nKn(),QCt)),h=!e&&!i&&(s||2==a.gc()),hxn(n,t),r=null,o=null,u){for(o=r=BB((c=a.Kc()).Pb(),111);c.Ob();)o=BB(c.Pb(),111);r.d.b=0,o.d.c=0,h&&!r.a&&(r.d.c=0)}f&&(DTn(a),u&&(r.d.b=0,o.d.c=0))}function kRn(n,t){var e,i,r,c,a,u,o,s,h,f;if(a=BB(BB(h6(n.r,t),21),84),u=n.u.Hc((lCn(),rCt)),e=n.u.Hc(tCt),i=n.u.Hc(nCt),o=n.u.Hc(cCt),f=n.B.Hc((nKn(),QCt)),s=!e&&!i&&(o||2==a.gc()),VKn(n,t),h=null,r=null,u){for(r=h=BB((c=a.Kc()).Pb(),111);c.Ob();)r=BB(c.Pb(),111);h.d.d=0,r.d.a=0,s&&!h.a&&(h.d.a=0)}f&&(RTn(a),u&&(h.d.d=0,r.d.a=0))}function jRn(n,t,e){var i,r,c,a,u;if(i=t.k,t.p>=0)return!1;if(t.p=e.b,WB(e.e,t),i==(uSn(),Put)||i==Cut)for(r=new Wb(t.j);r.a<r.c.c.length;)for(u=new zw(new Wb(new Gw(BB(n0(r),11)).a.g));y$(u.a);)if(a=(c=BB(n0(u.a),17).d.i).k,t.c!=c.c&&(a==Put||a==Cut)&&jRn(n,c,e))return!0;return!0}function ERn(n){var t;return 0!=(64&n.Db)?_On(n):((t=new fN(_On(n))).a+=" (changeable: ",yE(t,0!=(n.Bb&k6n)),t.a+=", volatile: ",yE(t,0!=(n.Bb&M9n)),t.a+=", transient: ",yE(t,0!=(n.Bb&KQn)),t.a+=", defaultValueLiteral: ",cO(t,n.j),t.a+=", unsettable: ",yE(t,0!=(n.Bb&T9n)),t.a+=", derived: ",yE(t,0!=(n.Bb&hVn)),t.a+=")",t.a)}function TRn(n){var t,e,i,r,c,a,u,o,s,h;for(e=NLn(n.d),c=(r=BB(mMn(n.b,(Epn(),vct)),116)).b+r.c,a=r.d+r.a,o=e.d.a*n.e+c,u=e.b.a*n.f+a,Ll(n.b,new xI(o,u)),h=new Wb(n.g);h.a<h.c.c.length;)t=UR(Fx(new xI((s=BB(n0(h),562)).g-e.a.a,s.i-e.c.a),s.a,s.b),kL(Bx(B$(VA(s.e)),s.d*s.a,s.c*s.b),-.5)),i=QA(s.e),ij(s.e,XR(t,i))}function MRn(n,t,e,i){var r,c,a,u,o;for(o=x8(xNt,sVn,104,(kUn(),Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])).length,0,2),a=0,u=(c=Pun(Gk(FCt,1),YZn,61,0,[PCt,sCt,oCt,SCt,ICt])).length;a<u;++a)o[(r=c[a]).g]=x8(xNt,qQn,25,n.c[r.g],15,1);return Bkn(o,n,sCt),Bkn(o,n,SCt),xmn(o,n,sCt,t,e,i),xmn(o,n,oCt,t,e,i),xmn(o,n,SCt,t,e,i),xmn(o,n,ICt,t,e,i),o}function SRn(n,t,e){if(hU(n.a,t)){if(FT(BB(RX(n.a,t),53),e))return 1}else VW(n.a,t,new Rv);if(hU(n.a,e)){if(FT(BB(RX(n.a,e),53),t))return-1}else VW(n.a,e,new Rv);if(hU(n.b,t)){if(FT(BB(RX(n.b,t),53),e))return-1}else VW(n.b,t,new Rv);if(hU(n.b,e)){if(FT(BB(RX(n.b,e),53),t))return 1}else VW(n.b,e,new Rv);return 0}function PRn(n,t,e,i){var r,c,a,u,o,s;if(null==e)for(r=BB(n.g,119),u=0;u<n.i;++u)if((a=r[u]).ak()==t)return Kpn(n,a,i);return ZM(),c=BB(t,66).Oj()?BB(e,72):Z3(t,e),mA(n.e)?(s=!adn(n,t),i=Ywn(n,c,i),o=t.$j()?LY(n,3,t,null,e,pBn(n,t,e,cL(t,99)&&0!=(BB(t,18).Bb&BQn)),s):LY(n,1,t,t.zj(),e,-1,s),i?i.Ei(o):i=o):i=Ywn(n,c,i),i}function IRn(n){var t,i,r,c,a,u;n.q!=(QEn(),WIt)&&n.q!=XIt&&(c=n.f.n.d+XH(BB(oV(n.b,(kUn(),sCt)),124))+n.c,t=n.f.n.a+XH(BB(oV(n.b,SCt),124))+n.c,r=BB(oV(n.b,oCt),124),u=BB(oV(n.b,ICt),124),a=e.Math.max(0,r.n.d-c),a=e.Math.max(a,u.n.d-c),i=e.Math.max(0,r.n.a-t),i=e.Math.max(i,u.n.a-t),r.n.d=a,u.n.d=a,r.n.a=i,u.n.a=i)}function CRn(n,t){var e,i,r,c,a,u,o;for(OTn(t,"Restoring reversed edges",1),a=new Wb(n.b);a.a<a.c.c.length;)for(u=new Wb(BB(n0(a),29).a);u.a<u.c.c.length;)for(o=new Wb(BB(n0(u),10).j);o.a<o.c.c.length;)for(r=0,c=(i=Z0(BB(n0(o),11).g)).length;r<c;++r)qy(TD(mMn(e=i[r],(hWn(),Ilt))))&&tBn(e,!1);HSn(t)}function ORn(){this.b=new v4,this.d=new v4,this.e=new v4,this.c=new v4,this.a=new xp,this.f=new xp,xJ(PMt,new mu,new yu),xJ(NMt,new Au,new $u),xJ(Eut,new Lu,new Nu),xJ(Kut,new Du,new Ru),xJ(hOt,new _u,new Ku),xJ(met,new ku,new ju),xJ(Cet,new Eu,new Tu),xJ(jet,new Mu,new Su),xJ(Eet,new Pu,new Iu),xJ(Bet,new Cu,new Ou)}function ARn(n){var t,e,i,r,c,a;return c=0,(t=Ckn(n)).Bj()&&(c|=4),0!=(n.Bb&T9n)&&(c|=2),cL(n,99)?(r=Ivn(e=BB(n,18)),0!=(e.Bb&h6n)&&(c|=32),r&&(bX(dZ(r)),c|=8,((a=r.t)>1||-1==a)&&(c|=16),0!=(r.Bb&h6n)&&(c|=64)),0!=(e.Bb&BQn)&&(c|=M9n),c|=k6n):cL(t,457)?c|=512:(i=t.Bj())&&0!=(1&i.i)&&(c|=256),0!=(512&n.Bb)&&(c|=128),c}function $Rn(n,t){var e,i,r,c,a;for(n=null==n?zWn:(kW(n),n),r=0;r<t.length;r++)t[r]=iLn(t[r]);for(e=new Ck,a=0,i=0;i<t.length&&-1!=(c=n.indexOf("%s",a));)e.a+=""+fx(null==n?zWn:(kW(n),n),a,c),uO(e,t[i++]),a=c+2;if(G0(e,n,a,n.length),i<t.length){for(e.a+=" [",uO(e,t[i++]);i<t.length;)e.a+=FWn,uO(e,t[i++]);e.a+="]"}return e.a}function LRn(n){var t,e,i,r,c;for(c=new J6(n.a.c.length),r=new Wb(n.a);r.a<r.c.c.length;){switch(i=BB(n0(r),10),t=null,(e=BB(mMn(i,(HXn(),kgt)),163)).g){case 1:case 2:Jun(),t=$ht;break;case 3:case 4:Jun(),t=Oht}t?(hon(i,(hWn(),Gft),(Jun(),$ht)),t==Oht?RNn(i,e,(ain(),Hvt)):t==$ht&&RNn(i,e,(ain(),qvt))):c.c[c.c.length]=i}return c}function NRn(n,t){var e,i,r,c,a,u,o;for(e=0,o=new Wb(t);o.a<o.c.c.length;){for(u=BB(n0(o),11),nhn(n.b,n.d[u.p]),a=0,r=new m6(u.b);y$(r.a)||y$(r.b);)IW(i=BB(y$(r.a)?n0(r.a):n0(r.b),17))?(c=ME(n,u==i.c?i.d:i.c))>n.d[u.p]&&(e+=n5(n.b,c),d3(n.a,iln(c))):++a;for(e+=n.b.d*a;!Wy(n.a);)Mnn(n.b,BB(dU(n.a),19).a)}return e}function xRn(n,t){var e;return n.f==uLt?(e=DW(B7((CPn(),Z$t),t)),n.e?4==e&&t!=(TOn(),lLt)&&t!=(TOn(),sLt)&&t!=(TOn(),hLt)&&t!=(TOn(),fLt):2==e):!(!n.d||!(n.d.Hc(t)||n.d.Hc(Z1(B7((CPn(),Z$t),t)))||n.d.Hc(Fqn((CPn(),Z$t),n.b,t))))||!(!n.f||!aNn((CPn(),n.f),jV(B7(Z$t,t))))&&(e=DW(B7(Z$t,t)),n.e?4==e:2==e)}function DRn(n,t,i,r){var c,a,u,o,s,h,f,l;return s=(u=BB(ZAn(i,(sWn(),gPt)),8)).a,f=u.b+n,(c=e.Math.atan2(f,s))<0&&(c+=Z3n),(c+=t)>Z3n&&(c-=Z3n),h=(o=BB(ZAn(r,gPt),8)).a,l=o.b+n,(a=e.Math.atan2(l,h))<0&&(a+=Z3n),(a+=t)>Z3n&&(a-=Z3n),h$(),rin(1e-10),e.Math.abs(c-a)<=1e-10||c==a||isNaN(c)&&isNaN(a)?0:c<a?-1:c>a?1:zO(isNaN(c),isNaN(a))}function RRn(n){var t,e,i,r,c,a,u;for(u=new xp,i=new Wb(n.a.b);i.a<i.c.c.length;)VW(u,t=BB(n0(i),57),new Np);for(r=new Wb(n.a.b);r.a<r.c.c.length;)for((t=BB(n0(r),57)).i=_Qn,a=t.c.Kc();a.Ob();)c=BB(a.Pb(),57),BB(qC(AY(u.f,c)),15).Fc(t);for(e=new Wb(n.a.b);e.a<e.c.c.length;)(t=BB(n0(e),57)).c.$b(),t.c=BB(qC(AY(u.f,t)),15);Kxn(n)}function _Rn(n){var t,e,i,r,c,a,u;for(u=new xp,i=new Wb(n.a.b);i.a<i.c.c.length;)VW(u,t=BB(n0(i),81),new Np);for(r=new Wb(n.a.b);r.a<r.c.c.length;)for((t=BB(n0(r),81)).o=_Qn,a=t.f.Kc();a.Ob();)c=BB(a.Pb(),81),BB(qC(AY(u.f,c)),15).Fc(t);for(e=new Wb(n.a.b);e.a<e.c.c.length;)(t=BB(n0(e),81)).f.$b(),t.f=BB(qC(AY(u.f,t)),15);BNn(n)}function KRn(n,t,e,i){var r,c;for(Gkn(n,t,e,i),xl(t,n.j-t.j+e),Dl(t,n.k-t.k+i),c=new Wb(t.f);c.a<c.c.c.length;)switch((r=BB(n0(c),324)).a.g){case 0:won(n,t.g+r.b.a,0,t.g+r.c.a,t.i-1);break;case 1:won(n,t.g+t.o,t.i+r.b.a,n.o-1,t.i+r.c.a);break;case 2:won(n,t.g+r.b.a,t.i+t.p,t.g+r.c.a,n.p-1);break;default:won(n,0,t.i+r.b.a,t.g-1,t.i+r.c.a)}}function FRn(n,t,e,i,r){var c,a;try{if(t>=n.o)throw Hp(new Sv);a=t>>5,c=yz(1,dG(yz(31&t,1))),n.n[e][a]=r?i0(n.n[e][a],c):e0(n.n[e][a],uH(c)),c=yz(c,1),n.n[e][a]=i?i0(n.n[e][a],c):e0(n.n[e][a],uH(c))}catch(u){throw cL(u=lun(u),320)?Hp(new Ay(MJn+n.o+"*"+n.p+SJn+t+FWn+e+PJn)):Hp(u)}}function BRn(n,t,i,r){var c,a;t&&(c=Gy(MD(mMn(t,(qqn(),fkt))))+r,a=i+Gy(MD(mMn(t,ukt)))/2,hon(t,gkt,iln(dG(fan(e.Math.round(c))))),hon(t,pkt,iln(dG(fan(e.Math.round(a))))),0==t.d.b||BRn(n,BB(iL(new wg(spn(new bg(t).a.d,0))),86),i+Gy(MD(mMn(t,ukt)))+n.a,r+Gy(MD(mMn(t,okt)))),null!=mMn(t,wkt)&&BRn(n,BB(mMn(t,wkt),86),i,r))}function HRn(n,t){var i,r,c,a,u,o,s,h,f,l,b;for(c=2*Gy(MD(mMn(s=vW(t.a),(HXn(),Tpt)))),f=Gy(MD(mMn(s,Apt))),h=e.Math.max(c,f),a=x8(xNt,qQn,25,t.f-t.c+1,15,1),r=-h,i=0,o=t.b.Kc();o.Ob();)u=BB(o.Pb(),10),r+=n.a[u.c.p]+h,a[i++]=r;for(r+=n.a[t.a.c.p]+h,a[i++]=r,b=new Wb(t.e);b.a<b.c.c.length;)l=BB(n0(b),10),r+=n.a[l.c.p]+h,a[i++]=r;return a}function qRn(n,t,e,i){var r,c,a,u,o,s,h,f;for(f=new dE(new Yd(n)),u=0,o=(a=Pun(Gk(Out,1),a1n,10,0,[t,e])).length;u<o;++u)for(h=Lfn(a[u],i).Kc();h.Ob();)for(c=new m6((s=BB(h.Pb(),11)).b);y$(c.a)||y$(c.b);)b5(r=BB(y$(c.a)?n0(c.a):n0(c.b),17))||(Mon(f.a,s,(hN(),ptt)),IW(r)&&ZU(f,s==r.c?r.d:r.c));return yX(f),new tK(f)}function GRn(n,t){var e,i,r,c;if(0!=(c=BB(ZAn(n,(sWn(),wPt)),61).g-BB(ZAn(t,wPt),61).g))return c;if(e=BB(ZAn(n,sPt),19),i=BB(ZAn(t,sPt),19),e&&i&&0!=(r=e.a-i.a))return r;switch(BB(ZAn(n,wPt),61).g){case 1:return Pln(n.i,t.i);case 2:return Pln(n.j,t.j);case 3:return Pln(t.i,n.i);case 4:return Pln(t.j,n.j);default:throw Hp(new Fy(r1n))}}function zRn(n){var t,e,i;return 0!=(64&n.Db)?mSn(n):(t=new lN(n6n),(e=n.k)?oO(oO((t.a+=' "',t),e),'"'):(!n.n&&(n.n=new eU(zOt,n,1,7)),n.n.i>0&&(!(i=(!n.n&&(n.n=new eU(zOt,n,1,7)),BB(Wtn(n.n,0),137)).a)||oO(oO((t.a+=' "',t),i),'"'))),oO(kE(oO(kE(oO(kE(oO(kE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function URn(n){var t,e,i;return 0!=(64&n.Db)?mSn(n):(t=new lN(t6n),(e=n.k)?oO(oO((t.a+=' "',t),e),'"'):(!n.n&&(n.n=new eU(zOt,n,1,7)),n.n.i>0&&(!(i=(!n.n&&(n.n=new eU(zOt,n,1,7)),BB(Wtn(n.n,0),137)).a)||oO(oO((t.a+=' "',t),i),'"'))),oO(kE(oO(kE(oO(kE(oO(kE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function XRn(n,t){var e,i,r,c,a,u;if(null==t||0==t.length)return null;if(!(r=BB(SJ(n.a,t),149))){for(i=new _b(new Ob(n.b).a.vc().Kc());i.a.Ob();)if(c=BB(i.a.Pb(),42),a=(e=BB(c.dd(),149)).c,u=t.length,m_(a.substr(a.length-u,u),t)&&(t.length==a.length||46==fV(a,a.length-t.length-1))){if(r)return null;r=e}r&&mZ(n.a,t,r)}return r}function WRn(n,t){var e,i,r;return e=new xn,(i=BB(P4($V(new Rq(null,new w1(n.f,16)),e),x7(new Q,new Y,new cn,new an,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Xet),Uet]))),21).gc())<(r=BB(P4($V(new Rq(null,new w1(t.f,16)),e),x7(new Q,new Y,new cn,new an,Pun(Gk(nit,1),$Vn,132,0,[Xet,Uet]))),21).gc())?-1:i==r?0:1}function VRn(n){var t,e,i;Lx(n,(HXn(),$gt))&&((i=BB(mMn(n,$gt),21)).dc()||(e=new Y_(t=BB(Vj(GIt),9),BB(SR(t,t.length),9),0),i.Hc((n$n(),$It))?orn(e,$It):orn(e,LIt),i.Hc(OIt)||orn(e,OIt),i.Hc(CIt)?orn(e,DIt):i.Hc(IIt)?orn(e,xIt):i.Hc(AIt)&&orn(e,NIt),i.Hc(DIt)?orn(e,CIt):i.Hc(xIt)?orn(e,IIt):i.Hc(NIt)&&orn(e,AIt),hon(n,$gt,e)))}function QRn(n){var t,e,i,r,c,a,u;for(r=BB(mMn(n,(hWn(),rlt)),10),l1(0,(i=n.j).c.length),e=BB(i.c[0],11),a=new Wb(r.j);a.a<a.c.c.length;)if(GC(c=BB(n0(a),11))===GC(mMn(e,dlt))){c.j==(kUn(),sCt)&&n.p>r.p?(qIn(c,SCt),c.d&&(u=c.o.b,t=c.a.b,c.a.b=u-t)):c.j==SCt&&r.p>n.p&&(qIn(c,sCt),c.d&&(u=c.o.b,t=c.a.b,c.a.b=-(u-t)));break}return r}function YRn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w;if(c=e,e<i)for(b=new Fan(n.p),w=new Fan(n.p),Frn(b.e,n.e),b.q=n.q,b.r=w,rX(b),Frn(w.j,n.j),w.r=b,rX(w),f=BB((l=new rC(b,w)).a,112),h=BB(l.b,112),l1(c,t.c.length),a=$Dn(n,f,h,r=BB(t.c[c],329)),s=e+1;s<=i;s++)l1(s,t.c.length),Vpn(u=BB(t.c[s],329),o=$Dn(n,f,h,u),r,a)&&(r=u,a=o);return c}function JRn(n,t,e,i,r){var c,a,u,o,s,h,f;if(!(cL(t,239)||cL(t,354)||cL(t,186)))throw Hp(new Ky("Method only works for ElkNode-, ElkLabel and ElkPort-objects."));return a=n.a/2,o=t.i+i-a,h=t.j+r-a,s=o+t.g+n.a,f=h+t.f+n.a,DH(c=new km,new xI(o,h)),DH(c,new xI(o,f)),DH(c,new xI(s,f)),DH(c,new xI(s,h)),qan(u=new EAn(c),t),e&&VW(n.b,t,u),u}function ZRn(n,t,e){var i,r,c,a,u,o,s,h;for(c=new xI(t,e),s=new Wb(n.a);s.a<s.c.c.length;)for(UR((o=BB(n0(s),10)).n,c),h=new Wb(o.j);h.a<h.c.c.length;)for(r=new Wb(BB(n0(h),11).g);r.a<r.c.c.length;)for(Ztn((i=BB(n0(r),17)).a,c),(a=BB(mMn(i,(HXn(),vgt)),74))&&Ztn(a,c),u=new Wb(i.b);u.a<u.c.c.length;)UR(BB(n0(u),70).n,c)}function n_n(n,t,e){var i,r,c,a,u,o,s,h;for(c=new xI(t,e),s=new Wb(n.a);s.a<s.c.c.length;)for(UR((o=BB(n0(s),10)).n,c),h=new Wb(o.j);h.a<h.c.c.length;)for(r=new Wb(BB(n0(h),11).g);r.a<r.c.c.length;)for(Ztn((i=BB(n0(r),17)).a,c),(a=BB(mMn(i,(HXn(),vgt)),74))&&Ztn(a,c),u=new Wb(i.b);u.a<u.c.c.length;)UR(BB(n0(u),70).n,c)}function t_n(n){if(0==(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b).i)throw Hp(new ck("Edges must have a source."));if(0==(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c).i)throw Hp(new ck("Edges must have a target."));if(!n.b&&(n.b=new h_(_Ot,n,4,7)),!(n.b.i<=1&&(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c.i<=1)))throw Hp(new ck("Hyperedges are not supported."))}function e_n(n,t){var e,i,r,c,a,u,o,s,h,f;for(f=0,d3(c=new Lp,t);c.b!=c.c;)for(o=BB(dU(c),214),s=0,h=BB(mMn(t.j,(HXn(),Ldt)),339),a=Gy(MD(mMn(t.j,Cdt))),u=Gy(MD(mMn(t.j,Odt))),h!=(mon(),Nvt)&&(s+=a*S$n(o.e,h),s+=u*rxn(o.e)),f+=syn(o.d,o.e)+s,r=new Wb(o.b);r.a<r.c.c.length;)i=BB(n0(r),37),(e=BB(xq(n.b,i.p),214)).s||(f+=nIn(n,e));return f}function i_n(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(o=b=t.length,b1(0,t.length),45==t.charCodeAt(0)?(f=-1,l=1,--b):(f=1,l=0),r=b/(c=(uHn(),cet)[10])|0,0!=(g=b%c)&&++r,u=x8(ANt,hQn,25,r,15,1),e=ret[8],a=0,w=l+(0==g?c:g),d=l;d<o;w=(d=w)+c)i=lKn(t.substr(d,w-d),KVn,DWn),$On(),s=dvn(u,u,a,e),s+=Uwn(u,a,i),u[a++]=s;h=a,n.e=f,n.d=h,n.a=u,X0(n)}function r_n(n,t,e,i,r,c,a){if(n.c=i.qf().a,n.d=i.qf().b,r&&(n.c+=r.qf().a,n.d+=r.qf().b),n.b=t.rf().a,n.a=t.rf().b,r)switch(r.Hf().g){case 0:case 2:n.c+=r.rf().a+a+c.a+a;break;case 4:n.c-=a+c.a+a+t.rf().a;break;case 1:n.c+=r.rf().a+a,n.d-=a+c.b+a+t.rf().b;break;case 3:n.c+=r.rf().a+a,n.d+=r.rf().b+a+c.b+a}else e?n.c-=a+t.rf().a:n.c+=i.rf().a+a}function c_n(n,t){var e,i;for(this.b=new Np,this.e=new Np,this.a=n,this.d=t,Gpn(this),pdn(this),this.b.dc()?this.c=n.c.p:this.c=BB(this.b.Xb(0),10).c.p,0==this.e.c.length?this.f=n.c.p:this.f=BB(xq(this.e,this.e.c.length-1),10).c.p,i=BB(mMn(n,(hWn(),Plt)),15).Kc();i.Ob();)if(Lx(e=BB(i.Pb(),70),(HXn(),Vdt))){this.d=BB(mMn(e,Vdt),227);break}}function a_n(n,t,e){var i,r,c,a,u,o,s,h;for(i=BB(RX(n.a,t),53),c=BB(RX(n.a,e),53),r=BB(RX(n.e,t),53),a=BB(RX(n.e,e),53),i.a.zc(e,i),a.a.zc(t,a),h=c.a.ec().Kc();h.Ob();)s=BB(h.Pb(),10),i.a.zc(s,i),TU(BB(RX(n.e,s),53),t),Frn(BB(RX(n.e,s),53),r);for(o=r.a.ec().Kc();o.Ob();)u=BB(o.Pb(),10),a.a.zc(u,a),TU(BB(RX(n.a,u),53),e),Frn(BB(RX(n.a,u),53),c)}function u_n(n,t,e){var i,r,c,a,u,o,s,h;for(i=BB(RX(n.a,t),53),c=BB(RX(n.a,e),53),r=BB(RX(n.b,t),53),a=BB(RX(n.b,e),53),i.a.zc(e,i),a.a.zc(t,a),h=c.a.ec().Kc();h.Ob();)s=BB(h.Pb(),10),i.a.zc(s,i),TU(BB(RX(n.b,s),53),t),Frn(BB(RX(n.b,s),53),r);for(o=r.a.ec().Kc();o.Ob();)u=BB(o.Pb(),10),a.a.zc(u,a),TU(BB(RX(n.a,u),53),e),Frn(BB(RX(n.a,u),53),c)}function o_n(n,t){var e,i,r;switch(OTn(t,"Breaking Point Insertion",1),i=new MAn(n),BB(mMn(n,(HXn(),Bpt)),337).g){case 2:r=new Tc;case 0:r=new wc;break;default:r=new Mc}if(e=r.Vf(n,i),qy(TD(mMn(n,qpt)))&&(e=Dqn(n,e)),!r.Wf()&&Lx(n,Xpt))switch(BB(mMn(n,Xpt),338).g){case 2:e=XIn(i,e);break;case 1:e=_Tn(i,e)}e.dc()||tXn(n,e),HSn(t)}function s_n(n,t,e){var i,r,c,a,u,o,s;if(s=t,$in(o=Q3(n,L3(e),s),R2(s,q6n)),a=N2(s,L6n),VIn((i=new oC(n,o)).a,i.b,a),u=N2(s,N6n),QIn((r=new sC(n,o)).a,r.b,u),0==(!o.b&&(o.b=new h_(_Ot,o,4,7)),o.b).i||0==(!o.c&&(o.c=new h_(_Ot,o,5,8)),o.c).i)throw c=R2(s,q6n),Hp(new ek(X6n+c+W6n));return STn(s,o),sXn(n,s,o),xon(n,s,o)}function h_n(n,t){var i,r,c,a,u,o,s;for(c=x8(ANt,hQn,25,n.e.a.c.length,15,1),u=new Wb(n.e.a);u.a<u.c.c.length;)c[(a=BB(n0(u),121)).d]+=a.b.a.c.length;for(o=zB(t);0!=o.b;)for(r=L9(new Wb((a=BB(0==o.b?null:(Px(0!=o.b),Atn(o,o.a.a)),121)).g.a));r.Ob();)(s=(i=BB(r.Pb(),213)).e).e=e.Math.max(s.e,a.e+i.a),--c[s.d],0==c[s.d]&&r5(o,s,o.c.b,o.c)}function f_n(n){var t,i,r,c,a,u,o,s,h,f,l;for(i=KVn,c=DWn,o=new Wb(n.e.a);o.a<o.c.c.length;)a=BB(n0(o),121),c=e.Math.min(c,a.e),i=e.Math.max(i,a.e);for(t=x8(ANt,hQn,25,i-c+1,15,1),u=new Wb(n.e.a);u.a<u.c.c.length;)(a=BB(n0(u),121)).e-=c,++t[a.e];if(r=0,null!=n.k)for(f=0,l=(h=n.k).length;f<l&&(s=h[f],t[r++]+=s,t.length!=r);++f);return t}function l_n(n){switch(n.d){case 9:case 8:return!0;case 3:case 5:case 4:case 6:return!1;case 7:return BB(_xn(n),19).a==n.o;case 1:case 2:if(-2==n.o)return!1;switch(n.p){case 0:case 1:case 2:case 6:case 5:case 7:return QC(n.k,n.f);case 3:case 4:return n.j==n.e;default:return null==n.n?null==n.g:Nfn(n.n,n.g)}default:return!1}}function b_n(n){NM(n,new MTn(vj(wj(pj(gj(new du,_5n),"ELK Fixed"),"Keeps the current layout as it is, without any automatic modification. Optional coordinates can be given for nodes and edge bend points."),new Vu))),u2(n,_5n,QJn,dIt),u2(n,_5n,g3n,mpn(gIt)),u2(n,_5n,g5n,mpn(hIt)),u2(n,_5n,PZn,mpn(fIt)),u2(n,_5n,BZn,mpn(bIt)),u2(n,_5n,Y2n,mpn(lIt))}function w_n(n,t,e){var i,r,c,a;if(i=dG(cbn(SVn,rV(dG(cbn(null==t?0:nsn(t),PVn)),15))),a=dG(cbn(SVn,rV(dG(cbn(null==e?0:nsn(e),PVn)),15))),(c=Jrn(n,t,i))&&a==c.f&&wW(e,c.i))return e;if(Zrn(n,e,a))throw Hp(new Ky("value already present: "+e));return r=new qW(t,i,e,a),c?(LLn(n,c),YIn(n,r,c),c.e=null,c.c=null,c.i):(YIn(n,r,null),qkn(n),null)}function d_n(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;s=e.a.c,a=e.a.c+e.a.b,l=(c=BB(RX(e.c,t),459)).f,b=c.a,u=c.b?new xI(a,l):new xI(s,l),h=c.c?new xI(s,b):new xI(a,b),r=s,e.p||(r+=n.c),o=new xI(r+=e.F+e.v*n.b,l),f=new xI(r,b),nin(t.a,Pun(Gk(PMt,1),sVn,8,0,[u,o])),e.d.a.gc()>1&&(i=new xI(r,e.b),DH(t.a,i)),nin(t.a,Pun(Gk(PMt,1),sVn,8,0,[f,h]))}function g_n(n,t,e){var i,r,c,a,u,o;if(t){if(e<=-1){if(cL(i=itn(t.Tg(),-1-e),99))return BB(i,18);for(u=0,o=(a=BB(t.ah(i),153)).gc();u<o;++u)if(GC(a.jl(u))===GC(n)&&cL(r=a.il(u),99)&&0!=((c=BB(r,18)).Bb&h6n))return c;throw Hp(new Fy("The containment feature could not be located"))}return Ivn(BB(itn(n.Tg(),e),18))}return null}function p_n(n){var t,e,i,r,c;for(i=n.length,t=new Pk,c=0;c<i;)if(9!=(e=fV(n,c++))&&10!=e&&12!=e&&13!=e&&32!=e)if(35!=e)92==e&&c<i?35==(b1(c,n.length),r=n.charCodeAt(c))||9==r||10==r||12==r||13==r||32==r?(NX(t,r&QVn),++c):(t.a+="\\",NX(t,r&QVn),++c):NX(t,e&QVn);else for(;c<i&&13!=(e=fV(n,c++))&&10!=e;);return t.a}function v_n(n,t){var e,i,r;for(i=new Wb(t);i.a<i.c.c.length;)if(e=BB(n0(i),33),JCn(n.a,e,e),JCn(n.b,e,e),0!=(r=wDn(e)).c.length)for(n.d&&n.d.lg(r),JCn(n.a,e,(l1(0,r.c.length),BB(r.c[0],33))),JCn(n.b,e,BB(xq(r,r.c.length-1),33));0!=Dun(r).c.length;)r=Dun(r),n.d&&n.d.lg(r),JCn(n.a,e,(l1(0,r.c.length),BB(r.c[0],33))),JCn(n.b,e,BB(xq(r,r.c.length-1),33))}function m_n(n){var t,e,i,r,c,a,u,o,s,h;for(e=0,u=new Wb(n.d);u.a<u.c.c.length;)(a=BB(n0(u),101)).i&&(a.i.c=e++);for(t=kq($Nt,[sVn,ZYn],[177,25],16,[e,e],2),h=n.d,r=0;r<h.c.length;r++)if(l1(r,h.c.length),(o=BB(h.c[r],101)).i)for(c=r+1;c<h.c.length;c++)l1(c,h.c.length),(s=BB(h.c[c],101)).i&&(i=rMn(o,s),t[o.i.c][s.i.c]=i,t[s.i.c][o.i.c]=i);return t}function y_n(n,t,e,i){var r,c,a;return a=new yT(t,e),n.a?i?(++(r=BB(RX(n.b,t),283)).a,a.d=i.d,a.e=i.e,a.b=i,a.c=i,i.e?i.e.c=a:BB(RX(n.b,t),283).b=a,i.d?i.d.b=a:n.a=a,i.d=a,i.e=a):(n.e.b=a,a.d=n.e,n.e=a,(r=BB(RX(n.b,t),283))?(++r.a,(c=r.c).c=a,a.e=c,r.c=a):(VW(n.b,t,r=new sY(a)),++n.c)):(n.a=n.e=a,VW(n.b,t,new sY(a)),++n.c),++n.d,a}function k_n(n,t){var e,i,r,c,a,u,o,s;for(e=new RegExp(t,"g"),o=x8(Qtt,sVn,2,0,6,1),i=0,s=n,c=null;;){if(null==(u=e.exec(s))||""==s){o[i]=s;break}a=u.index,o[i]=s.substr(0,a),s=fx(s,a+u[0].length,s.length),e.lastIndex=0,c==s&&(o[i]=s.substr(0,1),s=s.substr(1)),c=s,++i}if(n.length>0){for(r=o.length;r>0&&""==o[r-1];)--r;r<o.length&&(o.length=r)}return o}function j_n(n,t){var e,i,r,c,a,u,o,s;for(u=null,r=!1,c=0,o=a4((s=kY(t)).a).i;c<o;++c)(e=j_n(n,BB(eGn(s,c,cL(a=BB(Wtn(a4(s.a),c),87).c,88)?BB(a,26):(gWn(),d$t)),26))).dc()||(u?(r||(r=!0,u=new rG(u)),u.Gc(e)):u=e);return(i=xCn(n,t)).dc()?u||(SQ(),SQ(),set):u?(r||(u=new rG(u)),u.Gc(i),u):i}function E_n(n,t){var e,i,r,c,a,u,o,s;for(u=null,i=!1,c=0,o=a4((s=kY(t)).a).i;c<o;++c)(e=E_n(n,BB(eGn(s,c,cL(a=BB(Wtn(a4(s.a),c),87).c,88)?BB(a,26):(gWn(),d$t)),26))).dc()||(u?(i||(i=!0,u=new rG(u)),u.Gc(e)):u=e);return(r=VOn(n,t)).dc()?u||(SQ(),SQ(),set):u?(i||(u=new rG(u)),u.Gc(r),u):r}function T_n(n,t,e){var i,r,c,a,u,o;if(cL(t,72))return Kpn(n,t,e);for(u=null,c=null,i=BB(n.g,119),a=0;a<n.i;++a)if(Nfn(t,(r=i[a]).dd())&&cL(c=r.ak(),99)&&0!=(BB(c,18).Bb&h6n)){u=r;break}return u&&(mA(n.e)&&(o=c.$j()?LY(n,4,c,t,null,pBn(n,c,t,cL(c,99)&&0!=(BB(c,18).Bb&BQn)),!0):LY(n,c.Kj()?2:1,c,t,c.zj(),-1,!0),e?e.Ei(o):e=o),e=T_n(n,u,e)),e}function M_n(n){var t,i,r,c;r=n.o,qD(),n.A.dc()||Nfn(n.A,$rt)?c=r.a:(c=SCn(n.f),n.A.Hc((mdn(),RCt))&&!n.B.Hc((nKn(),XCt))&&(c=e.Math.max(c,SCn(BB(oV(n.p,(kUn(),sCt)),244))),c=e.Math.max(c,SCn(BB(oV(n.p,SCt),244)))),(t=oan(n))&&(c=e.Math.max(c,t.a))),qy(TD(n.e.yf().We((sWn(),FSt))))?r.a=e.Math.max(r.a,c):r.a=c,(i=n.f.i).c=0,i.b=c,KFn(n.f)}function S_n(n,t){var e,i,r,c,a,u,o,s,h;if((e=t.Hh(n.a))&&null!=(o=SD(cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),"memberTypes")))){for(s=new Np,a=0,u=(c=k_n(o,"\\w")).length;a<u;++a)cL(h=-1==(i=(r=c[a]).lastIndexOf("#"))?uD(n,t.Aj(),r):0==i?M9(n,null,r.substr(1)):M9(n,r.substr(0,i),r.substr(i+1)),148)&&WB(s,BB(h,148));return s}return SQ(),SQ(),set}function P_n(n,t,e){var i,r,c,a,u,o,s,h;for(OTn(e,aZn,1),n.bf(t),c=0;n.df(c);){for(h=new Wb(t.e);h.a<h.c.c.length;)for(o=BB(n0(h),144),u=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[t.e,t.d,t.b])));dAn(u);)(a=BB(U5(u),357))!=o&&(r=n.af(a,o))&&UR(o.a,r);for(s=new Wb(t.e);s.a<s.c.c.length;)WSn(i=(o=BB(n0(s),144)).a,-n.d,-n.d,n.d,n.d),UR(o.d,i),kO(i);n.cf(),++c}HSn(e)}function I_n(n,t,e){var i,r,c,a;if(a=axn(n.e.Tg(),t),i=BB(n.g,119),ZM(),BB(t,66).Oj()){for(c=0;c<n.i;++c)if(r=i[c],a.rl(r.ak())&&Nfn(r,e))return fDn(n,c),!0}else if(null!=e){for(c=0;c<n.i;++c)if(r=i[c],a.rl(r.ak())&&Nfn(e,r.dd()))return fDn(n,c),!0}else for(c=0;c<n.i;++c)if(r=i[c],a.rl(r.ak())&&null==r.dd())return fDn(n,c),!0;return!1}function C_n(n,t){var e,i,r,c,a;for(null==n.c||n.c.length<t.c.length?n.c=x8($Nt,ZYn,25,t.c.length,16,1):nk(n.c),n.a=new Np,i=0,a=new Wb(t);a.a<a.c.c.length;)(r=BB(n0(a),10)).p=i++;for(e=new YT,c=new Wb(t);c.a<c.c.c.length;)r=BB(n0(c),10),n.c[r.p]||(hCn(n,r),0==e.b||(Px(0!=e.b),BB(e.a.a.c,15)).gc()<n.a.c.length?hO(e,n.a):fO(e,n.a),n.a=new Np);return e}function O_n(n,t,e,i){var r,c,a,u,o,s,h;for(Pen(a=BB(Wtn(t,0),33),0),Ien(a,0),(o=new Np).c[o.c.length]=a,u=a,c=new eq(n.a,a.g,a.f,(YLn(),KEt)),s=1;s<t.i;s++)Pen(h=BB(Wtn(t,s),33),(r=aqn(n,nHn(n,DEt,h,u,c,o,e),nHn(n,xEt,h,u,c,o,e),nHn(n,_Et,h,u,c,o,e),nHn(n,REt,h,u,c,o,e),h,u,i)).d),Ien(h,r.e),ab(r,KEt),c=r,u=h,o.c[o.c.length]=h;return c}function A_n(n){NM(n,new MTn(vj(wj(pj(gj(new du,Q4n),"ELK SPOrE Overlap Removal"),'A node overlap removal algorithm proposed by Nachmanson et al. in "Node overlap removal by growing a tree".'),new eu))),u2(n,Q4n,_4n,mpn(qTt)),u2(n,Q4n,QJn,BTt),u2(n,Q4n,vZn,8),u2(n,Q4n,q4n,mpn(HTt)),u2(n,Q4n,U4n,mpn(KTt)),u2(n,Q4n,X4n,mpn(FTt)),u2(n,Q4n,X2n,(hN(),!1))}function $_n(n,t,e,i){var r,c,a,u,o,s,h,f;for(a=Kx(t.c,e,i),h=new Wb(t.a);h.a<h.c.c.length;){for(UR((s=BB(n0(h),10)).n,a),f=new Wb(s.j);f.a<f.c.c.length;)for(c=new Wb(BB(n0(f),11).g);c.a<c.c.c.length;)for(Ztn((r=BB(n0(c),17)).a,a),(u=BB(mMn(r,(HXn(),vgt)),74))&&Ztn(u,a),o=new Wb(r.b);o.a<o.c.c.length;)UR(BB(n0(o),70).n,a);WB(n.a,s),s.a=n}}function L_n(n,t){var e,i,r,c;if(OTn(t,"Node and Port Label Placement and Node Sizing",1),RA((gM(),new HV(n,!0,!0,new Ve))),BB(mMn(n,(hWn(),Zft)),21).Hc((bDn(),lft)))for(i=(r=BB(mMn(n,(HXn(),cpt)),21)).Hc((lCn(),iCt)),c=qy(TD(mMn(n,apt))),e=new Wb(n.b);e.a<e.c.c.length;)JT(AV(new Rq(null,new w1(BB(n0(e),29).a,16)),new Qe),new _K(r,i,c));HSn(t)}function N_n(n,t){var e,i,r,c,a,u;if((e=t.Hh(n.a))&&null!=(u=SD(cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),n8n))))switch(r=mN(u,YTn(35)),i=t.Hj(),-1==r?(a=az(n,Utn(i)),c=u):0==r?(a=null,c=u.substr(1)):(a=u.substr(0,r),c=u.substr(r+1)),DW(B7(n,t))){case 2:case 3:return Don(n,i,a,c);case 0:case 4:case 5:case 6:return Ron(n,i,a,c)}return null}function x_n(n,t,e){var i,r,c,a,u;if(ZM(),a=BB(t,66).Oj(),$xn(n.e,t)){if(t.hi()&&UFn(n,t,e,cL(t,99)&&0!=(BB(t,18).Bb&BQn)))return!1}else for(u=axn(n.e.Tg(),t),i=BB(n.g,119),c=0;c<n.i;++c)if(r=i[c],u.rl(r.ak()))return!(a?Nfn(r,e):null==e?null==r.dd():Nfn(e,r.dd()))&&(BB(ovn(n,c,a?BB(e,72):Z3(t,e)),72),!0);return f9(n,a?BB(e,72):Z3(t,e))}function D_n(n){var t,e,i,r,c;if(n.d)throw Hp(new Fy((ED(Yat),AYn+Yat.k+$Yn)));for(n.c==(Ffn(),BPt)&&Mzn(n,KPt),t=new Wb(n.a.a);t.a<t.c.c.length;)BB(n0(t),189).e=0;for(r=new Wb(n.a.b);r.a<r.c.c.length;)for((i=BB(n0(r),81)).o=_Qn,e=i.f.Kc();e.Ob();)++BB(e.Pb(),81).d.e;for(Gzn(n),c=new Wb(n.a.b);c.a<c.c.c.length;)BB(n0(c),81).k=!0;return n}function R_n(n,t){var e,i,r,c,a,u,o,s;for(u=new pPn(n),r5(e=new YT,t,e.c.b,e.c);0!=e.b;){for((i=BB(0==e.b?null:(Px(0!=e.b),Atn(e,e.a.a)),113)).d.p=1,a=new Wb(i.e);a.a<a.c.c.length;)jTn(u,r=BB(n0(a),409)),0==(s=r.d).d.p&&r5(e,s,e.c.b,e.c);for(c=new Wb(i.b);c.a<c.c.c.length;)jTn(u,r=BB(n0(c),409)),0==(o=r.c).d.p&&r5(e,o,e.c.b,e.c)}return u}function __n(n){var t,e,i,r,c;if(1!=(i=Gy(MD(ZAn(n,(sWn(),yPt))))))for(MA(n,i*n.g,i*n.f),e=XO(KB((!n.c&&(n.c=new eU(XOt,n,9,9)),n.c),new Bu)),c=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[(!n.n&&(n.n=new eU(zOt,n,1,7)),n.n),(!n.c&&(n.c=new eU(XOt,n,9,9)),n.c),e])));dAn(c);)(r=BB(U5(c),470)).Gg(i*r.Dg(),i*r.Eg()),r.Fg(i*r.Cg(),i*r.Bg()),(t=BB(r.We(cPt),8))&&(t.a*=i,t.b*=i)}function K_n(n,t,e,i,r){var c,a,u,o,s,h;for(c=new Wb(n.b);c.a<c.c.c.length;)for(s=0,h=(o=n2(BB(n0(c),29).a)).length;s<h;++s)switch(BB(mMn(u=o[s],(HXn(),kgt)),163).g){case 1:vxn(u),PZ(u,t),lvn(u,!0,i);break;case 3:ZNn(u),PZ(u,e),lvn(u,!1,r)}for(a=new M2(n.b,0);a.b<a.d.gc();)0==(Px(a.b<a.d.gc()),BB(a.d.Xb(a.c=a.b++),29)).a.c.length&&fW(a)}function F_n(n,t){var e,i,r,c,a,u,o;if((e=t.Hh(n.a))&&null!=(o=SD(cdn((!e.b&&(e.b=new Jx((gWn(),k$t),X$t,e)),e.b),M7n)))){for(i=new Np,a=0,u=(c=k_n(o,"\\w")).length;a<u;++a)m_(r=c[a],"##other")?WB(i,"!##"+az(n,Utn(t.Hj()))):m_(r,"##local")?i.c[i.c.length]=null:m_(r,E7n)?WB(i,az(n,Utn(t.Hj()))):i.c[i.c.length]=r;return i}return SQ(),SQ(),set}function B_n(n,t){var e,i,r;return e=new Xn,(i=1==(i=BB(P4($V(new Rq(null,new w1(n.f,16)),e),x7(new Q,new Y,new cn,new an,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Xet),Uet]))),21).gc())?1:0)<(r=1==(r=BB(P4($V(new Rq(null,new w1(t.f,16)),e),x7(new Q,new Y,new cn,new an,Pun(Gk(nit,1),$Vn,132,0,[Xet,Uet]))),21).gc())?1:0)?-1:i==r?0:1}function H_n(n){var t,e,i,r,c,a,u,o,s,h,f,l;for(r=qy(TD(mMn(u=n.i,(HXn(),wgt)))),h=0,i=0,s=new Wb(n.g);s.a<s.c.c.length;)c=(a=b5(o=BB(n0(s),17)))&&r&&qy(TD(mMn(o,dgt))),l=o.d.i,a&&c?++i:a&&!c?++h:vW(l).e==u?++i:++h;for(e=new Wb(n.e);e.a<e.c.c.length;)c=(a=b5(t=BB(n0(e),17)))&&r&&qy(TD(mMn(t,dgt))),f=t.c.i,a&&c?++h:a&&!c?++i:vW(f).e==u?++h:++i;return h-i}function q_n(n,t,e,i){this.e=n,this.k=BB(mMn(n,(hWn(),Alt)),304),this.g=x8(Out,a1n,10,t,0,1),this.b=x8(Ptt,sVn,333,t,7,1),this.a=x8(Out,a1n,10,t,0,1),this.d=x8(Ptt,sVn,333,t,7,1),this.j=x8(Out,a1n,10,t,0,1),this.i=x8(Ptt,sVn,333,t,7,1),this.p=x8(Ptt,sVn,333,t,7,1),this.n=x8(ktt,sVn,476,t,8,1),yS(this.n,(hN(),!1)),this.f=x8(ktt,sVn,476,t,8,1),yS(this.f,!0),this.o=e,this.c=i}function G_n(n,t){var e,i,r;if(!t.dc())if(BB(t.Xb(0),286).d==($Pn(),nht))Akn(n,t);else for(i=t.Kc();i.Ob();){switch((e=BB(i.Pb(),286)).d.g){case 5:hPn(n,e,Vbn(n,e));break;case 0:hPn(n,e,(r=(e.f-e.c+1-1)/2|0,e.c+r));break;case 4:hPn(n,e,$nn(n,e));break;case 2:_wn(e),hPn(n,e,$En(e)?e.c:e.f);break;case 1:_wn(e),hPn(n,e,$En(e)?e.f:e.c)}hMn(e.a)}}function z_n(n,t){var e,i,r,c,a;if(!t.e){for(t.e=!0,i=t.d.a.ec().Kc();i.Ob();)e=BB(i.Pb(),17),t.o&&t.d.a.gc()<=1?(a=new xI((c=t.a.c)+(t.a.c+t.a.b-c)/2,t.b),DH(BB(t.d.a.ec().Kc().Pb(),17).a,a)):(r=BB(RX(t.c,e),459)).b||r.c?d_n(n,e,t):n.d==(Usn(),rmt)&&(r.d||r.e)&&LOn(n,t)&&t.d.a.gc()<=1?dzn(e,t):DDn(n,e,t);t.k&&e5(t.d,new Te)}}function U_n(n,t,i,r,c,a){var u,o,s,h,f,l,b,w,d,g,p,v,m;for(o=(r+c)/2+a,g=i*e.Math.cos(o),p=i*e.Math.sin(o),v=g-t.g/2,m=p-t.f/2,Pen(t,v),Ien(t,m),l=n.a.jg(t),(d=2*e.Math.acos(i/i+n.c))<c-r?(b=d/l,u=(r+c-d)/2):(b=(c-r)/l,u=r),w=wDn(t),n.e&&(n.e.kg(n.d),n.e.lg(w)),h=new Wb(w);h.a<h.c.c.length;)s=BB(n0(h),33),f=n.a.jg(s),U_n(n,s,i+n.c,u,u+b*f,a),u+=b*f}function X_n(n,t,e){var i;switch(i=e.q.getMonth(),t){case 5:oO(n,Pun(Gk(Qtt,1),sVn,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[i]);break;case 4:oO(n,Pun(Gk(Qtt,1),sVn,2,6,[YVn,JVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn,uQn,oQn])[i]);break;case 3:oO(n,Pun(Gk(Qtt,1),sVn,2,6,["Jan","Feb","Mar","Apr",tQn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[i]);break;default:Enn(n,i+1,t)}}function W_n(n,t){var e,i,r,c;if(OTn(t,"Network simplex",1),n.e.a.c.length<1)HSn(t);else{for(r=new Wb(n.e.a);r.a<r.c.c.length;)BB(n0(r),121).e=0;for((c=n.e.a.c.length>=40)&&EFn(n),BHn(n),Txn(n),e=yln(n),i=0;e&&i<n.f;)eKn(n,e,e$n(n,e)),e=yln(n),++i;c&&tTn(n),n.a?p$n(n,f_n(n)):f_n(n),n.b=null,n.d=null,n.p=null,n.c=null,n.g=null,n.i=null,n.n=null,n.o=null,HSn(t)}}function V_n(n,t,e,i){var r,c,a,u,o,s,h,f;for(XR(u=new xI(e,i),BB(mMn(t,(Mrn(),oat)),8)),f=new Wb(t.e);f.a<f.c.c.length;)UR((h=BB(n0(f),144)).d,u),WB(n.e,h);for(a=new Wb(t.c);a.a<a.c.c.length;){for(r=new Wb((c=BB(n0(a),282)).a);r.a<r.c.c.length;)UR(BB(n0(r),559).d,u);WB(n.c,c)}for(s=new Wb(t.d);s.a<s.c.c.length;)UR((o=BB(n0(s),447)).d,u),WB(n.d,o)}function Q_n(n,t){var e,i,r,c,a,u,o,s;for(o=new Wb(t.j);o.a<o.c.c.length;)for(r=new m6((u=BB(n0(o),11)).b);y$(r.a)||y$(r.b);)t!=(c=(e=(i=BB(y$(r.a)?n0(r.a):n0(r.b),17)).c==u?i.d:i.c).i)&&((s=BB(mMn(i,(HXn(),fpt)),19).a)<0&&(s=0),a=c.p,0==n.b[a]&&(i.d==e?(n.a[a]-=s+1,n.a[a]<=0&&n.c[a]>0&&DH(n.f,c)):(n.c[a]-=s+1,n.c[a]<=0&&n.a[a]>0&&DH(n.e,c))))}function Y_n(n){var t,e,i,r,c,a,u;for(c=new dE(BB(yX(new Rn),62)),u=_Qn,e=new Wb(n.d);e.a<e.c.c.length;){for(u=(t=BB(n0(e),222)).c.c;0!=c.a.c&&(a=BB(MU(q9(c.a)),222)).c.c+a.c.b<u;)$J(c.a,a);for(r=new Fb(new BR(new xN(new Kb(c.a).a).b));aS(r.a.a);)DH((i=BB(mx(r.a).cd(),222)).b,t),DH(t.b,i);Mon(c.a,t,(hN(),ptt))}}function J_n(n,t,e){var i,r,c,a,u,o,s,h,f;for(c=new J6(t.c.length),s=new Wb(t);s.a<s.c.c.length;)a=BB(n0(s),10),WB(c,n.b[a.c.p][a.p]);for(mqn(n,c,e),f=null;f=ezn(c);)rBn(n,BB(f.a,233),BB(f.b,233),c);for(t.c=x8(Ant,HWn,1,0,5,1),r=new Wb(c);r.a<r.c.c.length;)for(o=0,h=(u=(i=BB(n0(r),233)).d).length;o<h;++o)a=u[o],t.c[t.c.length]=a,n.a[a.c.p][a.p].a=lL(i.g,i.d[0]).a}function Z_n(n,t){var e,i,r,c;if(0<(cL(n,14)?BB(n,14).gc():F3(n.Kc()))){if(1<(r=t)){for(--r,c=new pa,i=n.Kc();i.Ob();)e=BB(i.Pb(),86),c=Wen(Pun(Gk(xnt,1),HWn,20,0,[c,new bg(e)]));return Z_n(c,r)}if(r<0){for(c=new va,i=n.Kc();i.Ob();)e=BB(i.Pb(),86),c=Wen(Pun(Gk(xnt,1),HWn,20,0,[c,new bg(e)]));if(0<(cL(c,14)?BB(c,14).gc():F3(c.Kc())))return Z_n(c,r)}}return BB(iL(n.Kc()),86)}function nKn(){nKn=O,GCt=new QI("DEFAULT_MINIMUM_SIZE",0),UCt=new QI("MINIMUM_SIZE_ACCOUNTS_FOR_PADDING",1),qCt=new QI("COMPUTE_PADDING",2),XCt=new QI("OUTSIDE_NODE_LABELS_OVERHANG",3),WCt=new QI("PORTS_OVERHANG",4),QCt=new QI("UNIFORM_PORT_SPACING",5),VCt=new QI("SPACE_EFFICIENT_PORT_LABELS",6),zCt=new QI("FORCE_TABULAR_NODE_LABELS",7),HCt=new QI("ASYMMETRICAL",8)}function tKn(n,t){var e,i,r,c,a,u,o,s;if(t){if(e=(c=t.Tg())?Utn(c).Nh().Jh(c):null){for(Jgn(n,t,e),o=0,s=(null==(r=t.Tg()).i&&qFn(r),r.i).length;o<s;++o)null==r.i&&qFn(r),i=r.i,(u=o>=0&&o<i.length?i[o]:null).Ij()&&!u.Jj()&&(cL(u,322)?nvn(n,BB(u,34),t,e):0!=((a=BB(u,18)).Bb&h6n)&&sEn(n,a,t,e));t.kh()&&BB(e,49).vh(BB(t,49).qh())}return e}return null}function eKn(n,t,e){var i,r,c;if(!t.f)throw Hp(new Ky("Given leave edge is no tree edge."));if(e.f)throw Hp(new Ky("Given enter edge is a tree edge already."));for(t.f=!1,eL(n.p,t),e.f=!0,TU(n.p,e),i=e.e.e-e.d.e-e.a,FIn(n,e.e,t)||(i=-i),c=new Wb(n.e.a);c.a<c.c.c.length;)FIn(n,r=BB(n0(c),121),t)||(r.e+=i);n.j=1,nk(n.c),pCn(n,BB(n0(new Wb(n.e.a)),121)),gGn(n)}function iKn(n,t){var e,i,r,c,a,u;if((u=BB(mMn(t,(HXn(),ept)),98))==(QEn(),WIt)||u==XIt)for(r=new xI(t.f.a+t.d.b+t.d.c,t.f.b+t.d.d+t.d.a).b,a=new Wb(n.a);a.a<a.c.c.length;)(c=BB(n0(a),10)).k==(uSn(),Mut)&&((e=BB(mMn(c,(hWn(),Qft)),61))!=(kUn(),oCt)&&e!=ICt||(i=Gy(MD(mMn(c,Tlt))),u==WIt&&(i*=r),c.n.b=i-BB(mMn(c,npt),8).b,Jan(c,!1,!0)))}function rKn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b;if(Ytn(n,t,e),c=t[e],b=i?(kUn(),ICt):(kUn(),oCt),mL(t.length,e,i)){for(G6(n,r=t[i?e-1:e+1],i?(ain(),qvt):(ain(),Hvt)),h=0,l=(o=c).length;h<l;++h)xvn(n,a=o[h],b);for(G6(n,c,i?(ain(),Hvt):(ain(),qvt)),s=0,f=(u=r).length;s<f;++s)(a=u[s]).e||xvn(n,a,Tln(b))}else for(s=0,f=(u=c).length;s<f;++s)xvn(n,a=u[s],b);return!1}function cKn(n,t,e,i){var r,c,a,u,o;u=abn(t,e),(e==(kUn(),SCt)||e==ICt)&&(u=cL(u,152)?o6(BB(u,152)):cL(u,131)?BB(u,131).a:cL(u,54)?new fy(u):new IT(u)),a=!1;do{for(r=!1,c=0;c<u.gc()-1;c++)BMn(n,BB(u.Xb(c),11),BB(u.Xb(c+1),11),i)&&(a=!0,k0(n.a,BB(u.Xb(c),11),BB(u.Xb(c+1),11)),o=BB(u.Xb(c+1),11),u._c(c+1,BB(u.Xb(c),11)),u._c(c,o),r=!0)}while(r);return a}function aKn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w;if(!mA(n.e))return BB(YCn(n,t,e),72);if(t!=e&&(a=(b=(r=BB(n.g,119))[e]).ak(),$xn(n.e,a))){for(w=axn(n.e.Tg(),a),o=-1,u=-1,i=0,s=0,f=t>e?t:e;s<=f;++s)s==e?u=i++:(c=r[s],h=w.rl(c.ak()),s==t&&(o=s!=f||h?i:i-1),h&&++i);return l=BB(Cln(n,t,e),72),u!=o&&Lv(n,new j9(n.e,7,a,iln(u),b.dd(),o)),l}return BB(Cln(n,t,e),72)}function uKn(n,t){var e,i,r,c,a,u;for(OTn(t,"Port order processing",1),u=BB(mMn(n,(HXn(),opt)),421),e=new Wb(n.b);e.a<e.c.c.length;)for(r=new Wb(BB(n0(e),29).a);r.a<r.c.c.length;)i=BB(n0(r),10),c=BB(mMn(i,ept),98),a=i.j,c==(QEn(),UIt)||c==WIt||c==XIt?(SQ(),m$(a,sst)):c!=QIt&&c!=YIt&&(SQ(),m$(a,fst),Lvn(a),u==(U7(),Kvt)&&m$(a,hst)),i.i=!0,eCn(i);HSn(t)}function oKn(n){var t,i,r,c,a,u,o,s;for(s=new xp,t=new Fv,u=n.Kc();u.Ob();)c=BB(u.Pb(),10),o=AN(oM(new qv,c),t),jIn(s.f,c,o);for(a=n.Kc();a.Ob();)for(r=new oz(ZL(lbn(c=BB(a.Pb(),10)).a.Kc(),new h));dAn(r);)b5(i=BB(U5(r),17))||UNn(aM(cM(rM(uM(new Hv,e.Math.max(1,BB(mMn(i,(HXn(),lpt)),19).a)),1),BB(RX(s,i.c.i),121)),BB(RX(s,i.d.i),121)));return t}function sKn(){sKn=O,byt=dq(new B2,(yMn(),Fat),(lWn(),vot)),dyt=dq(new B2,Kat,jot),gyt=WG(dq(new B2,Kat,Dot),Bat,xot),lyt=WG(dq(dq(new B2,Kat,lot),Fat,bot),Bat,wot),pyt=ogn(ogn(FM(WG(dq(new B2,Rat,Uot),Bat,zot),Fat),Got),Xot),wyt=WG(new B2,Bat,mot),hyt=WG(dq(dq(dq(new B2,_at,Mot),Fat,Pot),Fat,Iot),Bat,Sot),fyt=WG(dq(dq(new B2,Fat,Iot),Fat,uot),Bat,aot)}function hKn(n,t,e,i,r,c){var a,u,o,s,h,f;for(a=lSn(t,o=jon(t)-jon(n)),u=M$(0,0,0);o>=0&&(!Iyn(n,a)||(o<22?u.l|=1<<o:o<44?u.m|=1<<o-22:u.h|=1<<o-44,0!=n.l||0!=n.m||0!=n.h));)s=a.m,h=a.h,f=a.l,a.h=h>>>1,a.m=s>>>1|(1&h)<<21,a.l=f>>>1|(1&s)<<21,--o;return e&&Oon(u),c&&(i?(ltt=aon(n),r&&(ltt=hun(ltt,(X7(),dtt)))):ltt=M$(n.l,n.m,n.h)),u}function fKn(n,t){var e,i,r,c,a,u,o,s,h,f;for(s=n.e[t.c.p][t.p]+1,o=t.c.a.c.length+1,u=new Wb(n.a);u.a<u.c.c.length;){for(a=BB(n0(u),11),f=0,c=0,r=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[new Hw(a),new Gw(a)])));dAn(r);)(i=BB(U5(r),11)).i.c==t.c&&(f+=bL(n,i.i)+1,++c);e=f/c,(h=a.j)==(kUn(),oCt)?n.f[a.p]=e<s?n.c-e:n.b+(o-e):h==ICt&&(n.f[a.p]=e<s?n.b+e:n.c-(o-e))}}function lKn(n,t,e){var i,r,c,a;if(null==n)throw Hp(new Mk(zWn));for(i=(c=n.length)>0&&(b1(0,n.length),45==n.charCodeAt(0)||(b1(0,n.length),43==n.charCodeAt(0)))?1:0;i<c;i++)if(-1==egn((b1(i,n.length),n.charCodeAt(i))))throw Hp(new Mk(DQn+n+'"'));if(r=(a=parseInt(n,10))<t,isNaN(a))throw Hp(new Mk(DQn+n+'"'));if(r||a>e)throw Hp(new Mk(DQn+n+'"'));return a}function bKn(n){var t,i,r,c,a,u;for(a=new YT,c=new Wb(n.a);c.a<c.c.c.length;)Vl(r=BB(n0(c),112),r.f.c.length),Ql(r,r.k.c.length),0==r.i&&(r.o=0,r5(a,r,a.c.b,a.c));for(;0!=a.b;)for(i=(r=BB(0==a.b?null:(Px(0!=a.b),Atn(a,a.a.a)),112)).o+1,t=new Wb(r.f);t.a<t.c.c.length;)Yl(u=BB(n0(t),129).a,e.Math.max(u.o,i)),Ql(u,u.i-1),0==u.i&&r5(a,u,a.c.b,a.c)}function wKn(n){var t,e,i,r,c,a,u,o;for(a=new Wb(n);a.a<a.c.c.length;){for(c=BB(n0(a),79),u=(i=PTn(BB(Wtn((!c.b&&(c.b=new h_(_Ot,c,4,7)),c.b),0),82))).i,o=i.j,IA(r=BB(Wtn((!c.a&&(c.a=new eU(FOt,c,6,6)),c.a),0),202),r.j+u,r.k+o),PA(r,r.b+u,r.c+o),e=new AL((!r.a&&(r.a=new $L(xOt,r,5)),r.a));e.e!=e.i.gc();)TA(t=BB(kpn(e),469),t.a+u,t.b+o);Yrn(BB(ZAn(c,(sWn(),OSt)),74),u,o)}}function dKn(n){switch(n){case 100:return mWn(snt,!0);case 68:return mWn(snt,!1);case 119:return mWn(hnt,!0);case 87:return mWn(hnt,!1);case 115:return mWn(fnt,!0);case 83:return mWn(fnt,!1);case 99:return mWn(lnt,!0);case 67:return mWn(lnt,!1);case 105:return mWn(bnt,!0);case 73:return mWn(bnt,!1);default:throw Hp(new dy(ont+n.toString(16)))}}function gKn(n){var t,i,r,c,a;switch(c=BB(xq(n.a,0),10),t=new $vn(n),WB(n.a,t),t.o.a=e.Math.max(1,c.o.a),t.o.b=e.Math.max(1,c.o.b),t.n.a=c.n.a,t.n.b=c.n.b,BB(mMn(c,(hWn(),Qft)),61).g){case 4:t.n.a+=2;break;case 1:t.n.b+=2;break;case 2:t.n.a-=2;break;case 3:t.n.b-=2}return IZ(r=new ISn,t),SZ(i=new wY,a=BB(xq(c.j,0),11)),MZ(i,r),UR(kO(r.n),a.n),UR(kO(r.a),a.a),t}function pKn(n,t,e,i,r){e&&(!i||(n.c-n.b&n.a.length-1)>1)&&1==t&&BB(n.a[n.b],10).k==(uSn(),Sut)?hFn(BB(n.a[n.b],10),(Xyn(),jIt)):i&&(!e||(n.c-n.b&n.a.length-1)>1)&&1==t&&BB(n.a[n.c-1&n.a.length-1],10).k==(uSn(),Sut)?hFn(BB(n.a[n.c-1&n.a.length-1],10),(Xyn(),EIt)):2==(n.c-n.b&n.a.length-1)?(hFn(BB(Eon(n),10),(Xyn(),jIt)),hFn(BB(Eon(n),10),EIt)):sLn(n,r),o4(n)}function vKn(n,t,i){var r,c,a,u,o;for(a=0,c=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));c.e!=c.i.gc();)u="",0==(!(r=BB(kpn(c),33)).n&&(r.n=new eU(zOt,r,1,7)),r.n).i||(u=BB(Wtn((!r.n&&(r.n=new eU(zOt,r,1,7)),r.n),0),137).a),qan(o=new csn(a++,t,u),r),hon(o,(qqn(),skt),r),o.e.b=r.j+r.f/2,o.f.a=e.Math.max(r.g,1),o.e.a=r.i+r.g/2,o.f.b=e.Math.max(r.f,1),DH(t.b,o),jIn(i.f,r,o)}function mKn(n){var t,e,i,r,c;i=BB(mMn(n,(hWn(),dlt)),33),c=BB(ZAn(i,(HXn(),Fgt)),174).Hc((mdn(),KCt)),n.e||(r=BB(mMn(n,Zft),21),t=new xI(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a),r.Hc((bDn(),lft))?(Ypn(i,ept,(QEn(),XIt)),_Un(i,t.a,t.b,!1,!0)):qy(TD(ZAn(i,Bgt)))||_Un(i,t.a,t.b,!0,!0)),Ypn(i,Fgt,c?nbn(KCt):new Y_(e=BB(Vj(YCt),9),BB(SR(e,e.length),9),0))}function yKn(n,t,e){var i,r,c,a;if(t[0]>=n.length)return e.o=0,!0;switch(fV(n,t[0])){case 43:r=1;break;case 45:r=-1;break;default:return e.o=0,!0}if(++t[0],c=t[0],0==(a=UCn(n,t))&&t[0]==c)return!1;if(t[0]<n.length&&58==fV(n,t[0])){if(i=60*a,++t[0],c=t[0],0==(a=UCn(n,t))&&t[0]==c)return!1;i+=a}else(i=a)<24&&t[0]-c<=2?i*=60:i=i%100+60*(i/100|0);return i*=r,e.o=-i,!0}function kKn(n){var t,e,i,r,c,a,u;for(r=new Np,i=new oz(ZL(lbn(n.b).a.Kc(),new h));dAn(i);)b5(e=BB(U5(i),17))&&WB(r,new j6(e,v9(n,e.c),v9(n,e.d)));for(u=new _b(new Ob(n.e).a.vc().Kc());u.a.Ob();)t=BB(u.a.Pb(),42),(c=BB(t.dd(),113)).d.p=0;for(a=new _b(new Ob(n.e).a.vc().Kc());a.a.Ob();)t=BB(a.a.Pb(),42),0==(c=BB(t.dd(),113)).d.p&&WB(n.d,R_n(n,c))}function jKn(n){var t,e,i,r,c;for(c=WJ(n),r=new AL((!n.e&&(n.e=new h_(KOt,n,7,4)),n.e));r.e!=r.i.gc();)if(i=BB(kpn(r),79),!Itn(PTn(BB(Wtn((!i.c&&(i.c=new h_(_Ot,i,5,8)),i.c),0),82)),c))return!0;for(e=new AL((!n.d&&(n.d=new h_(KOt,n,8,5)),n.d));e.e!=e.i.gc();)if(t=BB(kpn(e),79),!Itn(PTn(BB(Wtn((!t.b&&(t.b=new h_(_Ot,t,4,7)),t.b),0),82)),c))return!0;return!1}function EKn(n){var t,i,r,c,a,u,o,s;for(s=new km,o=null,i=BB(b3(t=spn(n,0)),8),c=BB(b3(t),8);t.b!=t.d.c;)o=i,i=c,c=BB(b3(t),8),a=ctn(XR(new xI(o.a,o.b),i)),u=ctn(XR(new xI(c.a,c.b),i)),r=10,r=e.Math.min(r,e.Math.abs(a.a+a.b)/2),r=e.Math.min(r,e.Math.abs(u.a+u.b)/2),a.a=HH(a.a)*r,a.b=HH(a.b)*r,u.a=HH(u.a)*r,u.b=HH(u.b)*r,DH(s,UR(a,i)),DH(s,UR(u,i));return s}function TKn(n,t,e,i){var r,c,a,u,o;return a=n.eh(),r=null,(o=n.Zg())?t&&0==(g_n(n,t,e).Bb&BQn)?(i=Kpn(o.Vk(),n,i),n.uh(null),r=t.fh()):o=null:(a&&(o=a.fh()),t&&(r=t.fh())),o!=r&&o&&o.Zk(n),u=n.Vg(),n.Rg(t,e),o!=r&&r&&r.Yk(n),n.Lg()&&n.Mg()&&(a&&u>=0&&u!=e&&(c=new nU(n,1,u,a,null),i?i.Ei(c):i=c),e>=0&&(c=new nU(n,1,e,u==e?a:null,t),i?i.Ei(c):i=c)),i}function MKn(n){var t,e,i;if(null==n.b){if(i=new Sk,null!=n.i&&(cO(i,n.i),i.a+=":"),0!=(256&n.f)){for(0!=(256&n.f)&&null!=n.a&&(rQ(n.i)||(i.a+="//"),cO(i,n.a)),null!=n.d&&(i.a+="/",cO(i,n.d)),0!=(16&n.f)&&(i.a+="/"),t=0,e=n.j.length;t<e;t++)0!=t&&(i.a+="/"),cO(i,n.j[t]);null!=n.g&&(i.a+="?",cO(i,n.g))}else cO(i,n.a);null!=n.e&&(i.a+="#",cO(i,n.e)),n.b=i.a}return n.b}function SKn(n,t){var e,i,r,c,a,u;for(r=new Wb(t.a);r.a<r.c.c.length;)cL(c=mMn(i=BB(n0(r),10),(hWn(),dlt)),11)&&(u=yFn(t,i,(a=BB(c,11)).o.a,a.o.b),a.n.a=u.a,a.n.b=u.b,qIn(a,BB(mMn(i,Qft),61)));e=new xI(t.f.a+t.d.b+t.d.c,t.f.b+t.d.d+t.d.a),BB(mMn(t,(hWn(),Zft)),21).Hc((bDn(),lft))?(hon(n,(HXn(),ept),(QEn(),XIt)),BB(mMn(vW(n),Zft),21).Fc(dft),bGn(n,e,!1)):bGn(n,e,!0)}function PKn(n,t,e){var i,r,c,a,u;OTn(e,"Minimize Crossings "+n.a,1),i=0==t.b.c.length||!jE(AV(new Rq(null,new w1(t.b,16)),new aw(new Ac))).sd((dM(),tit)),u=1==t.b.c.length&&1==BB(xq(t.b,0),29).a.c.length,c=GC(mMn(t,(HXn(),sgt)))===GC((ufn(),pIt)),i||u&&!c||(Ssn(r=sxn(n,t),(a=BB(Dpn(r,0),214)).c.Rf()?a.c.Lf()?new Ud(n):new Xd(n):new zd(n)),afn(n)),HSn(e)}function IKn(n,t,e,i){var r,c,a,u;if(u=dG(cbn(SVn,rV(dG(cbn(null==t?0:nsn(t),PVn)),15))),r=dG(cbn(SVn,rV(dG(cbn(null==e?0:nsn(e),PVn)),15))),a=Zrn(n,t,u),c=Jrn(n,e,r),a&&r==a.a&&wW(e,a.g))return e;if(c&&!i)throw Hp(new Ky("key already present: "+e));return a&&LLn(n,a),c&&LLn(n,c),YIn(n,new qW(e,r,t,u),c),c&&(c.e=null,c.c=null),a&&(a.e=null,a.c=null),qkn(n),a?a.g:null}function CKn(n,t,e){var i,r,c,a,u;for(c=0;c<t;c++){for(i=0,u=c+1;u<t;u++)i=rbn(rbn(cbn(e0(n[c],UQn),e0(n[u],UQn)),e0(e[c+u],UQn)),e0(dG(i),UQn)),e[c+u]=dG(i),i=jz(i,32);e[c+t]=dG(i)}for(ncn(e,e,t<<1),i=0,r=0,a=0;r<t;++r,a++)i=rbn(rbn(cbn(e0(n[r],UQn),e0(n[r],UQn)),e0(e[a],UQn)),e0(dG(i),UQn)),e[a]=dG(i),i=rbn(i=jz(i,32),e0(e[++a],UQn)),e[a]=dG(i),i=jz(i,32);return e}function OKn(n,t,i){var r,c,a,u,o,s,h,f;if(!h3(t)){for(s=Gy(MD(edn(i.c,(HXn(),Npt)))),!(h=BB(edn(i.c,Lpt),142))&&(h=new lm),r=i.a,c=null,o=t.Kc();o.Ob();)u=BB(o.Pb(),11),f=0,c?(f=s,f+=c.o.b):f=h.d,a=AN(oM(new qv,u),n.f),VW(n.k,u,a),UNn(aM(cM(rM(uM(new Hv,0),IJ(e.Math.ceil(f))),r),a)),c=u,r=a;UNn(aM(cM(rM(uM(new Hv,0),IJ(e.Math.ceil(h.a+c.o.b))),r),i.d))}}function AKn(n,t,e,i,r,c,a,u){var o,s,h;return h=!1,s=c-e.s,o=e.t-t.f+cHn(e,s,!1).a,!(i.g+u>s)&&(o+u+cHn(i,s,!1).a<=t.b&&(p9(e,c-e.s),e.c=!0,p9(i,c-e.s),Tvn(i,e.s,e.t+e.d+u),i.k=!0,xcn(e.q,i),h=!0,r&&(tin(t,i),i.j=t,n.c.length>a&&(Tkn((l1(a,n.c.length),BB(n.c[a],200)),i),0==(l1(a,n.c.length),BB(n.c[a],200)).a.c.length&&s6(n,a)))),h)}function $Kn(n,t){var e,i,r,c,a;if(OTn(t,"Partition midprocessing",1),r=new pJ,JT(AV(new Rq(null,new w1(n.a,16)),new di),new ld(r)),0!=r.d){for(a=BB(P4(a1(new Rq(null,(r.i||(r.i=new HL(r,r.c))).Nc())),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15),e=BB((i=a.Kc()).Pb(),19);i.Ob();)c=BB(i.Pb(),19),XLn(BB(h6(r,e),21),BB(h6(r,c),21)),e=c;HSn(t)}}function LKn(n,t,e){var i,r,c,a,u;if(0==t.p){for(t.p=1,(r=e)||(r=new rC(new Np,new Y_(i=BB(Vj(FCt),9),BB(SR(i,i.length),9),0))),BB(r.a,15).Fc(t),t.k==(uSn(),Mut)&&BB(r.b,21).Fc(BB(mMn(t,(hWn(),Qft)),61)),a=new Wb(t.j);a.a<a.c.c.length;)for(c=BB(n0(a),11),u=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[new Hw(c),new Gw(c)])));dAn(u);)LKn(n,BB(U5(u),11).i,r);return r}return null}function NKn(n,t){var e,i,r,c,a;if(n.Ab)if(n.Ab){if((a=n.Ab.i)>0)if(r=BB(n.Ab.g,1934),null==t){for(c=0;c<a;++c)if(null==(e=r[c]).d)return e}else for(c=0;c<a;++c)if(m_(t,(e=r[c]).d))return e}else if(null==t){for(i=new AL(n.Ab);i.e!=i.i.gc();)if(null==(e=BB(kpn(i),590)).d)return e}else for(i=new AL(n.Ab);i.e!=i.i.gc();)if(m_(t,(e=BB(kpn(i),590)).d))return e;return null}function xKn(n,t){var e,i,r,c,a,u,o;if(null==(o=TD(mMn(t,(IAn(),Nkt))))||(kW(o),o)){for(DOn(n,t),r=new Np,u=spn(t.b,0);u.b!=u.d.c;)(e=xPn(n,BB(b3(u),86),null))&&(qan(e,t),r.c[r.c.length]=e);if(n.a=null,n.b=null,r.c.length>1)for(i=new Wb(r);i.a<i.c.c.length;)for(c=0,a=spn((e=BB(n0(i),135)).b,0);a.b!=a.d.c;)BB(b3(a),86).g=c++;return r}return u6(Pun(Gk(Gyt,1),tZn,135,0,[t]))}function DKn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p;crn(b=A3(n,qun(t),r),R2(r,q6n)),d=D2(w=r,U6n),cSn(new Lg(b).a,d),g=D2(w,"endPoint"),rSn(new Rg(b).a,g),p=N2(w,D6n),SEn(new Fg(b).a,p),f=R2(r,_6n),qR((c=new hC(n,b)).a,c.b,f),l=R2(r,R6n),GR((a=new fC(n,b)).a,a.b,l),s=N2(r,F6n),Fyn((u=new lC(e,b)).b,u.a,s),h=N2(r,K6n),Byn((o=new bC(i,b)).b,o.a,h)}function RKn(n,t,e){var i,r,c,a,u;switch(u=null,t.g){case 1:for(r=new Wb(n.j);r.a<r.c.c.length;)if(qy(TD(mMn(i=BB(n0(r),11),(hWn(),tlt)))))return i;hon(u=new ISn,(hWn(),tlt),(hN(),!0));break;case 2:for(a=new Wb(n.j);a.a<a.c.c.length;)if(qy(TD(mMn(c=BB(n0(a),11),(hWn(),klt)))))return c;hon(u=new ISn,(hWn(),klt),(hN(),!0))}return u&&(IZ(u,n),qIn(u,e),yvn(u.n,n.o,e)),u}function _Kn(n,t){var i,r,c,a,u,o;for(o=-1,u=new YT,r=new m6(n.b);y$(r.a)||y$(r.b);){for(i=BB(y$(r.a)?n0(r.a):n0(r.b),17),o=e.Math.max(o,Gy(MD(mMn(i,(HXn(),agt))))),i.c==n?JT(AV(new Rq(null,new w1(i.b,16)),new fe),new nd(u)):JT(AV(new Rq(null,new w1(i.b,16)),new le),new td(u)),a=spn(u,0);a.b!=a.d.c;)Lx(c=BB(b3(a),70),(hWn(),Uft))||hon(c,Uft,i);gun(t,u),yQ(u)}return o}function KKn(n,t,e,i,r){var c,a,u,o;Bl(c=new $vn(n),(uSn(),Cut)),hon(c,(HXn(),ept),(QEn(),XIt)),hon(c,(hWn(),dlt),t.c.i),hon(a=new ISn,dlt,t.c),qIn(a,r),IZ(a,c),hon(t.c,Elt,c),Bl(u=new $vn(n),Cut),hon(u,ept,XIt),hon(u,dlt,t.d.i),hon(o=new ISn,dlt,t.d),qIn(o,r),IZ(o,u),hon(t.d,Elt,u),SZ(t,a),MZ(t,o),LZ(0,e.c.length),MS(e.c,0,c),i.c[i.c.length]=u,hon(c,Bft,iln(1)),hon(u,Bft,iln(1))}function FKn(n,t,i,r,c){var a,u,o,s,h;o=c?r.b:r.a,FT(n.a,r)||(h=o>i.s&&o<i.c,s=!1,0!=i.e.b&&0!=i.j.b&&(s|=e.Math.abs(o-Gy(MD(gx(i.e))))<lZn&&e.Math.abs(o-Gy(MD(gx(i.j))))<lZn,s|=e.Math.abs(o-Gy(MD(px(i.e))))<lZn&&e.Math.abs(o-Gy(MD(px(i.j))))<lZn),(h||s)&&((u=BB(mMn(t,(HXn(),vgt)),74))||(u=new km,hon(t,vgt,u)),r5(u,a=new wA(r),u.c.b,u.c),TU(n.a,a)))}function BKn(n,t,e,i){var r,c,a,u,o,s,h;if(WCn(n,t,e,i))return!0;for(a=new Wb(t.f);a.a<a.c.c.length;){switch(c=BB(n0(a),324),u=!1,s=(o=n.j-t.j+e)+t.o,r=(h=n.k-t.k+i)+t.p,c.a.g){case 0:u=Osn(n,o+c.b.a,0,o+c.c.a,h-1);break;case 1:u=Osn(n,s,h+c.b.a,n.o-1,h+c.c.a);break;case 2:u=Osn(n,o+c.b.a,r,o+c.c.a,n.p-1);break;default:u=Osn(n,0,h+c.b.a,o-1,h+c.c.a)}if(u)return!0}return!1}function HKn(n,t){var e,i,r,c,a,u,o,s;for(c=new Wb(t.b);c.a<c.c.c.length;)for(o=new Wb(BB(n0(c),29).a);o.a<o.c.c.length;){for(u=BB(n0(o),10),s=new Np,a=0,i=new oz(ZL(fbn(u).a.Kc(),new h));dAn(i);)b5(e=BB(U5(i),17))||!b5(e)&&e.c.i.c==e.d.i.c||((r=BB(mMn(e,(HXn(),bpt)),19).a)>a&&(a=r,s.c=x8(Ant,HWn,1,0,5,1)),r==a&&WB(s,new rC(e.c.i,e)));SQ(),m$(s,n.c),kG(n.b,u.p,s)}}function qKn(n,t){var e,i,r,c,a,u,o,s;for(c=new Wb(t.b);c.a<c.c.c.length;)for(o=new Wb(BB(n0(c),29).a);o.a<o.c.c.length;){for(u=BB(n0(o),10),s=new Np,a=0,i=new oz(ZL(lbn(u).a.Kc(),new h));dAn(i);)b5(e=BB(U5(i),17))||!b5(e)&&e.c.i.c==e.d.i.c||((r=BB(mMn(e,(HXn(),bpt)),19).a)>a&&(a=r,s.c=x8(Ant,HWn,1,0,5,1)),r==a&&WB(s,new rC(e.d.i,e)));SQ(),m$(s,n.c),kG(n.f,u.p,s)}}function GKn(n){NM(n,new MTn(vj(wj(pj(gj(new du,l5n),"ELK Box"),"Algorithm for packing of unconnected boxes, i.e. graphs without edges."),new xu))),u2(n,l5n,QJn,zMt),u2(n,l5n,vZn,15),u2(n,l5n,pZn,iln(0)),u2(n,l5n,A4n,mpn(KMt)),u2(n,l5n,PZn,mpn(BMt)),u2(n,l5n,SZn,mpn(qMt)),u2(n,l5n,VJn,f5n),u2(n,l5n,jZn,mpn(FMt)),u2(n,l5n,BZn,mpn(HMt)),u2(n,l5n,b5n,mpn(RMt)),u2(n,l5n,u3n,mpn(_Mt))}function zKn(n,t){var e,i,r,c,a,u,o,s,h;if(a=(r=n.i).o.a,c=r.o.b,a<=0&&c<=0)return kUn(),PCt;switch(s=n.n.a,h=n.n.b,u=n.o.a,e=n.o.b,t.g){case 2:case 1:if(s<0)return kUn(),ICt;if(s+u>a)return kUn(),oCt;break;case 4:case 3:if(h<0)return kUn(),sCt;if(h+e>c)return kUn(),SCt}return(o=(s+u/2)/a)+(i=(h+e/2)/c)<=1&&o-i<=0?(kUn(),ICt):o+i>=1&&o-i>=0?(kUn(),oCt):i<.5?(kUn(),sCt):(kUn(),SCt)}function UKn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;for(e=!1,o=Gy(MD(mMn(t,(HXn(),Opt)))),l=_Vn*o,r=new Wb(t.b);r.a<r.c.c.length;)for(i=BB(n0(r),29),c=BB(n0(u=new Wb(i.a)),10),s=wU(n.a[c.p]);u.a<u.c.c.length;)a=BB(n0(u),10),s!=(h=wU(n.a[a.p]))&&(f=_$(n.b,c,a),c.n.b+c.o.b+c.d.a+s.a+f>a.n.b-a.d.d+h.a+l&&(b=s.g+h.g,h.a=(h.g*h.a+s.g*s.a)/b,h.g=b,s.f=h,e=!0)),c=a,s=h;return e}function XKn(n,t,e,i,r,c,a){var u,o,s,h,f;for(f=new bA,o=t.Kc();o.Ob();)for(h=new Wb(BB(o.Pb(),839).wf());h.a<h.c.c.length;)GC((s=BB(n0(h),181)).We((sWn(),gSt)))===GC((Rtn(),XPt))&&(r_n(f,s,!1,i,r,c,a),IPn(n,f));for(u=e.Kc();u.Ob();)for(h=new Wb(BB(u.Pb(),839).wf());h.a<h.c.c.length;)GC((s=BB(n0(h),181)).We((sWn(),gSt)))===GC((Rtn(),UPt))&&(r_n(f,s,!0,i,r,c,a),IPn(n,f))}function WKn(n,t,e){var i,r,c,a,u,o,s;for(a=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));a.e!=a.i.gc();)for(r=new oz(ZL(dLn(c=BB(kpn(a),33)).a.Kc(),new h));dAn(r);)nAn(i=BB(U5(r),79))||nAn(i)||QCn(i)||(o=BB(qC(AY(e.f,c)),86),s=BB(RX(e,PTn(BB(Wtn((!i.c&&(i.c=new h_(_Ot,i,5,8)),i.c),0),82))),86),o&&s&&(hon(u=new UQ(o,s),(qqn(),skt),i),qan(u,i),DH(o.d,u),DH(s.b,u),DH(t.a,u)))}function VKn(n,t){var i,r,c,a,u,o,s;for(o=BB(BB(h6(n.r,t),21),84).Kc();o.Ob();)(r=(u=BB(o.Pb(),111)).c?WH(u.c):0)>0?u.a?r>(s=u.b.rf().b)&&(n.v||1==u.c.d.c.length?(a=(r-s)/2,u.d.d=a,u.d.a=a):(i=(BB(xq(u.c.d,0),181).rf().b-s)/2,u.d.d=e.Math.max(0,i),u.d.a=r-i-s)):u.d.a=n.t+r:Hz(n.u)&&((c=KTn(u.b)).d<0&&(u.d.d=-c.d),c.d+c.a>u.b.rf().b&&(u.d.a=c.d+c.a-u.b.rf().b))}function QKn(n,t){var e;switch(vnn(n)){case 6:return XC(t);case 7:return UC(t);case 8:return zC(t);case 3:return Array.isArray(t)&&!((e=vnn(t))>=14&&e<=16);case 11:return null!=t&&typeof t===xWn;case 12:return null!=t&&(typeof t===AWn||typeof t==xWn);case 0:return Qpn(t,n.__elementTypeId$);case 2:return DU(t)&&!(t.im===C);case 1:return DU(t)&&!(t.im===C)||Qpn(t,n.__elementTypeId$);default:return!0}}function YKn(n,t){var i,r,c,a;return r=e.Math.min(e.Math.abs(n.c-(t.c+t.b)),e.Math.abs(n.c+n.b-t.c)),a=e.Math.min(e.Math.abs(n.d-(t.d+t.a)),e.Math.abs(n.d+n.a-t.d)),(i=e.Math.abs(n.c+n.b/2-(t.c+t.b/2)))>n.b/2+t.b/2||(c=e.Math.abs(n.d+n.a/2-(t.d+t.a/2)))>n.a/2+t.a/2?1:0==i&&0==c?0:0==i?a/c+1:0==c?r/i+1:e.Math.min(r/i,a/c)+1}function JKn(n,t){var i,r,c,a,u,o;return(c=iin(n))==(o=iin(t))?n.e==t.e&&n.a<54&&t.a<54?n.f<t.f?-1:n.f>t.f?1:0:(r=n.e-t.e,(i=(n.d>0?n.d:e.Math.floor((n.a-1)*zQn)+1)-(t.d>0?t.d:e.Math.floor((t.a-1)*zQn)+1))>r+1?c:i<r-1?-c:(!n.c&&(n.c=yhn(n.f)),a=n.c,!t.c&&(t.c=yhn(t.f)),u=t.c,r<0?a=Nnn(a,kBn(-r)):r>0&&(u=Nnn(u,kBn(r))),tgn(a,u))):c<o?-1:1}function ZKn(n,t){var e,i,r,c,a,u,o;for(c=0,u=0,o=0,r=new Wb(n.f.e);r.a<r.c.c.length;)t!=(i=BB(n0(r),144))&&(c+=a=n.i[t.b][i.b],(e=W8(t.d,i.d))>0&&n.d!=(q7(),Aat)&&(u+=a*(i.d.a+n.a[t.b][i.b]*(t.d.a-i.d.a)/e)),e>0&&n.d!=(q7(),Cat)&&(o+=a*(i.d.b+n.a[t.b][i.b]*(t.d.b-i.d.b)/e)));switch(n.d.g){case 1:return new xI(u/c,t.d.b);case 2:return new xI(t.d.a,o/c);default:return new xI(u/c,o/c)}}function nFn(n,t){var e,i,r,c;if(zsn(),c=BB(mMn(n.i,(HXn(),ept)),98),0!=n.j.g-t.j.g||c!=(QEn(),UIt)&&c!=WIt&&c!=XIt)return 0;if(c==(QEn(),UIt)&&(e=BB(mMn(n,ipt),19),i=BB(mMn(t,ipt),19),e&&i&&0!=(r=e.a-i.a)))return r;switch(n.j.g){case 1:return Pln(n.n.a,t.n.a);case 2:return Pln(n.n.b,t.n.b);case 3:return Pln(t.n.a,n.n.a);case 4:return Pln(t.n.b,n.n.b);default:throw Hp(new Fy(r1n))}}function tFn(n){var t,e,i,r,c;for(WB(c=new J6((!n.a&&(n.a=new $L(xOt,n,5)),n.a).i+2),new xI(n.j,n.k)),JT(new Rq(null,(!n.a&&(n.a=new $L(xOt,n,5)),new w1(n.a,16))),new Cg(c)),WB(c,new xI(n.b,n.c)),t=1;t<c.c.length-1;)l1(t-1,c.c.length),e=BB(c.c[t-1],8),l1(t,c.c.length),i=BB(c.c[t],8),l1(t+1,c.c.length),r=BB(c.c[t+1],8),e.a==i.a&&i.a==r.a||e.b==i.b&&i.b==r.b?s6(c,t):++t;return c}function eFn(n,t){var e,i,r,c,a,u,o;for(e=ON(iM(tM(eM(new Wv,t),new gY(t.e)),gst),n.a),0==t.j.c.length||V9(BB(xq(t.j,0),57).a,e),o=new Dp,VW(n.e,e,o),a=new Rv,u=new Rv,c=new Wb(t.k);c.a<c.c.c.length;)TU(a,(r=BB(n0(c),17)).c),TU(u,r.d);(i=a.a.gc()-u.a.gc())<0?(Uun(o,!0,(Ffn(),KPt)),Uun(o,!1,FPt)):i>0&&(Uun(o,!1,(Ffn(),KPt)),Uun(o,!0,FPt)),Otn(t.g,new sP(n,e)),VW(n.g,t,e)}function iFn(){var n;for(iFn=O,Ltt=Pun(Gk(ANt,1),hQn,25,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]),Ntt=x8(ANt,hQn,25,37,15,1),xtt=Pun(Gk(ANt,1),hQn,25,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]),Dtt=x8(LNt,FQn,25,37,14,1),n=2;n<=36;n++)Ntt[n]=IJ(e.Math.pow(n,Ltt[n])),Dtt[n]=Ojn(bVn,Ntt[n])}function rFn(n){var t;if(1!=(!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i)throw Hp(new Ky(B5n+(!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i));return t=new km,bun(BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82))&&Frn(t,zXn(n,bun(BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82)),!1)),bun(BB(Wtn((!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c),0),82))&&Frn(t,zXn(n,bun(BB(Wtn((!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c),0),82)),!0)),t}function cFn(n,t){var e,i,r;for(r=!1,i=new oz(ZL((t.d?n.a.c==(gJ(),tyt)?fbn(t.b):lbn(t.b):n.a.c==(gJ(),nyt)?fbn(t.b):lbn(t.b)).a.Kc(),new h));dAn(i);)if(e=BB(U5(i),17),(qy(n.a.f[n.a.g[t.b.p].p])||b5(e)||e.c.i.c!=e.d.i.c)&&!qy(n.a.n[n.a.g[t.b.p].p])&&!qy(n.a.n[n.a.g[t.b.p].p])&&(r=!0,FT(n.b,n.a.g[Lmn(e,t.b).p])))return t.c=!0,t.a=e,t;return t.c=r,t.a=null,t}function aFn(n,t,e,i,r){var c,a,u,o,s,h,f;for(SQ(),m$(n,new Xu),u=new M2(n,0),f=new Np,c=0;u.b<u.d.gc();)Px(u.b<u.d.gc()),a=BB(u.d.Xb(u.c=u.b++),157),0!=f.c.length&&iG(a)*eG(a)>2*c?(h=new Gtn(f),s=iG(a)/eG(a),o=yXn(h,t,new bm,e,i,r,s),UR(kO(h.e),o),f.c=x8(Ant,HWn,1,0,5,1),c=0,f.c[f.c.length]=h,f.c[f.c.length]=a,c=iG(h)*eG(h)+iG(a)*eG(a)):(f.c[f.c.length]=a,c+=iG(a)*eG(a));return f}function uFn(n,t,e){var i,r,c,a,u,o,s;if(0==(i=e.gc()))return!1;if(n.ej())if(o=n.fj(),kwn(n,t,e),a=1==i?n.Zi(3,null,e.Kc().Pb(),t,o):n.Zi(5,null,e,t,o),n.bj()){for(u=i<100?null:new Fj(i),c=t+i,r=t;r<c;++r)s=n.Oi(r),u=n.cj(s,u);u?(u.Ei(a),u.Fi()):n.$i(a)}else n.$i(a);else if(kwn(n,t,e),n.bj()){for(u=i<100?null:new Fj(i),c=t+i,r=t;r<c;++r)u=n.cj(n.Oi(r),u);u&&u.Fi()}return!0}function oFn(n,t,e){var i,r,c,a;return n.ej()?(r=null,c=n.fj(),i=n.Zi(1,a=n.Ui(t,n.oi(t,e)),e,t,c),n.bj()&&!(n.ni()&&a?Nfn(a,e):GC(a)===GC(e))?(a&&(r=n.dj(a,r)),(r=n.cj(e,r))?(r.Ei(i),r.Fi()):n.$i(i)):r?(r.Ei(i),r.Fi()):n.$i(i),a):(a=n.Ui(t,n.oi(t,e)),n.bj()&&!(n.ni()&&a?Nfn(a,e):GC(a)===GC(e))&&(r=null,a&&(r=n.dj(a,null)),(r=n.cj(e,r))&&r.Fi()),a)}function sFn(n,t){var i,r,c,a,u,o,s,h;if(n.e=t,n.f=BB(mMn(t,(Mrn(),hat)),230),XTn(t),n.d=e.Math.max(16*t.e.c.length+t.c.c.length,256),!qy(TD(mMn(t,(fRn(),Hct)))))for(h=n.e.e.c.length,o=new Wb(t.e);o.a<o.c.c.length;)(s=BB(n0(o),144).d).a=OG(n.f)*h,s.b=OG(n.f)*h;for(i=t.b,a=new Wb(t.c);a.a<a.c.c.length;)if(c=BB(n0(a),282),(r=BB(mMn(c,eat),19).a)>0){for(u=0;u<r;u++)WB(i,new hX(c));BIn(c)}}function hFn(n,t){var i,r,c,a,u;if(n.k==(uSn(),Sut)&&(i=jE(AV(BB(mMn(n,(hWn(),Plt)),15).Oc(),new aw(new ri))).sd((dM(),tit))?t:(Xyn(),TIt),hon(n,ult,i),i!=(Xyn(),EIt)))for(r=BB(mMn(n,dlt),17),u=Gy(MD(mMn(r,(HXn(),agt)))),a=0,i==jIt?a=n.o.b-e.Math.ceil(u/2):i==TIt&&(n.o.b-=Gy(MD(mMn(vW(n),jpt))),a=(n.o.b-e.Math.ceil(u))/2),c=new Wb(n.j);c.a<c.c.c.length;)BB(n0(c),11).n.b=a}function fFn(){fFn=O,JM(),TNt=new Rh,Pun(Gk(A$t,2),sVn,368,0,[Pun(Gk(A$t,1),jnt,592,0,[new UE(z7n)])]),Pun(Gk(A$t,2),sVn,368,0,[Pun(Gk(A$t,1),jnt,592,0,[new UE(U7n)])]),Pun(Gk(A$t,2),sVn,368,0,[Pun(Gk(A$t,1),jnt,592,0,[new UE(X7n)]),Pun(Gk(A$t,1),jnt,592,0,[new UE(U7n)])]),new $A("-1"),Pun(Gk(A$t,2),sVn,368,0,[Pun(Gk(A$t,1),jnt,592,0,[new UE("\\c+")])]),new $A("0"),new $A("0"),new $A("1"),new $A("0"),new $A(int)}function lFn(n){var t,e;return n.c&&n.c.kh()&&(e=BB(n.c,49),n.c=BB(tfn(n,e),138),n.c!=e&&(0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,9,2,e,n.c)),cL(n.Cb,399)?n.Db>>16==-15&&n.Cb.nh()&&$7(new k9(n.Cb,9,13,e,n.c,uvn(H7(BB(n.Cb,59)),n))):cL(n.Cb,88)&&n.Db>>16==-23&&n.Cb.nh()&&(cL(t=n.c,88)||(gWn(),t=d$t),cL(e,88)||(gWn(),e=d$t),$7(new k9(n.Cb,9,10,e,t,uvn(a4(BB(n.Cb,26)),n)))))),n.c}function bFn(n,t){var e,i,r,c,a,u,o,s;for(OTn(t,"Hypernodes processing",1),i=new Wb(n.b);i.a<i.c.c.length;)for(a=new Wb(BB(n0(i),29).a);a.a<a.c.c.length;)if(qy(TD(mMn(c=BB(n0(a),10),(HXn(),bgt))))&&c.j.c.length<=2){for(s=0,o=0,e=0,r=0,u=new Wb(c.j);u.a<u.c.c.length;)switch(BB(n0(u),11).j.g){case 1:++s;break;case 2:++o;break;case 3:++e;break;case 4:++r}0==s&&0==e&&jXn(n,c,r<=o)}HSn(t)}function wFn(n,t){var e,i,r,c,a,u,o,s,h;for(OTn(t,"Layer constraint edge reversal",1),a=new Wb(n.b);a.a<a.c.c.length;){for(c=BB(n0(a),29),h=-1,e=new Np,s=n2(c.a),r=0;r<s.length;r++)i=BB(mMn(s[r],(hWn(),ilt)),303),-1==h?i!=(z7(),Ift)&&(h=r):i==(z7(),Ift)&&(PZ(s[r],null),Qyn(s[r],h++,c)),i==(z7(),Sft)&&WB(e,s[r]);for(o=new Wb(e);o.a<o.c.c.length;)PZ(u=BB(n0(o),10),null),PZ(u,c)}HSn(t)}function dFn(n,t,e){var i,r,c,a,u,o,s,h;for(OTn(e,"Hyperedge merging",1),xAn(n,t),u=new M2(t.b,0);u.b<u.d.gc();)if(Px(u.b<u.d.gc()),0!=(s=BB(u.d.Xb(u.c=u.b++),29).a).c.length)for(i=null,r=null,c=null,a=null,o=0;o<s.c.length;o++)l1(o,s.c.length),(r=(i=BB(s.c[o],10)).k)==(uSn(),Put)&&a==Put&&(h=hHn(i,c)).a&&(rDn(i,c,h.b,h.c),l1(o,s.c.length),PE(s.c,o,1),--o,i=c,r=a),c=i,a=r;HSn(e)}function gFn(n,t){var e,i,r;i=0!=H$n(n.d,1),!qy(TD(mMn(t.j,(hWn(),Jft))))&&!qy(TD(mMn(t.j,Clt)))||GC(mMn(t.j,(HXn(),Ldt)))===GC((mon(),Nvt))?t.c.Tf(t.e,i):i=qy(TD(mMn(t.j,Jft))),DNn(n,t,i,!0),qy(TD(mMn(t.j,Clt)))&&hon(t.j,Clt,(hN(),!1)),qy(TD(mMn(t.j,Jft)))&&(hon(t.j,Jft,(hN(),!1)),hon(t.j,Clt,!0)),e=e_n(n,t);do{if($rn(n),0==e)return 0;r=e,DNn(n,t,i=!i,!1),e=e_n(n,t)}while(r>e);return r}function pFn(n,t){var e,i,r;i=0!=H$n(n.d,1),!qy(TD(mMn(t.j,(hWn(),Jft))))&&!qy(TD(mMn(t.j,Clt)))||GC(mMn(t.j,(HXn(),Ldt)))===GC((mon(),Nvt))?t.c.Tf(t.e,i):i=qy(TD(mMn(t.j,Jft))),DNn(n,t,i,!0),qy(TD(mMn(t.j,Clt)))&&hon(t.j,Clt,(hN(),!1)),qy(TD(mMn(t.j,Jft)))&&(hon(t.j,Jft,(hN(),!1)),hon(t.j,Clt,!0)),e=nIn(n,t);do{if($rn(n),0==e)return 0;r=e,DNn(n,t,i=!i,!1),e=nIn(n,t)}while(r>e);return r}function vFn(n,t,e){var i,r,c,a,u,o,s;if(t==e)return!0;if(t=bAn(n,t),e=bAn(n,e),i=qvn(t)){if((o=qvn(e))!=i)return!!o&&(a=i.Dj())==o.Dj()&&null!=a;if(!t.d&&(t.d=new $L(VAt,t,1)),r=(c=t.d).i,!e.d&&(e.d=new $L(VAt,e,1)),r==(s=e.d).i)for(u=0;u<r;++u)if(!vFn(n,BB(Wtn(c,u),87),BB(Wtn(s,u),87)))return!1;return!0}return t.e==e.e}function mFn(n,t,e,i){var r,c,a,u,o,s,h,f;if($xn(n.e,t)){for(f=axn(n.e.Tg(),t),c=BB(n.g,119),h=null,o=-1,u=-1,r=0,s=0;s<n.i;++s)a=c[s],f.rl(a.ak())&&(r==e&&(o=s),r==i&&(u=s,h=a.dd()),++r);if(-1==o)throw Hp(new Ay(u8n+e+o8n+r));if(-1==u)throw Hp(new Ay(s8n+i+o8n+r));return Cln(n,o,u),mA(n.e)&&Lv(n,LY(n,7,t,iln(i),h,e,!0)),h}throw Hp(new Ky("The feature must be many-valued to support move"))}function yFn(n,t,e,i){var r,c,a,u,o;switch((o=new wA(t.n)).a+=t.o.a/2,o.b+=t.o.b/2,u=Gy(MD(mMn(t,(HXn(),tpt)))),c=n.f,a=n.d,r=n.c,BB(mMn(t,(hWn(),Qft)),61).g){case 1:o.a+=a.b+r.a-e/2,o.b=-i-u,t.n.b=-(a.d+u+r.b);break;case 2:o.a=c.a+a.b+a.c+u,o.b+=a.d+r.b-i/2,t.n.a=c.a+a.c+u-r.a;break;case 3:o.a+=a.b+r.a-e/2,o.b=c.b+a.d+a.a+u,t.n.b=c.b+a.a+u-r.b;break;case 4:o.a=-e-u,o.b+=a.d+r.b-i/2,t.n.a=-(a.b+u+r.a)}return o}function kFn(n){var t,e,i,r,c,a;return qan(i=new min,n),GC(mMn(i,(HXn(),Udt)))===GC((Ffn(),BPt))&&hon(i,Udt,Wln(i)),null==mMn(i,(I6(),TMt))&&(a=BB($Mn(n),160),hon(i,TMt,iO(a.We(TMt)))),hon(i,(hWn(),dlt),n),hon(i,Zft,new Y_(t=BB(Vj(Tft),9),BB(SR(t,t.length),9),0)),r=Pzn((JJ(n)&&(GM(),new Dy(JJ(n))),GM(),new JN(JJ(n)?new Dy(JJ(n)):null,n)),FPt),c=BB(mMn(i,zgt),116),eZ(e=i.d,c),eZ(e,r),i}function jFn(n,t,e){var i,r;i=t.c.i,r=e.d.i,i.k==(uSn(),Put)?(hon(n,(hWn(),hlt),BB(mMn(i,hlt),11)),hon(n,flt,BB(mMn(i,flt),11)),hon(n,slt,TD(mMn(i,slt)))):i.k==Sut?(hon(n,(hWn(),hlt),BB(mMn(i,hlt),11)),hon(n,flt,BB(mMn(i,flt),11)),hon(n,slt,(hN(),!0))):r.k==Sut?(hon(n,(hWn(),hlt),BB(mMn(r,hlt),11)),hon(n,flt,BB(mMn(r,flt),11)),hon(n,slt,(hN(),!0))):(hon(n,(hWn(),hlt),t.c),hon(n,flt,e.d))}function EFn(n){var t,e,i,r,c,a,u;for(n.o=new Lp,i=new YT,a=new Wb(n.e.a);a.a<a.c.c.length;)1==kbn(c=BB(n0(a),121)).c.length&&r5(i,c,i.c.b,i.c);for(;0!=i.b;)0!=kbn(c=BB(0==i.b?null:(Px(0!=i.b),Atn(i,i.a.a)),121)).c.length&&(t=BB(xq(kbn(c),0),213),e=c.g.a.c.length>0,u=Nbn(t,c),_N(e?u.b:u.g,t),1==kbn(u).c.length&&r5(i,u,i.c.b,i.c),r=new rC(c,t),d3(n.o,r),y7(n.e.a,c))}function TFn(n,t){var i,r,c,a;return r=e.Math.abs(qz(n.b).a-qz(t.b).a),a=e.Math.abs(qz(n.b).b-qz(t.b).b),i=1,c=1,r>n.b.b/2+t.b.b/2&&(i=1-e.Math.min(e.Math.abs(n.b.c-(t.b.c+t.b.b)),e.Math.abs(n.b.c+n.b.b-t.b.c))/r),a>n.b.a/2+t.b.a/2&&(c=1-e.Math.min(e.Math.abs(n.b.d-(t.b.d+t.b.a)),e.Math.abs(n.b.d+n.b.a-t.b.d))/a),(1-e.Math.min(i,c))*e.Math.sqrt(r*r+a*a)}function MFn(n){var t,e,i;for(nUn(n,n.e,n.f,(dJ(),Lyt),!0,n.c,n.i),nUn(n,n.e,n.f,Lyt,!1,n.c,n.i),nUn(n,n.e,n.f,Nyt,!0,n.c,n.i),nUn(n,n.e,n.f,Nyt,!1,n.c,n.i),CFn(n,n.c,n.e,n.f,n.i),e=new M2(n.i,0);e.b<e.d.gc();)for(Px(e.b<e.d.gc()),t=BB(e.d.Xb(e.c=e.b++),128),i=new M2(n.i,e.b);i.b<i.d.gc();)Px(i.b<i.d.gc()),Nqn(t,BB(i.d.Xb(i.c=i.b++),128));CXn(n.i,BB(mMn(n.d,(hWn(),Slt)),230)),GGn(n.i)}function SFn(n,t){var e,i;if(null!=t)if(i=iyn(n)){if(0==(1&i.i))return nS(),!(e=BB(RX(mAt,i),55))||e.wj(t);if(i==$Nt)return zC(t);if(i==ANt)return cL(t,19);if(i==DNt)return cL(t,155);if(i==NNt)return cL(t,217);if(i==ONt)return cL(t,172);if(i==xNt)return UC(t);if(i==RNt)return cL(t,184);if(i==LNt)return cL(t,162)}else if(cL(t,56))return n.uk(BB(t,56));return!1}function PFn(){var n,t,e,i,r,c,a,u,o;for(PFn=O,WLt=x8(NNt,v6n,25,255,15,1),VLt=x8(ONt,WVn,25,64,15,1),t=0;t<255;t++)WLt[t]=-1;for(e=90;e>=65;e--)WLt[e]=e-65<<24>>24;for(i=122;i>=97;i--)WLt[i]=i-97+26<<24>>24;for(r=57;r>=48;r--)WLt[r]=r-48+52<<24>>24;for(WLt[43]=62,WLt[47]=63,c=0;c<=25;c++)VLt[c]=65+c&QVn;for(a=26,o=0;a<=51;++a,o++)VLt[a]=97+o&QVn;for(n=52,u=0;n<=61;++n,u++)VLt[n]=48+u&QVn;VLt[62]=43,VLt[63]=47}function IFn(n,t){var i,r,c,a,u,o,s,h,f,l,b;if(n.dc())return new Gj;for(s=0,f=0,r=n.Kc();r.Ob();)c=BB(r.Pb(),37).f,s=e.Math.max(s,c.a),f+=c.a*c.b;for(s=e.Math.max(s,e.Math.sqrt(f)*Gy(MD(mMn(BB(n.Kc().Pb(),37),(HXn(),Edt))))),l=0,b=0,o=0,i=t,u=n.Kc();u.Ob();)l+(h=(a=BB(u.Pb(),37)).f).a>s&&(l=0,b+=o+t,o=0),ZRn(a,l,b),i=e.Math.max(i,l+h.a),o=e.Math.max(o,h.b),l+=h.a+t;return new xI(i+t,b+o+t)}function CFn(n,t,e,i,r){var c,a,u,o,s,h,f;for(a=new Wb(t);a.a<a.c.c.length;){if(o=(c=BB(n0(a),17)).c,e.a._b(o))dJ(),s=Lyt;else{if(!i.a._b(o))throw Hp(new Ky("Source port must be in one of the port sets."));dJ(),s=Nyt}if(h=c.d,e.a._b(h))dJ(),f=Lyt;else{if(!i.a._b(h))throw Hp(new Ky("Target port must be in one of the port sets."));dJ(),f=Nyt}u=new tIn(c,s,f),VW(n.b,c,u),r.c[r.c.length]=u}}function OFn(n,t){var e,i,r,c,a,u,o;if(!WJ(n))throw Hp(new Fy(F5n));if(c=(i=WJ(n)).g,r=i.f,c<=0&&r<=0)return kUn(),PCt;switch(u=n.i,o=n.j,t.g){case 2:case 1:if(u<0)return kUn(),ICt;if(u+n.g>c)return kUn(),oCt;break;case 4:case 3:if(o<0)return kUn(),sCt;if(o+n.f>r)return kUn(),SCt}return(a=(u+n.g/2)/c)+(e=(o+n.f/2)/r)<=1&&a-e<=0?(kUn(),ICt):a+e>=1&&a-e>=0?(kUn(),oCt):e<.5?(kUn(),sCt):(kUn(),SCt)}function AFn(n,t,e,i,r){var c,a;if(c=rbn(e0(t[0],UQn),e0(i[0],UQn)),n[0]=dG(c),c=kz(c,32),e>=r){for(a=1;a<r;a++)c=rbn(c,rbn(e0(t[a],UQn),e0(i[a],UQn))),n[a]=dG(c),c=kz(c,32);for(;a<e;a++)c=rbn(c,e0(t[a],UQn)),n[a]=dG(c),c=kz(c,32)}else{for(a=1;a<e;a++)c=rbn(c,rbn(e0(t[a],UQn),e0(i[a],UQn))),n[a]=dG(c),c=kz(c,32);for(;a<r;a++)c=rbn(c,e0(i[a],UQn)),n[a]=dG(c),c=kz(c,32)}0!=Vhn(c,0)&&(n[a]=dG(c))}function $Fn(n){var t,e,i,r,c,a;if(wWn(),4!=n.e&&5!=n.e)throw Hp(new Ky("Token#complementRanges(): must be RANGE: "+n.e));for(T$n(c=n),qHn(c),i=c.b.length+2,0==c.b[0]&&(i-=2),(e=c.b[c.b.length-1])==unt&&(i-=2),(r=new M0(4)).b=x8(ANt,hQn,25,i,15,1),a=0,c.b[0]>0&&(r.b[a++]=0,r.b[a++]=c.b[0]-1),t=1;t<c.b.length-2;t+=2)r.b[a++]=c.b[t]+1,r.b[a++]=c.b[t+1]-1;return e!=unt&&(r.b[a++]=e+1,r.b[a]=unt),r.a=!0,r}function LFn(n,t,e){var i,r,c,a,u,o,s,h;if(0==(i=e.gc()))return!1;if(n.ej())if(s=n.fj(),BTn(n,t,e),a=1==i?n.Zi(3,null,e.Kc().Pb(),t,s):n.Zi(5,null,e,t,s),n.bj()){for(u=i<100?null:new Fj(i),c=t+i,r=t;r<c;++r)h=n.g[r],u=n.cj(h,u),u=n.jj(h,u);u?(u.Ei(a),u.Fi()):n.$i(a)}else n.$i(a);else if(BTn(n,t,e),n.bj()){for(u=i<100?null:new Fj(i),c=t+i,r=t;r<c;++r)o=n.g[r],u=n.cj(o,u);u&&u.Fi()}return!0}function NFn(n,t,e,i){var r,c,a,u,o;for(a=new Wb(n.k);a.a<a.c.c.length;)r=BB(n0(a),129),i&&r.c!=(O6(),Tyt)||(o=r.b).g<0&&r.d>0&&(Vl(o,o.d-r.d),r.c==(O6(),Tyt)&&Xl(o,o.a-r.d),o.d<=0&&o.i>0&&r5(t,o,t.c.b,t.c));for(c=new Wb(n.f);c.a<c.c.c.length;)r=BB(n0(c),129),i&&r.c!=(O6(),Tyt)||(u=r.a).g<0&&r.d>0&&(Ql(u,u.i-r.d),r.c==(O6(),Tyt)&&Wl(u,u.b-r.d),u.i<=0&&u.d>0&&r5(e,u,e.c.b,e.c))}function xFn(n,t,e){var i,r,c,a,u,o,s,h;for(OTn(e,"Processor compute fanout",1),$U(n.b),$U(n.a),u=null,c=spn(t.b,0);!u&&c.b!=c.d.c;)qy(TD(mMn(s=BB(b3(c),86),(qqn(),dkt))))&&(u=s);for(r5(o=new YT,u,o.c.b,o.c),jUn(n,o),h=spn(t.b,0);h.b!=h.d.c;)a=SD(mMn(s=BB(b3(h),86),(qqn(),rkt))),r=null!=SJ(n.b,a)?BB(SJ(n.b,a),19).a:0,hon(s,ikt,iln(r)),i=1+(null!=SJ(n.a,a)?BB(SJ(n.a,a),19).a:0),hon(s,tkt,iln(i));HSn(e)}function DFn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(f=yEn(n,e),u=0;u<t;u++){for(yR(r,e),l=new Np,Px(i.b<i.d.gc()),b=BB(i.d.Xb(i.c=i.b++),407),s=f+u;s<n.b;s++)a=b,Px(i.b<i.d.gc()),WB(l,new Exn(a,b=BB(i.d.Xb(i.c=i.b++),407),e));for(h=f+u;h<n.b;h++)Px(i.b>0),i.a.Xb(i.c=--i.b),h>f+u&&fW(i);for(c=new Wb(l);c.a<c.c.c.length;)yR(i,BB(n0(c),407));if(u<t-1)for(o=f+u;o<n.b;o++)Px(i.b>0),i.a.Xb(i.c=--i.b)}}function RFn(){var n,t,e,i,r,c;if(wWn(),INt)return INt;for(sHn(n=new M0(4),ZUn(pnt,!0)),WGn(n,ZUn("M",!0)),WGn(n,ZUn("C",!0)),c=new M0(4),i=0;i<11;i++)Yxn(c,i,i);return sHn(t=new M0(4),ZUn("M",!0)),Yxn(t,4448,4607),Yxn(t,65438,65439),tqn(r=new r$(2),n),tqn(r,sNt),(e=new r$(2)).$l(gG(c,ZUn("L",!0))),e.$l(t),e=new h4(3,e),e=new UU(r,e),INt=e}function _Fn(n){var t,e;if(!Ycn(t=SD(ZAn(n,(sWn(),eSt))),n)&&!P8(n,mPt)&&(0!=(!n.a&&(n.a=new eU(UOt,n,10,11)),n.a).i||qy(TD(ZAn(n,SSt))))){if(null!=t&&0!=RMn(t).length)throw gzn(n,e=oO(oO(new lN("Layout algorithm '"),t),"' not found for ")),Hp(new rk(e.a));if(!Ycn(w1n,n))throw gzn(n,e=oO(oO(new lN("Unable to load default layout algorithm "),w1n)," for unconfigured node ")),Hp(new rk(e.a))}}function KFn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w;if(i=n.i,t=n.n,0==n.b)for(w=i.c+t.b,b=i.b-t.b-t.c,s=0,f=(u=n.a).length;s<f;++s)UG(c=u[s],w,b);else r=Wvn(n,!1),UG(n.a[0],i.c+t.b,r[0]),UG(n.a[2],i.c+i.b-t.c-r[2],r[2]),l=i.b-t.b-t.c,r[0]>0&&(l-=r[0]+n.c,r[0]+=n.c),r[2]>0&&(l-=r[2]+n.c),r[1]=e.Math.max(r[1],l),UG(n.a[1],i.c+t.b+r[0]-(r[1]-l)/2,r[1]);for(o=0,h=(a=n.a).length;o<h;++o)cL(c=a[o],326)&&BB(c,326).Te()}function FFn(n){var t,e,i,r,c,a,u,o,s,h,f;for((f=new aa).d=0,a=new Wb(n.b);a.a<a.c.c.length;)c=BB(n0(a),29),f.d+=c.a.c.length;for(i=0,r=0,f.a=x8(ANt,hQn,25,n.b.c.length,15,1),s=0,h=0,f.e=x8(ANt,hQn,25,f.d,15,1),e=new Wb(n.b);e.a<e.c.c.length;)for((t=BB(n0(e),29)).p=i++,f.a[t.p]=r++,h=0,o=new Wb(t.a);o.a<o.c.c.length;)(u=BB(n0(o),10)).p=s++,f.e[u.p]=h++;return f.c=new fg(f),f.b=sx(f.d),HKn(f,n),f.f=sx(f.d),qKn(f,n),f}function BFn(n,t){var i,r,c;for(c=BB(xq(n.n,n.n.c.length-1),211).d,n.p=e.Math.min(n.p,t.g),n.r=e.Math.max(n.r,c),n.g=e.Math.max(n.g,t.g+(1==n.b.c.length?0:n.i)),n.o=e.Math.min(n.o,t.f),n.e+=t.f+(1==n.b.c.length?0:n.i),n.f=e.Math.max(n.f,t.f),r=n.n.c.length>0?(n.n.c.length-1)*n.i:0,i=new Wb(n.n);i.a<i.c.c.length;)r+=BB(n0(i),211).a;n.d=r,n.a=n.e/n.b.c.length-n.i*((n.b.c.length-1)/n.b.c.length),yyn(n.j)}function HFn(n,t){var e,i,r,c,a,u,o,s,h;if(null==(s=TD(mMn(t,(fRn(),iat))))||(kW(s),s)){for(h=x8($Nt,ZYn,25,t.e.c.length,16,1),a=kOn(t),r=new YT,o=new Wb(t.e);o.a<o.c.c.length;)(e=Y$n(n,BB(n0(o),144),null,null,h,a))&&(qan(e,t),r5(r,e,r.c.b,r.c));if(r.b>1)for(i=spn(r,0);i.b!=i.d.c;)for(c=0,u=new Wb((e=BB(b3(i),231)).e);u.a<u.c.c.length;)BB(n0(u),144).b=c++;return r}return u6(Pun(Gk(_ct,1),tZn,231,0,[t]))}function qFn(n){var t,e,i,r,c;if(!n.g){if(c=new To,null==(t=P$t).a.zc(n,t)){for(e=new AL(kY(n));e.e!=e.i.gc();)pX(c,qFn(BB(kpn(e),26)));t.a.Bc(n),t.a.gc()}for(i=c.i,!n.s&&(n.s=new eU(FAt,n,21,17)),r=new AL(n.s);r.e!=r.i.gc();++i)ub(BB(kpn(r),449),i);pX(c,(!n.s&&(n.s=new eU(FAt,n,21,17)),n.s)),chn(c),n.g=new don(n,c),n.i=BB(c.g,247),null==n.i&&(n.i=C$t),n.p=null,P5(n).b&=-5}return n.g}function GFn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w;if(r=n.i,i=n.n,0==n.b)t=Xvn(n,!1),XG(n.a[0],r.d+i.d,t[0]),XG(n.a[2],r.d+r.a-i.a-t[2],t[2]),l=r.a-i.d-i.a,t[0]>0&&(t[0]+=n.c,l-=t[0]),t[2]>0&&(l-=t[2]+n.c),t[1]=e.Math.max(t[1],l),XG(n.a[1],r.d+i.d+t[0]-(t[1]-l)/2,t[1]);else for(w=r.d+i.d,b=r.a-i.d-i.a,s=0,f=(u=n.a).length;s<f;++s)XG(c=u[s],w,b);for(o=0,h=(a=n.a).length;o<h;++o)cL(c=a[o],326)&&BB(c,326).Ue()}function zFn(n){var t,e,i,r,c,a,u,o,s;for(s=x8(ANt,hQn,25,n.b.c.length+1,15,1),o=new Rv,i=0,c=new Wb(n.b);c.a<c.c.c.length;){for(r=BB(n0(c),29),s[i++]=o.a.gc(),u=new Wb(r.a);u.a<u.c.c.length;)for(e=new oz(ZL(lbn(BB(n0(u),10)).a.Kc(),new h));dAn(e);)t=BB(U5(e),17),o.a.zc(t,o);for(a=new Wb(r.a);a.a<a.c.c.length;)for(e=new oz(ZL(fbn(BB(n0(a),10)).a.Kc(),new h));dAn(e);)t=BB(U5(e),17),o.a.Bc(t)}return s}function UFn(n,t,e,i){var r,c,a,u,o;if(o=axn(n.e.Tg(),t),r=BB(n.g,119),ZM(),BB(t,66).Oj()){for(a=0;a<n.i;++a)if(c=r[a],o.rl(c.ak())&&Nfn(c,e))return!0}else if(null!=e){for(u=0;u<n.i;++u)if(c=r[u],o.rl(c.ak())&&Nfn(e,c.dd()))return!0;if(i)for(a=0;a<n.i;++a)if(c=r[a],o.rl(c.ak())&&GC(e)===GC(hD(n,BB(c.dd(),56))))return!0}else for(a=0;a<n.i;++a)if(c=r[a],o.rl(c.ak())&&null==c.dd())return!1;return!1}function XFn(n,t,e,i){var r,c,a,u,o,s;if(s=axn(n.e.Tg(),t),a=BB(n.g,119),$xn(n.e,t)){if(t.hi()&&(c=pBn(n,t,i,cL(t,99)&&0!=(BB(t,18).Bb&BQn)))>=0&&c!=e)throw Hp(new Ky(a8n));for(r=0,o=0;o<n.i;++o)if(u=a[o],s.rl(u.ak())){if(r==e)return BB(ovn(n,o,(ZM(),BB(t,66).Oj()?BB(i,72):Z3(t,i))),72);++r}throw Hp(new Ay(e9n+e+o8n+r))}for(o=0;o<n.i;++o)if(u=a[o],s.rl(u.ak()))return ZM(),BB(t,66).Oj()?u:u.dd();return null}function WFn(n,t,i,r){var c,a,u,o;for(o=i,u=new Wb(t.a);u.a<u.c.c.length;){if(a=BB(n0(u),221),c=BB(a.b,65),Cbn(n.b.c,c.b.c+c.b.b)<=0&&Cbn(c.b.c,n.b.c+n.b.b)<=0&&Cbn(n.b.d,c.b.d+c.b.a)<=0&&Cbn(c.b.d,n.b.d+n.b.a)<=0){if(0==Cbn(c.b.c,n.b.c+n.b.b)&&r.a<0||0==Cbn(c.b.c+c.b.b,n.b.c)&&r.a>0||0==Cbn(c.b.d,n.b.d+n.b.a)&&r.b<0||0==Cbn(c.b.d+c.b.a,n.b.d)&&r.b>0){o=0;break}}else o=e.Math.min(o,HIn(n,c,r));o=e.Math.min(o,WFn(n,a,o,r))}return o}function VFn(n,t){var e,i,r,c,a,u;if(n.b<2)throw Hp(new Ky("The vector chain must contain at least a source and a target point."));for(Px(0!=n.b),IA(t,(i=BB(n.a.a.c,8)).a,i.b),u=new cx((!t.a&&(t.a=new $L(xOt,t,5)),t.a)),c=spn(n,1);c.a<n.b-1;)a=BB(b3(c),8),u.e!=u.i.gc()?e=BB(kpn(u),469):(tE(),odn(u,e=new ro)),TA(e,a.a,a.b);for(;u.e!=u.i.gc();)kpn(u),Qjn(u);Px(0!=n.b),PA(t,(r=BB(n.c.b.c,8)).a,r.b)}function QFn(n,t){var e,i,r,c,a,u,o,s;for(e=0,i=new Wb((l1(0,n.c.length),BB(n.c[0],101)).g.b.j);i.a<i.c.c.length;)BB(n0(i),11).p=e++;for(t==(kUn(),sCt)?m$(n,new nc):m$(n,new tc),a=0,s=n.c.length-1;a<s;)l1(a,n.c.length),c=BB(n.c[a],101),l1(s,n.c.length),o=BB(n.c[s],101),r=t==sCt?c.c:c.a,u=t==sCt?o.a:o.c,bU(c,t,(Oun(),yst),r),bU(o,t,mst,u),++a,--s;a==s&&bU((l1(a,n.c.length),BB(n.c[a],101)),t,(Oun(),vst),null)}function YFn(n,t,e){var i,r,c,a,u,o,s,h,f,l;return h=n.a.i+n.a.g/2,f=n.a.i+n.a.g/2,a=new xI(t.i+t.g/2,t.j+t.f/2),(o=BB(ZAn(t,(sWn(),gPt)),8)).a=o.a+h,o.b=o.b+f,r=(a.b-o.b)/(a.a-o.a),i=a.b-r*a.a,u=new xI(e.i+e.g/2,e.j+e.f/2),(s=BB(ZAn(e,gPt),8)).a=s.a+h,s.b=s.b+f,c=(u.b-s.b)/(u.a-s.a),l=(i-(u.b-c*u.a))/(c-r),!(o.a<l&&a.a<l||l<o.a&&l<a.a||s.a<l&&u.a<l||l<s.a&&l<u.a)}function JFn(n,t){var e,i,r,c,a,u;if(!(a=BB(RX(n.c,t),183)))throw Hp(new ek("Edge did not exist in input."));return i=Qdn(a),!WE((!t.a&&(t.a=new eU(FOt,t,6,6)),t.a))&&(e=new MB(n,i,u=new Il),wO((!t.a&&(t.a=new eU(FOt,t,6,6)),t.a),e),rtn(a,x6n,u)),P8(t,(sWn(),OSt))&&!(!(r=BB(ZAn(t,OSt),74))||pW(r))&&(e5(r,new Qg(c=new Il)),rtn(a,"junctionPoints",c)),AH(a,"container",XJ(t).k),null}function ZFn(n,t,e){var i,r,c,a,u,o;this.a=n,this.b=t,this.c=e,this.e=u6(Pun(Gk(uit,1),HWn,168,0,[new xS(n,t),new xS(t,e),new xS(e,n)])),this.f=u6(Pun(Gk(PMt,1),sVn,8,0,[n,t,e])),this.d=(i=XR(B$(this.b),this.a),r=XR(B$(this.c),this.a),c=XR(B$(this.c),this.b),a=i.a*(this.a.a+this.b.a)+i.b*(this.a.b+this.b.b),u=r.a*(this.a.a+this.c.a)+r.b*(this.a.b+this.c.b),o=2*(i.a*c.b-i.b*c.a),new xI((r.b*a-i.b*u)/o,(i.a*u-r.a*a)/o))}function nBn(n,t,e,i){var r,c,a,u,o,s,h,f,l;if(f=new GX(n.p),rtn(t,t8n,f),e&&!(n.f?rY(n.f):null).a.dc())for(rtn(t,"logs",s=new Il),u=0,l=new qb((n.f?rY(n.f):null).b.Kc());l.b.Ob();)h=new GX(SD(l.b.Pb())),dnn(s,u),r4(s,u,h),++u;if(i&&rtn(t,"executionTime",new Sl(n.q)),!rY(n.a).a.dc())for(a=new Il,rtn(t,A6n,a),u=0,c=new qb(rY(n.a).b.Kc());c.b.Ob();)r=BB(c.b.Pb(),1949),o=new py,dnn(a,u),r4(a,u,o),nBn(r,o,e,i),++u}function tBn(n,t){var e,i,r,c,a,u;for(c=n.c,a=n.d,SZ(n,null),MZ(n,null),t&&qy(TD(mMn(a,(hWn(),tlt))))?SZ(n,RKn(a.i,(ain(),qvt),(kUn(),oCt))):SZ(n,a),t&&qy(TD(mMn(c,(hWn(),klt))))?MZ(n,RKn(c.i,(ain(),Hvt),(kUn(),ICt))):MZ(n,c),i=new Wb(n.b);i.a<i.c.c.length;)e=BB(n0(i),70),(r=BB(mMn(e,(HXn(),Ydt)),272))==(Rtn(),XPt)?hon(e,Ydt,UPt):r==UPt&&hon(e,Ydt,XPt);u=qy(TD(mMn(n,(hWn(),Ilt)))),hon(n,Ilt,(hN(),!u)),n.a=Jon(n.a)}function eBn(n,t,i){var r,c,a,u,o;for(r=0,a=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));a.e!=a.i.gc();)u="",0==(!(c=BB(kpn(a),33)).n&&(c.n=new eU(zOt,c,1,7)),c.n).i||(u=BB(Wtn((!c.n&&(c.n=new eU(zOt,c,1,7)),c.n),0),137).a),qan(o=new qX(u),c),hon(o,(Mrn(),sat),c),o.b=r++,o.d.a=c.i+c.g/2,o.d.b=c.j+c.f/2,o.e.a=e.Math.max(c.g,1),o.e.b=e.Math.max(c.f,1),WB(t.e,o),jIn(i.f,c,o),BB(ZAn(c,(fRn(),Yct)),98),QEn()}function iBn(n,t){var i,r,c,a,u,o,s,h,f,l,b;i=AN(new qv,n.f),o=n.i[t.c.i.p],l=n.i[t.d.i.p],u=t.c,f=t.d,a=u.a.b,h=f.a.b,o.b||(a+=u.n.b),l.b||(h+=f.n.b),s=IJ(e.Math.max(0,a-h)),c=IJ(e.Math.max(0,h-a)),b=e.Math.max(1,BB(mMn(t,(HXn(),bpt)),19).a)*X3(t.c.i.k,t.d.i.k),r=new nI(UNn(aM(cM(rM(uM(new Hv,b),c),i),BB(RX(n.k,t.c),121))),UNn(aM(cM(rM(uM(new Hv,b),s),i),BB(RX(n.k,t.d),121)))),n.c[t.p]=r}function rBn(n,t,e,i){var r,c,a,u,o,s;for(a=new uGn(n,t,e),o=new M2(i,0),r=!1;o.b<o.d.gc();)Px(o.b<o.d.gc()),(u=BB(o.d.Xb(o.c=o.b++),233))==t||u==e?fW(o):!r&&Gy(lL(u.g,u.d[0]).a)>Gy(lL(a.g,a.d[0]).a)?(Px(o.b>0),o.a.Xb(o.c=--o.b),yR(o,a),r=!0):u.e&&u.e.gc()>0&&(c=(!u.e&&(u.e=new Np),u.e).Mc(t),s=(!u.e&&(u.e=new Np),u.e).Mc(e),(c||s)&&((!u.e&&(u.e=new Np),u.e).Fc(a),++a.c));r||(i.c[i.c.length]=a)}function cBn(n){var t,e,i;if(vA(BB(mMn(n,(HXn(),ept)),98)))for(e=new Wb(n.j);e.a<e.c.c.length;)(t=BB(n0(e),11)).j==(kUn(),PCt)&&((i=BB(mMn(t,(hWn(),Elt)),10))?qIn(t,BB(mMn(i,Qft),61)):t.e.c.length-t.g.c.length<0?qIn(t,oCt):qIn(t,ICt));else{for(e=new Wb(n.j);e.a<e.c.c.length;)t=BB(n0(e),11),(i=BB(mMn(t,(hWn(),Elt)),10))?qIn(t,BB(mMn(i,Qft),61)):t.e.c.length-t.g.c.length<0?qIn(t,(kUn(),oCt)):qIn(t,(kUn(),ICt));hon(n,ept,(QEn(),VIt))}}function aBn(n){var t,e;switch(n){case 91:case 93:case 45:case 94:case 44:case 92:e="\\"+String.fromCharCode(n&QVn);break;case 12:e="\\f";break;case 10:e="\\n";break;case 13:e="\\r";break;case 9:e="\\t";break;case 27:e="\\e";break;default:e=n<32?"\\x"+fx(t="0"+(n>>>0).toString(16),t.length-2,t.length):n>=BQn?"\\v"+fx(t="0"+(n>>>0).toString(16),t.length-6,t.length):""+String.fromCharCode(n&QVn)}return e}function uBn(n,t){var e,i,r,c,a,u,o,s,h,f;if(a=n.e,0==(o=t.e))return n;if(0==a)return 0==t.e?t:new lU(-t.e,t.d,t.a);if((c=n.d)+(u=t.d)==2)return e=e0(n.a[0],UQn),i=e0(t.a[0],UQn),a<0&&(e=j7(e)),o<0&&(i=j7(i)),npn(ibn(e,i));if(-1==(r=c!=u?c>u?1:-1:Msn(n.a,t.a,c)))f=-o,h=a==o?d6(t.a,u,n.a,c):N8(t.a,u,n.a,c);else if(f=a,a==o){if(0==r)return ODn(),eet;h=d6(n.a,c,t.a,u)}else h=N8(n.a,c,t.a,u);return X0(s=new lU(f,h.length,h)),s}function oBn(n){var t,e,i,r,c,a;for(this.e=new Np,this.a=new Np,e=n.b-1;e<3;e++)_x(n,0,BB(Dpn(n,0),8));if(n.b<4)throw Hp(new Ky("At (least dimension + 1) control points are necessary!"));for(this.b=3,this.d=!0,this.c=!1,C$n(this,n.b+this.b-1),a=new Np,c=new Wb(this.e),t=0;t<this.b-1;t++)WB(a,MD(n0(c)));for(r=spn(n,0);r.b!=r.d.c;)i=BB(b3(r),8),WB(a,MD(n0(c))),WB(this.a,new wJ(i,a)),l1(0,a.c.length),a.c.splice(0,1)}function sBn(n,t){var e,i,r,c,a,u,o;for(r=new Wb(n.b);r.a<r.c.c.length;)for(a=new Wb(BB(n0(r),29).a);a.a<a.c.c.length;)for((c=BB(n0(a),10)).k==(uSn(),Sut)&&(u=BB(U5(new oz(ZL(fbn(c).a.Kc(),new h))),17),o=BB(U5(new oz(ZL(lbn(c).a.Kc(),new h))),17),hFn(c,qy(TD(mMn(u,(hWn(),Ilt))))&&qy(TD(mMn(o,Ilt)))?Xun(t):t)),i=new oz(ZL(lbn(c).a.Kc(),new h));dAn(i);)vun(e=BB(U5(i),17),qy(TD(mMn(e,(hWn(),Ilt))))?Xun(t):t)}function hBn(n,t,e,i,r){var c,a;if(e.f>=t.o&&e.f<=t.f||.5*t.a<=e.f&&1.5*t.a>=e.f){if((c=BB(xq(t.n,t.n.c.length-1),211)).e+c.d+e.g+r<=i&&(BB(xq(t.n,t.n.c.length-1),211).f-n.f+e.f<=n.b||1==n.a.c.length))return ybn(t,e),!0;if(t.s+e.g<=i&&(t.t+t.d+e.f+r<=n.b||1==n.a.c.length))return WB(t.b,e),a=BB(xq(t.n,t.n.c.length-1),211),WB(t.n,new RJ(t.s,a.f+a.a+t.i,t.i)),smn(BB(xq(t.n,t.n.c.length-1),211),e),BFn(t,e),!0}return!1}function fBn(n,t,e){var i,r,c,a;return n.ej()?(r=null,c=n.fj(),i=n.Zi(1,a=onn(n,t,e),e,t,c),n.bj()&&!(n.ni()&&null!=a?Nfn(a,e):GC(a)===GC(e))?(null!=a&&(r=n.dj(a,r)),r=n.cj(e,r),n.ij()&&(r=n.lj(a,e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)):(n.ij()&&(r=n.lj(a,e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)),a):(a=onn(n,t,e),n.bj()&&!(n.ni()&&null!=a?Nfn(a,e):GC(a)===GC(e))&&(r=null,null!=a&&(r=n.dj(a,null)),(r=n.cj(e,r))&&r.Fi()),a)}function lBn(n,t){var i,r,c,a,u,o,s;t%=24,n.q.getHours()!=t&&((i=new e.Date(n.q.getTime())).setDate(i.getDate()+1),(u=n.q.getTimezoneOffset()-i.getTimezoneOffset())>0&&(o=u/60|0,s=u%60,r=n.q.getDate(),n.q.getHours()+o>=24&&++r,c=new e.Date(n.q.getFullYear(),n.q.getMonth(),r,t+o,n.q.getMinutes()+s,n.q.getSeconds(),n.q.getMilliseconds()),n.q.setTime(c.getTime()))),a=n.q.getTime(),n.q.setTime(a+36e5),n.q.getHours()!=t&&n.q.setTime(a)}function bBn(n,t){var e,i,r,c;if(OTn(t,"Path-Like Graph Wrapping",1),0!=n.b.c.length)if(null==(r=new MAn(n)).i&&(r.i=Wrn(r,new kc)),e=Gy(r.i)*r.f/(null==r.i&&(r.i=Wrn(r,new kc)),Gy(r.i)),r.b>e)HSn(t);else{switch(BB(mMn(n,(HXn(),Bpt)),337).g){case 2:c=new Tc;break;case 0:c=new wc;break;default:c=new Mc}if(i=c.Vf(n,r),!c.Wf())switch(BB(mMn(n,Xpt),338).g){case 2:i=XIn(r,i);break;case 1:i=_Tn(r,i)}iqn(n,r,i),HSn(t)}else HSn(t)}function wBn(n,t){var e,i,r,c;if(f1(n.d,n.e),n.c.a.$b(),0!=Gy(MD(mMn(t.j,(HXn(),Cdt))))||0!=Gy(MD(mMn(t.j,Cdt))))for(e=ZJn,GC(mMn(t.j,Ldt))!==GC((mon(),Nvt))&&hon(t.j,(hWn(),Jft),(hN(),!0)),c=BB(mMn(t.j,xpt),19).a,r=0;r<c&&!((i=gFn(n,t))<e&&(e=i,Lrn(n),0==e));r++);else for(e=DWn,GC(mMn(t.j,Ldt))!==GC((mon(),Nvt))&&hon(t.j,(hWn(),Jft),(hN(),!0)),c=BB(mMn(t.j,xpt),19).a,r=0;r<c&&!((i=pFn(n,t))<e&&(e=i,Lrn(n),0==e));r++);}function dBn(n,t){var e,i,r,c,a,u;for(r=new Np,c=0,e=0,a=0;c<t.c.length-1&&e<n.gc();){for(i=BB(n.Xb(e),19).a+a;(l1(c+1,t.c.length),BB(t.c[c+1],19)).a<i;)++c;for(u=0,i-(l1(c,t.c.length),BB(t.c[c],19)).a>(l1(c+1,t.c.length),BB(t.c[c+1],19)).a-i&&++u,WB(r,(l1(c+u,t.c.length),BB(t.c[c+u],19))),a+=(l1(c+u,t.c.length),BB(t.c[c+u],19)).a-i,++e;e<n.gc()&&BB(n.Xb(e),19).a+a<=(l1(c+u,t.c.length),BB(t.c[c+u],19)).a;)++e;c+=1+u}return r}function gBn(n){var t,e,i,r,c;if(!n.d){if(c=new Po,null==(t=P$t).a.zc(n,t)){for(e=new AL(kY(n));e.e!=e.i.gc();)pX(c,gBn(BB(kpn(e),26)));t.a.Bc(n),t.a.gc()}for(r=c.i,!n.q&&(n.q=new eU(QAt,n,11,10)),i=new AL(n.q);i.e!=i.i.gc();++r)BB(kpn(i),399);pX(c,(!n.q&&(n.q=new eU(QAt,n,11,10)),n.q)),chn(c),n.d=new NO((BB(Wtn(QQ((QX(),t$t).o),9),18),c.i),c.g),n.e=BB(c.g,673),null==n.e&&(n.e=I$t),P5(n).b&=-17}return n.d}function pBn(n,t,e,i){var r,c,a,u,o,s;if(s=axn(n.e.Tg(),t),o=0,r=BB(n.g,119),ZM(),BB(t,66).Oj()){for(a=0;a<n.i;++a)if(c=r[a],s.rl(c.ak())){if(Nfn(c,e))return o;++o}}else if(null!=e){for(u=0;u<n.i;++u)if(c=r[u],s.rl(c.ak())){if(Nfn(e,c.dd()))return o;++o}if(i)for(o=0,a=0;a<n.i;++a)if(c=r[a],s.rl(c.ak())){if(GC(e)===GC(hD(n,BB(c.dd(),56))))return o;++o}}else for(a=0;a<n.i;++a)if(c=r[a],s.rl(c.ak())){if(null==c.dd())return o;++o}return-1}function vBn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(SQ(),m$(n,new zu),a=zB(n),b=new Np,l=new Np,u=null,o=0;0!=a.b;)c=BB(0==a.b?null:(Px(0!=a.b),Atn(a,a.a.a)),157),!u||iG(u)*eG(u)/2<iG(c)*eG(c)?(u=c,b.c[b.c.length]=c):(o+=iG(c)*eG(c),l.c[l.c.length]=c,l.c.length>1&&(o>iG(u)*eG(u)/2||0==a.b)&&(f=new Gtn(l),h=iG(u)/eG(u),s=yXn(f,t,new bm,e,i,r,h),UR(kO(f.e),s),u=f,b.c[b.c.length]=f,o=0,l.c=x8(Ant,HWn,1,0,5,1)));return gun(b,l),b}function mBn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(e.mh(t)&&(h=(b=t)?BB(i,49).xh(b):null))if(d=e.bh(t,n.a),(w=t.t)>1||-1==w)if(f=BB(d,69),l=BB(h,69),f.dc())l.$b();else for(a=!!Ivn(t),c=0,u=n.a?f.Kc():f.Zh();u.Ob();)s=BB(u.Pb(),56),(r=BB(lnn(n,s),56))?(a?-1==(o=l.Xc(r))?l.Xh(c,r):c!=o&&l.ji(c,r):l.Xh(c,r),++c):n.b&&!a&&(l.Xh(c,s),++c);else null==d?h.Wb(null):null==(r=lnn(n,d))?n.b&&!Ivn(t)&&h.Wb(d):h.Wb(r)}function yBn(n,t){var i,r,c,a,u,o,s,f;for(i=new Le,c=new oz(ZL(fbn(t).a.Kc(),new h));dAn(c);)if(!b5(r=BB(U5(c),17))&&eTn(o=r.c.i,Xut)){if(-1==(f=VDn(n,o,Xut,Uut)))continue;i.b=e.Math.max(i.b,f),!i.a&&(i.a=new Np),WB(i.a,o)}for(u=new oz(ZL(lbn(t).a.Kc(),new h));dAn(u);)if(!b5(a=BB(U5(u),17))&&eTn(s=a.d.i,Uut)){if(-1==(f=VDn(n,s,Uut,Xut)))continue;i.d=e.Math.max(i.d,f),!i.c&&(i.c=new Np),WB(i.c,s)}return i}function kBn(n){var t,e,i,r;if($On(),t=IJ(n),n<uet.length)return uet[t];if(n<=50)return uOn((ODn(),net),t);if(n<=VVn)return G5(uOn(aet[1],t),t);if(n>1e6)throw Hp(new Oy("power of ten too big"));if(n<=DWn)return G5(uOn(aet[1],t),t);for(r=i=uOn(aet[1],DWn),e=fan(n-DWn),t=IJ(n%DWn);Vhn(e,DWn)>0;)r=Nnn(r,i),e=ibn(e,DWn);for(r=G5(r=Nnn(r,uOn(aet[1],t)),DWn),e=fan(n-DWn);Vhn(e,DWn)>0;)r=G5(r,DWn),e=ibn(e,DWn);return r=G5(r,t)}function jBn(n,t){var e,i,r,c,a,u,o,s;for(OTn(t,"Hierarchical port dummy size processing",1),u=new Np,s=new Np,e=2*Gy(MD(mMn(n,(HXn(),kpt)))),r=new Wb(n.b);r.a<r.c.c.length;){for(i=BB(n0(r),29),u.c=x8(Ant,HWn,1,0,5,1),s.c=x8(Ant,HWn,1,0,5,1),a=new Wb(i.a);a.a<a.c.c.length;)(c=BB(n0(a),10)).k==(uSn(),Mut)&&((o=BB(mMn(c,(hWn(),Qft)),61))==(kUn(),sCt)?u.c[u.c.length]=c:o==SCt&&(s.c[s.c.length]=c));HOn(u,!0,e),HOn(s,!1,e)}HSn(t)}function EBn(n,t){var e,i,r,c,a;OTn(t,"Layer constraint postprocessing",1),0!=(a=n.b).c.length&&(l1(0,a.c.length),K_n(n,BB(a.c[0],29),BB(xq(a,a.c.length-1),29),e=new HX(n),r=new HX(n)),0==e.a.c.length||(LZ(0,a.c.length),MS(a.c,0,e)),0==r.a.c.length||(a.c[a.c.length]=r)),Lx(n,(hWn(),nlt))&&(yDn(n,i=new HX(n),c=new HX(n)),0==i.a.c.length||(LZ(0,a.c.length),MS(a.c,0,i)),0==c.a.c.length||(a.c[a.c.length]=c)),HSn(t)}function TBn(n){var t,e,i,r,c,a,u,o;for(a=new Wb(n.a);a.a<a.c.c.length;)if((c=BB(n0(a),10)).k==(uSn(),Mut)&&((r=BB(mMn(c,(hWn(),Qft)),61))==(kUn(),oCt)||r==ICt))for(i=new oz(ZL(hbn(c).a.Kc(),new h));dAn(i);)0!=(t=(e=BB(U5(i),17)).a).b&&((u=e.c).i==c&&(Px(0!=t.b),BB(t.a.a.c,8).b=Aon(Pun(Gk(PMt,1),sVn,8,0,[u.i.n,u.n,u.a])).b),(o=e.d).i==c&&(Px(0!=t.b),BB(t.c.b.c,8).b=Aon(Pun(Gk(PMt,1),sVn,8,0,[o.i.n,o.n,o.a])).b))}function MBn(n,t){var e,i,r,c,a,u,o;for(OTn(t,"Sort By Input Model "+mMn(n,(HXn(),Ldt)),1),r=0,i=new Wb(n.b);i.a<i.c.c.length;){for(e=BB(n0(i),29),o=0==r?0:r-1,u=BB(xq(n.b,o),29),a=new Wb(e.a);a.a<a.c.c.length;)GC(mMn(c=BB(n0(a),10),ept))!==GC((QEn(),UIt))&&GC(mMn(c,ept))!==GC(XIt)&&(SQ(),m$(c.j,new O7(u,okn(c))),OH(t,"Node "+c+" ports: "+c.j));SQ(),m$(e.a,new Grn(u,BB(mMn(n,Ldt),339),BB(mMn(n,Adt),378))),OH(t,"Layer "+r+": "+e),++r}HSn(t)}function SBn(n,t){var e,i,r;if(r=kFn(t),JT(new Rq(null,(!t.c&&(t.c=new eU(XOt,t,9,9)),new w1(t.c,16))),new Uw(r)),uzn(t,i=BB(mMn(r,(hWn(),Zft)),21)),i.Hc((bDn(),lft)))for(e=new AL((!t.c&&(t.c=new eU(XOt,t,9,9)),t.c));e.e!=e.i.gc();)Qzn(n,t,r,BB(kpn(e),118));return 0!=BB(ZAn(t,(HXn(),Fgt)),174).gc()&&mDn(t,r),qy(TD(mMn(r,Xgt)))&&i.Fc(pft),Lx(r,gpt)&&My(new uwn(Gy(MD(mMn(r,gpt)))),r),GC(ZAn(t,sgt))===GC((ufn(),pIt))?cWn(n,t,r):eXn(n,t,r),r}function PBn(n,t,i,r){var c,a,u;if(this.j=new Np,this.k=new Np,this.b=new Np,this.c=new Np,this.e=new bA,this.i=new km,this.f=new Dp,this.d=new Np,this.g=new Np,WB(this.b,n),WB(this.b,t),this.e.c=e.Math.min(n.a,t.a),this.e.d=e.Math.min(n.b,t.b),this.e.b=e.Math.abs(n.a-t.a),this.e.a=e.Math.abs(n.b-t.b),c=BB(mMn(r,(HXn(),vgt)),74))for(u=spn(c,0);u.b!=u.d.c;)aen((a=BB(b3(u),8)).a,n.a)&&DH(this.i,a);i&&WB(this.j,i),WB(this.k,r)}function IBn(n,t,e){var i,r,c,a,u,o,s,h,f,l;for(h=new Xz(new xw(e)),vU(u=x8($Nt,ZYn,25,n.f.e.c.length,16,1),u.length),e[t.b]=0,s=new Wb(n.f.e);s.a<s.c.c.length;)(o=BB(n0(s),144)).b!=t.b&&(e[o.b]=DWn),F8(eMn(h,o));for(;0!=h.b.c.length;)for(u[(f=BB(mnn(h),144)).b]=!0,c=vN(new mT(n.b,f),0);c.c;)u[(l=$mn(r=BB(EZ(c),282),f)).b]||(a=Lx(r,(rkn(),pat))?Gy(MD(mMn(r,pat))):n.c,(i=e[f.b]+a)<e[l.b]&&(e[l.b]=i,srn(h,l),F8(eMn(h,l))))}function CBn(n,t,e){var i,r,c,a,u,o,s,h,f;for(r=!0,a=new Wb(n.b);a.a<a.c.c.length;){for(c=BB(n0(a),29),s=_Qn,h=null,o=new Wb(c.a);o.a<o.c.c.length;){if(u=BB(n0(o),10),f=Gy(t.p[u.p])+Gy(t.d[u.p])-u.d.d,i=Gy(t.p[u.p])+Gy(t.d[u.p])+u.o.b+u.d.a,!(f>s&&i>s)){r=!1,e.n&&OH(e,"bk node placement breaks on "+u+" which should have been after "+h);break}h=u,s=Gy(t.p[u.p])+Gy(t.d[u.p])+u.o.b+u.d.a}if(!r)break}return e.n&&OH(e,t+" is feasible: "+r),r}function OBn(n,t,e,i){var r,c,a,u,o,s,h;for(u=-1,h=new Wb(n);h.a<h.c.c.length;)(s=BB(n0(h),112)).g=u--,a=r=dG(E2(NV(AV(new Rq(null,new w1(s.f,16)),new sa),new ha)).d),o=c=dG(E2(NV(AV(new Rq(null,new w1(s.k,16)),new fa),new la)).d),i||(a=dG(E2(NV(new Rq(null,new w1(s.f,16)),new ba)).d),o=dG(E2(NV(new Rq(null,new w1(s.k,16)),new wa)).d)),s.d=a,s.a=r,s.i=o,s.b=c,0==o?r5(e,s,e.c.b,e.c):0==a&&r5(t,s,t.c.b,t.c)}function ABn(n,t,e,i){var r,c,a,u,o,s,h;if(e.d.i!=t.i){for(Bl(r=new $vn(n),(uSn(),Put)),hon(r,(hWn(),dlt),e),hon(r,(HXn(),ept),(QEn(),XIt)),i.c[i.c.length]=r,IZ(a=new ISn,r),qIn(a,(kUn(),ICt)),IZ(u=new ISn,r),qIn(u,oCt),h=e.d,MZ(e,a),qan(c=new wY,e),hon(c,vgt,null),SZ(c,u),MZ(c,h),s=new M2(e.b,0);s.b<s.d.gc();)Px(s.b<s.d.gc()),GC(mMn(o=BB(s.d.Xb(s.c=s.b++),70),Ydt))===GC((Rtn(),UPt))&&(hon(o,Uft,e),fW(s),WB(c.b,o));yAn(r,a,u)}}function $Bn(n,t,e,i){var r,c,a,u,o,s;if(e.c.i!=t.i)for(Bl(r=new $vn(n),(uSn(),Put)),hon(r,(hWn(),dlt),e),hon(r,(HXn(),ept),(QEn(),XIt)),i.c[i.c.length]=r,IZ(a=new ISn,r),qIn(a,(kUn(),ICt)),IZ(u=new ISn,r),qIn(u,oCt),MZ(e,a),qan(c=new wY,e),hon(c,vgt,null),SZ(c,u),MZ(c,t),yAn(r,a,u),s=new M2(e.b,0);s.b<s.d.gc();)Px(s.b<s.d.gc()),o=BB(s.d.Xb(s.c=s.b++),70),BB(mMn(o,Ydt),272)==(Rtn(),UPt)&&(Lx(o,Uft)||hon(o,Uft,e),fW(s),WB(c.b,o))}function LBn(n,t,i,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(l=new Np,p=S4(r),g=t*n.a,w=0,a=new Rv,u=new Rv,o=new Np,v=0,m=0,b=0,d=0,h=0,f=0;0!=p.a.gc();)(s=tbn(p,c,u))&&(p.a.Bc(s),o.c[o.c.length]=s,a.a.zc(s,a),w=n.f[s.p],v+=n.e[s.p]-w*n.b,m+=n.c[s.p]*n.b,f+=w*n.b,d+=n.e[s.p]),(!s||0==p.a.gc()||v>=g&&n.e[s.p]>w*n.b||m>=i*g)&&(l.c[l.c.length]=o,o=new Np,Frn(u,a),a.a.$b(),h-=f,b=e.Math.max(b,h*n.b+d),h+=m,v=m,m=0,f=0,d=0);return new rC(b,l)}function NBn(n){var t,e,i,r,c,a,u,o,s,h,f,l;for(e=new _b(new Ob(n.c.b).a.vc().Kc());e.a.Ob();)u=BB(e.a.Pb(),42),null==(r=(t=BB(u.dd(),149)).a)&&(r=""),!(i=KD(n.c,r))&&0==r.length&&(i=yfn(n)),i&&!ywn(i.c,t,!1)&&DH(i.c,t);for(a=spn(n.a,0);a.b!=a.d.c;)c=BB(b3(a),478),s=T5(n.c,c.a),l=T5(n.c,c.b),s&&l&&DH(s.c,new rC(l,c.c));for(yQ(n.a),f=spn(n.b,0);f.b!=f.d.c;)h=BB(b3(f),478),t=_D(n.c,h.a),o=T5(n.c,h.b),t&&o&&DM(t,o,h.c);yQ(n.b)}function xBn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;c=new Pl(n),d5((a=new dkn).g),d5(a.j),$U(a.b),d5(a.d),d5(a.i),$U(a.k),$U(a.c),$U(a.e),b=bCn(a,c,null),O$n(a,c),r=b,t&&(u=eHn(s=new Pl(t)),vSn(r,Pun(Gk(nMt,1),HWn,527,0,[u]))),l=!1,f=!1,e&&(s=new Pl(e),l8n in s.a&&(l=zJ(s,l8n).ge().a),b8n in s.a&&(f=zJ(s,b8n).ge().a)),h=$j(Fen(new Xm,l),f),BSn(new su,r,h),l8n in c.a&&rtn(c,l8n,null),(l||f)&&(nBn(h,o=new py,l,f),rtn(c,l8n,o)),i=new Xg(a),Uon(new OA(r),i)}function DBn(n,t,e){var i,r,c,a,u,o,s,h,f;for(a=new Ykn,s=Pun(Gk(ANt,1),hQn,25,15,[0]),r=-1,c=0,i=0,o=0;o<n.b.c.length;++o){if(!((h=BB(xq(n.b,o),434)).b>0)){if(r=-1,32==fV(h.c,0)){if(f=s[0],ynn(t,s),s[0]>f)continue}else if($Y(t,h.c,s[0])){s[0]+=h.c.length;continue}return 0}if(r<0&&h.a&&(r=o,c=s[0],i=0),r>=0){if(u=h.b,o==r&&0==(u-=i++))return 0;if(!LUn(t,s,h,u,a)){o=r-1,s[0]=c;continue}}else if(r=-1,!LUn(t,s,h,0,a))return 0}return dUn(a,e)?s[0]:0}function RBn(n){var t,e,i,r,c,a;if(!n.f){if(a=new Mo,c=new Mo,null==(t=P$t).a.zc(n,t)){for(r=new AL(kY(n));r.e!=r.i.gc();)pX(a,RBn(BB(kpn(r),26)));t.a.Bc(n),t.a.gc()}for(!n.s&&(n.s=new eU(FAt,n,21,17)),i=new AL(n.s);i.e!=i.i.gc();)cL(e=BB(kpn(i),170),99)&&f9(c,BB(e,18));chn(c),n.r=new TH(n,(BB(Wtn(QQ((QX(),t$t).o),6),18),c.i),c.g),pX(a,n.r),chn(a),n.f=new NO((BB(Wtn(QQ(t$t.o),5),18),a.i),a.g),P5(n).b&=-3}return n.f}function _Bn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w;for(a=n.o,i=x8(ANt,hQn,25,a,15,1),r=x8(ANt,hQn,25,a,15,1),e=n.p,t=x8(ANt,hQn,25,e,15,1),c=x8(ANt,hQn,25,e,15,1),s=0;s<a;s++){for(f=0;f<e&&!vmn(n,s,f);)++f;i[s]=f}for(h=0;h<a;h++){for(f=e-1;f>=0&&!vmn(n,h,f);)--f;r[h]=f}for(b=0;b<e;b++){for(u=0;u<a&&!vmn(n,u,b);)++u;t[b]=u}for(w=0;w<e;w++){for(u=a-1;u>=0&&!vmn(n,u,w);)--u;c[w]=u}for(o=0;o<a;o++)for(l=0;l<e;l++)o<c[l]&&o>t[l]&&l<r[o]&&l>i[o]&&FRn(n,o,l,!1,!0)}function KBn(n){var t,e,i,r,c,a,u,o;e=qy(TD(mMn(n,(fRn(),Bct)))),c=n.a.c.d,u=n.a.d.d,e?(a=kL(XR(new xI(u.a,u.b),c),.5),o=kL(B$(n.e),.5),t=XR(UR(new xI(c.a,c.b),a),o),Hx(n.d,t)):(r=Gy(MD(mMn(n.a,rat))),i=n.d,c.a>=u.a?c.b>=u.b?(i.a=u.a+(c.a-u.a)/2+r,i.b=u.b+(c.b-u.b)/2-r-n.e.b):(i.a=u.a+(c.a-u.a)/2+r,i.b=c.b+(u.b-c.b)/2+r):c.b>=u.b?(i.a=c.a+(u.a-c.a)/2+r,i.b=u.b+(c.b-u.b)/2+r):(i.a=c.a+(u.a-c.a)/2+r,i.b=c.b+(u.b-c.b)/2-r-n.e.b))}function FBn(n,t){var e,i,r,c,a,u,o;if(null==n)return null;if(0==(c=n.length))return"";for(o=x8(ONt,WVn,25,c,15,1),K8(0,c,n.length),K8(0,c,o.length),YU(n,0,c,o,0),e=null,u=t,r=0,a=0;r<c;r++)i=o[r],EWn(),i<=32&&0!=(2&JLt[i])?u?(!e&&(e=new fN(n)),aY(e,r-a++)):(u=t,32!=i&&(!e&&(e=new fN(n)),sV(e,r-a,r-a+1,String.fromCharCode(32)))):u=!1;return u?e?(c=e.a.length)>0?fx(e.a,0,c-1):"":n.substr(0,c-1):e?e.a:n}function BBn(n){NM(n,new MTn(vj(wj(pj(gj(new du,UJn),"ELK DisCo"),"Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out."),new at))),u2(n,UJn,XJn,mpn(Ect)),u2(n,UJn,WJn,mpn(pct)),u2(n,UJn,VJn,mpn(lct)),u2(n,UJn,QJn,mpn(vct)),u2(n,UJn,XYn,mpn(kct)),u2(n,UJn,WYn,mpn(yct)),u2(n,UJn,UYn,mpn(jct)),u2(n,UJn,VYn,mpn(mct)),u2(n,UJn,BJn,mpn(wct)),u2(n,UJn,HJn,mpn(bct)),u2(n,UJn,qJn,mpn(dct)),u2(n,UJn,GJn,mpn(gct))}function HBn(n,t,e,i){var r,c,a,u,o,s,h;if(Bl(c=new $vn(n),(uSn(),Cut)),hon(c,(HXn(),ept),(QEn(),XIt)),r=0,t){for(hon(a=new ISn,(hWn(),dlt),t),hon(c,dlt,t.i),qIn(a,(kUn(),ICt)),IZ(a,c),s=0,h=(o=Z0(t.e)).length;s<h;++s)MZ(o[s],a);hon(t,Elt,c),++r}if(e){for(u=new ISn,hon(c,(hWn(),dlt),e.i),hon(u,dlt,e),qIn(u,(kUn(),oCt)),IZ(u,c),s=0,h=(o=Z0(e.g)).length;s<h;++s)SZ(o[s],u);hon(e,Elt,c),++r}return hon(c,(hWn(),Bft),iln(r)),i.c[i.c.length]=c,c}function qBn(){qBn=O,OOt=Pun(Gk(ONt,1),WVn,25,15,[48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70]),AOt=new RegExp("[ \t\n\r\f]+");try{COt=Pun(Gk(D$t,1),HWn,2015,0,[new vp((s$(),sdn("yyyy-MM-dd'T'HH:mm:ss'.'SSSZ",fR((fk(),fk(),rtt))))),new vp(sdn("yyyy-MM-dd'T'HH:mm:ss'.'SSS",fR(rtt))),new vp(sdn("yyyy-MM-dd'T'HH:mm:ss",fR(rtt))),new vp(sdn("yyyy-MM-dd'T'HH:mm",fR(rtt))),new vp(sdn("yyyy-MM-dd",fR(rtt)))])}catch(n){if(!cL(n=lun(n),78))throw Hp(n)}}function GBn(n){var t,i,r,c;if(r=qXn((!n.c&&(n.c=yhn(n.f)),n.c),0),0==n.e||0==n.a&&-1!=n.f&&n.e<0)return r;if(t=iin(n)<0?1:0,i=n.e,r.length,e.Math.abs(IJ(n.e)),c=new Ck,1==t&&(c.a+="-"),n.e>0)if((i-=r.length-t)>=0){for(c.a+="0.";i>qtt.length;i-=qtt.length)Nq(c,qtt);gR(c,qtt,IJ(i)),oO(c,r.substr(t))}else oO(c,fx(r,t,IJ(i=t-i))),c.a+=".",oO(c,nO(r,IJ(i)));else{for(oO(c,r.substr(t));i<-qtt.length;i+=qtt.length)Nq(c,qtt);gR(c,qtt,IJ(-i))}return c.a}function zBn(n,t,i,r){var c,a,u,o,s,h,f,l,b;return h=(s=XR(new xI(i.a,i.b),n)).a*t.b-s.b*t.a,f=t.a*r.b-t.b*r.a,l=(s.a*r.b-s.b*r.a)/f,b=h/f,0==f?0==h?(a=W8(n,c=UR(new xI(i.a,i.b),kL(new xI(r.a,r.b),.5))),u=W8(UR(new xI(n.a,n.b),t),c),o=.5*e.Math.sqrt(r.a*r.a+r.b*r.b),a<u&&a<=o?new xI(n.a,n.b):u<=o?UR(new xI(n.a,n.b),t):null):null:l>=0&&l<=1&&b>=0&&b<=1?UR(new xI(n.a,n.b),kL(new xI(t.a,t.b),l)):null}function UBn(n,t,e){var i,r,c,a,u;if(i=BB(mMn(n,(HXn(),Ndt)),21),e.a>t.a&&(i.Hc((wEn(),WMt))?n.c.a+=(e.a-t.a)/2:i.Hc(QMt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((wEn(),JMt))?n.c.b+=(e.b-t.b)/2:i.Hc(YMt)&&(n.c.b+=e.b-t.b)),BB(mMn(n,(hWn(),Zft)),21).Hc((bDn(),lft))&&(e.a>t.a||e.b>t.b))for(u=new Wb(n.a);u.a<u.c.c.length;)(a=BB(n0(u),10)).k==(uSn(),Mut)&&((r=BB(mMn(a,Qft),61))==(kUn(),oCt)?a.n.a+=e.a-t.a:r==SCt&&(a.n.b+=e.b-t.b));c=n.d,n.f.a=e.a-c.b-c.c,n.f.b=e.b-c.d-c.a}function XBn(n,t,e){var i,r,c,a,u;if(i=BB(mMn(n,(HXn(),Ndt)),21),e.a>t.a&&(i.Hc((wEn(),WMt))?n.c.a+=(e.a-t.a)/2:i.Hc(QMt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((wEn(),JMt))?n.c.b+=(e.b-t.b)/2:i.Hc(YMt)&&(n.c.b+=e.b-t.b)),BB(mMn(n,(hWn(),Zft)),21).Hc((bDn(),lft))&&(e.a>t.a||e.b>t.b))for(a=new Wb(n.a);a.a<a.c.c.length;)(c=BB(n0(a),10)).k==(uSn(),Mut)&&((r=BB(mMn(c,Qft),61))==(kUn(),oCt)?c.n.a+=e.a-t.a:r==SCt&&(c.n.b+=e.b-t.b));u=n.d,n.f.a=e.a-u.b-u.c,n.f.b=e.b-u.d-u.a}function WBn(n){var t,i,r,c,a,u,o,s,h,f;for(s=new Cb(new Ib(xOn(n)).a.vc().Kc());s.a.Ob();){for(r=BB(s.a.Pb(),42),h=0,f=0,h=(o=BB(r.cd(),10)).d.d,f=o.o.b+o.d.a,n.d[o.p]=0,t=o;(c=n.a[t.p])!=o;)i=Mgn(t,c),u=0,u=n.c==(gJ(),nyt)?i.d.n.b+i.d.a.b-i.c.n.b-i.c.a.b:i.c.n.b+i.c.a.b-i.d.n.b-i.d.a.b,a=Gy(n.d[t.p])+u,n.d[c.p]=a,h=e.Math.max(h,c.d.d-a),f=e.Math.max(f,a+c.o.b+c.d.a),t=c;t=o;do{n.d[t.p]=Gy(n.d[t.p])+h,t=n.a[t.p]}while(t!=o);n.b[o.p]=h+f}}function VBn(n){var t,i,r,c,a,u,o,s,h,f,l;for(n.b=!1,f=RQn,o=_Qn,l=RQn,s=_Qn,i=n.e.a.ec().Kc();i.Ob();)for(r=(t=BB(i.Pb(),266)).a,f=e.Math.min(f,r.c),o=e.Math.max(o,r.c+r.b),l=e.Math.min(l,r.d),s=e.Math.max(s,r.d+r.a),a=new Wb(t.c);a.a<a.c.c.length;)(c=BB(n0(a),395)).a.a?(u=(h=r.d+c.b.b)+c.c,l=e.Math.min(l,h),s=e.Math.max(s,u)):(u=(h=r.c+c.b.a)+c.c,f=e.Math.min(f,h),o=e.Math.max(o,u));n.a=new xI(o-f,s-l),n.c=new xI(f+n.d.a,l+n.d.b)}function QBn(n,t,e){var i,r,c,a,u,o,s,h;for(h=new Np,c=0,tin(s=new x0(0,e),new asn(0,0,s,e)),r=0,o=new AL(n);o.e!=o.i.gc();)u=BB(kpn(o),33),i=BB(xq(s.a,s.a.c.length-1),187),r+u.g+(0==BB(xq(s.a,0),187).b.c.length?0:e)>t&&(r=0,c+=s.b+e,h.c[h.c.length]=s,tin(s=new x0(c,e),i=new asn(0,s.f,s,e)),r=0),0==i.b.c.length||u.f>=i.o&&u.f<=i.f||.5*i.a<=u.f&&1.5*i.a>=u.f?ybn(i,u):(tin(s,a=new asn(i.s+i.r+e,s.f,s,e)),ybn(a,u)),r=u.i+u.g;return h.c[h.c.length]=s,h}function YBn(n){var t,e,i,r,c,a;if(!n.a){if(n.o=null,a=new gp(n),t=new So,null==(e=P$t).a.zc(n,e)){for(c=new AL(kY(n));c.e!=c.i.gc();)pX(a,YBn(BB(kpn(c),26)));e.a.Bc(n),e.a.gc()}for(!n.s&&(n.s=new eU(FAt,n,21,17)),r=new AL(n.s);r.e!=r.i.gc();)cL(i=BB(kpn(r),170),322)&&f9(t,BB(i,34));chn(t),n.k=new EH(n,(BB(Wtn(QQ((QX(),t$t).o),7),18),t.i),t.g),pX(a,n.k),chn(a),n.a=new NO((BB(Wtn(QQ(t$t.o),4),18),a.i),a.g),P5(n).b&=-2}return n.a}function JBn(n,t,e,i,r,c,a){var u,o,s,h,f;return h=!1,u=dNn(e.q,t.f+t.b-e.q.f),!((f=r-(e.q.e+u-a))<i.g)&&(o=c==n.c.length-1&&f>=(l1(c,n.c.length),BB(n.c[c],200)).e,!((s=cHn(i,f,!1).a)>t.b&&!o)&&((o||s<=t.b)&&(o&&s>t.b?(e.d=s,p9(e,FSn(e,s))):(aEn(e.q,u),e.c=!0),p9(i,r-(e.s+e.r)),Tvn(i,e.q.e+e.q.d,t.f),tin(t,i),n.c.length>c&&(Tkn((l1(c,n.c.length),BB(n.c[c],200)),i),0==(l1(c,n.c.length),BB(n.c[c],200)).a.c.length&&s6(n,c)),h=!0),h))}function ZBn(n,t,e,i){var r,c,a,u,o,s,h;if(h=axn(n.e.Tg(),t),r=0,c=BB(n.g,119),o=null,ZM(),BB(t,66).Oj()){for(u=0;u<n.i;++u)if(a=c[u],h.rl(a.ak())){if(Nfn(a,e)){o=a;break}++r}}else if(null!=e){for(u=0;u<n.i;++u)if(a=c[u],h.rl(a.ak())){if(Nfn(e,a.dd())){o=a;break}++r}}else for(u=0;u<n.i;++u)if(a=c[u],h.rl(a.ak())){if(null==a.dd()){o=a;break}++r}return o&&(mA(n.e)&&(s=t.$j()?new b4(n.e,4,t,e,null,r,!0):LY(n,t.Kj()?2:1,t,e,t.zj(),-1,!0),i?i.Ei(s):i=s),i=T_n(n,o,i)),i}function nHn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d;switch(w=0,d=0,s=c.c,o=c.b,f=i.f,b=i.g,t.g){case 0:w=r.i+r.g+u,d=n.c?gTn(w,a,r,u):r.j,l=e.Math.max(s,w+b),h=e.Math.max(o,d+f);break;case 1:d=r.j+r.f+u,w=n.c?dTn(d,a,r,u):r.i,l=e.Math.max(s,w+b),h=e.Math.max(o,d+f);break;case 2:w=s+u,d=0,l=s+u+b,h=e.Math.max(o,f);break;case 3:w=0,d=o+u,l=e.Math.max(s,b),h=o+u+f;break;default:throw Hp(new Ky("IllegalPlacementOption."))}return new awn(n.a,l,h,t,w,d)}function tHn(n){var t,i,r,c,a,u,o,s,h,f,l,b;if(o=n.d,l=BB(mMn(n,(hWn(),_lt)),15),t=BB(mMn(n,Dft),15),l||t){if(a=Gy(MD(edn(n,(HXn(),ppt)))),u=Gy(MD(edn(n,vpt))),b=0,l){for(h=0,c=l.Kc();c.Ob();)r=BB(c.Pb(),10),h=e.Math.max(h,r.o.b),b+=r.o.a;b+=a*(l.gc()-1),o.d+=h+u}if(i=0,t){for(h=0,c=t.Kc();c.Ob();)r=BB(c.Pb(),10),h=e.Math.max(h,r.o.b),i+=r.o.a;i+=a*(t.gc()-1),o.a+=h+u}(s=e.Math.max(b,i))>n.o.a&&(f=(s-n.o.a)/2,o.b=e.Math.max(o.b,f),o.c=e.Math.max(o.c,f))}}function eHn(n){var t,e,i,r,c,a;for(cA(r=new R0,(Nun(),JTt)),i=new Sb(new Jy(new TT(n,jrn(n,x8(Qtt,sVn,2,0,6,1))).b));i.b<i.d.gc();)Px(i.b<i.d.gc()),e=SD(i.d.Xb(i.c=i.b++)),(c=pGn(lAt,e))&&null!=(a=Zqn(c,(t=zJ(n,e)).je()?t.je().a:t.ge()?""+t.ge().a:t.he()?""+t.he().a:t.Ib()))&&((SN(c.j,(rpn(),sMt))||SN(c.j,hMt))&&son(Ynn(r,UOt),c,a),SN(c.j,uMt)&&son(Ynn(r,KOt),c,a),SN(c.j,fMt)&&son(Ynn(r,XOt),c,a),SN(c.j,oMt)&&son(Ynn(r,zOt),c,a));return r}function iHn(n,t,e,i){var r,c,a,u,o,s;if(o=axn(n.e.Tg(),t),c=BB(n.g,119),$xn(n.e,t)){for(r=0,u=0;u<n.i;++u)if(a=c[u],o.rl(a.ak())){if(r==e)return ZM(),BB(t,66).Oj()?a:(null!=(s=a.dd())&&i&&cL(t,99)&&0!=(BB(t,18).Bb&BQn)&&(s=FCn(n,t,u,r,s)),s);++r}throw Hp(new Ay(e9n+e+o8n+r))}for(r=0,u=0;u<n.i;++u){if(a=c[u],o.rl(a.ak()))return ZM(),BB(t,66).Oj()?a:(null!=(s=a.dd())&&i&&cL(t,99)&&0!=(BB(t,18).Bb&BQn)&&(s=FCn(n,t,u,r,s)),s);++r}return t.zj()}function rHn(n,t,e){var i,r,c,a,u,o,s,h;if(r=BB(n.g,119),$xn(n.e,t))return ZM(),BB(t,66).Oj()?new lq(t,n):new xC(t,n);for(s=axn(n.e.Tg(),t),i=0,u=0;u<n.i;++u){if(a=(c=r[u]).ak(),s.rl(a)){if(ZM(),BB(t,66).Oj())return c;if(a==(TOn(),lLt)||a==sLt){for(o=new lN(Bbn(c.dd()));++u<n.i;)((a=(c=r[u]).ak())==lLt||a==sLt)&&oO(o,Bbn(c.dd()));return g_(BB(t.Yj(),148),o.a)}return null!=(h=c.dd())&&e&&cL(t,99)&&0!=(BB(t,18).Bb&BQn)&&(h=FCn(n,t,u,i,h)),h}++i}return t.zj()}function cHn(n,t,i){var r,c,a,u,o,s,h,f,l,b;for(a=0,u=n.t,c=0,r=0,s=0,b=0,l=0,i&&(n.n.c=x8(Ant,HWn,1,0,5,1),WB(n.n,new RJ(n.s,n.t,n.i))),o=0,f=new Wb(n.b);f.a<f.c.c.length;)a+(h=BB(n0(f),33)).g+(o>0?n.i:0)>t&&s>0&&(a=0,u+=s+n.i,c=e.Math.max(c,b),r+=s+n.i,s=0,b=0,i&&(++l,WB(n.n,new RJ(n.s,u,n.i))),o=0),b+=h.g+(o>0?n.i:0),s=e.Math.max(s,h.f),i&&smn(BB(xq(n.n,l),211),h),a+=h.g+(o>0?n.i:0),++o;return c=e.Math.max(c,b),r+=s,i&&(n.r=c,n.d=r,yyn(n.j)),new UV(n.s,n.t,c,r)}function aHn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;if($T(),SU(n,"src"),SU(e,"dest"),l=tsn(n),o=tsn(e),pH(0!=(4&l.i),"srcType is not an array"),pH(0!=(4&o.i),"destType is not an array"),f=l.c,a=o.c,pH(0!=(1&f.i)?f==a:0==(1&a.i),"Array types don't match"),b=n.length,s=e.length,t<0||i<0||r<0||t+r>b||i+r>s)throw Hp(new fv);if(0==(1&f.i)&&l!=o)if(h=een(n),c=een(e),GC(n)===GC(e)&&t<i)for(t+=r,u=i+r;u-- >i;)$X(c,u,h[--t]);else for(u=i+r;i<u;)$X(c,i++,h[t++]);else r>0&&KIn(n,t,e,i,r,!0)}function uHn(){uHn=O,ret=Pun(Gk(ANt,1),hQn,25,15,[KVn,1162261467,OVn,1220703125,362797056,1977326743,OVn,387420489,AQn,214358881,429981696,815730721,1475789056,170859375,268435456,410338673,612220032,893871739,128e7,1801088541,113379904,148035889,191102976,244140625,308915776,387420489,481890304,594823321,729e6,887503681,OVn,1291467969,1544804416,1838265625,60466176]),cet=Pun(Gk(ANt,1),hQn,25,15,[-1,-1,31,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5])}function oHn(n){var t,e,i,r,c,a,u;for(i=new Wb(n.b);i.a<i.c.c.length;)for(c=new Wb(a0(BB(n0(i),29).a));c.a<c.c.c.length;)if(Znn(r=BB(n0(c),10))&&!(e=BB(mMn(r,(hWn(),Rft)),305)).g&&e.d)for(t=e,u=e.d;u;)eRn(u.i,u.k,!1,!0),A7(t.a),A7(u.i),A7(u.k),A7(u.b),MZ(u.c,t.c.d),MZ(t.c,null),PZ(t.a,null),PZ(u.i,null),PZ(u.k,null),PZ(u.b,null),(a=new v3(t.i,u.a,t.e,u.j,u.f)).k=t.k,a.n=t.n,a.b=t.b,a.c=u.c,a.g=t.g,a.d=u.d,hon(t.i,Rft,a),hon(u.a,Rft,a),u=u.d,t=a}function sHn(n,t){var e,i,r,c,a;if(a=BB(t,136),T$n(n),T$n(a),null!=a.b){if(n.c=!0,null==n.b)return n.b=x8(ANt,hQn,25,a.b.length,15,1),void aHn(a.b,0,n.b,0,a.b.length);for(c=x8(ANt,hQn,25,n.b.length+a.b.length,15,1),e=0,i=0,r=0;e<n.b.length||i<a.b.length;)e>=n.b.length?(c[r++]=a.b[i++],c[r++]=a.b[i++]):i>=a.b.length?(c[r++]=n.b[e++],c[r++]=n.b[e++]):a.b[i]<n.b[e]||a.b[i]===n.b[e]&&a.b[i+1]<n.b[e+1]?(c[r++]=a.b[i++],c[r++]=a.b[i++]):(c[r++]=n.b[e++],c[r++]=n.b[e++]);n.b=c}}function hHn(n,t){var e,i,r,c,a,u,o,s,h,f;return e=qy(TD(mMn(n,(hWn(),slt)))),u=qy(TD(mMn(t,slt))),i=BB(mMn(n,hlt),11),o=BB(mMn(t,hlt),11),r=BB(mMn(n,flt),11),s=BB(mMn(t,flt),11),h=!!i&&i==o,f=!!r&&r==s,e||u?(c=(!qy(TD(mMn(n,slt)))||qy(TD(mMn(n,olt))))&&(!qy(TD(mMn(t,slt)))||qy(TD(mMn(t,olt)))),a=!(qy(TD(mMn(n,slt)))&&qy(TD(mMn(n,olt)))||qy(TD(mMn(t,slt)))&&qy(TD(mMn(t,olt)))),new RK(h&&c||f&&a,h,f)):new RK(BB(n0(new Wb(n.j)),11).p==BB(n0(new Wb(t.j)),11).p,h,f)}function fHn(n){var t,i,r,c,a,u,o,s;for(r=0,i=0,s=new YT,t=0,o=new Wb(n.n);o.a<o.c.c.length;)0==(u=BB(n0(o),211)).c.c.length?r5(s,u,s.c.b,s.c):(r=e.Math.max(r,u.d),i+=u.a+(t>0?n.i:0)),++t;for(nwn(n.n,s),n.d=i,n.r=r,n.g=0,n.f=0,n.e=0,n.o=RQn,n.p=RQn,a=new Wb(n.b);a.a<a.c.c.length;)c=BB(n0(a),33),n.p=e.Math.min(n.p,c.g),n.g=e.Math.max(n.g,c.g),n.f=e.Math.max(n.f,c.f),n.o=e.Math.min(n.o,c.f),n.e+=c.f+n.i;n.a=n.e/n.b.c.length-n.i*((n.b.c.length-1)/n.b.c.length),yyn(n.j)}function lHn(n){var t,e,i,r;return 0!=(64&n.Db)?Yln(n):(t=new lN(V5n),(i=n.k)?oO(oO((t.a+=' "',t),i),'"'):(!n.n&&(n.n=new eU(zOt,n,1,7)),n.n.i>0&&(!(r=(!n.n&&(n.n=new eU(zOt,n,1,7)),BB(Wtn(n.n,0),137)).a)||oO(oO((t.a+=' "',t),r),'"'))),!n.b&&(n.b=new h_(_Ot,n,4,7)),e=!(n.b.i<=1&&(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c.i<=1)),t.a+=e?" [":" ",oO(t,JL(new mk,new AL(n.b))),e&&(t.a+="]"),t.a+=e1n,e&&(t.a+="["),oO(t,JL(new mk,new AL(n.c))),e&&(t.a+="]"),t.a)}function bHn(n,t){var e,i,r,c,a,u,o;if(n.a){if(o=null,null!=(u=n.a.ne())?t.a+=""+u:null!=(a=n.a.Dj())&&(-1!=(c=GO(a,YTn(91)))?(o=a.substr(c),t.a+=""+fx(null==a?zWn:(kW(a),a),0,c)):t.a+=""+a),n.d&&0!=n.d.i){for(r=!0,t.a+="<",i=new AL(n.d);i.e!=i.i.gc();)e=BB(kpn(i),87),r?r=!1:t.a+=FWn,bHn(e,t);t.a+=">"}null!=o&&(t.a+=""+o)}else n.e?null!=(u=n.e.zb)&&(t.a+=""+u):(t.a+="?",n.b?(t.a+=" super ",bHn(n.b,t)):n.f&&(t.a+=" extends ",bHn(n.f,t)))}function wHn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(y=n.c,k=t.c,e=E7(y.a,n,0),i=E7(k.a,t,0),v=BB(xwn(n,(ain(),Hvt)).Kc().Pb(),11),T=BB(xwn(n,qvt).Kc().Pb(),11),m=BB(xwn(t,Hvt).Kc().Pb(),11),M=BB(xwn(t,qvt).Kc().Pb(),11),g=Z0(v.e),j=Z0(T.g),p=Z0(m.e),E=Z0(M.g),Qyn(n,i,k),s=0,b=(c=p).length;s<b;++s)MZ(c[s],v);for(h=0,w=(a=E).length;h<w;++h)SZ(a[h],T);for(Qyn(t,e,y),f=0,d=(u=g).length;f<d;++f)MZ(u[f],m);for(o=0,l=(r=j).length;o<l;++o)SZ(r[o],M)}function dHn(n,t,e,i){var r,c,a,u,o,s;if(c=Wln(i),!qy(TD(mMn(i,(HXn(),Cgt))))&&!qy(TD(mMn(n,bgt)))||vA(BB(mMn(n,ept),98)))switch(IZ(u=new ISn,n),t?((s=u.n).a=t.a-n.n.a,s.b=t.b-n.n.b,WSn(s,0,0,n.o.a,n.o.b),qIn(u,zKn(u,c))):(r=hwn(c),qIn(u,e==(ain(),qvt)?r:Tln(r))),a=BB(mMn(i,(hWn(),Zft)),21),o=u.j,c.g){case 2:case 1:(o==(kUn(),sCt)||o==SCt)&&a.Fc((bDn(),gft));break;case 4:case 3:(o==(kUn(),oCt)||o==ICt)&&a.Fc((bDn(),gft))}else r=hwn(c),u=RKn(n,e,e==(ain(),qvt)?r:Tln(r));return u}function gHn(n,t,i){var r,c,a,u,o,s,h;return e.Math.abs(t.s-t.c)<lZn||e.Math.abs(i.s-i.c)<lZn?0:(r=WNn(n,t.j,i.e),c=WNn(n,i.j,t.e),a=0,-1==r||-1==c?(-1==r&&(new zZ((O6(),Tyt),i,t,1),++a),-1==c&&(new zZ((O6(),Tyt),t,i,1),++a)):(u=Tfn(t.j,i.s,i.c),u+=Tfn(i.e,t.s,t.c),o=Tfn(i.j,t.s,t.c),(s=r+16*u)<(h=c+16*(o+=Tfn(t.e,i.s,i.c)))?new zZ((O6(),Myt),t,i,h-s):s>h?new zZ((O6(),Myt),i,t,s-h):s>0&&h>0&&(new zZ((O6(),Myt),t,i,0),new zZ(Myt,i,t,0))),a)}function pHn(n,t){var i,r,c,a,u;for(u=new usn(new Pb(n.f.b).a);u.b;){if(c=BB((a=ten(u)).cd(),594),1==t){if(c.gf()!=(Ffn(),HPt)&&c.gf()!=_Pt)continue}else if(c.gf()!=(Ffn(),KPt)&&c.gf()!=FPt)continue;switch(r=BB(BB(a.dd(),46).b,81),i=BB(BB(a.dd(),46).a,189).c,c.gf().g){case 2:r.g.c=n.e.a,r.g.b=e.Math.max(1,r.g.b+i);break;case 1:r.g.c=r.g.c+i,r.g.b=e.Math.max(1,r.g.b-i);break;case 4:r.g.d=n.e.b,r.g.a=e.Math.max(1,r.g.a+i);break;case 3:r.g.d=r.g.d+i,r.g.a=e.Math.max(1,r.g.a-i)}}}function vHn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(o=x8(ANt,hQn,25,t.b.c.length,15,1),h=x8($ut,$Vn,267,t.b.c.length,0,1),s=x8(Out,a1n,10,t.b.c.length,0,1),b=0,w=(l=n.a).length;b<w;++b){for(g=0,u=new Wb((f=l[b]).e);u.a<u.c.c.length;)++o[r=tA((c=BB(n0(u),10)).c)],d=Gy(MD(mMn(t,(HXn(),ypt)))),o[r]>0&&s[r]&&(d=_$(n.b,s[r],c)),g=e.Math.max(g,c.c.c.b+d);for(a=new Wb(f.e);a.a<a.c.c.length;)(c=BB(n0(a),10)).n.b=g+c.d.d,(i=c.c).c.b=g+c.d.d+c.o.b+c.d.a,h[E7(i.b.b,i,0)]=c.k,s[E7(i.b.b,i,0)]=c}}function mHn(n,t){var e,i,r,c,a,u,o,s,f,l,b;for(i=new oz(ZL(dLn(t).a.Kc(),new h));dAn(i);)cL(Wtn((!(e=BB(U5(i),79)).b&&(e.b=new h_(_Ot,e,4,7)),e.b),0),186)||(o=PTn(BB(Wtn((!e.c&&(e.c=new h_(_Ot,e,5,8)),e.c),0),82)),nAn(e)||(a=t.i+t.g/2,u=t.j+t.f/2,f=o.i+o.g/2,l=o.j+o.f/2,(b=new Gj).a=f-a,b.b=l-u,Ukn(c=new xI(b.a,b.b),t.g,t.f),b.a-=c.a,b.b-=c.b,a=f-b.a,u=l-b.b,Ukn(s=new xI(b.a,b.b),o.g,o.f),b.a-=s.a,b.b-=s.b,f=a+b.a,l=u+b.b,Cen(r=cDn(e,!0,!0),a),Aen(r,u),Ten(r,f),Oen(r,l),mHn(n,o)))}function yHn(n){NM(n,new MTn(vj(wj(pj(gj(new du,R4n),"ELK SPOrE Compaction"),"ShrinkTree is a compaction algorithm that maintains the topology of a layout. The relocation of diagram elements is based on contracting a spanning tree."),new tu))),u2(n,R4n,_4n,mpn(kTt)),u2(n,R4n,K4n,mpn(vTt)),u2(n,R4n,F4n,mpn(pTt)),u2(n,R4n,B4n,mpn(dTt)),u2(n,R4n,H4n,mpn(gTt)),u2(n,R4n,QJn,wTt),u2(n,R4n,vZn,8),u2(n,R4n,q4n,mpn(yTt)),u2(n,R4n,G4n,mpn(hTt)),u2(n,R4n,z4n,mpn(fTt)),u2(n,R4n,X2n,(hN(),!1))}function kHn(n,t){var i,r,c,a,u,o,s,h,f,l;for(OTn(t,"Simple node placement",1),l=BB(mMn(n,(hWn(),Alt)),304),o=0,a=new Wb(n.b);a.a<a.c.c.length;){for((u=(r=BB(n0(a),29)).c).b=0,i=null,h=new Wb(r.a);h.a<h.c.c.length;)s=BB(n0(h),10),i&&(u.b+=Cdn(s,i,l.c)),u.b+=s.d.d+s.o.b+s.d.a,i=s;o=e.Math.max(o,u.b)}for(c=new Wb(n.b);c.a<c.c.c.length;)for(f=(o-(u=(r=BB(n0(c),29)).c).b)/2,i=null,h=new Wb(r.a);h.a<h.c.c.length;)s=BB(n0(h),10),i&&(f+=Cdn(s,i,l.c)),f+=s.d.d,s.n.b=f,f+=s.o.b+s.d.a,i=s;HSn(t)}function jHn(n,t,e,i){var r,c,a,u,o,s,h,f;if(0==i.gc())return!1;if(ZM(),a=(o=BB(t,66).Oj())?i:new gtn(i.gc()),$xn(n.e,t)){if(t.hi())for(h=i.Kc();h.Ob();)UFn(n,t,s=h.Pb(),cL(t,99)&&0!=(BB(t,18).Bb&BQn))||(c=Z3(t,s),a.Fc(c));else if(!o)for(h=i.Kc();h.Ob();)c=Z3(t,s=h.Pb()),a.Fc(c)}else{for(f=axn(n.e.Tg(),t),r=BB(n.g,119),u=0;u<n.i;++u)if(c=r[u],f.rl(c.ak()))throw Hp(new Ky(C7n));if(i.gc()>1)throw Hp(new Ky(C7n));o||(c=Z3(t,i.Kc().Pb()),a.Fc(c))}return oon(n,EPn(n,t,e),a)}function EHn(n,t){var e,i,r,c;for(Qtn(t.b.j),JT($V(new Rq(null,new w1(t.d,16)),new cc),new ac),c=new Wb(t.d);c.a<c.c.c.length;){switch((r=BB(n0(c),101)).e.g){case 0:e=BB(xq(r.j,0),113).d.j,Gl(r,BB($N(Oz(BB(h6(r.k,e),15).Oc(),Qst)),113)),ql(r,BB($N(Cz(BB(h6(r.k,e),15).Oc(),Qst)),113));break;case 1:i=Hyn(r),Gl(r,BB($N(Oz(BB(h6(r.k,i[0]),15).Oc(),Qst)),113)),ql(r,BB($N(Cz(BB(h6(r.k,i[1]),15).Oc(),Qst)),113));break;case 2:VPn(n,r);break;case 3:_Nn(r);break;case 4:GNn(n,r)}Vtn(r)}n.a=null}function THn(n,t,e){var i,r,c,a,u,o,s,h;return i=n.a.o==(oZ(),cyt)?RQn:_Qn,!(u=cFn(n,new aI(t,e))).a&&u.c?(DH(n.d,u),i):u.a?(r=u.a.c,o=u.a.d,e?(s=n.a.c==(gJ(),tyt)?o:r,c=n.a.c==tyt?r:o,a=n.a.g[c.i.p],h=Gy(n.a.p[a.p])+Gy(n.a.d[c.i.p])+c.n.b+c.a.b-Gy(n.a.d[s.i.p])-s.n.b-s.a.b):(s=n.a.c==(gJ(),nyt)?o:r,c=n.a.c==nyt?r:o,h=Gy(n.a.p[n.a.g[c.i.p].p])+Gy(n.a.d[c.i.p])+c.n.b+c.a.b-Gy(n.a.d[s.i.p])-s.n.b-s.a.b),n.a.n[n.a.g[r.i.p].p]=(hN(),!0),n.a.n[n.a.g[o.i.p].p]=!0,h):i}function MHn(n,t,e){var i,r,c,a,u,o,s;if($xn(n.e,t))ZM(),AOn((u=BB(t,66).Oj()?new lq(t,n):new xC(t,n)).c,u.b),Z$(u,BB(e,14));else{for(s=axn(n.e.Tg(),t),i=BB(n.g,119),c=0;c<n.i;++c)if(r=i[c].ak(),s.rl(r)){if(r==(TOn(),lLt)||r==sLt){for(a=c,(o=Ovn(n,t,e))?fDn(n,c):++c;c<n.i;)(r=i[c].ak())==lLt||r==sLt?fDn(n,c):++c;o||BB(ovn(n,a,Z3(t,e)),72)}else Ovn(n,t,e)?fDn(n,c):BB(ovn(n,c,(ZM(),BB(t,66).Oj()?BB(e,72):Z3(t,e))),72);return}Ovn(n,t,e)||f9(n,(ZM(),BB(t,66).Oj()?BB(e,72):Z3(t,e)))}}function SHn(n,t,e){var i,r,c,a,u,o,s,h;return Nfn(e,n.b)||(n.b=e,c=new Jn,a=BB(P4($V(new Rq(null,new w1(e.f,16)),c),x7(new Q,new Y,new cn,new an,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Xet),Uet]))),21),n.e=!0,n.f=!0,n.c=!0,n.d=!0,r=a.Hc((Hpn(),Brt)),i=a.Hc(Hrt),r&&!i&&(n.f=!1),!r&&i&&(n.d=!1),r=a.Hc(Frt),i=a.Hc(qrt),r&&!i&&(n.c=!1),!r&&i&&(n.e=!1)),h=BB(n.a.Ce(t,e),46),o=BB(h.a,19).a,s=BB(h.b,19).a,u=!1,o<0?n.c||(u=!0):n.e||(u=!0),s<0?n.d||(u=!0):n.f||(u=!0),u?SHn(n,h,e):h}function PHn(n){var t,i,r,c;c=n.o,qD(),n.A.dc()||Nfn(n.A,$rt)?t=c.b:(t=MCn(n.f),n.A.Hc((mdn(),RCt))&&!n.B.Hc((nKn(),XCt))&&(t=e.Math.max(t,MCn(BB(oV(n.p,(kUn(),oCt)),244))),t=e.Math.max(t,MCn(BB(oV(n.p,ICt),244)))),(i=oan(n))&&(t=e.Math.max(t,i.b)),n.A.Hc(_Ct)&&(n.q!=(QEn(),WIt)&&n.q!=XIt||(t=e.Math.max(t,XH(BB(oV(n.b,(kUn(),oCt)),124))),t=e.Math.max(t,XH(BB(oV(n.b,ICt),124)))))),qy(TD(n.e.yf().We((sWn(),FSt))))?c.b=e.Math.max(c.b,t):c.b=t,(r=n.f.i).d=0,r.a=t,GFn(n.f)}function IHn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;for(h=0;h<t.length;h++){for(a=n.Kc();a.Ob();)BB(a.Pb(),225).Of(h,t);for(f=0;f<t[h].length;f++){for(u=n.Kc();u.Ob();)BB(u.Pb(),225).Pf(h,f,t);for(b=t[h][f].j,l=0;l<b.c.length;l++){for(o=n.Kc();o.Ob();)BB(o.Pb(),225).Qf(h,f,l,t);for(l1(l,b.c.length),e=0,r=new m6(BB(b.c[l],11).b);y$(r.a)||y$(r.b);)for(i=BB(y$(r.a)?n0(r.a):n0(r.b),17),s=n.Kc();s.Ob();)BB(s.Pb(),225).Nf(h,f,l,e++,i,t)}}}for(c=n.Kc();c.Ob();)BB(c.Pb(),225).Mf()}function CHn(n,t){var e,i,r,c,a;for(n.b=Gy(MD(mMn(t,(HXn(),kpt)))),n.c=Gy(MD(mMn(t,Tpt))),n.d=BB(mMn(t,rgt),336),n.a=BB(mMn(t,Pdt),275),fmn(t),r=(c=BB(P4(AV(AV(wnn(wnn(new Rq(null,new w1(t.b,16)),new ye),new ke),new je),new Ee),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15)).Kc();r.Ob();)e=BB(r.Pb(),17),BB(mMn(e,(hWn(),Nlt)),15).Jc(new ed(n)),hon(e,Nlt,null);for(i=c.Kc();i.Ob();)e=BB(i.Pb(),17),a=BB(mMn(e,(hWn(),xlt)),17),FXn(n,BB(mMn(e,$lt),15),a),hon(e,$lt,null)}function OHn(n){n.b=null,n.a=null,n.o=null,n.q=null,n.v=null,n.w=null,n.B=null,n.p=null,n.Q=null,n.R=null,n.S=null,n.T=null,n.U=null,n.V=null,n.W=null,n.bb=null,n.eb=null,n.ab=null,n.H=null,n.db=null,n.c=null,n.d=null,n.f=null,n.n=null,n.r=null,n.s=null,n.u=null,n.G=null,n.J=null,n.e=null,n.j=null,n.i=null,n.g=null,n.k=null,n.t=null,n.F=null,n.I=null,n.L=null,n.M=null,n.O=null,n.P=null,n.$=null,n.N=null,n.Z=null,n.cb=null,n.K=null,n.D=null,n.A=null,n.C=null,n._=null,n.fb=null,n.X=null,n.Y=null,n.gb=!1,n.hb=!1}function AHn(n){var t,e,i,r,c;if(n.k!=(uSn(),Iut))return!1;if(n.j.c.length<=1)return!1;if(BB(mMn(n,(HXn(),ept)),98)==(QEn(),XIt))return!1;if(bvn(),(i=(n.q?n.q:(SQ(),SQ(),het))._b(Rgt)?BB(mMn(n,Rgt),197):BB(mMn(vW(n),_gt),197))==lvt)return!1;if(i!=fvt&&i!=hvt){if(r=Gy(MD(edn(n,Npt))),!(t=BB(mMn(n,Lpt),142))&&(t=new HR(r,r,r,r)),c=abn(n,(kUn(),ICt)),t.d+t.a+(c.gc()-1)*r>n.o.b)return!1;if(e=abn(n,oCt),t.d+t.a+(e.gc()-1)*r>n.o.b)return!1}return!0}function $Hn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(a=n.e,o=t.e,0==a)return t;if(0==o)return n;if((c=n.d)+(u=t.d)==2)return e=e0(n.a[0],UQn),i=e0(t.a[0],UQn),a==o?(w=dG(h=rbn(e,i)),0==(b=dG(jz(h,32)))?new X6(a,w):new lU(a,2,Pun(Gk(ANt,1),hQn,25,15,[w,b]))):npn(a<0?ibn(i,e):ibn(e,i));if(a==o)l=a,f=c>=u?N8(n.a,c,t.a,u):N8(t.a,u,n.a,c);else{if(0==(r=c!=u?c>u?1:-1:Msn(n.a,t.a,c)))return ODn(),eet;1==r?(l=a,f=d6(n.a,c,t.a,u)):(l=o,f=d6(t.a,u,n.a,c))}return X0(s=new lU(l,f.length,f)),s}function LHn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w;return l=qy(TD(mMn(t,(HXn(),Ogt)))),b=null,a==(ain(),Hvt)&&r.c.i==i?b=r.c:a==qvt&&r.d.i==i&&(b=r.d),(h=u)&&l&&!b?(WB(h.e,r),w=e.Math.max(Gy(MD(mMn(h.d,agt))),Gy(MD(mMn(r,agt)))),hon(h.d,agt,w)):(kUn(),f=PCt,b?f=b.j:vA(BB(mMn(i,ept),98))&&(f=a==Hvt?ICt:oCt),s=xHn(n,t,i,a,f,r),o=W5((vW(i),r)),a==Hvt?(SZ(o,BB(xq(s.j,0),11)),MZ(o,c)):(SZ(o,c),MZ(o,BB(xq(s.j,0),11))),h=new zfn(r,o,s,BB(mMn(s,(hWn(),dlt)),11),a,!b)),JCn(n.a,r,new LK(h.d,t,a)),h}function NHn(n,t){var e,i,r,c,a,u,o,s,h,f;if(h=null,n.d&&(h=BB(SJ(n.d,t),138)),!h){if(f=(c=n.a.Mh()).i,!n.d||NT(n.d)!=f){for(o=new xp,n.d&&Tcn(o,n.d),u=s=o.f.c+o.g.c;u<f;++u)i=BB(Wtn(c,u),138),(e=BB(null==(r=Ifn(n.e,i).ne())?jIn(o.f,null,i):ubn(o.g,r,i),138))&&e!=i&&(null==r?jIn(o.f,null,e):ubn(o.g,r,e));if(o.f.c+o.g.c!=f)for(a=0;a<s;++a)i=BB(Wtn(c,a),138),(e=BB(null==(r=Ifn(n.e,i).ne())?jIn(o.f,null,i):ubn(o.g,r,i),138))&&e!=i&&(null==r?jIn(o.f,null,e):ubn(o.g,r,e));n.d=o}h=BB(SJ(n.d,t),138)}return h}function xHn(n,t,e,i,r,c){var a,u,o,s,h,f;return a=null,s=i==(ain(),Hvt)?c.c:c.d,o=Wln(t),s.i==e?(a=BB(RX(n.b,s),10))||(hon(a=bXn(s,BB(mMn(e,(HXn(),ept)),98),r,H_n(s),null,s.n,s.o,o,t),(hWn(),dlt),s),VW(n.b,s,a)):(u=AEn(a=bXn((h=new Zn,f=Gy(MD(mMn(t,(HXn(),ypt))))/2,son(h,tpt,f),h),BB(mMn(e,ept),98),r,i==Hvt?-1:1,null,new Gj,new xI(0,0),o,t),e,i),hon(a,(hWn(),dlt),u),VW(n.b,u,a)),BB(mMn(t,(hWn(),Zft)),21).Fc((bDn(),lft)),vA(BB(mMn(t,(HXn(),ept)),98))?hon(t,ept,(QEn(),VIt)):hon(t,ept,(QEn(),QIt)),a}function DHn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d;OTn(t,"Orthogonal edge routing",1),s=Gy(MD(mMn(n,(HXn(),Apt)))),e=Gy(MD(mMn(n,kpt))),i=Gy(MD(mMn(n,Tpt))),l=new fX(0,e),d=0,a=new M2(n.b,0),u=null,h=null,o=null,f=null;do{f=(h=a.b<a.d.gc()?(Px(a.b<a.d.gc()),BB(a.d.Xb(a.c=a.b++),29)):null)?h.a:null,u&&(Tqn(u,d),d+=u.c.a),w=AGn(l,n,o,f,u?d+i:d),r=!u||VC(o,(dxn(),jyt)),c=!h||VC(f,(dxn(),jyt)),w>0?(b=(w-1)*e,u&&(b+=i),h&&(b+=i),b<s&&!r&&!c&&(b=s),d+=b):!r&&!c&&(d+=s),u=h,o=f}while(h);n.f.a=d,HSn(t)}function RHn(){var n;RHn=O,EAt=new Sm,kAt=x8(Qtt,sVn,2,0,6,1),SAt=i0(Bun(33,58),Bun(1,26)),PAt=i0(Bun(97,122),Bun(65,90)),IAt=Bun(48,57),TAt=i0(SAt,0),MAt=i0(PAt,IAt),CAt=i0(i0(0,Bun(1,6)),Bun(33,38)),OAt=i0(i0(IAt,Bun(65,70)),Bun(97,102)),xAt=i0(TAt,dpn("-_.!~*'()")),DAt=i0(MAt,Xwn("-_.!~*'()")),dpn(u9n),Xwn(u9n),i0(xAt,dpn(";:@&=+$,")),i0(DAt,Xwn(";:@&=+$,")),AAt=dpn(":/?#"),$At=Xwn(":/?#"),LAt=dpn("/?#"),NAt=Xwn("/?#"),(n=new Rv).a.zc("jar",n),n.a.zc("zip",n),n.a.zc("archive",n),SQ(),jAt=new Ak(n)}function _Hn(n,t){var e,i,r,c,a;if(hon(t,(qqn(),okt),0),r=BB(mMn(t,akt),86),0==t.d.b)r?(a=Gy(MD(mMn(r,fkt)))+n.a+E5(r,t),hon(t,fkt,a)):hon(t,fkt,0);else{for(e=new wg(spn(new bg(t).a.d,0));EE(e.a);)_Hn(n,BB(b3(e.a),188).c);i=BB(iL(new wg(spn(new bg(t).a.d,0))),86),c=(Gy(MD(mMn(BB(TN(new wg(spn(new bg(t).a.d,0))),86),fkt)))+Gy(MD(mMn(i,fkt))))/2,r?(a=Gy(MD(mMn(r,fkt)))+n.a+E5(r,t),hon(t,fkt,a),hon(t,okt,Gy(MD(mMn(t,fkt)))-c),CGn(n,t)):hon(t,fkt,c)}}function KHn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;u=0,b=0,o=TJ(n.f,n.f.length),c=n.d,a=n.i,i=n.a,r=n.b;do{for(l=0,s=new Wb(n.p);s.a<s.c.c.length;)f=OGn(n,BB(n0(s),10)),e=!0,(n.q==(sNn(),Tvt)||n.q==Pvt)&&(e=qy(TD(f.b))),BB(f.a,19).a<0&&e?(++l,o=TJ(n.f,n.f.length),n.d=n.d+BB(f.a,19).a,b+=c-n.d,c=n.d+BB(f.a,19).a,a=n.i,i=a0(n.a),r=a0(n.b)):(n.f=TJ(o,o.length),n.d=c,n.a=(yX(i),i?new tK(i):HB(new Wb(i))),n.b=(yX(r),r?new tK(r):HB(new Wb(r))),n.i=a);++u,h=0!=l&&qy(TD(t.Kb(new rC(iln(b),iln(u)))))}while(h)}function FHn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;return a=n.f,l=t.f,u=a==(YLn(),xEt)||a==REt,o=a==DEt||a==_Et,b=l==DEt||l==_Et,s=a==DEt||a==xEt,w=l==DEt||l==xEt,!u||l!=xEt&&l!=REt?o&&b?n.f==_Et?n:t:s&&w?(a==DEt?(f=n,h=t):(f=t,h=n),d=i.j+i.f,g=f.e+r.f,p=e.Math.max(d,g)-e.Math.min(i.j,f.e),c=(f.d+r.g-i.i)*p,v=i.i+i.g,m=h.d+r.g,c<=(e.Math.max(v,m)-e.Math.min(i.i,h.d))*(h.e+r.f-i.j)?n.f==DEt?n:t:n.f==xEt?n:t):n:n.f==REt?n:t}function BHn(n){var t,e,i,r,c,a,u,o,s,h;for(s=n.e.a.c.length,c=new Wb(n.e.a);c.a<c.c.c.length;)BB(n0(c),121).j=!1;for(n.i=x8(ANt,hQn,25,s,15,1),n.g=x8(ANt,hQn,25,s,15,1),n.n=new Np,r=0,h=new Np,u=new Wb(n.e.a);u.a<u.c.c.length;)(a=BB(n0(u),121)).d=r++,0==a.b.a.c.length&&WB(n.n,a),gun(h,a.g);for(t=0,i=new Wb(h);i.a<i.c.c.length;)(e=BB(n0(i),213)).c=t++,e.f=!1;o=h.c.length,null==n.b||n.b.length<o?(n.b=x8(xNt,qQn,25,o,15,1),n.c=x8($Nt,ZYn,25,o,16,1)):nk(n.c),n.d=h,n.p=new LN(etn(n.d.c.length)),n.j=1}function HHn(n,t){var e,i,r,c,a,u,o,s,h;if(!(t.e.c.length<=1)){for(n.f=t,n.d=BB(mMn(n.f,(rkn(),vat)),379),n.g=BB(mMn(n.f,jat),19).a,n.e=Gy(MD(mMn(n.f,mat))),n.c=Gy(MD(mMn(n.f,pat))),cX(n.b),r=new Wb(n.f.c);r.a<r.c.c.length;)i=BB(n0(r),282),y_n(n.b,i.c,i,null),y_n(n.b,i.d,i,null);for(u=n.f.e.c.length,n.a=kq(xNt,[sVn,qQn],[104,25],15,[u,u],2),s=new Wb(n.f.e);s.a<s.c.c.length;)IBn(n,o=BB(n0(s),144),n.a[o.b]);for(n.i=kq(xNt,[sVn,qQn],[104,25],15,[u,u],2),c=0;c<u;++c)for(a=0;a<u;++a)h=1/((e=n.a[c][a])*e),n.i[c][a]=h}}function qHn(n){var t,e,i,r;if(!(null==n.b||n.b.length<=2||n.a)){for(t=0,r=0;r<n.b.length;){for(t!=r?(n.b[t]=n.b[r++],n.b[t+1]=n.b[r++]):r+=2,e=n.b[t+1];r<n.b.length&&!(e+1<n.b[r]);)if(e+1==n.b[r])n.b[t+1]=n.b[r+1],e=n.b[t+1],r+=2;else if(e>=n.b[r+1])r+=2;else{if(!(e<n.b[r+1]))throw Hp(new dy("Token#compactRanges(): Internel Error: ["+n.b[t]+","+n.b[t+1]+"] ["+n.b[r]+","+n.b[r+1]+"]"));n.b[t+1]=n.b[r+1],e=n.b[t+1],r+=2}t+=2}t!=n.b.length&&(i=x8(ANt,hQn,25,t,15,1),aHn(n.b,0,i,0,t),n.b=i),n.a=!0}}function GHn(n,t){var e,i,r,c,a,u,o;for(a=gz(n.a).Kc();a.Ob();){if((c=BB(a.Pb(),17)).b.c.length>0)for(i=new tK(BB(h6(n.a,c),21)),SQ(),m$(i,new Kw(t)),r=new M2(c.b,0);r.b<r.d.gc();){switch(Px(r.b<r.d.gc()),e=BB(r.d.Xb(r.c=r.b++),70),u=-1,BB(mMn(e,(HXn(),Ydt)),272).g){case 1:u=i.c.length-1;break;case 0:u=Jjn(i);break;case 2:u=0}-1!=u&&(l1(u,i.c.length),WB((o=BB(i.c[u],243)).b.b,e),BB(mMn(vW(o.b.c.i),(hWn(),Zft)),21).Fc((bDn(),fft)),BB(mMn(vW(o.b.c.i),Zft),21).Fc(sft),fW(r),hon(e,vlt,c))}SZ(c,null),MZ(c,null)}}function zHn(n,t){var e,i,r,c;return e=new Kn,1==(r=2==(r=(i=BB(P4($V(new Rq(null,new w1(n.f,16)),e),x7(new Q,new Y,new cn,new an,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Xet),Uet]))),21)).gc())?1:0)&&QC(ldn(BB(P4(AV(i.Lc(),new Fn),Wcn(jgn(0),new en)),162).a,2),0)&&(r=0),1==(c=2==(c=(i=BB(P4($V(new Rq(null,new w1(t.f,16)),e),x7(new Q,new Y,new cn,new an,Pun(Gk(nit,1),$Vn,132,0,[Xet,Uet]))),21)).gc())?1:0)&&QC(ldn(BB(P4(AV(i.Lc(),new Bn),Wcn(jgn(0),new en)),162).a,2),0)&&(c=0),r<c?-1:r==c?0:1}function UHn(n){var t,e,i,r,c,a,u,o,s,h,f;if(o=new Np,!Lx(n,(hWn(),Wft)))return o;for(i=BB(mMn(n,Wft),15).Kc();i.Ob();)dqn(t=BB(i.Pb(),10),n),o.c[o.c.length]=t;for(r=new Wb(n.b);r.a<r.c.c.length;)for(a=new Wb(BB(n0(r),29).a);a.a<a.c.c.length;)(c=BB(n0(a),10)).k==(uSn(),Mut)&&(u=BB(mMn(c,Vft),10))&&(IZ(s=new ISn,c),qIn(s,BB(mMn(c,Qft),61)),h=BB(xq(u.j,0),11),SZ(f=new wY,s),MZ(f,h));for(e=new Wb(o);e.a<e.c.c.length;)PZ(t=BB(n0(e),10),BB(xq(n.b,n.b.c.length-1),29));return o}function XHn(n){var t,e,i,r,c,a,u,o,s,h,f,l;for(c=qy(TD(ZAn(t=WJ(n),(HXn(),wgt)))),h=0,r=0,s=new AL((!n.e&&(n.e=new h_(KOt,n,7,4)),n.e));s.e!=s.i.gc();)a=(u=QCn(o=BB(kpn(s),79)))&&c&&qy(TD(ZAn(o,dgt))),l=PTn(BB(Wtn((!o.c&&(o.c=new h_(_Ot,o,5,8)),o.c),0),82)),u&&a?++r:u&&!a?++h:JJ(l)==t||l==t?++r:++h;for(i=new AL((!n.d&&(n.d=new h_(KOt,n,8,5)),n.d));i.e!=i.i.gc();)a=(u=QCn(e=BB(kpn(i),79)))&&c&&qy(TD(ZAn(e,dgt))),f=PTn(BB(Wtn((!e.b&&(e.b=new h_(_Ot,e,4,7)),e.b),0),82)),u&&a?++h:u&&!a?++r:JJ(f)==t||f==t?++h:++r;return h-r}function WHn(n,t){var e,i,r,c,a,u,o,s,h;if(OTn(t,"Edge splitting",1),n.b.c.length<=2)HSn(t);else{for(Px((c=new M2(n.b,0)).b<c.d.gc()),a=BB(c.d.Xb(c.c=c.b++),29);c.b<c.d.gc();)for(r=a,Px(c.b<c.d.gc()),a=BB(c.d.Xb(c.c=c.b++),29),u=new Wb(r.a);u.a<u.c.c.length;)for(o=new Wb(BB(n0(u),10).j);o.a<o.c.c.length;)for(i=new Wb(BB(n0(o),11).g);i.a<i.c.c.length;)(s=(e=BB(n0(i),17)).d.i.c)!=r&&s!=a&&zxn(e,(Bl(h=new $vn(n),(uSn(),Put)),hon(h,(hWn(),dlt),e),hon(h,(HXn(),ept),(QEn(),XIt)),PZ(h,a),h));HSn(t)}}function VHn(n,t){var e,i,r,c,a,u,o,s,h;if((a=null!=t.p&&!t.b)||OTn(t,aZn,1),c=1/(e=BB(mMn(n,(hWn(),Mlt)),15)).gc(),t.n)for(OH(t,"ELK Layered uses the following "+e.gc()+" modules:"),h=0,s=e.Kc();s.Ob();)OH(t," Slot "+(h<10?"0":"")+h+++": "+nE(tsn(BB(s.Pb(),51))));for(o=e.Kc();o.Ob();)BB(o.Pb(),51).pf(n,mcn(t,c));for(r=new Wb(n.b);r.a<r.c.c.length;)i=BB(n0(r),29),gun(n.a,i.a),i.a.c=x8(Ant,HWn,1,0,5,1);for(u=new Wb(n.a);u.a<u.c.c.length;)PZ(BB(n0(u),10),null);n.b.c=x8(Ant,HWn,1,0,5,1),a||HSn(t)}function QHn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;r=Gy(MD(mMn(t,(HXn(),Dgt)))),l=4,c=3,j=20/(k=BB(mMn(t,xpt),19).a),b=!1,s=0,u=DWn;do{for(a=1!=s,f=0!=s,E=0,v=0,y=(g=n.a).length;v<y;++v)(w=g[v]).f=null,Bzn(n,w,a,f,r),E+=e.Math.abs(w.a);do{o=UKn(n,t)}while(o);for(p=0,m=(d=n.a).length;p<m;++p)if(0!=(i=wU(w=d[p]).a))for(h=new Wb(w.e);h.a<h.c.c.length;)BB(n0(h),10).n.b+=i;0==s||1==s?--l<=0&&(E<u||-l>k)?(s=2,u=DWn):0==s?(s=1,u=E):(s=0,u=E):(b=E>=u||u-E<j,u=E,b&&--c)}while(!(b&&c<=0))}function YHn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w;for(w=new xp,c=n.a.ec().Kc();c.Ob();)VW(w,i=BB(c.Pb(),168),e.Je(i));for(yX(n),m$(a=n?new tK(n):HB(n.a.ec().Kc()),new Ew(w)),u=S4(a),o=new I$(t),jIn((b=new xp).f,t,o);0!=u.a.gc();){for(s=null,h=null,f=null,r=u.a.ec().Kc();r.Ob();)if(i=BB(r.Pb(),168),Gy(MD(qC(AY(w.f,i))))<=RQn){if(hU(b,i.a)&&!hU(b,i.b)){h=i.b,f=i.a,s=i;break}if(hU(b,i.b)&&!hU(b,i.a)){h=i.a,f=i.b,s=i;break}}if(!s)break;l=new I$(h),WB(BB(qC(AY(b.f,f)),221).a,l),jIn(b.f,h,l),u.a.Bc(s)}return o}function JHn(n,t,e){var i,r,c,a,u,o,s,h;for(OTn(e,"Depth-first cycle removal",1),o=(s=t.a).c.length,n.c=new Np,n.d=x8($Nt,ZYn,25,o,16,1),n.a=x8($Nt,ZYn,25,o,16,1),n.b=new Np,c=0,u=new Wb(s);u.a<u.c.c.length;)(a=BB(n0(u),10)).p=c,h3(fbn(a))&&WB(n.c,a),++c;for(h=new Wb(n.c);h.a<h.c.c.length;)GPn(n,BB(n0(h),10));for(r=0;r<o;r++)n.d[r]||(l1(r,s.c.length),GPn(n,BB(s.c[r],10)));for(i=new Wb(n.b);i.a<i.c.c.length;)tBn(BB(n0(i),17),!0),hon(t,(hWn(),qft),(hN(),!0));n.c=null,n.d=null,n.a=null,n.b=null,HSn(e)}function ZHn(n,t){var e,i,r,c,a,u,o;for(n.a.c=x8(Ant,HWn,1,0,5,1),i=spn(t.b,0);i.b!=i.d.c;)0==(e=BB(b3(i),86)).b.b&&(hon(e,(qqn(),dkt),(hN(),!0)),WB(n.a,e));switch(n.a.c.length){case 0:hon(r=new csn(0,t,"DUMMY_ROOT"),(qqn(),dkt),(hN(),!0)),hon(r,ekt,!0),DH(t.b,r);break;case 1:break;default:for(c=new csn(0,t,"SUPER_ROOT"),u=new Wb(n.a);u.a<u.c.c.length;)hon(o=new UQ(c,a=BB(n0(u),86)),(qqn(),ekt),(hN(),!0)),DH(c.a.a,o),DH(c.d,o),DH(a.b,o),hon(a,dkt,!1);hon(c,(qqn(),dkt),(hN(),!0)),hon(c,ekt,!0),DH(t.b,c)}}function nqn(n,t){var i,r,c,a,u,o;return jDn(),a=t.c-(n.c+n.b),c=n.c-(t.c+t.b),u=n.d-(t.d+t.a),i=t.d-(n.d+n.a),r=e.Math.max(c,a),o=e.Math.max(u,i),h$(),rin(A3n),(e.Math.abs(r)<=A3n||0==r||isNaN(r)&&isNaN(0)?0:r<0?-1:r>0?1:zO(isNaN(r),isNaN(0)))>=0^(rin(A3n),(e.Math.abs(o)<=A3n||0==o||isNaN(o)&&isNaN(0)?0:o<0?-1:o>0?1:zO(isNaN(o),isNaN(0)))>=0)?e.Math.max(o,r):(rin(A3n),(e.Math.abs(r)<=A3n||0==r||isNaN(r)&&isNaN(0)?0:r<0?-1:r>0?1:zO(isNaN(r),isNaN(0)))>0?e.Math.sqrt(o*o+r*r):-e.Math.sqrt(o*o+r*r))}function tqn(n,t){var e,i,r,c,a;if(t)if(!n.a&&(n.a=new Kv),2!=n.e)if(1!=t.e)0!=(a=n.a.a.c.length)?0!=(c=BB(bW(n.a,a-1),117)).e&&10!=c.e||0!=t.e&&10!=t.e?Iv(n.a,t):(0==t.e||t.bm().length,0==c.e?(e=new Pk,(i=c._l())>=BQn?cO(e,Xln(i)):NX(e,i&QVn),c=new vJ(10,null,0),kU(n.a,c,a-1)):(c.bm().length,cO(e=new Pk,c.bm())),0==t.e?(i=t._l())>=BQn?cO(e,Xln(i)):NX(e,i&QVn):cO(e,t.bm()),BB(c,521).b=e.a):Iv(n.a,t);else for(r=0;r<t.em();r++)tqn(n,t.am(r));else Iv(n.a,t)}function eqn(n){var t,e,i,r,c;return null!=n.g?n.g:n.a<32?(n.g=DUn(fan(n.f),IJ(n.e)),n.g):(r=qXn((!n.c&&(n.c=yhn(n.f)),n.c),0),0==n.e?r:(t=(!n.c&&(n.c=yhn(n.f)),n.c).e<0?2:1,e=r.length,i=-n.e+e-t,(c=new Ik).a+=""+r,n.e>0&&i>=-6?i>=0?kZ(c,e-IJ(n.e),String.fromCharCode(46)):(c.a=fx(c.a,0,t-1)+"0."+nO(c.a,t-1),kZ(c,t+1,Bdn(qtt,0,-IJ(i)-1))):(e-t>=1&&(kZ(c,t,String.fromCharCode(46)),++e),kZ(c,e,String.fromCharCode(69)),i>0&&kZ(c,++e,String.fromCharCode(43)),kZ(c,++e,""+vz(fan(i)))),n.g=c.a,n.g))}function iqn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(!e.dc()){for(a=0,h=0,l=BB((i=e.Kc()).Pb(),19).a;a<t.f;){if(a==l&&(h=0,l=i.Ob()?BB(i.Pb(),19).a:t.f+1),a!=h)for(b=BB(xq(n.b,a),29),f=BB(xq(n.b,h),29),s=new Wb(a0(b.a));s.a<s.c.c.length;)if(Qyn(o=BB(n0(s),10),f.a.c.length,f),0==h)for(c=new Wb(a0(fbn(o)));c.a<c.c.c.length;)tBn(r=BB(n0(c),17),!0),hon(n,(hWn(),qft),(hN(),!0)),iGn(n,r,1);++h,++a}for(u=new M2(n.b,0);u.b<u.d.gc();)Px(u.b<u.d.gc()),0==BB(u.d.Xb(u.c=u.b++),29).a.c.length&&fW(u)}}function rqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(h=(a=t.b).o,o=a.d,i=Gy(MD(gpn(a,(HXn(),ypt)))),r=Gy(MD(gpn(a,jpt))),s=Gy(MD(gpn(a,$pt))),rH(u=new fm,o.d,o.c,o.a,o.b),l=MRn(t,i,r,s),p=new Wb(t.d);p.a<p.c.c.length;){for(w=(g=BB(n0(p),101)).f.a.ec().Kc();w.Ob();)c=(b=BB(w.Pb(),409)).a,f=ETn(b),v=new km,bTn(b,b.c,l,v),FMn(b,f,l,v),bTn(b,b.d,l,v),e=v,e=n.Uf(b,f,e),yQ(c.a),Frn(c.a,e),JT(new Rq(null,new w1(e,16)),new wP(h,u));(d=g.i)&&(aTn(g,d,l,r),pgn(h,u,m=new wA(d.g)),UR(m,d.j),pgn(h,u,m))}rH(o,u.d,u.c,u.a,u.b)}function cqn(n,t,e){var i,r,c;if((r=BB(mMn(t,(HXn(),Pdt)),275))!=(JMn(),cft)){switch(OTn(e,"Horizontal Compaction",1),n.a=t,Vk(i=new yOn(((c=new C7).d=t,c.c=BB(mMn(c.d,Zdt),218),UDn(c),SGn(c),sRn(c),c.a)),n.b),1===BB(mMn(t,Sdt),422).g?Wk(i,new grn(n.a)):Wk(i,(IQ(),fit)),r.g){case 1:I$n(i);break;case 2:I$n(Tzn(i,(Ffn(),FPt)));break;case 3:I$n(Uk(Tzn(I$n(i),(Ffn(),FPt)),new gr));break;case 4:I$n(Uk(Tzn(I$n(i),(Ffn(),FPt)),new kd(c)));break;case 5:I$n(Xk(i,wst))}Tzn(i,(Ffn(),KPt)),i.e=!0,Lzn(c),HSn(e)}}function aqn(n,t,e,i,r,c,a,u){var o,s,h,f;switch(o=u6(Pun(Gk(FEt,1),HWn,220,0,[t,e,i,r])),f=null,n.b.g){case 1:f=u6(Pun(Gk(tEt,1),HWn,526,0,[new Ja,new Qa,new Ya]));break;case 0:f=u6(Pun(Gk(tEt,1),HWn,526,0,[new Ya,new Qa,new Ja]));break;case 2:f=u6(Pun(Gk(tEt,1),HWn,526,0,[new Qa,new Ja,new Ya]))}for(h=new Wb(f);h.a<h.c.c.length;)s=BB(n0(h),526),o.c.length>1&&(o=s.mg(o,n.a,u));return 1==o.c.length?BB(xq(o,o.c.length-1),220):2==o.c.length?FHn((l1(0,o.c.length),BB(o.c[0],220)),(l1(1,o.c.length),BB(o.c[1],220)),a,c):null}function uqn(n){var t,i,r,c,a,u;for(Otn(n.a,new nt),i=new Wb(n.a);i.a<i.c.c.length;)t=BB(n0(i),221),r=XR(B$(BB(n.b,65).c),BB(t.b,65).c),ect?(u=BB(n.b,65).b,a=BB(t.b,65).b,e.Math.abs(r.a)>=e.Math.abs(r.b)?(r.b=0,a.d+a.a>u.d&&a.d<u.d+u.a&&NH(r,e.Math.max(u.c-(a.c+a.b),a.c-(u.c+u.b)))):(r.a=0,a.c+a.b>u.c&&a.c<u.c+u.b&&NH(r,e.Math.max(u.d-(a.d+a.a),a.d-(u.d+u.a))))):NH(r,TFn(BB(n.b,65),BB(t.b,65))),c=e.Math.sqrt(r.a*r.a+r.b*r.b),NH(r,c=HEn(Wrt,t,c,r)),LG(BB(t.b,65),r),Otn(t.a,new Aw(r)),BB(Wrt.b,65),_8(Wrt,Vrt,t)}function oqn(n){var t,i,r,c,a,u,o,s,f,l,b,w;for(n.f=new Fv,o=0,r=0,c=new Wb(n.e.b);c.a<c.c.c.length;)for(u=new Wb(BB(n0(c),29).a);u.a<u.c.c.length;){for((a=BB(n0(u),10)).p=o++,i=new oz(ZL(lbn(a).a.Kc(),new h));dAn(i);)BB(U5(i),17).p=r++;for(t=AHn(a),l=new Wb(a.j);l.a<l.c.c.length;)f=BB(n0(l),11),t&&(w=f.a.b)!=e.Math.floor(w)&&(s=w-j2(fan(e.Math.round(w))),f.a.b-=s),(b=f.n.b+f.a.b)!=e.Math.floor(b)&&(s=b-j2(fan(e.Math.round(b))),f.n.b-=s)}n.g=o,n.b=r,n.i=x8(eyt,HWn,401,o,0,1),n.c=x8(Jmt,HWn,649,r,0,1),n.d.a.$b()}function sqn(n){var t,e,i,r,c,a,u,o,s;if(n.ej())if(o=n.fj(),n.i>0){if(t=new DC(n.i,n.g),c=(e=n.i)<100?null:new Fj(e),n.ij())for(i=0;i<n.i;++i)a=n.g[i],c=n.kj(a,c);if(a6(n),r=1==e?n.Zi(4,Wtn(t,0),null,0,o):n.Zi(6,t,null,-1,o),n.bj()){for(i=new ax(t);i.e!=i.i.gc();)c=n.dj(jpn(i),c);c?(c.Ei(r),c.Fi()):n.$i(r)}else c?(c.Ei(r),c.Fi()):n.$i(r)}else a6(n),n.$i(n.Zi(6,(SQ(),set),null,-1,o));else if(n.bj())if(n.i>0){for(u=n.g,s=n.i,a6(n),c=s<100?null:new Fj(s),i=0;i<s;++i)a=u[i],c=n.dj(a,c);c&&c.Fi()}else a6(n);else a6(n)}function hqn(n,t,i){var r,c,a,u,o,s,h,f,l;for(Kan(this),i==(dJ(),Lyt)?TU(this.r,n):TU(this.w,n),f=RQn,h=_Qn,u=t.a.ec().Kc();u.Ob();)c=BB(u.Pb(),46),o=BB(c.a,455),(s=(r=BB(c.b,17)).c)==n&&(s=r.d),TU(o==Lyt?this.r:this.w,s),l=(kUn(),yCt).Hc(s.j)?Gy(MD(mMn(s,(hWn(),Llt)))):Aon(Pun(Gk(PMt,1),sVn,8,0,[s.i.n,s.n,s.a])).b,f=e.Math.min(f,l),h=e.Math.max(h,l);for(XMn(this,(kUn(),yCt).Hc(n.j)?Gy(MD(mMn(n,(hWn(),Llt)))):Aon(Pun(Gk(PMt,1),sVn,8,0,[n.i.n,n.n,n.a])).b,f,h),a=t.a.ec().Kc();a.Ob();)c=BB(a.Pb(),46),tPn(this,BB(c.b,17));this.o=!1}function fqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;return e=8191&n.l,i=n.l>>13|(15&n.m)<<9,r=n.m>>4&8191,c=n.m>>17|(255&n.h)<<5,a=(1048320&n.h)>>8,g=i*(u=8191&t.l),p=r*u,v=c*u,m=a*u,0!=(o=t.l>>13|(15&t.m)<<9)&&(g+=e*o,p+=i*o,v+=r*o,m+=c*o),0!=(s=t.m>>4&8191)&&(p+=e*s,v+=i*s,m+=r*s),0!=(h=t.m>>17|(255&t.h)<<5)&&(v+=e*h,m+=i*h),0!=(f=(1048320&t.h)>>8)&&(m+=e*f),b=((d=e*u)>>22)+(g>>9)+((262143&p)<<4)+((31&v)<<17),w=(p>>18)+(v>>5)+((4095&m)<<8),w+=(b+=(l=(d&SQn)+((511&g)<<13))>>22)>>22,M$(l&=SQn,b&=SQn,w&=PQn)}function lqn(n){var t,i,r,c,a,u,o;if(0!=(o=BB(xq(n.j,0),11)).g.c.length&&0!=o.e.c.length)throw Hp(new Fy("Interactive layout does not support NORTH/SOUTH ports with incoming _and_ outgoing edges."));if(0!=o.g.c.length){for(a=RQn,i=new Wb(o.g);i.a<i.c.c.length;)t=BB(n0(i),17),r=BB(mMn(u=t.d.i,(HXn(),Igt)),142),a=e.Math.min(a,u.n.a-r.b);return new qf(yX(a))}if(0!=o.e.c.length){for(c=_Qn,i=new Wb(o.e);i.a<i.c.c.length;)t=BB(n0(i),17),r=BB(mMn(u=t.c.i,(HXn(),Igt)),142),c=e.Math.max(c,u.n.a+u.o.a+r.c);return new qf(yX(c))}return iy(),iy(),Ont}function bqn(n,t){var e,i,r,c,a,u;if(n.Fk()){if(n.i>4){if(!n.wj(t))return!1;if(n.rk()){if(u=(e=(i=BB(t,49)).Ug())==n.e&&(n.Dk()?i.Og(i.Vg(),n.zk())==n.Ak():-1-i.Vg()==n.aj()),n.Ek()&&!u&&!e&&i.Zg())for(r=0;r<n.i;++r)if(GC(n.Gk(BB(n.g[r],56)))===GC(t))return!0;return u}if(n.Dk()&&!n.Ck()){if(GC(c=BB(t,56).ah(Ivn(BB(n.ak(),18))))===GC(n.e))return!0;if(null==c||!BB(c,56).kh())return!1}}if(a=Sjn(n,t),n.Ek()&&!a)for(r=0;r<n.i;++r)if(GC(i=n.Gk(BB(n.g[r],56)))===GC(t))return!0;return a}return Sjn(n,t)}function wqn(n,t){var e,i,r,c,a,u,o,s,h,f,l;for(h=new Np,l=new Rv,a=t.b,r=0;r<a.c.length;r++){for(s=(l1(r,a.c.length),BB(a.c[r],29)).a,h.c=x8(Ant,HWn,1,0,5,1),c=0;c<s.c.length;c++)(u=n.a[r][c]).p=c,u.k==(uSn(),Cut)&&(h.c[h.c.length]=u),c5(BB(xq(t.b,r),29).a,c,u),u.j.c=x8(Ant,HWn,1,0,5,1),gun(u.j,BB(BB(xq(n.b,r),15).Xb(c),14)),L_(BB(mMn(u,(HXn(),ept)),98))||hon(u,ept,(QEn(),UIt));for(i=new Wb(h);i.a<i.c.c.length;)f=QRn(e=BB(n0(i),10)),l.a.zc(f,l),l.a.zc(e,l)}for(o=l.a.ec().Kc();o.Ob();)u=BB(o.Pb(),10),SQ(),m$(u.j,(zsn(),sst)),u.i=!0,eCn(u)}function dqn(n,t){var e,i,r,c,a,u,o,s,h,f;if(h=BB(mMn(n,(hWn(),Qft)),61),i=BB(xq(n.j,0),11),h==(kUn(),sCt)?qIn(i,SCt):h==SCt&&qIn(i,sCt),BB(mMn(t,(HXn(),Fgt)),174).Hc((mdn(),KCt))){if(o=Gy(MD(mMn(n,Ipt))),s=Gy(MD(mMn(n,Cpt))),a=Gy(MD(mMn(n,Spt))),(u=BB(mMn(t,cpt),21)).Hc((lCn(),eCt)))for(e=s,f=n.o.a/2-i.n.a,c=new Wb(i.f);c.a<c.c.c.length;)(r=BB(n0(c),70)).n.b=e,r.n.a=f-r.o.a/2,e+=r.o.b+a;else if(u.Hc(rCt))for(c=new Wb(i.f);c.a<c.c.c.length;)(r=BB(n0(c),70)).n.a=o+n.o.a-i.n.a;f0(new Pw((gM(),new HV(t,!1,!1,new Ft))),new KK(null,n,!1))}}function gqn(n,t){var i,r,c,a,u,o,s;if(0!=t.c.length){for(SQ(),yG(t.c,t.c.length,null),r=BB(n0(c=new Wb(t)),145);c.a<c.c.c.length;)i=BB(n0(c),145),!aen(r.e.c,i.e.c)||_dn(BD(r.e).b,i.e.d)||_dn(BD(i.e).b,r.e.d)?(eFn(n,r),r=i):(gun(r.k,i.k),gun(r.b,i.b),gun(r.c,i.c),Frn(r.i,i.i),gun(r.d,i.d),gun(r.j,i.j),a=e.Math.min(r.e.c,i.e.c),u=e.Math.min(r.e.d,i.e.d),o=e.Math.max(r.e.c+r.e.b,i.e.c+i.e.b)-a,s=e.Math.max(r.e.d+r.e.a,i.e.d+i.e.a)-u,xH(r.e,a,u,o,s),t0(r.f,i.f),!r.a&&(r.a=i.a),gun(r.g,i.g),WB(r.g,i));eFn(n,r)}}function pqn(n,t,e,i){var r,c,a,u,o,s;if((u=n.j)==(kUn(),PCt)&&t!=(QEn(),QIt)&&t!=(QEn(),YIt)&&(qIn(n,u=zKn(n,e)),!(n.q?n.q:(SQ(),SQ(),het))._b((HXn(),tpt))&&u!=PCt&&(0!=n.n.a||0!=n.n.b)&&hon(n,tpt,jkn(n,u))),t==(QEn(),WIt)){switch(s=0,u.g){case 1:case 3:(c=n.i.o.a)>0&&(s=n.n.a/c);break;case 2:case 4:(r=n.i.o.b)>0&&(s=n.n.b/r)}hon(n,(hWn(),Tlt),s)}if(o=n.o,a=n.a,i)a.a=i.a,a.b=i.b,n.d=!0;else if(t!=QIt&&t!=YIt&&u!=PCt)switch(u.g){case 1:a.a=o.a/2;break;case 2:a.a=o.a,a.b=o.b/2;break;case 3:a.a=o.a/2,a.b=o.b;break;case 4:a.b=o.b/2}else a.a=o.a/2,a.b=o.b/2}function vqn(n){var t,e,i,r,c,a,u,o,s,h;if(n.ej())if(h=n.Vi(),o=n.fj(),h>0)if(t=new jcn(n.Gi()),c=(e=h)<100?null:new Fj(e),JD(n,e,t.g),r=1==e?n.Zi(4,Wtn(t,0),null,0,o):n.Zi(6,t,null,-1,o),n.bj()){for(i=new AL(t);i.e!=i.i.gc();)c=n.dj(kpn(i),c);c?(c.Ei(r),c.Fi()):n.$i(r)}else c?(c.Ei(r),c.Fi()):n.$i(r);else JD(n,n.Vi(),n.Wi()),n.$i(n.Zi(6,(SQ(),set),null,-1,o));else if(n.bj())if((h=n.Vi())>0){for(u=n.Wi(),s=h,JD(n,h,u),c=s<100?null:new Fj(s),i=0;i<s;++i)a=u[i],c=n.dj(a,c);c&&c.Fi()}else JD(n,n.Vi(),n.Wi());else JD(n,n.Vi(),n.Wi())}function mqn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;for(u=new Wb(t);u.a<u.c.c.length;)(c=BB(n0(u),233)).e=null,c.c=0;for(o=null,a=new Wb(t);a.a<a.c.c.length;)if(f=(c=BB(n0(a),233)).d[0],!e||f.k==(uSn(),Iut)){for(b=BB(mMn(f,(hWn(),clt)),15).Kc();b.Ob();)l=BB(b.Pb(),10),e&&l.k!=(uSn(),Iut)||((!c.e&&(c.e=new Np),c.e).Fc(n.b[l.c.p][l.p]),++n.b[l.c.p][l.p].c);if(!e&&f.k==(uSn(),Iut)){if(o)for(h=BB(h6(n.d,o),21).Kc();h.Ob();)for(s=BB(h.Pb(),10),r=BB(h6(n.d,f),21).Kc();r.Ob();)i=BB(r.Pb(),10),UB(n.b[s.c.p][s.p]).Fc(n.b[i.c.p][i.p]),++n.b[i.c.p][i.p].c;o=f}}}function yqn(n,t){var e,i,r,c,a,u,o;for(e=0,o=new Np,c=new Wb(t);c.a<c.c.c.length;){switch(r=BB(n0(c),11),nhn(n.b,n.d[r.p]),o.c=x8(Ant,HWn,1,0,5,1),r.i.k.g){case 0:Otn(BB(mMn(r,(hWn(),Elt)),10).j,new Zd(o));break;case 1:S$(Qon(AV(new Rq(null,new w1(r.i.j,16)),new ng(r))),new tg(o));break;case 3:WB(o,new rC(BB(mMn(r,(hWn(),dlt)),11),iln(r.e.c.length+r.g.c.length)))}for(u=new Wb(o);u.a<u.c.c.length;)a=BB(n0(u),46),(i=ME(n,BB(a.a,11)))>n.d[r.p]&&(e+=n5(n.b,i)*BB(a.b,19).a,d3(n.a,iln(i)));for(;!Wy(n.a);)Mnn(n.b,BB(dU(n.a),19).a)}return e}function kqn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w;for((f=new wA(BB(ZAn(n,(SMn(),HMt)),8))).a=e.Math.max(f.a-i.b-i.c,0),f.b=e.Math.max(f.b-i.d-i.a,0),(null==(c=MD(ZAn(n,DMt)))||(kW(c),c<=0))&&(c=1.3),u=new Np,l=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));l.e!=l.i.gc();)a=new zx(BB(kpn(l),33)),u.c[u.c.length]=a;switch(BB(ZAn(n,RMt),311).g){case 3:w=aFn(u,t,f.a,f.b,(s=r,kW(c),s));break;case 1:w=vBn(u,t,f.a,f.b,(h=r,kW(c),h));break;default:w=Mqn(u,t,f.a,f.b,(o=r,kW(c),o))}_Un(n,(b=yXn(new Gtn(w),t,i,f.a,f.b,r,(kW(c),c))).a,b.b,!1,!0)}function jqn(n,t){var e,i,r,c;c=new tK((e=t.b).j),r=0,(i=e.j).c=x8(Ant,HWn,1,0,5,1),eX(BB(gan(n.b,(kUn(),sCt),(Irn(),Rst)),15),e),r=Jmn(c,r,new xr,i),eX(BB(gan(n.b,sCt,Dst),15),e),r=Jmn(c,r,new Nr,i),eX(BB(gan(n.b,sCt,xst),15),e),eX(BB(gan(n.b,oCt,Rst),15),e),eX(BB(gan(n.b,oCt,Dst),15),e),r=Jmn(c,r,new Dr,i),eX(BB(gan(n.b,oCt,xst),15),e),eX(BB(gan(n.b,SCt,Rst),15),e),r=Jmn(c,r,new Rr,i),eX(BB(gan(n.b,SCt,Dst),15),e),r=Jmn(c,r,new _r,i),eX(BB(gan(n.b,SCt,xst),15),e),eX(BB(gan(n.b,ICt,Rst),15),e),r=Jmn(c,r,new Qr,i),eX(BB(gan(n.b,ICt,Dst),15),e),eX(BB(gan(n.b,ICt,xst),15),e)}function Eqn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(OTn(t,"Layer size calculation",1),f=RQn,h=_Qn,c=!1,o=new Wb(n.b);o.a<o.c.c.length;)if((s=(u=BB(n0(o),29)).c).a=0,s.b=0,0!=u.a.c.length){for(c=!0,b=new Wb(u.a);b.a<b.c.c.length;)d=(l=BB(n0(b),10)).o,w=l.d,s.a=e.Math.max(s.a,d.a+w.b+w.c);g=(r=BB(xq(u.a,0),10)).n.b-r.d.d,r.k==(uSn(),Mut)&&(g-=BB(mMn(n,(HXn(),Lpt)),142).d),i=(a=BB(xq(u.a,u.a.c.length-1),10)).n.b+a.o.b+a.d.a,a.k==Mut&&(i+=BB(mMn(n,(HXn(),Lpt)),142).a),s.b=i-g,f=e.Math.min(f,g),h=e.Math.max(h,i)}c||(f=0,h=0),n.f.b=h-f,n.c.b-=f,HSn(t)}function Tqn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;for(c=0,a=0,s=new Wb(n.a);s.a<s.c.c.length;)u=BB(n0(s),10),c=e.Math.max(c,u.d.b),a=e.Math.max(a,u.d.c);for(o=new Wb(n.a);o.a<o.c.c.length;){switch(u=BB(n0(o),10),BB(mMn(u,(HXn(),kdt)),248).g){case 1:w=0;break;case 2:w=1;break;case 5:w=.5;break;default:for(i=0,f=0,b=new Wb(u.j);b.a<b.c.c.length;)0==(l=BB(n0(b),11)).e.c.length||++i,0==l.g.c.length||++f;w=i+f==0?.5:f/(i+f)}g=n.c,h=u.o.a,p=(g.a-h)*w,w>.5?p-=2*a*(w-.5):w<.5&&(p+=2*c*(.5-w)),p<(r=u.d.b)&&(p=r),d=u.d.c,p>g.a-d-h&&(p=g.a-d-h),u.n.a=t+p}}function Mqn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(u=x8(xNt,qQn,25,n.c.length,15,1),ikn(l=new Xz(new Uu),n),s=0,b=new Np;0!=l.b.c.length;)if(a=BB(0==l.b.c.length?null:xq(l.b,0),157),s>1&&iG(a)*eG(a)/2>u[0]){for(c=0;c<b.c.length-1&&iG(a)*eG(a)/2>u[c];)++c;f=new Gtn(new s1(b,0,c+1)),h=iG(a)/eG(a),o=yXn(f,t,new bm,e,i,r,h),UR(kO(f.e),o),F8(eMn(l,f)),ikn(l,new s1(b,c+1,b.c.length)),b.c=x8(Ant,HWn,1,0,5,1),s=0,jG(u,u.length,0)}else null!=(0==l.b.c.length?null:xq(l.b,0))&&hrn(l,0),s>0&&(u[s]=u[s-1]),u[s]+=iG(a)*eG(a),++s,b.c[b.c.length]=a;return b}function Sqn(n){var t,e,i;if((e=BB(mMn(n,(HXn(),kgt)),163))==(Tbn(),Flt)){for(t=new oz(ZL(fbn(n).a.Kc(),new h));dAn(t);)if(!X5(BB(U5(t),17)))throw Hp(new rk(P1n+gyn(n)+"' has its layer constraint set to FIRST_SEPARATE, but has at least one incoming edge. FIRST_SEPARATE nodes must not have incoming edges."))}else if(e==Hlt)for(i=new oz(ZL(lbn(n).a.Kc(),new h));dAn(i);)if(!X5(BB(U5(i),17)))throw Hp(new rk(P1n+gyn(n)+"' has its layer constraint set to LAST_SEPARATE, but has at least one outgoing edge. LAST_SEPARATE nodes must not have outgoing edges."))}function Pqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;for(OTn(t,"Label dummy removal",1),i=Gy(MD(mMn(n,(HXn(),jpt)))),r=Gy(MD(mMn(n,Spt))),o=BB(mMn(n,Udt),103),u=new Wb(n.b);u.a<u.c.c.length;)for(h=new M2(BB(n0(u),29).a,0);h.b<h.d.gc();)Px(h.b<h.d.gc()),(s=BB(h.d.Xb(h.c=h.b++),10)).k==(uSn(),Sut)&&(f=BB(mMn(s,(hWn(),dlt)),17),b=Gy(MD(mMn(f,agt))),a=GC(mMn(s,ult))===GC((Xyn(),EIt)),e=new wA(s.n),a&&(e.b+=b+i),c=new xI(s.o.a,s.o.b-b-i),l=BB(mMn(s,Plt),15),o==(Ffn(),HPt)||o==_Pt?ADn(l,e,r,c,a,o):qhn(l,e,r,c),gun(f.b,l),rGn(s,GC(mMn(n,Zdt))===GC((Mbn(),YPt))),fW(h));HSn(t)}function Iqn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y;for(u=new Np,r=new Wb(t.a);r.a<r.c.c.length;)for(a=new Wb(BB(n0(r),10).j);a.a<a.c.c.length;){for(s=null,m=0,y=(v=Z0((c=BB(n0(a),11)).g)).length;m<y;++m)wan((p=v[m]).d.i,e)||((g=LHn(n,t,e,p,p.c,(ain(),qvt),s))!=s&&(u.c[u.c.length]=g),g.c&&(s=g));for(o=null,w=0,d=(b=Z0(c.e)).length;w<d;++w)wan((l=b[w]).c.i,e)||((g=LHn(n,t,e,l,l.d,(ain(),Hvt),o))!=o&&(u.c[u.c.length]=g),g.c&&(o=g))}for(f=new Wb(u);f.a<f.c.c.length;)h=BB(n0(f),441),-1!=E7(t.a,h.a,0)||WB(t.a,h.a),h.c&&(i.c[i.c.length]=h)}function Cqn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w;for(OTn(e,"Interactive cycle breaking",1),h=new Np,l=new Wb(t.a);l.a<l.c.c.length;)for((f=BB(n0(l),10)).p=1,b=Fjn(f).a,s=xwn(f,(ain(),qvt)).Kc();s.Ob();)for(c=new Wb(BB(s.Pb(),11).g);c.a<c.c.c.length;)(w=(i=BB(n0(c),17)).d.i)!=f&&Fjn(w).a<b&&(h.c[h.c.length]=i);for(a=new Wb(h);a.a<a.c.c.length;)tBn(i=BB(n0(a),17),!0);for(h.c=x8(Ant,HWn,1,0,5,1),o=new Wb(t.a);o.a<o.c.c.length;)(u=BB(n0(o),10)).p>0&&lPn(n,u,h);for(r=new Wb(h);r.a<r.c.c.length;)tBn(i=BB(n0(r),17),!0);h.c=x8(Ant,HWn,1,0,5,1),HSn(e)}function Oqn(n,t){var e,i,r,c,a,u,o,s,h;return s="",0==t.length?n.de(XVn,zVn,-1,-1):(m_((h=RMn(t)).substr(0,3),"at ")&&(h=h.substr(3)),-1==(a=(h=h.replace(/\[.*?\]/g,"")).indexOf("("))?-1==(a=h.indexOf("@"))?(s=h,h=""):(s=RMn(h.substr(a+1)),h=RMn(h.substr(0,a))):(e=h.indexOf(")",a),s=h.substr(a+1,e-(a+1)),h=RMn(h.substr(0,a))),-1!=(a=GO(h,YTn(46)))&&(h=h.substr(a+1)),(0==h.length||m_(h,"Anonymous function"))&&(h=zVn),u=mN(s,YTn(58)),r=M_(s,YTn(58),u-1),o=-1,i=-1,c=XVn,-1!=u&&-1!=r&&(c=s.substr(0,r),o=hx(s.substr(r+1,u-(r+1))),i=hx(s.substr(u+1))),n.de(c,h,o,i))}function Aqn(n,t,e){var i,r,c,a,u,o;if(0==t.l&&0==t.m&&0==t.h)throw Hp(new Oy("divide by zero"));if(0==n.l&&0==n.m&&0==n.h)return e&&(ltt=M$(0,0,0)),M$(0,0,0);if(t.h==IQn&&0==t.m&&0==t.l)return Fbn(n,e);if(o=!1,t.h>>19!=0&&(t=aon(t),o=!o),a=OLn(t),c=!1,r=!1,i=!1,n.h==IQn&&0==n.m&&0==n.l){if(r=!0,c=!0,-1!=a)return u=jAn(n,a),o&&Oon(u),e&&(ltt=M$(0,0,0)),u;n=WO((X7(),btt)),i=!0,o=!o}else n.h>>19!=0&&(c=!0,n=aon(n),i=!0,o=!o);return-1!=a?Bon(n,a,o,c,e):_kn(n,t)<0?(e&&(ltt=c?aon(n):M$(n.l,n.m,n.h)),M$(0,0,0)):hKn(i?n:M$(n.l,n.m,n.h),t,o,c,r,e)}function $qn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(n.e&&n.c.c<n.f)throw Hp(new Fy("Expected "+n.f+" phases to be configured; only found "+n.c.c));for(h=BB(Vj(n.g),9),b=sx(n.f),u=0,s=(c=h).length;u<s;++u)(f=BB(D7(n,(i=c[u]).g),246))?WB(b,BB(own(n,f),123)):b.c[b.c.length]=null;for(w=new B2,JT(AV($V(AV(new Rq(null,new w1(b,16)),new hu),new Eg(t)),new fu),new Tg(w)),Jcn(w,n.a),e=new Np,a=0,o=(r=h).length;a<o;++a)gun(e,Eun(n,JQ(BB(D7(w,(i=r[a]).g),20)))),(l=BB(xq(b,i.g),123))&&(e.c[e.c.length]=l);return gun(e,Eun(n,JQ(BB(D7(w,h[h.length-1].g+1),20)))),e}function Lqn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w;for(OTn(i,"Model order cycle breaking",1),n.a=0,n.b=0,l=new Np,h=t.a.c.length,s=new Wb(t.a);s.a<s.c.c.length;)Lx(o=BB(n0(s),10),(hWn(),wlt))&&(h=e.Math.max(h,BB(mMn(o,wlt),19).a+1));for(w=new Wb(t.a);w.a<w.c.c.length;)for(u=zPn(n,b=BB(n0(w),10),h),f=xwn(b,(ain(),qvt)).Kc();f.Ob();)for(a=new Wb(BB(f.Pb(),11).g);a.a<a.c.c.length;)zPn(n,(r=BB(n0(a),17)).d.i,h)<u&&(l.c[l.c.length]=r);for(c=new Wb(l);c.a<c.c.c.length;)tBn(r=BB(n0(c),17),!0),hon(t,(hWn(),qft),(hN(),!0));l.c=x8(Ant,HWn,1,0,5,1),HSn(i)}function Nqn(n,t){var e,i,r,c,a,u,o;if(!(n.g>t.f||t.g>n.f)){for(e=0,i=0,a=n.w.a.ec().Kc();a.Ob();)r=BB(a.Pb(),11),phn(Aon(Pun(Gk(PMt,1),sVn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&++e;for(u=n.r.a.ec().Kc();u.Ob();)r=BB(u.Pb(),11),phn(Aon(Pun(Gk(PMt,1),sVn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&--e;for(o=t.w.a.ec().Kc();o.Ob();)r=BB(o.Pb(),11),phn(Aon(Pun(Gk(PMt,1),sVn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&++i;for(c=t.r.a.ec().Kc();c.Ob();)r=BB(c.Pb(),11),phn(Aon(Pun(Gk(PMt,1),sVn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&--i;e<i?new S6(n,t,i-e):i<e?new S6(t,n,e-i):(new S6(t,n,0),new S6(n,t,0))}}function xqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(s=t.c,r=QA(n.e),f=kL(Bx(B$(VA(n.e)),n.d*n.a,n.c*n.b),-.5),e=r.a-f.a,i=r.b-f.b,e=(a=t.a).c-e,i=a.d-i,o=new Wb(s);o.a<o.c.c.length;){switch(b=e+(l=(u=BB(n0(o),395)).b).a,g=i+l.b,w=IJ(b/n.a),p=IJ(g/n.b),(c=u.a).g){case 0:Hpn(),h=Brt;break;case 1:Hpn(),h=Frt;break;case 2:Hpn(),h=Hrt;break;default:Hpn(),h=qrt}c.a?(v=IJ((g+u.c)/n.b),WB(n.f,new xK(h,iln(p),iln(v))),c==(qpn(),tct)?won(n,0,p,w,v):won(n,w,p,n.d-1,v)):(d=IJ((b+u.c)/n.a),WB(n.f,new xK(h,iln(w),iln(d))),c==(qpn(),Zrt)?won(n,w,0,d,p):won(n,w,p,d,n.c-1))}}function Dqn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y;for(l=new Np,c=new Np,d=null,u=t.Kc();u.Ob();)a=new Hd(BB(u.Pb(),19).a),c.c[c.c.length]=a,d&&(a.d=d,d.e=a),d=a;for(m=zFn(n),h=0;h<c.c.length;++h){for(b=null,g=D6((l1(0,c.c.length),BB(c.c[0],652))),i=null,r=RQn,f=1;f<n.b.c.length;++f)p=g?e.Math.abs(g.b-f):e.Math.abs(f-b.b)+1,(w=b?e.Math.abs(f-b.b):p+1)<p?(s=b,o=w):(s=g,o=p),y=Gy(MD(mMn(n,(HXn(),Hpt)))),(v=m[f]+e.Math.pow(o,y))<r&&(r=v,(i=s).c=f),g&&f==g.b&&(b=g,g=xz(g));i&&(WB(l,iln(i.c)),i.a=!0,vln(i))}return SQ(),yG(l.c,l.c.length,null),l}function Rqn(n){var t,e,i,r,c,a,u,o,s,h;for(t=new To,e=new To,s=m_(_9n,(r=NKn(n.b,K9n))?SD(cdn((!r.b&&(r.b=new Jx((gWn(),k$t),X$t,r)),r.b),F9n)):null),o=0;o<n.i;++o)cL(u=BB(n.g[o],170),99)?0!=((a=BB(u,18)).Bb&h6n)?(0==(a.Bb&hVn)||!s&&null==((c=NKn(a,K9n))?SD(cdn((!c.b&&(c.b=new Jx((gWn(),k$t),X$t,c)),c.b),n8n)):null))&&f9(t,a):(h=Ivn(a))&&0!=(h.Bb&h6n)||(0==(a.Bb&hVn)||!s&&null==((i=NKn(a,K9n))?SD(cdn((!i.b&&(i.b=new Jx((gWn(),k$t),X$t,i)),i.b),n8n)):null))&&f9(e,a):(ZM(),BB(u,66).Oj()&&(u.Jj()||(f9(t,u),f9(e,u))));chn(t),chn(e),n.a=BB(t.g,247),BB(e.g,247)}function _qn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;for(o=xSn(t),BB(mMn(t,(HXn(),qdt)),314)!=(Oin(),hht)&&e5(o,new vt),e5(o,new Dw(BB(mMn(t,Rdt),292))),b=0,s=new Np,r=new bV(o);r.a!=r.b;)i=BB(Khn(r),37),$Gn(n.c,i),b+=(f=BB(mMn(i,(hWn(),Mlt)),15)).gc(),WB(s,new rC(i,f.Kc()));for(OTn(e,"Recursive hierarchical layout",b),l=BB(BB(xq(s,s.c.length-1),46).b,47);l.Ob();)for(u=new Wb(s);u.a<u.c.c.length;)for(a=BB(n0(u),46),f=BB(a.b,47),c=BB(a.a,37);f.Ob();){if(cL(h=BB(f.Pb(),51),507)){if(c.e)break;h.pf(c,mcn(e,1));break}h.pf(c,mcn(e,1))}HSn(e)}function Kqn(n,t){var e,i,r,c,a,u,o,s;if(b1(u=t.length-1,t.length),93==(a=t.charCodeAt(u))){if((c=GO(t,YTn(91)))>=0)return r=dbn(n,t.substr(1,c-1)),YUn(n,t.substr(c+1,u-(c+1)),r)}else{if(e=-1,null==Ett&&(Ett=new RegExp("\\d")),Ett.test(String.fromCharCode(a))&&(e=M_(t,YTn(46),u-1))>=0){i=BB(V5(n,Ptn(n,t.substr(1,e-1)),!1),58),o=0;try{o=lKn(t.substr(e+1),KVn,DWn)}catch(h){throw cL(h=lun(h),127)?Hp(new L7(h)):Hp(h)}if(o<i.gc())return cL(s=i.Xb(o),72)&&(s=BB(s,72).dd()),BB(s,56)}if(e<0)return BB(V5(n,Ptn(n,t.substr(1)),!1),56)}return null}function Fqn(n,t,e){var i,r,c,a,u,o,s;if(Awn(t,e)>=0)return e;switch(DW(B7(n,e))){case 2:if(m_("",Ifn(n,e.Hj()).ne())){if(o=m$n(n,t,u=jV(B7(n,e)),kV(B7(n,e))))return o;for(a=0,s=(r=j_n(n,t)).gc();a<s;++a)if(aNn(OU(B7(n,o=BB(r.Xb(a),170))),u))return o}return null;case 4:if(m_("",Ifn(n,e.Hj()).ne())){for(i=e;i;i=J1(B7(n,i)))if(o=y$n(n,t,jV(B7(n,i)),kV(B7(n,i))))return o;if(u=jV(B7(n,e)),m_(S7n,u))return mjn(n,t);for(a=0,s=(c=E_n(n,t)).gc();a<s;++a)if(aNn(OU(B7(n,o=BB(c.Xb(a),170))),u))return o}return null;default:return null}}function Bqn(n,t,e){var i,r,c,a,u,o,s,h;if(0==e.gc())return!1;if(ZM(),c=(u=BB(t,66).Oj())?e:new gtn(e.gc()),$xn(n.e,t)){if(t.hi())for(s=e.Kc();s.Ob();)UFn(n,t,o=s.Pb(),cL(t,99)&&0!=(BB(t,18).Bb&BQn))||(r=Z3(t,o),c.Hc(r)||c.Fc(r));else if(!u)for(s=e.Kc();s.Ob();)r=Z3(t,o=s.Pb()),c.Fc(r)}else{if(e.gc()>1)throw Hp(new Ky(C7n));for(h=axn(n.e.Tg(),t),i=BB(n.g,119),a=0;a<n.i;++a)if(r=i[a],h.rl(r.ak())){if(e.Hc(u?r:r.dd()))return!1;for(s=e.Kc();s.Ob();)o=s.Pb(),BB(ovn(n,a,u?BB(o,72):Z3(t,o)),72);return!0}u||(r=Z3(t,e.Kc().Pb()),c.Fc(r))}return pX(n,c)}function Hqn(n,t){var i,r,c,a,u,o,s;for(s=new YT,o=new _b(new Ob(n.c).a.vc().Kc());o.a.Ob();)c=BB(o.a.Pb(),42),0==(a=BB(c.dd(),458)).b&&r5(s,a,s.c.b,s.c);for(;0!=s.b;)for(null==(a=BB(0==s.b?null:(Px(0!=s.b),Atn(s,s.a.a)),458)).a&&(a.a=0),r=new Wb(a.d);r.a<r.c.c.length;)null==(i=BB(n0(r),654)).b.a?i.b.a=Gy(a.a)+i.a:t.o==(oZ(),ryt)?i.b.a=e.Math.min(Gy(i.b.a),Gy(a.a)+i.a):i.b.a=e.Math.max(Gy(i.b.a),Gy(a.a)+i.a),--i.b.b,0==i.b.b&&DH(s,i.b);for(u=new _b(new Ob(n.c).a.vc().Kc());u.a.Ob();)c=BB(u.a.Pb(),42),a=BB(c.dd(),458),t.i[a.c.p]=a.a}function qqn(){qqn=O,skt=new up(OZn),new up(AZn),new iR("DEPTH",iln(0)),ikt=new iR("FAN",iln(0)),tkt=new iR(U3n,iln(0)),dkt=new iR("ROOT",(hN(),!1)),ckt=new iR("LEFTNEIGHBOR",null),bkt=new iR("RIGHTNEIGHBOR",null),akt=new iR("LEFTSIBLING",null),wkt=new iR("RIGHTSIBLING",null),ekt=new iR("DUMMY",!1),new iR("LEVEL",iln(0)),lkt=new iR("REMOVABLE_EDGES",new YT),gkt=new iR("XCOOR",iln(0)),pkt=new iR("YCOOR",iln(0)),ukt=new iR("LEVELHEIGHT",0),rkt=new iR("ID",""),hkt=new iR("POSITION",iln(0)),fkt=new iR("PRELIM",0),okt=new iR("MODIFIER",0),nkt=new up($Zn),Zyt=new up(LZn)}function Gqn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w;for(f=i+t.c.c.a,w=new Wb(t.j);w.a<w.c.c.length;){if(b=BB(n0(w),11),c=Aon(Pun(Gk(PMt,1),sVn,8,0,[b.i.n,b.n,b.a])),t.k==(uSn(),Cut)&&(o=BB(mMn(b,(hWn(),dlt)),11),c.a=Aon(Pun(Gk(PMt,1),sVn,8,0,[o.i.n,o.n,o.a])).a,t.n.a=c.a),u=new xI(0,c.b),b.j==(kUn(),oCt))u.a=f;else{if(b.j!=ICt)continue;u.a=i}if(!(e.Math.abs(c.a-u.a)<=r)||Nkn(t))for(a=b.g.c.length+b.e.c.length>1,h=new m6(b.b);y$(h.a)||y$(h.b);)l=(s=BB(y$(h.a)?n0(h.a):n0(h.b),17)).c==b?s.d:s.c,e.Math.abs(Aon(Pun(Gk(PMt,1),sVn,8,0,[l.i.n,l.n,l.a])).b-u.b)>1&&pxn(n,s,u,a,b)}}function zqn(n){var t,i,r,c,a,u;if(c=new M2(n.e,0),r=new M2(n.a,0),n.d)for(i=0;i<n.b;i++)Px(c.b<c.d.gc()),c.d.Xb(c.c=c.b++);else for(i=0;i<n.b-1;i++)Px(c.b<c.d.gc()),c.d.Xb(c.c=c.b++),fW(c);for(t=Gy((Px(c.b<c.d.gc()),MD(c.d.Xb(c.c=c.b++))));n.f-t>D3n;){for(a=t,u=0;e.Math.abs(t-a)<D3n;)++u,t=Gy((Px(c.b<c.d.gc()),MD(c.d.Xb(c.c=c.b++)))),Px(r.b<r.d.gc()),r.d.Xb(r.c=r.b++);u<n.b&&(Px(c.b>0),c.a.Xb(c.c=--c.b),DFn(n,n.b-u,a,r,c),Px(c.b<c.d.gc()),c.d.Xb(c.c=c.b++)),Px(r.b>0),r.a.Xb(r.c=--r.b)}if(!n.d)for(i=0;i<n.b-1;i++)Px(c.b<c.d.gc()),c.d.Xb(c.c=c.b++),fW(c);n.d=!0,n.c=!0}function Uqn(){Uqn=O,pLt=(cE(),gLt).b,yLt=BB(Wtn(QQ(gLt.b),0),34),vLt=BB(Wtn(QQ(gLt.b),1),34),mLt=BB(Wtn(QQ(gLt.b),2),34),OLt=gLt.bb,BB(Wtn(QQ(gLt.bb),0),34),BB(Wtn(QQ(gLt.bb),1),34),$Lt=gLt.fb,LLt=BB(Wtn(QQ(gLt.fb),0),34),BB(Wtn(QQ(gLt.fb),1),34),BB(Wtn(QQ(gLt.fb),2),18),xLt=gLt.qb,_Lt=BB(Wtn(QQ(gLt.qb),0),34),BB(Wtn(QQ(gLt.qb),1),18),BB(Wtn(QQ(gLt.qb),2),18),DLt=BB(Wtn(QQ(gLt.qb),3),34),RLt=BB(Wtn(QQ(gLt.qb),4),34),FLt=BB(Wtn(QQ(gLt.qb),6),34),KLt=BB(Wtn(QQ(gLt.qb),5),18),kLt=gLt.j,jLt=gLt.k,ELt=gLt.q,TLt=gLt.w,MLt=gLt.B,SLt=gLt.A,PLt=gLt.C,ILt=gLt.D,CLt=gLt._,ALt=gLt.cb,NLt=gLt.hb}function Xqn(n,t,i){var r,c,a,u,o,s,h,f,l;n.c=0,n.b=0,r=2*t.c.a.c.length+1;n:for(h=i.Kc();h.Ob();){if(l=0,u=(s=BB(h.Pb(),11)).j==(kUn(),sCt)||s.j==SCt){if(!(f=BB(mMn(s,(hWn(),Elt)),10)))continue;l+=iRn(n,r,s,f)}else{for(o=new Wb(s.g);o.a<o.c.c.length;){if((c=BB(n0(o),17).d).i.c==t.c){WB(n.a,s);continue n}l+=n.g[c.p]}for(a=new Wb(s.e);a.a<a.c.c.length;){if((c=BB(n0(a),17).c).i.c==t.c){WB(n.a,s);continue n}l-=n.g[c.p]}}s.e.c.length+s.g.c.length>0?(n.f[s.p]=l/(s.e.c.length+s.g.c.length),n.c=e.Math.min(n.c,n.f[s.p]),n.b=e.Math.max(n.b,n.f[s.p])):u&&(n.f[s.p]=l)}}function Wqn(n){n.b=null,n.bb=null,n.fb=null,n.qb=null,n.a=null,n.c=null,n.d=null,n.e=null,n.f=null,n.n=null,n.M=null,n.L=null,n.Q=null,n.R=null,n.K=null,n.db=null,n.eb=null,n.g=null,n.i=null,n.j=null,n.k=null,n.gb=null,n.o=null,n.p=null,n.q=null,n.r=null,n.$=null,n.ib=null,n.S=null,n.T=null,n.t=null,n.s=null,n.u=null,n.v=null,n.w=null,n.B=null,n.A=null,n.C=null,n.D=null,n.F=null,n.G=null,n.H=null,n.I=null,n.J=null,n.P=null,n.Z=null,n.U=null,n.V=null,n.W=null,n.X=null,n.Y=null,n._=null,n.ab=null,n.cb=null,n.hb=null,n.nb=null,n.lb=null,n.mb=null,n.ob=null,n.pb=null,n.jb=null,n.kb=null,n.N=!1,n.O=!1}function Vqn(n,t,e){var i,r;for(OTn(e,"Graph transformation ("+n.a+")",1),r=a0(t.a),i=new Wb(t.b);i.a<i.c.c.length;)gun(r,BB(n0(i),29).a);if(BB(mMn(t,(HXn(),Xdt)),419)==(Knn(),Sht))switch(BB(mMn(t,Udt),103).g){case 2:L2(t,r);break;case 3:bdn(t,r);break;case 4:n.a==(Srn(),qut)?(bdn(t,r),$2(t,r)):($2(t,r),bdn(t,r))}else if(n.a==(Srn(),qut))switch(BB(mMn(t,Udt),103).g){case 2:L2(t,r),$2(t,r);break;case 3:bdn(t,r),L2(t,r);break;case 4:L2(t,r),bdn(t,r)}else switch(BB(mMn(t,Udt),103).g){case 2:L2(t,r),$2(t,r);break;case 3:L2(t,r),bdn(t,r);break;case 4:bdn(t,r),L2(t,r)}HSn(e)}function Qqn(n,t,e){var i,r,c,a,u,o,s,f,l,b,w;for(o=new fA,s=new fA,b=new fA,w=new fA,u=Gy(MD(mMn(t,(HXn(),Opt)))),r=Gy(MD(mMn(t,ypt))),a=new Wb(e);a.a<a.c.c.length;)if(c=BB(n0(a),10),(f=BB(mMn(c,(hWn(),Qft)),61))==(kUn(),sCt))for(s.a.zc(c,s),i=new oz(ZL(fbn(c).a.Kc(),new h));dAn(i);)TU(o,BB(U5(i),17).c.i);else if(f==SCt)for(w.a.zc(c,w),i=new oz(ZL(fbn(c).a.Kc(),new h));dAn(i);)TU(b,BB(U5(i),17).c.i);0!=o.a.gc()&&(l=AGn(new fX(2,r),t,o,s,-u-t.c.b))>0&&(n.a=u+(l-1)*r,t.c.b+=n.a,t.f.b+=n.a),0!=b.a.gc()&&(l=AGn(new fX(1,r),t,b,w,t.f.b+u-t.c.b))>0&&(t.f.b+=u+(l-1)*r)}function Yqn(n,t){var e,i,r,c;c=n.F,null==t?(n.F=null,Dsn(n,null)):(n.F=(kW(t),t),-1!=(i=GO(t,YTn(60)))?(r=t.substr(0,i),-1==GO(t,YTn(46))&&!m_(r,$Wn)&&!m_(r,S9n)&&!m_(r,P9n)&&!m_(r,I9n)&&!m_(r,C9n)&&!m_(r,O9n)&&!m_(r,A9n)&&!m_(r,$9n)&&(r=L9n),-1!=(e=mN(t,YTn(62)))&&(r+=""+t.substr(e+1)),Dsn(n,r)):(r=t,-1==GO(t,YTn(46))&&(-1!=(i=GO(t,YTn(91)))&&(r=t.substr(0,i)),m_(r,$Wn)||m_(r,S9n)||m_(r,P9n)||m_(r,I9n)||m_(r,C9n)||m_(r,O9n)||m_(r,A9n)||m_(r,$9n)?r=t:(r=L9n,-1!=i&&(r+=""+t.substr(i)))),Dsn(n,r),r==t&&(n.F=n.D))),0!=(4&n.Db)&&0==(1&n.Db)&&ban(n,new nU(n,1,5,c,t))}function Jqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;if(!((d=t.b.c.length)<3)){for(b=x8(ANt,hQn,25,d,15,1),f=0,h=new Wb(t.b);h.a<h.c.c.length;)s=BB(n0(h),29),b[f++]=s.a.c.length;for(l=new M2(t.b,2),i=1;i<d-1;i++)for(Px(l.b<l.d.gc()),w=new Wb((e=BB(l.d.Xb(l.c=l.b++),29)).a),c=0,u=0,o=0;o<b[i+1];o++)if(m=BB(n0(w),10),o==b[i+1]-1||YSn(n,m,i+1,i)){for(a=b[i]-1,YSn(n,m,i+1,i)&&(a=n.c.e[BB(BB(BB(xq(n.c.b,m.p),15).Xb(0),46).a,10).p]);u<=o;){if(!YSn(n,v=BB(xq(e.a,u),10),i+1,i))for(p=BB(xq(n.c.b,v.p),15).Kc();p.Ob();)g=BB(p.Pb(),46),((r=n.c.e[BB(g.a,10).p])<c||r>a)&&TU(n.b,BB(g.b,17));++u}c=a}}}function Zqn(n,t){var e;if(null==t||m_(t,zWn))return null;if(0==t.length&&n.k!=(PPn(),pMt))return null;switch(n.k.g){case 1:return mgn(t,a5n)?(hN(),vtt):mgn(t,u5n)?(hN(),ptt):null;case 2:try{return iln(lKn(t,KVn,DWn))}catch(i){if(cL(i=lun(i),127))return null;throw Hp(i)}case 4:try{return bSn(t)}catch(i){if(cL(i=lun(i),127))return null;throw Hp(i)}case 3:return t;case 5:return rhn(n),HCn(n,t);case 6:return rhn(n),_$n(n,n.a,t);case 7:try{return(e=rAn(n)).Jf(t),e}catch(i){if(cL(i=lun(i),32))return null;throw Hp(i)}default:throw Hp(new Fy("Invalid type set for this layout option."))}}function nGn(n){var t,e,i,r,c,a,u;for(Dnn(),u=new Vv,e=new Wb(n);e.a<e.c.c.length;)t=BB(n0(e),140),(!u.b||t.c>=u.b.c)&&(u.b=t),(!u.c||t.c<=u.c.c)&&(u.d=u.c,u.c=t),(!u.e||t.d>=u.e.d)&&(u.e=t),(!u.f||t.d<=u.f.d)&&(u.f=t);return i=new Tpn((Aun(),Zat)),i2(n,out,new Jy(Pun(Gk(Jat,1),HWn,369,0,[i]))),a=new Tpn(eut),i2(n,uut,new Jy(Pun(Gk(Jat,1),HWn,369,0,[a]))),r=new Tpn(nut),i2(n,aut,new Jy(Pun(Gk(Jat,1),HWn,369,0,[r]))),c=new Tpn(tut),i2(n,cut,new Jy(Pun(Gk(Jat,1),HWn,369,0,[c]))),xLn(i.c,Zat),xLn(r.c,nut),xLn(c.c,tut),xLn(a.c,eut),u.a.c=x8(Ant,HWn,1,0,5,1),gun(u.a,i.c),gun(u.a,ean(r.c)),gun(u.a,c.c),gun(u.a,ean(a.c)),u}function tGn(n){var t;switch(n.d){case 1:if(n.hj())return-2!=n.o;break;case 2:if(n.hj())return-2==n.o;break;case 3:case 5:case 4:case 6:case 7:return n.o>-2;default:return!1}switch(t=n.gj(),n.p){case 0:return null!=t&&qy(TD(t))!=JC(n.k,0);case 1:return null!=t&&BB(t,217).a!=dG(n.k)<<24>>24;case 2:return null!=t&&BB(t,172).a!=(dG(n.k)&QVn);case 6:return null!=t&&JC(BB(t,162).a,n.k);case 5:return null!=t&&BB(t,19).a!=dG(n.k);case 7:return null!=t&&BB(t,184).a!=dG(n.k)<<16>>16;case 3:return null!=t&&Gy(MD(t))!=n.j;case 4:return null!=t&&BB(t,155).a!=n.j;default:return null==t?null!=n.n:!Nfn(t,n.n)}}function eGn(n,t,e){var i,r,c,a;return n.Fk()&&n.Ek()&&GC(a=Gz(n,BB(e,56)))!==GC(e)?(n.Oi(t),n.Ui(t,B9(n,t,a)),n.rk()&&(r=BB(e,49),c=n.Dk()?n.Bk()?r.ih(n.b,Ivn(BB(itn(jY(n.b),n.aj()),18)).n,BB(itn(jY(n.b),n.aj()).Yj(),26).Bj(),null):r.ih(n.b,Awn(r.Tg(),Ivn(BB(itn(jY(n.b),n.aj()),18))),null,null):r.ih(n.b,-1-n.aj(),null,null),!BB(a,49).eh()&&(i=BB(a,49),c=n.Dk()?n.Bk()?i.gh(n.b,Ivn(BB(itn(jY(n.b),n.aj()),18)).n,BB(itn(jY(n.b),n.aj()).Yj(),26).Bj(),c):i.gh(n.b,Awn(i.Tg(),Ivn(BB(itn(jY(n.b),n.aj()),18))),null,c):i.gh(n.b,-1-n.aj(),null,c)),c&&c.Fi()),mA(n.b)&&n.$i(n.Zi(9,e,a,t,!1)),a):e}function iGn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(f=Gy(MD(mMn(n,(HXn(),Ept)))),r=Gy(MD(mMn(n,Rpt))),hon(b=new Yu,Ept,f+r),v=(h=t).d,g=h.c.i,m=h.d.i,p=tA(g.c),y=tA(m.c),c=new Np,l=p;l<=y;l++)Bl(o=new $vn(n),(uSn(),Put)),hon(o,(hWn(),dlt),h),hon(o,ept,(QEn(),XIt)),hon(o,Mpt,b),w=BB(xq(n.b,l),29),l==p?Qyn(o,w.a.c.length-i,w):PZ(o,w),(k=Gy(MD(mMn(h,agt))))<0&&hon(h,agt,k=0),o.o.b=k,d=e.Math.floor(k/2),qIn(u=new ISn,(kUn(),ICt)),IZ(u,o),u.n.b=d,qIn(s=new ISn,oCt),IZ(s,o),s.n.b=d,MZ(h,u),qan(a=new wY,h),hon(a,vgt,null),SZ(a,s),MZ(a,v),zkn(o,h,a),c.c[c.c.length]=a,h=a;return c}function rGn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(u=BB(DSn(n,(kUn(),ICt)).Kc().Pb(),11).e,f=BB(DSn(n,oCt).Kc().Pb(),11).g,a=u.c.length,g=g1(BB(xq(n.j,0),11));a-- >0;){for(l1(0,u.c.length),b=BB(u.c[0],17),l1(0,f.c.length),r=E7((i=BB(f.c[0],17)).d.e,i,0),A2(b,i.d,r),SZ(i,null),MZ(i,null),l=b.a,t&&DH(l,new wA(g)),e=spn(i.a,0);e.b!=e.d.c;)DH(l,new wA(BB(b3(e),8)));for(d=b.b,h=new Wb(i.b);h.a<h.c.c.length;)s=BB(n0(h),70),d.c[d.c.length]=s;if(w=BB(mMn(b,(HXn(),vgt)),74),c=BB(mMn(i,vgt),74))for(w||(w=new km,hon(b,vgt,w)),o=spn(c,0);o.b!=o.d.c;)DH(w,new wA(BB(b3(o),8)))}}function cGn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w;if(i=BB(oV(n.b,t),124),(s=BB(BB(h6(n.r,t),21),84)).dc())return i.n.b=0,void(i.n.c=0);for(h=n.u.Hc((lCn(),eCt)),u=0,o=s.Kc(),f=null,l=0,b=0;o.Ob();)c=Gy(MD((r=BB(o.Pb(),111)).b.We((DN(),Lrt)))),a=r.b.rf().a,n.A.Hc((mdn(),KCt))&&yRn(n,t),f?(w=b+f.d.c+n.w+r.d.b,u=e.Math.max(u,(h$(),rin(fJn),e.Math.abs(l-c)<=fJn||l==c||isNaN(l)&&isNaN(c)?0:w/(c-l)))):n.C&&n.C.b>0&&(u=e.Math.max(u,lcn(n.C.b+r.d.b,c))),f=r,l=c,b=a;n.C&&n.C.c>0&&(w=b+n.C.c,h&&(w+=f.d.c),u=e.Math.max(u,(h$(),rin(fJn),e.Math.abs(l-1)<=fJn||1==l||isNaN(l)&&isNaN(1)?0:w/(1-l)))),i.n.b=0,i.a.a=u}function aGn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w;if(i=BB(oV(n.b,t),124),(s=BB(BB(h6(n.r,t),21),84)).dc())return i.n.d=0,void(i.n.a=0);for(h=n.u.Hc((lCn(),eCt)),u=0,n.A.Hc((mdn(),KCt))&&kRn(n,t),o=s.Kc(),f=null,b=0,l=0;o.Ob();)a=Gy(MD((r=BB(o.Pb(),111)).b.We((DN(),Lrt)))),c=r.b.rf().b,f?(w=l+f.d.a+n.w+r.d.d,u=e.Math.max(u,(h$(),rin(fJn),e.Math.abs(b-a)<=fJn||b==a||isNaN(b)&&isNaN(a)?0:w/(a-b)))):n.C&&n.C.d>0&&(u=e.Math.max(u,lcn(n.C.d+r.d.d,a))),f=r,b=a,l=c;n.C&&n.C.a>0&&(w=l+n.C.a,h&&(w+=f.d.a),u=e.Math.max(u,(h$(),rin(fJn),e.Math.abs(b-1)<=fJn||1==b||isNaN(b)&&isNaN(1)?0:w/(1-b)))),i.n.d=0,i.a.b=u}function uGn(n,t,e){var i,r,c,a,u,o;for(this.g=n,u=t.d.length,o=e.d.length,this.d=x8(Out,a1n,10,u+o,0,1),a=0;a<u;a++)this.d[a]=t.d[a];for(c=0;c<o;c++)this.d[u+c]=e.d[c];if(t.e){if(this.e=zB(t.e),this.e.Mc(e),e.e)for(r=e.e.Kc();r.Ob();)(i=BB(r.Pb(),233))!=t&&(this.e.Hc(i)?--i.c:this.e.Fc(i))}else e.e&&(this.e=zB(e.e),this.e.Mc(t));this.f=t.f+e.f,this.a=t.a+e.a,this.a>0?Jtn(this,this.f/this.a):null!=lL(t.g,t.d[0]).a&&null!=lL(e.g,e.d[0]).a?Jtn(this,(Gy(lL(t.g,t.d[0]).a)+Gy(lL(e.g,e.d[0]).a))/2):null!=lL(t.g,t.d[0]).a?Jtn(this,lL(t.g,t.d[0]).a):null!=lL(e.g,e.d[0]).a&&Jtn(this,lL(e.g,e.d[0]).a)}function oGn(n,t){var e,i,r,c,a,u,o,s,h;for(n.a=new BX($cn(WPt)),i=new Wb(t.a);i.a<i.c.c.length;){for(e=BB(n0(i),841),a=new Pgn(Pun(Gk(Qat,1),HWn,81,0,[])),WB(n.a.a,a),o=new Wb(e.d);o.a<o.c.c.length;)FGn(s=new NN(n,u=BB(n0(o),110)),BB(mMn(e.c,(hWn(),Xft)),21)),hU(n.g,e)||(VW(n.g,e,new xI(u.c,u.d)),VW(n.f,e,s)),WB(n.a.b,s),g2(a,s);for(c=new Wb(e.b);c.a<c.c.c.length;)s=new NN(n,(r=BB(n0(c),594)).kf()),VW(n.b,r,new rC(a,s)),FGn(s,BB(mMn(e.c,(hWn(),Xft)),21)),r.hf()&&(FGn(h=new Sgn(n,r.hf(),1),BB(mMn(e.c,Xft),21)),g2(new Pgn(Pun(Gk(Qat,1),HWn,81,0,[])),h),JCn(n.c,r.gf(),new rC(a,h)))}return n.a}function sGn(n){var t;this.a=n,t=(uSn(),Pun(Gk($ut,1),$Vn,267,0,[Iut,Put,Mut,Cut,Sut,Tut])).length,this.b=kq(lMt,[sVn,k3n],[593,146],0,[t,t],2),this.c=kq(lMt,[sVn,k3n],[593,146],0,[t,t],2),FY(this,Iut,(HXn(),Opt),Apt),tun(this,Iut,Put,Ept,Tpt),KY(this,Iut,Cut,Ept),KY(this,Iut,Mut,Ept),tun(this,Iut,Sut,Opt,Apt),FY(this,Put,ypt,kpt),KY(this,Put,Cut,ypt),KY(this,Put,Mut,ypt),tun(this,Put,Sut,Ept,Tpt),ZA(this,Cut,ypt),KY(this,Cut,Mut,ypt),KY(this,Cut,Sut,Ppt),ZA(this,Mut,Npt),tun(this,Mut,Sut,Cpt,Ipt),FY(this,Sut,ypt,ypt),FY(this,Tut,ypt,kpt),tun(this,Tut,Iut,Ept,Tpt),tun(this,Tut,Sut,Ept,Tpt),tun(this,Tut,Put,Ept,Tpt)}function hGn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g;if(cL(a=e.ak(),99)&&0!=(BB(a,18).Bb&BQn)&&(l=BB(e.dd(),49),(d=tfn(n.e,l))!=l)){if(jL(n,t,sTn(n,t,h=Z3(a,d))),f=null,mA(n.e)&&(i=Fqn((CPn(),Z$t),n.e.Tg(),a))!=itn(n.e.Tg(),n.c)){for(g=axn(n.e.Tg(),a),u=0,c=BB(n.g,119),o=0;o<t;++o)r=c[o],g.rl(r.ak())&&++u;(f=new b4(n.e,9,i,l,d,u,!1)).Ei(new N7(n.e,9,n.c,e,h,t,!1))}return(b=Ivn(w=BB(a,18)))?(f=l.ih(n.e,Awn(l.Tg(),b),null,f),f=BB(d,49).gh(n.e,Awn(d.Tg(),b),null,f)):0!=(w.Bb&h6n)&&(s=-1-Awn(n.e.Tg(),w),f=l.ih(n.e,s,null,null),!BB(d,49).eh()&&(f=BB(d,49).gh(n.e,s,null,f))),f&&f.Fi(),h}return e}function fGn(n){var t,i,r,c,a,u,o,s;for(a=new Wb(n.a.b);a.a<a.c.c.length;)(c=BB(n0(a),81)).b.c=c.g.c,c.b.d=c.g.d;for(s=new xI(RQn,RQn),t=new xI(_Qn,_Qn),r=new Wb(n.a.b);r.a<r.c.c.length;)i=BB(n0(r),81),s.a=e.Math.min(s.a,i.g.c),s.b=e.Math.min(s.b,i.g.d),t.a=e.Math.max(t.a,i.g.c+i.g.b),t.b=e.Math.max(t.b,i.g.d+i.g.a);for(o=TX(n.c).a.nc();o.Ob();)u=BB(o.Pb(),46),i=BB(u.b,81),s.a=e.Math.min(s.a,i.g.c),s.b=e.Math.min(s.b,i.g.d),t.a=e.Math.max(t.a,i.g.c+i.g.b),t.b=e.Math.max(t.b,i.g.d+i.g.a);n.d=qx(new xI(s.a,s.b)),n.e=XR(new xI(t.a,t.b),s),n.a.a.c=x8(Ant,HWn,1,0,5,1),n.a.b.c=x8(Ant,HWn,1,0,5,1)}function lGn(n){var t,e,i;for(ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new Nf])),e=new Tl(n),i=0;i<e.a.length;++i)m_(t=dnn(e,i).je().a,"layered")?ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new hf])):m_(t,"force")?ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new zh])):m_(t,"stress")?ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new Xh])):m_(t,"mrtree")?ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new Pf])):m_(t,"radial")?ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new yf])):m_(t,"disco")?ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new Gh,new Hh])):m_(t,"sporeOverlap")||m_(t,"sporeCompaction")?ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new Tf])):m_(t,"rectpacking")&&ksn(lAt,Pun(Gk(Kit,1),HWn,130,0,[new Of]))}function bGn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;if(l=new wA(n.o),p=t.a/l.a,u=t.b/l.b,d=t.a-l.a,c=t.b-l.b,e)for(r=GC(mMn(n,(HXn(),ept)))===GC((QEn(),XIt)),w=new Wb(n.j);w.a<w.c.c.length;)switch((b=BB(n0(w),11)).j.g){case 1:r||(b.n.a*=p);break;case 2:b.n.a+=d,r||(b.n.b*=u);break;case 3:r||(b.n.a*=p),b.n.b+=c;break;case 4:r||(b.n.b*=u)}for(s=new Wb(n.b);s.a<s.c.c.length;)h=(o=BB(n0(s),70)).n.a+o.o.a/2,f=o.n.b+o.o.b/2,(g=h/l.a)+(a=f/l.b)>=1&&(g-a>0&&f>=0?(o.n.a+=d,o.n.b+=c*a):g-a<0&&h>=0&&(o.n.a+=d*g,o.n.b+=c));n.o.a=t.a,n.o.b=t.b,hon(n,(HXn(),Fgt),(mdn(),new Y_(i=BB(Vj(YCt),9),BB(SR(i,i.length),9),0)))}function wGn(n,t,e,i,r,c){if(null!=t&&Xbn(t,AAt,$At))throw Hp(new Ky("invalid scheme: "+t));if(!(n||null!=e&&-1==GO(e,YTn(35))&&e.length>0&&(b1(0,e.length),47!=e.charCodeAt(0))))throw Hp(new Ky("invalid opaquePart: "+e));if(n&&(null==t||!xT(jAt,t.toLowerCase()))&&null!=e&&Xbn(e,LAt,NAt))throw Hp(new Ky(o9n+e));if(n&&null!=t&&xT(jAt,t.toLowerCase())&&!IEn(e))throw Hp(new Ky(o9n+e));if(!Ubn(i))throw Hp(new Ky("invalid device: "+i));if(!Rhn(r))throw Hp(new Ky(null==r?"invalid segments: null":"invalid segment: "+shn(r)));if(null!=c&&-1!=GO(c,YTn(35)))throw Hp(new Ky("invalid query: "+c))}function dGn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(OTn(t,"Calculate Graph Size",1),t.n&&n&&y0(t,o2(n),(Bsn(),uOt)),o=ZJn,s=ZJn,a=n4n,u=n4n,l=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));l.e!=l.i.gc();)d=(h=BB(kpn(l),33)).i,g=h.j,v=h.g,r=h.f,c=BB(ZAn(h,(sWn(),$St)),142),o=e.Math.min(o,d-c.b),s=e.Math.min(s,g-c.d),a=e.Math.max(a,d+v+c.c),u=e.Math.max(u,g+r+c.a);for(b=new xI(o-(w=BB(ZAn(n,(sWn(),XSt)),116)).b,s-w.d),f=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));f.e!=f.i.gc();)Pen(h=BB(kpn(f),33),h.i-b.a),Ien(h,h.j-b.b);p=a-o+(w.b+w.c),i=u-s+(w.d+w.a),Sen(n,p),Men(n,i),t.n&&n&&y0(t,o2(n),(Bsn(),uOt))}function gGn(n){var t,e,i,r,c,a,u,o,s,h;for(i=new Np,a=new Wb(n.e.a);a.a<a.c.c.length;){for(h=0,(r=BB(n0(a),121)).k.c=x8(Ant,HWn,1,0,5,1),e=new Wb(kbn(r));e.a<e.c.c.length;)(t=BB(n0(e),213)).f&&(WB(r.k,t),++h);1==h&&(i.c[i.c.length]=r)}for(c=new Wb(i);c.a<c.c.c.length;)for(r=BB(n0(c),121);1==r.k.c.length;){for(s=BB(n0(new Wb(r.k)),213),n.b[s.c]=s.g,u=s.d,o=s.e,e=new Wb(kbn(r));e.a<e.c.c.length;)Nfn(t=BB(n0(e),213),s)||(t.f?u==t.d||o==t.e?n.b[s.c]-=n.b[t.c]-t.g:n.b[s.c]+=n.b[t.c]-t.g:r==u?t.d==r?n.b[s.c]+=t.g:n.b[s.c]-=t.g:t.d==r?n.b[s.c]-=t.g:n.b[s.c]+=t.g);y7(u.k,s),y7(o.k,s),r=u==r?s.e:s.d}}function pGn(n,t){var e,i,r,c,a,u,o,s,h,f,l;if(null==t||0==t.length)return null;if(!(c=BB(SJ(n.f,t),23))){for(r=new _b(new Ob(n.d).a.vc().Kc());r.a.Ob();)if(a=BB(r.a.Pb(),42),u=(e=BB(a.dd(),23)).f,l=t.length,m_(u.substr(u.length-l,l),t)&&(t.length==u.length||46==fV(u,u.length-t.length-1))){if(c)return null;c=e}if(!c)for(i=new _b(new Ob(n.d).a.vc().Kc());i.a.Ob();)if(a=BB(i.a.Pb(),42),null!=(f=(e=BB(a.dd(),23)).g))for(s=0,h=(o=f).length;s<h;++s)if(u=o[s],l=t.length,m_(u.substr(u.length-l,l),t)&&(t.length==u.length||46==fV(u,u.length-t.length-1))){if(c)return null;c=e}c&&mZ(n.f,t,c)}return c}function vGn(n,t){var e,i,r,c,a;for(e=new Ck,a=!1,c=0;c<t.length;c++)if(b1(c,t.length),32!=(i=t.charCodeAt(c)))a?39==i?c+1<t.length&&(b1(c+1,t.length),39==t.charCodeAt(c+1))?(e.a+=String.fromCharCode(i),++c):a=!1:e.a+=String.fromCharCode(i):GO("GyMLdkHmsSEcDahKzZv",YTn(i))>0?(Ppn(n,e,0),e.a+=String.fromCharCode(i),Ppn(n,e,r=cgn(t,c)),c+=r-1):39==i?c+1<t.length&&(b1(c+1,t.length),39==t.charCodeAt(c+1))?(e.a+="'",++c):a=!0:e.a+=String.fromCharCode(i);else for(Ppn(n,e,0),e.a+=" ",Ppn(n,e,0);c+1<t.length&&(b1(c+1,t.length),32==t.charCodeAt(c+1));)++c;Ppn(n,e,0),pTn(n)}function mGn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p;if(OTn(i,"Network simplex layering",1),n.b=t,p=4*BB(mMn(t,(HXn(),xpt)),19).a,(g=n.b.a).c.length<1)HSn(i);else{for(d=null,c=spn(a=C_n(n,g),0);c.b!=c.d.c;){for(r=BB(b3(c),15),o=p*IJ(e.Math.sqrt(r.gc())),W_n(Qk(Jk(Yk(BK(u=oKn(r)),o),d),!0),mcn(i,1)),l=n.b.b,w=new Wb(u.a);w.a<w.c.c.length;){for(b=BB(n0(w),121);l.c.length<=b.e;)kG(l,l.c.length,new HX(n.b));PZ(BB(b.f,10),BB(xq(l,b.e),29))}if(a.b>1)for(d=x8(ANt,hQn,25,n.b.b.c.length,15,1),f=0,h=new Wb(n.b.b);h.a<h.c.c.length;)s=BB(n0(h),29),d[f++]=s.a.c.length}g.c=x8(Ant,HWn,1,0,5,1),n.a=null,n.b=null,n.c=null,HSn(i)}}function yGn(n){var t,i,r,c,a,u,o;for(t=0,a=new Wb(n.b.a);a.a<a.c.c.length;)(r=BB(n0(a),189)).b=0,r.c=0;for(ESn(n,0),ewn(n,n.g),kNn(n.c),Zy(n.c),Ffn(),i=KPt,D_n(eO(Mzn(D_n(eO(Mzn(D_n(Mzn(n.c,i)),jln(i)))),i))),Mzn(n.c,KPt),Bln(n,n.g),kMn(n,0),pHn(n,0),M$n(n,1),ESn(n,1),ewn(n,n.d),kNn(n.c),u=new Wb(n.b.a);u.a<u.c.c.length;)r=BB(n0(u),189),t+=e.Math.abs(r.c);for(o=new Wb(n.b.a);o.a<o.c.c.length;)(r=BB(n0(o),189)).b=0,r.c=0;for(i=HPt,D_n(eO(Mzn(D_n(eO(Mzn(D_n(Zy(Mzn(n.c,i))),jln(i)))),i))),Mzn(n.c,KPt),Bln(n,n.d),kMn(n,1),pHn(n,1),M$n(n,0),Zy(n.c),c=new Wb(n.b.a);c.a<c.c.c.length;)r=BB(n0(c),189),t+=e.Math.abs(r.c);return t}function kGn(n,t){var e,i,r,c,a,u,o,s,h;if(null!=(s=t).b&&null!=n.b){for(T$n(n),qHn(n),T$n(s),qHn(s),e=x8(ANt,hQn,25,n.b.length+s.b.length,15,1),h=0,i=0,a=0;i<n.b.length&&a<s.b.length;)if(r=n.b[i],c=n.b[i+1],u=s.b[a],o=s.b[a+1],c<u)i+=2;else if(c>=u&&r<=o)u<=r&&c<=o?(e[h++]=r,e[h++]=c,i+=2):u<=r?(e[h++]=r,e[h++]=o,n.b[i]=o+1,a+=2):c<=o?(e[h++]=u,e[h++]=c,i+=2):(e[h++]=u,e[h++]=o,n.b[i]=o+1);else{if(!(o<r))throw Hp(new dy("Token#intersectRanges(): Internal Error: ["+n.b[i]+","+n.b[i+1]+"] & ["+s.b[a]+","+s.b[a+1]+"]"));a+=2}for(;i<n.b.length;)e[h++]=n.b[i++],e[h++]=n.b[i++];n.b=x8(ANt,hQn,25,h,15,1),aHn(e,0,n.b,0,h)}}function jGn(n){var t,i,r,c,a,u,o;for(t=new Np,n.g=new Np,n.d=new Np,u=new usn(new Pb(n.f.b).a);u.b;)WB(t,BB(BB((a=ten(u)).dd(),46).b,81)),dA(BB(a.cd(),594).gf())?WB(n.d,BB(a.dd(),46)):WB(n.g,BB(a.dd(),46));for(ewn(n,n.d),ewn(n,n.g),n.c=new sOn(n.b),ej(n.c,(vM(),Gat)),Bln(n,n.d),Bln(n,n.g),gun(t,n.c.a.b),n.e=new xI(RQn,RQn),n.a=new xI(_Qn,_Qn),r=new Wb(t);r.a<r.c.c.length;)i=BB(n0(r),81),n.e.a=e.Math.min(n.e.a,i.g.c),n.e.b=e.Math.min(n.e.b,i.g.d),n.a.a=e.Math.max(n.a.a,i.g.c+i.g.b),n.a.b=e.Math.max(n.a.b,i.g.d+i.g.a);tj(n.c,new jt),o=0;do{c=yGn(n),++o}while((o<2||c>_Vn)&&o<10);tj(n.c,new Et),yGn(n),CU(n.c),fGn(n.f)}function EGn(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(qy(TD(mMn(e,(HXn(),wgt)))))for(r=new Wb(e.j);r.a<r.c.c.length;)for(u=0,o=(a=Z0(BB(n0(r),11).g)).length;u<o;++u)(c=a[u]).d.i==e&&qy(TD(mMn(c,dgt)))&&(h=c.c,(s=BB(RX(n.b,h),10))||(hon(s=bXn(h,(QEn(),QIt),h.j,-1,null,null,h.o,BB(mMn(t,Udt),103),t),(hWn(),dlt),h),VW(n.b,h,s),WB(t.a,s)),l=c.d,(f=BB(RX(n.b,l),10))||(hon(f=bXn(l,(QEn(),QIt),l.j,1,null,null,l.o,BB(mMn(t,Udt),103),t),(hWn(),dlt),l),VW(n.b,l,f),WB(t.a,f)),SZ(i=W5(c),BB(xq(s.j,0),11)),MZ(i,BB(xq(f.j,0),11)),JCn(n.a,c,new LK(i,t,(ain(),qvt))),BB(mMn(t,(hWn(),Zft)),21).Fc((bDn(),lft)))}function TGn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w;for(OTn(e,"Label dummy switching",1),i=BB(mMn(t,(HXn(),Vdt)),227),pcn(t),r=j$n(t,i),n.a=x8(xNt,qQn,25,t.b.c.length,15,1),$Pn(),h=0,b=(u=Pun(Gk(uht,1),$Vn,227,0,[Zst,tht,Jst,nht,eht,Yst])).length;h<b;++h)if(((c=u[h])==eht||c==Yst||c==nht)&&!BB(SN(r.a,c)?r.b[c.g]:null,15).dc()){Zcn(n,t);break}for(f=0,w=(o=Pun(Gk(uht,1),$Vn,227,0,[Zst,tht,Jst,nht,eht,Yst])).length;f<w;++f)(c=o[f])==eht||c==Yst||c==nht||G_n(n,BB(SN(r.a,c)?r.b[c.g]:null,15));for(s=0,l=(a=Pun(Gk(uht,1),$Vn,227,0,[Zst,tht,Jst,nht,eht,Yst])).length;s<l;++s)((c=a[s])==eht||c==Yst||c==nht)&&G_n(n,BB(SN(r.a,c)?r.b[c.g]:null,15));n.a=null,HSn(e)}function MGn(n,t){var e,i,r,c,a,u,o,s,h,f,l;switch(n.k.g){case 1:if(i=BB(mMn(n,(hWn(),dlt)),17),(e=BB(mMn(i,glt),74))?qy(TD(mMn(i,Ilt)))&&(e=Jon(e)):e=new km,s=BB(mMn(n,hlt),11)){if(t<=(h=Aon(Pun(Gk(PMt,1),sVn,8,0,[s.i.n,s.n,s.a]))).a)return h.b;r5(e,h,e.a,e.a.a)}if(f=BB(mMn(n,flt),11)){if((l=Aon(Pun(Gk(PMt,1),sVn,8,0,[f.i.n,f.n,f.a]))).a<=t)return l.b;r5(e,l,e.c.b,e.c)}if(e.b>=2){for(a=BB(b3(o=spn(e,0)),8),u=BB(b3(o),8);u.a<t&&o.b!=o.d.c;)a=u,u=BB(b3(o),8);return a.b+(t-a.a)/(u.a-a.a)*(u.b-a.b)}break;case 3:switch(r=(c=BB(mMn(BB(xq(n.j,0),11),(hWn(),dlt)),11)).i,c.j.g){case 1:return r.n.b;case 3:return r.n.b+r.o.b}}return Fjn(n).b}function SGn(n){var t,e,i,r,c,a,u,o,s,f;for(c=new Wb(n.d.b);c.a<c.c.c.length;)for(u=new Wb(BB(n0(c),29).a);u.a<u.c.c.length;)!qy(TD(mMn(a=BB(n0(u),10),(HXn(),Tdt))))||h3(hbn(a))?(r=new UV(a.n.a-a.d.b,a.n.b-a.d.d,a.o.a+a.d.b+a.d.c,a.o.b+a.d.d+a.d.a),t=ON(iM(tM(eM(new Wv,a),r),dst),n.a),CN(nM(Xen(new Xv,Pun(Gk(bit,1),HWn,57,0,[t])),t),n.a),o=new Dp,VW(n.e,t,o),(e=F3(new oz(ZL(fbn(a).a.Kc(),new h)))-F3(new oz(ZL(lbn(a).a.Kc(),new h))))<0?Uun(o,!0,(Ffn(),KPt)):e>0&&Uun(o,!0,(Ffn(),FPt)),a.k==(uSn(),Mut)&&wV(o),VW(n.f,a,t)):((s=(i=BB(iY(hbn(a)),17)).c.i)==a&&(s=i.d.i),f=new rC(s,XR(B$(a.n),s.n)),VW(n.b,a,f))}function PGn(n,t,i){var r,c,a,u,o,s,h,f;switch(OTn(i,"Node promotion heuristic",1),n.g=t,yUn(n),n.q=BB(mMn(t,(HXn(),Sgt)),260),f=BB(mMn(n.g,Mgt),19).a,a=new hi,n.q.g){case 2:case 1:default:KHn(n,a);break;case 3:for(n.q=(sNn(),Ovt),KHn(n,a),s=0,o=new Wb(n.a);o.a<o.c.c.length;)u=BB(n0(o),19),s=e.Math.max(s,u.a);s>n.j&&(n.q=Tvt,KHn(n,a));break;case 4:for(n.q=(sNn(),Ovt),KHn(n,a),h=0,c=new Wb(n.b);c.a<c.c.c.length;)r=MD(n0(c)),h=e.Math.max(h,(kW(r),r));h>n.k&&(n.q=Pvt,KHn(n,a));break;case 6:KHn(n,new od(IJ(e.Math.ceil(n.f.length*f/100))));break;case 5:KHn(n,new sd(IJ(e.Math.ceil(n.d*f/100))))}oDn(n,t),HSn(i)}function IGn(n,t,e){var i,r,c,a;this.j=n,this.e=qEn(n),this.o=this.j.e,this.i=!!this.o,this.p=this.i?BB(xq(e,vW(this.o).p),214):null,r=BB(mMn(n,(hWn(),Zft)),21),this.g=r.Hc((bDn(),lft)),this.b=new Np,this.d=new wdn(this.e),a=BB(mMn(this.j,Slt),230),this.q=Han(t,a,this.e),this.k=new aZ(this),c=u6(Pun(Gk(jst,1),HWn,225,0,[this,this.d,this.k,this.q])),t!=(oin(),Omt)||qy(TD(mMn(n,(HXn(),xdt))))?t==Omt&&qy(TD(mMn(n,(HXn(),xdt))))?(i=new UEn(this.e),c.c[c.c.length]=i,this.c=new prn(i,a,BB(this.q,402))):this.c=new vP(t,this):(i=new UEn(this.e),c.c[c.c.length]=i,this.c=new G2(i,a,BB(this.q,402))),WB(c,this.c),IHn(c,this.e),this.s=wXn(this.k)}function CGn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(l=(s=BB(iL(new wg(spn(new bg(t).a.d,0))),86))?BB(mMn(s,(qqn(),ckt)),86):null,r=1;s&&l;){for(a=0,v=0,e=s,i=l,c=0;c<r;c++)e=G8(e),i=G8(i),v+=Gy(MD(mMn(e,(qqn(),okt)))),a+=Gy(MD(mMn(i,okt)));if(p=Gy(MD(mMn(l,(qqn(),fkt)))),g=Gy(MD(mMn(s,fkt))),h=E5(s,l),0<(f=p+a+n.a+h-g-v)){for(u=t,o=0;u&&u!=i;)++o,u=BB(mMn(u,akt),86);if(!u)return;for(d=f/o,u=t;u!=i;)w=Gy(MD(mMn(u,fkt)))+f,hon(u,fkt,w),b=Gy(MD(mMn(u,okt)))+f,hon(u,okt,b),f-=d,u=BB(mMn(u,akt),86)}++r,l=(s=0==s.d.b?Z_n(new bg(t),r):BB(iL(new wg(spn(new bg(s).a.d,0))),86))?BB(mMn(s,ckt),86):null}}function OGn(n,t){var e,i,r,c,a,u,o,s,f;for(u=!0,r=0,o=n.f[t.p],s=t.o.b+n.n,e=n.c[t.p][2],c5(n.a,o,iln(BB(xq(n.a,o),19).a-1+e)),c5(n.b,o,Gy(MD(xq(n.b,o)))-s+e*n.e),++o>=n.i?(++n.i,WB(n.a,iln(1)),WB(n.b,s)):(i=n.c[t.p][1],c5(n.a,o,iln(BB(xq(n.a,o),19).a+1-i)),c5(n.b,o,Gy(MD(xq(n.b,o)))+s-i*n.e)),(n.q==(sNn(),Tvt)&&(BB(xq(n.a,o),19).a>n.j||BB(xq(n.a,o-1),19).a>n.j)||n.q==Pvt&&(Gy(MD(xq(n.b,o)))>n.k||Gy(MD(xq(n.b,o-1)))>n.k))&&(u=!1),c=new oz(ZL(fbn(t).a.Kc(),new h));dAn(c);)a=BB(U5(c),17).c.i,n.f[a.p]==o&&(r+=BB((f=OGn(n,a)).a,19).a,u=u&&qy(TD(f.b)));return n.f[t.p]=o,new rC(iln(r+=n.c[t.p][0]),(hN(),!!u))}function AGn(n,t,i,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v;for(l=new xp,u=new Np,rCn(n,i,n.d.fg(),u,l),rCn(n,r,n.d.gg(),u,l),n.b=.2*(g=BAn(wnn(new Rq(null,new w1(u,16)),new Sa)),p=BAn(wnn(new Rq(null,new w1(u,16)),new Pa)),e.Math.min(g,p)),a=0,o=0;o<u.c.length-1;o++)for(l1(o,u.c.length),s=BB(u.c[o],112),d=o+1;d<u.c.length;d++)a+=gHn(n,s,(l1(d,u.c.length),BB(u.c[d],112)));for(b=BB(mMn(t,(hWn(),Slt)),230),a>=2&&(v=QLn(u,!0,b),!n.e&&(n.e=new lg(n)),sgn(n.e,v,u,n.b)),iTn(u,b),czn(u),w=-1,f=new Wb(u);f.a<f.c.c.length;)h=BB(n0(f),112),e.Math.abs(h.s-h.c)<lZn||(w=e.Math.max(w,h.o),n.d.dg(h,c,n.c));return n.d.a.a.$b(),w+1}function $Gn(n,t){var e,i;Gy(MD(mMn(t,(HXn(),ypt))))<2&&hon(t,ypt,2),BB(mMn(t,Udt),103)==(Ffn(),BPt)&&hon(t,Udt,Wln(t)),0==(e=BB(mMn(t,wpt),19)).a?hon(t,(hWn(),Slt),new sbn):hon(t,(hWn(),Slt),new I4(e.a)),null==TD(mMn(t,xgt))&&hon(t,xgt,(hN(),GC(mMn(t,Zdt))===GC((Mbn(),QPt)))),JT(new Rq(null,new w1(t.a,16)),new Rw(n)),JT(wnn(new Rq(null,new w1(t.b,16)),new mt),new _w(n)),i=new sGn(t),hon(t,(hWn(),Alt),i),h2(n.a),IU(n.a,(yMn(),Rat),BB(mMn(t,Gdt),246)),IU(n.a,_at,BB(mMn(t,Pgt),246)),IU(n.a,Kat,BB(mMn(t,qdt),246)),IU(n.a,Fat,BB(mMn(t,Kgt),246)),IU(n.a,Bat,San(BB(mMn(t,Zdt),218))),aA(n.a,LXn(t)),hon(t,Mlt,$qn(n.a,t))}function LGn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;return l=n.c[t],b=n.c[e],!((w=BB(mMn(l,(hWn(),clt)),15))&&0!=w.gc()&&w.Hc(b)||(d=l.k!=(uSn(),Put)&&b.k!=Put,v=(g=BB(mMn(l,rlt),10))!=(p=BB(mMn(b,rlt),10)),m=!!g&&g!=l||!!p&&p!=b,y=omn(l,(kUn(),sCt)),k=omn(b,SCt),m|=omn(l,SCt)||omn(b,sCt),d&&(m&&v||y||k))||l.k==(uSn(),Cut)&&b.k==Iut||b.k==(uSn(),Cut)&&l.k==Iut)&&(h=n.c[t],c=n.c[e],r=fjn(n.e,h,c,(kUn(),ICt)),o=fjn(n.i,h,c,oCt),TNn(n.f,h,c),s=Nsn(n.b,h,c)+BB(r.a,19).a+BB(o.a,19).a+n.f.d,u=Nsn(n.b,c,h)+BB(r.b,19).a+BB(o.b,19).a+n.f.b,n.a&&(f=BB(mMn(h,dlt),11),a=BB(mMn(c,dlt),11),s+=BB((i=qyn(n.g,f,a)).a,19).a,u+=BB(i.b,19).a),s>u)}function NGn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(i=BB(mMn(n,(HXn(),ept)),98),u=n.f,a=n.d,o=u.a+a.b+a.c,s=0-a.d-n.c.b,f=u.b+a.d+a.a-n.c.b,h=new Np,l=new Np,c=new Wb(t);c.a<c.c.c.length;){switch(r=BB(n0(c),10),i.g){case 1:case 2:case 3:KNn(r);break;case 4:w=(b=BB(mMn(r,npt),8))?b.a:0,r.n.a=o*Gy(MD(mMn(r,(hWn(),Tlt))))-w,Jan(r,!0,!1);break;case 5:g=(d=BB(mMn(r,npt),8))?d.a:0,r.n.a=Gy(MD(mMn(r,(hWn(),Tlt))))-g,Jan(r,!0,!1),u.a=e.Math.max(u.a,r.n.a+r.o.a/2)}switch(BB(mMn(r,(hWn(),Qft)),61).g){case 1:r.n.b=s,h.c[h.c.length]=r;break;case 3:r.n.b=f,l.c[l.c.length]=r}}switch(i.g){case 1:case 2:Rfn(h,n),Rfn(l,n);break;case 3:_fn(h,n),_fn(l,n)}}function xGn(n,t){var e,i,r,c,a,u,o,s,h,f;for(h=new Np,f=new Lp,c=null,r=0,i=0;i<t.length;++i)switch(Rsn(c,e=t[i])&&(r=Idn(n,f,h,_mt,r)),Lx(e,(hWn(),rlt))&&(c=BB(mMn(e,rlt),10)),e.k.g){case 0:for(o=qA(_B(abn(e,(kUn(),sCt)),new xc));Zin(o);)a=BB(P7(o),11),n.d[a.p]=r++,h.c[h.c.length]=a;for(r=Idn(n,f,h,_mt,r),s=qA(_B(abn(e,SCt),new xc));Zin(s);)a=BB(P7(s),11),n.d[a.p]=r++,h.c[h.c.length]=a;break;case 3:abn(e,Rmt).dc()||(a=BB(abn(e,Rmt).Xb(0),11),n.d[a.p]=r++,h.c[h.c.length]=a),abn(e,_mt).dc()||d3(f,e);break;case 1:for(u=abn(e,(kUn(),ICt)).Kc();u.Ob();)a=BB(u.Pb(),11),n.d[a.p]=r++,h.c[h.c.length]=a;abn(e,oCt).Jc(new ZP(f,e))}return Idn(n,f,h,_mt,r),h}function DGn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(h=RQn,f=RQn,o=_Qn,s=_Qn,b=new Wb(t.i);b.a<b.c.c.length;)l=BB(n0(b),65),SA(c=BB(BB(RX(n.g,l.a),46).b,33),l.b.c,l.b.d),h=e.Math.min(h,c.i),f=e.Math.min(f,c.j),o=e.Math.max(o,c.i+c.g),s=e.Math.max(s,c.j+c.f);for(w=BB(ZAn(n.c,(MMn(),bTt)),116),_Un(n.c,o-h+(w.b+w.c),s-f+(w.d+w.a),!0,!0),lMn(n.c,-h+w.b,-f+w.d),r=new AL(iQ(n.c));r.e!=r.i.gc();)u=cDn(i=BB(kpn(r),79),!0,!0),d=PMn(i),p=OMn(i),g=new xI(d.i+d.g/2,d.j+d.f/2),a=new xI(p.i+p.g/2,p.j+p.f/2),Ukn(v=XR(new xI(a.a,a.b),g),d.g,d.f),UR(g,v),Ukn(m=XR(new xI(g.a,g.b),a),p.g,p.f),UR(a,m),IA(u,g.a,g.b),PA(u,a.a,a.b)}function RGn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;if(n.c=n.d,l=null==(b=TD(mMn(t,(HXn(),dpt))))||(kW(b),b),c=BB(mMn(t,(hWn(),Zft)),21).Hc((bDn(),lft)),e=!((r=BB(mMn(t,ept),98))==(QEn(),UIt)||r==WIt||r==XIt),!l||!e&&c)f=new Jy(Pun(Gk(jut,1),JZn,37,0,[t]));else{for(h=new Wb(t.a);h.a<h.c.c.length;)BB(n0(h),10).p=0;for(f=new Np,s=new Wb(t.a);s.a<s.c.c.length;)if(i=LKn(n,BB(n0(s),10),null)){for(qan(o=new min,t),hon(o,Xft,BB(i.b,21)),kQ(o.d,t.d),hon(o,Hgt,null),u=BB(i.a,15).Kc();u.Ob();)a=BB(u.Pb(),10),WB(o.a,a),a.a=o;f.Fc(o)}c&&(GC(mMn(t,Idt))===GC((Bfn(),lut))?n.c=n.b:n.c=n.a)}return GC(mMn(t,Idt))!==GC((Bfn(),wut))&&(SQ(),f.ad(new xt)),f}function _Gn(n){NM(n,new MTn(mj(dj(vj(wj(pj(gj(new du,Q3n),"ELK Mr. Tree"),"Tree-based algorithm provided by the Eclipse Layout Kernel. Computes a spanning tree of the input graph and arranges all nodes according to the resulting parent-children hierarchy. I pity the fool who doesn't use Mr. Tree Layout."),new Na),Y3n),nbn((hAn(),JOt))))),u2(n,Q3n,QJn,Okt),u2(n,Q3n,vZn,20),u2(n,Q3n,VJn,dZn),u2(n,Q3n,pZn,iln(1)),u2(n,Q3n,kZn,(hN(),!0)),u2(n,Q3n,X2n,mpn(Ekt)),u2(n,Q3n,PZn,mpn(Mkt)),u2(n,Q3n,BZn,mpn(Skt)),u2(n,Q3n,SZn,mpn(Pkt)),u2(n,Q3n,IZn,mpn(Tkt)),u2(n,Q3n,MZn,mpn(Ikt)),u2(n,Q3n,CZn,mpn(Akt)),u2(n,Q3n,X3n,mpn(Dkt)),u2(n,Q3n,W3n,mpn(Lkt))}function KGn(n){n.q||(n.q=!0,n.p=kan(n,0),n.a=kan(n,1),_rn(n.a,0),n.f=kan(n,2),_rn(n.f,1),Rrn(n.f,2),n.n=kan(n,3),Rrn(n.n,3),Rrn(n.n,4),Rrn(n.n,5),Rrn(n.n,6),n.g=kan(n,4),_rn(n.g,7),Rrn(n.g,8),n.c=kan(n,5),_rn(n.c,7),_rn(n.c,8),n.i=kan(n,6),_rn(n.i,9),_rn(n.i,10),_rn(n.i,11),_rn(n.i,12),Rrn(n.i,13),n.j=kan(n,7),_rn(n.j,9),n.d=kan(n,8),_rn(n.d,3),_rn(n.d,4),_rn(n.d,5),_rn(n.d,6),Rrn(n.d,7),Rrn(n.d,8),Rrn(n.d,9),Rrn(n.d,10),n.b=kan(n,9),Rrn(n.b,0),Rrn(n.b,1),n.e=kan(n,10),Rrn(n.e,1),Rrn(n.e,2),Rrn(n.e,3),Rrn(n.e,4),_rn(n.e,5),_rn(n.e,6),_rn(n.e,7),_rn(n.e,8),_rn(n.e,9),_rn(n.e,10),Rrn(n.e,11),n.k=kan(n,11),Rrn(n.k,0),Rrn(n.k,1),n.o=jan(n,12),n.s=jan(n,13))}function FGn(n,t){t.dc()&&eH(n.j,!0,!0,!0,!0),Nfn(t,(kUn(),dCt))&&eH(n.j,!0,!0,!0,!1),Nfn(t,hCt)&&eH(n.j,!1,!0,!0,!0),Nfn(t,ECt)&&eH(n.j,!0,!0,!1,!0),Nfn(t,MCt)&&eH(n.j,!0,!1,!0,!0),Nfn(t,gCt)&&eH(n.j,!1,!0,!0,!1),Nfn(t,fCt)&&eH(n.j,!1,!0,!1,!0),Nfn(t,TCt)&&eH(n.j,!0,!1,!1,!0),Nfn(t,jCt)&&eH(n.j,!0,!1,!0,!1),Nfn(t,yCt)&&eH(n.j,!0,!0,!0,!0),Nfn(t,bCt)&&eH(n.j,!0,!0,!0,!0),Nfn(t,yCt)&&eH(n.j,!0,!0,!0,!0),Nfn(t,lCt)&&eH(n.j,!0,!0,!0,!0),Nfn(t,kCt)&&eH(n.j,!0,!0,!0,!0),Nfn(t,mCt)&&eH(n.j,!0,!0,!0,!0),Nfn(t,vCt)&&eH(n.j,!0,!0,!0,!0)}function BGn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g;for(c=new Np,s=new Wb(i);s.a<s.c.c.length;)if(a=null,(u=BB(n0(s),441)).f==(ain(),qvt))for(w=new Wb(u.e);w.a<w.c.c.length;)vW(g=(b=BB(n0(w),17)).d.i)==t?Stn(n,t,u,b,u.b,b.d):!e||wan(g,e)?GMn(n,t,u,i,b):((l=LHn(n,t,e,b,u.b,qvt,a))!=a&&(c.c[c.c.length]=l),l.c&&(a=l));else for(f=new Wb(u.e);f.a<f.c.c.length;)if(vW(d=(h=BB(n0(f),17)).c.i)==t)Stn(n,t,u,h,h.c,u.b);else{if(!e||wan(d,e))continue;(l=LHn(n,t,e,h,u.b,Hvt,a))!=a&&(c.c[c.c.length]=l),l.c&&(a=l)}for(o=new Wb(c);o.a<o.c.c.length;)u=BB(n0(o),441),-1!=E7(t.a,u.a,0)||WB(t.a,u.a),u.c&&(r.c[r.c.length]=u)}function HGn(n,t,e){var i,r,c,a,u,o,s,h;for(o=new Np,u=new Wb(t.a);u.a<u.c.c.length;)for(h=abn(BB(n0(u),10),(kUn(),oCt)).Kc();h.Ob();)for(r=new Wb(BB(h.Pb(),11).g);r.a<r.c.c.length;)!b5(i=BB(n0(r),17))&&i.c.i.c==i.d.i.c||b5(i)||i.d.i.c!=e||(o.c[o.c.length]=i);for(a=ean(e.a).Kc();a.Ob();)for(h=abn(BB(a.Pb(),10),(kUn(),ICt)).Kc();h.Ob();)for(r=new Wb(BB(h.Pb(),11).e);r.a<r.c.c.length;)if((b5(i=BB(n0(r),17))||i.c.i.c!=i.d.i.c)&&!b5(i)&&i.c.i.c==t){for(Px((s=new M2(o,o.c.length)).b>0),c=BB(s.a.Xb(s.c=--s.b),17);c!=i&&s.b>0;)n.a[c.p]=!0,n.a[i.p]=!0,Px(s.b>0),c=BB(s.a.Xb(s.c=--s.b),17);s.b>0&&fW(s)}}function qGn(n,t,e){var i,r,c,a,u,o,s,h,f;if(n.a!=t.Aj())throw Hp(new Ky(d6n+t.ne()+g6n));if(i=Ifn((CPn(),Z$t),t).$k())return i.Aj().Nh().Ih(i,e);if(a=Ifn(Z$t,t).al()){if(null==e)return null;if((u=BB(e,15)).dc())return"";for(f=new Sk,c=u.Kc();c.Ob();)r=c.Pb(),cO(f,a.Aj().Nh().Ih(a,r)),f.a+=" ";return _O(f,f.a.length-1)}if(!(h=Ifn(Z$t,t).bl()).dc()){for(s=h.Kc();s.Ob();)if((o=BB(s.Pb(),148)).wj(e))try{if(null!=(f=o.Aj().Nh().Ih(o,e)))return f}catch(l){if(!cL(l=lun(l),102))throw Hp(l)}throw Hp(new Ky("Invalid value: '"+e+"' for datatype :"+t.ne()))}return BB(t,834).Fj(),null==e?null:cL(e,172)?""+BB(e,172).a:tsn(e)==mtt?H$(COt[0],BB(e,199)):Bbn(e)}function GGn(n){var t,i,r,c,a,u,o,s,h;for(s=new YT,u=new YT,c=new Wb(n);c.a<c.c.c.length;)(i=BB(n0(c),128)).v=0,i.n=i.i.c.length,i.u=i.t.c.length,0==i.n&&r5(s,i,s.c.b,s.c),0==i.u&&0==i.r.a.gc()&&r5(u,i,u.c.b,u.c);for(a=-1;0!=s.b;)for(t=new Wb((i=BB(tkn(s,0),128)).t);t.a<t.c.c.length;)(h=BB(n0(t),268).b).v=e.Math.max(h.v,i.v+1),a=e.Math.max(a,h.v),--h.n,0==h.n&&r5(s,h,s.c.b,s.c);if(a>-1){for(r=spn(u,0);r.b!=r.d.c;)(i=BB(b3(r),128)).v=a;for(;0!=u.b;)for(t=new Wb((i=BB(tkn(u,0),128)).i);t.a<t.c.c.length;)0==(o=BB(n0(t),268).a).r.a.gc()&&(o.v=e.Math.min(o.v,i.v-1),--o.u,0==o.u&&r5(u,o,u.c.b,u.c))}}function zGn(n,t,i,r,c){var a,u,o,s;return s=RQn,u=!1,a=!!(o=zBn(n,XR(new xI(t.a,t.b),n),UR(new xI(i.a,i.b),c),XR(new xI(r.a,r.b),i)))&&!(e.Math.abs(o.a-n.a)<=s5n&&e.Math.abs(o.b-n.b)<=s5n||e.Math.abs(o.a-t.a)<=s5n&&e.Math.abs(o.b-t.b)<=s5n),(o=zBn(n,XR(new xI(t.a,t.b),n),i,c))&&((e.Math.abs(o.a-n.a)<=s5n&&e.Math.abs(o.b-n.b)<=s5n)==(e.Math.abs(o.a-t.a)<=s5n&&e.Math.abs(o.b-t.b)<=s5n)||a?s=e.Math.min(s,lW(XR(o,i))):u=!0),(o=zBn(n,XR(new xI(t.a,t.b),n),r,c))&&(u||(e.Math.abs(o.a-n.a)<=s5n&&e.Math.abs(o.b-n.b)<=s5n)==(e.Math.abs(o.a-t.a)<=s5n&&e.Math.abs(o.b-t.b)<=s5n)||a)&&(s=e.Math.min(s,lW(XR(o,r)))),s}function UGn(n){NM(n,new MTn(dj(vj(wj(pj(gj(new du,KZn),FZn),"Minimizes the stress within a layout using stress majorization. Stress exists if the euclidean distance between a pair of nodes doesn't match their graph theoretic distance, that is, the shortest path between the two nodes. The method allows to specify individual edge lengths."),new gt),gZn))),u2(n,KZn,jZn,mpn(kat)),u2(n,KZn,TZn,(hN(),!0)),u2(n,KZn,PZn,mpn(Tat)),u2(n,KZn,BZn,mpn(Mat)),u2(n,KZn,SZn,mpn(Sat)),u2(n,KZn,IZn,mpn(Eat)),u2(n,KZn,MZn,mpn(Pat)),u2(n,KZn,CZn,mpn(Iat)),u2(n,KZn,NZn,mpn(yat)),u2(n,KZn,DZn,mpn(vat)),u2(n,KZn,RZn,mpn(mat)),u2(n,KZn,_Zn,mpn(jat)),u2(n,KZn,xZn,mpn(pat))}function XGn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(OTn(t,"Interactive crossing minimization",1),a=0,c=new Wb(n.b);c.a<c.c.c.length;)(i=BB(n0(c),29)).p=a++;for(d=new Rj((l=qEn(n)).length),IHn(new Jy(Pun(Gk(jst,1),HWn,225,0,[d])),l),w=0,a=0,r=new Wb(n.b);r.a<r.c.c.length;){for(e=0,f=0,h=new Wb((i=BB(n0(r),29)).a);h.a<h.c.c.length;)for((o=BB(n0(h),10)).n.a>0&&(e+=o.n.a+o.o.a/2,++f),b=new Wb(o.j);b.a<b.c.c.length;)BB(n0(b),11).p=w++;for(f>0&&(e/=f),g=x8(xNt,qQn,25,i.a.c.length,15,1),u=0,s=new Wb(i.a);s.a<s.c.c.length;)(o=BB(n0(s),10)).p=u++,g[o.p]=MGn(o,e),o.k==(uSn(),Put)&&hon(o,(hWn(),plt),g[o.p]);SQ(),m$(i.a,new Gd(g)),rKn(d,l,a,!0),++a}HSn(t)}function WGn(n,t){var e,i,r,c,a,u,o,s,h;if(5!=t.e){if(null!=(s=t).b&&null!=n.b){for(T$n(n),qHn(n),T$n(s),qHn(s),e=x8(ANt,hQn,25,n.b.length+s.b.length,15,1),h=0,i=0,a=0;i<n.b.length&&a<s.b.length;)if(r=n.b[i],c=n.b[i+1],u=s.b[a],o=s.b[a+1],c<u)e[h++]=n.b[i++],e[h++]=n.b[i++];else if(c>=u&&r<=o)u<=r&&c<=o?i+=2:u<=r?(n.b[i]=o+1,a+=2):c<=o?(e[h++]=r,e[h++]=u-1,i+=2):(e[h++]=r,e[h++]=u-1,n.b[i]=o+1,a+=2);else{if(!(o<r))throw Hp(new dy("Token#subtractRanges(): Internal Error: ["+n.b[i]+","+n.b[i+1]+"] - ["+s.b[a]+","+s.b[a+1]+"]"));a+=2}for(;i<n.b.length;)e[h++]=n.b[i++],e[h++]=n.b[i++];n.b=x8(ANt,hQn,25,h,15,1),aHn(e,0,n.b,0,h)}}else kGn(n,t)}function VGn(n){var t,e,i,r,c,a,u;if(!n.A.dc()){if(n.A.Hc((mdn(),_Ct))&&(BB(oV(n.b,(kUn(),sCt)),124).k=!0,BB(oV(n.b,SCt),124).k=!0,t=n.q!=(QEn(),WIt)&&n.q!=XIt,Nl(BB(oV(n.b,oCt),124),t),Nl(BB(oV(n.b,ICt),124),t),Nl(n.g,t),n.A.Hc(KCt)&&(BB(oV(n.b,sCt),124).j=!0,BB(oV(n.b,SCt),124).j=!0,BB(oV(n.b,oCt),124).k=!0,BB(oV(n.b,ICt),124).k=!0,n.g.k=!0)),n.A.Hc(RCt))for(n.a.j=!0,n.a.k=!0,n.g.j=!0,n.g.k=!0,u=n.B.Hc((nKn(),XCt)),c=0,a=(r=tpn()).length;c<a;++c)i=r[c],(e=BB(oV(n.i,i),306))&&(agn(i)?(e.j=!0,e.k=!0):(e.j=!u,e.k=!u));n.A.Hc(DCt)&&n.B.Hc((nKn(),UCt))&&(n.g.j=!0,n.g.j=!0,n.a.j||(n.a.j=!0,n.a.k=!0,n.a.e=!0))}}function QGn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d;for(e=new Wb(n.e.b);e.a<e.c.c.length;)for(r=new Wb(BB(n0(e),29).a);r.a<r.c.c.length;)if(i=BB(n0(r),10),o=(f=n.i[i.p]).a.e,u=f.d.e,i.n.b=o,d=u-o-i.o.b,t=AHn(i),bvn(),h=(i.q?i.q:(SQ(),SQ(),het))._b((HXn(),Rgt))?BB(mMn(i,Rgt),197):BB(mMn(vW(i),_gt),197),t&&(h==fvt||h==hvt)&&(i.o.b+=d),t&&(h==bvt||h==fvt||h==hvt)){for(b=new Wb(i.j);b.a<b.c.c.length;)l=BB(n0(b),11),(kUn(),bCt).Hc(l.j)&&(s=BB(RX(n.k,l),121),l.n.b=s.e-o);for(a=new Wb(i.b);a.a<a.c.c.length;)c=BB(n0(a),70),(w=BB(mMn(i,$gt),21)).Hc((n$n(),NIt))?c.n.b+=d:w.Hc(xIt)&&(c.n.b+=d/2);(h==fvt||h==hvt)&&abn(i,(kUn(),SCt)).Jc(new ag(d))}}function YGn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(!n.b)return!1;for(a=null,l=null,r=1,(o=new H8(null,null)).a[1]=n.b,f=o;f.a[r];)s=r,u=l,l=f,f=f.a[r],r=(i=n.a.ue(t,f.d))<0?0:1,0==i&&(!e.c||cV(f.e,e.d))&&(a=f),f&&f.b||Vy(f.a[r])||(Vy(f.a[1-r])?l=l.a[s]=wrn(f,r):Vy(f.a[1-r])||(b=l.a[1-s])&&(Vy(b.a[1-s])||Vy(b.a[s])?(c=u.a[1]==l?1:0,Vy(b.a[s])?u.a[c]=r2(l,s):Vy(b.a[1-s])&&(u.a[c]=wrn(l,s)),f.b=u.a[c].b=!0,u.a[c].a[0].b=!1,u.a[c].a[1].b=!1):(l.b=!1,b.b=!0,f.b=!0)));return a&&(e.b=!0,e.d=a.e,f!=a&&(bMn(n,o,a,h=new H8(f.d,f.e)),l==a&&(l=h)),l.a[l.a[1]==f?1:0]=f.a[f.a[0]?0:1],--n.c),n.b=o.a[1],n.b&&(n.b.b=!1),e.b}function JGn(n){var t,i,r,c,a,u,o,s,h,f,l,b;for(c=new Wb(n.a.a.b);c.a<c.c.c.length;)for(s=(r=BB(n0(c),57)).c.Kc();s.Ob();)o=BB(s.Pb(),57),r.a!=o.a&&(l=dA(n.a.d)?n.a.g.Oe(r,o):n.a.g.Pe(r,o),a=r.b.a+r.d.b+l-o.b.a,a=e.Math.ceil(a),a=e.Math.max(0,a),Z7(r,o)?(u=AN(new qv,n.d),t=(h=IJ(e.Math.ceil(o.b.a-r.b.a)))-(o.b.a-r.b.a),i=r,(f=f3(r).a)||(f=f3(o).a,t=-t,i=o),f&&(i.b.a-=t,f.n.a-=t),UNn(aM(cM(uM(rM(new Hv,e.Math.max(0,h)),1),u),n.c[r.a.d])),UNn(aM(cM(uM(rM(new Hv,e.Math.max(0,-h)),1),u),n.c[o.a.d]))):(b=1,(cL(r.g,145)&&cL(o.g,10)||cL(o.g,145)&&cL(r.g,10))&&(b=2),UNn(aM(cM(uM(rM(new Hv,IJ(a)),b),n.c[r.a.d]),n.c[o.a.d]))))}function ZGn(n,t,i){var r,c,a,u,o,s,h,f,l,b;if(i)for(r=-1,f=new M2(t,0);f.b<f.d.gc();){if(Px(f.b<f.d.gc()),o=BB(f.d.Xb(f.c=f.b++),10),null==(l=n.c[o.c.p][o.p].a)){for(u=r+1,a=new M2(t,f.b);a.b<a.d.gc();)if(null!=(b=wL(n,(Px(a.b<a.d.gc()),BB(a.d.Xb(a.c=a.b++),10))).a)){kW(b),u=b;break}l=(r+u)/2,n.c[o.c.p][o.p].a=l,n.c[o.c.p][o.p].d=(kW(l),l),n.c[o.c.p][o.p].b=1}kW(l),r=l}else{for(c=0,h=new Wb(t);h.a<h.c.c.length;)o=BB(n0(h),10),null!=n.c[o.c.p][o.p].a&&(c=e.Math.max(c,Gy(n.c[o.c.p][o.p].a)));for(c+=2,s=new Wb(t);s.a<s.c.c.length;)o=BB(n0(s),10),null==n.c[o.c.p][o.p].a&&(l=H$n(n.i,24)*uYn*c-1,n.c[o.c.p][o.p].a=l,n.c[o.c.p][o.p].d=l,n.c[o.c.p][o.p].b=1)}}function nzn(){RO(BAt,new ts),RO(_At,new ls),RO(qAt,new Es),RO(HAt,new Cs),RO(GAt,new Os),RO(XAt,new As),RO(WAt,new $s),RO(HOt,new Ls),RO(BOt,new zo),RO(qOt,new Uo),RO(LOt,new Xo),RO(QAt,new Wo),RO(GOt,new Vo),RO(YAt,new Qo),RO(JAt,new Yo),RO(FAt,new Jo),RO(KAt,new Zo),RO(X$t,new ns),RO(VAt,new es),RO(O$t,new is),RO(ktt,new rs),RO(Gk(NNt,1),new cs),RO(Ttt,new as),RO(Stt,new us),RO(mtt,new os),RO(KNt,new ss),RO(Ptt,new hs),RO(uAt,new fs),RO(yAt,new bs),RO(oLt,new ws),RO($$t,new ds),RO(Itt,new gs),RO(Att,new ps),RO($nt,new vs),RO(Rtt,new ms),RO(Nnt,new ys),RO(iLt,new ks),RO(FNt,new js),RO(Ktt,new Ts),RO(Qtt,new Ms),RO(sAt,new Ss),RO(BNt,new Ps)}function tzn(n,t,e){var i,r,c,a,u,o,s,h,f;for(!e&&(e=Gun(t.q.getTimezoneOffset())),r=6e4*(t.q.getTimezoneOffset()-e.a),o=u=new PD(rbn(fan(t.q.getTime()),r)),u.q.getTimezoneOffset()!=t.q.getTimezoneOffset()&&(r>0?r-=864e5:r+=864e5,o=new PD(rbn(fan(t.q.getTime()),r))),h=new Ck,s=n.a.length,c=0;c<s;)if((i=fV(n.a,c))>=97&&i<=122||i>=65&&i<=90){for(a=c+1;a<s&&fV(n.a,a)==i;++a);aWn(h,i,a-c,u,o,e),c=a}else if(39==i){if(++c<s&&39==fV(n.a,c)){h.a+="'",++c;continue}for(f=!1;!f;){for(a=c;a<s&&39!=fV(n.a,a);)++a;if(a>=s)throw Hp(new Ky("Missing trailing '"));a+1<s&&39==fV(n.a,a+1)?++a:f=!0,oO(h,fx(n.a,c,a)),c=a+1}}else h.a+=String.fromCharCode(i),++c;return h.a}function ezn(n){var t,e,i,r,c,a,u,o;for(t=null,i=new Wb(n);i.a<i.c.c.length;)Gy(lL((e=BB(n0(i),233)).g,e.d[0]).a),e.b=null,e.e&&e.e.gc()>0&&0==e.c&&(!t&&(t=new Np),t.c[t.c.length]=e);if(t)for(;0!=t.c.length;){if((e=BB(s6(t,0),233)).b&&e.b.c.length>0)for(!e.b&&(e.b=new Np),c=new Wb(e.b);c.a<c.c.c.length;)if(zy(lL((r=BB(n0(c),233)).g,r.d[0]).a)==zy(lL(e.g,e.d[0]).a)){if(E7(n,r,0)>E7(n,e,0))return new rC(r,e)}else if(Gy(lL(r.g,r.d[0]).a)>Gy(lL(e.g,e.d[0]).a))return new rC(r,e);for(u=(!e.e&&(e.e=new Np),e.e).Kc();u.Ob();)!(a=BB(u.Pb(),233)).b&&(a.b=new Np),LZ(0,(o=a.b).c.length),MS(o.c,0,e),a.c==o.c.length&&(t.c[t.c.length]=a)}return null}function izn(n,t){var e,i,r,c,a,u;if(null==n)return zWn;if(null!=t.a.zc(n,t))return"[...]";for(e=new $an(FWn,"[","]"),c=0,a=(r=n).length;c<a;++c)null!=(i=r[c])&&0!=(4&tsn(i).i)?!Array.isArray(i)||(u=vnn(i))>=14&&u<=16?cL(i,177)?b6(e,RIn(BB(i,177))):cL(i,190)?b6(e,JEn(BB(i,190))):cL(i,195)?b6(e,kSn(BB(i,195))):cL(i,2012)?b6(e,ZEn(BB(i,2012))):cL(i,48)?b6(e,DIn(BB(i,48))):cL(i,364)?b6(e,gCn(BB(i,364))):cL(i,832)?b6(e,xIn(BB(i,832))):cL(i,104)&&b6(e,NIn(BB(i,104))):t.a._b(i)?(e.a?oO(e.a,e.b):e.a=new lN(e.d),aO(e.a,"[...]")):b6(e,izn(een(i),new $q(t))):b6(e,null==i?zWn:Bbn(i));return e.a?0==e.e.length?e.a.a:e.a.a+""+e.e:e.c}function rzn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w,d,g;for(w=qSn(cDn(t,!1,!1)),r&&(w=Jon(w)),g=Gy(MD(ZAn(t,(Epn(),pct)))),Px(0!=w.b),b=BB(w.a.a.c,8),h=BB(Dpn(w,1),8),w.b>2?(gun(s=new Np,new s1(w,1,w.b)),qan(d=new EAn(XXn(s,g+n.a)),t),i.c[i.c.length]=d):d=BB(RX(n.b,r?PMn(t):OMn(t)),266),u=PMn(t),r&&(u=OMn(t)),a=iPn(b,u),o=g+n.a,a.a?(o+=e.Math.abs(b.b-h.b),l=new xI(h.a,(h.b+b.b)/2)):(o+=e.Math.abs(b.a-h.a),l=new xI((h.a+b.a)/2,h.b)),VW(r?n.d:n.c,t,new Cmn(d,a,l,o)),VW(n.b,t,d),!t.n&&(t.n=new eU(zOt,t,1,7)),f=new AL(t.n);f.e!=f.i.gc();)c=JRn(n,BB(kpn(f),137),!0,0,0),i.c[i.c.length]=c}function czn(n){var t,i,r,c,a,u,o,s,h;for(s=new Np,u=new Np,a=new Wb(n);a.a<a.c.c.length;)Vl(r=BB(n0(a),112),r.f.c.length),Ql(r,r.k.c.length),0==r.d&&(s.c[s.c.length]=r),0==r.i&&0==r.e.b&&(u.c[u.c.length]=r);for(i=-1;0!=s.c.length;)for(t=new Wb((r=BB(s6(s,0),112)).k);t.a<t.c.c.length;)Yl(h=BB(n0(t),129).b,e.Math.max(h.o,r.o+1)),i=e.Math.max(i,h.o),Vl(h,h.d-1),0==h.d&&(s.c[s.c.length]=h);if(i>-1){for(c=new Wb(u);c.a<c.c.c.length;)(r=BB(n0(c),112)).o=i;for(;0!=u.c.length;)for(t=new Wb((r=BB(s6(u,0),112)).f);t.a<t.c.c.length;)(o=BB(n0(t),129).a).e.b>0||(Yl(o,e.Math.min(o.o,r.o-1)),Ql(o,o.i-1),0==o.i&&(u.c[u.c.length]=o))}}function azn(n,t,e){var i,r,c,a,u;if(u=n.c,!t&&(t=L$t),n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&(a=new nU(n,1,2,u,n.c),e?e.Ei(a):e=a),u!=t)if(cL(n.Cb,284))n.Db>>16==-10?e=BB(n.Cb,284).nk(t,e):n.Db>>16==-15&&(!t&&(gWn(),t=l$t),!u&&(gWn(),u=l$t),n.Cb.nh()&&(a=new N7(n.Cb,1,13,u,t,uvn(H7(BB(n.Cb,59)),n),!1),e?e.Ei(a):e=a));else if(cL(n.Cb,88))n.Db>>16==-23&&(cL(t,88)||(gWn(),t=d$t),cL(u,88)||(gWn(),u=d$t),n.Cb.nh()&&(a=new N7(n.Cb,1,10,u,t,uvn(a4(BB(n.Cb,26)),n),!1),e?e.Ei(a):e=a));else if(cL(n.Cb,444))for(!(c=BB(n.Cb,836)).b&&(c.b=new Tp(new xm)),r=new Mp(new usn(new Pb(c.b.a).a));r.a.b;)e=azn(i=BB(ten(r.a).cd(),87),kLn(i,c),e);return e}function uzn(n,t){var e,i,r,c,a,u,o,s,h,f,l;for(a=qy(TD(ZAn(n,(HXn(),wgt)))),l=BB(ZAn(n,cpt),21),o=!1,s=!1,f=new AL((!n.c&&(n.c=new eU(XOt,n,9,9)),n.c));!(f.e==f.i.gc()||o&&s);){for(c=BB(kpn(f),118),u=0,r=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[(!c.d&&(c.d=new h_(KOt,c,8,5)),c.d),(!c.e&&(c.e=new h_(KOt,c,7,4)),c.e)])));dAn(r)&&(i=BB(U5(r),79),h=a&&QCn(i)&&qy(TD(ZAn(i,dgt))),e=bqn((!i.b&&(i.b=new h_(_Ot,i,4,7)),i.b),c)?n==JJ(PTn(BB(Wtn((!i.c&&(i.c=new h_(_Ot,i,5,8)),i.c),0),82))):n==JJ(PTn(BB(Wtn((!i.b&&(i.b=new h_(_Ot,i,4,7)),i.b),0),82))),!((h||e)&&++u>1)););(u>0||l.Hc((lCn(),eCt))&&(!c.n&&(c.n=new eU(zOt,c,1,7)),c.n).i>0)&&(o=!0),u>1&&(s=!0)}o&&t.Fc((bDn(),lft)),s&&t.Fc((bDn(),bft))}function ozn(n){var t,i,r,c,a,u,o,s,h,f,l,b;if((b=BB(ZAn(n,(sWn(),_St)),21)).dc())return null;if(o=0,u=0,b.Hc((mdn(),_Ct))){for(f=BB(ZAn(n,uPt),98),r=2,i=2,c=2,a=2,t=JJ(n)?BB(ZAn(JJ(n),bSt),103):BB(ZAn(n,bSt),103),h=new AL((!n.c&&(n.c=new eU(XOt,n,9,9)),n.c));h.e!=h.i.gc();)if(s=BB(kpn(h),118),(l=BB(ZAn(s,wPt),61))==(kUn(),PCt)&&(l=OFn(s,t),Ypn(s,wPt,l)),f==(QEn(),XIt))switch(l.g){case 1:r=e.Math.max(r,s.i+s.g);break;case 2:i=e.Math.max(i,s.j+s.f);break;case 3:c=e.Math.max(c,s.i+s.g);break;case 4:a=e.Math.max(a,s.j+s.f)}else switch(l.g){case 1:r+=s.g+2;break;case 2:i+=s.f+2;break;case 3:c+=s.g+2;break;case 4:a+=s.f+2}o=e.Math.max(r,c),u=e.Math.max(i,a)}return _Un(n,o,u,!0,!0)}function szn(n,t,i,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(m=BB(P4(ytn(AV(new Rq(null,new w1(t.d,16)),new $d(i)),new Ld(i)),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)]))),15),l=DWn,f=KVn,s=new Wb(t.b.j);s.a<s.c.c.length;)(o=BB(n0(s),11)).j==i&&(l=e.Math.min(l,o.p),f=e.Math.max(f,o.p));if(l==DWn)for(u=0;u<m.gc();u++)g9(BB(m.Xb(u),101),i,u);else for(Zq(y=x8(ANt,hQn,25,c.length,15,1),y.length),v=m.Kc();v.Ob();){for(p=BB(v.Pb(),101),a=BB(RX(n.b,p),177),h=0,g=l;g<=f;g++)a[g]&&(h=e.Math.max(h,r[g]));if(p.i){for(w=p.i.c,k=new Rv,b=0;b<c.length;b++)c[w][b]&&TU(k,iln(y[b]));for(;FT(k,iln(h));)++h}for(g9(p,i,h),d=l;d<=f;d++)a[d]&&(r[d]=h+1);p.i&&(y[p.i.c]=h)}}function hzn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d;for(c=null,r=new Wb(t.a);r.a<r.c.c.length;)AHn(i=BB(n0(r),10))?(h=new GV(i,!0,o=AN(oM(new qv,i),n.f),s=AN(oM(new qv,i),n.f)),f=i.o.b,bvn(),b=1e4,(l=(i.q?i.q:(SQ(),SQ(),het))._b((HXn(),Rgt))?BB(mMn(i,Rgt),197):BB(mMn(vW(i),_gt),197))==hvt&&(b=1),w=UNn(aM(cM(rM(uM(new Hv,b),IJ(e.Math.ceil(f))),o),s)),l==fvt&&TU(n.d,w),OKn(n,ean(abn(i,(kUn(),ICt))),h),OKn(n,abn(i,oCt),h),a=h):(d=AN(oM(new qv,i),n.f),JT(AV(new Rq(null,new w1(i.j,16)),new Bc),new tI(n,d)),a=new GV(i,!1,d,d)),n.i[i.p]=a,c&&(u=c.c.d.a+_$(n.n,c.c,i)+i.d.d,c.b||(u+=c.c.o.b),UNn(aM(cM(uM(rM(new Hv,IJ(e.Math.ceil(u))),0),c.d),a.a))),c=a}function fzn(n,t){var i,r,c,a,u,o,s,f,l,b,w,d,g;for(OTn(t,"Label dummy insertions",1),b=new Np,u=Gy(MD(mMn(n,(HXn(),jpt)))),f=Gy(MD(mMn(n,Spt))),l=BB(mMn(n,Udt),103),w=new Wb(n.a);w.a<w.c.c.length;)for(a=new oz(ZL(lbn(BB(n0(w),10)).a.Kc(),new h));dAn(a);)if((c=BB(U5(a),17)).c.i!=c.d.i&&tL(c.b,nst)){for(i=oLn(n,c,g=Etn(c),d=sx(c.b.c.length)),b.c[b.c.length]=i,r=i.o,o=new M2(c.b,0);o.b<o.d.gc();)Px(o.b<o.d.gc()),GC(mMn(s=BB(o.d.Xb(o.c=o.b++),70),Ydt))===GC((Rtn(),zPt))&&(l==(Ffn(),HPt)||l==_Pt?(r.a+=s.o.a+f,r.b=e.Math.max(r.b,s.o.b)):(r.a=e.Math.max(r.a,s.o.a),r.b+=s.o.b+f),d.c[d.c.length]=s,fW(o));l==(Ffn(),HPt)||l==_Pt?(r.a-=f,r.b+=u+g):r.b+=u-f+g}gun(n.a,b),HSn(t)}function lzn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w;for(l=XDn(n,t,a=new dOn(t)),w=e.Math.max(Gy(MD(mMn(t,(HXn(),agt)))),1),f=new Wb(l.a);f.a<f.c.c.length;)h=BB(n0(f),46),s=Bgn(BB(h.a,8),BB(h.b,8),w),zH(i,new xI(s.c,s.d)),zH(i,Kx(new xI(s.c,s.d),s.b,0)),zH(i,Kx(new xI(s.c,s.d),0,s.a)),zH(i,Kx(new xI(s.c,s.d),s.b,s.a));switch(b=a.d,o=Bgn(BB(l.b.a,8),BB(l.b.b,8),w),b==(kUn(),ICt)||b==oCt?(r.c[b.g]=e.Math.min(r.c[b.g],o.d),r.b[b.g]=e.Math.max(r.b[b.g],o.d+o.a)):(r.c[b.g]=e.Math.min(r.c[b.g],o.c),r.b[b.g]=e.Math.max(r.b[b.g],o.c+o.b)),c=_Qn,u=a.c.i.d,b.g){case 4:c=u.c;break;case 2:c=u.b;break;case 1:c=u.a;break;case 3:c=u.d}return r.a[b.g]=e.Math.max(r.a[b.g],c),a}function bzn(n){var t,e,i,r;if(-1!=(t=GO(e=null!=n.D?n.D:n.B,YTn(91)))){i=e.substr(0,t),r=new Sk;do{r.a+="["}while(-1!=(t=lx(e,91,++t)));m_(i,$Wn)?r.a+="Z":m_(i,S9n)?r.a+="B":m_(i,P9n)?r.a+="C":m_(i,I9n)?r.a+="D":m_(i,C9n)?r.a+="F":m_(i,O9n)?r.a+="I":m_(i,A9n)?r.a+="J":m_(i,$9n)?r.a+="S":(r.a+="L",r.a+=""+i,r.a+=";");try{return null}catch(c){if(!cL(c=lun(c),60))throw Hp(c)}}else if(-1==GO(e,YTn(46))){if(m_(e,$Wn))return $Nt;if(m_(e,S9n))return NNt;if(m_(e,P9n))return ONt;if(m_(e,I9n))return xNt;if(m_(e,C9n))return DNt;if(m_(e,O9n))return ANt;if(m_(e,A9n))return LNt;if(m_(e,$9n))return RNt}return null}function wzn(n,t,e){var i,r,c,a,u,o,s,h;for(qan(s=new $vn(e),t),hon(s,(hWn(),dlt),t),s.o.a=t.g,s.o.b=t.f,s.n.a=t.i,s.n.b=t.j,WB(e.a,s),VW(n.a,t,s),(0!=(!t.a&&(t.a=new eU(UOt,t,10,11)),t.a).i||qy(TD(ZAn(t,(HXn(),wgt)))))&&hon(s,Kft,(hN(),!0)),o=BB(mMn(e,Zft),21),(h=BB(mMn(s,(HXn(),ept)),98))==(QEn(),YIt)?hon(s,ept,QIt):h!=QIt&&o.Fc((bDn(),dft)),i=BB(mMn(e,Udt),103),u=new AL((!t.c&&(t.c=new eU(XOt,t,9,9)),t.c));u.e!=u.i.gc();)qy(TD(ZAn(a=BB(kpn(u),118),Ggt)))||Zzn(n,a,s,o,i,h);for(c=new AL((!t.n&&(t.n=new eU(zOt,t,1,7)),t.n));c.e!=c.i.gc();)!qy(TD(ZAn(r=BB(kpn(c),137),Ggt)))&&r.a&&WB(s.b,Hhn(r));return qy(TD(mMn(s,Tdt)))&&o.Fc((bDn(),hft)),qy(TD(mMn(s,bgt)))&&(o.Fc((bDn(),wft)),o.Fc(bft),hon(s,ept,QIt)),s}function dzn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;u=BB(RX(t.c,n),459),g=t.a.c,o=t.a.c+t.a.b,a=(E=u.f)<(T=u.a),b=new xI(g,E),p=new xI(o,T),w=new xI(r=(g+o)/2,E),v=new xI(r,T),c=eNn(n,E,T),y=g1(t.B),k=new xI(r,c),j=g1(t.D),e=lon(Pun(Gk(PMt,1),sVn,8,0,[y,k,j])),f=!1,(d=t.B.i)&&d.c&&u.d&&((s=a&&d.p<d.c.a.c.length-1||!a&&d.p>0)?s&&(h=d.p,a?++h:--h,f=!(cNn(i=ion(BB(xq(d.c.a,h),10)),y,e[0])||Bz(i,y,e[0]))):f=!0),l=!1,(m=t.D.i)&&m.c&&u.e&&(a&&m.p>0||!a&&m.p<m.c.a.c.length-1?(h=m.p,a?--h:++h,l=!(cNn(i=ion(BB(xq(m.c.a,h),10)),e[0],j)||Bz(i,e[0],j))):l=!0),f&&l&&DH(n.a,k),f||nin(n.a,Pun(Gk(PMt,1),sVn,8,0,[b,w])),l||nin(n.a,Pun(Gk(PMt,1),sVn,8,0,[v,p]))}function gzn(n,t){var e,i,r,c,a,u,o;if(cL(n.Ug(),160)?(gzn(BB(n.Ug(),160),t),t.a+=" > "):t.a+="Root ",m_((e=n.Tg().zb).substr(0,3),"Elk")?oO(t,e.substr(3)):t.a+=""+e,r=n.zg())oO((t.a+=" ",t),r);else if(cL(n,354)&&(o=BB(n,137).a))oO((t.a+=" ",t),o);else{for(c=new AL(n.Ag());c.e!=c.i.gc();)if(o=BB(kpn(c),137).a)return void oO((t.a+=" ",t),o);if(cL(n,352)&&(!(i=BB(n,79)).b&&(i.b=new h_(_Ot,i,4,7)),0!=i.b.i&&(!i.c&&(i.c=new h_(_Ot,i,5,8)),0!=i.c.i))){for(t.a+=" (",a=new cx((!i.b&&(i.b=new h_(_Ot,i,4,7)),i.b));a.e!=a.i.gc();)a.e>0&&(t.a+=FWn),gzn(BB(kpn(a),160),t);for(t.a+=e1n,u=new cx((!i.c&&(i.c=new h_(_Ot,i,5,8)),i.c));u.e!=u.i.gc();)u.e>0&&(t.a+=FWn),gzn(BB(kpn(u),160),t);t.a+=")"}}}function pzn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(c=BB(mMn(n,(hWn(),dlt)),79)){for(i=n.a,UR(r=new wA(e),$jn(n)),wan(n.d.i,n.c.i)?(l=n.c,XR(f=Aon(Pun(Gk(PMt,1),sVn,8,0,[l.n,l.a])),e)):f=g1(n.c),r5(i,f,i.a,i.a.a),b=g1(n.d),null!=mMn(n,Rlt)&&UR(b,BB(mMn(n,Rlt),8)),r5(i,b,i.c.b,i.c),Ztn(i,r),Lin(a=cDn(c,!0,!0),BB(Wtn((!c.b&&(c.b=new h_(_Ot,c,4,7)),c.b),0),82)),Nin(a,BB(Wtn((!c.c&&(c.c=new h_(_Ot,c,5,8)),c.c),0),82)),VFn(i,a),h=new Wb(n.b);h.a<h.c.c.length;)s=BB(n0(h),70),Sen(u=BB(mMn(s,dlt),137),s.o.a),Men(u,s.o.b),SA(u,s.n.a+r.a,s.n.b+r.b),Ypn(u,(Crn(),tst),TD(mMn(s,tst)));(o=BB(mMn(n,(HXn(),vgt)),74))?(Ztn(o,r),Ypn(c,vgt,o)):Ypn(c,vgt,null),t==(Mbn(),JPt)?Ypn(c,Zdt,JPt):Ypn(c,Zdt,null)}}function vzn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(b=t.c.length,l=0,f=new Wb(n.b);f.a<f.c.c.length;)if(0!=(p=(h=BB(n0(f),29)).a).c.length){for(s=0,v=null,r=BB(n0(g=new Wb(p)),10),c=null;r;){if((c=BB(xq(t,r.p),257)).c>=0){for(o=null,u=new M2(h.a,s+1);u.b<u.d.gc()&&(Px(u.b<u.d.gc()),a=BB(u.d.Xb(u.c=u.b++),10),!((o=BB(xq(t,a.p),257)).d==c.d&&o.c<c.c));)o=null;o&&(v&&(c5(i,r.p,iln(BB(xq(i,r.p),19).a-1)),BB(xq(e,v.p),15).Mc(c)),c=wTn(c,r,b++),t.c[t.c.length]=c,WB(e,new Np),v?(BB(xq(e,v.p),15).Fc(c),WB(i,iln(1))):WB(i,iln(0)))}w=null,g.a<g.c.c.length&&(w=BB(n0(g),10),d=BB(xq(t,w.p),257),BB(xq(e,r.p),15).Fc(d),c5(i,w.p,iln(BB(xq(i,w.p),19).a+1))),c.d=l,c.c=s++,v=r,r=w}++l}}function mzn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;return o=n,h=XR(new xI(t.a,t.b),n),s=i,f=XR(new xI(r.a,r.b),i),l=o.a,g=o.b,w=s.a,v=s.b,b=h.a,p=h.b,c=(d=f.a)*p-b*(m=f.b),h$(),rin(A3n),!(e.Math.abs(0-c)<=A3n||0==c||isNaN(0)&&isNaN(c))&&(a=1/c*((l-w)*p-(g-v)*b),u=1/c*-(-(l-w)*m+(g-v)*d),rin(A3n),(e.Math.abs(0-a)<=A3n||0==a||isNaN(0)&&isNaN(a)?0:0<a?-1:0>a?1:zO(isNaN(0),isNaN(a)))<0&&(rin(A3n),(e.Math.abs(a-1)<=A3n||1==a||isNaN(a)&&isNaN(1)?0:a<1?-1:a>1?1:zO(isNaN(a),isNaN(1)))<0)&&(rin(A3n),(e.Math.abs(0-u)<=A3n||0==u||isNaN(0)&&isNaN(u)?0:0<u?-1:0>u?1:zO(isNaN(0),isNaN(u)))<0)&&(rin(A3n),(e.Math.abs(u-1)<=A3n||1==u||isNaN(u)&&isNaN(1)?0:u<1?-1:u>1?1:zO(isNaN(u),isNaN(1)))<0))}function yzn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j;for(f=new hW(new iw(n));f.b!=f.c.a.d;)for(u=BB((h=s9(f)).d,56),t=BB(h.e,56),d=0,y=(null==(a=u.Tg()).i&&qFn(a),a.i).length;d<y;++d)if(null==a.i&&qFn(a),c=a.i,(s=d>=0&&d<c.length?c[d]:null).Ij()&&!s.Jj())if(cL(s,99))0==((o=BB(s,18)).Bb&h6n)&&(!(j=Ivn(o))||0==(j.Bb&h6n))&&mBn(n,o,u,t);else if(ZM(),BB(s,66).Oj()&&(e=BB((k=s)?BB(t,49).xh(k):null,153)))for(b=BB(u.ah(s),153),i=e.gc(),g=0,w=b.gc();g<w;++g)if(cL(l=b.il(g),99)){if(null==(r=lnn(n,m=b.jl(g)))&&null!=m){if(v=BB(l,18),!n.b||0!=(v.Bb&h6n)||Ivn(v))continue;r=m}if(!e.dl(l,r))for(p=0;p<i;++p)if(e.il(p)==l&&GC(e.jl(p))===GC(r)){e.ii(e.gc()-1,p),--i;break}}else e.dl(b.il(g),b.jl(g))}function kzn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m;if(p=QBn(t,i,n.g),c.n&&c.n&&a&&y0(c,o2(a),(Bsn(),uOt)),n.b)for(g=0;g<p.c.length;g++)l1(g,p.c.length),f=BB(p.c[g],200),0!=g&&(l1(g-1,p.c.length),ghn(f,(b=BB(p.c[g-1],200)).f+b.b+n.g)),mXn(g,p,i,n.g),Hkn(n,f),c.n&&a&&y0(c,o2(a),(Bsn(),uOt));else for(d=new Wb(p);d.a<d.c.c.length;)for(h=new Wb((w=BB(n0(d),200)).a);h.a<h.c.c.length;)xcn(v=new _J((s=BB(n0(h),187)).s,s.t,n.g),s),WB(w.d,v);return zmn(n,p),c.n&&c.n&&a&&y0(c,o2(a),(Bsn(),uOt)),m=e.Math.max(n.d,r.a-(u.b+u.c)),o=(l=e.Math.max(n.c,r.b-(u.d+u.a)))-n.c,n.e&&n.f&&(m/l<n.a?m=l*n.a:o+=m/n.a-l),n.e&&Odn(p,m,o),c.n&&c.n&&a&&y0(c,o2(a),(Bsn(),uOt)),new eq(n.a,m,n.c+o,(YLn(),KEt))}function jzn(n){var t,i,r,c,a,u,o,s,h,f;for(n.j=x8(ANt,hQn,25,n.g,15,1),n.o=new Np,JT(wnn(new Rq(null,new w1(n.e.b,16)),new Wc),new ug(n)),n.a=x8($Nt,ZYn,25,n.b,16,1),$fn(new Rq(null,new w1(n.e.b,16)),new sg(n)),f=new Np,JT(AV(wnn(new Rq(null,new w1(n.e.b,16)),new Qc),new og(n)),new eI(n,f)),o=new Wb(f);o.a<o.c.c.length;)if(!((u=BB(n0(o),508)).c.length<=1))if(2!=u.c.length){if(!XEn(u)&&!NPn(u,new Vc))for(s=new Wb(u),r=null;s.a<s.c.c.length;)t=BB(n0(s),17),i=n.c[t.p],h=!r||s.a>=s.c.c.length?X3((uSn(),Iut),Put):X3((uSn(),Put),Put),h*=2,c=i.a.g,i.a.g=e.Math.max(c,c+(h-c)),a=i.b.g,i.b.g=e.Math.max(a,a+(h-a)),r=t}else zAn(u),AHn((l1(0,u.c.length),BB(u.c[0],17)).d.i)||WB(n.o,u)}function Ezn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(m=GB(n),o=new Np,s=(c=n.c.length)-1,h=c+1;0!=m.a.c;){for(;0!=e.b;)Px(0!=e.b),p=BB(Atn(e,e.a.a),112),$J(m.a,p),p.g=s--,NFn(p,t,e,i);for(;0!=t.b;)Px(0!=t.b),v=BB(Atn(t,t.a.a),112),$J(m.a,v),v.g=h++,NFn(v,t,e,i);for(u=KVn,d=new Fb(new BR(new xN(new Kb(m.a).a).b));aS(d.a.a);){if(w=BB(mx(d.a).cd(),112),!i&&w.b>0&&w.a<=0){o.c=x8(Ant,HWn,1,0,5,1),o.c[o.c.length]=w;break}(b=w.i-w.d)>=u&&(b>u&&(o.c=x8(Ant,HWn,1,0,5,1),u=b),o.c[o.c.length]=w)}0!=o.c.length&&(a=BB(xq(o,pvn(r,o.c.length)),112),$J(m.a,a),a.g=h++,NFn(a,t,e,i),o.c=x8(Ant,HWn,1,0,5,1))}for(g=n.c.length+1,l=new Wb(n);l.a<l.c.c.length;)(f=BB(n0(l),112)).g<c&&(f.g=f.g+g)}function Tzn(n,t){var e;if(n.e)throw Hp(new Fy((ED(git),AYn+git.k+$Yn)));if(!SS(n.a,t))throw Hp(new dy(LYn+t+NYn));if(t==n.d)return n;switch(e=n.d,n.d=t,e.g){case 0:switch(t.g){case 2:Hmn(n);break;case 1:Ion(n),Hmn(n);break;case 4:nEn(n),Hmn(n);break;case 3:nEn(n),Ion(n),Hmn(n)}break;case 2:switch(t.g){case 1:Ion(n),RRn(n);break;case 4:nEn(n),Hmn(n);break;case 3:nEn(n),Ion(n),Hmn(n)}break;case 1:switch(t.g){case 2:Ion(n),RRn(n);break;case 4:Ion(n),nEn(n),Hmn(n);break;case 3:Ion(n),nEn(n),Ion(n),Hmn(n)}break;case 4:switch(t.g){case 2:nEn(n),Hmn(n);break;case 1:nEn(n),Ion(n),Hmn(n);break;case 3:Ion(n),RRn(n)}break;case 3:switch(t.g){case 2:Ion(n),nEn(n),Hmn(n);break;case 1:Ion(n),nEn(n),Ion(n),Hmn(n);break;case 4:Ion(n),RRn(n)}}return n}function Mzn(n,t){var e;if(n.d)throw Hp(new Fy((ED(Yat),AYn+Yat.k+$Yn)));if(!PI(n.a,t))throw Hp(new dy(LYn+t+NYn));if(t==n.c)return n;switch(e=n.c,n.c=t,e.g){case 0:switch(t.g){case 2:Zon(n);break;case 1:Pon(n),Zon(n);break;case 4:tEn(n),Zon(n);break;case 3:tEn(n),Pon(n),Zon(n)}break;case 2:switch(t.g){case 1:Pon(n),_Rn(n);break;case 4:tEn(n),Zon(n);break;case 3:tEn(n),Pon(n),Zon(n)}break;case 1:switch(t.g){case 2:Pon(n),_Rn(n);break;case 4:Pon(n),tEn(n),Zon(n);break;case 3:Pon(n),tEn(n),Pon(n),Zon(n)}break;case 4:switch(t.g){case 2:tEn(n),Zon(n);break;case 1:tEn(n),Pon(n),Zon(n);break;case 3:Pon(n),_Rn(n)}break;case 3:switch(t.g){case 2:Pon(n),tEn(n),Zon(n);break;case 1:Pon(n),tEn(n),Pon(n),Zon(n);break;case 4:Pon(n),_Rn(n)}}return n}function Szn(n,t,i){var r,c,a,u,o,s,f,l;for(s=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));s.e!=s.i.gc();)for(c=new oz(ZL(dLn(o=BB(kpn(s),33)).a.Kc(),new h));dAn(c);){if(!(r=BB(U5(c),79)).b&&(r.b=new h_(_Ot,r,4,7)),!(r.b.i<=1&&(!r.c&&(r.c=new h_(_Ot,r,5,8)),r.c.i<=1)))throw Hp(new ck("Graph must not contain hyperedges."));if(!nAn(r)&&o!=PTn(BB(Wtn((!r.c&&(r.c=new h_(_Ot,r,5,8)),r.c),0),82)))for(qan(f=new CR,r),hon(f,(Mrn(),sat),r),Rl(f,BB(qC(AY(i.f,o)),144)),_l(f,BB(RX(i,PTn(BB(Wtn((!r.c&&(r.c=new h_(_Ot,r,5,8)),r.c),0),82))),144)),WB(t.c,f),u=new AL((!r.n&&(r.n=new eU(zOt,r,1,7)),r.n));u.e!=u.i.gc();)qan(l=new m4(f,(a=BB(kpn(u),137)).a),a),hon(l,sat,a),l.e.a=e.Math.max(a.g,1),l.e.b=e.Math.max(a.f,1),KBn(l),WB(t.d,l)}}function Pzn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(EJ(l=new eUn(n),!(t==(Ffn(),HPt)||t==_Pt)),f=l.a,b=new bm,Dtn(),u=0,s=(c=Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length;u<s;++u)i=c[u],(h=fL(f,Git,i))&&(b.d=e.Math.max(b.d,h.Re()));for(a=0,o=(r=Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length;a<o;++a)i=r[a],(h=fL(f,Uit,i))&&(b.a=e.Math.max(b.a,h.Re()));for(p=0,m=(d=Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length;p<m;++p)(h=fL(f,d[p],Git))&&(b.b=e.Math.max(b.b,h.Se()));for(g=0,v=(w=Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length;g<v;++g)(h=fL(f,w[g],Uit))&&(b.c=e.Math.max(b.c,h.Se()));return b.d>0&&(b.d+=f.n.d,b.d+=f.d),b.a>0&&(b.a+=f.n.a,b.a+=f.d),b.b>0&&(b.b+=f.n.b,b.b+=f.d),b.c>0&&(b.c+=f.n.c,b.c+=f.d),b}function Izn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d;for(b=i.d,l=i.c,u=(a=new xI(i.f.a+i.d.b+i.d.c,i.f.b+i.d.d+i.d.a)).b,h=new Wb(n.a);h.a<h.c.c.length;)if((o=BB(n0(h),10)).k==(uSn(),Mut)){switch(r=BB(mMn(o,(hWn(),Qft)),61),c=BB(mMn(o,Yft),8),f=o.n,r.g){case 2:f.a=i.f.a+b.c-l.a;break;case 4:f.a=-l.a-b.b}switch(d=0,r.g){case 2:case 4:t==(QEn(),WIt)?(w=Gy(MD(mMn(o,Tlt))),f.b=a.b*w-BB(mMn(o,(HXn(),npt)),8).b,d=f.b+c.b,Jan(o,!1,!0)):t==XIt&&(f.b=Gy(MD(mMn(o,Tlt)))-BB(mMn(o,(HXn(),npt)),8).b,d=f.b+c.b,Jan(o,!1,!0))}u=e.Math.max(u,d)}for(i.f.b+=u-a.b,s=new Wb(n.a);s.a<s.c.c.length;)if((o=BB(n0(s),10)).k==(uSn(),Mut))switch(r=BB(mMn(o,(hWn(),Qft)),61),f=o.n,r.g){case 1:f.b=-l.b-b.d;break;case 3:f.b=i.f.b+b.a-l.b}}function Czn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j;for(r=BB(mMn(n,(qqn(),skt)),33),o=DWn,s=DWn,a=KVn,u=KVn,k=spn(n.b,0);k.b!=k.d.c;)w=(m=BB(b3(k),86)).e,d=m.f,o=e.Math.min(o,w.a-d.a/2),s=e.Math.min(s,w.b-d.b/2),a=e.Math.max(a,w.a+d.a/2),u=e.Math.max(u,w.b+d.b/2);for(l=new xI((b=BB(ZAn(r,(IAn(),Ckt)),116)).b-o,b.d-s),y=spn(n.b,0);y.b!=y.d.c;)cL(f=mMn(m=BB(b3(y),86),skt),239)&&SA(c=BB(f,33),(h=UR(m.e,l)).a-c.g/2,h.b-c.f/2);for(v=spn(n.a,0);v.b!=v.d.c;)p=BB(b3(v),188),(i=BB(mMn(p,skt),79))&&(r5(t=p.a,g=new wA(p.b.e),t.a,t.a.a),r5(t,j=new wA(p.c.e),t.c.b,t.c),ZMn(g,BB(Dpn(t,1),8),p.b.f),ZMn(j,BB(Dpn(t,t.b-2),8),p.c.f),VFn(t,cDn(i,!0,!0)));_Un(r,a-o+(b.b+b.c),u-s+(b.d+b.a),!1,!1)}function Ozn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;for(yR(o=new M2(s=n.b,0),new HX(n)),g=!1,c=1;o.b<o.d.gc();){for(Px(o.b<o.d.gc()),u=BB(o.d.Xb(o.c=o.b++),29),l1(c,s.c.length),b=BB(s.c[c],29),d=(w=a0(u.a)).c.length,l=new Wb(w);l.a<l.c.c.length;)PZ(h=BB(n0(l),10),b);if(g){for(f=W1(new fy(w),0);f.c.Sb();)for(r=new Wb(a0(fbn(h=BB(w5(f),10))));r.a<r.c.c.length;)tBn(i=BB(n0(r),17),!0),hon(n,(hWn(),qft),(hN(),!0)),e=iGn(n,i,d),t=BB(mMn(h,Rft),305),p=BB(xq(e,e.c.length-1),17),t.k=p.c.i,t.n=p,t.b=i.d.i,t.c=i;g=!1}else 0!=w.c.length&&(l1(0,w.c.length),BB(w.c[0],10).k==(uSn(),Tut)&&(g=!0,c=-1));++c}for(a=new M2(n.b,0);a.b<a.d.gc();)Px(a.b<a.d.gc()),0==BB(a.d.Xb(a.c=a.b++),29).a.c.length&&fW(a)}function Azn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if((f=BB(BB(h6(n.r,t),21),84)).gc()<=2||t==(kUn(),oCt)||t==(kUn(),ICt))JUn(n,t);else{for(g=n.u.Hc((lCn(),cCt)),i=t==(kUn(),sCt)?(Dan(),Rrt):(Dan(),Nrt),v=t==sCt?(G7(),irt):(G7(),crt),r=Zk(HK(i),n.s),p=t==sCt?RQn:_Qn,h=f.Kc();h.Ob();)!(o=BB(h.Pb(),111)).c||o.c.d.c.length<=0||(d=o.b.rf(),w=o.e,(b=(l=o.c).i).b=(a=l.n,l.e.a+a.b+a.c),b.a=(u=l.n,l.e.b+u.d+u.a),g?(b.c=w.a-(c=l.n,l.e.a+c.b+c.c)-n.s,g=!1):b.c=w.a+d.a+n.s,OY(v,uJn),l.f=v,l9(l,(J9(),Jit)),WB(r.d,new xG(b,kln(r,b))),p=t==sCt?e.Math.min(p,w.b):e.Math.max(p,w.b+o.b.rf().b));for(p+=t==sCt?-n.t:n.t,Pwn((r.e=p,r)),s=f.Kc();s.Ob();)!(o=BB(s.Pb(),111)).c||o.c.d.c.length<=0||((b=o.c.i).c-=o.e.a,b.d-=o.e.b)}}function $zn(n,t,i){var r;if(OTn(i,"StretchWidth layering",1),0!=t.a.c.length){for(n.c=t,n.t=0,n.u=0,n.i=RQn,n.g=_Qn,n.d=Gy(MD(mMn(t,(HXn(),ypt)))),zpn(n),PAn(n),SAn(n),xjn(n),ddn(n),n.i=e.Math.max(1,n.i),n.g=e.Math.max(1,n.g),n.d=n.d/n.i,n.f=n.g/n.i,n.s=Kvn(n),r=new HX(n.c),WB(n.c.b,r),n.r=a0(n.p),n.n=TJ(n.k,n.k.length);0!=n.r.c.length;)n.o=zhn(n),!n.o||Ton(n)&&0!=n.b.a.gc()?(xEn(n,r),r=new HX(n.c),WB(n.c.b,r),Frn(n.a,n.b),n.b.a.$b(),n.t=n.u,n.u=0):Ton(n)?(n.c.b.c=x8(Ant,HWn,1,0,5,1),r=new HX(n.c),WB(n.c.b,r),n.t=0,n.u=0,n.b.a.$b(),n.a.a.$b(),++n.f,n.r=a0(n.p),n.n=TJ(n.k,n.k.length)):(PZ(n.o,r),y7(n.r,n.o),TU(n.b,n.o),n.t=n.t-n.k[n.o.p]*n.d+n.j[n.o.p],n.u+=n.e[n.o.p]*n.d);t.a.c=x8(Ant,HWn,1,0,5,1),JPn(t.b),HSn(i)}else HSn(i)}function Lzn(n){var t,i,r,c;for(JT(AV(new Rq(null,new w1(n.a.b,16)),new yr),new kr),fEn(n),JT(AV(new Rq(null,new w1(n.a.b,16)),new jr),new Er),n.c==(Mbn(),JPt)&&(JT(AV(wnn(new Rq(null,new w1(new Ib(n.f),1)),new Tr),new Mr),new Md(n)),JT(AV($V(wnn(wnn(new Rq(null,new w1(n.d.b,16)),new Sr),new Pr),new Ir),new Cr),new Pd(n))),c=new xI(RQn,RQn),t=new xI(_Qn,_Qn),r=new Wb(n.a.b);r.a<r.c.c.length;)i=BB(n0(r),57),c.a=e.Math.min(c.a,i.d.c),c.b=e.Math.min(c.b,i.d.d),t.a=e.Math.max(t.a,i.d.c+i.d.b),t.b=e.Math.max(t.b,i.d.d+i.d.a);UR(kO(n.d.c),qx(new xI(c.a,c.b))),UR(kO(n.d.f),XR(new xI(t.a,t.b),c)),oNn(n,c,t),$U(n.f),$U(n.b),$U(n.g),$U(n.e),n.a.a.c=x8(Ant,HWn,1,0,5,1),n.a.b.c=x8(Ant,HWn,1,0,5,1),n.a=null,n.d=null}function Nzn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(i=new Np,w=new Wb(t.a);w.a<w.c.c.length;)if((l=(b=BB(n0(w),10)).e)&&(gun(i,Nzn(n,l,b)),EGn(n,l,b),BB(mMn(l,(hWn(),Zft)),21).Hc((bDn(),lft))))for(p=BB(mMn(b,(HXn(),ept)),98),f=BB(mMn(b,cpt),174).Hc((lCn(),eCt)),g=new Wb(b.j);g.a<g.c.c.length;)for(d=BB(n0(g),11),(r=BB(RX(n.b,d),10))||(hon(r=bXn(d,p,d.j,-(d.e.c.length-d.g.c.length),null,new Gj,d.o,BB(mMn(l,Udt),103),l),dlt,d),VW(n.b,d,r),WB(l.a,r)),c=BB(xq(r.j,0),11),s=new Wb(d.f);s.a<s.c.c.length;)o=BB(n0(s),70),(a=new qj).o.a=o.o.a,a.o.b=o.o.b,WB(c.f,a),f||(v=d.j,h=0,Hz(BB(mMn(b,cpt),21))&&(h=$Cn(o.n,o.o,d.o,0,v)),p==(QEn(),QIt)||(kUn(),bCt).Hc(v)?a.o.a=h:a.o.b=h);return BGn(n,t,e,i,u=new Np),e&&Iqn(n,t,e,u),u}function xzn(n,t,e){var i,r,c,a,u,o,s,h;if(!n.c[t.c.p][t.p].e){for(n.c[t.c.p][t.p].e=!0,n.c[t.c.p][t.p].b=0,n.c[t.c.p][t.p].d=0,n.c[t.c.p][t.p].a=null,h=new Wb(t.j);h.a<h.c.c.length;)for(s=BB(n0(h),11),o=(e?new Hw(s):new Gw(s)).Kc();o.Ob();)(a=(u=BB(o.Pb(),11)).i).c==t.c?a!=t&&(xzn(n,a,e),n.c[t.c.p][t.p].b+=n.c[a.c.p][a.p].b,n.c[t.c.p][t.p].d+=n.c[a.c.p][a.p].d):(n.c[t.c.p][t.p].d+=n.g[u.p],++n.c[t.c.p][t.p].b);if(c=BB(mMn(t,(hWn(),xft)),15))for(r=c.Kc();r.Ob();)i=BB(r.Pb(),10),t.c==i.c&&(xzn(n,i,e),n.c[t.c.p][t.p].b+=n.c[i.c.p][i.p].b,n.c[t.c.p][t.p].d+=n.c[i.c.p][i.p].d);n.c[t.c.p][t.p].b>0&&(n.c[t.c.p][t.p].d+=H$n(n.i,24)*uYn*.07000000029802322-.03500000014901161,n.c[t.c.p][t.p].a=n.c[t.c.p][t.p].d/n.c[t.c.p][t.p].b)}}function Dzn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w;for(l=new Wb(n);l.a<l.c.c.length;){for(nx((f=BB(n0(l),10)).n),nx(f.o),V6(f.f),VRn(f),aRn(f),w=new Wb(f.j);w.a<w.c.c.length;){for(nx((b=BB(n0(w),11)).n),nx(b.a),nx(b.o),qIn(b,amn(b.j)),(r=BB(mMn(b,(HXn(),ipt)),19))&&hon(b,ipt,iln(-r.a)),i=new Wb(b.g);i.a<i.c.c.length;){for(t=spn((e=BB(n0(i),17)).a,0);t.b!=t.d.c;)nx(BB(b3(t),8));if(a=BB(mMn(e,vgt),74))for(c=spn(a,0);c.b!=c.d.c;)nx(BB(b3(c),8));for(s=new Wb(e.b);s.a<s.c.c.length;)nx((u=BB(n0(s),70)).n),nx(u.o)}for(h=new Wb(b.f);h.a<h.c.c.length;)nx((u=BB(n0(h),70)).n),nx(u.o)}for(f.k==(uSn(),Mut)&&(hon(f,(hWn(),Qft),amn(BB(mMn(f,Qft),61))),wxn(f)),o=new Wb(f.b);o.a<o.c.c.length;)VRn(u=BB(n0(o),70)),nx(u.o),nx(u.n)}}function Rzn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y;for(n.e=t,u=nOn(t),m=new Np,i=new Wb(u);i.a<i.c.c.length;){for(e=BB(n0(i),15),y=new Np,m.c[m.c.length]=y,o=new Rv,l=e.Kc();l.Ob();){for(c=JRn(n,f=BB(l.Pb(),33),!0,0,0),y.c[y.c.length]=c,new xI(b=f.i,w=f.j),!f.n&&(f.n=new eU(zOt,f,1,7)),h=new AL(f.n);h.e!=h.i.gc();)r=JRn(n,BB(kpn(h),137),!1,b,w),y.c[y.c.length]=r;for(!f.c&&(f.c=new eU(XOt,f,9,9)),g=new AL(f.c);g.e!=g.i.gc();)for(a=JRn(n,d=BB(kpn(g),118),!1,b,w),y.c[y.c.length]=a,p=d.i+b,v=d.j+w,!d.n&&(d.n=new eU(zOt,d,1,7)),s=new AL(d.n);s.e!=s.i.gc();)r=JRn(n,BB(kpn(s),137),!1,p,v),y.c[y.c.length]=r;Frn(o,JQ(Wen(Pun(Gk(xnt,1),HWn,20,0,[dLn(f),wLn(f)]))))}ULn(n,o,y)}return n.f=new Kj(m),qan(n.f,t),n.f}function _zn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g;null==(w=RX(n.e,i))&&(s=BB(w=new py,183),o=new GX(t+"_s"+r),rtn(s,q6n,o)),nW(e,b=BB(w,183)),qQ(g=new py,"x",i.j),qQ(g,"y",i.k),rtn(b,U6n,g),qQ(f=new py,"x",i.b),qQ(f,"y",i.c),rtn(b,"endPoint",f),!WE((!i.a&&(i.a=new $L(xOt,i,5)),i.a))&&(c=new Wg(h=new Il),e5((!i.a&&(i.a=new $L(xOt,i,5)),i.a),c),rtn(b,D6n,h)),!!Svn(i)&&cMn(n.a,b,_6n,RPn(n,Svn(i))),!!Pvn(i)&&cMn(n.a,b,R6n,RPn(n,Pvn(i))),!(0==(!i.e&&(i.e=new h_(FOt,i,10,9)),i.e).i)&&(a=new SC(n,l=new Il),e5((!i.e&&(i.e=new h_(FOt,i,10,9)),i.e),a),rtn(b,F6n,l)),0!=(!i.g&&(i.g=new h_(FOt,i,9,10)),i.g).i&&(u=new PC(n,d=new Il),e5((!i.g&&(i.g=new h_(FOt,i,9,10)),i.g),u),rtn(b,K6n,d))}function Kzn(n){var t,i,r,c,a,u,o;for(qD(),r=n.f.n,u=EX(n.r).a.nc();u.Ob();){if(c=0,(a=BB(u.Pb(),111)).b.Xe((sWn(),aPt))&&(c=Gy(MD(a.b.We(aPt))))<0)switch(a.b.Hf().g){case 1:r.d=e.Math.max(r.d,-c);break;case 3:r.a=e.Math.max(r.a,-c);break;case 2:r.c=e.Math.max(r.c,-c);break;case 4:r.b=e.Math.max(r.b,-c)}if(Hz(n.u))switch(t=vcn(a.b,c),o=!BB(n.e.We(qSt),174).Hc((nKn(),HCt)),i=!1,a.b.Hf().g){case 1:i=t>r.d,r.d=e.Math.max(r.d,t),o&&i&&(r.d=e.Math.max(r.d,r.a),r.a=r.d+c);break;case 3:i=t>r.a,r.a=e.Math.max(r.a,t),o&&i&&(r.a=e.Math.max(r.a,r.d),r.d=r.a+c);break;case 2:i=t>r.c,r.c=e.Math.max(r.c,t),o&&i&&(r.c=e.Math.max(r.b,r.c),r.b=r.c+c);break;case 4:i=t>r.b,r.b=e.Math.max(r.b,t),o&&i&&(r.b=e.Math.max(r.b,r.c),r.c=r.b+c)}}}function Fzn(n){var t,e,i,r,c,a,u,o,s,h,f;for(s=new Wb(n);s.a<s.c.c.length;){switch(o=BB(n0(s),10),c=null,(a=BB(mMn(o,(HXn(),kgt)),163)).g){case 1:case 2:Jun(),c=$ht;break;case 3:case 4:Jun(),c=Oht}if(c)hon(o,(hWn(),Gft),(Jun(),$ht)),c==Oht?RNn(o,a,(ain(),Hvt)):c==$ht&&RNn(o,a,(ain(),qvt));else if(vA(BB(mMn(o,ept),98))&&0!=o.j.c.length){for(t=!0,f=new Wb(o.j);f.a<f.c.c.length;){if(!((h=BB(n0(f),11)).j==(kUn(),oCt)&&h.e.c.length-h.g.c.length>0||h.j==ICt&&h.e.c.length-h.g.c.length<0)){t=!1;break}for(r=new Wb(h.g);r.a<r.c.c.length;)if(e=BB(n0(r),17),(u=BB(mMn(e.d.i,kgt),163))==(Tbn(),Blt)||u==Hlt){t=!1;break}for(i=new Wb(h.e);i.a<i.c.c.length;)if(e=BB(n0(i),17),(u=BB(mMn(e.c.i,kgt),163))==(Tbn(),Klt)||u==Flt){t=!1;break}}t&&RNn(o,a,(ain(),Gvt))}}}function Bzn(n,t,i,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;for(E=0,w=0,l=new Wb(t.e);l.a<l.c.c.length;){for(f=BB(n0(l),10),b=0,o=0,s=i?BB(mMn(f,Xmt),19).a:KVn,v=r?BB(mMn(f,Wmt),19).a:KVn,h=e.Math.max(s,v),y=new Wb(f.j);y.a<y.c.c.length;){if(m=BB(n0(y),11),k=f.n.b+m.n.b+m.a.b,r)for(u=new Wb(m.g);u.a<u.c.c.length;)d=(g=(a=BB(n0(u),17)).d).i,t!=n.a[d.p]&&(p=e.Math.max(BB(mMn(d,Xmt),19).a,BB(mMn(d,Wmt),19).a),(j=BB(mMn(a,(HXn(),bpt)),19).a)>=h&&j>=p&&(b+=d.n.b+g.n.b+g.a.b-k,++o));if(i)for(u=new Wb(m.e);u.a<u.c.c.length;)d=(g=(a=BB(n0(u),17)).c).i,t!=n.a[d.p]&&(p=e.Math.max(BB(mMn(d,Xmt),19).a,BB(mMn(d,Wmt),19).a),(j=BB(mMn(a,(HXn(),bpt)),19).a)>=h&&j>=p&&(b+=d.n.b+g.n.b+g.a.b-k,++o))}o>0&&(E+=b/o,++w)}w>0?(t.a=c*E/w,t.g=w):(t.a=0,t.g=0)}function Hzn(n,t){var e,i,r,c,a,u,o,s,h,f;for(i=new Wb(n.a.b);i.a<i.c.c.length;)for(u=new Wb(BB(n0(i),29).a);u.a<u.c.c.length;)a=BB(n0(u),10),t.j[a.p]=a,t.i[a.p]=t.o==(oZ(),cyt)?_Qn:RQn;for($U(n.c),c=n.a.b,t.c==(gJ(),nyt)&&(c=cL(c,152)?o6(BB(c,152)):cL(c,131)?BB(c,131).a:cL(c,54)?new fy(c):new IT(c)),R9(n.e,t,n.b),yS(t.p,null),r=c.Kc();r.Ob();)for(o=BB(r.Pb(),29).a,t.o==(oZ(),cyt)&&(o=cL(o,152)?o6(BB(o,152)):cL(o,131)?BB(o,131).a:cL(o,54)?new fy(o):new IT(o)),f=o.Kc();f.Ob();)h=BB(f.Pb(),10),t.g[h.p]==h&&oXn(n,h,t);for(Hqn(n,t),e=c.Kc();e.Ob();)for(f=new Wb(BB(e.Pb(),29).a);f.a<f.c.c.length;)h=BB(n0(f),10),t.p[h.p]=t.p[t.g[h.p].p],h==t.g[h.p]&&(s=Gy(t.i[t.j[h.p].p]),(t.o==(oZ(),cyt)&&s>_Qn||t.o==ryt&&s<RQn)&&(t.p[h.p]=Gy(t.p[h.p])+s));n.e.cg()}function qzn(n,t,e,i){var r,c,a,u,o;return pNn(u=new eUn(t),i),r=!0,n&&n.Xe((sWn(),bSt))&&(r=(c=BB(n.We((sWn(),bSt)),103))==(Ffn(),BPt)||c==KPt||c==FPt),oRn(u,!1),Otn(u.e.wf(),new $K(u,!1,r)),LJ(u,u.f,(Dtn(),Git),(kUn(),sCt)),LJ(u,u.f,Uit,SCt),LJ(u,u.g,Git,ICt),LJ(u,u.g,Uit,oCt),Bpn(u,sCt),Bpn(u,SCt),hV(u,oCt),hV(u,ICt),qD(),(a=u.A.Hc((mdn(),DCt))&&u.B.Hc((nKn(),UCt))?ndn(u):null)&&rj(u.a,a),Kzn(u),ryn(u),cyn(u),VGn(u),M_n(u),mkn(u),Kgn(u,sCt),Kgn(u,SCt),IRn(u),PHn(u),e?(Gbn(u),ykn(u),Kgn(u,oCt),Kgn(u,ICt),o=u.B.Hc((nKn(),XCt)),MIn(u,o,sCt),MIn(u,o,SCt),SIn(u,o,oCt),SIn(u,o,ICt),JT(new Rq(null,new w1(new Ob(u.i),0)),new Cn),JT(AV(new Rq(null,EX(u.r).a.oc()),new On),new An),BEn(u),u.e.uf(u.o),JT(new Rq(null,EX(u.r).a.oc()),new Ln),u.o):u.o}function Gzn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(h=RQn,r=new Wb(n.a.b);r.a<r.c.c.length;)t=BB(n0(r),81),h=e.Math.min(h,t.d.f.g.c+t.e.a);for(w=new YT,u=new Wb(n.a.a);u.a<u.c.c.length;)(a=BB(n0(u),189)).i=h,0==a.e&&r5(w,a,w.c.b,w.c);for(;0!=w.b;){for(c=(a=BB(0==w.b?null:(Px(0!=w.b),Atn(w,w.a.a)),189)).f.g.c,b=a.a.a.ec().Kc();b.Ob();)f=BB(b.Pb(),81),g=a.i+f.e.a,f.d.g||f.g.c<g?f.o=g:f.o=f.g.c;for(c-=a.f.o,a.b+=c,n.c==(Ffn(),FPt)||n.c==_Pt?a.c+=c:a.c-=c,l=a.a.a.ec().Kc();l.Ob();)for(s=(f=BB(l.Pb(),81)).f.Kc();s.Ob();)o=BB(s.Pb(),81),d=dA(n.c)?n.f.ef(f,o):n.f.ff(f,o),o.d.i=e.Math.max(o.d.i,f.o+f.g.b+d-o.e.a),o.k||(o.d.i=e.Math.max(o.d.i,o.g.c-o.e.a)),--o.d.e,0==o.d.e&&DH(w,o.d)}for(i=new Wb(n.a.b);i.a<i.c.c.length;)(t=BB(n0(i),81)).g.c=t.o}function zzn(n){var t,e,i,r,c,a,u,o;switch(u=n.b,t=n.a,0===BB(mMn(n,(Kkn(),Mit)),427).g?m$(u,new nw(new Gn)):m$(u,new nw(new zn)),1===BB(mMn(n,Eit),428).g?(m$(u,new qn),m$(u,new Un),m$(u,new _n)):(m$(u,new qn),m$(u,new Hn)),BB(mMn(n,Pit),250).g){case 0:o=new Yn;break;case 1:o=new Vn;break;case 2:o=new Qn;break;case 3:o=new Wn;break;case 5:o=new Ow(new Qn);break;case 4:o=new Ow(new Vn);break;case 7:o=new DS(new Ow(new Vn),new Ow(new Qn));break;case 8:o=new DS(new Ow(new Wn),new Ow(new Qn));break;default:o=new Ow(new Wn)}for(a=new Wb(u);a.a<a.c.c.length;){for(c=BB(n0(a),167),r=0,e=new rC(iln(i=0),iln(r));BKn(t,c,i,r);)e=BB(o.Ce(e,c),46),i=BB(e.a,19).a,r=BB(e.b,19).a;KRn(t,c,i,r)}}function Uzn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;for(l=(c=n.f.b).a,h=c.b,w=n.e.g,b=n.e.f,MA(n.e,c.a,c.b),j=l/w,E=h/b,s=new AL(mV(n.e));s.e!=s.i.gc();)Pen(o=BB(kpn(s),137),o.i*j),Ien(o,o.j*E);for(v=new AL(yV(n.e));v.e!=v.i.gc();)y=(p=BB(kpn(v),118)).i,k=p.j,y>0&&Pen(p,y*j),k>0&&Ien(p,k*E);for(nan(n.b,new lt),t=new Np,u=new usn(new Pb(n.c).a);u.b;)i=BB((a=ten(u)).cd(),79),e=BB(a.dd(),395).a,r=cDn(i,!1,!1),VFn(f=lTn(PMn(i),qSn(r),e),r),(m=IMn(i))&&-1==E7(t,m,0)&&(t.c[t.c.length]=m,sQ(m,(Px(0!=f.b),BB(f.a.a.c,8)),e));for(g=new usn(new Pb(n.d).a);g.b;)i=BB((d=ten(g)).cd(),79),e=BB(d.dd(),395).a,r=cDn(i,!1,!1),f=lTn(OMn(i),Jon(qSn(r)),e),VFn(f=Jon(f),r),(m=CMn(i))&&-1==E7(t,m,0)&&(t.c[t.c.length]=m,sQ(m,(Px(0!=f.b),BB(f.c.b.c,8)),e))}function Xzn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;if(0!=i.c.length){for(w=new Np,b=new Wb(i);b.a<b.c.c.length;)WB(w,new xI((l=BB(n0(b),33)).i,l.j));for(r.n&&t&&y0(r,o2(t),(Bsn(),uOt));NMn(n,i);)E$n(n,i,!1);for(r.n&&t&&y0(r,o2(t),(Bsn(),uOt)),u=0,o=0,c=null,0!=i.c.length&&(l1(0,i.c.length),u=(c=BB(i.c[0],33)).i-(l1(0,w.c.length),BB(w.c[0],8)).a,o=c.j-(l1(0,w.c.length),BB(w.c[0],8)).b),a=e.Math.sqrt(u*u+o*o),f=Uhn(i);0!=f.a.gc();){for(h=f.a.ec().Kc();h.Ob();)s=BB(h.Pb(),33),g=(d=n.f).i+d.g/2,p=d.j+d.f/2,v=s.i+s.g/2,y=s.j+s.f/2-p,j=(m=v-g)/(k=e.Math.sqrt(m*m+y*y)),E=y/k,Pen(s,s.i+j*a),Ien(s,s.j+E*a);r.n&&t&&y0(r,o2(t),(Bsn(),uOt)),f=Uhn(new tK(f))}n.a&&n.a.lg(new tK(f)),r.n&&t&&y0(r,o2(t),(Bsn(),uOt)),Xzn(n,t,new tK(f),r)}}function Wzn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if(g=n.n,p=n.o,b=n.d,l=Gy(MD(edn(n,(HXn(),ppt)))),t){for(f=l*(t.gc()-1),w=0,s=t.Kc();s.Ob();)f+=(u=BB(s.Pb(),10)).o.a,w=e.Math.max(w,u.o.b);for(v=g.a-(f-p.a)/2,a=g.b-b.d+w,c=r=p.a/(t.gc()+1),o=t.Kc();o.Ob();)(u=BB(o.Pb(),10)).n.a=v,u.n.b=a-u.o.b,v+=u.o.a+l,(h=DLn(u)).n.a=u.o.a/2-h.a.a,h.n.b=u.o.b,(d=BB(mMn(u,(hWn(),_ft)),11)).e.c.length+d.g.c.length==1&&(d.n.a=c-d.a.a,d.n.b=0,IZ(d,n)),c+=r}if(i){for(f=l*(i.gc()-1),w=0,s=i.Kc();s.Ob();)f+=(u=BB(s.Pb(),10)).o.a,w=e.Math.max(w,u.o.b);for(v=g.a-(f-p.a)/2,a=g.b+p.b+b.a-w,c=r=p.a/(i.gc()+1),o=i.Kc();o.Ob();)(u=BB(o.Pb(),10)).n.a=v,u.n.b=a,v+=u.o.a+l,(h=DLn(u)).n.a=u.o.a/2-h.a.a,h.n.b=0,(d=BB(mMn(u,(hWn(),_ft)),11)).e.c.length+d.g.c.length==1&&(d.n.a=c-d.a.a,d.n.b=p.b,IZ(d,n)),c+=r}}function Vzn(n,t){var i,r,c,a,u,o;if(BB(mMn(t,(hWn(),Zft)),21).Hc((bDn(),lft))){for(o=new Wb(t.a);o.a<o.c.c.length;)(a=BB(n0(o),10)).k==(uSn(),Iut)&&(c=BB(mMn(a,(HXn(),Igt)),142),n.c=e.Math.min(n.c,a.n.a-c.b),n.a=e.Math.max(n.a,a.n.a+a.o.a+c.c),n.d=e.Math.min(n.d,a.n.b-c.d),n.b=e.Math.max(n.b,a.n.b+a.o.b+c.a));for(u=new Wb(t.a);u.a<u.c.c.length;)if((a=BB(n0(u),10)).k!=(uSn(),Iut))switch(a.k.g){case 2:if((r=BB(mMn(a,(HXn(),kgt)),163))==(Tbn(),Flt)){a.n.a=n.c-10,Yyn(a,new Ge).Jb(new rd(a));break}if(r==Hlt){a.n.a=n.a+10,Yyn(a,new ze).Jb(new cd(a));break}if((i=BB(mMn(a,ilt),303))==(z7(),Ift)){lqn(a).Jb(new ad(a)),a.n.b=n.d-10;break}if(i==Sft){lqn(a).Jb(new ud(a)),a.n.b=n.b+10;break}break;default:throw Hp(new Ky("The node type "+a.k+" is not supported by the "+Jot))}}}function Qzn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d;for(o=new xI(i.i+i.g/2,i.j+i.f/2),l=XHn(i),b=BB(ZAn(t,(HXn(),ept)),98),d=BB(ZAn(i,upt),61),BC(lpn(i),tpt)||(w=0==i.i&&0==i.j?0:tMn(i,d),Ypn(i,tpt,w)),hon(r=bXn(i,b,d,l,new xI(t.g,t.f),o,new xI(i.g,i.f),BB(mMn(e,Udt),103),e),(hWn(),dlt),i),Hl(c=BB(xq(r.j,0),11),jKn(i)),hon(r,cpt,(lCn(),nbn(rCt))),h=BB(ZAn(t,cpt),174).Hc(eCt),u=new AL((!i.n&&(i.n=new eU(zOt,i,1,7)),i.n));u.e!=u.i.gc();)if(!qy(TD(ZAn(a=BB(kpn(u),137),Ggt)))&&a.a&&(f=Hhn(a),WB(c.f,f),!h))switch(s=0,Hz(BB(ZAn(t,cpt),21))&&(s=$Cn(new xI(a.i,a.j),new xI(a.g,a.f),new xI(i.g,i.f),0,d)),d.g){case 2:case 4:f.o.a=s;break;case 1:case 3:f.o.b=s}hon(r,Ipt,MD(ZAn(JJ(t),Ipt))),hon(r,Cpt,MD(ZAn(JJ(t),Cpt))),hon(r,Spt,MD(ZAn(JJ(t),Spt))),WB(e.a,r),VW(n.a,i,r)}function Yzn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(OTn(e,"Processor arrange level",1),h=0,SQ(),Krn(t,new ap((qqn(),ikt))),c=t.b,u=spn(t,t.b),s=!0;s&&u.b.b!=u.d.a;)g=BB(U0(u),86),0==BB(mMn(g,ikt),19).a?--c:s=!1;if(a=new nK(new s1(t,0,c)),o=new nK(new s1(t,c,t.b)),0==a.b)for(b=spn(o,0);b.b!=b.d.c;)hon(BB(b3(b),86),hkt,iln(h++));else for(f=a.b,m=spn(a,0);m.b!=m.d.c;){for(hon(v=BB(b3(m),86),hkt,iln(h++)),Yzn(n,i=xun(v),mcn(e,1/f|0)),Krn(i,QW(new ap(hkt))),l=new YT,p=spn(i,0);p.b!=p.d.c;)for(g=BB(b3(p),86),d=spn(v.d,0);d.b!=d.d.c;)(w=BB(b3(d),188)).c==g&&r5(l,w,l.c.b,l.c);for(yQ(v.d),Frn(v.d,l),u=spn(o,o.b),r=v.d.b,s=!0;0<r&&s&&u.b.b!=u.d.a;)g=BB(U0(u),86),0==BB(mMn(g,ikt),19).a?(hon(g,hkt,iln(h++)),--r,mtn(u)):s=!1}HSn(e)}function Jzn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(OTn(t,"Inverted port preprocessing",1),u=new M2(n.b,0),e=null,g=new Np;u.b<u.d.gc();){for(d=e,Px(u.b<u.d.gc()),e=BB(u.d.Xb(u.c=u.b++),29),h=new Wb(g);h.a<h.c.c.length;)PZ(o=BB(n0(h),10),d);for(g.c=x8(Ant,HWn,1,0,5,1),f=new Wb(e.a);f.a<f.c.c.length;)if((o=BB(n0(f),10)).k==(uSn(),Iut)&&vA(BB(mMn(o,(HXn(),ept)),98))){for(w=cRn(o,(ain(),Hvt),(kUn(),oCt)).Kc();w.Ob();)for(l=BB(w.Pb(),11),r=0,c=(i=BB(Qgn(a=l.e,x8(yut,c1n,17,a.c.length,0,1)),474)).length;r<c;++r)$Bn(n,l,i[r],g);for(b=cRn(o,qvt,ICt).Kc();b.Ob();)for(l=BB(b.Pb(),11),r=0,c=(i=BB(Qgn(a=l.g,x8(yut,c1n,17,a.c.length,0,1)),474)).length;r<c;++r)ABn(n,l,i[r],g)}}for(s=new Wb(g);s.a<s.c.c.length;)PZ(o=BB(n0(s),10),e);HSn(t)}function Zzn(n,t,e,i,r,c){var a,u,o,s,h,f;for(qan(s=new ISn,t),qIn(s,BB(ZAn(t,(HXn(),upt)),61)),hon(s,(hWn(),dlt),t),IZ(s,e),(f=s.o).a=t.g,f.b=t.f,(h=s.n).a=t.i,h.b=t.j,VW(n.a,t,s),(a=o5($V(wnn(new Rq(null,(!t.e&&(t.e=new h_(KOt,t,7,4)),new w1(t.e,16))),new Vt),new Xt),new Ww(t)))||(a=o5($V(wnn(new Rq(null,(!t.d&&(t.d=new h_(KOt,t,8,5)),new w1(t.d,16))),new Qt),new Wt),new Vw(t))),a||(a=o5(new Rq(null,(!t.e&&(t.e=new h_(KOt,t,7,4)),new w1(t.e,16))),new Yt)),hon(s,elt,(hN(),!!a)),pqn(s,c,r,BB(ZAn(t,npt),8)),o=new AL((!t.n&&(t.n=new eU(zOt,t,1,7)),t.n));o.e!=o.i.gc();)!qy(TD(ZAn(u=BB(kpn(o),137),Ggt)))&&u.a&&WB(s.f,Hhn(u));switch(r.g){case 2:case 1:(s.j==(kUn(),sCt)||s.j==SCt)&&i.Fc((bDn(),gft));break;case 4:case 3:(s.j==(kUn(),oCt)||s.j==ICt)&&i.Fc((bDn(),gft))}return s}function nUn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m;for(l=null,r==(dJ(),Lyt)?l=t:r==Nyt&&(l=i),d=l.a.ec().Kc();d.Ob();){for(w=BB(d.Pb(),11),g=Aon(Pun(Gk(PMt,1),sVn,8,0,[w.i.n,w.n,w.a])).b,m=new Rv,o=new Rv,h=new m6(w.b);y$(h.a)||y$(h.b);)if(qy(TD(mMn(s=BB(y$(h.a)?n0(h.a):n0(h.b),17),(hWn(),Ilt))))==c&&-1!=E7(a,s,0)){if(p=s.d==w?s.c:s.d,v=Aon(Pun(Gk(PMt,1),sVn,8,0,[p.i.n,p.n,p.a])).b,e.Math.abs(v-g)<.2)continue;v<g?t.a._b(p)?TU(m,new rC(Lyt,s)):TU(m,new rC(Nyt,s)):t.a._b(p)?TU(o,new rC(Lyt,s)):TU(o,new rC(Nyt,s))}if(m.a.gc()>1)for(e5(m,new sI(n,b=new hqn(w,m,r))),u.c[u.c.length]=b,f=m.a.ec().Kc();f.Ob();)y7(a,BB(f.Pb(),46).b);if(o.a.gc()>1)for(e5(o,new hI(n,b=new hqn(w,o,r))),u.c[u.c.length]=b,f=o.a.ec().Kc();f.Ob();)y7(a,BB(f.Pb(),46).b)}}function tUn(n){NM(n,new MTn(dj(vj(wj(pj(gj(new du,w4n),"ELK Radial"),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new Ha),w4n))),u2(n,w4n,g3n,mpn(xjt)),u2(n,w4n,vZn,mpn(_jt)),u2(n,w4n,PZn,mpn(Ijt)),u2(n,w4n,BZn,mpn(Cjt)),u2(n,w4n,SZn,mpn(Ojt)),u2(n,w4n,IZn,mpn(Pjt)),u2(n,w4n,MZn,mpn(Ajt)),u2(n,w4n,CZn,mpn(Njt)),u2(n,w4n,h4n,mpn(Mjt)),u2(n,w4n,s4n,mpn(Sjt)),u2(n,w4n,b4n,mpn($jt)),u2(n,w4n,u4n,mpn(Ljt)),u2(n,w4n,o4n,mpn(Djt)),u2(n,w4n,f4n,mpn(Rjt)),u2(n,w4n,l4n,mpn(Kjt))}function eUn(n){var t;if(this.r=xV(new Pn,new In),this.b=new Hbn(BB(yX(FCt),290)),this.p=new Hbn(BB(yX(FCt),290)),this.i=new Hbn(BB(yX(_rt),290)),this.e=n,this.o=new wA(n.rf()),this.D=n.Df()||qy(TD(n.We((sWn(),SSt)))),this.A=BB(n.We((sWn(),_St)),21),this.B=BB(n.We(qSt),21),this.q=BB(n.We(uPt),98),this.u=BB(n.We(fPt),21),!wMn(this.u))throw Hp(new rk("Invalid port label placement: "+this.u));if(this.v=qy(TD(n.We(bPt))),this.j=BB(n.We(DSt),21),!tLn(this.j))throw Hp(new rk("Invalid node label placement: "+this.j));this.n=BB(nkn(n,NSt),116),this.k=Gy(MD(nkn(n,OPt))),this.d=Gy(MD(nkn(n,CPt))),this.w=Gy(MD(nkn(n,RPt))),this.s=Gy(MD(nkn(n,APt))),this.t=Gy(MD(nkn(n,$Pt))),this.C=BB(nkn(n,xPt),142),this.c=2*this.d,t=!this.B.Hc((nKn(),HCt)),this.f=new Cgn(0,t,0),this.g=new Cgn(1,t,0),jy(this.f,(Dtn(),zit),this.g)}function iUn(n,t,i,r,c){var a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;for(y=0,g=0,d=0,w=1,m=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));m.e!=m.i.gc();)w+=F3(new oz(ZL(dLn(p=BB(kpn(m),33)).a.Kc(),new h))),T=p.g,g=e.Math.max(g,T),b=p.f,d=e.Math.max(d,b),y+=T*b;for(u=y+2*r*r*w*(!n.a&&(n.a=new eU(UOt,n,10,11)),n.a).i,a=e.Math.sqrt(u),s=e.Math.max(a*i,g),o=e.Math.max(a/i,d),v=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));v.e!=v.i.gc();)p=BB(kpn(v),33),M=c.b+(H$n(t,26)*rYn+H$n(t,27)*cYn)*(s-p.g),S=c.b+(H$n(t,26)*rYn+H$n(t,27)*cYn)*(o-p.f),Pen(p,M),Ien(p,S);for(E=s+(c.b+c.c),j=o+(c.d+c.a),k=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));k.e!=k.i.gc();)for(l=new oz(ZL(dLn(BB(kpn(k),33)).a.Kc(),new h));dAn(l);)nAn(f=BB(U5(l),79))||BXn(f,t,E,j);_Un(n,E+=c.b+c.c,j+=c.d+c.a,!1,!0)}function rUn(n){var t,e,i,r,c,a,u,o,s,h,f;if(null==n)throw Hp(new Mk(zWn));if(s=n,o=!1,(c=n.length)>0&&(b1(0,n.length),45!=(t=n.charCodeAt(0))&&43!=t||(n=n.substr(1),--c,o=45==t)),0==c)throw Hp(new Mk(DQn+s+'"'));for(;n.length>0&&(b1(0,n.length),48==n.charCodeAt(0));)n=n.substr(1),--c;if(c>(iFn(),xtt)[10])throw Hp(new Mk(DQn+s+'"'));for(r=0;r<c;r++)if(-1==egn((b1(r,n.length),n.charCodeAt(r))))throw Hp(new Mk(DQn+s+'"'));for(f=0,a=Ltt[10],h=Ntt[10],u=j7(Dtt[10]),e=!0,(i=c%a)>0&&(f=-parseInt(n.substr(0,i),10),n=n.substr(i),c-=i,e=!1);c>=a;){if(i=parseInt(n.substr(0,a),10),n=n.substr(a),c-=a,e)e=!1;else{if(Vhn(f,u)<0)throw Hp(new Mk(DQn+s+'"'));f=cbn(f,h)}f=ibn(f,i)}if(Vhn(f,0)>0)throw Hp(new Mk(DQn+s+'"'));if(!o&&Vhn(f=j7(f),0)<0)throw Hp(new Mk(DQn+s+'"'));return f}function cUn(n,t){var e,i,r,c,a,u,o;if(ZH(),this.a=new X$(this),this.b=n,this.c=t,this.f=OU(B7((CPn(),Z$t),t)),this.f.dc())if((u=mjn(Z$t,n))==t)for(this.e=!0,this.d=new Np,this.f=new fo,this.f.Fc(S7n),BB(NHn(F7(Z$t,Utn(n)),""),26)==n&&this.f.Fc(az(Z$t,Utn(n))),r=E_n(Z$t,n).Kc();r.Ob();)switch(i=BB(r.Pb(),170),DW(B7(Z$t,i))){case 4:this.d.Fc(i);break;case 5:this.f.Gc(OU(B7(Z$t,i)))}else if(ZM(),BB(t,66).Oj())for(this.e=!0,this.f=null,this.d=new Np,a=0,o=(null==n.i&&qFn(n),n.i).length;a<o;++a)for(null==n.i&&qFn(n),e=n.i,i=a>=0&&a<e.length?e[a]:null,c=Z1(B7(Z$t,i));c;c=Z1(B7(Z$t,c)))c==t&&this.d.Fc(i);else 1==DW(B7(Z$t,t))&&u?(this.f=null,this.d=(TOn(),bLt)):(this.f=null,this.e=!0,this.d=(SQ(),new Gb(t)));else this.e=5==DW(B7(Z$t,t)),this.f.Fb(uLt)&&(this.f=uLt)}function aUn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d;for(i=0,r=Pmn(n,t),b=n.s,w=n.t,h=BB(BB(h6(n.r,t),21),84).Kc();h.Ob();)if((s=BB(h.Pb(),111)).c&&!(s.c.d.c.length<=0)){switch(d=s.b.rf(),o=s.b.Xe((sWn(),aPt))?Gy(MD(s.b.We(aPt))):0,(l=(f=s.c).i).b=(u=f.n,f.e.a+u.b+u.c),l.a=(a=f.n,f.e.b+a.d+a.a),t.g){case 1:l.c=s.a?(d.a-l.b)/2:d.a+b,l.d=d.b+o+r,l9(f,(J9(),Qit)),WD(f,(G7(),crt));break;case 3:l.c=s.a?(d.a-l.b)/2:d.a+b,l.d=-o-r-l.a,l9(f,(J9(),Qit)),WD(f,(G7(),irt));break;case 2:l.c=-o-r-l.b,s.a?(c=n.v?l.a:BB(xq(f.d,0),181).rf().b,l.d=(d.b-c)/2):l.d=d.b+w,l9(f,(J9(),Jit)),WD(f,(G7(),rrt));break;case 4:l.c=d.a+o+r,s.a?(c=n.v?l.a:BB(xq(f.d,0),181).rf().b,l.d=(d.b-c)/2):l.d=d.b+w,l9(f,(J9(),Yit)),WD(f,(G7(),rrt))}(t==(kUn(),sCt)||t==SCt)&&(i=e.Math.max(i,l.a))}i>0&&(BB(oV(n.b,t),124).a.b=i)}function uUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(OTn(t,"Comment pre-processing",1),e=0,o=new Wb(n.a);o.a<o.c.c.length;)if(qy(TD(mMn(u=BB(n0(o),10),(HXn(),Tdt))))){for(++e,r=0,i=null,s=null,w=new Wb(u.j);w.a<w.c.c.length;)r+=(l=BB(n0(w),11)).e.c.length+l.g.c.length,1==l.e.c.length&&(s=(i=BB(xq(l.e,0),17)).c),1==l.g.c.length&&(s=(i=BB(xq(l.g,0),17)).d);if(1!=r||s.e.c.length+s.g.c.length!=1||qy(TD(mMn(s.i,Tdt)))){for(g=new Np,b=new Wb(u.j);b.a<b.c.c.length;){for(f=new Wb((l=BB(n0(b),11)).g);f.a<f.c.c.length;)0==(h=BB(n0(f),17)).d.g.c.length||(g.c[g.c.length]=h);for(a=new Wb(l.e);a.a<a.c.c.length;)0==(c=BB(n0(a),17)).c.e.c.length||(g.c[g.c.length]=c)}for(d=new Wb(g);d.a<d.c.c.length;)tBn(BB(n0(d),17),!0)}else nXn(u,i,s,s.i),AU(o)}t.n&&OH(t,"Found "+e+" comment boxes"),HSn(t)}function oUn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(l=Gy(MD(mMn(n,(HXn(),Ipt)))),b=Gy(MD(mMn(n,Cpt))),f=Gy(MD(mMn(n,Spt))),u=n.o,a=(c=BB(xq(n.j,0),11)).n,d=TPn(c,f)){if(t.Hc((lCn(),eCt)))switch(BB(mMn(n,(hWn(),Qft)),61).g){case 1:d.c=(u.a-d.b)/2-a.a,d.d=b;break;case 3:d.c=(u.a-d.b)/2-a.a,d.d=-b-d.a;break;case 2:e&&0==c.e.c.length&&0==c.g.c.length?(h=i?d.a:BB(xq(c.f,0),70).o.b,d.d=(u.b-h)/2-a.b):d.d=u.b+b-a.b,d.c=-l-d.b;break;case 4:e&&0==c.e.c.length&&0==c.g.c.length?(h=i?d.a:BB(xq(c.f,0),70).o.b,d.d=(u.b-h)/2-a.b):d.d=u.b+b-a.b,d.c=l}else if(t.Hc(rCt))switch(BB(mMn(n,(hWn(),Qft)),61).g){case 1:case 3:d.c=a.a+l;break;case 2:case 4:e&&!c.c?(h=i?d.a:BB(xq(c.f,0),70).o.b,d.d=(u.b-h)/2-a.b):d.d=a.b+b}for(r=d.d,s=new Wb(c.f);s.a<s.c.c.length;)(w=(o=BB(n0(s),70)).n).a=d.c,w.b=r,r+=o.o.b+f}}function sUn(){RO(wLt,new Vs),RO(zLt,new ah),RO(ULt,new ph),RO(XLt,new Ih),RO(Qtt,new $h),RO(Gk(NNt,1),new Lh),RO(ktt,new Nh),RO(Ttt,new xh),RO(Qtt,new Ks),RO(Qtt,new Fs),RO(Qtt,new Bs),RO(Ptt,new Hs),RO(Qtt,new qs),RO(Rnt,new Gs),RO(Rnt,new zs),RO(Qtt,new Us),RO(Itt,new Xs),RO(Qtt,new Ws),RO(Qtt,new Qs),RO(Qtt,new Ys),RO(Qtt,new Js),RO(Qtt,new Zs),RO(Gk(NNt,1),new nh),RO(Qtt,new th),RO(Qtt,new eh),RO(Rnt,new ih),RO(Rnt,new rh),RO(Qtt,new ch),RO(Att,new uh),RO(Qtt,new oh),RO(Rtt,new sh),RO(Qtt,new hh),RO(Qtt,new fh),RO(Qtt,new lh),RO(Qtt,new bh),RO(Rnt,new wh),RO(Rnt,new dh),RO(Qtt,new gh),RO(Qtt,new vh),RO(Qtt,new mh),RO(Qtt,new yh),RO(Qtt,new kh),RO(Qtt,new jh),RO(Ktt,new Eh),RO(Qtt,new Th),RO(Qtt,new Mh),RO(Qtt,new Sh),RO(Ktt,new Ph),RO(Rtt,new Ch),RO(Qtt,new Oh),RO(Att,new Ah)}function hUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if((f=t.length)>0&&(b1(0,t.length),64!=(u=t.charCodeAt(0)))){if(37==u&&(o=!1,0!=(h=t.lastIndexOf("%"))&&(h==f-1||(b1(h+1,t.length),o=46==t.charCodeAt(h+1))))){if(v=m_("%",a=t.substr(1,h-1))?null:$Un(a),i=0,o)try{i=lKn(t.substr(h+2),KVn,DWn)}catch(m){throw cL(m=lun(m),127)?Hp(new L7(m)):Hp(m)}for(d=Ern(n.Wg());d.Ob();)if(cL(b=Man(d),510)&&(p=(r=BB(b,590)).d,(null==v?null==p:m_(v,p))&&0==i--))return r;return null}if(l=-1==(s=t.lastIndexOf("."))?t:t.substr(0,s),e=0,-1!=s)try{e=lKn(t.substr(s+1),KVn,DWn)}catch(m){if(!cL(m=lun(m),127))throw Hp(m);l=t}for(l=m_("%",l)?null:$Un(l),w=Ern(n.Wg());w.Ob();)if(cL(b=Man(w),191)&&(g=(c=BB(b,191)).ne(),(null==l?null==g:m_(l,g))&&0==e--))return c;return null}return Kqn(n,t)}function fUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(m=new Np,f=new Wb(n.b);f.a<f.c.c.length;)for(w=new Wb(BB(n0(f),29).a);w.a<w.c.c.length;)if((l=BB(n0(w),10)).k==(uSn(),Mut)&&Lx(l,(hWn(),Vft))){for(d=null,p=null,g=null,j=new Wb(l.j);j.a<j.c.c.length;)switch((k=BB(n0(j),11)).j.g){case 4:d=k;break;case 2:p=k;break;default:g=k}for(s=new _j((v=BB(xq(g.g,0),17)).a),UR(o=new wA(g.n),l.n),nX(spn(s,0),o),y=Jon(v.a),UR(h=new wA(g.n),l.n),r5(y,h,y.c.b,y.c),E=BB(mMn(l,Vft),10),T=BB(xq(E.j,0),11),c=0,u=(i=BB(Qgn(d.e,x8(yut,c1n,17,0,0,1)),474)).length;c<u;++c)MZ(t=i[c],T),Wsn(t.a,t.a.b,s);for(r=0,a=(e=Z0(p.g)).length;r<a;++r)SZ(t=e[r],T),Wsn(t.a,0,y);SZ(v,null),MZ(v,null),m.c[m.c.length]=l}for(b=new Wb(m);b.a<b.c.c.length;)PZ(l=BB(n0(b),10),null)}function lUn(){var n,t,e;for(lUn=O,new knn(1,0),new knn(10,0),new knn(0,0),Htt=x8(iet,sVn,240,11,0,1),qtt=x8(ONt,WVn,25,100,15,1),Gtt=Pun(Gk(xNt,1),qQn,25,15,[1,5,25,125,625,3125,15625,78125,390625,1953125,9765625,48828125,244140625,1220703125,6103515625,30517578125,152587890625,762939453125,3814697265625,19073486328125,95367431640625,476837158203125,0x878678326eac9]),ztt=x8(ANt,hQn,25,Gtt.length,15,1),Utt=Pun(Gk(xNt,1),qQn,25,15,[1,10,100,VVn,1e4,GQn,1e6,1e7,1e8,AQn,1e10,1e11,1e12,1e13,1e14,1e15,1e16]),Xtt=x8(ANt,hQn,25,Utt.length,15,1),Wtt=x8(iet,sVn,240,11,0,1),n=0;n<Wtt.length;n++)Htt[n]=new knn(n,0),Wtt[n]=new knn(0,n),qtt[n]=48;for(;n<qtt.length;n++)qtt[n]=48;for(e=0;e<ztt.length;e++)ztt[e]=aCn(Gtt[e]);for(t=0;t<Xtt.length;t++)Xtt[t]=aCn(Utt[t]);$On()}function bUn(){function n(){this.obj=this.createObject()}return n.prototype.createObject=function(n){return Object.create(null)},n.prototype.get=function(n){return this.obj[n]},n.prototype.set=function(n,t){this.obj[n]=t},n.prototype[iYn]=function(n){delete this.obj[n]},n.prototype.keys=function(){return Object.getOwnPropertyNames(this.obj)},n.prototype.entries=function(){var n=this.keys(),t=this,e=0;return{next:function(){if(e>=n.length)return{done:!0};var i=n[e++];return{value:[i,t.get(i)],done:!1}}}},zDn()||(n.prototype.createObject=function(){return{}},n.prototype.get=function(n){return this.obj[":"+n]},n.prototype.set=function(n,t){this.obj[":"+n]=t},n.prototype[iYn]=function(n){delete this.obj[":"+n]},n.prototype.keys=function(){var n=[];for(var t in this.obj)58==t.charCodeAt(0)&&n.push(t.substring(1));return n}),n}function wUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d;if(PFn(),null==n)return null;if(0==(f=8*n.length))return"";for(l=f/24|0,c=null,c=x8(ONt,WVn,25,4*(0!=(u=f%24)?l+1:l),15,1),s=0,h=0,t=0,e=0,i=0,a=0,r=0,o=0;o<l;o++)t=n[r++],h=(15&(e=n[r++]))<<24>>24,s=(3&t)<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,w=0==(-128&e)?e>>4<<24>>24:(e>>4^240)<<24>>24,d=0==(-128&(i=n[r++]))?i>>6<<24>>24:(i>>6^252)<<24>>24,c[a++]=VLt[b],c[a++]=VLt[w|s<<4],c[a++]=VLt[h<<2|d],c[a++]=VLt[63&i];return 8==u?(s=(3&(t=n[r]))<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,c[a++]=VLt[b],c[a++]=VLt[s<<4],c[a++]=61,c[a++]=61):16==u&&(t=n[r],h=(15&(e=n[r+1]))<<24>>24,s=(3&t)<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,w=0==(-128&e)?e>>4<<24>>24:(e>>4^240)<<24>>24,c[a++]=VLt[b],c[a++]=VLt[w|s<<4],c[a++]=VLt[h<<2],c[a++]=61),Bdn(c,0,c.length)}function dUn(n,t){var i,r,c,a,u,o;if(0==n.e&&n.p>0&&(n.p=-(n.p-1)),n.p>KVn&&e4(t,n.p-sQn),u=t.q.getDate(),FJ(t,1),n.k>=0&&vZ(t,n.k),n.c>=0?FJ(t,n.c):n.k>=0?(r=35-new von(t.q.getFullYear()-sQn,t.q.getMonth(),35).q.getDate(),FJ(t,e.Math.min(r,u))):FJ(t,u),n.f<0&&(n.f=t.q.getHours()),n.b>0&&n.f<12&&(n.f+=12),aL(t,24==n.f&&n.g?0:n.f),n.j>=0&&g6(t,n.j),n.n>=0&&U8(t,n.n),n.i>=0&&dO(t,rbn(cbn(Ojn(fan(t.q.getTime()),VVn),VVn),n.i)),n.a&&(e4(c=new AT,c.q.getFullYear()-sQn-80),sS(fan(t.q.getTime()),fan(c.q.getTime()))&&e4(t,c.q.getFullYear()-sQn+100)),n.d>=0)if(-1==n.c)(i=(7+n.d-t.q.getDay())%7)>3&&(i-=7),o=t.q.getMonth(),FJ(t,t.q.getDate()+i),t.q.getMonth()!=o&&FJ(t,t.q.getDate()+(i>0?-7:7));else if(t.q.getDay()!=n.d)return!1;return n.o>KVn&&(a=t.q.getTimezoneOffset(),dO(t,rbn(fan(t.q.getTime()),60*(n.o-a)*VVn))),!0}function gUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;if(cL(r=mMn(t,(hWn(),dlt)),239)){for(b=BB(r,33),w=t.e,f=new wA(t.c),c=t.d,f.a+=c.b,f.b+=c.d,SN(BB(ZAn(b,(HXn(),qgt)),174),(nKn(),qCt))&&(Ol(l=BB(ZAn(b,zgt),116),c.a),Kl(l,c.d),Al(l,c.b),Fl(l,c.c)),e=new Np,s=new Wb(t.a);s.a<s.c.c.length;)for(cL(mMn(u=BB(n0(s),10),dlt),239)?IUn(u,f):cL(mMn(u,dlt),186)&&!w&&SA(i=BB(mMn(u,dlt),118),(g=yFn(t,u,i.g,i.f)).a,g.b),d=new Wb(u.j);d.a<d.c.c.length;)JT(AV(new Rq(null,new w1(BB(n0(d),11).g,16)),new Qw(u)),new Yw(e));if(w)for(d=new Wb(w.j);d.a<d.c.c.length;)JT(AV(new Rq(null,new w1(BB(n0(d),11).g,16)),new Jw(w)),new Zw(e));for(p=BB(ZAn(b,Zdt),218),a=new Wb(e);a.a<a.c.c.length;)pzn(BB(n0(a),17),p,f);for(mKn(t),o=new Wb(t.a);o.a<o.c.c.length;)(h=(u=BB(n0(o),10)).e)&&gUn(n,h)}}function pUn(n){NM(n,new MTn(mj(dj(vj(wj(pj(gj(new du,gZn),"ELK Force"),"Force-based algorithm provided by the Eclipse Layout Kernel. Implements methods that follow physical analogies by simulating forces that move the nodes into a balanced distribution. Currently the original Eades model and the Fruchterman - Reingold model are supported."),new dt),gZn),EG((hAn(),tAt),Pun(Gk(aAt,1),$Vn,237,0,[ZOt]))))),u2(n,gZn,pZn,iln(1)),u2(n,gZn,vZn,80),u2(n,gZn,mZn,5),u2(n,gZn,VJn,dZn),u2(n,gZn,yZn,iln(1)),u2(n,gZn,kZn,(hN(),!0)),u2(n,gZn,QJn,Qct),u2(n,gZn,jZn,mpn(Hct)),u2(n,gZn,EZn,mpn(Yct)),u2(n,gZn,TZn,!1),u2(n,gZn,MZn,mpn(Wct)),u2(n,gZn,SZn,mpn(Xct)),u2(n,gZn,PZn,mpn(Uct)),u2(n,gZn,IZn,mpn(zct)),u2(n,gZn,CZn,mpn(Jct)),u2(n,gZn,oZn,mpn(Gct)),u2(n,gZn,fZn,mpn(aat)),u2(n,gZn,sZn,mpn(qct)),u2(n,gZn,bZn,mpn(tat)),u2(n,gZn,hZn,mpn(eat))}function vUn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w;if(!BB(BB(h6(n.r,t),21),84).dc()){if(s=(u=BB(oV(n.b,t),124)).i,o=u.n,f=PDn(n,t),r=s.b-o.b-o.c,c=u.a.a,a=s.c+o.b,w=n.w,f!=(cpn(),BIt)&&f!=qIt||1!=BB(BB(h6(n.r,t),21),84).gc()||(c=f==BIt?c-2*n.w:c,f=FIt),r<c&&!n.B.Hc((nKn(),WCt)))f==BIt?a+=w+=(r-c)/(BB(BB(h6(n.r,t),21),84).gc()+1):w+=(r-c)/(BB(BB(h6(n.r,t),21),84).gc()-1);else switch(r<c&&(c=f==BIt?c-2*n.w:c,f=FIt),f.g){case 3:a+=(r-c)/2;break;case 4:a+=r-c;break;case 0:i=(r-c)/(BB(BB(h6(n.r,t),21),84).gc()+1),a+=w+=e.Math.max(0,i);break;case 1:i=(r-c)/(BB(BB(h6(n.r,t),21),84).gc()-1),w+=e.Math.max(0,i)}for(b=BB(BB(h6(n.r,t),21),84).Kc();b.Ob();)(l=BB(b.Pb(),111)).e.a=a+l.d.b,l.e.b=(h=l.b).Xe((sWn(),aPt))?h.Hf()==(kUn(),sCt)?-h.rf().b-Gy(MD(h.We(aPt))):Gy(MD(h.We(aPt))):h.Hf()==(kUn(),sCt)?-h.rf().b:0,a+=l.d.b+l.b.rf().a+l.d.c+w}}function mUn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d;if(!BB(BB(h6(n.r,t),21),84).dc()){if(s=(u=BB(oV(n.b,t),124)).i,o=u.n,l=PDn(n,t),r=s.a-o.d-o.a,c=u.a.b,a=s.d+o.d,d=n.w,h=n.o.a,l!=(cpn(),BIt)&&l!=qIt||1!=BB(BB(h6(n.r,t),21),84).gc()||(c=l==BIt?c-2*n.w:c,l=FIt),r<c&&!n.B.Hc((nKn(),WCt)))l==BIt?a+=d+=(r-c)/(BB(BB(h6(n.r,t),21),84).gc()+1):d+=(r-c)/(BB(BB(h6(n.r,t),21),84).gc()-1);else switch(r<c&&(c=l==BIt?c-2*n.w:c,l=FIt),l.g){case 3:a+=(r-c)/2;break;case 4:a+=r-c;break;case 0:i=(r-c)/(BB(BB(h6(n.r,t),21),84).gc()+1),a+=d+=e.Math.max(0,i);break;case 1:i=(r-c)/(BB(BB(h6(n.r,t),21),84).gc()-1),d+=e.Math.max(0,i)}for(w=BB(BB(h6(n.r,t),21),84).Kc();w.Ob();)(b=BB(w.Pb(),111)).e.a=(f=b.b).Xe((sWn(),aPt))?f.Hf()==(kUn(),ICt)?-f.rf().a-Gy(MD(f.We(aPt))):h+Gy(MD(f.We(aPt))):f.Hf()==(kUn(),ICt)?-f.rf().a:h,b.e.b=a+b.d.d,a+=b.d.d+b.b.rf().b+b.d.a+d}}function yUn(n){var t,i,r,c,a,u,o,s,f,l,b,w,d,g,p;for(n.n=Gy(MD(mMn(n.g,(HXn(),Opt)))),n.e=Gy(MD(mMn(n.g,Tpt))),n.i=n.g.b.c.length,o=n.i-1,w=0,n.j=0,n.k=0,n.a=u6(x8(Att,sVn,19,n.i,0,1)),n.b=u6(x8(Ptt,sVn,333,n.i,7,1)),u=new Wb(n.g.b);u.a<u.c.c.length;){for((c=BB(n0(u),29)).p=o,b=new Wb(c.a);b.a<b.c.c.length;)(l=BB(n0(b),10)).p=w,++w;--o}for(n.f=x8(ANt,hQn,25,w,15,1),n.c=kq(ANt,[sVn,hQn],[48,25],15,[w,3],2),n.o=new Np,n.p=new Np,t=0,n.d=0,a=new Wb(n.g.b);a.a<a.c.c.length;){for(o=(c=BB(n0(a),29)).p,r=0,p=0,s=c.a.c.length,f=0,b=new Wb(c.a);b.a<b.c.c.length;)w=(l=BB(n0(b),10)).p,n.f[w]=l.c.p,f+=l.o.b+n.n,i=F3(new oz(ZL(fbn(l).a.Kc(),new h))),g=F3(new oz(ZL(lbn(l).a.Kc(),new h))),n.c[w][0]=g-i,n.c[w][1]=i,n.c[w][2]=g,r+=i,p+=g,i>0&&WB(n.p,l),WB(n.o,l);d=s+(t-=r),f+=t*n.e,c5(n.a,o,iln(d)),c5(n.b,o,f),n.j=e.Math.max(n.j,d),n.k=e.Math.max(n.k,f),n.d+=t,t+=p}}function kUn(){var n;kUn=O,PCt=new WI(hJn,0),sCt=new WI(mJn,1),oCt=new WI(yJn,2),SCt=new WI(kJn,3),ICt=new WI(jJn,4),SQ(),wCt=new Ak(new Y_(n=BB(Vj(FCt),9),BB(SR(n,n.length),9),0)),dCt=ffn(EG(sCt,Pun(Gk(FCt,1),YZn,61,0,[]))),hCt=ffn(EG(oCt,Pun(Gk(FCt,1),YZn,61,0,[]))),ECt=ffn(EG(SCt,Pun(Gk(FCt,1),YZn,61,0,[]))),MCt=ffn(EG(ICt,Pun(Gk(FCt,1),YZn,61,0,[]))),yCt=ffn(EG(sCt,Pun(Gk(FCt,1),YZn,61,0,[SCt]))),bCt=ffn(EG(oCt,Pun(Gk(FCt,1),YZn,61,0,[ICt]))),jCt=ffn(EG(sCt,Pun(Gk(FCt,1),YZn,61,0,[ICt]))),gCt=ffn(EG(sCt,Pun(Gk(FCt,1),YZn,61,0,[oCt]))),TCt=ffn(EG(SCt,Pun(Gk(FCt,1),YZn,61,0,[ICt]))),fCt=ffn(EG(oCt,Pun(Gk(FCt,1),YZn,61,0,[SCt]))),mCt=ffn(EG(sCt,Pun(Gk(FCt,1),YZn,61,0,[oCt,ICt]))),lCt=ffn(EG(oCt,Pun(Gk(FCt,1),YZn,61,0,[SCt,ICt]))),kCt=ffn(EG(sCt,Pun(Gk(FCt,1),YZn,61,0,[SCt,ICt]))),pCt=ffn(EG(sCt,Pun(Gk(FCt,1),YZn,61,0,[oCt,SCt]))),vCt=ffn(EG(sCt,Pun(Gk(FCt,1),YZn,61,0,[oCt,SCt,ICt])))}function jUn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if(0!=t.b){for(l=new YT,a=null,b=null,i=IJ(e.Math.floor(e.Math.log(t.b)*e.Math.LOG10E)+1),u=0,v=spn(t,0);v.b!=v.d.c;)for(g=BB(b3(v),86),GC(b)!==GC(mMn(g,(qqn(),rkt)))&&(b=SD(mMn(g,rkt)),u=0),a=null!=b?b+d0(u++,i):d0(u++,i),hon(g,rkt,a),d=new wg(spn(new bg(g).a.d,0));EE(d.a);)r5(l,w=BB(b3(d.a),188).c,l.c.b,l.c),hon(w,rkt,a);for(f=new xp,c=0;c<a.length-i;c++)for(p=spn(t,0);p.b!=p.d.c;)mZ(f,o=fx(SD(mMn(g=BB(b3(p),86),(qqn(),rkt))),0,c+1),iln(null!=(null==o?qC(AY(f.f,null)):hS(f.g,o))?BB(null==o?qC(AY(f.f,null)):hS(f.g,o),19).a+1:1));for(h=new usn(new Pb(f).a);h.b;)s=ten(h),r=iln(null!=RX(n.a,s.cd())?BB(RX(n.a,s.cd()),19).a:0),mZ(n.a,SD(s.cd()),iln(BB(s.dd(),19).a+r.a)),(!(r=BB(RX(n.b,s.cd()),19))||r.a<BB(s.dd(),19).a)&&mZ(n.b,SD(s.cd()),BB(s.dd(),19));jUn(n,l)}}function EUn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(OTn(i,"Interactive node layering",1),r=new Np,w=new Wb(t.a);w.a<w.c.c.length;){for(s=(h=(l=BB(n0(w),10)).n.a)+l.o.a,s=e.Math.max(h+1,s),v=new M2(r,0),c=null;v.b<v.d.gc();){if(Px(v.b<v.d.gc()),(g=BB(v.d.Xb(v.c=v.b++),569)).c>=s){Px(v.b>0),v.a.Xb(v.c=--v.b);break}g.a>h&&(c?(gun(c.b,g.b),c.a=e.Math.max(c.a,g.a),fW(v)):(WB(g.b,l),g.c=e.Math.min(g.c,h),g.a=e.Math.max(g.a,s),c=g))}c||((c=new im).c=h,c.a=s,yR(v,c),WB(c.b,l))}for(o=t.b,f=0,p=new Wb(r);p.a<p.c.c.length;)for(g=BB(n0(p),569),(a=new HX(t)).p=f++,o.c[o.c.length]=a,d=new Wb(g.b);d.a<d.c.c.length;)PZ(l=BB(n0(d),10),a),l.p=0;for(b=new Wb(t.a);b.a<b.c.c.length;)0==(l=BB(n0(b),10)).p&&IDn(n,l,t);for(u=new M2(o,0);u.b<u.d.gc();)0==(Px(u.b<u.d.gc()),BB(u.d.Xb(u.c=u.b++),29)).a.c.length&&fW(u);t.a.c=x8(Ant,HWn,1,0,5,1),HSn(i)}function TUn(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(0!=t.e.c.length&&0!=e.e.c.length){if((i=BB(xq(t.e,0),17).c.i)==(a=BB(xq(e.e,0),17).c.i))return E$(BB(mMn(BB(xq(t.e,0),17),(hWn(),wlt)),19).a,BB(mMn(BB(xq(e.e,0),17),wlt),19).a);for(f=0,l=(h=n.a).length;f<l;++f){if((s=h[f])==i)return 1;if(s==a)return-1}}return 0!=t.g.c.length&&0!=e.g.c.length?(c=BB(mMn(t,(hWn(),llt)),10),o=BB(mMn(e,llt),10),r=0,u=0,Lx(BB(xq(t.g,0),17),wlt)&&(r=BB(mMn(BB(xq(t.g,0),17),wlt),19).a),Lx(BB(xq(e.g,0),17),wlt)&&(u=BB(mMn(BB(xq(t.g,0),17),wlt),19).a),c&&c==o?qy(TD(mMn(BB(xq(t.g,0),17),Ilt)))&&!qy(TD(mMn(BB(xq(e.g,0),17),Ilt)))?1:!qy(TD(mMn(BB(xq(t.g,0),17),Ilt)))&&qy(TD(mMn(BB(xq(e.g,0),17),Ilt)))||r<u?-1:r>u?1:0:(n.b&&(n.b._b(c)&&(r=BB(n.b.xc(c),19).a),n.b._b(o)&&(u=BB(n.b.xc(o),19).a)),r<u?-1:r>u?1:0)):0!=t.e.c.length&&0!=e.g.c.length?1:-1}function MUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(OTn(t,O1n,1),w=new Np,y=new Np,s=new Wb(n.b);s.a<s.c.c.length;)for(g=-1,l=0,b=(f=n2((o=BB(n0(s),29)).a)).length;l<b;++l)if(++g,(h=f[l]).k==(uSn(),Iut)&&vA(BB(mMn(h,(HXn(),ept)),98))){for(L_(BB(mMn(h,(HXn(),ept)),98))||HNn(h),hon(h,(hWn(),rlt),h),w.c=x8(Ant,HWn,1,0,5,1),y.c=x8(Ant,HWn,1,0,5,1),e=new Np,qrn(v=new YT,DSn(h,(kUn(),sCt))),AXn(n,v,w,y,e),u=g,k=h,c=new Wb(w);c.a<c.c.c.length;)Qyn(i=BB(n0(c),10),u,o),++g,hon(i,rlt,h),a=BB(xq(i.j,0),11),d=BB(mMn(a,dlt),11),qy(TD(mMn(d,jdt)))||BB(mMn(i,clt),15).Fc(k);for(yQ(v),p=DSn(h,SCt).Kc();p.Ob();)r5(v,BB(p.Pb(),11),v.a,v.a.a);for(AXn(n,v,y,null,e),m=h,r=new Wb(y);r.a<r.c.c.length;)Qyn(i=BB(n0(r),10),++g,o),hon(i,rlt,h),a=BB(xq(i.j,0),11),d=BB(mMn(a,dlt),11),qy(TD(mMn(d,jdt)))||BB(mMn(m,clt),15).Fc(i);0==e.c.length||hon(h,xft,e)}HSn(t)}function SUn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P;for(h=BB(mMn(n,(Mrn(),sat)),33),d=DWn,g=DWn,b=KVn,w=KVn,v=new Wb(n.e);v.a<v.c.c.length;)E=(p=BB(n0(v),144)).d,T=p.e,d=e.Math.min(d,E.a-T.a/2),g=e.Math.min(g,E.b-T.b/2),b=e.Math.max(b,E.a+T.a/2),w=e.Math.max(w,E.b+T.b/2);for(k=new xI((j=BB(ZAn(h,(fRn(),Vct)),116)).b-d,j.d-g),o=new Wb(n.e);o.a<o.c.c.length;)cL(y=mMn(u=BB(n0(o),144),sat),239)&&SA(f=BB(y,33),(m=UR(u.d,k)).a-f.g/2,m.b-f.f/2);for(r=new Wb(n.c);r.a<r.c.c.length;)i=BB(n0(r),282),s=cDn(BB(mMn(i,sat),79),!0,!0),Ukn(S=XR(B$(i.d.d),i.c.d),i.c.e.a,i.c.e.b),IA(s,(M=UR(S,i.c.d)).a,M.b),Ukn(P=XR(B$(i.c.d),i.d.d),i.d.e.a,i.d.e.b),PA(s,(t=UR(P,i.d.d)).a,t.b);for(a=new Wb(n.d);a.a<a.c.c.length;)c=BB(n0(a),447),SA(BB(mMn(c,sat),137),(l=UR(c.d,k)).a,l.b);_Un(h,b-d+(j.b+j.c),w-g+(j.d+j.a),!1,!0)}function PUn(n){var t,e,i,r,c,a,u,o,s,h,f;for(e=null,u=null,(r=BB(mMn(n.b,(HXn(),igt)),376))==(A6(),Jvt)&&(e=new Np,u=new Np),a=new Wb(n.d);a.a<a.c.c.length;)if((c=BB(n0(a),101)).i)switch(c.e.g){case 0:t=BB(u4(new QT(c.b)),61),r==Jvt&&t==(kUn(),sCt)?e.c[e.c.length]=c:r==Jvt&&t==(kUn(),SCt)?u.c[u.c.length]=c:Nmn(c,t);break;case 1:o=c.a.d.j,s=c.c.d.j,o==(kUn(),sCt)?bU(c,sCt,(Oun(),mst),c.a):s==sCt?bU(c,sCt,(Oun(),yst),c.c):o==SCt?bU(c,SCt,(Oun(),yst),c.a):s==SCt&&bU(c,SCt,(Oun(),mst),c.c);break;case 2:case 3:SN(i=c.b,(kUn(),sCt))?SN(i,SCt)?SN(i,ICt)?SN(i,oCt)||bU(c,sCt,(Oun(),yst),c.c):bU(c,sCt,(Oun(),mst),c.a):bU(c,sCt,(Oun(),vst),null):bU(c,SCt,(Oun(),vst),null);break;case 4:h=c.a.d.j,f=c.a.d.j,h==(kUn(),sCt)||f==sCt?bU(c,SCt,(Oun(),vst),null):bU(c,sCt,(Oun(),vst),null)}e&&(0==e.c.length||QFn(e,(kUn(),sCt)),0==u.c.length||QFn(u,(kUn(),SCt)))}function IUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;for(i=BB(mMn(n,(hWn(),dlt)),33),b=BB(mMn(n,(HXn(),Bdt)),19).a,c=BB(mMn(n,jgt),19).a,Ypn(i,Bdt,iln(b)),Ypn(i,jgt,iln(c)),Pen(i,n.n.a+t.a),Ien(i,n.n.b+t.b),(0!=BB(ZAn(i,Fgt),174).gc()||n.e||GC(mMn(vW(n),Kgt))===GC((Nvn(),mvt))&&pA((bvn(),(n.q?n.q:(SQ(),SQ(),het))._b(Rgt)?BB(mMn(n,Rgt),197):BB(mMn(vW(n),_gt),197))))&&(Sen(i,n.o.a),Men(i,n.o.b)),f=new Wb(n.j);f.a<f.c.c.length;)cL(w=mMn(s=BB(n0(f),11),dlt),186)&&(SA(r=BB(w,118),s.n.a,s.n.b),Ypn(r,upt,s.j));for(l=0!=BB(mMn(n,$gt),174).gc(),o=new Wb(n.b);o.a<o.c.c.length;)a=BB(n0(o),70),(l||0!=BB(mMn(a,$gt),174).gc())&&(MA(e=BB(mMn(a,dlt),137),a.o.a,a.o.b),SA(e,a.n.a,a.n.b));if(!Hz(BB(mMn(n,cpt),21)))for(h=new Wb(n.j);h.a<h.c.c.length;)for(u=new Wb((s=BB(n0(h),11)).f);u.a<u.c.c.length;)a=BB(n0(u),70),Sen(e=BB(mMn(a,dlt),137),a.o.a),Men(e,a.o.b),SA(e,a.n.a,a.n.b)}function CUn(n){var t,e,i,r,c;switch(OY(n,i8n),(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b).i+(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c).i){case 0:throw Hp(new Ky("The edge must have at least one source or target."));case 1:return 0==(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b).i?JJ(PTn(BB(Wtn((!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c),0),82))):JJ(PTn(BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82)))}if(1==(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b).i&&1==(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c).i){if(r=PTn(BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82)),c=PTn(BB(Wtn((!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c),0),82)),JJ(r)==JJ(c))return JJ(r);if(r==JJ(c))return r;if(c==JJ(r))return c}for(t=PTn(BB(U5(i=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[(!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),(!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c)])))),82));dAn(i);)if((e=PTn(BB(U5(i),82)))!=t&&!Itn(e,t))if(JJ(e)==JJ(t))t=JJ(e);else if(!(t=B$n(t,e)))return null;return t}function OUn(n,t,i){var r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j;for(OTn(i,"Polyline edge routing",1),v=Gy(MD(mMn(t,(HXn(),tgt)))),d=Gy(MD(mMn(t,Apt))),c=Gy(MD(mMn(t,kpt))),r=e.Math.min(1,c/d),k=0,s=0,0!=t.b.c.length&&(k=.4*r*(j=hLn(BB(xq(t.b,0),29)))),o=new M2(t.b,0);o.b<o.d.gc();){for(Px(o.b<o.d.gc()),(a=VC(u=BB(o.d.Xb(o.c=o.b++),29),jyt))&&k>0&&(k-=d),Tqn(u,k),l=0,w=new Wb(u.a);w.a<w.c.c.length;){for(f=0,p=new oz(ZL(lbn(b=BB(n0(w),10)).a.Kc(),new h));dAn(p);)m=g1((g=BB(U5(p),17)).c).b,y=g1(g.d).b,u!=g.d.i.c||b5(g)||(VCn(g,k,.4*r*e.Math.abs(m-y)),g.c.j==(kUn(),ICt)&&(m=0,y=0)),f=e.Math.max(f,e.Math.abs(y-m));switch(b.k.g){case 0:case 4:case 1:case 3:case 5:Gqn(n,b,k,v)}l=e.Math.max(l,f)}o.b<o.d.gc()&&(j=hLn((Px(o.b<o.d.gc()),BB(o.d.Xb(o.c=o.b++),29))),l=e.Math.max(l,j),Px(o.b>0),o.a.Xb(o.c=--o.b)),s=.4*r*l,!a&&o.b<o.d.gc()&&(s+=d),k+=u.c.a+s}n.a.a.$b(),t.f.a=k,HSn(i)}function AUn(n){var t,e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v;for(s=new xp,u=new pJ,i=new Wb(n.a.a.b);i.a<i.c.c.length;)if(o=f2(t=BB(n0(i),57)))jIn(s.f,o,t);else if(v=f3(t))for(r=new Wb(v.k);r.a<r.c.c.length;)JCn(u,BB(n0(r),17),t);for(e=new Wb(n.a.a.b);e.a<e.c.c.length;)if(o=f2(t=BB(n0(e),57)))for(a=new oz(ZL(lbn(o).a.Kc(),new h));dAn(a);)if(!b5(c=BB(U5(a),17))&&(w=c.c,p=c.d,!(kUn(),yCt).Hc(c.c.j)||!yCt.Hc(c.d.j))){if(d=BB(RX(s,c.d.i),57),UNn(aM(cM(uM(rM(new Hv,0),100),n.c[t.a.d]),n.c[d.a.d])),w.j==ICt&&$z((gcn(),w)))for(l=BB(h6(u,c),21).Kc();l.Ob();)if((f=BB(l.Pb(),57)).d.c<t.d.c){if((b=n.c[f.a.d])==(g=n.c[t.a.d]))continue;UNn(aM(cM(uM(rM(new Hv,1),100),b),g))}if(p.j==oCt&&Az((gcn(),p)))for(l=BB(h6(u,c),21).Kc();l.Ob();)if((f=BB(l.Pb(),57)).d.c>t.d.c){if((b=n.c[t.a.d])==(g=n.c[f.a.d]))continue;UNn(aM(cM(uM(rM(new Hv,1),100),b),g))}}}function $Un(n){var t,e,i,r,c,a,u,o;if(RHn(),null==n)return null;if((r=GO(n,YTn(37)))<0)return n;for(o=new lN(n.substr(0,r)),t=x8(NNt,v6n,25,4,15,1),u=0,i=0,a=n.length;r<a;r++)if(b1(r,n.length),37==n.charCodeAt(r)&&n.length>r+2&&ton((b1(r+1,n.length),n.charCodeAt(r+1)),CAt,OAt)&&ton((b1(r+2,n.length),n.charCodeAt(r+2)),CAt,OAt))if(e=IH((b1(r+1,n.length),n.charCodeAt(r+1)),(b1(r+2,n.length),n.charCodeAt(r+2))),r+=2,i>0?128==(192&e)?t[u++]=e<<24>>24:i=0:e>=128&&(192==(224&e)?(t[u++]=e<<24>>24,i=2):224==(240&e)?(t[u++]=e<<24>>24,i=3):240==(248&e)&&(t[u++]=e<<24>>24,i=4)),i>0){if(u==i){switch(u){case 2:xX(o,((31&t[0])<<6|63&t[1])&QVn);break;case 3:xX(o,((15&t[0])<<12|(63&t[1])<<6|63&t[2])&QVn)}u=0,i=0}}else{for(c=0;c<u;++c)xX(o,t[c]&QVn);u=0,o.a+=String.fromCharCode(e)}else{for(c=0;c<u;++c)xX(o,t[c]&QVn);u=0,xX(o,(b1(r,n.length),n.charCodeAt(r)))}return o.a}function LUn(n,t,e,i,r){var c,a,u;if(ynn(n,t),a=t[0],c=fV(e.c,0),u=-1,Yon(e))if(i>0){if(a+i>n.length)return!1;u=UCn(n.substr(0,a+i),t)}else u=UCn(n,t);switch(c){case 71:return u=zTn(n,a,Pun(Gk(Qtt,1),sVn,2,6,[fQn,lQn]),t),r.e=u,!0;case 77:return gDn(n,t,r,u,a);case 76:return pDn(n,t,r,u,a);case 69:return rIn(n,t,a,r);case 99:return cIn(n,t,a,r);case 97:return u=zTn(n,a,Pun(Gk(Qtt,1),sVn,2,6,["AM","PM"]),t),r.b=u,!0;case 121:return vDn(n,t,a,u,e,r);case 100:return!(u<=0||(r.c=u,0));case 83:return!(u<0)&&jwn(u,a,t[0],r);case 104:12==u&&(u=0);case 75:case 72:return!(u<0||(r.f=u,r.g=!1,0));case 107:return!(u<0||(r.f=u,r.g=!0,0));case 109:return!(u<0||(r.j=u,0));case 115:return!(u<0||(r.n=u,0));case 90:if(a<n.length&&(b1(a,n.length),90==n.charCodeAt(a)))return++t[0],r.o=0,!0;case 122:case 118:return ITn(n,a,t,r);default:return!1}}function NUn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;if(b=BB(BB(h6(n.r,t),21),84),t!=(kUn(),oCt)&&t!=ICt){for(a=t==sCt?(Dan(),Nrt):(Dan(),Rrt),k=t==sCt?(G7(),crt):(G7(),irt),c=(r=(i=BB(oV(n.b,t),124)).i).c+Lon(Pun(Gk(xNt,1),qQn,25,15,[i.n.b,n.C.b,n.k])),v=r.c+r.b-Lon(Pun(Gk(xNt,1),qQn,25,15,[i.n.c,n.C.c,n.k])),u=Zk(HK(a),n.t),m=t==sCt?_Qn:RQn,l=b.Kc();l.Ob();)!(h=BB(l.Pb(),111)).c||h.c.d.c.length<=0||(p=h.b.rf(),g=h.e,(d=(w=h.c).i).b=(s=w.n,w.e.a+s.b+s.c),d.a=(o=w.n,w.e.b+o.d+o.a),OY(k,uJn),w.f=k,l9(w,(J9(),Jit)),d.c=g.a-(d.b-p.a)/2,j=e.Math.min(c,g.a),E=e.Math.max(v,g.a+p.a),d.c<j?d.c=j:d.c+d.b>E&&(d.c=E-d.b),WB(u.d,new xG(d,kln(u,d))),m=t==sCt?e.Math.max(m,g.b+h.b.rf().b):e.Math.min(m,g.b));for(m+=t==sCt?n.t:-n.t,(y=Pwn((u.e=m,u)))>0&&(BB(oV(n.b,t),124).a.b=y),f=b.Kc();f.Ob();)!(h=BB(f.Pb(),111)).c||h.c.d.c.length<=0||((d=h.c.i).c-=h.e.a,d.d-=h.e.b)}else aUn(n,t)}function xUn(n){var t,e,i,r,c,a,u,o,s,f;for(t=new xp,a=new AL(n);a.e!=a.i.gc();){for(c=BB(kpn(a),33),e=new Rv,VW(Mct,c,e),f=new ut,i=BB(P4(new Rq(null,new zU(new oz(ZL(wLn(c).a.Kc(),new h)))),SG(f,m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[(qsn(),Uet)])))),83),Jen(e,BB(i.xc((hN(),!0)),14),new ot),r=BB(P4(AV(BB(i.xc(!1),15).Lc(),new st),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[Uet]))),15).Kc();r.Ob();)(s=IMn(BB(r.Pb(),79)))&&((u=BB(qC(AY(t.f,s)),21))||(u=Oxn(s),jIn(t.f,s,u)),Frn(e,u));for(i=BB(P4(new Rq(null,new zU(new oz(ZL(dLn(c).a.Kc(),new h)))),SG(f,m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[Uet])))),83),Jen(e,BB(i.xc(!0),14),new ht),o=BB(P4(AV(BB(i.xc(!1),15).Lc(),new ft),m9(new H,new B,new rn,Pun(Gk(nit,1),$Vn,132,0,[Uet]))),15).Kc();o.Ob();)(s=CMn(BB(o.Pb(),79)))&&((u=BB(qC(AY(t.f,s)),21))||(u=Oxn(s),jIn(t.f,s,u)),Frn(e,u))}}function DUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d;if(uHn(),(o=Vhn(n,0)<0)&&(n=j7(n)),0==Vhn(n,0))switch(t){case 0:return"0";case 1:return WQn;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(b=new Ik).a+=t<0?"0E+":"0E",b.a+=t==KVn?"2147483648":""+-t,b.a}f=x8(ONt,WVn,25,1+(h=18),15,1),e=h,d=n;do{s=d,d=Ojn(d,10),f[--e]=dG(rbn(48,ibn(s,cbn(d,10))))&QVn}while(0!=Vhn(d,0));if(r=ibn(ibn(ibn(h,e),t),1),0==t)return o&&(f[--e]=45),Bdn(f,e,h-e);if(t>0&&Vhn(r,-6)>=0){if(Vhn(r,0)>=0){for(c=e+dG(r),u=h-1;u>=c;u--)f[u+1]=f[u];return f[++c]=46,o&&(f[--e]=45),Bdn(f,e,h-e+1)}for(a=2;sS(a,rbn(j7(r),1));a++)f[--e]=48;return f[--e]=46,f[--e]=48,o&&(f[--e]=45),Bdn(f,e,h-e)}return w=e+1,i=h,l=new Ck,o&&(l.a+="-"),i-w>=1?(xX(l,f[e]),l.a+=".",l.a+=Bdn(f,e+1,h-e-1)):l.a+=Bdn(f,e,h-e),l.a+="E",Vhn(r,0)>0&&(l.a+="+"),l.a+=""+vz(r),l.a}function RUn(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(n.e.a.$b(),n.f.a.$b(),n.c.c=x8(Ant,HWn,1,0,5,1),n.i.c=x8(Ant,HWn,1,0,5,1),n.g.a.$b(),t)for(a=new Wb(t.a);a.a<a.c.c.length;)for(h=DSn(c=BB(n0(a),10),(kUn(),oCt)).Kc();h.Ob();)for(s=BB(h.Pb(),11),TU(n.e,s),r=new Wb(s.g);r.a<r.c.c.length;)b5(i=BB(n0(r),17))||(WB(n.c,i),ppn(n,i),((u=i.c.i.k)==(uSn(),Iut)||u==Cut||u==Mut||u==Tut)&&WB(n.j,i),(f=(l=i.d).i.c)==e?TU(n.f,l):f==t?TU(n.e,l):y7(n.c,i));if(e)for(a=new Wb(e.a);a.a<a.c.c.length;){for(o=new Wb((c=BB(n0(a),10)).j);o.a<o.c.c.length;)for(r=new Wb(BB(n0(o),11).g);r.a<r.c.c.length;)b5(i=BB(n0(r),17))&&TU(n.g,i);for(h=DSn(c,(kUn(),ICt)).Kc();h.Ob();)for(s=BB(h.Pb(),11),TU(n.f,s),r=new Wb(s.g);r.a<r.c.c.length;)b5(i=BB(n0(r),17))||(WB(n.c,i),ppn(n,i),((u=i.c.i.k)==(uSn(),Iut)||u==Cut||u==Mut||u==Tut)&&WB(n.j,i),(f=(l=i.d).i.c)==e?TU(n.f,l):f==t?TU(n.e,l):y7(n.c,i))}}function _Un(n,t,i,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;if(p=new xI(n.g,n.f),(g=XPn(n)).a=e.Math.max(g.a,t),g.b=e.Math.max(g.b,i),E=g.a/p.a,f=g.b/p.b,k=g.a-p.a,s=g.b-p.b,r)for(u=JJ(n)?BB(ZAn(JJ(n),(sWn(),bSt)),103):BB(ZAn(n,(sWn(),bSt)),103),o=GC(ZAn(n,(sWn(),uPt)))===GC((QEn(),XIt)),m=new AL((!n.c&&(n.c=new eU(XOt,n,9,9)),n.c));m.e!=m.i.gc();)switch(v=BB(kpn(m),118),(y=BB(ZAn(v,wPt),61))==(kUn(),PCt)&&(y=OFn(v,u),Ypn(v,wPt,y)),y.g){case 1:o||Pen(v,v.i*E);break;case 2:Pen(v,v.i+k),o||Ien(v,v.j*f);break;case 3:o||Pen(v,v.i*E),Ien(v,v.j+s);break;case 4:o||Ien(v,v.j*f)}if(MA(n,g.a,g.b),c)for(b=new AL((!n.n&&(n.n=new eU(zOt,n,1,7)),n.n));b.e!=b.i.gc();)w=(l=BB(kpn(b),137)).i+l.g/2,d=l.j+l.f/2,(j=w/p.a)+(h=d/p.b)>=1&&(j-h>0&&d>=0?(Pen(l,l.i+k),Ien(l,l.j+s*h)):j-h<0&&w>=0&&(Pen(l,l.i+k*j),Ien(l,l.j+s)));return Ypn(n,(sWn(),_St),(mdn(),new Y_(a=BB(Vj(YCt),9),BB(SR(a,a.length),9),0))),new xI(E,f)}function KUn(n){var t,i,r,c,a,u,o,s,h,f,l;if(f=JJ(PTn(BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82)))==JJ(PTn(BB(Wtn((!n.c&&(n.c=new h_(_Ot,n,5,8)),n.c),0),82))),u=new Gj,(t=BB(ZAn(n,(Xsn(),hIt)),74))&&t.b>=2){if(0==(!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i)tE(),i=new co,f9((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a),i);else if((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i>1)for(l=new cx((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a));l.e!=l.i.gc();)Qjn(l);VFn(t,BB(Wtn((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a),0),202))}if(f)for(r=new AL((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a));r.e!=r.i.gc();)for(s=new AL((!(i=BB(kpn(r),202)).a&&(i.a=new $L(xOt,i,5)),i.a));s.e!=s.i.gc();)o=BB(kpn(s),469),u.a=e.Math.max(u.a,o.a),u.b=e.Math.max(u.b,o.b);for(a=new AL((!n.n&&(n.n=new eU(zOt,n,1,7)),n.n));a.e!=a.i.gc();)c=BB(kpn(a),137),(h=BB(ZAn(c,gIt),8))&&SA(c,h.a,h.b),f&&(u.a=e.Math.max(u.a,c.i+c.g),u.b=e.Math.max(u.b,c.j+c.f));return u}function FUn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;for(v=t.c.length,c=new q_n(n.a,i,null,null),E=x8(xNt,qQn,25,v,15,1),w=x8(xNt,qQn,25,v,15,1),b=x8(xNt,qQn,25,v,15,1),d=0,o=0;o<v;o++)w[o]=DWn,b[o]=KVn;for(s=0;s<v;s++)for(l1(s,t.c.length),r=BB(t.c[s],180),E[s]=v$n(r),E[d]>E[s]&&(d=s),f=new Wb(n.a.b);f.a<f.c.c.length;)for(p=new Wb(BB(n0(f),29).a);p.a<p.c.c.length;)g=BB(n0(p),10),k=Gy(r.p[g.p])+Gy(r.d[g.p]),w[s]=e.Math.min(w[s],k),b[s]=e.Math.max(b[s],k+g.o.b);for(j=x8(xNt,qQn,25,v,15,1),h=0;h<v;h++)(l1(h,t.c.length),BB(t.c[h],180)).o==(oZ(),ryt)?j[h]=w[d]-w[h]:j[h]=b[d]-b[h];for(a=x8(xNt,qQn,25,v,15,1),l=new Wb(n.a.b);l.a<l.c.c.length;)for(y=new Wb(BB(n0(l),29).a);y.a<y.c.c.length;){for(m=BB(n0(y),10),u=0;u<v;u++)a[u]=Gy((l1(u,t.c.length),BB(t.c[u],180)).p[m.p])+Gy((l1(u,t.c.length),BB(t.c[u],180)).d[m.p])+j[u];a.sort(ien(T.prototype.te,T,[])),c.p[m.p]=(a[1]+a[2])/2,c.d[m.p]=0}return c}function BUn(n,t,e){var i,r,c,a,u;switch(i=t.i,c=n.i.o,r=n.i.d,u=n.n,a=Aon(Pun(Gk(PMt,1),sVn,8,0,[u,n.a])),n.j.g){case 1:WD(t,(G7(),irt)),i.d=-r.d-e-i.a,BB(BB(xq(t.d,0),181).We((hWn(),ult)),285)==(Xyn(),jIt)?(l9(t,(J9(),Jit)),i.c=a.a-Gy(MD(mMn(n,blt)))-e-i.b):(l9(t,(J9(),Yit)),i.c=a.a+Gy(MD(mMn(n,blt)))+e);break;case 2:l9(t,(J9(),Yit)),i.c=c.a+r.c+e,BB(BB(xq(t.d,0),181).We((hWn(),ult)),285)==(Xyn(),jIt)?(WD(t,(G7(),irt)),i.d=a.b-Gy(MD(mMn(n,blt)))-e-i.a):(WD(t,(G7(),crt)),i.d=a.b+Gy(MD(mMn(n,blt)))+e);break;case 3:WD(t,(G7(),crt)),i.d=c.b+r.a+e,BB(BB(xq(t.d,0),181).We((hWn(),ult)),285)==(Xyn(),jIt)?(l9(t,(J9(),Jit)),i.c=a.a-Gy(MD(mMn(n,blt)))-e-i.b):(l9(t,(J9(),Yit)),i.c=a.a+Gy(MD(mMn(n,blt)))+e);break;case 4:l9(t,(J9(),Jit)),i.c=-r.b-e-i.b,BB(BB(xq(t.d,0),181).We((hWn(),ult)),285)==(Xyn(),jIt)?(WD(t,(G7(),irt)),i.d=a.b-Gy(MD(mMn(n,blt)))-e-i.a):(WD(t,(G7(),crt)),i.d=a.b+Gy(MD(mMn(n,blt)))+e)}}function HUn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O;for(w=0,S=0,s=new Wb(n);s.a<s.c.c.length;)ozn(o=BB(n0(s),33)),w=e.Math.max(w,o.g),S+=o.g*o.f;for(M=Zyn(n,S/n.c.length),S+=n.c.length*M,w=e.Math.max(w,e.Math.sqrt(S*u))+i.b,C=i.b,O=i.d,b=0,f=i.b+i.c,DH(T=new YT,iln(0)),j=new YT,h=new M2(n,0);h.b<h.d.gc();)Px(h.b<h.d.gc()),I=(o=BB(h.d.Xb(h.c=h.b++),33)).g,l=o.f,C+I>w&&(a&&(fO(j,b),fO(T,iln(h.b-1))),C=i.b,O+=b+t,b=0,f=e.Math.max(f,i.b+i.c+I)),Pen(o,C),Ien(o,O),f=e.Math.max(f,C+I+i.c),b=e.Math.max(b,l),C+=I+t;if(f=e.Math.max(f,r),(P=O+b+i.a)<c&&(b+=c-P,P=c),a)for(C=i.b,h=new M2(n,0),fO(T,iln(n.c.length)),p=BB(b3(E=spn(T,0)),19).a,fO(j,b),k=spn(j,0),y=0;h.b<h.d.gc();)h.b==p&&(C=i.b,y=Gy(MD(b3(k))),p=BB(b3(E),19).a),Px(h.b<h.d.gc()),v=(o=BB(h.d.Xb(h.c=h.b++),33)).f,Men(o,y),d=y,h.b==p&&(g=f-C-i.c,m=o.g,Sen(o,g),lIn(o,new xI(g,d),new xI(m,v))),C+=o.g+t;return new xI(f,P)}function qUn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;for(OTn(t,"Compound graph postprocessor",1),i=qy(TD(mMn(n,(HXn(),Dpt)))),o=BB(mMn(n,(hWn(),Hft)),224),f=new Rv,v=o.ec().Kc();v.Ob();){for(p=BB(v.Pb(),17),u=new tK(o.cc(p)),SQ(),m$(u,new Kw(n)),j=ccn((l1(0,u.c.length),BB(u.c[0],243))),T=acn(BB(xq(u,u.c.length-1),243)),y=j.i,m=wan(T.i,y)?y.e:vW(y),l=Apn(p,u),yQ(p.a),b=null,a=new Wb(u);a.a<a.c.c.length;)c=BB(n0(a),243),OPn(g=new Gj,c.a,m),w=c.b,Wsn(r=new km,0,w.a),Ztn(r,g),k=new wA(g1(w.c)),E=new wA(g1(w.d)),UR(k,g),UR(E,g),b&&(0==r.b?d=E:(Px(0!=r.b),d=BB(r.a.a.c,8)),M=e.Math.abs(b.a-d.a)>lZn,S=e.Math.abs(b.b-d.b)>lZn,(!i&&M&&S||i&&(M||S))&&DH(p.a,k)),Frn(p.a,r),0==r.b?b=k:(Px(0!=r.b),b=BB(r.c.b.c,8)),Yan(w,l,g),acn(c)==T&&(vW(T.i)!=c.a&&OPn(g=new Gj,vW(T.i),m),hon(p,Rlt,g)),MSn(w,p,m),f.a.zc(w,f);SZ(p,j),MZ(p,T)}for(h=f.a.ec().Kc();h.Ob();)SZ(s=BB(h.Pb(),17),null),MZ(s,null);HSn(t)}function GUn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(1==n.gc())return BB(n.Xb(0),231);if(n.gc()<=0)return new y6;for(c=n.Kc();c.Ob();){for(i=BB(c.Pb(),231),d=0,f=DWn,l=DWn,s=KVn,h=KVn,w=new Wb(i.e);w.a<w.c.c.length;)b=BB(n0(w),144),d+=BB(mMn(b,(fRn(),Zct)),19).a,f=e.Math.min(f,b.d.a-b.e.a/2),l=e.Math.min(l,b.d.b-b.e.b/2),s=e.Math.max(s,b.d.a+b.e.a/2),h=e.Math.max(h,b.d.b+b.e.b/2);hon(i,(fRn(),Zct),iln(d)),hon(i,(Mrn(),oat),new xI(f,l)),hon(i,uat,new xI(s,h))}for(SQ(),n.ad(new wt),qan(g=new y6,BB(n.Xb(0),94)),o=0,m=0,a=n.Kc();a.Ob();)i=BB(a.Pb(),231),p=XR(B$(BB(mMn(i,(Mrn(),uat)),8)),BB(mMn(i,oat),8)),o=e.Math.max(o,p.a),m+=p.a*p.b;for(o=e.Math.max(o,e.Math.sqrt(m)*Gy(MD(mMn(g,(fRn(),Fct))))),y=0,k=0,u=0,t=v=Gy(MD(mMn(g,cat))),r=n.Kc();r.Ob();)i=BB(r.Pb(),231),y+(p=XR(B$(BB(mMn(i,(Mrn(),uat)),8)),BB(mMn(i,oat),8))).a>o&&(y=0,k+=u+v,u=0),V_n(g,i,y,k),t=e.Math.max(t,y+p.a),u=e.Math.max(u,p.b),y+=p.a+v;return g}function zUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;switch(h=new km,n.a.g){case 3:l=BB(mMn(t.e,(hWn(),Nlt)),15),b=BB(mMn(t.j,Nlt),15),w=BB(mMn(t.f,Nlt),15),e=BB(mMn(t.e,$lt),15),i=BB(mMn(t.j,$lt),15),r=BB(mMn(t.f,$lt),15),gun(a=new Np,l),b.Jc(new yc),gun(a,cL(b,152)?o6(BB(b,152)):cL(b,131)?BB(b,131).a:cL(b,54)?new fy(b):new IT(b)),gun(a,w),gun(c=new Np,e),gun(c,cL(i,152)?o6(BB(i,152)):cL(i,131)?BB(i,131).a:cL(i,54)?new fy(i):new IT(i)),gun(c,r),hon(t.f,Nlt,a),hon(t.f,$lt,c),hon(t.f,xlt,t.f),hon(t.e,Nlt,null),hon(t.e,$lt,null),hon(t.j,Nlt,null),hon(t.j,$lt,null);break;case 1:Frn(h,t.e.a),DH(h,t.i.n),Frn(h,ean(t.j.a)),DH(h,t.a.n),Frn(h,t.f.a);break;default:Frn(h,t.e.a),Frn(h,ean(t.j.a)),Frn(h,t.f.a)}yQ(t.f.a),Frn(t.f.a,h),SZ(t.f,t.e.c),u=BB(mMn(t.e,(HXn(),vgt)),74),s=BB(mMn(t.j,vgt),74),o=BB(mMn(t.f,vgt),74),(u||s||o)&&(PU(f=new km,o),PU(f,s),PU(f,u),hon(t.f,vgt,f)),SZ(t.j,null),MZ(t.j,null),SZ(t.e,null),MZ(t.e,null),PZ(t.a,null),PZ(t.i,null),t.g&&zUn(n,t.g)}function UUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;if(PFn(),null==n)return null;if((w=bln(c=V7(n)))%4!=0)return null;if(0==(d=w/4|0))return x8(NNt,v6n,25,0,15,1);for(f=null,t=0,e=0,i=0,r=0,a=0,u=0,o=0,s=0,b=0,l=0,h=0,f=x8(NNt,v6n,25,3*d,15,1);b<d-1;b++){if(!(VE(a=c[h++])&&VE(u=c[h++])&&VE(o=c[h++])&&VE(s=c[h++])))return null;t=WLt[a],e=WLt[u],i=WLt[o],r=WLt[s],f[l++]=(t<<2|e>>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24}return VE(a=c[h++])&&VE(u=c[h++])?(t=WLt[a],e=WLt[u],o=c[h++],s=c[h++],-1==WLt[o]||-1==WLt[s]?61==o&&61==s?0!=(15&e)?null:(aHn(f,0,g=x8(NNt,v6n,25,3*b+1,15,1),0,3*b),g[l]=(t<<2|e>>4)<<24>>24,g):61!=o&&61==s?0!=(3&(i=WLt[o]))?null:(aHn(f,0,g=x8(NNt,v6n,25,3*b+2,15,1),0,3*b),g[l++]=(t<<2|e>>4)<<24>>24,g[l]=((15&e)<<4|i>>2&15)<<24>>24,g):null:(i=WLt[o],r=WLt[s],f[l++]=(t<<2|e>>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24,f)):null}function XUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(OTn(t,O1n,1),l=BB(mMn(n,(HXn(),Zdt)),218),i=new Wb(n.b);i.a<i.c.c.length;)for(a=0,u=(c=n2(BB(n0(i),29).a)).length;a<u;++a)if((r=c[a]).k==(uSn(),Cut)){if(l==(Mbn(),JPt))for(s=new Wb(r.j);s.a<s.c.c.length;)0==(o=BB(n0(s),11)).e.c.length||Agn(o),0==o.g.c.length||$gn(o);else if(cL(mMn(r,(hWn(),dlt)),17))w=BB(mMn(r,dlt),17),d=BB(DSn(r,(kUn(),ICt)).Kc().Pb(),11),g=BB(DSn(r,oCt).Kc().Pb(),11),p=BB(mMn(d,dlt),11),SZ(w,v=BB(mMn(g,dlt),11)),MZ(w,p),(m=new wA(g.i.n)).a=Aon(Pun(Gk(PMt,1),sVn,8,0,[v.i.n,v.n,v.a])).a,DH(w.a,m),(m=new wA(d.i.n)).a=Aon(Pun(Gk(PMt,1),sVn,8,0,[p.i.n,p.n,p.a])).a,DH(w.a,m);else{if(r.j.c.length>=2){for(b=!0,e=BB(n0(h=new Wb(r.j)),11),f=null;h.a<h.c.c.length;)if(f=e,e=BB(n0(h),11),!Nfn(mMn(f,dlt),mMn(e,dlt))){b=!1;break}}else b=!1;for(s=new Wb(r.j);s.a<s.c.c.length;)0==(o=BB(n0(s),11)).e.c.length||uxn(o,b),0==o.g.c.length||oxn(o,b)}PZ(r,null)}HSn(t)}function WUn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;return y=n.c[(l1(0,t.c.length),BB(t.c[0],17)).p],T=n.c[(l1(1,t.c.length),BB(t.c[1],17)).p],!(y.a.e.e-y.a.a-(y.b.e.e-y.b.a)==0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)==0||!cL(v=y.b.e.f,10)||(p=BB(v,10),j=n.i[p.p],E=p.c?E7(p.c.a,p,0):-1,a=RQn,E>0&&(c=BB(xq(p.c.a,E-1),10),u=n.i[c.p],M=e.Math.ceil(_$(n.n,c,p)),a=j.a.e-p.d.d-(u.a.e+c.o.b+c.d.a)-M),h=RQn,E<p.c.a.c.length-1&&(s=BB(xq(p.c.a,E+1),10),f=n.i[s.p],M=e.Math.ceil(_$(n.n,s,p)),h=f.a.e-s.d.d-(j.a.e+p.o.b+p.d.a)-M),!(i&&(h$(),rin(A3n),e.Math.abs(a-h)<=A3n||a==h||isNaN(a)&&isNaN(h)))&&(r=aX(y.a),o=-aX(y.b),l=-aX(T.a),m=aX(T.b),g=y.a.e.e-y.a.a-(y.b.e.e-y.b.a)>0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)<0,d=y.a.e.e-y.a.a-(y.b.e.e-y.b.a)<0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)>0,w=y.a.e.e+y.b.a<T.b.e.e+T.a.a,b=y.a.e.e+y.b.a>T.b.e.e+T.a.a,k=0,!g&&!d&&(b?a+l>0?k=l:h-r>0&&(k=r):w&&(a+o>0?k=o:h-m>0&&(k=m))),j.a.e+=k,j.b&&(j.d.e+=k),1)))}function VUn(n,t,i){var r,c,a,u,o,s,h,f,l,b;if(r=new UV(t.qf().a,t.qf().b,t.rf().a,t.rf().b),c=new bA,n.c)for(u=new Wb(t.wf());u.a<u.c.c.length;)a=BB(n0(u),181),c.c=a.qf().a+t.qf().a,c.d=a.qf().b+t.qf().b,c.b=a.rf().a,c.a=a.rf().b,IPn(r,c);for(h=new Wb(t.Cf());h.a<h.c.c.length;){if(f=(s=BB(n0(h),838)).qf().a+t.qf().a,l=s.qf().b+t.qf().b,n.e&&(c.c=f,c.d=l,c.b=s.rf().a,c.a=s.rf().b,IPn(r,c)),n.d)for(u=new Wb(s.wf());u.a<u.c.c.length;)a=BB(n0(u),181),c.c=a.qf().a+f,c.d=a.qf().b+l,c.b=a.rf().a,c.a=a.rf().b,IPn(r,c);if(n.b){if(b=new xI(-i,-i),BB(t.We((sWn(),fPt)),174).Hc((lCn(),rCt)))for(u=new Wb(s.wf());u.a<u.c.c.length;)a=BB(n0(u),181),b.a+=a.rf().a+i,b.b+=a.rf().b+i;b.a=e.Math.max(b.a,0),b.b=e.Math.max(b.b,0),XKn(r,s.Bf(),s.zf(),t,s,b,i)}}n.b&&XKn(r,t.Bf(),t.zf(),t,null,null,i),(o=new AK(t.Af())).d=e.Math.max(0,t.qf().b-r.d),o.a=e.Math.max(0,r.d+r.a-(t.qf().b+t.rf().b)),o.b=e.Math.max(0,t.qf().a-r.c),o.c=e.Math.max(0,r.c+r.b-(t.qf().a+t.rf().a)),t.Ef(o)}function QUn(){var n=["\\u0000","\\u0001","\\u0002","\\u0003","\\u0004","\\u0005","\\u0006","\\u0007","\\b","\\t","\\n","\\u000B","\\f","\\r","\\u000E","\\u000F","\\u0010","\\u0011","\\u0012","\\u0013","\\u0014","\\u0015","\\u0016","\\u0017","\\u0018","\\u0019","\\u001A","\\u001B","\\u001C","\\u001D","\\u001E","\\u001F"];return n[34]='\\"',n[92]="\\\\",n[173]="\\u00ad",n[1536]="\\u0600",n[1537]="\\u0601",n[1538]="\\u0602",n[1539]="\\u0603",n[1757]="\\u06dd",n[1807]="\\u070f",n[6068]="\\u17b4",n[6069]="\\u17b5",n[8203]="\\u200b",n[8204]="\\u200c",n[8205]="\\u200d",n[8206]="\\u200e",n[8207]="\\u200f",n[8232]="\\u2028",n[8233]="\\u2029",n[8234]="\\u202a",n[8235]="\\u202b",n[8236]="\\u202c",n[8237]="\\u202d",n[8238]="\\u202e",n[8288]="\\u2060",n[8289]="\\u2061",n[8290]="\\u2062",n[8291]="\\u2063",n[8292]="\\u2064",n[8298]="\\u206a",n[8299]="\\u206b",n[8300]="\\u206c",n[8301]="\\u206d",n[8302]="\\u206e",n[8303]="\\u206f",n[65279]="\\ufeff",n[65529]="\\ufff9",n[65530]="\\ufffa",n[65531]="\\ufffb",n}function YUn(n,t,e){var i,r,c,a,u,o,s,h,f,l;for(o=new Np,f=t.length,a=Con(e),s=0;s<f;++s){switch(h=yN(t,YTn(61),s),c=(r=uun(i=fln(a,t.substr(s,h-s)))).Aj().Nh(),fV(t,++h)){case 39:u=lx(t,39,++h),WB(o,new IC(i,YV(t.substr(h,u-h),c,r))),s=u+1;break;case 34:u=lx(t,34,++h),WB(o,new IC(i,YV(t.substr(h,u-h),c,r))),s=u+1;break;case 91:WB(o,new IC(i,l=new Np));n:for(;;){switch(fV(t,++h)){case 39:u=lx(t,39,++h),WB(l,YV(t.substr(h,u-h),c,r)),h=u+1;break;case 34:u=lx(t,34,++h),WB(l,YV(t.substr(h,u-h),c,r)),h=u+1;break;case 110:if(++h,t.indexOf("ull",h)!=h)throw Hp(new dy(a6n));l.c[l.c.length]=null,h+=3}if(!(h<f))break;switch(b1(h,t.length),t.charCodeAt(h)){case 44:break;case 93:break n;default:throw Hp(new dy("Expecting , or ]"))}}s=h+1;break;case 110:if(++h,t.indexOf("ull",h)!=h)throw Hp(new dy(a6n));WB(o,new IC(i,null)),s=h+3}if(!(s<f))break;if(b1(s,t.length),44!=t.charCodeAt(s))throw Hp(new dy("Expecting ,"))}return iDn(n,o,e)}function JUn(n,t){var e,i,r,c,a,u,o,s,h,f,l;for(s=BB(BB(h6(n.r,t),21),84),a=JTn(n,t),e=n.u.Hc((lCn(),nCt)),o=s.Kc();o.Ob();)if((u=BB(o.Pb(),111)).c&&!(u.c.d.c.length<=0)){switch(l=u.b.rf(),(f=(h=u.c).i).b=(c=h.n,h.e.a+c.b+c.c),f.a=(r=h.n,h.e.b+r.d+r.a),t.g){case 1:u.a?(f.c=(l.a-f.b)/2,l9(h,(J9(),Qit))):a||e?(f.c=-f.b-n.s,l9(h,(J9(),Jit))):(f.c=l.a+n.s,l9(h,(J9(),Yit))),f.d=-f.a-n.t,WD(h,(G7(),irt));break;case 3:u.a?(f.c=(l.a-f.b)/2,l9(h,(J9(),Qit))):a||e?(f.c=-f.b-n.s,l9(h,(J9(),Jit))):(f.c=l.a+n.s,l9(h,(J9(),Yit))),f.d=l.b+n.t,WD(h,(G7(),crt));break;case 2:u.a?(i=n.v?f.a:BB(xq(h.d,0),181).rf().b,f.d=(l.b-i)/2,WD(h,(G7(),rrt))):a||e?(f.d=-f.a-n.t,WD(h,(G7(),irt))):(f.d=l.b+n.t,WD(h,(G7(),crt))),f.c=l.a+n.s,l9(h,(J9(),Yit));break;case 4:u.a?(i=n.v?f.a:BB(xq(h.d,0),181).rf().b,f.d=(l.b-i)/2,WD(h,(G7(),rrt))):a||e?(f.d=-f.a-n.t,WD(h,(G7(),irt))):(f.d=l.b+n.t,WD(h,(G7(),crt))),f.c=-f.b-n.s,l9(h,(J9(),Jit))}a=!1}}function ZUn(n,t){var e,i,r,c,a,u,o,s,h,f,l;if(wWn(),0==NT(iNt)){for(f=x8(CNt,sVn,117,cNt.length,0,1),a=0;a<f.length;a++)f[a]=new M0(4);for(i=new Pk,c=0;c<eNt.length;c++){if(h=new M0(4),c<84?(b1(u=2*c,vnt.length),l=vnt.charCodeAt(u),b1(u+1,vnt.length),Yxn(h,l,vnt.charCodeAt(u+1))):Yxn(h,aNt[u=2*(c-84)],aNt[u+1]),m_(o=eNt[c],"Specials")&&Yxn(h,65520,65533),m_(o,gnt)&&(Yxn(h,983040,1048573),Yxn(h,1048576,1114109)),mZ(iNt,o,h),mZ(rNt,o,$Fn(h)),0<(s=i.a.length)?i.a=i.a.substr(0,0):0>s&&(i.a+=rL(x8(ONt,WVn,25,-s,15,1))),i.a+="Is",GO(o,YTn(32))>=0)for(r=0;r<o.length;r++)b1(r,o.length),32!=o.charCodeAt(r)&&NX(i,(b1(r,o.length),o.charCodeAt(r)));else i.a+=""+o;Tdn(i.a,o,!0)}Tdn(pnt,"Cn",!1),Tdn(mnt,"Cn",!0),Yxn(e=new M0(4),0,unt),mZ(iNt,"ALL",e),mZ(rNt,"ALL",$Fn(e)),!SNt&&(SNt=new xp),mZ(SNt,pnt,pnt),!SNt&&(SNt=new xp),mZ(SNt,mnt,mnt),!SNt&&(SNt=new xp),mZ(SNt,"ALL","ALL")}return BB(SJ(t?iNt:rNt,n),136)}function nXn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p;if(l=!1,f=!1,vA(BB(mMn(i,(HXn(),ept)),98))){a=!1,u=!1;n:for(w=new Wb(i.j);w.a<w.c.c.length;)for(b=BB(n0(w),11),d=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[new Hw(b),new Gw(b)])));dAn(d);)if(!qy(TD(mMn(BB(U5(d),11).i,Tdt)))){if(b.j==(kUn(),sCt)){a=!0;break n}if(b.j==SCt){u=!0;break n}}l=u&&!a,f=a&&!u}if(l||f||0==i.b.c.length)p=!f;else{for(h=0,s=new Wb(i.b);s.a<s.c.c.length;)h+=(o=BB(n0(s),70)).n.b+o.o.b/2;p=(h/=i.b.c.length)>=i.o.b/2}p?(g=BB(mMn(i,(hWn(),_lt)),15))?l?c=g:(r=BB(mMn(i,Dft),15))?c=g.gc()<=r.gc()?g:r:(c=new Np,hon(i,Dft,c)):(c=new Np,hon(i,_lt,c)):(r=BB(mMn(i,(hWn(),Dft)),15))?f?c=r:(g=BB(mMn(i,_lt),15))?c=r.gc()<=g.gc()?r:g:(c=new Np,hon(i,_lt,c)):(c=new Np,hon(i,Dft,c)),c.Fc(n),hon(n,(hWn(),_ft),e),t.d==e?(MZ(t,null),e.e.c.length+e.g.c.length==0&&IZ(e,null),gsn(e)):(SZ(t,null),e.e.c.length+e.g.c.length==0&&IZ(e,null)),yQ(t.a)}function tXn(n,t){var e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C;for(v=new M2(n.b,0),d=0,s=BB((f=t.Kc()).Pb(),19).a,k=0,e=new Rv,E=new fA;v.b<v.d.gc();){for(Px(v.b<v.d.gc()),y=new Wb(BB(v.d.Xb(v.c=v.b++),29).a);y.a<y.c.c.length;){for(w=new oz(ZL(lbn(m=BB(n0(y),10)).a.Kc(),new h));dAn(w);)l=BB(U5(w),17),E.a.zc(l,E);for(b=new oz(ZL(fbn(m).a.Kc(),new h));dAn(b);)l=BB(U5(b),17),E.a.Bc(l)}if(d+1==s){for(yR(v,r=new HX(n)),yR(v,c=new HX(n)),M=E.a.ec().Kc();M.Ob();)T=BB(M.Pb(),17),e.a._b(T)||(++k,e.a.zc(T,e)),hon(a=new $vn(n),(HXn(),ept),(QEn(),VIt)),PZ(a,r),Bl(a,(uSn(),Tut)),IZ(g=new ISn,a),qIn(g,(kUn(),ICt)),IZ(S=new ISn,a),qIn(S,oCt),hon(i=new $vn(n),ept,VIt),PZ(i,c),Bl(i,Tut),IZ(p=new ISn,i),qIn(p,ICt),IZ(P=new ISn,i),qIn(P,oCt),SZ(j=new wY,T.c),MZ(j,g),SZ(C=new wY,S),MZ(C,p),SZ(T,P),u=new v3(a,i,j,C,T),hon(a,(hWn(),Rft),u),hon(i,Rft,u),(I=j.c.i).k==Tut&&((o=BB(mMn(I,Rft),305)).d=u,u.g=o);if(!f.Ob())break;s=BB(f.Pb(),19).a}++d}return iln(k)}function eXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d;for(f=0,r=new AL((!t.a&&(t.a=new eU(UOt,t,10,11)),t.a));r.e!=r.i.gc();)qy(TD(ZAn(i=BB(kpn(r),33),(HXn(),Ggt))))||(GC(ZAn(t,Ldt))===GC((mon(),Nvt))&&GC(ZAn(t,Gdt))!==GC((Vvn(),Eht))&&GC(ZAn(t,Gdt))!==GC((Vvn(),kht))&&!qy(TD(ZAn(t,xdt)))&&GC(ZAn(t,Idt))===GC((Bfn(),wut))||qy(TD(ZAn(i,$dt)))||(Ypn(i,(hWn(),wlt),iln(f)),++f),wzn(n,i,e));for(f=0,s=new AL((!t.b&&(t.b=new eU(KOt,t,12,3)),t.b));s.e!=s.i.gc();)u=BB(kpn(s),79),(GC(ZAn(t,(HXn(),Ldt)))!==GC((mon(),Nvt))||GC(ZAn(t,Gdt))===GC((Vvn(),Eht))||GC(ZAn(t,Gdt))===GC((Vvn(),kht))||qy(TD(ZAn(t,xdt)))||GC(ZAn(t,Idt))!==GC((Bfn(),wut)))&&(Ypn(u,(hWn(),wlt),iln(f)),++f),w=PMn(u),d=OMn(u),h=qy(TD(ZAn(w,wgt))),b=!qy(TD(ZAn(u,Ggt))),l=h&&QCn(u)&&qy(TD(ZAn(u,dgt))),c=JJ(w)==t&&JJ(w)==JJ(d),a=(JJ(w)==t&&d==t)^(JJ(d)==t&&w==t),b&&!l&&(a||c)&&uWn(n,u,t,e);if(JJ(t))for(o=new AL(iQ(JJ(t)));o.e!=o.i.gc();)(w=PMn(u=BB(kpn(o),79)))==t&&QCn(u)&&(l=qy(TD(ZAn(w,(HXn(),wgt))))&&qy(TD(ZAn(u,dgt))))&&uWn(n,u,t,e)}function iXn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A;for(OTn(i,"MinWidth layering",1),w=t.b,T=t.a,A=BB(mMn(t,(HXn(),Egt)),19).a,o=BB(mMn(t,Tgt),19).a,n.b=Gy(MD(mMn(t,ypt))),n.d=RQn,k=new Wb(T);k.a<k.c.c.length;)(m=BB(n0(k),10)).k==(uSn(),Iut)&&(P=m.o.b,n.d=e.Math.min(n.d,P));for(n.d=e.Math.max(1,n.d),M=T.c.length,n.c=x8(ANt,hQn,25,M,15,1),n.f=x8(ANt,hQn,25,M,15,1),n.e=x8(xNt,qQn,25,M,15,1),h=0,n.a=0,j=new Wb(T);j.a<j.c.c.length;)(m=BB(n0(j),10)).p=h++,n.c[m.p]=whn(fbn(m)),n.f[m.p]=whn(lbn(m)),n.e[m.p]=m.o.b/n.d,n.a+=n.e[m.p];for(n.b/=n.d,n.a/=M,E=jOn(T),m$(T,QW(new _d(n))),g=RQn,d=DWn,u=null,O=A,C=A,a=o,c=o,A<0&&(O=BB(Tmt.a.zd(),19).a,C=BB(Tmt.b.zd(),19).a),o<0&&(a=BB(Emt.a.zd(),19).a,c=BB(Emt.b.zd(),19).a),I=O;I<=C;I++)for(r=a;r<=c;r++)v=Gy(MD((S=LBn(n,I,r,T,E)).a)),p=(b=BB(S.b,15)).gc(),(v<g||v==g&&p<d)&&(g=v,d=p,u=b);for(l=u.Kc();l.Ob();){for(f=BB(l.Pb(),15),s=new HX(t),y=f.Kc();y.Ob();)PZ(m=BB(y.Pb(),10),s);w.c[w.c.length]=s}JPn(w),T.c=x8(Ant,HWn,1,0,5,1),HSn(i)}function rXn(n,t){var i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(n.b=t,n.a=BB(mMn(t,(HXn(),hgt)),19).a,n.c=BB(mMn(t,lgt),19).a,0==n.c&&(n.c=DWn),g=new M2(t.b,0);g.b<g.d.gc();){for(Px(g.b<g.d.gc()),d=BB(g.d.Xb(g.c=g.b++),29),o=new Np,l=-1,y=-1,m=new Wb(d.a);m.a<m.c.c.length;)v=BB(n0(m),10),F3((qK(),new oz(ZL(hbn(v).a.Kc(),new h))))>=n.a&&(r=yBn(n,v),l=e.Math.max(l,r.b),y=e.Math.max(y,r.d),WB(o,new rC(v,r)));for(E=new Np,f=0;f<l;++f)kG(E,0,(Px(g.b>0),g.a.Xb(g.c=--g.b),yR(g,T=new HX(n.b)),Px(g.b<g.d.gc()),g.d.Xb(g.c=g.b++),T));for(u=new Wb(o);u.a<u.c.c.length;)if(c=BB(n0(u),46),w=BB(c.b,571).a)for(b=new Wb(w);b.a<b.c.c.length;)ukn(n,BB(n0(b),10),Uut,E);for(i=new Np,s=0;s<y;++s)WB(i,(yR(g,M=new HX(n.b)),M));for(a=new Wb(o);a.a<a.c.c.length;)if(c=BB(n0(a),46),j=BB(c.b,571).c)for(k=new Wb(j);k.a<k.c.c.length;)ukn(n,BB(n0(k),10),Xut,i)}for(p=new M2(t.b,0);p.b<p.d.gc();)Px(p.b<p.d.gc()),0==BB(p.d.Xb(p.c=p.b++),29).a.c.length&&fW(p)}function cXn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(OTn(i,"Spline edge routing",1),0==t.b.c.length)return t.f.a=0,void HSn(i);v=Gy(MD(mMn(t,(HXn(),Apt)))),o=Gy(MD(mMn(t,Tpt))),u=Gy(MD(mMn(t,kpt))),T=BB(mMn(t,rgt),336)==(Usn(),rmt),E=Gy(MD(mMn(t,cgt))),n.d=t,n.j.c=x8(Ant,HWn,1,0,5,1),n.a.c=x8(Ant,HWn,1,0,5,1),$U(n.k),f=VC((s=BB(xq(t.b,0),29)).a,(dxn(),jyt)),l=VC((d=BB(xq(t.b,t.b.c.length-1),29)).a,jyt),g=new Wb(t.b),p=null,I=0;do{for(RUn(n,p,m=g.a<g.c.c.length?BB(n0(g),29):null),MFn(n),P=0,y=I,b=!p||f&&p==s,w=!m||l&&m==d,(M=Kk(rcn(NV(AV(new Rq(null,new w1(n.i,16)),new ya),new ma))))>0?(h=0,p&&(h+=o),h+=(M-1)*u,m&&(h+=o),T&&m&&(h=e.Math.max(h,nxn(m,u,v,E))),h<v&&!b&&!w&&(P=(v-h)/2,h=v),y+=h):!b&&!w&&(y+=v),m&&Tqn(m,y),j=new Wb(n.i);j.a<j.c.c.length;)(k=BB(n0(j),128)).a.c=I,k.a.b=y-I,k.F=P,k.p=!p;gun(n.a,n.i),I=y,m&&(I+=m.c.a),p=m,b=w}while(m);for(c=new Wb(n.j);c.a<c.c.c.length;)a=man(n,r=BB(n0(c),17)),hon(r,(hWn(),$lt),a),S=Dxn(n,r),hon(r,Nlt,S);t.f.a=I,n.d=null,HSn(i)}function aXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;if(d=0!=n.i,v=!1,g=null,mA(n.e)){if((h=t.gc())>0){for(l=h<100?null:new Fj(h),w=(s=new jcn(t)).g,g=x8(ANt,hQn,25,h,15,1),i=0,m=new gtn(h),r=0;r<n.i;++r){b=u=n.g[r];n:for(p=0;p<2;++p){for(o=h;--o>=0;)if(null!=b?Nfn(b,w[o]):GC(b)===GC(w[o])){g.length<=i&&aHn(g,0,g=x8(ANt,hQn,25,2*g.length,15,1),0,i),g[i++]=r,f9(m,w[o]);break n}if(GC(b)===GC(u))break}}if(s=m,w=m.g,h=i,i>g.length&&aHn(g,0,g=x8(ANt,hQn,25,i,15,1),0,i),i>0){for(v=!0,c=0;c<i;++c)l=z_(n,BB(b=w[c],72),l);for(a=i;--a>=0;)Lyn(n,g[a]);if(i!=h){for(r=h;--r>=i;)Lyn(s,r);aHn(g,0,g=x8(ANt,hQn,25,i,15,1),0,i)}t=s}}}else for(t=jyn(n,t),r=n.i;--r>=0;)t.Hc(n.g[r])&&(Lyn(n,r),v=!0);if(v){if(null!=g){for(f=1==(e=t.gc())?yZ(n,4,t.Kc().Pb(),null,g[0],d):yZ(n,6,t,g,g[0],d),l=e<100?null:new Fj(e),r=t.Kc();r.Ob();)l=q_(n,BB(b=r.Pb(),72),l);l?(l.Ei(f),l.Fi()):ban(n.e,f)}else{for(l=$_(t.gc()),r=t.Kc();r.Ob();)l=q_(n,BB(b=r.Pb(),72),l);l&&l.Fi()}return!0}return!1}function uXn(n,t){var e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m;for((e=new hvn(t)).a||gKn(t),s=lRn(t),o=new pJ,g=new Qxn,d=new Wb(t.a);d.a<d.c.c.length;)for(r=new oz(ZL(lbn(BB(n0(d),10)).a.Kc(),new h));dAn(r);)(i=BB(U5(r),17)).c.i.k!=(uSn(),Mut)&&i.d.i.k!=Mut||JCn(o,upn((f=lzn(n,i,s,g)).d),f.a);for(a=new Np,m=BB(mMn(e.c,(hWn(),Xft)),21).Kc();m.Ob();){switch(v=BB(m.Pb(),61),w=g.c[v.g],b=g.b[v.g],u=g.a[v.g],c=null,p=null,v.g){case 4:c=new UV(n.d.a,w,s.b.a-n.d.a,b-w),p=new UV(n.d.a,w,u,b-w),zH(s,new xI(c.c+c.b,c.d)),zH(s,new xI(c.c+c.b,c.d+c.a));break;case 2:c=new UV(s.a.a,w,n.c.a-s.a.a,b-w),p=new UV(n.c.a-u,w,u,b-w),zH(s,new xI(c.c,c.d)),zH(s,new xI(c.c,c.d+c.a));break;case 1:c=new UV(w,n.d.b,b-w,s.b.b-n.d.b),p=new UV(w,n.d.b,b-w,u),zH(s,new xI(c.c,c.d+c.a)),zH(s,new xI(c.c+c.b,c.d+c.a));break;case 3:c=new UV(w,s.a.b,b-w,n.c.b-s.a.b),p=new UV(w,n.c.b-u,b-w,u),zH(s,new xI(c.c,c.d)),zH(s,new xI(c.c+c.b,c.d))}c&&((l=new nm).d=v,l.b=c,l.c=p,l.a=JQ(BB(h6(o,upn(v)),21)),a.c[a.c.length]=l)}return gun(e.b,a),e.d=Bhn(nGn(s)),e}function oXn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(null==i.p[t.p]){o=!0,i.p[t.p]=0,u=t,d=i.o==(oZ(),ryt)?_Qn:RQn;do{c=n.b.e[u.p],a=u.c.a.c.length,i.o==ryt&&c>0||i.o==cyt&&c<a-1?(s=null,h=null,s=i.o==cyt?BB(xq(u.c.a,c+1),10):BB(xq(u.c.a,c-1),10),oXn(n,h=i.g[s.p],i),d=n.e.bg(d,t,u),i.j[t.p]==t&&(i.j[t.p]=i.j[h.p]),i.j[t.p]==i.j[h.p]?(w=_$(n.d,u,s),i.o==cyt?(r=Gy(i.p[t.p]),l=Gy(i.p[h.p])+Gy(i.d[s.p])-s.d.d-w-u.d.a-u.o.b-Gy(i.d[u.p]),o?(o=!1,i.p[t.p]=e.Math.min(l,d)):i.p[t.p]=e.Math.min(r,e.Math.min(l,d))):(r=Gy(i.p[t.p]),l=Gy(i.p[h.p])+Gy(i.d[s.p])+s.o.b+s.d.a+w+u.d.d-Gy(i.d[u.p]),o?(o=!1,i.p[t.p]=e.Math.max(l,d)):i.p[t.p]=e.Math.max(r,e.Math.max(l,d)))):(w=Gy(MD(mMn(n.a,(HXn(),Opt)))),b=krn(n,i.j[t.p]),f=krn(n,i.j[h.p]),i.o==cyt?U1(b,f,Gy(i.p[t.p])+Gy(i.d[u.p])+u.o.b+u.d.a+w-(Gy(i.p[h.p])+Gy(i.d[s.p])-s.d.d)):U1(b,f,Gy(i.p[t.p])+Gy(i.d[u.p])-u.d.d-Gy(i.p[h.p])-Gy(i.d[s.p])-s.o.b-s.d.a-w))):d=n.e.bg(d,t,u),u=i.a[u.p]}while(u!=t);Ov(n.e,t)}}function sXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(f=t,h=new pJ,l=new pJ,c=N2(f,x6n),GSn((i=new fQ(n,e,h,l)).a,i.b,i.c,i.d,c),d=(h.i||(h.i=new HL(h,h.c))).Kc();d.Ob();)for(w=BB(d.Pb(),202),u=BB(h6(h,w),21).Kc();u.Ob();){if(a=u.Pb(),!(b=BB(sen(n.d,a),202)))throw r=R2(f,q6n),Hp(new ek(V6n+a+Q6n+r+W6n));!w.e&&(w.e=new h_(FOt,w,10,9)),f9(w.e,b)}for(p=(l.i||(l.i=new HL(l,l.c))).Kc();p.Ob();)for(g=BB(p.Pb(),202),s=BB(h6(l,g),21).Kc();s.Ob();){if(o=s.Pb(),!(b=BB(sen(n.d,o),202)))throw r=R2(f,q6n),Hp(new ek(V6n+o+Q6n+r+W6n));!g.g&&(g.g=new h_(FOt,g,9,10)),f9(g.g,b)}!e.b&&(e.b=new h_(_Ot,e,4,7)),0!=e.b.i&&(!e.c&&(e.c=new h_(_Ot,e,5,8)),0!=e.c.i)&&(!e.b&&(e.b=new h_(_Ot,e,4,7)),e.b.i<=1&&(!e.c&&(e.c=new h_(_Ot,e,5,8)),e.c.i<=1))&&1==(!e.a&&(e.a=new eU(FOt,e,6,6)),e.a).i&&(Svn(v=BB(Wtn((!e.a&&(e.a=new eU(FOt,e,6,6)),e.a),0),202))||Pvn(v)||(Lin(v,BB(Wtn((!e.b&&(e.b=new h_(_Ot,e,4,7)),e.b),0),82)),Nin(v,BB(Wtn((!e.c&&(e.c=new h_(_Ot,e,5,8)),e.c),0),82))))}function hXn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;for(y=0,k=(m=n.a).length;y<k;++y){for(v=m[y],s=DWn,h=DWn,w=new Wb(v.e);w.a<w.c.c.length;)(a=(l=BB(n0(w),10)).c?E7(l.c.a,l,0):-1)>0?(f=BB(xq(l.c.a,a-1),10),T=_$(n.b,l,f),g=l.n.b-l.d.d-(f.n.b+f.o.b+f.d.a+T)):g=l.n.b-l.d.d,s=e.Math.min(g,s),a<l.c.a.c.length-1?(f=BB(xq(l.c.a,a+1),10),T=_$(n.b,l,f),p=f.n.b-f.d.d-(l.n.b+l.o.b+l.d.a+T)):p=2*l.n.b,h=e.Math.min(p,h);for(o=DWn,c=!1,S=new Wb((r=BB(xq(v.e,0),10)).j);S.a<S.c.c.length;)for(M=BB(n0(S),11),d=r.n.b+M.n.b+M.a.b,i=new Wb(M.e);i.a<i.c.c.length;)t=(j=BB(n0(i),17).c).i.n.b+j.n.b+j.a.b-d,e.Math.abs(t)<e.Math.abs(o)&&e.Math.abs(t)<(t<0?s:h)&&(o=t,c=!0);for(E=new Wb((u=BB(xq(v.e,v.e.c.length-1),10)).j);E.a<E.c.c.length;)for(j=BB(n0(E),11),d=u.n.b+j.n.b+j.a.b,i=new Wb(j.g);i.a<i.c.c.length;)t=(M=BB(n0(i),17).d).i.n.b+M.n.b+M.a.b-d,e.Math.abs(t)<e.Math.abs(o)&&e.Math.abs(t)<(t<0?s:h)&&(o=t,c=!0);if(c&&0!=o)for(b=new Wb(v.e);b.a<b.c.c.length;)(l=BB(n0(b),10)).n.b+=o}}function fXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g;if(hU(n.a,t)){if(FT(BB(RX(n.a,t),53),e))return 1}else VW(n.a,t,new Rv);if(hU(n.a,e)){if(FT(BB(RX(n.a,e),53),t))return-1}else VW(n.a,e,new Rv);if(hU(n.e,t)){if(FT(BB(RX(n.e,t),53),e))return-1}else VW(n.e,t,new Rv);if(hU(n.e,e)){if(FT(BB(RX(n.a,e),53),t))return 1}else VW(n.e,e,new Rv);if(n.c==(mon(),xvt)||!Lx(t,(hWn(),wlt))||!Lx(e,(hWn(),wlt))){if(o=BB(EN(M4(Qon(AV(new Rq(null,new w1(t.j,16)),new sc)),new hc)),11),h=BB(EN(M4(Qon(AV(new Rq(null,new w1(e.j,16)),new fc)),new lc)),11),o&&h){if(u=o.i,s=h.i,u&&u==s){for(l=new Wb(u.j);l.a<l.c.c.length;){if((f=BB(n0(l),11))==o)return a_n(n,e,t),-1;if(f==h)return a_n(n,t,e),1}return E$(iEn(n,t),iEn(n,e))}for(d=0,g=(w=n.d).length;d<g;++d){if((b=w[d])==u)return a_n(n,e,t),-1;if(b==s)return a_n(n,t,e),1}}if(!Lx(t,(hWn(),wlt))||!Lx(e,wlt))return(r=iEn(n,t))>(a=iEn(n,e))?a_n(n,t,e):a_n(n,e,t),r<a?-1:r>a?1:0}return(i=BB(mMn(t,(hWn(),wlt)),19).a)>(c=BB(mMn(e,wlt),19).a)?a_n(n,t,e):a_n(n,e,t),i<c?-1:i>c?1:0}function lXn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(qy(TD(ZAn(t,(sWn(),zSt)))))return SQ(),SQ(),set;if(o=0!=(!t.a&&(t.a=new eU(UOt,t,10,11)),t.a).i,s=!(h=yCn(t)).dc(),o||s){if(!(r=BB(ZAn(t,mPt),149)))throw Hp(new rk("Resolved algorithm is not set; apply a LayoutAlgorithmResolver before computing layout."));if(d=OI(r,(hAn(),nAt)),Ngn(t),!o&&s&&!d)return SQ(),SQ(),set;if(u=new Np,GC(ZAn(t,ESt))===GC((ufn(),pIt))&&(OI(r,YOt)||OI(r,QOt)))for(l=pRn(n,t),Frn(b=new YT,(!t.a&&(t.a=new eU(UOt,t,10,11)),t.a));0!=b.b;)Ngn(f=BB(0==b.b?null:(Px(0!=b.b),Atn(b,b.a.a)),33)),GC(ZAn(f,ESt))===GC(mIt)||P8(f,eSt)&&!j5(r,ZAn(f,mPt))?(gun(u,lXn(n,f,e,i)),Ypn(f,ESt,mIt),__n(f)):Frn(b,(!f.a&&(f.a=new eU(UOt,f,10,11)),f.a));else for(l=(!t.a&&(t.a=new eU(UOt,t,10,11)),t.a).i,a=new AL((!t.a&&(t.a=new eU(UOt,t,10,11)),t.a));a.e!=a.i.gc();)gun(u,lXn(n,c=BB(kpn(a),33),e,i)),__n(c);for(w=new Wb(u);w.a<w.c.c.length;)Ypn(BB(n0(w),79),zSt,(hN(),!0));return Ugn(t,r,mcn(i,l)),wKn(u),s&&d?h:(SQ(),SQ(),set)}return SQ(),SQ(),set}function bXn(n,t,e,i,r,c,a,u,o){var s,h,f,l,b,w,d;switch(b=e,Bl(h=new $vn(o),(uSn(),Mut)),hon(h,(hWn(),Yft),a),hon(h,(HXn(),ept),(QEn(),XIt)),d=Gy(MD(n.We(tpt))),hon(h,tpt,d),IZ(f=new ISn,h),t!=QIt&&t!=YIt||(b=i>=0?hwn(u):Tln(hwn(u)),n.Ye(upt,b)),s=new Gj,l=!1,n.Xe(npt)?(Hx(s,BB(n.We(npt),8)),l=!0):yL(s,a.a/2,a.b/2),b.g){case 4:hon(h,kgt,(Tbn(),Flt)),hon(h,Gft,(Jun(),$ht)),h.o.b=a.b,d<0&&(h.o.a=-d),qIn(f,(kUn(),oCt)),l||(s.a=a.a),s.a-=a.a;break;case 2:hon(h,kgt,(Tbn(),Hlt)),hon(h,Gft,(Jun(),Oht)),h.o.b=a.b,d<0&&(h.o.a=-d),qIn(f,(kUn(),ICt)),l||(s.a=0);break;case 1:hon(h,ilt,(z7(),Ift)),h.o.a=a.a,d<0&&(h.o.b=-d),qIn(f,(kUn(),SCt)),l||(s.b=a.b),s.b-=a.b;break;case 3:hon(h,ilt,(z7(),Sft)),h.o.a=a.a,d<0&&(h.o.b=-d),qIn(f,(kUn(),sCt)),l||(s.b=0)}if(Hx(f.n,s),hon(h,npt,s),t==UIt||t==WIt||t==XIt){if(w=0,t==UIt&&n.Xe(ipt))switch(b.g){case 1:case 2:w=BB(n.We(ipt),19).a;break;case 3:case 4:w=-BB(n.We(ipt),19).a}else switch(b.g){case 4:case 2:w=c.b,t==WIt&&(w/=r.b);break;case 1:case 3:w=c.a,t==WIt&&(w/=r.a)}hon(h,Tlt,w)}return hon(h,Qft,b),h}function wXn(n){var t,e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E;if((e=Gy(MD(mMn(n.a.j,(HXn(),Kdt)))))<-1||!n.a.i||L_(BB(mMn(n.a.o,ept),98))||abn(n.a.o,(kUn(),oCt)).gc()<2&&abn(n.a.o,ICt).gc()<2)return!0;if(n.a.c.Rf())return!1;for(y=0,m=0,v=new Np,o=0,s=(u=n.a.e).length;o<s;++o){for(b=0,d=(l=u[o]).length;b<d;++b)if((f=l[b]).k!=(uSn(),Cut)){for(i=n.b[f.c.p][f.p],f.k==Mut?(i.b=1,BB(mMn(f,(hWn(),dlt)),11).j==(kUn(),oCt)&&(m+=i.a)):(E=abn(f,(kUn(),ICt))).dc()||!tL(E,new Nc)?i.c=1:((r=abn(f,oCt)).dc()||!tL(r,new Lc))&&(y+=i.a),a=new oz(ZL(lbn(f).a.Kc(),new h));dAn(a);)c=BB(U5(a),17),y+=i.c,m+=i.b,X8(n,i,c.d.i);for(j=new oz(new WL((g=Wen(Pun(Gk(xnt,1),HWn,20,0,[abn(f,(kUn(),sCt)),abn(f,SCt)]))).a.length,g.a));dAn(j);)k=BB(U5(j),11),(p=BB(mMn(k,(hWn(),Elt)),10))&&(y+=i.c,m+=i.b,X8(n,i,p))}else v.c[v.c.length]=f;for(w=new Wb(v);w.a<w.c.c.length;)for(f=BB(n0(w),10),i=n.b[f.c.p][f.p],a=new oz(ZL(lbn(f).a.Kc(),new h));dAn(a);)c=BB(U5(a),17),y+=i.c,m+=i.b,X8(n,i,c.d.i);v.c=x8(Ant,HWn,1,0,5,1)}return(0==(t=y+m)?RQn:(y-m)/t)>=e}function dXn(){function n(n){var t=this;this.dispatch=function(t){var e=t.data;switch(e.cmd){case"algorithms":var i=Swn((SQ(),new Hb(new Ob(lAt.b))));n.postMessage({id:e.id,data:i});break;case"categories":var r=Swn((SQ(),new Hb(new Ob(lAt.c))));n.postMessage({id:e.id,data:r});break;case"options":var c=Swn((SQ(),new Hb(new Ob(lAt.d))));n.postMessage({id:e.id,data:c});break;case"register":lGn(e.algorithms),n.postMessage({id:e.id});break;case"layout":xBn(e.graph,e.layoutOptions||{},e.options||{}),n.postMessage({id:e.id,data:e.graph})}},this.saveDispatch=function(e){try{t.dispatch(e)}catch(i){n.postMessage({id:e.data.id,error:i})}}}function e(t){var e=this;this.dispatcher=new n({postMessage:function(n){e.onmessage({data:n})}}),this.postMessage=function(n){setTimeout((function(){e.dispatcher.saveDispatch({data:n})}),0)}}if(aE(),typeof document===gYn&&typeof self!==gYn){var r=new n(self);self.onmessage=r.saveDispatch}else typeof t!==gYn&&t.exports&&(Object.defineProperty(i,"__esModule",{value:!0}),t.exports={default:e,Worker:e})}function gXn(n){n.N||(n.N=!0,n.b=kan(n,0),Rrn(n.b,0),Rrn(n.b,1),Rrn(n.b,2),n.bb=kan(n,1),Rrn(n.bb,0),Rrn(n.bb,1),n.fb=kan(n,2),Rrn(n.fb,3),Rrn(n.fb,4),_rn(n.fb,5),n.qb=kan(n,3),Rrn(n.qb,0),_rn(n.qb,1),_rn(n.qb,2),Rrn(n.qb,3),Rrn(n.qb,4),_rn(n.qb,5),Rrn(n.qb,6),n.a=jan(n,4),n.c=jan(n,5),n.d=jan(n,6),n.e=jan(n,7),n.f=jan(n,8),n.g=jan(n,9),n.i=jan(n,10),n.j=jan(n,11),n.k=jan(n,12),n.n=jan(n,13),n.o=jan(n,14),n.p=jan(n,15),n.q=jan(n,16),n.s=jan(n,17),n.r=jan(n,18),n.t=jan(n,19),n.u=jan(n,20),n.v=jan(n,21),n.w=jan(n,22),n.B=jan(n,23),n.A=jan(n,24),n.C=jan(n,25),n.D=jan(n,26),n.F=jan(n,27),n.G=jan(n,28),n.H=jan(n,29),n.J=jan(n,30),n.I=jan(n,31),n.K=jan(n,32),n.M=jan(n,33),n.L=jan(n,34),n.P=jan(n,35),n.Q=jan(n,36),n.R=jan(n,37),n.S=jan(n,38),n.T=jan(n,39),n.U=jan(n,40),n.V=jan(n,41),n.X=jan(n,42),n.W=jan(n,43),n.Y=jan(n,44),n.Z=jan(n,45),n.$=jan(n,46),n._=jan(n,47),n.ab=jan(n,48),n.cb=jan(n,49),n.db=jan(n,50),n.eb=jan(n,51),n.gb=jan(n,52),n.hb=jan(n,53),n.ib=jan(n,54),n.jb=jan(n,55),n.kb=jan(n,56),n.lb=jan(n,57),n.mb=jan(n,58),n.nb=jan(n,59),n.ob=jan(n,60),n.pb=jan(n,61))}function pXn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(m=0,0==t.f.a)for(p=new Wb(n);p.a<p.c.c.length;)d=BB(n0(p),10),m=e.Math.max(m,d.n.a+d.o.a+d.d.c);else m=t.f.a-t.c.a;for(m-=t.c.a,g=new Wb(n);g.a<g.c.c.length;){switch(Zp((d=BB(n0(g),10)).n,m-d.o.a),cH(d.f),Vmn(d),(d.q?d.q:(SQ(),SQ(),het))._b((HXn(),spt))&&Zp(BB(mMn(d,spt),8),m-d.o.a),BB(mMn(d,kdt),248).g){case 1:hon(d,kdt,(wvn(),$Mt));break;case 2:hon(d,kdt,(wvn(),AMt))}for(v=d.o,k=new Wb(d.j);k.a<k.c.c.length;){for(Zp((y=BB(n0(k),11)).n,v.a-y.o.a),Zp(y.a,y.o.a),qIn(y,Ccn(y.j)),(u=BB(mMn(y,ipt),19))&&hon(y,ipt,iln(-u.a)),a=new Wb(y.g);a.a<a.c.c.length;){for(r=spn((c=BB(n0(a),17)).a,0);r.b!=r.d.c;)(i=BB(b3(r),8)).a=m-i.a;if(h=BB(mMn(c,vgt),74))for(s=spn(h,0);s.b!=s.d.c;)(o=BB(b3(s),8)).a=m-o.a;for(b=new Wb(c.b);b.a<b.c.c.length;)Zp((f=BB(n0(b),70)).n,m-f.o.a)}for(w=new Wb(y.f);w.a<w.c.c.length;)Zp((f=BB(n0(w),70)).n,y.o.a-f.o.a)}for(d.k==(uSn(),Mut)&&(hon(d,(hWn(),Qft),Ccn(BB(mMn(d,Qft),61))),YMn(d)),l=new Wb(d.b);l.a<l.c.c.length;)Vmn(f=BB(n0(l),70)),Zp(f.n,v.a-f.o.a)}}function vXn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(m=0,0==t.f.b)for(p=new Wb(n);p.a<p.c.c.length;)d=BB(n0(p),10),m=e.Math.max(m,d.n.b+d.o.b+d.d.a);else m=t.f.b-t.c.b;for(m-=t.c.b,g=new Wb(n);g.a<g.c.c.length;){switch(Jp((d=BB(n0(g),10)).n,m-d.o.b),aH(d.f),Qmn(d),(d.q?d.q:(SQ(),SQ(),het))._b((HXn(),spt))&&Jp(BB(mMn(d,spt),8),m-d.o.b),BB(mMn(d,kdt),248).g){case 3:hon(d,kdt,(wvn(),CMt));break;case 4:hon(d,kdt,(wvn(),LMt))}for(v=d.o,k=new Wb(d.j);k.a<k.c.c.length;){for(Jp((y=BB(n0(k),11)).n,v.b-y.o.b),Jp(y.a,y.o.b),qIn(y,Ocn(y.j)),(u=BB(mMn(y,ipt),19))&&hon(y,ipt,iln(-u.a)),a=new Wb(y.g);a.a<a.c.c.length;){for(r=spn((c=BB(n0(a),17)).a,0);r.b!=r.d.c;)(i=BB(b3(r),8)).b=m-i.b;if(h=BB(mMn(c,vgt),74))for(s=spn(h,0);s.b!=s.d.c;)(o=BB(b3(s),8)).b=m-o.b;for(b=new Wb(c.b);b.a<b.c.c.length;)Jp((f=BB(n0(b),70)).n,m-f.o.b)}for(w=new Wb(y.f);w.a<w.c.c.length;)Jp((f=BB(n0(w),70)).n,y.o.b-f.o.b)}for(d.k==(uSn(),Mut)&&(hon(d,(hWn(),Qft),Ocn(BB(mMn(d,Qft),61))),gln(d)),l=new Wb(d.b);l.a<l.c.c.length;)Qmn(f=BB(n0(l),70)),Jp(f.n,v.b-f.o.b)}}function mXn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b;for(f=!1,s=n+1,l1(n,t.c.length),a=(h=BB(t.c[n],200)).a,u=null,c=0;c<h.a.c.length;c++)if(l1(c,a.c.length),!(r=BB(a.c[c],187)).c)if(0!=r.b.c.length){if(r.k||(u&&Gmn(u),Tvn(r,(u=new _J(u?u.e+u.d+i:0,h.f,i)).e+u.d,h.f),WB(h.d,u),xcn(u,r),r.k=!0),o=null,b=null,c<h.a.c.length-1?b=BB(xq(h.a,c+1),187):s<t.c.length&&0!=(l1(s,t.c.length),BB(t.c[s],200)).a.c.length&&(b=BB(xq((l1(s,t.c.length),BB(t.c[s],200)).a,0),187)),l=!1,(o=b)&&(l=!Nfn(o.j,h)),o){if(0==o.b.c.length){Tkn(h,o);break}if(p9(r,e-r.s),Gmn(r.q),f|=nSn(h,r,o,e,i),0==o.b.c.length)for(Tkn((l1(s,t.c.length),BB(t.c[s],200)),o),o=null;t.c.length>s&&0==(l1(s,t.c.length),BB(t.c[s],200)).a.c.length;)y7(t,(l1(s,t.c.length),t.c[s]));if(!o){--c;continue}if(AKn(t,h,r,o,l,e,s,i)){f=!0;continue}if(l){if(JBn(t,h,r,o,e,s,i)){f=!0;continue}if(Ahn(h,r)){r.c=!0,f=!0;continue}}else if(Ahn(h,r)){r.c=!0,f=!0;continue}if(f)continue}Ahn(h,r)?(r.c=!0,f=!0,o&&(o.k=!1)):Gmn(r.q)}else $T(),Tkn(h,r),--c,f=!0;return f}function yXn(n,t,i,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A;for(g=0,P=0,h=new Wb(n.b);h.a<h.c.c.length;)(s=BB(n0(h),157)).c&&ozn(s.c),g=e.Math.max(g,iG(s)),P+=iG(s)*eG(s);for(p=P/n.b.c.length,S=hjn(n.b,p),P+=n.b.c.length*S,g=e.Math.max(g,e.Math.sqrt(P*u))+i.b,O=i.b,A=i.d,w=0,l=i.b+i.c,DH(M=new YT,iln(0)),E=new YT,f=new M2(n.b,0),d=null,o=new Np;f.b<f.d.gc();)Px(f.b<f.d.gc()),C=iG(s=BB(f.d.Xb(f.c=f.b++),157)),b=eG(s),O+C>g&&(a&&(fO(E,w),fO(M,iln(f.b-1)),WB(n.d,d),o.c=x8(Ant,HWn,1,0,5,1)),O=i.b,A+=w+t,w=0,l=e.Math.max(l,i.b+i.c+C)),o.c[o.c.length]=s,Mpn(s,O,A),l=e.Math.max(l,O+C+i.c),w=e.Math.max(w,b),O+=C+t,d=s;if(gun(n.a,o),WB(n.d,BB(xq(o,o.c.length-1),157)),l=e.Math.max(l,r),(I=A+w+i.a)<c&&(w+=c-I,I=c),a)for(O=i.b,f=new M2(n.b,0),fO(M,iln(n.b.c.length)),m=BB(b3(T=spn(M,0)),19).a,fO(E,w),j=spn(E,0),k=0;f.b<f.d.gc();)f.b==m&&(O=i.b,k=Gy(MD(b3(j))),m=BB(b3(T),19).a),Px(f.b<f.d.gc()),Udn(s=BB(f.d.Xb(f.c=f.b++),157),k),f.b==m&&(v=l-O-i.c,y=iG(s),zdn(s,v),Fln(s,(v-y)/2,0)),O+=iG(s)+t;return new xI(l,I)}function kXn(n){var t,e,i,r;switch(r=null,n.c){case 6:return n.Vl();case 13:return n.Wl();case 23:return n.Nl();case 22:return n.Sl();case 18:return n.Pl();case 8:QXn(n),wWn(),r=oNt;break;case 9:return n.vl(!0);case 19:return n.wl();case 10:switch(n.a){case 100:case 68:case 119:case 87:case 115:case 83:return r=n.ul(n.a),QXn(n),r;case 101:case 102:case 110:case 114:case 116:case 117:case 118:case 120:(t=n.tl())<BQn?(wWn(),wWn(),r=new oG(0,t)):r=pz(Xln(t));break;case 99:return n.Fl();case 67:return n.Al();case 105:return n.Il();case 73:return n.Bl();case 103:return n.Gl();case 88:return n.Cl();case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return n.xl();case 80:case 112:if(!(r=DCn(n,n.a)))throw Hp(new ak(kWn((u$(),O8n))));break;default:r=QH(n.a)}QXn(n);break;case 0:if(93==n.a||123==n.a||125==n.a)throw Hp(new ak(kWn((u$(),C8n))));r=QH(n.a),e=n.a,QXn(n),(64512&e)==HQn&&0==n.c&&56320==(64512&n.a)&&((i=x8(ONt,WVn,25,2,15,1))[0]=e&QVn,i[1]=n.a&QVn,r=oU(pz(Bdn(i,0,i.length)),0),QXn(n));break;default:throw Hp(new ak(kWn((u$(),C8n))))}return r}function jXn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(r=new Np,c=DWn,a=DWn,u=DWn,i)for(c=n.f.a,d=new Wb(t.j);d.a<d.c.c.length;)for(s=new Wb(BB(n0(d),11).g);s.a<s.c.c.length;)0!=(o=BB(n0(s),17)).a.b&&((f=BB(gx(o.a),8)).a<c&&(a=c-f.a,u=DWn,r.c=x8(Ant,HWn,1,0,5,1),c=f.a),f.a<=c&&(r.c[r.c.length]=o,o.a.b>1&&(u=e.Math.min(u,e.Math.abs(BB(Dpn(o.a,1),8).b-f.b)))));else for(d=new Wb(t.j);d.a<d.c.c.length;)for(s=new Wb(BB(n0(d),11).e);s.a<s.c.c.length;)0!=(o=BB(n0(s),17)).a.b&&((b=BB(px(o.a),8)).a>c&&(a=b.a-c,u=DWn,r.c=x8(Ant,HWn,1,0,5,1),c=b.a),b.a>=c&&(r.c[r.c.length]=o,o.a.b>1&&(u=e.Math.min(u,e.Math.abs(BB(Dpn(o.a,o.a.b-2),8).b-b.b)))));if(0!=r.c.length&&a>t.o.a/2&&u>t.o.b/2){for(IZ(w=new ISn,t),qIn(w,(kUn(),sCt)),w.n.a=t.o.a/2,IZ(g=new ISn,t),qIn(g,SCt),g.n.a=t.o.a/2,g.n.b=t.o.b,s=new Wb(r);s.a<s.c.c.length;)o=BB(n0(s),17),i?(h=BB(dH(o.a),8),(0==o.a.b?g1(o.d):BB(gx(o.a),8)).b>=h.b?SZ(o,g):SZ(o,w)):(h=BB(gH(o.a),8),(0==o.a.b?g1(o.c):BB(px(o.a),8)).b>=h.b?MZ(o,g):MZ(o,w)),(l=BB(mMn(o,(HXn(),vgt)),74))&&ywn(l,h,!0);t.n.a=c-t.o.a/2}}function EXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(s=t,$in(o=Q3(n,L3(e),s),R2(s,q6n)),h=BB(sen(n.g,kCn(zJ(s,T6n))),33),i=null,(a=zJ(s,"sourcePort"))&&(i=kCn(a)),f=BB(sen(n.j,i),118),!h)throw Hp(new ek("An edge must have a source node (edge id: '"+Qdn(s)+W6n));if(f&&!wW(WJ(f),h))throw Hp(new ek("The source port of an edge must be a port of the edge's source node (edge id: '"+R2(s,q6n)+W6n));if(!o.b&&(o.b=new h_(_Ot,o,4,7)),f9(o.b,f||h),l=BB(sen(n.g,kCn(zJ(s,Y6n))),33),r=null,(u=zJ(s,"targetPort"))&&(r=kCn(u)),b=BB(sen(n.j,r),118),!l)throw Hp(new ek("An edge must have a target node (edge id: '"+Qdn(s)+W6n));if(b&&!wW(WJ(b),l))throw Hp(new ek("The target port of an edge must be a port of the edge's target node (edge id: '"+R2(s,q6n)+W6n));if(!o.c&&(o.c=new h_(_Ot,o,5,8)),f9(o.c,b||l),0==(!o.b&&(o.b=new h_(_Ot,o,4,7)),o.b).i||0==(!o.c&&(o.c=new h_(_Ot,o,5,8)),o.c).i)throw c=R2(s,q6n),Hp(new ek(X6n+c+W6n));return STn(s,o),s$n(s,o),xon(n,s,o)}function TXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;return f=IFn(HN(n,(kUn(),wCt)),t),w=ayn(HN(n,dCt),t),y=ayn(HN(n,ECt),t),T=uyn(HN(n,MCt),t),l=uyn(HN(n,hCt),t),v=ayn(HN(n,jCt),t),d=ayn(HN(n,gCt),t),j=ayn(HN(n,TCt),t),k=ayn(HN(n,fCt),t),M=uyn(HN(n,bCt),t),p=ayn(HN(n,yCt),t),m=ayn(HN(n,mCt),t),E=ayn(HN(n,lCt),t),S=uyn(HN(n,kCt),t),b=uyn(HN(n,pCt),t),g=ayn(HN(n,vCt),t),e=Lon(Pun(Gk(xNt,1),qQn,25,15,[v.a,T.a,j.a,S.a])),i=Lon(Pun(Gk(xNt,1),qQn,25,15,[w.a,f.a,y.a,g.a])),r=p.a,c=Lon(Pun(Gk(xNt,1),qQn,25,15,[d.a,l.a,k.a,b.a])),s=Lon(Pun(Gk(xNt,1),qQn,25,15,[v.b,w.b,d.b,m.b])),o=Lon(Pun(Gk(xNt,1),qQn,25,15,[T.b,f.b,l.b,g.b])),h=M.b,u=Lon(Pun(Gk(xNt,1),qQn,25,15,[j.b,y.b,k.b,E.b])),w9(HN(n,wCt),e+r,s+h),w9(HN(n,vCt),e+r,s+h),w9(HN(n,dCt),e+r,0),w9(HN(n,ECt),e+r,s+h+o),w9(HN(n,MCt),0,s+h),w9(HN(n,hCt),e+r+i,s+h),w9(HN(n,gCt),e+r+i,0),w9(HN(n,TCt),0,s+h+o),w9(HN(n,fCt),e+r+i,s+h+o),w9(HN(n,bCt),0,s),w9(HN(n,yCt),e,0),w9(HN(n,lCt),0,s+h+o),w9(HN(n,pCt),e+r+i,0),(a=new Gj).a=Lon(Pun(Gk(xNt,1),qQn,25,15,[e+i+r+c,M.a,m.a,E.a])),a.b=Lon(Pun(Gk(xNt,1),qQn,25,15,[s+o+h+u,p.b,S.b,b.b])),a}function MXn(n){var t,e,i,r,c,a,u,o,s,f,l,b,w,d,g;for(d=new Np,l=new Wb(n.d.b);l.a<l.c.c.length;)for(w=new Wb(BB(n0(l),29).a);w.a<w.c.c.length;){for(b=BB(n0(w),10),r=BB(RX(n.f,b),57),o=new oz(ZL(lbn(b).a.Kc(),new h));dAn(o);)if(s=!0,f=null,(i=spn((a=BB(U5(o),17)).a,0)).b!=i.d.c){for(t=BB(b3(i),8),e=null,a.c.j==(kUn(),sCt)&&((g=new PBn(t,new xI(t.a,r.d.d),r,a)).f.a=!0,g.a=a.c,d.c[d.c.length]=g),a.c.j==SCt&&((g=new PBn(t,new xI(t.a,r.d.d+r.d.a),r,a)).f.d=!0,g.a=a.c,d.c[d.c.length]=g);i.b!=i.d.c;)e=BB(b3(i),8),aen(t.b,e.b)||(f=new PBn(t,e,null,a),d.c[d.c.length]=f,s&&(s=!1,e.b<r.d.d?f.f.a=!0:e.b>r.d.d+r.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))),i.b!=i.d.c&&(t=e);f&&(c=BB(RX(n.f,a.d.i),57),t.b<c.d.d?f.f.a=!0:t.b>c.d.d+c.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))}for(u=new oz(ZL(fbn(b).a.Kc(),new h));dAn(u);)0!=(a=BB(U5(u),17)).a.b&&(t=BB(px(a.a),8),a.d.j==(kUn(),sCt)&&((g=new PBn(t,new xI(t.a,r.d.d),r,a)).f.a=!0,g.a=a.d,d.c[d.c.length]=g),a.d.j==SCt&&((g=new PBn(t,new xI(t.a,r.d.d+r.d.a),r,a)).f.d=!0,g.a=a.d,d.c[d.c.length]=g))}return d}function SXn(n,t,e){var i,r,c,a,u,o,s;if(OTn(e,"Network simplex node placement",1),n.e=t,n.n=BB(mMn(t,(hWn(),Alt)),304),oqn(n),REn(n),JT(wnn(new Rq(null,new w1(n.e.b,16)),new Hc),new cg(n)),JT(AV(wnn(AV(wnn(new Rq(null,new w1(n.e.b,16)),new ta),new ea),new ia),new ra),new rg(n)),qy(TD(mMn(n.e,(HXn(),xgt))))&&(OTn(c=mcn(e,1),"Straight Edges Pre-Processing",1),jzn(n),HSn(c)),Mvn(n.f),r=BB(mMn(t,xpt),19).a*n.f.a.c.length,W_n(Qk(Yk(BK(n.f),r),!1),mcn(e,1)),0!=n.d.a.gc()){for(OTn(c=mcn(e,1),"Flexible Where Space Processing",1),a=BB($N(Oz($V(new Rq(null,new w1(n.f.a,16)),new qc),new Dc)),19).a,u=BB($N(Cz($V(new Rq(null,new w1(n.f.a,16)),new Gc),new Rc)),19).a-a,o=AN(new qv,n.f),s=AN(new qv,n.f),UNn(aM(cM(rM(uM(new Hv,2e4),u),o),s)),JT(AV(AV(LU(n.i),new zc),new Uc),new zV(a,o,u,s)),i=n.d.a.ec().Kc();i.Ob();)BB(i.Pb(),213).g=1;W_n(Qk(Yk(BK(n.f),r),!1),mcn(c,1)),HSn(c)}qy(TD(mMn(t,xgt)))&&(OTn(c=mcn(e,1),"Straight Edges Post-Processing",1),SPn(n),HSn(c)),QGn(n),n.e=null,n.f=null,n.i=null,n.c=null,$U(n.k),n.j=null,n.a=null,n.o=null,n.d.a.$b(),HSn(e)}function PXn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(u=new Wb(n.a.b);u.a<u.c.c.length;)for(m=new Wb(BB(n0(u),29).a);m.a<m.c.c.length;)v=BB(n0(m),10),t.g[v.p]=v,t.a[v.p]=v,t.d[v.p]=0;for(o=n.a.b,t.c==(gJ(),nyt)&&(o=cL(o,152)?o6(BB(o,152)):cL(o,131)?BB(o,131).a:cL(o,54)?new fy(o):new IT(o)),a=o.Kc();a.Ob();)for(b=-1,l=BB(a.Pb(),29).a,t.o==(oZ(),cyt)&&(b=DWn,l=cL(l,152)?o6(BB(l,152)):cL(l,131)?BB(l,131).a:cL(l,54)?new fy(l):new IT(l)),k=l.Kc();k.Ob();)if(y=BB(k.Pb(),10),f=null,(f=t.c==nyt?BB(xq(n.b.f,y.p),15):BB(xq(n.b.b,y.p),15)).gc()>0)if(r=f.gc(),s=IJ(e.Math.floor((r+1)/2))-1,c=IJ(e.Math.ceil((r+1)/2))-1,t.o==cyt)for(h=c;h>=s;h--)t.a[y.p]==y&&(d=BB(f.Xb(h),46),w=BB(d.a,10),!FT(i,d.b)&&b>n.b.e[w.p]&&(t.a[w.p]=y,t.g[y.p]=t.g[w.p],t.a[y.p]=t.g[y.p],t.f[t.g[y.p].p]=(hN(),!!(qy(t.f[t.g[y.p].p])&y.k==(uSn(),Put))),b=n.b.e[w.p]));else for(h=s;h<=c;h++)t.a[y.p]==y&&(p=BB(f.Xb(h),46),g=BB(p.a,10),!FT(i,p.b)&&b<n.b.e[g.p]&&(t.a[g.p]=y,t.g[y.p]=t.g[g.p],t.a[y.p]=t.g[y.p],t.f[t.g[y.p].p]=(hN(),!!(qy(t.f[t.g[y.p].p])&y.k==(uSn(),Put))),b=n.b.e[g.p]))}function IXn(){IXn=O,eE(),POt=gOt.a,BB(Wtn(QQ(gOt.a),0),18),kOt=gOt.f,BB(Wtn(QQ(gOt.f),0),18),BB(Wtn(QQ(gOt.f),1),34),SOt=gOt.n,BB(Wtn(QQ(gOt.n),0),34),BB(Wtn(QQ(gOt.n),1),34),BB(Wtn(QQ(gOt.n),2),34),BB(Wtn(QQ(gOt.n),3),34),jOt=gOt.g,BB(Wtn(QQ(gOt.g),0),18),BB(Wtn(QQ(gOt.g),1),34),vOt=gOt.c,BB(Wtn(QQ(gOt.c),0),18),BB(Wtn(QQ(gOt.c),1),18),EOt=gOt.i,BB(Wtn(QQ(gOt.i),0),18),BB(Wtn(QQ(gOt.i),1),18),BB(Wtn(QQ(gOt.i),2),18),BB(Wtn(QQ(gOt.i),3),18),BB(Wtn(QQ(gOt.i),4),34),TOt=gOt.j,BB(Wtn(QQ(gOt.j),0),18),mOt=gOt.d,BB(Wtn(QQ(gOt.d),0),18),BB(Wtn(QQ(gOt.d),1),18),BB(Wtn(QQ(gOt.d),2),18),BB(Wtn(QQ(gOt.d),3),18),BB(Wtn(QQ(gOt.d),4),34),BB(Wtn(QQ(gOt.d),5),34),BB(Wtn(QQ(gOt.d),6),34),BB(Wtn(QQ(gOt.d),7),34),pOt=gOt.b,BB(Wtn(QQ(gOt.b),0),34),BB(Wtn(QQ(gOt.b),1),34),yOt=gOt.e,BB(Wtn(QQ(gOt.e),0),34),BB(Wtn(QQ(gOt.e),1),34),BB(Wtn(QQ(gOt.e),2),34),BB(Wtn(QQ(gOt.e),3),34),BB(Wtn(QQ(gOt.e),4),18),BB(Wtn(QQ(gOt.e),5),18),BB(Wtn(QQ(gOt.e),6),18),BB(Wtn(QQ(gOt.e),7),18),BB(Wtn(QQ(gOt.e),8),18),BB(Wtn(QQ(gOt.e),9),18),BB(Wtn(QQ(gOt.e),10),34),MOt=gOt.k,BB(Wtn(QQ(gOt.k),0),34),BB(Wtn(QQ(gOt.k),1),34)}function CXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P;for(M=new YT,j=new YT,g=-1,o=new Wb(n);o.a<o.c.c.length;){for((a=BB(n0(o),128)).s=g--,h=0,m=0,c=new Wb(a.t);c.a<c.c.c.length;)m+=(i=BB(n0(c),268)).c;for(r=new Wb(a.i);r.a<r.c.c.length;)h+=(i=BB(n0(r),268)).c;a.n=h,a.u=m,0==m?r5(j,a,j.c.b,j.c):0==h&&r5(M,a,M.c.b,M.c)}for(P=S4(n),d=(f=n.c.length)+1,p=f-1,b=new Np;0!=P.a.gc();){for(;0!=j.b;)Px(0!=j.b),k=BB(Atn(j,j.a.a),128),P.a.Bc(k),k.s=p--,cLn(k,M,j);for(;0!=M.b;)Px(0!=M.b),E=BB(Atn(M,M.a.a),128),P.a.Bc(E),E.s=d++,cLn(E,M,j);for(w=KVn,s=P.a.ec().Kc();s.Ob();)(v=(a=BB(s.Pb(),128)).u-a.n)>=w&&(v>w&&(b.c=x8(Ant,HWn,1,0,5,1),w=v),b.c[b.c.length]=a);0!=b.c.length&&(l=BB(xq(b,pvn(t,b.c.length)),128),P.a.Bc(l),l.s=d++,cLn(l,M,j),b.c=x8(Ant,HWn,1,0,5,1))}for(y=n.c.length+1,u=new Wb(n);u.a<u.c.c.length;)(a=BB(n0(u),128)).s<f&&(a.s+=y);for(T=new Wb(n);T.a<T.c.c.length;)for(e=new M2((E=BB(n0(T),128)).t,0);e.b<e.d.gc();)Px(e.b<e.d.gc()),S=(i=BB(e.d.Xb(e.c=e.b++),268)).b,E.s>S.s&&(fW(e),y7(S.i,i),i.c>0&&(i.a=S,WB(S.t,i),i.b=E,WB(E.i,i)))}function OXn(n){var t,e,i,r,c;switch(t=n.c){case 11:return n.Ml();case 12:return n.Ol();case 14:return n.Ql();case 15:return n.Tl();case 16:return n.Rl();case 17:return n.Ul();case 21:return QXn(n),wWn(),wWn(),sNt;case 10:switch(n.a){case 65:return n.yl();case 90:return n.Dl();case 122:return n.Kl();case 98:return n.El();case 66:return n.zl();case 60:return n.Jl();case 62:return n.Hl()}}switch(c=kXn(n),t=n.c){case 3:return n.Zl(c);case 4:return n.Xl(c);case 5:return n.Yl(c);case 0:if(123==n.a&&n.d<n.j){if(r=n.d,i=0,e=-1,!((t=fV(n.i,r++))>=48&&t<=57))throw Hp(new ak(kWn((u$(),X8n))));for(i=t-48;r<n.j&&(t=fV(n.i,r++))>=48&&t<=57;)if((i=10*i+t-48)<0)throw Hp(new ak(kWn((u$(),Y8n))));if(e=i,44==t){if(r>=n.j)throw Hp(new ak(kWn((u$(),V8n))));if((t=fV(n.i,r++))>=48&&t<=57){for(e=t-48;r<n.j&&(t=fV(n.i,r++))>=48&&t<=57;)if((e=10*e+t-48)<0)throw Hp(new ak(kWn((u$(),Y8n))));if(i>e)throw Hp(new ak(kWn((u$(),Q8n))))}else e=-1}if(125!=t)throw Hp(new ak(kWn((u$(),W8n))));n.sl(r)?(wWn(),wWn(),c=new h4(9,c),n.d=r+1):(wWn(),wWn(),c=new h4(3,c),n.d=r),c.dm(i),c.cm(e),QXn(n)}}return c}function AXn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(w=new J6(t.b),v=new J6(t.b),l=new J6(t.b),j=new J6(t.b),d=new J6(t.b),k=spn(t,0);k.b!=k.d.c;)for(u=new Wb((m=BB(b3(k),11)).g);u.a<u.c.c.length;)if((c=BB(n0(u),17)).c.i==c.d.i){if(m.j==c.d.j){j.c[j.c.length]=c;continue}if(m.j==(kUn(),sCt)&&c.d.j==SCt){d.c[d.c.length]=c;continue}}for(o=new Wb(d);o.a<o.c.c.length;)KKn(n,c=BB(n0(o),17),e,i,(kUn(),oCt));for(a=new Wb(j);a.a<a.c.c.length;)c=BB(n0(a),17),Bl(E=new $vn(n),(uSn(),Cut)),hon(E,(HXn(),ept),(QEn(),XIt)),hon(E,(hWn(),dlt),c),hon(T=new ISn,dlt,c.d),qIn(T,(kUn(),ICt)),IZ(T,E),hon(M=new ISn,dlt,c.c),qIn(M,oCt),IZ(M,E),hon(c.c,Elt,E),hon(c.d,Elt,E),SZ(c,null),MZ(c,null),e.c[e.c.length]=E,hon(E,Bft,iln(2));for(y=spn(t,0);y.b!=y.d.c;)s=(m=BB(b3(y),11)).e.c.length>0,g=m.g.c.length>0,s&&g?l.c[l.c.length]=m:s?w.c[w.c.length]=m:g&&(v.c[v.c.length]=m);for(b=new Wb(w);b.a<b.c.c.length;)WB(r,HBn(n,BB(n0(b),11),null,e));for(p=new Wb(v);p.a<p.c.c.length;)WB(r,HBn(n,null,BB(n0(p),11),e));for(f=new Wb(l);f.a<f.c.c.length;)WB(r,HBn(n,h=BB(n0(f),11),h,e))}function $Xn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;for(d=new xI(RQn,RQn),t=new xI(_Qn,_Qn),k=new Wb(n);k.a<k.c.c.length;)y=BB(n0(k),8),d.a=e.Math.min(d.a,y.a),d.b=e.Math.min(d.b,y.b),t.a=e.Math.max(t.a,y.a),t.b=e.Math.max(t.b,y.b);for(s=new xI(t.a-d.a,t.b-d.b),h=new ZFn(new xI(d.a-50,d.b-s.a-50),new xI(d.a-50,t.b+s.a+50),new xI(t.a+s.b/2+50,d.b+s.b/2)),m=new Rv,c=new Np,i=new Np,m.a.zc(h,m),E=new Wb(n);E.a<E.c.c.length;){for(j=BB(n0(E),8),c.c=x8(Ant,HWn,1,0,5,1),v=m.a.ec().Kc();v.Ob();)W8((g=BB(v.Pb(),308)).d,g.a),Cbn(W8(g.d,j),W8(g.d,g.a))<0&&(c.c[c.c.length]=g);for(i.c=x8(Ant,HWn,1,0,5,1),p=new Wb(c);p.a<p.c.c.length;)for(b=new Wb((g=BB(n0(p),308)).e);b.a<b.c.c.length;){for(f=BB(n0(b),168),a=!0,o=new Wb(c);o.a<o.c.c.length;)(u=BB(n0(o),308))!=g&&(cV(f,xq(u.e,0))||cV(f,xq(u.e,1))||cV(f,xq(u.e,2)))&&(a=!1);a&&(i.c[i.c.length]=f)}for(oMn(m,c),e5(m,new bn),l=new Wb(i);l.a<l.c.c.length;)TU(m,new ZFn(j,(f=BB(n0(l),168)).a,f.b))}for(e5(m,new jw(w=new Rv)),r=w.a.ec().Kc();r.Ob();)(_7(h,(f=BB(r.Pb(),168)).a)||_7(h,f.b))&&r.Qb();return e5(w,new wn),w}function LXn(n){var t,e,i;switch(e=BB(mMn(n,(hWn(),Zft)),21),t=kA(Nat),BB(mMn(n,(HXn(),sgt)),334)==(ufn(),pIt)&&Jcn(t,xat),qy(TD(mMn(n,ugt)))?dq(t,(yMn(),Rat),(lWn(),Hot)):dq(t,(yMn(),Kat),(lWn(),Hot)),null!=mMn(n,(I6(),TMt))&&Jcn(t,Dat),(qy(TD(mMn(n,ggt)))||qy(TD(mMn(n,ogt))))&&WG(t,(yMn(),Bat),(lWn(),eot)),BB(mMn(n,Udt),103).g){case 2:case 3:case 4:WG(dq(t,(yMn(),Rat),(lWn(),rot)),Bat,iot)}switch(e.Hc((bDn(),hft))&&WG(dq(dq(t,(yMn(),Rat),(lWn(),tot)),Fat,Zut),Bat,not),GC(mMn(n,Sgt))!==GC((sNn(),Cvt))&&dq(t,(yMn(),Kat),(lWn(),Not)),e.Hc(pft)&&(dq(t,(yMn(),Rat),(lWn(),Fot)),dq(t,_at,_ot),dq(t,Kat,Kot)),GC(mMn(n,Pdt))!==GC((JMn(),cft))&&GC(mMn(n,Zdt))!==GC((Mbn(),YPt))&&WG(t,(yMn(),Bat),(lWn(),pot)),qy(TD(mMn(n,fgt)))&&dq(t,(yMn(),Kat),(lWn(),got)),qy(TD(mMn(n,Hdt)))&&dq(t,(yMn(),Kat),(lWn(),Wot)),_Ln(n)&&(i=(GC(mMn(n,sgt))===GC(pIt)?BB(mMn(n,Rdt),292):BB(mMn(n,_dt),292))==(_an(),jft)?(lWn(),Rot):(lWn(),Yot),dq(t,(yMn(),Fat),i)),BB(mMn(n,zpt),377).g){case 1:dq(t,(yMn(),Fat),(lWn(),Vot));break;case 2:WG(dq(dq(t,(yMn(),Kat),(lWn(),Vut)),Fat,Qut),Bat,Yut)}return GC(mMn(n,Ldt))!==GC((mon(),Nvt))&&dq(t,(yMn(),Kat),(lWn(),Qot)),t}function NXn(n){NM(n,new MTn(vj(wj(pj(gj(new du,$4n),"ELK Rectangle Packing"),"Algorithm for packing of unconnected boxes, i.e. graphs without edges. The given order of the boxes is always preserved and the main reading direction of the boxes is left to right. The algorithm is divided into two phases. One phase approximates the width in which the rectangles can be placed. The next phase places the rectangles in rows using the previously calculated width as bounding width and bundles rectangles with a similar height in blocks. A compaction step reduces the size of the drawing. Finally, the rectangles are expanded to fill their bounding box and eliminate empty unused spaces."),new Za))),u2(n,$4n,VJn,1.3),u2(n,$4n,A4n,mpn(gEt)),u2(n,$4n,QJn,CEt),u2(n,$4n,vZn,15),u2(n,$4n,u3n,mpn(bEt)),u2(n,$4n,PZn,mpn(jEt)),u2(n,$4n,BZn,mpn(EEt)),u2(n,$4n,SZn,mpn(TEt)),u2(n,$4n,IZn,mpn(kEt)),u2(n,$4n,MZn,mpn(MEt)),u2(n,$4n,CZn,mpn(OEt)),u2(n,$4n,E4n,mpn(PEt)),u2(n,$4n,T4n,mpn(yEt)),u2(n,$4n,P4n,mpn(SEt)),u2(n,$4n,I4n,mpn(AEt)),u2(n,$4n,C4n,mpn(pEt)),u2(n,$4n,jZn,mpn(vEt)),u2(n,$4n,m3n,mpn(mEt)),u2(n,$4n,S4n,mpn(dEt)),u2(n,$4n,M4n,mpn(wEt)),u2(n,$4n,O4n,mpn(LEt))}function xXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d;if(null==e)return null;if(n.a!=t.Aj())throw Hp(new Ky(d6n+t.ne()+g6n));if(cL(t,457)){if(!(d=SDn(BB(t,671),e)))throw Hp(new Ky(p6n+e+"' is not a valid enumerator of '"+t.ne()+"'"));return d}switch(Ifn((CPn(),Z$t),t).cl()){case 2:e=FBn(e,!1);break;case 3:e=FBn(e,!0)}if(i=Ifn(Z$t,t).$k())return i.Aj().Nh().Kh(i,e);if(f=Ifn(Z$t,t).al()){for(d=new Np,s=0,h=(o=ysn(e)).length;s<h;++s)u=o[s],WB(d,f.Aj().Nh().Kh(f,u));return d}if(!(w=Ifn(Z$t,t).bl()).dc()){for(b=w.Kc();b.Ob();){l=BB(b.Pb(),148);try{if(null!=(d=l.Aj().Nh().Kh(l,e)))return d}catch(g){if(!cL(g=lun(g),60))throw Hp(g)}}throw Hp(new Ky(p6n+e+"' does not match any member types of the union datatype '"+t.ne()+"'"))}if(BB(t,834).Fj(),!(r=xfn(t.Bj())))return null;if(r==Stt){c=0;try{c=lKn(e,KVn,DWn)&QVn}catch(g){if(!cL(g=lun(g),127))throw Hp(g);c=V7(e)[0]}return fun(c)}if(r==mtt){for(a=0;a<COt.length;++a)try{return BM(COt[a],e)}catch(g){if(!cL(g=lun(g),32))throw Hp(g)}throw Hp(new Ky(p6n+e+"' is not a date formatted string of the form yyyy-MM-dd'T'HH:mm:ss'.'SSSZ or a valid subset thereof"))}throw Hp(new Ky(p6n+e+"' is invalid. "))}function DXn(n,t){var e,i,r,c,a,u,o,s;if(e=0,a=0,c=t.length,u=null,s=new Ck,a<c&&(b1(a,t.length),43==t.charCodeAt(a))&&(++e,++a<c&&(b1(a,t.length),43==t.charCodeAt(a)||(b1(a,t.length),45==t.charCodeAt(a)))))throw Hp(new Mk(DQn+t+'"'));for(;a<c&&(b1(a,t.length),46!=t.charCodeAt(a))&&(b1(a,t.length),101!=t.charCodeAt(a))&&(b1(a,t.length),69!=t.charCodeAt(a));)++a;if(s.a+=""+fx(null==t?zWn:(kW(t),t),e,a),a<c&&(b1(a,t.length),46==t.charCodeAt(a))){for(e=++a;a<c&&(b1(a,t.length),101!=t.charCodeAt(a))&&(b1(a,t.length),69!=t.charCodeAt(a));)++a;n.e=a-e,s.a+=""+fx(null==t?zWn:(kW(t),t),e,a)}else n.e=0;if(a<c&&(b1(a,t.length),101==t.charCodeAt(a)||(b1(a,t.length),69==t.charCodeAt(a)))&&(e=++a,a<c&&(b1(a,t.length),43==t.charCodeAt(a))&&++a<c&&(b1(a,t.length),45!=t.charCodeAt(a))&&++e,u=t.substr(e,c-e),n.e=n.e-lKn(u,KVn,DWn),n.e!=IJ(n.e)))throw Hp(new Mk("Scale out of range."));if((o=s.a).length<16){if(n.f=(null==Vtt&&(Vtt=new RegExp("^[+-]?\\d*$","i")),Vtt.test(o)?parseInt(o,10):NaN),isNaN(n.f))throw Hp(new Mk(DQn+t+'"'));n.a=aCn(n.f)}else fdn(n,new $A(o));for(n.d=s.a.length,r=0;r<s.a.length&&(45==(i=fV(s.a,r))||48==i);++r)--n.d;0==n.d&&(n.d=1)}function RXn(){RXn=O,JCn(fut=new pJ,(kUn(),wCt),vCt),JCn(fut,MCt,vCt),JCn(fut,MCt,kCt),JCn(fut,hCt,pCt),JCn(fut,hCt,vCt),JCn(fut,dCt,vCt),JCn(fut,dCt,mCt),JCn(fut,ECt,lCt),JCn(fut,ECt,vCt),JCn(fut,yCt,bCt),JCn(fut,yCt,vCt),JCn(fut,yCt,mCt),JCn(fut,yCt,lCt),JCn(fut,bCt,yCt),JCn(fut,bCt,kCt),JCn(fut,bCt,pCt),JCn(fut,bCt,vCt),JCn(fut,jCt,jCt),JCn(fut,jCt,mCt),JCn(fut,jCt,kCt),JCn(fut,gCt,gCt),JCn(fut,gCt,mCt),JCn(fut,gCt,pCt),JCn(fut,TCt,TCt),JCn(fut,TCt,lCt),JCn(fut,TCt,kCt),JCn(fut,fCt,fCt),JCn(fut,fCt,lCt),JCn(fut,fCt,pCt),JCn(fut,mCt,dCt),JCn(fut,mCt,yCt),JCn(fut,mCt,jCt),JCn(fut,mCt,gCt),JCn(fut,mCt,vCt),JCn(fut,mCt,mCt),JCn(fut,mCt,kCt),JCn(fut,mCt,pCt),JCn(fut,lCt,ECt),JCn(fut,lCt,yCt),JCn(fut,lCt,TCt),JCn(fut,lCt,fCt),JCn(fut,lCt,lCt),JCn(fut,lCt,kCt),JCn(fut,lCt,pCt),JCn(fut,lCt,vCt),JCn(fut,kCt,MCt),JCn(fut,kCt,bCt),JCn(fut,kCt,jCt),JCn(fut,kCt,TCt),JCn(fut,kCt,mCt),JCn(fut,kCt,lCt),JCn(fut,kCt,kCt),JCn(fut,kCt,vCt),JCn(fut,pCt,hCt),JCn(fut,pCt,bCt),JCn(fut,pCt,gCt),JCn(fut,pCt,fCt),JCn(fut,pCt,mCt),JCn(fut,pCt,lCt),JCn(fut,pCt,pCt),JCn(fut,pCt,vCt),JCn(fut,vCt,wCt),JCn(fut,vCt,MCt),JCn(fut,vCt,hCt),JCn(fut,vCt,dCt),JCn(fut,vCt,ECt),JCn(fut,vCt,yCt),JCn(fut,vCt,bCt),JCn(fut,vCt,mCt),JCn(fut,vCt,lCt),JCn(fut,vCt,kCt),JCn(fut,vCt,pCt),JCn(fut,vCt,vCt)}function _Xn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(n.d=new xI(RQn,RQn),n.c=new xI(_Qn,_Qn),l=t.Kc();l.Ob();)for(m=new Wb(BB(l.Pb(),37).a);m.a<m.c.c.length;)v=BB(n0(m),10),n.d.a=e.Math.min(n.d.a,v.n.a-v.d.b),n.d.b=e.Math.min(n.d.b,v.n.b-v.d.d),n.c.a=e.Math.max(n.c.a,v.n.a+v.o.a+v.d.c),n.c.b=e.Math.max(n.c.b,v.n.b+v.o.b+v.d.a);for(o=new Yv,f=t.Kc();f.Ob();)r=uXn(n,BB(f.Pb(),37)),WB(o.a,r),r.a=r.a|!BB(mMn(r.c,(hWn(),Xft)),21).dc();for(n.b=(Shn(),(T=new kt).f=new vin(i),T.b=oGn(T.f,o),T),jGn((w=n.b,new Xm,w)),n.e=new Gj,n.a=n.b.f.e,u=new Wb(o.a);u.a<u.c.c.length;)for(c=BB(n0(u),841),y=AJ(n.b,c),n_n(c.c,y.a,y.b),g=new Wb(c.c.a);g.a<g.c.c.length;)(d=BB(n0(g),10)).k==(uSn(),Mut)&&(p=lLn(n,d.n,BB(mMn(d,(hWn(),Qft)),61)),UR(kO(d.n),p));for(a=new Wb(o.a);a.a<a.c.c.length;)for(h=new Wb(wln(c=BB(n0(a),841)));h.a<h.c.c.length;)for(_x(E=new _j((s=BB(n0(h),17)).a),0,g1(s.c)),DH(E,g1(s.d)),b=null,j=spn(E,0);j.b!=j.d.c;)k=BB(b3(j),8),b?(uen(b.a,k.a)?(n.e.a=e.Math.min(n.e.a,b.a),n.a.a=e.Math.max(n.a.a,b.a)):uen(b.b,k.b)&&(n.e.b=e.Math.min(n.e.b,b.b),n.a.b=e.Math.max(n.a.b,b.b)),b=k):b=k;qx(n.e),UR(n.a,n.e)}function KXn(n){V$n(n.b,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"ConsistentTransient"])),V$n(n.a,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"WellFormedSourceURI"])),V$n(n.o,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"InterfaceIsAbstract AtMostOneID UniqueFeatureNames UniqueOperationSignatures NoCircularSuperTypes WellFormedMapEntryClass ConsistentSuperTypes DisjointFeatureAndOperationSignatures"])),V$n(n.p,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"WellFormedInstanceTypeName UniqueTypeParameterNames"])),V$n(n.v,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"UniqueEnumeratorNames UniqueEnumeratorLiterals"])),V$n(n.R,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"WellFormedName"])),V$n(n.T,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"UniqueParameterNames UniqueTypeParameterNames NoRepeatingVoid"])),V$n(n.U,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"WellFormedNsURI WellFormedNsPrefix UniqueSubpackageNames UniqueClassifierNames UniqueNsURIs"])),V$n(n.W,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"ConsistentOpposite SingleContainer ConsistentKeys ConsistentUnique ConsistentContainer"])),V$n(n.bb,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"ValidDefaultValueLiteral"])),V$n(n.eb,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"ValidLowerBound ValidUpperBound ConsistentBounds ValidType"])),V$n(n.H,V9n,Pun(Gk(Qtt,1),sVn,2,6,[Y9n,"ConsistentType ConsistentBounds ConsistentArguments"]))}function FXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(!t.dc()){if(r=new km,f=(a=e||BB(t.Xb(0),17)).c,gxn(),(s=f.i.k)!=(uSn(),Iut)&&s!=Cut&&s!=Mut&&s!=Tut)throw Hp(new Ky("The target node of the edge must be a normal node or a northSouthPort."));for(fO(r,Aon(Pun(Gk(PMt,1),sVn,8,0,[f.i.n,f.n,f.a]))),(kUn(),yCt).Hc(f.j)&&(b=Gy(MD(mMn(f,(hWn(),Llt)))),r5(r,new xI(Aon(Pun(Gk(PMt,1),sVn,8,0,[f.i.n,f.n,f.a])).a,b),r.c.b,r.c)),o=null,i=!1,u=t.Kc();u.Ob();)0!=(c=BB(u.Pb(),17).a).b&&(i?(r5(r,kL(UR(o,(Px(0!=c.b),BB(c.a.a.c,8))),.5),r.c.b,r.c),i=!1):i=!0,o=B$((Px(0!=c.b),BB(c.c.b.c,8))),Frn(r,c),yQ(c));l=a.d,yCt.Hc(l.j)&&(b=Gy(MD(mMn(l,(hWn(),Llt)))),r5(r,new xI(Aon(Pun(Gk(PMt,1),sVn,8,0,[l.i.n,l.n,l.a])).a,b),r.c.b,r.c)),fO(r,Aon(Pun(Gk(PMt,1),sVn,8,0,[l.i.n,l.n,l.a]))),n.d==(Usn(),emt)&&(Px(0!=r.b),w=BB(r.a.a.c,8),d=BB(Dpn(r,1),8),(g=new XZ(hsn(f.j))).a*=5,g.b*=5,p=XR(new xI(d.a,d.b),w),UR(v=new xI(iZ(g.a,p.a),iZ(g.b,p.b)),w),nX(spn(r,1),v),Px(0!=r.b),m=BB(r.c.b.c,8),y=BB(Dpn(r,r.b-2),8),(g=new XZ(hsn(l.j))).a*=5,g.b*=5,p=XR(new xI(y.a,y.b),m),UR(k=new xI(iZ(g.a,p.a),iZ(g.b,p.b)),m),_x(r,r.b-1,k)),h=new oBn(r),Frn(a.a,Fvn(h))}}function BXn(n,t,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A,$,L,N,x;if(y=(v=BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82)).Dg(),k=v.Eg(),m=v.Cg()/2,w=v.Bg()/2,cL(v,186)&&(y+=WJ(p=BB(v,118)).i,y+=WJ(p).i),y+=m,k+=w,I=(S=BB(Wtn((!n.b&&(n.b=new h_(_Ot,n,4,7)),n.b),0),82)).Dg(),C=S.Eg(),P=S.Cg()/2,j=S.Bg()/2,cL(S,186)&&(I+=WJ(M=BB(S,118)).i,I+=WJ(M).i),I+=P,C+=j,0==(!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i)tE(),o=new co,f9((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a),o);else if((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i>1)for(b=new cx((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a));b.e!=b.i.gc();)Qjn(b);for(d=I,I>y+m?d=y+m:I<y-m&&(d=y-m),g=C,C>k+w?g=k+w:C<k-w&&(g=k-w),d>y-m&&d<y+m&&g>k-w&&g<k+w&&(d=y+m),Cen(u=BB(Wtn((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a),0),202),d),Aen(u,g),E=y,y>I+P?E=I+P:y<I-P&&(E=I-P),T=k,k>C+j?T=C+j:k<C-j&&(T=C-j),E>I-P&&E<I+P&&T>C-j&&T<C+j&&(T=C+j),Ten(u,E),Oen(u,T),sqn((!u.a&&(u.a=new $L(xOt,u,5)),u.a)),a=pvn(t,5),v==S&&++a,A=E-d,N=T-g,h=.20000000298023224*e.Math.sqrt(A*A+N*N),$=A/(a+1),x=N/(a+1),O=d,L=g,s=0;s<a;s++)L+=x,(f=(O+=$)+H$n(t,24)*uYn*h-h/2)<0?f=1:f>i&&(f=i-1),(l=L+H$n(t,24)*uYn*h-h/2)<0?l=1:l>r&&(l=r-1),tE(),jen(c=new ro,f),Een(c,l),f9((!u.a&&(u.a=new $L(xOt,u,5)),u.a),c)}function HXn(){HXn=O,sWn(),ppt=jPt,vpt=EPt,mpt=TPt,ypt=MPt,jpt=SPt,Ept=PPt,Spt=CPt,Ipt=APt,Cpt=$Pt,Ppt=OPt,Opt=LPt,$pt=NPt,Npt=RPt,Mpt=IPt,fWn(),gpt=Kwt,kpt=Fwt,Tpt=Bwt,Apt=Hwt,hpt=new XA(pPt,iln(0)),fpt=Dwt,lpt=Rwt,bpt=_wt,zpt=ldt,Rpt=zwt,_pt=Wwt,Bpt=edt,Kpt=Ywt,Fpt=Zwt,Xpt=pdt,Upt=wdt,qpt=odt,Hpt=adt,Gpt=hdt,Rgt=Pwt,_gt=Iwt,rgt=_bt,cgt=Bbt,Ugt=new WA(12),zgt=new XA(XSt,Ugt),Mbn(),Zdt=new XA(vSt,ngt=QPt),tpt=new XA(aPt,0),wpt=new XA(vPt,iln(1)),Edt=new XA(cSt,dZn),Ggt=zSt,ept=uPt,upt=wPt,zdt=lSt,kdt=iSt,sgt=ESt,dpt=new XA(kPt,(hN(),!0)),wgt=SSt,dgt=PSt,Fgt=_St,qgt=qSt,Bgt=FSt,Ffn(),Udt=new XA(bSt,Wdt=BPt),$gt=DSt,Agt=NSt,cpt=fPt,rpt=hPt,apt=bPt,cpn(),new XA(ZSt,Vgt=qIt),Ygt=ePt,Jgt=iPt,Zgt=rPt,Qgt=tPt,Dpt=Gwt,Pgt=lwt,Sgt=hwt,xpt=qwt,kgt=ewt,Gdt=Tbt,qdt=jbt,xdt=ubt,Ddt=obt,_dt=bbt,Rdt=sbt,Hdt=ybt,Cgt=wwt,Ogt=dwt,pgt=Vbt,Kgt=$wt,Ngt=mwt,ugt=Gbt,Dgt=Mwt,egt=Nbt,igt=Dbt,Ndt=hSt,Lgt=gwt,Pdt=Qlt,Sdt=Wlt,Mdt=Xlt,fgt=Xbt,hgt=Ubt,lgt=Wbt,Hgt=BSt,vgt=OSt,agt=ySt,Ydt=gSt,Qdt=dSt,Kdt=gbt,ipt=sPt,Tdt=sSt,bgt=MSt,npt=cPt,Xgt=VSt,Wgt=YSt,Egt=cwt,Tgt=uwt,spt=gPt,jdt=Ult,Mgt=swt,Jdt=Obt,Vdt=Ibt,Igt=$St,mgt=Zbt,xgt=jwt,Lpt=xPt,Xdt=Sbt,opt=Nwt,tgt=$bt,ygt=twt,Fdt=vbt,ggt=CSt,jgt=rwt,Bdt=mbt,Ldt=cbt,Adt=ebt,Cdt=nbt,Odt=tbt,$dt=rbt,Idt=Jlt,ogt=zbt}function qXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(uHn(),T=n.e,w=n.d,r=n.a,0==T)switch(t){case 0:return"0";case 1:return WQn;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(j=new Ik).a+=t<0?"0E+":"0E",j.a+=-t,j.a}if(y=x8(ONt,WVn,25,1+(m=10*w+1+7),15,1),e=m,1==w)if((u=r[0])<0){I=e0(u,UQn);do{d=I,I=Ojn(I,10),y[--e]=48+dG(ibn(d,cbn(I,10)))&QVn}while(0!=Vhn(I,0))}else{I=u;do{d=I,I=I/10|0,y[--e]=d-10*I+48&QVn}while(0!=I)}else{aHn(r,0,S=x8(ANt,hQn,25,w,15,1),0,P=w);n:for(;;){for(E=0,s=P-1;s>=0;s--)p=fTn(rbn(yz(E,32),e0(S[s],UQn))),S[s]=dG(p),E=dG(kz(p,32));v=dG(E),g=e;do{y[--e]=48+v%10&QVn}while(0!=(v=v/10|0)&&0!=e);for(i=9-g+e,o=0;o<i&&e>0;o++)y[--e]=48;for(f=P-1;0==S[f];f--)if(0==f)break n;P=f+1}for(;48==y[e];)++e}if(b=T<0,a=m-e-t-1,0==t)return b&&(y[--e]=45),Bdn(y,e,m-e);if(t>0&&a>=-6){if(a>=0){for(h=e+a,l=m-1;l>=h;l--)y[l+1]=y[l];return y[++h]=46,b&&(y[--e]=45),Bdn(y,e,m-e+1)}for(f=2;f<1-a;f++)y[--e]=48;return y[--e]=46,y[--e]=48,b&&(y[--e]=45),Bdn(y,e,m-e)}return M=e+1,c=m,k=new Ck,b&&(k.a+="-"),c-M>=1?(xX(k,y[e]),k.a+=".",k.a+=Bdn(y,e+1,m-e-1)):k.a+=Bdn(y,e,m-e),k.a+="E",a>0&&(k.a+="+"),k.a+=""+a,k.a}function GXn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;switch(n.c=t,n.g=new xp,GM(),twn(new Pw(new Dy(n.c))),v=SD(ZAn(n.c,(MMn(),dTt))),u=BB(ZAn(n.c,pTt),316),y=BB(ZAn(n.c,vTt),429),c=BB(ZAn(n.c,hTt),482),m=BB(ZAn(n.c,gTt),430),n.j=Gy(MD(ZAn(n.c,mTt))),a=n.a,u.g){case 0:a=n.a;break;case 1:a=n.b;break;case 2:a=n.i;break;case 3:a=n.e;break;case 4:a=n.f;break;default:throw Hp(new Ky(N4n+(null!=u.f?u.f:""+u.g)))}if(n.d=new DJ(a,y,c),hon(n.d,(Xcn(),Qrt),TD(ZAn(n.c,lTt))),n.d.c=qy(TD(ZAn(n.c,fTt))),0==YQ(n.c).i)return n.d;for(h=new AL(YQ(n.c));h.e!=h.i.gc();){for(l=(s=BB(kpn(h),33)).g/2,f=s.f/2,k=new xI(s.i+l,s.j+f);hU(n.g,k);)Kx(k,(e.Math.random()-.5)*lZn,(e.Math.random()-.5)*lZn);w=BB(ZAn(s,(sWn(),$St)),142),d=new AZ(k,new UV(k.a-l-n.j/2-w.b,k.b-f-n.j/2-w.d,s.g+n.j+(w.b+w.c),s.f+n.j+(w.d+w.a))),WB(n.d.i,d),VW(n.g,k,new rC(d,s))}switch(m.g){case 0:if(null==v)n.d.d=BB(xq(n.d.i,0),65);else for(p=new Wb(n.d.i);p.a<p.c.c.length;)d=BB(n0(p),65),null!=(b=BB(BB(RX(n.g,d.a),46).b,33).zg())&&m_(b,v)&&(n.d.d=d);break;case 1:for((i=new xI(n.c.g,n.c.f)).a*=.5,i.b*=.5,Kx(i,n.c.i,n.c.j),r=RQn,g=new Wb(n.d.i);g.a<g.c.c.length;)(o=W8((d=BB(n0(g),65)).a,i))<r&&(r=o,n.d.d=d);break;default:throw Hp(new Ky(N4n+(null!=m.f?m.f:""+m.g)))}return n.d}function zXn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;for(j=BB(Wtn((!n.a&&(n.a=new eU(FOt,n,6,6)),n.a),0),202),f=new km,k=new xp,E=tFn(j),jIn(k.f,j,E),b=new xp,r=new YT,d=NU(Wen(Pun(Gk(xnt,1),HWn,20,0,[(!t.d&&(t.d=new h_(KOt,t,8,5)),t.d),(!t.e&&(t.e=new h_(KOt,t,7,4)),t.e)])));dAn(d);){if(w=BB(U5(d),79),1!=(!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i)throw Hp(new Ky(B5n+(!n.a&&(n.a=new eU(FOt,n,6,6)),n.a).i));w!=n&&(r5(r,p=BB(Wtn((!w.a&&(w.a=new eU(FOt,w,6,6)),w.a),0),202),r.c.b,r.c),(g=BB(qC(AY(k.f,p)),12))||(g=tFn(p),jIn(k.f,p,g)),l=i?XR(new wA(BB(xq(E,E.c.length-1),8)),BB(xq(g,g.c.length-1),8)):XR(new wA((l1(0,E.c.length),BB(E.c[0],8))),(l1(0,g.c.length),BB(g.c[0],8))),jIn(b.f,p,l))}if(0!=r.b)for(v=BB(xq(E,i?E.c.length-1:0),8),h=1;h<E.c.length;h++){for(m=BB(xq(E,i?E.c.length-1-h:h),8),c=spn(r,0);c.b!=c.d.c;)p=BB(b3(c),202),(g=BB(qC(AY(k.f,p)),12)).c.length<=h?mtn(c):(y=UR(new wA(BB(xq(g,i?g.c.length-1-h:h),8)),BB(qC(AY(b.f,p)),8)),m.a==y.a&&m.b==y.b||(a=m.a-v.a,o=m.b-v.b,(u=y.a-v.a)*o==(s=y.b-v.b)*a&&(0==a||isNaN(a)?a:a<0?-1:1)==(0==u||isNaN(u)?u:u<0?-1:1)&&(0==o||isNaN(o)?o:o<0?-1:1)==(0==s||isNaN(s)?s:s<0?-1:1)?(e.Math.abs(a)<e.Math.abs(u)||e.Math.abs(o)<e.Math.abs(s))&&r5(f,m,f.c.b,f.c):h>1&&r5(f,v,f.c.b,f.c),mtn(c)));v=m}return f}function UXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A;for(OTn(e,"Greedy cycle removal",1),A=(m=t.a).c.length,n.a=x8(ANt,hQn,25,A,15,1),n.c=x8(ANt,hQn,25,A,15,1),n.b=x8(ANt,hQn,25,A,15,1),s=0,p=new Wb(m);p.a<p.c.c.length;){for((d=BB(n0(p),10)).p=s,T=new Wb(d.j);T.a<T.c.c.length;){for(u=new Wb((k=BB(n0(T),11)).e);u.a<u.c.c.length;)(i=BB(n0(u),17)).c.i!=d&&(S=BB(mMn(i,(HXn(),fpt)),19).a,n.a[s]+=S>0?S+1:1);for(a=new Wb(k.g);a.a<a.c.c.length;)(i=BB(n0(a),17)).d.i!=d&&(S=BB(mMn(i,(HXn(),fpt)),19).a,n.c[s]+=S>0?S+1:1)}0==n.c[s]?DH(n.e,d):0==n.a[s]&&DH(n.f,d),++s}for(w=-1,b=1,f=new Np,n.d=BB(mMn(t,(hWn(),Slt)),230);A>0;){for(;0!=n.e.b;)I=BB(dH(n.e),10),n.b[I.p]=w--,Q_n(n,I),--A;for(;0!=n.f.b;)C=BB(dH(n.f),10),n.b[C.p]=b++,Q_n(n,C),--A;if(A>0){for(l=KVn,v=new Wb(m);v.a<v.c.c.length;)d=BB(n0(v),10),0==n.b[d.p]&&(y=n.c[d.p]-n.a[d.p])>=l&&(y>l&&(f.c=x8(Ant,HWn,1,0,5,1),l=y),f.c[f.c.length]=d);h=n.Zf(f),n.b[h.p]=b++,Q_n(n,h),--A}}for(P=m.c.length+1,s=0;s<m.c.length;s++)n.b[s]<0&&(n.b[s]+=P);for(g=new Wb(m);g.a<g.c.c.length;)for(E=0,M=(j=C2((d=BB(n0(g),10)).j)).length;E<M;++E)for(c=0,o=(r=Z0((k=j[E]).g)).length;c<o;++c)O=(i=r[c]).d.i.p,n.b[d.p]>n.b[O]&&(tBn(i,!0),hon(t,qft,(hN(),!0)));n.a=null,n.c=null,n.b=null,yQ(n.f),yQ(n.e),HSn(e)}function XXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;for(i=new Np,u=new Np,g=t/2,b=n.gc(),r=BB(n.Xb(0),8),p=BB(n.Xb(1),8),WB(i,(l1(0,(w=QAn(r.a,r.b,p.a,p.b,g)).c.length),BB(w.c[0],8))),WB(u,(l1(1,w.c.length),BB(w.c[1],8))),s=2;s<b;s++)d=r,r=p,p=BB(n.Xb(s),8),WB(i,(l1(1,(w=QAn(r.a,r.b,d.a,d.b,g)).c.length),BB(w.c[1],8))),WB(u,(l1(0,w.c.length),BB(w.c[0],8))),WB(i,(l1(0,(w=QAn(r.a,r.b,p.a,p.b,g)).c.length),BB(w.c[0],8))),WB(u,(l1(1,w.c.length),BB(w.c[1],8)));for(WB(i,(l1(1,(w=QAn(p.a,p.b,r.a,r.b,g)).c.length),BB(w.c[1],8))),WB(u,(l1(0,w.c.length),BB(w.c[0],8))),e=new km,a=new Np,DH(e,(l1(0,i.c.length),BB(i.c[0],8))),h=1;h<i.c.length-2;h+=2)l1(h,i.c.length),c=BB(i.c[h],8),l=qPn((l1(h-1,i.c.length),BB(i.c[h-1],8)),c,(l1(h+1,i.c.length),BB(i.c[h+1],8)),(l1(h+2,i.c.length),BB(i.c[h+2],8))),isFinite(l.a)&&isFinite(l.b)?r5(e,l,e.c.b,e.c):r5(e,c,e.c.b,e.c);for(DH(e,BB(xq(i,i.c.length-1),8)),WB(a,(l1(0,u.c.length),BB(u.c[0],8))),f=1;f<u.c.length-2;f+=2)l1(f,u.c.length),c=BB(u.c[f],8),l=qPn((l1(f-1,u.c.length),BB(u.c[f-1],8)),c,(l1(f+1,u.c.length),BB(u.c[f+1],8)),(l1(f+2,u.c.length),BB(u.c[f+2],8))),isFinite(l.a)&&isFinite(l.b)?a.c[a.c.length]=l:a.c[a.c.length]=c;for(WB(a,BB(xq(u,u.c.length-1),8)),o=a.c.length-1;o>=0;o--)DH(e,(l1(o,a.c.length),BB(a.c[o],8)));return e}function WXn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b;if(a=!0,f=null,i=null,r=null,t=!1,b=kAt,s=null,c=null,(o=Vgn(n,u=0,AAt,$At))<n.length&&(b1(o,n.length),58==n.charCodeAt(o))&&(f=n.substr(u,o-u),u=o+1),e=null!=f&&xT(jAt,f.toLowerCase())){if(-1==(o=n.lastIndexOf("!/")))throw Hp(new Ky("no archive separator"));a=!0,i=fx(n,u,++o),u=o}else u>=0&&m_(n.substr(u,2),"//")?(o=Vgn(n,u+=2,LAt,NAt),i=n.substr(u,o-u),u=o):null==f||u!=n.length&&(b1(u,n.length),47==n.charCodeAt(u))||(a=!1,-1==(o=yN(n,YTn(35),u))&&(o=n.length),i=n.substr(u,o-u),u=o);if(!e&&u<n.length&&(b1(u,n.length),47==n.charCodeAt(u))&&(o=Vgn(n,u+1,LAt,NAt),(h=n.substr(u+1,o-(u+1))).length>0&&58==fV(h,h.length-1)&&(r=h,u=o)),u<n.length&&(b1(u,n.length),47==n.charCodeAt(u))&&(++u,t=!0),u<n.length&&(b1(u,n.length),63!=n.charCodeAt(u))&&(b1(u,n.length),35!=n.charCodeAt(u))){for(l=new Np;u<n.length&&(b1(u,n.length),63!=n.charCodeAt(u))&&(b1(u,n.length),35!=n.charCodeAt(u));)o=Vgn(n,u,LAt,NAt),WB(l,n.substr(u,o-u)),(u=o)<n.length&&(b1(u,n.length),47==n.charCodeAt(u))&&(Qhn(n,++u)||(l.c[l.c.length]=""));Qgn(l,b=x8(Qtt,sVn,2,l.c.length,6,1))}return u<n.length&&(b1(u,n.length),63==n.charCodeAt(u))&&(-1==(o=lx(n,35,++u))&&(o=n.length),s=n.substr(u,o-u),u=o),u<n.length&&(c=nO(n,++u)),wGn(a,f,i,r,b,s),new rRn(a,f,i,r,t,b,s,c)}function VXn(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A,$;for(O=new Np,w=new Wb(t.b);w.a<w.c.c.length;)for(k=new Wb(BB(n0(w),29).a);k.a<k.c.c.length;){for((y=BB(n0(k),10)).p=-1,l=KVn,T=KVn,S=new Wb(y.j);S.a<S.c.c.length;){for(c=new Wb((M=BB(n0(S),11)).e);c.a<c.c.c.length;)i=BB(n0(c),17),P=BB(mMn(i,(HXn(),bpt)),19).a,l=e.Math.max(l,P);for(r=new Wb(M.g);r.a<r.c.c.length;)i=BB(n0(r),17),P=BB(mMn(i,(HXn(),bpt)),19).a,T=e.Math.max(T,P)}hon(y,Xmt,iln(l)),hon(y,Wmt,iln(T))}for(p=0,b=new Wb(t.b);b.a<b.c.c.length;)for(k=new Wb(BB(n0(b),29).a);k.a<k.c.c.length;)(y=BB(n0(k),10)).p<0&&((C=new rm).b=p++,jRn(n,y,C),O.c[O.c.length]=C);for(E=sx(O.c.length),f=sx(O.c.length),u=0;u<O.c.length;u++)WB(E,new Np),WB(f,iln(0));for(vzn(t,O,E,f),A=BB(Qgn(O,x8(Ymt,O3n,257,O.c.length,0,1)),840),j=BB(Qgn(E,x8(Rnt,nZn,15,E.c.length,0,1)),192),h=x8(ANt,hQn,25,f.c.length,15,1),o=0;o<h.length;o++)h[o]=(l1(o,f.c.length),BB(f.c[o],19)).a;for(v=0,m=new Np,s=0;s<A.length;s++)0==h[s]&&WB(m,A[s]);for(g=x8(ANt,hQn,25,A.length,15,1);0!=m.c.length;)for(g[(C=BB(s6(m,0),257)).b]=v++;!j[C.b].dc();)--h[($=BB(j[C.b].$c(0),257)).b],0==h[$.b]&&(m.c[m.c.length]=$);for(n.a=x8(Ymt,O3n,257,A.length,0,1),a=0;a<A.length;a++)for(d=A[a],I=g[a],n.a[I]=d,d.b=I,k=new Wb(d.e);k.a<k.c.c.length;)(y=BB(n0(k),10)).p=I;return n.a}function QXn(n){var t,e,i;if(n.d>=n.j)return n.a=-1,void(n.c=1);if(t=fV(n.i,n.d++),n.a=t,1!=n.b){switch(t){case 124:i=2;break;case 42:i=3;break;case 43:i=4;break;case 63:i=5;break;case 41:i=7;break;case 46:i=8;break;case 91:i=9;break;case 94:i=11;break;case 36:i=12;break;case 40:if(i=6,n.d>=n.j)break;if(63!=fV(n.i,n.d))break;if(++n.d>=n.j)throw Hp(new ak(kWn((u$(),p8n))));switch(t=fV(n.i,n.d++)){case 58:i=13;break;case 61:i=14;break;case 33:i=15;break;case 91:i=19;break;case 62:i=18;break;case 60:if(n.d>=n.j)throw Hp(new ak(kWn((u$(),p8n))));if(61==(t=fV(n.i,n.d++)))i=16;else{if(33!=t)throw Hp(new ak(kWn((u$(),v8n))));i=17}break;case 35:for(;n.d<n.j&&41!=(t=fV(n.i,n.d++)););if(41!=t)throw Hp(new ak(kWn((u$(),m8n))));i=21;break;default:if(45==t||97<=t&&t<=122||65<=t&&t<=90){--n.d,i=22;break}if(40==t){i=23;break}throw Hp(new ak(kWn((u$(),p8n))))}break;case 92:if(i=10,n.d>=n.j)throw Hp(new ak(kWn((u$(),g8n))));n.a=fV(n.i,n.d++);break;default:i=0}n.c=i}else{switch(t){case 92:if(i=10,n.d>=n.j)throw Hp(new ak(kWn((u$(),g8n))));n.a=fV(n.i,n.d++);break;case 45:512==(512&n.e)&&n.d<n.j&&91==fV(n.i,n.d)?(++n.d,i=24):i=0;break;case 91:if(512!=(512&n.e)&&n.d<n.j&&58==fV(n.i,n.d)){++n.d,i=20;break}default:(64512&t)==HQn&&n.d<n.j&&56320==(64512&(e=fV(n.i,n.d)))&&(n.a=BQn+(t-HQn<<10)+e-56320,++n.d),i=0}n.c=i}}function YXn(n){var t,e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P;if((j=BB(mMn(n,(HXn(),ept)),98))!=(QEn(),QIt)&&j!=YIt){for(s=new J6((lin((b=(w=n.b).c.length)+2,NVn),ttn(rbn(rbn(5,b+2),(b+2)/10|0)))),d=new J6((lin(b+2,NVn),ttn(rbn(rbn(5,b+2),(b+2)/10|0)))),WB(s,new xp),WB(s,new xp),WB(d,new Np),WB(d,new Np),k=new Np,t=0;t<b;t++)for(l1(t,w.c.length),e=BB(w.c[t],29),l1(t,s.c.length),E=BB(s.c[t],83),g=new xp,s.c[s.c.length]=g,l1(t,d.c.length),M=BB(d.c[t],15),v=new Np,d.c[d.c.length]=v,r=new Wb(e.a);r.a<r.c.c.length;)if(cln(i=BB(n0(r),10)))k.c[k.c.length]=i;else{for(o=new oz(ZL(fbn(i).a.Kc(),new h));dAn(o);)cln(S=(a=BB(U5(o),17)).c.i)&&((T=BB(E.xc(mMn(S,(hWn(),dlt))),10))||(T=oCn(n,S),E.zc(mMn(S,dlt),T),M.Fc(T)),SZ(a,BB(xq(T.j,1),11)));for(u=new oz(ZL(lbn(i).a.Kc(),new h));dAn(u);)cln(P=(a=BB(U5(u),17)).d.i)&&((p=BB(RX(g,mMn(P,(hWn(),dlt))),10))||(p=oCn(n,P),VW(g,mMn(P,dlt),p),v.c[v.c.length]=p),MZ(a,BB(xq(p.j,0),11)))}for(f=0;f<d.c.length;f++)if(l1(f,d.c.length),!(m=BB(d.c[f],15)).dc())for(l=null,0==f?(l=new HX(n),LZ(0,w.c.length),MS(w.c,0,l)):f==s.c.length-1?(l=new HX(n),w.c[w.c.length]=l):(l1(f-1,w.c.length),l=BB(w.c[f-1],29)),c=m.Kc();c.Ob();)PZ(BB(c.Pb(),10),l);for(y=new Wb(k);y.a<y.c.c.length;)PZ(BB(n0(y),10),null);hon(n,(hWn(),Wft),k)}}function JXn(n,t,e){var i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j;if(OTn(e,"Coffman-Graham Layering",1),0!=t.a.c.length){for(j=BB(mMn(t,(HXn(),mgt)),19).a,o=0,a=0,b=new Wb(t.a);b.a<b.c.c.length;)for((l=BB(n0(b),10)).p=o++,c=new oz(ZL(lbn(l).a.Kc(),new h));dAn(c);)(r=BB(U5(c),17)).p=a++;for(n.d=x8($Nt,ZYn,25,o,16,1),n.a=x8($Nt,ZYn,25,a,16,1),n.b=x8(ANt,hQn,25,o,15,1),n.e=x8(ANt,hQn,25,o,15,1),n.f=x8(ANt,hQn,25,o,15,1),win(n.c),rEn(n,t),d=new Xz(new Dd(n)),k=new Wb(t.a);k.a<k.c.c.length;){for(c=new oz(ZL(fbn(m=BB(n0(k),10)).a.Kc(),new h));dAn(c);)r=BB(U5(c),17),n.a[r.p]||++n.b[m.p];0==n.b[m.p]&&F8(eMn(d,m))}for(u=0;0!=d.b.c.length;)for(m=BB(mnn(d),10),n.f[m.p]=u++,c=new oz(ZL(lbn(m).a.Kc(),new h));dAn(c);)r=BB(U5(c),17),n.a[r.p]||(p=r.d.i,--n.b[p.p],JCn(n.c,p,iln(n.f[m.p])),0==n.b[p.p]&&F8(eMn(d,p)));for(w=new Xz(new Rd(n)),y=new Wb(t.a);y.a<y.c.c.length;){for(c=new oz(ZL(lbn(m=BB(n0(y),10)).a.Kc(),new h));dAn(c);)r=BB(U5(c),17),n.a[r.p]||++n.e[m.p];0==n.e[m.p]&&F8(eMn(w,m))}for(i=r1(t,f=new Np);0!=w.b.c.length;)for(v=BB(mnn(w),10),(i.a.c.length>=j||!Ndn(v,i))&&(i=r1(t,f)),PZ(v,i),c=new oz(ZL(fbn(v).a.Kc(),new h));dAn(c);)r=BB(U5(c),17),n.a[r.p]||(g=r.c.i,--n.e[g.p],0==n.e[g.p]&&F8(eMn(w,g)));for(s=f.c.length-1;s>=0;--s)WB(t.b,(l1(s,f.c.length),BB(f.c[s],29)));t.a.c=x8(Ant,HWn,1,0,5,1),HSn(e)}else HSn(e)}function ZXn(n){var t,e,i,r,c,a,u,o;for(n.b=1,QXn(n),t=null,0==n.c&&94==n.a?(QXn(n),wWn(),wWn(),Yxn(t=new M0(4),0,unt),a=new M0(4)):(wWn(),wWn(),a=new M0(4)),r=!0;1!=(o=n.c);){if(0==o&&93==n.a&&!r){t&&(WGn(t,a),a=t);break}if(e=n.a,i=!1,10==o)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:sHn(a,dKn(e)),i=!0;break;case 105:case 73:case 99:case 67:sHn(a,dKn(e)),(e=-1)<0&&(i=!0);break;case 112:case 80:if(!(u=DCn(n,e)))throw Hp(new ak(kWn((u$(),O8n))));sHn(a,u),i=!0;break;default:e=qDn(n)}else if(24==o&&!r){if(t&&(WGn(t,a),a=t),WGn(a,ZXn(n)),0!=n.c||93!=n.a)throw Hp(new ak(kWn((u$(),N8n))));break}if(QXn(n),!i){if(0==o){if(91==e)throw Hp(new ak(kWn((u$(),x8n))));if(93==e)throw Hp(new ak(kWn((u$(),D8n))));if(45==e&&!r&&93!=n.a)throw Hp(new ak(kWn((u$(),R8n))))}if(0!=n.c||45!=n.a||45==e&&r)Yxn(a,e,e);else{if(QXn(n),1==(o=n.c))throw Hp(new ak(kWn((u$(),$8n))));if(0==o&&93==n.a)Yxn(a,e,e),Yxn(a,45,45);else{if(0==o&&93==n.a||24==o)throw Hp(new ak(kWn((u$(),R8n))));if(c=n.a,0==o){if(91==c)throw Hp(new ak(kWn((u$(),x8n))));if(93==c)throw Hp(new ak(kWn((u$(),D8n))));if(45==c)throw Hp(new ak(kWn((u$(),R8n))))}else 10==o&&(c=qDn(n));if(QXn(n),e>c)throw Hp(new ak(kWn((u$(),F8n))));Yxn(a,e,c)}}}r=!1}if(1==n.c)throw Hp(new ak(kWn((u$(),$8n))));return T$n(a),qHn(a),n.b=0,QXn(n),a}function nWn(n){V$n(n.c,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#decimal"])),V$n(n.d,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#integer"])),V$n(n.e,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#boolean"])),V$n(n.f,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"EBoolean",t8n,"EBoolean:Object"])),V$n(n.i,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#byte"])),V$n(n.g,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#hexBinary"])),V$n(n.j,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"EByte",t8n,"EByte:Object"])),V$n(n.n,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"EChar",t8n,"EChar:Object"])),V$n(n.t,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#double"])),V$n(n.u,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"EDouble",t8n,"EDouble:Object"])),V$n(n.F,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#float"])),V$n(n.G,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"EFloat",t8n,"EFloat:Object"])),V$n(n.I,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#int"])),V$n(n.J,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"EInt",t8n,"EInt:Object"])),V$n(n.N,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#long"])),V$n(n.O,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"ELong",t8n,"ELong:Object"])),V$n(n.Z,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#short"])),V$n(n.$,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"EShort",t8n,"EShort:Object"])),V$n(n._,K9n,Pun(Gk(Qtt,1),sVn,2,6,[J9n,"http://www.w3.org/2001/XMLSchema#string"]))}function tWn(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(1==n.c.length)return l1(0,n.c.length),BB(n.c[0],135);if(n.c.length<=0)return new P6;for(s=new Wb(n);s.a<s.c.c.length;){for(u=BB(n0(s),135),m=0,d=DWn,g=DWn,b=KVn,w=KVn,v=spn(u.b,0);v.b!=v.d.c;)p=BB(b3(v),86),m+=BB(mMn(p,(IAn(),$kt)),19).a,d=e.Math.min(d,p.e.a),g=e.Math.min(g,p.e.b),b=e.Math.max(b,p.e.a+p.f.a),w=e.Math.max(w,p.e.b+p.f.b);hon(u,(IAn(),$kt),iln(m)),hon(u,(qqn(),nkt),new xI(d,g)),hon(u,Zyt,new xI(b,w))}for(SQ(),m$(n,new ga),qan(k=new P6,(l1(0,n.c.length),BB(n.c[0],94))),l=0,S=0,h=new Wb(n);h.a<h.c.c.length;)u=BB(n0(h),135),j=XR(B$(BB(mMn(u,(qqn(),Zyt)),8)),BB(mMn(u,nkt),8)),l=e.Math.max(l,j.a),S+=j.a*j.b;for(l=e.Math.max(l,e.Math.sqrt(S)*Gy(MD(mMn(k,(IAn(),jkt))))),P=0,I=0,f=0,t=E=Gy(MD(mMn(k,xkt))),o=new Wb(n);o.a<o.c.c.length;)u=BB(n0(o),135),P+(j=XR(B$(BB(mMn(u,(qqn(),Zyt)),8)),BB(mMn(u,nkt),8))).a>l&&(P=0,I+=f+E,f=0),ELn(k,u,P,I),t=e.Math.max(t,P+j.a),f=e.Math.max(f,j.b),P+=j.a+E;for(y=new xp,i=new xp,M=new Wb(n);M.a<M.c.c.length;)for(r=qy(TD(mMn(T=BB(n0(M),135),(sWn(),lSt)))),a=(T.q?T.q:het).vc().Kc();a.Ob();)hU(y,(c=BB(a.Pb(),42)).cd())?GC(BB(c.cd(),146).wg())!==GC(c.dd())&&(r&&hU(i,c.cd())?($T(),BB(c.cd(),146).tg()):(VW(y,BB(c.cd(),146),c.dd()),hon(k,BB(c.cd(),146),c.dd()),r&&VW(i,BB(c.cd(),146),c.dd()))):(VW(y,BB(c.cd(),146),c.dd()),hon(k,BB(c.cd(),146),c.dd()));return k}function eWn(){eWn=O,RXn(),JCn(put=new pJ,(kUn(),dCt),wCt),JCn(put,MCt,wCt),JCn(put,gCt,wCt),JCn(put,jCt,wCt),JCn(put,kCt,wCt),JCn(put,mCt,wCt),JCn(put,jCt,dCt),JCn(put,wCt,hCt),JCn(put,dCt,hCt),JCn(put,MCt,hCt),JCn(put,gCt,hCt),JCn(put,yCt,hCt),JCn(put,jCt,hCt),JCn(put,kCt,hCt),JCn(put,mCt,hCt),JCn(put,bCt,hCt),JCn(put,wCt,ECt),JCn(put,dCt,ECt),JCn(put,hCt,ECt),JCn(put,MCt,ECt),JCn(put,gCt,ECt),JCn(put,yCt,ECt),JCn(put,jCt,ECt),JCn(put,bCt,ECt),JCn(put,TCt,ECt),JCn(put,kCt,ECt),JCn(put,pCt,ECt),JCn(put,mCt,ECt),JCn(put,dCt,MCt),JCn(put,gCt,MCt),JCn(put,jCt,MCt),JCn(put,mCt,MCt),JCn(put,dCt,gCt),JCn(put,MCt,gCt),JCn(put,jCt,gCt),JCn(put,gCt,gCt),JCn(put,kCt,gCt),JCn(put,wCt,fCt),JCn(put,dCt,fCt),JCn(put,hCt,fCt),JCn(put,ECt,fCt),JCn(put,MCt,fCt),JCn(put,gCt,fCt),JCn(put,yCt,fCt),JCn(put,jCt,fCt),JCn(put,TCt,fCt),JCn(put,bCt,fCt),JCn(put,mCt,fCt),JCn(put,kCt,fCt),JCn(put,vCt,fCt),JCn(put,wCt,TCt),JCn(put,dCt,TCt),JCn(put,hCt,TCt),JCn(put,MCt,TCt),JCn(put,gCt,TCt),JCn(put,yCt,TCt),JCn(put,jCt,TCt),JCn(put,bCt,TCt),JCn(put,mCt,TCt),JCn(put,pCt,TCt),JCn(put,vCt,TCt),JCn(put,dCt,bCt),JCn(put,MCt,bCt),JCn(put,gCt,bCt),JCn(put,jCt,bCt),JCn(put,TCt,bCt),JCn(put,mCt,bCt),JCn(put,kCt,bCt),JCn(put,wCt,lCt),JCn(put,dCt,lCt),JCn(put,hCt,lCt),JCn(put,MCt,lCt),JCn(put,gCt,lCt),JCn(put,yCt,lCt),JCn(put,jCt,lCt),JCn(put,bCt,lCt),JCn(put,mCt,lCt),JCn(put,dCt,kCt),JCn(put,hCt,kCt),JCn(put,ECt,kCt),JCn(put,gCt,kCt),JCn(put,wCt,pCt),JCn(put,dCt,pCt),JCn(put,ECt,pCt),JCn(put,MCt,pCt),JCn(put,gCt,pCt),JCn(put,yCt,pCt),JCn(put,jCt,pCt),JCn(put,jCt,vCt),JCn(put,gCt,vCt),JCn(put,bCt,wCt),JCn(put,bCt,MCt),JCn(put,bCt,hCt),JCn(put,yCt,wCt),JCn(put,yCt,dCt),JCn(put,yCt,ECt)}function iWn(n,t){switch(n.e){case 0:case 2:case 4:case 6:case 42:case 44:case 46:case 48:case 8:case 10:case 12:case 14:case 16:case 18:case 20:case 22:case 24:case 26:case 28:case 30:case 32:case 34:case 36:case 38:return new zQ(n.b,n.a,t,n.c);case 1:return new LL(n.a,t,Awn(t.Tg(),n.c));case 43:return new xL(n.a,t,Awn(t.Tg(),n.c));case 3:return new $L(n.a,t,Awn(t.Tg(),n.c));case 45:return new NL(n.a,t,Awn(t.Tg(),n.c));case 41:return new y9(BB(Ckn(n.c),26),n.a,t,Awn(t.Tg(),n.c));case 50:return new yin(BB(Ckn(n.c),26),n.a,t,Awn(t.Tg(),n.c));case 5:return new i_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 47:return new r_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 7:return new eU(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 49:return new e_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 9:return new FL(n.a,t,Awn(t.Tg(),n.c));case 11:return new KL(n.a,t,Awn(t.Tg(),n.c));case 13:return new _L(n.a,t,Awn(t.Tg(),n.c));case 15:return new MH(n.a,t,Awn(t.Tg(),n.c));case 17:return new BL(n.a,t,Awn(t.Tg(),n.c));case 19:return new RL(n.a,t,Awn(t.Tg(),n.c));case 21:return new DL(n.a,t,Awn(t.Tg(),n.c));case 23:return new yH(n.a,t,Awn(t.Tg(),n.c));case 25:return new f_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 27:return new h_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 29:return new o_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 31:return new c_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 33:return new s_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 35:return new u_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 37:return new a_(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 39:return new iU(n.a,t,Awn(t.Tg(),n.c),n.d.n);case 40:return new Ecn(t,Awn(t.Tg(),n.c));default:throw Hp(new dy("Unknown feature style: "+n.e))}}function rWn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;switch(OTn(e,"Brandes & Koepf node placement",1),n.a=t,n.c=FFn(t),i=BB(mMn(t,(HXn(),Ngt)),274),b=qy(TD(mMn(t,xgt))),n.d=i==(Bjn(),Qht)&&!b||i==Xht,Jqn(n,t),y=null,k=null,g=null,p=null,lin(4,AVn),d=new J6(4),BB(mMn(t,Ngt),274).g){case 3:g=new q_n(t,n.c.d,(oZ(),ryt),(gJ(),nyt)),d.c[d.c.length]=g;break;case 1:p=new q_n(t,n.c.d,(oZ(),cyt),(gJ(),nyt)),d.c[d.c.length]=p;break;case 4:y=new q_n(t,n.c.d,(oZ(),ryt),(gJ(),tyt)),d.c[d.c.length]=y;break;case 2:k=new q_n(t,n.c.d,(oZ(),cyt),(gJ(),tyt)),d.c[d.c.length]=k;break;default:g=new q_n(t,n.c.d,(oZ(),ryt),(gJ(),nyt)),p=new q_n(t,n.c.d,cyt,nyt),y=new q_n(t,n.c.d,ryt,tyt),k=new q_n(t,n.c.d,cyt,tyt),d.c[d.c.length]=y,d.c[d.c.length]=k,d.c[d.c.length]=g,d.c[d.c.length]=p}for(r=new iI(t,n.c),u=new Wb(d);u.a<u.c.c.length;)PXn(r,c=BB(n0(u),180),n.b),WBn(c);for(l=new Jyn(t,n.c),o=new Wb(d);o.a<o.c.c.length;)Hzn(l,c=BB(n0(o),180));if(e.n)for(s=new Wb(d);s.a<s.c.c.length;)OH(e,(c=BB(n0(s),180))+" size is "+v$n(c));if(f=null,n.d&&CBn(t,h=FUn(n,d,n.c.d),e)&&(f=h),!f)for(s=new Wb(d);s.a<s.c.c.length;)CBn(t,c=BB(n0(s),180),e)&&(!f||v$n(f)>v$n(c))&&(f=c);for(!f&&(l1(0,d.c.length),f=BB(d.c[0],180)),w=new Wb(t.b);w.a<w.c.c.length;)for(m=new Wb(BB(n0(w),29).a);m.a<m.c.c.length;)(v=BB(n0(m),10)).n.b=Gy(f.p[v.p])+Gy(f.d[v.p]);for(e.n&&(OH(e,"Chosen node placement: "+f),OH(e,"Blocks: "+xOn(f)),OH(e,"Classes: "+UAn(f,e)),OH(e,"Marked edges: "+n.b)),a=new Wb(d);a.a<a.c.c.length;)(c=BB(n0(a),180)).g=null,c.b=null,c.a=null,c.d=null,c.j=null,c.i=null,c.p=null;zrn(n.c),n.b.a.$b(),HSn(e)}function cWn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(a=new YT,v=BB(mMn(e,(HXn(),Udt)),103),w=0,Frn(a,(!t.a&&(t.a=new eU(UOt,t,10,11)),t.a));0!=a.b;)s=BB(0==a.b?null:(Px(0!=a.b),Atn(a,a.a.a)),33),(GC(ZAn(t,Ldt))!==GC((mon(),Nvt))||GC(ZAn(t,Gdt))===GC((Vvn(),Eht))||GC(ZAn(t,Gdt))===GC((Vvn(),kht))||qy(TD(ZAn(t,xdt)))||GC(ZAn(t,Idt))!==GC((Bfn(),wut)))&&!qy(TD(ZAn(s,$dt)))&&Ypn(s,(hWn(),wlt),iln(w++)),!qy(TD(ZAn(s,Ggt)))&&(f=0!=(!s.a&&(s.a=new eU(UOt,s,10,11)),s.a).i,b=kTn(s),l=GC(ZAn(s,sgt))===GC((ufn(),pIt)),g=null,(T=!P8(s,(sWn(),eSt))||m_(SD(ZAn(s,eSt)),w1n))&&l&&(f||b)&&(hon(g=kFn(s),Udt,v),Lx(g,gpt)&&My(new uwn(Gy(MD(mMn(g,gpt)))),g),0!=BB(ZAn(s,Fgt),174).gc()&&(h=g,JT(new Rq(null,(!s.c&&(s.c=new eU(XOt,s,9,9)),new w1(s.c,16))),new Xw(h)),mDn(s,g))),m=e,(y=BB(RX(n.a,JJ(s)),10))&&(m=y.e),d=wzn(n,s,m),g&&(d.e=g,g.e=d,Frn(a,(!s.a&&(s.a=new eU(UOt,s,10,11)),s.a))));for(w=0,r5(a,t,a.c.b,a.c);0!=a.b;){for(o=new AL((!(c=BB(0==a.b?null:(Px(0!=a.b),Atn(a,a.a.a)),33)).b&&(c.b=new eU(KOt,c,12,3)),c.b));o.e!=o.i.gc();)t_n(u=BB(kpn(o),79)),(GC(ZAn(t,Ldt))!==GC((mon(),Nvt))||GC(ZAn(t,Gdt))===GC((Vvn(),Eht))||GC(ZAn(t,Gdt))===GC((Vvn(),kht))||qy(TD(ZAn(t,xdt)))||GC(ZAn(t,Idt))!==GC((Bfn(),wut)))&&Ypn(u,(hWn(),wlt),iln(w++)),j=PTn(BB(Wtn((!u.b&&(u.b=new h_(_Ot,u,4,7)),u.b),0),82)),E=PTn(BB(Wtn((!u.c&&(u.c=new h_(_Ot,u,5,8)),u.c),0),82)),qy(TD(ZAn(u,Ggt)))||qy(TD(ZAn(j,Ggt)))||qy(TD(ZAn(E,Ggt)))||(p=c,QCn(u)&&qy(TD(ZAn(j,wgt)))&&qy(TD(ZAn(u,dgt)))||Itn(E,j)?p=j:Itn(j,E)&&(p=E),m=e,(y=BB(RX(n.a,p),10))&&(m=y.e),hon(uWn(n,u,p,m),(hWn(),Fft),Lxn(n,u,t,e)));if(l=GC(ZAn(c,sgt))===GC((ufn(),pIt)))for(r=new AL((!c.a&&(c.a=new eU(UOt,c,10,11)),c.a));r.e!=r.i.gc();)T=!P8(i=BB(kpn(r),33),(sWn(),eSt))||m_(SD(ZAn(i,eSt)),w1n),k=GC(ZAn(i,sgt))===GC(pIt),T&&k&&r5(a,i,a.c.b,a.c)}}function aWn(n,t,e,i,r,c){var a,u,o,s,h,f,l;switch(t){case 71:a=i.q.getFullYear()-sQn>=-1900?1:0,oO(n,e>=4?Pun(Gk(Qtt,1),sVn,2,6,[fQn,lQn])[a]:Pun(Gk(Qtt,1),sVn,2,6,["BC","AD"])[a]);break;case 121:opn(n,e,i);break;case 77:X_n(n,e,i);break;case 107:Enn(n,0==(u=r.q.getHours())?24:u,e);break;case 83:RLn(n,e,r);break;case 69:o=i.q.getDay(),oO(n,5==e?Pun(Gk(Qtt,1),sVn,2,6,["S","M","T","W","T","F","S"])[o]:4==e?Pun(Gk(Qtt,1),sVn,2,6,[bQn,wQn,dQn,gQn,pQn,vQn,mQn])[o]:Pun(Gk(Qtt,1),sVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[o]);break;case 97:r.q.getHours()>=12&&r.q.getHours()<24?oO(n,Pun(Gk(Qtt,1),sVn,2,6,["AM","PM"])[1]):oO(n,Pun(Gk(Qtt,1),sVn,2,6,["AM","PM"])[0]);break;case 104:Enn(n,0==(s=r.q.getHours()%12)?12:s,e);break;case 75:Enn(n,r.q.getHours()%12,e);break;case 72:Enn(n,r.q.getHours(),e);break;case 99:h=i.q.getDay(),5==e?oO(n,Pun(Gk(Qtt,1),sVn,2,6,["S","M","T","W","T","F","S"])[h]):4==e?oO(n,Pun(Gk(Qtt,1),sVn,2,6,[bQn,wQn,dQn,gQn,pQn,vQn,mQn])[h]):3==e?oO(n,Pun(Gk(Qtt,1),sVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[h]):Enn(n,h,1);break;case 76:f=i.q.getMonth(),5==e?oO(n,Pun(Gk(Qtt,1),sVn,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[f]):4==e?oO(n,Pun(Gk(Qtt,1),sVn,2,6,[YVn,JVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn,uQn,oQn])[f]):3==e?oO(n,Pun(Gk(Qtt,1),sVn,2,6,["Jan","Feb","Mar","Apr",tQn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[f]):Enn(n,f+1,e);break;case 81:l=i.q.getMonth()/3|0,oO(n,e<4?Pun(Gk(Qtt,1),sVn,2,6,["Q1","Q2","Q3","Q4"])[l]:Pun(Gk(Qtt,1),sVn,2,6,["1st quarter","2nd quarter","3rd quarter","4th quarter"])[l]);break;case 100:Enn(n,i.q.getDate(),e);break;case 109:Enn(n,r.q.getMinutes(),e);break;case 115:Enn(n,r.q.getSeconds(),e);break;case 122:oO(n,e<4?c.c[0]:c.c[1]);break;case 118:oO(n,c.b);break;case 90:oO(n,e<3?nCn(c):3==e?wCn(c):dCn(c.a));break;default:return!1}return!0}function uWn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(t_n(t),o=BB(Wtn((!t.b&&(t.b=new h_(_Ot,t,4,7)),t.b),0),82),h=BB(Wtn((!t.c&&(t.c=new h_(_Ot,t,5,8)),t.c),0),82),u=PTn(o),s=PTn(h),a=0==(!t.a&&(t.a=new eU(FOt,t,6,6)),t.a).i?null:BB(Wtn((!t.a&&(t.a=new eU(FOt,t,6,6)),t.a),0),202),j=BB(RX(n.a,u),10),S=BB(RX(n.a,s),10),E=null,P=null,cL(o,186)&&(cL(k=BB(RX(n.a,o),299),11)?E=BB(k,11):cL(k,10)&&(j=BB(k,10),E=BB(xq(j.j,0),11))),cL(h,186)&&(cL(M=BB(RX(n.a,h),299),11)?P=BB(M,11):cL(M,10)&&(S=BB(M,10),P=BB(xq(S.j,0),11))),!j||!S)throw Hp(new ck("The source or the target of edge "+t+" could not be found. This usually happens when an edge connects a node laid out by ELK Layered to a node in another level of hierarchy laid out by either another instance of ELK Layered or another layout algorithm alltogether. The former can be solved by setting the hierarchyHandling option to INCLUDE_CHILDREN."));for(qan(d=new wY,t),hon(d,(hWn(),dlt),t),hon(d,(HXn(),vgt),null),b=BB(mMn(i,Zft),21),j==S&&b.Fc((bDn(),vft)),E||(ain(),y=qvt,T=null,a&&vA(BB(mMn(j,ept),98))&&(Y3(T=new xI(a.j,a.k),XJ(t)),t5(T,e),Itn(s,u)&&(y=Hvt,UR(T,j.n))),E=dHn(j,T,y,i)),P||(ain(),y=Hvt,I=null,a&&vA(BB(mMn(S,ept),98))&&(Y3(I=new xI(a.b,a.c),XJ(t)),t5(I,e)),P=dHn(S,I,y,vW(S))),SZ(d,E),MZ(d,P),(E.e.c.length>1||E.g.c.length>1||P.e.c.length>1||P.g.c.length>1)&&b.Fc((bDn(),bft)),l=new AL((!t.n&&(t.n=new eU(zOt,t,1,7)),t.n));l.e!=l.i.gc();)if(!qy(TD(ZAn(f=BB(kpn(l),137),Ggt)))&&f.a)switch(g=Hhn(f),WB(d.b,g),BB(mMn(g,Ydt),272).g){case 1:case 2:b.Fc((bDn(),fft));break;case 0:b.Fc((bDn(),sft)),hon(g,Ydt,(Rtn(),zPt))}if(c=BB(mMn(i,qdt),314),p=BB(mMn(i,Kgt),315),r=c==(Oin(),sht)||p==(Nvn(),pvt),a&&0!=(!a.a&&(a.a=new $L(xOt,a,5)),a.a).i&&r){for(v=qSn(a),w=new km,m=spn(v,0);m.b!=m.d.c;)DH(w,new wA(BB(b3(m),8)));hon(d,glt,w)}return d}function oWn(n){n.gb||(n.gb=!0,n.b=kan(n,0),Rrn(n.b,18),_rn(n.b,19),n.a=kan(n,1),Rrn(n.a,1),_rn(n.a,2),_rn(n.a,3),_rn(n.a,4),_rn(n.a,5),n.o=kan(n,2),Rrn(n.o,8),Rrn(n.o,9),_rn(n.o,10),_rn(n.o,11),_rn(n.o,12),_rn(n.o,13),_rn(n.o,14),_rn(n.o,15),_rn(n.o,16),_rn(n.o,17),_rn(n.o,18),_rn(n.o,19),_rn(n.o,20),_rn(n.o,21),_rn(n.o,22),_rn(n.o,23),otn(n.o),otn(n.o),otn(n.o),otn(n.o),otn(n.o),otn(n.o),otn(n.o),otn(n.o),otn(n.o),otn(n.o),n.p=kan(n,3),Rrn(n.p,2),Rrn(n.p,3),Rrn(n.p,4),Rrn(n.p,5),_rn(n.p,6),_rn(n.p,7),otn(n.p),otn(n.p),n.q=kan(n,4),Rrn(n.q,8),n.v=kan(n,5),_rn(n.v,9),otn(n.v),otn(n.v),otn(n.v),n.w=kan(n,6),Rrn(n.w,2),Rrn(n.w,3),Rrn(n.w,4),_rn(n.w,5),n.B=kan(n,7),_rn(n.B,1),otn(n.B),otn(n.B),otn(n.B),n.Q=kan(n,8),_rn(n.Q,0),otn(n.Q),n.R=kan(n,9),Rrn(n.R,1),n.S=kan(n,10),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),otn(n.S),n.T=kan(n,11),_rn(n.T,10),_rn(n.T,11),_rn(n.T,12),_rn(n.T,13),_rn(n.T,14),otn(n.T),otn(n.T),n.U=kan(n,12),Rrn(n.U,2),Rrn(n.U,3),_rn(n.U,4),_rn(n.U,5),_rn(n.U,6),_rn(n.U,7),otn(n.U),n.V=kan(n,13),_rn(n.V,10),n.W=kan(n,14),Rrn(n.W,18),Rrn(n.W,19),Rrn(n.W,20),_rn(n.W,21),_rn(n.W,22),_rn(n.W,23),n.bb=kan(n,15),Rrn(n.bb,10),Rrn(n.bb,11),Rrn(n.bb,12),Rrn(n.bb,13),Rrn(n.bb,14),Rrn(n.bb,15),Rrn(n.bb,16),_rn(n.bb,17),otn(n.bb),otn(n.bb),n.eb=kan(n,16),Rrn(n.eb,2),Rrn(n.eb,3),Rrn(n.eb,4),Rrn(n.eb,5),Rrn(n.eb,6),Rrn(n.eb,7),_rn(n.eb,8),_rn(n.eb,9),n.ab=kan(n,17),Rrn(n.ab,0),Rrn(n.ab,1),n.H=kan(n,18),_rn(n.H,0),_rn(n.H,1),_rn(n.H,2),_rn(n.H,3),_rn(n.H,4),_rn(n.H,5),otn(n.H),n.db=kan(n,19),_rn(n.db,2),n.c=jan(n,20),n.d=jan(n,21),n.e=jan(n,22),n.f=jan(n,23),n.i=jan(n,24),n.g=jan(n,25),n.j=jan(n,26),n.k=jan(n,27),n.n=jan(n,28),n.r=jan(n,29),n.s=jan(n,30),n.t=jan(n,31),n.u=jan(n,32),n.fb=jan(n,33),n.A=jan(n,34),n.C=jan(n,35),n.D=jan(n,36),n.F=jan(n,37),n.G=jan(n,38),n.I=jan(n,39),n.J=jan(n,40),n.L=jan(n,41),n.M=jan(n,42),n.N=jan(n,43),n.O=jan(n,44),n.P=jan(n,45),n.X=jan(n,46),n.Y=jan(n,47),n.Z=jan(n,48),n.$=jan(n,49),n._=jan(n,50),n.cb=jan(n,51),n.K=jan(n,52))}function sWn(){var n,t;sWn=O,eSt=new up(w5n),mPt=new up(d5n),wvn(),iSt=new $O(W2n,rSt=IMt),new $p,cSt=new $O(VJn,null),aSt=new up(g5n),wEn(),fSt=EG(ZMt,Pun(Gk(qPt,1),$Vn,291,0,[VMt])),hSt=new $O(u3n,fSt),lSt=new $O(X2n,(hN(),!1)),Ffn(),bSt=new $O(J2n,wSt=BPt),Mbn(),vSt=new $O(y2n,mSt=ZPt),jSt=new $O(A4n,!1),ufn(),ESt=new $O(d2n,TSt=vIt),WSt=new WA(12),XSt=new $O(QJn,WSt),ISt=new $O(jZn,!1),CSt=new $O(m3n,!1),USt=new $O(MZn,!1),QEn(),uPt=new $O(EZn,oPt=YIt),gPt=new up(g3n),pPt=new up(pZn),vPt=new up(yZn),kPt=new up(kZn),ASt=new km,OSt=new $O(o3n,ASt),sSt=new $O(f3n,!1),MSt=new $O(l3n,!1),new up(p5n),LSt=new lm,$St=new $O(p3n,LSt),zSt=new $O(z2n,!1),new $p,yPt=new $O(v5n,1),new $O(m5n,!0),iln(0),new $O(y5n,iln(100)),new $O(k5n,!1),iln(0),new $O(j5n,iln(4e3)),iln(0),new $O(E5n,iln(400)),new $O(T5n,!1),new $O(M5n,!1),new $O(S5n,!0),new $O(P5n,!1),Fwn(),uSt=new $O(b5n,oSt=eOt),jPt=new $O(L2n,10),EPt=new $O(N2n,10),TPt=new $O(XJn,20),MPt=new $O(x2n,10),SPt=new $O(mZn,2),PPt=new $O(D2n,10),CPt=new $O(R2n,0),OPt=new $O(F2n,5),APt=new $O(_2n,1),$Pt=new $O(K2n,1),LPt=new $O(vZn,20),NPt=new $O(B2n,10),RPt=new $O(H2n,10),IPt=new up(q2n),DPt=new lA,xPt=new $O(v3n,DPt),YSt=new up(d3n),VSt=new $O(w3n,QSt=!1),xSt=new WA(5),NSt=new $O(Z2n,xSt),n$n(),t=BB(Vj(GIt),9),RSt=new Y_(t,BB(SR(t,t.length),9),0),DSt=new $O(IZn,RSt),cpn(),ZSt=new $O(e3n,nPt=BIt),ePt=new up(i3n),iPt=new up(r3n),rPt=new up(c3n),tPt=new up(a3n),n=BB(Vj(YCt),9),KSt=new Y_(n,BB(SR(n,n.length),9),0),_St=new $O(PZn,KSt),GSt=nbn((nKn(),GCt)),qSt=new $O(SZn,GSt),HSt=new xI(0,0),BSt=new $O(BZn,HSt),FSt=new $O(Y2n,!1),Rtn(),gSt=new $O(s3n,pSt=zPt),dSt=new $O(TZn,!1),new up(I5n),iln(1),new $O(C5n,null),cPt=new up(b3n),sPt=new up(h3n),kUn(),wPt=new $O(U2n,dPt=PCt),aPt=new up(G2n),lCn(),lPt=nbn(rCt),fPt=new $O(CZn,lPt),hPt=new $O(n3n,!1),bPt=new $O(t3n,!0),SSt=new $O(V2n,!1),PSt=new $O(Q2n,!1),ySt=new $O(WJn,1),nMn(),new $O(O5n,kSt=aIt),JSt=!0}function hWn(){var n,t;hWn=O,dlt=new up(OZn),Fft=new up("coordinateOrigin"),Mlt=new up("processors"),Kft=new iR("compoundNode",(hN(),!1)),elt=new iR("insideConnections",!1),glt=new up("originalBendpoints"),plt=new up("originalDummyNodePosition"),vlt=new up("originalLabelEdge"),Plt=new up("representedLabels"),zft=new up("endLabels"),Uft=new up("endLabel.origin"),ult=new iR("labelSide",(Xyn(),MIt)),blt=new iR("maxEdgeThickness",0),Ilt=new iR("reversed",!1),Slt=new up(AZn),hlt=new iR("longEdgeSource",null),flt=new iR("longEdgeTarget",null),slt=new iR("longEdgeHasLabelDummies",!1),olt=new iR("longEdgeBeforeLabelDummy",!1),Gft=new iR("edgeConstraint",(Jun(),Aht)),rlt=new up("inLayerLayoutUnit"),ilt=new iR("inLayerConstraint",(z7(),Pft)),clt=new iR("inLayerSuccessorConstraint",new Np),alt=new iR("inLayerSuccessorConstraintBetweenNonDummies",!1),Elt=new up("portDummy"),Bft=new iR("crossingHint",iln(0)),Zft=new iR("graphProperties",new Y_(t=BB(Vj(Tft),9),BB(SR(t,t.length),9),0)),Qft=new iR("externalPortSide",(kUn(),PCt)),Yft=new iR("externalPortSize",new Gj),Wft=new up("externalPortReplacedDummies"),Vft=new up("externalPortReplacedDummy"),Xft=new iR("externalPortConnections",new Y_(n=BB(Vj(FCt),9),BB(SR(n,n.length),9),0)),Tlt=new iR(dJn,0),xft=new up("barycenterAssociates"),_lt=new up("TopSideComments"),Dft=new up("BottomSideComments"),_ft=new up("CommentConnectionPort"),tlt=new iR("inputCollect",!1),klt=new iR("outputCollect",!1),qft=new iR("cyclic",!1),Hft=new up("crossHierarchyMap"),Rlt=new up("targetOffset"),new iR("splineLabelSize",new Gj),Alt=new up("spacings"),jlt=new iR("partitionConstraint",!1),Rft=new up("breakingPoint.info"),xlt=new up("splines.survivingEdge"),Nlt=new up("splines.route.start"),$lt=new up("splines.edgeChain"),ylt=new up("originalPortConstraints"),Olt=new up("selfLoopHolder"),Llt=new up("splines.nsPortY"),wlt=new up("modelOrder"),llt=new up("longEdgeTargetNode"),Jft=new iR(z1n,!1),Clt=new iR(z1n,!1),nlt=new up("layerConstraints.hiddenNodes"),mlt=new up("layerConstraints.opposidePort"),Dlt=new up("targetNode.modelOrder")}function fWn(){fWn=O,Knn(),Sbt=new $O(U1n,Pbt=Sht),Gbt=new $O(X1n,(hN(),!1)),z2(),Vbt=new $O(W1n,Qbt=Aft),wwt=new $O(V1n,!1),dwt=new $O(Q1n,!0),Ult=new $O(Y1n,!1),U7(),Nwt=new $O(J1n,xwt=_vt),iln(1),qwt=new $O(Z1n,iln(7)),Gwt=new $O(n0n,!1),zbt=new $O(t0n,!1),Vvn(),Tbt=new $O(e0n,Mbt=yht),TTn(),lwt=new $O(i0n,bwt=tvt),Tbn(),ewt=new $O(r0n,iwt=qlt),iln(-1),twt=new $O(c0n,iln(-1)),iln(-1),rwt=new $O(a0n,iln(-1)),iln(-1),cwt=new $O(u0n,iln(4)),iln(-1),uwt=new $O(o0n,iln(2)),sNn(),hwt=new $O(s0n,fwt=Cvt),iln(0),swt=new $O(h0n,iln(0)),Zbt=new $O(f0n,iln(DWn)),Oin(),jbt=new $O(l0n,Ebt=hht),ubt=new $O(b0n,!1),gbt=new $O(w0n,.1),ybt=new $O(d0n,!1),iln(-1),vbt=new $O(g0n,iln(-1)),iln(-1),mbt=new $O(p0n,iln(-1)),iln(0),obt=new $O(v0n,iln(40)),_an(),bbt=new $O(m0n,wbt=Eft),sbt=new $O(y0n,hbt=kft),Nvn(),$wt=new $O(k0n,Lwt=gvt),jwt=new up(j0n),g7(),gwt=new $O(E0n,pwt=qht),Bjn(),mwt=new $O(T0n,ywt=Qht),new $p,Mwt=new $O(M0n,.3),Pwt=new up(S0n),bvn(),Iwt=new $O(P0n,Cwt=lvt),Hcn(),Nbt=new $O(I0n,xbt=Wvt),A6(),Dbt=new $O(C0n,Rbt=Zvt),Usn(),_bt=new $O(O0n,Kbt=rmt),Bbt=new $O(A0n,.2),$bt=new $O($0n,2),Kwt=new $O(L0n,null),Bwt=new $O(N0n,10),Fwt=new $O(x0n,10),Hwt=new $O(D0n,20),iln(0),Dwt=new $O(R0n,iln(0)),iln(0),Rwt=new $O(_0n,iln(0)),iln(0),_wt=new $O(K0n,iln(0)),Xlt=new $O(F0n,!1),JMn(),Qlt=new $O(B0n,Ylt=cft),V8(),Wlt=new $O(H0n,Vlt=aht),Xbt=new $O(q0n,!1),iln(0),Ubt=new $O(G0n,iln(16)),iln(0),Wbt=new $O(z0n,iln(5)),$un(),ldt=new $O(U0n,bdt=bmt),zwt=new $O(X0n,10),Wwt=new $O(W0n,1),uin(),edt=new $O(V0n,idt=ght),Ywt=new up(Q0n),ndt=iln(1),iln(0),Zwt=new $O(Y0n,ndt),dcn(),pdt=new $O(J0n,vdt=umt),wdt=new up(Z0n),odt=new $O(n2n,!0),adt=new $O(t2n,2),hdt=new $O(e2n,!0),gSn(),Obt=new $O(i2n,Abt=Kht),$Pn(),Ibt=new $O(r2n,Cbt=Zst),mon(),cbt=new $O(c2n,abt=Nvt),rbt=new $O(a2n,!1),Bfn(),Jlt=new $O(u2n,Zlt=wut),Mhn(),ebt=new $O(o2n,ibt=cvt),nbt=new $O(s2n,0),tbt=new $O(h2n,0),Jbt=jht,Ybt=sht,awt=nvt,owt=nvt,nwt=Ypt,ufn(),pbt=pIt,kbt=hht,dbt=hht,fbt=hht,lbt=pIt,Ewt=mvt,Twt=gvt,vwt=gvt,kwt=gvt,Swt=vvt,Awt=mvt,Owt=mvt,Mbn(),Fbt=JPt,Hbt=JPt,qbt=rmt,Lbt=YPt,Uwt=wmt,Xwt=lmt,Vwt=wmt,Qwt=lmt,rdt=wmt,cdt=lmt,Jwt=dht,tdt=ght,mdt=wmt,ydt=lmt,ddt=wmt,gdt=lmt,sdt=lmt,udt=lmt,fdt=lmt}function lWn(){lWn=O,rot=new nP("DIRECTION_PREPROCESSOR",0),tot=new nP("COMMENT_PREPROCESSOR",1),cot=new nP("EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER",2),kot=new nP("INTERACTIVE_EXTERNAL_PORT_POSITIONER",3),Fot=new nP("PARTITION_PREPROCESSOR",4),Mot=new nP("LABEL_DUMMY_INSERTER",5),Uot=new nP("SELF_LOOP_PREPROCESSOR",6),Oot=new nP("LAYER_CONSTRAINT_PREPROCESSOR",7),_ot=new nP("PARTITION_MIDPROCESSOR",8),got=new nP("HIGH_DEGREE_NODE_LAYER_PROCESSOR",9),Not=new nP("NODE_PROMOTION",10),Cot=new nP("LAYER_CONSTRAINT_POSTPROCESSOR",11),Kot=new nP("PARTITION_POSTPROCESSOR",12),lot=new nP("HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR",13),Wot=new nP("SEMI_INTERACTIVE_CROSSMIN_PROCESSOR",14),Vut=new nP("BREAKING_POINT_INSERTER",15),Lot=new nP("LONG_EDGE_SPLITTER",16),Hot=new nP("PORT_SIDE_PROCESSOR",17),jot=new nP("INVERTED_PORT_PROCESSOR",18),Bot=new nP("PORT_LIST_SORTER",19),Qot=new nP("SORT_BY_INPUT_ORDER_OF_MODEL",20),Dot=new nP("NORTH_SOUTH_PORT_PREPROCESSOR",21),Qut=new nP("BREAKING_POINT_PROCESSOR",22),Rot=new nP(E1n,23),Yot=new nP(T1n,24),Got=new nP("SELF_LOOP_PORT_RESTORER",25),Vot=new nP("SINGLE_EDGE_GRAPH_WRAPPER",26),Eot=new nP("IN_LAYER_CONSTRAINT_PROCESSOR",27),sot=new nP("END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR",28),Tot=new nP("LABEL_AND_NODE_SIZE_PROCESSOR",29),yot=new nP("INNERMOST_NODE_MARGIN_CALCULATOR",30),Xot=new nP("SELF_LOOP_ROUTER",31),Zut=new nP("COMMENT_NODE_MARGIN_CALCULATOR",32),uot=new nP("END_LABEL_PREPROCESSOR",33),Pot=new nP("LABEL_DUMMY_SWITCHER",34),Jut=new nP("CENTER_LABEL_MANAGEMENT_PROCESSOR",35),Iot=new nP("LABEL_SIDE_SELECTOR",36),vot=new nP("HYPEREDGE_DUMMY_MERGER",37),bot=new nP("HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR",38),Aot=new nP("LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR",39),dot=new nP("HIERARCHICAL_PORT_POSITION_PROCESSOR",40),eot=new nP("CONSTRAINTS_POSTPROCESSOR",41),not=new nP("COMMENT_POSTPROCESSOR",42),mot=new nP("HYPERNODE_PROCESSOR",43),wot=new nP("HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER",44),$ot=new nP("LONG_EDGE_JOINER",45),zot=new nP("SELF_LOOP_POSTPROCESSOR",46),Yut=new nP("BREAKING_POINT_REMOVER",47),xot=new nP("NORTH_SOUTH_PORT_POSTPROCESSOR",48),pot=new nP("HORIZONTAL_COMPACTOR",49),Sot=new nP("LABEL_DUMMY_REMOVER",50),hot=new nP("FINAL_SPLINE_BENDPOINTS_CALCULATOR",51),oot=new nP("END_LABEL_SORTER",52),qot=new nP("REVERSED_EDGE_RESTORER",53),aot=new nP("END_LABEL_POSTPROCESSOR",54),fot=new nP("HIERARCHICAL_NODE_RESIZER",55),iot=new nP("DIRECTION_POSTPROCESSOR",56)}function bWn(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A,$,L,N,x,D,R,_,K,F,B,H,q,G,z,U,X,W,V,Q,Y,J,Z,nn,tn,en,rn,cn,an,un,on;for(J=0,L=0,D=(O=t).length;L<D;++L)for(G=new Wb((I=O[L]).j);G.a<G.c.c.length;){for(U=0,o=new Wb((q=BB(n0(G),11)).g);o.a<o.c.c.length;)u=BB(n0(o),17),I.c!=u.d.i.c&&++U;U>0&&(n.a[q.p]=J++)}for(rn=0,N=0,R=(A=i).length;N<R;++N){for(_=0,G=new Wb((I=A[N]).j);G.a<G.c.c.length&&(q=BB(n0(G),11)).j==(kUn(),sCt);)for(o=new Wb(q.e);o.a<o.c.c.length;)if(u=BB(n0(o),17),I.c!=u.c.i.c){++_;break}for(F=0,X=new M2(I.j,I.j.c.length);X.b>0;){for(Px(X.b>0),U=0,o=new Wb((q=BB(X.a.Xb(X.c=--X.b),11)).e);o.a<o.c.c.length;)u=BB(n0(o),17),I.c!=u.c.i.c&&++U;U>0&&(q.j==(kUn(),sCt)?(n.a[q.p]=rn,++rn):(n.a[q.p]=rn+_+F,++F))}rn+=F}for(z=new xp,d=new fA,$=0,x=(C=t).length;$<x;++$)for(tn=new Wb((I=C[$]).j);tn.a<tn.c.c.length;)for(o=new Wb((nn=BB(n0(tn),11)).g);o.a<o.c.c.length;)if(an=(u=BB(n0(o),17)).d,I.c!=an.i.c)if(Z=BB(qC(AY(z.f,nn)),467),cn=BB(qC(AY(z.f,an)),467),Z||cn)if(Z)if(cn)if(Z==cn)WB(Z.a,u);else{for(WB(Z.a,u),H=new Wb(cn.d);H.a<H.c.c.length;)B=BB(n0(H),11),jIn(z.f,B,Z);gun(Z.a,cn.a),gun(Z.d,cn.d),d.a.Bc(cn)}else WB(Z.a,u),WB(Z.d,an),jIn(z.f,an,Z);else WB(cn.a,u),WB(cn.d,nn),jIn(z.f,nn,cn);else w=new DR,d.a.zc(w,d),WB(w.a,u),WB(w.d,nn),jIn(z.f,nn,w),WB(w.d,an),jIn(z.f,an,w);for(g=BB(Emn(d,x8(Fmt,{3:1,4:1,5:1,1946:1},467,d.a.gc(),0,1)),1946),P=t[0].c,Y=i[0].c,l=0,b=(f=g).length;l<b;++l)for((h=f[l]).e=J,h.f=rn,G=new Wb(h.d);G.a<G.c.c.length;)q=BB(n0(G),11),W=n.a[q.p],q.i.c==P?(W<h.e&&(h.e=W),W>h.b&&(h.b=W)):q.i.c==Y&&(W<h.f&&(h.f=W),W>h.c&&(h.c=W));for(z9(g,0,g.length,null),en=x8(ANt,hQn,25,g.length,15,1),r=x8(ANt,hQn,25,rn+1,15,1),v=0;v<g.length;v++)en[v]=g[v].f,r[en[v]]=1;for(a=0,m=0;m<r.length;m++)1==r[m]?r[m]=a:--a;for(V=0,y=0;y<en.length;y++)en[y]+=r[en[y]],V=e.Math.max(V,en[y]+1);for(s=1;s<V;)s*=2;for(on=2*s-1,s-=1,un=x8(ANt,hQn,25,on,15,1),c=0,M=0;M<en.length;M++)for(++un[T=en[M]+s];T>0;)T%2>0&&(c+=un[T+1]),++un[T=(T-1)/2|0];for(S=x8(qmt,HWn,362,2*g.length,0,1),k=0;k<g.length;k++)S[2*k]=new qV(g[k],g[k].e,g[k].b,(Q4(),Hmt)),S[2*k+1]=new qV(g[k],g[k].b,g[k].e,Bmt);for(z9(S,0,S.length,null),K=0,j=0;j<S.length;j++)switch(S[j].d.g){case 0:++K;break;case 1:c+=--K}for(Q=x8(qmt,HWn,362,2*g.length,0,1),E=0;E<g.length;E++)Q[2*E]=new qV(g[E],g[E].f,g[E].c,(Q4(),Hmt)),Q[2*E+1]=new qV(g[E],g[E].c,g[E].f,Bmt);for(z9(Q,0,Q.length,null),K=0,p=0;p<Q.length;p++)switch(Q[p].d.g){case 0:++K;break;case 1:c+=--K}return c}function wWn(){wWn=O,sNt=new Ap(7),hNt=new oG(8,94),new oG(8,64),fNt=new oG(8,36),pNt=new oG(8,65),vNt=new oG(8,122),mNt=new oG(8,90),jNt=new oG(8,98),dNt=new oG(8,66),yNt=new oG(8,60),ENt=new oG(8,62),oNt=new Ap(11),Yxn(uNt=new M0(4),48,57),Yxn(kNt=new M0(4),48,57),Yxn(kNt,65,90),Yxn(kNt,95,95),Yxn(kNt,97,122),Yxn(gNt=new M0(4),9,9),Yxn(gNt,10,10),Yxn(gNt,12,12),Yxn(gNt,13,13),Yxn(gNt,32,32),lNt=$Fn(uNt),wNt=$Fn(kNt),bNt=$Fn(gNt),iNt=new xp,rNt=new xp,cNt=Pun(Gk(Qtt,1),sVn,2,6,["Cn","Lu","Ll","Lt","Lm","Lo","Mn","Me","Mc","Nd","Nl","No","Zs","Zl","Zp","Cc","Cf",null,"Co","Cs","Pd","Ps","Pe","Pc","Po","Sm","Sc","Sk","So","Pi","Pf","L","M","N","Z","C","P","S"]),eNt=Pun(Gk(Qtt,1),sVn,2,6,["Basic Latin","Latin-1 Supplement","Latin Extended-A","Latin Extended-B","IPA Extensions","Spacing Modifier Letters","Combining Diacritical Marks","Greek","Cyrillic","Armenian","Hebrew","Arabic","Syriac","Thaana","Devanagari","Bengali","Gurmukhi","Gujarati","Oriya","Tamil","Telugu","Kannada","Malayalam","Sinhala","Thai","Lao","Tibetan","Myanmar","Georgian","Hangul Jamo","Ethiopic","Cherokee","Unified Canadian Aboriginal Syllabics","Ogham","Runic","Khmer","Mongolian","Latin Extended Additional","Greek Extended","General Punctuation","Superscripts and Subscripts","Currency Symbols","Combining Marks for Symbols","Letterlike Symbols","Number Forms","Arrows","Mathematical Operators","Miscellaneous Technical","Control Pictures","Optical Character Recognition","Enclosed Alphanumerics","Box Drawing","Block Elements","Geometric Shapes","Miscellaneous Symbols","Dingbats","Braille Patterns","CJK Radicals Supplement","Kangxi Radicals","Ideographic Description Characters","CJK Symbols and Punctuation","Hiragana","Katakana","Bopomofo","Hangul Compatibility Jamo","Kanbun","Bopomofo Extended","Enclosed CJK Letters and Months","CJK Compatibility","CJK Unified Ideographs Extension A","CJK Unified Ideographs","Yi Syllables","Yi Radicals","Hangul Syllables",gnt,"CJK Compatibility Ideographs","Alphabetic Presentation Forms","Arabic Presentation Forms-A","Combining Half Marks","CJK Compatibility Forms","Small Form Variants","Arabic Presentation Forms-B","Specials","Halfwidth and Fullwidth Forms","Old Italic","Gothic","Deseret","Byzantine Musical Symbols","Musical Symbols","Mathematical Alphanumeric Symbols","CJK Unified Ideographs Extension B","CJK Compatibility Ideographs Supplement","Tags"]),aNt=Pun(Gk(ANt,1),hQn,25,15,[66304,66351,66352,66383,66560,66639,118784,119039,119040,119295,119808,120831,131072,173782,194560,195103,917504,917631])}function dWn(){dWn=O,Prt=new ocn("OUT_T_L",0,(J9(),Yit),(G7(),irt),(Dtn(),Git),Git,Pun(Gk(Dnt,1),HWn,21,0,[EG((n$n(),LIt),Pun(Gk(GIt,1),$Vn,93,0,[DIt,CIt]))])),Srt=new ocn("OUT_T_C",1,Qit,irt,Git,zit,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[DIt,IIt])),EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[DIt,IIt,OIt]))])),Irt=new ocn("OUT_T_R",2,Jit,irt,Git,Uit,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[DIt,AIt]))])),vrt=new ocn("OUT_B_L",3,Yit,crt,Uit,Git,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[NIt,CIt]))])),prt=new ocn("OUT_B_C",4,Qit,crt,Uit,zit,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[NIt,IIt])),EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[NIt,IIt,OIt]))])),mrt=new ocn("OUT_B_R",5,Jit,crt,Uit,Uit,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[NIt,AIt]))])),jrt=new ocn("OUT_L_T",6,Jit,crt,Git,Git,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[CIt,DIt,OIt]))])),krt=new ocn("OUT_L_C",7,Jit,rrt,zit,Git,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[CIt,xIt])),EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[CIt,xIt,OIt]))])),yrt=new ocn("OUT_L_B",8,Jit,irt,Uit,Git,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[CIt,NIt,OIt]))])),Mrt=new ocn("OUT_R_T",9,Yit,crt,Git,Uit,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[AIt,DIt,OIt]))])),Trt=new ocn("OUT_R_C",10,Yit,rrt,zit,Uit,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[AIt,xIt])),EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[AIt,xIt,OIt]))])),Ert=new ocn("OUT_R_B",11,Yit,irt,Uit,Uit,Pun(Gk(Dnt,1),HWn,21,0,[EG(LIt,Pun(Gk(GIt,1),$Vn,93,0,[AIt,NIt,OIt]))])),drt=new ocn("IN_T_L",12,Yit,crt,Git,Git,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[DIt,CIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[DIt,CIt,OIt]))])),wrt=new ocn("IN_T_C",13,Qit,crt,Git,zit,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[DIt,IIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[DIt,IIt,OIt]))])),grt=new ocn("IN_T_R",14,Jit,crt,Git,Uit,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[DIt,AIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[DIt,AIt,OIt]))])),lrt=new ocn("IN_C_L",15,Yit,rrt,zit,Git,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[xIt,CIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[xIt,CIt,OIt]))])),frt=new ocn("IN_C_C",16,Qit,rrt,zit,zit,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[xIt,IIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[xIt,IIt,OIt]))])),brt=new ocn("IN_C_R",17,Jit,rrt,zit,Uit,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[xIt,AIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[xIt,AIt,OIt]))])),srt=new ocn("IN_B_L",18,Yit,irt,Uit,Git,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[NIt,CIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[NIt,CIt,OIt]))])),ort=new ocn("IN_B_C",19,Qit,irt,Uit,zit,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[NIt,IIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[NIt,IIt,OIt]))])),hrt=new ocn("IN_B_R",20,Jit,irt,Uit,Uit,Pun(Gk(Dnt,1),HWn,21,0,[EG($It,Pun(Gk(GIt,1),$Vn,93,0,[NIt,AIt])),EG($It,Pun(Gk(GIt,1),$Vn,93,0,[NIt,AIt,OIt]))])),Crt=new ocn(hJn,21,null,null,null,null,Pun(Gk(Dnt,1),HWn,21,0,[]))}function gWn(){gWn=O,i$t=(QX(),t$t).b,BB(Wtn(QQ(t$t.b),0),34),BB(Wtn(QQ(t$t.b),1),18),e$t=t$t.a,BB(Wtn(QQ(t$t.a),0),34),BB(Wtn(QQ(t$t.a),1),18),BB(Wtn(QQ(t$t.a),2),18),BB(Wtn(QQ(t$t.a),3),18),BB(Wtn(QQ(t$t.a),4),18),r$t=t$t.o,BB(Wtn(QQ(t$t.o),0),34),BB(Wtn(QQ(t$t.o),1),34),a$t=BB(Wtn(QQ(t$t.o),2),18),BB(Wtn(QQ(t$t.o),3),18),BB(Wtn(QQ(t$t.o),4),18),BB(Wtn(QQ(t$t.o),5),18),BB(Wtn(QQ(t$t.o),6),18),BB(Wtn(QQ(t$t.o),7),18),BB(Wtn(QQ(t$t.o),8),18),BB(Wtn(QQ(t$t.o),9),18),BB(Wtn(QQ(t$t.o),10),18),BB(Wtn(QQ(t$t.o),11),18),BB(Wtn(QQ(t$t.o),12),18),BB(Wtn(QQ(t$t.o),13),18),BB(Wtn(QQ(t$t.o),14),18),BB(Wtn(QQ(t$t.o),15),18),BB(Wtn(VQ(t$t.o),0),59),BB(Wtn(VQ(t$t.o),1),59),BB(Wtn(VQ(t$t.o),2),59),BB(Wtn(VQ(t$t.o),3),59),BB(Wtn(VQ(t$t.o),4),59),BB(Wtn(VQ(t$t.o),5),59),BB(Wtn(VQ(t$t.o),6),59),BB(Wtn(VQ(t$t.o),7),59),BB(Wtn(VQ(t$t.o),8),59),BB(Wtn(VQ(t$t.o),9),59),c$t=t$t.p,BB(Wtn(QQ(t$t.p),0),34),BB(Wtn(QQ(t$t.p),1),34),BB(Wtn(QQ(t$t.p),2),34),BB(Wtn(QQ(t$t.p),3),34),BB(Wtn(QQ(t$t.p),4),18),BB(Wtn(QQ(t$t.p),5),18),BB(Wtn(VQ(t$t.p),0),59),BB(Wtn(VQ(t$t.p),1),59),u$t=t$t.q,BB(Wtn(QQ(t$t.q),0),34),o$t=t$t.v,BB(Wtn(QQ(t$t.v),0),18),BB(Wtn(VQ(t$t.v),0),59),BB(Wtn(VQ(t$t.v),1),59),BB(Wtn(VQ(t$t.v),2),59),s$t=t$t.w,BB(Wtn(QQ(t$t.w),0),34),BB(Wtn(QQ(t$t.w),1),34),BB(Wtn(QQ(t$t.w),2),34),BB(Wtn(QQ(t$t.w),3),18),h$t=t$t.B,BB(Wtn(QQ(t$t.B),0),18),BB(Wtn(VQ(t$t.B),0),59),BB(Wtn(VQ(t$t.B),1),59),BB(Wtn(VQ(t$t.B),2),59),b$t=t$t.Q,BB(Wtn(QQ(t$t.Q),0),18),BB(Wtn(VQ(t$t.Q),0),59),w$t=t$t.R,BB(Wtn(QQ(t$t.R),0),34),d$t=t$t.S,BB(Wtn(VQ(t$t.S),0),59),BB(Wtn(VQ(t$t.S),1),59),BB(Wtn(VQ(t$t.S),2),59),BB(Wtn(VQ(t$t.S),3),59),BB(Wtn(VQ(t$t.S),4),59),BB(Wtn(VQ(t$t.S),5),59),BB(Wtn(VQ(t$t.S),6),59),BB(Wtn(VQ(t$t.S),7),59),BB(Wtn(VQ(t$t.S),8),59),BB(Wtn(VQ(t$t.S),9),59),BB(Wtn(VQ(t$t.S),10),59),BB(Wtn(VQ(t$t.S),11),59),BB(Wtn(VQ(t$t.S),12),59),BB(Wtn(VQ(t$t.S),13),59),BB(Wtn(VQ(t$t.S),14),59),g$t=t$t.T,BB(Wtn(QQ(t$t.T),0),18),BB(Wtn(QQ(t$t.T),2),18),p$t=BB(Wtn(QQ(t$t.T),3),18),BB(Wtn(QQ(t$t.T),4),18),BB(Wtn(VQ(t$t.T),0),59),BB(Wtn(VQ(t$t.T),1),59),BB(Wtn(QQ(t$t.T),1),18),v$t=t$t.U,BB(Wtn(QQ(t$t.U),0),34),BB(Wtn(QQ(t$t.U),1),34),BB(Wtn(QQ(t$t.U),2),18),BB(Wtn(QQ(t$t.U),3),18),BB(Wtn(QQ(t$t.U),4),18),BB(Wtn(QQ(t$t.U),5),18),BB(Wtn(VQ(t$t.U),0),59),m$t=t$t.V,BB(Wtn(QQ(t$t.V),0),18),y$t=t$t.W,BB(Wtn(QQ(t$t.W),0),34),BB(Wtn(QQ(t$t.W),1),34),BB(Wtn(QQ(t$t.W),2),34),BB(Wtn(QQ(t$t.W),3),18),BB(Wtn(QQ(t$t.W),4),18),BB(Wtn(QQ(t$t.W),5),18),j$t=t$t.bb,BB(Wtn(QQ(t$t.bb),0),34),BB(Wtn(QQ(t$t.bb),1),34),BB(Wtn(QQ(t$t.bb),2),34),BB(Wtn(QQ(t$t.bb),3),34),BB(Wtn(QQ(t$t.bb),4),34),BB(Wtn(QQ(t$t.bb),5),34),BB(Wtn(QQ(t$t.bb),6),34),BB(Wtn(QQ(t$t.bb),7),18),BB(Wtn(VQ(t$t.bb),0),59),BB(Wtn(VQ(t$t.bb),1),59),E$t=t$t.eb,BB(Wtn(QQ(t$t.eb),0),34),BB(Wtn(QQ(t$t.eb),1),34),BB(Wtn(QQ(t$t.eb),2),34),BB(Wtn(QQ(t$t.eb),3),34),BB(Wtn(QQ(t$t.eb),4),34),BB(Wtn(QQ(t$t.eb),5),34),BB(Wtn(QQ(t$t.eb),6),18),BB(Wtn(QQ(t$t.eb),7),18),k$t=t$t.ab,BB(Wtn(QQ(t$t.ab),0),34),BB(Wtn(QQ(t$t.ab),1),34),f$t=t$t.H,BB(Wtn(QQ(t$t.H),0),18),BB(Wtn(QQ(t$t.H),1),18),BB(Wtn(QQ(t$t.H),2),18),BB(Wtn(QQ(t$t.H),3),18),BB(Wtn(QQ(t$t.H),4),18),BB(Wtn(QQ(t$t.H),5),18),BB(Wtn(VQ(t$t.H),0),59),T$t=t$t.db,BB(Wtn(QQ(t$t.db),0),18),l$t=t$t.M}function pWn(n){var t;n.O||(n.O=!0,Nrn(n,"type"),xrn(n,"ecore.xml.type"),Drn(n,S7n),t=BB($$n((WM(),zAt),S7n),1945),f9(kY(n.fb),n.b),z0(n.b,wLt,"AnyType",!1,!1,!0),ucn(BB(Wtn(QQ(n.b),0),34),n.wb.D,_9n,null,0,-1,wLt,!1,!1,!0,!1,!1,!1),ucn(BB(Wtn(QQ(n.b),1),34),n.wb.D,"any",null,0,-1,wLt,!0,!0,!0,!1,!1,!0),ucn(BB(Wtn(QQ(n.b),2),34),n.wb.D,"anyAttribute",null,0,-1,wLt,!1,!1,!0,!1,!1,!1),z0(n.bb,zLt,A7n,!1,!1,!0),ucn(BB(Wtn(QQ(n.bb),0),34),n.gb,"data",null,0,1,zLt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.bb),1),34),n.gb,Y6n,null,1,1,zLt,!1,!1,!0,!1,!0,!1),z0(n.fb,ULt,$7n,!1,!1,!0),ucn(BB(Wtn(QQ(n.fb),0),34),t.gb,"rawValue",null,0,1,ULt,!0,!0,!0,!1,!0,!0),ucn(BB(Wtn(QQ(n.fb),1),34),t.a,E6n,null,0,1,ULt,!0,!0,!0,!1,!0,!0),Myn(BB(Wtn(QQ(n.fb),2),18),n.wb.q,null,"instanceType",1,1,ULt,!1,!1,!0,!1,!1,!1,!1),z0(n.qb,XLt,L7n,!1,!1,!0),ucn(BB(Wtn(QQ(n.qb),0),34),n.wb.D,_9n,null,0,-1,null,!1,!1,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.qb),1),18),n.wb.ab,null,"xMLNSPrefixMap",0,-1,null,!0,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.qb),2),18),n.wb.ab,null,"xSISchemaLocation",0,-1,null,!0,!1,!0,!0,!1,!1,!1),ucn(BB(Wtn(QQ(n.qb),3),34),n.gb,"cDATA",null,0,-2,null,!0,!0,!0,!1,!1,!0),ucn(BB(Wtn(QQ(n.qb),4),34),n.gb,"comment",null,0,-2,null,!0,!0,!0,!1,!1,!0),Myn(BB(Wtn(QQ(n.qb),5),18),n.bb,null,cnt,0,-2,null,!0,!0,!0,!0,!1,!1,!0),ucn(BB(Wtn(QQ(n.qb),6),34),n.gb,O6n,null,0,-2,null,!0,!0,!0,!1,!1,!0),dV(n.a,Ant,"AnySimpleType",!0),dV(n.c,Qtt,"AnyURI",!0),dV(n.d,Gk(NNt,1),"Base64Binary",!0),dV(n.e,$Nt,"Boolean",!0),dV(n.f,ktt,"BooleanObject",!0),dV(n.g,NNt,"Byte",!0),dV(n.i,Ttt,"ByteObject",!0),dV(n.j,Qtt,"Date",!0),dV(n.k,Qtt,"DateTime",!0),dV(n.n,iet,"Decimal",!0),dV(n.o,xNt,"Double",!0),dV(n.p,Ptt,"DoubleObject",!0),dV(n.q,Qtt,"Duration",!0),dV(n.s,Rnt,"ENTITIES",!0),dV(n.r,Rnt,"ENTITIESBase",!0),dV(n.t,Qtt,K7n,!0),dV(n.u,DNt,"Float",!0),dV(n.v,Itt,"FloatObject",!0),dV(n.w,Qtt,"GDay",!0),dV(n.B,Qtt,"GMonth",!0),dV(n.A,Qtt,"GMonthDay",!0),dV(n.C,Qtt,"GYear",!0),dV(n.D,Qtt,"GYearMonth",!0),dV(n.F,Gk(NNt,1),"HexBinary",!0),dV(n.G,Qtt,"ID",!0),dV(n.H,Qtt,"IDREF",!0),dV(n.J,Rnt,"IDREFS",!0),dV(n.I,Rnt,"IDREFSBase",!0),dV(n.K,ANt,"Int",!0),dV(n.M,oet,"Integer",!0),dV(n.L,Att,"IntObject",!0),dV(n.P,Qtt,"Language",!0),dV(n.Q,LNt,"Long",!0),dV(n.R,Rtt,"LongObject",!0),dV(n.S,Qtt,"Name",!0),dV(n.T,Qtt,F7n,!0),dV(n.U,oet,"NegativeInteger",!0),dV(n.V,Qtt,Q7n,!0),dV(n.X,Rnt,"NMTOKENS",!0),dV(n.W,Rnt,"NMTOKENSBase",!0),dV(n.Y,oet,"NonNegativeInteger",!0),dV(n.Z,oet,"NonPositiveInteger",!0),dV(n.$,Qtt,"NormalizedString",!0),dV(n._,Qtt,"NOTATION",!0),dV(n.ab,Qtt,"PositiveInteger",!0),dV(n.cb,Qtt,"QName",!0),dV(n.db,RNt,"Short",!0),dV(n.eb,Ktt,"ShortObject",!0),dV(n.gb,Qtt,qVn,!0),dV(n.hb,Qtt,"Time",!0),dV(n.ib,Qtt,"Token",!0),dV(n.jb,RNt,"UnsignedByte",!0),dV(n.kb,Ktt,"UnsignedByteObject",!0),dV(n.lb,LNt,"UnsignedInt",!0),dV(n.mb,Rtt,"UnsignedIntObject",!0),dV(n.nb,oet,"UnsignedLong",!0),dV(n.ob,ANt,"UnsignedShort",!0),dV(n.pb,Att,"UnsignedShortObject",!0),Lhn(n,S7n),yWn(n))}function vWn(n){NM(n,new MTn(mj(dj(vj(wj(pj(gj(new du,w1n),"ELK Layered"),"Layer-based algorithm provided by the Eclipse Layout Kernel. Arranges as many edges as possible into one direction by placing nodes into subsequent layers. This implementation supports different routing styles (straight, orthogonal, splines); if orthogonal routing is selected, arbitrary port constraints are respected, thus enabling the layout of block diagrams such as actor-oriented models or circuit schematics. Furthermore, full layout of compound graphs with cross-hierarchy edges is supported when the respective option is activated on the top level."),new Ic),w1n),EG((hAn(),iAt),Pun(Gk(aAt,1),$Vn,237,0,[nAt,tAt,ZOt,eAt,YOt,QOt]))))),u2(n,w1n,L2n,mpn(ppt)),u2(n,w1n,N2n,mpn(vpt)),u2(n,w1n,XJn,mpn(mpt)),u2(n,w1n,x2n,mpn(ypt)),u2(n,w1n,mZn,mpn(jpt)),u2(n,w1n,D2n,mpn(Ept)),u2(n,w1n,R2n,mpn(Spt)),u2(n,w1n,_2n,mpn(Ipt)),u2(n,w1n,K2n,mpn(Cpt)),u2(n,w1n,F2n,mpn(Ppt)),u2(n,w1n,vZn,mpn(Opt)),u2(n,w1n,B2n,mpn($pt)),u2(n,w1n,H2n,mpn(Npt)),u2(n,w1n,q2n,mpn(Mpt)),u2(n,w1n,L0n,mpn(gpt)),u2(n,w1n,x0n,mpn(kpt)),u2(n,w1n,N0n,mpn(Tpt)),u2(n,w1n,D0n,mpn(Apt)),u2(n,w1n,pZn,iln(0)),u2(n,w1n,R0n,mpn(fpt)),u2(n,w1n,_0n,mpn(lpt)),u2(n,w1n,K0n,mpn(bpt)),u2(n,w1n,U0n,mpn(zpt)),u2(n,w1n,X0n,mpn(Rpt)),u2(n,w1n,W0n,mpn(_pt)),u2(n,w1n,V0n,mpn(Bpt)),u2(n,w1n,Q0n,mpn(Kpt)),u2(n,w1n,Y0n,mpn(Fpt)),u2(n,w1n,J0n,mpn(Xpt)),u2(n,w1n,Z0n,mpn(Upt)),u2(n,w1n,n2n,mpn(qpt)),u2(n,w1n,t2n,mpn(Hpt)),u2(n,w1n,e2n,mpn(Gpt)),u2(n,w1n,S0n,mpn(Rgt)),u2(n,w1n,P0n,mpn(_gt)),u2(n,w1n,O0n,mpn(rgt)),u2(n,w1n,A0n,mpn(cgt)),u2(n,w1n,QJn,Ugt),u2(n,w1n,y2n,ngt),u2(n,w1n,G2n,0),u2(n,w1n,yZn,iln(1)),u2(n,w1n,VJn,dZn),u2(n,w1n,z2n,mpn(Ggt)),u2(n,w1n,EZn,mpn(ept)),u2(n,w1n,U2n,mpn(upt)),u2(n,w1n,X2n,mpn(zdt)),u2(n,w1n,W2n,mpn(kdt)),u2(n,w1n,d2n,mpn(sgt)),u2(n,w1n,kZn,(hN(),!0)),u2(n,w1n,V2n,mpn(wgt)),u2(n,w1n,Q2n,mpn(dgt)),u2(n,w1n,PZn,mpn(Fgt)),u2(n,w1n,SZn,mpn(qgt)),u2(n,w1n,Y2n,mpn(Bgt)),u2(n,w1n,J2n,Wdt),u2(n,w1n,IZn,mpn($gt)),u2(n,w1n,Z2n,mpn(Agt)),u2(n,w1n,CZn,mpn(cpt)),u2(n,w1n,n3n,mpn(rpt)),u2(n,w1n,t3n,mpn(apt)),u2(n,w1n,e3n,Vgt),u2(n,w1n,i3n,mpn(Ygt)),u2(n,w1n,r3n,mpn(Jgt)),u2(n,w1n,c3n,mpn(Zgt)),u2(n,w1n,a3n,mpn(Qgt)),u2(n,w1n,n0n,mpn(Dpt)),u2(n,w1n,i0n,mpn(Pgt)),u2(n,w1n,s0n,mpn(Sgt)),u2(n,w1n,Z1n,mpn(xpt)),u2(n,w1n,r0n,mpn(kgt)),u2(n,w1n,e0n,mpn(Gdt)),u2(n,w1n,l0n,mpn(qdt)),u2(n,w1n,b0n,mpn(xdt)),u2(n,w1n,v0n,mpn(Ddt)),u2(n,w1n,m0n,mpn(_dt)),u2(n,w1n,y0n,mpn(Rdt)),u2(n,w1n,d0n,mpn(Hdt)),u2(n,w1n,V1n,mpn(Cgt)),u2(n,w1n,Q1n,mpn(Ogt)),u2(n,w1n,W1n,mpn(pgt)),u2(n,w1n,k0n,mpn(Kgt)),u2(n,w1n,T0n,mpn(Ngt)),u2(n,w1n,X1n,mpn(ugt)),u2(n,w1n,M0n,mpn(Dgt)),u2(n,w1n,I0n,mpn(egt)),u2(n,w1n,C0n,mpn(igt)),u2(n,w1n,u3n,mpn(Ndt)),u2(n,w1n,E0n,mpn(Lgt)),u2(n,w1n,B0n,mpn(Pdt)),u2(n,w1n,H0n,mpn(Sdt)),u2(n,w1n,F0n,mpn(Mdt)),u2(n,w1n,q0n,mpn(fgt)),u2(n,w1n,G0n,mpn(hgt)),u2(n,w1n,z0n,mpn(lgt)),u2(n,w1n,BZn,mpn(Hgt)),u2(n,w1n,o3n,mpn(vgt)),u2(n,w1n,WJn,mpn(agt)),u2(n,w1n,s3n,mpn(Ydt)),u2(n,w1n,TZn,mpn(Qdt)),u2(n,w1n,w0n,mpn(Kdt)),u2(n,w1n,h3n,mpn(ipt)),u2(n,w1n,f3n,mpn(Tdt)),u2(n,w1n,l3n,mpn(bgt)),u2(n,w1n,b3n,mpn(npt)),u2(n,w1n,w3n,mpn(Xgt)),u2(n,w1n,d3n,mpn(Wgt)),u2(n,w1n,u0n,mpn(Egt)),u2(n,w1n,o0n,mpn(Tgt)),u2(n,w1n,g3n,mpn(spt)),u2(n,w1n,Y1n,mpn(jdt)),u2(n,w1n,h0n,mpn(Mgt)),u2(n,w1n,i2n,mpn(Jdt)),u2(n,w1n,r2n,mpn(Vdt)),u2(n,w1n,p3n,mpn(Igt)),u2(n,w1n,f0n,mpn(mgt)),u2(n,w1n,j0n,mpn(xgt)),u2(n,w1n,v3n,mpn(Lpt)),u2(n,w1n,U1n,mpn(Xdt)),u2(n,w1n,J1n,mpn(opt)),u2(n,w1n,$0n,mpn(tgt)),u2(n,w1n,c0n,mpn(ygt)),u2(n,w1n,g0n,mpn(Fdt)),u2(n,w1n,m3n,mpn(ggt)),u2(n,w1n,a0n,mpn(jgt)),u2(n,w1n,p0n,mpn(Bdt)),u2(n,w1n,c2n,mpn(Ldt)),u2(n,w1n,o2n,mpn(Adt)),u2(n,w1n,s2n,mpn(Cdt)),u2(n,w1n,h2n,mpn(Odt)),u2(n,w1n,a2n,mpn($dt)),u2(n,w1n,u2n,mpn(Idt)),u2(n,w1n,t0n,mpn(ogt))}function mWn(n,t){var e;return nNt||(nNt=new xp,tNt=new xp,wWn(),wWn(),ydn(e=new M0(4),"\t\n\r\r "),mZ(nNt,fnt,e),mZ(tNt,fnt,$Fn(e)),ydn(e=new M0(4),wnt),mZ(nNt,snt,e),mZ(tNt,snt,$Fn(e)),ydn(e=new M0(4),wnt),mZ(nNt,snt,e),mZ(tNt,snt,$Fn(e)),ydn(e=new M0(4),dnt),sHn(e,BB(SJ(nNt,snt),117)),mZ(nNt,hnt,e),mZ(tNt,hnt,$Fn(e)),ydn(e=new M0(4),"-.0:AZ__az\xb7\xb7\xc0\xd6\xd8\xf6\xf8\u0131\u0134\u013e\u0141\u0148\u014a\u017e\u0180\u01c3\u01cd\u01f0\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1\u02d0\u02d1\u0300\u0345\u0360\u0361\u0386\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da\u03dc\u03dc\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c\u045e\u0481\u0483\u0486\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9\u0531\u0556\u0559\u0559\u0561\u0586\u0591\u05a1\u05a3\u05b9\u05bb\u05bd\u05bf\u05bf\u05c1\u05c2\u05c4\u05c4\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0640\u0652\u0660\u0669\u0670\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06d5\u06e8\u06ea\u06ed\u06f0\u06f9\u0901\u0903\u0905\u0939\u093c\u094d\u0951\u0954\u0958\u0963\u0966\u096f\u0981\u0983\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09bc\u09bc\u09be\u09c4\u09c7\u09c8\u09cb\u09cd\u09d7\u09d7\u09dc\u09dd\u09df\u09e3\u09e6\u09f1\u0a02\u0a02\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3c\u0a3e\u0a42\u0a47\u0a48\u0a4b\u0a4d\u0a59\u0a5c\u0a5e\u0a5e\u0a66\u0a74\u0a81\u0a83\u0a85\u0a8b\u0a8d\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9\u0abc\u0ac5\u0ac7\u0ac9\u0acb\u0acd\u0ae0\u0ae0\u0ae6\u0aef\u0b01\u0b03\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b36\u0b39\u0b3c\u0b43\u0b47\u0b48\u0b4b\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f\u0b61\u0b66\u0b6f\u0b82\u0b83\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9\u0bbe\u0bc2\u0bc6\u0bc8\u0bca\u0bcd\u0bd7\u0bd7\u0be7\u0bef\u0c01\u0c03\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33\u0c35\u0c39\u0c3e\u0c44\u0c46\u0c48\u0c4a\u0c4d\u0c55\u0c56\u0c60\u0c61\u0c66\u0c6f\u0c82\u0c83\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cbe\u0cc4\u0cc6\u0cc8\u0cca\u0ccd\u0cd5\u0cd6\u0cde\u0cde\u0ce0\u0ce1\u0ce6\u0cef\u0d02\u0d03\u0d05\u0d0c\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d3e\u0d43\u0d46\u0d48\u0d4a\u0d4d\u0d57\u0d57\u0d60\u0d61\u0d66\u0d6f\u0e01\u0e2e\u0e30\u0e3a\u0e40\u0e4e\u0e50\u0e59\u0e81\u0e82\u0e84\u0e84\u0e87\u0e88\u0e8a\u0e8a\u0e8d\u0e8d\u0e94\u0e97\u0e99\u0e9f\u0ea1\u0ea3\u0ea5\u0ea5\u0ea7\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eb0\u0eb9\u0ebb\u0ebd\u0ec0\u0ec4\u0ec6\u0ec6\u0ec8\u0ecd\u0ed0\u0ed9\u0f18\u0f19\u0f20\u0f29\u0f35\u0f35\u0f37\u0f37\u0f39\u0f39\u0f3e\u0f47\u0f49\u0f69\u0f71\u0f84\u0f86\u0f8b\u0f90\u0f95\u0f97\u0f97\u0f99\u0fad\u0fb1\u0fb7\u0fb9\u0fb9\u10a0\u10c5\u10d0\u10f6\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110b\u110c\u110e\u1112\u113c\u113c\u113e\u113e\u1140\u1140\u114c\u114c\u114e\u114e\u1150\u1150\u1154\u1155\u1159\u1159\u115f\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116d\u116e\u1172\u1173\u1175\u1175\u119e\u119e\u11a8\u11a8\u11ab\u11ab\u11ae\u11af\u11b7\u11b8\u11ba\u11ba\u11bc\u11c2\u11eb\u11eb\u11f0\u11f0\u11f9\u11f9\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u20d0\u20dc\u20e1\u20e1\u2126\u2126\u212a\u212b\u212e\u212e\u2180\u2182\u3005\u3005\u3007\u3007\u3021\u302f\u3031\u3035\u3041\u3094\u3099\u309a\u309d\u309e\u30a1\u30fa\u30fc\u30fe\u3105\u312c\u4e00\u9fa5\uac00\ud7a3"),mZ(nNt,lnt,e),mZ(tNt,lnt,$Fn(e)),ydn(e=new M0(4),dnt),Yxn(e,95,95),Yxn(e,58,58),mZ(nNt,bnt,e),mZ(tNt,bnt,$Fn(e))),BB(SJ(t?nNt:tNt,n),136)}function yWn(n){V$n(n.a,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"anySimpleType"])),V$n(n.b,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"anyType",F9n,_9n])),V$n(BB(Wtn(QQ(n.b),0),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,m7n,t8n,":mixed"])),V$n(BB(Wtn(QQ(n.b),1),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,m7n,M7n,P7n,t8n,":1",D7n,"lax"])),V$n(BB(Wtn(QQ(n.b),2),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,p7n,M7n,P7n,t8n,":2",D7n,"lax"])),V$n(n.c,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"anyURI",T7n,y7n])),V$n(n.d,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"base64Binary",T7n,y7n])),V$n(n.e,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,$Wn,T7n,y7n])),V$n(n.f,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"boolean:Object",J9n,$Wn])),V$n(n.g,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,S9n])),V$n(n.i,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"byte:Object",J9n,S9n])),V$n(n.j,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"date",T7n,y7n])),V$n(n.k,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"dateTime",T7n,y7n])),V$n(n.n,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"decimal",T7n,y7n])),V$n(n.o,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,I9n,T7n,y7n])),V$n(n.p,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"double:Object",J9n,I9n])),V$n(n.q,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"duration",T7n,y7n])),V$n(n.s,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"ENTITIES",J9n,R7n,_7n,"1"])),V$n(n.r,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,R7n,k7n,K7n])),V$n(n.t,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,K7n,J9n,F7n])),V$n(n.u,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,C9n,T7n,y7n])),V$n(n.v,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"float:Object",J9n,C9n])),V$n(n.w,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"gDay",T7n,y7n])),V$n(n.B,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"gMonth",T7n,y7n])),V$n(n.A,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"gMonthDay",T7n,y7n])),V$n(n.C,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"gYear",T7n,y7n])),V$n(n.D,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"gYearMonth",T7n,y7n])),V$n(n.F,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"hexBinary",T7n,y7n])),V$n(n.G,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"ID",J9n,F7n])),V$n(n.H,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"IDREF",J9n,F7n])),V$n(n.J,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"IDREFS",J9n,B7n,_7n,"1"])),V$n(n.I,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,B7n,k7n,"IDREF"])),V$n(n.K,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,O9n])),V$n(n.M,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,H7n])),V$n(n.L,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"int:Object",J9n,O9n])),V$n(n.P,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"language",J9n,q7n,G7n,z7n])),V$n(n.Q,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,A9n])),V$n(n.R,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"long:Object",J9n,A9n])),V$n(n.S,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"Name",J9n,q7n,G7n,U7n])),V$n(n.T,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,F7n,J9n,"Name",G7n,X7n])),V$n(n.U,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"negativeInteger",J9n,W7n,V7n,"-1"])),V$n(n.V,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,Q7n,J9n,q7n,G7n,"\\c+"])),V$n(n.X,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"NMTOKENS",J9n,Y7n,_7n,"1"])),V$n(n.W,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,Y7n,k7n,Q7n])),V$n(n.Y,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,J7n,J9n,H7n,Z7n,"0"])),V$n(n.Z,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,W7n,J9n,H7n,V7n,"0"])),V$n(n.$,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,nnt,J9n,NWn,T7n,"replace"])),V$n(n._,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"NOTATION",T7n,y7n])),V$n(n.ab,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"positiveInteger",J9n,J7n,Z7n,"1"])),V$n(n.bb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"processingInstruction_._type",F9n,"empty"])),V$n(BB(Wtn(QQ(n.bb),0),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,g7n,t8n,"data"])),V$n(BB(Wtn(QQ(n.bb),1),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,g7n,t8n,Y6n])),V$n(n.cb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"QName",T7n,y7n])),V$n(n.db,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,$9n])),V$n(n.eb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"short:Object",J9n,$9n])),V$n(n.fb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"simpleAnyType",F9n,d7n])),V$n(BB(Wtn(QQ(n.fb),0),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,":3",F9n,d7n])),V$n(BB(Wtn(QQ(n.fb),1),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,":4",F9n,d7n])),V$n(BB(Wtn(QQ(n.fb),2),18),K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,":5",F9n,d7n])),V$n(n.gb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,NWn,T7n,"preserve"])),V$n(n.hb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"time",T7n,y7n])),V$n(n.ib,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,q7n,J9n,nnt,T7n,y7n])),V$n(n.jb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,tnt,V7n,"255",Z7n,"0"])),V$n(n.kb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"unsignedByte:Object",J9n,tnt])),V$n(n.lb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,ent,V7n,"4294967295",Z7n,"0"])),V$n(n.mb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"unsignedInt:Object",J9n,ent])),V$n(n.nb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"unsignedLong",J9n,J7n,V7n,int,Z7n,"0"])),V$n(n.ob,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,rnt,V7n,"65535",Z7n,"0"])),V$n(n.pb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"unsignedShort:Object",J9n,rnt])),V$n(n.qb,K9n,Pun(Gk(Qtt,1),sVn,2,6,[t8n,"",F9n,_9n])),V$n(BB(Wtn(QQ(n.qb),0),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,m7n,t8n,":mixed"])),V$n(BB(Wtn(QQ(n.qb),1),18),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,g7n,t8n,"xmlns:prefix"])),V$n(BB(Wtn(QQ(n.qb),2),18),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,g7n,t8n,"xsi:schemaLocation"])),V$n(BB(Wtn(QQ(n.qb),3),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,v7n,t8n,"cDATA",j7n,E7n])),V$n(BB(Wtn(QQ(n.qb),4),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,v7n,t8n,"comment",j7n,E7n])),V$n(BB(Wtn(QQ(n.qb),5),18),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,v7n,t8n,cnt,j7n,E7n])),V$n(BB(Wtn(QQ(n.qb),6),34),K9n,Pun(Gk(Qtt,1),sVn,2,6,[F9n,v7n,t8n,O6n,j7n,E7n]))}function kWn(n){return m_("_UI_EMFDiagnostic_marker",n)?"EMF Problem":m_("_UI_CircularContainment_diagnostic",n)?"An object may not circularly contain itself":m_(w8n,n)?"Wrong character.":m_(d8n,n)?"Invalid reference number.":m_(g8n,n)?"A character is required after \\.":m_(p8n,n)?"'?' is not expected. '(?:' or '(?=' or '(?!' or '(?<' or '(?#' or '(?>'?":m_(v8n,n)?"'(?<' or '(?<!' is expected.":m_(m8n,n)?"A comment is not terminated.":m_(y8n,n)?"')' is expected.":m_(k8n,n)?"Unexpected end of the pattern in a modifier group.":m_(j8n,n)?"':' is expected.":m_(E8n,n)?"Unexpected end of the pattern in a conditional group.":m_(T8n,n)?"A back reference or an anchor or a lookahead or a look-behind is expected in a conditional pattern.":m_(M8n,n)?"There are more than three choices in a conditional group.":m_(S8n,n)?"A character in U+0040-U+005f must follow \\c.":m_(P8n,n)?"A '{' is required before a character category.":m_(I8n,n)?"A property name is not closed by '}'.":m_(C8n,n)?"Unexpected meta character.":m_(O8n,n)?"Unknown property.":m_(A8n,n)?"A POSIX character class must be closed by ':]'.":m_($8n,n)?"Unexpected end of the pattern in a character class.":m_(L8n,n)?"Unknown name for a POSIX character class.":m_("parser.cc.4",n)?"'-' is invalid here.":m_(N8n,n)?"']' is expected.":m_(x8n,n)?"'[' is invalid in a character class. Write '\\['.":m_(D8n,n)?"']' is invalid in a character class. Write '\\]'.":m_(R8n,n)?"'-' is an invalid character range. Write '\\-'.":m_(_8n,n)?"'[' is expected.":m_(K8n,n)?"')' or '-[' or '+[' or '&[' is expected.":m_(F8n,n)?"The range end code point is less than the start code point.":m_(B8n,n)?"Invalid Unicode hex notation.":m_(H8n,n)?"Overflow in a hex notation.":m_(q8n,n)?"'\\x{' must be closed by '}'.":m_(G8n,n)?"Invalid Unicode code point.":m_(z8n,n)?"An anchor must not be here.":m_(U8n,n)?"This expression is not supported in the current option setting.":m_(X8n,n)?"Invalid quantifier. A digit is expected.":m_(W8n,n)?"Invalid quantifier. Invalid quantity or a '}' is missing.":m_(V8n,n)?"Invalid quantifier. A digit or '}' is expected.":m_(Q8n,n)?"Invalid quantifier. A min quantity must be <= a max quantity.":m_(Y8n,n)?"Invalid quantifier. A quantity value overflow.":m_("_UI_PackageRegistry_extensionpoint",n)?"Ecore Package Registry for Generated Packages":m_("_UI_DynamicPackageRegistry_extensionpoint",n)?"Ecore Package Registry for Dynamic Packages":m_("_UI_FactoryRegistry_extensionpoint",n)?"Ecore Factory Override Registry":m_("_UI_URIExtensionParserRegistry_extensionpoint",n)?"URI Extension Parser Registry":m_("_UI_URIProtocolParserRegistry_extensionpoint",n)?"URI Protocol Parser Registry":m_("_UI_URIContentParserRegistry_extensionpoint",n)?"URI Content Parser Registry":m_("_UI_ContentHandlerRegistry_extensionpoint",n)?"Content Handler Registry":m_("_UI_URIMappingRegistry_extensionpoint",n)?"URI Converter Mapping Registry":m_("_UI_PackageRegistryImplementation_extensionpoint",n)?"Ecore Package Registry Implementation":m_("_UI_ValidationDelegateRegistry_extensionpoint",n)?"Validation Delegate Registry":m_("_UI_SettingDelegateRegistry_extensionpoint",n)?"Feature Setting Delegate Factory Registry":m_("_UI_InvocationDelegateRegistry_extensionpoint",n)?"Operation Invocation Delegate Factory Registry":m_("_UI_EClassInterfaceNotAbstract_diagnostic",n)?"A class that is an interface must also be abstract":m_("_UI_EClassNoCircularSuperTypes_diagnostic",n)?"A class may not be a super type of itself":m_("_UI_EClassNotWellFormedMapEntryNoInstanceClassName_diagnostic",n)?"A class that inherits from a map entry class must have instance class name 'java.util.Map$Entry'":m_("_UI_EReferenceOppositeOfOppositeInconsistent_diagnostic",n)?"The opposite of the opposite may not be a reference different from this one":m_("_UI_EReferenceOppositeNotFeatureOfType_diagnostic",n)?"The opposite must be a feature of the reference's type":m_("_UI_EReferenceTransientOppositeNotTransient_diagnostic",n)?"The opposite of a transient reference must be transient if it is proxy resolving":m_("_UI_EReferenceOppositeBothContainment_diagnostic",n)?"The opposite of a containment reference must not be a containment reference":m_("_UI_EReferenceConsistentUnique_diagnostic",n)?"A containment or bidirectional reference must be unique if its upper bound is different from 1":m_("_UI_ETypedElementNoType_diagnostic",n)?"The typed element must have a type":m_("_UI_EAttributeNoDataType_diagnostic",n)?"The generic attribute type must not refer to a class":m_("_UI_EReferenceNoClass_diagnostic",n)?"The generic reference type must not refer to a data type":m_("_UI_EGenericTypeNoTypeParameterAndClassifier_diagnostic",n)?"A generic type can't refer to both a type parameter and a classifier":m_("_UI_EGenericTypeNoClass_diagnostic",n)?"A generic super type must refer to a class":m_("_UI_EGenericTypeNoTypeParameterOrClassifier_diagnostic",n)?"A generic type in this context must refer to a classifier or a type parameter":m_("_UI_EGenericTypeBoundsOnlyForTypeArgument_diagnostic",n)?"A generic type may have bounds only when used as a type argument":m_("_UI_EGenericTypeNoUpperAndLowerBound_diagnostic",n)?"A generic type must not have both a lower and an upper bound":m_("_UI_EGenericTypeNoTypeParameterOrClassifierAndBound_diagnostic",n)?"A generic type with bounds must not also refer to a type parameter or classifier":m_("_UI_EGenericTypeNoArguments_diagnostic",n)?"A generic type may have arguments only if it refers to a classifier":m_("_UI_EGenericTypeOutOfScopeTypeParameter_diagnostic",n)?"A generic type may only refer to a type parameter that is in scope":n}function jWn(n){var t,e,i,r,c,a,u;n.r||(n.r=!0,Nrn(n,"graph"),xrn(n,"graph"),Drn(n,y6n),cun(n.o,"T"),f9(kY(n.a),n.p),f9(kY(n.f),n.a),f9(kY(n.n),n.f),f9(kY(n.g),n.n),f9(kY(n.c),n.n),f9(kY(n.i),n.c),f9(kY(n.j),n.c),f9(kY(n.d),n.f),f9(kY(n.e),n.a),z0(n.p,Xrt,OJn,!0,!0,!1),u=Tun(a=msn(n.p,n.p,"setProperty")),t=ZV(n.o),e=new _p,f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),kEn(e,i=nQ(u)),Ujn(a,t,j6n),Ujn(a,t=nQ(u),E6n),u=Tun(a=msn(n.p,null,"getProperty")),t=ZV(n.o),e=nQ(u),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),Ujn(a,t,j6n),(c=HTn(a,t=nQ(u),null))&&c.Fi(),a=msn(n.p,n.wb.e,"hasProperty"),t=ZV(n.o),e=new _p,f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),Ujn(a,t,j6n),$yn(a=msn(n.p,n.p,"copyProperties"),n.p,T6n),a=msn(n.p,null,"getAllProperties"),t=ZV(n.wb.P),e=ZV(n.o),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),i=new _p,f9((!e.d&&(e.d=new $L(VAt,e,1)),e.d),i),e=ZV(n.wb.M),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),(r=HTn(a,t,null))&&r.Fi(),z0(n.a,NOt,z5n,!0,!1,!0),Myn(BB(Wtn(QQ(n.a),0),18),n.k,null,M6n,0,-1,NOt,!1,!1,!0,!0,!1,!1,!1),z0(n.f,DOt,X5n,!0,!1,!0),Myn(BB(Wtn(QQ(n.f),0),18),n.g,BB(Wtn(QQ(n.g),0),18),"labels",0,-1,DOt,!1,!1,!0,!0,!1,!1,!1),ucn(BB(Wtn(QQ(n.f),1),34),n.wb._,S6n,null,0,1,DOt,!1,!1,!0,!1,!0,!1),z0(n.n,ROt,"ElkShape",!0,!1,!0),ucn(BB(Wtn(QQ(n.n),0),34),n.wb.t,P6n,WQn,1,1,ROt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.n),1),34),n.wb.t,I6n,WQn,1,1,ROt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.n),2),34),n.wb.t,"x",WQn,1,1,ROt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.n),3),34),n.wb.t,"y",WQn,1,1,ROt,!1,!1,!0,!1,!0,!1),$yn(a=msn(n.n,null,"setDimensions"),n.wb.t,I6n),$yn(a,n.wb.t,P6n),$yn(a=msn(n.n,null,"setLocation"),n.wb.t,"x"),$yn(a,n.wb.t,"y"),z0(n.g,zOt,Z5n,!1,!1,!0),Myn(BB(Wtn(QQ(n.g),0),18),n.f,BB(Wtn(QQ(n.f),0),18),C6n,0,1,zOt,!1,!1,!0,!1,!1,!1,!1),ucn(BB(Wtn(QQ(n.g),1),34),n.wb._,O6n,"",0,1,zOt,!1,!1,!0,!1,!0,!1),z0(n.c,_Ot,W5n,!0,!1,!0),Myn(BB(Wtn(QQ(n.c),0),18),n.d,BB(Wtn(QQ(n.d),1),18),"outgoingEdges",0,-1,_Ot,!1,!1,!0,!1,!0,!1,!1),Myn(BB(Wtn(QQ(n.c),1),18),n.d,BB(Wtn(QQ(n.d),2),18),"incomingEdges",0,-1,_Ot,!1,!1,!0,!1,!0,!1,!1),z0(n.i,UOt,n6n,!1,!1,!0),Myn(BB(Wtn(QQ(n.i),0),18),n.j,BB(Wtn(QQ(n.j),0),18),"ports",0,-1,UOt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.i),1),18),n.i,BB(Wtn(QQ(n.i),2),18),A6n,0,-1,UOt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.i),2),18),n.i,BB(Wtn(QQ(n.i),1),18),C6n,0,1,UOt,!1,!1,!0,!1,!1,!1,!1),Myn(BB(Wtn(QQ(n.i),3),18),n.d,BB(Wtn(QQ(n.d),0),18),"containedEdges",0,-1,UOt,!1,!1,!0,!0,!1,!1,!1),ucn(BB(Wtn(QQ(n.i),4),34),n.wb.e,$6n,null,0,1,UOt,!0,!0,!1,!1,!0,!0),z0(n.j,XOt,t6n,!1,!1,!0),Myn(BB(Wtn(QQ(n.j),0),18),n.i,BB(Wtn(QQ(n.i),0),18),C6n,0,1,XOt,!1,!1,!0,!1,!1,!1,!1),z0(n.d,KOt,V5n,!1,!1,!0),Myn(BB(Wtn(QQ(n.d),0),18),n.i,BB(Wtn(QQ(n.i),3),18),"containingNode",0,1,KOt,!1,!1,!0,!1,!1,!1,!1),Myn(BB(Wtn(QQ(n.d),1),18),n.c,BB(Wtn(QQ(n.c),0),18),L6n,0,-1,KOt,!1,!1,!0,!1,!0,!1,!1),Myn(BB(Wtn(QQ(n.d),2),18),n.c,BB(Wtn(QQ(n.c),1),18),N6n,0,-1,KOt,!1,!1,!0,!1,!0,!1,!1),Myn(BB(Wtn(QQ(n.d),3),18),n.e,BB(Wtn(QQ(n.e),5),18),x6n,0,-1,KOt,!1,!1,!0,!0,!1,!1,!1),ucn(BB(Wtn(QQ(n.d),4),34),n.wb.e,"hyperedge",null,0,1,KOt,!0,!0,!1,!1,!0,!0),ucn(BB(Wtn(QQ(n.d),5),34),n.wb.e,$6n,null,0,1,KOt,!0,!0,!1,!1,!0,!0),ucn(BB(Wtn(QQ(n.d),6),34),n.wb.e,"selfloop",null,0,1,KOt,!0,!0,!1,!1,!0,!0),ucn(BB(Wtn(QQ(n.d),7),34),n.wb.e,"connected",null,0,1,KOt,!0,!0,!1,!1,!0,!0),z0(n.b,xOt,U5n,!1,!1,!0),ucn(BB(Wtn(QQ(n.b),0),34),n.wb.t,"x",WQn,1,1,xOt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.b),1),34),n.wb.t,"y",WQn,1,1,xOt,!1,!1,!0,!1,!0,!1),$yn(a=msn(n.b,null,"set"),n.wb.t,"x"),$yn(a,n.wb.t,"y"),z0(n.e,FOt,Q5n,!1,!1,!0),ucn(BB(Wtn(QQ(n.e),0),34),n.wb.t,"startX",null,0,1,FOt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.e),1),34),n.wb.t,"startY",null,0,1,FOt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.e),2),34),n.wb.t,"endX",null,0,1,FOt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.e),3),34),n.wb.t,"endY",null,0,1,FOt,!1,!1,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.e),4),18),n.b,null,D6n,0,-1,FOt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.e),5),18),n.d,BB(Wtn(QQ(n.d),3),18),C6n,0,1,FOt,!1,!1,!0,!1,!1,!1,!1),Myn(BB(Wtn(QQ(n.e),6),18),n.c,null,R6n,0,1,FOt,!1,!1,!0,!1,!0,!1,!1),Myn(BB(Wtn(QQ(n.e),7),18),n.c,null,_6n,0,1,FOt,!1,!1,!0,!1,!0,!1,!1),Myn(BB(Wtn(QQ(n.e),8),18),n.e,BB(Wtn(QQ(n.e),9),18),K6n,0,-1,FOt,!1,!1,!0,!1,!0,!1,!1),Myn(BB(Wtn(QQ(n.e),9),18),n.e,BB(Wtn(QQ(n.e),8),18),F6n,0,-1,FOt,!1,!1,!0,!1,!0,!1,!1),ucn(BB(Wtn(QQ(n.e),10),34),n.wb._,S6n,null,0,1,FOt,!1,!1,!0,!1,!0,!1),$yn(a=msn(n.e,null,"setStartLocation"),n.wb.t,"x"),$yn(a,n.wb.t,"y"),$yn(a=msn(n.e,null,"setEndLocation"),n.wb.t,"x"),$yn(a,n.wb.t,"y"),z0(n.k,Hnt,"ElkPropertyToValueMapEntry",!1,!1,!1),t=ZV(n.o),e=new _p,f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),KOn(BB(Wtn(QQ(n.k),0),34),t,"key",Hnt,!1,!1,!0,!1),ucn(BB(Wtn(QQ(n.k),1),34),n.s,E6n,null,0,1,Hnt,!1,!1,!0,!1,!0,!1),dV(n.o,lMt,"IProperty",!0),dV(n.s,Ant,"PropertyValue",!0),Lhn(n,y6n))}function EWn(){EWn=O,(JLt=x8(NNt,v6n,25,BQn,15,1))[9]=35,JLt[10]=19,JLt[13]=19,JLt[32]=51,JLt[33]=49,JLt[34]=33,yU(JLt,35,38,49),JLt[38]=1,yU(JLt,39,45,49),yU(JLt,45,47,-71),JLt[47]=49,yU(JLt,48,58,-71),JLt[58]=61,JLt[59]=49,JLt[60]=1,JLt[61]=49,JLt[62]=33,yU(JLt,63,65,49),yU(JLt,65,91,-3),yU(JLt,91,93,33),JLt[93]=1,JLt[94]=33,JLt[95]=-3,JLt[96]=33,yU(JLt,97,123,-3),yU(JLt,123,183,33),JLt[183]=-87,yU(JLt,184,192,33),yU(JLt,192,215,-19),JLt[215]=33,yU(JLt,216,247,-19),JLt[247]=33,yU(JLt,248,306,-19),yU(JLt,306,308,33),yU(JLt,308,319,-19),yU(JLt,319,321,33),yU(JLt,321,329,-19),JLt[329]=33,yU(JLt,330,383,-19),JLt[383]=33,yU(JLt,384,452,-19),yU(JLt,452,461,33),yU(JLt,461,497,-19),yU(JLt,497,500,33),yU(JLt,500,502,-19),yU(JLt,502,506,33),yU(JLt,506,536,-19),yU(JLt,536,592,33),yU(JLt,592,681,-19),yU(JLt,681,699,33),yU(JLt,699,706,-19),yU(JLt,706,720,33),yU(JLt,720,722,-87),yU(JLt,722,768,33),yU(JLt,768,838,-87),yU(JLt,838,864,33),yU(JLt,864,866,-87),yU(JLt,866,902,33),JLt[902]=-19,JLt[903]=-87,yU(JLt,904,907,-19),JLt[907]=33,JLt[908]=-19,JLt[909]=33,yU(JLt,910,930,-19),JLt[930]=33,yU(JLt,931,975,-19),JLt[975]=33,yU(JLt,976,983,-19),yU(JLt,983,986,33),JLt[986]=-19,JLt[987]=33,JLt[988]=-19,JLt[989]=33,JLt[990]=-19,JLt[991]=33,JLt[992]=-19,JLt[993]=33,yU(JLt,994,1012,-19),yU(JLt,1012,1025,33),yU(JLt,1025,1037,-19),JLt[1037]=33,yU(JLt,1038,1104,-19),JLt[1104]=33,yU(JLt,1105,1117,-19),JLt[1117]=33,yU(JLt,1118,1154,-19),JLt[1154]=33,yU(JLt,1155,1159,-87),yU(JLt,1159,1168,33),yU(JLt,1168,1221,-19),yU(JLt,1221,1223,33),yU(JLt,1223,1225,-19),yU(JLt,1225,1227,33),yU(JLt,1227,1229,-19),yU(JLt,1229,1232,33),yU(JLt,1232,1260,-19),yU(JLt,1260,1262,33),yU(JLt,1262,1270,-19),yU(JLt,1270,1272,33),yU(JLt,1272,1274,-19),yU(JLt,1274,1329,33),yU(JLt,1329,1367,-19),yU(JLt,1367,1369,33),JLt[1369]=-19,yU(JLt,1370,1377,33),yU(JLt,1377,1415,-19),yU(JLt,1415,1425,33),yU(JLt,1425,1442,-87),JLt[1442]=33,yU(JLt,1443,1466,-87),JLt[1466]=33,yU(JLt,1467,1470,-87),JLt[1470]=33,JLt[1471]=-87,JLt[1472]=33,yU(JLt,1473,1475,-87),JLt[1475]=33,JLt[1476]=-87,yU(JLt,1477,1488,33),yU(JLt,1488,1515,-19),yU(JLt,1515,1520,33),yU(JLt,1520,1523,-19),yU(JLt,1523,1569,33),yU(JLt,1569,1595,-19),yU(JLt,1595,1600,33),JLt[1600]=-87,yU(JLt,1601,1611,-19),yU(JLt,1611,1619,-87),yU(JLt,1619,1632,33),yU(JLt,1632,1642,-87),yU(JLt,1642,1648,33),JLt[1648]=-87,yU(JLt,1649,1720,-19),yU(JLt,1720,1722,33),yU(JLt,1722,1727,-19),JLt[1727]=33,yU(JLt,1728,1743,-19),JLt[1743]=33,yU(JLt,1744,1748,-19),JLt[1748]=33,JLt[1749]=-19,yU(JLt,1750,1765,-87),yU(JLt,1765,1767,-19),yU(JLt,1767,1769,-87),JLt[1769]=33,yU(JLt,1770,1774,-87),yU(JLt,1774,1776,33),yU(JLt,1776,1786,-87),yU(JLt,1786,2305,33),yU(JLt,2305,2308,-87),JLt[2308]=33,yU(JLt,2309,2362,-19),yU(JLt,2362,2364,33),JLt[2364]=-87,JLt[2365]=-19,yU(JLt,2366,2382,-87),yU(JLt,2382,2385,33),yU(JLt,2385,2389,-87),yU(JLt,2389,2392,33),yU(JLt,2392,2402,-19),yU(JLt,2402,2404,-87),yU(JLt,2404,2406,33),yU(JLt,2406,2416,-87),yU(JLt,2416,2433,33),yU(JLt,2433,2436,-87),JLt[2436]=33,yU(JLt,2437,2445,-19),yU(JLt,2445,2447,33),yU(JLt,2447,2449,-19),yU(JLt,2449,2451,33),yU(JLt,2451,2473,-19),JLt[2473]=33,yU(JLt,2474,2481,-19),JLt[2481]=33,JLt[2482]=-19,yU(JLt,2483,2486,33),yU(JLt,2486,2490,-19),yU(JLt,2490,2492,33),JLt[2492]=-87,JLt[2493]=33,yU(JLt,2494,2501,-87),yU(JLt,2501,2503,33),yU(JLt,2503,2505,-87),yU(JLt,2505,2507,33),yU(JLt,2507,2510,-87),yU(JLt,2510,2519,33),JLt[2519]=-87,yU(JLt,2520,2524,33),yU(JLt,2524,2526,-19),JLt[2526]=33,yU(JLt,2527,2530,-19),yU(JLt,2530,2532,-87),yU(JLt,2532,2534,33),yU(JLt,2534,2544,-87),yU(JLt,2544,2546,-19),yU(JLt,2546,2562,33),JLt[2562]=-87,yU(JLt,2563,2565,33),yU(JLt,2565,2571,-19),yU(JLt,2571,2575,33),yU(JLt,2575,2577,-19),yU(JLt,2577,2579,33),yU(JLt,2579,2601,-19),JLt[2601]=33,yU(JLt,2602,2609,-19),JLt[2609]=33,yU(JLt,2610,2612,-19),JLt[2612]=33,yU(JLt,2613,2615,-19),JLt[2615]=33,yU(JLt,2616,2618,-19),yU(JLt,2618,2620,33),JLt[2620]=-87,JLt[2621]=33,yU(JLt,2622,2627,-87),yU(JLt,2627,2631,33),yU(JLt,2631,2633,-87),yU(JLt,2633,2635,33),yU(JLt,2635,2638,-87),yU(JLt,2638,2649,33),yU(JLt,2649,2653,-19),JLt[2653]=33,JLt[2654]=-19,yU(JLt,2655,2662,33),yU(JLt,2662,2674,-87),yU(JLt,2674,2677,-19),yU(JLt,2677,2689,33),yU(JLt,2689,2692,-87),JLt[2692]=33,yU(JLt,2693,2700,-19),JLt[2700]=33,JLt[2701]=-19,JLt[2702]=33,yU(JLt,2703,2706,-19),JLt[2706]=33,yU(JLt,2707,2729,-19),JLt[2729]=33,yU(JLt,2730,2737,-19),JLt[2737]=33,yU(JLt,2738,2740,-19),JLt[2740]=33,yU(JLt,2741,2746,-19),yU(JLt,2746,2748,33),JLt[2748]=-87,JLt[2749]=-19,yU(JLt,2750,2758,-87),JLt[2758]=33,yU(JLt,2759,2762,-87),JLt[2762]=33,yU(JLt,2763,2766,-87),yU(JLt,2766,2784,33),JLt[2784]=-19,yU(JLt,2785,2790,33),yU(JLt,2790,2800,-87),yU(JLt,2800,2817,33),yU(JLt,2817,2820,-87),JLt[2820]=33,yU(JLt,2821,2829,-19),yU(JLt,2829,2831,33),yU(JLt,2831,2833,-19),yU(JLt,2833,2835,33),yU(JLt,2835,2857,-19),JLt[2857]=33,yU(JLt,2858,2865,-19),JLt[2865]=33,yU(JLt,2866,2868,-19),yU(JLt,2868,2870,33),yU(JLt,2870,2874,-19),yU(JLt,2874,2876,33),JLt[2876]=-87,JLt[2877]=-19,yU(JLt,2878,2884,-87),yU(JLt,2884,2887,33),yU(JLt,2887,2889,-87),yU(JLt,2889,2891,33),yU(JLt,2891,2894,-87),yU(JLt,2894,2902,33),yU(JLt,2902,2904,-87),yU(JLt,2904,2908,33),yU(JLt,2908,2910,-19),JLt[2910]=33,yU(JLt,2911,2914,-19),yU(JLt,2914,2918,33),yU(JLt,2918,2928,-87),yU(JLt,2928,2946,33),yU(JLt,2946,2948,-87),JLt[2948]=33,yU(JLt,2949,2955,-19),yU(JLt,2955,2958,33),yU(JLt,2958,2961,-19),JLt[2961]=33,yU(JLt,2962,2966,-19),yU(JLt,2966,2969,33),yU(JLt,2969,2971,-19),JLt[2971]=33,JLt[2972]=-19,JLt[2973]=33,yU(JLt,2974,2976,-19),yU(JLt,2976,2979,33),yU(JLt,2979,2981,-19),yU(JLt,2981,2984,33),yU(JLt,2984,2987,-19),yU(JLt,2987,2990,33),yU(JLt,2990,2998,-19),JLt[2998]=33,yU(JLt,2999,3002,-19),yU(JLt,3002,3006,33),yU(JLt,3006,3011,-87),yU(JLt,3011,3014,33),yU(JLt,3014,3017,-87),JLt[3017]=33,yU(JLt,3018,3022,-87),yU(JLt,3022,3031,33),JLt[3031]=-87,yU(JLt,3032,3047,33),yU(JLt,3047,3056,-87),yU(JLt,3056,3073,33),yU(JLt,3073,3076,-87),JLt[3076]=33,yU(JLt,3077,3085,-19),JLt[3085]=33,yU(JLt,3086,3089,-19),JLt[3089]=33,yU(JLt,3090,3113,-19),JLt[3113]=33,yU(JLt,3114,3124,-19),JLt[3124]=33,yU(JLt,3125,3130,-19),yU(JLt,3130,3134,33),yU(JLt,3134,3141,-87),JLt[3141]=33,yU(JLt,3142,3145,-87),JLt[3145]=33,yU(JLt,3146,3150,-87),yU(JLt,3150,3157,33),yU(JLt,3157,3159,-87),yU(JLt,3159,3168,33),yU(JLt,3168,3170,-19),yU(JLt,3170,3174,33),yU(JLt,3174,3184,-87),yU(JLt,3184,3202,33),yU(JLt,3202,3204,-87),JLt[3204]=33,yU(JLt,3205,3213,-19),JLt[3213]=33,yU(JLt,3214,3217,-19),JLt[3217]=33,yU(JLt,3218,3241,-19),JLt[3241]=33,yU(JLt,3242,3252,-19),JLt[3252]=33,yU(JLt,3253,3258,-19),yU(JLt,3258,3262,33),yU(JLt,3262,3269,-87),JLt[3269]=33,yU(JLt,3270,3273,-87),JLt[3273]=33,yU(JLt,3274,3278,-87),yU(JLt,3278,3285,33),yU(JLt,3285,3287,-87),yU(JLt,3287,3294,33),JLt[3294]=-19,JLt[3295]=33,yU(JLt,3296,3298,-19),yU(JLt,3298,3302,33),yU(JLt,3302,3312,-87),yU(JLt,3312,3330,33),yU(JLt,3330,3332,-87),JLt[3332]=33,yU(JLt,3333,3341,-19),JLt[3341]=33,yU(JLt,3342,3345,-19),JLt[3345]=33,yU(JLt,3346,3369,-19),JLt[3369]=33,yU(JLt,3370,3386,-19),yU(JLt,3386,3390,33),yU(JLt,3390,3396,-87),yU(JLt,3396,3398,33),yU(JLt,3398,3401,-87),JLt[3401]=33,yU(JLt,3402,3406,-87),yU(JLt,3406,3415,33),JLt[3415]=-87,yU(JLt,3416,3424,33),yU(JLt,3424,3426,-19),yU(JLt,3426,3430,33),yU(JLt,3430,3440,-87),yU(JLt,3440,3585,33),yU(JLt,3585,3631,-19),JLt[3631]=33,JLt[3632]=-19,JLt[3633]=-87,yU(JLt,3634,3636,-19),yU(JLt,3636,3643,-87),yU(JLt,3643,3648,33),yU(JLt,3648,3654,-19),yU(JLt,3654,3663,-87),JLt[3663]=33,yU(JLt,3664,3674,-87),yU(JLt,3674,3713,33),yU(JLt,3713,3715,-19),JLt[3715]=33,JLt[3716]=-19,yU(JLt,3717,3719,33),yU(JLt,3719,3721,-19),JLt[3721]=33,JLt[3722]=-19,yU(JLt,3723,3725,33),JLt[3725]=-19,yU(JLt,3726,3732,33),yU(JLt,3732,3736,-19),JLt[3736]=33,yU(JLt,3737,3744,-19),JLt[3744]=33,yU(JLt,3745,3748,-19),JLt[3748]=33,JLt[3749]=-19,JLt[3750]=33,JLt[3751]=-19,yU(JLt,3752,3754,33),yU(JLt,3754,3756,-19),JLt[3756]=33,yU(JLt,3757,3759,-19),JLt[3759]=33,JLt[3760]=-19,JLt[3761]=-87,yU(JLt,3762,3764,-19),yU(JLt,3764,3770,-87),JLt[3770]=33,yU(JLt,3771,3773,-87),JLt[3773]=-19,yU(JLt,3774,3776,33),yU(JLt,3776,3781,-19),JLt[3781]=33,JLt[3782]=-87,JLt[3783]=33,yU(JLt,3784,3790,-87),yU(JLt,3790,3792,33),yU(JLt,3792,3802,-87),yU(JLt,3802,3864,33),yU(JLt,3864,3866,-87),yU(JLt,3866,3872,33),yU(JLt,3872,3882,-87),yU(JLt,3882,3893,33),JLt[3893]=-87,JLt[3894]=33,JLt[3895]=-87,JLt[3896]=33,JLt[3897]=-87,yU(JLt,3898,3902,33),yU(JLt,3902,3904,-87),yU(JLt,3904,3912,-19),JLt[3912]=33,yU(JLt,3913,3946,-19),yU(JLt,3946,3953,33),yU(JLt,3953,3973,-87),JLt[3973]=33,yU(JLt,3974,3980,-87),yU(JLt,3980,3984,33),yU(JLt,3984,3990,-87),JLt[3990]=33,JLt[3991]=-87,JLt[3992]=33,yU(JLt,3993,4014,-87),yU(JLt,4014,4017,33),yU(JLt,4017,4024,-87),JLt[4024]=33,JLt[4025]=-87,yU(JLt,4026,4256,33),yU(JLt,4256,4294,-19),yU(JLt,4294,4304,33),yU(JLt,4304,4343,-19),yU(JLt,4343,4352,33),JLt[4352]=-19,JLt[4353]=33,yU(JLt,4354,4356,-19),JLt[4356]=33,yU(JLt,4357,4360,-19),JLt[4360]=33,JLt[4361]=-19,JLt[4362]=33,yU(JLt,4363,4365,-19),JLt[4365]=33,yU(JLt,4366,4371,-19),yU(JLt,4371,4412,33),JLt[4412]=-19,JLt[4413]=33,JLt[4414]=-19,JLt[4415]=33,JLt[4416]=-19,yU(JLt,4417,4428,33),JLt[4428]=-19,JLt[4429]=33,JLt[4430]=-19,JLt[4431]=33,JLt[4432]=-19,yU(JLt,4433,4436,33),yU(JLt,4436,4438,-19),yU(JLt,4438,4441,33),JLt[4441]=-19,yU(JLt,4442,4447,33),yU(JLt,4447,4450,-19),JLt[4450]=33,JLt[4451]=-19,JLt[4452]=33,JLt[4453]=-19,JLt[4454]=33,JLt[4455]=-19,JLt[4456]=33,JLt[4457]=-19,yU(JLt,4458,4461,33),yU(JLt,4461,4463,-19),yU(JLt,4463,4466,33),yU(JLt,4466,4468,-19),JLt[4468]=33,JLt[4469]=-19,yU(JLt,4470,4510,33),JLt[4510]=-19,yU(JLt,4511,4520,33),JLt[4520]=-19,yU(JLt,4521,4523,33),JLt[4523]=-19,yU(JLt,4524,4526,33),yU(JLt,4526,4528,-19),yU(JLt,4528,4535,33),yU(JLt,4535,4537,-19),JLt[4537]=33,JLt[4538]=-19,JLt[4539]=33,yU(JLt,4540,4547,-19),yU(JLt,4547,4587,33),JLt[4587]=-19,yU(JLt,4588,4592,33),JLt[4592]=-19,yU(JLt,4593,4601,33),JLt[4601]=-19,yU(JLt,4602,7680,33),yU(JLt,7680,7836,-19),yU(JLt,7836,7840,33),yU(JLt,7840,7930,-19),yU(JLt,7930,7936,33),yU(JLt,7936,7958,-19),yU(JLt,7958,7960,33),yU(JLt,7960,7966,-19),yU(JLt,7966,7968,33),yU(JLt,7968,8006,-19),yU(JLt,8006,8008,33),yU(JLt,8008,8014,-19),yU(JLt,8014,8016,33),yU(JLt,8016,8024,-19),JLt[8024]=33,JLt[8025]=-19,JLt[8026]=33,JLt[8027]=-19,JLt[8028]=33,JLt[8029]=-19,JLt[8030]=33,yU(JLt,8031,8062,-19),yU(JLt,8062,8064,33),yU(JLt,8064,8117,-19),JLt[8117]=33,yU(JLt,8118,8125,-19),JLt[8125]=33,JLt[8126]=-19,yU(JLt,8127,8130,33),yU(JLt,8130,8133,-19),JLt[8133]=33,yU(JLt,8134,8141,-19),yU(JLt,8141,8144,33),yU(JLt,8144,8148,-19),yU(JLt,8148,8150,33),yU(JLt,8150,8156,-19),yU(JLt,8156,8160,33),yU(JLt,8160,8173,-19),yU(JLt,8173,8178,33),yU(JLt,8178,8181,-19),JLt[8181]=33,yU(JLt,8182,8189,-19),yU(JLt,8189,8400,33),yU(JLt,8400,8413,-87),yU(JLt,8413,8417,33),JLt[8417]=-87,yU(JLt,8418,8486,33),JLt[8486]=-19,yU(JLt,8487,8490,33),yU(JLt,8490,8492,-19),yU(JLt,8492,8494,33),JLt[8494]=-19,yU(JLt,8495,8576,33),yU(JLt,8576,8579,-19),yU(JLt,8579,12293,33),JLt[12293]=-87,JLt[12294]=33,JLt[12295]=-19,yU(JLt,12296,12321,33),yU(JLt,12321,12330,-19),yU(JLt,12330,12336,-87),JLt[12336]=33,yU(JLt,12337,12342,-87),yU(JLt,12342,12353,33),yU(JLt,12353,12437,-19),yU(JLt,12437,12441,33),yU(JLt,12441,12443,-87),yU(JLt,12443,12445,33),yU(JLt,12445,12447,-87),yU(JLt,12447,12449,33),yU(JLt,12449,12539,-19),JLt[12539]=33,yU(JLt,12540,12543,-87),yU(JLt,12543,12549,33),yU(JLt,12549,12589,-19),yU(JLt,12589,19968,33),yU(JLt,19968,40870,-19),yU(JLt,40870,44032,33),yU(JLt,44032,55204,-19),yU(JLt,55204,HQn,33),yU(JLt,57344,65534,33)}function TWn(n){var t,e,i,r,c,a,u;n.hb||(n.hb=!0,Nrn(n,"ecore"),xrn(n,"ecore"),Drn(n,V9n),cun(n.fb,"E"),cun(n.L,"T"),cun(n.P,"K"),cun(n.P,"V"),cun(n.cb,"E"),f9(kY(n.b),n.bb),f9(kY(n.a),n.Q),f9(kY(n.o),n.p),f9(kY(n.p),n.R),f9(kY(n.q),n.p),f9(kY(n.v),n.q),f9(kY(n.w),n.R),f9(kY(n.B),n.Q),f9(kY(n.R),n.Q),f9(kY(n.T),n.eb),f9(kY(n.U),n.R),f9(kY(n.V),n.eb),f9(kY(n.W),n.bb),f9(kY(n.bb),n.eb),f9(kY(n.eb),n.R),f9(kY(n.db),n.R),z0(n.b,BAt,l9n,!1,!1,!0),ucn(BB(Wtn(QQ(n.b),0),34),n.e,"iD",null,0,1,BAt,!1,!1,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.b),1),18),n.q,null,"eAttributeType",1,1,BAt,!0,!0,!1,!1,!0,!1,!0),z0(n.a,_At,s9n,!1,!1,!0),ucn(BB(Wtn(QQ(n.a),0),34),n._,T6n,null,0,1,_At,!1,!1,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.a),1),18),n.ab,null,"details",0,-1,_At,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.a),2),18),n.Q,BB(Wtn(QQ(n.Q),0),18),"eModelElement",0,1,_At,!0,!1,!0,!1,!1,!1,!1),Myn(BB(Wtn(QQ(n.a),3),18),n.S,null,"contents",0,-1,_At,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.a),4),18),n.S,null,"references",0,-1,_At,!1,!1,!0,!1,!0,!1,!1),z0(n.o,qAt,"EClass",!1,!1,!0),ucn(BB(Wtn(QQ(n.o),0),34),n.e,"abstract",null,0,1,qAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.o),1),34),n.e,"interface",null,0,1,qAt,!1,!1,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.o),2),18),n.o,null,"eSuperTypes",0,-1,qAt,!1,!1,!0,!1,!0,!0,!1),Myn(BB(Wtn(QQ(n.o),3),18),n.T,BB(Wtn(QQ(n.T),0),18),"eOperations",0,-1,qAt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.o),4),18),n.b,null,"eAllAttributes",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.o),5),18),n.W,null,"eAllReferences",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.o),6),18),n.W,null,"eReferences",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.o),7),18),n.b,null,"eAttributes",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.o),8),18),n.W,null,"eAllContainments",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.o),9),18),n.T,null,"eAllOperations",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.o),10),18),n.bb,null,"eAllStructuralFeatures",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.o),11),18),n.o,null,"eAllSuperTypes",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.o),12),18),n.b,null,"eIDAttribute",0,1,qAt,!0,!0,!1,!1,!1,!1,!0),Myn(BB(Wtn(QQ(n.o),13),18),n.bb,BB(Wtn(QQ(n.bb),7),18),"eStructuralFeatures",0,-1,qAt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.o),14),18),n.H,null,"eGenericSuperTypes",0,-1,qAt,!1,!1,!0,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.o),15),18),n.H,null,"eAllGenericSuperTypes",0,-1,qAt,!0,!0,!1,!1,!0,!1,!0),$yn(u=fin(BB(Wtn(VQ(n.o),0),59),n.e,"isSuperTypeOf"),n.o,"someClass"),fin(BB(Wtn(VQ(n.o),1),59),n.I,"getFeatureCount"),$yn(u=fin(BB(Wtn(VQ(n.o),2),59),n.bb,Z9n),n.I,"featureID"),$yn(u=fin(BB(Wtn(VQ(n.o),3),59),n.I,n7n),n.bb,t7n),$yn(u=fin(BB(Wtn(VQ(n.o),4),59),n.bb,Z9n),n._,"featureName"),fin(BB(Wtn(VQ(n.o),5),59),n.I,"getOperationCount"),$yn(u=fin(BB(Wtn(VQ(n.o),6),59),n.T,"getEOperation"),n.I,"operationID"),$yn(u=fin(BB(Wtn(VQ(n.o),7),59),n.I,e7n),n.T,i7n),$yn(u=fin(BB(Wtn(VQ(n.o),8),59),n.T,"getOverride"),n.T,i7n),$yn(u=fin(BB(Wtn(VQ(n.o),9),59),n.H,"getFeatureType"),n.bb,t7n),z0(n.p,HAt,b9n,!0,!1,!0),ucn(BB(Wtn(QQ(n.p),0),34),n._,"instanceClassName",null,0,1,HAt,!1,!0,!0,!0,!0,!1),t=ZV(n.L),e=s2(),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),KOn(BB(Wtn(QQ(n.p),1),34),t,"instanceClass",HAt,!0,!0,!1,!0),ucn(BB(Wtn(QQ(n.p),2),34),n.M,r7n,null,0,1,HAt,!0,!0,!1,!1,!0,!0),ucn(BB(Wtn(QQ(n.p),3),34),n._,"instanceTypeName",null,0,1,HAt,!1,!0,!0,!0,!0,!1),Myn(BB(Wtn(QQ(n.p),4),18),n.U,BB(Wtn(QQ(n.U),3),18),"ePackage",0,1,HAt,!0,!1,!1,!1,!0,!1,!1),Myn(BB(Wtn(QQ(n.p),5),18),n.db,null,c7n,0,-1,HAt,!1,!1,!0,!0,!0,!1,!1),$yn(u=fin(BB(Wtn(VQ(n.p),0),59),n.e,a7n),n.M,AWn),fin(BB(Wtn(VQ(n.p),1),59),n.I,"getClassifierID"),z0(n.q,GAt,"EDataType",!1,!1,!0),ucn(BB(Wtn(QQ(n.q),0),34),n.e,"serializable",a5n,0,1,GAt,!1,!1,!0,!1,!0,!1),z0(n.v,XAt,"EEnum",!1,!1,!0),Myn(BB(Wtn(QQ(n.v),0),18),n.w,BB(Wtn(QQ(n.w),3),18),"eLiterals",0,-1,XAt,!1,!1,!0,!0,!1,!1,!1),$yn(u=fin(BB(Wtn(VQ(n.v),0),59),n.w,u7n),n._,t8n),$yn(u=fin(BB(Wtn(VQ(n.v),1),59),n.w,u7n),n.I,E6n),$yn(u=fin(BB(Wtn(VQ(n.v),2),59),n.w,"getEEnumLiteralByLiteral"),n._,"literal"),z0(n.w,WAt,w9n,!1,!1,!0),ucn(BB(Wtn(QQ(n.w),0),34),n.I,E6n,null,0,1,WAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.w),1),34),n.A,"instance",null,0,1,WAt,!0,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.w),2),34),n._,"literal",null,0,1,WAt,!1,!1,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.w),3),18),n.v,BB(Wtn(QQ(n.v),0),18),"eEnum",0,1,WAt,!0,!1,!1,!1,!1,!1,!1),z0(n.B,HOt,"EFactory",!1,!1,!0),Myn(BB(Wtn(QQ(n.B),0),18),n.U,BB(Wtn(QQ(n.U),2),18),"ePackage",1,1,HOt,!0,!1,!0,!1,!1,!1,!1),$yn(u=fin(BB(Wtn(VQ(n.B),0),59),n.S,"create"),n.o,"eClass"),$yn(u=fin(BB(Wtn(VQ(n.B),1),59),n.M,"createFromString"),n.q,"eDataType"),$yn(u,n._,"literalValue"),$yn(u=fin(BB(Wtn(VQ(n.B),2),59),n._,"convertToString"),n.q,"eDataType"),$yn(u,n.M,"instanceValue"),z0(n.Q,BOt,Y5n,!0,!1,!0),Myn(BB(Wtn(QQ(n.Q),0),18),n.a,BB(Wtn(QQ(n.a),2),18),"eAnnotations",0,-1,BOt,!1,!1,!0,!0,!1,!1,!1),$yn(u=fin(BB(Wtn(VQ(n.Q),0),59),n.a,"getEAnnotation"),n._,T6n),z0(n.R,qOt,J5n,!0,!1,!0),ucn(BB(Wtn(QQ(n.R),0),34),n._,t8n,null,0,1,qOt,!1,!1,!0,!1,!0,!1),z0(n.S,LOt,"EObject",!1,!1,!0),fin(BB(Wtn(VQ(n.S),0),59),n.o,"eClass"),fin(BB(Wtn(VQ(n.S),1),59),n.e,"eIsProxy"),fin(BB(Wtn(VQ(n.S),2),59),n.X,"eResource"),fin(BB(Wtn(VQ(n.S),3),59),n.S,"eContainer"),fin(BB(Wtn(VQ(n.S),4),59),n.bb,"eContainingFeature"),fin(BB(Wtn(VQ(n.S),5),59),n.W,"eContainmentFeature"),u=fin(BB(Wtn(VQ(n.S),6),59),null,"eContents"),t=ZV(n.fb),e=ZV(n.S),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),(r=HTn(u,t,null))&&r.Fi(),u=fin(BB(Wtn(VQ(n.S),7),59),null,"eAllContents"),t=ZV(n.cb),e=ZV(n.S),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),(c=HTn(u,t,null))&&c.Fi(),u=fin(BB(Wtn(VQ(n.S),8),59),null,"eCrossReferences"),t=ZV(n.fb),e=ZV(n.S),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),(a=HTn(u,t,null))&&a.Fi(),$yn(u=fin(BB(Wtn(VQ(n.S),9),59),n.M,"eGet"),n.bb,t7n),$yn(u=fin(BB(Wtn(VQ(n.S),10),59),n.M,"eGet"),n.bb,t7n),$yn(u,n.e,"resolve"),$yn(u=fin(BB(Wtn(VQ(n.S),11),59),null,"eSet"),n.bb,t7n),$yn(u,n.M,"newValue"),$yn(u=fin(BB(Wtn(VQ(n.S),12),59),n.e,"eIsSet"),n.bb,t7n),$yn(u=fin(BB(Wtn(VQ(n.S),13),59),null,"eUnset"),n.bb,t7n),$yn(u=fin(BB(Wtn(VQ(n.S),14),59),n.M,"eInvoke"),n.T,i7n),t=ZV(n.fb),e=s2(),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),Ujn(u,t,"arguments"),KW(u,n.K),z0(n.T,QAt,g9n,!1,!1,!0),Myn(BB(Wtn(QQ(n.T),0),18),n.o,BB(Wtn(QQ(n.o),3),18),o7n,0,1,QAt,!0,!1,!1,!1,!1,!1,!1),Myn(BB(Wtn(QQ(n.T),1),18),n.db,null,c7n,0,-1,QAt,!1,!1,!0,!0,!0,!1,!1),Myn(BB(Wtn(QQ(n.T),2),18),n.V,BB(Wtn(QQ(n.V),0),18),"eParameters",0,-1,QAt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.T),3),18),n.p,null,"eExceptions",0,-1,QAt,!1,!1,!0,!1,!0,!0,!1),Myn(BB(Wtn(QQ(n.T),4),18),n.H,null,"eGenericExceptions",0,-1,QAt,!1,!1,!0,!0,!1,!0,!1),fin(BB(Wtn(VQ(n.T),0),59),n.I,e7n),$yn(u=fin(BB(Wtn(VQ(n.T),1),59),n.e,"isOverrideOf"),n.T,"someOperation"),z0(n.U,GOt,"EPackage",!1,!1,!0),ucn(BB(Wtn(QQ(n.U),0),34),n._,"nsURI",null,0,1,GOt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.U),1),34),n._,"nsPrefix",null,0,1,GOt,!1,!1,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.U),2),18),n.B,BB(Wtn(QQ(n.B),0),18),"eFactoryInstance",1,1,GOt,!0,!1,!0,!1,!1,!1,!1),Myn(BB(Wtn(QQ(n.U),3),18),n.p,BB(Wtn(QQ(n.p),4),18),"eClassifiers",0,-1,GOt,!1,!1,!0,!0,!0,!1,!1),Myn(BB(Wtn(QQ(n.U),4),18),n.U,BB(Wtn(QQ(n.U),5),18),"eSubpackages",0,-1,GOt,!1,!1,!0,!0,!0,!1,!1),Myn(BB(Wtn(QQ(n.U),5),18),n.U,BB(Wtn(QQ(n.U),4),18),"eSuperPackage",0,1,GOt,!0,!1,!1,!1,!0,!1,!1),$yn(u=fin(BB(Wtn(VQ(n.U),0),59),n.p,"getEClassifier"),n._,t8n),z0(n.V,YAt,p9n,!1,!1,!0),Myn(BB(Wtn(QQ(n.V),0),18),n.T,BB(Wtn(QQ(n.T),2),18),"eOperation",0,1,YAt,!0,!1,!1,!1,!1,!1,!1),z0(n.W,JAt,v9n,!1,!1,!0),ucn(BB(Wtn(QQ(n.W),0),34),n.e,"containment",null,0,1,JAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.W),1),34),n.e,"container",null,0,1,JAt,!0,!0,!1,!1,!0,!0),ucn(BB(Wtn(QQ(n.W),2),34),n.e,"resolveProxies",a5n,0,1,JAt,!1,!1,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.W),3),18),n.W,null,"eOpposite",0,1,JAt,!1,!1,!0,!1,!0,!1,!1),Myn(BB(Wtn(QQ(n.W),4),18),n.o,null,"eReferenceType",1,1,JAt,!0,!0,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.W),5),18),n.b,null,"eKeys",0,-1,JAt,!1,!1,!0,!1,!0,!1,!1),z0(n.bb,FAt,f9n,!0,!1,!0),ucn(BB(Wtn(QQ(n.bb),0),34),n.e,"changeable",a5n,0,1,FAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.bb),1),34),n.e,"volatile",null,0,1,FAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.bb),2),34),n.e,"transient",null,0,1,FAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.bb),3),34),n._,"defaultValueLiteral",null,0,1,FAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.bb),4),34),n.M,r7n,null,0,1,FAt,!0,!0,!1,!1,!0,!0),ucn(BB(Wtn(QQ(n.bb),5),34),n.e,"unsettable",null,0,1,FAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.bb),6),34),n.e,"derived",null,0,1,FAt,!1,!1,!0,!1,!0,!1),Myn(BB(Wtn(QQ(n.bb),7),18),n.o,BB(Wtn(QQ(n.o),13),18),o7n,0,1,FAt,!0,!1,!1,!1,!1,!1,!1),fin(BB(Wtn(VQ(n.bb),0),59),n.I,n7n),u=fin(BB(Wtn(VQ(n.bb),1),59),null,"getContainerClass"),t=ZV(n.L),e=s2(),f9((!t.d&&(t.d=new $L(VAt,t,1)),t.d),e),(i=HTn(u,t,null))&&i.Fi(),z0(n.eb,KAt,h9n,!0,!1,!0),ucn(BB(Wtn(QQ(n.eb),0),34),n.e,"ordered",a5n,0,1,KAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.eb),1),34),n.e,"unique",a5n,0,1,KAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.eb),2),34),n.I,"lowerBound",null,0,1,KAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.eb),3),34),n.I,"upperBound","1",0,1,KAt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.eb),4),34),n.e,"many",null,0,1,KAt,!0,!0,!1,!1,!0,!0),ucn(BB(Wtn(QQ(n.eb),5),34),n.e,"required",null,0,1,KAt,!0,!0,!1,!1,!0,!0),Myn(BB(Wtn(QQ(n.eb),6),18),n.p,null,"eType",0,1,KAt,!1,!0,!0,!1,!0,!0,!1),Myn(BB(Wtn(QQ(n.eb),7),18),n.H,null,"eGenericType",0,1,KAt,!1,!0,!0,!0,!1,!0,!1),z0(n.ab,Hnt,"EStringToStringMapEntry",!1,!1,!1),ucn(BB(Wtn(QQ(n.ab),0),34),n._,"key",null,0,1,Hnt,!1,!1,!0,!1,!0,!1),ucn(BB(Wtn(QQ(n.ab),1),34),n._,E6n,null,0,1,Hnt,!1,!1,!0,!1,!0,!1),z0(n.H,VAt,d9n,!1,!1,!0),Myn(BB(Wtn(QQ(n.H),0),18),n.H,null,"eUpperBound",0,1,VAt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.H),1),18),n.H,null,"eTypeArguments",0,-1,VAt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.H),2),18),n.p,null,"eRawType",1,1,VAt,!0,!1,!1,!1,!0,!1,!0),Myn(BB(Wtn(QQ(n.H),3),18),n.H,null,"eLowerBound",0,1,VAt,!1,!1,!0,!0,!1,!1,!1),Myn(BB(Wtn(QQ(n.H),4),18),n.db,null,"eTypeParameter",0,1,VAt,!1,!1,!0,!1,!1,!1,!1),Myn(BB(Wtn(QQ(n.H),5),18),n.p,null,"eClassifier",0,1,VAt,!1,!1,!0,!1,!0,!1,!1),$yn(u=fin(BB(Wtn(VQ(n.H),0),59),n.e,a7n),n.M,AWn),z0(n.db,O$t,m9n,!1,!1,!0),Myn(BB(Wtn(QQ(n.db),0),18),n.H,null,"eBounds",0,-1,O$t,!1,!1,!0,!0,!1,!1,!1),dV(n.c,iet,"EBigDecimal",!0),dV(n.d,oet,"EBigInteger",!0),dV(n.e,$Nt,"EBoolean",!0),dV(n.f,ktt,"EBooleanObject",!0),dV(n.i,NNt,"EByte",!0),dV(n.g,Gk(NNt,1),"EByteArray",!0),dV(n.j,Ttt,"EByteObject",!0),dV(n.k,ONt,"EChar",!0),dV(n.n,Stt,"ECharacterObject",!0),dV(n.r,mtt,"EDate",!0),dV(n.s,KNt,"EDiagnosticChain",!1),dV(n.t,xNt,"EDouble",!0),dV(n.u,Ptt,"EDoubleObject",!0),dV(n.fb,uAt,"EEList",!1),dV(n.A,yAt,"EEnumerator",!1),dV(n.C,oLt,"EFeatureMap",!1),dV(n.D,$$t,"EFeatureMapEntry",!1),dV(n.F,DNt,"EFloat",!0),dV(n.G,Itt,"EFloatObject",!0),dV(n.I,ANt,"EInt",!0),dV(n.J,Att,"EIntegerObject",!0),dV(n.L,$nt,"EJavaClass",!0),dV(n.M,Ant,"EJavaObject",!0),dV(n.N,LNt,"ELong",!0),dV(n.O,Rtt,"ELongObject",!0),dV(n.P,Nnt,"EMap",!1),dV(n.X,iLt,"EResource",!1),dV(n.Y,FNt,"EResourceSet",!1),dV(n.Z,RNt,"EShort",!0),dV(n.$,Ktt,"EShortObject",!0),dV(n._,Qtt,"EString",!0),dV(n.cb,sAt,"ETreeIterator",!1),dV(n.K,BNt,"EInvocationTargetException",!1),Lhn(n,V9n))}"undefined"!=typeof window?e=window:void 0!==n?e=n:"undefined"!=typeof self&&(e=self);var MWn,SWn,PWn,IWn,CWn,OWn,AWn="object",$Wn="boolean",LWn="number",NWn="string",xWn="function",DWn=2147483647,RWn="java.lang",_Wn={3:1},KWn="com.google.common.base",FWn=", ",BWn="%s (%s) must not be negative",HWn={3:1,4:1,5:1},qWn="negative size: ",GWn="Optional.of(",zWn="null",UWn={198:1,47:1},XWn="com.google.common.collect",WWn={198:1,47:1,125:1},VWn={224:1,3:1},QWn={47:1},YWn="java.util",JWn={83:1},ZWn={20:1,28:1,14:1},nVn=1965,tVn={20:1,28:1,14:1,21:1},eVn={83:1,171:1,161:1},iVn={20:1,28:1,14:1,21:1,84:1},rVn={20:1,28:1,14:1,271:1,21:1,84:1},cVn={47:1,125:1},aVn={345:1,42:1},uVn="AbstractMapEntry",oVn="expectedValuesPerKey",sVn={3:1,6:1,4:1,5:1},hVn=16384,fVn={164:1},lVn={38:1},bVn={l:4194303,m:4194303,h:524287},wVn={196:1},dVn={245:1,3:1,35:1},gVn="range unbounded on this side",pVn={20:1},vVn={20:1,14:1},mVn={3:1,20:1,28:1,14:1},yVn={152:1,3:1,20:1,28:1,14:1,15:1,54:1},kVn={3:1,4:1,5:1,165:1},jVn={3:1,83:1},EVn={20:1,14:1,21:1},TVn={3:1,20:1,28:1,14:1,21:1},MVn={20:1,14:1,21:1,84:1},SVn=461845907,PVn=-862048943,IVn={3:1,6:1,4:1,5:1,165:1},CVn="expectedSize",OVn=1073741824,AVn="initialArraySize",$Vn={3:1,6:1,4:1,9:1,5:1},LVn={20:1,28:1,52:1,14:1,15:1},NVn="arraySize",xVn={20:1,28:1,52:1,14:1,15:1,54:1},DVn={45:1},RVn={365:1},_Vn=1e-4,KVn=-2147483648,FVn="__noinit__",BVn={3:1,102:1,60:1,78:1},HVn="com.google.gwt.core.client.impl",qVn="String",GVn="com.google.gwt.core.client",zVn="anonymous",UVn="fnStack",XVn="Unknown",WVn={195:1,3:1,4:1},VVn=1e3,QVn=65535,YVn="January",JVn="February",ZVn="March",nQn="April",tQn="May",eQn="June",iQn="July",rQn="August",cQn="September",aQn="October",uQn="November",oQn="December",sQn=1900,hQn={48:1,3:1,4:1},fQn="Before Christ",lQn="Anno Domini",bQn="Sunday",wQn="Monday",dQn="Tuesday",gQn="Wednesday",pQn="Thursday",vQn="Friday",mQn="Saturday",yQn="com.google.gwt.i18n.shared",kQn="DateTimeFormat",jQn="com.google.gwt.i18n.client",EQn="DefaultDateTimeFormatInfo",TQn={3:1,4:1,35:1,199:1},MQn="com.google.gwt.json.client",SQn=4194303,PQn=1048575,IQn=524288,CQn=4194304,OQn=17592186044416,AQn=1e9,$Qn=-17592186044416,LQn="java.io",NQn={3:1,102:1,73:1,60:1,78:1},xQn={3:1,289:1,78:1},DQn='For input string: "',RQn=1/0,_Qn=-1/0,KQn=4096,FQn={3:1,4:1,364:1},BQn=65536,HQn=55296,qQn={104:1,3:1,4:1},GQn=1e5,zQn=.3010299956639812,UQn=4294967295,XQn=4294967296,WQn="0.0",VQn={42:1},QQn={3:1,4:1,20:1,28:1,52:1,12:1,14:1,15:1,54:1},YQn={3:1,20:1,28:1,52:1,14:1,15:1,54:1},JQn={20:1,14:1,15:1},ZQn={3:1,62:1},nYn={182:1},tYn={3:1,4:1,83:1},eYn={3:1,4:1,20:1,28:1,14:1,53:1,21:1},iYn="delete",rYn=1.4901161193847656e-8,cYn=11102230246251565e-32,aYn=15525485,uYn=5.960464477539063e-8,oYn=16777216,sYn=16777215,hYn=", length: ",fYn={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1},lYn={3:1,35:1,22:1,297:1},bYn="java.util.function",wYn="java.util.logging",dYn={3:1,4:1,5:1,842:1},gYn="undefined",pYn="java.util.stream",vYn={525:1,670:1},mYn="fromIndex: ",yYn=" > toIndex: ",kYn=", toIndex: ",jYn="Index: ",EYn=", Size: ",TYn="org.eclipse.elk.alg.common",MYn={62:1},SYn="org.eclipse.elk.alg.common.compaction",PYn="Scanline/EventHandler",IYn="org.eclipse.elk.alg.common.compaction.oned",CYn="CNode belongs to another CGroup.",OYn="ISpacingsHandler/1",AYn="The ",$Yn=" instance has been finished already.",LYn="The direction ",NYn=" is not supported by the CGraph instance.",xYn="OneDimensionalCompactor",DYn="OneDimensionalCompactor/lambda$0$Type",RYn="Quadruplet",_Yn="ScanlineConstraintCalculator",KYn="ScanlineConstraintCalculator/ConstraintsScanlineHandler",FYn="ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type",BYn="ScanlineConstraintCalculator/Timestamp",HYn="ScanlineConstraintCalculator/lambda$0$Type",qYn={169:1,45:1},GYn="org.eclipse.elk.alg.common.compaction.options",zYn="org.eclipse.elk.core.data",UYn="org.eclipse.elk.polyomino.traversalStrategy",XYn="org.eclipse.elk.polyomino.lowLevelSort",WYn="org.eclipse.elk.polyomino.highLevelSort",VYn="org.eclipse.elk.polyomino.fill",QYn={130:1},YYn="polyomino",JYn="org.eclipse.elk.alg.common.networksimplex",ZYn={177:1,3:1,4:1},nJn="org.eclipse.elk.alg.common.nodespacing",tJn="org.eclipse.elk.alg.common.nodespacing.cellsystem",eJn="CENTER",iJn={212:1,326:1},rJn={3:1,4:1,5:1,595:1},cJn="LEFT",aJn="RIGHT",uJn="Vertical alignment cannot be null",oJn="BOTTOM",sJn="org.eclipse.elk.alg.common.nodespacing.internal",hJn="UNDEFINED",fJn=.01,lJn="org.eclipse.elk.alg.common.nodespacing.internal.algorithm",bJn="LabelPlacer/lambda$0$Type",wJn="LabelPlacer/lambda$1$Type",dJn="portRatioOrPosition",gJn="org.eclipse.elk.alg.common.overlaps",pJn="DOWN",vJn="org.eclipse.elk.alg.common.polyomino",mJn="NORTH",yJn="EAST",kJn="SOUTH",jJn="WEST",EJn="org.eclipse.elk.alg.common.polyomino.structures",TJn="Direction",MJn="Grid is only of size ",SJn=". Requested point (",PJn=") is out of bounds.",IJn=" Given center based coordinates were (",CJn="org.eclipse.elk.graph.properties",OJn="IPropertyHolder",AJn={3:1,94:1,134:1},$Jn="org.eclipse.elk.alg.common.spore",LJn="org.eclipse.elk.alg.common.utils",NJn={209:1},xJn="org.eclipse.elk.core",DJn="Connected Components Compaction",RJn="org.eclipse.elk.alg.disco",_Jn="org.eclipse.elk.alg.disco.graph",KJn="org.eclipse.elk.alg.disco.options",FJn="CompactionStrategy",BJn="org.eclipse.elk.disco.componentCompaction.strategy",HJn="org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm",qJn="org.eclipse.elk.disco.debug.discoGraph",GJn="org.eclipse.elk.disco.debug.discoPolys",zJn="componentCompaction",UJn="org.eclipse.elk.disco",XJn="org.eclipse.elk.spacing.componentComponent",WJn="org.eclipse.elk.edge.thickness",VJn="org.eclipse.elk.aspectRatio",QJn="org.eclipse.elk.padding",YJn="org.eclipse.elk.alg.disco.transform",JJn=1.5707963267948966,ZJn=17976931348623157e292,nZn={3:1,4:1,5:1,192:1},tZn={3:1,6:1,4:1,5:1,106:1,120:1},eZn="org.eclipse.elk.alg.force",iZn="ComponentsProcessor",rZn="ComponentsProcessor/1",cZn="org.eclipse.elk.alg.force.graph",aZn="Component Layout",uZn="org.eclipse.elk.alg.force.model",oZn="org.eclipse.elk.force.model",sZn="org.eclipse.elk.force.iterations",hZn="org.eclipse.elk.force.repulsivePower",fZn="org.eclipse.elk.force.temperature",lZn=.001,bZn="org.eclipse.elk.force.repulsion",wZn="org.eclipse.elk.alg.force.options",dZn=1.600000023841858,gZn="org.eclipse.elk.force",pZn="org.eclipse.elk.priority",vZn="org.eclipse.elk.spacing.nodeNode",mZn="org.eclipse.elk.spacing.edgeLabel",yZn="org.eclipse.elk.randomSeed",kZn="org.eclipse.elk.separateConnectedComponents",jZn="org.eclipse.elk.interactive",EZn="org.eclipse.elk.portConstraints",TZn="org.eclipse.elk.edgeLabels.inline",MZn="org.eclipse.elk.omitNodeMicroLayout",SZn="org.eclipse.elk.nodeSize.options",PZn="org.eclipse.elk.nodeSize.constraints",IZn="org.eclipse.elk.nodeLabels.placement",CZn="org.eclipse.elk.portLabels.placement",OZn="origin",AZn="random",$Zn="boundingBox.upLeft",LZn="boundingBox.lowRight",NZn="org.eclipse.elk.stress.fixed",xZn="org.eclipse.elk.stress.desiredEdgeLength",DZn="org.eclipse.elk.stress.dimension",RZn="org.eclipse.elk.stress.epsilon",_Zn="org.eclipse.elk.stress.iterationLimit",KZn="org.eclipse.elk.stress",FZn="ELK Stress",BZn="org.eclipse.elk.nodeSize.minimum",HZn="org.eclipse.elk.alg.force.stress",qZn="Layered layout",GZn="org.eclipse.elk.alg.layered",zZn="org.eclipse.elk.alg.layered.compaction.components",UZn="org.eclipse.elk.alg.layered.compaction.oned",XZn="org.eclipse.elk.alg.layered.compaction.oned.algs",WZn="org.eclipse.elk.alg.layered.compaction.recthull",VZn="org.eclipse.elk.alg.layered.components",QZn="NONE",YZn={3:1,6:1,4:1,9:1,5:1,122:1},JZn={3:1,6:1,4:1,5:1,141:1,106:1,120:1},ZZn="org.eclipse.elk.alg.layered.compound",n1n={51:1},t1n="org.eclipse.elk.alg.layered.graph",e1n=" -> ",i1n="Not supported by LGraph",r1n="Port side is undefined",c1n={3:1,6:1,4:1,5:1,474:1,141:1,106:1,120:1},a1n={3:1,6:1,4:1,5:1,141:1,193:1,203:1,106:1,120:1},u1n={3:1,6:1,4:1,5:1,141:1,1943:1,203:1,106:1,120:1},o1n="([{\"' \t\r\n",s1n=")]}\"' \t\r\n",h1n="The given string contains parts that cannot be parsed as numbers.",f1n="org.eclipse.elk.core.math",l1n={3:1,4:1,142:1,207:1,414:1},b1n={3:1,4:1,116:1,207:1,414:1},w1n="org.eclipse.elk.layered",d1n="org.eclipse.elk.alg.layered.graph.transform",g1n="ElkGraphImporter",p1n="ElkGraphImporter/lambda$0$Type",v1n="ElkGraphImporter/lambda$1$Type",m1n="ElkGraphImporter/lambda$2$Type",y1n="ElkGraphImporter/lambda$4$Type",k1n="Node margin calculation",j1n="org.eclipse.elk.alg.layered.intermediate",E1n="ONE_SIDED_GREEDY_SWITCH",T1n="TWO_SIDED_GREEDY_SWITCH",M1n="No implementation is available for the layout processor ",S1n="IntermediateProcessorStrategy",P1n="Node '",I1n="FIRST_SEPARATE",C1n="LAST_SEPARATE",O1n="Odd port side processing",A1n="org.eclipse.elk.alg.layered.intermediate.compaction",$1n="org.eclipse.elk.alg.layered.intermediate.greedyswitch",L1n="org.eclipse.elk.alg.layered.p3order.counting",N1n={225:1},x1n="org.eclipse.elk.alg.layered.intermediate.loops",D1n="org.eclipse.elk.alg.layered.intermediate.loops.ordering",R1n="org.eclipse.elk.alg.layered.intermediate.loops.routing",_1n="org.eclipse.elk.alg.layered.intermediate.preserveorder",K1n="org.eclipse.elk.alg.layered.intermediate.wrapping",F1n="org.eclipse.elk.alg.layered.options",B1n="INTERACTIVE",H1n="DEPTH_FIRST",q1n="EDGE_LENGTH",G1n="SELF_LOOPS",z1n="firstTryWithInitialOrder",U1n="org.eclipse.elk.layered.directionCongruency",X1n="org.eclipse.elk.layered.feedbackEdges",W1n="org.eclipse.elk.layered.interactiveReferencePoint",V1n="org.eclipse.elk.layered.mergeEdges",Q1n="org.eclipse.elk.layered.mergeHierarchyEdges",Y1n="org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides",J1n="org.eclipse.elk.layered.portSortingStrategy",Z1n="org.eclipse.elk.layered.thoroughness",n0n="org.eclipse.elk.layered.unnecessaryBendpoints",t0n="org.eclipse.elk.layered.generatePositionAndLayerIds",e0n="org.eclipse.elk.layered.cycleBreaking.strategy",i0n="org.eclipse.elk.layered.layering.strategy",r0n="org.eclipse.elk.layered.layering.layerConstraint",c0n="org.eclipse.elk.layered.layering.layerChoiceConstraint",a0n="org.eclipse.elk.layered.layering.layerId",u0n="org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth",o0n="org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor",s0n="org.eclipse.elk.layered.layering.nodePromotion.strategy",h0n="org.eclipse.elk.layered.layering.nodePromotion.maxIterations",f0n="org.eclipse.elk.layered.layering.coffmanGraham.layerBound",l0n="org.eclipse.elk.layered.crossingMinimization.strategy",b0n="org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder",w0n="org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness",d0n="org.eclipse.elk.layered.crossingMinimization.semiInteractive",g0n="org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint",p0n="org.eclipse.elk.layered.crossingMinimization.positionId",v0n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold",m0n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.type",y0n="org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type",k0n="org.eclipse.elk.layered.nodePlacement.strategy",j0n="org.eclipse.elk.layered.nodePlacement.favorStraightEdges",E0n="org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening",T0n="org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment",M0n="org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening",S0n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility",P0n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default",I0n="org.eclipse.elk.layered.edgeRouting.selfLoopDistribution",C0n="org.eclipse.elk.layered.edgeRouting.selfLoopOrdering",O0n="org.eclipse.elk.layered.edgeRouting.splines.mode",A0n="org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor",$0n="org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth",L0n="org.eclipse.elk.layered.spacing.baseValue",N0n="org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers",x0n="org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers",D0n="org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers",R0n="org.eclipse.elk.layered.priority.direction",_0n="org.eclipse.elk.layered.priority.shortness",K0n="org.eclipse.elk.layered.priority.straightness",F0n="org.eclipse.elk.layered.compaction.connectedComponents",B0n="org.eclipse.elk.layered.compaction.postCompaction.strategy",H0n="org.eclipse.elk.layered.compaction.postCompaction.constraints",q0n="org.eclipse.elk.layered.highDegreeNodes.treatment",G0n="org.eclipse.elk.layered.highDegreeNodes.threshold",z0n="org.eclipse.elk.layered.highDegreeNodes.treeHeight",U0n="org.eclipse.elk.layered.wrapping.strategy",X0n="org.eclipse.elk.layered.wrapping.additionalEdgeSpacing",W0n="org.eclipse.elk.layered.wrapping.correctionFactor",V0n="org.eclipse.elk.layered.wrapping.cutting.strategy",Q0n="org.eclipse.elk.layered.wrapping.cutting.cuts",Y0n="org.eclipse.elk.layered.wrapping.cutting.msd.freedom",J0n="org.eclipse.elk.layered.wrapping.validify.strategy",Z0n="org.eclipse.elk.layered.wrapping.validify.forbiddenIndices",n2n="org.eclipse.elk.layered.wrapping.multiEdge.improveCuts",t2n="org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty",e2n="org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges",i2n="org.eclipse.elk.layered.edgeLabels.sideSelection",r2n="org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy",c2n="org.eclipse.elk.layered.considerModelOrder.strategy",a2n="org.eclipse.elk.layered.considerModelOrder.noModelOrder",u2n="org.eclipse.elk.layered.considerModelOrder.components",o2n="org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy",s2n="org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence",h2n="org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence",f2n="layering",l2n="layering.minWidth",b2n="layering.nodePromotion",w2n="crossingMinimization",d2n="org.eclipse.elk.hierarchyHandling",g2n="crossingMinimization.greedySwitch",p2n="nodePlacement",v2n="nodePlacement.bk",m2n="edgeRouting",y2n="org.eclipse.elk.edgeRouting",k2n="spacing",j2n="priority",E2n="compaction",T2n="compaction.postCompaction",M2n="Specifies whether and how post-process compaction is applied.",S2n="highDegreeNodes",P2n="wrapping",I2n="wrapping.cutting",C2n="wrapping.validify",O2n="wrapping.multiEdge",A2n="edgeLabels",$2n="considerModelOrder",L2n="org.eclipse.elk.spacing.commentComment",N2n="org.eclipse.elk.spacing.commentNode",x2n="org.eclipse.elk.spacing.edgeEdge",D2n="org.eclipse.elk.spacing.edgeNode",R2n="org.eclipse.elk.spacing.labelLabel",_2n="org.eclipse.elk.spacing.labelPortHorizontal",K2n="org.eclipse.elk.spacing.labelPortVertical",F2n="org.eclipse.elk.spacing.labelNode",B2n="org.eclipse.elk.spacing.nodeSelfLoop",H2n="org.eclipse.elk.spacing.portPort",q2n="org.eclipse.elk.spacing.individual",G2n="org.eclipse.elk.port.borderOffset",z2n="org.eclipse.elk.noLayout",U2n="org.eclipse.elk.port.side",X2n="org.eclipse.elk.debugMode",W2n="org.eclipse.elk.alignment",V2n="org.eclipse.elk.insideSelfLoops.activate",Q2n="org.eclipse.elk.insideSelfLoops.yo",Y2n="org.eclipse.elk.nodeSize.fixedGraphSize",J2n="org.eclipse.elk.direction",Z2n="org.eclipse.elk.nodeLabels.padding",n3n="org.eclipse.elk.portLabels.nextToPortIfPossible",t3n="org.eclipse.elk.portLabels.treatAsGroup",e3n="org.eclipse.elk.portAlignment.default",i3n="org.eclipse.elk.portAlignment.north",r3n="org.eclipse.elk.portAlignment.south",c3n="org.eclipse.elk.portAlignment.west",a3n="org.eclipse.elk.portAlignment.east",u3n="org.eclipse.elk.contentAlignment",o3n="org.eclipse.elk.junctionPoints",s3n="org.eclipse.elk.edgeLabels.placement",h3n="org.eclipse.elk.port.index",f3n="org.eclipse.elk.commentBox",l3n="org.eclipse.elk.hypernode",b3n="org.eclipse.elk.port.anchor",w3n="org.eclipse.elk.partitioning.activate",d3n="org.eclipse.elk.partitioning.partition",g3n="org.eclipse.elk.position",p3n="org.eclipse.elk.margins",v3n="org.eclipse.elk.spacing.portsSurrounding",m3n="org.eclipse.elk.interactiveLayout",y3n="org.eclipse.elk.core.util",k3n={3:1,4:1,5:1,593:1},j3n="NETWORK_SIMPLEX",E3n={123:1,51:1},T3n="org.eclipse.elk.alg.layered.p1cycles",M3n="org.eclipse.elk.alg.layered.p2layers",S3n={402:1,225:1},P3n={832:1,3:1,4:1},I3n="org.eclipse.elk.alg.layered.p3order",C3n="org.eclipse.elk.alg.layered.p4nodes",O3n={3:1,4:1,5:1,840:1},A3n=1e-5,$3n="org.eclipse.elk.alg.layered.p4nodes.bk",L3n="org.eclipse.elk.alg.layered.p5edges",N3n="org.eclipse.elk.alg.layered.p5edges.orthogonal",x3n="org.eclipse.elk.alg.layered.p5edges.orthogonal.direction",D3n=1e-6,R3n="org.eclipse.elk.alg.layered.p5edges.splines",_3n=.09999999999999998,K3n=1e-8,F3n=4.71238898038469,B3n=3.141592653589793,H3n="org.eclipse.elk.alg.mrtree",q3n="org.eclipse.elk.alg.mrtree.graph",G3n="org.eclipse.elk.alg.mrtree.intermediate",z3n="Set neighbors in level",U3n="DESCENDANTS",X3n="org.eclipse.elk.mrtree.weighting",W3n="org.eclipse.elk.mrtree.searchOrder",V3n="org.eclipse.elk.alg.mrtree.options",Q3n="org.eclipse.elk.mrtree",Y3n="org.eclipse.elk.tree",J3n="org.eclipse.elk.alg.radial",Z3n=6.283185307179586,n4n=5e-324,t4n="org.eclipse.elk.alg.radial.intermediate",e4n="org.eclipse.elk.alg.radial.intermediate.compaction",i4n={3:1,4:1,5:1,106:1},r4n="org.eclipse.elk.alg.radial.intermediate.optimization",c4n="No implementation is available for the layout option ",a4n="org.eclipse.elk.alg.radial.options",u4n="org.eclipse.elk.radial.orderId",o4n="org.eclipse.elk.radial.radius",s4n="org.eclipse.elk.radial.compactor",h4n="org.eclipse.elk.radial.compactionStepSize",f4n="org.eclipse.elk.radial.sorter",l4n="org.eclipse.elk.radial.wedgeCriteria",b4n="org.eclipse.elk.radial.optimizationCriteria",w4n="org.eclipse.elk.radial",d4n="org.eclipse.elk.alg.radial.p1position.wedge",g4n="org.eclipse.elk.alg.radial.sorting",p4n=5.497787143782138,v4n=3.9269908169872414,m4n=2.356194490192345,y4n="org.eclipse.elk.alg.rectpacking",k4n="org.eclipse.elk.alg.rectpacking.firstiteration",j4n="org.eclipse.elk.alg.rectpacking.options",E4n="org.eclipse.elk.rectpacking.optimizationGoal",T4n="org.eclipse.elk.rectpacking.lastPlaceShift",M4n="org.eclipse.elk.rectpacking.currentPosition",S4n="org.eclipse.elk.rectpacking.desiredPosition",P4n="org.eclipse.elk.rectpacking.onlyFirstIteration",I4n="org.eclipse.elk.rectpacking.rowCompaction",C4n="org.eclipse.elk.rectpacking.expandToAspectRatio",O4n="org.eclipse.elk.rectpacking.targetWidth",A4n="org.eclipse.elk.expandNodes",$4n="org.eclipse.elk.rectpacking",L4n="org.eclipse.elk.alg.rectpacking.util",N4n="No implementation available for ",x4n="org.eclipse.elk.alg.spore",D4n="org.eclipse.elk.alg.spore.options",R4n="org.eclipse.elk.sporeCompaction",_4n="org.eclipse.elk.underlyingLayoutAlgorithm",K4n="org.eclipse.elk.processingOrder.treeConstruction",F4n="org.eclipse.elk.processingOrder.spanningTreeCostFunction",B4n="org.eclipse.elk.processingOrder.preferredRoot",H4n="org.eclipse.elk.processingOrder.rootSelection",q4n="org.eclipse.elk.structure.structureExtractionStrategy",G4n="org.eclipse.elk.compaction.compactionStrategy",z4n="org.eclipse.elk.compaction.orthogonal",U4n="org.eclipse.elk.overlapRemoval.maxIterations",X4n="org.eclipse.elk.overlapRemoval.runScanline",W4n="processingOrder",V4n="overlapRemoval",Q4n="org.eclipse.elk.sporeOverlap",Y4n="org.eclipse.elk.alg.spore.p1structure",J4n="org.eclipse.elk.alg.spore.p2processingorder",Z4n="org.eclipse.elk.alg.spore.p3execution",n5n="Invalid index: ",t5n="org.eclipse.elk.core.alg",e5n={331:1},i5n={288:1},r5n="Make sure its type is registered with the ",c5n=" utility class.",a5n="true",u5n="false",o5n="Couldn't clone property '",s5n=.05,h5n="org.eclipse.elk.core.options",f5n=1.2999999523162842,l5n="org.eclipse.elk.box",b5n="org.eclipse.elk.box.packingMode",w5n="org.eclipse.elk.algorithm",d5n="org.eclipse.elk.resolvedAlgorithm",g5n="org.eclipse.elk.bendPoints",p5n="org.eclipse.elk.labelManager",v5n="org.eclipse.elk.scaleFactor",m5n="org.eclipse.elk.animate",y5n="org.eclipse.elk.animTimeFactor",k5n="org.eclipse.elk.layoutAncestors",j5n="org.eclipse.elk.maxAnimTime",E5n="org.eclipse.elk.minAnimTime",T5n="org.eclipse.elk.progressBar",M5n="org.eclipse.elk.validateGraph",S5n="org.eclipse.elk.validateOptions",P5n="org.eclipse.elk.zoomToFit",I5n="org.eclipse.elk.font.name",C5n="org.eclipse.elk.font.size",O5n="org.eclipse.elk.edge.type",A5n="partitioning",$5n="nodeLabels",L5n="portAlignment",N5n="nodeSize",x5n="port",D5n="portLabels",R5n="insideSelfLoops",_5n="org.eclipse.elk.fixed",K5n="org.eclipse.elk.random",F5n="port must have a parent node to calculate the port side",B5n="The edge needs to have exactly one edge section. Found: ",H5n="org.eclipse.elk.core.util.adapters",q5n="org.eclipse.emf.ecore",G5n="org.eclipse.elk.graph",z5n="EMapPropertyHolder",U5n="ElkBendPoint",X5n="ElkGraphElement",W5n="ElkConnectableShape",V5n="ElkEdge",Q5n="ElkEdgeSection",Y5n="EModelElement",J5n="ENamedElement",Z5n="ElkLabel",n6n="ElkNode",t6n="ElkPort",e6n={92:1,90:1},i6n="org.eclipse.emf.common.notify.impl",r6n="The feature '",c6n="' is not a valid changeable feature",a6n="Expecting null",u6n="' is not a valid feature",o6n="The feature ID",s6n=" is not a valid feature ID",h6n=32768,f6n={105:1,92:1,90:1,56:1,49:1,97:1},l6n="org.eclipse.emf.ecore.impl",b6n="org.eclipse.elk.graph.impl",w6n="Recursive containment not allowed for ",d6n="The datatype '",g6n="' is not a valid classifier",p6n="The value '",v6n={190:1,3:1,4:1},m6n="The class '",y6n="http://www.eclipse.org/elk/ElkGraph",k6n=1024,j6n="property",E6n="value",T6n="source",M6n="properties",S6n="identifier",P6n="height",I6n="width",C6n="parent",O6n="text",A6n="children",$6n="hierarchical",L6n="sources",N6n="targets",x6n="sections",D6n="bendPoints",R6n="outgoingShape",_6n="incomingShape",K6n="outgoingSections",F6n="incomingSections",B6n="org.eclipse.emf.common.util",H6n="Severe implementation error in the Json to ElkGraph importer.",q6n="id",G6n="org.eclipse.elk.graph.json",z6n="Unhandled parameter types: ",U6n="startPoint",X6n="An edge must have at least one source and one target (edge id: '",W6n="').",V6n="Referenced edge section does not exist: ",Q6n=" (edge id: '",Y6n="target",J6n="sourcePoint",Z6n="targetPoint",n8n="group",t8n="name",e8n="connectableShape cannot be null",i8n="edge cannot be null",r8n="Passed edge is not 'simple'.",c8n="org.eclipse.elk.graph.util",a8n="The 'no duplicates' constraint is violated",u8n="targetIndex=",o8n=", size=",s8n="sourceIndex=",h8n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1},f8n={3:1,4:1,20:1,28:1,52:1,14:1,47:1,15:1,54:1,67:1,63:1,58:1,588:1},l8n="logging",b8n="measureExecutionTime",w8n="parser.parse.1",d8n="parser.parse.2",g8n="parser.next.1",p8n="parser.next.2",v8n="parser.next.3",m8n="parser.next.4",y8n="parser.factor.1",k8n="parser.factor.2",j8n="parser.factor.3",E8n="parser.factor.4",T8n="parser.factor.5",M8n="parser.factor.6",S8n="parser.atom.1",P8n="parser.atom.2",I8n="parser.atom.3",C8n="parser.atom.4",O8n="parser.atom.5",A8n="parser.cc.1",$8n="parser.cc.2",L8n="parser.cc.3",N8n="parser.cc.5",x8n="parser.cc.6",D8n="parser.cc.7",R8n="parser.cc.8",_8n="parser.ope.1",K8n="parser.ope.2",F8n="parser.ope.3",B8n="parser.descape.1",H8n="parser.descape.2",q8n="parser.descape.3",G8n="parser.descape.4",z8n="parser.descape.5",U8n="parser.process.1",X8n="parser.quantifier.1",W8n="parser.quantifier.2",V8n="parser.quantifier.3",Q8n="parser.quantifier.4",Y8n="parser.quantifier.5",J8n="org.eclipse.emf.common.notify",Z8n={415:1,672:1},n9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1},t9n={366:1,143:1},e9n="index=",i9n={3:1,4:1,5:1,126:1},r9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,58:1},c9n={3:1,6:1,4:1,5:1,192:1},a9n={3:1,4:1,5:1,165:1,367:1},u9n=";/?:@&=+$,",o9n="invalid authority: ",s9n="EAnnotation",h9n="ETypedElement",f9n="EStructuralFeature",l9n="EAttribute",b9n="EClassifier",w9n="EEnumLiteral",d9n="EGenericType",g9n="EOperation",p9n="EParameter",v9n="EReference",m9n="ETypeParameter",y9n="org.eclipse.emf.ecore.util",k9n={76:1},j9n={3:1,20:1,14:1,15:1,58:1,589:1,76:1,69:1,95:1},E9n="org.eclipse.emf.ecore.util.FeatureMap$Entry",T9n=8192,M9n=2048,S9n="byte",P9n="char",I9n="double",C9n="float",O9n="int",A9n="long",$9n="short",L9n="java.lang.Object",N9n={3:1,4:1,5:1,247:1},x9n={3:1,4:1,5:1,673:1},D9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,69:1},R9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,69:1,95:1},_9n="mixed",K9n="http:///org/eclipse/emf/ecore/util/ExtendedMetaData",F9n="kind",B9n={3:1,4:1,5:1,674:1},H9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1,76:1,69:1,95:1},q9n={20:1,28:1,52:1,14:1,15:1,58:1,69:1},G9n={47:1,125:1,279:1},z9n={72:1,332:1},U9n="The value of type '",X9n="' must be of type '",W9n=1316,V9n="http://www.eclipse.org/emf/2002/Ecore",Q9n=-32768,Y9n="constraints",J9n="baseType",Z9n="getEStructuralFeature",n7n="getFeatureID",t7n="feature",e7n="getOperationID",i7n="operation",r7n="defaultValue",c7n="eTypeParameters",a7n="isInstance",u7n="getEEnumLiteral",o7n="eContainingClass",s7n={55:1},h7n={3:1,4:1,5:1,119:1},f7n="org.eclipse.emf.ecore.resource",l7n={92:1,90:1,591:1,1935:1},b7n="org.eclipse.emf.ecore.resource.impl",w7n="unspecified",d7n="simple",g7n="attribute",p7n="attributeWildcard",v7n="element",m7n="elementWildcard",y7n="collapse",k7n="itemType",j7n="namespace",E7n="##targetNamespace",T7n="whiteSpace",M7n="wildcards",S7n="http://www.eclipse.org/emf/2003/XMLType",P7n="##any",I7n="uninitialized",C7n="The multiplicity constraint is violated",O7n="org.eclipse.emf.ecore.xml.type",A7n="ProcessingInstruction",$7n="SimpleAnyType",L7n="XMLTypeDocumentRoot",N7n="org.eclipse.emf.ecore.xml.type.impl",x7n="INF",D7n="processing",R7n="ENTITIES_._base",_7n="minLength",K7n="ENTITY",F7n="NCName",B7n="IDREFS_._base",H7n="integer",q7n="token",G7n="pattern",z7n="[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",U7n="\\i\\c*",X7n="[\\i-[:]][\\c-[:]]*",W7n="nonPositiveInteger",V7n="maxInclusive",Q7n="NMTOKEN",Y7n="NMTOKENS_._base",J7n="nonNegativeInteger",Z7n="minInclusive",nnt="normalizedString",tnt="unsignedByte",ent="unsignedInt",int="18446744073709551615",rnt="unsignedShort",cnt="processingInstruction",ant="org.eclipse.emf.ecore.xml.type.internal",unt=1114111,ont="Internal Error: shorthands: \\u",snt="xml:isDigit",hnt="xml:isWord",fnt="xml:isSpace",lnt="xml:isNameChar",bnt="xml:isInitialNameChar",wnt="09\u0660\u0669\u06f0\u06f9\u0966\u096f\u09e6\u09ef\u0a66\u0a6f\u0ae6\u0aef\u0b66\u0b6f\u0be7\u0bef\u0c66\u0c6f\u0ce6\u0cef\u0d66\u0d6f\u0e50\u0e59\u0ed0\u0ed9\u0f20\u0f29",dnt="AZaz\xc0\xd6\xd8\xf6\xf8\u0131\u0134\u013e\u0141\u0148\u014a\u017e\u0180\u01c3\u01cd\u01f0\u01f4\u01f5\u01fa\u0217\u0250\u02a8\u02bb\u02c1\u0386\u0386\u0388\u038a\u038c\u038c\u038e\u03a1\u03a3\u03ce\u03d0\u03d6\u03da\u03da\u03dc\u03dc\u03de\u03de\u03e0\u03e0\u03e2\u03f3\u0401\u040c\u040e\u044f\u0451\u045c\u045e\u0481\u0490\u04c4\u04c7\u04c8\u04cb\u04cc\u04d0\u04eb\u04ee\u04f5\u04f8\u04f9\u0531\u0556\u0559\u0559\u0561\u0586\u05d0\u05ea\u05f0\u05f2\u0621\u063a\u0641\u064a\u0671\u06b7\u06ba\u06be\u06c0\u06ce\u06d0\u06d3\u06d5\u06d5\u06e5\u06e6\u0905\u0939\u093d\u093d\u0958\u0961\u0985\u098c\u098f\u0990\u0993\u09a8\u09aa\u09b0\u09b2\u09b2\u09b6\u09b9\u09dc\u09dd\u09df\u09e1\u09f0\u09f1\u0a05\u0a0a\u0a0f\u0a10\u0a13\u0a28\u0a2a\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59\u0a5c\u0a5e\u0a5e\u0a72\u0a74\u0a85\u0a8b\u0a8d\u0a8d\u0a8f\u0a91\u0a93\u0aa8\u0aaa\u0ab0\u0ab2\u0ab3\u0ab5\u0ab9\u0abd\u0abd\u0ae0\u0ae0\u0b05\u0b0c\u0b0f\u0b10\u0b13\u0b28\u0b2a\u0b30\u0b32\u0b33\u0b36\u0b39\u0b3d\u0b3d\u0b5c\u0b5d\u0b5f\u0b61\u0b85\u0b8a\u0b8e\u0b90\u0b92\u0b95\u0b99\u0b9a\u0b9c\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8\u0baa\u0bae\u0bb5\u0bb7\u0bb9\u0c05\u0c0c\u0c0e\u0c10\u0c12\u0c28\u0c2a\u0c33\u0c35\u0c39\u0c60\u0c61\u0c85\u0c8c\u0c8e\u0c90\u0c92\u0ca8\u0caa\u0cb3\u0cb5\u0cb9\u0cde\u0cde\u0ce0\u0ce1\u0d05\u0d0c\u0d0e\u0d10\u0d12\u0d28\u0d2a\u0d39\u0d60\u0d61\u0e01\u0e2e\u0e30\u0e30\u0e32\u0e33\u0e40\u0e45\u0e81\u0e82\u0e84\u0e84\u0e87\u0e88\u0e8a\u0e8a\u0e8d\u0e8d\u0e94\u0e97\u0e99\u0e9f\u0ea1\u0ea3\u0ea5\u0ea5\u0ea7\u0ea7\u0eaa\u0eab\u0ead\u0eae\u0eb0\u0eb0\u0eb2\u0eb3\u0ebd\u0ebd\u0ec0\u0ec4\u0f40\u0f47\u0f49\u0f69\u10a0\u10c5\u10d0\u10f6\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110b\u110c\u110e\u1112\u113c\u113c\u113e\u113e\u1140\u1140\u114c\u114c\u114e\u114e\u1150\u1150\u1154\u1155\u1159\u1159\u115f\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116d\u116e\u1172\u1173\u1175\u1175\u119e\u119e\u11a8\u11a8\u11ab\u11ab\u11ae\u11af\u11b7\u11b8\u11ba\u11ba\u11bc\u11c2\u11eb\u11eb\u11f0\u11f0\u11f9\u11f9\u1e00\u1e9b\u1ea0\u1ef9\u1f00\u1f15\u1f18\u1f1d\u1f20\u1f45\u1f48\u1f4d\u1f50\u1f57\u1f59\u1f59\u1f5b\u1f5b\u1f5d\u1f5d\u1f5f\u1f7d\u1f80\u1fb4\u1fb6\u1fbc\u1fbe\u1fbe\u1fc2\u1fc4\u1fc6\u1fcc\u1fd0\u1fd3\u1fd6\u1fdb\u1fe0\u1fec\u1ff2\u1ff4\u1ff6\u1ffc\u2126\u2126\u212a\u212b\u212e\u212e\u2180\u2182\u3007\u3007\u3021\u3029\u3041\u3094\u30a1\u30fa\u3105\u312c\u4e00\u9fa5\uac00\ud7a3",gnt="Private Use",pnt="ASSIGNED",vnt="\0\x7f\x80\xff\u0100\u017f\u0180\u024f\u0250\u02af\u02b0\u02ff\u0300\u036f\u0370\u03ff\u0400\u04ff\u0530\u058f\u0590\u05ff\u0600\u06ff\u0700\u074f\u0780\u07bf\u0900\u097f\u0980\u09ff\u0a00\u0a7f\u0a80\u0aff\u0b00\u0b7f\u0b80\u0bff\u0c00\u0c7f\u0c80\u0cff\u0d00\u0d7f\u0d80\u0dff\u0e00\u0e7f\u0e80\u0eff\u0f00\u0fff\u1000\u109f\u10a0\u10ff\u1100\u11ff\u1200\u137f\u13a0\u13ff\u1400\u167f\u1680\u169f\u16a0\u16ff\u1780\u17ff\u1800\u18af\u1e00\u1eff\u1f00\u1fff\u2000\u206f\u2070\u209f\u20a0\u20cf\u20d0\u20ff\u2100\u214f\u2150\u218f\u2190\u21ff\u2200\u22ff\u2300\u23ff\u2400\u243f\u2440\u245f\u2460\u24ff\u2500\u257f\u2580\u259f\u25a0\u25ff\u2600\u26ff\u2700\u27bf\u2800\u28ff\u2e80\u2eff\u2f00\u2fdf\u2ff0\u2fff\u3000\u303f\u3040\u309f\u30a0\u30ff\u3100\u312f\u3130\u318f\u3190\u319f\u31a0\u31bf\u3200\u32ff\u3300\u33ff\u3400\u4db5\u4e00\u9fff\ua000\ua48f\ua490\ua4cf\uac00\ud7a3\ue000\uf8ff\uf900\ufaff\ufb00\ufb4f\ufb50\ufdff\ufe20\ufe2f\ufe30\ufe4f\ufe50\ufe6f\ufe70\ufefe\ufeff\ufeff\uff00\uffef",mnt="UNASSIGNED",ynt={3:1,117:1},knt="org.eclipse.emf.ecore.xml.type.util",jnt={3:1,4:1,5:1,368:1},Ent="org.eclipse.xtext.xbase.lib",Tnt="Cannot add elements to a Range",Mnt="Cannot set elements in a Range",Snt="Cannot remove elements from a Range",Pnt="locale",Int="default",Cnt="user.agent";e.goog=e.goog||{},e.goog.global=e.goog.global||e,WMn(),wAn(1,null,{},r),MWn.Fb=function(n){return FO(this,n)},MWn.Gb=function(){return this.gm},MWn.Hb=function(){return PN(this)},MWn.Ib=function(){return nE(tsn(this))+"@"+(nsn(this)>>>0).toString(16)},MWn.equals=function(n){return this.Fb(n)},MWn.hashCode=function(){return this.Hb()},MWn.toString=function(){return this.Ib()},wAn(290,1,{290:1,2026:1},pon),MWn.le=function(n){var t;return(t=new pon).i=4,t.c=n>1?gZ(this,n-1):this,t},MWn.me=function(){return ED(this),this.b},MWn.ne=function(){return nE(this)},MWn.oe=function(){return ED(this),this.k},MWn.pe=function(){return 0!=(4&this.i)},MWn.qe=function(){return 0!=(1&this.i)},MWn.Ib=function(){return utn(this)},MWn.i=0;var Ont,Ant=vX(RWn,"Object",1),$nt=vX(RWn,"Class",290);wAn(1998,1,_Wn),vX(KWn,"Optional",1998),wAn(1170,1998,_Wn,c),MWn.Fb=function(n){return n===this},MWn.Hb=function(){return 2040732332},MWn.Ib=function(){return"Optional.absent()"},MWn.Jb=function(n){return yX(n),iy(),Ont},vX(KWn,"Absent",1170),wAn(628,1,{},mk),vX(KWn,"Joiner",628);var Lnt=bq(KWn,"Predicate");wAn(582,1,{169:1,582:1,3:1,45:1},Hf),MWn.Mb=function(n){return _on(this,n)},MWn.Lb=function(n){return _on(this,n)},MWn.Fb=function(n){var t;return!!cL(n,582)&&(t=BB(n,582),NAn(this.a,t.a))},MWn.Hb=function(){return Fon(this.a)+306654252},MWn.Ib=function(){return wPn(this.a)},vX(KWn,"Predicates/AndPredicate",582),wAn(408,1998,{408:1,3:1},qf),MWn.Fb=function(n){var t;return!!cL(n,408)&&(t=BB(n,408),Nfn(this.a,t.a))},MWn.Hb=function(){return 1502476572+nsn(this.a)},MWn.Ib=function(){return GWn+this.a+")"},MWn.Jb=function(n){return new qf(WQ(n.Kb(this.a),"the Function passed to Optional.transform() must not return null."))},vX(KWn,"Present",408),wAn(198,1,UWn),MWn.Nb=function(n){fU(this,n)},MWn.Qb=function(){bk()},vX(XWn,"UnmodifiableIterator",198),wAn(1978,198,WWn),MWn.Qb=function(){bk()},MWn.Rb=function(n){throw Hp(new pv)},MWn.Wb=function(n){throw Hp(new pv)},vX(XWn,"UnmodifiableListIterator",1978),wAn(386,1978,WWn),MWn.Ob=function(){return this.c<this.d},MWn.Sb=function(){return this.c>0},MWn.Pb=function(){if(this.c>=this.d)throw Hp(new yv);return this.Xb(this.c++)},MWn.Tb=function(){return this.c},MWn.Ub=function(){if(this.c<=0)throw Hp(new yv);return this.Xb(--this.c)},MWn.Vb=function(){return this.c-1},MWn.c=0,MWn.d=0,vX(XWn,"AbstractIndexedListIterator",386),wAn(699,198,UWn),MWn.Ob=function(){return Zin(this)},MWn.Pb=function(){return P7(this)},MWn.e=1,vX(XWn,"AbstractIterator",699),wAn(1986,1,{224:1}),MWn.Zb=function(){return this.f||(this.f=this.ac())},MWn.Fb=function(n){return jsn(this,n)},MWn.Hb=function(){return nsn(this.Zb())},MWn.dc=function(){return 0==this.gc()},MWn.ec=function(){return gz(this)},MWn.Ib=function(){return Bbn(this.Zb())},vX(XWn,"AbstractMultimap",1986),wAn(726,1986,VWn),MWn.$b=function(){win(this)},MWn._b=function(n){return Wj(this,n)},MWn.ac=function(){return new pT(this,this.c)},MWn.ic=function(n){return this.hc()},MWn.bc=function(){return new HL(this,this.c)},MWn.jc=function(){return this.mc(this.hc())},MWn.kc=function(){return new Hm(this)},MWn.lc=function(){return qTn(this.c.vc().Nc(),new u,64,this.d)},MWn.cc=function(n){return h6(this,n)},MWn.fc=function(n){return Nhn(this,n)},MWn.gc=function(){return this.d},MWn.mc=function(n){return SQ(),new Hb(n)},MWn.nc=function(){return new Bm(this)},MWn.oc=function(){return qTn(this.c.Cc().Nc(),new a,64,this.d)},MWn.pc=function(n,t){return new W6(this,n,t,null)},MWn.d=0,vX(XWn,"AbstractMapBasedMultimap",726),wAn(1631,726,VWn),MWn.hc=function(){return new J6(this.a)},MWn.jc=function(){return SQ(),SQ(),set},MWn.cc=function(n){return BB(h6(this,n),15)},MWn.fc=function(n){return BB(Nhn(this,n),15)},MWn.Zb=function(){return OQ(this)},MWn.Fb=function(n){return jsn(this,n)},MWn.qc=function(n){return BB(h6(this,n),15)},MWn.rc=function(n){return BB(Nhn(this,n),15)},MWn.mc=function(n){return rY(BB(n,15))},MWn.pc=function(n,t){return i3(this,n,BB(t,15),null)},vX(XWn,"AbstractListMultimap",1631),wAn(732,1,QWn),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return this.c.Ob()||this.e.Ob()},MWn.Pb=function(){var n;return this.e.Ob()||(n=BB(this.c.Pb(),42),this.b=n.cd(),this.a=BB(n.dd(),14),this.e=this.a.Kc()),this.sc(this.b,this.e.Pb())},MWn.Qb=function(){this.e.Qb(),this.a.dc()&&this.c.Qb(),--this.d.d},vX(XWn,"AbstractMapBasedMultimap/Itr",732),wAn(1099,732,QWn,Bm),MWn.sc=function(n,t){return t},vX(XWn,"AbstractMapBasedMultimap/1",1099),wAn(1100,1,{},a),MWn.Kb=function(n){return BB(n,14).Nc()},vX(XWn,"AbstractMapBasedMultimap/1methodref$spliterator$Type",1100),wAn(1101,732,QWn,Hm),MWn.sc=function(n,t){return new vT(n,t)},vX(XWn,"AbstractMapBasedMultimap/2",1101);var Nnt=bq(YWn,"Map");wAn(1967,1,JWn),MWn.wc=function(n){nan(this,n)},MWn.yc=function(n,t,e){return Zln(this,n,t,e)},MWn.$b=function(){this.vc().$b()},MWn.tc=function(n){return Mmn(this,n)},MWn._b=function(n){return!!FEn(this,n,!1)},MWn.uc=function(n){var t,e;for(t=this.vc().Kc();t.Ob();)if(e=BB(t.Pb(),42).dd(),GC(n)===GC(e)||null!=n&&Nfn(n,e))return!0;return!1},MWn.Fb=function(n){var t,e,i;if(n===this)return!0;if(!cL(n,83))return!1;if(i=BB(n,83),this.gc()!=i.gc())return!1;for(e=i.vc().Kc();e.Ob();)if(t=BB(e.Pb(),42),!this.tc(t))return!1;return!0},MWn.xc=function(n){return qC(FEn(this,n,!1))},MWn.Hb=function(){return Hun(this.vc())},MWn.dc=function(){return 0==this.gc()},MWn.ec=function(){return new Ib(this)},MWn.zc=function(n,t){throw Hp(new tk("Put not supported on this map"))},MWn.Ac=function(n){Tcn(this,n)},MWn.Bc=function(n){return qC(FEn(this,n,!0))},MWn.gc=function(){return this.vc().gc()},MWn.Ib=function(){return nTn(this)},MWn.Cc=function(){return new Ob(this)},vX(YWn,"AbstractMap",1967),wAn(1987,1967,JWn),MWn.bc=function(){return new ST(this)},MWn.vc=function(){return dz(this)},MWn.ec=function(){return this.g||(this.g=this.bc())},MWn.Cc=function(){return this.i||(this.i=new PT(this))},vX(XWn,"Maps/ViewCachingAbstractMap",1987),wAn(389,1987,JWn,pT),MWn.xc=function(n){return ktn(this,n)},MWn.Bc=function(n){return Zsn(this,n)},MWn.$b=function(){this.d==this.e.c?this.e.$b():Iq(new Oq(this))},MWn._b=function(n){return gfn(this.d,n)},MWn.Ec=function(){return new Xf(this)},MWn.Dc=function(){return this.Ec()},MWn.Fb=function(n){return this===n||Nfn(this.d,n)},MWn.Hb=function(){return nsn(this.d)},MWn.ec=function(){return this.e.ec()},MWn.gc=function(){return this.d.gc()},MWn.Ib=function(){return Bbn(this.d)},vX(XWn,"AbstractMapBasedMultimap/AsMap",389);var xnt=bq(RWn,"Iterable");wAn(28,1,ZWn),MWn.Jc=function(n){e5(this,n)},MWn.Lc=function(){return this.Oc()},MWn.Nc=function(){return new w1(this,0)},MWn.Oc=function(){return new Rq(null,this.Nc())},MWn.Fc=function(n){throw Hp(new tk("Add not supported on this collection"))},MWn.Gc=function(n){return Frn(this,n)},MWn.$b=function(){TV(this)},MWn.Hc=function(n){return ywn(this,n,!1)},MWn.Ic=function(n){return oun(this,n)},MWn.dc=function(){return 0==this.gc()},MWn.Mc=function(n){return ywn(this,n,!0)},MWn.Pc=function(){return cz(this)},MWn.Qc=function(n){return Emn(this,n)},MWn.Ib=function(){return LMn(this)},vX(YWn,"AbstractCollection",28);var Dnt=bq(YWn,"Set");wAn(nVn,28,tVn),MWn.Nc=function(){return new w1(this,1)},MWn.Fb=function(n){return ign(this,n)},MWn.Hb=function(){return Hun(this)},vX(YWn,"AbstractSet",nVn),wAn(1970,nVn,tVn),vX(XWn,"Sets/ImprovedAbstractSet",1970),wAn(1971,1970,tVn),MWn.$b=function(){this.Rc().$b()},MWn.Hc=function(n){return idn(this,n)},MWn.dc=function(){return this.Rc().dc()},MWn.Mc=function(n){var t;return!!this.Hc(n)&&(t=BB(n,42),this.Rc().ec().Mc(t.cd()))},MWn.gc=function(){return this.Rc().gc()},vX(XWn,"Maps/EntrySet",1971),wAn(1097,1971,tVn,Xf),MWn.Hc=function(n){return wfn(this.a.d.vc(),n)},MWn.Kc=function(){return new Oq(this.a)},MWn.Rc=function(){return this.a},MWn.Mc=function(n){var t;return!!wfn(this.a.d.vc(),n)&&(t=BB(n,42),H5(this.a.e,t.cd()),!0)},MWn.Nc=function(){return RB(this.a.d.vc().Nc(),new Wf(this.a))},vX(XWn,"AbstractMapBasedMultimap/AsMap/AsMapEntries",1097),wAn(1098,1,{},Wf),MWn.Kb=function(n){return i5(this.a,BB(n,42))},vX(XWn,"AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type",1098),wAn(730,1,QWn,Oq),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){var n;return n=BB(this.b.Pb(),42),this.a=BB(n.dd(),14),i5(this.c,n)},MWn.Ob=function(){return this.b.Ob()},MWn.Qb=function(){han(!!this.a),this.b.Qb(),this.c.e.d-=this.a.gc(),this.a.$b(),this.a=null},vX(XWn,"AbstractMapBasedMultimap/AsMap/AsMapIterator",730),wAn(532,1970,tVn,ST),MWn.$b=function(){this.b.$b()},MWn.Hc=function(n){return this.b._b(n)},MWn.Jc=function(n){yX(n),this.b.wc(new vl(n))},MWn.dc=function(){return this.b.dc()},MWn.Kc=function(){return new ly(this.b.vc().Kc())},MWn.Mc=function(n){return!!this.b._b(n)&&(this.b.Bc(n),!0)},MWn.gc=function(){return this.b.gc()},vX(XWn,"Maps/KeySet",532),wAn(318,532,tVn,HL),MWn.$b=function(){Iq(new eT(this,this.b.vc().Kc()))},MWn.Ic=function(n){return this.b.ec().Ic(n)},MWn.Fb=function(n){return this===n||Nfn(this.b.ec(),n)},MWn.Hb=function(){return nsn(this.b.ec())},MWn.Kc=function(){return new eT(this,this.b.vc().Kc())},MWn.Mc=function(n){var t,e;return e=0,(t=BB(this.b.Bc(n),14))&&(e=t.gc(),t.$b(),this.a.d-=e),e>0},MWn.Nc=function(){return this.b.ec().Nc()},vX(XWn,"AbstractMapBasedMultimap/KeySet",318),wAn(731,1,QWn,eT),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return this.c.Ob()},MWn.Pb=function(){return this.a=BB(this.c.Pb(),42),this.a.cd()},MWn.Qb=function(){var n;han(!!this.a),n=BB(this.a.dd(),14),this.c.Qb(),this.b.a.d-=n.gc(),n.$b(),this.a=null},vX(XWn,"AbstractMapBasedMultimap/KeySet/1",731),wAn(491,389,{83:1,161:1},ID),MWn.bc=function(){return this.Sc()},MWn.ec=function(){return this.Tc()},MWn.Sc=function(){return new nT(this.c,this.Uc())},MWn.Tc=function(){return this.b||(this.b=this.Sc())},MWn.Uc=function(){return BB(this.d,161)},vX(XWn,"AbstractMapBasedMultimap/SortedAsMap",491),wAn(542,491,eVn,CD),MWn.bc=function(){return new tT(this.a,BB(BB(this.d,161),171))},MWn.Sc=function(){return new tT(this.a,BB(BB(this.d,161),171))},MWn.ec=function(){return BB(this.b||(this.b=new tT(this.a,BB(BB(this.d,161),171))),271)},MWn.Tc=function(){return BB(this.b||(this.b=new tT(this.a,BB(BB(this.d,161),171))),271)},MWn.Uc=function(){return BB(BB(this.d,161),171)},vX(XWn,"AbstractMapBasedMultimap/NavigableAsMap",542),wAn(490,318,iVn,nT),MWn.Nc=function(){return this.b.ec().Nc()},vX(XWn,"AbstractMapBasedMultimap/SortedKeySet",490),wAn(388,490,rVn,tT),vX(XWn,"AbstractMapBasedMultimap/NavigableKeySet",388),wAn(541,28,ZWn,W6),MWn.Fc=function(n){var t,e;return zbn(this),e=this.d.dc(),(t=this.d.Fc(n))&&(++this.f.d,e&&jR(this)),t},MWn.Gc=function(n){var t,e,i;return!n.dc()&&(zbn(this),i=this.d.gc(),(t=this.d.Gc(n))&&(e=this.d.gc(),this.f.d+=e-i,0==i&&jR(this)),t)},MWn.$b=function(){var n;zbn(this),0!=(n=this.d.gc())&&(this.d.$b(),this.f.d-=n,$G(this))},MWn.Hc=function(n){return zbn(this),this.d.Hc(n)},MWn.Ic=function(n){return zbn(this),this.d.Ic(n)},MWn.Fb=function(n){return n===this||(zbn(this),Nfn(this.d,n))},MWn.Hb=function(){return zbn(this),nsn(this.d)},MWn.Kc=function(){return zbn(this),new QB(this)},MWn.Mc=function(n){var t;return zbn(this),(t=this.d.Mc(n))&&(--this.f.d,$G(this)),t},MWn.gc=function(){return tO(this)},MWn.Nc=function(){return zbn(this),this.d.Nc()},MWn.Ib=function(){return zbn(this),Bbn(this.d)},vX(XWn,"AbstractMapBasedMultimap/WrappedCollection",541);var Rnt=bq(YWn,"List");wAn(728,541,{20:1,28:1,14:1,15:1},sz),MWn.ad=function(n){Krn(this,n)},MWn.Nc=function(){return zbn(this),this.d.Nc()},MWn.Vc=function(n,t){var e;zbn(this),e=this.d.dc(),BB(this.d,15).Vc(n,t),++this.a.d,e&&jR(this)},MWn.Wc=function(n,t){var e,i,r;return!t.dc()&&(zbn(this),r=this.d.gc(),(e=BB(this.d,15).Wc(n,t))&&(i=this.d.gc(),this.a.d+=i-r,0==r&&jR(this)),e)},MWn.Xb=function(n){return zbn(this),BB(this.d,15).Xb(n)},MWn.Xc=function(n){return zbn(this),BB(this.d,15).Xc(n)},MWn.Yc=function(){return zbn(this),new g$(this)},MWn.Zc=function(n){return zbn(this),new gQ(this,n)},MWn.$c=function(n){var t;return zbn(this),t=BB(this.d,15).$c(n),--this.a.d,$G(this),t},MWn._c=function(n,t){return zbn(this),BB(this.d,15)._c(n,t)},MWn.bd=function(n,t){return zbn(this),i3(this.a,this.e,BB(this.d,15).bd(n,t),this.b?this.b:this)},vX(XWn,"AbstractMapBasedMultimap/WrappedList",728),wAn(1096,728,{20:1,28:1,14:1,15:1,54:1},Ox),vX(XWn,"AbstractMapBasedMultimap/RandomAccessWrappedList",1096),wAn(620,1,QWn,QB),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return MV(this),this.b.Ob()},MWn.Pb=function(){return MV(this),this.b.Pb()},MWn.Qb=function(){eN(this)},vX(XWn,"AbstractMapBasedMultimap/WrappedCollection/WrappedIterator",620),wAn(729,620,cVn,g$,gQ),MWn.Qb=function(){eN(this)},MWn.Rb=function(n){var t;t=0==tO(this.a),(MV(this),BB(this.b,125)).Rb(n),++this.a.a.d,t&&jR(this.a)},MWn.Sb=function(){return(MV(this),BB(this.b,125)).Sb()},MWn.Tb=function(){return(MV(this),BB(this.b,125)).Tb()},MWn.Ub=function(){return(MV(this),BB(this.b,125)).Ub()},MWn.Vb=function(){return(MV(this),BB(this.b,125)).Vb()},MWn.Wb=function(n){(MV(this),BB(this.b,125)).Wb(n)},vX(XWn,"AbstractMapBasedMultimap/WrappedList/WrappedListIterator",729),wAn(727,541,iVn,ND),MWn.Nc=function(){return zbn(this),this.d.Nc()},vX(XWn,"AbstractMapBasedMultimap/WrappedSortedSet",727),wAn(1095,727,rVn,AA),vX(XWn,"AbstractMapBasedMultimap/WrappedNavigableSet",1095),wAn(1094,541,tVn,xD),MWn.Nc=function(){return zbn(this),this.d.Nc()},vX(XWn,"AbstractMapBasedMultimap/WrappedSet",1094),wAn(1103,1,{},u),MWn.Kb=function(n){return F6(BB(n,42))},vX(XWn,"AbstractMapBasedMultimap/lambda$1$Type",1103),wAn(1102,1,{},Vf),MWn.Kb=function(n){return new vT(this.a,n)},vX(XWn,"AbstractMapBasedMultimap/lambda$2$Type",1102);var _nt,Knt,Fnt,Bnt,Hnt=bq(YWn,"Map/Entry");wAn(345,1,aVn),MWn.Fb=function(n){var t;return!!cL(n,42)&&(t=BB(n,42),wW(this.cd(),t.cd())&&wW(this.dd(),t.dd()))},MWn.Hb=function(){var n,t;return n=this.cd(),t=this.dd(),(null==n?0:nsn(n))^(null==t?0:nsn(t))},MWn.ed=function(n){throw Hp(new pv)},MWn.Ib=function(){return this.cd()+"="+this.dd()},vX(XWn,uVn,345),wAn(1988,28,ZWn),MWn.$b=function(){this.fd().$b()},MWn.Hc=function(n){var t;return!!cL(n,42)&&(t=BB(n,42),H0(this.fd(),t.cd(),t.dd()))},MWn.Mc=function(n){var t;return!!cL(n,42)&&(t=BB(n,42),q0(this.fd(),t.cd(),t.dd()))},MWn.gc=function(){return this.fd().d},vX(XWn,"Multimaps/Entries",1988),wAn(733,1988,ZWn,Qf),MWn.Kc=function(){return this.a.kc()},MWn.fd=function(){return this.a},MWn.Nc=function(){return this.a.lc()},vX(XWn,"AbstractMultimap/Entries",733),wAn(734,733,tVn,qm),MWn.Nc=function(){return this.a.lc()},MWn.Fb=function(n){return zSn(this,n)},MWn.Hb=function(){return Brn(this)},vX(XWn,"AbstractMultimap/EntrySet",734),wAn(735,28,ZWn,Yf),MWn.$b=function(){this.a.$b()},MWn.Hc=function(n){return Csn(this.a,n)},MWn.Kc=function(){return this.a.nc()},MWn.gc=function(){return this.a.d},MWn.Nc=function(){return this.a.oc()},vX(XWn,"AbstractMultimap/Values",735),wAn(1989,28,{835:1,20:1,28:1,14:1}),MWn.Jc=function(n){yX(n),EV(this).Jc(new pl(n))},MWn.Nc=function(){var n;return qTn(n=EV(this).Nc(),new y,64|1296&n.qd(),this.a.d)},MWn.Fc=function(n){return wk(),!0},MWn.Gc=function(n){return yX(this),yX(n),cL(n,543)?l2(BB(n,835)):!n.dc()&&fnn(this,n.Kc())},MWn.Hc=function(n){var t;return((t=BB(lfn(OQ(this.a),n),14))?t.gc():0)>0},MWn.Fb=function(n){return h$n(this,n)},MWn.Hb=function(){return nsn(EV(this))},MWn.dc=function(){return EV(this).dc()},MWn.Mc=function(n){return ECn(this,n,1)>0},MWn.Ib=function(){return Bbn(EV(this))},vX(XWn,"AbstractMultiset",1989),wAn(1991,1970,tVn),MWn.$b=function(){win(this.a.a)},MWn.Hc=function(n){var t;return!(!cL(n,492)||(t=BB(n,416),BB(t.a.dd(),14).gc()<=0||c1(this.a,t.a.cd())!=BB(t.a.dd(),14).gc()))},MWn.Mc=function(n){var t,e,i;return!(!cL(n,492)||(t=(e=BB(n,416)).a.cd(),0==(i=BB(e.a.dd(),14).gc())))&&TCn(this.a,t,i)},vX(XWn,"Multisets/EntrySet",1991),wAn(1109,1991,tVn,Jf),MWn.Kc=function(){return new wy(dz(OQ(this.a.a)).Kc())},MWn.gc=function(){return OQ(this.a.a).gc()},vX(XWn,"AbstractMultiset/EntrySet",1109),wAn(619,726,VWn),MWn.hc=function(){return this.gd()},MWn.jc=function(){return this.hd()},MWn.cc=function(n){return this.jd(n)},MWn.fc=function(n){return this.kd(n)},MWn.Zb=function(){return this.f||(this.f=this.ac())},MWn.hd=function(){return SQ(),SQ(),fet},MWn.Fb=function(n){return jsn(this,n)},MWn.jd=function(n){return BB(h6(this,n),21)},MWn.kd=function(n){return BB(Nhn(this,n),21)},MWn.mc=function(n){return SQ(),new Ak(BB(n,21))},MWn.pc=function(n,t){return new xD(this,n,BB(t,21))},vX(XWn,"AbstractSetMultimap",619),wAn(1657,619,VWn),MWn.hc=function(){return new dE(this.b)},MWn.gd=function(){return new dE(this.b)},MWn.jc=function(){return CX(new dE(this.b))},MWn.hd=function(){return CX(new dE(this.b))},MWn.cc=function(n){return BB(BB(h6(this,n),21),84)},MWn.jd=function(n){return BB(BB(h6(this,n),21),84)},MWn.fc=function(n){return BB(BB(Nhn(this,n),21),84)},MWn.kd=function(n){return BB(BB(Nhn(this,n),21),84)},MWn.mc=function(n){return cL(n,271)?CX(BB(n,271)):(SQ(),new dN(BB(n,84)))},MWn.Zb=function(){return this.f||(this.f=cL(this.c,171)?new CD(this,BB(this.c,171)):cL(this.c,161)?new ID(this,BB(this.c,161)):new pT(this,this.c))},MWn.pc=function(n,t){return cL(t,271)?new AA(this,n,BB(t,271)):new ND(this,n,BB(t,84))},vX(XWn,"AbstractSortedSetMultimap",1657),wAn(1658,1657,VWn),MWn.Zb=function(){return BB(BB(this.f||(this.f=cL(this.c,171)?new CD(this,BB(this.c,171)):cL(this.c,161)?new ID(this,BB(this.c,161)):new pT(this,this.c)),161),171)},MWn.ec=function(){return BB(BB(this.i||(this.i=cL(this.c,171)?new tT(this,BB(this.c,171)):cL(this.c,161)?new nT(this,BB(this.c,161)):new HL(this,this.c)),84),271)},MWn.bc=function(){return cL(this.c,171)?new tT(this,BB(this.c,171)):cL(this.c,161)?new nT(this,BB(this.c,161)):new HL(this,this.c)},vX(XWn,"AbstractSortedKeySortedSetMultimap",1658),wAn(2010,1,{1947:1}),MWn.Fb=function(n){return Ijn(this,n)},MWn.Hb=function(){return Hun(this.g||(this.g=new Zf(this)))},MWn.Ib=function(){return nTn(this.f||(this.f=new UL(this)))},vX(XWn,"AbstractTable",2010),wAn(665,nVn,tVn,Zf),MWn.$b=function(){dk()},MWn.Hc=function(n){var t,e;return!!cL(n,468)&&(t=BB(n,682),!!(e=BB(lfn(jX(this.a),WC(t.c.e,t.b)),83))&&wfn(e.vc(),new vT(WC(t.c.c,t.a),U6(t.c,t.b,t.a))))},MWn.Kc=function(){return ZQ(this.a)},MWn.Mc=function(n){var t,e;return!!cL(n,468)&&(t=BB(n,682),!!(e=BB(lfn(jX(this.a),WC(t.c.e,t.b)),83))&&dfn(e.vc(),new vT(WC(t.c.c,t.a),U6(t.c,t.b,t.a))))},MWn.gc=function(){return zq(this.a)},MWn.Nc=function(){return P2(this.a)},vX(XWn,"AbstractTable/CellSet",665),wAn(1928,28,ZWn,nl),MWn.$b=function(){dk()},MWn.Hc=function(n){return hTn(this.a,n)},MWn.Kc=function(){return nY(this.a)},MWn.gc=function(){return zq(this.a)},MWn.Nc=function(){return Y0(this.a)},vX(XWn,"AbstractTable/Values",1928),wAn(1632,1631,VWn),vX(XWn,"ArrayListMultimapGwtSerializationDependencies",1632),wAn(513,1632,VWn,ok,o1),MWn.hc=function(){return new J6(this.a)},MWn.a=0,vX(XWn,"ArrayListMultimap",513),wAn(664,2010,{664:1,1947:1,3:1},vOn),vX(XWn,"ArrayTable",664),wAn(1924,386,WWn,qL),MWn.Xb=function(n){return new gon(this.a,n)},vX(XWn,"ArrayTable/1",1924),wAn(1925,1,{},Gf),MWn.ld=function(n){return new gon(this.a,n)},vX(XWn,"ArrayTable/1methodref$getCell$Type",1925),wAn(2011,1,{682:1}),MWn.Fb=function(n){var t;return n===this||!!cL(n,468)&&(t=BB(n,682),wW(WC(this.c.e,this.b),WC(t.c.e,t.b))&&wW(WC(this.c.c,this.a),WC(t.c.c,t.a))&&wW(U6(this.c,this.b,this.a),U6(t.c,t.b,t.a)))},MWn.Hb=function(){return fhn(Pun(Gk(Ant,1),HWn,1,5,[WC(this.c.e,this.b),WC(this.c.c,this.a),U6(this.c,this.b,this.a)]))},MWn.Ib=function(){return"("+WC(this.c.e,this.b)+","+WC(this.c.c,this.a)+")="+U6(this.c,this.b,this.a)},vX(XWn,"Tables/AbstractCell",2011),wAn(468,2011,{468:1,682:1},gon),MWn.a=0,MWn.b=0,MWn.d=0,vX(XWn,"ArrayTable/2",468),wAn(1927,1,{},zf),MWn.ld=function(n){return Y9(this.a,n)},vX(XWn,"ArrayTable/2methodref$getValue$Type",1927),wAn(1926,386,WWn,GL),MWn.Xb=function(n){return Y9(this.a,n)},vX(XWn,"ArrayTable/3",1926),wAn(1979,1967,JWn),MWn.$b=function(){Iq(this.kc())},MWn.vc=function(){return new ml(this)},MWn.lc=function(){return new IV(this.kc(),this.gc())},vX(XWn,"Maps/IteratorBasedAbstractMap",1979),wAn(828,1979,JWn),MWn.$b=function(){throw Hp(new pv)},MWn._b=function(n){return Yj(this.c,n)},MWn.kc=function(){return new zL(this,this.c.b.c.gc())},MWn.lc=function(){return yq(this.c.b.c.gc(),16,new Uf(this))},MWn.xc=function(n){var t;return(t=BB(U_(this.c,n),19))?this.nd(t.a):null},MWn.dc=function(){return this.c.b.c.dc()},MWn.ec=function(){return bz(this.c)},MWn.zc=function(n,t){var e;if(!(e=BB(U_(this.c,n),19)))throw Hp(new Ky(this.md()+" "+n+" not in "+bz(this.c)));return this.od(e.a,t)},MWn.Bc=function(n){throw Hp(new pv)},MWn.gc=function(){return this.c.b.c.gc()},vX(XWn,"ArrayTable/ArrayMap",828),wAn(1923,1,{},Uf),MWn.ld=function(n){return OX(this.a,n)},vX(XWn,"ArrayTable/ArrayMap/0methodref$getEntry$Type",1923),wAn(1921,345,aVn,sT),MWn.cd=function(){return YL(this.a,this.b)},MWn.dd=function(){return this.a.nd(this.b)},MWn.ed=function(n){return this.a.od(this.b,n)},MWn.b=0,vX(XWn,"ArrayTable/ArrayMap/1",1921),wAn(1922,386,WWn,zL),MWn.Xb=function(n){return OX(this.a,n)},vX(XWn,"ArrayTable/ArrayMap/2",1922),wAn(1920,828,JWn,cU),MWn.md=function(){return"Column"},MWn.nd=function(n){return U6(this.b,this.a,n)},MWn.od=function(n,t){return Sun(this.b,this.a,n,t)},MWn.a=0,vX(XWn,"ArrayTable/Row",1920),wAn(829,828,JWn,UL),MWn.nd=function(n){return new cU(this.a,n)},MWn.zc=function(n,t){return BB(t,83),gk()},MWn.od=function(n,t){return BB(t,83),pk()},MWn.md=function(){return"Row"},vX(XWn,"ArrayTable/RowMap",829),wAn(1120,1,fVn,hT),MWn.qd=function(){return-262&this.a.qd()},MWn.rd=function(){return this.a.rd()},MWn.Nb=function(n){this.a.Nb(new cT(n,this.b))},MWn.sd=function(n){return this.a.sd(new rT(n,this.b))},vX(XWn,"CollectSpliterators/1",1120),wAn(1121,1,lVn,rT),MWn.td=function(n){this.a.td(this.b.Kb(n))},vX(XWn,"CollectSpliterators/1/lambda$0$Type",1121),wAn(1122,1,lVn,cT),MWn.td=function(n){this.a.td(this.b.Kb(n))},vX(XWn,"CollectSpliterators/1/lambda$1$Type",1122),wAn(1123,1,fVn,q2),MWn.qd=function(){return this.a},MWn.rd=function(){return this.d&&(this.b=T$(this.b,this.d.rd())),T$(this.b,0)},MWn.Nb=function(n){this.d&&(this.d.Nb(n),this.d=null),this.c.Nb(new iT(this.e,n)),this.b=0},MWn.sd=function(n){for(;;){if(this.d&&this.d.sd(n))return JC(this.b,bVn)&&(this.b=ibn(this.b,1)),!0;if(this.d=null,!this.c.sd(new aT(this,this.e)))return!1}},MWn.a=0,MWn.b=0,vX(XWn,"CollectSpliterators/1FlatMapSpliterator",1123),wAn(1124,1,lVn,aT),MWn.td=function(n){d_(this.a,this.b,n)},vX(XWn,"CollectSpliterators/1FlatMapSpliterator/lambda$0$Type",1124),wAn(1125,1,lVn,iT),MWn.td=function(n){oL(this.b,this.a,n)},vX(XWn,"CollectSpliterators/1FlatMapSpliterator/lambda$1$Type",1125),wAn(1117,1,fVn,w_),MWn.qd=function(){return 16464|this.b},MWn.rd=function(){return this.a.rd()},MWn.Nb=function(n){this.a.xe(new oT(n,this.c))},MWn.sd=function(n){return this.a.ye(new uT(n,this.c))},MWn.b=0,vX(XWn,"CollectSpliterators/1WithCharacteristics",1117),wAn(1118,1,wVn,uT),MWn.ud=function(n){this.a.td(this.b.ld(n))},vX(XWn,"CollectSpliterators/1WithCharacteristics/lambda$0$Type",1118),wAn(1119,1,wVn,oT),MWn.ud=function(n){this.a.td(this.b.ld(n))},vX(XWn,"CollectSpliterators/1WithCharacteristics/lambda$1$Type",1119),wAn(245,1,dVn),MWn.wd=function(n){return this.vd(BB(n,245))},MWn.vd=function(n){var t;return n==(ty(),Knt)?1:n==(ey(),_nt)?-1:(nq(),0!=(t=Ncn(this.a,n.a))?t:cL(this,519)==cL(n,519)?0:cL(this,519)?1:-1)},MWn.zd=function(){return this.a},MWn.Fb=function(n){return xdn(this,n)},vX(XWn,"Cut",245),wAn(1761,245,dVn,Nk),MWn.vd=function(n){return n==this?0:1},MWn.xd=function(n){throw Hp(new hv)},MWn.yd=function(n){n.a+="+\u221e)"},MWn.zd=function(){throw Hp(new Fy(gVn))},MWn.Hb=function(){return $T(),evn(this)},MWn.Ad=function(n){return!1},MWn.Ib=function(){return"+\u221e"},vX(XWn,"Cut/AboveAll",1761),wAn(519,245,{245:1,519:1,3:1,35:1},iN),MWn.xd=function(n){uO((n.a+="(",n),this.a)},MWn.yd=function(n){xX(uO(n,this.a),93)},MWn.Hb=function(){return~nsn(this.a)},MWn.Ad=function(n){return nq(),Ncn(this.a,n)<0},MWn.Ib=function(){return"/"+this.a+"\\"},vX(XWn,"Cut/AboveValue",519),wAn(1760,245,dVn,xk),MWn.vd=function(n){return n==this?0:-1},MWn.xd=function(n){n.a+="(-\u221e"},MWn.yd=function(n){throw Hp(new hv)},MWn.zd=function(){throw Hp(new Fy(gVn))},MWn.Hb=function(){return $T(),evn(this)},MWn.Ad=function(n){return!0},MWn.Ib=function(){return"-\u221e"},vX(XWn,"Cut/BelowAll",1760),wAn(1762,245,dVn,rN),MWn.xd=function(n){uO((n.a+="[",n),this.a)},MWn.yd=function(n){xX(uO(n,this.a),41)},MWn.Hb=function(){return nsn(this.a)},MWn.Ad=function(n){return nq(),Ncn(this.a,n)<=0},MWn.Ib=function(){return"\\"+this.a+"/"},vX(XWn,"Cut/BelowValue",1762),wAn(537,1,pVn),MWn.Jc=function(n){e5(this,n)},MWn.Ib=function(){return Hln(BB(WQ(this,"use Optional.orNull() instead of Optional.or(null)"),20).Kc())},vX(XWn,"FluentIterable",537),wAn(433,537,pVn,OO),MWn.Kc=function(){return new oz(ZL(this.a.Kc(),new h))},vX(XWn,"FluentIterable/2",433),wAn(1046,537,pVn,AO),MWn.Kc=function(){return NU(this)},vX(XWn,"FluentIterable/3",1046),wAn(708,386,WWn,WL),MWn.Xb=function(n){return this.a[n].Kc()},vX(XWn,"FluentIterable/3/1",708),wAn(1972,1,{}),MWn.Ib=function(){return Bbn(this.Bd().b)},vX(XWn,"ForwardingObject",1972),wAn(1973,1972,vVn),MWn.Bd=function(){return this.Cd()},MWn.Jc=function(n){e5(this,n)},MWn.Lc=function(){return this.Oc()},MWn.Nc=function(){return new w1(this,0)},MWn.Oc=function(){return new Rq(null,this.Nc())},MWn.Fc=function(n){return this.Cd(),oE()},MWn.Gc=function(n){return this.Cd(),sE()},MWn.$b=function(){this.Cd(),hE()},MWn.Hc=function(n){return this.Cd().Hc(n)},MWn.Ic=function(n){return this.Cd().Ic(n)},MWn.dc=function(){return this.Cd().b.dc()},MWn.Kc=function(){return this.Cd().Kc()},MWn.Mc=function(n){return this.Cd(),fE()},MWn.gc=function(){return this.Cd().b.gc()},MWn.Pc=function(){return this.Cd().Pc()},MWn.Qc=function(n){return this.Cd().Qc(n)},vX(XWn,"ForwardingCollection",1973),wAn(1980,28,mVn),MWn.Kc=function(){return this.Ed()},MWn.Fc=function(n){throw Hp(new pv)},MWn.Gc=function(n){throw Hp(new pv)},MWn.$b=function(){throw Hp(new pv)},MWn.Hc=function(n){return null!=n&&ywn(this,n,!1)},MWn.Dd=function(){switch(this.gc()){case 0:return WX(),WX(),Fnt;case 1:return WX(),new Pq(yX(this.Ed().Pb()));default:return new aU(this,this.Pc())}},MWn.Mc=function(n){throw Hp(new pv)},vX(XWn,"ImmutableCollection",1980),wAn(712,1980,mVn,rv),MWn.Kc=function(){return L9(this.a.Kc())},MWn.Hc=function(n){return null!=n&&this.a.Hc(n)},MWn.Ic=function(n){return this.a.Ic(n)},MWn.dc=function(){return this.a.dc()},MWn.Ed=function(){return L9(this.a.Kc())},MWn.gc=function(){return this.a.gc()},MWn.Pc=function(){return this.a.Pc()},MWn.Qc=function(n){return this.a.Qc(n)},MWn.Ib=function(){return Bbn(this.a)},vX(XWn,"ForwardingImmutableCollection",712),wAn(152,1980,yVn),MWn.Kc=function(){return this.Ed()},MWn.Yc=function(){return this.Fd(0)},MWn.Zc=function(n){return this.Fd(n)},MWn.ad=function(n){Krn(this,n)},MWn.Nc=function(){return new w1(this,16)},MWn.bd=function(n,t){return this.Gd(n,t)},MWn.Vc=function(n,t){throw Hp(new pv)},MWn.Wc=function(n,t){throw Hp(new pv)},MWn.Fb=function(n){return qAn(this,n)},MWn.Hb=function(){return Can(this)},MWn.Xc=function(n){return null==n?-1:Tmn(this,n)},MWn.Ed=function(){return this.Fd(0)},MWn.Fd=function(n){return ix(this,n)},MWn.$c=function(n){throw Hp(new pv)},MWn._c=function(n,t){throw Hp(new pv)},MWn.Gd=function(n,t){return sfn(new s1(new CT(this),n,t))},vX(XWn,"ImmutableList",152),wAn(2006,152,yVn),MWn.Kc=function(){return L9(this.Hd().Kc())},MWn.bd=function(n,t){return sfn(this.Hd().bd(n,t))},MWn.Hc=function(n){return null!=n&&this.Hd().Hc(n)},MWn.Ic=function(n){return this.Hd().Ic(n)},MWn.Fb=function(n){return Nfn(this.Hd(),n)},MWn.Xb=function(n){return WC(this,n)},MWn.Hb=function(){return nsn(this.Hd())},MWn.Xc=function(n){return this.Hd().Xc(n)},MWn.dc=function(){return this.Hd().dc()},MWn.Ed=function(){return L9(this.Hd().Kc())},MWn.gc=function(){return this.Hd().gc()},MWn.Gd=function(n,t){return sfn(this.Hd().bd(n,t))},MWn.Pc=function(){return this.Hd().Qc(x8(Ant,HWn,1,this.Hd().gc(),5,1))},MWn.Qc=function(n){return this.Hd().Qc(n)},MWn.Ib=function(){return Bbn(this.Hd())},vX(XWn,"ForwardingImmutableList",2006),wAn(714,1,jVn),MWn.vc=function(){return lz(this)},MWn.wc=function(n){nan(this,n)},MWn.ec=function(){return bz(this)},MWn.yc=function(n,t,e){return Zln(this,n,t,e)},MWn.Cc=function(){return this.Ld()},MWn.$b=function(){throw Hp(new pv)},MWn._b=function(n){return null!=this.xc(n)},MWn.uc=function(n){return this.Ld().Hc(n)},MWn.Jd=function(){return new cv(this)},MWn.Kd=function(){return new av(this)},MWn.Fb=function(n){return $sn(this,n)},MWn.Hb=function(){return lz(this).Hb()},MWn.dc=function(){return 0==this.gc()},MWn.zc=function(n,t){return vk()},MWn.Bc=function(n){throw Hp(new pv)},MWn.Ib=function(){return fSn(this)},MWn.Ld=function(){return this.e?this.e:this.e=this.Kd()},MWn.c=null,MWn.d=null,MWn.e=null,vX(XWn,"ImmutableMap",714),wAn(715,714,jVn),MWn._b=function(n){return Yj(this,n)},MWn.uc=function(n){return KT(this.b,n)},MWn.Id=function(){return hfn(new el(this))},MWn.Jd=function(){return hfn(iV(this.b))},MWn.Kd=function(){return sK(),new rv(tV(this.b))},MWn.Fb=function(n){return BT(this.b,n)},MWn.xc=function(n){return U_(this,n)},MWn.Hb=function(){return nsn(this.b.c)},MWn.dc=function(){return this.b.c.dc()},MWn.gc=function(){return this.b.c.gc()},MWn.Ib=function(){return Bbn(this.b.c)},vX(XWn,"ForwardingImmutableMap",715),wAn(1974,1973,EVn),MWn.Bd=function(){return this.Md()},MWn.Cd=function(){return this.Md()},MWn.Nc=function(){return new w1(this,1)},MWn.Fb=function(n){return n===this||this.Md().Fb(n)},MWn.Hb=function(){return this.Md().Hb()},vX(XWn,"ForwardingSet",1974),wAn(1069,1974,EVn,el),MWn.Bd=function(){return eV(this.a.b)},MWn.Cd=function(){return eV(this.a.b)},MWn.Hc=function(n){if(cL(n,42)&&null==BB(n,42).cd())return!1;try{return _T(eV(this.a.b),n)}catch(t){if(cL(t=lun(t),205))return!1;throw Hp(t)}},MWn.Md=function(){return eV(this.a.b)},MWn.Qc=function(n){var t;return t=CY(eV(this.a.b),n),eV(this.a.b).b.gc()<t.length&&$X(t,eV(this.a.b).b.gc(),null),t},vX(XWn,"ForwardingImmutableMap/1",1069),wAn(1981,1980,TVn),MWn.Kc=function(){return this.Ed()},MWn.Nc=function(){return new w1(this,1)},MWn.Fb=function(n){return zSn(this,n)},MWn.Hb=function(){return Brn(this)},vX(XWn,"ImmutableSet",1981),wAn(703,1981,TVn),MWn.Kc=function(){return L9(new qb(this.a.b.Kc()))},MWn.Hc=function(n){return null!=n&&xT(this.a,n)},MWn.Ic=function(n){return DT(this.a,n)},MWn.Hb=function(){return nsn(this.a.b)},MWn.dc=function(){return this.a.b.dc()},MWn.Ed=function(){return L9(new qb(this.a.b.Kc()))},MWn.gc=function(){return this.a.b.gc()},MWn.Pc=function(){return this.a.b.Pc()},MWn.Qc=function(n){return RT(this.a,n)},MWn.Ib=function(){return Bbn(this.a.b)},vX(XWn,"ForwardingImmutableSet",703),wAn(1975,1974,MVn),MWn.Bd=function(){return this.b},MWn.Cd=function(){return this.b},MWn.Md=function(){return this.b},MWn.Nc=function(){return new wS(this)},vX(XWn,"ForwardingSortedSet",1975),wAn(533,1979,jVn,Avn),MWn.Ac=function(n){Tcn(this,n)},MWn.Cc=function(){return new p$(this.d||(this.d=new il(this)))},MWn.$b=function(){d5(this)},MWn._b=function(n){return!!Jrn(this,n,dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15))))},MWn.uc=function(n){return Ltn(this,n)},MWn.kc=function(){return new VL(this,this)},MWn.wc=function(n){BJ(this,n)},MWn.xc=function(n){return sen(this,n)},MWn.ec=function(){return new v$(this)},MWn.zc=function(n,t){return w_n(this,n,t)},MWn.Bc=function(n){var t;return(t=Jrn(this,n,dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15)))))?(LLn(this,t),t.e=null,t.c=null,t.i):null},MWn.gc=function(){return this.i},MWn.pd=function(){return new p$(this.d||(this.d=new il(this)))},MWn.f=0,MWn.g=0,MWn.i=0,vX(XWn,"HashBiMap",533),wAn(534,1,QWn),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return l3(this)},MWn.Pb=function(){var n;if(!l3(this))throw Hp(new yv);return n=this.c,this.c=n.c,this.f=n,--this.d,this.Nd(n)},MWn.Qb=function(){if(this.e.g!=this.b)throw Hp(new vv);han(!!this.f),LLn(this.e,this.f),this.b=this.e.g,this.f=null},MWn.b=0,MWn.d=0,MWn.f=null,vX(XWn,"HashBiMap/Itr",534),wAn(1011,534,QWn,VL),MWn.Nd=function(n){return new bT(this,n)},vX(XWn,"HashBiMap/1",1011),wAn(1012,345,aVn,bT),MWn.cd=function(){return this.a.g},MWn.dd=function(){return this.a.i},MWn.ed=function(n){var t,e,i;return e=this.a.i,(i=dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15))))==this.a.f&&(GC(n)===GC(e)||null!=n&&Nfn(n,e))?n:(yun(!Zrn(this.b.a,n,i),n),LLn(this.b.a,this.a),t=new qW(this.a.g,this.a.a,n,i),YIn(this.b.a,t,this.a),this.a.e=null,this.a.c=null,this.b.b=this.b.a.g,this.b.f==this.a&&(this.b.f=t),this.a=t,e)},vX(XWn,"HashBiMap/1/MapEntry",1012),wAn(238,345,{345:1,238:1,3:1,42:1},vT),MWn.cd=function(){return this.g},MWn.dd=function(){return this.i},MWn.ed=function(n){throw Hp(new pv)},vX(XWn,"ImmutableEntry",238),wAn(317,238,{345:1,317:1,238:1,3:1,42:1},qW),MWn.a=0,MWn.f=0;var qnt,Gnt=vX(XWn,"HashBiMap/BiEntry",317);wAn(610,1979,jVn,il),MWn.Ac=function(n){Tcn(this,n)},MWn.Cc=function(){return new v$(this.a)},MWn.$b=function(){d5(this.a)},MWn._b=function(n){return Ltn(this.a,n)},MWn.kc=function(){return new QL(this,this.a)},MWn.wc=function(n){yX(n),BJ(this.a,new rl(n))},MWn.xc=function(n){return Uin(this,n)},MWn.ec=function(){return new p$(this)},MWn.zc=function(n,t){return IKn(this.a,n,t,!1)},MWn.Bc=function(n){var t;return(t=Zrn(this.a,n,dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15)))))?(LLn(this.a,t),t.e=null,t.c=null,t.g):null},MWn.gc=function(){return this.a.i},MWn.pd=function(){return new v$(this.a)},vX(XWn,"HashBiMap/Inverse",610),wAn(1008,534,QWn,QL),MWn.Nd=function(n){return new wT(this,n)},vX(XWn,"HashBiMap/Inverse/1",1008),wAn(1009,345,aVn,wT),MWn.cd=function(){return this.a.i},MWn.dd=function(){return this.a.g},MWn.ed=function(n){var t,e,i;return i=this.a.g,(t=dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15))))==this.a.a&&(GC(n)===GC(i)||null!=n&&Nfn(n,i))?n:(yun(!Jrn(this.b.a.a,n,t),n),LLn(this.b.a.a,this.a),e=new qW(n,t,this.a.i,this.a.f),this.a=e,YIn(this.b.a.a,e,null),this.b.b=this.b.a.a.g,i)},vX(XWn,"HashBiMap/Inverse/1/InverseEntry",1009),wAn(611,532,tVn,p$),MWn.Kc=function(){return new uy(this.a.a)},MWn.Mc=function(n){var t;return!!(t=Zrn(this.a.a,n,dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15)))))&&(LLn(this.a.a,t),!0)},vX(XWn,"HashBiMap/Inverse/InverseKeySet",611),wAn(1007,534,QWn,uy),MWn.Nd=function(n){return n.i},vX(XWn,"HashBiMap/Inverse/InverseKeySet/1",1007),wAn(1010,1,{},rl),MWn.Od=function(n,t){ev(this.a,n,t)},vX(XWn,"HashBiMap/Inverse/lambda$0$Type",1010),wAn(609,532,tVn,v$),MWn.Kc=function(){return new oy(this.a)},MWn.Mc=function(n){var t;return!!(t=Jrn(this.a,n,dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15)))))&&(LLn(this.a,t),t.e=null,t.c=null,!0)},vX(XWn,"HashBiMap/KeySet",609),wAn(1006,534,QWn,oy),MWn.Nd=function(n){return n.g},vX(XWn,"HashBiMap/KeySet/1",1006),wAn(1093,619,VWn),vX(XWn,"HashMultimapGwtSerializationDependencies",1093),wAn(265,1093,VWn,pJ),MWn.hc=function(){return new bE(etn(this.a))},MWn.gd=function(){return new bE(etn(this.a))},MWn.a=2,vX(XWn,"HashMultimap",265),wAn(1999,152,yVn),MWn.Hc=function(n){return this.Pd().Hc(n)},MWn.dc=function(){return this.Pd().dc()},MWn.gc=function(){return this.Pd().gc()},vX(XWn,"ImmutableAsList",1999),wAn(1931,715,jVn),MWn.Ld=function(){return sK(),new yk(this.a)},MWn.Cc=function(){return sK(),new yk(this.a)},MWn.pd=function(){return sK(),new yk(this.a)},vX(XWn,"ImmutableBiMap",1931),wAn(1977,1,{}),vX(XWn,"ImmutableCollection/Builder",1977),wAn(1022,703,TVn,sy),vX(XWn,"ImmutableEnumSet",1022),wAn(969,386,WWn,b_),MWn.Xb=function(n){return this.a.Xb(n)},vX(XWn,"ImmutableList/1",969),wAn(968,1977,{},sR),vX(XWn,"ImmutableList/Builder",968),wAn(614,198,UWn,cl),MWn.Ob=function(){return this.a.Ob()},MWn.Pb=function(){return BB(this.a.Pb(),42).cd()},vX(XWn,"ImmutableMap/1",614),wAn(1041,1,{},o),MWn.Kb=function(n){return BB(n,42).cd()},vX(XWn,"ImmutableMap/2methodref$getKey$Type",1041),wAn(1040,1,{},hR),vX(XWn,"ImmutableMap/Builder",1040),wAn(2e3,1981,TVn),MWn.Kc=function(){return new cl(lz(this.a).Ed())},MWn.Dd=function(){return new uv(this)},MWn.Jc=function(n){var t,e;for(yX(n),e=this.gc(),t=0;t<e;t++)n.td(BB(wz(lz(this.a)).Xb(t),42).cd())},MWn.Ed=function(){var n;return(n=this.c,n||(this.c=new uv(this))).Ed()},MWn.Nc=function(){return yq(this.gc(),1296,new ul(this))},vX(XWn,"IndexedImmutableSet",2e3),wAn(1180,2e3,TVn,cv),MWn.Kc=function(){return new cl(lz(this.a).Ed())},MWn.Hc=function(n){return this.a._b(n)},MWn.Jc=function(n){yX(n),nan(this.a,new al(n))},MWn.Ed=function(){return new cl(lz(this.a).Ed())},MWn.gc=function(){return this.a.gc()},MWn.Nc=function(){return RB(lz(this.a).Nc(),new o)},vX(XWn,"ImmutableMapKeySet",1180),wAn(1181,1,{},al),MWn.Od=function(n,t){sK(),this.a.td(n)},vX(XWn,"ImmutableMapKeySet/lambda$0$Type",1181),wAn(1178,1980,mVn,av),MWn.Kc=function(){return new _H(this)},MWn.Hc=function(n){return null!=n&&Pjn(new _H(this),n)},MWn.Ed=function(){return new _H(this)},MWn.gc=function(){return this.a.gc()},MWn.Nc=function(){return RB(lz(this.a).Nc(),new s)},vX(XWn,"ImmutableMapValues",1178),wAn(1179,1,{},s),MWn.Kb=function(n){return BB(n,42).dd()},vX(XWn,"ImmutableMapValues/0methodref$getValue$Type",1179),wAn(626,198,UWn,_H),MWn.Ob=function(){return this.a.Ob()},MWn.Pb=function(){return BB(this.a.Pb(),42).dd()},vX(XWn,"ImmutableMapValues/1",626),wAn(1182,1,{},ul),MWn.ld=function(n){return HU(this.a,n)},vX(XWn,"IndexedImmutableSet/0methodref$get$Type",1182),wAn(752,1999,yVn,uv),MWn.Pd=function(){return this.a},MWn.Xb=function(n){return HU(this.a,n)},MWn.gc=function(){return this.a.a.gc()},vX(XWn,"IndexedImmutableSet/1",752),wAn(44,1,{},h),MWn.Kb=function(n){return BB(n,20).Kc()},MWn.Fb=function(n){return this===n},vX(XWn,"Iterables/10",44),wAn(1042,537,pVn,KH),MWn.Jc=function(n){yX(n),this.b.Jc(new dT(this.a,n))},MWn.Kc=function(){return qA(this)},vX(XWn,"Iterables/4",1042),wAn(1043,1,lVn,dT),MWn.td=function(n){TS(this.b,this.a,n)},vX(XWn,"Iterables/4/lambda$0$Type",1043),wAn(1044,537,pVn,FH),MWn.Jc=function(n){yX(n),e5(this.a,new fT(n,this.b))},MWn.Kc=function(){return ZL(new AL(this.a),this.b)},vX(XWn,"Iterables/5",1044),wAn(1045,1,lVn,fT),MWn.td=function(n){this.a.td(yA(n))},vX(XWn,"Iterables/5/lambda$0$Type",1045),wAn(1071,198,UWn,ol),MWn.Ob=function(){return this.a.Ob()},MWn.Pb=function(){return this.a.Pb()},vX(XWn,"Iterators/1",1071),wAn(1072,699,UWn,lT),MWn.Yb=function(){for(var n;this.b.Ob();)if(n=this.b.Pb(),this.a.Lb(n))return n;return this.e=2,null},vX(XWn,"Iterators/5",1072),wAn(487,1,QWn),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return this.b.Ob()},MWn.Pb=function(){return this.Qd(this.b.Pb())},MWn.Qb=function(){this.b.Qb()},vX(XWn,"TransformedIterator",487),wAn(1073,487,QWn,nN),MWn.Qd=function(n){return this.a.Kb(n)},vX(XWn,"Iterators/6",1073),wAn(717,198,UWn,sl),MWn.Ob=function(){return!this.a},MWn.Pb=function(){if(this.a)throw Hp(new yv);return this.a=!0,this.b},MWn.a=!1,vX(XWn,"Iterators/9",717),wAn(1070,386,WWn,fG),MWn.Xb=function(n){return this.a[this.b+n]},MWn.b=0,vX(XWn,"Iterators/ArrayItr",1070),wAn(39,1,{39:1,47:1},oz),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return dAn(this)},MWn.Pb=function(){return U5(this)},MWn.Qb=function(){han(!!this.c),this.c.Qb(),this.c=null},vX(XWn,"Iterators/ConcatenatedIterator",39),wAn(22,1,{3:1,35:1,22:1}),MWn.wd=function(n){return Py(this,BB(n,22))},MWn.Fb=function(n){return this===n},MWn.Hb=function(){return PN(this)},MWn.Ib=function(){return dx(this)},MWn.g=0;var znt,Unt=vX(RWn,"Enum",22);wAn(538,22,{538:1,3:1,35:1,22:1,47:1},cN),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return!1},MWn.Pb=function(){throw Hp(new yv)},MWn.Qb=function(){han(!1)};var Xnt,Wnt=Ben(XWn,"Iterators/EmptyModifiableIterator",538,Unt,oX,rx);wAn(1834,619,VWn),vX(XWn,"LinkedHashMultimapGwtSerializationDependencies",1834),wAn(1835,1834,VWn,Thn),MWn.hc=function(){return new LN(etn(this.b))},MWn.$b=function(){win(this),iv(this.a,this.a)},MWn.gd=function(){return new LN(etn(this.b))},MWn.ic=function(n){return new Tsn(this,n,this.b)},MWn.kc=function(){return new tN(this)},MWn.lc=function(){return new w1(BB(this.g||(this.g=new qm(this)),21),17)},MWn.ec=function(){return this.i||(this.i=new HL(this,this.c))},MWn.nc=function(){return new by(new tN(this))},MWn.oc=function(){return RB(new w1(BB(this.g||(this.g=new qm(this)),21),17),new f)},MWn.b=2,vX(XWn,"LinkedHashMultimap",1835),wAn(1838,1,{},f),MWn.Kb=function(n){return BB(n,42).dd()},vX(XWn,"LinkedHashMultimap/0methodref$getValue$Type",1838),wAn(824,1,QWn,tN),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return vtn(this)},MWn.Ob=function(){return this.a!=this.b.a},MWn.Qb=function(){han(!!this.c),q0(this.b,this.c.g,this.c.i),this.c=null},vX(XWn,"LinkedHashMultimap/1",824),wAn(330,238,{345:1,238:1,330:1,2020:1,3:1,42:1},HW),MWn.Rd=function(){return this.f},MWn.Sd=function(n){this.c=n},MWn.Td=function(n){this.f=n},MWn.d=0;var Vnt,Qnt=vX(XWn,"LinkedHashMultimap/ValueEntry",330);wAn(1836,1970,{2020:1,20:1,28:1,14:1,21:1},Tsn),MWn.Fc=function(n){var t,e,i,r,c;for(t=(c=dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15))))&this.b.length-1,e=r=this.b[t];e;e=e.a)if(e.d==c&&wW(e.i,n))return!1;return i=new HW(this.c,n,c,r),kk(this.d,i),i.f=this,this.d=i,iv(this.g.a.b,i),iv(i,this.g.a),this.b[t]=i,++this.f,++this.e,yjn(this),!0},MWn.$b=function(){var n,t;for(yS(this.b,null),this.f=0,n=this.a;n!=this;n=n.Rd())iv((t=BB(n,330)).b,t.e);this.a=this,this.d=this,++this.e},MWn.Hc=function(n){var t,e;for(e=dG(cbn(SVn,rV(dG(cbn(null==n?0:nsn(n),PVn)),15))),t=this.b[e&this.b.length-1];t;t=t.a)if(t.d==e&&wW(t.i,n))return!0;return!1},MWn.Jc=function(n){var t;for(yX(n),t=this.a;t!=this;t=t.Rd())n.td(BB(t,330).i)},MWn.Rd=function(){return this.a},MWn.Kc=function(){return new sW(this)},MWn.Mc=function(n){return kAn(this,n)},MWn.Sd=function(n){this.d=n},MWn.Td=function(n){this.a=n},MWn.gc=function(){return this.f},MWn.e=0,MWn.f=0,vX(XWn,"LinkedHashMultimap/ValueSet",1836),wAn(1837,1,QWn,sW),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return wG(this),this.b!=this.c},MWn.Pb=function(){var n,t;if(wG(this),this.b==this.c)throw Hp(new yv);return t=(n=BB(this.b,330)).i,this.d=n,this.b=n.f,t},MWn.Qb=function(){wG(this),han(!!this.d),kAn(this.c,this.d.i),this.a=this.c.e,this.d=null},MWn.a=0,vX(XWn,"LinkedHashMultimap/ValueSet/1",1837),wAn(766,1986,VWn,PO),MWn.Zb=function(){return this.f||(this.f=new rS(this))},MWn.Fb=function(n){return jsn(this,n)},MWn.cc=function(n){return new mT(this,n)},MWn.fc=function(n){return J3(this,n)},MWn.$b=function(){cX(this)},MWn._b=function(n){return HT(this,n)},MWn.ac=function(){return new rS(this)},MWn.bc=function(){return new yl(this)},MWn.qc=function(n){return new mT(this,n)},MWn.dc=function(){return!this.a},MWn.rc=function(n){return J3(this,n)},MWn.gc=function(){return this.d},MWn.c=0,MWn.d=0,vX(XWn,"LinkedListMultimap",766),wAn(52,28,LVn),MWn.ad=function(n){Krn(this,n)},MWn.Nc=function(){return new w1(this,16)},MWn.Vc=function(n,t){throw Hp(new tk("Add not supported on this list"))},MWn.Fc=function(n){return this.Vc(this.gc(),n),!0},MWn.Wc=function(n,t){var e,i,r;for(kW(t),e=!1,r=t.Kc();r.Ob();)i=r.Pb(),this.Vc(n++,i),e=!0;return e},MWn.$b=function(){this.Ud(0,this.gc())},MWn.Fb=function(n){return NAn(this,n)},MWn.Hb=function(){return Fon(this)},MWn.Xc=function(n){return bin(this,n)},MWn.Kc=function(){return new Sb(this)},MWn.Yc=function(){return this.Zc(0)},MWn.Zc=function(n){return new M2(this,n)},MWn.$c=function(n){throw Hp(new tk("Remove not supported on this list"))},MWn.Ud=function(n,t){var e,i;for(i=this.Zc(n),e=n;e<t;++e)i.Pb(),i.Qb()},MWn._c=function(n,t){throw Hp(new tk("Set not supported on this list"))},MWn.bd=function(n,t){return new s1(this,n,t)},MWn.j=0,vX(YWn,"AbstractList",52),wAn(1964,52,LVn),MWn.Vc=function(n,t){_x(this,n,t)},MWn.Wc=function(n,t){return Asn(this,n,t)},MWn.Xb=function(n){return Dpn(this,n)},MWn.Kc=function(){return this.Zc(0)},MWn.$c=function(n){return tkn(this,n)},MWn._c=function(n,t){var e,i;e=this.Zc(n);try{return i=e.Pb(),e.Wb(t),i}catch(r){throw cL(r=lun(r),109)?Hp(new Ay("Can't set element "+n)):Hp(r)}},vX(YWn,"AbstractSequentialList",1964),wAn(636,1964,LVn,mT),MWn.Zc=function(n){return vN(this,n)},MWn.gc=function(){var n;return(n=BB(RX(this.a.b,this.b),283))?n.a:0},vX(XWn,"LinkedListMultimap/1",636),wAn(1297,1970,tVn,yl),MWn.Hc=function(n){return HT(this.a,n)},MWn.Kc=function(){return new vrn(this.a)},MWn.Mc=function(n){return!J3(this.a,n).a.dc()},MWn.gc=function(){return NT(this.a.b)},vX(XWn,"LinkedListMultimap/1KeySetImpl",1297),wAn(1296,1,QWn,vrn),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return bG(this),!!this.c},MWn.Pb=function(){bG(this),oN(this.c),this.a=this.c,TU(this.d,this.a.a);do{this.c=this.c.b}while(this.c&&!TU(this.d,this.c.a));return this.a.a},MWn.Qb=function(){bG(this),han(!!this.a),Iq(new I7(this.e,this.a.a)),this.a=null,this.b=this.e.c},MWn.b=0,vX(XWn,"LinkedListMultimap/DistinctKeyIterator",1296),wAn(283,1,{283:1},sY),MWn.a=0,vX(XWn,"LinkedListMultimap/KeyList",283),wAn(1295,345,aVn,yT),MWn.cd=function(){return this.a},MWn.dd=function(){return this.f},MWn.ed=function(n){var t;return t=this.f,this.f=n,t},vX(XWn,"LinkedListMultimap/Node",1295),wAn(560,1,cVn,I7,_Pn),MWn.Nb=function(n){fU(this,n)},MWn.Rb=function(n){this.e=y_n(this.f,this.b,n,this.c),++this.d,this.a=null},MWn.Ob=function(){return!!this.c},MWn.Sb=function(){return!!this.e},MWn.Pb=function(){return EZ(this)},MWn.Tb=function(){return this.d},MWn.Ub=function(){return TZ(this)},MWn.Vb=function(){return this.d-1},MWn.Qb=function(){han(!!this.a),this.a!=this.c?(this.e=this.a.e,--this.d):this.c=this.a.c,ZIn(this.f,this.a),this.a=null},MWn.Wb=function(n){uN(!!this.a),this.a.f=n},MWn.d=0,vX(XWn,"LinkedListMultimap/ValueForKeyIterator",560),wAn(1018,52,LVn),MWn.Vc=function(n,t){this.a.Vc(n,t)},MWn.Wc=function(n,t){return this.a.Wc(n,t)},MWn.Hc=function(n){return this.a.Hc(n)},MWn.Xb=function(n){return this.a.Xb(n)},MWn.$c=function(n){return this.a.$c(n)},MWn._c=function(n,t){return this.a._c(n,t)},MWn.gc=function(){return this.a.gc()},vX(XWn,"Lists/AbstractListWrapper",1018),wAn(1019,1018,xVn),vX(XWn,"Lists/RandomAccessListWrapper",1019),wAn(1021,1019,xVn,CT),MWn.Zc=function(n){return this.a.Zc(n)},vX(XWn,"Lists/1",1021),wAn(131,52,{131:1,20:1,28:1,52:1,14:1,15:1},IT),MWn.Vc=function(n,t){this.a.Vc(pU(this,n),t)},MWn.$b=function(){this.a.$b()},MWn.Xb=function(n){return this.a.Xb(LX(this,n))},MWn.Kc=function(){return W1(this,0)},MWn.Zc=function(n){return W1(this,n)},MWn.$c=function(n){return this.a.$c(LX(this,n))},MWn.Ud=function(n,t){(d2(n,t,this.a.gc()),ean(this.a.bd(pU(this,t),pU(this,n)))).$b()},MWn._c=function(n,t){return this.a._c(LX(this,n),t)},MWn.gc=function(){return this.a.gc()},MWn.bd=function(n,t){return d2(n,t,this.a.gc()),ean(this.a.bd(pU(this,t),pU(this,n)))},vX(XWn,"Lists/ReverseList",131),wAn(280,131,{131:1,20:1,28:1,52:1,14:1,15:1,54:1},fy),vX(XWn,"Lists/RandomAccessReverseList",280),wAn(1020,1,cVn,kT),MWn.Nb=function(n){fU(this,n)},MWn.Rb=function(n){this.c.Rb(n),this.c.Ub(),this.a=!1},MWn.Ob=function(){return this.c.Sb()},MWn.Sb=function(){return this.c.Ob()},MWn.Pb=function(){return w5(this)},MWn.Tb=function(){return pU(this.b,this.c.Tb())},MWn.Ub=function(){if(!this.c.Ob())throw Hp(new yv);return this.a=!0,this.c.Pb()},MWn.Vb=function(){return pU(this.b,this.c.Tb())-1},MWn.Qb=function(){han(this.a),this.c.Qb(),this.a=!1},MWn.Wb=function(n){uN(this.a),this.c.Wb(n)},MWn.a=!1,vX(XWn,"Lists/ReverseList/1",1020),wAn(432,487,QWn,ly),MWn.Qd=function(n){return cS(n)},vX(XWn,"Maps/1",432),wAn(698,487,QWn,by),MWn.Qd=function(n){return BB(n,42).dd()},vX(XWn,"Maps/2",698),wAn(962,487,QWn,pN),MWn.Qd=function(n){return new vT(n,KO(this.a,n))},vX(XWn,"Maps/3",962),wAn(959,1971,tVn,ml),MWn.Jc=function(n){xv(this.a,n)},MWn.Kc=function(){return this.a.kc()},MWn.Rc=function(){return this.a},MWn.Nc=function(){return this.a.lc()},vX(XWn,"Maps/IteratorBasedAbstractMap/1",959),wAn(960,1,{},vl),MWn.Od=function(n,t){this.a.td(n)},vX(XWn,"Maps/KeySet/lambda$0$Type",960),wAn(958,28,ZWn,PT),MWn.$b=function(){this.a.$b()},MWn.Hc=function(n){return this.a.uc(n)},MWn.Jc=function(n){yX(n),this.a.wc(new ll(n))},MWn.dc=function(){return this.a.dc()},MWn.Kc=function(){return new by(this.a.vc().Kc())},MWn.Mc=function(n){var t,e;try{return ywn(this,n,!0)}catch(i){if(cL(i=lun(i),41)){for(e=this.a.vc().Kc();e.Ob();)if(wW(n,(t=BB(e.Pb(),42)).dd()))return this.a.Bc(t.cd()),!0;return!1}throw Hp(i)}},MWn.gc=function(){return this.a.gc()},vX(XWn,"Maps/Values",958),wAn(961,1,{},ll),MWn.Od=function(n,t){this.a.td(t)},vX(XWn,"Maps/Values/lambda$0$Type",961),wAn(736,1987,JWn,rS),MWn.xc=function(n){return this.a._b(n)?this.a.cc(n):null},MWn.Bc=function(n){return this.a._b(n)?this.a.fc(n):null},MWn.$b=function(){this.a.$b()},MWn._b=function(n){return this.a._b(n)},MWn.Ec=function(){return new fl(this)},MWn.Dc=function(){return this.Ec()},MWn.dc=function(){return this.a.dc()},MWn.ec=function(){return this.a.ec()},MWn.gc=function(){return this.a.ec().gc()},vX(XWn,"Multimaps/AsMap",736),wAn(1104,1971,tVn,fl),MWn.Kc=function(){return nL(this.a.a.ec(),new bl(this))},MWn.Rc=function(){return this.a},MWn.Mc=function(n){var t;return!!idn(this,n)&&(t=BB(n,42),jk(this.a,t.cd()),!0)},vX(XWn,"Multimaps/AsMap/EntrySet",1104),wAn(1108,1,{},bl),MWn.Kb=function(n){return KO(this,n)},MWn.Fb=function(n){return this===n},vX(XWn,"Multimaps/AsMap/EntrySet/1",1108),wAn(543,1989,{543:1,835:1,20:1,28:1,14:1},wl),MWn.$b=function(){win(this.a)},MWn.Hc=function(n){return Wj(this.a,n)},MWn.Jc=function(n){yX(n),e5(MX(this.a),new gl(n))},MWn.Kc=function(){return new ly(MX(this.a).a.kc())},MWn.gc=function(){return this.a.d},MWn.Nc=function(){return RB(MX(this.a).Nc(),new l)},vX(XWn,"Multimaps/Keys",543),wAn(1106,1,{},l),MWn.Kb=function(n){return BB(n,42).cd()},vX(XWn,"Multimaps/Keys/0methodref$getKey$Type",1106),wAn(1105,487,QWn,wy),MWn.Qd=function(n){return new dl(BB(n,42))},vX(XWn,"Multimaps/Keys/1",1105),wAn(1990,1,{416:1}),MWn.Fb=function(n){var t;return!!cL(n,492)&&(t=BB(n,416),BB(this.a.dd(),14).gc()==BB(t.a.dd(),14).gc()&&wW(this.a.cd(),t.a.cd()))},MWn.Hb=function(){var n;return(null==(n=this.a.cd())?0:nsn(n))^BB(this.a.dd(),14).gc()},MWn.Ib=function(){var n,t;return t=kN(this.a.cd()),1==(n=BB(this.a.dd(),14).gc())?t:t+" x "+n},vX(XWn,"Multisets/AbstractEntry",1990),wAn(492,1990,{492:1,416:1},dl),vX(XWn,"Multimaps/Keys/1/1",492),wAn(1107,1,lVn,gl),MWn.td=function(n){this.a.td(BB(n,42).cd())},vX(XWn,"Multimaps/Keys/lambda$1$Type",1107),wAn(1110,1,lVn,b),MWn.td=function(n){Cq(BB(n,416))},vX(XWn,"Multiset/lambda$0$Type",1110),wAn(737,1,lVn,pl),MWn.td=function(n){Ctn(this.a,BB(n,416))},vX(XWn,"Multiset/lambda$1$Type",737),wAn(1111,1,{},m),vX(XWn,"Multisets/0methodref$add$Type",1111),wAn(738,1,{},y),MWn.Kb=function(n){return s3(BB(n,416))},vX(XWn,"Multisets/lambda$3$Type",738),wAn(2008,1,_Wn),vX(XWn,"RangeGwtSerializationDependencies",2008),wAn(514,2008,{169:1,514:1,3:1,45:1},svn),MWn.Lb=function(n){return Mz(this,BB(n,35))},MWn.Mb=function(n){return Mz(this,BB(n,35))},MWn.Fb=function(n){var t;return!!cL(n,514)&&(t=BB(n,514),xdn(this.a,t.a)&&xdn(this.b,t.b))},MWn.Hb=function(){return 31*this.a.Hb()+this.b.Hb()},MWn.Ib=function(){return B3(this.a,this.b)},vX(XWn,"Range",514),wAn(778,1999,yVn,aU),MWn.Zc=function(n){return ix(this.b,n)},MWn.Pd=function(){return this.a},MWn.Xb=function(n){return WC(this.b,n)},MWn.Fd=function(n){return ix(this.b,n)},vX(XWn,"RegularImmutableAsList",778),wAn(646,2006,yVn,SY),MWn.Hd=function(){return this.a},vX(XWn,"RegularImmutableList",646),wAn(616,715,jVn,hy),vX(XWn,"RegularImmutableMap",616),wAn(716,703,TVn,vS),vX(XWn,"RegularImmutableSet",716),wAn(1976,nVn,tVn),MWn.Kc=function(){return new SV(this.a,this.b)},MWn.Fc=function(n){throw Hp(new pv)},MWn.Gc=function(n){throw Hp(new pv)},MWn.$b=function(){throw Hp(new pv)},MWn.Mc=function(n){throw Hp(new pv)},vX(XWn,"Sets/SetView",1976),wAn(963,1976,tVn,ET),MWn.Kc=function(){return new SV(this.a,this.b)},MWn.Hc=function(n){return IG(this.a,n)&&this.b.Hc(n)},MWn.Ic=function(n){return oun(this.a,n)&&this.b.Ic(n)},MWn.dc=function(){return _pn(this.b,this.a)},MWn.Lc=function(){return AV(new Rq(null,new w1(this.a,1)),new jl(this.b))},MWn.gc=function(){return Ian(this)},MWn.Oc=function(){return AV(new Rq(null,new w1(this.a,1)),new kl(this.b))},vX(XWn,"Sets/2",963),wAn(700,699,UWn,SV),MWn.Yb=function(){for(var n;k$(this.a);)if(n=u4(this.a),this.c.Hc(n))return n;return this.e=2,null},vX(XWn,"Sets/2/1",700),wAn(964,1,DVn,kl),MWn.Mb=function(n){return this.a.Hc(n)},vX(XWn,"Sets/2/4methodref$contains$Type",964),wAn(965,1,DVn,jl),MWn.Mb=function(n){return this.a.Hc(n)},vX(XWn,"Sets/2/5methodref$contains$Type",965),wAn(607,1975,{607:1,3:1,20:1,14:1,271:1,21:1,84:1},bJ),MWn.Bd=function(){return this.b},MWn.Cd=function(){return this.b},MWn.Md=function(){return this.b},MWn.Jc=function(n){this.a.Jc(n)},MWn.Lc=function(){return this.a.Lc()},MWn.Oc=function(){return this.a.Oc()},vX(XWn,"Sets/UnmodifiableNavigableSet",607),wAn(1932,1931,jVn,GW),MWn.Ld=function(){return sK(),new yk(this.a)},MWn.Cc=function(){return sK(),new yk(this.a)},MWn.pd=function(){return sK(),new yk(this.a)},vX(XWn,"SingletonImmutableBiMap",1932),wAn(647,2006,yVn,Pq),MWn.Hd=function(){return this.a},vX(XWn,"SingletonImmutableList",647),wAn(350,1981,TVn,yk),MWn.Kc=function(){return new sl(this.a)},MWn.Hc=function(n){return Nfn(this.a,n)},MWn.Ed=function(){return new sl(this.a)},MWn.gc=function(){return 1},vX(XWn,"SingletonImmutableSet",350),wAn(1115,1,{},k),MWn.Kb=function(n){return BB(n,164)},vX(XWn,"Streams/lambda$0$Type",1115),wAn(1116,1,RVn,El),MWn.Vd=function(){B5(this.a)},vX(XWn,"Streams/lambda$1$Type",1116),wAn(1659,1658,VWn,pY),MWn.Zb=function(){return BB(BB(this.f||(this.f=cL(this.c,171)?new CD(this,BB(this.c,171)):cL(this.c,161)?new ID(this,BB(this.c,161)):new pT(this,this.c)),161),171)},MWn.hc=function(){return new dE(this.b)},MWn.gd=function(){return new dE(this.b)},MWn.ec=function(){return BB(BB(this.i||(this.i=cL(this.c,171)?new tT(this,BB(this.c,171)):cL(this.c,161)?new nT(this,BB(this.c,161)):new HL(this,this.c)),84),271)},MWn.ac=function(){return cL(this.c,171)?new CD(this,BB(this.c,171)):cL(this.c,161)?new ID(this,BB(this.c,161)):new pT(this,this.c)},MWn.ic=function(n){return null==n&&this.a.ue(n,n),new dE(this.b)},vX(XWn,"TreeMultimap",1659),wAn(78,1,{3:1,78:1}),MWn.Wd=function(n){return new Error(n)},MWn.Xd=function(){return this.e},MWn.Yd=function(){return Kwn($V(LU((null==this.k&&(this.k=x8(Jnt,sVn,78,0,0,1)),this.k)),new x),new on)},MWn.Zd=function(){return this.f},MWn.$d=function(){return this.g},MWn._d=function(){yy(this,b2(this.Wd(IY(this,this.g)))),ov(this)},MWn.Ib=function(){return IY(this,this.$d())},MWn.e=FVn,MWn.i=!1,MWn.n=!0;var Ynt,Jnt=vX(RWn,"Throwable",78);wAn(102,78,{3:1,102:1,78:1}),vX(RWn,"Exception",102),wAn(60,102,BVn,sv,dy),vX(RWn,"RuntimeException",60),wAn(598,60,BVn),vX(RWn,"JsException",598),wAn(863,598,BVn),vX(HVn,"JavaScriptExceptionBase",863),wAn(477,863,{477:1,3:1,102:1,60:1,78:1},jhn),MWn.$d=function(){return pEn(this),this.c},MWn.ae=function(){return GC(this.b)===GC(Ynt)?null:this.b},vX(GVn,"JavaScriptException",477);var Znt,ntt=vX(GVn,"JavaScriptObject$",0);wAn(1948,1,{}),vX(GVn,"Scheduler",1948);var ttt,ett,itt,rtt,ctt=0,att=0,utt=-1;wAn(890,1948,{},j),vX(HVn,"SchedulerImpl",890),wAn(1960,1,{}),vX(HVn,"StackTraceCreator/Collector",1960),wAn(864,1960,{},E),MWn.be=function(n){var t={},e=[];n[UVn]=e;for(var i=arguments.callee.caller;i;){var r=(PY(),i.name||(i.name=Ven(i.toString())));e.push(r);var c,a,u=":"+r,o=t[u];if(o)for(c=0,a=o.length;c<a;c++)if(o[c]===i)return;(o||(t[u]=[])).push(i),i=i.caller}},MWn.ce=function(n){var t,e,i,r;for(PY(),e=(i=n&&n[UVn]?n[UVn]:[]).length,r=x8(Ftt,sVn,310,e,0,1),t=0;t<e;t++)r[t]=new PV(i[t],null,-1);return r},vX(HVn,"StackTraceCreator/CollectorLegacy",864),wAn(1961,1960,{}),MWn.be=function(n){},MWn.de=function(n,t,e,i){return new PV(t,n+"@"+i,e<0?-1:e)},MWn.ce=function(n){var t,e,i,r,c,a;if(r=lyn(n),c=x8(Ftt,sVn,310,0,0,1),t=0,0==(i=r.length))return c;for(m_((a=Oqn(this,r[0])).d,zVn)||(c[t++]=a),e=1;e<i;e++)c[t++]=Oqn(this,r[e]);return c},vX(HVn,"StackTraceCreator/CollectorModern",1961),wAn(865,1961,{},d),MWn.de=function(n,t,e,i){return new PV(t,n,-1)},vX(HVn,"StackTraceCreator/CollectorModernNoSourceMap",865),wAn(1050,1,{}),vX(yQn,kQn,1050),wAn(615,1050,{615:1},zX),vX(jQn,kQn,615),wAn(2001,1,{}),vX(yQn,EQn,2001),wAn(2002,2001,{}),vX(jQn,EQn,2002),wAn(1090,1,{},g),vX(jQn,"LocaleInfo",1090),wAn(1918,1,{},p),MWn.a=0,vX(jQn,"TimeZone",1918),wAn(1258,2002,{},w),vX("com.google.gwt.i18n.client.impl.cldr","DateTimeFormatInfoImpl",1258),wAn(434,1,{434:1},VB),MWn.a=!1,MWn.b=0,vX(yQn,"DateTimeFormat/PatternPart",434),wAn(199,1,TQn,AT,von,PD),MWn.wd=function(n){return J0(this,BB(n,199))},MWn.Fb=function(n){return cL(n,199)&&QC(fan(this.q.getTime()),fan(BB(n,199).q.getTime()))},MWn.Hb=function(){var n;return dG(r0(n=fan(this.q.getTime()),jz(n,32)))},MWn.Ib=function(){var n,t,i;return n=((i=-this.q.getTimezoneOffset())>=0?"+":"")+(i/60|0),t=UO(e.Math.abs(i)%60),(pMn(),pet)[this.q.getDay()]+" "+vet[this.q.getMonth()]+" "+UO(this.q.getDate())+" "+UO(this.q.getHours())+":"+UO(this.q.getMinutes())+":"+UO(this.q.getSeconds())+" GMT"+n+t+" "+this.q.getFullYear()};var ott,stt,htt,ftt,ltt,btt,wtt,dtt,gtt,ptt,vtt,mtt=vX(YWn,"Date",199);wAn(1915,199,TQn,Ykn),MWn.a=!1,MWn.b=0,MWn.c=0,MWn.d=0,MWn.e=0,MWn.f=0,MWn.g=!1,MWn.i=0,MWn.j=0,MWn.k=0,MWn.n=0,MWn.o=0,MWn.p=0,vX("com.google.gwt.i18n.shared.impl","DateRecord",1915),wAn(1966,1,{}),MWn.fe=function(){return null},MWn.ge=function(){return null},MWn.he=function(){return null},MWn.ie=function(){return null},MWn.je=function(){return null},vX(MQn,"JSONValue",1966),wAn(216,1966,{216:1},Il,Tl),MWn.Fb=function(n){return!!cL(n,216)&&v0(this.a,BB(n,216).a)},MWn.ee=function(){return qp},MWn.Hb=function(){return tY(this.a)},MWn.fe=function(){return this},MWn.Ib=function(){var n,t,e;for(e=new lN("["),t=0,n=this.a.length;t<n;t++)t>0&&(e.a+=","),uO(e,dnn(this,t));return e.a+="]",e.a},vX(MQn,"JSONArray",216),wAn(483,1966,{483:1},Ml),MWn.ee=function(){return Gp},MWn.ge=function(){return this},MWn.Ib=function(){return hN(),""+this.a},MWn.a=!1,vX(MQn,"JSONBoolean",483),wAn(985,60,BVn,gy),vX(MQn,"JSONException",985),wAn(1023,1966,{},v),MWn.ee=function(){return Vp},MWn.Ib=function(){return zWn},vX(MQn,"JSONNull",1023),wAn(258,1966,{258:1},Sl),MWn.Fb=function(n){return!!cL(n,258)&&this.a==BB(n,258).a},MWn.ee=function(){return zp},MWn.Hb=function(){return VO(this.a)},MWn.he=function(){return this},MWn.Ib=function(){return this.a+""},MWn.a=0,vX(MQn,"JSONNumber",258),wAn(183,1966,{183:1},py,Pl),MWn.Fb=function(n){return!!cL(n,183)&&v0(this.a,BB(n,183).a)},MWn.ee=function(){return Up},MWn.Hb=function(){return tY(this.a)},MWn.ie=function(){return this},MWn.Ib=function(){var n,t,e,i,r,c;for(c=new lN("{"),n=!0,i=0,r=(e=jrn(this,x8(Qtt,sVn,2,0,6,1))).length;i<r;++i)t=e[i],n?n=!1:c.a+=FWn,oO(c,mOn(t)),c.a+=":",uO(c,zJ(this,t));return c.a+="}",c.a},vX(MQn,"JSONObject",183),wAn(596,nVn,tVn,TT),MWn.Hc=function(n){return XC(n)&&zk(this.a,SD(n))},MWn.Kc=function(){return new Sb(new Jy(this.b))},MWn.gc=function(){return this.b.length},vX(MQn,"JSONObject/1",596),wAn(204,1966,{204:1},GX),MWn.Fb=function(n){return!!cL(n,204)&&m_(this.a,BB(n,204).a)},MWn.ee=function(){return Xp},MWn.Hb=function(){return vvn(this.a)},MWn.je=function(){return this},MWn.Ib=function(){return mOn(this.a)},vX(MQn,"JSONString",204),wAn(1962,1,{525:1}),vX(LQn,"OutputStream",1962),wAn(1963,1962,{525:1}),vX(LQn,"FilterOutputStream",1963),wAn(866,1963,{525:1},A),vX(LQn,"PrintStream",866),wAn(418,1,{475:1}),MWn.Ib=function(){return this.a},vX(RWn,"AbstractStringBuilder",418),wAn(529,60,BVn,Oy),vX(RWn,"ArithmeticException",529),wAn(73,60,NQn,fv,Ay),vX(RWn,"IndexOutOfBoundsException",73),wAn(320,73,{3:1,320:1,102:1,73:1,60:1,78:1},Sv,Tk),vX(RWn,"ArrayIndexOutOfBoundsException",320),wAn(528,60,BVn,lv,$y),vX(RWn,"ArrayStoreException",528),wAn(289,78,xQn,Ly),vX(RWn,"Error",289),wAn(194,289,xQn,hv,g5),vX(RWn,"AssertionError",194),IWn={3:1,476:1,35:1};var ytt,ktt=vX(RWn,"Boolean",476);wAn(236,1,{3:1,236:1}),vX(RWn,"Number",236),wAn(217,236,{3:1,217:1,35:1,236:1},$b),MWn.wd=function(n){return Fk(this,BB(n,217))},MWn.ke=function(){return this.a},MWn.Fb=function(n){return cL(n,217)&&BB(n,217).a==this.a},MWn.Hb=function(){return this.a},MWn.Ib=function(){return""+this.a},MWn.a=0;var jtt,Ett,Ttt=vX(RWn,"Byte",217);wAn(172,1,{3:1,172:1,35:1},Lb),MWn.wd=function(n){return Bk(this,BB(n,172))},MWn.Fb=function(n){return cL(n,172)&&BB(n,172).a==this.a},MWn.Hb=function(){return this.a},MWn.Ib=function(){return String.fromCharCode(this.a)},MWn.a=0;var Mtt,Stt=vX(RWn,"Character",172);wAn(205,60,{3:1,205:1,102:1,60:1,78:1},bv,_y),vX(RWn,"ClassCastException",205),CWn={3:1,35:1,333:1,236:1};var Ptt=vX(RWn,"Double",333);wAn(155,236,{3:1,35:1,155:1,236:1},Nb,Dv),MWn.wd=function(n){return BO(this,BB(n,155))},MWn.ke=function(){return this.a},MWn.Fb=function(n){return cL(n,155)&&v_(this.a,BB(n,155).a)},MWn.Hb=function(){return IJ(this.a)},MWn.Ib=function(){return""+this.a},MWn.a=0;var Itt=vX(RWn,"Float",155);wAn(32,60,{3:1,102:1,32:1,60:1,78:1},wv,Ky,Fsn),vX(RWn,"IllegalArgumentException",32),wAn(71,60,BVn,dv,Fy),vX(RWn,"IllegalStateException",71),wAn(19,236,{3:1,35:1,19:1,236:1},xb),MWn.wd=function(n){return HO(this,BB(n,19))},MWn.ke=function(){return this.a},MWn.Fb=function(n){return cL(n,19)&&BB(n,19).a==this.a},MWn.Hb=function(){return this.a},MWn.Ib=function(){return""+this.a},MWn.a=0;var Ctt,Ott,Att=vX(RWn,"Integer",19);wAn(162,236,{3:1,35:1,162:1,236:1},Db),MWn.wd=function(n){return qO(this,BB(n,162))},MWn.ke=function(){return j2(this.a)},MWn.Fb=function(n){return cL(n,162)&&QC(BB(n,162).a,this.a)},MWn.Hb=function(){return dG(this.a)},MWn.Ib=function(){return""+vz(this.a)},MWn.a=0;var $tt,Ltt,Ntt,xtt,Dtt,Rtt=vX(RWn,"Long",162);wAn(2039,1,{}),wAn(1831,60,BVn,By),vX(RWn,"NegativeArraySizeException",1831),wAn(173,598,{3:1,102:1,173:1,60:1,78:1},gv,Hy),MWn.Wd=function(n){return new TypeError(n)},vX(RWn,"NullPointerException",173),wAn(127,32,{3:1,102:1,32:1,127:1,60:1,78:1},Mk),vX(RWn,"NumberFormatException",127),wAn(184,236,{3:1,35:1,236:1,184:1},Rb),MWn.wd=function(n){return Hk(this,BB(n,184))},MWn.ke=function(){return this.a},MWn.Fb=function(n){return cL(n,184)&&BB(n,184).a==this.a},MWn.Hb=function(){return this.a},MWn.Ib=function(){return""+this.a},MWn.a=0;var _tt,Ktt=vX(RWn,"Short",184);wAn(310,1,{3:1,310:1},PV),MWn.Fb=function(n){var t;return!!cL(n,310)&&(t=BB(n,310),this.c==t.c&&this.d==t.d&&this.a==t.a&&this.b==t.b)},MWn.Hb=function(){return fhn(Pun(Gk(Ant,1),HWn,1,5,[iln(this.c),this.a,this.d,this.b]))},MWn.Ib=function(){return this.a+"."+this.d+"("+(null!=this.b?this.b:"Unknown Source")+(this.c>=0?":"+this.c:"")+")"},MWn.c=0;var Ftt=vX(RWn,"StackTraceElement",310);OWn={3:1,475:1,35:1,2:1};var Btt,Htt,qtt,Gtt,ztt,Utt,Xtt,Wtt,Vtt,Qtt=vX(RWn,qVn,2);wAn(107,418,{475:1},Sk,Pk,fN),vX(RWn,"StringBuffer",107),wAn(100,418,{475:1},Ik,Ck,lN),vX(RWn,"StringBuilder",100),wAn(687,73,NQn,Ok),vX(RWn,"StringIndexOutOfBoundsException",687),wAn(2043,1,{}),wAn(844,1,{},x),MWn.Kb=function(n){return BB(n,78).e},vX(RWn,"Throwable/lambda$0$Type",844),wAn(41,60,{3:1,102:1,60:1,78:1,41:1},pv,tk),vX(RWn,"UnsupportedOperationException",41),wAn(240,236,{3:1,35:1,236:1,240:1},knn,wE),MWn.wd=function(n){return JKn(this,BB(n,240))},MWn.ke=function(){return bSn(eqn(this))},MWn.Fb=function(n){var t;return this===n||!!cL(n,240)&&(t=BB(n,240),this.e==t.e&&0==JKn(this,t))},MWn.Hb=function(){var n;return 0!=this.b?this.b:this.a<54?(n=fan(this.f),this.b=dG(e0(n,-1)),this.b=33*this.b+dG(e0(kz(n,32),-1)),this.b=17*this.b+IJ(this.e),this.b):(this.b=17*_hn(this.c)+IJ(this.e),this.b)},MWn.Ib=function(){return eqn(this)},MWn.a=0,MWn.b=0,MWn.d=0,MWn.e=0,MWn.f=0;var Ytt,Jtt,Ztt,net,tet,eet,iet=vX("java.math","BigDecimal",240);wAn(91,236,{3:1,35:1,236:1,91:1},Rpn,X6,lU,vEn,Ign,$A),MWn.wd=function(n){return tgn(this,BB(n,91))},MWn.ke=function(){return bSn(qXn(this,0))},MWn.Fb=function(n){return swn(this,n)},MWn.Hb=function(){return _hn(this)},MWn.Ib=function(){return qXn(this,0)},MWn.b=-2,MWn.c=0,MWn.d=0,MWn.e=0;var ret,cet,aet,uet,oet=vX("java.math","BigInteger",91);wAn(488,1967,JWn),MWn.$b=function(){$U(this)},MWn._b=function(n){return hU(this,n)},MWn.uc=function(n){return Lsn(this,n,this.g)||Lsn(this,n,this.f)},MWn.vc=function(){return new Pb(this)},MWn.xc=function(n){return RX(this,n)},MWn.zc=function(n,t){return VW(this,n,t)},MWn.Bc=function(n){return v6(this,n)},MWn.gc=function(){return NT(this)},vX(YWn,"AbstractHashMap",488),wAn(261,nVn,tVn,Pb),MWn.$b=function(){this.a.$b()},MWn.Hc=function(n){return m2(this,n)},MWn.Kc=function(){return new usn(this.a)},MWn.Mc=function(n){var t;return!!m2(this,n)&&(t=BB(n,42).cd(),this.a.Bc(t),!0)},MWn.gc=function(){return this.a.gc()},vX(YWn,"AbstractHashMap/EntrySet",261),wAn(262,1,QWn,usn),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return ten(this)},MWn.Ob=function(){return this.b},MWn.Qb=function(){o9(this)},MWn.b=!1,vX(YWn,"AbstractHashMap/EntrySetIterator",262),wAn(417,1,QWn,Sb),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return aS(this)},MWn.Pb=function(){return mQ(this)},MWn.Qb=function(){fW(this)},MWn.b=0,MWn.c=-1,vX(YWn,"AbstractList/IteratorImpl",417),wAn(96,417,cVn,M2),MWn.Qb=function(){fW(this)},MWn.Rb=function(n){yR(this,n)},MWn.Sb=function(){return this.b>0},MWn.Tb=function(){return this.b},MWn.Ub=function(){return Px(this.b>0),this.a.Xb(this.c=--this.b)},MWn.Vb=function(){return this.b-1},MWn.Wb=function(n){Mx(-1!=this.c),this.a._c(this.c,n)},vX(YWn,"AbstractList/ListIteratorImpl",96),wAn(219,52,LVn,s1),MWn.Vc=function(n,t){LZ(n,this.b),this.c.Vc(this.a+n,t),++this.b},MWn.Xb=function(n){return l1(n,this.b),this.c.Xb(this.a+n)},MWn.$c=function(n){var t;return l1(n,this.b),t=this.c.$c(this.a+n),--this.b,t},MWn._c=function(n,t){return l1(n,this.b),this.c._c(this.a+n,t)},MWn.gc=function(){return this.b},MWn.a=0,MWn.b=0,vX(YWn,"AbstractList/SubList",219),wAn(384,nVn,tVn,Ib),MWn.$b=function(){this.a.$b()},MWn.Hc=function(n){return this.a._b(n)},MWn.Kc=function(){return new Cb(this.a.vc().Kc())},MWn.Mc=function(n){return!!this.a._b(n)&&(this.a.Bc(n),!0)},MWn.gc=function(){return this.a.gc()},vX(YWn,"AbstractMap/1",384),wAn(691,1,QWn,Cb),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return this.a.Ob()},MWn.Pb=function(){return BB(this.a.Pb(),42).cd()},MWn.Qb=function(){this.a.Qb()},vX(YWn,"AbstractMap/1/1",691),wAn(226,28,ZWn,Ob),MWn.$b=function(){this.a.$b()},MWn.Hc=function(n){return this.a.uc(n)},MWn.Kc=function(){return new _b(this.a.vc().Kc())},MWn.gc=function(){return this.a.gc()},vX(YWn,"AbstractMap/2",226),wAn(294,1,QWn,_b),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return this.a.Ob()},MWn.Pb=function(){return BB(this.a.Pb(),42).dd()},MWn.Qb=function(){this.a.Qb()},vX(YWn,"AbstractMap/2/1",294),wAn(484,1,{484:1,42:1}),MWn.Fb=function(n){var t;return!!cL(n,42)&&(t=BB(n,42),cV(this.d,t.cd())&&cV(this.e,t.dd()))},MWn.cd=function(){return this.d},MWn.dd=function(){return this.e},MWn.Hb=function(){return _A(this.d)^_A(this.e)},MWn.ed=function(n){return pR(this,n)},MWn.Ib=function(){return this.d+"="+this.e},vX(YWn,"AbstractMap/AbstractEntry",484),wAn(383,484,{484:1,383:1,42:1},PS),vX(YWn,"AbstractMap/SimpleEntry",383),wAn(1984,1,VQn),MWn.Fb=function(n){var t;return!!cL(n,42)&&(t=BB(n,42),cV(this.cd(),t.cd())&&cV(this.dd(),t.dd()))},MWn.Hb=function(){return _A(this.cd())^_A(this.dd())},MWn.Ib=function(){return this.cd()+"="+this.dd()},vX(YWn,uVn,1984),wAn(1992,1967,eVn),MWn.tc=function(n){return q5(this,n)},MWn._b=function(n){return D_(this,n)},MWn.vc=function(){return new Bb(this)},MWn.xc=function(n){return qC(lsn(this,n))},MWn.ec=function(){return new Kb(this)},vX(YWn,"AbstractNavigableMap",1992),wAn(739,nVn,tVn,Bb),MWn.Hc=function(n){return cL(n,42)&&q5(this.b,BB(n,42))},MWn.Kc=function(){return new BR(this.b)},MWn.Mc=function(n){var t;return!!cL(n,42)&&(t=BB(n,42),z8(this.b,t))},MWn.gc=function(){return this.b.c},vX(YWn,"AbstractNavigableMap/EntrySet",739),wAn(493,nVn,rVn,Kb),MWn.Nc=function(){return new wS(this)},MWn.$b=function(){my(this.a)},MWn.Hc=function(n){return D_(this.a,n)},MWn.Kc=function(){return new Fb(new BR(new xN(this.a).b))},MWn.Mc=function(n){return!!D_(this.a,n)&&($J(this.a,n),!0)},MWn.gc=function(){return this.a.c},vX(YWn,"AbstractNavigableMap/NavigableKeySet",493),wAn(494,1,QWn,Fb),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return aS(this.a.a)},MWn.Pb=function(){return mx(this.a).cd()},MWn.Qb=function(){eK(this.a)},vX(YWn,"AbstractNavigableMap/NavigableKeySet/1",494),wAn(2004,28,ZWn),MWn.Fc=function(n){return F8(eMn(this,n)),!0},MWn.Gc=function(n){return kW(n),vH(n!=this,"Can't add a queue to itself"),Frn(this,n)},MWn.$b=function(){for(;null!=mnn(this););},vX(YWn,"AbstractQueue",2004),wAn(302,28,{4:1,20:1,28:1,14:1},Lp,d1),MWn.Fc=function(n){return w3(this,n),!0},MWn.$b=function(){o4(this)},MWn.Hc=function(n){return wun(new bV(this),n)},MWn.dc=function(){return Wy(this)},MWn.Kc=function(){return new bV(this)},MWn.Mc=function(n){return GJ(new bV(this),n)},MWn.gc=function(){return this.c-this.b&this.a.length-1},MWn.Nc=function(){return new w1(this,272)},MWn.Qc=function(n){var t;return t=this.c-this.b&this.a.length-1,n.length<t&&(n=qk(new Array(t),n)),urn(this,n,t),n.length>t&&$X(n,t,null),n},MWn.b=0,MWn.c=0,vX(YWn,"ArrayDeque",302),wAn(446,1,QWn,bV),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return this.a!=this.b},MWn.Pb=function(){return Khn(this)},MWn.Qb=function(){ein(this)},MWn.a=0,MWn.b=0,MWn.c=-1,vX(YWn,"ArrayDeque/IteratorImpl",446),wAn(12,52,QQn,Np,J6,tK),MWn.Vc=function(n,t){kG(this,n,t)},MWn.Fc=function(n){return WB(this,n)},MWn.Wc=function(n,t){return ohn(this,n,t)},MWn.Gc=function(n){return gun(this,n)},MWn.$b=function(){this.c=x8(Ant,HWn,1,0,5,1)},MWn.Hc=function(n){return-1!=E7(this,n,0)},MWn.Jc=function(n){Otn(this,n)},MWn.Xb=function(n){return xq(this,n)},MWn.Xc=function(n){return E7(this,n,0)},MWn.dc=function(){return 0==this.c.length},MWn.Kc=function(){return new Wb(this)},MWn.$c=function(n){return s6(this,n)},MWn.Mc=function(n){return y7(this,n)},MWn.Ud=function(n,t){h1(this,n,t)},MWn._c=function(n,t){return c5(this,n,t)},MWn.gc=function(){return this.c.length},MWn.ad=function(n){m$(this,n)},MWn.Pc=function(){return bx(this)},MWn.Qc=function(n){return Qgn(this,n)};var set,het,fet,bet,wet,det,get,pet,vet,met=vX(YWn,"ArrayList",12);wAn(7,1,QWn,Wb),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return y$(this)},MWn.Pb=function(){return n0(this)},MWn.Qb=function(){AU(this)},MWn.a=0,MWn.b=-1,vX(YWn,"ArrayList/1",7),wAn(2013,e.Function,{},T),MWn.te=function(n,t){return Pln(n,t)},wAn(154,52,YQn,Jy),MWn.Hc=function(n){return-1!=bin(this,n)},MWn.Jc=function(n){var t,e,i,r;for(kW(n),i=0,r=(e=this.a).length;i<r;++i)t=e[i],n.td(t)},MWn.Xb=function(n){return Dq(this,n)},MWn._c=function(n,t){var e;return l1(n,this.a.length),e=this.a[n],$X(this.a,n,t),e},MWn.gc=function(){return this.a.length},MWn.ad=function(n){yG(this.a,this.a.length,n)},MWn.Pc=function(){return Ygn(this,x8(Ant,HWn,1,this.a.length,5,1))},MWn.Qc=function(n){return Ygn(this,n)},vX(YWn,"Arrays/ArrayList",154),wAn(940,52,YQn,S),MWn.Hc=function(n){return!1},MWn.Xb=function(n){return yO(n)},MWn.Kc=function(){return SQ(),LT(),bet},MWn.Yc=function(){return SQ(),LT(),bet},MWn.gc=function(){return 0},vX(YWn,"Collections/EmptyList",940),wAn(941,1,cVn,P),MWn.Nb=function(n){fU(this,n)},MWn.Rb=function(n){throw Hp(new pv)},MWn.Ob=function(){return!1},MWn.Sb=function(){return!1},MWn.Pb=function(){throw Hp(new yv)},MWn.Tb=function(){return 0},MWn.Ub=function(){throw Hp(new yv)},MWn.Vb=function(){return-1},MWn.Qb=function(){throw Hp(new dv)},MWn.Wb=function(n){throw Hp(new dv)},vX(YWn,"Collections/EmptyListIterator",941),wAn(943,1967,jVn,I),MWn._b=function(n){return!1},MWn.uc=function(n){return!1},MWn.vc=function(){return SQ(),fet},MWn.xc=function(n){return null},MWn.ec=function(){return SQ(),fet},MWn.gc=function(){return 0},MWn.Cc=function(){return SQ(),set},vX(YWn,"Collections/EmptyMap",943),wAn(942,nVn,TVn,M),MWn.Hc=function(n){return!1},MWn.Kc=function(){return SQ(),LT(),bet},MWn.gc=function(){return 0},vX(YWn,"Collections/EmptySet",942),wAn(599,52,{3:1,20:1,28:1,52:1,14:1,15:1},Gb),MWn.Hc=function(n){return cV(this.a,n)},MWn.Xb=function(n){return l1(n,1),this.a},MWn.gc=function(){return 1},vX(YWn,"Collections/SingletonList",599),wAn(372,1,vVn,Hb),MWn.Jc=function(n){e5(this,n)},MWn.Lc=function(){return new Rq(null,this.Nc())},MWn.Nc=function(){return new w1(this,0)},MWn.Oc=function(){return new Rq(null,this.Nc())},MWn.Fc=function(n){return oE()},MWn.Gc=function(n){return sE()},MWn.$b=function(){hE()},MWn.Hc=function(n){return xT(this,n)},MWn.Ic=function(n){return DT(this,n)},MWn.dc=function(){return this.b.dc()},MWn.Kc=function(){return new qb(this.b.Kc())},MWn.Mc=function(n){return fE()},MWn.gc=function(){return this.b.gc()},MWn.Pc=function(){return this.b.Pc()},MWn.Qc=function(n){return RT(this,n)},MWn.Ib=function(){return Bbn(this.b)},vX(YWn,"Collections/UnmodifiableCollection",372),wAn(371,1,QWn,qb),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return this.b.Ob()},MWn.Pb=function(){return this.b.Pb()},MWn.Qb=function(){lE()},vX(YWn,"Collections/UnmodifiableCollectionIterator",371),wAn(531,372,JQn,bN),MWn.Nc=function(){return new w1(this,16)},MWn.Vc=function(n,t){throw Hp(new pv)},MWn.Wc=function(n,t){throw Hp(new pv)},MWn.Fb=function(n){return Nfn(this.a,n)},MWn.Xb=function(n){return this.a.Xb(n)},MWn.Hb=function(){return nsn(this.a)},MWn.Xc=function(n){return this.a.Xc(n)},MWn.dc=function(){return this.a.dc()},MWn.Yc=function(){return new wN(this.a.Zc(0))},MWn.Zc=function(n){return new wN(this.a.Zc(n))},MWn.$c=function(n){throw Hp(new pv)},MWn._c=function(n,t){throw Hp(new pv)},MWn.ad=function(n){throw Hp(new pv)},MWn.bd=function(n,t){return new bN(this.a.bd(n,t))},vX(YWn,"Collections/UnmodifiableList",531),wAn(690,371,cVn,wN),MWn.Qb=function(){lE()},MWn.Rb=function(n){throw Hp(new pv)},MWn.Sb=function(){return this.a.Sb()},MWn.Tb=function(){return this.a.Tb()},MWn.Ub=function(){return this.a.Ub()},MWn.Vb=function(){return this.a.Vb()},MWn.Wb=function(n){throw Hp(new pv)},vX(YWn,"Collections/UnmodifiableListIterator",690),wAn(600,1,JWn,Xb),MWn.wc=function(n){nan(this,n)},MWn.yc=function(n,t,e){return Zln(this,n,t,e)},MWn.$b=function(){throw Hp(new pv)},MWn._b=function(n){return this.c._b(n)},MWn.uc=function(n){return KT(this,n)},MWn.vc=function(){return eV(this)},MWn.Fb=function(n){return BT(this,n)},MWn.xc=function(n){return this.c.xc(n)},MWn.Hb=function(){return nsn(this.c)},MWn.dc=function(){return this.c.dc()},MWn.ec=function(){return iV(this)},MWn.zc=function(n,t){throw Hp(new pv)},MWn.Bc=function(n){throw Hp(new pv)},MWn.gc=function(){return this.c.gc()},MWn.Ib=function(){return Bbn(this.c)},MWn.Cc=function(){return tV(this)},vX(YWn,"Collections/UnmodifiableMap",600),wAn(382,372,EVn,Ak),MWn.Nc=function(){return new w1(this,1)},MWn.Fb=function(n){return Nfn(this.b,n)},MWn.Hb=function(){return nsn(this.b)},vX(YWn,"Collections/UnmodifiableSet",382),wAn(944,382,EVn,Lk),MWn.Hc=function(n){return _T(this,n)},MWn.Ic=function(n){return this.b.Ic(n)},MWn.Kc=function(){return new zb(this.b.Kc())},MWn.Pc=function(){var n;return j4(n=this.b.Pc(),n.length),n},MWn.Qc=function(n){return CY(this,n)},vX(YWn,"Collections/UnmodifiableMap/UnmodifiableEntrySet",944),wAn(945,1,QWn,zb),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return new Ub(BB(this.a.Pb(),42))},MWn.Ob=function(){return this.a.Ob()},MWn.Qb=function(){throw Hp(new pv)},vX(YWn,"Collections/UnmodifiableMap/UnmodifiableEntrySet/1",945),wAn(688,1,VQn,Ub),MWn.Fb=function(n){return this.a.Fb(n)},MWn.cd=function(){return this.a.cd()},MWn.dd=function(){return this.a.dd()},MWn.Hb=function(){return this.a.Hb()},MWn.ed=function(n){throw Hp(new pv)},MWn.Ib=function(){return Bbn(this.a)},vX(YWn,"Collections/UnmodifiableMap/UnmodifiableEntrySet/UnmodifiableEntry",688),wAn(601,531,{20:1,14:1,15:1,54:1},$k),vX(YWn,"Collections/UnmodifiableRandomAccessList",601),wAn(689,382,MVn,dN),MWn.Nc=function(){return new wS(this)},MWn.Fb=function(n){return Nfn(this.a,n)},MWn.Hb=function(){return nsn(this.a)},vX(YWn,"Collections/UnmodifiableSortedSet",689),wAn(847,1,ZQn,D),MWn.ue=function(n,t){var e;return 0!=(e=T4(BB(n,11),BB(t,11)))?e:nFn(BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(YWn,"Comparator/lambda$0$Type",847),wAn(751,1,ZQn,R),MWn.ue=function(n,t){return Kq(BB(n,35),BB(t,35))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return PQ(),get},vX(YWn,"Comparators/NaturalOrderComparator",751),wAn(1177,1,ZQn,_),MWn.ue=function(n,t){return Fq(BB(n,35),BB(t,35))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return PQ(),det},vX(YWn,"Comparators/ReverseNaturalOrderComparator",1177),wAn(64,1,ZQn,nw),MWn.Fb=function(n){return this===n},MWn.ue=function(n,t){return this.a.ue(t,n)},MWn.ve=function(){return this.a},vX(YWn,"Comparators/ReversedComparator",64),wAn(166,60,BVn,vv),vX(YWn,"ConcurrentModificationException",166),wAn(1904,1,nYn,K),MWn.we=function(n){hdn(this,n)},MWn.Ib=function(){return"DoubleSummaryStatistics[count = "+vz(this.a)+", avg = "+(oS(this.a,0)?l6(this)/j2(this.a):0)+", min = "+this.c+", max = "+this.b+", sum = "+l6(this)+"]"},MWn.a=0,MWn.b=_Qn,MWn.c=RQn,MWn.d=0,MWn.e=0,MWn.f=0,vX(YWn,"DoubleSummaryStatistics",1904),wAn(1805,60,BVn,mv),vX(YWn,"EmptyStackException",1805),wAn(451,1967,JWn,Hbn),MWn.zc=function(n,t){return wR(this,n,t)},MWn.$b=function(){TW(this)},MWn._b=function(n){return uS(this,n)},MWn.uc=function(n){var t,e;for(e=new QT(this.a);e.a<e.c.a.length;)if(t=u4(e),cV(n,this.b[t.g]))return!0;return!1},MWn.vc=function(){return new tw(this)},MWn.xc=function(n){return oV(this,n)},MWn.Bc=function(n){return NZ(this,n)},MWn.gc=function(){return this.a.c},vX(YWn,"EnumMap",451),wAn(1352,nVn,tVn,tw),MWn.$b=function(){TW(this.a)},MWn.Hc=function(n){return v2(this,n)},MWn.Kc=function(){return new Aq(this.a)},MWn.Mc=function(n){var t;return!!v2(this,n)&&(t=BB(n,42).cd(),NZ(this.a,t),!0)},MWn.gc=function(){return this.a.a.c},vX(YWn,"EnumMap/EntrySet",1352),wAn(1353,1,QWn,Aq),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return this.b=u4(this.a),new IS(this.c,this.b)},MWn.Ob=function(){return k$(this.a)},MWn.Qb=function(){Mx(!!this.b),NZ(this.c,this.b),this.b=null},vX(YWn,"EnumMap/EntrySetIterator",1353),wAn(1354,1984,VQn,IS),MWn.cd=function(){return this.a},MWn.dd=function(){return this.b.b[this.a.g]},MWn.ed=function(n){return EU(this.b,this.a.g,n)},vX(YWn,"EnumMap/MapEntry",1354),wAn(174,nVn,{20:1,28:1,14:1,174:1,21:1});var yet=vX(YWn,"EnumSet",174);wAn(156,174,{20:1,28:1,14:1,174:1,156:1,21:1},Y_),MWn.Fc=function(n){return orn(this,BB(n,22))},MWn.Hc=function(n){return IG(this,n)},MWn.Kc=function(){return new QT(this)},MWn.Mc=function(n){return CG(this,n)},MWn.gc=function(){return this.c},MWn.c=0,vX(YWn,"EnumSet/EnumSetImpl",156),wAn(343,1,QWn,QT),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return u4(this)},MWn.Ob=function(){return k$(this)},MWn.Qb=function(){Mx(-1!=this.b),$X(this.c.b,this.b,null),--this.c.c,this.b=-1},MWn.a=-1,MWn.b=-1,vX(YWn,"EnumSet/EnumSetImpl/IteratorImpl",343),wAn(43,488,tYn,xp,XT,mO),MWn.re=function(n,t){return GC(n)===GC(t)||null!=n&&Nfn(n,t)},MWn.se=function(n){return 0|nsn(n)},vX(YWn,"HashMap",43),wAn(53,nVn,eYn,Rv,bE,$q),MWn.Fc=function(n){return TU(this,n)},MWn.$b=function(){this.a.$b()},MWn.Hc=function(n){return FT(this,n)},MWn.dc=function(){return 0==this.a.gc()},MWn.Kc=function(){return this.a.ec().Kc()},MWn.Mc=function(n){return eL(this,n)},MWn.gc=function(){return this.a.gc()};var ket,jet=vX(YWn,"HashSet",53);wAn(1781,1,wVn,F),MWn.ud=function(n){ran(this,n)},MWn.Ib=function(){return"IntSummaryStatistics[count = "+vz(this.a)+", avg = "+(oS(this.a,0)?j2(this.d)/j2(this.a):0)+", min = "+this.c+", max = "+this.b+", sum = "+vz(this.d)+"]"},MWn.a=0,MWn.b=KVn,MWn.c=DWn,MWn.d=0,vX(YWn,"IntSummaryStatistics",1781),wAn(1049,1,pVn,eA),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new S2(this)},MWn.c=0,vX(YWn,"InternalHashCodeMap",1049),wAn(711,1,QWn,S2),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return this.d=this.a[this.c++],this.d},MWn.Ob=function(){var n;return this.c<this.a.length||!(n=this.b.next()).done&&(this.a=n.value[1],this.c=0,!0)},MWn.Qb=function(){gAn(this.e,this.d.cd()),0!=this.c&&--this.c},MWn.c=0,MWn.d=null,vX(YWn,"InternalHashCodeMap/1",711),wAn(1047,1,pVn,iA),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new p4(this)},MWn.c=0,MWn.d=0,vX(YWn,"InternalStringMap",1047),wAn(710,1,QWn,p4),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return this.c=this.a,this.a=this.b.next(),new J_(this.d,this.c,this.d.d)},MWn.Ob=function(){return!this.a.done},MWn.Qb=function(){Gan(this.d,this.c.value[0])},vX(YWn,"InternalStringMap/1",710),wAn(1048,1984,VQn,J_),MWn.cd=function(){return this.b.value[0]},MWn.dd=function(){return this.a.d!=this.c?hS(this.a,this.b.value[0]):this.b.value[1]},MWn.ed=function(n){return ubn(this.a,this.b.value[0],n)},MWn.c=0,vX(YWn,"InternalStringMap/2",1048),wAn(228,43,tYn,v4,q8),MWn.$b=function(){kR(this)},MWn._b=function(n){return lS(this,n)},MWn.uc=function(n){var t;for(t=this.d.a;t!=this.d;){if(cV(t.e,n))return!0;t=t.a}return!1},MWn.vc=function(){return new iw(this)},MWn.xc=function(n){return lnn(this,n)},MWn.zc=function(n,t){return Jgn(this,n,t)},MWn.Bc=function(n){return k7(this,n)},MWn.gc=function(){return NT(this.e)},MWn.c=!1,vX(YWn,"LinkedHashMap",228),wAn(387,383,{484:1,383:1,387:1,42:1},Ix,nH),vX(YWn,"LinkedHashMap/ChainEntry",387),wAn(701,nVn,tVn,iw),MWn.$b=function(){kR(this.a)},MWn.Hc=function(n){return y2(this,n)},MWn.Kc=function(){return new hW(this)},MWn.Mc=function(n){var t;return!!y2(this,n)&&(t=BB(n,42).cd(),k7(this.a,t),!0)},MWn.gc=function(){return NT(this.a.e)},vX(YWn,"LinkedHashMap/EntrySet",701),wAn(702,1,QWn,hW),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return s9(this)},MWn.Ob=function(){return this.b!=this.c.a.d},MWn.Qb=function(){Mx(!!this.a),p2(this.c.a.e,this),RH(this.a),v6(this.c.a.e,this.a.d),bD(this.c.a.e,this),this.a=null},vX(YWn,"LinkedHashMap/EntrySet/EntryIterator",702),wAn(178,53,eYn,fA,LN,Lq);var Eet=vX(YWn,"LinkedHashSet",178);wAn(68,1964,{3:1,4:1,20:1,28:1,52:1,14:1,68:1,15:1},YT,nK),MWn.Fc=function(n){return DH(this,n)},MWn.$b=function(){yQ(this)},MWn.Zc=function(n){return spn(this,n)},MWn.gc=function(){return this.b},MWn.b=0;var Tet,Met,Set,Pet,Iet,Cet=vX(YWn,"LinkedList",68);wAn(970,1,cVn,Z_),MWn.Nb=function(n){fU(this,n)},MWn.Rb=function(n){nX(this,n)},MWn.Ob=function(){return EE(this)},MWn.Sb=function(){return this.b.b!=this.d.a},MWn.Pb=function(){return b3(this)},MWn.Tb=function(){return this.a},MWn.Ub=function(){return U0(this)},MWn.Vb=function(){return this.a-1},MWn.Qb=function(){mtn(this)},MWn.Wb=function(n){Mx(!!this.c),this.c.c=n},MWn.a=0,MWn.c=null,vX(YWn,"LinkedList/ListIteratorImpl",970),wAn(608,1,{},$),vX(YWn,"LinkedList/Node",608),wAn(1959,1,{}),vX(YWn,"Locale",1959),wAn(861,1959,{},L),MWn.Ib=function(){return""},vX(YWn,"Locale/1",861),wAn(862,1959,{},N),MWn.Ib=function(){return"unknown"},vX(YWn,"Locale/4",862),wAn(109,60,{3:1,102:1,60:1,78:1,109:1},yv,lV),vX(YWn,"NoSuchElementException",109),wAn(404,1,{404:1},vy),MWn.Fb=function(n){var t;return n===this||!!cL(n,404)&&(t=BB(n,404),cV(this.a,t.a))},MWn.Hb=function(){return _A(this.a)},MWn.Ib=function(){return null!=this.a?GWn+kN(this.a)+")":"Optional.empty()"},vX(YWn,"Optional",404),wAn(463,1,{463:1},IO,yx),MWn.Fb=function(n){var t;return n===this||!!cL(n,463)&&(t=BB(n,463),this.a==t.a&&0==Pln(this.b,t.b))},MWn.Hb=function(){return this.a?IJ(this.b):0},MWn.Ib=function(){return this.a?"OptionalDouble.of("+this.b+")":"OptionalDouble.empty()"},MWn.a=!1,MWn.b=0,vX(YWn,"OptionalDouble",463),wAn(517,1,{517:1},CO,kx),MWn.Fb=function(n){var t;return n===this||!!cL(n,517)&&(t=BB(n,517),this.a==t.a&&0==E$(this.b,t.b))},MWn.Hb=function(){return this.a?this.b:0},MWn.Ib=function(){return this.a?"OptionalInt.of("+this.b+")":"OptionalInt.empty()"},MWn.a=!1,MWn.b=0,vX(YWn,"OptionalInt",517),wAn(503,2004,ZWn,Xz),MWn.Gc=function(n){return ikn(this,n)},MWn.$b=function(){this.b.c=x8(Ant,HWn,1,0,5,1)},MWn.Hc=function(n){return-1!=(null==n?-1:E7(this.b,n,0))},MWn.Kc=function(){return new Vb(this)},MWn.Mc=function(n){return srn(this,n)},MWn.gc=function(){return this.b.c.length},MWn.Nc=function(){return new w1(this,256)},MWn.Pc=function(){return bx(this.b)},MWn.Qc=function(n){return Qgn(this.b,n)},vX(YWn,"PriorityQueue",503),wAn(1277,1,QWn,Vb),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return this.a<this.c.b.c.length},MWn.Pb=function(){return Px(this.a<this.c.b.c.length),this.b=this.a++,xq(this.c.b,this.b)},MWn.Qb=function(){Mx(-1!=this.b),hrn(this.c,this.a=this.b),this.b=-1},MWn.a=0,MWn.b=-1,vX(YWn,"PriorityQueue/1",1277),wAn(230,1,{230:1},sbn,I4),MWn.a=0,MWn.b=0;var Oet,Aet,$et,Let=0;vX(YWn,"Random",230),wAn(27,1,fVn,w1,zU,IV),MWn.qd=function(){return this.a},MWn.rd=function(){return Dz(this),this.c},MWn.Nb=function(n){Dz(this),this.d.Nb(n)},MWn.sd=function(n){return ntn(this,n)},MWn.a=0,MWn.c=0,vX(YWn,"Spliterators/IteratorSpliterator",27),wAn(485,27,fVn,wS),vX(YWn,"SortedSet/1",485),wAn(602,1,nYn,Qb),MWn.we=function(n){this.a.td(n)},vX(YWn,"Spliterator/OfDouble/0methodref$accept$Type",602),wAn(603,1,nYn,Yb),MWn.we=function(n){this.a.td(n)},vX(YWn,"Spliterator/OfDouble/1methodref$accept$Type",603),wAn(604,1,wVn,Jb),MWn.ud=function(n){this.a.td(iln(n))},vX(YWn,"Spliterator/OfInt/2methodref$accept$Type",604),wAn(605,1,wVn,Zb),MWn.ud=function(n){this.a.td(iln(n))},vX(YWn,"Spliterator/OfInt/3methodref$accept$Type",605),wAn(617,1,fVn),MWn.Nb=function(n){pE(this,n)},MWn.qd=function(){return this.d},MWn.rd=function(){return this.e},MWn.d=0,MWn.e=0,vX(YWn,"Spliterators/BaseSpliterator",617),wAn(721,617,fVn),MWn.xe=function(n){gE(this,n)},MWn.Nb=function(n){cL(n,182)?gE(this,BB(n,182)):gE(this,new Yb(n))},MWn.sd=function(n){return cL(n,182)?this.ye(BB(n,182)):this.ye(new Qb(n))},vX(YWn,"Spliterators/AbstractDoubleSpliterator",721),wAn(720,617,fVn),MWn.xe=function(n){gE(this,n)},MWn.Nb=function(n){cL(n,196)?gE(this,BB(n,196)):gE(this,new Zb(n))},MWn.sd=function(n){return cL(n,196)?this.ye(BB(n,196)):this.ye(new Jb(n))},vX(YWn,"Spliterators/AbstractIntSpliterator",720),wAn(540,617,fVn),vX(YWn,"Spliterators/AbstractSpliterator",540),wAn(692,1,fVn),MWn.Nb=function(n){pE(this,n)},MWn.qd=function(){return this.b},MWn.rd=function(){return this.d-this.c},MWn.b=0,MWn.c=0,MWn.d=0,vX(YWn,"Spliterators/BaseArraySpliterator",692),wAn(947,692,fVn,BH),MWn.ze=function(n,t){cj(this,BB(n,38),t)},MWn.Nb=function(n){DX(this,n)},MWn.sd=function(n){return _6(this,n)},vX(YWn,"Spliterators/ArraySpliterator",947),wAn(693,692,fVn,K_),MWn.ze=function(n,t){aj(this,BB(n,182),t)},MWn.xe=function(n){DX(this,n)},MWn.Nb=function(n){cL(n,182)?DX(this,BB(n,182)):DX(this,new Yb(n))},MWn.ye=function(n){return _6(this,n)},MWn.sd=function(n){return cL(n,182)?_6(this,BB(n,182)):_6(this,new Qb(n))},vX(YWn,"Spliterators/DoubleArraySpliterator",693),wAn(1968,1,fVn),MWn.Nb=function(n){pE(this,n)},MWn.qd=function(){return 16448},MWn.rd=function(){return 0},vX(YWn,"Spliterators/EmptySpliterator",1968),wAn(946,1968,fVn,z),MWn.xe=function(n){Bf(n)},MWn.Nb=function(n){cL(n,196)?Bf(BB(n,196)):Bf(new Zb(n))},MWn.ye=function(n){return bS(n)},MWn.sd=function(n){return cL(n,196)?bS(BB(n,196)):bS(new Jb(n))},vX(YWn,"Spliterators/EmptySpliterator/OfInt",946),wAn(580,52,fYn,Kv),MWn.Vc=function(n,t){_z(n,this.a.c.length+1),kG(this.a,n,t)},MWn.Fc=function(n){return WB(this.a,n)},MWn.Wc=function(n,t){return _z(n,this.a.c.length+1),ohn(this.a,n,t)},MWn.Gc=function(n){return gun(this.a,n)},MWn.$b=function(){this.a.c=x8(Ant,HWn,1,0,5,1)},MWn.Hc=function(n){return-1!=E7(this.a,n,0)},MWn.Ic=function(n){return oun(this.a,n)},MWn.Jc=function(n){Otn(this.a,n)},MWn.Xb=function(n){return _z(n,this.a.c.length),xq(this.a,n)},MWn.Xc=function(n){return E7(this.a,n,0)},MWn.dc=function(){return 0==this.a.c.length},MWn.Kc=function(){return new Wb(this.a)},MWn.$c=function(n){return _z(n,this.a.c.length),s6(this.a,n)},MWn.Ud=function(n,t){h1(this.a,n,t)},MWn._c=function(n,t){return _z(n,this.a.c.length),c5(this.a,n,t)},MWn.gc=function(){return this.a.c.length},MWn.ad=function(n){m$(this.a,n)},MWn.bd=function(n,t){return new s1(this.a,n,t)},MWn.Pc=function(){return bx(this.a)},MWn.Qc=function(n){return Qgn(this.a,n)},MWn.Ib=function(){return LMn(this.a)},vX(YWn,"Vector",580),wAn(809,580,fYn,om),vX(YWn,"Stack",809),wAn(206,1,{206:1},$an),MWn.Ib=function(){return W0(this)},vX(YWn,"StringJoiner",206),wAn(544,1992,{3:1,83:1,171:1,161:1},WT,Wz),MWn.$b=function(){my(this)},MWn.vc=function(){return new xN(this)},MWn.zc=function(n,t){return Mon(this,n,t)},MWn.Bc=function(n){return $J(this,n)},MWn.gc=function(){return this.c},MWn.c=0,vX(YWn,"TreeMap",544),wAn(390,1,QWn,BR),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return mx(this)},MWn.Ob=function(){return aS(this.a)},MWn.Qb=function(){eK(this)},vX(YWn,"TreeMap/EntryIterator",390),wAn(435,739,tVn,xN),MWn.$b=function(){my(this.a)},vX(YWn,"TreeMap/EntrySet",435),wAn(436,383,{484:1,383:1,42:1,436:1},H8),MWn.b=!1;var Net,xet,Det,Ret,_et=vX(YWn,"TreeMap/Node",436);wAn(621,1,{},q),MWn.Ib=function(){return"State: mv="+this.c+" value="+this.d+" done="+this.a+" found="+this.b},MWn.a=!1,MWn.b=!1,MWn.c=!1,vX(YWn,"TreeMap/State",621),wAn(297,22,lYn,gS),MWn.Ae=function(){return!1},MWn.Be=function(){return!1};var Ket,Fet=Ben(YWn,"TreeMap/SubMapType",297,Unt,J2,hK);wAn(1112,297,lYn,LA),MWn.Be=function(){return!0},Ben(YWn,"TreeMap/SubMapType/1",1112,Fet,null,null),wAn(1113,297,lYn,A$),MWn.Ae=function(){return!0},MWn.Be=function(){return!0},Ben(YWn,"TreeMap/SubMapType/2",1113,Fet,null,null),wAn(1114,297,lYn,NA),MWn.Ae=function(){return!0},Ben(YWn,"TreeMap/SubMapType/3",1114,Fet,null,null),wAn(208,nVn,{3:1,20:1,28:1,14:1,271:1,21:1,84:1,208:1},zv,dE),MWn.Nc=function(){return new wS(this)},MWn.Fc=function(n){return ZU(this,n)},MWn.$b=function(){my(this.a)},MWn.Hc=function(n){return D_(this.a,n)},MWn.Kc=function(){return new Fb(new BR(new xN(new Kb(this.a).a).b))},MWn.Mc=function(n){return MN(this,n)},MWn.gc=function(){return this.a.c};var Bet=vX(YWn,"TreeSet",208);wAn(966,1,{},rw),MWn.Ce=function(n,t){return DD(this.a,n,t)},vX(bYn,"BinaryOperator/lambda$0$Type",966),wAn(967,1,{},cw),MWn.Ce=function(n,t){return RD(this.a,n,t)},vX(bYn,"BinaryOperator/lambda$1$Type",967),wAn(846,1,{},G),MWn.Kb=function(n){return n},vX(bYn,"Function/lambda$0$Type",846),wAn(431,1,DVn,aw),MWn.Mb=function(n){return!this.a.Mb(n)},vX(bYn,"Predicate/lambda$2$Type",431),wAn(572,1,{572:1});var Het,qet,Get=vX(wYn,"Handler",572);wAn(2007,1,_Wn),MWn.ne=function(){return"DUMMY"},MWn.Ib=function(){return this.ne()},vX(wYn,"Level",2007),wAn(1621,2007,_Wn,U),MWn.ne=function(){return"INFO"},vX(wYn,"Level/LevelInfo",1621),wAn(1640,1,{},_v),vX(wYn,"LogManager",1640),wAn(1780,1,_Wn,iK),MWn.b=null,vX(wYn,"LogRecord",1780),wAn(512,1,{512:1},y5),MWn.e=!1;var zet,Uet,Xet,Wet=!1,Vet=!1,Qet=!1,Yet=!1,Jet=!1;vX(wYn,"Logger",512),wAn(819,572,{572:1},X),vX(wYn,"SimpleConsoleLogHandler",819),wAn(132,22,{3:1,35:1,22:1,132:1},pS);var Zet,nit=Ben(pYn,"Collector/Characteristics",132,Unt,p1,fK);wAn(744,1,{},jU),vX(pYn,"CollectorImpl",744),wAn(1060,1,{},W),MWn.Ce=function(n,t){return Ofn(BB(n,206),BB(t,206))},vX(pYn,"Collectors/10methodref$merge$Type",1060),wAn(1061,1,{},V),MWn.Kb=function(n){return W0(BB(n,206))},vX(pYn,"Collectors/11methodref$toString$Type",1061),wAn(1062,1,{},uw),MWn.Kb=function(n){return hN(),!!TO(n)},vX(pYn,"Collectors/12methodref$test$Type",1062),wAn(251,1,{},B),MWn.Od=function(n,t){BB(n,14).Fc(t)},vX(pYn,"Collectors/20methodref$add$Type",251),wAn(253,1,{},H),MWn.Ee=function(){return new Np},vX(pYn,"Collectors/21methodref$ctor$Type",253),wAn(346,1,{},Q),MWn.Ee=function(){return new Rv},vX(pYn,"Collectors/23methodref$ctor$Type",346),wAn(347,1,{},Y),MWn.Od=function(n,t){TU(BB(n,53),t)},vX(pYn,"Collectors/24methodref$add$Type",347),wAn(1055,1,{},J),MWn.Ce=function(n,t){return ZT(BB(n,15),BB(t,14))},vX(pYn,"Collectors/4methodref$addAll$Type",1055),wAn(1059,1,{},Z),MWn.Od=function(n,t){b6(BB(n,206),BB(t,475))},vX(pYn,"Collectors/9methodref$add$Type",1059),wAn(1058,1,{},YB),MWn.Ee=function(){return new $an(this.a,this.b,this.c)},vX(pYn,"Collectors/lambda$15$Type",1058),wAn(1063,1,{},nn),MWn.Ee=function(){var n;return Jgn(n=new v4,(hN(),!1),new Np),Jgn(n,!0,new Np),n},vX(pYn,"Collectors/lambda$22$Type",1063),wAn(1064,1,{},ow),MWn.Ee=function(){return Pun(Gk(Ant,1),HWn,1,5,[this.a])},vX(pYn,"Collectors/lambda$25$Type",1064),wAn(1065,1,{},sw),MWn.Od=function(n,t){Bq(this.a,een(n))},vX(pYn,"Collectors/lambda$26$Type",1065),wAn(1066,1,{},hw),MWn.Ce=function(n,t){return Kz(this.a,een(n),een(t))},vX(pYn,"Collectors/lambda$27$Type",1066),wAn(1067,1,{},tn),MWn.Kb=function(n){return een(n)[0]},vX(pYn,"Collectors/lambda$28$Type",1067),wAn(713,1,{},en),MWn.Ce=function(n,t){return Hq(n,t)},vX(pYn,"Collectors/lambda$4$Type",713),wAn(252,1,{},rn),MWn.Ce=function(n,t){return GT(BB(n,14),BB(t,14))},vX(pYn,"Collectors/lambda$42$Type",252),wAn(348,1,{},cn),MWn.Ce=function(n,t){return zT(BB(n,53),BB(t,53))},vX(pYn,"Collectors/lambda$50$Type",348),wAn(349,1,{},an),MWn.Kb=function(n){return BB(n,53)},vX(pYn,"Collectors/lambda$51$Type",349),wAn(1054,1,{},fw),MWn.Od=function(n,t){bsn(this.a,BB(n,83),t)},vX(pYn,"Collectors/lambda$7$Type",1054),wAn(1056,1,{},un),MWn.Ce=function(n,t){return pun(BB(n,83),BB(t,83),new J)},vX(pYn,"Collectors/lambda$8$Type",1056),wAn(1057,1,{},lw),MWn.Kb=function(n){return mbn(this.a,BB(n,83))},vX(pYn,"Collectors/lambda$9$Type",1057),wAn(539,1,{}),MWn.He=function(){jW(this)},MWn.d=!1,vX(pYn,"TerminatableStream",539),wAn(812,539,vYn,AD),MWn.He=function(){jW(this)},vX(pYn,"DoubleStreamImpl",812),wAn(1784,721,fVn,ZB),MWn.ye=function(n){return pmn(this,BB(n,182))},MWn.a=null,vX(pYn,"DoubleStreamImpl/2",1784),wAn(1785,1,nYn,bw),MWn.we=function(n){HA(this.a,n)},vX(pYn,"DoubleStreamImpl/2/lambda$0$Type",1785),wAn(1782,1,nYn,ww),MWn.we=function(n){BA(this.a,n)},vX(pYn,"DoubleStreamImpl/lambda$0$Type",1782),wAn(1783,1,nYn,dw),MWn.we=function(n){hdn(this.a,n)},vX(pYn,"DoubleStreamImpl/lambda$2$Type",1783),wAn(1358,720,fVn,m5),MWn.ye=function(n){return k2(this,BB(n,196))},MWn.a=0,MWn.b=0,MWn.c=0,vX(pYn,"IntStream/5",1358),wAn(787,539,vYn,$D),MWn.He=function(){jW(this)},MWn.Ie=function(){return EW(this),this.a},vX(pYn,"IntStreamImpl",787),wAn(788,539,vYn,VT),MWn.He=function(){jW(this)},MWn.Ie=function(){return EW(this),CL(),$et},vX(pYn,"IntStreamImpl/Empty",788),wAn(1463,1,wVn,gw),MWn.ud=function(n){ran(this.a,n)},vX(pYn,"IntStreamImpl/lambda$4$Type",1463);var tit,eit=bq(pYn,"Stream");wAn(30,539,{525:1,670:1,833:1},Rq),MWn.He=function(){jW(this)},vX(pYn,"StreamImpl",30),wAn(845,1,{},on),MWn.ld=function(n){return lH(n)},vX(pYn,"StreamImpl/0methodref$lambda$2$Type",845),wAn(1084,540,fVn,__),MWn.sd=function(n){for(;$9(this);){if(this.a.sd(n))return!0;jW(this.b),this.b=null,this.a=null}return!1},vX(pYn,"StreamImpl/1",1084),wAn(1085,1,lVn,pw),MWn.td=function(n){iH(this.a,BB(n,833))},vX(pYn,"StreamImpl/1/lambda$0$Type",1085),wAn(1086,1,DVn,vw),MWn.Mb=function(n){return TU(this.a,n)},vX(pYn,"StreamImpl/1methodref$add$Type",1086),wAn(1087,540,fVn,vQ),MWn.sd=function(n){var t;return this.a||(t=new Np,this.b.a.Nb(new mw(t)),SQ(),m$(t,this.c),this.a=new w1(t,16)),ntn(this.a,n)},MWn.a=null,vX(pYn,"StreamImpl/5",1087),wAn(1088,1,lVn,mw),MWn.td=function(n){WB(this.a,n)},vX(pYn,"StreamImpl/5/2methodref$add$Type",1088),wAn(722,540,fVn,Q9),MWn.sd=function(n){for(this.b=!1;!this.b&&this.c.sd(new AS(this,n)););return this.b},MWn.b=!1,vX(pYn,"StreamImpl/FilterSpliterator",722),wAn(1079,1,lVn,AS),MWn.td=function(n){Rz(this.a,this.b,n)},vX(pYn,"StreamImpl/FilterSpliterator/lambda$0$Type",1079),wAn(1075,721,fVn,E6),MWn.ye=function(n){return j_(this,BB(n,182))},vX(pYn,"StreamImpl/MapToDoubleSpliterator",1075),wAn(1078,1,lVn,$S),MWn.td=function(n){jS(this.a,this.b,n)},vX(pYn,"StreamImpl/MapToDoubleSpliterator/lambda$0$Type",1078),wAn(1074,720,fVn,T6),MWn.ye=function(n){return E_(this,BB(n,196))},vX(pYn,"StreamImpl/MapToIntSpliterator",1074),wAn(1077,1,lVn,LS),MWn.td=function(n){kS(this.a,this.b,n)},vX(pYn,"StreamImpl/MapToIntSpliterator/lambda$0$Type",1077),wAn(719,540,fVn,M6),MWn.sd=function(n){return T_(this,n)},vX(pYn,"StreamImpl/MapToObjSpliterator",719),wAn(1076,1,lVn,NS),MWn.td=function(n){ES(this.a,this.b,n)},vX(pYn,"StreamImpl/MapToObjSpliterator/lambda$0$Type",1076),wAn(618,1,lVn,sn),MWn.td=function(n){Cl(this,n)},vX(pYn,"StreamImpl/ValueConsumer",618),wAn(1080,1,lVn,hn),MWn.td=function(n){dM()},vX(pYn,"StreamImpl/lambda$0$Type",1080),wAn(1081,1,lVn,fn),MWn.td=function(n){dM()},vX(pYn,"StreamImpl/lambda$1$Type",1081),wAn(1082,1,{},yw),MWn.Ce=function(n,t){return FK(this.a,n,t)},vX(pYn,"StreamImpl/lambda$4$Type",1082),wAn(1083,1,lVn,CS),MWn.td=function(n){ER(this.b,this.a,n)},vX(pYn,"StreamImpl/lambda$5$Type",1083),wAn(1089,1,lVn,kw),MWn.td=function(n){Hon(this.a,BB(n,365))},vX(pYn,"TerminatableStream/lambda$0$Type",1089),wAn(2041,1,{}),wAn(1914,1,{},ln),vX("javaemul.internal","ConsoleLogger",1914),wAn(2038,1,{});var iit,rit,cit=0,ait=0;wAn(1768,1,lVn,bn),MWn.td=function(n){BB(n,308)},vX(TYn,"BowyerWatsonTriangulation/lambda$0$Type",1768),wAn(1769,1,lVn,jw),MWn.td=function(n){Frn(this.a,BB(n,308).e)},vX(TYn,"BowyerWatsonTriangulation/lambda$1$Type",1769),wAn(1770,1,lVn,wn),MWn.td=function(n){BB(n,168)},vX(TYn,"BowyerWatsonTriangulation/lambda$2$Type",1770),wAn(1765,1,MYn,Ew),MWn.ue=function(n,t){return q3(this.a,BB(n,168),BB(t,168))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(TYn,"NaiveMinST/lambda$0$Type",1765),wAn(499,1,{},Tw),vX(TYn,"NodeMicroLayout",499),wAn(168,1,{168:1},xS),MWn.Fb=function(n){var t;return!!cL(n,168)&&(t=BB(n,168),cV(this.a,t.a)&&cV(this.b,t.b)||cV(this.a,t.b)&&cV(this.b,t.a))},MWn.Hb=function(){return _A(this.a)+_A(this.b)};var uit=vX(TYn,"TEdge",168);wAn(308,1,{308:1},ZFn),MWn.Fb=function(n){var t;return!!cL(n,308)&&_7(this,(t=BB(n,308)).a)&&_7(this,t.b)&&_7(this,t.c)},MWn.Hb=function(){return _A(this.a)+_A(this.b)+_A(this.c)},vX(TYn,"TTriangle",308),wAn(221,1,{221:1},I$),vX(TYn,"Tree",221),wAn(1254,1,{},CZ),vX(SYn,"Scanline",1254);var oit=bq(SYn,PYn);wAn(1692,1,{},ltn),vX(IYn,"CGraph",1692),wAn(307,1,{307:1},cZ),MWn.b=0,MWn.c=0,MWn.d=0,MWn.g=0,MWn.i=0,MWn.k=_Qn,vX(IYn,"CGroup",307),wAn(815,1,{},Xv),vX(IYn,"CGroup/CGroupBuilder",815),wAn(57,1,{57:1},AR),MWn.Ib=function(){return this.j?SD(this.j.Kb(this)):(ED(bit),bit.o+"@"+(PN(this)>>>0).toString(16))},MWn.f=0,MWn.i=_Qn;var sit,hit,fit,lit,bit=vX(IYn,"CNode",57);wAn(814,1,{},Wv),vX(IYn,"CNode/CNodeBuilder",814),wAn(1525,1,{},dn),MWn.Oe=function(n,t){return 0},MWn.Pe=function(n,t){return 0},vX(IYn,OYn,1525),wAn(1790,1,{},gn),MWn.Le=function(n){var t,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(h=RQn,r=new Wb(n.a.b);r.a<r.c.c.length;)t=BB(n0(r),57),h=e.Math.min(h,t.a.j.d.c+t.b.a);for(w=new YT,u=new Wb(n.a.a);u.a<u.c.c.length;)(a=BB(n0(u),307)).k=h,0==a.g&&r5(w,a,w.c.b,w.c);for(;0!=w.b;){for(c=(a=BB(0==w.b?null:(Px(0!=w.b),Atn(w,w.a.a)),307)).j.d.c,b=a.a.a.ec().Kc();b.Ob();)f=BB(b.Pb(),57),g=a.k+f.b.a,!Ghn(n,a,n.d)||f.d.c<g?f.i=g:f.i=f.d.c;for(c-=a.j.i,a.b+=c,n.d==(Ffn(),FPt)||n.d==_Pt?a.c+=c:a.c-=c,l=a.a.a.ec().Kc();l.Ob();)for(s=(f=BB(l.Pb(),57)).c.Kc();s.Ob();)o=BB(s.Pb(),57),d=dA(n.d)?n.g.Oe(f,o):n.g.Pe(f,o),o.a.k=e.Math.max(o.a.k,f.i+f.d.b+d-o.b.a),cY(n,o,n.d)&&(o.a.k=e.Math.max(o.a.k,o.d.c-o.b.a)),--o.a.g,0==o.a.g&&DH(w,o.a)}for(i=new Wb(n.a.b);i.a<i.c.c.length;)(t=BB(n0(i),57)).d.c=t.i},vX(IYn,"LongestPathCompaction",1790),wAn(1690,1,{},yOn),MWn.e=!1;var wit,dit,git=vX(IYn,xYn,1690);wAn(1691,1,lVn,Mw),MWn.td=function(n){iun(this.a,BB(n,46))},vX(IYn,DYn,1691),wAn(1791,1,{},pn),MWn.Me=function(n){var t,e,i,r,c,a;for(t=new Wb(n.a.b);t.a<t.c.c.length;)BB(n0(t),57).c.$b();for(i=new Wb(n.a.b);i.a<i.c.c.length;)for(e=BB(n0(i),57),c=new Wb(n.a.b);c.a<c.c.c.length;)e!=(r=BB(n0(c),57))&&(e.a&&e.a==r.a||(a=dA(n.d)?n.g.Pe(e,r):n.g.Oe(e,r),(r.d.c>e.d.c||e.d.c==r.d.c&&e.d.b<r.d.b)&&Rdn(r.d.d+r.d.a+a,e.d.d)&&_dn(r.d.d,e.d.d+e.d.a+a)&&e.c.Fc(r)))},vX(IYn,"QuadraticConstraintCalculation",1791),wAn(522,1,{522:1},Dp),MWn.a=!1,MWn.b=!1,MWn.c=!1,MWn.d=!1,vX(IYn,RYn,522),wAn(803,1,{},RG),MWn.Me=function(n){this.c=n,pIn(this,new yn)},vX(IYn,_Yn,803),wAn(1718,1,{679:1},fY),MWn.Ke=function(n){KPn(this,BB(n,464))},vX(IYn,KYn,1718),wAn(1719,1,MYn,vn),MWn.ue=function(n,t){return uQ(BB(n,57),BB(t,57))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(IYn,FYn,1719),wAn(464,1,{464:1},OS),MWn.a=!1,vX(IYn,BYn,464),wAn(1720,1,MYn,mn),MWn.ue=function(n,t){return Jkn(BB(n,464),BB(t,464))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(IYn,HYn,1720),wAn(1721,1,qYn,yn),MWn.Lb=function(n){return BB(n,57),!0},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return BB(n,57),!0},vX(IYn,"ScanlineConstraintCalculator/lambda$1$Type",1721),wAn(428,22,{3:1,35:1,22:1,428:1},FS);var pit,vit,mit,yit=Ben(GYn,"HighLevelSortingCriterion",428,Unt,rJ,lK);wAn(427,22,{3:1,35:1,22:1,427:1},BS);var kit,jit,Eit,Tit,Mit,Sit,Pit,Iit,Cit,Oit,Ait,$it,Lit,Nit,xit,Dit,Rit,_it=Ben(GYn,"LowLevelSortingCriterion",427,Unt,cJ,bK),Kit=bq(zYn,"ILayoutMetaDataProvider");wAn(853,1,QYn,Gh),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,UYn),YYn),"Polyomino Traversal Strategy"),"Traversal strategy for trying different candidate positions for polyominoes."),Iit),(PPn(),gMt)),Bit),nbn((rpn(),hMt))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,XYn),YYn),"Polyomino Secondary Sorting Criterion"),"Possible secondary sorting criteria for the processing order of polyominoes. They are used when polyominoes are equal according to the primary sorting criterion HighLevelSortingCriterion."),Sit),gMt),_it),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,WYn),YYn),"Polyomino Primary Sorting Criterion"),"Possible primary sorting criteria for the processing order of polyominoes."),Tit),gMt),yit),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,VYn),YYn),"Fill Polyominoes"),"Use the Profile Fill algorithm to fill polyominoes to prevent small polyominoes from being placed inside of big polyominoes with large holes. Might increase packing area."),(hN(),!0)),wMt),ktt),nbn(hMt))))},vX(GYn,"PolyominoOptions",853),wAn(250,22,{3:1,35:1,22:1,250:1},HS);var Fit,Bit=Ben(GYn,"TraversalStrategy",250,Unt,Tin,wK);wAn(213,1,{213:1},kn),MWn.Ib=function(){return"NEdge[id="+this.b+" w="+this.g+" d="+this.a+"]"},MWn.a=1,MWn.b=0,MWn.c=0,MWn.f=!1,MWn.g=0;var Hit=vX(JYn,"NEdge",213);wAn(176,1,{},Hv),vX(JYn,"NEdge/NEdgeBuilder",176),wAn(653,1,{},Fv),vX(JYn,"NGraph",653),wAn(121,1,{121:1},k6),MWn.c=-1,MWn.d=0,MWn.e=0,MWn.i=-1,MWn.j=!1;var qit=vX(JYn,"NNode",121);wAn(795,1,JQn,Bv),MWn.Jc=function(n){e5(this,n)},MWn.Lc=function(){return new Rq(null,new w1(this,16))},MWn.ad=function(n){Krn(this,n)},MWn.Nc=function(){return new w1(this,16)},MWn.Oc=function(){return new Rq(null,new w1(this,16))},MWn.Vc=function(n,t){++this.b,kG(this.a,n,t)},MWn.Fc=function(n){return RN(this,n)},MWn.Wc=function(n,t){return++this.b,ohn(this.a,n,t)},MWn.Gc=function(n){return++this.b,gun(this.a,n)},MWn.$b=function(){++this.b,this.a.c=x8(Ant,HWn,1,0,5,1)},MWn.Hc=function(n){return-1!=E7(this.a,n,0)},MWn.Ic=function(n){return oun(this.a,n)},MWn.Xb=function(n){return xq(this.a,n)},MWn.Xc=function(n){return E7(this.a,n,0)},MWn.dc=function(){return 0==this.a.c.length},MWn.Kc=function(){return L9(new Wb(this.a))},MWn.Yc=function(){throw Hp(new pv)},MWn.Zc=function(n){throw Hp(new pv)},MWn.$c=function(n){return++this.b,s6(this.a,n)},MWn.Mc=function(n){return _N(this,n)},MWn._c=function(n,t){return++this.b,c5(this.a,n,t)},MWn.gc=function(){return this.a.c.length},MWn.bd=function(n,t){return new s1(this.a,n,t)},MWn.Pc=function(){return bx(this.a)},MWn.Qc=function(n){return Qgn(this.a,n)},MWn.b=0,vX(JYn,"NNode/ChangeAwareArrayList",795),wAn(269,1,{},qv),vX(JYn,"NNode/NNodeBuilder",269),wAn(1630,1,{},jn),MWn.a=!1,MWn.f=DWn,MWn.j=0,vX(JYn,"NetworkSimplex",1630),wAn(1294,1,lVn,Sw),MWn.td=function(n){qzn(this.a,BB(n,680),!0,!1)},vX(nJn,"NodeLabelAndSizeCalculator/lambda$0$Type",1294),wAn(558,1,{},Pw),MWn.b=!0,MWn.c=!0,MWn.d=!0,MWn.e=!0,vX(nJn,"NodeMarginCalculator",558),wAn(212,1,{212:1}),MWn.j=!1,MWn.k=!1;var Git,zit,Uit,Xit=vX(tJn,"Cell",212);wAn(124,212,{124:1,212:1},FR),MWn.Re=function(){return XH(this)},MWn.Se=function(){var n;return n=this.n,this.a.a+n.b+n.c},vX(tJn,"AtomicCell",124),wAn(232,22,{3:1,35:1,22:1,232:1},qS);var Wit,Vit=Ben(tJn,"ContainerArea",232,Unt,v1,dK);wAn(326,212,iJn),vX(tJn,"ContainerCell",326),wAn(1473,326,iJn,Hwn),MWn.Re=function(){var n;return n=0,this.e?this.b?n=this.b.b:this.a[1][1]&&(n=this.a[1][1].Re()):n=Ybn(this,Umn(this,!0)),n>0?n+this.n.d+this.n.a:0},MWn.Se=function(){var n,t,i,r,c;if(c=0,this.e)this.b?c=this.b.a:this.a[1][1]&&(c=this.a[1][1].Se());else if(this.g)c=Ybn(this,Okn(this,null,!0));else for(Dtn(),i=0,r=(t=Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length;i<r;++i)n=t[i],c=e.Math.max(c,Ybn(this,Okn(this,n,!0)));return c>0?c+this.n.b+this.n.c:0},MWn.Te=function(){var n,t,e,i,r;if(this.g)for(n=Okn(this,null,!1),Dtn(),i=0,r=(e=Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length;i<r;++i)Vxn(this,t=e[i],n);else for(Dtn(),i=0,r=(e=Pun(Gk(Vit,1),$Vn,232,0,[Git,zit,Uit])).length;i<r;++i)Vxn(this,t=e[i],n=Okn(this,t,!1))},MWn.Ue=function(){var n,t,i,r;t=this.i,n=this.n,r=Umn(this,!1),Q5(this,(Dtn(),Git),t.d+n.d,r),Q5(this,Uit,t.d+t.a-n.a-r[2],r),i=t.a-n.d-n.a,r[0]>0&&(r[0]+=this.d,i-=r[0]),r[2]>0&&(r[2]+=this.d,i-=r[2]),this.c.a=e.Math.max(0,i),this.c.d=t.d+n.d+(this.c.a-i)/2,r[1]=e.Math.max(r[1],i),Q5(this,zit,t.d+n.d+r[0]-(r[1]-i)/2,r)},MWn.b=null,MWn.d=0,MWn.e=!1,MWn.f=!1,MWn.g=!1;var Qit,Yit,Jit,Zit=0,nrt=0;vX(tJn,"GridContainerCell",1473),wAn(461,22,{3:1,35:1,22:1,461:1},GS);var trt,ert=Ben(tJn,"HorizontalLabelAlignment",461,Unt,m1,gK);wAn(306,212,{212:1,306:1},yJ,wtn,_Y),MWn.Re=function(){return WH(this)},MWn.Se=function(){return VH(this)},MWn.a=0,MWn.c=!1;var irt,rrt,crt,art=vX(tJn,"LabelCell",306);wAn(244,326,{212:1,326:1,244:1},Cgn),MWn.Re=function(){return MCn(this)},MWn.Se=function(){return SCn(this)},MWn.Te=function(){KFn(this)},MWn.Ue=function(){GFn(this)},MWn.b=0,MWn.c=0,MWn.d=!1,vX(tJn,"StripContainerCell",244),wAn(1626,1,DVn,En),MWn.Mb=function(n){return Qy(BB(n,212))},vX(tJn,"StripContainerCell/lambda$0$Type",1626),wAn(1627,1,{},Tn),MWn.Fe=function(n){return BB(n,212).Se()},vX(tJn,"StripContainerCell/lambda$1$Type",1627),wAn(1628,1,DVn,Mn),MWn.Mb=function(n){return Yy(BB(n,212))},vX(tJn,"StripContainerCell/lambda$2$Type",1628),wAn(1629,1,{},Sn),MWn.Fe=function(n){return BB(n,212).Re()},vX(tJn,"StripContainerCell/lambda$3$Type",1629),wAn(462,22,{3:1,35:1,22:1,462:1},zS);var urt,ort,srt,hrt,frt,lrt,brt,wrt,drt,grt,prt,vrt,mrt,yrt,krt,jrt,Ert,Trt,Mrt,Srt,Prt,Irt,Crt,Ort=Ben(tJn,"VerticalLabelAlignment",462,Unt,y1,pK);wAn(789,1,{},eUn),MWn.c=0,MWn.d=0,MWn.k=0,MWn.s=0,MWn.t=0,MWn.v=!1,MWn.w=0,MWn.D=!1,vX(sJn,"NodeContext",789),wAn(1471,1,MYn,Pn),MWn.ue=function(n,t){return YO(BB(n,61),BB(t,61))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(sJn,"NodeContext/0methodref$comparePortSides$Type",1471),wAn(1472,1,MYn,In),MWn.ue=function(n,t){return UTn(BB(n,111),BB(t,111))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(sJn,"NodeContext/1methodref$comparePortContexts$Type",1472),wAn(159,22,{3:1,35:1,22:1,159:1},ocn);var Art,$rt,Lrt,Nrt,xrt,Drt,Rrt,_rt=Ben(sJn,"NodeLabelLocation",159,Unt,tpn,vK);wAn(111,1,{111:1},MOn),MWn.a=!1,vX(sJn,"PortContext",111),wAn(1476,1,lVn,Cn),MWn.td=function(n){IE(BB(n,306))},vX(lJn,bJn,1476),wAn(1477,1,DVn,On),MWn.Mb=function(n){return!!BB(n,111).c},vX(lJn,wJn,1477),wAn(1478,1,lVn,An),MWn.td=function(n){IE(BB(n,111).c)},vX(lJn,"LabelPlacer/lambda$2$Type",1478),wAn(1475,1,lVn,Ln),MWn.td=function(n){qD(),Yp(BB(n,111))},vX(lJn,"NodeLabelAndSizeUtilities/lambda$0$Type",1475),wAn(790,1,lVn,$K),MWn.td=function(n){RM(this.b,this.c,this.a,BB(n,181))},MWn.a=!1,MWn.c=!1,vX(lJn,"NodeLabelCellCreator/lambda$0$Type",790),wAn(1474,1,lVn,Iw),MWn.td=function(n){Cv(this.a,BB(n,181))},vX(lJn,"PortContextCreator/lambda$0$Type",1474),wAn(1829,1,{},Nn),vX(gJn,"GreedyRectangleStripOverlapRemover",1829),wAn(1830,1,MYn,$n),MWn.ue=function(n,t){return FN(BB(n,222),BB(t,222))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(gJn,"GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type",1830),wAn(1786,1,{},Zv),MWn.a=5,MWn.e=0,vX(gJn,"RectangleStripOverlapRemover",1786),wAn(1787,1,MYn,Dn),MWn.ue=function(n,t){return BN(BB(n,222),BB(t,222))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(gJn,"RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type",1787),wAn(1789,1,MYn,Rn),MWn.ue=function(n,t){return JU(BB(n,222),BB(t,222))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(gJn,"RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type",1789),wAn(406,22,{3:1,35:1,22:1,406:1},US);var Krt,Frt,Brt,Hrt,qrt,Grt=Ben(gJn,"RectangleStripOverlapRemover/OverlapRemovalDirection",406,Unt,Y2,mK);wAn(222,1,{222:1},xG),vX(gJn,"RectangleStripOverlapRemover/RectangleNode",222),wAn(1788,1,lVn,Cw),MWn.td=function(n){Imn(this.a,BB(n,222))},vX(gJn,"RectangleStripOverlapRemover/lambda$1$Type",1788),wAn(1304,1,MYn,_n),MWn.ue=function(n,t){return zHn(BB(n,167),BB(t,167))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(vJn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator",1304),wAn(1307,1,{},Kn),MWn.Kb=function(n){return BB(n,324).a},vX(vJn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$0$Type",1307),wAn(1308,1,DVn,Fn),MWn.Mb=function(n){return BB(n,323).a},vX(vJn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$1$Type",1308),wAn(1309,1,DVn,Bn),MWn.Mb=function(n){return BB(n,323).a},vX(vJn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$2$Type",1309),wAn(1302,1,MYn,Hn),MWn.ue=function(n,t){return WRn(BB(n,167),BB(t,167))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(vJn,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator",1302),wAn(1305,1,{},xn),MWn.Kb=function(n){return BB(n,324).a},vX(vJn,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator/lambda$0$Type",1305),wAn(767,1,MYn,qn),MWn.ue=function(n,t){return Uan(BB(n,167),BB(t,167))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(vJn,"PolyominoCompactor/MinNumOfExtensionsComparator",767),wAn(1300,1,MYn,Gn),MWn.ue=function(n,t){return Qin(BB(n,321),BB(t,321))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(vJn,"PolyominoCompactor/MinPerimeterComparator",1300),wAn(1301,1,MYn,zn),MWn.ue=function(n,t){return avn(BB(n,321),BB(t,321))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(vJn,"PolyominoCompactor/MinPerimeterComparatorWithShape",1301),wAn(1303,1,MYn,Un),MWn.ue=function(n,t){return B_n(BB(n,167),BB(t,167))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(vJn,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator",1303),wAn(1306,1,{},Xn),MWn.Kb=function(n){return BB(n,324).a},vX(vJn,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator/lambda$0$Type",1306),wAn(777,1,{},DS),MWn.Ce=function(n,t){return O2(this,BB(n,46),BB(t,167))},vX(vJn,"SuccessorCombination",777),wAn(644,1,{},Wn),MWn.Ce=function(n,t){var e;return XCn((e=BB(n,46),BB(t,167),e))},vX(vJn,"SuccessorJitter",644),wAn(643,1,{},Vn),MWn.Ce=function(n,t){var e;return bxn((e=BB(n,46),BB(t,167),e))},vX(vJn,"SuccessorLineByLine",643),wAn(568,1,{},Qn),MWn.Ce=function(n,t){var e;return f$n((e=BB(n,46),BB(t,167),e))},vX(vJn,"SuccessorManhattan",568),wAn(1356,1,{},Yn),MWn.Ce=function(n,t){var e;return jNn((e=BB(n,46),BB(t,167),e))},vX(vJn,"SuccessorMaxNormWindingInMathPosSense",1356),wAn(400,1,{},Ow),MWn.Ce=function(n,t){return BU(this,n,t)},MWn.c=!1,MWn.d=!1,MWn.e=!1,MWn.f=!1,vX(vJn,"SuccessorQuadrantsGeneric",400),wAn(1357,1,{},Jn),MWn.Kb=function(n){return BB(n,324).a},vX(vJn,"SuccessorQuadrantsGeneric/lambda$0$Type",1357),wAn(323,22,{3:1,35:1,22:1,323:1},KS),MWn.a=!1;var zrt,Urt=Ben(EJn,TJn,323,Unt,n3,yK);wAn(1298,1,{}),MWn.Ib=function(){var n,t,e,i,r,c;for(e=" ",n=iln(0),r=0;r<this.o;r++)e+=""+n.a,n=iln(lR(n.a));for(e+="\n",n=iln(0),c=0;c<this.p;c++){for(e+=""+n.a,n=iln(lR(n.a)),i=0;i<this.o;i++)0==Vhn(t=trn(this,i,c),0)?e+="_":0==Vhn(t,1)?e+="X":e+="0";e+="\n"}return fx(e,0,e.length-1)},MWn.o=0,MWn.p=0,vX(EJn,"TwoBitGrid",1298),wAn(321,1298,{321:1},qwn),MWn.j=0,MWn.k=0,vX(EJn,"PlanarGrid",321),wAn(167,321,{321:1,167:1}),MWn.g=0,MWn.i=0,vX(EJn,"Polyomino",167);var Xrt=bq(CJn,OJn);wAn(134,1,AJn,Zn),MWn.Ye=function(n,t){return son(this,n,t)},MWn.Ve=function(){return Gq(this)},MWn.We=function(n){return mMn(this,n)},MWn.Xe=function(n){return Lx(this,n)},vX(CJn,"MapPropertyHolder",134),wAn(1299,134,AJn,yxn),vX(EJn,"Polyominoes",1299);var Wrt,Vrt,Qrt,Yrt,Jrt,Zrt,nct,tct,ect=!1;wAn(1766,1,lVn,nt),MWn.td=function(n){uqn(BB(n,221))},vX($Jn,"DepthFirstCompaction/0methodref$compactTree$Type",1766),wAn(810,1,lVn,Aw),MWn.td=function(n){_W(this.a,BB(n,221))},vX($Jn,"DepthFirstCompaction/lambda$1$Type",810),wAn(1767,1,lVn,NK),MWn.td=function(n){dgn(this.a,this.b,this.c,BB(n,221))},vX($Jn,"DepthFirstCompaction/lambda$2$Type",1767),wAn(65,1,{65:1},AZ),vX($Jn,"Node",65),wAn(1250,1,{},C$),vX($Jn,"ScanlineOverlapCheck",1250),wAn(1251,1,{679:1},hY),MWn.Ke=function(n){GD(this,BB(n,440))},vX($Jn,"ScanlineOverlapCheck/OverlapsScanlineHandler",1251),wAn(1252,1,MYn,tt),MWn.ue=function(n,t){return xln(BB(n,65),BB(t,65))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX($Jn,"ScanlineOverlapCheck/OverlapsScanlineHandler/lambda$0$Type",1252),wAn(440,1,{440:1},RS),MWn.a=!1,vX($Jn,"ScanlineOverlapCheck/Timestamp",440),wAn(1253,1,MYn,et),MWn.ue=function(n,t){return Zkn(BB(n,440),BB(t,440))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX($Jn,"ScanlineOverlapCheck/lambda$0$Type",1253),wAn(550,1,{},it),vX(LJn,"SVGImage",550),wAn(324,1,{324:1},xK),MWn.Ib=function(){return"("+this.a+FWn+this.b+FWn+this.c+")"},vX(LJn,"UniqueTriple",324),wAn(209,1,NJn),vX(xJn,"AbstractLayoutProvider",209),wAn(1132,209,NJn,rt),MWn.Ze=function(n,t){var e,i,r;OTn(t,DJn,1),this.a=Gy(MD(ZAn(n,(Epn(),Ect)))),P8(n,bct)&&(i=SD(ZAn(n,bct)),(e=XRn(cin(),i))&&BB(sJ(e.f),209).Ze(n,mcn(t,1))),r=new s4(this.a),this.b=Rzn(r,n),0===BB(ZAn(n,(Gsn(),oct)),481).g?(BOn(new ct,this.b),Ypn(n,gct,mMn(this.b,gct))):$T(),Uzn(r),Ypn(n,dct,this.b),HSn(t)},MWn.a=0,vX(RJn,"DisCoLayoutProvider",1132),wAn(1244,1,{},ct),MWn.c=!1,MWn.e=0,MWn.f=0,vX(RJn,"DisCoPolyominoCompactor",1244),wAn(561,1,{561:1},hG),MWn.b=!0,vX(_Jn,"DCComponent",561),wAn(394,22,{3:1,35:1,22:1,394:1},_S),MWn.a=!1;var ict,rct,cct=Ben(_Jn,"DCDirection",394,Unt,Z2,kK);wAn(266,134,{3:1,266:1,94:1,134:1},EAn),vX(_Jn,"DCElement",266),wAn(395,1,{395:1},Cmn),MWn.c=0,vX(_Jn,"DCExtension",395),wAn(755,134,AJn,Kj),vX(_Jn,"DCGraph",755),wAn(481,22,{3:1,35:1,22:1,481:1},Cx);var act,uct,oct,sct,hct,fct,lct,bct,wct,dct,gct,pct,vct,mct,yct,kct,jct,Ect,Tct,Mct,Sct,Pct=Ben(KJn,FJn,481,Unt,RV,jK);wAn(854,1,QYn,Hh),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,BJn),zJn),"Connected Components Compaction Strategy"),"Strategy for packing different connected components in order to save space and enhance readability of a graph."),sct),(PPn(),gMt)),Pct),nbn((rpn(),hMt))))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,HJn),zJn),"Connected Components Layout Algorithm"),"A layout algorithm that is to be applied to each connected component before the components themselves are compacted. If unspecified, the positions of the components' nodes are not altered."),yMt),Qtt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,qJn),"debug"),"DCGraph"),"Access to the DCGraph is intended for the debug view,"),mMt),Ant),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,GJn),"debug"),"List of Polyominoes"),"Access to the polyominoes is intended for the debug view,"),mMt),Ant),nbn(hMt)))),BBn((new qh,n))},vX(KJn,"DisCoMetaDataProvider",854),wAn(998,1,QYn,qh),MWn.Qe=function(n){BBn(n)},vX(KJn,"DisCoOptions",998),wAn(999,1,{},at),MWn.$e=function(){return new rt},MWn._e=function(n){},vX(KJn,"DisCoOptions/DiscoFactory",999),wAn(562,167,{321:1,167:1,562:1},Q$n),MWn.a=0,MWn.b=0,MWn.c=0,MWn.d=0,vX("org.eclipse.elk.alg.disco.structures","DCPolyomino",562),wAn(1268,1,DVn,ut),MWn.Mb=function(n){return TO(n)},vX(YJn,"ElkGraphComponentsProcessor/lambda$0$Type",1268),wAn(1269,1,{},ot),MWn.Kb=function(n){return MQ(),PMn(BB(n,79))},vX(YJn,"ElkGraphComponentsProcessor/lambda$1$Type",1269),wAn(1270,1,DVn,st),MWn.Mb=function(n){return qH(BB(n,79))},vX(YJn,"ElkGraphComponentsProcessor/lambda$2$Type",1270),wAn(1271,1,{},ht),MWn.Kb=function(n){return MQ(),OMn(BB(n,79))},vX(YJn,"ElkGraphComponentsProcessor/lambda$3$Type",1271),wAn(1272,1,DVn,ft),MWn.Mb=function(n){return GH(BB(n,79))},vX(YJn,"ElkGraphComponentsProcessor/lambda$4$Type",1272),wAn(1273,1,DVn,$w),MWn.Mb=function(n){return MJ(this.a,BB(n,79))},vX(YJn,"ElkGraphComponentsProcessor/lambda$5$Type",1273),wAn(1274,1,{},Lw),MWn.Kb=function(n){return _X(this.a,BB(n,79))},vX(YJn,"ElkGraphComponentsProcessor/lambda$6$Type",1274),wAn(1241,1,{},s4),MWn.a=0,vX(YJn,"ElkGraphTransformer",1241),wAn(1242,1,{},lt),MWn.Od=function(n,t){tOn(this,BB(n,160),BB(t,266))},vX(YJn,"ElkGraphTransformer/OffsetApplier",1242),wAn(1243,1,lVn,Nw),MWn.td=function(n){TL(this,BB(n,8))},vX(YJn,"ElkGraphTransformer/OffsetApplier/OffSetToChainApplier",1243),wAn(753,1,{},bt),vX(eZn,iZn,753),wAn(1232,1,MYn,wt),MWn.ue=function(n,t){return ICn(BB(n,231),BB(t,231))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(eZn,rZn,1232),wAn(740,209,NJn,Gv),MWn.Ze=function(n,t){vLn(this,n,t)},vX(eZn,"ForceLayoutProvider",740),wAn(357,134,{3:1,357:1,94:1,134:1}),vX(cZn,"FParticle",357),wAn(559,357,{3:1,559:1,357:1,94:1,134:1},hX),MWn.Ib=function(){var n;return this.a?(n=E7(this.a.a,this,0))>=0?"b"+n+"["+u5(this.a)+"]":"b["+u5(this.a)+"]":"b_"+PN(this)},vX(cZn,"FBendpoint",559),wAn(282,134,{3:1,282:1,94:1,134:1},CR),MWn.Ib=function(){return u5(this)},vX(cZn,"FEdge",282),wAn(231,134,{3:1,231:1,94:1,134:1},y6);var Ict,Cct,Oct,Act,$ct,Lct,Nct,xct,Dct,Rct,_ct=vX(cZn,"FGraph",231);wAn(447,357,{3:1,447:1,357:1,94:1,134:1},m4),MWn.Ib=function(){return null==this.b||0==this.b.length?"l["+u5(this.a)+"]":"l_"+this.b},vX(cZn,"FLabel",447),wAn(144,357,{3:1,144:1,357:1,94:1,134:1},qX),MWn.Ib=function(){return p0(this)},MWn.b=0,vX(cZn,"FNode",144),wAn(2003,1,{}),MWn.bf=function(n){sFn(this,n)},MWn.cf=function(){qmn(this)},MWn.d=0,vX(uZn,"AbstractForceModel",2003),wAn(631,2003,{631:1},Lan),MWn.af=function(n,t){var i,r,c,a;return tCn(this.f,n,t),c=XR(B$(t.d),n.d),a=e.Math.sqrt(c.a*c.a+c.b*c.b),r=e.Math.max(0,a-lW(n.e)/2-lW(t.e)/2),kL(c,((i=qon(this.e,n,t))>0?-KU(r,this.c)*i:xx(r,this.b)*BB(mMn(n,(fRn(),Zct)),19).a)/a),c},MWn.bf=function(n){sFn(this,n),this.a=BB(mMn(n,(fRn(),qct)),19).a,this.c=Gy(MD(mMn(n,cat))),this.b=Gy(MD(mMn(n,tat)))},MWn.df=function(n){return n<this.a},MWn.a=0,MWn.b=0,MWn.c=0,vX(uZn,"EadesModel",631),wAn(632,2003,{632:1},fH),MWn.af=function(n,t){var i,r,c,a,u;return tCn(this.f,n,t),c=XR(B$(t.d),n.d),u=e.Math.sqrt(c.a*c.a+c.b*c.b),a=Nx(r=e.Math.max(0,u-lW(n.e)/2-lW(t.e)/2),this.a)*BB(mMn(n,(fRn(),Zct)),19).a,(i=qon(this.e,n,t))>0&&(a-=Sy(r,this.a)*i),kL(c,a*this.b/u),c},MWn.bf=function(n){var t,i,r,c,a,u,o;for(sFn(this,n),this.b=Gy(MD(mMn(n,(fRn(),aat)))),this.c=this.b/BB(mMn(n,qct),19).a,r=n.e.c.length,a=0,c=0,o=new Wb(n.e);o.a<o.c.c.length;)a+=(u=BB(n0(o),144)).e.a,c+=u.e.b;t=a*c,i=Gy(MD(mMn(n,cat)))*fJn,this.a=e.Math.sqrt(t/(2*r))*i},MWn.cf=function(){qmn(this),this.b-=this.c},MWn.df=function(n){return this.b>0},MWn.a=0,MWn.b=0,MWn.c=0,vX(uZn,"FruchtermanReingoldModel",632),wAn(849,1,QYn,zh),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,oZn),""),"Force Model"),"Determines the model for force calculation."),Oct),(PPn(),gMt)),$at),nbn((rpn(),hMt))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,sZn),""),"Iterations"),"The number of iterations on the force model."),iln(300)),vMt),Att),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,hZn),""),"Repulsive Power"),"Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model"),iln(0)),vMt),Att),nbn(uMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,fZn),""),"FR Temperature"),"The temperature is used as a scaling factor for particle displacements."),lZn),dMt),Ptt),nbn(hMt)))),a2(n,fZn,oZn,xct),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,bZn),""),"Eades Repulsion"),"Factor for repulsive forces in Eades' model."),5),dMt),Ptt),nbn(hMt)))),a2(n,bZn,oZn,$ct),pUn((new Uh,n))},vX(wZn,"ForceMetaDataProvider",849),wAn(424,22,{3:1,35:1,22:1,424:1},XS);var Kct,Fct,Bct,Hct,qct,Gct,zct,Uct,Xct,Wct,Vct,Qct,Yct,Jct,Zct,nat,tat,eat,iat,rat,cat,aat,uat,oat,sat,hat,fat,lat,bat,wat,dat,gat,pat,vat,mat,yat,kat,jat,Eat,Tat,Mat,Sat,Pat,Iat,Cat,Oat,Aat,$at=Ben(wZn,"ForceModelStrategy",424,Unt,aJ,EK);wAn(988,1,QYn,Uh),MWn.Qe=function(n){pUn(n)},vX(wZn,"ForceOptions",988),wAn(989,1,{},dt),MWn.$e=function(){return new Gv},MWn._e=function(n){},vX(wZn,"ForceOptions/ForceFactory",989),wAn(850,1,QYn,Xh),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,NZn),""),"Fixed Position"),"Prevent that the node is moved by the layout algorithm."),(hN(),!1)),(PPn(),wMt)),ktt),nbn((rpn(),sMt))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,xZn),""),"Desired Edge Length"),"Either specified for parent nodes or for individual edges, where the latter takes higher precedence."),100),dMt),Ptt),EG(hMt,Pun(Gk(jMt,1),$Vn,175,0,[uMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,DZn),""),"Layout Dimension"),"Dimensions that are permitted to be altered during layout."),bat),gMt),Hat),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,RZn),""),"Stress Epsilon"),"Termination criterion for the iterative process."),lZn),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,_Zn),""),"Iteration Limit"),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),iln(DWn)),vMt),Att),nbn(hMt)))),UGn((new Wh,n))},vX(wZn,"StressMetaDataProvider",850),wAn(992,1,QYn,Wh),MWn.Qe=function(n){UGn(n)},vX(wZn,"StressOptions",992),wAn(993,1,{},gt),MWn.$e=function(){return new OR},MWn._e=function(n){},vX(wZn,"StressOptions/StressFactory",993),wAn(1128,209,NJn,OR),MWn.Ze=function(n,t){var e,i,r,c;for(OTn(t,FZn,1),qy(TD(ZAn(n,(rkn(),kat))))?qy(TD(ZAn(n,Pat)))||jJ(new Tw((GM(),new Dy(n)))):vLn(new Gv,n,mcn(t,1)),i=fon(n),c=(e=HFn(this.a,i)).Kc();c.Ob();)(r=BB(c.Pb(),231)).e.c.length<=1||(HHn(this.b,r),i$n(this.b),Otn(r.d,new pt));SUn(i=GUn(e)),HSn(t)},vX(HZn,"StressLayoutProvider",1128),wAn(1129,1,lVn,pt),MWn.td=function(n){KBn(BB(n,447))},vX(HZn,"StressLayoutProvider/lambda$0$Type",1129),wAn(990,1,{},Tv),MWn.c=0,MWn.e=0,MWn.g=0,vX(HZn,"StressMajorization",990),wAn(379,22,{3:1,35:1,22:1,379:1},WS);var Lat,Nat,xat,Dat,Rat,_at,Kat,Fat,Bat,Hat=Ben(HZn,"StressMajorization/Dimension",379,Unt,j1,TK);wAn(991,1,MYn,xw),MWn.ue=function(n,t){return S_(this.a,BB(n,144),BB(t,144))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(HZn,"StressMajorization/lambda$0$Type",991),wAn(1229,1,{},D0),vX(GZn,"ElkLayered",1229),wAn(1230,1,lVn,vt),MWn.td=function(n){RCn(BB(n,37))},vX(GZn,"ElkLayered/lambda$0$Type",1230),wAn(1231,1,lVn,Dw),MWn.td=function(n){P_(this.a,BB(n,37))},vX(GZn,"ElkLayered/lambda$1$Type",1231),wAn(1263,1,{},$$),vX(GZn,"GraphConfigurator",1263),wAn(759,1,lVn,Rw),MWn.td=function(n){VMn(this.a,BB(n,10))},vX(GZn,"GraphConfigurator/lambda$0$Type",759),wAn(760,1,{},mt),MWn.Kb=function(n){return tjn(),new Rq(null,new w1(BB(n,29).a,16))},vX(GZn,"GraphConfigurator/lambda$1$Type",760),wAn(761,1,lVn,_w),MWn.td=function(n){VMn(this.a,BB(n,10))},vX(GZn,"GraphConfigurator/lambda$2$Type",761),wAn(1127,209,NJn,Uv),MWn.Ze=function(n,t){var e;e=SBn(new tm,n),GC(ZAn(n,(HXn(),sgt)))===GC((ufn(),pIt))?rwn(this.a,e,t):wOn(this.a,e,t),gUn(new Qh,e)},vX(GZn,"LayeredLayoutProvider",1127),wAn(356,22,{3:1,35:1,22:1,356:1},VS);var qat,Gat,zat,Uat=Ben(GZn,"LayeredPhases",356,Unt,s5,MK);wAn(1651,1,{},vin),MWn.i=0,vX(zZn,"ComponentsToCGraphTransformer",1651),wAn(1652,1,{},yt),MWn.ef=function(n,t){return e.Math.min(null!=n.a?Gy(n.a):n.c.i,null!=t.a?Gy(t.a):t.c.i)},MWn.ff=function(n,t){return e.Math.min(null!=n.a?Gy(n.a):n.c.i,null!=t.a?Gy(t.a):t.c.i)},vX(zZn,"ComponentsToCGraphTransformer/1",1652),wAn(81,1,{81:1}),MWn.i=0,MWn.k=!0,MWn.o=_Qn;var Xat,Wat,Vat,Qat=vX(UZn,"CNode",81);wAn(460,81,{460:1,81:1},NN,Sgn),MWn.Ib=function(){return""},vX(zZn,"ComponentsToCGraphTransformer/CRectNode",460),wAn(1623,1,{},kt),vX(zZn,"OneDimensionalComponentsCompaction",1623),wAn(1624,1,{},jt),MWn.Kb=function(n){return xZ(BB(n,46))},MWn.Fb=function(n){return this===n},vX(zZn,"OneDimensionalComponentsCompaction/lambda$0$Type",1624),wAn(1625,1,{},Et),MWn.Kb=function(n){return Ewn(BB(n,46))},MWn.Fb=function(n){return this===n},vX(zZn,"OneDimensionalComponentsCompaction/lambda$1$Type",1625),wAn(1654,1,{},BX),vX(UZn,"CGraph",1654),wAn(189,1,{189:1},Pgn),MWn.b=0,MWn.c=0,MWn.e=0,MWn.g=!0,MWn.i=_Qn,vX(UZn,"CGroup",189),wAn(1653,1,{},Pt),MWn.ef=function(n,t){return e.Math.max(null!=n.a?Gy(n.a):n.c.i,null!=t.a?Gy(t.a):t.c.i)},MWn.ff=function(n,t){return e.Math.max(null!=n.a?Gy(n.a):n.c.i,null!=t.a?Gy(t.a):t.c.i)},vX(UZn,OYn,1653),wAn(1655,1,{},sOn),MWn.d=!1;var Yat=vX(UZn,xYn,1655);wAn(1656,1,{},It),MWn.Kb=function(n){return kM(),hN(),0!=BB(BB(n,46).a,81).d.e},MWn.Fb=function(n){return this===n},vX(UZn,DYn,1656),wAn(823,1,{},Sq),MWn.a=!1,MWn.b=!1,MWn.c=!1,MWn.d=!1,vX(UZn,RYn,823),wAn(1825,1,{},DG),vX(XZn,_Yn,1825);var Jat=bq(WZn,PYn);wAn(1826,1,{369:1},lY),MWn.Ke=function(n){Gxn(this,BB(n,466))},vX(XZn,KYn,1826),wAn(1827,1,MYn,Ct),MWn.ue=function(n,t){return oQ(BB(n,81),BB(t,81))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(XZn,FYn,1827),wAn(466,1,{466:1},fP),MWn.a=!1,vX(XZn,BYn,466),wAn(1828,1,MYn,Ot),MWn.ue=function(n,t){return njn(BB(n,466),BB(t,466))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(XZn,HYn,1828),wAn(140,1,{140:1},dP,mH),MWn.Fb=function(n){var t;return null!=n&&iut==tsn(n)&&(t=BB(n,140),cV(this.c,t.c)&&cV(this.d,t.d))},MWn.Hb=function(){return fhn(Pun(Gk(Ant,1),HWn,1,5,[this.c,this.d]))},MWn.Ib=function(){return"("+this.c+FWn+this.d+(this.a?"cx":"")+this.b+")"},MWn.a=!0,MWn.c=0,MWn.d=0;var Zat,nut,tut,eut,iut=vX(WZn,"Point",140);wAn(405,22,{3:1,35:1,22:1,405:1},QS);var rut,cut,aut,uut,out,sut,hut,fut,lut,but,wut,dut=Ben(WZn,"Point/Quadrant",405,Unt,t3,SK);wAn(1642,1,{},Vv),MWn.b=null,MWn.c=null,MWn.d=null,MWn.e=null,MWn.f=null,vX(WZn,"RectilinearConvexHull",1642),wAn(574,1,{369:1},Tpn),MWn.Ke=function(n){K9(this,BB(n,140))},MWn.b=0,vX(WZn,"RectilinearConvexHull/MaximalElementsEventHandler",574),wAn(1644,1,MYn,Mt),MWn.ue=function(n,t){return DV(MD(n),MD(t))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(WZn,"RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type",1644),wAn(1643,1,{369:1},ftn),MWn.Ke=function(n){PNn(this,BB(n,140))},MWn.a=0,MWn.b=null,MWn.c=null,MWn.d=null,MWn.e=null,vX(WZn,"RectilinearConvexHull/RectangleEventHandler",1643),wAn(1645,1,MYn,St),MWn.ue=function(n,t){return u0(BB(n,140),BB(t,140))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(WZn,"RectilinearConvexHull/lambda$0$Type",1645),wAn(1646,1,MYn,Tt),MWn.ue=function(n,t){return o0(BB(n,140),BB(t,140))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(WZn,"RectilinearConvexHull/lambda$1$Type",1646),wAn(1647,1,MYn,At),MWn.ue=function(n,t){return h0(BB(n,140),BB(t,140))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(WZn,"RectilinearConvexHull/lambda$2$Type",1647),wAn(1648,1,MYn,$t),MWn.ue=function(n,t){return s0(BB(n,140),BB(t,140))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(WZn,"RectilinearConvexHull/lambda$3$Type",1648),wAn(1649,1,MYn,Lt),MWn.ue=function(n,t){return jMn(BB(n,140),BB(t,140))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(WZn,"RectilinearConvexHull/lambda$4$Type",1649),wAn(1650,1,{},OZ),vX(WZn,"Scanline",1650),wAn(2005,1,{}),vX(VZn,"AbstractGraphPlacer",2005),wAn(325,1,{325:1},Xx),MWn.mf=function(n){return!!this.nf(n)&&(JCn(this.b,BB(mMn(n,(hWn(),Xft)),21),n),!0)},MWn.nf=function(n){var t,e,i;for(t=BB(mMn(n,(hWn(),Xft)),21),i=BB(h6(fut,t),21).Kc();i.Ob();)if(e=BB(i.Pb(),21),!BB(h6(this.b,e),15).dc())return!1;return!0},vX(VZn,"ComponentGroup",325),wAn(765,2005,{},Qv),MWn.of=function(n){var t;for(t=new Wb(this.a);t.a<t.c.c.length;)if(BB(n0(t),325).mf(n))return;WB(this.a,new Xx(n))},MWn.lf=function(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(this.a.c=x8(Ant,HWn,1,0,5,1),t.a.c=x8(Ant,HWn,1,0,5,1),n.dc())return t.f.a=0,void(t.f.b=0);for(qan(t,a=BB(n.Xb(0),37)),r=n.Kc();r.Ob();)i=BB(r.Pb(),37),this.of(i);for(w=new Gj,c=Gy(MD(mMn(a,(HXn(),mpt)))),s=new Wb(this.a);s.a<s.c.c.length;)h=TXn(u=BB(n0(s),325),c),w9(TX(u.b),w.a,w.b),w.a+=h.a,w.b+=h.b;if(t.f.a=w.a-c,t.f.b=w.b-c,qy(TD(mMn(a,Mdt)))&&GC(mMn(a,Zdt))===GC((Mbn(),QPt))){for(b=n.Kc();b.Ob();)ZRn(f=BB(b.Pb(),37),f.c.a,f.c.b);for(_Xn(e=new Nt,n,c),l=n.Kc();l.Ob();)UR(kO((f=BB(l.Pb(),37)).c),e.e);UR(kO(t.f),e.a)}for(o=new Wb(this.a);o.a<o.c.c.length;)d9(t,TX((u=BB(n0(o),325)).b))},vX(VZn,"ComponentGroupGraphPlacer",765),wAn(1293,765,{},hm),MWn.of=function(n){pfn(this,n)},MWn.lf=function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if(this.a.c=x8(Ant,HWn,1,0,5,1),t.a.c=x8(Ant,HWn,1,0,5,1),n.dc())return t.f.a=0,void(t.f.b=0);for(qan(t,a=BB(n.Xb(0),37)),r=n.Kc();r.Ob();)pfn(this,BB(r.Pb(),37));for(v=new Gj,p=new Gj,d=new Gj,w=new Gj,c=Gy(MD(mMn(a,(HXn(),mpt)))),s=new Wb(this.a);s.a<s.c.c.length;){if(u=BB(n0(s),325),dA(BB(mMn(t,(sWn(),bSt)),103))){for(d.a=v.a,g=new ly(MX(kX(u.b).a).a.kc());g.b.Ob();)if(BB(cS(g.b.Pb()),21).Hc((kUn(),sCt))){d.a=p.a;break}}else if(gA(BB(mMn(t,bSt),103)))for(d.b=v.b,g=new ly(MX(kX(u.b).a).a.kc());g.b.Ob();)if(BB(cS(g.b.Pb()),21).Hc((kUn(),ICt))){d.b=p.b;break}if(h=TXn(BB(u,570),c),w9(TX(u.b),d.a,d.b),dA(BB(mMn(t,bSt),103))){for(p.a=d.a+h.a,w.a=e.Math.max(w.a,p.a),g=new ly(MX(kX(u.b).a).a.kc());g.b.Ob();)if(BB(cS(g.b.Pb()),21).Hc((kUn(),SCt))){v.a=d.a+h.a;break}p.b=d.b+h.b,d.b=p.b,w.b=e.Math.max(w.b,d.b)}else if(gA(BB(mMn(t,bSt),103))){for(p.b=d.b+h.b,w.b=e.Math.max(w.b,p.b),g=new ly(MX(kX(u.b).a).a.kc());g.b.Ob();)if(BB(cS(g.b.Pb()),21).Hc((kUn(),oCt))){v.b=d.b+h.b;break}p.a=d.a+h.a,d.a=p.a,w.a=e.Math.max(w.a,d.a)}}if(t.f.a=w.a-c,t.f.b=w.b-c,qy(TD(mMn(a,Mdt)))&&GC(mMn(a,Zdt))===GC((Mbn(),QPt))){for(b=n.Kc();b.Ob();)ZRn(f=BB(b.Pb(),37),f.c.a,f.c.b);for(_Xn(i=new Nt,n,c),l=n.Kc();l.Ob();)UR(kO((f=BB(l.Pb(),37)).c),i.e);UR(kO(t.f),i.a)}for(o=new Wb(this.a);o.a<o.c.c.length;)d9(t,TX((u=BB(n0(o),325)).b))},vX(VZn,"ComponentGroupModelOrderGraphPlacer",1293),wAn(423,22,{3:1,35:1,22:1,423:1},YS);var gut,put,vut,mut=Ben(VZn,"ComponentOrderingStrategy",423,Unt,k1,PK);wAn(650,1,{},Nt),vX(VZn,"ComponentsCompactor",650),wAn(1468,12,QQn,v5),MWn.Fc=function(n){return Yjn(this,BB(n,140))},vX(VZn,"ComponentsCompactor/Hullpoints",1468),wAn(1465,1,{841:1},hvn),MWn.a=!1,vX(VZn,"ComponentsCompactor/InternalComponent",1465),wAn(1464,1,pVn,Yv),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new Wb(this.a)},vX(VZn,"ComponentsCompactor/InternalConnectedComponents",1464),wAn(1467,1,{594:1},dOn),MWn.hf=function(){return null},MWn.jf=function(){return this.a},MWn.gf=function(){return upn(this.d)},MWn.kf=function(){return this.b},vX(VZn,"ComponentsCompactor/InternalExternalExtension",1467),wAn(1466,1,{594:1},nm),MWn.jf=function(){return this.a},MWn.gf=function(){return upn(this.d)},MWn.hf=function(){return this.c},MWn.kf=function(){return this.b},vX(VZn,"ComponentsCompactor/InternalUnionExternalExtension",1466),wAn(1470,1,{},Qxn),vX(VZn,"ComponentsCompactor/OuterSegments",1470),wAn(1469,1,{},Jv),vX(VZn,"ComponentsCompactor/Segments",1469),wAn(1264,1,{},bY),vX(VZn,iZn,1264),wAn(1265,1,MYn,xt),MWn.ue=function(n,t){return b0(BB(n,37),BB(t,37))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(VZn,"ComponentsProcessor/lambda$0$Type",1265),wAn(570,325,{325:1,570:1},p5),MWn.mf=function(n){return dsn(this,n)},MWn.nf=function(n){return bNn(this,n)},vX(VZn,"ModelOrderComponentGroup",570),wAn(1291,2005,{},Dt),MWn.lf=function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j;if(1!=n.gc()){if(n.dc())return t.a.c=x8(Ant,HWn,1,0,5,1),t.f.a=0,void(t.f.b=0);if(GC(mMn(t,(HXn(),Idt)))===GC((Bfn(),wut))){for(s=n.Kc();s.Ob();){for(p=0,d=new Wb((u=BB(s.Pb(),37)).a);d.a<d.c.c.length;)w=BB(n0(d),10),p+=BB(mMn(w,hpt),19).a;u.p=p}SQ(),n.ad(new Rt)}for(a=BB(n.Xb(0),37),t.a.c=x8(Ant,HWn,1,0,5,1),qan(t,a),b=0,y=0,h=n.Kc();h.Ob();)v=(u=BB(h.Pb(),37)).f,b=e.Math.max(b,v.a),y+=v.a*v.b;for(b=e.Math.max(b,e.Math.sqrt(y)*Gy(MD(mMn(t,Edt)))),k=0,j=0,l=0,i=c=Gy(MD(mMn(t,mpt))),o=n.Kc();o.Ob();)k+(v=(u=BB(o.Pb(),37)).f).a>b&&(k=0,j+=l+c,l=0),ZRn(u,k+(g=u.c).a,j+g.b),kO(g),i=e.Math.max(i,k+v.a),l=e.Math.max(l,v.b),k+=v.a+c;if(t.f.a=i,t.f.b=j+l,qy(TD(mMn(a,Mdt)))){for(_Xn(r=new Nt,n,c),f=n.Kc();f.Ob();)UR(kO(BB(f.Pb(),37).c),r.e);UR(kO(t.f),r.a)}d9(t,n)}else(m=BB(n.Xb(0),37))!=t&&(t.a.c=x8(Ant,HWn,1,0,5,1),$_n(t,m,0,0),qan(t,m),kQ(t.d,m.d),t.f.a=m.f.a,t.f.b=m.f.b)},vX(VZn,"SimpleRowGraphPlacer",1291),wAn(1292,1,MYn,Rt),MWn.ue=function(n,t){return zan(BB(n,37),BB(t,37))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(VZn,"SimpleRowGraphPlacer/1",1292),wAn(1262,1,qYn,_t),MWn.Lb=function(n){var t;return!!(t=BB(mMn(BB(n,243).b,(HXn(),vgt)),74))&&0!=t.b},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){var t;return!!(t=BB(mMn(BB(n,243).b,(HXn(),vgt)),74))&&0!=t.b},vX(ZZn,"CompoundGraphPostprocessor/1",1262),wAn(1261,1,n1n,em),MWn.pf=function(n,t){mvn(this,BB(n,37),t)},vX(ZZn,"CompoundGraphPreprocessor",1261),wAn(441,1,{441:1},zfn),MWn.c=!1,vX(ZZn,"CompoundGraphPreprocessor/ExternalPort",441),wAn(243,1,{243:1},LK),MWn.Ib=function(){return dx(this.c)+":"+OCn(this.b)},vX(ZZn,"CrossHierarchyEdge",243),wAn(763,1,MYn,Kw),MWn.ue=function(n,t){return Vyn(this,BB(n,243),BB(t,243))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(ZZn,"CrossHierarchyEdgeComparator",763),wAn(299,134,{3:1,299:1,94:1,134:1}),MWn.p=0,vX(t1n,"LGraphElement",299),wAn(17,299,{3:1,17:1,299:1,94:1,134:1},wY),MWn.Ib=function(){return OCn(this)};var yut=vX(t1n,"LEdge",17);wAn(37,299,{3:1,20:1,37:1,299:1,94:1,134:1},min),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new Wb(this.b)},MWn.Ib=function(){return 0==this.b.c.length?"G-unlayered"+LMn(this.a):0==this.a.c.length?"G-layered"+LMn(this.b):"G[layerless"+LMn(this.a)+", layers"+LMn(this.b)+"]"};var kut,jut=vX(t1n,"LGraph",37);wAn(657,1,{}),MWn.qf=function(){return this.e.n},MWn.We=function(n){return mMn(this.e,n)},MWn.rf=function(){return this.e.o},MWn.sf=function(){return this.e.p},MWn.Xe=function(n){return Lx(this.e,n)},MWn.tf=function(n){this.e.n.a=n.a,this.e.n.b=n.b},MWn.uf=function(n){this.e.o.a=n.a,this.e.o.b=n.b},MWn.vf=function(n){this.e.p=n},vX(t1n,"LGraphAdapters/AbstractLShapeAdapter",657),wAn(577,1,{839:1},Fw),MWn.wf=function(){var n,t;if(!this.b)for(this.b=sx(this.a.b.c.length),t=new Wb(this.a.b);t.a<t.c.c.length;)n=BB(n0(t),70),WB(this.b,new Bw(n));return this.b},MWn.b=null,vX(t1n,"LGraphAdapters/LEdgeAdapter",577),wAn(656,1,{},HV),MWn.xf=function(){var n,t,e,i,r;if(!this.b)for(this.b=new Np,e=new Wb(this.a.b);e.a<e.c.c.length;)for(r=new Wb(BB(n0(e),29).a);r.a<r.c.c.length;)if(i=BB(n0(r),10),this.c.Mb(i)&&(WB(this.b,new KK(this,i,this.e)),this.d)){if(Lx(i,(hWn(),_lt)))for(t=BB(mMn(i,_lt),15).Kc();t.Ob();)n=BB(t.Pb(),10),WB(this.b,new KK(this,n,!1));if(Lx(i,Dft))for(t=BB(mMn(i,Dft),15).Kc();t.Ob();)n=BB(t.Pb(),10),WB(this.b,new KK(this,n,!1))}return this.b},MWn.qf=function(){throw Hp(new tk(i1n))},MWn.We=function(n){return mMn(this.a,n)},MWn.rf=function(){return this.a.f},MWn.sf=function(){return this.a.p},MWn.Xe=function(n){return Lx(this.a,n)},MWn.tf=function(n){throw Hp(new tk(i1n))},MWn.uf=function(n){this.a.f.a=n.a,this.a.f.b=n.b},MWn.vf=function(n){this.a.p=n},MWn.b=null,MWn.d=!1,MWn.e=!1,vX(t1n,"LGraphAdapters/LGraphAdapter",656),wAn(576,657,{181:1},Bw),vX(t1n,"LGraphAdapters/LLabelAdapter",576),wAn(575,657,{680:1},KK),MWn.yf=function(){return this.b},MWn.zf=function(){return SQ(),SQ(),set},MWn.wf=function(){var n,t;if(!this.a)for(this.a=sx(BB(this.e,10).b.c.length),t=new Wb(BB(this.e,10).b);t.a<t.c.c.length;)n=BB(n0(t),70),WB(this.a,new Bw(n));return this.a},MWn.Af=function(){var n;return new HR((n=BB(this.e,10).d).d,n.c,n.a,n.b)},MWn.Bf=function(){return SQ(),SQ(),set},MWn.Cf=function(){var n,t;if(!this.c)for(this.c=sx(BB(this.e,10).j.c.length),t=new Wb(BB(this.e,10).j);t.a<t.c.c.length;)n=BB(n0(t),11),WB(this.c,new gP(n,this.d));return this.c},MWn.Df=function(){return qy(TD(mMn(BB(this.e,10),(hWn(),Kft))))},MWn.Ef=function(n){BB(this.e,10).d.b=n.b,BB(this.e,10).d.d=n.d,BB(this.e,10).d.c=n.c,BB(this.e,10).d.a=n.a},MWn.Ff=function(n){BB(this.e,10).f.b=n.b,BB(this.e,10).f.d=n.d,BB(this.e,10).f.c=n.c,BB(this.e,10).f.a=n.a},MWn.Gf=function(){Ntn(this,(gM(),kut))},MWn.a=null,MWn.b=null,MWn.c=null,MWn.d=!1,vX(t1n,"LGraphAdapters/LNodeAdapter",575),wAn(1722,657,{838:1},gP),MWn.zf=function(){var n,t,e,i;if(this.d&&BB(this.e,11).i.k==(uSn(),Cut))return SQ(),SQ(),set;if(!this.a){for(this.a=new Np,e=new Wb(BB(this.e,11).e);e.a<e.c.c.length;)n=BB(n0(e),17),WB(this.a,new Fw(n));if(this.d&&(i=BB(mMn(BB(this.e,11),(hWn(),Elt)),10)))for(t=new oz(ZL(fbn(i).a.Kc(),new h));dAn(t);)n=BB(U5(t),17),WB(this.a,new Fw(n))}return this.a},MWn.wf=function(){var n,t;if(!this.b)for(this.b=sx(BB(this.e,11).f.c.length),t=new Wb(BB(this.e,11).f);t.a<t.c.c.length;)n=BB(n0(t),70),WB(this.b,new Bw(n));return this.b},MWn.Bf=function(){var n,t,e,i;if(this.d&&BB(this.e,11).i.k==(uSn(),Cut))return SQ(),SQ(),set;if(!this.c){for(this.c=new Np,e=new Wb(BB(this.e,11).g);e.a<e.c.c.length;)n=BB(n0(e),17),WB(this.c,new Fw(n));if(this.d&&(i=BB(mMn(BB(this.e,11),(hWn(),Elt)),10)))for(t=new oz(ZL(lbn(i).a.Kc(),new h));dAn(t);)n=BB(U5(t),17),WB(this.c,new Fw(n))}return this.c},MWn.Hf=function(){return BB(this.e,11).j},MWn.If=function(){return qy(TD(mMn(BB(this.e,11),(hWn(),elt))))},MWn.a=null,MWn.b=null,MWn.c=null,MWn.d=!1,vX(t1n,"LGraphAdapters/LPortAdapter",1722),wAn(1723,1,MYn,Kt),MWn.ue=function(n,t){return WDn(BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(t1n,"LGraphAdapters/PortComparator",1723),wAn(804,1,DVn,Ft),MWn.Mb=function(n){return BB(n,10),gM(),!0},vX(t1n,"LGraphAdapters/lambda$0$Type",804),wAn(392,299,{3:1,299:1,392:1,94:1,134:1}),vX(t1n,"LShape",392),wAn(70,392,{3:1,299:1,70:1,392:1,94:1,134:1},qj,O$),MWn.Ib=function(){var n;return null==(n=YH(this))?"label":"l_"+n},vX(t1n,"LLabel",70),wAn(207,1,{3:1,4:1,207:1,414:1}),MWn.Fb=function(n){var t;return!!cL(n,207)&&(t=BB(n,207),this.d==t.d&&this.a==t.a&&this.b==t.b&&this.c==t.c)},MWn.Hb=function(){var n,t;return n=VO(this.b)<<16,n|=VO(this.a)&QVn,t=VO(this.c)<<16,n^(t|=VO(this.d)&QVn)},MWn.Jf=function(n){var t,e,i,r,c,a,u,o,s;for(r=0;r<n.length&&Dhn((b1(r,n.length),n.charCodeAt(r)),o1n);)++r;for(t=n.length;t>0&&Dhn((b1(t-1,n.length),n.charCodeAt(t-1)),s1n);)--t;if(r<t){o=k_n(n.substr(r,t-r),",|;");try{for(a=0,u=(c=o).length;a<u;++a){if(2!=(i=k_n(c[a],"=")).length)throw Hp(new Ky("Expecting a list of key-value pairs."));e=RMn(i[0]),s=bSn(RMn(i[1])),m_(e,"top")?this.d=s:m_(e,"left")?this.b=s:m_(e,"bottom")?this.a=s:m_(e,"right")&&(this.c=s)}}catch(h){throw cL(h=lun(h),127)?Hp(new Ky(h1n+h)):Hp(h)}}},MWn.Ib=function(){return"[top="+this.d+",left="+this.b+",bottom="+this.a+",right="+this.c+"]"},MWn.a=0,MWn.b=0,MWn.c=0,MWn.d=0,vX(f1n,"Spacing",207),wAn(142,207,l1n,lm,lA,HR,AK);var Eut=vX(f1n,"ElkMargin",142);wAn(651,142,l1n,fm),vX(t1n,"LMargin",651),wAn(10,392,{3:1,299:1,10:1,392:1,94:1,134:1},$vn),MWn.Ib=function(){return $pn(this)},MWn.i=!1;var Tut,Mut,Sut,Put,Iut,Cut,Out=vX(t1n,"LNode",10);wAn(267,22,{3:1,35:1,22:1,267:1},JS);var Aut,$ut=Ben(t1n,"LNode/NodeType",267,Unt,u9,CK);wAn(116,207,b1n,bm,WA,OK);var Lut,Nut,xut,Dut,Rut,_ut,Kut=vX(f1n,"ElkPadding",116);wAn(764,116,b1n,wm),vX(t1n,"LPadding",764),wAn(11,392,{3:1,299:1,11:1,392:1,94:1,134:1},ISn),MWn.Ib=function(){var n,t,e;return oO(((n=new Ik).a+="p_",n),pyn(this)),this.i&&oO(uO((n.a+="[",n),this.i),"]"),1==this.e.c.length&&0==this.g.c.length&&BB(xq(this.e,0),17).c!=this&&(t=BB(xq(this.e,0),17).c,oO((n.a+=" << ",n),pyn(t)),oO(uO((n.a+="[",n),t.i),"]")),0==this.e.c.length&&1==this.g.c.length&&BB(xq(this.g,0),17).d!=this&&(e=BB(xq(this.g,0),17).d,oO((n.a+=" >> ",n),pyn(e)),oO(uO((n.a+="[",n),e.i),"]")),n.a},MWn.c=!0,MWn.d=!1;var Fut,But,Hut,qut,Gut=vX(t1n,"LPort",11);wAn(397,1,pVn,Hw),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new qw(new Wb(this.a.e))},vX(t1n,"LPort/1",397),wAn(1290,1,QWn,qw),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return BB(n0(this.a),17).c},MWn.Ob=function(){return y$(this.a)},MWn.Qb=function(){AU(this.a)},vX(t1n,"LPort/1/1",1290),wAn(359,1,pVn,Gw),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new zw(new Wb(this.a.g))},vX(t1n,"LPort/2",359),wAn(762,1,QWn,zw),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return BB(n0(this.a),17).d},MWn.Ob=function(){return y$(this.a)},MWn.Qb=function(){AU(this.a)},vX(t1n,"LPort/2/1",762),wAn(1283,1,pVn,hP),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new m6(this)},vX(t1n,"LPort/CombineIter",1283),wAn(201,1,QWn,m6),MWn.Nb=function(n){fU(this,n)},MWn.Qb=function(){uE()},MWn.Ob=function(){return zN(this)},MWn.Pb=function(){return y$(this.a)?n0(this.a):n0(this.b)},vX(t1n,"LPort/CombineIter/1",201),wAn(1285,1,qYn,Bt),MWn.Lb=function(n){return Az(n)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return gcn(),0!=BB(n,11).e.c.length},vX(t1n,"LPort/lambda$0$Type",1285),wAn(1284,1,qYn,Ht),MWn.Lb=function(n){return $z(n)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return gcn(),0!=BB(n,11).g.c.length},vX(t1n,"LPort/lambda$1$Type",1284),wAn(1286,1,qYn,qt),MWn.Lb=function(n){return gcn(),BB(n,11).j==(kUn(),sCt)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return gcn(),BB(n,11).j==(kUn(),sCt)},vX(t1n,"LPort/lambda$2$Type",1286),wAn(1287,1,qYn,Gt),MWn.Lb=function(n){return gcn(),BB(n,11).j==(kUn(),oCt)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return gcn(),BB(n,11).j==(kUn(),oCt)},vX(t1n,"LPort/lambda$3$Type",1287),wAn(1288,1,qYn,zt),MWn.Lb=function(n){return gcn(),BB(n,11).j==(kUn(),SCt)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return gcn(),BB(n,11).j==(kUn(),SCt)},vX(t1n,"LPort/lambda$4$Type",1288),wAn(1289,1,qYn,Ut),MWn.Lb=function(n){return gcn(),BB(n,11).j==(kUn(),ICt)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return gcn(),BB(n,11).j==(kUn(),ICt)},vX(t1n,"LPort/lambda$5$Type",1289),wAn(29,299,{3:1,20:1,299:1,29:1,94:1,134:1},HX),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new Wb(this.a)},MWn.Ib=function(){return"L_"+E7(this.b.b,this,0)+LMn(this.a)},vX(t1n,"Layer",29),wAn(1342,1,{},tm),vX(d1n,g1n,1342),wAn(1346,1,{},Xt),MWn.Kb=function(n){return PTn(BB(n,82))},vX(d1n,"ElkGraphImporter/0methodref$connectableShapeToNode$Type",1346),wAn(1349,1,{},Wt),MWn.Kb=function(n){return PTn(BB(n,82))},vX(d1n,"ElkGraphImporter/1methodref$connectableShapeToNode$Type",1349),wAn(1343,1,lVn,Uw),MWn.td=function(n){POn(this.a,BB(n,118))},vX(d1n,p1n,1343),wAn(1344,1,lVn,Xw),MWn.td=function(n){POn(this.a,BB(n,118))},vX(d1n,v1n,1344),wAn(1345,1,{},Vt),MWn.Kb=function(n){return new Rq(null,new w1(pV(BB(n,79)),16))},vX(d1n,m1n,1345),wAn(1347,1,DVn,Ww),MWn.Mb=function(n){return KA(this.a,BB(n,33))},vX(d1n,y1n,1347),wAn(1348,1,{},Qt),MWn.Kb=function(n){return new Rq(null,new w1(vV(BB(n,79)),16))},vX(d1n,"ElkGraphImporter/lambda$5$Type",1348),wAn(1350,1,DVn,Vw),MWn.Mb=function(n){return FA(this.a,BB(n,33))},vX(d1n,"ElkGraphImporter/lambda$7$Type",1350),wAn(1351,1,DVn,Yt),MWn.Mb=function(n){return AQ(BB(n,79))},vX(d1n,"ElkGraphImporter/lambda$8$Type",1351),wAn(1278,1,{},Qh),vX(d1n,"ElkGraphLayoutTransferrer",1278),wAn(1279,1,DVn,Qw),MWn.Mb=function(n){return JR(this.a,BB(n,17))},vX(d1n,"ElkGraphLayoutTransferrer/lambda$0$Type",1279),wAn(1280,1,lVn,Yw),MWn.td=function(n){mM(),WB(this.a,BB(n,17))},vX(d1n,"ElkGraphLayoutTransferrer/lambda$1$Type",1280),wAn(1281,1,DVn,Jw),MWn.Mb=function(n){return UD(this.a,BB(n,17))},vX(d1n,"ElkGraphLayoutTransferrer/lambda$2$Type",1281),wAn(1282,1,lVn,Zw),MWn.td=function(n){mM(),WB(this.a,BB(n,17))},vX(d1n,"ElkGraphLayoutTransferrer/lambda$3$Type",1282),wAn(1485,1,n1n,Jt),MWn.pf=function(n,t){Vrn(BB(n,37),t)},vX(j1n,"CommentNodeMarginCalculator",1485),wAn(1486,1,{},Zt),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"CommentNodeMarginCalculator/lambda$0$Type",1486),wAn(1487,1,lVn,ne),MWn.td=function(n){tHn(BB(n,10))},vX(j1n,"CommentNodeMarginCalculator/lambda$1$Type",1487),wAn(1488,1,n1n,te),MWn.pf=function(n,t){aDn(BB(n,37),t)},vX(j1n,"CommentPostprocessor",1488),wAn(1489,1,n1n,ee),MWn.pf=function(n,t){uUn(BB(n,37),t)},vX(j1n,"CommentPreprocessor",1489),wAn(1490,1,n1n,ie),MWn.pf=function(n,t){jLn(BB(n,37),t)},vX(j1n,"ConstraintsPostprocessor",1490),wAn(1491,1,n1n,re),MWn.pf=function(n,t){can(BB(n,37),t)},vX(j1n,"EdgeAndLayerConstraintEdgeReverser",1491),wAn(1492,1,n1n,ce),MWn.pf=function(n,t){Gwn(BB(n,37),t)},vX(j1n,"EndLabelPostprocessor",1492),wAn(1493,1,{},ae),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"EndLabelPostprocessor/lambda$0$Type",1493),wAn(1494,1,DVn,ue),MWn.Mb=function(n){return MY(BB(n,10))},vX(j1n,"EndLabelPostprocessor/lambda$1$Type",1494),wAn(1495,1,lVn,oe),MWn.td=function(n){ejn(BB(n,10))},vX(j1n,"EndLabelPostprocessor/lambda$2$Type",1495),wAn(1496,1,n1n,se),MWn.pf=function(n,t){ZPn(BB(n,37),t)},vX(j1n,"EndLabelPreprocessor",1496),wAn(1497,1,{},he),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"EndLabelPreprocessor/lambda$0$Type",1497),wAn(1498,1,lVn,DK),MWn.td=function(n){_M(this.a,this.b,this.c,BB(n,10))},MWn.a=0,MWn.b=0,MWn.c=!1,vX(j1n,"EndLabelPreprocessor/lambda$1$Type",1498),wAn(1499,1,DVn,fe),MWn.Mb=function(n){return GC(mMn(BB(n,70),(HXn(),Ydt)))===GC((Rtn(),XPt))},vX(j1n,"EndLabelPreprocessor/lambda$2$Type",1499),wAn(1500,1,lVn,nd),MWn.td=function(n){DH(this.a,BB(n,70))},vX(j1n,"EndLabelPreprocessor/lambda$3$Type",1500),wAn(1501,1,DVn,le),MWn.Mb=function(n){return GC(mMn(BB(n,70),(HXn(),Ydt)))===GC((Rtn(),UPt))},vX(j1n,"EndLabelPreprocessor/lambda$4$Type",1501),wAn(1502,1,lVn,td),MWn.td=function(n){DH(this.a,BB(n,70))},vX(j1n,"EndLabelPreprocessor/lambda$5$Type",1502),wAn(1551,1,n1n,Vh),MWn.pf=function(n,t){Iln(BB(n,37),t)},vX(j1n,"EndLabelSorter",1551),wAn(1552,1,MYn,be),MWn.ue=function(n,t){return Hgn(BB(n,456),BB(t,456))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"EndLabelSorter/1",1552),wAn(456,1,{456:1},TQ),vX(j1n,"EndLabelSorter/LabelGroup",456),wAn(1553,1,{},we),MWn.Kb=function(n){return EM(),new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"EndLabelSorter/lambda$0$Type",1553),wAn(1554,1,DVn,de),MWn.Mb=function(n){return EM(),BB(n,10).k==(uSn(),Iut)},vX(j1n,"EndLabelSorter/lambda$1$Type",1554),wAn(1555,1,lVn,ge),MWn.td=function(n){oSn(BB(n,10))},vX(j1n,"EndLabelSorter/lambda$2$Type",1555),wAn(1556,1,DVn,pe),MWn.Mb=function(n){return EM(),GC(mMn(BB(n,70),(HXn(),Ydt)))===GC((Rtn(),UPt))},vX(j1n,"EndLabelSorter/lambda$3$Type",1556),wAn(1557,1,DVn,ve),MWn.Mb=function(n){return EM(),GC(mMn(BB(n,70),(HXn(),Ydt)))===GC((Rtn(),XPt))},vX(j1n,"EndLabelSorter/lambda$4$Type",1557),wAn(1503,1,n1n,me),MWn.pf=function(n,t){CHn(this,BB(n,37))},MWn.b=0,MWn.c=0,vX(j1n,"FinalSplineBendpointsCalculator",1503),wAn(1504,1,{},ye),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"FinalSplineBendpointsCalculator/lambda$0$Type",1504),wAn(1505,1,{},ke),MWn.Kb=function(n){return new Rq(null,new zU(new oz(ZL(lbn(BB(n,10)).a.Kc(),new h))))},vX(j1n,"FinalSplineBendpointsCalculator/lambda$1$Type",1505),wAn(1506,1,DVn,je),MWn.Mb=function(n){return!b5(BB(n,17))},vX(j1n,"FinalSplineBendpointsCalculator/lambda$2$Type",1506),wAn(1507,1,DVn,Ee),MWn.Mb=function(n){return Lx(BB(n,17),(hWn(),Nlt))},vX(j1n,"FinalSplineBendpointsCalculator/lambda$3$Type",1507),wAn(1508,1,lVn,ed),MWn.td=function(n){z_n(this.a,BB(n,128))},vX(j1n,"FinalSplineBendpointsCalculator/lambda$4$Type",1508),wAn(1509,1,lVn,Te),MWn.td=function(n){JPn(BB(n,17).a)},vX(j1n,"FinalSplineBendpointsCalculator/lambda$5$Type",1509),wAn(792,1,n1n,id),MWn.pf=function(n,t){Vqn(this,BB(n,37),t)},vX(j1n,"GraphTransformer",792),wAn(511,22,{3:1,35:1,22:1,511:1},ZS);var zut,Uut,Xut,Wut=Ben(j1n,"GraphTransformer/Mode",511,Unt,uJ,tB);wAn(1510,1,n1n,Me),MWn.pf=function(n,t){exn(BB(n,37),t)},vX(j1n,"HierarchicalNodeResizingProcessor",1510),wAn(1511,1,n1n,Se),MWn.pf=function(n,t){lrn(BB(n,37),t)},vX(j1n,"HierarchicalPortConstraintProcessor",1511),wAn(1512,1,MYn,Pe),MWn.ue=function(n,t){return Cpn(BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"HierarchicalPortConstraintProcessor/NodeComparator",1512),wAn(1513,1,n1n,Ie),MWn.pf=function(n,t){jBn(BB(n,37),t)},vX(j1n,"HierarchicalPortDummySizeProcessor",1513),wAn(1514,1,n1n,Ce),MWn.pf=function(n,t){JDn(this,BB(n,37),t)},MWn.a=0,vX(j1n,"HierarchicalPortOrthogonalEdgeRouter",1514),wAn(1515,1,MYn,Oe),MWn.ue=function(n,t){return KN(BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"HierarchicalPortOrthogonalEdgeRouter/1",1515),wAn(1516,1,MYn,Ae),MWn.ue=function(n,t){return P9(BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"HierarchicalPortOrthogonalEdgeRouter/2",1516),wAn(1517,1,n1n,$e),MWn.pf=function(n,t){EMn(BB(n,37),t)},vX(j1n,"HierarchicalPortPositionProcessor",1517),wAn(1518,1,n1n,Yh),MWn.pf=function(n,t){rXn(this,BB(n,37))},MWn.a=0,MWn.c=0,vX(j1n,"HighDegreeNodeLayeringProcessor",1518),wAn(571,1,{571:1},Le),MWn.b=-1,MWn.d=-1,vX(j1n,"HighDegreeNodeLayeringProcessor/HighDegreeNodeInformation",571),wAn(1519,1,{},Ne),MWn.Kb=function(n){return qK(),fbn(BB(n,10))},MWn.Fb=function(n){return this===n},vX(j1n,"HighDegreeNodeLayeringProcessor/lambda$0$Type",1519),wAn(1520,1,{},xe),MWn.Kb=function(n){return qK(),lbn(BB(n,10))},MWn.Fb=function(n){return this===n},vX(j1n,"HighDegreeNodeLayeringProcessor/lambda$1$Type",1520),wAn(1526,1,n1n,De),MWn.pf=function(n,t){dFn(this,BB(n,37),t)},vX(j1n,"HyperedgeDummyMerger",1526),wAn(793,1,{},RK),MWn.a=!1,MWn.b=!1,MWn.c=!1,vX(j1n,"HyperedgeDummyMerger/MergeState",793),wAn(1527,1,{},Re),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"HyperedgeDummyMerger/lambda$0$Type",1527),wAn(1528,1,{},_e),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,10).j,16))},vX(j1n,"HyperedgeDummyMerger/lambda$1$Type",1528),wAn(1529,1,lVn,Ke),MWn.td=function(n){BB(n,11).p=-1},vX(j1n,"HyperedgeDummyMerger/lambda$2$Type",1529),wAn(1530,1,n1n,Fe),MWn.pf=function(n,t){bFn(BB(n,37),t)},vX(j1n,"HypernodesProcessor",1530),wAn(1531,1,n1n,Be),MWn.pf=function(n,t){wFn(BB(n,37),t)},vX(j1n,"InLayerConstraintProcessor",1531),wAn(1532,1,n1n,He),MWn.pf=function(n,t){Lcn(BB(n,37),t)},vX(j1n,"InnermostNodeMarginCalculator",1532),wAn(1533,1,n1n,qe),MWn.pf=function(n,t){Vzn(this,BB(n,37))},MWn.a=_Qn,MWn.b=_Qn,MWn.c=RQn,MWn.d=RQn;var Vut,Qut,Yut,Jut,Zut,not,tot,eot,iot,rot,cot,aot,uot,oot,sot,hot,fot,lot,bot,wot,dot,got,pot,vot,mot,yot,kot,jot,Eot,Tot,Mot,Sot,Pot,Iot,Cot,Oot,Aot,$ot,Lot,Not,xot,Dot,Rot,_ot,Kot,Fot,Bot,Hot,qot,Got,zot,Uot,Xot,Wot,Vot,Qot,Yot,Jot=vX(j1n,"InteractiveExternalPortPositioner",1533);wAn(1534,1,{},Ge),MWn.Kb=function(n){return BB(n,17).d.i},MWn.Fb=function(n){return this===n},vX(j1n,"InteractiveExternalPortPositioner/lambda$0$Type",1534),wAn(1535,1,{},rd),MWn.Kb=function(n){return qN(this.a,MD(n))},MWn.Fb=function(n){return this===n},vX(j1n,"InteractiveExternalPortPositioner/lambda$1$Type",1535),wAn(1536,1,{},ze),MWn.Kb=function(n){return BB(n,17).c.i},MWn.Fb=function(n){return this===n},vX(j1n,"InteractiveExternalPortPositioner/lambda$2$Type",1536),wAn(1537,1,{},cd),MWn.Kb=function(n){return GN(this.a,MD(n))},MWn.Fb=function(n){return this===n},vX(j1n,"InteractiveExternalPortPositioner/lambda$3$Type",1537),wAn(1538,1,{},ad),MWn.Kb=function(n){return WR(this.a,MD(n))},MWn.Fb=function(n){return this===n},vX(j1n,"InteractiveExternalPortPositioner/lambda$4$Type",1538),wAn(1539,1,{},ud),MWn.Kb=function(n){return VR(this.a,MD(n))},MWn.Fb=function(n){return this===n},vX(j1n,"InteractiveExternalPortPositioner/lambda$5$Type",1539),wAn(77,22,{3:1,35:1,22:1,77:1,234:1},nP),MWn.Kf=function(){switch(this.g){case 15:return new dc;case 22:return new gc;case 47:return new mc;case 28:case 35:return new ei;case 32:return new Jt;case 42:return new te;case 1:return new ee;case 41:return new ie;case 56:return new id((Srn(),qut));case 0:return new id((Srn(),Hut));case 2:return new re;case 54:return new ce;case 33:return new se;case 51:return new me;case 55:return new Me;case 13:return new Se;case 38:return new Ie;case 44:return new Ce;case 40:return new $e;case 9:return new Yh;case 49:return new ox;case 37:return new De;case 43:return new Fe;case 27:return new Be;case 30:return new He;case 3:return new qe;case 18:return new Xe;case 29:return new We;case 5:return new Jh;case 50:return new Ue;case 34:return new Zh;case 36:return new ii;case 52:return new Vh;case 11:return new ci;case 7:return new tf;case 39:return new ai;case 45:return new ui;case 16:return new oi;case 10:return new si;case 48:return new fi;case 21:return new li;case 23:return new Ny((oin(),Amt));case 8:return new wi;case 12:return new gi;case 4:return new pi;case 19:return new af;case 17:return new Pi;case 53:return new Ii;case 6:return new Bi;case 25:return new am;case 46:return new Ni;case 31:return new xR;case 14:return new Vi;case 26:return new Sc;case 20:return new nr;case 24:return new Ny((oin(),$mt));default:throw Hp(new Ky(M1n+(null!=this.f?this.f:""+this.g)))}};var Zot,nst,tst,est,ist,rst,cst,ast,ust=Ben(j1n,S1n,77,Unt,ENn,nB);wAn(1540,1,n1n,Xe),MWn.pf=function(n,t){Jzn(BB(n,37),t)},vX(j1n,"InvertedPortProcessor",1540),wAn(1541,1,n1n,We),MWn.pf=function(n,t){L_n(BB(n,37),t)},vX(j1n,"LabelAndNodeSizeProcessor",1541),wAn(1542,1,DVn,Ve),MWn.Mb=function(n){return BB(n,10).k==(uSn(),Iut)},vX(j1n,"LabelAndNodeSizeProcessor/lambda$0$Type",1542),wAn(1543,1,DVn,Qe),MWn.Mb=function(n){return BB(n,10).k==(uSn(),Mut)},vX(j1n,"LabelAndNodeSizeProcessor/lambda$1$Type",1543),wAn(1544,1,lVn,_K),MWn.td=function(n){KM(this.b,this.a,this.c,BB(n,10))},MWn.a=!1,MWn.c=!1,vX(j1n,"LabelAndNodeSizeProcessor/lambda$2$Type",1544),wAn(1545,1,n1n,Jh),MWn.pf=function(n,t){fzn(BB(n,37),t)},vX(j1n,"LabelDummyInserter",1545),wAn(1546,1,qYn,Ye),MWn.Lb=function(n){return GC(mMn(BB(n,70),(HXn(),Ydt)))===GC((Rtn(),zPt))},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return GC(mMn(BB(n,70),(HXn(),Ydt)))===GC((Rtn(),zPt))},vX(j1n,"LabelDummyInserter/1",1546),wAn(1547,1,n1n,Ue),MWn.pf=function(n,t){Pqn(BB(n,37),t)},vX(j1n,"LabelDummyRemover",1547),wAn(1548,1,DVn,Je),MWn.Mb=function(n){return qy(TD(mMn(BB(n,70),(HXn(),Qdt))))},vX(j1n,"LabelDummyRemover/lambda$0$Type",1548),wAn(1359,1,n1n,Zh),MWn.pf=function(n,t){TGn(this,BB(n,37),t)},MWn.a=null,vX(j1n,"LabelDummySwitcher",1359),wAn(286,1,{286:1},c_n),MWn.c=0,MWn.d=null,MWn.f=0,vX(j1n,"LabelDummySwitcher/LabelDummyInfo",286),wAn(1360,1,{},Ze),MWn.Kb=function(n){return Crn(),new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"LabelDummySwitcher/lambda$0$Type",1360),wAn(1361,1,DVn,ni),MWn.Mb=function(n){return Crn(),BB(n,10).k==(uSn(),Sut)},vX(j1n,"LabelDummySwitcher/lambda$1$Type",1361),wAn(1362,1,{},hd),MWn.Kb=function(n){return XD(this.a,BB(n,10))},vX(j1n,"LabelDummySwitcher/lambda$2$Type",1362),wAn(1363,1,lVn,fd),MWn.td=function(n){YX(this.a,BB(n,286))},vX(j1n,"LabelDummySwitcher/lambda$3$Type",1363),wAn(1364,1,MYn,ti),MWn.ue=function(n,t){return Lz(BB(n,286),BB(t,286))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"LabelDummySwitcher/lambda$4$Type",1364),wAn(791,1,n1n,ei),MWn.pf=function(n,t){Y6(BB(n,37),t)},vX(j1n,"LabelManagementProcessor",791),wAn(1549,1,n1n,ii),MWn.pf=function(n,t){Nxn(BB(n,37),t)},vX(j1n,"LabelSideSelector",1549),wAn(1550,1,DVn,ri),MWn.Mb=function(n){return qy(TD(mMn(BB(n,70),(HXn(),Qdt))))},vX(j1n,"LabelSideSelector/lambda$0$Type",1550),wAn(1558,1,n1n,ci),MWn.pf=function(n,t){EBn(BB(n,37),t)},vX(j1n,"LayerConstraintPostprocessor",1558),wAn(1559,1,n1n,tf),MWn.pf=function(n,t){r$n(BB(n,37),t)},vX(j1n,"LayerConstraintPreprocessor",1559),wAn(360,22,{3:1,35:1,22:1,360:1},tP);var ost,sst,hst,fst,lst,bst,wst,dst,gst,pst=Ben(j1n,"LayerConstraintPreprocessor/HiddenNodeConnections",360,Unt,e3,zK);wAn(1560,1,n1n,ai),MWn.pf=function(n,t){Eqn(BB(n,37),t)},vX(j1n,"LayerSizeAndGraphHeightCalculator",1560),wAn(1561,1,n1n,ui),MWn.pf=function(n,t){ALn(BB(n,37),t)},vX(j1n,"LongEdgeJoiner",1561),wAn(1562,1,n1n,oi),MWn.pf=function(n,t){WHn(BB(n,37),t)},vX(j1n,"LongEdgeSplitter",1562),wAn(1563,1,n1n,si),MWn.pf=function(n,t){PGn(this,BB(n,37),t)},MWn.d=0,MWn.e=0,MWn.i=0,MWn.j=0,MWn.k=0,MWn.n=0,vX(j1n,"NodePromotion",1563),wAn(1564,1,{},hi),MWn.Kb=function(n){return BB(n,46),hN(),!0},MWn.Fb=function(n){return this===n},vX(j1n,"NodePromotion/lambda$0$Type",1564),wAn(1565,1,{},od),MWn.Kb=function(n){return aV(this.a,BB(n,46))},MWn.Fb=function(n){return this===n},MWn.a=0,vX(j1n,"NodePromotion/lambda$1$Type",1565),wAn(1566,1,{},sd),MWn.Kb=function(n){return uV(this.a,BB(n,46))},MWn.Fb=function(n){return this===n},MWn.a=0,vX(j1n,"NodePromotion/lambda$2$Type",1566),wAn(1567,1,n1n,fi),MWn.pf=function(n,t){XUn(BB(n,37),t)},vX(j1n,"NorthSouthPortPostprocessor",1567),wAn(1568,1,n1n,li),MWn.pf=function(n,t){MUn(BB(n,37),t)},vX(j1n,"NorthSouthPortPreprocessor",1568),wAn(1569,1,MYn,bi),MWn.ue=function(n,t){return Zan(BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"NorthSouthPortPreprocessor/lambda$0$Type",1569),wAn(1570,1,n1n,wi),MWn.pf=function(n,t){$Kn(BB(n,37),t)},vX(j1n,"PartitionMidprocessor",1570),wAn(1571,1,DVn,di),MWn.Mb=function(n){return Lx(BB(n,10),(HXn(),Wgt))},vX(j1n,"PartitionMidprocessor/lambda$0$Type",1571),wAn(1572,1,lVn,ld),MWn.td=function(n){$Q(this.a,BB(n,10))},vX(j1n,"PartitionMidprocessor/lambda$1$Type",1572),wAn(1573,1,n1n,gi),MWn.pf=function(n,t){wNn(BB(n,37),t)},vX(j1n,"PartitionPostprocessor",1573),wAn(1574,1,n1n,pi),MWn.pf=function(n,t){NOn(BB(n,37),t)},vX(j1n,"PartitionPreprocessor",1574),wAn(1575,1,DVn,vi),MWn.Mb=function(n){return Lx(BB(n,10),(HXn(),Wgt))},vX(j1n,"PartitionPreprocessor/lambda$0$Type",1575),wAn(1576,1,{},mi),MWn.Kb=function(n){return new Rq(null,new zU(new oz(ZL(lbn(BB(n,10)).a.Kc(),new h))))},vX(j1n,"PartitionPreprocessor/lambda$1$Type",1576),wAn(1577,1,DVn,yi),MWn.Mb=function(n){return Lgn(BB(n,17))},vX(j1n,"PartitionPreprocessor/lambda$2$Type",1577),wAn(1578,1,lVn,ki),MWn.td=function(n){Run(BB(n,17))},vX(j1n,"PartitionPreprocessor/lambda$3$Type",1578),wAn(1579,1,n1n,af),MWn.pf=function(n,t){uKn(BB(n,37),t)},vX(j1n,"PortListSorter",1579),wAn(1580,1,{},ji),MWn.Kb=function(n){return zsn(),BB(n,11).e},vX(j1n,"PortListSorter/lambda$0$Type",1580),wAn(1581,1,{},Ei),MWn.Kb=function(n){return zsn(),BB(n,11).g},vX(j1n,"PortListSorter/lambda$1$Type",1581),wAn(1582,1,MYn,Ti),MWn.ue=function(n,t){return T4(BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"PortListSorter/lambda$2$Type",1582),wAn(1583,1,MYn,Mi),MWn.ue=function(n,t){return Oyn(BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"PortListSorter/lambda$3$Type",1583),wAn(1584,1,MYn,Si),MWn.ue=function(n,t){return nFn(BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"PortListSorter/lambda$4$Type",1584),wAn(1585,1,n1n,Pi),MWn.pf=function(n,t){WAn(BB(n,37),t)},vX(j1n,"PortSideProcessor",1585),wAn(1586,1,n1n,Ii),MWn.pf=function(n,t){CRn(BB(n,37),t)},vX(j1n,"ReversedEdgeRestorer",1586),wAn(1591,1,n1n,am),MWn.pf=function(n,t){Ymn(this,BB(n,37),t)},vX(j1n,"SelfLoopPortRestorer",1591),wAn(1592,1,{},Ci),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"SelfLoopPortRestorer/lambda$0$Type",1592),wAn(1593,1,DVn,Oi),MWn.Mb=function(n){return BB(n,10).k==(uSn(),Iut)},vX(j1n,"SelfLoopPortRestorer/lambda$1$Type",1593),wAn(1594,1,DVn,Ai),MWn.Mb=function(n){return Lx(BB(n,10),(hWn(),Olt))},vX(j1n,"SelfLoopPortRestorer/lambda$2$Type",1594),wAn(1595,1,{},$i),MWn.Kb=function(n){return BB(mMn(BB(n,10),(hWn(),Olt)),403)},vX(j1n,"SelfLoopPortRestorer/lambda$3$Type",1595),wAn(1596,1,lVn,bd),MWn.td=function(n){SSn(this.a,BB(n,403))},vX(j1n,"SelfLoopPortRestorer/lambda$4$Type",1596),wAn(794,1,lVn,Li),MWn.td=function(n){nPn(BB(n,101))},vX(j1n,"SelfLoopPortRestorer/lambda$5$Type",794),wAn(1597,1,n1n,Ni),MWn.pf=function(n,t){Lpn(BB(n,37),t)},vX(j1n,"SelfLoopPostProcessor",1597),wAn(1598,1,{},xi),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"SelfLoopPostProcessor/lambda$0$Type",1598),wAn(1599,1,DVn,Di),MWn.Mb=function(n){return BB(n,10).k==(uSn(),Iut)},vX(j1n,"SelfLoopPostProcessor/lambda$1$Type",1599),wAn(1600,1,DVn,Ri),MWn.Mb=function(n){return Lx(BB(n,10),(hWn(),Olt))},vX(j1n,"SelfLoopPostProcessor/lambda$2$Type",1600),wAn(1601,1,lVn,_i),MWn.td=function(n){Ljn(BB(n,10))},vX(j1n,"SelfLoopPostProcessor/lambda$3$Type",1601),wAn(1602,1,{},Ki),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,101).f,1))},vX(j1n,"SelfLoopPostProcessor/lambda$4$Type",1602),wAn(1603,1,lVn,wd),MWn.td=function(n){a3(this.a,BB(n,409))},vX(j1n,"SelfLoopPostProcessor/lambda$5$Type",1603),wAn(1604,1,DVn,Fi),MWn.Mb=function(n){return!!BB(n,101).i},vX(j1n,"SelfLoopPostProcessor/lambda$6$Type",1604),wAn(1605,1,lVn,dd),MWn.td=function(n){Ty(this.a,BB(n,101))},vX(j1n,"SelfLoopPostProcessor/lambda$7$Type",1605),wAn(1587,1,n1n,Bi),MWn.pf=function(n,t){Z$n(BB(n,37),t)},vX(j1n,"SelfLoopPreProcessor",1587),wAn(1588,1,{},Hi),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,101).f,1))},vX(j1n,"SelfLoopPreProcessor/lambda$0$Type",1588),wAn(1589,1,{},qi),MWn.Kb=function(n){return BB(n,409).a},vX(j1n,"SelfLoopPreProcessor/lambda$1$Type",1589),wAn(1590,1,lVn,Gi),MWn.td=function(n){q$(BB(n,17))},vX(j1n,"SelfLoopPreProcessor/lambda$2$Type",1590),wAn(1606,1,n1n,xR),MWn.pf=function(n,t){sSn(this,BB(n,37),t)},vX(j1n,"SelfLoopRouter",1606),wAn(1607,1,{},zi),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,29).a,16))},vX(j1n,"SelfLoopRouter/lambda$0$Type",1607),wAn(1608,1,DVn,Ui),MWn.Mb=function(n){return BB(n,10).k==(uSn(),Iut)},vX(j1n,"SelfLoopRouter/lambda$1$Type",1608),wAn(1609,1,DVn,Xi),MWn.Mb=function(n){return Lx(BB(n,10),(hWn(),Olt))},vX(j1n,"SelfLoopRouter/lambda$2$Type",1609),wAn(1610,1,{},Wi),MWn.Kb=function(n){return BB(mMn(BB(n,10),(hWn(),Olt)),403)},vX(j1n,"SelfLoopRouter/lambda$3$Type",1610),wAn(1611,1,lVn,eP),MWn.td=function(n){QV(this.a,this.b,BB(n,403))},vX(j1n,"SelfLoopRouter/lambda$4$Type",1611),wAn(1612,1,n1n,Vi),MWn.pf=function(n,t){fxn(BB(n,37),t)},vX(j1n,"SemiInteractiveCrossMinProcessor",1612),wAn(1613,1,DVn,Qi),MWn.Mb=function(n){return BB(n,10).k==(uSn(),Iut)},vX(j1n,"SemiInteractiveCrossMinProcessor/lambda$0$Type",1613),wAn(1614,1,DVn,Yi),MWn.Mb=function(n){return Gq(BB(n,10))._b((HXn(),spt))},vX(j1n,"SemiInteractiveCrossMinProcessor/lambda$1$Type",1614),wAn(1615,1,MYn,Ji),MWn.ue=function(n,t){return drn(BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(j1n,"SemiInteractiveCrossMinProcessor/lambda$2$Type",1615),wAn(1616,1,{},Zi),MWn.Ce=function(n,t){return XQ(BB(n,10),BB(t,10))},vX(j1n,"SemiInteractiveCrossMinProcessor/lambda$3$Type",1616),wAn(1618,1,n1n,nr),MWn.pf=function(n,t){MBn(BB(n,37),t)},vX(j1n,"SortByInputModelProcessor",1618),wAn(1619,1,DVn,tr),MWn.Mb=function(n){return 0!=BB(n,11).g.c.length},vX(j1n,"SortByInputModelProcessor/lambda$0$Type",1619),wAn(1620,1,lVn,gd),MWn.td=function(n){fPn(this.a,BB(n,11))},vX(j1n,"SortByInputModelProcessor/lambda$1$Type",1620),wAn(1693,803,{},grn),MWn.Me=function(n){var t,e,i,r;switch(this.c=n,this.a.g){case 2:t=new Np,JT(AV(new Rq(null,new w1(this.c.a.b,16)),new dr),new uP(this,t)),pIn(this,new rr),Otn(t,new cr),t.c=x8(Ant,HWn,1,0,5,1),JT(AV(new Rq(null,new w1(this.c.a.b,16)),new ar),new vd(t)),pIn(this,new ur),Otn(t,new or),t.c=x8(Ant,HWn,1,0,5,1),e=j$(icn(LV(new Rq(null,new w1(this.c.a.b,16)),new md(this))),new sr),JT(new Rq(null,new w1(this.c.a.a,16)),new rP(e,t)),pIn(this,new fr),Otn(t,new er),t.c=x8(Ant,HWn,1,0,5,1);break;case 3:i=new Np,pIn(this,new ir),r=j$(icn(LV(new Rq(null,new w1(this.c.a.b,16)),new pd(this))),new hr),JT(AV(new Rq(null,new w1(this.c.a.b,16)),new lr),new aP(r,i)),pIn(this,new br),Otn(i,new wr),i.c=x8(Ant,HWn,1,0,5,1);break;default:throw Hp(new kv)}},MWn.b=0,vX(A1n,"EdgeAwareScanlineConstraintCalculation",1693),wAn(1694,1,qYn,ir),MWn.Lb=function(n){return cL(BB(n,57).g,145)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return cL(BB(n,57).g,145)},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$0$Type",1694),wAn(1695,1,{},pd),MWn.Fe=function(n){return GIn(this.a,BB(n,57))},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$1$Type",1695),wAn(1703,1,RVn,iP),MWn.Vd=function(){Fkn(this.a,this.b,-1)},MWn.b=0,vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$10$Type",1703),wAn(1705,1,qYn,rr),MWn.Lb=function(n){return cL(BB(n,57).g,145)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return cL(BB(n,57).g,145)},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$11$Type",1705),wAn(1706,1,lVn,cr),MWn.td=function(n){BB(n,365).Vd()},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$12$Type",1706),wAn(1707,1,DVn,ar),MWn.Mb=function(n){return cL(BB(n,57).g,10)},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$13$Type",1707),wAn(1709,1,lVn,vd),MWn.td=function(n){Ebn(this.a,BB(n,57))},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$14$Type",1709),wAn(1708,1,RVn,lP),MWn.Vd=function(){Fkn(this.b,this.a,-1)},MWn.a=0,vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$15$Type",1708),wAn(1710,1,qYn,ur),MWn.Lb=function(n){return cL(BB(n,57).g,10)},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return cL(BB(n,57).g,10)},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$16$Type",1710),wAn(1711,1,lVn,or),MWn.td=function(n){BB(n,365).Vd()},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$17$Type",1711),wAn(1712,1,{},md),MWn.Fe=function(n){return zIn(this.a,BB(n,57))},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$18$Type",1712),wAn(1713,1,{},sr),MWn.De=function(){return 0},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$19$Type",1713),wAn(1696,1,{},hr),MWn.De=function(){return 0},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$2$Type",1696),wAn(1715,1,lVn,rP),MWn.td=function(n){HG(this.a,this.b,BB(n,307))},MWn.a=0,vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$20$Type",1715),wAn(1714,1,RVn,cP),MWn.Vd=function(){VAn(this.a,this.b,-1)},MWn.b=0,vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$21$Type",1714),wAn(1716,1,qYn,fr),MWn.Lb=function(n){return BB(n,57),!0},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return BB(n,57),!0},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$22$Type",1716),wAn(1717,1,lVn,er),MWn.td=function(n){BB(n,365).Vd()},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$23$Type",1717),wAn(1697,1,DVn,lr),MWn.Mb=function(n){return cL(BB(n,57).g,10)},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$3$Type",1697),wAn(1699,1,lVn,aP),MWn.td=function(n){qG(this.a,this.b,BB(n,57))},MWn.a=0,vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$4$Type",1699),wAn(1698,1,RVn,bP),MWn.Vd=function(){Fkn(this.b,this.a,-1)},MWn.a=0,vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$5$Type",1698),wAn(1700,1,qYn,br),MWn.Lb=function(n){return BB(n,57),!0},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return BB(n,57),!0},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$6$Type",1700),wAn(1701,1,lVn,wr),MWn.td=function(n){BB(n,365).Vd()},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$7$Type",1701),wAn(1702,1,DVn,dr),MWn.Mb=function(n){return cL(BB(n,57).g,145)},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$8$Type",1702),wAn(1704,1,lVn,uP),MWn.td=function(n){Ttn(this.a,this.b,BB(n,57))},vX(A1n,"EdgeAwareScanlineConstraintCalculation/lambda$9$Type",1704),wAn(1521,1,n1n,ox),MWn.pf=function(n,t){cqn(this,BB(n,37),t)},vX(A1n,"HorizontalGraphCompactor",1521),wAn(1522,1,{},yd),MWn.Oe=function(n,t){var e,i;return Z7(n,t)?0:(e=f2(n),i=f2(t),e&&e.k==(uSn(),Mut)||i&&i.k==(uSn(),Mut)?0:UN(BB(mMn(this.a.a,(hWn(),Alt)),304),e?e.k:(uSn(),Put),i?i.k:(uSn(),Put)))},MWn.Pe=function(n,t){var e,i;return Z7(n,t)?1:(e=f2(n),i=f2(t),XN(BB(mMn(this.a.a,(hWn(),Alt)),304),e?e.k:(uSn(),Put),i?i.k:(uSn(),Put)))},vX(A1n,"HorizontalGraphCompactor/1",1522),wAn(1523,1,{},gr),MWn.Ne=function(n,t){return MM(),0==n.a.i},vX(A1n,"HorizontalGraphCompactor/lambda$0$Type",1523),wAn(1524,1,{},kd),MWn.Ne=function(n,t){return KQ(this.a,n,t)},vX(A1n,"HorizontalGraphCompactor/lambda$1$Type",1524),wAn(1664,1,{},C7),vX(A1n,"LGraphToCGraphTransformer",1664),wAn(1672,1,DVn,pr),MWn.Mb=function(n){return null!=n},vX(A1n,"LGraphToCGraphTransformer/0methodref$nonNull$Type",1672),wAn(1665,1,{},vr),MWn.Kb=function(n){return GK(),Bbn(mMn(BB(BB(n,57).g,10),(hWn(),dlt)))},vX(A1n,"LGraphToCGraphTransformer/lambda$0$Type",1665),wAn(1666,1,{},mr),MWn.Kb=function(n){return GK(),mfn(BB(BB(n,57).g,145))},vX(A1n,"LGraphToCGraphTransformer/lambda$1$Type",1666),wAn(1675,1,DVn,yr),MWn.Mb=function(n){return GK(),cL(BB(n,57).g,10)},vX(A1n,"LGraphToCGraphTransformer/lambda$10$Type",1675),wAn(1676,1,lVn,kr),MWn.td=function(n){_Q(BB(n,57))},vX(A1n,"LGraphToCGraphTransformer/lambda$11$Type",1676),wAn(1677,1,DVn,jr),MWn.Mb=function(n){return GK(),cL(BB(n,57).g,145)},vX(A1n,"LGraphToCGraphTransformer/lambda$12$Type",1677),wAn(1681,1,lVn,Er),MWn.td=function(n){vfn(BB(n,57))},vX(A1n,"LGraphToCGraphTransformer/lambda$13$Type",1681),wAn(1678,1,lVn,jd),MWn.td=function(n){uA(this.a,BB(n,8))},MWn.a=0,vX(A1n,"LGraphToCGraphTransformer/lambda$14$Type",1678),wAn(1679,1,lVn,Ed),MWn.td=function(n){sA(this.a,BB(n,110))},MWn.a=0,vX(A1n,"LGraphToCGraphTransformer/lambda$15$Type",1679),wAn(1680,1,lVn,Td),MWn.td=function(n){oA(this.a,BB(n,8))},MWn.a=0,vX(A1n,"LGraphToCGraphTransformer/lambda$16$Type",1680),wAn(1682,1,{},Tr),MWn.Kb=function(n){return GK(),new Rq(null,new zU(new oz(ZL(lbn(BB(n,10)).a.Kc(),new h))))},vX(A1n,"LGraphToCGraphTransformer/lambda$17$Type",1682),wAn(1683,1,DVn,Mr),MWn.Mb=function(n){return GK(),b5(BB(n,17))},vX(A1n,"LGraphToCGraphTransformer/lambda$18$Type",1683),wAn(1684,1,lVn,Md),MWn.td=function(n){Snn(this.a,BB(n,17))},vX(A1n,"LGraphToCGraphTransformer/lambda$19$Type",1684),wAn(1668,1,lVn,Sd),MWn.td=function(n){l0(this.a,BB(n,145))},vX(A1n,"LGraphToCGraphTransformer/lambda$2$Type",1668),wAn(1685,1,{},Sr),MWn.Kb=function(n){return GK(),new Rq(null,new w1(BB(n,29).a,16))},vX(A1n,"LGraphToCGraphTransformer/lambda$20$Type",1685),wAn(1686,1,{},Pr),MWn.Kb=function(n){return GK(),new Rq(null,new zU(new oz(ZL(lbn(BB(n,10)).a.Kc(),new h))))},vX(A1n,"LGraphToCGraphTransformer/lambda$21$Type",1686),wAn(1687,1,{},Ir),MWn.Kb=function(n){return GK(),BB(mMn(BB(n,17),(hWn(),Nlt)),15)},vX(A1n,"LGraphToCGraphTransformer/lambda$22$Type",1687),wAn(1688,1,DVn,Cr),MWn.Mb=function(n){return tx(BB(n,15))},vX(A1n,"LGraphToCGraphTransformer/lambda$23$Type",1688),wAn(1689,1,lVn,Pd),MWn.td=function(n){PIn(this.a,BB(n,15))},vX(A1n,"LGraphToCGraphTransformer/lambda$24$Type",1689),wAn(1667,1,lVn,oP),MWn.td=function(n){H3(this.a,this.b,BB(n,145))},vX(A1n,"LGraphToCGraphTransformer/lambda$3$Type",1667),wAn(1669,1,{},Or),MWn.Kb=function(n){return GK(),new Rq(null,new w1(BB(n,29).a,16))},vX(A1n,"LGraphToCGraphTransformer/lambda$4$Type",1669),wAn(1670,1,{},Ar),MWn.Kb=function(n){return GK(),new Rq(null,new zU(new oz(ZL(lbn(BB(n,10)).a.Kc(),new h))))},vX(A1n,"LGraphToCGraphTransformer/lambda$5$Type",1670),wAn(1671,1,{},$r),MWn.Kb=function(n){return GK(),BB(mMn(BB(n,17),(hWn(),Nlt)),15)},vX(A1n,"LGraphToCGraphTransformer/lambda$6$Type",1671),wAn(1673,1,lVn,Id),MWn.td=function(n){_Cn(this.a,BB(n,15))},vX(A1n,"LGraphToCGraphTransformer/lambda$8$Type",1673),wAn(1674,1,lVn,sP),MWn.td=function(n){x$(this.a,this.b,BB(n,145))},vX(A1n,"LGraphToCGraphTransformer/lambda$9$Type",1674),wAn(1663,1,{},Lr),MWn.Le=function(n){var t,e,i,r,c;for(this.a=n,this.d=new Fv,this.c=x8(qit,HWn,121,this.a.a.a.c.length,0,1),this.b=0,e=new Wb(this.a.a.a);e.a<e.c.c.length;)(t=BB(n0(e),307)).d=this.b,c=AN(oM(new qv,t),this.d),this.c[this.b]=c,++this.b;for(JGn(this),AUn(this),ZLn(this),W_n(BK(this.d),new Xm),r=new Wb(this.a.a.b);r.a<r.c.c.length;)(i=BB(n0(r),57)).d.c=this.c[i.a.d].e+i.b.a},MWn.b=0,vX(A1n,"NetworkSimplexCompaction",1663),wAn(145,1,{35:1,145:1},PBn),MWn.wd=function(n){return Lnn(this,BB(n,145))},MWn.Ib=function(){return mfn(this)},vX(A1n,"VerticalSegment",145),wAn(827,1,{},zEn),MWn.c=0,MWn.e=0,MWn.i=0,vX($1n,"BetweenLayerEdgeTwoNodeCrossingsCounter",827),wAn(663,1,{663:1},kcn),MWn.Ib=function(){return"AdjacencyList [node="+this.d+", adjacencies= "+this.a+"]"},MWn.b=0,MWn.c=0,MWn.f=0,vX($1n,"BetweenLayerEdgeTwoNodeCrossingsCounter/AdjacencyList",663),wAn(287,1,{35:1,287:1},Gx),MWn.wd=function(n){return aq(this,BB(n,287))},MWn.Ib=function(){return"Adjacency [position="+this.c+", cardinality="+this.a+", currentCardinality="+this.b+"]"},MWn.a=0,MWn.b=0,MWn.c=0,vX($1n,"BetweenLayerEdgeTwoNodeCrossingsCounter/AdjacencyList/Adjacency",287),wAn(1929,1,{},ZSn),MWn.b=0,MWn.e=!1,vX($1n,"CrossingMatrixFiller",1929);var vst,mst,yst,kst,jst=bq(L1n,"IInitializable");wAn(1804,1,N1n,vP),MWn.Nf=function(n,t,e,i,r,c){},MWn.Pf=function(n,t,e){},MWn.Lf=function(){return this.c!=(oin(),Amt)},MWn.Mf=function(){this.e=x8(ANt,hQn,25,this.d,15,1)},MWn.Of=function(n,t){t[n][0].c.p=n},MWn.Qf=function(n,t,e,i){++this.d},MWn.Rf=function(){return!0},MWn.Sf=function(n,t,e,i){return Yhn(this,n,t,e),Z4(this,t)},MWn.Tf=function(n,t){var e;return Yhn(this,n,e=hj(t,n.length),t),bon(this,e)},MWn.d=0,vX($1n,"GreedySwitchHeuristic",1804),wAn(1930,1,{},lG),MWn.b=0,MWn.d=0,vX($1n,"NorthSouthEdgeNeighbouringNodeCrossingsCounter",1930),wAn(1917,1,{},uRn),MWn.a=!1,vX($1n,"SwitchDecider",1917),wAn(101,1,{101:1},pPn),MWn.a=null,MWn.c=null,MWn.i=null,vX(x1n,"SelfHyperLoop",101),wAn(1916,1,{},epn),MWn.c=0,MWn.e=0,vX(x1n,"SelfHyperLoopLabels",1916),wAn(411,22,{3:1,35:1,22:1,411:1},mP);var Est,Tst,Mst,Sst,Pst,Ist,Cst=Ben(x1n,"SelfHyperLoopLabels/Alignment",411,Unt,r3,UK);wAn(409,1,{409:1},j6),vX(x1n,"SelfLoopEdge",409),wAn(403,1,{403:1},Ogn),MWn.a=!1,vX(x1n,"SelfLoopHolder",403),wAn(1724,1,DVn,qr),MWn.Mb=function(n){return b5(BB(n,17))},vX(x1n,"SelfLoopHolder/lambda$0$Type",1724),wAn(113,1,{113:1},ipn),MWn.a=!1,MWn.c=!1,vX(x1n,"SelfLoopPort",113),wAn(1792,1,DVn,Gr),MWn.Mb=function(n){return b5(BB(n,17))},vX(x1n,"SelfLoopPort/lambda$0$Type",1792),wAn(363,22,{3:1,35:1,22:1,363:1},yP);var Ost,Ast,$st,Lst,Nst,xst,Dst,Rst,_st=Ben(x1n,"SelfLoopType",363,Unt,x5,YK);wAn(1732,1,{},uf),vX(D1n,"PortRestorer",1732),wAn(361,22,{3:1,35:1,22:1,361:1},kP);var Kst,Fst,Bst,Hst,qst,Gst,zst,Ust,Xst,Wst=Ben(D1n,"PortRestorer/PortSideArea",361,Unt,P1,JK);wAn(1733,1,{},Wr),MWn.Kb=function(n){return KMn(),BB(n,15).Oc()},vX(D1n,"PortRestorer/lambda$0$Type",1733),wAn(1734,1,lVn,Vr),MWn.td=function(n){KMn(),BB(n,113).c=!1},vX(D1n,"PortRestorer/lambda$1$Type",1734),wAn(1743,1,DVn,Qr),MWn.Mb=function(n){return KMn(),BB(n,11).j==(kUn(),ICt)},vX(D1n,"PortRestorer/lambda$10$Type",1743),wAn(1744,1,{},Yr),MWn.Kb=function(n){return KMn(),BB(n,113).d},vX(D1n,"PortRestorer/lambda$11$Type",1744),wAn(1745,1,lVn,Cd),MWn.td=function(n){Nj(this.a,BB(n,11))},vX(D1n,"PortRestorer/lambda$12$Type",1745),wAn(1735,1,lVn,Od),MWn.td=function(n){Ax(this.a,BB(n,101))},vX(D1n,"PortRestorer/lambda$2$Type",1735),wAn(1736,1,MYn,Jr),MWn.ue=function(n,t){return oen(BB(n,113),BB(t,113))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(D1n,"PortRestorer/lambda$3$Type",1736),wAn(1737,1,DVn,Zr),MWn.Mb=function(n){return KMn(),BB(n,113).c},vX(D1n,"PortRestorer/lambda$4$Type",1737),wAn(1738,1,DVn,xr),MWn.Mb=function(n){return Acn(BB(n,11))},vX(D1n,"PortRestorer/lambda$5$Type",1738),wAn(1739,1,DVn,Nr),MWn.Mb=function(n){return KMn(),BB(n,11).j==(kUn(),sCt)},vX(D1n,"PortRestorer/lambda$6$Type",1739),wAn(1740,1,DVn,Dr),MWn.Mb=function(n){return KMn(),BB(n,11).j==(kUn(),oCt)},vX(D1n,"PortRestorer/lambda$7$Type",1740),wAn(1741,1,DVn,Rr),MWn.Mb=function(n){return c3(BB(n,11))},vX(D1n,"PortRestorer/lambda$8$Type",1741),wAn(1742,1,DVn,_r),MWn.Mb=function(n){return KMn(),BB(n,11).j==(kUn(),SCt)},vX(D1n,"PortRestorer/lambda$9$Type",1742),wAn(270,22,{3:1,35:1,22:1,270:1},WV);var Vst,Qst,Yst,Jst,Zst,nht,tht,eht,iht=Ben(D1n,"PortSideAssigner/Target",270,Unt,Ftn,XK);wAn(1725,1,{},Kr),MWn.Kb=function(n){return AV(new Rq(null,new w1(BB(n,101).j,16)),new Xr)},vX(D1n,"PortSideAssigner/lambda$1$Type",1725),wAn(1726,1,{},Fr),MWn.Kb=function(n){return BB(n,113).d},vX(D1n,"PortSideAssigner/lambda$2$Type",1726),wAn(1727,1,lVn,Br),MWn.td=function(n){qIn(BB(n,11),(kUn(),sCt))},vX(D1n,"PortSideAssigner/lambda$3$Type",1727),wAn(1728,1,{},Hr),MWn.Kb=function(n){return BB(n,113).d},vX(D1n,"PortSideAssigner/lambda$4$Type",1728),wAn(1729,1,lVn,Ad),MWn.td=function(n){tv(this.a,BB(n,11))},vX(D1n,"PortSideAssigner/lambda$5$Type",1729),wAn(1730,1,MYn,zr),MWn.ue=function(n,t){return MW(BB(n,101),BB(t,101))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(D1n,"PortSideAssigner/lambda$6$Type",1730),wAn(1731,1,MYn,Ur),MWn.ue=function(n,t){return oH(BB(n,113),BB(t,113))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(D1n,"PortSideAssigner/lambda$7$Type",1731),wAn(805,1,DVn,Xr),MWn.Mb=function(n){return BB(n,113).c},vX(D1n,"PortSideAssigner/lambda$8$Type",805),wAn(2009,1,{}),vX(R1n,"AbstractSelfLoopRouter",2009),wAn(1750,1,MYn,nc),MWn.ue=function(n,t){return C_(BB(n,101),BB(t,101))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(R1n,bJn,1750),wAn(1751,1,MYn,tc),MWn.ue=function(n,t){return I_(BB(n,101),BB(t,101))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(R1n,wJn,1751),wAn(1793,2009,{},ec),MWn.Uf=function(n,t,e){return e},vX(R1n,"OrthogonalSelfLoopRouter",1793),wAn(1795,1,lVn,wP),MWn.td=function(n){pgn(this.b,this.a,BB(n,8))},vX(R1n,"OrthogonalSelfLoopRouter/lambda$0$Type",1795),wAn(1794,1793,{},ic),MWn.Uf=function(n,t,e){var i,r;return _x(e,0,UR(B$((i=n.c.d).n),i.a)),DH(e,UR(B$((r=n.d.d).n),r.a)),EKn(e)},vX(R1n,"PolylineSelfLoopRouter",1794),wAn(1746,1,{},nf),MWn.a=null,vX(R1n,"RoutingDirector",1746),wAn(1747,1,MYn,rc),MWn.ue=function(n,t){return wH(BB(n,113),BB(t,113))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(R1n,"RoutingDirector/lambda$0$Type",1747),wAn(1748,1,{},cc),MWn.Kb=function(n){return SM(),BB(n,101).j},vX(R1n,"RoutingDirector/lambda$1$Type",1748),wAn(1749,1,lVn,ac),MWn.td=function(n){SM(),BB(n,15).ad(Qst)},vX(R1n,"RoutingDirector/lambda$2$Type",1749),wAn(1752,1,{},uc),vX(R1n,"RoutingSlotAssigner",1752),wAn(1753,1,DVn,$d),MWn.Mb=function(n){return II(this.a,BB(n,101))},vX(R1n,"RoutingSlotAssigner/lambda$0$Type",1753),wAn(1754,1,MYn,Ld),MWn.ue=function(n,t){return Uq(this.a,BB(n,101),BB(t,101))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(R1n,"RoutingSlotAssigner/lambda$1$Type",1754),wAn(1796,1793,{},oc),MWn.Uf=function(n,t,e){var i,r,c,a;return i=Gy(MD(gpn(n.b.g.b,(HXn(),jpt)))),nLn(n,t,e,a=new Ux(Pun(Gk(PMt,1),sVn,8,0,[(c=n.c.d,UR(new wA(c.n),c.a))])),i),DH(a,UR(new wA((r=n.d.d).n),r.a)),Fvn(new oBn(a))},vX(R1n,"SplineSelfLoopRouter",1796),wAn(578,1,MYn,Grn,kH),MWn.ue=function(n,t){return fXn(this,BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(_1n,"ModelOrderNodeComparator",578),wAn(1755,1,DVn,sc),MWn.Mb=function(n){return 0!=BB(n,11).e.c.length},vX(_1n,"ModelOrderNodeComparator/lambda$0$Type",1755),wAn(1756,1,{},hc),MWn.Kb=function(n){return BB(xq(BB(n,11).e,0),17).c},vX(_1n,"ModelOrderNodeComparator/lambda$1$Type",1756),wAn(1757,1,DVn,fc),MWn.Mb=function(n){return 0!=BB(n,11).e.c.length},vX(_1n,"ModelOrderNodeComparator/lambda$2$Type",1757),wAn(1758,1,{},lc),MWn.Kb=function(n){return BB(xq(BB(n,11).e,0),17).c},vX(_1n,"ModelOrderNodeComparator/lambda$3$Type",1758),wAn(1759,1,DVn,bc),MWn.Mb=function(n){return 0!=BB(n,11).e.c.length},vX(_1n,"ModelOrderNodeComparator/lambda$4$Type",1759),wAn(806,1,MYn,O7,pP),MWn.ue=function(n,t){return Nz(this,n,t)},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(_1n,"ModelOrderPortComparator",806),wAn(801,1,{},wc),MWn.Vf=function(n,t){var i,r,c,a;for(c=PSn(t),i=new Np,a=t.f/c,r=1;r<c;++r)WB(i,iln(dG(fan(e.Math.round(r*a)))));return i},MWn.Wf=function(){return!1},vX(K1n,"ARDCutIndexHeuristic",801),wAn(1479,1,n1n,dc),MWn.pf=function(n,t){o_n(BB(n,37),t)},vX(K1n,"BreakingPointInserter",1479),wAn(305,1,{305:1},v3),MWn.Ib=function(){var n;return(n=new Ik).a+="BPInfo[",n.a+="\n\tstart=",uO(n,this.i),n.a+="\n\tend=",uO(n,this.a),n.a+="\n\tnodeStartEdge=",uO(n,this.e),n.a+="\n\tstartEndEdge=",uO(n,this.j),n.a+="\n\toriginalEdge=",uO(n,this.f),n.a+="\n\tstartInLayerDummy=",uO(n,this.k),n.a+="\n\tstartInLayerEdge=",uO(n,this.n),n.a+="\n\tendInLayerDummy=",uO(n,this.b),n.a+="\n\tendInLayerEdge=",uO(n,this.c),n.a},vX(K1n,"BreakingPointInserter/BPInfo",305),wAn(652,1,{652:1},Hd),MWn.a=!1,MWn.b=0,MWn.c=0,vX(K1n,"BreakingPointInserter/Cut",652),wAn(1480,1,n1n,gc),MWn.pf=function(n,t){mLn(BB(n,37),t)},vX(K1n,"BreakingPointProcessor",1480),wAn(1481,1,DVn,pc),MWn.Mb=function(n){return Jnn(BB(n,10))},vX(K1n,"BreakingPointProcessor/0methodref$isEnd$Type",1481),wAn(1482,1,DVn,vc),MWn.Mb=function(n){return Znn(BB(n,10))},vX(K1n,"BreakingPointProcessor/1methodref$isStart$Type",1482),wAn(1483,1,n1n,mc),MWn.pf=function(n,t){rNn(this,BB(n,37),t)},vX(K1n,"BreakingPointRemover",1483),wAn(1484,1,lVn,yc),MWn.td=function(n){BB(n,128).k=!0},vX(K1n,"BreakingPointRemover/lambda$0$Type",1484),wAn(797,1,{},MAn),MWn.b=0,MWn.e=0,MWn.f=0,MWn.j=0,vX(K1n,"GraphStats",797),wAn(798,1,{},kc),MWn.Ce=function(n,t){return e.Math.max(Gy(MD(n)),Gy(MD(t)))},vX(K1n,"GraphStats/0methodref$max$Type",798),wAn(799,1,{},jc),MWn.Ce=function(n,t){return e.Math.max(Gy(MD(n)),Gy(MD(t)))},vX(K1n,"GraphStats/2methodref$max$Type",799),wAn(1660,1,{},Ec),MWn.Ce=function(n,t){return vB(MD(n),MD(t))},vX(K1n,"GraphStats/lambda$1$Type",1660),wAn(1661,1,{},Nd),MWn.Kb=function(n){return wpn(this.a,BB(n,29))},vX(K1n,"GraphStats/lambda$2$Type",1661),wAn(1662,1,{},xd),MWn.Kb=function(n){return VLn(this.a,BB(n,29))},vX(K1n,"GraphStats/lambda$6$Type",1662),wAn(800,1,{},Tc),MWn.Vf=function(n,t){return BB(mMn(n,(HXn(),Kpt)),15)||(SQ(),SQ(),set)},MWn.Wf=function(){return!1},vX(K1n,"ICutIndexCalculator/ManualCutIndexCalculator",800),wAn(802,1,{},Mc),MWn.Vf=function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(null==t.n&&Dmn(t),k=t.n,null==t.d&&Dmn(t),s=t.d,(y=x8(xNt,qQn,25,k.length,15,1))[0]=k[0],v=k[0],h=1;h<k.length;h++)y[h]=y[h-1]+k[h],v+=k[h];for(c=PSn(t)-1,u=BB(mMn(n,(HXn(),Fpt)),19).a,r=_Qn,i=new Np,b=e.Math.max(0,c-u);b<=e.Math.min(t.f-1,c+u);b++){if(g=v/(b+1),p=0,f=1,a=new Np,m=_Qn,l=0,o=0,d=s[0],0==b)m=v,null==t.g&&(t.g=Xrn(t,new jc)),o=Gy(t.g);else{for(;f<t.f;)y[f-1]-p>=g&&(WB(a,iln(f)),m=e.Math.max(m,y[f-1]-l),o+=d,p+=y[f-1]-p,l=y[f-1],d=s[f]),d=e.Math.max(d,s[f]),++f;o+=d}(w=e.Math.min(1/m,1/t.b/o))>r&&(r=w,i=a)}return i},MWn.Wf=function(){return!1},vX(K1n,"MSDCutIndexHeuristic",802),wAn(1617,1,n1n,Sc),MWn.pf=function(n,t){bBn(BB(n,37),t)},vX(K1n,"SingleEdgeGraphWrapper",1617),wAn(227,22,{3:1,35:1,22:1,227:1},jP);var rht,cht,aht,uht=Ben(F1n,"CenterEdgeLabelPlacementStrategy",227,Unt,Z8,WK);wAn(422,22,{3:1,35:1,22:1,422:1},EP);var oht,sht,hht,fht,lht=Ben(F1n,"ConstraintCalculationStrategy",422,Unt,GY,VK);wAn(314,22,{3:1,35:1,22:1,314:1,246:1,234:1},TP),MWn.Kf=function(){return sCn(this)},MWn.Xf=function(){return sCn(this)};var bht,wht,dht,ght,pht=Ben(F1n,"CrossingMinimizationStrategy",314,Unt,T1,QK);wAn(337,22,{3:1,35:1,22:1,337:1},MP);var vht,mht,yht,kht,jht,Eht,Tht=Ben(F1n,"CuttingStrategy",337,Unt,M1,ZK);wAn(335,22,{3:1,35:1,22:1,335:1,246:1,234:1},SP),MWn.Kf=function(){return RAn(this)},MWn.Xf=function(){return RAn(this)};var Mht,Sht,Pht,Iht=Ben(F1n,"CycleBreakingStrategy",335,Unt,L5,nF);wAn(419,22,{3:1,35:1,22:1,419:1},PP);var Cht,Oht,Aht,$ht,Lht=Ben(F1n,"DirectionCongruency",419,Unt,qY,tF);wAn(450,22,{3:1,35:1,22:1,450:1},IP);var Nht,xht,Dht,Rht,_ht,Kht,Fht,Bht=Ben(F1n,"EdgeConstraint",450,Unt,S1,eF);wAn(276,22,{3:1,35:1,22:1,276:1},CP);var Hht,qht,Ght,zht=Ben(F1n,"EdgeLabelSideSelection",276,Unt,i9,iF);wAn(479,22,{3:1,35:1,22:1,479:1},OP);var Uht,Xht,Wht,Vht,Qht,Yht,Jht,Zht=Ben(F1n,"EdgeStraighteningStrategy",479,Unt,HY,rF);wAn(274,22,{3:1,35:1,22:1,274:1},AP);var nft,tft,eft,ift,rft,cft,aft,uft=Ben(F1n,"FixedAlignment",274,Unt,t9,cF);wAn(275,22,{3:1,35:1,22:1,275:1},$P);var oft,sft,hft,fft,lft,bft,wft,dft,gft,pft,vft,mft=Ben(F1n,"GraphCompactionStrategy",275,Unt,n9,aF);wAn(256,22,{3:1,35:1,22:1,256:1},LP);var yft,kft,jft,Eft,Tft=Ben(F1n,"GraphProperties",256,Unt,bcn,uF);wAn(292,22,{3:1,35:1,22:1,292:1},NP);var Mft,Sft,Pft,Ift,Cft=Ben(F1n,"GreedySwitchType",292,Unt,C1,oF);wAn(303,22,{3:1,35:1,22:1,303:1},xP);var Oft,Aft,$ft,Lft=Ben(F1n,"InLayerConstraint",303,Unt,I1,sF);wAn(420,22,{3:1,35:1,22:1,420:1},DP);var Nft,xft,Dft,Rft,_ft,Kft,Fft,Bft,Hft,qft,Gft,zft,Uft,Xft,Wft,Vft,Qft,Yft,Jft,Zft,nlt,tlt,elt,ilt,rlt,clt,alt,ult,olt,slt,hlt,flt,llt,blt,wlt,dlt,glt,plt,vlt,mlt,ylt,klt,jlt,Elt,Tlt,Mlt,Slt,Plt,Ilt,Clt,Olt,Alt,$lt,Llt,Nlt,xlt,Dlt,Rlt,_lt,Klt,Flt,Blt,Hlt,qlt,Glt=Ben(F1n,"InteractiveReferencePoint",420,Unt,zY,hF);wAn(163,22,{3:1,35:1,22:1,163:1},BP);var zlt,Ult,Xlt,Wlt,Vlt,Qlt,Ylt,Jlt,Zlt,nbt,tbt,ebt,ibt,rbt,cbt,abt,ubt,obt,sbt,hbt,fbt,lbt,bbt,wbt,dbt,gbt,pbt,vbt,mbt,ybt,kbt,jbt,Ebt,Tbt,Mbt,Sbt,Pbt,Ibt,Cbt,Obt,Abt,$bt,Lbt,Nbt,xbt,Dbt,Rbt,_bt,Kbt,Fbt,Bbt,Hbt,qbt,Gbt,zbt,Ubt,Xbt,Wbt,Vbt,Qbt,Ybt,Jbt,Zbt,nwt,twt,ewt,iwt,rwt,cwt,awt,uwt,owt,swt,hwt,fwt,lwt,bwt,wwt,dwt,gwt,pwt,vwt,mwt,ywt,kwt,jwt,Ewt,Twt,Mwt,Swt,Pwt,Iwt,Cwt,Owt,Awt,$wt,Lwt,Nwt,xwt,Dwt,Rwt,_wt,Kwt,Fwt,Bwt,Hwt,qwt,Gwt,zwt,Uwt,Xwt,Wwt,Vwt,Qwt,Ywt,Jwt,Zwt,ndt,tdt,edt,idt,rdt,cdt,adt,udt,odt,sdt,hdt,fdt,ldt,bdt,wdt,ddt,gdt,pdt,vdt,mdt,ydt,kdt,jdt,Edt,Tdt,Mdt,Sdt,Pdt,Idt,Cdt,Odt,Adt,$dt,Ldt,Ndt,xdt,Ddt,Rdt,_dt,Kdt,Fdt,Bdt,Hdt,qdt,Gdt,zdt,Udt,Xdt,Wdt,Vdt,Qdt,Ydt,Jdt,Zdt,ngt,tgt,egt,igt,rgt,cgt,agt,ugt,ogt,sgt,hgt,fgt,lgt,bgt,wgt,dgt,ggt,pgt,vgt,mgt,ygt,kgt,jgt,Egt,Tgt,Mgt,Sgt,Pgt,Igt,Cgt,Ogt,Agt,$gt,Lgt,Ngt,xgt,Dgt,Rgt,_gt,Kgt,Fgt,Bgt,Hgt,qgt,Ggt,zgt,Ugt,Xgt,Wgt,Vgt,Qgt,Ygt,Jgt,Zgt,npt,tpt,ept,ipt,rpt,cpt,apt,upt,opt,spt,hpt,fpt,lpt,bpt,wpt,dpt,gpt,ppt,vpt,mpt,ypt,kpt,jpt,Ept,Tpt,Mpt,Spt,Ppt,Ipt,Cpt,Opt,Apt,$pt,Lpt,Npt,xpt,Dpt,Rpt,_pt,Kpt,Fpt,Bpt,Hpt,qpt,Gpt,zpt,Upt,Xpt,Wpt,Vpt,Qpt,Ypt,Jpt,Zpt,nvt,tvt,evt,ivt=Ben(F1n,"LayerConstraint",163,Unt,D5,fF);wAn(848,1,QYn,hf),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,U1n),""),"Direction Congruency"),"Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other."),Pbt),(PPn(),gMt)),Lht),nbn((rpn(),hMt))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,X1n),""),"Feedback Edges"),"Whether feedback edges should be highlighted by routing around the nodes."),(hN(),!1)),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,W1n),""),"Interactive Reference Point"),"Determines which point of a node is considered by interactive layout phases."),Qbt),gMt),Glt),nbn(hMt)))),a2(n,W1n,e0n,Jbt),a2(n,W1n,l0n,Ybt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,V1n),""),"Merge Edges"),"Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,Q1n),""),"Merge Hierarchy-Crossing Edges"),"If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port."),!0),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Pj(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,Y1n),""),"Allow Non-Flow Ports To Switch Sides"),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),!1),wMt),ktt),nbn(fMt)),Pun(Gk(Qtt,1),sVn,2,6,["org.eclipse.elk.layered.northOrSouthPort"])))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,J1n),""),"Port Sorting Strategy"),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),xwt),gMt),zvt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,Z1n),""),"Thoroughness"),"How much effort should be spent to produce a nice layout."),iln(7)),vMt),Att),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,n0n),""),"Add Unnecessary Bendpoints"),"Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,t0n),""),"Generate Position and Layer IDs"),"If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,e0n),"cycleBreaking"),"Cycle Breaking Strategy"),"Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right)."),Mbt),gMt),Iht),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,i0n),f2n),"Node Layering Strategy"),"Strategy for node layering."),bwt),gMt),ovt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,r0n),f2n),"Layer Constraint"),"Determines a constraint on the placement of the node regarding the layering."),iwt),gMt),ivt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,c0n),f2n),"Layer Choice Constraint"),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),iln(-1)),vMt),Att),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,a0n),f2n),"Layer ID"),"Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),iln(-1)),vMt),Att),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,u0n),l2n),"Upper Bound On Width [MinWidth Layerer]"),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),iln(4)),vMt),Att),nbn(hMt)))),a2(n,u0n,i0n,awt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,o0n),l2n),"Upper Layer Estimation Scaling Factor [MinWidth Layerer]"),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),iln(2)),vMt),Att),nbn(hMt)))),a2(n,o0n,i0n,owt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,s0n),b2n),"Node Promotion Strategy"),"Reduces number of dummy nodes after layering phase (if possible)."),fwt),gMt),Dvt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,h0n),b2n),"Max Node Promotion Iterations"),"Limits the number of iterations for node promotion."),iln(0)),vMt),Att),nbn(hMt)))),a2(n,h0n,s0n,null),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,f0n),"layering.coffmanGraham"),"Layer Bound"),"The maximum number of nodes allowed per layer."),iln(DWn)),vMt),Att),nbn(hMt)))),a2(n,f0n,i0n,nwt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,l0n),w2n),"Crossing Minimization Strategy"),"Strategy for crossing minimization."),Ebt),gMt),pht),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,b0n),w2n),"Force Node Model Order"),"The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,w0n),w2n),"Hierarchical Sweepiness"),"How likely it is to use cross-hierarchy (1) vs bottom-up (-1)."),.1),dMt),Ptt),nbn(hMt)))),a2(n,w0n,d2n,pbt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,d0n),w2n),"Semi-Interactive Crossing Minimization"),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),!1),wMt),ktt),nbn(hMt)))),a2(n,d0n,l0n,kbt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,g0n),w2n),"Position Choice Constraint"),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),iln(-1)),vMt),Att),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,p0n),w2n),"Position ID"),"Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),iln(-1)),vMt),Att),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,v0n),g2n),"Greedy Switch Activation Threshold"),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),iln(40)),vMt),Att),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,m0n),g2n),"Greedy Switch Crossing Minimization"),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),wbt),gMt),Cft),nbn(hMt)))),a2(n,m0n,l0n,dbt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,y0n),"crossingMinimization.greedySwitchHierarchical"),"Greedy Switch Crossing Minimization (hierarchical)"),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),hbt),gMt),Cft),nbn(hMt)))),a2(n,y0n,l0n,fbt),a2(n,y0n,d2n,lbt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,k0n),p2n),"Node Placement Strategy"),"Strategy for node placement."),Lwt),gMt),Avt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,j0n),p2n),"Favor Straight Edges Over Balancing"),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),wMt),ktt),nbn(hMt)))),a2(n,j0n,k0n,Ewt),a2(n,j0n,k0n,Twt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,E0n),v2n),"BK Edge Straightening"),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),pwt),gMt),Zht),nbn(hMt)))),a2(n,E0n,k0n,vwt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,T0n),v2n),"BK Fixed Alignment"),"Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four."),ywt),gMt),uft),nbn(hMt)))),a2(n,T0n,k0n,kwt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,M0n),"nodePlacement.linearSegments"),"Linear Segments Deflection Dampening"),"Dampens the movement of nodes to keep the diagram from getting too large."),.3),dMt),Ptt),nbn(hMt)))),a2(n,M0n,k0n,Swt),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,S0n),"nodePlacement.networkSimplex"),"Node Flexibility"),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),gMt),kvt),nbn(sMt)))),a2(n,S0n,k0n,Awt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,P0n),"nodePlacement.networkSimplex.nodeFlexibility"),"Node Flexibility Default"),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),Cwt),gMt),kvt),nbn(hMt)))),a2(n,P0n,k0n,Owt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,I0n),m2n),"Self-Loop Distribution"),"Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE."),xbt),gMt),nmt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,C0n),m2n),"Self-Loop Ordering"),"Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE."),Rbt),gMt),cmt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,O0n),"edgeRouting.splines"),"Spline Routing Mode"),"Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes."),Kbt),gMt),hmt),nbn(hMt)))),a2(n,O0n,y2n,Fbt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,A0n),"edgeRouting.splines.sloppy"),"Sloppy Spline Layer Spacing Factor"),"Spacing factor for routing area between layers when using sloppy spline routing."),.2),dMt),Ptt),nbn(hMt)))),a2(n,A0n,y2n,Hbt),a2(n,A0n,O0n,qbt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,$0n),"edgeRouting.polyline"),"Sloped Edge Zone Width"),"Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer."),2),dMt),Ptt),nbn(hMt)))),a2(n,$0n,y2n,Lbt),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,L0n),k2n),"Spacing Base Value"),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,N0n),k2n),"Edge Node Between Layers Spacing"),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,x0n),k2n),"Edge Edge Between Layer Spacing"),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,D0n),k2n),"Node Node Between Layers Spacing"),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,R0n),j2n),"Direction Priority"),"Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase."),iln(0)),vMt),Att),nbn(uMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,_0n),j2n),"Shortness Priority"),"Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase."),iln(0)),vMt),Att),nbn(uMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,K0n),j2n),"Straightness Priority"),"Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement."),iln(0)),vMt),Att),nbn(uMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,F0n),E2n),DJn),"Tries to further compact components (disconnected sub-graphs)."),!1),wMt),ktt),nbn(hMt)))),a2(n,F0n,kZn,!0),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,B0n),T2n),"Post Compaction Strategy"),M2n),Ylt),gMt),mft),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,H0n),T2n),"Post Compaction Constraint Calculation"),M2n),Vlt),gMt),lht),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,q0n),S2n),"High Degree Node Treatment"),"Makes room around high degree nodes to place leafs and trees."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,G0n),S2n),"High Degree Node Threshold"),"Whether a node is considered to have a high degree."),iln(16)),vMt),Att),nbn(hMt)))),a2(n,G0n,q0n,!0),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,z0n),S2n),"High Degree Node Maximum Tree Height"),"Maximum height of a subtree connected to a high degree node to be moved to separate layers."),iln(5)),vMt),Att),nbn(hMt)))),a2(n,z0n,q0n,!0),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,U0n),P2n),"Graph Wrapping Strategy"),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),bdt),gMt),Smt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,X0n),P2n),"Additional Wrapped Edges Spacing"),"To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing."),10),dMt),Ptt),nbn(hMt)))),a2(n,X0n,U0n,Uwt),a2(n,X0n,U0n,Xwt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,W0n),P2n),"Correction Factor for Wrapping"),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),dMt),Ptt),nbn(hMt)))),a2(n,W0n,U0n,Vwt),a2(n,W0n,U0n,Qwt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,V0n),I2n),"Cutting Strategy"),"The strategy by which the layer indexes are determined at which the layering crumbles into chunks."),idt),gMt),Tht),nbn(hMt)))),a2(n,V0n,U0n,rdt),a2(n,V0n,U0n,cdt),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,Q0n),I2n),"Manually Specified Cuts"),"Allows the user to specify her own cuts for a certain graph."),mMt),Rnt),nbn(hMt)))),a2(n,Q0n,V0n,Jwt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,Y0n),"wrapping.cutting.msd"),"MSD Freedom"),"The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts."),ndt),vMt),Att),nbn(hMt)))),a2(n,Y0n,V0n,tdt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,J0n),C2n),"Validification Strategy"),"When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed."),vdt),gMt),dmt),nbn(hMt)))),a2(n,J0n,U0n,mdt),a2(n,J0n,U0n,ydt),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,Z0n),C2n),"Valid Indices for Wrapping"),null),mMt),Rnt),nbn(hMt)))),a2(n,Z0n,U0n,ddt),a2(n,Z0n,U0n,gdt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,n2n),O2n),"Improve Cuts"),"For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought."),!0),wMt),ktt),nbn(hMt)))),a2(n,n2n,U0n,sdt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,t2n),O2n),"Distance Penalty When Improving Cuts"),null),2),dMt),Ptt),nbn(hMt)))),a2(n,t2n,U0n,udt),a2(n,t2n,n2n,!0),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,e2n),O2n),"Improve Wrapped Edges"),"The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges."),!0),wMt),ktt),nbn(hMt)))),a2(n,e2n,U0n,fdt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,i2n),A2n),"Edge Label Side Selection"),"Method to decide on edge label sides."),Abt),gMt),zht),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,r2n),A2n),"Edge Center Label Placement Strategy"),"Determines in which layer center labels of long edges should be placed."),Cbt),gMt),uht),EG(hMt,Pun(Gk(jMt,1),$Vn,175,0,[oMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,c2n),$2n),"Consider Model Order"),"Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting."),abt),gMt),Fvt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,a2n),$2n),"No Model Order"),"Set on a node to not set a model order for this node even though it is a real node."),!1),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,u2n),$2n),"Consider Model Order for Components"),"If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected."),Zlt),gMt),mut),nbn(hMt)))),a2(n,u2n,kZn,null),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,o2n),$2n),"Long Edge Ordering Strategy"),"Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout."),ibt),gMt),wvt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,s2n),$2n),"Crossing Counter Node Order Influence"),"Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0)."),0),dMt),Ptt),nbn(hMt)))),a2(n,s2n,c2n,null),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,h2n),$2n),"Crossing Counter Port Order Influence"),"Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0)."),0),dMt),Ptt),nbn(hMt)))),a2(n,h2n,c2n,null),vWn((new bf,n))},vX(F1n,"LayeredMetaDataProvider",848),wAn(986,1,QYn,bf),MWn.Qe=function(n){vWn(n)},vX(F1n,"LayeredOptions",986),wAn(987,1,{},Ic),MWn.$e=function(){return new Uv},MWn._e=function(n){},vX(F1n,"LayeredOptions/LayeredFactory",987),wAn(1372,1,{}),MWn.a=0,vX(y3n,"ElkSpacings/AbstractSpacingsBuilder",1372),wAn(779,1372,{},uwn),vX(F1n,"LayeredSpacings/LayeredSpacingsBuilder",779),wAn(313,22,{3:1,35:1,22:1,313:1,246:1,234:1},RP),MWn.Kf=function(){return rLn(this)},MWn.Xf=function(){return rLn(this)};var rvt,cvt,avt,uvt,ovt=Ben(F1n,"LayeringStrategy",313,Unt,e9,lF);wAn(378,22,{3:1,35:1,22:1,378:1},_P);var svt,hvt,fvt,lvt,bvt,wvt=Ben(F1n,"LongEdgeOrderingStrategy",378,Unt,E1,bF);wAn(197,22,{3:1,35:1,22:1,197:1},KP);var dvt,gvt,pvt,vvt,mvt,yvt,kvt=Ben(F1n,"NodeFlexibility",197,Unt,k3,wF);wAn(315,22,{3:1,35:1,22:1,315:1,246:1,234:1},FP),MWn.Kf=function(){return DAn(this)},MWn.Xf=function(){return DAn(this)};var jvt,Evt,Tvt,Mvt,Svt,Pvt,Ivt,Cvt,Ovt,Avt=Ben(F1n,"NodePlacementStrategy",315,Unt,$5,yF);wAn(260,22,{3:1,35:1,22:1,260:1},HP);var $vt,Lvt,Nvt,xvt,Dvt=Ben(F1n,"NodePromotionStrategy",260,Unt,Btn,gF);wAn(339,22,{3:1,35:1,22:1,339:1},qP);var Rvt,_vt,Kvt,Fvt=Ben(F1n,"OrderingStrategy",339,Unt,A1,pF);wAn(421,22,{3:1,35:1,22:1,421:1},GP);var Bvt,Hvt,qvt,Gvt,zvt=Ben(F1n,"PortSortingStrategy",421,Unt,UY,vF);wAn(452,22,{3:1,35:1,22:1,452:1},zP);var Uvt,Xvt,Wvt,Vvt,Qvt=Ben(F1n,"PortType",452,Unt,O1,dF);wAn(375,22,{3:1,35:1,22:1,375:1},UP);var Yvt,Jvt,Zvt,nmt=Ben(F1n,"SelfLoopDistributionStrategy",375,Unt,$1,mF);wAn(376,22,{3:1,35:1,22:1,376:1},XP);var tmt,emt,imt,rmt,cmt=Ben(F1n,"SelfLoopOrderingStrategy",376,Unt,BY,kF);wAn(304,1,{304:1},sGn),vX(F1n,"Spacings",304),wAn(336,22,{3:1,35:1,22:1,336:1},WP);var amt,umt,omt,smt,hmt=Ben(F1n,"SplineRoutingMode",336,Unt,N1,jF);wAn(338,22,{3:1,35:1,22:1,338:1},VP);var fmt,lmt,bmt,wmt,dmt=Ben(F1n,"ValidifyStrategy",338,Unt,x1,EF);wAn(377,22,{3:1,35:1,22:1,377:1},QP);var gmt,pmt,vmt,mmt,ymt,kmt,jmt,Emt,Tmt,Mmt,Smt=Ben(F1n,"WrappingStrategy",377,Unt,L1,TF);wAn(1383,1,E3n,wf),MWn.Yf=function(n){return BB(n,37),pmt},MWn.pf=function(n,t){JHn(this,BB(n,37),t)},vX(T3n,"DepthFirstCycleBreaker",1383),wAn(782,1,E3n,_G),MWn.Yf=function(n){return BB(n,37),vmt},MWn.pf=function(n,t){UXn(this,BB(n,37),t)},MWn.Zf=function(n){return BB(xq(n,pvn(this.d,n.c.length)),10)},vX(T3n,"GreedyCycleBreaker",782),wAn(1386,782,E3n,TC),MWn.Zf=function(n){var t,e,i,r;for(r=null,t=DWn,i=new Wb(n);i.a<i.c.c.length;)Lx(e=BB(n0(i),10),(hWn(),wlt))&&BB(mMn(e,wlt),19).a<t&&(t=BB(mMn(e,wlt),19).a,r=e);return r||BB(xq(n,pvn(this.d,n.c.length)),10)},vX(T3n,"GreedyModelOrderCycleBreaker",1386),wAn(1384,1,E3n,rf),MWn.Yf=function(n){return BB(n,37),mmt},MWn.pf=function(n,t){Cqn(this,BB(n,37),t)},vX(T3n,"InteractiveCycleBreaker",1384),wAn(1385,1,E3n,cf),MWn.Yf=function(n){return BB(n,37),ymt},MWn.pf=function(n,t){Lqn(this,BB(n,37),t)},MWn.a=0,MWn.b=0,vX(T3n,"ModelOrderCycleBreaker",1385),wAn(1389,1,E3n,$M),MWn.Yf=function(n){return BB(n,37),kmt},MWn.pf=function(n,t){JXn(this,BB(n,37),t)},vX(M3n,"CoffmanGrahamLayerer",1389),wAn(1390,1,MYn,Dd),MWn.ue=function(n,t){return BCn(this.a,BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(M3n,"CoffmanGrahamLayerer/0methodref$compareNodesInTopo$Type",1390),wAn(1391,1,MYn,Rd),MWn.ue=function(n,t){return zG(this.a,BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(M3n,"CoffmanGrahamLayerer/lambda$1$Type",1391),wAn(1392,1,E3n,Cc),MWn.Yf=function(n){return BB(n,37),dq(dq(dq(new B2,(yMn(),Rat),(lWn(),kot)),_at,Oot),Kat,Cot)},MWn.pf=function(n,t){EUn(this,BB(n,37),t)},vX(M3n,"InteractiveLayerer",1392),wAn(569,1,{569:1},im),MWn.a=0,MWn.c=0,vX(M3n,"InteractiveLayerer/LayerSpan",569),wAn(1388,1,E3n,ef),MWn.Yf=function(n){return BB(n,37),jmt},MWn.pf=function(n,t){qxn(this,BB(n,37),t)},vX(M3n,"LongestPathLayerer",1388),wAn(1395,1,E3n,sf),MWn.Yf=function(n){return BB(n,37),dq(dq(dq(new B2,(yMn(),Rat),(lWn(),cot)),_at,Oot),Kat,Cot)},MWn.pf=function(n,t){iXn(this,BB(n,37),t)},MWn.a=0,MWn.b=0,MWn.d=0,vX(M3n,"MinWidthLayerer",1395),wAn(1396,1,MYn,_d),MWn.ue=function(n,t){return dan(this,BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(M3n,"MinWidthLayerer/MinOutgoingEdgesComparator",1396),wAn(1387,1,E3n,of),MWn.Yf=function(n){return BB(n,37),Mmt},MWn.pf=function(n,t){mGn(this,BB(n,37),t)},vX(M3n,"NetworkSimplexLayerer",1387),wAn(1393,1,E3n,RR),MWn.Yf=function(n){return BB(n,37),dq(dq(dq(new B2,(yMn(),Rat),(lWn(),cot)),_at,Oot),Kat,Cot)},MWn.pf=function(n,t){$zn(this,BB(n,37),t)},MWn.d=0,MWn.f=0,MWn.g=0,MWn.i=0,MWn.s=0,MWn.t=0,MWn.u=0,vX(M3n,"StretchWidthLayerer",1393),wAn(1394,1,MYn,Oc),MWn.ue=function(n,t){return R6(BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(M3n,"StretchWidthLayerer/1",1394),wAn(402,1,S3n),MWn.Nf=function(n,t,e,i,r,c){},MWn._f=function(n,t,e){return rKn(this,n,t,e)},MWn.Mf=function(){this.g=x8(DNt,P3n,25,this.d,15,1),this.f=x8(DNt,P3n,25,this.d,15,1)},MWn.Of=function(n,t){this.e[n]=x8(ANt,hQn,25,t[n].length,15,1)},MWn.Pf=function(n,t,e){e[n][t].p=t,this.e[n][t]=t},MWn.Qf=function(n,t,e,i){BB(xq(i[n][t].j,e),11).p=this.d++},MWn.b=0,MWn.c=0,MWn.d=0,vX(I3n,"AbstractBarycenterPortDistributor",402),wAn(1633,1,MYn,Kd),MWn.ue=function(n,t){return qgn(this.a,BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(I3n,"AbstractBarycenterPortDistributor/lambda$0$Type",1633),wAn(817,1,N1n,G2),MWn.Nf=function(n,t,e,i,r,c){},MWn.Pf=function(n,t,e){},MWn.Qf=function(n,t,e,i){},MWn.Lf=function(){return!1},MWn.Mf=function(){this.c=this.e.a,this.g=this.f.g},MWn.Of=function(n,t){t[n][0].c.p=n},MWn.Rf=function(){return!1},MWn.ag=function(n,t,e,i){e?sjn(this,n):(Djn(this,n,i),ZGn(this,n,t)),n.c.length>1&&(qy(TD(mMn(vW((l1(0,n.c.length),BB(n.c[0],10))),(HXn(),xdt))))?R$n(n,this.d,BB(this,660)):(SQ(),m$(n,this.d)),Ban(this.e,n))},MWn.Sf=function(n,t,e,i){var r,c,a,u,o,s,h;for(t!=Jq(e,n.length)&&(c=n[t-(e?1:-1)],G6(this.f,c,e?(ain(),qvt):(ain(),Hvt))),r=n[t][0],h=!i||r.k==(uSn(),Mut),s=u6(n[t]),this.ag(s,h,!1,e),a=0,o=new Wb(s);o.a<o.c.c.length;)u=BB(n0(o),10),n[t][a++]=u;return!1},MWn.Tf=function(n,t){var e,i,r,c,a;for(c=u6(n[a=Jq(t,n.length)]),this.ag(c,!1,!0,t),e=0,r=new Wb(c);r.a<r.c.c.length;)i=BB(n0(r),10),n[a][e++]=i;return!1},vX(I3n,"BarycenterHeuristic",817),wAn(658,1,{658:1},Bd),MWn.Ib=function(){return"BarycenterState [node="+this.c+", summedWeight="+this.d+", degree="+this.b+", barycenter="+this.a+", visited="+this.e+"]"},MWn.b=0,MWn.d=0,MWn.e=!1;var Pmt=vX(I3n,"BarycenterHeuristic/BarycenterState",658);wAn(1802,1,MYn,Fd),MWn.ue=function(n,t){return MEn(this.a,BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(I3n,"BarycenterHeuristic/lambda$0$Type",1802),wAn(816,1,N1n,UEn),MWn.Mf=function(){},MWn.Nf=function(n,t,e,i,r,c){},MWn.Qf=function(n,t,e,i){},MWn.Of=function(n,t){this.a[n]=x8(Pmt,{3:1,4:1,5:1,2018:1},658,t[n].length,0,1),this.b[n]=x8(Lmt,{3:1,4:1,5:1,2019:1},233,t[n].length,0,1)},MWn.Pf=function(n,t,e){Dgn(this,e[n][t],!0)},MWn.c=!1,vX(I3n,"ForsterConstraintResolver",816),wAn(233,1,{233:1},DY,uGn),MWn.Ib=function(){var n,t;for((t=new Ik).a+="[",n=0;n<this.d.length;n++)oO(t,$pn(this.d[n])),null!=lL(this.g,this.d[0]).a&&oO(oO((t.a+="<",t),ZC(lL(this.g,this.d[0]).a)),">"),n<this.d.length-1&&(t.a+=FWn);return(t.a+="]",t).a},MWn.a=0,MWn.c=0,MWn.f=0;var Imt,Cmt,Omt,Amt,$mt,Lmt=vX(I3n,"ForsterConstraintResolver/ConstraintGroup",233);wAn(1797,1,lVn,qd),MWn.td=function(n){Dgn(this.a,BB(n,10),!1)},vX(I3n,"ForsterConstraintResolver/lambda$0$Type",1797),wAn(214,1,{214:1,225:1},IGn),MWn.Nf=function(n,t,e,i,r,c){},MWn.Of=function(n,t){},MWn.Mf=function(){this.r=x8(ANt,hQn,25,this.n,15,1)},MWn.Pf=function(n,t,e){var i;(i=e[n][t].e)&&WB(this.b,i)},MWn.Qf=function(n,t,e,i){++this.n},MWn.Ib=function(){return izn(this.e,new Rv)},MWn.g=!1,MWn.i=!1,MWn.n=0,MWn.s=!1,vX(I3n,"GraphInfoHolder",214),wAn(1832,1,N1n,Pc),MWn.Nf=function(n,t,e,i,r,c){},MWn.Of=function(n,t){},MWn.Qf=function(n,t,e,i){},MWn._f=function(n,t,e){return e&&t>0?uZ(this.a,n[t-1],n[t]):!e&&t<n.length-1?uZ(this.a,n[t],n[t+1]):yrn(this.a,n[t],e?(kUn(),ICt):(kUn(),oCt)),bLn(this,n,t,e)},MWn.Mf=function(){this.d=x8(ANt,hQn,25,this.c,15,1),this.a=new Q_(this.d)},MWn.Pf=function(n,t,e){var i;i=e[n][t],this.c+=i.j.c.length},MWn.c=0,vX(I3n,"GreedyPortDistributor",1832),wAn(1401,1,E3n,df),MWn.Yf=function(n){return Xhn(BB(n,37))},MWn.pf=function(n,t){XGn(BB(n,37),t)},vX(I3n,"InteractiveCrossingMinimizer",1401),wAn(1402,1,MYn,Gd),MWn.ue=function(n,t){return Hjn(this,BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(I3n,"InteractiveCrossingMinimizer/1",1402),wAn(507,1,{507:1,123:1,51:1},Ny),MWn.Yf=function(n){var t;return BB(n,37),dq(t=kA(Cmt),(yMn(),Kat),(lWn(),Bot)),t},MWn.pf=function(n,t){PKn(this,BB(n,37),t)},MWn.e=0,vX(I3n,"LayerSweepCrossingMinimizer",507),wAn(1398,1,lVn,zd),MWn.td=function(n){wBn(this.a,BB(n,214))},vX(I3n,"LayerSweepCrossingMinimizer/0methodref$compareDifferentRandomizedLayouts$Type",1398),wAn(1399,1,lVn,Ud),MWn.td=function(n){Ohn(this.a,BB(n,214))},vX(I3n,"LayerSweepCrossingMinimizer/1methodref$minimizeCrossingsNoCounter$Type",1399),wAn(1400,1,lVn,Xd),MWn.td=function(n){pFn(this.a,BB(n,214))},vX(I3n,"LayerSweepCrossingMinimizer/2methodref$minimizeCrossingsWithCounter$Type",1400),wAn(454,22,{3:1,35:1,22:1,454:1},YP);var Nmt,xmt=Ben(I3n,"LayerSweepCrossingMinimizer/CrossMinType",454,Unt,D1,MF);wAn(1397,1,DVn,Ac),MWn.Mb=function(n){return Kcn(),0==BB(n,29).a.c.length},vX(I3n,"LayerSweepCrossingMinimizer/lambda$0$Type",1397),wAn(1799,1,N1n,aZ),MWn.Mf=function(){},MWn.Nf=function(n,t,e,i,r,c){},MWn.Qf=function(n,t,e,i){},MWn.Of=function(n,t){t[n][0].c.p=n,this.b[n]=x8(Kmt,{3:1,4:1,5:1,1944:1},659,t[n].length,0,1)},MWn.Pf=function(n,t,e){e[n][t].p=t,$X(this.b[n],t,new $c)},vX(I3n,"LayerSweepTypeDecider",1799),wAn(659,1,{659:1},$c),MWn.Ib=function(){return"NodeInfo [connectedEdges="+this.a+", hierarchicalInfluence="+this.b+", randomInfluence="+this.c+"]"},MWn.a=0,MWn.b=0,MWn.c=0;var Dmt,Rmt,_mt,Kmt=vX(I3n,"LayerSweepTypeDecider/NodeInfo",659);wAn(1800,1,qYn,Lc),MWn.Lb=function(n){return zN(new m6(BB(n,11).b))},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return zN(new m6(BB(n,11).b))},vX(I3n,"LayerSweepTypeDecider/lambda$0$Type",1800),wAn(1801,1,qYn,Nc),MWn.Lb=function(n){return zN(new m6(BB(n,11).b))},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return zN(new m6(BB(n,11).b))},vX(I3n,"LayerSweepTypeDecider/lambda$1$Type",1801),wAn(1833,402,S3n,Dj),MWn.$f=function(n,t,e){var i,r,c,a,u,o,s,h,f;switch(s=this.g,e.g){case 1:for(i=0,r=0,o=new Wb(n.j);o.a<o.c.c.length;)0!=(a=BB(n0(o),11)).e.c.length&&(++i,a.j==(kUn(),sCt)&&++r);for(c=t+r,f=t+i,u=xwn(n,(ain(),Hvt)).Kc();u.Ob();)(a=BB(u.Pb(),11)).j==(kUn(),sCt)?(s[a.p]=c,--c):(s[a.p]=f,--f);return i;case 2:for(h=0,u=xwn(n,(ain(),qvt)).Kc();u.Ob();)++h,s[(a=BB(u.Pb(),11)).p]=t+h;return h;default:throw Hp(new wv)}},vX(I3n,"LayerTotalPortDistributor",1833),wAn(660,817,{660:1,225:1},prn),MWn.ag=function(n,t,e,i){e?sjn(this,n):(Djn(this,n,i),ZGn(this,n,t)),n.c.length>1&&(qy(TD(mMn(vW((l1(0,n.c.length),BB(n.c[0],10))),(HXn(),xdt))))?R$n(n,this.d,this):(SQ(),m$(n,this.d)),qy(TD(mMn(vW((l1(0,n.c.length),BB(n.c[0],10))),xdt)))||Ban(this.e,n))},vX(I3n,"ModelOrderBarycenterHeuristic",660),wAn(1803,1,MYn,Wd),MWn.ue=function(n,t){return _Sn(this.a,BB(n,10),BB(t,10))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(I3n,"ModelOrderBarycenterHeuristic/lambda$0$Type",1803),wAn(1403,1,E3n,jf),MWn.Yf=function(n){var t;return BB(n,37),dq(t=kA(Dmt),(yMn(),Kat),(lWn(),Bot)),t},MWn.pf=function(n,t){mY((BB(n,37),t))},vX(I3n,"NoCrossingMinimizer",1403),wAn(796,402,S3n,Rj),MWn.$f=function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;switch(f=this.g,e.g){case 1:for(r=0,c=0,h=new Wb(n.j);h.a<h.c.c.length;)0!=(o=BB(n0(h),11)).e.c.length&&(++r,o.j==(kUn(),sCt)&&++c);for(a=t+c*(i=1/(r+1)),b=t+1-i,s=xwn(n,(ain(),Hvt)).Kc();s.Ob();)(o=BB(s.Pb(),11)).j==(kUn(),sCt)?(f[o.p]=a,a-=i):(f[o.p]=b,b-=i);break;case 2:for(u=0,h=new Wb(n.j);h.a<h.c.c.length;)0==(o=BB(n0(h),11)).g.c.length||++u;for(l=t+(i=1/(u+1)),s=xwn(n,(ain(),qvt)).Kc();s.Ob();)f[(o=BB(s.Pb(),11)).p]=l,l+=i;break;default:throw Hp(new Ky("Port type is undefined"))}return 1},vX(I3n,"NodeRelativePortDistributor",796),wAn(807,1,{},Vz,HMn),vX(I3n,"SweepCopy",807),wAn(1798,1,N1n,wdn),MWn.Of=function(n,t){},MWn.Mf=function(){var n;n=x8(ANt,hQn,25,this.f,15,1),this.d=new eg(n),this.a=new Q_(n)},MWn.Nf=function(n,t,e,i,r,c){var a;a=BB(xq(c[n][t].j,e),11),r.c==a&&r.c.i.c==r.d.i.c&&++this.e[n]},MWn.Pf=function(n,t,e){var i;i=e[n][t],this.c[n]=this.c[n]|i.k==(uSn(),Cut)},MWn.Qf=function(n,t,e,i){var r;(r=BB(xq(i[n][t].j,e),11)).p=this.f++,r.g.c.length+r.e.c.length>1&&(r.j==(kUn(),oCt)?this.b[n]=!0:r.j==ICt&&n>0&&(this.b[n-1]=!0))},MWn.f=0,vX(L1n,"AllCrossingsCounter",1798),wAn(587,1,{},mrn),MWn.b=0,MWn.d=0,vX(L1n,"BinaryIndexedTree",587),wAn(524,1,{},Q_),vX(L1n,"CrossingsCounter",524),wAn(1906,1,MYn,Vd),MWn.ue=function(n,t){return Xq(this.a,BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(L1n,"CrossingsCounter/lambda$0$Type",1906),wAn(1907,1,MYn,Qd),MWn.ue=function(n,t){return Wq(this.a,BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(L1n,"CrossingsCounter/lambda$1$Type",1907),wAn(1908,1,MYn,Yd),MWn.ue=function(n,t){return Vq(this.a,BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(L1n,"CrossingsCounter/lambda$2$Type",1908),wAn(1909,1,MYn,Jd),MWn.ue=function(n,t){return Qq(this.a,BB(n,11),BB(t,11))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(L1n,"CrossingsCounter/lambda$3$Type",1909),wAn(1910,1,lVn,Zd),MWn.td=function(n){p7(this.a,BB(n,11))},vX(L1n,"CrossingsCounter/lambda$4$Type",1910),wAn(1911,1,DVn,ng),MWn.Mb=function(n){return yC(this.a,BB(n,11))},vX(L1n,"CrossingsCounter/lambda$5$Type",1911),wAn(1912,1,lVn,tg),MWn.td=function(n){mC(this,n)},vX(L1n,"CrossingsCounter/lambda$6$Type",1912),wAn(1913,1,lVn,ZP),MWn.td=function(n){var t;hH(),d3(this.b,(t=this.a,BB(n,11),t))},vX(L1n,"CrossingsCounter/lambda$7$Type",1913),wAn(826,1,qYn,xc),MWn.Lb=function(n){return hH(),Lx(BB(n,11),(hWn(),Elt))},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return hH(),Lx(BB(n,11),(hWn(),Elt))},vX(L1n,"CrossingsCounter/lambda$8$Type",826),wAn(1905,1,{},eg),vX(L1n,"HyperedgeCrossingsCounter",1905),wAn(467,1,{35:1,467:1},DR),MWn.wd=function(n){return vgn(this,BB(n,467))},MWn.b=0,MWn.c=0,MWn.e=0,MWn.f=0;var Fmt=vX(L1n,"HyperedgeCrossingsCounter/Hyperedge",467);wAn(362,1,{35:1,362:1},qV),MWn.wd=function(n){return l$n(this,BB(n,362))},MWn.b=0,MWn.c=0;var Bmt,Hmt,qmt=vX(L1n,"HyperedgeCrossingsCounter/HyperedgeCorner",362);wAn(523,22,{3:1,35:1,22:1,523:1},JP);var Gmt,zmt,Umt,Xmt,Wmt,Vmt=Ben(L1n,"HyperedgeCrossingsCounter/HyperedgeCorner/Type",523,Unt,XY,SF);wAn(1405,1,E3n,lf),MWn.Yf=function(n){return BB(mMn(BB(n,37),(hWn(),Zft)),21).Hc((bDn(),lft))?zmt:null},MWn.pf=function(n,t){ljn(this,BB(n,37),t)},vX(C3n,"InteractiveNodePlacer",1405),wAn(1406,1,E3n,ff),MWn.Yf=function(n){return BB(mMn(BB(n,37),(hWn(),Zft)),21).Hc((bDn(),lft))?Umt:null},MWn.pf=function(n,t){jmn(this,BB(n,37),t)},vX(C3n,"LinearSegmentsNodePlacer",1406),wAn(257,1,{35:1,257:1},rm),MWn.wd=function(n){return uj(this,BB(n,257))},MWn.Fb=function(n){var t;return!!cL(n,257)&&(t=BB(n,257),this.b==t.b)},MWn.Hb=function(){return this.b},MWn.Ib=function(){return"ls"+LMn(this.e)},MWn.a=0,MWn.b=0,MWn.c=-1,MWn.d=-1,MWn.g=0;var Qmt,Ymt=vX(C3n,"LinearSegmentsNodePlacer/LinearSegment",257);wAn(1408,1,E3n,KG),MWn.Yf=function(n){return BB(mMn(BB(n,37),(hWn(),Zft)),21).Hc((bDn(),lft))?Qmt:null},MWn.pf=function(n,t){SXn(this,BB(n,37),t)},MWn.b=0,MWn.g=0,vX(C3n,"NetworkSimplexPlacer",1408),wAn(1427,1,MYn,Dc),MWn.ue=function(n,t){return E$(BB(n,19).a,BB(t,19).a)},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(C3n,"NetworkSimplexPlacer/0methodref$compare$Type",1427),wAn(1429,1,MYn,Rc),MWn.ue=function(n,t){return E$(BB(n,19).a,BB(t,19).a)},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(C3n,"NetworkSimplexPlacer/1methodref$compare$Type",1429),wAn(649,1,{649:1},nI);var Jmt=vX(C3n,"NetworkSimplexPlacer/EdgeRep",649);wAn(401,1,{401:1},GV),MWn.b=!1;var Zmt,nyt,tyt,eyt=vX(C3n,"NetworkSimplexPlacer/NodeRep",401);wAn(508,12,{3:1,4:1,20:1,28:1,52:1,12:1,14:1,15:1,54:1,508:1},um),vX(C3n,"NetworkSimplexPlacer/Path",508),wAn(1409,1,{},_c),MWn.Kb=function(n){return BB(n,17).d.i.k},vX(C3n,"NetworkSimplexPlacer/Path/lambda$0$Type",1409),wAn(1410,1,DVn,Kc),MWn.Mb=function(n){return BB(n,267)==(uSn(),Put)},vX(C3n,"NetworkSimplexPlacer/Path/lambda$1$Type",1410),wAn(1411,1,{},Fc),MWn.Kb=function(n){return BB(n,17).d.i},vX(C3n,"NetworkSimplexPlacer/Path/lambda$2$Type",1411),wAn(1412,1,DVn,ig),MWn.Mb=function(n){return HD(tdn(BB(n,10)))},vX(C3n,"NetworkSimplexPlacer/Path/lambda$3$Type",1412),wAn(1413,1,DVn,Bc),MWn.Mb=function(n){return hq(BB(n,11))},vX(C3n,"NetworkSimplexPlacer/lambda$0$Type",1413),wAn(1414,1,lVn,tI),MWn.td=function(n){D$(this.a,this.b,BB(n,11))},vX(C3n,"NetworkSimplexPlacer/lambda$1$Type",1414),wAn(1423,1,lVn,rg),MWn.td=function(n){WIn(this.a,BB(n,17))},vX(C3n,"NetworkSimplexPlacer/lambda$10$Type",1423),wAn(1424,1,{},Hc),MWn.Kb=function(n){return BZ(),new Rq(null,new w1(BB(n,29).a,16))},vX(C3n,"NetworkSimplexPlacer/lambda$11$Type",1424),wAn(1425,1,lVn,cg),MWn.td=function(n){BDn(this.a,BB(n,10))},vX(C3n,"NetworkSimplexPlacer/lambda$12$Type",1425),wAn(1426,1,{},qc),MWn.Kb=function(n){return BZ(),iln(BB(n,121).e)},vX(C3n,"NetworkSimplexPlacer/lambda$13$Type",1426),wAn(1428,1,{},Gc),MWn.Kb=function(n){return BZ(),iln(BB(n,121).e)},vX(C3n,"NetworkSimplexPlacer/lambda$15$Type",1428),wAn(1430,1,DVn,zc),MWn.Mb=function(n){return BZ(),BB(n,401).c.k==(uSn(),Iut)},vX(C3n,"NetworkSimplexPlacer/lambda$17$Type",1430),wAn(1431,1,DVn,Uc),MWn.Mb=function(n){return BZ(),BB(n,401).c.j.c.length>1},vX(C3n,"NetworkSimplexPlacer/lambda$18$Type",1431),wAn(1432,1,lVn,zV),MWn.td=function(n){cwn(this.c,this.b,this.d,this.a,BB(n,401))},MWn.c=0,MWn.d=0,vX(C3n,"NetworkSimplexPlacer/lambda$19$Type",1432),wAn(1415,1,{},Xc),MWn.Kb=function(n){return BZ(),new Rq(null,new w1(BB(n,29).a,16))},vX(C3n,"NetworkSimplexPlacer/lambda$2$Type",1415),wAn(1433,1,lVn,ag),MWn.td=function(n){N$(this.a,BB(n,11))},MWn.a=0,vX(C3n,"NetworkSimplexPlacer/lambda$20$Type",1433),wAn(1434,1,{},Wc),MWn.Kb=function(n){return BZ(),new Rq(null,new w1(BB(n,29).a,16))},vX(C3n,"NetworkSimplexPlacer/lambda$21$Type",1434),wAn(1435,1,lVn,ug),MWn.td=function(n){dL(this.a,BB(n,10))},vX(C3n,"NetworkSimplexPlacer/lambda$22$Type",1435),wAn(1436,1,DVn,Vc),MWn.Mb=function(n){return HD(n)},vX(C3n,"NetworkSimplexPlacer/lambda$23$Type",1436),wAn(1437,1,{},Qc),MWn.Kb=function(n){return BZ(),new Rq(null,new w1(BB(n,29).a,16))},vX(C3n,"NetworkSimplexPlacer/lambda$24$Type",1437),wAn(1438,1,DVn,og),MWn.Mb=function(n){return EO(this.a,BB(n,10))},vX(C3n,"NetworkSimplexPlacer/lambda$25$Type",1438),wAn(1439,1,lVn,eI),MWn.td=function(n){MPn(this.a,this.b,BB(n,10))},vX(C3n,"NetworkSimplexPlacer/lambda$26$Type",1439),wAn(1440,1,DVn,Yc),MWn.Mb=function(n){return BZ(),!b5(BB(n,17))},vX(C3n,"NetworkSimplexPlacer/lambda$27$Type",1440),wAn(1441,1,DVn,Jc),MWn.Mb=function(n){return BZ(),!b5(BB(n,17))},vX(C3n,"NetworkSimplexPlacer/lambda$28$Type",1441),wAn(1442,1,{},sg),MWn.Ce=function(n,t){return sL(this.a,BB(n,29),BB(t,29))},vX(C3n,"NetworkSimplexPlacer/lambda$29$Type",1442),wAn(1416,1,{},Zc),MWn.Kb=function(n){return BZ(),new Rq(null,new zU(new oz(ZL(lbn(BB(n,10)).a.Kc(),new h))))},vX(C3n,"NetworkSimplexPlacer/lambda$3$Type",1416),wAn(1417,1,DVn,na),MWn.Mb=function(n){return BZ(),t2(BB(n,17))},vX(C3n,"NetworkSimplexPlacer/lambda$4$Type",1417),wAn(1418,1,lVn,hg),MWn.td=function(n){iBn(this.a,BB(n,17))},vX(C3n,"NetworkSimplexPlacer/lambda$5$Type",1418),wAn(1419,1,{},ta),MWn.Kb=function(n){return BZ(),new Rq(null,new w1(BB(n,29).a,16))},vX(C3n,"NetworkSimplexPlacer/lambda$6$Type",1419),wAn(1420,1,DVn,ea),MWn.Mb=function(n){return BZ(),BB(n,10).k==(uSn(),Iut)},vX(C3n,"NetworkSimplexPlacer/lambda$7$Type",1420),wAn(1421,1,{},ia),MWn.Kb=function(n){return BZ(),new Rq(null,new zU(new oz(ZL(hbn(BB(n,10)).a.Kc(),new h))))},vX(C3n,"NetworkSimplexPlacer/lambda$8$Type",1421),wAn(1422,1,DVn,ra),MWn.Mb=function(n){return BZ(),UH(BB(n,17))},vX(C3n,"NetworkSimplexPlacer/lambda$9$Type",1422),wAn(1404,1,E3n,If),MWn.Yf=function(n){return BB(mMn(BB(n,37),(hWn(),Zft)),21).Hc((bDn(),lft))?Zmt:null},MWn.pf=function(n,t){kHn(BB(n,37),t)},vX(C3n,"SimpleNodePlacer",1404),wAn(180,1,{180:1},q_n),MWn.Ib=function(){var n;return n="",this.c==(gJ(),tyt)?n+=aJn:this.c==nyt&&(n+=cJn),this.o==(oZ(),ryt)?n+=pJn:this.o==cyt?n+="UP":n+="BALANCED",n},vX($3n,"BKAlignedLayout",180),wAn(516,22,{3:1,35:1,22:1,516:1},cI);var iyt,ryt,cyt,ayt=Ben($3n,"BKAlignedLayout/HDirection",516,Unt,VY,PF);wAn(515,22,{3:1,35:1,22:1,515:1},rI);var uyt,oyt,syt,hyt,fyt,lyt,byt,wyt,dyt,gyt,pyt,vyt,myt,yyt,kyt,jyt,Eyt,Tyt,Myt,Syt=Ben($3n,"BKAlignedLayout/VDirection",515,Unt,QY,IF);wAn(1634,1,{},iI),vX($3n,"BKAligner",1634),wAn(1637,1,{},Jyn),vX($3n,"BKCompactor",1637),wAn(654,1,{654:1},ca),MWn.a=0,vX($3n,"BKCompactor/ClassEdge",654),wAn(458,1,{458:1},cm),MWn.a=null,MWn.b=0,vX($3n,"BKCompactor/ClassNode",458),wAn(1407,1,E3n,jC),MWn.Yf=function(n){return BB(mMn(BB(n,37),(hWn(),Zft)),21).Hc((bDn(),lft))?oyt:null},MWn.pf=function(n,t){rWn(this,BB(n,37),t)},MWn.d=!1,vX($3n,"BKNodePlacer",1407),wAn(1635,1,{},aa),MWn.d=0,vX($3n,"NeighborhoodInformation",1635),wAn(1636,1,MYn,fg),MWn.ue=function(n,t){return Mtn(this,BB(n,46),BB(t,46))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX($3n,"NeighborhoodInformation/NeighborComparator",1636),wAn(808,1,{}),vX($3n,"ThresholdStrategy",808),wAn(1763,808,{},dm),MWn.bg=function(n,t,e){return this.a.o==(oZ(),cyt)?RQn:_Qn},MWn.cg=function(){},vX($3n,"ThresholdStrategy/NullThresholdStrategy",1763),wAn(579,1,{579:1},aI),MWn.c=!1,MWn.d=!1,vX($3n,"ThresholdStrategy/Postprocessable",579),wAn(1764,808,{},gm),MWn.bg=function(n,t,e){var i,r,c;return r=t==e,i=this.a.a[e.p]==t,r||i?(c=n,this.a.c,gJ(),r&&(c=THn(this,t,!0)),!isNaN(c)&&!isFinite(c)&&i&&(c=THn(this,e,!1)),c):n},MWn.cg=function(){for(var n,t,e;0!=this.d.b;)(t=cFn(this,e=BB(PJ(this.d),579))).a&&(n=t.a,(qy(this.a.f[this.a.g[e.b.p].p])||b5(n)||n.c.i.c!=n.d.i.c)&&(b$n(this,e)||rA(this.e,e)));for(;0!=this.e.a.c.length;)b$n(this,BB(thn(this.e),579))},vX($3n,"ThresholdStrategy/SimpleThresholdStrategy",1764),wAn(635,1,{635:1,246:1,234:1},ua),MWn.Kf=function(){return Tan(this)},MWn.Xf=function(){return Tan(this)},vX(L3n,"EdgeRouterFactory",635),wAn(1458,1,E3n,Cf),MWn.Yf=function(n){return Uxn(BB(n,37))},MWn.pf=function(n,t){DHn(BB(n,37),t)},vX(L3n,"OrthogonalEdgeRouter",1458),wAn(1451,1,E3n,EC),MWn.Yf=function(n){return Ejn(BB(n,37))},MWn.pf=function(n,t){OUn(this,BB(n,37),t)},vX(L3n,"PolylineEdgeRouter",1451),wAn(1452,1,qYn,oa),MWn.Lb=function(n){return Qan(BB(n,10))},MWn.Fb=function(n){return this===n},MWn.Mb=function(n){return Qan(BB(n,10))},vX(L3n,"PolylineEdgeRouter/1",1452),wAn(1809,1,DVn,sa),MWn.Mb=function(n){return BB(n,129).c==(O6(),Tyt)},vX(N3n,"HyperEdgeCycleDetector/lambda$0$Type",1809),wAn(1810,1,{},ha),MWn.Ge=function(n){return BB(n,129).d},vX(N3n,"HyperEdgeCycleDetector/lambda$1$Type",1810),wAn(1811,1,DVn,fa),MWn.Mb=function(n){return BB(n,129).c==(O6(),Tyt)},vX(N3n,"HyperEdgeCycleDetector/lambda$2$Type",1811),wAn(1812,1,{},la),MWn.Ge=function(n){return BB(n,129).d},vX(N3n,"HyperEdgeCycleDetector/lambda$3$Type",1812),wAn(1813,1,{},ba),MWn.Ge=function(n){return BB(n,129).d},vX(N3n,"HyperEdgeCycleDetector/lambda$4$Type",1813),wAn(1814,1,{},wa),MWn.Ge=function(n){return BB(n,129).d},vX(N3n,"HyperEdgeCycleDetector/lambda$5$Type",1814),wAn(112,1,{35:1,112:1},Fan),MWn.wd=function(n){return oj(this,BB(n,112))},MWn.Fb=function(n){var t;return!!cL(n,112)&&(t=BB(n,112),this.g==t.g)},MWn.Hb=function(){return this.g},MWn.Ib=function(){var n,t,e,i;for(n=new lN("{"),i=new Wb(this.n);i.a<i.c.c.length;)null==(t=gyn((e=BB(n0(i),11)).i))&&(t="n"+A_(e.i)),n.a+=""+t,i.a<i.c.c.length&&(n.a+=",");return n.a+="}",n.a},MWn.a=0,MWn.b=0,MWn.c=NaN,MWn.d=0,MWn.g=0,MWn.i=0,MWn.o=0,MWn.s=NaN,vX(N3n,"HyperEdgeSegment",112),wAn(129,1,{129:1},zZ),MWn.Ib=function(){return this.a+"->"+this.b+" ("+wx(this.c)+")"},MWn.d=0,vX(N3n,"HyperEdgeSegmentDependency",129),wAn(520,22,{3:1,35:1,22:1,520:1},uI);var Pyt,Iyt,Cyt,Oyt,Ayt,$yt,Lyt,Nyt,xyt=Ben(N3n,"HyperEdgeSegmentDependency/DependencyType",520,Unt,WY,CF);wAn(1815,1,{},lg),vX(N3n,"HyperEdgeSegmentSplitter",1815),wAn(1816,1,{},zj),MWn.a=0,MWn.b=0,vX(N3n,"HyperEdgeSegmentSplitter/AreaRating",1816),wAn(329,1,{329:1},kB),MWn.a=0,MWn.b=0,MWn.c=0,vX(N3n,"HyperEdgeSegmentSplitter/FreeArea",329),wAn(1817,1,MYn,ja),MWn.ue=function(n,t){return O_(BB(n,112),BB(t,112))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(N3n,"HyperEdgeSegmentSplitter/lambda$0$Type",1817),wAn(1818,1,lVn,XV),MWn.td=function(n){n4(this.a,this.d,this.c,this.b,BB(n,112))},MWn.b=0,vX(N3n,"HyperEdgeSegmentSplitter/lambda$1$Type",1818),wAn(1819,1,{},Ea),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,112).e,16))},vX(N3n,"HyperEdgeSegmentSplitter/lambda$2$Type",1819),wAn(1820,1,{},Ta),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,112).j,16))},vX(N3n,"HyperEdgeSegmentSplitter/lambda$3$Type",1820),wAn(1821,1,{},Ma),MWn.Fe=function(n){return Gy(MD(n))},vX(N3n,"HyperEdgeSegmentSplitter/lambda$4$Type",1821),wAn(655,1,{},fX),MWn.a=0,MWn.b=0,MWn.c=0,vX(N3n,"OrthogonalRoutingGenerator",655),wAn(1638,1,{},Sa),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,112).e,16))},vX(N3n,"OrthogonalRoutingGenerator/lambda$0$Type",1638),wAn(1639,1,{},Pa),MWn.Kb=function(n){return new Rq(null,new w1(BB(n,112).j,16))},vX(N3n,"OrthogonalRoutingGenerator/lambda$1$Type",1639),wAn(661,1,{}),vX(x3n,"BaseRoutingDirectionStrategy",661),wAn(1807,661,{},pm),MWn.dg=function(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*i,h=new Wb(n.n);h.a<h.c.c.length;)for(s=BB(n0(h),11),l=Aon(Pun(Gk(PMt,1),sVn,8,0,[s.i.n,s.n,s.a])).a,o=new Wb(s.g);o.a<o.c.c.length;)b5(u=BB(n0(o),17))||(d=u.d,g=Aon(Pun(Gk(PMt,1),sVn,8,0,[d.i.n,d.n,d.a])).a,e.Math.abs(l-g)>lZn&&(c=n,r=new xI(l,a=f),DH(u.a,r),FKn(this,u,c,r,!1),(b=n.r)&&(r=new xI(w=Gy(MD(Dpn(b.e,0))),a),DH(u.a,r),FKn(this,u,c,r,!1),c=b,r=new xI(w,a=t+b.o*i),DH(u.a,r),FKn(this,u,c,r,!1)),r=new xI(g,a),DH(u.a,r),FKn(this,u,c,r,!1)))},MWn.eg=function(n){return n.i.n.a+n.n.a+n.a.a},MWn.fg=function(){return kUn(),SCt},MWn.gg=function(){return kUn(),sCt},vX(x3n,"NorthToSouthRoutingStrategy",1807),wAn(1808,661,{},vm),MWn.dg=function(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t-n.o*i,h=new Wb(n.n);h.a<h.c.c.length;)for(s=BB(n0(h),11),l=Aon(Pun(Gk(PMt,1),sVn,8,0,[s.i.n,s.n,s.a])).a,o=new Wb(s.g);o.a<o.c.c.length;)b5(u=BB(n0(o),17))||(d=u.d,g=Aon(Pun(Gk(PMt,1),sVn,8,0,[d.i.n,d.n,d.a])).a,e.Math.abs(l-g)>lZn&&(c=n,r=new xI(l,a=f),DH(u.a,r),FKn(this,u,c,r,!1),(b=n.r)&&(r=new xI(w=Gy(MD(Dpn(b.e,0))),a),DH(u.a,r),FKn(this,u,c,r,!1),c=b,r=new xI(w,a=t-b.o*i),DH(u.a,r),FKn(this,u,c,r,!1)),r=new xI(g,a),DH(u.a,r),FKn(this,u,c,r,!1)))},MWn.eg=function(n){return n.i.n.a+n.n.a+n.a.a},MWn.fg=function(){return kUn(),sCt},MWn.gg=function(){return kUn(),SCt},vX(x3n,"SouthToNorthRoutingStrategy",1808),wAn(1806,661,{},mm),MWn.dg=function(n,t,i){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*i,h=new Wb(n.n);h.a<h.c.c.length;)for(s=BB(n0(h),11),l=Aon(Pun(Gk(PMt,1),sVn,8,0,[s.i.n,s.n,s.a])).b,o=new Wb(s.g);o.a<o.c.c.length;)b5(u=BB(n0(o),17))||(d=u.d,g=Aon(Pun(Gk(PMt,1),sVn,8,0,[d.i.n,d.n,d.a])).b,e.Math.abs(l-g)>lZn&&(c=n,r=new xI(a=f,l),DH(u.a,r),FKn(this,u,c,r,!0),(b=n.r)&&(r=new xI(a,w=Gy(MD(Dpn(b.e,0)))),DH(u.a,r),FKn(this,u,c,r,!0),c=b,r=new xI(a=t+b.o*i,w),DH(u.a,r),FKn(this,u,c,r,!0)),r=new xI(a,g),DH(u.a,r),FKn(this,u,c,r,!0)))},MWn.eg=function(n){return n.i.n.b+n.n.b+n.a.b},MWn.fg=function(){return kUn(),oCt},MWn.gg=function(){return kUn(),ICt},vX(x3n,"WestToEastRoutingStrategy",1806),wAn(813,1,{},oBn),MWn.Ib=function(){return LMn(this.a)},MWn.b=0,MWn.c=!1,MWn.d=!1,MWn.f=0,vX(R3n,"NubSpline",813),wAn(407,1,{407:1},Exn,wJ),vX(R3n,"NubSpline/PolarCP",407),wAn(1453,1,E3n,hyn),MWn.Yf=function(n){return rTn(BB(n,37))},MWn.pf=function(n,t){cXn(this,BB(n,37),t)},vX(R3n,"SplineEdgeRouter",1453),wAn(268,1,{268:1},S6),MWn.Ib=function(){return this.a+" ->("+this.c+") "+this.b},MWn.c=0,vX(R3n,"SplineEdgeRouter/Dependency",268),wAn(455,22,{3:1,35:1,22:1,455:1},oI);var Dyt,Ryt,_yt,Kyt,Fyt,Byt=Ben(R3n,"SplineEdgeRouter/SideToProcess",455,Unt,YY,OF);wAn(1454,1,DVn,ya),MWn.Mb=function(n){return gxn(),!BB(n,128).o},vX(R3n,"SplineEdgeRouter/lambda$0$Type",1454),wAn(1455,1,{},ma),MWn.Ge=function(n){return gxn(),BB(n,128).v+1},vX(R3n,"SplineEdgeRouter/lambda$1$Type",1455),wAn(1456,1,lVn,sI),MWn.td=function(n){iq(this.a,this.b,BB(n,46))},vX(R3n,"SplineEdgeRouter/lambda$2$Type",1456),wAn(1457,1,lVn,hI),MWn.td=function(n){rq(this.a,this.b,BB(n,46))},vX(R3n,"SplineEdgeRouter/lambda$3$Type",1457),wAn(128,1,{35:1,128:1},tIn,hqn),MWn.wd=function(n){return sj(this,BB(n,128))},MWn.b=0,MWn.e=!1,MWn.f=0,MWn.g=0,MWn.j=!1,MWn.k=!1,MWn.n=0,MWn.o=!1,MWn.p=!1,MWn.q=!1,MWn.s=0,MWn.u=0,MWn.v=0,MWn.F=0,vX(R3n,"SplineSegment",128),wAn(459,1,{459:1},ka),MWn.a=0,MWn.b=!1,MWn.c=!1,MWn.d=!1,MWn.e=!1,MWn.f=0,vX(R3n,"SplineSegment/EdgeInformation",459),wAn(1234,1,{},da),vX(H3n,iZn,1234),wAn(1235,1,MYn,ga),MWn.ue=function(n,t){return CCn(BB(n,135),BB(t,135))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(H3n,rZn,1235),wAn(1233,1,{},AE),vX(H3n,"MrTree",1233),wAn(393,22,{3:1,35:1,22:1,393:1,246:1,234:1},fI),MWn.Kf=function(){return ACn(this)},MWn.Xf=function(){return ACn(this)};var Hyt,qyt=Ben(H3n,"TreeLayoutPhases",393,Unt,j3,AF);wAn(1130,209,NJn,KR),MWn.Ze=function(n,t){var e,i,r,c,a,u;for(qy(TD(ZAn(n,(IAn(),Ikt))))||jJ(new Tw((GM(),new Dy(n)))),qan(a=new P6,n),hon(a,(qqn(),skt),n),vKn(n,a,u=new xp),WKn(n,a,u),c=a,i=new Wb(r=xKn(this.a,c));i.a<i.c.c.length;)e=BB(n0(i),135),WEn(this.b,e,mcn(t,1/r.c.length));Czn(c=tWn(r))},vX(H3n,"TreeLayoutProvider",1130),wAn(1847,1,pVn,pa),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return SQ(),LT(),bet},vX(H3n,"TreeUtil/1",1847),wAn(1848,1,pVn,va),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return SQ(),LT(),bet},vX(H3n,"TreeUtil/2",1848),wAn(502,134,{3:1,502:1,94:1,134:1}),MWn.g=0,vX(q3n,"TGraphElement",502),wAn(188,502,{3:1,188:1,502:1,94:1,134:1},UQ),MWn.Ib=function(){return this.b&&this.c?g0(this.b)+"->"+g0(this.c):"e_"+nsn(this)},vX(q3n,"TEdge",188),wAn(135,134,{3:1,135:1,94:1,134:1},P6),MWn.Ib=function(){var n,t,e,i,r;for(r=null,i=spn(this.b,0);i.b!=i.d.c;)r+=(null==(e=BB(b3(i),86)).c||0==e.c.length?"n_"+e.g:"n_"+e.c)+"\n";for(t=spn(this.a,0);t.b!=t.d.c;)r+=((n=BB(b3(t),188)).b&&n.c?g0(n.b)+"->"+g0(n.c):"e_"+nsn(n))+"\n";return r};var Gyt=vX(q3n,"TGraph",135);wAn(633,502,{3:1,502:1,633:1,94:1,134:1}),vX(q3n,"TShape",633),wAn(86,633,{3:1,502:1,86:1,633:1,94:1,134:1},csn),MWn.Ib=function(){return g0(this)};var zyt,Uyt,Xyt,Wyt,Vyt,Qyt,Yyt=vX(q3n,"TNode",86);wAn(255,1,pVn,bg),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return new wg(spn(this.a.d,0))},vX(q3n,"TNode/2",255),wAn(358,1,QWn,wg),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return BB(b3(this.a),188).c},MWn.Ob=function(){return EE(this.a)},MWn.Qb=function(){mtn(this.a)},vX(q3n,"TNode/2/1",358),wAn(1840,1,n1n,_R),MWn.pf=function(n,t){xFn(this,BB(n,135),t)},vX(G3n,"FanProcessor",1840),wAn(327,22,{3:1,35:1,22:1,327:1,234:1},lI),MWn.Kf=function(){switch(this.g){case 0:return new Qm;case 1:return new _R;case 2:return new Oa;case 3:return new Ia;case 4:return new $a;case 5:return new La;default:throw Hp(new Ky(M1n+(null!=this.f?this.f:""+this.g)))}};var Jyt,Zyt,nkt,tkt,ekt,ikt,rkt,ckt,akt,ukt,okt,skt,hkt,fkt,lkt,bkt,wkt,dkt,gkt,pkt,vkt,mkt,ykt,kkt,jkt,Ekt,Tkt,Mkt,Skt,Pkt,Ikt,Ckt,Okt,Akt,$kt,Lkt,Nkt,xkt,Dkt,Rkt,_kt,Kkt=Ben(G3n,S1n,327,Unt,r9,$F);wAn(1843,1,n1n,Ia),MWn.pf=function(n,t){u$n(this,BB(n,135),t)},MWn.a=0,vX(G3n,"LevelHeightProcessor",1843),wAn(1844,1,pVn,Ca),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return SQ(),LT(),bet},vX(G3n,"LevelHeightProcessor/1",1844),wAn(1841,1,n1n,Oa),MWn.pf=function(n,t){QPn(this,BB(n,135),t)},MWn.a=0,vX(G3n,"NeighborsProcessor",1841),wAn(1842,1,pVn,Aa),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return SQ(),LT(),bet},vX(G3n,"NeighborsProcessor/1",1842),wAn(1845,1,n1n,$a),MWn.pf=function(n,t){a$n(this,BB(n,135),t)},MWn.a=0,vX(G3n,"NodePositionProcessor",1845),wAn(1839,1,n1n,Qm),MWn.pf=function(n,t){ZHn(this,BB(n,135))},vX(G3n,"RootProcessor",1839),wAn(1846,1,n1n,La),MWn.pf=function(n,t){dln(BB(n,135))},vX(G3n,"Untreeifyer",1846),wAn(851,1,QYn,Pf),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,X3n),""),"Weighting of Nodes"),"Which weighting to use when computing a node order."),kkt),(PPn(),gMt)),qkt),nbn((rpn(),hMt))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,W3n),""),"Search Order"),"Which search order to use when computing a spanning tree."),mkt),gMt),Jkt),nbn(hMt)))),_Gn((new Sf,n))},vX(V3n,"MrTreeMetaDataProvider",851),wAn(994,1,QYn,Sf),MWn.Qe=function(n){_Gn(n)},vX(V3n,"MrTreeOptions",994),wAn(995,1,{},Na),MWn.$e=function(){return new KR},MWn._e=function(n){},vX(V3n,"MrTreeOptions/MrtreeFactory",995),wAn(480,22,{3:1,35:1,22:1,480:1},bI);var Fkt,Bkt,Hkt,qkt=Ben(V3n,"OrderWeighting",480,Unt,ZY,LF);wAn(425,22,{3:1,35:1,22:1,425:1},wI);var Gkt,zkt,Ukt,Xkt,Wkt,Vkt,Qkt,Ykt,Jkt=Ben(V3n,"TreeifyingOrder",425,Unt,JY,xF);wAn(1459,1,E3n,pf),MWn.Yf=function(n){return BB(n,135),zkt},MWn.pf=function(n,t){ycn(this,BB(n,135),t)},vX("org.eclipse.elk.alg.mrtree.p1treeify","DFSTreeifyer",1459),wAn(1460,1,E3n,vf),MWn.Yf=function(n){return BB(n,135),Ukt},MWn.pf=function(n,t){fIn(this,BB(n,135),t)},vX("org.eclipse.elk.alg.mrtree.p2order","NodeOrderer",1460),wAn(1461,1,E3n,gf),MWn.Yf=function(n){return BB(n,135),Xkt},MWn.pf=function(n,t){nRn(this,BB(n,135),t)},MWn.a=0,vX("org.eclipse.elk.alg.mrtree.p3place","NodePlacer",1461),wAn(1462,1,E3n,mf),MWn.Yf=function(n){return BB(n,135),Wkt},MWn.pf=function(n,t){xkn(BB(n,135),t)},vX("org.eclipse.elk.alg.mrtree.p4route","EdgeRouter",1462),wAn(495,22,{3:1,35:1,22:1,495:1,246:1,234:1},dI),MWn.Kf=function(){return bwn(this)},MWn.Xf=function(){return bwn(this)};var Zkt,njt,tjt,ejt,ijt=Ben(J3n,"RadialLayoutPhases",495,Unt,nJ,NF);wAn(1131,209,NJn,OE),MWn.Ze=function(n,t){var e,i,r;if(OTn(t,"Radial layout",EIn(this,n).c.length),qy(TD(ZAn(n,(Uyn(),Ajt))))||jJ(new Tw((GM(),new Dy(n)))),r=uTn(n),Ypn(n,(wD(),Vkt),r),!r)throw Hp(new Ky("The given graph is not a tree!"));for(0==(e=Gy(MD(ZAn(n,Djt))))&&(e=fCn(n)),Ypn(n,Djt,e),i=new Wb(EIn(this,n));i.a<i.c.c.length;)BB(n0(i),51).pf(n,mcn(t,1));HSn(t)},vX(J3n,"RadialLayoutProvider",1131),wAn(549,1,MYn,CE),MWn.ue=function(n,t){return DRn(this.a,this.b,BB(n,33),BB(t,33))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},MWn.a=0,MWn.b=0,vX(J3n,"RadialUtil/lambda$0$Type",549),wAn(1375,1,n1n,Da),MWn.pf=function(n,t){dGn(BB(n,33),t)},vX(t4n,"CalculateGraphSize",1375),wAn(442,22,{3:1,35:1,22:1,442:1,234:1},gI),MWn.Kf=function(){switch(this.g){case 0:return new Ba;case 1:return new xa;case 2:return new Da;default:throw Hp(new Ky(M1n+(null!=this.f?this.f:""+this.g)))}};var rjt,cjt,ajt,ujt=Ben(t4n,S1n,442,Unt,R1,DF);wAn(645,1,{}),MWn.e=1,MWn.g=0,vX(e4n,"AbstractRadiusExtensionCompaction",645),wAn(1772,645,{},gD),MWn.hg=function(n){var t,e,i,r,c,a,u,o,s;for(this.c=BB(ZAn(n,(wD(),Vkt)),33),eb(this,this.c),this.d=Evn(BB(ZAn(n,(Uyn(),Rjt)),293)),(o=BB(ZAn(n,Mjt),19))&&tb(this,o.a),ib(this,(kW(u=MD(ZAn(n,(sWn(),LPt)))),u)),s=wDn(this.c),this.d&&this.d.lg(s),v_n(this,s),a=new Jy(Pun(Gk(UOt,1),i4n,33,0,[this.c])),e=0;e<2;e++)for(t=0;t<s.c.length;t++)r=new Jy(Pun(Gk(UOt,1),i4n,33,0,[(l1(t,s.c.length),BB(s.c[t],33))])),c=t<s.c.length-1?(l1(t+1,s.c.length),BB(s.c[t+1],33)):(l1(0,s.c.length),BB(s.c[0],33)),i=0==t?BB(xq(s,s.c.length-1),33):(l1(t-1,s.c.length),BB(s.c[t-1],33)),ZTn(this,(l1(t,s.c.length),BB(s.c[t],33),a),i,c,r)},vX(e4n,"AnnulusWedgeCompaction",1772),wAn(1374,1,n1n,xa),MWn.pf=function(n,t){bjn(BB(n,33),t)},vX(e4n,"GeneralCompactor",1374),wAn(1771,645,{},Ra),MWn.hg=function(n){var t,e,i,r;e=BB(ZAn(n,(wD(),Vkt)),33),this.f=e,this.b=Evn(BB(ZAn(n,(Uyn(),Rjt)),293)),(r=BB(ZAn(n,Mjt),19))&&tb(this,r.a),ib(this,(kW(i=MD(ZAn(n,(sWn(),LPt)))),i)),t=wDn(e),this.b&&this.b.lg(t),vPn(this,t)},MWn.a=0,vX(e4n,"RadialCompaction",1771),wAn(1779,1,{},_a),MWn.ig=function(n){var t,e,i,r,c,a;for(this.a=n,t=0,i=0,c=new Wb(a=wDn(n));c.a<c.c.c.length;)for(r=BB(n0(c),33),e=++i;e<a.c.length;e++)YFn(this,r,(l1(e,a.c.length),BB(a.c[e],33)))&&(t+=1);return t},vX(r4n,"CrossingMinimizationPosition",1779),wAn(1777,1,{},Ka),MWn.ig=function(n){var t,i,r,c,a,u,o,s,f,l,b,w,d;for(r=0,i=new oz(ZL(dLn(n).a.Kc(),new h));dAn(i);)t=BB(U5(i),79),f=(o=PTn(BB(Wtn((!t.c&&(t.c=new h_(_Ot,t,5,8)),t.c),0),82))).i+o.g/2,l=o.j+o.f/2,c=n.i+n.g/2,a=n.j+n.f/2,(b=new Gj).a=f-c,b.b=l-a,Ukn(u=new xI(b.a,b.b),n.g,n.f),b.a-=u.a,b.b-=u.b,c=f-b.a,a=l-b.b,Ukn(s=new xI(b.a,b.b),o.g,o.f),b.a-=s.a,b.b-=s.b,w=(f=c+b.a)-c,d=(l=a+b.b)-a,r+=e.Math.sqrt(w*w+d*d);return r},vX(r4n,"EdgeLengthOptimization",1777),wAn(1778,1,{},Fa),MWn.ig=function(n){var t,i,r,c,a,u,o,s,f;for(r=0,i=new oz(ZL(dLn(n).a.Kc(),new h));dAn(i);)t=BB(U5(i),79),u=(a=PTn(BB(Wtn((!t.c&&(t.c=new h_(_Ot,t,5,8)),t.c),0),82))).i+a.g/2,o=a.j+a.f/2,c=BB(ZAn(a,(sWn(),gPt)),8),s=u-(n.i+c.a+n.g/2),f=o-(n.j+c.b+n.f),r+=e.Math.sqrt(s*s+f*f);return r},vX(r4n,"EdgeLengthPositionOptimization",1778),wAn(1373,645,n1n,Ba),MWn.pf=function(n,t){fLn(this,BB(n,33),t)},vX("org.eclipse.elk.alg.radial.intermediate.overlaps","RadiusExtensionOverlapRemoval",1373),wAn(426,22,{3:1,35:1,22:1,426:1},pI);var ojt,sjt,hjt,fjt,ljt=Ben(a4n,"AnnulusWedgeCriteria",426,Unt,tJ,RF);wAn(380,22,{3:1,35:1,22:1,380:1},vI);var bjt,wjt,djt,gjt,pjt,vjt,mjt,yjt,kjt,jjt,Ejt,Tjt,Mjt,Sjt,Pjt,Ijt,Cjt,Ojt,Ajt,$jt,Ljt,Njt,xjt,Djt,Rjt,_jt,Kjt,Fjt,Bjt,Hjt,qjt,Gjt=Ben(a4n,FJn,380,Unt,_1,_F);wAn(852,1,QYn,yf),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,u4n),""),"Order ID"),"The id can be used to define an order for nodes of one radius. This can be used to sort them in the layer accordingly."),iln(0)),(PPn(),vMt)),Att),nbn((rpn(),sMt))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,o4n),""),"Radius"),"The radius option can be used to set the initial radius for the radial layouter."),0),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,s4n),""),"Compaction"),"With the compacter option it can be determined how compaction on the graph is done. It can be chosen between none, the radial compaction or the compaction of wedges separately."),gjt),gMt),Gjt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,h4n),""),"Compaction Step Size"),"Determine the size of steps with which the compaction is done. Step size 1 correlates to a compaction of 1 pixel per Iteration."),iln(1)),vMt),Att),nbn(hMt)))),a2(n,h4n,s4n,null),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,f4n),""),"Sorter"),"Sort the nodes per radius according to the sorting algorithm. The strategies are none, by the given order id, or sorting them by polar coordinates."),jjt),gMt),Yjt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,l4n),""),"Annulus Wedge Criteria"),"Determine how the wedge for the node placement is calculated. It can be chosen between wedge determination by the number of leaves or by the maximum sum of diagonals."),Tjt),gMt),ljt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,b4n),""),"Translation Optimization"),"Find the optimal translation of the nodes of the first radii according to this criteria. For example edge crossings can be minimized."),vjt),gMt),Vjt),nbn(hMt)))),tUn((new kf,n))},vX(a4n,"RadialMetaDataProvider",852),wAn(996,1,QYn,kf),MWn.Qe=function(n){tUn(n)},vX(a4n,"RadialOptions",996),wAn(997,1,{},Ha),MWn.$e=function(){return new OE},MWn._e=function(n){},vX(a4n,"RadialOptions/RadialFactory",997),wAn(340,22,{3:1,35:1,22:1,340:1},mI);var zjt,Ujt,Xjt,Wjt,Vjt=Ben(a4n,"RadialTranslationStrategy",340,Unt,E3,KF);wAn(293,22,{3:1,35:1,22:1,293:1},yI);var Qjt,Yjt=Ben(a4n,"SortingStrategy",293,Unt,F1,FF);wAn(1449,1,E3n,qa),MWn.Yf=function(n){return BB(n,33),null},MWn.pf=function(n,t){SLn(this,BB(n,33),t)},MWn.c=0,vX("org.eclipse.elk.alg.radial.p1position","EadesRadial",1449),wAn(1775,1,{},Ga),MWn.jg=function(n){return Upn(n)},vX(d4n,"AnnulusWedgeByLeafs",1775),wAn(1776,1,{},za),MWn.jg=function(n){return VEn(this,n)},vX(d4n,"AnnulusWedgeByNodeSpace",1776),wAn(1450,1,E3n,Ua),MWn.Yf=function(n){return BB(n,33),null},MWn.pf=function(n,t){bEn(this,BB(n,33),t)},vX("org.eclipse.elk.alg.radial.p2routing","StraightLineEdgeRouter",1450),wAn(811,1,{},Jm),MWn.kg=function(n){},MWn.lg=function(n){nv(this,n)},vX(g4n,"IDSorter",811),wAn(1774,1,MYn,Xa),MWn.ue=function(n,t){return Qrn(BB(n,33),BB(t,33))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(g4n,"IDSorter/lambda$0$Type",1774),wAn(1773,1,{},Arn),MWn.kg=function(n){c2(this,n)},MWn.lg=function(n){n.dc()||(this.e||c2(this,nG(BB(n.Xb(0),33))),nv(this.e,n))},vX(g4n,"PolarCoordinateSorter",1773),wAn(1136,209,NJn,Wa),MWn.Ze=function(n,t){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;if(OTn(t,"Rectangle Packing",1),t.n&&t.n&&n&&y0(t,o2(n),(Bsn(),uOt)),i=Gy(MD(ZAn(n,(W$n(),lEt)))),w=BB(ZAn(n,PEt),381),p=qy(TD(ZAn(n,yEt))),y=qy(TD(ZAn(n,SEt))),f=qy(TD(ZAn(n,gEt))),k=BB(ZAn(n,IEt),116),m=Gy(MD(ZAn(n,$Et))),r=qy(TD(ZAn(n,AEt))),l=qy(TD(ZAn(n,pEt))),g=qy(TD(ZAn(n,vEt))),T=Gy(MD(ZAn(n,LEt))),!n.a&&(n.a=new eU(UOt,n,10,11)),Trn(E=n.a),g){for(b=new Np,o=new AL(E);o.e!=o.i.gc();)P8(a=BB(kpn(o),33),dEt)&&(b.c[b.c.length]=a);for(s=new Wb(b);s.a<s.c.c.length;)snn(E,a=BB(n0(s),33));for(SQ(),m$(b,new Va),h=new Wb(b);h.a<h.c.c.length;)a=BB(n0(h),33),j=BB(ZAn(a,dEt),19).a,sln(E,j=e.Math.min(j,E.i),a);for(d=0,u=new AL(E);u.e!=u.i.gc();)Ypn(a=BB(kpn(u),33),wEt,iln(d)),++d}(v=XPn(n)).a-=k.b+k.c,v.b-=k.d+k.a,v.a,T<0||T<v.a?(c=O_n(new jB(i,w,p),E,m,k),t.n&&t.n&&n&&y0(t,o2(n),(Bsn(),uOt))):c=new eq(i,T,0,(YLn(),KEt)),v.a+=k.b+k.c,v.b+=k.d+k.a,y||(Trn(E),c=kzn(new m3(i,f,l,r,m),E,e.Math.max(v.a,c.c),v,t,n,k)),pan(E,k),_Un(n,c.c+(k.b+k.c),c.b+(k.d+k.a),!1,!0),qy(TD(ZAn(n,MEt)))||jJ(new Tw((GM(),new Dy(n)))),t.n&&t.n&&n&&y0(t,o2(n),(Bsn(),uOt)),HSn(t)},vX(y4n,"RectPackingLayoutProvider",1136),wAn(1137,1,MYn,Va),MWn.ue=function(n,t){return wsn(BB(n,33),BB(t,33))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(y4n,"RectPackingLayoutProvider/lambda$0$Type",1137),wAn(1256,1,{},jB),MWn.a=0,MWn.c=!1,vX(k4n,"AreaApproximation",1256);var Jjt,Zjt,nEt,tEt=bq(k4n,"BestCandidateFilter");wAn(638,1,{526:1},Qa),MWn.mg=function(n,t,i){var r,c,a,u,o,s;for(s=new Np,a=RQn,o=new Wb(n);o.a<o.c.c.length;)u=BB(n0(o),220),a=e.Math.min(a,(u.c+(i.b+i.c))*(u.b+(i.d+i.a)));for(c=new Wb(n);c.a<c.c.c.length;)((r=BB(n0(c),220)).c+(i.b+i.c))*(r.b+(i.d+i.a))==a&&(s.c[s.c.length]=r);return s},vX(k4n,"AreaFilter",638),wAn(639,1,{526:1},Ya),MWn.mg=function(n,t,i){var r,c,a,u,o,s;for(o=new Np,s=RQn,u=new Wb(n);u.a<u.c.c.length;)a=BB(n0(u),220),s=e.Math.min(s,e.Math.abs((a.c+(i.b+i.c))/(a.b+(i.d+i.a))-t));for(c=new Wb(n);c.a<c.c.c.length;)r=BB(n0(c),220),e.Math.abs((r.c+(i.b+i.c))/(r.b+(i.d+i.a))-t)==s&&(o.c[o.c.length]=r);return o},vX(k4n,"AspectRatioFilter",639),wAn(637,1,{526:1},Ja),MWn.mg=function(n,t,i){var r,c,a,u,o,s;for(s=new Np,a=_Qn,o=new Wb(n);o.a<o.c.c.length;)u=BB(n0(o),220),a=e.Math.max(a,Yq(u.c+(i.b+i.c),u.b+(i.d+i.a),u.a));for(c=new Wb(n);c.a<c.c.c.length;)Yq((r=BB(n0(c),220)).c+(i.b+i.c),r.b+(i.d+i.a),r.a)==a&&(s.c[s.c.length]=r);return s},vX(k4n,"ScaleMeasureFilter",637),wAn(381,22,{3:1,35:1,22:1,381:1},kI);var eEt,iEt,rEt,cEt,aEt,uEt,oEt,sEt,hEt,fEt,lEt,bEt,wEt,dEt,gEt,pEt,vEt,mEt,yEt,kEt,jEt,EEt,TEt,MEt,SEt,PEt,IEt,CEt,OEt,AEt,$Et,LEt,NEt=Ben(j4n,"OptimizationGoal",381,Unt,K1,BF);wAn(856,1,QYn,Of),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,E4n),""),"Optimization Goal"),"Optimization goal for approximation of the bounding box given by the first iteration. Determines whether layout is sorted by the maximum scaling, aspect ratio, or area. Depending on the strategy the aspect ratio might be nearly ignored."),sEt),(PPn(),gMt)),NEt),nbn((rpn(),sMt))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,T4n),""),"Shift Last Placed."),"When placing a rectangle behind or below the last placed rectangle in the first iteration, it is sometimes possible to shift the rectangle further to the left or right, resulting in less whitespace. True (default) enables the shift and false disables it. Disabling the shift produces a greater approximated area by the first iteration and a layout, when using ONLY the first iteration (default not the case), where it is sometimes impossible to implement a size transformation of rectangles that will fill the bounding box and eliminate empty spaces."),(hN(),!0)),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,M4n),""),"Current position of a node in the order of nodes"),"The rectangles are ordered. Normally according to their definition the the model. This option specifies the current position of a node."),iln(-1)),vMt),Att),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,S4n),""),"Desired index of node"),"The rectangles are ordered. Normally according to their definition the the model. This option allows to specify a desired position that has preference over the original position."),iln(-1)),vMt),Att),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,P4n),""),"Only Area Approximation"),"If enabled only the width approximation step is executed and the nodes are placed accordingly. The nodes are layouted according to the packingStrategy. If set to true not expansion of nodes is taking place."),!1),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,I4n),""),"Compact Rows"),"Enables compaction. Compacts blocks if they do not use the full height of the row. This option allows to have a smaller drawing. If this option is disabled all nodes are placed next to each other in rows."),!0),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,C4n),""),"Fit Aspect Ratio"),"Expands nodes if expandNodes is true to fit the aspect ratio instead of only in their bounds. The option is only useful if the used packingStrategy is ASPECT_RATIO_DRIVEN, otherwise this may result in unreasonable ndoe expansion."),!1),wMt),ktt),nbn(sMt)))),a2(n,C4n,A4n,null),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,O4n),""),"Target Width"),"Option to place the rectangles in the given target width instead of approximating the width using the desired aspect ratio. The padding is not included in this. Meaning a drawing will have width of targetwidth + horizontal padding."),-1),dMt),Ptt),nbn(sMt)))),NXn((new Af,n))},vX(j4n,"RectPackingMetaDataProvider",856),wAn(1004,1,QYn,Af),MWn.Qe=function(n){NXn(n)},vX(j4n,"RectPackingOptions",1004),wAn(1005,1,{},Za),MWn.$e=function(){return new Wa},MWn._e=function(n){},vX(j4n,"RectPackingOptions/RectpackingFactory",1005),wAn(1257,1,{},m3),MWn.a=0,MWn.b=!1,MWn.c=0,MWn.d=0,MWn.e=!1,MWn.f=!1,MWn.g=0,vX("org.eclipse.elk.alg.rectpacking.seconditeration","RowFillingAndCompaction",1257),wAn(187,1,{187:1},asn),MWn.a=0,MWn.c=!1,MWn.d=0,MWn.e=0,MWn.f=0,MWn.g=0,MWn.i=0,MWn.k=!1,MWn.o=RQn,MWn.p=RQn,MWn.r=0,MWn.s=0,MWn.t=0,vX(L4n,"Block",187),wAn(211,1,{211:1},RJ),MWn.a=0,MWn.b=0,MWn.d=0,MWn.e=0,MWn.f=0,vX(L4n,"BlockRow",211),wAn(443,1,{443:1},_J),MWn.b=0,MWn.c=0,MWn.d=0,MWn.e=0,MWn.f=0,vX(L4n,"BlockStack",443),wAn(220,1,{220:1},eq,awn),MWn.a=0,MWn.b=0,MWn.c=0,MWn.d=0,MWn.e=0;var xEt,DEt,REt,_Et,KEt,FEt=vX(L4n,"DrawingData",220);wAn(355,22,{3:1,35:1,22:1,355:1},jI);var BEt,HEt,qEt,GEt,zEt=Ben(L4n,"DrawingDataDescriptor",355,Unt,N5,HF);wAn(200,1,{200:1},x0),MWn.b=0,MWn.c=0,MWn.e=0,MWn.f=0,vX(L4n,"RectRow",200),wAn(756,1,{},Ehn),MWn.j=0,vX(x4n,g1n,756),wAn(1245,1,{},nu),MWn.Je=function(n){return W8(n.a,n.b)},vX(x4n,p1n,1245),wAn(1246,1,{},dg),MWn.Je=function(n){return p6(this.a,n)},vX(x4n,v1n,1246),wAn(1247,1,{},gg),MWn.Je=function(n){return Opn(this.a,n)},vX(x4n,m1n,1247),wAn(1248,1,{},pg),MWn.Je=function(n){return uon(this.a,n)},vX(x4n,"ElkGraphImporter/lambda$3$Type",1248),wAn(1249,1,{},vg),MWn.Je=function(n){return iOn(this.a,n)},vX(x4n,y1n,1249),wAn(1133,209,NJn,$E),MWn.Ze=function(n,t){var e,i,r,c,a,u,o,s,h,f;for(P8(n,(MMn(),kTt))&&(f=SD(ZAn(n,(Bvn(),qTt))),(c=XRn(cin(),f))&&BB(sJ(c.f),209).Ze(n,mcn(t,1))),Ypn(n,gTt,($6(),ZEt)),Ypn(n,pTt,($Sn(),cTt)),Ypn(n,vTt,(Lun(),WTt)),a=BB(ZAn(n,(Bvn(),KTt)),19).a,OTn(t,"Overlap removal",1),qy(TD(ZAn(n,_Tt))),o=new mg(u=new Rv),e=GXn(i=new Ehn,n),s=!0,r=0;r<a&&s;){if(qy(TD(ZAn(n,FTt)))){if(u.a.$b(),HPn(new C$(o),e.i),0==u.a.gc())break;e.e=u}for(h2(this.b),IU(this.b,(Pbn(),HEt),(OM(),GTt)),IU(this.b,qEt,e.g),IU(this.b,GEt,(CM(),QEt)),this.a=$qn(this.b,e),h=new Wb(this.a);h.a<h.c.c.length;)BB(n0(h),51).pf(e,mcn(t,1));cjn(i,e),s=qy(TD(mMn(e,(Xcn(),Yrt)))),++r}DGn(i,e),HSn(t)},vX(x4n,"OverlapRemovalLayoutProvider",1133),wAn(1134,1,{},mg),vX(x4n,"OverlapRemovalLayoutProvider/lambda$0$Type",1134),wAn(437,22,{3:1,35:1,22:1,437:1},EI);var UEt,XEt,WEt=Ben(x4n,"SPOrEPhases",437,Unt,B1,qF);wAn(1255,1,{},LE),vX(x4n,"ShrinkTree",1255),wAn(1135,209,NJn,Zm),MWn.Ze=function(n,t){var e,i,r,c;P8(n,(MMn(),kTt))&&(c=SD(ZAn(n,kTt)),(r=XRn(cin(),c))&&BB(sJ(r.f),209).Ze(n,mcn(t,1))),e=GXn(i=new Ehn,n),$Ln(this.a,e,mcn(t,1)),DGn(i,e)},vX(x4n,"ShrinkTreeLayoutProvider",1135),wAn(300,134,{3:1,300:1,94:1,134:1},DJ),MWn.c=!1,vX("org.eclipse.elk.alg.spore.graph","Graph",300),wAn(482,22,{3:1,35:1,22:1,482:1,246:1,234:1},LM),MWn.Kf=function(){return esn(this)},MWn.Xf=function(){return esn(this)};var VEt,QEt,YEt=Ben(D4n,FJn,482,Unt,_V,GF);wAn(551,22,{3:1,35:1,22:1,551:1,246:1,234:1},vD),MWn.Kf=function(){return new ru},MWn.Xf=function(){return new ru};var JEt,ZEt,nTt,tTt=Ben(D4n,"OverlapRemovalStrategy",551,Unt,KV,zF);wAn(430,22,{3:1,35:1,22:1,430:1},TI);var eTt,iTt,rTt,cTt,aTt,uTt,oTt=Ben(D4n,"RootSelection",430,Unt,iJ,UF);wAn(316,22,{3:1,35:1,22:1,316:1},MI);var sTt,hTt,fTt,lTt,bTt,wTt,dTt,gTt,pTt,vTt,mTt,yTt,kTt,jTt,ETt,TTt,MTt,STt,PTt,ITt,CTt,OTt,ATt,$Tt,LTt,NTt,xTt,DTt,RTt,_Tt,KTt,FTt,BTt,HTt,qTt,GTt,zTt=Ben(D4n,"SpanningTreeCostFunction",316,Unt,A5,XF);wAn(1002,1,QYn,Ef),MWn.Qe=function(n){yHn(n)},vX(D4n,"SporeCompactionOptions",1002),wAn(1003,1,{},tu),MWn.$e=function(){return new Zm},MWn._e=function(n){},vX(D4n,"SporeCompactionOptions/SporeCompactionFactory",1003),wAn(855,1,QYn,Tf),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,_4n),""),"Underlying Layout Algorithm"),"A layout algorithm that is applied to the graph before it is compacted. If this is null, nothing is applied before compaction."),(PPn(),yMt)),Qtt),nbn((rpn(),hMt))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,q4n),"structure"),"Structure Extraction Strategy"),"This option defines what kind of triangulation or other partitioning of the plane is applied to the vertices."),DTt),gMt),VTt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,K4n),W4n),"Tree Construction Strategy"),"Whether a minimum spanning tree or a maximum spanning tree should be constructed."),NTt),gMt),YTt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,F4n),W4n),"Cost Function for Spanning Tree"),"The cost function is used in the creation of the spanning tree."),$Tt),gMt),zTt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,B4n),W4n),"Root node for spanning tree construction"),"The identifier of the node that is preferred as the root of the spanning tree. If this is null, the first node is chosen."),null),yMt),Qtt),nbn(hMt)))),a2(n,B4n,H4n,ITt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,H4n),W4n),"Root selection for spanning tree"),"This sets the method used to select a root node for the construction of a spanning tree"),OTt),gMt),oTt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,G4n),E2n),"Compaction Strategy"),"This option defines how the compaction is applied."),ETt),gMt),YEt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,z4n),E2n),"Orthogonal Compaction"),"Restricts the translation of nodes to orthogonal directions in the compaction phase."),(hN(),!1)),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,U4n),V4n),"Upper limit for iterations of overlap removal"),null),iln(64)),vMt),Att),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,X4n),V4n),"Whether to run a supplementary scanline overlap check."),null),!0),wMt),ktt),nbn(hMt)))),A_n((new Mf,n)),yHn((new Ef,n))},vX(D4n,"SporeMetaDataProvider",855),wAn(VVn,1,QYn,Mf),MWn.Qe=function(n){A_n(n)},vX(D4n,"SporeOverlapRemovalOptions",VVn),wAn(1001,1,{},eu),MWn.$e=function(){return new $E},MWn._e=function(n){},vX(D4n,"SporeOverlapRemovalOptions/SporeOverlapFactory",1001),wAn(530,22,{3:1,35:1,22:1,530:1,246:1,234:1},XW),MWn.Kf=function(){return isn(this)},MWn.Xf=function(){return isn(this)};var UTt,XTt,WTt,VTt=Ben(D4n,"StructureExtractionStrategy",530,Unt,FV,WF);wAn(429,22,{3:1,35:1,22:1,429:1,246:1,234:1},SI),MWn.Kf=function(){return wwn(this)},MWn.Xf=function(){return wwn(this)};var QTt,YTt=Ben(D4n,"TreeConstructionStrategy",429,Unt,eJ,VF);wAn(1443,1,E3n,iu),MWn.Yf=function(n){return BB(n,300),new B2},MWn.pf=function(n,t){Tjn(BB(n,300),t)},vX(Y4n,"DelaunayTriangulationPhase",1443),wAn(1444,1,lVn,yg),MWn.td=function(n){WB(this.a,BB(n,65).a)},vX(Y4n,"DelaunayTriangulationPhase/lambda$0$Type",1444),wAn(783,1,E3n,Vm),MWn.Yf=function(n){return BB(n,300),new B2},MWn.pf=function(n,t){this.ng(BB(n,300),t)},MWn.ng=function(n,t){var e;OTn(t,"Minimum spanning tree construction",1),e=n.d?n.d.a:BB(xq(n.i,0),65).a,_un(this,(qy(TD(mMn(n,(Xcn(),Qrt)))),YHn(n.e,e,n.b)),n),HSn(t)},vX(J4n,"MinSTPhase",783),wAn(1446,783,E3n,ym),MWn.ng=function(n,t){var e,i;OTn(t,"Maximum spanning tree construction",1),e=new kg(n),i=n.d?n.d.c:BB(xq(n.i,0),65).c,_un(this,(qy(TD(mMn(n,(Xcn(),Qrt)))),YHn(n.e,i,e)),n),HSn(t)},vX(J4n,"MaxSTPhase",1446),wAn(1447,1,{},kg),MWn.Je=function(n){return CI(this.a,n)},vX(J4n,"MaxSTPhase/lambda$0$Type",1447),wAn(1445,1,lVn,jg),MWn.td=function(n){R$(this.a,BB(n,65))},vX(J4n,"MinSTPhase/lambda$0$Type",1445),wAn(785,1,E3n,ru),MWn.Yf=function(n){return BB(n,300),new B2},MWn.pf=function(n,t){WTn(this,BB(n,300),t)},MWn.a=!1,vX(Z4n,"GrowTreePhase",785),wAn(786,1,lVn,EB),MWn.td=function(n){eun(this.a,this.b,this.c,BB(n,221))},vX(Z4n,"GrowTreePhase/lambda$0$Type",786),wAn(1448,1,E3n,cu),MWn.Yf=function(n){return BB(n,300),new B2},MWn.pf=function(n,t){tmn(this,BB(n,300),t)},vX(Z4n,"ShrinkTreeCompactionPhase",1448),wAn(784,1,lVn,TB),MWn.td=function(n){lAn(this.a,this.b,this.c,BB(n,221))},vX(Z4n,"ShrinkTreeCompactionPhase/lambda$0$Type",784);var JTt,ZTt,nMt=bq(y3n,"IGraphElementVisitor");wAn(860,1,{527:1},R0),MWn.og=function(n){var t;qan(t=hRn(this,n),BB(RX(this.b,n),94)),yLn(this,n,t)},vX(xJn,"LayoutConfigurator",860);var tMt,eMt,iMt,rMt=bq(xJn,"LayoutConfigurator/IPropertyHolderOptionFilter");wAn(932,1,{1933:1},au),MWn.pg=function(n,t){return Nun(),!n.Xe(t)},vX(xJn,"LayoutConfigurator/lambda$0$Type",932),wAn(933,1,{1933:1},uu),MWn.pg=function(n,t){return SE(n,t)},vX(xJn,"LayoutConfigurator/lambda$1$Type",933),wAn(931,1,{831:1},ou),MWn.qg=function(n,t){return Nun(),!n.Xe(t)},vX(xJn,"LayoutConfigurator/lambda$2$Type",931),wAn(934,1,DVn,LI),MWn.Mb=function(n){return YW(this.a,this.b,BB(n,1933))},vX(xJn,"LayoutConfigurator/lambda$3$Type",934),wAn(858,1,{},su),vX(xJn,"RecursiveGraphLayoutEngine",858),wAn(296,60,BVn,kv,rk),vX(xJn,"UnsupportedConfigurationException",296),wAn(453,60,BVn,ck),vX(xJn,"UnsupportedGraphException",453),wAn(754,1,{}),vX(y3n,"AbstractRandomListAccessor",754),wAn(500,754,{},INn),MWn.rg=function(){return null},MWn.d=!0,MWn.e=!0,MWn.f=0,vX(t5n,"AlgorithmAssembler",500),wAn(1236,1,DVn,hu),MWn.Mb=function(n){return!!BB(n,123)},vX(t5n,"AlgorithmAssembler/lambda$0$Type",1236),wAn(1237,1,{},Eg),MWn.Kb=function(n){return bj(this.a,BB(n,123))},vX(t5n,"AlgorithmAssembler/lambda$1$Type",1237),wAn(1238,1,DVn,fu),MWn.Mb=function(n){return!!BB(n,80)},vX(t5n,"AlgorithmAssembler/lambda$2$Type",1238),wAn(1239,1,lVn,Tg),MWn.td=function(n){Jcn(this.a,BB(n,80))},vX(t5n,"AlgorithmAssembler/lambda$3$Type",1239),wAn(1240,1,lVn,NI),MWn.td=function(n){Dx(this.a,this.b,BB(n,234))},vX(t5n,"AlgorithmAssembler/lambda$4$Type",1240),wAn(1355,1,MYn,lu),MWn.ue=function(n,t){return FQ(BB(n,234),BB(t,234))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(t5n,"EnumBasedFactoryComparator",1355),wAn(80,754,{80:1},B2),MWn.rg=function(){return new Rv},MWn.a=0,vX(t5n,"LayoutProcessorConfiguration",80),wAn(1013,1,{527:1},$f),MWn.og=function(n){nan(eMt,new Mg(n))},vX(zYn,"DeprecatedLayoutOptionReplacer",1013),wAn(1014,1,lVn,bu),MWn.td=function(n){N9(BB(n,160))},vX(zYn,"DeprecatedLayoutOptionReplacer/lambda$0$Type",1014),wAn(1015,1,lVn,wu),MWn.td=function(n){Twn(BB(n,160))},vX(zYn,"DeprecatedLayoutOptionReplacer/lambda$1$Type",1015),wAn(1016,1,{},Mg),MWn.Od=function(n,t){Rx(this.a,BB(n,146),BB(t,38))},vX(zYn,"DeprecatedLayoutOptionReplacer/lambda$2$Type",1016),wAn(149,1,{686:1,149:1},MTn),MWn.Fb=function(n){return j5(this,n)},MWn.sg=function(){return this.b},MWn.tg=function(){return this.c},MWn.ne=function(){return this.e},MWn.Hb=function(){return vvn(this.c)},MWn.Ib=function(){return"Layout Algorithm: "+this.c};var cMt,aMt=vX(zYn,"LayoutAlgorithmData",149);wAn(263,1,{},du),vX(zYn,"LayoutAlgorithmData/Builder",263),wAn(1017,1,{527:1},gu),MWn.og=function(n){cL(n,239)&&!qy(TD(n.We((sWn(),zSt))))&&_Fn(BB(n,33))},vX(zYn,"LayoutAlgorithmResolver",1017),wAn(229,1,{686:1,229:1},UZ),MWn.Fb=function(n){return!!cL(n,229)&&m_(this.b,BB(n,229).b)},MWn.sg=function(){return this.a},MWn.tg=function(){return this.b},MWn.ne=function(){return this.d},MWn.Hb=function(){return vvn(this.b)},MWn.Ib=function(){return"Layout Type: "+this.b},vX(zYn,"LayoutCategoryData",229),wAn(344,1,{},pu),vX(zYn,"LayoutCategoryData/Builder",344),wAn(867,1,{},ORn),vX(zYn,"LayoutMetaDataService",867),wAn(868,1,{},UX),vX(zYn,"LayoutMetaDataService/Registry",868),wAn(478,1,{478:1},vu),vX(zYn,"LayoutMetaDataService/Registry/Triple",478),wAn(869,1,e5n,mu),MWn.ug=function(){return new Gj},vX(zYn,"LayoutMetaDataService/lambda$0$Type",869),wAn(870,1,i5n,yu),MWn.vg=function(n){return B$(BB(n,8))},vX(zYn,"LayoutMetaDataService/lambda$1$Type",870),wAn(879,1,e5n,ku),MWn.ug=function(){return new Np},vX(zYn,"LayoutMetaDataService/lambda$10$Type",879),wAn(880,1,i5n,ju),MWn.vg=function(n){return new tK(BB(n,12))},vX(zYn,"LayoutMetaDataService/lambda$11$Type",880),wAn(881,1,e5n,Eu),MWn.ug=function(){return new YT},vX(zYn,"LayoutMetaDataService/lambda$12$Type",881),wAn(882,1,i5n,Tu),MWn.vg=function(n){return zB(BB(n,68))},vX(zYn,"LayoutMetaDataService/lambda$13$Type",882),wAn(883,1,e5n,Mu),MWn.ug=function(){return new Rv},vX(zYn,"LayoutMetaDataService/lambda$14$Type",883),wAn(884,1,i5n,Su),MWn.vg=function(n){return JQ(BB(n,53))},vX(zYn,"LayoutMetaDataService/lambda$15$Type",884),wAn(885,1,e5n,Pu),MWn.ug=function(){return new fA},vX(zYn,"LayoutMetaDataService/lambda$16$Type",885),wAn(886,1,i5n,Iu),MWn.vg=function(n){return S4(BB(n,53))},vX(zYn,"LayoutMetaDataService/lambda$17$Type",886),wAn(887,1,e5n,Cu),MWn.ug=function(){return new zv},vX(zYn,"LayoutMetaDataService/lambda$18$Type",887),wAn(888,1,i5n,Ou),MWn.vg=function(n){return GB(BB(n,208))},vX(zYn,"LayoutMetaDataService/lambda$19$Type",888),wAn(871,1,e5n,Au),MWn.ug=function(){return new km},vX(zYn,"LayoutMetaDataService/lambda$2$Type",871),wAn(872,1,i5n,$u),MWn.vg=function(n){return new _j(BB(n,74))},vX(zYn,"LayoutMetaDataService/lambda$3$Type",872),wAn(873,1,e5n,Lu),MWn.ug=function(){return new lm},vX(zYn,"LayoutMetaDataService/lambda$4$Type",873),wAn(874,1,i5n,Nu),MWn.vg=function(n){return new AK(BB(n,142))},vX(zYn,"LayoutMetaDataService/lambda$5$Type",874),wAn(875,1,e5n,Du),MWn.ug=function(){return new bm},vX(zYn,"LayoutMetaDataService/lambda$6$Type",875),wAn(876,1,i5n,Ru),MWn.vg=function(n){return new OK(BB(n,116))},vX(zYn,"LayoutMetaDataService/lambda$7$Type",876),wAn(877,1,e5n,_u),MWn.ug=function(){return new Yu},vX(zYn,"LayoutMetaDataService/lambda$8$Type",877),wAn(878,1,i5n,Ku),MWn.vg=function(n){return new rnn(BB(n,373))},vX(zYn,"LayoutMetaDataService/lambda$9$Type",878);var uMt,oMt,sMt,hMt,fMt,lMt=bq(CJn,"IProperty");wAn(23,1,{35:1,686:1,23:1,146:1},bPn),MWn.wd=function(n){return gL(this,BB(n,146))},MWn.Fb=function(n){return cL(n,23)?m_(this.f,BB(n,23).f):cL(n,146)&&m_(this.f,BB(n,146).tg())},MWn.wg=function(){var n;if(cL(this.b,4)){if(null==(n=Jdn(this.b)))throw Hp(new Fy(o5n+this.f+"'. Make sure it's type is registered with the "+(ED(bAt),bAt.k)+c5n));return n}return this.b},MWn.sg=function(){return this.d},MWn.tg=function(){return this.f},MWn.ne=function(){return this.i},MWn.Hb=function(){return vvn(this.f)},MWn.Ib=function(){return"Layout Option: "+this.f},vX(zYn,"LayoutOptionData",23),wAn(24,1,{},Fu),vX(zYn,"LayoutOptionData/Builder",24),wAn(175,22,{3:1,35:1,22:1,175:1},AI);var bMt,wMt,dMt,gMt,pMt,vMt,mMt,yMt,kMt,jMt=Ben(zYn,"LayoutOptionData/Target",175,Unt,O5,QF);wAn(277,22,{3:1,35:1,22:1,277:1},$I);var EMt,TMt,MMt,SMt=Ben(zYn,"LayoutOptionData/Type",277,Unt,Ktn,YF);wAn(110,1,{110:1},bA,UV,gY),MWn.Fb=function(n){var t;return!(null==n||!cL(n,110))&&(t=BB(n,110),cV(this.c,t.c)&&cV(this.d,t.d)&&cV(this.b,t.b)&&cV(this.a,t.a))},MWn.Hb=function(){return fhn(Pun(Gk(Ant,1),HWn,1,5,[this.c,this.d,this.b,this.a]))},MWn.Ib=function(){return"Rect[x="+this.c+",y="+this.d+",w="+this.b+",h="+this.a+"]"},MWn.a=0,MWn.b=0,MWn.c=0,MWn.d=0,vX(f1n,"ElkRectangle",110),wAn(8,1,{3:1,4:1,8:1,414:1},Gj,XZ,xI,wA),MWn.Fb=function(n){return nrn(this,n)},MWn.Hb=function(){return VO(this.a)+byn(VO(this.b))},MWn.Jf=function(n){var t,e,i;for(e=0;e<n.length&&xhn((b1(e,n.length),n.charCodeAt(e)),o1n);)++e;for(t=n.length;t>0&&xhn((b1(t-1,n.length),n.charCodeAt(t-1)),s1n);)--t;if(e>=t)throw Hp(new Ky("The given string does not contain any numbers."));if(2!=(i=k_n(n.substr(e,t-e),",|;|\r|\n")).length)throw Hp(new Ky("Exactly two numbers are expected, "+i.length+" were found."));try{this.a=bSn(RMn(i[0])),this.b=bSn(RMn(i[1]))}catch(r){throw cL(r=lun(r),127)?Hp(new Ky(h1n+r)):Hp(r)}},MWn.Ib=function(){return"("+this.a+","+this.b+")"},MWn.a=0,MWn.b=0;var PMt=vX(f1n,"KVector",8);wAn(74,68,{3:1,4:1,20:1,28:1,52:1,14:1,68:1,15:1,74:1,414:1},km,_j,Ux),MWn.Pc=function(){return Vsn(this)},MWn.Jf=function(n){var t,e,i,r,c;e=k_n(n,",|;|\\(|\\)|\\[|\\]|\\{|\\}| |\t|\n"),yQ(this);try{for(t=0,r=0,i=0,c=0;t<e.length;)null!=e[t]&&RMn(e[t]).length>0&&(r%2==0?i=bSn(e[t]):c=bSn(e[t]),r>0&&r%2!=0&&DH(this,new xI(i,c)),++r),++t}catch(a){throw cL(a=lun(a),127)?Hp(new Ky("The given string does not match the expected format for vectors."+a)):Hp(a)}},MWn.Ib=function(){var n,t,e;for(n=new lN("("),t=spn(this,0);t.b!=t.d.c;)oO(n,(e=BB(b3(t),8)).a+","+e.b),t.b!=t.d.c&&(n.a+="; ");return(n.a+=")",n).a};var IMt,CMt,OMt,AMt,$Mt,LMt,NMt=vX(f1n,"KVectorChain",74);wAn(248,22,{3:1,35:1,22:1,248:1},DI);var xMt,DMt,RMt,_Mt,KMt,FMt,BMt,HMt,qMt,GMt,zMt,UMt,XMt,WMt,VMt,QMt,YMt,JMt,ZMt,nSt=Ben(h5n,"Alignment",248,Unt,J8,JF);wAn(979,1,QYn,Lf),MWn.Qe=function(n){GKn(n)},vX(h5n,"BoxLayouterOptions",979),wAn(980,1,{},xu),MWn.$e=function(){return new Gu},MWn._e=function(n){},vX(h5n,"BoxLayouterOptions/BoxFactory",980),wAn(291,22,{3:1,35:1,22:1,291:1},RI);var tSt,eSt,iSt,rSt,cSt,aSt,uSt,oSt,sSt,hSt,fSt,lSt,bSt,wSt,dSt,gSt,pSt,vSt,mSt,ySt,kSt,jSt,ESt,TSt,MSt,SSt,PSt,ISt,CSt,OSt,ASt,$St,LSt,NSt,xSt,DSt,RSt,_St,KSt,FSt,BSt,HSt,qSt,GSt,zSt,USt,XSt,WSt,VSt,QSt,YSt,JSt,ZSt,nPt,tPt,ePt,iPt,rPt,cPt,aPt,uPt,oPt,sPt,hPt,fPt,lPt,bPt,wPt,dPt,gPt,pPt,vPt,mPt,yPt,kPt,jPt,EPt,TPt,MPt,SPt,PPt,IPt,CPt,OPt,APt,$Pt,LPt,NPt,xPt,DPt,RPt,_Pt,KPt,FPt,BPt,HPt,qPt=Ben(h5n,"ContentAlignment",291,Unt,Y8,ZF);wAn(684,1,QYn,Nf),MWn.Qe=function(n){Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,w5n),""),"Layout Algorithm"),"Select a specific layout algorithm."),(PPn(),yMt)),Qtt),nbn((rpn(),hMt))))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,d5n),""),"Resolved Layout Algorithm"),"Meta data associated with the selected algorithm."),mMt),aMt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,W2n),""),"Alignment"),"Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm."),rSt),gMt),nSt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,VJn),""),"Aspect Ratio"),"The desired aspect ratio of the drawing, that is the quotient of width by height."),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,g5n),""),"Bend Points"),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),mMt),NMt),nbn(uMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,u3n),""),"Content Alignment"),"Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option."),fSt),pMt),qPt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,X2n),""),"Debug Mode"),"Whether additional debug information shall be generated."),(hN(),!1)),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,J2n),""),TJn),"Overall direction of edges: horizontal (right / left) or vertical (down / up)."),wSt),gMt),WPt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,y2n),""),"Edge Routing"),"What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline."),mSt),gMt),oIt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,A4n),""),"Expand Nodes"),"If active, nodes are expanded to fill the area of their parent."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,d2n),""),"Hierarchy Handling"),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),TSt),gMt),SIt),EG(hMt,Pun(Gk(jMt,1),$Vn,175,0,[sMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,QJn),""),"Padding"),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),WSt),mMt),Kut),EG(hMt,Pun(Gk(jMt,1),$Vn,175,0,[sMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,jZn),""),"Interactive"),"Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,m3n),""),"interactive Layout"),"Whether the graph should be changeable interactively and by setting constraints"),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,MZn),""),"Omit Node Micro Layout"),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,EZn),""),"Port Constraints"),"Defines constraints of the position of the ports of a node."),oPt),gMt),aCt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,g3n),""),"Position"),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),mMt),PMt),EG(sMt,Pun(Gk(jMt,1),$Vn,175,0,[fMt,oMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,pZn),""),"Priority"),"Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used."),vMt),Att),EG(sMt,Pun(Gk(jMt,1),$Vn,175,0,[uMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,yZn),""),"Randomization Seed"),"Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time)."),vMt),Att),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,kZn),""),"Separate Connected Components"),"Whether each connected component should be processed separately."),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,o3n),""),"Junction Points"),"This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order."),ASt),mMt),NMt),nbn(uMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,f3n),""),"Comment Box"),"Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related."),!1),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,l3n),""),"Hypernode"),"Whether the node should be handled as a hypernode."),!1),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,p5n),""),"Label Manager"),"Label managers can shorten labels upon a layout algorithm's request."),mMt),_Nt),EG(hMt,Pun(Gk(jMt,1),$Vn,175,0,[oMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,p3n),""),"Margins"),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),LSt),mMt),Eut),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,z2n),""),"No Layout"),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),!1),wMt),ktt),EG(sMt,Pun(Gk(jMt,1),$Vn,175,0,[uMt,fMt,oMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,v5n),""),"Scale Factor"),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),dMt),Ptt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,m5n),""),"Animate"),"Whether the shift from the old layout to the new computed layout shall be animated."),!0),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,y5n),""),"Animation Time Factor"),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),iln(100)),vMt),Att),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,k5n),""),"Layout Ancestors"),"Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,j5n),""),"Maximal Animation Time"),"The maximal time for animations, in milliseconds."),iln(4e3)),vMt),Att),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,E5n),""),"Minimal Animation Time"),"The minimal time for animations, in milliseconds."),iln(400)),vMt),Att),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,T5n),""),"Progress Bar"),"Whether a progress bar shall be displayed during layout computations."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,M5n),""),"Validate Graph"),"Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,S5n),""),"Validate Options"),"Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!0),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,P5n),""),"Zoom to Fit"),"Whether the zoom level shall be set to view the whole diagram after layout."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,b5n),"box"),"Box Layout Mode"),"Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better."),oSt),gMt),cOt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,L2n),k2n),"Comment Comment Spacing"),"Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing."),10),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,N2n),k2n),"Comment Node Spacing"),"Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing."),10),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,XJn),k2n),"Components Spacing"),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,x2n),k2n),"Edge Spacing"),"Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines."),10),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,mZn),k2n),"Edge Label Spacing"),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,D2n),k2n),"Edge Node Spacing"),"Spacing to be preserved between nodes and edges."),10),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,R2n),k2n),"Label Spacing"),"Determines the amount of space to be left between two labels of the same graph element."),0),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,F2n),k2n),"Label Node Spacing"),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,_2n),k2n),"Horizontal spacing between Label and Port"),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,K2n),k2n),"Vertical spacing between Label and Port"),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,vZn),k2n),"Node Spacing"),"The minimal distance to be preserved between each two nodes."),20),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,B2n),k2n),"Node Self Loop Spacing"),"Spacing to be preserved between a node and its self loops."),10),dMt),Ptt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,H2n),k2n),"Port Spacing"),"Spacing between pairs of ports of the same node."),10),dMt),Ptt),EG(hMt,Pun(Gk(jMt,1),$Vn,175,0,[sMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,q2n),k2n),"Individual Spacing"),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),mMt),hOt),EG(sMt,Pun(Gk(jMt,1),$Vn,175,0,[uMt,fMt,oMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,v3n),k2n),"Additional Port Space"),"Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border."),DPt),mMt),Eut),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,d3n),A5n),"Layout Partition"),"Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction)."),vMt),Att),EG(hMt,Pun(Gk(jMt,1),$Vn,175,0,[sMt]))))),a2(n,d3n,w3n,JSt),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,w3n),A5n),"Layout Partitioning"),"Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle."),QSt),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,Z2n),$5n),"Node Label Padding"),"Define padding for node labels that are placed inside of a node."),xSt),mMt),Kut),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,IZn),$5n),"Node Label Placement"),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),RSt),pMt),GIt),EG(sMt,Pun(Gk(jMt,1),$Vn,175,0,[oMt]))))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,e3n),L5n),"Port Alignment"),"Defines the default port distribution for a node. May be overridden for each side individually."),nPt),gMt),JIt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,i3n),L5n),"Port Alignment (North)"),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),gMt),JIt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,r3n),L5n),"Port Alignment (South)"),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),gMt),JIt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,c3n),L5n),"Port Alignment (West)"),"Defines how ports on the western side are placed, overriding the node's general port alignment."),gMt),JIt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,a3n),L5n),"Port Alignment (East)"),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),gMt),JIt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,PZn),N5n),"Node Size Constraints"),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),KSt),pMt),YCt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,SZn),N5n),"Node Size Options"),"Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications."),GSt),pMt),iOt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,BZn),N5n),"Node Size Minimum"),"The minimal size to which a node can be reduced."),HSt),mMt),PMt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,Y2n),N5n),"Fixed Graph Size"),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),!1),wMt),ktt),nbn(hMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,s3n),A2n),"Edge Label Placement"),"Gives a hint on where to put edge labels."),pSt),gMt),nIt),nbn(oMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,TZn),A2n),"Inline Edge Labels"),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),!1),wMt),ktt),nbn(oMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,I5n),"font"),"Font Name"),"Font name used for a label."),yMt),Qtt),nbn(oMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,C5n),"font"),"Font Size"),"Font size used for a label."),vMt),Att),nbn(oMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,b3n),x5n),"Port Anchor Offset"),"The offset to the port position where connections shall be attached."),mMt),PMt),nbn(fMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,h3n),x5n),"Port Index"),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),vMt),Att),nbn(fMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,U2n),x5n),"Port Side"),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),dPt),gMt),FCt),nbn(fMt)))),Abn(n,new bPn(Oj(Cj(Aj(Ej(Ij(Mj(Sj(new Fu,G2n),x5n),"Port Border Offset"),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),dMt),Ptt),nbn(fMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,CZn),D5n),"Port Label Placement"),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),lPt),pMt),CCt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,n3n),D5n),"Port Labels Next to Port"),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),!1),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,t3n),D5n),"Treat Port Labels as Group"),"If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port."),!0),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,V2n),R5n),"Activate Inside Self Loops"),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),!1),wMt),ktt),nbn(sMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,Q2n),R5n),"Inside Self Loop"),"Whether a self loop should be routed inside a node instead of around that node."),!1),wMt),ktt),nbn(uMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,WJn),"edge"),"Edge Thickness"),"The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it."),1),dMt),Ptt),nbn(uMt)))),Abn(n,new bPn(Oj(Cj(Aj(Tj(Ej(Ij(Mj(Sj(new Fu,O5n),"edge"),"Edge Type"),"The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations."),kSt),gMt),yIt),nbn(uMt)))),xM(n,new UZ(yj(jj(kj(new pu,w1n),"Layered"),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.'))),xM(n,new UZ(yj(jj(kj(new pu,"org.eclipse.elk.orthogonal"),"Orthogonal"),'Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.'))),xM(n,new UZ(yj(jj(kj(new pu,gZn),"Force"),"Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984."))),xM(n,new UZ(yj(jj(kj(new pu,"org.eclipse.elk.circle"),"Circle"),"Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph."))),xM(n,new UZ(yj(jj(kj(new pu,Y3n),"Tree"),"Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type."))),xM(n,new UZ(yj(jj(kj(new pu,"org.eclipse.elk.planar"),"Planar"),"Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable."))),xM(n,new UZ(yj(jj(kj(new pu,w4n),"Radial"),"Radial layout algorithms usually position the nodes of the graph on concentric circles."))),b_n((new xf,n)),GKn((new Lf,n)),RDn((new Df,n))},vX(h5n,"CoreOptions",684),wAn(103,22,{3:1,35:1,22:1,103:1},_I);var GPt,zPt,UPt,XPt,WPt=Ben(h5n,TJn,103,Unt,I5,eB);wAn(272,22,{3:1,35:1,22:1,272:1},KI);var VPt,QPt,YPt,JPt,ZPt,nIt=Ben(h5n,"EdgeLabelPlacement",272,Unt,q1,iB);wAn(218,22,{3:1,35:1,22:1,218:1},FI);var tIt,eIt,iIt,rIt,cIt,aIt,uIt,oIt=Ben(h5n,"EdgeRouting",218,Unt,S3,rB);wAn(312,22,{3:1,35:1,22:1,312:1},BI);var sIt,hIt,fIt,lIt,bIt,wIt,dIt,gIt,pIt,vIt,mIt,yIt=Ben(h5n,"EdgeType",312,Unt,a9,cB);wAn(977,1,QYn,xf),MWn.Qe=function(n){b_n(n)},vX(h5n,"FixedLayouterOptions",977),wAn(978,1,{},Vu),MWn.$e=function(){return new Hu},MWn._e=function(n){},vX(h5n,"FixedLayouterOptions/FixedFactory",978),wAn(334,22,{3:1,35:1,22:1,334:1},HI);var kIt,jIt,EIt,TIt,MIt,SIt=Ben(h5n,"HierarchyHandling",334,Unt,H1,aB);wAn(285,22,{3:1,35:1,22:1,285:1},qI);var PIt,IIt,CIt,OIt,AIt,$It,LIt,NIt,xIt,DIt,RIt=Ben(h5n,"LabelSide",285,Unt,M3,uB);wAn(93,22,{3:1,35:1,22:1,93:1},GI);var _It,KIt,FIt,BIt,HIt,qIt,GIt=Ben(h5n,"NodeLabelPlacement",93,Unt,ken,oB);wAn(249,22,{3:1,35:1,22:1,249:1},zI);var zIt,UIt,XIt,WIt,VIt,QIt,YIt,JIt=Ben(h5n,"PortAlignment",249,Unt,C5,sB);wAn(98,22,{3:1,35:1,22:1,98:1},UI);var ZIt,nCt,tCt,eCt,iCt,rCt,cCt,aCt=Ben(h5n,"PortConstraints",98,Unt,S8,hB);wAn(273,22,{3:1,35:1,22:1,273:1},XI);var uCt,oCt,sCt,hCt,fCt,lCt,bCt,wCt,dCt,gCt,pCt,vCt,mCt,yCt,kCt,jCt,ECt,TCt,MCt,SCt,PCt,ICt,CCt=Ben(h5n,"PortLabelPlacement",273,Unt,c9,fB);wAn(61,22,{3:1,35:1,22:1,61:1},WI);var OCt,ACt,$Ct,LCt,NCt,xCt,DCt,RCt,_Ct,KCt,FCt=Ben(h5n,"PortSide",61,Unt,h5,wB);wAn(981,1,QYn,Df),MWn.Qe=function(n){RDn(n)},vX(h5n,"RandomLayouterOptions",981),wAn(982,1,{},Qu),MWn.$e=function(){return new no},MWn._e=function(n){},vX(h5n,"RandomLayouterOptions/RandomFactory",982),wAn(374,22,{3:1,35:1,22:1,374:1},VI);var BCt,HCt,qCt,GCt,zCt,UCt,XCt,WCt,VCt,QCt,YCt=Ben(h5n,"SizeConstraint",374,Unt,T3,lB);wAn(259,22,{3:1,35:1,22:1,259:1},QI);var JCt,ZCt,nOt,tOt,eOt,iOt=Ben(h5n,"SizeOptions",259,Unt,Ein,bB);wAn(370,1,{1949:1},Xm),MWn.b=!1,MWn.c=0,MWn.d=-1,MWn.e=null,MWn.f=null,MWn.g=-1,MWn.j=!1,MWn.k=!1,MWn.n=!1,MWn.o=0,MWn.q=0,MWn.r=0,vX(y3n,"BasicProgressMonitor",370),wAn(972,209,NJn,Gu),MWn.Ze=function(n,t){var e,i,r,c,a,u,o,s,h;OTn(t,"Box layout",2),r=zy(MD(ZAn(n,(SMn(),XMt)))),c=BB(ZAn(n,GMt),116),e=qy(TD(ZAn(n,KMt))),i=qy(TD(ZAn(n,FMt))),0===BB(ZAn(n,RMt),311).g?(u=new tK((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a)),SQ(),m$(u,new Sg(i)),a=u,o=XPn(n),(null==(s=MD(ZAn(n,DMt)))||(kW(s),s<=0))&&(s=1.3),_Un(n,(h=HUn(a,r,c,o.a,o.b,e,(kW(s),s))).a,h.b,!1,!0)):kqn(n,r,c,e),HSn(t)},vX(y3n,"BoxLayoutProvider",972),wAn(973,1,MYn,Sg),MWn.ue=function(n,t){return hNn(this,BB(n,33),BB(t,33))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},MWn.a=!1,vX(y3n,"BoxLayoutProvider/1",973),wAn(157,1,{157:1},Gtn,zx),MWn.Ib=function(){return this.c?zRn(this.c):LMn(this.b)},vX(y3n,"BoxLayoutProvider/Group",157),wAn(311,22,{3:1,35:1,22:1,311:1},YI);var rOt,cOt=Ben(y3n,"BoxLayoutProvider/PackingMode",311,Unt,P3,dB);wAn(974,1,MYn,zu),MWn.ue=function(n,t){return DQ(BB(n,157),BB(t,157))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(y3n,"BoxLayoutProvider/lambda$0$Type",974),wAn(975,1,MYn,Uu),MWn.ue=function(n,t){return cQ(BB(n,157),BB(t,157))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(y3n,"BoxLayoutProvider/lambda$1$Type",975),wAn(976,1,MYn,Xu),MWn.ue=function(n,t){return aQ(BB(n,157),BB(t,157))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(y3n,"BoxLayoutProvider/lambda$2$Type",976),wAn(1365,1,{831:1},Wu),MWn.qg=function(n,t){return AM(),!cL(t,160)||SE((Nun(),BB(n,160)),t)},vX(y3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$0$Type",1365),wAn(1366,1,lVn,Pg),MWn.td=function(n){Jsn(this.a,BB(n,146))},vX(y3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$1$Type",1366),wAn(1367,1,lVn,qu),MWn.td=function(n){BB(n,94),AM()},vX(y3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$2$Type",1367),wAn(1371,1,lVn,Ig),MWn.td=function(n){Orn(this.a,BB(n,94))},vX(y3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$3$Type",1371),wAn(1369,1,DVn,JI),MWn.Mb=function(n){return Von(this.a,this.b,BB(n,146))},vX(y3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$4$Type",1369),wAn(1368,1,DVn,ZI),MWn.Mb=function(n){return $x(this.a,this.b,BB(n,831))},vX(y3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$5$Type",1368),wAn(1370,1,lVn,nC),MWn.td=function(n){Fz(this.a,this.b,BB(n,146))},vX(y3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$6$Type",1370),wAn(935,1,{},Bu),MWn.Kb=function(n){return yA(n)},MWn.Fb=function(n){return this===n},vX(y3n,"ElkUtil/lambda$0$Type",935),wAn(936,1,lVn,tC),MWn.td=function(n){rOn(this.a,this.b,BB(n,79))},MWn.a=0,MWn.b=0,vX(y3n,"ElkUtil/lambda$1$Type",936),wAn(937,1,lVn,eC),MWn.td=function(n){Ey(this.a,this.b,BB(n,202))},MWn.a=0,MWn.b=0,vX(y3n,"ElkUtil/lambda$2$Type",937),wAn(938,1,lVn,iC),MWn.td=function(n){t$(this.a,this.b,BB(n,137))},MWn.a=0,MWn.b=0,vX(y3n,"ElkUtil/lambda$3$Type",938),wAn(939,1,lVn,Cg),MWn.td=function(n){cq(this.a,BB(n,469))},vX(y3n,"ElkUtil/lambda$4$Type",939),wAn(342,1,{35:1,342:1},$p),MWn.wd=function(n){return vL(this,BB(n,236))},MWn.Fb=function(n){var t;return!!cL(n,342)&&(t=BB(n,342),this.a==t.a)},MWn.Hb=function(){return IJ(this.a)},MWn.Ib=function(){return this.a+" (exclusive)"},MWn.a=0,vX(y3n,"ExclusiveBounds/ExclusiveLowerBound",342),wAn(1138,209,NJn,Hu),MWn.Ze=function(n,t){var i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(OTn(t,"Fixed Layout",1),a=BB(ZAn(n,(sWn(),vSt)),218),b=0,w=0,v=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));v.e!=v.i.gc();){for(g=BB(kpn(v),33),(T=BB(ZAn(g,(Xsn(),gIt)),8))&&(SA(g,T.a,T.b),BB(ZAn(g,fIt),174).Hc((mdn(),DCt))&&(d=BB(ZAn(g,bIt),8)).a>0&&d.b>0&&_Un(g,d.a,d.b,!0,!0)),b=e.Math.max(b,g.i+g.g),w=e.Math.max(w,g.j+g.f),f=new AL((!g.n&&(g.n=new eU(zOt,g,1,7)),g.n));f.e!=f.i.gc();)o=BB(kpn(f),137),(T=BB(ZAn(o,gIt),8))&&SA(o,T.a,T.b),b=e.Math.max(b,g.i+o.i+o.g),w=e.Math.max(w,g.j+o.j+o.f);for(k=new AL((!g.c&&(g.c=new eU(XOt,g,9,9)),g.c));k.e!=k.i.gc();)for(y=BB(kpn(k),118),(T=BB(ZAn(y,gIt),8))&&SA(y,T.a,T.b),j=g.i+y.i,E=g.j+y.j,b=e.Math.max(b,j+y.g),w=e.Math.max(w,E+y.f),s=new AL((!y.n&&(y.n=new eU(zOt,y,1,7)),y.n));s.e!=s.i.gc();)o=BB(kpn(s),137),(T=BB(ZAn(o,gIt),8))&&SA(o,T.a,T.b),b=e.Math.max(b,j+o.i+o.g),w=e.Math.max(w,E+o.j+o.f);for(c=new oz(ZL(dLn(g).a.Kc(),new h));dAn(c);)l=KUn(i=BB(U5(c),79)),b=e.Math.max(b,l.a),w=e.Math.max(w,l.b);for(r=new oz(ZL(wLn(g).a.Kc(),new h));dAn(r);)JJ(PMn(i=BB(U5(r),79)))!=n&&(l=KUn(i),b=e.Math.max(b,l.a),w=e.Math.max(w,l.b))}if(a==(Mbn(),QPt))for(p=new AL((!n.a&&(n.a=new eU(UOt,n,10,11)),n.a));p.e!=p.i.gc();)for(r=new oz(ZL(dLn(g=BB(kpn(p),33)).a.Kc(),new h));dAn(r);)0==(u=rFn(i=BB(U5(r),79))).b?Ypn(i,OSt,null):Ypn(i,OSt,u);qy(TD(ZAn(n,(Xsn(),lIt))))||_Un(n,b+(m=BB(ZAn(n,wIt),116)).b+m.c,w+m.d+m.a,!0,!0),HSn(t)},vX(y3n,"FixedLayoutProvider",1138),wAn(373,134,{3:1,414:1,373:1,94:1,134:1},Yu,rnn),MWn.Jf=function(n){var t,e,i,r,c,a,u;if(n)try{for(a=k_n(n,";,;"),r=0,c=(i=a).length;r<c;++r){if(t=k_n(i[r],"\\:"),!(e=pGn(cin(),t[0])))throw Hp(new Ky("Invalid option id: "+t[0]));if(null==(u=Zqn(e,t[1])))throw Hp(new Ky("Invalid option value: "+t[1]));null==u?(!this.q&&(this.q=new xp),v6(this.q,e)):(!this.q&&(this.q=new xp),VW(this.q,e,u))}}catch(o){throw cL(o=lun(o),102)?Hp(new Fsn(o)):Hp(o)}},MWn.Ib=function(){return SD(P4($V((this.q?this.q:(SQ(),SQ(),het)).vc().Oc(),new Ju),x7(new YB,new Z,new W,new V,Pun(Gk(nit,1),$Vn,132,0,[]))))};var aOt,uOt,oOt,sOt,hOt=vX(y3n,"IndividualSpacings",373);wAn(971,1,{},Ju),MWn.Kb=function(n){return RQ(BB(n,42))},vX(y3n,"IndividualSpacings/lambda$0$Type",971),wAn(709,1,{},sG),MWn.c=0,vX(y3n,"InstancePool",709),wAn(1275,1,{},Zu),vX(y3n,"LoggedGraph",1275),wAn(396,22,{3:1,35:1,22:1,396:1},cC);var fOt,lOt,bOt,wOt=Ben(y3n,"LoggedGraph/Type",396,Unt,I3,gB);wAn(46,1,{20:1,46:1},rC),MWn.Jc=function(n){e5(this,n)},MWn.Fb=function(n){var t,e,i;return!!cL(n,46)&&(e=BB(n,46),t=null==this.a?null==e.a:Nfn(this.a,e.a),i=null==this.b?null==e.b:Nfn(this.b,e.b),t&&i)},MWn.Hb=function(){var n,t,e;return n=-65536&(t=null==this.a?0:nsn(this.a)),t&QVn^(-65536&(e=null==this.b?0:nsn(this.b)))>>16&QVn|n^(e&QVn)<<16},MWn.Kc=function(){return new Og(this)},MWn.Ib=function(){return null==this.a&&null==this.b?"pair(null,null)":null==this.a?"pair(null,"+Bbn(this.b)+")":null==this.b?"pair("+Bbn(this.a)+",null)":"pair("+Bbn(this.a)+","+Bbn(this.b)+")"},vX(y3n,"Pair",46),wAn(983,1,QWn,Og),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return!this.c&&(!this.b&&null!=this.a.a||null!=this.a.b)},MWn.Pb=function(){if(!this.c&&!this.b&&null!=this.a.a)return this.b=!0,this.a.a;if(!this.c&&null!=this.a.b)return this.c=!0,this.a.b;throw Hp(new yv)},MWn.Qb=function(){throw this.c&&null!=this.a.b?this.a.b=null:this.b&&null!=this.a.a&&(this.a.a=null),Hp(new dv)},MWn.b=!1,MWn.c=!1,vX(y3n,"Pair/1",983),wAn(448,1,{448:1},VV),MWn.Fb=function(n){return cV(this.a,BB(n,448).a)&&cV(this.c,BB(n,448).c)&&cV(this.d,BB(n,448).d)&&cV(this.b,BB(n,448).b)},MWn.Hb=function(){return fhn(Pun(Gk(Ant,1),HWn,1,5,[this.a,this.c,this.d,this.b]))},MWn.Ib=function(){return"("+this.a+FWn+this.c+FWn+this.d+FWn+this.b+")"},vX(y3n,"Quadruple",448),wAn(1126,209,NJn,no),MWn.Ze=function(n,t){var e;OTn(t,"Random Layout",1),0!=(!n.a&&(n.a=new eU(UOt,n,10,11)),n.a).i?(iUn(n,(e=BB(ZAn(n,(vdn(),NCt)),19))&&0!=e.a?new I4(e.a):new sbn,zy(MD(ZAn(n,ACt))),zy(MD(ZAn(n,xCt))),BB(ZAn(n,$Ct),116)),HSn(t)):HSn(t)},vX(y3n,"RandomLayoutProvider",1126),wAn(553,1,{}),MWn.qf=function(){return new xI(this.f.i,this.f.j)},MWn.We=function(n){return EY(n,(sWn(),aPt))?ZAn(this.f,bOt):ZAn(this.f,n)},MWn.rf=function(){return new xI(this.f.g,this.f.f)},MWn.sf=function(){return this.g},MWn.Xe=function(n){return P8(this.f,n)},MWn.tf=function(n){Pen(this.f,n.a),Ien(this.f,n.b)},MWn.uf=function(n){Sen(this.f,n.a),Men(this.f,n.b)},MWn.vf=function(n){this.g=n},MWn.g=0,vX(H5n,"ElkGraphAdapters/AbstractElkGraphElementAdapter",553),wAn(554,1,{839:1},Ag),MWn.wf=function(){var n,t;if(!this.b)for(this.b=I2(mV(this.a).i),t=new AL(mV(this.a));t.e!=t.i.gc();)n=BB(kpn(t),137),WB(this.b,new Ry(n));return this.b},MWn.b=null,vX(H5n,"ElkGraphAdapters/ElkEdgeAdapter",554),wAn(301,553,{},Dy),MWn.xf=function(){return eyn(this)},MWn.a=null,vX(H5n,"ElkGraphAdapters/ElkGraphAdapter",301),wAn(630,553,{181:1},Ry),vX(H5n,"ElkGraphAdapters/ElkLabelAdapter",630),wAn(629,553,{680:1},JN),MWn.wf=function(){return nyn(this)},MWn.Af=function(){var n;return!(n=BB(ZAn(this.f,(sWn(),$St)),142))&&(n=new lm),n},MWn.Cf=function(){return tyn(this)},MWn.Ef=function(n){var t;t=new AK(n),Ypn(this.f,(sWn(),$St),t)},MWn.Ff=function(n){Ypn(this.f,(sWn(),XSt),new OK(n))},MWn.yf=function(){return this.d},MWn.zf=function(){var n,t;if(!this.a)for(this.a=new Np,t=new oz(ZL(wLn(BB(this.f,33)).a.Kc(),new h));dAn(t);)n=BB(U5(t),79),WB(this.a,new Ag(n));return this.a},MWn.Bf=function(){var n,t;if(!this.c)for(this.c=new Np,t=new oz(ZL(dLn(BB(this.f,33)).a.Kc(),new h));dAn(t);)n=BB(U5(t),79),WB(this.c,new Ag(n));return this.c},MWn.Df=function(){return 0!=YQ(BB(this.f,33)).i||qy(TD(BB(this.f,33).We((sWn(),SSt))))},MWn.Gf=function(){K7(this,(GM(),lOt))},MWn.a=null,MWn.b=null,MWn.c=null,MWn.d=null,MWn.e=null,vX(H5n,"ElkGraphAdapters/ElkNodeAdapter",629),wAn(1266,553,{838:1},op),MWn.wf=function(){return kyn(this)},MWn.zf=function(){var n,t;if(!this.a)for(this.a=sx(BB(this.f,118).xg().i),t=new AL(BB(this.f,118).xg());t.e!=t.i.gc();)n=BB(kpn(t),79),WB(this.a,new Ag(n));return this.a},MWn.Bf=function(){var n,t;if(!this.c)for(this.c=sx(BB(this.f,118).yg().i),t=new AL(BB(this.f,118).yg());t.e!=t.i.gc();)n=BB(kpn(t),79),WB(this.c,new Ag(n));return this.c},MWn.Hf=function(){return BB(BB(this.f,118).We((sWn(),wPt)),61)},MWn.If=function(){var n,t,e,i,r,c,a;for(i=WJ(BB(this.f,118)),e=new AL(BB(this.f,118).yg());e.e!=e.i.gc();)for(a=new AL((!(n=BB(kpn(e),79)).c&&(n.c=new h_(_Ot,n,5,8)),n.c));a.e!=a.i.gc();){if(Itn(PTn(c=BB(kpn(a),82)),i))return!0;if(PTn(c)==i&&qy(TD(ZAn(n,(sWn(),PSt)))))return!0}for(t=new AL(BB(this.f,118).xg());t.e!=t.i.gc();)for(r=new AL((!(n=BB(kpn(t),79)).b&&(n.b=new h_(_Ot,n,4,7)),n.b));r.e!=r.i.gc();)if(Itn(PTn(BB(kpn(r),82)),i))return!0;return!1},MWn.a=null,MWn.b=null,MWn.c=null,vX(H5n,"ElkGraphAdapters/ElkPortAdapter",1266),wAn(1267,1,MYn,to),MWn.ue=function(n,t){return GRn(BB(n,118),BB(t,118))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(H5n,"ElkGraphAdapters/PortComparator",1267);var dOt,gOt,pOt,vOt,mOt,yOt,kOt,jOt,EOt,TOt,MOt,SOt,POt,IOt,COt,OOt,AOt,$Ot,LOt=bq(q5n,"EObject"),NOt=bq(G5n,z5n),xOt=bq(G5n,U5n),DOt=bq(G5n,X5n),ROt=bq(G5n,"ElkShape"),_Ot=bq(G5n,W5n),KOt=bq(G5n,V5n),FOt=bq(G5n,Q5n),BOt=bq(q5n,Y5n),HOt=bq(q5n,"EFactory"),qOt=bq(q5n,J5n),GOt=bq(q5n,"EPackage"),zOt=bq(G5n,Z5n),UOt=bq(G5n,n6n),XOt=bq(G5n,t6n);wAn(90,1,e6n),MWn.Jg=function(){return this.Kg(),null},MWn.Kg=function(){return null},MWn.Lg=function(){return this.Kg(),!1},MWn.Mg=function(){return!1},MWn.Ng=function(n){ban(this,n)},vX(i6n,"BasicNotifierImpl",90),wAn(97,90,f6n),MWn.nh=function(){return mA(this)},MWn.Og=function(n,t){return n},MWn.Pg=function(){throw Hp(new pv)},MWn.Qg=function(n){var t;return t=Ivn(BB(itn(this.Tg(),this.Vg()),18)),this.eh().ih(this,t.n,t.f,n)},MWn.Rg=function(n,t){throw Hp(new pv)},MWn.Sg=function(n,t,e){return TKn(this,n,t,e)},MWn.Tg=function(){var n;return this.Pg()&&(n=this.Pg().ck())?n:this.zh()},MWn.Ug=function(){return cAn(this)},MWn.Vg=function(){throw Hp(new pv)},MWn.Wg=function(){var n,t;return!(t=this.ph().dk())&&this.Pg().ik((QM(),t=null==(n=lJ(qFn(this.Tg())))?N$t:new QN(this,n))),t},MWn.Xg=function(n,t){return n},MWn.Yg=function(n){return n.Gj()?n.aj():Awn(this.Tg(),n)},MWn.Zg=function(){var n;return(n=this.Pg())?n.fk():null},MWn.$g=function(){return this.Pg()?this.Pg().ck():null},MWn._g=function(n,t,e){return Zpn(this,n,t,e)},MWn.ah=function(n){return S9(this,n)},MWn.bh=function(n,t){return V5(this,n,t)},MWn.dh=function(){var n;return!!(n=this.Pg())&&n.gk()},MWn.eh=function(){throw Hp(new pv)},MWn.fh=function(){return Ydn(this)},MWn.gh=function(n,t,e,i){return Npn(this,n,t,i)},MWn.hh=function(n,t,e){return BB(itn(this.Tg(),t),66).Nj().Qj(this,this.yh(),t-this.Ah(),n,e)},MWn.ih=function(n,t,e,i){return oJ(this,n,t,i)},MWn.jh=function(n,t,e){return BB(itn(this.Tg(),t),66).Nj().Rj(this,this.yh(),t-this.Ah(),n,e)},MWn.kh=function(){return!!this.Pg()&&!!this.Pg().ek()},MWn.lh=function(n){return vpn(this,n)},MWn.mh=function(n){return ZJ(this,n)},MWn.oh=function(n){return Kqn(this,n)},MWn.ph=function(){throw Hp(new pv)},MWn.qh=function(){return this.Pg()?this.Pg().ek():null},MWn.rh=function(){return Ydn(this)},MWn.sh=function(n,t){yIn(this,n,t)},MWn.th=function(n){this.ph().hk(n)},MWn.uh=function(n){this.ph().kk(n)},MWn.vh=function(n){this.ph().jk(n)},MWn.wh=function(n,t){var e,i,r,c;return(c=this.Zg())&&n&&(t=Kpn(c.Vk(),this,t),c.Zk(this)),(i=this.eh())&&(0!=(g_n(this,this.eh(),this.Vg()).Bb&BQn)?(r=i.fh())&&(n?!c&&r.Zk(this):r.Yk(this)):(t=(e=this.Vg())>=0?this.Qg(t):this.eh().ih(this,-1-e,null,t),t=this.Sg(null,-1,t))),this.uh(n),t},MWn.xh=function(n){var t,e,i,r,c,a,u;if((c=Awn(e=this.Tg(),n))>=(t=this.Ah()))return BB(n,66).Nj().Uj(this,this.yh(),c-t);if(c<=-1){if(!(a=Fqn((CPn(),Z$t),e,n)))throw Hp(new Ky(r6n+n.ne()+u6n));if(ZM(),BB(a,66).Oj()||(a=Z1(B7(Z$t,a))),r=BB((i=this.Yg(a))>=0?this._g(i,!0,!0):cOn(this,a,!0),153),(u=a.Zj())>1||-1==u)return BB(BB(r,215).hl(n,!1),76)}else if(n.$j())return BB((i=this.Yg(n))>=0?this._g(i,!1,!0):cOn(this,n,!1),76);return new CC(this,n)},MWn.yh=function(){return Q7(this)},MWn.zh=function(){return(QX(),t$t).S},MWn.Ah=function(){return bX(this.zh())},MWn.Bh=function(n){mPn(this,n)},MWn.Ib=function(){return P$n(this)},vX(l6n,"BasicEObjectImpl",97),wAn(114,97,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1}),MWn.Ch=function(n){return Y7(this)[n]},MWn.Dh=function(n,t){$X(Y7(this),n,t)},MWn.Eh=function(n){$X(Y7(this),n,null)},MWn.Jg=function(){return BB(yan(this,4),126)},MWn.Kg=function(){throw Hp(new pv)},MWn.Lg=function(){return 0!=(4&this.Db)},MWn.Pg=function(){throw Hp(new pv)},MWn.Fh=function(n){hgn(this,2,n)},MWn.Rg=function(n,t){this.Db=t<<16|255&this.Db,this.Fh(n)},MWn.Tg=function(){return jY(this)},MWn.Vg=function(){return this.Db>>16},MWn.Wg=function(){var n;return QM(),null==(n=lJ(qFn(BB(yan(this,16),26)||this.zh())))?N$t:new QN(this,n)},MWn.Mg=function(){return 0==(1&this.Db)},MWn.Zg=function(){return BB(yan(this,128),1935)},MWn.$g=function(){return BB(yan(this,16),26)},MWn.dh=function(){return 0!=(32&this.Db)},MWn.eh=function(){return BB(yan(this,2),49)},MWn.kh=function(){return 0!=(64&this.Db)},MWn.ph=function(){throw Hp(new pv)},MWn.qh=function(){return BB(yan(this,64),281)},MWn.th=function(n){hgn(this,16,n)},MWn.uh=function(n){hgn(this,128,n)},MWn.vh=function(n){hgn(this,64,n)},MWn.yh=function(){return fgn(this)},MWn.Db=0,vX(l6n,"MinimalEObjectImpl",114),wAn(115,114,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),MWn.Fh=function(n){this.Cb=n},MWn.eh=function(){return this.Cb},vX(l6n,"MinimalEObjectImpl/Container",115),wAn(1985,115,{105:1,413:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),MWn._g=function(n,t,e){return Eyn(this,n,t,e)},MWn.jh=function(n,t,e){return eSn(this,n,t,e)},MWn.lh=function(n){return m0(this,n)},MWn.sh=function(n,t){rsn(this,n,t)},MWn.zh=function(){return IXn(),POt},MWn.Bh=function(n){zun(this,n)},MWn.Ve=function(){return lpn(this)},MWn.We=function(n){return ZAn(this,n)},MWn.Xe=function(n){return P8(this,n)},MWn.Ye=function(n,t){return Ypn(this,n,t)},vX(b6n,"EMapPropertyHolderImpl",1985),wAn(567,115,{105:1,469:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},ro),MWn._g=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return Zpn(this,n,t,e)},MWn.lh=function(n){switch(n){case 0:return 0!=this.a;case 1:return 0!=this.b}return vpn(this,n)},MWn.sh=function(n,t){switch(n){case 0:return void jen(this,Gy(MD(t)));case 1:return void Een(this,Gy(MD(t)))}yIn(this,n,t)},MWn.zh=function(){return IXn(),pOt},MWn.Bh=function(n){switch(n){case 0:return void jen(this,0);case 1:return void Een(this,0)}mPn(this,n)},MWn.Ib=function(){var n;return 0!=(64&this.Db)?P$n(this):((n=new fN(P$n(this))).a+=" (x: ",vE(n,this.a),n.a+=", y: ",vE(n,this.b),n.a+=")",n.a)},MWn.a=0,MWn.b=0,vX(b6n,"ElkBendPointImpl",567),wAn(723,1985,{105:1,413:1,160:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),MWn._g=function(n,t,e){return Kfn(this,n,t,e)},MWn.hh=function(n,t,e){return FTn(this,n,t,e)},MWn.jh=function(n,t,e){return run(this,n,t,e)},MWn.lh=function(n){return Ean(this,n)},MWn.sh=function(n,t){Gjn(this,n,t)},MWn.zh=function(){return IXn(),kOt},MWn.Bh=function(n){ofn(this,n)},MWn.zg=function(){return this.k},MWn.Ag=function(){return mV(this)},MWn.Ib=function(){return Yln(this)},MWn.k=null,vX(b6n,"ElkGraphElementImpl",723),wAn(724,723,{105:1,413:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),MWn._g=function(n,t,e){return Rbn(this,n,t,e)},MWn.lh=function(n){return fwn(this,n)},MWn.sh=function(n,t){zjn(this,n,t)},MWn.zh=function(){return IXn(),SOt},MWn.Bh=function(n){Dwn(this,n)},MWn.Bg=function(){return this.f},MWn.Cg=function(){return this.g},MWn.Dg=function(){return this.i},MWn.Eg=function(){return this.j},MWn.Fg=function(n,t){MA(this,n,t)},MWn.Gg=function(n,t){SA(this,n,t)},MWn.Hg=function(n){Pen(this,n)},MWn.Ig=function(n){Ien(this,n)},MWn.Ib=function(){return mSn(this)},MWn.f=0,MWn.g=0,MWn.i=0,MWn.j=0,vX(b6n,"ElkShapeImpl",724),wAn(725,724,{105:1,413:1,82:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),MWn._g=function(n,t,e){return Hvn(this,n,t,e)},MWn.hh=function(n,t,e){return djn(this,n,t,e)},MWn.jh=function(n,t,e){return gjn(this,n,t,e)},MWn.lh=function(n){return Gon(this,n)},MWn.sh=function(n,t){LAn(this,n,t)},MWn.zh=function(){return IXn(),vOt},MWn.Bh=function(n){xpn(this,n)},MWn.xg=function(){return!this.d&&(this.d=new h_(KOt,this,8,5)),this.d},MWn.yg=function(){return!this.e&&(this.e=new h_(KOt,this,7,4)),this.e},vX(b6n,"ElkConnectableShapeImpl",725),wAn(352,723,{105:1,413:1,79:1,160:1,352:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},io),MWn.Qg=function(n){return Mkn(this,n)},MWn._g=function(n,t,e){switch(n){case 3:return XJ(this);case 4:return!this.b&&(this.b=new h_(_Ot,this,4,7)),this.b;case 5:return!this.c&&(this.c=new h_(_Ot,this,5,8)),this.c;case 6:return!this.a&&(this.a=new eU(FOt,this,6,6)),this.a;case 7:return hN(),!this.b&&(this.b=new h_(_Ot,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new h_(_Ot,this,5,8)),this.c.i<=1));case 8:return hN(),!!nAn(this);case 9:return hN(),!!QCn(this);case 10:return hN(),!this.b&&(this.b=new h_(_Ot,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new h_(_Ot,this,5,8)),0!=this.c.i)}return Kfn(this,n,t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?Mkn(this,e):this.Cb.ih(this,-1-i,null,e)),VD(this,BB(n,33),e);case 4:return!this.b&&(this.b=new h_(_Ot,this,4,7)),Ywn(this.b,n,e);case 5:return!this.c&&(this.c=new h_(_Ot,this,5,8)),Ywn(this.c,n,e);case 6:return!this.a&&(this.a=new eU(FOt,this,6,6)),Ywn(this.a,n,e)}return FTn(this,n,t,e)},MWn.jh=function(n,t,e){switch(t){case 3:return VD(this,null,e);case 4:return!this.b&&(this.b=new h_(_Ot,this,4,7)),Kpn(this.b,n,e);case 5:return!this.c&&(this.c=new h_(_Ot,this,5,8)),Kpn(this.c,n,e);case 6:return!this.a&&(this.a=new eU(FOt,this,6,6)),Kpn(this.a,n,e)}return run(this,n,t,e)},MWn.lh=function(n){switch(n){case 3:return!!XJ(this);case 4:return!!this.b&&0!=this.b.i;case 5:return!!this.c&&0!=this.c.i;case 6:return!!this.a&&0!=this.a.i;case 7:return!this.b&&(this.b=new h_(_Ot,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new h_(_Ot,this,5,8)),this.c.i<=1));case 8:return nAn(this);case 9:return QCn(this);case 10:return!this.b&&(this.b=new h_(_Ot,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new h_(_Ot,this,5,8)),0!=this.c.i)}return Ean(this,n)},MWn.sh=function(n,t){switch(n){case 3:return void HLn(this,BB(t,33));case 4:return!this.b&&(this.b=new h_(_Ot,this,4,7)),sqn(this.b),!this.b&&(this.b=new h_(_Ot,this,4,7)),void pX(this.b,BB(t,14));case 5:return!this.c&&(this.c=new h_(_Ot,this,5,8)),sqn(this.c),!this.c&&(this.c=new h_(_Ot,this,5,8)),void pX(this.c,BB(t,14));case 6:return!this.a&&(this.a=new eU(FOt,this,6,6)),sqn(this.a),!this.a&&(this.a=new eU(FOt,this,6,6)),void pX(this.a,BB(t,14))}Gjn(this,n,t)},MWn.zh=function(){return IXn(),mOt},MWn.Bh=function(n){switch(n){case 3:return void HLn(this,null);case 4:return!this.b&&(this.b=new h_(_Ot,this,4,7)),void sqn(this.b);case 5:return!this.c&&(this.c=new h_(_Ot,this,5,8)),void sqn(this.c);case 6:return!this.a&&(this.a=new eU(FOt,this,6,6)),void sqn(this.a)}ofn(this,n)},MWn.Ib=function(){return lHn(this)},vX(b6n,"ElkEdgeImpl",352),wAn(439,1985,{105:1,413:1,202:1,439:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},co),MWn.Qg=function(n){return skn(this,n)},MWn._g=function(n,t,e){switch(n){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return!this.a&&(this.a=new $L(xOt,this,5)),this.a;case 6:return VJ(this);case 7:return t?Pvn(this):this.i;case 8:return t?Svn(this):this.f;case 9:return!this.g&&(this.g=new h_(FOt,this,9,10)),this.g;case 10:return!this.e&&(this.e=new h_(FOt,this,10,9)),this.e;case 11:return this.d}return Eyn(this,n,t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?skn(this,e):this.Cb.ih(this,-1-i,null,e)),QD(this,BB(n,79),e);case 9:return!this.g&&(this.g=new h_(FOt,this,9,10)),Ywn(this.g,n,e);case 10:return!this.e&&(this.e=new h_(FOt,this,10,9)),Ywn(this.e,n,e)}return BB(itn(BB(yan(this,16),26)||(IXn(),yOt),t),66).Nj().Qj(this,fgn(this),t-bX((IXn(),yOt)),n,e)},MWn.jh=function(n,t,e){switch(t){case 5:return!this.a&&(this.a=new $L(xOt,this,5)),Kpn(this.a,n,e);case 6:return QD(this,null,e);case 9:return!this.g&&(this.g=new h_(FOt,this,9,10)),Kpn(this.g,n,e);case 10:return!this.e&&(this.e=new h_(FOt,this,10,9)),Kpn(this.e,n,e)}return eSn(this,n,t,e)},MWn.lh=function(n){switch(n){case 1:return 0!=this.j;case 2:return 0!=this.k;case 3:return 0!=this.b;case 4:return 0!=this.c;case 5:return!!this.a&&0!=this.a.i;case 6:return!!VJ(this);case 7:return!!this.i;case 8:return!!this.f;case 9:return!!this.g&&0!=this.g.i;case 10:return!!this.e&&0!=this.e.i;case 11:return null!=this.d}return m0(this,n)},MWn.sh=function(n,t){switch(n){case 1:return void Cen(this,Gy(MD(t)));case 2:return void Aen(this,Gy(MD(t)));case 3:return void Ten(this,Gy(MD(t)));case 4:return void Oen(this,Gy(MD(t)));case 5:return!this.a&&(this.a=new $L(xOt,this,5)),sqn(this.a),!this.a&&(this.a=new $L(xOt,this,5)),void pX(this.a,BB(t,14));case 6:return void FLn(this,BB(t,79));case 7:return void Nin(this,BB(t,82));case 8:return void Lin(this,BB(t,82));case 9:return!this.g&&(this.g=new h_(FOt,this,9,10)),sqn(this.g),!this.g&&(this.g=new h_(FOt,this,9,10)),void pX(this.g,BB(t,14));case 10:return!this.e&&(this.e=new h_(FOt,this,10,9)),sqn(this.e),!this.e&&(this.e=new h_(FOt,this,10,9)),void pX(this.e,BB(t,14));case 11:return void crn(this,SD(t))}rsn(this,n,t)},MWn.zh=function(){return IXn(),yOt},MWn.Bh=function(n){switch(n){case 1:return void Cen(this,0);case 2:return void Aen(this,0);case 3:return void Ten(this,0);case 4:return void Oen(this,0);case 5:return!this.a&&(this.a=new $L(xOt,this,5)),void sqn(this.a);case 6:return void FLn(this,null);case 7:return void Nin(this,null);case 8:return void Lin(this,null);case 9:return!this.g&&(this.g=new h_(FOt,this,9,10)),void sqn(this.g);case 10:return!this.e&&(this.e=new h_(FOt,this,10,9)),void sqn(this.e);case 11:return void crn(this,null)}zun(this,n)},MWn.Ib=function(){return ROn(this)},MWn.b=0,MWn.c=0,MWn.d=null,MWn.j=0,MWn.k=0,vX(b6n,"ElkEdgeSectionImpl",439),wAn(150,115,{105:1,92:1,90:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1}),MWn._g=function(n,t,e){return 0==n?(!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab):U9(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t,e)},MWn.hh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e)):BB(itn(BB(yan(this,16),26)||this.zh(),t),66).Nj().Qj(this,fgn(this),t-bX(this.zh()),n,e)},MWn.jh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e)):BB(itn(BB(yan(this,16),26)||this.zh(),t),66).Nj().Rj(this,fgn(this),t-bX(this.zh()),n,e)},MWn.lh=function(n){return 0==n?!!this.Ab&&0!=this.Ab.i:O3(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.oh=function(n){return hUn(this,n)},MWn.sh=function(n,t){if(0===n)return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));Lbn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t)},MWn.uh=function(n){hgn(this,128,n)},MWn.zh=function(){return gWn(),b$t},MWn.Bh=function(n){if(0===n)return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);qfn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.Gh=function(){this.Bb|=1},MWn.Hh=function(n){return NKn(this,n)},MWn.Bb=0,vX(l6n,"EModelElementImpl",150),wAn(704,150,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},Rf),MWn.Ih=function(n,t){return qGn(this,n,t)},MWn.Jh=function(n){var t,e,i,r;if(this.a!=Utn(n)||0!=(256&n.Bb))throw Hp(new Ky(m6n+n.zb+g6n));for(e=kY(n);0!=a4(e.a).i;){if(iyn(t=BB(eGn(e,0,cL(r=BB(Wtn(a4(e.a),0),87).c,88)?BB(r,26):(gWn(),d$t)),26)))return BB(i=Utn(t).Nh().Jh(t),49).th(n),i;e=kY(t)}return"java.util.Map$Entry"==(null!=n.D?n.D:n.B)?new fq(n):new jH(n)},MWn.Kh=function(n,t){return xXn(this,n,t)},MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.a}return U9(this,n-bX((gWn(),h$t)),itn(BB(yan(this,16),26)||h$t,n),t,e)},MWn.hh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 1:return this.a&&(e=BB(this.a,49).ih(this,4,GOt,e)),Jhn(this,BB(n,235),e)}return BB(itn(BB(yan(this,16),26)||(gWn(),h$t),t),66).Nj().Qj(this,fgn(this),t-bX((gWn(),h$t)),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 1:return Jhn(this,null,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),h$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),h$t)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return!!this.a}return O3(this,n-bX((gWn(),h$t)),itn(BB(yan(this,16),26)||h$t,n))},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void xMn(this,BB(t,235))}Lbn(this,n-bX((gWn(),h$t)),itn(BB(yan(this,16),26)||h$t,n),t)},MWn.zh=function(){return gWn(),h$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return void xMn(this,null)}qfn(this,n-bX((gWn(),h$t)),itn(BB(yan(this,16),26)||h$t,n))},vX(l6n,"EFactoryImpl",704),wAn(k6n,704,{105:1,2014:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},ao),MWn.Ih=function(n,t){switch(n.yj()){case 12:return BB(t,146).tg();case 13:return Bbn(t);default:throw Hp(new Ky(d6n+n.ne()+g6n))}},MWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Utn(n))?uvn(t.Mh(),n):-1),n.G){case 4:return new uo;case 6:return new jm;case 7:return new Em;case 8:return new io;case 9:return new ro;case 10:return new co;case 11:return new so;default:throw Hp(new Ky(m6n+n.zb+g6n))}},MWn.Kh=function(n,t){switch(n.yj()){case 13:case 12:return null;default:throw Hp(new Ky(d6n+n.ne()+g6n))}},vX(b6n,"ElkGraphFactoryImpl",k6n),wAn(438,150,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1}),MWn.Wg=function(){var n;return null==(n=lJ(qFn(BB(yan(this,16),26)||this.zh())))?(QM(),QM(),N$t):new Wx(this,n)},MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.ne()}return U9(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb}return O3(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void this.Lh(SD(t))}Lbn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t)},MWn.zh=function(){return gWn(),w$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return void this.Lh(null)}qfn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.ne=function(){return this.zb},MWn.Lh=function(n){Nrn(this,n)},MWn.Ib=function(){return kfn(this)},MWn.zb=null,vX(l6n,"ENamedElementImpl",438),wAn(179,438,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},vY),MWn.Qg=function(n){return wkn(this,n)},MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return!this.rb&&(this.rb=new Jz(this,HAt,this)),this.rb;case 6:return!this.vb&&(this.vb=new e_(GOt,this,6,7)),this.vb;case 7:return t?this.Db>>16==7?BB(this.Cb,235):null:QJ(this)}return U9(this,n-bX((gWn(),v$t)),itn(BB(yan(this,16),26)||v$t,n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 4:return this.sb&&(e=BB(this.sb,49).ih(this,1,HOt,e)),jfn(this,BB(n,471),e);case 5:return!this.rb&&(this.rb=new Jz(this,HAt,this)),Ywn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new e_(GOt,this,6,7)),Ywn(this.vb,n,e);case 7:return this.Cb&&(e=(i=this.Db>>16)>=0?wkn(this,e):this.Cb.ih(this,-1-i,null,e)),TKn(this,n,7,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),v$t),t),66).Nj().Qj(this,fgn(this),t-bX((gWn(),v$t)),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 4:return jfn(this,null,e);case 5:return!this.rb&&(this.rb=new Jz(this,HAt,this)),Kpn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new e_(GOt,this,6,7)),Kpn(this.vb,n,e);case 7:return TKn(this,null,7,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),v$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),v$t)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.yb;case 3:return null!=this.xb;case 4:return!!this.sb;case 5:return!!this.rb&&0!=this.rb.i;case 6:return!!this.vb&&0!=this.vb.i;case 7:return!!QJ(this)}return O3(this,n-bX((gWn(),v$t)),itn(BB(yan(this,16),26)||v$t,n))},MWn.oh=function(n){return LNn(this,n)||hUn(this,n)},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void Nrn(this,SD(t));case 2:return void Drn(this,SD(t));case 3:return void xrn(this,SD(t));case 4:return void iSn(this,BB(t,471));case 5:return!this.rb&&(this.rb=new Jz(this,HAt,this)),sqn(this.rb),!this.rb&&(this.rb=new Jz(this,HAt,this)),void pX(this.rb,BB(t,14));case 6:return!this.vb&&(this.vb=new e_(GOt,this,6,7)),sqn(this.vb),!this.vb&&(this.vb=new e_(GOt,this,6,7)),void pX(this.vb,BB(t,14))}Lbn(this,n-bX((gWn(),v$t)),itn(BB(yan(this,16),26)||v$t,n),t)},MWn.vh=function(n){var t,e;if(n&&this.rb)for(e=new AL(this.rb);e.e!=e.i.gc();)cL(t=kpn(e),351)&&(BB(t,351).w=null);hgn(this,64,n)},MWn.zh=function(){return gWn(),v$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return void Nrn(this,null);case 2:return void Drn(this,null);case 3:return void xrn(this,null);case 4:return void iSn(this,null);case 5:return!this.rb&&(this.rb=new Jz(this,HAt,this)),void sqn(this.rb);case 6:return!this.vb&&(this.vb=new e_(GOt,this,6,7)),void sqn(this.vb)}qfn(this,n-bX((gWn(),v$t)),itn(BB(yan(this,16),26)||v$t,n))},MWn.Gh=function(){Tyn(this)},MWn.Mh=function(){return!this.rb&&(this.rb=new Jz(this,HAt,this)),this.rb},MWn.Nh=function(){return this.sb},MWn.Oh=function(){return this.ub},MWn.Ph=function(){return this.xb},MWn.Qh=function(){return this.yb},MWn.Rh=function(n){this.ub=n},MWn.Ib=function(){var n;return 0!=(64&this.Db)?kfn(this):((n=new fN(kfn(this))).a+=" (nsURI: ",cO(n,this.yb),n.a+=", nsPrefix: ",cO(n,this.xb),n.a+=")",n.a)},MWn.xb=null,MWn.yb=null,vX(l6n,"EPackageImpl",179),wAn(555,179,{105:1,2016:1,555:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},sAn),MWn.q=!1,MWn.r=!1;var WOt=!1;vX(b6n,"ElkGraphPackageImpl",555),wAn(354,724,{105:1,413:1,160:1,137:1,470:1,354:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},uo),MWn.Qg=function(n){return hkn(this,n)},MWn._g=function(n,t,e){switch(n){case 7:return YJ(this);case 8:return this.a}return Rbn(this,n,t,e)},MWn.hh=function(n,t,e){var i;return 7===t?(this.Cb&&(e=(i=this.Db>>16)>=0?hkn(this,e):this.Cb.ih(this,-1-i,null,e)),VG(this,BB(n,160),e)):FTn(this,n,t,e)},MWn.jh=function(n,t,e){return 7==t?VG(this,null,e):run(this,n,t,e)},MWn.lh=function(n){switch(n){case 7:return!!YJ(this);case 8:return!m_("",this.a)}return fwn(this,n)},MWn.sh=function(n,t){switch(n){case 7:return void CNn(this,BB(t,160));case 8:return void xin(this,SD(t))}zjn(this,n,t)},MWn.zh=function(){return IXn(),jOt},MWn.Bh=function(n){switch(n){case 7:return void CNn(this,null);case 8:return void xin(this,"")}Dwn(this,n)},MWn.Ib=function(){return cPn(this)},MWn.a="",vX(b6n,"ElkLabelImpl",354),wAn(239,725,{105:1,413:1,82:1,160:1,33:1,470:1,239:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},jm),MWn.Qg=function(n){return Skn(this,n)},MWn._g=function(n,t,e){switch(n){case 9:return!this.c&&(this.c=new eU(XOt,this,9,9)),this.c;case 10:return!this.a&&(this.a=new eU(UOt,this,10,11)),this.a;case 11:return JJ(this);case 12:return!this.b&&(this.b=new eU(KOt,this,12,3)),this.b;case 13:return hN(),!this.a&&(this.a=new eU(UOt,this,10,11)),this.a.i>0}return Hvn(this,n,t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 9:return!this.c&&(this.c=new eU(XOt,this,9,9)),Ywn(this.c,n,e);case 10:return!this.a&&(this.a=new eU(UOt,this,10,11)),Ywn(this.a,n,e);case 11:return this.Cb&&(e=(i=this.Db>>16)>=0?Skn(this,e):this.Cb.ih(this,-1-i,null,e)),zR(this,BB(n,33),e);case 12:return!this.b&&(this.b=new eU(KOt,this,12,3)),Ywn(this.b,n,e)}return djn(this,n,t,e)},MWn.jh=function(n,t,e){switch(t){case 9:return!this.c&&(this.c=new eU(XOt,this,9,9)),Kpn(this.c,n,e);case 10:return!this.a&&(this.a=new eU(UOt,this,10,11)),Kpn(this.a,n,e);case 11:return zR(this,null,e);case 12:return!this.b&&(this.b=new eU(KOt,this,12,3)),Kpn(this.b,n,e)}return gjn(this,n,t,e)},MWn.lh=function(n){switch(n){case 9:return!!this.c&&0!=this.c.i;case 10:return!!this.a&&0!=this.a.i;case 11:return!!JJ(this);case 12:return!!this.b&&0!=this.b.i;case 13:return!this.a&&(this.a=new eU(UOt,this,10,11)),this.a.i>0}return Gon(this,n)},MWn.sh=function(n,t){switch(n){case 9:return!this.c&&(this.c=new eU(XOt,this,9,9)),sqn(this.c),!this.c&&(this.c=new eU(XOt,this,9,9)),void pX(this.c,BB(t,14));case 10:return!this.a&&(this.a=new eU(UOt,this,10,11)),sqn(this.a),!this.a&&(this.a=new eU(UOt,this,10,11)),void pX(this.a,BB(t,14));case 11:return void nNn(this,BB(t,33));case 12:return!this.b&&(this.b=new eU(KOt,this,12,3)),sqn(this.b),!this.b&&(this.b=new eU(KOt,this,12,3)),void pX(this.b,BB(t,14))}LAn(this,n,t)},MWn.zh=function(){return IXn(),EOt},MWn.Bh=function(n){switch(n){case 9:return!this.c&&(this.c=new eU(XOt,this,9,9)),void sqn(this.c);case 10:return!this.a&&(this.a=new eU(UOt,this,10,11)),void sqn(this.a);case 11:return void nNn(this,null);case 12:return!this.b&&(this.b=new eU(KOt,this,12,3)),void sqn(this.b)}xpn(this,n)},MWn.Ib=function(){return zRn(this)},vX(b6n,"ElkNodeImpl",239),wAn(186,725,{105:1,413:1,82:1,160:1,118:1,470:1,186:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},Em),MWn.Qg=function(n){return fkn(this,n)},MWn._g=function(n,t,e){return 9==n?WJ(this):Hvn(this,n,t,e)},MWn.hh=function(n,t,e){var i;return 9===t?(this.Cb&&(e=(i=this.Db>>16)>=0?fkn(this,e):this.Cb.ih(this,-1-i,null,e)),YD(this,BB(n,33),e)):djn(this,n,t,e)},MWn.jh=function(n,t,e){return 9==t?YD(this,null,e):gjn(this,n,t,e)},MWn.lh=function(n){return 9==n?!!WJ(this):Gon(this,n)},MWn.sh=function(n,t){9!==n?LAn(this,n,t):BLn(this,BB(t,33))},MWn.zh=function(){return IXn(),TOt},MWn.Bh=function(n){9!==n?xpn(this,n):BLn(this,null)},MWn.Ib=function(){return URn(this)},vX(b6n,"ElkPortImpl",186);var VOt=bq(B6n,"BasicEMap/Entry");wAn(1092,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,114:1,115:1},so),MWn.Fb=function(n){return this===n},MWn.cd=function(){return this.b},MWn.Hb=function(){return PN(this)},MWn.Uh=function(n){Din(this,BB(n,146))},MWn._g=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return Zpn(this,n,t,e)},MWn.lh=function(n){switch(n){case 0:return!!this.b;case 1:return null!=this.c}return vpn(this,n)},MWn.sh=function(n,t){switch(n){case 0:return void Din(this,BB(t,146));case 1:return void Kin(this,t)}yIn(this,n,t)},MWn.zh=function(){return IXn(),MOt},MWn.Bh=function(n){switch(n){case 0:return void Din(this,null);case 1:return void Kin(this,null)}mPn(this,n)},MWn.Sh=function(){var n;return-1==this.a&&(n=this.b,this.a=n?nsn(n):0),this.a},MWn.dd=function(){return this.c},MWn.Th=function(n){this.a=n},MWn.ed=function(n){var t;return t=this.c,Kin(this,n),t},MWn.Ib=function(){var n;return 0!=(64&this.Db)?P$n(this):(oO(oO(oO(n=new Ik,this.b?this.b.tg():zWn),e1n),kN(this.c)),n.a)},MWn.a=-1,MWn.c=null;var QOt,YOt,JOt,ZOt,nAt,tAt,eAt,iAt,rAt=vX(b6n,"ElkPropertyToValueMapEntryImpl",1092);wAn(984,1,{},lo),vX(G6n,"JsonAdapter",984),wAn(210,60,BVn,ek),vX(G6n,"JsonImportException",210),wAn(857,1,{},dkn),vX(G6n,"JsonImporter",857),wAn(891,1,{},aC),vX(G6n,"JsonImporter/lambda$0$Type",891),wAn(892,1,{},uC),vX(G6n,"JsonImporter/lambda$1$Type",892),wAn(900,1,{},$g),vX(G6n,"JsonImporter/lambda$10$Type",900),wAn(902,1,{},oC),vX(G6n,"JsonImporter/lambda$11$Type",902),wAn(903,1,{},sC),vX(G6n,"JsonImporter/lambda$12$Type",903),wAn(909,1,{},fQ),vX(G6n,"JsonImporter/lambda$13$Type",909),wAn(908,1,{},hQ),vX(G6n,"JsonImporter/lambda$14$Type",908),wAn(904,1,{},hC),vX(G6n,"JsonImporter/lambda$15$Type",904),wAn(905,1,{},fC),vX(G6n,"JsonImporter/lambda$16$Type",905),wAn(906,1,{},lC),vX(G6n,"JsonImporter/lambda$17$Type",906),wAn(907,1,{},bC),vX(G6n,"JsonImporter/lambda$18$Type",907),wAn(912,1,{},Lg),vX(G6n,"JsonImporter/lambda$19$Type",912),wAn(893,1,{},Ng),vX(G6n,"JsonImporter/lambda$2$Type",893),wAn(910,1,{},xg),vX(G6n,"JsonImporter/lambda$20$Type",910),wAn(911,1,{},Dg),vX(G6n,"JsonImporter/lambda$21$Type",911),wAn(915,1,{},Rg),vX(G6n,"JsonImporter/lambda$22$Type",915),wAn(913,1,{},_g),vX(G6n,"JsonImporter/lambda$23$Type",913),wAn(914,1,{},Kg),vX(G6n,"JsonImporter/lambda$24$Type",914),wAn(917,1,{},Fg),vX(G6n,"JsonImporter/lambda$25$Type",917),wAn(916,1,{},Bg),vX(G6n,"JsonImporter/lambda$26$Type",916),wAn(918,1,lVn,wC),MWn.td=function(n){E9(this.b,this.a,SD(n))},vX(G6n,"JsonImporter/lambda$27$Type",918),wAn(919,1,lVn,dC),MWn.td=function(n){T9(this.b,this.a,SD(n))},vX(G6n,"JsonImporter/lambda$28$Type",919),wAn(920,1,{},gC),vX(G6n,"JsonImporter/lambda$29$Type",920),wAn(896,1,{},Hg),vX(G6n,"JsonImporter/lambda$3$Type",896),wAn(921,1,{},pC),vX(G6n,"JsonImporter/lambda$30$Type",921),wAn(922,1,{},qg),vX(G6n,"JsonImporter/lambda$31$Type",922),wAn(923,1,{},Gg),vX(G6n,"JsonImporter/lambda$32$Type",923),wAn(924,1,{},zg),vX(G6n,"JsonImporter/lambda$33$Type",924),wAn(925,1,{},Ug),vX(G6n,"JsonImporter/lambda$34$Type",925),wAn(859,1,{},Xg),vX(G6n,"JsonImporter/lambda$35$Type",859),wAn(929,1,{},MB),vX(G6n,"JsonImporter/lambda$36$Type",929),wAn(926,1,lVn,Wg),MWn.td=function(n){Y4(this.a,BB(n,469))},vX(G6n,"JsonImporter/lambda$37$Type",926),wAn(927,1,lVn,SC),MWn.td=function(n){lO(this.a,this.b,BB(n,202))},vX(G6n,"JsonImporter/lambda$38$Type",927),wAn(928,1,lVn,PC),MWn.td=function(n){bO(this.a,this.b,BB(n,202))},vX(G6n,"JsonImporter/lambda$39$Type",928),wAn(894,1,{},Vg),vX(G6n,"JsonImporter/lambda$4$Type",894),wAn(930,1,lVn,Qg),MWn.td=function(n){J4(this.a,BB(n,8))},vX(G6n,"JsonImporter/lambda$40$Type",930),wAn(895,1,{},Yg),vX(G6n,"JsonImporter/lambda$5$Type",895),wAn(899,1,{},Jg),vX(G6n,"JsonImporter/lambda$6$Type",899),wAn(897,1,{},Zg),vX(G6n,"JsonImporter/lambda$7$Type",897),wAn(898,1,{},np),vX(G6n,"JsonImporter/lambda$8$Type",898),wAn(901,1,{},tp),vX(G6n,"JsonImporter/lambda$9$Type",901),wAn(948,1,lVn,ep),MWn.td=function(n){nW(this.a,new GX(SD(n)))},vX(G6n,"JsonMetaDataConverter/lambda$0$Type",948),wAn(949,1,lVn,ip),MWn.td=function(n){KX(this.a,BB(n,237))},vX(G6n,"JsonMetaDataConverter/lambda$1$Type",949),wAn(950,1,lVn,rp),MWn.td=function(n){t1(this.a,BB(n,149))},vX(G6n,"JsonMetaDataConverter/lambda$2$Type",950),wAn(951,1,lVn,cp),MWn.td=function(n){FX(this.a,BB(n,175))},vX(G6n,"JsonMetaDataConverter/lambda$3$Type",951),wAn(237,22,{3:1,35:1,22:1,237:1},MC);var cAt,aAt=Ben(CJn,"GraphFeature",237,Unt,_tn,pB);wAn(13,1,{35:1,146:1},up,iR,$O,XA),MWn.wd=function(n){return pL(this,BB(n,146))},MWn.Fb=function(n){return EY(this,n)},MWn.wg=function(){return mpn(this)},MWn.tg=function(){return this.b},MWn.Hb=function(){return vvn(this.b)},MWn.Ib=function(){return this.b},vX(CJn,"Property",13),wAn(818,1,MYn,ap),MWn.ue=function(n,t){return Kln(this,BB(n,94),BB(t,94))},MWn.Fb=function(n){return this===n},MWn.ve=function(){return new nw(this)},vX(CJn,"PropertyHolderComparator",818),wAn(695,1,QWn,sp),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return A9(this)},MWn.Qb=function(){uE()},MWn.Ob=function(){return!!this.a},vX(c8n,"ElkGraphUtil/AncestorIterator",695);var uAt=bq(B6n,"EList");wAn(67,52,{20:1,28:1,52:1,14:1,15:1,67:1,58:1}),MWn.Vc=function(n,t){sln(this,n,t)},MWn.Fc=function(n){return f9(this,n)},MWn.Wc=function(n,t){return oon(this,n,t)},MWn.Gc=function(n){return pX(this,n)},MWn.Zh=function(){return new ax(this)},MWn.$h=function(){return new ux(this)},MWn._h=function(n){return sin(this,n)},MWn.ai=function(){return!0},MWn.bi=function(n,t){},MWn.ci=function(){},MWn.di=function(n,t){L8(this,n,t)},MWn.ei=function(n,t,e){},MWn.fi=function(n,t){},MWn.gi=function(n,t,e){},MWn.Fb=function(n){return QDn(this,n)},MWn.Hb=function(){return Mun(this)},MWn.hi=function(){return!1},MWn.Kc=function(){return new AL(this)},MWn.Yc=function(){return new cx(this)},MWn.Zc=function(n){var t;if(t=this.gc(),n<0||n>t)throw Hp(new t_(n,t));return new GU(this,n)},MWn.ji=function(n,t){this.ii(n,this.Xc(t))},MWn.Mc=function(n){return snn(this,n)},MWn.li=function(n,t){return t},MWn._c=function(n,t){return ovn(this,n,t)},MWn.Ib=function(){return Jbn(this)},MWn.ni=function(){return!0},MWn.oi=function(n,t){return xsn(this,t)},vX(B6n,"AbstractEList",67),wAn(63,67,h8n,go,gtn,jcn),MWn.Vh=function(n,t){return BTn(this,n,t)},MWn.Wh=function(n){return bmn(this,n)},MWn.Xh=function(n,t){Cfn(this,n,t)},MWn.Yh=function(n){c6(this,n)},MWn.pi=function(n){return F9(this,n)},MWn.$b=function(){a6(this)},MWn.Hc=function(n){return Sjn(this,n)},MWn.Xb=function(n){return Wtn(this,n)},MWn.qi=function(n){var t,e,i;++this.j,n>(e=null==this.g?0:this.g.length)&&(i=this.g,(t=e+(e/2|0)+4)<n&&(t=n),this.g=this.ri(t),null!=i&&aHn(i,0,this.g,0,this.i))},MWn.Xc=function(n){return Wyn(this,n)},MWn.dc=function(){return 0==this.i},MWn.ii=function(n,t){return YCn(this,n,t)},MWn.ri=function(n){return x8(Ant,HWn,1,n,5,1)},MWn.ki=function(n){return this.g[n]},MWn.$c=function(n){return Lyn(this,n)},MWn.mi=function(n,t){return onn(this,n,t)},MWn.gc=function(){return this.i},MWn.Pc=function(){return N3(this)},MWn.Qc=function(n){return Qwn(this,n)},MWn.i=0;var oAt=vX(B6n,"BasicEList",63),sAt=bq(B6n,"TreeIterator");wAn(694,63,f8n),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return null!=this.g||this.c?null==this.g||0!=this.i&&BB(this.g[this.i-1],47).Ob():tZ(this)},MWn.Pb=function(){return aLn(this)},MWn.Qb=function(){if(!this.e)throw Hp(new Fy("There is no valid object to remove."));this.e.Qb()},MWn.c=!1,vX(B6n,"AbstractTreeIterator",694),wAn(685,694,f8n,OA),MWn.si=function(n){var t;return cL(t=BB(n,56).Wg().Kc(),279)&&BB(t,279).Nk(new bo),t},vX(c8n,"ElkGraphUtil/PropertiesSkippingTreeIterator",685),wAn(952,1,{},bo),vX(c8n,"ElkGraphUtil/PropertiesSkippingTreeIterator/1",952);var hAt,fAt,lAt,bAt=vX(c8n,"ElkReflect",null);wAn(889,1,i5n,wo),MWn.vg=function(n){return hZ(),B6(BB(n,174))},vX(c8n,"ElkReflect/lambda$0$Type",889),bq(B6n,"ResourceLocator"),wAn(1051,1,{}),vX(B6n,"DelegatingResourceLocator",1051),wAn(1052,1051,{}),vX("org.eclipse.emf.common","EMFPlugin",1052);var wAt,dAt=bq(J8n,"Adapter"),gAt=bq(J8n,"Notification");wAn(1153,1,Z8n),MWn.ti=function(){return this.d},MWn.ui=function(n){},MWn.vi=function(n){this.d=n},MWn.wi=function(n){this.d==n&&(this.d=null)},MWn.d=null,vX(i6n,"AdapterImpl",1153),wAn(1995,67,n9n),MWn.Vh=function(n,t){return kwn(this,n,t)},MWn.Wh=function(n){var t,e,i;if(++this.j,n.dc())return!1;for(t=this.Vi(),i=n.Kc();i.Ob();)e=i.Pb(),this.Ii(this.oi(t,e)),++t;return!0},MWn.Xh=function(n,t){ZD(this,n,t)},MWn.Yh=function(n){eW(this,n)},MWn.Gi=function(){return this.Ji()},MWn.$b=function(){JD(this,this.Vi(),this.Wi())},MWn.Hc=function(n){return this.Li(n)},MWn.Ic=function(n){return this.Mi(n)},MWn.Hi=function(n,t){this.Si().jm()},MWn.Ii=function(n){this.Si().jm()},MWn.Ji=function(){return this.Si()},MWn.Ki=function(){this.Si().jm()},MWn.Li=function(n){return this.Si().jm()},MWn.Mi=function(n){return this.Si().jm()},MWn.Ni=function(n){return this.Si().jm()},MWn.Oi=function(n){return this.Si().jm()},MWn.Pi=function(){return this.Si().jm()},MWn.Qi=function(n){return this.Si().jm()},MWn.Ri=function(){return this.Si().jm()},MWn.Ti=function(n){return this.Si().jm()},MWn.Ui=function(n,t){return this.Si().jm()},MWn.Vi=function(){return this.Si().jm()},MWn.Wi=function(){return this.Si().jm()},MWn.Xi=function(n){return this.Si().jm()},MWn.Yi=function(){return this.Si().jm()},MWn.Fb=function(n){return this.Ni(n)},MWn.Xb=function(n){return this.li(n,this.Oi(n))},MWn.Hb=function(){return this.Pi()},MWn.Xc=function(n){return this.Qi(n)},MWn.dc=function(){return this.Ri()},MWn.ii=function(n,t){return AMn(this,n,t)},MWn.ki=function(n){return this.Oi(n)},MWn.$c=function(n){return wq(this,n)},MWn.Mc=function(n){var t;return(t=this.Xc(n))>=0&&(this.$c(t),!0)},MWn.mi=function(n,t){return this.Ui(n,this.oi(n,t))},MWn.gc=function(){return this.Vi()},MWn.Pc=function(){return this.Wi()},MWn.Qc=function(n){return this.Xi(n)},MWn.Ib=function(){return this.Yi()},vX(B6n,"DelegatingEList",1995),wAn(1996,1995,n9n),MWn.Vh=function(n,t){return uFn(this,n,t)},MWn.Wh=function(n){return this.Vh(this.Vi(),n)},MWn.Xh=function(n,t){eAn(this,n,t)},MWn.Yh=function(n){OOn(this,n)},MWn.ai=function(){return!this.bj()},MWn.$b=function(){vqn(this)},MWn.Zi=function(n,t,e,i,r){return new NY(this,n,t,e,i,r)},MWn.$i=function(n){ban(this.Ai(),n)},MWn._i=function(){return null},MWn.aj=function(){return-1},MWn.Ai=function(){return null},MWn.bj=function(){return!1},MWn.cj=function(n,t){return t},MWn.dj=function(n,t){return t},MWn.ej=function(){return!1},MWn.fj=function(){return!this.Ri()},MWn.ii=function(n,t){var e,i;return this.ej()?(i=this.fj(),e=AMn(this,n,t),this.$i(this.Zi(7,iln(t),e,n,i)),e):AMn(this,n,t)},MWn.$c=function(n){var t,e,i,r;return this.ej()?(e=null,i=this.fj(),t=this.Zi(4,r=wq(this,n),null,n,i),this.bj()&&r?(e=this.dj(r,e))?(e.Ei(t),e.Fi()):this.$i(t):e?(e.Ei(t),e.Fi()):this.$i(t),r):(r=wq(this,n),this.bj()&&r&&(e=this.dj(r,null))&&e.Fi(),r)},MWn.mi=function(n,t){return oFn(this,n,t)},vX(i6n,"DelegatingNotifyingListImpl",1996),wAn(143,1,t9n),MWn.Ei=function(n){return _En(this,n)},MWn.Fi=function(){$7(this)},MWn.xi=function(){return this.d},MWn._i=function(){return null},MWn.gj=function(){return null},MWn.yi=function(n){return-1},MWn.zi=function(){return Rxn(this)},MWn.Ai=function(){return null},MWn.Bi=function(){return _xn(this)},MWn.Ci=function(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o},MWn.hj=function(){return!1},MWn.Di=function(n){var t,e,i,r,c,a,u,o;switch(this.d){case 1:case 2:switch(n.xi()){case 1:case 2:if(GC(n.Ai())===GC(this.Ai())&&this.yi(null)==n.yi(null))return this.g=n.zi(),1==n.xi()&&(this.d=1),!0}case 4:if(4===n.xi()&&GC(n.Ai())===GC(this.Ai())&&this.yi(null)==n.yi(null))return a=tGn(this),c=this.o<0?this.o<-2?-2-this.o-1:-1:this.o,i=n.Ci(),this.d=6,o=new gtn(2),c<=i?(f9(o,this.n),f9(o,n.Bi()),this.g=Pun(Gk(ANt,1),hQn,25,15,[this.o=c,i+1])):(f9(o,n.Bi()),f9(o,this.n),this.g=Pun(Gk(ANt,1),hQn,25,15,[this.o=i,c])),this.n=o,a||(this.o=-2-this.o-1),!0;break;case 6:if(4===n.xi()&&GC(n.Ai())===GC(this.Ai())&&this.yi(null)==n.yi(null)){for(a=tGn(this),i=n.Ci(),u=BB(this.g,48),e=x8(ANt,hQn,25,u.length+1,15,1),t=0;t<u.length&&(r=u[t])<=i;)e[t++]=r,++i;for(BB(this.n,15).Vc(t,n.Bi()),e[t]=i;++t<e.length;)e[t]=u[t-1];return this.g=e,a||(this.o=-2-e[0]),!0}}return!1},MWn.Ib=function(){var n,t,e;switch((e=new fN(nE(this.gm)+"@"+(nsn(this)>>>0).toString(16))).a+=" (eventType: ",this.d){case 1:e.a+="SET";break;case 2:e.a+="UNSET";break;case 3:e.a+="ADD";break;case 5:e.a+="ADD_MANY";break;case 4:e.a+="REMOVE";break;case 6:e.a+="REMOVE_MANY";break;case 7:e.a+="MOVE";break;case 8:e.a+="REMOVING_ADAPTER";break;case 9:e.a+="RESOLVE";break;default:mE(e,this.d)}if(l_n(this)&&(e.a+=", touch: true"),e.a+=", position: ",mE(e,this.o<0?this.o<-2?-2-this.o-1:-1:this.o),e.a+=", notifier: ",rO(e,this.Ai()),e.a+=", feature: ",rO(e,this._i()),e.a+=", oldValue: ",rO(e,_xn(this)),e.a+=", newValue: ",6==this.d&&cL(this.g,48)){for(t=BB(this.g,48),e.a+="[",n=0;n<t.length;)e.a+=t[n],++n<t.length&&(e.a+=FWn);e.a+="]"}else rO(e,Rxn(this));return e.a+=", isTouch: ",yE(e,l_n(this)),e.a+=", wasSet: ",yE(e,tGn(this)),e.a+=")",e.a},MWn.d=0,MWn.e=0,MWn.f=0,MWn.j=0,MWn.k=0,MWn.o=0,MWn.p=0,vX(i6n,"NotificationImpl",143),wAn(1167,143,t9n,NY),MWn._i=function(){return this.a._i()},MWn.yi=function(n){return this.a.aj()},MWn.Ai=function(){return this.a.Ai()},vX(i6n,"DelegatingNotifyingListImpl/1",1167),wAn(242,63,h8n,po,Fj),MWn.Fc=function(n){return Mwn(this,BB(n,366))},MWn.Ei=function(n){return Mwn(this,n)},MWn.Fi=function(){var n,t,e;for(n=0;n<this.i;++n)null!=(e=(t=BB(this.g[n],366)).Ai())&&-1!=t.xi()&&BB(e,92).Ng(t)},MWn.ri=function(n){return x8(gAt,HWn,366,n,0,1)},vX(i6n,"NotificationChainImpl",242),wAn(1378,90,e6n),MWn.Kg=function(){return this.e},MWn.Mg=function(){return 0!=(1&this.f)},MWn.f=1,vX(i6n,"NotifierImpl",1378),wAn(1993,63,h8n),MWn.Vh=function(n,t){return LFn(this,n,t)},MWn.Wh=function(n){return this.Vh(this.i,n)},MWn.Xh=function(n,t){qOn(this,n,t)},MWn.Yh=function(n){tAn(this,n)},MWn.ai=function(){return!this.bj()},MWn.$b=function(){sqn(this)},MWn.Zi=function(n,t,e,i,r){return new xY(this,n,t,e,i,r)},MWn.$i=function(n){ban(this.Ai(),n)},MWn._i=function(){return null},MWn.aj=function(){return-1},MWn.Ai=function(){return null},MWn.bj=function(){return!1},MWn.ij=function(){return!1},MWn.cj=function(n,t){return t},MWn.dj=function(n,t){return t},MWn.ej=function(){return!1},MWn.fj=function(){return 0!=this.i},MWn.ii=function(n,t){return Cln(this,n,t)},MWn.$c=function(n){return fDn(this,n)},MWn.mi=function(n,t){return fBn(this,n,t)},MWn.jj=function(n,t){return t},MWn.kj=function(n,t){return t},MWn.lj=function(n,t,e){return e},vX(i6n,"NotifyingListImpl",1993),wAn(1166,143,t9n,xY),MWn._i=function(){return this.a._i()},MWn.yi=function(n){return this.a.aj()},MWn.Ai=function(){return this.a.Ai()},vX(i6n,"NotifyingListImpl/1",1166),wAn(953,63,h8n,aR),MWn.Hc=function(n){return this.i>10?(this.b&&this.c.j==this.a||(this.b=new $q(this),this.a=this.j),FT(this.b,n)):Sjn(this,n)},MWn.ni=function(){return!0},MWn.a=0,vX(B6n,"AbstractEList/1",953),wAn(295,73,NQn,t_),vX(B6n,"AbstractEList/BasicIndexOutOfBoundsException",295),wAn(40,1,QWn,AL),MWn.Nb=function(n){fU(this,n)},MWn.mj=function(){if(this.i.j!=this.f)throw Hp(new vv)},MWn.nj=function(){return kpn(this)},MWn.Ob=function(){return this.e!=this.i.gc()},MWn.Pb=function(){return this.nj()},MWn.Qb=function(){Qjn(this)},MWn.e=0,MWn.f=0,MWn.g=-1,vX(B6n,"AbstractEList/EIterator",40),wAn(278,40,cVn,cx,GU),MWn.Qb=function(){Qjn(this)},MWn.Rb=function(n){odn(this,n)},MWn.oj=function(){var n;try{return n=this.d.Xb(--this.e),this.mj(),this.g=this.e,n}catch(t){throw cL(t=lun(t),73)?(this.mj(),Hp(new yv)):Hp(t)}},MWn.pj=function(n){kmn(this,n)},MWn.Sb=function(){return 0!=this.e},MWn.Tb=function(){return this.e},MWn.Ub=function(){return this.oj()},MWn.Vb=function(){return this.e-1},MWn.Wb=function(n){this.pj(n)},vX(B6n,"AbstractEList/EListIterator",278),wAn(341,40,QWn,ax),MWn.nj=function(){return jpn(this)},MWn.Qb=function(){throw Hp(new pv)},vX(B6n,"AbstractEList/NonResolvingEIterator",341),wAn(385,278,cVn,ux,R_),MWn.Rb=function(n){throw Hp(new pv)},MWn.nj=function(){var n;try{return n=this.c.ki(this.e),this.mj(),this.g=this.e++,n}catch(t){throw cL(t=lun(t),73)?(this.mj(),Hp(new yv)):Hp(t)}},MWn.oj=function(){var n;try{return n=this.c.ki(--this.e),this.mj(),this.g=this.e,n}catch(t){throw cL(t=lun(t),73)?(this.mj(),Hp(new yv)):Hp(t)}},MWn.Qb=function(){throw Hp(new pv)},MWn.Wb=function(n){throw Hp(new pv)},vX(B6n,"AbstractEList/NonResolvingEListIterator",385),wAn(1982,67,r9n),MWn.Vh=function(n,t){var e,i,r,c,a,u,o,s,h;if(0!=(i=t.gc())){for(e=Psn(this,(s=null==(o=BB(yan(this.a,4),126))?0:o.length)+i),(h=s-n)>0&&aHn(o,n,e,n+i,h),u=t.Kc(),c=0;c<i;++c)JA(e,n+c,xsn(this,a=u.Pb()));for(Fgn(this,e),r=0;r<i;++r)a=e[n],this.bi(n,a),++n;return!0}return++this.j,!1},MWn.Wh=function(n){var t,e,i,r,c,a,u,o,s;if(0!=(i=n.gc())){for(t=Psn(this,s=(o=null==(e=BB(yan(this.a,4),126))?0:e.length)+i),u=n.Kc(),c=o;c<s;++c)JA(t,c,xsn(this,a=u.Pb()));for(Fgn(this,t),r=o;r<s;++r)a=t[r],this.bi(r,a);return!0}return++this.j,!1},MWn.Xh=function(n,t){var e,i,r,c;e=Psn(this,(r=null==(i=BB(yan(this.a,4),126))?0:i.length)+1),c=xsn(this,t),n!=r&&aHn(i,n,e,n+1,r-n),$X(e,n,c),Fgn(this,e),this.bi(n,t)},MWn.Yh=function(n){var t,e,i;JA(t=Psn(this,(i=null==(e=BB(yan(this.a,4),126))?0:e.length)+1),i,xsn(this,n)),Fgn(this,t),this.bi(i,n)},MWn.Zh=function(){return new S5(this)},MWn.$h=function(){return new Yz(this)},MWn._h=function(n){var t,e;if(e=null==(t=BB(yan(this.a,4),126))?0:t.length,n<0||n>e)throw Hp(new t_(n,e));return new BW(this,n)},MWn.$b=function(){var n,t;++this.j,t=null==(n=BB(yan(this.a,4),126))?0:n.length,Fgn(this,null),L8(this,t,n)},MWn.Hc=function(n){var t,e,i,r;if(null!=(t=BB(yan(this.a,4),126)))if(null!=n){for(i=0,r=(e=t).length;i<r;++i)if(Nfn(n,e[i]))return!0}else for(i=0,r=(e=t).length;i<r;++i)if(GC(e[i])===GC(n))return!0;return!1},MWn.Xb=function(n){var t,e;if(n>=(e=null==(t=BB(yan(this.a,4),126))?0:t.length))throw Hp(new t_(n,e));return t[n]},MWn.Xc=function(n){var t,e,i;if(null!=(t=BB(yan(this.a,4),126)))if(null!=n){for(e=0,i=t.length;e<i;++e)if(Nfn(n,t[e]))return e}else for(e=0,i=t.length;e<i;++e)if(GC(t[e])===GC(n))return e;return-1},MWn.dc=function(){return null==BB(yan(this.a,4),126)},MWn.Kc=function(){return new M5(this)},MWn.Yc=function(){return new Qz(this)},MWn.Zc=function(n){var t,e;if(e=null==(t=BB(yan(this.a,4),126))?0:t.length,n<0||n>e)throw Hp(new t_(n,e));return new FW(this,n)},MWn.ii=function(n,t){var e,i,r;if(n>=(r=null==(e=$dn(this))?0:e.length))throw Hp(new Ay(u8n+n+o8n+r));if(t>=r)throw Hp(new Ay(s8n+t+o8n+r));return i=e[t],n!=t&&(n<t?aHn(e,n,e,n+1,t-n):aHn(e,t+1,e,t,n-t),$X(e,n,i),Fgn(this,e)),i},MWn.ki=function(n){return BB(yan(this.a,4),126)[n]},MWn.$c=function(n){return EOn(this,n)},MWn.mi=function(n,t){var e,i;return i=(e=$dn(this))[n],JA(e,n,xsn(this,t)),Fgn(this,e),i},MWn.gc=function(){var n;return null==(n=BB(yan(this.a,4),126))?0:n.length},MWn.Pc=function(){var n,t,e;return e=null==(n=BB(yan(this.a,4),126))?0:n.length,t=x8(dAt,i9n,415,e,0,1),e>0&&aHn(n,0,t,0,e),t},MWn.Qc=function(n){var t,e;return(e=null==(t=BB(yan(this.a,4),126))?0:t.length)>0&&(n.length<e&&(n=Den(tsn(n).c,e)),aHn(t,0,n,0,e)),n.length>e&&$X(n,e,null),n},vX(B6n,"ArrayDelegatingEList",1982),wAn(1038,40,QWn,M5),MWn.mj=function(){if(this.b.j!=this.f||GC(BB(yan(this.b.a,4),126))!==GC(this.a))throw Hp(new vv)},MWn.Qb=function(){Qjn(this),this.a=BB(yan(this.b.a,4),126)},vX(B6n,"ArrayDelegatingEList/EIterator",1038),wAn(706,278,cVn,Qz,FW),MWn.mj=function(){if(this.b.j!=this.f||GC(BB(yan(this.b.a,4),126))!==GC(this.a))throw Hp(new vv)},MWn.pj=function(n){kmn(this,n),this.a=BB(yan(this.b.a,4),126)},MWn.Qb=function(){Qjn(this),this.a=BB(yan(this.b.a,4),126)},vX(B6n,"ArrayDelegatingEList/EListIterator",706),wAn(1039,341,QWn,S5),MWn.mj=function(){if(this.b.j!=this.f||GC(BB(yan(this.b.a,4),126))!==GC(this.a))throw Hp(new vv)},vX(B6n,"ArrayDelegatingEList/NonResolvingEIterator",1039),wAn(707,385,cVn,Yz,BW),MWn.mj=function(){if(this.b.j!=this.f||GC(BB(yan(this.b.a,4),126))!==GC(this.a))throw Hp(new vv)},vX(B6n,"ArrayDelegatingEList/NonResolvingEListIterator",707),wAn(606,295,NQn,LO),vX(B6n,"BasicEList/BasicIndexOutOfBoundsException",606),wAn(696,63,h8n,DC),MWn.Vc=function(n,t){throw Hp(new pv)},MWn.Fc=function(n){throw Hp(new pv)},MWn.Wc=function(n,t){throw Hp(new pv)},MWn.Gc=function(n){throw Hp(new pv)},MWn.$b=function(){throw Hp(new pv)},MWn.qi=function(n){throw Hp(new pv)},MWn.Kc=function(){return this.Zh()},MWn.Yc=function(){return this.$h()},MWn.Zc=function(n){return this._h(n)},MWn.ii=function(n,t){throw Hp(new pv)},MWn.ji=function(n,t){throw Hp(new pv)},MWn.$c=function(n){throw Hp(new pv)},MWn.Mc=function(n){throw Hp(new pv)},MWn._c=function(n,t){throw Hp(new pv)},vX(B6n,"BasicEList/UnmodifiableEList",696),wAn(705,1,{3:1,20:1,14:1,15:1,58:1,589:1}),MWn.Vc=function(n,t){Q$(this,n,BB(t,42))},MWn.Fc=function(n){return aD(this,BB(n,42))},MWn.Jc=function(n){e5(this,n)},MWn.Xb=function(n){return BB(Wtn(this.c,n),133)},MWn.ii=function(n,t){return BB(this.c.ii(n,t),42)},MWn.ji=function(n,t){Y$(this,n,BB(t,42))},MWn.Lc=function(){return new Rq(null,new w1(this,16))},MWn.$c=function(n){return BB(this.c.$c(n),42)},MWn._c=function(n,t){return uX(this,n,BB(t,42))},MWn.ad=function(n){Krn(this,n)},MWn.Nc=function(){return new w1(this,16)},MWn.Oc=function(){return new Rq(null,new w1(this,16))},MWn.Wc=function(n,t){return this.c.Wc(n,t)},MWn.Gc=function(n){return this.c.Gc(n)},MWn.$b=function(){this.c.$b()},MWn.Hc=function(n){return this.c.Hc(n)},MWn.Ic=function(n){return oun(this.c,n)},MWn.qj=function(){var n,t;if(null==this.d){for(this.d=x8(oAt,c9n,63,2*this.f+1,0,1),t=this.e,this.f=0,n=this.c.Kc();n.e!=n.i.gc();)Cvn(this,BB(n.nj(),133));this.e=t}},MWn.Fb=function(n){return N_(this,n)},MWn.Hb=function(){return Mun(this.c)},MWn.Xc=function(n){return this.c.Xc(n)},MWn.rj=function(){this.c=new hp(this)},MWn.dc=function(){return 0==this.f},MWn.Kc=function(){return this.c.Kc()},MWn.Yc=function(){return this.c.Yc()},MWn.Zc=function(n){return this.c.Zc(n)},MWn.sj=function(){return A8(this)},MWn.tj=function(n,t,e){return new SB(n,t,e)},MWn.uj=function(){return new vo},MWn.Mc=function(n){return hin(this,n)},MWn.gc=function(){return this.f},MWn.bd=function(n,t){return new s1(this.c,n,t)},MWn.Pc=function(){return this.c.Pc()},MWn.Qc=function(n){return this.c.Qc(n)},MWn.Ib=function(){return Jbn(this.c)},MWn.e=0,MWn.f=0,vX(B6n,"BasicEMap",705),wAn(1033,63,h8n,hp),MWn.bi=function(n,t){Av(this,BB(t,133))},MWn.ei=function(n,t,e){var i;++(i=this,BB(t,133),i).a.e},MWn.fi=function(n,t){$v(this,BB(t,133))},MWn.gi=function(n,t,e){VN(this,BB(t,133),BB(e,133))},MWn.di=function(n,t){aan(this.a)},vX(B6n,"BasicEMap/1",1033),wAn(1034,63,h8n,vo),MWn.ri=function(n){return x8(vAt,a9n,612,n,0,1)},vX(B6n,"BasicEMap/2",1034),wAn(1035,nVn,tVn,fp),MWn.$b=function(){this.a.c.$b()},MWn.Hc=function(n){return rdn(this.a,n)},MWn.Kc=function(){return 0==this.a.f?(dD(),pAt.a):new Bj(this.a)},MWn.Mc=function(n){var t;return t=this.a.f,Wdn(this.a,n),this.a.f!=t},MWn.gc=function(){return this.a.f},vX(B6n,"BasicEMap/3",1035),wAn(1036,28,ZWn,lp),MWn.$b=function(){this.a.c.$b()},MWn.Hc=function(n){return YDn(this.a,n)},MWn.Kc=function(){return 0==this.a.f?(dD(),pAt.a):new Hj(this.a)},MWn.gc=function(){return this.a.f},vX(B6n,"BasicEMap/4",1036),wAn(1037,nVn,tVn,bp),MWn.$b=function(){this.a.c.$b()},MWn.Hc=function(n){var t,e,i,r,c,a,u,o,s;if(this.a.f>0&&cL(n,42)&&(this.a.qj(),r=null==(u=(o=BB(n,42)).cd())?0:nsn(u),c=eR(this.a,r),t=this.a.d[c]))for(e=BB(t.g,367),s=t.i,a=0;a<s;++a)if((i=e[a]).Sh()==r&&i.Fb(o))return!0;return!1},MWn.Kc=function(){return 0==this.a.f?(dD(),pAt.a):new pQ(this.a)},MWn.Mc=function(n){return CAn(this,n)},MWn.gc=function(){return this.a.f},vX(B6n,"BasicEMap/5",1037),wAn(613,1,QWn,pQ),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return-1!=this.b},MWn.Pb=function(){var n;if(this.f.e!=this.c)throw Hp(new vv);if(-1==this.b)throw Hp(new yv);return this.d=this.a,this.e=this.b,ujn(this),n=BB(this.f.d[this.d].g[this.e],133),this.vj(n)},MWn.Qb=function(){if(this.f.e!=this.c)throw Hp(new vv);if(-1==this.e)throw Hp(new dv);this.f.c.Mc(Wtn(this.f.d[this.d],this.e)),this.c=this.f.e,this.e=-1,this.a==this.d&&-1!=this.b&&--this.b},MWn.vj=function(n){return n},MWn.a=0,MWn.b=-1,MWn.c=0,MWn.d=0,MWn.e=0,vX(B6n,"BasicEMap/BasicEMapIterator",613),wAn(1031,613,QWn,Bj),MWn.vj=function(n){return n.cd()},vX(B6n,"BasicEMap/BasicEMapKeyIterator",1031),wAn(1032,613,QWn,Hj),MWn.vj=function(n){return n.dd()},vX(B6n,"BasicEMap/BasicEMapValueIterator",1032),wAn(1030,1,JWn,wp),MWn.wc=function(n){nan(this,n)},MWn.yc=function(n,t,e){return Zln(this,n,t,e)},MWn.$b=function(){this.a.c.$b()},MWn._b=function(n){return BC(this,n)},MWn.uc=function(n){return YDn(this.a,n)},MWn.vc=function(){return C8(this.a)},MWn.Fb=function(n){return N_(this.a,n)},MWn.xc=function(n){return cdn(this.a,n)},MWn.Hb=function(){return Mun(this.a.c)},MWn.dc=function(){return 0==this.a.f},MWn.ec=function(){return O8(this.a)},MWn.zc=function(n,t){return vjn(this.a,n,t)},MWn.Bc=function(n){return Wdn(this.a,n)},MWn.gc=function(){return this.a.f},MWn.Ib=function(){return Jbn(this.a.c)},MWn.Cc=function(){return I8(this.a)},vX(B6n,"BasicEMap/DelegatingMap",1030),wAn(612,1,{42:1,133:1,612:1},SB),MWn.Fb=function(n){var t;return!!cL(n,42)&&(t=BB(n,42),(null!=this.b?Nfn(this.b,t.cd()):GC(this.b)===GC(t.cd()))&&(null!=this.c?Nfn(this.c,t.dd()):GC(this.c)===GC(t.dd())))},MWn.Sh=function(){return this.a},MWn.cd=function(){return this.b},MWn.dd=function(){return this.c},MWn.Hb=function(){return this.a^(null==this.c?0:nsn(this.c))},MWn.Th=function(n){this.a=n},MWn.Uh=function(n){throw Hp(new sv)},MWn.ed=function(n){var t;return t=this.c,this.c=n,t},MWn.Ib=function(){return this.b+"->"+this.c},MWn.a=0;var pAt,vAt=vX(B6n,"BasicEMap/EntryImpl",612);wAn(536,1,{},oo),vX(B6n,"BasicEMap/View",536),wAn(768,1,{}),MWn.Fb=function(n){return NAn((SQ(),set),n)},MWn.Hb=function(){return Fon((SQ(),set))},MWn.Ib=function(){return LMn((SQ(),set))},vX(B6n,"ECollections/BasicEmptyUnmodifiableEList",768),wAn(1312,1,cVn,mo),MWn.Nb=function(n){fU(this,n)},MWn.Rb=function(n){throw Hp(new pv)},MWn.Ob=function(){return!1},MWn.Sb=function(){return!1},MWn.Pb=function(){throw Hp(new yv)},MWn.Tb=function(){return 0},MWn.Ub=function(){throw Hp(new yv)},MWn.Vb=function(){return-1},MWn.Qb=function(){throw Hp(new pv)},MWn.Wb=function(n){throw Hp(new pv)},vX(B6n,"ECollections/BasicEmptyUnmodifiableEList/1",1312),wAn(1310,768,{20:1,14:1,15:1,58:1},Tm),MWn.Vc=function(n,t){NE()},MWn.Fc=function(n){return xE()},MWn.Wc=function(n,t){return DE()},MWn.Gc=function(n){return RE()},MWn.$b=function(){_E()},MWn.Hc=function(n){return!1},MWn.Ic=function(n){return!1},MWn.Jc=function(n){e5(this,n)},MWn.Xb=function(n){return yO((SQ(),n)),null},MWn.Xc=function(n){return-1},MWn.dc=function(){return!0},MWn.Kc=function(){return this.a},MWn.Yc=function(){return this.a},MWn.Zc=function(n){return this.a},MWn.ii=function(n,t){return KE()},MWn.ji=function(n,t){FE()},MWn.Lc=function(){return new Rq(null,new w1(this,16))},MWn.$c=function(n){return BE()},MWn.Mc=function(n){return HE()},MWn._c=function(n,t){return qE()},MWn.gc=function(){return 0},MWn.ad=function(n){Krn(this,n)},MWn.Nc=function(){return new w1(this,16)},MWn.Oc=function(){return new Rq(null,new w1(this,16))},MWn.bd=function(n,t){return SQ(),new s1(set,n,t)},MWn.Pc=function(){return cz((SQ(),set))},MWn.Qc=function(n){return SQ(),Emn(set,n)},vX(B6n,"ECollections/EmptyUnmodifiableEList",1310),wAn(1311,768,{20:1,14:1,15:1,58:1,589:1},Mm),MWn.Vc=function(n,t){NE()},MWn.Fc=function(n){return xE()},MWn.Wc=function(n,t){return DE()},MWn.Gc=function(n){return RE()},MWn.$b=function(){_E()},MWn.Hc=function(n){return!1},MWn.Ic=function(n){return!1},MWn.Jc=function(n){e5(this,n)},MWn.Xb=function(n){return yO((SQ(),n)),null},MWn.Xc=function(n){return-1},MWn.dc=function(){return!0},MWn.Kc=function(){return this.a},MWn.Yc=function(){return this.a},MWn.Zc=function(n){return this.a},MWn.ii=function(n,t){return KE()},MWn.ji=function(n,t){FE()},MWn.Lc=function(){return new Rq(null,new w1(this,16))},MWn.$c=function(n){return BE()},MWn.Mc=function(n){return HE()},MWn._c=function(n,t){return qE()},MWn.gc=function(){return 0},MWn.ad=function(n){Krn(this,n)},MWn.Nc=function(){return new w1(this,16)},MWn.Oc=function(){return new Rq(null,new w1(this,16))},MWn.bd=function(n,t){return SQ(),new s1(set,n,t)},MWn.Pc=function(){return cz((SQ(),set))},MWn.Qc=function(n){return SQ(),Emn(set,n)},MWn.sj=function(){return SQ(),SQ(),het},vX(B6n,"ECollections/EmptyUnmodifiableEMap",1311);var mAt,yAt=bq(B6n,"Enumerator");wAn(281,1,{281:1},rRn),MWn.Fb=function(n){var t;return this===n||!!cL(n,281)&&(t=BB(n,281),this.f==t.f&&vG(this.i,t.i)&&pG(this.a,0!=(256&this.f)?0!=(256&t.f)?t.a:null:0!=(256&t.f)?null:t.a)&&pG(this.d,t.d)&&pG(this.g,t.g)&&pG(this.e,t.e)&&Spn(this,t))},MWn.Hb=function(){return this.f},MWn.Ib=function(){return MKn(this)},MWn.f=0;var kAt,jAt,EAt,TAt=0,MAt=0,SAt=0,PAt=0,IAt=0,CAt=0,OAt=0,AAt=0,$At=0,LAt=0,NAt=0,xAt=0,DAt=0;vX(B6n,"URI",281),wAn(1091,43,tYn,Sm),MWn.zc=function(n,t){return BB(mZ(this,SD(n),BB(t,281)),281)},vX(B6n,"URI/URICache",1091),wAn(497,63,h8n,fo,rG),MWn.hi=function(){return!0},vX(B6n,"UniqueEList",497),wAn(581,60,BVn,L7),vX(B6n,"WrappedException",581);var RAt,_At=bq(q5n,s9n),KAt=bq(q5n,h9n),FAt=bq(q5n,f9n),BAt=bq(q5n,l9n),HAt=bq(q5n,b9n),qAt=bq(q5n,"EClass"),GAt=bq(q5n,"EDataType");wAn(1183,43,tYn,Pm),MWn.xc=function(n){return XC(n)?SJ(this,n):qC(AY(this.f,n))},vX(q5n,"EDataType/Internal/ConversionDelegate/Factory/Registry/Impl",1183);var zAt,UAt,XAt=bq(q5n,"EEnum"),WAt=bq(q5n,w9n),VAt=bq(q5n,d9n),QAt=bq(q5n,g9n),YAt=bq(q5n,p9n),JAt=bq(q5n,v9n);wAn(1029,1,{},ho),MWn.Ib=function(){return"NIL"},vX(q5n,"EStructuralFeature/Internal/DynamicValueHolder/1",1029),wAn(1028,43,tYn,Im),MWn.xc=function(n){return XC(n)?SJ(this,n):qC(AY(this.f,n))},vX(q5n,"EStructuralFeature/Internal/SettingDelegate/Factory/Registry/Impl",1028);var ZAt,n$t,t$t,e$t,i$t,r$t,c$t,a$t,u$t,o$t,s$t,h$t,f$t,l$t,b$t,w$t,d$t,g$t,p$t,v$t,m$t,y$t,k$t,j$t,E$t,T$t,M$t,S$t,P$t,I$t,C$t,O$t=bq(q5n,m9n),A$t=bq(q5n,"EValidator/PatternMatcher"),$$t=bq(y9n,"FeatureMap/Entry");wAn(535,1,{72:1},IC),MWn.ak=function(){return this.a},MWn.dd=function(){return this.b},vX(l6n,"BasicEObjectImpl/1",535),wAn(1027,1,k9n,CC),MWn.Wj=function(n){return V5(this.a,this.b,n)},MWn.fj=function(){return ZJ(this.a,this.b)},MWn.Wb=function(n){NJ(this.a,this.b,n)},MWn.Xj=function(){PW(this.a,this.b)},vX(l6n,"BasicEObjectImpl/4",1027),wAn(1983,1,{108:1}),MWn.bk=function(n){this.e=0==n?M$t:x8(Ant,HWn,1,n,5,1)},MWn.Ch=function(n){return this.e[n]},MWn.Dh=function(n,t){this.e[n]=t},MWn.Eh=function(n){this.e[n]=null},MWn.ck=function(){return this.c},MWn.dk=function(){throw Hp(new pv)},MWn.ek=function(){throw Hp(new pv)},MWn.fk=function(){return this.d},MWn.gk=function(){return null!=this.e},MWn.hk=function(n){this.c=n},MWn.ik=function(n){throw Hp(new pv)},MWn.jk=function(n){throw Hp(new pv)},MWn.kk=function(n){this.d=n},vX(l6n,"BasicEObjectImpl/EPropertiesHolderBaseImpl",1983),wAn(185,1983,{108:1},_f),MWn.dk=function(){return this.a},MWn.ek=function(){return this.b},MWn.ik=function(n){this.a=n},MWn.jk=function(n){this.b=n},vX(l6n,"BasicEObjectImpl/EPropertiesHolderImpl",185),wAn(506,97,f6n,yo),MWn.Kg=function(){return this.f},MWn.Pg=function(){return this.k},MWn.Rg=function(n,t){this.g=n,this.i=t},MWn.Tg=function(){return 0==(2&this.j)?this.zh():this.ph().ck()},MWn.Vg=function(){return this.i},MWn.Mg=function(){return 0!=(1&this.j)},MWn.eh=function(){return this.g},MWn.kh=function(){return 0!=(4&this.j)},MWn.ph=function(){return!this.k&&(this.k=new _f),this.k},MWn.th=function(n){this.ph().hk(n),n?this.j|=2:this.j&=-3},MWn.vh=function(n){this.ph().jk(n),n?this.j|=4:this.j&=-5},MWn.zh=function(){return(QX(),t$t).S},MWn.i=0,MWn.j=1,vX(l6n,"EObjectImpl",506),wAn(780,506,{105:1,92:1,90:1,56:1,108:1,49:1,97:1},jH),MWn.Ch=function(n){return this.e[n]},MWn.Dh=function(n,t){this.e[n]=t},MWn.Eh=function(n){this.e[n]=null},MWn.Tg=function(){return this.d},MWn.Yg=function(n){return Awn(this.d,n)},MWn.$g=function(){return this.d},MWn.dh=function(){return null!=this.e},MWn.ph=function(){return!this.k&&(this.k=new ko),this.k},MWn.th=function(n){this.d=n},MWn.yh=function(){var n;return null==this.e&&(n=bX(this.d),this.e=0==n?S$t:x8(Ant,HWn,1,n,5,1)),this},MWn.Ah=function(){return 0},vX(l6n,"DynamicEObjectImpl",780),wAn(1376,780,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1},fq),MWn.Fb=function(n){return this===n},MWn.Hb=function(){return PN(this)},MWn.th=function(n){this.d=n,this.b=NNn(n,"key"),this.c=NNn(n,E6n)},MWn.Sh=function(){var n;return-1==this.a&&(n=J7(this,this.b),this.a=null==n?0:nsn(n)),this.a},MWn.cd=function(){return J7(this,this.b)},MWn.dd=function(){return J7(this,this.c)},MWn.Th=function(n){this.a=n},MWn.Uh=function(n){NJ(this,this.b,n)},MWn.ed=function(n){var t;return t=J7(this,this.c),NJ(this,this.c,n),t},MWn.a=0,vX(l6n,"DynamicEObjectImpl/BasicEMapEntry",1376),wAn(1377,1,{108:1},ko),MWn.bk=function(n){throw Hp(new pv)},MWn.Ch=function(n){throw Hp(new pv)},MWn.Dh=function(n,t){throw Hp(new pv)},MWn.Eh=function(n){throw Hp(new pv)},MWn.ck=function(){throw Hp(new pv)},MWn.dk=function(){return this.a},MWn.ek=function(){return this.b},MWn.fk=function(){return this.c},MWn.gk=function(){throw Hp(new pv)},MWn.hk=function(n){throw Hp(new pv)},MWn.ik=function(n){this.a=n},MWn.jk=function(n){this.b=n},MWn.kk=function(n){this.c=n},vX(l6n,"DynamicEObjectImpl/DynamicEPropertiesHolderImpl",1377),wAn(510,150,{105:1,92:1,90:1,590:1,147:1,56:1,108:1,49:1,97:1,510:1,150:1,114:1,115:1},jo),MWn.Qg=function(n){return bkn(this,n)},MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.d;case 2:return e?(!this.b&&(this.b=new Jx((gWn(),k$t),X$t,this)),this.b):(!this.b&&(this.b=new Jx((gWn(),k$t),X$t,this)),A8(this.b));case 3:return bZ(this);case 4:return!this.a&&(this.a=new $L(LOt,this,4)),this.a;case 5:return!this.c&&(this.c=new RL(LOt,this,5)),this.c}return U9(this,n-bX((gWn(),e$t)),itn(BB(yan(this,16),26)||e$t,n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?bkn(this,e):this.Cb.ih(this,-1-i,null,e)),QG(this,BB(n,147),e)}return BB(itn(BB(yan(this,16),26)||(gWn(),e$t),t),66).Nj().Qj(this,fgn(this),t-bX((gWn(),e$t)),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 2:return!this.b&&(this.b=new Jx((gWn(),k$t),X$t,this)),B_(this.b,n,e);case 3:return QG(this,null,e);case 4:return!this.a&&(this.a=new $L(LOt,this,4)),Kpn(this.a,n,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),e$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),e$t)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.d;case 2:return!!this.b&&0!=this.b.f;case 3:return!!bZ(this);case 4:return!!this.a&&0!=this.a.i;case 5:return!!this.c&&0!=this.c.i}return O3(this,n-bX((gWn(),e$t)),itn(BB(yan(this,16),26)||e$t,n))},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void pq(this,SD(t));case 2:return!this.b&&(this.b=new Jx((gWn(),k$t),X$t,this)),void tan(this.b,t);case 3:return void ONn(this,BB(t,147));case 4:return!this.a&&(this.a=new $L(LOt,this,4)),sqn(this.a),!this.a&&(this.a=new $L(LOt,this,4)),void pX(this.a,BB(t,14));case 5:return!this.c&&(this.c=new RL(LOt,this,5)),sqn(this.c),!this.c&&(this.c=new RL(LOt,this,5)),void pX(this.c,BB(t,14))}Lbn(this,n-bX((gWn(),e$t)),itn(BB(yan(this,16),26)||e$t,n),t)},MWn.zh=function(){return gWn(),e$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return void Bin(this,null);case 2:return!this.b&&(this.b=new Jx((gWn(),k$t),X$t,this)),void this.b.c.$b();case 3:return void ONn(this,null);case 4:return!this.a&&(this.a=new $L(LOt,this,4)),void sqn(this.a);case 5:return!this.c&&(this.c=new RL(LOt,this,5)),void sqn(this.c)}qfn(this,n-bX((gWn(),e$t)),itn(BB(yan(this,16),26)||e$t,n))},MWn.Ib=function(){return Vfn(this)},MWn.d=null,vX(l6n,"EAnnotationImpl",510),wAn(151,705,j9n,y9),MWn.Xh=function(n,t){n$(this,n,BB(t,42))},MWn.lk=function(n,t){return F_(this,BB(n,42),t)},MWn.pi=function(n){return BB(BB(this.c,69).pi(n),133)},MWn.Zh=function(){return BB(this.c,69).Zh()},MWn.$h=function(){return BB(this.c,69).$h()},MWn._h=function(n){return BB(this.c,69)._h(n)},MWn.mk=function(n,t){return B_(this,n,t)},MWn.Wj=function(n){return BB(this.c,76).Wj(n)},MWn.rj=function(){},MWn.fj=function(){return BB(this.c,76).fj()},MWn.tj=function(n,t,e){var i;return(i=BB(Utn(this.b).Nh().Jh(this.b),133)).Th(n),i.Uh(t),i.ed(e),i},MWn.uj=function(){return new Cp(this)},MWn.Wb=function(n){tan(this,n)},MWn.Xj=function(){BB(this.c,76).Xj()},vX(y9n,"EcoreEMap",151),wAn(158,151,j9n,Jx),MWn.qj=function(){var n,t,e,i,r;if(null==this.d){for(r=x8(oAt,c9n,63,2*this.f+1,0,1),e=this.c.Kc();e.e!=e.i.gc();)!(n=r[i=((t=BB(e.nj(),133)).Sh()&DWn)%r.length])&&(n=r[i]=new Cp(this)),n.Fc(t);this.d=r}},vX(l6n,"EAnnotationImpl/1",158),wAn(284,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,472:1,49:1,97:1,150:1,284:1,114:1,115:1}),MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return hN(),0!=(256&this.Bb);case 3:return hN(),0!=(512&this.Bb);case 4:return iln(this.s);case 5:return iln(this.t);case 6:return hN(),!!this.$j();case 7:return hN(),this.s>=1;case 8:return t?Ckn(this):this.r;case 9:return this.q}return U9(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 9:return gX(this,e)}return BB(itn(BB(yan(this,16),26)||this.zh(),t),66).Nj().Rj(this,fgn(this),t-bX(this.zh()),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.$j();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yW(this.q).i)}return O3(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void this.Lh(SD(t));case 2:return void Yfn(this,qy(TD(t)));case 3:return void nln(this,qy(TD(t)));case 4:return void Len(this,BB(t,19).a);case 5:return void this.ok(BB(t,19).a);case 8:return void Chn(this,BB(t,138));case 9:return void((e=HTn(this,BB(t,87),null))&&e.Fi())}Lbn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t)},MWn.zh=function(){return gWn(),E$t},MWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return void this.Lh(null);case 2:return void Yfn(this,!0);case 3:return void nln(this,!0);case 4:return void Len(this,0);case 5:return void this.ok(1);case 8:return void Chn(this,null);case 9:return void((t=HTn(this,null,null))&&t.Fi())}qfn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.Gh=function(){Ckn(this),this.Bb|=1},MWn.Yj=function(){return Ckn(this)},MWn.Zj=function(){return this.t},MWn.$j=function(){var n;return(n=this.t)>1||-1==n},MWn.hi=function(){return 0!=(512&this.Bb)},MWn.nk=function(n,t){return Pfn(this,n,t)},MWn.ok=function(n){Nen(this,n)},MWn.Ib=function(){return _On(this)},MWn.s=0,MWn.t=1,vX(l6n,"ETypedElementImpl",284),wAn(449,284,{105:1,92:1,90:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,449:1,284:1,114:1,115:1,677:1}),MWn.Qg=function(n){return Nyn(this,n)},MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return hN(),0!=(256&this.Bb);case 3:return hN(),0!=(512&this.Bb);case 4:return iln(this.s);case 5:return iln(this.t);case 6:return hN(),!!this.$j();case 7:return hN(),this.s>=1;case 8:return t?Ckn(this):this.r;case 9:return this.q;case 10:return hN(),0!=(this.Bb&k6n);case 11:return hN(),0!=(this.Bb&M9n);case 12:return hN(),0!=(this.Bb&KQn);case 13:return this.j;case 14:return qLn(this);case 15:return hN(),0!=(this.Bb&T9n);case 16:return hN(),0!=(this.Bb&hVn);case 17:return dZ(this)}return U9(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 17:return this.Cb&&(e=(i=this.Db>>16)>=0?Nyn(this,e):this.Cb.ih(this,-1-i,null,e)),TKn(this,n,17,e)}return BB(itn(BB(yan(this,16),26)||this.zh(),t),66).Nj().Qj(this,fgn(this),t-bX(this.zh()),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 9:return gX(this,e);case 17:return TKn(this,null,17,e)}return BB(itn(BB(yan(this,16),26)||this.zh(),t),66).Nj().Rj(this,fgn(this),t-bX(this.zh()),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.$j();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yW(this.q).i);case 10:return 0==(this.Bb&k6n);case 11:return 0!=(this.Bb&M9n);case 12:return 0!=(this.Bb&KQn);case 13:return null!=this.j;case 14:return null!=qLn(this);case 15:return 0!=(this.Bb&T9n);case 16:return 0!=(this.Bb&hVn);case 17:return!!dZ(this)}return O3(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void JZ(this,SD(t));case 2:return void Yfn(this,qy(TD(t)));case 3:return void nln(this,qy(TD(t)));case 4:return void Len(this,BB(t,19).a);case 5:return void this.ok(BB(t,19).a);case 8:return void Chn(this,BB(t,138));case 9:return void((e=HTn(this,BB(t,87),null))&&e.Fi());case 10:return void Aln(this,qy(TD(t)));case 11:return void Nln(this,qy(TD(t)));case 12:return void $ln(this,qy(TD(t)));case 13:return void KC(this,SD(t));case 15:return void Lln(this,qy(TD(t)));case 16:return void qln(this,qy(TD(t)))}Lbn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t)},MWn.zh=function(){return gWn(),j$t},MWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return cL(this.Cb,88)&&AIn(P5(BB(this.Cb,88)),4),void Nrn(this,null);case 2:return void Yfn(this,!0);case 3:return void nln(this,!0);case 4:return void Len(this,0);case 5:return void this.ok(1);case 8:return void Chn(this,null);case 9:return void((t=HTn(this,null,null))&&t.Fi());case 10:return void Aln(this,!0);case 11:return void Nln(this,!1);case 12:return void $ln(this,!1);case 13:return this.i=null,void arn(this,null);case 15:return void Lln(this,!1);case 16:return void qln(this,!1)}qfn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.Gh=function(){kV(B7((CPn(),Z$t),this)),Ckn(this),this.Bb|=1},MWn.Gj=function(){return this.f},MWn.zj=function(){return qLn(this)},MWn.Hj=function(){return dZ(this)},MWn.Lj=function(){return null},MWn.pk=function(){return this.k},MWn.aj=function(){return this.n},MWn.Mj=function(){return oEn(this)},MWn.Nj=function(){var n,t,e,i,r,c,a,u,o;return this.p||((null==(e=dZ(this)).i&&qFn(e),e.i).length,(i=this.Lj())&&bX(dZ(i)),n=(a=(r=Ckn(this)).Bj())?0!=(1&a.i)?a==$Nt?ktt:a==ANt?Att:a==DNt?Itt:a==xNt?Ptt:a==LNt?Rtt:a==RNt?Ktt:a==NNt?Ttt:Stt:a:null,t=qLn(this),u=r.zj(),bbn(this),0!=(this.Bb&hVn)&&((c=mjn((CPn(),Z$t),e))&&c!=this||(c=Z1(B7(Z$t,this))))?this.p=new AC(this,c):this.$j()?this.rk()?i?0!=(this.Bb&T9n)?n?this.sk()?this.p=new lQ(47,n,this,i):this.p=new lQ(5,n,this,i):this.sk()?this.p=new w4(46,this,i):this.p=new w4(4,this,i):n?this.sk()?this.p=new lQ(49,n,this,i):this.p=new lQ(7,n,this,i):this.sk()?this.p=new w4(48,this,i):this.p=new w4(6,this,i):0!=(this.Bb&T9n)?n?n==Hnt?this.p=new PB(50,VOt,this):this.sk()?this.p=new PB(43,n,this):this.p=new PB(1,n,this):this.sk()?this.p=new RY(42,this):this.p=new RY(0,this):n?n==Hnt?this.p=new PB(41,VOt,this):this.sk()?this.p=new PB(45,n,this):this.p=new PB(3,n,this):this.sk()?this.p=new RY(44,this):this.p=new RY(2,this):cL(r,148)?n==$$t?this.p=new RY(40,this):0!=(512&this.Bb)?0!=(this.Bb&T9n)?this.p=n?new PB(9,n,this):new RY(8,this):this.p=n?new PB(11,n,this):new RY(10,this):0!=(this.Bb&T9n)?this.p=n?new PB(13,n,this):new RY(12,this):this.p=n?new PB(15,n,this):new RY(14,this):i?(o=i.t)>1||-1==o?this.sk()?0!=(this.Bb&T9n)?this.p=n?new lQ(25,n,this,i):new w4(24,this,i):this.p=n?new lQ(27,n,this,i):new w4(26,this,i):0!=(this.Bb&T9n)?this.p=n?new lQ(29,n,this,i):new w4(28,this,i):this.p=n?new lQ(31,n,this,i):new w4(30,this,i):this.sk()?0!=(this.Bb&T9n)?this.p=n?new lQ(33,n,this,i):new w4(32,this,i):this.p=n?new lQ(35,n,this,i):new w4(34,this,i):0!=(this.Bb&T9n)?this.p=n?new lQ(37,n,this,i):new w4(36,this,i):this.p=n?new lQ(39,n,this,i):new w4(38,this,i):this.sk()?0!=(this.Bb&T9n)?this.p=n?new PB(17,n,this):new RY(16,this):this.p=n?new PB(19,n,this):new RY(18,this):0!=(this.Bb&T9n)?this.p=n?new PB(21,n,this):new RY(20,this):this.p=n?new PB(23,n,this):new RY(22,this):this.qk()?this.sk()?this.p=new IB(BB(r,26),this,i):this.p=new mJ(BB(r,26),this,i):cL(r,148)?n==$$t?this.p=new RY(40,this):0!=(this.Bb&T9n)?this.p=n?new nz(t,u,this,(Bwn(),a==ANt?q$t:a==$Nt?_$t:a==LNt?G$t:a==DNt?H$t:a==xNt?B$t:a==RNt?U$t:a==NNt?K$t:a==ONt?F$t:z$t)):new dQ(BB(r,148),t,u,this):this.p=n?new ZG(t,u,this,(Bwn(),a==ANt?q$t:a==$Nt?_$t:a==LNt?G$t:a==DNt?H$t:a==xNt?B$t:a==RNt?U$t:a==NNt?K$t:a==ONt?F$t:z$t)):new wQ(BB(r,148),t,u,this):this.rk()?i?0!=(this.Bb&T9n)?this.sk()?this.p=new NB(BB(r,26),this,i):this.p=new LB(BB(r,26),this,i):this.sk()?this.p=new $B(BB(r,26),this,i):this.p=new CB(BB(r,26),this,i):0!=(this.Bb&T9n)?this.sk()?this.p=new eD(BB(r,26),this):this.p=new tD(BB(r,26),this):this.sk()?this.p=new nD(BB(r,26),this):this.p=new Zx(BB(r,26),this):this.sk()?i?0!=(this.Bb&T9n)?this.p=new xB(BB(r,26),this,i):this.p=new OB(BB(r,26),this,i):0!=(this.Bb&T9n)?this.p=new rD(BB(r,26),this):this.p=new iD(BB(r,26),this):i?0!=(this.Bb&T9n)?this.p=new DB(BB(r,26),this,i):this.p=new AB(BB(r,26),this,i):0!=(this.Bb&T9n)?this.p=new cD(BB(r,26),this):this.p=new cG(BB(r,26),this)),this.p},MWn.Ij=function(){return 0!=(this.Bb&k6n)},MWn.qk=function(){return!1},MWn.rk=function(){return!1},MWn.Jj=function(){return 0!=(this.Bb&hVn)},MWn.Oj=function(){return hnn(this)},MWn.sk=function(){return!1},MWn.Kj=function(){return 0!=(this.Bb&T9n)},MWn.tk=function(n){this.k=n},MWn.Lh=function(n){JZ(this,n)},MWn.Ib=function(){return ERn(this)},MWn.e=!1,MWn.n=0,vX(l6n,"EStructuralFeatureImpl",449),wAn(322,449,{105:1,92:1,90:1,34:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,322:1,150:1,449:1,284:1,114:1,115:1,677:1},Om),MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return hN(),0!=(256&this.Bb);case 3:return hN(),0!=(512&this.Bb);case 4:return iln(this.s);case 5:return iln(this.t);case 6:return hN(),!!NCn(this);case 7:return hN(),this.s>=1;case 8:return t?Ckn(this):this.r;case 9:return this.q;case 10:return hN(),0!=(this.Bb&k6n);case 11:return hN(),0!=(this.Bb&M9n);case 12:return hN(),0!=(this.Bb&KQn);case 13:return this.j;case 14:return qLn(this);case 15:return hN(),0!=(this.Bb&T9n);case 16:return hN(),0!=(this.Bb&hVn);case 17:return dZ(this);case 18:return hN(),0!=(this.Bb&h6n);case 19:return t?uun(this):x6(this)}return U9(this,n-bX((gWn(),i$t)),itn(BB(yan(this,16),26)||i$t,n),t,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return NCn(this);case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yW(this.q).i);case 10:return 0==(this.Bb&k6n);case 11:return 0!=(this.Bb&M9n);case 12:return 0!=(this.Bb&KQn);case 13:return null!=this.j;case 14:return null!=qLn(this);case 15:return 0!=(this.Bb&T9n);case 16:return 0!=(this.Bb&hVn);case 17:return!!dZ(this);case 18:return 0!=(this.Bb&h6n);case 19:return!!x6(this)}return O3(this,n-bX((gWn(),i$t)),itn(BB(yan(this,16),26)||i$t,n))},MWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void JZ(this,SD(t));case 2:return void Yfn(this,qy(TD(t)));case 3:return void nln(this,qy(TD(t)));case 4:return void Len(this,BB(t,19).a);case 5:return void Uj(this,BB(t,19).a);case 8:return void Chn(this,BB(t,138));case 9:return void((e=HTn(this,BB(t,87),null))&&e.Fi());case 10:return void Aln(this,qy(TD(t)));case 11:return void Nln(this,qy(TD(t)));case 12:return void $ln(this,qy(TD(t)));case 13:return void KC(this,SD(t));case 15:return void Lln(this,qy(TD(t)));case 16:return void qln(this,qy(TD(t)));case 18:return void Gln(this,qy(TD(t)))}Lbn(this,n-bX((gWn(),i$t)),itn(BB(yan(this,16),26)||i$t,n),t)},MWn.zh=function(){return gWn(),i$t},MWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return cL(this.Cb,88)&&AIn(P5(BB(this.Cb,88)),4),void Nrn(this,null);case 2:return void Yfn(this,!0);case 3:return void nln(this,!0);case 4:return void Len(this,0);case 5:return this.b=0,void Nen(this,1);case 8:return void Chn(this,null);case 9:return void((t=HTn(this,null,null))&&t.Fi());case 10:return void Aln(this,!0);case 11:return void Nln(this,!1);case 12:return void $ln(this,!1);case 13:return this.i=null,void arn(this,null);case 15:return void Lln(this,!1);case 16:return void qln(this,!1);case 18:return void Gln(this,!1)}qfn(this,n-bX((gWn(),i$t)),itn(BB(yan(this,16),26)||i$t,n))},MWn.Gh=function(){uun(this),kV(B7((CPn(),Z$t),this)),Ckn(this),this.Bb|=1},MWn.$j=function(){return NCn(this)},MWn.nk=function(n,t){return this.b=0,this.a=null,Pfn(this,n,t)},MWn.ok=function(n){Uj(this,n)},MWn.Ib=function(){var n;return 0!=(64&this.Db)?ERn(this):((n=new fN(ERn(this))).a+=" (iD: ",yE(n,0!=(this.Bb&h6n)),n.a+=")",n.a)},MWn.b=0,vX(l6n,"EAttributeImpl",322),wAn(351,438,{105:1,92:1,90:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,150:1,114:1,115:1,676:1}),MWn.uk=function(n){return n.Tg()==this},MWn.Qg=function(n){return fyn(this,n)},MWn.Rg=function(n,t){this.w=null,this.Db=t<<16|255&this.Db,this.Cb=n},MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return iyn(this);case 4:return this.zj();case 5:return this.F;case 6:return t?Utn(this):wZ(this);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),this.A}return U9(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?fyn(this,e):this.Cb.ih(this,-1-i,null,e)),TKn(this,n,6,e)}return BB(itn(BB(yan(this,16),26)||this.zh(),t),66).Nj().Qj(this,fgn(this),t-bX(this.zh()),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 6:return TKn(this,null,6,e);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),Kpn(this.A,n,e)}return BB(itn(BB(yan(this,16),26)||this.zh(),t),66).Nj().Rj(this,fgn(this),t-bX(this.zh()),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!iyn(this);case 4:return null!=this.zj();case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!wZ(this);case 7:return!!this.A&&0!=this.A.i}return O3(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void ZZ(this,SD(t));case 2:return void CA(this,SD(t));case 5:return void Yqn(this,SD(t));case 7:return!this.A&&(this.A=new NL(O$t,this,7)),sqn(this.A),!this.A&&(this.A=new NL(O$t,this,7)),void pX(this.A,BB(t,14))}Lbn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t)},MWn.zh=function(){return gWn(),c$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return cL(this.Cb,179)&&(BB(this.Cb,179).tb=null),void Nrn(this,null);case 2:return Dsn(this,null),void xen(this,this.D);case 5:return void Yqn(this,null);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),void sqn(this.A)}qfn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.yj=function(){var n;return-1==this.G&&(this.G=(n=Utn(this))?uvn(n.Mh(),this):-1),this.G},MWn.zj=function(){return null},MWn.Aj=function(){return Utn(this)},MWn.vk=function(){return this.v},MWn.Bj=function(){return iyn(this)},MWn.Cj=function(){return null!=this.D?this.D:this.B},MWn.Dj=function(){return this.F},MWn.wj=function(n){return SFn(this,n)},MWn.wk=function(n){this.v=n},MWn.xk=function(n){Urn(this,n)},MWn.yk=function(n){this.C=n},MWn.Lh=function(n){ZZ(this,n)},MWn.Ib=function(){return Iwn(this)},MWn.C=null,MWn.D=null,MWn.G=-1,vX(l6n,"EClassifierImpl",351),wAn(88,351,{105:1,92:1,90:1,26:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,88:1,351:1,150:1,473:1,114:1,115:1,676:1},Kf),MWn.uk=function(n){return QR(this,n.Tg())},MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return iyn(this);case 4:return null;case 5:return this.F;case 6:return t?Utn(this):wZ(this);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),this.A;case 8:return hN(),0!=(256&this.Bb);case 9:return hN(),0!=(512&this.Bb);case 10:return kY(this);case 11:return!this.q&&(this.q=new eU(QAt,this,11,10)),this.q;case 12:return YBn(this);case 13:return RBn(this);case 14:return RBn(this),this.r;case 15:return YBn(this),this.k;case 16:return WPn(this);case 17:return gBn(this);case 18:return qFn(this);case 19:return ILn(this);case 20:return YBn(this),this.o;case 21:return!this.s&&(this.s=new eU(FAt,this,21,17)),this.s;case 22:return a4(this);case 23:return HDn(this)}return U9(this,n-bX((gWn(),r$t)),itn(BB(yan(this,16),26)||r$t,n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?fyn(this,e):this.Cb.ih(this,-1-i,null,e)),TKn(this,n,6,e);case 11:return!this.q&&(this.q=new eU(QAt,this,11,10)),Ywn(this.q,n,e);case 21:return!this.s&&(this.s=new eU(FAt,this,21,17)),Ywn(this.s,n,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),r$t),t),66).Nj().Qj(this,fgn(this),t-bX((gWn(),r$t)),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 6:return TKn(this,null,6,e);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),Kpn(this.A,n,e);case 11:return!this.q&&(this.q=new eU(QAt,this,11,10)),Kpn(this.q,n,e);case 21:return!this.s&&(this.s=new eU(FAt,this,21,17)),Kpn(this.s,n,e);case 22:return Kpn(a4(this),n,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),r$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),r$t)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!iyn(this);case 4:return!1;case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!wZ(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0!=(256&this.Bb);case 9:return 0!=(512&this.Bb);case 10:return!(!this.u||0==a4(this.u.a).i||this.n&&Rvn(this.n));case 11:return!!this.q&&0!=this.q.i;case 12:return 0!=YBn(this).i;case 13:return 0!=RBn(this).i;case 14:return RBn(this),0!=this.r.i;case 15:return YBn(this),0!=this.k.i;case 16:return 0!=WPn(this).i;case 17:return 0!=gBn(this).i;case 18:return 0!=qFn(this).i;case 19:return 0!=ILn(this).i;case 20:return YBn(this),!!this.o;case 21:return!!this.s&&0!=this.s.i;case 22:return!!this.n&&Rvn(this.n);case 23:return 0!=HDn(this).i}return O3(this,n-bX((gWn(),r$t)),itn(BB(yan(this,16),26)||r$t,n))},MWn.oh=function(n){return(null==this.i||this.q&&0!=this.q.i?null:NNn(this,n))||hUn(this,n)},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void ZZ(this,SD(t));case 2:return void CA(this,SD(t));case 5:return void Yqn(this,SD(t));case 7:return!this.A&&(this.A=new NL(O$t,this,7)),sqn(this.A),!this.A&&(this.A=new NL(O$t,this,7)),void pX(this.A,BB(t,14));case 8:return void Jfn(this,qy(TD(t)));case 9:return void tln(this,qy(TD(t)));case 10:return vqn(kY(this)),void pX(kY(this),BB(t,14));case 11:return!this.q&&(this.q=new eU(QAt,this,11,10)),sqn(this.q),!this.q&&(this.q=new eU(QAt,this,11,10)),void pX(this.q,BB(t,14));case 21:return!this.s&&(this.s=new eU(FAt,this,21,17)),sqn(this.s),!this.s&&(this.s=new eU(FAt,this,21,17)),void pX(this.s,BB(t,14));case 22:return sqn(a4(this)),void pX(a4(this),BB(t,14))}Lbn(this,n-bX((gWn(),r$t)),itn(BB(yan(this,16),26)||r$t,n),t)},MWn.zh=function(){return gWn(),r$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return cL(this.Cb,179)&&(BB(this.Cb,179).tb=null),void Nrn(this,null);case 2:return Dsn(this,null),void xen(this,this.D);case 5:return void Yqn(this,null);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),void sqn(this.A);case 8:return void Jfn(this,!1);case 9:return void tln(this,!1);case 10:return void(this.u&&vqn(this.u));case 11:return!this.q&&(this.q=new eU(QAt,this,11,10)),void sqn(this.q);case 21:return!this.s&&(this.s=new eU(FAt,this,21,17)),void sqn(this.s);case 22:return void(this.n&&sqn(this.n))}qfn(this,n-bX((gWn(),r$t)),itn(BB(yan(this,16),26)||r$t,n))},MWn.Gh=function(){var n,t;if(YBn(this),RBn(this),WPn(this),gBn(this),qFn(this),ILn(this),HDn(this),a6(XB(P5(this))),this.s)for(n=0,t=this.s.i;n<t;++n)vx(Wtn(this.s,n));if(this.q)for(n=0,t=this.q.i;n<t;++n)vx(Wtn(this.q,n));Ifn((CPn(),Z$t),this).ne(),this.Bb|=1},MWn.Ib=function(){return dEn(this)},MWn.k=null,MWn.r=null,vX(l6n,"EClassImpl",88),wAn(1994,1993,D9n),MWn.Vh=function(n,t){return LFn(this,n,t)},MWn.Wh=function(n){return LFn(this,this.i,n)},MWn.Xh=function(n,t){qOn(this,n,t)},MWn.Yh=function(n){tAn(this,n)},MWn.lk=function(n,t){return Ywn(this,n,t)},MWn.pi=function(n){return F9(this,n)},MWn.mk=function(n,t){return Kpn(this,n,t)},MWn.mi=function(n,t){return fBn(this,n,t)},MWn.Zh=function(){return new ax(this)},MWn.$h=function(){return new ux(this)},MWn._h=function(n){return sin(this,n)},vX(y9n,"NotifyingInternalEListImpl",1994),wAn(622,1994,R9n),MWn.Hc=function(n){return bqn(this,n)},MWn.Zi=function(n,t,e,i,r){return yZ(this,n,t,e,i,r)},MWn.$i=function(n){Lv(this,n)},MWn.Wj=function(n){return this},MWn.ak=function(){return itn(this.e.Tg(),this.aj())},MWn._i=function(){return this.ak()},MWn.aj=function(){return Awn(this.e.Tg(),this.ak())},MWn.zk=function(){return BB(this.ak().Yj(),26).Bj()},MWn.Ak=function(){return Ivn(BB(this.ak(),18)).n},MWn.Ai=function(){return this.e},MWn.Bk=function(){return!0},MWn.Ck=function(){return!1},MWn.Dk=function(){return!1},MWn.Ek=function(){return!1},MWn.Xc=function(n){return uvn(this,n)},MWn.cj=function(n,t){var e;return e=BB(n,49),this.Dk()?this.Bk()?e.gh(this.e,this.Ak(),this.zk(),t):e.gh(this.e,Awn(e.Tg(),Ivn(BB(this.ak(),18))),null,t):e.gh(this.e,-1-this.aj(),null,t)},MWn.dj=function(n,t){var e;return e=BB(n,49),this.Dk()?this.Bk()?e.ih(this.e,this.Ak(),this.zk(),t):e.ih(this.e,Awn(e.Tg(),Ivn(BB(this.ak(),18))),null,t):e.ih(this.e,-1-this.aj(),null,t)},MWn.rk=function(){return!1},MWn.Fk=function(){return!0},MWn.wj=function(n){return x3(this.d,n)},MWn.ej=function(){return mA(this.e)},MWn.fj=function(){return 0!=this.i},MWn.ri=function(n){return Den(this.d,n)},MWn.li=function(n,t){return this.Fk()&&this.Ek()?GOn(this,n,BB(t,56)):t},MWn.Gk=function(n){return n.kh()?tfn(this.e,BB(n,49)):n},MWn.Wb=function(n){J$(this,n)},MWn.Pc=function(){return H9(this)},MWn.Qc=function(n){var t;if(this.Ek())for(t=this.i-1;t>=0;--t)Wtn(this,t);return Qwn(this,n)},MWn.Xj=function(){sqn(this)},MWn.oi=function(n,t){return Ken(this,n,t)},vX(y9n,"EcoreEList",622),wAn(496,622,R9n,yH),MWn.ai=function(){return!1},MWn.aj=function(){return this.c},MWn.bj=function(){return!1},MWn.Fk=function(){return!0},MWn.hi=function(){return!0},MWn.li=function(n,t){return t},MWn.ni=function(){return!1},MWn.c=0,vX(y9n,"EObjectEList",496),wAn(85,496,R9n,$L),MWn.bj=function(){return!0},MWn.Dk=function(){return!1},MWn.rk=function(){return!0},vX(y9n,"EObjectContainmentEList",85),wAn(545,85,R9n,LL),MWn.ci=function(){this.b=!0},MWn.fj=function(){return this.b},MWn.Xj=function(){var n;sqn(this),mA(this.e)?(n=this.b,this.b=!1,ban(this.e,new t6(this.e,2,this.c,n,!1))):this.b=!1},MWn.b=!1,vX(y9n,"EObjectContainmentEList/Unsettable",545),wAn(1140,545,R9n,YG),MWn.ii=function(n,t){var e,i;return e=BB(Cln(this,n,t),87),mA(this.e)&&Lv(this,new j9(this.a,7,(gWn(),a$t),iln(t),cL(i=e.c,88)?BB(i,26):d$t,n)),e},MWn.jj=function(n,t){return Zwn(this,BB(n,87),t)},MWn.kj=function(n,t){return Jwn(this,BB(n,87),t)},MWn.lj=function(n,t,e){return Kjn(this,BB(n,87),BB(t,87),e)},MWn.Zi=function(n,t,e,i,r){switch(n){case 3:return yZ(this,n,t,e,i,this.i>1);case 5:return yZ(this,n,t,e,i,this.i-BB(e,15).gc()>0);default:return new N7(this.e,n,this.c,t,e,i,!0)}},MWn.ij=function(){return!0},MWn.fj=function(){return Rvn(this)},MWn.Xj=function(){sqn(this)},vX(l6n,"EClassImpl/1",1140),wAn(1154,1153,Z8n),MWn.ui=function(n){var t,e,i,r,c,a,u;if(8!=(e=n.xi())){if(0==(i=apn(n)))switch(e){case 1:case 9:null!=(u=n.Bi())&&(!(t=P5(BB(u,473))).c&&(t.c=new Bo),snn(t.c,n.Ai())),null!=(a=n.zi())&&0==(1&(r=BB(a,473)).Bb)&&(!(t=P5(r)).c&&(t.c=new Bo),f9(t.c,BB(n.Ai(),26)));break;case 3:null!=(a=n.zi())&&0==(1&(r=BB(a,473)).Bb)&&(!(t=P5(r)).c&&(t.c=new Bo),f9(t.c,BB(n.Ai(),26)));break;case 5:if(null!=(a=n.zi()))for(c=BB(a,14).Kc();c.Ob();)0==(1&(r=BB(c.Pb(),473)).Bb)&&(!(t=P5(r)).c&&(t.c=new Bo),f9(t.c,BB(n.Ai(),26)));break;case 4:null!=(u=n.Bi())&&0==(1&(r=BB(u,473)).Bb)&&(!(t=P5(r)).c&&(t.c=new Bo),snn(t.c,n.Ai()));break;case 6:if(null!=(u=n.Bi()))for(c=BB(u,14).Kc();c.Ob();)0==(1&(r=BB(c.Pb(),473)).Bb)&&(!(t=P5(r)).c&&(t.c=new Bo),snn(t.c,n.Ai()))}this.Hk(i)}},MWn.Hk=function(n){dRn(this,n)},MWn.b=63,vX(l6n,"ESuperAdapter",1154),wAn(1155,1154,Z8n,dp),MWn.Hk=function(n){AIn(this,n)},vX(l6n,"EClassImpl/10",1155),wAn(1144,696,R9n),MWn.Vh=function(n,t){return BTn(this,n,t)},MWn.Wh=function(n){return bmn(this,n)},MWn.Xh=function(n,t){Cfn(this,n,t)},MWn.Yh=function(n){c6(this,n)},MWn.pi=function(n){return F9(this,n)},MWn.mi=function(n,t){return onn(this,n,t)},MWn.lk=function(n,t){throw Hp(new pv)},MWn.Zh=function(){return new ax(this)},MWn.$h=function(){return new ux(this)},MWn._h=function(n){return sin(this,n)},MWn.mk=function(n,t){throw Hp(new pv)},MWn.Wj=function(n){return this},MWn.fj=function(){return 0!=this.i},MWn.Wb=function(n){throw Hp(new pv)},MWn.Xj=function(){throw Hp(new pv)},vX(y9n,"EcoreEList/UnmodifiableEList",1144),wAn(319,1144,R9n,NO),MWn.ni=function(){return!1},vX(y9n,"EcoreEList/UnmodifiableEList/FastCompare",319),wAn(1147,319,R9n,don),MWn.Xc=function(n){var t,e;if(cL(n,170)&&-1!=(t=BB(n,170).aj()))for(e=this.i;t<e;++t)if(GC(this.g[t])===GC(n))return t;return-1},vX(l6n,"EClassImpl/1EAllStructuralFeaturesList",1147),wAn(1141,497,h8n,Eo),MWn.ri=function(n){return x8(VAt,B9n,87,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"EClassImpl/1EGenericSuperTypeEList",1141),wAn(623,497,h8n,To),MWn.ri=function(n){return x8(FAt,N9n,170,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"EClassImpl/1EStructuralFeatureUniqueEList",623),wAn(741,497,h8n,Mo),MWn.ri=function(n){return x8(JAt,N9n,18,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"EClassImpl/1ReferenceList",741),wAn(1142,497,h8n,gp),MWn.bi=function(n,t){tz(this,BB(t,34))},MWn.ri=function(n){return x8(BAt,N9n,34,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"EClassImpl/2",1142),wAn(1143,497,h8n,So),MWn.ri=function(n){return x8(BAt,N9n,34,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"EClassImpl/3",1143),wAn(1145,319,R9n,EH),MWn.Fc=function(n){return mB(this,BB(n,34))},MWn.Yh=function(n){JE(this,BB(n,34))},vX(l6n,"EClassImpl/4",1145),wAn(1146,319,R9n,TH),MWn.Fc=function(n){return yB(this,BB(n,18))},MWn.Yh=function(n){ZE(this,BB(n,18))},vX(l6n,"EClassImpl/5",1146),wAn(1148,497,h8n,Po),MWn.ri=function(n){return x8(QAt,x9n,59,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"EClassImpl/6",1148),wAn(1149,497,h8n,Io),MWn.ri=function(n){return x8(JAt,N9n,18,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"EClassImpl/7",1149),wAn(1997,1996,{3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1,69:1}),MWn.Vh=function(n,t){return uFn(this,n,t)},MWn.Wh=function(n){return uFn(this,this.Vi(),n)},MWn.Xh=function(n,t){eAn(this,n,t)},MWn.Yh=function(n){OOn(this,n)},MWn.lk=function(n,t){return wmn(this,n,t)},MWn.mk=function(n,t){return Fpn(this,n,t)},MWn.mi=function(n,t){return oFn(this,n,t)},MWn.pi=function(n){return this.Oi(n)},MWn.Zh=function(){return new ax(this)},MWn.Gi=function(){return this.Ji()},MWn.$h=function(){return new ux(this)},MWn._h=function(n){return sin(this,n)},vX(y9n,"DelegatingNotifyingInternalEListImpl",1997),wAn(742,1997,H9n),MWn.ai=function(){var n;return cL(n=itn(jY(this.b),this.aj()).Yj(),148)&&!cL(n,457)&&0==(1&n.Bj().i)},MWn.Hc=function(n){var t,e,i,r,c,a,u;if(this.Fk()){if((u=this.Vi())>4){if(!this.wj(n))return!1;if(this.rk()){if(a=(t=(e=BB(n,49)).Ug())==this.b&&(this.Dk()?e.Og(e.Vg(),BB(itn(jY(this.b),this.aj()).Yj(),26).Bj())==Ivn(BB(itn(jY(this.b),this.aj()),18)).n:-1-e.Vg()==this.aj()),this.Ek()&&!a&&!t&&e.Zg())for(i=0;i<u;++i)if(GC(Gz(this,this.Oi(i)))===GC(n))return!0;return a}if(this.Dk()&&!this.Ck()){if(GC(r=BB(n,56).ah(Ivn(BB(itn(jY(this.b),this.aj()),18))))===GC(this.b))return!0;if(null==r||!BB(r,56).kh())return!1}}if(c=this.Li(n),this.Ek()&&!c)for(i=0;i<u;++i)if(GC(e=Gz(this,this.Oi(i)))===GC(n))return!0;return c}return this.Li(n)},MWn.Zi=function(n,t,e,i,r){return new N7(this.b,n,this.aj(),t,e,i,r)},MWn.$i=function(n){ban(this.b,n)},MWn.Wj=function(n){return this},MWn._i=function(){return itn(jY(this.b),this.aj())},MWn.aj=function(){return Awn(jY(this.b),itn(jY(this.b),this.aj()))},MWn.Ai=function(){return this.b},MWn.Bk=function(){return!!itn(jY(this.b),this.aj()).Yj().Bj()},MWn.bj=function(){var n;return!(!cL(n=itn(jY(this.b),this.aj()),99)||0==(BB(n,18).Bb&h6n)&&!Ivn(BB(n,18)))},MWn.Ck=function(){var n,t,e;return!!cL(n=itn(jY(this.b),this.aj()),99)&&!!(t=Ivn(BB(n,18)))&&((e=t.t)>1||-1==e)},MWn.Dk=function(){var n;return!!cL(n=itn(jY(this.b),this.aj()),99)&&!!Ivn(BB(n,18))},MWn.Ek=function(){var n;return!!cL(n=itn(jY(this.b),this.aj()),99)&&0!=(BB(n,18).Bb&BQn)},MWn.Xc=function(n){var t,e,i;if((e=this.Qi(n))>=0)return e;if(this.Fk())for(t=0,i=this.Vi();t<i;++t)if(GC(Gz(this,this.Oi(t)))===GC(n))return t;return-1},MWn.cj=function(n,t){var e;return e=BB(n,49),this.Dk()?this.Bk()?e.gh(this.b,Ivn(BB(itn(jY(this.b),this.aj()),18)).n,BB(itn(jY(this.b),this.aj()).Yj(),26).Bj(),t):e.gh(this.b,Awn(e.Tg(),Ivn(BB(itn(jY(this.b),this.aj()),18))),null,t):e.gh(this.b,-1-this.aj(),null,t)},MWn.dj=function(n,t){var e;return e=BB(n,49),this.Dk()?this.Bk()?e.ih(this.b,Ivn(BB(itn(jY(this.b),this.aj()),18)).n,BB(itn(jY(this.b),this.aj()).Yj(),26).Bj(),t):e.ih(this.b,Awn(e.Tg(),Ivn(BB(itn(jY(this.b),this.aj()),18))),null,t):e.ih(this.b,-1-this.aj(),null,t)},MWn.rk=function(){var n;return!!cL(n=itn(jY(this.b),this.aj()),99)&&0!=(BB(n,18).Bb&h6n)},MWn.Fk=function(){return cL(itn(jY(this.b),this.aj()).Yj(),88)},MWn.wj=function(n){return itn(jY(this.b),this.aj()).Yj().wj(n)},MWn.ej=function(){return mA(this.b)},MWn.fj=function(){return!this.Ri()},MWn.hi=function(){return itn(jY(this.b),this.aj()).hi()},MWn.li=function(n,t){return eGn(this,n,t)},MWn.Wb=function(n){vqn(this),pX(this,BB(n,15))},MWn.Pc=function(){var n;if(this.Ek())for(n=this.Vi()-1;n>=0;--n)eGn(this,n,this.Oi(n));return this.Wi()},MWn.Qc=function(n){var t;if(this.Ek())for(t=this.Vi()-1;t>=0;--t)eGn(this,t,this.Oi(t));return this.Xi(n)},MWn.Xj=function(){vqn(this)},MWn.oi=function(n,t){return B9(this,n,t)},vX(y9n,"DelegatingEcoreEList",742),wAn(1150,742,H9n,uR),MWn.Hi=function(n,t){lD(this,n,BB(t,26))},MWn.Ii=function(n){e$(this,BB(n,26))},MWn.Oi=function(n){var t;return cL(t=BB(Wtn(a4(this.a),n),87).c,88)?BB(t,26):(gWn(),d$t)},MWn.Ti=function(n){var t;return cL(t=BB(fDn(a4(this.a),n),87).c,88)?BB(t,26):(gWn(),d$t)},MWn.Ui=function(n,t){return dmn(this,n,BB(t,26))},MWn.ai=function(){return!1},MWn.Zi=function(n,t,e,i,r){return null},MWn.Ji=function(){return new pp(this)},MWn.Ki=function(){sqn(a4(this.a))},MWn.Li=function(n){return Ufn(this,n)},MWn.Mi=function(n){var t;for(t=n.Kc();t.Ob();)if(!Ufn(this,t.Pb()))return!1;return!0},MWn.Ni=function(n){var t,e,i;if(cL(n,15)&&(i=BB(n,15)).gc()==a4(this.a).i){for(t=i.Kc(),e=new AL(this);t.Ob();)if(GC(t.Pb())!==GC(kpn(e)))return!1;return!0}return!1},MWn.Pi=function(){var n,t,e,i;for(t=1,n=new AL(a4(this.a));n.e!=n.i.gc();)t=31*t+((e=cL(i=BB(kpn(n),87).c,88)?BB(i,26):(gWn(),d$t))?PN(e):0);return t},MWn.Qi=function(n){var t,e,i,r;for(i=0,e=new AL(a4(this.a));e.e!=e.i.gc();){if(t=BB(kpn(e),87),GC(n)===GC(cL(r=t.c,88)?BB(r,26):(gWn(),d$t)))return i;++i}return-1},MWn.Ri=function(){return 0==a4(this.a).i},MWn.Si=function(){return null},MWn.Vi=function(){return a4(this.a).i},MWn.Wi=function(){var n,t,e,i,r,c;for(c=a4(this.a).i,r=x8(Ant,HWn,1,c,5,1),e=0,t=new AL(a4(this.a));t.e!=t.i.gc();)n=BB(kpn(t),87),r[e++]=cL(i=n.c,88)?BB(i,26):(gWn(),d$t);return r},MWn.Xi=function(n){var t,e,i,r;for(r=a4(this.a).i,n.length<r&&(n=Den(tsn(n).c,r)),n.length>r&&$X(n,r,null),e=0,t=new AL(a4(this.a));t.e!=t.i.gc();)$X(n,e++,cL(i=BB(kpn(t),87).c,88)?BB(i,26):(gWn(),d$t));return n},MWn.Yi=function(){var n,t,e,i,r;for((r=new Sk).a+="[",n=a4(this.a),t=0,i=a4(this.a).i;t<i;)cO(r,kN(cL(e=BB(Wtn(n,t),87).c,88)?BB(e,26):(gWn(),d$t))),++t<i&&(r.a+=FWn);return r.a+="]",r.a},MWn.$i=function(n){},MWn.aj=function(){return 10},MWn.Bk=function(){return!0},MWn.bj=function(){return!1},MWn.Ck=function(){return!1},MWn.Dk=function(){return!1},MWn.Ek=function(){return!0},MWn.rk=function(){return!1},MWn.Fk=function(){return!0},MWn.wj=function(n){return cL(n,88)},MWn.fj=function(){return Q0(this.a)},MWn.hi=function(){return!0},MWn.ni=function(){return!0},vX(l6n,"EClassImpl/8",1150),wAn(1151,1964,LVn,pp),MWn.Zc=function(n){return sin(this.a,n)},MWn.gc=function(){return a4(this.a.a).i},vX(l6n,"EClassImpl/8/1",1151),wAn(1152,497,h8n,Co),MWn.ri=function(n){return x8(HAt,HWn,138,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"EClassImpl/9",1152),wAn(1139,53,eYn,Cm),vX(l6n,"EClassImpl/MyHashSet",1139),wAn(566,351,{105:1,92:1,90:1,138:1,148:1,834:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,150:1,114:1,115:1,676:1},Ev),MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return iyn(this);case 4:return this.zj();case 5:return this.F;case 6:return t?Utn(this):wZ(this);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),this.A;case 8:return hN(),0!=(256&this.Bb)}return U9(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!iyn(this);case 4:return null!=this.zj();case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!wZ(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0==(256&this.Bb)}return O3(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void ZZ(this,SD(t));case 2:return void CA(this,SD(t));case 5:return void Yqn(this,SD(t));case 7:return!this.A&&(this.A=new NL(O$t,this,7)),sqn(this.A),!this.A&&(this.A=new NL(O$t,this,7)),void pX(this.A,BB(t,14));case 8:return void Zfn(this,qy(TD(t)))}Lbn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n),t)},MWn.zh=function(){return gWn(),u$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return cL(this.Cb,179)&&(BB(this.Cb,179).tb=null),void Nrn(this,null);case 2:return Dsn(this,null),void xen(this,this.D);case 5:return void Yqn(this,null);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),void sqn(this.A);case 8:return void Zfn(this,!0)}qfn(this,n-bX(this.zh()),itn(BB(yan(this,16),26)||this.zh(),n))},MWn.Gh=function(){Ifn((CPn(),Z$t),this).ne(),this.Bb|=1},MWn.Fj=function(){var n,t;if(!this.c&&!(n=G$n(Utn(this))).dc())for(t=n.Kc();t.Ob();)NKn(this,SD(t.Pb()))&&Rln(this);return this.b},MWn.zj=function(){var n;if(!this.e){n=null;try{n=iyn(this)}catch(t){if(!cL(t=lun(t),102))throw Hp(t)}this.d=null,n&&0!=(1&n.i)&&(this.d=n==$Nt?(hN(),ptt):n==ANt?iln(0):n==DNt?new Nb(0):n==xNt?0:n==LNt?jgn(0):n==RNt?rln(0):n==NNt?Pnn(0):fun(0)),this.e=!0}return this.d},MWn.Ej=function(){return 0!=(256&this.Bb)},MWn.Ik=function(n){n&&(this.D="org.eclipse.emf.common.util.AbstractEnumerator")},MWn.xk=function(n){Urn(this,n),this.Ik(n)},MWn.yk=function(n){this.C=n,this.e=!1},MWn.Ib=function(){var n;return 0!=(64&this.Db)?Iwn(this):((n=new fN(Iwn(this))).a+=" (serializable: ",yE(n,0!=(256&this.Bb)),n.a+=")",n.a)},MWn.c=!1,MWn.d=null,MWn.e=!1,vX(l6n,"EDataTypeImpl",566),wAn(457,566,{105:1,92:1,90:1,138:1,148:1,834:1,671:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,457:1,150:1,114:1,115:1,676:1},Am),MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return iyn(this);case 4:return Qsn(this);case 5:return this.F;case 6:return t?Utn(this):wZ(this);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),this.A;case 8:return hN(),0!=(256&this.Bb);case 9:return!this.a&&(this.a=new eU(WAt,this,9,5)),this.a}return U9(this,n-bX((gWn(),o$t)),itn(BB(yan(this,16),26)||o$t,n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?fyn(this,e):this.Cb.ih(this,-1-i,null,e)),TKn(this,n,6,e);case 9:return!this.a&&(this.a=new eU(WAt,this,9,5)),Ywn(this.a,n,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),o$t),t),66).Nj().Qj(this,fgn(this),t-bX((gWn(),o$t)),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 6:return TKn(this,null,6,e);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),Kpn(this.A,n,e);case 9:return!this.a&&(this.a=new eU(WAt,this,9,5)),Kpn(this.a,n,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),o$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),o$t)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!iyn(this);case 4:return!!Qsn(this);case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!wZ(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0==(256&this.Bb);case 9:return!!this.a&&0!=this.a.i}return O3(this,n-bX((gWn(),o$t)),itn(BB(yan(this,16),26)||o$t,n))},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void ZZ(this,SD(t));case 2:return void CA(this,SD(t));case 5:return void Yqn(this,SD(t));case 7:return!this.A&&(this.A=new NL(O$t,this,7)),sqn(this.A),!this.A&&(this.A=new NL(O$t,this,7)),void pX(this.A,BB(t,14));case 8:return void Zfn(this,qy(TD(t)));case 9:return!this.a&&(this.a=new eU(WAt,this,9,5)),sqn(this.a),!this.a&&(this.a=new eU(WAt,this,9,5)),void pX(this.a,BB(t,14))}Lbn(this,n-bX((gWn(),o$t)),itn(BB(yan(this,16),26)||o$t,n),t)},MWn.zh=function(){return gWn(),o$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return cL(this.Cb,179)&&(BB(this.Cb,179).tb=null),void Nrn(this,null);case 2:return Dsn(this,null),void xen(this,this.D);case 5:return void Yqn(this,null);case 7:return!this.A&&(this.A=new NL(O$t,this,7)),void sqn(this.A);case 8:return void Zfn(this,!0);case 9:return!this.a&&(this.a=new eU(WAt,this,9,5)),void sqn(this.a)}qfn(this,n-bX((gWn(),o$t)),itn(BB(yan(this,16),26)||o$t,n))},MWn.Gh=function(){var n,t;if(this.a)for(n=0,t=this.a.i;n<t;++n)vx(Wtn(this.a,n));Ifn((CPn(),Z$t),this).ne(),this.Bb|=1},MWn.zj=function(){return Qsn(this)},MWn.wj=function(n){return null!=n},MWn.Ik=function(n){},vX(l6n,"EEnumImpl",457),wAn(573,438,{105:1,92:1,90:1,1940:1,678:1,147:1,191:1,56:1,108:1,49:1,97:1,573:1,150:1,114:1,115:1},jv),MWn.ne=function(){return this.zb},MWn.Qg=function(n){return lkn(this,n)},MWn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return iln(this.d);case 3:return this.b?this.b:this.a;case 4:return null==(i=this.c)?this.zb:i;case 5:return this.Db>>16==5?BB(this.Cb,671):null}return U9(this,n-bX((gWn(),s$t)),itn(BB(yan(this,16),26)||s$t,n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 5:return this.Cb&&(e=(i=this.Db>>16)>=0?lkn(this,e):this.Cb.ih(this,-1-i,null,e)),TKn(this,n,5,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),s$t),t),66).Nj().Qj(this,fgn(this),t-bX((gWn(),s$t)),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 5:return TKn(this,null,5,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),s$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),s$t)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0!=this.d;case 3:return!!this.b;case 4:return null!=this.c;case 5:return!(this.Db>>16!=5||!BB(this.Cb,671))}return O3(this,n-bX((gWn(),s$t)),itn(BB(yan(this,16),26)||s$t,n))},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void Nrn(this,SD(t));case 2:return void $en(this,BB(t,19).a);case 3:return void gOn(this,BB(t,1940));case 4:return void Fin(this,SD(t))}Lbn(this,n-bX((gWn(),s$t)),itn(BB(yan(this,16),26)||s$t,n),t)},MWn.zh=function(){return gWn(),s$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return void Nrn(this,null);case 2:return void $en(this,0);case 3:return void gOn(this,null);case 4:return void Fin(this,null)}qfn(this,n-bX((gWn(),s$t)),itn(BB(yan(this,16),26)||s$t,n))},MWn.Ib=function(){var n;return null==(n=this.c)?this.zb:n},MWn.b=null,MWn.c=null,MWn.d=0,vX(l6n,"EEnumLiteralImpl",573);var L$t,N$t,x$t,D$t=bq(l6n,"EFactoryImpl/InternalEDateTimeFormat");wAn(489,1,{2015:1},vp),vX(l6n,"EFactoryImpl/1ClientInternalEDateTimeFormat",489),wAn(241,115,{105:1,92:1,90:1,87:1,56:1,108:1,49:1,97:1,241:1,114:1,115:1},_p),MWn.Sg=function(n,t,e){var i;return e=TKn(this,n,t,e),this.e&&cL(n,170)&&(i=kLn(this,this.e))!=this.c&&(e=azn(this,i,e)),e},MWn._g=function(n,t,e){switch(n){case 0:return this.f;case 1:return!this.d&&(this.d=new $L(VAt,this,1)),this.d;case 2:return t?lFn(this):this.c;case 3:return this.b;case 4:return this.e;case 5:return t?qvn(this):this.a}return U9(this,n-bX((gWn(),f$t)),itn(BB(yan(this,16),26)||f$t,n),t,e)},MWn.jh=function(n,t,e){switch(t){case 0:return nfn(this,null,e);case 1:return!this.d&&(this.d=new $L(VAt,this,1)),Kpn(this.d,n,e);case 3:return Zhn(this,null,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),f$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),f$t)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.f;case 1:return!!this.d&&0!=this.d.i;case 2:return!!this.c;case 3:return!!this.b;case 4:return!!this.e;case 5:return!!this.a}return O3(this,n-bX((gWn(),f$t)),itn(BB(yan(this,16),26)||f$t,n))},MWn.sh=function(n,t){switch(n){case 0:return void jEn(this,BB(t,87));case 1:return!this.d&&(this.d=new $L(VAt,this,1)),sqn(this.d),!this.d&&(this.d=new $L(VAt,this,1)),void pX(this.d,BB(t,14));case 3:return void kEn(this,BB(t,87));case 4:return void DMn(this,BB(t,836));case 5:return void cen(this,BB(t,138))}Lbn(this,n-bX((gWn(),f$t)),itn(BB(yan(this,16),26)||f$t,n),t)},MWn.zh=function(){return gWn(),f$t},MWn.Bh=function(n){switch(n){case 0:return void jEn(this,null);case 1:return!this.d&&(this.d=new $L(VAt,this,1)),void sqn(this.d);case 3:return void kEn(this,null);case 4:return void DMn(this,null);case 5:return void cen(this,null)}qfn(this,n-bX((gWn(),f$t)),itn(BB(yan(this,16),26)||f$t,n))},MWn.Ib=function(){var n;return(n=new lN(P$n(this))).a+=" (expression: ",bHn(this,n),n.a+=")",n.a},vX(l6n,"EGenericTypeImpl",241),wAn(1969,1964,q9n),MWn.Xh=function(n,t){nR(this,n,t)},MWn.lk=function(n,t){return nR(this,this.gc(),n),t},MWn.pi=function(n){return Dpn(this.Gi(),n)},MWn.Zh=function(){return this.$h()},MWn.Gi=function(){return new Pp(this)},MWn.$h=function(){return this._h(0)},MWn._h=function(n){return this.Gi().Zc(n)},MWn.mk=function(n,t){return ywn(this,n,!0),t},MWn.ii=function(n,t){var e;return e=tkn(this,t),this.Zc(n).Rb(e),e},MWn.ji=function(n,t){ywn(this,t,!0),this.Zc(n).Rb(t)},vX(y9n,"AbstractSequentialInternalEList",1969),wAn(486,1969,q9n,QN),MWn.pi=function(n){return Dpn(this.Gi(),n)},MWn.Zh=function(){return null==this.b?(YM(),YM(),x$t):this.Jk()},MWn.Gi=function(){return new DO(this.a,this.b)},MWn.$h=function(){return null==this.b?(YM(),YM(),x$t):this.Jk()},MWn._h=function(n){var t,e;if(null==this.b){if(n<0||n>1)throw Hp(new Ay(e9n+n+", size=0"));return YM(),YM(),x$t}for(e=this.Jk(),t=0;t<n;++t)Man(e);return e},MWn.dc=function(){var n,t,e,i,r,c;if(null!=this.b)for(e=0;e<this.b.length;++e)if(n=this.b[e],!this.Mk()||this.a.mh(n))if(c=this.a.bh(n,!1),ZM(),BB(n,66).Oj()){for(i=0,r=(t=BB(c,153)).gc();i<r;++i)if(wX(t.il(i))&&null!=t.jl(i))return!1}else if(n.$j()){if(!BB(c,14).dc())return!1}else if(null!=c)return!1;return!0},MWn.Kc=function(){return Ern(this)},MWn.Zc=function(n){var t,e;if(null==this.b){if(0!=n)throw Hp(new Ay(e9n+n+", size=0"));return YM(),YM(),x$t}for(e=this.Lk()?this.Kk():this.Jk(),t=0;t<n;++t)Man(e);return e},MWn.ii=function(n,t){throw Hp(new pv)},MWn.ji=function(n,t){throw Hp(new pv)},MWn.Jk=function(){return new YN(this.a,this.b)},MWn.Kk=function(){return new Vx(this.a,this.b)},MWn.Lk=function(){return!0},MWn.gc=function(){var n,t,e,i,r,c,a;if(r=0,null!=this.b)for(e=0;e<this.b.length;++e)if(n=this.b[e],!this.Mk()||this.a.mh(n))if(a=this.a.bh(n,!1),ZM(),BB(n,66).Oj())for(i=0,c=(t=BB(a,153)).gc();i<c;++i)wX(t.il(i))&&null!=t.jl(i)&&++r;else n.$j()?r+=BB(a,14).gc():null!=a&&++r;return r},MWn.Mk=function(){return!0},vX(y9n,"EContentsEList",486),wAn(1156,486,q9n,Wx),MWn.Jk=function(){return new Qx(this.a,this.b)},MWn.Kk=function(){return new Yx(this.a,this.b)},MWn.Mk=function(){return!1},vX(l6n,"ENamedElementImpl/1",1156),wAn(279,1,G9n,YN),MWn.Nb=function(n){fU(this,n)},MWn.Rb=function(n){throw Hp(new pv)},MWn.Nk=function(n){if(0!=this.g||this.e)throw Hp(new Fy("Iterator already in use or already filtered"));this.e=n},MWn.Ob=function(){var n,t,e,i,r,c;switch(this.g){case 3:case 2:return!0;case 1:return!1;case-3:this.p?this.p.Pb():++this.n;default:if(this.k&&(this.p?kPn(this,this.p):pOn(this)))return r=this.p?this.p.Pb():this.j?this.j.pi(this.n++):this.k.Xb(this.n++),this.f?((n=BB(r,72)).ak(),e=n.dd(),this.i=e):(e=r,this.i=e),this.g=3,!0;for(;this.d<this.c.length;)if(t=this.c[this.d++],(!this.e||t.Gj()!=NOt||0!=t.aj())&&(!this.Mk()||this.b.mh(t)))if(c=this.b.bh(t,this.Lk()),this.f=(ZM(),BB(t,66).Oj()),this.f||t.$j()){if(this.Lk()?(i=BB(c,15),this.k=i):(i=BB(c,69),this.k=this.j=i),cL(this.k,54)?(this.p=null,this.o=this.k.gc(),this.n=0):this.p=this.j?this.j.$h():this.k.Yc(),this.p?kPn(this,this.p):pOn(this))return r=this.p?this.p.Pb():this.j?this.j.pi(this.n++):this.k.Xb(this.n++),this.f?((n=BB(r,72)).ak(),e=n.dd(),this.i=e):(e=r,this.i=e),this.g=3,!0}else if(null!=c)return this.k=null,this.p=null,e=c,this.i=e,this.g=2,!0;return this.k=null,this.p=null,this.f=!1,this.g=1,!1}},MWn.Sb=function(){var n,t,e,i,r,c;switch(this.g){case-3:case-2:return!0;case-1:return!1;case 3:this.p?this.p.Ub():--this.n;default:if(this.k&&(this.p?jPn(this,this.p):wIn(this)))return r=this.p?this.p.Ub():this.j?this.j.pi(--this.n):this.k.Xb(--this.n),this.f?((n=BB(r,72)).ak(),e=n.dd(),this.i=e):(e=r,this.i=e),this.g=-3,!0;for(;this.d>0;)if(t=this.c[--this.d],(!this.e||t.Gj()!=NOt||0!=t.aj())&&(!this.Mk()||this.b.mh(t)))if(c=this.b.bh(t,this.Lk()),this.f=(ZM(),BB(t,66).Oj()),this.f||t.$j()){if(this.Lk()?(i=BB(c,15),this.k=i):(i=BB(c,69),this.k=this.j=i),cL(this.k,54)?(this.o=this.k.gc(),this.n=this.o):this.p=this.j?this.j._h(this.k.gc()):this.k.Zc(this.k.gc()),this.p?jPn(this,this.p):wIn(this))return r=this.p?this.p.Ub():this.j?this.j.pi(--this.n):this.k.Xb(--this.n),this.f?((n=BB(r,72)).ak(),e=n.dd(),this.i=e):(e=r,this.i=e),this.g=-3,!0}else if(null!=c)return this.k=null,this.p=null,e=c,this.i=e,this.g=-2,!0;return this.k=null,this.p=null,this.g=-1,!1}},MWn.Pb=function(){return Man(this)},MWn.Tb=function(){return this.a},MWn.Ub=function(){var n;if(this.g<-1||this.Sb())return--this.a,this.g=0,n=this.i,this.Sb(),n;throw Hp(new yv)},MWn.Vb=function(){return this.a-1},MWn.Qb=function(){throw Hp(new pv)},MWn.Lk=function(){return!1},MWn.Wb=function(n){throw Hp(new pv)},MWn.Mk=function(){return!0},MWn.a=0,MWn.d=0,MWn.f=!1,MWn.g=0,MWn.n=0,MWn.o=0,vX(y9n,"EContentsEList/FeatureIteratorImpl",279),wAn(697,279,G9n,Vx),MWn.Lk=function(){return!0},vX(y9n,"EContentsEList/ResolvingFeatureIteratorImpl",697),wAn(1157,697,G9n,Yx),MWn.Mk=function(){return!1},vX(l6n,"ENamedElementImpl/1/1",1157),wAn(1158,279,G9n,Qx),MWn.Mk=function(){return!1},vX(l6n,"ENamedElementImpl/1/2",1158),wAn(36,143,t9n,f4,l4,nU,k9,N7,t6,Hen,S0,qen,P0,J5,I0,Uen,C0,Z5,O0,Gen,A0,tU,j9,GQ,zen,$0,n6,L0),MWn._i=function(){return h9(this)},MWn.gj=function(){var n;return(n=h9(this))?n.zj():null},MWn.yi=function(n){return-1==this.b&&this.a&&(this.b=this.c.Xg(this.a.aj(),this.a.Gj())),this.c.Og(this.b,n)},MWn.Ai=function(){return this.c},MWn.hj=function(){var n;return!!(n=h9(this))&&n.Kj()},MWn.b=-1,vX(l6n,"ENotificationImpl",36),wAn(399,284,{105:1,92:1,90:1,147:1,191:1,56:1,59:1,108:1,472:1,49:1,97:1,150:1,399:1,284:1,114:1,115:1},$m),MWn.Qg=function(n){return Pkn(this,n)},MWn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return hN(),0!=(256&this.Bb);case 3:return hN(),0!=(512&this.Bb);case 4:return iln(this.s);case 5:return iln(this.t);case 6:return hN(),(i=this.t)>1||-1==i;case 7:return hN(),this.s>=1;case 8:return t?Ckn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?BB(this.Cb,26):null;case 11:return!this.d&&(this.d=new NL(O$t,this,11)),this.d;case 12:return!this.c&&(this.c=new eU(YAt,this,12,10)),this.c;case 13:return!this.a&&(this.a=new oR(this,this)),this.a;case 14:return H7(this)}return U9(this,n-bX((gWn(),g$t)),itn(BB(yan(this,16),26)||g$t,n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?Pkn(this,e):this.Cb.ih(this,-1-i,null,e)),TKn(this,n,10,e);case 12:return!this.c&&(this.c=new eU(YAt,this,12,10)),Ywn(this.c,n,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),g$t),t),66).Nj().Qj(this,fgn(this),t-bX((gWn(),g$t)),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 9:return gX(this,e);case 10:return TKn(this,null,10,e);case 11:return!this.d&&(this.d=new NL(O$t,this,11)),Kpn(this.d,n,e);case 12:return!this.c&&(this.c=new eU(YAt,this,12,10)),Kpn(this.c,n,e);case 14:return Kpn(H7(this),n,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),g$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),g$t)),n,e)},MWn.lh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yW(this.q).i);case 10:return!(this.Db>>16!=10||!BB(this.Cb,26));case 11:return!!this.d&&0!=this.d.i;case 12:return!!this.c&&0!=this.c.i;case 13:return!(!this.a||0==H7(this.a.a).i||this.b&&_vn(this.b));case 14:return!!this.b&&_vn(this.b)}return O3(this,n-bX((gWn(),g$t)),itn(BB(yan(this,16),26)||g$t,n))},MWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void Nrn(this,SD(t));case 2:return void Yfn(this,qy(TD(t)));case 3:return void nln(this,qy(TD(t)));case 4:return void Len(this,BB(t,19).a);case 5:return void Nen(this,BB(t,19).a);case 8:return void Chn(this,BB(t,138));case 9:return void((e=HTn(this,BB(t,87),null))&&e.Fi());case 11:return!this.d&&(this.d=new NL(O$t,this,11)),sqn(this.d),!this.d&&(this.d=new NL(O$t,this,11)),void pX(this.d,BB(t,14));case 12:return!this.c&&(this.c=new eU(YAt,this,12,10)),sqn(this.c),!this.c&&(this.c=new eU(YAt,this,12,10)),void pX(this.c,BB(t,14));case 13:return!this.a&&(this.a=new oR(this,this)),vqn(this.a),!this.a&&(this.a=new oR(this,this)),void pX(this.a,BB(t,14));case 14:return sqn(H7(this)),void pX(H7(this),BB(t,14))}Lbn(this,n-bX((gWn(),g$t)),itn(BB(yan(this,16),26)||g$t,n),t)},MWn.zh=function(){return gWn(),g$t},MWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return void Nrn(this,null);case 2:return void Yfn(this,!0);case 3:return void nln(this,!0);case 4:return void Len(this,0);case 5:return void Nen(this,1);case 8:return void Chn(this,null);case 9:return void((t=HTn(this,null,null))&&t.Fi());case 11:return!this.d&&(this.d=new NL(O$t,this,11)),void sqn(this.d);case 12:return!this.c&&(this.c=new eU(YAt,this,12,10)),void sqn(this.c);case 13:return void(this.a&&vqn(this.a));case 14:return void(this.b&&sqn(this.b))}qfn(this,n-bX((gWn(),g$t)),itn(BB(yan(this,16),26)||g$t,n))},MWn.Gh=function(){var n,t;if(this.c)for(n=0,t=this.c.i;n<t;++n)vx(Wtn(this.c,n));Ckn(this),this.Bb|=1},vX(l6n,"EOperationImpl",399),wAn(505,742,H9n,oR),MWn.Hi=function(n,t){fD(this,n,BB(t,138))},MWn.Ii=function(n){i$(this,BB(n,138))},MWn.Oi=function(n){return BB(Wtn(H7(this.a),n),87).c||(gWn(),l$t)},MWn.Ti=function(n){return BB(fDn(H7(this.a),n),87).c||(gWn(),l$t)},MWn.Ui=function(n,t){return bgn(this,n,BB(t,138))},MWn.ai=function(){return!1},MWn.Zi=function(n,t,e,i,r){return null},MWn.Ji=function(){return new mp(this)},MWn.Ki=function(){sqn(H7(this.a))},MWn.Li=function(n){return oln(this,n)},MWn.Mi=function(n){var t;for(t=n.Kc();t.Ob();)if(!oln(this,t.Pb()))return!1;return!0},MWn.Ni=function(n){var t,e,i;if(cL(n,15)&&(i=BB(n,15)).gc()==H7(this.a).i){for(t=i.Kc(),e=new AL(this);t.Ob();)if(GC(t.Pb())!==GC(kpn(e)))return!1;return!0}return!1},MWn.Pi=function(){var n,t,e;for(t=1,n=new AL(H7(this.a));n.e!=n.i.gc();)t=31*t+((e=BB(kpn(n),87).c||(gWn(),l$t))?nsn(e):0);return t},MWn.Qi=function(n){var t,e,i;for(i=0,e=new AL(H7(this.a));e.e!=e.i.gc();){if(t=BB(kpn(e),87),GC(n)===GC(t.c||(gWn(),l$t)))return i;++i}return-1},MWn.Ri=function(){return 0==H7(this.a).i},MWn.Si=function(){return null},MWn.Vi=function(){return H7(this.a).i},MWn.Wi=function(){var n,t,e,i,r;for(r=H7(this.a).i,i=x8(Ant,HWn,1,r,5,1),e=0,t=new AL(H7(this.a));t.e!=t.i.gc();)n=BB(kpn(t),87),i[e++]=n.c||(gWn(),l$t);return i},MWn.Xi=function(n){var t,e,i;for(i=H7(this.a).i,n.length<i&&(n=Den(tsn(n).c,i)),n.length>i&&$X(n,i,null),e=0,t=new AL(H7(this.a));t.e!=t.i.gc();)$X(n,e++,BB(kpn(t),87).c||(gWn(),l$t));return n},MWn.Yi=function(){var n,t,e,i;for((i=new Sk).a+="[",n=H7(this.a),t=0,e=H7(this.a).i;t<e;)cO(i,kN(BB(Wtn(n,t),87).c||(gWn(),l$t))),++t<e&&(i.a+=FWn);return i.a+="]",i.a},MWn.$i=function(n){},MWn.aj=function(){return 13},MWn.Bk=function(){return!0},MWn.bj=function(){return!1},MWn.Ck=function(){return!1},MWn.Dk=function(){return!1},MWn.Ek=function(){return!0},MWn.rk=function(){return!1},MWn.Fk=function(){return!0},MWn.wj=function(n){return cL(n,138)},MWn.fj=function(){return V0(this.a)},MWn.hi=function(){return!0},MWn.ni=function(){return!0},vX(l6n,"EOperationImpl/1",505),wAn(1340,1964,LVn,mp),MWn.Zc=function(n){return sin(this.a,n)},MWn.gc=function(){return H7(this.a.a).i},vX(l6n,"EOperationImpl/1/1",1340),wAn(1341,545,R9n,JG),MWn.ii=function(n,t){var e;return e=BB(Cln(this,n,t),87),mA(this.e)&&Lv(this,new j9(this.a,7,(gWn(),p$t),iln(t),e.c||l$t,n)),e},MWn.jj=function(n,t){return Mfn(this,BB(n,87),t)},MWn.kj=function(n,t){return Sfn(this,BB(n,87),t)},MWn.lj=function(n,t,e){return Wgn(this,BB(n,87),BB(t,87),e)},MWn.Zi=function(n,t,e,i,r){switch(n){case 3:return yZ(this,n,t,e,i,this.i>1);case 5:return yZ(this,n,t,e,i,this.i-BB(e,15).gc()>0);default:return new N7(this.e,n,this.c,t,e,i,!0)}},MWn.ij=function(){return!0},MWn.fj=function(){return _vn(this)},MWn.Xj=function(){sqn(this)},vX(l6n,"EOperationImpl/2",1341),wAn(498,1,{1938:1,498:1},OC),vX(l6n,"EPackageImpl/1",498),wAn(16,85,R9n,eU),MWn.zk=function(){return this.d},MWn.Ak=function(){return this.b},MWn.Dk=function(){return!0},MWn.b=0,vX(y9n,"EObjectContainmentWithInverseEList",16),wAn(353,16,R9n,e_),MWn.Ek=function(){return!0},MWn.li=function(n,t){return GOn(this,n,BB(t,56))},vX(y9n,"EObjectContainmentWithInverseEList/Resolving",353),wAn(298,353,R9n,Jz),MWn.ci=function(){this.a.tb=null},vX(l6n,"EPackageImpl/2",298),wAn(1228,1,{},Oo),vX(l6n,"EPackageImpl/3",1228),wAn(718,43,tYn,Nm),MWn._b=function(n){return XC(n)?eY(this,n):!!AY(this.f,n)},vX(l6n,"EPackageRegistryImpl",718),wAn(509,284,{105:1,92:1,90:1,147:1,191:1,56:1,2017:1,108:1,472:1,49:1,97:1,150:1,509:1,284:1,114:1,115:1},Lm),MWn.Qg=function(n){return Ikn(this,n)},MWn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return hN(),0!=(256&this.Bb);case 3:return hN(),0!=(512&this.Bb);case 4:return iln(this.s);case 5:return iln(this.t);case 6:return hN(),(i=this.t)>1||-1==i;case 7:return hN(),this.s>=1;case 8:return t?Ckn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?BB(this.Cb,59):null}return U9(this,n-bX((gWn(),m$t)),itn(BB(yan(this,16),26)||m$t,n),t,e)},MWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Ywn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?Ikn(this,e):this.Cb.ih(this,-1-i,null,e)),TKn(this,n,10,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),m$t),t),66).Nj().Qj(this,fgn(this),t-bX((gWn(),m$t)),n,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 9:return gX(this,e);case 10:return TKn(this,null,10,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),m$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),m$t)),n,e)},MWn.lh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yW(this.q).i);case 10:return!(this.Db>>16!=10||!BB(this.Cb,59))}return O3(this,n-bX((gWn(),m$t)),itn(BB(yan(this,16),26)||m$t,n))},MWn.zh=function(){return gWn(),m$t},vX(l6n,"EParameterImpl",509),wAn(99,449,{105:1,92:1,90:1,147:1,191:1,56:1,18:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,99:1,449:1,284:1,114:1,115:1,677:1},pD),MWn._g=function(n,t,e){var i,r;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return hN(),0!=(256&this.Bb);case 3:return hN(),0!=(512&this.Bb);case 4:return iln(this.s);case 5:return iln(this.t);case 6:return hN(),(r=this.t)>1||-1==r;case 7:return hN(),this.s>=1;case 8:return t?Ckn(this):this.r;case 9:return this.q;case 10:return hN(),0!=(this.Bb&k6n);case 11:return hN(),0!=(this.Bb&M9n);case 12:return hN(),0!=(this.Bb&KQn);case 13:return this.j;case 14:return qLn(this);case 15:return hN(),0!=(this.Bb&T9n);case 16:return hN(),0!=(this.Bb&hVn);case 17:return dZ(this);case 18:return hN(),0!=(this.Bb&h6n);case 19:return hN(),!(!(i=Ivn(this))||0==(i.Bb&h6n));case 20:return hN(),0!=(this.Bb&BQn);case 21:return t?Ivn(this):this.b;case 22:return t?Con(this):_5(this);case 23:return!this.a&&(this.a=new RL(BAt,this,23)),this.a}return U9(this,n-bX((gWn(),y$t)),itn(BB(yan(this,16),26)||y$t,n),t,e)},MWn.lh=function(n){var t,e;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(e=this.t)>1||-1==e;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==yW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==yW(this.q).i);case 10:return 0==(this.Bb&k6n);case 11:return 0!=(this.Bb&M9n);case 12:return 0!=(this.Bb&KQn);case 13:return null!=this.j;case 14:return null!=qLn(this);case 15:return 0!=(this.Bb&T9n);case 16:return 0!=(this.Bb&hVn);case 17:return!!dZ(this);case 18:return 0!=(this.Bb&h6n);case 19:return!!(t=Ivn(this))&&0!=(t.Bb&h6n);case 20:return 0==(this.Bb&BQn);case 21:return!!this.b;case 22:return!!_5(this);case 23:return!!this.a&&0!=this.a.i}return O3(this,n-bX((gWn(),y$t)),itn(BB(yan(this,16),26)||y$t,n))},MWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void JZ(this,SD(t));case 2:return void Yfn(this,qy(TD(t)));case 3:return void nln(this,qy(TD(t)));case 4:return void Len(this,BB(t,19).a);case 5:return void Nen(this,BB(t,19).a);case 8:return void Chn(this,BB(t,138));case 9:return void((e=HTn(this,BB(t,87),null))&&e.Fi());case 10:return void Aln(this,qy(TD(t)));case 11:return void Nln(this,qy(TD(t)));case 12:return void $ln(this,qy(TD(t)));case 13:return void KC(this,SD(t));case 15:return void Lln(this,qy(TD(t)));case 16:return void qln(this,qy(TD(t)));case 18:return void YZ(this,qy(TD(t)));case 20:return void Uln(this,qy(TD(t)));case 21:return void rrn(this,BB(t,18));case 23:return!this.a&&(this.a=new RL(BAt,this,23)),sqn(this.a),!this.a&&(this.a=new RL(BAt,this,23)),void pX(this.a,BB(t,14))}Lbn(this,n-bX((gWn(),y$t)),itn(BB(yan(this,16),26)||y$t,n),t)},MWn.zh=function(){return gWn(),y$t},MWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return cL(this.Cb,88)&&AIn(P5(BB(this.Cb,88)),4),void Nrn(this,null);case 2:return void Yfn(this,!0);case 3:return void nln(this,!0);case 4:return void Len(this,0);case 5:return void Nen(this,1);case 8:return void Chn(this,null);case 9:return void((t=HTn(this,null,null))&&t.Fi());case 10:return void Aln(this,!0);case 11:return void Nln(this,!1);case 12:return void $ln(this,!1);case 13:return this.i=null,void arn(this,null);case 15:return void Lln(this,!1);case 16:return void qln(this,!1);case 18:return zln(this,!1),void(cL(this.Cb,88)&&AIn(P5(BB(this.Cb,88)),2));case 20:return void Uln(this,!0);case 21:return void rrn(this,null);case 23:return!this.a&&(this.a=new RL(BAt,this,23)),void sqn(this.a)}qfn(this,n-bX((gWn(),y$t)),itn(BB(yan(this,16),26)||y$t,n))},MWn.Gh=function(){Con(this),kV(B7((CPn(),Z$t),this)),Ckn(this),this.Bb|=1},MWn.Lj=function(){return Ivn(this)},MWn.qk=function(){var n;return!!(n=Ivn(this))&&0!=(n.Bb&h6n)},MWn.rk=function(){return 0!=(this.Bb&h6n)},MWn.sk=function(){return 0!=(this.Bb&BQn)},MWn.nk=function(n,t){return this.c=null,Pfn(this,n,t)},MWn.Ib=function(){var n;return 0!=(64&this.Db)?ERn(this):((n=new fN(ERn(this))).a+=" (containment: ",yE(n,0!=(this.Bb&h6n)),n.a+=", resolveProxies: ",yE(n,0!=(this.Bb&BQn)),n.a+=")",n.a)},vX(l6n,"EReferenceImpl",99),wAn(548,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,548:1,114:1,115:1},Ao),MWn.Fb=function(n){return this===n},MWn.cd=function(){return this.b},MWn.dd=function(){return this.c},MWn.Hb=function(){return PN(this)},MWn.Uh=function(n){vq(this,SD(n))},MWn.ed=function(n){return $H(this,SD(n))},MWn._g=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return U9(this,n-bX((gWn(),k$t)),itn(BB(yan(this,16),26)||k$t,n),t,e)},MWn.lh=function(n){switch(n){case 0:return null!=this.b;case 1:return null!=this.c}return O3(this,n-bX((gWn(),k$t)),itn(BB(yan(this,16),26)||k$t,n))},MWn.sh=function(n,t){switch(n){case 0:return void mq(this,SD(t));case 1:return void _in(this,SD(t))}Lbn(this,n-bX((gWn(),k$t)),itn(BB(yan(this,16),26)||k$t,n),t)},MWn.zh=function(){return gWn(),k$t},MWn.Bh=function(n){switch(n){case 0:return void Rin(this,null);case 1:return void _in(this,null)}qfn(this,n-bX((gWn(),k$t)),itn(BB(yan(this,16),26)||k$t,n))},MWn.Sh=function(){var n;return-1==this.a&&(n=this.b,this.a=null==n?0:vvn(n)),this.a},MWn.Th=function(n){this.a=n},MWn.Ib=function(){var n;return 0!=(64&this.Db)?P$n(this):((n=new fN(P$n(this))).a+=" (key: ",cO(n,this.b),n.a+=", value: ",cO(n,this.c),n.a+=")",n.a)},MWn.a=-1,MWn.b=null,MWn.c=null;var R$t,_$t,K$t,F$t,B$t,H$t,q$t,G$t,z$t,U$t,X$t=vX(l6n,"EStringToStringMapEntryImpl",548),W$t=bq(y9n,"FeatureMap/Entry/Internal");wAn(565,1,z9n),MWn.Ok=function(n){return this.Pk(BB(n,49))},MWn.Pk=function(n){return this.Ok(n)},MWn.Fb=function(n){var t,e;return this===n||!!cL(n,72)&&(t=BB(n,72)).ak()==this.c&&(null==(e=this.dd())?null==t.dd():Nfn(e,t.dd()))},MWn.ak=function(){return this.c},MWn.Hb=function(){var n;return n=this.dd(),nsn(this.c)^(null==n?0:nsn(n))},MWn.Ib=function(){var n,t;return t=Utn((n=this.c).Hj()).Ph(),n.ne(),(null!=t&&0!=t.length?t+":"+n.ne():n.ne())+"="+this.dd()},vX(l6n,"EStructuralFeatureImpl/BasicFeatureMapEntry",565),wAn(776,565,z9n,rR),MWn.Pk=function(n){return new rR(this.c,n)},MWn.dd=function(){return this.a},MWn.Qk=function(n,t,e){return Scn(this,n,this.a,t,e)},MWn.Rk=function(n,t,e){return Pcn(this,n,this.a,t,e)},vX(l6n,"EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry",776),wAn(1314,1,{},AC),MWn.Pj=function(n,t,e,i,r){return BB(S9(n,this.b),215).nl(this.a).Wj(i)},MWn.Qj=function(n,t,e,i,r){return BB(S9(n,this.b),215).el(this.a,i,r)},MWn.Rj=function(n,t,e,i,r){return BB(S9(n,this.b),215).fl(this.a,i,r)},MWn.Sj=function(n,t,e){return BB(S9(n,this.b),215).nl(this.a).fj()},MWn.Tj=function(n,t,e,i){BB(S9(n,this.b),215).nl(this.a).Wb(i)},MWn.Uj=function(n,t,e){return BB(S9(n,this.b),215).nl(this.a)},MWn.Vj=function(n,t,e){BB(S9(n,this.b),215).nl(this.a).Xj()},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator",1314),wAn(89,1,{},PB,lQ,RY,w4),MWn.Pj=function(n,t,e,i,r){var c;if(null==(c=t.Ch(e))&&t.Dh(e,c=iWn(this,n)),!r)switch(this.e){case 50:case 41:return BB(c,589).sj();case 40:return BB(c,215).kl()}return c},MWn.Qj=function(n,t,e,i,r){var c;return null==(c=t.Ch(e))&&t.Dh(e,c=iWn(this,n)),BB(c,69).lk(i,r)},MWn.Rj=function(n,t,e,i,r){var c;return null!=(c=t.Ch(e))&&(r=BB(c,69).mk(i,r)),r},MWn.Sj=function(n,t,e){var i;return null!=(i=t.Ch(e))&&BB(i,76).fj()},MWn.Tj=function(n,t,e,i){var r;!(r=BB(t.Ch(e),76))&&t.Dh(e,r=iWn(this,n)),r.Wb(i)},MWn.Uj=function(n,t,e){var i;return null==(i=t.Ch(e))&&t.Dh(e,i=iWn(this,n)),cL(i,76)?BB(i,76):new Ep(BB(t.Ch(e),15))},MWn.Vj=function(n,t,e){var i;!(i=BB(t.Ch(e),76))&&t.Dh(e,i=iWn(this,n)),i.Xj()},MWn.b=0,MWn.e=0,vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateMany",89),wAn(504,1,{}),MWn.Qj=function(n,t,e,i,r){throw Hp(new pv)},MWn.Rj=function(n,t,e,i,r){throw Hp(new pv)},MWn.Uj=function(n,t,e){return new bQ(this,n,t,e)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingle",504),wAn(1331,1,k9n,bQ),MWn.Wj=function(n){return this.a.Pj(this.c,this.d,this.b,n,!0)},MWn.fj=function(){return this.a.Sj(this.c,this.d,this.b)},MWn.Wb=function(n){this.a.Tj(this.c,this.d,this.b,n)},MWn.Xj=function(){this.a.Vj(this.c,this.d,this.b)},MWn.b=0,vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingle/1",1331),wAn(769,504,{},mJ),MWn.Pj=function(n,t,e,i,r){return g_n(n,n.eh(),n.Vg())==this.b?this.sk()&&i?cAn(n):n.eh():null},MWn.Qj=function(n,t,e,i,r){var c,a;return n.eh()&&(r=(c=n.Vg())>=0?n.Qg(r):n.eh().ih(n,-1-c,null,r)),a=Awn(n.Tg(),this.e),n.Sg(i,a,r)},MWn.Rj=function(n,t,e,i,r){var c;return c=Awn(n.Tg(),this.e),n.Sg(null,c,r)},MWn.Sj=function(n,t,e){var i;return i=Awn(n.Tg(),this.e),!!n.eh()&&n.Vg()==i},MWn.Tj=function(n,t,e,i){var r,c,a,u,o;if(null!=i&&!SFn(this.a,i))throw Hp(new _y(U9n+(cL(i,56)?dEn(BB(i,56).Tg()):utn(tsn(i)))+X9n+this.a+"'"));if(r=n.eh(),a=Awn(n.Tg(),this.e),GC(i)!==GC(r)||n.Vg()!=a&&null!=i){if(vkn(n,BB(i,56)))throw Hp(new Ky(w6n+n.Ib()));o=null,r&&(o=(c=n.Vg())>=0?n.Qg(o):n.eh().ih(n,-1-c,null,o)),(u=BB(i,49))&&(o=u.gh(n,Awn(u.Tg(),this.b),null,o)),(o=n.Sg(u,a,o))&&o.Fi()}else n.Lg()&&n.Mg()&&ban(n,new nU(n,1,a,i,i))},MWn.Vj=function(n,t,e){var i,r,c;n.eh()?(c=(i=n.Vg())>=0?n.Qg(null):n.eh().ih(n,-1-i,null,null),r=Awn(n.Tg(),this.e),(c=n.Sg(null,r,c))&&c.Fi()):n.Lg()&&n.Mg()&&ban(n,new tU(n,1,this.e,null,null))},MWn.sk=function(){return!1},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainer",769),wAn(1315,769,{},IB),MWn.sk=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving",1315),wAn(563,504,{}),MWn.Pj=function(n,t,e,i,r){var c;return null==(c=t.Ch(e))?this.b:GC(c)===GC(R$t)?null:c},MWn.Sj=function(n,t,e){var i;return null!=(i=t.Ch(e))&&(GC(i)===GC(R$t)||!Nfn(i,this.b))},MWn.Tj=function(n,t,e,i){var r,c;n.Lg()&&n.Mg()?(r=null==(c=t.Ch(e))?this.b:GC(c)===GC(R$t)?null:c,null==i?null!=this.c?(t.Dh(e,null),i=this.b):null!=this.b?t.Dh(e,R$t):t.Dh(e,null):(this.Sk(i),t.Dh(e,i)),ban(n,this.d.Tk(n,1,this.e,r,i))):null==i?null!=this.c?t.Dh(e,null):null!=this.b?t.Dh(e,R$t):t.Dh(e,null):(this.Sk(i),t.Dh(e,i))},MWn.Vj=function(n,t,e){var i,r;n.Lg()&&n.Mg()?(i=null==(r=t.Ch(e))?this.b:GC(r)===GC(R$t)?null:r,t.Eh(e),ban(n,this.d.Tk(n,1,this.e,i,this.b))):t.Eh(e)},MWn.Sk=function(n){throw Hp(new bv)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData",563),wAn(W9n,1,{},$o),MWn.Tk=function(n,t,e,i,r){return new tU(n,t,e,i,r)},MWn.Uk=function(n,t,e,i,r,c){return new GQ(n,t,e,i,r,c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator",W9n),wAn(1332,W9n,{},Lo),MWn.Tk=function(n,t,e,i,r){return new n6(n,t,e,qy(TD(i)),qy(TD(r)))},MWn.Uk=function(n,t,e,i,r,c){return new L0(n,t,e,qy(TD(i)),qy(TD(r)),c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1",1332),wAn(1333,W9n,{},No),MWn.Tk=function(n,t,e,i,r){return new Hen(n,t,e,BB(i,217).a,BB(r,217).a)},MWn.Uk=function(n,t,e,i,r,c){return new S0(n,t,e,BB(i,217).a,BB(r,217).a,c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2",1333),wAn(1334,W9n,{},xo),MWn.Tk=function(n,t,e,i,r){return new qen(n,t,e,BB(i,172).a,BB(r,172).a)},MWn.Uk=function(n,t,e,i,r,c){return new P0(n,t,e,BB(i,172).a,BB(r,172).a,c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3",1334),wAn(1335,W9n,{},Do),MWn.Tk=function(n,t,e,i,r){return new J5(n,t,e,Gy(MD(i)),Gy(MD(r)))},MWn.Uk=function(n,t,e,i,r,c){return new I0(n,t,e,Gy(MD(i)),Gy(MD(r)),c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4",1335),wAn(1336,W9n,{},Ro),MWn.Tk=function(n,t,e,i,r){return new Uen(n,t,e,BB(i,155).a,BB(r,155).a)},MWn.Uk=function(n,t,e,i,r,c){return new C0(n,t,e,BB(i,155).a,BB(r,155).a,c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5",1336),wAn(1337,W9n,{},_o),MWn.Tk=function(n,t,e,i,r){return new Z5(n,t,e,BB(i,19).a,BB(r,19).a)},MWn.Uk=function(n,t,e,i,r,c){return new O0(n,t,e,BB(i,19).a,BB(r,19).a,c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6",1337),wAn(1338,W9n,{},Ko),MWn.Tk=function(n,t,e,i,r){return new Gen(n,t,e,BB(i,162).a,BB(r,162).a)},MWn.Uk=function(n,t,e,i,r,c){return new A0(n,t,e,BB(i,162).a,BB(r,162).a,c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7",1338),wAn(1339,W9n,{},Fo),MWn.Tk=function(n,t,e,i,r){return new zen(n,t,e,BB(i,184).a,BB(r,184).a)},MWn.Uk=function(n,t,e,i,r,c){return new $0(n,t,e,BB(i,184).a,BB(r,184).a,c)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8",1339),wAn(1317,563,{},wQ),MWn.Sk=function(n){if(!this.a.wj(n))throw Hp(new _y(U9n+tsn(n)+X9n+this.a+"'"))},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic",1317),wAn(1318,563,{},ZG),MWn.Sk=function(n){},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic",1318),wAn(770,563,{}),MWn.Sj=function(n,t,e){return null!=t.Ch(e)},MWn.Tj=function(n,t,e,i){var r,c;n.Lg()&&n.Mg()?(r=!0,null==(c=t.Ch(e))?(r=!1,c=this.b):GC(c)===GC(R$t)&&(c=null),null==i?null!=this.c?(t.Dh(e,null),i=this.b):t.Dh(e,R$t):(this.Sk(i),t.Dh(e,i)),ban(n,this.d.Uk(n,1,this.e,c,i,!r))):null==i?null!=this.c?t.Dh(e,null):t.Dh(e,R$t):(this.Sk(i),t.Dh(e,i))},MWn.Vj=function(n,t,e){var i,r;n.Lg()&&n.Mg()?(i=!0,null==(r=t.Ch(e))?(i=!1,r=this.b):GC(r)===GC(R$t)&&(r=null),t.Eh(e),ban(n,this.d.Uk(n,2,this.e,r,this.b,i))):t.Eh(e)},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable",770),wAn(1319,770,{},dQ),MWn.Sk=function(n){if(!this.a.wj(n))throw Hp(new _y(U9n+tsn(n)+X9n+this.a+"'"))},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic",1319),wAn(1320,770,{},nz),MWn.Sk=function(n){},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic",1320),wAn(398,504,{},cG),MWn.Pj=function(n,t,e,i,r){var c,a,u,o,s;if(s=t.Ch(e),this.Kj()&&GC(s)===GC(R$t))return null;if(this.sk()&&i&&null!=s){if((u=BB(s,49)).kh()&&u!=(o=tfn(n,u))){if(!SFn(this.a,o))throw Hp(new _y(U9n+tsn(o)+X9n+this.a+"'"));t.Dh(e,s=o),this.rk()&&(c=BB(o,49),a=u.ih(n,this.b?Awn(u.Tg(),this.b):-1-Awn(n.Tg(),this.e),null,null),!c.eh()&&(a=c.gh(n,this.b?Awn(c.Tg(),this.b):-1-Awn(n.Tg(),this.e),null,a)),a&&a.Fi()),n.Lg()&&n.Mg()&&ban(n,new tU(n,9,this.e,u,o))}return s}return s},MWn.Qj=function(n,t,e,i,r){var c,a;return GC(a=t.Ch(e))===GC(R$t)&&(a=null),t.Dh(e,i),this.bj()?GC(a)!==GC(i)&&null!=a&&(r=(c=BB(a,49)).ih(n,Awn(c.Tg(),this.b),null,r)):this.rk()&&null!=a&&(r=BB(a,49).ih(n,-1-Awn(n.Tg(),this.e),null,r)),n.Lg()&&n.Mg()&&(!r&&(r=new Fj(4)),r.Ei(new tU(n,1,this.e,a,i))),r},MWn.Rj=function(n,t,e,i,r){var c;return GC(c=t.Ch(e))===GC(R$t)&&(c=null),t.Eh(e),n.Lg()&&n.Mg()&&(!r&&(r=new Fj(4)),this.Kj()?r.Ei(new tU(n,2,this.e,c,null)):r.Ei(new tU(n,1,this.e,c,null))),r},MWn.Sj=function(n,t,e){return null!=t.Ch(e)},MWn.Tj=function(n,t,e,i){var r,c,a,u,o;if(null!=i&&!SFn(this.a,i))throw Hp(new _y(U9n+(cL(i,56)?dEn(BB(i,56).Tg()):utn(tsn(i)))+X9n+this.a+"'"));u=null!=(o=t.Ch(e)),this.Kj()&&GC(o)===GC(R$t)&&(o=null),a=null,this.bj()?GC(o)!==GC(i)&&(null!=o&&(a=(r=BB(o,49)).ih(n,Awn(r.Tg(),this.b),null,a)),null!=i&&(a=(r=BB(i,49)).gh(n,Awn(r.Tg(),this.b),null,a))):this.rk()&&GC(o)!==GC(i)&&(null!=o&&(a=BB(o,49).ih(n,-1-Awn(n.Tg(),this.e),null,a)),null!=i&&(a=BB(i,49).gh(n,-1-Awn(n.Tg(),this.e),null,a))),null==i&&this.Kj()?t.Dh(e,R$t):t.Dh(e,i),n.Lg()&&n.Mg()?(c=new GQ(n,1,this.e,o,i,this.Kj()&&!u),a?(a.Ei(c),a.Fi()):ban(n,c)):a&&a.Fi()},MWn.Vj=function(n,t,e){var i,r,c,a,u;a=null!=(u=t.Ch(e)),this.Kj()&&GC(u)===GC(R$t)&&(u=null),c=null,null!=u&&(this.bj()?c=(i=BB(u,49)).ih(n,Awn(i.Tg(),this.b),null,c):this.rk()&&(c=BB(u,49).ih(n,-1-Awn(n.Tg(),this.e),null,c))),t.Eh(e),n.Lg()&&n.Mg()?(r=new GQ(n,this.Kj()?2:1,this.e,u,null,a),c?(c.Ei(r),c.Fi()):ban(n,r)):c&&c.Fi()},MWn.bj=function(){return!1},MWn.rk=function(){return!1},MWn.sk=function(){return!1},MWn.Kj=function(){return!1},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObject",398),wAn(564,398,{},Zx),MWn.rk=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment",564),wAn(1323,564,{},nD),MWn.sk=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving",1323),wAn(772,564,{},tD),MWn.Kj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable",772),wAn(1325,772,{},eD),MWn.sk=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving",1325),wAn(640,564,{},CB),MWn.bj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse",640),wAn(1324,640,{},$B),MWn.sk=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving",1324),wAn(773,640,{},LB),MWn.Kj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable",773),wAn(1326,773,{},NB),MWn.sk=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving",1326),wAn(641,398,{},iD),MWn.sk=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving",641),wAn(1327,641,{},rD),MWn.Kj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable",1327),wAn(774,641,{},OB),MWn.bj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse",774),wAn(1328,774,{},xB),MWn.Kj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable",1328),wAn(1321,398,{},cD),MWn.Kj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable",1321),wAn(771,398,{},AB),MWn.bj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse",771),wAn(1322,771,{},DB),MWn.Kj=function(){return!0},vX(l6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable",1322),wAn(775,565,z9n,aW),MWn.Pk=function(n){return new aW(this.a,this.c,n)},MWn.dd=function(){return this.b},MWn.Qk=function(n,t,e){return D8(this,n,this.b,e)},MWn.Rk=function(n,t,e){return R8(this,n,this.b,e)},vX(l6n,"EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry",775),wAn(1329,1,k9n,Ep),MWn.Wj=function(n){return this.a},MWn.fj=function(){return cL(this.a,95)?BB(this.a,95).fj():!this.a.dc()},MWn.Wb=function(n){this.a.$b(),this.a.Gc(BB(n,15))},MWn.Xj=function(){cL(this.a,95)?BB(this.a,95).Xj():this.a.$b()},vX(l6n,"EStructuralFeatureImpl/SettingMany",1329),wAn(1330,565,z9n,g4),MWn.Ok=function(n){return new cR((Uqn(),FLt),this.b.Ih(this.a,n))},MWn.dd=function(){return null},MWn.Qk=function(n,t,e){return e},MWn.Rk=function(n,t,e){return e},vX(l6n,"EStructuralFeatureImpl/SimpleContentFeatureMapEntry",1330),wAn(642,565,z9n,cR),MWn.Ok=function(n){return new cR(this.c,n)},MWn.dd=function(){return this.a},MWn.Qk=function(n,t,e){return e},MWn.Rk=function(n,t,e){return e},vX(l6n,"EStructuralFeatureImpl/SimpleFeatureMapEntry",642),wAn(391,497,h8n,Bo),MWn.ri=function(n){return x8(qAt,HWn,26,n,0,1)},MWn.ni=function(){return!1},vX(l6n,"ESuperAdapter/1",391),wAn(444,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,836:1,49:1,97:1,150:1,444:1,114:1,115:1},Ho),MWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),this.Ab;case 1:return this.zb;case 2:return!this.a&&(this.a=new aG(this,VAt,this)),this.a}return U9(this,n-bX((gWn(),T$t)),itn(BB(yan(this,16),26)||T$t,n),t,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),Kpn(this.Ab,n,e);case 2:return!this.a&&(this.a=new aG(this,VAt,this)),Kpn(this.a,n,e)}return BB(itn(BB(yan(this,16),26)||(gWn(),T$t),t),66).Nj().Rj(this,fgn(this),t-bX((gWn(),T$t)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!!this.a&&0!=this.a.i}return O3(this,n-bX((gWn(),T$t)),itn(BB(yan(this,16),26)||T$t,n))},MWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),sqn(this.Ab),!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void pX(this.Ab,BB(t,14));case 1:return void Nrn(this,SD(t));case 2:return!this.a&&(this.a=new aG(this,VAt,this)),sqn(this.a),!this.a&&(this.a=new aG(this,VAt,this)),void pX(this.a,BB(t,14))}Lbn(this,n-bX((gWn(),T$t)),itn(BB(yan(this,16),26)||T$t,n),t)},MWn.zh=function(){return gWn(),T$t},MWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new eU(_At,this,0,3)),void sqn(this.Ab);case 1:return void Nrn(this,null);case 2:return!this.a&&(this.a=new aG(this,VAt,this)),void sqn(this.a)}qfn(this,n-bX((gWn(),T$t)),itn(BB(yan(this,16),26)||T$t,n))},vX(l6n,"ETypeParameterImpl",444),wAn(445,85,R9n,aG),MWn.cj=function(n,t){return LTn(this,BB(n,87),t)},MWn.dj=function(n,t){return NTn(this,BB(n,87),t)},vX(l6n,"ETypeParameterImpl/1",445),wAn(634,43,tYn,xm),MWn.ec=function(){return new Tp(this)},vX(l6n,"ETypeParameterImpl/2",634),wAn(556,nVn,tVn,Tp),MWn.Fc=function(n){return YR(this,BB(n,87))},MWn.Gc=function(n){var t,e,i;for(i=!1,e=n.Kc();e.Ob();)t=BB(e.Pb(),87),null==VW(this.a,t,"")&&(i=!0);return i},MWn.$b=function(){$U(this.a)},MWn.Hc=function(n){return hU(this.a,n)},MWn.Kc=function(){return new Mp(new usn(new Pb(this.a).a))},MWn.Mc=function(n){return K6(this,n)},MWn.gc=function(){return NT(this.a)},vX(l6n,"ETypeParameterImpl/2/1",556),wAn(557,1,QWn,Mp),MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return BB(ten(this.a).cd(),87)},MWn.Ob=function(){return this.a.b},MWn.Qb=function(){o9(this.a)},vX(l6n,"ETypeParameterImpl/2/1/1",557),wAn(1276,43,tYn,Dm),MWn._b=function(n){return XC(n)?eY(this,n):!!AY(this.f,n)},MWn.xc=function(n){var t;return cL(t=XC(n)?SJ(this,n):qC(AY(this.f,n)),837)?(t=BB(t,837)._j(),VW(this,BB(n,235),t),t):null!=t?t:null==n?(JM(),rLt):null},vX(l6n,"EValidatorRegistryImpl",1276),wAn(1313,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,1941:1,49:1,97:1,150:1,114:1,115:1},qo),MWn.Ih=function(n,t){switch(n.yj()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return null==t?null:Bbn(t);case 25:return Xtn(t);case 27:return X9(t);case 28:return W9(t);case 29:return null==t?null:H$(COt[0],BB(t,199));case 41:return null==t?"":nE(BB(t,290));case 42:return Bbn(t);case 50:return SD(t);default:throw Hp(new Ky(d6n+n.ne()+g6n))}},MWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Utn(n))?uvn(t.Mh(),n):-1),n.G){case 0:return new Om;case 1:return new jo;case 2:return new Kf;case 4:return new Ev;case 5:return new Am;case 6:return new jv;case 7:return new Rf;case 10:return new yo;case 11:return new $m;case 12:return new vY;case 13:return new Lm;case 14:return new pD;case 17:return new Ao;case 18:return new _p;case 19:return new Ho;default:throw Hp(new Ky(m6n+n.zb+g6n))}},MWn.Kh=function(n,t){switch(n.yj()){case 20:return null==t?null:new wE(t);case 21:return null==t?null:new $A(t);case 23:case 22:return null==t?null:Zdn(t);case 26:case 24:return null==t?null:Pnn(lKn(t,-128,127)<<24>>24);case 25:return d$n(t);case 27:return Syn(t);case 28:return Pyn(t);case 29:return gMn(t);case 32:case 31:return null==t?null:bSn(t);case 38:case 37:return null==t?null:new Dv(t);case 40:case 39:return null==t?null:iln(lKn(t,KVn,DWn));case 41:case 42:return null;case 44:case 43:return null==t?null:jgn(rUn(t));case 49:case 48:return null==t?null:rln(lKn(t,Q9n,32767)<<16>>16);case 50:return t;default:throw Hp(new Ky(d6n+n.ne()+g6n))}},vX(l6n,"EcoreFactoryImpl",1313),wAn(547,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,1939:1,49:1,97:1,150:1,179:1,547:1,114:1,115:1,675:1},UW),MWn.gb=!1,MWn.hb=!1;var V$t,Q$t=!1;vX(l6n,"EcorePackageImpl",547),wAn(1184,1,{837:1},Go),MWn._j=function(){return sN(),cLt},vX(l6n,"EcorePackageImpl/1",1184),wAn(1193,1,s7n,zo),MWn.wj=function(n){return cL(n,147)},MWn.xj=function(n){return x8(BOt,HWn,147,n,0,1)},vX(l6n,"EcorePackageImpl/10",1193),wAn(1194,1,s7n,Uo),MWn.wj=function(n){return cL(n,191)},MWn.xj=function(n){return x8(qOt,HWn,191,n,0,1)},vX(l6n,"EcorePackageImpl/11",1194),wAn(1195,1,s7n,Xo),MWn.wj=function(n){return cL(n,56)},MWn.xj=function(n){return x8(LOt,HWn,56,n,0,1)},vX(l6n,"EcorePackageImpl/12",1195),wAn(1196,1,s7n,Wo),MWn.wj=function(n){return cL(n,399)},MWn.xj=function(n){return x8(QAt,x9n,59,n,0,1)},vX(l6n,"EcorePackageImpl/13",1196),wAn(1197,1,s7n,Vo),MWn.wj=function(n){return cL(n,235)},MWn.xj=function(n){return x8(GOt,HWn,235,n,0,1)},vX(l6n,"EcorePackageImpl/14",1197),wAn(1198,1,s7n,Qo),MWn.wj=function(n){return cL(n,509)},MWn.xj=function(n){return x8(YAt,HWn,2017,n,0,1)},vX(l6n,"EcorePackageImpl/15",1198),wAn(1199,1,s7n,Yo),MWn.wj=function(n){return cL(n,99)},MWn.xj=function(n){return x8(JAt,N9n,18,n,0,1)},vX(l6n,"EcorePackageImpl/16",1199),wAn(1200,1,s7n,Jo),MWn.wj=function(n){return cL(n,170)},MWn.xj=function(n){return x8(FAt,N9n,170,n,0,1)},vX(l6n,"EcorePackageImpl/17",1200),wAn(1201,1,s7n,Zo),MWn.wj=function(n){return cL(n,472)},MWn.xj=function(n){return x8(KAt,HWn,472,n,0,1)},vX(l6n,"EcorePackageImpl/18",1201),wAn(1202,1,s7n,ns),MWn.wj=function(n){return cL(n,548)},MWn.xj=function(n){return x8(X$t,a9n,548,n,0,1)},vX(l6n,"EcorePackageImpl/19",1202),wAn(1185,1,s7n,ts),MWn.wj=function(n){return cL(n,322)},MWn.xj=function(n){return x8(BAt,N9n,34,n,0,1)},vX(l6n,"EcorePackageImpl/2",1185),wAn(1203,1,s7n,es),MWn.wj=function(n){return cL(n,241)},MWn.xj=function(n){return x8(VAt,B9n,87,n,0,1)},vX(l6n,"EcorePackageImpl/20",1203),wAn(1204,1,s7n,is),MWn.wj=function(n){return cL(n,444)},MWn.xj=function(n){return x8(O$t,HWn,836,n,0,1)},vX(l6n,"EcorePackageImpl/21",1204),wAn(1205,1,s7n,rs),MWn.wj=function(n){return zC(n)},MWn.xj=function(n){return x8(ktt,sVn,476,n,8,1)},vX(l6n,"EcorePackageImpl/22",1205),wAn(1206,1,s7n,cs),MWn.wj=function(n){return cL(n,190)},MWn.xj=function(n){return x8(NNt,sVn,190,n,0,2)},vX(l6n,"EcorePackageImpl/23",1206),wAn(1207,1,s7n,as),MWn.wj=function(n){return cL(n,217)},MWn.xj=function(n){return x8(Ttt,sVn,217,n,0,1)},vX(l6n,"EcorePackageImpl/24",1207),wAn(1208,1,s7n,us),MWn.wj=function(n){return cL(n,172)},MWn.xj=function(n){return x8(Stt,sVn,172,n,0,1)},vX(l6n,"EcorePackageImpl/25",1208),wAn(1209,1,s7n,os),MWn.wj=function(n){return cL(n,199)},MWn.xj=function(n){return x8(mtt,sVn,199,n,0,1)},vX(l6n,"EcorePackageImpl/26",1209),wAn(1210,1,s7n,ss),MWn.wj=function(n){return!1},MWn.xj=function(n){return x8(KNt,HWn,2110,n,0,1)},vX(l6n,"EcorePackageImpl/27",1210),wAn(1211,1,s7n,hs),MWn.wj=function(n){return UC(n)},MWn.xj=function(n){return x8(Ptt,sVn,333,n,7,1)},vX(l6n,"EcorePackageImpl/28",1211),wAn(1212,1,s7n,fs),MWn.wj=function(n){return cL(n,58)},MWn.xj=function(n){return x8(uAt,nZn,58,n,0,1)},vX(l6n,"EcorePackageImpl/29",1212),wAn(1186,1,s7n,ls),MWn.wj=function(n){return cL(n,510)},MWn.xj=function(n){return x8(_At,{3:1,4:1,5:1,1934:1},590,n,0,1)},vX(l6n,"EcorePackageImpl/3",1186),wAn(1213,1,s7n,bs),MWn.wj=function(n){return cL(n,573)},MWn.xj=function(n){return x8(yAt,HWn,1940,n,0,1)},vX(l6n,"EcorePackageImpl/30",1213),wAn(1214,1,s7n,ws),MWn.wj=function(n){return cL(n,153)},MWn.xj=function(n){return x8(oLt,nZn,153,n,0,1)},vX(l6n,"EcorePackageImpl/31",1214),wAn(1215,1,s7n,ds),MWn.wj=function(n){return cL(n,72)},MWn.xj=function(n){return x8($$t,h7n,72,n,0,1)},vX(l6n,"EcorePackageImpl/32",1215),wAn(1216,1,s7n,gs),MWn.wj=function(n){return cL(n,155)},MWn.xj=function(n){return x8(Itt,sVn,155,n,0,1)},vX(l6n,"EcorePackageImpl/33",1216),wAn(1217,1,s7n,ps),MWn.wj=function(n){return cL(n,19)},MWn.xj=function(n){return x8(Att,sVn,19,n,0,1)},vX(l6n,"EcorePackageImpl/34",1217),wAn(1218,1,s7n,vs),MWn.wj=function(n){return cL(n,290)},MWn.xj=function(n){return x8($nt,HWn,290,n,0,1)},vX(l6n,"EcorePackageImpl/35",1218),wAn(1219,1,s7n,ms),MWn.wj=function(n){return cL(n,162)},MWn.xj=function(n){return x8(Rtt,sVn,162,n,0,1)},vX(l6n,"EcorePackageImpl/36",1219),wAn(1220,1,s7n,ys),MWn.wj=function(n){return cL(n,83)},MWn.xj=function(n){return x8(Nnt,HWn,83,n,0,1)},vX(l6n,"EcorePackageImpl/37",1220),wAn(1221,1,s7n,ks),MWn.wj=function(n){return cL(n,591)},MWn.xj=function(n){return x8(iLt,HWn,591,n,0,1)},vX(l6n,"EcorePackageImpl/38",1221),wAn(1222,1,s7n,js),MWn.wj=function(n){return!1},MWn.xj=function(n){return x8(FNt,HWn,2111,n,0,1)},vX(l6n,"EcorePackageImpl/39",1222),wAn(1187,1,s7n,Es),MWn.wj=function(n){return cL(n,88)},MWn.xj=function(n){return x8(qAt,HWn,26,n,0,1)},vX(l6n,"EcorePackageImpl/4",1187),wAn(1223,1,s7n,Ts),MWn.wj=function(n){return cL(n,184)},MWn.xj=function(n){return x8(Ktt,sVn,184,n,0,1)},vX(l6n,"EcorePackageImpl/40",1223),wAn(1224,1,s7n,Ms),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(l6n,"EcorePackageImpl/41",1224),wAn(1225,1,s7n,Ss),MWn.wj=function(n){return cL(n,588)},MWn.xj=function(n){return x8(sAt,HWn,588,n,0,1)},vX(l6n,"EcorePackageImpl/42",1225),wAn(1226,1,s7n,Ps),MWn.wj=function(n){return!1},MWn.xj=function(n){return x8(BNt,sVn,2112,n,0,1)},vX(l6n,"EcorePackageImpl/43",1226),wAn(1227,1,s7n,Is),MWn.wj=function(n){return cL(n,42)},MWn.xj=function(n){return x8(Hnt,kVn,42,n,0,1)},vX(l6n,"EcorePackageImpl/44",1227),wAn(1188,1,s7n,Cs),MWn.wj=function(n){return cL(n,138)},MWn.xj=function(n){return x8(HAt,HWn,138,n,0,1)},vX(l6n,"EcorePackageImpl/5",1188),wAn(1189,1,s7n,Os),MWn.wj=function(n){return cL(n,148)},MWn.xj=function(n){return x8(GAt,HWn,148,n,0,1)},vX(l6n,"EcorePackageImpl/6",1189),wAn(1190,1,s7n,As),MWn.wj=function(n){return cL(n,457)},MWn.xj=function(n){return x8(XAt,HWn,671,n,0,1)},vX(l6n,"EcorePackageImpl/7",1190),wAn(1191,1,s7n,$s),MWn.wj=function(n){return cL(n,573)},MWn.xj=function(n){return x8(WAt,HWn,678,n,0,1)},vX(l6n,"EcorePackageImpl/8",1191),wAn(1192,1,s7n,Ls),MWn.wj=function(n){return cL(n,471)},MWn.xj=function(n){return x8(HOt,HWn,471,n,0,1)},vX(l6n,"EcorePackageImpl/9",1192),wAn(1025,1982,r9n,xy),MWn.bi=function(n,t){Afn(this,BB(t,415))},MWn.fi=function(n,t){eIn(this,n,BB(t,415))},vX(l6n,"MinimalEObjectImpl/1ArrayDelegatingAdapterList",1025),wAn(1026,143,t9n,uW),MWn.Ai=function(){return this.a.a},vX(l6n,"MinimalEObjectImpl/1ArrayDelegatingAdapterList/1",1026),wAn(1053,1052,{},o$),vX("org.eclipse.emf.ecore.plugin","EcorePlugin",1053);var Y$t,J$t,Z$t,nLt,tLt,eLt,iLt=bq(f7n,"Resource");wAn(781,1378,l7n),MWn.Yk=function(n){},MWn.Zk=function(n){},MWn.Vk=function(){return!this.a&&(this.a=new Sp(this)),this.a},MWn.Wk=function(n){var t,e,i,r,c;if((i=n.length)>0){if(b1(0,n.length),47==n.charCodeAt(0)){for(c=new J6(4),r=1,t=1;t<i;++t)b1(t,n.length),47==n.charCodeAt(t)&&(WB(c,r==t?"":n.substr(r,t-r)),r=t+1);return WB(c,n.substr(r)),ojn(this,c)}b1(i-1,n.length),63==n.charCodeAt(i-1)&&(e=M_(n,YTn(63),i-2))>0&&(n=n.substr(0,e))}return jCn(this,n)},MWn.Xk=function(){return this.c},MWn.Ib=function(){return nE(this.gm)+"@"+(nsn(this)>>>0).toString(16)+" uri='"+this.d+"'"},MWn.b=!1,vX(b7n,"ResourceImpl",781),wAn(1379,781,l7n,Ip),vX(b7n,"BinaryResourceImpl",1379),wAn(1169,694,f8n),MWn.si=function(n){return cL(n,56)?TY(this,BB(n,56)):cL(n,591)?new AL(BB(n,591).Vk()):GC(n)===GC(this.f)?BB(n,14).Kc():(dD(),pAt.a)},MWn.Ob=function(){return bOn(this)},MWn.a=!1,vX(y9n,"EcoreUtil/ContentTreeIterator",1169),wAn(1380,1169,f8n,rU),MWn.si=function(n){return GC(n)===GC(this.f)?BB(n,15).Kc():new F2(BB(n,56))},vX(b7n,"ResourceImpl/5",1380),wAn(648,1994,D9n,Sp),MWn.Hc=function(n){return this.i<=4?Sjn(this,n):cL(n,49)&&BB(n,49).Zg()==this.a},MWn.bi=function(n,t){n==this.i-1&&(this.a.b||(this.a.b=!0))},MWn.di=function(n,t){0==n?this.a.b||(this.a.b=!0):L8(this,n,t)},MWn.fi=function(n,t){},MWn.gi=function(n,t,e){},MWn.aj=function(){return 2},MWn.Ai=function(){return this.a},MWn.bj=function(){return!0},MWn.cj=function(n,t){return t=BB(n,49).wh(this.a,t)},MWn.dj=function(n,t){return BB(n,49).wh(null,t)},MWn.ej=function(){return!1},MWn.hi=function(){return!0},MWn.ri=function(n){return x8(LOt,HWn,56,n,0,1)},MWn.ni=function(){return!1},vX(b7n,"ResourceImpl/ContentsEList",648),wAn(957,1964,LVn,Pp),MWn.Zc=function(n){return this.a._h(n)},MWn.gc=function(){return this.a.gc()},vX(y9n,"AbstractSequentialInternalEList/1",957),wAn(624,1,{},SH),vX(y9n,"BasicExtendedMetaData",624),wAn(1160,1,{},$C),MWn.$k=function(){return null},MWn._k=function(){return-2==this.a&&ob(this,aMn(this.d,this.b)),this.a},MWn.al=function(){return null},MWn.bl=function(){return SQ(),SQ(),set},MWn.ne=function(){return this.c==I7n&&hb(this,Egn(this.d,this.b)),this.c},MWn.cl=function(){return 0},MWn.a=-2,MWn.c=I7n,vX(y9n,"BasicExtendedMetaData/EClassExtendedMetaDataImpl",1160),wAn(1161,1,{},K0),MWn.$k=function(){return this.a==(R5(),tLt)&&sb(this,vNn(this.f,this.b)),this.a},MWn._k=function(){return 0},MWn.al=function(){return this.c==(R5(),tLt)&&fb(this,mNn(this.f,this.b)),this.c},MWn.bl=function(){return!this.d&&lb(this,S_n(this.f,this.b)),this.d},MWn.ne=function(){return this.e==I7n&&bb(this,Egn(this.f,this.b)),this.e},MWn.cl=function(){return-2==this.g&&wb(this,YEn(this.f,this.b)),this.g},MWn.e=I7n,MWn.g=-2,vX(y9n,"BasicExtendedMetaData/EDataTypeExtendedMetaDataImpl",1161),wAn(1159,1,{},RC),MWn.b=!1,MWn.c=!1,vX(y9n,"BasicExtendedMetaData/EPackageExtendedMetaDataImpl",1159),wAn(1162,1,{},_0),MWn.c=-2,MWn.e=I7n,MWn.f=I7n,vX(y9n,"BasicExtendedMetaData/EStructuralFeatureExtendedMetaDataImpl",1162),wAn(585,622,R9n,MH),MWn.aj=function(){return this.c},MWn.Fk=function(){return!1},MWn.li=function(n,t){return t},MWn.c=0,vX(y9n,"EDataTypeEList",585);var rLt,cLt,aLt,uLt,oLt=bq(y9n,"FeatureMap");wAn(75,585,{3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,153:1,215:1,1937:1,69:1,95:1},Ecn),MWn.Vc=function(n,t){lNn(this,n,BB(t,72))},MWn.Fc=function(n){return uLn(this,BB(n,72))},MWn.Yh=function(n){dX(this,BB(n,72))},MWn.cj=function(n,t){return H_(this,BB(n,72),t)},MWn.dj=function(n,t){return q_(this,BB(n,72),t)},MWn.ii=function(n,t){return aKn(this,n,t)},MWn.li=function(n,t){return hGn(this,n,BB(t,72))},MWn._c=function(n,t){return Pxn(this,n,BB(t,72))},MWn.jj=function(n,t){return G_(this,BB(n,72),t)},MWn.kj=function(n,t){return z_(this,BB(n,72),t)},MWn.lj=function(n,t,e){return gEn(this,BB(n,72),BB(t,72),e)},MWn.oi=function(n,t){return sTn(this,n,BB(t,72))},MWn.dl=function(n,t){return x_n(this,n,t)},MWn.Wc=function(n,t){var e,i,r,c,a,u,o,s,h;for(s=new gtn(t.gc()),r=t.Kc();r.Ob();)if(c=(i=BB(r.Pb(),72)).ak(),$xn(this.e,c))(!c.hi()||!G3(this,c,i.dd())&&!Sjn(s,i))&&f9(s,i);else{for(h=axn(this.e.Tg(),c),e=BB(this.g,119),a=!0,u=0;u<this.i;++u)if(o=e[u],h.rl(o.ak())){BB(ovn(this,u,i),72),a=!1;break}a&&f9(s,i)}return oon(this,n,s)},MWn.Gc=function(n){var t,e,i,r,c,a,u,o,s;for(o=new gtn(n.gc()),i=n.Kc();i.Ob();)if(r=(e=BB(i.Pb(),72)).ak(),$xn(this.e,r))(!r.hi()||!G3(this,r,e.dd())&&!Sjn(o,e))&&f9(o,e);else{for(s=axn(this.e.Tg(),r),t=BB(this.g,119),c=!0,a=0;a<this.i;++a)if(u=t[a],s.rl(u.ak())){BB(ovn(this,a,e),72),c=!1;break}c&&f9(o,e)}return pX(this,o)},MWn.Wh=function(n){return this.j=-1,LFn(this,this.i,n)},MWn.el=function(n,t,e){return PRn(this,n,t,e)},MWn.mk=function(n,t){return T_n(this,n,t)},MWn.fl=function(n,t,e){return ZBn(this,n,t,e)},MWn.gl=function(){return this},MWn.hl=function(n,t){return rHn(this,n,t)},MWn.il=function(n){return BB(Wtn(this,n),72).ak()},MWn.jl=function(n){return BB(Wtn(this,n),72).dd()},MWn.kl=function(){return this.b},MWn.bj=function(){return!0},MWn.ij=function(){return!0},MWn.ll=function(n){return!adn(this,n)},MWn.ri=function(n){return x8(W$t,h7n,332,n,0,1)},MWn.Gk=function(n){return hD(this,n)},MWn.Wb=function(n){tX(this,n)},MWn.ml=function(n,t){MHn(this,n,t)},MWn.nl=function(n){return zin(this,n)},MWn.ol=function(n){_mn(this,n)},vX(y9n,"BasicFeatureMap",75),wAn(1851,1,cVn),MWn.Nb=function(n){fU(this,n)},MWn.Rb=function(n){if(-1==this.g)throw Hp(new dv);mz(this);try{Axn(this.e,this.b,this.a,n),this.d=this.e.j,cvn(this)}catch(t){throw cL(t=lun(t),73)?Hp(new vv):Hp(t)}},MWn.Ob=function(){return _sn(this)},MWn.Sb=function(){return Ksn(this)},MWn.Pb=function(){return cvn(this)},MWn.Tb=function(){return this.a},MWn.Ub=function(){var n;if(Ksn(this))return mz(this),this.g=--this.a,this.Lk()&&(n=FCn(this.e,this.b,this.c,this.a,this.j),this.j=n),this.i=0,this.j;throw Hp(new yv)},MWn.Vb=function(){return this.a-1},MWn.Qb=function(){if(-1==this.g)throw Hp(new dv);mz(this);try{aPn(this.e,this.b,this.g),this.d=this.e.j,this.g<this.a&&(--this.a,--this.c),--this.g}catch(n){throw cL(n=lun(n),73)?Hp(new vv):Hp(n)}},MWn.Lk=function(){return!1},MWn.Wb=function(n){if(-1==this.g)throw Hp(new dv);mz(this);try{XFn(this.e,this.b,this.g,n),this.d=this.e.j}catch(t){throw cL(t=lun(t),73)?Hp(new vv):Hp(t)}},MWn.a=0,MWn.c=0,MWn.d=0,MWn.f=!1,MWn.g=0,MWn.i=0,vX(y9n,"FeatureMapUtil/BasicFeatureEIterator",1851),wAn(410,1851,cVn,Aan),MWn.pl=function(){var n,t,e;for(e=this.e.i,n=BB(this.e.g,119);this.c<e;){if(t=n[this.c],this.k.rl(t.ak()))return this.j=this.f?t:t.dd(),this.i=2,!0;++this.c}return this.i=1,this.g=-1,!1},MWn.ql=function(){var n,t;for(n=BB(this.e.g,119);--this.c>=0;)if(t=n[this.c],this.k.rl(t.ak()))return this.j=this.f?t:t.dd(),this.i=-2,!0;return this.i=-1,this.g=-1,!1},vX(y9n,"BasicFeatureMap/FeatureEIterator",410),wAn(662,410,cVn,xO),MWn.Lk=function(){return!0},vX(y9n,"BasicFeatureMap/ResolvingFeatureEIterator",662),wAn(955,486,q9n,z$),MWn.Gi=function(){return this},vX(y9n,"EContentsEList/1",955),wAn(956,486,q9n,DO),MWn.Lk=function(){return!1},vX(y9n,"EContentsEList/2",956),wAn(954,279,G9n,U$),MWn.Nk=function(n){},MWn.Ob=function(){return!1},MWn.Sb=function(){return!1},vX(y9n,"EContentsEList/FeatureIteratorImpl/1",954),wAn(825,585,R9n,_L),MWn.ci=function(){this.a=!0},MWn.fj=function(){return this.a},MWn.Xj=function(){var n;sqn(this),mA(this.e)?(n=this.a,this.a=!1,ban(this.e,new t6(this.e,2,this.c,n,!1))):this.a=!1},MWn.a=!1,vX(y9n,"EDataTypeEList/Unsettable",825),wAn(1849,585,R9n,KL),MWn.hi=function(){return!0},vX(y9n,"EDataTypeUniqueEList",1849),wAn(1850,825,R9n,FL),MWn.hi=function(){return!0},vX(y9n,"EDataTypeUniqueEList/Unsettable",1850),wAn(139,85,R9n,NL),MWn.Ek=function(){return!0},MWn.li=function(n,t){return GOn(this,n,BB(t,56))},vX(y9n,"EObjectContainmentEList/Resolving",139),wAn(1163,545,R9n,xL),MWn.Ek=function(){return!0},MWn.li=function(n,t){return GOn(this,n,BB(t,56))},vX(y9n,"EObjectContainmentEList/Unsettable/Resolving",1163),wAn(748,16,R9n,i_),MWn.ci=function(){this.a=!0},MWn.fj=function(){return this.a},MWn.Xj=function(){var n;sqn(this),mA(this.e)?(n=this.a,this.a=!1,ban(this.e,new t6(this.e,2,this.c,n,!1))):this.a=!1},MWn.a=!1,vX(y9n,"EObjectContainmentWithInverseEList/Unsettable",748),wAn(1173,748,R9n,r_),MWn.Ek=function(){return!0},MWn.li=function(n,t){return GOn(this,n,BB(t,56))},vX(y9n,"EObjectContainmentWithInverseEList/Unsettable/Resolving",1173),wAn(743,496,R9n,DL),MWn.ci=function(){this.a=!0},MWn.fj=function(){return this.a},MWn.Xj=function(){var n;sqn(this),mA(this.e)?(n=this.a,this.a=!1,ban(this.e,new t6(this.e,2,this.c,n,!1))):this.a=!1},MWn.a=!1,vX(y9n,"EObjectEList/Unsettable",743),wAn(328,496,R9n,RL),MWn.Ek=function(){return!0},MWn.li=function(n,t){return GOn(this,n,BB(t,56))},vX(y9n,"EObjectResolvingEList",328),wAn(1641,743,R9n,BL),MWn.Ek=function(){return!0},MWn.li=function(n,t){return GOn(this,n,BB(t,56))},vX(y9n,"EObjectResolvingEList/Unsettable",1641),wAn(1381,1,{},Ns),vX(y9n,"EObjectValidator",1381),wAn(546,496,R9n,iU),MWn.zk=function(){return this.d},MWn.Ak=function(){return this.b},MWn.bj=function(){return!0},MWn.Dk=function(){return!0},MWn.b=0,vX(y9n,"EObjectWithInverseEList",546),wAn(1176,546,R9n,c_),MWn.Ck=function(){return!0},vX(y9n,"EObjectWithInverseEList/ManyInverse",1176),wAn(625,546,R9n,a_),MWn.ci=function(){this.a=!0},MWn.fj=function(){return this.a},MWn.Xj=function(){var n;sqn(this),mA(this.e)?(n=this.a,this.a=!1,ban(this.e,new t6(this.e,2,this.c,n,!1))):this.a=!1},MWn.a=!1,vX(y9n,"EObjectWithInverseEList/Unsettable",625),wAn(1175,625,R9n,o_),MWn.Ck=function(){return!0},vX(y9n,"EObjectWithInverseEList/Unsettable/ManyInverse",1175),wAn(749,546,R9n,u_),MWn.Ek=function(){return!0},MWn.li=function(n,t){return GOn(this,n,BB(t,56))},vX(y9n,"EObjectWithInverseResolvingEList",749),wAn(31,749,R9n,h_),MWn.Ck=function(){return!0},vX(y9n,"EObjectWithInverseResolvingEList/ManyInverse",31),wAn(750,625,R9n,s_),MWn.Ek=function(){return!0},MWn.li=function(n,t){return GOn(this,n,BB(t,56))},vX(y9n,"EObjectWithInverseResolvingEList/Unsettable",750),wAn(1174,750,R9n,f_),MWn.Ck=function(){return!0},vX(y9n,"EObjectWithInverseResolvingEList/Unsettable/ManyInverse",1174),wAn(1164,622,R9n),MWn.ai=function(){return 0==(1792&this.b)},MWn.ci=function(){this.b|=1},MWn.Bk=function(){return 0!=(4&this.b)},MWn.bj=function(){return 0!=(40&this.b)},MWn.Ck=function(){return 0!=(16&this.b)},MWn.Dk=function(){return 0!=(8&this.b)},MWn.Ek=function(){return 0!=(this.b&M9n)},MWn.rk=function(){return 0!=(32&this.b)},MWn.Fk=function(){return 0!=(this.b&k6n)},MWn.wj=function(n){return this.d?x3(this.d,n):this.ak().Yj().wj(n)},MWn.fj=function(){return 0!=(2&this.b)?0!=(1&this.b):0!=this.i},MWn.hi=function(){return 0!=(128&this.b)},MWn.Xj=function(){var n;sqn(this),0!=(2&this.b)&&(mA(this.e)?(n=0!=(1&this.b),this.b&=-2,Lv(this,new t6(this.e,2,Awn(this.e.Tg(),this.ak()),n,!1))):this.b&=-2)},MWn.ni=function(){return 0==(1536&this.b)},MWn.b=0,vX(y9n,"EcoreEList/Generic",1164),wAn(1165,1164,R9n,zQ),MWn.ak=function(){return this.a},vX(y9n,"EcoreEList/Dynamic",1165),wAn(747,63,h8n,Cp),MWn.ri=function(n){return Den(this.a.a,n)},vX(y9n,"EcoreEMap/1",747),wAn(746,85,R9n,Zz),MWn.bi=function(n,t){Cvn(this.b,BB(t,133))},MWn.di=function(n,t){aan(this.b)},MWn.ei=function(n,t,e){var i;++(i=this.b,BB(t,133),i).e},MWn.fi=function(n,t){Oln(this.b,BB(t,133))},MWn.gi=function(n,t,e){Oln(this.b,BB(e,133)),GC(e)===GC(t)&&BB(e,133).Th(c$(BB(t,133).cd())),Cvn(this.b,BB(t,133))},vX(y9n,"EcoreEMap/DelegateEObjectContainmentEList",746),wAn(1171,151,j9n,yin),vX(y9n,"EcoreEMap/Unsettable",1171),wAn(1172,746,R9n,l_),MWn.ci=function(){this.a=!0},MWn.fj=function(){return this.a},MWn.Xj=function(){var n;sqn(this),mA(this.e)?(n=this.a,this.a=!1,ban(this.e,new t6(this.e,2,this.c,n,!1))):this.a=!1},MWn.a=!1,vX(y9n,"EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList",1172),wAn(1168,228,tYn,lX),MWn.a=!1,MWn.b=!1,vX(y9n,"EcoreUtil/Copier",1168),wAn(745,1,QWn,F2),MWn.Nb=function(n){fU(this,n)},MWn.Ob=function(){return udn(this)},MWn.Pb=function(){var n;return udn(this),n=this.b,this.b=null,n},MWn.Qb=function(){this.a.Qb()},vX(y9n,"EcoreUtil/ProperContentIterator",745),wAn(1382,1381,{},Ff),vX(y9n,"EcoreValidator",1382),bq(y9n,"FeatureMapUtil/Validator"),wAn(1260,1,{1942:1},xs),MWn.rl=function(n){return!0},vX(y9n,"FeatureMapUtil/1",1260),wAn(757,1,{1942:1},cUn),MWn.rl=function(n){var t;return this.c==n||(null==(t=TD(RX(this.a,n)))?xRn(this,n)?(r6(this.a,n,(hN(),vtt)),!0):(r6(this.a,n,(hN(),ptt)),!1):t==(hN(),vtt))},MWn.e=!1,vX(y9n,"FeatureMapUtil/BasicValidator",757),wAn(758,43,tYn,X$),vX(y9n,"FeatureMapUtil/BasicValidator/Cache",758),wAn(501,52,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,69:1,95:1},xC),MWn.Vc=function(n,t){Axn(this.c,this.b,n,t)},MWn.Fc=function(n){return x_n(this.c,this.b,n)},MWn.Wc=function(n,t){return jHn(this.c,this.b,n,t)},MWn.Gc=function(n){return Z$(this,n)},MWn.Xh=function(n,t){htn(this.c,this.b,n,t)},MWn.lk=function(n,t){return PRn(this.c,this.b,n,t)},MWn.pi=function(n){return iHn(this.c,this.b,n,!1)},MWn.Zh=function(){return jA(this.c,this.b)},MWn.$h=function(){return EA(this.c,this.b)},MWn._h=function(n){return $8(this.c,this.b,n)},MWn.mk=function(n,t){return tR(this,n,t)},MWn.$b=function(){Nv(this)},MWn.Hc=function(n){return G3(this.c,this.b,n)},MWn.Ic=function(n){return Mcn(this.c,this.b,n)},MWn.Xb=function(n){return iHn(this.c,this.b,n,!0)},MWn.Wj=function(n){return this},MWn.Xc=function(n){return z3(this.c,this.b,n)},MWn.dc=function(){return HC(this)},MWn.fj=function(){return!adn(this.c,this.b)},MWn.Kc=function(){return cnn(this.c,this.b)},MWn.Yc=function(){return ann(this.c,this.b)},MWn.Zc=function(n){return lln(this.c,this.b,n)},MWn.ii=function(n,t){return mFn(this.c,this.b,n,t)},MWn.ji=function(n,t){Q6(this.c,this.b,n,t)},MWn.$c=function(n){return aPn(this.c,this.b,n)},MWn.Mc=function(n){return I_n(this.c,this.b,n)},MWn._c=function(n,t){return XFn(this.c,this.b,n,t)},MWn.Wb=function(n){AOn(this.c,this.b),Z$(this,BB(n,15))},MWn.gc=function(){return _ln(this.c,this.b)},MWn.Pc=function(){return G1(this.c,this.b)},MWn.Qc=function(n){return U3(this.c,this.b,n)},MWn.Ib=function(){var n,t;for((t=new Sk).a+="[",n=jA(this.c,this.b);_sn(n);)cO(t,kN(cvn(n))),_sn(n)&&(t.a+=FWn);return t.a+="]",t.a},MWn.Xj=function(){AOn(this.c,this.b)},vX(y9n,"FeatureMapUtil/FeatureEList",501),wAn(627,36,t9n,b4),MWn.yi=function(n){return eln(this,n)},MWn.Di=function(n){var t,e,i,r;switch(this.d){case 1:case 2:if(GC(n.Ai())===GC(this.c)&&eln(this,null)==n.yi(null))return this.g=n.zi(),1==n.xi()&&(this.d=1),!0;break;case 3:if(3===n.xi()&&GC(n.Ai())===GC(this.c)&&eln(this,null)==n.yi(null))return this.d=5,f9(t=new gtn(2),this.g),f9(t,n.zi()),this.g=t,!0;break;case 5:if(3===n.xi()&&GC(n.Ai())===GC(this.c)&&eln(this,null)==n.yi(null))return BB(this.g,14).Fc(n.zi()),!0;break;case 4:switch(n.xi()){case 3:if(GC(n.Ai())===GC(this.c)&&eln(this,null)==n.yi(null))return this.d=1,this.g=n.zi(),!0;break;case 4:if(GC(n.Ai())===GC(this.c)&&eln(this,null)==n.yi(null))return this.d=6,f9(r=new gtn(2),this.n),f9(r,n.Bi()),this.n=r,i=Pun(Gk(ANt,1),hQn,25,15,[this.o,n.Ci()]),this.g=i,!0}break;case 6:if(4===n.xi()&&GC(n.Ai())===GC(this.c)&&eln(this,null)==n.yi(null))return BB(this.n,14).Fc(n.Bi()),aHn(i=BB(this.g,48),0,e=x8(ANt,hQn,25,i.length+1,15,1),0,i.length),e[i.length]=n.Ci(),this.g=e,!0}return!1},vX(y9n,"FeatureMapUtil/FeatureENotificationImpl",627),wAn(552,501,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,153:1,215:1,1937:1,69:1,95:1},lq),MWn.dl=function(n,t){return x_n(this.c,n,t)},MWn.el=function(n,t,e){return PRn(this.c,n,t,e)},MWn.fl=function(n,t,e){return ZBn(this.c,n,t,e)},MWn.gl=function(){return this},MWn.hl=function(n,t){return rHn(this.c,n,t)},MWn.il=function(n){return BB(iHn(this.c,this.b,n,!1),72).ak()},MWn.jl=function(n){return BB(iHn(this.c,this.b,n,!1),72).dd()},MWn.kl=function(){return this.a},MWn.ll=function(n){return!adn(this.c,n)},MWn.ml=function(n,t){MHn(this.c,n,t)},MWn.nl=function(n){return zin(this.c,n)},MWn.ol=function(n){_mn(this.c,n)},vX(y9n,"FeatureMapUtil/FeatureFeatureMap",552),wAn(1259,1,k9n,_C),MWn.Wj=function(n){return iHn(this.b,this.a,-1,n)},MWn.fj=function(){return!adn(this.b,this.a)},MWn.Wb=function(n){MHn(this.b,this.a,n)},MWn.Xj=function(){AOn(this.b,this.a)},vX(y9n,"FeatureMapUtil/FeatureValue",1259);var sLt,hLt,fLt,lLt,bLt,wLt=bq(O7n,"AnyType");wAn(666,60,BVn,ik),vX(O7n,"InvalidDatatypeValueException",666);var dLt,gLt,pLt,vLt,mLt,yLt,kLt,jLt,ELt,TLt,MLt,SLt,PLt,ILt,CLt,OLt,ALt,$Lt,LLt,NLt,xLt,DLt,RLt,_Lt,KLt,FLt,BLt,HLt,qLt,GLt,zLt=bq(O7n,A7n),ULt=bq(O7n,$7n),XLt=bq(O7n,L7n);wAn(830,506,{105:1,92:1,90:1,56:1,49:1,97:1,843:1},Rm),MWn._g=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new Ecn(this,0)),this.c):(!this.c&&(this.c=new Ecn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new Ecn(this,0)),BB(n1(this.c,(Uqn(),vLt)),153)):(!this.c&&(this.c=new Ecn(this,0)),BB(BB(n1(this.c,(Uqn(),vLt)),153),215)).kl();case 2:return e?(!this.b&&(this.b=new Ecn(this,2)),this.b):(!this.b&&(this.b=new Ecn(this,2)),this.b.b)}return U9(this,n-bX(this.zh()),itn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new _f),this.k).ck(),n),t,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.c&&(this.c=new Ecn(this,0)),T_n(this.c,n,e);case 1:return(!this.c&&(this.c=new Ecn(this,0)),BB(BB(n1(this.c,(Uqn(),vLt)),153),69)).mk(n,e);case 2:return!this.b&&(this.b=new Ecn(this,2)),T_n(this.b,n,e)}return BB(itn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new _f),this.k).ck(),t),66).Nj().Rj(this,Q7(this),t-bX(this.zh()),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new Ecn(this,0)),BB(n1(this.c,(Uqn(),vLt)),153)).dc();case 2:return!!this.b&&0!=this.b.i}return O3(this,n-bX(this.zh()),itn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new _f),this.k).ck(),n))},MWn.sh=function(n,t){switch(n){case 0:return!this.c&&(this.c=new Ecn(this,0)),void tX(this.c,t);case 1:return void(!this.c&&(this.c=new Ecn(this,0)),BB(BB(n1(this.c,(Uqn(),vLt)),153),215)).Wb(t);case 2:return!this.b&&(this.b=new Ecn(this,2)),void tX(this.b,t)}Lbn(this,n-bX(this.zh()),itn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new _f),this.k).ck(),n),t)},MWn.zh=function(){return Uqn(),pLt},MWn.Bh=function(n){switch(n){case 0:return!this.c&&(this.c=new Ecn(this,0)),void sqn(this.c);case 1:return void(!this.c&&(this.c=new Ecn(this,0)),BB(n1(this.c,(Uqn(),vLt)),153)).$b();case 2:return!this.b&&(this.b=new Ecn(this,2)),void sqn(this.b)}qfn(this,n-bX(this.zh()),itn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new _f),this.k).ck(),n))},MWn.Ib=function(){var n;return 0!=(4&this.j)?P$n(this):((n=new fN(P$n(this))).a+=" (mixed: ",rO(n,this.c),n.a+=", anyAttribute: ",rO(n,this.b),n.a+=")",n.a)},vX(N7n,"AnyTypeImpl",830),wAn(667,506,{105:1,92:1,90:1,56:1,49:1,97:1,2021:1,667:1},Rs),MWn._g=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return U9(this,n-bX((Uqn(),OLt)),itn(0==(2&this.j)?OLt:(!this.k&&(this.k=new _f),this.k).ck(),n),t,e)},MWn.lh=function(n){switch(n){case 0:return null!=this.a;case 1:return null!=this.b}return O3(this,n-bX((Uqn(),OLt)),itn(0==(2&this.j)?OLt:(!this.k&&(this.k=new _f),this.k).ck(),n))},MWn.sh=function(n,t){switch(n){case 0:return void kb(this,SD(t));case 1:return void jb(this,SD(t))}Lbn(this,n-bX((Uqn(),OLt)),itn(0==(2&this.j)?OLt:(!this.k&&(this.k=new _f),this.k).ck(),n),t)},MWn.zh=function(){return Uqn(),OLt},MWn.Bh=function(n){switch(n){case 0:return void(this.a=null);case 1:return void(this.b=null)}qfn(this,n-bX((Uqn(),OLt)),itn(0==(2&this.j)?OLt:(!this.k&&(this.k=new _f),this.k).ck(),n))},MWn.Ib=function(){var n;return 0!=(4&this.j)?P$n(this):((n=new fN(P$n(this))).a+=" (data: ",cO(n,this.a),n.a+=", target: ",cO(n,this.b),n.a+=")",n.a)},MWn.a=null,MWn.b=null,vX(N7n,"ProcessingInstructionImpl",667),wAn(668,830,{105:1,92:1,90:1,56:1,49:1,97:1,843:1,2022:1,668:1},Km),MWn._g=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new Ecn(this,0)),this.c):(!this.c&&(this.c=new Ecn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new Ecn(this,0)),BB(n1(this.c,(Uqn(),vLt)),153)):(!this.c&&(this.c=new Ecn(this,0)),BB(BB(n1(this.c,(Uqn(),vLt)),153),215)).kl();case 2:return e?(!this.b&&(this.b=new Ecn(this,2)),this.b):(!this.b&&(this.b=new Ecn(this,2)),this.b.b);case 3:return!this.c&&(this.c=new Ecn(this,0)),SD(rHn(this.c,(Uqn(),LLt),!0));case 4:return g_(this.a,(!this.c&&(this.c=new Ecn(this,0)),SD(rHn(this.c,(Uqn(),LLt),!0))));case 5:return this.a}return U9(this,n-bX((Uqn(),$Lt)),itn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new _f),this.k).ck(),n),t,e)},MWn.lh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new Ecn(this,0)),BB(n1(this.c,(Uqn(),vLt)),153)).dc();case 2:return!!this.b&&0!=this.b.i;case 3:return!this.c&&(this.c=new Ecn(this,0)),null!=SD(rHn(this.c,(Uqn(),LLt),!0));case 4:return null!=g_(this.a,(!this.c&&(this.c=new Ecn(this,0)),SD(rHn(this.c,(Uqn(),LLt),!0))));case 5:return!!this.a}return O3(this,n-bX((Uqn(),$Lt)),itn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new _f),this.k).ck(),n))},MWn.sh=function(n,t){switch(n){case 0:return!this.c&&(this.c=new Ecn(this,0)),void tX(this.c,t);case 1:return void(!this.c&&(this.c=new Ecn(this,0)),BB(BB(n1(this.c,(Uqn(),vLt)),153),215)).Wb(t);case 2:return!this.b&&(this.b=new Ecn(this,2)),void tX(this.b,t);case 3:return void F0(this,SD(t));case 4:return void F0(this,p_(this.a,t));case 5:return void Eb(this,BB(t,148))}Lbn(this,n-bX((Uqn(),$Lt)),itn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new _f),this.k).ck(),n),t)},MWn.zh=function(){return Uqn(),$Lt},MWn.Bh=function(n){switch(n){case 0:return!this.c&&(this.c=new Ecn(this,0)),void sqn(this.c);case 1:return void(!this.c&&(this.c=new Ecn(this,0)),BB(n1(this.c,(Uqn(),vLt)),153)).$b();case 2:return!this.b&&(this.b=new Ecn(this,2)),void sqn(this.b);case 3:return!this.c&&(this.c=new Ecn(this,0)),void MHn(this.c,(Uqn(),LLt),null);case 4:return void F0(this,p_(this.a,null));case 5:return void(this.a=null)}qfn(this,n-bX((Uqn(),$Lt)),itn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new _f),this.k).ck(),n))},vX(N7n,"SimpleAnyTypeImpl",668),wAn(669,506,{105:1,92:1,90:1,56:1,49:1,97:1,2023:1,669:1},_m),MWn._g=function(n,t,e){switch(n){case 0:return e?(!this.a&&(this.a=new Ecn(this,0)),this.a):(!this.a&&(this.a=new Ecn(this,0)),this.a.b);case 1:return e?(!this.b&&(this.b=new y9((gWn(),k$t),X$t,this,1)),this.b):(!this.b&&(this.b=new y9((gWn(),k$t),X$t,this,1)),A8(this.b));case 2:return e?(!this.c&&(this.c=new y9((gWn(),k$t),X$t,this,2)),this.c):(!this.c&&(this.c=new y9((gWn(),k$t),X$t,this,2)),A8(this.c));case 3:return!this.a&&(this.a=new Ecn(this,0)),n1(this.a,(Uqn(),DLt));case 4:return!this.a&&(this.a=new Ecn(this,0)),n1(this.a,(Uqn(),RLt));case 5:return!this.a&&(this.a=new Ecn(this,0)),n1(this.a,(Uqn(),KLt));case 6:return!this.a&&(this.a=new Ecn(this,0)),n1(this.a,(Uqn(),FLt))}return U9(this,n-bX((Uqn(),xLt)),itn(0==(2&this.j)?xLt:(!this.k&&(this.k=new _f),this.k).ck(),n),t,e)},MWn.jh=function(n,t,e){switch(t){case 0:return!this.a&&(this.a=new Ecn(this,0)),T_n(this.a,n,e);case 1:return!this.b&&(this.b=new y9((gWn(),k$t),X$t,this,1)),B_(this.b,n,e);case 2:return!this.c&&(this.c=new y9((gWn(),k$t),X$t,this,2)),B_(this.c,n,e);case 5:return!this.a&&(this.a=new Ecn(this,0)),tR(n1(this.a,(Uqn(),KLt)),n,e)}return BB(itn(0==(2&this.j)?(Uqn(),xLt):(!this.k&&(this.k=new _f),this.k).ck(),t),66).Nj().Rj(this,Q7(this),t-bX((Uqn(),xLt)),n,e)},MWn.lh=function(n){switch(n){case 0:return!!this.a&&0!=this.a.i;case 1:return!!this.b&&0!=this.b.f;case 2:return!!this.c&&0!=this.c.f;case 3:return!this.a&&(this.a=new Ecn(this,0)),!HC(n1(this.a,(Uqn(),DLt)));case 4:return!this.a&&(this.a=new Ecn(this,0)),!HC(n1(this.a,(Uqn(),RLt)));case 5:return!this.a&&(this.a=new Ecn(this,0)),!HC(n1(this.a,(Uqn(),KLt)));case 6:return!this.a&&(this.a=new Ecn(this,0)),!HC(n1(this.a,(Uqn(),FLt)))}return O3(this,n-bX((Uqn(),xLt)),itn(0==(2&this.j)?xLt:(!this.k&&(this.k=new _f),this.k).ck(),n))},MWn.sh=function(n,t){switch(n){case 0:return!this.a&&(this.a=new Ecn(this,0)),void tX(this.a,t);case 1:return!this.b&&(this.b=new y9((gWn(),k$t),X$t,this,1)),void tan(this.b,t);case 2:return!this.c&&(this.c=new y9((gWn(),k$t),X$t,this,2)),void tan(this.c,t);case 3:return!this.a&&(this.a=new Ecn(this,0)),Nv(n1(this.a,(Uqn(),DLt))),!this.a&&(this.a=new Ecn(this,0)),void Z$(n1(this.a,DLt),BB(t,14));case 4:return!this.a&&(this.a=new Ecn(this,0)),Nv(n1(this.a,(Uqn(),RLt))),!this.a&&(this.a=new Ecn(this,0)),void Z$(n1(this.a,RLt),BB(t,14));case 5:return!this.a&&(this.a=new Ecn(this,0)),Nv(n1(this.a,(Uqn(),KLt))),!this.a&&(this.a=new Ecn(this,0)),void Z$(n1(this.a,KLt),BB(t,14));case 6:return!this.a&&(this.a=new Ecn(this,0)),Nv(n1(this.a,(Uqn(),FLt))),!this.a&&(this.a=new Ecn(this,0)),void Z$(n1(this.a,FLt),BB(t,14))}Lbn(this,n-bX((Uqn(),xLt)),itn(0==(2&this.j)?xLt:(!this.k&&(this.k=new _f),this.k).ck(),n),t)},MWn.zh=function(){return Uqn(),xLt},MWn.Bh=function(n){switch(n){case 0:return!this.a&&(this.a=new Ecn(this,0)),void sqn(this.a);case 1:return!this.b&&(this.b=new y9((gWn(),k$t),X$t,this,1)),void this.b.c.$b();case 2:return!this.c&&(this.c=new y9((gWn(),k$t),X$t,this,2)),void this.c.c.$b();case 3:return!this.a&&(this.a=new Ecn(this,0)),void Nv(n1(this.a,(Uqn(),DLt)));case 4:return!this.a&&(this.a=new Ecn(this,0)),void Nv(n1(this.a,(Uqn(),RLt)));case 5:return!this.a&&(this.a=new Ecn(this,0)),void Nv(n1(this.a,(Uqn(),KLt)));case 6:return!this.a&&(this.a=new Ecn(this,0)),void Nv(n1(this.a,(Uqn(),FLt)))}qfn(this,n-bX((Uqn(),xLt)),itn(0==(2&this.j)?xLt:(!this.k&&(this.k=new _f),this.k).ck(),n))},MWn.Ib=function(){var n;return 0!=(4&this.j)?P$n(this):((n=new fN(P$n(this))).a+=" (mixed: ",rO(n,this.a),n.a+=")",n.a)},vX(N7n,"XMLTypeDocumentRootImpl",669),wAn(1919,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1,2024:1},Ds),MWn.Ih=function(n,t){switch(n.yj()){case 7:case 8:case 9:case 10:case 16:case 22:case 23:case 24:case 25:case 26:case 32:case 33:case 34:case 36:case 37:case 44:case 45:case 50:case 51:case 53:case 55:case 56:case 57:case 58:case 60:case 61:case 4:return null==t?null:Bbn(t);case 19:case 28:case 29:case 35:case 38:case 39:case 41:case 46:case 52:case 54:case 5:return SD(t);case 6:return mD(BB(t,190));case 12:case 47:case 49:case 11:return qGn(this,n,t);case 13:return null==t?null:GBn(BB(t,240));case 15:case 14:return null==t?null:RU(Gy(MD(t)));case 17:return EEn((Uqn(),t));case 18:return EEn(t);case 21:case 20:return null==t?null:_U(BB(t,155).a);case 27:return yD(BB(t,190));case 30:return Kmn((Uqn(),BB(t,15)));case 31:return Kmn(BB(t,15));case 40:return jD((Uqn(),t));case 42:return TEn((Uqn(),t));case 43:return TEn(t);case 59:case 48:return kD((Uqn(),t));default:throw Hp(new Ky(d6n+n.ne()+g6n))}},MWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Utn(n))?uvn(t.Mh(),n):-1),n.G){case 0:return new Rm;case 1:return new Rs;case 2:return new Km;case 3:return new _m;default:throw Hp(new Ky(m6n+n.zb+g6n))}},MWn.Kh=function(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;switch(n.yj()){case 5:case 52:case 4:return t;case 6:return ypn(t);case 8:case 7:return null==t?null:KEn(t);case 9:return null==t?null:Pnn(lKn((i=FBn(t,!0)).length>0&&(b1(0,i.length),43==i.charCodeAt(0))?i.substr(1):i,-128,127)<<24>>24);case 10:return null==t?null:Pnn(lKn((r=FBn(t,!0)).length>0&&(b1(0,r.length),43==r.charCodeAt(0))?r.substr(1):r,-128,127)<<24>>24);case 11:return SD(xXn(this,(Uqn(),kLt),t));case 12:return SD(xXn(this,(Uqn(),jLt),t));case 13:return null==t?null:new wE(FBn(t,!0));case 15:case 14:return gLn(t);case 16:return SD(xXn(this,(Uqn(),ELt),t));case 17:return Hdn((Uqn(),t));case 18:return Hdn(t);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return FBn(t,!0);case 21:case 20:return CLn(t);case 22:return SD(xXn(this,(Uqn(),TLt),t));case 23:return SD(xXn(this,(Uqn(),MLt),t));case 24:return SD(xXn(this,(Uqn(),SLt),t));case 25:return SD(xXn(this,(Uqn(),PLt),t));case 26:return SD(xXn(this,(Uqn(),ILt),t));case 27:return Zgn(t);case 30:return qdn((Uqn(),t));case 31:return qdn(t);case 32:return null==t?null:iln(lKn((h=FBn(t,!0)).length>0&&(b1(0,h.length),43==h.charCodeAt(0))?h.substr(1):h,KVn,DWn));case 33:return null==t?null:new $A((f=FBn(t,!0)).length>0&&(b1(0,f.length),43==f.charCodeAt(0))?f.substr(1):f);case 34:return null==t?null:iln(lKn((l=FBn(t,!0)).length>0&&(b1(0,l.length),43==l.charCodeAt(0))?l.substr(1):l,KVn,DWn));case 36:return null==t?null:jgn(rUn((b=FBn(t,!0)).length>0&&(b1(0,b.length),43==b.charCodeAt(0))?b.substr(1):b));case 37:return null==t?null:jgn(rUn((w=FBn(t,!0)).length>0&&(b1(0,w.length),43==w.charCodeAt(0))?w.substr(1):w));case 40:return Vwn((Uqn(),t));case 42:return Gdn((Uqn(),t));case 43:return Gdn(t);case 44:return null==t?null:new $A((d=FBn(t,!0)).length>0&&(b1(0,d.length),43==d.charCodeAt(0))?d.substr(1):d);case 45:return null==t?null:new $A((g=FBn(t,!0)).length>0&&(b1(0,g.length),43==g.charCodeAt(0))?g.substr(1):g);case 46:return FBn(t,!1);case 47:return SD(xXn(this,(Uqn(),CLt),t));case 59:case 48:return Wwn((Uqn(),t));case 49:return SD(xXn(this,(Uqn(),ALt),t));case 50:return null==t?null:rln(lKn((p=FBn(t,!0)).length>0&&(b1(0,p.length),43==p.charCodeAt(0))?p.substr(1):p,Q9n,32767)<<16>>16);case 51:return null==t?null:rln(lKn((c=FBn(t,!0)).length>0&&(b1(0,c.length),43==c.charCodeAt(0))?c.substr(1):c,Q9n,32767)<<16>>16);case 53:return SD(xXn(this,(Uqn(),NLt),t));case 55:return null==t?null:rln(lKn((a=FBn(t,!0)).length>0&&(b1(0,a.length),43==a.charCodeAt(0))?a.substr(1):a,Q9n,32767)<<16>>16);case 56:return null==t?null:rln(lKn((u=FBn(t,!0)).length>0&&(b1(0,u.length),43==u.charCodeAt(0))?u.substr(1):u,Q9n,32767)<<16>>16);case 57:return null==t?null:jgn(rUn((o=FBn(t,!0)).length>0&&(b1(0,o.length),43==o.charCodeAt(0))?o.substr(1):o));case 58:return null==t?null:jgn(rUn((s=FBn(t,!0)).length>0&&(b1(0,s.length),43==s.charCodeAt(0))?s.substr(1):s));case 60:return null==t?null:iln(lKn((e=FBn(t,!0)).length>0&&(b1(0,e.length),43==e.charCodeAt(0))?e.substr(1):e,KVn,DWn));case 61:return null==t?null:iln(lKn(FBn(t,!0),KVn,DWn));default:throw Hp(new Ky(d6n+n.ne()+g6n))}},vX(N7n,"XMLTypeFactoryImpl",1919),wAn(586,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1,1945:1,586:1},zW),MWn.N=!1,MWn.O=!1;var WLt,VLt,QLt,YLt,JLt,ZLt=!1;vX(N7n,"XMLTypePackageImpl",586),wAn(1852,1,{837:1},_s),MWn._j=function(){return fFn(),TNt},vX(N7n,"XMLTypePackageImpl/1",1852),wAn(1861,1,s7n,Ks),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/10",1861),wAn(1862,1,s7n,Fs),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/11",1862),wAn(1863,1,s7n,Bs),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/12",1863),wAn(1864,1,s7n,Hs),MWn.wj=function(n){return UC(n)},MWn.xj=function(n){return x8(Ptt,sVn,333,n,7,1)},vX(N7n,"XMLTypePackageImpl/13",1864),wAn(1865,1,s7n,qs),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/14",1865),wAn(1866,1,s7n,Gs),MWn.wj=function(n){return cL(n,15)},MWn.xj=function(n){return x8(Rnt,nZn,15,n,0,1)},vX(N7n,"XMLTypePackageImpl/15",1866),wAn(1867,1,s7n,zs),MWn.wj=function(n){return cL(n,15)},MWn.xj=function(n){return x8(Rnt,nZn,15,n,0,1)},vX(N7n,"XMLTypePackageImpl/16",1867),wAn(1868,1,s7n,Us),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/17",1868),wAn(1869,1,s7n,Xs),MWn.wj=function(n){return cL(n,155)},MWn.xj=function(n){return x8(Itt,sVn,155,n,0,1)},vX(N7n,"XMLTypePackageImpl/18",1869),wAn(1870,1,s7n,Ws),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/19",1870),wAn(1853,1,s7n,Vs),MWn.wj=function(n){return cL(n,843)},MWn.xj=function(n){return x8(wLt,HWn,843,n,0,1)},vX(N7n,"XMLTypePackageImpl/2",1853),wAn(1871,1,s7n,Qs),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/20",1871),wAn(1872,1,s7n,Ys),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/21",1872),wAn(1873,1,s7n,Js),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/22",1873),wAn(1874,1,s7n,Zs),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/23",1874),wAn(1875,1,s7n,nh),MWn.wj=function(n){return cL(n,190)},MWn.xj=function(n){return x8(NNt,sVn,190,n,0,2)},vX(N7n,"XMLTypePackageImpl/24",1875),wAn(1876,1,s7n,th),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/25",1876),wAn(1877,1,s7n,eh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/26",1877),wAn(1878,1,s7n,ih),MWn.wj=function(n){return cL(n,15)},MWn.xj=function(n){return x8(Rnt,nZn,15,n,0,1)},vX(N7n,"XMLTypePackageImpl/27",1878),wAn(1879,1,s7n,rh),MWn.wj=function(n){return cL(n,15)},MWn.xj=function(n){return x8(Rnt,nZn,15,n,0,1)},vX(N7n,"XMLTypePackageImpl/28",1879),wAn(1880,1,s7n,ch),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/29",1880),wAn(1854,1,s7n,ah),MWn.wj=function(n){return cL(n,667)},MWn.xj=function(n){return x8(zLt,HWn,2021,n,0,1)},vX(N7n,"XMLTypePackageImpl/3",1854),wAn(1881,1,s7n,uh),MWn.wj=function(n){return cL(n,19)},MWn.xj=function(n){return x8(Att,sVn,19,n,0,1)},vX(N7n,"XMLTypePackageImpl/30",1881),wAn(1882,1,s7n,oh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/31",1882),wAn(1883,1,s7n,sh),MWn.wj=function(n){return cL(n,162)},MWn.xj=function(n){return x8(Rtt,sVn,162,n,0,1)},vX(N7n,"XMLTypePackageImpl/32",1883),wAn(1884,1,s7n,hh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/33",1884),wAn(1885,1,s7n,fh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/34",1885),wAn(1886,1,s7n,lh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/35",1886),wAn(1887,1,s7n,bh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/36",1887),wAn(1888,1,s7n,wh),MWn.wj=function(n){return cL(n,15)},MWn.xj=function(n){return x8(Rnt,nZn,15,n,0,1)},vX(N7n,"XMLTypePackageImpl/37",1888),wAn(1889,1,s7n,dh),MWn.wj=function(n){return cL(n,15)},MWn.xj=function(n){return x8(Rnt,nZn,15,n,0,1)},vX(N7n,"XMLTypePackageImpl/38",1889),wAn(1890,1,s7n,gh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/39",1890),wAn(1855,1,s7n,ph),MWn.wj=function(n){return cL(n,668)},MWn.xj=function(n){return x8(ULt,HWn,2022,n,0,1)},vX(N7n,"XMLTypePackageImpl/4",1855),wAn(1891,1,s7n,vh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/40",1891),wAn(1892,1,s7n,mh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/41",1892),wAn(1893,1,s7n,yh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/42",1893),wAn(1894,1,s7n,kh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/43",1894),wAn(1895,1,s7n,jh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/44",1895),wAn(1896,1,s7n,Eh),MWn.wj=function(n){return cL(n,184)},MWn.xj=function(n){return x8(Ktt,sVn,184,n,0,1)},vX(N7n,"XMLTypePackageImpl/45",1896),wAn(1897,1,s7n,Th),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/46",1897),wAn(1898,1,s7n,Mh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/47",1898),wAn(1899,1,s7n,Sh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/48",1899),wAn(sQn,1,s7n,Ph),MWn.wj=function(n){return cL(n,184)},MWn.xj=function(n){return x8(Ktt,sVn,184,n,0,1)},vX(N7n,"XMLTypePackageImpl/49",sQn),wAn(1856,1,s7n,Ih),MWn.wj=function(n){return cL(n,669)},MWn.xj=function(n){return x8(XLt,HWn,2023,n,0,1)},vX(N7n,"XMLTypePackageImpl/5",1856),wAn(1901,1,s7n,Ch),MWn.wj=function(n){return cL(n,162)},MWn.xj=function(n){return x8(Rtt,sVn,162,n,0,1)},vX(N7n,"XMLTypePackageImpl/50",1901),wAn(1902,1,s7n,Oh),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/51",1902),wAn(1903,1,s7n,Ah),MWn.wj=function(n){return cL(n,19)},MWn.xj=function(n){return x8(Att,sVn,19,n,0,1)},vX(N7n,"XMLTypePackageImpl/52",1903),wAn(1857,1,s7n,$h),MWn.wj=function(n){return XC(n)},MWn.xj=function(n){return x8(Qtt,sVn,2,n,6,1)},vX(N7n,"XMLTypePackageImpl/6",1857),wAn(1858,1,s7n,Lh),MWn.wj=function(n){return cL(n,190)},MWn.xj=function(n){return x8(NNt,sVn,190,n,0,2)},vX(N7n,"XMLTypePackageImpl/7",1858),wAn(1859,1,s7n,Nh),MWn.wj=function(n){return zC(n)},MWn.xj=function(n){return x8(ktt,sVn,476,n,8,1)},vX(N7n,"XMLTypePackageImpl/8",1859),wAn(1860,1,s7n,xh),MWn.wj=function(n){return cL(n,217)},MWn.xj=function(n){return x8(Ttt,sVn,217,n,0,1)},vX(N7n,"XMLTypePackageImpl/9",1860),wAn(50,60,BVn,ak),vX(ant,"RegEx/ParseException",50),wAn(820,1,{},Dh),MWn.sl=function(n){return n<this.j&&63==fV(this.i,n)},MWn.tl=function(){var n,t,e,i,r;if(10!=this.c)throw Hp(new ak(kWn((u$(),g8n))));switch(n=this.a){case 101:n=27;break;case 102:n=12;break;case 110:n=10;break;case 114:n=13;break;case 116:n=9;break;case 120:if(QXn(this),0!=this.c)throw Hp(new ak(kWn((u$(),B8n))));if(123==this.a){for(r=0,e=0;;){if(QXn(this),0!=this.c)throw Hp(new ak(kWn((u$(),B8n))));if((r=Gvn(this.a))<0)break;if(e>16*e)throw Hp(new ak(kWn((u$(),H8n))));e=16*e+r}if(125!=this.a)throw Hp(new ak(kWn((u$(),q8n))));if(e>unt)throw Hp(new ak(kWn((u$(),G8n))));n=e}else{if(r=0,0!=this.c||(r=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(e=r,QXn(this),0!=this.c||(r=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));n=e=16*e+r}break;case 117:if(i=0,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(t=i,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(t=16*t+i,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(t=16*t+i,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));n=t=16*t+i;break;case 118:if(QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(t=i,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(t=16*t+i,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(t=16*t+i,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(t=16*t+i,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if(t=16*t+i,QXn(this),0!=this.c||(i=Gvn(this.a))<0)throw Hp(new ak(kWn((u$(),B8n))));if((t=16*t+i)>unt)throw Hp(new ak(kWn((u$(),"parser.descappe.4"))));n=t;break;case 65:case 90:case 122:throw Hp(new ak(kWn((u$(),z8n))))}return n},MWn.ul=function(n){var t;switch(n){case 100:t=32==(32&this.e)?ZUn("Nd",!0):(wWn(),uNt);break;case 68:t=32==(32&this.e)?ZUn("Nd",!1):(wWn(),lNt);break;case 119:t=32==(32&this.e)?ZUn("IsWord",!0):(wWn(),kNt);break;case 87:t=32==(32&this.e)?ZUn("IsWord",!1):(wWn(),wNt);break;case 115:t=32==(32&this.e)?ZUn("IsSpace",!0):(wWn(),gNt);break;case 83:t=32==(32&this.e)?ZUn("IsSpace",!1):(wWn(),bNt);break;default:throw Hp(new dy(ont+n.toString(16)))}return t},MWn.vl=function(n){var t,e,i,r,c,a,u,o,s,h,f;for(this.b=1,QXn(this),t=null,0==this.c&&94==this.a?(QXn(this),n?(wWn(),wWn(),s=new M0(5)):(wWn(),wWn(),Yxn(t=new M0(4),0,unt),s=new M0(4))):(wWn(),wWn(),s=new M0(4)),r=!0;1!=(f=this.c)&&(0!=f||93!=this.a||r);){if(r=!1,e=this.a,i=!1,10==f)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:sHn(s,this.ul(e)),i=!0;break;case 105:case 73:case 99:case 67:(e=this.Ll(s,e))<0&&(i=!0);break;case 112:case 80:if(!(h=DCn(this,e)))throw Hp(new ak(kWn((u$(),O8n))));sHn(s,h),i=!0;break;default:e=this.tl()}else if(20==f){if((c=lx(this.i,58,this.d))<0)throw Hp(new ak(kWn((u$(),A8n))));if(a=!0,94==fV(this.i,this.d)&&(++this.d,a=!1),!(u=b9(fx(this.i,this.d,c),a,512==(512&this.e))))throw Hp(new ak(kWn((u$(),L8n))));if(sHn(s,u),i=!0,c+1>=this.j||93!=fV(this.i,c+1))throw Hp(new ak(kWn((u$(),A8n))));this.d=c+2}if(QXn(this),!i)if(0!=this.c||45!=this.a)Yxn(s,e,e);else{if(QXn(this),1==(f=this.c))throw Hp(new ak(kWn((u$(),$8n))));0==f&&93==this.a?(Yxn(s,e,e),Yxn(s,45,45)):(o=this.a,10==f&&(o=this.tl()),QXn(this),Yxn(s,e,o))}(this.e&k6n)==k6n&&0==this.c&&44==this.a&&QXn(this)}if(1==this.c)throw Hp(new ak(kWn((u$(),$8n))));return t&&(WGn(t,s),s=t),T$n(s),qHn(s),this.b=0,QXn(this),s},MWn.wl=function(){var n,t,e,i;for(e=this.vl(!1);7!=(i=this.c);){if(n=this.a,(0!=i||45!=n&&38!=n)&&4!=i)throw Hp(new ak(kWn((u$(),K8n))));if(QXn(this),9!=this.c)throw Hp(new ak(kWn((u$(),_8n))));if(t=this.vl(!1),4==i)sHn(e,t);else if(45==n)WGn(e,t);else{if(38!=n)throw Hp(new dy("ASSERT"));kGn(e,t)}}return QXn(this),e},MWn.xl=function(){var n,t;return n=this.a-48,wWn(),wWn(),t=new vJ(12,null,n),!this.g&&(this.g=new Kv),Iv(this.g,new Op(n)),QXn(this),t},MWn.yl=function(){return QXn(this),wWn(),pNt},MWn.zl=function(){return QXn(this),wWn(),dNt},MWn.Al=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Bl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Cl=function(){return QXn(this),fsn()},MWn.Dl=function(){return QXn(this),wWn(),mNt},MWn.El=function(){return QXn(this),wWn(),jNt},MWn.Fl=function(){var n;if(this.d>=this.j||64!=(65504&(n=fV(this.i,this.d++))))throw Hp(new ak(kWn((u$(),S8n))));return QXn(this),wWn(),wWn(),new oG(0,n-64)},MWn.Gl=function(){return QXn(this),RFn()},MWn.Hl=function(){return QXn(this),wWn(),ENt},MWn.Il=function(){var n;return wWn(),wWn(),n=new oG(0,105),QXn(this),n},MWn.Jl=function(){return QXn(this),wWn(),yNt},MWn.Kl=function(){return QXn(this),wWn(),vNt},MWn.Ll=function(n,t){return this.tl()},MWn.Ml=function(){return QXn(this),wWn(),hNt},MWn.Nl=function(){var n,t,e,i,r;if(this.d+1>=this.j)throw Hp(new ak(kWn((u$(),E8n))));if(i=-1,t=null,49<=(n=fV(this.i,this.d))&&n<=57){if(i=n-48,!this.g&&(this.g=new Kv),Iv(this.g,new Op(i)),++this.d,41!=fV(this.i,this.d))throw Hp(new ak(kWn((u$(),y8n))));++this.d}else switch(63==n&&--this.d,QXn(this),(t=OXn(this)).e){case 20:case 21:case 22:case 23:break;case 8:if(7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));break;default:throw Hp(new ak(kWn((u$(),T8n))))}if(QXn(this),e=null,2==(r=Vdn(this)).e){if(2!=r.em())throw Hp(new ak(kWn((u$(),M8n))));e=r.am(1),r=r.am(0)}if(7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),wWn(),wWn(),new jnn(i,t,r,e)},MWn.Ol=function(){return QXn(this),wWn(),fNt},MWn.Pl=function(){var n;if(QXn(this),n=uU(24,Vdn(this)),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),n},MWn.Ql=function(){var n;if(QXn(this),n=uU(20,Vdn(this)),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),n},MWn.Rl=function(){var n;if(QXn(this),n=uU(22,Vdn(this)),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),n},MWn.Sl=function(){var n,t,e,i,r;for(n=0,e=0,t=-1;this.d<this.j&&0!=(r=QOn(t=fV(this.i,this.d)));)n|=r,++this.d;if(this.d>=this.j)throw Hp(new ak(kWn((u$(),k8n))));if(45==t){for(++this.d;this.d<this.j&&0!=(r=QOn(t=fV(this.i,this.d)));)e|=r,++this.d;if(this.d>=this.j)throw Hp(new ak(kWn((u$(),k8n))))}if(58==t){if(++this.d,QXn(this),i=AX(Vdn(this),n,e),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));QXn(this)}else{if(41!=t)throw Hp(new ak(kWn((u$(),j8n))));++this.d,QXn(this),i=AX(Vdn(this),n,e)}return i},MWn.Tl=function(){var n;if(QXn(this),n=uU(21,Vdn(this)),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),n},MWn.Ul=function(){var n;if(QXn(this),n=uU(23,Vdn(this)),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),n},MWn.Vl=function(){var n,t;if(QXn(this),n=this.f++,t=oU(Vdn(this),n),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),t},MWn.Wl=function(){var n;if(QXn(this),n=oU(Vdn(this),0),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),n},MWn.Xl=function(n){return QXn(this),5==this.c?(QXn(this),gG(n,(wWn(),wWn(),new h4(9,n)))):gG(n,(wWn(),wWn(),new h4(3,n)))},MWn.Yl=function(n){var t;return QXn(this),wWn(),wWn(),t=new r$(2),5==this.c?(QXn(this),tqn(t,sNt),tqn(t,n)):(tqn(t,n),tqn(t,sNt)),t},MWn.Zl=function(n){return QXn(this),5==this.c?(QXn(this),wWn(),wWn(),new h4(9,n)):(wWn(),wWn(),new h4(3,n))},MWn.a=0,MWn.b=0,MWn.c=0,MWn.d=0,MWn.e=0,MWn.f=1,MWn.g=null,MWn.j=0,vX(ant,"RegEx/RegexParser",820),wAn(1824,820,{},Fm),MWn.sl=function(n){return!1},MWn.tl=function(){return qDn(this)},MWn.ul=function(n){return dKn(n)},MWn.vl=function(n){return ZXn(this)},MWn.wl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.xl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.yl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.zl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Al=function(){return QXn(this),dKn(67)},MWn.Bl=function(){return QXn(this),dKn(73)},MWn.Cl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Dl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.El=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Fl=function(){return QXn(this),dKn(99)},MWn.Gl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Hl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Il=function(){return QXn(this),dKn(105)},MWn.Jl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Kl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Ll=function(n,t){return sHn(n,dKn(t)),-1},MWn.Ml=function(){return QXn(this),wWn(),wWn(),new oG(0,94)},MWn.Nl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Ol=function(){return QXn(this),wWn(),wWn(),new oG(0,36)},MWn.Pl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Ql=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Rl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Sl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Tl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Ul=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Vl=function(){var n;if(QXn(this),n=oU(Vdn(this),0),7!=this.c)throw Hp(new ak(kWn((u$(),y8n))));return QXn(this),n},MWn.Wl=function(){throw Hp(new ak(kWn((u$(),U8n))))},MWn.Xl=function(n){return QXn(this),gG(n,(wWn(),wWn(),new h4(3,n)))},MWn.Yl=function(n){var t;return QXn(this),wWn(),wWn(),tqn(t=new r$(2),n),tqn(t,sNt),t},MWn.Zl=function(n){return QXn(this),wWn(),wWn(),new h4(3,n)};var nNt=null,tNt=null;vX(ant,"RegEx/ParserForXMLSchema",1824),wAn(117,1,ynt,Ap),MWn.$l=function(n){throw Hp(new dy("Not supported."))},MWn._l=function(){return-1},MWn.am=function(n){return null},MWn.bm=function(){return null},MWn.cm=function(n){},MWn.dm=function(n){},MWn.em=function(){return 0},MWn.Ib=function(){return this.fm(0)},MWn.fm=function(n){return 11==this.e?".":""},MWn.e=0;var eNt,iNt,rNt,cNt,aNt,uNt,oNt,sNt,hNt,fNt,lNt,bNt,wNt,dNt,gNt,pNt,vNt,mNt,yNt,kNt,jNt,ENt,TNt,MNt,SNt=null,PNt=null,INt=null,CNt=vX(ant,"RegEx/Token",117);wAn(136,117,{3:1,136:1,117:1},M0),MWn.fm=function(n){var t,e,i;if(4==this.e)if(this==oNt)e=".";else if(this==uNt)e="\\d";else if(this==kNt)e="\\w";else if(this==gNt)e="\\s";else{for((i=new Sk).a+="[",t=0;t<this.b.length;t+=2)0!=(n&k6n)&&t>0&&(i.a+=","),this.b[t]===this.b[t+1]?cO(i,aBn(this.b[t])):(cO(i,aBn(this.b[t])),i.a+="-",cO(i,aBn(this.b[t+1])));i.a+="]",e=i.a}else if(this==lNt)e="\\D";else if(this==wNt)e="\\W";else if(this==bNt)e="\\S";else{for((i=new Sk).a+="[^",t=0;t<this.b.length;t+=2)0!=(n&k6n)&&t>0&&(i.a+=","),this.b[t]===this.b[t+1]?cO(i,aBn(this.b[t])):(cO(i,aBn(this.b[t])),i.a+="-",cO(i,aBn(this.b[t+1])));i.a+="]",e=i.a}return e},MWn.a=!1,MWn.c=!1,vX(ant,"RegEx/RangeToken",136),wAn(584,1,{584:1},Op),MWn.a=0,vX(ant,"RegEx/RegexParser/ReferencePosition",584),wAn(583,1,{3:1,583:1},XE),MWn.Fb=function(n){var t;return null!=n&&!!cL(n,583)&&(t=BB(n,583),m_(this.b,t.b)&&this.a==t.a)},MWn.Hb=function(){return vvn(this.b+"/"+txn(this.a))},MWn.Ib=function(){return this.c.fm(this.a)},MWn.a=0,vX(ant,"RegEx/RegularExpression",583),wAn(223,117,ynt,oG),MWn._l=function(){return this.a},MWn.fm=function(n){var t,e;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:e="\\"+PR(this.a&QVn);break;case 12:e="\\f";break;case 10:e="\\n";break;case 13:e="\\r";break;case 9:e="\\t";break;case 27:e="\\e";break;default:e=this.a>=BQn?"\\v"+fx(t="0"+(this.a>>>0).toString(16),t.length-6,t.length):""+PR(this.a&QVn)}break;case 8:e=this==hNt||this==fNt?""+PR(this.a&QVn):"\\"+PR(this.a&QVn);break;default:e=null}return e},MWn.a=0,vX(ant,"RegEx/Token/CharToken",223),wAn(309,117,ynt,h4),MWn.am=function(n){return this.a},MWn.cm=function(n){this.b=n},MWn.dm=function(n){this.c=n},MWn.em=function(){return 1},MWn.fm=function(n){var t;if(3==this.e)if(this.c<0&&this.b<0)t=this.a.fm(n)+"*";else if(this.c==this.b)t=this.a.fm(n)+"{"+this.c+"}";else if(this.c>=0&&this.b>=0)t=this.a.fm(n)+"{"+this.c+","+this.b+"}";else{if(!(this.c>=0&&this.b<0))throw Hp(new dy("Token#toString(): CLOSURE "+this.c+FWn+this.b));t=this.a.fm(n)+"{"+this.c+",}"}else if(this.c<0&&this.b<0)t=this.a.fm(n)+"*?";else if(this.c==this.b)t=this.a.fm(n)+"{"+this.c+"}?";else if(this.c>=0&&this.b>=0)t=this.a.fm(n)+"{"+this.c+","+this.b+"}?";else{if(!(this.c>=0&&this.b<0))throw Hp(new dy("Token#toString(): NONGREEDYCLOSURE "+this.c+FWn+this.b));t=this.a.fm(n)+"{"+this.c+",}?"}return t},MWn.b=0,MWn.c=0,vX(ant,"RegEx/Token/ClosureToken",309),wAn(821,117,ynt,UU),MWn.am=function(n){return 0==n?this.a:this.b},MWn.em=function(){return 2},MWn.fm=function(n){return 3==this.b.e&&this.b.am(0)==this.a?this.a.fm(n)+"+":9==this.b.e&&this.b.am(0)==this.a?this.a.fm(n)+"+?":this.a.fm(n)+""+this.b.fm(n)},vX(ant,"RegEx/Token/ConcatToken",821),wAn(1822,117,ynt,jnn),MWn.am=function(n){if(0==n)return this.d;if(1==n)return this.b;throw Hp(new dy("Internal Error: "+n))},MWn.em=function(){return this.b?2:1},MWn.fm=function(n){var t;return t=this.c>0?"(?("+this.c+")":8==this.a.e?"(?("+this.a+")":"(?"+this.a,this.b?t+=this.d+"|"+this.b+")":t+=this.d+")",t},MWn.c=0,vX(ant,"RegEx/Token/ConditionToken",1822),wAn(1823,117,ynt,T0),MWn.am=function(n){return this.b},MWn.em=function(){return 1},MWn.fm=function(n){return"(?"+(0==this.a?"":txn(this.a))+(0==this.c?"":txn(this.c))+":"+this.b.fm(n)+")"},MWn.a=0,MWn.c=0,vX(ant,"RegEx/Token/ModifierToken",1823),wAn(822,117,ynt,cW),MWn.am=function(n){return this.a},MWn.em=function(){return 1},MWn.fm=function(n){var t;switch(t=null,this.e){case 6:t=0==this.b?"(?:"+this.a.fm(n)+")":"("+this.a.fm(n)+")";break;case 20:t="(?="+this.a.fm(n)+")";break;case 21:t="(?!"+this.a.fm(n)+")";break;case 22:t="(?<="+this.a.fm(n)+")";break;case 23:t="(?<!"+this.a.fm(n)+")";break;case 24:t="(?>"+this.a.fm(n)+")"}return t},MWn.b=0,vX(ant,"RegEx/Token/ParenToken",822),wAn(521,117,{3:1,117:1,521:1},vJ),MWn.bm=function(){return this.b},MWn.fm=function(n){return 12==this.e?"\\"+this.a:iAn(this.b)},MWn.a=0,vX(ant,"RegEx/Token/StringToken",521),wAn(465,117,ynt,r$),MWn.$l=function(n){tqn(this,n)},MWn.am=function(n){return BB(bW(this.a,n),117)},MWn.em=function(){return this.a?this.a.a.c.length:0},MWn.fm=function(n){var t,e,i,r,c;if(1==this.e){if(2==this.a.a.c.length)t=BB(bW(this.a,0),117),r=3==(e=BB(bW(this.a,1),117)).e&&e.am(0)==t?t.fm(n)+"+":9==e.e&&e.am(0)==t?t.fm(n)+"+?":t.fm(n)+""+e.fm(n);else{for(c=new Sk,i=0;i<this.a.a.c.length;i++)cO(c,BB(bW(this.a,i),117).fm(n));r=c.a}return r}if(2==this.a.a.c.length&&7==BB(bW(this.a,1),117).e)r=BB(bW(this.a,0),117).fm(n)+"?";else if(2==this.a.a.c.length&&7==BB(bW(this.a,0),117).e)r=BB(bW(this.a,1),117).fm(n)+"??";else{for(cO(c=new Sk,BB(bW(this.a,0),117).fm(n)),i=1;i<this.a.a.c.length;i++)c.a+="|",cO(c,BB(bW(this.a,i),117).fm(n));r=c.a}return r},vX(ant,"RegEx/Token/UnionToken",465),wAn(518,1,{592:1},UE),MWn.Ib=function(){return this.a.b},vX(knt,"XMLTypeUtil/PatternMatcherImpl",518),wAn(1622,1381,{},Rh),vX(knt,"XMLTypeValidator",1622),wAn(264,1,pVn,hz),MWn.Jc=function(n){e5(this,n)},MWn.Kc=function(){return(this.b-this.a)*this.c<0?MNt:new XL(this)},MWn.a=0,MWn.b=0,MWn.c=0,vX(Ent,"ExclusiveRange",264),wAn(1068,1,cVn,_h),MWn.Rb=function(n){BB(n,19),l$()},MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return GE()},MWn.Ub=function(){return zE()},MWn.Wb=function(n){BB(n,19),w$()},MWn.Ob=function(){return!1},MWn.Sb=function(){return!1},MWn.Tb=function(){return-1},MWn.Vb=function(){return-1},MWn.Qb=function(){throw Hp(new tk(Snt))},vX(Ent,"ExclusiveRange/1",1068),wAn(254,1,cVn,XL),MWn.Rb=function(n){BB(n,19),b$()},MWn.Nb=function(n){fU(this,n)},MWn.Pb=function(){return Fhn(this)},MWn.Ub=function(){return O9(this)},MWn.Wb=function(n){BB(n,19),d$()},MWn.Ob=function(){return this.c.c<0?this.a>=this.c.b:this.a<=this.c.b},MWn.Sb=function(){return this.b>0},MWn.Tb=function(){return this.b},MWn.Vb=function(){return this.b-1},MWn.Qb=function(){throw Hp(new tk(Snt))},MWn.a=0,MWn.b=0,vX(Ent,"ExclusiveRange/RangeIterator",254);var ONt=RW(P9n,"C"),ANt=RW(O9n,"I"),$Nt=RW($Wn,"Z"),LNt=RW(A9n,"J"),NNt=RW(S9n,"B"),xNt=RW(I9n,"D"),DNt=RW(C9n,"F"),RNt=RW($9n,"S"),_Nt=bq("org.eclipse.elk.core.labels","ILabelManager"),KNt=bq(B6n,"DiagnosticChain"),FNt=bq(f7n,"ResourceSet"),BNt=vX(B6n,"InvocationTargetException",null),HNt=(Dk(),f5),qNt=qNt=hEn;Zen(Qp),scn("permProps",[[[Pnt,Int],[Cnt,"gecko1_8"]],[[Pnt,Int],[Cnt,"ie10"]],[[Pnt,Int],[Cnt,"ie8"]],[[Pnt,Int],[Cnt,"ie9"]],[[Pnt,Int],[Cnt,"safari"]]]),qNt(null,"elk",null)}).call(this)}).call(this,void 0!==e.g?e.g:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,t,e){"use strict";function i(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}function r(n,t){if(!n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?n:t}function c(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);n.prototype=Object.create(t&&t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(n,t):n.__proto__=t)}var a=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,e);var c=Object.assign({},t),a=!1;try{n.resolve("web-worker"),a=!0}catch(s){}if(t.workerUrl)if(a){var u=n("web-worker");c.workerFactory=function(n){return new u(n)}}else console.warn("Web worker requested but 'web-worker' package not installed. \nConsider installing the package or pass your own 'workerFactory' to ELK's constructor.\n... Falling back to non-web worker version.");if(!c.workerFactory){var o=n("./elk-worker.min.js").Worker;c.workerFactory=function(n){return new o(n)}}return r(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,c))}return c(e,t),e}(n("./elk-api.js").default);Object.defineProperty(t.exports,"__esModule",{value:!0}),t.exports=a,a.default=a},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(n,t,e){t.exports=Worker},{}]},{},[3])(3)},47740:(n,t,e)=>{"use strict";e.d(t,{diagram:()=>k});var i=e(75254),r=e(64218),c=e(27707),a=e(56363),u=e(17295);e(27484),e(17967),e(27856);const o=new u;let s={};const h={};let f={};const l=(n,t,e)=>{const i={TB:{in:{north:"north"},out:{south:"west",west:"east",east:"south"}},LR:{in:{west:"west"},out:{east:"south",south:"north",north:"east"}},RL:{in:{east:"east"},out:{west:"north",north:"south",south:"west"}},BT:{in:{south:"south"},out:{north:"east",east:"west",west:"north"}}};return i.TD=i.TB,a.l.info("abc88",e,t,n),i[e][t][n]},b=(n,t,e)=>{if(a.l.info("getNextPort abc88",{node:n,edgeDirection:t,graphDirection:e}),!s[n])switch(e){case"TB":case"TD":s[n]={inPosition:"north",outPosition:"south"};break;case"BT":s[n]={inPosition:"south",outPosition:"north"};break;case"RL":s[n]={inPosition:"east",outPosition:"west"};break;case"LR":s[n]={inPosition:"west",outPosition:"east"}}const i="in"===t?s[n].inPosition:s[n].outPosition;return"in"===t?s[n].inPosition=l(s[n].inPosition,t,e):s[n].outPosition=l(s[n].outPosition,t,e),i},w=function(n,t,e,i){a.l.info("abc78 edges = ",n);const u=i.insert("g").attr("class","edgeLabels");let o,s,l={},w=t.db.getDirection();if(void 0!==n.defaultStyle){const t=(0,a.k)(n.defaultStyle);o=t.style,s=t.labelStyle}return n.forEach((function(t){const i="L-"+t.start+"-"+t.end;void 0===l[i]?(l[i]=0,a.l.info("abc78 new entry",i,l[i])):(l[i]++,a.l.info("abc78 new entry",i,l[i]));let d=i+"-"+l[i];a.l.info("abc78 new link id to be used is",i,d,l[i]);const g="LS-"+t.start,p="LE-"+t.end,v={style:"",labelStyle:""};switch(v.minlen=t.length||1,"arrow_open"===t.type?v.arrowhead="none":v.arrowhead="normal",v.arrowTypeStart="arrow_open",v.arrowTypeEnd="arrow_open",t.type){case"double_arrow_cross":v.arrowTypeStart="arrow_cross";case"arrow_cross":v.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":v.arrowTypeStart="arrow_point";case"arrow_point":v.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":v.arrowTypeStart="arrow_circle";case"arrow_circle":v.arrowTypeEnd="arrow_circle"}let m="",y="";switch(t.stroke){case"normal":m="fill:none;",void 0!==o&&(m=o),void 0!==s&&(y=s),v.thickness="normal",v.pattern="solid";break;case"dotted":v.thickness="normal",v.pattern="dotted",v.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":v.thickness="thick",v.pattern="solid",v.style="stroke-width: 3.5px;fill:none;"}if(void 0!==t.style){const n=(0,a.k)(t.style);m=n.style,y=n.labelStyle}v.style=v.style+=m,v.labelStyle=v.labelStyle+=y,void 0!==t.interpolate?v.curve=(0,a.n)(t.interpolate,r.c_6):void 0!==n.defaultInterpolate?v.curve=(0,a.n)(n.defaultInterpolate,r.c_6):v.curve=(0,a.n)(h.curve,r.c_6),void 0===t.text?void 0!==t.style&&(v.arrowheadStyle="fill: #333"):(v.arrowheadStyle="fill: #333",v.labelpos="c"),v.labelType=t.labelType,v.label=t.text.replace(a.e.lineBreakRegex,"\n"),void 0===t.style&&(v.style=v.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),v.labelStyle=v.labelStyle.replace("color:","fill:"),v.id=d,v.classes="flowchart-link "+g+" "+p;const k=(0,c.f)(u,v),{source:j,target:E,sourceId:T,targetId:M}=((n,t)=>{let e=n.start,i=n.end;const r=e,c=i,a=f[e],u=f[i];return a&&u?("diamond"===a.type&&(e=`${e}-${b(e,"out",t)}`),"diamond"===u.type&&(i=`${i}-${b(i,"in",t)}`),{source:e,target:i,sourceId:r,targetId:c}):{source:e,target:i}})(t,w);a.l.debug("abc78 source and target",j,E),e.edges.push({id:"e"+t.start+t.end,sources:[j],targets:[E],sourceId:T,targetId:M,labelEl:k,labels:[{width:v.width,height:v.height,orgWidth:v.width,orgHeight:v.height,text:v.label,layoutOptions:{"edgeLabels.inline":"true","edgeLabels.placement":"CENTER"}}],edgeData:v})})),e},d=function(n,t,e){const i=((n,t,e)=>{const{parentById:i}=e,r=new Set;let c=n;for(;c;){if(r.add(c),c===t)return c;c=i[c]}for(c=t;c;){if(r.has(c))return c;c=i[c]}return"root"})(n,t,e);if(void 0===i||"root"===i)return{x:0,y:0};const r=f[i].offset;return{x:r.posX,y:r.posY}},g=function(n,t,e,i,a,u){const o=d(t.sourceId,t.targetId,a),s=t.sections[0].startPoint,h=t.sections[0].endPoint,f=(t.sections[0].bendPoints?t.sections[0].bendPoints:[]).map((n=>[n.x+o.x,n.y+o.y])),l=[[s.x+o.x,s.y+o.y],...f,[h.x+o.x,h.y+o.y]],{x:b,y:w}=(0,c.j)(t.edgeData),g=(0,r.jvg)().x(b).y(w).curve(r.c_6),p=n.insert("path").attr("d",g(l)).attr("class","path "+e.classes).attr("fill","none"),v=n.insert("g").attr("class","edgeLabel"),m=(0,r.Ys)(v.node().appendChild(t.labelEl)),y=m.node().firstChild.getBoundingClientRect();m.attr("width",y.width),m.attr("height",y.height),v.attr("transform",`translate(${t.labels[0].x+o.x}, ${t.labels[0].y+o.y})`),function(n,t,e,i,r){let c="";switch(i&&(c=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,c=c.replace(/\(/g,"\\("),c=c.replace(/\)/g,"\\)")),t.arrowTypeStart){case"arrow_cross":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-crossStart)");break;case"arrow_point":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-pointStart)");break;case"arrow_barb":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-barbStart)");break;case"arrow_circle":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-circleStart)");break;case"aggregation":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-aggregationStart)");break;case"extension":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-extensionStart)");break;case"composition":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-compositionStart)");break;case"dependency":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-dependencyStart)");break;case"lollipop":n.attr("marker-start","url("+c+"#"+r+"_"+e+"-lollipopStart)")}switch(t.arrowTypeEnd){case"arrow_cross":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-crossEnd)");break;case"arrow_point":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-pointEnd)");break;case"arrow_barb":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-barbEnd)");break;case"arrow_circle":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-circleEnd)");break;case"aggregation":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-aggregationEnd)");break;case"extension":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-extensionEnd)");break;case"composition":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-compositionEnd)");break;case"dependency":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-dependencyEnd)");break;case"lollipop":n.attr("marker-end","url("+c+"#"+r+"_"+e+"-lollipopEnd)")}}(p,e,i.type,i.arrowMarkerAbsolute,u)},p=(n,t)=>{n.forEach((n=>{n.children||(n.children=[]);const e=t.childrenById[n.id];e&&e.forEach((t=>{n.children.push(f[t])})),p(n.children,t)}))},v=(n,t,e,i,r,c,u)=>{e.forEach((function(e){if(e)if(f[e.id].offset={posX:e.x+n,posY:e.y+t,x:n,y:t,depth:u,width:e.width,height:e.height},"group"===e.type){const i=r.insert("g").attr("class","subgraph");i.insert("rect").attr("class","subgraph subgraph-lvl-"+u%5+" node").attr("x",e.x+n).attr("y",e.y+t).attr("width",e.width).attr("height",e.height);const c=i.insert("g").attr("class","label"),o=(0,a.E)().flowchart.htmlLabels?e.labelData.width/2:0;c.attr("transform",`translate(${e.labels[0].x+n+e.x+o}, ${e.labels[0].y+t+e.y+3})`),c.node().appendChild(e.labelData.labelNode),a.l.info("Id (UGH)= ",e.type,e.labels)}else a.l.info("Id (UGH)= ",e.id),e.el.attr("transform",`translate(${e.x+n+e.width/2}, ${e.y+t+e.height/2})`)})),e.forEach((function(e){e&&"group"===e.type&&v(n+e.x,t+e.y,e.children,i,r,c,u+1)}))},m={getClasses:function(n,t){return a.l.info("Extracting classes"),t.db.getClasses()},draw:async function(n,t,e,i){var u;i.db.clear(),f={},s={},i.db.setGen("gen-2"),i.parser.parse(n);const h=(0,r.Ys)("body").append("div").attr("style","height:400px").attr("id","cy");let l={id:"root",layoutOptions:{"elk.hierarchyHandling":"INCLUDE_CHILDREN","org.eclipse.elk.padding":"[top=100, left=100, bottom=110, right=110]","elk.layered.spacing.edgeNodeBetweenLayers":"30","elk.direction":"DOWN"},children:[],edges:[]};switch(a.l.info("Drawing flowchart using v3 renderer",o),i.db.getDirection()){case"BT":l.layoutOptions["elk.direction"]="UP";break;case"TB":l.layoutOptions["elk.direction"]="DOWN";break;case"LR":l.layoutOptions["elk.direction"]="RIGHT";break;case"RL":l.layoutOptions["elk.direction"]="LEFT"}const{securityLevel:b,flowchart:d}=(0,a.E)();let m;"sandbox"===b&&(m=(0,r.Ys)("#i"+t));const y="sandbox"===b?(0,r.Ys)(m.nodes()[0].contentDocument.body):(0,r.Ys)("body"),k="sandbox"===b?m.nodes()[0].contentDocument:document,j=y.select(`[id="${t}"]`);(0,c.a)(j,["point","circle","cross"],i.type,t);const E=i.db.getVertices();let T;const M=i.db.getSubGraphs();a.l.info("Subgraphs - ",M);for(let r=M.length-1;r>=0;r--)T=M[r],i.db.addVertex(T.id,{text:T.title,type:T.labelType},"group",void 0,T.classes,T.dir);const S=j.insert("g").attr("class","subgraphs"),P=function(n){const t={parentById:{},childrenById:{}},e=n.getSubGraphs();return a.l.info("Subgraphs - ",e),e.forEach((function(n){n.nodes.forEach((function(e){t.parentById[e]=n.id,void 0===t.childrenById[n.id]&&(t.childrenById[n.id]=[]),t.childrenById[n.id].push(e)}))})),e.forEach((function(n){n.id,void 0!==t.parentById[n.id]&&t.parentById[n.id]})),t}(i.db);l=await async function(n,t,e,i,r,u,o){const s=e.select(`[id="${t}"]`).insert("g").attr("class","nodes"),h=Object.keys(n);return await Promise.all(h.map((async function(t){const e=n[t];let o="default";e.classes.length>0&&(o=e.classes.join(" ")),o+=" flowchart-label";const h=(0,a.k)(e.styles);let l=void 0!==e.text?e.text:e.id;const b={width:0,height:0},w=[{id:e.id+"-west",layoutOptions:{"port.side":"WEST"}},{id:e.id+"-east",layoutOptions:{"port.side":"EAST"}},{id:e.id+"-south",layoutOptions:{"port.side":"SOUTH"}},{id:e.id+"-north",layoutOptions:{"port.side":"NORTH"}}];let d=0,g="",p={};switch(e.type){case"round":d=5,g="rect";break;case"square":case"group":default:g="rect";break;case"diamond":g="question",p={portConstraints:"FIXED_SIDE"};break;case"hexagon":g="hexagon";break;case"odd":case"odd_right":g="rect_left_inv_arrow";break;case"lean_right":g="lean_right";break;case"lean_left":g="lean_left";break;case"trapezoid":g="trapezoid";break;case"inv_trapezoid":g="inv_trapezoid";break;case"circle":g="circle";break;case"ellipse":g="ellipse";break;case"stadium":g="stadium";break;case"subroutine":g="subroutine";break;case"cylinder":g="cylinder";break;case"doublecircle":g="doublecircle"}const v={labelStyle:h.labelStyle,shape:g,labelText:l,labelType:e.labelType,rx:d,ry:d,class:o,style:h.style,id:e.id,link:e.link,linkTarget:e.linkTarget,tooltip:r.db.getTooltip(e.id)||"",domId:r.db.lookUpDomId(e.id),haveCallback:e.haveCallback,width:"group"===e.type?500:void 0,dir:e.dir,type:e.type,props:e.props,padding:(0,a.E)().flowchart.padding};let m,y;if("group"!==v.type)y=await(0,c.e)(s,v,e.dir),m=y.node().getBBox();else{i.createElementNS("http://www.w3.org/2000/svg","text");const{shapeSvg:n,bbox:t}=await(0,c.l)(s,v,void 0,!0);b.width=t.width,b.wrappingWidth=(0,a.E)().flowchart.wrappingWidth,b.height=t.height,b.labelNode=n.node(),v.labelData=b}const k={id:e.id,ports:"diamond"===e.type?w:[],layoutOptions:p,labelText:l,labelData:b,domId:r.db.lookUpDomId(e.id),width:null==m?void 0:m.width,height:null==m?void 0:m.height,type:e.type,el:y,parent:u.parentById[e.id]};f[v.id]=k}))),o}(E,t,y,k,i,P,l);const I=j.insert("g").attr("class","edges edgePath"),C=i.db.getEdges();l=w(C,i,l,j);Object.keys(f).forEach((n=>{const t=f[n];t.parent||l.children.push(t),void 0!==P.childrenById[n]&&(t.labels=[{text:t.labelText,layoutOptions:{"nodeLabels.placement":"[H_CENTER, V_TOP, INSIDE]"},width:t.labelData.width,height:t.labelData.height}],delete t.x,delete t.y,delete t.width,delete t.height)})),p(l.children,P),a.l.info("after layout",JSON.stringify(l,null,2));const O=await o.layout(l);v(0,0,O.children,j,S,i,0),a.l.info("after layout",O),null==(u=O.edges)||u.map((n=>{g(I,n,n.edgeData,i,P,t)})),(0,a.o)({},j,d.diagramPadding,d.useMaxWidth),h.remove()}},y=n=>`.label {\n font-family: ${n.fontFamily};\n color: ${n.nodeTextColor||n.textColor};\n }\n .cluster-label text {\n fill: ${n.titleColor};\n }\n .cluster-label span {\n color: ${n.titleColor};\n }\n\n .label text,span {\n fill: ${n.nodeTextColor||n.textColor};\n color: ${n.nodeTextColor||n.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${n.mainBkg};\n stroke: ${n.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${n.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${n.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${n.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${n.edgeLabelBackground};\n rect {\n opacity: 0.85;\n background-color: ${n.edgeLabelBackground};\n fill: ${n.edgeLabelBackground};\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ${n.clusterBkg};\n stroke: ${n.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${n.titleColor};\n }\n\n .cluster span {\n color: ${n.titleColor};\n }\n /* .cluster div {\n color: ${n.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${n.fontFamily};\n font-size: 12px;\n background: ${n.tertiaryColor};\n border: 1px solid ${n.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${n.textColor};\n }\n .subgraph {\n stroke-width:2;\n rx:3;\n }\n // .subgraph-lvl-1 {\n // fill:#ccc;\n // // stroke:black;\n // }\n\n .flowchart-label text {\n text-anchor: middle;\n }\n\n ${(n=>{let t="";for(let e=0;e<5;e++)t+=`\n .subgraph-lvl-${e} {\n fill: ${n[`surface${e}`]};\n stroke: ${n[`surfacePeer${e}`]};\n }\n `;return t})(n)}\n`,k={db:i.d,renderer:m,parser:i.p,styles:y}}}]); \ No newline at end of file diff --git a/assets/js/5a473bed.c195eeae.js b/assets/js/5a473bed.c195eeae.js deleted file mode 100644 index 6540f01f4..000000000 --- a/assets/js/5a473bed.c195eeae.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9686],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>s});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),c=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=c(e.components);return a.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,i=e.parentName,d=p(e,["components","mdxType","originalType","parentName"]),m=c(n),s=r,g=m["".concat(i,".").concat(s)]||m[s]||u[s]||l;return n?a.createElement(g,o(o({ref:t},d),{},{components:n})):a.createElement(g,o({ref:t},d))}));function s(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:r,o[1]=p;for(var c=2;c<l;c++)o[c]=n[c];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"},94429:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var a=n(87462),r=(n(67294),n(3905));const l={title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"mvc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,p={permalink:"/mvc-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-mvc/pull/404",date:"2023-10-07T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 7\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.175,hasTruncateMarker:!1,authors:[],frontMatter:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"mvc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/jdbc-retrospective"},nextItem:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",permalink:"/spring-test-isolation"}},i={authorsImageUrls:[]},c=[{value:"MVC \uad6c\ud604",id:"mvc-\uad6c\ud604",level:3},{value:"\uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30",id:"\uc560\ub108\ud14c\uc774\uc158-\uae30\ubc18-\ud504\ub808\uc784\uc6cc\ud06c-\ub9cc\ub4e4\uae30",level:3},{value:"Legacy MVC\uc640 @MVC \ud1b5\ud569",id:"legacy-mvc\uc640-mvc-\ud1b5\ud569",level:3},{value:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",level:3},{value:"\ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95",id:"\ucd94\uc0c1\uc801\uc778-\uac1c\ub150-\ud559\uc2b5-\ubc29\ubc95",level:3},{value:"\uc815\ub9ac",id:"\uc815\ub9ac",level:3}],d={toc:c};function u(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("admonition",{title:"PR \ub9c1\ud06c",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/404"},"https://github.com/woowacourse/jwp-dashboard-mvc/pull/404"),(0,r.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/465"},"https://github.com/woowacourse/jwp-dashboard-mvc/pull/465"),(0,r.kt)("br",{parentName:"p"}),"\n","3\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/580"},"https://github.com/woowacourse/jwp-dashboard-mvc/pull/580")," ")),(0,r.kt)("h3",{id:"mvc-\uad6c\ud604"},"MVC \uad6c\ud604"),(0,r.kt)("p",null,"Reflection\uc744 \uc774\uc6a9\ud558\uc5ec Spring MVC\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc758 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\uc558\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"MVC \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uad6c\ud604\ud558\uba74\uc11c \ub0b4\ubd80 \ub3d9\uc791 \uc6d0\ub9ac\ub97c \ud559\uc2b5\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc810\uc9c4\uc801\uc778 \ub9ac\ud329\ud1a0\ub9c1\uc744 \uacbd\ud5d8\ud55c\ub2e4.")),(0,r.kt)("p",null,"\ubbf8\uc158\uc758 \ubaa9\ud45c\uc640 \ub354\ubd88\uc5b4 \uac01 \ud074\ub798\uc2a4\ub4e4\uc774 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \uc801\uc808\ud788 \uac00\uc9c0\ub3c4\ub85d \ud558\uace0, \ud328\ud0a4\uc9c0\uc758 \uc758\uc874 \ubc29\ud5a5\uc744 \uace0\ubbfc\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc5d0 \uc911\uc810\uc744 \ub450\uc5c8\ub2e4. "),(0,r.kt)("h3",{id:"\uc560\ub108\ud14c\uc774\uc158-\uae30\ubc18-\ud504\ub808\uc784\uc6cc\ud06c-\ub9cc\ub4e4\uae30"},"\uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30"),(0,r.kt)("p",null,"\uae30\uc874 \ucf54\ub4dc\uc5d0 ManualHandlerMapping\uc774\ub77c\ub294 \uc11c\ube14\ub9bf\uc744 \uc9c1\uc811 \ub4f1\ub85d\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 HandlerMapping \ud074\ub798\uc2a4\uac00 \uc788\uc5c8\uace0, 1\ub2e8\uacc4\uc5d0\uc11c\ub294 \uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18\uc758 AnnotationHandlerMapping\uc744 \uad6c\ud604\ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 @Controller, @RequestMapping\uc744 Reflection\uc744 \uc774\uc6a9\ud558\uc5ec \uc2a4\uce94\ud558\uace0, \ud578\ub4e4\ub7ec \ub9e4\ud551\uc744 \ub4f1\ub85d\ud558\ub294 \ubd80\ubd84\uae4c\uc9c0 \uc9c4\ud589\ud574\uc57c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud14c\uc624\uac00 @GetMapping\uc774\ub098 @PostMapping \ubd80\ubd84\ub3c4 \uc9c4\ud589\ud558\uba74 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4\uace0 \ud574\uc11c \uac19\uc774 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ubbf8\uc158 \uc694\uad6c\uc0ac\ud56d\uc740 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ud074\ub798\uc2a4 \ub808\ubca8\uc5d0 \uc801\uc6a9\ub41c @RequestMapping\ub3c4 \ub3d9\uc791\ud558\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\uc558\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n AHM[AnnotationHandlerMapping] --\x3e AS[AnnotationScanner]\n\tAHM --\x3e HKG[HandlerKeyGenerator] --\x3e HMAP[HttpMappingAnnotationParser]"}),(0,r.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc740 Flow\ub85c Handler(\uc2e4\uc81c \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uba54\uc11c\ub4dc) \ub4f1\ub85d\uc744 \uc9c4\ud589\ud55c\ub2e4. "),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"@Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 \uc815\ubcf4\ub97c \uc2a4\uce94\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4. "),(0,r.kt)("li",{parentName:"ol"},"@Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 @RequestMapping\uc774 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\ub4e4\uc758 \uc815\ubcf4\ub97c \ubc18\ud658\ud55c\ub2e4. "),(0,r.kt)("li",{parentName:"ol"},"\uac01 \uba54\uc11c\ub4dc\ub4e4\uc744 \uc21c\ud68c\ud558\uba70 HandlerKey(uri + httpMethod \uc815\ubcf4)\uc640 HandlerExecution(\uc778\uc2a4\ud134\uc2a4 + \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc)\uc744 \uc0dd\uc131\ud558\uc5ec Map<HandlerKey, HandlerExecution>\uc5d0 \ucd94\uac00\ud55c\ub2e4. ")),(0,r.kt)("p",null,"AnnotationHandlerMapping\uc758 initialize \uba54\uc11c\ub4dc\uc5d0\uc11c Handler\ub97c \ub4f1\ub85d\ud55c\ub2e4. \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AnnotationHandlerMapping",title:"AnnotationHandlerMapping"},'public void initialize() {\n if (!initialized.compareAndSet(false, true)) {\n return;\n }\n\n final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();\n final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());\n for (final Method method : methods) {\n final ControllerInstance controller = controllers.get(method.getDeclaringClass());\n final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);\n final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);\n handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));\n }\n\n log.info("Initialized AnnotationHandlerMapping!");\n handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));\n}\n')),(0,r.kt)("h3",{id:"legacy-mvc\uc640-mvc-\ud1b5\ud569"},"Legacy MVC\uc640 @MVC \ud1b5\ud569"),(0,r.kt)("p",null,"2\ub2e8\uacc4\ub294 Legacy MVC\uc640 AnnotationHandlerMapping\uc744 \ud1b5\ud569\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc758 MVC\uc640 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc801\uc6a9\ub41c MVC \ub450 \uac1c\ub97c \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5b4\uc57c \ud5c0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub300\ub7b5\uc801\uc778 \ud750\ub984\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"DispatcherServlet.service(request, response) \ud638\ucd9c"),(0,r.kt)("li",{parentName:"ol"},"HandlerMappings\ub97c \ud1b5\ud574 \uc785\ub825\ubc1b\uc740 request\uc5d0 \ud574\ub2f9\ud558\ub294 Handler \uc870\ud68c"),(0,r.kt)("li",{parentName:"ol"},"HandlerAdapters\ub97c \ud1b5\ud574 Handler\ub97c \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub294 HandlerAdapter \uc870\ud68c"),(0,r.kt)("li",{parentName:"ol"},"HandlerAdapter\uc758.handle \uba54\uc11c\ub4dc \uc2e4\ud589"),(0,r.kt)("li",{parentName:"ol"},"View\uc758 render \ud638\ucd9c")),(0,r.kt)("mermaid",{value:"graph LR\n D[DispatcherServlet]\n D --\x3e HMS[HandlerMappings]\n D --\x3e HAS[HandlerAdapters]\n\n\tHMS --\x3e HandlerMapping\n\tsubgraph HandlerMapping\n\t\tdirection BT\n\t\tAHM[AnnotationHandlerMapping] --\x3e HM[HandlerMapping]\n\t\tMHM[ManualHandlerMapping] --\x3e HM\n\tend\n\n\tHAS --\x3e HandlerAdapter\n\tsubgraph HandlerAdapter\n\t\tdirection BT\n\t\tHEHA[HandlerExecutionHandlerAdapter] --\x3e HA[HandlerAdapter]\n\t\tCHA[ControllerHandlerAdapter] --\x3e HA\n\tend"}),(0,r.kt)("h3",{id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815"},"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815"),(0,r.kt)("p",null,"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4."),(0,r.kt)("mermaid",{value:"graph LR\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking"}),(0,r.kt)("p",null,"\ub0b4\uc6a9\uc774 \uae38\uc5b4\uc838\uc11c ",(0,r.kt)("a",{parentName:"p",href:"./web-application-evolution"},"\ub2e4\uc74c \ubb38\uc11c"),"\uc5d0 \uc815\ub9ac\ud588\ub2e4."),(0,r.kt)("h3",{id:"\ucd94\uc0c1\uc801\uc778-\uac1c\ub150-\ud559\uc2b5-\ubc29\ubc95"},"\ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95"),(0,r.kt)("p",null,"\uc9c1\uad00\uc801\uc774\uc9c0 \uc54a\uc740 \ucd94\uc0c1\uc801\uc778 \uac1c\ub150\uc744 \ud559\uc2b5\ud560 \ub54c\ub294 \uac1c\ub150\uc758 \uad6c\ud604\uc744 \ucc38\uace0\ud558\uba74 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \ud55c\ub2e4."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\uac1c\ub150"),(0,r.kt)("th",{parentName:"tr",align:null},"\uad6c\ud604"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OOP"),(0,r.kt)("td",{parentName:"tr",align:null},"Java")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"WAS"),(0,r.kt)("td",{parentName:"tr",align:null},"Tomcat, Jetty")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"IoC"),(0,r.kt)("td",{parentName:"tr",align:null},"Spring BeanFactory, Servlet Container, Framework")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"DI"),(0,r.kt)("td",{parentName:"tr",align:null},"Spring BeanFactory")))),(0,r.kt)("h3",{id:"\uc815\ub9ac"},"\uc815\ub9ac"),(0,r.kt)("p",null,"\uc9c0\uae08\uae4c\uc9c0 \uc2a4\ud504\ub9c1\uc758 DispatcherServlet\uc758 \ub3d9\uc791\uc744 \uc774\ub860\uc801\uc73c\ub85c\ub9cc \uc54c\uace0 \uc788\uc5c8\ub294\ub370, \uc2e4\uc81c\ub85c \uad6c\ud604\ud574 \ubcf4\ub2c8 \uc870\uae08 \ub354 \uc774\ud574\uac00 \uc798 \uac00\ub294 \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c \ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub8e8\uce74, \ub9ac\ubdf0\uc774\ub294 \ud5e4\ub098\uc600\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub9e4 \ub2e8\uacc4\ub9c8\ub2e4 \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0\ud574 \uc900 \ub8e8\uce74\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\uace0, \ud5e4\ub098\uc5d0\uac8c \uc774\uc0c1\ud55c \ub9ac\ubdf0\ub97c \ub9ce\uc774 \ub0a8\uae34 \uac83 \uac19\uc740\ub370 \uaf3c\uaf3c\ud788 \ubc18\uc601\ud574\uc918\uc11c \uac10\uc0ac\ud558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc624\ub7ab\ub3d9\uc548 \uae30\ub2e4\ub824\uc654\ub358 \ub808\ubca8 4 \ubbf8\uc158\uc774 \ud558\ub098\uc529 \ub9c8\ubb34\ub9ac \ub420 \ub54c \ub9c8\ub2e4 \uc544\uc26c\uc6c0\uc774 \ub0a8\ub294\ub2e4."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5a473bed.c534c8ad.js b/assets/js/5a473bed.c534c8ad.js new file mode 100644 index 000000000..46e5e912a --- /dev/null +++ b/assets/js/5a473bed.c534c8ad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9686],{52857:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var t=r(85893),a=r(3905);const l={title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"mvc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,o={permalink:"/mvc-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-mvc/pull/404",date:"2023-10-07T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 7\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.175,hasTruncateMarker:!1,authors:[],frontMatter:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"mvc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/jdbc-retrospective"},nextItem:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",permalink:"/spring-test-isolation"}},s={authorsImageUrls:[]},c=[{value:"MVC \uad6c\ud604",id:"mvc-\uad6c\ud604",level:3},{value:"\uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30",id:"\uc560\ub108\ud14c\uc774\uc158-\uae30\ubc18-\ud504\ub808\uc784\uc6cc\ud06c-\ub9cc\ub4e4\uae30",level:3},{value:"Legacy MVC\uc640 @MVC \ud1b5\ud569",id:"legacy-mvc\uc640-mvc-\ud1b5\ud569",level:3},{value:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",level:3},{value:"\ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95",id:"\ucd94\uc0c1\uc801\uc778-\uac1c\ub150-\ud559\uc2b5-\ubc29\ubc95",level:3},{value:"\uc815\ub9ac",id:"\uc815\ub9ac",level:3}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(n.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/404",children:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/404"}),(0,t.jsx)(n.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/465",children:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/465"}),(0,t.jsx)(n.br,{}),"\n","3\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/580",children:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/580"})]})}),"\n",(0,t.jsx)(n.h3,{id:"mvc-\uad6c\ud604",children:"MVC \uad6c\ud604"}),"\n",(0,t.jsxs)(n.p,{children:["Reflection\uc744 \uc774\uc6a9\ud558\uc5ec Spring MVC\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubbf8\uc158\uc758 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\uc558\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"MVC \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uad6c\ud604\ud558\uba74\uc11c \ub0b4\ubd80 \ub3d9\uc791 \uc6d0\ub9ac\ub97c \ud559\uc2b5\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uc810\uc9c4\uc801\uc778 \ub9ac\ud329\ud1a0\ub9c1\uc744 \uacbd\ud5d8\ud55c\ub2e4."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\ubbf8\uc158\uc758 \ubaa9\ud45c\uc640 \ub354\ubd88\uc5b4 \uac01 \ud074\ub798\uc2a4\ub4e4\uc774 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \uc801\uc808\ud788 \uac00\uc9c0\ub3c4\ub85d \ud558\uace0, \ud328\ud0a4\uc9c0\uc758 \uc758\uc874 \ubc29\ud5a5\uc744 \uace0\ubbfc\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc5d0 \uc911\uc810\uc744 \ub450\uc5c8\ub2e4."}),"\n",(0,t.jsx)(n.h3,{id:"\uc560\ub108\ud14c\uc774\uc158-\uae30\ubc18-\ud504\ub808\uc784\uc6cc\ud06c-\ub9cc\ub4e4\uae30",children:"\uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30"}),"\n",(0,t.jsxs)(n.p,{children:["\uae30\uc874 \ucf54\ub4dc\uc5d0 ManualHandlerMapping\uc774\ub77c\ub294 \uc11c\ube14\ub9bf\uc744 \uc9c1\uc811 \ub4f1\ub85d\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 HandlerMapping \ud074\ub798\uc2a4\uac00 \uc788\uc5c8\uace0, 1\ub2e8\uacc4\uc5d0\uc11c\ub294 \uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18\uc758 AnnotationHandlerMapping\uc744 \uad6c\ud604\ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 @Controller, @RequestMapping\uc744 Reflection\uc744 \uc774\uc6a9\ud558\uc5ec \uc2a4\uce94\ud558\uace0, \ud578\ub4e4\ub7ec \ub9e4\ud551\uc744 \ub4f1\ub85d\ud558\ub294 \ubd80\ubd84\uae4c\uc9c0 \uc9c4\ud589\ud574\uc57c \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud14c\uc624\uac00 @GetMapping\uc774\ub098 @PostMapping \ubd80\ubd84\ub3c4 \uc9c4\ud589\ud558\uba74 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4\uace0 \ud574\uc11c \uac19\uc774 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ubbf8\uc158 \uc694\uad6c\uc0ac\ud56d\uc740 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ud074\ub798\uc2a4 \ub808\ubca8\uc5d0 \uc801\uc6a9\ub41c @RequestMapping\ub3c4 \ub3d9\uc791\ud558\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\uc558\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph LR\n AHM[AnnotationHandlerMapping] --\x3e AS[AnnotationScanner]\n\tAHM --\x3e HKG[HandlerKeyGenerator] --\x3e HMAP[HttpMappingAnnotationParser]"}),"\n",(0,t.jsx)(n.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc740 Flow\ub85c Handler(\uc2e4\uc81c \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uba54\uc11c\ub4dc) \ub4f1\ub85d\uc744 \uc9c4\ud589\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"@Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 \uc815\ubcf4\ub97c \uc2a4\uce94\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"@Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 @RequestMapping\uc774 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\ub4e4\uc758 \uc815\ubcf4\ub97c \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.li,{children:["\uac01 \uba54\uc11c\ub4dc\ub4e4\uc744 \uc21c\ud68c\ud558\uba70 HandlerKey(uri + httpMethod \uc815\ubcf4)\uc640 HandlerExecution(\uc778\uc2a4\ud134\uc2a4 + \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc)\uc744 \uc0dd\uc131\ud558\uc5ec ",(0,t.jsx)(n.code,{children:"Map<HandlerKey, HandlerExecution>"}),"\uc5d0 \ucd94\uac00\ud55c\ub2e4."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"AnnotationHandlerMapping\uc758 initialize \uba54\uc11c\ub4dc\uc5d0\uc11c Handler\ub97c \ub4f1\ub85d\ud55c\ub2e4. \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=AnnotationHandlerMapping",children:'public void initialize() {\n if (!initialized.compareAndSet(false, true)) {\n return;\n }\n\n final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();\n final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());\n for (final Method method : methods) {\n final ControllerInstance controller = controllers.get(method.getDeclaringClass());\n final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);\n final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);\n handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));\n }\n\n log.info("Initialized AnnotationHandlerMapping!");\n handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"legacy-mvc\uc640-mvc-\ud1b5\ud569",children:"Legacy MVC\uc640 @MVC \ud1b5\ud569"}),"\n",(0,t.jsxs)(n.p,{children:["2\ub2e8\uacc4\ub294 Legacy MVC\uc640 AnnotationHandlerMapping\uc744 \ud1b5\ud569\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae30\uc874\uc758 MVC\uc640 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc801\uc6a9\ub41c MVC \ub450 \uac1c\ub97c \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5b4\uc57c \ud5c0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub300\ub7b5\uc801\uc778 \ud750\ub984\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"DispatcherServlet.service(request, response) \ud638\ucd9c"}),"\n",(0,t.jsx)(n.li,{children:"HandlerMappings\ub97c \ud1b5\ud574 \uc785\ub825\ubc1b\uc740 request\uc5d0 \ud574\ub2f9\ud558\ub294 Handler \uc870\ud68c"}),"\n",(0,t.jsx)(n.li,{children:"HandlerAdapters\ub97c \ud1b5\ud574 Handler\ub97c \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub294 HandlerAdapter \uc870\ud68c"}),"\n",(0,t.jsx)(n.li,{children:"HandlerAdapter\uc758.handle \uba54\uc11c\ub4dc \uc2e4\ud589"}),"\n",(0,t.jsx)(n.li,{children:"View\uc758 render \ud638\ucd9c"}),"\n"]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph LR\n D[DispatcherServlet]\n D --\x3e HMS[HandlerMappings]\n D --\x3e HAS[HandlerAdapters]\n\n\tHMS --\x3e HandlerMapping\n\tsubgraph HandlerMapping\n\t\tdirection BT\n\t\tAHM[AnnotationHandlerMapping] --\x3e HM[HandlerMapping]\n\t\tMHM[ManualHandlerMapping] --\x3e HM\n\tend\n\n\tHAS --\x3e HandlerAdapter\n\tsubgraph HandlerAdapter\n\t\tdirection BT\n\t\tHEHA[HandlerExecutionHandlerAdapter] --\x3e HA[HandlerAdapter]\n\t\tCHA[ControllerHandlerAdapter] --\x3e HA\n\tend"}),"\n",(0,t.jsx)(n.h3,{id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",children:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815"}),"\n",(0,t.jsxs)(n.p,{children:["\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph LR\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking"}),"\n",(0,t.jsxs)(n.p,{children:["\ub0b4\uc6a9\uc774 \uae38\uc5b4\uc838\uc11c ",(0,t.jsx)(n.a,{href:"./web-application-evolution",children:"\ub2e4\uc74c \ubb38\uc11c"}),"\uc5d0 \uc815\ub9ac\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ucd94\uc0c1\uc801\uc778-\uac1c\ub150-\ud559\uc2b5-\ubc29\ubc95",children:"\ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95"}),"\n",(0,t.jsx)(n.p,{children:"\uc9c1\uad00\uc801\uc774\uc9c0 \uc54a\uc740 \ucd94\uc0c1\uc801\uc778 \uac1c\ub150\uc744 \ud559\uc2b5\ud560 \ub54c\ub294 \uac1c\ub150\uc758 \uad6c\ud604\uc744 \ucc38\uace0\ud558\uba74 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"\uac1c\ub150"}),(0,t.jsx)(n.th,{children:"\uad6c\ud604"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"OOP"}),(0,t.jsx)(n.td,{children:"Java"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"WAS"}),(0,t.jsx)(n.td,{children:"Tomcat, Jetty"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"IoC"}),(0,t.jsx)(n.td,{children:"Spring BeanFactory, Servlet Container, Framework"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"DI"}),(0,t.jsx)(n.td,{children:"Spring BeanFactory"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"\uc815\ub9ac",children:"\uc815\ub9ac"}),"\n",(0,t.jsxs)(n.p,{children:["\uc9c0\uae08\uae4c\uc9c0 \uc2a4\ud504\ub9c1\uc758 DispatcherServlet\uc758 \ub3d9\uc791\uc744 \uc774\ub860\uc801\uc73c\ub85c\ub9cc \uc54c\uace0 \uc788\uc5c8\ub294\ub370, \uc2e4\uc81c\ub85c \uad6c\ud604\ud574 \ubcf4\ub2c8 \uc870\uae08 \ub354 \uc774\ud574\uac00 \uc798 \uac00\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c \ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub8e8\uce74, \ub9ac\ubdf0\uc774\ub294 \ud5e4\ub098\uc600\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub9e4 \ub2e8\uacc4\ub9c8\ub2e4 \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0\ud574 \uc900 \ub8e8\uce74\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\uace0, \ud5e4\ub098\uc5d0\uac8c \uc774\uc0c1\ud55c \ub9ac\ubdf0\ub97c \ub9ce\uc774 \ub0a8\uae34 \uac83 \uac19\uc740\ub370 \uaf3c\uaf3c\ud788 \ubc18\uc601\ud574\uc918\uc11c \uac10\uc0ac\ud558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc624\ub7ab\ub3d9\uc548 \uae30\ub2e4\ub824\uc654\ub358 \ub808\ubca8 4 \ubbf8\uc158\uc774 \ud558\ub098\uc529 \ub9c8\ubb34\ub9ac \ub420 \ub54c \ub9c8\ub2e4 \uc544\uc26c\uc6c0\uc774 \ub0a8\ub294\ub2e4."]})]})}function p(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>c});var t=r(67294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function l(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?l(Object(r),!0).forEach((function(n){a(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function o(e,n){if(null==e)return{};var r,t,a=function(e,n){if(null==e)return{};var r,t,a={},l=Object.keys(e);for(t=0;t<l.length;t++)r=l[t],n.indexOf(r)>=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(t=0;t<l.length;t++)r=l[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=t.createContext({}),c=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),h=c(r),u=a,x=h["".concat(s,".").concat(u)]||h[u]||d[u]||l;return r?t.createElement(x,i(i({ref:n},p),{},{components:r})):t.createElement(x,i({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/5a6c6934.8a355bab.js b/assets/js/5a6c6934.7bd0504f.js similarity index 59% rename from assets/js/5a6c6934.8a355bab.js rename to assets/js/5a6c6934.7bd0504f.js index bbe539f9a..1ee86eb83 100644 --- a/assets/js/5a6c6934.8a355bab.js +++ b/assets/js/5a6c6934.7bd0504f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5953],{48630:e=>{e.exports=JSON.parse('{"label":"DTO","permalink":"/tags/dto","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5953],{48630:e=>{e.exports=JSON.parse('{"label":"DTO","permalink":"/tags/dto","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/5c07bdab.54ff7247.js b/assets/js/5c07bdab.54ff7247.js new file mode 100644 index 000000000..7377a1d52 --- /dev/null +++ b/assets/js/5c07bdab.54ff7247.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6300],{50701:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=n(85893),a=n(3905);const o={title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"jdbc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,i={permalink:"/jdbc-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-jdbc/pull/267",date:"2023-10-10T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 10\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.83,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"jdbc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",permalink:"/refactoring-retrospective"},nextItem:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/mvc-retrospective"}},s={authorsImageUrls:[]},l=[{value:"Jdbc \uad6c\ud604",id:"jdbc-\uad6c\ud604",level:3},{value:"JdbcTemplate",id:"jdbctemplate",level:3},{value:"\ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9",id:"\ud2b8\ub79c\uc7ad\uc158-\uc801\uc6a9",level:3},{value:"\ub9c8\ubb34\ub9ac",id:"\ub9c8\ubb34\ub9ac",level:3}];function p(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",mermaid:"mermaid",p:"p",pre:"pre",ul:"ul",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,r.jsxs)(t.p,{children:["1\ub2e8\uacc4: ",(0,r.jsx)(t.a,{href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267",children:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267"}),(0,r.jsx)(t.br,{}),"\n","2\ub2e8\uacc4: ",(0,r.jsx)(t.a,{href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358",children:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358"}),(0,r.jsx)(t.br,{}),"\n","3\ub2e8\uacc4: ",(0,r.jsx)(t.a,{href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448",children:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448"}),(0,r.jsx)(t.br,{}),"\n","4\ub2e8\uacc4: ",(0,r.jsx)(t.a,{href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515",children:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515"})]})}),"\n",(0,r.jsx)(t.h3,{id:"jdbc-\uad6c\ud604",children:"Jdbc \uad6c\ud604"}),"\n",(0,r.jsxs)(t.p,{children:["\uc774\ubc88 \ubbf8\uc158\uc740 Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uace0, Transaction \uacbd\uacc4 \uc124\uc815\uacfc \ub3d9\uae30\ud654\ud558\ub294 \ubd80\ubd84\uc744 \uad6c\ud604\ud574 \ubcf4\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ubbf8\uc158 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"JDBC \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uba74\uc11c \uc911\ubcf5\uc744 \uc81c\uac70\ud558\ub294 \uc5f0\uc2b5\uc744 \ud55c\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\ub97c \ub192\uc778\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"\ucd5c\ub300\ud55c Java\uac00 \uc81c\uacf5\ud558\ub294 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud588\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"jdbctemplate",children:"JdbcTemplate"}),"\n",(0,r.jsxs)(t.p,{children:["JdbcTemplate\uc740 Connection\uc744 \uc774\uc6a9\ud558\uc5ec PreparedStatement\ub97c \uc0dd\uc131\ud558\ub294 \ubd80\ubd84, \uadf8\ub9ac\uace0 PreparedStatement\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ubd84\ub9ac\ud588\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc801\uc808\ud558\uac8c \uc801\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \ube44\uad50\uc801 \uac04\ub2e8\ud558\uac8c \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc608\uc804\uc5d0\ub3c4 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c ",(0,r.jsx)(t.a,{href:"./custom-jdbc-template",children:"JdbcTemplate\uc744 \uad6c\ud604"}),"\ud55c \uc801\uc774 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \uc790\uc6d0 \ud560\ub2f9\uacfc \ud574\uc81c \ubd80\ubd84\uc5d0 \ub300\ud55c \uc911\ubcf5\ub3c4 \uc81c\uac70\ud588\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",children:'public class JdbcTemplate {\n\n private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);\n\n private final DataSource dataSource;\n private final StatementCreator statementCreator;\n private final StatementExecutor statementExecutor;\n\n public JdbcTemplate(final DataSource dataSource) {\n this(dataSource, new StatementCreator(), new StatementExecutor());\n }\n\n JdbcTemplate(\n final DataSource dataSource,\n final StatementCreator statementCreator,\n final StatementExecutor statementExecutor\n ) {\n this.dataSource = dataSource;\n this.statementCreator = statementCreator;\n this.statementExecutor = statementExecutor;\n }\n\n private <T> T query(\n final String sql,\n final PreparedStatementCallback<T> preparedStatementCallback,\n final Object... parameters\n ) {\n final Connection connection = DataSourceUtils.getConnection(dataSource);\n try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {\n return preparedStatementCallback.execute(preparedStatement);\n } catch (final SQLException e) {\n log.error(e.getMessage(), e);\n throw new DataAccessException(e);\n } finally {\n DataSourceUtils.releaseConnection(connection, dataSource);\n }\n }\n\n public void update(final String sql, final Object... parameters) {\n query(sql, PreparedStatement::executeUpdate, parameters);\n }\n\n public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\n final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\n if (results.size() > 1) {\n throw new DataAccessException("2\uac1c \uc774\uc0c1\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.");\n }\n return results.stream().findAny();\n }\n\n public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\n return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\n }\n}\n'})}),"\n",(0,r.jsx)(t.h3,{id:"\ud2b8\ub79c\uc7ad\uc158-\uc801\uc6a9",children:"\ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9"}),"\n",(0,r.jsxs)(t.p,{children:["3, 4\ub2e8\uacc4\ub294 \uae30\uc874\uc758 \ucf54\ub4dc\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uace0 \ub05d\ub098\ub294 \ubd80\ubd84\uc778 \ud2b8\ub79c\uc7ad\uc158 \uacbd\uacc4\ub97c \uc124\uc815\ud558\uace0 ThreadLocal\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654(Transaction synchronization)\ub97c \uc801\uc6a9\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654\ub780 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uae30 \uc704\ud55c Connection \uac1d\uccb4\ub97c ThreadLocal\uacfc \uac19\uc740 \uacf5\uac04\uc5d0 \ub530\ub85c \uc800\uc7a5 \ud6c4, \ud544\uc694\ud560 \ub54c \uc800\uc7a5\ub41c Connection\uc744 \uac00\uc838\ub2e4 \uc0ac\uc6a9\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub294\ub370, ThreadLocal\uc5d0 Connection \uac1d\uccb4\uac00 \uc544\ub2cc, Connection \uac1d\uccb4\uc640 Transaction\uc774 \uc9c4\ud589 \uc911\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 flag\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \uc800\uc7a5\ud574\uc11c \uc0ac\uc6a9\ud558\ub3c4\ub85d \ud588\ub2e4."]}),"\n",(0,r.jsx)(t.mermaid,{value:"graph LR\n\tTransactionTemplate --\x3e TransactionManager\n\tTransactionManager --\x3e TransactionSynchronizationManager\n\tDataSourceUtils --\x3e TransactionSynchronizationManager\n\tJdbcTemplate --\x3e DataSourceUtils"}),"\n",(0,r.jsx)(t.h3,{id:"\ub9c8\ubb34\ub9ac",children:"\ub9c8\ubb34\ub9ac"}),"\n",(0,r.jsxs)(t.p,{children:["Jdbc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c AOP\ub098 Transactional\uc5d0 \ub300\ud55c \ud559\uc2b5 \ud14c\uc2a4\ud2b8\ub3c4 \uc9c4\ud589\ud558\uace0, \uc57d\uac04 \uc54c\ucc2c \ubbf8\uc158\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uaf3c\uaf3c\ud788 \ucf54\ub4dc\ub97c \ubd10\uc900 \ub9ac\ubdf0\uc5b4 \ud638\uc774 \uadf8\ub9ac\uace0 \uc5f0\ud734 \ub3d9\uc548 \uacc4\uc18d \ud2f0\ud0a4\ud0c0\uce74 \ud558\uba74\uc11c \uc7ac\ubc0c\uac8c \ub9ac\ubdf0\ud55c \ubbfc\ud2b8\uc5d0\uac8c \uac10\uc0ac\ud558\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud68c\uace0 \uc774\ub9cc \ub05d\ub0b4\uace0 \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud558\ub7ec\uac00\uc57c\uaca0\ub2e4. \ud83d\ude0a"]})]})}function d(e={}){const{wrapper:t}={...(0,a.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>l});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=l(n),b=a,m=u["".concat(s,".").concat(b)]||u[b]||p[b]||o;return n?r.createElement(m,c(c({ref:t},d),{},{components:n})):r.createElement(m,c({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/5c07bdab.7765e80c.js b/assets/js/5c07bdab.7765e80c.js deleted file mode 100644 index 6bb4c8b61..000000000 --- a/assets/js/5c07bdab.7765e80c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6300],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>d});var r=a(67294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function c(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function p(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),i=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):c(c({},t),e)),a},s=function(e){var t=i(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),m=i(a),d=n,b=m["".concat(l,".").concat(d)]||m[d]||u[d]||o;return a?r.createElement(b,c(c({ref:t},s),{},{components:a})):r.createElement(b,c({ref:t},s))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,c=new Array(o);c[0]=m;var p={};for(var l in t)hasOwnProperty.call(t,l)&&(p[l]=t[l]);p.originalType=e,p.mdxType="string"==typeof e?e:n,c[1]=p;for(var i=2;i<o;i++)c[i]=a[i];return r.createElement.apply(null,c)}return r.createElement.apply(null,a)}m.displayName="MDXCreateElement"},23438:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>p,toc:()=>i});var r=a(87462),n=(a(67294),a(3905));const o={title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"jdbc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,p={permalink:"/jdbc-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-jdbc/pull/267",date:"2023-10-10T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 10\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.83,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"jdbc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",permalink:"/refactoring-retrospective"},nextItem:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/mvc-retrospective"}},l={authorsImageUrls:[]},i=[{value:"Jdbc \uad6c\ud604",id:"jdbc-\uad6c\ud604",level:3},{value:"JdbcTemplate",id:"jdbctemplate",level:3},{value:"\ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9",id:"\ud2b8\ub79c\uc7ad\uc158-\uc801\uc6a9",level:3},{value:"\ub9c8\ubb34\ub9ac",id:"\ub9c8\ubb34\ub9ac",level:3}],s={toc:i};function u(e){let{components:t,...a}=e;return(0,n.kt)("wrapper",(0,r.Z)({},s,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("admonition",{title:"PR \ub9c1\ud06c",type:"note"},(0,n.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267"},"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267"),(0,n.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358"},"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358"),(0,n.kt)("br",{parentName:"p"}),"\n","3\ub2e8\uacc4: ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448"},"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448"),(0,n.kt)("br",{parentName:"p"}),"\n","4\ub2e8\uacc4: ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515"},"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515")," ")),(0,n.kt)("h3",{id:"jdbc-\uad6c\ud604"},"Jdbc \uad6c\ud604"),(0,n.kt)("p",null,"\uc774\ubc88 \ubbf8\uc158\uc740 Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uace0, Transaction \uacbd\uacc4 \uc124\uc815\uacfc \ub3d9\uae30\ud654\ud558\ub294 \ubd80\ubd84\uc744 \uad6c\ud604\ud574 \ubcf4\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"JDBC \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uba74\uc11c \uc911\ubcf5\uc744 \uc81c\uac70\ud558\ub294 \uc5f0\uc2b5\uc744 \ud55c\ub2e4."),(0,n.kt)("li",{parentName:"ul"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\ub97c \ub192\uc778\ub2e4.")),(0,n.kt)("p",null,"\ucd5c\ub300\ud55c Java\uac00 \uc81c\uacf5\ud558\ub294 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud588\ub2e4. "),(0,n.kt)("h3",{id:"jdbctemplate"},"JdbcTemplate"),(0,n.kt)("p",null,"JdbcTemplate\uc740 Connection\uc744 \uc774\uc6a9\ud558\uc5ec PreparedStatement\ub97c \uc0dd\uc131\ud558\ub294 \ubd80\ubd84, \uadf8\ub9ac\uace0 PreparedStatement\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ubd84\ub9ac\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc801\uc808\ud558\uac8c \uc801\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \ube44\uad50\uc801 \uac04\ub2e8\ud558\uac8c \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc608\uc804\uc5d0\ub3c4 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c ",(0,n.kt)("a",{parentName:"p",href:"./custom-jdbc-template"},"JdbcTemplate\uc744 \uad6c\ud604"),"\ud55c \uc801\uc774 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \uc790\uc6d0 \ud560\ub2f9\uacfc \ud574\uc81c \ubd80\ubd84\uc5d0 \ub300\ud55c \uc911\ubcf5\ub3c4 \uc81c\uac70\ud588\ub2e4. "),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},'public class JdbcTemplate {\n\n private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);\n\n private final DataSource dataSource;\n private final StatementCreator statementCreator;\n private final StatementExecutor statementExecutor;\n\n public JdbcTemplate(final DataSource dataSource) {\n this(dataSource, new StatementCreator(), new StatementExecutor());\n }\n\n JdbcTemplate(\n final DataSource dataSource,\n final StatementCreator statementCreator,\n final StatementExecutor statementExecutor\n ) {\n this.dataSource = dataSource;\n this.statementCreator = statementCreator;\n this.statementExecutor = statementExecutor;\n }\n\n private <T> T query(\n final String sql,\n final PreparedStatementCallback<T> preparedStatementCallback,\n final Object... parameters\n ) {\n final Connection connection = DataSourceUtils.getConnection(dataSource);\n try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {\n return preparedStatementCallback.execute(preparedStatement);\n } catch (final SQLException e) {\n log.error(e.getMessage(), e);\n throw new DataAccessException(e);\n } finally {\n DataSourceUtils.releaseConnection(connection, dataSource);\n }\n }\n\n public void update(final String sql, final Object... parameters) {\n query(sql, PreparedStatement::executeUpdate, parameters);\n }\n\n public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\n final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\n if (results.size() > 1) {\n throw new DataAccessException("2\uac1c \uc774\uc0c1\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.");\n }\n return results.stream().findAny();\n }\n\n public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\n return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\n }\n}\n')),(0,n.kt)("h3",{id:"\ud2b8\ub79c\uc7ad\uc158-\uc801\uc6a9"},"\ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9"),(0,n.kt)("p",null,"3, 4\ub2e8\uacc4\ub294 \uae30\uc874\uc758 \ucf54\ub4dc\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uace0 \ub05d\ub098\ub294 \ubd80\ubd84\uc778 \ud2b8\ub79c\uc7ad\uc158 \uacbd\uacc4\ub97c \uc124\uc815\ud558\uace0 ThreadLocal\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654(Transaction synchronization)\ub97c \uc801\uc6a9\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654\ub780 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uae30 \uc704\ud55c Connection \uac1d\uccb4\ub97c ThreadLocal\uacfc \uac19\uc740 \uacf5\uac04\uc5d0 \ub530\ub85c \uc800\uc7a5 \ud6c4, \ud544\uc694\ud560 \ub54c \uc800\uc7a5\ub41c Connection\uc744 \uac00\uc838\ub2e4 \uc0ac\uc6a9\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub294\ub370, ThreadLocal\uc5d0 Connection \uac1d\uccb4\uac00 \uc544\ub2cc, Connection \uac1d\uccb4\uc640 Transaction\uc774 \uc9c4\ud589 \uc911\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 flag\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \uc800\uc7a5\ud574\uc11c \uc0ac\uc6a9\ud558\ub3c4\ub85d \ud588\ub2e4. "),(0,n.kt)("mermaid",{value:"graph LR\n\tTransactionTemplate --\x3e TransactionManager\n\tTransactionManager --\x3e TransactionSynchronizationManager\n\tDataSourceUtils --\x3e TransactionSynchronizationManager\n\tJdbcTemplate --\x3e DataSourceUtils"}),(0,n.kt)("h3",{id:"\ub9c8\ubb34\ub9ac"},"\ub9c8\ubb34\ub9ac"),(0,n.kt)("p",null,"Jdbc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c AOP\ub098 Transactional\uc5d0 \ub300\ud55c \ud559\uc2b5 \ud14c\uc2a4\ud2b8\ub3c4 \uc9c4\ud589\ud558\uace0, \uc57d\uac04 \uc54c\ucc2c \ubbf8\uc158\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uaf3c\uaf3c\ud788 \ucf54\ub4dc\ub97c \ubd10\uc900 \ub9ac\ubdf0\uc5b4 \ud638\uc774 \uadf8\ub9ac\uace0 \uc5f0\ud734 \ub3d9\uc548 \uacc4\uc18d \ud2f0\ud0a4\ud0c0\uce74 \ud558\uba74\uc11c \uc7ac\ubc0c\uac8c \ub9ac\ubdf0\ud55c \ubbfc\ud2b8\uc5d0\uac8c \uac10\uc0ac\ud558\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud68c\uace0 \uc774\ub9cc \ub05d\ub0b4\uace0 \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud558\ub7ec\uac00\uc57c\uaca0\ub2e4. \ud83d\ude0a"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5c38e66e.502a685d.js b/assets/js/5c38e66e.a18cbc60.js similarity index 77% rename from assets/js/5c38e66e.502a685d.js rename to assets/js/5c38e66e.a18cbc60.js index d0a8c5043..020784c39 100644 --- a/assets/js/5c38e66e.502a685d.js +++ b/assets/js/5c38e66e.a18cbc60.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5521],{28638:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5521],{28638:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/5d4cff52.7e9bdf80.js b/assets/js/5d4cff52.7e9bdf80.js deleted file mode 100644 index 5f80569f8..000000000 --- a/assets/js/5d4cff52.7e9bdf80.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1252],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>s});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var i=a.createContext({}),c=function(e){var t=a.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},d=function(e){var t=c(e.components);return a.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,i=e.parentName,d=p(e,["components","mdxType","originalType","parentName"]),m=c(n),s=r,g=m["".concat(i,".").concat(s)]||m[s]||u[s]||l;return n?a.createElement(g,o(o({ref:t},d),{},{components:n})):a.createElement(g,o({ref:t},d))}));function s(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=m;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:r,o[1]=p;for(var c=2;c<l;c++)o[c]=n[c];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"},73688:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var a=n(87462),r=(n(67294),n(3905));const l={title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"mvc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,p={permalink:"/mvc-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-mvc/pull/404",date:"2023-10-07T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 7\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.175,hasTruncateMarker:!1,authors:[],frontMatter:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"mvc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/jdbc-retrospective"},nextItem:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",permalink:"/spring-test-isolation"}},i={authorsImageUrls:[]},c=[{value:"MVC \uad6c\ud604",id:"mvc-\uad6c\ud604",level:3},{value:"\uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30",id:"\uc560\ub108\ud14c\uc774\uc158-\uae30\ubc18-\ud504\ub808\uc784\uc6cc\ud06c-\ub9cc\ub4e4\uae30",level:3},{value:"Legacy MVC\uc640 @MVC \ud1b5\ud569",id:"legacy-mvc\uc640-mvc-\ud1b5\ud569",level:3},{value:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",level:3},{value:"\ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95",id:"\ucd94\uc0c1\uc801\uc778-\uac1c\ub150-\ud559\uc2b5-\ubc29\ubc95",level:3},{value:"\uc815\ub9ac",id:"\uc815\ub9ac",level:3}],d={toc:c};function u(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("admonition",{title:"PR \ub9c1\ud06c",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/404"},"https://github.com/woowacourse/jwp-dashboard-mvc/pull/404"),(0,r.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/465"},"https://github.com/woowacourse/jwp-dashboard-mvc/pull/465"),(0,r.kt)("br",{parentName:"p"}),"\n","3\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/580"},"https://github.com/woowacourse/jwp-dashboard-mvc/pull/580")," ")),(0,r.kt)("h3",{id:"mvc-\uad6c\ud604"},"MVC \uad6c\ud604"),(0,r.kt)("p",null,"Reflection\uc744 \uc774\uc6a9\ud558\uc5ec Spring MVC\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc758 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\uc558\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"MVC \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uad6c\ud604\ud558\uba74\uc11c \ub0b4\ubd80 \ub3d9\uc791 \uc6d0\ub9ac\ub97c \ud559\uc2b5\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc810\uc9c4\uc801\uc778 \ub9ac\ud329\ud1a0\ub9c1\uc744 \uacbd\ud5d8\ud55c\ub2e4.")),(0,r.kt)("p",null,"\ubbf8\uc158\uc758 \ubaa9\ud45c\uc640 \ub354\ubd88\uc5b4 \uac01 \ud074\ub798\uc2a4\ub4e4\uc774 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \uc801\uc808\ud788 \uac00\uc9c0\ub3c4\ub85d \ud558\uace0, \ud328\ud0a4\uc9c0\uc758 \uc758\uc874 \ubc29\ud5a5\uc744 \uace0\ubbfc\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc5d0 \uc911\uc810\uc744 \ub450\uc5c8\ub2e4. "),(0,r.kt)("h3",{id:"\uc560\ub108\ud14c\uc774\uc158-\uae30\ubc18-\ud504\ub808\uc784\uc6cc\ud06c-\ub9cc\ub4e4\uae30"},"\uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30"),(0,r.kt)("p",null,"\uae30\uc874 \ucf54\ub4dc\uc5d0 ManualHandlerMapping\uc774\ub77c\ub294 \uc11c\ube14\ub9bf\uc744 \uc9c1\uc811 \ub4f1\ub85d\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 HandlerMapping \ud074\ub798\uc2a4\uac00 \uc788\uc5c8\uace0, 1\ub2e8\uacc4\uc5d0\uc11c\ub294 \uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18\uc758 AnnotationHandlerMapping\uc744 \uad6c\ud604\ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 @Controller, @RequestMapping\uc744 Reflection\uc744 \uc774\uc6a9\ud558\uc5ec \uc2a4\uce94\ud558\uace0, \ud578\ub4e4\ub7ec \ub9e4\ud551\uc744 \ub4f1\ub85d\ud558\ub294 \ubd80\ubd84\uae4c\uc9c0 \uc9c4\ud589\ud574\uc57c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud14c\uc624\uac00 @GetMapping\uc774\ub098 @PostMapping \ubd80\ubd84\ub3c4 \uc9c4\ud589\ud558\uba74 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4\uace0 \ud574\uc11c \uac19\uc774 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ubbf8\uc158 \uc694\uad6c\uc0ac\ud56d\uc740 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ud074\ub798\uc2a4 \ub808\ubca8\uc5d0 \uc801\uc6a9\ub41c @RequestMapping\ub3c4 \ub3d9\uc791\ud558\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\uc558\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n AHM[AnnotationHandlerMapping] --\x3e AS[AnnotationScanner]\n\tAHM --\x3e HKG[HandlerKeyGenerator] --\x3e HMAP[HttpMappingAnnotationParser]"}),(0,r.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc740 Flow\ub85c Handler(\uc2e4\uc81c \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uba54\uc11c\ub4dc) \ub4f1\ub85d\uc744 \uc9c4\ud589\ud55c\ub2e4. "),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"@Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 \uc815\ubcf4\ub97c \uc2a4\uce94\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4. "),(0,r.kt)("li",{parentName:"ol"},"@Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 @RequestMapping\uc774 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\ub4e4\uc758 \uc815\ubcf4\ub97c \ubc18\ud658\ud55c\ub2e4. "),(0,r.kt)("li",{parentName:"ol"},"\uac01 \uba54\uc11c\ub4dc\ub4e4\uc744 \uc21c\ud68c\ud558\uba70 HandlerKey(uri + httpMethod \uc815\ubcf4)\uc640 HandlerExecution(\uc778\uc2a4\ud134\uc2a4 + \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc)\uc744 \uc0dd\uc131\ud558\uc5ec Map<HandlerKey, HandlerExecution>\uc5d0 \ucd94\uac00\ud55c\ub2e4. ")),(0,r.kt)("p",null,"AnnotationHandlerMapping\uc758 initialize \uba54\uc11c\ub4dc\uc5d0\uc11c Handler\ub97c \ub4f1\ub85d\ud55c\ub2e4. \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AnnotationHandlerMapping",title:"AnnotationHandlerMapping"},'public void initialize() {\n if (!initialized.compareAndSet(false, true)) {\n return;\n }\n\n final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();\n final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());\n for (final Method method : methods) {\n final ControllerInstance controller = controllers.get(method.getDeclaringClass());\n final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);\n final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);\n handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));\n }\n\n log.info("Initialized AnnotationHandlerMapping!");\n handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));\n}\n')),(0,r.kt)("h3",{id:"legacy-mvc\uc640-mvc-\ud1b5\ud569"},"Legacy MVC\uc640 @MVC \ud1b5\ud569"),(0,r.kt)("p",null,"2\ub2e8\uacc4\ub294 Legacy MVC\uc640 AnnotationHandlerMapping\uc744 \ud1b5\ud569\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc758 MVC\uc640 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc801\uc6a9\ub41c MVC \ub450 \uac1c\ub97c \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5b4\uc57c \ud5c0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub300\ub7b5\uc801\uc778 \ud750\ub984\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"DispatcherServlet.service(request, response) \ud638\ucd9c"),(0,r.kt)("li",{parentName:"ol"},"HandlerMappings\ub97c \ud1b5\ud574 \uc785\ub825\ubc1b\uc740 request\uc5d0 \ud574\ub2f9\ud558\ub294 Handler \uc870\ud68c"),(0,r.kt)("li",{parentName:"ol"},"HandlerAdapters\ub97c \ud1b5\ud574 Handler\ub97c \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub294 HandlerAdapter \uc870\ud68c"),(0,r.kt)("li",{parentName:"ol"},"HandlerAdapter\uc758.handle \uba54\uc11c\ub4dc \uc2e4\ud589"),(0,r.kt)("li",{parentName:"ol"},"View\uc758 render \ud638\ucd9c")),(0,r.kt)("mermaid",{value:"graph LR\n D[DispatcherServlet]\n D --\x3e HMS[HandlerMappings]\n D --\x3e HAS[HandlerAdapters]\n\n\tHMS --\x3e HandlerMapping\n\tsubgraph HandlerMapping\n\t\tdirection BT\n\t\tAHM[AnnotationHandlerMapping] --\x3e HM[HandlerMapping]\n\t\tMHM[ManualHandlerMapping] --\x3e HM\n\tend\n\n\tHAS --\x3e HandlerAdapter\n\tsubgraph HandlerAdapter\n\t\tdirection BT\n\t\tHEHA[HandlerExecutionHandlerAdapter] --\x3e HA[HandlerAdapter]\n\t\tCHA[ControllerHandlerAdapter] --\x3e HA\n\tend"}),(0,r.kt)("h3",{id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815"},"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815"),(0,r.kt)("p",null,"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4."),(0,r.kt)("mermaid",{value:"graph LR\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking"}),(0,r.kt)("p",null,"\ub0b4\uc6a9\uc774 \uae38\uc5b4\uc838\uc11c ",(0,r.kt)("a",{parentName:"p",href:"./web-application-evolution"},"\ub2e4\uc74c \ubb38\uc11c"),"\uc5d0 \uc815\ub9ac\ud588\ub2e4."),(0,r.kt)("h3",{id:"\ucd94\uc0c1\uc801\uc778-\uac1c\ub150-\ud559\uc2b5-\ubc29\ubc95"},"\ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95"),(0,r.kt)("p",null,"\uc9c1\uad00\uc801\uc774\uc9c0 \uc54a\uc740 \ucd94\uc0c1\uc801\uc778 \uac1c\ub150\uc744 \ud559\uc2b5\ud560 \ub54c\ub294 \uac1c\ub150\uc758 \uad6c\ud604\uc744 \ucc38\uace0\ud558\uba74 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \ud55c\ub2e4."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\uac1c\ub150"),(0,r.kt)("th",{parentName:"tr",align:null},"\uad6c\ud604"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"OOP"),(0,r.kt)("td",{parentName:"tr",align:null},"Java")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"WAS"),(0,r.kt)("td",{parentName:"tr",align:null},"Tomcat, Jetty")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"IoC"),(0,r.kt)("td",{parentName:"tr",align:null},"Spring BeanFactory, Servlet Container, Framework")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"DI"),(0,r.kt)("td",{parentName:"tr",align:null},"Spring BeanFactory")))),(0,r.kt)("h3",{id:"\uc815\ub9ac"},"\uc815\ub9ac"),(0,r.kt)("p",null,"\uc9c0\uae08\uae4c\uc9c0 \uc2a4\ud504\ub9c1\uc758 DispatcherServlet\uc758 \ub3d9\uc791\uc744 \uc774\ub860\uc801\uc73c\ub85c\ub9cc \uc54c\uace0 \uc788\uc5c8\ub294\ub370, \uc2e4\uc81c\ub85c \uad6c\ud604\ud574 \ubcf4\ub2c8 \uc870\uae08 \ub354 \uc774\ud574\uac00 \uc798 \uac00\ub294 \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c \ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub8e8\uce74, \ub9ac\ubdf0\uc774\ub294 \ud5e4\ub098\uc600\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub9e4 \ub2e8\uacc4\ub9c8\ub2e4 \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0\ud574 \uc900 \ub8e8\uce74\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\uace0, \ud5e4\ub098\uc5d0\uac8c \uc774\uc0c1\ud55c \ub9ac\ubdf0\ub97c \ub9ce\uc774 \ub0a8\uae34 \uac83 \uac19\uc740\ub370 \uaf3c\uaf3c\ud788 \ubc18\uc601\ud574\uc918\uc11c \uac10\uc0ac\ud558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc624\ub7ab\ub3d9\uc548 \uae30\ub2e4\ub824\uc654\ub358 \ub808\ubca8 4 \ubbf8\uc158\uc774 \ud558\ub098\uc529 \ub9c8\ubb34\ub9ac \ub420 \ub54c \ub9c8\ub2e4 \uc544\uc26c\uc6c0\uc774 \ub0a8\ub294\ub2e4."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5d4cff52.e443e998.js b/assets/js/5d4cff52.e443e998.js new file mode 100644 index 000000000..2dbaa2a07 --- /dev/null +++ b/assets/js/5d4cff52.e443e998.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1252],{88653:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var t=r(85893),a=r(3905);const l={title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"mvc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,o={permalink:"/mvc-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-mvc/pull/404",date:"2023-10-07T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 7\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.175,hasTruncateMarker:!1,authors:[],frontMatter:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"mvc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/jdbc-retrospective"},nextItem:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",permalink:"/spring-test-isolation"}},s={authorsImageUrls:[]},c=[{value:"MVC \uad6c\ud604",id:"mvc-\uad6c\ud604",level:3},{value:"\uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30",id:"\uc560\ub108\ud14c\uc774\uc158-\uae30\ubc18-\ud504\ub808\uc784\uc6cc\ud06c-\ub9cc\ub4e4\uae30",level:3},{value:"Legacy MVC\uc640 @MVC \ud1b5\ud569",id:"legacy-mvc\uc640-mvc-\ud1b5\ud569",level:3},{value:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",level:3},{value:"\ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95",id:"\ucd94\uc0c1\uc801\uc778-\uac1c\ub150-\ud559\uc2b5-\ubc29\ubc95",level:3},{value:"\uc815\ub9ac",id:"\uc815\ub9ac",level:3}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(n.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/404",children:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/404"}),(0,t.jsx)(n.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/465",children:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/465"}),(0,t.jsx)(n.br,{}),"\n","3\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/580",children:"https://github.com/woowacourse/jwp-dashboard-mvc/pull/580"})]})}),"\n",(0,t.jsx)(n.h3,{id:"mvc-\uad6c\ud604",children:"MVC \uad6c\ud604"}),"\n",(0,t.jsxs)(n.p,{children:["Reflection\uc744 \uc774\uc6a9\ud558\uc5ec Spring MVC\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubbf8\uc158\uc758 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\uc558\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"MVC \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uad6c\ud604\ud558\uba74\uc11c \ub0b4\ubd80 \ub3d9\uc791 \uc6d0\ub9ac\ub97c \ud559\uc2b5\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uc810\uc9c4\uc801\uc778 \ub9ac\ud329\ud1a0\ub9c1\uc744 \uacbd\ud5d8\ud55c\ub2e4."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\ubbf8\uc158\uc758 \ubaa9\ud45c\uc640 \ub354\ubd88\uc5b4 \uac01 \ud074\ub798\uc2a4\ub4e4\uc774 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \uc801\uc808\ud788 \uac00\uc9c0\ub3c4\ub85d \ud558\uace0, \ud328\ud0a4\uc9c0\uc758 \uc758\uc874 \ubc29\ud5a5\uc744 \uace0\ubbfc\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc5d0 \uc911\uc810\uc744 \ub450\uc5c8\ub2e4."}),"\n",(0,t.jsx)(n.h3,{id:"\uc560\ub108\ud14c\uc774\uc158-\uae30\ubc18-\ud504\ub808\uc784\uc6cc\ud06c-\ub9cc\ub4e4\uae30",children:"\uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30"}),"\n",(0,t.jsxs)(n.p,{children:["\uae30\uc874 \ucf54\ub4dc\uc5d0 ManualHandlerMapping\uc774\ub77c\ub294 \uc11c\ube14\ub9bf\uc744 \uc9c1\uc811 \ub4f1\ub85d\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 HandlerMapping \ud074\ub798\uc2a4\uac00 \uc788\uc5c8\uace0, 1\ub2e8\uacc4\uc5d0\uc11c\ub294 \uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18\uc758 AnnotationHandlerMapping\uc744 \uad6c\ud604\ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 @Controller, @RequestMapping\uc744 Reflection\uc744 \uc774\uc6a9\ud558\uc5ec \uc2a4\uce94\ud558\uace0, \ud578\ub4e4\ub7ec \ub9e4\ud551\uc744 \ub4f1\ub85d\ud558\ub294 \ubd80\ubd84\uae4c\uc9c0 \uc9c4\ud589\ud574\uc57c \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud14c\uc624\uac00 @GetMapping\uc774\ub098 @PostMapping \ubd80\ubd84\ub3c4 \uc9c4\ud589\ud558\uba74 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4\uace0 \ud574\uc11c \uac19\uc774 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ubbf8\uc158 \uc694\uad6c\uc0ac\ud56d\uc740 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ud074\ub798\uc2a4 \ub808\ubca8\uc5d0 \uc801\uc6a9\ub41c @RequestMapping\ub3c4 \ub3d9\uc791\ud558\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\uc558\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph LR\n AHM[AnnotationHandlerMapping] --\x3e AS[AnnotationScanner]\n\tAHM --\x3e HKG[HandlerKeyGenerator] --\x3e HMAP[HttpMappingAnnotationParser]"}),"\n",(0,t.jsx)(n.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc740 Flow\ub85c Handler(\uc2e4\uc81c \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uba54\uc11c\ub4dc) \ub4f1\ub85d\uc744 \uc9c4\ud589\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"@Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 \uc815\ubcf4\ub97c \uc2a4\uce94\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"@Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 @RequestMapping\uc774 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\ub4e4\uc758 \uc815\ubcf4\ub97c \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.li,{children:["\uac01 \uba54\uc11c\ub4dc\ub4e4\uc744 \uc21c\ud68c\ud558\uba70 HandlerKey(uri + httpMethod \uc815\ubcf4)\uc640 HandlerExecution(\uc778\uc2a4\ud134\uc2a4 + \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc)\uc744 \uc0dd\uc131\ud558\uc5ec ",(0,t.jsx)(n.code,{children:"Map<HandlerKey, HandlerExecution>"}),"\uc5d0 \ucd94\uac00\ud55c\ub2e4."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"AnnotationHandlerMapping\uc758 initialize \uba54\uc11c\ub4dc\uc5d0\uc11c Handler\ub97c \ub4f1\ub85d\ud55c\ub2e4. \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=AnnotationHandlerMapping",children:'public void initialize() {\n if (!initialized.compareAndSet(false, true)) {\n return;\n }\n\n final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();\n final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());\n for (final Method method : methods) {\n final ControllerInstance controller = controllers.get(method.getDeclaringClass());\n final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);\n final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);\n handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));\n }\n\n log.info("Initialized AnnotationHandlerMapping!");\n handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"legacy-mvc\uc640-mvc-\ud1b5\ud569",children:"Legacy MVC\uc640 @MVC \ud1b5\ud569"}),"\n",(0,t.jsxs)(n.p,{children:["2\ub2e8\uacc4\ub294 Legacy MVC\uc640 AnnotationHandlerMapping\uc744 \ud1b5\ud569\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae30\uc874\uc758 MVC\uc640 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc801\uc6a9\ub41c MVC \ub450 \uac1c\ub97c \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5b4\uc57c \ud5c0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub300\ub7b5\uc801\uc778 \ud750\ub984\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"DispatcherServlet.service(request, response) \ud638\ucd9c"}),"\n",(0,t.jsx)(n.li,{children:"HandlerMappings\ub97c \ud1b5\ud574 \uc785\ub825\ubc1b\uc740 request\uc5d0 \ud574\ub2f9\ud558\ub294 Handler \uc870\ud68c"}),"\n",(0,t.jsx)(n.li,{children:"HandlerAdapters\ub97c \ud1b5\ud574 Handler\ub97c \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub294 HandlerAdapter \uc870\ud68c"}),"\n",(0,t.jsx)(n.li,{children:"HandlerAdapter\uc758.handle \uba54\uc11c\ub4dc \uc2e4\ud589"}),"\n",(0,t.jsx)(n.li,{children:"View\uc758 render \ud638\ucd9c"}),"\n"]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph LR\n D[DispatcherServlet]\n D --\x3e HMS[HandlerMappings]\n D --\x3e HAS[HandlerAdapters]\n\n\tHMS --\x3e HandlerMapping\n\tsubgraph HandlerMapping\n\t\tdirection BT\n\t\tAHM[AnnotationHandlerMapping] --\x3e HM[HandlerMapping]\n\t\tMHM[ManualHandlerMapping] --\x3e HM\n\tend\n\n\tHAS --\x3e HandlerAdapter\n\tsubgraph HandlerAdapter\n\t\tdirection BT\n\t\tHEHA[HandlerExecutionHandlerAdapter] --\x3e HA[HandlerAdapter]\n\t\tCHA[ControllerHandlerAdapter] --\x3e HA\n\tend"}),"\n",(0,t.jsx)(n.h3,{id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",children:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815"}),"\n",(0,t.jsxs)(n.p,{children:["\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph LR\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking"}),"\n",(0,t.jsxs)(n.p,{children:["\ub0b4\uc6a9\uc774 \uae38\uc5b4\uc838\uc11c ",(0,t.jsx)(n.a,{href:"./web-application-evolution",children:"\ub2e4\uc74c \ubb38\uc11c"}),"\uc5d0 \uc815\ub9ac\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ucd94\uc0c1\uc801\uc778-\uac1c\ub150-\ud559\uc2b5-\ubc29\ubc95",children:"\ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95"}),"\n",(0,t.jsx)(n.p,{children:"\uc9c1\uad00\uc801\uc774\uc9c0 \uc54a\uc740 \ucd94\uc0c1\uc801\uc778 \uac1c\ub150\uc744 \ud559\uc2b5\ud560 \ub54c\ub294 \uac1c\ub150\uc758 \uad6c\ud604\uc744 \ucc38\uace0\ud558\uba74 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"\uac1c\ub150"}),(0,t.jsx)(n.th,{children:"\uad6c\ud604"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"OOP"}),(0,t.jsx)(n.td,{children:"Java"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"WAS"}),(0,t.jsx)(n.td,{children:"Tomcat, Jetty"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"IoC"}),(0,t.jsx)(n.td,{children:"Spring BeanFactory, Servlet Container, Framework"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"DI"}),(0,t.jsx)(n.td,{children:"Spring BeanFactory"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"\uc815\ub9ac",children:"\uc815\ub9ac"}),"\n",(0,t.jsxs)(n.p,{children:["\uc9c0\uae08\uae4c\uc9c0 \uc2a4\ud504\ub9c1\uc758 DispatcherServlet\uc758 \ub3d9\uc791\uc744 \uc774\ub860\uc801\uc73c\ub85c\ub9cc \uc54c\uace0 \uc788\uc5c8\ub294\ub370, \uc2e4\uc81c\ub85c \uad6c\ud604\ud574 \ubcf4\ub2c8 \uc870\uae08 \ub354 \uc774\ud574\uac00 \uc798 \uac00\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c \ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub8e8\uce74, \ub9ac\ubdf0\uc774\ub294 \ud5e4\ub098\uc600\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub9e4 \ub2e8\uacc4\ub9c8\ub2e4 \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0\ud574 \uc900 \ub8e8\uce74\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\uace0, \ud5e4\ub098\uc5d0\uac8c \uc774\uc0c1\ud55c \ub9ac\ubdf0\ub97c \ub9ce\uc774 \ub0a8\uae34 \uac83 \uac19\uc740\ub370 \uaf3c\uaf3c\ud788 \ubc18\uc601\ud574\uc918\uc11c \uac10\uc0ac\ud558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc624\ub7ab\ub3d9\uc548 \uae30\ub2e4\ub824\uc654\ub358 \ub808\ubca8 4 \ubbf8\uc158\uc774 \ud558\ub098\uc529 \ub9c8\ubb34\ub9ac \ub420 \ub54c \ub9c8\ub2e4 \uc544\uc26c\uc6c0\uc774 \ub0a8\ub294\ub2e4."]})]})}function p(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>c});var t=r(67294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function l(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?l(Object(r),!0).forEach((function(n){a(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function o(e,n){if(null==e)return{};var r,t,a=function(e,n){if(null==e)return{};var r,t,a={},l=Object.keys(e);for(t=0;t<l.length;t++)r=l[t],n.indexOf(r)>=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(t=0;t<l.length;t++)r=l[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=t.createContext({}),c=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,l=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),h=c(r),u=a,x=h["".concat(s,".").concat(u)]||h[u]||d[u]||l;return r?t.createElement(x,i(i({ref:n},p),{},{components:r})):t.createElement(x,i({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/5e95c892.3b35697a.js b/assets/js/5e95c892.3b35697a.js new file mode 100644 index 000000000..d2a7bb5d8 --- /dev/null +++ b/assets/js/5e95c892.3b35697a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9661],{41892:(e,s,r)=>{r.r(s),r.d(s,{default:()=>l});r(67294);var t=r(86010),u=r(10833),a=r(35281),c=r(18790),n=r(58207),i=r(85893);function l(e){return(0,i.jsx)(u.FG,{className:(0,t.Z)(a.k.wrapper.docsPages),children:(0,i.jsx)(n.Z,{children:(0,c.H)(e.route.routes)})})}}}]); \ No newline at end of file diff --git a/assets/js/5ffd2c10.ccf10cdb.js b/assets/js/5ffd2c10.6cc0bd94.js similarity index 79% rename from assets/js/5ffd2c10.ccf10cdb.js rename to assets/js/5ffd2c10.6cc0bd94.js index 4224d3cf6..f0c74b018 100644 --- a/assets/js/5ffd2c10.ccf10cdb.js +++ b/assets/js/5ffd2c10.6cc0bd94.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2100],{86515:e=>{e.exports=JSON.parse('{"label":"JPA","permalink":"/docs/tags/jpa","allTagsPath":"/docs/tags","count":1,"items":[{"id":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551","title":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","description":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","permalink":"/docs/jpa/key"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2100],{86515:e=>{e.exports=JSON.parse('{"label":"JPA","permalink":"/docs/tags/jpa","allTagsPath":"/docs/tags","count":1,"items":[{"id":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551","title":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","description":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","permalink":"/docs/jpa/key"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/601.bd9904a4.js b/assets/js/601.bd9904a4.js new file mode 100644 index 000000000..2d9c9941a --- /dev/null +++ b/assets/js/601.bd9904a4.js @@ -0,0 +1,3429 @@ +"use strict"; +exports.id = 601; +exports.ids = [601]; +exports.modules = { + +/***/ 43601: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(93799); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17967); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27484); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 2], $V1 = [1, 3], $V2 = [1, 4], $V3 = [2, 4], $V4 = [1, 9], $V5 = [1, 11], $V6 = [1, 13], $V7 = [1, 14], $V8 = [1, 16], $V9 = [1, 17], $Va = [1, 18], $Vb = [1, 24], $Vc = [1, 25], $Vd = [1, 26], $Ve = [1, 27], $Vf = [1, 28], $Vg = [1, 29], $Vh = [1, 30], $Vi = [1, 31], $Vj = [1, 32], $Vk = [1, 33], $Vl = [1, 34], $Vm = [1, 35], $Vn = [1, 36], $Vo = [1, 37], $Vp = [1, 38], $Vq = [1, 39], $Vr = [1, 41], $Vs = [1, 42], $Vt = [1, 43], $Vu = [1, 44], $Vv = [1, 45], $Vw = [1, 46], $Vx = [1, 4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 47, 48, 49, 50, 52, 53, 54, 59, 60, 61, 62, 70], $Vy = [4, 5, 16, 50, 52, 53], $Vz = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VA = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 49, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VB = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 48, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VC = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 47, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VD = [68, 69, 70], $VE = [1, 120]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "SPACE": 4, "NEWLINE": 5, "SD": 6, "document": 7, "line": 8, "statement": 9, "box_section": 10, "box_line": 11, "participant_statement": 12, "create": 13, "box": 14, "restOfLine": 15, "end": 16, "signal": 17, "autonumber": 18, "NUM": 19, "off": 20, "activate": 21, "actor": 22, "deactivate": 23, "note_statement": 24, "links_statement": 25, "link_statement": 26, "properties_statement": 27, "details_statement": 28, "title": 29, "legacy_title": 30, "acc_title": 31, "acc_title_value": 32, "acc_descr": 33, "acc_descr_value": 34, "acc_descr_multiline_value": 35, "loop": 36, "rect": 37, "opt": 38, "alt": 39, "else_sections": 40, "par": 41, "par_sections": 42, "par_over": 43, "critical": 44, "option_sections": 45, "break": 46, "option": 47, "and": 48, "else": 49, "participant": 50, "AS": 51, "participant_actor": 52, "destroy": 53, "note": 54, "placement": 55, "text2": 56, "over": 57, "actor_pair": 58, "links": 59, "link": 60, "properties": 61, "details": 62, "spaceList": 63, ",": 64, "left_of": 65, "right_of": 66, "signaltype": 67, "+": 68, "-": 69, "ACTOR": 70, "SOLID_OPEN_ARROW": 71, "DOTTED_OPEN_ARROW": 72, "SOLID_ARROW": 73, "DOTTED_ARROW": 74, "SOLID_CROSS": 75, "DOTTED_CROSS": 76, "SOLID_POINT": 77, "DOTTED_POINT": 78, "TXT": 79, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SPACE", 5: "NEWLINE", 6: "SD", 13: "create", 14: "box", 15: "restOfLine", 16: "end", 18: "autonumber", 19: "NUM", 20: "off", 21: "activate", 23: "deactivate", 29: "title", 30: "legacy_title", 31: "acc_title", 32: "acc_title_value", 33: "acc_descr", 34: "acc_descr_value", 35: "acc_descr_multiline_value", 36: "loop", 37: "rect", 38: "opt", 39: "alt", 41: "par", 43: "par_over", 44: "critical", 46: "break", 47: "option", 48: "and", 49: "else", 50: "participant", 51: "AS", 52: "participant_actor", 53: "destroy", 54: "note", 57: "over", 59: "links", 60: "link", 61: "properties", 62: "details", 64: ",", 65: "left_of", 66: "right_of", 68: "+", 69: "-", 70: "ACTOR", 71: "SOLID_OPEN_ARROW", 72: "DOTTED_OPEN_ARROW", 73: "SOLID_ARROW", 74: "DOTTED_ARROW", 75: "SOLID_CROSS", 76: "DOTTED_CROSS", 77: "SOLID_POINT", 78: "DOTTED_POINT", 79: "TXT" }, + productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [8, 1], [8, 1], [10, 0], [10, 2], [11, 2], [11, 1], [11, 1], [9, 1], [9, 2], [9, 4], [9, 2], [9, 4], [9, 3], [9, 3], [9, 2], [9, 3], [9, 3], [9, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [45, 1], [45, 4], [42, 1], [42, 4], [40, 1], [40, 4], [12, 5], [12, 3], [12, 5], [12, 3], [12, 3], [24, 4], [24, 4], [25, 3], [26, 3], [27, 3], [28, 3], [63, 2], [63, 1], [58, 3], [58, 1], [55, 1], [55, 1], [17, 5], [17, 5], [17, 4], [22, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [56, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.apply($$[$0]); + return $$[$0]; + case 4: + case 9: + this.$ = []; + break; + case 5: + case 10: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 6: + case 7: + case 11: + case 12: + this.$ = $$[$0]; + break; + case 8: + case 13: + this.$ = []; + break; + case 15: + $$[$0].type = "createParticipant"; + this.$ = $$[$0]; + break; + case 16: + $$[$0 - 1].unshift({ type: "boxStart", boxData: yy.parseBoxData($$[$0 - 2]) }); + $$[$0 - 1].push({ type: "boxEnd", boxText: $$[$0 - 2] }); + this.$ = $$[$0 - 1]; + break; + case 18: + this.$ = { type: "sequenceIndex", sequenceIndex: Number($$[$0 - 2]), sequenceIndexStep: Number($$[$0 - 1]), sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER }; + break; + case 19: + this.$ = { type: "sequenceIndex", sequenceIndex: Number($$[$0 - 1]), sequenceIndexStep: 1, sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER }; + break; + case 20: + this.$ = { type: "sequenceIndex", sequenceVisible: false, signalType: yy.LINETYPE.AUTONUMBER }; + break; + case 21: + this.$ = { type: "sequenceIndex", sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER }; + break; + case 22: + this.$ = { type: "activeStart", signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0 - 1] }; + break; + case 23: + this.$ = { type: "activeEnd", signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0 - 1] }; + break; + case 29: + yy.setDiagramTitle($$[$0].substring(6)); + this.$ = $$[$0].substring(6); + break; + case 30: + yy.setDiagramTitle($$[$0].substring(7)); + this.$ = $$[$0].substring(7); + break; + case 31: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 32: + case 33: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 34: + $$[$0 - 1].unshift({ type: "loopStart", loopText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.LOOP_START }); + $$[$0 - 1].push({ type: "loopEnd", loopText: $$[$0 - 2], signalType: yy.LINETYPE.LOOP_END }); + this.$ = $$[$0 - 1]; + break; + case 35: + $$[$0 - 1].unshift({ type: "rectStart", color: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.RECT_START }); + $$[$0 - 1].push({ type: "rectEnd", color: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.RECT_END }); + this.$ = $$[$0 - 1]; + break; + case 36: + $$[$0 - 1].unshift({ type: "optStart", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.OPT_START }); + $$[$0 - 1].push({ type: "optEnd", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.OPT_END }); + this.$ = $$[$0 - 1]; + break; + case 37: + $$[$0 - 1].unshift({ type: "altStart", altText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.ALT_START }); + $$[$0 - 1].push({ type: "altEnd", signalType: yy.LINETYPE.ALT_END }); + this.$ = $$[$0 - 1]; + break; + case 38: + $$[$0 - 1].unshift({ type: "parStart", parText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.PAR_START }); + $$[$0 - 1].push({ type: "parEnd", signalType: yy.LINETYPE.PAR_END }); + this.$ = $$[$0 - 1]; + break; + case 39: + $$[$0 - 1].unshift({ type: "parStart", parText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.PAR_OVER_START }); + $$[$0 - 1].push({ type: "parEnd", signalType: yy.LINETYPE.PAR_END }); + this.$ = $$[$0 - 1]; + break; + case 40: + $$[$0 - 1].unshift({ type: "criticalStart", criticalText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.CRITICAL_START }); + $$[$0 - 1].push({ type: "criticalEnd", signalType: yy.LINETYPE.CRITICAL_END }); + this.$ = $$[$0 - 1]; + break; + case 41: + $$[$0 - 1].unshift({ type: "breakStart", breakText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.BREAK_START }); + $$[$0 - 1].push({ type: "breakEnd", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.BREAK_END }); + this.$ = $$[$0 - 1]; + break; + case 43: + this.$ = $$[$0 - 3].concat([{ type: "option", optionText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.CRITICAL_OPTION }, $$[$0]]); + break; + case 45: + this.$ = $$[$0 - 3].concat([{ type: "and", parText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.PAR_AND }, $$[$0]]); + break; + case 47: + this.$ = $$[$0 - 3].concat([{ type: "else", altText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.ALT_ELSE }, $$[$0]]); + break; + case 48: + $$[$0 - 3].draw = "participant"; + $$[$0 - 3].type = "addParticipant"; + $$[$0 - 3].description = yy.parseMessage($$[$0 - 1]); + this.$ = $$[$0 - 3]; + break; + case 49: + $$[$0 - 1].draw = "participant"; + $$[$0 - 1].type = "addParticipant"; + this.$ = $$[$0 - 1]; + break; + case 50: + $$[$0 - 3].draw = "actor"; + $$[$0 - 3].type = "addParticipant"; + $$[$0 - 3].description = yy.parseMessage($$[$0 - 1]); + this.$ = $$[$0 - 3]; + break; + case 51: + $$[$0 - 1].draw = "actor"; + $$[$0 - 1].type = "addParticipant"; + this.$ = $$[$0 - 1]; + break; + case 52: + $$[$0 - 1].type = "destroyParticipant"; + this.$ = $$[$0 - 1]; + break; + case 53: + this.$ = [$$[$0 - 1], { type: "addNote", placement: $$[$0 - 2], actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 54: + $$[$0 - 2] = [].concat($$[$0 - 1], $$[$0 - 1]).slice(0, 2); + $$[$0 - 2][0] = $$[$0 - 2][0].actor; + $$[$0 - 2][1] = $$[$0 - 2][1].actor; + this.$ = [$$[$0 - 1], { type: "addNote", placement: yy.PLACEMENT.OVER, actor: $$[$0 - 2].slice(0, 2), text: $$[$0] }]; + break; + case 55: + this.$ = [$$[$0 - 1], { type: "addLinks", actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 56: + this.$ = [$$[$0 - 1], { type: "addALink", actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 57: + this.$ = [$$[$0 - 1], { type: "addProperties", actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 58: + this.$ = [$$[$0 - 1], { type: "addDetails", actor: $$[$0 - 1].actor, text: $$[$0] }]; + break; + case 61: + this.$ = [$$[$0 - 2], $$[$0]]; + break; + case 62: + this.$ = $$[$0]; + break; + case 63: + this.$ = yy.PLACEMENT.LEFTOF; + break; + case 64: + this.$ = yy.PLACEMENT.RIGHTOF; + break; + case 65: + this.$ = [ + $$[$0 - 4], + $$[$0 - 1], + { type: "addMessage", from: $$[$0 - 4].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 3], msg: $$[$0], activate: true }, + { type: "activeStart", signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0 - 1] } + ]; + break; + case 66: + this.$ = [ + $$[$0 - 4], + $$[$0 - 1], + { type: "addMessage", from: $$[$0 - 4].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 3], msg: $$[$0] }, + { type: "activeEnd", signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0 - 4] } + ]; + break; + case 67: + this.$ = [$$[$0 - 3], $$[$0 - 1], { type: "addMessage", from: $$[$0 - 3].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 2], msg: $$[$0] }]; + break; + case 68: + this.$ = { type: "addParticipant", actor: $$[$0] }; + break; + case 69: + this.$ = yy.LINETYPE.SOLID_OPEN; + break; + case 70: + this.$ = yy.LINETYPE.DOTTED_OPEN; + break; + case 71: + this.$ = yy.LINETYPE.SOLID; + break; + case 72: + this.$ = yy.LINETYPE.DOTTED; + break; + case 73: + this.$ = yy.LINETYPE.SOLID_CROSS; + break; + case 74: + this.$ = yy.LINETYPE.DOTTED_CROSS; + break; + case 75: + this.$ = yy.LINETYPE.SOLID_POINT; + break; + case 76: + this.$ = yy.LINETYPE.DOTTED_POINT; + break; + case 77: + this.$ = yy.parseMessage($$[$0].trim().substring(1)); + break; + } + }, + table: [{ 3: 1, 4: $V0, 5: $V1, 6: $V2 }, { 1: [3] }, { 3: 5, 4: $V0, 5: $V1, 6: $V2 }, { 3: 6, 4: $V0, 5: $V1, 6: $V2 }, o([1, 4, 5, 13, 14, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 50, 52, 53, 54, 59, 60, 61, 62, 70], $V3, { 7: 7 }), { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3], 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, o($Vx, [2, 5]), { 9: 47, 12: 12, 13: $V6, 14: $V7, 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, o($Vx, [2, 7]), o($Vx, [2, 8]), o($Vx, [2, 14]), { 12: 48, 50: $Vo, 52: $Vp, 53: $Vq }, { 15: [1, 49] }, { 5: [1, 50] }, { 5: [1, 53], 19: [1, 51], 20: [1, 52] }, { 22: 54, 70: $Vw }, { 22: 55, 70: $Vw }, { 5: [1, 56] }, { 5: [1, 57] }, { 5: [1, 58] }, { 5: [1, 59] }, { 5: [1, 60] }, o($Vx, [2, 29]), o($Vx, [2, 30]), { 32: [1, 61] }, { 34: [1, 62] }, o($Vx, [2, 33]), { 15: [1, 63] }, { 15: [1, 64] }, { 15: [1, 65] }, { 15: [1, 66] }, { 15: [1, 67] }, { 15: [1, 68] }, { 15: [1, 69] }, { 15: [1, 70] }, { 22: 71, 70: $Vw }, { 22: 72, 70: $Vw }, { 22: 73, 70: $Vw }, { 67: 74, 71: [1, 75], 72: [1, 76], 73: [1, 77], 74: [1, 78], 75: [1, 79], 76: [1, 80], 77: [1, 81], 78: [1, 82] }, { 55: 83, 57: [1, 84], 65: [1, 85], 66: [1, 86] }, { 22: 87, 70: $Vw }, { 22: 88, 70: $Vw }, { 22: 89, 70: $Vw }, { 22: 90, 70: $Vw }, o([5, 51, 64, 71, 72, 73, 74, 75, 76, 77, 78, 79], [2, 68]), o($Vx, [2, 6]), o($Vx, [2, 15]), o($Vy, [2, 9], { 10: 91 }), o($Vx, [2, 17]), { 5: [1, 93], 19: [1, 92] }, { 5: [1, 94] }, o($Vx, [2, 21]), { 5: [1, 95] }, { 5: [1, 96] }, o($Vx, [2, 24]), o($Vx, [2, 25]), o($Vx, [2, 26]), o($Vx, [2, 27]), o($Vx, [2, 28]), o($Vx, [2, 31]), o($Vx, [2, 32]), o($Vz, $V3, { 7: 97 }), o($Vz, $V3, { 7: 98 }), o($Vz, $V3, { 7: 99 }), o($VA, $V3, { 40: 100, 7: 101 }), o($VB, $V3, { 42: 102, 7: 103 }), o($VB, $V3, { 7: 103, 42: 104 }), o($VC, $V3, { 45: 105, 7: 106 }), o($Vz, $V3, { 7: 107 }), { 5: [1, 109], 51: [1, 108] }, { 5: [1, 111], 51: [1, 110] }, { 5: [1, 112] }, { 22: 115, 68: [1, 113], 69: [1, 114], 70: $Vw }, o($VD, [2, 69]), o($VD, [2, 70]), o($VD, [2, 71]), o($VD, [2, 72]), o($VD, [2, 73]), o($VD, [2, 74]), o($VD, [2, 75]), o($VD, [2, 76]), { 22: 116, 70: $Vw }, { 22: 118, 58: 117, 70: $Vw }, { 70: [2, 63] }, { 70: [2, 64] }, { 56: 119, 79: $VE }, { 56: 121, 79: $VE }, { 56: 122, 79: $VE }, { 56: 123, 79: $VE }, { 4: [1, 126], 5: [1, 128], 11: 125, 12: 127, 16: [1, 124], 50: $Vo, 52: $Vp, 53: $Vq }, { 5: [1, 129] }, o($Vx, [2, 19]), o($Vx, [2, 20]), o($Vx, [2, 22]), o($Vx, [2, 23]), { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 130], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 131], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 132], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 133] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 46], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 49: [1, 134], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 135] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 44], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 48: [1, 136], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 137] }, { 16: [1, 138] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 42], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 47: [1, 139], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 140], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 15: [1, 141] }, o($Vx, [2, 49]), { 15: [1, 142] }, o($Vx, [2, 51]), o($Vx, [2, 52]), { 22: 143, 70: $Vw }, { 22: 144, 70: $Vw }, { 56: 145, 79: $VE }, { 56: 146, 79: $VE }, { 56: 147, 79: $VE }, { 64: [1, 148], 79: [2, 62] }, { 5: [2, 55] }, { 5: [2, 77] }, { 5: [2, 56] }, { 5: [2, 57] }, { 5: [2, 58] }, o($Vx, [2, 16]), o($Vy, [2, 10]), { 12: 149, 50: $Vo, 52: $Vp, 53: $Vq }, o($Vy, [2, 12]), o($Vy, [2, 13]), o($Vx, [2, 18]), o($Vx, [2, 34]), o($Vx, [2, 35]), o($Vx, [2, 36]), o($Vx, [2, 37]), { 15: [1, 150] }, o($Vx, [2, 38]), { 15: [1, 151] }, o($Vx, [2, 39]), o($Vx, [2, 40]), { 15: [1, 152] }, o($Vx, [2, 41]), { 5: [1, 153] }, { 5: [1, 154] }, { 56: 155, 79: $VE }, { 56: 156, 79: $VE }, { 5: [2, 67] }, { 5: [2, 53] }, { 5: [2, 54] }, { 22: 157, 70: $Vw }, o($Vy, [2, 11]), o($VA, $V3, { 7: 101, 40: 158 }), o($VB, $V3, { 7: 103, 42: 159 }), o($VC, $V3, { 7: 106, 45: 160 }), o($Vx, [2, 48]), o($Vx, [2, 50]), { 5: [2, 65] }, { 5: [2, 66] }, { 79: [2, 61] }, { 16: [2, 47] }, { 16: [2, 45] }, { 16: [2, 43] }], + defaultActions: { 5: [2, 1], 6: [2, 2], 85: [2, 63], 86: [2, 64], 119: [2, 55], 120: [2, 77], 121: [2, 56], 122: [2, 57], 123: [2, 58], 145: [2, 67], 146: [2, 53], 147: [2, 54], 155: [2, 65], 156: [2, 66], 157: [2, 61], 158: [2, 47], 159: [2, 45], 160: [2, 43] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 5; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + return 19; + case 7: + this.begin("LINE"); + return 14; + case 8: + this.begin("ID"); + return 50; + case 9: + this.begin("ID"); + return 52; + case 10: + return 13; + case 11: + this.begin("ID"); + return 53; + case 12: + yy_.yytext = yy_.yytext.trim(); + this.begin("ALIAS"); + return 70; + case 13: + this.popState(); + this.popState(); + this.begin("LINE"); + return 51; + case 14: + this.popState(); + this.popState(); + return 5; + case 15: + this.begin("LINE"); + return 36; + case 16: + this.begin("LINE"); + return 37; + case 17: + this.begin("LINE"); + return 38; + case 18: + this.begin("LINE"); + return 39; + case 19: + this.begin("LINE"); + return 49; + case 20: + this.begin("LINE"); + return 41; + case 21: + this.begin("LINE"); + return 43; + case 22: + this.begin("LINE"); + return 48; + case 23: + this.begin("LINE"); + return 44; + case 24: + this.begin("LINE"); + return 47; + case 25: + this.begin("LINE"); + return 46; + case 26: + this.popState(); + return 15; + case 27: + return 16; + case 28: + return 65; + case 29: + return 66; + case 30: + return 59; + case 31: + return 60; + case 32: + return 61; + case 33: + return 62; + case 34: + return 57; + case 35: + return 54; + case 36: + this.begin("ID"); + return 21; + case 37: + this.begin("ID"); + return 23; + case 38: + return 29; + case 39: + return 30; + case 40: + this.begin("acc_title"); + return 31; + case 41: + this.popState(); + return "acc_title_value"; + case 42: + this.begin("acc_descr"); + return 33; + case 43: + this.popState(); + return "acc_descr_value"; + case 44: + this.begin("acc_descr_multiline"); + break; + case 45: + this.popState(); + break; + case 46: + return "acc_descr_multiline_value"; + case 47: + return 6; + case 48: + return 18; + case 49: + return 20; + case 50: + return 64; + case 51: + return 5; + case 52: + yy_.yytext = yy_.yytext.trim(); + return 70; + case 53: + return 73; + case 54: + return 74; + case 55: + return 71; + case 56: + return 72; + case 57: + return 75; + case 58: + return 76; + case 59: + return 77; + case 60: + return 78; + case 61: + return 79; + case 62: + return 68; + case 63: + return 69; + case 64: + return 5; + case 65: + return "INVALID"; + } + }, + rules: [/^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:((?!\n)\s)+)/i, /^(?:#[^\n]*)/i, /^(?:%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[0-9]+(?=[ \n]+))/i, /^(?:box\b)/i, /^(?:participant\b)/i, /^(?:actor\b)/i, /^(?:create\b)/i, /^(?:destroy\b)/i, /^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i, /^(?:as\b)/i, /^(?:(?:))/i, /^(?:loop\b)/i, /^(?:rect\b)/i, /^(?:opt\b)/i, /^(?:alt\b)/i, /^(?:else\b)/i, /^(?:par\b)/i, /^(?:par_over\b)/i, /^(?:and\b)/i, /^(?:critical\b)/i, /^(?:option\b)/i, /^(?:break\b)/i, /^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i, /^(?:end\b)/i, /^(?:left of\b)/i, /^(?:right of\b)/i, /^(?:links\b)/i, /^(?:link\b)/i, /^(?:properties\b)/i, /^(?:details\b)/i, /^(?:over\b)/i, /^(?:note\b)/i, /^(?:activate\b)/i, /^(?:deactivate\b)/i, /^(?:title\s[^#\n;]+)/i, /^(?:title:\s[^#\n;]+)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:sequenceDiagram\b)/i, /^(?:autonumber\b)/i, /^(?:off\b)/i, /^(?:,)/i, /^(?:;)/i, /^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i, /^(?:->>)/i, /^(?:-->>)/i, /^(?:->)/i, /^(?:-->)/i, /^(?:-[x])/i, /^(?:--[x])/i, /^(?:-[\)])/i, /^(?:--[\)])/i, /^(?::(?:(?:no)?wrap)?[^#\n;]+)/i, /^(?:\+)/i, /^(?:-)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "acc_descr_multiline": { "rules": [45, 46], "inclusive": false }, "acc_descr": { "rules": [43], "inclusive": false }, "acc_title": { "rules": [41], "inclusive": false }, "ID": { "rules": [2, 3, 12], "inclusive": false }, "ALIAS": { "rules": [2, 3, 13, 14], "inclusive": false }, "LINE": { "rules": [2, 3, 26], "inclusive": false }, "INITIAL": { "rules": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +let prevActor = void 0; +let actors = {}; +let createdActors = {}; +let destroyedActors = {}; +let boxes = []; +let messages = []; +let sequenceNumbersEnabled = false; +let wrapEnabled; +let currentBox = void 0; +let lastCreated = void 0; +let lastDestroyed = void 0; +const addBox = function(data) { + boxes.push({ + name: data.text, + wrap: data.wrap === void 0 && autoWrap() || !!data.wrap, + fill: data.color, + actorKeys: [] + }); + currentBox = boxes.slice(-1)[0]; +}; +const addActor = function(id, name, description, type) { + let assignedBox = currentBox; + const old = actors[id]; + if (old) { + if (currentBox && old.box && currentBox !== old.box) { + throw new Error( + "A same participant should only be defined in one Box: " + old.name + " can't be in '" + old.box.name + "' and in '" + currentBox.name + "' at the same time." + ); + } + assignedBox = old.box ? old.box : currentBox; + old.box = assignedBox; + if (old && name === old.name && description == null) { + return; + } + } + if (description == null || description.text == null) { + description = { text: name, wrap: null, type }; + } + if (type == null || description.text == null) { + description = { text: name, wrap: null, type }; + } + actors[id] = { + box: assignedBox, + name, + description: description.text, + wrap: description.wrap === void 0 && autoWrap() || !!description.wrap, + prevActor, + links: {}, + properties: {}, + actorCnt: null, + rectData: null, + type: type || "participant" + }; + if (prevActor && actors[prevActor]) { + actors[prevActor].nextActor = id; + } + if (currentBox) { + currentBox.actorKeys.push(id); + } + prevActor = id; +}; +const activationCount = (part) => { + let i; + let count = 0; + for (i = 0; i < messages.length; i++) { + if (messages[i].type === LINETYPE.ACTIVE_START && messages[i].from.actor === part) { + count++; + } + if (messages[i].type === LINETYPE.ACTIVE_END && messages[i].from.actor === part) { + count--; + } + } + return count; +}; +const addMessage = function(idFrom, idTo, message, answer) { + messages.push({ + from: idFrom, + to: idTo, + message: message.text, + wrap: message.wrap === void 0 && autoWrap() || !!message.wrap, + answer + }); +}; +const addSignal = function(idFrom, idTo, message = { text: void 0, wrap: void 0 }, messageType, activate = false) { + if (messageType === LINETYPE.ACTIVE_END) { + const cnt = activationCount(idFrom.actor); + if (cnt < 1) { + let error = new Error("Trying to inactivate an inactive participant (" + idFrom.actor + ")"); + error.hash = { + text: "->>-", + token: "->>-", + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["'ACTIVE_PARTICIPANT'"] + }; + throw error; + } + } + messages.push({ + from: idFrom, + to: idTo, + message: message.text, + wrap: message.wrap === void 0 && autoWrap() || !!message.wrap, + type: messageType, + activate + }); + return true; +}; +const hasAtLeastOneBox = function() { + return boxes.length > 0; +}; +const hasAtLeastOneBoxWithTitle = function() { + return boxes.some((b) => b.name); +}; +const getMessages = function() { + return messages; +}; +const getBoxes = function() { + return boxes; +}; +const getActors = function() { + return actors; +}; +const getCreatedActors = function() { + return createdActors; +}; +const getDestroyedActors = function() { + return destroyedActors; +}; +const getActor = function(id) { + return actors[id]; +}; +const getActorKeys = function() { + return Object.keys(actors); +}; +const enableSequenceNumbers = function() { + sequenceNumbersEnabled = true; +}; +const disableSequenceNumbers = function() { + sequenceNumbersEnabled = false; +}; +const showSequenceNumbers = () => sequenceNumbersEnabled; +const setWrap = function(wrapSetting) { + wrapEnabled = wrapSetting; +}; +const autoWrap = () => { + if (wrapEnabled !== void 0) { + return wrapEnabled; + } + return (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().sequence.wrap; +}; +const clear = function() { + actors = {}; + createdActors = {}; + destroyedActors = {}; + boxes = []; + messages = []; + sequenceNumbersEnabled = false; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.t)(); +}; +const parseMessage = function(str) { + const _str = str.trim(); + const message = { + text: _str.replace(/^:?(?:no)?wrap:/, "").trim(), + wrap: _str.match(/^:?wrap:/) !== null ? true : _str.match(/^:?nowrap:/) !== null ? false : void 0 + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("parseMessage:", message); + return message; +}; +const parseBoxData = function(str) { + const match = str.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/); + let color = match != null && match[1] ? match[1].trim() : "transparent"; + let title = match != null && match[2] ? match[2].trim() : void 0; + if (window && window.CSS) { + if (!window.CSS.supports("color", color)) { + color = "transparent"; + title = str.trim(); + } + } else { + const style = new Option().style; + style.color = color; + if (style.color !== color) { + color = "transparent"; + title = str.trim(); + } + } + const boxData = { + color, + text: title !== void 0 ? (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.d)(title.replace(/^:?(?:no)?wrap:/, ""), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()) : void 0, + wrap: title !== void 0 ? title.match(/^:?wrap:/) !== null ? true : title.match(/^:?nowrap:/) !== null ? false : void 0 : void 0 + }; + return boxData; +}; +const LINETYPE = { + SOLID: 0, + DOTTED: 1, + NOTE: 2, + SOLID_CROSS: 3, + DOTTED_CROSS: 4, + SOLID_OPEN: 5, + DOTTED_OPEN: 6, + LOOP_START: 10, + LOOP_END: 11, + ALT_START: 12, + ALT_ELSE: 13, + ALT_END: 14, + OPT_START: 15, + OPT_END: 16, + ACTIVE_START: 17, + ACTIVE_END: 18, + PAR_START: 19, + PAR_AND: 20, + PAR_END: 21, + RECT_START: 22, + RECT_END: 23, + SOLID_POINT: 24, + DOTTED_POINT: 25, + AUTONUMBER: 26, + CRITICAL_START: 27, + CRITICAL_OPTION: 28, + CRITICAL_END: 29, + BREAK_START: 30, + BREAK_END: 31, + PAR_OVER_START: 32 +}; +const ARROWTYPE = { + FILLED: 0, + OPEN: 1 +}; +const PLACEMENT = { + LEFTOF: 0, + RIGHTOF: 1, + OVER: 2 +}; +const addNote = function(actor, placement, message) { + ({ + actor, + placement, + message: message.text, + wrap: message.wrap === void 0 && autoWrap() || !!message.wrap + }); + const actors2 = [].concat(actor, actor); + messages.push({ + from: actors2[0], + to: actors2[1], + message: message.text, + wrap: message.wrap === void 0 && autoWrap() || !!message.wrap, + type: LINETYPE.NOTE, + placement + }); +}; +const addLinks = function(actorId, text) { + const actor = getActor(actorId); + try { + let sanitizedText = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.d)(text.text, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + sanitizedText = sanitizedText.replace(/&/g, "&"); + sanitizedText = sanitizedText.replace(/=/g, "="); + const links = JSON.parse(sanitizedText); + insertLinks(actor, links); + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing actor link text", e); + } +}; +const addALink = function(actorId, text) { + const actor = getActor(actorId); + try { + const links = {}; + let sanitizedText = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.d)(text.text, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + var sep = sanitizedText.indexOf("@"); + sanitizedText = sanitizedText.replace(/&/g, "&"); + sanitizedText = sanitizedText.replace(/=/g, "="); + var label = sanitizedText.slice(0, sep - 1).trim(); + var link = sanitizedText.slice(sep + 1).trim(); + links[label] = link; + insertLinks(actor, links); + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing actor link text", e); + } +}; +function insertLinks(actor, links) { + if (actor.links == null) { + actor.links = links; + } else { + for (let key in links) { + actor.links[key] = links[key]; + } + } +} +const addProperties = function(actorId, text) { + const actor = getActor(actorId); + try { + let sanitizedText = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.d)(text.text, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + const properties = JSON.parse(sanitizedText); + insertProperties(actor, properties); + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing actor properties text", e); + } +}; +function insertProperties(actor, properties) { + if (actor.properties == null) { + actor.properties = properties; + } else { + for (let key in properties) { + actor.properties[key] = properties[key]; + } + } +} +function boxEnd() { + currentBox = void 0; +} +const addDetails = function(actorId, text) { + const actor = getActor(actorId); + const elem = document.getElementById(text.text); + try { + const text2 = elem.innerHTML; + const details = JSON.parse(text2); + if (details["properties"]) { + insertProperties(actor, details["properties"]); + } + if (details["links"]) { + insertLinks(actor, details["links"]); + } + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing actor details text", e); + } +}; +const getActorProperty = function(actor, key) { + if (actor !== void 0 && actor.properties !== void 0) { + return actor.properties[key]; + } + return void 0; +}; +const apply = function(param) { + if (Array.isArray(param)) { + param.forEach(function(item) { + apply(item); + }); + } else { + switch (param.type) { + case "sequenceIndex": + messages.push({ + from: void 0, + to: void 0, + message: { + start: param.sequenceIndex, + step: param.sequenceIndexStep, + visible: param.sequenceVisible + }, + wrap: false, + type: param.signalType + }); + break; + case "addParticipant": + addActor(param.actor, param.actor, param.description, param.draw); + break; + case "createParticipant": + if (actors[param.actor]) { + throw new Error( + "It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior" + ); + } + lastCreated = param.actor; + addActor(param.actor, param.actor, param.description, param.draw); + createdActors[param.actor] = messages.length; + break; + case "destroyParticipant": + lastDestroyed = param.actor; + destroyedActors[param.actor] = messages.length; + break; + case "activeStart": + addSignal(param.actor, void 0, void 0, param.signalType); + break; + case "activeEnd": + addSignal(param.actor, void 0, void 0, param.signalType); + break; + case "addNote": + addNote(param.actor, param.placement, param.text); + break; + case "addLinks": + addLinks(param.actor, param.text); + break; + case "addALink": + addALink(param.actor, param.text); + break; + case "addProperties": + addProperties(param.actor, param.text); + break; + case "addDetails": + addDetails(param.actor, param.text); + break; + case "addMessage": + if (lastCreated) { + if (param.to !== lastCreated) { + throw new Error( + "The created participant " + lastCreated + " does not have an associated creating message after its declaration. Please check the sequence diagram." + ); + } else { + lastCreated = void 0; + } + } else if (lastDestroyed) { + if (param.to !== lastDestroyed && param.from !== lastDestroyed) { + throw new Error( + "The destroyed participant " + lastDestroyed + " does not have an associated destroying message after its declaration. Please check the sequence diagram." + ); + } else { + lastDestroyed = void 0; + } + } + addSignal(param.from, param.to, param.msg, param.signalType, param.activate); + break; + case "boxStart": + addBox(param.boxData); + break; + case "boxEnd": + boxEnd(); + break; + case "loopStart": + addSignal(void 0, void 0, param.loopText, param.signalType); + break; + case "loopEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "rectStart": + addSignal(void 0, void 0, param.color, param.signalType); + break; + case "rectEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "optStart": + addSignal(void 0, void 0, param.optText, param.signalType); + break; + case "optEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "altStart": + addSignal(void 0, void 0, param.altText, param.signalType); + break; + case "else": + addSignal(void 0, void 0, param.altText, param.signalType); + break; + case "altEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "setAccTitle": + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.s)(param.text); + break; + case "parStart": + addSignal(void 0, void 0, param.parText, param.signalType); + break; + case "and": + addSignal(void 0, void 0, param.parText, param.signalType); + break; + case "parEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "criticalStart": + addSignal(void 0, void 0, param.criticalText, param.signalType); + break; + case "option": + addSignal(void 0, void 0, param.optionText, param.signalType); + break; + case "criticalEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + case "breakStart": + addSignal(void 0, void 0, param.breakText, param.signalType); + break; + case "breakEnd": + addSignal(void 0, void 0, void 0, param.signalType); + break; + } + } +}; +const db = { + addActor, + addMessage, + addSignal, + addLinks, + addDetails, + addProperties, + autoWrap, + setWrap, + enableSequenceNumbers, + disableSequenceNumbers, + showSequenceNumbers, + getMessages, + getActors, + getCreatedActors, + getDestroyedActors, + getActor, + getActorKeys, + getActorProperty, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.g, + getBoxes, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.r, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.q, + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().sequence, + clear, + parseMessage, + parseBoxData, + LINETYPE, + ARROWTYPE, + PLACEMENT, + addNote, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.s, + apply, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.b, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.a, + hasAtLeastOneBox, + hasAtLeastOneBoxWithTitle +}; +const getStyles = (options) => `.actor { + stroke: ${options.actorBorder}; + fill: ${options.actorBkg}; + } + + text.actor > tspan { + fill: ${options.actorTextColor}; + stroke: none; + } + + .actor-line { + stroke: ${options.actorLineColor}; + } + + .messageLine0 { + stroke-width: 1.5; + stroke-dasharray: none; + stroke: ${options.signalColor}; + } + + .messageLine1 { + stroke-width: 1.5; + stroke-dasharray: 2, 2; + stroke: ${options.signalColor}; + } + + #arrowhead path { + fill: ${options.signalColor}; + stroke: ${options.signalColor}; + } + + .sequenceNumber { + fill: ${options.sequenceNumberColor}; + } + + #sequencenumber { + fill: ${options.signalColor}; + } + + #crosshead path { + fill: ${options.signalColor}; + stroke: ${options.signalColor}; + } + + .messageText { + fill: ${options.signalTextColor}; + stroke: none; + } + + .labelBox { + stroke: ${options.labelBoxBorderColor}; + fill: ${options.labelBoxBkgColor}; + } + + .labelText, .labelText > tspan { + fill: ${options.labelTextColor}; + stroke: none; + } + + .loopText, .loopText > tspan { + fill: ${options.loopTextColor}; + stroke: none; + } + + .loopLine { + stroke-width: 2px; + stroke-dasharray: 2, 2; + stroke: ${options.labelBoxBorderColor}; + fill: ${options.labelBoxBorderColor}; + } + + .note { + //stroke: #decc93; + stroke: ${options.noteBorderColor}; + fill: ${options.noteBkgColor}; + } + + .noteText, .noteText > tspan { + fill: ${options.noteTextColor}; + stroke: none; + } + + .activation0 { + fill: ${options.activationBkgColor}; + stroke: ${options.activationBorderColor}; + } + + .activation1 { + fill: ${options.activationBkgColor}; + stroke: ${options.activationBorderColor}; + } + + .activation2 { + fill: ${options.activationBkgColor}; + stroke: ${options.activationBorderColor}; + } + + .actorPopupMenu { + position: absolute; + } + + .actorPopupMenuPanel { + position: absolute; + fill: ${options.actorBkg}; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4)); +} + .actor-man line { + stroke: ${options.actorBorder}; + fill: ${options.actorBkg}; + } + .actor-man circle, line { + stroke: ${options.actorBorder}; + fill: ${options.actorBkg}; + stroke-width: 2px; + } +`; +const styles = getStyles; +const ACTOR_TYPE_WIDTH = 18 * 2; +const drawRect = function(elem, rectData) { + return (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.d)(elem, rectData); +}; +const addPopupInteraction = (id, actorCnt2) => { + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.F)(() => { + const arr = document.querySelectorAll(id); + if (arr.length === 0) { + return; + } + arr[0].addEventListener("mouseover", function() { + popupMenuUpFunc("actor" + actorCnt2 + "_popup"); + }); + arr[0].addEventListener("mouseout", function() { + popupMenuDownFunc("actor" + actorCnt2 + "_popup"); + }); + }); +}; +const drawPopup = function(elem, actor, minMenuWidth, textAttrs, forceMenus) { + if (actor.links === void 0 || actor.links === null || Object.keys(actor.links).length === 0) { + return { height: 0, width: 0 }; + } + const links = actor.links; + const actorCnt2 = actor.actorCnt; + const rectData = actor.rectData; + var displayValue = "none"; + if (forceMenus) { + displayValue = "block !important"; + } + const g = elem.append("g"); + g.attr("id", "actor" + actorCnt2 + "_popup"); + g.attr("class", "actorPopupMenu"); + g.attr("display", displayValue); + addPopupInteraction("#actor" + actorCnt2 + "_popup", actorCnt2); + var actorClass = ""; + if (rectData.class !== void 0) { + actorClass = " " + rectData.class; + } + let menuWidth = rectData.width > minMenuWidth ? rectData.width : minMenuWidth; + const rectElem = g.append("rect"); + rectElem.attr("class", "actorPopupMenuPanel" + actorClass); + rectElem.attr("x", rectData.x); + rectElem.attr("y", rectData.height); + rectElem.attr("fill", rectData.fill); + rectElem.attr("stroke", rectData.stroke); + rectElem.attr("width", menuWidth); + rectElem.attr("height", rectData.height); + rectElem.attr("rx", rectData.rx); + rectElem.attr("ry", rectData.ry); + if (links != null) { + var linkY = 20; + for (let key in links) { + var linkElem = g.append("a"); + var sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__/* .sanitizeUrl */ .Nm)(links[key]); + linkElem.attr("xlink:href", sanitizedLink); + linkElem.attr("target", "_blank"); + _drawMenuItemTextCandidateFunc(textAttrs)( + key, + linkElem, + rectData.x + 10, + rectData.height + linkY, + menuWidth, + 20, + { class: "actor" }, + textAttrs + ); + linkY += 30; + } + } + rectElem.attr("height", linkY); + return { height: rectData.height + linkY, width: menuWidth }; +}; +const popupMenu = function(popid) { + return "var pu = document.getElementById('" + popid + "'); if (pu != null) { pu.style.display = 'block'; }"; +}; +const popdownMenu = function(popid) { + return "var pu = document.getElementById('" + popid + "'); if (pu != null) { pu.style.display = 'none'; }"; +}; +const popupMenuUpFunc = function(popupId) { + var pu = document.getElementById(popupId); + if (pu != null) { + pu.style.display = "block"; + } +}; +const popupMenuDownFunc = function(popupId) { + var pu = document.getElementById(popupId); + if (pu != null) { + pu.style.display = "none"; + } +}; +const drawText = function(elem, textData) { + let prevTextHeight = 0; + let textHeight = 0; + const lines = textData.text.split(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + const [_textFontSize, _textFontSizePx] = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.C)(textData.fontSize); + let textElems = []; + let dy = 0; + let yfunc = () => textData.y; + if (textData.valign !== void 0 && textData.textMargin !== void 0 && textData.textMargin > 0) { + switch (textData.valign) { + case "top": + case "start": + yfunc = () => Math.round(textData.y + textData.textMargin); + break; + case "middle": + case "center": + yfunc = () => Math.round(textData.y + (prevTextHeight + textHeight + textData.textMargin) / 2); + break; + case "bottom": + case "end": + yfunc = () => Math.round( + textData.y + (prevTextHeight + textHeight + 2 * textData.textMargin) - textData.textMargin + ); + break; + } + } + if (textData.anchor !== void 0 && textData.textMargin !== void 0 && textData.width !== void 0) { + switch (textData.anchor) { + case "left": + case "start": + textData.x = Math.round(textData.x + textData.textMargin); + textData.anchor = "start"; + textData.dominantBaseline = "middle"; + textData.alignmentBaseline = "middle"; + break; + case "middle": + case "center": + textData.x = Math.round(textData.x + textData.width / 2); + textData.anchor = "middle"; + textData.dominantBaseline = "middle"; + textData.alignmentBaseline = "middle"; + break; + case "right": + case "end": + textData.x = Math.round(textData.x + textData.width - textData.textMargin); + textData.anchor = "end"; + textData.dominantBaseline = "middle"; + textData.alignmentBaseline = "middle"; + break; + } + } + for (let [i, line] of lines.entries()) { + if (textData.textMargin !== void 0 && textData.textMargin === 0 && _textFontSize !== void 0) { + dy = i * _textFontSize; + } + const textElem = elem.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", yfunc()); + if (textData.anchor !== void 0) { + textElem.attr("text-anchor", textData.anchor).attr("dominant-baseline", textData.dominantBaseline).attr("alignment-baseline", textData.alignmentBaseline); + } + if (textData.fontFamily !== void 0) { + textElem.style("font-family", textData.fontFamily); + } + if (_textFontSizePx !== void 0) { + textElem.style("font-size", _textFontSizePx); + } + if (textData.fontWeight !== void 0) { + textElem.style("font-weight", textData.fontWeight); + } + if (textData.fill !== void 0) { + textElem.attr("fill", textData.fill); + } + if (textData.class !== void 0) { + textElem.attr("class", textData.class); + } + if (textData.dy !== void 0) { + textElem.attr("dy", textData.dy); + } else if (dy !== 0) { + textElem.attr("dy", dy); + } + const text = line || _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.Z; + if (textData.tspan) { + const span = textElem.append("tspan"); + span.attr("x", textData.x); + if (textData.fill !== void 0) { + span.attr("fill", textData.fill); + } + span.text(text); + } else { + textElem.text(text); + } + if (textData.valign !== void 0 && textData.textMargin !== void 0 && textData.textMargin > 0) { + textHeight += (textElem._groups || textElem)[0][0].getBBox().height; + prevTextHeight = textHeight; + } + textElems.push(textElem); + } + return textElems; +}; +const drawLabel = function(elem, txtObject) { + function genPoints(x, y, width, height, cut) { + return x + "," + y + " " + (x + width) + "," + y + " " + (x + width) + "," + (y + height - cut) + " " + (x + width - cut * 1.2) + "," + (y + height) + " " + x + "," + (y + height); + } + const polygon = elem.append("polygon"); + polygon.attr("points", genPoints(txtObject.x, txtObject.y, txtObject.width, txtObject.height, 7)); + polygon.attr("class", "labelBox"); + txtObject.y = txtObject.y + txtObject.height / 2; + drawText(elem, txtObject); + return polygon; +}; +let actorCnt = -1; +const fixLifeLineHeights = (diagram2, actors2, actorKeys, conf2) => { + if (!diagram2.select) { + return; + } + actorKeys.forEach((actorKey) => { + const actor = actors2[actorKey]; + const actorDOM = diagram2.select("#actor" + actor.actorCnt); + if (!conf2.mirrorActors && actor.stopy) { + actorDOM.attr("y2", actor.stopy + actor.height / 2); + } else if (conf2.mirrorActors) { + actorDOM.attr("y2", actor.stopy); + } + }); +}; +const drawActorTypeParticipant = function(elem, actor, conf2, isFooter) { + const actorY = isFooter ? actor.stopy : actor.starty; + const center = actor.x + actor.width / 2; + const centerY = actorY + 5; + const boxpluslineGroup = elem.append("g").lower(); + var g = boxpluslineGroup; + if (!isFooter) { + actorCnt++; + g.append("line").attr("id", "actor" + actorCnt).attr("x1", center).attr("y1", centerY).attr("x2", center).attr("y2", 2e3).attr("class", "actor-line").attr("class", "200").attr("stroke-width", "0.5px").attr("stroke", "#999"); + g = boxpluslineGroup.append("g"); + actor.actorCnt = actorCnt; + if (actor.links != null) { + g.attr("id", "root-" + actorCnt); + addPopupInteraction("#root-" + actorCnt, actorCnt); + } + } + const rect = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + var cssclass = "actor"; + if (actor.properties != null && actor.properties["class"]) { + cssclass = actor.properties["class"]; + } else { + rect.fill = "#eaeaea"; + } + rect.x = actor.x; + rect.y = actorY; + rect.width = actor.width; + rect.height = actor.height; + rect.class = cssclass; + rect.rx = 3; + rect.ry = 3; + const rectElem = drawRect(g, rect); + actor.rectData = rect; + if (actor.properties != null && actor.properties["icon"]) { + const iconSrc = actor.properties["icon"].trim(); + if (iconSrc.charAt(0) === "@") { + (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.b)(g, rect.x + rect.width - 20, rect.y + 10, iconSrc.substr(1)); + } else { + (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.c)(g, rect.x + rect.width - 20, rect.y + 10, iconSrc); + } + } + _drawTextCandidateFunc(conf2)( + actor.description, + g, + rect.x, + rect.y, + rect.width, + rect.height, + { class: "actor" }, + conf2 + ); + let height = actor.height; + if (rectElem.node) { + const bounds2 = rectElem.node().getBBox(); + actor.height = bounds2.height; + height = bounds2.height; + } + return height; +}; +const drawActorTypeActor = function(elem, actor, conf2, isFooter) { + const actorY = isFooter ? actor.stopy : actor.starty; + const center = actor.x + actor.width / 2; + const centerY = actorY + 80; + elem.lower(); + if (!isFooter) { + actorCnt++; + elem.append("line").attr("id", "actor" + actorCnt).attr("x1", center).attr("y1", centerY).attr("x2", center).attr("y2", 2e3).attr("class", "actor-line").attr("class", "200").attr("stroke-width", "0.5px").attr("stroke", "#999"); + actor.actorCnt = actorCnt; + } + const actElem = elem.append("g"); + actElem.attr("class", "actor-man"); + const rect = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + rect.x = actor.x; + rect.y = actorY; + rect.fill = "#eaeaea"; + rect.width = actor.width; + rect.height = actor.height; + rect.class = "actor"; + rect.rx = 3; + rect.ry = 3; + actElem.append("line").attr("id", "actor-man-torso" + actorCnt).attr("x1", center).attr("y1", actorY + 25).attr("x2", center).attr("y2", actorY + 45); + actElem.append("line").attr("id", "actor-man-arms" + actorCnt).attr("x1", center - ACTOR_TYPE_WIDTH / 2).attr("y1", actorY + 33).attr("x2", center + ACTOR_TYPE_WIDTH / 2).attr("y2", actorY + 33); + actElem.append("line").attr("x1", center - ACTOR_TYPE_WIDTH / 2).attr("y1", actorY + 60).attr("x2", center).attr("y2", actorY + 45); + actElem.append("line").attr("x1", center).attr("y1", actorY + 45).attr("x2", center + ACTOR_TYPE_WIDTH / 2 - 2).attr("y2", actorY + 60); + const circle = actElem.append("circle"); + circle.attr("cx", actor.x + actor.width / 2); + circle.attr("cy", actorY + 10); + circle.attr("r", 15); + circle.attr("width", actor.width); + circle.attr("height", actor.height); + const bounds2 = actElem.node().getBBox(); + actor.height = bounds2.height; + _drawTextCandidateFunc(conf2)( + actor.description, + actElem, + rect.x, + rect.y + 35, + rect.width, + rect.height, + { class: "actor" }, + conf2 + ); + return actor.height; +}; +const drawActor = function(elem, actor, conf2, isFooter) { + switch (actor.type) { + case "actor": + return drawActorTypeActor(elem, actor, conf2, isFooter); + case "participant": + return drawActorTypeParticipant(elem, actor, conf2, isFooter); + } +}; +const drawBox = function(elem, box, conf2) { + const boxplustextGroup = elem.append("g"); + const g = boxplustextGroup; + drawBackgroundRect(g, box); + if (box.name) { + _drawTextCandidateFunc(conf2)( + box.name, + g, + box.x, + box.y + (box.textMaxHeight || 0) / 2, + box.width, + 0, + { class: "text" }, + conf2 + ); + } + g.lower(); +}; +const anchorElement = function(elem) { + return elem.append("g"); +}; +const drawActivation = function(elem, bounds2, verticalPos, conf2, actorActivations2) { + const rect = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + const g = bounds2.anchored; + rect.x = bounds2.startx; + rect.y = bounds2.starty; + rect.class = "activation" + actorActivations2 % 3; + rect.width = bounds2.stopx - bounds2.startx; + rect.height = verticalPos - bounds2.starty; + drawRect(g, rect); +}; +const drawLoop = function(elem, loopModel, labelText, conf2) { + const { + boxMargin, + boxTextMargin, + labelBoxHeight, + labelBoxWidth, + messageFontFamily: fontFamily, + messageFontSize: fontSize, + messageFontWeight: fontWeight + } = conf2; + const g = elem.append("g"); + const drawLoopLine = function(startx, starty, stopx, stopy) { + return g.append("line").attr("x1", startx).attr("y1", starty).attr("x2", stopx).attr("y2", stopy).attr("class", "loopLine"); + }; + drawLoopLine(loopModel.startx, loopModel.starty, loopModel.stopx, loopModel.starty); + drawLoopLine(loopModel.stopx, loopModel.starty, loopModel.stopx, loopModel.stopy); + drawLoopLine(loopModel.startx, loopModel.stopy, loopModel.stopx, loopModel.stopy); + drawLoopLine(loopModel.startx, loopModel.starty, loopModel.startx, loopModel.stopy); + if (loopModel.sections !== void 0) { + loopModel.sections.forEach(function(item) { + drawLoopLine(loopModel.startx, item.y, loopModel.stopx, item.y).style( + "stroke-dasharray", + "3, 3" + ); + }); + } + let txt = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.e)(); + txt.text = labelText; + txt.x = loopModel.startx; + txt.y = loopModel.starty; + txt.fontFamily = fontFamily; + txt.fontSize = fontSize; + txt.fontWeight = fontWeight; + txt.anchor = "middle"; + txt.valign = "middle"; + txt.tspan = false; + txt.width = labelBoxWidth || 50; + txt.height = labelBoxHeight || 20; + txt.textMargin = boxTextMargin; + txt.class = "labelText"; + drawLabel(g, txt); + txt = getTextObj(); + txt.text = loopModel.title; + txt.x = loopModel.startx + labelBoxWidth / 2 + (loopModel.stopx - loopModel.startx) / 2; + txt.y = loopModel.starty + boxMargin + boxTextMargin; + txt.anchor = "middle"; + txt.valign = "middle"; + txt.textMargin = boxTextMargin; + txt.class = "loopText"; + txt.fontFamily = fontFamily; + txt.fontSize = fontSize; + txt.fontWeight = fontWeight; + txt.wrap = true; + let textElem = drawText(g, txt); + if (loopModel.sectionTitles !== void 0) { + loopModel.sectionTitles.forEach(function(item, idx) { + if (item.message) { + txt.text = item.message; + txt.x = loopModel.startx + (loopModel.stopx - loopModel.startx) / 2; + txt.y = loopModel.sections[idx].y + boxMargin + boxTextMargin; + txt.class = "loopText"; + txt.anchor = "middle"; + txt.valign = "middle"; + txt.tspan = false; + txt.fontFamily = fontFamily; + txt.fontSize = fontSize; + txt.fontWeight = fontWeight; + txt.wrap = loopModel.wrap; + textElem = drawText(g, txt); + let sectionHeight = Math.round( + textElem.map((te) => (te._groups || te)[0][0].getBBox().height).reduce((acc, curr) => acc + curr) + ); + loopModel.sections[idx].height += sectionHeight - (boxMargin + boxTextMargin); + } + }); + } + loopModel.height = Math.round(loopModel.stopy - loopModel.starty); + return g; +}; +const drawBackgroundRect = function(elem, bounds2) { + (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.a)(elem, bounds2); +}; +const insertDatabaseIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "database").attr("fill-rule", "evenodd").attr("clip-rule", "evenodd").append("path").attr("transform", "scale(.5)").attr( + "d", + "M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z" + ); +}; +const insertComputerIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "computer").attr("width", "24").attr("height", "24").append("path").attr("transform", "scale(.5)").attr( + "d", + "M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z" + ); +}; +const insertClockIcon = function(elem) { + elem.append("defs").append("symbol").attr("id", "clock").attr("width", "24").attr("height", "24").append("path").attr("transform", "scale(.5)").attr( + "d", + "M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z" + ); +}; +const insertArrowHead = function(elem) { + elem.append("defs").append("marker").attr("id", "arrowhead").attr("refX", 7.9).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z"); +}; +const insertArrowFilledHead = function(elem) { + elem.append("defs").append("marker").attr("id", "filled-head").attr("refX", 15.5).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const insertSequenceNumber = function(elem) { + elem.append("defs").append("marker").attr("id", "sequencenumber").attr("refX", 15).attr("refY", 15).attr("markerWidth", 60).attr("markerHeight", 40).attr("orient", "auto").append("circle").attr("cx", 15).attr("cy", 15).attr("r", 6); +}; +const insertArrowCrossHead = function(elem) { + const defs = elem.append("defs"); + const marker = defs.append("marker").attr("id", "crosshead").attr("markerWidth", 15).attr("markerHeight", 8).attr("orient", "auto").attr("refX", 4).attr("refY", 4.5); + marker.append("path").attr("fill", "none").attr("stroke", "#000000").style("stroke-dasharray", "0, 0").attr("stroke-width", "1pt").attr("d", "M 1,2 L 6,7 M 6,2 L 1,7"); +}; +const getTextObj = function() { + return { + x: 0, + y: 0, + fill: void 0, + anchor: void 0, + style: "#666", + width: void 0, + height: void 0, + textMargin: 0, + rx: 0, + ry: 0, + tspan: true, + valign: void 0 + }; +}; +const getNoteRect = function() { + return { + x: 0, + y: 0, + fill: "#EDF2AE", + stroke: "#666", + width: 100, + anchor: "start", + height: 100, + rx: 0, + ry: 0 + }; +}; +const _drawTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs) { + const text = g.append("text").attr("x", x + width / 2).attr("y", y + height / 2 + 5).style("text-anchor", "middle").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf2) { + const { actorFontSize, actorFontFamily, actorFontWeight } = conf2; + const [_actorFontSize, _actorFontSizePx] = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.C)(actorFontSize); + const lines = content.split(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + for (let i = 0; i < lines.length; i++) { + const dy = i * _actorFontSize - _actorFontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x + width / 2).attr("y", y).style("text-anchor", "middle").style("font-size", _actorFontSizePx).style("font-weight", actorFontWeight).style("font-family", actorFontFamily); + text.append("tspan").attr("x", x + width / 2).attr("dy", dy).text(lines[i]); + text.attr("y", y + height / 2).attr("dominant-baseline", "central").attr("alignment-baseline", "central"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf2) { + const s = g.append("switch"); + const f = s.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, s, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (fromTextAttrsDict.hasOwnProperty(key)) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf2) { + return conf2.textPlacement === "fo" ? byFo : conf2.textPlacement === "old" ? byText : byTspan; + }; +}(); +const _drawMenuItemTextCandidateFunc = function() { + function byText(content, g, x, y, width, height, textAttrs) { + const text = g.append("text").attr("x", x).attr("y", y).style("text-anchor", "start").text(content); + _setTextAttrs(text, textAttrs); + } + function byTspan(content, g, x, y, width, height, textAttrs, conf2) { + const { actorFontSize, actorFontFamily, actorFontWeight } = conf2; + const lines = content.split(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.lineBreakRegex); + for (let i = 0; i < lines.length; i++) { + const dy = i * actorFontSize - actorFontSize * (lines.length - 1) / 2; + const text = g.append("text").attr("x", x).attr("y", y).style("text-anchor", "start").style("font-size", actorFontSize).style("font-weight", actorFontWeight).style("font-family", actorFontFamily); + text.append("tspan").attr("x", x).attr("dy", dy).text(lines[i]); + text.attr("y", y + height / 2).attr("dominant-baseline", "central").attr("alignment-baseline", "central"); + _setTextAttrs(text, textAttrs); + } + } + function byFo(content, g, x, y, width, height, textAttrs, conf2) { + const s = g.append("switch"); + const f = s.append("foreignObject").attr("x", x).attr("y", y).attr("width", width).attr("height", height); + const text = f.append("xhtml:div").style("display", "table").style("height", "100%").style("width", "100%"); + text.append("div").style("display", "table-cell").style("text-align", "center").style("vertical-align", "middle").text(content); + byTspan(content, s, x, y, width, height, textAttrs, conf2); + _setTextAttrs(text, textAttrs); + } + function _setTextAttrs(toText, fromTextAttrsDict) { + for (const key in fromTextAttrsDict) { + if (fromTextAttrsDict.hasOwnProperty(key)) { + toText.attr(key, fromTextAttrsDict[key]); + } + } + } + return function(conf2) { + return conf2.textPlacement === "fo" ? byFo : conf2.textPlacement === "old" ? byText : byTspan; + }; +}(); +const svgDraw = { + drawRect, + drawText, + drawLabel, + drawActor, + drawBox, + drawPopup, + anchorElement, + drawActivation, + drawLoop, + drawBackgroundRect, + insertArrowHead, + insertArrowFilledHead, + insertSequenceNumber, + insertArrowCrossHead, + insertDatabaseIcon, + insertComputerIcon, + insertClockIcon, + getTextObj, + getNoteRect, + popupMenu, + popdownMenu, + fixLifeLineHeights, + sanitizeUrl: _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_1__/* .sanitizeUrl */ .Nm +}; +let conf = {}; +const bounds = { + data: { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0 + }, + verticalPos: 0, + sequenceItems: [], + activations: [], + models: { + getHeight: function() { + return Math.max.apply( + null, + this.actors.length === 0 ? [0] : this.actors.map((actor) => actor.height || 0) + ) + (this.loops.length === 0 ? 0 : this.loops.map((it) => it.height || 0).reduce((acc, h) => acc + h)) + (this.messages.length === 0 ? 0 : this.messages.map((it) => it.height || 0).reduce((acc, h) => acc + h)) + (this.notes.length === 0 ? 0 : this.notes.map((it) => it.height || 0).reduce((acc, h) => acc + h)); + }, + clear: function() { + this.actors = []; + this.boxes = []; + this.loops = []; + this.messages = []; + this.notes = []; + }, + addBox: function(boxModel) { + this.boxes.push(boxModel); + }, + addActor: function(actorModel) { + this.actors.push(actorModel); + }, + addLoop: function(loopModel) { + this.loops.push(loopModel); + }, + addMessage: function(msgModel) { + this.messages.push(msgModel); + }, + addNote: function(noteModel) { + this.notes.push(noteModel); + }, + lastActor: function() { + return this.actors[this.actors.length - 1]; + }, + lastLoop: function() { + return this.loops[this.loops.length - 1]; + }, + lastMessage: function() { + return this.messages[this.messages.length - 1]; + }, + lastNote: function() { + return this.notes[this.notes.length - 1]; + }, + actors: [], + boxes: [], + loops: [], + messages: [], + notes: [] + }, + init: function() { + this.sequenceItems = []; + this.activations = []; + this.models.clear(); + this.data = { + startx: void 0, + stopx: void 0, + starty: void 0, + stopy: void 0 + }; + this.verticalPos = 0; + setConf((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + }, + updateVal: function(obj, key, val, fun) { + if (obj[key] === void 0) { + obj[key] = val; + } else { + obj[key] = fun(val, obj[key]); + } + }, + updateBounds: function(startx, starty, stopx, stopy) { + const _self = this; + let cnt = 0; + function updateFn(type) { + return function updateItemBounds(item) { + cnt++; + const n = _self.sequenceItems.length - cnt + 1; + _self.updateVal(item, "starty", starty - n * conf.boxMargin, Math.min); + _self.updateVal(item, "stopy", stopy + n * conf.boxMargin, Math.max); + _self.updateVal(bounds.data, "startx", startx - n * conf.boxMargin, Math.min); + _self.updateVal(bounds.data, "stopx", stopx + n * conf.boxMargin, Math.max); + if (!(type === "activation")) { + _self.updateVal(item, "startx", startx - n * conf.boxMargin, Math.min); + _self.updateVal(item, "stopx", stopx + n * conf.boxMargin, Math.max); + _self.updateVal(bounds.data, "starty", starty - n * conf.boxMargin, Math.min); + _self.updateVal(bounds.data, "stopy", stopy + n * conf.boxMargin, Math.max); + } + }; + } + this.sequenceItems.forEach(updateFn()); + this.activations.forEach(updateFn("activation")); + }, + insert: function(startx, starty, stopx, stopy) { + const _startx = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(startx, stopx); + const _stopx = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(startx, stopx); + const _starty = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(starty, stopy); + const _stopy = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(starty, stopy); + this.updateVal(bounds.data, "startx", _startx, Math.min); + this.updateVal(bounds.data, "starty", _starty, Math.min); + this.updateVal(bounds.data, "stopx", _stopx, Math.max); + this.updateVal(bounds.data, "stopy", _stopy, Math.max); + this.updateBounds(_startx, _starty, _stopx, _stopy); + }, + newActivation: function(message, diagram2, actors2) { + const actorRect = actors2[message.from.actor]; + const stackedSize = actorActivations(message.from.actor).length || 0; + const x = actorRect.x + actorRect.width / 2 + (stackedSize - 1) * conf.activationWidth / 2; + this.activations.push({ + startx: x, + starty: this.verticalPos + 2, + stopx: x + conf.activationWidth, + stopy: void 0, + actor: message.from.actor, + anchored: svgDraw.anchorElement(diagram2) + }); + }, + endActivation: function(message) { + const lastActorActivationIdx = this.activations.map(function(activation) { + return activation.actor; + }).lastIndexOf(message.from.actor); + return this.activations.splice(lastActorActivationIdx, 1)[0]; + }, + createLoop: function(title = { message: void 0, wrap: false, width: void 0 }, fill) { + return { + startx: void 0, + starty: this.verticalPos, + stopx: void 0, + stopy: void 0, + title: title.message, + wrap: title.wrap, + width: title.width, + height: 0, + fill + }; + }, + newLoop: function(title = { message: void 0, wrap: false, width: void 0 }, fill) { + this.sequenceItems.push(this.createLoop(title, fill)); + }, + endLoop: function() { + return this.sequenceItems.pop(); + }, + isLoopOverlap: function() { + return this.sequenceItems.length ? this.sequenceItems[this.sequenceItems.length - 1].overlap : false; + }, + addSectionToLoop: function(message) { + const loop = this.sequenceItems.pop(); + loop.sections = loop.sections || []; + loop.sectionTitles = loop.sectionTitles || []; + loop.sections.push({ y: bounds.getVerticalPos(), height: 0 }); + loop.sectionTitles.push(message); + this.sequenceItems.push(loop); + }, + saveVerticalPos: function() { + if (this.isLoopOverlap()) { + this.savedVerticalPos = this.verticalPos; + } + }, + resetVerticalPos: function() { + if (this.isLoopOverlap()) { + this.verticalPos = this.savedVerticalPos; + } + }, + bumpVerticalPos: function(bump) { + this.verticalPos = this.verticalPos + bump; + this.data.stopy = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(this.data.stopy, this.verticalPos); + }, + getVerticalPos: function() { + return this.verticalPos; + }, + getBounds: function() { + return { bounds: this.data, models: this.models }; + } +}; +const drawNote = function(elem, noteModel) { + bounds.bumpVerticalPos(conf.boxMargin); + noteModel.height = conf.boxMargin; + noteModel.starty = bounds.getVerticalPos(); + const rect = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.g)(); + rect.x = noteModel.startx; + rect.y = noteModel.starty; + rect.width = noteModel.width || conf.width; + rect.class = "note"; + const g = elem.append("g"); + const rectElem = svgDraw.drawRect(g, rect); + const textObj = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.e)(); + textObj.x = noteModel.startx; + textObj.y = noteModel.starty; + textObj.width = rect.width; + textObj.dy = "1em"; + textObj.text = noteModel.message; + textObj.class = "noteText"; + textObj.fontFamily = conf.noteFontFamily; + textObj.fontSize = conf.noteFontSize; + textObj.fontWeight = conf.noteFontWeight; + textObj.anchor = conf.noteAlign; + textObj.textMargin = conf.noteMargin; + textObj.valign = "center"; + const textElem = drawText(g, textObj); + const textHeight = Math.round( + textElem.map((te) => (te._groups || te)[0][0].getBBox().height).reduce((acc, curr) => acc + curr) + ); + rectElem.attr("height", textHeight + 2 * conf.noteMargin); + noteModel.height += textHeight + 2 * conf.noteMargin; + bounds.bumpVerticalPos(textHeight + 2 * conf.noteMargin); + noteModel.stopy = noteModel.starty + textHeight + 2 * conf.noteMargin; + noteModel.stopx = noteModel.startx + rect.width; + bounds.insert(noteModel.startx, noteModel.starty, noteModel.stopx, noteModel.stopy); + bounds.models.addNote(noteModel); +}; +const messageFont = (cnf) => { + return { + fontFamily: cnf.messageFontFamily, + fontSize: cnf.messageFontSize, + fontWeight: cnf.messageFontWeight + }; +}; +const noteFont = (cnf) => { + return { + fontFamily: cnf.noteFontFamily, + fontSize: cnf.noteFontSize, + fontWeight: cnf.noteFontWeight + }; +}; +const actorFont = (cnf) => { + return { + fontFamily: cnf.actorFontFamily, + fontSize: cnf.actorFontSize, + fontWeight: cnf.actorFontWeight + }; +}; +function boundMessage(_diagram, msgModel) { + bounds.bumpVerticalPos(10); + const { startx, stopx, message } = msgModel; + const lines = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.splitBreaks(message).length; + const textDims = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(message, messageFont(conf)); + const lineHeight = textDims.height / lines; + msgModel.height += lineHeight; + bounds.bumpVerticalPos(lineHeight); + let lineStartY; + let totalOffset = textDims.height - 10; + const textWidth = textDims.width; + if (startx === stopx) { + lineStartY = bounds.getVerticalPos() + totalOffset; + if (!conf.rightAngles) { + totalOffset += conf.boxMargin; + lineStartY = bounds.getVerticalPos() + totalOffset; + } + totalOffset += 30; + const dx = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(textWidth / 2, conf.width / 2); + bounds.insert( + startx - dx, + bounds.getVerticalPos() - 10 + totalOffset, + stopx + dx, + bounds.getVerticalPos() + 30 + totalOffset + ); + } else { + totalOffset += conf.boxMargin; + lineStartY = bounds.getVerticalPos() + totalOffset; + bounds.insert(startx, lineStartY - 10, stopx, lineStartY); + } + bounds.bumpVerticalPos(totalOffset); + msgModel.height += totalOffset; + msgModel.stopy = msgModel.starty + msgModel.height; + bounds.insert(msgModel.fromBounds, msgModel.starty, msgModel.toBounds, msgModel.stopy); + return lineStartY; +} +const drawMessage = function(diagram2, msgModel, lineStartY, diagObj) { + const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel; + const textDims = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(message, messageFont(conf)); + const textObj = (0,_svgDrawCommon_4835440b_js__WEBPACK_IMPORTED_MODULE_5__.e)(); + textObj.x = startx; + textObj.y = starty + 10; + textObj.width = stopx - startx; + textObj.class = "messageText"; + textObj.dy = "1em"; + textObj.text = message; + textObj.fontFamily = conf.messageFontFamily; + textObj.fontSize = conf.messageFontSize; + textObj.fontWeight = conf.messageFontWeight; + textObj.anchor = conf.messageAlign; + textObj.valign = "center"; + textObj.textMargin = conf.wrapPadding; + textObj.tspan = false; + drawText(diagram2, textObj); + const textWidth = textDims.width; + let line; + if (startx === stopx) { + if (conf.rightAngles) { + line = diagram2.append("path").attr( + "d", + `M ${startx},${lineStartY} H ${startx + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width / 2, textWidth / 2)} V ${lineStartY + 25} H ${startx}` + ); + } else { + line = diagram2.append("path").attr( + "d", + "M " + startx + "," + lineStartY + " C " + (startx + 60) + "," + (lineStartY - 10) + " " + (startx + 60) + "," + (lineStartY + 30) + " " + startx + "," + (lineStartY + 20) + ); + } + } else { + line = diagram2.append("line"); + line.attr("x1", startx); + line.attr("y1", lineStartY); + line.attr("x2", stopx); + line.attr("y2", lineStartY); + } + if (type === diagObj.db.LINETYPE.DOTTED || type === diagObj.db.LINETYPE.DOTTED_CROSS || type === diagObj.db.LINETYPE.DOTTED_POINT || type === diagObj.db.LINETYPE.DOTTED_OPEN) { + line.style("stroke-dasharray", "3, 3"); + line.attr("class", "messageLine1"); + } else { + line.attr("class", "messageLine0"); + } + let url = ""; + if (conf.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + line.attr("stroke-width", 2); + line.attr("stroke", "none"); + line.style("fill", "none"); + if (type === diagObj.db.LINETYPE.SOLID || type === diagObj.db.LINETYPE.DOTTED) { + line.attr("marker-end", "url(" + url + "#arrowhead)"); + } + if (type === diagObj.db.LINETYPE.SOLID_POINT || type === diagObj.db.LINETYPE.DOTTED_POINT) { + line.attr("marker-end", "url(" + url + "#filled-head)"); + } + if (type === diagObj.db.LINETYPE.SOLID_CROSS || type === diagObj.db.LINETYPE.DOTTED_CROSS) { + line.attr("marker-end", "url(" + url + "#crosshead)"); + } + if (sequenceVisible || conf.showSequenceNumbers) { + line.attr("marker-start", "url(" + url + "#sequencenumber)"); + diagram2.append("text").attr("x", startx).attr("y", lineStartY + 4).attr("font-family", "sans-serif").attr("font-size", "12px").attr("text-anchor", "middle").attr("class", "sequenceNumber").text(sequenceIndex); + } +}; +const addActorRenderingData = function(diagram2, actors2, createdActors2, actorKeys, verticalPos, messages2, isFooter) { + let prevWidth = 0; + let prevMargin = 0; + let prevBox = void 0; + let maxHeight = 0; + for (const actorKey of actorKeys) { + const actor = actors2[actorKey]; + const box = actor.box; + if (prevBox && prevBox != box) { + if (!isFooter) { + bounds.models.addBox(prevBox); + } + prevMargin += conf.boxMargin + prevBox.margin; + } + if (box && box != prevBox) { + if (!isFooter) { + box.x = prevWidth + prevMargin; + box.y = verticalPos; + } + prevMargin += box.margin; + } + actor.width = actor.width || conf.width; + actor.height = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(actor.height || conf.height, conf.height); + actor.margin = actor.margin || conf.actorMargin; + maxHeight = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(maxHeight, actor.height); + if (createdActors2[actor.name]) { + prevMargin += actor.width / 2; + } + actor.x = prevWidth + prevMargin; + actor.starty = bounds.getVerticalPos(); + bounds.insert(actor.x, verticalPos, actor.x + actor.width, actor.height); + prevWidth += actor.width + prevMargin; + if (actor.box) { + actor.box.width = prevWidth + box.margin - actor.box.x; + } + prevMargin = actor.margin; + prevBox = actor.box; + bounds.models.addActor(actor); + } + if (prevBox && !isFooter) { + bounds.models.addBox(prevBox); + } + bounds.bumpVerticalPos(maxHeight); +}; +const drawActors = function(diagram2, actors2, actorKeys, isFooter) { + if (!isFooter) { + for (const actorKey of actorKeys) { + const actor = actors2[actorKey]; + svgDraw.drawActor(diagram2, actor, conf, false); + } + } else { + let maxHeight = 0; + bounds.bumpVerticalPos(conf.boxMargin * 2); + for (const actorKey of actorKeys) { + const actor = actors2[actorKey]; + if (!actor.stopy) { + actor.stopy = bounds.getVerticalPos(); + } + const height = svgDraw.drawActor(diagram2, actor, conf, true); + maxHeight = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(maxHeight, height); + } + bounds.bumpVerticalPos(maxHeight + conf.boxMargin); + } +}; +const drawActorsPopup = function(diagram2, actors2, actorKeys, doc) { + let maxHeight = 0; + let maxWidth = 0; + for (const actorKey of actorKeys) { + const actor = actors2[actorKey]; + const minMenuWidth = getRequiredPopupWidth(actor); + const menuDimensions = svgDraw.drawPopup( + diagram2, + actor, + minMenuWidth, + conf, + conf.forceMenus, + doc + ); + if (menuDimensions.height > maxHeight) { + maxHeight = menuDimensions.height; + } + if (menuDimensions.width + actor.x > maxWidth) { + maxWidth = menuDimensions.width + actor.x; + } + } + return { maxHeight, maxWidth }; +}; +const setConf = function(cnf) { + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.f)(conf, cnf); + if (cnf.fontFamily) { + conf.actorFontFamily = conf.noteFontFamily = conf.messageFontFamily = cnf.fontFamily; + } + if (cnf.fontSize) { + conf.actorFontSize = conf.noteFontSize = conf.messageFontSize = cnf.fontSize; + } + if (cnf.fontWeight) { + conf.actorFontWeight = conf.noteFontWeight = conf.messageFontWeight = cnf.fontWeight; + } +}; +const actorActivations = function(actor) { + return bounds.activations.filter(function(activation) { + return activation.actor === actor; + }); +}; +const activationBounds = function(actor, actors2) { + const actorObj = actors2[actor]; + const activations = actorActivations(actor); + const left = activations.reduce(function(acc, activation) { + return _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(acc, activation.startx); + }, actorObj.x + actorObj.width / 2 - 1); + const right = activations.reduce(function(acc, activation) { + return _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(acc, activation.stopx); + }, actorObj.x + actorObj.width / 2 + 1); + return [left, right]; +}; +function adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoopFn) { + bounds.bumpVerticalPos(preMargin); + let heightAdjust = postMargin; + if (msg.id && msg.message && loopWidths[msg.id]) { + const loopWidth = loopWidths[msg.id].width; + const textConf = messageFont(conf); + msg.message = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel(`[${msg.message}]`, loopWidth - 2 * conf.wrapPadding, textConf); + msg.width = loopWidth; + msg.wrap = true; + const textDims = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(msg.message, textConf); + const totalOffset = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(textDims.height, conf.labelBoxHeight); + heightAdjust = postMargin + totalOffset; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`${totalOffset} - ${msg.message}`); + } + addLoopFn(msg); + bounds.bumpVerticalPos(heightAdjust); +} +function adjustCreatedDestroyedData(msg, msgModel, lineStartY, index, actors2, createdActors2, destroyedActors2) { + function receiverAdjustment(actor, adjustment) { + if (actor.x < actors2[msg.from].x) { + bounds.insert( + msgModel.stopx - adjustment, + msgModel.starty, + msgModel.startx, + msgModel.stopy + actor.height / 2 + conf.noteMargin + ); + msgModel.stopx = msgModel.stopx + adjustment; + } else { + bounds.insert( + msgModel.startx, + msgModel.starty, + msgModel.stopx + adjustment, + msgModel.stopy + actor.height / 2 + conf.noteMargin + ); + msgModel.stopx = msgModel.stopx - adjustment; + } + } + function senderAdjustment(actor, adjustment) { + if (actor.x < actors2[msg.to].x) { + bounds.insert( + msgModel.startx - adjustment, + msgModel.starty, + msgModel.stopx, + msgModel.stopy + actor.height / 2 + conf.noteMargin + ); + msgModel.startx = msgModel.startx + adjustment; + } else { + bounds.insert( + msgModel.stopx, + msgModel.starty, + msgModel.startx + adjustment, + msgModel.stopy + actor.height / 2 + conf.noteMargin + ); + msgModel.startx = msgModel.startx - adjustment; + } + } + if (createdActors2[msg.to] == index) { + const actor = actors2[msg.to]; + const adjustment = actor.type == "actor" ? ACTOR_TYPE_WIDTH / 2 + 3 : actor.width / 2 + 3; + receiverAdjustment(actor, adjustment); + actor.starty = lineStartY - actor.height / 2; + bounds.bumpVerticalPos(actor.height / 2); + } else if (destroyedActors2[msg.from] == index) { + const actor = actors2[msg.from]; + if (conf.mirrorActors) { + const adjustment = actor.type == "actor" ? ACTOR_TYPE_WIDTH / 2 : actor.width / 2; + senderAdjustment(actor, adjustment); + } + actor.stopy = lineStartY - actor.height / 2; + bounds.bumpVerticalPos(actor.height / 2); + } else if (destroyedActors2[msg.to] == index) { + const actor = actors2[msg.to]; + if (conf.mirrorActors) { + const adjustment = actor.type == "actor" ? ACTOR_TYPE_WIDTH / 2 + 3 : actor.width / 2 + 3; + receiverAdjustment(actor, adjustment); + } + actor.stopy = lineStartY - actor.height / 2; + bounds.bumpVerticalPos(actor.height / 2); + } +} +const draw = function(_text, id, _version, diagObj) { + const { securityLevel, sequence } = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + conf = sequence; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + bounds.init(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(diagObj.db); + const diagram2 = securityLevel === "sandbox" ? root.select(`[id="${id}"]`) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(`[id="${id}"]`); + const actors2 = diagObj.db.getActors(); + const createdActors2 = diagObj.db.getCreatedActors(); + const destroyedActors2 = diagObj.db.getDestroyedActors(); + const boxes2 = diagObj.db.getBoxes(); + let actorKeys = diagObj.db.getActorKeys(); + const messages2 = diagObj.db.getMessages(); + const title = diagObj.db.getDiagramTitle(); + const hasBoxes = diagObj.db.hasAtLeastOneBox(); + const hasBoxTitles = diagObj.db.hasAtLeastOneBoxWithTitle(); + const maxMessageWidthPerActor = getMaxMessageWidthPerActor(actors2, messages2, diagObj); + conf.height = calculateActorMargins(actors2, maxMessageWidthPerActor, boxes2); + svgDraw.insertComputerIcon(diagram2); + svgDraw.insertDatabaseIcon(diagram2); + svgDraw.insertClockIcon(diagram2); + if (hasBoxes) { + bounds.bumpVerticalPos(conf.boxMargin); + if (hasBoxTitles) { + bounds.bumpVerticalPos(boxes2[0].textMaxHeight); + } + } + if (conf.hideUnusedParticipants === true) { + const newActors = /* @__PURE__ */ new Set(); + messages2.forEach((message) => { + newActors.add(message.from); + newActors.add(message.to); + }); + actorKeys = actorKeys.filter((actorKey) => newActors.has(actorKey)); + } + addActorRenderingData(diagram2, actors2, createdActors2, actorKeys, 0, messages2, false); + const loopWidths = calculateLoopBounds(messages2, actors2, maxMessageWidthPerActor, diagObj); + svgDraw.insertArrowHead(diagram2); + svgDraw.insertArrowCrossHead(diagram2); + svgDraw.insertArrowFilledHead(diagram2); + svgDraw.insertSequenceNumber(diagram2); + function activeEnd(msg, verticalPos) { + const activationData = bounds.endActivation(msg); + if (activationData.starty + 18 > verticalPos) { + activationData.starty = verticalPos - 6; + verticalPos += 12; + } + svgDraw.drawActivation( + diagram2, + activationData, + verticalPos, + conf, + actorActivations(msg.from.actor).length + ); + bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos); + } + let sequenceIndex = 1; + let sequenceIndexStep = 1; + const messagesToDraw = []; + const backgrounds = []; + messages2.forEach(function(msg, index) { + let loopModel, noteModel, msgModel; + switch (msg.type) { + case diagObj.db.LINETYPE.NOTE: + bounds.resetVerticalPos(); + noteModel = msg.noteModel; + drawNote(diagram2, noteModel); + break; + case diagObj.db.LINETYPE.ACTIVE_START: + bounds.newActivation(msg, diagram2, actors2); + break; + case diagObj.db.LINETYPE.ACTIVE_END: + activeEnd(msg, bounds.getVerticalPos()); + break; + case diagObj.db.LINETYPE.LOOP_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.LOOP_END: + loopModel = bounds.endLoop(); + svgDraw.drawLoop(diagram2, loopModel, "loop", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.RECT_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin, + (message) => bounds.newLoop(void 0, message.message) + ); + break; + case diagObj.db.LINETYPE.RECT_END: + loopModel = bounds.endLoop(); + backgrounds.push(loopModel); + bounds.models.addLoop(loopModel); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + break; + case diagObj.db.LINETYPE.OPT_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.OPT_END: + loopModel = bounds.endLoop(); + svgDraw.drawLoop(diagram2, loopModel, "opt", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.ALT_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.ALT_ELSE: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin + conf.boxTextMargin, + conf.boxMargin, + (message) => bounds.addSectionToLoop(message) + ); + break; + case diagObj.db.LINETYPE.ALT_END: + loopModel = bounds.endLoop(); + svgDraw.drawLoop(diagram2, loopModel, "alt", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.PAR_START: + case diagObj.db.LINETYPE.PAR_OVER_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + bounds.saveVerticalPos(); + break; + case diagObj.db.LINETYPE.PAR_AND: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin + conf.boxTextMargin, + conf.boxMargin, + (message) => bounds.addSectionToLoop(message) + ); + break; + case diagObj.db.LINETYPE.PAR_END: + loopModel = bounds.endLoop(); + svgDraw.drawLoop(diagram2, loopModel, "par", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.AUTONUMBER: + sequenceIndex = msg.message.start || sequenceIndex; + sequenceIndexStep = msg.message.step || sequenceIndexStep; + if (msg.message.visible) { + diagObj.db.enableSequenceNumbers(); + } else { + diagObj.db.disableSequenceNumbers(); + } + break; + case diagObj.db.LINETYPE.CRITICAL_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.CRITICAL_OPTION: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin + conf.boxTextMargin, + conf.boxMargin, + (message) => bounds.addSectionToLoop(message) + ); + break; + case diagObj.db.LINETYPE.CRITICAL_END: + loopModel = bounds.endLoop(); + svgDraw.drawLoop(diagram2, loopModel, "critical", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + case diagObj.db.LINETYPE.BREAK_START: + adjustLoopHeightForWrap( + loopWidths, + msg, + conf.boxMargin, + conf.boxMargin + conf.boxTextMargin, + (message) => bounds.newLoop(message) + ); + break; + case diagObj.db.LINETYPE.BREAK_END: + loopModel = bounds.endLoop(); + svgDraw.drawLoop(diagram2, loopModel, "break", conf); + bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos()); + bounds.models.addLoop(loopModel); + break; + default: + try { + msgModel = msg.msgModel; + msgModel.starty = bounds.getVerticalPos(); + msgModel.sequenceIndex = sequenceIndex; + msgModel.sequenceVisible = diagObj.db.showSequenceNumbers(); + const lineStartY = boundMessage(diagram2, msgModel); + adjustCreatedDestroyedData( + msg, + msgModel, + lineStartY, + index, + actors2, + createdActors2, + destroyedActors2 + ); + messagesToDraw.push({ messageModel: msgModel, lineStartY }); + bounds.models.addMessage(msgModel); + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while drawing message", e); + } + } + if ([ + diagObj.db.LINETYPE.SOLID_OPEN, + diagObj.db.LINETYPE.DOTTED_OPEN, + diagObj.db.LINETYPE.SOLID, + diagObj.db.LINETYPE.DOTTED, + diagObj.db.LINETYPE.SOLID_CROSS, + diagObj.db.LINETYPE.DOTTED_CROSS, + diagObj.db.LINETYPE.SOLID_POINT, + diagObj.db.LINETYPE.DOTTED_POINT + ].includes(msg.type)) { + sequenceIndex = sequenceIndex + sequenceIndexStep; + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("createdActors", createdActors2); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("destroyedActors", destroyedActors2); + drawActors(diagram2, actors2, actorKeys, false); + messagesToDraw.forEach((e) => drawMessage(diagram2, e.messageModel, e.lineStartY, diagObj)); + if (conf.mirrorActors) { + drawActors(diagram2, actors2, actorKeys, true); + } + backgrounds.forEach((e) => svgDraw.drawBackgroundRect(diagram2, e)); + fixLifeLineHeights(diagram2, actors2, actorKeys, conf); + bounds.models.boxes.forEach(function(box2) { + box2.height = bounds.getVerticalPos() - box2.y; + bounds.insert(box2.x, box2.y, box2.x + box2.width, box2.height); + box2.startx = box2.x; + box2.starty = box2.y; + box2.stopx = box2.startx + box2.width; + box2.stopy = box2.starty + box2.height; + box2.stroke = "rgb(0,0,0, 0.5)"; + svgDraw.drawBox(diagram2, box2, conf); + }); + if (hasBoxes) { + bounds.bumpVerticalPos(conf.boxMargin); + } + const requiredBoxSize = drawActorsPopup(diagram2, actors2, actorKeys, doc); + const { bounds: box } = bounds.getBounds(); + let boxHeight = box.stopy - box.starty; + if (boxHeight < requiredBoxSize.maxHeight) { + boxHeight = requiredBoxSize.maxHeight; + } + let height = boxHeight + 2 * conf.diagramMarginY; + if (conf.mirrorActors) { + height = height - conf.boxMargin + conf.bottomMarginAdj; + } + let boxWidth = box.stopx - box.startx; + if (boxWidth < requiredBoxSize.maxWidth) { + boxWidth = requiredBoxSize.maxWidth; + } + const width = boxWidth + 2 * conf.diagramMarginX; + if (title) { + diagram2.append("text").text(title).attr("x", (box.stopx - box.startx) / 2 - 2 * conf.diagramMarginX).attr("y", -25); + } + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.i)(diagram2, height, width, conf.useMaxWidth); + const extraVertForTitle = title ? 40 : 0; + diagram2.attr( + "viewBox", + box.startx - conf.diagramMarginX + " -" + (conf.diagramMarginY + extraVertForTitle) + " " + width + " " + (height + extraVertForTitle) + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(`models:`, bounds.models); +}; +function getMaxMessageWidthPerActor(actors2, messages2, diagObj) { + const maxMessageWidthPerActor = {}; + messages2.forEach(function(msg) { + if (actors2[msg.to] && actors2[msg.from]) { + const actor = actors2[msg.to]; + if (msg.placement === diagObj.db.PLACEMENT.LEFTOF && !actor.prevActor) { + return; + } + if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF && !actor.nextActor) { + return; + } + const isNote = msg.placement !== void 0; + const isMessage = !isNote; + const textFont = isNote ? noteFont(conf) : messageFont(conf); + const wrappedMessage = msg.wrap ? _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel(msg.message, conf.width - 2 * conf.wrapPadding, textFont) : msg.message; + const messageDimensions = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(wrappedMessage, textFont); + const messageWidth = messageDimensions.width + 2 * conf.wrapPadding; + if (isMessage && msg.from === actor.nextActor) { + maxMessageWidthPerActor[msg.to] = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.to] || 0, + messageWidth + ); + } else if (isMessage && msg.from === actor.prevActor) { + maxMessageWidthPerActor[msg.from] = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.from] || 0, + messageWidth + ); + } else if (isMessage && msg.from === msg.to) { + maxMessageWidthPerActor[msg.from] = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.from] || 0, + messageWidth / 2 + ); + maxMessageWidthPerActor[msg.to] = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.to] || 0, + messageWidth / 2 + ); + } else if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF) { + maxMessageWidthPerActor[msg.from] = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.from] || 0, + messageWidth + ); + } else if (msg.placement === diagObj.db.PLACEMENT.LEFTOF) { + maxMessageWidthPerActor[actor.prevActor] = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[actor.prevActor] || 0, + messageWidth + ); + } else if (msg.placement === diagObj.db.PLACEMENT.OVER) { + if (actor.prevActor) { + maxMessageWidthPerActor[actor.prevActor] = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[actor.prevActor] || 0, + messageWidth / 2 + ); + } + if (actor.nextActor) { + maxMessageWidthPerActor[msg.from] = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + maxMessageWidthPerActor[msg.from] || 0, + messageWidth / 2 + ); + } + } + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("maxMessageWidthPerActor:", maxMessageWidthPerActor); + return maxMessageWidthPerActor; +} +const getRequiredPopupWidth = function(actor) { + let requiredPopupWidth = 0; + const textFont = actorFont(conf); + for (const key in actor.links) { + const labelDimensions = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(key, textFont); + const labelWidth = labelDimensions.width + 2 * conf.wrapPadding + 2 * conf.boxMargin; + if (requiredPopupWidth < labelWidth) { + requiredPopupWidth = labelWidth; + } + } + return requiredPopupWidth; +}; +function calculateActorMargins(actors2, actorToMessageWidth, boxes2) { + let maxHeight = 0; + Object.keys(actors2).forEach((prop) => { + const actor = actors2[prop]; + if (actor.wrap) { + actor.description = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel( + actor.description, + conf.width - 2 * conf.wrapPadding, + actorFont(conf) + ); + } + const actDims = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(actor.description, actorFont(conf)); + actor.width = actor.wrap ? conf.width : _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, actDims.width + 2 * conf.wrapPadding); + actor.height = actor.wrap ? _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(actDims.height, conf.height) : conf.height; + maxHeight = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(maxHeight, actor.height); + }); + for (const actorKey in actorToMessageWidth) { + const actor = actors2[actorKey]; + if (!actor) { + continue; + } + const nextActor = actors2[actor.nextActor]; + if (!nextActor) { + const messageWidth2 = actorToMessageWidth[actorKey]; + const actorWidth2 = messageWidth2 + conf.actorMargin - actor.width / 2; + actor.margin = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(actorWidth2, conf.actorMargin); + continue; + } + const messageWidth = actorToMessageWidth[actorKey]; + const actorWidth = messageWidth + conf.actorMargin - actor.width / 2 - nextActor.width / 2; + actor.margin = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(actorWidth, conf.actorMargin); + } + let maxBoxHeight = 0; + boxes2.forEach((box) => { + const textFont = messageFont(conf); + let totalWidth = box.actorKeys.reduce((total, aKey) => { + return total += actors2[aKey].width + (actors2[aKey].margin || 0); + }, 0); + totalWidth -= 2 * conf.boxTextMargin; + if (box.wrap) { + box.name = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel(box.name, totalWidth - 2 * conf.wrapPadding, textFont); + } + const boxMsgDimensions = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(box.name, textFont); + maxBoxHeight = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(boxMsgDimensions.height, maxBoxHeight); + const minWidth = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(totalWidth, boxMsgDimensions.width + 2 * conf.wrapPadding); + box.margin = conf.boxTextMargin; + if (totalWidth < minWidth) { + const missing = (minWidth - totalWidth) / 2; + box.margin += missing; + } + }); + boxes2.forEach((box) => box.textMaxHeight = maxBoxHeight); + return _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(maxHeight, conf.height); +} +const buildNoteModel = function(msg, actors2, diagObj) { + const startx = actors2[msg.from].x; + const stopx = actors2[msg.to].x; + const shouldWrap = msg.wrap && msg.message; + let textDimensions = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions( + shouldWrap ? _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel(msg.message, conf.width, noteFont(conf)) : msg.message, + noteFont(conf) + ); + const noteModel = { + width: shouldWrap ? conf.width : _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, textDimensions.width + 2 * conf.noteMargin), + height: 0, + startx: actors2[msg.from].x, + stopx: 0, + starty: 0, + stopy: 0, + message: msg.message + }; + if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF) { + noteModel.width = shouldWrap ? _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, textDimensions.width) : _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + actors2[msg.from].width / 2 + actors2[msg.to].width / 2, + textDimensions.width + 2 * conf.noteMargin + ); + noteModel.startx = startx + (actors2[msg.from].width + conf.actorMargin) / 2; + } else if (msg.placement === diagObj.db.PLACEMENT.LEFTOF) { + noteModel.width = shouldWrap ? _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, textDimensions.width + 2 * conf.noteMargin) : _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + actors2[msg.from].width / 2 + actors2[msg.to].width / 2, + textDimensions.width + 2 * conf.noteMargin + ); + noteModel.startx = startx - noteModel.width + (actors2[msg.from].width - conf.actorMargin) / 2; + } else if (msg.to === msg.from) { + textDimensions = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions( + shouldWrap ? _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel( + msg.message, + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, actors2[msg.from].width), + noteFont(conf) + ) : msg.message, + noteFont(conf) + ); + noteModel.width = shouldWrap ? _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(conf.width, actors2[msg.from].width) : _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + actors2[msg.from].width, + conf.width, + textDimensions.width + 2 * conf.noteMargin + ); + noteModel.startx = startx + (actors2[msg.from].width - noteModel.width) / 2; + } else { + noteModel.width = Math.abs(startx + actors2[msg.from].width / 2 - (stopx + actors2[msg.to].width / 2)) + conf.actorMargin; + noteModel.startx = startx < stopx ? startx + actors2[msg.from].width / 2 - conf.actorMargin / 2 : stopx + actors2[msg.to].width / 2 - conf.actorMargin / 2; + } + if (shouldWrap) { + noteModel.message = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel( + msg.message, + noteModel.width - 2 * conf.wrapPadding, + noteFont(conf) + ); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + `NM:[${noteModel.startx},${noteModel.stopx},${noteModel.starty},${noteModel.stopy}:${noteModel.width},${noteModel.height}=${msg.message}]` + ); + return noteModel; +}; +const buildMessageModel = function(msg, actors2, diagObj) { + if (![ + diagObj.db.LINETYPE.SOLID_OPEN, + diagObj.db.LINETYPE.DOTTED_OPEN, + diagObj.db.LINETYPE.SOLID, + diagObj.db.LINETYPE.DOTTED, + diagObj.db.LINETYPE.SOLID_CROSS, + diagObj.db.LINETYPE.DOTTED_CROSS, + diagObj.db.LINETYPE.SOLID_POINT, + diagObj.db.LINETYPE.DOTTED_POINT + ].includes(msg.type)) { + return {}; + } + const [fromLeft, fromRight] = activationBounds(msg.from, actors2); + const [toLeft, toRight] = activationBounds(msg.to, actors2); + const isArrowToRight = fromLeft <= toLeft; + const startx = isArrowToRight ? fromRight : fromLeft; + let stopx = isArrowToRight ? toLeft : toRight; + const isArrowToActivation = Math.abs(toLeft - toRight) > 2; + const adjustValue = (value) => { + return isArrowToRight ? -value : value; + }; + if (msg.from === msg.to) { + stopx = startx; + } else { + if (msg.activate && !isArrowToActivation) { + stopx += adjustValue(conf.activationWidth / 2 - 1); + } + if (![diagObj.db.LINETYPE.SOLID_OPEN, diagObj.db.LINETYPE.DOTTED_OPEN].includes(msg.type)) { + stopx += adjustValue(3); + } + } + const allBounds = [fromLeft, fromRight, toLeft, toRight]; + const boundedWidth = Math.abs(startx - stopx); + if (msg.wrap && msg.message) { + msg.message = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.wrapLabel( + msg.message, + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(boundedWidth + 2 * conf.wrapPadding, conf.width), + messageFont(conf) + ); + } + const msgDims = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.calculateTextDimensions(msg.message, messageFont(conf)); + return { + width: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + msg.wrap ? 0 : msgDims.width + 2 * conf.wrapPadding, + boundedWidth + 2 * conf.wrapPadding, + conf.width + ), + height: 0, + startx, + stopx, + starty: 0, + stopy: 0, + message: msg.message, + type: msg.type, + wrap: msg.wrap, + fromBounds: Math.min.apply(null, allBounds), + toBounds: Math.max.apply(null, allBounds) + }; +}; +const calculateLoopBounds = function(messages2, actors2, _maxWidthPerActor, diagObj) { + const loops = {}; + const stack = []; + let current, noteModel, msgModel; + messages2.forEach(function(msg) { + msg.id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.random({ length: 10 }); + switch (msg.type) { + case diagObj.db.LINETYPE.LOOP_START: + case diagObj.db.LINETYPE.ALT_START: + case diagObj.db.LINETYPE.OPT_START: + case diagObj.db.LINETYPE.PAR_START: + case diagObj.db.LINETYPE.PAR_OVER_START: + case diagObj.db.LINETYPE.CRITICAL_START: + case diagObj.db.LINETYPE.BREAK_START: + stack.push({ + id: msg.id, + msg: msg.message, + from: Number.MAX_SAFE_INTEGER, + to: Number.MIN_SAFE_INTEGER, + width: 0 + }); + break; + case diagObj.db.LINETYPE.ALT_ELSE: + case diagObj.db.LINETYPE.PAR_AND: + case diagObj.db.LINETYPE.CRITICAL_OPTION: + if (msg.message) { + current = stack.pop(); + loops[current.id] = current; + loops[msg.id] = current; + stack.push(current); + } + break; + case diagObj.db.LINETYPE.LOOP_END: + case diagObj.db.LINETYPE.ALT_END: + case diagObj.db.LINETYPE.OPT_END: + case diagObj.db.LINETYPE.PAR_END: + case diagObj.db.LINETYPE.CRITICAL_END: + case diagObj.db.LINETYPE.BREAK_END: + current = stack.pop(); + loops[current.id] = current; + break; + case diagObj.db.LINETYPE.ACTIVE_START: + { + const actorRect = actors2[msg.from ? msg.from.actor : msg.to.actor]; + const stackedSize = actorActivations(msg.from ? msg.from.actor : msg.to.actor).length; + const x = actorRect.x + actorRect.width / 2 + (stackedSize - 1) * conf.activationWidth / 2; + const toAdd = { + startx: x, + stopx: x + conf.activationWidth, + actor: msg.from.actor, + enabled: true + }; + bounds.activations.push(toAdd); + } + break; + case diagObj.db.LINETYPE.ACTIVE_END: + { + const lastActorActivationIdx = bounds.activations.map((a) => a.actor).lastIndexOf(msg.from.actor); + delete bounds.activations.splice(lastActorActivationIdx, 1)[0]; + } + break; + } + const isNote = msg.placement !== void 0; + if (isNote) { + noteModel = buildNoteModel(msg, actors2, diagObj); + msg.noteModel = noteModel; + stack.forEach((stk) => { + current = stk; + current.from = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(current.from, noteModel.startx); + current.to = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(current.to, noteModel.startx + noteModel.width); + current.width = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(current.width, Math.abs(current.from - current.to)) - conf.labelBoxWidth; + }); + } else { + msgModel = buildMessageModel(msg, actors2, diagObj); + msg.msgModel = msgModel; + if (msgModel.startx && msgModel.stopx && stack.length > 0) { + stack.forEach((stk) => { + current = stk; + if (msgModel.startx === msgModel.stopx) { + const from = actors2[msg.from]; + const to = actors2[msg.to]; + current.from = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin( + from.x - msgModel.width / 2, + from.x - from.width / 2, + current.from + ); + current.to = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax( + to.x + msgModel.width / 2, + to.x + from.width / 2, + current.to + ); + current.width = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(current.width, Math.abs(current.to - current.from)) - conf.labelBoxWidth; + } else { + current.from = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMin(msgModel.startx, current.from); + current.to = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(msgModel.stopx, current.to); + current.width = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.getMax(current.width, msgModel.width) - conf.labelBoxWidth; + } + }); + } + } + }); + bounds.activations = []; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Loop type widths:", loops); + return loops; +}; +const renderer = { + bounds, + drawActors, + drawActorsPopup, + setConf, + draw +}; +const diagram = { + parser: parser$1, + db, + renderer, + styles, + init: ({ wrap }) => { + db.setWrap(wrap); + } +}; + + + +/***/ }), + +/***/ 93799: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ drawBackgroundRect), +/* harmony export */ b: () => (/* binding */ drawEmbeddedImage), +/* harmony export */ c: () => (/* binding */ drawImage), +/* harmony export */ d: () => (/* binding */ drawRect), +/* harmony export */ e: () => (/* binding */ getTextObj), +/* harmony export */ f: () => (/* binding */ drawText), +/* harmony export */ g: () => (/* binding */ getNoteRect) +/* harmony export */ }); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(17967); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); + + +const drawRect = (element, rectData) => { + const rectElement = element.append("rect"); + rectElement.attr("x", rectData.x); + rectElement.attr("y", rectData.y); + rectElement.attr("fill", rectData.fill); + rectElement.attr("stroke", rectData.stroke); + rectElement.attr("width", rectData.width); + rectElement.attr("height", rectData.height); + rectData.rx !== void 0 && rectElement.attr("rx", rectData.rx); + rectData.ry !== void 0 && rectElement.attr("ry", rectData.ry); + if (rectData.attrs !== void 0) { + for (const attrKey in rectData.attrs) { + rectElement.attr(attrKey, rectData.attrs[attrKey]); + } + } + rectData.class !== void 0 && rectElement.attr("class", rectData.class); + return rectElement; +}; +const drawBackgroundRect = (element, bounds) => { + const rectData = { + x: bounds.startx, + y: bounds.starty, + width: bounds.stopx - bounds.startx, + height: bounds.stopy - bounds.starty, + fill: bounds.fill, + stroke: bounds.stroke, + class: "rect" + }; + const rectElement = drawRect(element, rectData); + rectElement.lower(); +}; +const drawText = (element, textData) => { + const nText = textData.text.replace(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.H, " "); + const textElem = element.append("text"); + textElem.attr("x", textData.x); + textElem.attr("y", textData.y); + textElem.attr("class", "legend"); + textElem.style("text-anchor", textData.anchor); + textData.class !== void 0 && textElem.attr("class", textData.class); + const tspan = textElem.append("tspan"); + tspan.attr("x", textData.x + textData.textMargin * 2); + tspan.text(nText); + return textElem; +}; +const drawImage = (elem, x, y, link) => { + const imageElement = elem.append("image"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Nm)(link); + imageElement.attr("xlink:href", sanitizedLink); +}; +const drawEmbeddedImage = (element, x, y, link) => { + const imageElement = element.append("use"); + imageElement.attr("x", x); + imageElement.attr("y", y); + const sanitizedLink = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Nm)(link); + imageElement.attr("xlink:href", `#${sanitizedLink}`); +}; +const getNoteRect = () => { + const noteRectData = { + x: 0, + y: 0, + width: 100, + height: 100, + fill: "#EDF2AE", + stroke: "#666", + anchor: "start", + rx: 0, + ry: 0 + }; + return noteRectData; +}; +const getTextObj = () => { + const testObject = { + x: 0, + y: 0, + width: 100, + height: 100, + "text-anchor": "start", + style: "#666", + textMargin: 0, + rx: 0, + ry: 0, + tspan: true + }; + return testObject; +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/6046.93fe74ca.js b/assets/js/6046.93fe74ca.js new file mode 100644 index 000000000..bc57c0ac7 --- /dev/null +++ b/assets/js/6046.93fe74ca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6046],{76046:(t,e,a)=>{a.d(e,{diagram:()=>u});var r=a(82127),i=a(64218),n=a(41644),d=a(45625),o=a(56363);a(27484),a(17967),a(27856);let s=0;const l=function(t){let e=t.id;return t.type&&(e+="<"+(0,o.v)(t.type)+">"),e},p=function(t,e,a,r){const{displayText:i,cssStyle:n}=e.getDisplayDetails(),d=t.append("tspan").attr("x",r.padding).text(i);""!==n&&d.attr("style",e.cssStyle),a||d.attr("dy",r.textHeight)},c=function(t,e,a,r){o.l.debug("Rendering class ",e,a);const i=e.id,n={id:i,label:e.id,width:0,height:0},d=t.append("g").attr("id",r.db.lookUpDomId(i)).attr("class","classGroup");let s;s=e.link?d.append("svg:a").attr("xlink:href",e.link).attr("target",e.linkTarget).append("text").attr("y",a.textHeight+a.padding).attr("x",0):d.append("text").attr("y",a.textHeight+a.padding).attr("x",0);let c=!0;e.annotations.forEach((function(t){const e=s.append("tspan").text("\xab"+t+"\xbb");c||e.attr("dy",a.textHeight),c=!1}));let g=l(e);const h=s.append("tspan").text(g).attr("class","title");c||h.attr("dy",a.textHeight);const f=s.node().getBBox().height;let x,y,u;if(e.members.length>0){x=d.append("line").attr("x1",0).attr("y1",a.padding+f+a.dividerMargin/2).attr("y2",a.padding+f+a.dividerMargin/2);const t=d.append("text").attr("x",a.padding).attr("y",f+a.dividerMargin+a.textHeight).attr("fill","white").attr("class","classText");c=!0,e.members.forEach((function(e){p(t,e,c,a),c=!1})),y=t.node().getBBox()}if(e.methods.length>0){u=d.append("line").attr("x1",0).attr("y1",a.padding+f+a.dividerMargin+y.height).attr("y2",a.padding+f+a.dividerMargin+y.height);const t=d.append("text").attr("x",a.padding).attr("y",f+2*a.dividerMargin+y.height+a.textHeight).attr("fill","white").attr("class","classText");c=!0,e.methods.forEach((function(e){p(t,e,c,a),c=!1}))}const b=d.node().getBBox();var m=" ";e.cssClasses.length>0&&(m+=e.cssClasses.join(" "));const k=d.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",b.width+2*a.padding).attr("height",b.height+a.padding+.5*a.dividerMargin).attr("class",m).node().getBBox().width;return s.node().childNodes.forEach((function(t){t.setAttribute("x",(k-t.getBBox().width)/2)})),e.tooltip&&s.insert("title").text(e.tooltip),x&&x.attr("x2",k),u&&u.attr("x2",k),n.width=k,n.height=b.height+a.padding+.5*a.dividerMargin,n},g=function(t,e,a,r,n){const d=function(t){switch(t){case n.db.relationType.AGGREGATION:return"aggregation";case n.db.relationType.EXTENSION:return"extension";case n.db.relationType.COMPOSITION:return"composition";case n.db.relationType.DEPENDENCY:return"dependency";case n.db.relationType.LOLLIPOP:return"lollipop"}};e.points=e.points.filter((t=>!Number.isNaN(t.y)));const l=e.points,p=(0,i.jvg)().x((function(t){return t.x})).y((function(t){return t.y})).curve(i.$0Z),c=t.append("path").attr("d",p(l)).attr("id","edge"+s).attr("class","relation");let g,h,f="";r.arrowMarkerAbsolute&&(f=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,f=f.replace(/\(/g,"\\("),f=f.replace(/\)/g,"\\)")),1==a.relation.lineType&&c.attr("class","relation dashed-line"),10==a.relation.lineType&&c.attr("class","relation dotted-line"),"none"!==a.relation.type1&&c.attr("marker-start","url("+f+"#"+d(a.relation.type1)+"Start)"),"none"!==a.relation.type2&&c.attr("marker-end","url("+f+"#"+d(a.relation.type2)+"End)");const x=e.points.length;let y,u,b,m,k=o.u.calcLabelPosition(e.points);if(g=k.x,h=k.y,x%2!=0&&x>1){let t=o.u.calcCardinalityPosition("none"!==a.relation.type1,e.points,e.points[0]),r=o.u.calcCardinalityPosition("none"!==a.relation.type2,e.points,e.points[x-1]);o.l.debug("cardinality_1_point "+JSON.stringify(t)),o.l.debug("cardinality_2_point "+JSON.stringify(r)),y=t.x,u=t.y,b=r.x,m=r.y}if(void 0!==a.title){const e=t.append("g").attr("class","classLabel"),i=e.append("text").attr("class","label").attr("x",g).attr("y",h).attr("fill","red").attr("text-anchor","middle").text(a.title);window.label=i;const n=i.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",n.x-r.padding/2).attr("y",n.y-r.padding/2).attr("width",n.width+r.padding).attr("height",n.height+r.padding)}if(o.l.info("Rendering relation "+JSON.stringify(a)),void 0!==a.relationTitle1&&"none"!==a.relationTitle1){t.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",y).attr("y",u).attr("fill","black").attr("font-size","6").text(a.relationTitle1)}if(void 0!==a.relationTitle2&&"none"!==a.relationTitle2){t.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",b).attr("y",m).attr("fill","black").attr("font-size","6").text(a.relationTitle2)}s++},h=function(t,e,a,r){o.l.debug("Rendering note ",e,a);const i=e.id,n={id:i,text:e.text,width:0,height:0},d=t.append("g").attr("id",i).attr("class","classGroup");let s=d.append("text").attr("y",a.textHeight+a.padding).attr("x",0);const l=JSON.parse(`"${e.text}"`).split("\n");l.forEach((function(t){o.l.debug(`Adding line: ${t}`),s.append("tspan").text(t).attr("class","title").attr("dy",a.textHeight)}));const p=d.node().getBBox(),c=d.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",p.width+2*a.padding).attr("height",p.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin).node().getBBox().width;return s.node().childNodes.forEach((function(t){t.setAttribute("x",(c-t.getBBox().width)/2)})),n.width=c,n.height=p.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin,n};let f={};const x=function(t){const e=Object.entries(f).find((e=>e[1].label===t));if(e)return e[0]},y={draw:function(t,e,a,r){const s=(0,o.c)().class;f={},o.l.info("Rendering diagram "+t);const l=(0,o.c)().securityLevel;let p;"sandbox"===l&&(p=(0,i.Ys)("#i"+e));const y="sandbox"===l?(0,i.Ys)(p.nodes()[0].contentDocument.body):(0,i.Ys)("body"),u=y.select(`[id='${e}']`);var b;(b=u).append("defs").append("marker").attr("id","extensionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),b.append("defs").append("marker").attr("id","extensionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z"),b.append("defs").append("marker").attr("id","compositionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","compositionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","aggregationStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","aggregationEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","dependencyStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),b.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z");const m=new d.k({multigraph:!0});m.setGraph({isMultiGraph:!0}),m.setDefaultEdgeLabel((function(){return{}}));const k=r.db.getClasses(),w=Object.keys(k);for(const i of w){const t=k[i],e=c(u,t,s,r);f[e.id]=e,m.setNode(e.id,e),o.l.info("Org height: "+e.height)}r.db.getRelations().forEach((function(t){o.l.info("tjoho"+x(t.id1)+x(t.id2)+JSON.stringify(t)),m.setEdge(x(t.id1),x(t.id2),{relation:t},t.title||"DEFAULT")}));r.db.getNotes().forEach((function(t){o.l.debug(`Adding note: ${JSON.stringify(t)}`);const e=h(u,t,s,r);f[e.id]=e,m.setNode(e.id,e),t.class&&t.class in k&&m.setEdge(t.id,x(t.class),{relation:{id1:t.id,id2:t.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")})),(0,n.bK)(m),m.nodes().forEach((function(t){void 0!==t&&void 0!==m.node(t)&&(o.l.debug("Node "+t+": "+JSON.stringify(m.node(t))),y.select("#"+(r.db.lookUpDomId(t)||t)).attr("transform","translate("+(m.node(t).x-m.node(t).width/2)+","+(m.node(t).y-m.node(t).height/2)+" )"))})),m.edges().forEach((function(t){void 0!==t&&void 0!==m.edge(t)&&(o.l.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(m.edge(t))),g(u,m.edge(t),m.edge(t).relation,s,r))}));const L=u.node().getBBox(),v=L.width+40,E=L.height+40;(0,o.i)(u,E,v,s.useMaxWidth);const M=`${L.x-20} ${L.y-20} ${v} ${E}`;o.l.debug(`viewBox ${M}`),u.attr("viewBox",M)}},u={parser:r.p,db:r.d,renderer:y,styles:r.s,init:t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute,r.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/6048.265dbd9c.js b/assets/js/6048.265dbd9c.js deleted file mode 100644 index 70dc27d67..000000000 --- a/assets/js/6048.265dbd9c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6048],{39058:(e,t,a)=>{a.d(t,{Z:()=>P});var l=a(67294),n=a(86010),r=a(7452),o=a(87524),s=a(39960),c=a(95999);const m="sidebar_re4s",i="sidebarItemTitle_pO2u",u="sidebarItemList_Yudw",d="sidebarItem__DBe",g="sidebarItemLink_mo7H",p="sidebarItemLinkActive_I1ZP";function h(e){let{sidebar:t}=e;return l.createElement("aside",{className:"col col--3"},l.createElement("nav",{className:(0,n.Z)(m,"thin-scrollbar"),"aria-label":(0,c.I)({id:"theme.blog.sidebar.navAriaLabel",message:"Blog recent posts navigation",description:"The ARIA label for recent posts in the blog sidebar"})},l.createElement("div",{className:(0,n.Z)(i,"margin-bottom--md")},t.title),l.createElement("ul",{className:(0,n.Z)(u,"clean-list")},t.items.map((e=>l.createElement("li",{key:e.permalink,className:d},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:g,activeClassName:p},e.title)))))))}var E=a(13102);function f(e){let{sidebar:t}=e;return l.createElement("ul",{className:"menu__list"},t.items.map((e=>l.createElement("li",{key:e.permalink,className:"menu__list-item"},l.createElement(s.Z,{isNavLink:!0,to:e.permalink,className:"menu__link",activeClassName:"menu__link--active"},e.title)))))}function b(e){return l.createElement(E.Zo,{component:f,props:e})}function v(e){let{sidebar:t}=e;const a=(0,o.i)();return t?.items.length?"mobile"===a?l.createElement(b,{sidebar:t}):l.createElement(h,{sidebar:t}):null}function P(e){const{sidebar:t,toc:a,children:o,...s}=e,c=t&&t.items.length>0;return l.createElement(r.Z,s,l.createElement("div",{className:"container margin-vert--lg"},l.createElement("div",{className:"row"},l.createElement(v,{sidebar:t}),l.createElement("main",{className:(0,n.Z)("col",{"col--7":c,"col--9 col--offset-1":!c}),itemScope:!0,itemType:"http://schema.org/Blog"},o),a&&l.createElement("div",{className:"col col--2"},a))))}},30390:(e,t,a)=>{a.d(t,{Z:()=>x});var l=a(67294),n=a(86010),r=a(9460),o=a(44996);function s(e){let{children:t,className:a}=e;const{frontMatter:n,assets:s,metadata:{description:c}}=(0,r.C)(),{withBaseUrl:m}=(0,o.C)(),i=s.image??n.image,u=n.keywords??[];return l.createElement("article",{className:a,itemProp:"blogPost",itemScope:!0,itemType:"http://schema.org/BlogPosting"},c&&l.createElement("meta",{itemProp:"description",content:c}),i&&l.createElement("link",{itemProp:"image",href:m(i,{absolute:!0})}),u.length>0&&l.createElement("meta",{itemProp:"keywords",content:u.join(",")}),t)}var c=a(39960);const m="title_f1Hy";function i(e){let{className:t}=e;const{metadata:a,isBlogPostPage:o}=(0,r.C)(),{permalink:s,title:i}=a,u=o?"h1":"h2";return l.createElement(u,{className:(0,n.Z)(m,t),itemProp:"headline"},o?i:l.createElement(c.Z,{itemProp:"url",to:s},i))}var u=a(95999),d=a(88824);const g="container_mt6G";function p(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,d.c)();return t=>{const a=Math.ceil(t);return e(a,(0,u.I)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return l.createElement(l.Fragment,null,a(t))}function h(e){let{date:t,formattedDate:a}=e;return l.createElement("time",{dateTime:t,itemProp:"datePublished"},a)}function E(){return l.createElement(l.Fragment,null," \xb7 ")}function f(e){let{className:t}=e;const{metadata:a}=(0,r.C)(),{date:o,formattedDate:s,readingTime:c}=a;return l.createElement("div",{className:(0,n.Z)(g,"margin-vert--md",t)},l.createElement(h,{date:o,formattedDate:s}),void 0!==c&&l.createElement(l.Fragment,null,l.createElement(E,null),l.createElement(p,{readingTime:c})))}function b(e){return e.href?l.createElement(c.Z,e):l.createElement(l.Fragment,null,e.children)}function v(e){let{author:t,className:a}=e;const{name:r,title:o,url:s,imageURL:c,email:m}=t,i=s||m&&`mailto:${m}`||void 0;return l.createElement("div",{className:(0,n.Z)("avatar margin-bottom--sm",a)},c&&l.createElement(b,{href:i,className:"avatar__photo-link"},l.createElement("img",{className:"avatar__photo",src:c,alt:r,itemProp:"image"})),r&&l.createElement("div",{className:"avatar__intro",itemProp:"author",itemScope:!0,itemType:"https://schema.org/Person"},l.createElement("div",{className:"avatar__name"},l.createElement(b,{href:i,itemProp:"url"},l.createElement("span",{itemProp:"name"},r))),o&&l.createElement("small",{className:"avatar__subtitle",itemProp:"description"},o)))}const P="authorCol_Hf19",N="imageOnlyAuthorRow_pa_O",_="imageOnlyAuthorCol_G86a";function Z(e){let{className:t}=e;const{metadata:{authors:a},assets:o}=(0,r.C)();if(0===a.length)return null;const s=a.every((e=>{let{name:t}=e;return!t}));return l.createElement("div",{className:(0,n.Z)("margin-top--md margin-bottom--sm",s?N:"row",t)},a.map(((e,t)=>l.createElement("div",{className:(0,n.Z)(!s&&"col col--6",s?_:P),key:t},l.createElement(v,{author:{...e,imageURL:o.authorsImageUrls[t]??e.imageURL}})))))}function k(){return l.createElement("header",null,l.createElement(i,null),l.createElement(f,null),l.createElement(Z,null))}var w=a(18780),y=a(38617);function C(e){let{children:t,className:a}=e;const{isBlogPostPage:o}=(0,r.C)();return l.createElement("div",{id:o?w.blogPostContainerID:void 0,className:(0,n.Z)("markdown",a),itemProp:"articleBody"},l.createElement(y.Z,null,t))}var T=a(84881),B=a(71526),I=a(87462);function F(){return l.createElement("b",null,l.createElement(u.Z,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts"},"Read More"))}function M(e){const{blogPostTitle:t,...a}=e;return l.createElement(c.Z,(0,I.Z)({"aria-label":(0,u.I)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t})},a),l.createElement(F,null))}const L="blogPostFooterDetailsFull_mRVl";function R(){const{metadata:e,isBlogPostPage:t}=(0,r.C)(),{tags:a,title:o,editUrl:s,hasTruncateMarker:c}=e,m=!t&&c,i=a.length>0;return i||m||s?l.createElement("footer",{className:(0,n.Z)("row docusaurus-mt-lg",t&&L)},i&&l.createElement("div",{className:(0,n.Z)("col",{"col--9":m})},l.createElement(B.Z,{tags:a})),t&&s&&l.createElement("div",{className:"col margin-top--sm"},l.createElement(T.Z,{editUrl:s})),m&&l.createElement("div",{className:(0,n.Z)("col text--right",{"col--3":i})},l.createElement(M,{blogPostTitle:o,to:e.permalink}))):null}function x(e){let{children:t,className:a}=e;const o=function(){const{isBlogPostPage:e}=(0,r.C)();return e?void 0:"margin-bottom--xl"}();return l.createElement(s,{className:(0,n.Z)(o,a)},l.createElement(k,null),l.createElement(C,null,t),l.createElement(R,null))}},9460:(e,t,a)=>{a.d(t,{C:()=>s,n:()=>o});var l=a(67294),n=a(902);const r=l.createContext(null);function o(e){let{children:t,content:a,isBlogPostPage:n=!1}=e;const o=function(e){let{content:t,isBlogPostPage:a}=e;return(0,l.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,toc:t.toc,isBlogPostPage:a})),[t,a])}({content:a,isBlogPostPage:n});return l.createElement(r.Provider,{value:o},t)}function s(){const e=(0,l.useContext)(r);if(null===e)throw new n.i6("BlogPostProvider");return e}},88824:(e,t,a)=>{a.d(t,{c:()=>m});var l=a(67294),n=a(52263);const r=["zero","one","two","few","many","other"];function o(e){return r.filter((t=>e.includes(t)))}const s={locale:"en",pluralForms:o(["one","other"]),select:e=>1===e?"one":"other"};function c(){const{i18n:{currentLocale:e}}=(0,n.Z)();return(0,l.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:o(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),s}}),[e])}function m(){const e=c();return{selectMessage:(t,a)=>function(e,t,a){const l=e.split("|");if(1===l.length)return l[0];l.length>a.pluralForms.length&&console.error(`For locale=${a.locale}, a maximum of ${a.pluralForms.length} plural forms are expected (${a.pluralForms.join(",")}), but the message contains ${l.length}: ${e}`);const n=a.select(t),r=a.pluralForms.indexOf(n);return l[Math.min(r,l.length-1)]}(a,t,e)}}}}]); \ No newline at end of file diff --git a/assets/js/6254.febe09ff.js b/assets/js/6254.febe09ff.js new file mode 100644 index 000000000..6ac5af8f9 --- /dev/null +++ b/assets/js/6254.febe09ff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6254],{86254:(t,i,e)=>{e.d(i,{diagram:()=>d});var a=e(56363),n=e(64218),r=(e(27484),e(17967),e(27856),function(){var t=function(t,i,e,a){for(e=e||{},a=t.length;a--;e[t[a]]=i);return e},i=[1,3],e=[1,4],a=[1,5],n=[1,6],r=[1,7],s=[1,5,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],l=[1,5,6,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],o=[32,33,34],h=[2,7],c=[1,13],d=[1,17],u=[1,18],x=[1,19],g=[1,20],f=[1,21],y=[1,22],p=[1,23],q=[1,24],T=[1,25],A=[1,26],m=[1,27],_=[1,30],b=[1,31],S=[1,32],k=[1,33],F=[1,34],P=[1,35],v=[1,36],L=[1,37],C=[1,38],z=[1,39],E=[1,40],D=[1,41],I=[1,42],B=[1,57],w=[1,58],R=[5,22,26,32,33,34,40,41,42,43,44,45,46,47,48,49,50,51],W={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,SPACE:5,QUADRANT:6,document:7,line:8,statement:9,axisDetails:10,quadrantDetails:11,points:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,text:21,point_start:22,point_x:23,point_y:24,"X-AXIS":25,"AXIS-TEXT-DELIMITER":26,"Y-AXIS":27,QUADRANT_1:28,QUADRANT_2:29,QUADRANT_3:30,QUADRANT_4:31,NEWLINE:32,SEMI:33,EOF:34,alphaNumToken:35,textNoTagsToken:36,STR:37,MD_STR:38,alphaNum:39,PUNCTUATION:40,AMP:41,NUM:42,ALPHA:43,COMMA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,UNDERSCORE:50,MINUS:51,$accept:0,$end:1},terminals_:{2:"error",5:"SPACE",6:"QUADRANT",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",22:"point_start",23:"point_x",24:"point_y",25:"X-AXIS",26:"AXIS-TEXT-DELIMITER",27:"Y-AXIS",28:"QUADRANT_1",29:"QUADRANT_2",30:"QUADRANT_3",31:"QUADRANT_4",32:"NEWLINE",33:"SEMI",34:"EOF",37:"STR",38:"MD_STR",40:"PUNCTUATION",41:"AMP",42:"NUM",43:"ALPHA",44:"COMMA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"UNDERSCORE",51:"MINUS"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[9,0],[9,2],[9,1],[9,1],[9,1],[9,2],[9,2],[9,2],[9,1],[9,1],[12,4],[10,4],[10,3],[10,2],[10,4],[10,3],[10,2],[11,2],[11,2],[11,2],[11,2],[4,1],[4,1],[4,1],[21,1],[21,2],[21,1],[21,1],[39,1],[39,2],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[36,1],[36,1],[36,1]],performAction:function(t,i,e,a,n,r,s){var l=r.length-1;switch(n){case 12:this.$=r[l].trim(),a.setDiagramTitle(this.$);break;case 13:this.$=r[l].trim(),a.setAccTitle(this.$);break;case 14:case 15:this.$=r[l].trim(),a.setAccDescription(this.$);break;case 16:a.addSection(r[l].substr(8)),this.$=r[l].substr(8);break;case 17:a.addPoint(r[l-3],r[l-1],r[l]);break;case 18:a.setXAxisLeftText(r[l-2]),a.setXAxisRightText(r[l]);break;case 19:r[l-1].text+=" \u27f6 ",a.setXAxisLeftText(r[l-1]);break;case 20:a.setXAxisLeftText(r[l]);break;case 21:a.setYAxisBottomText(r[l-2]),a.setYAxisTopText(r[l]);break;case 22:r[l-1].text+=" \u27f6 ",a.setYAxisBottomText(r[l-1]);break;case 23:a.setYAxisBottomText(r[l]);break;case 24:a.setQuadrant1Text(r[l]);break;case 25:a.setQuadrant2Text(r[l]);break;case 26:a.setQuadrant3Text(r[l]);break;case 27:a.setQuadrant4Text(r[l]);break;case 31:case 33:this.$={text:r[l],type:"text"};break;case 32:this.$={text:r[l-1].text+""+r[l],type:r[l-1].type};break;case 34:this.$={text:r[l],type:"markdown"};break;case 35:this.$=r[l];break;case 36:this.$=r[l-1]+""+r[l]}},table:[{3:1,4:2,5:i,6:e,32:a,33:n,34:r},{1:[3]},{3:8,4:2,5:i,6:e,32:a,33:n,34:r},{3:9,4:2,5:i,6:e,32:a,33:n,34:r},t(s,[2,4],{7:10}),t(l,[2,28]),t(l,[2,29]),t(l,[2,30]),{1:[2,1]},{1:[2,2]},t(o,h,{8:11,9:12,10:14,11:15,12:16,21:28,35:29,1:[2,3],5:c,13:d,15:u,17:x,19:g,20:f,25:y,27:p,28:q,29:T,30:A,31:m,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I}),t(s,[2,5]),{4:43,32:a,33:n,34:r},t(o,h,{10:14,11:15,12:16,21:28,35:29,9:44,5:c,13:d,15:u,17:x,19:g,20:f,25:y,27:p,28:q,29:T,30:A,31:m,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I}),t(o,[2,9]),t(o,[2,10]),t(o,[2,11]),{14:[1,45]},{16:[1,46]},{18:[1,47]},t(o,[2,15]),t(o,[2,16]),{21:48,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I},{21:49,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I},{21:50,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I},{21:51,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I},{21:52,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I},{21:53,35:29,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I},{5:B,22:[1,54],35:56,36:55,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w},t(R,[2,31]),t(R,[2,33]),t(R,[2,34]),t(R,[2,37]),t(R,[2,38]),t(R,[2,39]),t(R,[2,40]),t(R,[2,41]),t(R,[2,42]),t(R,[2,43]),t(R,[2,44]),t(R,[2,45]),t(R,[2,46]),t(R,[2,47]),t(s,[2,6]),t(o,[2,8]),t(o,[2,12]),t(o,[2,13]),t(o,[2,14]),t(o,[2,20],{36:55,35:56,5:B,26:[1,59],40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w}),t(o,[2,23],{36:55,35:56,5:B,26:[1,60],40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w}),t(o,[2,24],{36:55,35:56,5:B,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w}),t(o,[2,25],{36:55,35:56,5:B,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w}),t(o,[2,26],{36:55,35:56,5:B,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w}),t(o,[2,27],{36:55,35:56,5:B,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w}),{23:[1,61]},t(R,[2,32]),t(R,[2,48]),t(R,[2,49]),t(R,[2,50]),t(o,[2,19],{35:29,21:62,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I}),t(o,[2,22],{35:29,21:63,37:_,38:b,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I}),{24:[1,64]},t(o,[2,18],{36:55,35:56,5:B,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w}),t(o,[2,21],{36:55,35:56,5:B,40:S,41:k,42:F,43:P,44:v,45:L,46:C,47:z,48:E,49:D,50:I,51:w}),t(o,[2,17])],defaultActions:{8:[2,1],9:[2,2]},parseError:function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},parse:function(t){var i=this,e=[0],a=[],n=[null],r=[],s=this.table,l="",o=0,h=0,c=r.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var g=d.yylloc;r.push(g);var f=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var y,p,q,T,A,m,_,b,S,k={};;){if(p=e[e.length-1],this.defaultActions[p]?q=this.defaultActions[p]:(null==y&&(S=void 0,"number"!=typeof(S=a.pop()||d.lex()||1)&&(S instanceof Array&&(S=(a=S).pop()),S=i.symbols_[S]||S),y=S),q=s[p]&&s[p][y]),void 0===q||!q.length||!q[0]){var F="";for(A in b=[],s[p])this.terminals_[A]&&A>2&&b.push("'"+this.terminals_[A]+"'");F=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+b.join(", ")+", got '"+(this.terminals_[y]||y)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==y?"end of input":"'"+(this.terminals_[y]||y)+"'"),this.parseError(F,{text:d.match,token:this.terminals_[y]||y,line:d.yylineno,loc:g,expected:b})}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+y);switch(q[0]){case 1:e.push(y),n.push(d.yytext),r.push(d.yylloc),e.push(q[1]),y=null,h=d.yyleng,l=d.yytext,o=d.yylineno,g=d.yylloc;break;case 2:if(m=this.productions_[q[1]][1],k.$=n[n.length-m],k._$={first_line:r[r.length-(m||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(m||1)].first_column,last_column:r[r.length-1].last_column},f&&(k._$.range=[r[r.length-(m||1)].range[0],r[r.length-1].range[1]]),void 0!==(T=this.performAction.apply(k,[l,h,o,u.yy,q[1],n,r].concat(c))))return T;m&&(e=e.slice(0,-1*m*2),n=n.slice(0,-1*m),r=r.slice(0,-1*m)),e.push(this.productions_[q[1]][0]),n.push(k.$),r.push(k._$),_=s[e[e.length-2]][e[e.length-1]],e.push(_);break;case 3:return!0}}return!0}},N={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===a.length?this.yylloc.first_column:0)+a[a.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var e,a,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((e=this._input.match(this.rules[n[r]]))&&(!i||e[0].length>i[0].length)){if(i=e,a=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,a){switch(e){case 0:case 1:case 3:break;case 2:return 32;case 4:return this.begin("title"),13;case 5:return this.popState(),"title_value";case 6:return this.begin("acc_title"),15;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),17;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 22:case 24:case 28:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 25;case 14:return 27;case 15:return 26;case 16:return 28;case 17:return 29;case 18:return 30;case 19:return 31;case 20:this.begin("md_string");break;case 21:return"MD_STR";case 23:this.begin("string");break;case 25:return"STR";case 26:return this.begin("point_start"),22;case 27:return this.begin("point_x"),23;case 29:this.popState(),this.begin("point_y");break;case 30:return this.popState(),24;case 31:return 6;case 32:return 43;case 33:return"COLON";case 34:return 45;case 35:return 44;case 36:case 37:return 46;case 38:return 47;case 39:return 49;case 40:return 50;case 41:return 48;case 42:return 41;case 43:return 51;case 44:return 42;case 45:return 5;case 46:return 33;case 47:return 40;case 48:return 34}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{point_y:{rules:[30],inclusive:!1},point_x:{rules:[29],inclusive:!1},point_start:{rules:[27,28],inclusive:!1},acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},title:{rules:[5],inclusive:!1},md_string:{rules:[21,22],inclusive:!1},string:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,23,26,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],inclusive:!0}}};function U(){this.yy={}}return W.lexer=N,U.prototype=W,W.Parser=U,new U}());r.parser=r;const s=r,l=(0,a.D)();const o=(0,a.c)();function h(t){return(0,a.d)(t.trim(),o)}const c=new class{constructor(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){var t,i,e,n,r,s,l,o,h,c,d,u,x,g,f,y,p,q;return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:(null==(t=a.A.quadrantChart)?void 0:t.chartWidth)||500,chartWidth:(null==(i=a.A.quadrantChart)?void 0:i.chartHeight)||500,titlePadding:(null==(e=a.A.quadrantChart)?void 0:e.titlePadding)||10,titleFontSize:(null==(n=a.A.quadrantChart)?void 0:n.titleFontSize)||20,quadrantPadding:(null==(r=a.A.quadrantChart)?void 0:r.quadrantPadding)||5,xAxisLabelPadding:(null==(s=a.A.quadrantChart)?void 0:s.xAxisLabelPadding)||5,yAxisLabelPadding:(null==(l=a.A.quadrantChart)?void 0:l.yAxisLabelPadding)||5,xAxisLabelFontSize:(null==(o=a.A.quadrantChart)?void 0:o.xAxisLabelFontSize)||16,yAxisLabelFontSize:(null==(h=a.A.quadrantChart)?void 0:h.yAxisLabelFontSize)||16,quadrantLabelFontSize:(null==(c=a.A.quadrantChart)?void 0:c.quadrantLabelFontSize)||16,quadrantTextTopPadding:(null==(d=a.A.quadrantChart)?void 0:d.quadrantTextTopPadding)||5,pointTextPadding:(null==(u=a.A.quadrantChart)?void 0:u.pointTextPadding)||5,pointLabelFontSize:(null==(x=a.A.quadrantChart)?void 0:x.pointLabelFontSize)||12,pointRadius:(null==(g=a.A.quadrantChart)?void 0:g.pointRadius)||5,xAxisPosition:(null==(f=a.A.quadrantChart)?void 0:f.xAxisPosition)||"top",yAxisPosition:(null==(y=a.A.quadrantChart)?void 0:y.yAxisPosition)||"left",quadrantInternalBorderStrokeWidth:(null==(p=a.A.quadrantChart)?void 0:p.quadrantInternalBorderStrokeWidth)||1,quadrantExternalBorderStrokeWidth:(null==(q=a.A.quadrantChart)?void 0:q.quadrantExternalBorderStrokeWidth)||2}}getDefaultThemeConfig(){return{quadrant1Fill:l.quadrant1Fill,quadrant2Fill:l.quadrant2Fill,quadrant3Fill:l.quadrant3Fill,quadrant4Fill:l.quadrant4Fill,quadrant1TextFill:l.quadrant1TextFill,quadrant2TextFill:l.quadrant2TextFill,quadrant3TextFill:l.quadrant3TextFill,quadrant4TextFill:l.quadrant4TextFill,quadrantPointFill:l.quadrantPointFill,quadrantPointTextFill:l.quadrantPointTextFill,quadrantXAxisTextFill:l.quadrantXAxisTextFill,quadrantYAxisTextFill:l.quadrantYAxisTextFill,quadrantTitleFill:l.quadrantTitleFill,quadrantInternalBorderStrokeFill:l.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:l.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),a.l.info("clear called")}setData(t){this.data={...this.data,...t}}addPoints(t){this.data.points=[...t,...this.data.points]}setConfig(t){a.l.trace("setConfig called with: ",t),this.config={...this.config,...t}}setThemeConfig(t){a.l.trace("setThemeConfig called with: ",t),this.themeConfig={...this.themeConfig,...t}}calculateSpace(t,i,e,a){const n=2*this.config.xAxisLabelPadding+this.config.xAxisLabelFontSize,r={top:"top"===t&&i?n:0,bottom:"bottom"===t&&i?n:0},s=2*this.config.yAxisLabelPadding+this.config.yAxisLabelFontSize,l={left:"left"===this.config.yAxisPosition&&e?s:0,right:"right"===this.config.yAxisPosition&&e?s:0},o=this.config.titleFontSize+2*this.config.titlePadding,h={top:a?o:0},c=this.config.quadrantPadding+l.left,d=this.config.quadrantPadding+r.top+h.top,u=this.config.chartWidth-2*this.config.quadrantPadding-l.left-l.right,x=this.config.chartHeight-2*this.config.quadrantPadding-r.top-r.bottom-h.top;return{xAxisSpace:r,yAxisSpace:l,titleSpace:h,quadrantSpace:{quadrantLeft:c,quadrantTop:d,quadrantWidth:u,quadrantHalfWidth:u/2,quadrantHeight:x,quadrantHalfHeight:x/2}}}getAxisLabels(t,i,e,a){const{quadrantSpace:n,titleSpace:r}=a,{quadrantHalfHeight:s,quadrantHeight:l,quadrantLeft:o,quadrantHalfWidth:h,quadrantTop:c,quadrantWidth:d}=n,u=Boolean(this.data.xAxisRightText),x=Boolean(this.data.yAxisTopText),g=[];return this.data.xAxisLeftText&&i&&g.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:o+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+l+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&i&&g.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:o+h+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+l+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&e&&g.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+o+d+this.config.quadrantPadding,y:c+l-(x?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&e&&g.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+o+d+this.config.quadrantPadding,y:c+s-(x?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),g}getQuadrants(t){const{quadrantSpace:i}=t,{quadrantHalfHeight:e,quadrantLeft:a,quadrantHalfWidth:n,quadrantTop:r}=i,s=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r,width:n,height:e,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r,width:n,height:e,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant4Fill}];for(const l of s)l.text.x=l.x+l.width/2,0===this.data.points.length?(l.text.y=l.y+l.height/2,l.text.horizontalPos="middle"):(l.text.y=l.y+this.config.quadrantTextTopPadding,l.text.horizontalPos="top");return s}getQuadrantPoints(t){const{quadrantSpace:i}=t,{quadrantHeight:e,quadrantLeft:a,quadrantTop:r,quadrantWidth:s}=i,l=(0,n.BYU)().domain([0,1]).range([a,s+a]),o=(0,n.BYU)().domain([0,1]).range([e+r,r]);return this.data.points.map((t=>({x:l(t.x),y:o(t.y),fill:this.themeConfig.quadrantPointFill,radius:this.config.pointRadius,text:{text:t.text,fill:this.themeConfig.quadrantPointTextFill,x:l(t.x),y:o(t.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0}})))}getBorders(t){const i=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:e}=t,{quadrantHalfHeight:a,quadrantHeight:n,quadrantLeft:r,quadrantHalfWidth:s,quadrantTop:l,quadrantWidth:o}=e;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:l,x2:r+o+i,y2:l},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r+o,y1:l+i,x2:r+o,y2:l+n-i},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:l+n,x2:r+o+i,y2:l+n},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r,y1:l+i,x2:r,y2:l+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+s,y1:l+i,x2:r+s,y2:l+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+i,y1:l+a,x2:r+o-i,y2:l+a}]}getTitle(t){if(t)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){const t=this.config.showXAxis&&!(!this.data.xAxisLeftText&&!this.data.xAxisRightText),i=this.config.showYAxis&&!(!this.data.yAxisTopText&&!this.data.yAxisBottomText),e=this.config.showTitle&&!!this.data.titleText,a=this.data.points.length>0?"bottom":this.config.xAxisPosition,n=this.calculateSpace(a,t,i,e);return{points:this.getQuadrantPoints(n),quadrants:this.getQuadrants(n),axisLabels:this.getAxisLabels(a,t,i,n),borderLines:this.getBorders(n),title:this.getTitle(e)}}};const d={parser:s,db:{setWidth:function(t){c.setConfig({chartWidth:t})},setHeight:function(t){c.setConfig({chartHeight:t})},setQuadrant1Text:function(t){c.setData({quadrant1Text:h(t.text)})},setQuadrant2Text:function(t){c.setData({quadrant2Text:h(t.text)})},setQuadrant3Text:function(t){c.setData({quadrant3Text:h(t.text)})},setQuadrant4Text:function(t){c.setData({quadrant4Text:h(t.text)})},setXAxisLeftText:function(t){c.setData({xAxisLeftText:h(t.text)})},setXAxisRightText:function(t){c.setData({xAxisRightText:h(t.text)})},setYAxisTopText:function(t){c.setData({yAxisTopText:h(t.text)})},setYAxisBottomText:function(t){c.setData({yAxisBottomText:h(t.text)})},addPoint:function(t,i,e){c.addPoints([{x:i,y:e,text:h(t.text)}])},getQuadrantData:function(){const t=(0,a.c)(),{themeVariables:i,quadrantChart:e}=t;return e&&c.setConfig(e),c.setThemeConfig({quadrant1Fill:i.quadrant1Fill,quadrant2Fill:i.quadrant2Fill,quadrant3Fill:i.quadrant3Fill,quadrant4Fill:i.quadrant4Fill,quadrant1TextFill:i.quadrant1TextFill,quadrant2TextFill:i.quadrant2TextFill,quadrant3TextFill:i.quadrant3TextFill,quadrant4TextFill:i.quadrant4TextFill,quadrantPointFill:i.quadrantPointFill,quadrantPointTextFill:i.quadrantPointTextFill,quadrantXAxisTextFill:i.quadrantXAxisTextFill,quadrantYAxisTextFill:i.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:i.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:i.quadrantInternalBorderStrokeFill,quadrantTitleFill:i.quadrantTitleFill}),c.setData({titleText:(0,a.r)()}),c.build()},clear:function(){c.clear(),(0,a.t)()},setAccTitle:a.s,getAccTitle:a.g,setDiagramTitle:a.q,getDiagramTitle:a.r,getAccDescription:a.a,setAccDescription:a.b},renderer:{draw:(t,i,e,r)=>{var s,l,o;function h(t){return"top"===t?"hanging":"middle"}function c(t){return"left"===t?"start":"middle"}function d(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}const u=(0,a.c)();a.l.debug("Rendering quadrant chart\n"+t);const x=u.securityLevel;let g;"sandbox"===x&&(g=(0,n.Ys)("#i"+i));const f=("sandbox"===x?(0,n.Ys)(g.nodes()[0].contentDocument.body):(0,n.Ys)("body")).select(`[id="${i}"]`),y=f.append("g").attr("class","main"),p=(null==(s=u.quadrantChart)?void 0:s.chartWidth)||500,q=(null==(l=u.quadrantChart)?void 0:l.chartHeight)||500;(0,a.i)(f,q,p,(null==(o=u.quadrantChart)?void 0:o.useMaxWidth)||!0),f.attr("viewBox","0 0 "+p+" "+q),r.db.setHeight(q),r.db.setWidth(p);const T=r.db.getQuadrantData(),A=y.append("g").attr("class","quadrants"),m=y.append("g").attr("class","border"),_=y.append("g").attr("class","data-points"),b=y.append("g").attr("class","labels"),S=y.append("g").attr("class","title");T.title&&S.append("text").attr("x",0).attr("y",0).attr("fill",T.title.fill).attr("font-size",T.title.fontSize).attr("dominant-baseline",h(T.title.horizontalPos)).attr("text-anchor",c(T.title.verticalPos)).attr("transform",d(T.title)).text(T.title.text),T.borderLines&&m.selectAll("line").data(T.borderLines).enter().append("line").attr("x1",(t=>t.x1)).attr("y1",(t=>t.y1)).attr("x2",(t=>t.x2)).attr("y2",(t=>t.y2)).style("stroke",(t=>t.strokeFill)).style("stroke-width",(t=>t.strokeWidth));const k=A.selectAll("g.quadrant").data(T.quadrants).enter().append("g").attr("class","quadrant");k.append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)),k.append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>h(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text))).text((t=>t.text.text));b.selectAll("g.label").data(T.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text((t=>t.text)).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>h(t.horizontalPos))).attr("text-anchor",(t=>c(t.verticalPos))).attr("transform",(t=>d(t)));const F=_.selectAll("g.data-point").data(T.points).enter().append("g").attr("class","data-point");F.append("circle").attr("cx",(t=>t.x)).attr("cy",(t=>t.y)).attr("r",(t=>t.radius)).attr("fill",(t=>t.fill)),F.append("text").attr("x",0).attr("y",0).text((t=>t.text.text)).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>h(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text)))}},styles:()=>""}}}]); \ No newline at end of file diff --git a/assets/js/6278.5c15eabc.js b/assets/js/6278.5c15eabc.js new file mode 100644 index 000000000..9f9cb3173 --- /dev/null +++ b/assets/js/6278.5c15eabc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6278],{36278:(t,n,e)=>{e.d(n,{diagram:()=>H});var i=e(56363),s=e(64218);function r(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e>i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e>s||void 0===e&&s>=s)&&(e=s)}return e}function o(t){return t.target.depth}function l(t,n){return t.sourceLinks.length?t.depth:n-1}function c(t,n){let e=0;if(void 0===n)for(let i of t)(i=+i)&&(e+=i);else{let i=-1;for(let s of t)(s=+n(s,++i,t))&&(e+=s)}return e}function h(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e<i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e<s||void 0===e&&s>=s)&&(e=s)}return e}function a(t){return function(){return t}}function u(t,n){return y(t.source,n.source)||t.index-n.index}function f(t,n){return y(t.target,n.target)||t.index-n.index}function y(t,n){return t.y0-n.y0}function d(t){return t.value}function p(t){return t.index}function g(t){return t.nodes}function _(t){return t.links}function x(t,n){const e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function k({nodes:t}){for(const n of t){let t=n.y0,e=t;for(const i of n.sourceLinks)i.y0=t+i.width/2,t+=i.width;for(const i of n.targetLinks)i.y1=e+i.width/2,e+=i.width}}function m(){let t,n,e,i=0,s=0,o=1,m=1,v=24,b=8,w=p,E=l,L=g,A=_,S=6;function M(){const l={nodes:L.apply(null,arguments),links:A.apply(null,arguments)};return function({nodes:t,links:n}){for(const[e,s]of t.entries())s.index=e,s.sourceLinks=[],s.targetLinks=[];const i=new Map(t.map(((n,e)=>[w(n,e,t),n])));for(const[e,s]of n.entries()){s.index=e;let{source:t,target:n}=s;"object"!=typeof t&&(t=s.source=x(i,t)),"object"!=typeof n&&(n=s.target=x(i,n)),t.sourceLinks.push(s),n.targetLinks.push(s)}if(null!=e)for(const{sourceLinks:s,targetLinks:r}of t)s.sort(e),r.sort(e)}(l),function({nodes:t}){for(const n of t)n.value=void 0===n.fixedValue?Math.max(c(n.sourceLinks,d),c(n.targetLinks,d)):n.fixedValue}(l),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.depth=s;for(const{target:n}of t.sourceLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(l),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.height=s;for(const{source:n}of t.targetLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(l),function(e){const l=function({nodes:t}){const e=h(t,(t=>t.depth))+1,s=(o-i-v)/(e-1),r=new Array(e);for(const n of t){const t=Math.max(0,Math.min(e-1,Math.floor(E.call(null,n,e))));n.layer=t,n.x0=i+t*s,n.x1=n.x0+v,r[t]?r[t].push(n):r[t]=[n]}if(n)for(const i of r)i.sort(n);return r}(e);t=Math.min(b,(m-s)/(h(l,(t=>t.length))-1)),function(n){const e=r(n,(n=>(m-s-(n.length-1)*t)/c(n,d)));for(const i of n){let n=s;for(const s of i){s.y0=n,s.y1=n+s.value*e,n=s.y1+t;for(const t of s.sourceLinks)t.width=t.value*e}n=(m-n+t)/(i.length+1);for(let t=0;t<i.length;++t){const e=i[t];e.y0+=n*(t+1),e.y1+=n*(t+1)}N(i)}}(l);for(let t=0;t<S;++t){const n=Math.pow(.99,t),e=Math.max(1-n,(t+1)/S);T(l,n,e),I(l,n,e)}}(l),k(l),l}function I(t,e,i){for(let s=1,r=t.length;s<r;++s){const r=t[s];for(const t of r){let n=0,i=0;for(const{source:e,value:r}of t.targetLinks){let s=r*(t.layer-e.layer);n+=$(e,t)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,D(t)}void 0===n&&r.sort(y),O(r,i)}}function T(t,e,i){for(let s=t.length-2;s>=0;--s){const r=t[s];for(const t of r){let n=0,i=0;for(const{target:e,value:r}of t.sourceLinks){let s=r*(e.layer-t.layer);n+=j(t,e)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,D(t)}void 0===n&&r.sort(y),O(r,i)}}function O(n,e){const i=n.length>>1,r=n[i];C(n,r.y0-t,i-1,e),P(n,r.y1+t,i+1,e),C(n,m,n.length-1,e),P(n,s,0,e)}function P(n,e,i,s){for(;i<n.length;++i){const r=n[i],o=(e-r.y0)*s;o>1e-6&&(r.y0+=o,r.y1+=o),e=r.y1+t}}function C(n,e,i,s){for(;i>=0;--i){const r=n[i],o=(r.y1-e)*s;o>1e-6&&(r.y0-=o,r.y1-=o),e=r.y0-t}}function D({sourceLinks:t,targetLinks:n}){if(void 0===e){for(const{source:{sourceLinks:t}}of n)t.sort(f);for(const{target:{targetLinks:n}}of t)n.sort(u)}}function N(t){if(void 0===e)for(const{sourceLinks:n,targetLinks:e}of t)n.sort(f),e.sort(u)}function $(n,e){let i=n.y0-(n.sourceLinks.length-1)*t/2;for(const{target:s,width:r}of n.sourceLinks){if(s===e)break;i+=r+t}for(const{source:t,width:s}of e.targetLinks){if(t===n)break;i-=s}return i}function j(n,e){let i=e.y0-(e.targetLinks.length-1)*t/2;for(const{source:s,width:r}of e.targetLinks){if(s===n)break;i+=r+t}for(const{target:t,width:s}of n.sourceLinks){if(t===e)break;i-=s}return i}return M.update=function(t){return k(t),t},M.nodeId=function(t){return arguments.length?(w="function"==typeof t?t:a(t),M):w},M.nodeAlign=function(t){return arguments.length?(E="function"==typeof t?t:a(t),M):E},M.nodeSort=function(t){return arguments.length?(n=t,M):n},M.nodeWidth=function(t){return arguments.length?(v=+t,M):v},M.nodePadding=function(n){return arguments.length?(b=t=+n,M):b},M.nodes=function(t){return arguments.length?(L="function"==typeof t?t:a(t),M):L},M.links=function(t){return arguments.length?(A="function"==typeof t?t:a(t),M):A},M.linkSort=function(t){return arguments.length?(e=t,M):e},M.size=function(t){return arguments.length?(i=s=0,o=+t[0],m=+t[1],M):[o-i,m-s]},M.extent=function(t){return arguments.length?(i=+t[0][0],o=+t[1][0],s=+t[0][1],m=+t[1][1],M):[[i,s],[o,m]]},M.iterations=function(t){return arguments.length?(S=+t,M):S},M}var v=Math.PI,b=2*v,w=1e-6,E=b-w;function L(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function A(){return new L}L.prototype=A.prototype={constructor:L,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,e,i){this._+="Q"+ +t+","+ +n+","+(this._x1=+e)+","+(this._y1=+i)},bezierCurveTo:function(t,n,e,i,s,r){this._+="C"+ +t+","+ +n+","+ +e+","+ +i+","+(this._x1=+s)+","+(this._y1=+r)},arcTo:function(t,n,e,i,s){t=+t,n=+n,e=+e,i=+i,s=+s;var r=this._x1,o=this._y1,l=e-t,c=i-n,h=r-t,a=o-n,u=h*h+a*a;if(s<0)throw new Error("negative radius: "+s);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(u>w)if(Math.abs(a*l-c*h)>w&&s){var f=e-r,y=i-o,d=l*l+c*c,p=f*f+y*y,g=Math.sqrt(d),_=Math.sqrt(u),x=s*Math.tan((v-Math.acos((d+u-p)/(2*g*_)))/2),k=x/_,m=x/g;Math.abs(k-1)>w&&(this._+="L"+(t+k*h)+","+(n+k*a)),this._+="A"+s+","+s+",0,0,"+ +(a*f>h*y)+","+(this._x1=t+m*l)+","+(this._y1=n+m*c)}else this._+="L"+(this._x1=t)+","+(this._y1=n);else;},arc:function(t,n,e,i,s,r){t=+t,n=+n,r=!!r;var o=(e=+e)*Math.cos(i),l=e*Math.sin(i),c=t+o,h=n+l,a=1^r,u=r?i-s:s-i;if(e<0)throw new Error("negative radius: "+e);null===this._x1?this._+="M"+c+","+h:(Math.abs(this._x1-c)>w||Math.abs(this._y1-h)>w)&&(this._+="L"+c+","+h),e&&(u<0&&(u=u%b+b),u>E?this._+="A"+e+","+e+",0,1,"+a+","+(t-o)+","+(n-l)+"A"+e+","+e+",0,1,"+a+","+(this._x1=c)+","+(this._y1=h):u>w&&(this._+="A"+e+","+e+",0,"+ +(u>=v)+","+a+","+(this._x1=t+e*Math.cos(s))+","+(this._y1=n+e*Math.sin(s))))},rect:function(t,n,e,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +e+"v"+ +i+"h"+-e+"Z"},toString:function(){return this._}};const S=A;var M=Array.prototype.slice;function I(t){return function(){return t}}function T(t){return t[0]}function O(t){return t[1]}function P(t){return t.source}function C(t){return t.target}function D(t){var n=P,e=C,i=T,s=O,r=null;function o(){var o,l=M.call(arguments),c=n.apply(this,l),h=e.apply(this,l);if(r||(r=o=S()),t(r,+i.apply(this,(l[0]=c,l)),+s.apply(this,l),+i.apply(this,(l[0]=h,l)),+s.apply(this,l)),o)return r=null,o+""||null}return o.source=function(t){return arguments.length?(n=t,o):n},o.target=function(t){return arguments.length?(e=t,o):e},o.x=function(t){return arguments.length?(i="function"==typeof t?t:I(+t),o):i},o.y=function(t){return arguments.length?(s="function"==typeof t?t:I(+t),o):s},o.context=function(t){return arguments.length?(r=null==t?null:t,o):r},o}function N(t,n,e,i,s){t.moveTo(n,e),t.bezierCurveTo(n=(n+i)/2,e,n,s,i,s)}function $(t){return[t.source.x1,t.y0]}function j(t){return[t.target.x0,t.y1]}function z(){return D(N).source($).target(j)}e(27484),e(17967),e(27856);var Y=function(){var t=function(t,n,e,i){for(e=e||{},i=t.length;i--;e[t[i]]=n);return e},n=[1,9],e=[1,10],i=[1,5,10,12],s={trace:function(){},yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:function(t,n,e,i,s,r,o){var l=r.length-1;switch(s){case 7:const t=i.findOrCreateNode(r[l-4].trim().replaceAll('""','"')),n=i.findOrCreateNode(r[l-2].trim().replaceAll('""','"')),e=parseFloat(r[l].trim());i.addLink(t,n,e);break;case 8:case 9:case 11:this.$=r[l];break;case 10:this.$=r[l-1]}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:n,20:e},{1:[2,6],7:11,10:[1,12]},t(e,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(i,[2,8]),t(i,[2,9]),{19:[1,16]},t(i,[2,11]),{1:[2,1]},{1:[2,5]},t(e,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:n,20:e},{15:18,16:7,17:8,18:n,20:e},{18:[1,19]},t(e,[2,3]),{12:[1,20]},t(i,[2,10]),{15:21,16:7,17:8,18:n,20:e},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:function(t,n){if(!n.recoverable){var e=new Error(t);throw e.hash=n,e}this.trace(t)},parse:function(t){var n=this,e=[0],i=[],s=[null],r=[],o=this.table,l="",c=0,h=0,a=r.slice.call(arguments,1),u=Object.create(this.lexer),f={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(f.yy[y]=this.yy[y]);u.setInput(t,f.yy),f.yy.lexer=u,f.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var d=u.yylloc;r.push(d);var p=u.options&&u.options.ranges;"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var g,_,x,k,m,v,b,w,E,L={};;){if(_=e[e.length-1],this.defaultActions[_]?x=this.defaultActions[_]:(null==g&&(E=void 0,"number"!=typeof(E=i.pop()||u.lex()||1)&&(E instanceof Array&&(E=(i=E).pop()),E=n.symbols_[E]||E),g=E),x=o[_]&&o[_][g]),void 0===x||!x.length||!x[0]){var A="";for(m in w=[],o[_])this.terminals_[m]&&m>2&&w.push("'"+this.terminals_[m]+"'");A=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[g]||g)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==g?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(A,{text:u.match,token:this.terminals_[g]||g,line:u.yylineno,loc:d,expected:w})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+g);switch(x[0]){case 1:e.push(g),s.push(u.yytext),r.push(u.yylloc),e.push(x[1]),g=null,h=u.yyleng,l=u.yytext,c=u.yylineno,d=u.yylloc;break;case 2:if(v=this.productions_[x[1]][1],L.$=s[s.length-v],L._$={first_line:r[r.length-(v||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(v||1)].first_column,last_column:r[r.length-1].last_column},p&&(L._$.range=[r[r.length-(v||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(L,[l,h,c,f.yy,x[1],s,r].concat(a))))return k;v&&(e=e.slice(0,-1*v*2),s=s.slice(0,-1*v),r=r.slice(0,-1*v)),e.push(this.productions_[x[1]][0]),s.push(L.$),r.push(L._$),b=o[e[e.length-2]][e[e.length-1]],e.push(b);break;case 3:return!0}}return!0}},r={EOF:1,parseError:function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)},setInput:function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===i.length?this.yylloc.first_column:0)+i[i.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"},test_match:function(t,n){var e,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,n,e,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((e=this._input.match(this.rules[s[r]]))&&(!n||e[0].length>n[0].length)){if(n=e,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,s[r])))return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?!1!==(t=this.test_match(n,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{easy_keword_rules:!0},performAction:function(t,n,e,i){switch(e){case 0:return this.pushState("csv"),4;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;case 5:return 20;case 6:return this.popState("escaped_text"),18;case 7:return 19}},rules:[/^(?:sankey-beta\b)/,/^(?:$)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:(\u002C))/,/^(?:(\u0022))/,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/,/^(?:(\u0022)(?!(\u0022)))/,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/],conditions:{csv:{rules:[1,2,3,4,5,6,7],inclusive:!1},escaped_text:{rules:[6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7],inclusive:!0}}};function o(){this.yy={}}return s.lexer=r,o.prototype=s,s.Parser=o,new o}();Y.parser=Y;const F=Y;let U=[],W=[],q={};class G{constructor(t,n,e=0){this.source=t,this.target=n,this.value=e}}class K{constructor(t){this.ID=t}}const V={nodesMap:q,getConfig:()=>(0,i.c)().sankey,getNodes:()=>W,getLinks:()=>U,getGraph:()=>({nodes:W.map((t=>({id:t.ID}))),links:U.map((t=>({source:t.source.ID,target:t.target.ID,value:t.value})))}),addLink:(t,n,e)=>{U.push(new G(t,n,e))},findOrCreateNode:t=>(t=i.e.sanitizeText(t,(0,i.c)()),q[t]||(q[t]=new K(t),W.push(q[t])),q[t]),getAccTitle:i.g,setAccTitle:i.s,getAccDescription:i.a,setAccDescription:i.b,getDiagramTitle:i.r,setDiagramTitle:i.q,clear:()=>{U=[],W=[],q={},(0,i.t)()}},X=class t{static next(n){return new t(n+ ++t.count)}constructor(t){this.id=t,this.href=`#${t}`}toString(){return"url("+this.href+")"}};X.count=0;let Q=X;const B={left:function(t){return t.depth},right:function(t,n){return n-1-t.height},center:function(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?r(t.sourceLinks,o)-1:0},justify:l},R={draw:function(t,n,e,r){const{securityLevel:o,sankey:l}=(0,i.c)(),c=i.I.sankey;let h;"sandbox"===o&&(h=(0,s.Ys)("#i"+n));const a="sandbox"===o?(0,s.Ys)(h.nodes()[0].contentDocument.body):(0,s.Ys)("body"),u="sandbox"===o?a.select(`[id="${n}"]`):(0,s.Ys)(`[id="${n}"]`),f=(null==l?void 0:l.width)??c.width,y=(null==l?void 0:l.height)??c.width,d=(null==l?void 0:l.useMaxWidth)??c.useMaxWidth,p=(null==l?void 0:l.nodeAlignment)??c.nodeAlignment,g=(null==l?void 0:l.prefix)??c.prefix,_=(null==l?void 0:l.suffix)??c.suffix,x=(null==l?void 0:l.showValues)??c.showValues;(0,i.i)(u,y,f,d);const k=r.db.getGraph(),v=B[p];m().nodeId((t=>t.id)).nodeWidth(10).nodePadding(10+(x?15:0)).nodeAlign(v).extent([[0,0],[f,y]])(k);const b=(0,s.PKp)(s.K2I);u.append("g").attr("class","nodes").selectAll(".node").data(k.nodes).join("g").attr("class","node").attr("id",(t=>(t.uid=Q.next("node-")).id)).attr("transform",(function(t){return"translate("+t.x0+","+t.y0+")"})).attr("x",(t=>t.x0)).attr("y",(t=>t.y0)).append("rect").attr("height",(t=>t.y1-t.y0)).attr("width",(t=>t.x1-t.x0)).attr("fill",(t=>b(t.id)));u.append("g").attr("class","node-labels").attr("font-family","sans-serif").attr("font-size",14).selectAll("text").data(k.nodes).join("text").attr("x",(t=>t.x0<f/2?t.x1+6:t.x0-6)).attr("y",(t=>(t.y1+t.y0)/2)).attr("dy",(x?"0":"0.35")+"em").attr("text-anchor",(t=>t.x0<f/2?"start":"end")).text((({id:t,value:n})=>x?`${t}\n${g}${Math.round(100*n)/100}${_}`:t));const w=u.append("g").attr("class","links").attr("fill","none").attr("stroke-opacity",.5).selectAll(".link").data(k.links).join("g").attr("class","link").style("mix-blend-mode","multiply"),E=(null==l?void 0:l.linkColor)||"gradient";if("gradient"===E){const t=w.append("linearGradient").attr("id",(t=>(t.uid=Q.next("linearGradient-")).id)).attr("gradientUnits","userSpaceOnUse").attr("x1",(t=>t.source.x1)).attr("x2",(t=>t.target.x0));t.append("stop").attr("offset","0%").attr("stop-color",(t=>b(t.source.id))),t.append("stop").attr("offset","100%").attr("stop-color",(t=>b(t.target.id)))}let L;switch(E){case"gradient":L=t=>t.uid;break;case"source":L=t=>b(t.source.id);break;case"target":L=t=>b(t.target.id);break;default:L=E}w.append("path").attr("d",z()).attr("stroke",L).attr("stroke-width",(t=>Math.max(1,t.width)))}},Z=F.parse.bind(F);F.parse=t=>Z((t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,"\n").trim())(t));const H={parser:F,db:V,renderer:R}}}]); \ No newline at end of file diff --git a/assets/js/6284.f0331339.js b/assets/js/6284.f0331339.js new file mode 100644 index 000000000..2600f88cd --- /dev/null +++ b/assets/js/6284.f0331339.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6284],{66284:(e,t,s)=>{s.d(t,{diagram:()=>N});var o=s(52244),i=s(45625),a=s(64218),r=s(56363),n=s(90360);s(27484),s(17967),s(27856),s(41644),s(39354);const d="rect",l="rectWithTitle",c="statediagram",p=`${c}-state`,b="transition",g=`${b} note-edge`,h=`${c}-note`,u=`${c}-cluster`,y=`${c}-cluster-alt`,f="parent",w="note",m="----",x=`${m}${w}`,$=`${m}${f}`,T="fill:none",S="fill: #333",k="text",D="normal";let A={},v=0;function B(e="",t=0,s="",o=m){return`state-${e}${null!==s&&s.length>0?`${o}${s}`:""}-${t}`}const C=(e,t,s,i,a,n)=>{const c=s.id,b=null==(m=i[c])?"":m.classes?m.classes.join(" "):"";var m;if("root"!==c){let t=d;!0===s.start&&(t="start"),!1===s.start&&(t="end"),s.type!==o.D&&(t=s.type),A[c]||(A[c]={id:c,shape:t,description:r.e.sanitizeText(c,(0,r.c)()),classes:`${b} ${p}`});const i=A[c];s.description&&(Array.isArray(i.description)?(i.shape=l,i.description.push(s.description)):i.description.length>0?(i.shape=l,i.description===c?i.description=[s.description]:i.description=[i.description,s.description]):(i.shape=d,i.description=s.description),i.description=r.e.sanitizeTextOrArray(i.description,(0,r.c)())),1===i.description.length&&i.shape===l&&(i.shape=d),!i.type&&s.doc&&(r.l.info("Setting cluster for ",c,R(s)),i.type="group",i.dir=R(s),i.shape=s.type===o.a?"divider":"roundedWithTitle",i.classes=i.classes+" "+u+" "+(n?y:""));const a={labelStyle:"",shape:i.shape,labelText:i.description,classes:i.classes,style:"",id:c,dir:i.dir,domId:B(c,v),type:i.type,padding:15,centerLabel:!0};if(s.note){const t={labelStyle:"",shape:"note",labelText:s.note.text,classes:h,style:"",id:c+x+"-"+v,domId:B(c,v,w),type:i.type,padding:15},o={labelStyle:"",shape:"noteGroup",labelText:s.note.text,classes:i.classes,style:"",id:c+$,domId:B(c,v,f),type:"group",padding:0};v++;const r=c+$;e.setNode(r,o),e.setNode(t.id,t),e.setNode(c,a),e.setParent(c,r),e.setParent(t.id,r);let n=c,d=t.id;"left of"===s.note.position&&(n=t.id,d=c),e.setEdge(n,d,{arrowhead:"none",arrowType:"",style:T,labelStyle:"",classes:g,arrowheadStyle:S,labelpos:"c",labelType:k,thickness:D})}else e.setNode(c,a)}t&&"root"!==t.id&&(r.l.trace("Setting node ",c," to be child of its parent ",t.id),e.setParent(c,t.id)),s.doc&&(r.l.trace("Adding nodes children "),E(e,s,s.doc,i,a,!n))},E=(e,t,s,i,a,n)=>{r.l.trace("items",s),s.forEach((s=>{switch(s.stmt){case o.b:case o.D:C(e,t,s,i,a,n);break;case o.S:{C(e,t,s.state1,i,a,n),C(e,t,s.state2,i,a,n);const o={id:"edge"+v,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:T,labelStyle:"",label:r.e.sanitizeText(s.description,(0,r.c)()),arrowheadStyle:S,labelpos:"c",labelType:k,thickness:D,classes:b};e.setEdge(s.state1.id,s.state2.id,o,v),v++}}}))},R=(e,t=o.c)=>{let s=t;if(e.doc)for(let o=0;o<e.doc.length;o++){const t=e.doc[o];"dir"===t.stmt&&(s=t.value)}return s},V={setConf:function(e){const t=Object.keys(e);for(const s of t)e[s]},getClasses:function(e,t){return t.db.extract(t.db.getRootDocV2()),t.db.getClasses()},draw:async function(e,t,s,o){r.l.info("Drawing state diagram (v2)",t),A={},o.db.getDirection();const{securityLevel:l,state:p}=(0,r.c)(),b=p.nodeSpacing||50,g=p.rankSpacing||50;r.l.info(o.db.getRootDocV2()),o.db.extract(o.db.getRootDocV2()),r.l.info(o.db.getRootDocV2());const h=o.db.getStates(),u=new i.k({multigraph:!0,compound:!0}).setGraph({rankdir:R(o.db.getRootDocV2()),nodesep:b,ranksep:g,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));let y;C(u,void 0,o.db.getRootDocV2(),h,o.db,!0),"sandbox"===l&&(y=(0,a.Ys)("#i"+t));const f="sandbox"===l?(0,a.Ys)(y.nodes()[0].contentDocument.body):(0,a.Ys)("body"),w=f.select(`[id="${t}"]`),m=f.select("#"+t+" g");await(0,n.r)(m,u,["barb"],c,t);r.u.insertTitle(w,"statediagramTitleText",p.titleTopMargin,o.db.getDiagramTitle());const x=w.node().getBBox(),$=x.width+16,T=x.height+16;w.attr("class",c);const S=w.node().getBBox();(0,r.i)(w,T,$,p.useMaxWidth);const k=`${S.x-8} ${S.y-8} ${$} ${T}`;r.l.debug(`viewBox ${k}`),w.attr("viewBox",k);const D=document.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const i of D){const e=i.getBBox(),t=document.createElementNS("http://www.w3.org/2000/svg",d);t.setAttribute("rx",0),t.setAttribute("ry",0),t.setAttribute("width",e.width),t.setAttribute("height",e.height),i.insertBefore(t,i.firstChild)}}},N={parser:o.p,db:o.d,renderer:V,styles:o.s,init:e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute,o.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/633582b9.05e73941.js b/assets/js/633582b9.6d800cdf.js similarity index 86% rename from assets/js/633582b9.05e73941.js rename to assets/js/633582b9.6d800cdf.js index 4a9f64752..5624f382a 100644 --- a/assets/js/633582b9.05e73941.js +++ b/assets/js/633582b9.6d800cdf.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2448],{32401:e=>{e.exports=JSON.parse('{"label":"Kotlin","permalink":"/tags/kotlin","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2448],{32401:e=>{e.exports=JSON.parse('{"label":"Kotlin","permalink":"/tags/kotlin","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/6552f31f.185b6073.js b/assets/js/6552f31f.185b6073.js deleted file mode 100644 index 3973139c2..000000000 --- a/assets/js/6552f31f.185b6073.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[917],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=c(r),b=a,v=m["".concat(i,".").concat(b)]||m[b]||s[b]||o;return r?n.createElement(v,p(p({ref:t},u),{},{components:r})):n.createElement(v,p({ref:t},u))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,p=new Array(o);p[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,p[1]=l;for(var c=2;c<o;c++)p[c]=r[c];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},29693:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>s,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",slug:"level2-interview-retrospective",tags:["Woowahan Techcourse","Retrospective"]},p=void 0,l={permalink:"/level2-interview-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",description:"\ub808\ubca8 \uc778\ud130\ubdf0",date:"2023-06-08T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 8\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.435,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",slug:"level2-interview-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",permalink:"/woowacourse-level2-retrospective"},nextItem:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",permalink:"/order-retrospective"}},i={authorsImageUrls:[]},c=[{value:"\ub808\ubca8 \uc778\ud130\ubdf0",id:"\ub808\ubca8-\uc778\ud130\ubdf0",level:3},{value:"API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd",id:"api-\ubb38\uc11c-\ub3c4\uad6c-\uc120\ud0dd",level:3},{value:"PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158",id:"put\uacfc-patch--\ud1a0\ud070\uacfc-\uc138\uc158",level:3},{value:"\uadf8 \uc678 \uac1c\uc120\ud560 \uc810",id:"\uadf8-\uc678-\uac1c\uc120\ud560-\uc810",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ub808\ubca8-\uc778\ud130\ubdf0"},"\ub808\ubca8 \uc778\ud130\ubdf0"),(0,a.kt)("p",null,"\ub808\ubca8 1 \ub54c\ub294 \uc900\ube44\ud574\ub454 \ub0b4\uc6a9\uc73c\ub85c \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud574\uc11c \uadf8\ub807\uac8c \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc774 \uc5c6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ub808\ubca8 1 \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0\ub294 \ub808\ubca8 1 \ud68c\uace0\ub97c \uc791\uc131\ud560 \ub54c \ub07c\uc6cc\ub123\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0\ub294 \ubc94\uc704\ub3c4 \uc81c\ud55c\ub418\uc5b4 \uc788\uc5b4 \uc5b4\ub5bb\uac8c \uc900\ube44\ud574\uc57c \ud560\uc9c0 \ub2f9\ud669\ud588\uace0, \ub2f5\ubcc0\uc5d0\ub3c4 \ubd80\uc871\ud55c \ubd80\ubd84\uc774 \ub9ce\uc558\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc5b5\uc774 \uc0ac\ub77c\uc9c0\uae30 \uc804\uc5d0 \ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\ud55c \ub0b4\uc6a9\uc744 \uc81c\uc678\ud558\uace0, \uae30\uc5b5 \ub0a8\ub294 \uac83 \uc704\uc8fc\ub85c \uc791\uc131\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"api-\ubb38\uc11c-\ub3c4\uad6c-\uc120\ud0dd"},"API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd"),(0,a.kt)("p",null,"\ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\uc744 \ud588\ub294\ub370 \uc55e\uc73c\ub85c\ub3c4 \ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \ud558\uba74\uc11c \ub3c4\uc6c0 \ub420 \uac83 \uac19\uc740 \ub0b4\uc6a9\uc774 \uc788\uc5b4\uc11c \ub0a8\uaca8\ub450\ub824\uace0 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc31\uc5d4\ub4dc \ud300\uc6d0\uc774 \ud568\uaed8 \uc758\uc0ac\uacb0\uc815\uc744 \ud588\uace0, \ubbf8\uc158 \uae30\uac04\uc774 \uc9e7\uc740 \ub9cc\ud07c \ud300 \ucc28\uc6d0\uc5d0\uc11c \ube44\uad50\uc801 \ud559\uc2b5\ud558\uae30 \uc26c\uc6b4 Swagger\ub97c \uc120\ud0dd\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ub4e4\uc5b4\uac00\ub294 \uc2dc\uac04 \ub300\ube44 \ud558\uc774 \ub9ac\ud134\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4\uace0 \ub2f5\ubcc0\ud588\ub2e4."),(0,a.kt)("p",null,"\ud300 \ucc28\uc6d0\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uc5b8\uae09\ud574\uc11c, \ub2e4\uc74c\uacfc \uac19\uc740 \uc88b\uc740 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4."),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\ud2b9\ud788 \ud300\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\ud558\ub294 \uacfc\uc815\uc744 \uacf5\uc720\ud574 \uc900 \uc810\uc774 \uc88b\uc558\uace0 \uae30\uc220\uc801 \uc758\uc0ac\uacb0\uc815 \uacfc\uc815\uc5d0\uc11c \ud300\uc758 \ud559\uc2b5\ube44\uc6a9\uc744 \uace0\ub824\ud55c \uc810\uc774 \uc88b\uc558\uc74c.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c\ub3c4 \ud559\uc2b5 \ube44\uc6a9\uc740 \uc8fc\uc694\ud558\uac8c \uace0\ub824\ud574\uc57c \ud560 \uc0ac\ud56d")),(0,a.kt)("h3",{id:"put\uacfc-patch--\ud1a0\ud070\uacfc-\uc138\uc158"},"PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158"),(0,a.kt)("p",null,"PUT\uacfc PATCH \ucc28\uc774\ub97c \uc124\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c\ub294 PATCH\ub97c \uc0ac\uc6a9\ud560 \ub54c \ud398\uc774\ub85c\ub4dc\uac00 \uc801\uc5b4\uc9c4\ub2e4\ub294 \ub0b4\uc6a9\uc744 \ube7c\uba39\uace0 \ub2f5\ubcc0\uc744 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud1a0\ud070\uacfc \uc138\uc158\uc758 \uacbd\uc6b0 \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud574\ub2ec\ub77c\ub294 \uc81c\uc57d\uc870\uac74\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ud574\ub2f9 \ub0b4\uc6a9\uc744 \ub2f5\ubcc0\ud558\uba74\uc11c \uae30\uc220\uc801\uc778 \uae4a\uc774\uac00 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2e4\uc81c\ub85c \ub808\ubca8 2 \ub54c \uc774\ub860\uc801\uc778 \ud559\uc2b5 \uc2dc\uac04\uc774 \ub9e4\uc6b0 \uc801\uc5c8\uace0, \uc9d1\uc911\ub825\ub3c4 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc5b4\ub5bb\uac8c \uae4a\uc774\ub97c \ucc44\uc6b8\uc9c0 \uace0\ubbfc\uc744 \ud560 \uc218 \uc788\ub294 \uc9c8\ubb38\ub4e4\uc774\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ucd94\uac00\ub85c \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud558\ub294 \uac00\uc815\uc744 \ub450\uace0 \ud559\uc2b5\uc744 \ud55c\ub2e4\uba74 \ud070 \ub3c4\uc6c0\uc774 \ub420 \uac70\ub77c\ub294 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4. "),(0,a.kt)("h3",{id:"\uadf8-\uc678-\uac1c\uc120\ud560-\uc810"},"\uadf8 \uc678 \uac1c\uc120\ud560 \uc810"),(0,a.kt)("p",null,"\uc778\ud130\ubdf0\ud560 \ub54c \ud2b9\uc720\uc758 \ub9d0\ubc84\ub987\uc744 \uac1c\uc120\ud558\uae30",(0,a.kt)("br",{parentName:"p"}),"\n",'\uc0dd\uac01\ud560 \uc2dc\uac04\uc744 \uac00\uc84c\uc744 \ub54c "\ub2e4\uc2dc \ub9d0\uc500\ub4dc\ub824\ub3c4 \ub420\uae4c\uc694?"\ub77c\uace0 \ub9d0\ud558\uace0 \ub2f5\ubcc0\uc744 \uc774\uc5b4\ub098\uac00\uae30',(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc220\uc801\uc73c\ub85c \uae4a\uc774\uac00 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5b4\uc11c \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\uae30",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804\uc5d0 \uacf5\ubd80\ud588\ub358\uac70 \ub418\ub3cc\uc544 \ubcf4\ub294 \uc2dc\uac04 \uac00\uc9c0\uae30"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6552f31f.46a2fccb.js b/assets/js/6552f31f.46a2fccb.js new file mode 100644 index 000000000..0ef20ef66 --- /dev/null +++ b/assets/js/6552f31f.46a2fccb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[917],{84112:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=t(85893),o=t(3905);const i={title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",slug:"level2-interview-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,s={permalink:"/level2-interview-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",description:"\ub808\ubca8 \uc778\ud130\ubdf0",date:"2023-06-08T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 8\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.435,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",slug:"level2-interview-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",permalink:"/woowacourse-level2-retrospective"},nextItem:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",permalink:"/order-retrospective"}},a={authorsImageUrls:[]},l=[{value:"\ub808\ubca8 \uc778\ud130\ubdf0",id:"\ub808\ubca8-\uc778\ud130\ubdf0",level:3},{value:"API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd",id:"api-\ubb38\uc11c-\ub3c4\uad6c-\uc120\ud0dd",level:3},{value:"PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158",id:"put\uacfc-patch--\ud1a0\ud070\uacfc-\uc138\uc158",level:3},{value:"\uadf8 \uc678 \uac1c\uc120\ud560 \uc810",id:"\uadf8-\uc678-\uac1c\uc120\ud560-\uc810",level:3}];function p(e){const r={blockquote:"blockquote",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h3,{id:"\ub808\ubca8-\uc778\ud130\ubdf0",children:"\ub808\ubca8 \uc778\ud130\ubdf0"}),"\n",(0,n.jsxs)(r.p,{children:["\ub808\ubca8 1 \ub54c\ub294 \uc900\ube44\ud574\ub454 \ub0b4\uc6a9\uc73c\ub85c \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud574\uc11c \uadf8\ub807\uac8c \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc774 \uc5c6\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub530\ub77c\uc11c \ub808\ubca8 1 \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0\ub294 \ub808\ubca8 1 \ud68c\uace0\ub97c \uc791\uc131\ud560 \ub54c \ub07c\uc6cc\ub123\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc774\ubc88\uc5d0\ub294 \ubc94\uc704\ub3c4 \uc81c\ud55c\ub418\uc5b4 \uc788\uc5b4 \uc5b4\ub5bb\uac8c \uc900\ube44\ud574\uc57c \ud560\uc9c0 \ub2f9\ud669\ud588\uace0, \ub2f5\ubcc0\uc5d0\ub3c4 \ubd80\uc871\ud55c \ubd80\ubd84\uc774 \ub9ce\uc558\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uae30\uc5b5\uc774 \uc0ac\ub77c\uc9c0\uae30 \uc804\uc5d0 \ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\ud55c \ub0b4\uc6a9\uc744 \uc81c\uc678\ud558\uace0, \uae30\uc5b5 \ub0a8\ub294 \uac83 \uc704\uc8fc\ub85c \uc791\uc131\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"api-\ubb38\uc11c-\ub3c4\uad6c-\uc120\ud0dd",children:"API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd"}),"\n",(0,n.jsxs)(r.p,{children:["\ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\uc744 \ud588\ub294\ub370 \uc55e\uc73c\ub85c\ub3c4 \ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \ud558\uba74\uc11c \ub3c4\uc6c0 \ub420 \uac83 \uac19\uc740 \ub0b4\uc6a9\uc774 \uc788\uc5b4\uc11c \ub0a8\uaca8\ub450\ub824\uace0 \ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubc31\uc5d4\ub4dc \ud300\uc6d0\uc774 \ud568\uaed8 \uc758\uc0ac\uacb0\uc815\uc744 \ud588\uace0, \ubbf8\uc158 \uae30\uac04\uc774 \uc9e7\uc740 \ub9cc\ud07c \ud300 \ucc28\uc6d0\uc5d0\uc11c \ube44\uad50\uc801 \ud559\uc2b5\ud558\uae30 \uc26c\uc6b4 Swagger\ub97c \uc120\ud0dd\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ucd94\uac00\ub85c \ub4e4\uc5b4\uac00\ub294 \uc2dc\uac04 \ub300\ube44 \ud558\uc774 \ub9ac\ud134\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4\uace0 \ub2f5\ubcc0\ud588\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:"\ud300 \ucc28\uc6d0\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uc5b8\uae09\ud574\uc11c, \ub2e4\uc74c\uacfc \uac19\uc740 \uc88b\uc740 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4."}),"\n",(0,n.jsxs)(r.blockquote,{children:["\n",(0,n.jsxs)(r.p,{children:["\ud2b9\ud788 \ud300\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\ud558\ub294 \uacfc\uc815\uc744 \uacf5\uc720\ud574 \uc900 \uc810\uc774 \uc88b\uc558\uace0 \uae30\uc220\uc801 \uc758\uc0ac\uacb0\uc815 \uacfc\uc815\uc5d0\uc11c \ud300\uc758 \ud559\uc2b5\ube44\uc6a9\uc744 \uace0\ub824\ud55c \uc810\uc774 \uc88b\uc558\uc74c.",(0,n.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c\ub3c4 \ud559\uc2b5 \ube44\uc6a9\uc740 \uc8fc\uc694\ud558\uac8c \uace0\ub824\ud574\uc57c \ud560 \uc0ac\ud56d"]}),"\n"]}),"\n",(0,n.jsx)(r.h3,{id:"put\uacfc-patch--\ud1a0\ud070\uacfc-\uc138\uc158",children:"PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158"}),"\n",(0,n.jsxs)(r.p,{children:["PUT\uacfc PATCH \ucc28\uc774\ub97c \uc124\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c\ub294 PATCH\ub97c \uc0ac\uc6a9\ud560 \ub54c \ud398\uc774\ub85c\ub4dc\uac00 \uc801\uc5b4\uc9c4\ub2e4\ub294 \ub0b4\uc6a9\uc744 \ube7c\uba39\uace0 \ub2f5\ubcc0\uc744 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud1a0\ud070\uacfc \uc138\uc158\uc758 \uacbd\uc6b0 \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud574\ub2ec\ub77c\ub294 \uc81c\uc57d\uc870\uac74\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ud574\ub2f9 \ub0b4\uc6a9\uc744 \ub2f5\ubcc0\ud558\uba74\uc11c \uae30\uc220\uc801\uc778 \uae4a\uc774\uac00 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc2e4\uc81c\ub85c \ub808\ubca8 2 \ub54c \uc774\ub860\uc801\uc778 \ud559\uc2b5 \uc2dc\uac04\uc774 \ub9e4\uc6b0 \uc801\uc5c8\uace0, \uc9d1\uc911\ub825\ub3c4 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c \uc5b4\ub5bb\uac8c \uae4a\uc774\ub97c \ucc44\uc6b8\uc9c0 \uace0\ubbfc\uc744 \ud560 \uc218 \uc788\ub294 \uc9c8\ubb38\ub4e4\uc774\uc5c8\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:"\ucd94\uac00\ub85c \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud558\ub294 \uac00\uc815\uc744 \ub450\uace0 \ud559\uc2b5\uc744 \ud55c\ub2e4\uba74 \ud070 \ub3c4\uc6c0\uc774 \ub420 \uac70\ub77c\ub294 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4."}),"\n",(0,n.jsx)(r.h3,{id:"\uadf8-\uc678-\uac1c\uc120\ud560-\uc810",children:"\uadf8 \uc678 \uac1c\uc120\ud560 \uc810"}),"\n",(0,n.jsxs)(r.p,{children:["\uc778\ud130\ubdf0\ud560 \ub54c \ud2b9\uc720\uc758 \ub9d0\ubc84\ub987\uc744 \uac1c\uc120\ud558\uae30",(0,n.jsx)(r.br,{}),"\n",'\uc0dd\uac01\ud560 \uc2dc\uac04\uc744 \uac00\uc84c\uc744 \ub54c "\ub2e4\uc2dc \ub9d0\uc500\ub4dc\ub824\ub3c4 \ub420\uae4c\uc694?"\ub77c\uace0 \ub9d0\ud558\uace0 \ub2f5\ubcc0\uc744 \uc774\uc5b4\ub098\uac00\uae30',(0,n.jsx)(r.br,{}),"\n","\uae30\uc220\uc801\uc73c\ub85c \uae4a\uc774\uac00 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5b4\uc11c \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\uae30",(0,n.jsx)(r.br,{}),"\n","\uc774\uc804\uc5d0 \uacf5\ubd80\ud588\ub358\uac70 \ub418\ub3cc\uc544 \ubcf4\ub294 \uc2dc\uac04 \uac00\uc9c0\uae30"]})]})}function u(e={}){const{wrapper:r}={...(0,o.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>l});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function c(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var a=n.createContext({}),l=function(e){var r=n.useContext(a),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},p={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},u=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),b=l(t),h=o,d=b["".concat(a,".").concat(h)]||b[h]||p[h]||i;return t?n.createElement(d,c(c({ref:r},u),{},{components:t})):n.createElement(d,c({ref:r},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/6675e9ab.ab8081ba.js b/assets/js/6675e9ab.ab8081ba.js deleted file mode 100644 index 53569cc4b..000000000 --- a/assets/js/6675e9ab.ab8081ba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1255],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>g});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),i=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=i(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=i(r),g=a,b=m["".concat(c,".").concat(g)]||m[g]||u[g]||p;return r?n.createElement(b,o(o({ref:t},s),{},{components:r})):n.createElement(b,o({ref:t},s))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var i=2;i<p;i++)o[i]=r[i];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},72336:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>p,metadata:()=>l,toc:()=>i});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",slug:"shopping-cart-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,l={permalink:"/shopping-cart-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-shopping-cart/pull/244",date:"2023-05-12T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 12\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.845,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",slug:"shopping-cart-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",permalink:"/accidental-duplication"},nextItem:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",permalink:"/web-racing-car-retrospective"}},c={authorsImageUrls:[]},i=[{value:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158",id:"\uc6f9-\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],s={toc:i};function u(e){let{components:t,...p}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,p,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-shopping-cart/pull/244"},"https://github.com/woowacourse/jwp-shopping-cart/pull/244"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-shopping-cart/pull/300"},"https://github.com/woowacourse/jwp-shopping-cart/pull/300")," ")),(0,a.kt)("h3",{id:"\uc6f9-\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158"},"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158"),(0,a.kt)("p",null,"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc740 \ube14\ub799\ucea3\uc774\ub791 \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uad6c\uc0ac\ud56d\uc774 \uc5c4\uccad \ubcf5\uc7a1\ud55c \ubbf8\uc158\uc740 \uc544\ub2c8\uc5c8\uace0, \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \uae30\ubcf8\uc801\uc778 CRUD\ub97c \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4\uc5d0\uc11c\ub294 Basic \uc778\uc99d\uc744 \ud1b5\ud574 \uc790\uc2e0\uc758 \uc7a5\ubc14\uad6c\ub2c8\uc5d0\ub9cc \uc0c1\ud488\uc744 \ub2f4\uace0, \uc81c\uac70\ud560 \uc218 \uc788\ub3c4\ub85d \uad6c\ud604\ud558\ub294 \uc694\uad6c\uc0ac\ud56d\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Interceptor\ub098 Argument Resolver\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\uac00 \ub192\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc870\uae08 \ub354 \uc54c\uc544\uac04 \ub290\ub08c\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804\uc5d0 \uc2a4\ud504\ub9c1 \uc0ac\uc6a9\ud560 \ub54c\ub294 \uc544\ubb34 \uc0dd\uac01 \uc5c6\uc774 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub294\ub370, \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \ub54c \uadfc\uac70\uac00 \uc0dd\uae30\uace0 \uc788\ub294 \uac83 \uac19\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"DTO \uc6b0\ubc1c\uc801 \uc911\ubcf5")),(0,a.kt)("p",null,"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"dto1",src:r(33946).Z,width:"2028",height:"704"})),(0,a.kt)("p",null,"\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d \ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0 \uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\uc744 \ud588\uace0, \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec \uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"\uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4.")),(0,a.kt)("p",null,"\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131 \uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ub9ac\ubdf0\uc5b4 \uc6e8\uc9c0\uac00 \uc544\ub798\uc640 \uac19\uc774 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\uace0 \uc54c\ub824\uc8fc\uc168\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"dto2",src:r(15907).Z,width:"1508",height:"896"})),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Interceptor\uc5d0\uc11c \uc778\uc99d\ud55c \uac12 \uc7ac\uc0ac\uc6a9")),(0,a.kt)("p",null,"\uc0ac\uc2e4 \uc870\ud68c\ub97c \ub450 \ubc88 \ud558\uae30 \uc2eb\uc5b4\uc11c \ub2e4\uc591\ud55c \ubc29\ubc95\uc744 \uc0dd\uac01\ud588\uc5c8\ub294\ub370 \uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 ThreadLocal\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ub2e8 Tomcat\uc740 \uc694\uccad\ub9c8\ub2e4 \ub2e4\ub978 \uc2a4\ub808\ub4dc\ub97c \uc0ac\uc6a9\ud558\uace0, Interceptor\uc5d0\uc11c \uc870\ud68c\ud574\uc11c \ub9cc\ub4e0 Credential\uc744 ThreadLocal\uc5d0 \ub123\uc5b4\ub450\uc5c8\ub2e4\uac00 ArgumentResolver\uc5d0\uc11c \uaebc\ub0b8 \ub2e4\uc74c ThreadLocal\uc744 clear \ud558\uba74 \ubb38\uc81c\uac00 \uc5c6\uc744 \uac70\ub77c \ud310\ub2e8\ud588\ub2e4. "),(0,a.kt)("p",null,"\ub9ac\ubdf0\uc5b4\uc778 \uc6e8\uc9c0\uc5d0\uac8c\ub3c4 \uc5b4\ub5a4 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560\uc9c0 \uad81\uae08\uc99d\uc744 \uc791\uc131\ud588\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6e8\uc9c0\ub294 email\uc5d0 index\ub97c \uac78\uc5b4\ub450\uace0 dao \uc7ac\uc870\ud68c\ub97c \uc0ac\uc6a9\ud560 \uac83\uc774\ub77c\uace0 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc7ac\uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 db\uc5d0 \uc778\ub371\uc2a4\ub97c \uac78 \uc0dd\uac01\uc740 \ud558\uc9c0 \ubabb\ud588\ub294\ub370, \uc81c\uc77c \uc9c1\uad00\uc801\uc774\uace0 \uc88b\uc740 \ubc29\ubc95\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uae30\ub85d")),(0,a.kt)("p",null,"\ube14\ub799\ucea3\uc740 \uae30\ub85d\uc744 \uad49\uc7a5\ud788 \uc798 \ud558\ub294 \ud06c\ub8e8\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub178\uc158\uc5d0 \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ud588\ub358 \ub0b4\uc6a9 + \uace0\ubbfc\ud588\ub358 \ubd80\ubd84 + \ud68c\uace0\ub97c \uaf3c\uaf3c\ud558\uac8c \uae30\ub85d\ud574\uc11c \uacf5\uc720\ud574 \uc8fc\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\uc801\uc73c\ub85c \uc774\ubaa8\uc9c0\ub97c \uc801\uadf9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\uc5ec \ub354\uc6b1 \uc88b\uc558\ub2e4!"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc758\uacac \uc77c\uce58\uc2dc\ud0a4\uae30")),(0,a.kt)("p",null,"\ud398\uc5b4 \uc2dc\uac04\uc740 \ud55c\uc815\ub418\uc5b4 \uc788\uace0, \uae30\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc801\ub2f9\ud788 \ud0c0\ud611\uc744 \ubd10\uc11c \uc758\uacac\uc744 \ube60\ub974\uac8c \uc218\uc6a9\ud574 \ub370\ub4dc\ub77c\uc778\uc744 \ub9de\ucd94\ub294 \uac83\ub3c4 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube14\ub799\ucea3\uc740 \ub0b4 \uc758\uacac\uc744 \uc798 \ub4e4\uc5b4\uc92c\uace0, \ub355\ubd84\uc5d0 \ub9c9\ud788\ub294 \ubd80\ubd84 \uc5c6\uc774 \ube60\ub974\uac8c \ubbf8\uc158\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ube68\ub9ac \uce5c\ud574\uc84c\uace0, \uc758\uc0ac\uc18c\ud1b5\uc774 \uc798 \ub3fc\uc11c \uc7ac\ubc0c\uac8c \ucf54\ub529\ud560 \uc218 \uc788\uc5c8\ub2e4!"))}u.isMDXComponent=!0},33946:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/dto1-ccd4f91674b224578f2b295b3fccaf2c.png"},15907:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/dto2-15b381e0a024487f54608d438e5385f9.png"}}]); \ No newline at end of file diff --git a/assets/js/6675e9ab.aea6d3a6.js b/assets/js/6675e9ab.aea6d3a6.js new file mode 100644 index 000000000..7b18b5591 --- /dev/null +++ b/assets/js/6675e9ab.aea6d3a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1255],{29218:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var n=t(85893),s=t(3905);const o={title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",slug:"shopping-cart-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,i={permalink:"/shopping-cart-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-shopping-cart/pull/244",date:"2023-05-12T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 12\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.845,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",slug:"shopping-cart-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",permalink:"/accidental-duplication"},nextItem:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",permalink:"/web-racing-car-retrospective"}},a={authorsImageUrls:[]},l=[{value:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158",id:"\uc6f9-\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function p(e){const r={a:"a",admonition:"admonition",br:"br",h3:"h3",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,n.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-shopping-cart/pull/244",children:"https://github.com/woowacourse/jwp-shopping-cart/pull/244"}),(0,n.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-shopping-cart/pull/300",children:"https://github.com/woowacourse/jwp-shopping-cart/pull/300"})]})}),"\n",(0,n.jsx)(r.h3,{id:"\uc6f9-\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158",children:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158"}),"\n",(0,n.jsxs)(r.p,{children:["\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc740 \ube14\ub799\ucea3\uc774\ub791 \uc9c4\ud589\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc694\uad6c\uc0ac\ud56d\uc774 \uc5c4\uccad \ubcf5\uc7a1\ud55c \ubbf8\uc158\uc740 \uc544\ub2c8\uc5c8\uace0, \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \uae30\ubcf8\uc801\uc778 CRUD\ub97c \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","2\ub2e8\uacc4\uc5d0\uc11c\ub294 Basic \uc778\uc99d\uc744 \ud1b5\ud574 \uc790\uc2e0\uc758 \uc7a5\ubc14\uad6c\ub2c8\uc5d0\ub9cc \uc0c1\ud488\uc744 \ub2f4\uace0, \uc81c\uac70\ud560 \uc218 \uc788\ub3c4\ub85d \uad6c\ud604\ud558\ub294 \uc694\uad6c\uc0ac\ud56d\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","Interceptor\ub098 Argument Resolver\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\uac00 \ub192\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc870\uae08 \ub354 \uc54c\uc544\uac04 \ub290\ub08c\uc774\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc774\uc804\uc5d0 \uc2a4\ud504\ub9c1 \uc0ac\uc6a9\ud560 \ub54c\ub294 \uc544\ubb34 \uc0dd\uac01 \uc5c6\uc774 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub294\ub370, \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \ub54c \uadfc\uac70\uac00 \uc0dd\uae30\uace0 \uc788\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.strong,{children:"DTO \uc6b0\ubc1c\uc801 \uc911\ubcf5"})}),"\n",(0,n.jsx)(r.p,{children:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4."}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.img,{alt:"dto1",src:t(33946).Z+"",width:"2028",height:"704"})}),"\n",(0,n.jsxs)(r.p,{children:["\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d \ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0 \uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\uc744 \ud588\uace0, \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec \uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4."]}),"\n",(0,n.jsxs)(r.ul,{children:["\n",(0,n.jsx)(r.li,{children:"\uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,n.jsx)(r.li,{children:"\uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4."}),"\n"]}),"\n",(0,n.jsxs)(r.p,{children:["\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131 \uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub530\ub77c\uc11c \ub9ac\ubdf0\uc5b4 \uc6e8\uc9c0\uac00 \uc544\ub798\uc640 \uac19\uc774 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\uace0 \uc54c\ub824\uc8fc\uc168\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.img,{alt:"dto2",src:t(15907).Z+"",width:"1508",height:"896"})}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.strong,{children:"Interceptor\uc5d0\uc11c \uc778\uc99d\ud55c \uac12 \uc7ac\uc0ac\uc6a9"})}),"\n",(0,n.jsxs)(r.p,{children:["\uc0ac\uc2e4 \uc870\ud68c\ub97c \ub450 \ubc88 \ud558\uae30 \uc2eb\uc5b4\uc11c \ub2e4\uc591\ud55c \ubc29\ubc95\uc744 \uc0dd\uac01\ud588\uc5c8\ub294\ub370 \uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 ThreadLocal\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc77c\ub2e8 Tomcat\uc740 \uc694\uccad\ub9c8\ub2e4 \ub2e4\ub978 \uc2a4\ub808\ub4dc\ub97c \uc0ac\uc6a9\ud558\uace0, Interceptor\uc5d0\uc11c \uc870\ud68c\ud574\uc11c \ub9cc\ub4e0 Credential\uc744 ThreadLocal\uc5d0 \ub123\uc5b4\ub450\uc5c8\ub2e4\uac00 ArgumentResolver\uc5d0\uc11c \uaebc\ub0b8 \ub2e4\uc74c ThreadLocal\uc744 clear \ud558\uba74 \ubb38\uc81c\uac00 \uc5c6\uc744 \uac70\ub77c \ud310\ub2e8\ud588\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ub9ac\ubdf0\uc5b4\uc778 \uc6e8\uc9c0\uc5d0\uac8c\ub3c4 \uc5b4\ub5a4 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560\uc9c0 \uad81\uae08\uc99d\uc744 \uc791\uc131\ud588\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc6e8\uc9c0\ub294 email\uc5d0 index\ub97c \uac78\uc5b4\ub450\uace0 dao \uc7ac\uc870\ud68c\ub97c \uc0ac\uc6a9\ud560 \uac83\uc774\ub77c\uace0 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc7ac\uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 db\uc5d0 \uc778\ub371\uc2a4\ub97c \uac78 \uc0dd\uac01\uc740 \ud558\uc9c0 \ubabb\ud588\ub294\ub370, \uc81c\uc77c \uc9c1\uad00\uc801\uc774\uace0 \uc88b\uc740 \ubc29\ubc95\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.strong,{children:"\uae30\ub85d"})}),"\n",(0,n.jsxs)(r.p,{children:["\ube14\ub799\ucea3\uc740 \uae30\ub85d\uc744 \uad49\uc7a5\ud788 \uc798 \ud558\ub294 \ud06c\ub8e8\uc600\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub178\uc158\uc5d0 \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ud588\ub358 \ub0b4\uc6a9 + \uace0\ubbfc\ud588\ub358 \ubd80\ubd84 + \ud68c\uace0\ub97c \uaf3c\uaf3c\ud558\uac8c \uae30\ub85d\ud574\uc11c \uacf5\uc720\ud574 \uc8fc\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ucd94\uac00\uc801\uc73c\ub85c \uc774\ubaa8\uc9c0\ub97c \uc801\uadf9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\uc5ec \ub354\uc6b1 \uc88b\uc558\ub2e4!"]}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.strong,{children:"\uc758\uacac \uc77c\uce58\uc2dc\ud0a4\uae30"})}),"\n",(0,n.jsxs)(r.p,{children:["\ud398\uc5b4 \uc2dc\uac04\uc740 \ud55c\uc815\ub418\uc5b4 \uc788\uace0, \uae30\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574\uc57c \ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub530\ub77c\uc11c \uc801\ub2f9\ud788 \ud0c0\ud611\uc744 \ubd10\uc11c \uc758\uacac\uc744 \ube60\ub974\uac8c \uc218\uc6a9\ud574 \ub370\ub4dc\ub77c\uc778\uc744 \ub9de\ucd94\ub294 \uac83\ub3c4 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ube14\ub799\ucea3\uc740 \ub0b4 \uc758\uacac\uc744 \uc798 \ub4e4\uc5b4\uc92c\uace0, \ub355\ubd84\uc5d0 \ub9c9\ud788\ub294 \ubd80\ubd84 \uc5c6\uc774 \ube60\ub974\uac8c \ubbf8\uc158\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:"\ube68\ub9ac \uce5c\ud574\uc84c\uace0, \uc758\uc0ac\uc18c\ud1b5\uc774 \uc798 \ub3fc\uc11c \uc7ac\ubc0c\uac8c \ucf54\ub529\ud560 \uc218 \uc788\uc5c8\ub2e4!"})]})}function h(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>l});var n=t(67294);function s(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function c(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){s(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function i(e,r){if(null==e)return{};var t,n,s=function(e,r){if(null==e)return{};var t,n,s={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(s[t]=e[t]);return s}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var a=n.createContext({}),l=function(e){var r=n.useContext(a),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},p={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},h=n.forwardRef((function(e,r){var t=e.components,s=e.mdxType,o=e.originalType,a=e.parentName,h=i(e,["components","mdxType","originalType","parentName"]),d=l(t),u=s,j=d["".concat(a,".").concat(u)]||d[u]||p[u]||o;return t?n.createElement(j,c(c({ref:r},h),{},{components:t})):n.createElement(j,c({ref:r},h))}));h.displayName="MDXCreateElement"},33946:(e,r,t)=>{t.d(r,{Z:()=>n});const n=t.p+"assets/images/dto1-ccd4f91674b224578f2b295b3fccaf2c.png"},15907:(e,r,t)=>{t.d(r,{Z:()=>n});const n=t.p+"assets/images/dto2-15b381e0a024487f54608d438e5385f9.png"}}]); \ No newline at end of file diff --git a/assets/js/6715.cd1e4516.js b/assets/js/6715.cd1e4516.js new file mode 100644 index 000000000..c388ceae4 --- /dev/null +++ b/assets/js/6715.cd1e4516.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6715],{46715:(t,e,r)=>{r.d(e,{diagram:()=>H});var i=r(56363),n=r(64218),a=(r(27484),r(17967),r(27856),function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,3],r=[1,6],i=[1,4],n=[1,5],a=[2,5],c=[1,12],s=[5,7,13,19,21,23,24,26,28,31,36,39,46],o=[7,13,19,21,23,24,26,28,31,36,39],l=[7,12,13,19,21,23,24,26,28,31,36,39],h=[7,13,46],m=[1,42],u=[1,41],y=[7,13,29,32,34,37,46],g=[1,55],p=[1,56],b=[1,57],d=[7,13,32,34,41,46],f={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,GG:5,document:6,EOF:7,":":8,DIR:9,options:10,body:11,OPT:12,NL:13,line:14,statement:15,commitStatement:16,mergeStatement:17,cherryPickStatement:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,section:24,branchStatement:25,CHECKOUT:26,ref:27,BRANCH:28,ORDER:29,NUM:30,CHERRY_PICK:31,COMMIT_ID:32,STR:33,COMMIT_TAG:34,EMPTYSTR:35,MERGE:36,COMMIT_TYPE:37,commitType:38,COMMIT:39,commit_arg:40,COMMIT_MSG:41,NORMAL:42,REVERSE:43,HIGHLIGHT:44,ID:45,";":46,$accept:0,$end:1},terminals_:{2:"error",5:"GG",7:"EOF",8:":",9:"DIR",12:"OPT",13:"NL",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"section",26:"CHECKOUT",28:"BRANCH",29:"ORDER",30:"NUM",31:"CHERRY_PICK",32:"COMMIT_ID",33:"STR",34:"COMMIT_TAG",35:"EMPTYSTR",36:"MERGE",37:"COMMIT_TYPE",39:"COMMIT",41:"COMMIT_MSG",42:"NORMAL",43:"REVERSE",44:"HIGHLIGHT",45:"ID",46:";"},productions_:[0,[3,2],[3,3],[3,4],[3,5],[6,0],[6,2],[10,2],[10,1],[11,0],[11,2],[14,2],[14,1],[15,1],[15,1],[15,1],[15,2],[15,2],[15,1],[15,1],[15,1],[15,2],[25,2],[25,4],[18,3],[18,5],[18,5],[18,5],[18,5],[17,2],[17,4],[17,4],[17,4],[17,6],[17,6],[17,6],[17,6],[17,6],[17,6],[17,8],[17,8],[17,8],[17,8],[17,8],[17,8],[16,2],[16,3],[16,3],[16,5],[16,5],[16,3],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,3],[16,5],[16,5],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[40,0],[40,1],[38,1],[38,1],[38,1],[27,1],[27,1],[4,1],[4,1],[4,1]],performAction:function(t,e,r,i,n,a,c){var s=a.length-1;switch(n){case 2:return a[s];case 3:return a[s-1];case 4:return i.setDirection(a[s-3]),a[s-1];case 6:i.setOptions(a[s-1]),this.$=a[s];break;case 7:a[s-1]+=a[s],this.$=a[s-1];break;case 9:this.$=[];break;case 10:a[s-1].push(a[s]),this.$=a[s-1];break;case 11:this.$=a[s-1];break;case 16:this.$=a[s].trim(),i.setAccTitle(this.$);break;case 17:case 18:this.$=a[s].trim(),i.setAccDescription(this.$);break;case 19:i.addSection(a[s].substr(8)),this.$=a[s].substr(8);break;case 21:i.checkout(a[s]);break;case 22:i.branch(a[s]);break;case 23:i.branch(a[s-2],a[s]);break;case 24:i.cherryPick(a[s],"",void 0);break;case 25:i.cherryPick(a[s-2],"",a[s]);break;case 26:case 28:i.cherryPick(a[s-2],"","");break;case 27:i.cherryPick(a[s],"",a[s-2]);break;case 29:i.merge(a[s],"","","");break;case 30:i.merge(a[s-2],a[s],"","");break;case 31:i.merge(a[s-2],"",a[s],"");break;case 32:i.merge(a[s-2],"","",a[s]);break;case 33:i.merge(a[s-4],a[s],"",a[s-2]);break;case 34:i.merge(a[s-4],"",a[s],a[s-2]);break;case 35:i.merge(a[s-4],"",a[s-2],a[s]);break;case 36:i.merge(a[s-4],a[s-2],a[s],"");break;case 37:i.merge(a[s-4],a[s-2],"",a[s]);break;case 38:i.merge(a[s-4],a[s],a[s-2],"");break;case 39:i.merge(a[s-6],a[s-4],a[s-2],a[s]);break;case 40:i.merge(a[s-6],a[s],a[s-4],a[s-2]);break;case 41:i.merge(a[s-6],a[s-4],a[s],a[s-2]);break;case 42:i.merge(a[s-6],a[s-2],a[s-4],a[s]);break;case 43:i.merge(a[s-6],a[s],a[s-2],a[s-4]);break;case 44:i.merge(a[s-6],a[s-2],a[s],a[s-4]);break;case 45:i.commit(a[s]);break;case 46:i.commit("","",i.commitType.NORMAL,a[s]);break;case 47:i.commit("","",a[s],"");break;case 48:i.commit("","",a[s],a[s-2]);break;case 49:i.commit("","",a[s-2],a[s]);break;case 50:i.commit("",a[s],i.commitType.NORMAL,"");break;case 51:i.commit("",a[s-2],i.commitType.NORMAL,a[s]);break;case 52:i.commit("",a[s],i.commitType.NORMAL,a[s-2]);break;case 53:i.commit("",a[s-2],a[s],"");break;case 54:i.commit("",a[s],a[s-2],"");break;case 55:i.commit("",a[s-4],a[s-2],a[s]);break;case 56:i.commit("",a[s-4],a[s],a[s-2]);break;case 57:i.commit("",a[s-2],a[s-4],a[s]);break;case 58:i.commit("",a[s],a[s-4],a[s-2]);break;case 59:i.commit("",a[s],a[s-2],a[s-4]);break;case 60:i.commit("",a[s-2],a[s],a[s-4]);break;case 61:i.commit(a[s],"",i.commitType.NORMAL,"");break;case 62:i.commit(a[s],"",i.commitType.NORMAL,a[s-2]);break;case 63:i.commit(a[s-2],"",i.commitType.NORMAL,a[s]);break;case 64:i.commit(a[s-2],"",a[s],"");break;case 65:i.commit(a[s],"",a[s-2],"");break;case 66:i.commit(a[s],a[s-2],i.commitType.NORMAL,"");break;case 67:i.commit(a[s-2],a[s],i.commitType.NORMAL,"");break;case 68:i.commit(a[s-4],"",a[s-2],a[s]);break;case 69:i.commit(a[s-4],"",a[s],a[s-2]);break;case 70:i.commit(a[s-2],"",a[s-4],a[s]);break;case 71:i.commit(a[s],"",a[s-4],a[s-2]);break;case 72:i.commit(a[s],"",a[s-2],a[s-4]);break;case 73:i.commit(a[s-2],"",a[s],a[s-4]);break;case 74:i.commit(a[s-4],a[s],a[s-2],"");break;case 75:i.commit(a[s-4],a[s-2],a[s],"");break;case 76:i.commit(a[s-2],a[s],a[s-4],"");break;case 77:i.commit(a[s],a[s-2],a[s-4],"");break;case 78:i.commit(a[s],a[s-4],a[s-2],"");break;case 79:i.commit(a[s-2],a[s-4],a[s],"");break;case 80:i.commit(a[s-4],a[s],i.commitType.NORMAL,a[s-2]);break;case 81:i.commit(a[s-4],a[s-2],i.commitType.NORMAL,a[s]);break;case 82:i.commit(a[s-2],a[s],i.commitType.NORMAL,a[s-4]);break;case 83:i.commit(a[s],a[s-2],i.commitType.NORMAL,a[s-4]);break;case 84:i.commit(a[s],a[s-4],i.commitType.NORMAL,a[s-2]);break;case 85:i.commit(a[s-2],a[s-4],i.commitType.NORMAL,a[s]);break;case 86:i.commit(a[s-6],a[s-4],a[s-2],a[s]);break;case 87:i.commit(a[s-6],a[s-4],a[s],a[s-2]);break;case 88:i.commit(a[s-6],a[s-2],a[s-4],a[s]);break;case 89:i.commit(a[s-6],a[s],a[s-4],a[s-2]);break;case 90:i.commit(a[s-6],a[s-2],a[s],a[s-4]);break;case 91:i.commit(a[s-6],a[s],a[s-2],a[s-4]);break;case 92:i.commit(a[s-4],a[s-6],a[s-2],a[s]);break;case 93:i.commit(a[s-4],a[s-6],a[s],a[s-2]);break;case 94:i.commit(a[s-2],a[s-6],a[s-4],a[s]);break;case 95:i.commit(a[s],a[s-6],a[s-4],a[s-2]);break;case 96:i.commit(a[s-2],a[s-6],a[s],a[s-4]);break;case 97:i.commit(a[s],a[s-6],a[s-2],a[s-4]);break;case 98:i.commit(a[s],a[s-4],a[s-2],a[s-6]);break;case 99:i.commit(a[s-2],a[s-4],a[s],a[s-6]);break;case 100:i.commit(a[s],a[s-2],a[s-4],a[s-6]);break;case 101:i.commit(a[s-2],a[s],a[s-4],a[s-6]);break;case 102:i.commit(a[s-4],a[s-2],a[s],a[s-6]);break;case 103:i.commit(a[s-4],a[s],a[s-2],a[s-6]);break;case 104:i.commit(a[s-2],a[s-4],a[s-6],a[s]);break;case 105:i.commit(a[s],a[s-4],a[s-6],a[s-2]);break;case 106:i.commit(a[s-2],a[s],a[s-6],a[s-4]);break;case 107:i.commit(a[s],a[s-2],a[s-6],a[s-4]);break;case 108:i.commit(a[s-4],a[s-2],a[s-6],a[s]);break;case 109:i.commit(a[s-4],a[s],a[s-6],a[s-2]);break;case 110:this.$="";break;case 111:this.$=a[s];break;case 112:this.$=i.commitType.NORMAL;break;case 113:this.$=i.commitType.REVERSE;break;case 114:this.$=i.commitType.HIGHLIGHT}},table:[{3:1,4:2,5:e,7:r,13:i,46:n},{1:[3]},{3:7,4:2,5:e,7:r,13:i,46:n},{6:8,7:a,8:[1,9],9:[1,10],10:11,13:c},t(s,[2,117]),t(s,[2,118]),t(s,[2,119]),{1:[2,1]},{7:[1,13]},{6:14,7:a,10:11,13:c},{8:[1,15]},t(o,[2,9],{11:16,12:[1,17]}),t(l,[2,8]),{1:[2,2]},{7:[1,18]},{6:19,7:a,10:11,13:c},{7:[2,6],13:[1,22],14:20,15:21,16:23,17:24,18:25,19:[1,26],21:[1,27],23:[1,28],24:[1,29],25:30,26:[1,31],28:[1,35],31:[1,34],36:[1,33],39:[1,32]},t(l,[2,7]),{1:[2,3]},{7:[1,36]},t(o,[2,10]),{4:37,7:r,13:i,46:n},t(o,[2,12]),t(h,[2,13]),t(h,[2,14]),t(h,[2,15]),{20:[1,38]},{22:[1,39]},t(h,[2,18]),t(h,[2,19]),t(h,[2,20]),{27:40,33:m,45:u},t(h,[2,110],{40:43,32:[1,46],33:[1,48],34:[1,44],37:[1,45],41:[1,47]}),{27:49,33:m,45:u},{32:[1,50],34:[1,51]},{27:52,33:m,45:u},{1:[2,4]},t(o,[2,11]),t(h,[2,16]),t(h,[2,17]),t(h,[2,21]),t(y,[2,115]),t(y,[2,116]),t(h,[2,45]),{33:[1,53]},{38:54,42:g,43:p,44:b},{33:[1,58]},{33:[1,59]},t(h,[2,111]),t(h,[2,29],{32:[1,60],34:[1,62],37:[1,61]}),{33:[1,63]},{33:[1,64],35:[1,65]},t(h,[2,22],{29:[1,66]}),t(h,[2,46],{32:[1,68],37:[1,67],41:[1,69]}),t(h,[2,47],{32:[1,71],34:[1,70],41:[1,72]}),t(d,[2,112]),t(d,[2,113]),t(d,[2,114]),t(h,[2,50],{34:[1,73],37:[1,74],41:[1,75]}),t(h,[2,61],{32:[1,78],34:[1,76],37:[1,77]}),{33:[1,79]},{38:80,42:g,43:p,44:b},{33:[1,81]},t(h,[2,24],{34:[1,82]}),{32:[1,83]},{32:[1,84]},{30:[1,85]},{38:86,42:g,43:p,44:b},{33:[1,87]},{33:[1,88]},{33:[1,89]},{33:[1,90]},{33:[1,91]},{33:[1,92]},{38:93,42:g,43:p,44:b},{33:[1,94]},{33:[1,95]},{38:96,42:g,43:p,44:b},{33:[1,97]},t(h,[2,30],{34:[1,99],37:[1,98]}),t(h,[2,31],{32:[1,101],34:[1,100]}),t(h,[2,32],{32:[1,102],37:[1,103]}),{33:[1,104],35:[1,105]},{33:[1,106]},{33:[1,107]},t(h,[2,23]),t(h,[2,48],{32:[1,108],41:[1,109]}),t(h,[2,52],{37:[1,110],41:[1,111]}),t(h,[2,62],{32:[1,113],37:[1,112]}),t(h,[2,49],{32:[1,114],41:[1,115]}),t(h,[2,54],{34:[1,116],41:[1,117]}),t(h,[2,65],{32:[1,119],34:[1,118]}),t(h,[2,51],{37:[1,120],41:[1,121]}),t(h,[2,53],{34:[1,122],41:[1,123]}),t(h,[2,66],{34:[1,125],37:[1,124]}),t(h,[2,63],{32:[1,127],37:[1,126]}),t(h,[2,64],{32:[1,129],34:[1,128]}),t(h,[2,67],{34:[1,131],37:[1,130]}),{38:132,42:g,43:p,44:b},{33:[1,133]},{33:[1,134]},{33:[1,135]},{33:[1,136]},{38:137,42:g,43:p,44:b},t(h,[2,25]),t(h,[2,26]),t(h,[2,27]),t(h,[2,28]),{33:[1,138]},{33:[1,139]},{38:140,42:g,43:p,44:b},{33:[1,141]},{38:142,42:g,43:p,44:b},{33:[1,143]},{33:[1,144]},{33:[1,145]},{33:[1,146]},{33:[1,147]},{33:[1,148]},{33:[1,149]},{38:150,42:g,43:p,44:b},{33:[1,151]},{33:[1,152]},{33:[1,153]},{38:154,42:g,43:p,44:b},{33:[1,155]},{38:156,42:g,43:p,44:b},{33:[1,157]},{33:[1,158]},{33:[1,159]},{38:160,42:g,43:p,44:b},{33:[1,161]},t(h,[2,36],{34:[1,162]}),t(h,[2,37],{37:[1,163]}),t(h,[2,35],{32:[1,164]}),t(h,[2,38],{34:[1,165]}),t(h,[2,33],{37:[1,166]}),t(h,[2,34],{32:[1,167]}),t(h,[2,59],{41:[1,168]}),t(h,[2,72],{32:[1,169]}),t(h,[2,60],{41:[1,170]}),t(h,[2,83],{37:[1,171]}),t(h,[2,73],{32:[1,172]}),t(h,[2,82],{37:[1,173]}),t(h,[2,58],{41:[1,174]}),t(h,[2,71],{32:[1,175]}),t(h,[2,57],{41:[1,176]}),t(h,[2,77],{34:[1,177]}),t(h,[2,70],{32:[1,178]}),t(h,[2,76],{34:[1,179]}),t(h,[2,56],{41:[1,180]}),t(h,[2,84],{37:[1,181]}),t(h,[2,55],{41:[1,182]}),t(h,[2,78],{34:[1,183]}),t(h,[2,79],{34:[1,184]}),t(h,[2,85],{37:[1,185]}),t(h,[2,69],{32:[1,186]}),t(h,[2,80],{37:[1,187]}),t(h,[2,68],{32:[1,188]}),t(h,[2,74],{34:[1,189]}),t(h,[2,75],{34:[1,190]}),t(h,[2,81],{37:[1,191]}),{33:[1,192]},{38:193,42:g,43:p,44:b},{33:[1,194]},{33:[1,195]},{38:196,42:g,43:p,44:b},{33:[1,197]},{33:[1,198]},{33:[1,199]},{33:[1,200]},{38:201,42:g,43:p,44:b},{33:[1,202]},{38:203,42:g,43:p,44:b},{33:[1,204]},{33:[1,205]},{33:[1,206]},{33:[1,207]},{33:[1,208]},{33:[1,209]},{33:[1,210]},{38:211,42:g,43:p,44:b},{33:[1,212]},{33:[1,213]},{33:[1,214]},{38:215,42:g,43:p,44:b},{33:[1,216]},{38:217,42:g,43:p,44:b},{33:[1,218]},{33:[1,219]},{33:[1,220]},{38:221,42:g,43:p,44:b},t(h,[2,39]),t(h,[2,41]),t(h,[2,40]),t(h,[2,42]),t(h,[2,44]),t(h,[2,43]),t(h,[2,100]),t(h,[2,101]),t(h,[2,98]),t(h,[2,99]),t(h,[2,103]),t(h,[2,102]),t(h,[2,107]),t(h,[2,106]),t(h,[2,105]),t(h,[2,104]),t(h,[2,109]),t(h,[2,108]),t(h,[2,97]),t(h,[2,96]),t(h,[2,95]),t(h,[2,94]),t(h,[2,92]),t(h,[2,93]),t(h,[2,91]),t(h,[2,90]),t(h,[2,89]),t(h,[2,88]),t(h,[2,86]),t(h,[2,87])],defaultActions:{7:[2,1],13:[2,2],18:[2,3],36:[2,4]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],n=[null],a=[],c=this.table,s="",o=0,l=0,h=a.slice.call(arguments,1),m=Object.create(this.lexer),u={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(u.yy[y]=this.yy[y]);m.setInput(t,u.yy),u.yy.lexer=m,u.yy.parser=this,void 0===m.yylloc&&(m.yylloc={});var g=m.yylloc;a.push(g);var p=m.options&&m.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,d,f,k,$,x,_,w,T,E={};;){if(d=r[r.length-1],this.defaultActions[d]?f=this.defaultActions[d]:(null==b&&(T=void 0,"number"!=typeof(T=i.pop()||m.lex()||1)&&(T instanceof Array&&(T=(i=T).pop()),T=e.symbols_[T]||T),b=T),f=c[d]&&c[d][b]),void 0===f||!f.length||!f[0]){var L="";for($ in w=[],c[d])this.terminals_[$]&&$>2&&w.push("'"+this.terminals_[$]+"'");L=m.showPosition?"Parse error on line "+(o+1)+":\n"+m.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(L,{text:m.match,token:this.terminals_[b]||b,line:m.yylineno,loc:g,expected:w})}if(f[0]instanceof Array&&f.length>1)throw new Error("Parse Error: multiple actions possible at state: "+d+", token: "+b);switch(f[0]){case 1:r.push(b),n.push(m.yytext),a.push(m.yylloc),r.push(f[1]),b=null,l=m.yyleng,s=m.yytext,o=m.yylineno,g=m.yylloc;break;case 2:if(x=this.productions_[f[1]][1],E.$=n[n.length-x],E._$={first_line:a[a.length-(x||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(x||1)].first_column,last_column:a[a.length-1].last_column},p&&(E._$.range=[a[a.length-(x||1)].range[0],a[a.length-1].range[1]]),void 0!==(k=this.performAction.apply(E,[s,l,o,u.yy,f[1],n,a].concat(h))))return k;x&&(r=r.slice(0,-1*x*2),n=n.slice(0,-1*x),a=a.slice(0,-1*x)),r.push(this.productions_[f[1]][0]),n.push(E.$),a.push(E._$),_=c[r[r.length-2]][r[r.length-1]],r.push(_);break;case 3:return!0}}return!0}},k={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var r,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var a in n)this[a]=n[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),a=0;a<n.length;a++)if((r=this._input.match(this.rules[n[a]]))&&(!e||r[0].length>e[0].length)){if(e=r,i=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,n[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),19;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),21;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:case 29:case 33:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 13;case 8:case 9:break;case 10:return 5;case 11:return 39;case 12:return 32;case 13:return 37;case 14:return 41;case 15:return 42;case 16:return 43;case 17:return 44;case 18:return 34;case 19:return 28;case 20:return 29;case 21:return 36;case 22:return 31;case 23:return 26;case 24:case 25:return 9;case 26:return 8;case 27:return"CARET";case 28:this.begin("options");break;case 30:return 12;case 31:return 35;case 32:this.begin("string");break;case 34:return 33;case 35:return 30;case 36:return 45;case 37:return 7}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit(?=\s|$))/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch(?=\s|$))/i,/^(?:order:)/i,/^(?:merge(?=\s|$))/i,/^(?:cherry-pick(?=\s|$))/i,/^(?:checkout(?=\s|$))/i,/^(?:LR\b)/i,/^(?:TB\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+(?=\s|$))/i,/^(?:\w([-\./\w]*[-\w])?)/i,/^(?:$)/i,/^(?:\s+)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},options:{rules:[29,30],inclusive:!1},string:{rules:[33,34],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,31,32,35,36,37,38],inclusive:!0}}};function $(){this.yy={}}return f.lexer=k,$.prototype=f,f.Parser=$,new $}());a.parser=a;const c=a;let s=(0,i.c)().gitGraph.mainBranchName,o=(0,i.c)().gitGraph.mainBranchOrder,l={},h=null,m={};m[s]={name:s,order:o};let u={};u[s]=h;let y=s,g="LR",p=0;function b(){return(0,i.x)({length:7})}let d={};const f=function(t){if(t=i.e.sanitizeText(t,(0,i.c)()),void 0===u[t]){let e=new Error('Trying to checkout branch which is not yet created. (Help try using "branch '+t+'")');throw e.hash={text:"checkout "+t,token:"checkout "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"branch '+t+'"']},e}{y=t;const e=u[y];h=l[e]}};function k(t,e,r){const i=t.indexOf(e);-1===i?t.push(r):t.splice(i,1,r)}function $(t){const e=t.reduce(((t,e)=>t.seq>e.seq?t:e),t[0]);let r="";t.forEach((function(t){r+=t===e?"\t*":"\t|"}));const n=[r,e.id,e.seq];for(let i in u)u[i]===e.id&&n.push(i);if(i.l.debug(n.join(" ")),e.parents&&2==e.parents.length){const r=l[e.parents[0]];k(t,e,r),t.push(l[e.parents[1]])}else{if(0==e.parents.length)return;{const r=l[e.parents];k(t,e,r)}}$(t=function(t,e){const r=Object.create(null);return t.reduce(((t,i)=>{const n=e(i);return r[n]||(r[n]=!0,t.push(i)),t}),[])}(t,(t=>t.id)))}const x=function(){const t=Object.keys(l).map((function(t){return l[t]}));return t.forEach((function(t){i.l.debug(t.id)})),t.sort(((t,e)=>t.seq-e.seq)),t},_={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},w={getConfig:()=>(0,i.c)().gitGraph,setDirection:function(t){g=t},setOptions:function(t){i.l.debug("options str",t),t=(t=t&&t.trim())||"{}";try{d=JSON.parse(t)}catch(e){i.l.error("error while parsing gitGraph options",e.message)}},getOptions:function(){return d},commit:function(t,e,r,n){i.l.debug("Entering commit:",t,e,r,n),e=i.e.sanitizeText(e,(0,i.c)()),t=i.e.sanitizeText(t,(0,i.c)()),n=i.e.sanitizeText(n,(0,i.c)());const a={id:e||p+"-"+b(),message:t,seq:p++,type:r||_.NORMAL,tag:n||"",parents:null==h?[]:[h.id],branch:y};h=a,l[a.id]=a,u[y]=a.id,i.l.debug("in pushCommit "+a.id)},branch:function(t,e){if(t=i.e.sanitizeText(t,(0,i.c)()),void 0!==u[t]){let e=new Error('Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout '+t+'")');throw e.hash={text:"branch "+t,token:"branch "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+t+'"']},e}u[t]=null!=h?h.id:null,m[t]={name:t,order:e?parseInt(e,10):null},f(t),i.l.debug("in createBranch")},merge:function(t,e,r,n){t=i.e.sanitizeText(t,(0,i.c)()),e=i.e.sanitizeText(e,(0,i.c)());const a=l[u[y]],c=l[u[t]];if(y===t){let e=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(void 0===a||!a){let e=new Error('Incorrect usage of "merge". Current branch ('+y+")has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["commit"]},e}if(void 0===u[t]){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") does not exist");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch "+t]},e}if(void 0===c||!c){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"commit"']},e}if(a===c){let e=new Error('Incorrect usage of "merge". Both branches have same head');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(e&&void 0!==l[e]){let i=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom Id");throw i.hash={text:"merge "+t+e+r+n,token:"merge "+t+e+r+n,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["merge "+t+" "+e+"_UNIQUE "+r+" "+n]},i}const s={id:e||p+"-"+b(),message:"merged branch "+t+" into "+y,seq:p++,parents:[null==h?null:h.id,u[t]],branch:y,type:_.MERGE,customType:r,customId:!!e,tag:n||""};h=s,l[s.id]=s,u[y]=s.id,i.l.debug(u),i.l.debug("in mergeBranch")},cherryPick:function(t,e,r){if(i.l.debug("Entering cherryPick:",t,e,r),t=i.e.sanitizeText(t,(0,i.c)()),e=i.e.sanitizeText(e,(0,i.c)()),r=i.e.sanitizeText(r,(0,i.c)()),!t||void 0===l[t]){let r=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}let n=l[t],a=n.branch;if(n.type===_.MERGE){let r=new Error('Incorrect usage of "cherryPick". Source commit should not be a merge commit');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}if(!e||void 0===l[e]){if(a===y){let r=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const c=l[u[y]];if(void 0===c||!c){let r=new Error('Incorrect usage of "cherry-pick". Current branch ('+y+")has no commits");throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const s={id:p+"-"+b(),message:"cherry-picked "+n+" into "+y,seq:p++,parents:[null==h?null:h.id,n.id],branch:y,type:_.CHERRY_PICK,tag:r??"cherry-pick:"+n.id};h=s,l[s.id]=s,u[y]=s.id,i.l.debug(u),i.l.debug("in cherryPick")}},checkout:f,prettyPrint:function(){i.l.debug(l);$([x()[0]])},clear:function(){l={},h=null;let t=(0,i.c)().gitGraph.mainBranchName,e=(0,i.c)().gitGraph.mainBranchOrder;u={},u[t]=null,m={},m[t]={name:t,order:e},y=t,p=0,(0,i.t)()},getBranchesAsObjArray:function(){return Object.values(m).map(((t,e)=>null!==t.order?t:{...t,order:parseFloat(`0.${e}`,10)})).sort(((t,e)=>t.order-e.order)).map((({name:t})=>({name:t})))},getBranches:function(){return u},getCommits:function(){return l},getCommitsArray:x,getCurrentBranch:function(){return y},getDirection:function(){return g},getHead:function(){return h},setAccTitle:i.s,getAccTitle:i.g,getAccDescription:i.a,setAccDescription:i.b,setDiagramTitle:i.q,getDiagramTitle:i.r,commitType:_};let T={};const E=0,L=1,v=2,M=3,A=4;let I={},R={},O=[],C=0,S="LR";const B=t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","text");let r=[];r="string"==typeof t?t.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(t)?t:[];for(const i of r){const t=document.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","0"),t.setAttribute("class","row"),t.textContent=i.trim(),e.appendChild(t)}return e},P=(t,e,r)=>{const n=(0,i.c)().gitGraph,a=t.append("g").attr("class","commit-bullets"),c=t.append("g").attr("class","commit-labels");let s=0;"TB"===S&&(s=30);Object.keys(e).sort(((t,r)=>e[t].seq-e[r].seq)).forEach((t=>{const i=e[t],o="TB"===S?s+10:I[i.branch].pos,l="TB"===S?I[i.branch].pos:s+10;if(r){let t,e=void 0!==i.customType&&""!==i.customType?i.customType:i.type;switch(e){case E:t="commit-normal";break;case L:t="commit-reverse";break;case v:t="commit-highlight";break;case M:t="commit-merge";break;case A:t="commit-cherry-pick";break;default:t="commit-normal"}if(e===v){const e=a.append("rect");e.attr("x",l-10),e.attr("y",o-10),e.attr("height",20),e.attr("width",20),e.attr("class",`commit ${i.id} commit-highlight${I[i.branch].index%8} ${t}-outer`),a.append("rect").attr("x",l-6).attr("y",o-6).attr("height",12).attr("width",12).attr("class",`commit ${i.id} commit${I[i.branch].index%8} ${t}-inner`)}else if(e===A)a.append("circle").attr("cx",l).attr("cy",o).attr("r",10).attr("class",`commit ${i.id} ${t}`),a.append("circle").attr("cx",l-3).attr("cy",o+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${i.id} ${t}`),a.append("circle").attr("cx",l+3).attr("cy",o+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${i.id} ${t}`),a.append("line").attr("x1",l+3).attr("y1",o+1).attr("x2",l).attr("y2",o-5).attr("stroke","#fff").attr("class",`commit ${i.id} ${t}`),a.append("line").attr("x1",l-3).attr("y1",o+1).attr("x2",l).attr("y2",o-5).attr("stroke","#fff").attr("class",`commit ${i.id} ${t}`);else{const r=a.append("circle");if(r.attr("cx",l),r.attr("cy",o),r.attr("r",i.type===M?9:10),r.attr("class",`commit ${i.id} commit${I[i.branch].index%8}`),e===M){const e=a.append("circle");e.attr("cx",l),e.attr("cy",o),e.attr("r",6),e.attr("class",`commit ${t} ${i.id} commit${I[i.branch].index%8}`)}if(e===L){a.append("path").attr("d",`M ${l-5},${o-5}L${l+5},${o+5}M${l-5},${o+5}L${l+5},${o-5}`).attr("class",`commit ${t} ${i.id} commit${I[i.branch].index%8}`)}}}if(R[i.id]="TB"===S?{x:l,y:s+10}:{x:s+10,y:o},r){const t=4,e=2;if(i.type!==A&&(i.customId&&i.type===M||i.type!==M)&&n.showCommitLabel){const r=c.append("g"),a=r.insert("rect").attr("class","commit-label-bkg"),h=r.append("text").attr("x",s).attr("y",o+25).attr("class","commit-label").text(i.id);let m=h.node().getBBox();if(a.attr("x",s+10-m.width/2-e).attr("y",o+13.5).attr("width",m.width+2*e).attr("height",m.height+2*e),"TB"===S&&(a.attr("x",l-(m.width+4*t+5)).attr("y",o-12),h.attr("x",l-(m.width+4*t)).attr("y",o+m.height-12)),"TB"!==S&&h.attr("x",s+10-m.width/2),n.rotateCommitLabel)if("TB"===S)h.attr("transform","rotate(-45, "+l+", "+o+")"),a.attr("transform","rotate(-45, "+l+", "+o+")");else{let t=-7.5-(m.width+10)/25*9.5,e=10+m.width/25*8.5;r.attr("transform","translate("+t+", "+e+") rotate(-45, "+s+", "+o+")")}}if(i.tag){const r=c.insert("polygon"),n=c.append("circle"),a=c.append("text").attr("y",o-16).attr("class","tag-label").text(i.tag);let h=a.node().getBBox();a.attr("x",s+10-h.width/2);const m=h.height/2,u=o-19.2;r.attr("class","tag-label-bkg").attr("points",`\n ${s-h.width/2-t/2},${u+e}\n ${s-h.width/2-t/2},${u-e}\n ${s+10-h.width/2-t},${u-m-e}\n ${s+10+h.width/2+t},${u-m-e}\n ${s+10+h.width/2+t},${u+m+e}\n ${s+10-h.width/2-t},${u+m+e}`),n.attr("cx",s-h.width/2+t/2).attr("cy",u).attr("r",1.5).attr("class","tag-hole"),"TB"===S&&(r.attr("class","tag-label-bkg").attr("points",`\n ${l},${s+e}\n ${l},${s-e}\n ${l+10},${s-m-e}\n ${l+10+h.width+t},${s-m-e}\n ${l+10+h.width+t},${s+m+e}\n ${l+10},${s+m+e}`).attr("transform","translate(12,12) rotate(45, "+l+","+s+")"),n.attr("cx",l+t/2).attr("cy",s).attr("transform","translate(12,12) rotate(45, "+l+","+s+")"),a.attr("x",l+5).attr("y",s+3).attr("transform","translate(14,14) rotate(45, "+l+","+s+")"))}}s+=50,s>C&&(C=s)}))},N=(t,e,r=0)=>{const i=t+Math.abs(t-e)/2;if(r>5)return i;if(O.every((t=>Math.abs(t-i)>=10)))return O.push(i),i;const n=Math.abs(t-e);return N(t,e-n/5,r+1)},G=(t,e,r,i)=>{const n=R[e.id],a=R[r.id],c=((t,e,r)=>Object.keys(r).filter((i=>r[i].branch===e.branch&&r[i].seq>t.seq&&r[i].seq<e.seq)).length>0)(e,r,i);let s,o="",l="",h=0,m=0,u=I[r.branch].index;if(c){o="A 10 10, 0, 0, 0,",l="A 10 10, 0, 0, 1,",h=10,m=10,u=I[r.branch].index;const t=n.y<a.y?N(n.y,a.y):N(a.y,n.y),e=n.x<a.x?N(n.x,a.x):N(a.x,n.x);s="TB"===S?n.x<a.x?`M ${n.x} ${n.y} L ${e-h} ${n.y} ${l} ${e} ${n.y+m} L ${e} ${a.y-h} ${o} ${e+m} ${a.y} L ${a.x} ${a.y}`:`M ${n.x} ${n.y} L ${e+h} ${n.y} ${o} ${e} ${n.y+m} L ${e} ${a.y-h} ${l} ${e-m} ${a.y} L ${a.x} ${a.y}`:n.y<a.y?`M ${n.x} ${n.y} L ${n.x} ${t-h} ${o} ${n.x+m} ${t} L ${a.x-h} ${t} ${l} ${a.x} ${t+m} L ${a.x} ${a.y}`:`M ${n.x} ${n.y} L ${n.x} ${t+h} ${l} ${n.x+m} ${t} L ${a.x-h} ${t} ${o} ${a.x} ${t-m} L ${a.x} ${a.y}`}else"TB"===S?(n.x<a.x&&(o="A 20 20, 0, 0, 0,",l="A 20 20, 0, 0, 1,",h=20,m=20,u=I[r.branch].index,s=`M ${n.x} ${n.y} L ${a.x-h} ${n.y} ${l} ${a.x} ${n.y+m} L ${a.x} ${a.y}`),n.x>a.x&&(o="A 20 20, 0, 0, 0,",l="A 20 20, 0, 0, 1,",h=20,m=20,u=I[e.branch].index,s=`M ${n.x} ${n.y} L ${n.x} ${a.y-h} ${l} ${n.x-m} ${a.y} L ${a.x} ${a.y}`),n.x===a.x&&(u=I[e.branch].index,s=`M ${n.x} ${n.y} L ${n.x+h} ${n.y} ${o} ${n.x+m} ${a.y+h} L ${a.x} ${a.y}`)):(n.y<a.y&&(o="A 20 20, 0, 0, 0,",h=20,m=20,u=I[r.branch].index,s=`M ${n.x} ${n.y} L ${n.x} ${a.y-h} ${o} ${n.x+m} ${a.y} L ${a.x} ${a.y}`),n.y>a.y&&(o="A 20 20, 0, 0, 0,",h=20,m=20,u=I[e.branch].index,s=`M ${n.x} ${n.y} L ${a.x-h} ${n.y} ${o} ${a.x} ${n.y-m} L ${a.x} ${a.y}`),n.y===a.y&&(u=I[e.branch].index,s=`M ${n.x} ${n.y} L ${n.x} ${a.y-h} ${o} ${n.x+m} ${a.y} L ${a.x} ${a.y}`));t.append("path").attr("d",s).attr("class","arrow arrow"+u%8)},H={parser:c,db:w,renderer:{draw:function(t,e,r,a){I={},R={},T={},C=0,O=[],S="LR";const c=(0,i.c)(),s=c.gitGraph;i.l.debug("in gitgraph renderer",t+"\n","id:",e,r),T=a.db.getCommits();const o=a.db.getBranchesAsObjArray();S=a.db.getDirection();const l=(0,n.Ys)(`[id="${e}"]`);let h=0;o.forEach(((t,e)=>{const r=B(t.name),i=l.append("g"),n=i.insert("g").attr("class","branchLabel"),a=n.insert("g").attr("class","label branch-label");a.node().appendChild(r);let c=r.getBBox();I[t.name]={pos:h,index:e},h+=50+(s.rotateCommitLabel?40:0)+("TB"===S?c.width/2:0),a.remove(),n.remove(),i.remove()})),P(l,T,!1),s.showBranches&&((t,e)=>{const r=(0,i.c)().gitGraph,n=t.append("g");e.forEach(((t,e)=>{const i=e%8,a=I[t.name].pos,c=n.append("line");c.attr("x1",0),c.attr("y1",a),c.attr("x2",C),c.attr("y2",a),c.attr("class","branch branch"+i),"TB"===S&&(c.attr("y1",30),c.attr("x1",a),c.attr("y2",C),c.attr("x2",a)),O.push(a);let s=t.name;const o=B(s),l=n.insert("rect"),h=n.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+i);h.node().appendChild(o);let m=o.getBBox();l.attr("class","branchLabelBkg label"+i).attr("rx",4).attr("ry",4).attr("x",-m.width-4-(!0===r.rotateCommitLabel?30:0)).attr("y",-m.height/2+8).attr("width",m.width+18).attr("height",m.height+4),h.attr("transform","translate("+(-m.width-14-(!0===r.rotateCommitLabel?30:0))+", "+(a-m.height/2-1)+")"),"TB"===S&&(l.attr("x",a-m.width/2-10).attr("y",0),h.attr("transform","translate("+(a-m.width/2-5)+", 0)")),"TB"!==S&&l.attr("transform","translate(-19, "+(a-m.height/2)+")")}))})(l,o),((t,e)=>{const r=t.append("g").attr("class","commit-arrows");Object.keys(e).forEach((t=>{const i=e[t];i.parents&&i.parents.length>0&&i.parents.forEach((t=>{G(r,e[t],i,e)}))}))})(l,T),P(l,T,!0),i.u.insertTitle(l,"gitTitleText",s.titleTopMargin,a.db.getDiagramTitle()),(0,i.y)(void 0,l,s.diagramPadding,s.useMaxWidth??c.useMaxWidth)}},styles:t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map((e=>`\n .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; }\n .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; }\n .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; }\n .label${e} { fill: ${t["git"+e]}; }\n .arrow${e} { stroke: ${t["git"+e]}; }\n `)).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/672a376b.94e40e70.js b/assets/js/672a376b.38ceaf22.js similarity index 77% rename from assets/js/672a376b.94e40e70.js rename to assets/js/672a376b.38ceaf22.js index 067dd1b5c..d07e9bea4 100644 --- a/assets/js/672a376b.94e40e70.js +++ b/assets/js/672a376b.38ceaf22.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2579],{41690:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2579],{41690:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/6780.71665265.js b/assets/js/6780.71665265.js deleted file mode 100644 index 13010a04a..000000000 --- a/assets/js/6780.71665265.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6780],{76780:(e,t,r)=>{function n(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t,r){var a,c=t.initialState;return{getState:function(){return c},dispatch:function(a,i){var l=function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}({},c);c=e(c,{type:a,props:t,payload:i}),r({state:c,prevState:l})},pendingRequests:(a=[],{add:function(e){return a.push(e),e.finally((function(){a=a.filter((function(t){return t!==e}))}))},cancelAll:function(){a.forEach((function(e){return e.cancel()}))},isEmpty:function(){return 0===a.length}})}}function c(e){return e.reduce((function(e,t){return e.concat(t)}),[])}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){s(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function s(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function u(e){return 0===e.collections.length?0:e.collections.reduce((function(e,t){return e+t.items.length}),0)}r.r(t),r.d(t,{DocSearchModal:()=>Dr});var f=0;var m=function(){};function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function d(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function h(e,t){var r=[];return Promise.resolve(e(t)).then((function(e){return Array.isArray(e),Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,r.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));r.push(e.sourceId);var t=function(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){d(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}({getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:m},e);return Promise.resolve(t)})))}))}function v(e){return function(e){if(Array.isArray(e))return y(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return y(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return y(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function y(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function g(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function b(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?g(Object(r),!0).forEach((function(t){O(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):g(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function O(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function S(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function E(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?S(Object(r),!0).forEach((function(t){j(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):S(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function j(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function w(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function P(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?w(Object(r),!0).forEach((function(t){I(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):w(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function I(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function D(e){return function(e){if(Array.isArray(e))return C(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return C(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return C(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function C(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function k(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function A(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?k(Object(r),!0).forEach((function(t){x(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):k(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function x(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function N(e){return Boolean(e.execute)}function R(e,t){return r=e,Boolean(null==r?void 0:r.execute)?A(A({},e),{},{requests:e.queries.map((function(r){return{query:r,sourceId:t,transformResponse:e.transformResponse}}))}):{items:e,sourceId:t};var r}function _(e){var t=e.reduce((function(e,t){if(!N(t))return e.push(t),e;var r=t.searchClient,n=t.execute,o=t.requesterId,a=t.requests,c=e.find((function(e){return N(t)&&N(e)&&e.searchClient===r&&Boolean(o)&&e.requesterId===o}));if(c){var i;(i=c.items).push.apply(i,D(a))}else{var l={execute:n,requesterId:o,items:a,searchClient:r};e.push(l)}return e}),[]).map((function(e){if(!N(e))return Promise.resolve(e);var t=e,r=t.execute,n=t.items;return r({searchClient:t.searchClient,requests:n})}));return Promise.all(t).then((function(e){return c(e)}))}function q(e,t){return t.map((function(t){var r=e.filter((function(e){return e.sourceId===t.sourceId})),n=r.map((function(e){return e.items})),o=r[0].transformResponse,a=o?o(function(e){var t=e.map((function(e){var t;return P(P({},e),{},{hits:null===(t=e.hits)||void 0===t?void 0:t.map((function(t){return P(P({},t),{},{__autocomplete_indexName:e.index,__autocomplete_queryID:e.queryID})}))})}));return{results:t,hits:t.map((function(e){return e.hits})).filter(Boolean),facetHits:t.map((function(e){var t;return null===(t=e.facetHits)||void 0===t?void 0:t.map((function(e){return{label:e.value,count:e.count,_highlightResult:{label:{value:e.highlighted}}}}))})).filter(Boolean)}}(n)):n;return Array.isArray(a),a.every(Boolean),'The `getItems` function from source "'.concat(t.sourceId,'" must return an array of items but returned ').concat(JSON.stringify(void 0),".\n\nDid you forget to return items?\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems"),{source:t,items:a}}))}function T(e,t){var r=t;return{then:function(t,n){return T(e.then(H(t,r,e),H(n,r,e)),r)},catch:function(t){return T(e.catch(H(t,r,e)),r)},finally:function(t){return t&&r.onCancelList.push(t),T(e.finally(H(t&&function(){return r.onCancelList=[],t()},r,e)),r)},cancel:function(){r.isCanceled=!0;var e=r.onCancelList;r.onCancelList=[],e.forEach((function(e){e()}))},isCanceled:function(){return!0===r.isCanceled}}}function L(e){return T(new Promise((function(t,r){return e(t,r)})),{isCanceled:!1,onCancelList:[]})}function M(e){return T(e,{isCanceled:!1,onCancelList:[]})}function H(e,t,r){return e?function(r){return t.isCanceled?r:e(r)}:r}function F(e){var t=function(e){var t=e.collections.map((function(e){return e.items.length})).reduce((function(e,t,r){var n=(e[r-1]||0)+t;return e.push(n),e}),[]).reduce((function(t,r){return r<=e.activeItemId?t+1:t}),0);return e.collections[t]}(e);if(!t)return null;var r=t.items[function(e){for(var t=e.state,r=e.collection,n=!1,o=0,a=0;!1===n;){var c=t.collections[o];if(c===r){n=!0;break}a+=c.items.length,o++}return t.activeItemId-a}({state:e,collection:t})],n=t.source;return{item:r,itemInputValue:n.getItemInputValue({item:r,state:e}),itemUrl:n.getItemUrl({item:r,state:e}),source:n}}L.resolve=function(e){return M(Promise.resolve(e))},L.reject=function(e){return M(Promise.reject(e))};var U=["event","nextState","props","query","refresh","store"];function B(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function V(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?B(Object(r),!0).forEach((function(t){K(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):B(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function K(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function J(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var $,z,W,Q=null,Z=($=-1,z=-1,W=void 0,function(e){var t=++$;return Promise.resolve(e).then((function(e){return W&&t<z?W:(z=t,W=e,e)}))});function Y(e){var t=e.event,r=e.nextState,n=void 0===r?{}:r,o=e.props,a=e.query,i=e.refresh,l=e.store,s=J(e,U);Q&&o.environment.clearTimeout(Q);var u=s.setCollections,f=s.setIsOpen,m=s.setQuery,p=s.setActiveItemId,d=s.setStatus;if(m(a),p(o.defaultActiveItemId),!a&&!1===o.openOnFocus){var h,v=l.getState().collections.map((function(e){return V(V({},e),{},{items:[]})}));d("idle"),u(v),f(null!==(h=n.isOpen)&&void 0!==h?h:o.shouldPanelOpen({state:l.getState()}));var y=M(Z(v).then((function(){return Promise.resolve()})));return l.pendingRequests.add(y)}d("loading"),Q=o.environment.setTimeout((function(){d("stalled")}),o.stallThreshold);var g=M(Z(o.getSources(V({query:a,refresh:i,state:l.getState()},s)).then((function(e){return Promise.all(e.map((function(e){return Promise.resolve(e.getItems(V({query:a,refresh:i,state:l.getState()},s))).then((function(t){return R(t,e.sourceId)}))}))).then(_).then((function(t){return q(t,e)})).then((function(e){return function(e){var t=e.collections,r=e.props,n=e.state,o=t.reduce((function(e,t){return E(E({},e),{},j({},t.source.sourceId,E(E({},t.source),{},{getItems:function(){return c(t.items)}})))}),{});return c(r.reshape({sources:Object.values(o),sourcesBySourceId:o,state:n})).filter(Boolean).map((function(e){return{source:e,items:e.getItems()}}))}({collections:e,props:o,state:l.getState()})}))})))).then((function(e){var r;d("idle"),u(e);var c=o.shouldPanelOpen({state:l.getState()});f(null!==(r=n.isOpen)&&void 0!==r?r:o.openOnFocus&&!a&&c||c);var m=F(l.getState());if(null!==l.getState().activeItemId&&m){var p=m.item,h=m.itemInputValue,v=m.itemUrl,y=m.source;y.onActive(V({event:t,item:p,itemInputValue:h,itemUrl:v,refresh:i,source:y,state:l.getState()},s))}})).finally((function(){d("idle"),Q&&o.environment.clearTimeout(Q)}));return l.pendingRequests.add(g)}var G=["event","props","refresh","store"];function X(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function ee(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?X(Object(r),!0).forEach((function(t){te(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):X(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function te(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function re(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var ne=/((gt|sm)-|galaxy nexus)|samsung[- ]/i;var oe=["props","refresh","store"],ae=["inputElement","formElement","panelElement"],ce=["inputElement"],ie=["inputElement","maxLength"],le=["item","source"];function se(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function ue(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?se(Object(r),!0).forEach((function(t){fe(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):se(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function fe(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function me(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function pe(e){var t=e.props,r=e.refresh,n=e.store,o=me(e,oe);return{getEnvironmentProps:function(e){var r=e.inputElement,o=e.formElement,a=e.panelElement;function c(e){!n.getState().isOpen&&n.pendingRequests.isEmpty()||e.target===r||!1===[o,a].some((function(t){return r=t,n=e.target,r===n||r.contains(n);var r,n}))&&(n.dispatch("blur",null),t.debug||n.pendingRequests.cancelAll())}return ue({onTouchStart:c,onMouseDown:c,onTouchMove:function(e){!1!==n.getState().isOpen&&r===t.environment.document.activeElement&&e.target!==r&&r.blur()}},me(e,ae))},getRootProps:function(e){return ue({role:"combobox","aria-expanded":n.getState().isOpen,"aria-haspopup":"listbox","aria-owns":n.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label")},e)},getFormProps:function(e){e.inputElement;return ue({action:"",noValidate:!0,role:"search",onSubmit:function(a){var c;a.preventDefault(),t.onSubmit(ue({event:a,refresh:r,state:n.getState()},o)),n.dispatch("submit",null),null===(c=e.inputElement)||void 0===c||c.blur()},onReset:function(a){var c;a.preventDefault(),t.onReset(ue({event:a,refresh:r,state:n.getState()},o)),n.dispatch("reset",null),null===(c=e.inputElement)||void 0===c||c.focus()}},me(e,ce))},getLabelProps:function(e){return ue({htmlFor:"".concat(t.id,"-input"),id:"".concat(t.id,"-label")},e)},getInputProps:function(e){var a;function c(e){(t.openOnFocus||Boolean(n.getState().query))&&Y(ue({event:e,props:t,query:n.getState().completion||n.getState().query,refresh:r,store:n},o)),n.dispatch("focus",null)}var i=e||{},l=(i.inputElement,i.maxLength),s=void 0===l?512:l,u=me(i,ie),f=F(n.getState()),p=function(e){return Boolean(e&&e.match(ne))}((null===(a=t.environment.navigator)||void 0===a?void 0:a.userAgent)||""),d=null!=f&&f.itemUrl&&!p?"go":"search";return ue({"aria-autocomplete":"both","aria-activedescendant":n.getState().isOpen&&null!==n.getState().activeItemId?"".concat(t.id,"-item-").concat(n.getState().activeItemId):void 0,"aria-controls":n.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label"),value:n.getState().completion||n.getState().query,id:"".concat(t.id,"-input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:d,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:s,type:"search",onChange:function(e){Y(ue({event:e,props:t,query:e.currentTarget.value.slice(0,s),refresh:r,store:n},o))},onKeyDown:function(e){!function(e){var t=e.event,r=e.props,n=e.refresh,o=e.store,a=re(e,G);if("ArrowUp"===t.key||"ArrowDown"===t.key){var c=function(){var e=r.environment.document.getElementById("".concat(r.id,"-item-").concat(o.getState().activeItemId));e&&(e.scrollIntoViewIfNeeded?e.scrollIntoViewIfNeeded(!1):e.scrollIntoView(!1))},i=function(){var e=F(o.getState());if(null!==o.getState().activeItemId&&e){var r=e.item,c=e.itemInputValue,i=e.itemUrl,l=e.source;l.onActive(ee({event:t,item:r,itemInputValue:c,itemUrl:i,refresh:n,source:l,state:o.getState()},a))}};t.preventDefault(),!1===o.getState().isOpen&&(r.openOnFocus||Boolean(o.getState().query))?Y(ee({event:t,props:r,query:o.getState().query,refresh:n,store:o},a)).then((function(){o.dispatch(t.key,{nextActiveItemId:r.defaultActiveItemId}),i(),setTimeout(c,0)})):(o.dispatch(t.key,{}),i(),c())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every((function(e){return 0===e.items.length})))return void(r.debug||o.pendingRequests.cancelAll());t.preventDefault();var l=F(o.getState()),s=l.item,u=l.itemInputValue,f=l.itemUrl,m=l.source;if(t.metaKey||t.ctrlKey)void 0!==f&&(m.onSelect(ee({event:t,item:s,itemInputValue:u,itemUrl:f,refresh:n,source:m,state:o.getState()},a)),r.navigator.navigateNewTab({itemUrl:f,item:s,state:o.getState()}));else if(t.shiftKey)void 0!==f&&(m.onSelect(ee({event:t,item:s,itemInputValue:u,itemUrl:f,refresh:n,source:m,state:o.getState()},a)),r.navigator.navigateNewWindow({itemUrl:f,item:s,state:o.getState()}));else if(t.altKey);else{if(void 0!==f)return m.onSelect(ee({event:t,item:s,itemInputValue:u,itemUrl:f,refresh:n,source:m,state:o.getState()},a)),void r.navigator.navigate({itemUrl:f,item:s,state:o.getState()});Y(ee({event:t,nextState:{isOpen:!1},props:r,query:u,refresh:n,store:o},a)).then((function(){m.onSelect(ee({event:t,item:s,itemInputValue:u,itemUrl:f,refresh:n,source:m,state:o.getState()},a))}))}}}(ue({event:e,props:t,refresh:r,store:n},o))},onFocus:c,onBlur:m,onClick:function(r){e.inputElement!==t.environment.document.activeElement||n.getState().isOpen||c(r)}},u)},getPanelProps:function(e){return ue({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){n.dispatch("mouseleave",null)}},e)},getListProps:function(e){return ue({role:"listbox","aria-labelledby":"".concat(t.id,"-label"),id:"".concat(t.id,"-list")},e)},getItemProps:function(e){var a=e.item,c=e.source,i=me(e,le);return ue({id:"".concat(t.id,"-item-").concat(a.__autocomplete_id),role:"option","aria-selected":n.getState().activeItemId===a.__autocomplete_id,onMouseMove:function(e){if(a.__autocomplete_id!==n.getState().activeItemId){n.dispatch("mousemove",a.__autocomplete_id);var t=F(n.getState());if(null!==n.getState().activeItemId&&t){var c=t.item,i=t.itemInputValue,l=t.itemUrl,s=t.source;s.onActive(ue({event:e,item:c,itemInputValue:i,itemUrl:l,refresh:r,source:s,state:n.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var i=c.getItemInputValue({item:a,state:n.getState()}),l=c.getItemUrl({item:a,state:n.getState()});(l?Promise.resolve():Y(ue({event:e,nextState:{isOpen:!1},props:t,query:i,refresh:r,store:n},o))).then((function(){c.onSelect(ue({event:e,item:a,itemInputValue:i,itemUrl:l,refresh:r,source:c,state:n.getState()},o))}))}},i)}}}var de=[{segment:"autocomplete-core",version:"1.7.2"}];function he(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function ve(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?he(Object(r),!0).forEach((function(t){ye(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):he(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function ye(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function ge(e){var t,r,n,o,a=e.plugins,c=e.options,i=null===(t=((null===(r=c.__autocomplete_metadata)||void 0===r?void 0:r.userAgents)||[])[0])||void 0===t?void 0:t.segment,l=i?ye({},i,Object.keys((null===(n=c.__autocomplete_metadata)||void 0===n?void 0:n.options)||{})):{};return{plugins:a.map((function(e){return{name:e.name,options:Object.keys(e.__autocomplete_pluginOptions||[])}})),options:ve({"autocomplete-core":Object.keys(c)},l),ua:de.concat((null===(o=c.__autocomplete_metadata)||void 0===o?void 0:o.userAgents)||[])}}function be(e){var t,r=e.state;return!1===r.isOpen||null===r.activeItemId?null:(null===(t=F(r))||void 0===t?void 0:t.itemInputValue)||null}function Oe(e,t,r,n){if(!r)return null;if(e<0&&(null===t||null!==n&&0===t))return r+e;var o=(null===t?-1:t)+e;return o<=-1||o>=r?null===n?null:0:o}function Se(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function Ee(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?Se(Object(r),!0).forEach((function(t){je(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):Se(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function je(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var we=function(e,t){switch(t.type){case"setActiveItemId":case"mousemove":return Ee(Ee({},e),{},{activeItemId:t.payload});case"setQuery":return Ee(Ee({},e),{},{query:t.payload,completion:null});case"setCollections":return Ee(Ee({},e),{},{collections:t.payload});case"setIsOpen":return Ee(Ee({},e),{},{isOpen:t.payload});case"setStatus":return Ee(Ee({},e),{},{status:t.payload});case"setContext":return Ee(Ee({},e),{},{context:Ee(Ee({},e.context),t.payload)});case"ArrowDown":var r=Ee(Ee({},e),{},{activeItemId:t.payload.hasOwnProperty("nextActiveItemId")?t.payload.nextActiveItemId:Oe(1,e.activeItemId,u(e),t.props.defaultActiveItemId)});return Ee(Ee({},r),{},{completion:be({state:r})});case"ArrowUp":var n=Ee(Ee({},e),{},{activeItemId:Oe(-1,e.activeItemId,u(e),t.props.defaultActiveItemId)});return Ee(Ee({},n),{},{completion:be({state:n})});case"Escape":return e.isOpen?Ee(Ee({},e),{},{activeItemId:null,isOpen:!1,completion:null}):Ee(Ee({},e),{},{activeItemId:null,query:"",status:"idle",collections:[]});case"submit":return Ee(Ee({},e),{},{activeItemId:null,isOpen:!1,status:"idle"});case"reset":return Ee(Ee({},e),{},{activeItemId:!0===t.props.openOnFocus?t.props.defaultActiveItemId:null,status:"idle",query:""});case"focus":return Ee(Ee({},e),{},{activeItemId:t.props.defaultActiveItemId,isOpen:(t.props.openOnFocus||Boolean(e.query))&&t.props.shouldPanelOpen({state:e})});case"blur":return t.props.debug?e:Ee(Ee({},e),{},{isOpen:!1,activeItemId:null});case"mouseleave":return Ee(Ee({},e),{},{activeItemId:t.props.defaultActiveItemId});default:return"The reducer action ".concat(JSON.stringify(t.type)," is not supported."),e}};function Pe(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function Ie(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?Pe(Object(r),!0).forEach((function(t){De(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):Pe(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function De(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function Ce(e){var t=[],r=function(e,t){var r,n="undefined"!=typeof window?window:{},o=e.plugins||[];return b(b({debug:!1,openOnFocus:!1,placeholder:"",autoFocus:!1,defaultActiveItemId:null,stallThreshold:300,environment:n,shouldPanelOpen:function(e){return u(e.state)>0},reshape:function(e){return e.sources}},e),{},{id:null!==(r=e.id)&&void 0!==r?r:"autocomplete-".concat(f++),plugins:o,initialState:b({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var r;null===(r=e.onStateChange)||void 0===r||r.call(e,t),o.forEach((function(e){var r;return null===(r=e.onStateChange)||void 0===r?void 0:r.call(e,t)}))},onSubmit:function(t){var r;null===(r=e.onSubmit)||void 0===r||r.call(e,t),o.forEach((function(e){var r;return null===(r=e.onSubmit)||void 0===r?void 0:r.call(e,t)}))},onReset:function(t){var r;null===(r=e.onReset)||void 0===r||r.call(e,t),o.forEach((function(e){var r;return null===(r=e.onReset)||void 0===r?void 0:r.call(e,t)}))},getSources:function(r){return Promise.all([].concat(v(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return h(e,r)}))).then((function(e){return c(e)})).then((function(e){return e.map((function(e){return b(b({},e),{},{onSelect:function(r){e.onSelect(r),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,r)}))},onActive:function(r){e.onActive(r),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,r)}))}})}))}))},navigator:b({navigate:function(e){var t=e.itemUrl;n.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,r=n.open(t,"_blank","noopener");null==r||r.focus()},navigateNewWindow:function(e){var t=e.itemUrl;n.open(t,"_blank","noopener")}},e.navigator)})}(e,t),n=a(we,r,(function(e){var t=e.prevState,n=e.state;r.onStateChange(Ie({prevState:t,state:n,refresh:s},o))})),o=function(e){var t=e.store;return{setActiveItemId:function(e){t.dispatch("setActiveItemId",e)},setQuery:function(e){t.dispatch("setQuery",e)},setCollections:function(e){var r=0,n=e.map((function(e){return l(l({},e),{},{items:c(e.items).map((function(e){return l(l({},e),{},{__autocomplete_id:r++})}))})}));t.dispatch("setCollections",n)},setIsOpen:function(e){t.dispatch("setIsOpen",e)},setStatus:function(e){t.dispatch("setStatus",e)},setContext:function(e){t.dispatch("setContext",e)}}}({store:n}),i=pe(Ie({props:r,refresh:s,store:n},o));function s(){return Y(Ie({event:new Event("input"),nextState:{isOpen:n.getState().isOpen},props:r,query:n.getState().query,refresh:s,store:n},o))}return r.plugins.forEach((function(e){var r;return null===(r=e.subscribe)||void 0===r?void 0:r.call(e,Ie(Ie({},o),{},{refresh:s,onSelect:function(e){t.push({onSelect:e})},onActive:function(e){t.push({onActive:e})}}))})),function(e){var t,r,n=e.metadata,o=e.environment;if(null===(t=o.navigator)||void 0===t||null===(r=t.userAgent)||void 0===r?void 0:r.includes("Algolia Crawler")){var a=o.document.createElement("meta"),c=o.document.querySelector("head");a.name="algolia:metadata",setTimeout((function(){a.content=JSON.stringify(n),c.appendChild(a)}),0)}}({metadata:ge({plugins:r.plugins,options:e}),environment:r.environment}),Ie(Ie({refresh:s},i),o)}var ke=r(67294);function Ae(e){var t=e.translations,r=(void 0===t?{}:t).searchByText,n=void 0===r?"Search by":r;return ke.createElement("a",{href:"https://www.algolia.com/ref/docsearch/?utm_source=".concat(window.location.hostname,"&utm_medium=referral&utm_content=powered_by&utm_campaign=docsearch"),target:"_blank",rel:"noopener noreferrer"},ke.createElement("span",{className:"DocSearch-Label"},n),ke.createElement("svg",{width:"77",height:"19","aria-label":"Algolia",role:"img",id:"Layer_1",xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 2196.2 500"},ke.createElement("defs",null,ke.createElement("style",null,".cls-1,.cls-2{fill:#003dff;}.cls-2{fill-rule:evenodd;}")),ke.createElement("path",{className:"cls-2",d:"M1070.38,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"}),ke.createElement("rect",{className:"cls-1",x:"1845.88",y:"104.73",width:"62.58",height:"277.9",rx:"5.9",ry:"5.9"}),ke.createElement("path",{className:"cls-2",d:"M1851.78,71.38h50.77c3.26,0,5.9-2.64,5.9-5.9V5.9c0-3.62-3.24-6.39-6.82-5.83l-50.77,7.95c-2.87,.45-4.99,2.92-4.99,5.83v51.62c0,3.26,2.64,5.9,5.9,5.9Z"}),ke.createElement("path",{className:"cls-2",d:"M1764.03,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"}),ke.createElement("path",{className:"cls-2",d:"M1631.95,142.72c-11.14-12.25-24.83-21.65-40.78-28.31-15.92-6.53-33.26-9.85-52.07-9.85-18.78,0-36.15,3.17-51.92,9.85-15.59,6.66-29.29,16.05-40.76,28.31-11.47,12.23-20.38,26.87-26.76,44.03-6.38,17.17-9.24,37.37-9.24,58.36,0,20.99,3.19,36.87,9.55,54.21,6.38,17.32,15.14,32.11,26.45,44.36,11.29,12.23,24.83,21.62,40.6,28.46,15.77,6.83,40.12,10.33,52.4,10.48,12.25,0,36.78-3.82,52.7-10.48,15.92-6.68,29.46-16.23,40.78-28.46,11.29-12.25,20.05-27.04,26.25-44.36,6.22-17.34,9.24-33.22,9.24-54.21,0-20.99-3.34-41.19-10.03-58.36-6.38-17.17-15.14-31.8-26.43-44.03Zm-44.43,163.75c-11.47,15.75-27.56,23.7-48.09,23.7-20.55,0-36.63-7.8-48.1-23.7-11.47-15.75-17.21-34.01-17.21-61.2,0-26.89,5.59-49.14,17.06-64.87,11.45-15.75,27.54-23.52,48.07-23.52,20.55,0,36.63,7.78,48.09,23.52,11.47,15.57,17.36,37.98,17.36,64.87,0,27.19-5.72,45.3-17.19,61.2Z"}),ke.createElement("path",{className:"cls-2",d:"M894.42,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"}),ke.createElement("path",{className:"cls-2",d:"M2133.97,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"}),ke.createElement("path",{className:"cls-2",d:"M1314.05,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-11.79,18.34-19.6,39.64-22.11,62.59-.58,5.3-.88,10.68-.88,16.14s.31,11.15,.93,16.59c4.28,38.09,23.14,71.61,50.66,94.52,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47h0c17.99,0,34.61-5.93,48.16-15.97,16.29-11.58,28.88-28.54,34.48-47.75v50.26h-.11v11.08c0,21.84-5.71,38.27-17.34,49.36-11.61,11.08-31.04,16.63-58.25,16.63-11.12,0-28.79-.59-46.6-2.41-2.83-.29-5.46,1.5-6.27,4.22l-12.78,43.11c-1.02,3.46,1.27,7.02,4.83,7.53,21.52,3.08,42.52,4.68,54.65,4.68,48.91,0,85.16-10.75,108.89-32.21,21.48-19.41,33.15-48.89,35.2-88.52V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,64.1s.65,139.13,0,143.36c-12.08,9.77-27.11,13.59-43.49,14.7-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-1.32,0-2.63-.03-3.94-.1-40.41-2.11-74.52-37.26-74.52-79.38,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33Z"}),ke.createElement("path",{className:"cls-1",d:"M249.83,0C113.3,0,2,110.09,.03,246.16c-2,138.19,110.12,252.7,248.33,253.5,42.68,.25,83.79-10.19,120.3-30.03,3.56-1.93,4.11-6.83,1.08-9.51l-23.38-20.72c-4.75-4.21-11.51-5.4-17.36-2.92-25.48,10.84-53.17,16.38-81.71,16.03-111.68-1.37-201.91-94.29-200.13-205.96,1.76-110.26,92-199.41,202.67-199.41h202.69V407.41l-115-102.18c-3.72-3.31-9.42-2.66-12.42,1.31-18.46,24.44-48.53,39.64-81.93,37.34-46.33-3.2-83.87-40.5-87.34-86.81-4.15-55.24,39.63-101.52,94-101.52,49.18,0,89.68,37.85,93.91,85.95,.38,4.28,2.31,8.27,5.52,11.12l29.95,26.55c3.4,3.01,8.79,1.17,9.63-3.3,2.16-11.55,2.92-23.58,2.07-35.92-4.82-70.34-61.8-126.93-132.17-131.26-80.68-4.97-148.13,58.14-150.27,137.25-2.09,77.1,61.08,143.56,138.19,145.26,32.19,.71,62.03-9.41,86.14-26.95l150.26,133.2c6.44,5.71,16.61,1.14,16.61-7.47V9.48C499.66,4.25,495.42,0,490.18,0H249.83Z"})))}function xe(e){return ke.createElement("svg",{width:"15",height:"15","aria-label":e.ariaLabel,role:"img"},ke.createElement("g",{fill:"none",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:"1.2"},e.children))}function Ne(e){var t=e.translations,r=void 0===t?{}:t,n=r.selectText,o=void 0===n?"to select":n,a=r.selectKeyAriaLabel,c=void 0===a?"Enter key":a,i=r.navigateText,l=void 0===i?"to navigate":i,s=r.navigateUpKeyAriaLabel,u=void 0===s?"Arrow up":s,f=r.navigateDownKeyAriaLabel,m=void 0===f?"Arrow down":f,p=r.closeText,d=void 0===p?"to close":p,h=r.closeKeyAriaLabel,v=void 0===h?"Escape key":h,y=r.searchByText,g=void 0===y?"Search by":y;return ke.createElement(ke.Fragment,null,ke.createElement("div",{className:"DocSearch-Logo"},ke.createElement(Ae,{translations:{searchByText:g}})),ke.createElement("ul",{className:"DocSearch-Commands"},ke.createElement("li",null,ke.createElement("kbd",{className:"DocSearch-Commands-Key"},ke.createElement(xe,{ariaLabel:c},ke.createElement("path",{d:"M12 3.53088v3c0 1-1 2-2 2H4M7 11.53088l-3-3 3-3"}))),ke.createElement("span",{className:"DocSearch-Label"},o)),ke.createElement("li",null,ke.createElement("kbd",{className:"DocSearch-Commands-Key"},ke.createElement(xe,{ariaLabel:m},ke.createElement("path",{d:"M7.5 3.5v8M10.5 8.5l-3 3-3-3"}))),ke.createElement("kbd",{className:"DocSearch-Commands-Key"},ke.createElement(xe,{ariaLabel:u},ke.createElement("path",{d:"M7.5 11.5v-8M10.5 6.5l-3-3-3 3"}))),ke.createElement("span",{className:"DocSearch-Label"},l)),ke.createElement("li",null,ke.createElement("kbd",{className:"DocSearch-Commands-Key"},ke.createElement(xe,{ariaLabel:v},ke.createElement("path",{d:"M13.6167 8.936c-.1065.3583-.6883.962-1.4875.962-.7993 0-1.653-.9165-1.653-2.1258v-.5678c0-1.2548.7896-2.1016 1.653-2.1016.8634 0 1.3601.4778 1.4875 1.0724M9 6c-.1352-.4735-.7506-.9219-1.46-.8972-.7092.0246-1.344.57-1.344 1.2166s.4198.8812 1.3445.9805C8.465 7.3992 8.968 7.9337 9 8.5c.032.5663-.454 1.398-1.4595 1.398C6.6593 9.898 6 9 5.963 8.4851m-1.4748.5368c-.2635.5941-.8099.876-1.5443.876s-1.7073-.6248-1.7073-2.204v-.4603c0-1.0416.721-2.131 1.7073-2.131.9864 0 1.6425 1.031 1.5443 2.2492h-2.956"}))),ke.createElement("span",{className:"DocSearch-Label"},d))))}function Re(e){var t=e.hit,r=e.children;return ke.createElement("a",{href:t.url},r)}function _e(){return ke.createElement("svg",{width:"40",height:"40",viewBox:"0 0 20 20",fill:"none",fillRule:"evenodd",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"},ke.createElement("path",{d:"M19 4.8a16 16 0 00-2-1.2m-3.3-1.2A16 16 0 001.1 4.7M16.7 8a12 12 0 00-2.8-1.4M10 6a12 12 0 00-6.7 2M12.3 14.7a4 4 0 00-4.5 0M14.5 11.4A8 8 0 0010 10M3 16L18 2M10 18h0"}))}function qe(e){var t=e.translations,r=void 0===t?{}:t,n=r.titleText,o=void 0===n?"Unable to fetch results":n,a=r.helpText,c=void 0===a?"You might want to check your network connection.":a;return ke.createElement("div",{className:"DocSearch-ErrorScreen"},ke.createElement("div",{className:"DocSearch-Screen-Icon"},ke.createElement(_e,null)),ke.createElement("p",{className:"DocSearch-Title"},o),ke.createElement("p",{className:"DocSearch-Help"},c))}function Te(){return ke.createElement("svg",{width:"40",height:"40",viewBox:"0 0 20 20",fill:"none",fillRule:"evenodd",stroke:"currentColor",strokeLinecap:"round",strokeLinejoin:"round"},ke.createElement("path",{d:"M15.5 4.8c2 3 1.7 7-1 9.7h0l4.3 4.3-4.3-4.3a7.8 7.8 0 01-9.8 1m-2.2-2.2A7.8 7.8 0 0113.2 2.4M2 18L18 2"}))}var Le=["translations"];function Me(e){return function(e){if(Array.isArray(e))return He(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return He(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return He(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function He(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function Fe(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function Ue(e){var t=e.translations,r=void 0===t?{}:t,n=Fe(e,Le),o=r.noResultsText,a=void 0===o?"No results for":o,c=r.suggestedQueryText,i=void 0===c?"Try searching for":c,l=r.reportMissingResultsText,s=void 0===l?"Believe this query should return results?":l,u=r.reportMissingResultsLinkText,f=void 0===u?"Let us know.":u,m=n.state.context.searchSuggestions;return ke.createElement("div",{className:"DocSearch-NoResults"},ke.createElement("div",{className:"DocSearch-Screen-Icon"},ke.createElement(Te,null)),ke.createElement("p",{className:"DocSearch-Title"},a,' "',ke.createElement("strong",null,n.state.query),'"'),m&&m.length>0&&ke.createElement("div",{className:"DocSearch-NoResults-Prefill-List"},ke.createElement("p",{className:"DocSearch-Help"},i,":"),ke.createElement("ul",null,m.slice(0,3).reduce((function(e,t){return[].concat(Me(e),[ke.createElement("li",{key:t},ke.createElement("button",{className:"DocSearch-Prefill",key:t,type:"button",onClick:function(){n.setQuery(t.toLowerCase()+" "),n.refresh(),n.inputRef.current.focus()}},t))])}),[]))),n.getMissingResultsUrl&&ke.createElement("p",{className:"DocSearch-Help"},"".concat(s," "),ke.createElement("a",{href:n.getMissingResultsUrl({query:n.state.query}),target:"_blank",rel:"noopener noreferrer"},f)))}var Be=function(){return ke.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},ke.createElement("path",{d:"M17 6v12c0 .52-.2 1-1 1H4c-.7 0-1-.33-1-1V2c0-.55.42-1 1-1h8l5 5zM14 8h-3.13c-.51 0-.87-.34-.87-.87V4",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinejoin:"round"}))};function Ve(e){switch(e.type){case"lvl1":return ke.createElement(Be,null);case"content":return ke.createElement(Je,null);default:return ke.createElement(Ke,null)}}function Ke(){return ke.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},ke.createElement("path",{d:"M13 13h4-4V8H7v5h6v4-4H7V8H3h4V3v5h6V3v5h4-4v5zm-6 0v4-4H3h4z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}function Je(){return ke.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},ke.createElement("path",{d:"M17 5H3h14zm0 5H3h14zm0 5H3h14z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinejoin:"round"}))}function $e(){return ke.createElement("svg",{className:"DocSearch-Hit-Select-Icon",width:"20",height:"20",viewBox:"0 0 20 20"},ke.createElement("g",{stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},ke.createElement("path",{d:"M18 3v4c0 2-2 4-4 4H2"}),ke.createElement("path",{d:"M8 17l-6-6 6-6"})))}var ze=["hit","attribute","tagName"];function We(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function Qe(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?We(Object(r),!0).forEach((function(t){Ze(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):We(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function Ze(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function Ye(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function Ge(e,t){return t.split(".").reduce((function(e,t){return null!=e&&e[t]?e[t]:null}),e)}function Xe(e){var t=e.hit,r=e.attribute,n=e.tagName,o=void 0===n?"span":n,a=Ye(e,ze);return(0,ke.createElement)(o,Qe(Qe({},a),{},{dangerouslySetInnerHTML:{__html:Ge(t,"_snippetResult.".concat(r,".value"))||Ge(t,r)}}))}function et(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==r)return;var n,o,a=[],c=!0,i=!1;try{for(r=r.call(e);!(c=(n=r.next()).done)&&(a.push(n.value),!t||a.length!==t);c=!0);}catch(l){i=!0,o=l}finally{try{c||null==r.return||r.return()}finally{if(i)throw o}}return a}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return tt(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return tt(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function tt(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function rt(){return rt=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},rt.apply(this,arguments)}function nt(e){return e.collection&&0!==e.collection.items.length?ke.createElement("section",{className:"DocSearch-Hits"},ke.createElement("div",{className:"DocSearch-Hit-source"},e.title),ke.createElement("ul",e.getListProps(),e.collection.items.map((function(t,r){return ke.createElement(ot,rt({key:[e.title,t.objectID].join(":"),item:t,index:r},e))})))):null}function ot(e){var t=e.item,r=e.index,n=e.renderIcon,o=e.renderAction,a=e.getItemProps,c=e.onItemClick,i=e.collection,l=e.hitComponent,s=et(ke.useState(!1),2),u=s[0],f=s[1],m=et(ke.useState(!1),2),p=m[0],d=m[1],h=ke.useRef(null),v=l;return ke.createElement("li",rt({className:["DocSearch-Hit",t.__docsearch_parent&&"DocSearch-Hit--Child",u&&"DocSearch-Hit--deleting",p&&"DocSearch-Hit--favoriting"].filter(Boolean).join(" "),onTransitionEnd:function(){h.current&&h.current()}},a({item:t,source:i.source,onClick:function(){c(t)}})),ke.createElement(v,{hit:t},ke.createElement("div",{className:"DocSearch-Hit-Container"},n({item:t,index:r}),t.hierarchy[t.type]&&"lvl1"===t.type&&ke.createElement("div",{className:"DocSearch-Hit-content-wrapper"},ke.createElement(Xe,{className:"DocSearch-Hit-title",hit:t,attribute:"hierarchy.lvl1"}),t.content&&ke.createElement(Xe,{className:"DocSearch-Hit-path",hit:t,attribute:"content"})),t.hierarchy[t.type]&&("lvl2"===t.type||"lvl3"===t.type||"lvl4"===t.type||"lvl5"===t.type||"lvl6"===t.type)&&ke.createElement("div",{className:"DocSearch-Hit-content-wrapper"},ke.createElement(Xe,{className:"DocSearch-Hit-title",hit:t,attribute:"hierarchy.".concat(t.type)}),ke.createElement(Xe,{className:"DocSearch-Hit-path",hit:t,attribute:"hierarchy.lvl1"})),"content"===t.type&&ke.createElement("div",{className:"DocSearch-Hit-content-wrapper"},ke.createElement(Xe,{className:"DocSearch-Hit-title",hit:t,attribute:"content"}),ke.createElement(Xe,{className:"DocSearch-Hit-path",hit:t,attribute:"hierarchy.lvl1"})),o({item:t,runDeleteTransition:function(e){f(!0),h.current=e},runFavoriteTransition:function(e){d(!0),h.current=e}}))))}var at=/(<mark>|<\/mark>)/g,ct=RegExp(at.source);function it(e){var t,r,n,o,a,c=e;if(!c.__docsearch_parent&&!e._highlightResult)return e.hierarchy.lvl0;var i=((c.__docsearch_parent?null===(t=c.__docsearch_parent)||void 0===t||null===(r=t._highlightResult)||void 0===r||null===(n=r.hierarchy)||void 0===n?void 0:n.lvl0:null===(o=e._highlightResult)||void 0===o||null===(a=o.hierarchy)||void 0===a?void 0:a.lvl0)||{}).value;return i&&ct.test(i)?i.replace(at,""):i}function lt(){return lt=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},lt.apply(this,arguments)}function st(e){return ke.createElement("div",{className:"DocSearch-Dropdown-Container"},e.state.collections.map((function(t){if(0===t.items.length)return null;var r=it(t.items[0]);return ke.createElement(nt,lt({},e,{key:t.source.sourceId,title:r,collection:t,renderIcon:function(e){var r,n=e.item,o=e.index;return ke.createElement(ke.Fragment,null,n.__docsearch_parent&&ke.createElement("svg",{className:"DocSearch-Hit-Tree",viewBox:"0 0 24 54"},ke.createElement("g",{stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},n.__docsearch_parent!==(null===(r=t.items[o+1])||void 0===r?void 0:r.__docsearch_parent)?ke.createElement("path",{d:"M8 6v21M20 27H8.3"}):ke.createElement("path",{d:"M8 6v42M20 27H8.3"}))),ke.createElement("div",{className:"DocSearch-Hit-icon"},ke.createElement(Ve,{type:n.type})))},renderAction:function(){return ke.createElement("div",{className:"DocSearch-Hit-action"},ke.createElement($e,null))}}))})),e.resultsFooterComponent&&ke.createElement("section",{className:"DocSearch-HitsFooter"},ke.createElement(e.resultsFooterComponent,{state:e.state})))}function ut(){return ke.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},ke.createElement("g",{stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"},ke.createElement("path",{d:"M3.18 6.6a8.23 8.23 0 1112.93 9.94h0a8.23 8.23 0 01-11.63 0"}),ke.createElement("path",{d:"M6.44 7.25H2.55V3.36M10.45 6v5.6M10.45 11.6L13 13"})))}function ft(){return ke.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},ke.createElement("path",{d:"M10 14.2L5 17l1-5.6-4-4 5.5-.7 2.5-5 2.5 5 5.6.8-4 4 .9 5.5z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinejoin:"round"}))}function mt(){return ke.createElement("svg",{width:"20",height:"20",viewBox:"0 0 20 20"},ke.createElement("path",{d:"M10 10l5.09-5.09L10 10l5.09 5.09L10 10zm0 0L4.91 4.91 10 10l-5.09 5.09L10 10z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}var pt=["translations"];function dt(){return dt=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},dt.apply(this,arguments)}function ht(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function vt(e){var t=e.translations,r=void 0===t?{}:t,n=ht(e,pt),o=r.recentSearchesTitle,a=void 0===o?"Recent":o,c=r.noRecentSearchesText,i=void 0===c?"No recent searches":c,l=r.saveRecentSearchButtonTitle,s=void 0===l?"Save this search":l,u=r.removeRecentSearchButtonTitle,f=void 0===u?"Remove this search from history":u,m=r.favoriteSearchesTitle,p=void 0===m?"Favorite":m,d=r.removeFavoriteSearchButtonTitle,h=void 0===d?"Remove this search from favorites":d;return"idle"===n.state.status&&!1===n.hasCollections?n.disableUserPersonalization?null:ke.createElement("div",{className:"DocSearch-StartScreen"},ke.createElement("p",{className:"DocSearch-Help"},i)):!1===n.hasCollections?null:ke.createElement("div",{className:"DocSearch-Dropdown-Container"},ke.createElement(nt,dt({},n,{title:a,collection:n.state.collections[0],renderIcon:function(){return ke.createElement("div",{className:"DocSearch-Hit-icon"},ke.createElement(ut,null))},renderAction:function(e){var t=e.item,r=e.runFavoriteTransition,o=e.runDeleteTransition;return ke.createElement(ke.Fragment,null,ke.createElement("div",{className:"DocSearch-Hit-action"},ke.createElement("button",{className:"DocSearch-Hit-action-button",title:s,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),r((function(){n.favoriteSearches.add(t),n.recentSearches.remove(t),n.refresh()}))}},ke.createElement(ft,null))),ke.createElement("div",{className:"DocSearch-Hit-action"},ke.createElement("button",{className:"DocSearch-Hit-action-button",title:f,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),o((function(){n.recentSearches.remove(t),n.refresh()}))}},ke.createElement(mt,null))))}})),ke.createElement(nt,dt({},n,{title:p,collection:n.state.collections[1],renderIcon:function(){return ke.createElement("div",{className:"DocSearch-Hit-icon"},ke.createElement(ft,null))},renderAction:function(e){var t=e.item,r=e.runDeleteTransition;return ke.createElement("div",{className:"DocSearch-Hit-action"},ke.createElement("button",{className:"DocSearch-Hit-action-button",title:h,type:"submit",onClick:function(e){e.preventDefault(),e.stopPropagation(),r((function(){n.favoriteSearches.remove(t),n.refresh()}))}},ke.createElement(mt,null)))}})))}var yt=["translations"];function gt(){return gt=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},gt.apply(this,arguments)}function bt(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var Ot=ke.memo((function(e){var t=e.translations,r=void 0===t?{}:t,n=bt(e,yt);if("error"===n.state.status)return ke.createElement(qe,{translations:null==r?void 0:r.errorScreen});var o=n.state.collections.some((function(e){return e.items.length>0}));return n.state.query?!1===o?ke.createElement(Ue,gt({},n,{translations:null==r?void 0:r.noResultsScreen})):ke.createElement(st,n):ke.createElement(vt,gt({},n,{hasCollections:o,translations:null==r?void 0:r.startScreen}))}),(function(e,t){return"loading"===t.state.status||"stalled"===t.state.status}));function St(){return ke.createElement("svg",{viewBox:"0 0 38 38",stroke:"currentColor",strokeOpacity:".5"},ke.createElement("g",{fill:"none",fillRule:"evenodd"},ke.createElement("g",{transform:"translate(1 1)",strokeWidth:"2"},ke.createElement("circle",{strokeOpacity:".3",cx:"18",cy:"18",r:"18"}),ke.createElement("path",{d:"M36 18c0-9.94-8.06-18-18-18"},ke.createElement("animateTransform",{attributeName:"transform",type:"rotate",from:"0 18 18",to:"360 18 18",dur:"1s",repeatCount:"indefinite"})))))}var Et=r(20830),jt=["translations"];function wt(){return wt=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},wt.apply(this,arguments)}function Pt(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function It(e){var t=e.translations,r=void 0===t?{}:t,n=Pt(e,jt),o=r.resetButtonTitle,a=void 0===o?"Clear the query":o,c=r.resetButtonAriaLabel,i=void 0===c?"Clear the query":c,l=r.cancelButtonText,s=void 0===l?"Cancel":l,u=r.cancelButtonAriaLabel,f=void 0===u?"Cancel":u,m=n.getFormProps({inputElement:n.inputRef.current}).onReset;return ke.useEffect((function(){n.autoFocus&&n.inputRef.current&&n.inputRef.current.focus()}),[n.autoFocus,n.inputRef]),ke.useEffect((function(){n.isFromSelection&&n.inputRef.current&&n.inputRef.current.select()}),[n.isFromSelection,n.inputRef]),ke.createElement(ke.Fragment,null,ke.createElement("form",{className:"DocSearch-Form",onSubmit:function(e){e.preventDefault()},onReset:m},ke.createElement("label",wt({className:"DocSearch-MagnifierLabel"},n.getLabelProps()),ke.createElement(Et.W,null)),ke.createElement("div",{className:"DocSearch-LoadingIndicator"},ke.createElement(St,null)),ke.createElement("input",wt({className:"DocSearch-Input",ref:n.inputRef},n.getInputProps({inputElement:n.inputRef.current,autoFocus:n.autoFocus,maxLength:64}))),ke.createElement("button",{type:"reset",title:a,className:"DocSearch-Reset","aria-label":i,hidden:!n.state.query},ke.createElement(mt,null))),ke.createElement("button",{className:"DocSearch-Cancel",type:"reset","aria-label":f,onClick:n.onClose},s))}var Dt=["_highlightResult","_snippetResult"];function Ct(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function kt(e){return!1===function(){var e="__TEST_KEY__";try{return localStorage.setItem(e,""),localStorage.removeItem(e),!0}catch(t){return!1}}()?{setItem:function(){},getItem:function(){return[]}}:{setItem:function(t){return window.localStorage.setItem(e,JSON.stringify(t))},getItem:function(){var t=window.localStorage.getItem(e);return t?JSON.parse(t):[]}}}function At(e){var t=e.key,r=e.limit,n=void 0===r?5:r,o=kt(t),a=o.getItem().slice(0,n);return{add:function(e){var t=e,r=(t._highlightResult,t._snippetResult,Ct(t,Dt)),c=a.findIndex((function(e){return e.objectID===r.objectID}));c>-1&&a.splice(c,1),a.unshift(r),a=a.slice(0,n),o.setItem(a)},remove:function(e){a=a.filter((function(t){return t.objectID!==e.objectID})),o.setItem(a)},getAll:function(){return a}}}function xt(e){const t=`algoliasearch-client-js-${e.key}`;let r;const n=()=>(void 0===r&&(r=e.localStorage||window.localStorage),r),o=()=>JSON.parse(n().getItem(t)||"{}");return{get:(e,t,r={miss:()=>Promise.resolve()})=>Promise.resolve().then((()=>{const r=JSON.stringify(e),n=o()[r];return Promise.all([n||t(),void 0!==n])})).then((([e,t])=>Promise.all([e,t||r.miss(e)]))).then((([e])=>e)),set:(e,r)=>Promise.resolve().then((()=>{const a=o();return a[JSON.stringify(e)]=r,n().setItem(t,JSON.stringify(a)),r})),delete:e=>Promise.resolve().then((()=>{const r=o();delete r[JSON.stringify(e)],n().setItem(t,JSON.stringify(r))})),clear:()=>Promise.resolve().then((()=>{n().removeItem(t)}))}}function Nt(e){const t=[...e.caches],r=t.shift();return void 0===r?{get:(e,t,r={miss:()=>Promise.resolve()})=>t().then((e=>Promise.all([e,r.miss(e)]))).then((([e])=>e)),set:(e,t)=>Promise.resolve(t),delete:e=>Promise.resolve(),clear:()=>Promise.resolve()}:{get:(e,n,o={miss:()=>Promise.resolve()})=>r.get(e,n,o).catch((()=>Nt({caches:t}).get(e,n,o))),set:(e,n)=>r.set(e,n).catch((()=>Nt({caches:t}).set(e,n))),delete:e=>r.delete(e).catch((()=>Nt({caches:t}).delete(e))),clear:()=>r.clear().catch((()=>Nt({caches:t}).clear()))}}function Rt(e={serializable:!0}){let t={};return{get(r,n,o={miss:()=>Promise.resolve()}){const a=JSON.stringify(r);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);const c=n(),i=o&&o.miss||(()=>Promise.resolve());return c.then((e=>i(e))).then((()=>c))},set:(r,n)=>(t[JSON.stringify(r)]=e.serializable?JSON.stringify(n):n,Promise.resolve(n)),delete:e=>(delete t[JSON.stringify(e)],Promise.resolve()),clear:()=>(t={},Promise.resolve())}}function _t(e){let t=e.length-1;for(;t>0;t--){const r=Math.floor(Math.random()*(t+1)),n=e[t];e[t]=e[r],e[r]=n}return e}function qt(e,t){return t?(Object.keys(t).forEach((r=>{e[r]=t[r](e)})),e):e}function Tt(e,...t){let r=0;return e.replace(/%s/g,(()=>encodeURIComponent(t[r++])))}const Lt="4.14.2",Mt={WithinQueryParameters:0,WithinHeaders:1};function Ht(e,t){const r=e||{},n=r.data||{};return Object.keys(r).forEach((e=>{-1===["timeout","headers","queryParameters","data","cacheable"].indexOf(e)&&(n[e]=r[e])})),{data:Object.entries(n).length>0?n:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}const Ft={Read:1,Write:2,Any:3},Ut=1,Bt=2,Vt=3,Kt=12e4;function Jt(e,t=Ut){return{...e,status:t,lastUpdate:Date.now()}}function $t(e){return"string"==typeof e?{protocol:"https",url:e,accept:Ft.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||Ft.Any}}const zt="GET",Wt="POST";function Qt(e,t){return Promise.all(t.map((t=>e.get(t,(()=>Promise.resolve(Jt(t))))))).then((e=>{const r=e.filter((e=>function(e){return e.status===Ut||Date.now()-e.lastUpdate>Kt}(e))),n=e.filter((e=>function(e){return e.status===Vt&&Date.now()-e.lastUpdate<=Kt}(e))),o=[...r,...n];return{getTimeout:(e,t)=>(0===n.length&&0===e?1:n.length+3+e)*t,statelessHosts:o.length>0?o.map((e=>$t(e))):t}}))}function Zt(e,t,r,n){const o=[],a=function(e,t){if(e.method===zt||void 0===e.data&&void 0===t.data)return;const r=Array.isArray(e.data)?e.data:{...e.data,...t.data};return JSON.stringify(r)}(r,n),c=function(e,t){const r={...e.headers,...t.headers},n={};return Object.keys(r).forEach((e=>{const t=r[e];n[e.toLowerCase()]=t})),n}(e,n),i=r.method,l=r.method!==zt?{}:{...r.data,...n.data},s={"x-algolia-agent":e.userAgent.value,...e.queryParameters,...l,...n.queryParameters};let u=0;const f=(t,l)=>{const m=t.pop();if(void 0===m)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:er(o)};const p={data:a,headers:c,method:i,url:Gt(m,r.path,s),connectTimeout:l(u,e.timeouts.connect),responseTimeout:l(u,n.timeout)},d=e=>{const r={request:p,response:e,host:m,triesLeft:t.length};return o.push(r),r},h={onSuccess:e=>function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e),onRetry(r){const n=d(r);return r.isTimedOut&&u++,Promise.all([e.logger.info("Retryable failure",tr(n)),e.hostsCache.set(m,Jt(m,r.isTimedOut?Vt:Bt))]).then((()=>f(t,l)))},onFail(e){throw d(e),function({content:e,status:t},r){let n=e;try{n=JSON.parse(e).message}catch(o){}return function(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}(n,t,r)}(e,er(o))}};return e.requester.send(p).then((e=>((e,t)=>(e=>{const t=e.status;return e.isTimedOut||(({isTimedOut:e,status:t})=>!e&&0==~~t)(e)||2!=~~(t/100)&&4!=~~(t/100)})(e)?t.onRetry(e):(({status:e})=>2==~~(e/100))(e)?t.onSuccess(e):t.onFail(e))(e,h)))};return Qt(e.hostsCache,t).then((e=>f([...e.statelessHosts].reverse(),e.getTimeout)))}function Yt(e){const t={value:`Algolia for JavaScript (${e})`,add(e){const r=`; ${e.segment}${void 0!==e.version?` (${e.version})`:""}`;return-1===t.value.indexOf(r)&&(t.value=`${t.value}${r}`),t}};return t}function Gt(e,t,r){const n=Xt(r);let o=`${e.protocol}://${e.url}/${"/"===t.charAt(0)?t.substr(1):t}`;return n.length&&(o+=`?${n}`),o}function Xt(e){return Object.keys(e).map((t=>{return Tt("%s=%s",t,(r=e[t],"[object Object]"===Object.prototype.toString.call(r)||"[object Array]"===Object.prototype.toString.call(r)?JSON.stringify(e[t]):e[t]));var r})).join("&")}function er(e){return e.map((e=>tr(e)))}function tr(e){const t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return{...e,request:{...e.request,headers:{...e.request.headers,...t}}}}const rr=e=>{const t=e.appId,r=function(e,t,r){const n={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers:()=>e===Mt.WithinHeaders?n:{},queryParameters:()=>e===Mt.WithinQueryParameters?n:{}}}(void 0!==e.authMode?e.authMode:Mt.WithinHeaders,t,e.apiKey),n=function(e){const{hostsCache:t,logger:r,requester:n,requestsCache:o,responsesCache:a,timeouts:c,userAgent:i,hosts:l,queryParameters:s,headers:u}=e,f={hostsCache:t,logger:r,requester:n,requestsCache:o,responsesCache:a,timeouts:c,userAgent:i,headers:u,queryParameters:s,hosts:l.map((e=>$t(e))),read(e,t){const r=Ht(t,f.timeouts.read),n=()=>Zt(f,f.hosts.filter((e=>0!=(e.accept&Ft.Read))),e,r);if(!0!==(void 0!==r.cacheable?r.cacheable:e.cacheable))return n();const o={request:e,mappedRequestOptions:r,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(o,(()=>f.requestsCache.get(o,(()=>f.requestsCache.set(o,n()).then((e=>Promise.all([f.requestsCache.delete(o),e])),(e=>Promise.all([f.requestsCache.delete(o),Promise.reject(e)]))).then((([e,t])=>t))))),{miss:e=>f.responsesCache.set(o,e)})},write:(e,t)=>Zt(f,f.hosts.filter((e=>0!=(e.accept&Ft.Write))),e,Ht(t,f.timeouts.write))};return f}({hosts:[{url:`${t}-dsn.algolia.net`,accept:Ft.Read},{url:`${t}.algolia.net`,accept:Ft.Write}].concat(_t([{url:`${t}-1.algolianet.com`},{url:`${t}-2.algolianet.com`},{url:`${t}-3.algolianet.com`}])),...e,headers:{...r.headers(),"content-type":"application/x-www-form-urlencoded",...e.headers},queryParameters:{...r.queryParameters(),...e.queryParameters}}),o={transporter:n,appId:t,addAlgoliaAgent(e,t){n.userAgent.add({segment:e,version:t})},clearCache:()=>Promise.all([n.requestsCache.clear(),n.responsesCache.clear()]).then((()=>{}))};return qt(o,e.methods)},nr=e=>(t,r)=>t.method===zt?e.transporter.read(t,r):e.transporter.write(t,r),or=e=>(t,r={})=>qt({transporter:e.transporter,appId:e.appId,indexName:t},r.methods),ar=e=>(t,r)=>{const n=t.map((e=>({...e,params:Xt(e.params||{})})));return e.transporter.read({method:Wt,path:"1/indexes/*/queries",data:{requests:n},cacheable:!0},r)},cr=e=>(t,r)=>Promise.all(t.map((t=>{const{facetName:n,facetQuery:o,...a}=t.params;return or(e)(t.indexName,{methods:{searchForFacetValues:sr}}).searchForFacetValues(n,o,{...r,...a})}))),ir=e=>(t,r,n)=>e.transporter.read({method:Wt,path:Tt("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:r},cacheable:!0},n),lr=e=>(t,r)=>e.transporter.read({method:Wt,path:Tt("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r),sr=e=>(t,r,n)=>e.transporter.read({method:Wt,path:Tt("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},n),ur=1,fr=2,mr=3;function pr(e,t,r){const n={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:e=>new Promise((t=>{const r=new XMLHttpRequest;r.open(e.method,e.url,!0),Object.keys(e.headers).forEach((t=>r.setRequestHeader(t,e.headers[t])));const n=(e,n)=>setTimeout((()=>{r.abort(),t({status:0,content:n,isTimedOut:!0})}),1e3*e),o=n(e.connectTimeout,"Connection timeout");let a;r.onreadystatechange=()=>{r.readyState>r.OPENED&&void 0===a&&(clearTimeout(o),a=n(e.responseTimeout,"Socket timeout"))},r.onerror=()=>{0===r.status&&(clearTimeout(o),clearTimeout(a),t({content:r.responseText||"Network request failed",status:r.status,isTimedOut:!1}))},r.onload=()=>{clearTimeout(o),clearTimeout(a),t({content:r.responseText,status:r.status,isTimedOut:!1})},r.send(e.data)}))},logger:(o=mr,{debug:(e,t)=>(ur>=o&&console.debug(e,t),Promise.resolve()),info:(e,t)=>(fr>=o&&console.info(e,t),Promise.resolve()),error:(e,t)=>(console.error(e,t),Promise.resolve())}),responsesCache:Rt(),requestsCache:Rt({serializable:!1}),hostsCache:Nt({caches:[xt({key:`4.14.2-${e}`}),Rt()]}),userAgent:Yt(Lt).add({segment:"Browser",version:"lite"}),authMode:Mt.WithinQueryParameters};var o;return rr({...n,...r,methods:{search:ar,searchForFacetValues:cr,multipleQueries:ar,multipleSearchForFacetValues:cr,customRequest:nr,initIndex:e=>t=>or(e)(t,{methods:{search:lr,searchForFacetValues:sr,findAnswers:ir}})}})}pr.version=Lt;const dr=pr;var hr="3.3.0";function vr(){}function yr(e){return e}function gr(e,t){return e.reduce((function(e,r){var n=t(r);return e.hasOwnProperty(n)||(e[n]=[]),e[n].length<5&&e[n].push(r),e}),{})}var br=["footer","searchBox"];function Or(){return Or=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},Or.apply(this,arguments)}function Sr(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function Er(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?Sr(Object(r),!0).forEach((function(t){jr(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):Sr(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function jr(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function wr(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==r)return;var n,o,a=[],c=!0,i=!1;try{for(r=r.call(e);!(c=(n=r.next()).done)&&(a.push(n.value),!t||a.length!==t);c=!0);}catch(l){i=!0,o=l}finally{try{c||null==r.return||r.return()}finally{if(i)throw o}}return a}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return Pr(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return Pr(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Pr(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function Ir(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function Dr(e){var t=e.appId,r=e.apiKey,n=e.indexName,o=e.placeholder,a=void 0===o?"Search docs":o,c=e.searchParameters,i=e.onClose,l=void 0===i?vr:i,s=e.transformItems,u=void 0===s?yr:s,f=e.hitComponent,m=void 0===f?Re:f,p=e.resultsFooterComponent,d=void 0===p?function(){return null}:p,h=e.navigator,v=e.initialScrollY,y=void 0===v?0:v,g=e.transformSearchClient,b=void 0===g?yr:g,O=e.disableUserPersonalization,S=void 0!==O&&O,E=e.initialQuery,j=void 0===E?"":E,w=e.translations,P=void 0===w?{}:w,I=e.getMissingResultsUrl,D=P.footer,C=P.searchBox,k=Ir(P,br),A=wr(ke.useState({query:"",collections:[],completion:null,context:{},isOpen:!1,activeItemId:null,status:"idle"}),2),x=A[0],N=A[1],R=ke.useRef(null),_=ke.useRef(null),q=ke.useRef(null),T=ke.useRef(null),L=ke.useRef(null),M=ke.useRef(10),H=ke.useRef("undefined"!=typeof window?window.getSelection().toString().slice(0,64):"").current,F=ke.useRef(j||H).current,U=function(e,t,r){return ke.useMemo((function(){var n=dr(e,t);return n.addAlgoliaAgent("docsearch",hr),!1===/docsearch.js \(.*\)/.test(n.transporter.userAgent.value)&&n.addAlgoliaAgent("docsearch-react",hr),r(n)}),[e,t,r])}(t,r,b),B=ke.useRef(At({key:"__DOCSEARCH_FAVORITE_SEARCHES__".concat(n),limit:10})).current,V=ke.useRef(At({key:"__DOCSEARCH_RECENT_SEARCHES__".concat(n),limit:0===B.getAll().length?7:4})).current,K=ke.useCallback((function(e){if(!S){var t="content"===e.type?e.__docsearch_parent:e;t&&-1===B.getAll().findIndex((function(e){return e.objectID===t.objectID}))&&V.add(t)}}),[B,V,S]),J=ke.useMemo((function(){return Ce({id:"docsearch",defaultActiveItemId:0,placeholder:a,openOnFocus:!0,initialState:{query:F,context:{searchSuggestions:[]}},navigator:h,onStateChange:function(e){N(e.state)},getSources:function(e){var t=e.query,r=e.state,o=e.setContext,a=e.setStatus;return t?U.search([{query:t,indexName:n,params:Er({attributesToRetrieve:["hierarchy.lvl0","hierarchy.lvl1","hierarchy.lvl2","hierarchy.lvl3","hierarchy.lvl4","hierarchy.lvl5","hierarchy.lvl6","content","type","url"],attributesToSnippet:["hierarchy.lvl1:".concat(M.current),"hierarchy.lvl2:".concat(M.current),"hierarchy.lvl3:".concat(M.current),"hierarchy.lvl4:".concat(M.current),"hierarchy.lvl5:".concat(M.current),"hierarchy.lvl6:".concat(M.current),"content:".concat(M.current)],snippetEllipsisText:"\u2026",highlightPreTag:"<mark>",highlightPostTag:"</mark>",hitsPerPage:20},c)}]).catch((function(e){throw"RetryError"===e.name&&a("error"),e})).then((function(e){var t=e.results[0],n=t.hits,a=t.nbHits,c=gr(n,(function(e){return it(e)}));return r.context.searchSuggestions.length<Object.keys(c).length&&o({searchSuggestions:Object.keys(c)}),o({nbHits:a}),Object.values(c).map((function(e,t){return{sourceId:"hits".concat(t),onSelect:function(e){var t=e.item,r=e.event;K(t),r.shiftKey||r.ctrlKey||r.metaKey||l()},getItemUrl:function(e){return e.item.url},getItems:function(){return Object.values(gr(e,(function(e){return e.hierarchy.lvl1}))).map(u).map((function(e){return e.map((function(t){return Er(Er({},t),{},{__docsearch_parent:"lvl1"!==t.type&&e.find((function(e){return"lvl1"===e.type&&e.hierarchy.lvl1===t.hierarchy.lvl1}))})}))})).flat()}}}))})):S?[]:[{sourceId:"recentSearches",onSelect:function(e){var t=e.item,r=e.event;K(t),r.shiftKey||r.ctrlKey||r.metaKey||l()},getItemUrl:function(e){return e.item.url},getItems:function(){return V.getAll()}},{sourceId:"favoriteSearches",onSelect:function(e){var t=e.item,r=e.event;K(t),r.shiftKey||r.ctrlKey||r.metaKey||l()},getItemUrl:function(e){return e.item.url},getItems:function(){return B.getAll()}}]}})}),[n,c,U,l,V,B,K,F,a,h,u,S]),$=J.getEnvironmentProps,z=J.getRootProps,W=J.refresh;return function(e){var t=e.getEnvironmentProps,r=e.panelElement,n=e.formElement,o=e.inputElement;ke.useEffect((function(){if(r&&n&&o){var e=t({panelElement:r,formElement:n,inputElement:o}),a=e.onTouchStart,c=e.onTouchMove;return window.addEventListener("touchstart",a),window.addEventListener("touchmove",c),function(){window.removeEventListener("touchstart",a),window.removeEventListener("touchmove",c)}}}),[t,r,n,o])}({getEnvironmentProps:$,panelElement:T.current,formElement:q.current,inputElement:L.current}),function(e){var t=e.container;ke.useEffect((function(){if(t){var e=t.querySelectorAll("a[href]:not([disabled]), button:not([disabled]), input:not([disabled])"),r=e[0],n=e[e.length-1];return t.addEventListener("keydown",o),function(){t.removeEventListener("keydown",o)}}function o(e){"Tab"===e.key&&(e.shiftKey?document.activeElement===r&&(e.preventDefault(),n.focus()):document.activeElement===n&&(e.preventDefault(),r.focus()))}}),[t])}({container:R.current}),ke.useEffect((function(){return document.body.classList.add("DocSearch--active"),function(){var e,t;document.body.classList.remove("DocSearch--active"),null===(e=(t=window).scrollTo)||void 0===e||e.call(t,0,y)}}),[]),ke.useEffect((function(){window.matchMedia("(max-width: 768px)").matches&&(M.current=5)}),[]),ke.useEffect((function(){T.current&&(T.current.scrollTop=0)}),[x.query]),ke.useEffect((function(){F.length>0&&(W(),L.current&&L.current.focus())}),[F,W]),ke.useEffect((function(){function e(){if(_.current){var e=.01*window.innerHeight;_.current.style.setProperty("--docsearch-vh","".concat(e,"px"))}}return e(),window.addEventListener("resize",e),function(){window.removeEventListener("resize",e)}}),[]),ke.createElement("div",Or({ref:R},z({"aria-expanded":!0}),{className:["DocSearch","DocSearch-Container","stalled"===x.status&&"DocSearch-Container--Stalled","error"===x.status&&"DocSearch-Container--Errored"].filter(Boolean).join(" "),role:"button",tabIndex:0,onMouseDown:function(e){e.target===e.currentTarget&&l()}}),ke.createElement("div",{className:"DocSearch-Modal",ref:_},ke.createElement("header",{className:"DocSearch-SearchBar",ref:q},ke.createElement(It,Or({},J,{state:x,autoFocus:0===F.length,inputRef:L,isFromSelection:Boolean(F)&&F===H,translations:C,onClose:l}))),ke.createElement("div",{className:"DocSearch-Dropdown",ref:T},ke.createElement(Ot,Or({},J,{indexName:n,state:x,hitComponent:m,resultsFooterComponent:d,disableUserPersonalization:S,recentSearches:V,favoriteSearches:B,inputRef:L,translations:k,getMissingResultsUrl:I,onItemClick:function(e){K(e),l()}}))),ke.createElement("footer",{className:"DocSearch-Footer"},ke.createElement(Ne,{translations:D}))))}}}]); \ No newline at end of file diff --git a/assets/js/687.7164fd06.js b/assets/js/687.7164fd06.js new file mode 100644 index 000000000..effff6baa --- /dev/null +++ b/assets/js/687.7164fd06.js @@ -0,0 +1,14653 @@ +"use strict"; +exports.id = 687; +exports.ids = [687]; +exports.modules = { + +/***/ 64589: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array<unknown>} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array<string>} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array<Extension>} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record<string, unknown>} */ + const left = maybe || (all[hook] = {}) + /** @type {Record<string, unknown> | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array<unknown>} existing + * @param {Array<unknown>} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array<unknown>} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array<HtmlExtension>} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array<StackItem>} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function micromark_util_chunked_splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function micromark_util_chunked_push(list, items) { + if (list.length > 0) { + micromark_util_chunked_splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array<Event>} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record<string, number>} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array<Event>} */ + let parameters + /** @type {Array<Event>} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + micromark_util_chunked_splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array<Event>} events + * @param {number} eventIndex + * @returns {Record<string, number>} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array<number>} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record<string, number>} */ + const gaps = {} + /** @type {Array<Chunk>} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + micromark_util_chunked_splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array<Event>} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array<Event>} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array<Resolver>} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit<Point, '_bufferIndex' | '_index'> | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record<string, number>} */ + const columnStart = {} + /** @type {Array<Construct>} */ + const resolveAllConstructs = [] + /** @type {Array<Chunk>} */ + let chunks = [] + /** @type {Array<Token>} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array<Construct> | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array<Construct>} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array<Construct>} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array<Chunk>} chunks + * @param {Pick<Token, 'end' | 'start'>} token + * @returns {Array<Chunk>} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array<Chunk>} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array<Chunk>} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array<string>} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * <a> + * <a\>b> + * <a b> + * <a)> + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`<a>` or `b`). + * @param {TokenType} literalType + * Type when enclosed (`<a>`). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | <aa> + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | <a\*a> + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | <x /> + * ^ + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<!-`, inside a comment, at another `-`. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<![`, inside CDATA, expecting `CDATA[`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | </x> + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | <ab> + * ^^ + * > | </ab> + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > | <div/> + * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | <x/> + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | <a /> + * ^ + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * > | <a > + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | <a b> + * ^ + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | <a b=c> + * ^ + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | <a b="c"> + * ^ + * > | <a b='c'> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | <x> + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | <x> + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after `</`, in a raw tag name. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | <!--> + * ^ + * > | <?> + * ^ + * > | <!q> + * ^ + * > | <!--ab--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > | <div> + * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record<string, string>} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array<Event>} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + * <p>!<a href=\"b\">^a</a></p> + * <p>!<a href=\"c\">^a</a></p> + * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array<Event>} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | a<user.name@ex-ample.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code> | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a <b> c + * ^ + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * > | a <![CDATA[>&<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after `<!-`, at another `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After `<![`, in CDATA, expecting `CDATA[`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a <!b> c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After `</x`, in a tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After `<x`, in opening tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a <!--a + * ^ + * | b--> + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array<Chunk>} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array<Chunk>} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array<Event>} events + * @returns {Array<Event>} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract<Node, UnistParent>} Parent + * + * @typedef {Omit<UnistParent, 'type' | 'children'> & {type: 'fragment', children: Array<PhrasingContent>}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record<string, Handle>} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array<string>} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array<Transform>} transforms + * Tree transforms. + * + * @typedef {Partial<Config>} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array<Node | Fragment>} stack + * Stack of nodes. + * @property {Array<TokenTuple>} tokenStack + * Stack of tokens. + * @property {<Key extends keyof CompileData>(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {<Key extends keyof CompileData>(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {<Kind extends Node>(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array<Extension | Array<Extension>> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array<Event>} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit<CompileContext, 'sliceSerialize'>} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array<number>} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array<Event>} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array<StaticPhrasingContent>} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array<Extension | Array<Extension>>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(18464); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-62fc7601.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.Z)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "<br/>"); + } else if (node.type === "strong") { + return `<strong>${node.children.map(output).join("")}</strong>`; + } else if (node.type === "emphasis") { + return `<em>${node.children.map(output).join("")}</em>`; + } else if (node.type === "paragraph") { + return `<p>${node.children.map(output).join("")}</p>`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + <span class="${labelClass} ${classes}" ` + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_8af3addd.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_8af3addd.J)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 78687: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(56363); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(64589); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 10, 12, 14, 16, 18, 19, 21, 23], $V1 = [2, 6], $V2 = [1, 3], $V3 = [1, 5], $V4 = [1, 6], $V5 = [1, 7], $V6 = [1, 5, 10, 12, 14, 16, 18, 19, 21, 23, 34, 35, 36], $V7 = [1, 25], $V8 = [1, 26], $V9 = [1, 28], $Va = [1, 29], $Vb = [1, 30], $Vc = [1, 31], $Vd = [1, 32], $Ve = [1, 33], $Vf = [1, 34], $Vg = [1, 35], $Vh = [1, 36], $Vi = [1, 37], $Vj = [1, 43], $Vk = [1, 42], $Vl = [1, 47], $Vm = [1, 50], $Vn = [1, 10, 12, 14, 16, 18, 19, 21, 23, 34, 35, 36], $Vo = [1, 10, 12, 14, 16, 18, 19, 21, 23, 24, 26, 27, 28, 34, 35, 36], $Vp = [1, 10, 12, 14, 16, 18, 19, 21, 23, 24, 26, 27, 28, 34, 35, 36, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], $Vq = [1, 64]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "eol": 4, "XYCHART": 5, "chartConfig": 6, "document": 7, "CHART_ORIENTATION": 8, "statement": 9, "title": 10, "text": 11, "X_AXIS": 12, "parseXAxis": 13, "Y_AXIS": 14, "parseYAxis": 15, "LINE": 16, "plotData": 17, "BAR": 18, "acc_title": 19, "acc_title_value": 20, "acc_descr": 21, "acc_descr_value": 22, "acc_descr_multiline_value": 23, "SQUARE_BRACES_START": 24, "commaSeparatedNumbers": 25, "SQUARE_BRACES_END": 26, "NUMBER_WITH_DECIMAL": 27, "COMMA": 28, "xAxisData": 29, "bandData": 30, "ARROW_DELIMITER": 31, "commaSeparatedTexts": 32, "yAxisData": 33, "NEWLINE": 34, "SEMI": 35, "EOF": 36, "alphaNum": 37, "STR": 38, "MD_STR": 39, "alphaNumToken": 40, "AMP": 41, "NUM": 42, "ALPHA": 43, "PLUS": 44, "EQUALS": 45, "MULT": 46, "DOT": 47, "BRKT": 48, "MINUS": 49, "UNDERSCORE": 50, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "XYCHART", 8: "CHART_ORIENTATION", 10: "title", 12: "X_AXIS", 14: "Y_AXIS", 16: "LINE", 18: "BAR", 19: "acc_title", 20: "acc_title_value", 21: "acc_descr", 22: "acc_descr_value", 23: "acc_descr_multiline_value", 24: "SQUARE_BRACES_START", 26: "SQUARE_BRACES_END", 27: "NUMBER_WITH_DECIMAL", 28: "COMMA", 31: "ARROW_DELIMITER", 34: "NEWLINE", 35: "SEMI", 36: "EOF", 38: "STR", 39: "MD_STR", 41: "AMP", 42: "NUM", 43: "ALPHA", 44: "PLUS", 45: "EQUALS", 46: "MULT", 47: "DOT", 48: "BRKT", 49: "MINUS", 50: "UNDERSCORE" }, + productions_: [0, [3, 2], [3, 3], [3, 2], [3, 1], [6, 1], [7, 0], [7, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 3], [9, 2], [9, 3], [9, 2], [9, 2], [9, 1], [17, 3], [25, 3], [25, 1], [13, 1], [13, 2], [13, 1], [29, 1], [29, 3], [30, 3], [32, 3], [32, 1], [15, 1], [15, 2], [15, 1], [33, 3], [4, 1], [4, 1], [4, 1], [11, 1], [11, 1], [11, 1], [37, 1], [37, 2], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 5: + yy.setOrientation($$[$0]); + break; + case 9: + yy.setDiagramTitle($$[$0].text.trim()); + break; + case 12: + yy.setLineData({ text: "", type: "text" }, $$[$0]); + break; + case 13: + yy.setLineData($$[$0 - 1], $$[$0]); + break; + case 14: + yy.setBarData({ text: "", type: "text" }, $$[$0]); + break; + case 15: + yy.setBarData($$[$0 - 1], $$[$0]); + break; + case 16: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 17: + case 18: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 19: + this.$ = $$[$0 - 1]; + break; + case 20: + this.$ = [Number($$[$0 - 2]), ...$$[$0]]; + break; + case 21: + this.$ = [Number($$[$0])]; + break; + case 22: + yy.setXAxisTitle($$[$0]); + break; + case 23: + yy.setXAxisTitle($$[$0 - 1]); + break; + case 24: + yy.setXAxisTitle({ type: "text", text: "" }); + break; + case 25: + yy.setXAxisBand($$[$0]); + break; + case 26: + yy.setXAxisRangeData(Number($$[$0 - 2]), Number($$[$0])); + break; + case 27: + this.$ = $$[$0 - 1]; + break; + case 28: + this.$ = [$$[$0 - 2], ...$$[$0]]; + break; + case 29: + this.$ = [$$[$0]]; + break; + case 30: + yy.setYAxisTitle($$[$0]); + break; + case 31: + yy.setYAxisTitle($$[$0 - 1]); + break; + case 32: + yy.setYAxisTitle({ type: "text", text: "" }); + break; + case 33: + yy.setYAxisRangeData(Number($$[$0 - 2]), Number($$[$0])); + break; + case 37: + this.$ = { text: $$[$0], type: "text" }; + break; + case 38: + this.$ = { text: $$[$0], type: "text" }; + break; + case 39: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 40: + this.$ = $$[$0]; + break; + case 41: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + } + }, + table: [o($V0, $V1, { 3: 1, 4: 2, 7: 4, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), { 1: [3] }, o($V0, $V1, { 4: 2, 7: 4, 3: 8, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), o($V0, $V1, { 4: 2, 7: 4, 6: 9, 3: 10, 5: $V2, 8: [1, 11], 34: $V3, 35: $V4, 36: $V5 }), { 1: [2, 4], 9: 12, 10: [1, 13], 12: [1, 14], 14: [1, 15], 16: [1, 16], 18: [1, 17], 19: [1, 18], 21: [1, 19], 23: [1, 20] }, o($V6, [2, 34]), o($V6, [2, 35]), o($V6, [2, 36]), { 1: [2, 1] }, o($V0, $V1, { 4: 2, 7: 4, 3: 21, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), { 1: [2, 3] }, o($V6, [2, 5]), o($V0, [2, 7], { 4: 22, 34: $V3, 35: $V4, 36: $V5 }), { 11: 23, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 39, 13: 38, 24: $Vj, 27: $Vk, 29: 40, 30: 41, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 45, 15: 44, 27: $Vl, 33: 46, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 49, 17: 48, 24: $Vm, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 52, 17: 51, 24: $Vm, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 20: [1, 53] }, { 22: [1, 54] }, o($Vn, [2, 18]), { 1: [2, 2] }, o($Vn, [2, 8]), o($Vn, [2, 9]), o($Vo, [2, 37], { 40: 55, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }), o($Vo, [2, 38]), o($Vo, [2, 39]), o($Vp, [2, 40]), o($Vp, [2, 42]), o($Vp, [2, 43]), o($Vp, [2, 44]), o($Vp, [2, 45]), o($Vp, [2, 46]), o($Vp, [2, 47]), o($Vp, [2, 48]), o($Vp, [2, 49]), o($Vp, [2, 50]), o($Vp, [2, 51]), o($Vn, [2, 10]), o($Vn, [2, 22], { 30: 41, 29: 56, 24: $Vj, 27: $Vk }), o($Vn, [2, 24]), o($Vn, [2, 25]), { 31: [1, 57] }, { 11: 59, 32: 58, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, o($Vn, [2, 11]), o($Vn, [2, 30], { 33: 60, 27: $Vl }), o($Vn, [2, 32]), { 31: [1, 61] }, o($Vn, [2, 12]), { 17: 62, 24: $Vm }, { 25: 63, 27: $Vq }, o($Vn, [2, 14]), { 17: 65, 24: $Vm }, o($Vn, [2, 16]), o($Vn, [2, 17]), o($Vp, [2, 41]), o($Vn, [2, 23]), { 27: [1, 66] }, { 26: [1, 67] }, { 26: [2, 29], 28: [1, 68] }, o($Vn, [2, 31]), { 27: [1, 69] }, o($Vn, [2, 13]), { 26: [1, 70] }, { 26: [2, 21], 28: [1, 71] }, o($Vn, [2, 15]), o($Vn, [2, 26]), o($Vn, [2, 27]), { 11: 59, 32: 72, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, o($Vn, [2, 33]), o($Vn, [2, 19]), { 25: 73, 27: $Vq }, { 26: [2, 28] }, { 26: [2, 20] }], + defaultActions: { 8: [2, 1], 10: [2, 3], 21: [2, 2], 72: [2, 28], 73: [2, 20] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + break; + case 1: + break; + case 2: + this.popState(); + return 34; + case 3: + this.popState(); + return 34; + case 4: + return 34; + case 5: + break; + case 6: + return 10; + case 7: + this.pushState("acc_title"); + return 19; + case 8: + this.popState(); + return "acc_title_value"; + case 9: + this.pushState("acc_descr"); + return 21; + case 10: + this.popState(); + return "acc_descr_value"; + case 11: + this.pushState("acc_descr_multiline"); + break; + case 12: + this.popState(); + break; + case 13: + return "acc_descr_multiline_value"; + case 14: + return 5; + case 15: + return 8; + case 16: + this.pushState("axis_data"); + return "X_AXIS"; + case 17: + this.pushState("axis_data"); + return "Y_AXIS"; + case 18: + this.pushState("axis_band_data"); + return 24; + case 19: + return 31; + case 20: + this.pushState("data"); + return 16; + case 21: + this.pushState("data"); + return 18; + case 22: + this.pushState("data_inner"); + return 24; + case 23: + return 27; + case 24: + this.popState(); + return 26; + case 25: + this.popState(); + break; + case 26: + this.pushState("string"); + break; + case 27: + this.popState(); + break; + case 28: + return "STR"; + case 29: + return 24; + case 30: + return 26; + case 31: + return 43; + case 32: + return "COLON"; + case 33: + return 44; + case 34: + return 28; + case 35: + return 45; + case 36: + return 46; + case 37: + return 48; + case 38: + return 50; + case 39: + return 47; + case 40: + return 41; + case 41: + return 49; + case 42: + return 42; + case 43: + break; + case 44: + return 35; + case 45: + return 36; + } + }, + rules: [/^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:(\r?\n))/i, /^(?:(\r?\n))/i, /^(?:[\n\r]+)/i, /^(?:%%[^\n]*)/i, /^(?:title\b)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:\{)/i, /^(?:[^\}]*)/i, /^(?:xychart-beta\b)/i, /^(?:(?:vertical|horizontal))/i, /^(?:x-axis\b)/i, /^(?:y-axis\b)/i, /^(?:\[)/i, /^(?:-->)/i, /^(?:line\b)/i, /^(?:bar\b)/i, /^(?:\[)/i, /^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i, /^(?:\])/i, /^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n<md_string>\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n<md_string>\(\?:`))/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:\[)/i, /^(?:\])/i, /^(?:[A-Za-z]+)/i, /^(?::)/i, /^(?:\+)/i, /^(?:,)/i, /^(?:=)/i, /^(?:\*)/i, /^(?:#)/i, /^(?:[\_])/i, /^(?:\.)/i, /^(?:&)/i, /^(?:-)/i, /^(?:[0-9]+)/i, /^(?:\s+)/i, /^(?:;)/i, /^(?:$)/i], + conditions: { "data_inner": { "rules": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true }, "data": { "rules": [0, 1, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 22, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true }, "axis_band_data": { "rules": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true }, "axis_data": { "rules": [0, 1, 2, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18, 19, 20, 21, 23, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true }, "acc_descr_multiline": { "rules": [12, 13], "inclusive": false }, "acc_descr": { "rules": [10], "inclusive": false }, "acc_title": { "rules": [8], "inclusive": false }, "title": { "rules": [], "inclusive": false }, "md_string": { "rules": [], "inclusive": false }, "string": { "rules": [27, 28], "inclusive": false }, "INITIAL": { "rules": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +function isBarPlot(data) { + return data.type === "bar"; +} +function isBandAxisData(data) { + return data.type === "band"; +} +function isLinearAxisData(data) { + return data.type === "linear"; +} +class TextDimensionCalculatorWithFont { + constructor(parentGroup) { + this.parentGroup = parentGroup; + } + getMaxDimension(texts, fontSize) { + if (!this.parentGroup) { + return { + width: texts.reduce((acc, cur) => Math.max(cur.length, acc), 0) * fontSize, + height: fontSize + }; + } + const dimension = { + width: 0, + height: 0 + }; + const elem = this.parentGroup.append("g").attr("visibility", "hidden").attr("font-size", fontSize); + for (const t of texts) { + const bbox = (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_4__.c)(elem, 1, t); + const width = bbox ? bbox.width : t.length * fontSize; + const height = bbox ? bbox.height : fontSize; + dimension.width = Math.max(dimension.width, width); + dimension.height = Math.max(dimension.height, height); + } + elem.remove(); + return dimension; + } +} +const BAR_WIDTH_TO_TICK_WIDTH_RATIO = 0.7; +const MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL = 0.2; +class BaseAxis { + constructor(axisConfig, title, textDimensionCalculator, axisThemeConfig) { + this.axisConfig = axisConfig; + this.title = title; + this.textDimensionCalculator = textDimensionCalculator; + this.axisThemeConfig = axisThemeConfig; + this.boundingRect = { x: 0, y: 0, width: 0, height: 0 }; + this.axisPosition = "left"; + this.showTitle = false; + this.showLabel = false; + this.showTick = false; + this.showAxisLine = false; + this.outerPadding = 0; + this.titleTextHeight = 0; + this.labelTextHeight = 0; + this.range = [0, 10]; + this.boundingRect = { x: 0, y: 0, width: 0, height: 0 }; + this.axisPosition = "left"; + } + setRange(range) { + this.range = range; + if (this.axisPosition === "left" || this.axisPosition === "right") { + this.boundingRect.height = range[1] - range[0]; + } else { + this.boundingRect.width = range[1] - range[0]; + } + this.recalculateScale(); + } + getRange() { + return [this.range[0] + this.outerPadding, this.range[1] - this.outerPadding]; + } + setAxisPosition(axisPosition) { + this.axisPosition = axisPosition; + this.setRange(this.range); + } + getTickDistance() { + const range = this.getRange(); + return Math.abs(range[0] - range[1]) / this.getTickValues().length; + } + getAxisOuterPadding() { + return this.outerPadding; + } + getLabelDimension() { + return this.textDimensionCalculator.getMaxDimension( + this.getTickValues().map((tick) => tick.toString()), + this.axisConfig.labelFontSize + ); + } + recalculateOuterPaddingToDrawBar() { + if (BAR_WIDTH_TO_TICK_WIDTH_RATIO * this.getTickDistance() > this.outerPadding * 2) { + this.outerPadding = Math.floor(BAR_WIDTH_TO_TICK_WIDTH_RATIO * this.getTickDistance() / 2); + } + this.recalculateScale(); + } + calculateSpaceIfDrawnHorizontally(availableSpace) { + let availableHeight = availableSpace.height; + if (this.axisConfig.showAxisLine && availableHeight > this.axisConfig.axisLineWidth) { + availableHeight -= this.axisConfig.axisLineWidth; + this.showAxisLine = true; + } + if (this.axisConfig.showLabel) { + const spaceRequired = this.getLabelDimension(); + const maxPadding = MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL * availableSpace.width; + this.outerPadding = Math.min(spaceRequired.width / 2, maxPadding); + const heightRequired = spaceRequired.height + this.axisConfig.labelPadding * 2; + this.labelTextHeight = spaceRequired.height; + if (heightRequired <= availableHeight) { + availableHeight -= heightRequired; + this.showLabel = true; + } + } + if (this.axisConfig.showTick && availableHeight >= this.axisConfig.tickLength) { + this.showTick = true; + availableHeight -= this.axisConfig.tickLength; + } + if (this.axisConfig.showTitle && this.title) { + const spaceRequired = this.textDimensionCalculator.getMaxDimension( + [this.title], + this.axisConfig.titleFontSize + ); + const heightRequired = spaceRequired.height + this.axisConfig.titlePadding * 2; + this.titleTextHeight = spaceRequired.height; + if (heightRequired <= availableHeight) { + availableHeight -= heightRequired; + this.showTitle = true; + } + } + this.boundingRect.width = availableSpace.width; + this.boundingRect.height = availableSpace.height - availableHeight; + } + calculateSpaceIfDrawnVertical(availableSpace) { + let availableWidth = availableSpace.width; + if (this.axisConfig.showAxisLine && availableWidth > this.axisConfig.axisLineWidth) { + availableWidth -= this.axisConfig.axisLineWidth; + this.showAxisLine = true; + } + if (this.axisConfig.showLabel) { + const spaceRequired = this.getLabelDimension(); + const maxPadding = MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL * availableSpace.height; + this.outerPadding = Math.min(spaceRequired.height / 2, maxPadding); + const widthRequired = spaceRequired.width + this.axisConfig.labelPadding * 2; + if (widthRequired <= availableWidth) { + availableWidth -= widthRequired; + this.showLabel = true; + } + } + if (this.axisConfig.showTick && availableWidth >= this.axisConfig.tickLength) { + this.showTick = true; + availableWidth -= this.axisConfig.tickLength; + } + if (this.axisConfig.showTitle && this.title) { + const spaceRequired = this.textDimensionCalculator.getMaxDimension( + [this.title], + this.axisConfig.titleFontSize + ); + const widthRequired = spaceRequired.height + this.axisConfig.titlePadding * 2; + this.titleTextHeight = spaceRequired.height; + if (widthRequired <= availableWidth) { + availableWidth -= widthRequired; + this.showTitle = true; + } + } + this.boundingRect.width = availableSpace.width - availableWidth; + this.boundingRect.height = availableSpace.height; + } + calculateSpace(availableSpace) { + if (this.axisPosition === "left" || this.axisPosition === "right") { + this.calculateSpaceIfDrawnVertical(availableSpace); + } else { + this.calculateSpaceIfDrawnHorizontally(availableSpace); + } + this.recalculateScale(); + return { + width: this.boundingRect.width, + height: this.boundingRect.height + }; + } + setBoundingBoxXY(point) { + this.boundingRect.x = point.x; + this.boundingRect.y = point.y; + } + getDrawableElementsForLeftAxis() { + const drawableElement = []; + if (this.showAxisLine) { + const x = this.boundingRect.x + this.boundingRect.width - this.axisConfig.axisLineWidth / 2; + drawableElement.push({ + type: "path", + groupTexts: ["left-axis", "axisl-line"], + data: [ + { + path: `M ${x},${this.boundingRect.y} L ${x},${this.boundingRect.y + this.boundingRect.height} `, + strokeFill: this.axisThemeConfig.axisLineColor, + strokeWidth: this.axisConfig.axisLineWidth + } + ] + }); + } + if (this.showLabel) { + drawableElement.push({ + type: "text", + groupTexts: ["left-axis", "label"], + data: this.getTickValues().map((tick) => ({ + text: tick.toString(), + x: this.boundingRect.x + this.boundingRect.width - (this.showLabel ? this.axisConfig.labelPadding : 0) - (this.showTick ? this.axisConfig.tickLength : 0) - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0), + y: this.getScaleValue(tick), + fill: this.axisThemeConfig.labelColor, + fontSize: this.axisConfig.labelFontSize, + rotation: 0, + verticalPos: "middle", + horizontalPos: "right" + })) + }); + } + if (this.showTick) { + const x = this.boundingRect.x + this.boundingRect.width - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0); + drawableElement.push({ + type: "path", + groupTexts: ["left-axis", "ticks"], + data: this.getTickValues().map((tick) => ({ + path: `M ${x},${this.getScaleValue(tick)} L ${x - this.axisConfig.tickLength},${this.getScaleValue(tick)}`, + strokeFill: this.axisThemeConfig.tickColor, + strokeWidth: this.axisConfig.tickWidth + })) + }); + } + if (this.showTitle) { + drawableElement.push({ + type: "text", + groupTexts: ["left-axis", "title"], + data: [ + { + text: this.title, + x: this.boundingRect.x + this.axisConfig.titlePadding, + y: this.boundingRect.y + this.boundingRect.height / 2, + fill: this.axisThemeConfig.titleColor, + fontSize: this.axisConfig.titleFontSize, + rotation: 270, + verticalPos: "top", + horizontalPos: "center" + } + ] + }); + } + return drawableElement; + } + getDrawableElementsForBottomAxis() { + const drawableElement = []; + if (this.showAxisLine) { + const y = this.boundingRect.y + this.axisConfig.axisLineWidth / 2; + drawableElement.push({ + type: "path", + groupTexts: ["bottom-axis", "axis-line"], + data: [ + { + path: `M ${this.boundingRect.x},${y} L ${this.boundingRect.x + this.boundingRect.width},${y}`, + strokeFill: this.axisThemeConfig.axisLineColor, + strokeWidth: this.axisConfig.axisLineWidth + } + ] + }); + } + if (this.showLabel) { + drawableElement.push({ + type: "text", + groupTexts: ["bottom-axis", "label"], + data: this.getTickValues().map((tick) => ({ + text: tick.toString(), + x: this.getScaleValue(tick), + y: this.boundingRect.y + this.axisConfig.labelPadding + (this.showTick ? this.axisConfig.tickLength : 0) + (this.showAxisLine ? this.axisConfig.axisLineWidth : 0), + fill: this.axisThemeConfig.labelColor, + fontSize: this.axisConfig.labelFontSize, + rotation: 0, + verticalPos: "top", + horizontalPos: "center" + })) + }); + } + if (this.showTick) { + const y = this.boundingRect.y + (this.showAxisLine ? this.axisConfig.axisLineWidth : 0); + drawableElement.push({ + type: "path", + groupTexts: ["bottom-axis", "ticks"], + data: this.getTickValues().map((tick) => ({ + path: `M ${this.getScaleValue(tick)},${y} L ${this.getScaleValue(tick)},${y + this.axisConfig.tickLength}`, + strokeFill: this.axisThemeConfig.tickColor, + strokeWidth: this.axisConfig.tickWidth + })) + }); + } + if (this.showTitle) { + drawableElement.push({ + type: "text", + groupTexts: ["bottom-axis", "title"], + data: [ + { + text: this.title, + x: this.range[0] + (this.range[1] - this.range[0]) / 2, + y: this.boundingRect.y + this.boundingRect.height - this.axisConfig.titlePadding - this.titleTextHeight, + fill: this.axisThemeConfig.titleColor, + fontSize: this.axisConfig.titleFontSize, + rotation: 0, + verticalPos: "top", + horizontalPos: "center" + } + ] + }); + } + return drawableElement; + } + getDrawableElementsForTopAxis() { + const drawableElement = []; + if (this.showAxisLine) { + const y = this.boundingRect.y + this.boundingRect.height - this.axisConfig.axisLineWidth / 2; + drawableElement.push({ + type: "path", + groupTexts: ["top-axis", "axis-line"], + data: [ + { + path: `M ${this.boundingRect.x},${y} L ${this.boundingRect.x + this.boundingRect.width},${y}`, + strokeFill: this.axisThemeConfig.axisLineColor, + strokeWidth: this.axisConfig.axisLineWidth + } + ] + }); + } + if (this.showLabel) { + drawableElement.push({ + type: "text", + groupTexts: ["top-axis", "label"], + data: this.getTickValues().map((tick) => ({ + text: tick.toString(), + x: this.getScaleValue(tick), + y: this.boundingRect.y + (this.showTitle ? this.titleTextHeight + this.axisConfig.titlePadding * 2 : 0) + this.axisConfig.labelPadding, + fill: this.axisThemeConfig.labelColor, + fontSize: this.axisConfig.labelFontSize, + rotation: 0, + verticalPos: "top", + horizontalPos: "center" + })) + }); + } + if (this.showTick) { + const y = this.boundingRect.y; + drawableElement.push({ + type: "path", + groupTexts: ["top-axis", "ticks"], + data: this.getTickValues().map((tick) => ({ + path: `M ${this.getScaleValue(tick)},${y + this.boundingRect.height - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0)} L ${this.getScaleValue(tick)},${y + this.boundingRect.height - this.axisConfig.tickLength - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0)}`, + strokeFill: this.axisThemeConfig.tickColor, + strokeWidth: this.axisConfig.tickWidth + })) + }); + } + if (this.showTitle) { + drawableElement.push({ + type: "text", + groupTexts: ["top-axis", "title"], + data: [ + { + text: this.title, + x: this.boundingRect.x + this.boundingRect.width / 2, + y: this.boundingRect.y + this.axisConfig.titlePadding, + fill: this.axisThemeConfig.titleColor, + fontSize: this.axisConfig.titleFontSize, + rotation: 0, + verticalPos: "top", + horizontalPos: "center" + } + ] + }); + } + return drawableElement; + } + getDrawableElements() { + if (this.axisPosition === "left") { + return this.getDrawableElementsForLeftAxis(); + } + if (this.axisPosition === "right") { + throw Error("Drawing of right axis is not implemented"); + } + if (this.axisPosition === "bottom") { + return this.getDrawableElementsForBottomAxis(); + } + if (this.axisPosition === "top") { + return this.getDrawableElementsForTopAxis(); + } + return []; + } +} +class BandAxis extends BaseAxis { + constructor(axisConfig, axisThemeConfig, categories, title, textDimensionCalculator) { + super(axisConfig, title, textDimensionCalculator, axisThemeConfig); + this.categories = categories; + this.scale = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleBand */ .tiA)().domain(this.categories).range(this.getRange()); + } + setRange(range) { + super.setRange(range); + } + recalculateScale() { + this.scale = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleBand */ .tiA)().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(0.5); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.trace("BandAxis axis final categories, range: ", this.categories, this.getRange()); + } + getTickValues() { + return this.categories; + } + getScaleValue(value) { + return this.scale(value) || this.getRange()[0]; + } +} +class LinearAxis extends BaseAxis { + constructor(axisConfig, axisThemeConfig, domain, title, textDimensionCalculator) { + super(axisConfig, title, textDimensionCalculator, axisThemeConfig); + this.domain = domain; + this.scale = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleLinear */ .BYU)().domain(this.domain).range(this.getRange()); + } + getTickValues() { + return this.scale.ticks(); + } + recalculateScale() { + const domain = [...this.domain]; + if (this.axisPosition === "left") { + domain.reverse(); + } + this.scale = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .scaleLinear */ .BYU)().domain(domain).range(this.getRange()); + } + getScaleValue(value) { + return this.scale(value); + } +} +function getAxis(data, axisConfig, axisThemeConfig, tmpSVGGroup2) { + const textDimansionCalculator = new TextDimensionCalculatorWithFont(tmpSVGGroup2); + if (isBandAxisData(data)) { + return new BandAxis( + axisConfig, + axisThemeConfig, + data.categories, + data.title, + textDimansionCalculator + ); + } + return new LinearAxis( + axisConfig, + axisThemeConfig, + [data.min, data.max], + data.title, + textDimansionCalculator + ); +} +class ChartTitle { + constructor(textDimensionCalculator, chartConfig, chartData, chartThemeConfig) { + this.textDimensionCalculator = textDimensionCalculator; + this.chartConfig = chartConfig; + this.chartData = chartData; + this.chartThemeConfig = chartThemeConfig; + this.boundingRect = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + this.showChartTitle = false; + } + setBoundingBoxXY(point) { + this.boundingRect.x = point.x; + this.boundingRect.y = point.y; + } + calculateSpace(availableSpace) { + const titleDimension = this.textDimensionCalculator.getMaxDimension( + [this.chartData.title], + this.chartConfig.titleFontSize + ); + const widthRequired = Math.max(titleDimension.width, availableSpace.width); + const heightRequired = titleDimension.height + 2 * this.chartConfig.titlePadding; + if (titleDimension.width <= widthRequired && titleDimension.height <= heightRequired && this.chartConfig.showTitle && this.chartData.title) { + this.boundingRect.width = widthRequired; + this.boundingRect.height = heightRequired; + this.showChartTitle = true; + } + return { + width: this.boundingRect.width, + height: this.boundingRect.height + }; + } + getDrawableElements() { + const drawableElem = []; + if (this.showChartTitle) { + drawableElem.push({ + groupTexts: ["chart-title"], + type: "text", + data: [ + { + fontSize: this.chartConfig.titleFontSize, + text: this.chartData.title, + verticalPos: "middle", + horizontalPos: "center", + x: this.boundingRect.x + this.boundingRect.width / 2, + y: this.boundingRect.y + this.boundingRect.height / 2, + fill: this.chartThemeConfig.titleColor, + rotation: 0 + } + ] + }); + } + return drawableElem; + } +} +function getChartTitleComponent(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2) { + const textDimensionCalculator = new TextDimensionCalculatorWithFont(tmpSVGGroup2); + return new ChartTitle(textDimensionCalculator, chartConfig, chartData, chartThemeConfig); +} +class LinePlot { + constructor(plotData, xAxis, yAxis, orientation, plotIndex2) { + this.plotData = plotData; + this.xAxis = xAxis; + this.yAxis = yAxis; + this.orientation = orientation; + this.plotIndex = plotIndex2; + } + getDrawableElement() { + const finalData = this.plotData.data.map((d) => [ + this.xAxis.getScaleValue(d[0]), + this.yAxis.getScaleValue(d[1]) + ]); + let path; + if (this.orientation === "horizontal") { + path = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().y((d) => d[0]).x((d) => d[1])(finalData); + } else { + path = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x((d) => d[0]).y((d) => d[1])(finalData); + } + if (!path) { + return []; + } + return [ + { + groupTexts: ["plot", `line-plot-${this.plotIndex}`], + type: "path", + data: [ + { + path, + strokeFill: this.plotData.strokeFill, + strokeWidth: this.plotData.strokeWidth + } + ] + } + ]; + } +} +class BarPlot { + constructor(barData, boundingRect, xAxis, yAxis, orientation, plotIndex2) { + this.barData = barData; + this.boundingRect = boundingRect; + this.xAxis = xAxis; + this.yAxis = yAxis; + this.orientation = orientation; + this.plotIndex = plotIndex2; + } + getDrawableElement() { + const finalData = this.barData.data.map((d) => [ + this.xAxis.getScaleValue(d[0]), + this.yAxis.getScaleValue(d[1]) + ]); + const barPaddingPercent = 0.05; + const barWidth = Math.min(this.xAxis.getAxisOuterPadding() * 2, this.xAxis.getTickDistance()) * (1 - barPaddingPercent); + const barWidthHalf = barWidth / 2; + if (this.orientation === "horizontal") { + return [ + { + groupTexts: ["plot", `bar-plot-${this.plotIndex}`], + type: "rect", + data: finalData.map((data) => ({ + x: this.boundingRect.x, + y: data[0] - barWidthHalf, + height: barWidth, + width: data[1] - this.boundingRect.x, + fill: this.barData.fill, + strokeWidth: 0, + strokeFill: this.barData.fill + })) + } + ]; + } + return [ + { + groupTexts: ["plot", `bar-plot-${this.plotIndex}`], + type: "rect", + data: finalData.map((data) => ({ + x: data[0] - barWidthHalf, + y: data[1], + width: barWidth, + height: this.boundingRect.y + this.boundingRect.height - data[1], + fill: this.barData.fill, + strokeWidth: 0, + strokeFill: this.barData.fill + })) + } + ]; + } +} +class BasePlot { + constructor(chartConfig, chartData, chartThemeConfig) { + this.chartConfig = chartConfig; + this.chartData = chartData; + this.chartThemeConfig = chartThemeConfig; + this.boundingRect = { + x: 0, + y: 0, + width: 0, + height: 0 + }; + } + setAxes(xAxis, yAxis) { + this.xAxis = xAxis; + this.yAxis = yAxis; + } + setBoundingBoxXY(point) { + this.boundingRect.x = point.x; + this.boundingRect.y = point.y; + } + calculateSpace(availableSpace) { + this.boundingRect.width = availableSpace.width; + this.boundingRect.height = availableSpace.height; + return { + width: this.boundingRect.width, + height: this.boundingRect.height + }; + } + getDrawableElements() { + if (!(this.xAxis && this.yAxis)) { + throw Error("Axes must be passed to render Plots"); + } + const drawableElem = []; + for (const [i, plot] of this.chartData.plots.entries()) { + switch (plot.type) { + case "line": + { + const linePlot = new LinePlot( + plot, + this.xAxis, + this.yAxis, + this.chartConfig.chartOrientation, + i + ); + drawableElem.push(...linePlot.getDrawableElement()); + } + break; + case "bar": + { + const barPlot = new BarPlot( + plot, + this.boundingRect, + this.xAxis, + this.yAxis, + this.chartConfig.chartOrientation, + i + ); + drawableElem.push(...barPlot.getDrawableElement()); + } + break; + } + } + return drawableElem; + } +} +function getPlotComponent(chartConfig, chartData, chartThemeConfig) { + return new BasePlot(chartConfig, chartData, chartThemeConfig); +} +class Orchestrator { + constructor(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2) { + this.chartConfig = chartConfig; + this.chartData = chartData; + this.componentStore = { + title: getChartTitleComponent(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2), + plot: getPlotComponent(chartConfig, chartData, chartThemeConfig), + xAxis: getAxis( + chartData.xAxis, + chartConfig.xAxis, + { + titleColor: chartThemeConfig.xAxisTitleColor, + labelColor: chartThemeConfig.xAxisLabelColor, + tickColor: chartThemeConfig.xAxisTickColor, + axisLineColor: chartThemeConfig.xAxisLineColor + }, + tmpSVGGroup2 + ), + yAxis: getAxis( + chartData.yAxis, + chartConfig.yAxis, + { + titleColor: chartThemeConfig.yAxisTitleColor, + labelColor: chartThemeConfig.yAxisLabelColor, + tickColor: chartThemeConfig.yAxisTickColor, + axisLineColor: chartThemeConfig.yAxisLineColor + }, + tmpSVGGroup2 + ) + }; + } + calculateVerticalSpace() { + let availableWidth = this.chartConfig.width; + let availableHeight = this.chartConfig.height; + let plotX = 0; + let plotY = 0; + let chartWidth = Math.floor(availableWidth * this.chartConfig.plotReservedSpacePercent / 100); + let chartHeight = Math.floor( + availableHeight * this.chartConfig.plotReservedSpacePercent / 100 + ); + let spaceUsed = this.componentStore.plot.calculateSpace({ + width: chartWidth, + height: chartHeight + }); + availableWidth -= spaceUsed.width; + availableHeight -= spaceUsed.height; + spaceUsed = this.componentStore.title.calculateSpace({ + width: this.chartConfig.width, + height: availableHeight + }); + plotY = spaceUsed.height; + availableHeight -= spaceUsed.height; + this.componentStore.xAxis.setAxisPosition("bottom"); + spaceUsed = this.componentStore.xAxis.calculateSpace({ + width: availableWidth, + height: availableHeight + }); + availableHeight -= spaceUsed.height; + this.componentStore.yAxis.setAxisPosition("left"); + spaceUsed = this.componentStore.yAxis.calculateSpace({ + width: availableWidth, + height: availableHeight + }); + plotX = spaceUsed.width; + availableWidth -= spaceUsed.width; + if (availableWidth > 0) { + chartWidth += availableWidth; + availableWidth = 0; + } + if (availableHeight > 0) { + chartHeight += availableHeight; + availableHeight = 0; + } + this.componentStore.plot.calculateSpace({ + width: chartWidth, + height: chartHeight + }); + this.componentStore.plot.setBoundingBoxXY({ x: plotX, y: plotY }); + this.componentStore.xAxis.setRange([plotX, plotX + chartWidth]); + this.componentStore.xAxis.setBoundingBoxXY({ x: plotX, y: plotY + chartHeight }); + this.componentStore.yAxis.setRange([plotY, plotY + chartHeight]); + this.componentStore.yAxis.setBoundingBoxXY({ x: 0, y: plotY }); + if (this.chartData.plots.some((p) => isBarPlot(p))) { + this.componentStore.xAxis.recalculateOuterPaddingToDrawBar(); + } + } + calculateHorizonatalSpace() { + let availableWidth = this.chartConfig.width; + let availableHeight = this.chartConfig.height; + let titleYEnd = 0; + let plotX = 0; + let plotY = 0; + let chartWidth = Math.floor(availableWidth * this.chartConfig.plotReservedSpacePercent / 100); + let chartHeight = Math.floor( + availableHeight * this.chartConfig.plotReservedSpacePercent / 100 + ); + let spaceUsed = this.componentStore.plot.calculateSpace({ + width: chartWidth, + height: chartHeight + }); + availableWidth -= spaceUsed.width; + availableHeight -= spaceUsed.height; + spaceUsed = this.componentStore.title.calculateSpace({ + width: this.chartConfig.width, + height: availableHeight + }); + titleYEnd = spaceUsed.height; + availableHeight -= spaceUsed.height; + this.componentStore.xAxis.setAxisPosition("left"); + spaceUsed = this.componentStore.xAxis.calculateSpace({ + width: availableWidth, + height: availableHeight + }); + availableWidth -= spaceUsed.width; + plotX = spaceUsed.width; + this.componentStore.yAxis.setAxisPosition("top"); + spaceUsed = this.componentStore.yAxis.calculateSpace({ + width: availableWidth, + height: availableHeight + }); + availableHeight -= spaceUsed.height; + plotY = titleYEnd + spaceUsed.height; + if (availableWidth > 0) { + chartWidth += availableWidth; + availableWidth = 0; + } + if (availableHeight > 0) { + chartHeight += availableHeight; + availableHeight = 0; + } + this.componentStore.plot.calculateSpace({ + width: chartWidth, + height: chartHeight + }); + this.componentStore.plot.setBoundingBoxXY({ x: plotX, y: plotY }); + this.componentStore.yAxis.setRange([plotX, plotX + chartWidth]); + this.componentStore.yAxis.setBoundingBoxXY({ x: plotX, y: titleYEnd }); + this.componentStore.xAxis.setRange([plotY, plotY + chartHeight]); + this.componentStore.xAxis.setBoundingBoxXY({ x: 0, y: plotY }); + if (this.chartData.plots.some((p) => isBarPlot(p))) { + this.componentStore.xAxis.recalculateOuterPaddingToDrawBar(); + } + } + calculateSpace() { + if (this.chartConfig.chartOrientation === "horizontal") { + this.calculateHorizonatalSpace(); + } else { + this.calculateVerticalSpace(); + } + } + getDrawableElement() { + this.calculateSpace(); + const drawableElem = []; + this.componentStore.plot.setAxes(this.componentStore.xAxis, this.componentStore.yAxis); + for (const component of Object.values(this.componentStore)) { + drawableElem.push(...component.getDrawableElements()); + } + return drawableElem; + } +} +class XYChartBuilder { + static build(config, chartData, chartThemeConfig, tmpSVGGroup2) { + const orchestrator = new Orchestrator(config, chartData, chartThemeConfig, tmpSVGGroup2); + return orchestrator.getDrawableElement(); + } +} +let plotIndex = 0; +let tmpSVGGroup; +let xyChartConfig = getChartDefaultConfig(); +let xyChartThemeConfig = getChartDefaultThemeConfig(); +let xyChartData = getChartDefaultData(); +let plotColorPalette = xyChartThemeConfig.plotColorPalette.split(",").map((color) => color.trim()); +let hasSetXAxis = false; +let hasSetYAxis = false; +function getChartDefaultThemeConfig() { + const defaultThemeVariables = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.D)(); + const config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.E)(); + return (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.B)(defaultThemeVariables.xyChart, config.themeVariables.xyChart); +} +function getChartDefaultConfig() { + const config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.E)(); + return (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.B)( + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.A.xyChart, + config.xyChart + ); +} +function getChartDefaultData() { + return { + yAxis: { + type: "linear", + title: "", + min: Infinity, + max: -Infinity + }, + xAxis: { + type: "band", + title: "", + categories: [] + }, + title: "", + plots: [] + }; +} +function textSanitizer(text) { + const config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.E)(); + return (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.d)(text.trim(), config); +} +function setTmpSVGG(SVGG) { + tmpSVGGroup = SVGG; +} +function setOrientation(orientation) { + if (orientation === "horizontal") { + xyChartConfig.chartOrientation = "horizontal"; + } else { + xyChartConfig.chartOrientation = "vertical"; + } +} +function setXAxisTitle(title) { + xyChartData.xAxis.title = textSanitizer(title.text); +} +function setXAxisRangeData(min, max) { + xyChartData.xAxis = { type: "linear", title: xyChartData.xAxis.title, min, max }; + hasSetXAxis = true; +} +function setXAxisBand(categories) { + xyChartData.xAxis = { + type: "band", + title: xyChartData.xAxis.title, + categories: categories.map((c) => textSanitizer(c.text)) + }; + hasSetXAxis = true; +} +function setYAxisTitle(title) { + xyChartData.yAxis.title = textSanitizer(title.text); +} +function setYAxisRangeData(min, max) { + xyChartData.yAxis = { type: "linear", title: xyChartData.yAxis.title, min, max }; + hasSetYAxis = true; +} +function setYAxisRangeFromPlotData(data) { + const minValue = Math.min(...data); + const maxValue = Math.max(...data); + const prevMinValue = isLinearAxisData(xyChartData.yAxis) ? xyChartData.yAxis.min : Infinity; + const prevMaxValue = isLinearAxisData(xyChartData.yAxis) ? xyChartData.yAxis.max : -Infinity; + xyChartData.yAxis = { + type: "linear", + title: xyChartData.yAxis.title, + min: Math.min(prevMinValue, minValue), + max: Math.max(prevMaxValue, maxValue) + }; +} +function transformDataWithoutCategory(data) { + let retData = []; + if (data.length === 0) { + return retData; + } + if (!hasSetXAxis) { + const prevMinValue = isLinearAxisData(xyChartData.xAxis) ? xyChartData.xAxis.min : Infinity; + const prevMaxValue = isLinearAxisData(xyChartData.xAxis) ? xyChartData.xAxis.max : -Infinity; + setXAxisRangeData(Math.min(prevMinValue, 1), Math.max(prevMaxValue, data.length)); + } + if (!hasSetYAxis) { + setYAxisRangeFromPlotData(data); + } + if (isBandAxisData(xyChartData.xAxis)) { + retData = xyChartData.xAxis.categories.map((c, i) => [c, data[i]]); + } + if (isLinearAxisData(xyChartData.xAxis)) { + const min = xyChartData.xAxis.min; + const max = xyChartData.xAxis.max; + const step = (max - min + 1) / data.length; + const categories = []; + for (let i = min; i <= max; i += step) { + categories.push(`${i}`); + } + retData = categories.map((c, i) => [c, data[i]]); + } + return retData; +} +function getPlotColorFromPalette(plotIndex2) { + return plotColorPalette[plotIndex2 === 0 ? 0 : plotIndex2 % plotColorPalette.length]; +} +function setLineData(title, data) { + const plotData = transformDataWithoutCategory(data); + xyChartData.plots.push({ + type: "line", + strokeFill: getPlotColorFromPalette(plotIndex), + strokeWidth: 2, + data: plotData + }); + plotIndex++; +} +function setBarData(title, data) { + const plotData = transformDataWithoutCategory(data); + xyChartData.plots.push({ + type: "bar", + fill: getPlotColorFromPalette(plotIndex), + data: plotData + }); + plotIndex++; +} +function getDrawableElem() { + if (xyChartData.plots.length === 0) { + throw Error("No Plot to render, please provide a plot with some data"); + } + xyChartData.title = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.r)(); + return XYChartBuilder.build(xyChartConfig, xyChartData, xyChartThemeConfig, tmpSVGGroup); +} +function getChartThemeConfig() { + return xyChartThemeConfig; +} +function getChartConfig() { + return xyChartConfig; +} +const clear = function() { + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.t)(); + plotIndex = 0; + xyChartConfig = getChartDefaultConfig(); + xyChartData = getChartDefaultData(); + xyChartThemeConfig = getChartDefaultThemeConfig(); + plotColorPalette = xyChartThemeConfig.plotColorPalette.split(",").map((color) => color.trim()); + hasSetXAxis = false; + hasSetYAxis = false; +}; +const db = { + getDrawableElem, + clear, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.g, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.r, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.b, + setOrientation, + setXAxisTitle, + setXAxisRangeData, + setXAxisBand, + setYAxisTitle, + setYAxisRangeData, + setLineData, + setBarData, + setTmpSVGG, + getChartThemeConfig, + getChartConfig +}; +const draw = (txt, id, _version, diagObj) => { + const db2 = diagObj.db; + const themeConfig = db2.getChartThemeConfig(); + const chartConfig = db2.getChartConfig(); + function getDominantBaseLine(horizontalPos) { + return horizontalPos === "top" ? "text-before-edge" : "middle"; + } + function getTextAnchor(verticalPos) { + return verticalPos === "left" ? "start" : verticalPos === "right" ? "end" : "middle"; + } + function getTextTransformation(data) { + return `translate(${data.x}, ${data.y}) rotate(${data.rotation || 0})`; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.debug("Rendering xychart chart\n" + txt); + const svg = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.z)(id); + const group = svg.append("g").attr("class", "main"); + const background = group.append("rect").attr("width", chartConfig.width).attr("height", chartConfig.height).attr("class", "background"); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.i)(svg, chartConfig.height, chartConfig.width, true); + svg.attr("viewBox", `0 0 ${chartConfig.width} ${chartConfig.height}`); + background.attr("fill", themeConfig.backgroundColor); + db2.setTmpSVGG(svg.append("g").attr("class", "mermaid-tmp-group")); + const shapes = db2.getDrawableElem(); + const groups = {}; + function getGroup(gList) { + let elem = group; + let prefix = ""; + for (const [i] of gList.entries()) { + let parent = group; + if (i > 0 && groups[prefix]) { + parent = groups[prefix]; + } + prefix += gList[i]; + elem = groups[prefix]; + if (!elem) { + elem = groups[prefix] = parent.append("g").attr("class", gList[i]); + } + } + return elem; + } + for (const shape of shapes) { + if (shape.data.length === 0) { + continue; + } + const shapeGroup = getGroup(shape.groupTexts); + switch (shape.type) { + case "rect": + shapeGroup.selectAll("rect").data(shape.data).enter().append("rect").attr("x", (data) => data.x).attr("y", (data) => data.y).attr("width", (data) => data.width).attr("height", (data) => data.height).attr("fill", (data) => data.fill).attr("stroke", (data) => data.strokeFill).attr("stroke-width", (data) => data.strokeWidth); + break; + case "text": + shapeGroup.selectAll("text").data(shape.data).enter().append("text").attr("x", 0).attr("y", 0).attr("fill", (data) => data.fill).attr("font-size", (data) => data.fontSize).attr("dominant-baseline", (data) => getDominantBaseLine(data.verticalPos)).attr("text-anchor", (data) => getTextAnchor(data.horizontalPos)).attr("transform", (data) => getTextTransformation(data)).text((data) => data.text); + break; + case "path": + shapeGroup.selectAll("path").data(shape.data).enter().append("path").attr("d", (data) => data.path).attr("fill", (data) => data.fill ? data.fill : "none").attr("stroke", (data) => data.strokeFill).attr("stroke-width", (data) => data.strokeWidth); + break; + } + } +}; +const renderer = { + draw +}; +const diagram = { + parser: parser$1, + db, + renderer +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/6875c492.e43a4554.js b/assets/js/6875c492.e43a4554.js deleted file mode 100644 index c5bf6123c..000000000 --- a/assets/js/6875c492.e43a4554.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8610],{99703:(e,t,a)=>{"use strict";a.d(t,{Z:()=>l});var n=a(67294),r=a(95999),s=a(32244);function l(e){const{metadata:t}=e,{previousPage:a,nextPage:l}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,r.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(s.Z,{permalink:a,title:n.createElement(r.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),l&&n.createElement(s.Z,{permalink:l,title:n.createElement(r.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},79985:(e,t,a)=>{"use strict";a.d(t,{Z:()=>l});var n=a(67294),r=a(9460),s=a(857);function l(e){let{items:t,component:a=s.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(r.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}},41714:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>E});var n=a(67294),r=a(86010),s=a(95999),l=a(88824),i=a(10833),o=a(35281),c=a(39960),g=a(39058),u=a(99703),m=a(90197),p=a(79985);function d(e){const t=function(){const{selectMessage:e}=(0,l.c)();return t=>e(t,(0,s.I)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}();return(0,s.I)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function b(e){let{tag:t}=e;const a=d(t);return n.createElement(n.Fragment,null,n.createElement(i.d,{title:a}),n.createElement(m.Z,{tag:"blog_tags_posts"}))}function h(e){let{tag:t,items:a,sidebar:r,listMetadata:l}=e;const i=d(t);return n.createElement(g.Z,{sidebar:r},n.createElement("header",{className:"margin-bottom--xl"},n.createElement("h1",null,i),n.createElement(c.Z,{href:t.allTagsPath},n.createElement(s.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page"},"View All Tags"))),n.createElement(p.Z,{items:a}),n.createElement(u.Z,{metadata:l}))}function E(e){return n.createElement(i.FG,{className:(0,r.Z)(o.k.wrapper.blogPages,o.k.page.blogTagPostListPage)},n.createElement(b,e),n.createElement(h,e))}},857:(e,t,a)=>{"use strict";a.d(t,{Z:()=>i});var n=a(30390),r=a(67294),s=a(92949),l=a(9460);const i=function(e){const{colorMode:t}=(0,s.I)(),{isBlogPostPage:a}=(0,l.C)(),i="dark"===t?"dark":"light",o=(0,r.useRef)(null);return(0,r.useEffect)((()=>{if(!a)return;const e=o.current.querySelector("iframe.giscus-frame");e?(()=>{const t={setConfig:{theme:i}};e.contentWindow.postMessage({giscus:t},"https://giscus.app")})():(()=>{const e=document.createElement("script");e.src="https://giscus.app/client.js",e.setAttribute("data-repo","greeng00se/greeng00se.github.io"),e.setAttribute("data-repo-id","R_kgDOIRAC3w"),e.setAttribute("data-category","Announcements"),e.setAttribute("data-category-id","DIC_kwDOIRAC384CTcGg"),e.setAttribute("data-mapping","pathname"),e.setAttribute("data-strict","0"),e.setAttribute("data-reactions-enabled","1"),e.setAttribute("data-emit-metadata","0"),e.setAttribute("data-input-position","bottom"),e.setAttribute("data-theme",i),e.setAttribute("data-lang","ko"),e.crossOrigin="anonymous",e.async=!0,o.current.appendChild(e)})()}),[i]),r.createElement(r.Fragment,null,r.createElement(n.Z,e),a&&r.createElement("div",{ref:o}))}},11748:(e,t,a)=>{var n={"./locale":89234,"./locale.js":89234};function r(e){var t=s(e);return a(t)}function s(e){if(!a.o(n,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return n[e]}r.keys=function(){return Object.keys(n)},r.resolve=s,e.exports=r,r.id=11748}}]); \ No newline at end of file diff --git a/assets/js/6875c492.e8e0a40f.js b/assets/js/6875c492.e8e0a40f.js new file mode 100644 index 000000000..e56e1ca0a --- /dev/null +++ b/assets/js/6875c492.e8e0a40f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8610],{99703:(e,t,s)=>{s.d(t,{Z:()=>r});s(67294);var n=s(95999),a=s(32244),i=s(85893);function r(e){const{metadata:t}=e,{previousPage:s,nextPage:r}=t;return(0,i.jsxs)("nav",{className:"pagination-nav","aria-label":(0,n.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[s&&(0,i.jsx)(a.Z,{permalink:s,title:(0,i.jsx)(n.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer Entries"})}),r&&(0,i.jsx)(a.Z,{permalink:r,title:(0,i.jsx)(n.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older Entries"}),isNext:!0})]})}},79985:(e,t,s)=>{s.d(t,{Z:()=>r});s(67294);var n=s(9460),a=s(857),i=s(85893);function r(e){let{items:t,component:s=a.Z}=e;return(0,i.jsx)(i.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,i.jsx)(n.n,{content:t,children:(0,i.jsx)(s,{children:(0,i.jsx)(t,{})})},t.metadata.permalink)}))})}},41714:(e,t,s)=>{s.r(t),s.d(t,{default:()=>f});s(67294);var n=s(86010),a=s(95999),i=s(88824),r=s(10833),o=s(35281),l=s(39960),c=s(61460),d=s(99703),g=s(90197),u=s(79985),p=s(22212),h=s(92503),m=s(85893);function b(e){const t=function(){const{selectMessage:e}=(0,i.c)();return t=>e(t,(0,a.I)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}();return(0,a.I)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function x(e){let{tag:t}=e;const s=b(t);return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(r.d,{title:s}),(0,m.jsx)(g.Z,{tag:"blog_tags_posts"})]})}function j(e){let{tag:t,items:s,sidebar:n,listMetadata:i}=e;const r=b(t);return(0,m.jsxs)(c.Z,{sidebar:n,children:[t.unlisted&&(0,m.jsx)(p.Z,{}),(0,m.jsxs)("header",{className:"margin-bottom--xl",children:[(0,m.jsx)(h.Z,{as:"h1",children:r}),(0,m.jsx)(l.Z,{href:t.allTagsPath,children:(0,m.jsx)(a.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,m.jsx)(u.Z,{items:s}),(0,m.jsx)(d.Z,{metadata:i})]})}function f(e){return(0,m.jsxs)(r.FG,{className:(0,n.Z)(o.k.wrapper.blogPages,o.k.page.blogTagPostListPage),children:[(0,m.jsx)(x,{...e}),(0,m.jsx)(j,{...e})]})}},22212:(e,t,s)=>{s.d(t,{Z:()=>p});s(67294);var n=s(86010),a=s(95999),i=s(35742),r=s(85893);function o(){return(0,r.jsx)(a.Z,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,r.jsx)(a.Z,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,r.jsx)(i.Z,{children:(0,r.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=s(35281),g=s(59047);function u(e){let{className:t}=e;return(0,r.jsx)(g.Z,{type:"caution",title:(0,r.jsx)(o,{}),className:(0,n.Z)(t,d.k.common.unlistedBanner),children:(0,r.jsx)(l,{})})}function p(e){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(c,{}),(0,r.jsx)(u,{...e})]})}},857:(e,t,s)=>{s.d(t,{Z:()=>l});var n=s(30390),a=s(67294),i=s(92949),r=s(9460),o=s(85893);const l=function(e){const{colorMode:t}=(0,i.I)(),{isBlogPostPage:s}=(0,r.C)(),l="dark"===t?"dark":"light",c=(0,a.useRef)(null);return(0,a.useEffect)((()=>{if(!s)return;const e=c.current.querySelector("iframe.giscus-frame");e?(()=>{const t={setConfig:{theme:l}};e.contentWindow.postMessage({giscus:t},"https://giscus.app")})():(()=>{const e=document.createElement("script");e.src="https://giscus.app/client.js",e.setAttribute("data-repo","greeng00se/greeng00se.github.io"),e.setAttribute("data-repo-id","R_kgDOIRAC3w"),e.setAttribute("data-category","Announcements"),e.setAttribute("data-category-id","DIC_kwDOIRAC384CTcGg"),e.setAttribute("data-mapping","pathname"),e.setAttribute("data-strict","0"),e.setAttribute("data-reactions-enabled","1"),e.setAttribute("data-emit-metadata","0"),e.setAttribute("data-input-position","bottom"),e.setAttribute("data-theme",l),e.setAttribute("data-lang","ko"),e.crossOrigin="anonymous",e.async=!0,c.current.appendChild(e)})()}),[l]),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.Z,{...e}),s&&(0,o.jsx)("div",{ref:c})]})}}}]); \ No newline at end of file diff --git a/assets/js/688.7a460c34.js b/assets/js/688.7a460c34.js new file mode 100644 index 000000000..1f0ce109a --- /dev/null +++ b/assets/js/688.7a460c34.js @@ -0,0 +1,26002 @@ +"use strict"; +exports.id = 688; +exports.ids = [688]; +exports.modules = { + +/***/ 41644: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + bK: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.Z(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.Z( + map/* default */.Z(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.Z(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.Z(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.k(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.Z(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.Z(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.Z(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.Z(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.Z(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.Z('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.Z(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.Z(g.outEdges(v), function (e) { + if (has/* default */.Z(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.Z(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.Z(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(59236); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.Z)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(74752); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.Z)(iteratee, 3); + + (0,_baseForOwn/* default */.Z)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.Z)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(66092); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.Z.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.Z(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.k().setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.k({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.Z(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.Z(range/* default */.Z(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.Z(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.Z(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.Z(layers, function (vs, i) { + if (isUndefined/* default */.Z(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.Z(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.Z(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.Z(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.Z(children, dfs); + } + + if (has/* default */.Z(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.Z(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, reverseYOne); + if (has/* default */.Z(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, swapXYOne); + if (has/* default */.Z(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.Z(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.Z)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.Z(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.Z(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.Z(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.k({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.Z(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.Z(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.Z(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.Z)(collection)) { + var iteratee = (0,_baseIteratee/* default */.Z)(predicate, 3); + collection = (0,keys/* default */.Z)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.Z)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.Z)(array, (0,_baseIteratee/* default */.Z)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(39473); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(93589); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.Z)(value) && (0,isObjectLike/* default */.Z)(value) && (0,_baseGetTag/* default */.Z)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.Z)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.Z)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.Z)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.Z)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.Z(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.Z(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.Z(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.Z(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.Z(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.Z(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.Z(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.Z(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.Z(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.Z(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.Z(tree.neighbors(v), function (w) { + if (!has/* default */.Z(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.Z(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.Z(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.Z(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.Z(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.Z(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.Z(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.Z(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.Z(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.Z( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.Z(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.k({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.Z(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.Z(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.Z(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.Z('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.Z); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(21018); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.Z)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.Z)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + if ((0,isArray/* default */.Z)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.Z)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.Z]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.Z)(iteratees, (0,_baseUnary/* default */.Z)(_baseIteratee/* default */.Z)); + + var result = (0,_baseMap/* default */.Z)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.Z)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.Z)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.Z)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.Z)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.Z(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.Z( + map/* default */.Z(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.Z(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.Z(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.Z( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.Z(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.Z(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.Z(range/* default */.Z(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.Z(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.Z(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.Z(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.Z(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.Z( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.Z(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.Z(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.Z(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.Z(entryV) && !isUndefined/* default */.Z(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.Z(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.Z(uEntry.barycenter) || + isUndefined/* default */.Z(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.Z(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.Z(entry.out, handleOut(entry)); + } + + return map/* default */.Z( + filter/* default */.Z(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.Z(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.Z(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.Z(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.Z(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.Z(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.Z(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.Z(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.Z([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.Z(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.Z(entries, function (entry) { + entry.vs = flatten/* default */.Z( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.Z(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.Z(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.Z(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.Z(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.k(); + forEach/* default */.Z(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.Z(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.Z(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.Z(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(68882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(61395); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee), keysIn/* default */.Z); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.Z(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.Z(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.Z(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.Z(range/* default */.Z(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.Z(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.Z(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.Z(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.Z(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.Z(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.Z(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.k(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.Z(layering, function (layer) { + var u; + forEach/* default */.Z(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.Z(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.Z(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.Z(['u', 'd'], function (vert) { + forEach/* default */.Z(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.Z(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.Z(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.Z(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.Z(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.Z(layering).reverse(); + forEach/* default */.Z(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.Z(adjustedLayering, function (inner) { + return values/* default */.Z(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.Z(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.Z(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.Z(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.Z(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.Z(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.Z(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.k({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.Z({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.Z(graph, graphAttrs)) + ); + + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.Z(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.Z({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.Z(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.Z(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.Z(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.Z(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.Z(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.Z(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.Z(layers, function (layer) { + var orderShift = 0; + forEach/* default */.Z(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.Z(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.Z(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.Z(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 52544: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + k: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(73234); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(79697); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.Z)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(93203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.Z && (1 / (0,_setToArray/* default */.Z)(new _Set/* default */.Z([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.Z(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.Z)(set); + } + isCommon = false; + includes = _cacheHas/* default */.Z; + seen = new _SetCache/* default */.Z; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(836); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.Z)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.Z)(arrays, 1, isArrayLikeObject/* default */.Z, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.Z(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.Z(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.Z(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.Z(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.Z(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.Z(this._nodes); + } + sources() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.Z(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.Z(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.Z(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.Z(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.Z(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.Z(keys/* default */.Z(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.Z(keys/* default */.Z(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.Z(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.Z(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.Z(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.Z(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.Z(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.Z(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.Z(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.Z(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.Z(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.Z(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.Z(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.Z(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.Z(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.Z(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.Z(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.Z(inV); + if (!u) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.Z(outV); + if (!w) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.Z(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 45625: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ k: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.k) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52544); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 39354: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + c: () => (/* binding */ write) +}); + +// UNUSED EXPORTS: read + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/clone.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_SYMBOLS_FLAG = 4; + +/** + * Creates a shallow clone of `value`. + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) + * and supports cloning arrays, array buffers, booleans, date objects, maps, + * numbers, `Object` objects, regexes, sets, strings, symbols, and typed + * arrays. The own enumerable properties of `arguments` objects are cloned + * as plain objects. An empty object is returned for uncloneable values such + * as error objects, functions, DOM nodes, and WeakMaps. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to clone. + * @returns {*} Returns the cloned value. + * @see _.cloneDeep + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var shallow = _.clone(objects); + * console.log(shallow[0] === objects[0]); + * // => true + */ +function clone(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_clone = (clone); + +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/json.js + + + + + +function write(g) { + var json = { + options: { + directed: g.isDirected(), + multigraph: g.isMultigraph(), + compound: g.isCompound(), + }, + nodes: writeNodes(g), + edges: writeEdges(g), + }; + if (!isUndefined/* default */.Z(g.graph())) { + json.value = lodash_es_clone(g.graph()); + } + return json; +} + +function writeNodes(g) { + return map/* default */.Z(g.nodes(), function (v) { + var nodeValue = g.node(v); + var parent = g.parent(v); + var node = { v: v }; + if (!isUndefined/* default */.Z(nodeValue)) { + node.value = nodeValue; + } + if (!isUndefined/* default */.Z(parent)) { + node.parent = parent; + } + return node; + }); +} + +function writeEdges(g) { + return map/* default */.Z(g.edges(), function (e) { + var edgeValue = g.edge(e); + var edge = { v: e.v, w: e.w }; + if (!isUndefined/* default */.Z(e.name)) { + edge.name = e.name; + } + if (!isUndefined/* default */.Z(edgeValue)) { + edge.value = edgeValue; + } + return edge; + }); +} + +function read(json) { + var g = new Graph(json.options).setGraph(json.value); + _.each(json.nodes, function (entry) { + g.setNode(entry.v, entry.value); + if (entry.parent) { + g.setParent(entry.v, entry.parent); + } + }); + _.each(json.edges, function (entry) { + g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); + }); + return g; +} + + +/***/ }), + +/***/ 63001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(37834); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.Z; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 76579: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 68774: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 74073: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 58694: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 48451: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(76579); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(31899); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keys/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keysIn/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(91050); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(87215); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(95695); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.Z)(source, (0,_getSymbols/* default */.Z)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(12513); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(60532); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.Z : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.Z)(result, (0,_getSymbols/* default */.Z)(object)); + object = (0,_getPrototype/* default */.Z)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.Z)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(63327); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.Z)(object, keysIn/* default */.Z, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(41884); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.Z)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(12701); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.Z)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.Z)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(73658); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(98351); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.Z)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.Z)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.Z)(value)) { + return value; + } + var isArr = (0,isArray/* default */.Z)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.Z)(value, result); + } + } else { + var tag = (0,_getTag/* default */.Z)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.Z)(value)) { + return (0,_cloneBuffer/* default */.Z)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.Z)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.Z); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.Z) + : (isFlat ? keysIn/* default */.Z : keys/* default */.Z); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.Z)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.Z)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 49811: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.Z)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.Z); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 21692: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 10626: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(29169); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.Z ? _Symbol/* default */.Z.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.Z)(value) || (0,isArguments/* default */.Z)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.Z)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 2693: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61395); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 13317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 63327: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58694); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 74765: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.Z : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.Z)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(84073); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(79651); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.Z(object), new _Uint8Array/* default */.Z(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.Z)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.Z); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.Z)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.Z)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(18843); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.Z)(object), + othIsArr = (0,isArray/* default */.Z)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.Z)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.Z)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.Z)(object)) { + if (!(0,isBuffer/* default */.Z)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.Z); + return (objIsArr || (0,isTypedArray/* default */.Z)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.Z); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.Z); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.Z)(value) && !(0,isObjectLike/* default */.Z)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.Z; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.Z)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.Z)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.Z)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.Z)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.Z)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.Z)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.Z)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.Z)(path) ? (0,_baseProperty/* default */.Z)((0,_toKey/* default */.Z)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.Z; + } + if (typeof value == 'object') { + return (0,isArray/* default */.Z)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 21018: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49811); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 54193: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 59548: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 68882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69203); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 22823: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(42454); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.Z)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(50751); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.Z)(value)) { + return value; + } + return (0,_isKey/* default */.Z)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.Z)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 1808: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63327); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(95695); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 95695: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68774); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(60532); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 16174: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29169); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27771); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(56009); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1656); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 99365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72714); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 6545: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 62281: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72714); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 3688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69581); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(79651); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50439); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32957); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 13445: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(68774); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.Z)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayFilter/* default */.Z : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.Z)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 27961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10626); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 70870: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76579); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49811); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(68882); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 17452: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 75487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 72714: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93589); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18533); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 49360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 17179: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87668); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39473); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 43836: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74073); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74765); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21018); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 61666: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(22823); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(56009); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.Z)(object)) { + return object; + } + path = (0,_castPath/* default */.Z)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.Z)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.Z)(objValue) + ? objValue + : ((0,_isIndex/* default */.Z)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.Z)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.Z)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.Z)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.Z)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(81211); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(27227); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.Z)((0,_overRest/* default */.Z)(func, undefined, flatten/* default */.Z), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 74379: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.Z)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.Z)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.Z)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.Z)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 92344: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.Z)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.Z); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 60532: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 94099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.Z)(value)) { + return NAN; + } + if ((0,isObject/* default */.Z)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.Z)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 50751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.Z)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.Z)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.Z)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 66749: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50751); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 34148: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.Z)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.Z)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 11688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(82127); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(45625); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(56363); +/* harmony import */ var _index_2c4b9a3b_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(90360); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20683); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(39354); + + + + + + + + + + + + + + + + + + + +const sanitizeText = (txt) => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.e.sanitizeText(txt, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)()); +let conf = { + dividerMargin: 10, + padding: 5, + textHeight: 10, + curve: void 0 +}; +const addNamespaces = function(namespaces, g, _id, diagObj) { + const keys = Object.keys(namespaces); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info("keys:", keys); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info(namespaces); + keys.forEach(function(id) { + var _a, _b; + const vertex = namespaces[id]; + const shape = "rect"; + const node = { + shape, + id: vertex.id, + domId: vertex.domId, + labelText: sanitizeText(vertex.id), + labelStyle: "", + style: "fill: none; stroke: black", + // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release + padding: ((_a = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart) == null ? void 0 : _a.padding) ?? ((_b = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().class) == null ? void 0 : _b.padding) + }; + g.setNode(vertex.id, node); + addClasses(vertex.classes, g, _id, diagObj, vertex.id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info("setNode", node); + }); +}; +const addClasses = function(classes, g, _id, diagObj, parent) { + const keys = Object.keys(classes); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info("keys:", keys); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info(classes); + keys.filter((id) => classes[id].parent == parent).forEach(function(id) { + var _a, _b; + const vertex = classes[id]; + const cssClassStr = vertex.cssClasses.join(" "); + const styles2 = { labelStyle: "", style: "" }; + const vertexText = vertex.label ?? vertex.id; + const radius = 0; + const shape = "class_box"; + const node = { + labelStyle: styles2.labelStyle, + shape, + labelText: sanitizeText(vertexText), + classData: vertex, + rx: radius, + ry: radius, + class: cssClassStr, + style: styles2.style, + id: vertex.id, + domId: vertex.domId, + tooltip: diagObj.db.getTooltip(vertex.id, parent) || "", + haveCallback: vertex.haveCallback, + link: vertex.link, + width: vertex.type === "group" ? 500 : void 0, + type: vertex.type, + // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release + padding: ((_a = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart) == null ? void 0 : _a.padding) ?? ((_b = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().class) == null ? void 0 : _b.padding) + }; + g.setNode(vertex.id, node); + if (parent) { + g.setParent(vertex.id, parent); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info("setNode", node); + }); +}; +const addNotes = function(notes, g, startEdgeId, classes) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info(notes); + notes.forEach(function(note, i) { + var _a, _b; + const vertex = note; + const cssNoteStr = ""; + const styles2 = { labelStyle: "", style: "" }; + const vertexText = vertex.text; + const radius = 0; + const shape = "note"; + const node = { + labelStyle: styles2.labelStyle, + shape, + labelText: sanitizeText(vertexText), + noteData: vertex, + rx: radius, + ry: radius, + class: cssNoteStr, + style: styles2.style, + id: vertex.id, + domId: vertex.id, + tooltip: "", + type: "note", + // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release + padding: ((_a = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart) == null ? void 0 : _a.padding) ?? ((_b = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().class) == null ? void 0 : _b.padding) + }; + g.setNode(vertex.id, node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info("setNode", node); + if (!vertex.class || !(vertex.class in classes)) { + return; + } + const edgeId = startEdgeId + i; + const edgeData = { + id: `edgeNote${edgeId}`, + //Set relationship style and line type + classes: "relation", + pattern: "dotted", + // Set link type for rendering + arrowhead: "none", + //Set edge extra labels + startLabelRight: "", + endLabelLeft: "", + //Set relation arrow types + arrowTypeStart: "none", + arrowTypeEnd: "none", + style: "fill:none", + labelStyle: "", + curve: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.n)(conf.curve, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .c_6) + }; + g.setEdge(vertex.id, vertex.class, edgeData, edgeId); + }); +}; +const addRelations = function(relations, g) { + const conf2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart; + let cnt = 0; + relations.forEach(function(edge) { + var _a; + cnt++; + const edgeData = { + //Set relationship style and line type + classes: "relation", + pattern: edge.relation.lineType == 1 ? "dashed" : "solid", + id: "id" + cnt, + // Set link type for rendering + arrowhead: edge.type === "arrow_open" ? "none" : "normal", + //Set edge extra labels + startLabelRight: edge.relationTitle1 === "none" ? "" : edge.relationTitle1, + endLabelLeft: edge.relationTitle2 === "none" ? "" : edge.relationTitle2, + //Set relation arrow types + arrowTypeStart: getArrowMarker(edge.relation.type1), + arrowTypeEnd: getArrowMarker(edge.relation.type2), + style: "fill:none", + labelStyle: "", + curve: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.n)(conf2 == null ? void 0 : conf2.curve, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .c_6) + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info(edgeData, edge); + if (edge.style !== void 0) { + const styles2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.k)(edge.style); + edgeData.style = styles2.style; + edgeData.labelStyle = styles2.labelStyle; + } + edge.text = edge.title; + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + if (((_a = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart) == null ? void 0 : _a.htmlLabels) ?? (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().htmlLabels) { + edgeData.labelType = "html"; + edgeData.label = '<span class="edgeLabel">' + edge.text + "</span>"; + } else { + edgeData.labelType = "text"; + edgeData.label = edge.text.replace(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.e.lineBreakRegex, "\n"); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + } + } + g.setEdge(edge.id1, edge.id2, edgeData, cnt); + }); +}; +const setConf = function(cnf) { + conf = { + ...conf, + ...cnf + }; +}; +const draw = async function(text, id, _version, diagObj) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info("Drawing class - ", id); + const conf2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().flowchart ?? (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().class; + const securityLevel = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info("config:", conf2); + const nodeSpacing = (conf2 == null ? void 0 : conf2.nodeSpacing) ?? 50; + const rankSpacing = (conf2 == null ? void 0 : conf2.rankSpacing) ?? 50; + const g = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_1__/* .Graph */ .k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: diagObj.db.getDirection(), + nodesep: nodeSpacing, + ranksep: rankSpacing, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + const namespaces = diagObj.db.getNamespaces(); + const classes = diagObj.db.getClasses(); + const relations = diagObj.db.getRelations(); + const notes = diagObj.db.getNotes(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.info(relations); + addNamespaces(namespaces, g, id, diagObj); + addClasses(classes, g, id, diagObj); + addRelations(relations, g); + addNotes(notes, g, relations.length + 1, classes); + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const svg = root.select(`[id="${id}"]`); + const element = root.select("#" + id + " g"); + await (0,_index_2c4b9a3b_js__WEBPACK_IMPORTED_MODULE_8__.r)( + element, + g, + ["aggregation", "extension", "composition", "dependency", "lollipop"], + "classDiagram", + id + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.u.insertTitle(svg, "classTitleText", (conf2 == null ? void 0 : conf2.titleTopMargin) ?? 5, diagObj.db.getDiagramTitle()); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.o)(g, svg, conf2 == null ? void 0 : conf2.diagramPadding, conf2 == null ? void 0 : conf2.useMaxWidth); + if (!(conf2 == null ? void 0 : conf2.htmlLabels)) { + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const labels = doc.querySelectorAll('[id="' + id + '"] .edgeLabel .label'); + for (const label of labels) { + const dim = label.getBBox(); + const rect = doc.createElementNS("http://www.w3.org/2000/svg", "rect"); + rect.setAttribute("rx", 0); + rect.setAttribute("ry", 0); + rect.setAttribute("width", dim.width); + rect.setAttribute("height", dim.height); + label.insertBefore(rect, label.firstChild); + } + } +}; +function getArrowMarker(type) { + let marker; + switch (type) { + case 0: + marker = "aggregation"; + break; + case 1: + marker = "extension"; + break; + case 2: + marker = "composition"; + break; + case 3: + marker = "dependency"; + break; + case 4: + marker = "lollipop"; + break; + default: + marker = "none"; + } + return marker; +} +const renderer = { + setConf, + draw +}; +const diagram = { + parser: _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_9__.p, + db: _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_9__.d, + renderer, + styles: _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_9__.s, + init: (cnf) => { + if (!cnf.class) { + cnf.class = {}; + } + cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + _styles_3dcbcfbf_js__WEBPACK_IMPORTED_MODULE_9__.d.clear(); + } +}; + + + +/***/ }), + +/***/ 64589: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array<unknown>} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array<string>} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array<Extension>} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record<string, unknown>} */ + const left = maybe || (all[hook] = {}) + /** @type {Record<string, unknown> | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array<unknown>} existing + * @param {Array<unknown>} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array<unknown>} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array<HtmlExtension>} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array<StackItem>} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function micromark_util_chunked_splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function micromark_util_chunked_push(list, items) { + if (list.length > 0) { + micromark_util_chunked_splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array<Event>} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record<string, number>} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array<Event>} */ + let parameters + /** @type {Array<Event>} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + micromark_util_chunked_splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array<Event>} events + * @param {number} eventIndex + * @returns {Record<string, number>} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array<number>} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record<string, number>} */ + const gaps = {} + /** @type {Array<Chunk>} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + micromark_util_chunked_splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array<Event>} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array<Event>} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array<Resolver>} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit<Point, '_bufferIndex' | '_index'> | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record<string, number>} */ + const columnStart = {} + /** @type {Array<Construct>} */ + const resolveAllConstructs = [] + /** @type {Array<Chunk>} */ + let chunks = [] + /** @type {Array<Token>} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array<Construct> | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array<Construct>} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array<Construct>} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array<Chunk>} chunks + * @param {Pick<Token, 'end' | 'start'>} token + * @returns {Array<Chunk>} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array<Chunk>} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array<Chunk>} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array<string>} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * <a> + * <a\>b> + * <a b> + * <a)> + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`<a>` or `b`). + * @param {TokenType} literalType + * Type when enclosed (`<a>`). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | <aa> + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | <a\*a> + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | <x /> + * ^ + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<!-`, inside a comment, at another `-`. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<![`, inside CDATA, expecting `CDATA[`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | </x> + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | <ab> + * ^^ + * > | </ab> + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > | <div/> + * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | <x/> + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | <a /> + * ^ + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * > | <a > + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | <a b> + * ^ + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | <a b=c> + * ^ + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | <a b="c"> + * ^ + * > | <a b='c'> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | <x> + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | <x> + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after `</`, in a raw tag name. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | <!--> + * ^ + * > | <?> + * ^ + * > | <!q> + * ^ + * > | <!--ab--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > | <div> + * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record<string, string>} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array<Event>} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + * <p>!<a href=\"b\">^a</a></p> + * <p>!<a href=\"c\">^a</a></p> + * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array<Event>} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | a<user.name@ex-ample.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code> | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a <b> c + * ^ + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * > | a <![CDATA[>&<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after `<!-`, at another `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After `<![`, in CDATA, expecting `CDATA[`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a <!b> c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After `</x`, in a tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After `<x`, in opening tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a <!--a + * ^ + * | b--> + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array<Chunk>} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array<Chunk>} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array<Event>} events + * @returns {Array<Event>} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract<Node, UnistParent>} Parent + * + * @typedef {Omit<UnistParent, 'type' | 'children'> & {type: 'fragment', children: Array<PhrasingContent>}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record<string, Handle>} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array<string>} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array<Transform>} transforms + * Tree transforms. + * + * @typedef {Partial<Config>} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array<Node | Fragment>} stack + * Stack of nodes. + * @property {Array<TokenTuple>} tokenStack + * Stack of tokens. + * @property {<Key extends keyof CompileData>(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {<Key extends keyof CompileData>(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {<Kind extends Node>(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array<Extension | Array<Extension>> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array<Event>} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit<CompileContext, 'sliceSerialize'>} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array<number>} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array<Event>} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array<StaticPhrasingContent>} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array<Extension | Array<Extension>>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(18464); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-62fc7601.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.Z)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "<br/>"); + } else if (node.type === "strong") { + return `<strong>${node.children.map(output).join("")}</strong>`; + } else if (node.type === "emphasis") { + return `<em>${node.children.map(output).join("")}</em>`; + } else if (node.type === "paragraph") { + return `<p>${node.children.map(output).join("")}</p>`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + <span class="${labelClass} ${classes}" ` + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_8af3addd.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_8af3addd.J)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 27707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ insertEdge), +/* harmony export */ h: () => (/* binding */ positionEdgeLabel), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(64589); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '<span class="' + labelClass + '" ' + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "<br />"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|<br\s*\/?>/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/<img[^>]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + img.style.width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = bbox.width + node.padding; + const totalHeight = bbox.height + node.padding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("<br/>") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(/</g, "<").replace(/>/g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(/</g, "<").replace(/>/g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc82", edge, edge.labelType); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Moving label abc78 ", edge.id, edge.label, edgeLabels[edge.id]); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc78" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundryNode) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 cutPathAtIntersect", _points, boundryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 checking point", point2, boundryNode); + if (!outsideNode(boundryNode, point2) && !isInside) { + const inter = intersection(boundryNode, lastPointOutside, point2); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 inside", point2, lastPointOutside, inter); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 intersection", inter); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 no intersect", inter, points); + } + isInside = true; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 outside", point2, lastPointOutside); + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 returning points", points); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 InsertEdge: ", edge); + if (head.intersect && tail.intersect) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Last point", + points[points.length - 1], + head, + head.intersect(points[points.length - 1]) + ); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .$0Z; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeStart", edge.arrowTypeStart); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeEnd", edge.arrowTypeEnd); + switch (edge.arrowTypeStart) { + case "arrow_cross": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-crossStart)" + ); + break; + case "arrow_point": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-pointStart)" + ); + break; + case "arrow_barb": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-barbStart)" + ); + break; + case "arrow_circle": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-circleStart)" + ); + break; + case "aggregation": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationStart)" + ); + break; + case "extension": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-extensionStart)" + ); + break; + case "composition": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-compositionStart)" + ); + break; + case "dependency": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyStart)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopStart)" + ); + break; + } + switch (edge.arrowTypeEnd) { + case "arrow_cross": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-crossEnd)"); + break; + case "arrow_point": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-pointEnd)"); + break; + case "arrow_barb": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-barbEnd)"); + break; + case "arrow_circle": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-circleEnd)"); + break; + case "aggregation": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationEnd)" + ); + break; + case "extension": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-extensionEnd)" + ); + break; + case "composition": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-compositionEnd)" + ); + break; + case "dependency": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyEnd)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopEnd)" + ); + break; + } + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 90360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ r: () => (/* binding */ render) +/* harmony export */ }); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39354); +/* harmony import */ var _edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(27707); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(45625); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(64589); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(64218); + + + + + + + +let clusterDb = {}; +let descendants = {}; +let parents = {}; +const clear$1 = () => { + descendants = {}; + parents = {}; + clusterDb = {}; +}; +const isDescendant = (id, ancenstorId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("In isDecendant", ancenstorId, " ", id, " = ", descendants[ancenstorId].includes(id)); + if (descendants[ancenstorId].includes(id)) { + return true; + } + return false; +}; +const edgeInCluster = (edge, clusterId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Decendants of ", clusterId, " is ", descendants[clusterId]); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge is ", edge); + if (edge.v === clusterId) { + return false; + } + if (edge.w === clusterId) { + return false; + } + if (!descendants[clusterId]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Tilt, ", clusterId, ",not in decendants"); + return false; + } + return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w); +}; +const copy = (clusterId, graph, newGraph, rootId) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Copying children of ", + clusterId, + "root", + rootId, + "data", + graph.node(clusterId), + rootId + ); + const nodes = graph.children(clusterId) || []; + if (clusterId !== rootId) { + nodes.push(clusterId); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Copying (nodes) clusterId", clusterId, "nodes", nodes); + nodes.forEach((node) => { + if (graph.children(node).length > 0) { + copy(node, graph, newGraph, rootId); + } else { + const data = graph.node(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("cp ", node, " to ", rootId, " with parent ", clusterId); + newGraph.setNode(node, data); + if (rootId !== graph.parent(node)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Setting parent", node, graph.parent(node)); + newGraph.setParent(node, graph.parent(node)); + } + if (clusterId !== rootId && node !== clusterId) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Setting parent", node, clusterId); + newGraph.setParent(node, clusterId); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("In copy ", clusterId, "root", rootId, "data", graph.node(clusterId), rootId); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Not Setting parent for node=", + node, + "cluster!==rootId", + clusterId !== rootId, + "node!==clusterId", + node !== clusterId + ); + } + const edges = graph.edges(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Copying Edges", edges); + edges.forEach((edge) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge", edge); + const data2 = graph.edge(edge.v, edge.w, edge.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge data", data2, rootId); + try { + if (edgeInCluster(edge, rootId)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Copying as ", edge.v, edge.w, data2, edge.name); + newGraph.setEdge(edge.v, edge.w, data2, edge.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("newGraph edges ", newGraph.edges(), newGraph.edge(newGraph.edges()[0])); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Skipping copy of edge ", + edge.v, + "-->", + edge.w, + " rootId: ", + rootId, + " clusterId:", + clusterId + ); + } + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error(e); + } + }); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Removing node", node); + graph.removeNode(node); + }); +}; +const extractDescendants = (id, graph) => { + const children = graph.children(id); + let res = [...children]; + for (const child of children) { + parents[child] = id; + res = [...res, ...extractDescendants(child, graph)]; + } + return res; +}; +const findNonClusterChild = (id, graph) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching", id); + const children = graph.children(id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Searching children of id ", id, children); + if (children.length < 1) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("This is a valid node", id); + return id; + } + for (const child of children) { + const _id = findNonClusterChild(child, graph); + if (_id) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Found replacement for", id, " => ", _id); + return _id; + } + } +}; +const getAnchorId = (id) => { + if (!clusterDb[id]) { + return id; + } + if (!clusterDb[id].externalConnections) { + return id; + } + if (clusterDb[id]) { + return clusterDb[id].id; + } + return id; +}; +const adjustClustersAndEdges = (graph, depth) => { + if (!graph || depth > 10) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting out, no graph "); + return; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Opting in, graph "); + } + graph.nodes().forEach(function(id) { + const children = graph.children(id); + if (children.length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster identified", + id, + " Replacement id in edges: ", + findNonClusterChild(id, graph) + ); + descendants[id] = extractDescendants(id, graph); + clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) }; + } + }); + graph.nodes().forEach(function(id) { + const children = graph.children(id); + const edges = graph.edges(); + if (children.length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Cluster identified", id, descendants); + edges.forEach((edge) => { + if (edge.v !== id && edge.w !== id) { + const d1 = isDescendant(edge.v, id); + const d2 = isDescendant(edge.w, id); + if (d1 ^ d2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge: ", edge, " leaves cluster ", id); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Decendants of XXX ", id, ": ", descendants[id]); + clusterDb[id].externalConnections = true; + } + } + }); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster ", id, descendants); + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + let v = e.v; + let w = e.w; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Fix XXX", + clusterDb, + "ids:", + e.v, + e.w, + "Translating: ", + clusterDb[e.v], + " --- ", + clusterDb[e.w] + ); + if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing link to self - removing XXX", e.v, e.w, e.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + const specialId = e.w + "---" + e.v; + graph.setNode(specialId, { + domId: specialId, + id: specialId, + labelStyle: "", + labelText: edge.label, + padding: 0, + shape: "labelRect", + style: "" + }); + const edge1 = structuredClone(edge); + const edge2 = structuredClone(edge); + edge1.label = ""; + edge1.arrowTypeEnd = "none"; + edge2.label = ""; + edge1.fromCluster = e.v; + edge2.toCluster = e.v; + graph.setEdge(v, specialId, edge1, e.name + "-cyclic-special"); + graph.setEdge(specialId, w, edge2, e.name + "-cyclic-special"); + } else if (clusterDb[e.v] || clusterDb[e.w]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing and trixing - removing XXX", e.v, e.w, e.name); + v = getAnchorId(e.v); + w = getAnchorId(e.w); + graph.removeEdge(e.v, e.w, e.name); + if (v !== e.v) { + edge.fromCluster = e.v; + } + if (w !== e.w) { + edge.toCluster = e.w; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fix Replacing with XXX", v, w, e.name); + graph.setEdge(v, w, edge, e.name); + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Adjusted Graph", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + extractor(graph, 0); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace(clusterDb); +}; +const extractor = (graph, depth) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("extractor - ", depth, dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph), graph.children("D")); + if (depth > 10) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("Bailing out"); + return; + } + let nodes = graph.nodes(); + let hasChildren = false; + for (const node of nodes) { + const children = graph.children(node); + hasChildren = hasChildren || children.length > 0; + } + if (!hasChildren) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Done, no node has children", graph.nodes()); + return; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Nodes = ", nodes, depth); + for (const node of nodes) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug( + "Extracting node", + node, + clusterDb, + clusterDb[node] && !clusterDb[node].externalConnections, + !graph.parent(node), + graph.node(node), + graph.children("D"), + " Depth ", + depth + ); + if (!clusterDb[node]) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Not a cluster", node, depth); + } else if (!clusterDb[node].externalConnections && // !graph.parent(node) && + graph.children(node) && graph.children(node).length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster without external connections, without a parent and with children", + node, + depth + ); + const graphSettings = graph.graph(); + let dir = graphSettings.rankdir === "TB" ? "LR" : "TB"; + if (clusterDb[node] && clusterDb[node].clusterData && clusterDb[node].clusterData.dir) { + dir = clusterDb[node].clusterData.dir; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Fixing dir", clusterDb[node].clusterData.dir, dir); + } + const clusterGraph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .k({ + multigraph: true, + compound: true + }).setGraph({ + rankdir: dir, + // Todo: set proper spacing + nodesep: 50, + ranksep: 50, + marginx: 8, + marginy: 8 + }).setDefaultEdgeLabel(function() { + return {}; + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Old graph before copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + copy(node, graph, clusterGraph, node); + graph.setNode(node, { + clusterNode: true, + id: node, + clusterData: clusterDb[node].clusterData, + labelText: clusterDb[node].labelText, + graph: clusterGraph + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New graph after copy node: (", node, ")", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(clusterGraph)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Old graph after copy", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn( + "Cluster ** ", + node, + " **not meeting the criteria !externalConnections:", + !clusterDb[node].externalConnections, + " no parent: ", + !graph.parent(node), + " children ", + graph.children(node) && graph.children(node).length > 0, + graph.children("D"), + depth + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(clusterDb); + } + } + nodes = graph.nodes(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("New list of nodes", nodes); + for (const node of nodes) { + const data = graph.node(node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn(" Now next level", node, data); + if (data.clusterNode) { + extractor(data.graph, depth + 1); + } + } +}; +const sorter = (graph, nodes) => { + if (nodes.length === 0) { + return []; + } + let result = Object.assign(nodes); + nodes.forEach((node) => { + const children = graph.children(node); + const sorted = sorter(graph, children); + result = [...result, ...sorted]; + }); + return result; +}; +const sortNodesByHierarchy = (graph) => sorter(graph, graph.children()); +const rect = (parent, node) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Creating subgraph rect for ", node.id, node); + const shapeSvg = parent.insert("g").attr("class", "cluster" + (node.class ? " " + node.class : "")).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const text = node.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_5__.a)(label, node.labelText, { style: node.labelStyle, useHtmlLabels }) : label.node().appendChild((0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width; + if (node.width <= bbox.width + padding) { + node.diff = (bbox.width - node.width) / 2 - node.padding / 2; + } else { + node.diff = -node.padding / 2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Data ", node, JSON.stringify(node)); + rect2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - width / 2).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width).attr("height", node.height + padding); + if (useHtmlLabels) { + label.attr( + "transform", + // This puts the labal on top of the box instead of inside it + "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2) + ")" + ); + } else { + label.attr( + "transform", + // This puts the labal on top of the box instead of inside it + "translate(" + node.x + ", " + (node.y - node.height / 2) + ")" + ); + } + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const noteGroup = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "note-cluster").attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", node.width + padding).attr("height", node.height + padding).attr("fill", "none"); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const roundedWithTitle = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const label = shapeSvg.insert("g").attr("class", "cluster-label"); + const innerRect = shapeSvg.append("rect"); + const text = label.node().appendChild((0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.c)(node.labelText, node.labelStyle, void 0, true)); + let bbox = text.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_3__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + bbox = text.getBBox(); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width; + if (node.width <= bbox.width + node.padding) { + node.diff = (bbox.width + node.padding * 0 - node.width) / 2; + } else { + node.diff = -node.padding / 2; + } + rect2.attr("class", "outer").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding).attr("width", width + padding).attr("height", node.height + padding); + innerRect.attr("class", "inner").attr("x", node.x - width / 2 - halfPadding).attr("y", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr("width", width + padding).attr("height", node.height + padding - bbox.height - 3); + label.attr( + "transform", + "translate(" + (node.x - bbox.width / 2) + ", " + (node.y - node.height / 2 - node.padding / 3 + ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().flowchart.htmlLabels) ? 5 : 3)) + ")" + ); + const rectBox = rect2.node().getBBox(); + node.height = rectBox.height; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const divider = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", node.classes).attr("id", node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const padding = 0 * node.padding; + const halfPadding = padding / 2; + rect2.attr("class", "divider").attr("x", node.x - node.width / 2 - halfPadding).attr("y", node.y - node.height / 2).attr("width", node.width + padding).attr("height", node.height + padding); + const rectBox = rect2.node().getBBox(); + node.width = rectBox.width; + node.height = rectBox.height; + node.diff = -node.padding / 2; + node.intersect = function(point) { + return (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.i)(node, point); + }; + return shapeSvg; +}; +const shapes = { rect, roundedWithTitle, noteGroup, divider }; +let clusterElems = {}; +const insertCluster = (elem, node) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Inserting cluster"); + const shape = node.shape || "rect"; + clusterElems[node.id] = shapes[shape](elem, node); +}; +const clear = () => { + clusterElems = {}; +}; +const recursiveRender = async (_elem, graph, diagramtype, id, parentCluster) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph in recursive render: XXX", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph), parentCluster); + const dir = graph.graph().rankdir; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Dir in recursive render - dir:", dir); + const elem = _elem.insert("g").attr("class", "root"); + if (!graph.nodes()) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("No nodes found for", graph); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Recursive render XXX", graph.nodes()); + } + if (graph.edges().length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Recursive edges", graph.edge(graph.edges()[0])); + } + const clusters = elem.insert("g").attr("class", "clusters"); + const edgePaths = elem.insert("g").attr("class", "edgePaths"); + const edgeLabels = elem.insert("g").attr("class", "edgeLabels"); + const nodes = elem.insert("g").attr("class", "nodes"); + await Promise.all( + graph.nodes().map(async function(v) { + const node = graph.node(v); + if (parentCluster !== void 0) { + const data = JSON.parse(JSON.stringify(parentCluster.clusterData)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Setting data for cluster XXX (", v, ") ", data, parentCluster); + graph.setNode(parentCluster.id, data); + if (!graph.parent(v)) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.trace("Setting parent", v, parentCluster.id); + graph.setParent(v, parentCluster.id, data); + } + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("(Insert) Node XXX" + v + ": " + JSON.stringify(graph.node(v))); + if (node && node.clusterNode) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster identified", v, node.width, graph.node(v)); + const o = await recursiveRender(nodes, node.graph, diagramtype, id, graph.node(v)); + const newEl = o.elem; + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.u)(node, newEl); + node.diff = o.diff || 0; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node bounds (abc123)", v, node, node.width, node.x, node.y); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.s)(newEl, node); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Recursive render complete ", newEl, node); + } else { + if (graph.children(v).length > 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Cluster - the non recursive path XXX", v, node.id, node, graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(findNonClusterChild(node.id, graph)); + clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node }; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Node - the non recursive path", v, node.id, node); + await (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, graph.node(v), dir); + } + } + }) + ); + graph.edges().forEach(function(e) { + const edge = graph.edge(e.v, e.w, e.name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": ", e, " ", JSON.stringify(graph.edge(e))); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Fix", clusterDb, "ids:", e.v, e.w, "Translateing: ", clusterDb[e.v], clusterDb[e.w]); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.f)(edgeLabels, edge); + }); + graph.edges().forEach(function(e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(e)); + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("### Layout ###"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("#############################################"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(graph); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_0__/* .layout */ .bK)(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Graph after layout:", dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph)); + let diff = 0; + sortNodesByHierarchy(graph).forEach(function(v) { + const node = graph.node(v); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Position " + v + ": " + JSON.stringify(graph.node(v))); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info( + "Position " + v + ": (" + node.x, + "," + node.y, + ") width: ", + node.width, + " height: ", + node.height + ); + if (node && node.clusterNode) { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } else { + if (graph.children(v).length > 0) { + insertCluster(clusters, node); + clusterDb[node.id].node = node; + } else { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.p)(node); + } + } + }); + graph.edges().forEach(function(e) { + const edge = graph.edge(e); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(edge), edge); + const paths = (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.g)(edgePaths, e, edge, clusterDb, diagramtype, graph, id); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.h)(edge, paths); + }); + graph.nodes().forEach(function(v) { + const n = graph.node(v); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.info(v, n.type, n.diff); + if (n.type === "group") { + diff = n.diff; + } + }); + return { elem, diff }; +}; +const render = async (elem, graph, markers, diagramtype, id) => { + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.a)(elem, markers, diagramtype, id); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.b)(); + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.d)(); + clear(); + clear$1(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph at first:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph))); + adjustClustersAndEdges(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.warn("Graph after:", JSON.stringify(dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_1__/* .write */ .c(graph))); + await recursiveRender(elem, graph, diagramtype, id); +}; + + + +/***/ }), + +/***/ 82127: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ p: () => (/* binding */ parser$1), +/* harmony export */ s: () => (/* binding */ styles) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 16], $V1 = [1, 17], $V2 = [1, 18], $V3 = [1, 37], $V4 = [1, 38], $V5 = [1, 24], $V6 = [1, 22], $V7 = [1, 23], $V8 = [1, 29], $V9 = [1, 30], $Va = [1, 31], $Vb = [1, 32], $Vc = [1, 33], $Vd = [1, 34], $Ve = [1, 25], $Vf = [1, 26], $Vg = [1, 27], $Vh = [1, 28], $Vi = [1, 42], $Vj = [1, 39], $Vk = [1, 40], $Vl = [1, 41], $Vm = [1, 43], $Vn = [1, 9], $Vo = [1, 8, 9], $Vp = [1, 54], $Vq = [1, 55], $Vr = [1, 56], $Vs = [1, 57], $Vt = [1, 58], $Vu = [1, 59], $Vv = [1, 60], $Vw = [1, 8, 9, 38], $Vx = [1, 71], $Vy = [1, 8, 9, 12, 13, 21, 36, 38, 41, 58, 59, 60, 61, 62, 63, 64, 69, 71], $Vz = [1, 8, 9, 12, 13, 19, 21, 36, 38, 41, 45, 58, 59, 60, 61, 62, 63, 64, 69, 71, 84, 86, 87, 88, 89], $VA = [13, 84, 86, 87, 88, 89], $VB = [13, 63, 64, 84, 86, 87, 88, 89], $VC = [13, 58, 59, 60, 61, 62, 84, 86, 87, 88, 89], $VD = [1, 90], $VE = [1, 8, 9, 36, 38, 41], $VF = [1, 8, 9, 21]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "mermaidDoc": 4, "statements": 5, "graphConfig": 6, "CLASS_DIAGRAM": 7, "NEWLINE": 8, "EOF": 9, "statement": 10, "classLabel": 11, "SQS": 12, "STR": 13, "SQE": 14, "namespaceName": 15, "alphaNumToken": 16, "className": 17, "classLiteralName": 18, "GENERICTYPE": 19, "relationStatement": 20, "LABEL": 21, "namespaceStatement": 22, "classStatement": 23, "memberStatement": 24, "annotationStatement": 25, "clickStatement": 26, "cssClassStatement": 27, "noteStatement": 28, "direction": 29, "acc_title": 30, "acc_title_value": 31, "acc_descr": 32, "acc_descr_value": 33, "acc_descr_multiline_value": 34, "namespaceIdentifier": 35, "STRUCT_START": 36, "classStatements": 37, "STRUCT_STOP": 38, "NAMESPACE": 39, "classIdentifier": 40, "STYLE_SEPARATOR": 41, "members": 42, "CLASS": 43, "ANNOTATION_START": 44, "ANNOTATION_END": 45, "MEMBER": 46, "SEPARATOR": 47, "relation": 48, "NOTE_FOR": 49, "noteText": 50, "NOTE": 51, "direction_tb": 52, "direction_bt": 53, "direction_rl": 54, "direction_lr": 55, "relationType": 56, "lineType": 57, "AGGREGATION": 58, "EXTENSION": 59, "COMPOSITION": 60, "DEPENDENCY": 61, "LOLLIPOP": 62, "LINE": 63, "DOTTED_LINE": 64, "CALLBACK": 65, "LINK": 66, "LINK_TARGET": 67, "CLICK": 68, "CALLBACK_NAME": 69, "CALLBACK_ARGS": 70, "HREF": 71, "CSSCLASS": 72, "commentToken": 73, "textToken": 74, "graphCodeTokens": 75, "textNoTagsToken": 76, "TAGSTART": 77, "TAGEND": 78, "==": 79, "--": 80, "PCT": 81, "DEFAULT": 82, "SPACE": 83, "MINUS": 84, "keywords": 85, "UNICODE_TEXT": 86, "NUM": 87, "ALPHA": 88, "BQUOTE_STR": 89, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 7: "CLASS_DIAGRAM", 8: "NEWLINE", 9: "EOF", 12: "SQS", 13: "STR", 14: "SQE", 19: "GENERICTYPE", 21: "LABEL", 30: "acc_title", 31: "acc_title_value", 32: "acc_descr", 33: "acc_descr_value", 34: "acc_descr_multiline_value", 36: "STRUCT_START", 38: "STRUCT_STOP", 39: "NAMESPACE", 41: "STYLE_SEPARATOR", 43: "CLASS", 44: "ANNOTATION_START", 45: "ANNOTATION_END", 46: "MEMBER", 47: "SEPARATOR", 49: "NOTE_FOR", 51: "NOTE", 52: "direction_tb", 53: "direction_bt", 54: "direction_rl", 55: "direction_lr", 58: "AGGREGATION", 59: "EXTENSION", 60: "COMPOSITION", 61: "DEPENDENCY", 62: "LOLLIPOP", 63: "LINE", 64: "DOTTED_LINE", 65: "CALLBACK", 66: "LINK", 67: "LINK_TARGET", 68: "CLICK", 69: "CALLBACK_NAME", 70: "CALLBACK_ARGS", 71: "HREF", 72: "CSSCLASS", 75: "graphCodeTokens", 77: "TAGSTART", 78: "TAGEND", 79: "==", 80: "--", 81: "PCT", 82: "DEFAULT", 83: "SPACE", 84: "MINUS", 85: "keywords", 86: "UNICODE_TEXT", 87: "NUM", 88: "ALPHA", 89: "BQUOTE_STR" }, + productions_: [0, [3, 1], [3, 1], [4, 1], [6, 4], [5, 1], [5, 2], [5, 3], [11, 3], [15, 1], [15, 2], [17, 1], [17, 1], [17, 2], [17, 2], [17, 2], [10, 1], [10, 2], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [10, 1], [22, 4], [22, 5], [35, 2], [37, 1], [37, 2], [37, 3], [23, 1], [23, 3], [23, 4], [23, 6], [40, 2], [40, 3], [25, 4], [42, 1], [42, 2], [24, 1], [24, 2], [24, 1], [24, 1], [20, 3], [20, 4], [20, 4], [20, 5], [28, 3], [28, 2], [29, 1], [29, 1], [29, 1], [29, 1], [48, 3], [48, 2], [48, 2], [48, 1], [56, 1], [56, 1], [56, 1], [56, 1], [56, 1], [57, 1], [57, 1], [26, 3], [26, 4], [26, 3], [26, 4], [26, 4], [26, 5], [26, 3], [26, 4], [26, 4], [26, 5], [26, 4], [26, 5], [26, 5], [26, 6], [27, 3], [73, 1], [73, 1], [74, 1], [74, 1], [74, 1], [74, 1], [74, 1], [74, 1], [74, 1], [76, 1], [76, 1], [76, 1], [76, 1], [16, 1], [16, 1], [16, 1], [16, 1], [18, 1], [50, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 8: + this.$ = $$[$0 - 1]; + break; + case 9: + case 11: + case 12: + this.$ = $$[$0]; + break; + case 10: + case 13: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 14: + case 15: + this.$ = $$[$0 - 1] + "~" + $$[$0] + "~"; + break; + case 16: + yy.addRelation($$[$0]); + break; + case 17: + $$[$0 - 1].title = yy.cleanupLabel($$[$0]); + yy.addRelation($$[$0 - 1]); + break; + case 26: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 27: + case 28: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 29: + yy.addClassesToNamespace($$[$0 - 3], $$[$0 - 1]); + break; + case 30: + yy.addClassesToNamespace($$[$0 - 4], $$[$0 - 1]); + break; + case 31: + this.$ = $$[$0]; + yy.addNamespace($$[$0]); + break; + case 32: + this.$ = [$$[$0]]; + break; + case 33: + this.$ = [$$[$0 - 1]]; + break; + case 34: + $$[$0].unshift($$[$0 - 2]); + this.$ = $$[$0]; + break; + case 36: + yy.setCssClass($$[$0 - 2], $$[$0]); + break; + case 37: + yy.addMembers($$[$0 - 3], $$[$0 - 1]); + break; + case 38: + yy.setCssClass($$[$0 - 5], $$[$0 - 3]); + yy.addMembers($$[$0 - 5], $$[$0 - 1]); + break; + case 39: + this.$ = $$[$0]; + yy.addClass($$[$0]); + break; + case 40: + this.$ = $$[$0 - 1]; + yy.addClass($$[$0 - 1]); + yy.setClassLabel($$[$0 - 1], $$[$0]); + break; + case 41: + yy.addAnnotation($$[$0], $$[$0 - 2]); + break; + case 42: + this.$ = [$$[$0]]; + break; + case 43: + $$[$0].push($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 44: + break; + case 45: + yy.addMember($$[$0 - 1], yy.cleanupLabel($$[$0])); + break; + case 46: + break; + case 47: + break; + case 48: + this.$ = { "id1": $$[$0 - 2], "id2": $$[$0], relation: $$[$0 - 1], relationTitle1: "none", relationTitle2: "none" }; + break; + case 49: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 1], relationTitle1: $$[$0 - 2], relationTitle2: "none" }; + break; + case 50: + this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: "none", relationTitle2: $$[$0 - 1] }; + break; + case 51: + this.$ = { id1: $$[$0 - 4], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: $$[$0 - 3], relationTitle2: $$[$0 - 1] }; + break; + case 52: + yy.addNote($$[$0], $$[$0 - 1]); + break; + case 53: + yy.addNote($$[$0]); + break; + case 54: + yy.setDirection("TB"); + break; + case 55: + yy.setDirection("BT"); + break; + case 56: + yy.setDirection("RL"); + break; + case 57: + yy.setDirection("LR"); + break; + case 58: + this.$ = { type1: $$[$0 - 2], type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 59: + this.$ = { type1: "none", type2: $$[$0], lineType: $$[$0 - 1] }; + break; + case 60: + this.$ = { type1: $$[$0 - 1], type2: "none", lineType: $$[$0] }; + break; + case 61: + this.$ = { type1: "none", type2: "none", lineType: $$[$0] }; + break; + case 62: + this.$ = yy.relationType.AGGREGATION; + break; + case 63: + this.$ = yy.relationType.EXTENSION; + break; + case 64: + this.$ = yy.relationType.COMPOSITION; + break; + case 65: + this.$ = yy.relationType.DEPENDENCY; + break; + case 66: + this.$ = yy.relationType.LOLLIPOP; + break; + case 67: + this.$ = yy.lineType.LINE; + break; + case 68: + this.$ = yy.lineType.DOTTED_LINE; + break; + case 69: + case 75: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 70: + case 76: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 2], $$[$0]); + break; + case 71: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 72: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 73: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 2], $$[$0]); + break; + case 74: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + yy.setTooltip($$[$0 - 3], $$[$0 - 1]); + break; + case 77: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 78: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 79: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 80: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 1], $$[$0]); + break; + case 81: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 3], $$[$0 - 1]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 82: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + yy.setTooltip($$[$0 - 4], $$[$0 - 1]); + break; + case 83: + yy.setCssClass($$[$0 - 1], $$[$0]); + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: 4, 7: [1, 6], 10: 5, 16: 35, 17: 19, 18: 36, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: $V0, 32: $V1, 34: $V2, 35: 20, 39: $V3, 40: 21, 43: $V4, 44: $V5, 46: $V6, 47: $V7, 49: $V8, 51: $V9, 52: $Va, 53: $Vb, 54: $Vc, 55: $Vd, 65: $Ve, 66: $Vf, 68: $Vg, 72: $Vh, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 1: [3] }, { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3] }, o($Vn, [2, 5], { 8: [1, 44] }), { 8: [1, 45] }, o($Vo, [2, 16], { 21: [1, 46] }), o($Vo, [2, 18]), o($Vo, [2, 19]), o($Vo, [2, 20]), o($Vo, [2, 21]), o($Vo, [2, 22]), o($Vo, [2, 23]), o($Vo, [2, 24]), o($Vo, [2, 25]), { 31: [1, 47] }, { 33: [1, 48] }, o($Vo, [2, 28]), o($Vo, [2, 44], { 48: 49, 56: 52, 57: 53, 13: [1, 50], 21: [1, 51], 58: $Vp, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv }), { 36: [1, 61] }, o($Vw, [2, 35], { 36: [1, 63], 41: [1, 62] }), o($Vo, [2, 46]), o($Vo, [2, 47]), { 16: 64, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, { 16: 35, 17: 65, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 16: 35, 17: 66, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 16: 35, 17: 67, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 13: [1, 68] }, { 16: 35, 17: 69, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 13: $Vx, 50: 70 }, o($Vo, [2, 54]), o($Vo, [2, 55]), o($Vo, [2, 56]), o($Vo, [2, 57]), o($Vy, [2, 11], { 16: 35, 18: 36, 17: 72, 19: [1, 73], 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }), o($Vy, [2, 12], { 19: [1, 74] }), { 15: 75, 16: 76, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, { 16: 35, 17: 77, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($Vz, [2, 97]), o($Vz, [2, 98]), o($Vz, [2, 99]), o($Vz, [2, 100]), o([1, 8, 9, 12, 13, 19, 21, 36, 38, 41, 58, 59, 60, 61, 62, 63, 64, 69, 71], [2, 101]), o($Vn, [2, 6], { 10: 5, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 17: 19, 35: 20, 40: 21, 16: 35, 18: 36, 5: 78, 30: $V0, 32: $V1, 34: $V2, 39: $V3, 43: $V4, 44: $V5, 46: $V6, 47: $V7, 49: $V8, 51: $V9, 52: $Va, 53: $Vb, 54: $Vc, 55: $Vd, 65: $Ve, 66: $Vf, 68: $Vg, 72: $Vh, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }), { 5: 79, 10: 5, 16: 35, 17: 19, 18: 36, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: $V0, 32: $V1, 34: $V2, 35: 20, 39: $V3, 40: 21, 43: $V4, 44: $V5, 46: $V6, 47: $V7, 49: $V8, 51: $V9, 52: $Va, 53: $Vb, 54: $Vc, 55: $Vd, 65: $Ve, 66: $Vf, 68: $Vg, 72: $Vh, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($Vo, [2, 17]), o($Vo, [2, 26]), o($Vo, [2, 27]), { 13: [1, 81], 16: 35, 17: 80, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 48: 82, 56: 52, 57: 53, 58: $Vp, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv }, o($Vo, [2, 45]), { 57: 83, 63: $Vu, 64: $Vv }, o($VA, [2, 61], { 56: 84, 58: $Vp, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt }), o($VB, [2, 62]), o($VB, [2, 63]), o($VB, [2, 64]), o($VB, [2, 65]), o($VB, [2, 66]), o($VC, [2, 67]), o($VC, [2, 68]), { 8: [1, 86], 23: 87, 37: 85, 40: 21, 43: $V4 }, { 16: 88, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, { 42: 89, 46: $VD }, { 45: [1, 91] }, { 13: [1, 92] }, { 13: [1, 93] }, { 69: [1, 94], 71: [1, 95] }, { 16: 96, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, { 13: $Vx, 50: 97 }, o($Vo, [2, 53]), o($Vo, [2, 102]), o($Vy, [2, 13]), o($Vy, [2, 14]), o($Vy, [2, 15]), { 36: [2, 31] }, { 15: 98, 16: 76, 36: [2, 9], 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl }, o($VE, [2, 39], { 11: 99, 12: [1, 100] }), o($Vn, [2, 7]), { 9: [1, 101] }, o($VF, [2, 48]), { 16: 35, 17: 102, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, { 13: [1, 104], 16: 35, 17: 103, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($VA, [2, 60], { 56: 105, 58: $Vp, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt }), o($VA, [2, 59]), { 38: [1, 106] }, { 23: 87, 37: 107, 40: 21, 43: $V4 }, { 8: [1, 108], 38: [2, 32] }, o($Vw, [2, 36], { 36: [1, 109] }), { 38: [1, 110] }, { 38: [2, 42], 42: 111, 46: $VD }, { 16: 35, 17: 112, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($Vo, [2, 69], { 13: [1, 113] }), o($Vo, [2, 71], { 13: [1, 115], 67: [1, 114] }), o($Vo, [2, 75], { 13: [1, 116], 70: [1, 117] }), { 13: [1, 118] }, o($Vo, [2, 83]), o($Vo, [2, 52]), { 36: [2, 10] }, o($VE, [2, 40]), { 13: [1, 119] }, { 1: [2, 4] }, o($VF, [2, 50]), o($VF, [2, 49]), { 16: 35, 17: 120, 18: 36, 84: $Vi, 86: $Vj, 87: $Vk, 88: $Vl, 89: $Vm }, o($VA, [2, 58]), o($Vo, [2, 29]), { 38: [1, 121] }, { 23: 87, 37: 122, 38: [2, 33], 40: 21, 43: $V4 }, { 42: 123, 46: $VD }, o($Vw, [2, 37]), { 38: [2, 43] }, o($Vo, [2, 41]), o($Vo, [2, 70]), o($Vo, [2, 72]), o($Vo, [2, 73], { 67: [1, 124] }), o($Vo, [2, 76]), o($Vo, [2, 77], { 13: [1, 125] }), o($Vo, [2, 79], { 13: [1, 127], 67: [1, 126] }), { 14: [1, 128] }, o($VF, [2, 51]), o($Vo, [2, 30]), { 38: [2, 34] }, { 38: [1, 129] }, o($Vo, [2, 74]), o($Vo, [2, 78]), o($Vo, [2, 80]), o($Vo, [2, 81], { 67: [1, 130] }), o($VE, [2, 8]), o($Vw, [2, 38]), o($Vo, [2, 82])], + defaultActions: { 2: [2, 1], 3: [2, 2], 4: [2, 3], 75: [2, 31], 98: [2, 10], 101: [2, 4], 111: [2, 43], 122: [2, 34] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 52; + case 1: + return 53; + case 2: + return 54; + case 3: + return 55; + case 4: + break; + case 5: + break; + case 6: + this.begin("acc_title"); + return 30; + case 7: + this.popState(); + return "acc_title_value"; + case 8: + this.begin("acc_descr"); + return 32; + case 9: + this.popState(); + return "acc_descr_value"; + case 10: + this.begin("acc_descr_multiline"); + break; + case 11: + this.popState(); + break; + case 12: + return "acc_descr_multiline_value"; + case 13: + return 8; + case 14: + break; + case 15: + return 7; + case 16: + return 7; + case 17: + return "EDGE_STATE"; + case 18: + this.begin("callback_name"); + break; + case 19: + this.popState(); + break; + case 20: + this.popState(); + this.begin("callback_args"); + break; + case 21: + return 69; + case 22: + this.popState(); + break; + case 23: + return 70; + case 24: + this.popState(); + break; + case 25: + return "STR"; + case 26: + this.begin("string"); + break; + case 27: + this.begin("namespace"); + return 39; + case 28: + this.popState(); + return 8; + case 29: + break; + case 30: + this.begin("namespace-body"); + return 36; + case 31: + this.popState(); + return 38; + case 32: + return "EOF_IN_STRUCT"; + case 33: + return 8; + case 34: + break; + case 35: + return "EDGE_STATE"; + case 36: + this.begin("class"); + return 43; + case 37: + this.popState(); + return 8; + case 38: + break; + case 39: + this.popState(); + this.popState(); + return 38; + case 40: + this.begin("class-body"); + return 36; + case 41: + this.popState(); + return 38; + case 42: + return "EOF_IN_STRUCT"; + case 43: + return "EDGE_STATE"; + case 44: + return "OPEN_IN_STRUCT"; + case 45: + break; + case 46: + return "MEMBER"; + case 47: + return 72; + case 48: + return 65; + case 49: + return 66; + case 50: + return 68; + case 51: + return 49; + case 52: + return 51; + case 53: + return 44; + case 54: + return 45; + case 55: + return 71; + case 56: + this.popState(); + break; + case 57: + return "GENERICTYPE"; + case 58: + this.begin("generic"); + break; + case 59: + this.popState(); + break; + case 60: + return "BQUOTE_STR"; + case 61: + this.begin("bqstring"); + break; + case 62: + return 67; + case 63: + return 67; + case 64: + return 67; + case 65: + return 67; + case 66: + return 59; + case 67: + return 59; + case 68: + return 61; + case 69: + return 61; + case 70: + return 60; + case 71: + return 58; + case 72: + return 62; + case 73: + return 63; + case 74: + return 64; + case 75: + return 21; + case 76: + return 41; + case 77: + return 84; + case 78: + return "DOT"; + case 79: + return "PLUS"; + case 80: + return 81; + case 81: + return "EQUALS"; + case 82: + return "EQUALS"; + case 83: + return 88; + case 84: + return 12; + case 85: + return 14; + case 86: + return "PUNCTUATION"; + case 87: + return 87; + case 88: + return 86; + case 89: + return 83; + case 90: + return 9; + } + }, + rules: [/^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/, /^(?:%%[^\n]*(\r?\n)*)/, /^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:classDiagram-v2\b)/, /^(?:classDiagram\b)/, /^(?:\[\*\])/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:["])/, /^(?:[^"]*)/, /^(?:["])/, /^(?:namespace\b)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:\[\*\])/, /^(?:class\b)/, /^(?:\s*(\r?\n)+)/, /^(?:\s+)/, /^(?:[}])/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\[\*\])/, /^(?:[{])/, /^(?:[\n])/, /^(?:[^{}\n]*)/, /^(?:cssClass\b)/, /^(?:callback\b)/, /^(?:link\b)/, /^(?:click\b)/, /^(?:note for\b)/, /^(?:note\b)/, /^(?:<<)/, /^(?:>>)/, /^(?:href\b)/, /^(?:[~])/, /^(?:[^~]*)/, /^(?:~)/, /^(?:[`])/, /^(?:[^`]+)/, /^(?:[`])/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:\s*<\|)/, /^(?:\s*\|>)/, /^(?:\s*>)/, /^(?:\s*<)/, /^(?:\s*\*)/, /^(?:\s*o\b)/, /^(?:\s*\(\))/, /^(?:--)/, /^(?:\.\.)/, /^(?::{1}[^:\n;]+)/, /^(?::{3})/, /^(?:-)/, /^(?:\.)/, /^(?:\+)/, /^(?:%)/, /^(?:=)/, /^(?:=)/, /^(?:\w+)/, /^(?:\[)/, /^(?:\])/, /^(?:[!"#$%&'*+,-.`?\\/])/, /^(?:[0-9]+)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\s)/, /^(?:$)/], + conditions: { "namespace-body": { "rules": [26, 31, 32, 33, 34, 35, 36, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "namespace": { "rules": [26, 27, 28, 29, 30, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "class-body": { "rules": [26, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "class": { "rules": [26, 37, 38, 39, 40, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "acc_descr_multiline": { "rules": [11, 12, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "acc_descr": { "rules": [9, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "acc_title": { "rules": [7, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "callback_args": { "rules": [22, 23, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "callback_name": { "rules": [19, 20, 21, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "href": { "rules": [26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "struct": { "rules": [26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "generic": { "rules": [26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "bqstring": { "rules": [26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "string": { "rules": [24, 25, 26, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 14, 15, 16, 17, 18, 26, 27, 36, 47, 48, 49, 50, 51, 52, 53, 54, 55, 58, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const visibilityValues = ["#", "+", "~", "-", ""]; +class ClassMember { + constructor(input, memberType) { + this.memberType = memberType; + this.visibility = ""; + this.classifier = ""; + const sanitizedInput = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)(input, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + this.parseMember(sanitizedInput); + } + getDisplayDetails() { + let displayText = this.visibility + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.v)(this.id); + if (this.memberType === "method") { + displayText += `(${(0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.v)(this.parameters.trim())})`; + if (this.returnType) { + displayText += " : " + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.v)(this.returnType); + } + } + displayText = displayText.trim(); + const cssStyle = this.parseClassifier(); + return { + displayText, + cssStyle + }; + } + parseMember(input) { + let potentialClassifier = ""; + if (this.memberType === "method") { + const methodRegEx = /([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/; + const match = input.match(methodRegEx); + if (match) { + const detectedVisibility = match[1] ? match[1].trim() : ""; + if (visibilityValues.includes(detectedVisibility)) { + this.visibility = detectedVisibility; + } + this.id = match[2].trim(); + this.parameters = match[3] ? match[3].trim() : ""; + potentialClassifier = match[4] ? match[4].trim() : ""; + this.returnType = match[5] ? match[5].trim() : ""; + if (potentialClassifier === "") { + const lastChar = this.returnType.substring(this.returnType.length - 1); + if (lastChar.match(/[$*]/)) { + potentialClassifier = lastChar; + this.returnType = this.returnType.substring(0, this.returnType.length - 1); + } + } + } + } else { + const length = input.length; + const firstChar = input.substring(0, 1); + const lastChar = input.substring(length - 1); + if (visibilityValues.includes(firstChar)) { + this.visibility = firstChar; + } + if (lastChar.match(/[*?]/)) { + potentialClassifier = lastChar; + } + this.id = input.substring( + this.visibility === "" ? 0 : 1, + potentialClassifier === "" ? length : length - 1 + ); + } + this.classifier = potentialClassifier; + } + parseClassifier() { + switch (this.classifier) { + case "*": + return "font-style:italic;"; + case "$": + return "text-decoration:underline;"; + default: + return ""; + } + } +} +const MERMAID_DOM_ID_PREFIX = "classId-"; +let relations = []; +let classes = {}; +let notes = []; +let classCounter = 0; +let namespaces = {}; +let namespaceCounter = 0; +let functions = []; +const sanitizeText = (txt) => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); +const splitClassNameAndType = function(_id) { + const id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + let genericType = ""; + let className = id; + if (id.indexOf("~") > 0) { + const split = id.split("~"); + className = sanitizeText(split[0]); + genericType = sanitizeText(split[1]); + } + return { className, type: genericType }; +}; +const setClassLabel = function(_id, label) { + const id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + if (label) { + label = sanitizeText(label); + } + const { className } = splitClassNameAndType(id); + classes[className].label = label; +}; +const addClass = function(_id) { + const id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + const { className, type } = splitClassNameAndType(id); + if (Object.hasOwn(classes, className)) { + return; + } + const name = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(className, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + classes[name] = { + id: name, + type, + label: name, + cssClasses: [], + methods: [], + members: [], + annotations: [], + domId: MERMAID_DOM_ID_PREFIX + name + "-" + classCounter + }; + classCounter++; +}; +const lookUpDomId = function(_id) { + const id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + if (id in classes) { + return classes[id].domId; + } + throw new Error("Class not found: " + id); +}; +const clear = function() { + relations = []; + classes = {}; + notes = []; + functions = []; + functions.push(setupToolTips); + namespaces = {}; + namespaceCounter = 0; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.t)(); +}; +const getClass = function(id) { + return classes[id]; +}; +const getClasses = function() { + return classes; +}; +const getRelations = function() { + return relations; +}; +const getNotes = function() { + return notes; +}; +const addRelation = function(relation) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("Adding relation: " + JSON.stringify(relation)); + addClass(relation.id1); + addClass(relation.id2); + relation.id1 = splitClassNameAndType(relation.id1).className; + relation.id2 = splitClassNameAndType(relation.id2).className; + relation.relationTitle1 = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(relation.relationTitle1.trim(), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + relation.relationTitle2 = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(relation.relationTitle2.trim(), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + relations.push(relation); +}; +const addAnnotation = function(className, annotation) { + const validatedClassName = splitClassNameAndType(className).className; + classes[validatedClassName].annotations.push(annotation); +}; +const addMember = function(className, member) { + addClass(className); + const validatedClassName = splitClassNameAndType(className).className; + const theClass = classes[validatedClassName]; + if (typeof member === "string") { + const memberString = member.trim(); + if (memberString.startsWith("<<") && memberString.endsWith(">>")) { + theClass.annotations.push(sanitizeText(memberString.substring(2, memberString.length - 2))); + } else if (memberString.indexOf(")") > 0) { + theClass.methods.push(new ClassMember(memberString, "method")); + } else if (memberString) { + theClass.members.push(new ClassMember(memberString, "attribute")); + } + } +}; +const addMembers = function(className, members) { + if (Array.isArray(members)) { + members.reverse(); + members.forEach((member) => addMember(className, member)); + } +}; +const addNote = function(text, className) { + const note = { + id: `note${notes.length}`, + class: className, + text + }; + notes.push(note); +}; +const cleanupLabel = function(label) { + if (label.startsWith(":")) { + label = label.substring(1); + } + return sanitizeText(label.trim()); +}; +const setCssClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== void 0) { + classes[id].cssClasses.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + classes[id].tooltip = sanitizeText(tooltip); + } + }); +}; +const getTooltip = function(id, namespace) { + if (namespace) { + return namespaces[namespace].classes[id].tooltip; + } + return classes[id].tooltip; +}; +const setLink = function(ids, linkStr, target) { + const config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + ids.split(",").forEach(function(_id) { + let id = _id; + if (_id[0].match(/\d/)) { + id = MERMAID_DOM_ID_PREFIX + id; + } + if (classes[id] !== void 0) { + classes[id].link = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + if (config.securityLevel === "sandbox") { + classes[id].linkTarget = "_top"; + } else if (typeof target === "string") { + classes[id].linkTarget = sanitizeText(target); + } else { + classes[id].linkTarget = "_blank"; + } + } + }); + setCssClass(ids, "clickable"); +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFunc(id, functionName, functionArgs); + classes[id].haveCallback = true; + }); + setCssClass(ids, "clickable"); +}; +const setClickFunc = function(_domId, functionName, functionArgs) { + const domId = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(_domId, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()); + const config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + if (config.securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + const id = domId; + if (classes[id] !== void 0) { + const elemId = lookUpDomId(id); + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(elemId); + } + functions.push(function() { + const elem = document.querySelector(`[id="${elemId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const bindFunctions = function(element) { + functions.forEach(function(fun) { + fun(element); + }); +}; +const lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; +const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3, + LOLLIPOP: 4 +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.top - 14 + document.body.scrollTop + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "<br/>")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + el.classed("hover", false); + }); +}; +functions.push(setupToolTips); +let direction = "TB"; +const getDirection = () => direction; +const setDirection = (dir) => { + direction = dir; +}; +const addNamespace = function(id) { + if (namespaces[id] !== void 0) { + return; + } + namespaces[id] = { + id, + classes: {}, + children: {}, + domId: MERMAID_DOM_ID_PREFIX + id + "-" + namespaceCounter + }; + namespaceCounter++; +}; +const getNamespace = function(name) { + return namespaces[name]; +}; +const getNamespaces = function() { + return namespaces; +}; +const addClassesToNamespace = function(id, classNames) { + if (namespaces[id] !== void 0) { + classNames.map((className) => { + classes[className].parent = id; + namespaces[id].classes[className] = classes[className]; + }); + } +}; +const db = { + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.b, + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().class, + addClass, + bindFunctions, + clear, + getClass, + getClasses, + getNotes, + addAnnotation, + addNote, + getRelations, + addRelation, + getDirection, + setDirection, + addMember, + addMembers, + cleanupLabel, + lineType, + relationType, + setClickEvent, + setCssClass, + setLink, + getTooltip, + setTooltip, + lookUpDomId, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.r, + setClassLabel, + addNamespace, + addClassesToNamespace, + getNamespace, + getNamespaces +}; +const getStyles = (options) => `g.classGroup text { + fill: ${options.nodeBorder || options.classText}; + stroke: none; + font-family: ${options.fontFamily}; + font-size: 10px; + + .title { + font-weight: bolder; + } + +} + +.nodeLabel, .edgeLabel { + color: ${options.classText}; +} +.edgeLabel .label rect { + fill: ${options.mainBkg}; +} +.label text { + fill: ${options.classText}; +} +.edgeLabel .label span { + background: ${options.mainBkg}; +} + +.classTitle { + font-weight: bolder; +} +.node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + +.divider { + stroke: ${options.nodeBorder}; + stroke-width: 1; +} + +g.clickable { + cursor: pointer; +} + +g.classGroup rect { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; +} + +g.classGroup line { + stroke: ${options.nodeBorder}; + stroke-width: 1; +} + +.classLabel .box { + stroke: none; + stroke-width: 0; + fill: ${options.mainBkg}; + opacity: 0.5; +} + +.classLabel .label { + fill: ${options.nodeBorder}; + font-size: 10px; +} + +.relation { + stroke: ${options.lineColor}; + stroke-width: 1; + fill: none; +} + +.dashed-line{ + stroke-dasharray: 3; +} + +.dotted-line{ + stroke-dasharray: 1 2; +} + +#compositionStart, .composition { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#compositionEnd, .composition { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#dependencyStart, .dependency { + fill: ${options.lineColor} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#extensionStart, .extension { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#extensionEnd, .extension { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#aggregationStart, .aggregation { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#aggregationEnd, .aggregation { + fill: transparent !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#lollipopStart, .lollipop { + fill: ${options.mainBkg} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +#lollipopEnd, .lollipop { + fill: ${options.mainBkg} !important; + stroke: ${options.lineColor} !important; + stroke-width: 1; +} + +.edgeTerminals { + font-size: 11px; +} + +.classTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} +`; +const styles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/6a19354d.c2212a44.js b/assets/js/6a19354d.67483436.js similarity index 88% rename from assets/js/6a19354d.c2212a44.js rename to assets/js/6a19354d.67483436.js index 139720068..0b651ccaa 100644 --- a/assets/js/6a19354d.c2212a44.js +++ b/assets/js/6a19354d.67483436.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[693],{36232:e=>{e.exports=JSON.parse('{"label":"Lock","permalink":"/tags/lock","allTagsPath":"/tags","count":2}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[693],{36232:e=>{e.exports=JSON.parse('{"label":"Lock","permalink":"/tags/lock","allTagsPath":"/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/6b4e1191.5ce4d8f9.js b/assets/js/6b4e1191.5ce4d8f9.js deleted file mode 100644 index 1c48bab9e..000000000 --- a/assets/js/6b4e1191.5ce4d8f9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[838],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},l=Object.keys(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=c(r),m=a,b=d["".concat(i,".").concat(m)]||d[m]||s[m]||l;return r?n.createElement(b,p(p({ref:t},u),{},{components:r})):n.createElement(b,p({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,p=new Array(l);p[0]=d;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o.mdxType="string"==typeof e?e:a,p[1]=o;for(var c=2;c<l;c++)p[c]=r[c];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},980:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>s,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",slug:"/etc/healthful-growth",last_update:{date:"2023/04/19"},tags:["etc"]},p=void 0,o={unversionedId:"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",id:"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",description:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 4\uc6d4 19\uc77c",source:"@site/docs/\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30.mdx",sourceDirName:"\uae30\ud0c0",slug:"/etc/healthful-growth",permalink:"/docs/etc/healthful-growth",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30.mdx",tags:[{label:"etc",permalink:"/docs/tags/etc"}],version:"current",lastUpdatedAt:1681862400,formattedLastUpdatedAt:"2023\ub144 4\uc6d4 19\uc77c",frontMatter:{title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",slug:"/etc/healthful-growth",last_update:{date:"2023/04/19"},tags:["etc"]},sidebar:"tutorialSidebar",previous:{title:"\ubb38\uc11c",permalink:"/docs/"},next:{title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",permalink:"/docs/etc/develop-with-spring"}},i={},c=[{value:"\uc790\uc874\uac10 \uae30\ub465 \ub9cc\ub4e4\uae30",id:"\uc790\uc874\uac10-\uae30\ub465-\ub9cc\ub4e4\uae30",level:3},{value:"\ub098\ub9cc\uc758 \ud559\uc2b5 \ubc29\ubc95 \ucc3e\uae30",id:"\ub098\ub9cc\uc758-\ud559\uc2b5-\ubc29\ubc95-\ucc3e\uae30",level:3},{value:"\uc0c8\ub85c\uc6b4 \ud658\uacbd\uc744 \uc798 \ubc30\uc6b0\ub294 \ubc29\ubc95",id:"\uc0c8\ub85c\uc6b4-\ud658\uacbd\uc744-\uc798-\ubc30\uc6b0\ub294-\ubc29\ubc95",level:3},{value:"\ud559\uc2b5 \uc8fc\uc81c",id:"\ud559\uc2b5-\uc8fc\uc81c",level:3},{value:"\uc0b0\ub9cc\ud568 \uad00\ub9ac\ud558\uae30",id:"\uc0b0\ub9cc\ud568-\uad00\ub9ac\ud558\uae30",level:3},{value:"\uac70\uc778\uc5d0 \uc5b4\uae68\uc704\uc5d0 \uc62c\ub77c\ud0c0\uae30",id:"\uac70\uc778\uc5d0-\uc5b4\uae68\uc704\uc5d0-\uc62c\ub77c\ud0c0\uae30",level:3},{value:"\ubcf4\uc0c1",id:"\ubcf4\uc0c1",level:3},{value:"\ub0a8\uc744 \uc124\ub4dd\ud558\ub294 \ubc29\ubc95 \ubc30\uc6b0\uae30",id:"\ub0a8\uc744-\uc124\ub4dd\ud558\ub294-\ubc29\ubc95-\ubc30\uc6b0\uae30",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 4\uc6d4 19\uc77c",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub3d9\uc6b1\ub2d8 \ud2b9\uac15"),(0,a.kt)("h3",{id:"\uc790\uc874\uac10-\uae30\ub465-\ub9cc\ub4e4\uae30"},"\uc790\uc874\uac10 \uae30\ub465 \ub9cc\ub4e4\uae30"),(0,a.kt)("p",null,"\ub6f0\uc5b4\ub09c \ub3d9\ub8cc, \uc0c8\ub85c\uc6b4 \ud658\uacbd \uadf8\ub9ac\uace0 \ud504\ub85c\uc81d\ud2b8\ub97c \uc2e4\ud328\ud558\uba74\uc11c \uc790\uc874\uac10\uc774 \ub5a8\uc5b4\uc9c8 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\uc874\uac10\uc774 \ubb34\ub108\uc9c0\uc9c0 \uc54a\ub3c4\ub85d \ub098\ub97c \uc9c0\ud0f1\ud560 \uc218 \uc788\ub294 \uae30\ub465\uc774 \ud544\uc694\ud558\ub2e4. (\ud55c \uac1c\uac00 \uc544\ub2cc \uc5ec\ub7ec \uac1c) "),(0,a.kt)("h3",{id:"\ub098\ub9cc\uc758-\ud559\uc2b5-\ubc29\ubc95-\ucc3e\uae30"},"\ub098\ub9cc\uc758 \ud559\uc2b5 \ubc29\ubc95 \ucc3e\uae30"),(0,a.kt)("p",null,"\ud68c\uc0ac \uc77c\uc744 \uc9c0\uc18d\uc801\uc73c\ub85c \ud55c\ub2e4\uba74 \ud68c\uc0ac \uc77c\uc758 \uc219\ub828\uc790\uac00 \ub418\uc9c0\ub9cc, \uac1c\ubc1c \uc804\ubb38\uac00\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc8fc\ub2c8\uc5b4 \uc77c\ub54c\ub294 \uc131\uacfc\uac00 \uc544\ub2cc \ud559\uc2b5\uc73c\ub85c!",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c0\uc18d\uc801\uc73c\ub85c \uc131\uc7a5\ud560 \uc218 \uc788\ub294 \uc0ac\ub78c\uc778\uc9c0? \uace0\ubbfc\ud558\uae30"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub3d9\uc6b1\ub2d8\uc774 \uadf8\ub3d9\uc548 \uc2dc\ub3c4\ud55c \ubc29\ubc95")),(0,a.kt)("p",null,"\uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8 \uc9c4\ud589\ud558\uae30 \u2192 A-Z \uad6c\ud604 \uacbd\ud5d8",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc45 \uc2a4\ud130\ub514 \u2192 \ub192\uc740 \uc644\uc8fc\uc728, \ud558\uc9c0\ub9cc \ub0b4\uac00 \ubc1c\ud45c\ud55c \uc8fc\uc81c\ub9cc \uae30\uc5b5\uc5d0 \ub0a8\ub294\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac15\uc758 \uc900\ube44 \u2192 100% \ub0b4\uc6a9 \uc2b5\ub4dd, \ub0ae\uc740 \uc2dc\uac04 \uac00\uc131\ube44, \uac15\uc758 \uc678\uc801\uc778 \ubd80\uac00\uc791\uc5c5",(0,a.kt)("br",{parentName:"p"}),"\n","\ube14\ub85c\uadf8 \u2192 \uc628\ub77c\uc778 \ubaa8\ub450\uac00 \ub9ac\ubdf0\uc5b4, \ub3d9\ub8cc\uc640 \uacf5\uc720 \uac00\ub2a5, \ud53c\ub4dc\ubc31\uc758 \ubd80\ub044\ub7ec\uc6c0 \ud83d\ude33 "),(0,a.kt)("p",null,"\uc2e4\ud328\ud558\uac70\ub098, \uc798\ubabb \uc801\uc5b4\ub3c4 \ub0a8\ub4e4\uc758 \uc2dc\uc120\ubcf4\ub2e8 \ub098 \uc790\uc2e0\uc758 \uc131\uc7a5\uc774 \uc911\uc694\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac00\ub2a5\ud558\uba74 \uc778\uc99d\ub418\uace0, \uc815\uc81c\ub41c \uc790\ub8cc\ub85c \uc2b5\ub4dd\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\uc5d0\uac8c \ub9de\ub294 \uac00\uc7a5 \ud6a8\uc728\uc774 \uc88b\uc740 \ud559\uc2b5 \ubc29\ubc95\uc73c\ub85c \ucc3e\uace0, \uc218\uc2dc\ub85c \uc810\uac80\ud558\uc5ec \ub354 \uc88b\uc740 \ubc29\ubc95\uc744 \ucc3e\uace0 \uc2dc\ub3c4\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c\uc6b4-\ud658\uacbd\uc744-\uc798-\ubc30\uc6b0\ub294-\ubc29\ubc95"},"\uc0c8\ub85c\uc6b4 \ud658\uacbd\uc744 \uc798 \ubc30\uc6b0\ub294 \ubc29\ubc95"),(0,a.kt)("p",null,"\uc2dc\uac04 > \ub3c8\uc774\uae30 \ub54c\ubb38\uc5d0 \uc2dc\uac04\uc744 \ub3c8\uc73c\ub85c \uad6c\ub9e4\ud558\uc790.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2e0\ub8b0\ud560\ub9cc\ud55c \ubd84\uaed8 \uc9c8\ubb38 \ub610\ub294 \ucf54\ub4dc \ub9ac\ubdf0\uac00 \uac00\ub2a5\ud55c \uac15\uc758\ub97c \uad6c\ub9e4\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc5b4\ub5a4 \ud559\uc2b5 \ubc29\uc2dd, \uc5b8\uc81c \uc9d1\uc911\uc774 \uc798 \ub418\ub294\uc9c0, \uc5b4\ub5a4 \ud658\uacbd\uc5d0\uc11c \uc9d1\uc911\uc774 \uc798 \ub418\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ud559\uc2b5-\uc8fc\uc81c"},"\ud559\uc2b5 \uc8fc\uc81c"),(0,a.kt)("p",null,"\ud68c\uc0ac \uc5c5\ubb34\uc5d0\uc11c \ub9cc\ub09c \ubb38\uc81c\ub97c \uc5f0\uad6c, \uc815\ub9ac, \ud574\uacb0\ud574\uc11c \ucee4\ubba4\ub2c8\ud2f0\uc5d0 \uacf5\uc720\ud558\uace0 \ud53c\ub4dc\ubc31\uc744 \ubc1b\ub294\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc8fc\ubcc0 \ub3d9\ub8cc\ub4e4\uc5d0\uac8c \uc778\uc815\ubc1b\ub294\uac8c \uc6b0\uc120\uc774\ub2e4. "),(0,a.kt)("h3",{id:"\uc0b0\ub9cc\ud568-\uad00\ub9ac\ud558\uae30"},"\uc0b0\ub9cc\ud568 \uad00\ub9ac\ud558\uae30"),(0,a.kt)("p",null,"\ucee8\ud14d\uc2a4\ud2b8 \uc2a4\uc704\uce6d\uc774 \uc790\uc8fc \uc77c\uc5b4\ub098\uba74 \uc0b0\ub9cc\ud574\uc9c0\uae30 \ub54c\ubb38\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub294 \ud658\uacbd\uc744 \uac00\uc838\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","ex) \uc9d1\uc911\uc774 \uc798 \ub418\ub294 \ud658\uacbd \uad6c\uc131\ud558\uae30, \ucd9c\uadfc \uc804 1~2\uc2dc\uac04 \uc9d1\uc911\ud558\uace0 \ucd9c\uadfc\ud558\uae30, \uc810\uc2ec \uc800\ub141 \uc0b0\ucc45\ud558\uae30, \uc8fc 2~3\ud68c \uc6b4\ub3d9\ud558\uae30"),(0,a.kt)("h3",{id:"\uac70\uc778\uc5d0-\uc5b4\uae68\uc704\uc5d0-\uc62c\ub77c\ud0c0\uae30"},"\uac70\uc778\uc5d0 \uc5b4\uae68\uc704\uc5d0 \uc62c\ub77c\ud0c0\uae30"),(0,a.kt)("p",null,"\ub6f0\uc5b4\ub09c \uc0ac\ub78c \uc606\uc5d0\uc11c \ubc30\uc6cc\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","C\ub808\ubca8, \ud14c\ud06c \ub9ac\ub4dc\uc640 \uac19\uc774 \uc77c\ud560 \uc218 \uc788\ub294 \uac83\uc740 \ud070 \uae30\ud68c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \ubc29\ubc95, \uc2e0\ub8b0 \uc790\uc0b0\uc744 \ud655\ubcf4\ud558\ub294 \ubc29\ubc95, \ubb38\ud654\ub97c \ub9cc\ub4e4\uc5b4\uac00\ub294 \ubc29\ubc95, \uacb0\uc815\uc758 \uae30\uc900\uacfc \uac19\uc740 \ubd80\ubd84\uc744 \ud559\uc2b5\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("h3",{id:"\ubcf4\uc0c1"},"\ubcf4\uc0c1"),(0,a.kt)("p",null,"\uc2dc\ub828 \ub4a4\uc5d0\ub294 \ud56d\uc0c1 \ubcf4\ubb3c\uc774 \uae30\ub2e4\ub9ac\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcf4\uc0c1\uc744 \ud1b5\ud574 \uafb8\uc900\ud568\uc744 \uc720\uc9c0\ud560 \uc218 \uc788\ub3c4\ub85d \ub9cc\ub4e4\uc5b4\ub77c. "),(0,a.kt)("h3",{id:"\ub0a8\uc744-\uc124\ub4dd\ud558\ub294-\ubc29\ubc95-\ubc30\uc6b0\uae30"},"\ub0a8\uc744 \uc124\ub4dd\ud558\ub294 \ubc29\ubc95 \ubc30\uc6b0\uae30"),(0,a.kt)("p",null,"\ud300\uc6d0\ub4e4\uc774 \ub9e4\ubc88 \ub0b4 \uc758\uacac\uc744 \ubc18\ub300\ud55c\ub2e4\uba74 \uc644\ubcbd\ud55c \ub17c\ub9ac\uac00 \uc911\uc694\ud55c\uac8c \uc544\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc5b4\ub5bb\uac8c \ud558\uba74 \uc2e0\ub8b0 \uc790\uc0b0\uc744 \ud655\ubcf4\ud560 \uc218 \uc788\ub294\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\ucee4\ubba4\ub2c8\ucf00\uc774\uc158, \ud611\uc5c5, \uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc5d0\uc11c \ubd80\uc871\ud568\uc774 \uc788\uc73c\uba74 \uc548\ub41c\ub2e4."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6b4e1191.964eb4c1.js b/assets/js/6b4e1191.964eb4c1.js new file mode 100644 index 000000000..8b26b18b0 --- /dev/null +++ b/assets/js/6b4e1191.964eb4c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[838],{88078:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>c,toc:()=>o});var n=r(85893),s=r(3905);const l={title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",slug:"/etc/healthful-growth",last_update:{date:"2023/04/19"},tags:["etc"]},i=void 0,c={id:"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",description:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 4\uc6d4 19\uc77c",source:"@site/docs/\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30.mdx",sourceDirName:"\uae30\ud0c0",slug:"/etc/healthful-growth",permalink:"/docs/etc/healthful-growth",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30.mdx",tags:[{label:"etc",permalink:"/docs/tags/etc"}],version:"current",lastUpdatedAt:1681862400,formattedLastUpdatedAt:"2023\ub144 4\uc6d4 19\uc77c",frontMatter:{title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",slug:"/etc/healthful-growth",last_update:{date:"2023/04/19"},tags:["etc"]},sidebar:"tutorialSidebar",previous:{title:"\ubb38\uc11c",permalink:"/docs/"},next:{title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",permalink:"/docs/etc/develop-with-spring"}},a={},o=[{value:"\uc790\uc874\uac10 \uae30\ub465 \ub9cc\ub4e4\uae30",id:"\uc790\uc874\uac10-\uae30\ub465-\ub9cc\ub4e4\uae30",level:3},{value:"\ub098\ub9cc\uc758 \ud559\uc2b5 \ubc29\ubc95 \ucc3e\uae30",id:"\ub098\ub9cc\uc758-\ud559\uc2b5-\ubc29\ubc95-\ucc3e\uae30",level:3},{value:"\uc0c8\ub85c\uc6b4 \ud658\uacbd\uc744 \uc798 \ubc30\uc6b0\ub294 \ubc29\ubc95",id:"\uc0c8\ub85c\uc6b4-\ud658\uacbd\uc744-\uc798-\ubc30\uc6b0\ub294-\ubc29\ubc95",level:3},{value:"\ud559\uc2b5 \uc8fc\uc81c",id:"\ud559\uc2b5-\uc8fc\uc81c",level:3},{value:"\uc0b0\ub9cc\ud568 \uad00\ub9ac\ud558\uae30",id:"\uc0b0\ub9cc\ud568-\uad00\ub9ac\ud558\uae30",level:3},{value:"\uac70\uc778\uc5d0 \uc5b4\uae68\uc704\uc5d0 \uc62c\ub77c\ud0c0\uae30",id:"\uac70\uc778\uc5d0-\uc5b4\uae68\uc704\uc5d0-\uc62c\ub77c\ud0c0\uae30",level:3},{value:"\ubcf4\uc0c1",id:"\ubcf4\uc0c1",level:3},{value:"\ub0a8\uc744 \uc124\ub4dd\ud558\ub294 \ubc29\ubc95 \ubc30\uc6b0\uae30",id:"\ub0a8\uc744-\uc124\ub4dd\ud558\ub294-\ubc29\ubc95-\ubc30\uc6b0\uae30",level:3}];function d(e){const t={br:"br",del:"del",h3:"h3",p:"p",strong:"strong",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 4\uc6d4 19\uc77c",(0,n.jsx)(t.br,{}),"\n","\uc774\ub3d9\uc6b1\ub2d8 \ud2b9\uac15"]}),"\n",(0,n.jsx)(t.h3,{id:"\uc790\uc874\uac10-\uae30\ub465-\ub9cc\ub4e4\uae30",children:"\uc790\uc874\uac10 \uae30\ub465 \ub9cc\ub4e4\uae30"}),"\n",(0,n.jsxs)(t.p,{children:["\ub6f0\uc5b4\ub09c \ub3d9\ub8cc, \uc0c8\ub85c\uc6b4 \ud658\uacbd \uadf8\ub9ac\uace0 \ud504\ub85c\uc81d\ud2b8\ub97c \uc2e4\ud328\ud558\uba74\uc11c \uc790\uc874\uac10\uc774 \ub5a8\uc5b4\uc9c8 \uc218 \uc788\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc790\uc874\uac10\uc774 \ubb34\ub108\uc9c0\uc9c0 \uc54a\ub3c4\ub85d \ub098\ub97c \uc9c0\ud0f1\ud560 \uc218 \uc788\ub294 \uae30\ub465\uc774 \ud544\uc694\ud558\ub2e4. (\ud55c \uac1c\uac00 \uc544\ub2cc \uc5ec\ub7ec \uac1c)"]}),"\n",(0,n.jsx)(t.h3,{id:"\ub098\ub9cc\uc758-\ud559\uc2b5-\ubc29\ubc95-\ucc3e\uae30",children:"\ub098\ub9cc\uc758 \ud559\uc2b5 \ubc29\ubc95 \ucc3e\uae30"}),"\n",(0,n.jsxs)(t.p,{children:["\ud68c\uc0ac \uc77c\uc744 \uc9c0\uc18d\uc801\uc73c\ub85c \ud55c\ub2e4\uba74 \ud68c\uc0ac \uc77c\uc758 \uc219\ub828\uc790\uac00 \ub418\uc9c0\ub9cc, \uac1c\ubc1c \uc804\ubb38\uac00\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc8fc\ub2c8\uc5b4 \uc77c\ub54c\ub294 \uc131\uacfc\uac00 \uc544\ub2cc \ud559\uc2b5\uc73c\ub85c!",(0,n.jsx)(t.br,{}),"\n","\uc9c0\uc18d\uc801\uc73c\ub85c \uc131\uc7a5\ud560 \uc218 \uc788\ub294 \uc0ac\ub78c\uc778\uc9c0? \uace0\ubbfc\ud558\uae30"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.strong,{children:"\ub3d9\uc6b1\ub2d8\uc774 \uadf8\ub3d9\uc548 \uc2dc\ub3c4\ud55c \ubc29\ubc95"})}),"\n",(0,n.jsxs)(t.p,{children:["\uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8 \uc9c4\ud589\ud558\uae30 \u2192 A-Z \uad6c\ud604 \uacbd\ud5d8",(0,n.jsx)(t.br,{}),"\n","\ucc45 \uc2a4\ud130\ub514 \u2192 \ub192\uc740 \uc644\uc8fc\uc728, \ud558\uc9c0\ub9cc \ub0b4\uac00 \ubc1c\ud45c\ud55c \uc8fc\uc81c\ub9cc \uae30\uc5b5\uc5d0 \ub0a8\ub294\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uac15\uc758 \uc900\ube44 \u2192 100% \ub0b4\uc6a9 \uc2b5\ub4dd, \ub0ae\uc740 \uc2dc\uac04 \uac00\uc131\ube44, \uac15\uc758 \uc678\uc801\uc778 \ubd80\uac00\uc791\uc5c5",(0,n.jsx)(t.br,{}),"\n","\ube14\ub85c\uadf8 \u2192 \uc628\ub77c\uc778 \ubaa8\ub450\uac00 \ub9ac\ubdf0\uc5b4, \ub3d9\ub8cc\uc640 \uacf5\uc720 \uac00\ub2a5, \ud53c\ub4dc\ubc31\uc758 \ubd80\ub044\ub7ec\uc6c0 \ud83d\ude33"]}),"\n",(0,n.jsxs)(t.p,{children:["\uc2e4\ud328\ud558\uac70\ub098, \uc798\ubabb \uc801\uc5b4\ub3c4 \ub0a8\ub4e4\uc758 \uc2dc\uc120\ubcf4\ub2e8 \ub098 \uc790\uc2e0\uc758 \uc131\uc7a5\uc774 \uc911\uc694\ud558\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uac00\ub2a5\ud558\uba74 \uc778\uc99d\ub418\uace0, \uc815\uc81c\ub41c \uc790\ub8cc\ub85c \uc2b5\ub4dd\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub098\uc5d0\uac8c \ub9de\ub294 \uac00\uc7a5 \ud6a8\uc728\uc774 \uc88b\uc740 \ud559\uc2b5 \ubc29\ubc95\uc73c\ub85c \ucc3e\uace0, \uc218\uc2dc\ub85c \uc810\uac80\ud558\uc5ec \ub354 \uc88b\uc740 \ubc29\ubc95\uc744 \ucc3e\uace0 \uc2dc\ub3c4\ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\uc0c8\ub85c\uc6b4-\ud658\uacbd\uc744-\uc798-\ubc30\uc6b0\ub294-\ubc29\ubc95",children:"\uc0c8\ub85c\uc6b4 \ud658\uacbd\uc744 \uc798 \ubc30\uc6b0\ub294 \ubc29\ubc95"}),"\n",(0,n.jsxs)(t.p,{children:["\uc2dc\uac04 > \ub3c8\uc774\uae30 \ub54c\ubb38\uc5d0 \uc2dc\uac04\uc744 \ub3c8\uc73c\ub85c \uad6c\ub9e4\ud558\uc790.",(0,n.jsx)(t.br,{}),"\n","\uc2e0\ub8b0\ud560\ub9cc\ud55c \ubd84\uaed8 \uc9c8\ubb38 \ub610\ub294 \ucf54\ub4dc \ub9ac\ubdf0\uac00 \uac00\ub2a5\ud55c \uac15\uc758\ub97c \uad6c\ub9e4\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc5b4\ub5a4 \ud559\uc2b5 \ubc29\uc2dd, \uc5b8\uc81c \uc9d1\uc911\uc774 \uc798 \ub418\ub294\uc9c0, \uc5b4\ub5a4 \ud658\uacbd\uc5d0\uc11c \uc9d1\uc911\uc774 \uc798 \ub418\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ud559\uc2b5-\uc8fc\uc81c",children:"\ud559\uc2b5 \uc8fc\uc81c"}),"\n",(0,n.jsxs)(t.p,{children:["\ud68c\uc0ac \uc5c5\ubb34\uc5d0\uc11c \ub9cc\ub09c \ubb38\uc81c\ub97c \uc5f0\uad6c, \uc815\ub9ac, \ud574\uacb0\ud574\uc11c \ucee4\ubba4\ub2c8\ud2f0\uc5d0 \uacf5\uc720\ud558\uace0 \ud53c\ub4dc\ubc31\uc744 \ubc1b\ub294\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc8fc\ubcc0 \ub3d9\ub8cc\ub4e4\uc5d0\uac8c \uc778\uc815\ubc1b\ub294\uac8c \uc6b0\uc120\uc774\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\uc0b0\ub9cc\ud568-\uad00\ub9ac\ud558\uae30",children:"\uc0b0\ub9cc\ud568 \uad00\ub9ac\ud558\uae30"}),"\n",(0,n.jsxs)(t.p,{children:["\ucee8\ud14d\uc2a4\ud2b8 \uc2a4\uc704\uce6d\uc774 \uc790\uc8fc \uc77c\uc5b4\ub098\uba74 \uc0b0\ub9cc\ud574\uc9c0\uae30 \ub54c\ubb38\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub294 \ud658\uacbd\uc744 \uac00\uc838\uc57c \ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","ex) \uc9d1\uc911\uc774 \uc798 \ub418\ub294 \ud658\uacbd \uad6c\uc131\ud558\uae30, \ucd9c\uadfc \uc804 1",(0,n.jsx)(t.del,{children:"2\uc2dc\uac04 \uc9d1\uc911\ud558\uace0 \ucd9c\uadfc\ud558\uae30, \uc810\uc2ec \uc800\ub141 \uc0b0\ucc45\ud558\uae30, \uc8fc 2"}),"3\ud68c \uc6b4\ub3d9\ud558\uae30"]}),"\n",(0,n.jsx)(t.h3,{id:"\uac70\uc778\uc5d0-\uc5b4\uae68\uc704\uc5d0-\uc62c\ub77c\ud0c0\uae30",children:"\uac70\uc778\uc5d0 \uc5b4\uae68\uc704\uc5d0 \uc62c\ub77c\ud0c0\uae30"}),"\n",(0,n.jsxs)(t.p,{children:["\ub6f0\uc5b4\ub09c \uc0ac\ub78c \uc606\uc5d0\uc11c \ubc30\uc6cc\uc57c \ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","C\ub808\ubca8, \ud14c\ud06c \ub9ac\ub4dc\uc640 \uac19\uc774 \uc77c\ud560 \uc218 \uc788\ub294 \uac83\uc740 \ud070 \uae30\ud68c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \ubc29\ubc95, \uc2e0\ub8b0 \uc790\uc0b0\uc744 \ud655\ubcf4\ud558\ub294 \ubc29\ubc95, \ubb38\ud654\ub97c \ub9cc\ub4e4\uc5b4\uac00\ub294 \ubc29\ubc95, \uacb0\uc815\uc758 \uae30\uc900\uacfc \uac19\uc740 \ubd80\ubd84\uc744 \ud559\uc2b5\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ubcf4\uc0c1",children:"\ubcf4\uc0c1"}),"\n",(0,n.jsxs)(t.p,{children:["\uc2dc\ub828 \ub4a4\uc5d0\ub294 \ud56d\uc0c1 \ubcf4\ubb3c\uc774 \uae30\ub2e4\ub9ac\uace0 \uc788\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ubcf4\uc0c1\uc744 \ud1b5\ud574 \uafb8\uc900\ud568\uc744 \uc720\uc9c0\ud560 \uc218 \uc788\ub3c4\ub85d \ub9cc\ub4e4\uc5b4\ub77c."]}),"\n",(0,n.jsx)(t.h3,{id:"\ub0a8\uc744-\uc124\ub4dd\ud558\ub294-\ubc29\ubc95-\ubc30\uc6b0\uae30",children:"\ub0a8\uc744 \uc124\ub4dd\ud558\ub294 \ubc29\ubc95 \ubc30\uc6b0\uae30"}),"\n",(0,n.jsxs)(t.p,{children:["\ud300\uc6d0\ub4e4\uc774 \ub9e4\ubc88 \ub0b4 \uc758\uacac\uc744 \ubc18\ub300\ud55c\ub2e4\uba74 \uc644\ubcbd\ud55c \ub17c\ub9ac\uac00 \uc911\uc694\ud55c\uac8c \uc544\ub2c8\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc5b4\ub5bb\uac8c \ud558\uba74 \uc2e0\ub8b0 \uc790\uc0b0\uc744 \ud655\ubcf4\ud560 \uc218 \uc788\ub294\uac00?",(0,n.jsx)(t.br,{}),"\n","\ucee4\ubba4\ub2c8\ucf00\uc774\uc158, \ud611\uc5c5, \uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc5d0\uc11c \ubd80\uc871\ud568\uc774 \uc788\uc73c\uba74 \uc548\ub41c\ub2e4."]})]})}function p(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>o});var n=r(67294);function s(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach((function(t){s(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,s=function(e,t){if(null==e)return{};var r,n,s={},l=Object.keys(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||(s[r]=e[r]);return s}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var a=n.createContext({}),o=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,s=e.mdxType,l=e.originalType,a=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=o(r),h=s,j=u["".concat(a,".").concat(h)]||u[h]||d[h]||l;return r?n.createElement(j,i(i({ref:t},p),{},{components:r})):n.createElement(j,i({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/6b54f6a4.2c404bfc.js b/assets/js/6b54f6a4.2c404bfc.js new file mode 100644 index 000000000..1b24f4739 --- /dev/null +++ b/assets/js/6b54f6a4.2c404bfc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4558],{57211:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>c,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=t(85893),a=t(3905),i=t(74866),l=t(85162);const o={title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",slug:"custom-jdbc-template",tags:["JDBC","Java"]},c=void 0,s={permalink:"/custom-jdbc-template",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",source:"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",description:"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.",date:"2023-04-02T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 2\uc77c",tags:[{label:"JDBC",permalink:"/tags/jdbc"},{label:"Java",permalink:"/tags/java"}],readingTime:9.025,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",slug:"custom-jdbc-template",tags:["JDBC","Java"]},unlisted:!1,prevItem:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",permalink:"/java-class-file"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",permalink:"/woowacourse-level1-retrospective"}},u={authorsImageUrls:[]},p=[{value:"\uae30\uc874 \ucf54\ub4dc",id:"\uae30\uc874-\ucf54\ub4dc",level:3},{value:"SELECT, DELETE \uc911\ubcf5 \uc81c\uac70",id:"select-delete-\uc911\ubcf5-\uc81c\uac70",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---1-\ucf5c\ubc31\uc744-\uc704\ud55c-\uc778\ud130\ud398\uc774\uc2a4-\uc815\uc758",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---2-\ub2e8\uac74-\uc870\ud68c",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---3-\ub2e4\uac74-\uc870\ud68c",level:3},{value:"\uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30",id:"\uc81c\ub124\ub9ad-\uc0ac\uc6a9\ud558\uae30",level:3},{value:"\uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30",id:"\uba54\uc11c\ub4dc-\ubd84\ub9ac\ud55c-\ubd80\ubd84-\ud074\ub798\uc2a4\ub85c-\ubd84\ub9ac\ud558\uae30--optional-\uc0ac\uc6a9\ud558\uae30",level:3}];function d(e){const n={admonition:"admonition",br:"br",code:"code",h3:"h3",mermaid:"mermaid",p:"p",pre:"pre",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.p,{children:["\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774 \ub54c JDBC\ub97c \uc0ac\uc6a9\ud560 \ub54c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 \ucee4\ub125\uc158\uc744 \uc5bb\uace0, try-with-resource\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc774 \ubc18\ubcf5\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc774\uc6a9\ud558\uc5ec \ub098\ub9cc\uc758 JdbcTemplate\uc744 \ub9cc\ub4e4\uc5b4\ubcf4\uc558\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uae30\uc874-\ucf54\ub4dc",children:"\uae30\uc874 \ucf54\ub4dc"}),"\n",(0,r.jsxs)(i.Z,{children:[(0,r.jsx)(l.Z,{value:"User",label:"User",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public class User {\n private final int id;\n private final String name;\n\n public User(final int id, final String name) {\n this.id = id;\n this.name = name;\n }\n\n public int getId() {\n return id;\n }\n\n public String getName() {\n return name;\n }\n}\n"})})}),(0,r.jsx)(l.Z,{value:"UserDao",label:"UserDao",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public class UserDao {\n private final ConnectionPool connectionPool;\n\n public UserDao(final ConnectionPool connectionPool) {\n this.connectionPool = connectionPool;\n }\n\n public void insert(final String name) {\n final Connection connection = connectionPool.getConnection();\n final String query = "INSERT INTO User (name) VALUES (?)";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setString(1, name);\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public void delete(final int userId) {\n final Connection connection = connectionPool.getConnection();\n final String query = "DELETE FROM user WHERE id = ?";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setInt(1, userId);\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public User findById(final int userId) {\n final Connection connection = connectionPool.getConnection();\n final String query = "SELECT * FROM user WHERE id = ?";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setInt(1, userId);\n final ResultSet resultSet = preparedStatement.executeQuery();\n if (resultSet.next()) {\n return new User(\n resultSet.getInt("id"),\n resultSet.getString("name")\n );\n }\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n return null;\n }\n\n public List<User> findAll() {\n final Connection connection = connectionPool.getConnection();\n final String query = "SELECT * FROM user";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n final ResultSet resultSet = preparedStatement.executeQuery();\n final List<User> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(new User(\n resultSet.getInt("id"),\n resultSet.getString("name")\n ));\n }\n return result;\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n}\n'})})}),(0,r.jsx)(l.Z,{value:"ConnectionPool",label:"ConnectionPool",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public class ConnectionPool {\n private static final String SERVER = "localhost:13306";\n private static final String DATABASE = "chess";\n private static final String OPTION = "?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";\n private static final String URL = "jdbc:mysql://" + SERVER + "/" + DATABASE + OPTION;\n private static final String USERNAME = "root";\n private static final String PASSWORD = "root";\n\n private final AtomicInteger index = new AtomicInteger();\n private final List<Connection> connections;\n\n public ConnectionPool(final int connectionCount) {\n connections = generateConnections(connectionCount);\n }\n\n private List<Connection> generateConnections(final int connectionCount) {\n return Stream.generate(this::generateConnection)\n .limit(connectionCount)\n .collect(toList());\n }\n\n private Connection generateConnection() {\n try {\n return DriverManager.getConnection(URL, USERNAME, PASSWORD);\n } catch (SQLException e) {\n throw new IllegalStateException("\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.");\n }\n }\n\n public Connection getConnection() {\n int currentIndex = index.getAndIncrement();\n return connections.get(currentIndex % connections.size());\n }\n}\n'})})})]}),"\n",(0,r.jsx)(n.h3,{id:"select-delete-\uc911\ubcf5-\uc81c\uac70",children:"SELECT, DELETE \uc911\ubcf5 \uc81c\uac70"}),"\n",(0,r.jsxs)(n.p,{children:["\ubcc0\ud558\uc9c0 \uc54a\ub294 \ubd80\ubd84: try-with-resource, preparedStatement\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84, executeUpdate\ub85c \uc2e4\ud589 \ub4f1\ub4f1",(0,r.jsx)(n.br,{}),"\n","\ubcc0\ud558\ub294 \ubd80\ubd84: SQL Query, \ub9e4\uac1c\ubcc0\uc218"]}),"\n",(0,r.jsx)(n.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\ub294 \ubd80\ubd84\uc744 \ubd84\ub9ac\ud558\uace0 \uac00\ubcc0\uc778\uc218\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 SELECT\uc640 DELETE\uc758 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public void insert(final String name) {\n final String query = "INSERT INTO User (name) VALUES (?)";\n executeUpdate(query, name);\n}\n\npublic void delete(final int userId) {\n final String query = "DELETE FROM user WHERE user_id = ?";\n executeUpdate(query, userId);\n}\n\nprivate void executeUpdate(final String query, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---1-\ucf5c\ubc31\uc744-\uc704\ud55c-\uc778\ud130\ud398\uc774\uc2a4-\uc815\uc758",children:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758"}),"\n",(0,r.jsxs)(n.p,{children:["\uc870\ud68c\ub294 INSERT, DELETE\uc640 \ub2ec\ub9ac \uac12\uc744 \ubc18\ud658\ubc1b\uc544\uc57c \ud558\uae30 \ub54c\ubb38\uc5d0 \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774 \ub54c \ucf5c\ubc31\uc774\ub77c\ub294 \uac83\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsxs)(n.admonition,{title:"\ucf5c\ubc31(Callback)",type:"note",children:[(0,r.jsxs)(n.p,{children:["\ud504\ub85c\uadf8\ub798\ubc0d\uc5d0\uc11c \ucf5c\ubc31\uc740 \ub2e4\ub978 \ucf54\ub4dc\uc758 \uc778\uc218\ub85c \ub118\uaca8\uc8fc\ub294 \uc2e4\ud589 \uac00\ub2a5\ud55c \ucf54\ub4dc\ub97c \ub73b\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc790\ubc14\uc5d0\uc11c\ub294 \ub78c\ub2e4\ub098 \uc775\uba85 \ud074\ub798\uc2a4\ub97c \ub118\uaca8\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),(0,r.jsx)(n.mermaid,{value:"flowchart LR\n \ud074\ub77c\uc774\uc5b8\ud2b8 -- \ucf5c\ubc31\uc804\ub2ec --\x3e \uba54\uc11c\ub4dc\n \uba54\uc11c\ub4dc -- \ub0b4\ubd80\ud638\ucd9c --\x3e \uc804\ub2ec\ubc1b\uc740\ucf5c\ubc31"})]}),"\n",(0,r.jsxs)(n.p,{children:["\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uc870\ud68c\ud558\uace0, \ud574\ub2f9 \uac12\uc744 \uac1d\uccb4\ub85c \ub9e4\ud551\ud558\uc5ec \uac12\uc744 \ubc18\ud658\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","executeQuery\ub85c \uc870\ud68c\ud55c \uac12\uc740 ResultSet \uc548\uc5d0 \ub4e4\uc5b4\uac00\uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ub97c \uc6d0\ud558\ub294 \ud0c0\uc785\uc758 \uac12\uc73c\ub85c \ubcc0\ud658\ud574\uc57c\ud558\ub2c8 \uc77c\ub2e8 \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@FunctionalInterface\npublic interface RowMapper {\n User mapRow(final ResultSet resultSet) throws SQLException;\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---2-\ub2e8\uac74-\uc870\ud68c",children:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c"}),"\n",(0,r.jsxs)(n.p,{children:["\uc704\uc5d0\uc11c \uc815\uc758\ud55c RowMapper\ub97c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc5b4\ub5bb\uac8c \uc0ac\uc6a9\ud574\uc57c \ud560\uae4c?",(0,r.jsx)(n.br,{}),"\n","\uc544\ub798\uc640 \uac19\uc774 SQL \ucffc\ub9ac, RowMapper, \ud30c\ub77c\ubbf8\ud130\ub97c \ubd84\ub9ac\ud55c \uba54\uc11c\ub4dc\uc5d0 \ub118\uaca8\uc8fc\uace0 \ucffc\ub9ac \uc2e4\ud589 \ud6c4 \ub9e4\ud551\ud55c \uac12\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public User findById(final int userId) {\n final String query = "SELECT * FROM user WHERE id = ?";\n return queryForSingleResult(query, resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n }, userId);\n}\n\nprivate User queryForSingleResult(\n final String query,\n final RowMapper rowMapper,\n final Object... parameters\n) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n if (resultSet.next()) {\n return rowMapper.mapRow(resultSet);\n }\n return null;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n\nprivate ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---3-\ub2e4\uac74-\uc870\ud68c",children:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c"}),"\n",(0,r.jsx)(n.p,{children:"\ub2e8\uac74 \uc870\ud68c\uc640 \uc720\uc0ac\ud558\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public List<User> findAll() {\n final String query = "SELECT * FROM user";\n return query(query, resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n });\n}\n\nprivate List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n final List<User> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(rowMapper.mapRow(resultSet));\n }\n return result;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n\nprivate ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"\uc81c\ub124\ub9ad-\uc0ac\uc6a9\ud558\uae30",children:"\uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30"}),"\n",(0,r.jsxs)(n.p,{children:["\uc704\uc758 \ucf54\ub4dc\ub294 User\ub97c \uc870\ud68c\ud560 \ub54c\ub9cc \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc544\ub798\uc640 \uac19\uc774 \uc81c\ub124\ub9ad\uc744 \uc801\uc6a9\ud558\uc5ec \ub2e4\ub978 Dao\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\ud558\ub3c4\ub85d \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@FunctionalInterface\npublic interface RowMapper<T> {\n T mapRow(final ResultSet resultSet) throws SQLException;\n}\n\nprivate <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\nprivate <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\uba54\uc11c\ub4dc-\ubd84\ub9ac\ud55c-\ubd80\ubd84-\ud074\ub798\uc2a4\ub85c-\ubd84\ub9ac\ud558\uae30--optional-\uc0ac\uc6a9\ud558\uae30",children:"\uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30"}),"\n",(0,r.jsxs)(n.p,{children:["\uba54\uc11c\ub4dc\ub85c \ubd84\ub9ac\ud55c \ubd80\ubd84\uc744 JdbcTemplate\uc774\ub77c\ub294 \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uc5b4 \uc62e\uae34\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub610\ud55c null\uc744 \ubc18\ud658\ud558\uae30 \ubcf4\ub2e8 Optional\ub85c \uac10\uc2f8\uc11c \ubc18\ud658\ud558\ub3c4\ub85d \ubcc0\uacbd\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd5c\uc885\uc801\uc73c\ub85c \uc544\ub798\uc640 \uac19\uc740 \ucf54\ub4dc\uac00 \uc644\uc131\ub41c\ub2e4."]}),"\n",(0,r.jsxs)(i.Z,{children:[(0,r.jsx)(l.Z,{value:"UserDao",label:"UserDao",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public class UserDao {\n private final RowMapper<User> rowMapper = resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n };\n private final JdbcTemplate jdbcTemplate;\n\n public UserDao(final JdbcTemplate jdbcTemplate) {\n this.jdbcTemplate = jdbcTemplate;\n }\n\n public void insert(final String name) {\n final String query = "INSERT INTO User (name) VALUES (?)";\n jdbcTemplate.executeUpdate(query, name);\n }\n\n public void delete(final int userId) {\n final String query = "DELETE FROM user WHERE user_id = ?";\n jdbcTemplate.executeUpdate(query, userId);\n }\n\n public Optional<User> findById(final int userId) {\n final String query = "SELECT * FROM user WHERE id = ?";\n return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);\n }\n\n public List<User> findAll() {\n final String query = "SELECT * FROM user";\n return jdbcTemplate.query(query, rowMapper);\n }\n}\n'})})}),(0,r.jsx)(l.Z,{value:"JdbcTemplate",label:"JdbcTemplate",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public class JdbcTemplate {\n private final ConnectionPool connectionPool;\n\n public JdbcTemplate(final ConnectionPool connectionPool) {\n this.connectionPool = connectionPool;\n }\n\n public void executeUpdate(final String query, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public <T> Optional<T> queryForSingleResult(\n final String query,\n final RowMapper<T> rowMapper,\n final Object... parameters\n ) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n if (resultSet.next()) {\n return Optional.of(rowMapper.mapRow(resultSet));\n }\n return Optional.empty();\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n private ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters\n ) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n }\n\n public <T> List<T> query(\n final String query,\n final RowMapper<T> rowMapper,\n final Object... parameters\n ) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n final List<T> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(rowMapper.mapRow(resultSet));\n }\n return result;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n}\n"})})})]})]})}function m(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>s});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function l(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?i(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=r.createContext({}),s=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},p=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=s(t),m=a,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||i;return t?r.createElement(f,l(l({ref:n},p),{},{components:t})):r.createElement(f,l({ref:n},p))}));p.displayName="MDXCreateElement"},85162:(e,n,t)=>{t.d(n,{Z:()=>l});t(67294);var r=t(86010);const a={tabItem:"tabItem_Ymn6"};var i=t(85893);function l(e){let{children:n,hidden:t,className:l}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,r.Z)(a.tabItem,l),hidden:t,children:n})}},74866:(e,n,t)=>{t.d(n,{Z:()=>j});var r=t(67294),a=t(86010),i=t(12466),l=t(16550),o=t(20469),c=t(91980),s=t(67392),u=t(50012);function p(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function d(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return p(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:a}}=e;return{value:n,label:t,attributes:r,default:a}}))}(t);return function(e){const n=(0,s.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function m(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function f(e){let{queryString:n=!1,groupId:t}=e;const a=(0,l.k6)(),i=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,c._X)(i),(0,r.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function S(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=d(e),[l,c]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!m({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:i}))),[s,p]=f({queryString:t,groupId:a}),[S,g]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,u.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),b=(()=>{const e=s??S;return m({value:e,tabValues:i})?e:null})();(0,o.Z)((()=>{b&&c(b)}),[b]);return{selectedValue:l,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);c(e),p(e),g(e)}),[p,g,i]),tabValues:i}}var g=t(72389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var h=t(85893);function x(e){let{className:n,block:t,selectedValue:r,selectValue:l,tabValues:o}=e;const c=[],{blockElementScrollPositionUntilNextRender:s}=(0,i.o5)(),u=e=>{const n=e.currentTarget,t=c.indexOf(n),a=o[t].value;a!==r&&(s(n),l(a))},p=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}n?.focus()};return(0,h.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.Z)("tabs",{"tabs--block":t},n),children:o.map((e=>{let{value:n,label:t,attributes:i}=e;return(0,h.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>c.push(e),onKeyDown:p,onClick:u,...i,className:(0,a.Z)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function y(e){let{lazy:n,children:t,selectedValue:a}=e;const i=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,h.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a})))})}function v(e){const n=S(e);return(0,h.jsxs)("div",{className:(0,a.Z)("tabs-container",b.tabList),children:[(0,h.jsx)(x,{...e,...n}),(0,h.jsx)(y,{...e,...n})]})}function j(e){const n=(0,g.Z)();return(0,h.jsx)(v,{...e,children:p(e.children)},String(n))}}}]); \ No newline at end of file diff --git a/assets/js/6b54f6a4.68a68fa1.js b/assets/js/6b54f6a4.68a68fa1.js deleted file mode 100644 index 0ef563774..000000000 --- a/assets/js/6b54f6a4.68a68fa1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4558],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>d});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?l(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):l(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},l=Object.keys(e);for(r=0;r<l.length;r++)t=l[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)t=l[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var u=r.createContext({}),c=function(e){var n=r.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return r.createElement(u.Provider,{value:n},e.children)},s={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,l=e.originalType,u=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=c(t),d=a,f=m["".concat(u,".").concat(d)]||m[d]||s[d]||l;return t?r.createElement(f,i(i({ref:n},p),{},{components:t})):r.createElement(f,i({ref:n},p))}));function d(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var l=t.length,i=new Array(l);i[0]=m;var o={};for(var u in n)hasOwnProperty.call(n,u)&&(o[u]=n[u]);o.originalType=e,o.mdxType="string"==typeof e?e:a,i[1]=o;for(var c=2;c<l;c++)i[c]=t[c];return r.createElement.apply(null,i)}return r.createElement.apply(null,t)}m.displayName="MDXCreateElement"},85162:(e,n,t)=>{t.d(n,{Z:()=>i});var r=t(67294),a=t(86010);const l="tabItem_Ymn6";function i(e){let{children:n,hidden:t,className:i}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(l,i),hidden:t},n)}},74866:(e,n,t)=>{t.d(n,{Z:()=>w});var r=t(87462),a=t(67294),l=t(86010),i=t(12466),o=t(16550),u=t(91980),c=t(67392),p=t(50012);function s(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:a}}=e;return{value:n,label:t,attributes:r,default:a}}))}function m(e){const{values:n,children:t}=e;return(0,a.useMemo)((()=>{const e=n??s(t);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function d(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function f(e){let{queryString:n=!1,groupId:t}=e;const r=(0,o.k6)(),l=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,u._X)(l),(0,a.useCallback)((e=>{if(!l)return;const n=new URLSearchParams(r.location.search);n.set(l,e),r.replace({...r.location,search:n.toString()})}),[l,r])]}function g(e){const{defaultValue:n,queryString:t=!1,groupId:r}=e,l=m(e),[i,o]=(0,a.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!d({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:l}))),[u,c]=f({queryString:t,groupId:r}),[s,g]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,l]=(0,p.Nk)(t);return[r,(0,a.useCallback)((e=>{t&&l.set(e)}),[t,l])]}({groupId:r}),S=(()=>{const e=u??s;return d({value:e,tabValues:l})?e:null})();(0,a.useLayoutEffect)((()=>{S&&o(S)}),[S]);return{selectedValue:i,selectValue:(0,a.useCallback)((e=>{if(!d({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);o(e),c(e),g(e)}),[c,g,l]),tabValues:l}}var S=t(72389);const b="tabList__CuJ",y="tabItem_LNqP";function v(e){let{className:n,block:t,selectedValue:o,selectValue:u,tabValues:c}=e;const p=[],{blockElementScrollPositionUntilNextRender:s}=(0,i.o5)(),m=e=>{const n=e.currentTarget,t=p.indexOf(n),r=c[t].value;r!==o&&(s(n),u(r))},d=e=>{let n=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":t},n)},c.map((e=>{let{value:n,label:t,attributes:i}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:o===n?0:-1,"aria-selected":o===n,key:n,ref:e=>p.push(e),onKeyDown:d,onClick:m},i,{className:(0,l.Z)("tabs__item",y,i?.className,{"tabs__item--active":o===n})}),t??n)})))}function E(e){let{lazy:n,children:t,selectedValue:r}=e;const l=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=l.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},l.map(((e,n)=>(0,a.cloneElement)(e,{key:n,hidden:e.props.value!==r}))))}function h(e){const n=g(e);return a.createElement("div",{className:(0,l.Z)("tabs-container",b)},a.createElement(v,(0,r.Z)({},e,n)),a.createElement(E,(0,r.Z)({},e,n)))}function w(e){const n=(0,S.Z)();return a.createElement(h,(0,r.Z)({key:String(n)},e))}},23826:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>u,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=t(87462),a=(t(67294),t(3905)),l=t(74866),i=t(85162);const o={title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",slug:"custom-jdbc-template",tags:["JDBC","Java"]},u=void 0,c={permalink:"/custom-jdbc-template",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",source:"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",description:"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.",date:"2023-04-02T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 2\uc77c",tags:[{label:"JDBC",permalink:"/tags/jdbc"},{label:"Java",permalink:"/tags/java"}],readingTime:9.025,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",slug:"custom-jdbc-template",tags:["JDBC","Java"]},prevItem:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",permalink:"/java-class-file"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",permalink:"/woowacourse-level1-retrospective"}},p={authorsImageUrls:[]},s=[{value:"\uae30\uc874 \ucf54\ub4dc",id:"\uae30\uc874-\ucf54\ub4dc",level:3},{value:"SELECT, DELETE \uc911\ubcf5 \uc81c\uac70",id:"select-delete-\uc911\ubcf5-\uc81c\uac70",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---1-\ucf5c\ubc31\uc744-\uc704\ud55c-\uc778\ud130\ud398\uc774\uc2a4-\uc815\uc758",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---2-\ub2e8\uac74-\uc870\ud68c",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---3-\ub2e4\uac74-\uc870\ud68c",level:3},{value:"\uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30",id:"\uc81c\ub124\ub9ad-\uc0ac\uc6a9\ud558\uae30",level:3},{value:"\uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30",id:"\uba54\uc11c\ub4dc-\ubd84\ub9ac\ud55c-\ubd80\ubd84-\ud074\ub798\uc2a4\ub85c-\ubd84\ub9ac\ud558\uae30--optional-\uc0ac\uc6a9\ud558\uae30",level:3}],m={toc:s};function d(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,r.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c JDBC\ub97c \uc0ac\uc6a9\ud560 \ub54c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 \ucee4\ub125\uc158\uc744 \uc5bb\uace0, try-with-resource\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc774 \ubc18\ubcf5\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc774\uc6a9\ud558\uc5ec \ub098\ub9cc\uc758 JdbcTemplate\uc744 \ub9cc\ub4e4\uc5b4\ubcf4\uc558\ub2e4. "),(0,a.kt)("h3",{id:"\uae30\uc874-\ucf54\ub4dc"},"\uae30\uc874 \ucf54\ub4dc"),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(i.Z,{value:"User",label:"User",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public class User {\n private final int id;\n private final String name;\n\n public User(final int id, final String name) {\n this.id = id;\n this.name = name;\n }\n\n public int getId() {\n return id;\n }\n\n public String getName() {\n return name;\n }\n}\n"))),(0,a.kt)(i.Z,{value:"UserDao",label:"UserDao",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public class UserDao {\n private final ConnectionPool connectionPool;\n\n public UserDao(final ConnectionPool connectionPool) {\n this.connectionPool = connectionPool;\n }\n\n public void insert(final String name) {\n final Connection connection = connectionPool.getConnection();\n final String query = "INSERT INTO User (name) VALUES (?)";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setString(1, name);\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public void delete(final int userId) {\n final Connection connection = connectionPool.getConnection();\n final String query = "DELETE FROM user WHERE id = ?";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setInt(1, userId);\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public User findById(final int userId) {\n final Connection connection = connectionPool.getConnection();\n final String query = "SELECT * FROM user WHERE id = ?";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setInt(1, userId);\n final ResultSet resultSet = preparedStatement.executeQuery();\n if (resultSet.next()) {\n return new User(\n resultSet.getInt("id"),\n resultSet.getString("name")\n );\n }\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n return null;\n }\n\n public List<User> findAll() {\n final Connection connection = connectionPool.getConnection();\n final String query = "SELECT * FROM user";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n final ResultSet resultSet = preparedStatement.executeQuery();\n final List<User> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(new User(\n resultSet.getInt("id"),\n resultSet.getString("name")\n ));\n }\n return result;\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n}\n'))),(0,a.kt)(i.Z,{value:"ConnectionPool",label:"ConnectionPool",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public class ConnectionPool {\n private static final String SERVER = "localhost:13306";\n private static final String DATABASE = "chess";\n private static final String OPTION = "?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";\n private static final String URL = "jdbc:mysql://" + SERVER + "/" + DATABASE + OPTION;\n private static final String USERNAME = "root";\n private static final String PASSWORD = "root";\n\n private final AtomicInteger index = new AtomicInteger();\n private final List<Connection> connections;\n\n public ConnectionPool(final int connectionCount) {\n connections = generateConnections(connectionCount);\n }\n\n private List<Connection> generateConnections(final int connectionCount) {\n return Stream.generate(this::generateConnection)\n .limit(connectionCount)\n .collect(toList());\n }\n\n private Connection generateConnection() {\n try {\n return DriverManager.getConnection(URL, USERNAME, PASSWORD);\n } catch (SQLException e) {\n throw new IllegalStateException("\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.");\n }\n }\n\n public Connection getConnection() {\n int currentIndex = index.getAndIncrement();\n return connections.get(currentIndex % connections.size());\n }\n}\n')))),(0,a.kt)("h3",{id:"select-delete-\uc911\ubcf5-\uc81c\uac70"},"SELECT, DELETE \uc911\ubcf5 \uc81c\uac70"),(0,a.kt)("p",null,"\ubcc0\ud558\uc9c0 \uc54a\ub294 \ubd80\ubd84: try-with-resource, preparedStatement\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84, executeUpdate\ub85c \uc2e4\ud589 \ub4f1\ub4f1",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcc0\ud558\ub294 \ubd80\ubd84: SQL Query, \ub9e4\uac1c\ubcc0\uc218 "),(0,a.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\ub294 \ubd80\ubd84\uc744 \ubd84\ub9ac\ud558\uace0 \uac00\ubcc0\uc778\uc218\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 SELECT\uc640 DELETE\uc758 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public void insert(final String name) {\n final String query = "INSERT INTO User (name) VALUES (?)";\n executeUpdate(query, name);\n}\n\npublic void delete(final int userId) {\n final String query = "DELETE FROM user WHERE user_id = ?";\n executeUpdate(query, userId);\n}\n\nprivate void executeUpdate(final String query, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n')),(0,a.kt)("h3",{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---1-\ucf5c\ubc31\uc744-\uc704\ud55c-\uc778\ud130\ud398\uc774\uc2a4-\uc815\uc758"},"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758"),(0,a.kt)("p",null,"\uc870\ud68c\ub294 INSERT, DELETE\uc640 \ub2ec\ub9ac \uac12\uc744 \ubc18\ud658\ubc1b\uc544\uc57c \ud558\uae30 \ub54c\ubb38\uc5d0 \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c \ucf5c\ubc31\uc774\ub77c\ub294 \uac83\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("admonition",{title:"\ucf5c\ubc31(Callback)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ud504\ub85c\uadf8\ub798\ubc0d\uc5d0\uc11c \ucf5c\ubc31\uc740 \ub2e4\ub978 \ucf54\ub4dc\uc758 \uc778\uc218\ub85c \ub118\uaca8\uc8fc\ub294 \uc2e4\ud589 \uac00\ub2a5\ud55c \ucf54\ub4dc\ub97c \ub73b\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\ubc14\uc5d0\uc11c\ub294 \ub78c\ub2e4\ub098 \uc775\uba85 \ud074\ub798\uc2a4\ub97c \ub118\uaca8\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("mermaid",{parentName:"admonition",value:"flowchart LR\n \ud074\ub77c\uc774\uc5b8\ud2b8 -- \ucf5c\ubc31\uc804\ub2ec --\x3e \uba54\uc11c\ub4dc\n \uba54\uc11c\ub4dc -- \ub0b4\ubd80\ud638\ucd9c --\x3e \uc804\ub2ec\ubc1b\uc740\ucf5c\ubc31"})),(0,a.kt)("p",null,"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uc870\ud68c\ud558\uace0, \ud574\ub2f9 \uac12\uc744 \uac1d\uccb4\ub85c \ub9e4\ud551\ud558\uc5ec \uac12\uc744 \ubc18\ud658\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","executeQuery\ub85c \uc870\ud68c\ud55c \uac12\uc740 ResultSet \uc548\uc5d0 \ub4e4\uc5b4\uac00\uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c \uc6d0\ud558\ub294 \ud0c0\uc785\uc758 \uac12\uc73c\ub85c \ubcc0\ud658\ud574\uc57c\ud558\ub2c8 \uc77c\ub2e8 \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@FunctionalInterface\npublic interface RowMapper {\n User mapRow(final ResultSet resultSet) throws SQLException;\n}\n")),(0,a.kt)("h3",{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---2-\ub2e8\uac74-\uc870\ud68c"},"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c"),(0,a.kt)("p",null,"\uc704\uc5d0\uc11c \uc815\uc758\ud55c RowMapper\ub97c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc5b4\ub5bb\uac8c \uc0ac\uc6a9\ud574\uc57c \ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc640 \uac19\uc774 SQL \ucffc\ub9ac, RowMapper, \ud30c\ub77c\ubbf8\ud130\ub97c \ubd84\ub9ac\ud55c \uba54\uc11c\ub4dc\uc5d0 \ub118\uaca8\uc8fc\uace0 \ucffc\ub9ac \uc2e4\ud589 \ud6c4 \ub9e4\ud551\ud55c \uac12\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public User findById(final int userId) {\n final String query = "SELECT * FROM user WHERE id = ?";\n return queryForSingleResult(query, resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n }, userId);\n}\n\nprivate User queryForSingleResult(\n final String query,\n final RowMapper rowMapper,\n final Object... parameters\n) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n if (resultSet.next()) {\n return rowMapper.mapRow(resultSet);\n }\n return null;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n\nprivate ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n}\n')),(0,a.kt)("h3",{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---3-\ub2e4\uac74-\uc870\ud68c"},"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c"),(0,a.kt)("p",null,"\ub2e8\uac74 \uc870\ud68c\uc640 \uc720\uc0ac\ud558\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public List<User> findAll() {\n final String query = "SELECT * FROM user";\n return query(query, resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n });\n}\n\nprivate List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n final List<User> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(rowMapper.mapRow(resultSet));\n }\n return result;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n\nprivate ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n}\n')),(0,a.kt)("h3",{id:"\uc81c\ub124\ub9ad-\uc0ac\uc6a9\ud558\uae30"},"\uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30"),(0,a.kt)("p",null,"\uc704\uc758 \ucf54\ub4dc\ub294 User\ub97c \uc870\ud68c\ud560 \ub54c\ub9cc \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc640 \uac19\uc774 \uc81c\ub124\ub9ad\uc744 \uc801\uc6a9\ud558\uc5ec \ub2e4\ub978 Dao\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\ud558\ub3c4\ub85d \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@FunctionalInterface\npublic interface RowMapper<T> {\n T mapRow(final ResultSet resultSet) throws SQLException;\n}\n\nprivate <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\nprivate <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\n")),(0,a.kt)("h3",{id:"\uba54\uc11c\ub4dc-\ubd84\ub9ac\ud55c-\ubd80\ubd84-\ud074\ub798\uc2a4\ub85c-\ubd84\ub9ac\ud558\uae30--optional-\uc0ac\uc6a9\ud558\uae30"},"\uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30"),(0,a.kt)("p",null,"\uba54\uc11c\ub4dc\ub85c \ubd84\ub9ac\ud55c \ubd80\ubd84\uc744 JdbcTemplate\uc774\ub77c\ub294 \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uc5b4 \uc62e\uae34\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c null\uc744 \ubc18\ud658\ud558\uae30 \ubcf4\ub2e8 Optional\ub85c \uac10\uc2f8\uc11c \ubc18\ud658\ud558\ub3c4\ub85d \ubcc0\uacbd\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\uc885\uc801\uc73c\ub85c \uc544\ub798\uc640 \uac19\uc740 \ucf54\ub4dc\uac00 \uc644\uc131\ub41c\ub2e4."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(i.Z,{value:"UserDao",label:"UserDao",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public class UserDao {\n private final RowMapper<User> rowMapper = resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n };\n private final JdbcTemplate jdbcTemplate;\n\n public UserDao(final JdbcTemplate jdbcTemplate) {\n this.jdbcTemplate = jdbcTemplate;\n }\n\n public void insert(final String name) {\n final String query = "INSERT INTO User (name) VALUES (?)";\n jdbcTemplate.executeUpdate(query, name);\n }\n\n public void delete(final int userId) {\n final String query = "DELETE FROM user WHERE user_id = ?";\n jdbcTemplate.executeUpdate(query, userId);\n }\n\n public Optional<User> findById(final int userId) {\n final String query = "SELECT * FROM user WHERE id = ?";\n return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);\n }\n\n public List<User> findAll() {\n final String query = "SELECT * FROM user";\n return jdbcTemplate.query(query, rowMapper);\n }\n}\n'))),(0,a.kt)(i.Z,{value:"JdbcTemplate",label:"JdbcTemplate",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public class JdbcTemplate {\n private final ConnectionPool connectionPool;\n\n public JdbcTemplate(final ConnectionPool connectionPool) {\n this.connectionPool = connectionPool;\n }\n\n public void executeUpdate(final String query, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public <T> Optional<T> queryForSingleResult(\n final String query,\n final RowMapper<T> rowMapper,\n final Object... parameters\n ) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n if (resultSet.next()) {\n return Optional.of(rowMapper.mapRow(resultSet));\n }\n return Optional.empty();\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n private ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters\n ) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n }\n\n public <T> List<T> query(\n final String query,\n final RowMapper<T> rowMapper,\n final Object... parameters\n ) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n final List<T> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(rowMapper.mapRow(resultSet));\n }\n return result;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n}\n")))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6b69808d.a3797a3c.js b/assets/js/6b69808d.a3797a3c.js deleted file mode 100644 index b696d32ca..000000000 --- a/assets/js/6b69808d.a3797a3c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5990],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),u=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=u(e.components);return r.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,p=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),d=u(n),m=a,E=d["".concat(p,".").concat(m)]||d[m]||s[m]||l;return n?r.createElement(E,i(i({ref:t},c),{},{components:n})):r.createElement(E,i({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,i=new Array(l);i[0]=d;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o.mdxType="string"==typeof e?e:a,i[1]=o;for(var u=2;u<l;u++)i[u]=n[u];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}d.displayName="MDXCreateElement"},5069:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>s,frontMatter:()=>l,metadata:()=>o,toc:()=>u});var r=n(87462),a=(n(67294),n(3905));const l={title:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",slug:"/jpa/key",last_update:{date:"2023/07/24"},tags:["JPA"]},i=void 0,o={unversionedId:"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551",id:"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551",title:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",description:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",source:"@site/docs/JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551.mdx",sourceDirName:"JPA",slug:"/jpa/key",permalink:"/docs/jpa/key",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551.mdx",tags:[{label:"JPA",permalink:"/docs/tags/jpa"}],version:"current",lastUpdatedAt:1690156800,formattedLastUpdatedAt:"2023\ub144 7\uc6d4 24\uc77c",frontMatter:{title:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",slug:"/jpa/key",last_update:{date:"2023/07/24"},tags:["JPA"]},sidebar:"tutorialSidebar",next:{title:"SequencedCollection",permalink:"/docs/java/sequenced-collection"}},p={},u=[{value:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",id:"\uae30\ubcf8-\ud0a4-\ub9e4\ud551",level:3},{value:"\uc9c1\uc811 \ud560\ub2f9",id:"\uc9c1\uc811-\ud560\ub2f9",level:3},{value:"IDENTITY",id:"identity",level:3},{value:"SEQUENCE",id:"sequence",level:3},{value:"TABLE",id:"table",level:3},{value:"AUTO",id:"auto",level:3},{value:"UUID",id:"uuid",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:u};function s(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uae30\ubcf8-\ud0a4-\ub9e4\ud551"},"\uae30\ubcf8 \ud0a4 \ub9e4\ud551"),(0,a.kt)("p",null,"\uae30\ubcf8 \ud0a4 \ub9e4\ud551 \uc804\ub7b5\uc5d0\ub294 \uc9c1\uc811 \ud560\ub2f9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\uace0 \uc790\ub3d9 \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\ub3d9 \uc0dd\uc131\uc744 \uc120\ud0dd\ud55c\ub2e4\uba74 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \ud0a4\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc9c1\uc811 \ud560\ub2f9\ud558\uc9c0 \uc54a\uace0, \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc0dd\uc131\ud574\uc8fc\ub294 \uac12\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\uc9c1\uc811-\ud560\ub2f9"},"\uc9c1\uc811 \ud560\ub2f9"),(0,a.kt)("p",null,"\uae30\ubcf8 \ud0a4\ub97c \uc9c1\uc811 \ud560\ub2f9\ud558\ub294 \uacbd\uc6b0\uc5d0 ",(0,a.kt)("inlineCode",{parentName:"p"},"@Id"),"\ub9cc \uc0ac\uc6a9\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\ub3d9 \ud560\ub2f9\ud558\ub294 \uacbd\uc6b0 ",(0,a.kt)("inlineCode",{parentName:"p"},"@Id"),"\uc5d0 \ucd94\uac00\uc801\uc73c\ub85c ",(0,a.kt)("inlineCode",{parentName:"p"},"@GeneratedValue"),"\ub97c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"identity"},"IDENTITY"),(0,a.kt)("p",null,"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc0dd\uc131\ud55c \ud0a4\ub97c \uc0ac\uc6a9\ud558\ub294 \uc804\ub7b5",(0,a.kt)("br",{parentName:"p"}),"\n","MySQL, PostgreSQL\uacfc \uac19\uc740 DB\uc5d0\uc11c \uc8fc\ub85c \uc0ac\uc6a9\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Hibernate\ub294 JDBC3\uc5d0 \ucd94\uac00\ub41c ",(0,a.kt)("inlineCode",{parentName:"p"},"Statement.getGeneratedKeys()"),"\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc0dd\uc131\uacfc \ub3d9\uc2dc\uc5d0 \ud0a4 \uac12\uc744 \uc5bb\uc5b4 \uc62c \uc218 \uc788\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@Entity\npublic class Member {\n\n @Id\n @GeneratedValue(strategy = GenerationType.IDENTITY)\n private Long id;\n}\n")),(0,a.kt)("h3",{id:"sequence"},"SEQUENCE"),(0,a.kt)("p",null,"\uc2dc\ud000\uc2a4\ub294 \uc720\uc77c\ud55c \uac12\uc744 \uc21c\uc11c\ub300\ub85c \uc0dd\uc131\ud558\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc624\ube0c\uc81d\ud2b8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","IDENTITY\uc758 \uacbd\uc6b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud55c \ud6c4 \uc2dd\ubcc4\uc790\ub97c \uc870\ud68c\ud574\uc11c \uc5d4\ud2f0\ud2f0\uc758 \uc2dd\ubcc4\uc790\uc5d0 \ud560\ub2f9\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","SEQUENCE\uc758 \uacbd\uc6b0 ",(0,a.kt)("inlineCode",{parentName:"p"},"call next value for member_seq"),"\uc640 \uac19\uc774 \uc2dc\ud000\uc2a4\ub97c \uc0ac\uc6a9\ud574\uc11c \uc2dd\ubcc4\uc790\ub97c "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@SequenceGenerator(\n name = "MEMBER_SEQ_GENERATOR",\n sequenceName = "MEMBER_SEQ",\n initialValue = 1,\n allocationSize = 1\n)\n@Entity\npublic class Member {\n\n @Id\n @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")\n private Long id;\n}\n')),(0,a.kt)("h3",{id:"table"},"TABLE"),(0,a.kt)("p",null,"\ud0a4 \uc0dd\uc131\uc6a9 \ud14c\uc774\ube14\uc744 \ubcc4\ub3c4\ub85c \ub450\uc5b4 \uc2dc\ud000\uc2a4\uc640 \uc720\uc0ac\ud558\uac8c \uc2dd\ubcc4\uc790 \ud0a4\ub97c \uc5bb\ub294 \uc804\ub7b5\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc870\ud68c\uc640 \uc5c5\ub370\uc774\ud2b8\ub97c \ud574\uc57c\ud55c\ub2e4\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@TableGenerator(\n name = "MEMBER_SEQ_GENERATOR",\n table = "MEMBER_SEQUENCES",\n pkColumnValue = "MEMBER_SEQ",\n allocationSize = 1\n)\n@Entity\npublic class Member {\n\n @Id\n @GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")\n private Long id;\n}\n')),(0,a.kt)("h3",{id:"auto"},"AUTO"),(0,a.kt)("p",null,"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ub530\ub77c \uc704\uc5d0 \uc5b8\uae09\ub41c \uc804\ub7b5 \uc911 \ud558\ub098\ub97c \uc790\ub3d9\uc73c\ub85c \uc120\ud0dd\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","MySQL\uc758 \uacbd\uc6b0 IDENTITY Oracle\uc758 \uacbd\uc6b0 SEQUENCE\ub97c \uc120\ud0dd\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"uuid"},"UUID"),(0,a.kt)("p",null,"JPA 3.1.0 UUID \uc0dd\uc131 \uc804\ub7b5\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Hibernate 6.2\ubd80\ud130 JPA 3.1.0\uc744 \uc9c0\uc6d0\ud558\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1 \uc774\uc0c1\uc778 \uacbd\uc6b0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@Entity\npublic class Member {\n\n @Id\n @GeneratedValue(strategy = GenerationType.UUID)\n @UuidGenerator(style = Style.RANDOM)\n private Long id;\n}\n")),(0,a.kt)("p",null,"UuidGenerator\ub97c \uc774\uc6a9\ud558\uc5ec UUID \uc0dd\uc131 \ubc29\uc2dd\ub3c4 \uc124\uc815\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0dd\uc131 \ubc29\uc2dd\uc740 3\uac00\uc9c0\uac00 \uc788\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"RANDOM - \ub09c\uc218 \uae30\ubc18 UUID \uc0dd\uc131(uuid v4)"),(0,a.kt)("li",{parentName:"ul"},"TIME \u2013 \uc2dc\uac04 \uae30\ubc18 UUID \uc0dd\uc131(uuid v1)"),(0,a.kt)("li",{parentName:"ul"},"AUTO \u2013 \uae30\ubcf8 \uc635\uc158, RANDOM\uacfc \ub3d9\uc77c")),(0,a.kt)("p",null,"UUID\uc758 \uacbd\uc6b0 \ub9ce\uc740 \uc591\uc758 \uc800\uc7a5 \uacf5\uac04\uc744 \ud544\uc694\ub85c \ud558\uace0, \uc131\ub2a5 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\uae30\uc5d0 UUID\ub97c \uc0ac\uc6a9\ud574\uc57c \ud558\ub294 \uacbd\uc6b0 TSID\ub97c \uace0\ub824\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc790\ubc14 ORM \ud45c\uc900 JPA \ud504\ub85c\uadf8\ub798\ubc0d, \uae40\uc601\ud55c p.131 ~ p.144",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.baeldung.com/java-hibernate-uuid-primary-key"},"Generate UUIDs as Primary Keys With Hibernate")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6b69808d.cfb22962.js b/assets/js/6b69808d.cfb22962.js new file mode 100644 index 000000000..6e522efed --- /dev/null +++ b/assets/js/6b69808d.cfb22962.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5990],{35703:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>l,toc:()=>o});var t=r(85893),a=r(3905);const s={title:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",slug:"/jpa/key",last_update:{date:"2023/07/24"},tags:["JPA"]},i=void 0,l={id:"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551",title:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",description:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",source:"@site/docs/JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551.mdx",sourceDirName:"JPA",slug:"/jpa/key",permalink:"/docs/jpa/key",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551.mdx",tags:[{label:"JPA",permalink:"/docs/tags/jpa"}],version:"current",lastUpdatedAt:1690156800,formattedLastUpdatedAt:"2023\ub144 7\uc6d4 24\uc77c",frontMatter:{title:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",slug:"/jpa/key",last_update:{date:"2023/07/24"},tags:["JPA"]},sidebar:"tutorialSidebar",next:{title:"SequencedCollection",permalink:"/docs/java/sequenced-collection"}},c={},o=[{value:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551",id:"\uae30\ubcf8-\ud0a4-\ub9e4\ud551",level:3},{value:"\uc9c1\uc811 \ud560\ub2f9",id:"\uc9c1\uc811-\ud560\ub2f9",level:3},{value:"IDENTITY",id:"identity",level:3},{value:"SEQUENCE",id:"sequence",level:3},{value:"TABLE",id:"table",level:3},{value:"AUTO",id:"auto",level:3},{value:"UUID",id:"uuid",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\uae30\ubcf8-\ud0a4-\ub9e4\ud551",children:"\uae30\ubcf8 \ud0a4 \ub9e4\ud551"}),"\n",(0,t.jsxs)(n.p,{children:["\uae30\ubcf8 \ud0a4 \ub9e4\ud551 \uc804\ub7b5\uc5d0\ub294 \uc9c1\uc811 \ud560\ub2f9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\uace0 \uc790\ub3d9 \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc790\ub3d9 \uc0dd\uc131\uc744 \uc120\ud0dd\ud55c\ub2e4\uba74 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \ud0a4\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc9c1\uc811 \ud560\ub2f9\ud558\uc9c0 \uc54a\uace0, \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc0dd\uc131\ud574\uc8fc\ub294 \uac12\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc9c1\uc811-\ud560\ub2f9",children:"\uc9c1\uc811 \ud560\ub2f9"}),"\n",(0,t.jsxs)(n.p,{children:["\uae30\ubcf8 \ud0a4\ub97c \uc9c1\uc811 \ud560\ub2f9\ud558\ub294 \uacbd\uc6b0\uc5d0 ",(0,t.jsx)(n.code,{children:"@Id"}),"\ub9cc \uc0ac\uc6a9\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc790\ub3d9 \ud560\ub2f9\ud558\ub294 \uacbd\uc6b0 ",(0,t.jsx)(n.code,{children:"@Id"}),"\uc5d0 \ucd94\uac00\uc801\uc73c\ub85c ",(0,t.jsx)(n.code,{children:"@GeneratedValue"}),"\ub97c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"identity",children:"IDENTITY"}),"\n",(0,t.jsxs)(n.p,{children:["\ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc0dd\uc131\ud55c \ud0a4\ub97c \uc0ac\uc6a9\ud558\ub294 \uc804\ub7b5",(0,t.jsx)(n.br,{}),"\n","MySQL, PostgreSQL\uacfc \uac19\uc740 DB\uc5d0\uc11c \uc8fc\ub85c \uc0ac\uc6a9\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Hibernate\ub294 JDBC3\uc5d0 \ucd94\uac00\ub41c ",(0,t.jsx)(n.code,{children:"Statement.getGeneratedKeys()"}),"\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc0dd\uc131\uacfc \ub3d9\uc2dc\uc5d0 \ud0a4 \uac12\uc744 \uc5bb\uc5b4 \uc62c \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@Entity\npublic class Member {\n\n @Id\n @GeneratedValue(strategy = GenerationType.IDENTITY)\n private Long id;\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"sequence",children:"SEQUENCE"}),"\n",(0,t.jsxs)(n.p,{children:["\uc2dc\ud000\uc2a4\ub294 \uc720\uc77c\ud55c \uac12\uc744 \uc21c\uc11c\ub300\ub85c \uc0dd\uc131\ud558\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc624\ube0c\uc81d\ud2b8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","IDENTITY\uc758 \uacbd\uc6b0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud55c \ud6c4 \uc2dd\ubcc4\uc790\ub97c \uc870\ud68c\ud574\uc11c \uc5d4\ud2f0\ud2f0\uc758 \uc2dd\ubcc4\uc790\uc5d0 \ud560\ub2f9\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","SEQUENCE\uc758 \uacbd\uc6b0 ",(0,t.jsx)(n.code,{children:"call next value for member_seq"}),"\uc640 \uac19\uc774 \uc2dc\ud000\uc2a4\ub97c \uc0ac\uc6a9\ud574\uc11c \uc2dd\ubcc4\uc790\ub97c"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@SequenceGenerator(\n name = "MEMBER_SEQ_GENERATOR",\n sequenceName = "MEMBER_SEQ",\n initialValue = 1,\n allocationSize = 1\n)\n@Entity\npublic class Member {\n\n @Id\n @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")\n private Long id;\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"table",children:"TABLE"}),"\n",(0,t.jsxs)(n.p,{children:["\ud0a4 \uc0dd\uc131\uc6a9 \ud14c\uc774\ube14\uc744 \ubcc4\ub3c4\ub85c \ub450\uc5b4 \uc2dc\ud000\uc2a4\uc640 \uc720\uc0ac\ud558\uac8c \uc2dd\ubcc4\uc790 \ud0a4\ub97c \uc5bb\ub294 \uc804\ub7b5\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc870\ud68c\uc640 \uc5c5\ub370\uc774\ud2b8\ub97c \ud574\uc57c\ud55c\ub2e4\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@TableGenerator(\n name = "MEMBER_SEQ_GENERATOR",\n table = "MEMBER_SEQUENCES",\n pkColumnValue = "MEMBER_SEQ",\n allocationSize = 1\n)\n@Entity\npublic class Member {\n\n @Id\n @GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")\n private Long id;\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"auto",children:"AUTO"}),"\n",(0,t.jsxs)(n.p,{children:["\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ub530\ub77c \uc704\uc5d0 \uc5b8\uae09\ub41c \uc804\ub7b5 \uc911 \ud558\ub098\ub97c \uc790\ub3d9\uc73c\ub85c \uc120\ud0dd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MySQL\uc758 \uacbd\uc6b0 IDENTITY Oracle\uc758 \uacbd\uc6b0 SEQUENCE\ub97c \uc120\ud0dd\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"uuid",children:"UUID"}),"\n",(0,t.jsxs)(n.p,{children:["JPA 3.1.0 UUID \uc0dd\uc131 \uc804\ub7b5\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Hibernate 6.2\ubd80\ud130 JPA 3.1.0\uc744 \uc9c0\uc6d0\ud558\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1 \uc774\uc0c1\uc778 \uacbd\uc6b0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@Entity\npublic class Member {\n\n @Id\n @GeneratedValue(strategy = GenerationType.UUID)\n @UuidGenerator(style = Style.RANDOM)\n private Long id;\n}\n"})}),"\n",(0,t.jsxs)(n.p,{children:["UuidGenerator\ub97c \uc774\uc6a9\ud558\uc5ec UUID \uc0dd\uc131 \ubc29\uc2dd\ub3c4 \uc124\uc815\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc0dd\uc131 \ubc29\uc2dd\uc740 3\uac00\uc9c0\uac00 \uc788\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"RANDOM - \ub09c\uc218 \uae30\ubc18 UUID \uc0dd\uc131(uuid v4)"}),"\n",(0,t.jsx)(n.li,{children:"TIME \u2013 \uc2dc\uac04 \uae30\ubc18 UUID \uc0dd\uc131(uuid v1)"}),"\n",(0,t.jsx)(n.li,{children:"AUTO \u2013 \uae30\ubcf8 \uc635\uc158, RANDOM\uacfc \ub3d9\uc77c"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"UUID\uc758 \uacbd\uc6b0 \ub9ce\uc740 \uc591\uc758 \uc800\uc7a5 \uacf5\uac04\uc744 \ud544\uc694\ub85c \ud558\uace0, \uc131\ub2a5 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\uae30\uc5d0 UUID\ub97c \uc0ac\uc6a9\ud574\uc57c \ud558\ub294 \uacbd\uc6b0 TSID\ub97c \uace0\ub824\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."}),"\n",(0,t.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:["\uc790\ubc14 ORM \ud45c\uc900 JPA \ud504\ub85c\uadf8\ub798\ubc0d, \uae40\uc601\ud55c p.131 ~ p.144",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://www.baeldung.com/java-hibernate-uuid-primary-key",children:"Generate UUIDs as Primary Keys With Hibernate"})]})]})}function u(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>o});var t=r(67294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?s(Object(r),!0).forEach((function(n){a(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function l(e,n){if(null==e)return{};var r,t,a=function(e,n){if(null==e)return{};var r,t,a={},s=Object.keys(e);for(t=0;t<s.length;t++)r=s[t],n.indexOf(r)>=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t<s.length;t++)r=s[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=t.createContext({}),o=function(e){var n=t.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=o(r),j=a,E=p["".concat(c,".").concat(j)]||p[j]||d[j]||s;return r?t.createElement(E,i(i({ref:n},u),{},{components:r})):t.createElement(E,i({ref:n},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/6c38e270.5da4b5e2.js b/assets/js/6c38e270.5142239c.js similarity index 79% rename from assets/js/6c38e270.5da4b5e2.js rename to assets/js/6c38e270.5142239c.js index d702a31fb..362d66e1d 100644 --- a/assets/js/6c38e270.5da4b5e2.js +++ b/assets/js/6c38e270.5142239c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7247],{51914:e=>{e.exports=JSON.parse('{"label":"sequenced","permalink":"/docs/tags/sequenced","allTagsPath":"/docs/tags","count":1,"items":[{"id":"Java/SequencedCollection","title":"SequencedCollection","description":"JEP 431: Sequenced Collections","permalink":"/docs/java/sequenced-collection"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7247],{51914:e=>{e.exports=JSON.parse('{"label":"sequenced","permalink":"/docs/tags/sequenced","allTagsPath":"/docs/tags","count":1,"items":[{"id":"Java/SequencedCollection","title":"SequencedCollection","description":"JEP 431: Sequenced Collections","permalink":"/docs/java/sequenced-collection"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/6c674d03.239b12b7.js b/assets/js/6c674d03.32ba75ec.js similarity index 94% rename from assets/js/6c674d03.239b12b7.js rename to assets/js/6c674d03.32ba75ec.js index ca638671b..d19534db7 100644 --- a/assets/js/6c674d03.239b12b7.js +++ b/assets/js/6c674d03.32ba75ec.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7600],{80372:e=>{e.exports=JSON.parse('{"label":"network","permalink":"/docs/tags/network","allTagsPath":"/docs/tags","count":2,"items":[{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1","description":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?","permalink":"/docs/network/load-balancing"},{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","description":"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)","permalink":"/docs/network/load-balancing-algorithm"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7600],{80372:e=>{e.exports=JSON.parse('{"label":"network","permalink":"/docs/tags/network","allTagsPath":"/docs/tags","count":2,"items":[{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1","description":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?","permalink":"/docs/network/load-balancing"},{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","description":"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)","permalink":"/docs/network/load-balancing-algorithm"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/6d4355d3.3a49ae35.js b/assets/js/6d4355d3.bb82b9e2.js similarity index 87% rename from assets/js/6d4355d3.3a49ae35.js rename to assets/js/6d4355d3.bb82b9e2.js index adef4f370..51c9514ed 100644 --- a/assets/js/6d4355d3.3a49ae35.js +++ b/assets/js/6d4355d3.bb82b9e2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3122],{37438:s=>{s.exports=JSON.parse('{"label":"async","permalink":"/tags/async","allTagsPath":"/tags","count":2}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3122],{37438:s=>{s.exports=JSON.parse('{"label":"async","permalink":"/tags/async","allTagsPath":"/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/6f385a52.ac98a76a.js b/assets/js/6f385a52.ac98a76a.js deleted file mode 100644 index e27d77c8c..000000000 --- a/assets/js/6f385a52.ac98a76a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6608],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,g=d["".concat(c,".").concat(m)]||d[m]||s[m]||l;return n?r.createElement(g,o(o({ref:t},u),{},{components:n})):r.createElement(g,o({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var p=2;p<l;p++)o[p]=n[p];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}d.displayName="MDXCreateElement"},65468:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>s,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const l={title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",slug:"accidental-duplication",tags:["DTO"]},o=void 0,i={permalink:"/accidental-duplication",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",source:"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",description:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",date:"2023-05-24T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 24\uc77c",tags:[{label:"DTO",permalink:"/tags/dto"}],readingTime:7.525,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",slug:"accidental-duplication",tags:["DTO"]},prevItem:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",permalink:"/subway-retrospective"},nextItem:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",permalink:"/shopping-cart-retrospective"}},c={authorsImageUrls:[]},p=[{value:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815",id:"\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158\uc5d0\uc11c\uc758-\uc0c1\ud488-\ucd94\uac00-\ubc0f-\uc218\uc815",level:3},{value:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",id:"\uc911\ubcf5\uacfc-\uc6b0\ubc1c\uc801-\uc911\ubcf5",level:3},{value:"\ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c",id:"\ud558\ub098\ub85c-\uc0ac\uc6a9\ud558\ub294-\uac74-\uc548\uc88b\uc544\ubcf4\uc774\uace0-\uc911\ubcf5\uc740-\uc81c\uac70\ud558\uace0-\uc2f6\uc740-\ub9c8\uc74c",level:3},{value:"\uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc",id:"\uc911\ubcf5-\uc81c\uac70-\uc804-\ucf54\ub4dc",level:3},{value:"\uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30",id:"\uc778\ud130\ud398\uc774\uc2a4-\uc791\uc131\ud558\uae30",level:3},{value:"\uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30",id:"\uad6c\ud604\uccb4-\uc791\uc131\ud558\uae30",level:3},{value:"\uc815\ub9ac",id:"\uc815\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:p};function s(e){let{components:t,...l}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,l,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uccad\uc5d0 \ub2f4\uae34 Body\ub97c \ud1b5\ud574 \uc804\ub2ec\ubc1b\uc740 \uac12\uc744 DTO\ub85c \ub9e4\ud551\ud558\uc5ec \ucd94\uac00\uc640 \uc218\uc815\uc744 \ud588\ub2e4."),(0,a.kt)("h3",{id:"\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158\uc5d0\uc11c\uc758-\uc0c1\ud488-\ucd94\uac00-\ubc0f-\uc218\uc815"},"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"\uc911\ubcf51",src:n(92725).Z,width:"2028",height:"704"})),(0,a.kt)("p",null,"\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d\ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0\uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc704 \uacbd\uc6b0\ub294 \uc911\ubcf5\uc77c\uae4c? \uc911\ubcf5\uc774 \uc544\ub2d0\uae4c?"),(0,a.kt)("p",null,"\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ub9ac\ubdf0\ub97c \ubc1b\uc558\ub2e4."),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},(0,a.kt)("inlineCode",{parentName:"p"},"ProductSaveRequest"),"\uc640 ",(0,a.kt)("inlineCode",{parentName:"p"},"ProductUpdateRequest"),"\uac00 \uc644\uc804\ud788 \ub3d9\uc77c\ud55c\ub370, \uc7ac\uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc744\uae4c? \ub77c\ub294 \ub9ac\ubdf0\ub97c \ub0a8\uacbc\uc5c8\uc5b4\uc694. \uc0ac\uc2e4 \uc0dd\uc131\uacfc \uc218\uc815\uc740 \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac1c\uc5f0\uc131\uc774 \ub192\uc544\uc11c \ubbf8\ub9ac \ubd84\ub9ac\ud574\ub193\ub294 \uac8c \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\uae34 \ud55c\ub370, \uadf8\ub798\ub3c4 \uc911\ubcf5\uc740 \uc2eb\uc5b4\uc11c \uc800\ub3c4 \uc694\uc998 \uc774\ub7f0\uc800\ub7f0 \ubc29\ubc95\ub4e4\uc744 \uc2dc\ub3c4\ud574\ubcf4\ub294 \uc911 \uc785\ub2c8\ub2e4. \ud5c8\ube0c\ub294 \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc5b4\ub5a4 \uc0dd\uac01\uc744 \uac00\uc9c0\uace0 \uc788\uc744\uc9c0 \uad81\uae08\ud558\ub124\uc694 \u314e\u314e")),(0,a.kt)("p",null,"\uc9c8\ubb38\uc5d0 \ub300\ud574 \uc544\ub798\uc640 \uac19\uc774 \ub2f5\ubcc0\uc744 \ud588\ub2e4."),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc800\uc7a5\uacfc \uc218\uc815\ud560 \ub54c \ud544\uc694\ud55c \ud544\ub4dc\uac12\uc774 \ub3d9\uc77c\ud558\uc5ec \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c\ub294 \ud558\ub098\ub85c \uc0ac\uc6a9\ud574\ub3c4 \ub41c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud558\uc9c0\ub9cc, \ub9d0\uc500\ud574\uc8fc\uc2e0\ub300\ub85c \uc694\uad6c\uc0ac\ud56d\uc774 \ubcc0\uacbd\ub41c\ub2e4\uba74 \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\ub2e4\uace0 \ud310\ub2e8\ud558\uc600\uc2b5\ub2c8\ub2e4!")),(0,a.kt)("h3",{id:"\uc911\ubcf5\uacfc-\uc6b0\ubc1c\uc801-\uc911\ubcf5"},"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5"),(0,a.kt)("p",null,"\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec\uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"\uac70\uc9d3\ub41c \uc911\ubcf5, \uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4.")),(0,a.kt)("p",null,"\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131\uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.\n\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc704 \uc0c1\ud669\uc740 \uc6b0\ubc1c\uc801 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc778\ub2e4. \uadf8\ub798\ub3c4 \uc911\ubcf5\uc744 \uc81c\uac70\ud574\ubcfc \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?"),(0,a.kt)("h3",{id:"\ud558\ub098\ub85c-\uc0ac\uc6a9\ud558\ub294-\uac74-\uc548\uc88b\uc544\ubcf4\uc774\uace0-\uc911\ubcf5\uc740-\uc81c\uac70\ud558\uace0-\uc2f6\uc740-\ub9c8\uc74c"},"\ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c"),(0,a.kt)("p",null,"\uc9c0\uae08\uc740 \ucd94\uac00, \uc218\uc815 2\uac00\uc9c0 \uacbd\uc6b0 \ubc16\uc5d0 \uc5c6\uc9c0\ub9cc \uc870\uae08 \ub354 \ubcf5\uc7a1\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc8fc\uc5b4\uc838\uc11c 10\uac00\uc9c0 \uacbd\uc6b0\ub85c \uc785\ub825\uc744 \ubc1b\uc73c\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c\ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc11c\ube44\uc2a4 \uacc4\uce35\uc5d0\uc11c\ub3c4 \uacc4\uce35\uc758 \ubd84\ub9ac\ub97c \uc704\ud574\uc11c \ub2e4\ub978 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uba74 20\uac1c\uc758 DTO\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ubdf0\uc5b4\uac00 \uc54c\ub824\uc900 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \ud1b5\ud574 \uc774\ub97c \ud574\uacb0\ud574\ubcf4\uc790! "),(0,a.kt)("h3",{id:"\uc911\ubcf5-\uc81c\uac70-\uc804-\ucf54\ub4dc"},"\uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc"),(0,a.kt)("p",null,"\ud604\uc7ac \ucf54\ub4dc\uc5d0\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Controller\uc640 Service\uc5d0\uc11c \uc800\uc7a5, \uc218\uc815\ud560 \ub54c \uac01\uac01\uc758 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.\n\ud604\uc7ac DTO\ub294 controller, service \ud328\ud0a4\uc9c0 \ub0b4\uc5d0 \uc788\ub294 \uac83\uc774 \uc544\ub2c8\ub77c dto\ub77c\ub294 \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\ud558\uace0 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductService\n\u251c\u2500\u2500 dto\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"\uc911\ubcf52",src:n(12314).Z,width:"1528",height:"912"})),(0,a.kt)("h3",{id:"\uc778\ud130\ud398\uc774\uc2a4-\uc791\uc131\ud558\uae30"},"\uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"\uc911\ubcf53",src:n(56531).Z,width:"1518",height:"904"})),(0,a.kt)("p",null,"\uc11c\ube44\uc2a4 \ub808\uc774\uc5b4\uc5d0\uc11c \ud544\uc694\ub85c \ud558\ub294 \uac12\ub4e4\uc744 \uc778\ud130\ud398\uc774\uc2a4\ub85c \uc815\uc758\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \uc11c\ube44\uc2a4\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 service \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub85c \uc62e\uaca8\uc900\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public interface ProductSaveRequest {\n\n String getName();\n\n String getImage();\n\n Long getPrice();\n}\n\n// ProductService\npublic Long save(final ProductSaveRequest request) {\n final Product product = new Product(request.getName(), request.getImage(), request.getPrice());\n return productDao.saveAndGetId(product);\n}\n")),(0,a.kt)("h3",{id:"\uad6c\ud604\uccb4-\uc791\uc131\ud558\uae30"},"\uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"\uc911\ubcf54",src:n(82237).Z,width:"1508",height:"896"})),(0,a.kt)("p",null,"\uc704\uc5d0\uc11c \uc791\uc131\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc791\uc131\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uccad\uc740 ProductRequest \ud074\ub798\uc2a4\ub85c \ubc1b\uace0, \uc11c\ube44\uc2a4\uc5d0 \uc804\ub2ec\ud560 \ub550 \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\uc758 \uba85\uc138\ub9cc \ub9de\ucd94\uba74 \ubb38\uc81c\uc5c6\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductController\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductRequest\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {\n\n @NotBlank(message = "\uc774\ub984\uc740 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.")\n @Size(min = 1, max = 100, message = "\uc774\ub984\uc740 \ucd5c\uc18c {min}\uc790 \uc774\uc0c1, {max}\uc790 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.")\n private final String name;\n\n @NotBlank(message = "\uc774\ubbf8\uc9c0\ub294 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.")\n private final String image;\n\n @Range(message = "\uac00\uaca9\uc740 \ucd5c\uc18c {min}\uc6d0 \uc774\uc0c1, {max}\uc6d0 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.")\n private final long price;\n\n public ProductRequest(final String name, final String image, final long price) {\n this.name = name;\n this.image = image;\n this.price = price;\n }\n\n @Override\n public String getName() {\n return name;\n }\n\n @Override\n public String getImage() {\n return image;\n }\n\n @Override\n public long getPrice() {\n return price;\n }\n}\n\n// ProductController\n@PostMapping("/products")\npublic ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {\n final Long id = productService.save(request);\n return ResponseEntity.created(URI.create("/products/" + id)).build();\n}\n')),(0,a.kt)("h3",{id:"\uc815\ub9ac"},"\uc815\ub9ac"),(0,a.kt)("p",null,"\uc704\uc640 \uac19\uc774 \uad6c\ud604\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc744 \uc5bb\uc744 \uc218 \uc788\ub2e4. "),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Service\uc5d0\uc11c \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc694\uccad\uc5d0 \ub300\ud55c DTO\ub97c \uc54c\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4."),(0,a.kt)("li",{parentName:"ol"},"\uacf5\ud1b5\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 DTO\ub97c \uc81c\uc678\ud558\uace0 DTO \ud328\ud0a4\uc9c0\uc5d0 \ub300\ud55c \uacb0\ud569\ub3c4\uac00 \ub0ae\uc544\uc9c0\uace0, \uac01 \ub808\uc774\uc5b4\uc758 \uc751\uc9d1\ub3c4\uac00 \uc99d\uac00\ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ol"},"\uc694\uccad \uac1d\uccb4\ub9cc \ub2e4\ub974\uace0 \uc11c\ube44\uc2a4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ud589\uc704\ub97c \uc218\ud589\ud558\ub294 \uacbd\uc6b0 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.")),(0,a.kt)("p",null,"\uc704 \ubc29\ubc95\uc744 \uc9c0\uae08 \ubbf8\uc158\uc5d0\uc11c \ubc14\ub85c \uc801\uc6a9\ud560\uae4c \ud558\ub2e4\uac00, \ub098\uc911\uc5d0 \ud544\uc694\ud560 \ub54c \uc801\uc6a9\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\uc544\uc11c \ubbf8\uc158\uc5d0\ub294 \uc801\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0c1\ud669\uc5d0 \ub9de\ucdb0 \uc801\uc7ac\uc801\uc18c\uc5d0 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud574\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4."),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98 16\uc7a5 \ub3c5\ub9bd\uc131, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/2647/"},"https://techblog.woowahan.com/2647/"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/"},"https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/")))}s.isMDXComponent=!0},92725:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/\uc911\ubcf51-ccd4f91674b224578f2b295b3fccaf2c.png"},12314:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/\uc911\ubcf52-0b4f9f493909fc139f0e4579f7569a6b.png"},56531:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/\uc911\ubcf53-1b6b93bc790ba29844083df5b70dbd2c.png"},82237:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/\uc911\ubcf54-15b381e0a024487f54608d438e5385f9.png"}}]); \ No newline at end of file diff --git a/assets/js/6f385a52.b5af1364.js b/assets/js/6f385a52.b5af1364.js new file mode 100644 index 000000000..d196759d2 --- /dev/null +++ b/assets/js/6f385a52.b5af1364.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6608],{54413:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>o});var t=r(85893),c=r(3905);const i={title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",slug:"accidental-duplication",tags:["DTO"]},s=void 0,l={permalink:"/accidental-duplication",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",source:"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",description:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",date:"2023-05-24T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 24\uc77c",tags:[{label:"DTO",permalink:"/tags/dto"}],readingTime:7.525,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",slug:"accidental-duplication",tags:["DTO"]},unlisted:!1,prevItem:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",permalink:"/subway-retrospective"},nextItem:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",permalink:"/shopping-cart-retrospective"}},a={authorsImageUrls:[]},o=[{value:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815",id:"\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158\uc5d0\uc11c\uc758-\uc0c1\ud488-\ucd94\uac00-\ubc0f-\uc218\uc815",level:3},{value:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",id:"\uc911\ubcf5\uacfc-\uc6b0\ubc1c\uc801-\uc911\ubcf5",level:3},{value:"\ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c",id:"\ud558\ub098\ub85c-\uc0ac\uc6a9\ud558\ub294-\uac74-\uc548\uc88b\uc544\ubcf4\uc774\uace0-\uc911\ubcf5\uc740-\uc81c\uac70\ud558\uace0-\uc2f6\uc740-\ub9c8\uc74c",level:3},{value:"\uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc",id:"\uc911\ubcf5-\uc81c\uac70-\uc804-\ucf54\ub4dc",level:3},{value:"\uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30",id:"\uc778\ud130\ud398\uc774\uc2a4-\uc791\uc131\ud558\uae30",level:3},{value:"\uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30",id:"\uad6c\ud604\uccb4-\uc791\uc131\ud558\uae30",level:3},{value:"\uc815\ub9ac",id:"\uc815\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",br:"br",code:"code",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,c.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc694\uccad\uc5d0 \ub2f4\uae34 Body\ub97c \ud1b5\ud574 \uc804\ub2ec\ubc1b\uc740 \uac12\uc744 DTO\ub85c \ub9e4\ud551\ud558\uc5ec \ucd94\uac00\uc640 \uc218\uc815\uc744 \ud588\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158\uc5d0\uc11c\uc758-\uc0c1\ud488-\ucd94\uac00-\ubc0f-\uc218\uc815",children:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"\uc911\ubcf51",src:r(92725).Z+"",width:"2028",height:"704"})}),"\n",(0,t.jsxs)(n.p,{children:["\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d\ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0\uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc704 \uacbd\uc6b0\ub294 \uc911\ubcf5\uc77c\uae4c? \uc911\ubcf5\uc774 \uc544\ub2d0\uae4c?"]}),"\n",(0,t.jsx)(n.p,{children:"\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ub9ac\ubdf0\ub97c \ubc1b\uc558\ub2e4."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ProductSaveRequest"}),"\uc640 ",(0,t.jsx)(n.code,{children:"ProductUpdateRequest"}),"\uac00 \uc644\uc804\ud788 \ub3d9\uc77c\ud55c\ub370, \uc7ac\uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc744\uae4c? \ub77c\ub294 \ub9ac\ubdf0\ub97c \ub0a8\uacbc\uc5c8\uc5b4\uc694. \uc0ac\uc2e4 \uc0dd\uc131\uacfc \uc218\uc815\uc740 \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac1c\uc5f0\uc131\uc774 \ub192\uc544\uc11c \ubbf8\ub9ac \ubd84\ub9ac\ud574\ub193\ub294 \uac8c \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\uae34 \ud55c\ub370, \uadf8\ub798\ub3c4 \uc911\ubcf5\uc740 \uc2eb\uc5b4\uc11c \uc800\ub3c4 \uc694\uc998 \uc774\ub7f0\uc800\ub7f0 \ubc29\ubc95\ub4e4\uc744 \uc2dc\ub3c4\ud574\ubcf4\ub294 \uc911 \uc785\ub2c8\ub2e4. \ud5c8\ube0c\ub294 \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc5b4\ub5a4 \uc0dd\uac01\uc744 \uac00\uc9c0\uace0 \uc788\uc744\uc9c0 \uad81\uae08\ud558\ub124\uc694 \u314e\u314e"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\uc9c8\ubb38\uc5d0 \ub300\ud574 \uc544\ub798\uc640 \uac19\uc774 \ub2f5\ubcc0\uc744 \ud588\ub2e4."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uc800\uc7a5\uacfc \uc218\uc815\ud560 \ub54c \ud544\uc694\ud55c \ud544\ub4dc\uac12\uc774 \ub3d9\uc77c\ud558\uc5ec \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c\ub294 \ud558\ub098\ub85c \uc0ac\uc6a9\ud574\ub3c4 \ub41c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud558\uc9c0\ub9cc, \ub9d0\uc500\ud574\uc8fc\uc2e0\ub300\ub85c \uc694\uad6c\uc0ac\ud56d\uc774 \ubcc0\uacbd\ub41c\ub2e4\uba74 \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\ub2e4\uace0 \ud310\ub2e8\ud558\uc600\uc2b5\ub2c8\ub2e4!"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc911\ubcf5\uacfc-\uc6b0\ubc1c\uc801-\uc911\ubcf5",children:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5"}),"\n",(0,t.jsx)(n.p,{children:"\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec\uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uac70\uc9d3\ub41c \uc911\ubcf5, \uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131\uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.\n\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc704 \uc0c1\ud669\uc740 \uc6b0\ubc1c\uc801 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc778\ub2e4. \uadf8\ub798\ub3c4 \uc911\ubcf5\uc744 \uc81c\uac70\ud574\ubcfc \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?"}),"\n",(0,t.jsx)(n.h3,{id:"\ud558\ub098\ub85c-\uc0ac\uc6a9\ud558\ub294-\uac74-\uc548\uc88b\uc544\ubcf4\uc774\uace0-\uc911\ubcf5\uc740-\uc81c\uac70\ud558\uace0-\uc2f6\uc740-\ub9c8\uc74c",children:"\ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c"}),"\n",(0,t.jsxs)(n.p,{children:["\uc9c0\uae08\uc740 \ucd94\uac00, \uc218\uc815 2\uac00\uc9c0 \uacbd\uc6b0 \ubc16\uc5d0 \uc5c6\uc9c0\ub9cc \uc870\uae08 \ub354 \ubcf5\uc7a1\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc8fc\uc5b4\uc838\uc11c 10\uac00\uc9c0 \uacbd\uc6b0\ub85c \uc785\ub825\uc744 \ubc1b\uc73c\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c\ud560\uae4c?",(0,t.jsx)(n.br,{}),"\n","\uc11c\ube44\uc2a4 \uacc4\uce35\uc5d0\uc11c\ub3c4 \uacc4\uce35\uc758 \ubd84\ub9ac\ub97c \uc704\ud574\uc11c \ub2e4\ub978 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uba74 20\uac1c\uc758 DTO\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud560\uae4c?",(0,t.jsx)(n.br,{}),"\n","\ub9ac\ubdf0\uc5b4\uac00 \uc54c\ub824\uc900 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \ud1b5\ud574 \uc774\ub97c \ud574\uacb0\ud574\ubcf4\uc790!"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc911\ubcf5-\uc81c\uac70-\uc804-\ucf54\ub4dc",children:"\uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc"}),"\n",(0,t.jsxs)(n.p,{children:["\ud604\uc7ac \ucf54\ub4dc\uc5d0\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Controller\uc640 Service\uc5d0\uc11c \uc800\uc7a5, \uc218\uc815\ud560 \ub54c \uac01\uac01\uc758 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.\n\ud604\uc7ac DTO\ub294 controller, service \ud328\ud0a4\uc9c0 \ub0b4\uc5d0 \uc788\ub294 \uac83\uc774 \uc544\ub2c8\ub77c dto\ub77c\ub294 \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\ud558\uace0 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductService\n\u251c\u2500\u2500 dto\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"\uc911\ubcf52",src:r(12314).Z+"",width:"1528",height:"912"})}),"\n",(0,t.jsx)(n.h3,{id:"\uc778\ud130\ud398\uc774\uc2a4-\uc791\uc131\ud558\uae30",children:"\uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"\uc911\ubcf53",src:r(56531).Z+"",width:"1518",height:"904"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc11c\ube44\uc2a4 \ub808\uc774\uc5b4\uc5d0\uc11c \ud544\uc694\ub85c \ud558\ub294 \uac12\ub4e4\uc744 \uc778\ud130\ud398\uc774\uc2a4\ub85c \uc815\uc758\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \uc11c\ube44\uc2a4\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 service \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub85c \uc62e\uaca8\uc900\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"public interface ProductSaveRequest {\n\n String getName();\n\n String getImage();\n\n Long getPrice();\n}\n\n// ProductService\npublic Long save(final ProductSaveRequest request) {\n final Product product = new Product(request.getName(), request.getImage(), request.getPrice());\n return productDao.saveAndGetId(product);\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\uad6c\ud604\uccb4-\uc791\uc131\ud558\uae30",children:"\uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"\uc911\ubcf54",src:r(82237).Z+"",width:"1508",height:"896"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc704\uc5d0\uc11c \uc791\uc131\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc791\uc131\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc694\uccad\uc740 ProductRequest \ud074\ub798\uc2a4\ub85c \ubc1b\uace0, \uc11c\ube44\uc2a4\uc5d0 \uc804\ub2ec\ud560 \ub550 \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\uc758 \uba85\uc138\ub9cc \ub9de\ucd94\uba74 \ubb38\uc81c\uc5c6\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductController\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductRequest\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {\n\n @NotBlank(message = "\uc774\ub984\uc740 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.")\n @Size(min = 1, max = 100, message = "\uc774\ub984\uc740 \ucd5c\uc18c {min}\uc790 \uc774\uc0c1, {max}\uc790 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.")\n private final String name;\n\n @NotBlank(message = "\uc774\ubbf8\uc9c0\ub294 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.")\n private final String image;\n\n @Range(message = "\uac00\uaca9\uc740 \ucd5c\uc18c {min}\uc6d0 \uc774\uc0c1, {max}\uc6d0 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.")\n private final long price;\n\n public ProductRequest(final String name, final String image, final long price) {\n this.name = name;\n this.image = image;\n this.price = price;\n }\n\n @Override\n public String getName() {\n return name;\n }\n\n @Override\n public String getImage() {\n return image;\n }\n\n @Override\n public long getPrice() {\n return price;\n }\n}\n\n// ProductController\n@PostMapping("/products")\npublic ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {\n final Long id = productService.save(request);\n return ResponseEntity.created(URI.create("/products/" + id)).build();\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"\uc815\ub9ac",children:"\uc815\ub9ac"}),"\n",(0,t.jsx)(n.p,{children:"\uc704\uc640 \uac19\uc774 \uad6c\ud604\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc744 \uc5bb\uc744 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Service\uc5d0\uc11c \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc694\uccad\uc5d0 \ub300\ud55c DTO\ub97c \uc54c\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uacf5\ud1b5\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 DTO\ub97c \uc81c\uc678\ud558\uace0 DTO \ud328\ud0a4\uc9c0\uc5d0 \ub300\ud55c \uacb0\ud569\ub3c4\uac00 \ub0ae\uc544\uc9c0\uace0, \uac01 \ub808\uc774\uc5b4\uc758 \uc751\uc9d1\ub3c4\uac00 \uc99d\uac00\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uc694\uccad \uac1d\uccb4\ub9cc \ub2e4\ub974\uace0 \uc11c\ube44\uc2a4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ud589\uc704\ub97c \uc218\ud589\ud558\ub294 \uacbd\uc6b0 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\uc704 \ubc29\ubc95\uc744 \uc9c0\uae08 \ubbf8\uc158\uc5d0\uc11c \ubc14\ub85c \uc801\uc6a9\ud560\uae4c \ud558\ub2e4\uac00, \ub098\uc911\uc5d0 \ud544\uc694\ud560 \ub54c \uc801\uc6a9\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\uc544\uc11c \ubbf8\uc158\uc5d0\ub294 \uc801\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc0c1\ud669\uc5d0 \ub9de\ucdb0 \uc801\uc7ac\uc801\uc18c\uc5d0 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud574\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:["\ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98 16\uc7a5 \ub3c5\ub9bd\uc131, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://techblog.woowahan.com/2647/",children:"https://techblog.woowahan.com/2647/"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/",children:"https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/"})]})]})}function u(e={}){const{wrapper:n}={...(0,c.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>o});var t=r(67294);function c(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){c(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function l(e,n){if(null==e)return{};var r,t,c=function(e,n){if(null==e)return{};var r,t,c={},i=Object.keys(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||(c[r]=e[r]);return c}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var a=t.createContext({}),o=function(e){var n=t.useContext(a),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var r=e.components,c=e.mdxType,i=e.originalType,a=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=o(r),h=c,g=p["".concat(a,".").concat(h)]||p[h]||d[h]||i;return r?t.createElement(g,s(s({ref:n},u),{},{components:r})):t.createElement(g,s({ref:n},u))}));u.displayName="MDXCreateElement"},92725:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/\uc911\ubcf51-ccd4f91674b224578f2b295b3fccaf2c.png"},12314:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/\uc911\ubcf52-0b4f9f493909fc139f0e4579f7569a6b.png"},56531:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/\uc911\ubcf53-1b6b93bc790ba29844083df5b70dbd2c.png"},82237:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/\uc911\ubcf54-15b381e0a024487f54608d438e5385f9.png"}}]); \ No newline at end of file diff --git a/assets/js/70834889.15e53e1e.js b/assets/js/70834889.15e53e1e.js new file mode 100644 index 000000000..5a7fa11c8 --- /dev/null +++ b/assets/js/70834889.15e53e1e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7344],{56135:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=n(85893),s=n(3905);const i={title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",slug:"performance-test-type",tags:["performance test"]},a=void 0,o={permalink:"/performance-test-type",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",source:"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",description:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8",date:"2023-09-10T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 10\uc77c",tags:[{label:"performance test",permalink:"/tags/performance-test"}],readingTime:5.8,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",slug:"performance-test-type",tags:["performance test"]},unlisted:!1,prevItem:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/tomcat-retrospective"},nextItem:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",permalink:"/db-replication"}},l={authorsImageUrls:[]},c=[{value:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8",id:"\uc131\ub2a5-\ud14c\uc2a4\ud2b8",level:2},{value:"\uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)",id:"\uc2a4\ubaa8\ud06c-\ud14c\uc2a4\ud2b8smoke-test",level:3},{value:"\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)",id:"\uc2a4\ud30c\uc774\ud06c-\ud14c\uc2a4\ud2b8spike-test",level:3},{value:"\ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)",id:"\ubd80\ud558-\ud14c\uc2a4\ud2b8load-test",level:3},{value:"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test)",id:"\uc2a4\ud2b8\ub808\uc2a4-\ud14c\uc2a4\ud2b8stress-test",level:3},{value:"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test)",id:"\ub0b4\uad6c-\ud14c\uc2a4\ud2b8endurance-test",level:3},{value:"\uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)",id:"\uc911\ub2e8\uc810-\ud14c\uc2a4\ud2b8breakpoint-test",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const t={a:"a",admonition:"admonition",br:"br",h2:"h2",h3:"h3",img:"img",p:"p",...(0,s.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h2,{id:"\uc131\ub2a5-\ud14c\uc2a4\ud2b8",children:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsx)(t.p,{children:"API\uc758 \uc694\uccad\uc774 \ub9ce\uc740 \uc0c1\ud669\uc5d0\uc11c \uc11c\ubc84\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2dc\uc2a4\ud15c\uc5d0 \ubd80\ud558\uac00 \uac78\ub9ac\uba74 \ubb38\uc81c \uc0c1\ud669\uc774 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\uc591\ud55c \uc0c1\ud669\uc5d0 \ub300\ube44\ud574\uc11c \uc131\ub2a5 \ud14c\uc2a4\ud2b8\ub97c \ud574\uc57c\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"./test.png",src:n(38715).Z+"",width:"2168",height:"1002"})}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ubaa8\ud06c-\ud14c\uc2a4\ud2b8smoke-test",children:"\uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)"}),"\n",(0,r.jsx)(t.p,{children:"\ucd5c\uc18c\ud55c\uc758 \ubd80\ud558\ub97c \uc8fc\uc5b4 \uc2dc\uc2a4\ud15c\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["VU\ub97c \ucd5c\uc18c\ud55c\uc73c\ub85c \ub450\uace0, \uc9e7\uc740 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \ud14c\uc2a4\ud2b8\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \uc2dc\uc791\ud558\uae30 \uc804\uc5d0 \uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud568\uc73c\ub85c\uc368 \ud14c\uc2a4\ud2b8 \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc624\ub958\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\uace0, \uc131\ub2a5 \uc9c0\ud45c\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \uc218\uc9d1, \ubaa8\ub2c8\ud130\ub9c1 \ub418\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.admonition,{title:"\uac00\uc0c1 \uc0ac\uc6a9\uc790(VU)",type:"note",children:(0,r.jsxs)(t.p,{children:["\uac00\uc0c1 \uc0ac\uc6a9\uc790\ub294 \uc11c\ubc84 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0 \ub300\ud574 \ud2b9\uc815 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub294 \ub2e4\ub978 \uac00\uc0c1 \uc0ac\uc6a9\uc790\uc640 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589\ub418\uba70, \uc5ec\ub7ec \uac00\uc0c1 \uc0ac\uc6a9\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub3d9\uc2dc \uc5f0\uacb0\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc2a4\ub808\ub4dc\ub77c\uace0 \uc0dd\uac01\ud558\uba74 \ub41c\ub2e4."]})}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ud30c\uc774\ud06c-\ud14c\uc2a4\ud2b8spike-test",children:"\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)"}),"\n",(0,r.jsx)(t.p,{children:"\uc0ac\uc6a9\ub7c9\uc774 \uae09\uc99d\ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uacac\ub514\uace0 \uc131\ub2a5\uc5d0 \ubb38\uc81c\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\ud2f0\ucf13 \ubc1c\uae09, \ud560\uc778 \ucfe0\ud3f0 \ubc1c\uae09\uacfc \uac19\uc740 \uc774\ubca4\ud2b8\ub97c \ud558\ub294 \uacbd\uc6b0 \ub300\uaddc\ubaa8 \ud2b8\ub798\ud53d\uc774 \ub4e4\uc5b4\uc628\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud574 \uae09\uc99d\ud558\ub294 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\uace0, \ubd80\ud558\ub97c \uc798 \ubc84\ud2f0\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ubd80\ud558-\ud14c\uc2a4\ud2b8load-test",children:"\ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)"}),"\n",(0,r.jsx)(t.p,{children:"\ubaa9\ud46f\uac12\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \uacac\ub51c \uc218 \uc788\uc744\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\uc77c\ubc18\uc801\uc778 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub7a8\ud504\uc5c5 \ub610\ub294 \ubb19\ud46f\uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ubd80\ud558 \uae30\uac04\ub3d9\uc548 \uc131\ub2a5\uc774 \ubb38\uc81c\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\uace0, \uc2dc\uc2a4\ud15c \ubcc0\uacbd \ud6c4\uc5d0\ub3c4 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \ub3cc\ub824 \ub3d9\uc77c\ud558\uac8c \ubaa9\ud46f\uac12\uc744 \ucc98\ub9ac\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.admonition,{title:"\ub7a8\ud504 \uc5c5(Ramp-up)",type:"note",children:(0,r.jsx)(t.p,{children:"\ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud574 \uc124\uc815\ud55c \uac00\uc0c1 \uc0ac\uc6a9\uc790 \uc218\uc5d0 \ub3c4\ub2ec\ud558\ub294 \ub370 \uac78\ub9ac\ub294 \uc2dc\uac04"})}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ud2b8\ub808\uc2a4-\ud14c\uc2a4\ud2b8stress-test",children:"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test)"}),"\n",(0,r.jsx)(t.p,{children:"\uc2dc\uc2a4\ud15c\uc758 \ucd5c\ub300\uce58\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \ubc1b\uc558\uc744 \ub54c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\uadf8\ub798\ud504\ub97c \ubd24\uc744 \ub54c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc640 \uc720\uc0ac\ud55c \ud615\ud0dc\ub85c \ubcf4\uc774\uc9c0\ub9cc, \ubd80\ud558\ub7c9\uc774 \ub2e4\ub974\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c \ud3c9\uade0\uc801\uc778 \ubaa9\ud46f\uac12 \ub300\ube44 \uc791\uac8c\ub294 50% \uc774\uc0c1, \ud544\uc694\uc758 \uacbd\uc6b0 \uadf8 \uc774\uc0c1\uc73c\ub85c \ubd80\ud558\ub97c \uc900\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub294 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c \ud6c4\uc5d0\ub9cc \uc2e4\ud589\ud574\uc57c \ud55c\ub2e4. \ubd80\ud558 \ud14c\uc2a4\ud2b8\uac00 \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\uc740 \uc0c1\ud669\uc5d0\uc11c \uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ubcd1\ubaa9 \uc9c0\uc810\uc774\ub098 \ubb38\uc81c \uc0c1\ud669\uc744 \ucc3e\uae30 \uc5b4\ub824\uc6cc\uc9c4\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub610\ud55c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \uc0ac\uc6a9\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c VU\uac12(\uc2a4\ub808\ub4dc \uc218)\ub9cc \uc218\uc815\ud558\uc5ec \uc7ac\uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ub0b4\uad6c-\ud14c\uc2a4\ud2b8endurance-test",children:"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test)"}),"\n",(0,r.jsx)(t.p,{children:"\ud3c9\uade0 \uc0ac\uc6a9\ub960\ub85c \uc77c\uc815 \ubd80\ud558\ub97c \uc9c0\uc18d\uc801\uc73c\ub85c \uc8fc\uba70 \uc2dc\uc2a4\ud15c\uc774 \ubb38\uc81c\ub418\ub294 \uc9c0\uc810\uc744 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\ud761\uc218 \ud14c\uc2a4\ud2b8(Soak Test)\ub77c\uace0\ub3c4 \ud558\uba70, \uae30\ubcf8\uc801\uc778 \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc758 \ubcc0\ud615\uc774\ub77c\uace0 \ubcfc \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc640 \ub2ec\ub9ac \uae34 \uc2dc\uac04\ub3d9\uc548 \ud14c\uc2a4\ud2b8\ub97c \ud558\ub294 \uac83\uc774 \ud2b9\uc9d5\uc774\uba70, \uba54\ubaa8\ub9ac \ub204\uc218 \ubb38\uc81c\uc640 \uac19\uc774 \uc7a5\uc2dc\uac04 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc2e4\ud589\ud560 \ub54c \uc2dc\uc2a4\ud15c\uc758 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \ubd80\ubd84\uc744 \ud655\uc778\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uc911\ub2e8\uc810-\ud14c\uc2a4\ud2b8breakpoint-test",children:"\uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)"}),"\n",(0,r.jsx)(t.p,{children:"\uc784\uacc4 \uc9c0\uc810\uc744 \ucc3e\uae30 \uc704\ud574 \ubd80\ud558\ub97c \uc810\uc9c4\uc801\uc73c\ub85c \uc99d\uac00\uc2dc\ud0a4\uba70 \uc9c4\ud589\ud558\ub294 \ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsxs)(t.p,{children:["\ubb38\uc81c\ub418\ub294 \ubd80\ubd84\uc744 \ub354 \ube68\ub9ac \ucc3e\uae30 \uc704\ud574 \ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\uacfc\ud55c \ub2e4\uc74c\uc5d0 \uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud558\uace0, \uc774 \ub54c \uc810\uc9c4\uc801\uc73c\ub85c \ubd80\ud558\ub97c \ub298\ub824\ub098\uac00\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc131\ub2a5 \ud29c\ub2dd\uacfc \ubc18\ubcf5\ud574\uc11c \uc9c4\ud589\ud55c\ub2e4\uba74, \uc2dc\uc2a4\ud15c\uc744 \ub354\uc6b1 \ubc1c\uc804\uc2dc\ud0ac \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub9cc Auto Scaling\uc774 \uc801\uc6a9\ub41c \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd\uc5d0\uc11c\ub294 \uc9c4\ud589\ud558\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://k6.io/docs/test-types/load-test-types/",children:"Load test types, k6"}),(0,r.jsx)(t.br,{}),"\n","\uc790\ubc14 \ucd5c\uc801\ud654 - \ubca4\uc800\ubbfc J. \uc5d0\ubc88\uc2a4, \uc81c\uc784\uc2a4 \uace0\ud504, \ud06c\ub9ac\uc2a4 \ub274\ub79c\ub4dc",(0,r.jsx)(t.br,{}),"\n","\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04"]})]})}function d(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>c});var r=n(67294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,s=function(e,t){if(null==e)return{};var n,r,s={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),h=c(n),u=s,j=h["".concat(l,".").concat(u)]||h[u]||p[u]||i;return n?r.createElement(j,a(a({ref:t},d),{},{components:n})):r.createElement(j,a({ref:t},d))}));d.displayName="MDXCreateElement"},38715:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/test-355aba93f96ef7d6a0f3161bf6a9c25e.png"}}]); \ No newline at end of file diff --git a/assets/js/70834889.7476dcca.js b/assets/js/70834889.7476dcca.js deleted file mode 100644 index a69ed6fb2..000000000 --- a/assets/js/70834889.7476dcca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7344],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>k});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),s=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=s(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,c=o(e,["components","mdxType","originalType","parentName"]),m=s(r),k=a,d=m["".concat(i,".").concat(k)]||m[k]||u[k]||p;return r?n.createElement(d,l(l({ref:t},c),{},{components:r})):n.createElement(d,l({ref:t},c))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=m;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var s=2;s<p;s++)l[s]=r[s];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},6777:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>u,frontMatter:()=>p,metadata:()=>o,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",slug:"performance-test-type",tags:["performance test"]},l=void 0,o={permalink:"/performance-test-type",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",source:"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",description:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8",date:"2023-09-10T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 10\uc77c",tags:[{label:"performance test",permalink:"/tags/performance-test"}],readingTime:5.8,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",slug:"performance-test-type",tags:["performance test"]},prevItem:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/tomcat-retrospective"},nextItem:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",permalink:"/db-replication"}},i={authorsImageUrls:[]},s=[{value:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8",id:"\uc131\ub2a5-\ud14c\uc2a4\ud2b8",level:2},{value:"\uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)",id:"\uc2a4\ubaa8\ud06c-\ud14c\uc2a4\ud2b8smoke-test",level:3},{value:"\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)",id:"\uc2a4\ud30c\uc774\ud06c-\ud14c\uc2a4\ud2b8spike-test",level:3},{value:"\ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)",id:"\ubd80\ud558-\ud14c\uc2a4\ud2b8load-test",level:3},{value:"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test)",id:"\uc2a4\ud2b8\ub808\uc2a4-\ud14c\uc2a4\ud2b8stress-test",level:3},{value:"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test)",id:"\ub0b4\uad6c-\ud14c\uc2a4\ud2b8endurance-test",level:3},{value:"\uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)",id:"\uc911\ub2e8\uc810-\ud14c\uc2a4\ud2b8breakpoint-test",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:s};function u(e){let{components:t,...p}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,p,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\uc131\ub2a5-\ud14c\uc2a4\ud2b8"},"\uc131\ub2a5 \ud14c\uc2a4\ud2b8"),(0,a.kt)("p",null,"API\uc758 \uc694\uccad\uc774 \ub9ce\uc740 \uc0c1\ud669\uc5d0\uc11c \uc11c\ubc84\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8"),(0,a.kt)("p",null,"\uc2dc\uc2a4\ud15c\uc5d0 \ubd80\ud558\uac00 \uac78\ub9ac\uba74 \ubb38\uc81c \uc0c1\ud669\uc774 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc591\ud55c \uc0c1\ud669\uc5d0 \ub300\ube44\ud574\uc11c \uc131\ub2a5 \ud14c\uc2a4\ud2b8\ub97c \ud574\uc57c\ud55c\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./test.png",src:r(38715).Z,width:"2168",height:"1002"})),(0,a.kt)("h3",{id:"\uc2a4\ubaa8\ud06c-\ud14c\uc2a4\ud2b8smoke-test"},"\uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)"),(0,a.kt)("p",null,"\ucd5c\uc18c\ud55c\uc758 \ubd80\ud558\ub97c \uc8fc\uc5b4 \uc2dc\uc2a4\ud15c\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"VU\ub97c \ucd5c\uc18c\ud55c\uc73c\ub85c \ub450\uace0, \uc9e7\uc740 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \ud14c\uc2a4\ud2b8\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \uc2dc\uc791\ud558\uae30 \uc804\uc5d0 \uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud568\uc73c\ub85c\uc368 \ud14c\uc2a4\ud2b8 \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc624\ub958\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\uace0, \uc131\ub2a5 \uc9c0\ud45c\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \uc218\uc9d1, \ubaa8\ub2c8\ud130\ub9c1 \ub418\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("admonition",{title:"\uac00\uc0c1 \uc0ac\uc6a9\uc790(VU)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\uac00\uc0c1 \uc0ac\uc6a9\uc790\ub294 \uc11c\ubc84 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0 \ub300\ud574 \ud2b9\uc815 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 \ub2e4\ub978 \uac00\uc0c1 \uc0ac\uc6a9\uc790\uc640 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589\ub418\uba70, \uc5ec\ub7ec \uac00\uc0c1 \uc0ac\uc6a9\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub3d9\uc2dc \uc5f0\uacb0\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ub808\ub4dc\ub77c\uace0 \uc0dd\uac01\ud558\uba74 \ub41c\ub2e4. ")),(0,a.kt)("h3",{id:"\uc2a4\ud30c\uc774\ud06c-\ud14c\uc2a4\ud2b8spike-test"},"\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)"),(0,a.kt)("p",null,"\uc0ac\uc6a9\ub7c9\uc774 \uae09\uc99d\ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uacac\ub514\uace0 \uc131\ub2a5\uc5d0 \ubb38\uc81c\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"\ud2f0\ucf13 \ubc1c\uae09, \ud560\uc778 \ucfe0\ud3f0 \ubc1c\uae09\uacfc \uac19\uc740 \uc774\ubca4\ud2b8\ub97c \ud558\ub294 \uacbd\uc6b0 \ub300\uaddc\ubaa8 \ud2b8\ub798\ud53d\uc774 \ub4e4\uc5b4\uc628\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud574 \uae09\uc99d\ud558\ub294 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\uace0, \ubd80\ud558\ub97c \uc798 \ubc84\ud2f0\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\ubd80\ud558-\ud14c\uc2a4\ud2b8load-test"},"\ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)"),(0,a.kt)("p",null,"\ubaa9\ud46f\uac12\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \uacac\ub51c \uc218 \uc788\uc744\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"\uc77c\ubc18\uc801\uc778 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub7a8\ud504\uc5c5 \ub610\ub294 \ubb19\ud46f\uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ubd80\ud558 \uae30\uac04\ub3d9\uc548 \uc131\ub2a5\uc774 \ubb38\uc81c\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\uace0, \uc2dc\uc2a4\ud15c \ubcc0\uacbd \ud6c4\uc5d0\ub3c4 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \ub3cc\ub824 \ub3d9\uc77c\ud558\uac8c \ubaa9\ud46f\uac12\uc744 \ucc98\ub9ac\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("admonition",{title:"\ub7a8\ud504 \uc5c5(Ramp-up)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud574 \uc124\uc815\ud55c \uac00\uc0c1 \uc0ac\uc6a9\uc790 \uc218\uc5d0 \ub3c4\ub2ec\ud558\ub294 \ub370 \uac78\ub9ac\ub294 \uc2dc\uac04")),(0,a.kt)("h3",{id:"\uc2a4\ud2b8\ub808\uc2a4-\ud14c\uc2a4\ud2b8stress-test"},"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test)"),(0,a.kt)("p",null,"\uc2dc\uc2a4\ud15c\uc758 \ucd5c\ub300\uce58\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \ubc1b\uc558\uc744 \ub54c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"\uadf8\ub798\ud504\ub97c \ubd24\uc744 \ub54c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc640 \uc720\uc0ac\ud55c \ud615\ud0dc\ub85c \ubcf4\uc774\uc9c0\ub9cc, \ubd80\ud558\ub7c9\uc774 \ub2e4\ub974\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c \ud3c9\uade0\uc801\uc778 \ubaa9\ud46f\uac12 \ub300\ube44 \uc791\uac8c\ub294 50% \uc774\uc0c1, \ud544\uc694\uc758 \uacbd\uc6b0 \uadf8 \uc774\uc0c1\uc73c\ub85c \ubd80\ud558\ub97c \uc900\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub294 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c \ud6c4\uc5d0\ub9cc \uc2e4\ud589\ud574\uc57c \ud55c\ub2e4. \ubd80\ud558 \ud14c\uc2a4\ud2b8\uac00 \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\uc740 \uc0c1\ud669\uc5d0\uc11c \uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ubcd1\ubaa9 \uc9c0\uc810\uc774\ub098 \ubb38\uc81c \uc0c1\ud669\uc744 \ucc3e\uae30 \uc5b4\ub824\uc6cc\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \uc0ac\uc6a9\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c VU\uac12(\uc2a4\ub808\ub4dc \uc218)\ub9cc \uc218\uc815\ud558\uc5ec \uc7ac\uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. "),(0,a.kt)("h3",{id:"\ub0b4\uad6c-\ud14c\uc2a4\ud2b8endurance-test"},"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test)"),(0,a.kt)("p",null,"\ud3c9\uade0 \uc0ac\uc6a9\ub960\ub85c \uc77c\uc815 \ubd80\ud558\ub97c \uc9c0\uc18d\uc801\uc73c\ub85c \uc8fc\uba70 \uc2dc\uc2a4\ud15c\uc774 \ubb38\uc81c\ub418\ub294 \uc9c0\uc810\uc744 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 "),(0,a.kt)("p",null,"\ud761\uc218 \ud14c\uc2a4\ud2b8(Soak Test)\ub77c\uace0\ub3c4 \ud558\uba70, \uae30\ubcf8\uc801\uc778 \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc758 \ubcc0\ud615\uc774\ub77c\uace0 \ubcfc \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc640 \ub2ec\ub9ac \uae34 \uc2dc\uac04\ub3d9\uc548 \ud14c\uc2a4\ud2b8\ub97c \ud558\ub294 \uac83\uc774 \ud2b9\uc9d5\uc774\uba70, \uba54\ubaa8\ub9ac \ub204\uc218 \ubb38\uc81c\uc640 \uac19\uc774 \uc7a5\uc2dc\uac04 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc2e4\ud589\ud560 \ub54c \uc2dc\uc2a4\ud15c\uc758 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \ubd80\ubd84\uc744 \ud655\uc778\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4. "),(0,a.kt)("h3",{id:"\uc911\ub2e8\uc810-\ud14c\uc2a4\ud2b8breakpoint-test"},"\uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)"),(0,a.kt)("p",null,"\uc784\uacc4 \uc9c0\uc810\uc744 \ucc3e\uae30 \uc704\ud574 \ubd80\ud558\ub97c \uc810\uc9c4\uc801\uc73c\ub85c \uc99d\uac00\uc2dc\ud0a4\uba70 \uc9c4\ud589\ud558\ub294 \ud14c\uc2a4\ud2b8"),(0,a.kt)("p",null,"\ubb38\uc81c\ub418\ub294 \ubd80\ubd84\uc744 \ub354 \ube68\ub9ac \ucc3e\uae30 \uc704\ud574 \ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\uacfc\ud55c \ub2e4\uc74c\uc5d0 \uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud558\uace0, \uc774 \ub54c \uc810\uc9c4\uc801\uc73c\ub85c \ubd80\ud558\ub97c \ub298\ub824\ub098\uac00\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc131\ub2a5 \ud29c\ub2dd\uacfc \ubc18\ubcf5\ud574\uc11c \uc9c4\ud589\ud55c\ub2e4\uba74, \uc2dc\uc2a4\ud15c\uc744 \ub354\uc6b1 \ubc1c\uc804\uc2dc\ud0ac \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub9cc Auto Scaling\uc774 \uc801\uc6a9\ub41c \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd\uc5d0\uc11c\ub294 \uc9c4\ud589\ud558\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://k6.io/docs/test-types/load-test-types/"},"Load test types, k6"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\ubc14 \ucd5c\uc801\ud654 - \ubca4\uc800\ubbfc J. \uc5d0\ubc88\uc2a4, \uc81c\uc784\uc2a4 \uace0\ud504, \ud06c\ub9ac\uc2a4 \ub274\ub79c\ub4dc",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04"))}u.isMDXComponent=!0},38715:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/test-355aba93f96ef7d6a0f3161bf6a9c25e.png"}}]); \ No newline at end of file diff --git a/assets/js/7111.8f25c1dd.js b/assets/js/7111.8f25c1dd.js new file mode 100644 index 000000000..e7df58e67 --- /dev/null +++ b/assets/js/7111.8f25c1dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7111],{67111:(t,e,n)=>{n.d(e,{diagram:()=>et});var a=n(56363),i=n(64218),s=n(93799),r=n(17967),l=(n(27484),n(27856),function(){var t=function(t,e,n,a){for(n=n||{},a=t.length;a--;n[t[a]]=e);return n},e=[1,24],n=[1,25],a=[1,26],i=[1,27],s=[1,28],r=[1,63],l=[1,64],o=[1,65],h=[1,66],d=[1,67],u=[1,68],p=[1,69],y=[1,29],f=[1,30],b=[1,31],g=[1,32],x=[1,33],_=[1,34],m=[1,35],E=[1,36],A=[1,37],S=[1,38],C=[1,39],k=[1,40],O=[1,41],v=[1,42],T=[1,43],w=[1,44],R=[1,45],D=[1,46],N=[1,47],P=[1,48],M=[1,50],j=[1,51],B=[1,52],Y=[1,53],L=[1,54],I=[1,55],U=[1,56],F=[1,57],X=[1,58],z=[1,59],W=[1,60],Q=[14,42],$=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],q=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],V=[1,82],G=[1,83],H=[1,84],K=[1,85],J=[12,14,42],Z=[12,14,33,42],tt=[12,14,33,42,76,77,79,80],et=[12,33],nt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],at={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:function(t,e,n,a,i,s,r){var l=s.length-1;switch(i){case 3:a.setDirection("TB");break;case 4:a.setDirection("BT");break;case 5:a.setDirection("RL");break;case 6:a.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:a.setC4Type(s[l-3]);break;case 19:a.setTitle(s[l].substring(6)),this.$=s[l].substring(6);break;case 20:a.setAccDescription(s[l].substring(15)),this.$=s[l].substring(15);break;case 21:this.$=s[l].trim(),a.setTitle(this.$);break;case 22:case 23:this.$=s[l].trim(),a.setAccDescription(this.$);break;case 28:case 29:s[l].splice(2,0,"ENTERPRISE"),a.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 30:a.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 31:s[l].splice(2,0,"CONTAINER"),a.addContainerBoundary(...s[l]),this.$=s[l];break;case 32:a.addDeploymentNode("node",...s[l]),this.$=s[l];break;case 33:a.addDeploymentNode("nodeL",...s[l]),this.$=s[l];break;case 34:a.addDeploymentNode("nodeR",...s[l]),this.$=s[l];break;case 35:a.popBoundaryParseStack();break;case 39:a.addPersonOrSystem("person",...s[l]),this.$=s[l];break;case 40:a.addPersonOrSystem("external_person",...s[l]),this.$=s[l];break;case 41:a.addPersonOrSystem("system",...s[l]),this.$=s[l];break;case 42:a.addPersonOrSystem("system_db",...s[l]),this.$=s[l];break;case 43:a.addPersonOrSystem("system_queue",...s[l]),this.$=s[l];break;case 44:a.addPersonOrSystem("external_system",...s[l]),this.$=s[l];break;case 45:a.addPersonOrSystem("external_system_db",...s[l]),this.$=s[l];break;case 46:a.addPersonOrSystem("external_system_queue",...s[l]),this.$=s[l];break;case 47:a.addContainer("container",...s[l]),this.$=s[l];break;case 48:a.addContainer("container_db",...s[l]),this.$=s[l];break;case 49:a.addContainer("container_queue",...s[l]),this.$=s[l];break;case 50:a.addContainer("external_container",...s[l]),this.$=s[l];break;case 51:a.addContainer("external_container_db",...s[l]),this.$=s[l];break;case 52:a.addContainer("external_container_queue",...s[l]),this.$=s[l];break;case 53:a.addComponent("component",...s[l]),this.$=s[l];break;case 54:a.addComponent("component_db",...s[l]),this.$=s[l];break;case 55:a.addComponent("component_queue",...s[l]),this.$=s[l];break;case 56:a.addComponent("external_component",...s[l]),this.$=s[l];break;case 57:a.addComponent("external_component_db",...s[l]),this.$=s[l];break;case 58:a.addComponent("external_component_queue",...s[l]),this.$=s[l];break;case 60:a.addRel("rel",...s[l]),this.$=s[l];break;case 61:a.addRel("birel",...s[l]),this.$=s[l];break;case 62:a.addRel("rel_u",...s[l]),this.$=s[l];break;case 63:a.addRel("rel_d",...s[l]),this.$=s[l];break;case 64:a.addRel("rel_l",...s[l]),this.$=s[l];break;case 65:a.addRel("rel_r",...s[l]),this.$=s[l];break;case 66:a.addRel("rel_b",...s[l]),this.$=s[l];break;case 67:s[l].splice(0,1),a.addRel("rel",...s[l]),this.$=s[l];break;case 68:a.updateElStyle("update_el_style",...s[l]),this.$=s[l];break;case 69:a.updateRelStyle("update_rel_style",...s[l]),this.$=s[l];break;case 70:a.updateLayoutConfig("update_layout_config",...s[l]),this.$=s[l];break;case 71:this.$=[s[l]];break;case 72:s[l].unshift(s[l-1]),this.$=s[l];break;case 73:case 75:this.$=s[l].trim();break;case 74:let t={};t[s[l-1].trim()]=s[l].trim(),this.$=t;break;case 76:this.$=""}},table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:Y,68:L,69:I,70:U,71:F,72:X,73:z,74:W},{13:70,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:Y,68:L,69:I,70:U,71:F,72:X,73:z,74:W},{13:71,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:Y,68:L,69:I,70:U,71:F,72:X,73:z,74:W},{13:72,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:Y,68:L,69:I,70:U,71:F,72:X,73:z,74:W},{13:73,19:20,20:21,21:22,22:e,23:n,24:a,26:i,28:s,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:Y,68:L,69:I,70:U,71:F,72:X,73:z,74:W},{14:[1,74]},t(Q,[2,13],{43:23,29:49,30:61,32:62,20:75,34:r,36:l,37:o,38:h,39:d,40:u,41:p,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:Y,68:L,69:I,70:U,71:F,72:X,73:z,74:W}),t(Q,[2,14]),t($,[2,16],{12:[1,76]}),t(Q,[2,36],{12:[1,77]}),t(q,[2,19]),t(q,[2,20]),{25:[1,78]},{27:[1,79]},t(q,[2,23]),{35:80,75:81,76:V,77:G,79:H,80:K},{35:86,75:81,76:V,77:G,79:H,80:K},{35:87,75:81,76:V,77:G,79:H,80:K},{35:88,75:81,76:V,77:G,79:H,80:K},{35:89,75:81,76:V,77:G,79:H,80:K},{35:90,75:81,76:V,77:G,79:H,80:K},{35:91,75:81,76:V,77:G,79:H,80:K},{35:92,75:81,76:V,77:G,79:H,80:K},{35:93,75:81,76:V,77:G,79:H,80:K},{35:94,75:81,76:V,77:G,79:H,80:K},{35:95,75:81,76:V,77:G,79:H,80:K},{35:96,75:81,76:V,77:G,79:H,80:K},{35:97,75:81,76:V,77:G,79:H,80:K},{35:98,75:81,76:V,77:G,79:H,80:K},{35:99,75:81,76:V,77:G,79:H,80:K},{35:100,75:81,76:V,77:G,79:H,80:K},{35:101,75:81,76:V,77:G,79:H,80:K},{35:102,75:81,76:V,77:G,79:H,80:K},{35:103,75:81,76:V,77:G,79:H,80:K},{35:104,75:81,76:V,77:G,79:H,80:K},t(J,[2,59]),{35:105,75:81,76:V,77:G,79:H,80:K},{35:106,75:81,76:V,77:G,79:H,80:K},{35:107,75:81,76:V,77:G,79:H,80:K},{35:108,75:81,76:V,77:G,79:H,80:K},{35:109,75:81,76:V,77:G,79:H,80:K},{35:110,75:81,76:V,77:G,79:H,80:K},{35:111,75:81,76:V,77:G,79:H,80:K},{35:112,75:81,76:V,77:G,79:H,80:K},{35:113,75:81,76:V,77:G,79:H,80:K},{35:114,75:81,76:V,77:G,79:H,80:K},{35:115,75:81,76:V,77:G,79:H,80:K},{20:116,29:49,30:61,32:62,34:r,36:l,37:o,38:h,39:d,40:u,41:p,43:23,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:Y,68:L,69:I,70:U,71:F,72:X,73:z,74:W},{12:[1,118],33:[1,117]},{35:119,75:81,76:V,77:G,79:H,80:K},{35:120,75:81,76:V,77:G,79:H,80:K},{35:121,75:81,76:V,77:G,79:H,80:K},{35:122,75:81,76:V,77:G,79:H,80:K},{35:123,75:81,76:V,77:G,79:H,80:K},{35:124,75:81,76:V,77:G,79:H,80:K},{35:125,75:81,76:V,77:G,79:H,80:K},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},t(Q,[2,15]),t($,[2,17],{21:22,19:130,22:e,23:n,24:a,26:i,28:s}),t(Q,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:e,23:n,24:a,26:i,28:s,34:r,36:l,37:o,38:h,39:d,40:u,41:p,44:y,45:f,46:b,47:g,48:x,49:_,50:m,51:E,52:A,53:S,54:C,55:k,56:O,57:v,58:T,59:w,60:R,61:D,62:N,63:P,64:M,65:j,66:B,67:Y,68:L,69:I,70:U,71:F,72:X,73:z,74:W}),t(q,[2,21]),t(q,[2,22]),t(J,[2,39]),t(Z,[2,71],{75:81,35:132,76:V,77:G,79:H,80:K}),t(tt,[2,73]),{78:[1,133]},t(tt,[2,75]),t(tt,[2,76]),t(J,[2,40]),t(J,[2,41]),t(J,[2,42]),t(J,[2,43]),t(J,[2,44]),t(J,[2,45]),t(J,[2,46]),t(J,[2,47]),t(J,[2,48]),t(J,[2,49]),t(J,[2,50]),t(J,[2,51]),t(J,[2,52]),t(J,[2,53]),t(J,[2,54]),t(J,[2,55]),t(J,[2,56]),t(J,[2,57]),t(J,[2,58]),t(J,[2,60]),t(J,[2,61]),t(J,[2,62]),t(J,[2,63]),t(J,[2,64]),t(J,[2,65]),t(J,[2,66]),t(J,[2,67]),t(J,[2,68]),t(J,[2,69]),t(J,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},t(et,[2,28]),t(et,[2,29]),t(et,[2,30]),t(et,[2,31]),t(et,[2,32]),t(et,[2,33]),t(et,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},t($,[2,18]),t(Q,[2,38]),t(Z,[2,72]),t(tt,[2,74]),t(J,[2,24]),t(J,[2,35]),t(nt,[2,25]),t(nt,[2,26],{12:[1,138]}),t(nt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],a=[],i=[null],s=[],r=this.table,l="",o=0,c=0,h=s.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var y=d.yylloc;s.push(y);var f=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,g,x,_,m,E,A,S,C,k={};;){if(g=n[n.length-1],this.defaultActions[g]?x=this.defaultActions[g]:(null==b&&(C=void 0,"number"!=typeof(C=a.pop()||d.lex()||1)&&(C instanceof Array&&(C=(a=C).pop()),C=e.symbols_[C]||C),b=C),x=r[g]&&r[g][b]),void 0===x||!x.length||!x[0]){var O="";for(m in S=[],r[g])this.terminals_[m]&&m>2&&S.push("'"+this.terminals_[m]+"'");O=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+S.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(O,{text:d.match,token:this.terminals_[b]||b,line:d.yylineno,loc:y,expected:S})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+b);switch(x[0]){case 1:n.push(b),i.push(d.yytext),s.push(d.yylloc),n.push(x[1]),b=null,c=d.yyleng,l=d.yytext,o=d.yylineno,y=d.yylloc;break;case 2:if(E=this.productions_[x[1]][1],k.$=i[i.length-E],k._$={first_line:s[s.length-(E||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(E||1)].first_column,last_column:s[s.length-1].last_column},f&&(k._$.range=[s[s.length-(E||1)].range[0],s[s.length-1].range[1]]),void 0!==(_=this.performAction.apply(k,[l,c,o,u.yy,x[1],i,s].concat(h))))return _;E&&(n=n.slice(0,-1*E*2),i=i.slice(0,-1*E),s=s.slice(0,-1*E)),n.push(this.productions_[x[1]][0]),i.push(k.$),s.push(k._$),A=r[n[n.length-2]][n[n.length-1]],n.push(A);break;case 3:return!0}}return!0}},it={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===a.length?this.yylloc.first_column:0)+a[a.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,a,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var s in i)this[s]=i[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),s=0;s<i.length;s++)if((n=this._input.match(this.rules[i[s]]))&&(!e||n[0].length>e[0].length)){if(e=n,a=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,n,a){switch(n){case 0:return 6;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 22;case 5:return 23;case 6:return this.begin("acc_title"),24;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),26;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 73:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 16:case 70:break;case 14:c;break;case 15:return 12;case 17:return 11;case 18:return 15;case 19:return 16;case 20:return 17;case 21:return 18;case 22:return this.begin("person_ext"),45;case 23:return this.begin("person"),44;case 24:return this.begin("system_ext_queue"),51;case 25:return this.begin("system_ext_db"),50;case 26:return this.begin("system_ext"),49;case 27:return this.begin("system_queue"),48;case 28:return this.begin("system_db"),47;case 29:return this.begin("system"),46;case 30:return this.begin("boundary"),37;case 31:return this.begin("enterprise_boundary"),34;case 32:return this.begin("system_boundary"),36;case 33:return this.begin("container_ext_queue"),57;case 34:return this.begin("container_ext_db"),56;case 35:return this.begin("container_ext"),55;case 36:return this.begin("container_queue"),54;case 37:return this.begin("container_db"),53;case 38:return this.begin("container"),52;case 39:return this.begin("container_boundary"),38;case 40:return this.begin("component_ext_queue"),63;case 41:return this.begin("component_ext_db"),62;case 42:return this.begin("component_ext"),61;case 43:return this.begin("component_queue"),60;case 44:return this.begin("component_db"),59;case 45:return this.begin("component"),58;case 46:case 47:return this.begin("node"),39;case 48:return this.begin("node_l"),40;case 49:return this.begin("node_r"),41;case 50:return this.begin("rel"),64;case 51:return this.begin("birel"),65;case 52:case 53:return this.begin("rel_u"),66;case 54:case 55:return this.begin("rel_d"),67;case 56:case 57:return this.begin("rel_l"),68;case 58:case 59:return this.begin("rel_r"),69;case 60:return this.begin("rel_b"),70;case 61:return this.begin("rel_index"),71;case 62:return this.begin("update_el_style"),72;case 63:return this.begin("update_rel_style"),73;case 64:return this.begin("update_layout_config"),74;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 67:this.begin("attribute");break;case 68:case 79:this.popState(),this.popState();break;case 69:case 71:return 80;case 72:this.begin("string");break;case 74:case 80:return"STR";case 75:this.begin("string_kv");break;case 76:return this.begin("string_kv_key"),"STR_KEY";case 77:this.popState(),this.begin("string_kv_value");break;case 78:return"STR_VALUE";case 81:return"LBRACE";case 82:return"RBRACE";case 83:return"SPACE";case 84:return"EOL";case 85:return 14}},rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},string_kv_value:{rules:[78,79],inclusive:!1},string_kv_key:{rules:[77],inclusive:!1},string_kv:{rules:[76],inclusive:!1},string:{rules:[73,74],inclusive:!1},attribute:{rules:[68,69,70,71,72,75,80],inclusive:!1},update_layout_config:{rules:[65,66,67,68],inclusive:!1},update_rel_style:{rules:[65,66,67,68],inclusive:!1},update_el_style:{rules:[65,66,67,68],inclusive:!1},rel_b:{rules:[65,66,67,68],inclusive:!1},rel_r:{rules:[65,66,67,68],inclusive:!1},rel_l:{rules:[65,66,67,68],inclusive:!1},rel_d:{rules:[65,66,67,68],inclusive:!1},rel_u:{rules:[65,66,67,68],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[65,66,67,68],inclusive:!1},node_r:{rules:[65,66,67,68],inclusive:!1},node_l:{rules:[65,66,67,68],inclusive:!1},node:{rules:[65,66,67,68],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[65,66,67,68],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[65,66,67,68],inclusive:!1},component_ext:{rules:[65,66,67,68],inclusive:!1},component_queue:{rules:[65,66,67,68],inclusive:!1},component_db:{rules:[65,66,67,68],inclusive:!1},component:{rules:[65,66,67,68],inclusive:!1},container_boundary:{rules:[65,66,67,68],inclusive:!1},container_ext_queue:{rules:[65,66,67,68],inclusive:!1},container_ext_db:{rules:[65,66,67,68],inclusive:!1},container_ext:{rules:[65,66,67,68],inclusive:!1},container_queue:{rules:[65,66,67,68],inclusive:!1},container_db:{rules:[65,66,67,68],inclusive:!1},container:{rules:[65,66,67,68],inclusive:!1},birel:{rules:[65,66,67,68],inclusive:!1},system_boundary:{rules:[65,66,67,68],inclusive:!1},enterprise_boundary:{rules:[65,66,67,68],inclusive:!1},boundary:{rules:[65,66,67,68],inclusive:!1},system_ext_queue:{rules:[65,66,67,68],inclusive:!1},system_ext_db:{rules:[65,66,67,68],inclusive:!1},system_ext:{rules:[65,66,67,68],inclusive:!1},system_queue:{rules:[65,66,67,68],inclusive:!1},system_db:{rules:[65,66,67,68],inclusive:!1},system:{rules:[65,66,67,68],inclusive:!1},person_ext:{rules:[65,66,67,68],inclusive:!1},person:{rules:[65,66,67,68],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,82,83,84,85],inclusive:!0}}};function st(){this.yy={}}return at.lexer=it,st.prototype=at,at.Parser=st,new st}());l.parser=l;const o=l;let h=[],d=[""],u="global",p="",y=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],f=[],b="",g=!1,x=4,_=2;var m;const E=function(t){return null==t?h:h.filter((e=>e.parentBoundary===t))},A=function(){return g},S={addPersonOrSystem:function(t,e,n,a,i,s,r){if(null===e||null===n)return;let l={};const o=h.find((t=>t.alias===e));if(o&&e===o.alias?l=o:(l.alias=e,h.push(l)),l.label=null==n?{text:""}:{text:n},null==a)l.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]={text:e}}else l.descr={text:a};if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.sprite=i;if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.tags=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=e}else l.link=r;l.typeC4Shape={text:t},l.parentBoundary=u,l.wrap=A()},addPersonOrSystemBoundary:function(t,e,n,a,i){if(null===t||null===e)return;let s={};const r=y.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,y.push(s)),s.label=null==e?{text:""}:{text:e},null==n)s.type={text:"system"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]={text:e}}else s.type={text:n};if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.tags=a;if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]=e}else s.link=i;s.parentBoundary=u,s.wrap=A(),p=u,u=t,d.push(p)},addContainer:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=h.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,h.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.techn={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=A(),o.typeC4Shape={text:t},o.parentBoundary=u},addContainerBoundary:function(t,e,n,a,i){if(null===t||null===e)return;let s={};const r=y.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,y.push(s)),s.label=null==e?{text:""}:{text:e},null==n)s.type={text:"container"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]={text:e}}else s.type={text:n};if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.tags=a;if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]=e}else s.link=i;s.parentBoundary=u,s.wrap=A(),p=u,u=t,d.push(p)},addComponent:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=h.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,h.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.techn={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=A(),o.typeC4Shape={text:t},o.parentBoundary=u},addDeploymentNode:function(t,e,n,a,i,s,r,l){if(null===e||null===n)return;let o={};const c=y.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,y.push(o)),o.label=null==n?{text:""}:{text:n},null==a)o.type={text:"node"};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.type={text:a};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.nodeType=t,o.parentBoundary=u,o.wrap=A(),p=u,u=e,d.push(p)},popBoundaryParseStack:function(){u=p,d.pop(),p=d.pop(),d.push(p)},addRel:function(t,e,n,a,i,s,r,l,o){if(null==t||null==e||null==n||null==a)return;let c={};const h=f.find((t=>t.from===e&&t.to===n));if(h?c=h:f.push(c),c.type=t,c.from=e,c.to=n,c.label={text:a},null==i)c.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];c[t]={text:e}}else c.techn={text:i};if(null==s)c.descr={text:""};else if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]={text:e}}else c.descr={text:s};if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]=e}else c.sprite=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];c[t]=e}else c.tags=l;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=A()},updateElStyle:function(t,e,n,a,i,s,r,l,o,c,d){let u=h.find((t=>t.alias===e));if(void 0!==u||(u=y.find((t=>t.alias===e)),void 0!==u)){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];u[t]=e}else u.bgColor=n;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];u[t]=e}else u.fontColor=a;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];u[t]=e}else u.borderColor=i;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];u[t]=e}else u.shadowing=s;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];u[t]=e}else u.shape=r;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];u[t]=e}else u.sprite=l;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];u[t]=e}else u.techn=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];u[t]=e}else u.legendText=c;if(null!=d)if("object"==typeof d){let[t,e]=Object.entries(d)[0];u[t]=e}else u.legendSprite=d}},updateRelStyle:function(t,e,n,a,i,s,r){const l=f.find((t=>t.from===e&&t.to===n));if(void 0!==l){if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.textColor=a;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.lineColor=i;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=parseInt(e)}else l.offsetX=parseInt(s);if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=parseInt(e)}else l.offsetY=parseInt(r)}},updateLayoutConfig:function(t,e,n){let a=x,i=_;if("object"==typeof e){const t=Object.values(e)[0];a=parseInt(t)}else a=parseInt(e);if("object"==typeof n){const t=Object.values(n)[0];i=parseInt(t)}else i=parseInt(n);a>=1&&(x=a),i>=1&&(_=i)},autoWrap:A,setWrap:function(t){g=t},getC4ShapeArray:E,getC4Shape:function(t){return h.find((e=>e.alias===t))},getC4ShapeKeys:function(t){return Object.keys(E(t))},getBoundarys:function(t){return null==t?y:y.filter((e=>e.parentBoundary===t))},getCurrentBoundaryParse:function(){return u},getParentBoundaryParse:function(){return p},getRels:function(){return f},getTitle:function(){return b},getC4Type:function(){return m},getC4ShapeInRow:function(){return x},getC4BoundaryInRow:function(){return _},setAccTitle:a.s,getAccTitle:a.g,getAccDescription:a.a,setAccDescription:a.b,getConfig:()=>(0,a.c)().c4,clear:function(){h=[],y=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],p="",u="global",d=[""],f=[],d=[""],b="",g=!1,x=4,_=2},LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:function(t){let e=(0,a.d)(t,(0,a.c)());b=e},setC4Type:function(t){let e=(0,a.d)(t,(0,a.c)());m=e}},C=function(t,e){return(0,s.d)(t,e)},k=function(t,e,n,a,i,s){const l=t.append("image");l.attr("width",e),l.attr("height",n),l.attr("x",a),l.attr("y",i);let o=s.startsWith("data:image/png;base64")?s:(0,r.Nm)(s);l.attr("xlink:href",o)},O=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),v=function(){function t(t,e,n,a,s,r,l){i(e.append("text").attr("x",n+s/2).attr("y",a+r/2+5).style("text-anchor","middle").text(t),l)}function e(t,e,n,s,r,l,o,c){const{fontSize:h,fontFamily:d,fontWeight:u}=c,p=t.split(a.e.lineBreakRegex);for(let a=0;a<p.length;a++){const t=a*h-h*(p.length-1)/2,l=e.append("text").attr("x",n+r/2).attr("y",s).style("text-anchor","middle").attr("dominant-baseline","middle").style("font-size",h).style("font-weight",u).style("font-family",d);l.append("tspan").attr("dy",t).text(p[a]).attr("alignment-baseline","mathematical"),i(l,o)}}function n(t,n,a,s,r,l,o,c){const h=n.append("switch"),d=h.append("foreignObject").attr("x",a).attr("y",s).attr("width",r).attr("height",l).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,a,s,r,0,o,c),i(d,o)}function i(t,e){for(const n in e)e.hasOwnProperty(n)&&t.attr(n,e[n])}return function(a){return"fo"===a.textPlacement?n:"old"===a.textPlacement?t:e}}(),T=function(t,e,n){const a=t.append("g");let i=e.bgColor?e.bgColor:"none",s=e.borderColor?e.borderColor:"#444444",r=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let o={x:e.x,y:e.y,fill:i,stroke:s,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};C(a,o);let c=n.boundaryFont();c.fontWeight="bold",c.fontSize=c.fontSize+2,c.fontColor=r,v(n)(e.label.text,a,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},c),e.type&&""!==e.type.text&&(c=n.boundaryFont(),c.fontColor=r,v(n)(e.type.text,a,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},c)),e.descr&&""!==e.descr.text&&(c=n.boundaryFont(),c.fontSize=c.fontSize-2,c.fontColor=r,v(n)(e.descr.text,a,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},c))},w=function(t,e,n){var a;let i=e.bgColor?e.bgColor:n[e.typeC4Shape.text+"_bg_color"],r=e.borderColor?e.borderColor:n[e.typeC4Shape.text+"_border_color"],l=e.fontColor?e.fontColor:"#FFFFFF",o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":o="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII="}const c=t.append("g");c.attr("class","person-man");const h=(0,s.g)();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":h.x=e.x,h.y=e.y,h.fill=i,h.width=e.width,h.height=e.height,h.stroke=r,h.rx=2.5,h.ry=2.5,h.attrs={"stroke-width":.5},C(c,h);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":c.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),c.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":c.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),c.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2))}let d=O(n,e.typeC4Shape.text);switch(c.append("text").attr("fill",l).attr("font-family",d.fontFamily).attr("font-size",d.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":k(c,48,48,e.x+e.width/2-24,e.y+e.image.Y,o)}let u=n[e.typeC4Shape.text+"Font"]();return u.fontWeight="bold",u.fontSize=u.fontSize+2,u.fontColor=l,v(n)(e.label.text,c,e.x,e.y+e.label.Y,e.width,e.height,{fill:l},u),u=n[e.typeC4Shape.text+"Font"](),u.fontColor=l,e.techn&&""!==(null==(a=e.techn)?void 0:a.text)?v(n)(e.techn.text,c,e.x,e.y+e.techn.Y,e.width,e.height,{fill:l,"font-style":"italic"},u):e.type&&""!==e.type.text&&v(n)(e.type.text,c,e.x,e.y+e.type.Y,e.width,e.height,{fill:l,"font-style":"italic"},u),e.descr&&""!==e.descr.text&&(u=n.personFont(),u.fontColor=l,v(n)(e.descr.text,c,e.x,e.y+e.descr.Y,e.width,e.height,{fill:l},u)),e.height},R=(t,e,n)=>{const a=t.append("g");let i=0;for(let s of e){let t=s.textColor?s.textColor:"#444444",e=s.lineColor?s.lineColor:"#444444",r=s.offsetX?parseInt(s.offsetX):0,l=s.offsetY?parseInt(s.offsetY):0,o="";if(0===i){let t=a.append("line");t.attr("x1",s.startPoint.x),t.attr("y1",s.startPoint.y),t.attr("x2",s.endPoint.x),t.attr("y2",s.endPoint.y),t.attr("stroke-width","1"),t.attr("stroke",e),t.style("fill","none"),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)"),i=-1}else{let t=a.append("path");t.attr("fill","none").attr("stroke-width","1").attr("stroke",e).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",s.startPoint.x).replaceAll("starty",s.startPoint.y).replaceAll("controlx",s.startPoint.x+(s.endPoint.x-s.startPoint.x)/2-(s.endPoint.x-s.startPoint.x)/4).replaceAll("controly",s.startPoint.y+(s.endPoint.y-s.startPoint.y)/2).replaceAll("stopx",s.endPoint.x).replaceAll("stopy",s.endPoint.y)),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)")}let c=n.messageFont();v(n)(s.label.text,a,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+l,s.label.width,s.label.height,{fill:t},c),s.techn&&""!==s.techn.text&&(c=n.messageFont(),v(n)("["+s.techn.text+"]",a,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+n.messageFontSize+5+l,Math.max(s.label.width,s.techn.width),s.techn.height,{fill:t,"font-style":"italic"},c))}},D=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")},N=function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},P=function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},M=function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},j=function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},B=function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},Y=function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")};let L=0,I=0,U=4,F=2;l.yy=S;let X={};class z{constructor(t){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,W(t.db.getConfig())}setData(t,e,n,a){this.nextData.startx=this.data.startx=t,this.nextData.stopx=this.data.stopx=e,this.nextData.starty=this.data.starty=n,this.nextData.stopy=this.data.stopy=a}updateVal(t,e,n,a){void 0===t[e]?t[e]=n:t[e]=a(n,t[e])}insert(t){this.nextData.cnt=this.nextData.cnt+1;let e=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+t.margin:this.nextData.stopx+2*t.margin,n=e+t.width,a=this.nextData.starty+2*t.margin,i=a+t.height;(e>=this.data.widthLimit||n>=this.data.widthLimit||this.nextData.cnt>U)&&(e=this.nextData.startx+t.margin+X.nextLinePaddingX,a=this.nextData.stopy+2*t.margin,this.nextData.stopx=n=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=i=a+t.height,this.nextData.cnt=1),t.x=e,t.y=a,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",a,Math.min),this.updateVal(this.data,"stopx",n,Math.max),this.updateVal(this.data,"stopy",i,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",a,Math.min),this.updateVal(this.nextData,"stopx",n,Math.max),this.updateVal(this.nextData,"stopy",i,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},W(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}}const W=function(t){(0,a.f)(X,t),t.fontFamily&&(X.personFontFamily=X.systemFontFamily=X.messageFontFamily=t.fontFamily),t.fontSize&&(X.personFontSize=X.systemFontSize=X.messageFontSize=t.fontSize),t.fontWeight&&(X.personFontWeight=X.systemFontWeight=X.messageFontWeight=t.fontWeight)},Q=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),$=t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight});function q(t,e,n,i,s){if(!e[t].width)if(n)e[t].text=(0,a.w)(e[t].text,s,i),e[t].textLines=e[t].text.split(a.e.lineBreakRegex).length,e[t].width=s,e[t].height=(0,a.j)(e[t].text,i);else{let n=e[t].text.split(a.e.lineBreakRegex);e[t].textLines=n.length;let s=0;e[t].height=0,e[t].width=0;for(const r of n)e[t].width=Math.max((0,a.h)(r,i),e[t].width),s=(0,a.j)(r,i),e[t].height=e[t].height+s}}const V=function(t,e,n){e.x=n.data.startx,e.y=n.data.starty,e.width=n.data.stopx-n.data.startx,e.height=n.data.stopy-n.data.starty,e.label.y=X.c4ShapeMargin-35;let i=e.wrap&&X.wrap,s=$(X);s.fontSize=s.fontSize+2,s.fontWeight="bold",q("label",e,i,s,(0,a.h)(e.label.text,s)),T(t,e,X)},G=function(t,e,n,i){let s=0;for(const r of i){s=0;const i=n[r];let l=Q(X,i.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,i.typeC4Shape.width=(0,a.h)("\xab"+i.typeC4Shape.text+"\xbb",l),i.typeC4Shape.height=l.fontSize+2,i.typeC4Shape.Y=X.c4ShapePadding,s=i.typeC4Shape.Y+i.typeC4Shape.height-4,i.image={width:0,height:0,Y:0},i.typeC4Shape.text){case"person":case"external_person":i.image.width=48,i.image.height=48,i.image.Y=s,s=i.image.Y+i.image.height}i.sprite&&(i.image.width=48,i.image.height=48,i.image.Y=s,s=i.image.Y+i.image.height);let o=i.wrap&&X.wrap,c=X.width-2*X.c4ShapePadding,h=Q(X,i.typeC4Shape.text);if(h.fontSize=h.fontSize+2,h.fontWeight="bold",q("label",i,o,h,c),i.label.Y=s+8,s=i.label.Y+i.label.height,i.type&&""!==i.type.text){i.type.text="["+i.type.text+"]",q("type",i,o,Q(X,i.typeC4Shape.text),c),i.type.Y=s+5,s=i.type.Y+i.type.height}else if(i.techn&&""!==i.techn.text){i.techn.text="["+i.techn.text+"]",q("techn",i,o,Q(X,i.techn.text),c),i.techn.Y=s+5,s=i.techn.Y+i.techn.height}let d=s,u=i.label.width;if(i.descr&&""!==i.descr.text){q("descr",i,o,Q(X,i.typeC4Shape.text),c),i.descr.Y=s+20,s=i.descr.Y+i.descr.height,u=Math.max(i.label.width,i.descr.width),d=s-5*i.descr.textLines}u+=X.c4ShapePadding,i.width=Math.max(i.width||X.width,u,X.width),i.height=Math.max(i.height||X.height,d,X.height),i.margin=i.margin||X.c4ShapeMargin,t.insert(i),w(e,i,X)}t.bumpLastMargin(X.c4ShapeMargin)};class H{constructor(t,e){this.x=t,this.y=e}}let K=function(t,e){let n=t.x,a=t.y,i=e.x,s=e.y,r=n+t.width/2,l=a+t.height/2,o=Math.abs(n-i),c=Math.abs(a-s),h=c/o,d=t.height/t.width,u=null;return a==s&&n<i?u=new H(n+t.width,l):a==s&&n>i?u=new H(n,l):n==i&&a<s?u=new H(r,a+t.height):n==i&&a>s&&(u=new H(r,a)),n>i&&a<s?u=d>=h?new H(n,l+h*t.width/2):new H(r-o/c*t.height/2,a+t.height):n<i&&a<s?u=d>=h?new H(n+t.width,l+h*t.width/2):new H(r+o/c*t.height/2,a+t.height):n<i&&a>s?u=d>=h?new H(n+t.width,l-h*t.width/2):new H(r+t.height/2*o/c,a):n>i&&a>s&&(u=d>=h?new H(n,l-t.width/2*h):new H(r-t.height/2*o/c,a)),u},J=function(t,e){let n={x:0,y:0};n.x=e.x+e.width/2,n.y=e.y+e.height/2;let a=K(t,n);return n.x=t.x+t.width/2,n.y=t.y+t.height/2,{startPoint:a,endPoint:K(e,n)}};function Z(t,e,n,a,i){let s=new z(i);s.data.widthLimit=n.data.widthLimit/Math.min(F,a.length);for(let[r,l]of a.entries()){let a=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=a,a=l.image.Y+l.image.height);let o=l.wrap&&X.wrap,c=$(X);if(c.fontSize=c.fontSize+2,c.fontWeight="bold",q("label",l,o,c,s.data.widthLimit),l.label.Y=a+8,a=l.label.Y+l.label.height,l.type&&""!==l.type.text){l.type.text="["+l.type.text+"]",q("type",l,o,$(X),s.data.widthLimit),l.type.Y=a+5,a=l.type.Y+l.type.height}if(l.descr&&""!==l.descr.text){let t=$(X);t.fontSize=t.fontSize-2,q("descr",l,o,t,s.data.widthLimit),l.descr.Y=a+20,a=l.descr.Y+l.descr.height}if(0==r||r%F==0){let t=n.data.startx+X.diagramMarginX,e=n.data.stopy+X.diagramMarginY+a;s.setData(t,t,e,e)}else{let t=s.data.stopx!==s.data.startx?s.data.stopx+X.diagramMarginX:s.data.startx,e=s.data.starty;s.setData(t,t,e,e)}s.name=l.alias;let h=i.db.getC4ShapeArray(l.alias),d=i.db.getC4ShapeKeys(l.alias);d.length>0&&G(s,t,h,d),e=l.alias;let u=i.db.getBoundarys(e);u.length>0&&Z(t,e,s,u,i),"global"!==l.alias&&V(t,l,s),n.data.stopy=Math.max(s.data.stopy+X.c4ShapeMargin,n.data.stopy),n.data.stopx=Math.max(s.data.stopx+X.c4ShapeMargin,n.data.stopx),L=Math.max(L,n.data.stopx),I=Math.max(I,n.data.stopy)}}const tt={drawPersonOrSystemArray:G,drawBoundary:V,setConf:W,draw:function(t,e,n,s){X=(0,a.c)().c4;const r=(0,a.c)().securityLevel;let l;"sandbox"===r&&(l=(0,i.Ys)("#i"+e));const o="sandbox"===r?(0,i.Ys)(l.nodes()[0].contentDocument.body):(0,i.Ys)("body");let c=s.db;s.db.setWrap(X.wrap),U=c.getC4ShapeInRow(),F=c.getC4BoundaryInRow(),a.l.debug(`C:${JSON.stringify(X,null,2)}`);const h="sandbox"===r?o.select(`[id="${e}"]`):(0,i.Ys)(`[id="${e}"]`);B(h),j(h),Y(h);let d=new z(s);d.setData(X.diagramMarginX,X.diagramMarginX,X.diagramMarginY,X.diagramMarginY),d.data.widthLimit=screen.availWidth,L=X.diagramMarginX,I=X.diagramMarginY;const u=s.db.getTitle();Z(h,"",d,s.db.getBoundarys(""),s),D(h),N(h),M(h),P(h),function(t,e,n,i){let s=0;for(let l of e){s+=1;let t=l.wrap&&X.wrap,e={fontFamily:(r=X).messageFontFamily,fontSize:r.messageFontSize,fontWeight:r.messageFontWeight};"C4Dynamic"===i.db.getC4Type()&&(l.label.text=s+": "+l.label.text);let o=(0,a.h)(l.label.text,e);q("label",l,t,e,o),l.techn&&""!==l.techn.text&&(o=(0,a.h)(l.techn.text,e),q("techn",l,t,e,o)),l.descr&&""!==l.descr.text&&(o=(0,a.h)(l.descr.text,e),q("descr",l,t,e,o));let c=n(l.from),h=n(l.to),d=J(c,h);l.startPoint=d.startPoint,l.endPoint=d.endPoint}var r;R(t,e,X)}(h,s.db.getRels(),s.db.getC4Shape,s),d.data.stopx=L,d.data.stopy=I;const p=d.data;let y=p.stopy-p.starty+2*X.diagramMarginY;const f=p.stopx-p.startx+2*X.diagramMarginX;u&&h.append("text").text(u).attr("x",(p.stopx-p.startx)/2-4*X.diagramMarginX).attr("y",p.starty+X.diagramMarginY),(0,a.i)(h,y,f,X.useMaxWidth);const b=u?60:0;h.attr("viewBox",p.startx-X.diagramMarginX+" -"+(X.diagramMarginY+b)+" "+f+" "+(y+b)),a.l.debug("models:",p)}},et={parser:o,db:S,renderer:tt,styles:t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`,init:({c4:t,wrap:e})=>{tt.setConf(t),S.setWrap(e)}}},93799:(t,e,n)=>{n.d(e,{a:()=>r,b:()=>c,c:()=>o,d:()=>s,e:()=>d,f:()=>l,g:()=>h});var a=n(17967),i=n(56363);const s=(t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),void 0!==e.rx&&n.attr("rx",e.rx),void 0!==e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const a in e.attrs)n.attr(a,e.attrs[a]);return void 0!==e.class&&n.attr("class",e.class),n},r=(t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};s(t,n).lower()},l=(t,e)=>{const n=e.text.replace(i.H," "),a=t.append("text");a.attr("x",e.x),a.attr("y",e.y),a.attr("class","legend"),a.style("text-anchor",e.anchor),void 0!==e.class&&a.attr("class",e.class);const s=a.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(n),a},o=(t,e,n,i)=>{const s=t.append("image");s.attr("x",e),s.attr("y",n);const r=(0,a.Nm)(i);s.attr("xlink:href",r)},c=(t,e,n,i)=>{const s=t.append("use");s.attr("x",e),s.attr("y",n);const r=(0,a.Nm)(i);s.attr("xlink:href",`#${r}`)},h=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),d=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})}}]); \ No newline at end of file diff --git a/assets/js/715.7c02bf77.js b/assets/js/715.7c02bf77.js new file mode 100644 index 000000000..a605586a7 --- /dev/null +++ b/assets/js/715.7c02bf77.js @@ -0,0 +1,1758 @@ +"use strict"; +exports.id = 715; +exports.ids = [715]; +exports.modules = { + +/***/ 46715: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(20683); + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 3], $V1 = [1, 6], $V2 = [1, 4], $V3 = [1, 5], $V4 = [2, 5], $V5 = [1, 12], $V6 = [5, 7, 13, 19, 21, 23, 24, 26, 28, 31, 36, 39, 46], $V7 = [7, 13, 19, 21, 23, 24, 26, 28, 31, 36, 39], $V8 = [7, 12, 13, 19, 21, 23, 24, 26, 28, 31, 36, 39], $V9 = [7, 13, 46], $Va = [1, 42], $Vb = [1, 41], $Vc = [7, 13, 29, 32, 34, 37, 46], $Vd = [1, 55], $Ve = [1, 56], $Vf = [1, 57], $Vg = [7, 13, 32, 34, 41, 46]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "eol": 4, "GG": 5, "document": 6, "EOF": 7, ":": 8, "DIR": 9, "options": 10, "body": 11, "OPT": 12, "NL": 13, "line": 14, "statement": 15, "commitStatement": 16, "mergeStatement": 17, "cherryPickStatement": 18, "acc_title": 19, "acc_title_value": 20, "acc_descr": 21, "acc_descr_value": 22, "acc_descr_multiline_value": 23, "section": 24, "branchStatement": 25, "CHECKOUT": 26, "ref": 27, "BRANCH": 28, "ORDER": 29, "NUM": 30, "CHERRY_PICK": 31, "COMMIT_ID": 32, "STR": 33, "COMMIT_TAG": 34, "EMPTYSTR": 35, "MERGE": 36, "COMMIT_TYPE": 37, "commitType": 38, "COMMIT": 39, "commit_arg": 40, "COMMIT_MSG": 41, "NORMAL": 42, "REVERSE": 43, "HIGHLIGHT": 44, "ID": 45, ";": 46, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 5: "GG", 7: "EOF", 8: ":", 9: "DIR", 12: "OPT", 13: "NL", 19: "acc_title", 20: "acc_title_value", 21: "acc_descr", 22: "acc_descr_value", 23: "acc_descr_multiline_value", 24: "section", 26: "CHECKOUT", 28: "BRANCH", 29: "ORDER", 30: "NUM", 31: "CHERRY_PICK", 32: "COMMIT_ID", 33: "STR", 34: "COMMIT_TAG", 35: "EMPTYSTR", 36: "MERGE", 37: "COMMIT_TYPE", 39: "COMMIT", 41: "COMMIT_MSG", 42: "NORMAL", 43: "REVERSE", 44: "HIGHLIGHT", 45: "ID", 46: ";" }, + productions_: [0, [3, 2], [3, 3], [3, 4], [3, 5], [6, 0], [6, 2], [10, 2], [10, 1], [11, 0], [11, 2], [14, 2], [14, 1], [15, 1], [15, 1], [15, 1], [15, 2], [15, 2], [15, 1], [15, 1], [15, 1], [15, 2], [25, 2], [25, 4], [18, 3], [18, 5], [18, 5], [18, 5], [18, 5], [17, 2], [17, 4], [17, 4], [17, 4], [17, 6], [17, 6], [17, 6], [17, 6], [17, 6], [17, 6], [17, 8], [17, 8], [17, 8], [17, 8], [17, 8], [17, 8], [16, 2], [16, 3], [16, 3], [16, 5], [16, 5], [16, 3], [16, 5], [16, 5], [16, 5], [16, 5], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 3], [16, 5], [16, 5], [16, 5], [16, 5], [16, 5], [16, 5], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 7], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [16, 9], [40, 0], [40, 1], [38, 1], [38, 1], [38, 1], [27, 1], [27, 1], [4, 1], [4, 1], [4, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 2: + return $$[$0]; + case 3: + return $$[$0 - 1]; + case 4: + yy.setDirection($$[$0 - 3]); + return $$[$0 - 1]; + case 6: + yy.setOptions($$[$0 - 1]); + this.$ = $$[$0]; + break; + case 7: + $$[$0 - 1] += $$[$0]; + this.$ = $$[$0 - 1]; + break; + case 9: + this.$ = []; + break; + case 10: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 11: + this.$ = $$[$0 - 1]; + break; + case 16: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 17: + case 18: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 19: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 21: + yy.checkout($$[$0]); + break; + case 22: + yy.branch($$[$0]); + break; + case 23: + yy.branch($$[$0 - 2], $$[$0]); + break; + case 24: + yy.cherryPick($$[$0], "", void 0); + break; + case 25: + yy.cherryPick($$[$0 - 2], "", $$[$0]); + break; + case 26: + case 28: + yy.cherryPick($$[$0 - 2], "", ""); + break; + case 27: + yy.cherryPick($$[$0], "", $$[$0 - 2]); + break; + case 29: + yy.merge($$[$0], "", "", ""); + break; + case 30: + yy.merge($$[$0 - 2], $$[$0], "", ""); + break; + case 31: + yy.merge($$[$0 - 2], "", $$[$0], ""); + break; + case 32: + yy.merge($$[$0 - 2], "", "", $$[$0]); + break; + case 33: + yy.merge($$[$0 - 4], $$[$0], "", $$[$0 - 2]); + break; + case 34: + yy.merge($$[$0 - 4], "", $$[$0], $$[$0 - 2]); + break; + case 35: + yy.merge($$[$0 - 4], "", $$[$0 - 2], $$[$0]); + break; + case 36: + yy.merge($$[$0 - 4], $$[$0 - 2], $$[$0], ""); + break; + case 37: + yy.merge($$[$0 - 4], $$[$0 - 2], "", $$[$0]); + break; + case 38: + yy.merge($$[$0 - 4], $$[$0], $$[$0 - 2], ""); + break; + case 39: + yy.merge($$[$0 - 6], $$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 40: + yy.merge($$[$0 - 6], $$[$0], $$[$0 - 4], $$[$0 - 2]); + break; + case 41: + yy.merge($$[$0 - 6], $$[$0 - 4], $$[$0], $$[$0 - 2]); + break; + case 42: + yy.merge($$[$0 - 6], $$[$0 - 2], $$[$0 - 4], $$[$0]); + break; + case 43: + yy.merge($$[$0 - 6], $$[$0], $$[$0 - 2], $$[$0 - 4]); + break; + case 44: + yy.merge($$[$0 - 6], $$[$0 - 2], $$[$0], $$[$0 - 4]); + break; + case 45: + yy.commit($$[$0]); + break; + case 46: + yy.commit("", "", yy.commitType.NORMAL, $$[$0]); + break; + case 47: + yy.commit("", "", $$[$0], ""); + break; + case 48: + yy.commit("", "", $$[$0], $$[$0 - 2]); + break; + case 49: + yy.commit("", "", $$[$0 - 2], $$[$0]); + break; + case 50: + yy.commit("", $$[$0], yy.commitType.NORMAL, ""); + break; + case 51: + yy.commit("", $$[$0 - 2], yy.commitType.NORMAL, $$[$0]); + break; + case 52: + yy.commit("", $$[$0], yy.commitType.NORMAL, $$[$0 - 2]); + break; + case 53: + yy.commit("", $$[$0 - 2], $$[$0], ""); + break; + case 54: + yy.commit("", $$[$0], $$[$0 - 2], ""); + break; + case 55: + yy.commit("", $$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 56: + yy.commit("", $$[$0 - 4], $$[$0], $$[$0 - 2]); + break; + case 57: + yy.commit("", $$[$0 - 2], $$[$0 - 4], $$[$0]); + break; + case 58: + yy.commit("", $$[$0], $$[$0 - 4], $$[$0 - 2]); + break; + case 59: + yy.commit("", $$[$0], $$[$0 - 2], $$[$0 - 4]); + break; + case 60: + yy.commit("", $$[$0 - 2], $$[$0], $$[$0 - 4]); + break; + case 61: + yy.commit($$[$0], "", yy.commitType.NORMAL, ""); + break; + case 62: + yy.commit($$[$0], "", yy.commitType.NORMAL, $$[$0 - 2]); + break; + case 63: + yy.commit($$[$0 - 2], "", yy.commitType.NORMAL, $$[$0]); + break; + case 64: + yy.commit($$[$0 - 2], "", $$[$0], ""); + break; + case 65: + yy.commit($$[$0], "", $$[$0 - 2], ""); + break; + case 66: + yy.commit($$[$0], $$[$0 - 2], yy.commitType.NORMAL, ""); + break; + case 67: + yy.commit($$[$0 - 2], $$[$0], yy.commitType.NORMAL, ""); + break; + case 68: + yy.commit($$[$0 - 4], "", $$[$0 - 2], $$[$0]); + break; + case 69: + yy.commit($$[$0 - 4], "", $$[$0], $$[$0 - 2]); + break; + case 70: + yy.commit($$[$0 - 2], "", $$[$0 - 4], $$[$0]); + break; + case 71: + yy.commit($$[$0], "", $$[$0 - 4], $$[$0 - 2]); + break; + case 72: + yy.commit($$[$0], "", $$[$0 - 2], $$[$0 - 4]); + break; + case 73: + yy.commit($$[$0 - 2], "", $$[$0], $$[$0 - 4]); + break; + case 74: + yy.commit($$[$0 - 4], $$[$0], $$[$0 - 2], ""); + break; + case 75: + yy.commit($$[$0 - 4], $$[$0 - 2], $$[$0], ""); + break; + case 76: + yy.commit($$[$0 - 2], $$[$0], $$[$0 - 4], ""); + break; + case 77: + yy.commit($$[$0], $$[$0 - 2], $$[$0 - 4], ""); + break; + case 78: + yy.commit($$[$0], $$[$0 - 4], $$[$0 - 2], ""); + break; + case 79: + yy.commit($$[$0 - 2], $$[$0 - 4], $$[$0], ""); + break; + case 80: + yy.commit($$[$0 - 4], $$[$0], yy.commitType.NORMAL, $$[$0 - 2]); + break; + case 81: + yy.commit($$[$0 - 4], $$[$0 - 2], yy.commitType.NORMAL, $$[$0]); + break; + case 82: + yy.commit($$[$0 - 2], $$[$0], yy.commitType.NORMAL, $$[$0 - 4]); + break; + case 83: + yy.commit($$[$0], $$[$0 - 2], yy.commitType.NORMAL, $$[$0 - 4]); + break; + case 84: + yy.commit($$[$0], $$[$0 - 4], yy.commitType.NORMAL, $$[$0 - 2]); + break; + case 85: + yy.commit($$[$0 - 2], $$[$0 - 4], yy.commitType.NORMAL, $$[$0]); + break; + case 86: + yy.commit($$[$0 - 6], $$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 87: + yy.commit($$[$0 - 6], $$[$0 - 4], $$[$0], $$[$0 - 2]); + break; + case 88: + yy.commit($$[$0 - 6], $$[$0 - 2], $$[$0 - 4], $$[$0]); + break; + case 89: + yy.commit($$[$0 - 6], $$[$0], $$[$0 - 4], $$[$0 - 2]); + break; + case 90: + yy.commit($$[$0 - 6], $$[$0 - 2], $$[$0], $$[$0 - 4]); + break; + case 91: + yy.commit($$[$0 - 6], $$[$0], $$[$0 - 2], $$[$0 - 4]); + break; + case 92: + yy.commit($$[$0 - 4], $$[$0 - 6], $$[$0 - 2], $$[$0]); + break; + case 93: + yy.commit($$[$0 - 4], $$[$0 - 6], $$[$0], $$[$0 - 2]); + break; + case 94: + yy.commit($$[$0 - 2], $$[$0 - 6], $$[$0 - 4], $$[$0]); + break; + case 95: + yy.commit($$[$0], $$[$0 - 6], $$[$0 - 4], $$[$0 - 2]); + break; + case 96: + yy.commit($$[$0 - 2], $$[$0 - 6], $$[$0], $$[$0 - 4]); + break; + case 97: + yy.commit($$[$0], $$[$0 - 6], $$[$0 - 2], $$[$0 - 4]); + break; + case 98: + yy.commit($$[$0], $$[$0 - 4], $$[$0 - 2], $$[$0 - 6]); + break; + case 99: + yy.commit($$[$0 - 2], $$[$0 - 4], $$[$0], $$[$0 - 6]); + break; + case 100: + yy.commit($$[$0], $$[$0 - 2], $$[$0 - 4], $$[$0 - 6]); + break; + case 101: + yy.commit($$[$0 - 2], $$[$0], $$[$0 - 4], $$[$0 - 6]); + break; + case 102: + yy.commit($$[$0 - 4], $$[$0 - 2], $$[$0], $$[$0 - 6]); + break; + case 103: + yy.commit($$[$0 - 4], $$[$0], $$[$0 - 2], $$[$0 - 6]); + break; + case 104: + yy.commit($$[$0 - 2], $$[$0 - 4], $$[$0 - 6], $$[$0]); + break; + case 105: + yy.commit($$[$0], $$[$0 - 4], $$[$0 - 6], $$[$0 - 2]); + break; + case 106: + yy.commit($$[$0 - 2], $$[$0], $$[$0 - 6], $$[$0 - 4]); + break; + case 107: + yy.commit($$[$0], $$[$0 - 2], $$[$0 - 6], $$[$0 - 4]); + break; + case 108: + yy.commit($$[$0 - 4], $$[$0 - 2], $$[$0 - 6], $$[$0]); + break; + case 109: + yy.commit($$[$0 - 4], $$[$0], $$[$0 - 6], $$[$0 - 2]); + break; + case 110: + this.$ = ""; + break; + case 111: + this.$ = $$[$0]; + break; + case 112: + this.$ = yy.commitType.NORMAL; + break; + case 113: + this.$ = yy.commitType.REVERSE; + break; + case 114: + this.$ = yy.commitType.HIGHLIGHT; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: $V0, 7: $V1, 13: $V2, 46: $V3 }, { 1: [3] }, { 3: 7, 4: 2, 5: $V0, 7: $V1, 13: $V2, 46: $V3 }, { 6: 8, 7: $V4, 8: [1, 9], 9: [1, 10], 10: 11, 13: $V5 }, o($V6, [2, 117]), o($V6, [2, 118]), o($V6, [2, 119]), { 1: [2, 1] }, { 7: [1, 13] }, { 6: 14, 7: $V4, 10: 11, 13: $V5 }, { 8: [1, 15] }, o($V7, [2, 9], { 11: 16, 12: [1, 17] }), o($V8, [2, 8]), { 1: [2, 2] }, { 7: [1, 18] }, { 6: 19, 7: $V4, 10: 11, 13: $V5 }, { 7: [2, 6], 13: [1, 22], 14: 20, 15: 21, 16: 23, 17: 24, 18: 25, 19: [1, 26], 21: [1, 27], 23: [1, 28], 24: [1, 29], 25: 30, 26: [1, 31], 28: [1, 35], 31: [1, 34], 36: [1, 33], 39: [1, 32] }, o($V8, [2, 7]), { 1: [2, 3] }, { 7: [1, 36] }, o($V7, [2, 10]), { 4: 37, 7: $V1, 13: $V2, 46: $V3 }, o($V7, [2, 12]), o($V9, [2, 13]), o($V9, [2, 14]), o($V9, [2, 15]), { 20: [1, 38] }, { 22: [1, 39] }, o($V9, [2, 18]), o($V9, [2, 19]), o($V9, [2, 20]), { 27: 40, 33: $Va, 45: $Vb }, o($V9, [2, 110], { 40: 43, 32: [1, 46], 33: [1, 48], 34: [1, 44], 37: [1, 45], 41: [1, 47] }), { 27: 49, 33: $Va, 45: $Vb }, { 32: [1, 50], 34: [1, 51] }, { 27: 52, 33: $Va, 45: $Vb }, { 1: [2, 4] }, o($V7, [2, 11]), o($V9, [2, 16]), o($V9, [2, 17]), o($V9, [2, 21]), o($Vc, [2, 115]), o($Vc, [2, 116]), o($V9, [2, 45]), { 33: [1, 53] }, { 38: 54, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 58] }, { 33: [1, 59] }, o($V9, [2, 111]), o($V9, [2, 29], { 32: [1, 60], 34: [1, 62], 37: [1, 61] }), { 33: [1, 63] }, { 33: [1, 64], 35: [1, 65] }, o($V9, [2, 22], { 29: [1, 66] }), o($V9, [2, 46], { 32: [1, 68], 37: [1, 67], 41: [1, 69] }), o($V9, [2, 47], { 32: [1, 71], 34: [1, 70], 41: [1, 72] }), o($Vg, [2, 112]), o($Vg, [2, 113]), o($Vg, [2, 114]), o($V9, [2, 50], { 34: [1, 73], 37: [1, 74], 41: [1, 75] }), o($V9, [2, 61], { 32: [1, 78], 34: [1, 76], 37: [1, 77] }), { 33: [1, 79] }, { 38: 80, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 81] }, o($V9, [2, 24], { 34: [1, 82] }), { 32: [1, 83] }, { 32: [1, 84] }, { 30: [1, 85] }, { 38: 86, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 87] }, { 33: [1, 88] }, { 33: [1, 89] }, { 33: [1, 90] }, { 33: [1, 91] }, { 33: [1, 92] }, { 38: 93, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 94] }, { 33: [1, 95] }, { 38: 96, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 97] }, o($V9, [2, 30], { 34: [1, 99], 37: [1, 98] }), o($V9, [2, 31], { 32: [1, 101], 34: [1, 100] }), o($V9, [2, 32], { 32: [1, 102], 37: [1, 103] }), { 33: [1, 104], 35: [1, 105] }, { 33: [1, 106] }, { 33: [1, 107] }, o($V9, [2, 23]), o($V9, [2, 48], { 32: [1, 108], 41: [1, 109] }), o($V9, [2, 52], { 37: [1, 110], 41: [1, 111] }), o($V9, [2, 62], { 32: [1, 113], 37: [1, 112] }), o($V9, [2, 49], { 32: [1, 114], 41: [1, 115] }), o($V9, [2, 54], { 34: [1, 116], 41: [1, 117] }), o($V9, [2, 65], { 32: [1, 119], 34: [1, 118] }), o($V9, [2, 51], { 37: [1, 120], 41: [1, 121] }), o($V9, [2, 53], { 34: [1, 122], 41: [1, 123] }), o($V9, [2, 66], { 34: [1, 125], 37: [1, 124] }), o($V9, [2, 63], { 32: [1, 127], 37: [1, 126] }), o($V9, [2, 64], { 32: [1, 129], 34: [1, 128] }), o($V9, [2, 67], { 34: [1, 131], 37: [1, 130] }), { 38: 132, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 133] }, { 33: [1, 134] }, { 33: [1, 135] }, { 33: [1, 136] }, { 38: 137, 42: $Vd, 43: $Ve, 44: $Vf }, o($V9, [2, 25]), o($V9, [2, 26]), o($V9, [2, 27]), o($V9, [2, 28]), { 33: [1, 138] }, { 33: [1, 139] }, { 38: 140, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 141] }, { 38: 142, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 143] }, { 33: [1, 144] }, { 33: [1, 145] }, { 33: [1, 146] }, { 33: [1, 147] }, { 33: [1, 148] }, { 33: [1, 149] }, { 38: 150, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 151] }, { 33: [1, 152] }, { 33: [1, 153] }, { 38: 154, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 155] }, { 38: 156, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 157] }, { 33: [1, 158] }, { 33: [1, 159] }, { 38: 160, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 161] }, o($V9, [2, 36], { 34: [1, 162] }), o($V9, [2, 37], { 37: [1, 163] }), o($V9, [2, 35], { 32: [1, 164] }), o($V9, [2, 38], { 34: [1, 165] }), o($V9, [2, 33], { 37: [1, 166] }), o($V9, [2, 34], { 32: [1, 167] }), o($V9, [2, 59], { 41: [1, 168] }), o($V9, [2, 72], { 32: [1, 169] }), o($V9, [2, 60], { 41: [1, 170] }), o($V9, [2, 83], { 37: [1, 171] }), o($V9, [2, 73], { 32: [1, 172] }), o($V9, [2, 82], { 37: [1, 173] }), o($V9, [2, 58], { 41: [1, 174] }), o($V9, [2, 71], { 32: [1, 175] }), o($V9, [2, 57], { 41: [1, 176] }), o($V9, [2, 77], { 34: [1, 177] }), o($V9, [2, 70], { 32: [1, 178] }), o($V9, [2, 76], { 34: [1, 179] }), o($V9, [2, 56], { 41: [1, 180] }), o($V9, [2, 84], { 37: [1, 181] }), o($V9, [2, 55], { 41: [1, 182] }), o($V9, [2, 78], { 34: [1, 183] }), o($V9, [2, 79], { 34: [1, 184] }), o($V9, [2, 85], { 37: [1, 185] }), o($V9, [2, 69], { 32: [1, 186] }), o($V9, [2, 80], { 37: [1, 187] }), o($V9, [2, 68], { 32: [1, 188] }), o($V9, [2, 74], { 34: [1, 189] }), o($V9, [2, 75], { 34: [1, 190] }), o($V9, [2, 81], { 37: [1, 191] }), { 33: [1, 192] }, { 38: 193, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 194] }, { 33: [1, 195] }, { 38: 196, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 197] }, { 33: [1, 198] }, { 33: [1, 199] }, { 33: [1, 200] }, { 38: 201, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 202] }, { 38: 203, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 204] }, { 33: [1, 205] }, { 33: [1, 206] }, { 33: [1, 207] }, { 33: [1, 208] }, { 33: [1, 209] }, { 33: [1, 210] }, { 38: 211, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 212] }, { 33: [1, 213] }, { 33: [1, 214] }, { 38: 215, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 216] }, { 38: 217, 42: $Vd, 43: $Ve, 44: $Vf }, { 33: [1, 218] }, { 33: [1, 219] }, { 33: [1, 220] }, { 38: 221, 42: $Vd, 43: $Ve, 44: $Vf }, o($V9, [2, 39]), o($V9, [2, 41]), o($V9, [2, 40]), o($V9, [2, 42]), o($V9, [2, 44]), o($V9, [2, 43]), o($V9, [2, 100]), o($V9, [2, 101]), o($V9, [2, 98]), o($V9, [2, 99]), o($V9, [2, 103]), o($V9, [2, 102]), o($V9, [2, 107]), o($V9, [2, 106]), o($V9, [2, 105]), o($V9, [2, 104]), o($V9, [2, 109]), o($V9, [2, 108]), o($V9, [2, 97]), o($V9, [2, 96]), o($V9, [2, 95]), o($V9, [2, 94]), o($V9, [2, 92]), o($V9, [2, 93]), o($V9, [2, 91]), o($V9, [2, 90]), o($V9, [2, 89]), o($V9, [2, 88]), o($V9, [2, 86]), o($V9, [2, 87])], + defaultActions: { 7: [2, 1], 13: [2, 2], 18: [2, 3], 36: [2, 4] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 19; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 21; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + return 13; + case 8: + break; + case 9: + break; + case 10: + return 5; + case 11: + return 39; + case 12: + return 32; + case 13: + return 37; + case 14: + return 41; + case 15: + return 42; + case 16: + return 43; + case 17: + return 44; + case 18: + return 34; + case 19: + return 28; + case 20: + return 29; + case 21: + return 36; + case 22: + return 31; + case 23: + return 26; + case 24: + return 9; + case 25: + return 9; + case 26: + return 8; + case 27: + return "CARET"; + case 28: + this.begin("options"); + break; + case 29: + this.popState(); + break; + case 30: + return 12; + case 31: + return 35; + case 32: + this.begin("string"); + break; + case 33: + this.popState(); + break; + case 34: + return 33; + case 35: + return 30; + case 36: + return 45; + case 37: + return 7; + } + }, + rules: [/^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:(\r?\n)+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:gitGraph\b)/i, /^(?:commit(?=\s|$))/i, /^(?:id:)/i, /^(?:type:)/i, /^(?:msg:)/i, /^(?:NORMAL\b)/i, /^(?:REVERSE\b)/i, /^(?:HIGHLIGHT\b)/i, /^(?:tag:)/i, /^(?:branch(?=\s|$))/i, /^(?:order:)/i, /^(?:merge(?=\s|$))/i, /^(?:cherry-pick(?=\s|$))/i, /^(?:checkout(?=\s|$))/i, /^(?:LR\b)/i, /^(?:TB\b)/i, /^(?::)/i, /^(?:\^)/i, /^(?:options\r?\n)/i, /^(?:[ \r\n\t]+end\b)/i, /^(?:[\s\S]+(?=[ \r\n\t]+end))/i, /^(?:["]["])/i, /^(?:["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[0-9]+(?=\s|$))/i, /^(?:\w([-\./\w]*[-\w])?)/i, /^(?:$)/i, /^(?:\s+)/i], + conditions: { "acc_descr_multiline": { "rules": [5, 6], "inclusive": false }, "acc_descr": { "rules": [3], "inclusive": false }, "acc_title": { "rules": [1], "inclusive": false }, "options": { "rules": [29, 30], "inclusive": false }, "string": { "rules": [33, 34], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 31, 32, 35, 36, 37, 38], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const gitGraphParser = parser; +let mainBranchName = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph.mainBranchName; +let mainBranchOrder = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph.mainBranchOrder; +let commits = {}; +let head = null; +let branchesConfig = {}; +branchesConfig[mainBranchName] = { name: mainBranchName, order: mainBranchOrder }; +let branches = {}; +branches[mainBranchName] = head; +let curBranch = mainBranchName; +let direction = "LR"; +let seq = 0; +function getId() { + return (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.x)({ length: 7 }); +} +function uniqBy(list, fn) { + const recordMap = /* @__PURE__ */ Object.create(null); + return list.reduce((out, item) => { + const key = fn(item); + if (!recordMap[key]) { + recordMap[key] = true; + out.push(item); + } + return out; + }, []); +} +const setDirection = function(dir2) { + direction = dir2; +}; +let options = {}; +const setOptions = function(rawOptString) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("options str", rawOptString); + rawOptString = rawOptString && rawOptString.trim(); + rawOptString = rawOptString || "{}"; + try { + options = JSON.parse(rawOptString); + } catch (e) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.error("error while parsing gitGraph options", e.message); + } +}; +const getOptions = function() { + return options; +}; +const commit = function(msg, id, type, tag) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Entering commit:", msg, id, type, tag); + id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + msg = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(msg, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + tag = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(tag, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + const commit2 = { + id: id ? id : seq + "-" + getId(), + message: msg, + seq: seq++, + type: type ? type : commitType$1.NORMAL, + tag: tag ? tag : "", + parents: head == null ? [] : [head.id], + branch: curBranch + }; + head = commit2; + commits[commit2.id] = commit2; + branches[curBranch] = commit2.id; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in pushCommit " + commit2.id); +}; +const branch = function(name, order) { + name = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(name, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + if (branches[name] === void 0) { + branches[name] = head != null ? head.id : null; + branchesConfig[name] = { name, order: order ? parseInt(order, 10) : null }; + checkout(name); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in createBranch"); + } else { + let error = new Error( + 'Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ' + name + '")' + ); + error.hash = { + text: "branch " + name, + token: "branch " + name, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ['"checkout ' + name + '"'] + }; + throw error; + } +}; +const merge = function(otherBranch, custom_id, override_type, custom_tag) { + otherBranch = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(otherBranch, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + custom_id = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(custom_id, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + const currentCommit = commits[branches[curBranch]]; + const otherCommit = commits[branches[otherBranch]]; + if (curBranch === otherBranch) { + let error = new Error('Incorrect usage of "merge". Cannot merge a branch to itself'); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["branch abc"] + }; + throw error; + } else if (currentCommit === void 0 || !currentCommit) { + let error = new Error( + 'Incorrect usage of "merge". Current branch (' + curBranch + ")has no commits" + ); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["commit"] + }; + throw error; + } else if (branches[otherBranch] === void 0) { + let error = new Error( + 'Incorrect usage of "merge". Branch to be merged (' + otherBranch + ") does not exist" + ); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["branch " + otherBranch] + }; + throw error; + } else if (otherCommit === void 0 || !otherCommit) { + let error = new Error( + 'Incorrect usage of "merge". Branch to be merged (' + otherBranch + ") has no commits" + ); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ['"commit"'] + }; + throw error; + } else if (currentCommit === otherCommit) { + let error = new Error('Incorrect usage of "merge". Both branches have same head'); + error.hash = { + text: "merge " + otherBranch, + token: "merge " + otherBranch, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["branch abc"] + }; + throw error; + } else if (custom_id && commits[custom_id] !== void 0) { + let error = new Error( + 'Incorrect usage of "merge". Commit with id:' + custom_id + " already exists, use different custom Id" + ); + error.hash = { + text: "merge " + otherBranch + custom_id + override_type + custom_tag, + token: "merge " + otherBranch + custom_id + override_type + custom_tag, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: [ + "merge " + otherBranch + " " + custom_id + "_UNIQUE " + override_type + " " + custom_tag + ] + }; + throw error; + } + const commit2 = { + id: custom_id ? custom_id : seq + "-" + getId(), + message: "merged branch " + otherBranch + " into " + curBranch, + seq: seq++, + parents: [head == null ? null : head.id, branches[otherBranch]], + branch: curBranch, + type: commitType$1.MERGE, + customType: override_type, + customId: custom_id ? true : false, + tag: custom_tag ? custom_tag : "" + }; + head = commit2; + commits[commit2.id] = commit2; + branches[curBranch] = commit2.id; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(branches); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in mergeBranch"); +}; +const cherryPick = function(sourceId, targetId, tag) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("Entering cherryPick:", sourceId, targetId, tag); + sourceId = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(sourceId, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + targetId = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(targetId, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + tag = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(tag, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + if (!sourceId || commits[sourceId] === void 0) { + let error = new Error( + 'Incorrect usage of "cherryPick". Source commit id should exist and provided' + ); + error.hash = { + text: "cherryPick " + sourceId + " " + targetId, + token: "cherryPick " + sourceId + " " + targetId, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["cherry-pick abc"] + }; + throw error; + } + let sourceCommit = commits[sourceId]; + let sourceCommitBranch = sourceCommit.branch; + if (sourceCommit.type === commitType$1.MERGE) { + let error = new Error( + 'Incorrect usage of "cherryPick". Source commit should not be a merge commit' + ); + error.hash = { + text: "cherryPick " + sourceId + " " + targetId, + token: "cherryPick " + sourceId + " " + targetId, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["cherry-pick abc"] + }; + throw error; + } + if (!targetId || commits[targetId] === void 0) { + if (sourceCommitBranch === curBranch) { + let error = new Error( + 'Incorrect usage of "cherryPick". Source commit is already on current branch' + ); + error.hash = { + text: "cherryPick " + sourceId + " " + targetId, + token: "cherryPick " + sourceId + " " + targetId, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["cherry-pick abc"] + }; + throw error; + } + const currentCommit = commits[branches[curBranch]]; + if (currentCommit === void 0 || !currentCommit) { + let error = new Error( + 'Incorrect usage of "cherry-pick". Current branch (' + curBranch + ")has no commits" + ); + error.hash = { + text: "cherryPick " + sourceId + " " + targetId, + token: "cherryPick " + sourceId + " " + targetId, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ["cherry-pick abc"] + }; + throw error; + } + const commit2 = { + id: seq + "-" + getId(), + message: "cherry-picked " + sourceCommit + " into " + curBranch, + seq: seq++, + parents: [head == null ? null : head.id, sourceCommit.id], + branch: curBranch, + type: commitType$1.CHERRY_PICK, + tag: tag ?? "cherry-pick:" + sourceCommit.id + }; + head = commit2; + commits[commit2.id] = commit2; + branches[curBranch] = commit2.id; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(branches); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in cherryPick"); + } +}; +const checkout = function(branch2) { + branch2 = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.e.sanitizeText(branch2, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)()); + if (branches[branch2] === void 0) { + let error = new Error( + 'Trying to checkout branch which is not yet created. (Help try using "branch ' + branch2 + '")' + ); + error.hash = { + text: "checkout " + branch2, + token: "checkout " + branch2, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ['"branch ' + branch2 + '"'] + }; + throw error; + } else { + curBranch = branch2; + const id = branches[curBranch]; + head = commits[id]; + } +}; +function upsert(arr, key, newVal) { + const index = arr.indexOf(key); + if (index === -1) { + arr.push(newVal); + } else { + arr.splice(index, 1, newVal); + } +} +function prettyPrintCommitHistory(commitArr) { + const commit2 = commitArr.reduce((out, commit3) => { + if (out.seq > commit3.seq) { + return out; + } + return commit3; + }, commitArr[0]); + let line = ""; + commitArr.forEach(function(c) { + if (c === commit2) { + line += " *"; + } else { + line += " |"; + } + }); + const label = [line, commit2.id, commit2.seq]; + for (let branch2 in branches) { + if (branches[branch2] === commit2.id) { + label.push(branch2); + } + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(label.join(" ")); + if (commit2.parents && commit2.parents.length == 2) { + const newCommit = commits[commit2.parents[0]]; + upsert(commitArr, commit2, newCommit); + commitArr.push(commits[commit2.parents[1]]); + } else if (commit2.parents.length == 0) { + return; + } else { + const nextCommit = commits[commit2.parents]; + upsert(commitArr, commit2, nextCommit); + } + commitArr = uniqBy(commitArr, (c) => c.id); + prettyPrintCommitHistory(commitArr); +} +const prettyPrint = function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(commits); + const node = getCommitsArray()[0]; + prettyPrintCommitHistory([node]); +}; +const clear$1 = function() { + commits = {}; + head = null; + let mainBranch = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph.mainBranchName; + let mainBranchOrder2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph.mainBranchOrder; + branches = {}; + branches[mainBranch] = null; + branchesConfig = {}; + branchesConfig[mainBranch] = { name: mainBranch, order: mainBranchOrder2 }; + curBranch = mainBranch; + seq = 0; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.t)(); +}; +const getBranchesAsObjArray = function() { + const branchesArray = Object.values(branchesConfig).map((branchConfig, i) => { + if (branchConfig.order !== null) { + return branchConfig; + } + return { + ...branchConfig, + order: parseFloat(`0.${i}`, 10) + }; + }).sort((a, b) => a.order - b.order).map(({ name }) => ({ name })); + return branchesArray; +}; +const getBranches = function() { + return branches; +}; +const getCommits = function() { + return commits; +}; +const getCommitsArray = function() { + const commitArr = Object.keys(commits).map(function(key) { + return commits[key]; + }); + commitArr.forEach(function(o) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug(o.id); + }); + commitArr.sort((a, b) => a.seq - b.seq); + return commitArr; +}; +const getCurrentBranch = function() { + return curBranch; +}; +const getDirection = function() { + return direction; +}; +const getHead = function() { + return head; +}; +const commitType$1 = { + NORMAL: 0, + REVERSE: 1, + HIGHLIGHT: 2, + MERGE: 3, + CHERRY_PICK: 4 +}; +const gitGraphDb = { + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph, + setDirection, + setOptions, + getOptions, + commit, + branch, + merge, + cherryPick, + checkout, + //reset, + prettyPrint, + clear: clear$1, + getBranchesAsObjArray, + getBranches, + getCommits, + getCommitsArray, + getCurrentBranch, + getDirection, + getHead, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.g, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.b, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.r, + commitType: commitType$1 +}; +let allCommitsDict = {}; +const commitType = { + NORMAL: 0, + REVERSE: 1, + HIGHLIGHT: 2, + MERGE: 3, + CHERRY_PICK: 4 +}; +const THEME_COLOR_LIMIT = 8; +let branchPos = {}; +let commitPos = {}; +let lanes = []; +let maxPos = 0; +let dir = "LR"; +const clear = () => { + branchPos = {}; + commitPos = {}; + allCommitsDict = {}; + maxPos = 0; + lanes = []; + dir = "LR"; +}; +const drawText = (txt) => { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + let rows = []; + if (typeof txt === "string") { + rows = txt.split(/\\n|\n|<br\s*\/?>/gi); + } else if (Array.isArray(txt)) { + rows = txt; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + tspan.setAttribute("class", "row"); + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; +}; +const drawCommits = (svg, commits2, modifyGraph) => { + const gitGraphConfig = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph; + const gBullets = svg.append("g").attr("class", "commit-bullets"); + const gLabels = svg.append("g").attr("class", "commit-labels"); + let pos = 0; + if (dir === "TB") { + pos = 30; + } + const keys = Object.keys(commits2); + const sortedKeys = keys.sort((a, b) => { + return commits2[a].seq - commits2[b].seq; + }); + sortedKeys.forEach((key) => { + const commit2 = commits2[key]; + const y = dir === "TB" ? pos + 10 : branchPos[commit2.branch].pos; + const x = dir === "TB" ? branchPos[commit2.branch].pos : pos + 10; + if (modifyGraph) { + let typeClass; + let commitSymbolType = commit2.customType !== void 0 && commit2.customType !== "" ? commit2.customType : commit2.type; + switch (commitSymbolType) { + case commitType.NORMAL: + typeClass = "commit-normal"; + break; + case commitType.REVERSE: + typeClass = "commit-reverse"; + break; + case commitType.HIGHLIGHT: + typeClass = "commit-highlight"; + break; + case commitType.MERGE: + typeClass = "commit-merge"; + break; + case commitType.CHERRY_PICK: + typeClass = "commit-cherry-pick"; + break; + default: + typeClass = "commit-normal"; + } + if (commitSymbolType === commitType.HIGHLIGHT) { + const circle = gBullets.append("rect"); + circle.attr("x", x - 10); + circle.attr("y", y - 10); + circle.attr("height", 20); + circle.attr("width", 20); + circle.attr( + "class", + `commit ${commit2.id} commit-highlight${branchPos[commit2.branch].index % THEME_COLOR_LIMIT} ${typeClass}-outer` + ); + gBullets.append("rect").attr("x", x - 6).attr("y", y - 6).attr("height", 12).attr("width", 12).attr( + "class", + `commit ${commit2.id} commit${branchPos[commit2.branch].index % THEME_COLOR_LIMIT} ${typeClass}-inner` + ); + } else if (commitSymbolType === commitType.CHERRY_PICK) { + gBullets.append("circle").attr("cx", x).attr("cy", y).attr("r", 10).attr("class", `commit ${commit2.id} ${typeClass}`); + gBullets.append("circle").attr("cx", x - 3).attr("cy", y + 2).attr("r", 2.75).attr("fill", "#fff").attr("class", `commit ${commit2.id} ${typeClass}`); + gBullets.append("circle").attr("cx", x + 3).attr("cy", y + 2).attr("r", 2.75).attr("fill", "#fff").attr("class", `commit ${commit2.id} ${typeClass}`); + gBullets.append("line").attr("x1", x + 3).attr("y1", y + 1).attr("x2", x).attr("y2", y - 5).attr("stroke", "#fff").attr("class", `commit ${commit2.id} ${typeClass}`); + gBullets.append("line").attr("x1", x - 3).attr("y1", y + 1).attr("x2", x).attr("y2", y - 5).attr("stroke", "#fff").attr("class", `commit ${commit2.id} ${typeClass}`); + } else { + const circle = gBullets.append("circle"); + circle.attr("cx", x); + circle.attr("cy", y); + circle.attr("r", commit2.type === commitType.MERGE ? 9 : 10); + circle.attr( + "class", + `commit ${commit2.id} commit${branchPos[commit2.branch].index % THEME_COLOR_LIMIT}` + ); + if (commitSymbolType === commitType.MERGE) { + const circle2 = gBullets.append("circle"); + circle2.attr("cx", x); + circle2.attr("cy", y); + circle2.attr("r", 6); + circle2.attr( + "class", + `commit ${typeClass} ${commit2.id} commit${branchPos[commit2.branch].index % THEME_COLOR_LIMIT}` + ); + } + if (commitSymbolType === commitType.REVERSE) { + const cross = gBullets.append("path"); + cross.attr("d", `M ${x - 5},${y - 5}L${x + 5},${y + 5}M${x - 5},${y + 5}L${x + 5},${y - 5}`).attr( + "class", + `commit ${typeClass} ${commit2.id} commit${branchPos[commit2.branch].index % THEME_COLOR_LIMIT}` + ); + } + } + } + if (dir === "TB") { + commitPos[commit2.id] = { x, y: pos + 10 }; + } else { + commitPos[commit2.id] = { x: pos + 10, y }; + } + if (modifyGraph) { + const px = 4; + const py = 2; + if (commit2.type !== commitType.CHERRY_PICK && (commit2.customId && commit2.type === commitType.MERGE || commit2.type !== commitType.MERGE) && gitGraphConfig.showCommitLabel) { + const wrapper = gLabels.append("g"); + const labelBkg = wrapper.insert("rect").attr("class", "commit-label-bkg"); + const text = wrapper.append("text").attr("x", pos).attr("y", y + 25).attr("class", "commit-label").text(commit2.id); + let bbox = text.node().getBBox(); + labelBkg.attr("x", pos + 10 - bbox.width / 2 - py).attr("y", y + 13.5).attr("width", bbox.width + 2 * py).attr("height", bbox.height + 2 * py); + if (dir === "TB") { + labelBkg.attr("x", x - (bbox.width + 4 * px + 5)).attr("y", y - 12); + text.attr("x", x - (bbox.width + 4 * px)).attr("y", y + bbox.height - 12); + } + if (dir !== "TB") { + text.attr("x", pos + 10 - bbox.width / 2); + } + if (gitGraphConfig.rotateCommitLabel) { + if (dir === "TB") { + text.attr("transform", "rotate(-45, " + x + ", " + y + ")"); + labelBkg.attr("transform", "rotate(-45, " + x + ", " + y + ")"); + } else { + let r_x = -7.5 - (bbox.width + 10) / 25 * 9.5; + let r_y = 10 + bbox.width / 25 * 8.5; + wrapper.attr( + "transform", + "translate(" + r_x + ", " + r_y + ") rotate(-45, " + pos + ", " + y + ")" + ); + } + } + } + if (commit2.tag) { + const rect = gLabels.insert("polygon"); + const hole = gLabels.append("circle"); + const tag = gLabels.append("text").attr("y", y - 16).attr("class", "tag-label").text(commit2.tag); + let tagBbox = tag.node().getBBox(); + tag.attr("x", pos + 10 - tagBbox.width / 2); + const h2 = tagBbox.height / 2; + const ly = y - 19.2; + rect.attr("class", "tag-label-bkg").attr( + "points", + ` + ${pos - tagBbox.width / 2 - px / 2},${ly + py} + ${pos - tagBbox.width / 2 - px / 2},${ly - py} + ${pos + 10 - tagBbox.width / 2 - px},${ly - h2 - py} + ${pos + 10 + tagBbox.width / 2 + px},${ly - h2 - py} + ${pos + 10 + tagBbox.width / 2 + px},${ly + h2 + py} + ${pos + 10 - tagBbox.width / 2 - px},${ly + h2 + py}` + ); + hole.attr("cx", pos - tagBbox.width / 2 + px / 2).attr("cy", ly).attr("r", 1.5).attr("class", "tag-hole"); + if (dir === "TB") { + rect.attr("class", "tag-label-bkg").attr( + "points", + ` + ${x},${pos + py} + ${x},${pos - py} + ${x + 10},${pos - h2 - py} + ${x + 10 + tagBbox.width + px},${pos - h2 - py} + ${x + 10 + tagBbox.width + px},${pos + h2 + py} + ${x + 10},${pos + h2 + py}` + ).attr("transform", "translate(12,12) rotate(45, " + x + "," + pos + ")"); + hole.attr("cx", x + px / 2).attr("cy", pos).attr("transform", "translate(12,12) rotate(45, " + x + "," + pos + ")"); + tag.attr("x", x + 5).attr("y", pos + 3).attr("transform", "translate(14,14) rotate(45, " + x + "," + pos + ")"); + } + } + } + pos += 50; + if (pos > maxPos) { + maxPos = pos; + } + }); +}; +const hasOverlappingCommits = (commit1, commit2, allCommits) => { + const keys = Object.keys(allCommits); + const overlappingComits = keys.filter((key) => { + return allCommits[key].branch === commit2.branch && allCommits[key].seq > commit1.seq && allCommits[key].seq < commit2.seq; + }); + return overlappingComits.length > 0; +}; +const findLane = (y1, y2, depth = 0) => { + const candidate = y1 + Math.abs(y1 - y2) / 2; + if (depth > 5) { + return candidate; + } + let ok = lanes.every((lane) => Math.abs(lane - candidate) >= 10); + if (ok) { + lanes.push(candidate); + return candidate; + } + const diff = Math.abs(y1 - y2); + return findLane(y1, y2 - diff / 5, depth + 1); +}; +const drawArrow = (svg, commit1, commit2, allCommits) => { + const p1 = commitPos[commit1.id]; + const p2 = commitPos[commit2.id]; + const overlappingCommits = hasOverlappingCommits(commit1, commit2, allCommits); + let arc = ""; + let arc2 = ""; + let radius = 0; + let offset = 0; + let colorClassNum = branchPos[commit2.branch].index; + let lineDef; + if (overlappingCommits) { + arc = "A 10 10, 0, 0, 0,"; + arc2 = "A 10 10, 0, 0, 1,"; + radius = 10; + offset = 10; + colorClassNum = branchPos[commit2.branch].index; + const lineY = p1.y < p2.y ? findLane(p1.y, p2.y) : findLane(p2.y, p1.y); + const lineX = p1.x < p2.x ? findLane(p1.x, p2.x) : findLane(p2.x, p1.x); + if (dir === "TB") { + if (p1.x < p2.x) { + lineDef = `M ${p1.x} ${p1.y} L ${lineX - radius} ${p1.y} ${arc2} ${lineX} ${p1.y + offset} L ${lineX} ${p2.y - radius} ${arc} ${lineX + offset} ${p2.y} L ${p2.x} ${p2.y}`; + } else { + lineDef = `M ${p1.x} ${p1.y} L ${lineX + radius} ${p1.y} ${arc} ${lineX} ${p1.y + offset} L ${lineX} ${p2.y - radius} ${arc2} ${lineX - offset} ${p2.y} L ${p2.x} ${p2.y}`; + } + } else { + if (p1.y < p2.y) { + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${lineY - radius} ${arc} ${p1.x + offset} ${lineY} L ${p2.x - radius} ${lineY} ${arc2} ${p2.x} ${lineY + offset} L ${p2.x} ${p2.y}`; + } else { + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${lineY + radius} ${arc2} ${p1.x + offset} ${lineY} L ${p2.x - radius} ${lineY} ${arc} ${p2.x} ${lineY - offset} L ${p2.x} ${p2.y}`; + } + } + } else { + if (dir === "TB") { + if (p1.x < p2.x) { + arc = "A 20 20, 0, 0, 0,"; + arc2 = "A 20 20, 0, 0, 1,"; + radius = 20; + offset = 20; + colorClassNum = branchPos[commit2.branch].index; + lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc2} ${p2.x} ${p1.y + offset} L ${p2.x} ${p2.y}`; + } + if (p1.x > p2.x) { + arc = "A 20 20, 0, 0, 0,"; + arc2 = "A 20 20, 0, 0, 1,"; + radius = 20; + offset = 20; + colorClassNum = branchPos[commit1.branch].index; + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc2} ${p1.x - offset} ${p2.y} L ${p2.x} ${p2.y}`; + } + if (p1.x === p2.x) { + colorClassNum = branchPos[commit1.branch].index; + lineDef = `M ${p1.x} ${p1.y} L ${p1.x + radius} ${p1.y} ${arc} ${p1.x + offset} ${p2.y + radius} L ${p2.x} ${p2.y}`; + } + } else { + if (p1.y < p2.y) { + arc = "A 20 20, 0, 0, 0,"; + radius = 20; + offset = 20; + colorClassNum = branchPos[commit2.branch].index; + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`; + } + if (p1.y > p2.y) { + arc = "A 20 20, 0, 0, 0,"; + radius = 20; + offset = 20; + colorClassNum = branchPos[commit1.branch].index; + lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc} ${p2.x} ${p1.y - offset} L ${p2.x} ${p2.y}`; + } + if (p1.y === p2.y) { + colorClassNum = branchPos[commit1.branch].index; + lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`; + } + } + } + svg.append("path").attr("d", lineDef).attr("class", "arrow arrow" + colorClassNum % THEME_COLOR_LIMIT); +}; +const drawArrows = (svg, commits2) => { + const gArrows = svg.append("g").attr("class", "commit-arrows"); + Object.keys(commits2).forEach((key) => { + const commit2 = commits2[key]; + if (commit2.parents && commit2.parents.length > 0) { + commit2.parents.forEach((parent) => { + drawArrow(gArrows, commits2[parent], commit2, commits2); + }); + } + }); +}; +const drawBranches = (svg, branches2) => { + const gitGraphConfig = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)().gitGraph; + const g = svg.append("g"); + branches2.forEach((branch2, index) => { + const adjustIndexForTheme = index % THEME_COLOR_LIMIT; + const pos = branchPos[branch2.name].pos; + const line = g.append("line"); + line.attr("x1", 0); + line.attr("y1", pos); + line.attr("x2", maxPos); + line.attr("y2", pos); + line.attr("class", "branch branch" + adjustIndexForTheme); + if (dir === "TB") { + line.attr("y1", 30); + line.attr("x1", pos); + line.attr("y2", maxPos); + line.attr("x2", pos); + } + lanes.push(pos); + let name = branch2.name; + const labelElement = drawText(name); + const bkg = g.insert("rect"); + const branchLabel = g.insert("g").attr("class", "branchLabel"); + const label = branchLabel.insert("g").attr("class", "label branch-label" + adjustIndexForTheme); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + bkg.attr("class", "branchLabelBkg label" + adjustIndexForTheme).attr("rx", 4).attr("ry", 4).attr("x", -bbox.width - 4 - (gitGraphConfig.rotateCommitLabel === true ? 30 : 0)).attr("y", -bbox.height / 2 + 8).attr("width", bbox.width + 18).attr("height", bbox.height + 4); + label.attr( + "transform", + "translate(" + (-bbox.width - 14 - (gitGraphConfig.rotateCommitLabel === true ? 30 : 0)) + ", " + (pos - bbox.height / 2 - 1) + ")" + ); + if (dir === "TB") { + bkg.attr("x", pos - bbox.width / 2 - 10).attr("y", 0); + label.attr("transform", "translate(" + (pos - bbox.width / 2 - 5) + ", 0)"); + } + if (dir !== "TB") { + bkg.attr("transform", "translate(-19, " + (pos - bbox.height / 2) + ")"); + } + }); +}; +const draw = function(txt, id, ver, diagObj) { + clear(); + const conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.c)(); + const gitGraphConfig = conf.gitGraph; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.l.debug("in gitgraph renderer", txt + "\n", "id:", id, ver); + allCommitsDict = diagObj.db.getCommits(); + const branches2 = diagObj.db.getBranchesAsObjArray(); + dir = diagObj.db.getDirection(); + const diagram2 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(`[id="${id}"]`); + let pos = 0; + branches2.forEach((branch2, index) => { + const labelElement = drawText(branch2.name); + const g = diagram2.append("g"); + const branchLabel = g.insert("g").attr("class", "branchLabel"); + const label = branchLabel.insert("g").attr("class", "label branch-label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + branchPos[branch2.name] = { pos, index }; + pos += 50 + (gitGraphConfig.rotateCommitLabel ? 40 : 0) + (dir === "TB" ? bbox.width / 2 : 0); + label.remove(); + branchLabel.remove(); + g.remove(); + }); + drawCommits(diagram2, allCommitsDict, false); + if (gitGraphConfig.showBranches) { + drawBranches(diagram2, branches2); + } + drawArrows(diagram2, allCommitsDict); + drawCommits(diagram2, allCommitsDict, true); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.u.insertTitle( + diagram2, + "gitTitleText", + gitGraphConfig.titleTopMargin, + diagObj.db.getDiagramTitle() + ); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_4__.y)( + void 0, + diagram2, + gitGraphConfig.diagramPadding, + gitGraphConfig.useMaxWidth ?? conf.useMaxWidth + ); +}; +const gitGraphRenderer = { + draw +}; +const getStyles = (options2) => ` + .commit-id, + .commit-msg, + .branch-label { + fill: lightgrey; + color: lightgrey; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + } + ${[0, 1, 2, 3, 4, 5, 6, 7].map( + (i) => ` + .branch-label${i} { fill: ${options2["gitBranchLabel" + i]}; } + .commit${i} { stroke: ${options2["git" + i]}; fill: ${options2["git" + i]}; } + .commit-highlight${i} { stroke: ${options2["gitInv" + i]}; fill: ${options2["gitInv" + i]}; } + .label${i} { fill: ${options2["git" + i]}; } + .arrow${i} { stroke: ${options2["git" + i]}; } + ` +).join("\n")} + + .branch { + stroke-width: 1; + stroke: ${options2.lineColor}; + stroke-dasharray: 2; + } + .commit-label { font-size: ${options2.commitLabelFontSize}; fill: ${options2.commitLabelColor};} + .commit-label-bkg { font-size: ${options2.commitLabelFontSize}; fill: ${options2.commitLabelBackground}; opacity: 0.5; } + .tag-label { font-size: ${options2.tagLabelFontSize}; fill: ${options2.tagLabelColor};} + .tag-label-bkg { fill: ${options2.tagLabelBackground}; stroke: ${options2.tagLabelBorder}; } + .tag-hole { fill: ${options2.textColor}; } + + .commit-merge { + stroke: ${options2.primaryColor}; + fill: ${options2.primaryColor}; + } + .commit-reverse { + stroke: ${options2.primaryColor}; + fill: ${options2.primaryColor}; + stroke-width: 3; + } + .commit-highlight-outer { + } + .commit-highlight-inner { + stroke: ${options2.primaryColor}; + fill: ${options2.primaryColor}; + } + + .arrow { stroke-width: 8; stroke-linecap: round; fill: none} + .gitTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options2.textColor}; + } +`; +const gitGraphStyles = getStyles; +const diagram = { + parser: gitGraphParser, + db: gitGraphDb, + renderer: gitGraphRenderer, + styles: gitGraphStyles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/7159c7ff.9f77b884.js b/assets/js/7159c7ff.9f77b884.js new file mode 100644 index 000000000..89b6abf50 --- /dev/null +++ b/assets/js/7159c7ff.9f77b884.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3287],{67219:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var i=t(85893),r=t(3905);const o={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",slug:"route-image-implementation",tags:["image","awt"]},a=void 0,s={permalink:"/route-image-implementation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",source:"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",description:"\uac1c\uc694",date:"2023-08-02T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 2\uc77c",tags:[{label:"image",permalink:"/tags/image"},{label:"awt",permalink:"/tags/awt"}],readingTime:11.665,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",slug:"route-image-implementation",tags:["image","awt"]},unlisted:!1,prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",permalink:"/route-image-async-with-event"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",permalink:"/route-image-python"}},l={authorsImageUrls:[]},d=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:2},{value:"\uad6c\ud604 \uacb0\uacfc",id:"\uad6c\ud604-\uacb0\uacfc",level:3},{value:"IMAGE_SIZE & ROUTE_SIZE",id:"image_size--route_size",level:3},{value:"\uc8fc\uc694 \ud074\ub798\uc2a4",id:"\uc8fc\uc694-\ud074\ub798\uc2a4",level:2},{value:"\uc694\uc57d",id:"\uc694\uc57d",level:3},{value:"\uc758\uc874\uad00\uacc4",id:"\uc758\uc874\uad00\uacc4",level:3},{value:"Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)",id:"coordinates\uc704\ub3c4-\uacbd\ub3c4\uc758-\uc77c\uae09-\uceec\ub809\uc158",level:3},{value:"Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)",id:"positions\uc2e4\uc81c-\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc5d0-\uc0ac\uc6a9\ud560-\uc704\uce58",level:3},{value:"RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)",id:"routeimagedrawer\uc2e4\uc81c-\uc774\ubbf8\uc9c0\uc5d0-\uacbd\ub85c\ub97c-\uadf8\ub824\uc8fc\ub294-\ud074\ub798\uc2a4",level:3},{value:"\uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow",id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131-flow",level:2},{value:"1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44",id:"1-\uc774\ubbf8\uc9c0-\uc0dd\uc131-\uc900\ube44",level:3},{value:"2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad",id:"2-\uc120-\uadf8\ub9ac\uae30-\uc694\uccad",level:3},{value:"3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad",id:"3-\uc704\uce58-\uc810-\uadf8\ub9ac\uae30-\uc694\uccad",level:3},{value:"4. \uc5c5\ub85c\ub4dc \uc694\uccad",id:"4-\uc5c5\ub85c\ub4dc-\uc694\uccad",level:3},{value:"\uc804\uccb4 Flow",id:"\uc804\uccb4-flow",level:3}];function c(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.ah)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,i.jsxs)(n.p,{children:["\uc5ec\ud589\uc5d0 \ub300\ud55c \uacbd\ub85c\ub97c \ubcf4\uc5ec\uc8fc\uae30 \uc704\ud574 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d \ubc0f \uae30\uc220 \uc120\ud0dd\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 ",(0,i.jsx)(n.a,{href:"./route-image-intro",children:"\ub9c1\ud06c"}),"\uc5d0 \uc788\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"\uad6c\ud604-\uacb0\uacfc",children:"\uad6c\ud604 \uacb0\uacfc"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"./result.png",src:t(59563).Z+"",width:"1840",height:"714"})}),"\n",(0,i.jsxs)(n.p,{children:["\uc608\uc2dc \ub370\uc774\ud130\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.",(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.strong,{children:"\uc11c\uc6b8\uc5ed(\uc810)"})," \u2192 \uc2e0\uc0ac\uc5ed \u2192 \ub178\ub7c9\uc9c4\uc5ed \u2192 \ud64d\ub300\uc785\uad6c\uc5ed \u2192 \uc885\ub85c3\uac00\uc5ed \u2192 \uc625\uc218\uc5ed \u2192 ",(0,i.jsx)(n.strong,{children:"\uad6c\ub85c\uc5ed(\uc810)"})," \u2192 \uc2e0\ub9bc\uc5ed \u2192 \ubc1c\uc0b0\uc5ed"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="\uc608\uc2dc \ub370\uc774\ud130"',children:"List<Double> x = List.of(\n 126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,\n 126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639\n);\nList<Double> y = List.of(\n 37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,\n 37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184\n);\nList<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);\nList<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);\n"})}),"\n",(0,i.jsx)(n.h3,{id:"image_size--route_size",children:"IMAGE_SIZE & ROUTE_SIZE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="RouteImageGenerator.java"',children:"private static final int IMAGE_SIZE = 800;\nprivate static final int ROUTE_SIZE = 600;\n"})}),"\n",(0,i.jsxs)(n.p,{children:["\ucf54\ub4dc\ub97c \ubcf4\uba74 IMAGE_SIZE\uc640 ROUTE_SIZE\uac00 \uc788\ub2e4.",(0,i.jsx)(n.br,{}),"\n","IMAGE_SIZE\ub294 \ub9d0 \uadf8\ub300\ub85c \uc774\ubbf8\uc9c0\uc758 width\uc640 height\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","ROUTE_SIZE\uc758 \uacbd\uc6b0 \uc0c1\ud558\uc88c\uc6b0 100px \ub9cc\ud07c\uc758 \uac04\uaca9\uc744 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc2e4\uc81c \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub294 600 * 600 \uc0ac\uc774\uc988\ub85c \uc0dd\uc131\ub41c\ub2e4."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"./600.png",src:t(49812).Z+"",width:"976",height:"970"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"\uc0ac\uc774\uc988 \ubcc0\uacbd\uc758 \uc774\uc720"})}),"\n",(0,i.jsx)(n.p,{children:"255 * 255 \uc815\ub3c4\uc758 \uc791\uc740 \uc0ac\uc774\uc988\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud574\ubcf4\ub824\uace0 \ud588\ub294\ub370, \uc774\ubbf8\uc9c0\uc758 \uc120\uba85\ub3c4\uac00 \uc88b\uc9c0 \uc54a\uc544 800 * 800 \uc0ac\uc774\uc988\ub85c \ubcc0\uacbd\ud588\ub2e4."}),"\n",(0,i.jsx)(n.h2,{id:"\uc8fc\uc694-\ud074\ub798\uc2a4",children:"\uc8fc\uc694 \ud074\ub798\uc2a4"}),"\n",(0,i.jsx)(n.h3,{id:"\uc694\uc57d",children:"\uc694\uc57d"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"\ud074\ub798\uc2a4\uba85"}),(0,i.jsx)(n.th,{children:"\uc124\uba85"}),(0,i.jsx)(n.th,{children:"\ud2b9\uc774\uc0ac\ud56d"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Coordinate"}),(0,i.jsx)(n.td,{children:"\uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \uc704\uce58 \uac12"}),(0,i.jsx)(n.td,{children:"\uc88c\ud45c\ub97c \ub73b\ud558\uc9c0\ub9cc \uc5ec\ud589 \ub3c4\uba54\uc778\uc5d0 \ud3ec\ud568\ub41c Point \ud074\ub798\uc2a4\uc640 \uad6c\ubd84\ud558\uae30 \uc704\ud574 longitude, latitude\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 x, y \uc0ac\uc6a9"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Coordinates"}),(0,i.jsx)(n.td,{children:"Coordinate\uc758 \uc77c\uae09 \uceec\ub809\uc158"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Position"}),(0,i.jsx)(n.td,{children:"\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58 \uac12"}),(0,i.jsx)(n.td,{children:"Integer \ud0c0\uc785\uc758 x, y \uc0ac\uc6a9"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Positions"}),(0,i.jsx)(n.td,{children:"Positions\uc758 \uc77c\uae09 \uceec\ub809\uc158"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RouteImageDrawer"}),(0,i.jsx)(n.td,{children:"\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4 BufferedImage, Graphics2D\ub97c \uac00\uc9c0\uace0 \uc788\uc74c"}),(0,i.jsx)(n.td,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc0c1\uc218\uac00 \uc815\uc758\ub418\uc5b4 \uc788\uc74c"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RouteImageUploader"}),(0,i.jsx)(n.td,{children:"BufferedImage\ub97c \ubc1b\uc544 \uc11c\ubc84\uc5d0 \uc5c5\ub85c\ub4dc \ud558\ub294 \ud074\ub798\uc2a4"}),(0,i.jsx)(n.td,{children:"\ud604\uc7ac \uc5c5\ub85c\ub4dc \uc704\uce58\uac00 \uc815\ud574\uc9c0\uc9c0 \uc54a\uc544 \uc77c\ub2e8 \uae30\ubcf8(\ud504\ub85c\uc81d\ud2b8 \ub8e8\ud2b8) \uc704\uce58\uc5d0 \uc0dd\uc131"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RouteImageGenerator"}),(0,i.jsx)(n.td,{children:"\uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uace0 \uc5c5\ub85c\ub4dc\ud558\ub294 \uc11c\ube44\uc2a4"}),(0,i.jsx)(n.td,{children:"\uc5ec\ud589 \uc885\ub8cc, \uac10\uc0c1 \uc800\uc7a5\uc2dc \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \ud1b5\ud574 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BufferedImage(AWT)"}),(0,i.jsx)(n.td,{children:"\uc774\ubbf8\uc9c0 \ub370\uc774\ud130\ub97c \ucc98\ub9ac\ud558\uace0 \uc870\uc791\ud558\ub294 \ub370 \uc0ac\uc6a9"}),(0,i.jsx)(n.td,{children:"\uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c\uac00 (0, 0)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Graphics2D(AWT)"}),(0,i.jsx)(n.td,{children:"\uc120 \uadf8\ub9ac\uae30, \uc0c9\uc0c1 \uad00\ub9ac \ub4f1\uc744 \uc9c0\uc6d0\ud558\ub294 \ud074\ub798\uc2a4 \uc2e4\uc81c \ud574\ub2f9 \ud074\ub798\uc2a4\uc758 draw \uba54\uc11c\ub4dc\ub97c \uacbd\ub85c\ub97c \uadf8\ub9bc"}),(0,i.jsx)(n.td,{children:"JDK 1.2 \uc774\ud6c4\uc5d0 \ucd94\uac00\ub428, 2D(\ud3c9\uba74) \uadf8\ub798\ud53d \ud658\uacbd\uc744 \uc9c0\uc6d0, bufferedImage.createGraphics \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \uc0dd\uc131"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"\uc758\uc874\uad00\uacc4",children:"\uc758\uc874\uad00\uacc4"}),"\n",(0,i.jsx)(n.mermaid,{value:'graph TD\n C1[Coordinates] --\x3e C[Coordinate]\n P1[Positions] --\x3e P[Position]\n\n\tRID[RouteImageDrawer] -- "\uc911\uc559 \uc815\ub82c\ub41c Positions\ub97c \ubc1b\uc544 \uc774\ubbf8\uc9c0 \uc0dd\uc131" --\x3e P1\n\tRID --\x3e B[BufferedImage]\n\tRID --\x3e G[Graphics2D]\n\n\tC1 -- "calculatePositions \uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc704\uce58 \uacc4\uc0b0" --\x3e P1\n\n\tRIU[RouteImageUploader] --\x3e B\n\tRIG[RouteImageGenerator] --\x3e RID\n\tRIG --\x3e RIU\n\tRIG --\x3e C1\n\tRIG --\x3e P1'}),"\n",(0,i.jsx)(n.h3,{id:"coordinates\uc704\ub3c4-\uacbd\ub3c4\uc758-\uc77c\uae09-\uceec\ub809\uc158",children:"Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"List<Double>"})," 2\uac1c(\uc704\ub3c4, \uacbd\ub3c4)\uc778 \ud615\ud0dc\ub85c \uad00\ub9ac\ud558\ub294 \ubc29\ubc95\uc774 \uc788\uc5c8\uc9c0\ub9cc, \uc704\uce58 \uc810\uc744 \uc5ec\ub7ec\uac1c \ucc0d\ub294 \ubd80\ubd84\uc5d0\uc11c \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud574 \uc9c8 \uac83 \uac19\uc544\uc11c Coordinate(x, y)\uc640 \uc77c\uae09 \uceec\ub809\uc158\uc778 Coordinates\ub85c \uad00\ub9ac\ud558\uae30\ub85c \ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","Coordinates \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub450 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"calculatePositions: \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub97c \ubc1b\uc544 \uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \uc0ac\uc6a9\ub420 Positions\ub97c \ubc18\ud658"}),"\n",(0,i.jsx)(n.li,{children:"indexOf: \ub2e4\ub978 Coordinates\ub97c \ubc1b\uc544 \ub3d9\uc77c\ud55c \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4\ub97c \ubc18\ud658\ud558\ub294"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Positions \uacc4\uc0b0 \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc704\ub3c4, \uacbd\ub3c4 \uac01\uac01\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \ud544\uc694\ud55c \uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="Coordinates.java"',children:"// \ud638\ucd9c\n// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);\n// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);\n\nprivate List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {\n Double minValue = Collections.min(values);\n return values.stream()\n .map(value -> normalizeCoordinate(value, maxDifference, minValue))\n .map(value -> mapToPosition(value, routeImageSize))\n .toList();\n}\n\nprivate double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {\n return (coordinate - minValue) / maxDifference;\n}\n\nprivate int mapToPosition(Double coordinate, Integer routeImageSize) {\n return (int) (coordinate * routeImageSize);\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"\uc704\ub3c4\ub85c \uc608\uc2dc\ub4e0 \ub0b4\uc6a9\uc774\ub2e4."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Collections.min(values) \u2192 \uc704\ub3c4 \ub9ac\uc2a4\ud2b8\uc758 \ucd5c\uc18c\uac12\uc744 \uad6c\ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.li,{children:["normalizeCoordinate \u2192 \uac01\uac01\uc758 \uc704\ub3c4 \uac12\uc5d0\uc11c \ucd5c\uc18c\uac12\uc744 \ube7c\uace0 0 ~ 1 \uc0ac\uc774 \uac12\uc73c\ub85c \ubcc0\ud658 \ud6c4 ",(0,i.jsx)(n.strong,{children:"\uc704\uacbd\ub3c4\uc758 \ucd5c\ub300 \ucc28\uc774"}),"\ub85c \ub098\ub208\ub2e4."]}),"\n",(0,i.jsx)(n.li,{children:"mapToPosition \u2192 \uadf8\ub798\ud504 \ud06c\uae30\ub97c \ubc1b\uc544 0 ~ 1 \uc0ac\uc774 \uac12\uc744 \uc2e4\uc81c \uc774\ubbf8\uc9c0\ub97c \uc704\ud55c \uc704\uce58\uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"positions\uc2e4\uc81c-\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc5d0-\uc0ac\uc6a9\ud560-\uc704\uce58",children:"Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)"}),"\n",(0,i.jsx)(n.p,{children:"Positions \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub2e4\uc12f \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"align: \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\uc640 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\ub97c \ubc1b\uc544 Position \uac12\ub4e4\uc744 \uc911\uc559 \uc815\ub82c\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"getPositionsByIndexes: \uc778\ub371\uc2a4 \ub9ac\uc2a4\ud2b8\ub97c \ubc1b\uc544 \uc785\ub825\ubc1b\uc740 \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"size: \ud06c\uae30\ub97c \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"xPositions: x \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"yPositions: y \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"\uc911\uc559 \uc815\ub82c \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="Positions.java"',children:"public Positions align(int imageSize, int routeSize) {\n int xOffset = calculateOffset(Position::x, imageSize);\n int yOffset = calculateOffset(Position::y, imageSize);\n\n return items.stream()\n .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))\n .collect(collectingAndThen(toList(), Positions::new));\n}\n\nprivate int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {\n List<Integer> positions = items.stream()\n .mapToInt(positionToInteger)\n .boxed()\n .toList();\n\n int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;\n return imageSize / 2 - midValue;\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["\uc0c1\ud558\uc88c\uc6b0 \uc5ec\ubc31\uc744 \ub3d9\uc77c\ud558\uac8c \uc8fc\uae30 \uc704\ud574\uc11c offset \uac12\uc744 \uad6c\ud574\uc11c x, y \uac12\uc5d0 \uac01\uac01 \ub354\ud558\ub294 \ud615\ud0dc\ub85c \uc911\uc559 \uc815\ub82c\uc744 \uc218\ud589\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","BufferedImage\ub97c \uc0ac\uc6a9\ud560 \ub54c \uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c (0, 0) \uae30\uc900\uc73c\ub85c \uc544\ub798\ub85c \ub0b4\ub824\uac08\uc218\ub85d y \uac12\uc774 \ucee4\uc9c0\uace0, \uc624\ub978\ucabd\uc73c\ub85c \uac08 \uc218\ub85d x \uac12\uc774 \ucee4\uc9c4\ub2e4."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"./800.png",src:t(77421).Z+"",width:"968",height:"978"})}),"\n",(0,i.jsx)(n.p,{children:"\ub530\ub77c\uc11c \ucd5c\uc885\uc801\uc73c\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud55c \uac12\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uad6c\ud588\ub2e4."}),"\n",(0,i.jsxs)(n.p,{children:["x \uac12 \u2192 \uacc4\uc0b0\ud55c offset \uadf8\ub300\ub85c \ub354\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","y \uac12 \u2192 imageSize(800)\uc5d0\uc11c y + offset \uac12\uc744 \ube80\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"routeimagedrawer\uc2e4\uc81c-\uc774\ubbf8\uc9c0\uc5d0-\uacbd\ub85c\ub97c-\uadf8\ub824\uc8fc\ub294-\ud074\ub798\uc2a4",children:"RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)"}),"\n",(0,i.jsxs)(n.p,{children:["BufferedImage, Graphics2D\ub97c \ud544\ub4dc\ub85c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uadf8\ub9bc\uc744 \uadf8\ub9ac\uae30 \uc704\ud574 \uc124\uc815\ud55c \uc0c1\uc218\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="RouteImageDrawer.java"',children:"// RGB\uc5d0 \uac01\uac01 8\ube44\ud2b8\uc529 \ud560\ub2f9\ud55c \uac12\uc744 24\ube44\ud2b8 \ud2b8\ub8e8\uceec\ub7ec\ub77c \ubd80\ub978\ub2e4.\n// \ud574\ub2f9 \uc124\uc815\uc740 24\ube44\ud2b8 + 8\ube44\ud2b8(alpha, \ud22c\uba85\ub3c4)\ub97c \ucd94\uac00\ud55c 32\ube44\ud2b8 \uc774\ubbf8\uc9c0 \ud0c0\uc785\uc774\ub2e4.\n// \uc774\ub97c RGBA\ub77c\uace0 \ubd80\ub978\ub2e4.\nprivate static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;\n// \ubc30\uacbd \ud22c\uba85\uc0c9\nprivate static final Color TRANSPARENT = new Color(0, 0, 0, 0);\n// \uacbd\ub85c\ub97c \uc704\ud55c STROKE\nprivate static final int LINE_STROKE_WIDTH = 7;\nprivate static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\n// \uc704\uce58 \uc810\uc744 \uc704\ud55c STROKE\nprivate static final int POINT_STROKE_WIDTH = 20;\nprivate static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\n// \uc548\ud2f0\uc568\ub9ac\uc5b4\uc2f1 \ub4f1 \ud654\uc9c8 \uac1c\uc120\uc744 \uc704\ud55c \uc124\uc815\nprivate static final Map<Object, Object> renderingHints = Map.of(\n RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,\n RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,\n RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC\n);\n"})}),"\n",(0,i.jsx)(n.p,{children:"RouteImageDrawer \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \uc138 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"drawLine: \uc120\uc744 \uadf8\ub9b0\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"drawPoint: \uc810\uc744 \ucc0d\ub294\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"dispose: \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"dispose\uc758 \uacbd\uc6b0 \ub0b4\ubd80\uc5d0\uc11c \uc0dd\uc131\ub41c graphics2D\uc5d0 \ub300\ud55c \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud558\ub294 \uba54\uc11c\ub4dc\uc778 graphics2D.dispose\ub97c \ud638\ucd9c\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h2,{id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131-flow",children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow"}),"\n",(0,i.jsx)(n.h3,{id:"1-\uc774\ubbf8\uc9c0-\uc0dd\uc131-\uc900\ube44",children:"1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\n"}),"\n",(0,i.jsx)(n.h3,{id:"2-\uc120-\uadf8\ub9ac\uae30-\uc694\uccad",children:"2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad"}),"\n",(0,i.jsx)(n.h3,{id:"3-\uc704\uce58-\uc810-\uadf8\ub9ac\uae30-\uc694\uccad",children:"3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\n\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad"}),"\n",(0,i.jsx)(n.h3,{id:"4-\uc5c5\ub85c\ub4dc-\uc694\uccad",children:"4. \uc5c5\ub85c\ub4dc \uc694\uccad"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n \tRouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\n \tRouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n \tRouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658"}),"\n",(0,i.jsx)(n.h3,{id:"\uc804\uccb4-flow",children:"\uc804\uccb4 Flow"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\n\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\n RouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\n RouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n RouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n\t"})]})}function u(e={}){const{wrapper:n}={...(0,r.ah)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>d});var i=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function a(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){r(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,i,r=function(e,n){if(null==e)return{};var t,i,r={},o=Object.keys(e);for(i=0;i<o.length;i++)t=o[i],n.indexOf(t)>=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)t=o[i],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=i.createContext({}),d=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},u=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),m=d(t),g=r,h=m["".concat(l,".").concat(g)]||m[g]||c[g]||o;return t?i.createElement(h,a(a({ref:n},u),{},{components:t})):i.createElement(h,a({ref:n},u))}));u.displayName="MDXCreateElement"},49812:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/600-50ee65176288cb73d2c777d255460f4f.png"},77421:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/800-88542ba3914ad40b45b999e95df96cdf.png"},59563:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/result-c2887223d62510a96c9c8f733bf5edf6.png"}}]); \ No newline at end of file diff --git a/assets/js/7159c7ff.d0063e09.js b/assets/js/7159c7ff.d0063e09.js deleted file mode 100644 index 4c679cddd..000000000 --- a/assets/js/7159c7ff.d0063e09.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3287],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),m=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=m(e.components);return a.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),g=m(n),d=r,c=g["".concat(s,".").concat(d)]||g[d]||p[d]||i;return n?a.createElement(c,o(o({ref:t},u),{},{components:n})):a.createElement(c,o({ref:t},u))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,o[1]=l;for(var m=2;m<i;m++)o[m]=n[m];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}g.displayName="MDXCreateElement"},92553:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>m});var a=n(87462),r=(n(67294),n(3905));const i={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",slug:"route-image-implementation",tags:["image","awt"]},o=void 0,l={permalink:"/route-image-implementation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",source:"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",description:"\uac1c\uc694",date:"2023-08-02T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 2\uc77c",tags:[{label:"image",permalink:"/tags/image"},{label:"awt",permalink:"/tags/awt"}],readingTime:11.665,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",slug:"route-image-implementation",tags:["image","awt"]},prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",permalink:"/route-image-async-with-event"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",permalink:"/route-image-python"}},s={authorsImageUrls:[]},m=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:2},{value:"\uad6c\ud604 \uacb0\uacfc",id:"\uad6c\ud604-\uacb0\uacfc",level:3},{value:"IMAGE_SIZE & ROUTE_SIZE",id:"image_size--route_size",level:3},{value:"\uc8fc\uc694 \ud074\ub798\uc2a4",id:"\uc8fc\uc694-\ud074\ub798\uc2a4",level:2},{value:"\uc694\uc57d",id:"\uc694\uc57d",level:3},{value:"\uc758\uc874\uad00\uacc4",id:"\uc758\uc874\uad00\uacc4",level:3},{value:"Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)",id:"coordinates\uc704\ub3c4-\uacbd\ub3c4\uc758-\uc77c\uae09-\uceec\ub809\uc158",level:3},{value:"Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)",id:"positions\uc2e4\uc81c-\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc5d0-\uc0ac\uc6a9\ud560-\uc704\uce58",level:3},{value:"RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)",id:"routeimagedrawer\uc2e4\uc81c-\uc774\ubbf8\uc9c0\uc5d0-\uacbd\ub85c\ub97c-\uadf8\ub824\uc8fc\ub294-\ud074\ub798\uc2a4",level:3},{value:"\uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow",id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131-flow",level:2},{value:"1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44",id:"1-\uc774\ubbf8\uc9c0-\uc0dd\uc131-\uc900\ube44",level:3},{value:"2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad",id:"2-\uc120-\uadf8\ub9ac\uae30-\uc694\uccad",level:3},{value:"3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad",id:"3-\uc704\uce58-\uc810-\uadf8\ub9ac\uae30-\uc694\uccad",level:3},{value:"4. \uc5c5\ub85c\ub4dc \uc694\uccad",id:"4-\uc5c5\ub85c\ub4dc-\uc694\uccad",level:3},{value:"\uc804\uccb4 Flow",id:"\uc804\uccb4-flow",level:3}],u={toc:m};function p(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,r.kt)("p",null,"\uc5ec\ud589\uc5d0 \ub300\ud55c \uacbd\ub85c\ub97c \ubcf4\uc5ec\uc8fc\uae30 \uc704\ud574 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d \ubc0f \uae30\uc220 \uc120\ud0dd\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 ",(0,r.kt)("a",{parentName:"p",href:"./route-image-intro"},"\ub9c1\ud06c"),"\uc5d0 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\uad6c\ud604-\uacb0\uacfc"},"\uad6c\ud604 \uacb0\uacfc"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./result.png",src:n(59563).Z,width:"1840",height:"714"})),(0,r.kt)("p",null,"\uc608\uc2dc \ub370\uc774\ud130\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("strong",{parentName:"p"},"\uc11c\uc6b8\uc5ed(\uc810)")," \u2192 \uc2e0\uc0ac\uc5ed \u2192 \ub178\ub7c9\uc9c4\uc5ed \u2192 \ud64d\ub300\uc785\uad6c\uc5ed \u2192 \uc885\ub85c3\uac00\uc5ed \u2192 \uc625\uc218\uc5ed \u2192 ",(0,r.kt)("strong",{parentName:"p"},"\uad6c\ub85c\uc5ed(\uc810)")," \u2192 \uc2e0\ub9bc\uc5ed \u2192 \ubc1c\uc0b0\uc5ed"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="\uc608\uc2dc \ub370\uc774\ud130"',title:'"\uc608\uc2dc','\ub370\uc774\ud130"':!0},"List<Double> x = List.of(\n 126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,\n 126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639\n);\nList<Double> y = List.of(\n 37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,\n 37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184\n);\nList<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);\nList<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);\n")),(0,r.kt)("h3",{id:"image_size--route_size"},"IMAGE_SIZE & ROUTE_SIZE"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="RouteImageGenerator.java"',title:'"RouteImageGenerator.java"'},"private static final int IMAGE_SIZE = 800;\nprivate static final int ROUTE_SIZE = 600;\n")),(0,r.kt)("p",null,"\ucf54\ub4dc\ub97c \ubcf4\uba74 IMAGE_SIZE\uc640 ROUTE_SIZE\uac00 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","IMAGE_SIZE\ub294 \ub9d0 \uadf8\ub300\ub85c \uc774\ubbf8\uc9c0\uc758 width\uc640 height\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","ROUTE_SIZE\uc758 \uacbd\uc6b0 \uc0c1\ud558\uc88c\uc6b0 100px \ub9cc\ud07c\uc758 \uac04\uaca9\uc744 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc2e4\uc81c \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub294 600 * 600 \uc0ac\uc774\uc988\ub85c \uc0dd\uc131\ub41c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./600.png",src:n(49812).Z,width:"976",height:"970"})),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uc0ac\uc774\uc988 \ubcc0\uacbd\uc758 \uc774\uc720")),(0,r.kt)("p",null,"255 ",(0,r.kt)("em",{parentName:"p"}," 255 \uc815\ub3c4\uc758 \uc791\uc740 \uc0ac\uc774\uc988\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud574\ubcf4\ub824\uace0 \ud588\ub294\ub370, \uc774\ubbf8\uc9c0\uc758 \uc120\uba85\ub3c4\uac00 \uc88b\uc9c0 \uc54a\uc544 800 ")," 800 \uc0ac\uc774\uc988\ub85c \ubcc0\uacbd\ud588\ub2e4."),(0,r.kt)("h2",{id:"\uc8fc\uc694-\ud074\ub798\uc2a4"},"\uc8fc\uc694 \ud074\ub798\uc2a4"),(0,r.kt)("h3",{id:"\uc694\uc57d"},"\uc694\uc57d"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\ud074\ub798\uc2a4\uba85"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"),(0,r.kt)("th",{parentName:"tr",align:null},"\ud2b9\uc774\uc0ac\ud56d"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Coordinate"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \uc704\uce58 \uac12"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc88c\ud45c\ub97c \ub73b\ud558\uc9c0\ub9cc \uc5ec\ud589 \ub3c4\uba54\uc778\uc5d0 \ud3ec\ud568\ub41c Point \ud074\ub798\uc2a4\uc640 \uad6c\ubd84\ud558\uae30 \uc704\ud574 longitude, latitude\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 x, y \uc0ac\uc6a9")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Coordinates"),(0,r.kt)("td",{parentName:"tr",align:null},"Coordinate\uc758 \uc77c\uae09 \uceec\ub809\uc158"),(0,r.kt)("td",{parentName:"tr",align:null},"-")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Position"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58 \uac12"),(0,r.kt)("td",{parentName:"tr",align:null},"Integer \ud0c0\uc785\uc758 x, y \uc0ac\uc6a9")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Positions"),(0,r.kt)("td",{parentName:"tr",align:null},"Positions\uc758 \uc77c\uae09 \uceec\ub809\uc158"),(0,r.kt)("td",{parentName:"tr",align:null},"-")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RouteImageDrawer"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4 BufferedImage, Graphics2D\ub97c \uac00\uc9c0\uace0 \uc788\uc74c"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc0c1\uc218\uac00 \uc815\uc758\ub418\uc5b4 \uc788\uc74c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RouteImageUploader"),(0,r.kt)("td",{parentName:"tr",align:null},"BufferedImage\ub97c \ubc1b\uc544 \uc11c\ubc84\uc5d0 \uc5c5\ub85c\ub4dc \ud558\ub294 \ud074\ub798\uc2a4"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud604\uc7ac \uc5c5\ub85c\ub4dc \uc704\uce58\uac00 \uc815\ud574\uc9c0\uc9c0 \uc54a\uc544 \uc77c\ub2e8 \uae30\ubcf8(\ud504\ub85c\uc81d\ud2b8 \ub8e8\ud2b8) \uc704\uce58\uc5d0 \uc0dd\uc131")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RouteImageGenerator"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uace0 \uc5c5\ub85c\ub4dc\ud558\ub294 \uc11c\ube44\uc2a4"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc5ec\ud589 \uc885\ub8cc, \uac10\uc0c1 \uc800\uc7a5\uc2dc \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \ud1b5\ud574 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"BufferedImage(AWT)"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc774\ubbf8\uc9c0 \ub370\uc774\ud130\ub97c \ucc98\ub9ac\ud558\uace0 \uc870\uc791\ud558\ub294 \ub370 \uc0ac\uc6a9"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c\uac00 (0, 0)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Graphics2D(AWT)"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc120 \uadf8\ub9ac\uae30, \uc0c9\uc0c1 \uad00\ub9ac \ub4f1\uc744 \uc9c0\uc6d0\ud558\ub294 \ud074\ub798\uc2a4 \uc2e4\uc81c \ud574\ub2f9 \ud074\ub798\uc2a4\uc758 draw \uba54\uc11c\ub4dc\ub97c \uacbd\ub85c\ub97c \uadf8\ub9bc"),(0,r.kt)("td",{parentName:"tr",align:null},"JDK 1.2 \uc774\ud6c4\uc5d0 \ucd94\uac00\ub428, 2D(\ud3c9\uba74) \uadf8\ub798\ud53d \ud658\uacbd\uc744 \uc9c0\uc6d0, bufferedImage.createGraphics \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \uc0dd\uc131")))),(0,r.kt)("h3",{id:"\uc758\uc874\uad00\uacc4"},"\uc758\uc874\uad00\uacc4"),(0,r.kt)("mermaid",{value:'graph TD\n C1[Coordinates] --\x3e C[Coordinate]\n P1[Positions] --\x3e P[Position]\n\n\tRID[RouteImageDrawer] -- "\uc911\uc559 \uc815\ub82c\ub41c Positions\ub97c \ubc1b\uc544 \uc774\ubbf8\uc9c0 \uc0dd\uc131" --\x3e P1\n\tRID --\x3e B[BufferedImage]\n\tRID --\x3e G[Graphics2D]\n\n\tC1 -- "calculatePositions \uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc704\uce58 \uacc4\uc0b0" --\x3e P1\n\n\tRIU[RouteImageUploader] --\x3e B\n\tRIG[RouteImageGenerator] --\x3e RID\n\tRIG --\x3e RIU\n\tRIG --\x3e C1\n\tRIG --\x3e P1'}),(0,r.kt)("h3",{id:"coordinates\uc704\ub3c4-\uacbd\ub3c4\uc758-\uc77c\uae09-\uceec\ub809\uc158"},"Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"List<Double>")," 2\uac1c(\uc704\ub3c4, \uacbd\ub3c4)\uc778 \ud615\ud0dc\ub85c \uad00\ub9ac\ud558\ub294 \ubc29\ubc95\uc774 \uc788\uc5c8\uc9c0\ub9cc, \uc704\uce58 \uc810\uc744 \uc5ec\ub7ec\uac1c \ucc0d\ub294 \ubd80\ubd84\uc5d0\uc11c \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud574 \uc9c8 \uac83 \uac19\uc544\uc11c Coordinate(x, y)\uc640 \uc77c\uae09 \uceec\ub809\uc158\uc778 Coordinates\ub85c \uad00\ub9ac\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Coordinates \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub450 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"calculatePositions: \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub97c \ubc1b\uc544 \uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \uc0ac\uc6a9\ub420 Positions\ub97c \ubc18\ud658"),(0,r.kt)("li",{parentName:"ul"},"indexOf: \ub2e4\ub978 Coordinates\ub97c \ubc1b\uc544 \ub3d9\uc77c\ud55c \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4\ub97c \ubc18\ud658\ud558\ub294 ")),(0,r.kt)("p",null,"Positions \uacc4\uc0b0 \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc704\ub3c4, \uacbd\ub3c4 \uac01\uac01\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \ud544\uc694\ud55c \uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="Coordinates.java"',title:'"Coordinates.java"'},"// \ud638\ucd9c\n// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);\n// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);\n\nprivate List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {\n Double minValue = Collections.min(values);\n return values.stream()\n .map(value -> normalizeCoordinate(value, maxDifference, minValue))\n .map(value -> mapToPosition(value, routeImageSize))\n .toList();\n}\n\nprivate double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {\n return (coordinate - minValue) / maxDifference;\n}\n\nprivate int mapToPosition(Double coordinate, Integer routeImageSize) {\n return (int) (coordinate * routeImageSize);\n}\n")),(0,r.kt)("p",null,"\uc704\ub3c4\ub85c \uc608\uc2dc\ub4e0 \ub0b4\uc6a9\uc774\ub2e4."),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Collections.min(values) \u2192 \uc704\ub3c4 \ub9ac\uc2a4\ud2b8\uc758 \ucd5c\uc18c\uac12\uc744 \uad6c\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ol"},"normalizeCoordinate \u2192 \uac01\uac01\uc758 \uc704\ub3c4 \uac12\uc5d0\uc11c \ucd5c\uc18c\uac12\uc744 \ube7c\uace0 0 ~ 1 \uc0ac\uc774 \uac12\uc73c\ub85c \ubcc0\ud658 \ud6c4 ",(0,r.kt)("strong",{parentName:"li"},"\uc704\uacbd\ub3c4\uc758 \ucd5c\ub300 \ucc28\uc774"),"\ub85c \ub098\ub208\ub2e4."),(0,r.kt)("li",{parentName:"ol"},"mapToPosition \u2192 \uadf8\ub798\ud504 \ud06c\uae30\ub97c \ubc1b\uc544 0 ~ 1 \uc0ac\uc774 \uac12\uc744 \uc2e4\uc81c \uc774\ubbf8\uc9c0\ub97c \uc704\ud55c \uc704\uce58\uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4.")),(0,r.kt)("h3",{id:"positions\uc2e4\uc81c-\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc5d0-\uc0ac\uc6a9\ud560-\uc704\uce58"},"Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)"),(0,r.kt)("p",null,"Positions \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub2e4\uc12f \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"align: \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\uc640 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\ub97c \ubc1b\uc544 Position \uac12\ub4e4\uc744 \uc911\uc559 \uc815\ub82c\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"getPositionsByIndexes: \uc778\ub371\uc2a4 \ub9ac\uc2a4\ud2b8\ub97c \ubc1b\uc544 \uc785\ub825\ubc1b\uc740 \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"size: \ud06c\uae30\ub97c \ubc18\ud658\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"xPositions: x \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"yPositions: y \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4.")),(0,r.kt)("p",null,"\uc911\uc559 \uc815\ub82c \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="Positions.java"',title:'"Positions.java"'},"public Positions align(int imageSize, int routeSize) {\n int xOffset = calculateOffset(Position::x, imageSize);\n int yOffset = calculateOffset(Position::y, imageSize);\n\n return items.stream()\n .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))\n .collect(collectingAndThen(toList(), Positions::new));\n}\n\nprivate int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {\n List<Integer> positions = items.stream()\n .mapToInt(positionToInteger)\n .boxed()\n .toList();\n\n int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;\n return imageSize / 2 - midValue;\n}\n")),(0,r.kt)("p",null,"\uc0c1\ud558\uc88c\uc6b0 \uc5ec\ubc31\uc744 \ub3d9\uc77c\ud558\uac8c \uc8fc\uae30 \uc704\ud574\uc11c offset \uac12\uc744 \uad6c\ud574\uc11c x, y \uac12\uc5d0 \uac01\uac01 \ub354\ud558\ub294 \ud615\ud0dc\ub85c \uc911\uc559 \uc815\ub82c\uc744 \uc218\ud589\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","BufferedImage\ub97c \uc0ac\uc6a9\ud560 \ub54c \uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c (0, 0) \uae30\uc900\uc73c\ub85c \uc544\ub798\ub85c \ub0b4\ub824\uac08\uc218\ub85d y \uac12\uc774 \ucee4\uc9c0\uace0, \uc624\ub978\ucabd\uc73c\ub85c \uac08 \uc218\ub85d x \uac12\uc774 \ucee4\uc9c4\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./800.png",src:n(77421).Z,width:"968",height:"978"})),(0,r.kt)("p",null,"\ub530\ub77c\uc11c \ucd5c\uc885\uc801\uc73c\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud55c \uac12\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uad6c\ud588\ub2e4."),(0,r.kt)("p",null,"x \uac12 \u2192 \uacc4\uc0b0\ud55c offset \uadf8\ub300\ub85c \ub354\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","y \uac12 \u2192 imageSize(800)\uc5d0\uc11c y + offset \uac12\uc744 \ube80\ub2e4. "),(0,r.kt)("h3",{id:"routeimagedrawer\uc2e4\uc81c-\uc774\ubbf8\uc9c0\uc5d0-\uacbd\ub85c\ub97c-\uadf8\ub824\uc8fc\ub294-\ud074\ub798\uc2a4"},"RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)"),(0,r.kt)("p",null,"BufferedImage, Graphics2D\ub97c \ud544\ub4dc\ub85c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uadf8\ub9bc\uc744 \uadf8\ub9ac\uae30 \uc704\ud574 \uc124\uc815\ud55c \uc0c1\uc218\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="RouteImageDrawer.java"',title:'"RouteImageDrawer.java"'},"// RGB\uc5d0 \uac01\uac01 8\ube44\ud2b8\uc529 \ud560\ub2f9\ud55c \uac12\uc744 24\ube44\ud2b8 \ud2b8\ub8e8\uceec\ub7ec\ub77c \ubd80\ub978\ub2e4.\n// \ud574\ub2f9 \uc124\uc815\uc740 24\ube44\ud2b8 + 8\ube44\ud2b8(alpha, \ud22c\uba85\ub3c4)\ub97c \ucd94\uac00\ud55c 32\ube44\ud2b8 \uc774\ubbf8\uc9c0 \ud0c0\uc785\uc774\ub2e4.\n// \uc774\ub97c RGBA\ub77c\uace0 \ubd80\ub978\ub2e4.\nprivate static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;\n// \ubc30\uacbd \ud22c\uba85\uc0c9\nprivate static final Color TRANSPARENT = new Color(0, 0, 0, 0);\n// \uacbd\ub85c\ub97c \uc704\ud55c STROKE\nprivate static final int LINE_STROKE_WIDTH = 7;\nprivate static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\n// \uc704\uce58 \uc810\uc744 \uc704\ud55c STROKE\nprivate static final int POINT_STROKE_WIDTH = 20;\nprivate static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\n// \uc548\ud2f0\uc568\ub9ac\uc5b4\uc2f1 \ub4f1 \ud654\uc9c8 \uac1c\uc120\uc744 \uc704\ud55c \uc124\uc815\nprivate static final Map<Object, Object> renderingHints = Map.of(\n RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,\n RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,\n RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC\n);\n")),(0,r.kt)("p",null,"RouteImageDrawer \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \uc138 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"drawLine: \uc120\uc744 \uadf8\ub9b0\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"drawPoint: \uc810\uc744 \ucc0d\ub294\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"dispose: \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud55c\ub2e4. ")),(0,r.kt)("p",null,"dispose\uc758 \uacbd\uc6b0 \ub0b4\ubd80\uc5d0\uc11c \uc0dd\uc131\ub41c graphics2D\uc5d0 \ub300\ud55c \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud558\ub294 \uba54\uc11c\ub4dc\uc778 graphics2D.dispose\ub97c \ud638\ucd9c\ud55c\ub2e4."),(0,r.kt)("h2",{id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131-flow"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow"),(0,r.kt)("h3",{id:"1-\uc774\ubbf8\uc9c0-\uc0dd\uc131-\uc900\ube44"},"1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\n"}),(0,r.kt)("h3",{id:"2-\uc120-\uadf8\ub9ac\uae30-\uc694\uccad"},"2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad"}),(0,r.kt)("h3",{id:"3-\uc704\uce58-\uc810-\uadf8\ub9ac\uae30-\uc694\uccad"},"3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\n\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad"}),(0,r.kt)("h3",{id:"4-\uc5c5\ub85c\ub4dc-\uc694\uccad"},"4. \uc5c5\ub85c\ub4dc \uc694\uccad"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n \tRouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\n \tRouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n \tRouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658"}),(0,r.kt)("h3",{id:"\uc804\uccb4-flow"},"\uc804\uccb4 Flow"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\n\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\n RouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\n RouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n RouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n\t"}))}p.isMDXComponent=!0},49812:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/600-50ee65176288cb73d2c777d255460f4f.png"},77421:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/800-88542ba3914ad40b45b999e95df96cdf.png"},59563:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/result-c2887223d62510a96c9c8f733bf5edf6.png"}}]); \ No newline at end of file diff --git a/assets/js/72657f57.a5decd7b.js b/assets/js/72657f57.a5decd7b.js deleted file mode 100644 index 568194332..000000000 --- a/assets/js/72657f57.a5decd7b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9581],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>b});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),m=l(r),b=a,g=m["".concat(i,".").concat(b)]||m[b]||u[b]||p;return r?n.createElement(g,o(o({ref:t},s),{},{components:r})):n.createElement(g,o({ref:t},s))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,o[1]=c;for(var l=2;l<p;l++)o[l]=r[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},8046:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>p,metadata:()=>c,toc:()=>l});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",slug:"web-racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,c={permalink:"/web-racing-car-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-racingcar/pull/24",date:"2023-05-02T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 2\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.6,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",slug:"web-racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",permalink:"/shopping-cart-retrospective"},nextItem:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",permalink:"/tecochat-retrospective-2"}},i={authorsImageUrls:[]},l=[{value:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158",id:"\uc6f9-\uc790\ub3d9\ucc28-\ubbf8\uc158",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],s={toc:l};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-racingcar/pull/24"},"https://github.com/woowacourse/jwp-racingcar/pull/24"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-racingcar/pull/128"},"https://github.com/woowacourse/jwp-racingcar/pull/128")," ")),(0,a.kt)("h3",{id:"\uc6f9-\uc790\ub3d9\ucc28-\ubbf8\uc158"},"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158"),(0,a.kt)("p",null,"\uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud55c\ub2e4\uace0 \uc2dc\uac04\uc774 \ub9ce\uc774 \uc5c6\uc5b4\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc84c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158\uc5d0\uc11c\ub294 \ube44\ubc84\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 2\uc5d0\uc11c \uc9c4\ud589\ud558\ub294 \uccab \ubbf8\uc158\uc774\ub77c \ub9ce\uc774 \uae34\uc7a5\ub418\uc5c8\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ube44\ubc84\ub791 \ucd08\ubc18\uc5d0 \ub9db\uc788\ub294 \uac83\ub3c4 \ub9ce\uc774 \uba39\uc73c\uba74\uc11c \ube68\ub9ac \uce5c\ud574\uc838\uc11c \uc7ac\ubc0c\uac8c \ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uc744 \uc870\uae08 \uc0ac\uc6a9\ud560 \uc904 \uc54c\uc544\uc11c, \ube44\ubc84\ub791 \uac19\uc774 \ud559\uc2b5\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uccab \ubbf8\uc158\uc774\ub77c \uadf8\ub7f0\uc9c0 \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc740 \uc5c6\uc5c8\uace0, \ucd5c\ub300\ud55c \uae54\ub054\ud558\uac8c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub09c\uc774\ub3c4 \ub192\uc740 \ubbf8\uc158\uc774 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ub9ac\ubdf0\uc5b4\uc778 \ub77c\ube48\uc5d0\uac8c \uce6d\ucc2c\uc744 \ub9ce\uc774 \ubc1b\uc544\uc11c \uae30\ubd84\uc774 \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub77c\ube48 \uac10\uc0ac\ud569\ub2c8\ub2e4! "),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,"\ucee8\ub514\uc158\ub3c4 \uc88b\uc9c0 \uc54a\uace0 \uc5f4\uc815\ub3c4 \uc2dd\uc740 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc774 \ub2e4\uc18c \uc5ec\uc720\ub86d\ub2e4\uace0 \ub290\uaef4\uc838\uc11c, \uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ubd84\ub3c4 \uc798 \uad00\ub9ac\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud574\uc11c \ud398\uc5b4\uc5d0\uac8c \ub9ce\uc774 \ubbf8\uc548\ud588\uace0, \ub098 \uc790\uc2e0\uc5d0\uac8c \uc544\uc26c\uc6e0\ub358 \ubd80\ubd84\uc774 \ub9ce\uc558\ub2e4. "),(0,a.kt)("p",null,"\uc9c0\ub09c\ubc88 \ud68c\uace0\ub97c \ub2e4\uc2dc \ubcf4\ub294\ub370 \uc9d1\uc911\uc744 \uc798 \ubabb\ud55c \uacbd\uc6b0\uac00 \ub9ce\uc740 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub3c4\uc804\uc801\uc774\uc9c0 \uc54a\uac70\ub098 \uc2dc\uac04\uc774 \ubd80\uc871\ud558\uc9c0 \uc54a\uc73c\uba74 \uc9d1\uc911\uc744 \uc798 \ubabb\ud558\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uba38\ub9bf\uc18d\uc5d0\uc11c \uc2dc\uac04\uc801 \uc5ec\uc720\uac00 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \ub54c\uac00 \uac00\uc7a5 \uc704\ud5d8\ud55c \uc21c\uac04\uc778 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\ud568\uaed8 \uc790\ub77c\uae30\uc5d0\uc11c \ub098\uc628 ",(0,a.kt)("inlineCode",{parentName:"p"},"\ub09c\uc774\ub3c4 \ub192\uc774\uae30"),"\uac00 \ud544\uc694\ud574\uc9c0\ub294 \uc21c\uac04\uc774\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc911\uc694\ub3c4\uac00 \uc788\ub294 \uc5b4\ub178\ud14c\uc774\uc158\ubd80\ud130 \ud074\ub798\uc2a4 \uc774\ub984\uc5d0 \uac00\uae5d\uac8c \uba85\uc2dc\ud558\uae30")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@SuppressWarnings("NonAsciiCharacters")\n@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)\n@Transactional\n@AutoConfigureMockMvc\n@SpringBootTest\npublic class RacingGameIntegrationTest {\n')),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ube44\ubc84\uc758 \uc131\uaca9"),(0,a.kt)("br",{parentName:"p"}),"\n","\ube44\ubc84\uac00 \uc131\uaca9\uc774 \uc88b\uc544\uc11c \ud3b8\ud558\uac8c \ud398\uc5b4\ub97c \ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc131\uae09\ud558\uc9c0 \uc54a\uace0 \uc5ec\uc720\ub85c\uc6cc\uc11c \uc88b\uc558\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ubbf8\uc158\uc5d0 \uc9d1\uc911\ud558\ub294 \ubd80\ubd84"),(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud588\ub294\ub370\ub3c4 \uac19\uc774 \ud398\uc5b4\ub97c \uc798 \uc9c4\ud589\ud55c \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube44\ubc84\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud574\uc11c \uadf8\ub807\uc9c0 \uc54a\uc558\ub098 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadfc\uc721\ub9e8 \ube44\ubc84\ub77c \uadf8\ub7f0\uc9c0 \uccb4\ub825\uc774 \uc88b\uc544\uc11c \uadf8\ub7f0\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04\uc5d0 \uc798 \uc548 \uc26c\uace0\ub3c4 \uc9d1\uc911\ud574\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac78 \ubcf4\uace0 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud559\uc2b5\uc5d0 \ub300\ud55c \uc5f4\uc815"),(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\uc801\uc73c\ub85c \uc54c\uace0 \uc2f6\uc740 \ubd80\ubd84\uc744 \ub530\ub85c \ud559\uc2b5\ud558\ub294 \uc5f4\uc815\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube44\ubc84\uc640 \uc2a4\ud504\ub9c1\uc5d0 \ub300\ud574 \uc54c\uc544\uac00\ub294 \uc2dc\uac04\uc744 \ub9ce\uc774 \uac00\uc9c4 \ubd80\ubd84\uc774 \ub9e4\uc6b0 \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 5\uc6d4\ubd80\ud130 \uc870\uae08 \ub354 \ud654\uc774\ud305 \ud574\uc57c\uaca0\ub2e4."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/72657f57.cd507c93.js b/assets/js/72657f57.cd507c93.js new file mode 100644 index 000000000..b27b43506 --- /dev/null +++ b/assets/js/72657f57.cd507c93.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9581],{32262:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var t=n(85893),s=n(3905);const c={title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",slug:"web-racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,a={permalink:"/web-racing-car-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-racingcar/pull/24",date:"2023-05-02T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 2\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.6,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",slug:"web-racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",permalink:"/shopping-cart-retrospective"},nextItem:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",permalink:"/tecochat-retrospective-2"}},i={authorsImageUrls:[]},l=[{value:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158",id:"\uc6f9-\uc790\ub3d9\ucc28-\ubbf8\uc158",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function p(e){const r={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-racingcar/pull/24",children:"https://github.com/woowacourse/jwp-racingcar/pull/24"}),(0,t.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-racingcar/pull/128",children:"https://github.com/woowacourse/jwp-racingcar/pull/128"})]})}),"\n",(0,t.jsx)(r.h3,{id:"\uc6f9-\uc790\ub3d9\ucc28-\ubbf8\uc158",children:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158"}),"\n",(0,t.jsxs)(r.p,{children:["\uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud55c\ub2e4\uace0 \uc2dc\uac04\uc774 \ub9ce\uc774 \uc5c6\uc5b4\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc84c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158\uc5d0\uc11c\ub294 \ube44\ubc84\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub808\ubca8 2\uc5d0\uc11c \uc9c4\ud589\ud558\ub294 \uccab \ubbf8\uc158\uc774\ub77c \ub9ce\uc774 \uae34\uc7a5\ub418\uc5c8\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ube44\ubc84\ub791 \ucd08\ubc18\uc5d0 \ub9db\uc788\ub294 \uac83\ub3c4 \ub9ce\uc774 \uba39\uc73c\uba74\uc11c \ube68\ub9ac \uce5c\ud574\uc838\uc11c \uc7ac\ubc0c\uac8c \ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc2a4\ud504\ub9c1\uc744 \uc870\uae08 \uc0ac\uc6a9\ud560 \uc904 \uc54c\uc544\uc11c, \ube44\ubc84\ub791 \uac19\uc774 \ud559\uc2b5\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uccab \ubbf8\uc158\uc774\ub77c \uadf8\ub7f0\uc9c0 \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc740 \uc5c6\uc5c8\uace0, \ucd5c\ub300\ud55c \uae54\ub054\ud558\uac8c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub09c\uc774\ub3c4 \ub192\uc740 \ubbf8\uc158\uc774 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ub9ac\ubdf0\uc5b4\uc778 \ub77c\ube48\uc5d0\uac8c \uce6d\ucc2c\uc744 \ub9ce\uc774 \ubc1b\uc544\uc11c \uae30\ubd84\uc774 \uc88b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub77c\ube48 \uac10\uc0ac\ud569\ub2c8\ub2e4!"]}),"\n",(0,t.jsx)(r.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:["\ucee8\ub514\uc158\ub3c4 \uc88b\uc9c0 \uc54a\uace0 \uc5f4\uc815\ub3c4 \uc2dd\uc740 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc774 \ub2e4\uc18c \uc5ec\uc720\ub86d\ub2e4\uace0 \ub290\uaef4\uc838\uc11c, \uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ubd84\ub3c4 \uc798 \uad00\ub9ac\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud574\uc11c \ud398\uc5b4\uc5d0\uac8c \ub9ce\uc774 \ubbf8\uc548\ud588\uace0, \ub098 \uc790\uc2e0\uc5d0\uac8c \uc544\uc26c\uc6e0\ub358 \ubd80\ubd84\uc774 \ub9ce\uc558\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc9c0\ub09c\ubc88 \ud68c\uace0\ub97c \ub2e4\uc2dc \ubcf4\ub294\ub370 \uc9d1\uc911\uc744 \uc798 \ubabb\ud55c \uacbd\uc6b0\uac00 \ub9ce\uc740 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub3c4\uc804\uc801\uc774\uc9c0 \uc54a\uac70\ub098 \uc2dc\uac04\uc774 \ubd80\uc871\ud558\uc9c0 \uc54a\uc73c\uba74 \uc9d1\uc911\uc744 \uc798 \ubabb\ud558\ub294 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uba38\ub9bf\uc18d\uc5d0\uc11c \uc2dc\uac04\uc801 \uc5ec\uc720\uac00 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \ub54c\uac00 \uac00\uc7a5 \uc704\ud5d8\ud55c \uc21c\uac04\uc778 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ud568\uaed8 \uc790\ub77c\uae30\uc5d0\uc11c \ub098\uc628 ",(0,t.jsx)(r.code,{children:"\ub09c\uc774\ub3c4 \ub192\uc774\uae30"}),"\uac00 \ud544\uc694\ud574\uc9c0\ub294 \uc21c\uac04\uc774\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uc911\uc694\ub3c4\uac00 \uc788\ub294 \uc5b4\ub178\ud14c\uc774\uc158\ubd80\ud130 \ud074\ub798\uc2a4 \uc774\ub984\uc5d0 \uac00\uae5d\uac8c \uba85\uc2dc\ud558\uae30"})}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-java",children:'@SuppressWarnings("NonAsciiCharacters")\n@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)\n@Transactional\n@AutoConfigureMockMvc\n@SpringBootTest\npublic class RacingGameIntegrationTest {\n'})}),"\n",(0,t.jsx)(r.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ube44\ubc84\uc758 \uc131\uaca9"}),(0,t.jsx)(r.br,{}),"\n","\ube44\ubc84\uac00 \uc131\uaca9\uc774 \uc88b\uc544\uc11c \ud3b8\ud558\uac8c \ud398\uc5b4\ub97c \ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc131\uae09\ud558\uc9c0 \uc54a\uace0 \uc5ec\uc720\ub85c\uc6cc\uc11c \uc88b\uc558\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ubbf8\uc158\uc5d0 \uc9d1\uc911\ud558\ub294 \ubd80\ubd84"}),(0,t.jsx)(r.br,{}),"\n","\ub0b4\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud588\ub294\ub370\ub3c4 \uac19\uc774 \ud398\uc5b4\ub97c \uc798 \uc9c4\ud589\ud55c \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ube44\ubc84\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud574\uc11c \uadf8\ub807\uc9c0 \uc54a\uc558\ub098 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uadfc\uc721\ub9e8 \ube44\ubc84\ub77c \uadf8\ub7f0\uc9c0 \uccb4\ub825\uc774 \uc88b\uc544\uc11c \uadf8\ub7f0\uac00?",(0,t.jsx)(r.br,{}),"\n","\uc911\uac04\uc5d0 \uc798 \uc548 \uc26c\uace0\ub3c4 \uc9d1\uc911\ud574\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac78 \ubcf4\uace0 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.strong,{children:"\ud559\uc2b5\uc5d0 \ub300\ud55c \uc5f4\uc815"}),(0,t.jsx)(r.br,{}),"\n","\ucd94\uac00\uc801\uc73c\ub85c \uc54c\uace0 \uc2f6\uc740 \ubd80\ubd84\uc744 \ub530\ub85c \ud559\uc2b5\ud558\ub294 \uc5f4\uc815\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ube44\ubc84\uc640 \uc2a4\ud504\ub9c1\uc5d0 \ub300\ud574 \uc54c\uc544\uac00\ub294 \uc2dc\uac04\uc744 \ub9ce\uc774 \uac00\uc9c4 \ubd80\ubd84\uc774 \ub9e4\uc6b0 \uc88b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub098\ub3c4 5\uc6d4\ubd80\ud130 \uc870\uae08 \ub354 \ud654\uc774\ud305 \ud574\uc57c\uaca0\ub2e4."]})]})}function u(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>l});var t=n(67294);function s(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function c(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?c(Object(n),!0).forEach((function(r){s(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function a(e,r){if(null==e)return{};var n,t,s=function(e,r){if(null==e)return{};var n,t,s={},c=Object.keys(e);for(t=0;t<c.length;t++)n=c[t],r.indexOf(n)>=0||(s[n]=e[n]);return s}(e,r);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t<c.length;t++)n=c[t],r.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var i=t.createContext({}),l=function(e){var r=t.useContext(i),n=r;return e&&(n="function"==typeof e?e(r):o(o({},r),e)),n},p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},u=t.forwardRef((function(e,r){var n=e.components,s=e.mdxType,c=e.originalType,i=e.parentName,u=a(e,["components","mdxType","originalType","parentName"]),h=l(n),j=s,d=h["".concat(i,".").concat(j)]||h[j]||p[j]||c;return n?t.createElement(d,o(o({ref:r},u),{},{components:n})):t.createElement(d,o({ref:r},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/73688d5c.50416e9c.js b/assets/js/73688d5c.50416e9c.js new file mode 100644 index 000000000..772c500c6 --- /dev/null +++ b/assets/js/73688d5c.50416e9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6908],{90465:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>b,frontMatter:()=>i,metadata:()=>s,toc:()=>o});var t=a(85893),r=a(3905);const i={title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",slug:"transaction-and-isolation",tags:["DataBase","Transaction","Isolation"]},l=void 0,s={permalink:"/transaction-and-isolation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",source:"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",description:"\ud2b8\ub79c\uc7ad\uc158(Transaction)",date:"2023-04-05T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 5\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Transaction",permalink:"/tags/transaction"},{label:"Isolation",permalink:"/tags/isolation"}],readingTime:9.57,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",slug:"transaction-and-isolation",tags:["DataBase","Transaction","Isolation"]},unlisted:!1,prevItem:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/mysql-lock"},nextItem:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",permalink:"/test-double"}},c={authorsImageUrls:[]},o=[{value:"\ud2b8\ub79c\uc7ad\uc158(Transaction)",id:"\ud2b8\ub79c\uc7ad\uc158transaction",level:2},{value:"\ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)",id:"\ud2b8\ub79c\uc7ad\uc158\uc758-\uc18d\uc131acid",level:3},{value:"\ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d",id:"\ud2b8\ub79c\uc7ad\uc158-\uc8fc\uc758\uc0ac\ud56d",level:3},{value:"\uaca9\ub9ac \uc218\uc900(Isolation level)",id:"\uaca9\ub9ac-\uc218\uc900isolation-level",level:2},{value:"READ UNCOMMITTED",id:"read-uncommitted",level:3},{value:"READ COMMITTED",id:"read-committed",level:3},{value:"REPEATABLE READ",id:"repeatable-read",level:3},{value:"SERIALIZABLE",id:"serializable",level:3},{value:"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c",id:"\uaca9\ub9ac-\uc218\uc900\uc5d0-\ub530\ub978-\ubd80\uc815\ud569-\ubb38\uc81c",level:2},{value:"\ub354\ud2f0 \ub9ac\ub4dc(Dirty read)",id:"\ub354\ud2f0-\ub9ac\ub4dcdirty-read",level:3},{value:"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)",id:"\ubc18\ubcf5-\uac00\ub2a5\ud558\uc9c0-\uc54a\uc740-\uc870\ud68cnon-repeatable-read",level:3},{value:"\ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)",id:"\ud32c\ud140-\ub9ac\ub4dcphantom-read-phantom-row",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",mermaid:"mermaid",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"\ud2b8\ub79c\uc7ad\uc158transaction",children:"\ud2b8\ub79c\uc7ad\uc158(Transaction)"}),"\n",(0,t.jsxs)(n.p,{children:["\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \ub17c\ub9ac\uc801 \uae30\ub2a5\uc744 \uc218\ud589\ud558\uae30 \uc704\ud55c \uc791\uc5c5\uc758 \ub2e8\uc704\ub97c \ub9d0\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc740 \uc791\uc5c5\uc758 \uc644\uc804\uc131\uacfc \ub370\uc774\ud130\uc758 \uc815\ud569\uc131\uc744 \ubcf4\uc7a5\ud574 \uc900\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub17c\ub9ac\uc801\uc778 \uc791\uc5c5 \uc14b\uc744 \uc644\ubcbd\ud558\uac8c \ucc98\ub9ac\ud558\uac70\ub098, \uc624\ub958 \uc2dc \uc791\uc5c5\uc758 \uc77c\ubd80\ub9cc \uc801\uc6a9\ub418\ub294 \ud604\uc0c1\uc744 \ub9c9\uc544\uc900\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ud2b8\ub79c\uc7ad\uc158\uc758-\uc18d\uc131acid",children:"\ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)"}),"\n",(0,t.jsxs)(n.p,{children:["\uc6d0\uc790\uc131(Atomicity): \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \uc2e4\ud589\ub41c \uc791\uc5c5\ub4e4\uc740 \ubaa8\ub450 \uc131\uacf5\ud558\uac70\ub098, \uc2e4\ud328\ud574\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc77c\uad00\uc131(Consistency): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc218\ud589\ub418\uae30 \uc804\uacfc \ud6c4\uc5d0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc77c\uad00\ub41c \uc0c1\ud0dc\ub97c \uc720\uc9c0\ud574\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uaca9\ub9ac\uc131(Isolation): \uac01\uac01\uc758 \ud2b8\ub79c\uc7ad\uc158\uc740 \ub3c5\ub9bd\uc801\uc774\ub77c \uc11c\ub85c\uc5d0\uac8c \uc601\ud5a5\uc744 \uc8fc\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc9c0\uc18d\uc131(Durability): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc131\uacf5\uc801\uc73c\ub85c \uc644\ub8cc\ub41c\ub2e4\uba74 \uc601\uad6c\uc801\uc73c\ub85c \uacb0\uacfc\uc5d0 \ubc18\uc601\ub418\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ud2b8\ub79c\uc7ad\uc158-\uc8fc\uc758\uc0ac\ud56d",children:"\ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d"}),"\n",(0,t.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc740 \uaf2d \ud544\uc694\ud55c \ucd5c\uc18c\uc758 \ucf54\ub4dc\uc5d0\ub9cc \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.(\ud2b8\ub79c\uc7ad\uc158\uc758 \ubc94\uc704\ub97c \ucd5c\uc18c\ud654\ud558\ub77c)",(0,t.jsx)(n.br,{}),"\n","\uad6c\ud604\ud574\uc57c \ud558\ub294 \uc5c5\ubb34\uc5d0 \ub530\ub77c \ud2b8\ub79c\uc7ad\uc158\uc744 \ubb36\uac70\ub098 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uace0, \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\ub294 \uacbd\uc6b0 \ubc18\ub4dc\uc2dc \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4."]}),"\n",(0,t.jsxs)(n.admonition,{title:"\uc65c \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\uc744 \ub54c \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud560\uae4c? \ud83e\udd14",type:"info",children:[(0,t.jsxs)(n.p,{children:["\ub370\uc774\ud130\uc758 \uc77c\uad00\uc131\uacfc \uc548\uc804\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc744 \ud2b8\ub79c\uc7ad\uc158 \ub0b4\ubd80\uc5d0 \ud3ec\ud568\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4."]}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc911\uac04\uc5d0 \uc2e4\ud328\ud560 \uac00\ub2a5\uc131(\uc548\uc804\uc131 X)"}),"\n",(0,t.jsx)(n.li,{children:"\ud1b5\uc2e0\uc73c\ub85c \uc778\ud574 \ub370\uc774\ud130\uac00 \ubcc0\uacbd\ub420 \uc218 \uc788\ub294 \ubd80\ubd84(\uc77c\uad00\uc131 X)"}),"\n"]})]}),"\n",(0,t.jsx)(n.h2,{id:"\uaca9\ub9ac-\uc218\uc900isolation-level",children:"\uaca9\ub9ac \uc218\uc900(Isolation level)"}),"\n",(0,t.jsxs)(n.p,{children:["\uc5ec\ub7ec \ud2b8\ub79c\uc7ad\uc158\uc774 \ub3d9\uc2dc\uc5d0 \ucc98\ub9ac\ub420 \ub54c \ud2b9\uc815 \ud2b8\ub79c\uc7ad\uc158\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\uc758 \uc870\ud68c \ubc0f \ubcc0\uacbd\uc744 \ud5c8\uc6a9\ud560\uc9c0 \uacb0\uc815\ud558\ub294 \uac83\uc744 \ub9d0\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uaca9\ub9ac \uc218\uc900\uc774 \ub192\uc544\uc9c8 \uc218\ub85d \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\uc774 \ub5a8\uc5b4\uc9c0\ub294 \uac83\uc774 \uc77c\ubc18\uc801\uc774\uc9c0\ub9cc, ",(0,t.jsx)(n.code,{children:"SERIALIZABLE"}),"\uc774 \uc544\ub2c8\ub77c\uba74 \ud06c\uac8c \uc131\ub2a5\uc758 \uc800\ud558\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"read-uncommitted",children:"READ UNCOMMITTED"}),"\n",(0,t.jsxs)(n.p,{children:["\uac01 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\uc758 \ubcc0\uacbd \ub0b4\uc6a9\uc774 ",(0,t.jsx)(n.code,{children:"COMMIT"}),"\uc774\ub098 ",(0,t.jsx)(n.code,{children:"ROLLBACK"})," \uc5ec\ubd80\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcf4\uc778\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub354\ud2f0 \ub9ac\ub4dc \ud604\uc0c1\uc774 \ubc1c\uc0dd\ud558\uae30 \ub54c\ubb38\uc5d0 \uc815\ud569\uc131\uc758 \ubb38\uc81c\uac00 \ub9ce\uc740 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MySQL \uc0ac\uc6a9\uc2dc \ucd5c\uc18c ",(0,t.jsx)(n.code,{children:"READ COMMITTED"})," \uc774\uc0c1\uc758 \uaca9\ub9ac \uc218\uc900 \uc0ac\uc6a9\uc744 \uad8c\uc7a5\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: READ UNCOMMITTED\n---\nsequenceDiagram\n Alice->>Database: BEGIN\n Alice->>Database: INSERT(Alice)\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: COMMIT(Alice)"}),"\n",(0,t.jsx)(n.h3,{id:"read-committed",children:"READ COMMITTED"}),"\n",(0,t.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 ",(0,t.jsx)(n.code,{children:"COMMIT"}),"\uc774 \uc644\ub8cc\ub41c \ub370\uc774\ud130\ub9cc \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc870\ud68c\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc624\ub77c\ud074 DBMS\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.code,{children:"REPEATABLE READ"}),"\uac00 \ubcf4\uc7a5\ub418\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 ",(0,t.jsx)(n.code,{children:"NON-REPEATABLE READ"})," \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: READ COMMITTED\n---\nsequenceDiagram\n Alice->>Database: BEGIN\n Alice->>Database: UPDATE(Alice to Bob)\n Bob->>Database: SELECT\n Database->>+Bob: Alice(Undo log)\n Alice->>Database: COMMIT"}),"\n",(0,t.jsx)(n.h3,{id:"repeatable-read",children:"REPEATABLE READ"}),"\n",(0,t.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc774 \uc2dc\uc791\ub418\uae30 \uc804\uc5d0 ",(0,t.jsx)(n.code,{children:"COMMIT"}),"\uc774 \uc644\ub8cc\ub41c \ub0b4\uc6a9\uc5d0 \ub300\ud574\uc11c\ub9cc \uc870\ud68c\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MySQL\uc758 InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MVCC\ub97c \uc774\uc6a9\ud574 \uc5b8\ub450(Undo) \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \uc774\uc804 \ub370\uc774\ud130\ub97c \uc774\uc6a9\ud574 \ub3d9\uc77c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c\ub294 \ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc5ec\uc904 \uc218 \uc788\uac8c \ubcf4\uc7a5\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc7a5\ud558\ub294 \ubc29\ubc95\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\ubaa8\ub4e0 InnoDB \ud2b8\ub79c\uc7ad\uc158\uc740 \uc21c\ucc28\uc801\uc73c\ub85c \uc99d\uac00\ud558\ub294 \uace0\uc720\ud55c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ub97c \uac00\uc9c4\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"Undo \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \ub808\ucf54\ub4dc\uc5d0\ub294 \ubcc0\uacbd\uc744 \ubc1c\uc0dd\uc2dc\ud0a8 \ud2b8\ub79c\uc7ad\uc158\uc758 \ubc88\ud638\uac00 \ud3ec\ud568\ub418\uc5b4\uc788\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"Undo \uc601\uc5ed\uc758 \ubc31\uc5c5\ub41c \ub370\uc774\ud130\ub294 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774 \ubd88\ud544\uc694\ud558\ub2e4\uace0 \ud310\ub2e8\ud558\ub294 \uacbd\uc6b0 \uc0ad\uc81c\ub41c\ub2e4."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"REPEATABLE READ"})," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c\ub294 MVCC\ub97c \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \uac00\uc7a5 \uc624\ub798\ub41c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ubcf4\ub2e4 \uc55e\uc120 Undo \uc601\uc5ed\uc758 \ub370\uc774\ud130\ub294 \uc0ad\uc81c\ud558\uc9c0 \uc54a\ub294\ub2e4."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"InnoDB\uc5d0\uc11c\ub294 \uac2d \ub77d\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc744 \uc774\uc6a9\ud558\uc5ec \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc744 \ubc29\uc9c0\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: REPEATABLE READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN(TRX-ID: 1)\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: BEGIN(TRX-ID: 2)\n Alice->>Database: UPDATE(Alice to Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT\n Database->>+Bob: Alice(Undo log)"}),"\n",(0,t.jsx)(n.admonition,{title:"\uac2d \ub78d(Gap lock)\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d(Next-key lock)",type:"note",children:(0,t.jsxs)(n.p,{children:["\uac2d \ub77d: \ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub125\uc2a4\ud2b8 \ud0a4 \ub77d: \ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4."]})}),"\n",(0,t.jsxs)(n.admonition,{title:"MVCC(Multi Version Concurrency Control)",type:"note",children:[(0,t.jsx)(n.p,{children:"\ub3d9\uc2dc\uc131\uc744 \uc81c\uc5b4\ud558\ub294 \ubc29\ubc95 \uc911 \ud558\ub098\ub85c \ud558\ub098\uc758 \ub808\ucf54\ub4dc\uc5d0 \ub300\ud574 \uc5ec\ub7ec \uac1c\uc758 \ubc84\uc804\uc774 \ub3d9\uc2dc\uc5d0 \uad00\ub9ac\ub418\ub294 \uac83\uc774\ub2e4."}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"PostgreSQL\uc740 \ub2e4\uc911 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\ub294 \uac83\uc73c\ub85c MVCC\ub97c \uad6c\ud604\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.li,{children:["Oracle, InnoDB\ub294 ",(0,t.jsx)(n.code,{children:"Undo log"}),"\ub97c \uc774\uc6a9\ud574 \uc774 \uae30\ub2a5\uc744 \uad6c\ud604\ud55c\ub2e4.(\ucd5c\uc2e0 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub9cc DB\uc5d0 \uc800\uc7a5)"]}),"\n"]}),(0,t.jsx)(n.p,{children:"\uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uc77d\uad00\ub41c \uc77d\uae30\ub97c \uc81c\uacf5\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4."})]}),"\n",(0,t.jsx)(n.h3,{id:"serializable",children:"SERIALIZABLE"}),"\n",(0,t.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc744 \uc21c\ucc28\uc801\uc73c\ub85c \uc9c4\ud589\uc2dc\ud0a4\ub294 \uaca9\ub9ac \uc218\uc900\uc774\uace0 \ub530\ub77c\uc11c \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\ub3c4 \ub2e4\ub978 \uaca9\ub9ac \uc218\uc900\ubcf4\ub2e4 \ub5a8\uc5b4\uc9c4\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uace0 \uc4f0\ub294 \ub808\ucf54\ub4dc\ub97c \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\ub294 \uc811\uadfc\ud560 \uc218 \uc5c6\uace0 \ub2e8\uc21c\ud55c \uc77d\uae30 \uc791\uc5c5\ub3c4 \uacf5\uc720 \uc7a0\uae08(\uc77d\uae30 \uc7a0\uae08)\uc744 \ud68d\ub4dd\ud574\uc57c\ub9cc \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","InnoDB\uc5d0\uc11c\ub294 \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc774 ",(0,t.jsx)(n.code,{children:"REPEATABLE READ"})," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ubc1c\uc0dd\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uad73\uc774 \uc0ac\uc6a9\ud560 \ud544\uc694\ub294 \uc5c6\ub2e4."]}),"\n",(0,t.jsx)(n.h2,{id:"\uaca9\ub9ac-\uc218\uc900\uc5d0-\ub530\ub978-\ubd80\uc815\ud569-\ubb38\uc81c",children:"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c"}),"\n",(0,t.jsx)(n.p,{children:"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ub354\ud2f0 \ub9ac\ub4dc, \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c, \ud32c\ud140 \ub9ac\ub4dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"\uaca9\ub9ac \uc218\uc900 / \ubd80\uc815\ud569 \ubb38\uc81c"}),(0,t.jsx)(n.th,{children:"\ub354\ud2f0 \ub9ac\ub4dc"}),(0,t.jsx)(n.th,{children:"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c"}),(0,t.jsx)(n.th,{children:"\ud32c\ud140 \ub9ac\ub4dc"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"READ UNCOMMITTED"}),(0,t.jsx)(n.td,{children:"O"}),(0,t.jsx)(n.td,{children:"O"}),(0,t.jsx)(n.td,{children:"O"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"READ COMMITTED"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"O"}),(0,t.jsx)(n.td,{children:"O"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"REPEATABLE READ"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"O(InnoDB\ub294 X)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SERIALIZABLE"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"X"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"\ub354\ud2f0-\ub9ac\ub4dcdirty-read",children:"\ub354\ud2f0 \ub9ac\ub4dc(Dirty read)"}),"\n",(0,t.jsxs)(n.p,{children:["\uc5b4\ub5a4 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ucc98\ub9ac\ud55c \uc791\uc5c5\uc774 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc558\uc5b4\ub3c4 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcfc \uc218 \uc788\ub294 \ud604\uc0c1",(0,t.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158 \uaca9\ub9ac \uc218\uc900\uc774 READ UNCOMMITTED\uc77c \ub54c \ubc1c\uc0dd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc608) B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uace0 \ucee4\ubc0b\uc744 \ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, A\uac00 \ud574\ub2f9 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud560 \uc218 \uc788\ub294 \uacbd\uc6b0"]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc18\ubcf5-\uac00\ub2a5\ud558\uc9c0-\uc54a\uc740-\uc870\ud68cnon-repeatable-read",children:"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)"}),"\n",(0,t.jsxs)(n.p,{children:["\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc758 \uac19\uc740 \ud589\uc5d0 \ub450 \ubc88 \uc774\uc0c1 \uc870\ud68c\uac00 \ubc1c\uc0dd\ud588\ub294\ub370, \uadf8 \uac12\uc774 \ub2e4\ub978 \ud604\uc0c1",(0,t.jsx)(n.br,{}),"\n","\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc5ec\ub7ec \ubc88 \uc870\ud68c\ud558\ub358 \uc911 B\uac00 \ub808\ucf54\ub4dc\ub97c \ubcc0\uacbd\ud558\uc5ec A\uac00 \uc870\ud68c\ud55c \uac12\uc774 \ub2ec\ub77c\uc9c0\ub294 \uacbd\uc6b0"]}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: NON REPEATABLE READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: BEGIN\n Alice->>Database: UPDATE(Alice to Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT\n Database->>+Bob: Bob"}),"\n",(0,t.jsx)(n.h3,{id:"\ud32c\ud140-\ub9ac\ub4dcphantom-read-phantom-row",children:"\ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)"}),"\n",(0,t.jsxs)(n.p,{children:["\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ucffc\ub9ac \uc218\ud589\uc2dc, \uc218\ud589 \uacb0\uacfc\uac00 \ub2e4\ub978 \ud604\uc0c1",(0,t.jsx)(n.br,{}),"\n","\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud558\uace0 B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uc5ec A\uac00 \ub2e4\uc2dc \uc870\ud68c\ud560 \ub54c \uc874\uc7ac\ud558\uc9c0 \uc54a\uc740 \ub808\ucf54\ub4dc\uac00 \uc870\ud68c\ub418\ub294 \uacbd\uc6b0"]}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: PHANTOM READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN(TRX-ID: 1)\n Bob->>Database: SELECT COUNT\n Database->>+Bob: 1\n Alice->>Database: BEGIN(TRX-ID: 2)\n Alice->>Database: INSERT(Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT COUNT\n Database->>+Bob: 2"}),"\n",(0,t.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:["Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html",children:"Isolation Level, MySQL"})]})]})}function b(e={}){const{wrapper:n}={...(0,r.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,a)=>{a.d(n,{ah:()=>o});var t=a(67294);function r(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function i(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function l(e){for(var n=1;n<arguments.length;n++){var a=null!=arguments[n]?arguments[n]:{};n%2?i(Object(a),!0).forEach((function(n){r(e,n,a[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(a,n))}))}return e}function s(e,n){if(null==e)return{};var a,t,r=function(e,n){if(null==e)return{};var a,t,r={},i=Object.keys(e);for(t=0;t<i.length;t++)a=i[t],n.indexOf(a)>=0||(r[a]=e[a]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)a=i[t],n.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=t.createContext({}),o=function(e){var n=t.useContext(c),a=n;return e&&(a="function"==typeof e?e(n):l(l({},n),e)),a},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},b=t.forwardRef((function(e,n){var a=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,b=s(e,["components","mdxType","originalType","parentName"]),h=o(a),j=r,x=h["".concat(c,".").concat(j)]||h[j]||d[j]||i;return a?t.createElement(x,l(l({ref:n},b),{},{components:a})):t.createElement(x,l({ref:n},b))}));b.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/73688d5c.e6c6d26a.js b/assets/js/73688d5c.e6c6d26a.js deleted file mode 100644 index cb6bab134..000000000 --- a/assets/js/73688d5c.e6c6d26a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6908],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>s});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?l(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function o(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},l=Object.keys(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),m=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},d=function(e){var t=m(e.components);return n.createElement(p.Provider,{value:t},e.children)},b={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),c=m(a),s=r,u=c["".concat(p,".").concat(s)]||c[s]||b[s]||l;return a?n.createElement(u,i(i({ref:t},d),{},{components:a})):n.createElement(u,i({ref:t},d))}));function s(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,i=new Array(l);i[0]=c;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var m=2;m<l;m++)i[m]=a[m];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}c.displayName="MDXCreateElement"},60641:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>b,frontMatter:()=>l,metadata:()=>o,toc:()=>m});var n=a(87462),r=(a(67294),a(3905));const l={title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",slug:"transaction-and-isolation",tags:["DataBase","Transaction","Isolation"]},i=void 0,o={permalink:"/transaction-and-isolation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",source:"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",description:"\ud2b8\ub79c\uc7ad\uc158(Transaction)",date:"2023-04-05T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 5\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Transaction",permalink:"/tags/transaction"},{label:"Isolation",permalink:"/tags/isolation"}],readingTime:9.57,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",slug:"transaction-and-isolation",tags:["DataBase","Transaction","Isolation"]},prevItem:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/mysql-lock"},nextItem:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",permalink:"/test-double"}},p={authorsImageUrls:[]},m=[{value:"\ud2b8\ub79c\uc7ad\uc158(Transaction)",id:"\ud2b8\ub79c\uc7ad\uc158transaction",level:2},{value:"\ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)",id:"\ud2b8\ub79c\uc7ad\uc158\uc758-\uc18d\uc131acid",level:3},{value:"\ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d",id:"\ud2b8\ub79c\uc7ad\uc158-\uc8fc\uc758\uc0ac\ud56d",level:3},{value:"\uaca9\ub9ac \uc218\uc900(Isolation level)",id:"\uaca9\ub9ac-\uc218\uc900isolation-level",level:2},{value:"READ UNCOMMITTED",id:"read-uncommitted",level:3},{value:"READ COMMITTED",id:"read-committed",level:3},{value:"REPEATABLE READ",id:"repeatable-read",level:3},{value:"SERIALIZABLE",id:"serializable",level:3},{value:"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c",id:"\uaca9\ub9ac-\uc218\uc900\uc5d0-\ub530\ub978-\ubd80\uc815\ud569-\ubb38\uc81c",level:2},{value:"\ub354\ud2f0 \ub9ac\ub4dc(Dirty read)",id:"\ub354\ud2f0-\ub9ac\ub4dcdirty-read",level:3},{value:"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)",id:"\ubc18\ubcf5-\uac00\ub2a5\ud558\uc9c0-\uc54a\uc740-\uc870\ud68cnon-repeatable-read",level:3},{value:"\ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)",id:"\ud32c\ud140-\ub9ac\ub4dcphantom-read-phantom-row",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],d={toc:m};function b(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"\ud2b8\ub79c\uc7ad\uc158transaction"},"\ud2b8\ub79c\uc7ad\uc158(Transaction)"),(0,r.kt)("p",null,"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \ub17c\ub9ac\uc801 \uae30\ub2a5\uc744 \uc218\ud589\ud558\uae30 \uc704\ud55c \uc791\uc5c5\uc758 \ub2e8\uc704\ub97c \ub9d0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc740 \uc791\uc5c5\uc758 \uc644\uc804\uc131\uacfc \ub370\uc774\ud130\uc758 \uc815\ud569\uc131\uc744 \ubcf4\uc7a5\ud574 \uc900\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub17c\ub9ac\uc801\uc778 \uc791\uc5c5 \uc14b\uc744 \uc644\ubcbd\ud558\uac8c \ucc98\ub9ac\ud558\uac70\ub098, \uc624\ub958 \uc2dc \uc791\uc5c5\uc758 \uc77c\ubd80\ub9cc \uc801\uc6a9\ub418\ub294 \ud604\uc0c1\uc744 \ub9c9\uc544\uc900\ub2e4. "),(0,r.kt)("h3",{id:"\ud2b8\ub79c\uc7ad\uc158\uc758-\uc18d\uc131acid"},"\ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)"),(0,r.kt)("p",null,"\uc6d0\uc790\uc131(Atomicity): \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \uc2e4\ud589\ub41c \uc791\uc5c5\ub4e4\uc740 \ubaa8\ub450 \uc131\uacf5\ud558\uac70\ub098, \uc2e4\ud328\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc77c\uad00\uc131(Consistency): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc218\ud589\ub418\uae30 \uc804\uacfc \ud6c4\uc5d0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc77c\uad00\ub41c \uc0c1\ud0dc\ub97c \uc720\uc9c0\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uaca9\ub9ac\uc131(Isolation): \uac01\uac01\uc758 \ud2b8\ub79c\uc7ad\uc158\uc740 \ub3c5\ub9bd\uc801\uc774\ub77c \uc11c\ub85c\uc5d0\uac8c \uc601\ud5a5\uc744 \uc8fc\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc9c0\uc18d\uc131(Durability): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc131\uacf5\uc801\uc73c\ub85c \uc644\ub8cc\ub41c\ub2e4\uba74 \uc601\uad6c\uc801\uc73c\ub85c \uacb0\uacfc\uc5d0 \ubc18\uc601\ub418\uc5b4\uc57c \ud55c\ub2e4. "),(0,r.kt)("h3",{id:"\ud2b8\ub79c\uc7ad\uc158-\uc8fc\uc758\uc0ac\ud56d"},"\ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d"),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc740 \uaf2d \ud544\uc694\ud55c \ucd5c\uc18c\uc758 \ucf54\ub4dc\uc5d0\ub9cc \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.(\ud2b8\ub79c\uc7ad\uc158\uc758 \ubc94\uc704\ub97c \ucd5c\uc18c\ud654\ud558\ub77c)",(0,r.kt)("br",{parentName:"p"}),"\n","\uad6c\ud604\ud574\uc57c \ud558\ub294 \uc5c5\ubb34\uc5d0 \ub530\ub77c \ud2b8\ub79c\uc7ad\uc158\uc744 \ubb36\uac70\ub098 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uace0, \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\ub294 \uacbd\uc6b0 \ubc18\ub4dc\uc2dc \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4. "),(0,r.kt)("admonition",{title:"\uc65c \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\uc744 \ub54c \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud560\uae4c? \ud83e\udd14",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"\ub370\uc774\ud130\uc758 \uc77c\uad00\uc131\uacfc \uc548\uc804\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc744 \ud2b8\ub79c\uc7ad\uc158 \ub0b4\ubd80\uc5d0 \ud3ec\ud568\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc911\uac04\uc5d0 \uc2e4\ud328\ud560 \uac00\ub2a5\uc131(\uc548\uc804\uc131 X)"),(0,r.kt)("li",{parentName:"ul"},"\ud1b5\uc2e0\uc73c\ub85c \uc778\ud574 \ub370\uc774\ud130\uac00 \ubcc0\uacbd\ub420 \uc218 \uc788\ub294 \ubd80\ubd84(\uc77c\uad00\uc131 X)"))),(0,r.kt)("h2",{id:"\uaca9\ub9ac-\uc218\uc900isolation-level"},"\uaca9\ub9ac \uc218\uc900(Isolation level)"),(0,r.kt)("p",null,"\uc5ec\ub7ec \ud2b8\ub79c\uc7ad\uc158\uc774 \ub3d9\uc2dc\uc5d0 \ucc98\ub9ac\ub420 \ub54c \ud2b9\uc815 \ud2b8\ub79c\uc7ad\uc158\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\uc758 \uc870\ud68c \ubc0f \ubcc0\uacbd\uc744 \ud5c8\uc6a9\ud560\uc9c0 \uacb0\uc815\ud558\ub294 \uac83\uc744 \ub9d0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uaca9\ub9ac \uc218\uc900\uc774 \ub192\uc544\uc9c8 \uc218\ub85d \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\uc774 \ub5a8\uc5b4\uc9c0\ub294 \uac83\uc774 \uc77c\ubc18\uc801\uc774\uc9c0\ub9cc, ",(0,r.kt)("inlineCode",{parentName:"p"},"SERIALIZABLE"),"\uc774 \uc544\ub2c8\ub77c\uba74 \ud06c\uac8c \uc131\ub2a5\uc758 \uc800\ud558\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4. "),(0,r.kt)("h3",{id:"read-uncommitted"},"READ UNCOMMITTED"),(0,r.kt)("p",null,"\uac01 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\uc758 \ubcc0\uacbd \ub0b4\uc6a9\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"COMMIT"),"\uc774\ub098 ",(0,r.kt)("inlineCode",{parentName:"p"},"ROLLBACK")," \uc5ec\ubd80\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcf4\uc778\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub354\ud2f0 \ub9ac\ub4dc \ud604\uc0c1\uc774 \ubc1c\uc0dd\ud558\uae30 \ub54c\ubb38\uc5d0 \uc815\ud569\uc131\uc758 \ubb38\uc81c\uac00 \ub9ce\uc740 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MySQL \uc0ac\uc6a9\uc2dc \ucd5c\uc18c ",(0,r.kt)("inlineCode",{parentName:"p"},"READ COMMITTED")," \uc774\uc0c1\uc758 \uaca9\ub9ac \uc218\uc900 \uc0ac\uc6a9\uc744 \uad8c\uc7a5\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"---\ntitle: READ UNCOMMITTED\n---\nsequenceDiagram\n Alice->>Database: BEGIN\n Alice->>Database: INSERT(Alice)\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: COMMIT(Alice)"}),(0,r.kt)("h3",{id:"read-committed"},"READ COMMITTED"),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 ",(0,r.kt)("inlineCode",{parentName:"p"},"COMMIT"),"\uc774 \uc644\ub8cc\ub41c \ub370\uc774\ud130\ub9cc \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc870\ud68c\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc624\ub77c\ud074 DBMS\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"REPEATABLE READ"),"\uac00 \ubcf4\uc7a5\ub418\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 ",(0,r.kt)("inlineCode",{parentName:"p"},"NON-REPEATABLE READ")," \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"---\ntitle: READ COMMITTED\n---\nsequenceDiagram\n Alice->>Database: BEGIN\n Alice->>Database: UPDATE(Alice to Bob)\n Bob->>Database: SELECT\n Database->>+Bob: Alice(Undo log)\n Alice->>Database: COMMIT"}),(0,r.kt)("h3",{id:"repeatable-read"},"REPEATABLE READ"),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc2dc\uc791\ub418\uae30 \uc804\uc5d0 ",(0,r.kt)("inlineCode",{parentName:"p"},"COMMIT"),"\uc774 \uc644\ub8cc\ub41c \ub0b4\uc6a9\uc5d0 \ub300\ud574\uc11c\ub9cc \uc870\ud68c\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MySQL\uc758 InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MVCC\ub97c \uc774\uc6a9\ud574 \uc5b8\ub450(Undo) \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \uc774\uc804 \ub370\uc774\ud130\ub97c \uc774\uc6a9\ud574 \ub3d9\uc77c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c\ub294 \ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc5ec\uc904 \uc218 \uc788\uac8c \ubcf4\uc7a5\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc7a5\ud558\ub294 \ubc29\ubc95\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ubaa8\ub4e0 InnoDB \ud2b8\ub79c\uc7ad\uc158\uc740 \uc21c\ucc28\uc801\uc73c\ub85c \uc99d\uac00\ud558\ub294 \uace0\uc720\ud55c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ub97c \uac00\uc9c4\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"Undo \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \ub808\ucf54\ub4dc\uc5d0\ub294 \ubcc0\uacbd\uc744 \ubc1c\uc0dd\uc2dc\ud0a8 \ud2b8\ub79c\uc7ad\uc158\uc758 \ubc88\ud638\uac00 \ud3ec\ud568\ub418\uc5b4\uc788\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"Undo \uc601\uc5ed\uc758 \ubc31\uc5c5\ub41c \ub370\uc774\ud130\ub294 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774 \ubd88\ud544\uc694\ud558\ub2e4\uace0 \ud310\ub2e8\ud558\ub294 \uacbd\uc6b0 \uc0ad\uc81c\ub41c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"REPEATABLE READ")," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c\ub294 MVCC\ub97c \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \uac00\uc7a5 \uc624\ub798\ub41c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ubcf4\ub2e4 \uc55e\uc120 Undo \uc601\uc5ed\uc758 \ub370\uc774\ud130\ub294 \uc0ad\uc81c\ud558\uc9c0 \uc54a\ub294\ub2e4. ")),(0,r.kt)("p",null,"InnoDB\uc5d0\uc11c\ub294 \uac2d \ub77d\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc744 \uc774\uc6a9\ud558\uc5ec \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc744 \ubc29\uc9c0\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"---\ntitle: REPEATABLE READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN(TRX-ID: 1)\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: BEGIN(TRX-ID: 2)\n Alice->>Database: UPDATE(Alice to Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT\n Database->>+Bob: Alice(Undo log)"}),(0,r.kt)("admonition",{title:"\uac2d \ub78d(Gap lock)\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d(Next-key lock)",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\uac2d \ub77d: \ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub125\uc2a4\ud2b8 \ud0a4 \ub77d: \ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4.")),(0,r.kt)("admonition",{title:"MVCC(Multi Version Concurrency Control)",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\ub3d9\uc2dc\uc131\uc744 \uc81c\uc5b4\ud558\ub294 \ubc29\ubc95 \uc911 \ud558\ub098\ub85c \ud558\ub098\uc758 \ub808\ucf54\ub4dc\uc5d0 \ub300\ud574 \uc5ec\ub7ec \uac1c\uc758 \ubc84\uc804\uc774 \ub3d9\uc2dc\uc5d0 \uad00\ub9ac\ub418\ub294 \uac83\uc774\ub2e4."),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"PostgreSQL\uc740 \ub2e4\uc911 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\ub294 \uac83\uc73c\ub85c MVCC\ub97c \uad6c\ud604\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"Oracle, InnoDB\ub294 ",(0,r.kt)("inlineCode",{parentName:"li"},"Undo log"),"\ub97c \uc774\uc6a9\ud574 \uc774 \uae30\ub2a5\uc744 \uad6c\ud604\ud55c\ub2e4.(\ucd5c\uc2e0 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub9cc DB\uc5d0 \uc800\uc7a5)")),(0,r.kt)("p",{parentName:"admonition"},"\uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uc77d\uad00\ub41c \uc77d\uae30\ub97c \uc81c\uacf5\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4.")),(0,r.kt)("h3",{id:"serializable"},"SERIALIZABLE"),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc744 \uc21c\ucc28\uc801\uc73c\ub85c \uc9c4\ud589\uc2dc\ud0a4\ub294 \uaca9\ub9ac \uc218\uc900\uc774\uace0 \ub530\ub77c\uc11c \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\ub3c4 \ub2e4\ub978 \uaca9\ub9ac \uc218\uc900\ubcf4\ub2e4 \ub5a8\uc5b4\uc9c4\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uace0 \uc4f0\ub294 \ub808\ucf54\ub4dc\ub97c \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\ub294 \uc811\uadfc\ud560 \uc218 \uc5c6\uace0 \ub2e8\uc21c\ud55c \uc77d\uae30 \uc791\uc5c5\ub3c4 \uacf5\uc720 \uc7a0\uae08(\uc77d\uae30 \uc7a0\uae08)\uc744 \ud68d\ub4dd\ud574\uc57c\ub9cc \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB\uc5d0\uc11c\ub294 \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"REPEATABLE READ")," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ubc1c\uc0dd\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uad73\uc774 \uc0ac\uc6a9\ud560 \ud544\uc694\ub294 \uc5c6\ub2e4. "),(0,r.kt)("h2",{id:"\uaca9\ub9ac-\uc218\uc900\uc5d0-\ub530\ub978-\ubd80\uc815\ud569-\ubb38\uc81c"},"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c"),(0,r.kt)("p",null,"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ub354\ud2f0 \ub9ac\ub4dc, \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c, \ud32c\ud140 \ub9ac\ub4dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\uaca9\ub9ac \uc218\uc900 / \ubd80\uc815\ud569 \ubb38\uc81c"),(0,r.kt)("th",{parentName:"tr",align:null},"\ub354\ud2f0 \ub9ac\ub4dc"),(0,r.kt)("th",{parentName:"tr",align:null},"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c"),(0,r.kt)("th",{parentName:"tr",align:null},"\ud32c\ud140 \ub9ac\ub4dc"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"READ UNCOMMITTED"),(0,r.kt)("td",{parentName:"tr",align:null},"O"),(0,r.kt)("td",{parentName:"tr",align:null},"O"),(0,r.kt)("td",{parentName:"tr",align:null},"O")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"READ COMMITTED"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"O"),(0,r.kt)("td",{parentName:"tr",align:null},"O")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"REPEATABLE READ"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"O(InnoDB\ub294 X)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"SERIALIZABLE"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"X")))),(0,r.kt)("h3",{id:"\ub354\ud2f0-\ub9ac\ub4dcdirty-read"},"\ub354\ud2f0 \ub9ac\ub4dc(Dirty read)"),(0,r.kt)("p",null,"\uc5b4\ub5a4 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ucc98\ub9ac\ud55c \uc791\uc5c5\uc774 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc558\uc5b4\ub3c4 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcfc \uc218 \uc788\ub294 \ud604\uc0c1",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158 \uaca9\ub9ac \uc218\uc900\uc774 READ UNCOMMITTED\uc77c \ub54c \ubc1c\uc0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uace0 \ucee4\ubc0b\uc744 \ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, A\uac00 \ud574\ub2f9 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud560 \uc218 \uc788\ub294 \uacbd\uc6b0"),(0,r.kt)("h3",{id:"\ubc18\ubcf5-\uac00\ub2a5\ud558\uc9c0-\uc54a\uc740-\uc870\ud68cnon-repeatable-read"},"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)"),(0,r.kt)("p",null,"\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc758 \uac19\uc740 \ud589\uc5d0 \ub450 \ubc88 \uc774\uc0c1 \uc870\ud68c\uac00 \ubc1c\uc0dd\ud588\ub294\ub370, \uadf8 \uac12\uc774 \ub2e4\ub978 \ud604\uc0c1",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc5ec\ub7ec \ubc88 \uc870\ud68c\ud558\ub358 \uc911 B\uac00 \ub808\ucf54\ub4dc\ub97c \ubcc0\uacbd\ud558\uc5ec A\uac00 \uc870\ud68c\ud55c \uac12\uc774 \ub2ec\ub77c\uc9c0\ub294 \uacbd\uc6b0 "),(0,r.kt)("mermaid",{value:"---\ntitle: NON REPEATABLE READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: BEGIN\n Alice->>Database: UPDATE(Alice to Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT\n Database->>+Bob: Bob"}),(0,r.kt)("h3",{id:"\ud32c\ud140-\ub9ac\ub4dcphantom-read-phantom-row"},"\ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)"),(0,r.kt)("p",null,"\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ucffc\ub9ac \uc218\ud589\uc2dc, \uc218\ud589 \uacb0\uacfc\uac00 \ub2e4\ub978 \ud604\uc0c1",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud558\uace0 B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uc5ec A\uac00 \ub2e4\uc2dc \uc870\ud68c\ud560 \ub54c \uc874\uc7ac\ud558\uc9c0 \uc54a\uc740 \ub808\ucf54\ub4dc\uac00 \uc870\ud68c\ub418\ub294 \uacbd\uc6b0 "),(0,r.kt)("mermaid",{value:"---\ntitle: PHANTOM READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN(TRX-ID: 1)\n Bob->>Database: SELECT COUNT\n Database->>+Bob: 1\n Alice->>Database: BEGIN(TRX-ID: 2)\n Alice->>Database: INSERT(Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT COUNT\n Database->>+Bob: 2"}),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html"},"Isolation Level, MySQL")))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/740.96c76535.js b/assets/js/740.96c76535.js new file mode 100644 index 000000000..fee774121 --- /dev/null +++ b/assets/js/740.96c76535.js @@ -0,0 +1,23653 @@ +exports.id = 740; +exports.ids = [740]; +exports.modules = { + +/***/ 17295: +/***/ ((module) => { + +(function(f){if(true){module.exports=f()}else { var g; }})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=undefined;if(!f&&c)return require(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=undefined,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); + +var _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/******************************************************************************* + * Copyright (c) 2017 Kiel University and others. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +var ELK = function () { + function ELK() { + var _this = this; + + var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, + _ref$defaultLayoutOpt = _ref.defaultLayoutOptions, + defaultLayoutOptions = _ref$defaultLayoutOpt === undefined ? {} : _ref$defaultLayoutOpt, + _ref$algorithms = _ref.algorithms, + algorithms = _ref$algorithms === undefined ? ['layered', 'stress', 'mrtree', 'radial', 'force', 'disco', 'sporeOverlap', 'sporeCompaction', 'rectpacking'] : _ref$algorithms, + workerFactory = _ref.workerFactory, + workerUrl = _ref.workerUrl; + + _classCallCheck(this, ELK); + + this.defaultLayoutOptions = defaultLayoutOptions; + this.initialized = false; + + // check valid worker construction possible + if (typeof workerUrl === 'undefined' && typeof workerFactory === 'undefined') { + throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'."); + } + var factory = workerFactory; + if (typeof workerUrl !== 'undefined' && typeof workerFactory === 'undefined') { + // use default Web Worker + factory = function factory(url) { + return new Worker(url); + }; + } + + // create the worker + var worker = factory(workerUrl); + if (typeof worker.postMessage !== 'function') { + throw new TypeError("Created worker does not provide" + " the required 'postMessage' function."); + } + + // wrap the worker to return promises + this.worker = new PromisedWorker(worker); + + // initially register algorithms + this.worker.postMessage({ + cmd: 'register', + algorithms: algorithms + }).then(function (r) { + return _this.initialized = true; + }).catch(console.err); + } + + _createClass(ELK, [{ + key: 'layout', + value: function layout(graph) { + var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref2$layoutOptions = _ref2.layoutOptions, + layoutOptions = _ref2$layoutOptions === undefined ? this.defaultLayoutOptions : _ref2$layoutOptions, + _ref2$logging = _ref2.logging, + logging = _ref2$logging === undefined ? false : _ref2$logging, + _ref2$measureExecutio = _ref2.measureExecutionTime, + measureExecutionTime = _ref2$measureExecutio === undefined ? false : _ref2$measureExecutio; + + if (!graph) { + return Promise.reject(new Error("Missing mandatory parameter 'graph'.")); + } + return this.worker.postMessage({ + cmd: 'layout', + graph: graph, + layoutOptions: layoutOptions, + options: { + logging: logging, + measureExecutionTime: measureExecutionTime + } + }); + } + }, { + key: 'knownLayoutAlgorithms', + value: function knownLayoutAlgorithms() { + return this.worker.postMessage({ cmd: 'algorithms' }); + } + }, { + key: 'knownLayoutOptions', + value: function knownLayoutOptions() { + return this.worker.postMessage({ cmd: 'options' }); + } + }, { + key: 'knownLayoutCategories', + value: function knownLayoutCategories() { + return this.worker.postMessage({ cmd: 'categories' }); + } + }, { + key: 'terminateWorker', + value: function terminateWorker() { + this.worker.terminate(); + } + }]); + + return ELK; +}(); + +exports.default = ELK; + +var PromisedWorker = function () { + function PromisedWorker(worker) { + var _this2 = this; + + _classCallCheck(this, PromisedWorker); + + if (worker === undefined) { + throw new Error("Missing mandatory parameter 'worker'."); + } + this.resolvers = {}; + this.worker = worker; + this.worker.onmessage = function (answer) { + // why is this necessary? + setTimeout(function () { + _this2.receive(_this2, answer); + }, 0); + }; + } + + _createClass(PromisedWorker, [{ + key: 'postMessage', + value: function postMessage(msg) { + var id = this.id || 0; + this.id = id + 1; + msg.id = id; + var self = this; + return new Promise(function (resolve, reject) { + // prepare the resolver + self.resolvers[id] = function (err, res) { + if (err) { + self.convertGwtStyleError(err); + reject(err); + } else { + resolve(res); + } + }; + // post the message + self.worker.postMessage(msg); + }); + } + }, { + key: 'receive', + value: function receive(self, answer) { + var json = answer.data; + var resolver = self.resolvers[json.id]; + if (resolver) { + delete self.resolvers[json.id]; + if (json.error) { + resolver(json.error); + } else { + resolver(null, json.data); + } + } + } + }, { + key: 'terminate', + value: function terminate() { + if (this.worker.terminate) { + this.worker.terminate(); + } + } + }, { + key: 'convertGwtStyleError', + value: function convertGwtStyleError(err) { + if (!err) { + return; + } + // Somewhat flatten the way GWT stores nested exception(s) + var javaException = err['__java$exception']; + if (javaException) { + // Note that the property name of the nested exception is different + // in the non-minified ('cause') and the minified (not deterministic) version. + // Hence, the version below only works for the non-minified version. + // However, as the minified stack trace is not of much use anyway, one + // should switch the used version for debugging in such a case. + if (javaException.cause && javaException.cause.backingJsObject) { + err.cause = javaException.cause.backingJsObject; + this.convertGwtStyleError(err.cause); + } + delete err['__java$exception']; + } + } + }]); + + return PromisedWorker; +}(); +},{}],2:[function(require,module,exports){ +(function (global){(function (){ +'use strict'; + +// -------------- FAKE ELEMENTS GWT ASSUMES EXIST -------------- +var $wnd; +if (typeof window !== 'undefined') + $wnd = window +else if (typeof global !== 'undefined') + $wnd = global // nodejs +else if (typeof self !== 'undefined') + $wnd = self // web worker + +var $moduleName, + $moduleBase; + +// -------------- WORKAROUND STRICT MODE, SEE #127 -------------- +var g, i, o; + +// -------------- GENERATED CODE -------------- +function nb(){} +function xb(){} +function Fd(){} +function $g(){} +function _p(){} +function yq(){} +function Sq(){} +function Es(){} +function Jw(){} +function Vw(){} +function VA(){} +function dA(){} +function MA(){} +function PA(){} +function PB(){} +function bx(){} +function cx(){} +function vy(){} +function Nz(){} +function Yz(){} +function Ylb(){} +function Ymb(){} +function xmb(){} +function Fmb(){} +function Qmb(){} +function gcb(){} +function ccb(){} +function jcb(){} +function jtb(){} +function otb(){} +function qtb(){} +function _fb(){} +function bpb(){} +function kpb(){} +function ppb(){} +function Gpb(){} +function drb(){} +function dzb(){} +function fzb(){} +function fxb(){} +function Vxb(){} +function Ovb(){} +function byb(){} +function zyb(){} +function Zyb(){} +function _yb(){} +function hzb(){} +function jzb(){} +function lzb(){} +function nzb(){} +function rzb(){} +function zzb(){} +function Czb(){} +function Ezb(){} +function Gzb(){} +function Izb(){} +function Mzb(){} +function bBb(){} +function NBb(){} +function PBb(){} +function RBb(){} +function iCb(){} +function OCb(){} +function SCb(){} +function GDb(){} +function JDb(){} +function fEb(){} +function xEb(){} +function CEb(){} +function GEb(){} +function yFb(){} +function KGb(){} +function tIb(){} +function vIb(){} +function xIb(){} +function zIb(){} +function OIb(){} +function SIb(){} +function TJb(){} +function VJb(){} +function XJb(){} +function XKb(){} +function fKb(){} +function VKb(){} +function VLb(){} +function jLb(){} +function nLb(){} +function GLb(){} +function KLb(){} +function MLb(){} +function OLb(){} +function RLb(){} +function YLb(){} +function bMb(){} +function gMb(){} +function lMb(){} +function pMb(){} +function wMb(){} +function zMb(){} +function CMb(){} +function FMb(){} +function LMb(){} +function zNb(){} +function PNb(){} +function kOb(){} +function pOb(){} +function tOb(){} +function yOb(){} +function FOb(){} +function GPb(){} +function aQb(){} +function cQb(){} +function eQb(){} +function gQb(){} +function iQb(){} +function CQb(){} +function MQb(){} +function OQb(){} +function ASb(){} +function fTb(){} +function kTb(){} +function STb(){} +function fUb(){} +function DUb(){} +function VUb(){} +function YUb(){} +function _Ub(){} +function _Wb(){} +function QWb(){} +function XWb(){} +function jVb(){} +function DVb(){} +function VVb(){} +function $Vb(){} +function dXb(){} +function hXb(){} +function lXb(){} +function gYb(){} +function HYb(){} +function SYb(){} +function VYb(){} +function dZb(){} +function P$b(){} +function T$b(){} +function h1b(){} +function m1b(){} +function q1b(){} +function u1b(){} +function y1b(){} +function C1b(){} +function e2b(){} +function g2b(){} +function m2b(){} +function q2b(){} +function u2b(){} +function S2b(){} +function U2b(){} +function W2b(){} +function _2b(){} +function e3b(){} +function h3b(){} +function p3b(){} +function t3b(){} +function w3b(){} +function y3b(){} +function A3b(){} +function M3b(){} +function Q3b(){} +function U3b(){} +function Y3b(){} +function l4b(){} +function q4b(){} +function s4b(){} +function u4b(){} +function w4b(){} +function y4b(){} +function L4b(){} +function N4b(){} +function P4b(){} +function R4b(){} +function T4b(){} +function X4b(){} +function I5b(){} +function Q5b(){} +function T5b(){} +function Z5b(){} +function l6b(){} +function o6b(){} +function t6b(){} +function z6b(){} +function L6b(){} +function M6b(){} +function P6b(){} +function X6b(){} +function $6b(){} +function a7b(){} +function c7b(){} +function g7b(){} +function j7b(){} +function m7b(){} +function r7b(){} +function x7b(){} +function D7b(){} +function D9b(){} +function b9b(){} +function h9b(){} +function j9b(){} +function l9b(){} +function w9b(){} +function F9b(){} +function hac(){} +function jac(){} +function pac(){} +function uac(){} +function Iac(){} +function Kac(){} +function Sac(){} +function obc(){} +function rbc(){} +function vbc(){} +function Fbc(){} +function Jbc(){} +function Xbc(){} +function ccc(){} +function fcc(){} +function lcc(){} +function occ(){} +function tcc(){} +function ycc(){} +function Acc(){} +function Ccc(){} +function Ecc(){} +function Gcc(){} +function Zcc(){} +function _cc(){} +function bdc(){} +function fdc(){} +function jdc(){} +function pdc(){} +function sdc(){} +function ydc(){} +function Adc(){} +function Cdc(){} +function Edc(){} +function Idc(){} +function Ndc(){} +function Qdc(){} +function Sdc(){} +function Udc(){} +function Wdc(){} +function Ydc(){} +function aec(){} +function hec(){} +function jec(){} +function lec(){} +function nec(){} +function uec(){} +function wec(){} +function yec(){} +function Aec(){} +function Fec(){} +function Jec(){} +function Lec(){} +function Nec(){} +function Rec(){} +function Uec(){} +function Zec(){} +function Zfc(){} +function lfc(){} +function tfc(){} +function xfc(){} +function zfc(){} +function Ffc(){} +function Jfc(){} +function Nfc(){} +function Pfc(){} +function Vfc(){} +function _fc(){} +function fgc(){} +function jgc(){} +function lgc(){} +function Bgc(){} +function ehc(){} +function ghc(){} +function ihc(){} +function khc(){} +function mhc(){} +function ohc(){} +function qhc(){} +function yhc(){} +function Ahc(){} +function Ghc(){} +function Ihc(){} +function Khc(){} +function Mhc(){} +function Shc(){} +function Uhc(){} +function Whc(){} +function dic(){} +function dlc(){} +function blc(){} +function flc(){} +function hlc(){} +function jlc(){} +function Glc(){} +function Ilc(){} +function Klc(){} +function Mlc(){} +function Mjc(){} +function Qjc(){} +function Qlc(){} +function Ulc(){} +function Ylc(){} +function Lkc(){} +function Nkc(){} +function Pkc(){} +function Rkc(){} +function Xkc(){} +function _kc(){} +function gmc(){} +function kmc(){} +function zmc(){} +function Fmc(){} +function Wmc(){} +function $mc(){} +function anc(){} +function mnc(){} +function wnc(){} +function Hnc(){} +function Jnc(){} +function Lnc(){} +function Nnc(){} +function Pnc(){} +function Ync(){} +function eoc(){} +function Aoc(){} +function Coc(){} +function Eoc(){} +function Joc(){} +function Loc(){} +function Zoc(){} +function _oc(){} +function bpc(){} +function hpc(){} +function kpc(){} +function ppc(){} +function pFc(){} +function Ryc(){} +function QCc(){} +function PDc(){} +function xGc(){} +function HGc(){} +function JGc(){} +function NGc(){} +function GIc(){} +function iKc(){} +function mKc(){} +function wKc(){} +function yKc(){} +function AKc(){} +function EKc(){} +function KKc(){} +function OKc(){} +function QKc(){} +function SKc(){} +function UKc(){} +function YKc(){} +function aLc(){} +function fLc(){} +function hLc(){} +function nLc(){} +function pLc(){} +function tLc(){} +function vLc(){} +function zLc(){} +function BLc(){} +function DLc(){} +function FLc(){} +function sMc(){} +function JMc(){} +function hNc(){} +function RNc(){} +function ZNc(){} +function _Nc(){} +function bOc(){} +function dOc(){} +function fOc(){} +function hOc(){} +function hRc(){} +function jRc(){} +function KRc(){} +function NRc(){} +function NQc(){} +function LQc(){} +function _Qc(){} +function cPc(){} +function iPc(){} +function kPc(){} +function mPc(){} +function xPc(){} +function zPc(){} +function zSc(){} +function BSc(){} +function GSc(){} +function ISc(){} +function NSc(){} +function TSc(){} +function NTc(){} +function NVc(){} +function oVc(){} +function SVc(){} +function VVc(){} +function XVc(){} +function ZVc(){} +function bWc(){} +function bXc(){} +function CXc(){} +function FXc(){} +function IXc(){} +function MXc(){} +function UXc(){} +function bYc(){} +function fYc(){} +function oYc(){} +function qYc(){} +function uYc(){} +function pZc(){} +function G$c(){} +function h0c(){} +function N0c(){} +function k1c(){} +function I1c(){} +function Q1c(){} +function f2c(){} +function i2c(){} +function k2c(){} +function w2c(){} +function O2c(){} +function S2c(){} +function Z2c(){} +function v3c(){} +function x3c(){} +function R3c(){} +function U3c(){} +function e4c(){} +function w4c(){} +function x4c(){} +function z4c(){} +function B4c(){} +function D4c(){} +function F4c(){} +function H4c(){} +function J4c(){} +function L4c(){} +function N4c(){} +function P4c(){} +function R4c(){} +function T4c(){} +function V4c(){} +function X4c(){} +function Z4c(){} +function _4c(){} +function _7c(){} +function b5c(){} +function d5c(){} +function f5c(){} +function h5c(){} +function H5c(){} +function Hfd(){} +function Zfd(){} +function Zed(){} +function ged(){} +function Jed(){} +function Ned(){} +function Red(){} +function Ved(){} +function bbd(){} +function mdd(){} +function _fd(){} +function fgd(){} +function kgd(){} +function Mgd(){} +function Ahd(){} +function Ald(){} +function Tld(){} +function xkd(){} +function rmd(){} +function knd(){} +function Jod(){} +function JCd(){} +function Bpd(){} +function BFd(){} +function oFd(){} +function bqd(){} +function bvd(){} +function jvd(){} +function yud(){} +function Hxd(){} +function EBd(){} +function aDd(){} +function MGd(){} +function vHd(){} +function RHd(){} +function wNd(){} +function zNd(){} +function CNd(){} +function KNd(){} +function XNd(){} +function $Nd(){} +function HPd(){} +function lUd(){} +function XUd(){} +function DWd(){} +function GWd(){} +function JWd(){} +function MWd(){} +function PWd(){} +function SWd(){} +function VWd(){} +function YWd(){} +function _Wd(){} +function xYd(){} +function BYd(){} +function mZd(){} +function EZd(){} +function GZd(){} +function JZd(){} +function MZd(){} +function PZd(){} +function SZd(){} +function VZd(){} +function YZd(){} +function _Zd(){} +function c$d(){} +function f$d(){} +function i$d(){} +function l$d(){} +function o$d(){} +function r$d(){} +function u$d(){} +function x$d(){} +function A$d(){} +function D$d(){} +function G$d(){} +function J$d(){} +function M$d(){} +function P$d(){} +function S$d(){} +function V$d(){} +function Y$d(){} +function _$d(){} +function c_d(){} +function f_d(){} +function i_d(){} +function l_d(){} +function o_d(){} +function r_d(){} +function u_d(){} +function x_d(){} +function A_d(){} +function D_d(){} +function G_d(){} +function J_d(){} +function M_d(){} +function P_d(){} +function S_d(){} +function V_d(){} +function Y_d(){} +function h5d(){} +function U6d(){} +function U9d(){} +function _8d(){} +function fae(){} +function hae(){} +function kae(){} +function nae(){} +function qae(){} +function tae(){} +function wae(){} +function zae(){} +function Cae(){} +function Fae(){} +function Iae(){} +function Lae(){} +function Oae(){} +function Rae(){} +function Uae(){} +function Xae(){} +function $ae(){} +function bbe(){} +function ebe(){} +function hbe(){} +function kbe(){} +function nbe(){} +function qbe(){} +function tbe(){} +function wbe(){} +function zbe(){} +function Cbe(){} +function Fbe(){} +function Ibe(){} +function Lbe(){} +function Obe(){} +function Rbe(){} +function Ube(){} +function Xbe(){} +function $be(){} +function bce(){} +function ece(){} +function hce(){} +function kce(){} +function nce(){} +function qce(){} +function tce(){} +function wce(){} +function zce(){} +function Cce(){} +function Fce(){} +function Ice(){} +function Lce(){} +function Oce(){} +function Rce(){} +function Uce(){} +function Xce(){} +function ude(){} +function Vge(){} +function dhe(){} +function s_b(a){} +function jSd(a){} +function ol(){wb()} +function oPb(){nPb()} +function EPb(){CPb()} +function gFb(){fFb()} +function TRb(){SRb()} +function ySb(){wSb()} +function PSb(){OSb()} +function dTb(){bTb()} +function i4b(){b4b()} +function D2b(){x2b()} +function J6b(){D6b()} +function u9b(){q9b()} +function $9b(){I9b()} +function Umc(){Imc()} +function abc(){Vac()} +function ZCc(){VCc()} +function kCc(){hCc()} +function rCc(){oCc()} +function Tcc(){Occ()} +function xkc(){gkc()} +function xDc(){rDc()} +function iDc(){cDc()} +function kwc(){jwc()} +function tJc(){jJc()} +function dJc(){aJc()} +function Pyc(){Nyc()} +function VBc(){SBc()} +function CFc(){yFc()} +function CUc(){wUc()} +function lUc(){fUc()} +function sUc(){pUc()} +function IUc(){GUc()} +function IWc(){HWc()} +function _Wc(){ZWc()} +function fHc(){dHc()} +function f0c(){d0c()} +function B0c(){A0c()} +function L0c(){J0c()} +function LTc(){JTc()} +function sTc(){rTc()} +function KLc(){ILc()} +function wNc(){tNc()} +function PYc(){OYc()} +function nZc(){lZc()} +function q3c(){p3c()} +function Z7c(){X7c()} +function Z9c(){Y9c()} +function _ad(){Zad()} +function kdd(){idd()} +function $md(){Smd()} +function HGd(){tGd()} +function hLd(){NKd()} +function J6d(){Uge()} +function Mvb(a){uCb(a)} +function Yb(a){this.a=a} +function cc(a){this.a=a} +function cj(a){this.a=a} +function ij(a){this.a=a} +function Dj(a){this.a=a} +function df(a){this.a=a} +function kf(a){this.a=a} +function ah(a){this.a=a} +function lh(a){this.a=a} +function th(a){this.a=a} +function Ph(a){this.a=a} +function vi(a){this.a=a} +function Ci(a){this.a=a} +function Fk(a){this.a=a} +function Ln(a){this.a=a} +function ap(a){this.a=a} +function zp(a){this.a=a} +function Yp(a){this.a=a} +function qq(a){this.a=a} +function Dq(a){this.a=a} +function wr(a){this.a=a} +function Ir(a){this.b=a} +function sj(a){this.c=a} +function sw(a){this.a=a} +function fw(a){this.a=a} +function xw(a){this.a=a} +function Cw(a){this.a=a} +function Qw(a){this.a=a} +function Rw(a){this.a=a} +function Xw(a){this.a=a} +function Xv(a){this.a=a} +function Sv(a){this.a=a} +function eu(a){this.a=a} +function Zx(a){this.a=a} +function _x(a){this.a=a} +function xy(a){this.a=a} +function xB(a){this.a=a} +function HB(a){this.a=a} +function TB(a){this.a=a} +function fC(a){this.a=a} +function wB(){this.a=[]} +function MBb(a,b){a.a=b} +function w_b(a,b){a.a=b} +function x_b(a,b){a.b=b} +function YOb(a,b){a.b=b} +function $Ob(a,b){a.b=b} +function ZGb(a,b){a.j=b} +function qNb(a,b){a.g=b} +function rNb(a,b){a.i=b} +function dRb(a,b){a.c=b} +function eRb(a,b){a.d=b} +function z_b(a,b){a.d=b} +function y_b(a,b){a.c=b} +function __b(a,b){a.k=b} +function E0b(a,b){a.c=b} +function njc(a,b){a.c=b} +function mjc(a,b){a.a=b} +function dFc(a,b){a.a=b} +function eFc(a,b){a.f=b} +function nOc(a,b){a.a=b} +function oOc(a,b){a.b=b} +function pOc(a,b){a.d=b} +function qOc(a,b){a.i=b} +function rOc(a,b){a.o=b} +function sOc(a,b){a.r=b} +function $Pc(a,b){a.a=b} +function _Pc(a,b){a.b=b} +function DVc(a,b){a.e=b} +function EVc(a,b){a.f=b} +function FVc(a,b){a.g=b} +function SZc(a,b){a.e=b} +function TZc(a,b){a.f=b} +function c$c(a,b){a.f=b} +function bJd(a,b){a.n=b} +function A1d(a,b){a.a=b} +function J1d(a,b){a.a=b} +function B1d(a,b){a.c=b} +function K1d(a,b){a.c=b} +function L1d(a,b){a.d=b} +function M1d(a,b){a.e=b} +function N1d(a,b){a.g=b} +function d2d(a,b){a.a=b} +function e2d(a,b){a.c=b} +function f2d(a,b){a.d=b} +function g2d(a,b){a.e=b} +function h2d(a,b){a.f=b} +function i2d(a,b){a.j=b} +function Z8d(a,b){a.a=b} +function $8d(a,b){a.b=b} +function g9d(a,b){a.a=b} +function Cic(a){a.b=a.a} +function Dg(a){a.c=a.d.d} +function vib(a){this.d=a} +function eib(a){this.a=a} +function Pib(a){this.a=a} +function Vib(a){this.a=a} +function $ib(a){this.a=a} +function mcb(a){this.a=a} +function Mcb(a){this.a=a} +function Xcb(a){this.a=a} +function Ndb(a){this.a=a} +function _db(a){this.a=a} +function teb(a){this.a=a} +function Qeb(a){this.a=a} +function djb(a){this.a=a} +function Gjb(a){this.a=a} +function Njb(a){this.a=a} +function Bjb(a){this.b=a} +function lnb(a){this.b=a} +function Dnb(a){this.b=a} +function anb(a){this.a=a} +function Mob(a){this.a=a} +function Rob(a){this.a=a} +function iob(a){this.c=a} +function olb(a){this.c=a} +function qub(a){this.c=a} +function Tub(a){this.a=a} +function Vub(a){this.a=a} +function Xub(a){this.a=a} +function Zub(a){this.a=a} +function tpb(a){this.a=a} +function _pb(a){this.a=a} +function Wqb(a){this.a=a} +function nsb(a){this.a=a} +function Rxb(a){this.a=a} +function Txb(a){this.a=a} +function Xxb(a){this.a=a} +function bzb(a){this.a=a} +function tzb(a){this.a=a} +function vzb(a){this.a=a} +function xzb(a){this.a=a} +function Kzb(a){this.a=a} +function Ozb(a){this.a=a} +function iAb(a){this.a=a} +function kAb(a){this.a=a} +function mAb(a){this.a=a} +function BAb(a){this.a=a} +function hBb(a){this.a=a} +function jBb(a){this.a=a} +function nBb(a){this.a=a} +function TBb(a){this.a=a} +function XBb(a){this.a=a} +function QCb(a){this.a=a} +function WCb(a){this.a=a} +function _Cb(a){this.a=a} +function dEb(a){this.a=a} +function QGb(a){this.a=a} +function YGb(a){this.a=a} +function tKb(a){this.a=a} +function CLb(a){this.a=a} +function JMb(a){this.a=a} +function RNb(a){this.a=a} +function kQb(a){this.a=a} +function mQb(a){this.a=a} +function FQb(a){this.a=a} +function ETb(a){this.a=a} +function UTb(a){this.a=a} +function dUb(a){this.a=a} +function hUb(a){this.a=a} +function EZb(a){this.a=a} +function j$b(a){this.a=a} +function v$b(a){this.e=a} +function J0b(a){this.a=a} +function M0b(a){this.a=a} +function R0b(a){this.a=a} +function U0b(a){this.a=a} +function i2b(a){this.a=a} +function k2b(a){this.a=a} +function o2b(a){this.a=a} +function s2b(a){this.a=a} +function G2b(a){this.a=a} +function I2b(a){this.a=a} +function K2b(a){this.a=a} +function M2b(a){this.a=a} +function W3b(a){this.a=a} +function $3b(a){this.a=a} +function V4b(a){this.a=a} +function u5b(a){this.a=a} +function A7b(a){this.a=a} +function G7b(a){this.a=a} +function J7b(a){this.a=a} +function M7b(a){this.a=a} +function Mbc(a){this.a=a} +function Pbc(a){this.a=a} +function lac(a){this.a=a} +function nac(a){this.a=a} +function qcc(a){this.a=a} +function Gdc(a){this.a=a} +function $dc(a){this.a=a} +function cec(a){this.a=a} +function _ec(a){this.a=a} +function pfc(a){this.a=a} +function Bfc(a){this.a=a} +function Lfc(a){this.a=a} +function ygc(a){this.a=a} +function Dgc(a){this.a=a} +function shc(a){this.a=a} +function uhc(a){this.a=a} +function whc(a){this.a=a} +function Chc(a){this.a=a} +function Ehc(a){this.a=a} +function Ohc(a){this.a=a} +function Yhc(a){this.a=a} +function Tkc(a){this.a=a} +function Vkc(a){this.a=a} +function Olc(a){this.a=a} +function pnc(a){this.a=a} +function rnc(a){this.a=a} +function dpc(a){this.a=a} +function fpc(a){this.a=a} +function GCc(a){this.a=a} +function KCc(a){this.a=a} +function mDc(a){this.a=a} +function jEc(a){this.a=a} +function HEc(a){this.a=a} +function FEc(a){this.c=a} +function qoc(a){this.b=a} +function bFc(a){this.a=a} +function GFc(a){this.a=a} +function iGc(a){this.a=a} +function kGc(a){this.a=a} +function mGc(a){this.a=a} +function $Gc(a){this.a=a} +function hIc(a){this.a=a} +function lIc(a){this.a=a} +function pIc(a){this.a=a} +function tIc(a){this.a=a} +function xIc(a){this.a=a} +function zIc(a){this.a=a} +function CIc(a){this.a=a} +function LIc(a){this.a=a} +function CKc(a){this.a=a} +function IKc(a){this.a=a} +function MKc(a){this.a=a} +function $Kc(a){this.a=a} +function cLc(a){this.a=a} +function jLc(a){this.a=a} +function rLc(a){this.a=a} +function xLc(a){this.a=a} +function OMc(a){this.a=a} +function ZOc(a){this.a=a} +function ZRc(a){this.a=a} +function aSc(a){this.a=a} +function I$c(a){this.a=a} +function K$c(a){this.a=a} +function M$c(a){this.a=a} +function O$c(a){this.a=a} +function U$c(a){this.a=a} +function n1c(a){this.a=a} +function z1c(a){this.a=a} +function B1c(a){this.a=a} +function Q2c(a){this.a=a} +function U2c(a){this.a=a} +function z3c(a){this.a=a} +function med(a){this.a=a} +function Xed(a){this.a=a} +function _ed(a){this.a=a} +function Qfd(a){this.a=a} +function Bgd(a){this.a=a} +function $gd(a){this.a=a} +function lrd(a){this.a=a} +function urd(a){this.a=a} +function vrd(a){this.a=a} +function wrd(a){this.a=a} +function xrd(a){this.a=a} +function yrd(a){this.a=a} +function zrd(a){this.a=a} +function Ard(a){this.a=a} +function Brd(a){this.a=a} +function Crd(a){this.a=a} +function Ird(a){this.a=a} +function Krd(a){this.a=a} +function Lrd(a){this.a=a} +function Mrd(a){this.a=a} +function Nrd(a){this.a=a} +function Prd(a){this.a=a} +function Srd(a){this.a=a} +function Yrd(a){this.a=a} +function Zrd(a){this.a=a} +function _rd(a){this.a=a} +function asd(a){this.a=a} +function bsd(a){this.a=a} +function csd(a){this.a=a} +function dsd(a){this.a=a} +function msd(a){this.a=a} +function osd(a){this.a=a} +function qsd(a){this.a=a} +function ssd(a){this.a=a} +function Wsd(a){this.a=a} +function Lsd(a){this.b=a} +function thd(a){this.f=a} +function qtd(a){this.a=a} +function yBd(a){this.a=a} +function GBd(a){this.a=a} +function MBd(a){this.a=a} +function SBd(a){this.a=a} +function iCd(a){this.a=a} +function YMd(a){this.a=a} +function GNd(a){this.a=a} +function EPd(a){this.a=a} +function EQd(a){this.a=a} +function NTd(a){this.a=a} +function qOd(a){this.b=a} +function lVd(a){this.c=a} +function VVd(a){this.e=a} +function iYd(a){this.a=a} +function RYd(a){this.a=a} +function ZYd(a){this.a=a} +function z0d(a){this.a=a} +function O0d(a){this.a=a} +function s0d(a){this.d=a} +function W5d(a){this.a=a} +function cge(a){this.a=a} +function xfe(a){this.e=a} +function Tfd(){this.a=0} +function jkb(){Vjb(this)} +function Rkb(){Ckb(this)} +function Lqb(){Uhb(this)} +function lEb(){kEb(this)} +function A_b(){s_b(this)} +function UQd(){this.c=FQd} +function v6d(a,b){b.Wb(a)} +function moc(a,b){a.b+=b} +function yXb(a){a.b=new Ji} +function vbb(a){return a.e} +function DB(a){return a.a} +function LB(a){return a.a} +function ZB(a){return a.a} +function lC(a){return a.a} +function EC(a){return a.a} +function wC(){return null} +function SB(){return null} +function hcb(){mvd();ovd()} +function zJb(a){a.b.tf(a.e)} +function j5b(a,b){a.b=b-a.b} +function g5b(a,b){a.a=b-a.a} +function PXc(a,b){b.ad(a.a)} +function plc(a,b){G0b(b,a)} +function hp(a,b,c){a.Od(c,b)} +function As(a,b){a.e=b;b.b=a} +function Zl(a){Ql();this.a=a} +function jq(a){Ql();this.a=a} +function sq(a){Ql();this.a=a} +function Fq(a){im();this.a=a} +function Sz(a){Rz();Qz.be(a)} +function gz(){Xy.call(this)} +function xcb(){Xy.call(this)} +function pcb(){gz.call(this)} +function tcb(){gz.call(this)} +function Bdb(){gz.call(this)} +function Vdb(){gz.call(this)} +function Ydb(){gz.call(this)} +function Geb(){gz.call(this)} +function bgb(){gz.call(this)} +function Apb(){gz.call(this)} +function Jpb(){gz.call(this)} +function utb(){gz.call(this)} +function x2c(){gz.call(this)} +function rQd(){this.a=this} +function MPd(){this.Bb|=256} +function tTb(){this.b=new mt} +function fA(){fA=ccb;new Lqb} +function rcb(){pcb.call(this)} +function dCb(a,b){a.length=b} +function Tvb(a,b){Ekb(a.a,b)} +function sKb(a,b){UHb(a.c,b)} +function SMc(a,b){Qqb(a.b,b)} +function vBd(a,b){uAd(a.a,b)} +function wBd(a,b){vAd(a.a,b)} +function GLd(a,b){Uhd(a.e,b)} +function d7d(a){D2d(a.c,a.b)} +function mj(a,b){a.kc().Nb(b)} +function Odb(a){this.a=Tdb(a)} +function Tqb(){this.a=new Lqb} +function gyb(){this.a=new Lqb} +function Wvb(){this.a=new Rkb} +function KFb(){this.a=new Rkb} +function PFb(){this.a=new Rkb} +function FFb(){this.a=new yFb} +function pGb(){this.a=new MFb} +function ZQb(){this.a=new MQb} +function Gxb(){this.a=new Pwb} +function jUb(){this.a=new PTb} +function sDb(){this.a=new oDb} +function zDb(){this.a=new tDb} +function CWb(){this.a=new Rkb} +function HXb(){this.a=new Rkb} +function nYb(){this.a=new Rkb} +function BYb(){this.a=new Rkb} +function fLb(){this.d=new Rkb} +function vYb(){this.a=new Tqb} +function a2b(){this.a=new Lqb} +function wZb(){this.b=new Lqb} +function TCc(){this.b=new Rkb} +function zJc(){this.e=new Rkb} +function uMc(){this.d=new Rkb} +function wdc(){this.a=new xkc} +function vKc(){Rkb.call(this)} +function twb(){Wvb.call(this)} +function oHb(){$Gb.call(this)} +function LXb(){HXb.call(this)} +function L_b(){H_b.call(this)} +function H_b(){A_b.call(this)} +function p0b(){A_b.call(this)} +function s0b(){p0b.call(this)} +function WMc(){VMc.call(this)} +function bNc(){VMc.call(this)} +function EPc(){CPc.call(this)} +function JPc(){CPc.call(this)} +function OPc(){CPc.call(this)} +function w1c(){s1c.call(this)} +function s7c(){Psb.call(this)} +function apd(){Ald.call(this)} +function ppd(){Ald.call(this)} +function lDd(){YCd.call(this)} +function NDd(){YCd.call(this)} +function mFd(){Lqb.call(this)} +function vFd(){Lqb.call(this)} +function GFd(){Lqb.call(this)} +function KPd(){Tqb.call(this)} +function OJd(){hJd.call(this)} +function aQd(){MPd.call(this)} +function SSd(){FId.call(this)} +function rUd(){FId.call(this)} +function oUd(){Lqb.call(this)} +function NYd(){Lqb.call(this)} +function cZd(){Lqb.call(this)} +function R8d(){MGd.call(this)} +function o9d(){MGd.call(this)} +function i9d(){R8d.call(this)} +function hee(){ude.call(this)} +function Dd(a){yd.call(this,a)} +function Hd(a){yd.call(this,a)} +function ph(a){lh.call(this,a)} +function Sh(a){Wc.call(this,a)} +function oi(a){Sh.call(this,a)} +function Ii(a){Wc.call(this,a)} +function Zdd(){this.a=new Psb} +function CPc(){this.a=new Tqb} +function s1c(){this.a=new Lqb} +function QSc(){this.a=new Rkb} +function D2c(){this.j=new Rkb} +function QXc(){this.a=new UXc} +function e_c(){this.a=new d_c} +function YCd(){this.a=new aDd} +function _k(){_k=ccb;$k=new al} +function Lk(){Lk=ccb;Kk=new Mk} +function wb(){wb=ccb;vb=new xb} +function hs(){hs=ccb;gs=new is} +function rs(a){Sh.call(this,a)} +function Gp(a){Sh.call(this,a)} +function xp(a){Lo.call(this,a)} +function Ep(a){Lo.call(this,a)} +function Tp(a){Wn.call(this,a)} +function wx(a){un.call(this,a)} +function ov(a){dv.call(this,a)} +function Mv(a){Br.call(this,a)} +function Ov(a){Br.call(this,a)} +function Lw(a){Br.call(this,a)} +function hz(a){Yy.call(this,a)} +function MB(a){hz.call(this,a)} +function eC(){fC.call(this,{})} +function Ftb(a){Atb();this.a=a} +function zwb(a){a.b=null;a.c=0} +function Vy(a,b){a.e=b;Sy(a,b)} +function LVb(a,b){a.a=b;NVb(a)} +function lIb(a,b,c){a.a[b.g]=c} +function vfd(a,b,c){Dfd(c,a,b)} +function Odc(a,b){rjc(b.i,a.n)} +function Wyc(a,b){Xyc(a).td(b)} +function ERb(a,b){return a*a/b} +function Xr(a,b){return a.g-b.g} +function tC(a){return new TB(a)} +function vC(a){return new yC(a)} +function ocb(a){hz.call(this,a)} +function qcb(a){hz.call(this,a)} +function ucb(a){hz.call(this,a)} +function vcb(a){Yy.call(this,a)} +function fGc(a){LFc();this.a=a} +function c0d(a){kzd();this.a=a} +function bhd(a){Rgd();this.f=a} +function dhd(a){Rgd();this.f=a} +function Cdb(a){hz.call(this,a)} +function Wdb(a){hz.call(this,a)} +function Zdb(a){hz.call(this,a)} +function Feb(a){hz.call(this,a)} +function Heb(a){hz.call(this,a)} +function Ccb(a){return uCb(a),a} +function Edb(a){return uCb(a),a} +function Gdb(a){return uCb(a),a} +function jfb(a){return uCb(a),a} +function tfb(a){return uCb(a),a} +function akb(a){return a.b==a.c} +function Hwb(a){return !!a&&a.b} +function pIb(a){return !!a&&a.k} +function qIb(a){return !!a&&a.j} +function amb(a){uCb(a);this.a=a} +function wVb(a){qVb(a);return a} +function Blb(a){Glb(a,a.length)} +function cgb(a){hz.call(this,a)} +function cqd(a){hz.call(this,a)} +function n8d(a){hz.call(this,a)} +function y2c(a){hz.call(this,a)} +function z2c(a){hz.call(this,a)} +function mde(a){hz.call(this,a)} +function pc(a){qc.call(this,a,0)} +function Ji(){Ki.call(this,12,3)} +function Kz(){Kz=ccb;Jz=new Nz} +function jz(){jz=ccb;iz=new nb} +function KA(){KA=ccb;JA=new MA} +function OB(){OB=ccb;NB=new PB} +function jc(){throw vbb(new bgb)} +function zh(){throw vbb(new bgb)} +function Pi(){throw vbb(new bgb)} +function Pj(){throw vbb(new bgb)} +function Qj(){throw vbb(new bgb)} +function Ym(){throw vbb(new bgb)} +function Gb(){this.a=GD(Qb(She))} +function oy(a){Ql();this.a=Qb(a)} +function Bs(a,b){a.Td(b);b.Sd(a)} +function iw(a,b){a.a.ec().Mc(b)} +function CYb(a,b,c){a.c.lf(b,c)} +function scb(a){qcb.call(this,a)} +function Oeb(a){Wdb.call(this,a)} +function Hfb(){mcb.call(this,'')} +function Ifb(){mcb.call(this,'')} +function Ufb(){mcb.call(this,'')} +function Vfb(){mcb.call(this,'')} +function Xfb(a){qcb.call(this,a)} +function zob(a){lnb.call(this,a)} +function Yob(a){Inb.call(this,a)} +function Gob(a){zob.call(this,a)} +function Mk(){Fk.call(this,null)} +function al(){Fk.call(this,null)} +function Az(){Az=ccb;!!(Rz(),Qz)} +function wrb(){wrb=ccb;vrb=yrb()} +function Mtb(a){return a.a?a.b:0} +function Vtb(a){return a.a?a.b:0} +function Lcb(a,b){return a.a-b.a} +function Wcb(a,b){return a.a-b.a} +function Peb(a,b){return a.a-b.a} +function eCb(a,b){return PC(a,b)} +function GC(a,b){return rdb(a,b)} +function _B(b,a){return a in b.a} +function _Db(a,b){a.f=b;return a} +function ZDb(a,b){a.b=b;return a} +function $Db(a,b){a.c=b;return a} +function aEb(a,b){a.g=b;return a} +function HGb(a,b){a.a=b;return a} +function IGb(a,b){a.f=b;return a} +function JGb(a,b){a.k=b;return a} +function dLb(a,b){a.a=b;return a} +function eLb(a,b){a.e=b;return a} +function zVb(a,b){a.e=b;return a} +function AVb(a,b){a.f=b;return a} +function KOb(a,b){a.b=true;a.d=b} +function DHb(a,b){a.b=new g7c(b)} +function uvb(a,b,c){b.td(a.a[c])} +function zvb(a,b,c){b.we(a.a[c])} +function wJc(a,b){return a.b-b.b} +function kOc(a,b){return a.g-b.g} +function WQc(a,b){return a.s-b.s} +function Lic(a,b){return a?0:b-1} +function SFc(a,b){return a?0:b-1} +function RFc(a,b){return a?b-1:0} +function M2c(a,b){return b.Yf(a)} +function M3c(a,b){a.b=b;return a} +function L3c(a,b){a.a=b;return a} +function N3c(a,b){a.c=b;return a} +function O3c(a,b){a.d=b;return a} +function P3c(a,b){a.e=b;return a} +function Q3c(a,b){a.f=b;return a} +function b4c(a,b){a.a=b;return a} +function c4c(a,b){a.b=b;return a} +function d4c(a,b){a.c=b;return a} +function z5c(a,b){a.c=b;return a} +function y5c(a,b){a.b=b;return a} +function A5c(a,b){a.d=b;return a} +function B5c(a,b){a.e=b;return a} +function C5c(a,b){a.f=b;return a} +function D5c(a,b){a.g=b;return a} +function E5c(a,b){a.a=b;return a} +function F5c(a,b){a.i=b;return a} +function G5c(a,b){a.j=b;return a} +function Vdd(a,b){a.k=b;return a} +function Wdd(a,b){a.j=b;return a} +function ykc(a,b){gkc();F0b(b,a)} +function T$c(a,b,c){R$c(a.a,b,c)} +function RGc(a){cEc.call(this,a)} +function iHc(a){cEc.call(this,a)} +function t7c(a){Qsb.call(this,a)} +function aPb(a){_Ob.call(this,a)} +function Ixd(a){zud.call(this,a)} +function dCd(a){ZBd.call(this,a)} +function fCd(a){ZBd.call(this,a)} +function p_b(){q_b.call(this,'')} +function d7c(){this.a=0;this.b=0} +function aPc(){this.b=0;this.a=0} +function NJd(a,b){a.b=0;DId(a,b)} +function X1d(a,b){a.c=b;a.b=true} +function Oc(a,b){return a.c._b(b)} +function gdb(a){return a.e&&a.e()} +function Vd(a){return !a?null:a.d} +function sn(a,b){return Gv(a.b,b)} +function Fv(a){return !a?null:a.g} +function Kv(a){return !a?null:a.i} +function hdb(a){fdb(a);return a.o} +function Fhd(){Fhd=ccb;Ehd=ond()} +function Hhd(){Hhd=ccb;Ghd=Cod()} +function LFd(){LFd=ccb;KFd=qZd()} +function p8d(){p8d=ccb;o8d=Y9d()} +function r8d(){r8d=ccb;q8d=dae()} +function mvd(){mvd=ccb;lvd=n4c()} +function Srb(){throw vbb(new bgb)} +function enb(){throw vbb(new bgb)} +function fnb(){throw vbb(new bgb)} +function gnb(){throw vbb(new bgb)} +function jnb(){throw vbb(new bgb)} +function Cnb(){throw vbb(new bgb)} +function Uqb(a){this.a=new Mqb(a)} +function tgb(a){lgb();ngb(this,a)} +function Hxb(a){this.a=new Qwb(a)} +function _ub(a,b){while(a.ye(b));} +function Sub(a,b){while(a.sd(b));} +function Bfb(a,b){a.a+=b;return a} +function Cfb(a,b){a.a+=b;return a} +function Ffb(a,b){a.a+=b;return a} +function Lfb(a,b){a.a+=b;return a} +function WAb(a){Tzb(a);return a.a} +function Wsb(a){return a.b!=a.d.c} +function pD(a){return a.l|a.m<<22} +function aIc(a,b){return a.d[b.p]} +function h2c(a,b){return c2c(a,b)} +function cCb(a,b,c){a.splice(b,c)} +function WHb(a){a.c?VHb(a):XHb(a)} +function jVc(a){this.a=0;this.b=a} +function ZUc(){this.a=new L2c(K$)} +function tRc(){this.b=new L2c(h$)} +function Q$c(){this.b=new L2c(J_)} +function d_c(){this.b=new L2c(J_)} +function OCd(){throw vbb(new bgb)} +function PCd(){throw vbb(new bgb)} +function QCd(){throw vbb(new bgb)} +function RCd(){throw vbb(new bgb)} +function SCd(){throw vbb(new bgb)} +function TCd(){throw vbb(new bgb)} +function UCd(){throw vbb(new bgb)} +function VCd(){throw vbb(new bgb)} +function WCd(){throw vbb(new bgb)} +function XCd(){throw vbb(new bgb)} +function ahe(){throw vbb(new utb)} +function bhe(){throw vbb(new utb)} +function Rge(a){this.a=new ege(a)} +function ege(a){dge(this,a,Vee())} +function Fhe(a){return !a||Ehe(a)} +function dde(a){return $ce[a]!=-1} +function Iz(){xz!=0&&(xz=0);zz=-1} +function Ybb(){Wbb==null&&(Wbb=[])} +function ONd(a,b){Rxd(ZKd(a.a),b)} +function TNd(a,b){Rxd(ZKd(a.a),b)} +function Yf(a,b){zf.call(this,a,b)} +function $f(a,b){Yf.call(this,a,b)} +function Hf(a,b){this.b=a;this.c=b} +function rk(a,b){this.b=a;this.a=b} +function ek(a,b){this.a=a;this.b=b} +function gk(a,b){this.a=a;this.b=b} +function pk(a,b){this.a=a;this.b=b} +function yk(a,b){this.a=a;this.b=b} +function Ak(a,b){this.a=a;this.b=b} +function Fj(a,b){this.a=a;this.b=b} +function _j(a,b){this.a=a;this.b=b} +function dr(a,b){this.a=a;this.b=b} +function zr(a,b){this.b=a;this.a=b} +function So(a,b){this.b=a;this.a=b} +function qp(a,b){this.b=a;this.a=b} +function $q(a,b){this.b=a;this.a=b} +function $r(a,b){this.f=a;this.g=b} +function ne(a,b){this.e=a;this.d=b} +function Wo(a,b){this.g=a;this.i=b} +function bu(a,b){this.a=a;this.b=b} +function qu(a,b){this.a=a;this.f=b} +function qv(a,b){this.b=a;this.c=b} +function ox(a,b){this.a=a;this.b=b} +function Px(a,b){this.a=a;this.b=b} +function mC(a,b){this.a=a;this.b=b} +function Wc(a){Lb(a.dc());this.c=a} +function rf(a){this.b=BD(Qb(a),83)} +function Zv(a){this.a=BD(Qb(a),83)} +function dv(a){this.a=BD(Qb(a),15)} +function $u(a){this.a=BD(Qb(a),15)} +function Br(a){this.b=BD(Qb(a),47)} +function eB(){this.q=new $wnd.Date} +function Zfb(){Zfb=ccb;Yfb=new jcb} +function Emb(){Emb=ccb;Dmb=new Fmb} +function Vhb(a){return a.f.c+a.g.c} +function hnb(a,b){return a.b.Hc(b)} +function inb(a,b){return a.b.Ic(b)} +function knb(a,b){return a.b.Qc(b)} +function Dob(a,b){return a.b.Hc(b)} +function dob(a,b){return a.c.uc(b)} +function Rqb(a,b){return a.a._b(b)} +function fob(a,b){return pb(a.c,b)} +function jt(a,b){return Mhb(a.b,b)} +function Lp(a,b){return a>b&&b<Iie} +function Ryb(a,b){return a.Gc(b),a} +function Syb(a,b){return ye(a,b),a} +function sC(a){return GB(),a?FB:EB} +function Mqb(a){Whb.call(this,a,0)} +function Pwb(){Qwb.call(this,null)} +function yAb(){Vzb.call(this,null)} +function Gqb(a){this.c=a;Dqb(this)} +function Psb(){Csb(this);Osb(this)} +function MAb(a,b){Tzb(a);a.a.Nb(b)} +function Myb(a,b){a.Gc(b);return a} +function qDb(a,b){a.a.f=b;return a} +function wDb(a,b){a.a.d=b;return a} +function xDb(a,b){a.a.g=b;return a} +function yDb(a,b){a.a.j=b;return a} +function BFb(a,b){a.a.a=b;return a} +function CFb(a,b){a.a.d=b;return a} +function DFb(a,b){a.a.e=b;return a} +function EFb(a,b){a.a.g=b;return a} +function oGb(a,b){a.a.f=b;return a} +function TGb(a){a.b=false;return a} +function Ltb(){Ltb=ccb;Ktb=new Otb} +function Utb(){Utb=ccb;Ttb=new Wtb} +function $xb(){$xb=ccb;Zxb=new byb} +function $Yb(){$Yb=ccb;ZYb=new dZb} +function cPb(){cPb=ccb;bPb=new dPb} +function EAb(){EAb=ccb;DAb=new PBb} +function a$b(){a$b=ccb;_Zb=new P$b} +function FDb(){FDb=ccb;EDb=new GDb} +function xUb(){xUb=ccb;wUb=new DUb} +function x2b(){x2b=ccb;w2b=new d7c} +function iVb(){iVb=ccb;hVb=new jVb} +function nVb(){nVb=ccb;mVb=new OVb} +function LWb(){LWb=ccb;KWb=new QWb} +function b4b(){b4b=ccb;a4b=new l4b} +function q9b(){q9b=ccb;p9b=new w9b} +function qgc(){qgc=ccb;pgc=new dic} +function Imc(){Imc=ccb;Hmc=new Wmc} +function GUc(){GUc=ccb;FUc=new j3c} +function i_c(){i_c=ccb;h_c=new k_c} +function s_c(){s_c=ccb;r_c=new t_c} +function R0c(){R0c=ccb;Q0c=new T0c} +function Vyc(){Vyc=ccb;Uyc=new Ved} +function DCc(){vCc();this.c=new Ji} +function k_c(){$r.call(this,Une,0)} +function r4c(a,b){Xrb(a.c.b,b.c,b)} +function s4c(a,b){Xrb(a.c.c,b.b,b)} +function B3c(a,b,c){Shb(a.d,b.f,c)} +function kKb(a,b,c,d){jKb(a,d,b,c)} +function E3b(a,b,c,d){J3b(d,a,b,c)} +function e9b(a,b,c,d){f9b(d,a,b,c)} +function g3c(a,b){a.a=b.g;return a} +function DQd(a,b){return qA(a.a,b)} +function nQd(a){return a.b?a.b:a.a} +function $Oc(a){return (a.c+a.a)/2} +function Pgd(){Pgd=ccb;Ogd=new Ahd} +function AFd(){AFd=ccb;zFd=new BFd} +function tFd(){tFd=ccb;sFd=new vFd} +function EFd(){EFd=ccb;DFd=new GFd} +function yFd(){yFd=ccb;xFd=new oUd} +function JFd(){JFd=ccb;IFd=new cZd} +function nRd(){nRd=ccb;mRd=new u4d} +function LRd(){LRd=ccb;KRd=new y4d} +function g5d(){g5d=ccb;f5d=new h5d} +function Q6d(){Q6d=ccb;P6d=new U6d} +function pEd(){pEd=ccb;oEd=new Lqb} +function tZd(){tZd=ccb;rZd=new Rkb} +function Xge(){Xge=ccb;Wge=new dhe} +function Hz(a){$wnd.clearTimeout(a)} +function jw(a){this.a=BD(Qb(a),224)} +function Lv(a){return BD(a,42).cd()} +function sib(a){return a.b<a.d.gc()} +function Lpb(a,b){return tqb(a.a,b)} +function Dbb(a,b){return ybb(a,b)>0} +function Gbb(a,b){return ybb(a,b)<0} +function Crb(a,b){return a.a.get(b)} +function icb(b,a){return a.split(b)} +function Vrb(a,b){return Mhb(a.e,b)} +function Nvb(a){return uCb(a),false} +function Rub(a){Kub.call(this,a,21)} +function wcb(a,b){Zy.call(this,a,b)} +function mxb(a,b){$r.call(this,a,b)} +function Gyb(a,b){$r.call(this,a,b)} +function zx(a){yx();Wn.call(this,a)} +function zlb(a,b){Dlb(a,a.length,b)} +function Alb(a,b){Flb(a,a.length,b)} +function ABb(a,b,c){b.ud(a.a.Ge(c))} +function uBb(a,b,c){b.we(a.a.Fe(c))} +function GBb(a,b,c){b.td(a.a.Kb(c))} +function Zq(a,b,c){a.Mb(c)&&b.td(c)} +function aCb(a,b,c){a.splice(b,0,c)} +function lDb(a,b){return uqb(a.e,b)} +function pjb(a,b){this.d=a;this.e=b} +function kqb(a,b){this.b=a;this.a=b} +function VBb(a,b){this.b=a;this.a=b} +function BEb(a,b){this.b=a;this.a=b} +function sBb(a,b){this.a=a;this.b=b} +function yBb(a,b){this.a=a;this.b=b} +function EBb(a,b){this.a=a;this.b=b} +function KBb(a,b){this.a=a;this.b=b} +function aDb(a,b){this.a=a;this.b=b} +function tMb(a,b){this.b=a;this.a=b} +function oOb(a,b){this.b=a;this.a=b} +function SOb(a,b){$r.call(this,a,b)} +function SMb(a,b){$r.call(this,a,b)} +function NEb(a,b){$r.call(this,a,b)} +function VEb(a,b){$r.call(this,a,b)} +function sFb(a,b){$r.call(this,a,b)} +function hHb(a,b){$r.call(this,a,b)} +function OHb(a,b){$r.call(this,a,b)} +function FIb(a,b){$r.call(this,a,b)} +function wLb(a,b){$r.call(this,a,b)} +function YRb(a,b){$r.call(this,a,b)} +function zTb(a,b){$r.call(this,a,b)} +function rUb(a,b){$r.call(this,a,b)} +function oWb(a,b){$r.call(this,a,b)} +function SXb(a,b){$r.call(this,a,b)} +function k0b(a,b){$r.call(this,a,b)} +function z5b(a,b){$r.call(this,a,b)} +function T8b(a,b){$r.call(this,a,b)} +function ibc(a,b){$r.call(this,a,b)} +function Cec(a,b){this.a=a;this.b=b} +function rfc(a,b){this.a=a;this.b=b} +function Rfc(a,b){this.a=a;this.b=b} +function Tfc(a,b){this.a=a;this.b=b} +function bgc(a,b){this.a=a;this.b=b} +function ngc(a,b){this.a=a;this.b=b} +function Qhc(a,b){this.a=a;this.b=b} +function $hc(a,b){this.a=a;this.b=b} +function Z0b(a,b){this.a=a;this.b=b} +function ZVb(a,b){this.b=a;this.a=b} +function Dfc(a,b){this.b=a;this.a=b} +function dgc(a,b){this.b=a;this.a=b} +function Bmc(a,b){this.b=a;this.a=b} +function cWb(a,b){this.c=a;this.d=b} +function I$b(a,b){this.e=a;this.d=b} +function Unc(a,b){this.a=a;this.b=b} +function Oic(a,b){this.b=b;this.c=a} +function Bjc(a,b){$r.call(this,a,b)} +function Yjc(a,b){$r.call(this,a,b)} +function Gkc(a,b){$r.call(this,a,b)} +function Bpc(a,b){$r.call(this,a,b)} +function Jpc(a,b){$r.call(this,a,b)} +function Tpc(a,b){$r.call(this,a,b)} +function cqc(a,b){$r.call(this,a,b)} +function oqc(a,b){$r.call(this,a,b)} +function yqc(a,b){$r.call(this,a,b)} +function Hqc(a,b){$r.call(this,a,b)} +function Uqc(a,b){$r.call(this,a,b)} +function arc(a,b){$r.call(this,a,b)} +function mrc(a,b){$r.call(this,a,b)} +function zrc(a,b){$r.call(this,a,b)} +function Prc(a,b){$r.call(this,a,b)} +function Yrc(a,b){$r.call(this,a,b)} +function fsc(a,b){$r.call(this,a,b)} +function nsc(a,b){$r.call(this,a,b)} +function nzc(a,b){$r.call(this,a,b)} +function zzc(a,b){$r.call(this,a,b)} +function Kzc(a,b){$r.call(this,a,b)} +function Xzc(a,b){$r.call(this,a,b)} +function Dtc(a,b){$r.call(this,a,b)} +function lAc(a,b){$r.call(this,a,b)} +function uAc(a,b){$r.call(this,a,b)} +function CAc(a,b){$r.call(this,a,b)} +function LAc(a,b){$r.call(this,a,b)} +function UAc(a,b){$r.call(this,a,b)} +function aBc(a,b){$r.call(this,a,b)} +function uBc(a,b){$r.call(this,a,b)} +function DBc(a,b){$r.call(this,a,b)} +function MBc(a,b){$r.call(this,a,b)} +function sGc(a,b){$r.call(this,a,b)} +function VIc(a,b){$r.call(this,a,b)} +function EIc(a,b){this.b=a;this.a=b} +function qKc(a,b){this.a=a;this.b=b} +function GKc(a,b){this.a=a;this.b=b} +function lLc(a,b){this.a=a;this.b=b} +function mMc(a,b){this.a=a;this.b=b} +function fMc(a,b){$r.call(this,a,b)} +function ZLc(a,b){$r.call(this,a,b)} +function ZMc(a,b){this.b=a;this.d=b} +function IOc(a,b){$r.call(this,a,b)} +function GQc(a,b){$r.call(this,a,b)} +function PQc(a,b){this.a=a;this.b=b} +function RQc(a,b){this.a=a;this.b=b} +function ARc(a,b){$r.call(this,a,b)} +function rSc(a,b){$r.call(this,a,b)} +function TTc(a,b){$r.call(this,a,b)} +function _Tc(a,b){$r.call(this,a,b)} +function RUc(a,b){$r.call(this,a,b)} +function uVc(a,b){$r.call(this,a,b)} +function hWc(a,b){$r.call(this,a,b)} +function rWc(a,b){$r.call(this,a,b)} +function kXc(a,b){$r.call(this,a,b)} +function uXc(a,b){$r.call(this,a,b)} +function AYc(a,b){$r.call(this,a,b)} +function l$c(a,b){$r.call(this,a,b)} +function Z$c(a,b){$r.call(this,a,b)} +function D_c(a,b){$r.call(this,a,b)} +function O_c(a,b){$r.call(this,a,b)} +function c1c(a,b){$r.call(this,a,b)} +function cVb(a,b){return uqb(a.c,b)} +function nnc(a,b){return uqb(b.b,a)} +function x1c(a,b){return -a.b.Je(b)} +function D3c(a,b){return uqb(a.g,b)} +function O5c(a,b){$r.call(this,a,b)} +function a6c(a,b){$r.call(this,a,b)} +function m2c(a,b){this.a=a;this.b=b} +function W2c(a,b){this.a=a;this.b=b} +function f7c(a,b){this.a=a;this.b=b} +function G7c(a,b){$r.call(this,a,b)} +function j8c(a,b){$r.call(this,a,b)} +function iad(a,b){$r.call(this,a,b)} +function rad(a,b){$r.call(this,a,b)} +function Bad(a,b){$r.call(this,a,b)} +function Nad(a,b){$r.call(this,a,b)} +function ibd(a,b){$r.call(this,a,b)} +function tbd(a,b){$r.call(this,a,b)} +function Ibd(a,b){$r.call(this,a,b)} +function Ubd(a,b){$r.call(this,a,b)} +function gcd(a,b){$r.call(this,a,b)} +function scd(a,b){$r.call(this,a,b)} +function Ycd(a,b){$r.call(this,a,b)} +function udd(a,b){$r.call(this,a,b)} +function Jdd(a,b){$r.call(this,a,b)} +function Eed(a,b){$r.call(this,a,b)} +function bfd(a,b){this.a=a;this.b=b} +function dfd(a,b){this.a=a;this.b=b} +function ffd(a,b){this.a=a;this.b=b} +function Kfd(a,b){this.a=a;this.b=b} +function Mfd(a,b){this.a=a;this.b=b} +function Ofd(a,b){this.a=a;this.b=b} +function vgd(a,b){this.a=a;this.b=b} +function qgd(a,b){$r.call(this,a,b)} +function jrd(a,b){this.a=a;this.b=b} +function krd(a,b){this.a=a;this.b=b} +function mrd(a,b){this.a=a;this.b=b} +function nrd(a,b){this.a=a;this.b=b} +function qrd(a,b){this.a=a;this.b=b} +function rrd(a,b){this.a=a;this.b=b} +function srd(a,b){this.b=a;this.a=b} +function trd(a,b){this.b=a;this.a=b} +function Drd(a,b){this.b=a;this.a=b} +function Frd(a,b){this.b=a;this.a=b} +function Hrd(a,b){this.a=a;this.b=b} +function Jrd(a,b){this.a=a;this.b=b} +function Ord(a,b){Xqd(a.a,BD(b,56))} +function BIc(a,b){gIc(a.a,BD(b,11))} +function fIc(a,b){FHc();return b!=a} +function Arb(){wrb();return new vrb} +function CMc(){wMc();this.b=new Tqb} +function NNc(){FNc();this.a=new Tqb} +function eCc(){ZBc();aCc.call(this)} +function Dsd(a,b){$r.call(this,a,b)} +function Urd(a,b){this.a=a;this.b=b} +function Wrd(a,b){this.a=a;this.b=b} +function kGd(a,b){this.a=a;this.b=b} +function nGd(a,b){this.a=a;this.b=b} +function bUd(a,b){this.a=a;this.b=b} +function zVd(a,b){this.a=a;this.b=b} +function C1d(a,b){this.d=a;this.b=b} +function MLd(a,b){this.d=a;this.e=b} +function Wud(a,b){this.f=a;this.c=b} +function f7d(a,b){this.b=a;this.c=b} +function _zd(a,b){this.i=a;this.g=b} +function Y1d(a,b){this.e=a;this.a=b} +function c8d(a,b){this.a=a;this.b=b} +function $Id(a,b){a.i=null;_Id(a,b)} +function ivd(a,b){!!a&&Rhb(cvd,a,b)} +function hCd(a,b){return qAd(a.a,b)} +function e7d(a){return R2d(a.c,a.b)} +function Wd(a){return !a?null:a.dd()} +function PD(a){return a==null?null:a} +function KD(a){return typeof a===Khe} +function LD(a){return typeof a===Lhe} +function ND(a){return typeof a===Mhe} +function Em(a,b){return a.Hd().Xb(b)} +function Kq(a,b){return hr(a.Kc(),b)} +function Bbb(a,b){return ybb(a,b)==0} +function Ebb(a,b){return ybb(a,b)>=0} +function Kbb(a,b){return ybb(a,b)!=0} +function Jdb(a){return ''+(uCb(a),a)} +function pfb(a,b){return a.substr(b)} +function cg(a){ag(a);return a.d.gc()} +function oVb(a){pVb(a,a.c);return a} +function RD(a){CCb(a==null);return a} +function Dfb(a,b){a.a+=''+b;return a} +function Efb(a,b){a.a+=''+b;return a} +function Nfb(a,b){a.a+=''+b;return a} +function Pfb(a,b){a.a+=''+b;return a} +function Qfb(a,b){a.a+=''+b;return a} +function Mfb(a,b){return a.a+=''+b,a} +function Esb(a,b){Gsb(a,b,a.a,a.a.a)} +function Fsb(a,b){Gsb(a,b,a.c.b,a.c)} +function Mqd(a,b,c){Rpd(b,kqd(a,c))} +function Nqd(a,b,c){Rpd(b,kqd(a,c))} +function Dhe(a,b){Hhe(new Fyd(a),b)} +function cB(a,b){a.q.setTime(Sbb(b))} +function fvb(a,b){bvb.call(this,a,b)} +function jvb(a,b){bvb.call(this,a,b)} +function nvb(a,b){bvb.call(this,a,b)} +function Nqb(a){Uhb(this);Ld(this,a)} +function wmb(a){tCb(a,0);return null} +function X6c(a){a.a=0;a.b=0;return a} +function f3c(a,b){a.a=b.g+1;return a} +function PJc(a,b){return a.j[b.p]==2} +function _Pb(a){return VPb(BD(a,79))} +function yJb(){yJb=ccb;xJb=as(wJb())} +function Y8b(){Y8b=ccb;X8b=as(W8b())} +function mt(){this.b=new Mqb(Cv(12))} +function Otb(){this.b=0;this.a=false} +function Wtb(){this.b=0;this.a=false} +function sl(a){this.a=a;ol.call(this)} +function vl(a){this.a=a;ol.call(this)} +function Nsd(a,b){Msd.call(this,a,b)} +function $zd(a,b){Cyd.call(this,a,b)} +function nNd(a,b){_zd.call(this,a,b)} +function s4d(a,b){p4d.call(this,a,b)} +function w4d(a,b){qRd.call(this,a,b)} +function rEd(a,b){pEd();Rhb(oEd,a,b)} +function lcb(a,b){return qfb(a.a,0,b)} +function ww(a,b){return a.a.a.a.cc(b)} +function mb(a,b){return PD(a)===PD(b)} +function Mdb(a,b){return Kdb(a.a,b.a)} +function $db(a,b){return beb(a.a,b.a)} +function seb(a,b){return ueb(a.a,b.a)} +function hfb(a,b){return a.indexOf(b)} +function Ny(a,b){return a==b?0:a?1:-1} +function kB(a){return a<10?'0'+a:''+a} +function Mq(a){return Qb(a),new sl(a)} +function SC(a){return TC(a.l,a.m,a.h)} +function Hdb(a){return QD((uCb(a),a))} +function Idb(a){return QD((uCb(a),a))} +function NIb(a,b){return beb(a.g,b.g)} +function Fbb(a){return typeof a===Lhe} +function mWb(a){return a==hWb||a==kWb} +function nWb(a){return a==hWb||a==iWb} +function G1b(a){return Jkb(a.b.b,a,0)} +function lrb(a){this.a=Arb();this.b=a} +function Frb(a){this.a=Arb();this.b=a} +function swb(a,b){Ekb(a.a,b);return b} +function Z1c(a,b){Ekb(a.c,b);return a} +function E2c(a,b){d3c(a.a,b);return a} +function _gc(a,b){Hgc();return b.a+=a} +function bhc(a,b){Hgc();return b.a+=a} +function ahc(a,b){Hgc();return b.c+=a} +function Nlb(a,b){Klb(a,0,a.length,b)} +function zsb(){Wqb.call(this,new $rb)} +function I_b(){B_b.call(this,0,0,0,0)} +function I6c(){J6c.call(this,0,0,0,0)} +function g7c(a){this.a=a.a;this.b=a.b} +function fad(a){return a==aad||a==bad} +function gad(a){return a==dad||a==_9c} +function Jzc(a){return a==Fzc||a==Ezc} +function fcd(a){return a!=bcd&&a!=ccd} +function oid(a){return a.Lg()&&a.Mg()} +function Gfd(a){return Kkd(BD(a,118))} +function k3c(a){return d3c(new j3c,a)} +function y2d(a,b){return new p4d(b,a)} +function z2d(a,b){return new p4d(b,a)} +function ukd(a,b,c){vkd(a,b);wkd(a,c)} +function _kd(a,b,c){cld(a,b);ald(a,c)} +function bld(a,b,c){dld(a,b);eld(a,c)} +function gmd(a,b,c){hmd(a,b);imd(a,c)} +function nmd(a,b,c){omd(a,b);pmd(a,c)} +function iKd(a,b){$Jd(a,b);_Jd(a,a.D)} +function _ud(a){Wud.call(this,a,true)} +function Xg(a,b,c){Vg.call(this,a,b,c)} +function Ygb(a){Hgb();Zgb.call(this,a)} +function rxb(){mxb.call(this,'Head',1)} +function wxb(){mxb.call(this,'Tail',3)} +function Ckb(a){a.c=KC(SI,Uhe,1,0,5,1)} +function Vjb(a){a.a=KC(SI,Uhe,1,8,5,1)} +function MGb(a){Hkb(a.xf(),new QGb(a))} +function xtb(a){return a!=null?tb(a):0} +function b2b(a,b){return ntd(b,mpd(a))} +function c2b(a,b){return ntd(b,mpd(a))} +function dAb(a,b){return a[a.length]=b} +function gAb(a,b){return a[a.length]=b} +function Vq(a){return lr(a.b.Kc(),a.a)} +function dqd(a,b){return _o(qo(a.d),b)} +function eqd(a,b){return _o(qo(a.g),b)} +function fqd(a,b){return _o(qo(a.j),b)} +function Osd(a,b){Msd.call(this,a.b,b)} +function q0b(a){B_b.call(this,a,a,a,a)} +function HOb(a){a.b&&LOb(a);return a.a} +function IOb(a){a.b&&LOb(a);return a.c} +function uyb(a,b){if(lyb){return}a.b=b} +function lzd(a,b,c){NC(a,b,c);return c} +function mBc(a,b,c){NC(a.c[b.g],b.g,c)} +function _Hd(a,b,c){BD(a.c,69).Xh(b,c)} +function wfd(a,b,c){bld(c,c.i+a,c.j+b)} +function UOd(a,b){wtd(VKd(a.a),XOd(b))} +function bTd(a,b){wtd(QSd(a.a),eTd(b))} +function Lge(a){wfe();xfe.call(this,a)} +function CAd(a){return a==null?0:tb(a)} +function fNc(){fNc=ccb;eNc=new Rpb(v1)} +function h0d(){h0d=ccb;new i0d;new Rkb} +function i0d(){new Lqb;new Lqb;new Lqb} +function GA(){GA=ccb;fA();FA=new Lqb} +function Iy(){Iy=ccb;$wnd.Math.log(2)} +function UVd(){UVd=ccb;TVd=(AFd(),zFd)} +function _ge(){throw vbb(new cgb(Cxe))} +function ohe(){throw vbb(new cgb(Cxe))} +function che(){throw vbb(new cgb(Dxe))} +function rhe(){throw vbb(new cgb(Dxe))} +function Mg(a){this.a=a;Gg.call(this,a)} +function up(a){this.a=a;rf.call(this,a)} +function Bp(a){this.a=a;rf.call(this,a)} +function Okb(a,b){Mlb(a.c,a.c.length,b)} +function llb(a){return a.a<a.c.c.length} +function Eqb(a){return a.a<a.c.a.length} +function Ntb(a,b){return a.a?a.b:b.De()} +function beb(a,b){return a<b?-1:a>b?1:0} +function Deb(a,b){return ybb(a,b)>0?a:b} +function TC(a,b,c){return {l:a,m:b,h:c}} +function Ctb(a,b){a.a!=null&&BIc(b,a.a)} +function Csb(a){a.a=new jtb;a.c=new jtb} +function hDb(a){this.b=a;this.a=new Rkb} +function dOb(a){this.b=new pOb;this.a=a} +function q_b(a){n_b.call(this);this.a=a} +function txb(){mxb.call(this,'Range',2)} +function bUb(){ZTb();this.a=new L2c(zP)} +function Bh(a,b){Qb(b);Ah(a).Jc(new Vw)} +function fKc(a,b){FJc();return b.n.b+=a} +function Tgc(a,b,c){return Rhb(a.g,c,b)} +function LJc(a,b,c){return Rhb(a.k,c,b)} +function r1c(a,b){return Rhb(a.a,b.a,b)} +function jBc(a,b,c){return hBc(b,c,a.c)} +function E6c(a){return new f7c(a.c,a.d)} +function F6c(a){return new f7c(a.c,a.d)} +function R6c(a){return new f7c(a.a,a.b)} +function CQd(a,b){return hA(a.a,b,null)} +function fec(a){QZb(a,null);RZb(a,null)} +function AOc(a){BOc(a,null);COc(a,null)} +function u4d(){qRd.call(this,null,null)} +function y4d(){RRd.call(this,null,null)} +function a7d(a){this.a=a;Lqb.call(this)} +function Pp(a){this.b=(mmb(),new iob(a))} +function Py(a){a.j=KC(VI,nie,310,0,0,1)} +function oAd(a,b,c){a.c.Vc(b,BD(c,133))} +function GAd(a,b,c){a.c.ji(b,BD(c,133))} +function JLd(a,b){Uxd(a);a.Gc(BD(b,15))} +function b7d(a,b){return t2d(a.c,a.b,b)} +function Bv(a,b){return new Qv(a.Kc(),b)} +function Lq(a,b){return rr(a.Kc(),b)!=-1} +function Sqb(a,b){return a.a.Bc(b)!=null} +function pr(a){return a.Ob()?a.Pb():null} +function yfb(a){return zfb(a,0,a.length)} +function JD(a,b){return a!=null&&AD(a,b)} +function $A(a,b){a.q.setHours(b);YA(a,b)} +function Yrb(a,b){if(a.c){jsb(b);isb(b)}} +function nk(a,b,c){BD(a.Kb(c),164).Nb(b)} +function RJc(a,b,c){SJc(a,b,c);return c} +function Eub(a,b,c){a.a=b^1502;a.b=c^kke} +function xHb(a,b,c){return a.a[b.g][c.g]} +function REc(a,b){return a.a[b.c.p][b.p]} +function aEc(a,b){return a.e[b.c.p][b.p]} +function tEc(a,b){return a.c[b.c.p][b.p]} +function OJc(a,b){return a.j[b.p]=aKc(b)} +function k5c(a,b){return cfb(a.f,b.tg())} +function Isd(a,b){return cfb(a.b,b.tg())} +function Sfd(a,b){return a.a<Kcb(b)?-1:1} +function ZDc(a,b,c){return c?b!=0:b!=a-1} +function _6c(a,b,c){a.a=b;a.b=c;return a} +function Y6c(a,b){a.a*=b;a.b*=b;return a} +function mud(a,b,c){NC(a.g,b,c);return c} +function CHb(a,b,c,d){NC(a.a[b.g],c.g,d)} +function EQb(a,b){O6c(b,a.a.a.a,a.a.a.b)} +function Ozd(a){a.a=BD(Ajd(a.b.a,4),126)} +function Wzd(a){a.a=BD(Ajd(a.b.a,4),126)} +function otd(a){ytb(a,hue);Rld(a,gtd(a))} +function Atb(){Atb=ccb;ztb=new Ftb(null)} +function Ivb(){Ivb=ccb;Ivb();Hvb=new Ovb} +function FId(){this.Bb|=256;this.Bb|=512} +function Fyd(a){this.i=a;this.f=this.i.j} +function xMd(a,b,c){pMd.call(this,a,b,c)} +function BMd(a,b,c){xMd.call(this,a,b,c)} +function K4d(a,b,c){xMd.call(this,a,b,c)} +function N4d(a,b,c){BMd.call(this,a,b,c)} +function X4d(a,b,c){pMd.call(this,a,b,c)} +function _4d(a,b,c){pMd.call(this,a,b,c)} +function C4d(a,b,c){k2d.call(this,a,b,c)} +function G4d(a,b,c){k2d.call(this,a,b,c)} +function I4d(a,b,c){C4d.call(this,a,b,c)} +function c5d(a,b,c){X4d.call(this,a,b,c)} +function zf(a,b){this.a=a;rf.call(this,b)} +function aj(a,b){this.a=a;pc.call(this,b)} +function kj(a,b){this.a=a;pc.call(this,b)} +function Jj(a,b){this.a=a;pc.call(this,b)} +function Rj(a){this.a=a;sj.call(this,a.d)} +function she(a){this.c=a;this.a=this.c.a} +function xl(a,b){this.a=b;pc.call(this,a)} +function Qo(a,b){this.a=b;Lo.call(this,a)} +function op(a,b){this.a=a;Lo.call(this,b)} +function rj(a,b){return Rl(Xm(a.c)).Xb(b)} +function Eb(a,b){return Db(a,new Ufb,b).a} +function ur(a,b){Qb(b);return new Gr(a,b)} +function Gr(a,b){this.a=b;Br.call(this,a)} +function Hs(a){this.b=a;this.a=this.b.a.e} +function Eg(a){a.b.Qb();--a.d.f.d;bg(a.d)} +function Uk(a){Fk.call(this,BD(Qb(a),35))} +function il(a){Fk.call(this,BD(Qb(a),35))} +function is(){$r.call(this,'INSTANCE',0)} +function Lb(a){if(!a){throw vbb(new Vdb)}} +function Ub(a){if(!a){throw vbb(new Ydb)}} +function ot(a){if(!a){throw vbb(new utb)}} +function I6d(){I6d=ccb;g5d();H6d=new J6d} +function Bcb(){Bcb=ccb;zcb=false;Acb=true} +function Jfb(a){mcb.call(this,(uCb(a),a))} +function Wfb(a){mcb.call(this,(uCb(a),a))} +function Inb(a){lnb.call(this,a);this.a=a} +function Xnb(a){Dnb.call(this,a);this.a=a} +function Zob(a){zob.call(this,a);this.a=a} +function Xy(){Py(this);Ry(this);this._d()} +function Qv(a,b){this.a=b;Br.call(this,a)} +function au(a,b){return new xu(a.a,a.b,b)} +function kfb(a,b){return a.lastIndexOf(b)} +function ifb(a,b,c){return a.indexOf(b,c)} +function xfb(a){return a==null?Xhe:fcb(a)} +function nz(a){return a==null?null:a.name} +function Etb(a){return a.a!=null?a.a:null} +function or(a){return Wsb(a.a)?nr(a):null} +function Fxb(a,b){return Jwb(a.a,b)!=null} +function uqb(a,b){return !!b&&a.b[b.g]==b} +function FCb(a){return a.$H||(a.$H=++ECb)} +function aD(a){return a.l+a.m*Hje+a.h*Ije} +function pDb(a,b){Ekb(b.a,a.a);return a.a} +function vDb(a,b){Ekb(b.b,a.a);return a.a} +function nGb(a,b){Ekb(b.a,a.a);return a.a} +function Btb(a){sCb(a.a!=null);return a.a} +function Asb(a){Wqb.call(this,new _rb(a))} +function GUb(a,b){HUb.call(this,a,b,null)} +function cxb(a){this.a=a;Bjb.call(this,a)} +function CKb(){CKb=ccb;BKb=new Msd(tle,0)} +function NFb(a,b){++a.b;return Ekb(a.a,b)} +function OFb(a,b){++a.b;return Lkb(a.a,b)} +function n6b(a,b){return Kdb(a.n.a,b.n.a)} +function WKb(a,b){return Kdb(a.c.d,b.c.d)} +function gLb(a,b){return Kdb(a.c.c,b.c.c)} +function zXb(a,b){return BD(Qc(a.b,b),15)} +function s7b(a,b){return a.n.b=(uCb(b),b)} +function t7b(a,b){return a.n.b=(uCb(b),b)} +function a1b(a){return llb(a.a)||llb(a.b)} +function fBc(a,b,c){return gBc(a,b,c,a.b)} +function iBc(a,b,c){return gBc(a,b,c,a.c)} +function i3c(a,b,c){BD(B2c(a,b),21).Fc(c)} +function xBd(a,b,c){vAd(a.a,c);uAd(a.a,b)} +function qRd(a,b){nRd();this.a=a;this.b=b} +function RRd(a,b){LRd();this.b=a;this.c=b} +function hhd(a,b){Rgd();this.f=b;this.d=a} +function qc(a,b){Sb(b,a);this.d=a;this.c=b} +function n5b(a){var b;b=a.a;a.a=a.b;a.b=b} +function chc(a){Hgc();return !!a&&!a.dc()} +function Afe(a){++vfe;return new lge(3,a)} +function jm(a,b){return new Vp(a,a.gc(),b)} +function ns(a){hs();return es((qs(),ps),a)} +function Oyd(a){this.d=a;Fyd.call(this,a)} +function $yd(a){this.c=a;Fyd.call(this,a)} +function bzd(a){this.c=a;Oyd.call(this,a)} +function sgc(){qgc();this.b=new ygc(this)} +function Pu(a){Xj(a,Jie);return new Skb(a)} +function Vz(a){Rz();return parseInt(a)||-1} +function qfb(a,b,c){return a.substr(b,c-b)} +function gfb(a,b,c){return ifb(a,wfb(b),c)} +function Pkb(a){return ZBb(a.c,a.c.length)} +function Yr(a){return a.f!=null?a.f:''+a.g} +function Zr(a){return a.f!=null?a.f:''+a.g} +function Hsb(a){sCb(a.b!=0);return a.a.a.c} +function Isb(a){sCb(a.b!=0);return a.c.b.c} +function Cmd(a){JD(a,150)&&BD(a,150).Gh()} +function Wwb(a){return a.b=BD(tib(a.a),42)} +function Ptb(a){Ltb();this.b=a;this.a=true} +function Xtb(a){Utb();this.b=a;this.a=true} +function Trb(a){a.d=new ksb(a);a.e=new Lqb} +function mkb(a){if(!a){throw vbb(new Apb)}} +function lCb(a){if(!a){throw vbb(new Vdb)}} +function yCb(a){if(!a){throw vbb(new Ydb)}} +function qCb(a){if(!a){throw vbb(new tcb)}} +function sCb(a){if(!a){throw vbb(new utb)}} +function ksb(a){lsb.call(this,a,null,null)} +function dPb(){$r.call(this,'POLYOMINO',0)} +function Cg(a,b,c,d){qg.call(this,a,b,c,d)} +function zkc(a,b){gkc();return Rc(a,b.e,b)} +function azc(a,b,c){Vyc();return c.qg(a,b)} +function wNb(a,b){return !!a.q&&Mhb(a.q,b)} +function JRb(a,b){return a>0?b*b/a:b*b*100} +function CRb(a,b){return a>0?b/(a*a):b*100} +function G2c(a,b,c){return Ekb(b,I2c(a,c))} +function t3c(a,b,c){p3c();a.Xe(b)&&c.td(a)} +function St(a,b,c){var d;d=a.Zc(b);d.Rb(c)} +function O6c(a,b,c){a.a+=b;a.b+=c;return a} +function Z6c(a,b,c){a.a*=b;a.b*=c;return a} +function b7c(a,b,c){a.a-=b;a.b-=c;return a} +function a7c(a,b){a.a=b.a;a.b=b.b;return a} +function V6c(a){a.a=-a.a;a.b=-a.b;return a} +function Dic(a){this.c=a;this.a=1;this.b=1} +function xed(a){this.c=a;dld(a,0);eld(a,0)} +function u7c(a){Psb.call(this);n7c(this,a)} +function AXb(a){xXb();yXb(this);this.mf(a)} +function GRd(a,b){nRd();qRd.call(this,a,b)} +function dSd(a,b){LRd();RRd.call(this,a,b)} +function hSd(a,b){LRd();RRd.call(this,a,b)} +function fSd(a,b){LRd();dSd.call(this,a,b)} +function sId(a,b,c){dId.call(this,a,b,c,2)} +function zXd(a,b){UVd();nXd.call(this,a,b)} +function BXd(a,b){UVd();zXd.call(this,a,b)} +function DXd(a,b){UVd();zXd.call(this,a,b)} +function FXd(a,b){UVd();DXd.call(this,a,b)} +function PXd(a,b){UVd();nXd.call(this,a,b)} +function RXd(a,b){UVd();PXd.call(this,a,b)} +function XXd(a,b){UVd();nXd.call(this,a,b)} +function pAd(a,b){return a.c.Fc(BD(b,133))} +function w1d(a,b,c){return V1d(p1d(a,b),c)} +function N2d(a,b,c){return b.Qk(a.e,a.c,c)} +function P2d(a,b,c){return b.Rk(a.e,a.c,c)} +function a3d(a,b){return xid(a.e,BD(b,49))} +function aTd(a,b,c){vtd(QSd(a.a),b,eTd(c))} +function TOd(a,b,c){vtd(VKd(a.a),b,XOd(c))} +function ypb(a,b){b.$modCount=a.$modCount} +function MUc(){MUc=ccb;LUc=new Lsd('root')} +function LCd(){LCd=ccb;KCd=new lDd;new NDd} +function KVc(){this.a=new Hp;this.b=new Hp} +function FUd(){hJd.call(this);this.Bb|=Tje} +function t_c(){$r.call(this,'GROW_TREE',0)} +function C9d(a){return a==null?null:cde(a)} +function G9d(a){return a==null?null:jde(a)} +function J9d(a){return a==null?null:fcb(a)} +function K9d(a){return a==null?null:fcb(a)} +function fdb(a){if(a.o!=null){return}vdb(a)} +function DD(a){CCb(a==null||KD(a));return a} +function ED(a){CCb(a==null||LD(a));return a} +function GD(a){CCb(a==null||ND(a));return a} +function gB(a){this.q=new $wnd.Date(Sbb(a))} +function Mf(a,b){this.c=a;ne.call(this,a,b)} +function Sf(a,b){this.a=a;Mf.call(this,a,b)} +function Hg(a,b){this.d=a;Dg(this);this.b=b} +function bAb(a,b){Vzb.call(this,a);this.a=b} +function vAb(a,b){Vzb.call(this,a);this.a=b} +function sNb(a){pNb.call(this,0,0);this.f=a} +function Vg(a,b,c){dg.call(this,a,b,c,null)} +function Yg(a,b,c){dg.call(this,a,b,c,null)} +function Pxb(a,b,c){return a.ue(b,c)<=0?c:b} +function Qxb(a,b,c){return a.ue(b,c)<=0?b:c} +function g4c(a,b){return BD(Wrb(a.b,b),149)} +function i4c(a,b){return BD(Wrb(a.c,b),229)} +function wic(a){return BD(Ikb(a.a,a.b),287)} +function B6c(a){return new f7c(a.c,a.d+a.a)} +function eLc(a){return FJc(),Jzc(BD(a,197))} +function $Jb(){$Jb=ccb;ZJb=pqb((tdd(),sdd))} +function fOb(a,b){b.a?gOb(a,b):Fxb(a.a,b.b)} +function qyb(a,b){if(lyb){return}Ekb(a.a,b)} +function F2b(a,b){x2b();return f_b(b.d.i,a)} +function _9b(a,b){I9b();return new gac(b,a)} +function _Hb(a,b){ytb(b,lle);a.f=b;return a} +function Kld(a,b,c){c=_hd(a,b,3,c);return c} +function bmd(a,b,c){c=_hd(a,b,6,c);return c} +function kpd(a,b,c){c=_hd(a,b,9,c);return c} +function Cvd(a,b,c){++a.j;a.Ki();Atd(a,b,c)} +function Avd(a,b,c){++a.j;a.Hi(b,a.oi(b,c))} +function bRd(a,b,c){var d;d=a.Zc(b);d.Rb(c)} +function c7d(a,b,c){return C2d(a.c,a.b,b,c)} +function DAd(a,b){return (b&Ohe)%a.d.length} +function Msd(a,b){Lsd.call(this,a);this.a=b} +function uVd(a,b){lVd.call(this,a);this.a=b} +function sYd(a,b){lVd.call(this,a);this.a=b} +function zyd(a,b){this.c=a;zud.call(this,b)} +function YOd(a,b){this.a=a;qOd.call(this,b)} +function fTd(a,b){this.a=a;qOd.call(this,b)} +function Xp(a){this.a=(Xj(a,Jie),new Skb(a))} +function cq(a){this.a=(Xj(a,Jie),new Skb(a))} +function LA(a){!a.a&&(a.a=new VA);return a.a} +function XMb(a){if(a>8){return 0}return a+1} +function Ecb(a,b){Bcb();return a==b?0:a?1:-1} +function Opb(a,b,c){return Npb(a,BD(b,22),c)} +function Bz(a,b,c){return a.apply(b,c);var d} +function Sfb(a,b,c){a.a+=zfb(b,0,c);return a} +function ijb(a,b){var c;c=a.e;a.e=b;return c} +function trb(a,b){var c;c=a[hke];c.call(a,b)} +function urb(a,b){var c;c=a[hke];c.call(a,b)} +function Aib(a,b){a.a.Vc(a.b,b);++a.b;a.c=-1} +function Urb(a){Uhb(a.e);a.d.b=a.d;a.d.a=a.d} +function _f(a){a.b?_f(a.b):a.f.c.zc(a.e,a.d)} +function _Ab(a,b,c){EAb();MBb(a,b.Ce(a.a,c))} +function Bxb(a,b){return Vd(Cwb(a.a,b,true))} +function Cxb(a,b){return Vd(Dwb(a.a,b,true))} +function _Bb(a,b){return eCb(new Array(b),a)} +function HD(a){return String.fromCharCode(a)} +function mz(a){return a==null?null:a.message} +function gRb(){this.a=new Rkb;this.b=new Rkb} +function iTb(){this.a=new MQb;this.b=new tTb} +function tDb(){this.b=new d7c;this.c=new Rkb} +function _Qb(){this.d=new d7c;this.e=new d7c} +function n_b(){this.n=new d7c;this.o=new d7c} +function $Gb(){this.n=new p0b;this.i=new I6c} +function sec(){this.a=new Umc;this.b=new mnc} +function NIc(){this.a=new Rkb;this.d=new Rkb} +function LDc(){this.b=new Tqb;this.a=new Tqb} +function hSc(){this.b=new Lqb;this.a=new Lqb} +function HRc(){this.b=new tRc;this.a=new hRc} +function aHb(){$Gb.call(this);this.a=new d7c} +function Ywb(a){Zwb.call(this,a,(lxb(),hxb))} +function J_b(a,b,c,d){B_b.call(this,a,b,c,d)} +function sqd(a,b,c){c!=null&&kmd(b,Wqd(a,c))} +function tqd(a,b,c){c!=null&&lmd(b,Wqd(a,c))} +function Tod(a,b,c){c=_hd(a,b,11,c);return c} +function P6c(a,b){a.a+=b.a;a.b+=b.b;return a} +function c7c(a,b){a.a-=b.a;a.b-=b.b;return a} +function u7b(a,b){return a.n.a=(uCb(b),b)+10} +function v7b(a,b){return a.n.a=(uCb(b),b)+10} +function dLd(a,b){return b==a||pud(UKd(b),a)} +function PYd(a,b){return Rhb(a.a,b,'')==null} +function E2b(a,b){x2b();return !f_b(b.d.i,a)} +function rjc(a,b){fad(a.f)?sjc(a,b):tjc(a,b)} +function h1d(a,b){var c;c=b.Hh(a.a);return c} +function Cyd(a,b){qcb.call(this,gve+a+mue+b)} +function gUd(a,b,c,d){cUd.call(this,a,b,c,d)} +function Q4d(a,b,c,d){cUd.call(this,a,b,c,d)} +function U4d(a,b,c,d){Q4d.call(this,a,b,c,d)} +function n5d(a,b,c,d){i5d.call(this,a,b,c,d)} +function p5d(a,b,c,d){i5d.call(this,a,b,c,d)} +function v5d(a,b,c,d){i5d.call(this,a,b,c,d)} +function t5d(a,b,c,d){p5d.call(this,a,b,c,d)} +function A5d(a,b,c,d){p5d.call(this,a,b,c,d)} +function y5d(a,b,c,d){v5d.call(this,a,b,c,d)} +function D5d(a,b,c,d){A5d.call(this,a,b,c,d)} +function d6d(a,b,c,d){Y5d.call(this,a,b,c,d)} +function Vp(a,b,c){this.a=a;qc.call(this,b,c)} +function tk(a,b,c){this.c=b;this.b=c;this.a=a} +function ik(a,b,c){return a.d=BD(b.Kb(c),164)} +function j6d(a,b){return a.Aj().Nh().Kh(a,b)} +function h6d(a,b){return a.Aj().Nh().Ih(a,b)} +function Fdb(a,b){return uCb(a),PD(a)===PD(b)} +function dfb(a,b){return uCb(a),PD(a)===PD(b)} +function Dxb(a,b){return Vd(Cwb(a.a,b,false))} +function Exb(a,b){return Vd(Dwb(a.a,b,false))} +function vBb(a,b){return a.b.sd(new yBb(a,b))} +function BBb(a,b){return a.b.sd(new EBb(a,b))} +function HBb(a,b){return a.b.sd(new KBb(a,b))} +function lfb(a,b,c){return a.lastIndexOf(b,c)} +function uTb(a,b,c){return Kdb(a[b.b],a[c.b])} +function RTb(a,b){return yNb(b,(Nyc(),Cwc),a)} +function fmc(a,b){return beb(b.a.d.p,a.a.d.p)} +function emc(a,b){return beb(a.a.d.p,b.a.d.p)} +function _Oc(a,b){return Kdb(a.c-a.s,b.c-b.s)} +function S_b(a){return !a.c?-1:Jkb(a.c.a,a,0)} +function Vxd(a){return a<100?null:new Ixd(a)} +function ecd(a){return a==Zbd||a==_bd||a==$bd} +function zAd(a,b){return JD(b,15)&&Btd(a.c,b)} +function vyb(a,b){if(lyb){return}!!b&&(a.d=b)} +function ujb(a,b){var c;c=b;return !!Awb(a,c)} +function czd(a,b){this.c=a;Pyd.call(this,a,b)} +function fBb(a){this.c=a;nvb.call(this,rie,0)} +function Avb(a,b){Bvb.call(this,a,a.length,b)} +function aId(a,b,c){return BD(a.c,69).lk(b,c)} +function bId(a,b,c){return BD(a.c,69).mk(b,c)} +function O2d(a,b,c){return N2d(a,BD(b,332),c)} +function Q2d(a,b,c){return P2d(a,BD(b,332),c)} +function i3d(a,b,c){return h3d(a,BD(b,332),c)} +function k3d(a,b,c){return j3d(a,BD(b,332),c)} +function tn(a,b){return b==null?null:Hv(a.b,b)} +function Kcb(a){return LD(a)?(uCb(a),a):a.ke()} +function Ldb(a){return !isNaN(a)&&!isFinite(a)} +function Wn(a){Ql();this.a=(mmb(),new zob(a))} +function dIc(a){FHc();this.d=a;this.a=new jkb} +function xqb(a,b,c){this.a=a;this.b=b;this.c=c} +function Nrb(a,b,c){this.a=a;this.b=b;this.c=c} +function $sb(a,b,c){this.d=a;this.b=c;this.a=b} +function Qsb(a){Csb(this);Osb(this);ye(this,a)} +function Tkb(a){Ckb(this);bCb(this.c,0,a.Pc())} +function Xwb(a){uib(a.a);Kwb(a.c,a.b);a.b=null} +function iyb(a){this.a=a;Zfb();Cbb(Date.now())} +function JCb(){JCb=ccb;GCb=new nb;ICb=new nb} +function ntb(){ntb=ccb;ltb=new otb;mtb=new qtb} +function kzd(){kzd=ccb;jzd=KC(SI,Uhe,1,0,5,1)} +function tGd(){tGd=ccb;sGd=KC(SI,Uhe,1,0,5,1)} +function $Gd(){$Gd=ccb;ZGd=KC(SI,Uhe,1,0,5,1)} +function Ql(){Ql=ccb;new Zl((mmb(),mmb(),jmb))} +function pxb(a){lxb();return es((zxb(),yxb),a)} +function Hyb(a){Fyb();return es((Kyb(),Jyb),a)} +function OEb(a){MEb();return es((REb(),QEb),a)} +function WEb(a){UEb();return es((ZEb(),YEb),a)} +function tFb(a){rFb();return es((wFb(),vFb),a)} +function iHb(a){gHb();return es((lHb(),kHb),a)} +function PHb(a){NHb();return es((SHb(),RHb),a)} +function GIb(a){EIb();return es((JIb(),IIb),a)} +function vJb(a){qJb();return es((yJb(),xJb),a)} +function xLb(a){vLb();return es((ALb(),zLb),a)} +function TMb(a){RMb();return es((WMb(),VMb),a)} +function TOb(a){ROb();return es((WOb(),VOb),a)} +function ePb(a){cPb();return es((hPb(),gPb),a)} +function ZRb(a){XRb();return es((aSb(),_Rb),a)} +function ATb(a){yTb();return es((DTb(),CTb),a)} +function sUb(a){qUb();return es((vUb(),uUb),a)} +function rWb(a){lWb();return es((uWb(),tWb),a)} +function TXb(a){RXb();return es((WXb(),VXb),a)} +function Mb(a,b){if(!a){throw vbb(new Wdb(b))}} +function l0b(a){j0b();return es((o0b(),n0b),a)} +function r0b(a){B_b.call(this,a.d,a.c,a.a,a.b)} +function K_b(a){B_b.call(this,a.d,a.c,a.a,a.b)} +function mKb(a,b,c){this.b=a;this.c=b;this.a=c} +function BZb(a,b,c){this.b=a;this.a=b;this.c=c} +function TNb(a,b,c){this.a=a;this.b=b;this.c=c} +function uOb(a,b,c){this.a=a;this.b=b;this.c=c} +function S3b(a,b,c){this.a=a;this.b=b;this.c=c} +function Z6b(a,b,c){this.a=a;this.b=b;this.c=c} +function n9b(a,b,c){this.b=a;this.a=b;this.c=c} +function x$b(a,b,c){this.e=b;this.b=a;this.d=c} +function $Ab(a,b,c){EAb();a.a.Od(b,c);return b} +function LGb(a){var b;b=new KGb;b.e=a;return b} +function iLb(a){var b;b=new fLb;b.b=a;return b} +function D6b(){D6b=ccb;B6b=new M6b;C6b=new P6b} +function Hgc(){Hgc=ccb;Fgc=new ghc;Ggc=new ihc} +function jbc(a){gbc();return es((mbc(),lbc),a)} +function Cjc(a){Ajc();return es((Fjc(),Ejc),a)} +function Clc(a){Alc();return es((Flc(),Elc),a)} +function Cpc(a){Apc();return es((Fpc(),Epc),a)} +function Kpc(a){Ipc();return es((Npc(),Mpc),a)} +function Wpc(a){Rpc();return es((Zpc(),Ypc),a)} +function $jc(a){Xjc();return es((bkc(),akc),a)} +function Hkc(a){Fkc();return es((Kkc(),Jkc),a)} +function dqc(a){bqc();return es((gqc(),fqc),a)} +function rqc(a){mqc();return es((uqc(),tqc),a)} +function zqc(a){xqc();return es((Cqc(),Bqc),a)} +function Iqc(a){Gqc();return es((Lqc(),Kqc),a)} +function Vqc(a){Sqc();return es((Yqc(),Xqc),a)} +function brc(a){_qc();return es((erc(),drc),a)} +function nrc(a){lrc();return es((qrc(),prc),a)} +function Arc(a){yrc();return es((Drc(),Crc),a)} +function Qrc(a){Orc();return es((Trc(),Src),a)} +function Zrc(a){Xrc();return es((asc(),_rc),a)} +function gsc(a){esc();return es((jsc(),isc),a)} +function osc(a){msc();return es((rsc(),qsc),a)} +function Etc(a){Ctc();return es((Htc(),Gtc),a)} +function qzc(a){lzc();return es((tzc(),szc),a)} +function Azc(a){xzc();return es((Dzc(),Czc),a)} +function Mzc(a){Izc();return es((Pzc(),Ozc),a)} +function MAc(a){KAc();return es((PAc(),OAc),a)} +function mAc(a){kAc();return es((pAc(),oAc),a)} +function vAc(a){tAc();return es((yAc(),xAc),a)} +function DAc(a){BAc();return es((GAc(),FAc),a)} +function VAc(a){TAc();return es((YAc(),XAc),a)} +function $zc(a){Vzc();return es((bAc(),aAc),a)} +function bBc(a){_Ac();return es((eBc(),dBc),a)} +function vBc(a){tBc();return es((yBc(),xBc),a)} +function EBc(a){CBc();return es((HBc(),GBc),a)} +function NBc(a){LBc();return es((QBc(),PBc),a)} +function tGc(a){rGc();return es((wGc(),vGc),a)} +function WIc(a){UIc();return es((ZIc(),YIc),a)} +function $Lc(a){YLc();return es((bMc(),aMc),a)} +function gMc(a){eMc();return es((jMc(),iMc),a)} +function JOc(a){HOc();return es((MOc(),LOc),a)} +function HQc(a){FQc();return es((KQc(),JQc),a)} +function DRc(a){yRc();return es((GRc(),FRc),a)} +function tSc(a){qSc();return es((wSc(),vSc),a)} +function UTc(a){STc();return es((XTc(),WTc),a)} +function UUc(a){PUc();return es((XUc(),WUc),a)} +function aUc(a){$Tc();return es((dUc(),cUc),a)} +function wVc(a){tVc();return es((zVc(),yVc),a)} +function iWc(a){fWc();return es((lWc(),kWc),a)} +function sWc(a){pWc();return es((vWc(),uWc),a)} +function lXc(a){iXc();return es((oXc(),nXc),a)} +function vXc(a){sXc();return es((yXc(),xXc),a)} +function BYc(a){zYc();return es((EYc(),DYc),a)} +function m$c(a){k$c();return es((p$c(),o$c),a)} +function $$c(a){Y$c();return es((b_c(),a_c),a)} +function n_c(a){i_c();return es((q_c(),p_c),a)} +function w_c(a){s_c();return es((z_c(),y_c),a)} +function E_c(a){C_c();return es((H_c(),G_c),a)} +function P_c(a){N_c();return es((S_c(),R_c),a)} +function W0c(a){R0c();return es((Z0c(),Y0c),a)} +function f1c(a){a1c();return es((i1c(),h1c),a)} +function P5c(a){N5c();return es((S5c(),R5c),a)} +function b6c(a){_5c();return es((e6c(),d6c),a)} +function H7c(a){F7c();return es((K7c(),J7c),a)} +function k8c(a){i8c();return es((n8c(),m8c),a)} +function V8b(a){S8b();return es((Y8b(),X8b),a)} +function A5b(a){y5b();return es((D5b(),C5b),a)} +function jad(a){ead();return es((mad(),lad),a)} +function sad(a){qad();return es((vad(),uad),a)} +function Cad(a){Aad();return es((Fad(),Ead),a)} +function Oad(a){Mad();return es((Rad(),Qad),a)} +function jbd(a){hbd();return es((mbd(),lbd),a)} +function ubd(a){rbd();return es((xbd(),wbd),a)} +function Kbd(a){Hbd();return es((Nbd(),Mbd),a)} +function Vbd(a){Tbd();return es((Ybd(),Xbd),a)} +function hcd(a){dcd();return es((kcd(),jcd),a)} +function vcd(a){rcd();return es((ycd(),xcd),a)} +function vdd(a){tdd();return es((ydd(),xdd),a)} +function Kdd(a){Idd();return es((Ndd(),Mdd),a)} +function $cd(a){Ucd();return es((cdd(),bdd),a)} +function Fed(a){Ded();return es((Ied(),Hed),a)} +function rgd(a){pgd();return es((ugd(),tgd),a)} +function Esd(a){Csd();return es((Hsd(),Gsd),a)} +function Yoc(a,b){return (uCb(a),a)+(uCb(b),b)} +function NNd(a,b){Zfb();return wtd(ZKd(a.a),b)} +function SNd(a,b){Zfb();return wtd(ZKd(a.a),b)} +function bPc(a,b){this.c=a;this.a=b;this.b=b-a} +function nYc(a,b,c){this.a=a;this.b=b;this.c=c} +function L1c(a,b,c){this.a=a;this.b=b;this.c=c} +function T1c(a,b,c){this.a=a;this.b=b;this.c=c} +function Rrd(a,b,c){this.a=a;this.b=b;this.c=c} +function zCd(a,b,c){this.a=a;this.b=b;this.c=c} +function IVd(a,b,c){this.e=a;this.a=b;this.c=c} +function kWd(a,b,c){UVd();cWd.call(this,a,b,c)} +function HXd(a,b,c){UVd();oXd.call(this,a,b,c)} +function TXd(a,b,c){UVd();oXd.call(this,a,b,c)} +function ZXd(a,b,c){UVd();oXd.call(this,a,b,c)} +function JXd(a,b,c){UVd();HXd.call(this,a,b,c)} +function LXd(a,b,c){UVd();HXd.call(this,a,b,c)} +function NXd(a,b,c){UVd();LXd.call(this,a,b,c)} +function VXd(a,b,c){UVd();TXd.call(this,a,b,c)} +function _Xd(a,b,c){UVd();ZXd.call(this,a,b,c)} +function $j(a,b){Qb(a);Qb(b);return new _j(a,b)} +function Nq(a,b){Qb(a);Qb(b);return new Wq(a,b)} +function Rq(a,b){Qb(a);Qb(b);return new ar(a,b)} +function lr(a,b){Qb(a);Qb(b);return new zr(a,b)} +function BD(a,b){CCb(a==null||AD(a,b));return a} +function Nu(a){var b;b=new Rkb;fr(b,a);return b} +function Ex(a){var b;b=new Tqb;fr(b,a);return b} +function Hx(a){var b;b=new Gxb;Jq(b,a);return b} +function Ru(a){var b;b=new Psb;Jq(b,a);return b} +function YEc(a){!a.e&&(a.e=new Rkb);return a.e} +function SMd(a){!a.c&&(a.c=new xYd);return a.c} +function Ekb(a,b){a.c[a.c.length]=b;return true} +function WA(a,b){this.c=a;this.b=b;this.a=false} +function Gg(a){this.d=a;Dg(this);this.b=ed(a.d)} +function pzb(){this.a=';,;';this.b='';this.c=''} +function Bvb(a,b,c){qvb.call(this,b,c);this.a=a} +function fAb(a,b,c){this.b=a;fvb.call(this,b,c)} +function lsb(a,b,c){this.c=a;pjb.call(this,b,c)} +function bCb(a,b,c){$Bb(c,0,a,b,c.length,false)} +function HVb(a,b,c,d,e){a.b=b;a.c=c;a.d=d;a.a=e} +function eBb(a,b){if(b){a.b=b;a.a=(Tzb(b),b.a)}} +function v_b(a,b,c,d,e){a.d=b;a.c=c;a.a=d;a.b=e} +function h5b(a){var b,c;b=a.b;c=a.c;a.b=c;a.c=b} +function k5b(a){var b,c;c=a.d;b=a.a;a.d=b;a.a=c} +function Lbb(a){return zbb(iD(Fbb(a)?Rbb(a):a))} +function rlc(a,b){return beb(D0b(a.d),D0b(b.d))} +function uic(a,b){return b==(Ucd(),Tcd)?a.c:a.d} +function FHc(){FHc=ccb;DHc=(Ucd(),Tcd);EHc=zcd} +function DRb(){this.b=Edb(ED(Ksd((wSb(),vSb))))} +function aBb(a){return EAb(),KC(SI,Uhe,1,a,5,1)} +function C6c(a){return new f7c(a.c+a.b,a.d+a.a)} +function Vmc(a,b){Imc();return beb(a.d.p,b.d.p)} +function Lsb(a){sCb(a.b!=0);return Nsb(a,a.a.a)} +function Msb(a){sCb(a.b!=0);return Nsb(a,a.c.b)} +function rCb(a,b){if(!a){throw vbb(new ucb(b))}} +function mCb(a,b){if(!a){throw vbb(new Wdb(b))}} +function dWb(a,b,c){cWb.call(this,a,b);this.b=c} +function pMd(a,b,c){MLd.call(this,a,b);this.c=c} +function Dnc(a,b,c){Cnc.call(this,b,c);this.d=a} +function _Gd(a){$Gd();MGd.call(this);this.th(a)} +function PNd(a,b,c){this.a=a;nNd.call(this,b,c)} +function UNd(a,b,c){this.a=a;nNd.call(this,b,c)} +function k2d(a,b,c){MLd.call(this,a,b);this.c=c} +function y1d(){T0d();z1d.call(this,(yFd(),xFd))} +function gFd(a){return a!=null&&!OEd(a,CEd,DEd)} +function dFd(a,b){return (jFd(a)<<4|jFd(b))&aje} +function ln(a,b){return Vm(),Wj(a,b),new iy(a,b)} +function Sdd(a,b){var c;if(a.n){c=b;Ekb(a.f,c)}} +function Upd(a,b,c){var d;d=new yC(c);cC(a,b,d)} +function WUd(a,b){var c;c=a.c;VUd(a,b);return c} +function Ydd(a,b){b<0?(a.g=-1):(a.g=b);return a} +function $6c(a,b){W6c(a);a.a*=b;a.b*=b;return a} +function G6c(a,b,c,d,e){a.c=b;a.d=c;a.b=d;a.a=e} +function Dsb(a,b){Gsb(a,b,a.c.b,a.c);return true} +function jsb(a){a.a.b=a.b;a.b.a=a.a;a.a=a.b=null} +function Aq(a){this.b=a;this.a=Wm(this.b.a).Ed()} +function Wq(a,b){this.b=a;this.a=b;ol.call(this)} +function ar(a,b){this.a=a;this.b=b;ol.call(this)} +function vvb(a,b){qvb.call(this,b,1040);this.a=a} +function Eeb(a){return a==0||isNaN(a)?a:a<0?-1:1} +function WPb(a){QPb();return jtd(a)==Xod(ltd(a))} +function XPb(a){QPb();return ltd(a)==Xod(jtd(a))} +function iYb(a,b){return hYb(a,new cWb(b.a,b.b))} +function NZb(a){return !OZb(a)&&a.c.i.c==a.d.i.c} +function _Gb(a){var b;b=a.n;return a.a.b+b.d+b.a} +function YHb(a){var b;b=a.n;return a.e.b+b.d+b.a} +function ZHb(a){var b;b=a.n;return a.e.a+b.b+b.c} +function zfe(a){wfe();++vfe;return new ige(0,a)} +function o_b(a){if(a.a){return a.a}return JZb(a)} +function CCb(a){if(!a){throw vbb(new Cdb(null))}} +function X6d(){X6d=ccb;W6d=(mmb(),new anb(Fwe))} +function ex(){ex=ccb;new gx((_k(),$k),(Lk(),Kk))} +function oeb(){oeb=ccb;neb=KC(JI,nie,19,256,0,1)} +function d$c(a,b,c,d){e$c.call(this,a,b,c,d,0,0)} +function sQc(a,b,c){return Rhb(a.b,BD(c.b,17),b)} +function tQc(a,b,c){return Rhb(a.b,BD(c.b,17),b)} +function xfd(a,b){return Ekb(a,new f7c(b.a,b.b))} +function Bic(a,b){return a.c<b.c?-1:a.c==b.c?0:1} +function B0b(a){return a.e.c.length+a.g.c.length} +function D0b(a){return a.e.c.length-a.g.c.length} +function Ojc(a){return a.b.c.length-a.e.c.length} +function dKc(a){FJc();return (Ucd(),Ecd).Hc(a.j)} +function lHd(a){$Gd();_Gd.call(this,a);this.a=-1} +function R7d(a,b){f7d.call(this,a,b);this.a=this} +function odb(a,b){var c;c=ldb(a,b);c.i=2;return c} +function Evd(a,b){var c;++a.j;c=a.Ti(b);return c} +function e3c(a,b,c){a.a=-1;i3c(a,b.g,c);return a} +function Qrd(a,b,c){Kqd(a.a,a.b,a.c,BD(b,202),c)} +function OHd(a,b){PHd(a,b==null?null:(uCb(b),b))} +function SUd(a,b){UUd(a,b==null?null:(uCb(b),b))} +function TUd(a,b){UUd(a,b==null?null:(uCb(b),b))} +function Zj(a,b,c){return new tk(oAb(a).Ie(),c,b)} +function IC(a,b,c,d,e,f){return JC(a,b,c,d,e,0,f)} +function Ucb(){Ucb=ccb;Tcb=KC(xI,nie,217,256,0,1)} +function Ceb(){Ceb=ccb;Beb=KC(MI,nie,162,256,0,1)} +function Yeb(){Yeb=ccb;Xeb=KC(UI,nie,184,256,0,1)} +function ddb(){ddb=ccb;cdb=KC(yI,nie,172,128,0,1)} +function IVb(){HVb(this,false,false,false,false)} +function my(a){im();this.a=(mmb(),new anb(Qb(a)))} +function ir(a){Qb(a);while(a.Ob()){a.Pb();a.Qb()}} +function Tw(a){a.a.cd();BD(a.a.dd(),14).gc();zh()} +function mf(a){this.c=a;this.b=this.c.d.vc().Kc()} +function fqb(a){this.c=a;this.a=new Gqb(this.c.a)} +function Vqb(a){this.a=new Mqb(a.gc());ye(this,a)} +function Bsb(a){Wqb.call(this,new $rb);ye(this,a)} +function Rfb(a,b){a.a+=zfb(b,0,b.length);return a} +function Ikb(a,b){tCb(b,a.c.length);return a.c[b]} +function $lb(a,b){tCb(b,a.a.length);return a.a[b]} +function YAb(a,b){EAb();Vzb.call(this,a);this.a=b} +function Qyb(a,b){return Aeb(wbb(Aeb(a.a).a,b.a))} +function jpb(a,b){return uCb(a),Fcb(a,(uCb(b),b))} +function opb(a,b){return uCb(b),Fcb(b,(uCb(a),a))} +function Oyb(a,b){return NC(b,0,Bzb(b[0],Aeb(1)))} +function Bzb(a,b){return Qyb(BD(a,162),BD(b,162))} +function vic(a){return a.c-BD(Ikb(a.a,a.b),287).b} +function uNb(a){return !a.q?(mmb(),mmb(),kmb):a.q} +function Xi(a){return a.e.Hd().gc()*a.c.Hd().gc()} +function onc(a,b,c){return beb(b.d[a.g],c.d[a.g])} +function YHc(a,b,c){return beb(a.d[b.p],a.d[c.p])} +function ZHc(a,b,c){return beb(a.d[b.p],a.d[c.p])} +function $Hc(a,b,c){return beb(a.d[b.p],a.d[c.p])} +function _Hc(a,b,c){return beb(a.d[b.p],a.d[c.p])} +function q$c(a,b,c){return $wnd.Math.min(c/a,1/b)} +function sEc(a,b){return a?0:$wnd.Math.max(0,b-1)} +function Elb(a,b){var c;for(c=0;c<b;++c){a[c]=-1}} +function bVc(a){var b;b=hVc(a);return !b?a:bVc(b)} +function Voc(a,b){a.a==null&&Toc(a);return a.a[b]} +function qed(a){if(a.c){return a.c.f}return a.e.b} +function red(a){if(a.c){return a.c.g}return a.e.a} +function pFd(a){zud.call(this,a.gc());ytd(this,a)} +function nXd(a,b){UVd();VVd.call(this,b);this.a=a} +function KYd(a,b,c){this.a=a;xMd.call(this,b,c,2)} +function B_b(a,b,c,d){s_b(this);v_b(this,a,b,c,d)} +function ige(a,b){wfe();xfe.call(this,a);this.a=b} +function jgd(a){this.b=new Psb;this.a=a;this.c=-1} +function MOb(){this.d=new f7c(0,0);this.e=new Tqb} +function Nr(a){qc.call(this,0,0);this.a=a;this.b=0} +function ejc(a){this.a=a;this.c=new Lqb;$ic(this)} +function ju(a){if(a.e.c!=a.b){throw vbb(new Apb)}} +function bt(a){if(a.c.e!=a.a){throw vbb(new Apb)}} +function Tbb(a){if(Fbb(a)){return a|0}return pD(a)} +function Bfe(a,b){wfe();++vfe;return new rge(a,b)} +function SEd(a,b){return a==null?b==null:dfb(a,b)} +function TEd(a,b){return a==null?b==null:efb(a,b)} +function Npb(a,b,c){rqb(a.a,b);return Qpb(a,b.g,c)} +function Mlb(a,b,c){oCb(0,b,a.length);Klb(a,0,b,c)} +function Dkb(a,b,c){wCb(b,a.c.length);aCb(a.c,b,c)} +function Dlb(a,b,c){var d;for(d=0;d<b;++d){a[d]=c}} +function qqb(a,b){var c;c=pqb(a);nmb(c,b);return c} +function Oz(a,b){!a&&(a=[]);a[a.length]=b;return a} +function Brb(a,b){return !(a.a.get(b)===undefined)} +function Wyb(a,b){return Nyb(new rzb,new bzb(a),b)} +function Itb(a){return a==null?ztb:new Ftb(uCb(a))} +function tqb(a,b){return JD(b,22)&&uqb(a,BD(b,22))} +function vqb(a,b){return JD(b,22)&&wqb(a,BD(b,22))} +function Aub(a){return Cub(a,26)*ike+Cub(a,27)*jke} +function MC(a){return Array.isArray(a)&&a.im===gcb} +function bg(a){a.b?bg(a.b):a.d.dc()&&a.f.c.Bc(a.e)} +function $Nb(a,b){P6c(a.c,b);a.b.c+=b.a;a.b.d+=b.b} +function ZNb(a,b){$Nb(a,c7c(new f7c(b.a,b.b),a.c))} +function BLb(a,b){this.b=new Psb;this.a=a;this.c=b} +function OVb(){this.b=new $Vb;this.c=new SVb(this)} +function oEb(){this.d=new CEb;this.e=new uEb(this)} +function aCc(){ZBc();this.f=new Psb;this.e=new Psb} +function $Jc(){FJc();this.k=new Lqb;this.d=new Tqb} +function Rgd(){Rgd=ccb;Qgd=new Osd((Y9c(),s9c),0)} +function Mr(){Mr=ccb;Lr=new Nr(KC(SI,Uhe,1,0,5,1))} +function gfc(a,b,c){bfc(c,a,1);Ekb(b,new Tfc(c,a))} +function hfc(a,b,c){cfc(c,a,1);Ekb(b,new dgc(c,a))} +function R$c(a,b,c){return Qqb(a,new aDb(b.a,c.a))} +function ACc(a,b,c){return -beb(a.f[b.p],a.f[c.p])} +function mHb(a,b,c){var d;if(a){d=a.i;d.c=b;d.b=c}} +function nHb(a,b,c){var d;if(a){d=a.i;d.d=b;d.a=c}} +function c3c(a,b,c){a.a=-1;i3c(a,b.g+1,c);return a} +function Dod(a,b,c){c=_hd(a,BD(b,49),7,c);return c} +function JHd(a,b,c){c=_hd(a,BD(b,49),3,c);return c} +function JMd(a,b,c){this.a=a;BMd.call(this,b,c,22)} +function UTd(a,b,c){this.a=a;BMd.call(this,b,c,14)} +function eXd(a,b,c,d){UVd();nWd.call(this,a,b,c,d)} +function lXd(a,b,c,d){UVd();nWd.call(this,a,b,c,d)} +function FNd(a,b){(b.Bb&ote)!=0&&!a.a.o&&(a.a.o=b)} +function MD(a){return a!=null&&OD(a)&&!(a.im===gcb)} +function ID(a){return !Array.isArray(a)&&a.im===gcb} +function ed(a){return JD(a,15)?BD(a,15).Yc():a.Kc()} +function De(a){return a.Qc(KC(SI,Uhe,1,a.gc(),5,1))} +function u1d(a,b){return W1d(p1d(a,b))?b.Qh():null} +function uvd(a){a?Ty(a,(Zfb(),Yfb),''):(Zfb(),Yfb)} +function Sr(a){this.a=(Mr(),Lr);this.d=BD(Qb(a),47)} +function qg(a,b,c,d){this.a=a;dg.call(this,a,b,c,d)} +function Yge(a){Xge();this.a=0;this.b=a-1;this.c=1} +function Yy(a){Py(this);this.g=a;Ry(this);this._d()} +function Wm(a){if(a.c){return a.c}return a.c=a.Id()} +function Xm(a){if(a.d){return a.d}return a.d=a.Jd()} +function Rl(a){var b;b=a.c;return !b?(a.c=a.Dd()):b} +function fe(a){var b;b=a.f;return !b?(a.f=a.Dc()):b} +function Ec(a){var b;b=a.i;return !b?(a.i=a.bc()):b} +function Ffe(a){wfe();++vfe;return new Hge(10,a,0)} +function Ubb(a){if(Fbb(a)){return ''+a}return qD(a)} +function a4d(a){if(a.e.j!=a.d){throw vbb(new Apb)}} +function Nbb(a,b){return zbb(kD(Fbb(a)?Rbb(a):a,b))} +function Obb(a,b){return zbb(lD(Fbb(a)?Rbb(a):a,b))} +function Pbb(a,b){return zbb(mD(Fbb(a)?Rbb(a):a,b))} +function Dcb(a,b){return Ecb((uCb(a),a),(uCb(b),b))} +function Ddb(a,b){return Kdb((uCb(a),a),(uCb(b),b))} +function fx(a,b){return Qb(b),a.a.Ad(b)&&!a.b.Ad(b)} +function dD(a,b){return TC(a.l&b.l,a.m&b.m,a.h&b.h)} +function jD(a,b){return TC(a.l|b.l,a.m|b.m,a.h|b.h)} +function rD(a,b){return TC(a.l^b.l,a.m^b.m,a.h^b.h)} +function QAb(a,b){return TAb(a,(uCb(b),new Rxb(b)))} +function RAb(a,b){return TAb(a,(uCb(b),new Txb(b)))} +function g1b(a){return z0b(),BD(a,11).e.c.length!=0} +function l1b(a){return z0b(),BD(a,11).g.c.length!=0} +function bac(a,b){I9b();return Kdb(b.a.o.a,a.a.o.a)} +function Rnc(a,b,c){return Snc(a,BD(b,11),BD(c,11))} +function koc(a){if(a.e){return poc(a.e)}return null} +function Iub(a){if(!a.d){a.d=a.b.Kc();a.c=a.b.gc()}} +function pBb(a,b,c){if(a.a.Mb(c)){a.b=true;b.td(c)}} +function _vb(a,b){if(a<0||a>=b){throw vbb(new rcb)}} +function Pyb(a,b,c){NC(b,0,Bzb(b[0],c[0]));return b} +function _yc(a,b,c){b.Ye(c,Edb(ED(Ohb(a.b,c)))*a.a)} +function n6c(a,b,c){i6c();return m6c(a,b)&&m6c(a,c)} +function tcd(a){rcd();return !a.Hc(ncd)&&!a.Hc(pcd)} +function D6c(a){return new f7c(a.c+a.b/2,a.d+a.a/2)} +function oOd(a,b){return b.kh()?xid(a.b,BD(b,49)):b} +function bvb(a,b){this.e=a;this.d=(b&64)!=0?b|oie:b} +function qvb(a,b){this.c=0;this.d=a;this.b=b|64|oie} +function gub(a){this.b=new Skb(11);this.a=(ipb(),a)} +function Qwb(a){this.b=null;this.a=(ipb(),!a?fpb:a)} +function nHc(a){this.a=lHc(a.a);this.b=new Tkb(a.b)} +function Pzd(a){this.b=a;Oyd.call(this,a);Ozd(this)} +function Xzd(a){this.b=a;bzd.call(this,a);Wzd(this)} +function jUd(a,b,c){this.a=a;gUd.call(this,b,c,5,6)} +function Y5d(a,b,c,d){this.b=a;xMd.call(this,b,c,d)} +function nSd(a,b,c,d,e){oSd.call(this,a,b,c,d,e,-1)} +function DSd(a,b,c,d,e){ESd.call(this,a,b,c,d,e,-1)} +function cUd(a,b,c,d){xMd.call(this,a,b,c);this.b=d} +function i5d(a,b,c,d){pMd.call(this,a,b,c);this.b=d} +function x0d(a){Wud.call(this,a,false);this.a=false} +function Lj(a,b){this.b=a;sj.call(this,a.b);this.a=b} +function px(a,b){im();ox.call(this,a,Dm(new amb(b)))} +function Cfe(a,b){wfe();++vfe;return new Dge(a,b,0)} +function Efe(a,b){wfe();++vfe;return new Dge(6,a,b)} +function nfb(a,b){return dfb(a.substr(0,b.length),b)} +function Mhb(a,b){return ND(b)?Qhb(a,b):!!irb(a.f,b)} +function Rrb(a,b){uCb(b);while(a.Ob()){b.td(a.Pb())}} +function Vgb(a,b,c){Hgb();this.e=a;this.d=b;this.a=c} +function amc(a,b,c,d){var e;e=a.i;e.i=b;e.a=c;e.b=d} +function xJc(a){var b;b=a;while(b.f){b=b.f}return b} +function fkb(a){var b;b=bkb(a);sCb(b!=null);return b} +function gkb(a){var b;b=ckb(a);sCb(b!=null);return b} +function cv(a,b){var c;c=a.a.gc();Sb(b,c);return c-b} +function Glb(a,b){var c;for(c=0;c<b;++c){a[c]=false}} +function Clb(a,b,c,d){var e;for(e=b;e<c;++e){a[e]=d}} +function ylb(a,b,c,d){oCb(b,c,a.length);Clb(a,b,c,d)} +function Vvb(a,b,c){_vb(c,a.a.c.length);Nkb(a.a,c,b)} +function Lyb(a,b,c){this.c=a;this.a=b;mmb();this.b=c} +function Qpb(a,b,c){var d;d=a.b[b];a.b[b]=c;return d} +function Qqb(a,b){var c;c=a.a.zc(b,a);return c==null} +function zjb(a){if(!a){throw vbb(new utb)}return a.d} +function vCb(a,b){if(a==null){throw vbb(new Heb(b))}} +function Goc(a,b){if(!b){return false}return ye(a,b)} +function K2c(a,b,c){C2c(a,b.g,c);rqb(a.c,b);return a} +function vVb(a){tVb(a,(ead(),aad));a.d=true;return a} +function c2d(a){!a.j&&i2d(a,d1d(a.g,a.b));return a.j} +function nlb(a){yCb(a.b!=-1);Kkb(a.c,a.a=a.b);a.b=-1} +function Uhb(a){a.f=new lrb(a);a.g=new Frb(a);zpb(a)} +function Plb(a){return new YAb(null,Olb(a,a.length))} +function ul(a){return new Sr(new xl(a.a.length,a.a))} +function iD(a){return TC(~a.l&Eje,~a.m&Eje,~a.h&Fje)} +function OD(a){return typeof a===Jhe||typeof a===Nhe} +function D9d(a){return a==Pje?Nwe:a==Qje?'-INF':''+a} +function F9d(a){return a==Pje?Nwe:a==Qje?'-INF':''+a} +function yRb(a,b){return a>0?$wnd.Math.log(a/b):-100} +function ueb(a,b){return ybb(a,b)<0?-1:ybb(a,b)>0?1:0} +function HMb(a,b,c){return IMb(a,BD(b,46),BD(c,167))} +function iq(a,b){return BD(Rl(Wm(a.a)).Xb(b),42).cd()} +function Olb(a,b){return avb(b,a.length),new vvb(a,b)} +function Pyd(a,b){this.d=a;Fyd.call(this,a);this.e=b} +function Lub(a){this.d=(uCb(a),a);this.a=0;this.c=rie} +function rge(a,b){xfe.call(this,1);this.a=a;this.b=b} +function Rzb(a,b){!a.c?Ekb(a.b,b):Rzb(a.c,b);return a} +function uB(a,b,c){var d;d=tB(a,b);vB(a,b,c);return d} +function ZBb(a,b){var c;c=a.slice(0,b);return PC(c,a)} +function Flb(a,b,c){var d;for(d=0;d<b;++d){NC(a,d,c)}} +function ffb(a,b,c,d,e){while(b<c){d[e++]=bfb(a,b++)}} +function hLb(a,b){return Kdb(a.c.c+a.c.b,b.c.c+b.c.b)} +function Axb(a,b){return Iwb(a.a,b,(Bcb(),zcb))==null} +function Vsb(a,b){Gsb(a.d,b,a.b.b,a.b);++a.a;a.c=null} +function d3d(a,b){JLd(a,JD(b,153)?b:BD(b,1937).gl())} +function hkc(a,b){MAb(NAb(a.Oc(),new Rkc),new Tkc(b))} +function kkc(a,b,c,d,e){jkc(a,BD(Qc(b.k,c),15),c,d,e)} +function lOc(a){a.s=NaN;a.c=NaN;mOc(a,a.e);mOc(a,a.j)} +function it(a){a.a=null;a.e=null;Uhb(a.b);a.d=0;++a.c} +function gKc(a){return $wnd.Math.abs(a.d.e-a.e.e)-a.a} +function MAd(a,b,c){return BD(a.c._c(b,BD(c,133)),42)} +function os(){hs();return OC(GC(yG,1),Kie,538,0,[gs])} +function VPb(a){QPb();return Xod(jtd(a))==Xod(ltd(a))} +function aRb(a){_Qb.call(this);this.a=a;Ekb(a.a,this)} +function tPc(a,b){this.d=DPc(a);this.c=b;this.a=0.5*b} +function A6d(){$rb.call(this);this.a=true;this.b=true} +function aLd(a){return (a.i==null&&TKd(a),a.i).length} +function oRd(a){return JD(a,99)&&(BD(a,18).Bb&ote)!=0} +function w2d(a,b){++a.j;t3d(a,a.i,b);v2d(a,BD(b,332))} +function vId(a,b){b=a.nk(null,b);return uId(a,null,b)} +function ytd(a,b){a.hi()&&(b=Dtd(a,b));return a.Wh(b)} +function mdb(a,b,c){var d;d=ldb(a,b);zdb(c,d);return d} +function ldb(a,b){var c;c=new jdb;c.j=a;c.d=b;return c} +function Qb(a){if(a==null){throw vbb(new Geb)}return a} +function Fc(a){var b;b=a.j;return !b?(a.j=new Cw(a)):b} +function Vi(a){var b;b=a.f;return !b?(a.f=new Rj(a)):b} +function ci(a){var b;return b=a.k,!b?(a.k=new th(a)):b} +function Uc(a){var b;return b=a.k,!b?(a.k=new th(a)):b} +function Pc(a){var b;return b=a.g,!b?(a.g=new lh(a)):b} +function Yi(a){var b;return b=a.i,!b?(a.i=new Ci(a)):b} +function qo(a){var b;b=a.d;return !b?(a.d=new ap(a)):b} +function Fb(a){Qb(a);return JD(a,475)?BD(a,475):fcb(a)} +function Ix(a){if(JD(a,607)){return a}return new by(a)} +function qj(a,b){Pb(b,a.c.b.c.gc());return new Fj(a,b)} +function Dfe(a,b,c){wfe();++vfe;return new zge(a,b,c)} +function NC(a,b,c){qCb(c==null||FC(a,c));return a[b]=c} +function bv(a,b){var c;c=a.a.gc();Pb(b,c);return c-1-b} +function Afb(a,b){a.a+=String.fromCharCode(b);return a} +function Kfb(a,b){a.a+=String.fromCharCode(b);return a} +function ovb(a,b){uCb(b);while(a.c<a.d){a.ze(b,a.c++)}} +function Ohb(a,b){return ND(b)?Phb(a,b):Wd(irb(a.f,b))} +function ZPb(a,b){QPb();return a==jtd(b)?ltd(b):jtd(b)} +function isd(a,b){Qpd(a,new yC(b.f!=null?b.f:''+b.g))} +function ksd(a,b){Qpd(a,new yC(b.f!=null?b.f:''+b.g))} +function dVb(a){this.b=new Rkb;this.a=new Rkb;this.c=a} +function H1b(a){this.c=new d7c;this.a=new Rkb;this.b=a} +function pRb(a){_Qb.call(this);this.a=new d7c;this.c=a} +function yC(a){if(a==null){throw vbb(new Geb)}this.a=a} +function HA(a){fA();this.b=new Rkb;this.a=a;sA(this,a)} +function v4c(a){this.c=a;this.a=new Psb;this.b=new Psb} +function GB(){GB=ccb;EB=new HB(false);FB=new HB(true)} +function im(){im=ccb;Ql();hm=new ux((mmb(),mmb(),jmb))} +function yx(){yx=ccb;Ql();xx=new zx((mmb(),mmb(),lmb))} +function NFd(){NFd=ccb;MFd=BZd();!!(jGd(),PFd)&&DZd()} +function aac(a,b){I9b();return BD(Mpb(a,b.d),15).Fc(b)} +function pTb(a,b,c,d){return c==0||(c-d)/c<a.e||b>=a.g} +function NHc(a,b,c){var d;d=THc(a,b,c);return MHc(a,d)} +function Qpd(a,b){var c;c=a.a.length;tB(a,c);vB(a,c,b)} +function gCb(a,b){var c;c=console[a];c.call(console,b)} +function Bvd(a,b){var c;++a.j;c=a.Vi();a.Ii(a.oi(c,b))} +function E1c(a,b,c){BD(b.b,65);Hkb(b.a,new L1c(a,c,b))} +function oXd(a,b,c){VVd.call(this,b);this.a=a;this.b=c} +function Dge(a,b,c){xfe.call(this,a);this.a=b;this.b=c} +function dYd(a,b,c){this.a=a;lVd.call(this,b);this.b=c} +function f0d(a,b,c){this.a=a;mxd.call(this,8,b,null,c)} +function z1d(a){this.a=(uCb(Rve),Rve);this.b=a;new oUd} +function ct(a){this.c=a;this.b=this.c.a;this.a=this.c.e} +function usb(a){this.c=a;this.b=a.a.d.a;ypb(a.a.e,this)} +function uib(a){yCb(a.c!=-1);a.d.$c(a.c);a.b=a.c;a.c=-1} +function U6c(a){return $wnd.Math.sqrt(a.a*a.a+a.b*a.b)} +function Uvb(a,b){return _vb(b,a.a.c.length),Ikb(a.a,b)} +function Hb(a,b){return PD(a)===PD(b)||a!=null&&pb(a,b)} +function oAb(a){if(0>=a){return new yAb}return pAb(a-1)} +function Nfe(a){if(!bfe)return false;return Qhb(bfe,a)} +function Ehe(a){if(a)return a.dc();return !a.Kc().Ob()} +function Q_b(a){if(!a.a&&!!a.c){return a.c.b}return a.a} +function LHd(a){!a.a&&(a.a=new xMd(m5,a,4));return a.a} +function LQd(a){!a.d&&(a.d=new xMd(j5,a,1));return a.d} +function uCb(a){if(a==null){throw vbb(new Geb)}return a} +function Qzb(a){if(!a.c){a.d=true;Szb(a)}else{a.c.He()}} +function Tzb(a){if(!a.c){Uzb(a);a.d=true}else{Tzb(a.c)}} +function Kpb(a){Ae(a.a);a.b=KC(SI,Uhe,1,a.b.length,5,1)} +function qlc(a,b){return beb(b.j.c.length,a.j.c.length)} +function igd(a,b){a.c<0||a.b.b<a.c?Fsb(a.b,b):a.a._e(b)} +function Did(a,b){var c;c=a.Yg(b);c>=0?a.Bh(c):vid(a,b)} +function WHc(a){var b,c;b=a.c.i.c;c=a.d.i.c;return b==c} +function Wwd(a){if(a.p!=4)throw vbb(new Ydb);return a.e} +function Vwd(a){if(a.p!=3)throw vbb(new Ydb);return a.e} +function Ywd(a){if(a.p!=6)throw vbb(new Ydb);return a.f} +function fxd(a){if(a.p!=6)throw vbb(new Ydb);return a.k} +function cxd(a){if(a.p!=3)throw vbb(new Ydb);return a.j} +function dxd(a){if(a.p!=4)throw vbb(new Ydb);return a.j} +function AYd(a){!a.b&&(a.b=new RYd(new NYd));return a.b} +function $1d(a){a.c==-2&&e2d(a,X0d(a.g,a.b));return a.c} +function pdb(a,b){var c;c=ldb('',a);c.n=b;c.i=1;return c} +function MNb(a,b){$Nb(BD(b.b,65),a);Hkb(b.a,new RNb(a))} +function Cnd(a,b){wtd((!a.a&&(a.a=new fTd(a,a)),a.a),b)} +function Qzd(a,b){this.b=a;Pyd.call(this,a,b);Ozd(this)} +function Yzd(a,b){this.b=a;czd.call(this,a,b);Wzd(this)} +function Ms(a,b,c,d){Wo.call(this,a,b);this.d=c;this.a=d} +function $o(a,b,c,d){Wo.call(this,a,c);this.a=b;this.f=d} +function iy(a,b){Pp.call(this,umb(Qb(a),Qb(b)));this.a=b} +function cae(){fod.call(this,Ewe,(p8d(),o8d));$9d(this)} +function AZd(){fod.call(this,_ve,(LFd(),KFd));uZd(this)} +function T0c(){$r.call(this,'DELAUNAY_TRIANGULATION',0)} +function vfb(a){return String.fromCharCode.apply(null,a)} +function Rhb(a,b,c){return ND(b)?Shb(a,b,c):jrb(a.f,b,c)} +function tmb(a){mmb();return !a?(ipb(),ipb(),hpb):a.ve()} +function d2c(a,b,c){Y1c();return c.pg(a,BD(b.cd(),146))} +function ix(a,b){ex();return new gx(new il(a),new Uk(b))} +function Iu(a){Xj(a,Mie);return Oy(wbb(wbb(5,a),a/10|0))} +function Vm(){Vm=ccb;Um=new wx(OC(GC(CK,1),zie,42,0,[]))} +function hob(a){!a.d&&(a.d=new lnb(a.c.Cc()));return a.d} +function eob(a){!a.a&&(a.a=new Gob(a.c.vc()));return a.a} +function gob(a){!a.b&&(a.b=new zob(a.c.ec()));return a.b} +function keb(a,b){while(b-->0){a=a<<1|(a<0?1:0)}return a} +function wtb(a,b){return PD(a)===PD(b)||a!=null&&pb(a,b)} +function Gbc(a,b){return Bcb(),BD(b.b,19).a<a?true:false} +function Hbc(a,b){return Bcb(),BD(b.a,19).a<a?true:false} +function Mpb(a,b){return tqb(a.a,b)?a.b[BD(b,22).g]:null} +function kcb(a,b,c,d){a.a=qfb(a.a,0,b)+(''+d)+pfb(a.a,c)} +function OJb(a,b){a.u.Hc((rcd(),ncd))&&MJb(a,b);QJb(a,b)} +function bfb(a,b){BCb(b,a.length);return a.charCodeAt(b)} +function vtb(){hz.call(this,'There is no more element.')} +function xkb(a){this.d=a;this.a=this.d.b;this.b=this.d.c} +function kEb(a){a.b=false;a.c=false;a.d=false;a.a=false} +function Znd(a,b,c,d){Ynd(a,b,c,false);LPd(a,d);return a} +function h3c(a){a.j.c=KC(SI,Uhe,1,0,5,1);a.a=-1;return a} +function Old(a){!a.c&&(a.c=new y5d(z2,a,5,8));return a.c} +function Nld(a){!a.b&&(a.b=new y5d(z2,a,4,7));return a.b} +function Kkd(a){!a.n&&(a.n=new cUd(D2,a,1,7));return a.n} +function Yod(a){!a.c&&(a.c=new cUd(F2,a,9,9));return a.c} +function a2d(a){a.e==Gwe&&g2d(a,a1d(a.g,a.b));return a.e} +function b2d(a){a.f==Gwe&&h2d(a,b1d(a.g,a.b));return a.f} +function Ah(a){var b;b=a.b;!b&&(a.b=b=new Ph(a));return b} +function Ae(a){var b;for(b=a.Kc();b.Ob();){b.Pb();b.Qb()}} +function Fg(a){ag(a.d);if(a.d.d!=a.c){throw vbb(new Apb)}} +function Xx(a,b){this.b=a;this.c=b;this.a=new Gqb(this.b)} +function Zeb(a,b,c){this.a=Zie;this.d=a;this.b=b;this.c=c} +function Mub(a,b){this.d=(uCb(a),a);this.a=16449;this.c=b} +function nqd(a,b){ctd(a,Edb(Xpd(b,'x')),Edb(Xpd(b,'y')))} +function Aqd(a,b){ctd(a,Edb(Xpd(b,'x')),Edb(Xpd(b,'y')))} +function JAb(a,b){Uzb(a);return new YAb(a,new qBb(b,a.a))} +function NAb(a,b){Uzb(a);return new YAb(a,new IBb(b,a.a))} +function OAb(a,b){Uzb(a);return new bAb(a,new wBb(b,a.a))} +function PAb(a,b){Uzb(a);return new vAb(a,new CBb(b,a.a))} +function Cy(a,b){return new Ay(BD(Qb(a),62),BD(Qb(b),62))} +function PWb(a,b){LWb();return Kdb((uCb(a),a),(uCb(b),b))} +function fPb(){cPb();return OC(GC(GO,1),Kie,481,0,[bPb])} +function o_c(){i_c();return OC(GC(N_,1),Kie,482,0,[h_c])} +function x_c(){s_c();return OC(GC(O_,1),Kie,551,0,[r_c])} +function X0c(){R0c();return OC(GC(W_,1),Kie,530,0,[Q0c])} +function cEc(a){this.a=new Rkb;this.e=KC(WD,nie,48,a,0,2)} +function l$b(a,b,c,d){this.a=a;this.e=b;this.d=c;this.c=d} +function QIc(a,b,c,d){this.a=a;this.c=b;this.b=c;this.d=d} +function rKc(a,b,c,d){this.c=a;this.b=b;this.a=c;this.d=d} +function WKc(a,b,c,d){this.c=a;this.b=b;this.d=c;this.a=d} +function J6c(a,b,c,d){this.c=a;this.d=b;this.b=c;this.a=d} +function gPc(a,b,c,d){this.a=a;this.d=b;this.c=c;this.b=d} +function Blc(a,b,c,d){$r.call(this,a,b);this.a=c;this.b=d} +function Ggd(a,b,c,d){this.a=a;this.c=b;this.d=c;this.b=d} +function pec(a,b,c){Pmc(a.a,c);dmc(c);enc(a.b,c);xmc(b,c)} +function Pid(a,b,c){var d,e;d=QEd(a);e=b.Kh(c,d);return e} +function KPb(a,b){var c,d;c=a/b;d=QD(c);c>d&&++d;return d} +function Nnd(a){var b,c;c=(b=new UQd,b);NQd(c,a);return c} +function Ond(a){var b,c;c=(b=new UQd,b);RQd(c,a);return c} +function hqd(a,b){var c;c=Ohb(a.f,b);Yqd(b,c);return null} +function JZb(a){var b;b=P2b(a);if(b){return b}return null} +function Wod(a){!a.b&&(a.b=new cUd(B2,a,12,3));return a.b} +function YEd(a){return a!=null&&hnb(GEd,a.toLowerCase())} +function ied(a,b){return Kdb(red(a)*qed(a),red(b)*qed(b))} +function jed(a,b){return Kdb(red(a)*qed(a),red(b)*qed(b))} +function wEb(a,b){return Kdb(a.d.c+a.d.b/2,b.d.c+b.d.b/2)} +function UVb(a,b){return Kdb(a.g.c+a.g.b/2,b.g.c+b.g.b/2)} +function pQb(a,b,c){c.a?eld(a,b.b-a.f/2):dld(a,b.a-a.g/2)} +function prd(a,b,c,d){this.a=a;this.b=b;this.c=c;this.d=d} +function ord(a,b,c,d){this.a=a;this.b=b;this.c=c;this.d=d} +function JVd(a,b,c,d){this.e=a;this.a=b;this.c=c;this.d=d} +function ZVd(a,b,c,d){this.a=a;this.c=b;this.d=c;this.b=d} +function cXd(a,b,c,d){UVd();mWd.call(this,b,c,d);this.a=a} +function jXd(a,b,c,d){UVd();mWd.call(this,b,c,d);this.a=a} +function Ng(a,b){this.a=a;Hg.call(this,a,BD(a.d,15).Zc(b))} +function ZBd(a){this.f=a;this.c=this.f.e;a.f>0&&YBd(this)} +function lBb(a,b,c,d){this.b=a;this.c=d;nvb.call(this,b,c)} +function tib(a){sCb(a.b<a.d.gc());return a.d.Xb(a.c=a.b++)} +function Osb(a){a.a.a=a.c;a.c.b=a.a;a.a.b=a.c.a=null;a.b=0} +function u_b(a,b){a.b=b.b;a.c=b.c;a.d=b.d;a.a=b.a;return a} +function Ry(a){if(a.n){a.e!==Sie&&a._d();a.j=null}return a} +function FD(a){CCb(a==null||OD(a)&&!(a.im===gcb));return a} +function p4b(a){this.b=new Rkb;Gkb(this.b,this.b);this.a=a} +function QPb(){QPb=ccb;PPb=new Rkb;OPb=new Lqb;NPb=new Rkb} +function mmb(){mmb=ccb;jmb=new xmb;kmb=new Qmb;lmb=new Ymb} +function ipb(){ipb=ccb;fpb=new kpb;gpb=new kpb;hpb=new ppb} +function ODb(){ODb=ccb;LDb=new JDb;NDb=new oEb;MDb=new fEb} +function MCb(){if(HCb==256){GCb=ICb;ICb=new nb;HCb=0}++HCb} +function nd(a){var b;return b=a.f,!b?(a.f=new ne(a,a.c)):b} +function d2b(a){return Qld(a)&&Ccb(DD(hkd(a,(Nyc(),gxc))))} +function mcc(a,b){return Rc(a,BD(vNb(b,(Nyc(),Nxc)),19),b)} +function POc(a,b){return vPc(a.j,b.s,b.c)+vPc(b.e,a.s,a.c)} +function ooc(a,b){if(!!a.e&&!a.e.a){moc(a.e,b);ooc(a.e,b)}} +function noc(a,b){if(!!a.d&&!a.d.a){moc(a.d,b);noc(a.d,b)}} +function hed(a,b){return -Kdb(red(a)*qed(a),red(b)*qed(b))} +function cgd(a){return BD(a.cd(),146).tg()+':'+fcb(a.dd())} +function Zgc(a){Hgc();var b;b=BD(a.g,10);b.n.a=a.d.c+b.d.b} +function wgc(a,b,c){qgc();return iEb(BD(Ohb(a.e,b),522),c)} +function Y2c(a,b){rb(a);rb(b);return Xr(BD(a,22),BD(b,22))} +function oic(a,b,c){a.i=0;a.e=0;if(b==c){return}kic(a,b,c)} +function pic(a,b,c){a.i=0;a.e=0;if(b==c){return}lic(a,b,c)} +function Spd(a,b,c){var d,e;d=Kcb(c);e=new TB(d);cC(a,b,e)} +function FSd(a,b,c,d,e,f){ESd.call(this,a,b,c,d,e,f?-2:-1)} +function U5d(a,b,c,d){MLd.call(this,b,c);this.b=a;this.a=d} +function QRc(a,b){new Psb;this.a=new s7c;this.b=a;this.c=b} +function Hec(a,b){BD(vNb(a,(wtc(),Qsc)),15).Fc(b);return b} +function Rb(a,b){if(a==null){throw vbb(new Heb(b))}return a} +function WKd(a){!a.q&&(a.q=new cUd(n5,a,11,10));return a.q} +function ZKd(a){!a.s&&(a.s=new cUd(t5,a,21,17));return a.s} +function Vod(a){!a.a&&(a.a=new cUd(E2,a,10,11));return a.a} +function Dx(a){return JD(a,14)?new Vqb(BD(a,14)):Ex(a.Kc())} +function Ni(a){return new aj(a,a.e.Hd().gc()*a.c.Hd().gc())} +function Zi(a){return new kj(a,a.e.Hd().gc()*a.c.Hd().gc())} +function rz(a){return !!a&&!!a.hashCode?a.hashCode():FCb(a)} +function Qhb(a,b){return b==null?!!irb(a.f,null):Brb(a.g,b)} +function Oq(a){Qb(a);return mr(new Sr(ur(a.a.Kc(),new Sq)))} +function vmb(a){mmb();return JD(a,54)?new Yob(a):new Inb(a)} +function VDb(a,b,c){if(a.f){return a.f.Ne(b,c)}return false} +function Gfb(a,b){a.a=qfb(a.a,0,b)+''+pfb(a.a,b+1);return a} +function fVb(a,b){var c;c=Sqb(a.a,b);c&&(b.d=null);return c} +function zpb(a){var b,c;c=a;b=c.$modCount|0;c.$modCount=b+1} +function pu(a){this.b=a;this.c=a;a.e=null;a.c=null;this.a=1} +function hOb(a){this.b=a;this.a=new Hxb(BD(Qb(new kOb),62))} +function uEb(a){this.c=a;this.b=new Hxb(BD(Qb(new xEb),62))} +function SVb(a){this.c=a;this.b=new Hxb(BD(Qb(new VVb),62))} +function FYb(){this.a=new HXb;this.b=new LXb;this.d=new SYb} +function UZb(){this.a=new s7c;this.b=(Xj(3,Jie),new Skb(3))} +function VMc(){this.b=new Tqb;this.d=new Psb;this.e=new twb} +function K6c(a){this.c=a.c;this.d=a.d;this.b=a.b;this.a=a.a} +function Ay(a,b){oi.call(this,new Qwb(a));this.a=a;this.b=b} +function eod(){bod(this,new $md);this.wb=(NFd(),MFd);LFd()} +function eHc(a){Odd(a,'No crossing minimization',1);Qdd(a)} +function Gz(a){Az();$wnd.setTimeout(function(){throw a},0)} +function _Kd(a){if(!a.u){$Kd(a);a.u=new YOd(a,a)}return a.u} +function wjd(a){var b;b=BD(Ajd(a,16),26);return !b?a.zh():b} +function Jsd(a,b){return JD(b,146)&&dfb(a.b,BD(b,146).tg())} +function t0d(a,b){return a.a?b.Wg().Kc():BD(b.Wg(),69).Zh()} +function u3b(a){return a.k==(j0b(),h0b)&&wNb(a,(wtc(),Csc))} +function ux(a){this.a=(mmb(),JD(a,54)?new Yob(a):new Inb(a))} +function Rz(){Rz=ccb;var a,b;b=!Xz();a=new dA;Qz=b?new Yz:a} +function Wy(a,b){var c;c=hdb(a.gm);return b==null?c:c+': '+b} +function Eob(a,b){var c;c=a.b.Qc(b);Fob(c,a.b.gc());return c} +function ytb(a,b){if(a==null){throw vbb(new Heb(b))}return a} +function irb(a,b){return grb(a,b,hrb(a,b==null?0:a.b.se(b)))} +function ofb(a,b,c){return c>=0&&dfb(a.substr(c,b.length),b)} +function H2d(a,b,c,d,e,f,g){return new O7d(a.e,b,c,d,e,f,g)} +function Cxd(a,b,c,d,e,f){this.a=a;nxd.call(this,b,c,d,e,f)} +function vyd(a,b,c,d,e,f){this.a=a;nxd.call(this,b,c,d,e,f)} +function $Ec(a,b){this.g=a;this.d=OC(GC(OQ,1),kne,10,0,[b])} +function KVd(a,b){this.e=a;this.a=SI;this.b=R5d(b);this.c=b} +function cIb(a,b){$Gb.call(this);THb(this);this.a=a;this.c=b} +function kBc(a,b,c,d){NC(a.c[b.g],c.g,d);NC(a.c[c.g],b.g,d)} +function nBc(a,b,c,d){NC(a.c[b.g],b.g,c);NC(a.b[b.g],b.g,d)} +function cBc(){_Ac();return OC(GC(fX,1),Kie,376,0,[$Ac,ZAc])} +function crc(){_qc();return OC(GC(MW,1),Kie,479,0,[$qc,Zqc])} +function Aqc(){xqc();return OC(GC(JW,1),Kie,419,0,[vqc,wqc])} +function Lpc(){Ipc();return OC(GC(FW,1),Kie,422,0,[Gpc,Hpc])} +function psc(){msc();return OC(GC(SW,1),Kie,420,0,[ksc,lsc])} +function EAc(){BAc();return OC(GC(cX,1),Kie,421,0,[zAc,AAc])} +function XIc(){UIc();return OC(GC(mY,1),Kie,523,0,[TIc,SIc])} +function KOc(){HOc();return OC(GC(DZ,1),Kie,520,0,[GOc,FOc])} +function _Lc(){YLc();return OC(GC(fZ,1),Kie,516,0,[XLc,WLc])} +function hMc(){eMc();return OC(GC(gZ,1),Kie,515,0,[cMc,dMc])} +function IQc(){FQc();return OC(GC(YZ,1),Kie,455,0,[DQc,EQc])} +function bUc(){$Tc();return OC(GC(F$,1),Kie,425,0,[ZTc,YTc])} +function VTc(){STc();return OC(GC(E$,1),Kie,480,0,[QTc,RTc])} +function VUc(){PUc();return OC(GC(K$,1),Kie,495,0,[NUc,OUc])} +function jWc(){fWc();return OC(GC(X$,1),Kie,426,0,[dWc,eWc])} +function g1c(){a1c();return OC(GC(X_,1),Kie,429,0,[_0c,$0c])} +function F_c(){C_c();return OC(GC(P_,1),Kie,430,0,[B_c,A_c])} +function PEb(){MEb();return OC(GC(aN,1),Kie,428,0,[LEb,KEb])} +function XEb(){UEb();return OC(GC(bN,1),Kie,427,0,[SEb,TEb])} +function $Rb(){XRb();return OC(GC(gP,1),Kie,424,0,[VRb,WRb])} +function B5b(){y5b();return OC(GC(ZR,1),Kie,511,0,[x5b,w5b])} +function lid(a,b,c,d){return c>=0?a.jh(b,c,d):a.Sg(null,c,d)} +function hgd(a){if(a.b.b==0){return a.a.$e()}return Lsb(a.b)} +function Xwd(a){if(a.p!=5)throw vbb(new Ydb);return Tbb(a.f)} +function exd(a){if(a.p!=5)throw vbb(new Ydb);return Tbb(a.k)} +function pNd(a){PD(a.a)===PD((NKd(),MKd))&&qNd(a);return a.a} +function by(a){this.a=BD(Qb(a),271);this.b=(mmb(),new Zob(a))} +function bQc(a,b){$Pc(this,new f7c(a.a,a.b));_Pc(this,Ru(b))} +function FQc(){FQc=ccb;DQc=new GQc(jle,0);EQc=new GQc(kle,1)} +function YLc(){YLc=ccb;XLc=new ZLc(kle,0);WLc=new ZLc(jle,1)} +function Hp(){Gp.call(this,new Mqb(Cv(12)));Lb(true);this.a=2} +function Hge(a,b,c){wfe();xfe.call(this,a);this.b=b;this.a=c} +function cWd(a,b,c){UVd();VVd.call(this,b);this.a=a;this.b=c} +function aIb(a){$Gb.call(this);THb(this);this.a=a;this.c=true} +function isb(a){var b;b=a.c.d.b;a.b=b;a.a=a.c.d;b.a=a.c.d.b=a} +function $Cb(a){var b;NGb(a.a);MGb(a.a);b=new YGb(a.a);UGb(b)} +function iKb(a,b){hKb(a,true);Hkb(a.e.wf(),new mKb(a,true,b))} +function tlb(a,b){pCb(b);return vlb(a,KC(WD,oje,25,b,15,1),b)} +function YPb(a,b){QPb();return a==Xod(jtd(b))||a==Xod(ltd(b))} +function Phb(a,b){return b==null?Wd(irb(a.f,null)):Crb(a.g,b)} +function Ksb(a){return a.b==0?null:(sCb(a.b!=0),Nsb(a,a.a.a))} +function QD(a){return Math.max(Math.min(a,Ohe),-2147483648)|0} +function uz(a,b){var c=tz[a.charCodeAt(0)];return c==null?a:c} +function Cx(a,b){Rb(a,'set1');Rb(b,'set2');return new Px(a,b)} +function QUb(a,b){var c;c=zUb(a.f,b);return P6c(V6c(c),a.f.d)} +function Jwb(a,b){var c,d;c=b;d=new fxb;Lwb(a,c,d);return d.d} +function NJb(a,b,c,d){var e;e=new aHb;b.a[c.g]=e;Npb(a.b,d,e)} +function zid(a,b,c){var d;d=a.Yg(b);d>=0?a.sh(d,c):uid(a,b,c)} +function hvd(a,b,c){evd();!!a&&Rhb(dvd,a,b);!!a&&Rhb(cvd,a,c)} +function g_c(a,b,c){this.i=new Rkb;this.b=a;this.g=b;this.a=c} +function VZc(a,b,c){this.c=new Rkb;this.e=a;this.f=b;this.b=c} +function b$c(a,b,c){this.a=new Rkb;this.e=a;this.f=b;this.c=c} +function Zy(a,b){Py(this);this.f=b;this.g=a;Ry(this);this._d()} +function ZA(a,b){var c;c=a.q.getHours();a.q.setDate(b);YA(a,c)} +function no(a,b){var c;Qb(b);for(c=a.a;c;c=c.c){b.Od(c.g,c.i)}} +function Fx(a){var b;b=new Uqb(Cv(a.length));nmb(b,a);return b} +function ecb(a){function b(){} +;b.prototype=a||{};return new b} +function dkb(a,b){if(Zjb(a,b)){wkb(a);return true}return false} +function aC(a,b){if(b==null){throw vbb(new Geb)}return bC(a,b)} +function tdb(a){if(a.qe()){return null}var b=a.n;return _bb[b]} +function Mld(a){if(a.Db>>16!=3)return null;return BD(a.Cb,33)} +function mpd(a){if(a.Db>>16!=9)return null;return BD(a.Cb,33)} +function fmd(a){if(a.Db>>16!=6)return null;return BD(a.Cb,79)} +function Ind(a){if(a.Db>>16!=7)return null;return BD(a.Cb,235)} +function Fod(a){if(a.Db>>16!=7)return null;return BD(a.Cb,160)} +function Xod(a){if(a.Db>>16!=11)return null;return BD(a.Cb,33)} +function nid(a,b){var c;c=a.Yg(b);return c>=0?a.lh(c):tid(a,b)} +function Dtd(a,b){var c;c=new Bsb(b);Ve(c,a);return new Tkb(c)} +function Uud(a){var b;b=a.d;b=a.si(a.f);wtd(a,b);return b.Ob()} +function t_b(a,b){a.b+=b.b;a.c+=b.c;a.d+=b.d;a.a+=b.a;return a} +function A4b(a,b){return $wnd.Math.abs(a)<$wnd.Math.abs(b)?a:b} +function Zod(a){return !a.a&&(a.a=new cUd(E2,a,10,11)),a.a.i>0} +function oDb(){this.a=new zsb;this.e=new Tqb;this.g=0;this.i=0} +function BGc(a){this.a=a;this.b=KC(SX,nie,1944,a.e.length,0,2)} +function RHc(a,b,c){var d;d=SHc(a,b,c);a.b=new BHc(d.c.length)} +function eMc(){eMc=ccb;cMc=new fMc(vle,0);dMc=new fMc('UP',1)} +function STc(){STc=ccb;QTc=new TTc(Yqe,0);RTc=new TTc('FAN',1)} +function evd(){evd=ccb;dvd=new Lqb;cvd=new Lqb;ivd(hK,new jvd)} +function Swd(a){if(a.p!=0)throw vbb(new Ydb);return Kbb(a.f,0)} +function _wd(a){if(a.p!=0)throw vbb(new Ydb);return Kbb(a.k,0)} +function MHd(a){if(a.Db>>16!=3)return null;return BD(a.Cb,147)} +function ZJd(a){if(a.Db>>16!=6)return null;return BD(a.Cb,235)} +function WId(a){if(a.Db>>16!=17)return null;return BD(a.Cb,26)} +function rdb(a,b){var c=a.a=a.a||[];return c[b]||(c[b]=a.le(b))} +function hrb(a,b){var c;c=a.a.get(b);return c==null?new Array:c} +function aB(a,b){var c;c=a.q.getHours();a.q.setMonth(b);YA(a,c)} +function Shb(a,b,c){return b==null?jrb(a.f,null,c):Drb(a.g,b,c)} +function FLd(a,b,c,d,e,f){return new pSd(a.e,b,a.aj(),c,d,e,f)} +function Tfb(a,b,c){a.a=qfb(a.a,0,b)+(''+c)+pfb(a.a,b);return a} +function bq(a,b,c){Ekb(a.a,(Vm(),Wj(b,c),new Wo(b,c)));return a} +function uu(a){ot(a.c);a.e=a.a=a.c;a.c=a.c.c;++a.d;return a.a.f} +function vu(a){ot(a.e);a.c=a.a=a.e;a.e=a.e.e;--a.d;return a.a.f} +function RZb(a,b){!!a.d&&Lkb(a.d.e,a);a.d=b;!!a.d&&Ekb(a.d.e,a)} +function QZb(a,b){!!a.c&&Lkb(a.c.g,a);a.c=b;!!a.c&&Ekb(a.c.g,a)} +function $_b(a,b){!!a.c&&Lkb(a.c.a,a);a.c=b;!!a.c&&Ekb(a.c.a,a)} +function F0b(a,b){!!a.i&&Lkb(a.i.j,a);a.i=b;!!a.i&&Ekb(a.i.j,a)} +function jDb(a,b,c){this.a=b;this.c=a;this.b=(Qb(c),new Tkb(c))} +function qXb(a,b,c){this.a=b;this.c=a;this.b=(Qb(c),new Tkb(c))} +function aOb(a,b){this.a=a;this.c=R6c(this.a);this.b=new K6c(b)} +function IAb(a){var b;Uzb(a);b=new Tqb;return JAb(a,new jBb(b))} +function wCb(a,b){if(a<0||a>b){throw vbb(new qcb(Ake+a+Bke+b))}} +function Ppb(a,b){return vqb(a.a,b)?Qpb(a,BD(b,22).g,null):null} +function WUb(a){LUb();return Bcb(),BD(a.a,81).d.e!=0?true:false} +function qs(){qs=ccb;ps=as((hs(),OC(GC(yG,1),Kie,538,0,[gs])))} +function SBc(){SBc=ccb;RBc=c3c(new j3c,(qUb(),pUb),(S8b(),J8b))} +function ZBc(){ZBc=ccb;YBc=c3c(new j3c,(qUb(),pUb),(S8b(),J8b))} +function oCc(){oCc=ccb;nCc=c3c(new j3c,(qUb(),pUb),(S8b(),J8b))} +function aJc(){aJc=ccb;_Ic=e3c(new j3c,(qUb(),pUb),(S8b(),h8b))} +function FJc(){FJc=ccb;EJc=e3c(new j3c,(qUb(),pUb),(S8b(),h8b))} +function ILc(){ILc=ccb;HLc=e3c(new j3c,(qUb(),pUb),(S8b(),h8b))} +function wMc(){wMc=ccb;vMc=e3c(new j3c,(qUb(),pUb),(S8b(),h8b))} +function fUc(){fUc=ccb;eUc=c3c(new j3c,(yRc(),xRc),(qSc(),kSc))} +function DOc(a,b,c,d){this.c=a;this.d=d;BOc(this,b);COc(this,c)} +function W3c(a){this.c=new Psb;this.b=a.b;this.d=a.c;this.a=a.a} +function e7c(a){this.a=$wnd.Math.cos(a);this.b=$wnd.Math.sin(a)} +function BOc(a,b){!!a.a&&Lkb(a.a.k,a);a.a=b;!!a.a&&Ekb(a.a.k,a)} +function COc(a,b){!!a.b&&Lkb(a.b.f,a);a.b=b;!!a.b&&Ekb(a.b.f,a)} +function D1c(a,b){E1c(a,a.b,a.c);BD(a.b.b,65);!!b&&BD(b.b,65).b} +function BUd(a,b){CUd(a,b);JD(a.Cb,88)&&XMd($Kd(BD(a.Cb,88)),2)} +function cJd(a,b){JD(a.Cb,88)&&XMd($Kd(BD(a.Cb,88)),4);pnd(a,b)} +function lKd(a,b){JD(a.Cb,179)&&(BD(a.Cb,179).tb=null);pnd(a,b)} +function T2d(a,b){return Q6d(),YId(b)?new R7d(b,a):new f7d(b,a)} +function jsd(a,b){var c,d;c=b.c;d=c!=null;d&&Qpd(a,new yC(b.c))} +function XOd(a){var b,c;c=(LFd(),b=new UQd,b);NQd(c,a);return c} +function eTd(a){var b,c;c=(LFd(),b=new UQd,b);NQd(c,a);return c} +function yCc(a,b){var c;c=new H1b(a);b.c[b.c.length]=c;return c} +function Aw(a,b){var c;c=BD(Hv(nd(a.a),b),14);return !c?0:c.gc()} +function UAb(a){var b;Uzb(a);b=(ipb(),ipb(),gpb);return VAb(a,b)} +function nr(a){var b;while(true){b=a.Pb();if(!a.Ob()){return b}}} +function Ki(a,b){Ii.call(this,new Mqb(Cv(a)));Xj(b,mie);this.a=b} +function Jib(a,b,c){xCb(b,c,a.gc());this.c=a;this.a=b;this.b=c-b} +function Mkb(a,b,c){var d;xCb(b,c,a.c.length);d=c-b;cCb(a.c,b,d)} +function Fub(a,b){Eub(a,Tbb(xbb(Obb(b,24),nke)),Tbb(xbb(b,nke)))} +function tCb(a,b){if(a<0||a>=b){throw vbb(new qcb(Ake+a+Bke+b))}} +function BCb(a,b){if(a<0||a>=b){throw vbb(new Xfb(Ake+a+Bke+b))}} +function Kub(a,b){this.b=(uCb(a),a);this.a=(b&Rje)==0?b|64|oie:b} +function kkb(a){Vjb(this);dCb(this.a,geb($wnd.Math.max(8,a))<<1)} +function A0b(a){return l7c(OC(GC(m1,1),nie,8,0,[a.i.n,a.n,a.a]))} +function Iyb(){Fyb();return OC(GC(xL,1),Kie,132,0,[Cyb,Dyb,Eyb])} +function jHb(){gHb();return OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb])} +function QHb(){NHb();return OC(GC(sN,1),Kie,461,0,[LHb,KHb,MHb])} +function HIb(){EIb();return OC(GC(zN,1),Kie,462,0,[DIb,CIb,BIb])} +function UXb(){RXb();return OC(GC(hQ,1),Kie,423,0,[QXb,PXb,OXb])} +function BTb(){yTb();return OC(GC(oP,1),Kie,379,0,[wTb,vTb,xTb])} +function Bzc(){xzc();return OC(GC(ZW,1),Kie,378,0,[uzc,vzc,wzc])} +function Xpc(){Rpc();return OC(GC(GW,1),Kie,314,0,[Ppc,Opc,Qpc])} +function eqc(){bqc();return OC(GC(HW,1),Kie,337,0,[$pc,aqc,_pc])} +function Jqc(){Gqc();return OC(GC(KW,1),Kie,450,0,[Eqc,Dqc,Fqc])} +function Ikc(){Fkc();return OC(GC(vV,1),Kie,361,0,[Ekc,Dkc,Ckc])} +function hsc(){esc();return OC(GC(RW,1),Kie,303,0,[csc,dsc,bsc])} +function $rc(){Xrc();return OC(GC(QW,1),Kie,292,0,[Vrc,Wrc,Urc])} +function NAc(){KAc();return OC(GC(dX,1),Kie,452,0,[JAc,HAc,IAc])} +function wAc(){tAc();return OC(GC(bX,1),Kie,339,0,[rAc,qAc,sAc])} +function WAc(){TAc();return OC(GC(eX,1),Kie,375,0,[QAc,RAc,SAc])} +function OBc(){LBc();return OC(GC(jX,1),Kie,377,0,[JBc,KBc,IBc])} +function wBc(){tBc();return OC(GC(hX,1),Kie,336,0,[qBc,rBc,sBc])} +function FBc(){CBc();return OC(GC(iX,1),Kie,338,0,[BBc,zBc,ABc])} +function uGc(){rGc();return OC(GC(PX,1),Kie,454,0,[oGc,pGc,qGc])} +function xVc(){tVc();return OC(GC(O$,1),Kie,442,0,[sVc,qVc,rVc])} +function tWc(){pWc();return OC(GC(Y$,1),Kie,380,0,[mWc,nWc,oWc])} +function CYc(){zYc();return OC(GC(q_,1),Kie,381,0,[xYc,yYc,wYc])} +function wXc(){sXc();return OC(GC(b_,1),Kie,293,0,[qXc,rXc,pXc])} +function _$c(){Y$c();return OC(GC(J_,1),Kie,437,0,[V$c,W$c,X$c])} +function kbd(){hbd();return OC(GC(z1,1),Kie,334,0,[fbd,ebd,gbd])} +function tad(){qad();return OC(GC(u1,1),Kie,272,0,[nad,oad,pad])} +function o3d(a,b){return p3d(a,b,JD(b,99)&&(BD(b,18).Bb&Tje)!=0)} +function LZc(a,b,c){var d;d=MZc(a,b,false);return d.b<=b&&d.a<=c} +function tMc(a,b,c){var d;d=new sMc;d.b=b;d.a=c;++b.b;Ekb(a.d,d)} +function fs(a,b){var c;c=(uCb(a),a).g;lCb(!!c);uCb(b);return c(b)} +function av(a,b){var c,d;d=cv(a,b);c=a.a.Zc(d);return new qv(a,c)} +function cKd(a){if(a.Db>>16!=6)return null;return BD(aid(a),235)} +function Uwd(a){if(a.p!=2)throw vbb(new Ydb);return Tbb(a.f)&aje} +function bxd(a){if(a.p!=2)throw vbb(new Ydb);return Tbb(a.k)&aje} +function Z1d(a){a.a==(T0d(),S0d)&&d2d(a,U0d(a.g,a.b));return a.a} +function _1d(a){a.d==(T0d(),S0d)&&f2d(a,Y0d(a.g,a.b));return a.d} +function mlb(a){sCb(a.a<a.c.c.length);a.b=a.a++;return a.c.c[a.b]} +function hEb(a,b){a.b=a.b|b.b;a.c=a.c|b.c;a.d=a.d|b.d;a.a=a.a|b.a} +function xbb(a,b){return zbb(dD(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b))} +function Mbb(a,b){return zbb(jD(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b))} +function Vbb(a,b){return zbb(rD(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b))} +function Dub(a){return wbb(Nbb(Cbb(Cub(a,32)),32),Cbb(Cub(a,32)))} +function Mu(a){Qb(a);return JD(a,14)?new Tkb(BD(a,14)):Nu(a.Kc())} +function EWb(a,b){AWb();return a.c==b.c?Kdb(b.d,a.d):Kdb(a.c,b.c)} +function FWb(a,b){AWb();return a.c==b.c?Kdb(a.d,b.d):Kdb(a.c,b.c)} +function HWb(a,b){AWb();return a.c==b.c?Kdb(a.d,b.d):Kdb(b.c,a.c)} +function GWb(a,b){AWb();return a.c==b.c?Kdb(b.d,a.d):Kdb(b.c,a.c)} +function WGb(a,b){var c;c=Edb(ED(a.a.We((Y9c(),Q9c))));XGb(a,b,c)} +function Rgc(a,b){var c;c=BD(Ohb(a.g,b),57);Hkb(b.d,new Qhc(a,c))} +function GYb(a,b){var c,d;c=d_b(a);d=d_b(b);return c<d?-1:c>d?1:0} +function bjc(a,b){var c,d;c=ajc(b);d=c;return BD(Ohb(a.c,d),19).a} +function iSc(a,b){var c;c=a+'';while(c.length<b){c='0'+c}return c} +function WRc(a){return a.c==null||a.c.length==0?'n_'+a.g:'n_'+a.c} +function oRb(a){return a.c==null||a.c.length==0?'n_'+a.b:'n_'+a.c} +function qz(a,b){return !!a&&!!a.equals?a.equals(b):PD(a)===PD(b)} +function dkd(a,b){if(b==0){return !!a.o&&a.o.f!=0}return mid(a,b)} +function Tdd(a,b,c){var d;if(a.n&&!!b&&!!c){d=new kgd;Ekb(a.e,d)}} +function cIc(a,b,c){var d;d=a.d[b.p];a.d[b.p]=a.d[c.p];a.d[c.p]=d} +function kxd(a,b,c){this.d=a;this.j=b;this.e=c;this.o=-1;this.p=3} +function lxd(a,b,c){this.d=a;this.k=b;this.f=c;this.o=-1;this.p=5} +function zge(a,b,c){xfe.call(this,25);this.b=a;this.a=b;this.c=c} +function $fe(a){wfe();xfe.call(this,a);this.c=false;this.a=false} +function sSd(a,b,c,d,e,f){rSd.call(this,a,b,c,d,e);f&&(this.o=-2)} +function uSd(a,b,c,d,e,f){tSd.call(this,a,b,c,d,e);f&&(this.o=-2)} +function wSd(a,b,c,d,e,f){vSd.call(this,a,b,c,d,e);f&&(this.o=-2)} +function ySd(a,b,c,d,e,f){xSd.call(this,a,b,c,d,e);f&&(this.o=-2)} +function ASd(a,b,c,d,e,f){zSd.call(this,a,b,c,d,e);f&&(this.o=-2)} +function CSd(a,b,c,d,e,f){BSd.call(this,a,b,c,d,e);f&&(this.o=-2)} +function HSd(a,b,c,d,e,f){GSd.call(this,a,b,c,d,e);f&&(this.o=-2)} +function JSd(a,b,c,d,e,f){ISd.call(this,a,b,c,d,e);f&&(this.o=-2)} +function nWd(a,b,c,d){VVd.call(this,c);this.b=a;this.c=b;this.d=d} +function x$c(a,b){this.a=new Rkb;this.d=new Rkb;this.f=a;this.c=b} +function PTb(){this.c=new bUb;this.a=new FYb;this.b=new wZb;$Yb()} +function b2c(){Y1c();this.b=new Lqb;this.a=new Lqb;this.c=new Rkb} +function j2d(a,b){this.g=a;this.d=(T0d(),S0d);this.a=S0d;this.b=b} +function O1d(a,b){this.f=a;this.a=(T0d(),R0d);this.c=R0d;this.b=b} +function h9d(a,b){!a.c&&(a.c=new u3d(a,0));f3d(a.c,(Q8d(),I8d),b)} +function $Tc(){$Tc=ccb;ZTc=new _Tc('DFS',0);YTc=new _Tc('BFS',1)} +function Cc(a,b,c){var d;d=BD(a.Zb().xc(b),14);return !!d&&d.Hc(c)} +function Gc(a,b,c){var d;d=BD(a.Zb().xc(b),14);return !!d&&d.Mc(c)} +function Ofb(a,b,c,d){a.a+=''+qfb(b==null?Xhe:fcb(b),c,d);return a} +function Xnd(a,b,c,d,e,f){Ynd(a,b,c,f);eLd(a,d);fLd(a,e);return a} +function Ysb(a){sCb(a.b.b!=a.d.a);a.c=a.b=a.b.b;--a.a;return a.c.c} +function Jgb(a){while(a.d>0&&a.a[--a.d]==0);a.a[a.d++]==0&&(a.e=0)} +function wwb(a){return !a.a?a.c:a.e.length==0?a.a.a:a.a.a+(''+a.e)} +function RSd(a){return !!a.a&&QSd(a.a.a).i!=0&&!(!!a.b&&QTd(a.b))} +function cLd(a){return !!a.u&&VKd(a.u.a).i!=0&&!(!!a.n&&FMd(a.n))} +function $i(a){return Zj(a.e.Hd().gc()*a.c.Hd().gc(),16,new ij(a))} +function XA(a,b){return ueb(Cbb(a.q.getTime()),Cbb(b.q.getTime()))} +function k_b(a){return BD(Qkb(a,KC(AQ,jne,17,a.c.length,0,1)),474)} +function l_b(a){return BD(Qkb(a,KC(OQ,kne,10,a.c.length,0,1)),193)} +function cKc(a){FJc();return !OZb(a)&&!(!OZb(a)&&a.c.i.c==a.d.i.c)} +function kDb(a,b,c){var d;d=(Qb(a),new Tkb(a));iDb(new jDb(d,b,c))} +function rXb(a,b,c){var d;d=(Qb(a),new Tkb(a));pXb(new qXb(d,b,c))} +function Nwb(a,b){var c;c=1-b;a.a[c]=Owb(a.a[c],c);return Owb(a,b)} +function YXc(a,b){var c;a.e=new QXc;c=gVc(b);Okb(c,a.c);ZXc(a,c,0)} +function o4c(a,b,c,d){var e;e=new w4c;e.a=b;e.b=c;e.c=d;Dsb(a.a,e)} +function p4c(a,b,c,d){var e;e=new w4c;e.a=b;e.b=c;e.c=d;Dsb(a.b,e)} +function i6d(a){var b,c,d;b=new A6d;c=s6d(b,a);z6d(b);d=c;return d} +function vZd(){var a,b,c;b=(c=(a=new UQd,a),c);Ekb(rZd,b);return b} +function H2c(a){a.j.c=KC(SI,Uhe,1,0,5,1);Ae(a.c);h3c(a.a);return a} +function tgc(a){qgc();if(JD(a.g,10)){return BD(a.g,10)}return null} +function Zw(a){if(Ah(a).dc()){return false}Bh(a,new bx);return true} +function _y(b){if(!('stack' in b)){try{throw b}catch(a){}}return b} +function Pb(a,b){if(a<0||a>=b){throw vbb(new qcb(Ib(a,b)))}return a} +function Tb(a,b,c){if(a<0||b<a||b>c){throw vbb(new qcb(Kb(a,b,c)))}} +function eVb(a,b){Qqb(a.a,b);if(b.d){throw vbb(new hz(Hke))}b.d=a} +function xpb(a,b){if(b.$modCount!=a.$modCount){throw vbb(new Apb)}} +function $pb(a,b){if(JD(b,42)){return Jd(a.a,BD(b,42))}return false} +function dib(a,b){if(JD(b,42)){return Jd(a.a,BD(b,42))}return false} +function msb(a,b){if(JD(b,42)){return Jd(a.a,BD(b,42))}return false} +function qAb(a,b){if(a.a<=a.b){b.ud(a.a++);return true}return false} +function Sbb(a){var b;if(Fbb(a)){b=a;return b==-0.?0:b}return oD(a)} +function tAb(a){var b;Tzb(a);b=new drb;_ub(a.a,new BAb(b));return b} +function Yzb(a){var b;Tzb(a);b=new Gpb;_ub(a.a,new mAb(b));return b} +function Bib(a,b){this.a=a;vib.call(this,a);wCb(b,a.gc());this.b=b} +function orb(a){this.e=a;this.b=this.e.a.entries();this.a=new Array} +function Oi(a){return Zj(a.e.Hd().gc()*a.c.Hd().gc(),273,new cj(a))} +function Qu(a){return new Skb((Xj(a,Mie),Oy(wbb(wbb(5,a),a/10|0))))} +function m_b(a){return BD(Qkb(a,KC(aR,lne,11,a.c.length,0,1)),1943)} +function sMb(a,b,c){return c.f.c.length>0?HMb(a.a,b,c):HMb(a.b,b,c)} +function SZb(a,b,c){!!a.d&&Lkb(a.d.e,a);a.d=b;!!a.d&&Dkb(a.d.e,c,a)} +function a5b(a,b){i5b(b,a);k5b(a.d);k5b(BD(vNb(a,(Nyc(),wxc)),207))} +function _4b(a,b){f5b(b,a);h5b(a.d);h5b(BD(vNb(a,(Nyc(),wxc)),207))} +function Ypd(a,b){var c,d;c=aC(a,b);d=null;!!c&&(d=c.fe());return d} +function Zpd(a,b){var c,d;c=tB(a,b);d=null;!!c&&(d=c.ie());return d} +function $pd(a,b){var c,d;c=aC(a,b);d=null;!!c&&(d=c.ie());return d} +function _pd(a,b){var c,d;c=aC(a,b);d=null;!!c&&(d=aqd(c));return d} +function Tqd(a,b,c){var d;d=Wpd(c);ro(a.g,d,b);ro(a.i,b,c);return b} +function Ez(a,b,c){var d;d=Cz();try{return Bz(a,b,c)}finally{Fz(d)}} +function C6d(a){var b;b=a.Wg();this.a=JD(b,69)?BD(b,69).Zh():b.Kc()} +function j3c(){D2c.call(this);this.j.c=KC(SI,Uhe,1,0,5,1);this.a=-1} +function mxd(a,b,c,d){this.d=a;this.n=b;this.g=c;this.o=d;this.p=-1} +function jk(a,b,c,d){this.e=d;this.d=null;this.c=a;this.a=b;this.b=c} +function uEc(a,b,c){this.d=new HEc(this);this.e=a;this.i=b;this.f=c} +function msc(){msc=ccb;ksc=new nsc(gle,0);lsc=new nsc('TOP_LEFT',1)} +function cDc(){cDc=ccb;bDc=ix(meb(1),meb(4));aDc=ix(meb(1),meb(2))} +function z_c(){z_c=ccb;y_c=as((s_c(),OC(GC(O_,1),Kie,551,0,[r_c])))} +function q_c(){q_c=ccb;p_c=as((i_c(),OC(GC(N_,1),Kie,482,0,[h_c])))} +function Z0c(){Z0c=ccb;Y0c=as((R0c(),OC(GC(W_,1),Kie,530,0,[Q0c])))} +function hPb(){hPb=ccb;gPb=as((cPb(),OC(GC(GO,1),Kie,481,0,[bPb])))} +function yLb(){vLb();return OC(GC(PN,1),Kie,406,0,[uLb,rLb,sLb,tLb])} +function qxb(){lxb();return OC(GC(iL,1),Kie,297,0,[hxb,ixb,jxb,kxb])} +function UOb(){ROb();return OC(GC(CO,1),Kie,394,0,[OOb,NOb,POb,QOb])} +function UMb(){RMb();return OC(GC(jO,1),Kie,323,0,[OMb,NMb,PMb,QMb])} +function sWb(){lWb();return OC(GC(SP,1),Kie,405,0,[hWb,kWb,iWb,jWb])} +function kbc(){gbc();return OC(GC(VS,1),Kie,360,0,[fbc,dbc,ebc,cbc])} +function Vc(a,b,c,d){return JD(c,54)?new Cg(a,b,c,d):new qg(a,b,c,d)} +function Djc(){Ajc();return OC(GC(mV,1),Kie,411,0,[wjc,xjc,yjc,zjc])} +function okc(a){var b;return a.j==(Ucd(),Rcd)&&(b=pkc(a),uqb(b,zcd))} +function Mdc(a,b){var c;c=b.a;QZb(c,b.c.d);RZb(c,b.d.d);q7c(c.a,a.n)} +function Smc(a,b){return BD(Btb(QAb(BD(Qc(a.k,b),15).Oc(),Hmc)),113)} +function Tmc(a,b){return BD(Btb(RAb(BD(Qc(a.k,b),15).Oc(),Hmc)),113)} +function _w(a){return new Kub(rmb(BD(a.a.dd(),14).gc(),a.a.cd()),16)} +function Qq(a){if(JD(a,14)){return BD(a,14).dc()}return !a.Kc().Ob()} +function ugc(a){qgc();if(JD(a.g,145)){return BD(a.g,145)}return null} +function Ko(a){if(a.e.g!=a.b){throw vbb(new Apb)}return !!a.c&&a.d>0} +function Xsb(a){sCb(a.b!=a.d.c);a.c=a.b;a.b=a.b.a;++a.a;return a.c.c} +function Xjb(a,b){uCb(b);NC(a.a,a.c,b);a.c=a.c+1&a.a.length-1;_jb(a)} +function Wjb(a,b){uCb(b);a.b=a.b-1&a.a.length-1;NC(a.a,a.b,b);_jb(a)} +function A2c(a,b){var c;for(c=a.j.c.length;c<b;c++){Ekb(a.j,a.rg())}} +function gBc(a,b,c,d){var e;e=d[b.g][c.g];return Edb(ED(vNb(a.a,e)))} +function goc(a,b,c,d,e){this.i=a;this.a=b;this.e=c;this.j=d;this.f=e} +function DZc(a,b,c,d,e){this.a=a;this.e=b;this.f=c;this.b=d;this.g=e} +function Fz(a){a&&Mz((Kz(),Jz));--xz;if(a){if(zz!=-1){Hz(zz);zz=-1}}} +function Nzc(){Izc();return OC(GC($W,1),Kie,197,0,[Gzc,Hzc,Fzc,Ezc])} +function ERc(){yRc();return OC(GC(h$,1),Kie,393,0,[uRc,vRc,wRc,xRc])} +function mXc(){iXc();return OC(GC(a_,1),Kie,340,0,[hXc,fXc,gXc,eXc])} +function wdd(){tdd();return OC(GC(I1,1),Kie,374,0,[rdd,sdd,qdd,pdd])} +function vbd(){rbd();return OC(GC(A1,1),Kie,285,0,[qbd,nbd,obd,pbd])} +function Dad(){Aad();return OC(GC(v1,1),Kie,218,0,[zad,xad,wad,yad])} +function Ged(){Ded();return OC(GC(O1,1),Kie,311,0,[Ced,zed,Bed,Aed])} +function sgd(){pgd();return OC(GC(k2,1),Kie,396,0,[mgd,ngd,lgd,ogd])} +function gvd(a){evd();return Mhb(dvd,a)?BD(Ohb(dvd,a),331).ug():null} +function cid(a,b,c){return b<0?tid(a,c):BD(c,66).Nj().Sj(a,a.yh(),b)} +function Sqd(a,b,c){var d;d=Wpd(c);ro(a.d,d,b);Rhb(a.e,b,c);return b} +function Uqd(a,b,c){var d;d=Wpd(c);ro(a.j,d,b);Rhb(a.k,b,c);return b} +function dtd(a){var b,c;b=(Fhd(),c=new Tld,c);!!a&&Rld(b,a);return b} +function wud(a){var b;b=a.ri(a.i);a.i>0&&$fb(a.g,0,b,0,a.i);return b} +function qEd(a,b){pEd();var c;c=BD(Ohb(oEd,a),55);return !c||c.wj(b)} +function Twd(a){if(a.p!=1)throw vbb(new Ydb);return Tbb(a.f)<<24>>24} +function axd(a){if(a.p!=1)throw vbb(new Ydb);return Tbb(a.k)<<24>>24} +function gxd(a){if(a.p!=7)throw vbb(new Ydb);return Tbb(a.k)<<16>>16} +function Zwd(a){if(a.p!=7)throw vbb(new Ydb);return Tbb(a.f)<<16>>16} +function sr(a){var b;b=0;while(a.Ob()){a.Pb();b=wbb(b,1)}return Oy(b)} +function nx(a,b){var c;c=new Vfb;a.xd(c);c.a+='..';b.yd(c);return c.a} +function Sgc(a,b,c){var d;d=BD(Ohb(a.g,c),57);Ekb(a.a.c,new vgd(b,d))} +function VCb(a,b,c){return Ddb(ED(Wd(irb(a.f,b))),ED(Wd(irb(a.f,c))))} +function E2d(a,b,c){return F2d(a,b,c,JD(b,99)&&(BD(b,18).Bb&Tje)!=0)} +function L2d(a,b,c){return M2d(a,b,c,JD(b,99)&&(BD(b,18).Bb&Tje)!=0)} +function q3d(a,b,c){return r3d(a,b,c,JD(b,99)&&(BD(b,18).Bb&Tje)!=0)} +function JJc(a,b){return a==(j0b(),h0b)&&b==h0b?4:a==h0b||b==h0b?8:32} +function Nd(a,b){return PD(b)===PD(a)?'(this Map)':b==null?Xhe:fcb(b)} +function kFd(a,b){return BD(b==null?Wd(irb(a.f,null)):Crb(a.g,b),281)} +function Rqd(a,b,c){var d;d=Wpd(c);Rhb(a.b,d,b);Rhb(a.c,b,c);return b} +function Bfd(a,b){var c;c=b;while(c){O6c(a,c.i,c.j);c=Xod(c)}return a} +function kt(a,b){var c;c=vmb(Nu(new wu(a,b)));ir(new wu(a,b));return c} +function R6d(a,b){Q6d();var c;c=BD(a,66).Mj();kVd(c,b);return c.Ok(b)} +function TOc(a,b,c,d,e){var f;f=OOc(e,c,d);Ekb(b,tOc(e,f));XOc(a,e,b)} +function mic(a,b,c){a.i=0;a.e=0;if(b==c){return}lic(a,b,c);kic(a,b,c)} +function dB(a,b){var c;c=a.q.getHours();a.q.setFullYear(b+nje);YA(a,c)} +function dC(d,a,b){if(b){var c=b.ee();d.a[a]=c(b)}else{delete d.a[a]}} +function vB(d,a,b){if(b){var c=b.ee();b=c(b)}else{b=undefined}d.a[a]=b} +function pCb(a){if(a<0){throw vbb(new Feb('Negative array size: '+a))}} +function VKd(a){if(!a.n){$Kd(a);a.n=new JMd(a,j5,a);_Kd(a)}return a.n} +function Fqb(a){sCb(a.a<a.c.a.length);a.b=a.a;Dqb(a);return a.c.b[a.b]} +function Yjb(a){if(a.b==a.c){return}a.a=KC(SI,Uhe,1,8,5,1);a.b=0;a.c=0} +function AQb(a){this.b=new Lqb;this.c=new Lqb;this.d=new Lqb;this.a=a} +function lge(a,b){wfe();xfe.call(this,a);this.a=b;this.c=-1;this.b=-1} +function lSd(a,b,c,d){kxd.call(this,1,c,d);jSd(this);this.c=a;this.b=b} +function mSd(a,b,c,d){lxd.call(this,1,c,d);jSd(this);this.c=a;this.b=b} +function O7d(a,b,c,d,e,f,g){nxd.call(this,b,d,e,f,g);this.c=a;this.a=c} +function LVd(a,b,c){this.e=a;this.a=SI;this.b=R5d(b);this.c=b;this.d=c} +function Lo(a){this.e=a;this.c=this.e.a;this.b=this.e.g;this.d=this.e.i} +function nYd(a){this.c=a;this.a=BD(wId(a),148);this.b=this.a.Aj().Nh()} +function Irb(a){this.d=a;this.b=this.d.a.entries();this.a=this.b.next()} +function $rb(){Lqb.call(this);Trb(this);this.d.b=this.d;this.d.a=this.d} +function mRb(a,b){_Qb.call(this);this.a=a;this.b=b;Ekb(this.a.b,this)} +function uFd(a,b){var c;return c=b!=null?Phb(a,b):Wd(irb(a.f,b)),RD(c)} +function FFd(a,b){var c;return c=b!=null?Phb(a,b):Wd(irb(a.f,b)),RD(c)} +function Fob(a,b){var c;for(c=0;c<b;++c){NC(a,c,new Rob(BD(a[c],42)))}} +function Lgb(a,b){var c;for(c=a.d-1;c>=0&&a.a[c]===b[c];c--);return c<0} +function Ucc(a,b){Occ();var c;c=a.j.g-b.j.g;if(c!=0){return c}return 0} +function Dtb(a,b){uCb(b);if(a.a!=null){return Itb(b.Kb(a.a))}return ztb} +function Gx(a){var b;if(a){return new Bsb(a)}b=new zsb;Jq(b,a);return b} +function GAb(a,b){var c;return b.b.Kb(SAb(a,b.c.Ee(),(c=new TBb(b),c)))} +function Hub(a){zub();Eub(this,Tbb(xbb(Obb(a,24),nke)),Tbb(xbb(a,nke)))} +function REb(){REb=ccb;QEb=as((MEb(),OC(GC(aN,1),Kie,428,0,[LEb,KEb])))} +function ZEb(){ZEb=ccb;YEb=as((UEb(),OC(GC(bN,1),Kie,427,0,[SEb,TEb])))} +function aSb(){aSb=ccb;_Rb=as((XRb(),OC(GC(gP,1),Kie,424,0,[VRb,WRb])))} +function D5b(){D5b=ccb;C5b=as((y5b(),OC(GC(ZR,1),Kie,511,0,[x5b,w5b])))} +function Cqc(){Cqc=ccb;Bqc=as((xqc(),OC(GC(JW,1),Kie,419,0,[vqc,wqc])))} +function erc(){erc=ccb;drc=as((_qc(),OC(GC(MW,1),Kie,479,0,[$qc,Zqc])))} +function eBc(){eBc=ccb;dBc=as((_Ac(),OC(GC(fX,1),Kie,376,0,[$Ac,ZAc])))} +function GAc(){GAc=ccb;FAc=as((BAc(),OC(GC(cX,1),Kie,421,0,[zAc,AAc])))} +function Npc(){Npc=ccb;Mpc=as((Ipc(),OC(GC(FW,1),Kie,422,0,[Gpc,Hpc])))} +function rsc(){rsc=ccb;qsc=as((msc(),OC(GC(SW,1),Kie,420,0,[ksc,lsc])))} +function MOc(){MOc=ccb;LOc=as((HOc(),OC(GC(DZ,1),Kie,520,0,[GOc,FOc])))} +function ZIc(){ZIc=ccb;YIc=as((UIc(),OC(GC(mY,1),Kie,523,0,[TIc,SIc])))} +function bMc(){bMc=ccb;aMc=as((YLc(),OC(GC(fZ,1),Kie,516,0,[XLc,WLc])))} +function jMc(){jMc=ccb;iMc=as((eMc(),OC(GC(gZ,1),Kie,515,0,[cMc,dMc])))} +function KQc(){KQc=ccb;JQc=as((FQc(),OC(GC(YZ,1),Kie,455,0,[DQc,EQc])))} +function dUc(){dUc=ccb;cUc=as(($Tc(),OC(GC(F$,1),Kie,425,0,[ZTc,YTc])))} +function XUc(){XUc=ccb;WUc=as((PUc(),OC(GC(K$,1),Kie,495,0,[NUc,OUc])))} +function XTc(){XTc=ccb;WTc=as((STc(),OC(GC(E$,1),Kie,480,0,[QTc,RTc])))} +function lWc(){lWc=ccb;kWc=as((fWc(),OC(GC(X$,1),Kie,426,0,[dWc,eWc])))} +function i1c(){i1c=ccb;h1c=as((a1c(),OC(GC(X_,1),Kie,429,0,[_0c,$0c])))} +function H_c(){H_c=ccb;G_c=as((C_c(),OC(GC(P_,1),Kie,430,0,[B_c,A_c])))} +function UIc(){UIc=ccb;TIc=new VIc('UPPER',0);SIc=new VIc('LOWER',1)} +function Lqd(a,b){var c;c=new eC;Spd(c,'x',b.a);Spd(c,'y',b.b);Qpd(a,c)} +function Oqd(a,b){var c;c=new eC;Spd(c,'x',b.a);Spd(c,'y',b.b);Qpd(a,c)} +function Jic(a,b){var c,d;d=false;do{c=Mic(a,b);d=d|c}while(c);return d} +function zHc(a,b){var c,d;c=b;d=0;while(c>0){d+=a.a[c];c-=c&-c}return d} +function Cfd(a,b){var c;c=b;while(c){O6c(a,-c.i,-c.j);c=Xod(c)}return a} +function reb(a,b){var c,d;uCb(b);for(d=a.Kc();d.Ob();){c=d.Pb();b.td(c)}} +function me(a,b){var c;c=b.cd();return new Wo(c,a.e.pc(c,BD(b.dd(),14)))} +function Gsb(a,b,c,d){var e;e=new jtb;e.c=b;e.b=c;e.a=d;d.b=c.a=e;++a.b} +function Nkb(a,b,c){var d;d=(tCb(b,a.c.length),a.c[b]);a.c[b]=c;return d} +function lFd(a,b,c){return BD(b==null?jrb(a.f,null,c):Drb(a.g,b,c),281)} +function fRb(a){return !!a.c&&!!a.d?oRb(a.c)+'->'+oRb(a.d):'e_'+FCb(a)} +function FAb(a,b){return (Uzb(a),WAb(new YAb(a,new qBb(b,a.a)))).sd(DAb)} +function tUb(){qUb();return OC(GC(zP,1),Kie,356,0,[lUb,mUb,nUb,oUb,pUb])} +function _cd(){Ucd();return OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd])} +function Dz(b){Az();return function(){return Ez(b,this,arguments);var a}} +function sz(){if(Date.now){return Date.now()}return (new Date).getTime()} +function OZb(a){if(!a.c||!a.d){return false}return !!a.c.i&&a.c.i==a.d.i} +function pv(a){if(!a.c.Sb()){throw vbb(new utb)}a.a=true;return a.c.Ub()} +function ko(a){a.i=0;Alb(a.b,null);Alb(a.c,null);a.a=null;a.e=null;++a.g} +function ycb(a){wcb.call(this,a==null?Xhe:fcb(a),JD(a,78)?BD(a,78):null)} +function PYb(a){MYb();yXb(this);this.a=new Psb;NYb(this,a);Dsb(this.a,a)} +function jYb(){Ckb(this);this.b=new f7c(Pje,Pje);this.a=new f7c(Qje,Qje)} +function rAb(a,b){this.c=0;this.b=b;jvb.call(this,a,17493);this.a=this.c} +function wyb(a){oyb();if(lyb){return}this.c=a;this.e=true;this.a=new Rkb} +function oyb(){oyb=ccb;lyb=true;jyb=false;kyb=false;nyb=false;myb=false} +function C3c(a,b){if(JD(b,149)){return dfb(a.c,BD(b,149).c)}return false} +function zUc(a,b){var c;c=0;!!a&&(c+=a.f.a/2);!!b&&(c+=b.f.a/2);return c} +function j4c(a,b){var c;c=BD(Wrb(a.d,b),23);return c?c:BD(Wrb(a.e,b),23)} +function Lzd(a){this.b=a;Fyd.call(this,a);this.a=BD(Ajd(this.b.a,4),126)} +function Uzd(a){this.b=a;$yd.call(this,a);this.a=BD(Ajd(this.b.a,4),126)} +function $Kd(a){if(!a.t){a.t=new YMd(a);vtd(new c0d(a),0,a.t)}return a.t} +function kad(){ead();return OC(GC(t1,1),Kie,103,0,[cad,bad,aad,_9c,dad])} +function Wbd(){Tbd();return OC(GC(C1,1),Kie,249,0,[Qbd,Sbd,Obd,Pbd,Rbd])} +function Q5c(){N5c();return OC(GC(e1,1),Kie,175,0,[L5c,K5c,I5c,M5c,J5c])} +function Q_c(){N_c();return OC(GC(Q_,1),Kie,316,0,[I_c,J_c,M_c,K_c,L_c])} +function _zc(){Vzc();return OC(GC(_W,1),Kie,315,0,[Uzc,Rzc,Szc,Qzc,Tzc])} +function sqc(){mqc();return OC(GC(IW,1),Kie,335,0,[iqc,hqc,kqc,lqc,jqc])} +function n$c(){k$c();return OC(GC(y_,1),Kie,355,0,[g$c,f$c,i$c,h$c,j$c])} +function _jc(){Xjc();return OC(GC(uV,1),Kie,363,0,[Tjc,Vjc,Wjc,Ujc,Sjc])} +function Ftc(){Ctc();return OC(GC(TW,1),Kie,163,0,[Btc,xtc,ytc,ztc,Atc])} +function T0d(){T0d=ccb;var a,b;R0d=(LFd(),b=new MPd,b);S0d=(a=new OJd,a)} +function yUd(a){var b;if(!a.c){b=a.r;JD(b,88)&&(a.c=BD(b,26))}return a.c} +function zc(a){a.e=3;a.d=a.Yb();if(a.e!=2){a.e=0;return true}return false} +function RC(a){var b,c,d;b=a&Eje;c=a>>22&Eje;d=a<0?Fje:0;return TC(b,c,d)} +function uy(a){var b,c,d,e;for(c=a,d=0,e=c.length;d<e;++d){b=c[d];Qzb(b)}} +function Tc(a,b){var c,d;c=BD(Iv(a.c,b),14);if(c){d=c.gc();c.$b();a.d-=d}} +function tjb(a,b){var c,d;c=b.cd();d=Awb(a,c);return !!d&&wtb(d.e,b.dd())} +function Qgb(a,b){if(b==0||a.e==0){return a}return b>0?ihb(a,b):lhb(a,-b)} +function Rgb(a,b){if(b==0||a.e==0){return a}return b>0?lhb(a,b):ihb(a,-b)} +function Rr(a){if(Qr(a)){a.c=a.a;return a.a.Pb()}else{throw vbb(new utb)}} +function Yac(a){var b,c;b=a.c.i;c=a.d.i;return b.k==(j0b(),e0b)&&c.k==e0b} +function kZb(a){var b;b=new UZb;tNb(b,a);yNb(b,(Nyc(),jxc),null);return b} +function hid(a,b,c){var d;return d=a.Yg(b),d>=0?a._g(d,c,true):sid(a,b,c)} +function uHb(a,b,c,d){var e;for(e=0;e<rHb;e++){nHb(a.a[b.g][e],c,d[b.g])}} +function vHb(a,b,c,d){var e;for(e=0;e<sHb;e++){mHb(a.a[e][b.g],c,d[b.g])}} +function vSd(a,b,c,d,e){kxd.call(this,b,d,e);jSd(this);this.c=a;this.a=c} +function zSd(a,b,c,d,e){lxd.call(this,b,d,e);jSd(this);this.c=a;this.a=c} +function ISd(a,b,c,d,e){oxd.call(this,b,d,e);jSd(this);this.c=a;this.a=c} +function qSd(a,b,c,d,e){oxd.call(this,b,d,e);jSd(this);this.c=a;this.b=c} +function mWd(a,b,c){VVd.call(this,c);this.b=a;this.c=b;this.d=(CWd(),AWd)} +function oxd(a,b,c){this.d=a;this.k=b?1:0;this.f=c?1:0;this.o=-1;this.p=0} +function _6d(a,b,c){var d;d=new a7d(a.a);Ld(d,a.a.a);jrb(d.f,b,c);a.a.a=d} +function lud(a,b){a.qi(a.i+1);mud(a,a.i,a.oi(a.i,b));a.bi(a.i++,b);a.ci()} +function oud(a){var b,c;++a.j;b=a.g;c=a.i;a.g=null;a.i=0;a.di(c,b);a.ci()} +function Ou(a){var b,c;Qb(a);b=Iu(a.length);c=new Skb(b);nmb(c,a);return c} +function km(a){var b;b=(Qb(a),a?new Tkb(a):Nu(a.Kc()));smb(b);return Dm(b)} +function Kkb(a,b){var c;c=(tCb(b,a.c.length),a.c[b]);cCb(a.c,b,1);return c} +function Qc(a,b){var c;c=BD(a.c.xc(b),14);!c&&(c=a.ic(b));return a.pc(b,c)} +function cfb(a,b){var c,d;c=(uCb(a),a);d=(uCb(b),b);return c==d?0:c<d?-1:1} +function Fpb(a){var b;b=a.e+a.f;if(isNaN(b)&&Ldb(a.d)){return a.d}return b} +function uwb(a,b){!a.a?(a.a=new Wfb(a.d)):Qfb(a.a,a.b);Nfb(a.a,b);return a} +function Sb(a,b){if(a<0||a>b){throw vbb(new qcb(Jb(a,b,'index')))}return a} +function zhb(a,b,c,d){var e;e=KC(WD,oje,25,b,15,1);Ahb(e,a,b,c,d);return e} +function _A(a,b){var c;c=a.q.getHours()+(b/60|0);a.q.setMinutes(b);YA(a,c)} +function A$c(a,b){return $wnd.Math.min(S6c(b.a,a.d.d.c),S6c(b.b,a.d.d.c))} +function Thb(a,b){return ND(b)?b==null?krb(a.f,null):Erb(a.g,b):krb(a.f,b)} +function b1b(a){this.c=a;this.a=new olb(this.c.a);this.b=new olb(this.c.b)} +function kRb(){this.e=new Rkb;this.c=new Rkb;this.d=new Rkb;this.b=new Rkb} +function MFb(){this.g=new PFb;this.b=new PFb;this.a=new Rkb;this.k=new Rkb} +function Gjc(a,b,c){this.a=a;this.c=b;this.d=c;Ekb(b.e,this);Ekb(c.b,this)} +function wBb(a,b){fvb.call(this,b.rd(),b.qd()&-6);uCb(a);this.a=a;this.b=b} +function CBb(a,b){jvb.call(this,b.rd(),b.qd()&-6);uCb(a);this.a=a;this.b=b} +function IBb(a,b){nvb.call(this,b.rd(),b.qd()&-6);uCb(a);this.a=a;this.b=b} +function BQc(a,b,c){this.a=a;this.b=b;this.c=c;Ekb(a.t,this);Ekb(b.i,this)} +function SRc(){this.b=new Psb;this.a=new Psb;this.b=new Psb;this.a=new Psb} +function g6c(){g6c=ccb;f6c=new Lsd('org.eclipse.elk.labels.labelManager')} +function Vac(){Vac=ccb;Uac=new Msd('separateLayerConnections',(gbc(),fbc))} +function HOc(){HOc=ccb;GOc=new IOc('REGULAR',0);FOc=new IOc('CRITICAL',1)} +function _Ac(){_Ac=ccb;$Ac=new aBc('STACKED',0);ZAc=new aBc('SEQUENCED',1)} +function C_c(){C_c=ccb;B_c=new D_c('FIXED',0);A_c=new D_c('CENTER_NODE',1)} +function PHc(a,b){var c;c=VHc(a,b);a.b=new BHc(c.c.length);return OHc(a,c)} +function KAd(a,b,c){var d;++a.e;--a.f;d=BD(a.d[b].$c(c),133);return d.dd()} +function JJd(a){var b;if(!a.a){b=a.r;JD(b,148)&&(a.a=BD(b,148))}return a.a} +function poc(a){if(a.a){if(a.e){return poc(a.e)}}else{return a}return null} +function ODc(a,b){if(a.p<b.p){return 1}else if(a.p>b.p){return -1}return 0} +function pvb(a,b){uCb(b);if(a.c<a.d){a.ze(b,a.c++);return true}return false} +function QYd(a,b){if(Mhb(a.a,b)){Thb(a.a,b);return true}else{return false}} +function fd(a){var b,c;b=a.cd();c=BD(a.dd(),14);return $j(c.Nc(),new ah(b))} +function sqb(a){var b;b=BD(ZBb(a.b,a.b.length),9);return new xqb(a.a,b,a.c)} +function _zb(a){var b;Uzb(a);b=new fAb(a,a.a.e,a.a.d|4);return new bAb(a,b)} +function HAb(a){var b;Tzb(a);b=0;while(a.a.sd(new RBb)){b=wbb(b,1)}return b} +function UDc(a,b,c){var d,e;d=0;for(e=0;e<b.length;e++){d+=a.$f(b[e],d,c)}} +function QJb(a,b){var c;if(a.C){c=BD(Mpb(a.b,b),124).n;c.d=a.C.d;c.a=a.C.a}} +function Mi(a,b,c){Pb(b,a.e.Hd().gc());Pb(c,a.c.Hd().gc());return a.a[b][c]} +function Ugb(a,b){Hgb();this.e=a;this.d=1;this.a=OC(GC(WD,1),oje,25,15,[b])} +function dg(a,b,c,d){this.f=a;this.e=b;this.d=c;this.b=d;this.c=!d?null:d.d} +function o5b(a){var b,c,d,e;e=a.d;b=a.a;c=a.b;d=a.c;a.d=c;a.a=d;a.b=e;a.c=b} +function Y2d(a,b,c,d){X2d(a,b,c,M2d(a,b,d,JD(b,99)&&(BD(b,18).Bb&Tje)!=0))} +function tac(a,b){Odd(b,'Label management',1);RD(vNb(a,(g6c(),f6c)));Qdd(b)} +function Skb(a){Ckb(this);mCb(a>=0,'Initial capacity must not be negative')} +function lHb(){lHb=ccb;kHb=as((gHb(),OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb])))} +function SHb(){SHb=ccb;RHb=as((NHb(),OC(GC(sN,1),Kie,461,0,[LHb,KHb,MHb])))} +function JIb(){JIb=ccb;IIb=as((EIb(),OC(GC(zN,1),Kie,462,0,[DIb,CIb,BIb])))} +function Kyb(){Kyb=ccb;Jyb=as((Fyb(),OC(GC(xL,1),Kie,132,0,[Cyb,Dyb,Eyb])))} +function DTb(){DTb=ccb;CTb=as((yTb(),OC(GC(oP,1),Kie,379,0,[wTb,vTb,xTb])))} +function WXb(){WXb=ccb;VXb=as((RXb(),OC(GC(hQ,1),Kie,423,0,[QXb,PXb,OXb])))} +function Zpc(){Zpc=ccb;Ypc=as((Rpc(),OC(GC(GW,1),Kie,314,0,[Ppc,Opc,Qpc])))} +function gqc(){gqc=ccb;fqc=as((bqc(),OC(GC(HW,1),Kie,337,0,[$pc,aqc,_pc])))} +function Lqc(){Lqc=ccb;Kqc=as((Gqc(),OC(GC(KW,1),Kie,450,0,[Eqc,Dqc,Fqc])))} +function Kkc(){Kkc=ccb;Jkc=as((Fkc(),OC(GC(vV,1),Kie,361,0,[Ekc,Dkc,Ckc])))} +function jsc(){jsc=ccb;isc=as((esc(),OC(GC(RW,1),Kie,303,0,[csc,dsc,bsc])))} +function asc(){asc=ccb;_rc=as((Xrc(),OC(GC(QW,1),Kie,292,0,[Vrc,Wrc,Urc])))} +function Dzc(){Dzc=ccb;Czc=as((xzc(),OC(GC(ZW,1),Kie,378,0,[uzc,vzc,wzc])))} +function YAc(){YAc=ccb;XAc=as((TAc(),OC(GC(eX,1),Kie,375,0,[QAc,RAc,SAc])))} +function yAc(){yAc=ccb;xAc=as((tAc(),OC(GC(bX,1),Kie,339,0,[rAc,qAc,sAc])))} +function PAc(){PAc=ccb;OAc=as((KAc(),OC(GC(dX,1),Kie,452,0,[JAc,HAc,IAc])))} +function QBc(){QBc=ccb;PBc=as((LBc(),OC(GC(jX,1),Kie,377,0,[JBc,KBc,IBc])))} +function yBc(){yBc=ccb;xBc=as((tBc(),OC(GC(hX,1),Kie,336,0,[qBc,rBc,sBc])))} +function HBc(){HBc=ccb;GBc=as((CBc(),OC(GC(iX,1),Kie,338,0,[BBc,zBc,ABc])))} +function wGc(){wGc=ccb;vGc=as((rGc(),OC(GC(PX,1),Kie,454,0,[oGc,pGc,qGc])))} +function zVc(){zVc=ccb;yVc=as((tVc(),OC(GC(O$,1),Kie,442,0,[sVc,qVc,rVc])))} +function vWc(){vWc=ccb;uWc=as((pWc(),OC(GC(Y$,1),Kie,380,0,[mWc,nWc,oWc])))} +function EYc(){EYc=ccb;DYc=as((zYc(),OC(GC(q_,1),Kie,381,0,[xYc,yYc,wYc])))} +function yXc(){yXc=ccb;xXc=as((sXc(),OC(GC(b_,1),Kie,293,0,[qXc,rXc,pXc])))} +function b_c(){b_c=ccb;a_c=as((Y$c(),OC(GC(J_,1),Kie,437,0,[V$c,W$c,X$c])))} +function mbd(){mbd=ccb;lbd=as((hbd(),OC(GC(z1,1),Kie,334,0,[fbd,ebd,gbd])))} +function vad(){vad=ccb;uad=as((qad(),OC(GC(u1,1),Kie,272,0,[nad,oad,pad])))} +function icd(){dcd();return OC(GC(D1,1),Kie,98,0,[ccd,bcd,acd,Zbd,_bd,$bd])} +function ikd(a,b){return !a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),qAd(a.o,b)} +function NAd(a){!a.g&&(a.g=new JCd);!a.g.d&&(a.g.d=new MBd(a));return a.g.d} +function yAd(a){!a.g&&(a.g=new JCd);!a.g.a&&(a.g.a=new SBd(a));return a.g.a} +function EAd(a){!a.g&&(a.g=new JCd);!a.g.b&&(a.g.b=new GBd(a));return a.g.b} +function FAd(a){!a.g&&(a.g=new JCd);!a.g.c&&(a.g.c=new iCd(a));return a.g.c} +function A2d(a,b,c){var d,e;e=new p4d(b,a);for(d=0;d<c;++d){d4d(e)}return e} +function Atd(a,b,c){var d,e;if(c!=null){for(d=0;d<b;++d){e=c[d];a.fi(d,e)}}} +function uhb(a,b,c,d){var e;e=KC(WD,oje,25,b+1,15,1);vhb(e,a,b,c,d);return e} +function KC(a,b,c,d,e,f){var g;g=LC(e,d);e!=10&&OC(GC(a,f),b,c,e,g);return g} +function bYd(a,b,c,d){!!c&&(d=c.gh(b,bLd(c.Tg(),a.c.Lj()),null,d));return d} +function cYd(a,b,c,d){!!c&&(d=c.ih(b,bLd(c.Tg(),a.c.Lj()),null,d));return d} +function KNb(a,b,c){BD(a.b,65);BD(a.b,65);BD(a.b,65);Hkb(a.a,new TNb(c,b,a))} +function ACb(a,b,c){if(a<0||b>c||b<a){throw vbb(new Xfb(xke+a+zke+b+oke+c))}} +function zCb(a){if(!a){throw vbb(new Zdb('Unable to add element to queue'))}} +function Vzb(a){if(!a){this.c=null;this.b=new Rkb}else{this.c=a;this.b=null}} +function exb(a,b){pjb.call(this,a,b);this.a=KC(dL,zie,436,2,0,1);this.b=true} +function _rb(a){Whb.call(this,a,0);Trb(this);this.d.b=this.d;this.d.a=this.d} +function VRc(a){var b;b=a.b;if(b.b==0){return null}return BD(Ut(b,0),188).b} +function Kwb(a,b){var c;c=new fxb;c.c=true;c.d=b.dd();return Lwb(a,b.cd(),c)} +function bB(a,b){var c;c=a.q.getHours()+(b/3600|0);a.q.setSeconds(b);YA(a,c)} +function zGc(a,b,c){var d;d=a.b[c.c.p][c.p];d.b+=b.b;d.c+=b.c;d.a+=b.a;++d.a} +function S6c(a,b){var c,d;c=a.a-b.a;d=a.b-b.b;return $wnd.Math.sqrt(c*c+d*d)} +function Ipc(){Ipc=ccb;Gpc=new Jpc('QUADRATIC',0);Hpc=new Jpc('SCANLINE',1)} +function hCc(){hCc=ccb;gCc=c3c(e3c(new j3c,(qUb(),lUb),(S8b(),n8b)),pUb,J8b)} +function l8c(){i8c();return OC(GC(r1,1),Kie,291,0,[h8c,g8c,f8c,d8c,c8c,e8c])} +function I7c(){F7c();return OC(GC(o1,1),Kie,248,0,[z7c,C7c,D7c,E7c,A7c,B7c])} +function Dpc(){Apc();return OC(GC(EW,1),Kie,227,0,[wpc,ypc,vpc,xpc,zpc,upc])} +function Brc(){yrc();return OC(GC(OW,1),Kie,275,0,[wrc,trc,xrc,vrc,urc,rrc])} +function orc(){lrc();return OC(GC(NW,1),Kie,274,0,[irc,hrc,krc,grc,jrc,frc])} +function rzc(){lzc();return OC(GC(YW,1),Kie,313,0,[jzc,hzc,fzc,gzc,kzc,izc])} +function Wqc(){Sqc();return OC(GC(LW,1),Kie,276,0,[Nqc,Mqc,Pqc,Oqc,Rqc,Qqc])} +function uSc(){qSc();return OC(GC(t$,1),Kie,327,0,[pSc,lSc,nSc,mSc,oSc,kSc])} +function wcd(){rcd();return OC(GC(E1,1),Kie,273,0,[pcd,ncd,ocd,mcd,lcd,qcd])} +function Pad(){Mad();return OC(GC(w1,1),Kie,312,0,[Kad,Iad,Lad,Gad,Jad,Had])} +function m0b(){j0b();return OC(GC(NQ,1),Kie,267,0,[h0b,g0b,e0b,i0b,f0b,d0b])} +function mib(a){yCb(!!a.c);xpb(a.e,a);a.c.Qb();a.c=null;a.b=kib(a);ypb(a.e,a)} +function tsb(a){xpb(a.c.a.e,a);sCb(a.b!=a.c.a.d);a.a=a.b;a.b=a.b.a;return a.a} +function kSd(a){var b;if(!a.a&&a.b!=-1){b=a.c.Tg();a.a=XKd(b,a.b)}return a.a} +function wtd(a,b){if(a.hi()&&a.Hc(b)){return false}else{a.Yh(b);return true}} +function $Hb(a,b){ytb(b,'Horizontal alignment cannot be null');a.b=b;return a} +function Lfe(a,b,c){wfe();var d;d=Kfe(a,b);c&&!!d&&Nfe(a)&&(d=null);return d} +function vXb(a,b,c){var d,e;for(e=a.Kc();e.Ob();){d=BD(e.Pb(),37);uXb(d,b,c)}} +function tXb(a,b){var c,d;for(d=b.Kc();d.Ob();){c=BD(d.Pb(),37);sXb(a,c,0,0)}} +function ojc(a,b,c){var d;a.d[b.g]=c;d=a.g.c;d[b.g]=$wnd.Math.max(d[b.g],c+1)} +function KZc(a,b){var c,d,e;e=a.r;d=a.d;c=MZc(a,b,true);return c.b!=e||c.a!=d} +function Jjc(a,b){Vrb(a.e,b)||Xrb(a.e,b,new Pjc(b));return BD(Wrb(a.e,b),113)} +function Byb(a,b,c,d){uCb(a);uCb(b);uCb(c);uCb(d);return new Lyb(a,b,new Vxb)} +function dId(a,b,c,d){this.rj();this.a=b;this.b=a;this.c=new Y5d(this,b,c,d)} +function oSd(a,b,c,d,e,f){mxd.call(this,b,d,e,f);jSd(this);this.c=a;this.b=c} +function ESd(a,b,c,d,e,f){mxd.call(this,b,d,e,f);jSd(this);this.c=a;this.a=c} +function Bqd(a,b,c){var d,e,f;d=aC(a,c);e=null;!!d&&(e=aqd(d));f=e;Vqd(b,c,f)} +function Cqd(a,b,c){var d,e,f;d=aC(a,c);e=null;!!d&&(e=aqd(d));f=e;Vqd(b,c,f)} +function v1d(a,b,c){var d,e;e=(d=nUd(a.b,b),d);return !e?null:V1d(p1d(a,e),c)} +function gid(a,b){var c;return c=a.Yg(b),c>=0?a._g(c,true,true):sid(a,b,true)} +function s6b(a,b){return Kdb(Edb(ED(vNb(a,(wtc(),htc)))),Edb(ED(vNb(b,htc))))} +function pUc(){pUc=ccb;oUc=b3c(b3c(g3c(new j3c,(yRc(),vRc)),(qSc(),pSc)),lSc)} +function IHc(a,b,c){var d;d=SHc(a,b,c);a.b=new BHc(d.c.length);return KHc(a,d)} +function qhe(a){if(a.b<=0)throw vbb(new utb);--a.b;a.a-=a.c.c;return meb(a.a)} +function ptd(a){var b;if(!a.a){throw vbb(new vtb)}b=a.a;a.a=Xod(a.a);return b} +function dBb(a){while(!a.a){if(!HBb(a.c,new hBb(a))){return false}}return true} +function vr(a){var b;Qb(a);if(JD(a,198)){b=BD(a,198);return b}return new wr(a)} +function r3c(a){p3c();BD(a.We((Y9c(),x9c)),174).Fc((rcd(),ocd));a.Ye(w9c,null)} +function p3c(){p3c=ccb;m3c=new v3c;o3c=new x3c;n3c=mn((Y9c(),w9c),m3c,b9c,o3c)} +function fWc(){fWc=ccb;dWc=new hWc('LEAF_NUMBER',0);eWc=new hWc('NODE_SIZE',1)} +function UMc(a,b,c){a.a=b;a.c=c;a.b.a.$b();Osb(a.d);a.e.a.c=KC(SI,Uhe,1,0,5,1)} +function yHc(a){a.a=KC(WD,oje,25,a.b+1,15,1);a.c=KC(WD,oje,25,a.b,15,1);a.d=0} +function MWb(a,b){if(a.a.ue(b.d,a.b)>0){Ekb(a.c,new dWb(b.c,b.d,a.d));a.b=b.d}} +function nud(a,b){if(a.g==null||b>=a.i)throw vbb(new $zd(b,a.i));return a.g[b]} +function pOd(a,b,c){Itd(a,c);if(c!=null&&!a.wj(c)){throw vbb(new tcb)}return c} +function KLd(a){var b;if(a.Ek()){for(b=a.i-1;b>=0;--b){qud(a,b)}}return wud(a)} +function Bwb(a){var b,c;if(!a.b){return null}c=a.b;while(b=c.a[0]){c=b}return c} +function ulb(a,b){var c,d;pCb(b);return c=(d=a.slice(0,b),PC(d,a)),c.length=b,c} +function Klb(a,b,c,d){var e;d=(ipb(),!d?fpb:d);e=a.slice(b,c);Llb(e,a,b,c,-b,d)} +function bid(a,b,c,d,e){return b<0?sid(a,c,d):BD(c,66).Nj().Pj(a,a.yh(),b,d,e)} +function hZd(a){if(JD(a,172)){return ''+BD(a,172).a}return a==null?null:fcb(a)} +function iZd(a){if(JD(a,172)){return ''+BD(a,172).a}return a==null?null:fcb(a)} +function nDb(a,b){if(b.a){throw vbb(new hz(Hke))}Qqb(a.a,b);b.a=a;!a.j&&(a.j=b)} +function qBb(a,b){nvb.call(this,b.rd(),b.qd()&-16449);uCb(a);this.a=a;this.c=b} +function Ti(a,b){var c,d;d=b/a.c.Hd().gc()|0;c=b%a.c.Hd().gc();return Mi(a,d,c)} +function NHb(){NHb=ccb;LHb=new OHb(jle,0);KHb=new OHb(gle,1);MHb=new OHb(kle,2)} +function lxb(){lxb=ccb;hxb=new mxb('All',0);ixb=new rxb;jxb=new txb;kxb=new wxb} +function zxb(){zxb=ccb;yxb=as((lxb(),OC(GC(iL,1),Kie,297,0,[hxb,ixb,jxb,kxb])))} +function uWb(){uWb=ccb;tWb=as((lWb(),OC(GC(SP,1),Kie,405,0,[hWb,kWb,iWb,jWb])))} +function ALb(){ALb=ccb;zLb=as((vLb(),OC(GC(PN,1),Kie,406,0,[uLb,rLb,sLb,tLb])))} +function WMb(){WMb=ccb;VMb=as((RMb(),OC(GC(jO,1),Kie,323,0,[OMb,NMb,PMb,QMb])))} +function WOb(){WOb=ccb;VOb=as((ROb(),OC(GC(CO,1),Kie,394,0,[OOb,NOb,POb,QOb])))} +function GRc(){GRc=ccb;FRc=as((yRc(),OC(GC(h$,1),Kie,393,0,[uRc,vRc,wRc,xRc])))} +function mbc(){mbc=ccb;lbc=as((gbc(),OC(GC(VS,1),Kie,360,0,[fbc,dbc,ebc,cbc])))} +function oXc(){oXc=ccb;nXc=as((iXc(),OC(GC(a_,1),Kie,340,0,[hXc,fXc,gXc,eXc])))} +function Fjc(){Fjc=ccb;Ejc=as((Ajc(),OC(GC(mV,1),Kie,411,0,[wjc,xjc,yjc,zjc])))} +function Pzc(){Pzc=ccb;Ozc=as((Izc(),OC(GC($W,1),Kie,197,0,[Gzc,Hzc,Fzc,Ezc])))} +function ugd(){ugd=ccb;tgd=as((pgd(),OC(GC(k2,1),Kie,396,0,[mgd,ngd,lgd,ogd])))} +function xbd(){xbd=ccb;wbd=as((rbd(),OC(GC(A1,1),Kie,285,0,[qbd,nbd,obd,pbd])))} +function Fad(){Fad=ccb;Ead=as((Aad(),OC(GC(v1,1),Kie,218,0,[zad,xad,wad,yad])))} +function Ied(){Ied=ccb;Hed=as((Ded(),OC(GC(O1,1),Kie,311,0,[Ced,zed,Bed,Aed])))} +function ydd(){ydd=ccb;xdd=as((tdd(),OC(GC(I1,1),Kie,374,0,[rdd,sdd,qdd,pdd])))} +function A9d(){A9d=ccb;Smd();x9d=Pje;w9d=Qje;z9d=new Ndb(Pje);y9d=new Ndb(Qje)} +function _qc(){_qc=ccb;$qc=new arc(ane,0);Zqc=new arc('IMPROVE_STRAIGHTNESS',1)} +function eIc(a,b){FHc();return Ekb(a,new vgd(b,meb(b.e.c.length+b.g.c.length)))} +function gIc(a,b){FHc();return Ekb(a,new vgd(b,meb(b.e.c.length+b.g.c.length)))} +function PC(a,b){HC(b)!=10&&OC(rb(b),b.hm,b.__elementTypeId$,HC(b),a);return a} +function Lkb(a,b){var c;c=Jkb(a,b,0);if(c==-1){return false}Kkb(a,c);return true} +function Zrb(a,b){var c;c=BD(Thb(a.e,b),387);if(c){jsb(c);return c.e}return null} +function Jbb(a){var b;if(Fbb(a)){b=0-a;if(!isNaN(b)){return b}}return zbb(hD(a))} +function Jkb(a,b,c){for(;c<a.c.length;++c){if(wtb(b,a.c[c])){return c}}return -1} +function SAb(a,b,c){var d;Tzb(a);d=new NBb;d.a=b;a.a.Nb(new VBb(d,c));return d.a} +function aAb(a){var b;Tzb(a);b=KC(UD,Vje,25,0,15,1);_ub(a.a,new kAb(b));return b} +function ajc(a){var b,c;c=BD(Ikb(a.j,0),11);b=BD(vNb(c,(wtc(),$sc)),11);return b} +function yc(a){var b;if(!xc(a)){throw vbb(new utb)}a.e=1;b=a.d;a.d=null;return b} +function wu(a,b){var c;this.f=a;this.b=b;c=BD(Ohb(a.b,b),283);this.c=!c?null:c.b} +function Ygc(){Hgc();this.b=new Lqb;this.f=new Lqb;this.g=new Lqb;this.e=new Lqb} +function Tnc(a,b){this.a=KC(OQ,kne,10,a.a.c.length,0,1);Qkb(a.a,this.a);this.b=b} +function zoc(a){var b;for(b=a.p+1;b<a.c.a.c.length;++b){--BD(Ikb(a.c.a,b),10).p}} +function Rwd(a){var b;b=a.Ai();b!=null&&a.d!=-1&&BD(b,92).Ng(a);!!a.i&&a.i.Fi()} +function rFd(a){Py(this);this.g=!a?null:Wy(a,a.$d());this.f=a;Ry(this);this._d()} +function pSd(a,b,c,d,e,f,g){nxd.call(this,b,d,e,f,g);jSd(this);this.c=a;this.b=c} +function Ayb(a,b,c,d,e){uCb(a);uCb(b);uCb(c);uCb(d);uCb(e);return new Lyb(a,b,d)} +function B2c(a,b){if(b<0){throw vbb(new qcb(ese+b))}A2c(a,b+1);return Ikb(a.j,b)} +function Ob(a,b,c,d){if(!a){throw vbb(new Wdb(hc(b,OC(GC(SI,1),Uhe,1,5,[c,d]))))}} +function dDb(a,b){return wtb(b,Ikb(a.f,0))||wtb(b,Ikb(a.f,1))||wtb(b,Ikb(a.f,2))} +function ghd(a,b){ecd(BD(BD(a.f,33).We((Y9c(),t9c)),98))&&NCd(Yod(BD(a.f,33)),b)} +function p1d(a,b){var c,d;c=BD(b,675);d=c.Oh();!d&&c.Rh(d=new Y1d(a,b));return d} +function q1d(a,b){var c,d;c=BD(b,677);d=c.pk();!d&&c.tk(d=new j2d(a,b));return d} +function QSd(a){if(!a.b){a.b=new UTd(a,j5,a);!a.a&&(a.a=new fTd(a,a))}return a.b} +function yTb(){yTb=ccb;wTb=new zTb('XY',0);vTb=new zTb('X',1);xTb=new zTb('Y',2)} +function EIb(){EIb=ccb;DIb=new FIb('TOP',0);CIb=new FIb(gle,1);BIb=new FIb(mle,2)} +function esc(){esc=ccb;csc=new fsc(ane,0);dsc=new fsc('TOP',1);bsc=new fsc(mle,2)} +function BAc(){BAc=ccb;zAc=new CAc('INPUT_ORDER',0);AAc=new CAc('PORT_DEGREE',1)} +function wD(){wD=ccb;sD=TC(Eje,Eje,524287);tD=TC(0,0,Gje);uD=RC(1);RC(2);vD=RC(0)} +function WDc(a,b,c){a.a.c=KC(SI,Uhe,1,0,5,1);$Dc(a,b,c);a.a.c.length==0||TDc(a,b)} +function rfb(a){var b,c;c=a.length;b=KC(TD,$ie,25,c,15,1);ffb(a,0,c,b,0);return b} +function Aid(a){var b;if(!a.dh()){b=aLd(a.Tg())-a.Ah();a.ph().bk(b)}return a.Pg()} +function xjd(a){var b;b=CD(Ajd(a,32));if(b==null){yjd(a);b=CD(Ajd(a,32))}return b} +function iid(a,b){var c;c=bLd(a.d,b);return c>=0?fid(a,c,true,true):sid(a,b,true)} +function vgc(a,b){qgc();var c,d;c=ugc(a);d=ugc(b);return !!c&&!!d&&!omb(c.k,d.k)} +function Gqd(a,b){dld(a,b==null||Ldb((uCb(b),b))||isNaN((uCb(b),b))?0:(uCb(b),b))} +function Hqd(a,b){eld(a,b==null||Ldb((uCb(b),b))||isNaN((uCb(b),b))?0:(uCb(b),b))} +function Iqd(a,b){cld(a,b==null||Ldb((uCb(b),b))||isNaN((uCb(b),b))?0:(uCb(b),b))} +function Jqd(a,b){ald(a,b==null||Ldb((uCb(b),b))||isNaN((uCb(b),b))?0:(uCb(b),b))} +function agd(a){(!this.q?(mmb(),mmb(),kmb):this.q).Ac(!a.q?(mmb(),mmb(),kmb):a.q)} +function S2d(a,b){return JD(b,99)&&(BD(b,18).Bb&Tje)!=0?new s4d(b,a):new p4d(b,a)} +function U2d(a,b){return JD(b,99)&&(BD(b,18).Bb&Tje)!=0?new s4d(b,a):new p4d(b,a)} +function INb(a,b){HNb=new tOb;FNb=b;GNb=a;BD(GNb.b,65);KNb(GNb,HNb,null);JNb(GNb)} +function uud(a,b,c){var d;d=a.g[b];mud(a,b,a.oi(b,c));a.gi(b,c,d);a.ci();return d} +function Ftd(a,b){var c;c=a.Xc(b);if(c>=0){a.$c(c);return true}else{return false}} +function YId(a){var b;if(a.d!=a.r){b=wId(a);a.e=!!b&&b.Cj()==Bve;a.d=b}return a.e} +function fr(a,b){var c;Qb(a);Qb(b);c=false;while(b.Ob()){c=c|a.Fc(b.Pb())}return c} +function Wrb(a,b){var c;c=BD(Ohb(a.e,b),387);if(c){Yrb(a,c);return c.e}return null} +function UA(a){var b,c;b=a/60|0;c=a%60;if(c==0){return ''+b}return ''+b+':'+(''+c)} +function LAb(a,b){var c,d;Uzb(a);d=new IBb(b,a.a);c=new fBb(d);return new YAb(a,c)} +function tB(d,a){var b=d.a[a];var c=(rC(),qC)[typeof b];return c?c(b):xC(typeof b)} +function yzc(a){switch(a.g){case 0:return Ohe;case 1:return -1;default:return 0;}} +function oD(a){if(eD(a,(wD(),vD))<0){return -aD(hD(a))}return a.l+a.m*Hje+a.h*Ije} +function HC(a){return a.__elementTypeCategory$==null?10:a.__elementTypeCategory$} +function dub(a){var b;b=a.b.c.length==0?null:Ikb(a.b,0);b!=null&&fub(a,0);return b} +function uA(a,b){while(b[0]<a.length&&hfb(' \t\r\n',wfb(bfb(a,b[0])))>=0){++b[0]}} +function sgb(a,b){this.e=b;this.a=vgb(a);this.a<54?(this.f=Sbb(a)):(this.c=ghb(a))} +function vge(a,b,c,d){wfe();xfe.call(this,26);this.c=a;this.a=b;this.d=c;this.b=d} +function EA(a,b,c){var d,e;d=10;for(e=0;e<c-1;e++){b<d&&(a.a+='0',a);d*=10}a.a+=b} +function Hhe(a,b){var c;c=0;while(a.e!=a.i.gc()){Qrd(b,Dyd(a),meb(c));c!=Ohe&&++c}} +function xHc(a,b){var c;++a.d;++a.c[b];c=b+1;while(c<a.a.length){++a.a[c];c+=c&-c}} +function Qgc(a,b){var c,d,e;e=b.c.i;c=BD(Ohb(a.f,e),57);d=c.d.c-c.e.c;p7c(b.a,d,0)} +function Scb(a){var b,c;b=a+128;c=(Ucb(),Tcb)[b];!c&&(c=Tcb[b]=new Mcb(a));return c} +function es(a,b){var c;uCb(b);c=a[':'+b];nCb(!!c,OC(GC(SI,1),Uhe,1,5,[b]));return c} +function Mz(a){var b,c;if(a.b){c=null;do{b=a.b;a.b=null;c=Pz(b,c)}while(a.b);a.b=c}} +function Lz(a){var b,c;if(a.a){c=null;do{b=a.a;a.a=null;c=Pz(b,c)}while(a.a);a.a=c}} +function Dqb(a){var b;++a.a;for(b=a.c.a.length;a.a<b;++a.a){if(a.c.b[a.a]){return}}} +function S9b(a,b){var c,d;d=b.c;for(c=d+1;c<=b.f;c++){a.a[c]>a.a[d]&&(d=c)}return d} +function fic(a,b){var c;c=Jy(a.e.c,b.e.c);if(c==0){return Kdb(a.e.d,b.e.d)}return c} +function Ogb(a,b){if(b.e==0){return Ggb}if(a.e==0){return Ggb}return Dhb(),Ehb(a,b)} +function nCb(a,b){if(!a){throw vbb(new Wdb(DCb('Enum constant undefined: %s',b)))}} +function AWb(){AWb=ccb;xWb=new XWb;yWb=new _Wb;vWb=new dXb;wWb=new hXb;zWb=new lXb} +function UEb(){UEb=ccb;SEb=new VEb('BY_SIZE',0);TEb=new VEb('BY_SIZE_AND_SHAPE',1)} +function XRb(){XRb=ccb;VRb=new YRb('EADES',0);WRb=new YRb('FRUCHTERMAN_REINGOLD',1)} +function xqc(){xqc=ccb;vqc=new yqc('READING_DIRECTION',0);wqc=new yqc('ROTATION',1)} +function uqc(){uqc=ccb;tqc=as((mqc(),OC(GC(IW,1),Kie,335,0,[iqc,hqc,kqc,lqc,jqc])))} +function bAc(){bAc=ccb;aAc=as((Vzc(),OC(GC(_W,1),Kie,315,0,[Uzc,Rzc,Szc,Qzc,Tzc])))} +function bkc(){bkc=ccb;akc=as((Xjc(),OC(GC(uV,1),Kie,363,0,[Tjc,Vjc,Wjc,Ujc,Sjc])))} +function Htc(){Htc=ccb;Gtc=as((Ctc(),OC(GC(TW,1),Kie,163,0,[Btc,xtc,ytc,ztc,Atc])))} +function S_c(){S_c=ccb;R_c=as((N_c(),OC(GC(Q_,1),Kie,316,0,[I_c,J_c,M_c,K_c,L_c])))} +function S5c(){S5c=ccb;R5c=as((N5c(),OC(GC(e1,1),Kie,175,0,[L5c,K5c,I5c,M5c,J5c])))} +function p$c(){p$c=ccb;o$c=as((k$c(),OC(GC(y_,1),Kie,355,0,[g$c,f$c,i$c,h$c,j$c])))} +function vUb(){vUb=ccb;uUb=as((qUb(),OC(GC(zP,1),Kie,356,0,[lUb,mUb,nUb,oUb,pUb])))} +function mad(){mad=ccb;lad=as((ead(),OC(GC(t1,1),Kie,103,0,[cad,bad,aad,_9c,dad])))} +function Ybd(){Ybd=ccb;Xbd=as((Tbd(),OC(GC(C1,1),Kie,249,0,[Qbd,Sbd,Obd,Pbd,Rbd])))} +function cdd(){cdd=ccb;bdd=as((Ucd(),OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd])))} +function _1c(a,b){var c;c=BD(Ohb(a.a,b),134);if(!c){c=new zNb;Rhb(a.a,b,c)}return c} +function hoc(a){var b;b=BD(vNb(a,(wtc(),usc)),305);if(b){return b.a==a}return false} +function ioc(a){var b;b=BD(vNb(a,(wtc(),usc)),305);if(b){return b.i==a}return false} +function Jub(a,b){uCb(b);Iub(a);if(a.d.Ob()){b.td(a.d.Pb());return true}return false} +function Oy(a){if(ybb(a,Ohe)>0){return Ohe}if(ybb(a,Rie)<0){return Rie}return Tbb(a)} +function Cv(a){if(a<3){Xj(a,Hie);return a+1}if(a<Iie){return QD(a/0.75+1)}return Ohe} +function XKd(a,b){var c;c=(a.i==null&&TKd(a),a.i);return b>=0&&b<c.length?c[b]:null} +function cC(a,b,c){var d;if(b==null){throw vbb(new Geb)}d=aC(a,b);dC(a,b,c);return d} +function Emc(a){a.a>=-0.01&&a.a<=ple&&(a.a=0);a.b>=-0.01&&a.b<=ple&&(a.b=0);return a} +function sfb(a,b){return b==(ntb(),ntb(),mtb)?a.toLocaleLowerCase():a.toLowerCase()} +function idb(a){return ((a.i&2)!=0?'interface ':(a.i&1)!=0?'':'class ')+(fdb(a),a.o)} +function Pnd(a){var b,c;c=(b=new SSd,b);wtd((!a.q&&(a.q=new cUd(n5,a,11,10)),a.q),c)} +function Pdd(a,b){var c;c=b>0?b-1:b;return Vdd(Wdd(Xdd(Ydd(new Zdd,c),a.n),a.j),a.k)} +function u2d(a,b,c,d){var e;a.j=-1;Qxd(a,I2d(a,b,c),(Q6d(),e=BD(b,66).Mj(),e.Ok(d)))} +function VWb(a){this.g=a;this.f=new Rkb;this.a=$wnd.Math.min(this.g.c.c,this.g.d.c)} +function mDb(a){this.b=new Rkb;this.a=new Rkb;this.c=new Rkb;this.d=new Rkb;this.e=a} +function Cnc(a,b){this.a=new Lqb;this.e=new Lqb;this.b=(xzc(),wzc);this.c=a;this.b=b} +function bIb(a,b,c){$Gb.call(this);THb(this);this.a=a;this.c=c;this.b=b.d;this.f=b.e} +function yd(a){this.d=a;this.c=a.c.vc().Kc();this.b=null;this.a=null;this.e=(hs(),gs)} +function zud(a){if(a<0){throw vbb(new Wdb('Illegal Capacity: '+a))}this.g=this.ri(a)} +function avb(a,b){if(0>a||a>b){throw vbb(new scb('fromIndex: 0, toIndex: '+a+oke+b))}} +function Gs(a){var b;if(a.a==a.b.a){throw vbb(new utb)}b=a.a;a.c=b;a.a=a.a.e;return b} +function Zsb(a){var b;yCb(!!a.c);b=a.c.a;Nsb(a.d,a.c);a.b==a.c?(a.b=b):--a.a;a.c=null} +function VAb(a,b){var c;Uzb(a);c=new lBb(a,a.a.rd(),a.a.qd()|4,b);return new YAb(a,c)} +function ke(a,b){var c,d;c=BD(Hv(a.d,b),14);if(!c){return null}d=b;return a.e.pc(d,c)} +function xac(a,b){var c,d;for(d=a.Kc();d.Ob();){c=BD(d.Pb(),70);yNb(c,(wtc(),Ssc),b)}} +function t9b(a){var b;b=Edb(ED(vNb(a,(Nyc(),Zwc))));if(b<0){b=0;yNb(a,Zwc,b)}return b} +function ifc(a,b,c){var d;d=$wnd.Math.max(0,a.b/2-0.5);cfc(c,d,1);Ekb(b,new rfc(c,d))} +function NMc(a,b,c){var d;d=a.a.e[BD(b.a,10).p]-a.a.e[BD(c.a,10).p];return QD(Eeb(d))} +function iZb(a,b,c,d,e,f){var g;g=kZb(d);QZb(g,e);RZb(g,f);Rc(a.a,d,new BZb(g,b,c.f))} +function Bid(a,b){var c;c=YKd(a.Tg(),b);if(!c){throw vbb(new Wdb(ite+b+lte))}return c} +function ntd(a,b){var c;c=a;while(Xod(c)){c=Xod(c);if(c==b){return true}}return false} +function Uw(a,b){var c,d,e;d=b.a.cd();c=BD(b.a.dd(),14).gc();for(e=0;e<c;e++){a.td(d)}} +function Hkb(a,b){var c,d,e,f;uCb(b);for(d=a.c,e=0,f=d.length;e<f;++e){c=d[e];b.td(c)}} +function Nsb(a,b){var c;c=b.c;b.a.b=b.b;b.b.a=b.a;b.a=b.b=null;b.c=null;--a.b;return c} +function wqb(a,b){if(!!b&&a.b[b.g]==b){NC(a.b,b.g,null);--a.c;return true}return false} +function lo(a,b){return !!vo(a,b,Tbb(Ibb(Eie,keb(Tbb(Ibb(b==null?0:tb(b),Fie)),15))))} +function w$b(a,b){ecd(BD(vNb(BD(a.e,10),(Nyc(),Vxc)),98))&&(mmb(),Okb(BD(a.e,10).j,b))} +function THb(a){a.b=(NHb(),KHb);a.f=(EIb(),CIb);a.d=(Xj(2,Jie),new Skb(2));a.e=new d7c} +function gHb(){gHb=ccb;dHb=new hHb('BEGIN',0);eHb=new hHb(gle,1);fHb=new hHb('END',2)} +function qad(){qad=ccb;nad=new rad(gle,0);oad=new rad('HEAD',1);pad=new rad('TAIL',2)} +function Fsd(){Csd();return OC(GC(O3,1),Kie,237,0,[Bsd,ysd,zsd,xsd,Asd,vsd,usd,wsd])} +function c6c(){_5c();return OC(GC(f1,1),Kie,277,0,[$5c,T5c,X5c,Z5c,U5c,V5c,W5c,Y5c])} +function Dlc(){Alc();return OC(GC(KV,1),Kie,270,0,[tlc,wlc,slc,zlc,vlc,ulc,ylc,xlc])} +function nAc(){kAc();return OC(GC(aX,1),Kie,260,0,[iAc,dAc,gAc,eAc,fAc,cAc,hAc,jAc])} +function kcd(){kcd=ccb;jcd=as((dcd(),OC(GC(D1,1),Kie,98,0,[ccd,bcd,acd,Zbd,_bd,$bd])))} +function tHb(){tHb=ccb;sHb=(gHb(),OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb])).length;rHb=sHb} +function wed(a){this.b=(Qb(a),new Tkb(a));this.a=new Rkb;this.d=new Rkb;this.e=new d7c} +function W6c(a){var b;b=$wnd.Math.sqrt(a.a*a.a+a.b*a.b);if(b>0){a.a/=b;a.b/=b}return a} +function bKd(a){var b;if(a.w){return a.w}else{b=cKd(a);!!b&&!b.kh()&&(a.w=b);return b}} +function gZd(a){var b;if(a==null){return null}else{b=BD(a,190);return Umd(b,b.length)}} +function qud(a,b){if(a.g==null||b>=a.i)throw vbb(new $zd(b,a.i));return a.li(b,a.g[b])} +function Mmc(a){var b,c;b=a.a.d.j;c=a.c.d.j;while(b!=c){rqb(a.b,b);b=Xcd(b)}rqb(a.b,b)} +function Jmc(a){var b;for(b=0;b<a.c.length;b++){(tCb(b,a.c.length),BD(a.c[b],11)).p=b}} +function bEc(a,b,c){var d,e,f;e=b[c];for(d=0;d<e.length;d++){f=e[d];a.e[f.c.p][f.p]=d}} +function ZEc(a,b){var c,d,e,f;for(d=a.d,e=0,f=d.length;e<f;++e){c=d[e];REc(a.g,c).a=b}} +function q7c(a,b){var c,d;for(d=Jsb(a,0);d.b!=d.d.c;){c=BD(Xsb(d),8);P6c(c,b)}return a} +function zUb(a,b){var c;c=c7c(R6c(BD(Ohb(a.g,b),8)),E6c(BD(Ohb(a.f,b),460).b));return c} +function lib(a){var b;xpb(a.e,a);sCb(a.b);a.c=a.a;b=BD(a.a.Pb(),42);a.b=kib(a);return b} +function CD(a){var b;CCb(a==null||Array.isArray(a)&&(b=HC(a),!(b>=14&&b<=16)));return a} +function dcb(a,b,c){var d=function(){return a.apply(d,arguments)};b.apply(d,c);return d} +function TLc(a,b,c){var d,e;d=b;do{e=Edb(a.p[d.p])+c;a.p[d.p]=e;d=a.a[d.p]}while(d!=b)} +function NQd(a,b){var c,d;d=a.a;c=OQd(a,b,null);d!=b&&!a.e&&(c=QQd(a,b,c));!!c&&c.Fi()} +function ADb(a,b){return Iy(),My(Qie),$wnd.Math.abs(a-b)<=Qie||a==b||isNaN(a)&&isNaN(b)} +function Ky(a,b){Iy();My(Qie);return $wnd.Math.abs(a-b)<=Qie||a==b||isNaN(a)&&isNaN(b)} +function Akc(a,b){gkc();return beb(a.b.c.length-a.e.c.length,b.b.c.length-b.e.c.length)} +function oo(a,b){return Kv(uo(a,b,Tbb(Ibb(Eie,keb(Tbb(Ibb(b==null?0:tb(b),Fie)),15)))))} +function o0b(){o0b=ccb;n0b=as((j0b(),OC(GC(NQ,1),Kie,267,0,[h0b,g0b,e0b,i0b,f0b,d0b])))} +function n8c(){n8c=ccb;m8c=as((i8c(),OC(GC(r1,1),Kie,291,0,[h8c,g8c,f8c,d8c,c8c,e8c])))} +function K7c(){K7c=ccb;J7c=as((F7c(),OC(GC(o1,1),Kie,248,0,[z7c,C7c,D7c,E7c,A7c,B7c])))} +function Fpc(){Fpc=ccb;Epc=as((Apc(),OC(GC(EW,1),Kie,227,0,[wpc,ypc,vpc,xpc,zpc,upc])))} +function Drc(){Drc=ccb;Crc=as((yrc(),OC(GC(OW,1),Kie,275,0,[wrc,trc,xrc,vrc,urc,rrc])))} +function qrc(){qrc=ccb;prc=as((lrc(),OC(GC(NW,1),Kie,274,0,[irc,hrc,krc,grc,jrc,frc])))} +function tzc(){tzc=ccb;szc=as((lzc(),OC(GC(YW,1),Kie,313,0,[jzc,hzc,fzc,gzc,kzc,izc])))} +function Yqc(){Yqc=ccb;Xqc=as((Sqc(),OC(GC(LW,1),Kie,276,0,[Nqc,Mqc,Pqc,Oqc,Rqc,Qqc])))} +function wSc(){wSc=ccb;vSc=as((qSc(),OC(GC(t$,1),Kie,327,0,[pSc,lSc,nSc,mSc,oSc,kSc])))} +function ycd(){ycd=ccb;xcd=as((rcd(),OC(GC(E1,1),Kie,273,0,[pcd,ncd,ocd,mcd,lcd,qcd])))} +function Rad(){Rad=ccb;Qad=as((Mad(),OC(GC(w1,1),Kie,312,0,[Kad,Iad,Lad,Gad,Jad,Had])))} +function Lbd(){Hbd();return OC(GC(B1,1),Kie,93,0,[zbd,ybd,Bbd,Gbd,Fbd,Ebd,Cbd,Dbd,Abd])} +function vkd(a,b){var c;c=a.a;a.a=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,0,c,a.a))} +function wkd(a,b){var c;c=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,1,c,a.b))} +function hmd(a,b){var c;c=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,3,c,a.b))} +function ald(a,b){var c;c=a.f;a.f=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,3,c,a.f))} +function cld(a,b){var c;c=a.g;a.g=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,4,c,a.g))} +function dld(a,b){var c;c=a.i;a.i=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,5,c,a.i))} +function eld(a,b){var c;c=a.j;a.j=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,6,c,a.j))} +function omd(a,b){var c;c=a.j;a.j=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,1,c,a.j))} +function imd(a,b){var c;c=a.c;a.c=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,4,c,a.c))} +function pmd(a,b){var c;c=a.k;a.k=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new lSd(a,2,c,a.k))} +function qQd(a,b){var c;c=a.d;a.d=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new mSd(a,2,c,a.d))} +function AId(a,b){var c;c=a.s;a.s=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new mSd(a,4,c,a.s))} +function DId(a,b){var c;c=a.t;a.t=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new mSd(a,5,c,a.t))} +function _Jd(a,b){var c;c=a.F;a.F=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,5,c,b))} +function izd(a,b){var c;c=BD(Ohb((pEd(),oEd),a),55);return c?c.xj(b):KC(SI,Uhe,1,b,5,1)} +function Xpd(a,b){var c,d;c=b in a.a;if(c){d=aC(a,b).he();if(d){return d.a}}return null} +function ftd(a,b){var c,d,e;c=(d=(Fhd(),e=new Jod,e),!!b&&God(d,b),d);Hod(c,a);return c} +function LLd(a,b,c){Itd(a,c);if(!a.Bk()&&c!=null&&!a.wj(c)){throw vbb(new tcb)}return c} +function Xdd(a,b){a.n=b;if(a.n){a.f=new Rkb;a.e=new Rkb}else{a.f=null;a.e=null}return a} +function ndb(a,b,c,d,e,f){var g;g=ldb(a,b);zdb(c,g);g.i=e?8:0;g.f=d;g.e=e;g.g=f;return g} +function rSd(a,b,c,d,e){this.d=b;this.k=d;this.f=e;this.o=-1;this.p=1;this.c=a;this.a=c} +function tSd(a,b,c,d,e){this.d=b;this.k=d;this.f=e;this.o=-1;this.p=2;this.c=a;this.a=c} +function BSd(a,b,c,d,e){this.d=b;this.k=d;this.f=e;this.o=-1;this.p=6;this.c=a;this.a=c} +function GSd(a,b,c,d,e){this.d=b;this.k=d;this.f=e;this.o=-1;this.p=7;this.c=a;this.a=c} +function xSd(a,b,c,d,e){this.d=b;this.j=d;this.e=e;this.o=-1;this.p=4;this.c=a;this.a=c} +function rDb(a,b){var c,d,e,f;for(d=b,e=0,f=d.length;e<f;++e){c=d[e];nDb(a.a,c)}return a} +function pl(a){var b,c,d,e;for(c=a,d=0,e=c.length;d<e;++d){b=c[d];Qb(b)}return new vl(a)} +function Uz(a){var b=/function(?:\s+([\w$]+))?\s*\(/;var c=b.exec(a);return c&&c[1]||Xie} +function zdb(a,b){var c;if(!a){return}b.n=a;var d=tdb(b);if(!d){_bb[a]=[b];return}d.gm=b} +function vlb(a,b,c){var d,e;e=a.length;d=$wnd.Math.min(c,e);$Bb(a,0,b,0,d,true);return b} +function RPb(a,b,c){var d,e;for(e=b.Kc();e.Ob();){d=BD(e.Pb(),79);Qqb(a,BD(c.Kb(d),33))}} +function Xbb(){Ybb();var a=Wbb;for(var b=0;b<arguments.length;b++){a.push(arguments[b])}} +function n7c(a,b){var c,d,e,f;for(d=b,e=0,f=d.length;e<f;++e){c=d[e];Gsb(a,c,a.c.b,a.c)}} +function s$c(a,b){a.b=$wnd.Math.max(a.b,b.d);a.e+=b.r+(a.a.c.length==0?0:a.c);Ekb(a.a,b)} +function wkb(a){yCb(a.c>=0);if(ekb(a.d,a.c)<0){a.a=a.a-1&a.d.a.length-1;a.b=a.d.c}a.c=-1} +function pgb(a){if(a.a<54){return a.f<0?-1:a.f>0?1:0}return (!a.c&&(a.c=fhb(a.f)),a.c).e} +function My(a){if(!(a>=0)){throw vbb(new Wdb('tolerance ('+a+') must be >= 0'))}return a} +function n4c(){if(!f4c){f4c=new m4c;l4c(f4c,OC(GC(C0,1),Uhe,130,0,[new Z9c]))}return f4c} +function KAc(){KAc=ccb;JAc=new LAc(ole,0);HAc=new LAc('INPUT',1);IAc=new LAc('OUTPUT',2)} +function bqc(){bqc=ccb;$pc=new cqc('ARD',0);aqc=new cqc('MSD',1);_pc=new cqc('MANUAL',2)} +function rGc(){rGc=ccb;oGc=new sGc('BARYCENTER',0);pGc=new sGc(Bne,1);qGc=new sGc(Cne,2)} +function ztd(a,b){var c;c=a.gc();if(b<0||b>c)throw vbb(new Cyd(b,c));return new czd(a,b)} +function JAd(a,b){var c;if(JD(b,42)){return a.c.Mc(b)}else{c=qAd(a,b);LAd(a,b);return c}} +function $nd(a,b,c){yId(a,b);pnd(a,c);AId(a,0);DId(a,1);CId(a,true);BId(a,true);return a} +function Xj(a,b){if(a<0){throw vbb(new Wdb(b+' cannot be negative but was: '+a))}return a} +function Bt(a,b){var c,d;for(c=0,d=a.gc();c<d;++c){if(wtb(b,a.Xb(c))){return c}}return -1} +function Nc(a){var b,c;for(c=a.c.Cc().Kc();c.Ob();){b=BD(c.Pb(),14);b.$b()}a.c.$b();a.d=0} +function Ri(a){var b,c,d,e;for(c=a.a,d=0,e=c.length;d<e;++d){b=c[d];Flb(b,b.length,null)}} +function ieb(a){var b,c;if(a==0){return 32}else{c=0;for(b=1;(b&a)==0;b<<=1){++c}return c}} +function NGb(a){var b,c;for(c=new olb(ahd(a));c.a<c.c.c.length;){b=BD(mlb(c),680);b.Gf()}} +function CUb(a){xUb();this.g=new Lqb;this.f=new Lqb;this.b=new Lqb;this.c=new Hp;this.i=a} +function XZb(){this.f=new d7c;this.d=new s0b;this.c=new d7c;this.a=new Rkb;this.b=new Rkb} +function c6d(a,b,c,d){this.rj();this.a=b;this.b=a;this.c=null;this.c=new d6d(this,b,c,d)} +function nxd(a,b,c,d,e){this.d=a;this.n=b;this.g=c;this.o=d;this.p=-1;e||(this.o=-2-d-1)} +function hJd(){FId.call(this);this.n=-1;this.g=null;this.i=null;this.j=null;this.Bb|=zte} +function Ldd(){Idd();return OC(GC(J1,1),Kie,259,0,[Bdd,Ddd,Add,Edd,Fdd,Hdd,Gdd,Cdd,zdd])} +function uFb(){rFb();return OC(GC(dN,1),Kie,250,0,[qFb,lFb,mFb,kFb,oFb,pFb,nFb,jFb,iFb])} +function qeb(){qeb=ccb;peb=OC(GC(WD,1),oje,25,15,[0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15])} +function vCc(){vCc=ccb;uCc=e3c(e3c(e3c(new j3c,(qUb(),lUb),(S8b(),Z7b)),mUb,w8b),nUb,v8b)} +function VCc(){VCc=ccb;UCc=e3c(e3c(e3c(new j3c,(qUb(),lUb),(S8b(),Z7b)),mUb,w8b),nUb,v8b)} +function rDc(){rDc=ccb;qDc=e3c(e3c(e3c(new j3c,(qUb(),lUb),(S8b(),Z7b)),mUb,w8b),nUb,v8b)} +function yFc(){yFc=ccb;xFc=c3c(e3c(e3c(new j3c,(qUb(),nUb),(S8b(),z8b)),oUb,p8b),pUb,y8b)} +function Rpc(){Rpc=ccb;Ppc=new Tpc('LAYER_SWEEP',0);Opc=new Tpc(Tne,1);Qpc=new Tpc(ane,2)} +function RLc(a,b){var c,d;c=a.c;d=b.e[a.p];if(d>0){return BD(Ikb(c.a,d-1),10)}return null} +function Lkd(a,b){var c;c=a.k;a.k=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,2,c,a.k))} +function kmd(a,b){var c;c=a.f;a.f=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,8,c,a.f))} +function lmd(a,b){var c;c=a.i;a.i=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,7,c,a.i))} +function Hod(a,b){var c;c=a.a;a.a=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,8,c,a.a))} +function zpd(a,b){var c;c=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,0,c,a.b))} +function UUd(a,b){var c;c=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,0,c,a.b))} +function VUd(a,b){var c;c=a.c;a.c=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,1,c,a.c))} +function Apd(a,b){var c;c=a.c;a.c=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,1,c,a.c))} +function pQd(a,b){var c;c=a.c;a.c=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,4,c,a.c))} +function PHd(a,b){var c;c=a.d;a.d=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,1,c,a.d))} +function jKd(a,b){var c;c=a.D;a.D=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,2,c,a.D))} +function Rdd(a,b){if(a.r>0&&a.c<a.r){a.c+=b;!!a.i&&a.i.d>0&&a.g!=0&&Rdd(a.i,b/a.r*a.i.d)}} +function dge(a,b,c){var d;a.b=b;a.a=c;d=(a.a&512)==512?new hee:new ude;a.c=ode(d,a.b,a.a)} +function g3d(a,b){return T6d(a.e,b)?(Q6d(),YId(b)?new R7d(b,a):new f7d(b,a)):new c8d(b,a)} +function _o(a,b){return Fv(vo(a.a,b,Tbb(Ibb(Eie,keb(Tbb(Ibb(b==null?0:tb(b),Fie)),15)))))} +function Nyb(a,b,c){return Ayb(a,new Kzb(b),new Mzb,new Ozb(c),OC(GC(xL,1),Kie,132,0,[]))} +function pAb(a){var b,c;if(0>a){return new yAb}b=a+1;c=new rAb(b,a);return new vAb(null,c)} +function umb(a,b){mmb();var c;c=new Mqb(1);ND(a)?Shb(c,a,b):jrb(c.f,a,b);return new iob(c)} +function aMb(a,b){var c,d;c=a.o+a.p;d=b.o+b.p;if(c<d){return -1}if(c==d){return 0}return 1} +function P2b(a){var b;b=vNb(a,(wtc(),$sc));if(JD(b,160)){return O2b(BD(b,160))}return null} +function Kp(a){var b;a=$wnd.Math.max(a,2);b=geb(a);if(a>b){b<<=1;return b>0?b:Iie}return b} +function xc(a){Ub(a.e!=3);switch(a.e){case 2:return false;case 0:return true;}return zc(a)} +function T6c(a,b){var c;if(JD(b,8)){c=BD(b,8);return a.a==c.a&&a.b==c.b}else{return false}} +function _Mb(a,b,c){var d,e,f;f=b>>5;e=b&31;d=xbb(Pbb(a.n[c][f],Tbb(Nbb(e,1))),3);return d} +function IAd(a,b){var c,d;for(d=b.vc().Kc();d.Ob();){c=BD(d.Pb(),42);HAd(a,c.cd(),c.dd())}} +function N1c(a,b){var c;c=new tOb;BD(b.b,65);BD(b.b,65);BD(b.b,65);Hkb(b.a,new T1c(a,c,b))} +function DUd(a,b){var c;c=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,21,c,a.b))} +function jmd(a,b){var c;c=a.d;a.d=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,11,c,a.d))} +function _Id(a,b){var c;c=a.j;a.j=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,13,c,a.j))} +function $jb(a,b,c){var d,e,f;f=a.a.length-1;for(e=a.b,d=0;d<c;e=e+1&f,++d){NC(b,d,a.a[e])}} +function rqb(a,b){var c;uCb(b);c=b.g;if(!a.b[c]){NC(a.b,c,b);++a.c;return true}return false} +function eub(a,b){var c;c=b==null?-1:Jkb(a.b,b,0);if(c<0){return false}fub(a,c);return true} +function fub(a,b){var c;c=Kkb(a.b,a.b.c.length-1);if(b<a.b.c.length){Nkb(a.b,b,c);bub(a,b)}} +function eyb(a,b){((oyb(),lyb)?null:b.c).length==0&&qyb(b,new zyb);Shb(a.a,lyb?null:b.c,b)} +function M5b(a,b){Odd(b,'Hierarchical port constraint processing',1);N5b(a);P5b(a);Qdd(b)} +function GOb(a,b){var c,d;for(d=b.Kc();d.Ob();){c=BD(d.Pb(),266);a.b=true;Qqb(a.e,c);c.b=a}} +function Owb(a,b){var c,d;c=1-b;d=a.a[c];a.a[c]=d.a[b];d.a[b]=a;a.b=true;d.b=false;return d} +function Gec(a,b){var c,d;c=BD(vNb(a,(Nyc(),ayc)),8);d=BD(vNb(b,ayc),8);return Kdb(c.b,d.b)} +function jfc(a){oEb.call(this);this.b=Edb(ED(vNb(a,(Nyc(),lyc))));this.a=BD(vNb(a,Swc),218)} +function XGc(a,b,c){uEc.call(this,a,b,c);this.a=new Lqb;this.b=new Lqb;this.d=new $Gc(this)} +function ku(a){this.e=a;this.d=new Uqb(Cv(Ec(this.e).gc()));this.c=this.e.a;this.b=this.e.c} +function BHc(a){this.b=a;this.a=KC(WD,oje,25,a+1,15,1);this.c=KC(WD,oje,25,a,15,1);this.d=0} +function THc(a,b,c){var d;d=new Rkb;UHc(a,b,d,c,true,true);a.b=new BHc(d.c.length);return d} +function nMc(a,b){var c;c=BD(Ohb(a.c,b),458);if(!c){c=new uMc;c.c=b;Rhb(a.c,c.c,c)}return c} +function $B(e,a){var b=e.a;var c=0;for(var d in b){b.hasOwnProperty(d)&&(a[c++]=d)}return a} +function pRd(a){var b;if(a.b==null){return LRd(),LRd(),KRd}b=a.Lk()?a.Kk():a.Jk();return b} +function r$c(a){var b,c;for(c=new Fyd(a);c.e!=c.i.gc();){b=BD(Dyd(c),33);dld(b,0);eld(b,0)}} +function HSb(){HSb=ccb;FSb=new Lsd(Ime);GSb=new Lsd(Jme);ESb=new Lsd(Kme);DSb=new Lsd(Lme)} +function y5b(){y5b=ccb;x5b=new z5b('TO_INTERNAL_LTR',0);w5b=new z5b('TO_INPUT_DIRECTION',1)} +function PUc(){PUc=ccb;NUc=new RUc('P1_NODE_PLACEMENT',0);OUc=new RUc('P2_EDGE_ROUTING',1)} +function Fkc(){Fkc=ccb;Ekc=new Gkc('START',0);Dkc=new Gkc('MIDDLE',1);Ckc=new Gkc('END',2)} +function I9b(){I9b=ccb;H9b=new Msd('edgelabelcenterednessanalysis.includelabel',(Bcb(),zcb))} +function Zyc(a,b){MAb(JAb(new YAb(null,new Kub(new Pib(a.b),1)),new bfd(a,b)),new ffd(a,b))} +function $Xc(){this.c=new jVc(0);this.b=new jVc(Tqe);this.d=new jVc(Sqe);this.a=new jVc(cme)} +function $Fc(a){var b,c;for(c=a.c.a.ec().Kc();c.Ob();){b=BD(c.Pb(),214);eFc(b,new oHc(b.e))}} +function ZFc(a){var b,c;for(c=a.c.a.ec().Kc();c.Ob();){b=BD(c.Pb(),214);dFc(b,new nHc(b.f))}} +function pnd(a,b){var c;c=a.zb;a.zb=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,1,c,a.zb))} +function cod(a,b){var c;c=a.xb;a.xb=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,3,c,a.xb))} +function dod(a,b){var c;c=a.yb;a.yb=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,2,c,a.yb))} +function Knd(a,b){var c,d;c=(d=new OJd,d);c.n=b;wtd((!a.s&&(a.s=new cUd(t5,a,21,17)),a.s),c)} +function Qnd(a,b){var c,d;d=(c=new FUd,c);d.n=b;wtd((!a.s&&(a.s=new cUd(t5,a,21,17)),a.s),d)} +function ktb(a,b){var c,d;c=a.Pc();Klb(c,0,c.length,b);for(d=0;d<c.length;d++){a._c(d,c[d])}} +function ye(a,b){var c,d,e;uCb(b);c=false;for(e=b.Kc();e.Ob();){d=e.Pb();c=c|a.Fc(d)}return c} +function Bx(a){var b,c,d;b=0;for(d=a.Kc();d.Ob();){c=d.Pb();b+=c!=null?tb(c):0;b=~~b}return b} +function SA(a){var b;if(a==0){return 'UTC'}if(a<0){a=-a;b='UTC+'}else{b='UTC-'}return b+UA(a)} +function Jq(a,b){var c;if(JD(b,14)){c=BD(b,14);return a.Gc(c)}return fr(a,BD(Qb(b),20).Kc())} +function Bnc(a,b,c){Cnc.call(this,b,c);this.d=KC(OQ,kne,10,a.a.c.length,0,1);Qkb(a.a,this.d)} +function IMc(a){a.a=null;a.e=null;a.b.c=KC(SI,Uhe,1,0,5,1);a.f.c=KC(SI,Uhe,1,0,5,1);a.c=null} +function gKd(a,b){if(b){if(a.B==null){a.B=a.D;a.D=null}}else if(a.B!=null){a.D=a.B;a.B=null}} +function Poc(a,b){return Edb(ED(Btb(TAb(NAb(new YAb(null,new Kub(a.c.b,16)),new fpc(a)),b))))} +function Soc(a,b){return Edb(ED(Btb(TAb(NAb(new YAb(null,new Kub(a.c.b,16)),new dpc(a)),b))))} +function Q2b(a,b){Odd(b,zne,1);MAb(LAb(new YAb(null,new Kub(a.b,16)),new U2b),new W2b);Qdd(b)} +function SXc(a,b){var c,d;c=BD(hkd(a,(ZWc(),SWc)),19);d=BD(hkd(b,SWc),19);return beb(c.a,d.a)} +function p7c(a,b,c){var d,e;for(e=Jsb(a,0);e.b!=e.d.c;){d=BD(Xsb(e),8);d.a+=b;d.b+=c}return a} +function uo(a,b,c){var d;for(d=a.b[c&a.f];d;d=d.b){if(c==d.a&&Hb(b,d.g)){return d}}return null} +function vo(a,b,c){var d;for(d=a.c[c&a.f];d;d=d.d){if(c==d.f&&Hb(b,d.i)){return d}}return null} +function khb(a,b,c){var d,e,f;d=0;for(e=0;e<c;e++){f=b[e];a[e]=f<<1|d;d=f>>>31}d!=0&&(a[c]=d)} +function rmb(a,b){mmb();var c,d;d=new Rkb;for(c=0;c<a;++c){d.c[d.c.length]=b}return new Yob(d)} +function Zzb(a){var b;b=Yzb(a);if(Bbb(b.a,0)){return Ltb(),Ltb(),Ktb}return Ltb(),new Ptb(b.b)} +function $zb(a){var b;b=Yzb(a);if(Bbb(b.a,0)){return Ltb(),Ltb(),Ktb}return Ltb(),new Ptb(b.c)} +function uAb(a){var b;b=tAb(a);if(Bbb(b.a,0)){return Utb(),Utb(),Ttb}return Utb(),new Xtb(b.b)} +function zZb(a){if(a.b.c.i.k==(j0b(),e0b)){return BD(vNb(a.b.c.i,(wtc(),$sc)),11)}return a.b.c} +function AZb(a){if(a.b.d.i.k==(j0b(),e0b)){return BD(vNb(a.b.d.i,(wtc(),$sc)),11)}return a.b.d} +function Vnd(a,b,c,d,e,f,g,h,i,j,k,l,m){aod(a,b,c,d,e,f,g,h,i,j,k,l,m);MJd(a,false);return a} +function tJb(a,b,c,d,e,f,g){$r.call(this,a,b);this.d=c;this.e=d;this.c=e;this.b=f;this.a=Ou(g)} +function $bb(a,b){typeof window===Jhe&&typeof window['$gwt']===Jhe&&(window['$gwt'][a]=b)} +function pWb(a,b){lWb();return a==hWb&&b==kWb||a==kWb&&b==hWb||a==jWb&&b==iWb||a==iWb&&b==jWb} +function qWb(a,b){lWb();return a==hWb&&b==iWb||a==hWb&&b==jWb||a==kWb&&b==jWb||a==kWb&&b==iWb} +function IJb(a,b){return Iy(),My(ple),$wnd.Math.abs(0-b)<=ple||0==b||isNaN(0)&&isNaN(b)?0:a/b} +function Rrc(){Orc();return OC(GC(PW,1),Kie,256,0,[Frc,Hrc,Irc,Jrc,Krc,Lrc,Nrc,Erc,Grc,Mrc])} +function NKd(){NKd=ccb;KKd=new KPd;MKd=OC(GC(t5,1),Mve,170,0,[]);LKd=OC(GC(n5,1),Nve,59,0,[])} +function CBc(){CBc=ccb;BBc=new DBc('NO',0);zBc=new DBc('GREEDY',1);ABc=new DBc('LOOK_BACK',2)} +function z0b(){z0b=ccb;w0b=new m1b;u0b=new h1b;v0b=new q1b;t0b=new u1b;x0b=new y1b;y0b=new C1b} +function J9b(a){var b,c,d;d=0;for(c=new olb(a.b);c.a<c.c.c.length;){b=BD(mlb(c),29);b.p=d;++d}} +function nfd(a,b){var c;c=sfd(a);return mfd(new f7c(c.c,c.d),new f7c(c.b,c.a),a.rf(),b,a.Hf())} +function Udd(a,b){var c;if(a.b){return null}else{c=Pdd(a,a.g);Dsb(a.a,c);c.i=a;a.d=b;return c}} +function kUc(a,b,c){Odd(c,'DFS Treeifying phase',1);jUc(a,b);hUc(a,b);a.a=null;a.b=null;Qdd(c)} +function zic(a,b,c){this.g=a;this.d=b;this.e=c;this.a=new Rkb;xic(this);mmb();Okb(this.a,null)} +function Aud(a){this.i=a.gc();if(this.i>0){this.g=this.ri(this.i+(this.i/8|0)+1);a.Qc(this.g)}} +function u3d(a,b){k2d.call(this,D9,a,b);this.b=this;this.a=S6d(a.Tg(),XKd(this.e.Tg(),this.c))} +function Ld(a,b){var c,d;uCb(b);for(d=b.vc().Kc();d.Ob();){c=BD(d.Pb(),42);a.zc(c.cd(),c.dd())}} +function G2d(a,b,c){var d;for(d=c.Kc();d.Ob();){if(!E2d(a,b,d.Pb())){return false}}return true} +function sVd(a,b,c,d,e){var f;if(c){f=bLd(b.Tg(),a.c);e=c.gh(b,-1-(f==-1?d:f),null,e)}return e} +function tVd(a,b,c,d,e){var f;if(c){f=bLd(b.Tg(),a.c);e=c.ih(b,-1-(f==-1?d:f),null,e)}return e} +function Mgb(a){var b;if(a.b==-2){if(a.e==0){b=-1}else{for(b=0;a.a[b]==0;b++);}a.b=b}return a.b} +function Z4b(a){switch(a.g){case 2:return Ucd(),Tcd;case 4:return Ucd(),zcd;default:return a;}} +function $4b(a){switch(a.g){case 1:return Ucd(),Rcd;case 3:return Ucd(),Acd;default:return a;}} +function nkc(a){var b,c,d;return a.j==(Ucd(),Acd)&&(b=pkc(a),c=uqb(b,zcd),d=uqb(b,Tcd),d||d&&c)} +function oqb(a){var b,c;b=BD(a.e&&a.e(),9);c=BD(ZBb(b,b.length),9);return new xqb(b,c,b.length)} +function l7b(a,b){Odd(b,zne,1);UGb(TGb(new YGb((a$b(),new l$b(a,false,false,new T$b)))));Qdd(b)} +function Fcb(a,b){Bcb();return ND(a)?cfb(a,GD(b)):LD(a)?Ddb(a,ED(b)):KD(a)?Dcb(a,DD(b)):a.wd(b)} +function WZc(a,b){b.q=a;a.d=$wnd.Math.max(a.d,b.r);a.b+=b.d+(a.a.c.length==0?0:a.c);Ekb(a.a,b)} +function m6c(a,b){var c,d,e,f;e=a.c;c=a.c+a.b;f=a.d;d=a.d+a.a;return b.a>e&&b.a<c&&b.b>f&&b.b<d} +function Ynd(a,b,c,d){JD(a.Cb,179)&&(BD(a.Cb,179).tb=null);pnd(a,c);!!b&&hKd(a,b);d&&a.xk(true)} +function Yqd(a,b){var c;c=BD(b,183);Spd(c,'x',a.i);Spd(c,'y',a.j);Spd(c,Gte,a.g);Spd(c,Fte,a.f)} +function LFc(){LFc=ccb;KFc=b3c(f3c(e3c(e3c(new j3c,(qUb(),nUb),(S8b(),z8b)),oUb,p8b),pUb),y8b)} +function dHc(){dHc=ccb;cHc=b3c(f3c(e3c(e3c(new j3c,(qUb(),nUb),(S8b(),z8b)),oUb,p8b),pUb),y8b)} +function sXc(){sXc=ccb;qXc=new uXc(ane,0);rXc=new uXc('POLAR_COORDINATE',1);pXc=new uXc('ID',2)} +function TAc(){TAc=ccb;QAc=new UAc('EQUALLY',0);RAc=new UAc(xle,1);SAc=new UAc('NORTH_SOUTH',2)} +function pAc(){pAc=ccb;oAc=as((kAc(),OC(GC(aX,1),Kie,260,0,[iAc,dAc,gAc,eAc,fAc,cAc,hAc,jAc])))} +function Flc(){Flc=ccb;Elc=as((Alc(),OC(GC(KV,1),Kie,270,0,[tlc,wlc,slc,zlc,vlc,ulc,ylc,xlc])))} +function e6c(){e6c=ccb;d6c=as((_5c(),OC(GC(f1,1),Kie,277,0,[$5c,T5c,X5c,Z5c,U5c,V5c,W5c,Y5c])))} +function Hsd(){Hsd=ccb;Gsd=as((Csd(),OC(GC(O3,1),Kie,237,0,[Bsd,ysd,zsd,xsd,Asd,vsd,usd,wsd])))} +function XNb(){XNb=ccb;VNb=new Msd('debugSVG',(Bcb(),false));WNb=new Msd('overlapsExisted',true)} +function Xyb(a,b){return Ayb(new tzb(a),new vzb(b),new xzb(b),new zzb,OC(GC(xL,1),Kie,132,0,[]))} +function hyb(){var a;if(!dyb){dyb=new gyb;a=new wyb('');uyb(a,($xb(),Zxb));eyb(dyb,a)}return dyb} +function hr(a,b){var c;Qb(b);while(a.Ob()){c=a.Pb();if(!QNc(BD(c,10))){return false}}return true} +function T3c(a,b){var c;c=h4c(n4c(),a);if(c){jkd(b,(Y9c(),F9c),c);return true}else{return false}} +function d3c(a,b){var c;for(c=0;c<b.j.c.length;c++){BD(B2c(a,c),21).Gc(BD(B2c(b,c),14))}return a} +function M9b(a,b){var c,d;for(d=new olb(b.b);d.a<d.c.c.length;){c=BD(mlb(d),29);a.a[c.p]=_$b(c)}} +function stb(a,b){var c,d;uCb(b);for(d=a.vc().Kc();d.Ob();){c=BD(d.Pb(),42);b.Od(c.cd(),c.dd())}} +function cId(a,b){var c;if(JD(b,83)){BD(a.c,76).Xj();c=BD(b,83);IAd(a,c)}else{BD(a.c,76).Wb(b)}} +function Su(a){return JD(a,152)?km(BD(a,152)):JD(a,131)?BD(a,131).a:JD(a,54)?new ov(a):new dv(a)} +function fac(a,b){return b<a.b.gc()?BD(a.b.Xb(b),10):b==a.b.gc()?a.a:BD(Ikb(a.e,b-a.b.gc()-1),10)} +function crb(a,b){a.a=wbb(a.a,1);a.c=$wnd.Math.min(a.c,b);a.b=$wnd.Math.max(a.b,b);a.d=wbb(a.d,b)} +function n3b(a,b){var c;Odd(b,'Edge and layer constraint edge reversal',1);c=m3b(a);l3b(c);Qdd(b)} +function tAd(a){var b;if(a.d==null){++a.e;a.f=0;sAd(null)}else{++a.e;b=a.d;a.d=null;a.f=0;sAd(b)}} +function zbb(a){var b;b=a.h;if(b==0){return a.l+a.m*Hje}if(b==Fje){return a.l+a.m*Hje-Ije}return a} +function aKb(a){$Jb();if(a.A.Hc((tdd(),pdd))){if(!a.B.Hc((Idd(),Ddd))){return _Jb(a)}}return null} +function Zgb(a){uCb(a);if(a.length==0){throw vbb(new Oeb('Zero length BigInteger'))}dhb(this,a)} +function Vb(a){if(!a){throw vbb(new Zdb('no calls to next() since the last call to remove()'))}} +function Cbb(a){if(Kje<a&&a<Ije){return a<0?$wnd.Math.ceil(a):$wnd.Math.floor(a)}return zbb(fD(a))} +function Yyb(a,b){var c,d,e;c=a.c.Ee();for(e=b.Kc();e.Ob();){d=e.Pb();a.a.Od(c,d)}return a.b.Kb(c)} +function Uhd(a,b){var c,d,e;c=a.Jg();if(c!=null&&a.Mg()){for(d=0,e=c.length;d<e;++d){c[d].ui(b)}}} +function f_b(a,b){var c,d;c=a;d=Q_b(c).e;while(d){c=d;if(c==b){return true}d=Q_b(c).e}return false} +function lDc(a,b,c){var d,e;d=a.a.f[b.p];e=a.a.f[c.p];if(d<e){return -1}if(d==e){return 0}return 1} +function Si(a,b,c){var d,e;e=BD(tn(a.d,b),19);d=BD(tn(a.b,c),19);return !e||!d?null:Mi(a,e.a,d.a)} +function cYc(a,b){var c,d;for(d=new Fyd(a);d.e!=d.i.gc();){c=BD(Dyd(d),33);bld(c,c.i+b.b,c.j+b.d)}} +function qjc(a,b){var c,d;for(d=new olb(b);d.a<d.c.c.length;){c=BD(mlb(d),70);Ekb(a.d,c);ujc(a,c)}} +function pQc(a,b){var c,d;d=new Rkb;c=b;do{d.c[d.c.length]=c;c=BD(Ohb(a.k,c),17)}while(c);return d} +function Ajd(a,b){var c;if((a.Db&b)!=0){c=zjd(a,b);return c==-1?a.Eb:CD(a.Eb)[c]}else{return null}} +function Lnd(a,b){var c,d;c=(d=new hLd,d);c.G=b;!a.rb&&(a.rb=new jUd(a,d5,a));wtd(a.rb,c);return c} +function Mnd(a,b){var c,d;c=(d=new MPd,d);c.G=b;!a.rb&&(a.rb=new jUd(a,d5,a));wtd(a.rb,c);return c} +function Hkd(a,b){switch(b){case 1:return !!a.n&&a.n.i!=0;case 2:return a.k!=null;}return dkd(a,b)} +function gNc(a){switch(a.a.g){case 1:return new NNc;case 3:return new vQc;default:return new wNc;}} +function MRd(a){var b;if(a.g>1||a.Ob()){++a.a;a.g=0;b=a.i;a.Ob();return b}else{throw vbb(new utb)}} +function kNc(a){fNc();var b;if(!Lpb(eNc,a)){b=new hNc;b.a=a;Opb(eNc,a,b)}return BD(Mpb(eNc,a),635)} +function Rbb(a){var b,c,d,e;e=a;d=0;if(e<0){e+=Ije;d=Fje}c=QD(e/Hje);b=QD(e-c*Hje);return TC(b,c,d)} +function Ox(a){var b,c,d;d=0;for(c=new Gqb(a.a);c.a<c.c.a.length;){b=Fqb(c);a.b.Hc(b)&&++d}return d} +function Ku(a){var b,c,d;b=1;for(d=a.Kc();d.Ob();){c=d.Pb();b=31*b+(c==null?0:tb(c));b=~~b}return b} +function Zwb(a,b){var c;this.c=a;c=new Rkb;Ewb(a,c,b,a.b,null,false,null,false);this.a=new Bib(c,0)} +function p4d(a,b){this.b=a;this.e=b;this.d=b.j;this.f=(Q6d(),BD(a,66).Oj());this.k=S6d(b.e.Tg(),a)} +function xwb(a,b,c){this.b=(uCb(a),a);this.d=(uCb(b),b);this.e=(uCb(c),c);this.c=this.d+(''+this.e)} +function xRb(){this.a=BD(Ksd((wSb(),eSb)),19).a;this.c=Edb(ED(Ksd(uSb)));this.b=Edb(ED(Ksd(qSb)))} +function Nbd(){Nbd=ccb;Mbd=as((Hbd(),OC(GC(B1,1),Kie,93,0,[zbd,ybd,Bbd,Gbd,Fbd,Ebd,Cbd,Dbd,Abd])))} +function wFb(){wFb=ccb;vFb=as((rFb(),OC(GC(dN,1),Kie,250,0,[qFb,lFb,mFb,kFb,oFb,pFb,nFb,jFb,iFb])))} +function vLb(){vLb=ccb;uLb=new wLb('UP',0);rLb=new wLb(vle,1);sLb=new wLb(jle,2);tLb=new wLb(kle,3)} +function rTc(){rTc=ccb;qTc=(STc(),QTc);pTc=new Nsd(Zqe,qTc);oTc=($Tc(),ZTc);nTc=new Nsd($qe,oTc)} +function Xrc(){Xrc=ccb;Vrc=new Yrc('ONE_SIDED',0);Wrc=new Yrc('TWO_SIDED',1);Urc=new Yrc('OFF',2)} +function TQc(a){a.r=new Tqb;a.w=new Tqb;a.t=new Rkb;a.i=new Rkb;a.d=new Tqb;a.a=new I6c;a.c=new Lqb} +function uOc(a){this.n=new Rkb;this.e=new Psb;this.j=new Psb;this.k=new Rkb;this.f=new Rkb;this.p=a} +function PEc(a,b){if(a.c){QEc(a,b,true);MAb(new YAb(null,new Kub(b,16)),new bFc(a))}QEc(a,b,false)} +function wFc(a,b,c){return a==(rGc(),qGc)?new pFc:Cub(b,1)!=0?new iHc(c.length):new RGc(c.length)} +function tNb(a,b){var c;if(!b){return a}c=b.Ve();c.dc()||(!a.q?(a.q=new Nqb(c)):Ld(a.q,c));return a} +function Erb(a,b){var c;c=a.a.get(b);if(c===undefined){++a.d}else{urb(a.a,b);--a.c;zpb(a.b)}return c} +function UYb(a,b){var c,d,e;c=b.p-a.p;if(c==0){d=a.f.a*a.f.b;e=b.f.a*b.f.b;return Kdb(d,e)}return c} +function XLb(a,b){var c,d;c=a.f.c.length;d=b.f.c.length;if(c<d){return -1}if(c==d){return 0}return 1} +function KZb(a){if(a.b.c.length!=0&&!!BD(Ikb(a.b,0),70).a){return BD(Ikb(a.b,0),70).a}return JZb(a)} +function Pq(a){var b;if(a){b=a;if(b.dc()){throw vbb(new utb)}return b.Xb(b.gc()-1)}return nr(a.Kc())} +function vgb(a){var b;ybb(a,0)<0&&(a=Lbb(a));return b=Tbb(Obb(a,32)),64-(b!=0?heb(b):heb(Tbb(a))+32)} +function QNc(a){var b;b=BD(vNb(a,(wtc(),Hsc)),61);return a.k==(j0b(),e0b)&&(b==(Ucd(),Tcd)||b==zcd)} +function bZb(a,b,c){var d,e;e=BD(vNb(a,(Nyc(),jxc)),74);if(e){d=new s7c;o7c(d,0,e);q7c(d,c);ye(b,d)}} +function M_b(a,b,c){var d,e,f,g;g=Q_b(a);d=g.d;e=g.c;f=a.n;b&&(f.a=f.a-d.b-e.a);c&&(f.b=f.b-d.d-e.b)} +function dcc(a,b){var c,d;c=a.j;d=b.j;return c!=d?c.g-d.g:a.p==b.p?0:c==(Ucd(),Acd)?a.p-b.p:b.p-a.p} +function dmc(a){var b,c;bmc(a);for(c=new olb(a.d);c.a<c.c.c.length;){b=BD(mlb(c),101);!!b.i&&cmc(b)}} +function lBc(a,b,c,d,e){NC(a.c[b.g],c.g,d);NC(a.c[c.g],b.g,d);NC(a.b[b.g],c.g,e);NC(a.b[c.g],b.g,e)} +function G1c(a,b,c,d){BD(c.b,65);BD(c.b,65);BD(d.b,65);BD(d.b,65);BD(d.b,65);Hkb(d.a,new L1c(a,b,d))} +function WDb(a,b){a.d==(ead(),aad)||a.d==dad?BD(b.a,57).c.Fc(BD(b.b,57)):BD(b.b,57).c.Fc(BD(b.a,57))} +function Gkd(a,b,c,d){if(c==1){return !a.n&&(a.n=new cUd(D2,a,1,7)),Txd(a.n,b,d)}return ckd(a,b,c,d)} +function Gnd(a,b){var c,d;d=(c=new BYd,c);pnd(d,b);wtd((!a.A&&(a.A=new K4d(u5,a,7)),a.A),d);return d} +function Zqd(a,b,c){var d,e,f,g;f=null;g=b;e=Ypd(g,Jte);d=new jrd(a,c);f=(lqd(d.a,d.b,e),e);return f} +function KJd(a){var b;if(!a.a||(a.Bb&1)==0&&a.a.kh()){b=wId(a);JD(b,148)&&(a.a=BD(b,148))}return a.a} +function Be(a,b){var c,d;uCb(b);for(d=b.Kc();d.Ob();){c=d.Pb();if(!a.Hc(c)){return false}}return true} +function cD(a,b){var c,d,e;c=a.l+b.l;d=a.m+b.m+(c>>22);e=a.h+b.h+(d>>22);return TC(c&Eje,d&Eje,e&Fje)} +function nD(a,b){var c,d,e;c=a.l-b.l;d=a.m-b.m+(c>>22);e=a.h-b.h+(d>>22);return TC(c&Eje,d&Eje,e&Fje)} +function bdb(a){var b;if(a<128){b=(ddb(),cdb)[a];!b&&(b=cdb[a]=new Xcb(a));return b}return new Xcb(a)} +function ubb(a){var b;if(JD(a,78)){return a}b=a&&a.__java$exception;if(!b){b=new lz(a);Sz(b)}return b} +function btd(a){if(JD(a,186)){return BD(a,118)}else if(!a){throw vbb(new Heb(gue))}else{return null}} +function Zjb(a,b){if(b==null){return false}while(a.a!=a.b){if(pb(b,vkb(a))){return true}}return false} +function kib(a){if(a.a.Ob()){return true}if(a.a!=a.d){return false}a.a=new orb(a.e.f);return a.a.Ob()} +function Gkb(a,b){var c,d;c=b.Pc();d=c.length;if(d==0){return false}bCb(a.c,a.c.length,c);return true} +function Vyb(a,b,c){var d,e;for(e=b.vc().Kc();e.Ob();){d=BD(e.Pb(),42);a.yc(d.cd(),d.dd(),c)}return a} +function yac(a,b){var c,d;for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),70);yNb(c,(wtc(),Ssc),b)}} +function FZc(a,b,c){var d,e;for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),33);bld(d,d.i+b,d.j+c)}} +function Nb(a,b){if(!a){throw vbb(new Wdb(hc('value already present: %s',OC(GC(SI,1),Uhe,1,5,[b]))))}} +function mEb(a,b){if(!a||!b||a==b){return false}return CDb(a.d.c,b.d.c+b.d.b)&&CDb(b.d.c,a.d.c+a.d.b)} +function xyb(){oyb();if(lyb){return new wyb(null)}return fyb(hyb(),'com.google.common.base.Strings')} +function J2c(a,b){var c;c=Pu(b.a.gc());MAb(VAb(new YAb(null,new Kub(b,1)),a.i),new W2c(a,c));return c} +function Hnd(a){var b,c;c=(b=new BYd,b);pnd(c,'T');wtd((!a.d&&(a.d=new K4d(u5,a,11)),a.d),c);return c} +function Etd(a){var b,c,d,e;b=1;for(c=0,e=a.gc();c<e;++c){d=a.ki(c);b=31*b+(d==null?0:tb(d))}return b} +function Wi(a,b,c,d){var e;Pb(b,a.e.Hd().gc());Pb(c,a.c.Hd().gc());e=a.a[b][c];NC(a.a[b],c,d);return e} +function OC(a,b,c,d,e){e.gm=a;e.hm=b;e.im=gcb;e.__elementTypeId$=c;e.__elementTypeCategory$=d;return e} +function p6c(a,b,c,d,e){i6c();return $wnd.Math.min(A6c(a,b,c,d,e),A6c(c,d,a,b,V6c(new f7c(e.a,e.b))))} +function gbc(){gbc=ccb;fbc=new ibc(ane,0);dbc=new ibc(Gne,1);ebc=new ibc(Hne,2);cbc=new ibc('BOTH',3)} +function Ajc(){Ajc=ccb;wjc=new Bjc(gle,0);xjc=new Bjc(jle,1);yjc=new Bjc(kle,2);zjc=new Bjc('TOP',3)} +function lWb(){lWb=ccb;hWb=new oWb('Q1',0);kWb=new oWb('Q4',1);iWb=new oWb('Q2',2);jWb=new oWb('Q3',3)} +function LBc(){LBc=ccb;JBc=new MBc('OFF',0);KBc=new MBc('SINGLE_EDGE',1);IBc=new MBc('MULTI_EDGE',2)} +function a1c(){a1c=ccb;_0c=new c1c('MINIMUM_SPANNING_TREE',0);$0c=new c1c('MAXIMUM_SPANNING_TREE',1)} +function Y1c(){Y1c=ccb;new Lsd('org.eclipse.elk.addLayoutConfig');W1c=new k2c;V1c=new f2c;X1c=new i2c} +function URc(a){var b,c,d;b=new Psb;for(d=Jsb(a.d,0);d.b!=d.d.c;){c=BD(Xsb(d),188);Dsb(b,c.c)}return b} +function dVc(a){var b,c,d,e;e=new Rkb;for(d=a.Kc();d.Ob();){c=BD(d.Pb(),33);b=gVc(c);Gkb(e,b)}return e} +function xcc(a){var b;PZb(a,true);b=_ie;wNb(a,(Nyc(),cyc))&&(b+=BD(vNb(a,cyc),19).a);yNb(a,cyc,meb(b))} +function q1c(a,b,c){var d;Uhb(a.a);Hkb(c.i,new B1c(a));d=new hDb(BD(Ohb(a.a,b.b),65));p1c(a,d,b);c.f=d} +function QLc(a,b){var c,d;c=a.c;d=b.e[a.p];if(d<c.a.c.length-1){return BD(Ikb(c.a,d+1),10)}return null} +function rr(a,b){var c,d;Rb(b,'predicate');for(d=0;a.Ob();d++){c=a.Pb();if(b.Lb(c)){return d}}return -1} +function ZEd(a,b){var c,d;d=0;if(a<64&&a<=b){b=b<64?b:63;for(c=a;c<=b;c++){d=Mbb(d,Nbb(1,c))}}return d} +function pmb(a){mmb();var b,c,d;d=0;for(c=a.Kc();c.Ob();){b=c.Pb();d=d+(b!=null?tb(b):0);d=d|0}return d} +function etd(a){var b,c;c=(Fhd(),b=new rmd,b);!!a&&wtd((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a),c);return c} +function TA(a){var b;b=new PA;b.a=a;b.b=RA(a);b.c=KC(ZI,nie,2,2,6,1);b.c[0]=SA(a);b.c[1]=SA(a);return b} +function fkd(a,b){switch(b){case 0:!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0));a.o.c.$b();return;}Cid(a,b)} +function jEb(a,b,c){switch(c.g){case 2:a.b=b;break;case 1:a.c=b;break;case 4:a.d=b;break;case 3:a.a=b;}} +function sbd(a){switch(a.g){case 1:return obd;case 2:return nbd;case 3:return pbd;default:return qbd;}} +function Zac(a){switch(BD(vNb(a,(Nyc(),mxc)),163).g){case 2:case 4:return true;default:return false;}} +function Trc(){Trc=ccb;Src=as((Orc(),OC(GC(PW,1),Kie,256,0,[Frc,Hrc,Irc,Jrc,Krc,Lrc,Nrc,Erc,Grc,Mrc])))} +function Ndd(){Ndd=ccb;Mdd=as((Idd(),OC(GC(J1,1),Kie,259,0,[Bdd,Ddd,Add,Edd,Fdd,Hdd,Gdd,Cdd,zdd])))} +function wUc(){wUc=ccb;vUc=e3c(b3c(b3c(g3c(e3c(new j3c,(yRc(),vRc),(qSc(),pSc)),wRc),mSc),nSc),xRc,oSc)} +function Gqc(){Gqc=ccb;Eqc=new Hqc(ane,0);Dqc=new Hqc('INCOMING_ONLY',1);Fqc=new Hqc('OUTGOING_ONLY',2)} +function rC(){rC=ccb;qC={'boolean':sC,'number':tC,'string':vC,'object':uC,'function':uC,'undefined':wC}} +function Whb(a,b){mCb(a>=0,'Negative initial capacity');mCb(b>=0,'Non-positive load factor');Uhb(this)} +function _Ed(a,b,c){if(a>=128)return false;return a<64?Kbb(xbb(Nbb(1,a),c),0):Kbb(xbb(Nbb(1,a-64),b),0)} +function bOb(a,b){if(!a||!b||a==b){return false}return Jy(a.b.c,b.b.c+b.b.b)<0&&Jy(b.b.c,a.b.c+a.b.b)<0} +function I4b(a){var b,c,d;c=a.n;d=a.o;b=a.d;return new J6c(c.a-b.b,c.b-b.d,d.a+(b.b+b.c),d.b+(b.d+b.a))} +function $ic(a){var b,c,d,e;for(c=a.a,d=0,e=c.length;d<e;++d){b=c[d];djc(a,b,(Ucd(),Rcd));djc(a,b,Acd)}} +function Uy(a){var b,c,d,e;for(b=(a.j==null&&(a.j=(Rz(),e=Qz.ce(a),Tz(e))),a.j),c=0,d=b.length;c<d;++c);} +function hD(a){var b,c,d;b=~a.l+1&Eje;c=~a.m+(b==0?1:0)&Eje;d=~a.h+(b==0&&c==0?1:0)&Fje;return TC(b,c,d)} +function C$c(a,b){var c,d;c=BD(BD(Ohb(a.g,b.a),46).a,65);d=BD(BD(Ohb(a.g,b.b),46).a,65);return _Nb(c,d)} +function xtd(a,b,c){var d;d=a.gc();if(b>d)throw vbb(new Cyd(b,d));a.hi()&&(c=Dtd(a,c));return a.Vh(b,c)} +function xNb(a,b,c){return c==null?(!a.q&&(a.q=new Lqb),Thb(a.q,b)):(!a.q&&(a.q=new Lqb),Rhb(a.q,b,c)),a} +function yNb(a,b,c){c==null?(!a.q&&(a.q=new Lqb),Thb(a.q,b)):(!a.q&&(a.q=new Lqb),Rhb(a.q,b,c));return a} +function TQb(a){var b,c;c=new kRb;tNb(c,a);yNb(c,(HSb(),FSb),a);b=new Lqb;VQb(a,c,b);UQb(a,c,b);return c} +function j6c(a){i6c();var b,c,d;c=KC(m1,nie,8,2,0,1);d=0;for(b=0;b<2;b++){d+=0.5;c[b]=r6c(d,a)}return c} +function Mic(a,b){var c,d,e,f;c=false;d=a.a[b].length;for(f=0;f<d-1;f++){e=f+1;c=c|Nic(a,b,f,e)}return c} +function nNb(a,b,c,d,e){var f,g;for(g=c;g<=e;g++){for(f=b;f<=d;f++){YMb(a,f,g)||aNb(a,f,g,true,false)}}} +function rNd(a,b){this.b=a;nNd.call(this,(BD(qud(ZKd((NFd(),MFd).o),10),18),b.i),b.g);this.a=(NKd(),MKd)} +function hj(a,b){this.c=a;this.d=b;this.b=this.d/this.c.c.Hd().gc()|0;this.a=this.d%this.c.c.Hd().gc()} +function jdb(){++edb;this.o=null;this.k=null;this.j=null;this.d=null;this.b=null;this.n=null;this.a=null} +function fB(a,b,c){this.q=new $wnd.Date;this.q.setFullYear(a+nje,b,c);this.q.setHours(0,0,0,0);YA(this,0)} +function tAc(){tAc=ccb;rAc=new uAc(ane,0);qAc=new uAc('NODES_AND_EDGES',1);sAc=new uAc('PREFER_EDGES',2)} +function RA(a){var b;if(a==0){return 'Etc/GMT'}if(a<0){a=-a;b='Etc/GMT-'}else{b='Etc/GMT+'}return b+UA(a)} +function geb(a){var b;if(a<0){return Rie}else if(a==0){return 0}else{for(b=Iie;(b&a)==0;b>>=1);return b}} +function $C(a){var b,c;c=heb(a.h);if(c==32){b=heb(a.m);return b==32?heb(a.l)+32:b+20-10}else{return c-12}} +function bkb(a){var b;b=a.a[a.b];if(b==null){return null}NC(a.a,a.b,null);a.b=a.b+1&a.a.length-1;return b} +function EDc(a){var b,c;b=a.t-a.k[a.o.p]*a.d+a.j[a.o.p]>a.f;c=a.u+a.e[a.o.p]*a.d>a.f*a.s*a.d;return b||c} +function Iwb(a,b,c){var d,e;d=new exb(b,c);e=new fxb;a.b=Gwb(a,a.b,d,e);e.b||++a.c;a.b.b=false;return e.d} +function djc(a,b,c){var d,e,f,g;g=CHc(b,c);f=0;for(e=g.Kc();e.Ob();){d=BD(e.Pb(),11);Rhb(a.c,d,meb(f++))}} +function xVb(a){var b,c;for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),81);b.g.c=-b.g.c-b.g.b}sVb(a)} +function XDb(a){var b,c;for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),57);b.d.c=-b.d.c-b.d.b}RDb(a)} +function AUd(a){var b;if(!a.c||(a.Bb&1)==0&&(a.c.Db&64)!=0){b=wId(a);JD(b,88)&&(a.c=BD(b,26))}return a.c} +function ZC(a){var b,c,d;b=~a.l+1&Eje;c=~a.m+(b==0?1:0)&Eje;d=~a.h+(b==0&&c==0?1:0)&Fje;a.l=b;a.m=c;a.h=d} +function l7c(a){var b,c,d,e,f;b=new d7c;for(d=a,e=0,f=d.length;e<f;++e){c=d[e];b.a+=c.a;b.b+=c.b}return b} +function nmb(a,b){mmb();var c,d,e,f,g;g=false;for(d=b,e=0,f=d.length;e<f;++e){c=d[e];g=g|a.Fc(c)}return g} +function w6c(a){i6c();var b,c;c=-1.7976931348623157E308;for(b=0;b<a.length;b++){a[b]>c&&(c=a[b])}return c} +function SHc(a,b,c){var d;d=new Rkb;UHc(a,b,d,(Ucd(),zcd),true,false);UHc(a,c,d,Tcd,false,false);return d} +function crd(a,b,c){var d,e,f,g;f=null;g=b;e=Ypd(g,'labels');d=new Hrd(a,c);f=(Dqd(d.a,d.b,e),e);return f} +function j1d(a,b,c,d){var e;e=r1d(a,b,c,d);if(!e){e=i1d(a,c,d);if(!!e&&!e1d(a,b,e)){return null}}return e} +function m1d(a,b,c,d){var e;e=s1d(a,b,c,d);if(!e){e=l1d(a,c,d);if(!!e&&!e1d(a,b,e)){return null}}return e} +function Xb(a,b){var c;for(c=0;c<a.a.a.length;c++){if(!BD($lb(a.a,c),169).Lb(b)){return false}}return true} +function Cb(a,b,c){Qb(b);if(c.Ob()){Mfb(b,Fb(c.Pb()));while(c.Ob()){Mfb(b,a.a);Mfb(b,Fb(c.Pb()))}}return b} +function qmb(a){mmb();var b,c,d;d=1;for(c=a.Kc();c.Ob();){b=c.Pb();d=31*d+(b!=null?tb(b):0);d=d|0}return d} +function WC(a,b,c,d,e){var f;f=lD(a,b);c&&ZC(f);if(e){a=YC(a,b);d?(QC=hD(a)):(QC=TC(a.l,a.m,a.h))}return f} +function Xzb(b,c){var d;try{c.Vd()}catch(a){a=ubb(a);if(JD(a,78)){d=a;b.c[b.c.length]=d}else throw vbb(a)}} +function jRb(a,b,c){var d,e;if(JD(b,144)&&!!c){d=BD(b,144);e=c;return a.a[d.b][e.b]+a.a[e.b][d.b]}return 0} +function xld(a,b){switch(b){case 7:return !!a.e&&a.e.i!=0;case 8:return !!a.d&&a.d.i!=0;}return Ykd(a,b)} +function YQb(a,b){switch(b.g){case 0:JD(a.b,631)||(a.b=new xRb);break;case 1:JD(a.b,632)||(a.b=new DRb);}} +function Ghe(a,b){while(a.g==null&&!a.c?Uud(a):a.g==null||a.i!=0&&BD(a.g[a.i-1],47).Ob()){Ord(b,Vud(a))}} +function kic(a,b,c){a.g=qic(a,b,(Ucd(),zcd),a.b);a.d=qic(a,c,zcd,a.b);if(a.g.c==0||a.d.c==0){return}nic(a)} +function lic(a,b,c){a.g=qic(a,b,(Ucd(),Tcd),a.j);a.d=qic(a,c,Tcd,a.j);if(a.g.c==0||a.d.c==0){return}nic(a)} +function $yc(a,b,c){return !WAb(JAb(new YAb(null,new Kub(a.c,16)),new Xxb(new dfd(b,c)))).sd((EAb(),DAb))} +function KAb(a){var b;Tzb(a);b=new NBb;if(a.a.sd(b)){return Atb(),new Ftb(uCb(b.a))}return Atb(),Atb(),ztb} +function nA(a){var b;if(a.b<=0){return false}b=hfb('MLydhHmsSDkK',wfb(bfb(a.c,0)));return b>1||b>=0&&a.b<3} +function w7c(a){var b,c,d;b=new s7c;for(d=Jsb(a,0);d.b!=d.d.c;){c=BD(Xsb(d),8);St(b,0,new g7c(c))}return b} +function qVb(a){var b,c;for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),81);b.f.$b()}LVb(a.b,a);rVb(a)} +function tb(a){return ND(a)?LCb(a):LD(a)?Hdb(a):KD(a)?(uCb(a),a)?1231:1237:ID(a)?a.Hb():MC(a)?FCb(a):rz(a)} +function rb(a){return ND(a)?ZI:LD(a)?BI:KD(a)?wI:ID(a)?a.gm:MC(a)?a.gm:a.gm||Array.isArray(a)&&GC(PH,1)||PH} +function j_c(a){switch(a.g){case 0:return new Q1c;default:throw vbb(new Wdb(Mre+(a.f!=null?a.f:''+a.g)));}} +function S0c(a){switch(a.g){case 0:return new k1c;default:throw vbb(new Wdb(Mre+(a.f!=null?a.f:''+a.g)));}} +function ekd(a,b,c){switch(b){case 0:!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0));cId(a.o,c);return;}yid(a,b,c)} +function XRc(a,b,c){this.g=a;this.e=new d7c;this.f=new d7c;this.d=new Psb;this.b=new Psb;this.a=b;this.c=c} +function PZc(a,b,c,d){this.b=new Rkb;this.n=new Rkb;this.i=d;this.j=c;this.s=a;this.t=b;this.r=0;this.d=0} +function nib(a){this.e=a;this.d=new Irb(this.e.g);this.a=this.d;this.b=kib(this);this.$modCount=a.$modCount} +function Pr(a){while(!a.d||!a.d.Ob()){if(!!a.b&&!akb(a.b)){a.d=BD(fkb(a.b),47)}else{return null}}return a.d} +function Xyc(a){Ekb(a.c,(Y1c(),W1c));if(Ky(a.a,Edb(ED(Ksd((dzc(),bzc)))))){return new Zed}return new _ed(a)} +function bRc(a){switch(a.g){case 1:return Sqe;default:case 2:return 0;case 3:return cme;case 4:return Tqe;}} +function Ife(){wfe();var a;if(dfe)return dfe;a=Afe(Kfe('M',true));a=Bfe(Kfe('M',false),a);dfe=a;return dfe} +function Awb(a,b){var c,d,e;e=a.b;while(e){c=a.a.ue(b,e.d);if(c==0){return e}d=c<0?0:1;e=e.a[d]}return null} +function Tyb(a,b,c){var d,e;d=(Bcb(),_Pb(c)?true:false);e=BD(b.xc(d),15);if(!e){e=new Rkb;b.zc(d,e)}e.Fc(c)} +function dYc(a,b){var c,d;c=BD(hkd(a,(lZc(),UYc)),19).a;d=BD(hkd(b,UYc),19).a;return c==d?-1:c<d?-1:c>d?1:0} +function NYb(a,b){if(OYb(a,b)){Rc(a.b,BD(vNb(b,(wtc(),Esc)),21),b);Dsb(a.a,b);return true}else{return false}} +function d3b(a){var b,c;b=BD(vNb(a,(wtc(),gtc)),10);if(b){c=b.c;Lkb(c.a,b);c.a.c.length==0&&Lkb(Q_b(b).b,c)}} +function syb(a){if(lyb){return KC(qL,tke,572,0,0,1)}return BD(Qkb(a.a,KC(qL,tke,572,a.a.c.length,0,1)),842)} +function mn(a,b,c,d){Vm();return new wx(OC(GC(CK,1),zie,42,0,[(Wj(a,b),new Wo(a,b)),(Wj(c,d),new Wo(c,d))]))} +function Dnd(a,b,c){var d,e;e=(d=new SSd,d);$nd(e,b,c);wtd((!a.q&&(a.q=new cUd(n5,a,11,10)),a.q),e);return e} +function Zmd(a){var b,c,d,e;e=icb(Rmd,a);c=e.length;d=KC(ZI,nie,2,c,6,1);for(b=0;b<c;++b){d[b]=e[b]}return d} +function l4c(a,b){var c,d,e,f,g;for(d=b,e=0,f=d.length;e<f;++e){c=d[e];g=new v4c(a);c.Qe(g);q4c(g)}Uhb(a.f)} +function hw(a,b){var c;if(b===a){return true}if(JD(b,224)){c=BD(b,224);return pb(a.Zb(),c.Zb())}return false} +function aub(a,b){var c;if(b*2+1>=a.b.c.length){return}aub(a,2*b+1);c=2*b+2;c<a.b.c.length&&aub(a,c);bub(a,b)} +function Ss(a,b,c){var d,e;this.g=a;this.c=b;this.a=this;this.d=this;e=Kp(c);d=KC(BG,Gie,330,e,0,1);this.b=d} +function whb(a,b,c){var d;for(d=c-1;d>=0&&a[d]===b[d];d--);return d<0?0:Gbb(xbb(a[d],Yje),xbb(b[d],Yje))?-1:1} +function UFc(a,b){var c,d;for(d=Jsb(a,0);d.b!=d.d.c;){c=BD(Xsb(d),214);if(c.e.length>0){b.td(c);c.i&&_Fc(c)}}} +function nzd(a,b){var c,d;d=BD(Ajd(a.a,4),126);c=KC($3,hve,415,b,0,1);d!=null&&$fb(d,0,c,0,d.length);return c} +function JEd(a,b){var c;c=new NEd((a.f&256)!=0,a.i,a.a,a.d,(a.f&16)!=0,a.j,a.g,b);a.e!=null||(c.c=a);return c} +function Dc(a,b){var c,d;for(d=a.Zb().Cc().Kc();d.Ob();){c=BD(d.Pb(),14);if(c.Hc(b)){return true}}return false} +function oNb(a,b,c,d,e){var f,g;for(g=c;g<=e;g++){for(f=b;f<=d;f++){if(YMb(a,f,g)){return true}}}return false} +function Tt(a,b,c){var d,e,f,g;uCb(c);g=false;f=a.Zc(b);for(e=c.Kc();e.Ob();){d=e.Pb();f.Rb(d);g=true}return g} +function Dv(a,b){var c;if(a===b){return true}else if(JD(b,83)){c=BD(b,83);return Ax(Wm(a),c.vc())}return false} +function Nhb(a,b,c){var d,e;for(e=c.Kc();e.Ob();){d=BD(e.Pb(),42);if(a.re(b,d.dd())){return true}}return false} +function Hic(a,b,c){if(!a.d[b.p][c.p]){Gic(a,b,c);a.d[b.p][c.p]=true;a.d[c.p][b.p]=true}return a.a[b.p][c.p]} +function Itd(a,b){if(!a.ai()&&b==null){throw vbb(new Wdb("The 'no null' constraint is violated"))}return b} +function $Jd(a,b){if(a.D==null&&a.B!=null){a.D=a.B;a.B=null}jKd(a,b==null?null:(uCb(b),b));!!a.C&&a.yk(null)} +function XHc(a,b){var c;if(!a||a==b||!wNb(b,(wtc(),Psc))){return false}c=BD(vNb(b,(wtc(),Psc)),10);return c!=a} +function b4d(a){switch(a.i){case 2:{return true}case 1:{return false}case -1:{++a.c}default:{return a.pl()}}} +function c4d(a){switch(a.i){case -2:{return true}case -1:{return false}case 1:{--a.c}default:{return a.ql()}}} +function Xdb(a){Zy.call(this,'The given string does not match the expected format for individual spacings.',a)} +function pgd(){pgd=ccb;mgd=new qgd('ELK',0);ngd=new qgd('JSON',1);lgd=new qgd('DOT',2);ogd=new qgd('SVG',3)} +function pWc(){pWc=ccb;mWc=new rWc(ane,0);nWc=new rWc('RADIAL_COMPACTION',1);oWc=new rWc('WEDGE_COMPACTION',2)} +function Fyb(){Fyb=ccb;Cyb=new Gyb('CONCURRENT',0);Dyb=new Gyb('IDENTITY_FINISH',1);Eyb=new Gyb('UNORDERED',2)} +function nPb(){nPb=ccb;kPb=(cPb(),bPb);jPb=new Nsd(Tle,kPb);iPb=new Lsd(Ule);lPb=new Lsd(Vle);mPb=new Lsd(Wle)} +function Occ(){Occ=ccb;Mcc=new Zcc;Ncc=new _cc;Lcc=new bdc;Kcc=new fdc;Jcc=new jdc;Icc=(uCb(Jcc),new bpb)} +function tBc(){tBc=ccb;qBc=new uBc('CONSERVATIVE',0);rBc=new uBc('CONSERVATIVE_SOFT',1);sBc=new uBc('SLOPPY',2)} +function Zad(){Zad=ccb;Xad=new q0b(15);Wad=new Osd((Y9c(),f9c),Xad);Yad=C9c;Sad=s8c;Tad=Y8c;Vad=_8c;Uad=$8c} +function o7c(a,b,c){var d,e,f;d=new Psb;for(f=Jsb(c,0);f.b!=f.d.c;){e=BD(Xsb(f),8);Dsb(d,new g7c(e))}Tt(a,b,d)} +function r7c(a){var b,c,d;b=0;d=KC(m1,nie,8,a.b,0,1);c=Jsb(a,0);while(c.b!=c.d.c){d[b++]=BD(Xsb(c),8)}return d} +function $Pd(a){var b;b=(!a.a&&(a.a=new cUd(g5,a,9,5)),a.a);if(b.i!=0){return nQd(BD(qud(b,0),678))}return null} +function Ly(a,b){var c;c=wbb(a,b);if(Gbb(Vbb(a,b),0)|Ebb(Vbb(a,c),0)){return c}return wbb(rie,Vbb(Pbb(c,63),1))} +function Yyc(a,b){var c;c=Ksd((dzc(),bzc))!=null&&b.wg()!=null?Edb(ED(b.wg()))/Edb(ED(Ksd(bzc))):1;Rhb(a.b,b,c)} +function le(a,b){var c,d;c=BD(a.d.Bc(b),14);if(!c){return null}d=a.e.hc();d.Gc(c);a.e.d-=c.gc();c.$b();return d} +function AHc(a,b){var c,d;d=a.c[b];if(d==0){return}a.c[b]=0;a.d-=d;c=b+1;while(c<a.a.length){a.a[c]-=d;c+=c&-c}} +function rwb(a){var b;b=a.a.c.length;if(b>0){return _vb(b-1,a.a.c.length),Kkb(a.a,b-1)}else{throw vbb(new Jpb)}} +function C2c(a,b,c){if(b<0){throw vbb(new qcb(ese+b))}if(b<a.j.c.length){Nkb(a.j,b,c)}else{A2c(a,b);Ekb(a.j,c)}} +function oCb(a,b,c){if(a>b){throw vbb(new Wdb(xke+a+yke+b))}if(a<0||b>c){throw vbb(new scb(xke+a+zke+b+oke+c))}} +function j5c(a){if(!a.a||(a.a.i&8)==0){throw vbb(new Zdb('Enumeration class expected for layout option '+a.f))}} +function vud(a){var b;++a.j;if(a.i==0){a.g=null}else if(a.i<a.g.length){b=a.g;a.g=a.ri(a.i);$fb(b,0,a.g,0,a.i)}} +function hkb(a,b){var c,d;c=a.a.length-1;a.c=a.c-1&c;while(b!=a.c){d=b+1&c;NC(a.a,b,a.a[d]);b=d}NC(a.a,a.c,null)} +function ikb(a,b){var c,d;c=a.a.length-1;while(b!=a.b){d=b-1&c;NC(a.a,b,a.a[d]);b=d}NC(a.a,a.b,null);a.b=a.b+1&c} +function Fkb(a,b,c){var d,e;wCb(b,a.c.length);d=c.Pc();e=d.length;if(e==0){return false}bCb(a.c,b,d);return true} +function VEd(a){var b,c;if(a==null)return null;for(b=0,c=a.length;b<c;b++){if(!gFd(a[b]))return a[b]}return null} +function grb(a,b,c){var d,e,f,g;for(e=c,f=0,g=e.length;f<g;++f){d=e[f];if(a.b.re(b,d.cd())){return d}}return null} +function Hlb(a){var b,c,d,e,f;f=1;for(c=a,d=0,e=c.length;d<e;++d){b=c[d];f=31*f+(b!=null?tb(b):0);f=f|0}return f} +function as(a){var b,c,d,e,f;b={};for(d=a,e=0,f=d.length;e<f;++e){c=d[e];b[':'+(c.f!=null?c.f:''+c.g)]=c}return b} +function gr(a){var b;Qb(a);Mb(true,'numberToAdvance must be nonnegative');for(b=0;b<0&&Qr(a);b++){Rr(a)}return b} +function eDc(a){var b,c,d;d=0;for(c=new Sr(ur(a.a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);b.c.i==b.d.i||++d}return d} +function HZb(a,b){var c,d,e;c=a;e=0;do{if(c==b){return e}d=c.e;if(!d){throw vbb(new Vdb)}c=Q_b(d);++e}while(true)} +function w$c(a,b){var c,d,e;e=b-a.f;for(d=new olb(a.d);d.a<d.c.c.length;){c=BD(mlb(d),443);_Zc(c,c.e,c.f+e)}a.f=b} +function aRc(a,b,c){if($wnd.Math.abs(b-a)<Rqe||$wnd.Math.abs(c-a)<Rqe){return true}return b-a>Rqe?a-c>Rqe:c-a>Rqe} +function pHb(a,b){if(!a){return 0}if(b&&!a.j){return 0}if(JD(a,124)){if(BD(a,124).a.b==0){return 0}}return a.Re()} +function qHb(a,b){if(!a){return 0}if(b&&!a.k){return 0}if(JD(a,124)){if(BD(a,124).a.a==0){return 0}}return a.Se()} +function fhb(a){Hgb();if(a<0){if(a!=-1){return new Tgb(-1,-a)}return Bgb}else return a<=10?Dgb[QD(a)]:new Tgb(1,a)} +function xC(a){rC();throw vbb(new MB("Unexpected typeof result '"+a+"'; please report this bug to the GWT team"))} +function lz(a){jz();Py(this);Ry(this);this.e=a;Sy(this,a);this.g=a==null?Xhe:fcb(a);this.a='';this.b=a;this.a=''} +function F$c(){this.a=new G$c;this.f=new I$c(this);this.b=new K$c(this);this.i=new M$c(this);this.e=new O$c(this)} +function ss(){rs.call(this,new _rb(Cv(16)));Xj(2,mie);this.b=2;this.a=new Ms(null,null,0,null);As(this.a,this.a)} +function xzc(){xzc=ccb;uzc=new zzc('DUMMY_NODE_OVER',0);vzc=new zzc('DUMMY_NODE_UNDER',1);wzc=new zzc('EQUAL',2)} +function LUb(){LUb=ccb;JUb=Fx(OC(GC(t1,1),Kie,103,0,[(ead(),aad),bad]));KUb=Fx(OC(GC(t1,1),Kie,103,0,[dad,_9c]))} +function VQc(a){return (Ucd(),Lcd).Hc(a.j)?Edb(ED(vNb(a,(wtc(),qtc)))):l7c(OC(GC(m1,1),nie,8,0,[a.i.n,a.n,a.a])).b} +function DOb(a){var b,c,d,e;d=a.b.a;for(c=d.a.ec().Kc();c.Ob();){b=BD(c.Pb(),561);e=new MPb(b,a.e,a.f);Ekb(a.g,e)}} +function yId(a,b){var c,d,e;d=a.nk(b,null);e=null;if(b){e=(LFd(),c=new UQd,c);NQd(e,a.r)}d=xId(a,e,d);!!d&&d.Fi()} +function VFc(a,b){var c,d;d=Cub(a.d,1)!=0;c=true;while(c){c=false;c=b.c.Tf(b.e,d);c=c|dGc(a,b,d,false);d=!d}$Fc(a)} +function wZc(a,b){var c,d,e;d=false;c=b.q.d;if(b.d<a.b){e=ZZc(b.q,a.b);if(b.q.d>e){$Zc(b.q,e);d=c!=b.q.d}}return d} +function PVc(a,b){var c,d,e,f,g,h,i,j;i=b.i;j=b.j;d=a.f;e=d.i;f=d.j;g=i-e;h=j-f;c=$wnd.Math.sqrt(g*g+h*h);return c} +function Rnd(a,b){var c,d;d=jid(a);if(!d){!And&&(And=new lUd);c=(IEd(),PEd(b));d=new s0d(c);wtd(d.Vk(),a)}return d} +function Sc(a,b){var c,d;c=BD(a.c.Bc(b),14);if(!c){return a.jc()}d=a.hc();d.Gc(c);a.d-=c.gc();c.$b();return a.mc(d)} +function j7c(a,b){var c;for(c=0;c<b.length;c++){if(a==(BCb(c,b.length),b.charCodeAt(c))){return true}}return false} +function E_b(a,b){var c;for(c=0;c<b.length;c++){if(a==(BCb(c,b.length),b.charCodeAt(c))){return true}}return false} +function hFd(a){var b,c;if(a==null)return false;for(b=0,c=a.length;b<c;b++){if(!gFd(a[b]))return false}return true} +function Ngb(a){var b;if(a.c!=0){return a.c}for(b=0;b<a.a.length;b++){a.c=a.c*33+(a.a[b]&-1)}a.c=a.c*a.e;return a.c} +function vkb(a){var b;sCb(a.a!=a.b);b=a.d.a[a.a];mkb(a.b==a.d.c&&b!=null);a.c=a.a;a.a=a.a+1&a.d.a.length-1;return b} +function phe(a){var b;if(!(a.c.c<0?a.a>=a.c.b:a.a<=a.c.b)){throw vbb(new utb)}b=a.a;a.a+=a.c.c;++a.b;return meb(b)} +function BWb(a){var b;b=new VWb(a);rXb(a.a,zWb,new amb(OC(GC(bQ,1),Uhe,369,0,[b])));!!b.d&&Ekb(b.f,b.d);return b.f} +function Z1b(a){var b;b=new q_b(a.a);tNb(b,a);yNb(b,(wtc(),$sc),a);b.o.a=a.g;b.o.b=a.f;b.n.a=a.i;b.n.b=a.j;return b} +function A9b(a,b,c,d){var e,f;for(f=a.Kc();f.Ob();){e=BD(f.Pb(),70);e.n.a=b.a+(d.a-e.o.a)/2;e.n.b=b.b;b.b+=e.o.b+c}} +function UDb(a,b,c){var d,e;for(e=b.a.a.ec().Kc();e.Ob();){d=BD(e.Pb(),57);if(VDb(a,d,c)){return true}}return false} +function JDc(a){var b,c;for(c=new olb(a.r);c.a<c.c.c.length;){b=BD(mlb(c),10);if(a.n[b.p]<=0){return b}}return null} +function cVc(a){var b,c,d,e;e=new Tqb;for(d=new olb(a);d.a<d.c.c.length;){c=BD(mlb(d),33);b=fVc(c);ye(e,b)}return e} +function zFc(a){var b;b=k3c(xFc);BD(vNb(a,(wtc(),Ksc)),21).Hc((Orc(),Krc))&&e3c(b,(qUb(),nUb),(S8b(),H8b));return b} +function qKb(a,b,c){var d;d=new AJb(a,b);Rc(a.r,b.Hf(),d);if(c&&!tcd(a.u)){d.c=new aIb(a.d);Hkb(b.wf(),new tKb(d))}} +function ybb(a,b){var c;if(Fbb(a)&&Fbb(b)){c=a-b;if(!isNaN(c)){return c}}return eD(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b)} +function bFd(a,b){return b<a.length&&(BCb(b,a.length),a.charCodeAt(b)!=63)&&(BCb(b,a.length),a.charCodeAt(b)!=35)} +function Kic(a,b,c,d){var e,f;a.a=b;f=d?0:1;a.f=(e=new Iic(a.c,a.a,c,f),new jjc(c,a.a,e,a.e,a.b,a.c==(rGc(),pGc)))} +function Tmd(a,b,c){var d,e;e=a.a;a.a=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new nSd(a,1,1,e,b);!c?(c=d):c.Ei(d)}return c} +function GQd(a,b,c){var d,e;e=a.b;a.b=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new nSd(a,1,3,e,b);!c?(c=d):c.Ei(d)}return c} +function IQd(a,b,c){var d,e;e=a.f;a.f=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new nSd(a,1,0,e,b);!c?(c=d):c.Ei(d)}return c} +function xid(a,b){var c,d,e,f;f=(e=a?jid(a):null,q6d((d=b,e?e.Xk():null,d)));if(f==b){c=jid(a);!!c&&c.Xk()}return f} +function x6c(a,b){var c,d,e;e=1;c=a;d=b>=0?b:-b;while(d>0){if(d%2==0){c*=c;d=d/2|0}else{e*=c;d-=1}}return b<0?1/e:e} +function y6c(a,b){var c,d,e;e=1;c=a;d=b>=0?b:-b;while(d>0){if(d%2==0){c*=c;d=d/2|0}else{e*=c;d-=1}}return b<0?1/e:e} +function sAd(a){var b,c,d,e;if(a!=null){for(c=0;c<a.length;++c){b=a[c];if(b){BD(b.g,367);e=b.i;for(d=0;d<e;++d);}}}} +function YZc(a){var b,c,d;d=0;for(c=new olb(a.a);c.a<c.c.c.length;){b=BD(mlb(c),187);d=$wnd.Math.max(d,b.g)}return d} +function eGc(a){var b,c,d;for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),214);b=c.c.Rf()?c.f:c.a;!!b&&mHc(b,c.j)}} +function hbd(){hbd=ccb;fbd=new ibd('INHERIT',0);ebd=new ibd('INCLUDE_CHILDREN',1);gbd=new ibd('SEPARATE_CHILDREN',2)} +function Jkd(a,b){switch(b){case 1:!a.n&&(a.n=new cUd(D2,a,1,7));Uxd(a.n);return;case 2:Lkd(a,null);return;}fkd(a,b)} +function Dm(a){var b;switch(a.gc()){case 0:return hm;case 1:return new my(Qb(a.Xb(0)));default:b=a;return new ux(b);}} +function Vn(a){Ql();switch(a.gc()){case 0:return yx(),xx;case 1:return new oy(a.Kc().Pb());default:return new zx(a);}} +function Up(a){Ql();switch(a.c){case 0:return yx(),xx;case 1:return new oy(qr(new Gqb(a)));default:return new Tp(a);}} +function Hv(b,c){Qb(b);try{return b.xc(c)}catch(a){a=ubb(a);if(JD(a,205)||JD(a,173)){return null}else throw vbb(a)}} +function Iv(b,c){Qb(b);try{return b.Bc(c)}catch(a){a=ubb(a);if(JD(a,205)||JD(a,173)){return null}else throw vbb(a)}} +function Ck(b,c){Qb(b);try{return b.Hc(c)}catch(a){a=ubb(a);if(JD(a,205)||JD(a,173)){return false}else throw vbb(a)}} +function Dk(b,c){Qb(b);try{return b.Mc(c)}catch(a){a=ubb(a);if(JD(a,205)||JD(a,173)){return false}else throw vbb(a)}} +function Gv(b,c){Qb(b);try{return b._b(c)}catch(a){a=ubb(a);if(JD(a,205)||JD(a,173)){return false}else throw vbb(a)}} +function KXb(a,b){var c;if(a.a.c.length>0){c=BD(Ikb(a.a,a.a.c.length-1),570);if(NYb(c,b)){return}}Ekb(a.a,new PYb(b))} +function $gc(a){Hgc();var b,c;b=a.d.c-a.e.c;c=BD(a.g,145);Hkb(c.b,new shc(b));Hkb(c.c,new uhc(b));reb(c.i,new whc(b))} +function gic(a){var b;b=new Ufb;b.a+='VerticalSegment ';Pfb(b,a.e);b.a+=' ';Qfb(b,Eb(new Gb,new olb(a.k)));return b.a} +function u4c(a){var b;b=BD(Wrb(a.c.c,''),229);if(!b){b=new W3c(d4c(c4c(new e4c,''),'Other'));Xrb(a.c.c,'',b)}return b} +function qnd(a){var b;if((a.Db&64)!=0)return Eid(a);b=new Jfb(Eid(a));b.a+=' (name: ';Efb(b,a.zb);b.a+=')';return b.a} +function Jnd(a,b,c){var d,e;e=a.sb;a.sb=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new nSd(a,1,4,e,b);!c?(c=d):c.Ei(d)}return c} +function _ic(a,b){var c,d,e;c=0;for(e=V_b(a,b).Kc();e.Ob();){d=BD(e.Pb(),11);c+=vNb(d,(wtc(),gtc))!=null?1:0}return c} +function vPc(a,b,c){var d,e,f;d=0;for(f=Jsb(a,0);f.b!=f.d.c;){e=Edb(ED(Xsb(f)));if(e>c){break}else e>=b&&++d}return d} +function RTd(a,b,c){var d,e;d=new pSd(a.e,3,13,null,(e=b.c,e?e:(jGd(),YFd)),HLd(a,b),false);!c?(c=d):c.Ei(d);return c} +function STd(a,b,c){var d,e;d=new pSd(a.e,4,13,(e=b.c,e?e:(jGd(),YFd)),null,HLd(a,b),false);!c?(c=d):c.Ei(d);return c} +function zId(a,b,c){var d,e;e=a.r;a.r=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new nSd(a,1,8,e,a.r);!c?(c=d):c.Ei(d)}return c} +function o1d(a,b){var c,d;c=BD(b,676);d=c.vk();!d&&c.wk(d=JD(b,88)?new C1d(a,BD(b,26)):new O1d(a,BD(b,148)));return d} +function kud(a,b,c){var d;a.qi(a.i+1);d=a.oi(b,c);b!=a.i&&$fb(a.g,b,a.g,b+1,a.i-b);NC(a.g,b,d);++a.i;a.bi(b,c);a.ci()} +function vwb(a,b){var c;if(b.a){c=b.a.a.length;!a.a?(a.a=new Wfb(a.d)):Qfb(a.a,a.b);Ofb(a.a,b.a,b.d.length,c)}return a} +function __d(a,b){var c,d,e,f;b.vi(a.a);f=BD(Ajd(a.a,8),1936);if(f!=null){for(c=f,d=0,e=c.length;d<e;++d){null.jm()}}} +function TAb(a,b){var c;c=new NBb;if(!a.a.sd(c)){Tzb(a);return Atb(),Atb(),ztb}return Atb(),new Ftb(uCb(SAb(a,c.a,b)))} +function CHc(a,b){switch(b.g){case 2:case 1:return V_b(a,b);case 3:case 4:return Su(V_b(a,b));}return mmb(),mmb(),jmb} +function pb(a,b){return ND(a)?dfb(a,b):LD(a)?Fdb(a,b):KD(a)?(uCb(a),PD(a)===PD(b)):ID(a)?a.Fb(b):MC(a)?mb(a,b):qz(a,b)} +function r6d(a){return !a?null:(a.i&1)!=0?a==sbb?wI:a==WD?JI:a==VD?FI:a==UD?BI:a==XD?MI:a==rbb?UI:a==SD?xI:yI:a} +function Fhb(a,b,c,d,e){if(b==0||d==0){return}b==1?(e[d]=Hhb(e,c,d,a[0])):d==1?(e[b]=Hhb(e,a,b,c[0])):Ghb(a,c,e,b,d)} +function c6b(a,b){var c;if(a.c.length==0){return}c=BD(Qkb(a,KC(OQ,kne,10,a.c.length,0,1)),193);Nlb(c,new o6b);_5b(c,b)} +function i6b(a,b){var c;if(a.c.length==0){return}c=BD(Qkb(a,KC(OQ,kne,10,a.c.length,0,1)),193);Nlb(c,new t6b);_5b(c,b)} +function Ekd(a,b,c,d){switch(b){case 1:return !a.n&&(a.n=new cUd(D2,a,1,7)),a.n;case 2:return a.k;}return bkd(a,b,c,d)} +function ead(){ead=ccb;cad=new iad(ole,0);bad=new iad(kle,1);aad=new iad(jle,2);_9c=new iad(vle,3);dad=new iad('UP',4)} +function RXb(){RXb=ccb;QXb=new SXb(ane,0);PXb=new SXb('INSIDE_PORT_SIDE_GROUPS',1);OXb=new SXb('FORCE_MODEL_ORDER',2)} +function xCb(a,b,c){if(a<0||b>c){throw vbb(new qcb(xke+a+zke+b+', size: '+c))}if(a>b){throw vbb(new Wdb(xke+a+yke+b))}} +function eid(a,b,c){if(b<0){vid(a,c)}else{if(!c.Ij()){throw vbb(new Wdb(ite+c.ne()+jte))}BD(c,66).Nj().Vj(a,a.yh(),b)}} +function Jlb(a,b,c,d,e,f,g,h){var i;i=c;while(f<g){i>=d||b<c&&h.ue(a[b],a[i])<=0?NC(e,f++,a[b++]):NC(e,f++,a[i++])}} +function yZb(a,b,c,d,e,f){this.e=new Rkb;this.f=(KAc(),JAc);Ekb(this.e,a);this.d=b;this.a=c;this.b=d;this.f=e;this.c=f} +function VOd(a,b){var c,d;for(d=new Fyd(a);d.e!=d.i.gc();){c=BD(Dyd(d),26);if(PD(b)===PD(c)){return true}}return false} +function uJb(a){qJb();var b,c,d,e;for(c=wJb(),d=0,e=c.length;d<e;++d){b=c[d];if(Jkb(b.a,a,0)!=-1){return b}}return pJb} +function jFd(a){if(a>=65&&a<=70){return a-65+10}if(a>=97&&a<=102){return a-97+10}if(a>=48&&a<=57){return a-48}return 0} +function QHd(a){var b;if((a.Db&64)!=0)return Eid(a);b=new Jfb(Eid(a));b.a+=' (source: ';Efb(b,a.d);b.a+=')';return b.a} +function OQd(a,b,c){var d,e;e=a.a;a.a=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new nSd(a,1,5,e,a.a);!c?(c=d):Qwd(c,d)}return c} +function BId(a,b){var c;c=(a.Bb&256)!=0;b?(a.Bb|=256):(a.Bb&=-257);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,2,c,b))} +function eLd(a,b){var c;c=(a.Bb&256)!=0;b?(a.Bb|=256):(a.Bb&=-257);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,8,c,b))} +function LPd(a,b){var c;c=(a.Bb&256)!=0;b?(a.Bb|=256):(a.Bb&=-257);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,8,c,b))} +function CId(a,b){var c;c=(a.Bb&512)!=0;b?(a.Bb|=512):(a.Bb&=-513);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,3,c,b))} +function fLd(a,b){var c;c=(a.Bb&512)!=0;b?(a.Bb|=512):(a.Bb&=-513);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,9,c,b))} +function N7d(a,b){var c;if(a.b==-1&&!!a.a){c=a.a.Gj();a.b=!c?bLd(a.c.Tg(),a.a):a.c.Xg(a.a.aj(),c)}return a.c.Og(a.b,b)} +function meb(a){var b,c;if(a>-129&&a<128){b=a+128;c=(oeb(),neb)[b];!c&&(c=neb[b]=new _db(a));return c}return new _db(a)} +function Web(a){var b,c;if(a>-129&&a<128){b=a+128;c=(Yeb(),Xeb)[b];!c&&(c=Xeb[b]=new Qeb(a));return c}return new Qeb(a)} +function L5b(a){var b,c;b=a.k;if(b==(j0b(),e0b)){c=BD(vNb(a,(wtc(),Hsc)),61);return c==(Ucd(),Acd)||c==Rcd}return false} +function i1d(a,b,c){var d,e,f;f=(e=nUd(a.b,b),e);if(f){d=BD(V1d(p1d(a,f),''),26);if(d){return r1d(a,d,b,c)}}return null} +function l1d(a,b,c){var d,e,f;f=(e=nUd(a.b,b),e);if(f){d=BD(V1d(p1d(a,f),''),26);if(d){return s1d(a,d,b,c)}}return null} +function cTd(a,b){var c,d;for(d=new Fyd(a);d.e!=d.i.gc();){c=BD(Dyd(d),138);if(PD(b)===PD(c)){return true}}return false} +function vtd(a,b,c){var d;d=a.gc();if(b>d)throw vbb(new Cyd(b,d));if(a.hi()&&a.Hc(c)){throw vbb(new Wdb(kue))}a.Xh(b,c)} +function iqd(a,b){var c;c=oo(a.i,b);if(c==null){throw vbb(new cqd('Node did not exist in input.'))}Yqd(b,c);return null} +function $hd(a,b){var c;c=YKd(a,b);if(JD(c,322)){return BD(c,34)}throw vbb(new Wdb(ite+b+"' is not a valid attribute"))} +function V2d(a,b,c){var d,e;e=JD(b,99)&&(BD(b,18).Bb&Tje)!=0?new s4d(b,a):new p4d(b,a);for(d=0;d<c;++d){d4d(e)}return e} +function ede(a){var b,c,d;d=0;c=a.length;for(b=0;b<c;b++){a[b]==32||a[b]==13||a[b]==10||a[b]==9||(a[d++]=a[b])}return d} +function lYb(a){var b,c,d;b=new Rkb;for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),594);Gkb(b,BD(c.jf(),14))}return b} +function SSc(a){var b,c,d;b=BD(vNb(a,(mTc(),gTc)),15);for(d=b.Kc();d.Ob();){c=BD(d.Pb(),188);Dsb(c.b.d,c);Dsb(c.c.b,c)}} +function b5b(a){switch(BD(vNb(a,(wtc(),Osc)),303).g){case 1:yNb(a,Osc,(esc(),bsc));break;case 2:yNb(a,Osc,(esc(),dsc));}} +function _Fc(a){var b;if(a.g){b=a.c.Rf()?a.f:a.a;bGc(b.a,a.o,true);bGc(b.a,a.o,false);yNb(a.o,(Nyc(),Vxc),(dcd(),Zbd))}} +function loc(a){var b;if(!a.a){throw vbb(new Zdb('Cannot offset an unassigned cut.'))}b=a.c-a.b;a.b+=b;noc(a,b);ooc(a,b)} +function ckb(a){var b;b=a.a[a.c-1&a.a.length-1];if(b==null){return null}a.c=a.c-1&a.a.length-1;NC(a.a,a.c,null);return b} +function zGb(a){var b,c;for(c=a.p.a.ec().Kc();c.Ob();){b=BD(c.Pb(),213);if(b.f&&a.b[b.c]<-1.0E-10){return b}}return null} +function bLb(a,b){switch(a.b.g){case 0:case 1:return b;case 2:case 3:return new J6c(b.d,0,b.a,b.b);default:return null;}} +function had(a){switch(a.g){case 2:return bad;case 1:return aad;case 4:return _9c;case 3:return dad;default:return cad;}} +function Vcd(a){switch(a.g){case 1:return Tcd;case 2:return Acd;case 3:return zcd;case 4:return Rcd;default:return Scd;}} +function Wcd(a){switch(a.g){case 1:return Rcd;case 2:return Tcd;case 3:return Acd;case 4:return zcd;default:return Scd;}} +function Xcd(a){switch(a.g){case 1:return zcd;case 2:return Rcd;case 3:return Tcd;case 4:return Acd;default:return Scd;}} +function DPc(a){switch(a){case 0:return new OPc;case 1:return new EPc;case 2:return new JPc;default:throw vbb(new Vdb);}} +function Kdb(a,b){if(a<b){return -1}if(a>b){return 1}if(a==b){return a==0?Kdb(1/a,1/b):0}return isNaN(a)?isNaN(b)?0:1:-1} +function f4b(a,b){Odd(b,'Sort end labels',1);MAb(JAb(LAb(new YAb(null,new Kub(a.b,16)),new q4b),new s4b),new u4b);Qdd(b)} +function Wxd(a,b,c){var d,e;if(a.ej()){e=a.fj();d=sud(a,b,c);a.$i(a.Zi(7,meb(c),d,b,e));return d}else{return sud(a,b,c)}} +function vAd(a,b){var c,d,e;if(a.d==null){++a.e;--a.f}else{e=b.cd();c=b.Sh();d=(c&Ohe)%a.d.length;KAd(a,d,xAd(a,d,c,e))}} +function ZId(a,b){var c;c=(a.Bb&zte)!=0;b?(a.Bb|=zte):(a.Bb&=-1025);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,10,c,b))} +function dJd(a,b){var c;c=(a.Bb&Rje)!=0;b?(a.Bb|=Rje):(a.Bb&=-4097);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,12,c,b))} +function eJd(a,b){var c;c=(a.Bb&Cve)!=0;b?(a.Bb|=Cve):(a.Bb&=-8193);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,15,c,b))} +function fJd(a,b){var c;c=(a.Bb&Dve)!=0;b?(a.Bb|=Dve):(a.Bb&=-2049);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,11,c,b))} +function jOb(a,b){var c;c=Kdb(a.b.c,b.b.c);if(c!=0){return c}c=Kdb(a.a.a,b.a.a);if(c!=0){return c}return Kdb(a.a.b,b.a.b)} +function jqd(a,b){var c;c=Ohb(a.k,b);if(c==null){throw vbb(new cqd('Port did not exist in input.'))}Yqd(b,c);return null} +function k6d(a){var b,c;for(c=l6d(bKd(a)).Kc();c.Ob();){b=GD(c.Pb());if(Dmd(a,b)){return uFd((tFd(),sFd),b)}}return null} +function n3d(a,b){var c,d,e,f,g;g=S6d(a.e.Tg(),b);f=0;c=BD(a.g,119);for(e=0;e<a.i;++e){d=c[e];g.rl(d.ak())&&++f}return f} +function Vsd(a,b,c){var d,e;d=BD(b.We(a.a),35);e=BD(c.We(a.a),35);return d!=null&&e!=null?Fcb(d,e):d!=null?-1:e!=null?1:0} +function ved(a,b,c){var d,e;if(a.c){Efd(a.c,b,c)}else{for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),157);ved(d,b,c)}}} +function RUb(a,b){var c,d;for(d=new olb(b);d.a<d.c.c.length;){c=BD(mlb(d),46);Lkb(a.b.b,c.b);fVb(BD(c.a,189),BD(c.b,81))}} +function tr(a){var b,c;c=Kfb(new Ufb,91);b=true;while(a.Ob()){b||(c.a+=She,c);b=false;Pfb(c,a.Pb())}return (c.a+=']',c).a} +function aJd(a,b){var c;c=(a.Bb&oie)!=0;b?(a.Bb|=oie):(a.Bb&=-16385);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,16,c,b))} +function MJd(a,b){var c;c=(a.Bb&ote)!=0;b?(a.Bb|=ote):(a.Bb&=-32769);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,18,c,b))} +function CUd(a,b){var c;c=(a.Bb&ote)!=0;b?(a.Bb|=ote):(a.Bb&=-32769);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,18,c,b))} +function EUd(a,b){var c;c=(a.Bb&Tje)!=0;b?(a.Bb|=Tje):(a.Bb&=-65537);(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new qSd(a,1,20,c,b))} +function Tee(a){var b;b=KC(TD,$ie,25,2,15,1);a-=Tje;b[0]=(a>>10)+Uje&aje;b[1]=(a&1023)+56320&aje;return zfb(b,0,b.length)} +function a_b(a){var b,c;c=BD(vNb(a,(Nyc(),Lwc)),103);if(c==(ead(),cad)){b=Edb(ED(vNb(a,owc)));return b>=1?bad:_9c}return c} +function rec(a){switch(BD(vNb(a,(Nyc(),Swc)),218).g){case 1:return new Fmc;case 3:return new wnc;default:return new zmc;}} +function Uzb(a){if(a.c){Uzb(a.c)}else if(a.d){throw vbb(new Zdb("Stream already terminated, can't be modified or used"))}} +function Mkd(a){var b;if((a.Db&64)!=0)return Eid(a);b=new Jfb(Eid(a));b.a+=' (identifier: ';Efb(b,a.k);b.a+=')';return b.a} +function ctd(a,b,c){var d,e;d=(Fhd(),e=new xkd,e);vkd(d,b);wkd(d,c);!!a&&wtd((!a.a&&(a.a=new xMd(y2,a,5)),a.a),d);return d} +function ttb(a,b,c,d){var e,f;uCb(d);uCb(c);e=a.xc(b);f=e==null?c:Myb(BD(e,15),BD(c,14));f==null?a.Bc(b):a.zc(b,f);return f} +function pqb(a){var b,c,d,e;c=(b=BD(gdb((d=a.gm,e=d.f,e==CI?d:e)),9),new xqb(b,BD(_Bb(b,b.length),9),0));rqb(c,a);return c} +function hDc(a,b,c){var d,e;for(e=a.a.ec().Kc();e.Ob();){d=BD(e.Pb(),10);if(Be(c,BD(Ikb(b,d.p),14))){return d}}return null} +function Db(b,c,d){var e;try{Cb(b,c,d)}catch(a){a=ubb(a);if(JD(a,597)){e=a;throw vbb(new ycb(e))}else throw vbb(a)}return c} +function Qbb(a,b){var c;if(Fbb(a)&&Fbb(b)){c=a-b;if(Kje<c&&c<Ije){return c}}return zbb(nD(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b))} +function wbb(a,b){var c;if(Fbb(a)&&Fbb(b)){c=a+b;if(Kje<c&&c<Ije){return c}}return zbb(cD(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b))} +function Ibb(a,b){var c;if(Fbb(a)&&Fbb(b)){c=a*b;if(Kje<c&&c<Ije){return c}}return zbb(gD(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b))} +function V_b(a,b){var c;a.i||N_b(a);c=BD(Mpb(a.g,b),46);return !c?(mmb(),mmb(),jmb):new Jib(a.j,BD(c.a,19).a,BD(c.b,19).a)} +function Drb(a,b,c){var d;d=a.a.get(b);a.a.set(b,c===undefined?null:c);if(d===undefined){++a.c;zpb(a.b)}else{++a.d}return d} +function kNb(a,b,c){a.n=IC(XD,[nie,Sje],[364,25],14,[c,QD($wnd.Math.ceil(b/32))],2);a.o=b;a.p=c;a.j=b-1>>1;a.k=c-1>>1} +function Gub(){zub();var a,b,c;c=yub+++Date.now();a=QD($wnd.Math.floor(c*lke))&nke;b=QD(c-a*mke);this.a=a^1502;this.b=b^kke} +function O_b(a){var b,c,d;b=new Rkb;for(d=new olb(a.j);d.a<d.c.c.length;){c=BD(mlb(d),11);Ekb(b,c.b)}return Qb(b),new sl(b)} +function R_b(a){var b,c,d;b=new Rkb;for(d=new olb(a.j);d.a<d.c.c.length;){c=BD(mlb(d),11);Ekb(b,c.e)}return Qb(b),new sl(b)} +function U_b(a){var b,c,d;b=new Rkb;for(d=new olb(a.j);d.a<d.c.c.length;){c=BD(mlb(d),11);Ekb(b,c.g)}return Qb(b),new sl(b)} +function n6d(a){var b,c;for(c=o6d(bKd(WId(a))).Kc();c.Ob();){b=GD(c.Pb());if(Dmd(a,b))return FFd((EFd(),DFd),b)}return null} +function wm(a){var b,c,d;for(c=0,d=a.length;c<d;c++){if(a[c]==null){throw vbb(new Heb('at index '+c))}}b=a;return new amb(b)} +function wid(a,b){var c;c=YKd(a.Tg(),b);if(JD(c,99)){return BD(c,18)}throw vbb(new Wdb(ite+b+"' is not a valid reference"))} +function Tdb(a){var b;b=Hcb(a);if(b>3.4028234663852886E38){return Pje}else if(b<-3.4028234663852886E38){return Qje}return b} +function aeb(a){a-=a>>1&1431655765;a=(a>>2&858993459)+(a&858993459);a=(a>>4)+a&252645135;a+=a>>8;a+=a>>16;return a&63} +function Ev(a){var b,c,d,e;b=new cq(a.Hd().gc());e=0;for(d=vr(a.Hd().Kc());d.Ob();){c=d.Pb();bq(b,c,meb(e++))}return fn(b.a)} +function Uyb(a,b){var c,d,e;e=new Lqb;for(d=b.vc().Kc();d.Ob();){c=BD(d.Pb(),42);Rhb(e,c.cd(),Yyb(a,BD(c.dd(),15)))}return e} +function EZc(a,b){a.n.c.length==0&&Ekb(a.n,new VZc(a.s,a.t,a.i));Ekb(a.b,b);QZc(BD(Ikb(a.n,a.n.c.length-1),211),b);GZc(a,b)} +function LFb(a){if(a.c!=a.b.b||a.i!=a.g.b){a.a.c=KC(SI,Uhe,1,0,5,1);Gkb(a.a,a.b);Gkb(a.a,a.g);a.c=a.b.b;a.i=a.g.b}return a.a} +function Ycc(a,b){var c,d,e;e=0;for(d=BD(b.Kb(a),20).Kc();d.Ob();){c=BD(d.Pb(),17);Ccb(DD(vNb(c,(wtc(),ltc))))||++e}return e} +function efc(a,b){var c,d,e;d=tgc(b);e=Edb(ED(pBc(d,(Nyc(),lyc))));c=$wnd.Math.max(0,e/2-0.5);cfc(b,c,1);Ekb(a,new Dfc(b,c))} +function Ctc(){Ctc=ccb;Btc=new Dtc(ane,0);xtc=new Dtc('FIRST',1);ytc=new Dtc(Gne,2);ztc=new Dtc('LAST',3);Atc=new Dtc(Hne,4)} +function Aad(){Aad=ccb;zad=new Bad(ole,0);xad=new Bad('POLYLINE',1);wad=new Bad('ORTHOGONAL',2);yad=new Bad('SPLINES',3)} +function zYc(){zYc=ccb;xYc=new AYc('ASPECT_RATIO_DRIVEN',0);yYc=new AYc('MAX_SCALE_DRIVEN',1);wYc=new AYc('AREA_DRIVEN',2)} +function Y$c(){Y$c=ccb;V$c=new Z$c('P1_STRUCTURE',0);W$c=new Z$c('P2_PROCESSING_ORDER',1);X$c=new Z$c('P3_EXECUTION',2)} +function tVc(){tVc=ccb;sVc=new uVc('OVERLAP_REMOVAL',0);qVc=new uVc('COMPACTION',1);rVc=new uVc('GRAPH_SIZE_CALCULATION',2)} +function Jy(a,b){Iy();return My(Qie),$wnd.Math.abs(a-b)<=Qie||a==b||isNaN(a)&&isNaN(b)?0:a<b?-1:a>b?1:Ny(isNaN(a),isNaN(b))} +function yOc(a,b){var c,d;c=Jsb(a,0);while(c.b!=c.d.c){d=Gdb(ED(Xsb(c)));if(d==b){return}else if(d>b){Ysb(c);break}}Vsb(c,b)} +function t4c(a,b){var c,d,e,f,g;c=b.f;Xrb(a.c.d,c,b);if(b.g!=null){for(e=b.g,f=0,g=e.length;f<g;++f){d=e[f];Xrb(a.c.e,d,b)}}} +function Ilb(a,b,c,d){var e,f,g;for(e=b+1;e<c;++e){for(f=e;f>b&&d.ue(a[f-1],a[f])>0;--f){g=a[f];NC(a,f,a[f-1]);NC(a,f-1,g)}}} +function did(a,b,c,d){if(b<0){uid(a,c,d)}else{if(!c.Ij()){throw vbb(new Wdb(ite+c.ne()+jte))}BD(c,66).Nj().Tj(a,a.yh(),b,d)}} +function xFb(a,b){if(b==a.d){return a.e}else if(b==a.e){return a.d}else{throw vbb(new Wdb('Node '+b+' not part of edge '+a))}} +function iEb(a,b){switch(b.g){case 2:return a.b;case 1:return a.c;case 4:return a.d;case 3:return a.a;default:return false;}} +function GVb(a,b){switch(b.g){case 2:return a.b;case 1:return a.c;case 4:return a.d;case 3:return a.a;default:return false;}} +function Xkd(a,b,c,d){switch(b){case 3:return a.f;case 4:return a.g;case 5:return a.i;case 6:return a.j;}return Ekd(a,b,c,d)} +function Ljc(a){if(a.k!=(j0b(),h0b)){return false}return FAb(new YAb(null,new Lub(new Sr(ur(U_b(a).a.Kc(),new Sq)))),new Mjc)} +function MEd(a){if(a.e==null){return a}else !a.c&&(a.c=new NEd((a.f&256)!=0,a.i,a.a,a.d,(a.f&16)!=0,a.j,a.g,null));return a.c} +function VC(a,b){if(a.h==Gje&&a.m==0&&a.l==0){b&&(QC=TC(0,0,0));return SC((wD(),uD))}b&&(QC=TC(a.l,a.m,a.h));return TC(0,0,0)} +function fcb(a){var b;if(Array.isArray(a)&&a.im===gcb){return hdb(rb(a))+'@'+(b=tb(a)>>>0,b.toString(16))}return a.toString()} +function Rpb(a){var b;this.a=(b=BD(a.e&&a.e(),9),new xqb(b,BD(_Bb(b,b.length),9),0));this.b=KC(SI,Uhe,1,this.a.a.length,5,1)} +function _Ob(a){var b,c,d;this.a=new zsb;for(d=new olb(a);d.a<d.c.c.length;){c=BD(mlb(d),14);b=new MOb;GOb(b,c);Qqb(this.a,b)}} +function cKb(a){$Jb();var b,c,d,e;b=a.o.b;for(d=BD(BD(Qc(a.r,(Ucd(),Rcd)),21),84).Kc();d.Ob();){c=BD(d.Pb(),111);e=c.e;e.b+=b}} +function ag(a){var b;if(a.b){ag(a.b);if(a.b.d!=a.c){throw vbb(new Apb)}}else if(a.d.dc()){b=BD(a.f.c.xc(a.e),14);!!b&&(a.d=b)}} +function fFd(a){var b;if(a==null)return true;b=a.length;return b>0&&(BCb(b-1,a.length),a.charCodeAt(b-1)==58)&&!OEd(a,CEd,DEd)} +function OEd(a,b,c){var d,e;for(d=0,e=a.length;d<e;d++){if(_Ed((BCb(d,a.length),a.charCodeAt(d)),b,c))return true}return false} +function JOb(a,b){var c,d;for(d=a.e.a.ec().Kc();d.Ob();){c=BD(d.Pb(),266);if(t6c(b,c.d)||o6c(b,c.d)){return true}}return false} +function Q9b(a,b){var c,d,e;d=N9b(a,b);e=d[d.length-1]/2;for(c=0;c<d.length;c++){if(d[c]>=e){return b.c+c}}return b.c+b.b.gc()} +function NCd(a,b){LCd();var c,d,e,f;d=KLd(a);e=b;Klb(d,0,d.length,e);for(c=0;c<d.length;c++){f=MCd(a,d[c],c);c!=f&&Wxd(a,c,f)}} +function EHb(a,b){var c,d,e,f,g,h;d=0;c=0;for(f=b,g=0,h=f.length;g<h;++g){e=f[g];if(e>0){d+=e;++c}}c>1&&(d+=a.d*(c-1));return d} +function Htd(a){var b,c,d;d=new Hfb;d.a+='[';for(b=0,c=a.gc();b<c;){Efb(d,xfb(a.ki(b)));++b<c&&(d.a+=She,d)}d.a+=']';return d.a} +function fsd(a){var b,c,d,e,f;f=hsd(a);c=Fhe(a.c);d=!c;if(d){e=new wB;cC(f,'knownLayouters',e);b=new qsd(e);reb(a.c,b)}return f} +function Ce(a,b){var c,d,e;uCb(b);c=false;for(d=new olb(a);d.a<d.c.c.length;){e=mlb(d);if(ze(b,e,false)){nlb(d);c=true}}return c} +function UGb(a){var b,c,d;d=Edb(ED(a.a.We((Y9c(),Q9c))));for(c=new olb(a.a.xf());c.a<c.c.c.length;){b=BD(mlb(c),680);XGb(a,b,d)}} +function MUb(a,b){var c,d;for(d=new olb(b);d.a<d.c.c.length;){c=BD(mlb(d),46);Ekb(a.b.b,BD(c.b,81));eVb(BD(c.a,189),BD(c.b,81))}} +function XCc(a,b,c){var d,e;e=a.a.b;for(d=e.c.length;d<c;d++){Dkb(e,0,new H1b(a.a))}$_b(b,BD(Ikb(e,e.c.length-c),29));a.b[b.p]=c} +function JTb(a,b,c){var d;d=c;!d&&(d=Ydd(new Zdd,0));Odd(d,Vme,2);qZb(a.b,b,Udd(d,1));LTb(a,b,Udd(d,1));_Yb(b,Udd(d,1));Qdd(d)} +function eKc(a,b,c,d,e){FJc();AFb(DFb(CFb(BFb(EFb(new FFb,0),e.d.e-a),b),e.d));AFb(DFb(CFb(BFb(EFb(new FFb,0),c-e.a.e),e.a),d))} +function e$c(a,b,c,d,e,f){this.a=a;this.c=b;this.b=c;this.f=d;this.d=e;this.e=f;this.c>0&&this.b>0&&q$c(this.c,this.b,this.a)} +function ezc(a){dzc();this.c=Ou(OC(GC(h0,1),Uhe,831,0,[Uyc]));this.b=new Lqb;this.a=a;Rhb(this.b,bzc,1);Hkb(czc,new Xed(this))} +function I2c(a,b){var c;if(a.d){if(Mhb(a.b,b)){return BD(Ohb(a.b,b),51)}else{c=b.Kf();Rhb(a.b,b,c);return c}}else{return b.Kf()}} +function Kgb(a,b){var c;if(PD(a)===PD(b)){return true}if(JD(b,91)){c=BD(b,91);return a.e==c.e&&a.d==c.d&&Lgb(a,c.a)}return false} +function Zcd(a){Ucd();switch(a.g){case 4:return Acd;case 1:return zcd;case 3:return Rcd;case 2:return Tcd;default:return Scd;}} +function Ykd(a,b){switch(b){case 3:return a.f!=0;case 4:return a.g!=0;case 5:return a.i!=0;case 6:return a.j!=0;}return Hkd(a,b)} +function gWc(a){switch(a.g){case 0:return new FXc;case 1:return new IXc;default:throw vbb(new Wdb(jre+(a.f!=null?a.f:''+a.g)));}} +function QUc(a){switch(a.g){case 0:return new CXc;case 1:return new MXc;default:throw vbb(new Wdb(Dne+(a.f!=null?a.f:''+a.g)));}} +function b1c(a){switch(a.g){case 0:return new s1c;case 1:return new w1c;default:throw vbb(new Wdb(Mre+(a.f!=null?a.f:''+a.g)));}} +function qWc(a){switch(a.g){case 1:return new SVc;case 2:return new KVc;default:throw vbb(new Wdb(jre+(a.f!=null?a.f:''+a.g)));}} +function ryb(a){var b,c;if(a.b){return a.b}c=lyb?null:a.d;while(c){b=lyb?null:c.b;if(b){return b}c=lyb?null:c.d}return $xb(),Zxb} +function hhb(a){var b,c,d;if(a.e==0){return 0}b=a.d<<5;c=a.a[a.d-1];if(a.e<0){d=Mgb(a);if(d==a.d-1){--c;c=c|0}}b-=heb(c);return b} +function bhb(a){var b,c,d;if(a<Fgb.length){return Fgb[a]}c=a>>5;b=a&31;d=KC(WD,oje,25,c+1,15,1);d[c]=1<<b;return new Vgb(1,c+1,d)} +function O2b(a){var b,c,d;c=a.zg();if(c){b=a.Ug();if(JD(b,160)){d=O2b(BD(b,160));if(d!=null){return d+'.'+c}}return c}return null} +function ze(a,b,c){var d,e;for(e=a.Kc();e.Ob();){d=e.Pb();if(PD(b)===PD(d)||b!=null&&pb(b,d)){c&&e.Qb();return true}}return false} +function zvd(a,b,c){var d,e;++a.j;if(c.dc()){return false}else{for(e=c.Kc();e.Ob();){d=e.Pb();a.Hi(b,a.oi(b,d));++b}return true}} +function yA(a,b,c,d){var e,f;f=c-b;if(f<3){while(f<3){a*=10;++f}}else{e=1;while(f>3){e*=10;--f}a=(a+(e>>1))/e|0}d.i=a;return true} +function XUb(a){LUb();return Bcb(),GVb(BD(a.a,81).j,BD(a.b,103))||BD(a.a,81).d.e!=0&&GVb(BD(a.a,81).j,BD(a.b,103))?true:false} +function s3c(a){p3c();if(BD(a.We((Y9c(),b9c)),174).Hc((Idd(),Gdd))){BD(a.We(x9c),174).Fc((rcd(),qcd));BD(a.We(b9c),174).Mc(Gdd)}} +function Gxd(a,b){var c,d;if(!b){return false}else{for(c=0;c<a.i;++c){d=BD(a.g[c],366);if(d.Di(b)){return false}}return wtd(a,b)}} +function pvd(a){var b,c,d,e;b=new wB;for(e=new Dnb(a.b.Kc());e.b.Ob();){d=BD(e.b.Pb(),686);c=lsd(d);uB(b,b.a.length,c)}return b.a} +function cLb(a){var b;!a.c&&(a.c=new VKb);Okb(a.d,new jLb);_Kb(a);b=UKb(a);MAb(new YAb(null,new Kub(a.d,16)),new CLb(a));return b} +function mKd(a){var b;if((a.Db&64)!=0)return qnd(a);b=new Jfb(qnd(a));b.a+=' (instanceClassName: ';Efb(b,a.D);b.a+=')';return b.a} +function Pqd(a,b){var c,d,e,f;if(b){e=Xpd(b,'x');c=new bsd(a);hmd(c.a,(uCb(e),e));f=Xpd(b,'y');d=new csd(a);imd(d.a,(uCb(f),f))}} +function Eqd(a,b){var c,d,e,f;if(b){e=Xpd(b,'x');c=new Yrd(a);omd(c.a,(uCb(e),e));f=Xpd(b,'y');d=new _rd(a);pmd(d.a,(uCb(f),f))}} +function bLd(a,b){var c,d,e;c=(a.i==null&&TKd(a),a.i);d=b.aj();if(d!=-1){for(e=c.length;d<e;++d){if(c[d]==b){return d}}}return -1} +function tNd(a){var b,c,d,e,f;c=BD(a.g,674);for(d=a.i-1;d>=0;--d){b=c[d];for(e=0;e<d;++e){f=c[e];if(uNd(a,b,f)){tud(a,d);break}}}} +function jCb(b){var c=b.e;function d(a){if(!a||a.length==0){return ''}return '\t'+a.join('\n\t')} +return c&&(c.stack||d(b[Yie]))} +function nm(a){im();var b;b=a.Pc();switch(b.length){case 0:return hm;case 1:return new my(Qb(b[0]));default:return new ux(wm(b));}} +function W_b(a,b){switch(b.g){case 1:return Nq(a.j,(z0b(),u0b));case 2:return Nq(a.j,(z0b(),w0b));default:return mmb(),mmb(),jmb;}} +function $kd(a,b){switch(b){case 3:ald(a,0);return;case 4:cld(a,0);return;case 5:dld(a,0);return;case 6:eld(a,0);return;}Jkd(a,b)} +function dzc(){dzc=ccb;Vyc();bzc=(Nyc(),vyc);czc=Ou(OC(GC(Q3,1),zqe,146,0,[kyc,lyc,nyc,oyc,ryc,syc,tyc,uyc,xyc,zyc,myc,pyc,wyc]))} +function Y9b(a){var b,c;b=a.d==(Apc(),vpc);c=U9b(a);b&&!c||!b&&c?yNb(a.a,(Nyc(),mwc),(F7c(),D7c)):yNb(a.a,(Nyc(),mwc),(F7c(),C7c))} +function XAb(a,b){var c;c=BD(GAb(a,Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);return c.Qc(aBb(c.gc()))} +function Ded(){Ded=ccb;Ced=new Eed('SIMPLE',0);zed=new Eed('GROUP_DEC',1);Bed=new Eed('GROUP_MIXED',2);Aed=new Eed('GROUP_INC',3)} +function CWd(){CWd=ccb;AWd=new DWd;tWd=new GWd;uWd=new JWd;vWd=new MWd;wWd=new PWd;xWd=new SWd;yWd=new VWd;zWd=new YWd;BWd=new _Wd} +function FHb(a,b,c){tHb();oHb.call(this);this.a=IC(oN,[nie,ile],[595,212],0,[sHb,rHb],2);this.c=new I6c;this.g=a;this.f=b;this.d=c} +function pNb(a,b){this.n=IC(XD,[nie,Sje],[364,25],14,[b,QD($wnd.Math.ceil(a/32))],2);this.o=a;this.p=b;this.j=a-1>>1;this.k=b-1>>1} +function r3b(a,b){Odd(b,'End label post-processing',1);MAb(JAb(LAb(new YAb(null,new Kub(a.b,16)),new w3b),new y3b),new A3b);Qdd(b)} +function NLc(a,b,c){var d,e;d=Edb(a.p[b.i.p])+Edb(a.d[b.i.p])+b.n.b+b.a.b;e=Edb(a.p[c.i.p])+Edb(a.d[c.i.p])+c.n.b+c.a.b;return e-d} +function xhb(a,b,c){var d,e;d=xbb(c,Yje);for(e=0;ybb(d,0)!=0&&e<b;e++){d=wbb(d,xbb(a[e],Yje));a[e]=Tbb(d);d=Obb(d,32)}return Tbb(d)} +function $Ed(a){var b,c,d,e;e=0;for(c=0,d=a.length;c<d;c++){b=(BCb(c,a.length),a.charCodeAt(c));b<64&&(e=Mbb(e,Nbb(1,b)))}return e} +function S9d(a){var b;return a==null?null:new Ygb((b=Qge(a,true),b.length>0&&(BCb(0,b.length),b.charCodeAt(0)==43)?b.substr(1):b))} +function T9d(a){var b;return a==null?null:new Ygb((b=Qge(a,true),b.length>0&&(BCb(0,b.length),b.charCodeAt(0)==43)?b.substr(1):b))} +function xud(a,b){var c;if(a.i>0){if(b.length<a.i){c=izd(rb(b).c,a.i);b=c}$fb(a.g,0,b,0,a.i)}b.length>a.i&&NC(b,a.i,null);return b} +function Sxd(a,b,c){var d,e,f;if(a.ej()){d=a.i;f=a.fj();kud(a,d,b);e=a.Zi(3,null,b,d,f);!c?(c=e):c.Ei(e)}else{kud(a,a.i,b)}return c} +function HMd(a,b,c){var d,e;d=new pSd(a.e,4,10,(e=b.c,JD(e,88)?BD(e,26):(jGd(),_Fd)),null,HLd(a,b),false);!c?(c=d):c.Ei(d);return c} +function GMd(a,b,c){var d,e;d=new pSd(a.e,3,10,null,(e=b.c,JD(e,88)?BD(e,26):(jGd(),_Fd)),HLd(a,b),false);!c?(c=d):c.Ei(d);return c} +function _Jb(a){$Jb();var b;b=new g7c(BD(a.e.We((Y9c(),_8c)),8));if(a.B.Hc((Idd(),Bdd))){b.a<=0&&(b.a=20);b.b<=0&&(b.b=20)}return b} +function Lzc(a){Izc();var b;(!a.q?(mmb(),mmb(),kmb):a.q)._b((Nyc(),Cxc))?(b=BD(vNb(a,Cxc),197)):(b=BD(vNb(Q_b(a),Dxc),197));return b} +function pBc(a,b){var c,d;d=null;if(wNb(a,(Nyc(),qyc))){c=BD(vNb(a,qyc),94);c.Xe(b)&&(d=c.We(b))}d==null&&(d=vNb(Q_b(a),b));return d} +function Ze(a,b){var c,d,e;if(JD(b,42)){c=BD(b,42);d=c.cd();e=Hv(a.Rc(),d);return Hb(e,c.dd())&&(e!=null||a.Rc()._b(d))}return false} +function qAd(a,b){var c,d,e;if(a.f>0){a.qj();d=b==null?0:tb(b);e=(d&Ohe)%a.d.length;c=xAd(a,e,d,b);return c!=-1}else{return false}} +function AAd(a,b){var c,d,e;if(a.f>0){a.qj();d=b==null?0:tb(b);e=(d&Ohe)%a.d.length;c=wAd(a,e,d,b);if(c){return c.dd()}}return null} +function R2d(a,b){var c,d,e,f;f=S6d(a.e.Tg(),b);c=BD(a.g,119);for(e=0;e<a.i;++e){d=c[e];if(f.rl(d.ak())){return false}}return true} +function B6d(a){if(a.b==null){while(a.a.Ob()){a.b=a.a.Pb();if(!BD(a.b,49).Zg()){return true}}a.b=null;return false}else{return true}} +function Myd(b,c){b.mj();try{b.d.Vc(b.e++,c);b.f=b.d.j;b.g=-1}catch(a){a=ubb(a);if(JD(a,73)){throw vbb(new Apb)}else throw vbb(a)}} +function IA(a,b){GA();var c,d;c=LA((KA(),KA(),JA));d=null;b==c&&(d=BD(Phb(FA,a),615));if(!d){d=new HA(a);b==c&&Shb(FA,a,d)}return d} +function Epb(a,b){var c,d;a.a=wbb(a.a,1);a.c=$wnd.Math.min(a.c,b);a.b=$wnd.Math.max(a.b,b);a.d+=b;c=b-a.f;d=a.e+c;a.f=d-a.e-c;a.e=d} +function ogb(a,b){var c;a.c=b;a.a=hhb(b);a.a<54&&(a.f=(c=b.d>1?Mbb(Nbb(b.a[1],32),xbb(b.a[0],Yje)):xbb(b.a[0],Yje),Sbb(Ibb(b.e,c))))} +function Hbb(a,b){var c;if(Fbb(a)&&Fbb(b)){c=a%b;if(Kje<c&&c<Ije){return c}}return zbb((UC(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b,true),QC))} +function p5b(a,b){var c;m5b(b);c=BD(vNb(a,(Nyc(),Rwc)),276);!!c&&yNb(a,Rwc,Tqc(c));n5b(a.c);n5b(a.f);o5b(a.d);o5b(BD(vNb(a,wxc),207))} +function rHc(a){this.e=KC(WD,oje,25,a.length,15,1);this.c=KC(sbb,dle,25,a.length,16,1);this.b=KC(sbb,dle,25,a.length,16,1);this.f=0} +function BDc(a){var b,c;a.j=KC(UD,Vje,25,a.p.c.length,15,1);for(c=new olb(a.p);c.a<c.c.c.length;){b=BD(mlb(c),10);a.j[b.p]=b.o.b/a.i}} +function yic(a){var b;if(a.c==0){return}b=BD(Ikb(a.a,a.b),287);b.b==1?(++a.b,a.b<a.a.c.length&&Cic(BD(Ikb(a.a,a.b),287))):--b.b;--a.c} +function eac(a){var b;b=a.a;do{b=BD(Rr(new Sr(ur(U_b(b).a.Kc(),new Sq))),17).d.i;b.k==(j0b(),g0b)&&Ekb(a.e,b)}while(b.k==(j0b(),g0b))} +function idd(){idd=ccb;fdd=new q0b(15);edd=new Osd((Y9c(),f9c),fdd);hdd=new Osd(T9c,15);gdd=new Osd(E9c,meb(0));ddd=new Osd(r8c,tme)} +function tdd(){tdd=ccb;rdd=new udd('PORTS',0);sdd=new udd('PORT_LABELS',1);qdd=new udd('NODE_LABELS',2);pdd=new udd('MINIMUM_SIZE',3)} +function Ree(a,b){var c,d;d=b.length;for(c=0;c<d;c+=2)Ufe(a,(BCb(c,b.length),b.charCodeAt(c)),(BCb(c+1,b.length),b.charCodeAt(c+1)))} +function _Zc(a,b,c){var d,e,f,g;f=b-a.e;g=c-a.f;for(e=new olb(a.a);e.a<e.c.c.length;){d=BD(mlb(e),187);OZc(d,d.s+f,d.t+g)}a.e=b;a.f=c} +function jUc(a,b){var c,d,e,f;f=b.b.b;a.a=new Psb;a.b=KC(WD,oje,25,f,15,1);c=0;for(e=Jsb(b.b,0);e.b!=e.d.c;){d=BD(Xsb(e),86);d.g=c++}} +function ihb(a,b){var c,d,e,f;c=b>>5;b&=31;e=a.d+c+(b==0?0:1);d=KC(WD,oje,25,e,15,1);jhb(d,a.a,c,b);f=new Vgb(a.e,e,d);Jgb(f);return f} +function Ofe(a,b,c){var d,e;d=BD(Phb(Zee,b),117);e=BD(Phb($ee,b),117);if(c){Shb(Zee,a,d);Shb($ee,a,e)}else{Shb($ee,a,d);Shb(Zee,a,e)}} +function Cwb(a,b,c){var d,e,f;e=null;f=a.b;while(f){d=a.a.ue(b,f.d);if(c&&d==0){return f}if(d>=0){f=f.a[1]}else{e=f;f=f.a[0]}}return e} +function Dwb(a,b,c){var d,e,f;e=null;f=a.b;while(f){d=a.a.ue(b,f.d);if(c&&d==0){return f}if(d<=0){f=f.a[0]}else{e=f;f=f.a[1]}}return e} +function Nic(a,b,c,d){var e,f,g;e=false;if(fjc(a.f,c,d)){ijc(a.f,a.a[b][c],a.a[b][d]);f=a.a[b];g=f[d];f[d]=f[c];f[c]=g;e=true}return e} +function QHc(a,b,c,d,e){var f,g,h;g=e;while(b.b!=b.c){f=BD(fkb(b),10);h=BD(V_b(f,d).Xb(0),11);a.d[h.p]=g++;c.c[c.c.length]=h}return g} +function hBc(a,b,c){var d,e,f,g,h;g=a.k;h=b.k;d=c[g.g][h.g];e=ED(pBc(a,d));f=ED(pBc(b,d));return $wnd.Math.max((uCb(e),e),(uCb(f),f))} +function zZc(a,b,c){var d,e,f,g;d=c/a.c.length;e=0;for(g=new olb(a);g.a<g.c.c.length;){f=BD(mlb(g),200);w$c(f,f.f+d*e);t$c(f,b,d);++e}} +function hnc(a,b,c){var d,e,f,g;e=BD(Ohb(a.b,c),177);d=0;for(g=new olb(b.j);g.a<g.c.c.length;){f=BD(mlb(g),113);e[f.d.p]&&++d}return d} +function mzd(a){var b,c;b=BD(Ajd(a.a,4),126);if(b!=null){c=KC($3,hve,415,b.length,0,1);$fb(b,0,c,0,b.length);return c}else{return jzd}} +function Cz(){var a;if(xz!=0){a=sz();if(a-yz>2000){yz=a;zz=$wnd.setTimeout(Iz,10)}}if(xz++==0){Lz((Kz(),Jz));return true}return false} +function wCc(a,b){var c,d,e;for(d=new Sr(ur(U_b(a).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);e=c.d.i;if(e.c==b){return false}}return true} +function Ek(b,c){var d,e;if(JD(c,245)){e=BD(c,245);try{d=b.vd(e);return d==0}catch(a){a=ubb(a);if(!JD(a,205))throw vbb(a)}}return false} +function Xz(){if(Error.stackTraceLimit>0){$wnd.Error.stackTraceLimit=Error.stackTraceLimit=64;return true}return 'stack' in new Error} +function BDb(a,b){return Iy(),Iy(),My(Qie),($wnd.Math.abs(a-b)<=Qie||a==b||isNaN(a)&&isNaN(b)?0:a<b?-1:a>b?1:Ny(isNaN(a),isNaN(b)))>0} +function DDb(a,b){return Iy(),Iy(),My(Qie),($wnd.Math.abs(a-b)<=Qie||a==b||isNaN(a)&&isNaN(b)?0:a<b?-1:a>b?1:Ny(isNaN(a),isNaN(b)))<0} +function CDb(a,b){return Iy(),Iy(),My(Qie),($wnd.Math.abs(a-b)<=Qie||a==b||isNaN(a)&&isNaN(b)?0:a<b?-1:a>b?1:Ny(isNaN(a),isNaN(b)))<=0} +function ydb(a,b){var c=0;while(!b[c]||b[c]==''){c++}var d=b[c++];for(;c<b.length;c++){if(!b[c]||b[c]==''){continue}d+=a+b[c]}return d} +function zfb(a,b,c){var d,e,f,g;f=b+c;ACb(b,f,a.length);g='';for(e=b;e<f;){d=$wnd.Math.min(e+10000,f);g+=vfb(a.slice(e,d));e=d}return g} +function N9d(a){var b,c,d,e,f;if(a==null)return null;f=new Rkb;for(c=Zmd(a),d=0,e=c.length;d<e;++d){b=c[d];Ekb(f,Qge(b,true))}return f} +function Q9d(a){var b,c,d,e,f;if(a==null)return null;f=new Rkb;for(c=Zmd(a),d=0,e=c.length;d<e;++d){b=c[d];Ekb(f,Qge(b,true))}return f} +function R9d(a){var b,c,d,e,f;if(a==null)return null;f=new Rkb;for(c=Zmd(a),d=0,e=c.length;d<e;++d){b=c[d];Ekb(f,Qge(b,true))}return f} +function ted(a,b){var c,d,e;if(a.c){cld(a.c,b)}else{c=b-red(a);for(e=new olb(a.d);e.a<e.c.c.length;){d=BD(mlb(e),157);ted(d,red(d)+c)}}} +function sed(a,b){var c,d,e;if(a.c){ald(a.c,b)}else{c=b-qed(a);for(e=new olb(a.a);e.a<e.c.c.length;){d=BD(mlb(e),157);sed(d,qed(d)+c)}}} +function t6d(a,b){var c,d,e,f;e=new Skb(b.gc());for(d=b.Kc();d.Ob();){c=d.Pb();f=s6d(a,BD(c,56));!!f&&(e.c[e.c.length]=f,true)}return e} +function LAd(a,b){var c,d,e;a.qj();d=b==null?0:tb(b);e=(d&Ohe)%a.d.length;c=wAd(a,e,d,b);if(c){JAd(a,c);return c.dd()}else{return null}} +function rde(a){var b,c;c=sde(a);b=null;while(a.c==2){nde(a);if(!b){b=(wfe(),wfe(),++vfe,new Lge(2));Kge(b,c);c=b}c.$l(sde(a))}return c} +function Wpd(a){var b,c,d;d=null;b=Vte in a.a;c=!b;if(c){throw vbb(new cqd('Every element must have an id.'))}d=Vpd(aC(a,Vte));return d} +function jid(a){var b,c,d;d=a.Zg();if(!d){b=0;for(c=a.eh();c;c=c.eh()){if(++b>Wje){return c.fh()}d=c.Zg();if(!!d||c==a){break}}}return d} +function fvd(a){evd();if(JD(a,156)){return BD(Ohb(cvd,hK),288).vg(a)}if(Mhb(cvd,rb(a))){return BD(Ohb(cvd,rb(a)),288).vg(a)}return null} +function fZd(a){if(efb(kse,a)){return Bcb(),Acb}else if(efb(lse,a)){return Bcb(),zcb}else{throw vbb(new Wdb('Expecting true or false'))}} +function uDc(a,b){if(b.c==a){return b.d}else if(b.d==a){return b.c}throw vbb(new Wdb('Input edge is not connected to the input port.'))} +function Igb(a,b){if(a.e>b.e){return 1}if(a.e<b.e){return -1}if(a.d>b.d){return a.e}if(a.d<b.d){return -b.e}return a.e*whb(a.a,b.a,a.d)} +function Zcb(a){if(a>=48&&a<48+$wnd.Math.min(10,10)){return a-48}if(a>=97&&a<97){return a-97+10}if(a>=65&&a<65){return a-65+10}return -1} +function Ue(a,b){var c;if(PD(b)===PD(a)){return true}if(!JD(b,21)){return false}c=BD(b,21);if(c.gc()!=a.gc()){return false}return a.Ic(c)} +function ekb(a,b){var c,d,e,f;d=a.a.length-1;c=b-a.b&d;f=a.c-b&d;e=a.c-a.b&d;mkb(c<e);if(c>=f){hkb(a,b);return -1}else{ikb(a,b);return 1}} +function lA(a,b){var c,d;c=(BCb(b,a.length),a.charCodeAt(b));d=b+1;while(d<a.length&&(BCb(d,a.length),a.charCodeAt(d)==c)){++d}return d-b} +function sJb(a){switch(a.g){case 12:case 13:case 14:case 15:case 16:case 17:case 18:case 19:case 20:return true;default:return false;}} +function bC(f,a){var b=f.a;var c;a=String(a);b.hasOwnProperty(a)&&(c=b[a]);var d=(rC(),qC)[typeof c];var e=d?d(c):xC(typeof c);return e} +function b3c(a,b){if(a.a<0){throw vbb(new Zdb('Did not call before(...) or after(...) before calling add(...).'))}i3c(a,a.a,b);return a} +function VOc(a,b,c,d){var e,f;if(b.c.length==0){return}e=ROc(c,d);f=QOc(b);MAb(VAb(new YAb(null,new Kub(f,1)),new cPc),new gPc(a,c,e,d))} +function Cjd(a,b,c){var d;if((a.Db&b)!=0){if(c==null){Bjd(a,b)}else{d=zjd(a,b);d==-1?(a.Eb=c):NC(CD(a.Eb),d,c)}}else c!=null&&vjd(a,b,c)} +function yjd(a){var b,c;if((a.Db&32)==0){c=(b=BD(Ajd(a,16),26),aLd(!b?a.zh():b)-aLd(a.zh()));c!=0&&Cjd(a,32,KC(SI,Uhe,1,c,5,1))}return a} +function W1d(a){var b;a.b||X1d(a,(b=h1d(a.e,a.a),!b||!dfb(lse,AAd((!b.b&&(b.b=new sId((jGd(),fGd),x6,b)),b.b),'qualified'))));return a.c} +function dTd(a,b,c){var d,e,f;d=BD(qud(QSd(a.a),b),87);f=(e=d.c,e?e:(jGd(),YFd));(f.kh()?xid(a.b,BD(f,49)):f)==c?KQd(d):NQd(d,c);return f} +function fCb(a,b){(!b&&console.groupCollapsed!=null?console.groupCollapsed:console.group!=null?console.group:console.log).call(console,a)} +function NNb(a,b,c,d){d==a?(BD(c.b,65),BD(c.b,65),BD(d.b,65),BD(d.b,65).c.b):(BD(c.b,65),BD(c.b,65),BD(d.b,65),BD(d.b,65).c.b);KNb(d,b,a)} +function EOb(a){var b,c,d;b=0;for(c=new olb(a.g);c.a<c.c.c.length;){BD(mlb(c),562);++b}d=new ENb(a.g,Edb(a.a),a.c);ELb(d);a.g=d.b;a.d=d.a} +function ymc(a,b,c){b.b=$wnd.Math.max(b.b,-c.a);b.c=$wnd.Math.max(b.c,c.a-a.a);b.d=$wnd.Math.max(b.d,-c.b);b.a=$wnd.Math.max(b.a,c.b-a.b)} +function MIc(a,b){if(a.e<b.e){return -1}else if(a.e>b.e){return 1}else if(a.f<b.f){return -1}else if(a.f>b.f){return 1}return tb(a)-tb(b)} +function efb(a,b){uCb(a);if(b==null){return false}if(dfb(a,b)){return true}return a.length==b.length&&dfb(a.toLowerCase(),b.toLowerCase())} +function x6d(a,b){var c,d,e,f;for(d=0,e=b.gc();d<e;++d){c=b.il(d);if(JD(c,99)&&(BD(c,18).Bb&ote)!=0){f=b.jl(d);f!=null&&s6d(a,BD(f,56))}}} +function p1c(a,b,c){var d,e,f;for(f=new olb(c.a);f.a<f.c.c.length;){e=BD(mlb(f),221);d=new hDb(BD(Ohb(a.a,e.b),65));Ekb(b.a,d);p1c(a,d,e)}} +function Aeb(a){var b,c;if(ybb(a,-129)>0&&ybb(a,128)<0){b=Tbb(a)+128;c=(Ceb(),Beb)[b];!c&&(c=Beb[b]=new teb(a));return c}return new teb(a)} +function _0d(a,b){var c,d;c=b.Hh(a.a);if(c){d=GD(AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),fue));if(d!=null){return d}}return b.ne()} +function a1d(a,b){var c,d;c=b.Hh(a.a);if(c){d=GD(AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),fue));if(d!=null){return d}}return b.ne()} +function FMc(a,b){wMc();var c,d;for(d=new Sr(ur(O_b(a).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);if(c.d.i==b||c.c.i==b){return c}}return null} +function HUb(a,b,c){this.c=a;this.f=new Rkb;this.e=new d7c;this.j=new IVb;this.n=new IVb;this.b=b;this.g=new J6c(b.c,b.d,b.b,b.a);this.a=c} +function gVb(a){var b,c,d,e;this.a=new zsb;this.d=new Tqb;this.e=0;for(c=a,d=0,e=c.length;d<e;++d){b=c[d];!this.f&&(this.f=b);eVb(this,b)}} +function Xgb(a){Hgb();if(a.length==0){this.e=0;this.d=1;this.a=OC(GC(WD,1),oje,25,15,[0])}else{this.e=1;this.d=a.length;this.a=a;Jgb(this)}} +function mIb(a,b,c){oHb.call(this);this.a=KC(oN,ile,212,(gHb(),OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb])).length,0,1);this.b=a;this.d=b;this.c=c} +function Kjc(a){this.d=new Rkb;this.e=new $rb;this.c=KC(WD,oje,25,(Ucd(),OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd])).length,15,1);this.b=a} +function Vbc(a){var b,c,d,e,f,g;g=BD(vNb(a,(wtc(),$sc)),11);yNb(g,qtc,a.i.n.b);b=k_b(a.e);for(d=b,e=0,f=d.length;e<f;++e){c=d[e];RZb(c,g)}} +function Wbc(a){var b,c,d,e,f,g;c=BD(vNb(a,(wtc(),$sc)),11);yNb(c,qtc,a.i.n.b);b=k_b(a.g);for(e=b,f=0,g=e.length;f<g;++f){d=e[f];QZb(d,c)}} +function vcc(a){var b,c;if(wNb(a.d.i,(Nyc(),Nxc))){b=BD(vNb(a.c.i,Nxc),19);c=BD(vNb(a.d.i,Nxc),19);return beb(b.a,c.a)>0}else{return false}} +function q2c(a){var b;if(PD(hkd(a,(Y9c(),J8c)))===PD((hbd(),fbd))){if(!Xod(a)){jkd(a,J8c,gbd)}else{b=BD(hkd(Xod(a),J8c),334);jkd(a,J8c,b)}}} +function ijc(a,b,c){var d,e;bIc(a.e,b,c,(Ucd(),Tcd));bIc(a.i,b,c,zcd);if(a.a){e=BD(vNb(b,(wtc(),$sc)),11);d=BD(vNb(c,$sc),11);cIc(a.g,e,d)}} +function OEc(a,b,c){var d,e,f;d=b.c.p;f=b.p;a.b[d][f]=new $Ec(a,b);if(c){a.a[d][f]=new FEc(b);e=BD(vNb(b,(wtc(),Psc)),10);!!e&&Rc(a.d,e,b)}} +function TPb(a,b){var c,d,e;Ekb(PPb,a);b.Fc(a);c=BD(Ohb(OPb,a),21);if(c){for(e=c.Kc();e.Ob();){d=BD(e.Pb(),33);Jkb(PPb,d,0)!=-1||TPb(d,b)}}} +function tyb(a,b,c){var d;(jyb?(ryb(a),true):kyb?($xb(),true):nyb?($xb(),true):myb&&($xb(),false))&&(d=new iyb(b),d.b=c,pyb(a,d),undefined)} +function xKb(a,b){var c;c=!a.A.Hc((tdd(),sdd))||a.q==(dcd(),$bd);a.u.Hc((rcd(),ncd))?c?vKb(a,b):zKb(a,b):a.u.Hc(pcd)&&(c?wKb(a,b):AKb(a,b))} +function b0d(a,b){var c,d;++a.j;if(b!=null){c=(d=a.a.Cb,JD(d,97)?BD(d,97).Jg():null);if(xlb(b,c)){Cjd(a.a,4,c);return}}Cjd(a.a,4,BD(b,126))} +function dYb(a,b,c){return new J6c($wnd.Math.min(a.a,b.a)-c/2,$wnd.Math.min(a.b,b.b)-c/2,$wnd.Math.abs(a.a-b.a)+c,$wnd.Math.abs(a.b-b.b)+c)} +function k4b(a,b){var c,d;c=beb(a.a.c.p,b.a.c.p);if(c!=0){return c}d=beb(a.a.d.i.p,b.a.d.i.p);if(d!=0){return d}return beb(b.a.d.p,a.a.d.p)} +function _Dc(a,b,c){var d,e,f,g;f=b.j;g=c.j;if(f!=g){return f.g-g.g}else{d=a.f[b.p];e=a.f[c.p];return d==0&&e==0?0:d==0?-1:e==0?1:Kdb(d,e)}} +function HFb(a,b,c){var d,e,f;if(c[b.d]){return}c[b.d]=true;for(e=new olb(LFb(b));e.a<e.c.c.length;){d=BD(mlb(e),213);f=xFb(d,b);HFb(a,f,c)}} +function umc(a,b,c){var d;d=c[a.g][b];switch(a.g){case 1:case 3:return new f7c(0,d);case 2:case 4:return new f7c(d,0);default:return null;}} +function r2c(b,c,d){var e,f;f=BD(hgd(c.f),209);try{f.Ze(b,d);igd(c.f,f)}catch(a){a=ubb(a);if(JD(a,102)){e=a;throw vbb(e)}else throw vbb(a)}} +function Vqd(a,b,c){var d,e,f,g,h,i;d=null;h=k4c(n4c(),b);f=null;if(h){e=null;i=o5c(h,c);g=null;i!=null&&(g=a.Ye(h,i));e=g;f=e}d=f;return d} +function TTd(a,b,c,d){var e,f,g;e=new pSd(a.e,1,13,(g=b.c,g?g:(jGd(),YFd)),(f=c.c,f?f:(jGd(),YFd)),HLd(a,b),false);!d?(d=e):d.Ei(e);return d} +function UEd(a,b,c,d){var e;e=a.length;if(b>=e)return e;for(b=b>0?b:0;b<e;b++){if(_Ed((BCb(b,a.length),a.charCodeAt(b)),c,d))break}return b} +function Qkb(a,b){var c,d;d=a.c.length;b.length<d&&(b=eCb(new Array(d),b));for(c=0;c<d;++c){NC(b,c,a.c[c])}b.length>d&&NC(b,d,null);return b} +function _lb(a,b){var c,d;d=a.a.length;b.length<d&&(b=eCb(new Array(d),b));for(c=0;c<d;++c){NC(b,c,a.a[c])}b.length>d&&NC(b,d,null);return b} +function Xrb(a,b,c){var d,e,f;e=BD(Ohb(a.e,b),387);if(!e){d=new lsb(a,b,c);Rhb(a.e,b,d);isb(d);return null}else{f=ijb(e,c);Yrb(a,e);return f}} +function P9d(a){var b;if(a==null)return null;b=ide(Qge(a,true));if(b==null){throw vbb(new n8d("Invalid hexBinary value: '"+a+"'"))}return b} +function ghb(a){Hgb();if(ybb(a,0)<0){if(ybb(a,-1)!=0){return new Wgb(-1,Jbb(a))}return Bgb}else return ybb(a,10)<=0?Dgb[Tbb(a)]:new Wgb(1,a)} +function wJb(){qJb();return OC(GC(DN,1),Kie,159,0,[nJb,mJb,oJb,eJb,dJb,fJb,iJb,hJb,gJb,lJb,kJb,jJb,bJb,aJb,cJb,$Ib,ZIb,_Ib,XIb,WIb,YIb,pJb])} +function vjc(a){var b;this.d=new Rkb;this.j=new d7c;this.g=new d7c;b=a.g.b;this.f=BD(vNb(Q_b(b),(Nyc(),Lwc)),103);this.e=Edb(ED(c_b(b,ryc)))} +function Pjc(a){this.b=new Rkb;this.e=new Rkb;this.d=a;this.a=!WAb(JAb(new YAb(null,new Lub(new b1b(a.b))),new Xxb(new Qjc))).sd((EAb(),DAb))} +function N5c(){N5c=ccb;L5c=new O5c('PARENTS',0);K5c=new O5c('NODES',1);I5c=new O5c('EDGES',2);M5c=new O5c('PORTS',3);J5c=new O5c('LABELS',4)} +function Tbd(){Tbd=ccb;Qbd=new Ubd('DISTRIBUTED',0);Sbd=new Ubd('JUSTIFIED',1);Obd=new Ubd('BEGIN',2);Pbd=new Ubd(gle,3);Rbd=new Ubd('END',4)} +function UMd(a){var b;b=a.yi(null);switch(b){case 10:return 0;case 15:return 1;case 14:return 2;case 11:return 3;case 21:return 4;}return -1} +function cYb(a){switch(a.g){case 1:return ead(),dad;case 4:return ead(),aad;case 2:return ead(),bad;case 3:return ead(),_9c;}return ead(),cad} +function kA(a,b,c){var d;d=c.q.getFullYear()-nje+nje;d<0&&(d=-d);switch(b){case 1:a.a+=d;break;case 2:EA(a,d%100,2);break;default:EA(a,d,b);}} +function Jsb(a,b){var c,d;wCb(b,a.b);if(b>=a.b>>1){d=a.c;for(c=a.b;c>b;--c){d=d.b}}else{d=a.a.a;for(c=0;c<b;++c){d=d.a}}return new $sb(a,b,d)} +function MEb(){MEb=ccb;LEb=new NEb('NUM_OF_EXTERNAL_SIDES_THAN_NUM_OF_EXTENSIONS_LAST',0);KEb=new NEb('CORNER_CASES_THAN_SINGLE_SIDE_LAST',1)} +function h4b(a){var b,c,d,e;d=c4b(a);Okb(d,a4b);e=a.d;e.c=KC(SI,Uhe,1,0,5,1);for(c=new olb(d);c.a<c.c.c.length;){b=BD(mlb(c),456);Gkb(e,b.b)}} +function gkd(a){var b,c,d;d=(!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),a.o);for(c=d.c.Kc();c.e!=c.i.gc();){b=BD(c.nj(),42);b.dd()}return FAd(d)} +function N5b(a){var b;if(!ecd(BD(vNb(a,(Nyc(),Vxc)),98))){return}b=a.b;O5b((tCb(0,b.c.length),BD(b.c[0],29)));O5b(BD(Ikb(b,b.c.length-1),29))} +function Roc(a,b){var c,d,e,f;c=0;for(e=new olb(b.a);e.a<e.c.c.length;){d=BD(mlb(e),10);f=d.o.a+d.d.c+d.d.b+a.j;c=$wnd.Math.max(c,f)}return c} +function XEd(a){var b,c,d,e;e=0;for(c=0,d=a.length;c<d;c++){b=(BCb(c,a.length),a.charCodeAt(c));b>=64&&b<128&&(e=Mbb(e,Nbb(1,b-64)))}return e} +function c_b(a,b){var c,d;d=null;if(wNb(a,(Y9c(),O9c))){c=BD(vNb(a,O9c),94);c.Xe(b)&&(d=c.We(b))}d==null&&!!Q_b(a)&&(d=vNb(Q_b(a),b));return d} +function oQc(a,b){var c,d,e;e=b.d.i;d=e.k;if(d==(j0b(),h0b)||d==d0b){return}c=new Sr(ur(U_b(e).a.Kc(),new Sq));Qr(c)&&Rhb(a.k,b,BD(Rr(c),17))} +function mid(a,b){var c,d,e;d=XKd(a.Tg(),b);c=b-a.Ah();return c<0?(e=a.Yg(d),e>=0?a.lh(e):tid(a,d)):c<0?tid(a,d):BD(d,66).Nj().Sj(a,a.yh(),c)} +function Ksd(a){var b;if(JD(a.a,4)){b=fvd(a.a);if(b==null){throw vbb(new Zdb(mse+a.b+"'. "+ise+(fdb(Y3),Y3.k)+jse))}return b}else{return a.a}} +function L9d(a){var b;if(a==null)return null;b=bde(Qge(a,true));if(b==null){throw vbb(new n8d("Invalid base64Binary value: '"+a+"'"))}return b} +function Dyd(b){var c;try{c=b.i.Xb(b.e);b.mj();b.g=b.e++;return c}catch(a){a=ubb(a);if(JD(a,73)){b.mj();throw vbb(new utb)}else throw vbb(a)}} +function Zyd(b){var c;try{c=b.c.ki(b.e);b.mj();b.g=b.e++;return c}catch(a){a=ubb(a);if(JD(a,73)){b.mj();throw vbb(new utb)}else throw vbb(a)}} +function CPb(){CPb=ccb;BPb=(Y9c(),K9c);vPb=G8c;qPb=r8c;wPb=f9c;zPb=(fFb(),bFb);yPb=_Eb;APb=dFb;xPb=$Eb;sPb=(nPb(),jPb);rPb=iPb;tPb=lPb;uPb=mPb} +function NWb(a){LWb();this.c=new Rkb;this.d=a;switch(a.g){case 0:case 2:this.a=tmb(KWb);this.b=Pje;break;case 3:case 1:this.a=KWb;this.b=Qje;}} +function ued(a,b,c){var d,e;if(a.c){dld(a.c,a.c.i+b);eld(a.c,a.c.j+c)}else{for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),157);ued(d,b,c)}}} +function KEd(a,b){var c,d;if(a.j.length!=b.j.length)return false;for(c=0,d=a.j.length;c<d;c++){if(!dfb(a.j[c],b.j[c]))return false}return true} +function gA(a,b,c){var d;if(b.a.length>0){Ekb(a.b,new WA(b.a,c));d=b.a.length;0<d?(b.a=b.a.substr(0,0)):0>d&&(b.a+=yfb(KC(TD,$ie,25,-d,15,1)))}} +function JKb(a,b){var c,d,e;c=a.o;for(e=BD(BD(Qc(a.r,b),21),84).Kc();e.Ob();){d=BD(e.Pb(),111);d.e.a=DKb(d,c.a);d.e.b=c.b*Edb(ED(d.b.We(BKb)))}} +function S5b(a,b){var c,d,e,f;e=a.k;c=Edb(ED(vNb(a,(wtc(),htc))));f=b.k;d=Edb(ED(vNb(b,htc)));return f!=(j0b(),e0b)?-1:e!=e0b?1:c==d?0:c<d?-1:1} +function B$c(a,b){var c,d;c=BD(BD(Ohb(a.g,b.a),46).a,65);d=BD(BD(Ohb(a.g,b.b),46).a,65);return S6c(b.a,b.b)-S6c(b.a,E6c(c.b))-S6c(b.b,E6c(d.b))} +function aZb(a,b){var c;c=BD(vNb(a,(Nyc(),jxc)),74);if(Lq(b,ZYb)){if(!c){c=new s7c;yNb(a,jxc,c)}else{Osb(c)}}else !!c&&yNb(a,jxc,null);return c} +function a0b(a){var b;b=new Ufb;b.a+='n';a.k!=(j0b(),h0b)&&Qfb(Qfb((b.a+='(',b),Zr(a.k).toLowerCase()),')');Qfb((b.a+='_',b),P_b(a));return b.a} +function Kdc(a,b){Odd(b,'Self-Loop post-processing',1);MAb(JAb(JAb(LAb(new YAb(null,new Kub(a.b,16)),new Qdc),new Sdc),new Udc),new Wdc);Qdd(b)} +function kid(a,b,c,d){var e;if(c>=0){return a.hh(b,c,d)}else{!!a.eh()&&(d=(e=a.Vg(),e>=0?a.Qg(d):a.eh().ih(a,-1-e,null,d)));return a.Sg(b,c,d)}} +function zld(a,b){switch(b){case 7:!a.e&&(a.e=new y5d(B2,a,7,4));Uxd(a.e);return;case 8:!a.d&&(a.d=new y5d(B2,a,8,5));Uxd(a.d);return;}$kd(a,b)} +function Ut(b,c){var d;d=b.Zc(c);try{return d.Pb()}catch(a){a=ubb(a);if(JD(a,109)){throw vbb(new qcb("Can't get element "+c))}else throw vbb(a)}} +function Tgb(a,b){this.e=a;if(b<Zje){this.d=1;this.a=OC(GC(WD,1),oje,25,15,[b|0])}else{this.d=2;this.a=OC(GC(WD,1),oje,25,15,[b%Zje|0,b/Zje|0])}} +function omb(a,b){mmb();var c,d,e,f;c=a;f=b;if(JD(a,21)&&!JD(b,21)){c=b;f=a}for(e=c.Kc();e.Ob();){d=e.Pb();if(f.Hc(d)){return false}}return true} +function Txd(a,b,c){var d,e,f,g;d=a.Xc(b);if(d!=-1){if(a.ej()){f=a.fj();g=tud(a,d);e=a.Zi(4,g,null,d,f);!c?(c=e):c.Ei(e)}else{tud(a,d)}}return c} +function uwd(a,b,c){var d,e,f,g;d=a.Xc(b);if(d!=-1){if(a.ej()){f=a.fj();g=Evd(a,d);e=a.Zi(4,g,null,d,f);!c?(c=e):c.Ei(e)}else{Evd(a,d)}}return c} +function PJb(a,b){var c;c=BD(Mpb(a.b,b),124).n;switch(b.g){case 1:a.t>=0&&(c.d=a.t);break;case 3:a.t>=0&&(c.a=a.t);}if(a.C){c.b=a.C.b;c.c=a.C.c}} +function RMb(){RMb=ccb;OMb=new SMb(xle,0);NMb=new SMb(yle,1);PMb=new SMb(zle,2);QMb=new SMb(Ale,3);OMb.a=false;NMb.a=true;PMb.a=false;QMb.a=true} +function ROb(){ROb=ccb;OOb=new SOb(xle,0);NOb=new SOb(yle,1);POb=new SOb(zle,2);QOb=new SOb(Ale,3);OOb.a=false;NOb.a=true;POb.a=false;QOb.a=true} +function dac(a){var b;b=a.a;do{b=BD(Rr(new Sr(ur(R_b(b).a.Kc(),new Sq))),17).c.i;b.k==(j0b(),g0b)&&a.b.Fc(b)}while(b.k==(j0b(),g0b));a.b=Su(a.b)} +function CDc(a){var b,c,d;d=a.c.a;a.p=(Qb(d),new Tkb(d));for(c=new olb(d);c.a<c.c.c.length;){b=BD(mlb(c),10);b.p=GDc(b).a}mmb();Okb(a.p,new PDc)} +function eVc(a){var b,c,d,e;d=0;e=gVc(a);if(e.c.length==0){return 1}else{for(c=new olb(e);c.a<c.c.c.length;){b=BD(mlb(c),33);d+=eVc(b)}}return d} +function JJb(a,b){var c,d,e;e=0;d=BD(BD(Qc(a.r,b),21),84).Kc();while(d.Ob()){c=BD(d.Pb(),111);e+=c.d.b+c.b.rf().a+c.d.c;d.Ob()&&(e+=a.w)}return e} +function RKb(a,b){var c,d,e;e=0;d=BD(BD(Qc(a.r,b),21),84).Kc();while(d.Ob()){c=BD(d.Pb(),111);e+=c.d.d+c.b.rf().b+c.d.a;d.Ob()&&(e+=a.w)}return e} +function SOc(a,b,c,d){if(b.a<d.a){return true}else if(b.a==d.a){if(b.b<d.b){return true}else if(b.b==d.b){if(a.b>c.b){return true}}}return false} +function AD(a,b){if(ND(a)){return !!zD[b]}else if(a.hm){return !!a.hm[b]}else if(LD(a)){return !!yD[b]}else if(KD(a)){return !!xD[b]}return false} +function jkd(a,b,c){c==null?(!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),LAd(a.o,b)):(!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),HAd(a.o,b,c));return a} +function jKb(a,b,c,d){var e,f;f=b.Xe((Y9c(),W8c))?BD(b.We(W8c),21):a.j;e=uJb(f);if(e==(qJb(),pJb)){return}if(c&&!sJb(e)){return}UHb(lKb(a,e,d),b)} +function fid(a,b,c,d){var e,f,g;f=XKd(a.Tg(),b);e=b-a.Ah();return e<0?(g=a.Yg(f),g>=0?a._g(g,c,true):sid(a,f,c)):BD(f,66).Nj().Pj(a,a.yh(),e,c,d)} +function u6d(a,b,c,d){var e,f,g;if(c.mh(b)){Q6d();if(YId(b)){e=BD(c.ah(b),153);x6d(a,e)}else{f=(g=b,!g?null:BD(d,49).xh(g));!!f&&v6d(c.ah(b),f)}}} +function H3b(a){switch(a.g){case 1:return vLb(),uLb;case 3:return vLb(),rLb;case 2:return vLb(),tLb;case 4:return vLb(),sLb;default:return null;}} +function kCb(a){switch(typeof(a)){case Mhe:return LCb(a);case Lhe:return QD(a);case Khe:return Bcb(),a?1231:1237;default:return a==null?0:FCb(a);}} +function Gic(a,b,c){if(a.e){switch(a.b){case 1:oic(a.c,b,c);break;case 0:pic(a.c,b,c);}}else{mic(a.c,b,c)}a.a[b.p][c.p]=a.c.i;a.a[c.p][b.p]=a.c.e} +function lHc(a){var b,c;if(a==null){return null}c=KC(OQ,nie,193,a.length,0,2);for(b=0;b<c.length;b++){c[b]=BD(ulb(a[b],a[b].length),193)}return c} +function d4d(a){var b;if(b4d(a)){a4d(a);if(a.Lk()){b=b3d(a.e,a.b,a.c,a.a,a.j);a.j=b}a.g=a.a;++a.a;++a.c;a.i=0;return a.j}else{throw vbb(new utb)}} +function fMb(a,b){var c,d,e,f;f=a.o;c=a.p;f<c?(f*=f):(c*=c);d=f+c;f=b.o;c=b.p;f<c?(f*=f):(c*=c);e=f+c;if(d<e){return -1}if(d==e){return 0}return 1} +function HLd(a,b){var c,d,e;e=rud(a,b);if(e>=0)return e;if(a.Fk()){for(d=0;d<a.i;++d){c=a.Gk(BD(a.g[d],56));if(PD(c)===PD(b)){return d}}}return -1} +function Gtd(a,b,c){var d,e;e=a.gc();if(b>=e)throw vbb(new Cyd(b,e));if(a.hi()){d=a.Xc(c);if(d>=0&&d!=b){throw vbb(new Wdb(kue))}}return a.mi(b,c)} +function gx(a,b){this.a=BD(Qb(a),245);this.b=BD(Qb(b),245);if(a.vd(b)>0||a==(Lk(),Kk)||b==(_k(),$k)){throw vbb(new Wdb('Invalid range: '+nx(a,b)))}} +function mYb(a){var b,c;this.b=new Rkb;this.c=a;this.a=false;for(c=new olb(a.a);c.a<c.c.c.length;){b=BD(mlb(c),10);this.a=this.a|b.k==(j0b(),h0b)}} +function GFb(a,b){var c,d,e;c=nGb(new pGb,a);for(e=new olb(b);e.a<e.c.c.length;){d=BD(mlb(e),121);AFb(DFb(CFb(EFb(BFb(new FFb,0),0),c),d))}return c} +function Nac(a,b,c){var d,e,f;for(e=new Sr(ur((b?R_b(a):U_b(a)).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);f=b?d.c.i:d.d.i;f.k==(j0b(),f0b)&&$_b(f,c)}} +function Izc(){Izc=ccb;Gzc=new Kzc(ane,0);Hzc=new Kzc('PORT_POSITION',1);Fzc=new Kzc('NODE_SIZE_WHERE_SPACE_PERMITS',2);Ezc=new Kzc('NODE_SIZE',3)} +function F7c(){F7c=ccb;z7c=new G7c('AUTOMATIC',0);C7c=new G7c(jle,1);D7c=new G7c(kle,2);E7c=new G7c('TOP',3);A7c=new G7c(mle,4);B7c=new G7c(gle,5)} +function Hhb(a,b,c,d){Dhb();var e,f;e=0;for(f=0;f<c;f++){e=wbb(Ibb(xbb(b[f],Yje),xbb(d,Yje)),xbb(Tbb(e),Yje));a[f]=Tbb(e);e=Pbb(e,32)}return Tbb(e)} +function zHb(a,b,c){var d,e;e=0;for(d=0;d<rHb;d++){e=$wnd.Math.max(e,pHb(a.a[b.g][d],c))}b==(gHb(),eHb)&&!!a.b&&(e=$wnd.Math.max(e,a.b.b));return e} +function Bub(a,b){var c,d;lCb(b>0);if((b&-b)==b){return QD(b*Cub(a,31)*4.6566128730773926E-10)}do{c=Cub(a,31);d=c%b}while(c-d+(b-1)<0);return QD(d)} +function LCb(a){JCb();var b,c,d;c=':'+a;d=ICb[c];if(d!=null){return QD((uCb(d),d))}d=GCb[c];b=d==null?KCb(a):QD((uCb(d),d));MCb();ICb[c]=b;return b} +function qZb(a,b,c){Odd(c,'Compound graph preprocessor',1);a.a=new Hp;vZb(a,b,null);pZb(a,b);uZb(a);yNb(b,(wtc(),zsc),a.a);a.a=null;Uhb(a.b);Qdd(c)} +function X$b(a,b,c){switch(c.g){case 1:a.a=b.a/2;a.b=0;break;case 2:a.a=b.a;a.b=b.b/2;break;case 3:a.a=b.a/2;a.b=b.b;break;case 4:a.a=0;a.b=b.b/2;}} +function tkc(a){var b,c,d;for(d=BD(Qc(a.a,(Xjc(),Vjc)),15).Kc();d.Ob();){c=BD(d.Pb(),101);b=Bkc(c);kkc(a,c,b[0],(Fkc(),Ckc),0);kkc(a,c,b[1],Ekc,1)}} +function ukc(a){var b,c,d;for(d=BD(Qc(a.a,(Xjc(),Wjc)),15).Kc();d.Ob();){c=BD(d.Pb(),101);b=Bkc(c);kkc(a,c,b[0],(Fkc(),Ckc),0);kkc(a,c,b[1],Ekc,1)}} +function tXc(a){switch(a.g){case 0:return null;case 1:return new $Xc;case 2:return new QXc;default:throw vbb(new Wdb(jre+(a.f!=null?a.f:''+a.g)));}} +function OZc(a,b,c){var d,e;FZc(a,b-a.s,c-a.t);for(e=new olb(a.n);e.a<e.c.c.length;){d=BD(mlb(e),211);SZc(d,d.e+b-a.s);TZc(d,d.f+c-a.t)}a.s=b;a.t=c} +function JFb(a){var b,c,d,e,f;c=0;for(e=new olb(a.a);e.a<e.c.c.length;){d=BD(mlb(e),121);d.d=c++}b=IFb(a);f=null;b.c.length>1&&(f=GFb(a,b));return f} +function dmd(a){var b;if(!!a.f&&a.f.kh()){b=BD(a.f,49);a.f=BD(xid(a,b),82);a.f!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,9,8,b,a.f))}return a.f} +function emd(a){var b;if(!!a.i&&a.i.kh()){b=BD(a.i,49);a.i=BD(xid(a,b),82);a.i!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,9,7,b,a.i))}return a.i} +function zUd(a){var b;if(!!a.b&&(a.b.Db&64)!=0){b=a.b;a.b=BD(xid(a,b),18);a.b!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,9,21,b,a.b))}return a.b} +function uAd(a,b){var c,d,e;if(a.d==null){++a.e;++a.f}else{d=b.Sh();BAd(a,a.f+1);e=(d&Ohe)%a.d.length;c=a.d[e];!c&&(c=a.d[e]=a.uj());c.Fc(b);++a.f}} +function m3d(a,b,c){var d;if(b.Kj()){return false}else if(b.Zj()!=-2){d=b.zj();return d==null?c==null:pb(d,c)}else return b.Hj()==a.e.Tg()&&c==null} +function wo(){var a;Xj(16,Hie);a=Kp(16);this.b=KC(GF,Gie,317,a,0,1);this.c=KC(GF,Gie,317,a,0,1);this.a=null;this.e=null;this.i=0;this.f=a-1;this.g=0} +function b0b(a){n_b.call(this);this.k=(j0b(),h0b);this.j=(Xj(6,Jie),new Skb(6));this.b=(Xj(2,Jie),new Skb(2));this.d=new L_b;this.f=new s0b;this.a=a} +function Scc(a){var b,c;if(a.c.length<=1){return}b=Pcc(a,(Ucd(),Rcd));Rcc(a,BD(b.a,19).a,BD(b.b,19).a);c=Pcc(a,Tcd);Rcc(a,BD(c.a,19).a,BD(c.b,19).a)} +function Vzc(){Vzc=ccb;Uzc=new Xzc('SIMPLE',0);Rzc=new Xzc(Tne,1);Szc=new Xzc('LINEAR_SEGMENTS',2);Qzc=new Xzc('BRANDES_KOEPF',3);Tzc=new Xzc(Aqe,4)} +function XDc(a,b,c){if(!ecd(BD(vNb(b,(Nyc(),Vxc)),98))){WDc(a,b,Y_b(b,c));WDc(a,b,Y_b(b,(Ucd(),Rcd)));WDc(a,b,Y_b(b,Acd));mmb();Okb(b.j,new jEc(a))}} +function HVc(a,b,c,d){var e,f,g;e=d?BD(Qc(a.a,b),21):BD(Qc(a.b,b),21);for(g=e.Kc();g.Ob();){f=BD(g.Pb(),33);if(BVc(a,c,f)){return true}}return false} +function FMd(a){var b,c;for(c=new Fyd(a);c.e!=c.i.gc();){b=BD(Dyd(c),87);if(!!b.e||(!b.d&&(b.d=new xMd(j5,b,1)),b.d).i!=0){return true}}return false} +function QTd(a){var b,c;for(c=new Fyd(a);c.e!=c.i.gc();){b=BD(Dyd(c),87);if(!!b.e||(!b.d&&(b.d=new xMd(j5,b,1)),b.d).i!=0){return true}}return false} +function FDc(a){var b,c,d;b=0;for(d=new olb(a.c.a);d.a<d.c.c.length;){c=BD(mlb(d),10);b+=sr(new Sr(ur(U_b(c).a.Kc(),new Sq)))}return b/a.c.a.c.length} +function UPc(a){var b,c;a.c||XPc(a);c=new s7c;b=new olb(a.a);mlb(b);while(b.a<b.c.c.length){Dsb(c,BD(mlb(b),407).a)}sCb(c.b!=0);Nsb(c,c.c.b);return c} +function J0c(){J0c=ccb;I0c=(A0c(),z0c);G0c=new q0b(8);new Osd((Y9c(),f9c),G0c);new Osd(T9c,8);H0c=x0c;E0c=n0c;F0c=o0c;D0c=new Osd(y8c,(Bcb(),false))} +function uld(a,b,c,d){switch(b){case 7:return !a.e&&(a.e=new y5d(B2,a,7,4)),a.e;case 8:return !a.d&&(a.d=new y5d(B2,a,8,5)),a.d;}return Xkd(a,b,c,d)} +function JQd(a){var b;if(!!a.a&&a.a.kh()){b=BD(a.a,49);a.a=BD(xid(a,b),138);a.a!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,9,5,b,a.a))}return a.a} +function yde(a){if(a<48)return -1;if(a>102)return -1;if(a<=57)return a-48;if(a<65)return -1;if(a<=70)return a-65+10;if(a<97)return -1;return a-97+10} +function Wj(a,b){if(a==null){throw vbb(new Heb('null key in entry: null='+b))}else if(b==null){throw vbb(new Heb('null value in entry: '+a+'=null'))}} +function kr(a,b){var c,d;while(a.Ob()){if(!b.Ob()){return false}c=a.Pb();d=b.Pb();if(!(PD(c)===PD(d)||c!=null&&pb(c,d))){return false}}return !b.Ob()} +function jIb(a,b){var c;c=OC(GC(UD,1),Vje,25,15,[pHb(a.a[0],b),pHb(a.a[1],b),pHb(a.a[2],b)]);if(a.d){c[0]=$wnd.Math.max(c[0],c[2]);c[2]=c[0]}return c} +function kIb(a,b){var c;c=OC(GC(UD,1),Vje,25,15,[qHb(a.a[0],b),qHb(a.a[1],b),qHb(a.a[2],b)]);if(a.d){c[0]=$wnd.Math.max(c[0],c[2]);c[2]=c[0]}return c} +function mqc(){mqc=ccb;iqc=new oqc('GREEDY',0);hqc=new oqc(Une,1);kqc=new oqc(Tne,2);lqc=new oqc('MODEL_ORDER',3);jqc=new oqc('GREEDY_MODEL_ORDER',4)} +function iUc(a,b){var c,d,e;a.b[b.g]=1;for(d=Jsb(b.d,0);d.b!=d.d.c;){c=BD(Xsb(d),188);e=c.c;a.b[e.g]==1?Dsb(a.a,c):a.b[e.g]==2?(a.b[e.g]=1):iUc(a,e)}} +function V9b(a,b){var c,d,e;e=new Skb(b.gc());for(d=b.Kc();d.Ob();){c=BD(d.Pb(),286);c.c==c.f?K9b(a,c,c.c):L9b(a,c)||(e.c[e.c.length]=c,true)}return e} +function IZc(a,b,c){var d,e,f,g,h;h=a.r+b;a.r+=b;a.d+=c;d=c/a.n.c.length;e=0;for(g=new olb(a.n);g.a<g.c.c.length;){f=BD(mlb(g),211);RZc(f,h,d,e);++e}} +function tEb(a){var b,c,d;zwb(a.b.a);a.a=KC(PM,Uhe,57,a.c.c.a.b.c.length,0,1);b=0;for(d=new olb(a.c.c.a.b);d.a<d.c.c.length;){c=BD(mlb(d),57);c.f=b++}} +function RVb(a){var b,c,d;zwb(a.b.a);a.a=KC(IP,Uhe,81,a.c.a.a.b.c.length,0,1);b=0;for(d=new olb(a.c.a.a.b);d.a<d.c.c.length;){c=BD(mlb(d),81);c.i=b++}} +function P1c(a,b,c){var d;Odd(c,'Shrinking tree compaction',1);if(Ccb(DD(vNb(b,(XNb(),VNb))))){N1c(a,b.f);INb(b.f,(d=b.c,d))}else{INb(b.f,b.c)}Qdd(c)} +function mr(a){var b;b=gr(a);if(!Qr(a)){throw vbb(new qcb('position (0) must be less than the number of elements that remained ('+b+')'))}return Rr(a)} +function hNb(b,c,d){var e;try{return YMb(b,c+b.j,d+b.k)}catch(a){a=ubb(a);if(JD(a,73)){e=a;throw vbb(new qcb(e.g+Gle+c+She+d+').'))}else throw vbb(a)}} +function iNb(b,c,d){var e;try{return ZMb(b,c+b.j,d+b.k)}catch(a){a=ubb(a);if(JD(a,73)){e=a;throw vbb(new qcb(e.g+Gle+c+She+d+').'))}else throw vbb(a)}} +function jNb(b,c,d){var e;try{return $Mb(b,c+b.j,d+b.k)}catch(a){a=ubb(a);if(JD(a,73)){e=a;throw vbb(new qcb(e.g+Gle+c+She+d+').'))}else throw vbb(a)}} +function s5b(a){switch(a.g){case 1:return Ucd(),Tcd;case 4:return Ucd(),Acd;case 3:return Ucd(),zcd;case 2:return Ucd(),Rcd;default:return Ucd(),Scd;}} +function cjc(a,b,c){if(b.k==(j0b(),h0b)&&c.k==g0b){a.d=_ic(b,(Ucd(),Rcd));a.b=_ic(b,Acd)}if(c.k==h0b&&b.k==g0b){a.d=_ic(c,(Ucd(),Acd));a.b=_ic(c,Rcd)}} +function gjc(a,b){var c,d,e;e=V_b(a,b);for(d=e.Kc();d.Ob();){c=BD(d.Pb(),11);if(vNb(c,(wtc(),gtc))!=null||a1b(new b1b(c.b))){return true}}return false} +function QZc(a,b){dld(b,a.e+a.d+(a.c.c.length==0?0:a.b));eld(b,a.f);a.a=$wnd.Math.max(a.a,b.f);a.d+=b.g+(a.c.c.length==0?0:a.b);Ekb(a.c,b);return true} +function XZc(a,b,c){var d,e,f,g;g=0;d=c/a.a.c.length;for(f=new olb(a.a);f.a<f.c.c.length;){e=BD(mlb(f),187);OZc(e,e.s,e.t+g*d);IZc(e,a.d-e.r+b,d);++g}} +function H4b(a){var b,c,d,e,f;for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),29);b=0;for(f=new olb(c.a);f.a<f.c.c.length;){e=BD(mlb(f),10);e.p=b++}}} +function r6c(a,b){var c,d,e,f,g,h;e=b.length-1;g=0;h=0;for(d=0;d<=e;d++){f=b[d];c=k6c(e,d)*x6c(1-a,e-d)*x6c(a,d);g+=f.a*c;h+=f.b*c}return new f7c(g,h)} +function jud(a,b){var c,d,e,f,g;c=b.gc();a.qi(a.i+c);f=b.Kc();g=a.i;a.i+=c;for(d=g;d<a.i;++d){e=f.Pb();mud(a,d,a.oi(d,e));a.bi(d,e);a.ci()}return c!=0} +function twd(a,b,c){var d,e,f;if(a.ej()){d=a.Vi();f=a.fj();++a.j;a.Hi(d,a.oi(d,b));e=a.Zi(3,null,b,d,f);!c?(c=e):c.Ei(e)}else{Avd(a,a.Vi(),b)}return c} +function WOd(a,b,c){var d,e,f;d=BD(qud(VKd(a.a),b),87);f=(e=d.c,JD(e,88)?BD(e,26):(jGd(),_Fd));((f.Db&64)!=0?xid(a.b,f):f)==c?KQd(d):NQd(d,c);return f} +function Ewb(a,b,c,d,e,f,g,h){var i,j;if(!d){return}i=d.a[0];!!i&&Ewb(a,b,c,i,e,f,g,h);Fwb(a,c,d.d,e,f,g,h)&&b.Fc(d);j=d.a[1];!!j&&Ewb(a,b,c,j,e,f,g,h)} +function eAb(a,b){var c;if(!a.a){c=KC(UD,Vje,25,0,15,1);_ub(a.b.a,new iAb(c));c.sort(dcb(Ylb.prototype.te,Ylb,[]));a.a=new Avb(c,a.d)}return pvb(a.a,b)} +function YMb(b,c,d){try{return Bbb(_Mb(b,c,d),1)}catch(a){a=ubb(a);if(JD(a,320)){throw vbb(new qcb(Dle+b.o+'*'+b.p+Ele+c+She+d+Fle))}else throw vbb(a)}} +function ZMb(b,c,d){try{return Bbb(_Mb(b,c,d),0)}catch(a){a=ubb(a);if(JD(a,320)){throw vbb(new qcb(Dle+b.o+'*'+b.p+Ele+c+She+d+Fle))}else throw vbb(a)}} +function $Mb(b,c,d){try{return Bbb(_Mb(b,c,d),2)}catch(a){a=ubb(a);if(JD(a,320)){throw vbb(new qcb(Dle+b.o+'*'+b.p+Ele+c+She+d+Fle))}else throw vbb(a)}} +function Nyd(b,c){if(b.g==-1){throw vbb(new Ydb)}b.mj();try{b.d._c(b.g,c);b.f=b.d.j}catch(a){a=ubb(a);if(JD(a,73)){throw vbb(new Apb)}else throw vbb(a)}} +function rJc(a,b,c){Odd(c,'Linear segments node placement',1);a.b=BD(vNb(b,(wtc(),otc)),304);sJc(a,b);nJc(a,b);kJc(a,b);qJc(a);a.a=null;a.b=null;Qdd(c)} +function Ee(a,b){var c,d,e,f;f=a.gc();b.length<f&&(b=eCb(new Array(f),b));e=b;d=a.Kc();for(c=0;c<f;++c){NC(e,c,d.Pb())}b.length>f&&NC(b,f,null);return b} +function Lu(a,b){var c,d;d=a.gc();if(b==null){for(c=0;c<d;c++){if(a.Xb(c)==null){return c}}}else{for(c=0;c<d;c++){if(pb(b,a.Xb(c))){return c}}}return -1} +function Jd(a,b){var c,d,e;c=b.cd();e=b.dd();d=a.xc(c);if(!(PD(e)===PD(d)||e!=null&&pb(e,d))){return false}if(d==null&&!a._b(c)){return false}return true} +function YC(a,b){var c,d,e;if(b<=22){c=a.l&(1<<b)-1;d=e=0}else if(b<=44){c=a.l;d=a.m&(1<<b-22)-1;e=0}else{c=a.l;d=a.m;e=a.h&(1<<b-44)-1}return TC(c,d,e)} +function yKb(a,b){switch(b.g){case 1:return a.f.n.d+a.t;case 3:return a.f.n.a+a.t;case 2:return a.f.n.c+a.s;case 4:return a.f.n.b+a.s;default:return 0;}} +function aLb(a,b){var c,d;d=b.c;c=b.a;switch(a.b.g){case 0:c.d=a.e-d.a-d.d;break;case 1:c.d+=a.e;break;case 2:c.c=a.e-d.a-d.d;break;case 3:c.c=a.e+d.d;}} +function ZOb(a,b,c,d){var e,f;this.a=b;this.c=d;e=a.a;YOb(this,new f7c(-e.c,-e.d));P6c(this.b,c);f=d/2;b.a?b7c(this.b,0,f):b7c(this.b,f,0);Ekb(a.c,this)} +function iXc(){iXc=ccb;hXc=new kXc(ane,0);fXc=new kXc(Vne,1);gXc=new kXc('EDGE_LENGTH_BY_POSITION',2);eXc=new kXc('CROSSING_MINIMIZATION_BY_POSITION',3)} +function Wqd(a,b){var c,d;c=BD(oo(a.g,b),33);if(c){return c}d=BD(oo(a.j,b),118);if(d){return d}throw vbb(new cqd('Referenced shape does not exist: '+b))} +function rTb(a,b){if(a.c==b){return a.d}else if(a.d==b){return a.c}else{throw vbb(new Wdb("Node 'one' must be either source or target of edge 'edge'."))}} +function TMc(a,b){if(a.c.i==b){return a.d.i}else if(a.d.i==b){return a.c.i}else{throw vbb(new Wdb('Node '+b+' is neither source nor target of edge '+a))}} +function _lc(a,b){var c;switch(b.g){case 2:case 4:c=a.a;a.c.d.n.b<c.d.n.b&&(c=a.c);amc(a,b,(Ajc(),zjc),c);break;case 1:case 3:amc(a,b,(Ajc(),wjc),null);}} +function smc(a,b,c,d,e,f){var g,h,i,j,k;g=qmc(b,c,f);h=c==(Ucd(),Acd)||c==Tcd?-1:1;j=a[c.g];for(k=0;k<j.length;k++){i=j[k];i>0&&(i+=e);j[k]=g;g+=h*(i+d)}} +function Uoc(a){var b,c,d;d=a.f;a.n=KC(UD,Vje,25,d,15,1);a.d=KC(UD,Vje,25,d,15,1);for(b=0;b<d;b++){c=BD(Ikb(a.c.b,b),29);a.n[b]=Roc(a,c);a.d[b]=Qoc(a,c)}} +function zjd(a,b){var c,d,e;e=0;for(d=2;d<b;d<<=1){(a.Db&d)!=0&&++e}if(e==0){for(c=b<<=1;c<=128;c<<=1){if((a.Db&c)!=0){return 0}}return -1}else{return e}} +function s3d(a,b){var c,d,e,f,g;g=S6d(a.e.Tg(),b);f=null;c=BD(a.g,119);for(e=0;e<a.i;++e){d=c[e];if(g.rl(d.ak())){!f&&(f=new yud);wtd(f,d)}}!!f&&Yxd(a,f)} +function H9d(a){var b,c,d;if(!a)return null;if(a.dc())return '';d=new Hfb;for(c=a.Kc();c.Ob();){b=c.Pb();Efb(d,GD(b));d.a+=' '}return lcb(d,d.a.length-1)} +function Ty(a,b,c){var d,e,f,g,h;Uy(a);for(e=(a.k==null&&(a.k=KC(_I,nie,78,0,0,1)),a.k),f=0,g=e.length;f<g;++f){d=e[f];Ty(d,b,'\t'+c)}h=a.f;!!h&&Ty(h,b,c)} +function LC(a,b){var c=new Array(b);var d;switch(a){case 14:case 15:d=0;break;case 16:d=false;break;default:return c;}for(var e=0;e<b;++e){c[e]=d}return c} +function PDb(a){var b,c,d;for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),57);b.c.$b()}fad(a.d)?(d=a.a.c):(d=a.a.d);Hkb(d,new dEb(a));a.c.Me(a);QDb(a)} +function sRb(a){var b,c,d,e;for(c=new olb(a.e.c);c.a<c.c.c.length;){b=BD(mlb(c),282);for(e=new olb(b.b);e.a<e.c.c.length;){d=BD(mlb(e),447);lRb(d)}cRb(b)}} +function a$c(a){var b,c,d,e,f;d=0;f=0;e=0;for(c=new olb(a.a);c.a<c.c.c.length;){b=BD(mlb(c),187);f=$wnd.Math.max(f,b.r);d+=b.d+(e>0?a.c:0);++e}a.b=d;a.d=f} +function BZc(a,b){var c,d,e,f,g;d=0;e=0;c=0;for(g=new olb(b);g.a<g.c.c.length;){f=BD(mlb(g),200);d=$wnd.Math.max(d,f.e);e+=f.b+(c>0?a.g:0);++c}a.c=e;a.d=d} +function AHb(a,b){var c;c=OC(GC(UD,1),Vje,25,15,[zHb(a,(gHb(),dHb),b),zHb(a,eHb,b),zHb(a,fHb,b)]);if(a.f){c[0]=$wnd.Math.max(c[0],c[2]);c[2]=c[0]}return c} +function lNb(b,c,d){var e;try{aNb(b,c+b.j,d+b.k,false,true)}catch(a){a=ubb(a);if(JD(a,73)){e=a;throw vbb(new qcb(e.g+Gle+c+She+d+').'))}else throw vbb(a)}} +function mNb(b,c,d){var e;try{aNb(b,c+b.j,d+b.k,true,false)}catch(a){a=ubb(a);if(JD(a,73)){e=a;throw vbb(new qcb(e.g+Gle+c+She+d+').'))}else throw vbb(a)}} +function d5b(a){var b;if(!wNb(a,(Nyc(),xxc))){return}b=BD(vNb(a,xxc),21);if(b.Hc((Hbd(),zbd))){b.Mc(zbd);b.Fc(Bbd)}else if(b.Hc(Bbd)){b.Mc(Bbd);b.Fc(zbd)}} +function e5b(a){var b;if(!wNb(a,(Nyc(),xxc))){return}b=BD(vNb(a,xxc),21);if(b.Hc((Hbd(),Gbd))){b.Mc(Gbd);b.Fc(Ebd)}else if(b.Hc(Ebd)){b.Mc(Ebd);b.Fc(Gbd)}} +function udc(a,b,c){Odd(c,'Self-Loop ordering',1);MAb(NAb(JAb(JAb(LAb(new YAb(null,new Kub(b.b,16)),new ydc),new Adc),new Cdc),new Edc),new Gdc(a));Qdd(c)} +function ikc(a,b,c,d){var e,f;for(e=b;e<a.c.length;e++){f=(tCb(e,a.c.length),BD(a.c[e],11));if(c.Mb(f)){d.c[d.c.length]=f}else{return e}}return a.c.length} +function Kmc(a,b,c,d){var e,f,g,h;a.a==null&&Nmc(a,b);g=b.b.j.c.length;f=c.d.p;h=d.d.p;e=h-1;e<0&&(e=g-1);return f<=e?a.a[e]-a.a[f]:a.a[g-1]-a.a[f]+a.a[e]} +function ehd(a){var b,c;if(!a.b){a.b=Qu(BD(a.f,33).Ag().i);for(c=new Fyd(BD(a.f,33).Ag());c.e!=c.i.gc();){b=BD(Dyd(c),137);Ekb(a.b,new dhd(b))}}return a.b} +function fhd(a){var b,c;if(!a.e){a.e=Qu(Yod(BD(a.f,33)).i);for(c=new Fyd(Yod(BD(a.f,33)));c.e!=c.i.gc();){b=BD(Dyd(c),118);Ekb(a.e,new thd(b))}}return a.e} +function ahd(a){var b,c;if(!a.a){a.a=Qu(Vod(BD(a.f,33)).i);for(c=new Fyd(Vod(BD(a.f,33)));c.e!=c.i.gc();){b=BD(Dyd(c),33);Ekb(a.a,new hhd(a,b))}}return a.a} +function dKd(b){var c;if(!b.C&&(b.D!=null||b.B!=null)){c=eKd(b);if(c){b.yk(c)}else{try{b.yk(null)}catch(a){a=ubb(a);if(!JD(a,60))throw vbb(a)}}}return b.C} +function GJb(a){switch(a.q.g){case 5:DJb(a,(Ucd(),Acd));DJb(a,Rcd);break;case 4:EJb(a,(Ucd(),Acd));EJb(a,Rcd);break;default:FJb(a,(Ucd(),Acd));FJb(a,Rcd);}} +function PKb(a){switch(a.q.g){case 5:MKb(a,(Ucd(),zcd));MKb(a,Tcd);break;case 4:NKb(a,(Ucd(),zcd));NKb(a,Tcd);break;default:OKb(a,(Ucd(),zcd));OKb(a,Tcd);}} +function EXb(a,b){var c,d,e;e=new d7c;for(d=a.Kc();d.Ob();){c=BD(d.Pb(),37);uXb(c,e.a,0);e.a+=c.f.a+b;e.b=$wnd.Math.max(e.b,c.f.b)}e.b>0&&(e.b+=b);return e} +function GXb(a,b){var c,d,e;e=new d7c;for(d=a.Kc();d.Ob();){c=BD(d.Pb(),37);uXb(c,0,e.b);e.b+=c.f.b+b;e.a=$wnd.Math.max(e.a,c.f.a)}e.a>0&&(e.a+=b);return e} +function d_b(a){var b,c,d;d=Ohe;for(c=new olb(a.a);c.a<c.c.c.length;){b=BD(mlb(c),10);wNb(b,(wtc(),Zsc))&&(d=$wnd.Math.min(d,BD(vNb(b,Zsc),19).a))}return d} +function pHc(a,b){var c,d;if(b.length==0){return 0}c=NHc(a.a,b[0],(Ucd(),Tcd));c+=NHc(a.a,b[b.length-1],zcd);for(d=0;d<b.length;d++){c+=qHc(a,d,b)}return c} +function vQc(){hQc();this.c=new Rkb;this.i=new Rkb;this.e=new zsb;this.f=new zsb;this.g=new zsb;this.j=new Rkb;this.a=new Rkb;this.b=new Lqb;this.k=new Lqb} +function aKd(a,b){var c,d;if(a.Db>>16==6){return a.Cb.ih(a,5,o5,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?a.zh():c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function Wz(a){Rz();var b=a.e;if(b&&b.stack){var c=b.stack;var d=b+'\n';c.substring(0,d.length)==d&&(c=c.substring(d.length));return c.split('\n')}return []} +function jeb(a){var b;b=(qeb(),peb);return b[a>>>28]|b[a>>24&15]<<4|b[a>>20&15]<<8|b[a>>16&15]<<12|b[a>>12&15]<<16|b[a>>8&15]<<20|b[a>>4&15]<<24|b[a&15]<<28} +function _jb(a){var b,c,d;if(a.b!=a.c){return}d=a.a.length;c=geb($wnd.Math.max(8,d))<<1;if(a.b!=0){b=_Bb(a.a,c);$jb(a,b,d);a.a=b;a.b=0}else{dCb(a.a,c)}a.c=d} +function DKb(a,b){var c;c=a.b;return c.Xe((Y9c(),s9c))?c.Hf()==(Ucd(),Tcd)?-c.rf().a-Edb(ED(c.We(s9c))):b+Edb(ED(c.We(s9c))):c.Hf()==(Ucd(),Tcd)?-c.rf().a:b} +function P_b(a){var b;if(a.b.c.length!=0&&!!BD(Ikb(a.b,0),70).a){return BD(Ikb(a.b,0),70).a}b=JZb(a);if(b!=null){return b}return ''+(!a.c?-1:Jkb(a.c.a,a,0))} +function C0b(a){var b;if(a.f.c.length!=0&&!!BD(Ikb(a.f,0),70).a){return BD(Ikb(a.f,0),70).a}b=JZb(a);if(b!=null){return b}return ''+(!a.i?-1:Jkb(a.i.j,a,0))} +function Ogc(a,b){var c,d;if(b<0||b>=a.gc()){return null}for(c=b;c<a.gc();++c){d=BD(a.Xb(c),128);if(c==a.gc()-1||!d.o){return new vgd(meb(c),d)}}return null} +function uoc(a,b,c){var d,e,f,g,h;f=a.c;h=c?b:a;d=c?a:b;for(e=h.p+1;e<d.p;++e){g=BD(Ikb(f.a,e),10);if(!(g.k==(j0b(),d0b)||voc(g))){return false}}return true} +function u$c(a){var b,c,d,e,f;f=0;e=Qje;d=0;for(c=new olb(a.a);c.a<c.c.c.length;){b=BD(mlb(c),187);f+=b.r+(d>0?a.c:0);e=$wnd.Math.max(e,b.d);++d}a.e=f;a.b=e} +function shd(a){var b,c;if(!a.b){a.b=Qu(BD(a.f,118).Ag().i);for(c=new Fyd(BD(a.f,118).Ag());c.e!=c.i.gc();){b=BD(Dyd(c),137);Ekb(a.b,new dhd(b))}}return a.b} +function Ctd(a,b){var c,d,e;if(b.dc()){return LCd(),LCd(),KCd}else{c=new zyd(a,b.gc());for(e=new Fyd(a);e.e!=e.i.gc();){d=Dyd(e);b.Hc(d)&&wtd(c,d)}return c}} +function bkd(a,b,c,d){if(b==0){return d?(!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),a.o):(!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),FAd(a.o))}return fid(a,b,c,d)} +function Tnd(a){var b,c;if(a.rb){for(b=0,c=a.rb.i;b<c;++b){Cmd(qud(a.rb,b))}}if(a.vb){for(b=0,c=a.vb.i;b<c;++b){Cmd(qud(a.vb,b))}}u1d((O6d(),M6d),a);a.Bb|=1} +function _nd(a,b,c,d,e,f,g,h,i,j,k,l,m,n){aod(a,b,d,null,e,f,g,h,i,j,m,true,n);CUd(a,k);JD(a.Cb,88)&&XMd($Kd(BD(a.Cb,88)),2);!!c&&DUd(a,c);EUd(a,l);return a} +function jZd(b){var c,d;if(b==null){return null}d=0;try{d=Icb(b,Rie,Ohe)&aje}catch(a){a=ubb(a);if(JD(a,127)){c=rfb(b);d=c[0]}else throw vbb(a)}return bdb(d)} +function kZd(b){var c,d;if(b==null){return null}d=0;try{d=Icb(b,Rie,Ohe)&aje}catch(a){a=ubb(a);if(JD(a,127)){c=rfb(b);d=c[0]}else throw vbb(a)}return bdb(d)} +function bD(a,b){var c,d,e;e=a.h-b.h;if(e<0){return false}c=a.l-b.l;d=a.m-b.m+(c>>22);e+=d>>22;if(e<0){return false}a.l=c&Eje;a.m=d&Eje;a.h=e&Fje;return true} +function Fwb(a,b,c,d,e,f,g){var h,i;if(b.Ae()&&(i=a.a.ue(c,d),i<0||!e&&i==0)){return false}if(b.Be()&&(h=a.a.ue(c,f),h>0||!g&&h==0)){return false}return true} +function Vcc(a,b){Occ();var c;c=a.j.g-b.j.g;if(c!=0){return 0}switch(a.j.g){case 2:return Ycc(b,Ncc)-Ycc(a,Ncc);case 4:return Ycc(a,Mcc)-Ycc(b,Mcc);}return 0} +function Tqc(a){switch(a.g){case 0:return Mqc;case 1:return Nqc;case 2:return Oqc;case 3:return Pqc;case 4:return Qqc;case 5:return Rqc;default:return null;}} +function End(a,b,c){var d,e;d=(e=new rUd,yId(e,b),pnd(e,c),wtd((!a.c&&(a.c=new cUd(p5,a,12,10)),a.c),e),e);AId(d,0);DId(d,1);CId(d,true);BId(d,true);return d} +function tud(a,b){var c,d;if(b>=a.i)throw vbb(new $zd(b,a.i));++a.j;c=a.g[b];d=a.i-b-1;d>0&&$fb(a.g,b+1,a.g,b,d);NC(a.g,--a.i,null);a.fi(b,c);a.ci();return c} +function UId(a,b){var c,d;if(a.Db>>16==17){return a.Cb.ih(a,21,c5,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?a.zh():c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function iDb(a){var b,c,d,e;mmb();Okb(a.c,a.a);for(e=new olb(a.c);e.a<e.c.c.length;){d=mlb(e);for(c=new olb(a.b);c.a<c.c.c.length;){b=BD(mlb(c),679);b.Ke(d)}}} +function pXb(a){var b,c,d,e;mmb();Okb(a.c,a.a);for(e=new olb(a.c);e.a<e.c.c.length;){d=mlb(e);for(c=new olb(a.b);c.a<c.c.c.length;){b=BD(mlb(c),369);b.Ke(d)}}} +function AGb(a){var b,c,d,e,f;e=Ohe;f=null;for(d=new olb(a.d);d.a<d.c.c.length;){c=BD(mlb(d),213);if(c.d.j^c.e.j){b=c.e.e-c.d.e-c.a;if(b<e){e=b;f=c}}}return f} +function OSb(){OSb=ccb;MSb=new Nsd(Mme,(Bcb(),false));ISb=new Nsd(Nme,100);KSb=(yTb(),wTb);JSb=new Nsd(Ome,KSb);LSb=new Nsd(Pme,qme);NSb=new Nsd(Qme,meb(Ohe))} +function ric(a,b,c){var d,e,f,g,h,i,j,k;j=0;for(e=a.a[b],f=0,g=e.length;f<g;++f){d=e[f];k=CHc(d,c);for(i=k.Kc();i.Ob();){h=BD(i.Pb(),11);Rhb(a.f,h,meb(j++))}}} +function uqd(a,b,c){var d,e,f,g;if(c){e=c.a.length;d=new Yge(e);for(g=(d.b-d.a)*d.c<0?(Xge(),Wge):new she(d);g.Ob();){f=BD(g.Pb(),19);Rc(a,b,Vpd(tB(c,f.a)))}}} +function vqd(a,b,c){var d,e,f,g;if(c){e=c.a.length;d=new Yge(e);for(g=(d.b-d.a)*d.c<0?(Xge(),Wge):new she(d);g.Ob();){f=BD(g.Pb(),19);Rc(a,b,Vpd(tB(c,f.a)))}}} +function Bkc(a){gkc();var b;b=BD(Ee(Ec(a.k),KC(F1,bne,61,2,0,1)),122);Klb(b,0,b.length,null);if(b[0]==(Ucd(),Acd)&&b[1]==Tcd){NC(b,0,Tcd);NC(b,1,Acd)}return b} +function JHc(a,b,c){var d,e,f;e=HHc(a,b,c);f=KHc(a,e);yHc(a.b);cIc(a,b,c);mmb();Okb(e,new hIc(a));d=KHc(a,e);yHc(a.b);cIc(a,c,b);return new vgd(meb(f),meb(d))} +function jJc(){jJc=ccb;gJc=e3c(new j3c,(qUb(),pUb),(S8b(),h8b));hJc=new Msd('linearSegments.inputPrio',meb(0));iJc=new Msd('linearSegments.outputPrio',meb(0))} +function yRc(){yRc=ccb;uRc=new ARc('P1_TREEIFICATION',0);vRc=new ARc('P2_NODE_ORDERING',1);wRc=new ARc('P3_NODE_PLACEMENT',2);xRc=new ARc('P4_EDGE_ROUTING',3)} +function ZWc(){ZWc=ccb;UWc=(Y9c(),C9c);XWc=T9c;NWc=Y8c;OWc=_8c;PWc=b9c;MWc=W8c;QWc=e9c;TWc=x9c;KWc=(HWc(),wWc);LWc=xWc;RWc=zWc;SWc=BWc;VWc=CWc;WWc=DWc;YWc=FWc} +function rbd(){rbd=ccb;qbd=new tbd('UNKNOWN',0);nbd=new tbd('ABOVE',1);obd=new tbd('BELOW',2);pbd=new tbd('INLINE',3);new Msd('org.eclipse.elk.labelSide',qbd)} +function rud(a,b){var c;if(a.ni()&&b!=null){for(c=0;c<a.i;++c){if(pb(b,a.g[c])){return c}}}else{for(c=0;c<a.i;++c){if(PD(a.g[c])===PD(b)){return c}}}return -1} +function DZb(a,b,c){var d,e;if(b.c==(KAc(),IAc)&&c.c==HAc){return -1}else if(b.c==HAc&&c.c==IAc){return 1}d=HZb(b.a,a.a);e=HZb(c.a,a.a);return b.c==IAc?e-d:d-e} +function Z_b(a,b,c){if(!!c&&(b<0||b>c.a.c.length)){throw vbb(new Wdb('index must be >= 0 and <= layer node count'))}!!a.c&&Lkb(a.c.a,a);a.c=c;!!c&&Dkb(c.a,b,a)} +function p7b(a,b){var c,d,e;for(d=new Sr(ur(O_b(a).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);e=BD(b.Kb(c),10);return new cc(Qb(e.n.b+e.o.b/2))}return wb(),wb(),vb} +function rMc(a,b){this.c=new Lqb;this.a=a;this.b=b;this.d=BD(vNb(a,(wtc(),otc)),304);PD(vNb(a,(Nyc(),yxc)))===PD((_qc(),Zqc))?(this.e=new bNc):(this.e=new WMc)} +function $dd(a,b){var c,d,e,f;f=0;for(d=new olb(a);d.a<d.c.c.length;){c=BD(mlb(d),33);f+=$wnd.Math.pow(c.g*c.f-b,2)}e=$wnd.Math.sqrt(f/(a.c.length-1));return e} +function bgd(a,b){var c,d;d=null;if(a.Xe((Y9c(),O9c))){c=BD(a.We(O9c),94);c.Xe(b)&&(d=c.We(b))}d==null&&!!a.yf()&&(d=a.yf().We(b));d==null&&(d=Ksd(b));return d} +function Vt(b,c){var d,e;d=b.Zc(c);try{e=d.Pb();d.Qb();return e}catch(a){a=ubb(a);if(JD(a,109)){throw vbb(new qcb("Can't remove element "+c))}else throw vbb(a)}} +function qA(a,b){var c,d,e;d=new eB;e=new fB(d.q.getFullYear()-nje,d.q.getMonth(),d.q.getDate());c=pA(a,b,e);if(c==0||c<b.length){throw vbb(new Wdb(b))}return e} +function _tb(a,b){var c,d,e;uCb(b);lCb(b!=a);e=a.b.c.length;for(d=b.Kc();d.Ob();){c=d.Pb();Ekb(a.b,uCb(c))}if(e!=a.b.c.length){aub(a,0);return true}return false} +function bTb(){bTb=ccb;VSb=(Y9c(),O8c);new Osd(B8c,(Bcb(),true));YSb=Y8c;ZSb=_8c;$Sb=b9c;XSb=W8c;_Sb=e9c;aTb=x9c;USb=(OSb(),MSb);SSb=JSb;TSb=LSb;WSb=NSb;RSb=ISb} +function MZb(a,b){if(b==a.c){return a.d}else if(b==a.d){return a.c}else{throw vbb(new Wdb("'port' must be either the source port or target port of the edge."))}} +function C3b(a,b,c){var d,e;e=a.o;d=a.d;switch(b.g){case 1:return -d.d-c;case 3:return e.b+d.a+c;case 2:return e.a+d.c+c;case 4:return -d.b-c;default:return 0;}} +function H6b(a,b,c,d){var e,f,g,h;$_b(b,BD(d.Xb(0),29));h=d.bd(1,d.gc());for(f=BD(c.Kb(b),20).Kc();f.Ob();){e=BD(f.Pb(),17);g=e.c.i==b?e.d.i:e.c.i;H6b(a,g,c,h)}} +function Xec(a){var b;b=new Lqb;if(wNb(a,(wtc(),ttc))){return BD(vNb(a,ttc),83)}MAb(JAb(new YAb(null,new Kub(a.j,16)),new Zec),new _ec(b));yNb(a,ttc,b);return b} +function cmd(a,b){var c,d;if(a.Db>>16==6){return a.Cb.ih(a,6,B2,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(Thd(),Lhd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function Eod(a,b){var c,d;if(a.Db>>16==7){return a.Cb.ih(a,1,C2,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(Thd(),Nhd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function lpd(a,b){var c,d;if(a.Db>>16==9){return a.Cb.ih(a,9,E2,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(Thd(),Phd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function mQd(a,b){var c,d;if(a.Db>>16==5){return a.Cb.ih(a,9,h5,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(jGd(),VFd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function KHd(a,b){var c,d;if(a.Db>>16==3){return a.Cb.ih(a,0,k5,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(jGd(),OFd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function Snd(a,b){var c,d;if(a.Db>>16==7){return a.Cb.ih(a,6,o5,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(jGd(),cGd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function ird(){this.a=new bqd;this.g=new wo;this.j=new wo;this.b=new Lqb;this.d=new wo;this.i=new wo;this.k=new Lqb;this.c=new Lqb;this.e=new Lqb;this.f=new Lqb} +function MCd(a,b,c){var d,e,f;c<0&&(c=0);f=a.i;for(e=c;e<f;e++){d=qud(a,e);if(b==null){if(d==null){return e}}else if(PD(b)===PD(d)||pb(b,d)){return e}}return -1} +function b1d(a,b){var c,d;c=b.Hh(a.a);if(!c){return null}else{d=GD(AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),Awe));return dfb(Bwe,d)?u1d(a,bKd(b.Hj())):d}} +function p6d(a,b){var c,d;if(b){if(b==a){return true}c=0;for(d=BD(b,49).eh();!!d&&d!=b;d=d.eh()){if(++c>Wje){return p6d(a,d)}if(d==a){return true}}}return false} +function HKb(a){CKb();switch(a.q.g){case 5:EKb(a,(Ucd(),Acd));EKb(a,Rcd);break;case 4:FKb(a,(Ucd(),Acd));FKb(a,Rcd);break;default:GKb(a,(Ucd(),Acd));GKb(a,Rcd);}} +function LKb(a){CKb();switch(a.q.g){case 5:IKb(a,(Ucd(),zcd));IKb(a,Tcd);break;case 4:JKb(a,(Ucd(),zcd));JKb(a,Tcd);break;default:KKb(a,(Ucd(),zcd));KKb(a,Tcd);}} +function XQb(a){var b,c;b=BD(vNb(a,(wSb(),pSb)),19);if(b){c=b.a;c==0?yNb(a,(HSb(),GSb),new Gub):yNb(a,(HSb(),GSb),new Hub(c))}else{yNb(a,(HSb(),GSb),new Hub(1))}} +function V$b(a,b){var c;c=a.i;switch(b.g){case 1:return -(a.n.b+a.o.b);case 2:return a.n.a-c.o.a;case 3:return a.n.b-c.o.b;case 4:return -(a.n.a+a.o.a);}return 0} +function hbc(a,b){switch(a.g){case 0:return b==(Ctc(),ytc)?dbc:ebc;case 1:return b==(Ctc(),ytc)?dbc:cbc;case 2:return b==(Ctc(),ytc)?cbc:ebc;default:return cbc;}} +function v$c(a,b){var c,d,e;Lkb(a.a,b);a.e-=b.r+(a.a.c.length==0?0:a.c);e=ere;for(d=new olb(a.a);d.a<d.c.c.length;){c=BD(mlb(d),187);e=$wnd.Math.max(e,c.d)}a.b=e} +function Lld(a,b){var c,d;if(a.Db>>16==3){return a.Cb.ih(a,12,E2,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(Thd(),Khd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function Uod(a,b){var c,d;if(a.Db>>16==11){return a.Cb.ih(a,10,E2,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(Thd(),Ohd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function PSd(a,b){var c,d;if(a.Db>>16==10){return a.Cb.ih(a,11,c5,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(jGd(),aGd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function qUd(a,b){var c,d;if(a.Db>>16==10){return a.Cb.ih(a,12,n5,b)}return d=zUd(BD(XKd((c=BD(Ajd(a,16),26),!c?(jGd(),dGd):c),a.Db>>16),18)),a.Cb.ih(a,d.n,d.f,b)} +function wId(a){var b;if((a.Bb&1)==0&&!!a.r&&a.r.kh()){b=BD(a.r,49);a.r=BD(xid(a,b),138);a.r!=b&&(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,9,8,b,a.r))}return a.r} +function yHb(a,b,c){var d;d=OC(GC(UD,1),Vje,25,15,[BHb(a,(gHb(),dHb),b,c),BHb(a,eHb,b,c),BHb(a,fHb,b,c)]);if(a.f){d[0]=$wnd.Math.max(d[0],d[2]);d[2]=d[0]}return d} +function O9b(a,b){var c,d,e;e=V9b(a,b);if(e.c.length==0){return}Okb(e,new pac);c=e.c.length;for(d=0;d<c;d++){K9b(a,(tCb(d,e.c.length),BD(e.c[d],286)),R9b(a,e,d))}} +function qkc(a){var b,c,d,e;for(e=BD(Qc(a.a,(Xjc(),Sjc)),15).Kc();e.Ob();){d=BD(e.Pb(),101);for(c=Ec(d.k).Kc();c.Ob();){b=BD(c.Pb(),61);kkc(a,d,b,(Fkc(),Dkc),1)}}} +function voc(a){var b,c;if(a.k==(j0b(),g0b)){for(c=new Sr(ur(O_b(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);if(!OZb(b)&&a.c==LZb(b,a).c){return true}}}return false} +function JNc(a){var b,c;if(a.k==(j0b(),g0b)){for(c=new Sr(ur(O_b(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);if(!OZb(b)&&b.c.i.c==b.d.i.c){return true}}}return false} +function HUc(a,b){var c,d,e,f;Odd(b,'Dull edge routing',1);for(f=Jsb(a.b,0);f.b!=f.d.c;){e=BD(Xsb(f),86);for(d=Jsb(e.d,0);d.b!=d.d.c;){c=BD(Xsb(d),188);Osb(c.a)}}} +function xqd(a,b){var c,d,e,f,g;if(b){e=b.a.length;c=new Yge(e);for(g=(c.b-c.a)*c.c<0?(Xge(),Wge):new she(c);g.Ob();){f=BD(g.Pb(),19);d=Zpd(b,f.a);!!d&&ard(a,d)}}} +function DZd(){tZd();var a,b;xZd((NFd(),MFd));wZd(MFd);Tnd(MFd);FQd=(jGd(),YFd);for(b=new olb(rZd);b.a<b.c.c.length;){a=BD(mlb(b),241);QQd(a,YFd,null)}return true} +function eD(a,b){var c,d,e,f,g,h,i,j;i=a.h>>19;j=b.h>>19;if(i!=j){return j-i}e=a.h;h=b.h;if(e!=h){return e-h}d=a.m;g=b.m;if(d!=g){return d-g}c=a.l;f=b.l;return c-f} +function fFb(){fFb=ccb;eFb=(rFb(),oFb);dFb=new Nsd(Yke,eFb);cFb=(UEb(),TEb);bFb=new Nsd(Zke,cFb);aFb=(MEb(),LEb);_Eb=new Nsd($ke,aFb);$Eb=new Nsd(_ke,(Bcb(),true))} +function cfc(a,b,c){var d,e;d=b*c;if(JD(a.g,145)){e=ugc(a);if(e.f.d){e.f.a||(a.d.a+=d+ple)}else{a.d.d-=d+ple;a.d.a+=d+ple}}else if(JD(a.g,10)){a.d.d-=d;a.d.a+=2*d}} +function vmc(a,b,c){var d,e,f,g,h;e=a[c.g];for(h=new olb(b.d);h.a<h.c.c.length;){g=BD(mlb(h),101);f=g.i;if(!!f&&f.i==c){d=g.d[c.g];e[d]=$wnd.Math.max(e[d],f.j.b)}}} +function AZc(a,b){var c,d,e,f,g;d=0;e=0;c=0;for(g=new olb(b.d);g.a<g.c.c.length;){f=BD(mlb(g),443);a$c(f);d=$wnd.Math.max(d,f.b);e+=f.d+(c>0?a.g:0);++c}b.b=d;b.e=e} +function to(a){var b,c,d;d=a.b;if(Lp(a.i,d.length)){c=d.length*2;a.b=KC(GF,Gie,317,c,0,1);a.c=KC(GF,Gie,317,c,0,1);a.f=c-1;a.i=0;for(b=a.a;b;b=b.c){po(a,b,b)}++a.g}} +function cNb(a,b,c,d){var e,f,g,h;for(e=0;e<b.o;e++){f=e-b.j+c;for(g=0;g<b.p;g++){h=g-b.k+d;YMb(b,e,g)?jNb(a,f,h)||lNb(a,f,h):$Mb(b,e,g)&&(hNb(a,f,h)||mNb(a,f,h))}}} +function Ooc(a,b,c){var d;d=b.c.i;if(d.k==(j0b(),g0b)){yNb(a,(wtc(),Vsc),BD(vNb(d,Vsc),11));yNb(a,Wsc,BD(vNb(d,Wsc),11))}else{yNb(a,(wtc(),Vsc),b.c);yNb(a,Wsc,c.d)}} +function l6c(a,b,c){i6c();var d,e,f,g,h,i;g=b/2;f=c/2;d=$wnd.Math.abs(a.a);e=$wnd.Math.abs(a.b);h=1;i=1;d>g&&(h=g/d);e>f&&(i=f/e);Y6c(a,$wnd.Math.min(h,i));return a} +function ond(){Smd();var b,c;try{c=BD(mUd((yFd(),xFd),yte),2014);if(c){return c}}catch(a){a=ubb(a);if(JD(a,102)){b=a;uvd((h0d(),b))}else throw vbb(a)}return new knd} +function Y9d(){A9d();var b,c;try{c=BD(mUd((yFd(),xFd),Ewe),2024);if(c){return c}}catch(a){a=ubb(a);if(JD(a,102)){b=a;uvd((h0d(),b))}else throw vbb(a)}return new U9d} +function qZd(){Smd();var b,c;try{c=BD(mUd((yFd(),xFd),_ve),1941);if(c){return c}}catch(a){a=ubb(a);if(JD(a,102)){b=a;uvd((h0d(),b))}else throw vbb(a)}return new mZd} +function HQd(a,b,c){var d,e;e=a.e;a.e=b;if((a.Db&4)!=0&&(a.Db&1)==0){d=new nSd(a,1,4,e,b);!c?(c=d):c.Ei(d)}e!=b&&(b?(c=QQd(a,MQd(a,b),c)):(c=QQd(a,a.a,c)));return c} +function nB(){eB.call(this);this.e=-1;this.a=false;this.p=Rie;this.k=-1;this.c=-1;this.b=-1;this.g=false;this.f=-1;this.j=-1;this.n=-1;this.i=-1;this.d=-1;this.o=Rie} +function qEb(a,b){var c,d,e;d=a.b.d.d;a.a||(d+=a.b.d.a);e=b.b.d.d;b.a||(e+=b.b.d.a);c=Kdb(d,e);if(c==0){if(!a.a&&b.a){return -1}else if(!b.a&&a.a){return 1}}return c} +function eOb(a,b){var c,d,e;d=a.b.b.d;a.a||(d+=a.b.b.a);e=b.b.b.d;b.a||(e+=b.b.b.a);c=Kdb(d,e);if(c==0){if(!a.a&&b.a){return -1}else if(!b.a&&a.a){return 1}}return c} +function PVb(a,b){var c,d,e;d=a.b.g.d;a.a||(d+=a.b.g.a);e=b.b.g.d;b.a||(e+=b.b.g.a);c=Kdb(d,e);if(c==0){if(!a.a&&b.a){return -1}else if(!b.a&&a.a){return 1}}return c} +function ZTb(){ZTb=ccb;WTb=c3c(e3c(e3c(e3c(new j3c,(qUb(),oUb),(S8b(),m8b)),oUb,q8b),pUb,x8b),pUb,a8b);YTb=e3c(e3c(new j3c,oUb,S7b),oUb,b8b);XTb=c3c(new j3c,pUb,d8b)} +function s3b(a){var b,c,d,e,f;b=BD(vNb(a,(wtc(),Csc)),83);f=a.n;for(d=b.Cc().Kc();d.Ob();){c=BD(d.Pb(),306);e=c.i;e.c+=f.a;e.d+=f.b;c.c?VHb(c):XHb(c)}yNb(a,Csc,null)} +function qmc(a,b,c){var d,e;e=a.b;d=e.d;switch(b.g){case 1:return -d.d-c;case 2:return e.o.a+d.c+c;case 3:return e.o.b+d.a+c;case 4:return -d.b-c;default:return -1;}} +function BXc(a){var b,c,d,e,f;d=0;e=dme;if(a.b){for(b=0;b<360;b++){c=b*0.017453292519943295;zXc(a,a.d,0,0,dre,c);f=a.b.ig(a.d);if(f<e){d=c;e=f}}}zXc(a,a.d,0,0,dre,d)} +function E$c(a,b){var c,d,e,f;f=new Lqb;b.e=null;b.f=null;for(d=new olb(b.i);d.a<d.c.c.length;){c=BD(mlb(d),65);e=BD(Ohb(a.g,c.a),46);c.a=D6c(c.b);Rhb(f,c.a,e)}a.g=f} +function t$c(a,b,c){var d,e,f,g,h,i;e=b-a.e;f=e/a.d.c.length;g=0;for(i=new olb(a.d);i.a<i.c.c.length;){h=BD(mlb(i),443);d=a.b-h.b+c;_Zc(h,h.e+g*f,h.f);XZc(h,f,d);++g}} +function YBd(a){var b;a.f.qj();if(a.b!=-1){++a.b;b=a.f.d[a.a];if(a.b<b.i){return}++a.a}for(;a.a<a.f.d.length;++a.a){b=a.f.d[a.a];if(!!b&&b.i!=0){a.b=0;return}}a.b=-1} +function j0d(a,b){var c,d,e;e=b.c.length;c=l0d(a,e==0?'':(tCb(0,b.c.length),GD(b.c[0])));for(d=1;d<e&&!!c;++d){c=BD(c,49).oh((tCb(d,b.c.length),GD(b.c[d])))}return c} +function rEc(a,b){var c,d;for(d=new olb(b);d.a<d.c.c.length;){c=BD(mlb(d),10);a.c[c.c.p][c.p].a=Aub(a.i);a.c[c.c.p][c.p].d=Edb(a.c[c.c.p][c.p].a);a.c[c.c.p][c.p].b=1}} +function _dd(a,b){var c,d,e,f;f=0;for(d=new olb(a);d.a<d.c.c.length;){c=BD(mlb(d),157);f+=$wnd.Math.pow(red(c)*qed(c)-b,2)}e=$wnd.Math.sqrt(f/(a.c.length-1));return e} +function LHc(a,b,c,d){var e,f,g;f=GHc(a,b,c,d);g=MHc(a,f);bIc(a,b,c,d);yHc(a.b);mmb();Okb(f,new lIc(a));e=MHc(a,f);bIc(a,c,b,d);yHc(a.b);return new vgd(meb(g),meb(e))} +function cJc(a,b,c){var d,e;Odd(c,'Interactive node placement',1);a.a=BD(vNb(b,(wtc(),otc)),304);for(e=new olb(b.b);e.a<e.c.c.length;){d=BD(mlb(e),29);bJc(a,d)}Qdd(c)} +function MVc(a,b){var c;Odd(b,'General Compactor',1);b.n&&!!a&&Tdd(b,i6d(a),(pgd(),mgd));c=qWc(BD(hkd(a,(ZWc(),LWc)),380));c.hg(a);b.n&&!!a&&Tdd(b,i6d(a),(pgd(),mgd))} +function Dfd(a,b,c){var d,e;nmd(a,a.j+b,a.k+c);for(e=new Fyd((!a.a&&(a.a=new xMd(y2,a,5)),a.a));e.e!=e.i.gc();){d=BD(Dyd(e),469);ukd(d,d.a+b,d.b+c)}gmd(a,a.b+b,a.c+c)} +function vld(a,b,c,d){switch(c){case 7:return !a.e&&(a.e=new y5d(B2,a,7,4)),Sxd(a.e,b,d);case 8:return !a.d&&(a.d=new y5d(B2,a,8,5)),Sxd(a.d,b,d);}return Fkd(a,b,c,d)} +function wld(a,b,c,d){switch(c){case 7:return !a.e&&(a.e=new y5d(B2,a,7,4)),Txd(a.e,b,d);case 8:return !a.d&&(a.d=new y5d(B2,a,8,5)),Txd(a.d,b,d);}return Gkd(a,b,c,d)} +function lqd(a,b,c){var d,e,f,g,h;if(c){f=c.a.length;d=new Yge(f);for(h=(d.b-d.a)*d.c<0?(Xge(),Wge):new she(d);h.Ob();){g=BD(h.Pb(),19);e=Zpd(c,g.a);!!e&&drd(a,e,b)}}} +function HAd(a,b,c){var d,e,f,g,h;a.qj();f=b==null?0:tb(b);if(a.f>0){g=(f&Ohe)%a.d.length;e=wAd(a,g,f,b);if(e){h=e.ed(c);return h}}d=a.tj(f,b,c);a.c.Fc(d);return null} +function t1d(a,b){var c,d,e,f;switch(o1d(a,b)._k()){case 3:case 2:{c=OKd(b);for(e=0,f=c.i;e<f;++e){d=BD(qud(c,e),34);if($1d(q1d(a,d))==5){return d}}break}}return null} +function Qs(a){var b,c,d,e,f;if(Lp(a.f,a.b.length)){d=KC(BG,Gie,330,a.b.length*2,0,1);a.b=d;e=d.length-1;for(c=a.a;c!=a;c=c.Rd()){f=BD(c,330);b=f.d&e;f.a=d[b];d[b]=f}}} +function DJb(a,b){var c,d,e,f;f=0;for(e=BD(BD(Qc(a.r,b),21),84).Kc();e.Ob();){d=BD(e.Pb(),111);f=$wnd.Math.max(f,d.e.a+d.b.rf().a)}c=BD(Mpb(a.b,b),124);c.n.b=0;c.a.a=f} +function MKb(a,b){var c,d,e,f;c=0;for(f=BD(BD(Qc(a.r,b),21),84).Kc();f.Ob();){e=BD(f.Pb(),111);c=$wnd.Math.max(c,e.e.b+e.b.rf().b)}d=BD(Mpb(a.b,b),124);d.n.d=0;d.a.b=c} +function INc(a){var b,c;c=BD(vNb(a,(wtc(),Ksc)),21);b=k3c(zNc);c.Hc((Orc(),Lrc))&&d3c(b,CNc);c.Hc(Nrc)&&d3c(b,ENc);c.Hc(Erc)&&d3c(b,ANc);c.Hc(Grc)&&d3c(b,BNc);return b} +function j1c(a,b){var c;Odd(b,'Delaunay triangulation',1);c=new Rkb;Hkb(a.i,new n1c(c));Ccb(DD(vNb(a,(XNb(),VNb))))&&'null10bw';!a.e?(a.e=NCb(c)):ye(a.e,NCb(c));Qdd(b)} +function q6c(a){if(a<0){throw vbb(new Wdb('The input must be positive'))}else return a<h6c.length?Sbb(h6c[a]):$wnd.Math.sqrt(dre*a)*(y6c(a,a)/x6c(2.718281828459045,a))} +function pud(a,b){var c;if(a.ni()&&b!=null){for(c=0;c<a.i;++c){if(pb(b,a.g[c])){return true}}}else{for(c=0;c<a.i;++c){if(PD(a.g[c])===PD(b)){return true}}}return false} +function jr(a,b){if(b==null){while(a.a.Ob()){if(BD(a.a.Pb(),42).dd()==null){return true}}}else{while(a.a.Ob()){if(pb(b,BD(a.a.Pb(),42).dd())){return true}}}return false} +function zy(a,b){var c,d,e;if(b===a){return true}else if(JD(b,664)){e=BD(b,1947);return Ue((d=a.g,!d?(a.g=new vi(a)):d),(c=e.g,!c?(e.g=new vi(e)):c))}else{return false}} +function Tz(a){var b,c,d,e;b='Sz';c='ez';e=$wnd.Math.min(a.length,5);for(d=e-1;d>=0;d--){if(dfb(a[d].d,b)||dfb(a[d].d,c)){a.length>=d+1&&a.splice(0,d+1);break}}return a} +function Abb(a,b){var c;if(Fbb(a)&&Fbb(b)){c=a/b;if(Kje<c&&c<Ije){return c<0?$wnd.Math.ceil(c):$wnd.Math.floor(c)}}return zbb(UC(Fbb(a)?Rbb(a):a,Fbb(b)?Rbb(b):b,false))} +function LZb(a,b){if(b==a.c.i){return a.d.i}else if(b==a.d.i){return a.c.i}else{throw vbb(new Wdb("'node' must either be the source node or target node of the edge."))}} +function C2b(a){var b,c,d,e;e=BD(vNb(a,(wtc(),xsc)),37);if(e){d=new d7c;b=Q_b(a.c.i);while(b!=e){c=b.e;b=Q_b(c);O6c(P6c(P6c(d,c.n),b.c),b.d.b,b.d.d)}return d}return w2b} +function Ldc(a){var b;b=BD(vNb(a,(wtc(),ntc)),403);MAb(LAb(new YAb(null,new Kub(b.d,16)),new Ydc),new $dc(a));MAb(JAb(new YAb(null,new Kub(b.d,16)),new aec),new cec(a))} +function woc(a,b){var c,d,e,f;e=b?U_b(a):R_b(a);for(d=new Sr(ur(e.a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);f=LZb(c,a);if(f.k==(j0b(),g0b)&&f.c!=a.c){return f}}return null} +function HDc(a){var b,c,d;for(c=new olb(a.p);c.a<c.c.c.length;){b=BD(mlb(c),10);if(b.k!=(j0b(),h0b)){continue}d=b.o.b;a.i=$wnd.Math.min(a.i,d);a.g=$wnd.Math.max(a.g,d)}} +function oEc(a,b,c){var d,e,f;for(f=new olb(b);f.a<f.c.c.length;){d=BD(mlb(f),10);a.c[d.c.p][d.p].e=false}for(e=new olb(b);e.a<e.c.c.length;){d=BD(mlb(e),10);nEc(a,d,c)}} +function WOc(a,b,c){var d,e;d=vPc(b.j,c.s,c.c)+vPc(c.e,b.s,b.c);e=vPc(c.j,b.s,b.c)+vPc(b.e,c.s,c.c);if(d==e){if(d>0){a.b+=2;a.a+=d}}else{a.b+=1;a.a+=$wnd.Math.min(d,e)}} +function Rpd(a,b){var c,d;d=false;if(ND(b)){d=true;Qpd(a,new yC(GD(b)))}if(!d){if(JD(b,236)){d=true;Qpd(a,(c=Kcb(BD(b,236)),new TB(c)))}}if(!d){throw vbb(new vcb(Ute))}} +function IMd(a,b,c,d){var e,f,g;e=new pSd(a.e,1,10,(g=b.c,JD(g,88)?BD(g,26):(jGd(),_Fd)),(f=c.c,JD(f,88)?BD(f,26):(jGd(),_Fd)),HLd(a,b),false);!d?(d=e):d.Ei(e);return d} +function T_b(a){var b,c;switch(BD(vNb(Q_b(a),(Nyc(),ixc)),420).g){case 0:b=a.n;c=a.o;return new f7c(b.a+c.a/2,b.b+c.b/2);case 1:return new g7c(a.n);default:return null;}} +function lrc(){lrc=ccb;irc=new mrc(ane,0);hrc=new mrc('LEFTUP',1);krc=new mrc('RIGHTUP',2);grc=new mrc('LEFTDOWN',3);jrc=new mrc('RIGHTDOWN',4);frc=new mrc('BALANCED',5)} +function FFc(a,b,c){var d,e,f;d=Kdb(a.a[b.p],a.a[c.p]);if(d==0){e=BD(vNb(b,(wtc(),Qsc)),15);f=BD(vNb(c,Qsc),15);if(e.Hc(c)){return -1}else if(f.Hc(b)){return 1}}return d} +function jXc(a){switch(a.g){case 1:return new XVc;case 2:return new ZVc;case 3:return new VVc;case 0:return null;default:throw vbb(new Wdb(jre+(a.f!=null?a.f:''+a.g)));}} +function Ikd(a,b,c){switch(b){case 1:!a.n&&(a.n=new cUd(D2,a,1,7));Uxd(a.n);!a.n&&(a.n=new cUd(D2,a,1,7));ytd(a.n,BD(c,14));return;case 2:Lkd(a,GD(c));return;}ekd(a,b,c)} +function Zkd(a,b,c){switch(b){case 3:ald(a,Edb(ED(c)));return;case 4:cld(a,Edb(ED(c)));return;case 5:dld(a,Edb(ED(c)));return;case 6:eld(a,Edb(ED(c)));return;}Ikd(a,b,c)} +function Fnd(a,b,c){var d,e,f;f=(d=new rUd,d);e=xId(f,b,null);!!e&&e.Fi();pnd(f,c);wtd((!a.c&&(a.c=new cUd(p5,a,12,10)),a.c),f);AId(f,0);DId(f,1);CId(f,true);BId(f,true)} +function mUd(a,b){var c,d,e;c=Crb(a.g,b);if(JD(c,235)){e=BD(c,235);e.Qh()==null&&undefined;return e.Nh()}else if(JD(c,498)){d=BD(c,1938);e=d.b;return e}else{return null}} +function Ui(a,b,c,d){var e,f;Qb(b);Qb(c);f=BD(tn(a.d,b),19);Ob(!!f,'Row %s not in %s',b,a.e);e=BD(tn(a.b,c),19);Ob(!!e,'Column %s not in %s',c,a.c);return Wi(a,f.a,e.a,d)} +function JC(a,b,c,d,e,f,g){var h,i,j,k,l;k=e[f];j=f==g-1;h=j?d:0;l=LC(h,k);d!=10&&OC(GC(a,g-f),b[f],c[f],h,l);if(!j){++f;for(i=0;i<k;++i){l[i]=JC(a,b,c,d,e,f,g)}}return l} +function Eyd(b){if(b.g==-1){throw vbb(new Ydb)}b.mj();try{b.i.$c(b.g);b.f=b.i.j;b.g<b.e&&--b.e;b.g=-1}catch(a){a=ubb(a);if(JD(a,73)){throw vbb(new Apb)}else throw vbb(a)}} +function hYb(a,b){a.b.a=$wnd.Math.min(a.b.a,b.c);a.b.b=$wnd.Math.min(a.b.b,b.d);a.a.a=$wnd.Math.max(a.a.a,b.c);a.a.b=$wnd.Math.max(a.a.b,b.d);return a.c[a.c.length]=b,true} +function nZb(a){var b,c,d,e;e=-1;d=0;for(c=new olb(a);c.a<c.c.c.length;){b=BD(mlb(c),243);if(b.c==(KAc(),HAc)){e=d==0?0:d-1;break}else d==a.c.length-1&&(e=d);d+=1}return e} +function UZc(a){var b,c,d,e;e=0;b=0;for(d=new olb(a.c);d.a<d.c.c.length;){c=BD(mlb(d),33);dld(c,a.e+e);eld(c,a.f);e+=c.g+a.b;b=$wnd.Math.max(b,c.f+a.b)}a.d=e-a.b;a.a=b-a.b} +function bEb(a){var b,c,d;for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),57);d=b.d.c;b.d.c=b.d.d;b.d.d=d;d=b.d.b;b.d.b=b.d.a;b.d.a=d;d=b.b.a;b.b.a=b.b.b;b.b.b=d}RDb(a)} +function BVb(a){var b,c,d;for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),81);d=b.g.c;b.g.c=b.g.d;b.g.d=d;d=b.g.b;b.g.b=b.g.a;b.g.a=d;d=b.e.a;b.e.a=b.e.b;b.e.b=d}sVb(a)} +function Lmc(a){var b,c,d,e,f;f=Ec(a.k);for(c=(Ucd(),OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd])),d=0,e=c.length;d<e;++d){b=c[d];if(b!=Scd&&!f.Hc(b)){return b}}return null} +function znc(a,b){var c,d;d=BD(Etb(KAb(JAb(new YAb(null,new Kub(b.j,16)),new Pnc))),11);if(d){c=BD(Ikb(d.e,0),17);if(c){return BD(vNb(c,(wtc(),Zsc)),19).a}}return yzc(a.b)} +function CCc(a,b){var c,d,e,f;for(f=new olb(b.a);f.a<f.c.c.length;){e=BD(mlb(f),10);Blb(a.d);for(d=new Sr(ur(U_b(e).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);zCc(a,e,c.d.i)}}} +function NZc(a,b){var c,d;Lkb(a.b,b);for(d=new olb(a.n);d.a<d.c.c.length;){c=BD(mlb(d),211);if(Jkb(c.c,b,0)!=-1){Lkb(c.c,b);UZc(c);c.c.c.length==0&&Lkb(a.n,c);break}}HZc(a)} +function $Zc(a,b){var c,d,e,f,g;g=a.f;e=0;f=0;for(d=new olb(a.a);d.a<d.c.c.length;){c=BD(mlb(d),187);OZc(c,a.e,g);KZc(c,b);f=$wnd.Math.max(f,c.r);g+=c.d+a.c;e=g}a.d=f;a.b=e} +function hVc(a){var b,c;c=$sd(a);if(Qq(c)){return null}else{b=(Qb(c),BD(mr(new Sr(ur(c.a.Kc(),new Sq))),79));return atd(BD(qud((!b.b&&(b.b=new y5d(z2,b,4,7)),b.b),0),82))}} +function XId(a){var b;if(!a.o){b=a.Lj();b?(a.o=new dYd(a,a,null)):a.rk()?(a.o=new uVd(a,null)):$1d(q1d((O6d(),M6d),a))==1?(a.o=new nYd(a)):(a.o=new sYd(a,null))}return a.o} +function w6d(a,b,c,d){var e,f,g,h,i;if(c.mh(b)){e=(g=b,!g?null:BD(d,49).xh(g));if(e){i=c.ah(b);h=b.t;if(h>1||h==-1){f=BD(i,15);e.Wb(t6d(a,f))}else{e.Wb(s6d(a,BD(i,56)))}}}} +function Zbb(b,c,d,e){Ybb();var f=Wbb;$moduleName=c;$moduleBase=d;tbb=e;function g(){for(var a=0;a<f.length;a++){f[a]()}} +if(b){try{Ihe(g)()}catch(a){b(c,a)}}else{Ihe(g)()}} +function Kgc(a){var b,c,d,e,f;for(d=new nib((new eib(a.b)).a);d.b;){c=lib(d);b=BD(c.cd(),10);f=BD(BD(c.dd(),46).a,10);e=BD(BD(c.dd(),46).b,8);P6c(X6c(b.n),P6c(R6c(f.n),e))}} +function llc(a){switch(BD(vNb(a.b,(Nyc(),Vwc)),375).g){case 1:MAb(NAb(LAb(new YAb(null,new Kub(a.d,16)),new Glc),new Ilc),new Klc);break;case 2:nlc(a);break;case 0:mlc(a);}} +function KXc(a,b,c){var d;Odd(c,'Straight Line Edge Routing',1);c.n&&!!b&&Tdd(c,i6d(b),(pgd(),mgd));d=BD(hkd(b,(MUc(),LUc)),33);LXc(a,d);c.n&&!!b&&Tdd(c,i6d(b),(pgd(),mgd))} +function i8c(){i8c=ccb;h8c=new j8c('V_TOP',0);g8c=new j8c('V_CENTER',1);f8c=new j8c('V_BOTTOM',2);d8c=new j8c('H_LEFT',3);c8c=new j8c('H_CENTER',4);e8c=new j8c('H_RIGHT',5)} +function gLd(a){var b;if((a.Db&64)!=0)return mKd(a);b=new Jfb(mKd(a));b.a+=' (abstract: ';Ffb(b,(a.Bb&256)!=0);b.a+=', interface: ';Ffb(b,(a.Bb&512)!=0);b.a+=')';return b.a} +function l3d(a,b,c,d){var e,f,g,h;if(oid(a.e)){e=b.ak();h=b.dd();f=c.dd();g=H2d(a,1,e,h,f,e.$j()?M2d(a,e,f,JD(e,99)&&(BD(e,18).Bb&Tje)!=0):-1,true);d?d.Ei(g):(d=g)}return d} +function kz(a){var b;if(a.c==null){b=PD(a.b)===PD(iz)?null:a.b;a.d=b==null?Xhe:MD(b)?nz(FD(b)):ND(b)?Vie:hdb(rb(b));a.a=a.a+': '+(MD(b)?mz(FD(b)):b+'');a.c='('+a.d+') '+a.a}} +function Wgb(a,b){this.e=a;if(Bbb(xbb(b,-4294967296),0)){this.d=1;this.a=OC(GC(WD,1),oje,25,15,[Tbb(b)])}else{this.d=2;this.a=OC(GC(WD,1),oje,25,15,[Tbb(b),Tbb(Obb(b,32))])}} +function yrb(){function b(){try{return (new Map).entries().next().done}catch(a){return false}} +if(typeof Map===Nhe&&Map.prototype.entries&&b()){return Map}else{return zrb()}} +function VPc(a,b){var c,d,e,f;f=new Bib(a.e,0);c=0;while(f.b<f.d.gc()){d=Edb((sCb(f.b<f.d.gc()),ED(f.d.Xb(f.c=f.b++))));e=d-b;if(e>Oqe){return c}else e>-1.0E-6&&++c}return c} +function PQd(a,b){var c;if(b!=a.b){c=null;!!a.b&&(c=lid(a.b,a,-4,c));!!b&&(c=kid(b,a,-4,c));c=GQd(a,b,c);!!c&&c.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,3,b,b))} +function SQd(a,b){var c;if(b!=a.f){c=null;!!a.f&&(c=lid(a.f,a,-1,c));!!b&&(c=kid(b,a,-1,c));c=IQd(a,b,c);!!c&&c.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,0,b,b))} +function E9d(a){var b,c,d;if(a==null)return null;c=BD(a,15);if(c.dc())return '';d=new Hfb;for(b=c.Kc();b.Ob();){Efb(d,(Q8d(),GD(b.Pb())));d.a+=' '}return lcb(d,d.a.length-1)} +function I9d(a){var b,c,d;if(a==null)return null;c=BD(a,15);if(c.dc())return '';d=new Hfb;for(b=c.Kc();b.Ob();){Efb(d,(Q8d(),GD(b.Pb())));d.a+=' '}return lcb(d,d.a.length-1)} +function qEc(a,b,c){var d,e;d=a.c[b.c.p][b.p];e=a.c[c.c.p][c.p];if(d.a!=null&&e.a!=null){return Ddb(d.a,e.a)}else if(d.a!=null){return -1}else if(e.a!=null){return 1}return 0} +function zqd(a,b){var c,d,e,f,g,h;if(b){f=b.a.length;c=new Yge(f);for(h=(c.b-c.a)*c.c<0?(Xge(),Wge):new she(c);h.Ob();){g=BD(h.Pb(),19);e=Zpd(b,g.a);d=new Crd(a);Aqd(d.a,e)}}} +function Qqd(a,b){var c,d,e,f,g,h;if(b){f=b.a.length;c=new Yge(f);for(h=(c.b-c.a)*c.c<0?(Xge(),Wge):new she(c);h.Ob();){g=BD(h.Pb(),19);e=Zpd(b,g.a);d=new lrd(a);nqd(d.a,e)}}} +function eFd(b){var c;if(b!=null&&b.length>0&&bfb(b,b.length-1)==33){try{c=PEd(qfb(b,0,b.length-1));return c.e==null}catch(a){a=ubb(a);if(!JD(a,32))throw vbb(a)}}return false} +function h3d(a,b,c){var d,e,f;d=b.ak();f=b.dd();e=d.$j()?H2d(a,3,d,null,f,M2d(a,d,f,JD(d,99)&&(BD(d,18).Bb&Tje)!=0),true):H2d(a,1,d,d.zj(),f,-1,true);c?c.Ei(e):(c=e);return c} +function Vee(){var a,b,c;b=0;for(a=0;a<'X'.length;a++){c=Uee((BCb(a,'X'.length),'X'.charCodeAt(a)));if(c==0)throw vbb(new mde('Unknown Option: '+'X'.substr(a)));b|=c}return b} +function mZb(a,b,c){var d,e,f;d=Q_b(b);e=a_b(d);f=new H0b;F0b(f,b);switch(c.g){case 1:G0b(f,Wcd(Zcd(e)));break;case 2:G0b(f,Zcd(e));}yNb(f,(Nyc(),Uxc),ED(vNb(a,Uxc)));return f} +function U9b(a){var b,c;b=BD(Rr(new Sr(ur(R_b(a.a).a.Kc(),new Sq))),17);c=BD(Rr(new Sr(ur(U_b(a.a).a.Kc(),new Sq))),17);return Ccb(DD(vNb(b,(wtc(),ltc))))||Ccb(DD(vNb(c,ltc)))} +function Xjc(){Xjc=ccb;Tjc=new Yjc('ONE_SIDE',0);Vjc=new Yjc('TWO_SIDES_CORNER',1);Wjc=new Yjc('TWO_SIDES_OPPOSING',2);Ujc=new Yjc('THREE_SIDES',3);Sjc=new Yjc('FOUR_SIDES',4)} +function jkc(a,b,c,d,e){var f,g;f=BD(GAb(JAb(b.Oc(),new _kc),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);g=BD(Si(a.b,c,d),15);e==0?g.Wc(0,f):g.Gc(f)} +function KDc(a,b){var c,d,e,f,g;for(f=new olb(b.a);f.a<f.c.c.length;){e=BD(mlb(f),10);for(d=new Sr(ur(R_b(e).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);g=c.c.i.p;a.n[g]=a.n[g]-1}}} +function cnc(a,b){var c,d,e,f,g;for(f=new olb(b.d);f.a<f.c.c.length;){e=BD(mlb(f),101);g=BD(Ohb(a.c,e),112).o;for(d=new Gqb(e.b);d.a<d.c.a.length;){c=BD(Fqb(d),61);ojc(e,c,g)}}} +function HJc(a){var b,c;for(c=new olb(a.e.b);c.a<c.c.c.length;){b=BD(mlb(c),29);YJc(a,b)}MAb(JAb(LAb(LAb(new YAb(null,new Kub(a.e.b,16)),new YKc),new tLc),new vLc),new xLc(a))} +function Qwd(a,b){if(!b){return false}else{if(a.Di(b)){return false}if(!a.i){if(JD(b,143)){a.i=BD(b,143);return true}else{a.i=new Hxd;return a.i.Ei(b)}}else{return a.i.Ei(b)}}} +function B9d(a){a=Qge(a,true);if(dfb(kse,a)||dfb('1',a)){return Bcb(),Acb}else if(dfb(lse,a)||dfb('0',a)){return Bcb(),zcb}throw vbb(new n8d("Invalid boolean value: '"+a+"'"))} +function Kd(a,b,c){var d,e,f;for(e=a.vc().Kc();e.Ob();){d=BD(e.Pb(),42);f=d.cd();if(PD(b)===PD(f)||b!=null&&pb(b,f)){if(c){d=new pjb(d.cd(),d.dd());e.Qb()}return d}}return null} +function dKb(a){$Jb();var b,c,d;if(!a.B.Hc((Idd(),Add))){return}d=a.f.i;b=new K6c(a.a.c);c=new p0b;c.b=b.c-d.c;c.d=b.d-d.d;c.c=d.c+d.b-(b.c+b.b);c.a=d.d+d.a-(b.d+b.a);a.e.Ff(c)} +function LNb(a,b,c,d){var e,f,g;g=$wnd.Math.min(c,ONb(BD(a.b,65),b,c,d));for(f=new olb(a.a);f.a<f.c.c.length;){e=BD(mlb(f),221);e!=b&&(g=$wnd.Math.min(g,LNb(e,b,g,d)))}return g} +function WZb(a){var b,c,d,e;e=KC(OQ,nie,193,a.b.c.length,0,2);d=new Bib(a.b,0);while(d.b<d.d.gc()){b=(sCb(d.b<d.d.gc()),BD(d.d.Xb(d.c=d.b++),29));c=d.b-1;e[c]=l_b(b.a)}return e} +function K3b(a,b,c,d,e){var f,g,h,i;g=eLb(dLb(iLb(H3b(c)),d),C3b(a,c,e));for(i=Y_b(a,c).Kc();i.Ob();){h=BD(i.Pb(),11);if(b[h.p]){f=b[h.p].i;Ekb(g.d,new BLb(f,bLb(g,f)))}}cLb(g)} +function sic(a,b){this.f=new Lqb;this.b=new Lqb;this.j=new Lqb;this.a=a;this.c=b;this.c>0&&ric(this,this.c-1,(Ucd(),zcd));this.c<this.a.length-1&&ric(this,this.c+1,(Ucd(),Tcd))} +function SEc(a){a.length>0&&a[0].length>0&&(this.c=Ccb(DD(vNb(Q_b(a[0][0]),(wtc(),Rsc)))));this.a=KC(CX,nie,2018,a.length,0,2);this.b=KC(FX,nie,2019,a.length,0,2);this.d=new ss} +function tKc(a){if(a.c.length==0){return false}if((tCb(0,a.c.length),BD(a.c[0],17)).c.i.k==(j0b(),g0b)){return true}return FAb(NAb(new YAb(null,new Kub(a,16)),new wKc),new yKc)} +function rRc(a,b,c){Odd(c,'Tree layout',1);H2c(a.b);K2c(a.b,(yRc(),uRc),uRc);K2c(a.b,vRc,vRc);K2c(a.b,wRc,wRc);K2c(a.b,xRc,xRc);a.a=F2c(a.b,b);sRc(a,b,Udd(c,1));Qdd(c);return b} +function HXc(a,b){var c,d,e,f,g,h,i;h=gVc(b);f=b.f;i=b.g;g=$wnd.Math.sqrt(f*f+i*i);e=0;for(d=new olb(h);d.a<d.c.c.length;){c=BD(mlb(d),33);e+=HXc(a,c)}return $wnd.Math.max(e,g)} +function dcd(){dcd=ccb;ccd=new gcd(ole,0);bcd=new gcd('FREE',1);acd=new gcd('FIXED_SIDE',2);Zbd=new gcd('FIXED_ORDER',3);_bd=new gcd('FIXED_RATIO',4);$bd=new gcd('FIXED_POS',5)} +function c1d(a,b){var c,d,e;c=b.Hh(a.a);if(c){e=GD(AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),Cwe));for(d=1;d<(O6d(),N6d).length;++d){if(dfb(N6d[d],e)){return d}}}return 0} +function Qlb(a){var b,c,d,e,f;if(a==null){return Xhe}f=new xwb(She,'[',']');for(c=a,d=0,e=c.length;d<e;++d){b=c[d];uwb(f,''+b)}return !f.a?f.c:f.e.length==0?f.a.a:f.a.a+(''+f.e)} +function Wlb(a){var b,c,d,e,f;if(a==null){return Xhe}f=new xwb(She,'[',']');for(c=a,d=0,e=c.length;d<e;++d){b=c[d];uwb(f,''+b)}return !f.a?f.c:f.e.length==0?f.a.a:f.a.a+(''+f.e)} +function Md(a){var b,c,d;d=new xwb(She,'{','}');for(c=a.vc().Kc();c.Ob();){b=BD(c.Pb(),42);uwb(d,Nd(a,b.cd())+'='+Nd(a,b.dd()))}return !d.a?d.c:d.e.length==0?d.a.a:d.a.a+(''+d.e)} +function EGb(a){var b,c,d,e;while(!akb(a.o)){c=BD(fkb(a.o),46);d=BD(c.a,121);b=BD(c.b,213);e=xFb(b,d);if(b.e==d){NFb(e.g,b);d.e=e.e+b.a}else{NFb(e.b,b);d.e=e.e-b.a}Ekb(a.e.a,d)}} +function F6b(a,b){var c,d,e;c=null;for(e=BD(b.Kb(a),20).Kc();e.Ob();){d=BD(e.Pb(),17);if(!c){c=d.c.i==a?d.d.i:d.c.i}else{if((d.c.i==a?d.d.i:d.c.i)!=c){return false}}}return true} +function uPc(a,b){var c,d,e,f,g;c=WNc(a,false,b);for(e=new olb(c);e.a<e.c.c.length;){d=BD(mlb(e),129);d.d==0?(BOc(d,null),COc(d,null)):(f=d.a,g=d.b,BOc(d,g),COc(d,f),undefined)}} +function qQc(a){var b,c;b=new j3c;d3c(b,cQc);c=BD(vNb(a,(wtc(),Ksc)),21);c.Hc((Orc(),Nrc))&&d3c(b,gQc);c.Hc(Erc)&&d3c(b,dQc);c.Hc(Lrc)&&d3c(b,fQc);c.Hc(Grc)&&d3c(b,eQc);return b} +function Xac(a){var b,c,d,e;Wac(a);for(c=new Sr(ur(O_b(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);d=b.c.i==a;e=d?b.d:b.c;d?RZb(b,null):QZb(b,null);yNb(b,(wtc(),ctc),e);_ac(a,e.i)}} +function wmc(a,b,c,d){var e,f;f=b.i;e=c[f.g][a.d[f.g]];switch(f.g){case 1:e-=d+b.j.b;b.g.b=e;break;case 3:e+=d;b.g.b=e;break;case 4:e-=d+b.j.a;b.g.a=e;break;case 2:e+=d;b.g.a=e;}} +function aVc(a){var b,c,d;for(c=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));c.e!=c.i.gc();){b=BD(Dyd(c),33);d=$sd(b);if(!Qr(new Sr(ur(d.a.Kc(),new Sq)))){return b}}return null} +function Cod(){var a;if(yod)return BD(nUd((yFd(),xFd),yte),2016);a=BD(JD(Phb((yFd(),xFd),yte),555)?Phb(xFd,yte):new Bod,555);yod=true;zod(a);Aod(a);Tnd(a);Shb(xFd,yte,a);return a} +function t3d(a,b,c){var d,e;if(a.j==0)return c;e=BD(LLd(a,b,c),72);d=c.ak();if(!d.Ij()||!a.a.rl(d)){throw vbb(new hz("Invalid entry feature '"+d.Hj().zb+'.'+d.ne()+"'"))}return e} +function Qi(a,b){var c,d,e,f,g,h,i,j;for(h=a.a,i=0,j=h.length;i<j;++i){g=h[i];for(d=g,e=0,f=d.length;e<f;++e){c=d[e];if(PD(b)===PD(c)||b!=null&&pb(b,c)){return true}}}return false} +function qhb(a){var b,c,d;if(ybb(a,0)>=0){c=Abb(a,Jje);d=Hbb(a,Jje)}else{b=Pbb(a,1);c=Abb(b,500000000);d=Hbb(b,500000000);d=wbb(Nbb(d,1),xbb(a,1))}return Mbb(Nbb(d,32),xbb(c,Yje))} +function oQb(a,b,c){var d,e;d=(sCb(b.b!=0),BD(Nsb(b,b.a.a),8));switch(c.g){case 0:d.b=0;break;case 2:d.b=a.f;break;case 3:d.a=0;break;default:d.a=a.g;}e=Jsb(b,0);Vsb(e,d);return b} +function pmc(a,b,c,d){var e,f,g,h,i;i=a.b;f=b.d;g=f.j;h=umc(g,i.d[g.g],c);e=P6c(R6c(f.n),f.a);switch(f.j.g){case 1:case 3:h.a+=e.a;break;case 2:case 4:h.b+=e.b;}Gsb(d,h,d.c.b,d.c)} +function yJc(a,b,c){var d,e,f,g;g=Jkb(a.e,b,0);f=new zJc;f.b=c;d=new Bib(a.e,g);while(d.b<d.d.gc()){e=(sCb(d.b<d.d.gc()),BD(d.d.Xb(d.c=d.b++),10));e.p=c;Ekb(f.e,e);uib(d)}return f} +function sYc(a,b,c,d){var e,f,g,h,i;e=null;f=0;for(h=new olb(b);h.a<h.c.c.length;){g=BD(mlb(h),33);i=g.i+g.g;if(a<g.j+g.f+d){!e?(e=g):c.i-i<c.i-f&&(e=g);f=e.i+e.g}}return !e?0:f+d} +function tYc(a,b,c,d){var e,f,g,h,i;f=null;e=0;for(h=new olb(b);h.a<h.c.c.length;){g=BD(mlb(h),33);i=g.j+g.f;if(a<g.i+g.g+d){!f?(f=g):c.j-i<c.j-e&&(f=g);e=f.j+f.f}}return !f?0:e+d} +function mA(a){var b,c,d;b=false;d=a.b.c.length;for(c=0;c<d;c++){if(nA(BD(Ikb(a.b,c),434))){if(!b&&c+1<d&&nA(BD(Ikb(a.b,c+1),434))){b=true;BD(Ikb(a.b,c),434).a=true}}else{b=false}}} +function Ahb(a,b,c,d,e){var f,g;f=0;for(g=0;g<e;g++){f=wbb(f,Qbb(xbb(b[g],Yje),xbb(d[g],Yje)));a[g]=Tbb(f);f=Obb(f,32)}for(;g<c;g++){f=wbb(f,xbb(b[g],Yje));a[g]=Tbb(f);f=Obb(f,32)}} +function Jhb(a,b){Dhb();var c,d;d=(Hgb(),Cgb);c=a;for(;b>1;b>>=1){(b&1)!=0&&(d=Ogb(d,c));c.d==1?(c=Ogb(c,c)):(c=new Xgb(Lhb(c.a,c.d,KC(WD,oje,25,c.d<<1,15,1))))}d=Ogb(d,c);return d} +function zub(){zub=ccb;var a,b,c,d;wub=KC(UD,Vje,25,25,15,1);xub=KC(UD,Vje,25,33,15,1);d=1.52587890625E-5;for(b=32;b>=0;b--){xub[b]=d;d*=0.5}c=1;for(a=24;a>=0;a--){wub[a]=c;c*=0.5}} +function S1b(a){var b,c;if(Ccb(DD(hkd(a,(Nyc(),fxc))))){for(c=new Sr(ur(_sd(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),79);if(Qld(b)){if(Ccb(DD(hkd(b,gxc)))){return true}}}}return false} +function kjc(a,b){var c,d,e;if(Qqb(a.f,b)){b.b=a;d=b.c;Jkb(a.j,d,0)!=-1||Ekb(a.j,d);e=b.d;Jkb(a.j,e,0)!=-1||Ekb(a.j,e);c=b.a.b;if(c.c.length!=0){!a.i&&(a.i=new vjc(a));qjc(a.i,c)}}} +function rmc(a){var b,c,d,e,f;c=a.c.d;d=c.j;e=a.d.d;f=e.j;if(d==f){return c.p<e.p?0:1}else if(Xcd(d)==f){return 0}else if(Vcd(d)==f){return 1}else{b=a.b;return uqb(b.b,Xcd(d))?0:1}} +function lzc(){lzc=ccb;jzc=new nzc(Aqe,0);hzc=new nzc('LONGEST_PATH',1);fzc=new nzc('COFFMAN_GRAHAM',2);gzc=new nzc(Tne,3);kzc=new nzc('STRETCH_WIDTH',4);izc=new nzc('MIN_WIDTH',5)} +function E3c(a){var b;this.d=new Lqb;this.c=a.c;this.e=a.d;this.b=a.b;this.f=new jgd(a.e);this.a=a.a;!a.f?(this.g=(b=BD(gdb(O3),9),new xqb(b,BD(_Bb(b,b.length),9),0))):(this.g=a.f)} +function grd(a,b){var c,d,e,f,g,h;e=a;g=$pd(e,'layoutOptions');!g&&(g=$pd(e,Dte));if(g){h=g;d=null;!!h&&(d=(f=$B(h,KC(ZI,nie,2,0,6,1)),new mC(h,f)));if(d){c=new Drd(h,b);reb(d,c)}}} +function atd(a){if(JD(a,239)){return BD(a,33)}else if(JD(a,186)){return mpd(BD(a,118))}else if(!a){throw vbb(new Heb(gue))}else{throw vbb(new cgb('Only support nodes and ports.'))}} +function CA(a,b,c,d){if(b>=0&&dfb(a.substr(b,'GMT'.length),'GMT')){c[0]=b+3;return tA(a,c,d)}if(b>=0&&dfb(a.substr(b,'UTC'.length),'UTC')){c[0]=b+3;return tA(a,c,d)}return tA(a,c,d)} +function tjc(a,b){var c,d,e,f,g;f=a.g.a;g=a.g.b;for(d=new olb(a.d);d.a<d.c.c.length;){c=BD(mlb(d),70);e=c.n;e.a=f;a.i==(Ucd(),Acd)?(e.b=g+a.j.b-c.o.b):(e.b=g);P6c(e,b);f+=c.o.a+a.e}} +function Odd(a,b,c){if(a.b){throw vbb(new Zdb('The task is already done.'))}else if(a.p!=null){return false}else{a.p=b;a.r=c;a.k&&(a.o=(Zfb(),Ibb(Cbb(Date.now()),_ie)));return true}} +function hsd(a){var b,c,d,e,f,g,h;h=new eC;c=a.tg();e=c!=null;e&&Upd(h,Vte,a.tg());d=a.ne();f=d!=null;f&&Upd(h,fue,a.ne());b=a.sg();g=b!=null;g&&Upd(h,'description',a.sg());return h} +function uId(a,b,c){var d,e,f;f=a.q;a.q=b;if((a.Db&4)!=0&&(a.Db&1)==0){e=new nSd(a,1,9,f,b);!c?(c=e):c.Ei(e)}if(!b){!!a.r&&(c=a.nk(null,c))}else{d=b.c;d!=a.r&&(c=a.nk(d,c))}return c} +function IYd(a,b,c){var d,e,f,g,h;c=(h=b,kid(h,a.e,-1-a.c,c));g=AYd(a.a);for(f=(d=new nib((new eib(g.a)).a),new ZYd(d));f.a.b;){e=BD(lib(f.a).cd(),87);c=QQd(e,MQd(e,a.a),c)}return c} +function JYd(a,b,c){var d,e,f,g,h;c=(h=b,lid(h,a.e,-1-a.c,c));g=AYd(a.a);for(f=(d=new nib((new eib(g.a)).a),new ZYd(d));f.a.b;){e=BD(lib(f.a).cd(),87);c=QQd(e,MQd(e,a.a),c)}return c} +function jhb(a,b,c,d){var e,f,g;if(d==0){$fb(b,0,a,c,a.length-c)}else{g=32-d;a[a.length-1]=0;for(f=a.length-1;f>c;f--){a[f]|=b[f-c-1]>>>g;a[f-1]=b[f-c-1]<<d}}for(e=0;e<c;e++){a[e]=0}} +function LJb(a){var b,c,d,e,f;b=0;c=0;for(f=a.Kc();f.Ob();){d=BD(f.Pb(),111);b=$wnd.Math.max(b,d.d.b);c=$wnd.Math.max(c,d.d.c)}for(e=a.Kc();e.Ob();){d=BD(e.Pb(),111);d.d.b=b;d.d.c=c}} +function TKb(a){var b,c,d,e,f;c=0;b=0;for(f=a.Kc();f.Ob();){d=BD(f.Pb(),111);c=$wnd.Math.max(c,d.d.d);b=$wnd.Math.max(b,d.d.a)}for(e=a.Kc();e.Ob();){d=BD(e.Pb(),111);d.d.d=c;d.d.a=b}} +function rpc(a,b){var c,d,e,f;f=new Rkb;e=0;d=b.Kc();while(d.Ob()){c=meb(BD(d.Pb(),19).a+e);while(c.a<a.f&&!Voc(a,c.a)){c=meb(c.a+1);++e}if(c.a>=a.f){break}f.c[f.c.length]=c}return f} +function sfd(a){var b,c,d,e;b=null;for(e=new olb(a.wf());e.a<e.c.c.length;){d=BD(mlb(e),181);c=new J6c(d.qf().a,d.qf().b,d.rf().a,d.rf().b);!b?(b=c):H6c(b,c)}!b&&(b=new I6c);return b} +function Fkd(a,b,c,d){var e,f;if(c==1){return !a.n&&(a.n=new cUd(D2,a,1,7)),Sxd(a.n,b,d)}return f=BD(XKd((e=BD(Ajd(a,16),26),!e?a.zh():e),c),66),f.Nj().Qj(a,yjd(a),c-aLd(a.zh()),b,d)} +function iud(a,b,c){var d,e,f,g,h;d=c.gc();a.qi(a.i+d);h=a.i-b;h>0&&$fb(a.g,b,a.g,b+d,h);g=c.Kc();a.i+=d;for(e=0;e<d;++e){f=g.Pb();mud(a,b,a.oi(b,f));a.bi(b,f);a.ci();++b}return d!=0} +function xId(a,b,c){var d;if(b!=a.q){!!a.q&&(c=lid(a.q,a,-10,c));!!b&&(c=kid(b,a,-10,c));c=uId(a,b,c)}else if((a.Db&4)!=0&&(a.Db&1)==0){d=new nSd(a,1,9,b,b);!c?(c=d):c.Ei(d)}return c} +function Yj(a,b,c,d){Mb((c&oie)==0,'flatMap does not support SUBSIZED characteristic');Mb((c&4)==0,'flatMap does not support SORTED characteristic');Qb(a);Qb(b);return new jk(a,c,d,b)} +function Qy(a,b){vCb(b,'Cannot suppress a null exception.');mCb(b!=a,'Exception can not suppress itself.');if(a.i){return}a.k==null?(a.k=OC(GC(_I,1),nie,78,0,[b])):(a.k[a.k.length]=b)} +function oA(a,b,c,d){var e,f,g,h,i,j;g=c.length;f=0;e=-1;j=sfb(a.substr(b),(ntb(),ltb));for(h=0;h<g;++h){i=c[h].length;if(i>f&&nfb(j,sfb(c[h],ltb))){e=h;f=i}}e>=0&&(d[0]=b+f);return e} +function MIb(a,b){var c;c=NIb(a.b.Hf(),b.b.Hf());if(c!=0){return c}switch(a.b.Hf().g){case 1:case 2:return beb(a.b.sf(),b.b.sf());case 3:case 4:return beb(b.b.sf(),a.b.sf());}return 0} +function iRb(a){var b,c,d;d=a.e.c.length;a.a=IC(WD,[nie,oje],[48,25],15,[d,d],2);for(c=new olb(a.c);c.a<c.c.c.length;){b=BD(mlb(c),282);a.a[b.c.b][b.d.b]+=BD(vNb(b,(wSb(),oSb)),19).a}} +function H1c(a,b,c){Odd(c,'Grow Tree',1);a.b=b.f;if(Ccb(DD(vNb(b,(XNb(),VNb))))){a.c=new tOb;D1c(a,null)}else{a.c=new tOb}a.a=false;F1c(a,b.f);yNb(b,WNb,(Bcb(),a.a?true:false));Qdd(c)} +function Umd(a,b){var c,d,e,f,g;if(a==null){return null}else{g=KC(TD,$ie,25,2*b,15,1);for(d=0,e=0;d<b;++d){c=a[d]>>4&15;f=a[d]&15;g[e++]=Qmd[c];g[e++]=Qmd[f]}return zfb(g,0,g.length)}} +function j3d(a,b,c){var d,e,f;d=b.ak();f=b.dd();e=d.$j()?H2d(a,4,d,f,null,M2d(a,d,f,JD(d,99)&&(BD(d,18).Bb&Tje)!=0),true):H2d(a,d.Kj()?2:1,d,f,d.zj(),-1,true);c?c.Ei(e):(c=e);return c} +function wfb(a){var b,c;if(a>=Tje){b=Uje+(a-Tje>>10&1023)&aje;c=56320+(a-Tje&1023)&aje;return String.fromCharCode(b)+(''+String.fromCharCode(c))}else{return String.fromCharCode(a&aje)}} +function bKb(a,b){$Jb();var c,d,e,f;e=BD(BD(Qc(a.r,b),21),84);if(e.gc()>=2){d=BD(e.Kc().Pb(),111);c=a.u.Hc((rcd(),mcd));f=a.u.Hc(qcd);return !d.a&&!c&&(e.gc()==2||f)}else{return false}} +function IVc(a,b,c,d,e){var f,g,h;f=JVc(a,b,c,d,e);h=false;while(!f){AVc(a,e,true);h=true;f=JVc(a,b,c,d,e)}h&&AVc(a,e,false);g=dVc(e);if(g.c.length!=0){!!a.d&&a.d.lg(g);IVc(a,e,c,d,g)}} +function Mad(){Mad=ccb;Kad=new Nad(ane,0);Iad=new Nad('DIRECTED',1);Lad=new Nad('UNDIRECTED',2);Gad=new Nad('ASSOCIATION',3);Jad=new Nad('GENERALIZATION',4);Had=new Nad('DEPENDENCY',5)} +function kfd(a,b){var c;if(!mpd(a)){throw vbb(new Zdb(Sse))}c=mpd(a);switch(b.g){case 1:return -(a.j+a.f);case 2:return a.i-c.g;case 3:return a.j-c.f;case 4:return -(a.i+a.g);}return 0} +function cub(a,b){var c,d;uCb(b);d=a.b.c.length;Ekb(a.b,b);while(d>0){c=d;d=(d-1)/2|0;if(a.a.ue(Ikb(a.b,d),b)<=0){Nkb(a.b,c,b);return true}Nkb(a.b,c,Ikb(a.b,d))}Nkb(a.b,d,b);return true} +function BHb(a,b,c,d){var e,f;e=0;if(!c){for(f=0;f<sHb;f++){e=$wnd.Math.max(e,qHb(a.a[f][b.g],d))}}else{e=qHb(a.a[c.g][b.g],d)}b==(gHb(),eHb)&&!!a.b&&(e=$wnd.Math.max(e,a.b.a));return e} +function knc(a,b){var c,d,e,f,g,h;e=a.i;f=b.i;if(!e||!f){return false}if(e.i!=f.i||e.i==(Ucd(),zcd)||e.i==(Ucd(),Tcd)){return false}g=e.g.a;c=g+e.j.a;h=f.g.a;d=h+f.j.a;return g<=d&&c>=h} +function Tpd(a,b,c,d){var e;e=false;if(ND(d)){e=true;Upd(b,c,GD(d))}if(!e){if(KD(d)){e=true;Tpd(a,b,c,d)}}if(!e){if(JD(d,236)){e=true;Spd(b,c,BD(d,236))}}if(!e){throw vbb(new vcb(Ute))}} +function W0d(a,b){var c,d,e;c=b.Hh(a.a);if(c){e=AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),Sve);if(e!=null){for(d=1;d<(O6d(),K6d).length;++d){if(dfb(K6d[d],e)){return d}}}}return 0} +function X0d(a,b){var c,d,e;c=b.Hh(a.a);if(c){e=AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),Sve);if(e!=null){for(d=1;d<(O6d(),L6d).length;++d){if(dfb(L6d[d],e)){return d}}}}return 0} +function Ve(a,b){var c,d,e,f;uCb(b);f=a.a.gc();if(f<b.gc()){for(c=a.a.ec().Kc();c.Ob();){d=c.Pb();b.Hc(d)&&c.Qb()}}else{for(e=b.Kc();e.Ob();){d=e.Pb();a.a.Bc(d)!=null}}return f!=a.a.gc()} +function bYb(a){var b,c;c=R6c(l7c(OC(GC(m1,1),nie,8,0,[a.i.n,a.n,a.a])));b=a.i.d;switch(a.j.g){case 1:c.b-=b.d;break;case 2:c.a+=b.c;break;case 3:c.b+=b.a;break;case 4:c.a-=b.b;}return c} +function P9b(a){var b;b=(I9b(),BD(Rr(new Sr(ur(R_b(a).a.Kc(),new Sq))),17).c.i);while(b.k==(j0b(),g0b)){yNb(b,(wtc(),Tsc),(Bcb(),true));b=BD(Rr(new Sr(ur(R_b(b).a.Kc(),new Sq))),17).c.i}} +function bIc(a,b,c,d){var e,f,g,h;h=CHc(b,d);for(g=h.Kc();g.Ob();){e=BD(g.Pb(),11);a.d[e.p]=a.d[e.p]+a.c[c.p]}h=CHc(c,d);for(f=h.Kc();f.Ob();){e=BD(f.Pb(),11);a.d[e.p]=a.d[e.p]-a.c[b.p]}} +function Efd(a,b,c){var d,e;for(e=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));e.e!=e.i.gc();){d=BD(Dyd(e),33);bld(d,d.i+b,d.j+c)}reb((!a.b&&(a.b=new cUd(B2,a,12,3)),a.b),new Kfd(b,c))} +function Mwb(a,b,c,d){var e,f;f=b;e=f.d==null||a.a.ue(c.d,f.d)>0?1:0;while(f.a[e]!=c){f=f.a[e];e=a.a.ue(c.d,f.d)>0?1:0}f.a[e]=d;d.b=c.b;d.a[0]=c.a[0];d.a[1]=c.a[1];c.a[0]=null;c.a[1]=null} +function ucd(a){rcd();var b,c;b=qqb(ncd,OC(GC(E1,1),Kie,273,0,[pcd]));if(Ox(Cx(b,a))>1){return false}c=qqb(mcd,OC(GC(E1,1),Kie,273,0,[lcd,qcd]));if(Ox(Cx(c,a))>1){return false}return true} +function fod(a,b){var c;c=Phb((yFd(),xFd),a);JD(c,498)?Shb(xFd,a,new bUd(this,b)):Shb(xFd,a,this);bod(this,b);if(b==(LFd(),KFd)){this.wb=BD(this,1939);BD(b,1941)}else{this.wb=(NFd(),MFd)}} +function lZd(b){var c,d,e;if(b==null){return null}c=null;for(d=0;d<Pmd.length;++d){try{return DQd(Pmd[d],b)}catch(a){a=ubb(a);if(JD(a,32)){e=a;c=e}else throw vbb(a)}}throw vbb(new rFd(c))} +function Dpb(){Dpb=ccb;Bpb=OC(GC(ZI,1),nie,2,6,['Sun','Mon','Tue','Wed','Thu','Fri','Sat']);Cpb=OC(GC(ZI,1),nie,2,6,['Jan','Feb','Mar','Apr',fje,'Jun','Jul','Aug','Sep','Oct','Nov','Dec'])} +function yyb(a){var b,c,d;b=dfb(typeof(b),uke)?null:new iCb;if(!b){return}$xb();c=(d=900,d>=_ie?'error':d>=900?'warn':d>=800?'info':'log');gCb(c,a.a);!!a.b&&hCb(b,c,a.b,'Exception: ',true)} +function vNb(a,b){var c,d;d=(!a.q&&(a.q=new Lqb),Ohb(a.q,b));if(d!=null){return d}c=b.wg();JD(c,4)&&(c==null?(!a.q&&(a.q=new Lqb),Thb(a.q,b)):(!a.q&&(a.q=new Lqb),Rhb(a.q,b,c)),a);return c} +function qUb(){qUb=ccb;lUb=new rUb('P1_CYCLE_BREAKING',0);mUb=new rUb('P2_LAYERING',1);nUb=new rUb('P3_NODE_ORDERING',2);oUb=new rUb('P4_NODE_PLACEMENT',3);pUb=new rUb('P5_EDGE_ROUTING',4)} +function SUb(a,b){var c,d,e,f,g;e=b==1?KUb:JUb;for(d=e.a.ec().Kc();d.Ob();){c=BD(d.Pb(),103);for(g=BD(Qc(a.f.c,c),21).Kc();g.Ob();){f=BD(g.Pb(),46);Lkb(a.b.b,f.b);Lkb(a.b.a,BD(f.b,81).d)}}} +function IWb(a,b){AWb();var c;if(a.c==b.c){if(a.b==b.b||pWb(a.b,b.b)){c=mWb(a.b)?1:-1;if(a.a&&!b.a){return c}else if(!a.a&&b.a){return -c}}return beb(a.b.g,b.b.g)}else{return Kdb(a.c,b.c)}} +function y6b(a,b){var c;Odd(b,'Hierarchical port position processing',1);c=a.b;c.c.length>0&&x6b((tCb(0,c.c.length),BD(c.c[0],29)),a);c.c.length>1&&x6b(BD(Ikb(c,c.c.length-1),29),a);Qdd(b)} +function RVc(a,b){var c,d,e;if(CVc(a,b)){return true}for(d=new olb(b);d.a<d.c.c.length;){c=BD(mlb(d),33);e=hVc(c);if(BVc(a,c,e)){return true}if(PVc(a,c)-a.g<=a.a){return true}}return false} +function d0c(){d0c=ccb;c0c=(A0c(),z0c);__c=v0c;$_c=t0c;Y_c=p0c;Z_c=r0c;X_c=new q0b(8);W_c=new Osd((Y9c(),f9c),X_c);a0c=new Osd(T9c,8);b0c=x0c;T_c=k0c;U_c=m0c;V_c=new Osd(y8c,(Bcb(),false))} +function X7c(){X7c=ccb;U7c=new q0b(15);T7c=new Osd((Y9c(),f9c),U7c);W7c=new Osd(T9c,15);V7c=new Osd(D9c,meb(0));O7c=I8c;Q7c=Y8c;S7c=b9c;L7c=new Osd(r8c,pse);P7c=O8c;R7c=_8c;M7c=t8c;N7c=w8c} +function jtd(a){if((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b).i!=1||(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c).i!=1){throw vbb(new Wdb(iue))}return atd(BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82))} +function ktd(a){if((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b).i!=1||(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c).i!=1){throw vbb(new Wdb(iue))}return btd(BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82))} +function mtd(a){if((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b).i!=1||(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c).i!=1){throw vbb(new Wdb(iue))}return btd(BD(qud((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c),0),82))} +function ltd(a){if((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b).i!=1||(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c).i!=1){throw vbb(new Wdb(iue))}return atd(BD(qud((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c),0),82))} +function Dvd(a,b,c){var d,e,f;++a.j;e=a.Vi();if(b>=e||b<0)throw vbb(new qcb(lue+b+mue+e));if(c>=e||c<0)throw vbb(new qcb(nue+c+mue+e));b!=c?(d=(f=a.Ti(c),a.Hi(b,f),f)):(d=a.Oi(c));return d} +function m6d(a){var b,c,d;d=a;if(a){b=0;for(c=a.Ug();c;c=c.Ug()){if(++b>Wje){return m6d(c)}d=c;if(c==a){throw vbb(new Zdb('There is a cycle in the containment hierarchy of '+a))}}}return d} +function Fe(a){var b,c,d;d=new xwb(She,'[',']');for(c=a.Kc();c.Ob();){b=c.Pb();uwb(d,PD(b)===PD(a)?'(this Collection)':b==null?Xhe:fcb(b))}return !d.a?d.c:d.e.length==0?d.a.a:d.a.a+(''+d.e)} +function CVc(a,b){var c,d;d=false;if(b.gc()<2){return false}for(c=0;c<b.gc();c++){c<b.gc()-1?(d=d|BVc(a,BD(b.Xb(c),33),BD(b.Xb(c+1),33))):(d=d|BVc(a,BD(b.Xb(c),33),BD(b.Xb(0),33)))}return d} +function Ymd(a,b){var c;if(b!=a.a){c=null;!!a.a&&(c=BD(a.a,49).ih(a,4,o5,c));!!b&&(c=BD(b,49).gh(a,4,o5,c));c=Tmd(a,b,c);!!c&&c.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,1,b,b))} +function RQd(a,b){var c;if(b!=a.e){!!a.e&&QYd(AYd(a.e),a);!!b&&(!b.b&&(b.b=new RYd(new NYd)),PYd(b.b,a));c=HQd(a,b,null);!!c&&c.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,4,b,b))} +function ufb(a){var b,c,d;c=a.length;d=0;while(d<c&&(BCb(d,a.length),a.charCodeAt(d)<=32)){++d}b=c;while(b>d&&(BCb(b-1,a.length),a.charCodeAt(b-1)<=32)){--b}return d>0||b<c?a.substr(d,b-d):a} +function ujc(a,b){var c;c=b.o;if(fad(a.f)){a.j.a=$wnd.Math.max(a.j.a,c.a);a.j.b+=c.b;a.d.c.length>1&&(a.j.b+=a.e)}else{a.j.a+=c.a;a.j.b=$wnd.Math.max(a.j.b,c.b);a.d.c.length>1&&(a.j.a+=a.e)}} +function gkc(){gkc=ccb;dkc=OC(GC(F1,1),bne,61,0,[(Ucd(),Acd),zcd,Rcd]);ckc=OC(GC(F1,1),bne,61,0,[zcd,Rcd,Tcd]);ekc=OC(GC(F1,1),bne,61,0,[Rcd,Tcd,Acd]);fkc=OC(GC(F1,1),bne,61,0,[Tcd,Acd,zcd])} +function omc(a,b,c,d){var e,f,g,h,i,j,k;g=a.c.d;h=a.d.d;if(g.j==h.j){return}k=a.b;e=g.j;i=null;while(e!=h.j){i=b==0?Xcd(e):Vcd(e);f=umc(e,k.d[e.g],c);j=umc(i,k.d[i.g],c);Dsb(d,P6c(f,j));e=i}} +function oFc(a,b,c,d){var e,f,g,h,i;g=JHc(a.a,b,c);h=BD(g.a,19).a;f=BD(g.b,19).a;if(d){i=BD(vNb(b,(wtc(),gtc)),10);e=BD(vNb(c,gtc),10);if(!!i&&!!e){mic(a.b,i,e);h+=a.b.i;f+=a.b.e}}return h>f} +function oHc(a){var b,c,d,e,f,g,h,i,j;this.a=lHc(a);this.b=new Rkb;for(c=a,d=0,e=c.length;d<e;++d){b=c[d];f=new Rkb;Ekb(this.b,f);for(h=b,i=0,j=h.length;i<j;++i){g=h[i];Ekb(f,new Tkb(g.j))}}} +function qHc(a,b,c){var d,e,f;f=0;d=c[b];if(b<c.length-1){e=c[b+1];if(a.b[b]){f=KIc(a.d,d,e);f+=NHc(a.a,d,(Ucd(),zcd));f+=NHc(a.a,e,Tcd)}else{f=IHc(a.a,d,e)}}a.c[b]&&(f+=PHc(a.a,d));return f} +function jZb(a,b,c,d,e){var f,g,h,i;i=null;for(h=new olb(d);h.a<h.c.c.length;){g=BD(mlb(h),441);if(g!=c&&Jkb(g.e,e,0)!=-1){i=g;break}}f=kZb(e);QZb(f,c.b);RZb(f,i.b);Rc(a.a,e,new BZb(f,b,c.f))} +function nic(a){while(a.g.c!=0&&a.d.c!=0){if(wic(a.g).c>wic(a.d).c){a.i+=a.g.c;yic(a.d)}else if(wic(a.d).c>wic(a.g).c){a.e+=a.d.c;yic(a.g)}else{a.i+=vic(a.g);a.e+=vic(a.d);yic(a.g);yic(a.d)}}} +function XOc(a,b,c){var d,e,f,g;f=b.q;g=b.r;new DOc((HOc(),FOc),b,f,1);new DOc(FOc,f,g,1);for(e=new olb(c);e.a<e.c.c.length;){d=BD(mlb(e),112);if(d!=f&&d!=b&&d!=g){pPc(a.a,d,b);pPc(a.a,d,g)}}} +function XQc(a,b,c,d){a.a.d=$wnd.Math.min(b,c);a.a.a=$wnd.Math.max(b,d)-a.a.d;if(b<c){a.b=0.5*(b+c);a.g=Qqe*a.b+0.9*b;a.f=Qqe*a.b+0.9*c}else{a.b=0.5*(b+d);a.g=Qqe*a.b+0.9*d;a.f=Qqe*a.b+0.9*b}} +function acb(){_bb={};!Array.isArray&&(Array.isArray=function(a){return Object.prototype.toString.call(a)==='[object Array]'});function b(){return (new Date).getTime()} +!Date.now&&(Date.now=b)} +function $Tb(a,b){var c,d;d=BD(vNb(b,(Nyc(),Vxc)),98);yNb(b,(wtc(),dtc),d);c=b.e;!!c&&(MAb(new YAb(null,new Kub(c.a,16)),new dUb(a)),MAb(LAb(new YAb(null,new Kub(c.b,16)),new fUb),new hUb(a)))} +function _$b(a){var b,c,d,e;if(gad(BD(vNb(a.b,(Nyc(),Lwc)),103))){return 0}b=0;for(d=new olb(a.a);d.a<d.c.c.length;){c=BD(mlb(d),10);if(c.k==(j0b(),h0b)){e=c.o.a;b=$wnd.Math.max(b,e)}}return b} +function c5b(a){switch(BD(vNb(a,(Nyc(),mxc)),163).g){case 1:yNb(a,mxc,(Ctc(),ztc));break;case 2:yNb(a,mxc,(Ctc(),Atc));break;case 3:yNb(a,mxc,(Ctc(),xtc));break;case 4:yNb(a,mxc,(Ctc(),ytc));}} +function yrc(){yrc=ccb;wrc=new zrc(ane,0);trc=new zrc(jle,1);xrc=new zrc(kle,2);vrc=new zrc('LEFT_RIGHT_CONSTRAINT_LOCKING',3);urc=new zrc('LEFT_RIGHT_CONNECTION_LOCKING',4);rrc=new zrc(Vne,5)} +function qRc(a,b,c){var d,e,f,g,h,i,j;h=c.a/2;f=c.b/2;d=$wnd.Math.abs(b.a-a.a);e=$wnd.Math.abs(b.b-a.b);i=1;j=1;d>h&&(i=h/d);e>f&&(j=f/e);g=$wnd.Math.min(i,j);a.a+=g*(b.a-a.a);a.b+=g*(b.b-a.b)} +function sZc(a,b,c,d,e){var f,g;g=false;f=BD(Ikb(c.b,0),33);while(yZc(a,b,f,d,e)){g=true;NZc(c,f);if(c.b.c.length==0){break}f=BD(Ikb(c.b,0),33)}c.b.c.length==0&&v$c(c.j,c);g&&a$c(b.q);return g} +function t6c(a,b){i6c();var c,d,e,f;if(b.b<2){return false}f=Jsb(b,0);c=BD(Xsb(f),8);d=c;while(f.b!=f.d.c){e=BD(Xsb(f),8);if(s6c(a,d,e)){return true}d=e}if(s6c(a,d,c)){return true}return false} +function ckd(a,b,c,d){var e,f;if(c==0){return !a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),bId(a.o,b,d)}return f=BD(XKd((e=BD(Ajd(a,16),26),!e?a.zh():e),c),66),f.Nj().Rj(a,yjd(a),c-aLd(a.zh()),b,d)} +function bod(a,b){var c;if(b!=a.sb){c=null;!!a.sb&&(c=BD(a.sb,49).ih(a,1,i5,c));!!b&&(c=BD(b,49).gh(a,1,i5,c));c=Jnd(a,b,c);!!c&&c.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,4,b,b))} +function yqd(a,b){var c,d,e,f;if(b){e=Xpd(b,'x');c=new zrd(a);hmd(c.a,(uCb(e),e));f=Xpd(b,'y');d=new Ard(a);imd(d.a,(uCb(f),f))}else{throw vbb(new cqd('All edge sections need an end point.'))}} +function wqd(a,b){var c,d,e,f;if(b){e=Xpd(b,'x');c=new wrd(a);omd(c.a,(uCb(e),e));f=Xpd(b,'y');d=new xrd(a);pmd(d.a,(uCb(f),f))}else{throw vbb(new cqd('All edge sections need a start point.'))}} +function pyb(a,b){var c,d,e,f,g,h,i;for(d=syb(a),f=0,h=d.length;f<h;++f){yyb(b)}i=!lyb&&a.e?lyb?null:a.d:null;while(i){for(c=syb(i),e=0,g=c.length;e<g;++e){yyb(b)}i=!lyb&&i.e?lyb?null:i.d:null}} +function j0b(){j0b=ccb;h0b=new k0b('NORMAL',0);g0b=new k0b('LONG_EDGE',1);e0b=new k0b('EXTERNAL_PORT',2);i0b=new k0b('NORTH_SOUTH_PORT',3);f0b=new k0b('LABEL',4);d0b=new k0b('BREAKING_POINT',5)} +function g4b(a){var b,c,d,e;b=false;if(wNb(a,(wtc(),Csc))){c=BD(vNb(a,Csc),83);for(e=new olb(a.j);e.a<e.c.c.length;){d=BD(mlb(e),11);if(e4b(d)){if(!b){d4b(Q_b(a));b=true}h4b(BD(c.xc(d),306))}}}} +function qec(a,b,c){var d;Odd(c,'Self-Loop routing',1);d=rec(b);RD(vNb(b,(g6c(),f6c)));MAb(NAb(JAb(JAb(LAb(new YAb(null,new Kub(b.b,16)),new uec),new wec),new yec),new Aec),new Cec(a,d));Qdd(c)} +function gsd(a){var b,c,d,e,f,g,h,i,j;j=hsd(a);c=a.e;f=c!=null;f&&Upd(j,eue,a.e);h=a.k;g=!!h;g&&Upd(j,'type',Zr(a.k));d=Fhe(a.j);e=!d;if(e){i=new wB;cC(j,Mte,i);b=new ssd(i);reb(a.j,b)}return j} +function Jv(a){var b,c,d,e;e=Kfb((Xj(a.gc(),'size'),new Vfb),123);d=true;for(c=Wm(a).Kc();c.Ob();){b=BD(c.Pb(),42);d||(e.a+=She,e);d=false;Pfb(Kfb(Pfb(e,b.cd()),61),b.dd())}return (e.a+='}',e).a} +function kD(a,b){var c,d,e;b&=63;if(b<22){c=a.l<<b;d=a.m<<b|a.l>>22-b;e=a.h<<b|a.m>>22-b}else if(b<44){c=0;d=a.l<<b-22;e=a.m<<b-22|a.l>>44-b}else{c=0;d=0;e=a.l<<b-44}return TC(c&Eje,d&Eje,e&Fje)} +function Hcb(a){Gcb==null&&(Gcb=new RegExp('^\\s*[+-]?(NaN|Infinity|((\\d+\\.?\\d*)|(\\.\\d+))([eE][+-]?\\d+)?[dDfF]?)\\s*$'));if(!Gcb.test(a)){throw vbb(new Oeb(Oje+a+'"'))}return parseFloat(a)} +function IFb(a){var b,c,d,e;b=new Rkb;c=KC(sbb,dle,25,a.a.c.length,16,1);Glb(c,c.length);for(e=new olb(a.a);e.a<e.c.c.length;){d=BD(mlb(e),121);if(!c[d.d]){b.c[b.c.length]=d;HFb(a,d,c)}}return b} +function Nmc(a,b){var c,d,e,f;f=b.b.j;a.a=KC(WD,oje,25,f.c.length,15,1);e=0;for(d=0;d<f.c.length;d++){c=(tCb(d,f.c.length),BD(f.c[d],11));c.e.c.length==0&&c.g.c.length==0?(e+=1):(e+=3);a.a[d]=e}} +function Sqc(){Sqc=ccb;Nqc=new Uqc('ALWAYS_UP',0);Mqc=new Uqc('ALWAYS_DOWN',1);Pqc=new Uqc('DIRECTION_UP',2);Oqc=new Uqc('DIRECTION_DOWN',3);Rqc=new Uqc('SMART_UP',4);Qqc=new Uqc('SMART_DOWN',5)} +function k6c(a,b){if(a<0||b<0){throw vbb(new Wdb('k and n must be positive'))}else if(b>a){throw vbb(new Wdb('k must be smaller than n'))}else return b==0||b==a?1:a==0?0:q6c(a)/(q6c(b)*q6c(a-b))} +function jfd(a,b){var c,d,e,f;c=new _ud(a);while(c.g==null&&!c.c?Uud(c):c.g==null||c.i!=0&&BD(c.g[c.i-1],47).Ob()){f=BD(Vud(c),56);if(JD(f,160)){d=BD(f,160);for(e=0;e<b.length;e++){b[e].og(d)}}}} +function fld(a){var b;if((a.Db&64)!=0)return Mkd(a);b=new Jfb(Mkd(a));b.a+=' (height: ';Bfb(b,a.f);b.a+=', width: ';Bfb(b,a.g);b.a+=', x: ';Bfb(b,a.i);b.a+=', y: ';Bfb(b,a.j);b.a+=')';return b.a} +function un(a){var b,c,d,e,f,g,h;b=new $rb;for(d=a,e=0,f=d.length;e<f;++e){c=d[e];g=Qb(c.cd());h=Xrb(b,g,Qb(c.dd()));if(h!=null){throw vbb(new Wdb('duplicate key: '+g))}}this.b=(mmb(),new iob(b))} +function Rlb(a){var b,c,d,e,f;if(a==null){return Xhe}f=new xwb(She,'[',']');for(c=a,d=0,e=c.length;d<e;++d){b=c[d];uwb(f,String.fromCharCode(b))}return !f.a?f.c:f.e.length==0?f.a.a:f.a.a+(''+f.e)} +function SRb(){SRb=ccb;MRb=(XRb(),WRb);LRb=new Nsd(mme,MRb);meb(1);KRb=new Nsd(nme,meb(300));meb(0);PRb=new Nsd(ome,meb(0));new Tfd;QRb=new Nsd(pme,qme);new Tfd;NRb=new Nsd(rme,5);RRb=WRb;ORb=VRb} +function NUb(a,b){var c,d,e,f,g;e=b==1?KUb:JUb;for(d=e.a.ec().Kc();d.Ob();){c=BD(d.Pb(),103);for(g=BD(Qc(a.f.c,c),21).Kc();g.Ob();){f=BD(g.Pb(),46);Ekb(a.b.b,BD(f.b,81));Ekb(a.b.a,BD(f.b,81).d)}}} +function kVd(a,b){var c;if(b!=null&&!a.c.Yj().wj(b)){c=JD(b,56)?BD(b,56).Tg().zb:hdb(rb(b));throw vbb(new Cdb(ite+a.c.ne()+"'s type '"+a.c.Yj().ne()+"' does not permit a value of type '"+c+"'"))}} +function cZb(a,b,c){var d,e;e=new Bib(a.b,0);while(e.b<e.d.gc()){d=(sCb(e.b<e.d.gc()),BD(e.d.Xb(e.c=e.b++),70));if(PD(vNb(d,(wtc(),btc)))!==PD(b)){continue}Y$b(d.n,Q_b(a.c.i),c);uib(e);Ekb(b.b,d)}} +function vdc(a,b){if(b.a){switch(BD(vNb(b.b,(wtc(),dtc)),98).g){case 0:case 1:llc(b);case 2:MAb(new YAb(null,new Kub(b.d,16)),new Idc);wkc(a.a,b);}}else{MAb(new YAb(null,new Kub(b.d,16)),new Idc)}} +function Znc(a){var b,c;c=$wnd.Math.sqrt((a.k==null&&(a.k=Soc(a,new bpc)),Edb(a.k)/(a.b*(a.g==null&&(a.g=Poc(a,new _oc)),Edb(a.g)))));b=Tbb(Cbb($wnd.Math.round(c)));b=$wnd.Math.min(b,a.f);return b} +function H0b(){z0b();n_b.call(this);this.j=(Ucd(),Scd);this.a=new d7c;new L_b;this.f=(Xj(2,Jie),new Skb(2));this.e=(Xj(4,Jie),new Skb(4));this.g=(Xj(4,Jie),new Skb(4));this.b=new Z0b(this.e,this.g)} +function j3b(a,b){var c,d;if(Ccb(DD(vNb(b,(wtc(),ltc))))){return false}d=b.c.i;if(a==(Ctc(),xtc)){if(d.k==(j0b(),f0b)){return false}}c=BD(vNb(d,(Nyc(),mxc)),163);if(c==ytc){return false}return true} +function k3b(a,b){var c,d;if(Ccb(DD(vNb(b,(wtc(),ltc))))){return false}d=b.d.i;if(a==(Ctc(),ztc)){if(d.k==(j0b(),f0b)){return false}}c=BD(vNb(d,(Nyc(),mxc)),163);if(c==Atc){return false}return true} +function L3b(a,b){var c,d,e,f,g,h,i;g=a.d;i=a.o;h=new J6c(-g.b,-g.d,g.b+i.a+g.c,g.d+i.b+g.a);for(d=b,e=0,f=d.length;e<f;++e){c=d[e];!!c&&H6c(h,c.i)}g.b=-h.c;g.d=-h.d;g.c=h.b-g.b-i.a;g.a=h.a-g.d-i.b} +function N_c(){N_c=ccb;I_c=new O_c('CENTER_DISTANCE',0);J_c=new O_c('CIRCLE_UNDERLAP',1);M_c=new O_c('RECTANGLE_UNDERLAP',2);K_c=new O_c('INVERTED_OVERLAP',3);L_c=new O_c('MINIMUM_ROOT_DISTANCE',4)} +function jde(a){hde();var b,c,d,e,f;if(a==null)return null;d=a.length;e=d*2;b=KC(TD,$ie,25,e,15,1);for(c=0;c<d;c++){f=a[c];f<0&&(f+=256);b[c*2]=gde[f>>4];b[c*2+1]=gde[f&15]}return zfb(b,0,b.length)} +function fn(a){Vm();var b,c,d;d=a.c.length;switch(d){case 0:return Um;case 1:b=BD(qr(new olb(a)),42);return ln(b.cd(),b.dd());default:c=BD(Qkb(a,KC(CK,zie,42,a.c.length,0,1)),165);return new wx(c);}} +function ITb(a){var b,c,d,e,f,g;b=new jkb;c=new jkb;Wjb(b,a);Wjb(c,a);while(c.b!=c.c){e=BD(fkb(c),37);for(g=new olb(e.a);g.a<g.c.c.length;){f=BD(mlb(g),10);if(f.e){d=f.e;Wjb(b,d);Wjb(c,d)}}}return b} +function Y_b(a,b){switch(b.g){case 1:return Nq(a.j,(z0b(),v0b));case 2:return Nq(a.j,(z0b(),t0b));case 3:return Nq(a.j,(z0b(),x0b));case 4:return Nq(a.j,(z0b(),y0b));default:return mmb(),mmb(),jmb;}} +function tic(a,b){var c,d,e;c=uic(b,a.e);d=BD(Ohb(a.g.f,c),19).a;e=a.a.c.length-1;if(a.a.c.length!=0&&BD(Ikb(a.a,e),287).c==d){++BD(Ikb(a.a,e),287).a;++BD(Ikb(a.a,e),287).b}else{Ekb(a.a,new Dic(d))}} +function VGc(a,b,c){var d,e;d=UGc(a,b,c);if(d!=0){return d}if(wNb(b,(wtc(),Zsc))&&wNb(c,Zsc)){e=beb(BD(vNb(b,Zsc),19).a,BD(vNb(c,Zsc),19).a);e<0?WGc(a,b,c):e>0&&WGc(a,c,b);return e}return TGc(a,b,c)} +function MSc(a,b,c){var d,e,f,g;if(b.b!=0){d=new Psb;for(g=Jsb(b,0);g.b!=g.d.c;){f=BD(Xsb(g),86);ye(d,URc(f));e=f.e;e.a=BD(vNb(f,(mTc(),kTc)),19).a;e.b=BD(vNb(f,lTc),19).a}MSc(a,d,Udd(c,d.b/a.a|0))}} +function JZc(a,b){var c,d,e,f,g;if(a.e<=b){return a.g}if(LZc(a,a.g,b)){return a.g}f=a.r;d=a.g;g=a.r;e=(f-d)/2+d;while(d+1<f){c=MZc(a,e,false);if(c.b<=e&&c.a<=b){g=e;f=e}else{d=e}e=(f-d)/2+d}return g} +function t2c(a,b,c){var d;d=o2c(a,b,true);Odd(c,'Recursive Graph Layout',d);jfd(b,OC(GC(g2,1),Uhe,527,0,[new q3c]));ikd(b,(Y9c(),F9c))||jfd(b,OC(GC(g2,1),Uhe,527,0,[new U3c]));u2c(a,b,null,c);Qdd(c)} +function Qdd(a){var b;if(a.p==null){throw vbb(new Zdb('The task has not begun yet.'))}if(!a.b){if(a.k){b=(Zfb(),Ibb(Cbb(Date.now()),_ie));a.q=Sbb(Qbb(b,a.o))*1.0E-9}a.c<a.r&&Rdd(a,a.r-a.c);a.b=true}} +function ofd(a){var b,c,d;d=new s7c;Dsb(d,new f7c(a.j,a.k));for(c=new Fyd((!a.a&&(a.a=new xMd(y2,a,5)),a.a));c.e!=c.i.gc();){b=BD(Dyd(c),469);Dsb(d,new f7c(b.a,b.b))}Dsb(d,new f7c(a.b,a.c));return d} +function qqd(a,b,c,d,e){var f,g,h,i,j,k;if(e){i=e.a.length;f=new Yge(i);for(k=(f.b-f.a)*f.c<0?(Xge(),Wge):new she(f);k.Ob();){j=BD(k.Pb(),19);h=Zpd(e,j.a);g=new prd(a,b,c,d);rqd(g.a,g.b,g.c,g.d,h)}}} +function Ax(b,c){var d;if(PD(b)===PD(c)){return true}if(JD(c,21)){d=BD(c,21);try{return b.gc()==d.gc()&&b.Ic(d)}catch(a){a=ubb(a);if(JD(a,173)||JD(a,205)){return false}else throw vbb(a)}}return false} +function UHb(a,b){var c;Ekb(a.d,b);c=b.rf();if(a.c){a.e.a=$wnd.Math.max(a.e.a,c.a);a.e.b+=c.b;a.d.c.length>1&&(a.e.b+=a.a)}else{a.e.a+=c.a;a.e.b=$wnd.Math.max(a.e.b,c.b);a.d.c.length>1&&(a.e.a+=a.a)}} +function cmc(a){var b,c,d,e;e=a.i;b=e.b;d=e.j;c=e.g;switch(e.a.g){case 0:c.a=(a.g.b.o.a-d.a)/2;break;case 1:c.a=b.d.n.a+b.d.a.a;break;case 2:c.a=b.d.n.a+b.d.a.a-d.a;break;case 3:c.b=b.d.n.b+b.d.a.b;}} +function Q6c(a,b,c,d,e){if(d<b||e<c){throw vbb(new Wdb('The highx must be bigger then lowx and the highy must be bigger then lowy'))}a.a<b?(a.a=b):a.a>d&&(a.a=d);a.b<c?(a.b=c):a.b>e&&(a.b=e);return a} +function lsd(a){if(JD(a,149)){return esd(BD(a,149))}else if(JD(a,229)){return fsd(BD(a,229))}else if(JD(a,23)){return gsd(BD(a,23))}else{throw vbb(new Wdb(Xte+Fe(new amb(OC(GC(SI,1),Uhe,1,5,[a])))))}} +function mhb(a,b,c,d,e){var f,g,h;f=true;for(g=0;g<d;g++){f=f&c[g]==0}if(e==0){$fb(c,d,a,0,b);g=b}else{h=32-e;f=f&c[g]<<h==0;for(g=0;g<b-1;g++){a[g]=c[g+d]>>>e|c[g+d+1]<<h}a[g]=c[g+d]>>>e;++g}return f} +function zMc(a,b,c,d){var e,f,g;if(b.k==(j0b(),g0b)){for(f=new Sr(ur(R_b(b).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);g=e.c.i.k;if(g==g0b&&a.c.a[e.c.i.c.p]==d&&a.c.a[b.c.p]==c){return true}}}return false} +function mD(a,b){var c,d,e,f;b&=63;c=a.h&Fje;if(b<22){f=c>>>b;e=a.m>>b|c<<22-b;d=a.l>>b|a.m<<22-b}else if(b<44){f=0;e=c>>>b-22;d=a.m>>b-22|a.h<<44-b}else{f=0;e=0;d=c>>>b-44}return TC(d&Eje,e&Eje,f&Fje)} +function Iic(a,b,c,d){var e;this.b=d;this.e=a==(rGc(),pGc);e=b[c];this.d=IC(sbb,[nie,dle],[177,25],16,[e.length,e.length],2);this.a=IC(WD,[nie,oje],[48,25],15,[e.length,e.length],2);this.c=new sic(b,c)} +function ljc(a){var b,c,d;a.k=new Ki((Ucd(),OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd])).length,a.j.c.length);for(d=new olb(a.j);d.a<d.c.c.length;){c=BD(mlb(d),113);b=c.d.j;Rc(a.k,b,c)}a.e=Zjc(Ec(a.k))} +function UQc(a,b){var c,d,e;Qqb(a.d,b);c=new _Qc;Rhb(a.c,b,c);c.f=VQc(b.c);c.a=VQc(b.d);c.d=(hQc(),e=b.c.i.k,e==(j0b(),h0b)||e==d0b);c.e=(d=b.d.i.k,d==h0b||d==d0b);c.b=b.c.j==(Ucd(),Tcd);c.c=b.d.j==zcd} +function BGb(a){var b,c,d,e,f;f=Ohe;e=Ohe;for(d=new olb(LFb(a));d.a<d.c.c.length;){c=BD(mlb(d),213);b=c.e.e-c.d.e;c.e==a&&b<e?(e=b):b<f&&(f=b)}e==Ohe&&(e=-1);f==Ohe&&(f=-1);return new vgd(meb(e),meb(f))} +function zQb(a,b){var c,d,e;e=dme;d=(ROb(),OOb);e=$wnd.Math.abs(a.b);c=$wnd.Math.abs(b.f-a.b);if(c<e){e=c;d=POb}c=$wnd.Math.abs(a.a);if(c<e){e=c;d=QOb}c=$wnd.Math.abs(b.g-a.a);if(c<e){e=c;d=NOb}return d} +function L9b(a,b){var c,d,e,f;c=b.a.o.a;f=new Jib(Q_b(b.a).b,b.c,b.f+1);for(e=new vib(f);e.b<e.d.gc();){d=(sCb(e.b<e.d.gc()),BD(e.d.Xb(e.c=e.b++),29));if(d.c.a>=c){K9b(a,b,d.p);return true}}return false} +function Iod(a){var b;if((a.Db&64)!=0)return fld(a);b=new Wfb(dte);!a.a||Qfb(Qfb((b.a+=' "',b),a.a),'"');Qfb(Lfb(Qfb(Lfb(Qfb(Lfb(Qfb(Lfb((b.a+=' (',b),a.i),','),a.j),' | '),a.g),','),a.f),')');return b.a} +function Z2d(a,b,c){var d,e,f,g,h;h=S6d(a.e.Tg(),b);e=BD(a.g,119);d=0;for(g=0;g<a.i;++g){f=e[g];if(h.rl(f.ak())){if(d==c){Xxd(a,g);return Q6d(),BD(b,66).Oj()?f:f.dd()}++d}}throw vbb(new qcb(gve+c+mue+d))} +function sde(a){var b,c,d;b=a.c;if(b==2||b==7||b==1){return wfe(),wfe(),ffe}else{d=qde(a);c=null;while((b=a.c)!=2&&b!=7&&b!=1){if(!c){c=(wfe(),wfe(),++vfe,new Lge(1));Kge(c,d);d=c}Kge(c,qde(a))}return d}} +function Kb(a,b,c){if(a<0||a>c){return Jb(a,c,'start index')}if(b<0||b>c){return Jb(b,c,'end index')}return hc('end index (%s) must not be less than start index (%s)',OC(GC(SI,1),Uhe,1,5,[meb(b),meb(a)]))} +function Pz(b,c){var d,e,f,g;for(e=0,f=b.length;e<f;e++){g=b[e];try{g[1]?g[0].jm()&&(c=Oz(c,g)):g[0].jm()}catch(a){a=ubb(a);if(JD(a,78)){d=a;Az();Gz(JD(d,477)?BD(d,477).ae():d)}else throw vbb(a)}}return c} +function K9b(a,b,c){var d,e,f;c!=b.c+b.b.gc()&&Z9b(b.a,fac(b,c-b.c));f=b.a.c.p;a.a[f]=$wnd.Math.max(a.a[f],b.a.o.a);for(e=BD(vNb(b.a,(wtc(),ktc)),15).Kc();e.Ob();){d=BD(e.Pb(),70);yNb(d,H9b,(Bcb(),true))}} +function Wec(a,b){var c,d,e;e=Vec(b);yNb(b,(wtc(),Xsc),e);if(e){d=Ohe;!!irb(a.f,e)&&(d=BD(Wd(irb(a.f,e)),19).a);c=BD(Ikb(b.g,0),17);Ccb(DD(vNb(c,ltc)))||Rhb(a,e,meb($wnd.Math.min(BD(vNb(c,Zsc),19).a,d)))}} +function iCc(a,b,c){var d,e,f,g,h;b.p=-1;for(h=W_b(b,(KAc(),IAc)).Kc();h.Ob();){g=BD(h.Pb(),11);for(e=new olb(g.g);e.a<e.c.c.length;){d=BD(mlb(e),17);f=d.d.i;b!=f&&(f.p<0?c.Fc(d):f.p>0&&iCc(a,f,c))}}b.p=0} +function p5c(a){var b;this.c=new Psb;this.f=a.e;this.e=a.d;this.i=a.g;this.d=a.c;this.b=a.b;this.k=a.j;this.a=a.a;!a.i?(this.j=(b=BD(gdb(e1),9),new xqb(b,BD(_Bb(b,b.length),9),0))):(this.j=a.i);this.g=a.f} +function Wb(a){var b,c,d,e;b=Kfb(Qfb(new Wfb('Predicates.'),'and'),40);c=true;for(e=new vib(a);e.b<e.d.gc();){d=(sCb(e.b<e.d.gc()),e.d.Xb(e.c=e.b++));c||(b.a+=',',b);b.a+=''+d;c=false}return (b.a+=')',b).a} +function Rcc(a,b,c){var d,e,f;if(c<=b+2){return}e=(c-b)/2|0;for(d=0;d<e;++d){f=(tCb(b+d,a.c.length),BD(a.c[b+d],11));Nkb(a,b+d,(tCb(c-d-1,a.c.length),BD(a.c[c-d-1],11)));tCb(c-d-1,a.c.length);a.c[c-d-1]=f}} +function hjc(a,b,c){var d,e,f,g,h,i,j,k;f=a.d.p;h=f.e;i=f.r;a.g=new dIc(i);g=a.d.o.c.p;d=g>0?h[g-1]:KC(OQ,kne,10,0,0,1);e=h[g];j=g<h.length-1?h[g+1]:KC(OQ,kne,10,0,0,1);k=b==c-1;k?RHc(a.g,e,j):RHc(a.g,d,e)} +function pjc(a){var b;this.j=new Rkb;this.f=new Tqb;this.b=(b=BD(gdb(F1),9),new xqb(b,BD(_Bb(b,b.length),9),0));this.d=KC(WD,oje,25,(Ucd(),OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd])).length,15,1);this.g=a} +function QVc(a,b){var c,d,e;if(b.c.length!=0){c=RVc(a,b);e=false;while(!c){AVc(a,b,true);e=true;c=RVc(a,b)}e&&AVc(a,b,false);d=dVc(b);!!a.b&&a.b.lg(d);a.a=PVc(a,(tCb(0,b.c.length),BD(b.c[0],33)));QVc(a,d)}} +function Cid(a,b){var c,d,e;d=XKd(a.Tg(),b);c=b-a.Ah();if(c<0){if(!d){throw vbb(new Wdb(mte+b+nte))}else if(d.Ij()){e=a.Yg(d);e>=0?a.Bh(e):vid(a,d)}else{throw vbb(new Wdb(ite+d.ne()+jte))}}else{eid(a,c,d)}} +function aqd(a){var b,c;c=null;b=false;if(JD(a,204)){b=true;c=BD(a,204).a}if(!b){if(JD(a,258)){b=true;c=''+BD(a,258).a}}if(!b){if(JD(a,483)){b=true;c=''+BD(a,483).a}}if(!b){throw vbb(new vcb(Ute))}return c} +function ORd(a,b){var c,d;if(a.f){while(b.Ob()){c=BD(b.Pb(),72);d=c.ak();if(JD(d,99)&&(BD(d,18).Bb&ote)!=0&&(!a.e||d.Gj()!=x2||d.aj()!=0)&&c.dd()!=null){b.Ub();return true}}return false}else{return b.Ob()}} +function QRd(a,b){var c,d;if(a.f){while(b.Sb()){c=BD(b.Ub(),72);d=c.ak();if(JD(d,99)&&(BD(d,18).Bb&ote)!=0&&(!a.e||d.Gj()!=x2||d.aj()!=0)&&c.dd()!=null){b.Pb();return true}}return false}else{return b.Sb()}} +function I2d(a,b,c){var d,e,f,g,h,i;i=S6d(a.e.Tg(),b);d=0;h=a.i;e=BD(a.g,119);for(g=0;g<a.i;++g){f=e[g];if(i.rl(f.ak())){if(c==d){return g}++d;h=g+1}}if(c==d){return h}else{throw vbb(new qcb(gve+c+mue+d))}} +function d9b(a,b){var c,d,e,f;if(a.f.c.length==0){return null}else{f=new I6c;for(d=new olb(a.f);d.a<d.c.c.length;){c=BD(mlb(d),70);e=c.o;f.b=$wnd.Math.max(f.b,e.a);f.a+=e.b}f.a+=(a.f.c.length-1)*b;return f}} +function QJc(a,b,c){var d,e,f;for(e=new Sr(ur(O_b(c).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);if(!(!OZb(d)&&!(!OZb(d)&&d.c.i.c==d.d.i.c))){continue}f=IJc(a,d,c,new vKc);f.c.length>1&&(b.c[b.c.length]=f,true)}} +function TJc(a){var b,c,d,e;c=new Psb;ye(c,a.o);d=new twb;while(c.b!=0){b=BD(c.b==0?null:(sCb(c.b!=0),Nsb(c,c.a.a)),508);e=KJc(a,b,true);e&&Ekb(d.a,b)}while(d.a.c.length!=0){b=BD(rwb(d),508);KJc(a,b,false)}} +function _5c(){_5c=ccb;$5c=new a6c(ole,0);T5c=new a6c('BOOLEAN',1);X5c=new a6c('INT',2);Z5c=new a6c('STRING',3);U5c=new a6c('DOUBLE',4);V5c=new a6c('ENUM',5);W5c=new a6c('ENUMSET',6);Y5c=new a6c('OBJECT',7)} +function H6c(a,b){var c,d,e,f,g;d=$wnd.Math.min(a.c,b.c);f=$wnd.Math.min(a.d,b.d);e=$wnd.Math.max(a.c+a.b,b.c+b.b);g=$wnd.Math.max(a.d+a.a,b.d+b.a);if(e<d){c=d;d=e;e=c}if(g<f){c=f;f=g;g=c}G6c(a,d,f,e-d,g-f)} +function O6d(){O6d=ccb;L6d=OC(GC(ZI,1),nie,2,6,[swe,twe,uwe,vwe,wwe,xwe,eue]);K6d=OC(GC(ZI,1),nie,2,6,[swe,'empty',twe,Qve,'elementOnly']);N6d=OC(GC(ZI,1),nie,2,6,[swe,'preserve','replace',ywe]);M6d=new y1d} +function Y$b(a,b,c){var d,e,f;if(b==c){return}d=b;do{P6c(a,d.c);e=d.e;if(e){f=d.d;O6c(a,f.b,f.d);P6c(a,e.n);d=Q_b(e)}}while(e);d=c;do{c7c(a,d.c);e=d.e;if(e){f=d.d;b7c(a,f.b,f.d);c7c(a,e.n);d=Q_b(e)}}while(e)} +function qic(a,b,c,d){var e,f,g,h,i;if(d.f.c+d.g.c==0){for(g=a.a[a.c],h=0,i=g.length;h<i;++h){f=g[h];Rhb(d,f,new zic(a,f,c))}}e=BD(Wd(irb(d.f,b)),663);e.b=0;e.c=e.f;e.c==0||Cic(BD(Ikb(e.a,e.b),287));return e} +function Apc(){Apc=ccb;wpc=new Bpc('MEDIAN_LAYER',0);ypc=new Bpc('TAIL_LAYER',1);vpc=new Bpc('HEAD_LAYER',2);xpc=new Bpc('SPACE_EFFICIENT_LAYER',3);zpc=new Bpc('WIDEST_LAYER',4);upc=new Bpc('CENTER_LAYER',5)} +function rJb(a){switch(a.g){case 0:case 1:case 2:return Ucd(),Acd;case 3:case 4:case 5:return Ucd(),Rcd;case 6:case 7:case 8:return Ucd(),Tcd;case 9:case 10:case 11:return Ucd(),zcd;default:return Ucd(),Scd;}} +function sKc(a,b){var c;if(a.c.length==0){return false}c=Lzc((tCb(0,a.c.length),BD(a.c[0],17)).c.i);FJc();if(c==(Izc(),Fzc)||c==Ezc){return true}return FAb(NAb(new YAb(null,new Kub(a,16)),new AKc),new CKc(b))} +function cRc(a,b,c){var d,e,f;if(!a.b[b.g]){a.b[b.g]=true;d=c;!d&&(d=new SRc);Dsb(d.b,b);for(f=a.a[b.g].Kc();f.Ob();){e=BD(f.Pb(),188);e.b!=b&&cRc(a,e.b,d);e.c!=b&&cRc(a,e.c,d);Dsb(d.a,e)}return d}return null} +function qSc(){qSc=ccb;pSc=new rSc('ROOT_PROC',0);lSc=new rSc('FAN_PROC',1);nSc=new rSc('NEIGHBORS_PROC',2);mSc=new rSc('LEVEL_HEIGHT',3);oSc=new rSc('NODE_POSITION_PROC',4);kSc=new rSc('DETREEIFYING_PROC',5)} +function kqd(a,b){if(JD(b,239)){return eqd(a,BD(b,33))}else if(JD(b,186)){return fqd(a,BD(b,118))}else if(JD(b,439)){return dqd(a,BD(b,202))}else{throw vbb(new Wdb(Xte+Fe(new amb(OC(GC(SI,1),Uhe,1,5,[b])))))}} +function xu(a,b,c){var d,e;this.f=a;d=BD(Ohb(a.b,b),283);e=!d?0:d.a;Sb(c,e);if(c>=(e/2|0)){this.e=!d?null:d.c;this.d=e;while(c++<e){vu(this)}}else{this.c=!d?null:d.b;while(c-->0){uu(this)}}this.b=b;this.a=null} +function rEb(a,b){var c,d;b.a?sEb(a,b):(c=BD(Exb(a.b,b.b),57),!!c&&c==a.a[b.b.f]&&!!c.a&&c.a!=b.b.a&&c.c.Fc(b.b),d=BD(Dxb(a.b,b.b),57),!!d&&a.a[d.f]==b.b&&!!d.a&&d.a!=b.b.a&&b.b.c.Fc(d),Fxb(a.b,b.b),undefined)} +function FJb(a,b){var c,d;c=BD(Mpb(a.b,b),124);if(BD(BD(Qc(a.r,b),21),84).dc()){c.n.b=0;c.n.c=0;return}c.n.b=a.C.b;c.n.c=a.C.c;a.A.Hc((tdd(),sdd))&&KJb(a,b);d=JJb(a,b);KIb(a,b)==(Tbd(),Qbd)&&(d+=2*a.w);c.a.a=d} +function OKb(a,b){var c,d;c=BD(Mpb(a.b,b),124);if(BD(BD(Qc(a.r,b),21),84).dc()){c.n.d=0;c.n.a=0;return}c.n.d=a.C.d;c.n.a=a.C.a;a.A.Hc((tdd(),sdd))&&SKb(a,b);d=RKb(a,b);KIb(a,b)==(Tbd(),Qbd)&&(d+=2*a.w);c.a.b=d} +function cOb(a,b){var c,d,e,f;f=new Rkb;for(d=new olb(b);d.a<d.c.c.length;){c=BD(mlb(d),65);Ekb(f,new oOb(c,true));Ekb(f,new oOb(c,false))}e=new hOb(a);zwb(e.a.a);kDb(f,a.b,new amb(OC(GC(JM,1),Uhe,679,0,[e])))} +function rQb(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q;i=a.a;n=a.b;j=b.a;o=b.b;k=c.a;p=c.b;l=d.a;q=d.b;f=i*o-n*j;g=k*q-p*l;e=(i-j)*(p-q)-(n-o)*(k-l);h=(f*(k-l)-g*(i-j))/e;m=(f*(p-q)-g*(n-o))/e;return new f7c(h,m)} +function TBc(a,b){var c,d,e;if(a.d[b.p]){return}a.d[b.p]=true;a.a[b.p]=true;for(d=new Sr(ur(U_b(b).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);if(OZb(c)){continue}e=c.d.i;a.a[e.p]?Ekb(a.b,c):TBc(a,e)}a.a[b.p]=false} +function pCc(a,b,c){var d;d=0;switch(BD(vNb(b,(Nyc(),mxc)),163).g){case 2:d=2*-c+a.a;++a.a;break;case 1:d=-c;break;case 3:d=c;break;case 4:d=2*c+a.b;++a.b;}wNb(b,(wtc(),Zsc))&&(d+=BD(vNb(b,Zsc),19).a);return d} +function jOc(a,b,c){var d,e,f;c.zc(b,a);Ekb(a.n,b);f=a.p.eg(b);b.j==a.p.fg()?yOc(a.e,f):yOc(a.j,f);lOc(a);for(e=ul(pl(OC(GC(KI,1),Uhe,20,0,[new J0b(b),new R0b(b)])));Qr(e);){d=BD(Rr(e),11);c._b(d)||jOc(a,d,c)}} +function rfd(a){var b,c,d;c=BD(hkd(a,(Y9c(),Y8c)),21);if(c.Hc((tdd(),pdd))){d=BD(hkd(a,b9c),21);b=new g7c(BD(hkd(a,_8c),8));if(d.Hc((Idd(),Bdd))){b.a<=0&&(b.a=20);b.b<=0&&(b.b=20)}return b}else{return new d7c}} +function PKd(a){var b,c,d;if(!a.b){d=new $Nd;for(c=new $yd(SKd(a));c.e!=c.i.gc();){b=BD(Zyd(c),18);(b.Bb&ote)!=0&&wtd(d,b)}vud(d);a.b=new nNd((BD(qud(ZKd((NFd(),MFd).o),8),18),d.i),d.g);$Kd(a).b&=-9}return a.b} +function Rmc(a,b){var c,d,e,f,g,h,i,j;i=BD(Ee(Ec(b.k),KC(F1,bne,61,2,0,1)),122);j=b.g;c=Tmc(b,i[0]);e=Smc(b,i[1]);d=Kmc(a,j,c,e);f=Tmc(b,i[1]);h=Smc(b,i[0]);g=Kmc(a,j,f,h);if(d<=g){b.a=c;b.c=e}else{b.a=f;b.c=h}} +function ESc(a,b,c){var d,e,f;Odd(c,'Processor set neighbors',1);a.a=b.b.b==0?1:b.b.b;e=null;d=Jsb(b.b,0);while(!e&&d.b!=d.d.c){f=BD(Xsb(d),86);Ccb(DD(vNb(f,(mTc(),jTc))))&&(e=f)}!!e&&FSc(a,new ZRc(e),c);Qdd(c)} +function PEd(a){IEd();var b,c,d,e;d=hfb(a,wfb(35));b=d==-1?a:a.substr(0,d);c=d==-1?null:a.substr(d+1);e=kFd(HEd,b);if(!e){e=aFd(b);lFd(HEd,b,e);c!=null&&(e=JEd(e,c))}else c!=null&&(e=JEd(e,(uCb(c),c)));return e} +function smb(a){var h;mmb();var b,c,d,e,f,g;if(JD(a,54)){for(e=0,d=a.gc()-1;e<d;++e,--d){h=a.Xb(e);a._c(e,a.Xb(d));a._c(d,h)}}else{b=a.Yc();f=a.Zc(a.gc());while(b.Tb()<f.Vb()){c=b.Pb();g=f.Ub();b.Wb(g);f.Wb(c)}}} +function I3b(a,b){var c,d,e;Odd(b,'End label pre-processing',1);c=Edb(ED(vNb(a,(Nyc(),nyc))));d=Edb(ED(vNb(a,ryc)));e=gad(BD(vNb(a,Lwc),103));MAb(LAb(new YAb(null,new Kub(a.b,16)),new Q3b),new S3b(c,d,e));Qdd(b)} +function NFc(a,b){var c,d,e,f,g,h;h=0;f=new jkb;Wjb(f,b);while(f.b!=f.c){g=BD(fkb(f),214);h+=pHc(g.d,g.e);for(e=new olb(g.b);e.a<e.c.c.length;){d=BD(mlb(e),37);c=BD(Ikb(a.b,d.p),214);c.s||(h+=NFc(a,c))}}return h} +function YQc(a,b,c){var d,e;TQc(this);b==(FQc(),DQc)?Qqb(this.r,a.c):Qqb(this.w,a.c);c==DQc?Qqb(this.r,a.d):Qqb(this.w,a.d);UQc(this,a);d=VQc(a.c);e=VQc(a.d);XQc(this,d,e,e);this.o=(hQc(),$wnd.Math.abs(d-e)<0.2)} +function a0d(a,b,c){var d,e,f,g,h,i;h=BD(Ajd(a.a,8),1936);if(h!=null){for(e=h,f=0,g=e.length;f<g;++f){null.jm()}}d=c;if((a.a.Db&1)==0){i=new f0d(a,c,b);d.ui(i)}JD(d,672)?BD(d,672).wi(a.a):d.ti()==a.a&&d.vi(null)} +function dae(){var a;if(Z9d)return BD(nUd((yFd(),xFd),Ewe),1945);eae();a=BD(JD(Phb((yFd(),xFd),Ewe),586)?Phb(xFd,Ewe):new cae,586);Z9d=true;aae(a);bae(a);Rhb((JFd(),IFd),a,new fae);Tnd(a);Shb(xFd,Ewe,a);return a} +function xA(a,b,c,d){var e;e=oA(a,c,OC(GC(ZI,1),nie,2,6,[rje,sje,tje,uje,vje,wje,xje]),b);e<0&&(e=oA(a,c,OC(GC(ZI,1),nie,2,6,['Sun','Mon','Tue','Wed','Thu','Fri','Sat']),b));if(e<0){return false}d.d=e;return true} +function AA(a,b,c,d){var e;e=oA(a,c,OC(GC(ZI,1),nie,2,6,[rje,sje,tje,uje,vje,wje,xje]),b);e<0&&(e=oA(a,c,OC(GC(ZI,1),nie,2,6,['Sun','Mon','Tue','Wed','Thu','Fri','Sat']),b));if(e<0){return false}d.d=e;return true} +function NVb(a){var b,c,d;KVb(a);d=new Rkb;for(c=new olb(a.a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),81);Ekb(d,new ZVb(b,true));Ekb(d,new ZVb(b,false))}RVb(a.c);rXb(d,a.b,new amb(OC(GC(bQ,1),Uhe,369,0,[a.c])));MVb(a)} +function c4b(a){var b,c,d,e;c=new Lqb;for(e=new olb(a.d);e.a<e.c.c.length;){d=BD(mlb(e),181);b=BD(d.We((wtc(),Dsc)),17);!!irb(c.f,b)||Rhb(c,b,new p4b(b));Ekb(BD(Wd(irb(c.f,b)),456).b,d)}return new Tkb(new $ib(c))} +function Gac(a,b){var c,d,e,f,g;d=new kkb(a.j.c.length);c=null;for(f=new olb(a.j);f.a<f.c.c.length;){e=BD(mlb(f),11);if(e.j!=c){d.b==d.c||Hac(d,c,b);Yjb(d);c=e.j}g=N3b(e);!!g&&(Xjb(d,g),true)}d.b==d.c||Hac(d,c,b)} +function wbc(a,b){var c,d,e;d=new Bib(a.b,0);while(d.b<d.d.gc()){c=(sCb(d.b<d.d.gc()),BD(d.d.Xb(d.c=d.b++),70));e=BD(vNb(c,(Nyc(),Qwc)),272);if(e==(qad(),oad)){uib(d);Ekb(b.b,c);wNb(c,(wtc(),Dsc))||yNb(c,Dsc,a)}}} +function GDc(a){var b,c,d,e,f;b=sr(new Sr(ur(U_b(a).a.Kc(),new Sq)));for(e=new Sr(ur(R_b(a).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);c=d.c.i;f=sr(new Sr(ur(U_b(c).a.Kc(),new Sq)));b=$wnd.Math.max(b,f)}return meb(b)} +function rUc(a,b,c){var d,e,f,g;Odd(c,'Processor arrange node',1);e=null;f=new Psb;d=Jsb(b.b,0);while(!e&&d.b!=d.d.c){g=BD(Xsb(d),86);Ccb(DD(vNb(g,(mTc(),jTc))))&&(e=g)}Gsb(f,e,f.c.b,f.c);qUc(a,f,Udd(c,1));Qdd(c)} +function Ffd(a,b,c){var d,e,f;d=BD(hkd(a,(Y9c(),w8c)),21);e=0;f=0;b.a>c.a&&(d.Hc((i8c(),c8c))?(e=(b.a-c.a)/2):d.Hc(e8c)&&(e=b.a-c.a));b.b>c.b&&(d.Hc((i8c(),g8c))?(f=(b.b-c.b)/2):d.Hc(f8c)&&(f=b.b-c.b));Efd(a,e,f)} +function aod(a,b,c,d,e,f,g,h,i,j,k,l,m){JD(a.Cb,88)&&XMd($Kd(BD(a.Cb,88)),4);pnd(a,c);a.f=g;dJd(a,h);fJd(a,i);ZId(a,j);eJd(a,k);CId(a,l);aJd(a,m);BId(a,true);AId(a,e);a.ok(f);yId(a,b);d!=null&&(a.i=null,_Id(a,d))} +function PRd(a){var b,c;if(a.f){while(a.n>0){b=BD(a.k.Xb(a.n-1),72);c=b.ak();if(JD(c,99)&&(BD(c,18).Bb&ote)!=0&&(!a.e||c.Gj()!=x2||c.aj()!=0)&&b.dd()!=null){return true}else{--a.n}}return false}else{return a.n>0}} +function Jb(a,b,c){if(a<0){return hc(The,OC(GC(SI,1),Uhe,1,5,[c,meb(a)]))}else if(b<0){throw vbb(new Wdb(Vhe+b))}else{return hc('%s (%s) must not be greater than size (%s)',OC(GC(SI,1),Uhe,1,5,[c,meb(a),meb(b)]))}} +function Llb(a,b,c,d,e,f){var g,h,i,j;g=d-c;if(g<7){Ilb(b,c,d,f);return}i=c+e;h=d+e;j=i+(h-i>>1);Llb(b,a,i,j,-e,f);Llb(b,a,j,h,-e,f);if(f.ue(a[j-1],a[j])<=0){while(c<d){NC(b,c++,a[i++])}return}Jlb(a,i,j,h,b,c,d,f)} +function nEb(a,b){var c,d,e;e=new Rkb;for(d=new olb(a.c.a.b);d.a<d.c.c.length;){c=BD(mlb(d),57);if(b.Lb(c)){Ekb(e,new BEb(c,true));Ekb(e,new BEb(c,false))}}tEb(a.e);kDb(e,a.d,new amb(OC(GC(JM,1),Uhe,679,0,[a.e])))} +function gnc(a,b){var c,d,e,f,g,h,i;i=b.d;e=b.b.j;for(h=new olb(i);h.a<h.c.c.length;){g=BD(mlb(h),101);f=KC(sbb,dle,25,e.c.length,16,1);Rhb(a.b,g,f);c=g.a.d.p-1;d=g.c.d.p;while(c!=d){c=(c+1)%e.c.length;f[c]=true}}} +function tOc(a,b){a.r=new uOc(a.p);sOc(a.r,a);ye(a.r.j,a.j);Osb(a.j);Dsb(a.j,b);Dsb(a.r.e,b);lOc(a);lOc(a.r);while(a.f.c.length!=0){AOc(BD(Ikb(a.f,0),129))}while(a.k.c.length!=0){AOc(BD(Ikb(a.k,0),129))}return a.r} +function yid(a,b,c){var d,e,f;e=XKd(a.Tg(),b);d=b-a.Ah();if(d<0){if(!e){throw vbb(new Wdb(mte+b+nte))}else if(e.Ij()){f=a.Yg(e);f>=0?a.sh(f,c):uid(a,e,c)}else{throw vbb(new Wdb(ite+e.ne()+jte))}}else{did(a,d,e,c)}} +function q6d(b){var c,d,e,f;d=BD(b,49).qh();if(d){try{e=null;c=nUd((yFd(),xFd),LEd(MEd(d)));if(c){f=c.rh();!!f&&(e=f.Wk(tfb(d.e)))}if(!!e&&e!=b){return q6d(e)}}catch(a){a=ubb(a);if(!JD(a,60))throw vbb(a)}}return b} +function jrb(a,b,c){var d,e,f,g;g=b==null?0:a.b.se(b);e=(d=a.a.get(g),d==null?new Array:d);if(e.length==0){a.a.set(g,e)}else{f=grb(a,b,e);if(f){return f.ed(c)}}NC(e,e.length,new pjb(b,c));++a.c;zpb(a.b);return null} +function YUc(a,b){var c,d;H2c(a.a);K2c(a.a,(PUc(),NUc),NUc);K2c(a.a,OUc,OUc);d=new j3c;e3c(d,OUc,(tVc(),sVc));PD(hkd(b,(ZWc(),LWc)))!==PD((pWc(),mWc))&&e3c(d,OUc,qVc);e3c(d,OUc,rVc);E2c(a.a,d);c=F2c(a.a,b);return c} +function uC(a){if(!a){return OB(),NB}var b=a.valueOf?a.valueOf():a;if(b!==a){var c=qC[typeof b];return c?c(b):xC(typeof b)}else if(a instanceof Array||a instanceof $wnd.Array){return new xB(a)}else{return new fC(a)}} +function RJb(a,b,c){var d,e,f;f=a.o;d=BD(Mpb(a.p,c),244);e=d.i;e.b=gIb(d);e.a=fIb(d);e.b=$wnd.Math.max(e.b,f.a);e.b>f.a&&!b&&(e.b=f.a);e.c=-(e.b-f.a)/2;switch(c.g){case 1:e.d=-e.a;break;case 3:e.d=f.b;}hIb(d);iIb(d)} +function SJb(a,b,c){var d,e,f;f=a.o;d=BD(Mpb(a.p,c),244);e=d.i;e.b=gIb(d);e.a=fIb(d);e.a=$wnd.Math.max(e.a,f.b);e.a>f.b&&!b&&(e.a=f.b);e.d=-(e.a-f.b)/2;switch(c.g){case 4:e.c=-e.b;break;case 2:e.c=f.a;}hIb(d);iIb(d)} +function Jgc(a,b){var c,d,e,f,g;if(b.dc()){return}e=BD(b.Xb(0),128);if(b.gc()==1){Igc(a,e,e,1,0,b);return}c=1;while(c<b.gc()){if(e.j||!e.o){f=Ogc(b,c);if(f){d=BD(f.a,19).a;g=BD(f.b,128);Igc(a,e,g,c,d,b);c=d+1;e=g}}}} +function mlc(a){var b,c,d,e,f,g;g=new Tkb(a.d);Okb(g,new Qlc);b=(Alc(),OC(GC(KV,1),Kie,270,0,[tlc,wlc,slc,zlc,vlc,ulc,ylc,xlc]));c=0;for(f=new olb(g);f.a<f.c.c.length;){e=BD(mlb(f),101);d=b[c%b.length];olc(e,d);++c}} +function o6c(a,b){i6c();var c,d,e,f;if(b.b<2){return false}f=Jsb(b,0);c=BD(Xsb(f),8);d=c;while(f.b!=f.d.c){e=BD(Xsb(f),8);if(!(m6c(a,d)&&m6c(a,e))){return false}d=e}if(!(m6c(a,d)&&m6c(a,c))){return false}return true} +function hrd(a,b){var c,d,e,f,g,h,i,j,k,l;k=null;l=a;g=Xpd(l,'x');c=new Krd(b);Gqd(c.a,g);h=Xpd(l,'y');d=new Lrd(b);Hqd(d.a,h);i=Xpd(l,Gte);e=new Mrd(b);Iqd(e.a,i);j=Xpd(l,Fte);f=new Nrd(b);k=(Jqd(f.a,j),j);return k} +function XMd(a,b){TMd(a,b);(a.b&1)!=0&&(a.a.a=null);(a.b&2)!=0&&(a.a.f=null);if((a.b&4)!=0){a.a.g=null;a.a.i=null}if((a.b&16)!=0){a.a.d=null;a.a.e=null}(a.b&8)!=0&&(a.a.b=null);if((a.b&32)!=0){a.a.j=null;a.a.c=null}} +function l0d(b,c){var d,e,f;f=0;if(c.length>0){try{f=Icb(c,Rie,Ohe)}catch(a){a=ubb(a);if(JD(a,127)){e=a;throw vbb(new rFd(e))}else throw vbb(a)}}d=(!b.a&&(b.a=new z0d(b)),b.a);return f<d.i&&f>=0?BD(qud(d,f),56):null} +function Ib(a,b){if(a<0){return hc(The,OC(GC(SI,1),Uhe,1,5,['index',meb(a)]))}else if(b<0){throw vbb(new Wdb(Vhe+b))}else{return hc('%s (%s) must be less than size (%s)',OC(GC(SI,1),Uhe,1,5,['index',meb(a),meb(b)]))}} +function Slb(a){var b,c,d,e,f;if(a==null){return Xhe}f=new xwb(She,'[',']');for(c=a,d=0,e=c.length;d<e;++d){b=c[d];!f.a?(f.a=new Wfb(f.d)):Qfb(f.a,f.b);Nfb(f.a,''+b)}return !f.a?f.c:f.e.length==0?f.a.a:f.a.a+(''+f.e)} +function Tlb(a){var b,c,d,e,f;if(a==null){return Xhe}f=new xwb(She,'[',']');for(c=a,d=0,e=c.length;d<e;++d){b=c[d];!f.a?(f.a=new Wfb(f.d)):Qfb(f.a,f.b);Nfb(f.a,''+b)}return !f.a?f.c:f.e.length==0?f.a.a:f.a.a+(''+f.e)} +function Ulb(a){var b,c,d,e,f;if(a==null){return Xhe}f=new xwb(She,'[',']');for(c=a,d=0,e=c.length;d<e;++d){b=c[d];!f.a?(f.a=new Wfb(f.d)):Qfb(f.a,f.b);Nfb(f.a,''+b)}return !f.a?f.c:f.e.length==0?f.a.a:f.a.a+(''+f.e)} +function Xlb(a){var b,c,d,e,f;if(a==null){return Xhe}f=new xwb(She,'[',']');for(c=a,d=0,e=c.length;d<e;++d){b=c[d];!f.a?(f.a=new Wfb(f.d)):Qfb(f.a,f.b);Nfb(f.a,''+b)}return !f.a?f.c:f.e.length==0?f.a.a:f.a.a+(''+f.e)} +function bub(a,b){var c,d,e,f,g,h;c=a.b.c.length;e=Ikb(a.b,b);while(b*2+1<c){d=(f=2*b+1,g=f+1,h=f,g<c&&a.a.ue(Ikb(a.b,g),Ikb(a.b,f))<0&&(h=g),h);if(a.a.ue(e,Ikb(a.b,d))<0){break}Nkb(a.b,b,Ikb(a.b,d));b=d}Nkb(a.b,b,e)} +function $Bb(a,b,c,d,e,f){var g,h,i,j,k;if(PD(a)===PD(c)){a=a.slice(b,b+e);b=0}i=c;for(h=b,j=b+e;h<j;){g=$wnd.Math.min(h+10000,j);e=g-h;k=a.slice(h,g);k.splice(0,0,d,f?e:0);Array.prototype.splice.apply(i,k);h=g;d+=e}} +function xGb(a,b,c){var d,e;d=c.d;e=c.e;if(a.g[d.d]<=a.i[b.d]&&a.i[b.d]<=a.i[d.d]&&a.g[e.d]<=a.i[b.d]&&a.i[b.d]<=a.i[e.d]){if(a.i[d.d]<a.i[e.d]){return false}return true}if(a.i[d.d]<a.i[e.d]){return true}return false} +function cRb(a){var b,c,d,e,f,g,h;d=a.a.c.length;if(d>0){g=a.c.d;h=a.d.d;e=Y6c(c7c(new f7c(h.a,h.b),g),1/(d+1));f=new f7c(g.a,g.b);for(c=new olb(a.a);c.a<c.c.c.length;){b=BD(mlb(c),559);b.d.a=f.a;b.d.b=f.b;P6c(f,e)}}} +function YNb(a,b,c){var d,e,f,g,h,i;i=Pje;for(f=new olb(wOb(a.b));f.a<f.c.c.length;){e=BD(mlb(f),168);for(h=new olb(wOb(b.b));h.a<h.c.c.length;){g=BD(mlb(h),168);d=p6c(e.a,e.b,g.a,g.b,c);i=$wnd.Math.min(i,d)}}return i} +function G0b(a,b){if(!b){throw vbb(new Geb)}a.j=b;if(!a.d){switch(a.j.g){case 1:a.a.a=a.o.a/2;a.a.b=0;break;case 2:a.a.a=a.o.a;a.a.b=a.o.b/2;break;case 3:a.a.a=a.o.a/2;a.a.b=a.o.b;break;case 4:a.a.a=0;a.a.b=a.o.b/2;}}} +function dfc(a,b){var c,d,e;if(JD(b.g,10)&&BD(b.g,10).k==(j0b(),e0b)){return Pje}e=ugc(b);if(e){return $wnd.Math.max(0,a.b/2-0.5)}c=tgc(b);if(c){d=Edb(ED(pBc(c,(Nyc(),vyc))));return $wnd.Math.max(0,d/2-0.5)}return Pje} +function ffc(a,b){var c,d,e;if(JD(b.g,10)&&BD(b.g,10).k==(j0b(),e0b)){return Pje}e=ugc(b);if(e){return $wnd.Math.max(0,a.b/2-0.5)}c=tgc(b);if(c){d=Edb(ED(pBc(c,(Nyc(),vyc))));return $wnd.Math.max(0,d/2-0.5)}return Pje} +function xic(a){var b,c,d,e,f,g;g=CHc(a.d,a.e);for(f=g.Kc();f.Ob();){e=BD(f.Pb(),11);d=a.e==(Ucd(),Tcd)?e.e:e.g;for(c=new olb(d);c.a<c.c.c.length;){b=BD(mlb(c),17);if(!OZb(b)&&b.c.i.c!=b.d.i.c){tic(a,b);++a.f;++a.c}}}} +function tpc(a,b){var c,d;if(b.dc()){return mmb(),mmb(),jmb}d=new Rkb;Ekb(d,meb(Rie));for(c=1;c<a.f;++c){a.a==null&&Toc(a);a.a[c]&&Ekb(d,meb(c))}if(d.c.length==1){return mmb(),mmb(),jmb}Ekb(d,meb(Ohe));return spc(b,d)} +function MJc(a,b){var c,d,e,f,g,h,i;g=b.c.i.k!=(j0b(),h0b);i=g?b.d:b.c;c=MZb(b,i).i;e=BD(Ohb(a.k,i),121);d=a.i[c.p].a;if(S_b(i.i)<(!c.c?-1:Jkb(c.c.a,c,0))){f=e;h=d}else{f=d;h=e}AFb(DFb(CFb(EFb(BFb(new FFb,0),4),f),h))} +function oqd(a,b,c){var d,e,f,g,h,i;if(c){e=c.a.length;d=new Yge(e);for(h=(d.b-d.a)*d.c<0?(Xge(),Wge):new she(d);h.Ob();){g=BD(h.Pb(),19);i=Wqd(a,Vpd(tB(c,g.a)));if(i){f=(!b.b&&(b.b=new y5d(z2,b,4,7)),b.b);wtd(f,i)}}}} +function pqd(a,b,c){var d,e,f,g,h,i;if(c){e=c.a.length;d=new Yge(e);for(h=(d.b-d.a)*d.c<0?(Xge(),Wge):new she(d);h.Ob();){g=BD(h.Pb(),19);i=Wqd(a,Vpd(tB(c,g.a)));if(i){f=(!b.c&&(b.c=new y5d(z2,b,5,8)),b.c);wtd(f,i)}}}} +function po(a,b,c){var d,e;d=b.a&a.f;b.b=a.b[d];a.b[d]=b;e=b.f&a.f;b.d=a.c[e];a.c[e]=b;if(!c){b.e=a.e;b.c=null;!a.e?(a.a=b):(a.e.c=b);a.e=b}else{b.e=c.e;!b.e?(a.a=b):(b.e.c=b);b.c=c.c;!b.c?(a.e=b):(b.c.e=b)}++a.i;++a.g} +function qr(a){var b,c,d;b=a.Pb();if(!a.Ob()){return b}d=Pfb(Qfb(new Ufb,'expected one element but was: <'),b);for(c=0;c<4&&a.Ob();c++){Pfb((d.a+=She,d),a.Pb())}a.Ob()&&(d.a+=', ...',d);d.a+='>';throw vbb(new Wdb(d.a))} +function lt(a,b){var c;b.d?(b.d.b=b.b):(a.a=b.b);b.b?(b.b.d=b.d):(a.e=b.d);if(!b.e&&!b.c){c=BD(Thb(a.b,b.a),283);c.a=0;++a.c}else{c=BD(Ohb(a.b,b.a),283);--c.a;!b.e?(c.b=b.c):(b.e.c=b.c);!b.c?(c.c=b.e):(b.c.e=b.e)}--a.d} +function OA(a){var b,c;c=-a.a;b=OC(GC(TD,1),$ie,25,15,[43,48,48,48,48]);if(c<0){b[0]=45;c=-c}b[1]=b[1]+((c/60|0)/10|0)&aje;b[2]=b[2]+(c/60|0)%10&aje;b[3]=b[3]+(c%60/10|0)&aje;b[4]=b[4]+c%10&aje;return zfb(b,0,b.length)} +function uRb(a,b,c){var d,e;d=b.d;e=c.d;while(d.a-e.a==0&&d.b-e.b==0){d.a+=Cub(a,26)*ike+Cub(a,27)*jke-0.5;d.b+=Cub(a,26)*ike+Cub(a,27)*jke-0.5;e.a+=Cub(a,26)*ike+Cub(a,27)*jke-0.5;e.b+=Cub(a,26)*ike+Cub(a,27)*jke-0.5}} +function N_b(a){var b,c,d,e;a.g=new Rpb(BD(Qb(F1),290));d=0;c=(Ucd(),Acd);b=0;for(;b<a.j.c.length;b++){e=BD(Ikb(a.j,b),11);if(e.j!=c){d!=b&&Npb(a.g,c,new vgd(meb(d),meb(b)));c=e.j;d=b}}Npb(a.g,c,new vgd(meb(d),meb(b)))} +function d4b(a){var b,c,d,e,f,g,h;d=0;for(c=new olb(a.b);c.a<c.c.c.length;){b=BD(mlb(c),29);for(f=new olb(b.a);f.a<f.c.c.length;){e=BD(mlb(f),10);e.p=d++;for(h=new olb(e.j);h.a<h.c.c.length;){g=BD(mlb(h),11);g.p=d++}}}} +function qPc(a,b,c,d,e){var f,g,h,i,j;if(b){for(h=b.Kc();h.Ob();){g=BD(h.Pb(),10);for(j=X_b(g,(KAc(),IAc),c).Kc();j.Ob();){i=BD(j.Pb(),11);f=BD(Wd(irb(e.f,i)),112);if(!f){f=new uOc(a.d);d.c[d.c.length]=f;jOc(f,i,e)}}}}} +function vid(a,b){var c,d,e;e=e1d((O6d(),M6d),a.Tg(),b);if(e){Q6d();BD(e,66).Oj()||(e=_1d(q1d(M6d,e)));d=(c=a.Yg(e),BD(c>=0?a._g(c,true,true):sid(a,e,true),153));BD(d,215).ol(b)}else{throw vbb(new Wdb(ite+b.ne()+jte))}} +function ugb(a){var b,c;if(a>-140737488355328&&a<140737488355328){if(a==0){return 0}b=a<0;b&&(a=-a);c=QD($wnd.Math.floor($wnd.Math.log(a)/0.6931471805599453));(!b||a!=$wnd.Math.pow(2,c))&&++c;return c}return vgb(Cbb(a))} +function QOc(a){var b,c,d,e,f,g,h;f=new zsb;for(c=new olb(a);c.a<c.c.c.length;){b=BD(mlb(c),129);g=b.a;h=b.b;if(f.a._b(g)||f.a._b(h)){continue}e=g;d=h;if(g.e.b+g.j.b>2&&h.e.b+h.j.b<=2){e=h;d=g}f.a.zc(e,f);e.q=d}return f} +function K5b(a,b){var c,d,e;d=new b0b(a);tNb(d,b);yNb(d,(wtc(),Gsc),b);yNb(d,(Nyc(),Vxc),(dcd(),$bd));yNb(d,mwc,(F7c(),B7c));__b(d,(j0b(),e0b));c=new H0b;F0b(c,d);G0b(c,(Ucd(),Tcd));e=new H0b;F0b(e,d);G0b(e,zcd);return d} +function Spc(a){switch(a.g){case 0:return new fGc((rGc(),oGc));case 1:return new CFc;case 2:return new fHc;default:throw vbb(new Wdb('No implementation is available for the crossing minimizer '+(a.f!=null?a.f:''+a.g)));}} +function tDc(a,b){var c,d,e,f,g;a.c[b.p]=true;Ekb(a.a,b);for(g=new olb(b.j);g.a<g.c.c.length;){f=BD(mlb(g),11);for(d=new b1b(f.b);llb(d.a)||llb(d.b);){c=BD(llb(d.a)?mlb(d.a):mlb(d.b),17);e=uDc(f,c).i;a.c[e.p]||tDc(a,e)}}} +function _Uc(a){var b,c,d,e,f,g,h;g=0;for(c=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));c.e!=c.i.gc();){b=BD(Dyd(c),33);h=b.g;e=b.f;d=$wnd.Math.sqrt(h*h+e*e);g=$wnd.Math.max(d,g);f=_Uc(b);g=$wnd.Math.max(f,g)}return g} +function rcd(){rcd=ccb;pcd=new scd('OUTSIDE',0);ncd=new scd('INSIDE',1);ocd=new scd('NEXT_TO_PORT_IF_POSSIBLE',2);mcd=new scd('ALWAYS_SAME_SIDE',3);lcd=new scd('ALWAYS_OTHER_SAME_SIDE',4);qcd=new scd('SPACE_EFFICIENT',5)} +function drd(a,b,c){var d,e,f,h,i,j;d=Tqd(a,(e=(Fhd(),f=new apd,f),!!c&&$od(e,c),e),b);Lkd(d,_pd(b,Vte));grd(b,d);brd(b,d);hrd(b,d);g=null;h=b;i=Ypd(h,'ports');j=new Jrd(a,d);Fqd(j.a,j.b,i);crd(a,b,d);Zqd(a,b,d);return d} +function NA(a){var b,c;c=-a.a;b=OC(GC(TD,1),$ie,25,15,[43,48,48,58,48,48]);if(c<0){b[0]=45;c=-c}b[1]=b[1]+((c/60|0)/10|0)&aje;b[2]=b[2]+(c/60|0)%10&aje;b[4]=b[4]+(c%60/10|0)&aje;b[5]=b[5]+c%10&aje;return zfb(b,0,b.length)} +function QA(a){var b;b=OC(GC(TD,1),$ie,25,15,[71,77,84,45,48,48,58,48,48]);if(a<=0){b[3]=43;a=-a}b[4]=b[4]+((a/60|0)/10|0)&aje;b[5]=b[5]+(a/60|0)%10&aje;b[7]=b[7]+(a%60/10|0)&aje;b[8]=b[8]+a%10&aje;return zfb(b,0,b.length)} +function Vlb(a){var b,c,d,e,f;if(a==null){return Xhe}f=new xwb(She,'[',']');for(c=a,d=0,e=c.length;d<e;++d){b=c[d];!f.a?(f.a=new Wfb(f.d)):Qfb(f.a,f.b);Nfb(f.a,''+Ubb(b))}return !f.a?f.c:f.e.length==0?f.a.a:f.a.a+(''+f.e)} +function DGb(a,b){var c,d,e;e=Ohe;for(d=new olb(LFb(b));d.a<d.c.c.length;){c=BD(mlb(d),213);if(c.f&&!a.c[c.c]){a.c[c.c]=true;e=$wnd.Math.min(e,DGb(a,xFb(c,b)))}}a.i[b.d]=a.j;a.g[b.d]=$wnd.Math.min(e,a.j++);return a.g[b.d]} +function EKb(a,b){var c,d,e;for(e=BD(BD(Qc(a.r,b),21),84).Kc();e.Ob();){d=BD(e.Pb(),111);d.e.b=(c=d.b,c.Xe((Y9c(),s9c))?c.Hf()==(Ucd(),Acd)?-c.rf().b-Edb(ED(c.We(s9c))):Edb(ED(c.We(s9c))):c.Hf()==(Ucd(),Acd)?-c.rf().b:0)}} +function LPb(a){var b,c,d,e,f,g,h;c=IOb(a.e);f=Y6c(b7c(R6c(HOb(a.e)),a.d*a.a,a.c*a.b),-0.5);b=c.a-f.a;e=c.b-f.b;for(h=0;h<a.c;h++){d=b;for(g=0;g<a.d;g++){JOb(a.e,new J6c(d,e,a.a,a.b))&&aNb(a,g,h,false,true);d+=a.a}e+=a.b}} +function s2c(a){var b,c,d;if(Ccb(DD(hkd(a,(Y9c(),M8c))))){d=new Rkb;for(c=new Sr(ur(_sd(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),79);Qld(b)&&Ccb(DD(hkd(b,N8c)))&&(d.c[d.c.length]=b,true)}return d}else{return mmb(),mmb(),jmb}} +function Vpd(a){var b,c;c=false;if(JD(a,204)){c=true;return BD(a,204).a}if(!c){if(JD(a,258)){b=BD(a,258).a%1==0;if(b){c=true;return meb(Idb(BD(a,258).a))}}}throw vbb(new cqd("Id must be a string or an integer: '"+a+"'."))} +function k0d(a,b){var c,d,e,f,g,h;f=null;for(e=new x0d((!a.a&&(a.a=new z0d(a)),a.a));u0d(e);){c=BD(Vud(e),56);d=(g=c.Tg(),h=(OKd(g),g.o),!h||!c.mh(h)?null:h6d(KJd(h),c.ah(h)));if(d!=null){if(dfb(d,b)){f=c;break}}}return f} +function Bw(a,b,c){var d,e,f,g,h;Xj(c,'occurrences');if(c==0){return h=BD(Hv(nd(a.a),b),14),!h?0:h.gc()}g=BD(Hv(nd(a.a),b),14);if(!g){return 0}f=g.gc();if(c>=f){g.$b()}else{e=g.Kc();for(d=0;d<c;d++){e.Pb();e.Qb()}}return f} +function ax(a,b,c){var d,e,f,g;Xj(c,'oldCount');Xj(0,'newCount');d=BD(Hv(nd(a.a),b),14);if((!d?0:d.gc())==c){Xj(0,'count');e=(f=BD(Hv(nd(a.a),b),14),!f?0:f.gc());g=-e;g>0?zh():g<0&&Bw(a,b,-g);return true}else{return false}} +function fIb(a){var b,c,d,e,f,g,h;h=0;if(a.b==0){g=jIb(a,true);b=0;for(d=g,e=0,f=d.length;e<f;++e){c=d[e];if(c>0){h+=c;++b}}b>1&&(h+=a.c*(b-1))}else{h=Mtb(Zzb(OAb(JAb(Plb(a.a),new xIb),new zIb)))}return h>0?h+a.n.d+a.n.a:0} +function gIb(a){var b,c,d,e,f,g,h;h=0;if(a.b==0){h=Mtb(Zzb(OAb(JAb(Plb(a.a),new tIb),new vIb)))}else{g=kIb(a,true);b=0;for(d=g,e=0,f=d.length;e<f;++e){c=d[e];if(c>0){h+=c;++b}}b>1&&(h+=a.c*(b-1))}return h>0?h+a.n.b+a.n.c:0} +function MJb(a,b){var c,d,e,f;f=BD(Mpb(a.b,b),124);c=f.a;for(e=BD(BD(Qc(a.r,b),21),84).Kc();e.Ob();){d=BD(e.Pb(),111);!!d.c&&(c.a=$wnd.Math.max(c.a,ZHb(d.c)))}if(c.a>0){switch(b.g){case 2:f.n.c=a.s;break;case 4:f.n.b=a.s;}}} +function NQb(a,b){var c,d,e;c=BD(vNb(b,(wSb(),oSb)),19).a-BD(vNb(a,oSb),19).a;if(c==0){d=c7c(R6c(BD(vNb(a,(HSb(),DSb)),8)),BD(vNb(a,ESb),8));e=c7c(R6c(BD(vNb(b,DSb),8)),BD(vNb(b,ESb),8));return Kdb(d.a*d.b,e.a*e.b)}return c} +function iRc(a,b){var c,d,e;c=BD(vNb(b,(JTc(),ETc)),19).a-BD(vNb(a,ETc),19).a;if(c==0){d=c7c(R6c(BD(vNb(a,(mTc(),VSc)),8)),BD(vNb(a,WSc),8));e=c7c(R6c(BD(vNb(b,VSc),8)),BD(vNb(b,WSc),8));return Kdb(d.a*d.b,e.a*e.b)}return c} +function TZb(a){var b,c;c=new Ufb;c.a+='e_';b=KZb(a);b!=null&&(c.a+=''+b,c);if(!!a.c&&!!a.d){Qfb((c.a+=' ',c),C0b(a.c));Qfb(Pfb((c.a+='[',c),a.c.i),']');Qfb((c.a+=gne,c),C0b(a.d));Qfb(Pfb((c.a+='[',c),a.d.i),']')}return c.a} +function zRc(a){switch(a.g){case 0:return new lUc;case 1:return new sUc;case 2:return new CUc;case 3:return new IUc;default:throw vbb(new Wdb('No implementation is available for the layout phase '+(a.f!=null?a.f:''+a.g)));}} +function mfd(a,b,c,d,e){var f;f=0;switch(e.g){case 1:f=$wnd.Math.max(0,b.b+a.b-(c.b+d));break;case 3:f=$wnd.Math.max(0,-a.b-d);break;case 2:f=$wnd.Math.max(0,-a.a-d);break;case 4:f=$wnd.Math.max(0,b.a+a.a-(c.a+d));}return f} +function mqd(a,b,c){var d,e,f,g,h;if(c){e=c.a.length;d=new Yge(e);for(h=(d.b-d.a)*d.c<0?(Xge(),Wge):new she(d);h.Ob();){g=BD(h.Pb(),19);f=Zpd(c,g.a);Lte in f.a||Mte in f.a?$qd(a,f,b):erd(a,f,b);otd(BD(Ohb(a.b,Wpd(f)),79))}}} +function LJd(a){var b,c;switch(a.b){case -1:{return true}case 0:{c=a.t;if(c>1||c==-1){a.b=-1;return true}else{b=wId(a);if(!!b&&(Q6d(),b.Cj()==Bve)){a.b=-1;return true}else{a.b=1;return false}}}default:case 1:{return false}}} +function k1d(a,b){var c,d,e,f,g;d=(!b.s&&(b.s=new cUd(t5,b,21,17)),b.s);f=null;for(e=0,g=d.i;e<g;++e){c=BD(qud(d,e),170);switch($1d(q1d(a,c))){case 2:case 3:{!f&&(f=new Rkb);f.c[f.c.length]=c}}}return !f?(mmb(),mmb(),jmb):f} +function tde(a,b){var c,d,e,f;nde(a);if(a.c!=0||a.a!=123)throw vbb(new mde(tvd((h0d(),Fue))));f=b==112;d=a.d;c=gfb(a.i,125,d);if(c<0)throw vbb(new mde(tvd((h0d(),Gue))));e=qfb(a.i,d,c);a.d=c+1;return Lfe(e,f,(a.e&512)==512)} +function QTb(a){var b;b=BD(vNb(a,(Nyc(),Iwc)),314);if(b==(Rpc(),Ppc)){throw vbb(new z2c('The hierarchy aware processor '+b+' in child node '+a+' is only allowed if the root node specifies the same hierarchical processor.'))}} +function dhc(a,b){Hgc();var c,d,e,f,g,h;c=null;for(g=b.Kc();g.Ob();){f=BD(g.Pb(),128);if(f.o){continue}d=F6c(f.a);e=C6c(f.a);h=new hic(d,e,null,BD(f.d.a.ec().Kc().Pb(),17));Ekb(h.c,f.a);a.c[a.c.length]=h;!!c&&Ekb(c.d,h);c=h}} +function hKd(a,b){var c,d,e;if(!b){jKd(a,null);_Jd(a,null)}else if((b.i&4)!=0){d='[]';for(c=b.c;;c=c.c){if((c.i&4)==0){e=jfb((fdb(c),c.o+d));jKd(a,e);_Jd(a,e);break}d+='[]'}}else{e=jfb((fdb(b),b.o));jKd(a,e);_Jd(a,e)}a.yk(b)} +function b3d(a,b,c,d,e){var f,g,h,i;i=a3d(a,BD(e,56));if(PD(i)!==PD(e)){h=BD(a.g[c],72);f=R6d(b,i);mud(a,c,t3d(a,c,f));if(oid(a.e)){g=H2d(a,9,f.ak(),e,i,d,false);Qwd(g,new pSd(a.e,9,a.c,h,f,d,false));Rwd(g)}return i}return e} +function xCc(a,b,c){var d,e,f,g,h,i;d=BD(Qc(a.c,b),15);e=BD(Qc(a.c,c),15);f=d.Zc(d.gc());g=e.Zc(e.gc());while(f.Sb()&&g.Sb()){h=BD(f.Ub(),19);i=BD(g.Ub(),19);if(h!=i){return beb(h.a,i.a)}}return !f.Ob()&&!g.Ob()?0:f.Ob()?1:-1} +function m5c(c,d){var e,f,g;try{g=fs(c.a,d);return g}catch(b){b=ubb(b);if(JD(b,32)){try{f=Icb(d,Rie,Ohe);e=gdb(c.a);if(f>=0&&f<e.length){return e[f]}}catch(a){a=ubb(a);if(!JD(a,127))throw vbb(a)}return null}else throw vbb(b)}} +function tid(a,b){var c,d,e;e=e1d((O6d(),M6d),a.Tg(),b);if(e){Q6d();BD(e,66).Oj()||(e=_1d(q1d(M6d,e)));d=(c=a.Yg(e),BD(c>=0?a._g(c,true,true):sid(a,e,true),153));return BD(d,215).ll(b)}else{throw vbb(new Wdb(ite+b.ne()+lte))}} +function BZd(){tZd();var a;if(sZd)return BD(nUd((yFd(),xFd),_ve),1939);rEd(CK,new J_d);CZd();a=BD(JD(Phb((yFd(),xFd),_ve),547)?Phb(xFd,_ve):new AZd,547);sZd=true;yZd(a);zZd(a);Rhb((JFd(),IFd),a,new EZd);Shb(xFd,_ve,a);return a} +function v2d(a,b){var c,d,e,f;a.j=-1;if(oid(a.e)){c=a.i;f=a.i!=0;lud(a,b);d=new pSd(a.e,3,a.c,null,b,c,f);e=b.Qk(a.e,a.c,null);e=h3d(a,b,e);if(!e){Uhd(a.e,d)}else{e.Ei(d);e.Fi()}}else{lud(a,b);e=b.Qk(a.e,a.c,null);!!e&&e.Fi()}} +function rA(a,b){var c,d,e;e=0;d=b[0];if(d>=a.length){return -1}c=(BCb(d,a.length),a.charCodeAt(d));while(c>=48&&c<=57){e=e*10+(c-48);++d;if(d>=a.length){break}c=(BCb(d,a.length),a.charCodeAt(d))}d>b[0]?(b[0]=d):(e=-1);return e} +function vMb(a){var b,c,d,e,f;e=BD(a.a,19).a;f=BD(a.b,19).a;c=e;d=f;b=$wnd.Math.max($wnd.Math.abs(e),$wnd.Math.abs(f));if(e<=0&&e==f){c=0;d=f-1}else{if(e==-b&&f!=b){c=f;d=e;f>=0&&++c}else{c=-f;d=e}}return new vgd(meb(c),meb(d))} +function fNb(a,b,c,d){var e,f,g,h,i,j;for(e=0;e<b.o;e++){f=e-b.j+c;for(g=0;g<b.p;g++){h=g-b.k+d;if((i=f,j=h,i+=a.j,j+=a.k,i>=0&&j>=0&&i<a.o&&j<a.p)&&(!ZMb(b,e,g)&&hNb(a,f,h)||YMb(b,e,g)&&!iNb(a,f,h))){return true}}}return false} +function LNc(a,b,c){var d,e,f,g,h;g=a.c;h=a.d;f=l7c(OC(GC(m1,1),nie,8,0,[g.i.n,g.n,g.a])).b;e=(f+l7c(OC(GC(m1,1),nie,8,0,[h.i.n,h.n,h.a])).b)/2;d=null;g.j==(Ucd(),zcd)?(d=new f7c(b+g.i.c.c.a+c,e)):(d=new f7c(b-c,e));St(a.a,0,d)} +function Qld(a){var b,c,d,e;b=null;for(d=ul(pl(OC(GC(KI,1),Uhe,20,0,[(!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c)])));Qr(d);){c=BD(Rr(d),82);e=atd(c);if(!b){b=e}else if(b!=e){return false}}return true} +function sud(a,b,c){var d;++a.j;if(b>=a.i)throw vbb(new qcb(lue+b+mue+a.i));if(c>=a.i)throw vbb(new qcb(nue+c+mue+a.i));d=a.g[c];if(b!=c){b<c?$fb(a.g,b,a.g,b+1,c-b):$fb(a.g,c+1,a.g,c,b-c);NC(a.g,b,d);a.ei(b,d,c);a.ci()}return d} +function Rc(a,b,c){var d;d=BD(a.c.xc(b),14);if(!d){d=a.ic(b);if(d.Fc(c)){++a.d;a.c.zc(b,d);return true}else{throw vbb(new ycb('New Collection violated the Collection spec'))}}else if(d.Fc(c)){++a.d;return true}else{return false}} +function heb(a){var b,c,d;if(a<0){return 0}else if(a==0){return 32}else{d=-(a>>16);b=d>>16&16;c=16-b;a=a>>b;d=a-256;b=d>>16&8;c+=b;a<<=b;d=a-Rje;b=d>>16&4;c+=b;a<<=b;d=a-oie;b=d>>16&2;c+=b;a<<=b;d=a>>14;b=d&~(d>>1);return c+2-b}} +function $Pb(a){QPb();var b,c,d,e;PPb=new Rkb;OPb=new Lqb;NPb=new Rkb;b=(!a.a&&(a.a=new cUd(E2,a,10,11)),a.a);SPb(b);for(e=new Fyd(b);e.e!=e.i.gc();){d=BD(Dyd(e),33);if(Jkb(PPb,d,0)==-1){c=new Rkb;Ekb(NPb,c);TPb(d,c)}}return NPb} +function BQb(a,b,c){var d,e,f,g;a.a=c.b.d;if(JD(b,352)){e=itd(BD(b,79),false,false);f=ofd(e);d=new FQb(a);reb(f,d);ifd(f,e);b.We((Y9c(),Q8c))!=null&&reb(BD(b.We(Q8c),74),d)}else{g=BD(b,470);g.Hg(g.Dg()+a.a.a);g.Ig(g.Eg()+a.a.b)}} +function _5b(a,b){var c,d,e,f,g,h,i,j;j=Edb(ED(vNb(b,(Nyc(),zyc))));i=a[0].n.a+a[0].o.a+a[0].d.c+j;for(h=1;h<a.length;h++){d=a[h].n;e=a[h].o;c=a[h].d;f=d.a-c.b-i;f<0&&(d.a-=f);g=b.f;g.a=$wnd.Math.max(g.a,d.a+e.a);i=d.a+e.a+c.c+j}} +function D$c(a,b){var c,d,e,f,g,h;d=BD(BD(Ohb(a.g,b.a),46).a,65);e=BD(BD(Ohb(a.g,b.b),46).a,65);f=d.b;g=e.b;c=z6c(f,g);if(c>=0){return c}h=U6c(c7c(new f7c(g.c+g.b/2,g.d+g.a/2),new f7c(f.c+f.b/2,f.d+f.a/2)));return -(xOb(f,g)-1)*h} +function ufd(a,b,c){var d;MAb(new YAb(null,(!c.a&&(c.a=new cUd(A2,c,6,6)),new Kub(c.a,16))),new Mfd(a,b));MAb(new YAb(null,(!c.n&&(c.n=new cUd(D2,c,1,7)),new Kub(c.n,16))),new Ofd(a,b));d=BD(hkd(c,(Y9c(),Q8c)),74);!!d&&p7c(d,a,b)} +function sid(a,b,c){var d,e,f;f=e1d((O6d(),M6d),a.Tg(),b);if(f){Q6d();BD(f,66).Oj()||(f=_1d(q1d(M6d,f)));e=(d=a.Yg(f),BD(d>=0?a._g(d,true,true):sid(a,f,true),153));return BD(e,215).hl(b,c)}else{throw vbb(new Wdb(ite+b.ne()+lte))}} +function wAd(a,b,c,d){var e,f,g,h,i;e=a.d[b];if(e){f=e.g;i=e.i;if(d!=null){for(h=0;h<i;++h){g=BD(f[h],133);if(g.Sh()==c&&pb(d,g.cd())){return g}}}else{for(h=0;h<i;++h){g=BD(f[h],133);if(PD(g.cd())===PD(d)){return g}}}}return null} +function Pgb(a,b){var c;if(b<0){throw vbb(new ocb('Negative exponent'))}if(b==0){return Cgb}else if(b==1||Kgb(a,Cgb)||Kgb(a,Ggb)){return a}if(!Sgb(a,0)){c=1;while(!Sgb(a,c)){++c}return Ogb(bhb(c*b),Pgb(Rgb(a,c),b))}return Jhb(a,b)} +function xlb(a,b){var c,d,e;if(PD(a)===PD(b)){return true}if(a==null||b==null){return false}if(a.length!=b.length){return false}for(c=0;c<a.length;++c){d=a[c];e=b[c];if(!(PD(d)===PD(e)||d!=null&&pb(d,e))){return false}}return true} +function CVb(a){nVb();var b,c,d;this.b=mVb;this.c=(ead(),cad);this.f=(iVb(),hVb);this.a=a;zVb(this,new DVb);sVb(this);for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),81);if(!c.d){b=new gVb(OC(GC(IP,1),Uhe,81,0,[c]));Ekb(a.a,b)}}} +function D3b(a,b,c){var d,e,f,g,h,i;if(!a||a.c.length==0){return null}f=new cIb(b,!c);for(e=new olb(a);e.a<e.c.c.length;){d=BD(mlb(e),70);UHb(f,(a$b(),new v$b(d)))}g=f.i;g.a=(i=f.n,f.e.b+i.d+i.a);g.b=(h=f.n,f.e.a+h.b+h.c);return f} +function O5b(a){var b,c,d,e,f,g,h;h=l_b(a.a);Nlb(h,new T5b);c=null;for(e=h,f=0,g=e.length;f<g;++f){d=e[f];if(d.k!=(j0b(),e0b)){break}b=BD(vNb(d,(wtc(),Hsc)),61);if(b!=(Ucd(),Tcd)&&b!=zcd){continue}!!c&&BD(vNb(c,Qsc),15).Fc(d);c=d}} +function YOc(a,b,c){var d,e,f,g,h,i,j;i=(tCb(b,a.c.length),BD(a.c[b],329));Kkb(a,b);if(i.b/2>=c){d=b;j=(i.c+i.a)/2;g=j-c;if(i.c<=j-c){e=new bPc(i.c,g);Dkb(a,d++,e)}h=j+c;if(h<=i.a){f=new bPc(h,i.a);wCb(d,a.c.length);aCb(a.c,d,f)}}} +function u0d(a){var b;if(!a.c&&a.g==null){a.d=a.si(a.f);wtd(a,a.d);b=a.d}else{if(a.g==null){return true}else if(a.i==0){return false}else{b=BD(a.g[a.i-1],47)}}if(b==a.b&&null.km>=null.jm()){Vud(a);return u0d(a)}else{return b.Ob()}} +function KTb(a,b,c){var d,e,f,g,h;h=c;!h&&(h=Ydd(new Zdd,0));Odd(h,Vme,1);aUb(a.c,b);g=EYb(a.a,b);if(g.gc()==1){MTb(BD(g.Xb(0),37),h)}else{f=1/g.gc();for(e=g.Kc();e.Ob();){d=BD(e.Pb(),37);MTb(d,Udd(h,f))}}CYb(a.a,g,b);NTb(b);Qdd(h)} +function qYb(a){this.a=a;if(a.c.i.k==(j0b(),e0b)){this.c=a.c;this.d=BD(vNb(a.c.i,(wtc(),Hsc)),61)}else if(a.d.i.k==e0b){this.c=a.d;this.d=BD(vNb(a.d.i,(wtc(),Hsc)),61)}else{throw vbb(new Wdb('Edge '+a+' is not an external edge.'))}} +function oQd(a,b){var c,d,e;e=a.b;a.b=b;(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,3,e,a.b));if(!b){pnd(a,null);qQd(a,0);pQd(a,null)}else if(b!=a){pnd(a,b.zb);qQd(a,b.d);c=(d=b.c,d==null?b.zb:d);pQd(a,c==null||dfb(c,b.zb)?null:c)}} +function NRd(a){var b,c;if(a.f){while(a.n<a.o){b=BD(!a.j?a.k.Xb(a.n):a.j.pi(a.n),72);c=b.ak();if(JD(c,99)&&(BD(c,18).Bb&ote)!=0&&(!a.e||c.Gj()!=x2||c.aj()!=0)&&b.dd()!=null){return true}else{++a.n}}return false}else{return a.n<a.o}} +function _i(a,b){var c;this.e=(im(),Qb(a),im(),nm(a));this.c=(Qb(b),nm(b));Lb(this.e.Hd().dc()==this.c.Hd().dc());this.d=Ev(this.e);this.b=Ev(this.c);c=IC(SI,[nie,Uhe],[5,1],5,[this.e.Hd().gc(),this.c.Hd().gc()],2);this.a=c;Ri(this)} +function vz(b){var c=(!tz&&(tz=wz()),tz);var d=b.replace(/[\x00-\x1f\xad\u0600-\u0603\u06dd\u070f\u17b4\u17b5\u200b-\u200f\u2028-\u202e\u2060-\u2064\u206a-\u206f\ufeff\ufff9-\ufffb"\\]/g,function(a){return uz(a,c)});return '"'+d+'"'} +function cEb(a){ODb();var b,c;this.b=LDb;this.c=NDb;this.g=(FDb(),EDb);this.d=(ead(),cad);this.a=a;RDb(this);for(c=new olb(a.b);c.a<c.c.c.length;){b=BD(mlb(c),57);!b.a&&pDb(rDb(new sDb,OC(GC(PM,1),Uhe,57,0,[b])),a);b.e=new K6c(b.d)}} +function HQb(a){var b,c,d,e,f,g;e=a.e.c.length;d=KC(yK,eme,15,e,0,1);for(g=new olb(a.e);g.a<g.c.c.length;){f=BD(mlb(g),144);d[f.b]=new Psb}for(c=new olb(a.c);c.a<c.c.c.length;){b=BD(mlb(c),282);d[b.c.b].Fc(b);d[b.d.b].Fc(b)}return d} +function fDc(a){var b,c,d,e,f,g,h;h=Pu(a.c.length);for(e=new olb(a);e.a<e.c.c.length;){d=BD(mlb(e),10);g=new Tqb;f=U_b(d);for(c=new Sr(ur(f.a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);b.c.i==b.d.i||Qqb(g,b.d.i)}h.c[h.c.length]=g}return h} +function ozd(a,b){var c,d,e,f,g;c=BD(Ajd(a.a,4),126);g=c==null?0:c.length;if(b>=g)throw vbb(new Cyd(b,g));e=c[b];if(g==1){d=null}else{d=KC($3,hve,415,g-1,0,1);$fb(c,0,d,0,b);f=g-b-1;f>0&&$fb(c,b+1,d,b,f)}b0d(a,d);a0d(a,b,e);return e} +function m8d(){m8d=ccb;k8d=BD(qud(ZKd((r8d(),q8d).qb),6),34);h8d=BD(qud(ZKd(q8d.qb),3),34);i8d=BD(qud(ZKd(q8d.qb),4),34);j8d=BD(qud(ZKd(q8d.qb),5),18);XId(k8d);XId(h8d);XId(i8d);XId(j8d);l8d=new amb(OC(GC(t5,1),Mve,170,0,[k8d,h8d]))} +function AJb(a,b){var c;this.d=new H_b;this.b=b;this.e=new g7c(b.qf());c=a.u.Hc((rcd(),ocd));a.u.Hc(ncd)?a.D?(this.a=c&&!b.If()):(this.a=true):a.u.Hc(pcd)?c?(this.a=!(b.zf().Kc().Ob()||b.Bf().Kc().Ob())):(this.a=false):(this.a=false)} +function IKb(a,b){var c,d,e,f;c=a.o.a;for(f=BD(BD(Qc(a.r,b),21),84).Kc();f.Ob();){e=BD(f.Pb(),111);e.e.a=(d=e.b,d.Xe((Y9c(),s9c))?d.Hf()==(Ucd(),Tcd)?-d.rf().a-Edb(ED(d.We(s9c))):c+Edb(ED(d.We(s9c))):d.Hf()==(Ucd(),Tcd)?-d.rf().a:c)}} +function Q1b(a,b){var c,d,e,f;c=BD(vNb(a,(Nyc(),Lwc)),103);f=BD(hkd(b,$xc),61);e=BD(vNb(a,Vxc),98);if(e!=(dcd(),bcd)&&e!=ccd){if(f==(Ucd(),Scd)){f=lfd(b,c);f==Scd&&(f=Zcd(c))}}else{d=M1b(b);d>0?(f=Zcd(c)):(f=Wcd(Zcd(c)))}jkd(b,$xc,f)} +function olc(a,b){var c,d,e,f,g;g=a.j;b.a!=b.b&&Okb(g,new Ulc);e=g.c.length/2|0;for(d=0;d<e;d++){f=(tCb(d,g.c.length),BD(g.c[d],113));f.c&&G0b(f.d,b.a)}for(c=e;c<g.c.length;c++){f=(tCb(c,g.c.length),BD(g.c[c],113));f.c&&G0b(f.d,b.b)}} +function TGc(a,b,c){var d,e,f;d=a.c[b.c.p][b.p];e=a.c[c.c.p][c.p];if(d.a!=null&&e.a!=null){f=Ddb(d.a,e.a);f<0?WGc(a,b,c):f>0&&WGc(a,c,b);return f}else if(d.a!=null){WGc(a,b,c);return -1}else if(e.a!=null){WGc(a,c,b);return 1}return 0} +function swd(a,b){var c,d,e,f;if(a.ej()){c=a.Vi();f=a.fj();++a.j;a.Hi(c,a.oi(c,b));d=a.Zi(3,null,b,c,f);if(a.bj()){e=a.cj(b,null);if(!e){a.$i(d)}else{e.Ei(d);e.Fi()}}else{a.$i(d)}}else{Bvd(a,b);if(a.bj()){e=a.cj(b,null);!!e&&e.Fi()}}} +function D2d(a,b){var c,d,e,f,g;g=S6d(a.e.Tg(),b);e=new yud;c=BD(a.g,119);for(f=a.i;--f>=0;){d=c[f];g.rl(d.ak())&&wtd(e,d)}!Yxd(a,e)&&oid(a.e)&&GLd(a,b.$j()?H2d(a,6,b,(mmb(),jmb),null,-1,false):H2d(a,b.Kj()?2:1,b,null,null,-1,false))} +function Dhb(){Dhb=ccb;var a,b;Bhb=KC(cJ,nie,91,32,0,1);Chb=KC(cJ,nie,91,32,0,1);a=1;for(b=0;b<=18;b++){Bhb[b]=ghb(a);Chb[b]=ghb(Nbb(a,b));a=Ibb(a,5)}for(;b<Chb.length;b++){Bhb[b]=Ogb(Bhb[b-1],Bhb[1]);Chb[b]=Ogb(Chb[b-1],(Hgb(),Egb))}} +function K4b(a,b){var c,d,e,f,g;if(a.a==(yrc(),wrc)){return true}f=b.a.c;c=b.a.c+b.a.b;if(b.j){d=b.A;g=d.c.c.a-d.o.a/2;e=f-(d.n.a+d.o.a);if(e>g){return false}}if(b.q){d=b.C;g=d.c.c.a-d.o.a/2;e=d.n.a-c;if(e>g){return false}}return true} +function wcc(a,b){var c;Odd(b,'Partition preprocessing',1);c=BD(GAb(JAb(LAb(JAb(new YAb(null,new Kub(a.a,16)),new Acc),new Ccc),new Ecc),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);MAb(c.Oc(),new Gcc);Qdd(b)} +function DMc(a){wMc();var b,c,d,e,f,g,h;c=new $rb;for(e=new olb(a.e.b);e.a<e.c.c.length;){d=BD(mlb(e),29);for(g=new olb(d.a);g.a<g.c.c.length;){f=BD(mlb(g),10);h=a.g[f.p];b=BD(Wrb(c,h),15);if(!b){b=new Rkb;Xrb(c,h,b)}b.Fc(f)}}return c} +function dRc(a,b){var c,d,e,f,g;e=b.b.b;a.a=KC(yK,eme,15,e,0,1);a.b=KC(sbb,dle,25,e,16,1);for(g=Jsb(b.b,0);g.b!=g.d.c;){f=BD(Xsb(g),86);a.a[f.g]=new Psb}for(d=Jsb(b.a,0);d.b!=d.d.c;){c=BD(Xsb(d),188);a.a[c.b.g].Fc(c);a.a[c.c.g].Fc(c)}} +function qmd(a){var b;if((a.Db&64)!=0)return Eid(a);b=new Jfb(Eid(a));b.a+=' (startX: ';Bfb(b,a.j);b.a+=', startY: ';Bfb(b,a.k);b.a+=', endX: ';Bfb(b,a.b);b.a+=', endY: ';Bfb(b,a.c);b.a+=', identifier: ';Efb(b,a.d);b.a+=')';return b.a} +function EId(a){var b;if((a.Db&64)!=0)return qnd(a);b=new Jfb(qnd(a));b.a+=' (ordered: ';Ffb(b,(a.Bb&256)!=0);b.a+=', unique: ';Ffb(b,(a.Bb&512)!=0);b.a+=', lowerBound: ';Cfb(b,a.s);b.a+=', upperBound: ';Cfb(b,a.t);b.a+=')';return b.a} +function Wnd(a,b,c,d,e,f,g,h){var i;JD(a.Cb,88)&&XMd($Kd(BD(a.Cb,88)),4);pnd(a,c);a.f=d;dJd(a,e);fJd(a,f);ZId(a,g);eJd(a,false);CId(a,true);aJd(a,h);BId(a,true);AId(a,0);a.b=0;DId(a,1);i=xId(a,b,null);!!i&&i.Fi();MJd(a,false);return a} +function fyb(a,b){var c,d,e,f;c=BD(Phb(a.a,b),512);if(!c){d=new wyb(b);e=(oyb(),lyb)?null:d.c;f=qfb(e,0,$wnd.Math.max(0,kfb(e,wfb(46))));vyb(d,fyb(a,f));(lyb?null:d.c).length==0&&qyb(d,new zyb);Shb(a.a,lyb?null:d.c,d);return d}return c} +function BOb(a,b){var c;a.b=b;a.g=new Rkb;c=COb(a.b);a.e=c;a.f=c;a.c=Ccb(DD(vNb(a.b,(fFb(),$Eb))));a.a=ED(vNb(a.b,(Y9c(),r8c)));a.a==null&&(a.a=1);Edb(a.a)>1?(a.e*=Edb(a.a)):(a.f/=Edb(a.a));DOb(a);EOb(a);AOb(a);yNb(a.b,(CPb(),uPb),a.g)} +function Y5b(a,b,c){var d,e,f,g,h,i;d=0;i=c;if(!b){d=c*(a.c.length-1);i*=-1}for(f=new olb(a);f.a<f.c.c.length;){e=BD(mlb(f),10);yNb(e,(Nyc(),mwc),(F7c(),B7c));e.o.a=d;for(h=Y_b(e,(Ucd(),zcd)).Kc();h.Ob();){g=BD(h.Pb(),11);g.n.a=d}d+=i}} +function Qxd(a,b,c){var d,e,f;if(a.ej()){f=a.fj();kud(a,b,c);d=a.Zi(3,null,c,b,f);if(a.bj()){e=a.cj(c,null);a.ij()&&(e=a.jj(c,e));if(!e){a.$i(d)}else{e.Ei(d);e.Fi()}}else{a.$i(d)}}else{kud(a,b,c);if(a.bj()){e=a.cj(c,null);!!e&&e.Fi()}}} +function ILd(a,b,c){var d,e,f,g,h,i;h=a.Gk(c);if(h!=c){g=a.g[b];i=h;mud(a,b,a.oi(b,i));f=g;a.gi(b,i,f);if(a.rk()){d=c;e=a.dj(d,null);!BD(h,49).eh()&&(e=a.cj(i,e));!!e&&e.Fi()}oid(a.e)&&GLd(a,a.Zi(9,c,h,b,false));return h}else{return c}} +function pVb(a,b){var c,d,e,f;for(d=new olb(a.a.a);d.a<d.c.c.length;){c=BD(mlb(d),189);c.g=true}for(f=new olb(a.a.b);f.a<f.c.c.length;){e=BD(mlb(f),81);e.k=Ccb(DD(a.e.Kb(new vgd(e,b))));e.d.g=e.d.g&Ccb(DD(a.e.Kb(new vgd(e,b))))}return a} +function pkc(a){var b,c,d,e,f;c=(b=BD(gdb(F1),9),new xqb(b,BD(_Bb(b,b.length),9),0));f=BD(vNb(a,(wtc(),gtc)),10);if(f){for(e=new olb(f.j);e.a<e.c.c.length;){d=BD(mlb(e),11);PD(vNb(d,$sc))===PD(a)&&a1b(new b1b(d.b))&&rqb(c,d.j)}}return c} +function zCc(a,b,c){var d,e,f,g,h;if(a.d[c.p]){return}for(e=new Sr(ur(U_b(c).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);h=d.d.i;for(g=new Sr(ur(R_b(h).a.Kc(),new Sq));Qr(g);){f=BD(Rr(g),17);f.c.i==b&&(a.a[f.p]=true)}zCc(a,b,h)}a.d[c.p]=true} +function Bjd(a,b){var c,d,e,f,g,h,i;d=aeb(a.Db&254);if(d==1){a.Eb=null}else{f=CD(a.Eb);if(d==2){e=zjd(a,b);a.Eb=f[e==0?1:0]}else{g=KC(SI,Uhe,1,d-1,5,1);for(c=2,h=0,i=0;c<=128;c<<=1){c==b?++h:(a.Db&c)!=0&&(g[i++]=f[h++])}a.Eb=g}}a.Db&=~b} +function n1d(a,b){var c,d,e,f,g;d=(!b.s&&(b.s=new cUd(t5,b,21,17)),b.s);f=null;for(e=0,g=d.i;e<g;++e){c=BD(qud(d,e),170);switch($1d(q1d(a,c))){case 4:case 5:case 6:{!f&&(f=new Rkb);f.c[f.c.length]=c;break}}}return !f?(mmb(),mmb(),jmb):f} +function Uee(a){var b;b=0;switch(a){case 105:b=2;break;case 109:b=8;break;case 115:b=4;break;case 120:b=16;break;case 117:b=32;break;case 119:b=64;break;case 70:b=256;break;case 72:b=128;break;case 88:b=512;break;case 44:b=zte;}return b} +function Ghb(a,b,c,d,e){var f,g,h,i;if(PD(a)===PD(b)&&d==e){Lhb(a,d,c);return}for(h=0;h<d;h++){g=0;f=a[h];for(i=0;i<e;i++){g=wbb(wbb(Ibb(xbb(f,Yje),xbb(b[i],Yje)),xbb(c[h+i],Yje)),xbb(Tbb(g),Yje));c[h+i]=Tbb(g);g=Pbb(g,32)}c[h+e]=Tbb(g)}} +function COb(a){var b,c,d,e,f,g,h,i,j,k,l;k=0;j=0;e=a.a;h=e.a.gc();for(d=e.a.ec().Kc();d.Ob();){c=BD(d.Pb(),561);b=(c.b&&LOb(c),c.a);l=b.a;g=b.b;k+=l+g;j+=l*g}i=$wnd.Math.sqrt(400*h*j-4*j+k*k)+k;f=2*(100*h-1);if(f==0){return i}return i/f} +function mOc(a,b){if(b.b!=0){isNaN(a.s)?(a.s=Edb((sCb(b.b!=0),ED(b.a.a.c)))):(a.s=$wnd.Math.min(a.s,Edb((sCb(b.b!=0),ED(b.a.a.c)))));isNaN(a.c)?(a.c=Edb((sCb(b.b!=0),ED(b.c.b.c)))):(a.c=$wnd.Math.max(a.c,Edb((sCb(b.b!=0),ED(b.c.b.c)))))}} +function Pld(a){var b,c,d,e;b=null;for(d=ul(pl(OC(GC(KI,1),Uhe,20,0,[(!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c)])));Qr(d);){c=BD(Rr(d),82);e=atd(c);if(!b){b=Xod(e)}else if(b!=Xod(e)){return true}}return false} +function Rxd(a,b){var c,d,e,f;if(a.ej()){c=a.i;f=a.fj();lud(a,b);d=a.Zi(3,null,b,c,f);if(a.bj()){e=a.cj(b,null);a.ij()&&(e=a.jj(b,e));if(!e){a.$i(d)}else{e.Ei(d);e.Fi()}}else{a.$i(d)}}else{lud(a,b);if(a.bj()){e=a.cj(b,null);!!e&&e.Fi()}}} +function rwd(a,b,c){var d,e,f;if(a.ej()){f=a.fj();++a.j;a.Hi(b,a.oi(b,c));d=a.Zi(3,null,c,b,f);if(a.bj()){e=a.cj(c,null);if(!e){a.$i(d)}else{e.Ei(d);e.Fi()}}else{a.$i(d)}}else{++a.j;a.Hi(b,a.oi(b,c));if(a.bj()){e=a.cj(c,null);!!e&&e.Fi()}}} +function Wee(a){var b,c,d,e;e=a.length;b=null;for(d=0;d<e;d++){c=(BCb(d,a.length),a.charCodeAt(d));if(hfb('.*+?{[()|\\^$',wfb(c))>=0){if(!b){b=new Ifb;d>0&&Efb(b,a.substr(0,d))}b.a+='\\';Afb(b,c&aje)}else !!b&&Afb(b,c&aje)}return b?b.a:a} +function l5c(a){var b;if(!a.a){throw vbb(new Zdb('IDataType class expected for layout option '+a.f))}b=gvd(a.a);if(b==null){throw vbb(new Zdb("Couldn't create new instance of property '"+a.f+"'. "+ise+(fdb(Y3),Y3.k)+jse))}return BD(b,414)} +function aid(a){var b,c,d,e,f;f=a.eh();if(f){if(f.kh()){e=xid(a,f);if(e!=f){c=a.Vg();d=(b=a.Vg(),b>=0?a.Qg(null):a.eh().ih(a,-1-b,null,null));a.Rg(BD(e,49),c);!!d&&d.Fi();a.Lg()&&a.Mg()&&c>-1&&Uhd(a,new nSd(a,9,c,f,e));return e}}}return f} +function nTb(a){var b,c,d,e,f,g,h,i;g=0;f=a.f.e;for(d=0;d<f.c.length;++d){h=(tCb(d,f.c.length),BD(f.c[d],144));for(e=d+1;e<f.c.length;++e){i=(tCb(e,f.c.length),BD(f.c[e],144));c=S6c(h.d,i.d);b=c-a.a[h.b][i.b];g+=a.i[h.b][i.b]*b*b}}return g} +function _ac(a,b){var c;if(wNb(b,(Nyc(),mxc))){return}c=hbc(BD(vNb(b,Uac),360),BD(vNb(a,mxc),163));yNb(b,Uac,c);if(Qr(new Sr(ur(O_b(b).a.Kc(),new Sq)))){return}switch(c.g){case 1:yNb(b,mxc,(Ctc(),xtc));break;case 2:yNb(b,mxc,(Ctc(),ztc));}} +function wkc(a,b){var c;mkc(a);a.a=(c=new Ji,MAb(new YAb(null,new Kub(b.d,16)),new Vkc(c)),c);rkc(a,BD(vNb(b.b,(Nyc(),Wwc)),376));tkc(a);skc(a);qkc(a);ukc(a);vkc(a,b);MAb(LAb(new YAb(null,$i(Yi(a.b).a)),new Lkc),new Nkc);b.a=false;a.a=null} +function Bod(){fod.call(this,yte,(Fhd(),Ehd));this.p=null;this.a=null;this.f=null;this.n=null;this.g=null;this.c=null;this.i=null;this.j=null;this.d=null;this.b=null;this.e=null;this.k=null;this.o=null;this.s=null;this.q=false;this.r=false} +function Csd(){Csd=ccb;Bsd=new Dsd(Wne,0);ysd=new Dsd('INSIDE_SELF_LOOPS',1);zsd=new Dsd('MULTI_EDGES',2);xsd=new Dsd('EDGE_LABELS',3);Asd=new Dsd('PORTS',4);vsd=new Dsd('COMPOUND',5);usd=new Dsd('CLUSTERS',6);wsd=new Dsd('DISCONNECTED',7)} +function Sgb(a,b){var c,d,e;if(b==0){return (a.a[0]&1)!=0}if(b<0){throw vbb(new ocb('Negative bit address'))}e=b>>5;if(e>=a.d){return a.e<0}c=a.a[e];b=1<<(b&31);if(a.e<0){d=Mgb(a);if(e<d){return false}else d==e?(c=-c):(c=~c)}return (c&b)!=0} +function O1c(a,b,c,d){var e;BD(c.b,65);BD(c.b,65);BD(d.b,65);BD(d.b,65);e=c7c(R6c(BD(c.b,65).c),BD(d.b,65).c);$6c(e,YNb(BD(c.b,65),BD(d.b,65),e));BD(d.b,65);BD(d.b,65);BD(d.b,65).c.a+e.a;BD(d.b,65).c.b+e.b;BD(d.b,65);Hkb(d.a,new T1c(a,b,d))} +function vNd(a,b){var c,d,e,f,g,h,i;f=b.e;if(f){c=aid(f);d=BD(a.g,674);for(g=0;g<a.i;++g){i=d[g];if(JQd(i)==c){e=(!i.d&&(i.d=new xMd(j5,i,1)),i.d);h=BD(c.ah(Nid(f,f.Cb,f.Db>>16)),15).Xc(f);if(h<e.i){return vNd(a,BD(qud(e,h),87))}}}}return b} +function bcb(a,b,c){var d=_bb,h;var e=d[a];var f=e instanceof Array?e[0]:null;if(e&&!f){_=e}else{_=(h=b&&b.prototype,!h&&(h=_bb[b]),ecb(h));_.hm=c;!b&&(_.im=gcb);d[a]=_}for(var g=3;g<arguments.length;++g){arguments[g].prototype=_}f&&(_.gm=f)} +function Qr(a){var b;while(!BD(Qb(a.a),47).Ob()){a.d=Pr(a);if(!a.d){return false}a.a=BD(a.d.Pb(),47);if(JD(a.a,39)){b=BD(a.a,39);a.a=b.a;!a.b&&(a.b=new jkb);Wjb(a.b,a.d);if(b.b){while(!akb(b.b)){Wjb(a.b,BD(gkb(b.b),47))}}a.d=b.d}}return true} +function krb(a,b){var c,d,e,f,g;f=b==null?0:a.b.se(b);d=(c=a.a.get(f),c==null?new Array:c);for(g=0;g<d.length;g++){e=d[g];if(a.b.re(b,e.cd())){if(d.length==1){d.length=0;trb(a.a,f)}else{d.splice(g,1)}--a.c;zpb(a.b);return e.dd()}}return null} +function GGb(a,b){var c,d,e,f;e=1;b.j=true;f=null;for(d=new olb(LFb(b));d.a<d.c.c.length;){c=BD(mlb(d),213);if(!a.c[c.c]){a.c[c.c]=true;f=xFb(c,b);if(c.f){e+=GGb(a,f)}else if(!f.j&&c.a==c.e.e-c.d.e){c.f=true;Qqb(a.p,c);e+=GGb(a,f)}}}return e} +function MVb(a){var b,c,d;for(c=new olb(a.a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),81);d=(uCb(0),0);if(d>0){!(fad(a.a.c)&&b.n.d)&&!(gad(a.a.c)&&b.n.b)&&(b.g.d+=$wnd.Math.max(0,d/2-0.5));!(fad(a.a.c)&&b.n.a)&&!(gad(a.a.c)&&b.n.c)&&(b.g.a-=d-1)}}} +function N3b(a){var b,c,d,e,f;e=new Rkb;f=O3b(a,e);b=BD(vNb(a,(wtc(),gtc)),10);if(b){for(d=new olb(b.j);d.a<d.c.c.length;){c=BD(mlb(d),11);PD(vNb(c,$sc))===PD(a)&&(f=$wnd.Math.max(f,O3b(c,e)))}}e.c.length==0||yNb(a,Ysc,f);return f!=-1?e:null} +function a9b(a,b,c){var d,e,f,g,h,i;f=BD(Ikb(b.e,0),17).c;d=f.i;e=d.k;i=BD(Ikb(c.g,0),17).d;g=i.i;h=g.k;e==(j0b(),g0b)?yNb(a,(wtc(),Vsc),BD(vNb(d,Vsc),11)):yNb(a,(wtc(),Vsc),f);h==g0b?yNb(a,(wtc(),Wsc),BD(vNb(g,Wsc),11)):yNb(a,(wtc(),Wsc),i)} +function Rs(a,b){var c,d,e,f;f=Tbb(Ibb(Eie,keb(Tbb(Ibb(b==null?0:tb(b),Fie)),15)));c=f&a.b.length-1;e=null;for(d=a.b[c];d;e=d,d=d.a){if(d.d==f&&Hb(d.i,b)){!e?(a.b[c]=d.a):(e.a=d.a);Bs(d.c,d.f);As(d.b,d.e);--a.f;++a.e;return true}}return false} +function lD(a,b){var c,d,e,f,g;b&=63;c=a.h;d=(c&Gje)!=0;d&&(c|=-1048576);if(b<22){g=c>>b;f=a.m>>b|c<<22-b;e=a.l>>b|a.m<<22-b}else if(b<44){g=d?Fje:0;f=c>>b-22;e=a.m>>b-22|c<<44-b}else{g=d?Fje:0;f=d?Eje:0;e=c>>b-44}return TC(e&Eje,f&Eje,g&Fje)} +function XOb(a){var b,c,d,e,f,g;this.c=new Rkb;this.d=a;d=Pje;e=Pje;b=Qje;c=Qje;for(g=Jsb(a,0);g.b!=g.d.c;){f=BD(Xsb(g),8);d=$wnd.Math.min(d,f.a);e=$wnd.Math.min(e,f.b);b=$wnd.Math.max(b,f.a);c=$wnd.Math.max(c,f.b)}this.a=new J6c(d,e,b-d,c-e)} +function Dac(a,b){var c,d,e,f,g,h;for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);for(h=new olb(e.a);h.a<h.c.c.length;){g=BD(mlb(h),10);g.k==(j0b(),f0b)&&zac(g,b);for(d=new Sr(ur(U_b(g).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);yac(c,b)}}}} +function Xoc(a){var b,c,d;this.c=a;d=BD(vNb(a,(Nyc(),Lwc)),103);b=Edb(ED(vNb(a,owc)));c=Edb(ED(vNb(a,Dyc)));d==(ead(),aad)||d==bad||d==cad?(this.b=b*c):(this.b=1/(b*c));this.j=Edb(ED(vNb(a,wyc)));this.e=Edb(ED(vNb(a,vyc)));this.f=a.b.c.length} +function ADc(a){var b,c;a.e=KC(WD,oje,25,a.p.c.length,15,1);a.k=KC(WD,oje,25,a.p.c.length,15,1);for(c=new olb(a.p);c.a<c.c.c.length;){b=BD(mlb(c),10);a.e[b.p]=sr(new Sr(ur(R_b(b).a.Kc(),new Sq)));a.k[b.p]=sr(new Sr(ur(U_b(b).a.Kc(),new Sq)))}} +function DDc(a){var b,c,d,e,f,g;e=0;a.q=new Rkb;b=new Tqb;for(g=new olb(a.p);g.a<g.c.c.length;){f=BD(mlb(g),10);f.p=e;for(d=new Sr(ur(U_b(f).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);Qqb(b,c.d.i)}b.a.Bc(f)!=null;Ekb(a.q,new Vqb(b));b.a.$b();++e}} +function JTc(){JTc=ccb;CTc=new q0b(20);BTc=new Osd((Y9c(),f9c),CTc);HTc=new Osd(T9c,20);uTc=new Osd(r8c,tme);ETc=new Osd(D9c,meb(1));GTc=new Osd(H9c,(Bcb(),true));vTc=y8c;xTc=Y8c;yTc=_8c;zTc=b9c;wTc=W8c;ATc=e9c;DTc=x9c;ITc=(rTc(),pTc);FTc=nTc} +function RBd(a,b){var c,d,e,f,g,h,i,j,k;if(a.a.f>0&&JD(b,42)){a.a.qj();j=BD(b,42);i=j.cd();f=i==null?0:tb(i);g=DAd(a.a,f);c=a.a.d[g];if(c){d=BD(c.g,367);k=c.i;for(h=0;h<k;++h){e=d[h];if(e.Sh()==f&&e.Fb(j)){RBd(a,j);return true}}}}return false} +function skc(a){var b,c,d,e;for(e=BD(Qc(a.a,(Xjc(),Ujc)),15).Kc();e.Ob();){d=BD(e.Pb(),101);c=(b=Ec(d.k),b.Hc((Ucd(),Acd))?b.Hc(zcd)?b.Hc(Rcd)?b.Hc(Tcd)?null:dkc:fkc:ekc:ckc);kkc(a,d,c[0],(Fkc(),Ckc),0);kkc(a,d,c[1],Dkc,1);kkc(a,d,c[2],Ekc,1)}} +function enc(a,b){var c,d;c=fnc(b);inc(a,b,c);uPc(a.a,BD(vNb(Q_b(b.b),(wtc(),jtc)),230));dnc(a);cnc(a,b);d=KC(WD,oje,25,b.b.j.c.length,15,1);lnc(a,b,(Ucd(),Acd),d,c);lnc(a,b,zcd,d,c);lnc(a,b,Rcd,d,c);lnc(a,b,Tcd,d,c);a.a=null;a.c=null;a.b=null} +function OYc(){OYc=ccb;LYc=(zYc(),yYc);KYc=new Nsd(Bre,LYc);IYc=new Nsd(Cre,(Bcb(),true));meb(-1);FYc=new Nsd(Dre,meb(-1));meb(-1);GYc=new Nsd(Ere,meb(-1));JYc=new Nsd(Fre,false);MYc=new Nsd(Gre,true);HYc=new Nsd(Hre,false);NYc=new Nsd(Ire,-1)} +function yld(a,b,c){switch(b){case 7:!a.e&&(a.e=new y5d(B2,a,7,4));Uxd(a.e);!a.e&&(a.e=new y5d(B2,a,7,4));ytd(a.e,BD(c,14));return;case 8:!a.d&&(a.d=new y5d(B2,a,8,5));Uxd(a.d);!a.d&&(a.d=new y5d(B2,a,8,5));ytd(a.d,BD(c,14));return;}Zkd(a,b,c)} +function At(a,b){var c,d,e,f,g;if(PD(b)===PD(a)){return true}if(!JD(b,15)){return false}g=BD(b,15);if(a.gc()!=g.gc()){return false}f=g.Kc();for(d=a.Kc();d.Ob();){c=d.Pb();e=f.Pb();if(!(PD(c)===PD(e)||c!=null&&pb(c,e))){return false}}return true} +function U6b(a,b){var c,d,e,f;f=BD(GAb(LAb(LAb(new YAb(null,new Kub(b.b,16)),new $6b),new a7b),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);f.Jc(new c7b);c=0;for(e=f.Kc();e.Ob();){d=BD(e.Pb(),11);d.p==-1&&T6b(a,d,c++)}} +function Wzc(a){switch(a.g){case 0:return new KLc;case 1:return new dJc;case 2:return new tJc;case 3:return new CMc;case 4:return new $Jc;default:throw vbb(new Wdb('No implementation is available for the node placer '+(a.f!=null?a.f:''+a.g)));}} +function nqc(a){switch(a.g){case 0:return new aCc;case 1:return new VBc;case 2:return new kCc;case 3:return new rCc;case 4:return new eCc;default:throw vbb(new Wdb('No implementation is available for the cycle breaker '+(a.f!=null?a.f:''+a.g)));}} +function HWc(){HWc=ccb;BWc=new Nsd(lre,meb(0));CWc=new Nsd(mre,0);yWc=(pWc(),mWc);xWc=new Nsd(nre,yWc);meb(0);wWc=new Nsd(ore,meb(1));EWc=(sXc(),qXc);DWc=new Nsd(pre,EWc);GWc=(fWc(),eWc);FWc=new Nsd(qre,GWc);AWc=(iXc(),hXc);zWc=new Nsd(rre,AWc)} +function XXb(a,b,c){var d;d=null;!!b&&(d=b.d);hYb(a,new cWb(b.n.a-d.b+c.a,b.n.b-d.d+c.b));hYb(a,new cWb(b.n.a-d.b+c.a,b.n.b+b.o.b+d.a+c.b));hYb(a,new cWb(b.n.a+b.o.a+d.c+c.a,b.n.b-d.d+c.b));hYb(a,new cWb(b.n.a+b.o.a+d.c+c.a,b.n.b+b.o.b+d.a+c.b))} +function T6b(a,b,c){var d,e,f;b.p=c;for(f=ul(pl(OC(GC(KI,1),Uhe,20,0,[new J0b(b),new R0b(b)])));Qr(f);){d=BD(Rr(f),11);d.p==-1&&T6b(a,d,c)}if(b.i.k==(j0b(),g0b)){for(e=new olb(b.i.j);e.a<e.c.c.length;){d=BD(mlb(e),11);d!=b&&d.p==-1&&T6b(a,d,c)}}} +function rPc(a){var b,c,d,e,f;e=BD(GAb(IAb(UAb(a)),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);d=dme;if(e.gc()>=2){c=e.Kc();b=ED(c.Pb());while(c.Ob()){f=b;b=ED(c.Pb());d=$wnd.Math.min(d,(uCb(b),b)-(uCb(f),f))}}return d} +function gUc(a,b){var c,d,e,f,g;d=new Psb;Gsb(d,b,d.c.b,d.c);do{c=(sCb(d.b!=0),BD(Nsb(d,d.a.a),86));a.b[c.g]=1;for(f=Jsb(c.d,0);f.b!=f.d.c;){e=BD(Xsb(f),188);g=e.c;a.b[g.g]==1?Dsb(a.a,e):a.b[g.g]==2?(a.b[g.g]=1):Gsb(d,g,d.c.b,d.c)}}while(d.b!=0)} +function Ju(a,b){var c,d,e;if(PD(b)===PD(Qb(a))){return true}if(!JD(b,15)){return false}d=BD(b,15);e=a.gc();if(e!=d.gc()){return false}if(JD(d,54)){for(c=0;c<e;c++){if(!Hb(a.Xb(c),d.Xb(c))){return false}}return true}else{return kr(a.Kc(),d.Kc())}} +function Aac(a,b){var c,d;if(a.c.length!=0){if(a.c.length==2){zac((tCb(0,a.c.length),BD(a.c[0],10)),(rbd(),nbd));zac((tCb(1,a.c.length),BD(a.c[1],10)),obd)}else{for(d=new olb(a);d.a<d.c.c.length;){c=BD(mlb(d),10);zac(c,b)}}a.c=KC(SI,Uhe,1,0,5,1)}} +function uKc(a){var b,c;if(a.c.length!=2){throw vbb(new Zdb('Order only allowed for two paths.'))}b=(tCb(0,a.c.length),BD(a.c[0],17));c=(tCb(1,a.c.length),BD(a.c[1],17));if(b.d.i!=c.c.i){a.c=KC(SI,Uhe,1,0,5,1);a.c[a.c.length]=c;a.c[a.c.length]=b}} +function EMc(a,b){var c,d,e,f,g,h;d=new $rb;g=Gx(new amb(a.g));for(f=g.a.ec().Kc();f.Ob();){e=BD(f.Pb(),10);if(!e){Sdd(b,'There are no classes in a balanced layout.');break}h=a.j[e.p];c=BD(Wrb(d,h),15);if(!c){c=new Rkb;Xrb(d,h,c)}c.Fc(e)}return d} +function Dqd(a,b,c){var d,e,f,g,h,i,j;if(c){f=c.a.length;d=new Yge(f);for(h=(d.b-d.a)*d.c<0?(Xge(),Wge):new she(d);h.Ob();){g=BD(h.Pb(),19);i=Zpd(c,g.a);if(i){j=ftd(_pd(i,Ite),b);Rhb(a.f,j,i);e=Vte in i.a;e&&Lkd(j,_pd(i,Vte));grd(i,j);hrd(i,j)}}}} +function ndc(a,b){var c,d,e,f,g;Odd(b,'Port side processing',1);for(g=new olb(a.a);g.a<g.c.c.length;){e=BD(mlb(g),10);odc(e)}for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),29);for(f=new olb(c.a);f.a<f.c.c.length;){e=BD(mlb(f),10);odc(e)}}Qdd(b)} +function bfc(a,b,c){var d,e,f,g,h;e=a.f;!e&&(e=BD(a.a.a.ec().Kc().Pb(),57));cfc(e,b,c);if(a.a.a.gc()==1){return}d=b*c;for(g=a.a.a.ec().Kc();g.Ob();){f=BD(g.Pb(),57);if(f!=e){h=ugc(f);if(h.f.d){f.d.d+=d+ple;f.d.a-=d+ple}else h.f.a&&(f.d.a-=d+ple)}}} +function tQb(a,b,c,d,e){var f,g,h,i,j,k,l,m,n;g=c-a;h=d-b;f=$wnd.Math.atan2(g,h);i=f+cme;j=f-cme;k=e*$wnd.Math.sin(i)+a;m=e*$wnd.Math.cos(i)+b;l=e*$wnd.Math.sin(j)+a;n=e*$wnd.Math.cos(j)+b;return Ou(OC(GC(m1,1),nie,8,0,[new f7c(k,m),new f7c(l,n)]))} +function OLc(a,b,c,d){var e,f,g,h,i,j,k,l;e=c;k=b;f=k;do{f=a.a[f.p];h=(l=a.g[f.p],Edb(a.p[l.p])+Edb(a.d[f.p])-f.d.d);i=RLc(f,d);if(i){g=(j=a.g[i.p],Edb(a.p[j.p])+Edb(a.d[i.p])+i.o.b+i.d.a);e=$wnd.Math.min(e,h-(g+jBc(a.k,f,i)))}}while(k!=f);return e} +function PLc(a,b,c,d){var e,f,g,h,i,j,k,l;e=c;k=b;f=k;do{f=a.a[f.p];g=(l=a.g[f.p],Edb(a.p[l.p])+Edb(a.d[f.p])+f.o.b+f.d.a);i=QLc(f,d);if(i){h=(j=a.g[i.p],Edb(a.p[j.p])+Edb(a.d[i.p])-i.d.d);e=$wnd.Math.min(e,h-(g+jBc(a.k,f,i)))}}while(k!=f);return e} +function hkd(a,b){var c,d;d=(!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),AAd(a.o,b));if(d!=null){return d}c=b.wg();JD(c,4)&&(c==null?(!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),LAd(a.o,b)):(!a.o&&(a.o=new dId((Thd(),Qhd),S2,a,0)),HAd(a.o,b,c)),a);return c} +function Hbd(){Hbd=ccb;zbd=new Ibd('H_LEFT',0);ybd=new Ibd('H_CENTER',1);Bbd=new Ibd('H_RIGHT',2);Gbd=new Ibd('V_TOP',3);Fbd=new Ibd('V_CENTER',4);Ebd=new Ibd('V_BOTTOM',5);Cbd=new Ibd('INSIDE',6);Dbd=new Ibd('OUTSIDE',7);Abd=new Ibd('H_PRIORITY',8)} +function o6d(a){var b,c,d,e,f,g,h;b=a.Hh(_ve);if(b){h=GD(AAd((!b.b&&(b.b=new sId((jGd(),fGd),x6,b)),b.b),'settingDelegates'));if(h!=null){c=new Rkb;for(e=mfb(h,'\\w+'),f=0,g=e.length;f<g;++f){d=e[f];c.c[c.c.length]=d}return c}}return mmb(),mmb(),jmb} +function sGb(a,b){var c,d,e,f,g,h,i;if(!b.f){throw vbb(new Wdb('The input edge is not a tree edge.'))}f=null;e=Ohe;for(d=new olb(a.d);d.a<d.c.c.length;){c=BD(mlb(d),213);h=c.d;i=c.e;if(xGb(a,h,b)&&!xGb(a,i,b)){g=i.e-h.e-c.a;if(g<e){e=g;f=c}}}return f} +function qTb(a){var b,c,d,e,f,g;if(a.f.e.c.length<=1){return}b=0;e=nTb(a);c=Pje;do{b>0&&(e=c);for(g=new olb(a.f.e);g.a<g.c.c.length;){f=BD(mlb(g),144);if(Ccb(DD(vNb(f,(bTb(),USb))))){continue}d=mTb(a,f);P6c(X6c(f.d),d)}c=nTb(a)}while(!pTb(a,b++,e,c))} +function $ac(a,b){var c,d,e;Odd(b,'Layer constraint preprocessing',1);c=new Rkb;e=new Bib(a.a,0);while(e.b<e.d.gc()){d=(sCb(e.b<e.d.gc()),BD(e.d.Xb(e.c=e.b++),10));if(Zac(d)){Xac(d);c.c[c.c.length]=d;uib(e)}}c.c.length==0||yNb(a,(wtc(),Lsc),c);Qdd(b)} +function sjc(a,b){var c,d,e,f,g;f=a.g.a;g=a.g.b;for(d=new olb(a.d);d.a<d.c.c.length;){c=BD(mlb(d),70);e=c.n;a.a==(Ajc(),xjc)||a.i==(Ucd(),zcd)?(e.a=f):a.a==yjc||a.i==(Ucd(),Tcd)?(e.a=f+a.j.a-c.o.a):(e.a=f+(a.j.a-c.o.a)/2);e.b=g;P6c(e,b);g+=c.o.b+a.e}} +function LSc(a,b,c){var d,e,f,g;Odd(c,'Processor set coordinates',1);a.a=b.b.b==0?1:b.b.b;f=null;d=Jsb(b.b,0);while(!f&&d.b!=d.d.c){g=BD(Xsb(d),86);if(Ccb(DD(vNb(g,(mTc(),jTc))))){f=g;e=g.e;e.a=BD(vNb(g,kTc),19).a;e.b=0}}MSc(a,URc(f),Udd(c,1));Qdd(c)} +function xSc(a,b,c){var d,e,f;Odd(c,'Processor determine the height for each level',1);a.a=b.b.b==0?1:b.b.b;e=null;d=Jsb(b.b,0);while(!e&&d.b!=d.d.c){f=BD(Xsb(d),86);Ccb(DD(vNb(f,(mTc(),jTc))))&&(e=f)}!!e&&ySc(a,Ou(OC(GC(q$,1),fme,86,0,[e])),c);Qdd(c)} +function brd(a,b){var c,d,e,f,g,h,i,j,k,l;j=a;i=$pd(j,'individualSpacings');if(i){d=ikd(b,(Y9c(),O9c));g=!d;if(g){e=new _fd;jkd(b,O9c,e)}h=BD(hkd(b,O9c),373);l=i;f=null;!!l&&(f=(k=$B(l,KC(ZI,nie,2,0,6,1)),new mC(l,k)));if(f){c=new Frd(l,h);reb(f,c)}}} +function frd(a,b){var c,d,e,f,g,h,i,j,k,l,m;i=null;l=a;k=null;if(cue in l.a||due in l.a||Ote in l.a){j=null;m=etd(b);g=$pd(l,cue);c=new Ird(m);Eqd(c.a,g);h=$pd(l,due);d=new asd(m);Pqd(d.a,h);f=Ypd(l,Ote);e=new dsd(m);j=(Qqd(e.a,f),f);k=j}i=k;return i} +function $w(a,b){var c,d,e;if(b===a){return true}if(JD(b,543)){e=BD(b,835);if(a.a.d!=e.a.d||Ah(a).gc()!=Ah(e).gc()){return false}for(d=Ah(e).Kc();d.Ob();){c=BD(d.Pb(),416);if(Aw(a,c.a.cd())!=BD(c.a.dd(),14).gc()){return false}}return true}return false} +function BMb(a){var b,c,d,e;d=BD(a.a,19).a;e=BD(a.b,19).a;b=d;c=e;if(d==0&&e==0){c-=1}else{if(d==-1&&e<=0){b=0;c-=2}else{if(d<=0&&e>0){b-=1;c-=1}else{if(d>=0&&e<0){b+=1;c+=1}else{if(d>0&&e>=0){b-=1;c+=1}else{b+=1;c-=1}}}}}return new vgd(meb(b),meb(c))} +function PIc(a,b){if(a.c<b.c){return -1}else if(a.c>b.c){return 1}else if(a.b<b.b){return -1}else if(a.b>b.b){return 1}else if(a.a!=b.a){return tb(a.a)-tb(b.a)}else if(a.d==(UIc(),TIc)&&b.d==SIc){return -1}else if(a.d==SIc&&b.d==TIc){return 1}return 0} +function aNc(a,b){var c,d,e,f,g;f=b.a;f.c.i==b.b?(g=f.d):(g=f.c);f.c.i==b.b?(d=f.c):(d=f.d);e=NLc(a.a,g,d);if(e>0&&e<dme){c=OLc(a.a,d.i,e,a.c);TLc(a.a,d.i,-c);return c>0}else if(e<0&&-e<dme){c=PLc(a.a,d.i,-e,a.c);TLc(a.a,d.i,c);return c>0}return false} +function RZc(a,b,c,d){var e,f,g,h,i,j,k,l;e=(b-a.d)/a.c.c.length;f=0;a.a+=c;a.d=b;for(l=new olb(a.c);l.a<l.c.c.length;){k=BD(mlb(l),33);j=k.g;i=k.f;dld(k,k.i+f*e);eld(k,k.j+d*c);cld(k,k.g+e);ald(k,a.a);++f;h=k.g;g=k.f;Ffd(k,new f7c(h,g),new f7c(j,i))}} +function Xmd(a){var b,c,d,e,f,g,h;if(a==null){return null}h=a.length;e=(h+1)/2|0;g=KC(SD,wte,25,e,15,1);h%2!=0&&(g[--e]=jnd((BCb(h-1,a.length),a.charCodeAt(h-1))));for(c=0,d=0;c<e;++c){b=jnd(bfb(a,d++));f=jnd(bfb(a,d++));g[c]=(b<<4|f)<<24>>24}return g} +function vdb(a){if(a.pe()){var b=a.c;b.qe()?(a.o='['+b.n):!b.pe()?(a.o='[L'+b.ne()+';'):(a.o='['+b.ne());a.b=b.me()+'[]';a.k=b.oe()+'[]';return}var c=a.j;var d=a.d;d=d.split('/');a.o=ydb('.',[c,ydb('$',d)]);a.b=ydb('.',[c,ydb('.',d)]);a.k=d[d.length-1]} +function qGb(a,b){var c,d,e,f,g;g=null;for(f=new olb(a.e.a);f.a<f.c.c.length;){e=BD(mlb(f),121);if(e.b.a.c.length==e.g.a.c.length){d=e.e;g=BGb(e);for(c=e.e-BD(g.a,19).a+1;c<e.e+BD(g.b,19).a;c++){b[c]<b[d]&&(d=c)}if(b[d]<b[e.e]){--b[e.e];++b[d];e.e=d}}}} +function SLc(a){var b,c,d,e,f,g,h,i;e=Pje;d=Qje;for(c=new olb(a.e.b);c.a<c.c.c.length;){b=BD(mlb(c),29);for(g=new olb(b.a);g.a<g.c.c.length;){f=BD(mlb(g),10);i=Edb(a.p[f.p]);h=i+Edb(a.b[a.g[f.p].p]);e=$wnd.Math.min(e,i);d=$wnd.Math.max(d,h)}}return d-e} +function r1d(a,b,c,d){var e,f,g,h,i,j;i=null;e=f1d(a,b);for(h=0,j=e.gc();h<j;++h){f=BD(e.Xb(h),170);if(dfb(d,a2d(q1d(a,f)))){g=b2d(q1d(a,f));if(c==null){if(g==null){return f}else !i&&(i=f)}else if(dfb(c,g)){return f}else g==null&&!i&&(i=f)}}return null} +function s1d(a,b,c,d){var e,f,g,h,i,j;i=null;e=g1d(a,b);for(h=0,j=e.gc();h<j;++h){f=BD(e.Xb(h),170);if(dfb(d,a2d(q1d(a,f)))){g=b2d(q1d(a,f));if(c==null){if(g==null){return f}else !i&&(i=f)}else if(dfb(c,g)){return f}else g==null&&!i&&(i=f)}}return null} +function p3d(a,b,c){var d,e,f,g,h,i;g=new yud;h=S6d(a.e.Tg(),b);d=BD(a.g,119);Q6d();if(BD(b,66).Oj()){for(f=0;f<a.i;++f){e=d[f];h.rl(e.ak())&&wtd(g,e)}}else{for(f=0;f<a.i;++f){e=d[f];if(h.rl(e.ak())){i=e.dd();wtd(g,c?b3d(a,b,f,g.i,i):i)}}}return wud(g)} +function T9b(a,b){var c,d,e,f,g;c=new Rpb(EW);for(e=(Apc(),OC(GC(EW,1),Kie,227,0,[wpc,ypc,vpc,xpc,zpc,upc])),f=0,g=e.length;f<g;++f){d=e[f];Opb(c,d,new Rkb)}MAb(NAb(JAb(LAb(new YAb(null,new Kub(a.b,16)),new hac),new jac),new lac(b)),new nac(c));return c} +function AVc(a,b,c){var d,e,f,g,h,i,j,k,l,m;for(f=b.Kc();f.Ob();){e=BD(f.Pb(),33);k=e.i+e.g/2;m=e.j+e.f/2;i=a.f;g=i.i+i.g/2;h=i.j+i.f/2;j=k-g;l=m-h;d=$wnd.Math.sqrt(j*j+l*l);j*=a.e/d;l*=a.e/d;if(c){k-=j;m-=l}else{k+=j;m+=l}dld(e,k-e.g/2);eld(e,m-e.f/2)}} +function Yfe(a){var b,c,d;if(a.c)return;if(a.b==null)return;for(b=a.b.length-4;b>=0;b-=2){for(c=0;c<=b;c+=2){if(a.b[c]>a.b[c+2]||a.b[c]===a.b[c+2]&&a.b[c+1]>a.b[c+3]){d=a.b[c+2];a.b[c+2]=a.b[c];a.b[c]=d;d=a.b[c+3];a.b[c+3]=a.b[c+1];a.b[c+1]=d}}}a.c=true} +function UUb(a,b){var c,d,e,f,g,h,i,j;g=b==1?KUb:JUb;for(f=g.a.ec().Kc();f.Ob();){e=BD(f.Pb(),103);for(i=BD(Qc(a.f.c,e),21).Kc();i.Ob();){h=BD(i.Pb(),46);d=BD(h.b,81);j=BD(h.a,189);c=j.c;switch(e.g){case 2:case 1:d.g.d+=c;break;case 4:case 3:d.g.c+=c;}}}} +function PFc(a,b){var c,d,e,f,g,h,i,j,k;j=-1;k=0;for(g=a,h=0,i=g.length;h<i;++h){f=g[h];c=new Dnc(j==-1?a[0]:a[j],b,(xzc(),wzc));for(d=0;d<f.length;d++){for(e=d+1;e<f.length;e++){wNb(f[d],(wtc(),Zsc))&&wNb(f[e],Zsc)&&ync(c,f[d],f[e])>0&&++k}}++j}return k} +function Eid(a){var b,c;c=new Wfb(hdb(a.gm));c.a+='@';Qfb(c,(b=tb(a)>>>0,b.toString(16)));if(a.kh()){c.a+=' (eProxyURI: ';Pfb(c,a.qh());if(a.$g()){c.a+=' eClass: ';Pfb(c,a.$g())}c.a+=')'}else if(a.$g()){c.a+=' (eClass: ';Pfb(c,a.$g());c.a+=')'}return c.a} +function TDb(a){var b,c,d,e;if(a.e){throw vbb(new Zdb((fdb(TM),Jke+TM.k+Kke)))}a.d==(ead(),cad)&&SDb(a,aad);for(c=new olb(a.a.a);c.a<c.c.c.length;){b=BD(mlb(c),307);b.g=b.i}for(e=new olb(a.a.b);e.a<e.c.c.length;){d=BD(mlb(e),57);d.i=Qje}a.b.Le(a);return a} +function TPc(a,b){var c,d,e,f,g;if(b<2*a.b){throw vbb(new Wdb('The knot vector must have at least two time the dimension elements.'))}a.f=1;for(e=0;e<a.b;e++){Ekb(a.e,0)}g=b+1-2*a.b;c=g;for(f=1;f<g;f++){Ekb(a.e,f/c)}if(a.d){for(d=0;d<a.b;d++){Ekb(a.e,1)}}} +function ard(a,b){var c,d,e,f,g,h,i,j,k;j=b;k=BD(_o(qo(a.i),j),33);if(!k){e=_pd(j,Vte);h="Unable to find elk node for json object '"+e;i=h+"' Panic!";throw vbb(new cqd(i))}f=Ypd(j,'edges');c=new krd(a,k);mqd(c.a,c.b,f);g=Ypd(j,Jte);d=new vrd(a);xqd(d.a,g)} +function xAd(a,b,c,d){var e,f,g,h,i;if(d!=null){e=a.d[b];if(e){f=e.g;i=e.i;for(h=0;h<i;++h){g=BD(f[h],133);if(g.Sh()==c&&pb(d,g.cd())){return h}}}}else{e=a.d[b];if(e){f=e.g;i=e.i;for(h=0;h<i;++h){g=BD(f[h],133);if(PD(g.cd())===PD(d)){return h}}}}return -1} +function nUd(a,b){var c,d,e;c=b==null?Wd(irb(a.f,null)):Crb(a.g,b);if(JD(c,235)){e=BD(c,235);e.Qh()==null&&undefined;return e}else if(JD(c,498)){d=BD(c,1938);e=d.a;!!e&&(e.yb==null?undefined:b==null?jrb(a.f,null,e):Drb(a.g,b,e));return e}else{return null}} +function ide(a){hde();var b,c,d,e,f,g,h;if(a==null)return null;e=a.length;if(e%2!=0)return null;b=rfb(a);f=e/2|0;c=KC(SD,wte,25,f,15,1);for(d=0;d<f;d++){g=fde[b[d*2]];if(g==-1)return null;h=fde[b[d*2+1]];if(h==-1)return null;c[d]=(g<<4|h)<<24>>24}return c} +function lKb(a,b,c){var d,e,f;e=BD(Mpb(a.i,b),306);if(!e){e=new bIb(a.d,b,c);Npb(a.i,b,e);if(sJb(b)){CHb(a.a,b.c,b.b,e)}else{f=rJb(b);d=BD(Mpb(a.p,f),244);switch(f.g){case 1:case 3:e.j=true;lIb(d,b.b,e);break;case 4:case 2:e.k=true;lIb(d,b.c,e);}}}return e} +function r3d(a,b,c,d){var e,f,g,h,i,j;h=new yud;i=S6d(a.e.Tg(),b);e=BD(a.g,119);Q6d();if(BD(b,66).Oj()){for(g=0;g<a.i;++g){f=e[g];i.rl(f.ak())&&wtd(h,f)}}else{for(g=0;g<a.i;++g){f=e[g];if(i.rl(f.ak())){j=f.dd();wtd(h,d?b3d(a,b,g,h.i,j):j)}}}return xud(h,c)} +function YCc(a,b){var c,d,e,f,g,h,i,j;e=a.b[b.p];if(e>=0){return e}else{f=1;for(h=new olb(b.j);h.a<h.c.c.length;){g=BD(mlb(h),11);for(d=new olb(g.g);d.a<d.c.c.length;){c=BD(mlb(d),17);j=c.d.i;if(b!=j){i=YCc(a,j);f=$wnd.Math.max(f,i+1)}}}XCc(a,b,f);return f}} +function YGc(a,b,c){var d,e,f;for(d=1;d<a.c.length;d++){f=(tCb(d,a.c.length),BD(a.c[d],10));e=d;while(e>0&&b.ue((tCb(e-1,a.c.length),BD(a.c[e-1],10)),f)>0){Nkb(a,e,(tCb(e-1,a.c.length),BD(a.c[e-1],10)));--e}tCb(e,a.c.length);a.c[e]=f}c.a=new Lqb;c.b=new Lqb} +function n5c(a,b,c){var d,e,f,g,h,i,j,k;k=(d=BD(b.e&&b.e(),9),new xqb(d,BD(_Bb(d,d.length),9),0));i=mfb(c,'[\\[\\]\\s,]+');for(f=i,g=0,h=f.length;g<h;++g){e=f[g];if(ufb(e).length==0){continue}j=m5c(a,e);if(j==null){return null}else{rqb(k,BD(j,22))}}return k} +function KVb(a){var b,c,d;for(c=new olb(a.a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),81);d=(uCb(0),0);if(d>0){!(fad(a.a.c)&&b.n.d)&&!(gad(a.a.c)&&b.n.b)&&(b.g.d-=$wnd.Math.max(0,d/2-0.5));!(fad(a.a.c)&&b.n.a)&&!(gad(a.a.c)&&b.n.c)&&(b.g.a+=$wnd.Math.max(0,d-1))}}} +function Hac(a,b,c){var d,e;if((a.c-a.b&a.a.length-1)==2){if(b==(Ucd(),Acd)||b==zcd){xac(BD(bkb(a),15),(rbd(),nbd));xac(BD(bkb(a),15),obd)}else{xac(BD(bkb(a),15),(rbd(),obd));xac(BD(bkb(a),15),nbd)}}else{for(e=new xkb(a);e.a!=e.b;){d=BD(vkb(e),15);xac(d,c)}}} +function htd(a,b){var c,d,e,f,g,h,i;e=Nu(new qtd(a));h=new Bib(e,e.c.length);f=Nu(new qtd(b));i=new Bib(f,f.c.length);g=null;while(h.b>0&&i.b>0){c=(sCb(h.b>0),BD(h.a.Xb(h.c=--h.b),33));d=(sCb(i.b>0),BD(i.a.Xb(i.c=--i.b),33));if(c==d){g=c}else{break}}return g} +function Cub(a,b){var c,d,e,f,g,h;f=a.a*kke+a.b*1502;h=a.b*kke+11;c=$wnd.Math.floor(h*lke);f+=c;h-=c*mke;f%=mke;a.a=f;a.b=h;if(b<=24){return $wnd.Math.floor(a.a*wub[b])}else{e=a.a*(1<<b-24);g=$wnd.Math.floor(a.b*xub[b]);d=e+g;d>=2147483648&&(d-=Zje);return d}} +function Zic(a,b,c){var d,e,f,g;if(bjc(a,b)>bjc(a,c)){d=V_b(c,(Ucd(),zcd));a.d=d.dc()?0:B0b(BD(d.Xb(0),11));g=V_b(b,Tcd);a.b=g.dc()?0:B0b(BD(g.Xb(0),11))}else{e=V_b(c,(Ucd(),Tcd));a.d=e.dc()?0:B0b(BD(e.Xb(0),11));f=V_b(b,zcd);a.b=f.dc()?0:B0b(BD(f.Xb(0),11))}} +function l6d(a){var b,c,d,e,f,g,h;if(a){b=a.Hh(_ve);if(b){g=GD(AAd((!b.b&&(b.b=new sId((jGd(),fGd),x6,b)),b.b),'conversionDelegates'));if(g!=null){h=new Rkb;for(d=mfb(g,'\\w+'),e=0,f=d.length;e<f;++e){c=d[e];h.c[h.c.length]=c}return h}}}return mmb(),mmb(),jmb} +function FKb(a,b){var c,d,e,f;c=a.o.a;for(f=BD(BD(Qc(a.r,b),21),84).Kc();f.Ob();){e=BD(f.Pb(),111);e.e.a=c*Edb(ED(e.b.We(BKb)));e.e.b=(d=e.b,d.Xe((Y9c(),s9c))?d.Hf()==(Ucd(),Acd)?-d.rf().b-Edb(ED(d.We(s9c))):Edb(ED(d.We(s9c))):d.Hf()==(Ucd(),Acd)?-d.rf().b:0)}} +function Woc(a){var b,c,d,e,f,g,h,i;b=true;e=null;f=null;j:for(i=new olb(a.a);i.a<i.c.c.length;){h=BD(mlb(i),10);for(d=new Sr(ur(R_b(h).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);if(!!e&&e!=h){b=false;break j}e=h;g=c.c.i;if(!!f&&f!=g){b=false;break j}f=g}}return b} +function OOc(a,b,c){var d,e,f,g,h,i;f=-1;h=-1;for(g=0;g<b.c.length;g++){e=(tCb(g,b.c.length),BD(b.c[g],329));if(e.c>a.c){break}else if(e.a>=a.s){f<0&&(f=g);h=g}}i=(a.s+a.c)/2;if(f>=0){d=NOc(a,b,f,h);i=$Oc((tCb(d,b.c.length),BD(b.c[d],329)));YOc(b,d,c)}return i} +function lZc(){lZc=ccb;RYc=new Osd((Y9c(),r8c),1.3);VYc=I8c;gZc=new q0b(15);fZc=new Osd(f9c,gZc);jZc=new Osd(T9c,15);SYc=w8c;_Yc=Y8c;aZc=_8c;bZc=b9c;$Yc=W8c;cZc=e9c;hZc=x9c;eZc=(OYc(),KYc);ZYc=IYc;dZc=JYc;iZc=MYc;WYc=HYc;XYc=O8c;YYc=P8c;UYc=GYc;TYc=FYc;kZc=NYc} +function Bnd(a,b,c){var d,e,f,g,h,i,j;g=(f=new RHd,f);PHd(g,(uCb(b),b));j=(!g.b&&(g.b=new sId((jGd(),fGd),x6,g)),g.b);for(i=1;i<c.length;i+=2){HAd(j,c[i-1],c[i])}d=(!a.Ab&&(a.Ab=new cUd(a5,a,0,3)),a.Ab);for(h=0;h<0;++h){e=LHd(BD(qud(d,d.i-1),590));d=e}wtd(d,g)} +function MPb(a,b,c){var d,e,f;sNb.call(this,new Rkb);this.a=b;this.b=c;this.e=a;d=(a.b&&LOb(a),a.a);this.d=KPb(d.a,this.a);this.c=KPb(d.b,this.b);kNb(this,this.d,this.c);LPb(this);for(f=this.e.e.a.ec().Kc();f.Ob();){e=BD(f.Pb(),266);e.c.c.length>0&&JPb(this,e)}} +function IQb(a,b,c,d,e,f){var g,h,i;if(!e[b.b]){e[b.b]=true;g=d;!g&&(g=new kRb);Ekb(g.e,b);for(i=f[b.b].Kc();i.Ob();){h=BD(i.Pb(),282);if(h.d==c||h.c==c){continue}h.c!=b&&IQb(a,h.c,b,g,e,f);h.d!=b&&IQb(a,h.d,b,g,e,f);Ekb(g.c,h);Gkb(g.d,h.b)}return g}return null} +function e4b(a){var b,c,d,e,f,g,h;b=0;for(e=new olb(a.e);e.a<e.c.c.length;){d=BD(mlb(e),17);c=FAb(new YAb(null,new Kub(d.b,16)),new w4b);c&&++b}for(g=new olb(a.g);g.a<g.c.c.length;){f=BD(mlb(g),17);h=FAb(new YAb(null,new Kub(f.b,16)),new y4b);h&&++b}return b>=2} +function gec(a,b){var c,d,e,f;Odd(b,'Self-Loop pre-processing',1);for(d=new olb(a.a);d.a<d.c.c.length;){c=BD(mlb(d),10);if(Ljc(c)){e=(f=new Kjc(c),yNb(c,(wtc(),ntc),f),Hjc(f),f);MAb(NAb(LAb(new YAb(null,new Kub(e.d,16)),new jec),new lec),new nec);eec(e)}}Qdd(b)} +function vnc(a,b,c,d,e){var f,g,h,i,j,k;f=a.c.d.j;g=BD(Ut(c,0),8);for(k=1;k<c.b;k++){j=BD(Ut(c,k),8);Gsb(d,g,d.c.b,d.c);h=Y6c(P6c(new g7c(g),j),0.5);i=Y6c(new e7c(bRc(f)),e);P6c(h,i);Gsb(d,h,d.c.b,d.c);g=j;f=b==0?Xcd(f):Vcd(f)}Dsb(d,(sCb(c.b!=0),BD(c.c.b.c,8)))} +function Jbd(a){Hbd();var b,c,d;c=qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Dbd]));if(Ox(Cx(c,a))>1){return false}b=qqb(zbd,OC(GC(B1,1),Kie,93,0,[ybd,Bbd]));if(Ox(Cx(b,a))>1){return false}d=qqb(Gbd,OC(GC(B1,1),Kie,93,0,[Fbd,Ebd]));if(Ox(Cx(d,a))>1){return false}return true} +function U0d(a,b){var c,d,e;c=b.Hh(a.a);if(c){e=GD(AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),'affiliation'));if(e!=null){d=kfb(e,wfb(35));return d==-1?l1d(a,u1d(a,bKd(b.Hj())),e):d==0?l1d(a,null,e.substr(1)):l1d(a,e.substr(0,d),e.substr(d+1))}}return null} +function ic(b){var c,d,e;try{return b==null?Xhe:fcb(b)}catch(a){a=ubb(a);if(JD(a,102)){c=a;e=hdb(rb(b))+'@'+(d=(Zfb(),kCb(b))>>>0,d.toString(16));tyb(xyb(),($xb(),'Exception during lenientFormat for '+e),c);return '<'+e+' threw '+hdb(c.gm)+'>'}else throw vbb(a)}} +function mzc(a){switch(a.g){case 0:return new xDc;case 1:return new ZCc;case 2:return new DCc;case 3:return new QCc;case 4:return new LDc;case 5:return new iDc;default:throw vbb(new Wdb('No implementation is available for the layerer '+(a.f!=null?a.f:''+a.g)));}} +function AQc(a,b,c){var d,e,f;for(f=new olb(a.t);f.a<f.c.c.length;){d=BD(mlb(f),268);if(d.b.s<0&&d.c>0){d.b.n-=d.c;d.b.n<=0&&d.b.u>0&&Dsb(b,d.b)}}for(e=new olb(a.i);e.a<e.c.c.length;){d=BD(mlb(e),268);if(d.a.s<0&&d.c>0){d.a.u-=d.c;d.a.u<=0&&d.a.n>0&&Dsb(c,d.a)}}} +function Vud(a){var b,c,d,e,f;if(a.g==null){a.d=a.si(a.f);wtd(a,a.d);if(a.c){f=a.f;return f}}b=BD(a.g[a.i-1],47);e=b.Pb();a.e=b;c=a.si(e);if(c.Ob()){a.d=c;wtd(a,c)}else{a.d=null;while(!b.Ob()){NC(a.g,--a.i,null);if(a.i==0){break}d=BD(a.g[a.i-1],47);b=d}}return e} +function r2d(a,b){var c,d,e,f,g,h;d=b;e=d.ak();if(T6d(a.e,e)){if(e.hi()&&E2d(a,e,d.dd())){return false}}else{h=S6d(a.e.Tg(),e);c=BD(a.g,119);for(f=0;f<a.i;++f){g=c[f];if(h.rl(g.ak())){if(pb(g,d)){return false}else{BD(Gtd(a,f,b),72);return true}}}}return wtd(a,b)} +function r9b(a,b,c,d){var e,f,g,h;e=new b0b(a);__b(e,(j0b(),f0b));yNb(e,(wtc(),$sc),b);yNb(e,ktc,d);yNb(e,(Nyc(),Vxc),(dcd(),$bd));yNb(e,Vsc,b.c);yNb(e,Wsc,b.d);zbc(b,e);h=$wnd.Math.floor(c/2);for(g=new olb(e.j);g.a<g.c.c.length;){f=BD(mlb(g),11);f.n.b=h}return e} +function wac(a,b){var c,d,e,f,g,h,i,j,k;i=Pu(a.c-a.b&a.a.length-1);j=null;k=null;for(f=new xkb(a);f.a!=f.b;){e=BD(vkb(f),10);c=(h=BD(vNb(e,(wtc(),Vsc)),11),!h?null:h.i);d=(g=BD(vNb(e,Wsc),11),!g?null:g.i);if(j!=c||k!=d){Aac(i,b);j=c;k=d}i.c[i.c.length]=e}Aac(i,b)} +function HNc(a){var b,c,d,e,f,g,h;b=0;for(d=new olb(a.a);d.a<d.c.c.length;){c=BD(mlb(d),10);for(f=new Sr(ur(U_b(c).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);if(a==e.d.i.c&&e.c.j==(Ucd(),Tcd)){g=A0b(e.c).b;h=A0b(e.d).b;b=$wnd.Math.max(b,$wnd.Math.abs(h-g))}}}return b} +function aWc(a,b,c){var d,e,f;Odd(c,'Remove overlaps',1);c.n&&!!b&&Tdd(c,i6d(b),(pgd(),mgd));d=BD(hkd(b,(MUc(),LUc)),33);a.f=d;a.a=tXc(BD(hkd(b,(ZWc(),WWc)),293));e=ED(hkd(b,(Y9c(),T9c)));FVc(a,(uCb(e),e));f=gVc(d);_Vc(a,b,f,c);c.n&&!!b&&Tdd(c,i6d(b),(pgd(),mgd))} +function aYb(a,b,c){switch(c.g){case 1:return new f7c(b.a,$wnd.Math.min(a.d.b,b.b));case 2:return new f7c($wnd.Math.max(a.c.a,b.a),b.b);case 3:return new f7c(b.a,$wnd.Math.max(a.c.b,b.b));case 4:return new f7c($wnd.Math.min(b.a,a.d.a),b.b);}return new f7c(b.a,b.b)} +function mFc(a,b,c,d){var e,f,g,h,i,j,k,l,m;l=d?(Ucd(),Tcd):(Ucd(),zcd);e=false;for(i=b[c],j=0,k=i.length;j<k;++j){h=i[j];if(ecd(BD(vNb(h,(Nyc(),Vxc)),98))){continue}g=h.e;m=!V_b(h,l).dc()&&!!g;if(m){f=WZb(g);a.b=new sic(f,d?0:f.length-1)}e=e|nFc(a,h,l,m)}return e} +function $sd(a){var b,c,d;b=Pu(1+(!a.c&&(a.c=new cUd(F2,a,9,9)),a.c).i);Ekb(b,(!a.d&&(a.d=new y5d(B2,a,8,5)),a.d));for(d=new Fyd((!a.c&&(a.c=new cUd(F2,a,9,9)),a.c));d.e!=d.i.gc();){c=BD(Dyd(d),118);Ekb(b,(!c.d&&(c.d=new y5d(B2,c,8,5)),c.d))}return Qb(b),new sl(b)} +function _sd(a){var b,c,d;b=Pu(1+(!a.c&&(a.c=new cUd(F2,a,9,9)),a.c).i);Ekb(b,(!a.e&&(a.e=new y5d(B2,a,7,4)),a.e));for(d=new Fyd((!a.c&&(a.c=new cUd(F2,a,9,9)),a.c));d.e!=d.i.gc();){c=BD(Dyd(d),118);Ekb(b,(!c.e&&(c.e=new y5d(B2,c,7,4)),c.e))}return Qb(b),new sl(b)} +function M9d(a){var b,c,d,e;if(a==null){return null}else{d=Qge(a,true);e=Nwe.length;if(dfb(d.substr(d.length-e,e),Nwe)){c=d.length;if(c==4){b=(BCb(0,d.length),d.charCodeAt(0));if(b==43){return x9d}else if(b==45){return w9d}}else if(c==3){return x9d}}return Hcb(d)}} +function aKc(a){var b,c,d,e;b=0;c=0;for(e=new olb(a.j);e.a<e.c.c.length;){d=BD(mlb(e),11);b=Tbb(wbb(b,HAb(JAb(new YAb(null,new Kub(d.e,16)),new nLc))));c=Tbb(wbb(c,HAb(JAb(new YAb(null,new Kub(d.g,16)),new pLc))));if(b>1||c>1){return 2}}if(b+c==1){return 2}return 0} +function WQb(a,b,c){var d,e,f,g,h;Odd(c,'ELK Force',1);Ccb(DD(hkd(b,(wSb(),jSb))))||$Cb((d=new _Cb((Pgd(),new bhd(b))),d));h=TQb(b);XQb(h);YQb(a,BD(vNb(h,fSb),424));g=LQb(a.a,h);for(f=g.Kc();f.Ob();){e=BD(f.Pb(),231);tRb(a.b,e,Udd(c,1/g.gc()))}h=KQb(g);SQb(h);Qdd(c)} +function yoc(a,b){var c,d,e,f,g;Odd(b,'Breaking Point Processor',1);xoc(a);if(Ccb(DD(vNb(a,(Nyc(),Jyc))))){for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),29);c=0;for(g=new olb(d.a);g.a<g.c.c.length;){f=BD(mlb(g),10);f.p=c++}}soc(a);toc(a,true);toc(a,false)}Qdd(b)} +function $1c(a,b,c){var d,e,f,g,h,i;h=a.c;for(g=(!c.q?(mmb(),mmb(),kmb):c.q).vc().Kc();g.Ob();){f=BD(g.Pb(),42);d=!WAb(JAb(new YAb(null,new Kub(h,16)),new Xxb(new m2c(b,f)))).sd((EAb(),DAb));if(d){i=f.dd();if(JD(i,4)){e=fvd(i);e!=null&&(i=e)}b.Ye(BD(f.cd(),146),i)}}} +function MQd(a,b){var c,d,e,f,g;if(!b){return null}else{f=JD(a.Cb,88)||JD(a.Cb,99);g=!f&&JD(a.Cb,322);for(d=new Fyd((!b.a&&(b.a=new KYd(b,j5,b)),b.a));d.e!=d.i.gc();){c=BD(Dyd(d),87);e=KQd(c);if(f?JD(e,88):g?JD(e,148):!!e){return e}}return f?(jGd(),_Fd):(jGd(),YFd)}} +function g3b(a,b){var c,d,e,f,g,h;Odd(b,'Constraints Postprocessor',1);g=0;for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);h=0;for(d=new olb(e.a);d.a<d.c.c.length;){c=BD(mlb(d),10);if(c.k==(j0b(),h0b)){yNb(c,(Nyc(),nxc),meb(g));yNb(c,Gwc,meb(h));++h}}++g}Qdd(b)} +function eRc(a,b,c,d){var e,f,g,h,i,j,k;i=new f7c(c,d);c7c(i,BD(vNb(b,(mTc(),WSc)),8));for(k=Jsb(b.b,0);k.b!=k.d.c;){j=BD(Xsb(k),86);P6c(j.e,i);Dsb(a.b,j)}for(h=Jsb(b.a,0);h.b!=h.d.c;){g=BD(Xsb(h),188);for(f=Jsb(g.a,0);f.b!=f.d.c;){e=BD(Xsb(f),8);P6c(e,i)}Dsb(a.a,g)}} +function uid(a,b,c){var d,e,f;f=e1d((O6d(),M6d),a.Tg(),b);if(f){Q6d();if(!BD(f,66).Oj()){f=_1d(q1d(M6d,f));if(!f){throw vbb(new Wdb(ite+b.ne()+jte))}}e=(d=a.Yg(f),BD(d>=0?a._g(d,true,true):sid(a,f,true),153));BD(e,215).ml(b,c)}else{throw vbb(new Wdb(ite+b.ne()+jte))}} +function ROc(a,b){var c,d,e,f,g;c=new Rkb;e=LAb(new YAb(null,new Kub(a,16)),new iPc);f=LAb(new YAb(null,new Kub(a,16)),new kPc);g=aAb(_zb(OAb(ty(OC(GC(xM,1),Uhe,833,0,[e,f])),new mPc)));for(d=1;d<g.length;d++){g[d]-g[d-1]>=2*b&&Ekb(c,new bPc(g[d-1]+b,g[d]-b))}return c} +function AXc(a,b,c){Odd(c,'Eades radial',1);c.n&&!!b&&Tdd(c,i6d(b),(pgd(),mgd));a.d=BD(hkd(b,(MUc(),LUc)),33);a.c=Edb(ED(hkd(b,(ZWc(),VWc))));a.e=tXc(BD(hkd(b,WWc),293));a.a=gWc(BD(hkd(b,YWc),426));a.b=jXc(BD(hkd(b,RWc),340));BXc(a);c.n&&!!b&&Tdd(c,i6d(b),(pgd(),mgd))} +function Fqd(a,b,c){var d,e,f,g,h,j,k,l;if(c){f=c.a.length;d=new Yge(f);for(h=(d.b-d.a)*d.c<0?(Xge(),Wge):new she(d);h.Ob();){g=BD(h.Pb(),19);e=Zpd(c,g.a);!!e&&(i=null,j=Uqd(a,(k=(Fhd(),l=new ppd,l),!!b&&npd(k,b),k),e),Lkd(j,_pd(e,Vte)),grd(e,j),hrd(e,j),crd(a,e,j))}}} +function UKd(a){var b,c,d,e,f,g;if(!a.j){g=new HPd;b=KKd;f=b.a.zc(a,b);if(f==null){for(d=new Fyd(_Kd(a));d.e!=d.i.gc();){c=BD(Dyd(d),26);e=UKd(c);ytd(g,e);wtd(g,c)}b.a.Bc(a)!=null}vud(g);a.j=new nNd((BD(qud(ZKd((NFd(),MFd).o),11),18),g.i),g.g);$Kd(a).b&=-33}return a.j} +function O9d(a){var b,c,d,e;if(a==null){return null}else{d=Qge(a,true);e=Nwe.length;if(dfb(d.substr(d.length-e,e),Nwe)){c=d.length;if(c==4){b=(BCb(0,d.length),d.charCodeAt(0));if(b==43){return z9d}else if(b==45){return y9d}}else if(c==3){return z9d}}return new Odb(d)}} +function _C(a){var b,c,d;c=a.l;if((c&c-1)!=0){return -1}d=a.m;if((d&d-1)!=0){return -1}b=a.h;if((b&b-1)!=0){return -1}if(b==0&&d==0&&c==0){return -1}if(b==0&&d==0&&c!=0){return ieb(c)}if(b==0&&d!=0&&c==0){return ieb(d)+22}if(b!=0&&d==0&&c==0){return ieb(b)+44}return -1} +function qbc(a,b){var c,d,e,f,g;Odd(b,'Edge joining',1);c=Ccb(DD(vNb(a,(Nyc(),Byc))));for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),29);g=new Bib(d.a,0);while(g.b<g.d.gc()){f=(sCb(g.b<g.d.gc()),BD(g.d.Xb(g.c=g.b++),10));if(f.k==(j0b(),g0b)){sbc(f,c);uib(g)}}}Qdd(b)} +function c_c(a,b,c){var d,e;H2c(a.b);K2c(a.b,(Y$c(),V$c),(R0c(),Q0c));K2c(a.b,W$c,b.g);K2c(a.b,X$c,b.a);a.a=F2c(a.b,b);Odd(c,'Compaction by shrinking a tree',a.a.c.length);if(b.i.c.length>1){for(e=new olb(a.a);e.a<e.c.c.length;){d=BD(mlb(e),51);d.pf(b,Udd(c,1))}}Qdd(c)} +function mo(a,b){var c,d,e,f,g;e=b.a&a.f;f=null;for(d=a.b[e];true;d=d.b){if(d==b){!f?(a.b[e]=b.b):(f.b=b.b);break}f=d}g=b.f&a.f;f=null;for(c=a.c[g];true;c=c.d){if(c==b){!f?(a.c[g]=b.d):(f.d=b.d);break}f=c}!b.e?(a.a=b.c):(b.e.c=b.c);!b.c?(a.e=b.e):(b.c.e=b.e);--a.i;++a.g} +function eNb(a){var b,c,d,e,f,g,h,i,j,k;c=a.o;b=a.p;g=Ohe;e=Rie;h=Ohe;f=Rie;for(j=0;j<c;++j){for(k=0;k<b;++k){if(YMb(a,j,k)){g=$wnd.Math.min(g,j);e=$wnd.Math.max(e,j);h=$wnd.Math.min(h,k);f=$wnd.Math.max(f,k)}}}i=e-g+1;d=f-h+1;return new Ggd(meb(g),meb(h),meb(i),meb(d))} +function DWb(a,b){var c,d,e,f;f=new Bib(a,0);c=(sCb(f.b<f.d.gc()),BD(f.d.Xb(f.c=f.b++),140));while(f.b<f.d.gc()){d=(sCb(f.b<f.d.gc()),BD(f.d.Xb(f.c=f.b++),140));e=new dWb(d.c,c.d,b);sCb(f.b>0);f.a.Xb(f.c=--f.b);Aib(f,e);sCb(f.b<f.d.gc());f.d.Xb(f.c=f.b++);e.a=false;c=d}} +function Y2b(a){var b,c,d,e,f,g;e=BD(vNb(a,(wtc(),vsc)),11);for(g=new olb(a.j);g.a<g.c.c.length;){f=BD(mlb(g),11);for(d=new olb(f.g);d.a<d.c.c.length;){b=BD(mlb(d),17);RZb(b,e);return f}for(c=new olb(f.e);c.a<c.c.c.length;){b=BD(mlb(c),17);QZb(b,e);return f}}return null} +function iA(a,b,c){var d,e;d=Cbb(c.q.getTime());if(ybb(d,0)<0){e=_ie-Tbb(Hbb(Jbb(d),_ie));e==_ie&&(e=0)}else{e=Tbb(Hbb(d,_ie))}if(b==1){e=$wnd.Math.min((e+50)/100|0,9);Kfb(a,48+e&aje)}else if(b==2){e=$wnd.Math.min((e+5)/10|0,99);EA(a,e,2)}else{EA(a,e,3);b>3&&EA(a,0,b-3)}} +function cUb(a){var b,c,d,e;if(PD(vNb(a,(Nyc(),axc)))===PD((hbd(),ebd))){return !a.e&&PD(vNb(a,Cwc))!==PD((Xrc(),Urc))}d=BD(vNb(a,Dwc),292);e=Ccb(DD(vNb(a,Hwc)))||PD(vNb(a,Iwc))===PD((Rpc(),Opc));b=BD(vNb(a,Bwc),19).a;c=a.a.c.length;return !e&&d!=(Xrc(),Urc)&&(b==0||b>c)} +function lkc(a){var b,c;c=0;for(;c<a.c.length;c++){if(Ojc((tCb(c,a.c.length),BD(a.c[c],113)))>0){break}}if(c>0&&c<a.c.length-1){return c}b=0;for(;b<a.c.length;b++){if(Ojc((tCb(b,a.c.length),BD(a.c[b],113)))>0){break}}if(b>0&&c<a.c.length-1){return b}return a.c.length/2|0} +function mmd(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=6&&!!b){if(p6d(a,b))throw vbb(new Wdb(ste+qmd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?cmd(a,d):a.Cb.ih(a,-1-c,null,d)));!!b&&(d=kid(b,a,6,d));d=bmd(a,b,d);!!d&&d.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,6,b,b))} +function npd(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=9&&!!b){if(p6d(a,b))throw vbb(new Wdb(ste+opd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?lpd(a,d):a.Cb.ih(a,-1-c,null,d)));!!b&&(d=kid(b,a,9,d));d=kpd(a,b,d);!!d&&d.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,9,b,b))} +function Rld(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=3&&!!b){if(p6d(a,b))throw vbb(new Wdb(ste+Sld(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?Lld(a,d):a.Cb.ih(a,-1-c,null,d)));!!b&&(d=kid(b,a,12,d));d=Kld(a,b,d);!!d&&d.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,3,b,b))} +function VId(b){var c,d,e,f,g;e=wId(b);g=b.j;if(g==null&&!!e){return b.$j()?null:e.zj()}else if(JD(e,148)){d=e.Aj();if(d){f=d.Nh();if(f!=b.i){c=BD(e,148);if(c.Ej()){try{b.g=f.Kh(c,g)}catch(a){a=ubb(a);if(JD(a,78)){b.g=null}else throw vbb(a)}}b.i=f}}return b.g}return null} +function wOb(a){var b;b=new Rkb;Ekb(b,new aDb(new f7c(a.c,a.d),new f7c(a.c+a.b,a.d)));Ekb(b,new aDb(new f7c(a.c,a.d),new f7c(a.c,a.d+a.a)));Ekb(b,new aDb(new f7c(a.c+a.b,a.d+a.a),new f7c(a.c+a.b,a.d)));Ekb(b,new aDb(new f7c(a.c+a.b,a.d+a.a),new f7c(a.c,a.d+a.a)));return b} +function IJc(a,b,c,d){var e,f,g;g=LZb(b,c);d.c[d.c.length]=b;if(a.j[g.p]==-1||a.j[g.p]==2||a.a[b.p]){return d}a.j[g.p]=-1;for(f=new Sr(ur(O_b(g).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);if(!(!OZb(e)&&!(!OZb(e)&&e.c.i.c==e.d.i.c))||e==b){continue}return IJc(a,e,g,d)}return d} +function vQb(a,b,c){var d,e,f;for(f=b.a.ec().Kc();f.Ob();){e=BD(f.Pb(),79);d=BD(Ohb(a.b,e),266);!d&&(Xod(jtd(e))==Xod(ltd(e))?uQb(a,e,c):jtd(e)==Xod(ltd(e))?Ohb(a.c,e)==null&&Ohb(a.b,ltd(e))!=null&&xQb(a,e,c,false):Ohb(a.d,e)==null&&Ohb(a.b,jtd(e))!=null&&xQb(a,e,c,true))}} +function jcc(a,b){var c,d,e,f,g,h,i;for(e=a.Kc();e.Ob();){d=BD(e.Pb(),10);h=new H0b;F0b(h,d);G0b(h,(Ucd(),zcd));yNb(h,(wtc(),ftc),(Bcb(),true));for(g=b.Kc();g.Ob();){f=BD(g.Pb(),10);i=new H0b;F0b(i,f);G0b(i,Tcd);yNb(i,ftc,true);c=new UZb;yNb(c,ftc,true);QZb(c,h);RZb(c,i)}}} +function jnc(a,b,c,d){var e,f,g,h;e=hnc(a,b,c);f=hnc(a,c,b);g=BD(Ohb(a.c,b),112);h=BD(Ohb(a.c,c),112);if(e<f){new DOc((HOc(),GOc),g,h,f-e)}else if(f<e){new DOc((HOc(),GOc),h,g,e-f)}else if(e!=0||!(!b.i||!c.i)&&d[b.i.c][c.i.c]){new DOc((HOc(),GOc),g,h,0);new DOc(GOc,h,g,0)}} +function Qoc(a,b){var c,d,e,f,g,h,i;e=0;for(g=new olb(b.a);g.a<g.c.c.length;){f=BD(mlb(g),10);e+=f.o.b+f.d.a+f.d.d+a.e;for(d=new Sr(ur(R_b(f).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);if(c.c.i.k==(j0b(),i0b)){i=c.c.i;h=BD(vNb(i,(wtc(),$sc)),10);e+=h.o.b+h.d.a+h.d.d}}}return e} +function WNc(a,b,c){var d,e,f,g,h,i,j;f=new Rkb;j=new Psb;g=new Psb;XNc(a,j,g,b);VNc(a,j,g,b,c);for(i=new olb(a);i.a<i.c.c.length;){h=BD(mlb(i),112);for(e=new olb(h.k);e.a<e.c.c.length;){d=BD(mlb(e),129);(!b||d.c==(HOc(),FOc))&&h.g>d.b.g&&(f.c[f.c.length]=d,true)}}return f} +function k$c(){k$c=ccb;g$c=new l$c('CANDIDATE_POSITION_LAST_PLACED_RIGHT',0);f$c=new l$c('CANDIDATE_POSITION_LAST_PLACED_BELOW',1);i$c=new l$c('CANDIDATE_POSITION_WHOLE_DRAWING_RIGHT',2);h$c=new l$c('CANDIDATE_POSITION_WHOLE_DRAWING_BELOW',3);j$c=new l$c('WHOLE_DRAWING',4)} +function Xqd(a,b){if(JD(b,239)){return iqd(a,BD(b,33))}else if(JD(b,186)){return jqd(a,BD(b,118))}else if(JD(b,354)){return hqd(a,BD(b,137))}else if(JD(b,352)){return gqd(a,BD(b,79))}else if(b){return null}else{throw vbb(new Wdb(Xte+Fe(new amb(OC(GC(SI,1),Uhe,1,5,[b])))))}} +function aic(a){var b,c,d,e,f,g,h;f=new Psb;for(e=new olb(a.d.a);e.a<e.c.c.length;){d=BD(mlb(e),121);d.b.a.c.length==0&&(Gsb(f,d,f.c.b,f.c),true)}if(f.b>1){b=nGb((c=new pGb,++a.b,c),a.d);for(h=Jsb(f,0);h.b!=h.d.c;){g=BD(Xsb(h),121);AFb(DFb(CFb(EFb(BFb(new FFb,1),0),b),g))}}} +function $od(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=11&&!!b){if(p6d(a,b))throw vbb(new Wdb(ste+_od(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?Uod(a,d):a.Cb.ih(a,-1-c,null,d)));!!b&&(d=kid(b,a,10,d));d=Tod(a,b,d);!!d&&d.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,11,b,b))} +function uZb(a){var b,c,d,e;for(d=new nib((new eib(a.b)).a);d.b;){c=lib(d);e=BD(c.cd(),11);b=BD(c.dd(),10);yNb(b,(wtc(),$sc),e);yNb(e,gtc,b);yNb(e,Nsc,(Bcb(),true));G0b(e,BD(vNb(b,Hsc),61));vNb(b,Hsc);yNb(e.i,(Nyc(),Vxc),(dcd(),acd));BD(vNb(Q_b(e.i),Ksc),21).Fc((Orc(),Krc))}} +function G4b(a,b,c){var d,e,f,g,h,i;f=0;g=0;if(a.c){for(i=new olb(a.d.i.j);i.a<i.c.c.length;){h=BD(mlb(i),11);f+=h.e.c.length}}else{f=1}if(a.d){for(i=new olb(a.c.i.j);i.a<i.c.c.length;){h=BD(mlb(i),11);g+=h.g.c.length}}else{g=1}e=QD(Eeb(g-f));d=(c+b)/2+(c-b)*(0.4*e);return d} +function Zjc(a){Xjc();var b,c;if(a.Hc((Ucd(),Scd))){throw vbb(new Wdb('Port sides must not contain UNDEFINED'))}switch(a.gc()){case 1:return Tjc;case 2:b=a.Hc(zcd)&&a.Hc(Tcd);c=a.Hc(Acd)&&a.Hc(Rcd);return b||c?Wjc:Vjc;case 3:return Ujc;case 4:return Sjc;default:return null;}} +function Hoc(a,b,c){var d,e,f,g,h;Odd(c,'Breaking Point Removing',1);a.a=BD(vNb(b,(Nyc(),Swc)),218);for(f=new olb(b.b);f.a<f.c.c.length;){e=BD(mlb(f),29);for(h=new olb(Mu(e.a));h.a<h.c.c.length;){g=BD(mlb(h),10);if(hoc(g)){d=BD(vNb(g,(wtc(),usc)),305);!d.d&&Ioc(a,d)}}}Qdd(c)} +function s6c(a,b,c){i6c();if(m6c(a,b)&&m6c(a,c)){return false}return u6c(new f7c(a.c,a.d),new f7c(a.c+a.b,a.d),b,c)||u6c(new f7c(a.c+a.b,a.d),new f7c(a.c+a.b,a.d+a.a),b,c)||u6c(new f7c(a.c+a.b,a.d+a.a),new f7c(a.c,a.d+a.a),b,c)||u6c(new f7c(a.c,a.d+a.a),new f7c(a.c,a.d),b,c)} +function x1d(a,b){var c,d,e,f;if(!a.dc()){for(c=0,d=a.gc();c<d;++c){f=GD(a.Xb(c));if(f==null?b==null:dfb(f.substr(0,3),'!##')?b!=null&&(e=b.length,!dfb(f.substr(f.length-e,e),b)||f.length!=b.length+3)&&!dfb(Ewe,b):dfb(f,Fwe)&&!dfb(Ewe,b)||dfb(f,b)){return true}}}return false} +function J3b(a,b,c,d){var e,f,g,h,i,j;g=a.j.c.length;i=KC(tN,ile,306,g,0,1);for(h=0;h<g;h++){f=BD(Ikb(a.j,h),11);f.p=h;i[h]=D3b(N3b(f),c,d)}F3b(a,i,c,b,d);j=new Lqb;for(e=0;e<i.length;e++){!!i[e]&&Rhb(j,BD(Ikb(a.j,e),11),i[e])}if(j.f.c+j.g.c!=0){yNb(a,(wtc(),Csc),j);L3b(a,i)}} +function Lgc(a,b,c){var d,e,f;for(e=new olb(a.a.b);e.a<e.c.c.length;){d=BD(mlb(e),57);f=tgc(d);if(f){if(f.k==(j0b(),e0b)){switch(BD(vNb(f,(wtc(),Hsc)),61).g){case 4:f.n.a=b.a;break;case 2:f.n.a=c.a-(f.o.a+f.d.c);break;case 1:f.n.b=b.b;break;case 3:f.n.b=c.b-(f.o.b+f.d.a);}}}}} +function kAc(){kAc=ccb;iAc=new lAc(ane,0);dAc=new lAc('NIKOLOV',1);gAc=new lAc('NIKOLOV_PIXEL',2);eAc=new lAc('NIKOLOV_IMPROVED',3);fAc=new lAc('NIKOLOV_IMPROVED_PIXEL',4);cAc=new lAc('DUMMYNODE_PERCENTAGE',5);hAc=new lAc('NODECOUNT_PERCENTAGE',6);jAc=new lAc('NO_BOUNDARY',7)} +function led(a,b,c){var d,e,f,g,h;e=BD(hkd(b,(X7c(),V7c)),19);!e&&(e=meb(0));f=BD(hkd(c,V7c),19);!f&&(f=meb(0));if(e.a>f.a){return -1}else if(e.a<f.a){return 1}else{if(a.a){d=Kdb(b.j,c.j);if(d!=0){return d}d=Kdb(b.i,c.i);if(d!=0){return d}}g=b.g*b.f;h=c.g*c.f;return Kdb(g,h)}} +function BAd(a,b){var c,d,e,f,g,h,i,j,k,l;++a.e;i=a.d==null?0:a.d.length;if(b>i){k=a.d;a.d=KC(y4,jve,63,2*i+4,0,1);for(f=0;f<i;++f){j=k[f];if(j){d=j.g;l=j.i;for(h=0;h<l;++h){e=BD(d[h],133);g=DAd(a,e.Sh());c=a.d[g];!c&&(c=a.d[g]=a.uj());c.Fc(e)}}}return true}else{return false}} +function o2d(a,b,c){var d,e,f,g,h,i;e=c;f=e.ak();if(T6d(a.e,f)){if(f.hi()){d=BD(a.g,119);for(g=0;g<a.i;++g){h=d[g];if(pb(h,e)&&g!=b){throw vbb(new Wdb(kue))}}}}else{i=S6d(a.e.Tg(),f);d=BD(a.g,119);for(g=0;g<a.i;++g){h=d[g];if(i.rl(h.ak())){throw vbb(new Wdb(Hwe))}}}vtd(a,b,c)} +function OYb(a,b){var c,d,e,f,g,h;c=BD(vNb(b,(wtc(),Esc)),21);g=BD(Qc((xXb(),wXb),c),21);h=BD(Qc(LYb,c),21);for(f=g.Kc();f.Ob();){d=BD(f.Pb(),21);if(!BD(Qc(a.b,d),15).dc()){return false}}for(e=h.Kc();e.Ob();){d=BD(e.Pb(),21);if(!BD(Qc(a.b,d),15).dc()){return false}}return true} +function scc(a,b){var c,d,e,f,g,h;Odd(b,'Partition postprocessing',1);for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),29);for(f=new olb(c.a);f.a<f.c.c.length;){e=BD(mlb(f),10);h=new olb(e.j);while(h.a<h.c.c.length){g=BD(mlb(h),11);Ccb(DD(vNb(g,(wtc(),ftc))))&&nlb(h)}}}Qdd(b)} +function ZZc(a,b){var c,d,e,f,g,h,i,j,k;if(a.a.c.length==1){return JZc(BD(Ikb(a.a,0),187),b)}g=YZc(a);i=0;j=a.d;f=g;k=a.d;h=(j-f)/2+f;while(f+1<j){i=0;for(d=new olb(a.a);d.a<d.c.c.length;){c=BD(mlb(d),187);i+=(e=MZc(c,h,false),e.a)}if(i<b){k=h;j=h}else{f=h}h=(j-f)/2+f}return k} +function fD(a){var b,c,d,e,f;if(isNaN(a)){return wD(),vD}if(a<-9223372036854775808){return wD(),tD}if(a>=9223372036854775807){return wD(),sD}e=false;if(a<0){e=true;a=-a}d=0;if(a>=Ije){d=QD(a/Ije);a-=d*Ije}c=0;if(a>=Hje){c=QD(a/Hje);a-=c*Hje}b=QD(a);f=TC(b,c,d);e&&ZC(f);return f} +function rKb(a,b){var c,d,e,f;c=!b||!a.u.Hc((rcd(),ncd));f=0;for(e=new olb(a.e.Cf());e.a<e.c.c.length;){d=BD(mlb(e),838);if(d.Hf()==(Ucd(),Scd)){throw vbb(new Wdb('Label and node size calculator can only be used with ports that have port sides assigned.'))}d.vf(f++);qKb(a,d,c)}} +function V0d(a,b){var c,d,e,f,g;e=b.Hh(a.a);if(e){d=(!e.b&&(e.b=new sId((jGd(),fGd),x6,e)),e.b);c=GD(AAd(d,cwe));if(c!=null){f=c.lastIndexOf('#');g=f==-1?w1d(a,b.Aj(),c):f==0?v1d(a,null,c.substr(1)):v1d(a,c.substr(0,f),c.substr(f+1));if(JD(g,148)){return BD(g,148)}}}return null} +function Z0d(a,b){var c,d,e,f,g;d=b.Hh(a.a);if(d){c=(!d.b&&(d.b=new sId((jGd(),fGd),x6,d)),d.b);f=GD(AAd(c,zwe));if(f!=null){e=f.lastIndexOf('#');g=e==-1?w1d(a,b.Aj(),f):e==0?v1d(a,null,f.substr(1)):v1d(a,f.substr(0,e),f.substr(e+1));if(JD(g,148)){return BD(g,148)}}}return null} +function RDb(a){var b,c,d,e,f;for(c=new olb(a.a.a);c.a<c.c.c.length;){b=BD(mlb(c),307);b.j=null;for(f=b.a.a.ec().Kc();f.Ob();){d=BD(f.Pb(),57);X6c(d.b);(!b.j||d.d.c<b.j.d.c)&&(b.j=d)}for(e=b.a.a.ec().Kc();e.Ob();){d=BD(e.Pb(),57);d.b.a=d.d.c-b.j.d.c;d.b.b=d.d.d-b.j.d.d}}return a} +function sVb(a){var b,c,d,e,f;for(c=new olb(a.a.a);c.a<c.c.c.length;){b=BD(mlb(c),189);b.f=null;for(f=b.a.a.ec().Kc();f.Ob();){d=BD(f.Pb(),81);X6c(d.e);(!b.f||d.g.c<b.f.g.c)&&(b.f=d)}for(e=b.a.a.ec().Kc();e.Ob();){d=BD(e.Pb(),81);d.e.a=d.g.c-b.f.g.c;d.e.b=d.g.d-b.f.g.d}}return a} +function EMb(a){var b,c,d;c=BD(a.a,19).a;d=BD(a.b,19).a;b=$wnd.Math.max($wnd.Math.abs(c),$wnd.Math.abs(d));if(c<b&&d==-b){return new vgd(meb(c+1),meb(d))}if(c==b&&d<b){return new vgd(meb(c),meb(d+1))}if(c>=-b&&d==b){return new vgd(meb(c-1),meb(d))}return new vgd(meb(c),meb(d-1))} +function W8b(){S8b();return OC(GC(AS,1),Kie,77,0,[Y7b,V7b,Z7b,n8b,G8b,r8b,M8b,w8b,E8b,i8b,A8b,v8b,F8b,e8b,O8b,P7b,z8b,I8b,o8b,H8b,Q8b,C8b,Q7b,D8b,R8b,K8b,P8b,p8b,b8b,q8b,m8b,N8b,T7b,_7b,t8b,S7b,u8b,k8b,f8b,x8b,h8b,W7b,U7b,l8b,g8b,y8b,L8b,R7b,B8b,j8b,s8b,c8b,a8b,J8b,$7b,d8b,X7b])} +function Yic(a,b,c){a.d=0;a.b=0;b.k==(j0b(),i0b)&&c.k==i0b&&BD(vNb(b,(wtc(),$sc)),10)==BD(vNb(c,$sc),10)&&(ajc(b).j==(Ucd(),Acd)?Zic(a,b,c):Zic(a,c,b));b.k==i0b&&c.k==g0b?ajc(b).j==(Ucd(),Acd)?(a.d=1):(a.b=1):c.k==i0b&&b.k==g0b&&(ajc(c).j==(Ucd(),Acd)?(a.b=1):(a.d=1));cjc(a,b,c)} +function esd(a){var b,c,d,e,f,g,h,i,j,k,l;l=hsd(a);b=a.a;i=b!=null;i&&Upd(l,'category',a.a);e=Fhe(new Pib(a.d));g=!e;if(g){j=new wB;cC(l,'knownOptions',j);c=new msd(j);reb(new Pib(a.d),c)}f=Fhe(a.g);h=!f;if(h){k=new wB;cC(l,'supportedFeatures',k);d=new osd(k);reb(a.g,d)}return l} +function ty(a){var b,c,d,e,f,g,h,i,j;d=false;b=336;c=0;f=new Xp(a.length);for(h=a,i=0,j=h.length;i<j;++i){g=h[i];d=d|(Uzb(g),false);e=(Tzb(g),g.a);Ekb(f.a,Qb(e));b&=e.qd();c=Ly(c,e.rd())}return BD(BD(Rzb(new YAb(null,Yj(new Kub((im(),nm(f.a)),16),new vy,b,c)),new xy(a)),670),833)} +function UWb(a,b){var c;if(!!a.d&&(b.c!=a.e.c||qWb(a.e.b,b.b))){Ekb(a.f,a.d);a.a=a.d.c+a.d.b;a.d=null;a.e=null}nWb(b.b)?(a.c=b):(a.b=b);if(b.b==(lWb(),hWb)&&!b.a||b.b==iWb&&b.a||b.b==jWb&&b.a||b.b==kWb&&!b.a){if(!!a.c&&!!a.b){c=new J6c(a.a,a.c.d,b.c-a.a,a.b.d-a.c.d);a.d=c;a.e=b}}} +function L2c(a){var b;D2c.call(this);this.i=new Z2c;this.g=a;this.f=BD(a.e&&a.e(),9).length;if(this.f==0){throw vbb(new Wdb('There must be at least one phase in the phase enumeration.'))}this.c=(b=BD(gdb(this.g),9),new xqb(b,BD(_Bb(b,b.length),9),0));this.a=new j3c;this.b=new Lqb} +function God(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=7&&!!b){if(p6d(a,b))throw vbb(new Wdb(ste+Iod(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?Eod(a,d):a.Cb.ih(a,-1-c,null,d)));!!b&&(d=BD(b,49).gh(a,1,C2,d));d=Dod(a,b,d);!!d&&d.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,7,b,b))} +function NHd(a,b){var c,d;if(b!=a.Cb||a.Db>>16!=3&&!!b){if(p6d(a,b))throw vbb(new Wdb(ste+QHd(a)));d=null;!!a.Cb&&(d=(c=a.Db>>16,c>=0?KHd(a,d):a.Cb.ih(a,-1-c,null,d)));!!b&&(d=BD(b,49).gh(a,0,k5,d));d=JHd(a,b,d);!!d&&d.Fi()}else (a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,3,b,b))} +function Ehb(a,b){Dhb();var c,d,e,f,g,h,i,j,k;if(b.d>a.d){h=a;a=b;b=h}if(b.d<63){return Ihb(a,b)}g=(a.d&-2)<<4;j=Rgb(a,g);k=Rgb(b,g);d=yhb(a,Qgb(j,g));e=yhb(b,Qgb(k,g));i=Ehb(j,k);c=Ehb(d,e);f=Ehb(yhb(j,d),yhb(e,k));f=thb(thb(f,i),c);f=Qgb(f,g);i=Qgb(i,g<<1);return thb(thb(i,f),c)} +function aGc(a,b,c){var d,e,f,g,h;g=CHc(a,c);h=KC(OQ,kne,10,b.length,0,1);d=0;for(f=g.Kc();f.Ob();){e=BD(f.Pb(),11);Ccb(DD(vNb(e,(wtc(),Nsc))))&&(h[d++]=BD(vNb(e,gtc),10))}if(d<b.length){throw vbb(new Zdb('Expected '+b.length+' hierarchical ports, but found only '+d+'.'))}return h} +function Und(a,b){var c,d,e,f,g,h;if(!a.tb){f=(!a.rb&&(a.rb=new jUd(a,d5,a)),a.rb);h=new Mqb(f.i);for(e=new Fyd(f);e.e!=e.i.gc();){d=BD(Dyd(e),138);g=d.ne();c=BD(g==null?jrb(h.f,null,d):Drb(h.g,g,d),138);!!c&&(g==null?jrb(h.f,null,c):Drb(h.g,g,c))}a.tb=h}return BD(Phb(a.tb,b),138)} +function YKd(a,b){var c,d,e,f,g;(a.i==null&&TKd(a),a.i).length;if(!a.p){g=new Mqb((3*a.g.i/2|0)+1);for(e=new $yd(a.g);e.e!=e.i.gc();){d=BD(Zyd(e),170);f=d.ne();c=BD(f==null?jrb(g.f,null,d):Drb(g.g,f,d),170);!!c&&(f==null?jrb(g.f,null,c):Drb(g.g,f,c))}a.p=g}return BD(Phb(a.p,b),170)} +function hCb(a,b,c,d,e){var f,g,h,i,j;fCb(d+Wy(c,c.$d()),e);gCb(b,jCb(c));f=c.f;!!f&&hCb(a,b,f,'Caused by: ',false);for(h=(c.k==null&&(c.k=KC(_I,nie,78,0,0,1)),c.k),i=0,j=h.length;i<j;++i){g=h[i];hCb(a,b,g,'Suppressed: ',false)}console.groupEnd!=null&&console.groupEnd.call(console)} +function dGc(a,b,c,d){var e,f,g,h,i;i=b.e;h=i.length;g=b.q._f(i,c?0:h-1,c);e=i[c?0:h-1];g=g|cGc(a,e,c,d);for(f=c?1:h-2;c?f<h:f>=0;f+=c?1:-1){g=g|b.c.Sf(i,f,c,d&&!Ccb(DD(vNb(b.j,(wtc(),Jsc))))&&!Ccb(DD(vNb(b.j,(wtc(),mtc)))));g=g|b.q._f(i,f,c);g=g|cGc(a,i[f],c,d)}Qqb(a.c,b);return g} +function o3b(a,b,c){var d,e,f,g,h,i,j,k,l,m;for(k=m_b(a.j),l=0,m=k.length;l<m;++l){j=k[l];if(c==(KAc(),HAc)||c==JAc){i=k_b(j.g);for(e=i,f=0,g=e.length;f<g;++f){d=e[f];k3b(b,d)&&PZb(d,true)}}if(c==IAc||c==JAc){h=k_b(j.e);for(e=h,f=0,g=e.length;f<g;++f){d=e[f];j3b(b,d)&&PZb(d,true)}}}} +function Qmc(a){var b,c;b=null;c=null;switch(Lmc(a).g){case 1:b=(Ucd(),zcd);c=Tcd;break;case 2:b=(Ucd(),Rcd);c=Acd;break;case 3:b=(Ucd(),Tcd);c=zcd;break;case 4:b=(Ucd(),Acd);c=Rcd;}mjc(a,BD(Btb(RAb(BD(Qc(a.k,b),15).Oc(),Hmc)),113));njc(a,BD(Btb(QAb(BD(Qc(a.k,c),15).Oc(),Hmc)),113))} +function a6b(a){var b,c,d,e,f,g;e=BD(Ikb(a.j,0),11);if(e.e.c.length+e.g.c.length==0){a.n.a=0}else{g=0;for(d=ul(pl(OC(GC(KI,1),Uhe,20,0,[new J0b(e),new R0b(e)])));Qr(d);){c=BD(Rr(d),11);g+=c.i.n.a+c.n.a+c.a.a}b=BD(vNb(a,(Nyc(),Txc)),8);f=!b?0:b.a;a.n.a=g/(e.e.c.length+e.g.c.length)-f}} +function F1c(a,b){var c,d,e;for(d=new olb(b.a);d.a<d.c.c.length;){c=BD(mlb(d),221);$Nb(BD(c.b,65),c7c(R6c(BD(b.b,65).c),BD(b.b,65).a));e=xOb(BD(b.b,65).b,BD(c.b,65).b);e>1&&(a.a=true);ZNb(BD(c.b,65),P6c(R6c(BD(b.b,65).c),Y6c(c7c(R6c(BD(c.b,65).a),BD(b.b,65).a),e)));D1c(a,b);F1c(a,c)}} +function rVb(a){var b,c,d,e,f,g,h;for(f=new olb(a.a.a);f.a<f.c.c.length;){d=BD(mlb(f),189);d.e=0;d.d.a.$b()}for(e=new olb(a.a.a);e.a<e.c.c.length;){d=BD(mlb(e),189);for(c=d.a.a.ec().Kc();c.Ob();){b=BD(c.Pb(),81);for(h=b.f.Kc();h.Ob();){g=BD(h.Pb(),81);if(g.d!=d){Qqb(d.d,g);++g.d.e}}}}} +function bcc(a){var b,c,d,e,f,g,h,i;i=a.j.c.length;c=0;b=i;e=2*i;for(h=new olb(a.j);h.a<h.c.c.length;){g=BD(mlb(h),11);switch(g.j.g){case 2:case 4:g.p=-1;break;case 1:case 3:d=g.e.c.length;f=g.g.c.length;d>0&&f>0?(g.p=b++):d>0?(g.p=c++):f>0?(g.p=e++):(g.p=c++);}}mmb();Okb(a.j,new fcc)} +function Vec(a){var b,c;c=null;b=BD(Ikb(a.g,0),17);do{c=b.d.i;if(wNb(c,(wtc(),Wsc))){return BD(vNb(c,Wsc),11).i}if(c.k!=(j0b(),h0b)&&Qr(new Sr(ur(U_b(c).a.Kc(),new Sq)))){b=BD(Rr(new Sr(ur(U_b(c).a.Kc(),new Sq))),17)}else if(c.k!=h0b){return null}}while(!!c&&c.k!=(j0b(),h0b));return c} +function Omc(a,b){var c,d,e,f,g,h,i,j,k;h=b.j;g=b.g;i=BD(Ikb(h,h.c.length-1),113);k=(tCb(0,h.c.length),BD(h.c[0],113));j=Kmc(a,g,i,k);for(f=1;f<h.c.length;f++){c=(tCb(f-1,h.c.length),BD(h.c[f-1],113));e=(tCb(f,h.c.length),BD(h.c[f],113));d=Kmc(a,g,c,e);if(d>j){i=c;k=e;j=d}}b.a=k;b.c=i} +function sEb(a,b){var c,d;d=Axb(a.b,b.b);if(!d){throw vbb(new Zdb('Invalid hitboxes for scanline constraint calculation.'))}(mEb(b.b,BD(Cxb(a.b,b.b),57))||mEb(b.b,BD(Bxb(a.b,b.b),57)))&&(Zfb(),b.b+' has overlap.');a.a[b.b.f]=BD(Exb(a.b,b.b),57);c=BD(Dxb(a.b,b.b),57);!!c&&(a.a[c.f]=b.b)} +function AFb(a){if(!a.a.d||!a.a.e){throw vbb(new Zdb((fdb(fN),fN.k+' must have a source and target '+(fdb(jN),jN.k)+' specified.')))}if(a.a.d==a.a.e){throw vbb(new Zdb('Network simplex does not support self-loops: '+a.a+' '+a.a.d+' '+a.a.e))}NFb(a.a.d.g,a.a);NFb(a.a.e.b,a.a);return a.a} +function HHc(a,b,c){var d,e,f,g,h,i,j;j=new Hxb(new tIc(a));for(g=OC(GC(aR,1),lne,11,0,[b,c]),h=0,i=g.length;h<i;++h){f=g[h];Iwb(j.a,f,(Bcb(),zcb))==null;for(e=new b1b(f.b);llb(e.a)||llb(e.b);){d=BD(llb(e.a)?mlb(e.a):mlb(e.b),17);d.c==d.d||Axb(j,f==d.c?d.d:d.c)}}return Qb(j),new Tkb(j)} +function oPc(a,b,c){var d,e,f,g,h,i;d=0;if(b.b!=0&&c.b!=0){f=Jsb(b,0);g=Jsb(c,0);h=Edb(ED(Xsb(f)));i=Edb(ED(Xsb(g)));e=true;do{if(h>i-a.b&&h<i+a.b){return -1}else h>i-a.a&&h<i+a.a&&++d;h<=i&&f.b!=f.d.c?(h=Edb(ED(Xsb(f)))):i<=h&&g.b!=g.d.c?(i=Edb(ED(Xsb(g)))):(e=false)}while(e)}return d} +function F3b(a,b,c,d,e){var f,g,h,i;i=(f=BD(gdb(F1),9),new xqb(f,BD(_Bb(f,f.length),9),0));for(h=new olb(a.j);h.a<h.c.c.length;){g=BD(mlb(h),11);if(b[g.p]){G3b(g,b[g.p],d);rqb(i,g.j)}}if(e){K3b(a,b,(Ucd(),zcd),2*c,d);K3b(a,b,Tcd,2*c,d)}else{K3b(a,b,(Ucd(),Acd),2*c,d);K3b(a,b,Rcd,2*c,d)}} +function Szb(a){var b,c,d,e,f;f=new Rkb;Hkb(a.b,new XBb(f));a.b.c=KC(SI,Uhe,1,0,5,1);if(f.c.length!=0){b=(tCb(0,f.c.length),BD(f.c[0],78));for(c=1,d=f.c.length;c<d;++c){e=(tCb(c,f.c.length),BD(f.c[c],78));e!=b&&Qy(b,e)}if(JD(b,60)){throw vbb(BD(b,60))}if(JD(b,289)){throw vbb(BD(b,289))}}} +function DCb(a,b){var c,d,e,f;a=a==null?Xhe:(uCb(a),a);c=new Vfb;f=0;d=0;while(d<b.length){e=a.indexOf('%s',f);if(e==-1){break}Qfb(c,a.substr(f,e-f));Pfb(c,b[d++]);f=e+2}Qfb(c,a.substr(f));if(d<b.length){c.a+=' [';Pfb(c,b[d++]);while(d<b.length){c.a+=She;Pfb(c,b[d++])}c.a+=']'}return c.a} +function KCb(a){var b,c,d,e;b=0;d=a.length;e=d-4;c=0;while(c<e){b=(BCb(c+3,a.length),a.charCodeAt(c+3)+(BCb(c+2,a.length),31*(a.charCodeAt(c+2)+(BCb(c+1,a.length),31*(a.charCodeAt(c+1)+(BCb(c,a.length),31*(a.charCodeAt(c)+31*b)))))));b=b|0;c+=4}while(c<d){b=b*31+bfb(a,c++)}b=b|0;return b} +function Rac(a){var b,c;for(c=new Sr(ur(U_b(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);if(b.d.i.k!=(j0b(),f0b)){throw vbb(new y2c(Fne+P_b(a)+"' has its layer constraint set to LAST, but has at least one outgoing edge that "+' does not go to a LAST_SEPARATE node. That must not happen.'))}}} +function jQc(a,b,c,d){var e,f,g,h,i,j,k,l,m;i=0;for(k=new olb(a.a);k.a<k.c.c.length;){j=BD(mlb(k),10);h=0;for(f=new Sr(ur(R_b(j).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);l=A0b(e.c).b;m=A0b(e.d).b;h=$wnd.Math.max(h,$wnd.Math.abs(m-l))}i=$wnd.Math.max(i,h)}g=d*$wnd.Math.min(1,b/c)*i;return g} +function See(a){var b;b=new Ifb;(a&256)!=0&&(b.a+='F',b);(a&128)!=0&&(b.a+='H',b);(a&512)!=0&&(b.a+='X',b);(a&2)!=0&&(b.a+='i',b);(a&8)!=0&&(b.a+='m',b);(a&4)!=0&&(b.a+='s',b);(a&32)!=0&&(b.a+='u',b);(a&64)!=0&&(b.a+='w',b);(a&16)!=0&&(b.a+='x',b);(a&zte)!=0&&(b.a+=',',b);return jfb(b.a)} +function F5b(a,b){var c,d,e,f;Odd(b,'Resize child graph to fit parent.',1);for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),29);Gkb(a.a,c.a);c.a.c=KC(SI,Uhe,1,0,5,1)}for(f=new olb(a.a);f.a<f.c.c.length;){e=BD(mlb(f),10);$_b(e,null)}a.b.c=KC(SI,Uhe,1,0,5,1);G5b(a);!!a.e&&E5b(a.e,a);Qdd(b)} +function eec(a){var b,c,d,e,f,g,h,i,j;d=a.b;f=d.e;g=ecd(BD(vNb(d,(Nyc(),Vxc)),98));c=!!f&&BD(vNb(f,(wtc(),Ksc)),21).Hc((Orc(),Hrc));if(g||c){return}for(j=(h=(new $ib(a.e)).a.vc().Kc(),new djb(h));j.a.Ob();){i=(b=BD(j.a.Pb(),42),BD(b.dd(),113));if(i.a){e=i.d;F0b(e,null);i.c=true;a.a=true}}} +function QFc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;m=-1;n=0;for(j=a,k=0,l=j.length;k<l;++k){i=j[k];for(f=i,g=0,h=f.length;g<h;++g){e=f[g];b=new Unc(m==-1?a[0]:a[m],Xec(e));for(c=0;c<e.j.c.length;c++){for(d=c+1;d<e.j.c.length;d++){Rnc(b,BD(Ikb(e.j,c),11),BD(Ikb(e.j,d),11))>0&&++n}}}++m}return n} +function hUc(a,b){var c,d,e,f,g;g=BD(vNb(b,(JTc(),FTc)),425);for(f=Jsb(b.b,0);f.b!=f.d.c;){e=BD(Xsb(f),86);if(a.b[e.g]==0){switch(g.g){case 0:iUc(a,e);break;case 1:gUc(a,e);}a.b[e.g]=2}}for(d=Jsb(a.a,0);d.b!=d.d.c;){c=BD(Xsb(d),188);ze(c.b.d,c,true);ze(c.c.b,c,true)}yNb(b,(mTc(),gTc),a.a)} +function S6d(a,b){Q6d();var c,d,e,f;if(!b){return P6d}else if(b==(Q8d(),N8d)||(b==v8d||b==t8d||b==u8d)&&a!=s8d){return new Z6d(a,b)}else{d=BD(b,677);c=d.pk();if(!c){a2d(q1d((O6d(),M6d),b));c=d.pk()}f=(!c.i&&(c.i=new Lqb),c.i);e=BD(Wd(irb(f.f,a)),1942);!e&&Rhb(f,a,e=new Z6d(a,b));return e}} +function Tbc(a,b){var c,d,e,f,g,h,i,j,k;i=BD(vNb(a,(wtc(),$sc)),11);j=l7c(OC(GC(m1,1),nie,8,0,[i.i.n,i.n,i.a])).a;k=a.i.n.b;c=k_b(a.e);for(e=c,f=0,g=e.length;f<g;++f){d=e[f];RZb(d,i);Fsb(d.a,new f7c(j,k));if(b){h=BD(vNb(d,(Nyc(),jxc)),74);if(!h){h=new s7c;yNb(d,jxc,h)}Dsb(h,new f7c(j,k))}}} +function Ubc(a,b){var c,d,e,f,g,h,i,j,k;e=BD(vNb(a,(wtc(),$sc)),11);j=l7c(OC(GC(m1,1),nie,8,0,[e.i.n,e.n,e.a])).a;k=a.i.n.b;c=k_b(a.g);for(g=c,h=0,i=g.length;h<i;++h){f=g[h];QZb(f,e);Esb(f.a,new f7c(j,k));if(b){d=BD(vNb(f,(Nyc(),jxc)),74);if(!d){d=new s7c;yNb(f,jxc,d)}Dsb(d,new f7c(j,k))}}} +function TFc(a,b){var c,d,e,f,g,h;a.b=new Rkb;a.d=BD(vNb(b,(wtc(),jtc)),230);a.e=Dub(a.d);f=new Psb;e=Ou(OC(GC(KQ,1),cne,37,0,[b]));g=0;while(g<e.c.length){d=(tCb(g,e.c.length),BD(e.c[g],37));d.p=g++;c=new fFc(d,a.a,a.b);Gkb(e,c.b);Ekb(a.b,c);c.s&&(h=Jsb(f,0),Vsb(h,c))}a.c=new Tqb;return f} +function HJb(a,b){var c,d,e,f,g,h;for(g=BD(BD(Qc(a.r,b),21),84).Kc();g.Ob();){f=BD(g.Pb(),111);c=f.c?ZHb(f.c):0;if(c>0){if(f.a){h=f.b.rf().a;if(c>h){e=(c-h)/2;f.d.b=e;f.d.c=e}}else{f.d.c=a.s+c}}else if(tcd(a.u)){d=sfd(f.b);d.c<0&&(f.d.b=-d.c);d.c+d.b>f.b.rf().a&&(f.d.c=d.c+d.b-f.b.rf().a)}}} +function Eec(a,b){var c,d,e,f;Odd(b,'Semi-Interactive Crossing Minimization Processor',1);c=false;for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),29);f=TAb(VAb(JAb(JAb(new YAb(null,new Kub(d.a,16)),new Jec),new Lec),new Nec),new Rec);c=c|f.a!=null}c&&yNb(a,(wtc(),Rsc),(Bcb(),true));Qdd(b)} +function sRc(a,b,c){var d,e,f,g,h;e=c;!e&&(e=new Zdd);Odd(e,'Layout',a.a.c.length);if(Ccb(DD(vNb(b,(JTc(),vTc))))){Zfb();for(d=0;d<a.a.c.length;d++){h=(d<10?'0':'')+d++;' Slot '+h+': '+hdb(rb(BD(Ikb(a.a,d),51)))}}for(g=new olb(a.a);g.a<g.c.c.length;){f=BD(mlb(g),51);f.pf(b,Udd(e,1))}Qdd(e)} +function yMb(a){var b,c;b=BD(a.a,19).a;c=BD(a.b,19).a;if(b>=0){if(b==c){return new vgd(meb(-b-1),meb(-b-1))}if(b==-c){return new vgd(meb(-b),meb(c+1))}}if($wnd.Math.abs(b)>$wnd.Math.abs(c)){if(b<0){return new vgd(meb(-b),meb(c))}return new vgd(meb(-b),meb(c+1))}return new vgd(meb(b+1),meb(c))} +function q5b(a){var b,c;c=BD(vNb(a,(Nyc(),mxc)),163);b=BD(vNb(a,(wtc(),Osc)),303);if(c==(Ctc(),ytc)){yNb(a,mxc,Btc);yNb(a,Osc,(esc(),dsc))}else if(c==Atc){yNb(a,mxc,Btc);yNb(a,Osc,(esc(),bsc))}else if(b==(esc(),dsc)){yNb(a,mxc,ytc);yNb(a,Osc,csc)}else if(b==bsc){yNb(a,mxc,Atc);yNb(a,Osc,csc)}} +function FNc(){FNc=ccb;DNc=new RNc;zNc=e3c(new j3c,(qUb(),nUb),(S8b(),o8b));CNc=c3c(e3c(new j3c,nUb,C8b),pUb,B8b);ENc=b3c(b3c(g3c(c3c(e3c(new j3c,lUb,M8b),pUb,L8b),oUb),K8b),N8b);ANc=c3c(e3c(e3c(e3c(new j3c,mUb,r8b),oUb,t8b),oUb,u8b),pUb,s8b);BNc=c3c(e3c(e3c(new j3c,oUb,u8b),oUb,_7b),pUb,$7b)} +function hQc(){hQc=ccb;cQc=e3c(c3c(new j3c,(qUb(),pUb),(S8b(),c8b)),nUb,o8b);gQc=b3c(b3c(g3c(c3c(e3c(new j3c,lUb,M8b),pUb,L8b),oUb),K8b),N8b);dQc=c3c(e3c(e3c(e3c(new j3c,mUb,r8b),oUb,t8b),oUb,u8b),pUb,s8b);fQc=e3c(e3c(new j3c,nUb,C8b),pUb,B8b);eQc=c3c(e3c(e3c(new j3c,oUb,u8b),oUb,_7b),pUb,$7b)} +function GNc(a,b,c,d,e){var f,g;if((!OZb(b)&&b.c.i.c==b.d.i.c||!T6c(l7c(OC(GC(m1,1),nie,8,0,[e.i.n,e.n,e.a])),c))&&!OZb(b)){b.c==e?St(b.a,0,new g7c(c)):Dsb(b.a,new g7c(c));if(d&&!Rqb(a.a,c)){g=BD(vNb(b,(Nyc(),jxc)),74);if(!g){g=new s7c;yNb(b,jxc,g)}f=new g7c(c);Gsb(g,f,g.c.b,g.c);Qqb(a.a,f)}}} +function Qac(a){var b,c;for(c=new Sr(ur(R_b(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);if(b.c.i.k!=(j0b(),f0b)){throw vbb(new y2c(Fne+P_b(a)+"' has its layer constraint set to FIRST, but has at least one incoming edge that "+' does not come from a FIRST_SEPARATE node. That must not happen.'))}}} +function vjd(a,b,c){var d,e,f,g,h,i,j;e=aeb(a.Db&254);if(e==0){a.Eb=c}else{if(e==1){h=KC(SI,Uhe,1,2,5,1);f=zjd(a,b);if(f==0){h[0]=c;h[1]=a.Eb}else{h[0]=a.Eb;h[1]=c}}else{h=KC(SI,Uhe,1,e+1,5,1);g=CD(a.Eb);for(d=2,i=0,j=0;d<=128;d<<=1){d==b?(h[j++]=c):(a.Db&d)!=0&&(h[j++]=g[i++])}}a.Eb=h}a.Db|=b} +function ENb(a,b,c){var d,e,f,g;this.b=new Rkb;e=0;d=0;for(g=new olb(a);g.a<g.c.c.length;){f=BD(mlb(g),167);c&&rMb(f);Ekb(this.b,f);e+=f.o;d+=f.p}if(this.b.c.length>0){f=BD(Ikb(this.b,0),167);e+=f.o;d+=f.p}e*=2;d*=2;b>1?(e=QD($wnd.Math.ceil(e*b))):(d=QD($wnd.Math.ceil(d/b)));this.a=new pNb(e,d)} +function Igc(a,b,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q,r;k=d;if(b.j&&b.o){n=BD(Ohb(a.f,b.A),57);p=n.d.c+n.d.b;--k}else{p=b.a.c+b.a.b}l=e;if(c.q&&c.o){n=BD(Ohb(a.f,c.C),57);j=n.d.c;++l}else{j=c.a.c}q=j-p;i=$wnd.Math.max(2,l-k);h=q/i;o=p+h;for(m=k;m<l;++m){g=BD(f.Xb(m),128);r=g.a.b;g.a.c=o-r/2;o+=h}} +function UHc(a,b,c,d,e,f){var g,h,i,j,k,l;j=c.c.length;f&&(a.c=KC(WD,oje,25,b.length,15,1));for(g=e?0:b.length-1;e?g<b.length:g>=0;g+=e?1:-1){h=b[g];i=d==(Ucd(),zcd)?e?V_b(h,d):Su(V_b(h,d)):e?Su(V_b(h,d)):V_b(h,d);f&&(a.c[h.p]=i.gc());for(l=i.Kc();l.Ob();){k=BD(l.Pb(),11);a.d[k.p]=j++}Gkb(c,i)}} +function aQc(a,b,c){var d,e,f,g,h,i,j,k;f=Edb(ED(a.b.Kc().Pb()));j=Edb(ED(Pq(b.b)));d=Y6c(R6c(a.a),j-c);e=Y6c(R6c(b.a),c-f);k=P6c(d,e);Y6c(k,1/(j-f));this.a=k;this.b=new Rkb;h=true;g=a.b.Kc();g.Pb();while(g.Ob()){i=Edb(ED(g.Pb()));if(h&&i-c>Oqe){this.b.Fc(c);h=false}this.b.Fc(i)}h&&this.b.Fc(c)} +function vGb(a){var b,c,d,e;yGb(a,a.n);if(a.d.c.length>0){Blb(a.c);while(GGb(a,BD(mlb(new olb(a.e.a)),121))<a.e.a.c.length){b=AGb(a);e=b.e.e-b.d.e-b.a;b.e.j&&(e=-e);for(d=new olb(a.e.a);d.a<d.c.c.length;){c=BD(mlb(d),121);c.j&&(c.e+=e)}Blb(a.c)}Blb(a.c);DGb(a,BD(mlb(new olb(a.e.a)),121));rGb(a)}} +function rkc(a,b){var c,d,e,f,g;for(e=BD(Qc(a.a,(Xjc(),Tjc)),15).Kc();e.Ob();){d=BD(e.Pb(),101);c=BD(Ikb(d.j,0),113).d.j;f=new Tkb(d.j);Okb(f,new Xkc);switch(b.g){case 1:jkc(a,f,c,(Fkc(),Dkc),1);break;case 0:g=lkc(f);jkc(a,new Jib(f,0,g),c,(Fkc(),Dkc),0);jkc(a,new Jib(f,g,f.c.length),c,Dkc,1);}}} +function c2c(a,b){Y1c();var c,d;c=j4c(n4c(),b.tg());if(c){d=c.j;if(JD(a,239)){return Zod(BD(a,33))?uqb(d,(N5c(),K5c))||uqb(d,L5c):uqb(d,(N5c(),K5c))}else if(JD(a,352)){return uqb(d,(N5c(),I5c))}else if(JD(a,186)){return uqb(d,(N5c(),M5c))}else if(JD(a,354)){return uqb(d,(N5c(),J5c))}}return true} +function c3d(a,b,c){var d,e,f,g,h,i;e=c;f=e.ak();if(T6d(a.e,f)){if(f.hi()){d=BD(a.g,119);for(g=0;g<a.i;++g){h=d[g];if(pb(h,e)&&g!=b){throw vbb(new Wdb(kue))}}}}else{i=S6d(a.e.Tg(),f);d=BD(a.g,119);for(g=0;g<a.i;++g){h=d[g];if(i.rl(h.ak())&&g!=b){throw vbb(new Wdb(Hwe))}}}return BD(Gtd(a,b,c),72)} +function Sy(d,b){if(b instanceof Object){try{b.__java$exception=d;if(navigator.userAgent.toLowerCase().indexOf('msie')!=-1&&$doc.documentMode<9){return}var c=d;Object.defineProperties(b,{cause:{get:function(){var a=c.Zd();return a&&a.Xd()}},suppressed:{get:function(){return c.Yd()}}})}catch(a){}}} +function lhb(a,b){var c,d,e,f,g;d=b>>5;b&=31;if(d>=a.d){return a.e<0?(Hgb(),Bgb):(Hgb(),Ggb)}f=a.d-d;e=KC(WD,oje,25,f+1,15,1);mhb(e,f,a.a,d,b);if(a.e<0){for(c=0;c<d&&a.a[c]==0;c++);if(c<d||b>0&&a.a[c]<<32-b!=0){for(c=0;c<f&&e[c]==-1;c++){e[c]=0}c==f&&++f;++e[c]}}g=new Vgb(a.e,f,e);Jgb(g);return g} +function UPb(a){var b,c,d,e;e=mpd(a);c=new kQb(e);d=new mQb(e);b=new Rkb;Gkb(b,(!a.d&&(a.d=new y5d(B2,a,8,5)),a.d));Gkb(b,(!a.e&&(a.e=new y5d(B2,a,7,4)),a.e));return BD(GAb(NAb(JAb(new YAb(null,new Kub(b,16)),c),d),Ayb(new hzb,new jzb,new Gzb,new Izb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Eyb),Dyb]))),21)} +function p2d(a,b,c,d){var e,f,g,h,i;h=(Q6d(),BD(b,66).Oj());if(T6d(a.e,b)){if(b.hi()&&F2d(a,b,d,JD(b,99)&&(BD(b,18).Bb&Tje)!=0)){throw vbb(new Wdb(kue))}}else{i=S6d(a.e.Tg(),b);e=BD(a.g,119);for(g=0;g<a.i;++g){f=e[g];if(i.rl(f.ak())){throw vbb(new Wdb(Hwe))}}}vtd(a,I2d(a,b,c),h?BD(d,72):R6d(b,d))} +function T6d(a,b){Q6d();var c,d,e;if(b.$j()){return true}else if(b.Zj()==-2){if(b==(m8d(),k8d)||b==h8d||b==i8d||b==j8d){return true}else{e=a.Tg();if(bLd(e,b)>=0){return false}else{c=e1d((O6d(),M6d),e,b);if(!c){return true}else{d=c.Zj();return (d>1||d==-1)&&$1d(q1d(M6d,c))!=3}}}}else{return false}} +function R1b(a,b,c,d){var e,f,g,h,i;h=atd(BD(qud((!b.b&&(b.b=new y5d(z2,b,4,7)),b.b),0),82));i=atd(BD(qud((!b.c&&(b.c=new y5d(z2,b,5,8)),b.c),0),82));if(Xod(h)==Xod(i)){return null}if(ntd(i,h)){return null}g=Mld(b);if(g==c){return d}else{f=BD(Ohb(a.a,g),10);if(f){e=f.e;if(e){return e}}}return null} +function Cac(a,b){var c;c=BD(vNb(a,(Nyc(),Rwc)),276);Odd(b,'Label side selection ('+c+')',1);switch(c.g){case 0:Dac(a,(rbd(),nbd));break;case 1:Dac(a,(rbd(),obd));break;case 2:Bac(a,(rbd(),nbd));break;case 3:Bac(a,(rbd(),obd));break;case 4:Eac(a,(rbd(),nbd));break;case 5:Eac(a,(rbd(),obd));}Qdd(b)} +function bGc(a,b,c){var d,e,f,g,h,i;d=RFc(c,a.length);g=a[d];if(g[0].k!=(j0b(),e0b)){return}f=SFc(c,g.length);i=b.j;for(e=0;e<i.c.length;e++){h=(tCb(e,i.c.length),BD(i.c[e],11));if((c?h.j==(Ucd(),zcd):h.j==(Ucd(),Tcd))&&Ccb(DD(vNb(h,(wtc(),Nsc))))){Nkb(i,e,BD(vNb(g[f],(wtc(),$sc)),11));f+=c?1:-1}}} +function rQc(a,b){var c,d,e,f,g;g=new Rkb;c=b;do{f=BD(Ohb(a.b,c),128);f.B=c.c;f.D=c.d;g.c[g.c.length]=f;c=BD(Ohb(a.k,c),17)}while(c);d=(tCb(0,g.c.length),BD(g.c[0],128));d.j=true;d.A=BD(d.d.a.ec().Kc().Pb(),17).c.i;e=BD(Ikb(g,g.c.length-1),128);e.q=true;e.C=BD(e.d.a.ec().Kc().Pb(),17).d.i;return g} +function $wd(a){if(a.g==null){switch(a.p){case 0:a.g=Swd(a)?(Bcb(),Acb):(Bcb(),zcb);break;case 1:a.g=Scb(Twd(a));break;case 2:a.g=bdb(Uwd(a));break;case 3:a.g=Vwd(a);break;case 4:a.g=new Ndb(Wwd(a));break;case 6:a.g=Aeb(Ywd(a));break;case 5:a.g=meb(Xwd(a));break;case 7:a.g=Web(Zwd(a));}}return a.g} +function hxd(a){if(a.n==null){switch(a.p){case 0:a.n=_wd(a)?(Bcb(),Acb):(Bcb(),zcb);break;case 1:a.n=Scb(axd(a));break;case 2:a.n=bdb(bxd(a));break;case 3:a.n=cxd(a);break;case 4:a.n=new Ndb(dxd(a));break;case 6:a.n=Aeb(fxd(a));break;case 5:a.n=meb(exd(a));break;case 7:a.n=Web(gxd(a));}}return a.n} +function QDb(a){var b,c,d,e,f,g,h;for(f=new olb(a.a.a);f.a<f.c.c.length;){d=BD(mlb(f),307);d.g=0;d.i=0;d.e.a.$b()}for(e=new olb(a.a.a);e.a<e.c.c.length;){d=BD(mlb(e),307);for(c=d.a.a.ec().Kc();c.Ob();){b=BD(c.Pb(),57);for(h=b.c.Kc();h.Ob();){g=BD(h.Pb(),57);if(g.a!=d){Qqb(d.e,g);++g.a.g;++g.a.i}}}}} +function gOb(a,b){var c,d,e,f,g,h;h=Axb(a.a,b.b);if(!h){throw vbb(new Zdb('Invalid hitboxes for scanline overlap calculation.'))}g=false;for(f=(d=new Ywb((new cxb((new Gjb(a.a.a)).a)).b),new Njb(d));sib(f.a.a);){e=(c=Wwb(f.a),BD(c.cd(),65));if(bOb(b.b,e)){T$c(a.b.a,b.b,e);g=true}else{if(g){break}}}} +function G5b(a){var b,c,d,e,f;e=BD(vNb(a,(Nyc(),Fxc)),21);f=BD(vNb(a,Ixc),21);c=new f7c(a.f.a+a.d.b+a.d.c,a.f.b+a.d.d+a.d.a);b=new g7c(c);if(e.Hc((tdd(),pdd))){d=BD(vNb(a,Hxc),8);if(f.Hc((Idd(),Bdd))){d.a<=0&&(d.a=20);d.b<=0&&(d.b=20)}b.a=$wnd.Math.max(c.a,d.a);b.b=$wnd.Math.max(c.b,d.b)}H5b(a,c,b)} +function toc(a,b){var c,d,e,f,g,h,i,j,k,l,m;e=b?new Coc:new Eoc;f=false;do{f=false;j=b?Su(a.b):a.b;for(i=j.Kc();i.Ob();){h=BD(i.Pb(),29);m=Mu(h.a);b||new ov(m);for(l=new olb(m);l.a<l.c.c.length;){k=BD(mlb(l),10);if(e.Mb(k)){d=k;c=BD(vNb(k,(wtc(),usc)),305);g=b?c.b:c.k;f=roc(d,g,b,false)}}}}while(f)} +function WCc(a,b,c){var d,e,f,g,h;Odd(c,'Longest path layering',1);a.a=b;h=a.a.a;a.b=KC(WD,oje,25,h.c.length,15,1);d=0;for(g=new olb(h);g.a<g.c.c.length;){e=BD(mlb(g),10);e.p=d;a.b[d]=-1;++d}for(f=new olb(h);f.a<f.c.c.length;){e=BD(mlb(f),10);YCc(a,e)}h.c=KC(SI,Uhe,1,0,5,1);a.a=null;a.b=null;Qdd(c)} +function QVb(a,b){var c,d,e;b.a?(Axb(a.b,b.b),a.a[b.b.i]=BD(Exb(a.b,b.b),81),c=BD(Dxb(a.b,b.b),81),!!c&&(a.a[c.i]=b.b),undefined):(d=BD(Exb(a.b,b.b),81),!!d&&d==a.a[b.b.i]&&!!d.d&&d.d!=b.b.d&&d.f.Fc(b.b),e=BD(Dxb(a.b,b.b),81),!!e&&a.a[e.i]==b.b&&!!e.d&&e.d!=b.b.d&&b.b.f.Fc(e),Fxb(a.b,b.b),undefined)} +function zbc(a,b){var c,d,e,f,g,h;f=a.d;h=Edb(ED(vNb(a,(Nyc(),Zwc))));if(h<0){h=0;yNb(a,Zwc,h)}b.o.b=h;g=$wnd.Math.floor(h/2);d=new H0b;G0b(d,(Ucd(),Tcd));F0b(d,b);d.n.b=g;e=new H0b;G0b(e,zcd);F0b(e,b);e.n.b=g;RZb(a,d);c=new UZb;tNb(c,a);yNb(c,jxc,null);QZb(c,e);RZb(c,f);ybc(b,a,c);wbc(a,c);return c} +function uNc(a){var b,c;c=BD(vNb(a,(wtc(),Ksc)),21);b=new j3c;if(c.Hc((Orc(),Irc))){d3c(b,oNc);d3c(b,qNc)}if(c.Hc(Krc)||Ccb(DD(vNb(a,(Nyc(),$wc))))){d3c(b,qNc);c.Hc(Lrc)&&d3c(b,rNc)}c.Hc(Hrc)&&d3c(b,nNc);c.Hc(Nrc)&&d3c(b,sNc);c.Hc(Jrc)&&d3c(b,pNc);c.Hc(Erc)&&d3c(b,lNc);c.Hc(Grc)&&d3c(b,mNc);return b} +function Ihb(a,b){var c,d,e,f,g,h,i,j,k,l,m;d=a.d;f=b.d;h=d+f;i=a.e!=b.e?-1:1;if(h==2){k=Ibb(xbb(a.a[0],Yje),xbb(b.a[0],Yje));m=Tbb(k);l=Tbb(Pbb(k,32));return l==0?new Ugb(i,m):new Vgb(i,2,OC(GC(WD,1),oje,25,15,[m,l]))}c=a.a;e=b.a;g=KC(WD,oje,25,h,15,1);Fhb(c,d,e,f,g);j=new Vgb(i,h,g);Jgb(j);return j} +function Gwb(a,b,c,d){var e,f;if(!b){return c}else{e=a.a.ue(c.d,b.d);if(e==0){d.d=ijb(b,c.e);d.b=true;return b}f=e<0?0:1;b.a[f]=Gwb(a,b.a[f],c,d);if(Hwb(b.a[f])){if(Hwb(b.a[1-f])){b.b=true;b.a[0].b=false;b.a[1].b=false}else{Hwb(b.a[f].a[f])?(b=Owb(b,1-f)):Hwb(b.a[f].a[1-f])&&(b=Nwb(b,1-f))}}}return b} +function wHb(a,b,c){var d,e,f,g;e=a.i;d=a.n;vHb(a,(gHb(),dHb),e.c+d.b,c);vHb(a,fHb,e.c+e.b-d.c-c[2],c);g=e.b-d.b-d.c;if(c[0]>0){c[0]+=a.d;g-=c[0]}if(c[2]>0){c[2]+=a.d;g-=c[2]}f=$wnd.Math.max(0,g);c[1]=$wnd.Math.max(c[1],g);vHb(a,eHb,e.c+d.b+c[0]-(c[1]-g)/2,c);if(b==eHb){a.c.b=f;a.c.c=e.c+d.b+(f-g)/2}} +function AYb(){this.c=KC(UD,Vje,25,(Ucd(),OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd])).length,15,1);this.b=KC(UD,Vje,25,OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd]).length,15,1);this.a=KC(UD,Vje,25,OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd]).length,15,1);zlb(this.c,Pje);zlb(this.b,Qje);zlb(this.a,Qje)} +function Ufe(a,b,c){var d,e,f,g;if(b<=c){e=b;f=c}else{e=c;f=b}d=0;if(a.b==null){a.b=KC(WD,oje,25,2,15,1);a.b[0]=e;a.b[1]=f;a.c=true}else{d=a.b.length;if(a.b[d-1]+1==e){a.b[d-1]=f;return}g=KC(WD,oje,25,d+2,15,1);$fb(a.b,0,g,0,d);a.b=g;a.b[d-1]>=e&&(a.c=false,a.a=false);a.b[d++]=e;a.b[d]=f;a.c||Yfe(a)}} +function inc(a,b,c){var d,e,f,g,h,i,j;j=b.d;a.a=new Skb(j.c.length);a.c=new Lqb;for(h=new olb(j);h.a<h.c.c.length;){g=BD(mlb(h),101);f=new uOc(null);Ekb(a.a,f);Rhb(a.c,g,f)}a.b=new Lqb;gnc(a,b);for(d=0;d<j.c.length-1;d++){i=BD(Ikb(b.d,d),101);for(e=d+1;e<j.c.length;e++){jnc(a,i,BD(Ikb(b.d,e),101),c)}}} +function ySc(a,b,c){var d,e,f,g,h,i;if(!Qq(b)){i=Udd(c,(JD(b,14)?BD(b,14).gc():sr(b.Kc()))/a.a|0);Odd(i,Xqe,1);h=new BSc;g=0;for(f=b.Kc();f.Ob();){d=BD(f.Pb(),86);h=pl(OC(GC(KI,1),Uhe,20,0,[h,new ZRc(d)]));g<d.f.b&&(g=d.f.b)}for(e=b.Kc();e.Ob();){d=BD(e.Pb(),86);yNb(d,(mTc(),bTc),g)}Qdd(i);ySc(a,h,c)}} +function bJc(a,b){var c,d,e,f,g,h,i;c=Qje;h=(j0b(),h0b);for(e=new olb(b.a);e.a<e.c.c.length;){d=BD(mlb(e),10);f=d.k;if(f!=h0b){g=ED(vNb(d,(wtc(),atc)));if(g==null){c=$wnd.Math.max(c,0);d.n.b=c+iBc(a.a,f,h)}else{d.n.b=(uCb(g),g)}}i=iBc(a.a,f,h);d.n.b<c+i+d.d.d&&(d.n.b=c+i+d.d.d);c=d.n.b+d.o.b+d.d.a;h=f}} +function uQb(a,b,c){var d,e,f,g,h,i,j,k,l;f=itd(b,false,false);j=ofd(f);l=Edb(ED(hkd(b,(CPb(),vPb))));e=sQb(j,l+a.a);k=new XOb(e);tNb(k,b);Rhb(a.b,b,k);c.c[c.c.length]=k;i=(!b.n&&(b.n=new cUd(D2,b,1,7)),b.n);for(h=new Fyd(i);h.e!=h.i.gc();){g=BD(Dyd(h),137);d=wQb(a,g,true,0,0);c.c[c.c.length]=d}return k} +function JVc(a,b,c,d,e){var f,g,h,i,j,k;!!a.d&&a.d.lg(e);f=BD(e.Xb(0),33);if(HVc(a,c,f,false)){return true}g=BD(e.Xb(e.gc()-1),33);if(HVc(a,d,g,true)){return true}if(CVc(a,e)){return true}for(k=e.Kc();k.Ob();){j=BD(k.Pb(),33);for(i=b.Kc();i.Ob();){h=BD(i.Pb(),33);if(BVc(a,j,h)){return true}}}return false} +function qid(a,b,c){var d,e,f,g,h,i,j,k,l,m;m=b.c.length;l=(j=a.Yg(c),BD(j>=0?a._g(j,false,true):sid(a,c,false),58));n:for(f=l.Kc();f.Ob();){e=BD(f.Pb(),56);for(k=0;k<m;++k){g=(tCb(k,b.c.length),BD(b.c[k],72));i=g.dd();h=g.ak();d=e.bh(h,false);if(i==null?d!=null:!pb(i,d)){continue n}}return e}return null} +function V6b(a,b,c,d){var e,f,g,h;e=BD(Y_b(b,(Ucd(),Tcd)).Kc().Pb(),11);f=BD(Y_b(b,zcd).Kc().Pb(),11);for(h=new olb(a.j);h.a<h.c.c.length;){g=BD(mlb(h),11);while(g.e.c.length!=0){RZb(BD(Ikb(g.e,0),17),e)}while(g.g.c.length!=0){QZb(BD(Ikb(g.g,0),17),f)}}c||yNb(b,(wtc(),Vsc),null);d||yNb(b,(wtc(),Wsc),null)} +function itd(a,b,c){var d,e;if((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i==0){return etd(a)}else{d=BD(qud((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a),0),202);if(b){Uxd((!d.a&&(d.a=new xMd(y2,d,5)),d.a));omd(d,0);pmd(d,0);hmd(d,0);imd(d,0)}if(c){e=(!a.a&&(a.a=new cUd(A2,a,6,6)),a.a);while(e.i>1){Xxd(e,e.i-1)}}return d}} +function Z2b(a,b){var c,d,e,f,g,h,i;Odd(b,'Comment post-processing',1);for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);d=new Rkb;for(h=new olb(e.a);h.a<h.c.c.length;){g=BD(mlb(h),10);i=BD(vNb(g,(wtc(),vtc)),15);c=BD(vNb(g,tsc),15);if(!!i||!!c){$2b(g,i,c);!!i&&Gkb(d,i);!!c&&Gkb(d,c)}}Gkb(e.a,d)}Qdd(b)} +function Eac(a,b){var c,d,e,f,g,h,i;c=new jkb;for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);i=true;d=0;for(h=new olb(e.a);h.a<h.c.c.length;){g=BD(mlb(h),10);switch(g.k.g){case 4:++d;case 1:Xjb(c,g);break;case 0:Gac(g,b);default:c.b==c.c||Fac(c,d,i,false,b);i=false;d=0;}}c.b==c.c||Fac(c,d,i,true,b)}} +function Ebc(a,b){var c,d,e,f,g,h,i;e=new Rkb;for(c=0;c<=a.i;c++){d=new H1b(b);d.p=a.i-c;e.c[e.c.length]=d}for(h=new olb(a.o);h.a<h.c.c.length;){g=BD(mlb(h),10);$_b(g,BD(Ikb(e,a.i-a.f[g.p]),29))}f=new olb(e);while(f.a<f.c.c.length){i=BD(mlb(f),29);i.a.c.length==0&&nlb(f)}b.b.c=KC(SI,Uhe,1,0,5,1);Gkb(b.b,e)} +function KHc(a,b){var c,d,e,f,g,h;c=0;for(h=new olb(b);h.a<h.c.c.length;){g=BD(mlb(h),11);AHc(a.b,a.d[g.p]);for(e=new b1b(g.b);llb(e.a)||llb(e.b);){d=BD(llb(e.a)?mlb(e.a):mlb(e.b),17);f=aIc(a,g==d.c?d.d:d.c);if(f>a.d[g.p]){c+=zHc(a.b,f);Wjb(a.a,meb(f))}}while(!akb(a.a)){xHc(a.b,BD(fkb(a.a),19).a)}}return c} +function o2c(a,b,c){var d,e,f,g;f=(!b.a&&(b.a=new cUd(E2,b,10,11)),b.a).i;for(e=new Fyd((!b.a&&(b.a=new cUd(E2,b,10,11)),b.a));e.e!=e.i.gc();){d=BD(Dyd(e),33);(!d.a&&(d.a=new cUd(E2,d,10,11)),d.a).i==0||(f+=o2c(a,d,false))}if(c){g=Xod(b);while(g){f+=(!g.a&&(g.a=new cUd(E2,g,10,11)),g.a).i;g=Xod(g)}}return f} +function Xxd(a,b){var c,d,e,f;if(a.ej()){d=null;e=a.fj();a.ij()&&(d=a.kj(a.pi(b),null));c=a.Zi(4,f=tud(a,b),null,b,e);if(a.bj()&&f!=null){d=a.dj(f,d);if(!d){a.$i(c)}else{d.Ei(c);d.Fi()}}else{if(!d){a.$i(c)}else{d.Ei(c);d.Fi()}}return f}else{f=tud(a,b);if(a.bj()&&f!=null){d=a.dj(f,null);!!d&&d.Fi()}return f}} +function UKb(a){var b,c,d,e,f,g,h,i,j,k;j=a.a;b=new Tqb;i=0;for(d=new olb(a.d);d.a<d.c.c.length;){c=BD(mlb(d),222);k=0;ktb(c.b,new XKb);for(g=Jsb(c.b,0);g.b!=g.d.c;){f=BD(Xsb(g),222);if(b.a._b(f)){e=c.c;h=f.c;k<h.d+h.a+j&&k+e.a+j>h.d&&(k=h.d+h.a+j)}}c.c.d=k;b.a.zc(c,b);i=$wnd.Math.max(i,c.c.d+c.c.a)}return i} +function Orc(){Orc=ccb;Frc=new Prc('COMMENTS',0);Hrc=new Prc('EXTERNAL_PORTS',1);Irc=new Prc('HYPEREDGES',2);Jrc=new Prc('HYPERNODES',3);Krc=new Prc('NON_FREE_PORTS',4);Lrc=new Prc('NORTH_SOUTH_PORTS',5);Nrc=new Prc(Wne,6);Erc=new Prc('CENTER_LABELS',7);Grc=new Prc('END_LABELS',8);Mrc=new Prc('PARTITIONS',9)} +function gVc(a){var b,c,d,e,f;e=new Rkb;b=new Vqb((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));for(d=new Sr(ur(_sd(a).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),79);if(!JD(qud((!c.b&&(c.b=new y5d(z2,c,4,7)),c.b),0),186)){f=atd(BD(qud((!c.c&&(c.c=new y5d(z2,c,5,8)),c.c),0),82));b.a._b(f)||(e.c[e.c.length]=f,true)}}return e} +function fVc(a){var b,c,d,e,f,g;f=new Tqb;b=new Vqb((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));for(e=new Sr(ur(_sd(a).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),79);if(!JD(qud((!d.b&&(d.b=new y5d(z2,d,4,7)),d.b),0),186)){g=atd(BD(qud((!d.c&&(d.c=new y5d(z2,d,5,8)),d.c),0),82));b.a._b(g)||(c=f.a.zc(g,f),c==null)}}return f} +function zA(a,b,c,d,e){if(d<0){d=oA(a,e,OC(GC(ZI,1),nie,2,6,[bje,cje,dje,eje,fje,gje,hje,ije,jje,kje,lje,mje]),b);d<0&&(d=oA(a,e,OC(GC(ZI,1),nie,2,6,['Jan','Feb','Mar','Apr',fje,'Jun','Jul','Aug','Sep','Oct','Nov','Dec']),b));if(d<0){return false}c.k=d;return true}else if(d>0){c.k=d-1;return true}return false} +function BA(a,b,c,d,e){if(d<0){d=oA(a,e,OC(GC(ZI,1),nie,2,6,[bje,cje,dje,eje,fje,gje,hje,ije,jje,kje,lje,mje]),b);d<0&&(d=oA(a,e,OC(GC(ZI,1),nie,2,6,['Jan','Feb','Mar','Apr',fje,'Jun','Jul','Aug','Sep','Oct','Nov','Dec']),b));if(d<0){return false}c.k=d;return true}else if(d>0){c.k=d-1;return true}return false} +function DA(a,b,c,d,e,f){var g,h,i,j;h=32;if(d<0){if(b[0]>=a.length){return false}h=bfb(a,b[0]);if(h!=43&&h!=45){return false}++b[0];d=rA(a,b);if(d<0){return false}h==45&&(d=-d)}if(h==32&&b[0]-c==2&&e.b==2){i=new eB;j=i.q.getFullYear()-nje+nje-80;g=j%100;f.a=d==g;d+=(j/100|0)*100+(d<g?100:0)}f.p=d;return true} +function L1b(a,b){var c,d,e,f,g;if(!Xod(a)){return}g=BD(vNb(b,(Nyc(),Fxc)),174);PD(hkd(a,Vxc))===PD((dcd(),ccd))&&jkd(a,Vxc,bcd);d=(Pgd(),new bhd(Xod(a)));f=new hhd(!Xod(a)?null:new bhd(Xod(a)),a);e=PGb(d,f,false,true);rqb(g,(tdd(),pdd));c=BD(vNb(b,Hxc),8);c.a=$wnd.Math.max(e.a,c.a);c.b=$wnd.Math.max(e.b,c.b)} +function Pac(a,b,c){var d,e,f,g,h,i;for(g=BD(vNb(a,(wtc(),Lsc)),15).Kc();g.Ob();){f=BD(g.Pb(),10);switch(BD(vNb(f,(Nyc(),mxc)),163).g){case 2:$_b(f,b);break;case 4:$_b(f,c);}for(e=new Sr(ur(O_b(f).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);if(!!d.c&&!!d.d){continue}h=!d.d;i=BD(vNb(d,ctc),11);h?RZb(d,i):QZb(d,i)}}} +function Alc(){Alc=ccb;tlc=new Blc(xle,0,(Ucd(),Acd),Acd);wlc=new Blc(zle,1,Rcd,Rcd);slc=new Blc(yle,2,zcd,zcd);zlc=new Blc(Ale,3,Tcd,Tcd);vlc=new Blc('NORTH_WEST_CORNER',4,Tcd,Acd);ulc=new Blc('NORTH_EAST_CORNER',5,Acd,zcd);ylc=new Blc('SOUTH_WEST_CORNER',6,Rcd,Tcd);xlc=new Blc('SOUTH_EAST_CORNER',7,zcd,Rcd)} +function i6c(){i6c=ccb;h6c=OC(GC(XD,1),Sje,25,14,[1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,87178291200,1307674368000,{l:3506176,m:794077,h:1},{l:884736,m:916411,h:20},{l:3342336,m:3912489,h:363},{l:589824,m:3034138,h:6914},{l:3407872,m:1962506,h:138294}]);$wnd.Math.pow(2,-65)} +function Pcc(a,b){var c,d,e,f,g;if(a.c.length==0){return new vgd(meb(0),meb(0))}c=(tCb(0,a.c.length),BD(a.c[0],11)).j;g=0;f=b.g;d=b.g+1;while(g<a.c.length-1&&c.g<f){++g;c=(tCb(g,a.c.length),BD(a.c[g],11)).j}e=g;while(e<a.c.length-1&&c.g<d){++e;c=(tCb(g,a.c.length),BD(a.c[g],11)).j}return new vgd(meb(g),meb(e))} +function R9b(a,b,c){var d,e,f,g,h,i,j,k,l,m;f=b.c.length;g=(tCb(c,b.c.length),BD(b.c[c],286));h=g.a.o.a;l=g.c;m=0;for(j=g.c;j<=g.f;j++){if(h<=a.a[j]){return j}k=a.a[j];i=null;for(e=c+1;e<f;e++){d=(tCb(e,b.c.length),BD(b.c[e],286));d.c<=j&&d.f>=j&&(i=d)}!!i&&(k=$wnd.Math.max(k,i.a.o.a));if(k>m){l=j;m=k}}return l} +function ode(a,b,c){var d,e,f;a.e=c;a.d=0;a.b=0;a.f=1;a.i=b;(a.e&16)==16&&(a.i=Xee(a.i));a.j=a.i.length;nde(a);f=rde(a);if(a.d!=a.j)throw vbb(new mde(tvd((h0d(),sue))));if(a.g){for(d=0;d<a.g.a.c.length;d++){e=BD(Uvb(a.g,d),584);if(a.f<=e.a)throw vbb(new mde(tvd((h0d(),tue))))}a.g.a.c=KC(SI,Uhe,1,0,5,1)}return f} +function _Pd(a,b){var c,d,e;if(b==null){for(d=(!a.a&&(a.a=new cUd(g5,a,9,5)),new Fyd(a.a));d.e!=d.i.gc();){c=BD(Dyd(d),678);e=c.c;if((e==null?c.zb:e)==null){return c}}}else{for(d=(!a.a&&(a.a=new cUd(g5,a,9,5)),new Fyd(a.a));d.e!=d.i.gc();){c=BD(Dyd(d),678);if(dfb(b,(e=c.c,e==null?c.zb:e))){return c}}}return null} +function KIb(a,b){var c;c=null;switch(b.g){case 1:a.e.Xe((Y9c(),o9c))&&(c=BD(a.e.We(o9c),249));break;case 3:a.e.Xe((Y9c(),p9c))&&(c=BD(a.e.We(p9c),249));break;case 2:a.e.Xe((Y9c(),n9c))&&(c=BD(a.e.We(n9c),249));break;case 4:a.e.Xe((Y9c(),q9c))&&(c=BD(a.e.We(q9c),249));}!c&&(c=BD(a.e.We((Y9c(),l9c)),249));return c} +function OCc(a,b,c){var d,e,f,g,h,i,j,k,l;b.p=1;f=b.c;for(l=W_b(b,(KAc(),IAc)).Kc();l.Ob();){k=BD(l.Pb(),11);for(e=new olb(k.g);e.a<e.c.c.length;){d=BD(mlb(e),17);j=d.d.i;if(b!=j){g=j.c;if(g.p<=f.p){h=f.p+1;if(h==c.b.c.length){i=new H1b(c);i.p=h;Ekb(c.b,i);$_b(j,i)}else{i=BD(Ikb(c.b,h),29);$_b(j,i)}OCc(a,j,c)}}}}} +function ZXc(a,b,c){var d,e,f,g,h,i;e=c;f=0;for(h=new olb(b);h.a<h.c.c.length;){g=BD(mlb(h),33);jkd(g,(ZWc(),SWc),meb(e++));i=gVc(g);d=$wnd.Math.atan2(g.j+g.f/2,g.i+g.g/2);d+=d<0?dre:0;d<0.7853981633974483||d>vre?Okb(i,a.b):d<=vre&&d>wre?Okb(i,a.d):d<=wre&&d>xre?Okb(i,a.c):d<=xre&&Okb(i,a.a);f=ZXc(a,i,f)}return e} +function Hgb(){Hgb=ccb;var a;Cgb=new Ugb(1,1);Egb=new Ugb(1,10);Ggb=new Ugb(0,0);Bgb=new Ugb(-1,1);Dgb=OC(GC(cJ,1),nie,91,0,[Ggb,Cgb,new Ugb(1,2),new Ugb(1,3),new Ugb(1,4),new Ugb(1,5),new Ugb(1,6),new Ugb(1,7),new Ugb(1,8),new Ugb(1,9),Egb]);Fgb=KC(cJ,nie,91,32,0,1);for(a=0;a<Fgb.length;a++){Fgb[a]=ghb(Nbb(1,a))}} +function B9b(a,b,c,d,e,f){var g,h,i,j;h=!WAb(JAb(a.Oc(),new Xxb(new F9b))).sd((EAb(),DAb));g=a;f==(ead(),dad)&&(g=JD(g,152)?km(BD(g,152)):JD(g,131)?BD(g,131).a:JD(g,54)?new ov(g):new dv(g));for(j=g.Kc();j.Ob();){i=BD(j.Pb(),70);i.n.a=b.a;h?(i.n.b=b.b+(d.b-i.o.b)/2):e?(i.n.b=b.b):(i.n.b=b.b+d.b-i.o.b);b.a+=i.o.a+c}} +function UOc(a,b,c,d){var e,f,g,h,i,j;e=(d.c+d.a)/2;Osb(b.j);Dsb(b.j,e);Osb(c.e);Dsb(c.e,e);j=new aPc;for(h=new olb(a.f);h.a<h.c.c.length;){f=BD(mlb(h),129);i=f.a;WOc(j,b,i);WOc(j,c,i)}for(g=new olb(a.k);g.a<g.c.c.length;){f=BD(mlb(g),129);i=f.b;WOc(j,b,i);WOc(j,c,i)}j.b+=2;j.a+=POc(b,a.q);j.a+=POc(a.q,c);return j} +function FSc(a,b,c){var d,e,f,g,h;if(!Qq(b)){h=Udd(c,(JD(b,14)?BD(b,14).gc():sr(b.Kc()))/a.a|0);Odd(h,Xqe,1);g=new ISc;f=null;for(e=b.Kc();e.Ob();){d=BD(e.Pb(),86);g=pl(OC(GC(KI,1),Uhe,20,0,[g,new ZRc(d)]));if(f){yNb(f,(mTc(),hTc),d);yNb(d,_Sc,f);if(VRc(d)==VRc(f)){yNb(f,iTc,d);yNb(d,aTc,f)}}f=d}Qdd(h);FSc(a,g,c)}} +function VHb(a){var b,c,d,e,f,g,h;c=a.i;b=a.n;h=c.d;a.f==(EIb(),CIb)?(h+=(c.a-a.e.b)/2):a.f==BIb&&(h+=c.a-a.e.b);for(e=new olb(a.d);e.a<e.c.c.length;){d=BD(mlb(e),181);g=d.rf();f=new d7c;f.b=h;h+=g.b+a.a;switch(a.b.g){case 0:f.a=c.c+b.b;break;case 1:f.a=c.c+b.b+(c.b-g.a)/2;break;case 2:f.a=c.c+c.b-b.c-g.a;}d.tf(f)}} +function XHb(a){var b,c,d,e,f,g,h;c=a.i;b=a.n;h=c.c;a.b==(NHb(),KHb)?(h+=(c.b-a.e.a)/2):a.b==MHb&&(h+=c.b-a.e.a);for(e=new olb(a.d);e.a<e.c.c.length;){d=BD(mlb(e),181);g=d.rf();f=new d7c;f.a=h;h+=g.a+a.a;switch(a.f.g){case 0:f.b=c.d+b.d;break;case 1:f.b=c.d+b.d+(c.a-g.b)/2;break;case 2:f.b=c.d+c.a-b.a-g.b;}d.tf(f)}} +function D4b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o;k=c.a.c;g=c.a.c+c.a.b;f=BD(Ohb(c.c,b),459);n=f.f;o=f.a;i=new f7c(k,n);l=new f7c(g,o);e=k;c.p||(e+=a.c);e+=c.F+c.v*a.b;j=new f7c(e,n);m=new f7c(e,o);n7c(b.a,OC(GC(m1,1),nie,8,0,[i,j]));h=c.d.a.gc()>1;if(h){d=new f7c(e,c.b);Dsb(b.a,d)}n7c(b.a,OC(GC(m1,1),nie,8,0,[m,l]))} +function jdd(a){r4c(a,new E3c(P3c(M3c(O3c(N3c(new R3c,Rse),'ELK Randomizer'),'Distributes the nodes randomly on the plane, leading to very obfuscating layouts. Can be useful to demonstrate the power of "real" layout algorithms.'),new mdd)));p4c(a,Rse,ame,fdd);p4c(a,Rse,wme,15);p4c(a,Rse,yme,meb(0));p4c(a,Rse,_le,tme)} +function hde(){hde=ccb;var a,b,c,d,e,f;fde=KC(SD,wte,25,255,15,1);gde=KC(TD,$ie,25,16,15,1);for(b=0;b<255;b++){fde[b]=-1}for(c=57;c>=48;c--){fde[c]=c-48<<24>>24}for(d=70;d>=65;d--){fde[d]=d-65+10<<24>>24}for(e=102;e>=97;e--){fde[e]=e-97+10<<24>>24}for(f=0;f<10;f++)gde[f]=48+f&aje;for(a=10;a<=15;a++)gde[a]=65+a-10&aje} +function BVc(a,b,c){var d,e,f,g,h,i,j,k;h=b.i-a.g/2;i=c.i-a.g/2;j=b.j-a.g/2;k=c.j-a.g/2;f=b.g+a.g/2;g=c.g+a.g/2;d=b.f+a.g/2;e=c.f+a.g/2;if(h<i+g&&i<h&&j<k+e&&k<j){return true}else if(i<h+f&&h<i&&k<j+d&&j<k){return true}else if(h<i+g&&i<h&&j<k&&k<j+d){return true}else if(i<h+f&&h<i&&j<k+e&&k<j){return true}return false} +function NTb(a){var b,c,d,e,f;e=BD(vNb(a,(Nyc(),Fxc)),21);f=BD(vNb(a,Ixc),21);c=new f7c(a.f.a+a.d.b+a.d.c,a.f.b+a.d.d+a.d.a);b=new g7c(c);if(e.Hc((tdd(),pdd))){d=BD(vNb(a,Hxc),8);if(f.Hc((Idd(),Bdd))){d.a<=0&&(d.a=20);d.b<=0&&(d.b=20)}b.a=$wnd.Math.max(c.a,d.a);b.b=$wnd.Math.max(c.b,d.b)}Ccb(DD(vNb(a,Gxc)))||OTb(a,c,b)} +function NJc(a,b){var c,d,e,f;for(f=V_b(b,(Ucd(),Rcd)).Kc();f.Ob();){d=BD(f.Pb(),11);c=BD(vNb(d,(wtc(),gtc)),10);!!c&&AFb(DFb(CFb(EFb(BFb(new FFb,0),0.1),a.i[b.p].d),a.i[c.p].a))}for(e=V_b(b,Acd).Kc();e.Ob();){d=BD(e.Pb(),11);c=BD(vNb(d,(wtc(),gtc)),10);!!c&&AFb(DFb(CFb(EFb(BFb(new FFb,0),0.1),a.i[c.p].d),a.i[b.p].a))}} +function QKd(a){var b,c,d,e,f,g;if(!a.c){g=new wNd;b=KKd;f=b.a.zc(a,b);if(f==null){for(d=new Fyd(VKd(a));d.e!=d.i.gc();){c=BD(Dyd(d),87);e=KQd(c);JD(e,88)&&ytd(g,QKd(BD(e,26)));wtd(g,c)}b.a.Bc(a)!=null;b.a.gc()==0&&undefined}tNd(g);vud(g);a.c=new nNd((BD(qud(ZKd((NFd(),MFd).o),15),18),g.i),g.g);$Kd(a).b&=-33}return a.c} +function eee(a){var b;if(a.c!=10)throw vbb(new mde(tvd((h0d(),uue))));b=a.a;switch(b){case 110:b=10;break;case 114:b=13;break;case 116:b=9;break;case 92:case 124:case 46:case 94:case 45:case 63:case 42:case 43:case 123:case 125:case 40:case 41:case 91:case 93:break;default:throw vbb(new mde(tvd((h0d(),Yue))));}return b} +function qD(a){var b,c,d,e,f;if(a.l==0&&a.m==0&&a.h==0){return '0'}if(a.h==Gje&&a.m==0&&a.l==0){return '-9223372036854775808'}if(a.h>>19!=0){return '-'+qD(hD(a))}c=a;d='';while(!(c.l==0&&c.m==0&&c.h==0)){e=RC(Jje);c=UC(c,e,true);b=''+pD(QC);if(!(c.l==0&&c.m==0&&c.h==0)){f=9-b.length;for(;f>0;f--){b='0'+b}}d=b+d}return d} +function xrb(){if(!Object.create||!Object.getOwnPropertyNames){return false}var a='__proto__';var b=Object.create(null);if(b[a]!==undefined){return false}var c=Object.getOwnPropertyNames(b);if(c.length!=0){return false}b[a]=42;if(b[a]!==42){return false}if(Object.getOwnPropertyNames(b).length==0){return false}return true} +function Pgc(a){var b,c,d,e,f,g,h;b=false;c=0;for(e=new olb(a.d.b);e.a<e.c.c.length;){d=BD(mlb(e),29);d.p=c++;for(g=new olb(d.a);g.a<g.c.c.length;){f=BD(mlb(g),10);!b&&!Qq(O_b(f))&&(b=true)}}h=qqb((ead(),cad),OC(GC(t1,1),Kie,103,0,[aad,bad]));if(!b){rqb(h,dad);rqb(h,_9c)}a.a=new mDb(h);Uhb(a.f);Uhb(a.b);Uhb(a.e);Uhb(a.g)} +function _Xb(a,b,c){var d,e,f,g,h,i,j,k,l;d=c.c;e=c.d;h=A0b(b.c);i=A0b(b.d);if(d==b.c){h=aYb(a,h,e);i=bYb(b.d)}else{h=bYb(b.c);i=aYb(a,i,e)}j=new t7c(b.a);Gsb(j,h,j.a,j.a.a);Gsb(j,i,j.c.b,j.c);g=b.c==d;l=new BYb;for(f=0;f<j.b-1;++f){k=new vgd(BD(Ut(j,f),8),BD(Ut(j,f+1),8));g&&f==0||!g&&f==j.b-2?(l.b=k):Ekb(l.a,k)}return l} +function O$b(a,b){var c,d,e,f;f=a.j.g-b.j.g;if(f!=0){return f}c=BD(vNb(a,(Nyc(),Wxc)),19);d=BD(vNb(b,Wxc),19);if(!!c&&!!d){e=c.a-d.a;if(e!=0){return e}}switch(a.j.g){case 1:return Kdb(a.n.a,b.n.a);case 2:return Kdb(a.n.b,b.n.b);case 3:return Kdb(b.n.a,a.n.a);case 4:return Kdb(b.n.b,a.n.b);default:throw vbb(new Zdb(ine));}} +function G6b(a,b,c,d){var e,f,g,h,i;if(sr((D6b(),new Sr(ur(O_b(b).a.Kc(),new Sq))))>=a.a){return -1}if(!F6b(b,c)){return -1}if(Qq(BD(d.Kb(b),20))){return 1}e=0;for(g=BD(d.Kb(b),20).Kc();g.Ob();){f=BD(g.Pb(),17);i=f.c.i==b?f.d.i:f.c.i;h=G6b(a,i,c,d);if(h==-1){return -1}e=$wnd.Math.max(e,h);if(e>a.c-1){return -1}}return e+1} +function Btd(a,b){var c,d,e,f,g,h;if(PD(b)===PD(a)){return true}if(!JD(b,15)){return false}d=BD(b,15);h=a.gc();if(d.gc()!=h){return false}g=d.Kc();if(a.ni()){for(c=0;c<h;++c){e=a.ki(c);f=g.Pb();if(e==null?f!=null:!pb(e,f)){return false}}}else{for(c=0;c<h;++c){e=a.ki(c);f=g.Pb();if(PD(e)!==PD(f)){return false}}}return true} +function rAd(a,b){var c,d,e,f,g,h;if(a.f>0){a.qj();if(b!=null){for(f=0;f<a.d.length;++f){c=a.d[f];if(c){d=BD(c.g,367);h=c.i;for(g=0;g<h;++g){e=d[g];if(pb(b,e.dd())){return true}}}}}else{for(f=0;f<a.d.length;++f){c=a.d[f];if(c){d=BD(c.g,367);h=c.i;for(g=0;g<h;++g){e=d[g];if(PD(b)===PD(e.dd())){return true}}}}}}return false} +function e6b(a,b,c){var d,e,f,g;Odd(c,'Orthogonally routing hierarchical port edges',1);a.a=0;d=h6b(b);k6b(b,d);j6b(a,b,d);f6b(b);e=BD(vNb(b,(Nyc(),Vxc)),98);f=b.b;d6b((tCb(0,f.c.length),BD(f.c[0],29)),e,b);d6b(BD(Ikb(f,f.c.length-1),29),e,b);g=b.b;b6b((tCb(0,g.c.length),BD(g.c[0],29)));b6b(BD(Ikb(g,g.c.length-1),29));Qdd(c)} +function jnd(a){switch(a){case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:{return a-48<<24>>24}case 97:case 98:case 99:case 100:case 101:case 102:{return a-97+10<<24>>24}case 65:case 66:case 67:case 68:case 69:case 70:{return a-65+10<<24>>24}default:{throw vbb(new Oeb('Invalid hexadecimal'))}}} +function AUc(a,b,c){var d,e,f,g;Odd(c,'Processor order nodes',2);a.a=Edb(ED(vNb(b,(JTc(),HTc))));e=new Psb;for(g=Jsb(b.b,0);g.b!=g.d.c;){f=BD(Xsb(g),86);Ccb(DD(vNb(f,(mTc(),jTc))))&&(Gsb(e,f,e.c.b,e.c),true)}d=(sCb(e.b!=0),BD(e.a.a.c,86));yUc(a,d);!c.b&&Rdd(c,1);BUc(a,d,0-Edb(ED(vNb(d,(mTc(),bTc))))/2,0);!c.b&&Rdd(c,1);Qdd(c)} +function rFb(){rFb=ccb;qFb=new sFb('SPIRAL',0);lFb=new sFb('LINE_BY_LINE',1);mFb=new sFb('MANHATTAN',2);kFb=new sFb('JITTER',3);oFb=new sFb('QUADRANTS_LINE_BY_LINE',4);pFb=new sFb('QUADRANTS_MANHATTAN',5);nFb=new sFb('QUADRANTS_JITTER',6);jFb=new sFb('COMBINE_LINE_BY_LINE_MANHATTAN',7);iFb=new sFb('COMBINE_JITTER_MANHATTAN',8)} +function roc(a,b,c,d){var e,f,g,h,i,j;i=woc(a,c);j=woc(b,c);e=false;while(!!i&&!!j){if(d||uoc(i,j,c)){g=woc(i,c);h=woc(j,c);zoc(b);zoc(a);f=i.c;sbc(i,false);sbc(j,false);if(c){Z_b(b,j.p,f);b.p=j.p;Z_b(a,i.p+1,f);a.p=i.p}else{Z_b(a,i.p,f);a.p=i.p;Z_b(b,j.p+1,f);b.p=j.p}$_b(i,null);$_b(j,null);i=g;j=h;e=true}else{break}}return e} +function VDc(a,b,c,d){var e,f,g,h,i;e=false;f=false;for(h=new olb(d.j);h.a<h.c.c.length;){g=BD(mlb(h),11);PD(vNb(g,(wtc(),$sc)))===PD(c)&&(g.g.c.length==0?g.e.c.length==0||(e=true):(f=true))}i=0;e&&e^f?(i=c.j==(Ucd(),Acd)?-a.e[d.c.p][d.p]:b-a.e[d.c.p][d.p]):f&&e^f?(i=a.e[d.c.p][d.p]+1):e&&f&&(i=c.j==(Ucd(),Acd)?0:b/2);return i} +function NEd(a,b,c,d,e,f,g,h){var i,j,k;i=0;b!=null&&(i^=LCb(b.toLowerCase()));c!=null&&(i^=LCb(c));d!=null&&(i^=LCb(d));g!=null&&(i^=LCb(g));h!=null&&(i^=LCb(h));for(j=0,k=f.length;j<k;j++){i^=LCb(f[j])}a?(i|=256):(i&=-257);e?(i|=16):(i&=-17);this.f=i;this.i=b==null?null:(uCb(b),b);this.a=c;this.d=d;this.j=f;this.g=g;this.e=h} +function X_b(a,b,c){var d,e;e=null;switch(b.g){case 1:e=(z0b(),u0b);break;case 2:e=(z0b(),w0b);}d=null;switch(c.g){case 1:d=(z0b(),v0b);break;case 2:d=(z0b(),t0b);break;case 3:d=(z0b(),x0b);break;case 4:d=(z0b(),y0b);}return !!e&&!!d?Nq(a.j,new Yb(new amb(OC(GC(_D,1),Uhe,169,0,[BD(Qb(e),169),BD(Qb(d),169)])))):(mmb(),mmb(),jmb)} +function t5b(a){var b,c,d;b=BD(vNb(a,(Nyc(),Hxc)),8);yNb(a,Hxc,new f7c(b.b,b.a));switch(BD(vNb(a,mwc),248).g){case 1:yNb(a,mwc,(F7c(),E7c));break;case 2:yNb(a,mwc,(F7c(),A7c));break;case 3:yNb(a,mwc,(F7c(),C7c));break;case 4:yNb(a,mwc,(F7c(),D7c));}if((!a.q?(mmb(),mmb(),kmb):a.q)._b(ayc)){c=BD(vNb(a,ayc),8);d=c.a;c.a=c.b;c.b=d}} +function jjc(a,b,c,d,e,f){this.b=c;this.d=e;if(a>=b.length){throw vbb(new qcb('Greedy SwitchDecider: Free layer not in graph.'))}this.c=b[a];this.e=new dIc(d);THc(this.e,this.c,(Ucd(),Tcd));this.i=new dIc(d);THc(this.i,this.c,zcd);this.f=new ejc(this.c);this.a=!f&&e.i&&!e.s&&this.c[0].k==(j0b(),e0b);this.a&&hjc(this,a,b.length)} +function hKb(a,b){var c,d,e,f,g,h;f=!a.B.Hc((Idd(),zdd));g=a.B.Hc(Cdd);a.a=new FHb(g,f,a.c);!!a.n&&u_b(a.a.n,a.n);lIb(a.g,(gHb(),eHb),a.a);if(!b){d=new mIb(1,f,a.c);d.n.a=a.k;Npb(a.p,(Ucd(),Acd),d);e=new mIb(1,f,a.c);e.n.d=a.k;Npb(a.p,Rcd,e);h=new mIb(0,f,a.c);h.n.c=a.k;Npb(a.p,Tcd,h);c=new mIb(0,f,a.c);c.n.b=a.k;Npb(a.p,zcd,c)}} +function Vgc(a){var b,c,d;b=BD(vNb(a.d,(Nyc(),Swc)),218);switch(b.g){case 2:c=Ngc(a);break;case 3:c=(d=new Rkb,MAb(JAb(NAb(LAb(LAb(new YAb(null,new Kub(a.d.b,16)),new Shc),new Uhc),new Whc),new ehc),new Yhc(d)),d);break;default:throw vbb(new Zdb('Compaction not supported for '+b+' edges.'));}Ugc(a,c);reb(new Pib(a.g),new Ehc(a))} +function a2c(a,b){var c;c=new zNb;!!b&&tNb(c,BD(Ohb(a.a,C2),94));JD(b,470)&&tNb(c,BD(Ohb(a.a,G2),94));if(JD(b,354)){tNb(c,BD(Ohb(a.a,D2),94));return c}JD(b,82)&&tNb(c,BD(Ohb(a.a,z2),94));if(JD(b,239)){tNb(c,BD(Ohb(a.a,E2),94));return c}if(JD(b,186)){tNb(c,BD(Ohb(a.a,F2),94));return c}JD(b,352)&&tNb(c,BD(Ohb(a.a,B2),94));return c} +function wSb(){wSb=ccb;oSb=new Osd((Y9c(),D9c),meb(1));uSb=new Osd(T9c,80);tSb=new Osd(M9c,5);bSb=new Osd(r8c,tme);pSb=new Osd(E9c,meb(1));sSb=new Osd(H9c,(Bcb(),true));lSb=new q0b(50);kSb=new Osd(f9c,lSb);dSb=O8c;mSb=t9c;cSb=new Osd(B8c,false);jSb=e9c;iSb=b9c;hSb=Y8c;gSb=W8c;nSb=x9c;fSb=(SRb(),LRb);vSb=QRb;eSb=KRb;qSb=NRb;rSb=PRb} +function ZXb(a){var b,c,d,e,f,g,h,i;i=new jYb;for(h=new olb(a.a);h.a<h.c.c.length;){g=BD(mlb(h),10);if(g.k==(j0b(),e0b)){continue}XXb(i,g,new d7c);for(f=new Sr(ur(U_b(g).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);if(e.c.i.k==e0b||e.d.i.k==e0b){continue}for(d=Jsb(e.a,0);d.b!=d.d.c;){c=BD(Xsb(d),8);b=c;hYb(i,new cWb(b.a,b.b))}}}return i} +function A0c(){A0c=ccb;z0c=new Lsd(Qre);y0c=(R0c(),Q0c);x0c=new Nsd(Vre,y0c);w0c=(a1c(),_0c);v0c=new Nsd(Rre,w0c);u0c=(N_c(),J_c);t0c=new Nsd(Sre,u0c);p0c=new Nsd(Tre,null);s0c=(C_c(),A_c);r0c=new Nsd(Ure,s0c);l0c=(i_c(),h_c);k0c=new Nsd(Wre,l0c);m0c=new Nsd(Xre,(Bcb(),false));n0c=new Nsd(Yre,meb(64));o0c=new Nsd(Zre,true);q0c=B_c} +function Toc(a){var b,c,d,e,f,g;if(a.a!=null){return}a.a=KC(sbb,dle,25,a.c.b.c.length,16,1);a.a[0]=false;if(wNb(a.c,(Nyc(),Lyc))){d=BD(vNb(a.c,Lyc),15);for(c=d.Kc();c.Ob();){b=BD(c.Pb(),19).a;b>0&&b<a.a.length&&(a.a[b]=false)}}else{g=new olb(a.c.b);g.a<g.c.c.length&&mlb(g);e=1;while(g.a<g.c.c.length){f=BD(mlb(g),29);a.a[e++]=Woc(f)}}} +function TMd(a,b){var c,d,e,f;e=a.b;switch(b){case 1:{a.b|=1;a.b|=4;a.b|=8;break}case 2:{a.b|=2;a.b|=4;a.b|=8;break}case 4:{a.b|=1;a.b|=2;a.b|=4;a.b|=8;break}case 3:{a.b|=16;a.b|=8;break}case 0:{a.b|=32;a.b|=16;a.b|=8;a.b|=1;a.b|=2;a.b|=4;break}}if(a.b!=e&&!!a.c){for(d=new Fyd(a.c);d.e!=d.i.gc();){f=BD(Dyd(d),473);c=$Kd(f);XMd(c,b)}}} +function cGc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o;e=false;for(g=b,h=0,i=g.length;h<i;++h){f=g[h];Ccb((Bcb(),f.e?true:false))&&!BD(Ikb(a.b,f.e.p),214).s&&(e=e|(j=f.e,k=BD(Ikb(a.b,j.p),214),l=k.e,m=SFc(c,l.length),n=l[m][0],n.k==(j0b(),e0b)?(l[m]=aGc(f,l[m],c?(Ucd(),Tcd):(Ucd(),zcd))):k.c.Tf(l,c),o=dGc(a,k,c,d),bGc(k.e,k.o,c),o))}return e} +function p2c(a,b){var c,d,e,f,g;f=(!b.a&&(b.a=new cUd(E2,b,10,11)),b.a).i;for(e=new Fyd((!b.a&&(b.a=new cUd(E2,b,10,11)),b.a));e.e!=e.i.gc();){d=BD(Dyd(e),33);if(PD(hkd(d,(Y9c(),J8c)))!==PD((hbd(),gbd))){g=BD(hkd(b,F9c),149);c=BD(hkd(d,F9c),149);(g==c||!!g&&C3c(g,c))&&(!d.a&&(d.a=new cUd(E2,d,10,11)),d.a).i!=0&&(f+=p2c(a,d))}}return f} +function nlc(a){var b,c,d,e,f,g,h;d=0;h=0;for(g=new olb(a.d);g.a<g.c.c.length;){f=BD(mlb(g),101);e=BD(GAb(JAb(new YAb(null,new Kub(f.j,16)),new Ylc),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);c=null;if(d<=h){c=(Ucd(),Acd);d+=e.gc()}else if(h<d){c=(Ucd(),Rcd);h+=e.gc()}b=c;MAb(NAb(e.Oc(),new Mlc),new Olc(b))}} +function mkc(a){var b,c,d,e,f,g,h,i;a.b=new _i(new amb((Ucd(),OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd]))),new amb((Fkc(),OC(GC(vV,1),Kie,361,0,[Ekc,Dkc,Ckc]))));for(g=OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd]),h=0,i=g.length;h<i;++h){f=g[h];for(c=OC(GC(vV,1),Kie,361,0,[Ekc,Dkc,Ckc]),d=0,e=c.length;d<e;++d){b=c[d];Ui(a.b,f,b,new Rkb)}}} +function KJb(a,b){var c,d,e,f,g,h,i,j,k,l;g=BD(BD(Qc(a.r,b),21),84);h=a.u.Hc((rcd(),pcd));c=a.u.Hc(mcd);d=a.u.Hc(lcd);j=a.u.Hc(qcd);l=a.B.Hc((Idd(),Hdd));k=!c&&!d&&(j||g.gc()==2);HJb(a,b);e=null;i=null;if(h){f=g.Kc();e=BD(f.Pb(),111);i=e;while(f.Ob()){i=BD(f.Pb(),111)}e.d.b=0;i.d.c=0;k&&!e.a&&(e.d.c=0)}if(l){LJb(g);if(h){e.d.b=0;i.d.c=0}}} +function SKb(a,b){var c,d,e,f,g,h,i,j,k,l;g=BD(BD(Qc(a.r,b),21),84);h=a.u.Hc((rcd(),pcd));c=a.u.Hc(mcd);d=a.u.Hc(lcd);i=a.u.Hc(qcd);l=a.B.Hc((Idd(),Hdd));j=!c&&!d&&(i||g.gc()==2);QKb(a,b);k=null;e=null;if(h){f=g.Kc();k=BD(f.Pb(),111);e=k;while(f.Ob()){e=BD(f.Pb(),111)}k.d.d=0;e.d.a=0;j&&!k.a&&(k.d.a=0)}if(l){TKb(g);if(h){k.d.d=0;e.d.a=0}}} +function oJc(a,b,c){var d,e,f,g,h,i,j,k;e=b.k;if(b.p>=0){return false}else{b.p=c.b;Ekb(c.e,b)}if(e==(j0b(),g0b)||e==i0b){for(g=new olb(b.j);g.a<g.c.c.length;){f=BD(mlb(g),11);for(k=(d=new olb((new R0b(f)).a.g),new U0b(d));llb(k.a);){j=BD(mlb(k.a),17).d;h=j.i;i=h.k;if(b.c!=h.c){if(i==g0b||i==i0b){if(oJc(a,h,c)){return true}}}}}}return true} +function gJd(a){var b;if((a.Db&64)!=0)return EId(a);b=new Jfb(EId(a));b.a+=' (changeable: ';Ffb(b,(a.Bb&zte)!=0);b.a+=', volatile: ';Ffb(b,(a.Bb&Dve)!=0);b.a+=', transient: ';Ffb(b,(a.Bb&Rje)!=0);b.a+=', defaultValueLiteral: ';Efb(b,a.j);b.a+=', unsettable: ';Ffb(b,(a.Bb&Cve)!=0);b.a+=', derived: ';Ffb(b,(a.Bb&oie)!=0);b.a+=')';return b.a} +function AOb(a){var b,c,d,e,f,g,h,i,j,k,l,m;e=eNb(a.d);g=BD(vNb(a.b,(CPb(),wPb)),116);h=g.b+g.c;i=g.d+g.a;k=e.d.a*a.e+h;j=e.b.a*a.f+i;$Ob(a.b,new f7c(k,j));for(m=new olb(a.g);m.a<m.c.c.length;){l=BD(mlb(m),562);b=l.g-e.a.a;c=l.i-e.c.a;d=P6c(Z6c(new f7c(b,c),l.a,l.b),Y6c(b7c(R6c(HOb(l.e)),l.d*l.a,l.c*l.b),-0.5));f=IOb(l.e);KOb(l.e,c7c(d,f))}} +function tmc(a,b,c,d){var e,f,g,h,i;i=KC(UD,nie,104,(Ucd(),OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd])).length,0,2);for(f=OC(GC(F1,1),bne,61,0,[Scd,Acd,zcd,Rcd,Tcd]),g=0,h=f.length;g<h;++g){e=f[g];i[e.g]=KC(UD,Vje,25,a.c[e.g],15,1)}vmc(i,a,Acd);vmc(i,a,Rcd);smc(i,a,Acd,b,c,d);smc(i,a,zcd,b,c,d);smc(i,a,Rcd,b,c,d);smc(i,a,Tcd,b,c,d);return i} +function UGc(a,b,c){if(Mhb(a.a,b)){if(Rqb(BD(Ohb(a.a,b),53),c)){return 1}}else{Rhb(a.a,b,new Tqb)}if(Mhb(a.a,c)){if(Rqb(BD(Ohb(a.a,c),53),b)){return -1}}else{Rhb(a.a,c,new Tqb)}if(Mhb(a.b,b)){if(Rqb(BD(Ohb(a.b,b),53),c)){return -1}}else{Rhb(a.b,b,new Tqb)}if(Mhb(a.b,c)){if(Rqb(BD(Ohb(a.b,c),53),b)){return 1}}else{Rhb(a.b,c,new Tqb)}return 0} +function x2d(a,b,c,d){var e,f,g,h,i,j;if(c==null){e=BD(a.g,119);for(h=0;h<a.i;++h){g=e[h];if(g.ak()==b){return Txd(a,g,d)}}}f=(Q6d(),BD(b,66).Oj()?BD(c,72):R6d(b,c));if(oid(a.e)){j=!R2d(a,b);d=Sxd(a,f,d);i=b.$j()?H2d(a,3,b,null,c,M2d(a,b,c,JD(b,99)&&(BD(b,18).Bb&Tje)!=0),j):H2d(a,1,b,b.zj(),c,-1,j);d?d.Ei(i):(d=i)}else{d=Sxd(a,f,d)}return d} +function CJb(a){var b,c,d,e,f,g;if(a.q==(dcd(),_bd)||a.q==$bd){return}e=a.f.n.d+_Gb(BD(Mpb(a.b,(Ucd(),Acd)),124))+a.c;b=a.f.n.a+_Gb(BD(Mpb(a.b,Rcd),124))+a.c;d=BD(Mpb(a.b,zcd),124);g=BD(Mpb(a.b,Tcd),124);f=$wnd.Math.max(0,d.n.d-e);f=$wnd.Math.max(f,g.n.d-e);c=$wnd.Math.max(0,d.n.a-b);c=$wnd.Math.max(c,g.n.a-b);d.n.d=f;g.n.d=f;d.n.a=c;g.n.a=c} +function rdc(a,b){var c,d,e,f,g,h,i,j,k,l,m;Odd(b,'Restoring reversed edges',1);for(i=new olb(a.b);i.a<i.c.c.length;){h=BD(mlb(i),29);for(k=new olb(h.a);k.a<k.c.c.length;){j=BD(mlb(k),10);for(m=new olb(j.j);m.a<m.c.c.length;){l=BD(mlb(m),11);g=k_b(l.g);for(d=g,e=0,f=d.length;e<f;++e){c=d[e];Ccb(DD(vNb(c,(wtc(),ltc))))&&PZb(c,false)}}}}Qdd(b)} +function m4c(){this.b=new $rb;this.d=new $rb;this.e=new $rb;this.c=new $rb;this.a=new Lqb;this.f=new Lqb;hvd(m1,new x4c,new z4c);hvd(l1,new V4c,new X4c);hvd(i1,new Z4c,new _4c);hvd(j1,new b5c,new d5c);hvd(i2,new f5c,new h5c);hvd(DJ,new B4c,new D4c);hvd(xK,new F4c,new H4c);hvd(jK,new J4c,new L4c);hvd(uK,new N4c,new P4c);hvd(kL,new R4c,new T4c)} +function R5d(a){var b,c,d,e,f,g;f=0;b=wId(a);!!b.Bj()&&(f|=4);(a.Bb&Cve)!=0&&(f|=2);if(JD(a,99)){c=BD(a,18);e=zUd(c);(c.Bb&ote)!=0&&(f|=32);if(e){aLd(WId(e));f|=8;g=e.t;(g>1||g==-1)&&(f|=16);(e.Bb&ote)!=0&&(f|=64)}(c.Bb&Tje)!=0&&(f|=Dve);f|=zte}else{if(JD(b,457)){f|=512}else{d=b.Bj();!!d&&(d.i&1)!=0&&(f|=256)}}(a.Bb&512)!=0&&(f|=128);return f} +function hc(a,b){var c,d,e,f,g;a=a==null?Xhe:(uCb(a),a);for(e=0;e<b.length;e++){b[e]=ic(b[e])}c=new Vfb;g=0;d=0;while(d<b.length){f=a.indexOf('%s',g);if(f==-1){break}c.a+=''+qfb(a==null?Xhe:(uCb(a),a),g,f);Pfb(c,b[d++]);g=f+2}Ofb(c,a,g,a.length);if(d<b.length){c.a+=' [';Pfb(c,b[d++]);while(d<b.length){c.a+=She;Pfb(c,b[d++])}c.a+=']'}return c.a} +function m3b(a){var b,c,d,e,f;f=new Skb(a.a.c.length);for(e=new olb(a.a);e.a<e.c.c.length;){d=BD(mlb(e),10);c=BD(vNb(d,(Nyc(),mxc)),163);b=null;switch(c.g){case 1:case 2:b=(Gqc(),Fqc);break;case 3:case 4:b=(Gqc(),Dqc);}if(b){yNb(d,(wtc(),Bsc),(Gqc(),Fqc));b==Dqc?o3b(d,c,(KAc(),HAc)):b==Fqc&&o3b(d,c,(KAc(),IAc))}else{f.c[f.c.length]=d}}return f} +function MHc(a,b){var c,d,e,f,g,h,i;c=0;for(i=new olb(b);i.a<i.c.c.length;){h=BD(mlb(i),11);AHc(a.b,a.d[h.p]);g=0;for(e=new b1b(h.b);llb(e.a)||llb(e.b);){d=BD(llb(e.a)?mlb(e.a):mlb(e.b),17);if(WHc(d)){f=aIc(a,h==d.c?d.d:d.c);if(f>a.d[h.p]){c+=zHc(a.b,f);Wjb(a.a,meb(f))}}else{++g}}c+=a.b.d*g;while(!akb(a.a)){xHc(a.b,BD(fkb(a.a),19).a)}}return c} +function Y6d(a,b){var c;if(a.f==W6d){c=$1d(q1d((O6d(),M6d),b));return a.e?c==4&&b!=(m8d(),k8d)&&b!=(m8d(),h8d)&&b!=(m8d(),i8d)&&b!=(m8d(),j8d):c==2}if(!!a.d&&(a.d.Hc(b)||a.d.Hc(_1d(q1d((O6d(),M6d),b)))||a.d.Hc(e1d((O6d(),M6d),a.b,b)))){return true}if(a.f){if(x1d((O6d(),a.f),b2d(q1d(M6d,b)))){c=$1d(q1d(M6d,b));return a.e?c==4:c==2}}return false} +function iVc(a,b,c,d){var e,f,g,h,i,j,k,l;g=BD(hkd(c,(Y9c(),C9c)),8);i=g.a;k=g.b+a;e=$wnd.Math.atan2(k,i);e<0&&(e+=dre);e+=b;e>dre&&(e-=dre);h=BD(hkd(d,C9c),8);j=h.a;l=h.b+a;f=$wnd.Math.atan2(l,j);f<0&&(f+=dre);f+=b;f>dre&&(f-=dre);return Iy(),My(1.0E-10),$wnd.Math.abs(e-f)<=1.0E-10||e==f||isNaN(e)&&isNaN(f)?0:e<f?-1:e>f?1:Ny(isNaN(e),isNaN(f))} +function YDb(a){var b,c,d,e,f,g,h;h=new Lqb;for(d=new olb(a.a.b);d.a<d.c.c.length;){b=BD(mlb(d),57);Rhb(h,b,new Rkb)}for(e=new olb(a.a.b);e.a<e.c.c.length;){b=BD(mlb(e),57);b.i=Qje;for(g=b.c.Kc();g.Ob();){f=BD(g.Pb(),57);BD(Wd(irb(h.f,f)),15).Fc(b)}}for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),57);b.c.$b();b.c=BD(Wd(irb(h.f,b)),15)}QDb(a)} +function yVb(a){var b,c,d,e,f,g,h;h=new Lqb;for(d=new olb(a.a.b);d.a<d.c.c.length;){b=BD(mlb(d),81);Rhb(h,b,new Rkb)}for(e=new olb(a.a.b);e.a<e.c.c.length;){b=BD(mlb(e),81);b.o=Qje;for(g=b.f.Kc();g.Ob();){f=BD(g.Pb(),81);BD(Wd(irb(h.f,f)),15).Fc(b)}}for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),81);b.f.$b();b.f=BD(Wd(irb(h.f,b)),15)}rVb(a)} +function dNb(a,b,c,d){var e,f;cNb(a,b,c,d);qNb(b,a.j-b.j+c);rNb(b,a.k-b.k+d);for(f=new olb(b.f);f.a<f.c.c.length;){e=BD(mlb(f),324);switch(e.a.g){case 0:nNb(a,b.g+e.b.a,0,b.g+e.c.a,b.i-1);break;case 1:nNb(a,b.g+b.o,b.i+e.b.a,a.o-1,b.i+e.c.a);break;case 2:nNb(a,b.g+e.b.a,b.i+b.p,b.g+e.c.a,a.p-1);break;default:nNb(a,0,b.i+e.b.a,b.g-1,b.i+e.c.a);}}} +function aNb(b,c,d,e,f){var g,h,i;try{if(c>=b.o){throw vbb(new rcb)}i=c>>5;h=c&31;g=Nbb(1,Tbb(Nbb(h,1)));f?(b.n[d][i]=Mbb(b.n[d][i],g)):(b.n[d][i]=xbb(b.n[d][i],Lbb(g)));g=Nbb(g,1);e?(b.n[d][i]=Mbb(b.n[d][i],g)):(b.n[d][i]=xbb(b.n[d][i],Lbb(g)))}catch(a){a=ubb(a);if(JD(a,320)){throw vbb(new qcb(Dle+b.o+'*'+b.p+Ele+c+She+d+Fle))}else throw vbb(a)}} +function BUc(a,b,c,d){var e,f,g;if(b){f=Edb(ED(vNb(b,(mTc(),fTc))))+d;g=c+Edb(ED(vNb(b,bTc)))/2;yNb(b,kTc,meb(Tbb(Cbb($wnd.Math.round(f)))));yNb(b,lTc,meb(Tbb(Cbb($wnd.Math.round(g)))));b.d.b==0||BUc(a,BD(pr((e=Jsb((new ZRc(b)).a.d,0),new aSc(e))),86),c+Edb(ED(vNb(b,bTc)))+a.a,d+Edb(ED(vNb(b,cTc))));vNb(b,iTc)!=null&&BUc(a,BD(vNb(b,iTc),86),c,d)}} +function N9b(a,b){var c,d,e,f,g,h,i,j,k,l,m;i=Q_b(b.a);e=Edb(ED(vNb(i,(Nyc(),pyc))))*2;k=Edb(ED(vNb(i,wyc)));j=$wnd.Math.max(e,k);f=KC(UD,Vje,25,b.f-b.c+1,15,1);d=-j;c=0;for(h=b.b.Kc();h.Ob();){g=BD(h.Pb(),10);d+=a.a[g.c.p]+j;f[c++]=d}d+=a.a[b.a.c.p]+j;f[c++]=d;for(m=new olb(b.e);m.a<m.c.c.length;){l=BD(mlb(m),10);d+=a.a[l.c.p]+j;f[c++]=d}return f} +function GHc(a,b,c,d){var e,f,g,h,i,j,k,l,m;m=new Hxb(new pIc(a));for(h=OC(GC(OQ,1),kne,10,0,[b,c]),i=0,j=h.length;i<j;++i){g=h[i];for(l=CHc(g,d).Kc();l.Ob();){k=BD(l.Pb(),11);for(f=new b1b(k.b);llb(f.a)||llb(f.b);){e=BD(llb(f.a)?mlb(f.a):mlb(f.b),17);if(!OZb(e)){Iwb(m.a,k,(Bcb(),zcb))==null;WHc(e)&&Axb(m,k==e.c?e.d:e.c)}}}}return Qb(m),new Tkb(m)} +function zhd(a,b){var c,d,e,f;f=BD(hkd(a,(Y9c(),A9c)),61).g-BD(hkd(b,A9c),61).g;if(f!=0){return f}c=BD(hkd(a,v9c),19);d=BD(hkd(b,v9c),19);if(!!c&&!!d){e=c.a-d.a;if(e!=0){return e}}switch(BD(hkd(a,A9c),61).g){case 1:return Kdb(a.i,b.i);case 2:return Kdb(a.j,b.j);case 3:return Kdb(b.i,a.i);case 4:return Kdb(b.j,a.j);default:throw vbb(new Zdb(ine));}} +function _od(a){var b,c,d;if((a.Db&64)!=0)return fld(a);b=new Wfb(ete);c=a.k;if(!c){!a.n&&(a.n=new cUd(D2,a,1,7));if(a.n.i>0){d=(!a.n&&(a.n=new cUd(D2,a,1,7)),BD(qud(a.n,0),137)).a;!d||Qfb(Qfb((b.a+=' "',b),d),'"')}}else{Qfb(Qfb((b.a+=' "',b),c),'"')}Qfb(Lfb(Qfb(Lfb(Qfb(Lfb(Qfb(Lfb((b.a+=' (',b),a.i),','),a.j),' | '),a.g),','),a.f),')');return b.a} +function opd(a){var b,c,d;if((a.Db&64)!=0)return fld(a);b=new Wfb(fte);c=a.k;if(!c){!a.n&&(a.n=new cUd(D2,a,1,7));if(a.n.i>0){d=(!a.n&&(a.n=new cUd(D2,a,1,7)),BD(qud(a.n,0),137)).a;!d||Qfb(Qfb((b.a+=' "',b),d),'"')}}else{Qfb(Qfb((b.a+=' "',b),c),'"')}Qfb(Lfb(Qfb(Lfb(Qfb(Lfb(Qfb(Lfb((b.a+=' (',b),a.i),','),a.j),' | '),a.g),','),a.f),')');return b.a} +function h4c(a,b){var c,d,e,f,g,h,i;if(b==null||b.length==0){return null}e=BD(Phb(a.a,b),149);if(!e){for(d=(h=(new $ib(a.b)).a.vc().Kc(),new djb(h));d.a.Ob();){c=(f=BD(d.a.Pb(),42),BD(f.dd(),149));g=c.c;i=b.length;if(dfb(g.substr(g.length-i,i),b)&&(b.length==g.length||bfb(g,g.length-b.length-1)==46)){if(e){return null}e=c}}!!e&&Shb(a.a,b,e)}return e} +function QLb(a,b){var c,d,e,f;c=new VLb;d=BD(GAb(NAb(new YAb(null,new Kub(a.f,16)),c),Ayb(new hzb,new jzb,new Gzb,new Izb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Eyb),Dyb]))),21);e=d.gc();d=BD(GAb(NAb(new YAb(null,new Kub(b.f,16)),c),Ayb(new hzb,new jzb,new Gzb,new Izb,OC(GC(xL,1),Kie,132,0,[Eyb,Dyb]))),21);f=d.gc();if(e<f){return -1}if(e==f){return 0}return 1} +function r5b(a){var b,c,d;if(!wNb(a,(Nyc(),xxc))){return}d=BD(vNb(a,xxc),21);if(d.dc()){return}c=(b=BD(gdb(B1),9),new xqb(b,BD(_Bb(b,b.length),9),0));d.Hc((Hbd(),Cbd))?rqb(c,Cbd):rqb(c,Dbd);d.Hc(Abd)||rqb(c,Abd);d.Hc(zbd)?rqb(c,Gbd):d.Hc(ybd)?rqb(c,Fbd):d.Hc(Bbd)&&rqb(c,Ebd);d.Hc(Gbd)?rqb(c,zbd):d.Hc(Fbd)?rqb(c,ybd):d.Hc(Ebd)&&rqb(c,Bbd);yNb(a,xxc,c)} +function kHc(a){var b,c,d,e,f,g,h;e=BD(vNb(a,(wtc(),Psc)),10);d=a.j;c=(tCb(0,d.c.length),BD(d.c[0],11));for(g=new olb(e.j);g.a<g.c.c.length;){f=BD(mlb(g),11);if(PD(f)===PD(vNb(c,$sc))){if(f.j==(Ucd(),Acd)&&a.p>e.p){G0b(f,Rcd);if(f.d){h=f.o.b;b=f.a.b;f.a.b=h-b}}else if(f.j==Rcd&&e.p>a.p){G0b(f,Acd);if(f.d){h=f.o.b;b=f.a.b;f.a.b=-(h-b)}}break}}return e} +function NOc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o;f=c;if(c<d){m=(n=new uOc(a.p),o=new uOc(a.p),ye(n.e,a.e),n.q=a.q,n.r=o,lOc(n),ye(o.j,a.j),o.r=n,lOc(o),new vgd(n,o));l=BD(m.a,112);k=BD(m.b,112);e=(tCb(f,b.c.length),BD(b.c[f],329));g=UOc(a,l,k,e);for(j=c+1;j<=d;j++){h=(tCb(j,b.c.length),BD(b.c[j],329));i=UOc(a,l,k,h);if(SOc(h,i,e,g)){e=h;g=i}}}return f} +function wQb(a,b,c,d,e){var f,g,h,i,j,k,l;if(!(JD(b,239)||JD(b,354)||JD(b,186))){throw vbb(new Wdb('Method only works for ElkNode-, ElkLabel and ElkPort-objects.'))}g=a.a/2;i=b.i+d-g;k=b.j+e-g;j=i+b.g+a.a;l=k+b.f+a.a;f=new s7c;Dsb(f,new f7c(i,k));Dsb(f,new f7c(i,l));Dsb(f,new f7c(j,l));Dsb(f,new f7c(j,k));h=new XOb(f);tNb(h,b);c&&Rhb(a.b,b,h);return h} +function uXb(a,b,c){var d,e,f,g,h,i,j,k,l,m;f=new f7c(b,c);for(k=new olb(a.a);k.a<k.c.c.length;){j=BD(mlb(k),10);P6c(j.n,f);for(m=new olb(j.j);m.a<m.c.c.length;){l=BD(mlb(m),11);for(e=new olb(l.g);e.a<e.c.c.length;){d=BD(mlb(e),17);q7c(d.a,f);g=BD(vNb(d,(Nyc(),jxc)),74);!!g&&q7c(g,f);for(i=new olb(d.b);i.a<i.c.c.length;){h=BD(mlb(i),70);P6c(h.n,f)}}}}} +function g_b(a,b,c){var d,e,f,g,h,i,j,k,l,m;f=new f7c(b,c);for(k=new olb(a.a);k.a<k.c.c.length;){j=BD(mlb(k),10);P6c(j.n,f);for(m=new olb(j.j);m.a<m.c.c.length;){l=BD(mlb(m),11);for(e=new olb(l.g);e.a<e.c.c.length;){d=BD(mlb(e),17);q7c(d.a,f);g=BD(vNb(d,(Nyc(),jxc)),74);!!g&&q7c(g,f);for(i=new olb(d.b);i.a<i.c.c.length;){h=BD(mlb(i),70);P6c(h.n,f)}}}}} +function N1b(a){if((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b).i==0){throw vbb(new z2c('Edges must have a source.'))}else if((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c).i==0){throw vbb(new z2c('Edges must have a target.'))}else{!a.b&&(a.b=new y5d(z2,a,4,7));if(!(a.b.i<=1&&(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c.i<=1))){throw vbb(new z2c('Hyperedges are not supported.'))}}} +function OFc(a,b){var c,d,e,f,g,h,i,j,k,l;l=0;f=new jkb;Wjb(f,b);while(f.b!=f.c){i=BD(fkb(f),214);j=0;k=BD(vNb(b.j,(Nyc(),ywc)),339);g=Edb(ED(vNb(b.j,uwc)));h=Edb(ED(vNb(b.j,vwc)));if(k!=(tAc(),rAc)){j+=g*PFc(i.e,k);j+=h*QFc(i.e)}l+=pHc(i.d,i.e)+j;for(e=new olb(i.b);e.a<e.c.c.length;){d=BD(mlb(e),37);c=BD(Ikb(a.b,d.p),214);c.s||(l+=NFc(a,c))}}return l} +function dhb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;n=b.length;i=n;BCb(0,b.length);if(b.charCodeAt(0)==45){l=-1;m=1;--n}else{l=1;m=0}f=(phb(),ohb)[10];e=n/f|0;q=n%f;q!=0&&++e;h=KC(WD,oje,25,e,15,1);c=nhb[8];g=0;o=m+(q==0?f:q);for(p=m;p<i;p=o,o=p+f){d=Icb(b.substr(p,o-p),Rie,Ohe);j=(Dhb(),Hhb(h,h,g,c));j+=xhb(h,g,d);h[g++]=j}k=g;a.e=l;a.d=k;a.a=h;Jgb(a)} +function SGb(a,b,c,d,e,f,g){a.c=d.qf().a;a.d=d.qf().b;if(e){a.c+=e.qf().a;a.d+=e.qf().b}a.b=b.rf().a;a.a=b.rf().b;if(!e){c?(a.c-=g+b.rf().a):(a.c+=d.rf().a+g)}else{switch(e.Hf().g){case 0:case 2:a.c+=e.rf().a+g+f.a+g;break;case 4:a.c-=g+f.a+g+b.rf().a;break;case 1:a.c+=e.rf().a+g;a.d-=g+f.b+g+b.rf().b;break;case 3:a.c+=e.rf().a+g;a.d+=e.rf().b+g+f.b+g;}}} +function gac(a,b){var c,d;this.b=new Rkb;this.e=new Rkb;this.a=a;this.d=b;dac(this);eac(this);this.b.dc()?(this.c=a.c.p):(this.c=BD(this.b.Xb(0),10).c.p);this.e.c.length==0?(this.f=a.c.p):(this.f=BD(Ikb(this.e,this.e.c.length-1),10).c.p);for(d=BD(vNb(a,(wtc(),ktc)),15).Kc();d.Ob();){c=BD(d.Pb(),70);if(wNb(c,(Nyc(),Owc))){this.d=BD(vNb(c,Owc),227);break}}} +function Anc(a,b,c){var d,e,f,g,h,i,j,k;d=BD(Ohb(a.a,b),53);f=BD(Ohb(a.a,c),53);e=BD(Ohb(a.e,b),53);g=BD(Ohb(a.e,c),53);d.a.zc(c,d);g.a.zc(b,g);for(k=f.a.ec().Kc();k.Ob();){j=BD(k.Pb(),10);d.a.zc(j,d);Qqb(BD(Ohb(a.e,j),53),b);ye(BD(Ohb(a.e,j),53),e)}for(i=e.a.ec().Kc();i.Ob();){h=BD(i.Pb(),10);g.a.zc(h,g);Qqb(BD(Ohb(a.a,h),53),c);ye(BD(Ohb(a.a,h),53),f)}} +function WGc(a,b,c){var d,e,f,g,h,i,j,k;d=BD(Ohb(a.a,b),53);f=BD(Ohb(a.a,c),53);e=BD(Ohb(a.b,b),53);g=BD(Ohb(a.b,c),53);d.a.zc(c,d);g.a.zc(b,g);for(k=f.a.ec().Kc();k.Ob();){j=BD(k.Pb(),10);d.a.zc(j,d);Qqb(BD(Ohb(a.b,j),53),b);ye(BD(Ohb(a.b,j),53),e)}for(i=e.a.ec().Kc();i.Ob();){h=BD(i.Pb(),10);g.a.zc(h,g);Qqb(BD(Ohb(a.a,h),53),c);ye(BD(Ohb(a.a,h),53),f)}} +function doc(a,b){var c,d,e;Odd(b,'Breaking Point Insertion',1);d=new Xoc(a);switch(BD(vNb(a,(Nyc(),Gyc)),337).g){case 2:e=new hpc;case 0:e=new Ync;break;default:e=new kpc;}c=e.Vf(a,d);Ccb(DD(vNb(a,Iyc)))&&(c=coc(a,c));if(!e.Wf()&&wNb(a,Myc)){switch(BD(vNb(a,Myc),338).g){case 2:c=tpc(d,c);break;case 1:c=rpc(d,c);}}if(c.dc()){Qdd(b);return}aoc(a,c);Qdd(b)} +function $qd(a,b,c){var d,e,f,g,h,i,j,k,l,m;k=null;m=b;l=Rqd(a,dtd(c),m);Lkd(l,_pd(m,Vte));g=Ypd(m,Lte);d=new mrd(a,l);oqd(d.a,d.b,g);h=Ypd(m,Mte);e=new nrd(a,l);pqd(e.a,e.b,h);if((!l.b&&(l.b=new y5d(z2,l,4,7)),l.b).i==0||(!l.c&&(l.c=new y5d(z2,l,5,8)),l.c).i==0){f=_pd(m,Vte);i=Zte+f;j=i+$te;throw vbb(new cqd(j))}grd(m,l);_qd(a,m,l);k=crd(a,m,l);return k} +function yGb(a,b){var c,d,e,f,g,h,i;e=KC(WD,oje,25,a.e.a.c.length,15,1);for(g=new olb(a.e.a);g.a<g.c.c.length;){f=BD(mlb(g),121);e[f.d]+=f.b.a.c.length}h=Ru(b);while(h.b!=0){f=BD(h.b==0?null:(sCb(h.b!=0),Nsb(h,h.a.a)),121);for(d=vr(new olb(f.g.a));d.Ob();){c=BD(d.Pb(),213);i=c.e;i.e=$wnd.Math.max(i.e,f.e+c.a);--e[i.d];e[i.d]==0&&(Gsb(h,i,h.c.b,h.c),true)}}} +function CGb(a){var b,c,d,e,f,g,h,i,j,k,l;c=Rie;e=Ohe;for(h=new olb(a.e.a);h.a<h.c.c.length;){f=BD(mlb(h),121);e=$wnd.Math.min(e,f.e);c=$wnd.Math.max(c,f.e)}b=KC(WD,oje,25,c-e+1,15,1);for(g=new olb(a.e.a);g.a<g.c.c.length;){f=BD(mlb(g),121);f.e-=e;++b[f.e]}d=0;if(a.k!=null){for(j=a.k,k=0,l=j.length;k<l;++k){i=j[k];b[d++]+=i;if(b.length==d){break}}}return b} +function ixd(a){switch(a.d){case 9:case 8:{return true}case 3:case 5:case 4:case 6:{return false}case 7:{return BD(hxd(a),19).a==a.o}case 1:case 2:{if(a.o==-2){return false}else{switch(a.p){case 0:case 1:case 2:case 6:case 5:case 7:{return Bbb(a.k,a.f)}case 3:case 4:{return a.j==a.e}default:{return a.n==null?a.g==null:pb(a.n,a.g)}}}}default:{return false}}} +function $ad(a){r4c(a,new E3c(P3c(M3c(O3c(N3c(new R3c,Qse),'ELK Fixed'),'Keeps the current layout as it is, without any automatic modification. Optional coordinates can be given for nodes and edge bend points.'),new bbd)));p4c(a,Qse,ame,Xad);p4c(a,Qse,uqe,Ksd(Yad));p4c(a,Qse,use,Ksd(Sad));p4c(a,Qse,Fme,Ksd(Tad));p4c(a,Qse,Tme,Ksd(Vad));p4c(a,Qse,bqe,Ksd(Uad))} +function ro(a,b,c){var d,e,f,g,h;d=Tbb(Ibb(Eie,keb(Tbb(Ibb(b==null?0:tb(b),Fie)),15)));h=Tbb(Ibb(Eie,keb(Tbb(Ibb(c==null?0:tb(c),Fie)),15)));f=uo(a,b,d);if(!!f&&h==f.f&&Hb(c,f.i)){return c}g=vo(a,c,h);if(g){throw vbb(new Wdb('value already present: '+c))}e=new $o(b,d,c,h);if(f){mo(a,f);po(a,e,f);f.e=null;f.c=null;return f.i}else{po(a,e,null);to(a);return null}} +function E4b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o;k=c.a.c;g=c.a.c+c.a.b;f=BD(Ohb(c.c,b),459);n=f.f;o=f.a;f.b?(i=new f7c(g,n)):(i=new f7c(k,n));f.c?(l=new f7c(k,o)):(l=new f7c(g,o));e=k;c.p||(e+=a.c);e+=c.F+c.v*a.b;j=new f7c(e,n);m=new f7c(e,o);n7c(b.a,OC(GC(m1,1),nie,8,0,[i,j]));h=c.d.a.gc()>1;if(h){d=new f7c(e,c.b);Dsb(b.a,d)}n7c(b.a,OC(GC(m1,1),nie,8,0,[m,l]))} +function Nid(a,b,c){var d,e,f,g,h,i;if(!b){return null}else{if(c<=-1){d=XKd(b.Tg(),-1-c);if(JD(d,99)){return BD(d,18)}else{g=BD(b.ah(d),153);for(h=0,i=g.gc();h<i;++h){if(PD(g.jl(h))===PD(a)){e=g.il(h);if(JD(e,99)){f=BD(e,18);if((f.Bb&ote)!=0){return f}}}}throw vbb(new Zdb('The containment feature could not be located'))}}else{return zUd(BD(XKd(a.Tg(),c),18))}}} +function Xee(a){var b,c,d,e,f;d=a.length;b=new Ifb;f=0;while(f<d){c=bfb(a,f++);if(c==9||c==10||c==12||c==13||c==32)continue;if(c==35){while(f<d){c=bfb(a,f++);if(c==13||c==10)break}continue}if(c==92&&f<d){if((e=(BCb(f,a.length),a.charCodeAt(f)))==35||e==9||e==10||e==12||e==13||e==32){Afb(b,e&aje);++f}else{b.a+='\\';Afb(b,e&aje);++f}}else Afb(b,c&aje)}return b.a} +function GVc(a,b){var c,d,e;for(d=new olb(b);d.a<d.c.c.length;){c=BD(mlb(d),33);Rc(a.a,c,c);Rc(a.b,c,c);e=gVc(c);if(e.c.length!=0){!!a.d&&a.d.lg(e);Rc(a.a,c,(tCb(0,e.c.length),BD(e.c[0],33)));Rc(a.b,c,BD(Ikb(e,e.c.length-1),33));while(dVc(e).c.length!=0){e=dVc(e);!!a.d&&a.d.lg(e);Rc(a.a,c,(tCb(0,e.c.length),BD(e.c[0],33)));Rc(a.b,c,BD(Ikb(e,e.c.length-1),33))}}}} +function fnc(a){var b,c,d,e,f,g,h,i,j,k;c=0;for(h=new olb(a.d);h.a<h.c.c.length;){g=BD(mlb(h),101);!!g.i&&(g.i.c=c++)}b=IC(sbb,[nie,dle],[177,25],16,[c,c],2);k=a.d;for(e=0;e<k.c.length;e++){i=(tCb(e,k.c.length),BD(k.c[e],101));if(i.i){for(f=e+1;f<k.c.length;f++){j=(tCb(f,k.c.length),BD(k.c[f],101));if(j.i){d=knc(i,j);b[i.i.c][j.i.c]=d;b[j.i.c][i.i.c]=d}}}}return b} +function ht(a,b,c,d){var e,f,g;g=new qu(b,c);if(!a.a){a.a=a.e=g;Rhb(a.b,b,new pu(g));++a.c}else if(!d){a.e.b=g;g.d=a.e;a.e=g;e=BD(Ohb(a.b,b),283);if(!e){Rhb(a.b,b,e=new pu(g));++a.c}else{++e.a;f=e.c;f.c=g;g.e=f;e.c=g}}else{e=BD(Ohb(a.b,b),283);++e.a;g.d=d.d;g.e=d.e;g.b=d;g.c=d;!d.e?(BD(Ohb(a.b,b),283).b=g):(d.e.c=g);!d.d?(a.a=g):(d.d.b=g);d.d=g;d.e=g}++a.d;return g} +function mfb(a,b){var c,d,e,f,g,h,i,j;c=new RegExp(b,'g');i=KC(ZI,nie,2,0,6,1);d=0;j=a;f=null;while(true){h=c.exec(j);if(h==null||j==''){i[d]=j;break}else{g=h.index;i[d]=j.substr(0,g);j=qfb(j,g+h[0].length,j.length);c.lastIndex=0;if(f==j){i[d]=j.substr(0,1);j=j.substr(1)}f=j;++d}}if(a.length>0){e=i.length;while(e>0&&i[e-1]==''){--e}e<i.length&&(i.length=e)}return i} +function f1d(a,b){var c,d,e,f,g,h,i,j,k,l;l=_Kd(b);j=null;e=false;for(h=0,k=VKd(l.a).i;h<k;++h){g=BD(nOd(l,h,(f=BD(qud(VKd(l.a),h),87),i=f.c,JD(i,88)?BD(i,26):(jGd(),_Fd))),26);c=f1d(a,g);if(!c.dc()){if(!j){j=c}else{if(!e){e=true;j=new pFd(j)}j.Gc(c)}}}d=k1d(a,b);if(d.dc()){return !j?(mmb(),mmb(),jmb):j}else{if(!j){return d}else{e||(j=new pFd(j));j.Gc(d);return j}}} +function g1d(a,b){var c,d,e,f,g,h,i,j,k,l;l=_Kd(b);j=null;d=false;for(h=0,k=VKd(l.a).i;h<k;++h){f=BD(nOd(l,h,(e=BD(qud(VKd(l.a),h),87),i=e.c,JD(i,88)?BD(i,26):(jGd(),_Fd))),26);c=g1d(a,f);if(!c.dc()){if(!j){j=c}else{if(!d){d=true;j=new pFd(j)}j.Gc(c)}}}g=n1d(a,b);if(g.dc()){return !j?(mmb(),mmb(),jmb):j}else{if(!j){return g}else{d||(j=new pFd(j));j.Gc(g);return j}}} +function B2d(a,b,c){var d,e,f,g,h,i;if(JD(b,72)){return Txd(a,b,c)}else{h=null;f=null;d=BD(a.g,119);for(g=0;g<a.i;++g){e=d[g];if(pb(b,e.dd())){f=e.ak();if(JD(f,99)&&(BD(f,18).Bb&ote)!=0){h=e;break}}}if(h){if(oid(a.e)){i=f.$j()?H2d(a,4,f,b,null,M2d(a,f,b,JD(f,99)&&(BD(f,18).Bb&Tje)!=0),true):H2d(a,f.Kj()?2:1,f,b,f.zj(),-1,true);c?c.Ei(i):(c=i)}c=B2d(a,h,c)}return c}} +function pKb(a){var b,c,d,e;d=a.o;$Jb();if(a.A.dc()||pb(a.A,ZJb)){e=d.a}else{e=gIb(a.f);if(a.A.Hc((tdd(),qdd))&&!a.B.Hc((Idd(),Edd))){e=$wnd.Math.max(e,gIb(BD(Mpb(a.p,(Ucd(),Acd)),244)));e=$wnd.Math.max(e,gIb(BD(Mpb(a.p,Rcd),244)))}b=aKb(a);!!b&&(e=$wnd.Math.max(e,b.a))}Ccb(DD(a.e.yf().We((Y9c(),$8c))))?(d.a=$wnd.Math.max(d.a,e)):(d.a=e);c=a.f.i;c.c=0;c.b=e;hIb(a.f)} +function $0d(a,b){var c,d,e,f,g,h,i,j,k;c=b.Hh(a.a);if(c){i=GD(AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),'memberTypes'));if(i!=null){j=new Rkb;for(f=mfb(i,'\\w'),g=0,h=f.length;g<h;++g){e=f[g];d=e.lastIndexOf('#');k=d==-1?w1d(a,b.Aj(),e):d==0?v1d(a,null,e.substr(1)):v1d(a,e.substr(0,d),e.substr(d+1));JD(k,148)&&Ekb(j,BD(k,148))}return j}}return mmb(),mmb(),jmb} +function tRb(a,b,c){var d,e,f,g,h,i,j,k;Odd(c,kme,1);a.bf(b);f=0;while(a.df(f)){for(k=new olb(b.e);k.a<k.c.c.length;){i=BD(mlb(k),144);for(h=ul(pl(OC(GC(KI,1),Uhe,20,0,[b.e,b.d,b.b])));Qr(h);){g=BD(Rr(h),357);if(g!=i){e=a.af(g,i);!!e&&P6c(i.a,e)}}}for(j=new olb(b.e);j.a<j.c.c.length;){i=BD(mlb(j),144);d=i.a;Q6c(d,-a.d,-a.d,a.d,a.d);P6c(i.d,d);X6c(d)}a.cf();++f}Qdd(c)} +function $2d(a,b,c){var d,e,f,g;g=S6d(a.e.Tg(),b);d=BD(a.g,119);Q6d();if(BD(b,66).Oj()){for(f=0;f<a.i;++f){e=d[f];if(g.rl(e.ak())){if(pb(e,c)){Xxd(a,f);return true}}}}else if(c!=null){for(f=0;f<a.i;++f){e=d[f];if(g.rl(e.ak())){if(pb(c,e.dd())){Xxd(a,f);return true}}}}else{for(f=0;f<a.i;++f){e=d[f];if(g.rl(e.ak())){if(e.dd()==null){Xxd(a,f);return true}}}}return false} +function sDc(a,b){var c,d,e,f,g;a.c==null||a.c.length<b.c.length?(a.c=KC(sbb,dle,25,b.c.length,16,1)):Blb(a.c);a.a=new Rkb;d=0;for(g=new olb(b);g.a<g.c.c.length;){e=BD(mlb(g),10);e.p=d++}c=new Psb;for(f=new olb(b);f.a<f.c.c.length;){e=BD(mlb(f),10);if(!a.c[e.p]){tDc(a,e);c.b==0||(sCb(c.b!=0),BD(c.a.a.c,15)).gc()<a.a.c.length?Esb(c,a.a):Fsb(c,a.a);a.a=new Rkb}}return c} +function jYc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o;g=BD(qud(b,0),33);dld(g,0);eld(g,0);m=new Rkb;m.c[m.c.length]=g;h=g;f=new d$c(a.a,g.g,g.f,(k$c(),j$c));for(n=1;n<b.i;n++){o=BD(qud(b,n),33);i=kYc(a,g$c,o,h,f,m,c);j=kYc(a,f$c,o,h,f,m,c);k=kYc(a,i$c,o,h,f,m,c);l=kYc(a,h$c,o,h,f,m,c);e=mYc(a,i,j,k,l,o,h,d);dld(o,e.d);eld(o,e.e);c$c(e,j$c);f=e;h=o;m.c[m.c.length]=o}return f} +function K0c(a){r4c(a,new E3c(P3c(M3c(O3c(N3c(new R3c,ase),'ELK SPOrE Overlap Removal'),'A node overlap removal algorithm proposed by Nachmanson et al. in "Node overlap removal by growing a tree".'),new N0c)));p4c(a,ase,Qre,Ksd(I0c));p4c(a,ase,ame,G0c);p4c(a,ase,wme,8);p4c(a,ase,Vre,Ksd(H0c));p4c(a,ase,Yre,Ksd(E0c));p4c(a,ase,Zre,Ksd(F0c));p4c(a,ase,Zpe,(Bcb(),false))} +function sXb(a,b,c,d){var e,f,g,h,i,j,k,l,m,n;g=O6c(b.c,c,d);for(l=new olb(b.a);l.a<l.c.c.length;){k=BD(mlb(l),10);P6c(k.n,g);for(n=new olb(k.j);n.a<n.c.c.length;){m=BD(mlb(n),11);for(f=new olb(m.g);f.a<f.c.c.length;){e=BD(mlb(f),17);q7c(e.a,g);h=BD(vNb(e,(Nyc(),jxc)),74);!!h&&q7c(h,g);for(j=new olb(e.b);j.a<j.c.c.length;){i=BD(mlb(j),70);P6c(i.n,g)}}}Ekb(a.a,k);k.a=a}} +function g9b(a,b){var c,d,e,f,g;Odd(b,'Node and Port Label Placement and Node Sizing',1);MGb((a$b(),new l$b(a,true,true,new j9b)));if(BD(vNb(a,(wtc(),Ksc)),21).Hc((Orc(),Hrc))){f=BD(vNb(a,(Nyc(),Yxc)),21);e=f.Hc((rcd(),ocd));g=Ccb(DD(vNb(a,Zxc)));for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),29);MAb(JAb(new YAb(null,new Kub(c.a,16)),new l9b),new n9b(f,e,g))}}Qdd(b)} +function Y0d(a,b){var c,d,e,f,g,h;c=b.Hh(a.a);if(c){h=GD(AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),eue));if(h!=null){e=kfb(h,wfb(35));d=b.Hj();if(e==-1){g=u1d(a,bKd(d));f=h}else if(e==0){g=null;f=h.substr(1)}else{g=h.substr(0,e);f=h.substr(e+1)}switch($1d(q1d(a,b))){case 2:case 3:{return j1d(a,d,g,f)}case 0:case 4:case 5:case 6:{return m1d(a,d,g,f)}}}}return null} +function q2d(a,b,c){var d,e,f,g,h;g=(Q6d(),BD(b,66).Oj());if(T6d(a.e,b)){if(b.hi()&&F2d(a,b,c,JD(b,99)&&(BD(b,18).Bb&Tje)!=0)){return false}}else{h=S6d(a.e.Tg(),b);d=BD(a.g,119);for(f=0;f<a.i;++f){e=d[f];if(h.rl(e.ak())){if(g?pb(e,c):c==null?e.dd()==null:pb(c,e.dd())){return false}else{BD(Gtd(a,f,g?BD(c,72):R6d(b,c)),72);return true}}}}return wtd(a,g?BD(c,72):R6d(b,c))} +function uVb(a){var b,c,d,e,f,g,h,i;if(a.d){throw vbb(new Zdb((fdb(LP),Jke+LP.k+Kke)))}a.c==(ead(),cad)&&tVb(a,aad);for(c=new olb(a.a.a);c.a<c.c.c.length;){b=BD(mlb(c),189);b.e=0}for(g=new olb(a.a.b);g.a<g.c.c.length;){f=BD(mlb(g),81);f.o=Qje;for(e=f.f.Kc();e.Ob();){d=BD(e.Pb(),81);++d.d.e}}JVb(a);for(i=new olb(a.a.b);i.a<i.c.c.length;){h=BD(mlb(i),81);h.k=true}return a} +function Ijc(a,b){var c,d,e,f,g,h,i,j;h=new pjc(a);c=new Psb;Gsb(c,b,c.c.b,c.c);while(c.b!=0){d=BD(c.b==0?null:(sCb(c.b!=0),Nsb(c,c.a.a)),113);d.d.p=1;for(g=new olb(d.e);g.a<g.c.c.length;){e=BD(mlb(g),409);kjc(h,e);j=e.d;j.d.p==0&&(Gsb(c,j,c.c.b,c.c),true)}for(f=new olb(d.b);f.a<f.c.c.length;){e=BD(mlb(f),409);kjc(h,e);i=e.c;i.d.p==0&&(Gsb(c,i,c.c.b,c.c),true)}}return h} +function hfd(a){var b,c,d,e,f;d=Edb(ED(hkd(a,(Y9c(),G9c))));if(d==1){return}_kd(a,d*a.g,d*a.f);c=Mq(Rq((!a.c&&(a.c=new cUd(F2,a,9,9)),a.c),new Hfd));for(f=ul(pl(OC(GC(KI,1),Uhe,20,0,[(!a.n&&(a.n=new cUd(D2,a,1,7)),a.n),(!a.c&&(a.c=new cUd(F2,a,9,9)),a.c),c])));Qr(f);){e=BD(Rr(f),470);e.Gg(d*e.Dg(),d*e.Eg());e.Fg(d*e.Cg(),d*e.Bg());b=BD(e.We(r9c),8);if(b){b.a*=d;b.b*=d}}} +function Mac(a,b,c,d,e){var f,g,h,i,j,k,l,m;for(g=new olb(a.b);g.a<g.c.c.length;){f=BD(mlb(g),29);m=l_b(f.a);for(j=m,k=0,l=j.length;k<l;++k){i=j[k];switch(BD(vNb(i,(Nyc(),mxc)),163).g){case 1:Qac(i);$_b(i,b);Nac(i,true,d);break;case 3:Rac(i);$_b(i,c);Nac(i,false,e);}}}h=new Bib(a.b,0);while(h.b<h.d.gc()){(sCb(h.b<h.d.gc()),BD(h.d.Xb(h.c=h.b++),29)).a.c.length==0&&uib(h)}} +function d1d(a,b){var c,d,e,f,g,h,i;c=b.Hh(a.a);if(c){i=GD(AAd((!c.b&&(c.b=new sId((jGd(),fGd),x6,c)),c.b),Dwe));if(i!=null){d=new Rkb;for(f=mfb(i,'\\w'),g=0,h=f.length;g<h;++g){e=f[g];dfb(e,'##other')?Ekb(d,'!##'+u1d(a,bKd(b.Hj()))):dfb(e,'##local')?(d.c[d.c.length]=null,true):dfb(e,Bwe)?Ekb(d,u1d(a,bKd(b.Hj()))):(d.c[d.c.length]=e,true)}return d}}return mmb(),mmb(),jmb} +function kMb(a,b){var c,d,e,f;c=new pMb;d=BD(GAb(NAb(new YAb(null,new Kub(a.f,16)),c),Ayb(new hzb,new jzb,new Gzb,new Izb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Eyb),Dyb]))),21);e=d.gc();d=BD(GAb(NAb(new YAb(null,new Kub(b.f,16)),c),Ayb(new hzb,new jzb,new Gzb,new Izb,OC(GC(xL,1),Kie,132,0,[Eyb,Dyb]))),21);f=d.gc();e=e==1?1:0;f=f==1?1:0;if(e<f){return -1}if(e==f){return 0}return 1} +function hZb(a){var b,c,d,e,f,g,h,i,j,k,l,m;h=a.i;e=Ccb(DD(vNb(h,(Nyc(),fxc))));k=0;d=0;for(j=new olb(a.g);j.a<j.c.c.length;){i=BD(mlb(j),17);g=OZb(i);f=g&&e&&Ccb(DD(vNb(i,gxc)));m=i.d.i;g&&f?++d:g&&!f?++k:Q_b(m).e==h?++d:++k}for(c=new olb(a.e);c.a<c.c.c.length;){b=BD(mlb(c),17);g=OZb(b);f=g&&e&&Ccb(DD(vNb(b,gxc)));l=b.c.i;g&&f?++k:g&&!f?++d:Q_b(l).e==h?++k:++d}return k-d} +function ULc(a,b,c,d){this.e=a;this.k=BD(vNb(a,(wtc(),otc)),304);this.g=KC(OQ,kne,10,b,0,1);this.b=KC(BI,nie,333,b,7,1);this.a=KC(OQ,kne,10,b,0,1);this.d=KC(BI,nie,333,b,7,1);this.j=KC(OQ,kne,10,b,0,1);this.i=KC(BI,nie,333,b,7,1);this.p=KC(BI,nie,333,b,7,1);this.n=KC(wI,nie,476,b,8,1);Alb(this.n,(Bcb(),false));this.f=KC(wI,nie,476,b,8,1);Alb(this.f,true);this.o=c;this.c=d} +function X9b(a,b){var c,d,e,f,g,h;if(b.dc()){return}if(BD(b.Xb(0),286).d==(Apc(),xpc)){O9b(a,b)}else{for(d=b.Kc();d.Ob();){c=BD(d.Pb(),286);switch(c.d.g){case 5:K9b(a,c,Q9b(a,c));break;case 0:K9b(a,c,(g=c.f-c.c+1,h=(g-1)/2|0,c.c+h));break;case 4:K9b(a,c,S9b(a,c));break;case 2:Y9b(c);K9b(a,c,(f=U9b(c),f?c.c:c.f));break;case 1:Y9b(c);K9b(a,c,(e=U9b(c),e?c.f:c.c));}P9b(c.a)}}} +function C4b(a,b){var c,d,e,f,g,h,i;if(b.e){return}b.e=true;for(d=b.d.a.ec().Kc();d.Ob();){c=BD(d.Pb(),17);if(b.o&&b.d.a.gc()<=1){g=b.a.c;h=b.a.c+b.a.b;i=new f7c(g+(h-g)/2,b.b);Dsb(BD(b.d.a.ec().Kc().Pb(),17).a,i);continue}e=BD(Ohb(b.c,c),459);if(e.b||e.c){E4b(a,c,b);continue}f=a.d==(tBc(),sBc)&&(e.d||e.e)&&K4b(a,b)&&b.d.a.gc()<=1;f?F4b(c,b):D4b(a,c,b)}b.k&&reb(b.d,new X4b)} +function zXc(a,b,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q,r,s,t;m=f;h=(d+e)/2+m;q=c*$wnd.Math.cos(h);r=c*$wnd.Math.sin(h);s=q-b.g/2;t=r-b.f/2;dld(b,s);eld(b,t);l=a.a.jg(b);p=2*$wnd.Math.acos(c/c+a.c);if(p<e-d){n=p/l;g=(d+e-p)/2}else{n=(e-d)/l;g=d}o=gVc(b);if(a.e){a.e.kg(a.d);a.e.lg(o)}for(j=new olb(o);j.a<j.c.c.length;){i=BD(mlb(j),33);k=a.a.jg(i);zXc(a,i,c+a.c,g,g+n*k,f);g+=n*k}} +function jA(a,b,c){var d;d=c.q.getMonth();switch(b){case 5:Qfb(a,OC(GC(ZI,1),nie,2,6,['J','F','M','A','M','J','J','A','S','O','N','D'])[d]);break;case 4:Qfb(a,OC(GC(ZI,1),nie,2,6,[bje,cje,dje,eje,fje,gje,hje,ije,jje,kje,lje,mje])[d]);break;case 3:Qfb(a,OC(GC(ZI,1),nie,2,6,['Jan','Feb','Mar','Apr',fje,'Jun','Jul','Aug','Sep','Oct','Nov','Dec'])[d]);break;default:EA(a,d+1,b);}} +function uGb(a,b){var c,d,e,f,g;Odd(b,'Network simplex',1);if(a.e.a.c.length<1){Qdd(b);return}for(f=new olb(a.e.a);f.a<f.c.c.length;){e=BD(mlb(f),121);e.e=0}g=a.e.a.c.length>=40;g&&FGb(a);wGb(a);vGb(a);c=zGb(a);d=0;while(!!c&&d<a.f){tGb(a,c,sGb(a,c));c=zGb(a);++d}g&&EGb(a);a.a?qGb(a,CGb(a)):CGb(a);a.b=null;a.d=null;a.p=null;a.c=null;a.g=null;a.i=null;a.n=null;a.o=null;Qdd(b)} +function JQb(a,b,c,d){var e,f,g,h,i,j,k,l,m;i=new f7c(c,d);c7c(i,BD(vNb(b,(HSb(),ESb)),8));for(m=new olb(b.e);m.a<m.c.c.length;){l=BD(mlb(m),144);P6c(l.d,i);Ekb(a.e,l)}for(h=new olb(b.c);h.a<h.c.c.length;){g=BD(mlb(h),282);for(f=new olb(g.a);f.a<f.c.c.length;){e=BD(mlb(f),559);P6c(e.d,i)}Ekb(a.c,g)}for(k=new olb(b.d);k.a<k.c.c.length;){j=BD(mlb(k),447);P6c(j.d,i);Ekb(a.d,j)}} +function _Bc(a,b){var c,d,e,f,g,h,i,j;for(i=new olb(b.j);i.a<i.c.c.length;){h=BD(mlb(i),11);for(e=new b1b(h.b);llb(e.a)||llb(e.b);){d=BD(llb(e.a)?mlb(e.a):mlb(e.b),17);c=d.c==h?d.d:d.c;f=c.i;if(b==f){continue}j=BD(vNb(d,(Nyc(),cyc)),19).a;j<0&&(j=0);g=f.p;if(a.b[g]==0){if(d.d==c){a.a[g]-=j+1;a.a[g]<=0&&a.c[g]>0&&Dsb(a.f,f)}else{a.c[g]-=j+1;a.c[g]<=0&&a.a[g]>0&&Dsb(a.e,f)}}}}} +function _Kb(a){var b,c,d,e,f,g,h,i,j;h=new Hxb(BD(Qb(new nLb),62));j=Qje;for(c=new olb(a.d);c.a<c.c.c.length;){b=BD(mlb(c),222);j=b.c.c;while(h.a.c!=0){i=BD(zjb(Bwb(h.a)),222);if(i.c.c+i.c.b<j){Jwb(h.a,i)!=null}else{break}}for(g=(e=new Ywb((new cxb((new Gjb(h.a)).a)).b),new Njb(e));sib(g.a.a);){f=(d=Wwb(g.a),BD(d.cd(),222));Dsb(f.b,b);Dsb(b.b,f)}Iwb(h.a,b,(Bcb(),zcb))==null}} +function QEc(a,b,c){var d,e,f,g,h,i,j,k,l;f=new Skb(b.c.length);for(j=new olb(b);j.a<j.c.c.length;){g=BD(mlb(j),10);Ekb(f,a.b[g.c.p][g.p])}LEc(a,f,c);l=null;while(l=MEc(f)){NEc(a,BD(l.a,233),BD(l.b,233),f)}b.c=KC(SI,Uhe,1,0,5,1);for(e=new olb(f);e.a<e.c.c.length;){d=BD(mlb(e),233);for(h=d.d,i=0,k=h.length;i<k;++i){g=h[i];b.c[b.c.length]=g;a.a[g.c.p][g.p].a=REc(d.g,d.d[0]).a}}} +function JRc(a,b){var c,d,e,f;if(0<(JD(a,14)?BD(a,14).gc():sr(a.Kc()))){e=b;if(1<e){--e;f=new KRc;for(d=a.Kc();d.Ob();){c=BD(d.Pb(),86);f=pl(OC(GC(KI,1),Uhe,20,0,[f,new ZRc(c)]))}return JRc(f,e)}if(e<0){f=new NRc;for(d=a.Kc();d.Ob();){c=BD(d.Pb(),86);f=pl(OC(GC(KI,1),Uhe,20,0,[f,new ZRc(c)]))}if(0<(JD(f,14)?BD(f,14).gc():sr(f.Kc()))){return JRc(f,e)}}}return BD(pr(a.Kc()),86)} +function Idd(){Idd=ccb;Bdd=new Jdd('DEFAULT_MINIMUM_SIZE',0);Ddd=new Jdd('MINIMUM_SIZE_ACCOUNTS_FOR_PADDING',1);Add=new Jdd('COMPUTE_PADDING',2);Edd=new Jdd('OUTSIDE_NODE_LABELS_OVERHANG',3);Fdd=new Jdd('PORTS_OVERHANG',4);Hdd=new Jdd('UNIFORM_PORT_SPACING',5);Gdd=new Jdd('SPACE_EFFICIENT_PORT_LABELS',6);Cdd=new Jdd('FORCE_TABULAR_NODE_LABELS',7);zdd=new Jdd('ASYMMETRICAL',8)} +function s6d(a,b){var c,d,e,f,g,h,i,j;if(!b){return null}else{c=(f=b.Tg(),!f?null:bKd(f).Nh().Jh(f));if(c){Xrb(a,b,c);e=b.Tg();for(i=0,j=(e.i==null&&TKd(e),e.i).length;i<j;++i){h=(d=(e.i==null&&TKd(e),e.i),i>=0&&i<d.length?d[i]:null);if(h.Ij()&&!h.Jj()){if(JD(h,322)){u6d(a,BD(h,34),b,c)}else{g=BD(h,18);(g.Bb&ote)!=0&&w6d(a,g,b,c)}}}b.kh()&&BD(c,49).vh(BD(b,49).qh())}return c}} +function tGb(a,b,c){var d,e,f;if(!b.f){throw vbb(new Wdb('Given leave edge is no tree edge.'))}if(c.f){throw vbb(new Wdb('Given enter edge is a tree edge already.'))}b.f=false;Sqb(a.p,b);c.f=true;Qqb(a.p,c);d=c.e.e-c.d.e-c.a;xGb(a,c.e,b)||(d=-d);for(f=new olb(a.e.a);f.a<f.c.c.length;){e=BD(mlb(f),121);xGb(a,e,b)||(e.e+=d)}a.j=1;Blb(a.c);DGb(a,BD(mlb(new olb(a.e.a)),121));rGb(a)} +function x6b(a,b){var c,d,e,f,g,h;h=BD(vNb(b,(Nyc(),Vxc)),98);if(!(h==(dcd(),_bd)||h==$bd)){return}e=(new f7c(b.f.a+b.d.b+b.d.c,b.f.b+b.d.d+b.d.a)).b;for(g=new olb(a.a);g.a<g.c.c.length;){f=BD(mlb(g),10);if(f.k!=(j0b(),e0b)){continue}c=BD(vNb(f,(wtc(),Hsc)),61);if(c!=(Ucd(),zcd)&&c!=Tcd){continue}d=Edb(ED(vNb(f,htc)));h==_bd&&(d*=e);f.n.b=d-BD(vNb(f,Txc),8).b;M_b(f,false,true)}} +function YDc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n;bEc(a,b,c);f=b[c];n=d?(Ucd(),Tcd):(Ucd(),zcd);if(ZDc(b.length,c,d)){e=b[d?c-1:c+1];UDc(a,e,d?(KAc(),IAc):(KAc(),HAc));for(i=f,k=0,m=i.length;k<m;++k){g=i[k];XDc(a,g,n)}UDc(a,f,d?(KAc(),HAc):(KAc(),IAc));for(h=e,j=0,l=h.length;j<l;++j){g=h[j];!!g.e||XDc(a,g,Wcd(n))}}else{for(h=f,j=0,l=h.length;j<l;++j){g=h[j];XDc(a,g,n)}}return false} +function nFc(a,b,c,d){var e,f,g,h,i,j,k;i=V_b(b,c);(c==(Ucd(),Rcd)||c==Tcd)&&(i=JD(i,152)?km(BD(i,152)):JD(i,131)?BD(i,131).a:JD(i,54)?new ov(i):new dv(i));g=false;do{e=false;for(f=0;f<i.gc()-1;f++){j=BD(i.Xb(f),11);h=BD(i.Xb(f+1),11);if(oFc(a,j,h,d)){g=true;cIc(a.a,BD(i.Xb(f),11),BD(i.Xb(f+1),11));k=BD(i.Xb(f+1),11);i._c(f+1,BD(i.Xb(f),11));i._c(f,k);e=true}}}while(e);return g} +function W2d(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o;if(oid(a.e)){if(b!=c){e=BD(a.g,119);n=e[c];g=n.ak();if(T6d(a.e,g)){o=S6d(a.e.Tg(),g);i=-1;h=-1;d=0;for(j=0,l=b>c?b:c;j<=l;++j){if(j==c){h=d++}else{f=e[j];k=o.rl(f.ak());j==b&&(i=j==l&&!k?d-1:d);k&&++d}}m=BD(Wxd(a,b,c),72);h!=i&&GLd(a,new ESd(a.e,7,g,meb(h),n.dd(),i));return m}}}else{return BD(sud(a,b,c),72)}return BD(Wxd(a,b,c),72)} +function Qcc(a,b){var c,d,e,f,g,h,i;Odd(b,'Port order processing',1);i=BD(vNb(a,(Nyc(),_xc)),421);for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),29);for(f=new olb(c.a);f.a<f.c.c.length;){e=BD(mlb(f),10);g=BD(vNb(e,Vxc),98);h=e.j;if(g==(dcd(),Zbd)||g==_bd||g==$bd){mmb();Okb(h,Icc)}else if(g!=bcd&&g!=ccd){mmb();Okb(h,Lcc);Scc(h);i==(BAc(),AAc)&&Okb(h,Kcc)}e.i=true;N_b(e)}}Qdd(b)} +function vDc(a){var b,c,d,e,f,g,h,i;i=new Lqb;b=new KFb;for(g=a.Kc();g.Ob();){e=BD(g.Pb(),10);h=nGb(oGb(new pGb,e),b);jrb(i.f,e,h)}for(f=a.Kc();f.Ob();){e=BD(f.Pb(),10);for(d=new Sr(ur(U_b(e).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);if(OZb(c)){continue}AFb(DFb(CFb(BFb(EFb(new FFb,$wnd.Math.max(1,BD(vNb(c,(Nyc(),dyc)),19).a)),1),BD(Ohb(i,c.c.i),121)),BD(Ohb(i,c.d.i),121)))}}return b} +function tNc(){tNc=ccb;oNc=e3c(new j3c,(qUb(),oUb),(S8b(),k8b));qNc=e3c(new j3c,nUb,o8b);rNc=c3c(e3c(new j3c,nUb,C8b),pUb,B8b);nNc=c3c(e3c(e3c(new j3c,nUb,e8b),oUb,f8b),pUb,g8b);sNc=b3c(b3c(g3c(c3c(e3c(new j3c,lUb,M8b),pUb,L8b),oUb),K8b),N8b);pNc=c3c(new j3c,pUb,l8b);lNc=c3c(e3c(e3c(e3c(new j3c,mUb,r8b),oUb,t8b),oUb,u8b),pUb,s8b);mNc=c3c(e3c(e3c(new j3c,oUb,u8b),oUb,_7b),pUb,$7b)} +function XC(a,b,c,d,e,f){var g,h,i,j,k,l,m;j=$C(b)-$C(a);g=kD(b,j);i=TC(0,0,0);while(j>=0){h=bD(a,g);if(h){j<22?(i.l|=1<<j,undefined):j<44?(i.m|=1<<j-22,undefined):(i.h|=1<<j-44,undefined);if(a.l==0&&a.m==0&&a.h==0){break}}k=g.m;l=g.h;m=g.l;g.h=l>>>1;g.m=k>>>1|(l&1)<<21;g.l=m>>>1|(k&1)<<21;--j}c&&ZC(i);if(f){if(d){QC=hD(a);e&&(QC=nD(QC,(wD(),uD)))}else{QC=TC(a.l,a.m,a.h)}}return i} +function TDc(a,b){var c,d,e,f,g,h,i,j,k,l;j=a.e[b.c.p][b.p]+1;i=b.c.a.c.length+1;for(h=new olb(a.a);h.a<h.c.c.length;){g=BD(mlb(h),11);l=0;f=0;for(e=ul(pl(OC(GC(KI,1),Uhe,20,0,[new J0b(g),new R0b(g)])));Qr(e);){d=BD(Rr(e),11);if(d.i.c==b.c){l+=aEc(a,d.i)+1;++f}}c=l/f;k=g.j;k==(Ucd(),zcd)?c<j?(a.f[g.p]=a.c-c):(a.f[g.p]=a.b+(i-c)):k==Tcd&&(c<j?(a.f[g.p]=a.b+c):(a.f[g.p]=a.c-(i-c)))}} +function Icb(a,b,c){var d,e,f,g,h;if(a==null){throw vbb(new Oeb(Xhe))}f=a.length;g=f>0&&(BCb(0,a.length),a.charCodeAt(0)==45||(BCb(0,a.length),a.charCodeAt(0)==43))?1:0;for(d=g;d<f;d++){if(Zcb((BCb(d,a.length),a.charCodeAt(d)))==-1){throw vbb(new Oeb(Oje+a+'"'))}}h=parseInt(a,10);e=h<b;if(isNaN(h)){throw vbb(new Oeb(Oje+a+'"'))}else if(e||h>c){throw vbb(new Oeb(Oje+a+'"'))}return h} +function dnc(a){var b,c,d,e,f,g,h;g=new Psb;for(f=new olb(a.a);f.a<f.c.c.length;){e=BD(mlb(f),112);pOc(e,e.f.c.length);qOc(e,e.k.c.length);if(e.i==0){e.o=0;Gsb(g,e,g.c.b,g.c)}}while(g.b!=0){e=BD(g.b==0?null:(sCb(g.b!=0),Nsb(g,g.a.a)),112);d=e.o+1;for(c=new olb(e.f);c.a<c.c.c.length;){b=BD(mlb(c),129);h=b.a;rOc(h,$wnd.Math.max(h.o,d));qOc(h,h.i-1);h.i==0&&(Gsb(g,h,g.c.b,g.c),true)}}} +function v2c(a){var b,c,d,e,f,g,h,i;for(g=new olb(a);g.a<g.c.c.length;){f=BD(mlb(g),79);d=atd(BD(qud((!f.b&&(f.b=new y5d(z2,f,4,7)),f.b),0),82));h=d.i;i=d.j;e=BD(qud((!f.a&&(f.a=new cUd(A2,f,6,6)),f.a),0),202);nmd(e,e.j+h,e.k+i);gmd(e,e.b+h,e.c+i);for(c=new Fyd((!e.a&&(e.a=new xMd(y2,e,5)),e.a));c.e!=c.i.gc();){b=BD(Dyd(c),469);ukd(b,b.a+h,b.b+i)}p7c(BD(hkd(f,(Y9c(),Q8c)),74),h,i)}} +function fee(a){var b;switch(a){case 100:return kee(nxe,true);case 68:return kee(nxe,false);case 119:return kee(oxe,true);case 87:return kee(oxe,false);case 115:return kee(pxe,true);case 83:return kee(pxe,false);case 99:return kee(qxe,true);case 67:return kee(qxe,false);case 105:return kee(rxe,true);case 73:return kee(rxe,false);default:throw vbb(new hz((b=a,mxe+b.toString(16))));}} +function $Xb(a){var b,c,d,e,f;e=BD(Ikb(a.a,0),10);b=new b0b(a);Ekb(a.a,b);b.o.a=$wnd.Math.max(1,e.o.a);b.o.b=$wnd.Math.max(1,e.o.b);b.n.a=e.n.a;b.n.b=e.n.b;switch(BD(vNb(e,(wtc(),Hsc)),61).g){case 4:b.n.a+=2;break;case 1:b.n.b+=2;break;case 2:b.n.a-=2;break;case 3:b.n.b-=2;}d=new H0b;F0b(d,b);c=new UZb;f=BD(Ikb(e.j,0),11);QZb(c,f);RZb(c,d);P6c(X6c(d.n),f.n);P6c(X6c(d.a),f.a);return b} +function Fac(a,b,c,d,e){if(c&&(!d||(a.c-a.b&a.a.length-1)>1)&&b==1&&BD(a.a[a.b],10).k==(j0b(),f0b)){zac(BD(a.a[a.b],10),(rbd(),nbd))}else if(d&&(!c||(a.c-a.b&a.a.length-1)>1)&&b==1&&BD(a.a[a.c-1&a.a.length-1],10).k==(j0b(),f0b)){zac(BD(a.a[a.c-1&a.a.length-1],10),(rbd(),obd))}else if((a.c-a.b&a.a.length-1)==2){zac(BD(bkb(a),10),(rbd(),nbd));zac(BD(bkb(a),10),obd)}else{wac(a,e)}Yjb(a)} +function pRc(a,b,c){var d,e,f,g,h;f=0;for(e=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));e.e!=e.i.gc();){d=BD(Dyd(e),33);g='';(!d.n&&(d.n=new cUd(D2,d,1,7)),d.n).i==0||(g=BD(qud((!d.n&&(d.n=new cUd(D2,d,1,7)),d.n),0),137).a);h=new XRc(f++,b,g);tNb(h,d);yNb(h,(mTc(),dTc),d);h.e.b=d.j+d.f/2;h.f.a=$wnd.Math.max(d.g,1);h.e.a=d.i+d.g/2;h.f.b=$wnd.Math.max(d.f,1);Dsb(b.b,h);jrb(c.f,d,h)}} +function B2b(a){var b,c,d,e,f;d=BD(vNb(a,(wtc(),$sc)),33);f=BD(hkd(d,(Nyc(),Fxc)),174).Hc((tdd(),sdd));if(!a.e){e=BD(vNb(a,Ksc),21);b=new f7c(a.f.a+a.d.b+a.d.c,a.f.b+a.d.d+a.d.a);if(e.Hc((Orc(),Hrc))){jkd(d,Vxc,(dcd(),$bd));Afd(d,b.a,b.b,false,true)}else{Ccb(DD(hkd(d,Gxc)))||Afd(d,b.a,b.b,true,true)}}f?jkd(d,Fxc,pqb(sdd)):jkd(d,Fxc,(c=BD(gdb(I1),9),new xqb(c,BD(_Bb(c,c.length),9),0)))} +function tA(a,b,c){var d,e,f,g;if(b[0]>=a.length){c.o=0;return true}switch(bfb(a,b[0])){case 43:e=1;break;case 45:e=-1;break;default:c.o=0;return true;}++b[0];f=b[0];g=rA(a,b);if(g==0&&b[0]==f){return false}if(b[0]<a.length&&bfb(a,b[0])==58){d=g*60;++b[0];f=b[0];g=rA(a,b);if(g==0&&b[0]==f){return false}d+=g}else{d=g;d<24&&b[0]-f<=2?(d*=60):(d=d%100+(d/100|0)*60)}d*=e;c.o=-d;return true} +function Hjc(a){var b,c,d,e,f,g,h,i,j;g=new Rkb;for(d=new Sr(ur(U_b(a.b).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);OZb(c)&&Ekb(g,new Gjc(c,Jjc(a,c.c),Jjc(a,c.d)))}for(j=(f=(new $ib(a.e)).a.vc().Kc(),new djb(f));j.a.Ob();){h=(b=BD(j.a.Pb(),42),BD(b.dd(),113));h.d.p=0}for(i=(e=(new $ib(a.e)).a.vc().Kc(),new djb(e));i.a.Ob();){h=(b=BD(i.a.Pb(),42),BD(b.dd(),113));h.d.p==0&&Ekb(a.d,Ijc(a,h))}} +function W1b(a){var b,c,d,e,f,g,h;f=mpd(a);for(e=new Fyd((!a.e&&(a.e=new y5d(B2,a,7,4)),a.e));e.e!=e.i.gc();){d=BD(Dyd(e),79);h=atd(BD(qud((!d.c&&(d.c=new y5d(z2,d,5,8)),d.c),0),82));if(!ntd(h,f)){return true}}for(c=new Fyd((!a.d&&(a.d=new y5d(B2,a,8,5)),a.d));c.e!=c.i.gc();){b=BD(Dyd(c),79);g=atd(BD(qud((!b.b&&(b.b=new y5d(z2,b,4,7)),b.b),0),82));if(!ntd(g,f)){return true}}return false} +function Dmc(a){var b,c,d,e,f,g,h,i;i=new s7c;b=Jsb(a,0);h=null;c=BD(Xsb(b),8);e=BD(Xsb(b),8);while(b.b!=b.d.c){h=c;c=e;e=BD(Xsb(b),8);f=Emc(c7c(new f7c(h.a,h.b),c));g=Emc(c7c(new f7c(e.a,e.b),c));d=10;d=$wnd.Math.min(d,$wnd.Math.abs(f.a+f.b)/2);d=$wnd.Math.min(d,$wnd.Math.abs(g.a+g.b)/2);f.a=Eeb(f.a)*d;f.b=Eeb(f.b)*d;g.a=Eeb(g.a)*d;g.b=Eeb(g.b)*d;Dsb(i,P6c(f,c));Dsb(i,P6c(g,c))}return i} +function _hd(a,b,c,d){var e,f,g,h,i;g=a.eh();i=a.Zg();e=null;if(i){if(!!b&&(Nid(a,b,c).Bb&Tje)==0){d=Txd(i.Vk(),a,d);a.uh(null);e=b.fh()}else{i=null}}else{!!g&&(i=g.fh());!!b&&(e=b.fh())}i!=e&&!!i&&i.Zk(a);h=a.Vg();a.Rg(b,c);i!=e&&!!e&&e.Yk(a);if(a.Lg()&&a.Mg()){if(!!g&&h>=0&&h!=c){f=new nSd(a,1,h,g,null);!d?(d=f):d.Ei(f)}if(c>=0){f=new nSd(a,1,c,h==c?g:null,b);!d?(d=f):d.Ei(f)}}return d} +function LEd(a){var b,c,d;if(a.b==null){d=new Hfb;if(a.i!=null){Efb(d,a.i);d.a+=':'}if((a.f&256)!=0){if((a.f&256)!=0&&a.a!=null){YEd(a.i)||(d.a+='//',d);Efb(d,a.a)}if(a.d!=null){d.a+='/';Efb(d,a.d)}(a.f&16)!=0&&(d.a+='/',d);for(b=0,c=a.j.length;b<c;b++){b!=0&&(d.a+='/',d);Efb(d,a.j[b])}if(a.g!=null){d.a+='?';Efb(d,a.g)}}else{Efb(d,a.a)}if(a.e!=null){d.a+='#';Efb(d,a.e)}a.b=d.a}return a.b} +function E5b(a,b){var c,d,e,f,g,h;for(e=new olb(b.a);e.a<e.c.c.length;){d=BD(mlb(e),10);f=vNb(d,(wtc(),$sc));if(JD(f,11)){g=BD(f,11);h=b_b(b,d,g.o.a,g.o.b);g.n.a=h.a;g.n.b=h.b;G0b(g,BD(vNb(d,Hsc),61))}}c=new f7c(b.f.a+b.d.b+b.d.c,b.f.b+b.d.d+b.d.a);if(BD(vNb(b,(wtc(),Ksc)),21).Hc((Orc(),Hrc))){yNb(a,(Nyc(),Vxc),(dcd(),$bd));BD(vNb(Q_b(a),Ksc),21).Fc(Krc);j_b(a,c,false)}else{j_b(a,c,true)}} +function YFc(a,b,c){var d,e,f,g,h,i;Odd(c,'Minimize Crossings '+a.a,1);d=b.b.c.length==0||!WAb(JAb(new YAb(null,new Kub(b.b,16)),new Xxb(new xGc))).sd((EAb(),DAb));i=b.b.c.length==1&&BD(Ikb(b.b,0),29).a.c.length==1;f=PD(vNb(b,(Nyc(),axc)))===PD((hbd(),ebd));if(d||i&&!f){Qdd(c);return}e=TFc(a,b);g=(h=BD(Ut(e,0),214),h.c.Rf()?h.c.Lf()?new kGc(a):new mGc(a):new iGc(a));UFc(e,g);eGc(a);Qdd(c)} +function so(a,b,c,d){var e,f,g,h,i;i=Tbb(Ibb(Eie,keb(Tbb(Ibb(b==null?0:tb(b),Fie)),15)));e=Tbb(Ibb(Eie,keb(Tbb(Ibb(c==null?0:tb(c),Fie)),15)));h=vo(a,b,i);g=uo(a,c,e);if(!!h&&e==h.a&&Hb(c,h.g)){return c}else if(!!g&&!d){throw vbb(new Wdb('key already present: '+c))}!!h&&mo(a,h);!!g&&mo(a,g);f=new $o(c,e,b,i);po(a,f,g);if(g){g.e=null;g.c=null}if(h){h.e=null;h.c=null}to(a);return !h?null:h.g} +function Lhb(a,b,c){var d,e,f,g,h;for(f=0;f<b;f++){d=0;for(h=f+1;h<b;h++){d=wbb(wbb(Ibb(xbb(a[f],Yje),xbb(a[h],Yje)),xbb(c[f+h],Yje)),xbb(Tbb(d),Yje));c[f+h]=Tbb(d);d=Pbb(d,32)}c[f+b]=Tbb(d)}khb(c,c,b<<1);d=0;for(e=0,g=0;e<b;++e,g++){d=wbb(wbb(Ibb(xbb(a[e],Yje),xbb(a[e],Yje)),xbb(c[g],Yje)),xbb(Tbb(d),Yje));c[g]=Tbb(d);d=Pbb(d,32);++g;d=wbb(d,xbb(c[g],Yje));c[g]=Tbb(d);d=Pbb(d,32)}return c} +function ZJc(a,b,c){var d,e,f,g,h,i,j,k;if(Qq(b)){return}i=Edb(ED(pBc(c.c,(Nyc(),zyc))));j=BD(pBc(c.c,yyc),142);!j&&(j=new H_b);d=c.a;e=null;for(h=b.Kc();h.Ob();){g=BD(h.Pb(),11);k=0;if(!e){k=j.d}else{k=i;k+=e.o.b}f=nGb(oGb(new pGb,g),a.f);Rhb(a.k,g,f);AFb(DFb(CFb(BFb(EFb(new FFb,0),QD($wnd.Math.ceil(k))),d),f));e=g;d=f}AFb(DFb(CFb(BFb(EFb(new FFb,0),QD($wnd.Math.ceil(j.a+e.o.b))),d),c.d))} +function uZc(a,b,c,d,e,f,g,h){var i,j,k,l,m,n;n=false;m=f-c.s;k=c.t-b.f+(j=MZc(c,m,false),j.a);if(d.g+h>m){return false}l=(i=MZc(d,m,false),i.a);if(k+h+l<=b.b){KZc(c,f-c.s);c.c=true;KZc(d,f-c.s);OZc(d,c.s,c.t+c.d+h);d.k=true;WZc(c.q,d);n=true;if(e){s$c(b,d);d.j=b;if(a.c.length>g){v$c((tCb(g,a.c.length),BD(a.c[g],200)),d);(tCb(g,a.c.length),BD(a.c[g],200)).a.c.length==0&&Kkb(a,g)}}}return n} +function kcc(a,b){var c,d,e,f,g,h;Odd(b,'Partition midprocessing',1);e=new Hp;MAb(JAb(new YAb(null,new Kub(a.a,16)),new occ),new qcc(e));if(e.d==0){return}h=BD(GAb(UAb((f=e.i,new YAb(null,(!f?(e.i=new zf(e,e.c)):f).Nc()))),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);d=h.Kc();c=BD(d.Pb(),19);while(d.Ob()){g=BD(d.Pb(),19);jcc(BD(Qc(e,c),21),BD(Qc(e,g),21));c=g}Qdd(b)} +function DYb(a,b,c){var d,e,f,g,h,i,j,k;if(b.p==0){b.p=1;g=c;if(!g){e=new Rkb;f=(d=BD(gdb(F1),9),new xqb(d,BD(_Bb(d,d.length),9),0));g=new vgd(e,f)}BD(g.a,15).Fc(b);b.k==(j0b(),e0b)&&BD(g.b,21).Fc(BD(vNb(b,(wtc(),Hsc)),61));for(i=new olb(b.j);i.a<i.c.c.length;){h=BD(mlb(i),11);for(k=ul(pl(OC(GC(KI,1),Uhe,20,0,[new J0b(h),new R0b(h)])));Qr(k);){j=BD(Rr(k),11);DYb(a,j.i,g)}}return g}return null} +function Dmd(a,b){var c,d,e,f,g;if(a.Ab){if(a.Ab){g=a.Ab.i;if(g>0){e=BD(a.Ab.g,1934);if(b==null){for(f=0;f<g;++f){c=e[f];if(c.d==null){return c}}}else{for(f=0;f<g;++f){c=e[f];if(dfb(b,c.d)){return c}}}}}else{if(b==null){for(d=new Fyd(a.Ab);d.e!=d.i.gc();){c=BD(Dyd(d),590);if(c.d==null){return c}}}else{for(d=new Fyd(a.Ab);d.e!=d.i.gc();){c=BD(Dyd(d),590);if(dfb(b,c.d)){return c}}}}}return null} +function gRc(a,b){var c,d,e,f,g,h,i,j;j=DD(vNb(b,(JTc(),GTc)));if(j==null||(uCb(j),j)){dRc(a,b);e=new Rkb;for(i=Jsb(b.b,0);i.b!=i.d.c;){g=BD(Xsb(i),86);c=cRc(a,g,null);if(c){tNb(c,b);e.c[e.c.length]=c}}a.a=null;a.b=null;if(e.c.length>1){for(d=new olb(e);d.a<d.c.c.length;){c=BD(mlb(d),135);f=0;for(h=Jsb(c.b,0);h.b!=h.d.c;){g=BD(Xsb(h),86);g.g=f++}}}return e}return Ou(OC(GC(n$,1),fme,135,0,[b]))} +function rqd(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,p,q,r,s,t,u,v;n=Sqd(a,etd(b),e);jmd(n,_pd(e,Vte));o=null;p=e;q=$pd(p,Yte);r=new urd(n);wqd(r.a,q);s=$pd(p,'endPoint');t=new yrd(n);yqd(t.a,s);u=Ypd(p,Ote);v=new Brd(n);zqd(v.a,u);l=_pd(e,Qte);f=new qrd(a,n);sqd(f.a,f.b,l);m=_pd(e,Pte);g=new rrd(a,n);tqd(g.a,g.b,m);j=Ypd(e,Ste);h=new srd(c,n);uqd(h.b,h.a,j);k=Ypd(e,Rte);i=new trd(d,n);vqd(i.b,i.a,k)} +function i_b(a,b,c){var d,e,f,g,h;h=null;switch(b.g){case 1:for(e=new olb(a.j);e.a<e.c.c.length;){d=BD(mlb(e),11);if(Ccb(DD(vNb(d,(wtc(),Msc))))){return d}}h=new H0b;yNb(h,(wtc(),Msc),(Bcb(),true));break;case 2:for(g=new olb(a.j);g.a<g.c.c.length;){f=BD(mlb(g),11);if(Ccb(DD(vNb(f,(wtc(),etc))))){return f}}h=new H0b;yNb(h,(wtc(),etc),(Bcb(),true));}if(h){F0b(h,a);G0b(h,c);X$b(h.n,a.o,c)}return h} +function O3b(a,b){var c,d,e,f,g,h;h=-1;g=new Psb;for(d=new b1b(a.b);llb(d.a)||llb(d.b);){c=BD(llb(d.a)?mlb(d.a):mlb(d.b),17);h=$wnd.Math.max(h,Edb(ED(vNb(c,(Nyc(),Zwc)))));c.c==a?MAb(JAb(new YAb(null,new Kub(c.b,16)),new U3b),new W3b(g)):MAb(JAb(new YAb(null,new Kub(c.b,16)),new Y3b),new $3b(g));for(f=Jsb(g,0);f.b!=f.d.c;){e=BD(Xsb(f),70);wNb(e,(wtc(),Dsc))||yNb(e,Dsc,c)}Gkb(b,g);Osb(g)}return h} +function _bc(a,b,c,d,e){var f,g,h,i;f=new b0b(a);__b(f,(j0b(),i0b));yNb(f,(Nyc(),Vxc),(dcd(),$bd));yNb(f,(wtc(),$sc),b.c.i);g=new H0b;yNb(g,$sc,b.c);G0b(g,e);F0b(g,f);yNb(b.c,gtc,f);h=new b0b(a);__b(h,i0b);yNb(h,Vxc,$bd);yNb(h,$sc,b.d.i);i=new H0b;yNb(i,$sc,b.d);G0b(i,e);F0b(i,h);yNb(b.d,gtc,h);QZb(b,g);RZb(b,i);wCb(0,c.c.length);aCb(c.c,0,f);d.c[d.c.length]=h;yNb(f,ysc,meb(1));yNb(h,ysc,meb(1))} +function BPc(a,b,c,d,e){var f,g,h,i,j;h=e?d.b:d.a;if(Rqb(a.a,d)){return}j=h>c.s&&h<c.c;i=false;if(c.e.b!=0&&c.j.b!=0){i=i|($wnd.Math.abs(h-Edb(ED(Hsb(c.e))))<qme&&$wnd.Math.abs(h-Edb(ED(Hsb(c.j))))<qme);i=i|($wnd.Math.abs(h-Edb(ED(Isb(c.e))))<qme&&$wnd.Math.abs(h-Edb(ED(Isb(c.j))))<qme)}if(j||i){g=BD(vNb(b,(Nyc(),jxc)),74);if(!g){g=new s7c;yNb(b,jxc,g)}f=new g7c(d);Gsb(g,f,g.c.b,g.c);Qqb(a.a,f)}} +function gNb(a,b,c,d){var e,f,g,h,i,j,k;if(fNb(a,b,c,d)){return true}else{for(g=new olb(b.f);g.a<g.c.c.length;){f=BD(mlb(g),324);h=false;i=a.j-b.j+c;j=i+b.o;k=a.k-b.k+d;e=k+b.p;switch(f.a.g){case 0:h=oNb(a,i+f.b.a,0,i+f.c.a,k-1);break;case 1:h=oNb(a,j,k+f.b.a,a.o-1,k+f.c.a);break;case 2:h=oNb(a,i+f.b.a,e,i+f.c.a,a.p-1);break;default:h=oNb(a,0,k+f.b.a,i-1,k+f.c.a);}if(h){return true}}}return false} +function LMc(a,b){var c,d,e,f,g,h,i,j,k;for(g=new olb(b.b);g.a<g.c.c.length;){f=BD(mlb(g),29);for(j=new olb(f.a);j.a<j.c.c.length;){i=BD(mlb(j),10);k=new Rkb;h=0;for(d=new Sr(ur(R_b(i).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);if(OZb(c)||!OZb(c)&&c.c.i.c==c.d.i.c){continue}e=BD(vNb(c,(Nyc(),eyc)),19).a;if(e>h){h=e;k.c=KC(SI,Uhe,1,0,5,1)}e==h&&Ekb(k,new vgd(c.c.i,c))}mmb();Okb(k,a.c);Dkb(a.b,i.p,k)}}} +function MMc(a,b){var c,d,e,f,g,h,i,j,k;for(g=new olb(b.b);g.a<g.c.c.length;){f=BD(mlb(g),29);for(j=new olb(f.a);j.a<j.c.c.length;){i=BD(mlb(j),10);k=new Rkb;h=0;for(d=new Sr(ur(U_b(i).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);if(OZb(c)||!OZb(c)&&c.c.i.c==c.d.i.c){continue}e=BD(vNb(c,(Nyc(),eyc)),19).a;if(e>h){h=e;k.c=KC(SI,Uhe,1,0,5,1)}e==h&&Ekb(k,new vgd(c.d.i,c))}mmb();Okb(k,a.c);Dkb(a.f,i.p,k)}}} +function Y7c(a){r4c(a,new E3c(P3c(M3c(O3c(N3c(new R3c,qse),'ELK Box'),'Algorithm for packing of unconnected boxes, i.e. graphs without edges.'),new _7c)));p4c(a,qse,ame,U7c);p4c(a,qse,wme,15);p4c(a,qse,vme,meb(0));p4c(a,qse,Jre,Ksd(O7c));p4c(a,qse,Fme,Ksd(Q7c));p4c(a,qse,Eme,Ksd(S7c));p4c(a,qse,_le,pse);p4c(a,qse,Ame,Ksd(P7c));p4c(a,qse,Tme,Ksd(R7c));p4c(a,qse,rse,Ksd(M7c));p4c(a,qse,lqe,Ksd(N7c))} +function W$b(a,b){var c,d,e,f,g,h,i,j,k;e=a.i;g=e.o.a;f=e.o.b;if(g<=0&&f<=0){return Ucd(),Scd}j=a.n.a;k=a.n.b;h=a.o.a;c=a.o.b;switch(b.g){case 2:case 1:if(j<0){return Ucd(),Tcd}else if(j+h>g){return Ucd(),zcd}break;case 4:case 3:if(k<0){return Ucd(),Acd}else if(k+c>f){return Ucd(),Rcd}}i=(j+h/2)/g;d=(k+c/2)/f;return i+d<=1&&i-d<=0?(Ucd(),Tcd):i+d>=1&&i-d>=0?(Ucd(),zcd):d<0.5?(Ucd(),Acd):(Ucd(),Rcd)} +function pJc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;c=false;k=Edb(ED(vNb(b,(Nyc(),vyc))));o=Qie*k;for(e=new olb(b.b);e.a<e.c.c.length;){d=BD(mlb(e),29);j=new olb(d.a);f=BD(mlb(j),10);l=xJc(a.a[f.p]);while(j.a<j.c.c.length){h=BD(mlb(j),10);m=xJc(a.a[h.p]);if(l!=m){n=jBc(a.b,f,h);g=f.n.b+f.o.b+f.d.a+l.a+n;i=h.n.b-h.d.d+m.a;if(g>i+o){p=l.g+m.g;m.a=(m.g*m.a+l.g*l.a)/p;m.g=p;l.f=m;c=true}}f=h;l=m}}return c} +function VGb(a,b,c,d,e,f,g){var h,i,j,k,l,m;m=new I6c;for(j=b.Kc();j.Ob();){h=BD(j.Pb(),839);for(l=new olb(h.wf());l.a<l.c.c.length;){k=BD(mlb(l),181);if(PD(k.We((Y9c(),C8c)))===PD((qad(),pad))){SGb(m,k,false,d,e,f,g);H6c(a,m)}}}for(i=c.Kc();i.Ob();){h=BD(i.Pb(),839);for(l=new olb(h.wf());l.a<l.c.c.length;){k=BD(mlb(l),181);if(PD(k.We((Y9c(),C8c)))===PD((qad(),oad))){SGb(m,k,true,d,e,f,g);H6c(a,m)}}}} +function oRc(a,b,c){var d,e,f,g,h,i,j;for(g=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));g.e!=g.i.gc();){f=BD(Dyd(g),33);for(e=new Sr(ur(_sd(f).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),79);if(!Pld(d)&&!Pld(d)&&!Qld(d)){i=BD(Wd(irb(c.f,f)),86);j=BD(Ohb(c,atd(BD(qud((!d.c&&(d.c=new y5d(z2,d,5,8)),d.c),0),82))),86);if(!!i&&!!j){h=new QRc(i,j);yNb(h,(mTc(),dTc),d);tNb(h,d);Dsb(i.d,h);Dsb(j.b,h);Dsb(b.a,h)}}}}} +function QKb(a,b){var c,d,e,f,g,h,i,j;for(i=BD(BD(Qc(a.r,b),21),84).Kc();i.Ob();){h=BD(i.Pb(),111);e=h.c?YHb(h.c):0;if(e>0){if(h.a){j=h.b.rf().b;if(e>j){if(a.v||h.c.d.c.length==1){g=(e-j)/2;h.d.d=g;h.d.a=g}else{c=BD(Ikb(h.c.d,0),181).rf().b;d=(c-j)/2;h.d.d=$wnd.Math.max(0,d);h.d.a=e-d-j}}}else{h.d.a=a.t+e}}else if(tcd(a.u)){f=sfd(h.b);f.d<0&&(h.d.d=-f.d);f.d+f.a>h.b.rf().b&&(h.d.a=f.d+f.a-h.b.rf().b)}}} +function FC(a,b){var c;switch(HC(a)){case 6:return ND(b);case 7:return LD(b);case 8:return KD(b);case 3:return Array.isArray(b)&&(c=HC(b),!(c>=14&&c<=16));case 11:return b!=null&&typeof b===Nhe;case 12:return b!=null&&(typeof b===Jhe||typeof b==Nhe);case 0:return AD(b,a.__elementTypeId$);case 2:return OD(b)&&!(b.im===gcb);case 1:return OD(b)&&!(b.im===gcb)||AD(b,a.__elementTypeId$);default:return true;}} +function xOb(a,b){var c,d,e,f;d=$wnd.Math.min($wnd.Math.abs(a.c-(b.c+b.b)),$wnd.Math.abs(a.c+a.b-b.c));f=$wnd.Math.min($wnd.Math.abs(a.d-(b.d+b.a)),$wnd.Math.abs(a.d+a.a-b.d));c=$wnd.Math.abs(a.c+a.b/2-(b.c+b.b/2));if(c>a.b/2+b.b/2){return 1}e=$wnd.Math.abs(a.d+a.a/2-(b.d+b.a/2));if(e>a.a/2+b.a/2){return 1}if(c==0&&e==0){return 0}if(c==0){return f/e+1}if(e==0){return d/c+1}return $wnd.Math.min(d/c,f/e)+1} +function mgb(a,b){var c,d,e,f,g,h;e=pgb(a);h=pgb(b);if(e==h){if(a.e==b.e&&a.a<54&&b.a<54){return a.f<b.f?-1:a.f>b.f?1:0}d=a.e-b.e;c=(a.d>0?a.d:$wnd.Math.floor((a.a-1)*Xje)+1)-(b.d>0?b.d:$wnd.Math.floor((b.a-1)*Xje)+1);if(c>d+1){return e}else if(c<d-1){return -e}else{f=(!a.c&&(a.c=fhb(a.f)),a.c);g=(!b.c&&(b.c=fhb(b.f)),b.c);d<0?(f=Ogb(f,Khb(-d))):d>0&&(g=Ogb(g,Khb(d)));return Igb(f,g)}}else return e<h?-1:1} +function mTb(a,b){var c,d,e,f,g,h,i;f=0;h=0;i=0;for(e=new olb(a.f.e);e.a<e.c.c.length;){d=BD(mlb(e),144);if(b==d){continue}g=a.i[b.b][d.b];f+=g;c=S6c(b.d,d.d);c>0&&a.d!=(yTb(),xTb)&&(h+=g*(d.d.a+a.a[b.b][d.b]*(b.d.a-d.d.a)/c));c>0&&a.d!=(yTb(),vTb)&&(i+=g*(d.d.b+a.a[b.b][d.b]*(b.d.b-d.d.b)/c))}switch(a.d.g){case 1:return new f7c(h/f,b.d.b);case 2:return new f7c(b.d.a,i/f);default:return new f7c(h/f,i/f);}} +function Wcc(a,b){Occ();var c,d,e,f,g;g=BD(vNb(a.i,(Nyc(),Vxc)),98);f=a.j.g-b.j.g;if(f!=0||!(g==(dcd(),Zbd)||g==_bd||g==$bd)){return 0}if(g==(dcd(),Zbd)){c=BD(vNb(a,Wxc),19);d=BD(vNb(b,Wxc),19);if(!!c&&!!d){e=c.a-d.a;if(e!=0){return e}}}switch(a.j.g){case 1:return Kdb(a.n.a,b.n.a);case 2:return Kdb(a.n.b,b.n.b);case 3:return Kdb(b.n.a,a.n.a);case 4:return Kdb(b.n.b,a.n.b);default:throw vbb(new Zdb(ine));}} +function tfd(a){var b,c,d,e,f,g;c=(!a.a&&(a.a=new xMd(y2,a,5)),a.a).i+2;g=new Skb(c);Ekb(g,new f7c(a.j,a.k));MAb(new YAb(null,(!a.a&&(a.a=new xMd(y2,a,5)),new Kub(a.a,16))),new Qfd(g));Ekb(g,new f7c(a.b,a.c));b=1;while(b<g.c.length-1){d=(tCb(b-1,g.c.length),BD(g.c[b-1],8));e=(tCb(b,g.c.length),BD(g.c[b],8));f=(tCb(b+1,g.c.length),BD(g.c[b+1],8));d.a==e.a&&e.a==f.a||d.b==e.b&&e.b==f.b?Kkb(g,b):++b}return g} +function Xgc(a,b){var c,d,e,f,g,h,i;c=vDb(yDb(wDb(xDb(new zDb,b),new K6c(b.e)),Ggc),a.a);b.j.c.length==0||nDb(BD(Ikb(b.j,0),57).a,c);i=new lEb;Rhb(a.e,c,i);g=new Tqb;h=new Tqb;for(f=new olb(b.k);f.a<f.c.c.length;){e=BD(mlb(f),17);Qqb(g,e.c);Qqb(h,e.d)}d=g.a.gc()-h.a.gc();if(d<0){jEb(i,true,(ead(),aad));jEb(i,false,bad)}else if(d>0){jEb(i,false,(ead(),aad));jEb(i,true,bad)}Hkb(b.g,new $hc(a,c));Rhb(a.g,b,c)} +function Neb(){Neb=ccb;var a;Jeb=OC(GC(WD,1),oje,25,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]);Keb=KC(WD,oje,25,37,15,1);Leb=OC(GC(WD,1),oje,25,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]);Meb=KC(XD,Sje,25,37,14,1);for(a=2;a<=36;a++){Keb[a]=QD($wnd.Math.pow(a,Jeb[a]));Meb[a]=Abb(rie,Keb[a])}} +function pfd(a){var b;if((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i!=1){throw vbb(new Wdb(Tse+(!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i))}b=new s7c;!!btd(BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82))&&ye(b,qfd(a,btd(BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82)),false));!!btd(BD(qud((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c),0),82))&&ye(b,qfd(a,btd(BD(qud((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c),0),82)),true));return b} +function _Mc(a,b){var c,d,e,f,g;b.d?(e=a.a.c==(YLc(),XLc)?R_b(b.b):U_b(b.b)):(e=a.a.c==(YLc(),WLc)?R_b(b.b):U_b(b.b));f=false;for(d=new Sr(ur(e.a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);g=Ccb(a.a.f[a.a.g[b.b.p].p]);if(!g&&!OZb(c)&&c.c.i.c==c.d.i.c){continue}if(Ccb(a.a.n[a.a.g[b.b.p].p])||Ccb(a.a.n[a.a.g[b.b.p].p])){continue}f=true;if(Rqb(a.b,a.a.g[TMc(c,b.b).p])){b.c=true;b.a=c;return b}}b.c=f;b.a=null;return b} +function bed(a,b,c,d,e){var f,g,h,i,j,k,l;mmb();Okb(a,new Red);h=new Bib(a,0);l=new Rkb;f=0;while(h.b<h.d.gc()){g=(sCb(h.b<h.d.gc()),BD(h.d.Xb(h.c=h.b++),157));if(l.c.length!=0&&red(g)*qed(g)>f*2){k=new wed(l);j=red(g)/qed(g);i=fed(k,b,new p0b,c,d,e,j);P6c(X6c(k.e),i);l.c=KC(SI,Uhe,1,0,5,1);f=0;l.c[l.c.length]=k;l.c[l.c.length]=g;f=red(k)*qed(k)+red(g)*qed(g)}else{l.c[l.c.length]=g;f+=red(g)*qed(g)}}return l} +function qwd(a,b,c){var d,e,f,g,h,i,j;d=c.gc();if(d==0){return false}else{if(a.ej()){i=a.fj();zvd(a,b,c);g=d==1?a.Zi(3,null,c.Kc().Pb(),b,i):a.Zi(5,null,c,b,i);if(a.bj()){h=d<100?null:new Ixd(d);f=b+d;for(e=b;e<f;++e){j=a.Oi(e);h=a.cj(j,h);h=h}if(!h){a.$i(g)}else{h.Ei(g);h.Fi()}}else{a.$i(g)}}else{zvd(a,b,c);if(a.bj()){h=d<100?null:new Ixd(d);f=b+d;for(e=b;e<f;++e){h=a.cj(a.Oi(e),h)}!!h&&h.Fi()}}return true}} +function wwd(a,b,c){var d,e,f,g,h;if(a.ej()){e=null;f=a.fj();d=a.Zi(1,h=(g=a.Ui(b,a.oi(b,c)),g),c,b,f);if(a.bj()&&!(a.ni()&&!!h?pb(h,c):PD(h)===PD(c))){!!h&&(e=a.dj(h,e));e=a.cj(c,e);if(!e){a.$i(d)}else{e.Ei(d);e.Fi()}}else{if(!e){a.$i(d)}else{e.Ei(d);e.Fi()}}return h}else{h=(g=a.Ui(b,a.oi(b,c)),g);if(a.bj()&&!(a.ni()&&!!h?pb(h,c):PD(h)===PD(c))){e=null;!!h&&(e=a.dj(h,null));e=a.cj(c,e);!!e&&e.Fi()}return h}} +function rRb(a,b){var c,d,e,f,g,h,i,j,k;a.e=b;a.f=BD(vNb(b,(HSb(),GSb)),230);iRb(b);a.d=$wnd.Math.max(b.e.c.length*16+b.c.c.length,256);if(!Ccb(DD(vNb(b,(wSb(),dSb))))){k=a.e.e.c.length;for(i=new olb(b.e);i.a<i.c.c.length;){h=BD(mlb(i),144);j=h.d;j.a=Aub(a.f)*k;j.b=Aub(a.f)*k}}c=b.b;for(f=new olb(b.c);f.a<f.c.c.length;){e=BD(mlb(f),282);d=BD(vNb(e,rSb),19).a;if(d>0){for(g=0;g<d;g++){Ekb(c,new aRb(e))}cRb(e)}}} +function zac(a,b){var c,d,e,f,g,h;if(a.k==(j0b(),f0b)){c=WAb(JAb(BD(vNb(a,(wtc(),ktc)),15).Oc(),new Xxb(new Kac))).sd((EAb(),DAb))?b:(rbd(),pbd);yNb(a,Ssc,c);if(c!=(rbd(),obd)){d=BD(vNb(a,$sc),17);h=Edb(ED(vNb(d,(Nyc(),Zwc))));g=0;if(c==nbd){g=a.o.b-$wnd.Math.ceil(h/2)}else if(c==pbd){a.o.b-=Edb(ED(vNb(Q_b(a),nyc)));g=(a.o.b-$wnd.Math.ceil(h))/2}for(f=new olb(a.j);f.a<f.c.c.length;){e=BD(mlb(f),11);e.n.b=g}}}} +function Uge(){Uge=ccb;g5d();Tge=new Vge;OC(GC(w5,2),nie,368,0,[OC(GC(w5,1),Axe,592,0,[new Rge(Xwe)])]);OC(GC(w5,2),nie,368,0,[OC(GC(w5,1),Axe,592,0,[new Rge(Ywe)])]);OC(GC(w5,2),nie,368,0,[OC(GC(w5,1),Axe,592,0,[new Rge(Zwe)]),OC(GC(w5,1),Axe,592,0,[new Rge(Ywe)])]);new Ygb('-1');OC(GC(w5,2),nie,368,0,[OC(GC(w5,1),Axe,592,0,[new Rge('\\c+')])]);new Ygb('0');new Ygb('0');new Ygb('1');new Ygb('0');new Ygb(hxe)} +function KQd(a){var b,c;if(!!a.c&&a.c.kh()){c=BD(a.c,49);a.c=BD(xid(a,c),138);if(a.c!=c){(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,9,2,c,a.c));if(JD(a.Cb,399)){a.Db>>16==-15&&a.Cb.nh()&&Rwd(new oSd(a.Cb,9,13,c,a.c,HLd(QSd(BD(a.Cb,59)),a)))}else if(JD(a.Cb,88)){if(a.Db>>16==-23&&a.Cb.nh()){b=a.c;JD(b,88)||(b=(jGd(),_Fd));JD(c,88)||(c=(jGd(),_Fd));Rwd(new oSd(a.Cb,9,10,c,b,HLd(VKd(BD(a.Cb,26)),a)))}}}}return a.c} +function f7b(a,b){var c,d,e,f,g,h,i,j,k,l;Odd(b,'Hypernodes processing',1);for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),29);for(h=new olb(d.a);h.a<h.c.c.length;){g=BD(mlb(h),10);if(Ccb(DD(vNb(g,(Nyc(),exc))))&&g.j.c.length<=2){l=0;k=0;c=0;f=0;for(j=new olb(g.j);j.a<j.c.c.length;){i=BD(mlb(j),11);switch(i.j.g){case 1:++l;break;case 2:++k;break;case 3:++c;break;case 4:++f;}}l==0&&c==0&&e7b(a,g,f<=k)}}}Qdd(b)} +function i7b(a,b){var c,d,e,f,g,h,i,j,k;Odd(b,'Layer constraint edge reversal',1);for(g=new olb(a.b);g.a<g.c.c.length;){f=BD(mlb(g),29);k=-1;c=new Rkb;j=l_b(f.a);for(e=0;e<j.length;e++){d=BD(vNb(j[e],(wtc(),Osc)),303);if(k==-1){d!=(esc(),dsc)&&(k=e)}else{if(d==(esc(),dsc)){$_b(j[e],null);Z_b(j[e],k++,f)}}d==(esc(),bsc)&&Ekb(c,j[e])}for(i=new olb(c);i.a<i.c.c.length;){h=BD(mlb(i),10);$_b(h,null);$_b(h,f)}}Qdd(b)} +function W6b(a,b,c){var d,e,f,g,h,i,j,k,l;Odd(c,'Hyperedge merging',1);U6b(a,b);i=new Bib(b.b,0);while(i.b<i.d.gc()){h=(sCb(i.b<i.d.gc()),BD(i.d.Xb(i.c=i.b++),29));k=h.a;if(k.c.length==0){continue}d=null;e=null;f=null;g=null;for(j=0;j<k.c.length;j++){d=(tCb(j,k.c.length),BD(k.c[j],10));e=d.k;if(e==(j0b(),g0b)&&g==g0b){l=S6b(d,f);if(l.a){V6b(d,f,l.b,l.c);tCb(j,k.c.length);cCb(k.c,j,1);--j;d=f;e=g}}f=d;g=e}}Qdd(c)} +function WFc(a,b){var c,d,e;d=Cub(a.d,1)!=0;!Ccb(DD(vNb(b.j,(wtc(),Jsc))))&&!Ccb(DD(vNb(b.j,mtc)))||PD(vNb(b.j,(Nyc(),ywc)))===PD((tAc(),rAc))?b.c.Tf(b.e,d):(d=Ccb(DD(vNb(b.j,Jsc))));dGc(a,b,d,true);Ccb(DD(vNb(b.j,mtc)))&&yNb(b.j,mtc,(Bcb(),false));if(Ccb(DD(vNb(b.j,Jsc)))){yNb(b.j,Jsc,(Bcb(),false));yNb(b.j,mtc,true)}c=OFc(a,b);do{$Fc(a);if(c==0){return 0}d=!d;e=c;dGc(a,b,d,false);c=OFc(a,b)}while(e>c);return e} +function XFc(a,b){var c,d,e;d=Cub(a.d,1)!=0;!Ccb(DD(vNb(b.j,(wtc(),Jsc))))&&!Ccb(DD(vNb(b.j,mtc)))||PD(vNb(b.j,(Nyc(),ywc)))===PD((tAc(),rAc))?b.c.Tf(b.e,d):(d=Ccb(DD(vNb(b.j,Jsc))));dGc(a,b,d,true);Ccb(DD(vNb(b.j,mtc)))&&yNb(b.j,mtc,(Bcb(),false));if(Ccb(DD(vNb(b.j,Jsc)))){yNb(b.j,Jsc,(Bcb(),false));yNb(b.j,mtc,true)}c=NFc(a,b);do{$Fc(a);if(c==0){return 0}d=!d;e=c;dGc(a,b,d,false);c=NFc(a,b)}while(e>c);return e} +function uNd(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o;if(b==c){return true}else{b=vNd(a,b);c=vNd(a,c);d=JQd(b);if(d){k=JQd(c);if(k!=d){if(!k){return false}else{i=d.Dj();o=k.Dj();return i==o&&i!=null}}else{g=(!b.d&&(b.d=new xMd(j5,b,1)),b.d);f=g.i;m=(!c.d&&(c.d=new xMd(j5,c,1)),c.d);if(f==m.i){for(j=0;j<f;++j){e=BD(qud(g,j),87);l=BD(qud(m,j),87);if(!uNd(a,e,l)){return false}}}return true}}else{h=b.e;n=c.e;return h==n}}} +function X2d(a,b,c,d){var e,f,g,h,i,j,k,l;if(T6d(a.e,b)){l=S6d(a.e.Tg(),b);f=BD(a.g,119);k=null;i=-1;h=-1;e=0;for(j=0;j<a.i;++j){g=f[j];if(l.rl(g.ak())){e==c&&(i=j);if(e==d){h=j;k=g.dd()}++e}}if(i==-1){throw vbb(new qcb(lue+c+mue+e))}if(h==-1){throw vbb(new qcb(nue+d+mue+e))}Wxd(a,i,h);oid(a.e)&&GLd(a,H2d(a,7,b,meb(d),k,c,true));return k}else{throw vbb(new Wdb('The feature must be many-valued to support move'))}} +function b_b(a,b,c,d){var e,f,g,h,i;i=new g7c(b.n);i.a+=b.o.a/2;i.b+=b.o.b/2;h=Edb(ED(vNb(b,(Nyc(),Uxc))));f=a.f;g=a.d;e=a.c;switch(BD(vNb(b,(wtc(),Hsc)),61).g){case 1:i.a+=g.b+e.a-c/2;i.b=-d-h;b.n.b=-(g.d+h+e.b);break;case 2:i.a=f.a+g.b+g.c+h;i.b+=g.d+e.b-d/2;b.n.a=f.a+g.c+h-e.a;break;case 3:i.a+=g.b+e.a-c/2;i.b=f.b+g.d+g.a+h;b.n.b=f.b+g.a+h-e.b;break;case 4:i.a=-c-h;i.b+=g.d+e.b-d/2;b.n.a=-(g.b+h+e.a);}return i} +function P1b(a){var b,c,d,e,f,g;d=new XZb;tNb(d,a);PD(vNb(d,(Nyc(),Lwc)))===PD((ead(),cad))&&yNb(d,Lwc,a_b(d));if(vNb(d,(g6c(),f6c))==null){g=BD(m6d(a),160);yNb(d,f6c,RD(g.We(f6c)))}yNb(d,(wtc(),$sc),a);yNb(d,Ksc,(b=BD(gdb(PW),9),new xqb(b,BD(_Bb(b,b.length),9),0)));e=OGb((!Xod(a)?null:(Pgd(),new bhd(Xod(a))),Pgd(),new hhd(!Xod(a)?null:new bhd(Xod(a)),a)),bad);f=BD(vNb(d,Kxc),116);c=d.d;t_b(c,f);t_b(c,e);return d} +function ybc(a,b,c){var d,e;d=b.c.i;e=c.d.i;if(d.k==(j0b(),g0b)){yNb(a,(wtc(),Vsc),BD(vNb(d,Vsc),11));yNb(a,Wsc,BD(vNb(d,Wsc),11));yNb(a,Usc,DD(vNb(d,Usc)))}else if(d.k==f0b){yNb(a,(wtc(),Vsc),BD(vNb(d,Vsc),11));yNb(a,Wsc,BD(vNb(d,Wsc),11));yNb(a,Usc,(Bcb(),true))}else if(e.k==f0b){yNb(a,(wtc(),Vsc),BD(vNb(e,Vsc),11));yNb(a,Wsc,BD(vNb(e,Wsc),11));yNb(a,Usc,(Bcb(),true))}else{yNb(a,(wtc(),Vsc),b.c);yNb(a,Wsc,c.d)}} +function FGb(a){var b,c,d,e,f,g,h;a.o=new jkb;d=new Psb;for(g=new olb(a.e.a);g.a<g.c.c.length;){f=BD(mlb(g),121);LFb(f).c.length==1&&(Gsb(d,f,d.c.b,d.c),true)}while(d.b!=0){f=BD(d.b==0?null:(sCb(d.b!=0),Nsb(d,d.a.a)),121);if(LFb(f).c.length==0){continue}b=BD(Ikb(LFb(f),0),213);c=f.g.a.c.length>0;h=xFb(b,f);c?OFb(h.b,b):OFb(h.g,b);LFb(h).c.length==1&&(Gsb(d,h,d.c.b,d.c),true);e=new vgd(f,b);Wjb(a.o,e);Lkb(a.e.a,f)}} +function _Nb(a,b){var c,d,e,f,g,h,i;d=$wnd.Math.abs(D6c(a.b).a-D6c(b.b).a);h=$wnd.Math.abs(D6c(a.b).b-D6c(b.b).b);e=0;i=0;c=1;g=1;if(d>a.b.b/2+b.b.b/2){e=$wnd.Math.min($wnd.Math.abs(a.b.c-(b.b.c+b.b.b)),$wnd.Math.abs(a.b.c+a.b.b-b.b.c));c=1-e/d}if(h>a.b.a/2+b.b.a/2){i=$wnd.Math.min($wnd.Math.abs(a.b.d-(b.b.d+b.b.a)),$wnd.Math.abs(a.b.d+a.b.a-b.b.d));g=1-i/h}f=$wnd.Math.min(c,g);return (1-f)*$wnd.Math.sqrt(d*d+h*h)} +function lQc(a){var b,c,d,e;nQc(a,a.e,a.f,(FQc(),DQc),true,a.c,a.i);nQc(a,a.e,a.f,DQc,false,a.c,a.i);nQc(a,a.e,a.f,EQc,true,a.c,a.i);nQc(a,a.e,a.f,EQc,false,a.c,a.i);mQc(a,a.c,a.e,a.f,a.i);d=new Bib(a.i,0);while(d.b<d.d.gc()){b=(sCb(d.b<d.d.gc()),BD(d.d.Xb(d.c=d.b++),128));e=new Bib(a.i,d.b);while(e.b<e.d.gc()){c=(sCb(e.b<e.d.gc()),BD(e.d.Xb(e.c=e.b++),128));kQc(b,c)}}wQc(a.i,BD(vNb(a.d,(wtc(),jtc)),230));zQc(a.i)} +function fKd(a,b){var c,d;if(b!=null){d=dKd(a);if(d){if((d.i&1)!=0){if(d==sbb){return KD(b)}else if(d==WD){return JD(b,19)}else if(d==VD){return JD(b,155)}else if(d==SD){return JD(b,217)}else if(d==TD){return JD(b,172)}else if(d==UD){return LD(b)}else if(d==rbb){return JD(b,184)}else if(d==XD){return JD(b,162)}}else{return pEd(),c=BD(Ohb(oEd,d),55),!c||c.wj(b)}}else if(JD(b,56)){return a.uk(BD(b,56))}}return false} +function ade(){ade=ccb;var a,b,c,d,e,f,g,h,i;$ce=KC(SD,wte,25,255,15,1);_ce=KC(TD,$ie,25,64,15,1);for(b=0;b<255;b++){$ce[b]=-1}for(c=90;c>=65;c--){$ce[c]=c-65<<24>>24}for(d=122;d>=97;d--){$ce[d]=d-97+26<<24>>24}for(e=57;e>=48;e--){$ce[e]=e-48+52<<24>>24}$ce[43]=62;$ce[47]=63;for(f=0;f<=25;f++)_ce[f]=65+f&aje;for(g=26,i=0;g<=51;++g,i++)_ce[g]=97+i&aje;for(a=52,h=0;a<=61;++a,h++)_ce[a]=48+h&aje;_ce[62]=43;_ce[63]=47} +function FXb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;if(a.dc()){return new d7c}j=0;l=0;for(e=a.Kc();e.Ob();){d=BD(e.Pb(),37);f=d.f;j=$wnd.Math.max(j,f.a);l+=f.a*f.b}j=$wnd.Math.max(j,$wnd.Math.sqrt(l)*Edb(ED(vNb(BD(a.Kc().Pb(),37),(Nyc(),owc)))));m=0;n=0;i=0;c=b;for(h=a.Kc();h.Ob();){g=BD(h.Pb(),37);k=g.f;if(m+k.a>j){m=0;n+=i+b;i=0}uXb(g,m,n);c=$wnd.Math.max(c,m+k.a);i=$wnd.Math.max(i,k.b);m+=k.a+b}return new f7c(c+b,n+i+b)} +function mQc(a,b,c,d,e){var f,g,h,i,j,k,l;for(g=new olb(b);g.a<g.c.c.length;){f=BD(mlb(g),17);i=f.c;if(c.a._b(i)){j=(FQc(),DQc)}else if(d.a._b(i)){j=(FQc(),EQc)}else{throw vbb(new Wdb('Source port must be in one of the port sets.'))}k=f.d;if(c.a._b(k)){l=(FQc(),DQc)}else if(d.a._b(k)){l=(FQc(),EQc)}else{throw vbb(new Wdb('Target port must be in one of the port sets.'))}h=new YQc(f,j,l);Rhb(a.b,f,h);e.c[e.c.length]=h}} +function lfd(a,b){var c,d,e,f,g,h,i;if(!mpd(a)){throw vbb(new Zdb(Sse))}d=mpd(a);f=d.g;e=d.f;if(f<=0&&e<=0){return Ucd(),Scd}h=a.i;i=a.j;switch(b.g){case 2:case 1:if(h<0){return Ucd(),Tcd}else if(h+a.g>f){return Ucd(),zcd}break;case 4:case 3:if(i<0){return Ucd(),Acd}else if(i+a.f>e){return Ucd(),Rcd}}g=(h+a.g/2)/f;c=(i+a.f/2)/e;return g+c<=1&&g-c<=0?(Ucd(),Tcd):g+c>=1&&g-c>=0?(Ucd(),zcd):c<0.5?(Ucd(),Acd):(Ucd(),Rcd)} +function vhb(a,b,c,d,e){var f,g;f=wbb(xbb(b[0],Yje),xbb(d[0],Yje));a[0]=Tbb(f);f=Obb(f,32);if(c>=e){for(g=1;g<e;g++){f=wbb(f,wbb(xbb(b[g],Yje),xbb(d[g],Yje)));a[g]=Tbb(f);f=Obb(f,32)}for(;g<c;g++){f=wbb(f,xbb(b[g],Yje));a[g]=Tbb(f);f=Obb(f,32)}}else{for(g=1;g<c;g++){f=wbb(f,wbb(xbb(b[g],Yje),xbb(d[g],Yje)));a[g]=Tbb(f);f=Obb(f,32)}for(;g<e;g++){f=wbb(f,xbb(d[g],Yje));a[g]=Tbb(f);f=Obb(f,32)}}ybb(f,0)!=0&&(a[g]=Tbb(f))} +function _fe(a){wfe();var b,c,d,e,f,g;if(a.e!=4&&a.e!=5)throw vbb(new Wdb('Token#complementRanges(): must be RANGE: '+a.e));f=a;Yfe(f);Vfe(f);d=f.b.length+2;f.b[0]==0&&(d-=2);c=f.b[f.b.length-1];c==lxe&&(d-=2);e=(++vfe,new $fe(4));e.b=KC(WD,oje,25,d,15,1);g=0;if(f.b[0]>0){e.b[g++]=0;e.b[g++]=f.b[0]-1}for(b=1;b<f.b.length-2;b+=2){e.b[g++]=f.b[b]+1;e.b[g++]=f.b[b+1]-1}if(c!=lxe){e.b[g++]=c+1;e.b[g]=lxe}e.a=true;return e} +function Pxd(a,b,c){var d,e,f,g,h,i,j,k;d=c.gc();if(d==0){return false}else{if(a.ej()){j=a.fj();iud(a,b,c);g=d==1?a.Zi(3,null,c.Kc().Pb(),b,j):a.Zi(5,null,c,b,j);if(a.bj()){h=d<100?null:new Ixd(d);f=b+d;for(e=b;e<f;++e){k=a.g[e];h=a.cj(k,h);h=a.jj(k,h)}if(!h){a.$i(g)}else{h.Ei(g);h.Fi()}}else{a.$i(g)}}else{iud(a,b,c);if(a.bj()){h=d<100?null:new Ixd(d);f=b+d;for(e=b;e<f;++e){i=a.g[e];h=a.cj(i,h)}!!h&&h.Fi()}}return true}} +function YNc(a,b,c,d){var e,f,g,h,i;for(g=new olb(a.k);g.a<g.c.c.length;){e=BD(mlb(g),129);if(!d||e.c==(HOc(),FOc)){i=e.b;if(i.g<0&&e.d>0){pOc(i,i.d-e.d);e.c==(HOc(),FOc)&&nOc(i,i.a-e.d);i.d<=0&&i.i>0&&(Gsb(b,i,b.c.b,b.c),true)}}}for(f=new olb(a.f);f.a<f.c.c.length;){e=BD(mlb(f),129);if(!d||e.c==(HOc(),FOc)){h=e.a;if(h.g<0&&e.d>0){qOc(h,h.i-e.d);e.c==(HOc(),FOc)&&oOc(h,h.b-e.d);h.i<=0&&h.d>0&&(Gsb(c,h,c.c.b,c.c),true)}}}} +function gSc(a,b,c){var d,e,f,g,h,i,j,k;Odd(c,'Processor compute fanout',1);Uhb(a.b);Uhb(a.a);h=null;f=Jsb(b.b,0);while(!h&&f.b!=f.d.c){j=BD(Xsb(f),86);Ccb(DD(vNb(j,(mTc(),jTc))))&&(h=j)}i=new Psb;Gsb(i,h,i.c.b,i.c);fSc(a,i);for(k=Jsb(b.b,0);k.b!=k.d.c;){j=BD(Xsb(k),86);g=GD(vNb(j,(mTc(),$Sc)));e=Phb(a.b,g)!=null?BD(Phb(a.b,g),19).a:0;yNb(j,ZSc,meb(e));d=1+(Phb(a.a,g)!=null?BD(Phb(a.a,g),19).a:0);yNb(j,XSc,meb(d))}Qdd(c)} +function WPc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o;m=VPc(a,c);for(i=0;i<b;i++){Aib(e,c);n=new Rkb;o=(sCb(d.b<d.d.gc()),BD(d.d.Xb(d.c=d.b++),407));for(k=m+i;k<a.b;k++){h=o;o=(sCb(d.b<d.d.gc()),BD(d.d.Xb(d.c=d.b++),407));Ekb(n,new aQc(h,o,c))}for(l=m+i;l<a.b;l++){sCb(d.b>0);d.a.Xb(d.c=--d.b);l>m+i&&uib(d)}for(g=new olb(n);g.a<g.c.c.length;){f=BD(mlb(g),407);Aib(d,f)}if(i<b-1){for(j=m+i;j<a.b;j++){sCb(d.b>0);d.a.Xb(d.c=--d.b)}}}} +function Jfe(){wfe();var a,b,c,d,e,f;if(gfe)return gfe;a=(++vfe,new $fe(4));Xfe(a,Kfe(vxe,true));Zfe(a,Kfe('M',true));Zfe(a,Kfe('C',true));f=(++vfe,new $fe(4));for(d=0;d<11;d++){Ufe(f,d,d)}b=(++vfe,new $fe(4));Xfe(b,Kfe('M',true));Ufe(b,4448,4607);Ufe(b,65438,65439);e=(++vfe,new Lge(2));Kge(e,a);Kge(e,ffe);c=(++vfe,new Lge(2));c.$l(Bfe(f,Kfe('L',true)));c.$l(b);c=(++vfe,new lge(3,c));c=(++vfe,new rge(e,c));gfe=c;return gfe} +function S3c(a){var b,c;b=GD(hkd(a,(Y9c(),o8c)));if(T3c(b,a)){return}if(!ikd(a,F9c)&&((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a).i!=0||Ccb(DD(hkd(a,M8c))))){if(b==null||ufb(b).length==0){if(!T3c(sne,a)){c=Qfb(Qfb(new Wfb('Unable to load default layout algorithm '),sne),' for unconfigured node ');yfd(a,c);throw vbb(new y2c(c.a))}}else{c=Qfb(Qfb(new Wfb("Layout algorithm '"),b),"' not found for ");yfd(a,c);throw vbb(new y2c(c.a))}}} +function hIb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;c=a.i;b=a.n;if(a.b==0){n=c.c+b.b;m=c.b-b.b-b.c;for(g=a.a,i=0,k=g.length;i<k;++i){e=g[i];mHb(e,n,m)}}else{d=kIb(a,false);mHb(a.a[0],c.c+b.b,d[0]);mHb(a.a[2],c.c+c.b-b.c-d[2],d[2]);l=c.b-b.b-b.c;if(d[0]>0){l-=d[0]+a.c;d[0]+=a.c}d[2]>0&&(l-=d[2]+a.c);d[1]=$wnd.Math.max(d[1],l);mHb(a.a[1],c.c+b.b+d[0]-(d[1]-l)/2,d[1])}for(f=a.a,h=0,j=f.length;h<j;++h){e=f[h];JD(e,326)&&BD(e,326).Te()}} +function KMc(a){var b,c,d,e,f,g,h,i,j,k,l;l=new JMc;l.d=0;for(g=new olb(a.b);g.a<g.c.c.length;){f=BD(mlb(g),29);l.d+=f.a.c.length}d=0;e=0;l.a=KC(WD,oje,25,a.b.c.length,15,1);j=0;k=0;l.e=KC(WD,oje,25,l.d,15,1);for(c=new olb(a.b);c.a<c.c.c.length;){b=BD(mlb(c),29);b.p=d++;l.a[b.p]=e++;k=0;for(i=new olb(b.a);i.a<i.c.c.length;){h=BD(mlb(i),10);h.p=j++;l.e[h.p]=k++}}l.c=new OMc(l);l.b=Pu(l.d);LMc(l,a);l.f=Pu(l.d);MMc(l,a);return l} +function GZc(a,b){var c,d,e,f;f=BD(Ikb(a.n,a.n.c.length-1),211).d;a.p=$wnd.Math.min(a.p,b.g);a.r=$wnd.Math.max(a.r,f);a.g=$wnd.Math.max(a.g,b.g+(a.b.c.length==1?0:a.i));a.o=$wnd.Math.min(a.o,b.f);a.e+=b.f+(a.b.c.length==1?0:a.i);a.f=$wnd.Math.max(a.f,b.f);e=a.n.c.length>0?(a.n.c.length-1)*a.i:0;for(d=new olb(a.n);d.a<d.c.c.length;){c=BD(mlb(d),211);e+=c.a}a.d=e;a.a=a.e/a.b.c.length-a.i*((a.b.c.length-1)/a.b.c.length);u$c(a.j)} +function LQb(a,b){var c,d,e,f,g,h,i,j,k,l;k=DD(vNb(b,(wSb(),sSb)));if(k==null||(uCb(k),k)){l=KC(sbb,dle,25,b.e.c.length,16,1);g=HQb(b);e=new Psb;for(j=new olb(b.e);j.a<j.c.c.length;){h=BD(mlb(j),144);c=IQb(a,h,null,null,l,g);if(c){tNb(c,b);Gsb(e,c,e.c.b,e.c)}}if(e.b>1){for(d=Jsb(e,0);d.b!=d.d.c;){c=BD(Xsb(d),231);f=0;for(i=new olb(c.e);i.a<i.c.c.length;){h=BD(mlb(i),144);h.b=f++}}}return e}return Ou(OC(GC($O,1),fme,231,0,[b]))} +function TKd(a){var b,c,d,e,f,g,h;if(!a.g){h=new zNd;b=KKd;g=b.a.zc(a,b);if(g==null){for(d=new Fyd(_Kd(a));d.e!=d.i.gc();){c=BD(Dyd(d),26);ytd(h,TKd(c))}b.a.Bc(a)!=null;b.a.gc()==0&&undefined}e=h.i;for(f=(!a.s&&(a.s=new cUd(t5,a,21,17)),new Fyd(a.s));f.e!=f.i.gc();++e){bJd(BD(Dyd(f),449),e)}ytd(h,(!a.s&&(a.s=new cUd(t5,a,21,17)),a.s));vud(h);a.g=new rNd(a,h);a.i=BD(h.g,247);a.i==null&&(a.i=MKd);a.p=null;$Kd(a).b&=-5}return a.g} +function iIb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;d=a.i;c=a.n;if(a.b==0){b=jIb(a,false);nHb(a.a[0],d.d+c.d,b[0]);nHb(a.a[2],d.d+d.a-c.a-b[2],b[2]);m=d.a-c.d-c.a;l=m;if(b[0]>0){b[0]+=a.c;l-=b[0]}b[2]>0&&(l-=b[2]+a.c);b[1]=$wnd.Math.max(b[1],l);nHb(a.a[1],d.d+c.d+b[0]-(b[1]-l)/2,b[1])}else{o=d.d+c.d;n=d.a-c.d-c.a;for(g=a.a,i=0,k=g.length;i<k;++i){e=g[i];nHb(e,o,n)}}for(f=a.a,h=0,j=f.length;h<j;++h){e=f[h];JD(e,326)&&BD(e,326).Ue()}} +function boc(a){var b,c,d,e,f,g,h,i,j,k;k=KC(WD,oje,25,a.b.c.length+1,15,1);j=new Tqb;d=0;for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);k[d++]=j.a.gc();for(i=new olb(e.a);i.a<i.c.c.length;){g=BD(mlb(i),10);for(c=new Sr(ur(U_b(g).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);j.a.zc(b,j)}}for(h=new olb(e.a);h.a<h.c.c.length;){g=BD(mlb(h),10);for(c=new Sr(ur(R_b(g).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);j.a.Bc(b)!=null}}}return k} +function F2d(a,b,c,d){var e,f,g,h,i;i=S6d(a.e.Tg(),b);e=BD(a.g,119);Q6d();if(BD(b,66).Oj()){for(g=0;g<a.i;++g){f=e[g];if(i.rl(f.ak())&&pb(f,c)){return true}}}else if(c!=null){for(h=0;h<a.i;++h){f=e[h];if(i.rl(f.ak())&&pb(c,f.dd())){return true}}if(d){for(g=0;g<a.i;++g){f=e[g];if(i.rl(f.ak())&&PD(c)===PD(a3d(a,BD(f.dd(),56)))){return true}}}}else{for(g=0;g<a.i;++g){f=e[g];if(i.rl(f.ak())&&f.dd()==null){return false}}}return false} +function e3d(a,b,c,d){var e,f,g,h,i,j;j=S6d(a.e.Tg(),b);g=BD(a.g,119);if(T6d(a.e,b)){if(b.hi()){f=M2d(a,b,d,JD(b,99)&&(BD(b,18).Bb&Tje)!=0);if(f>=0&&f!=c){throw vbb(new Wdb(kue))}}e=0;for(i=0;i<a.i;++i){h=g[i];if(j.rl(h.ak())){if(e==c){return BD(Gtd(a,i,(Q6d(),BD(b,66).Oj()?BD(d,72):R6d(b,d))),72)}++e}}throw vbb(new qcb(gve+c+mue+e))}else{for(i=0;i<a.i;++i){h=g[i];if(j.rl(h.ak())){return Q6d(),BD(b,66).Oj()?h:h.dd()}}return null}} +function ONb(a,b,c,d){var e,f,g,h;h=c;for(g=new olb(b.a);g.a<g.c.c.length;){f=BD(mlb(g),221);e=BD(f.b,65);if(Jy(a.b.c,e.b.c+e.b.b)<=0&&Jy(e.b.c,a.b.c+a.b.b)<=0&&Jy(a.b.d,e.b.d+e.b.a)<=0&&Jy(e.b.d,a.b.d+a.b.a)<=0){if(Jy(e.b.c,a.b.c+a.b.b)==0&&d.a<0||Jy(e.b.c+e.b.b,a.b.c)==0&&d.a>0||Jy(e.b.d,a.b.d+a.b.a)==0&&d.b<0||Jy(e.b.d+e.b.a,a.b.d)==0&&d.b>0){h=0;break}}else{h=$wnd.Math.min(h,YNb(a,e,d))}h=$wnd.Math.min(h,ONb(a,f,h,d))}return h} +function ifd(a,b){var c,d,e,f,g,h,i;if(a.b<2){throw vbb(new Wdb('The vector chain must contain at least a source and a target point.'))}e=(sCb(a.b!=0),BD(a.a.a.c,8));nmd(b,e.a,e.b);i=new Oyd((!b.a&&(b.a=new xMd(y2,b,5)),b.a));g=Jsb(a,1);while(g.a<a.b-1){h=BD(Xsb(g),8);if(i.e!=i.i.gc()){c=BD(Dyd(i),469)}else{c=(Fhd(),d=new xkd,d);Myd(i,c)}ukd(c,h.a,h.b)}while(i.e!=i.i.gc()){Dyd(i);Eyd(i)}f=(sCb(a.b!=0),BD(a.c.b.c,8));gmd(b,f.a,f.b)} +function $lc(a,b){var c,d,e,f,g,h,i,j,k;c=0;for(e=new olb((tCb(0,a.c.length),BD(a.c[0],101)).g.b.j);e.a<e.c.c.length;){d=BD(mlb(e),11);d.p=c++}b==(Ucd(),Acd)?Okb(a,new gmc):Okb(a,new kmc);h=0;k=a.c.length-1;while(h<k){g=(tCb(h,a.c.length),BD(a.c[h],101));j=(tCb(k,a.c.length),BD(a.c[k],101));f=b==Acd?g.c:g.a;i=b==Acd?j.a:j.c;amc(g,b,(Ajc(),yjc),f);amc(j,b,xjc,i);++h;--k}h==k&&amc((tCb(h,a.c.length),BD(a.c[h],101)),b,(Ajc(),wjc),null)} +function UVc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;l=a.a.i+a.a.g/2;m=a.a.i+a.a.g/2;o=b.i+b.g/2;q=b.j+b.f/2;h=new f7c(o,q);j=BD(hkd(b,(Y9c(),C9c)),8);j.a=j.a+l;j.b=j.b+m;f=(h.b-j.b)/(h.a-j.a);d=h.b-f*h.a;p=c.i+c.g/2;r=c.j+c.f/2;i=new f7c(p,r);k=BD(hkd(c,C9c),8);k.a=k.a+l;k.b=k.b+m;g=(i.b-k.b)/(i.a-k.a);e=i.b-g*i.a;n=(d-e)/(g-f);if(j.a<n&&h.a<n||n<j.a&&n<h.a){return false}else if(k.a<n&&i.a<n||n<k.a&&n<i.a){return false}return true} +function gqd(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;m=BD(Ohb(a.c,b),183);if(!m){throw vbb(new cqd('Edge did not exist in input.'))}j=Wpd(m);f=Fhe((!b.a&&(b.a=new cUd(A2,b,6,6)),b.a));h=!f;if(h){n=new wB;c=new Rrd(a,j,n);Dhe((!b.a&&(b.a=new cUd(A2,b,6,6)),b.a),c);cC(m,Nte,n)}e=ikd(b,(Y9c(),Q8c));if(e){k=BD(hkd(b,Q8c),74);g=!k||Ehe(k);i=!g;if(i){l=new wB;d=new Zrd(l);reb(k,d);cC(m,'junctionPoints',l)}}Upd(m,'container',Mld(b).k);return null} +function eDb(a,b,c){var d,e,f,g,h,i,j,k;this.a=a;this.b=b;this.c=c;this.e=Ou(OC(GC(GM,1),Uhe,168,0,[new aDb(a,b),new aDb(b,c),new aDb(c,a)]));this.f=Ou(OC(GC(m1,1),nie,8,0,[a,b,c]));this.d=(d=c7c(R6c(this.b),this.a),e=c7c(R6c(this.c),this.a),f=c7c(R6c(this.c),this.b),g=d.a*(this.a.a+this.b.a)+d.b*(this.a.b+this.b.b),h=e.a*(this.a.a+this.c.a)+e.b*(this.a.b+this.c.b),i=2*(d.a*f.b-d.b*f.a),j=(e.b*g-d.b*h)/i,k=(d.a*h-e.a*g)/i,new f7c(j,k))} +function nvd(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o;m=new yC(a.p);cC(b,fue,m);if(c&&!(!a.f?null:vmb(a.f)).a.dc()){k=new wB;cC(b,'logs',k);h=0;for(o=new Dnb((!a.f?null:vmb(a.f)).b.Kc());o.b.Ob();){n=GD(o.b.Pb());l=new yC(n);tB(k,h);vB(k,h,l);++h}}if(d){j=new TB(a.q);cC(b,'executionTime',j)}if(!vmb(a.a).a.dc()){g=new wB;cC(b,Jte,g);h=0;for(f=new Dnb(vmb(a.a).b.Kc());f.b.Ob();){e=BD(f.b.Pb(),1949);i=new eC;tB(g,h);vB(g,h,i);nvd(e,i,c,d);++h}}} +function PZb(a,b){var c,d,e,f,g,h;f=a.c;g=a.d;QZb(a,null);RZb(a,null);b&&Ccb(DD(vNb(g,(wtc(),Msc))))?QZb(a,i_b(g.i,(KAc(),IAc),(Ucd(),zcd))):QZb(a,g);b&&Ccb(DD(vNb(f,(wtc(),etc))))?RZb(a,i_b(f.i,(KAc(),HAc),(Ucd(),Tcd))):RZb(a,f);for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),70);e=BD(vNb(c,(Nyc(),Qwc)),272);e==(qad(),pad)?yNb(c,Qwc,oad):e==oad&&yNb(c,Qwc,pad)}h=Ccb(DD(vNb(a,(wtc(),ltc))));yNb(a,ltc,(Bcb(),h?false:true));a.a=w7c(a.a)} +function VQb(a,b,c){var d,e,f,g,h,i;d=0;for(f=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));f.e!=f.i.gc();){e=BD(Dyd(f),33);g='';(!e.n&&(e.n=new cUd(D2,e,1,7)),e.n).i==0||(g=BD(qud((!e.n&&(e.n=new cUd(D2,e,1,7)),e.n),0),137).a);h=new pRb(g);tNb(h,e);yNb(h,(HSb(),FSb),e);h.b=d++;h.d.a=e.i+e.g/2;h.d.b=e.j+e.f/2;h.e.a=$wnd.Math.max(e.g,1);h.e.b=$wnd.Math.max(e.f,1);Ekb(b.e,h);jrb(c.f,e,h);i=BD(hkd(e,(wSb(),mSb)),98);i==(dcd(),ccd)&&(i=bcd)}} +function XJc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;c=nGb(new pGb,a.f);j=a.i[b.c.i.p];n=a.i[b.d.i.p];i=b.c;m=b.d;h=i.a.b;l=m.a.b;j.b||(h+=i.n.b);n.b||(l+=m.n.b);k=QD($wnd.Math.max(0,h-l));g=QD($wnd.Math.max(0,l-h));o=(p=$wnd.Math.max(1,BD(vNb(b,(Nyc(),eyc)),19).a),q=JJc(b.c.i.k,b.d.i.k),p*q);e=AFb(DFb(CFb(BFb(EFb(new FFb,o),g),c),BD(Ohb(a.k,b.c),121)));f=AFb(DFb(CFb(BFb(EFb(new FFb,o),k),c),BD(Ohb(a.k,b.d),121)));d=new qKc(e,f);a.c[b.p]=d} +function NEc(a,b,c,d){var e,f,g,h,i,j;g=new _Ec(a,b,c);i=new Bib(d,0);e=false;while(i.b<i.d.gc()){h=(sCb(i.b<i.d.gc()),BD(i.d.Xb(i.c=i.b++),233));if(h==b||h==c){uib(i)}else if(!e&&Edb(REc(h.g,h.d[0]).a)>Edb(REc(g.g,g.d[0]).a)){sCb(i.b>0);i.a.Xb(i.c=--i.b);Aib(i,g);e=true}else if(!!h.e&&h.e.gc()>0){f=(!h.e&&(h.e=new Rkb),h.e).Mc(b);j=(!h.e&&(h.e=new Rkb),h.e).Mc(c);if(f||j){(!h.e&&(h.e=new Rkb),h.e).Fc(g);++g.c}}}e||(d.c[d.c.length]=g,true)} +function odc(a){var b,c,d;if(fcd(BD(vNb(a,(Nyc(),Vxc)),98))){for(c=new olb(a.j);c.a<c.c.c.length;){b=BD(mlb(c),11);b.j==(Ucd(),Scd)&&(d=BD(vNb(b,(wtc(),gtc)),10),d?G0b(b,BD(vNb(d,Hsc),61)):b.e.c.length-b.g.c.length<0?G0b(b,zcd):G0b(b,Tcd))}}else{for(c=new olb(a.j);c.a<c.c.c.length;){b=BD(mlb(c),11);d=BD(vNb(b,(wtc(),gtc)),10);d?G0b(b,BD(vNb(d,Hsc),61)):b.e.c.length-b.g.c.length<0?G0b(b,(Ucd(),zcd)):G0b(b,(Ucd(),Tcd))}yNb(a,Vxc,(dcd(),acd))}} +function age(a){var b,c,d;switch(a){case 91:case 93:case 45:case 94:case 44:case 92:d='\\'+String.fromCharCode(a&aje);break;case 12:d='\\f';break;case 10:d='\\n';break;case 13:d='\\r';break;case 9:d='\\t';break;case 27:d='\\e';break;default:if(a<32){c=(b=a>>>0,'0'+b.toString(16));d='\\x'+qfb(c,c.length-2,c.length)}else if(a>=Tje){c=(b=a>>>0,'0'+b.toString(16));d='\\v'+qfb(c,c.length-6,c.length)}else d=''+String.fromCharCode(a&aje);}return d} +function yhb(a,b){var c,d,e,f,g,h,i,j,k,l;g=a.e;i=b.e;if(i==0){return a}if(g==0){return b.e==0?b:new Vgb(-b.e,b.d,b.a)}f=a.d;h=b.d;if(f+h==2){c=xbb(a.a[0],Yje);d=xbb(b.a[0],Yje);g<0&&(c=Jbb(c));i<0&&(d=Jbb(d));return ghb(Qbb(c,d))}e=f!=h?f>h?1:-1:whb(a.a,b.a,f);if(e==-1){l=-i;k=g==i?zhb(b.a,h,a.a,f):uhb(b.a,h,a.a,f)}else{l=g;if(g==i){if(e==0){return Hgb(),Ggb}k=zhb(a.a,f,b.a,h)}else{k=uhb(a.a,f,b.a,h)}}j=new Vgb(l,k.length,k);Jgb(j);return j} +function YPc(a){var b,c,d,e,f,g;this.e=new Rkb;this.a=new Rkb;for(c=a.b-1;c<3;c++){St(a,0,BD(Ut(a,0),8))}if(a.b<4){throw vbb(new Wdb('At (least dimension + 1) control points are necessary!'))}else{this.b=3;this.d=true;this.c=false;TPc(this,a.b+this.b-1);g=new Rkb;f=new olb(this.e);for(b=0;b<this.b-1;b++){Ekb(g,ED(mlb(f)))}for(e=Jsb(a,0);e.b!=e.d.c;){d=BD(Xsb(e),8);Ekb(g,ED(mlb(f)));Ekb(this.a,new bQc(d,g));tCb(0,g.c.length);g.c.splice(0,1)}}} +function Bac(a,b){var c,d,e,f,g,h,i,j,k;for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);for(h=new olb(e.a);h.a<h.c.c.length;){g=BD(mlb(h),10);if(g.k==(j0b(),f0b)){i=(j=BD(Rr(new Sr(ur(R_b(g).a.Kc(),new Sq))),17),k=BD(Rr(new Sr(ur(U_b(g).a.Kc(),new Sq))),17),!Ccb(DD(vNb(j,(wtc(),ltc))))||!Ccb(DD(vNb(k,ltc))))?b:sbd(b);zac(g,i)}for(d=new Sr(ur(U_b(g).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);i=Ccb(DD(vNb(c,(wtc(),ltc))))?sbd(b):b;yac(c,i)}}}} +function yZc(a,b,c,d,e){var f,g,h;if(c.f>=b.o&&c.f<=b.f||b.a*0.5<=c.f&&b.a*1.5>=c.f){g=BD(Ikb(b.n,b.n.c.length-1),211);if(g.e+g.d+c.g+e<=d&&(f=BD(Ikb(b.n,b.n.c.length-1),211),f.f-a.f+c.f<=a.b||a.a.c.length==1)){EZc(b,c);return true}else if(b.s+c.g<=d&&(b.t+b.d+c.f+e<=a.b||a.a.c.length==1)){Ekb(b.b,c);h=BD(Ikb(b.n,b.n.c.length-1),211);Ekb(b.n,new VZc(b.s,h.f+h.a+b.i,b.i));QZc(BD(Ikb(b.n,b.n.c.length-1),211),c);GZc(b,c);return true}}return false} +function Zxd(a,b,c){var d,e,f,g;if(a.ej()){e=null;f=a.fj();d=a.Zi(1,g=uud(a,b,c),c,b,f);if(a.bj()&&!(a.ni()&&g!=null?pb(g,c):PD(g)===PD(c))){g!=null&&(e=a.dj(g,e));e=a.cj(c,e);a.ij()&&(e=a.lj(g,c,e));if(!e){a.$i(d)}else{e.Ei(d);e.Fi()}}else{a.ij()&&(e=a.lj(g,c,e));if(!e){a.$i(d)}else{e.Ei(d);e.Fi()}}return g}else{g=uud(a,b,c);if(a.bj()&&!(a.ni()&&g!=null?pb(g,c):PD(g)===PD(c))){e=null;g!=null&&(e=a.dj(g,null));e=a.cj(c,e);!!e&&e.Fi()}return g}} +function YA(a,b){var c,d,e,f,g,h,i,j;b%=24;if(a.q.getHours()!=b){d=new $wnd.Date(a.q.getTime());d.setDate(d.getDate()+1);h=a.q.getTimezoneOffset()-d.getTimezoneOffset();if(h>0){i=h/60|0;j=h%60;e=a.q.getDate();c=a.q.getHours();c+i>=24&&++e;f=new $wnd.Date(a.q.getFullYear(),a.q.getMonth(),e,b+i,a.q.getMinutes()+j,a.q.getSeconds(),a.q.getMilliseconds());a.q.setTime(f.getTime())}}g=a.q.getTime();a.q.setTime(g+3600000);a.q.getHours()!=b&&a.q.setTime(g)} +function opc(a,b){var c,d,e,f,g;Odd(b,'Path-Like Graph Wrapping',1);if(a.b.c.length==0){Qdd(b);return}e=new Xoc(a);g=(e.i==null&&(e.i=Soc(e,new Zoc)),Edb(e.i)*e.f);c=g/(e.i==null&&(e.i=Soc(e,new Zoc)),Edb(e.i));if(e.b>c){Qdd(b);return}switch(BD(vNb(a,(Nyc(),Gyc)),337).g){case 2:f=new hpc;break;case 0:f=new Ync;break;default:f=new kpc;}d=f.Vf(a,e);if(!f.Wf()){switch(BD(vNb(a,Myc),338).g){case 2:d=tpc(e,d);break;case 1:d=rpc(e,d);}}npc(a,e,d);Qdd(b)} +function MFc(a,b){var c,d,e,f;Fub(a.d,a.e);a.c.a.$b();if(Edb(ED(vNb(b.j,(Nyc(),uwc))))!=0||Edb(ED(vNb(b.j,uwc)))!=0){c=dme;PD(vNb(b.j,ywc))!==PD((tAc(),rAc))&&yNb(b.j,(wtc(),Jsc),(Bcb(),true));f=BD(vNb(b.j,Ayc),19).a;for(e=0;e<f;e++){d=WFc(a,b);if(d<c){c=d;ZFc(a);if(c==0){break}}}}else{c=Ohe;PD(vNb(b.j,ywc))!==PD((tAc(),rAc))&&yNb(b.j,(wtc(),Jsc),(Bcb(),true));f=BD(vNb(b.j,Ayc),19).a;for(e=0;e<f;e++){d=XFc(a,b);if(d<c){c=d;ZFc(a);if(c==0){break}}}}} +function spc(a,b){var c,d,e,f,g,h,i,j;g=new Rkb;h=0;c=0;i=0;while(h<b.c.length-1&&c<a.gc()){d=BD(a.Xb(c),19).a+i;while((tCb(h+1,b.c.length),BD(b.c[h+1],19)).a<d){++h}j=0;f=d-(tCb(h,b.c.length),BD(b.c[h],19)).a;e=(tCb(h+1,b.c.length),BD(b.c[h+1],19)).a-d;f>e&&++j;Ekb(g,(tCb(h+j,b.c.length),BD(b.c[h+j],19)));i+=(tCb(h+j,b.c.length),BD(b.c[h+j],19)).a-d;++c;while(c<a.gc()&&BD(a.Xb(c),19).a+i<=(tCb(h+j,b.c.length),BD(b.c[h+j],19)).a){++c}h+=1+j}return g} +function RKd(a){var b,c,d,e,f,g,h;if(!a.d){h=new XNd;b=KKd;f=b.a.zc(a,b);if(f==null){for(d=new Fyd(_Kd(a));d.e!=d.i.gc();){c=BD(Dyd(d),26);ytd(h,RKd(c))}b.a.Bc(a)!=null;b.a.gc()==0&&undefined}g=h.i;for(e=(!a.q&&(a.q=new cUd(n5,a,11,10)),new Fyd(a.q));e.e!=e.i.gc();++g){BD(Dyd(e),399)}ytd(h,(!a.q&&(a.q=new cUd(n5,a,11,10)),a.q));vud(h);a.d=new nNd((BD(qud(ZKd((NFd(),MFd).o),9),18),h.i),h.g);a.e=BD(h.g,673);a.e==null&&(a.e=LKd);$Kd(a).b&=-17}return a.d} +function M2d(a,b,c,d){var e,f,g,h,i,j;j=S6d(a.e.Tg(),b);i=0;e=BD(a.g,119);Q6d();if(BD(b,66).Oj()){for(g=0;g<a.i;++g){f=e[g];if(j.rl(f.ak())){if(pb(f,c)){return i}++i}}}else if(c!=null){for(h=0;h<a.i;++h){f=e[h];if(j.rl(f.ak())){if(pb(c,f.dd())){return i}++i}}if(d){i=0;for(g=0;g<a.i;++g){f=e[g];if(j.rl(f.ak())){if(PD(c)===PD(a3d(a,BD(f.dd(),56)))){return i}++i}}}}else{for(g=0;g<a.i;++g){f=e[g];if(j.rl(f.ak())){if(f.dd()==null){return i}++i}}}return -1} +function aed(a,b,c,d,e){var f,g,h,i,j,k,l,m,n;mmb();Okb(a,new Jed);g=Ru(a);n=new Rkb;m=new Rkb;h=null;i=0;while(g.b!=0){f=BD(g.b==0?null:(sCb(g.b!=0),Nsb(g,g.a.a)),157);if(!h||red(h)*qed(h)/2<red(f)*qed(f)){h=f;n.c[n.c.length]=f}else{i+=red(f)*qed(f);m.c[m.c.length]=f;if(m.c.length>1&&(i>red(h)*qed(h)/2||g.b==0)){l=new wed(m);k=red(h)/qed(h);j=fed(l,b,new p0b,c,d,e,k);P6c(X6c(l.e),j);h=l;n.c[n.c.length]=l;i=0;m.c=KC(SI,Uhe,1,0,5,1)}}}Gkb(n,m);return n} +function y6d(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p;if(c.mh(b)){k=(n=b,!n?null:BD(d,49).xh(n));if(k){p=c.bh(b,a.a);o=b.t;if(o>1||o==-1){l=BD(p,69);m=BD(k,69);if(l.dc()){m.$b()}else{g=!!zUd(b);f=0;for(h=a.a?l.Kc():l.Zh();h.Ob();){j=BD(h.Pb(),56);e=BD(Wrb(a,j),56);if(!e){if(a.b&&!g){m.Xh(f,j);++f}}else{if(g){i=m.Xc(e);i==-1?m.Xh(f,e):f!=i&&m.ji(f,e)}else{m.Xh(f,e)}++f}}}}else{if(p==null){k.Wb(null)}else{e=Wrb(a,p);e==null?a.b&&!zUd(b)&&k.Wb(p):k.Wb(e)}}}}} +function E6b(a,b){var c,d,e,f,g,h,i,j;c=new L6b;for(e=new Sr(ur(R_b(b).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);if(OZb(d)){continue}h=d.c.i;if(F6b(h,C6b)){j=G6b(a,h,C6b,B6b);if(j==-1){continue}c.b=$wnd.Math.max(c.b,j);!c.a&&(c.a=new Rkb);Ekb(c.a,h)}}for(g=new Sr(ur(U_b(b).a.Kc(),new Sq));Qr(g);){f=BD(Rr(g),17);if(OZb(f)){continue}i=f.d.i;if(F6b(i,B6b)){j=G6b(a,i,B6b,C6b);if(j==-1){continue}c.d=$wnd.Math.max(c.d,j);!c.c&&(c.c=new Rkb);Ekb(c.c,i)}}return c} +function Khb(a){Dhb();var b,c,d,e;b=QD(a);if(a<Chb.length){return Chb[b]}else if(a<=50){return Pgb((Hgb(),Egb),b)}else if(a<=_ie){return Qgb(Pgb(Bhb[1],b),b)}if(a>1000000){throw vbb(new ocb('power of ten too big'))}if(a<=Ohe){return Qgb(Pgb(Bhb[1],b),b)}d=Pgb(Bhb[1],Ohe);e=d;c=Cbb(a-Ohe);b=QD(a%Ohe);while(ybb(c,Ohe)>0){e=Ogb(e,d);c=Qbb(c,Ohe)}e=Ogb(e,Pgb(Bhb[1],b));e=Qgb(e,Ohe);c=Cbb(a-Ohe);while(ybb(c,Ohe)>0){e=Qgb(e,Ohe);c=Qbb(c,Ohe)}e=Qgb(e,b);return e} +function X5b(a,b){var c,d,e,f,g,h,i,j,k;Odd(b,'Hierarchical port dummy size processing',1);i=new Rkb;k=new Rkb;d=Edb(ED(vNb(a,(Nyc(),myc))));c=d*2;for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);i.c=KC(SI,Uhe,1,0,5,1);k.c=KC(SI,Uhe,1,0,5,1);for(h=new olb(e.a);h.a<h.c.c.length;){g=BD(mlb(h),10);if(g.k==(j0b(),e0b)){j=BD(vNb(g,(wtc(),Hsc)),61);j==(Ucd(),Acd)?(i.c[i.c.length]=g,true):j==Rcd&&(k.c[k.c.length]=g,true)}}Y5b(i,true,c);Y5b(k,false,c)}Qdd(b)} +function Oac(a,b){var c,d,e,f,g,h,i;Odd(b,'Layer constraint postprocessing',1);i=a.b;if(i.c.length!=0){d=(tCb(0,i.c.length),BD(i.c[0],29));g=BD(Ikb(i,i.c.length-1),29);c=new H1b(a);f=new H1b(a);Mac(a,d,g,c,f);c.a.c.length==0||(wCb(0,i.c.length),aCb(i.c,0,c));f.a.c.length==0||(i.c[i.c.length]=f,true)}if(wNb(a,(wtc(),Lsc))){e=new H1b(a);h=new H1b(a);Pac(a,e,h);e.a.c.length==0||(wCb(0,i.c.length),aCb(i.c,0,e));h.a.c.length==0||(i.c[i.c.length]=h,true)}Qdd(b)} +function b6b(a){var b,c,d,e,f,g,h,i,j,k;for(i=new olb(a.a);i.a<i.c.c.length;){h=BD(mlb(i),10);if(h.k!=(j0b(),e0b)){continue}e=BD(vNb(h,(wtc(),Hsc)),61);if(e==(Ucd(),zcd)||e==Tcd){for(d=new Sr(ur(O_b(h).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);b=c.a;if(b.b==0){continue}j=c.c;if(j.i==h){f=(sCb(b.b!=0),BD(b.a.a.c,8));f.b=l7c(OC(GC(m1,1),nie,8,0,[j.i.n,j.n,j.a])).b}k=c.d;if(k.i==h){g=(sCb(b.b!=0),BD(b.c.b.c,8));g.b=l7c(OC(GC(m1,1),nie,8,0,[k.i.n,k.n,k.a])).b}}}}} +function Tec(a,b){var c,d,e,f,g,h,i;Odd(b,'Sort By Input Model '+vNb(a,(Nyc(),ywc)),1);e=0;for(d=new olb(a.b);d.a<d.c.c.length;){c=BD(mlb(d),29);i=e==0?0:e-1;h=BD(Ikb(a.b,i),29);for(g=new olb(c.a);g.a<g.c.c.length;){f=BD(mlb(g),10);if(PD(vNb(f,Vxc))!==PD((dcd(),Zbd))&&PD(vNb(f,Vxc))!==PD($bd)){mmb();Okb(f.j,new Tnc(h,Xec(f)));Sdd(b,'Node '+f+' ports: '+f.j)}}mmb();Okb(c.a,new Bnc(h,BD(vNb(a,ywc),339),BD(vNb(a,wwc),378)));Sdd(b,'Layer '+e+': '+c);++e}Qdd(b)} +function U1b(a,b){var c,d,e,f;f=P1b(b);MAb(new YAb(null,(!b.c&&(b.c=new cUd(F2,b,9,9)),new Kub(b.c,16))),new i2b(f));e=BD(vNb(f,(wtc(),Ksc)),21);O1b(b,e);if(e.Hc((Orc(),Hrc))){for(d=new Fyd((!b.c&&(b.c=new cUd(F2,b,9,9)),b.c));d.e!=d.i.gc();){c=BD(Dyd(d),118);Y1b(a,b,f,c)}}BD(hkd(b,(Nyc(),Fxc)),174).gc()!=0&&L1b(b,f);Ccb(DD(vNb(f,Mxc)))&&e.Fc(Mrc);wNb(f,hyc)&&Wyc(new ezc(Edb(ED(vNb(f,hyc)))),f);PD(hkd(b,axc))===PD((hbd(),ebd))?V1b(a,b,f):T1b(a,b,f);return f} +function hic(a,b,c,d){var e,f,g;this.j=new Rkb;this.k=new Rkb;this.b=new Rkb;this.c=new Rkb;this.e=new I6c;this.i=new s7c;this.f=new lEb;this.d=new Rkb;this.g=new Rkb;Ekb(this.b,a);Ekb(this.b,b);this.e.c=$wnd.Math.min(a.a,b.a);this.e.d=$wnd.Math.min(a.b,b.b);this.e.b=$wnd.Math.abs(a.a-b.a);this.e.a=$wnd.Math.abs(a.b-b.b);e=BD(vNb(d,(Nyc(),jxc)),74);if(e){for(g=Jsb(e,0);g.b!=g.d.c;){f=BD(Xsb(g),8);ADb(f.a,a.a)&&Dsb(this.i,f)}}!!c&&Ekb(this.j,c);Ekb(this.k,d)} +function oTb(a,b,c){var d,e,f,g,h,i,j,k,l,m;k=new gub(new ETb(c));h=KC(sbb,dle,25,a.f.e.c.length,16,1);Glb(h,h.length);c[b.b]=0;for(j=new olb(a.f.e);j.a<j.c.c.length;){i=BD(mlb(j),144);i.b!=b.b&&(c[i.b]=Ohe);zCb(cub(k,i))}while(k.b.c.length!=0){l=BD(dub(k),144);h[l.b]=true;for(f=au(new bu(a.b,l),0);f.c;){e=BD(uu(f),282);m=rTb(e,l);if(h[m.b]){continue}wNb(e,(bTb(),RSb))?(g=Edb(ED(vNb(e,RSb)))):(g=a.c);d=c[l.b]+g;if(d<c[m.b]){c[m.b]=d;eub(k,m);zCb(cub(k,m))}}}} +function xMc(a,b,c){var d,e,f,g,h,i,j,k,l;e=true;for(g=new olb(a.b);g.a<g.c.c.length;){f=BD(mlb(g),29);j=Qje;k=null;for(i=new olb(f.a);i.a<i.c.c.length;){h=BD(mlb(i),10);l=Edb(b.p[h.p])+Edb(b.d[h.p])-h.d.d;d=Edb(b.p[h.p])+Edb(b.d[h.p])+h.o.b+h.d.a;if(l>j&&d>j){k=h;j=Edb(b.p[h.p])+Edb(b.d[h.p])+h.o.b+h.d.a}else{e=false;c.n&&Sdd(c,'bk node placement breaks on '+h+' which should have been after '+k);break}}if(!e){break}}c.n&&Sdd(c,b+' is feasible: '+e);return e} +function XNc(a,b,c,d){var e,f,g,h,i,j,k;h=-1;for(k=new olb(a);k.a<k.c.c.length;){j=BD(mlb(k),112);j.g=h--;e=Tbb(tAb(PAb(JAb(new YAb(null,new Kub(j.f,16)),new ZNc),new _Nc)).d);f=Tbb(tAb(PAb(JAb(new YAb(null,new Kub(j.k,16)),new bOc),new dOc)).d);g=e;i=f;if(!d){g=Tbb(tAb(PAb(new YAb(null,new Kub(j.f,16)),new fOc)).d);i=Tbb(tAb(PAb(new YAb(null,new Kub(j.k,16)),new hOc)).d)}j.d=g;j.a=e;j.i=i;j.b=f;i==0?(Gsb(c,j,c.c.b,c.c),true):g==0&&(Gsb(b,j,b.c.b,b.c),true)}} +function $8b(a,b,c,d){var e,f,g,h,i,j,k;if(c.d.i==b.i){return}e=new b0b(a);__b(e,(j0b(),g0b));yNb(e,(wtc(),$sc),c);yNb(e,(Nyc(),Vxc),(dcd(),$bd));d.c[d.c.length]=e;g=new H0b;F0b(g,e);G0b(g,(Ucd(),Tcd));h=new H0b;F0b(h,e);G0b(h,zcd);k=c.d;RZb(c,g);f=new UZb;tNb(f,c);yNb(f,jxc,null);QZb(f,h);RZb(f,k);j=new Bib(c.b,0);while(j.b<j.d.gc()){i=(sCb(j.b<j.d.gc()),BD(j.d.Xb(j.c=j.b++),70));if(PD(vNb(i,Qwc))===PD((qad(),oad))){yNb(i,Dsc,c);uib(j);Ekb(f.b,i)}}a9b(e,g,h)} +function Z8b(a,b,c,d){var e,f,g,h,i,j,k;if(c.c.i==b.i){return}e=new b0b(a);__b(e,(j0b(),g0b));yNb(e,(wtc(),$sc),c);yNb(e,(Nyc(),Vxc),(dcd(),$bd));d.c[d.c.length]=e;g=new H0b;F0b(g,e);G0b(g,(Ucd(),Tcd));h=new H0b;F0b(h,e);G0b(h,zcd);RZb(c,g);f=new UZb;tNb(f,c);yNb(f,jxc,null);QZb(f,h);RZb(f,b);a9b(e,g,h);j=new Bib(c.b,0);while(j.b<j.d.gc()){i=(sCb(j.b<j.d.gc()),BD(j.d.Xb(j.c=j.b++),70));k=BD(vNb(i,Qwc),272);if(k==(qad(),oad)){wNb(i,Dsc)||yNb(i,Dsc,c);uib(j);Ekb(f.b,i)}}} +function dDc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;m=new Rkb;r=Gx(d);q=b*a.a;l=0;o=0;f=new Tqb;g=new Tqb;h=new Rkb;s=0;t=0;n=0;p=0;j=0;k=0;while(r.a.gc()!=0){i=hDc(r,e,g);if(i){r.a.Bc(i)!=null;h.c[h.c.length]=i;f.a.zc(i,f);o=a.f[i.p];s+=a.e[i.p]-o*a.b;l=a.c[i.p];t+=l*a.b;k+=o*a.b;p+=a.e[i.p]}if(!i||r.a.gc()==0||s>=q&&a.e[i.p]>o*a.b||t>=c*q){m.c[m.c.length]=h;h=new Rkb;ye(g,f);f.a.$b();j-=k;n=$wnd.Math.max(n,j*a.b+p);j+=t;s=t;t=0;k=0;p=0}}return new vgd(n,m)} +function q4c(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;for(c=(j=(new $ib(a.c.b)).a.vc().Kc(),new djb(j));c.a.Ob();){b=(h=BD(c.a.Pb(),42),BD(h.dd(),149));e=b.a;e==null&&(e='');d=i4c(a.c,e);!d&&e.length==0&&(d=u4c(a));!!d&&!ze(d.c,b,false)&&Dsb(d.c,b)}for(g=Jsb(a.a,0);g.b!=g.d.c;){f=BD(Xsb(g),478);k=j4c(a.c,f.a);n=j4c(a.c,f.b);!!k&&!!n&&Dsb(k.c,new vgd(n,f.c))}Osb(a.a);for(m=Jsb(a.b,0);m.b!=m.d.c;){l=BD(Xsb(m),478);b=g4c(a.c,l.a);i=j4c(a.c,l.b);!!b&&!!i&&B3c(b,i,l.c)}Osb(a.b)} +function qvd(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;f=new fC(a);g=new ird;e=(ko(g.g),ko(g.j),Uhb(g.b),ko(g.d),ko(g.i),Uhb(g.k),Uhb(g.c),Uhb(g.e),n=drd(g,f,null),ard(g,f),n);if(b){j=new fC(b);h=rvd(j);jfd(e,OC(GC(g2,1),Uhe,527,0,[h]))}m=false;l=false;if(c){j=new fC(c);que in j.a&&(m=aC(j,que).ge().a);rue in j.a&&(l=aC(j,rue).ge().a)}k=Vdd(Xdd(new Zdd,m),l);t2c(new w2c,e,k);que in f.a&&cC(f,que,null);if(m||l){i=new eC;nvd(k,i,m,l);cC(f,que,i)}d=new Prd(g);Ghe(new _ud(e),d)} +function pA(a,b,c){var d,e,f,g,h,i,j,k,l;g=new nB;j=OC(GC(WD,1),oje,25,15,[0]);e=-1;f=0;d=0;for(i=0;i<a.b.c.length;++i){k=BD(Ikb(a.b,i),434);if(k.b>0){if(e<0&&k.a){e=i;f=j[0];d=0}if(e>=0){h=k.b;if(i==e){h-=d++;if(h==0){return 0}}if(!wA(b,j,k,h,g)){i=e-1;j[0]=f;continue}}else{e=-1;if(!wA(b,j,k,0,g)){return 0}}}else{e=-1;if(bfb(k.c,0)==32){l=j[0];uA(b,j);if(j[0]>l){continue}}else if(ofb(b,k.c,j[0])){j[0]+=k.c.length;continue}return 0}}if(!mB(g,c)){return 0}return j[0]} +function SKd(a){var b,c,d,e,f,g,h,i;if(!a.f){i=new CNd;h=new CNd;b=KKd;g=b.a.zc(a,b);if(g==null){for(f=new Fyd(_Kd(a));f.e!=f.i.gc();){e=BD(Dyd(f),26);ytd(i,SKd(e))}b.a.Bc(a)!=null;b.a.gc()==0&&undefined}for(d=(!a.s&&(a.s=new cUd(t5,a,21,17)),new Fyd(a.s));d.e!=d.i.gc();){c=BD(Dyd(d),170);JD(c,99)&&wtd(h,BD(c,18))}vud(h);a.r=new UNd(a,(BD(qud(ZKd((NFd(),MFd).o),6),18),h.i),h.g);ytd(i,a.r);vud(i);a.f=new nNd((BD(qud(ZKd(MFd.o),5),18),i.i),i.g);$Kd(a).b&=-3}return a.f} +function rMb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;g=a.o;d=KC(WD,oje,25,g,15,1);e=KC(WD,oje,25,g,15,1);c=a.p;b=KC(WD,oje,25,c,15,1);f=KC(WD,oje,25,c,15,1);for(j=0;j<g;j++){l=0;while(l<c&&!YMb(a,j,l)){++l}d[j]=l}for(k=0;k<g;k++){l=c-1;while(l>=0&&!YMb(a,k,l)){--l}e[k]=l}for(n=0;n<c;n++){h=0;while(h<g&&!YMb(a,h,n)){++h}b[n]=h}for(o=0;o<c;o++){h=g-1;while(h>=0&&!YMb(a,h,o)){--h}f[o]=h}for(i=0;i<g;i++){for(m=0;m<c;m++){i<f[m]&&i>b[m]&&m<e[i]&&m>d[i]&&aNb(a,i,m,false,true)}}} +function lRb(a){var b,c,d,e,f,g,h,i;c=Ccb(DD(vNb(a,(wSb(),cSb))));f=a.a.c.d;h=a.a.d.d;if(c){g=Y6c(c7c(new f7c(h.a,h.b),f),0.5);i=Y6c(R6c(a.e),0.5);b=c7c(P6c(new f7c(f.a,f.b),g),i);a7c(a.d,b)}else{e=Edb(ED(vNb(a.a,tSb)));d=a.d;if(f.a>=h.a){if(f.b>=h.b){d.a=h.a+(f.a-h.a)/2+e;d.b=h.b+(f.b-h.b)/2-e-a.e.b}else{d.a=h.a+(f.a-h.a)/2+e;d.b=f.b+(h.b-f.b)/2+e}}else{if(f.b>=h.b){d.a=f.a+(h.a-f.a)/2+e;d.b=h.b+(f.b-h.b)/2+e}else{d.a=f.a+(h.a-f.a)/2+e;d.b=f.b+(h.b-f.b)/2-e-a.e.b}}}} +function Qge(a,b){var c,d,e,f,g,h,i;if(a==null){return null}f=a.length;if(f==0){return ''}i=KC(TD,$ie,25,f,15,1);ACb(0,f,a.length);ACb(0,f,i.length);ffb(a,0,f,i,0);c=null;h=b;for(e=0,g=0;e<f;e++){d=i[e];lde();if(d<=32&&(kde[d]&2)!=0){if(h){!c&&(c=new Jfb(a));Gfb(c,e-g++)}else{h=b;if(d!=32){!c&&(c=new Jfb(a));kcb(c,e-g,e-g+1,String.fromCharCode(32))}}}else{h=false}}if(h){if(!c){return a.substr(0,f-1)}else{f=c.a.length;return f>0?qfb(c.a,0,f-1):''}}else{return !c?a:c.a}} +function DPb(a){r4c(a,new E3c(P3c(M3c(O3c(N3c(new R3c,Yle),'ELK DisCo'),'Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out.'),new GPb)));p4c(a,Yle,Zle,Ksd(BPb));p4c(a,Yle,$le,Ksd(vPb));p4c(a,Yle,_le,Ksd(qPb));p4c(a,Yle,ame,Ksd(wPb));p4c(a,Yle,Zke,Ksd(zPb));p4c(a,Yle,$ke,Ksd(yPb));p4c(a,Yle,Yke,Ksd(APb));p4c(a,Yle,_ke,Ksd(xPb));p4c(a,Yle,Tle,Ksd(sPb));p4c(a,Yle,Ule,Ksd(rPb));p4c(a,Yle,Vle,Ksd(tPb));p4c(a,Yle,Wle,Ksd(uPb))} +function Zbc(a,b,c,d){var e,f,g,h,i,j,k,l,m;f=new b0b(a);__b(f,(j0b(),i0b));yNb(f,(Nyc(),Vxc),(dcd(),$bd));e=0;if(b){g=new H0b;yNb(g,(wtc(),$sc),b);yNb(f,$sc,b.i);G0b(g,(Ucd(),Tcd));F0b(g,f);m=k_b(b.e);for(j=m,k=0,l=j.length;k<l;++k){i=j[k];RZb(i,g)}yNb(b,gtc,f);++e}if(c){h=new H0b;yNb(f,(wtc(),$sc),c.i);yNb(h,$sc,c);G0b(h,(Ucd(),zcd));F0b(h,f);m=k_b(c.g);for(j=m,k=0,l=j.length;k<l;++k){i=j[k];QZb(i,h)}yNb(c,gtc,f);++e}yNb(f,(wtc(),ysc),meb(e));d.c[d.c.length]=f;return f} +function Smd(){Smd=ccb;Qmd=OC(GC(TD,1),$ie,25,15,[48,49,50,51,52,53,54,55,56,57,65,66,67,68,69,70]);Rmd=new RegExp('[ \t\n\r\f]+');try{Pmd=OC(GC(c6,1),Uhe,2015,0,[new EQd((GA(),IA("yyyy-MM-dd'T'HH:mm:ss'.'SSSZ",LA((KA(),KA(),JA))))),new EQd(IA("yyyy-MM-dd'T'HH:mm:ss'.'SSS",LA((null,JA)))),new EQd(IA("yyyy-MM-dd'T'HH:mm:ss",LA((null,JA)))),new EQd(IA("yyyy-MM-dd'T'HH:mm",LA((null,JA)))),new EQd(IA('yyyy-MM-dd',LA((null,JA))))])}catch(a){a=ubb(a);if(!JD(a,78))throw vbb(a)}} +function qgb(a){var b,c,d,e;d=shb((!a.c&&(a.c=fhb(a.f)),a.c),0);if(a.e==0||a.a==0&&a.f!=-1&&a.e<0){return d}b=pgb(a)<0?1:0;c=a.e;e=(d.length+1+$wnd.Math.abs(QD(a.e)),new Vfb);b==1&&(e.a+='-',e);if(a.e>0){c-=d.length-b;if(c>=0){e.a+='0.';for(;c>egb.length;c-=egb.length){Rfb(e,egb)}Sfb(e,egb,QD(c));Qfb(e,d.substr(b))}else{c=b-c;Qfb(e,qfb(d,b,QD(c)));e.a+='.';Qfb(e,pfb(d,QD(c)))}}else{Qfb(e,d.substr(b));for(;c<-egb.length;c+=egb.length){Rfb(e,egb)}Sfb(e,egb,QD(-c))}return e.a} +function v6c(a,b,c,d){var e,f,g,h,i,j,k,l,m;i=c7c(new f7c(c.a,c.b),a);j=i.a*b.b-i.b*b.a;k=b.a*d.b-b.b*d.a;l=(i.a*d.b-i.b*d.a)/k;m=j/k;if(k==0){if(j==0){e=P6c(new f7c(c.a,c.b),Y6c(new f7c(d.a,d.b),0.5));f=S6c(a,e);g=S6c(P6c(new f7c(a.a,a.b),b),e);h=$wnd.Math.sqrt(d.a*d.a+d.b*d.b)*0.5;if(f<g&&f<=h){return new f7c(a.a,a.b)}if(g<=h){return P6c(new f7c(a.a,a.b),b)}return null}else{return null}}else{return l>=0&&l<=1&&m>=0&&m<=1?P6c(new f7c(a.a,a.b),Y6c(new f7c(b.a,b.b),l)):null}} +function OTb(a,b,c){var d,e,f,g,h;d=BD(vNb(a,(Nyc(),zwc)),21);c.a>b.a&&(d.Hc((i8c(),c8c))?(a.c.a+=(c.a-b.a)/2):d.Hc(e8c)&&(a.c.a+=c.a-b.a));c.b>b.b&&(d.Hc((i8c(),g8c))?(a.c.b+=(c.b-b.b)/2):d.Hc(f8c)&&(a.c.b+=c.b-b.b));if(BD(vNb(a,(wtc(),Ksc)),21).Hc((Orc(),Hrc))&&(c.a>b.a||c.b>b.b)){for(h=new olb(a.a);h.a<h.c.c.length;){g=BD(mlb(h),10);if(g.k==(j0b(),e0b)){e=BD(vNb(g,Hsc),61);e==(Ucd(),zcd)?(g.n.a+=c.a-b.a):e==Rcd&&(g.n.b+=c.b-b.b)}}}f=a.d;a.f.a=c.a-f.b-f.c;a.f.b=c.b-f.d-f.a} +function H5b(a,b,c){var d,e,f,g,h;d=BD(vNb(a,(Nyc(),zwc)),21);c.a>b.a&&(d.Hc((i8c(),c8c))?(a.c.a+=(c.a-b.a)/2):d.Hc(e8c)&&(a.c.a+=c.a-b.a));c.b>b.b&&(d.Hc((i8c(),g8c))?(a.c.b+=(c.b-b.b)/2):d.Hc(f8c)&&(a.c.b+=c.b-b.b));if(BD(vNb(a,(wtc(),Ksc)),21).Hc((Orc(),Hrc))&&(c.a>b.a||c.b>b.b)){for(g=new olb(a.a);g.a<g.c.c.length;){f=BD(mlb(g),10);if(f.k==(j0b(),e0b)){e=BD(vNb(f,Hsc),61);e==(Ucd(),zcd)?(f.n.a+=c.a-b.a):e==Rcd&&(f.n.b+=c.b-b.b)}}}h=a.d;a.f.a=c.a-h.b-h.c;a.f.b=c.b-h.d-h.a} +function kMc(a){var b,c,d,e,f,g,h,i,j,k,l,m;b=DMc(a);for(k=(h=(new Pib(b)).a.vc().Kc(),new Vib(h));k.a.Ob();){j=(e=BD(k.a.Pb(),42),BD(e.cd(),10));l=0;m=0;l=j.d.d;m=j.o.b+j.d.a;a.d[j.p]=0;c=j;while((f=a.a[c.p])!=j){d=FMc(c,f);i=0;a.c==(YLc(),WLc)?(i=d.d.n.b+d.d.a.b-d.c.n.b-d.c.a.b):(i=d.c.n.b+d.c.a.b-d.d.n.b-d.d.a.b);g=Edb(a.d[c.p])+i;a.d[f.p]=g;l=$wnd.Math.max(l,f.d.d-g);m=$wnd.Math.max(m,g+f.o.b+f.d.a);c=f}c=j;do{a.d[c.p]=Edb(a.d[c.p])+l;c=a.a[c.p]}while(c!=j);a.b[j.p]=l+m}} +function LOb(a){var b,c,d,e,f,g,h,i,j,k,l,m;a.b=false;l=Pje;i=Qje;m=Pje;j=Qje;for(d=a.e.a.ec().Kc();d.Ob();){c=BD(d.Pb(),266);e=c.a;l=$wnd.Math.min(l,e.c);i=$wnd.Math.max(i,e.c+e.b);m=$wnd.Math.min(m,e.d);j=$wnd.Math.max(j,e.d+e.a);for(g=new olb(c.c);g.a<g.c.c.length;){f=BD(mlb(g),395);b=f.a;if(b.a){k=e.d+f.b.b;h=k+f.c;m=$wnd.Math.min(m,k);j=$wnd.Math.max(j,h)}else{k=e.c+f.b.a;h=k+f.c;l=$wnd.Math.min(l,k);i=$wnd.Math.max(i,h)}}}a.a=new f7c(i-l,j-m);a.c=new f7c(l+a.d.a,m+a.d.b)} +function xZc(a,b,c){var d,e,f,g,h,i,j,k,l;l=new Rkb;k=new x$c(0,c);f=0;s$c(k,new PZc(0,0,k,c));e=0;for(j=new Fyd(a);j.e!=j.i.gc();){i=BD(Dyd(j),33);d=BD(Ikb(k.a,k.a.c.length-1),187);h=e+i.g+(BD(Ikb(k.a,0),187).b.c.length==0?0:c);if(h>b){e=0;f+=k.b+c;l.c[l.c.length]=k;k=new x$c(f,c);d=new PZc(0,k.f,k,c);s$c(k,d);e=0}if(d.b.c.length==0||i.f>=d.o&&i.f<=d.f||d.a*0.5<=i.f&&d.a*1.5>=i.f){EZc(d,i)}else{g=new PZc(d.s+d.r+c,k.f,k,c);s$c(k,g);EZc(g,i)}e=i.i+i.g}l.c[l.c.length]=k;return l} +function OKd(a){var b,c,d,e,f,g,h,i;if(!a.a){a.o=null;i=new GNd(a);b=new KNd;c=KKd;h=c.a.zc(a,c);if(h==null){for(g=new Fyd(_Kd(a));g.e!=g.i.gc();){f=BD(Dyd(g),26);ytd(i,OKd(f))}c.a.Bc(a)!=null;c.a.gc()==0&&undefined}for(e=(!a.s&&(a.s=new cUd(t5,a,21,17)),new Fyd(a.s));e.e!=e.i.gc();){d=BD(Dyd(e),170);JD(d,322)&&wtd(b,BD(d,34))}vud(b);a.k=new PNd(a,(BD(qud(ZKd((NFd(),MFd).o),7),18),b.i),b.g);ytd(i,a.k);vud(i);a.a=new nNd((BD(qud(ZKd(MFd.o),4),18),i.i),i.g);$Kd(a).b&=-2}return a.a} +function vZc(a,b,c,d,e,f,g){var h,i,j,k,l,m;l=false;i=ZZc(c.q,b.f+b.b-c.q.f);m=e-(c.q.e+i-g);if(m<d.g){return false}j=f==a.c.length-1&&m>=(tCb(f,a.c.length),BD(a.c[f],200)).e;k=(h=MZc(d,m,false),h.a);if(k>b.b&&!j){return false}if(j||k<=b.b){if(j&&k>b.b){c.d=k;KZc(c,JZc(c,k))}else{$Zc(c.q,i);c.c=true}KZc(d,e-(c.s+c.r));OZc(d,c.q.e+c.q.d,b.f);s$c(b,d);if(a.c.length>f){v$c((tCb(f,a.c.length),BD(a.c[f],200)),d);(tCb(f,a.c.length),BD(a.c[f],200)).a.c.length==0&&Kkb(a,f)}l=true}return l} +function C2d(a,b,c,d){var e,f,g,h,i,j,k;k=S6d(a.e.Tg(),b);e=0;f=BD(a.g,119);i=null;Q6d();if(BD(b,66).Oj()){for(h=0;h<a.i;++h){g=f[h];if(k.rl(g.ak())){if(pb(g,c)){i=g;break}++e}}}else if(c!=null){for(h=0;h<a.i;++h){g=f[h];if(k.rl(g.ak())){if(pb(c,g.dd())){i=g;break}++e}}}else{for(h=0;h<a.i;++h){g=f[h];if(k.rl(g.ak())){if(g.dd()==null){i=g;break}++e}}}if(i){if(oid(a.e)){j=b.$j()?new O7d(a.e,4,b,c,null,e,true):H2d(a,b.Kj()?2:1,b,c,b.zj(),-1,true);d?d.Ei(j):(d=j)}d=B2d(a,i,d)}return d} +function kYc(a,b,c,d,e,f,g){var h,i,j,k,l,m,n,o,p;o=0;p=0;i=e.c;h=e.b;k=c.f;n=c.g;switch(b.g){case 0:o=d.i+d.g+g;a.c?(p=tYc(o,f,d,g)):(p=d.j);m=$wnd.Math.max(i,o+n);j=$wnd.Math.max(h,p+k);break;case 1:p=d.j+d.f+g;a.c?(o=sYc(p,f,d,g)):(o=d.i);m=$wnd.Math.max(i,o+n);j=$wnd.Math.max(h,p+k);break;case 2:o=i+g;p=0;m=i+g+n;j=$wnd.Math.max(h,k);break;case 3:o=0;p=h+g;m=$wnd.Math.max(i,n);j=h+g+k;break;default:throw vbb(new Wdb('IllegalPlacementOption.'));}l=new e$c(a.a,m,j,b,o,p);return l} +function R2b(a){var b,c,d,e,f,g,h,i,j,k,l,m;h=a.d;l=BD(vNb(a,(wtc(),vtc)),15);b=BD(vNb(a,tsc),15);if(!l&&!b){return}f=Edb(ED(pBc(a,(Nyc(),iyc))));g=Edb(ED(pBc(a,jyc)));m=0;if(l){j=0;for(e=l.Kc();e.Ob();){d=BD(e.Pb(),10);j=$wnd.Math.max(j,d.o.b);m+=d.o.a}m+=f*(l.gc()-1);h.d+=j+g}c=0;if(b){j=0;for(e=b.Kc();e.Ob();){d=BD(e.Pb(),10);j=$wnd.Math.max(j,d.o.b);c+=d.o.a}c+=f*(b.gc()-1);h.a+=j+g}i=$wnd.Math.max(m,c);if(i>a.o.a){k=(i-a.o.a)/2;h.b=$wnd.Math.max(h.b,k);h.c=$wnd.Math.max(h.c,k)}} +function rvd(a){var b,c,d,e,f,g,h,i;f=new b2c;Z1c(f,(Y1c(),V1c));for(d=(e=$B(a,KC(ZI,nie,2,0,6,1)),new vib(new amb((new mC(a,e)).b)));d.b<d.d.gc();){c=(sCb(d.b<d.d.gc()),GD(d.d.Xb(d.c=d.b++)));g=k4c(lvd,c);if(g){b=aC(a,c);b.je()?(h=b.je().a):b.ge()?(h=''+b.ge().a):b.he()?(h=''+b.he().a):(h=b.Ib());i=o5c(g,h);if(i!=null){(uqb(g.j,(N5c(),K5c))||uqb(g.j,L5c))&&xNb(_1c(f,E2),g,i);uqb(g.j,I5c)&&xNb(_1c(f,B2),g,i);uqb(g.j,M5c)&&xNb(_1c(f,F2),g,i);uqb(g.j,J5c)&&xNb(_1c(f,D2),g,i)}}}return f} +function J2d(a,b,c,d){var e,f,g,h,i,j;i=S6d(a.e.Tg(),b);f=BD(a.g,119);if(T6d(a.e,b)){e=0;for(h=0;h<a.i;++h){g=f[h];if(i.rl(g.ak())){if(e==c){Q6d();if(BD(b,66).Oj()){return g}else{j=g.dd();j!=null&&d&&JD(b,99)&&(BD(b,18).Bb&Tje)!=0&&(j=b3d(a,b,h,e,j));return j}}++e}}throw vbb(new qcb(gve+c+mue+e))}else{e=0;for(h=0;h<a.i;++h){g=f[h];if(i.rl(g.ak())){Q6d();if(BD(b,66).Oj()){return g}else{j=g.dd();j!=null&&d&&JD(b,99)&&(BD(b,18).Bb&Tje)!=0&&(j=b3d(a,b,h,e,j));return j}}++e}return b.zj()}} +function K2d(a,b,c){var d,e,f,g,h,i,j,k;e=BD(a.g,119);if(T6d(a.e,b)){return Q6d(),BD(b,66).Oj()?new R7d(b,a):new f7d(b,a)}else{j=S6d(a.e.Tg(),b);d=0;for(h=0;h<a.i;++h){f=e[h];g=f.ak();if(j.rl(g)){Q6d();if(BD(b,66).Oj()){return f}else if(g==(m8d(),k8d)||g==h8d){i=new Wfb(fcb(f.dd()));while(++h<a.i){f=e[h];g=f.ak();(g==k8d||g==h8d)&&Qfb(i,fcb(f.dd()))}return j6d(BD(b.Yj(),148),i.a)}else{k=f.dd();k!=null&&c&&JD(b,99)&&(BD(b,18).Bb&Tje)!=0&&(k=b3d(a,b,h,d,k));return k}}++d}return b.zj()}} +function MZc(a,b,c){var d,e,f,g,h,i,j,k,l,m;f=0;g=a.t;e=0;d=0;i=0;m=0;l=0;if(c){a.n.c=KC(SI,Uhe,1,0,5,1);Ekb(a.n,new VZc(a.s,a.t,a.i))}h=0;for(k=new olb(a.b);k.a<k.c.c.length;){j=BD(mlb(k),33);if(f+j.g+(h>0?a.i:0)>b&&i>0){f=0;g+=i+a.i;e=$wnd.Math.max(e,m);d+=i+a.i;i=0;m=0;if(c){++l;Ekb(a.n,new VZc(a.s,g,a.i))}h=0}m+=j.g+(h>0?a.i:0);i=$wnd.Math.max(i,j.f);c&&QZc(BD(Ikb(a.n,l),211),j);f+=j.g+(h>0?a.i:0);++h}e=$wnd.Math.max(e,m);d+=i;if(c){a.r=e;a.d=d;u$c(a.j)}return new J6c(a.s,a.t,e,d)} +function $fb(a,b,c,d,e){Zfb();var f,g,h,i,j,k,l,m,n;vCb(a,'src');vCb(c,'dest');m=rb(a);i=rb(c);rCb((m.i&4)!=0,'srcType is not an array');rCb((i.i&4)!=0,'destType is not an array');l=m.c;g=i.c;rCb((l.i&1)!=0?l==g:(g.i&1)==0,"Array types don't match");n=a.length;j=c.length;if(b<0||d<0||e<0||b+e>n||d+e>j){throw vbb(new pcb)}if((l.i&1)==0&&m!=i){k=CD(a);f=CD(c);if(PD(a)===PD(c)&&b<d){b+=e;for(h=d+e;h-->d;){NC(f,h,k[--b])}}else{for(h=d+e;d<h;){NC(f,d++,k[b++])}}}else e>0&&$Bb(a,b,c,d,e,true)} +function phb(){phb=ccb;nhb=OC(GC(WD,1),oje,25,15,[Rie,1162261467,Iie,1220703125,362797056,1977326743,Iie,387420489,Jje,214358881,429981696,815730721,1475789056,170859375,268435456,410338673,612220032,893871739,1280000000,1801088541,113379904,148035889,191102976,244140625,308915776,387420489,481890304,594823321,729000000,887503681,Iie,1291467969,1544804416,1838265625,60466176]);ohb=OC(GC(WD,1),oje,25,15,[-1,-1,31,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5])} +function soc(a){var b,c,d,e,f,g,h,i;for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),29);for(g=new olb(Mu(d.a));g.a<g.c.c.length;){f=BD(mlb(g),10);if(ioc(f)){c=BD(vNb(f,(wtc(),usc)),305);if(!c.g&&!!c.d){b=c;i=c.d;while(i){roc(i.i,i.k,false,true);zoc(b.a);zoc(i.i);zoc(i.k);zoc(i.b);RZb(i.c,b.c.d);RZb(b.c,null);$_b(b.a,null);$_b(i.i,null);$_b(i.k,null);$_b(i.b,null);h=new goc(b.i,i.a,b.e,i.j,i.f);h.k=b.k;h.n=b.n;h.b=b.b;h.c=i.c;h.g=b.g;h.d=i.d;yNb(b.i,usc,h);yNb(i.a,usc,h);i=i.d;b=h}}}}}} +function Xfe(a,b){var c,d,e,f,g;g=BD(b,136);Yfe(a);Yfe(g);if(g.b==null)return;a.c=true;if(a.b==null){a.b=KC(WD,oje,25,g.b.length,15,1);$fb(g.b,0,a.b,0,g.b.length);return}f=KC(WD,oje,25,a.b.length+g.b.length,15,1);for(c=0,d=0,e=0;c<a.b.length||d<g.b.length;){if(c>=a.b.length){f[e++]=g.b[d++];f[e++]=g.b[d++]}else if(d>=g.b.length){f[e++]=a.b[c++];f[e++]=a.b[c++]}else if(g.b[d]<a.b[c]||g.b[d]===a.b[c]&&g.b[d+1]<a.b[c+1]){f[e++]=g.b[d++];f[e++]=g.b[d++]}else{f[e++]=a.b[c++];f[e++]=a.b[c++]}}a.b=f} +function S6b(a,b){var c,d,e,f,g,h,i,j,k,l;c=Ccb(DD(vNb(a,(wtc(),Usc))));h=Ccb(DD(vNb(b,Usc)));d=BD(vNb(a,Vsc),11);i=BD(vNb(b,Vsc),11);e=BD(vNb(a,Wsc),11);j=BD(vNb(b,Wsc),11);k=!!d&&d==i;l=!!e&&e==j;if(!c&&!h){return new Z6b(BD(mlb(new olb(a.j)),11).p==BD(mlb(new olb(b.j)),11).p,k,l)}f=(!Ccb(DD(vNb(a,Usc)))||Ccb(DD(vNb(a,Tsc))))&&(!Ccb(DD(vNb(b,Usc)))||Ccb(DD(vNb(b,Tsc))));g=(!Ccb(DD(vNb(a,Usc)))||!Ccb(DD(vNb(a,Tsc))))&&(!Ccb(DD(vNb(b,Usc)))||!Ccb(DD(vNb(b,Tsc))));return new Z6b(k&&f||l&&g,k,l)} +function HZc(a){var b,c,d,e,f,g,h,i;d=0;c=0;i=new Psb;b=0;for(h=new olb(a.n);h.a<h.c.c.length;){g=BD(mlb(h),211);if(g.c.c.length==0){Gsb(i,g,i.c.b,i.c)}else{d=$wnd.Math.max(d,g.d);c+=g.a+(b>0?a.i:0)}++b}Ce(a.n,i);a.d=c;a.r=d;a.g=0;a.f=0;a.e=0;a.o=Pje;a.p=Pje;for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),33);a.p=$wnd.Math.min(a.p,e.g);a.g=$wnd.Math.max(a.g,e.g);a.f=$wnd.Math.max(a.f,e.f);a.o=$wnd.Math.min(a.o,e.f);a.e+=e.f+a.i}a.a=a.e/a.b.c.length-a.i*((a.b.c.length-1)/a.b.c.length);u$c(a.j)} +function Sld(a){var b,c,d,e;if((a.Db&64)!=0)return Mkd(a);b=new Wfb(_se);d=a.k;if(!d){!a.n&&(a.n=new cUd(D2,a,1,7));if(a.n.i>0){e=(!a.n&&(a.n=new cUd(D2,a,1,7)),BD(qud(a.n,0),137)).a;!e||Qfb(Qfb((b.a+=' "',b),e),'"')}}else{Qfb(Qfb((b.a+=' "',b),d),'"')}c=(!a.b&&(a.b=new y5d(z2,a,4,7)),!(a.b.i<=1&&(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c.i<=1)));c?(b.a+=' [',b):(b.a+=' ',b);Qfb(b,Eb(new Gb,new Fyd(a.b)));c&&(b.a+=']',b);b.a+=gne;c&&(b.a+='[',b);Qfb(b,Eb(new Gb,new Fyd(a.c)));c&&(b.a+=']',b);return b.a} +function TQd(a,b){var c,d,e,f,g,h,i;if(a.a){h=a.a.ne();i=null;if(h!=null){b.a+=''+h}else{g=a.a.Dj();if(g!=null){f=hfb(g,wfb(91));if(f!=-1){i=g.substr(f);b.a+=''+qfb(g==null?Xhe:(uCb(g),g),0,f)}else{b.a+=''+g}}}if(!!a.d&&a.d.i!=0){e=true;b.a+='<';for(d=new Fyd(a.d);d.e!=d.i.gc();){c=BD(Dyd(d),87);e?(e=false):(b.a+=She,b);TQd(c,b)}b.a+='>'}i!=null&&(b.a+=''+i,b)}else if(a.e){h=a.e.zb;h!=null&&(b.a+=''+h,b)}else{b.a+='?';if(a.b){b.a+=' super ';TQd(a.b,b)}else{if(a.f){b.a+=' extends ';TQd(a.f,b)}}}} +function Z9b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;v=a.c;w=b.c;c=Jkb(v.a,a,0);d=Jkb(w.a,b,0);t=BD(W_b(a,(KAc(),HAc)).Kc().Pb(),11);C=BD(W_b(a,IAc).Kc().Pb(),11);u=BD(W_b(b,HAc).Kc().Pb(),11);D=BD(W_b(b,IAc).Kc().Pb(),11);r=k_b(t.e);A=k_b(C.g);s=k_b(u.e);B=k_b(D.g);Z_b(a,d,w);for(g=s,k=0,o=g.length;k<o;++k){e=g[k];RZb(e,t)}for(h=B,l=0,p=h.length;l<p;++l){e=h[l];QZb(e,C)}Z_b(b,c,v);for(i=r,m=0,q=i.length;m<q;++m){e=i[m];RZb(e,u)}for(f=A,j=0,n=f.length;j<n;++j){e=f[j];QZb(e,D)}} +function $$b(a,b,c,d){var e,f,g,h,i,j,k;f=a_b(d);h=Ccb(DD(vNb(d,(Nyc(),uxc))));if((h||Ccb(DD(vNb(a,exc))))&&!fcd(BD(vNb(a,Vxc),98))){e=Zcd(f);i=i_b(a,c,c==(KAc(),IAc)?e:Wcd(e))}else{i=new H0b;F0b(i,a);if(b){k=i.n;k.a=b.a-a.n.a;k.b=b.b-a.n.b;Q6c(k,0,0,a.o.a,a.o.b);G0b(i,W$b(i,f))}else{e=Zcd(f);G0b(i,c==(KAc(),IAc)?e:Wcd(e))}g=BD(vNb(d,(wtc(),Ksc)),21);j=i.j;switch(f.g){case 2:case 1:(j==(Ucd(),Acd)||j==Rcd)&&g.Fc((Orc(),Lrc));break;case 4:case 3:(j==(Ucd(),zcd)||j==Tcd)&&g.Fc((Orc(),Lrc));}}return i} +function pPc(a,b,c){var d,e,f,g,h,i,j,k;if($wnd.Math.abs(b.s-b.c)<qme||$wnd.Math.abs(c.s-c.c)<qme){return 0}d=oPc(a,b.j,c.e);e=oPc(a,c.j,b.e);f=d==-1||e==-1;g=0;if(f){if(d==-1){new DOc((HOc(),FOc),c,b,1);++g}if(e==-1){new DOc((HOc(),FOc),b,c,1);++g}}else{h=vPc(b.j,c.s,c.c);h+=vPc(c.e,b.s,b.c);i=vPc(c.j,b.s,b.c);i+=vPc(b.e,c.s,c.c);j=d+16*h;k=e+16*i;if(j<k){new DOc((HOc(),GOc),b,c,k-j)}else if(j>k){new DOc((HOc(),GOc),c,b,j-k)}else if(j>0&&k>0){new DOc((HOc(),GOc),b,c,0);new DOc(GOc,c,b,0)}}return g} +function TUb(a,b){var c,d,e,f,g,h;for(g=new nib((new eib(a.f.b)).a);g.b;){f=lib(g);e=BD(f.cd(),594);if(b==1){if(e.gf()!=(ead(),dad)&&e.gf()!=_9c){continue}}else{if(e.gf()!=(ead(),aad)&&e.gf()!=bad){continue}}d=BD(BD(f.dd(),46).b,81);h=BD(BD(f.dd(),46).a,189);c=h.c;switch(e.gf().g){case 2:d.g.c=a.e.a;d.g.b=$wnd.Math.max(1,d.g.b+c);break;case 1:d.g.c=d.g.c+c;d.g.b=$wnd.Math.max(1,d.g.b-c);break;case 4:d.g.d=a.e.b;d.g.a=$wnd.Math.max(1,d.g.a+c);break;case 3:d.g.d=d.g.d+c;d.g.a=$wnd.Math.max(1,d.g.a-c);}}} +function nJc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;h=KC(WD,oje,25,b.b.c.length,15,1);j=KC(NQ,Kie,267,b.b.c.length,0,1);i=KC(OQ,kne,10,b.b.c.length,0,1);for(l=a.a,m=0,n=l.length;m<n;++m){k=l[m];p=0;for(g=new olb(k.e);g.a<g.c.c.length;){e=BD(mlb(g),10);d=G1b(e.c);++h[d];o=Edb(ED(vNb(b,(Nyc(),lyc))));h[d]>0&&!!i[d]&&(o=jBc(a.b,i[d],e));p=$wnd.Math.max(p,e.c.c.b+o)}for(f=new olb(k.e);f.a<f.c.c.length;){e=BD(mlb(f),10);e.n.b=p+e.d.d;c=e.c;c.c.b=p+e.d.d+e.o.b+e.d.a;j[Jkb(c.b.b,c,0)]=e.k;i[Jkb(c.b.b,c,0)]=e}}} +function LXc(a,b){var c,d,e,f,g,h,i,j,k,l,m;for(d=new Sr(ur(_sd(b).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),79);if(!JD(qud((!c.b&&(c.b=new y5d(z2,c,4,7)),c.b),0),186)){i=atd(BD(qud((!c.c&&(c.c=new y5d(z2,c,5,8)),c.c),0),82));if(!Pld(c)){g=b.i+b.g/2;h=b.j+b.f/2;k=i.i+i.g/2;l=i.j+i.f/2;m=new d7c;m.a=k-g;m.b=l-h;f=new f7c(m.a,m.b);l6c(f,b.g,b.f);m.a-=f.a;m.b-=f.b;g=k-m.a;h=l-m.b;j=new f7c(m.a,m.b);l6c(j,i.g,i.f);m.a-=j.a;m.b-=j.b;k=g+m.a;l=h+m.b;e=itd(c,true,true);omd(e,g);pmd(e,h);hmd(e,k);imd(e,l);LXc(a,i)}}}} +function e0c(a){r4c(a,new E3c(P3c(M3c(O3c(N3c(new R3c,Pre),'ELK SPOrE Compaction'),'ShrinkTree is a compaction algorithm that maintains the topology of a layout. The relocation of diagram elements is based on contracting a spanning tree.'),new h0c)));p4c(a,Pre,Qre,Ksd(c0c));p4c(a,Pre,Rre,Ksd(__c));p4c(a,Pre,Sre,Ksd($_c));p4c(a,Pre,Tre,Ksd(Y_c));p4c(a,Pre,Ure,Ksd(Z_c));p4c(a,Pre,ame,X_c);p4c(a,Pre,wme,8);p4c(a,Pre,Vre,Ksd(b0c));p4c(a,Pre,Wre,Ksd(T_c));p4c(a,Pre,Xre,Ksd(U_c));p4c(a,Pre,Zpe,(Bcb(),false))} +function JLc(a,b){var c,d,e,f,g,h,i,j,k,l;Odd(b,'Simple node placement',1);l=BD(vNb(a,(wtc(),otc)),304);h=0;for(f=new olb(a.b);f.a<f.c.c.length;){d=BD(mlb(f),29);g=d.c;g.b=0;c=null;for(j=new olb(d.a);j.a<j.c.c.length;){i=BD(mlb(j),10);!!c&&(g.b+=hBc(i,c,l.c));g.b+=i.d.d+i.o.b+i.d.a;c=i}h=$wnd.Math.max(h,g.b)}for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),29);g=d.c;k=(h-g.b)/2;c=null;for(j=new olb(d.a);j.a<j.c.c.length;){i=BD(mlb(j),10);!!c&&(k+=hBc(i,c,l.c));k+=i.d.d;i.n.b=k;k+=i.o.b+i.d.a;c=i}}Qdd(b)} +function s2d(a,b,c,d){var e,f,g,h,i,j,k,l;if(d.gc()==0){return false}i=(Q6d(),BD(b,66).Oj());g=i?d:new zud(d.gc());if(T6d(a.e,b)){if(b.hi()){for(k=d.Kc();k.Ob();){j=k.Pb();if(!F2d(a,b,j,JD(b,99)&&(BD(b,18).Bb&Tje)!=0)){f=R6d(b,j);g.Fc(f)}}}else if(!i){for(k=d.Kc();k.Ob();){j=k.Pb();f=R6d(b,j);g.Fc(f)}}}else{l=S6d(a.e.Tg(),b);e=BD(a.g,119);for(h=0;h<a.i;++h){f=e[h];if(l.rl(f.ak())){throw vbb(new Wdb(Hwe))}}if(d.gc()>1){throw vbb(new Wdb(Hwe))}if(!i){f=R6d(b,d.Kc().Pb());g.Fc(f)}}return xtd(a,I2d(a,b,c),g)} +function Pmc(a,b){var c,d,e,f;Jmc(b.b.j);MAb(NAb(new YAb(null,new Kub(b.d,16)),new $mc),new anc);for(f=new olb(b.d);f.a<f.c.c.length;){e=BD(mlb(f),101);switch(e.e.g){case 0:c=BD(Ikb(e.j,0),113).d.j;mjc(e,BD(Btb(RAb(BD(Qc(e.k,c),15).Oc(),Hmc)),113));njc(e,BD(Btb(QAb(BD(Qc(e.k,c),15).Oc(),Hmc)),113));break;case 1:d=Bkc(e);mjc(e,BD(Btb(RAb(BD(Qc(e.k,d[0]),15).Oc(),Hmc)),113));njc(e,BD(Btb(QAb(BD(Qc(e.k,d[1]),15).Oc(),Hmc)),113));break;case 2:Rmc(a,e);break;case 3:Qmc(e);break;case 4:Omc(a,e);}Mmc(e)}a.a=null} +function $Mc(a,b,c){var d,e,f,g,h,i,j,k;d=a.a.o==(eMc(),dMc)?Pje:Qje;h=_Mc(a,new ZMc(b,c));if(!h.a&&h.c){Dsb(a.d,h);return d}else if(h.a){e=h.a.c;i=h.a.d;if(c){j=a.a.c==(YLc(),XLc)?i:e;f=a.a.c==XLc?e:i;g=a.a.g[f.i.p];k=Edb(a.a.p[g.p])+Edb(a.a.d[f.i.p])+f.n.b+f.a.b-Edb(a.a.d[j.i.p])-j.n.b-j.a.b}else{j=a.a.c==(YLc(),WLc)?i:e;f=a.a.c==WLc?e:i;k=Edb(a.a.p[a.a.g[f.i.p].p])+Edb(a.a.d[f.i.p])+f.n.b+f.a.b-Edb(a.a.d[j.i.p])-j.n.b-j.a.b}a.a.n[a.a.g[e.i.p].p]=(Bcb(),true);a.a.n[a.a.g[i.i.p].p]=true;return k}return d} +function f3d(a,b,c){var d,e,f,g,h,i,j,k;if(T6d(a.e,b)){i=(Q6d(),BD(b,66).Oj()?new R7d(b,a):new f7d(b,a));D2d(i.c,i.b);b7d(i,BD(c,14))}else{k=S6d(a.e.Tg(),b);d=BD(a.g,119);for(g=0;g<a.i;++g){e=d[g];f=e.ak();if(k.rl(f)){if(f==(m8d(),k8d)||f==h8d){j=m3d(a,b,c);h=g;j?Xxd(a,g):++g;while(g<a.i){e=d[g];f=e.ak();f==k8d||f==h8d?Xxd(a,g):++g}j||BD(Gtd(a,h,R6d(b,c)),72)}else m3d(a,b,c)?Xxd(a,g):BD(Gtd(a,g,(Q6d(),BD(b,66).Oj()?BD(c,72):R6d(b,c))),72);return}}m3d(a,b,c)||wtd(a,(Q6d(),BD(b,66).Oj()?BD(c,72):R6d(b,c)))}} +function IMb(a,b,c){var d,e,f,g,h,i,j,k;if(!pb(c,a.b)){a.b=c;f=new LMb;g=BD(GAb(NAb(new YAb(null,new Kub(c.f,16)),f),Ayb(new hzb,new jzb,new Gzb,new Izb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Eyb),Dyb]))),21);a.e=true;a.f=true;a.c=true;a.d=true;e=g.Hc((RMb(),OMb));d=g.Hc(PMb);e&&!d&&(a.f=false);!e&&d&&(a.d=false);e=g.Hc(NMb);d=g.Hc(QMb);e&&!d&&(a.c=false);!e&&d&&(a.e=false)}k=BD(a.a.Ce(b,c),46);i=BD(k.a,19).a;j=BD(k.b,19).a;h=false;i<0?a.c||(h=true):a.e||(h=true);j<0?a.d||(h=true):a.f||(h=true);return h?IMb(a,k,c):k} +function oKb(a){var b,c,d,e;e=a.o;$Jb();if(a.A.dc()||pb(a.A,ZJb)){b=e.b}else{b=fIb(a.f);if(a.A.Hc((tdd(),qdd))&&!a.B.Hc((Idd(),Edd))){b=$wnd.Math.max(b,fIb(BD(Mpb(a.p,(Ucd(),zcd)),244)));b=$wnd.Math.max(b,fIb(BD(Mpb(a.p,Tcd),244)))}c=aKb(a);!!c&&(b=$wnd.Math.max(b,c.b));if(a.A.Hc(rdd)){if(a.q==(dcd(),_bd)||a.q==$bd){b=$wnd.Math.max(b,_Gb(BD(Mpb(a.b,(Ucd(),zcd)),124)));b=$wnd.Math.max(b,_Gb(BD(Mpb(a.b,Tcd),124)))}}}Ccb(DD(a.e.yf().We((Y9c(),$8c))))?(e.b=$wnd.Math.max(e.b,b)):(e.b=b);d=a.f.i;d.d=0;d.a=b;iIb(a.f)} +function $Ic(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;for(l=0;l<b.length;l++){for(h=a.Kc();h.Ob();){f=BD(h.Pb(),225);f.Of(l,b)}for(m=0;m<b[l].length;m++){for(i=a.Kc();i.Ob();){f=BD(i.Pb(),225);f.Pf(l,m,b)}p=b[l][m].j;for(n=0;n<p.c.length;n++){for(j=a.Kc();j.Ob();){f=BD(j.Pb(),225);f.Qf(l,m,n,b)}o=(tCb(n,p.c.length),BD(p.c[n],11));c=0;for(e=new b1b(o.b);llb(e.a)||llb(e.b);){d=BD(llb(e.a)?mlb(e.a):mlb(e.b),17);for(k=a.Kc();k.Ob();){f=BD(k.Pb(),225);f.Nf(l,m,n,c++,d,b)}}}}}for(g=a.Kc();g.Ob();){f=BD(g.Pb(),225);f.Mf()}} +function J4b(a,b){var c,d,e,f,g,h,i;a.b=Edb(ED(vNb(b,(Nyc(),myc))));a.c=Edb(ED(vNb(b,pyc)));a.d=BD(vNb(b,Xwc),336);a.a=BD(vNb(b,swc),275);H4b(b);h=BD(GAb(JAb(JAb(LAb(LAb(new YAb(null,new Kub(b.b,16)),new N4b),new P4b),new R4b),new T4b),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);for(e=h.Kc();e.Ob();){c=BD(e.Pb(),17);g=BD(vNb(c,(wtc(),rtc)),15);g.Jc(new V4b(a));yNb(c,rtc,null)}for(d=h.Kc();d.Ob();){c=BD(d.Pb(),17);i=BD(vNb(c,(wtc(),stc)),17);f=BD(vNb(c,ptc),15);B4b(a,f,i);yNb(c,ptc,null)}} +function uZd(a){a.b=null;a.a=null;a.o=null;a.q=null;a.v=null;a.w=null;a.B=null;a.p=null;a.Q=null;a.R=null;a.S=null;a.T=null;a.U=null;a.V=null;a.W=null;a.bb=null;a.eb=null;a.ab=null;a.H=null;a.db=null;a.c=null;a.d=null;a.f=null;a.n=null;a.r=null;a.s=null;a.u=null;a.G=null;a.J=null;a.e=null;a.j=null;a.i=null;a.g=null;a.k=null;a.t=null;a.F=null;a.I=null;a.L=null;a.M=null;a.O=null;a.P=null;a.$=null;a.N=null;a.Z=null;a.cb=null;a.K=null;a.D=null;a.A=null;a.C=null;a._=null;a.fb=null;a.X=null;a.Y=null;a.gb=false;a.hb=false} +function bKc(a){var b,c,d,e,f,g,h,i,j;if(a.k!=(j0b(),h0b)){return false}if(a.j.c.length<=1){return false}f=BD(vNb(a,(Nyc(),Vxc)),98);if(f==(dcd(),$bd)){return false}e=(Izc(),(!a.q?(mmb(),mmb(),kmb):a.q)._b(Cxc)?(d=BD(vNb(a,Cxc),197)):(d=BD(vNb(Q_b(a),Dxc),197)),d);if(e==Gzc){return false}if(!(e==Fzc||e==Ezc)){g=Edb(ED(pBc(a,zyc)));b=BD(vNb(a,yyc),142);!b&&(b=new J_b(g,g,g,g));j=V_b(a,(Ucd(),Tcd));i=b.d+b.a+(j.gc()-1)*g;if(i>a.o.b){return false}c=V_b(a,zcd);h=b.d+b.a+(c.gc()-1)*g;if(h>a.o.b){return false}}return true} +function thb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;g=a.e;i=b.e;if(g==0){return b}if(i==0){return a}f=a.d;h=b.d;if(f+h==2){c=xbb(a.a[0],Yje);d=xbb(b.a[0],Yje);if(g==i){k=wbb(c,d);o=Tbb(k);n=Tbb(Pbb(k,32));return n==0?new Ugb(g,o):new Vgb(g,2,OC(GC(WD,1),oje,25,15,[o,n]))}return ghb(g<0?Qbb(d,c):Qbb(c,d))}else if(g==i){m=g;l=f>=h?uhb(a.a,f,b.a,h):uhb(b.a,h,a.a,f)}else{e=f!=h?f>h?1:-1:whb(a.a,b.a,f);if(e==0){return Hgb(),Ggb}if(e==1){m=g;l=zhb(a.a,f,b.a,h)}else{m=i;l=zhb(b.a,h,a.a,f)}}j=new Vgb(m,l.length,l);Jgb(j);return j} +function oZb(a,b,c,d,e,f,g){var h,i,j,k,l,m,n;l=Ccb(DD(vNb(b,(Nyc(),vxc))));m=null;f==(KAc(),HAc)&&d.c.i==c?(m=d.c):f==IAc&&d.d.i==c&&(m=d.d);j=g;if(!j||!l||!!m){k=(Ucd(),Scd);m?(k=m.j):fcd(BD(vNb(c,Vxc),98))&&(k=f==HAc?Tcd:zcd);i=lZb(a,b,c,f,k,d);h=kZb((Q_b(c),d));if(f==HAc){QZb(h,BD(Ikb(i.j,0),11));RZb(h,e)}else{QZb(h,e);RZb(h,BD(Ikb(i.j,0),11))}j=new yZb(d,h,i,BD(vNb(i,(wtc(),$sc)),11),f,!m)}else{Ekb(j.e,d);n=$wnd.Math.max(Edb(ED(vNb(j.d,Zwc))),Edb(ED(vNb(d,Zwc))));yNb(j.d,Zwc,n)}Rc(a.a,d,new BZb(j.d,b,f));return j} +function V1d(a,b){var c,d,e,f,g,h,i,j,k,l;k=null;!!a.d&&(k=BD(Phb(a.d,b),138));if(!k){f=a.a.Mh();l=f.i;if(!a.d||Vhb(a.d)!=l){i=new Lqb;!!a.d&&Ld(i,a.d);j=i.f.c+i.g.c;for(h=j;h<l;++h){d=BD(qud(f,h),138);e=o1d(a.e,d).ne();c=BD(e==null?jrb(i.f,null,d):Drb(i.g,e,d),138);!!c&&c!=d&&(e==null?jrb(i.f,null,c):Drb(i.g,e,c))}if(i.f.c+i.g.c!=l){for(g=0;g<j;++g){d=BD(qud(f,g),138);e=o1d(a.e,d).ne();c=BD(e==null?jrb(i.f,null,d):Drb(i.g,e,d),138);!!c&&c!=d&&(e==null?jrb(i.f,null,c):Drb(i.g,e,c))}}a.d=i}k=BD(Phb(a.d,b),138)}return k} +function lZb(a,b,c,d,e,f){var g,h,i,j,k,l;g=null;j=d==(KAc(),HAc)?f.c:f.d;i=a_b(b);if(j.i==c){g=BD(Ohb(a.b,j),10);if(!g){g=Z$b(j,BD(vNb(c,(Nyc(),Vxc)),98),e,hZb(j),null,j.n,j.o,i,b);yNb(g,(wtc(),$sc),j);Rhb(a.b,j,g)}}else{g=Z$b((k=new zNb,l=Edb(ED(vNb(b,(Nyc(),lyc))))/2,xNb(k,Uxc,l),k),BD(vNb(c,Vxc),98),e,d==HAc?-1:1,null,new d7c,new f7c(0,0),i,b);h=mZb(g,c,d);yNb(g,(wtc(),$sc),h);Rhb(a.b,h,g)}BD(vNb(b,(wtc(),Ksc)),21).Fc((Orc(),Hrc));fcd(BD(vNb(b,(Nyc(),Vxc)),98))?yNb(b,Vxc,(dcd(),acd)):yNb(b,Vxc,(dcd(),bcd));return g} +function vNc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;Odd(b,'Orthogonal edge routing',1);j=Edb(ED(vNb(a,(Nyc(),wyc))));c=Edb(ED(vNb(a,myc)));d=Edb(ED(vNb(a,pyc)));m=new tPc(0,c);q=0;g=new Bib(a.b,0);h=null;k=null;i=null;l=null;do{k=g.b<g.d.gc()?(sCb(g.b<g.d.gc()),BD(g.d.Xb(g.c=g.b++),29)):null;l=!k?null:k.a;if(h){h_b(h,q);q+=h.c.a}p=!h?q:q+d;o=sPc(m,a,i,l,p);e=!h||Kq(i,(FNc(),DNc));f=!k||Kq(l,(FNc(),DNc));if(o>0){n=(o-1)*c;!!h&&(n+=d);!!k&&(n+=d);n<j&&!e&&!f&&(n=j);q+=n}else !e&&!f&&(q+=j);h=k;i=l}while(k);a.f.a=q;Qdd(b)} +function IEd(){IEd=ccb;var a;HEd=new mFd;BEd=KC(ZI,nie,2,0,6,1);uEd=Mbb(ZEd(33,58),ZEd(1,26));vEd=Mbb(ZEd(97,122),ZEd(65,90));wEd=ZEd(48,57);sEd=Mbb(uEd,0);tEd=Mbb(vEd,wEd);xEd=Mbb(Mbb(0,ZEd(1,6)),ZEd(33,38));yEd=Mbb(Mbb(wEd,ZEd(65,70)),ZEd(97,102));EEd=Mbb(sEd,XEd("-_.!~*'()"));FEd=Mbb(tEd,$Ed("-_.!~*'()"));XEd(lve);$Ed(lve);Mbb(EEd,XEd(';:@&=+$,'));Mbb(FEd,$Ed(';:@&=+$,'));zEd=XEd(':/?#');AEd=$Ed(':/?#');CEd=XEd('/?#');DEd=$Ed('/?#');a=new Tqb;a.a.zc('jar',a);a.a.zc('zip',a);a.a.zc('archive',a);GEd=(mmb(),new zob(a))} +function yUc(a,b){var c,d,e,f,g,h,i,j,k,l;yNb(b,(mTc(),cTc),0);i=BD(vNb(b,aTc),86);if(b.d.b==0){if(i){k=Edb(ED(vNb(i,fTc)))+a.a+zUc(i,b);yNb(b,fTc,k)}else{yNb(b,fTc,0)}}else{for(d=(f=Jsb((new ZRc(b)).a.d,0),new aSc(f));Wsb(d.a);){c=BD(Xsb(d.a),188).c;yUc(a,c)}h=BD(pr((g=Jsb((new ZRc(b)).a.d,0),new aSc(g))),86);l=BD(or((e=Jsb((new ZRc(b)).a.d,0),new aSc(e))),86);j=(Edb(ED(vNb(l,fTc)))+Edb(ED(vNb(h,fTc))))/2;if(i){k=Edb(ED(vNb(i,fTc)))+a.a+zUc(i,b);yNb(b,fTc,k);yNb(b,cTc,Edb(ED(vNb(b,fTc)))-j);xUc(a,b)}else{yNb(b,fTc,j)}}} +function Dbc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;h=0;o=0;i=tlb(a.f,a.f.length);f=a.d;g=a.i;d=a.a;e=a.b;do{n=0;for(k=new olb(a.p);k.a<k.c.c.length;){j=BD(mlb(k),10);m=Cbc(a,j);c=true;(a.q==(kAc(),dAc)||a.q==gAc)&&(c=Ccb(DD(m.b)));if(BD(m.a,19).a<0&&c){++n;i=tlb(a.f,a.f.length);a.d=a.d+BD(m.a,19).a;o+=f-a.d;f=a.d+BD(m.a,19).a;g=a.i;d=Mu(a.a);e=Mu(a.b)}else{a.f=tlb(i,i.length);a.d=f;a.a=(Qb(d),d?new Tkb(d):Nu(new olb(d)));a.b=(Qb(e),e?new Tkb(e):Nu(new olb(e)));a.i=g}}++h;l=n!=0&&Ccb(DD(b.Kb(new vgd(meb(o),meb(h)))))}while(l)} +function lYc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C;g=a.f;m=b.f;h=g==(k$c(),f$c)||g==h$c;n=m==f$c||m==h$c;i=g==g$c||g==i$c;o=m==g$c||m==i$c;j=g==g$c||g==f$c;p=m==g$c||m==f$c;if(h&&n){return a.f==h$c?a:b}else if(i&&o){return a.f==i$c?a:b}else if(j&&p){if(g==g$c){l=a;k=b}else{l=b;k=a}f=(q=c.j+c.f,r=l.e+d.f,s=$wnd.Math.max(q,r),t=s-$wnd.Math.min(c.j,l.e),u=l.d+d.g-c.i,u*t);e=(v=c.i+c.g,w=k.d+d.g,A=$wnd.Math.max(v,w),B=A-$wnd.Math.min(c.i,k.d),C=k.e+d.f-c.j,B*C);return f<=e?a.f==g$c?a:b:a.f==f$c?a:b}return a} +function wGb(a){var b,c,d,e,f,g,h,i,j,k,l;k=a.e.a.c.length;for(g=new olb(a.e.a);g.a<g.c.c.length;){f=BD(mlb(g),121);f.j=false}a.i=KC(WD,oje,25,k,15,1);a.g=KC(WD,oje,25,k,15,1);a.n=new Rkb;e=0;l=new Rkb;for(i=new olb(a.e.a);i.a<i.c.c.length;){h=BD(mlb(i),121);h.d=e++;h.b.a.c.length==0&&Ekb(a.n,h);Gkb(l,h.g)}b=0;for(d=new olb(l);d.a<d.c.c.length;){c=BD(mlb(d),213);c.c=b++;c.f=false}j=l.c.length;if(a.b==null||a.b.length<j){a.b=KC(UD,Vje,25,j,15,1);a.c=KC(sbb,dle,25,j,16,1)}else{Blb(a.c)}a.d=l;a.p=new Asb(Cv(a.d.c.length));a.j=1} +function sTb(a,b){var c,d,e,f,g,h,i,j,k;if(b.e.c.length<=1){return}a.f=b;a.d=BD(vNb(a.f,(bTb(),SSb)),379);a.g=BD(vNb(a.f,WSb),19).a;a.e=Edb(ED(vNb(a.f,TSb)));a.c=Edb(ED(vNb(a.f,RSb)));it(a.b);for(e=new olb(a.f.c);e.a<e.c.c.length;){d=BD(mlb(e),282);ht(a.b,d.c,d,null);ht(a.b,d.d,d,null)}h=a.f.e.c.length;a.a=IC(UD,[nie,Vje],[104,25],15,[h,h],2);for(j=new olb(a.f.e);j.a<j.c.c.length;){i=BD(mlb(j),144);oTb(a,i,a.a[i.b])}a.i=IC(UD,[nie,Vje],[104,25],15,[h,h],2);for(f=0;f<h;++f){for(g=0;g<h;++g){c=a.a[f][g];k=1/(c*c);a.i[f][g]=k}}} +function Vfe(a){var b,c,d,e;if(a.b==null||a.b.length<=2)return;if(a.a)return;b=0;e=0;while(e<a.b.length){if(b!=e){a.b[b]=a.b[e++];a.b[b+1]=a.b[e++]}else e+=2;c=a.b[b+1];while(e<a.b.length){if(c+1<a.b[e])break;if(c+1==a.b[e]){a.b[b+1]=a.b[e+1];c=a.b[b+1];e+=2}else if(c>=a.b[e+1]){e+=2}else if(c<a.b[e+1]){a.b[b+1]=a.b[e+1];c=a.b[b+1];e+=2}else{throw vbb(new hz('Token#compactRanges(): Internel Error: ['+a.b[b]+','+a.b[b+1]+'] ['+a.b[e]+','+a.b[e+1]+']'))}}b+=2}if(b!=a.b.length){d=KC(WD,oje,25,b,15,1);$fb(a.b,0,d,0,b);a.b=d}a.a=true} +function pZb(a,b){var c,d,e,f,g,h,i;for(g=Ec(a.a).Kc();g.Ob();){f=BD(g.Pb(),17);if(f.b.c.length>0){d=new Tkb(BD(Qc(a.a,f),21));mmb();Okb(d,new EZb(b));e=new Bib(f.b,0);while(e.b<e.d.gc()){c=(sCb(e.b<e.d.gc()),BD(e.d.Xb(e.c=e.b++),70));h=-1;switch(BD(vNb(c,(Nyc(),Qwc)),272).g){case 1:h=d.c.length-1;break;case 0:h=nZb(d);break;case 2:h=0;}if(h!=-1){i=(tCb(h,d.c.length),BD(d.c[h],243));Ekb(i.b.b,c);BD(vNb(Q_b(i.b.c.i),(wtc(),Ksc)),21).Fc((Orc(),Grc));BD(vNb(Q_b(i.b.c.i),Ksc),21).Fc(Erc);uib(e);yNb(c,btc,f)}}}QZb(f,null);RZb(f,null)}} +function FLb(a,b){var c,d,e,f;c=new KLb;d=BD(GAb(NAb(new YAb(null,new Kub(a.f,16)),c),Ayb(new hzb,new jzb,new Gzb,new Izb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Eyb),Dyb]))),21);e=d.gc();e=e==2?1:0;e==1&&Bbb(Hbb(BD(GAb(JAb(d.Lc(),new MLb),Xyb(Aeb(0),new Czb)),162).a,2),0)&&(e=0);d=BD(GAb(NAb(new YAb(null,new Kub(b.f,16)),c),Ayb(new hzb,new jzb,new Gzb,new Izb,OC(GC(xL,1),Kie,132,0,[Eyb,Dyb]))),21);f=d.gc();f=f==2?1:0;f==1&&Bbb(Hbb(BD(GAb(JAb(d.Lc(),new OLb),Xyb(Aeb(0),new Czb)),162).a,2),0)&&(f=0);if(e<f){return -1}if(e==f){return 0}return 1} +function h6b(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;j=new Rkb;if(!wNb(a,(wtc(),Fsc))){return j}for(d=BD(vNb(a,Fsc),15).Kc();d.Ob();){b=BD(d.Pb(),10);g6b(b,a);j.c[j.c.length]=b}for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);for(h=new olb(e.a);h.a<h.c.c.length;){g=BD(mlb(h),10);if(g.k!=(j0b(),e0b)){continue}i=BD(vNb(g,Gsc),10);!!i&&(k=new H0b,F0b(k,g),l=BD(vNb(g,Hsc),61),G0b(k,l),m=BD(Ikb(i.j,0),11),n=new UZb,QZb(n,k),RZb(n,m),undefined)}}for(c=new olb(j);c.a<c.c.c.length;){b=BD(mlb(c),10);$_b(b,BD(Ikb(a.b,a.b.c.length-1),29))}return j} +function M1b(a){var b,c,d,e,f,g,h,i,j,k,l,m;b=mpd(a);f=Ccb(DD(hkd(b,(Nyc(),fxc))));k=0;e=0;for(j=new Fyd((!a.e&&(a.e=new y5d(B2,a,7,4)),a.e));j.e!=j.i.gc();){i=BD(Dyd(j),79);h=Qld(i);g=h&&f&&Ccb(DD(hkd(i,gxc)));m=atd(BD(qud((!i.c&&(i.c=new y5d(z2,i,5,8)),i.c),0),82));h&&g?++e:h&&!g?++k:Xod(m)==b||m==b?++e:++k}for(d=new Fyd((!a.d&&(a.d=new y5d(B2,a,8,5)),a.d));d.e!=d.i.gc();){c=BD(Dyd(d),79);h=Qld(c);g=h&&f&&Ccb(DD(hkd(c,gxc)));l=atd(BD(qud((!c.b&&(c.b=new y5d(z2,c,4,7)),c.b),0),82));h&&g?++k:h&&!g?++e:Xod(l)==b||l==b?++k:++e}return k-e} +function ubc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;Odd(b,'Edge splitting',1);if(a.b.c.length<=2){Qdd(b);return}f=new Bib(a.b,0);g=(sCb(f.b<f.d.gc()),BD(f.d.Xb(f.c=f.b++),29));while(f.b<f.d.gc()){e=g;g=(sCb(f.b<f.d.gc()),BD(f.d.Xb(f.c=f.b++),29));for(i=new olb(e.a);i.a<i.c.c.length;){h=BD(mlb(i),10);for(k=new olb(h.j);k.a<k.c.c.length;){j=BD(mlb(k),11);for(d=new olb(j.g);d.a<d.c.c.length;){c=BD(mlb(d),17);m=c.d;l=m.i.c;l!=e&&l!=g&&zbc(c,(n=new b0b(a),__b(n,(j0b(),g0b)),yNb(n,(wtc(),$sc),c),yNb(n,(Nyc(),Vxc),(dcd(),$bd)),$_b(n,g),n))}}}}Qdd(b)} +function MTb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;h=b.p!=null&&!b.b;h||Odd(b,kme,1);c=BD(vNb(a,(wtc(),itc)),15);g=1/c.gc();if(b.n){Sdd(b,'ELK Layered uses the following '+c.gc()+' modules:');n=0;for(m=c.Kc();m.Ob();){k=BD(m.Pb(),51);d=(n<10?'0':'')+n++;Sdd(b,' Slot '+d+': '+hdb(rb(k)))}}o=0;for(l=c.Kc();l.Ob();){k=BD(l.Pb(),51);k.pf(a,Udd(b,g));++o}for(f=new olb(a.b);f.a<f.c.c.length;){e=BD(mlb(f),29);Gkb(a.a,e.a);e.a.c=KC(SI,Uhe,1,0,5,1)}for(j=new olb(a.a);j.a<j.c.c.length;){i=BD(mlb(j),10);$_b(i,null)}a.b.c=KC(SI,Uhe,1,0,5,1);h||Qdd(b)} +function kJc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A;d=Edb(ED(vNb(b,(Nyc(),Bxc))));v=BD(vNb(b,Ayc),19).a;m=4;e=3;w=20/v;n=false;i=0;g=Ohe;do{f=i!=1;l=i!=0;A=0;for(q=a.a,s=0,u=q.length;s<u;++s){o=q[s];o.f=null;lJc(a,o,f,l,d);A+=$wnd.Math.abs(o.a)}do{h=pJc(a,b)}while(h);for(p=a.a,r=0,t=p.length;r<t;++r){o=p[r];c=xJc(o).a;if(c!=0){for(k=new olb(o.e);k.a<k.c.c.length;){j=BD(mlb(k),10);j.n.b+=c}}}if(i==0||i==1){--m;if(m<=0&&(A<g||-m>v)){i=2;g=Ohe}else if(i==0){i=1;g=A}else{i=0;g=A}}else{n=A>=g||g-A<w;g=A;n&&--e}}while(!(n&&e<=0))} +function UCb(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o;o=new Lqb;for(f=a.a.ec().Kc();f.Ob();){d=BD(f.Pb(),168);Rhb(o,d,c.Je(d))}g=(Qb(a),a?new Tkb(a):Nu(a.a.ec().Kc()));Okb(g,new WCb(o));h=Gx(g);i=new hDb(b);n=new Lqb;jrb(n.f,b,i);while(h.a.gc()!=0){j=null;k=null;l=null;for(e=h.a.ec().Kc();e.Ob();){d=BD(e.Pb(),168);if(Edb(ED(Wd(irb(o.f,d))))<=Pje){if(Mhb(n,d.a)&&!Mhb(n,d.b)){k=d.b;l=d.a;j=d;break}if(Mhb(n,d.b)){if(!Mhb(n,d.a)){k=d.a;l=d.b;j=d;break}}}}if(!j){break}m=new hDb(k);Ekb(BD(Wd(irb(n.f,l)),221).a,m);jrb(n.f,k,m);h.a.Bc(j)!=null}return i} +function UBc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;Odd(c,'Depth-first cycle removal',1);l=b.a;k=l.c.length;a.c=new Rkb;a.d=KC(sbb,dle,25,k,16,1);a.a=KC(sbb,dle,25,k,16,1);a.b=new Rkb;g=0;for(j=new olb(l);j.a<j.c.c.length;){i=BD(mlb(j),10);i.p=g;Qq(R_b(i))&&Ekb(a.c,i);++g}for(n=new olb(a.c);n.a<n.c.c.length;){m=BD(mlb(n),10);TBc(a,m)}for(f=0;f<k;f++){if(!a.d[f]){h=(tCb(f,l.c.length),BD(l.c[f],10));TBc(a,h)}}for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),17);PZb(d,true);yNb(b,(wtc(),Asc),(Bcb(),true))}a.c=null;a.d=null;a.a=null;a.b=null;Qdd(c)} +function PSc(a,b){var c,d,e,f,g,h,i;a.a.c=KC(SI,Uhe,1,0,5,1);for(d=Jsb(b.b,0);d.b!=d.d.c;){c=BD(Xsb(d),86);if(c.b.b==0){yNb(c,(mTc(),jTc),(Bcb(),true));Ekb(a.a,c)}}switch(a.a.c.length){case 0:e=new XRc(0,b,'DUMMY_ROOT');yNb(e,(mTc(),jTc),(Bcb(),true));yNb(e,YSc,true);Dsb(b.b,e);break;case 1:break;default:f=new XRc(0,b,'SUPER_ROOT');for(h=new olb(a.a);h.a<h.c.c.length;){g=BD(mlb(h),86);i=new QRc(f,g);yNb(i,(mTc(),YSc),(Bcb(),true));Dsb(f.a.a,i);Dsb(f.d,i);Dsb(g.b,i);yNb(g,jTc,false)}yNb(f,(mTc(),jTc),(Bcb(),true));yNb(f,YSc,true);Dsb(b.b,f);}} +function z6c(a,b){i6c();var c,d,e,f,g,h;f=b.c-(a.c+a.b);e=a.c-(b.c+b.b);g=a.d-(b.d+b.a);c=b.d-(a.d+a.a);d=$wnd.Math.max(e,f);h=$wnd.Math.max(g,c);Iy();My(Jqe);if(($wnd.Math.abs(d)<=Jqe||d==0||isNaN(d)&&isNaN(0)?0:d<0?-1:d>0?1:Ny(isNaN(d),isNaN(0)))>=0^(null,My(Jqe),($wnd.Math.abs(h)<=Jqe||h==0||isNaN(h)&&isNaN(0)?0:h<0?-1:h>0?1:Ny(isNaN(h),isNaN(0)))>=0)){return $wnd.Math.max(h,d)}My(Jqe);if(($wnd.Math.abs(d)<=Jqe||d==0||isNaN(d)&&isNaN(0)?0:d<0?-1:d>0?1:Ny(isNaN(d),isNaN(0)))>0){return $wnd.Math.sqrt(h*h+d*d)}return -$wnd.Math.sqrt(h*h+d*d)} +function Kge(a,b){var c,d,e,f,g,h;if(!b)return;!a.a&&(a.a=new Wvb);if(a.e==2){Tvb(a.a,b);return}if(b.e==1){for(e=0;e<b.em();e++)Kge(a,b.am(e));return}h=a.a.a.c.length;if(h==0){Tvb(a.a,b);return}g=BD(Uvb(a.a,h-1),117);if(!((g.e==0||g.e==10)&&(b.e==0||b.e==10))){Tvb(a.a,b);return}f=b.e==0?2:b.bm().length;if(g.e==0){c=new Ifb;d=g._l();d>=Tje?Efb(c,Tee(d)):Afb(c,d&aje);g=(++vfe,new Hge(10,null,0));Vvb(a.a,g,h-1)}else{c=(g.bm().length+f,new Ifb);Efb(c,g.bm())}if(b.e==0){d=b._l();d>=Tje?Efb(c,Tee(d)):Afb(c,d&aje)}else{Efb(c,b.bm())}BD(g,521).b=c.a} +function rgb(a){var b,c,d,e,f;if(a.g!=null){return a.g}if(a.a<32){a.g=rhb(Cbb(a.f),QD(a.e));return a.g}e=shb((!a.c&&(a.c=fhb(a.f)),a.c),0);if(a.e==0){return e}b=(!a.c&&(a.c=fhb(a.f)),a.c).e<0?2:1;c=e.length;d=-a.e+c-b;f=new Ufb;f.a+=''+e;if(a.e>0&&d>=-6){if(d>=0){Tfb(f,c-QD(a.e),String.fromCharCode(46))}else{f.a=qfb(f.a,0,b-1)+'0.'+pfb(f.a,b-1);Tfb(f,b+1,zfb(egb,0,-QD(d)-1))}}else{if(c-b>=1){Tfb(f,b,String.fromCharCode(46));++c}Tfb(f,c,String.fromCharCode(69));d>0&&Tfb(f,++c,String.fromCharCode(43));Tfb(f,++c,''+Ubb(Cbb(d)))}a.g=f.a;return a.g} +function npc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q;if(c.dc()){return}h=0;m=0;d=c.Kc();o=BD(d.Pb(),19).a;while(h<b.f){if(h==o){m=0;d.Ob()?(o=BD(d.Pb(),19).a):(o=b.f+1)}if(h!=m){q=BD(Ikb(a.b,h),29);n=BD(Ikb(a.b,m),29);p=Mu(q.a);for(l=new olb(p);l.a<l.c.c.length;){k=BD(mlb(l),10);Z_b(k,n.a.c.length,n);if(m==0){g=Mu(R_b(k));for(f=new olb(g);f.a<f.c.c.length;){e=BD(mlb(f),17);PZb(e,true);yNb(a,(wtc(),Asc),(Bcb(),true));Noc(a,e,1)}}}}++m;++h}i=new Bib(a.b,0);while(i.b<i.d.gc()){j=(sCb(i.b<i.d.gc()),BD(i.d.Xb(i.c=i.b++),29));j.a.c.length==0&&uib(i)}} +function xmc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;g=b.b;k=g.o;i=g.d;d=Edb(ED(c_b(g,(Nyc(),lyc))));e=Edb(ED(c_b(g,nyc)));j=Edb(ED(c_b(g,xyc)));h=new L_b;v_b(h,i.d,i.c,i.a,i.b);m=tmc(b,d,e,j);for(r=new olb(b.d);r.a<r.c.c.length;){q=BD(mlb(r),101);for(o=q.f.a.ec().Kc();o.Ob();){n=BD(o.Pb(),409);f=n.a;l=rmc(n);c=(s=new s7c,pmc(n,n.c,m,s),omc(n,l,m,s),pmc(n,n.d,m,s),s);c=a.Uf(n,l,c);Osb(f.a);ye(f.a,c);MAb(new YAb(null,new Kub(c,16)),new Bmc(k,h))}p=q.i;if(p){wmc(q,p,m,e);t=new g7c(p.g);ymc(k,h,t);P6c(t,p.j);ymc(k,h,t)}}v_b(i,h.d,h.c,h.a,h.b)} +function rgc(a,b,c){var d,e,f;e=BD(vNb(b,(Nyc(),swc)),275);if(e==(yrc(),wrc)){return}Odd(c,'Horizontal Compaction',1);a.a=b;f=new Ygc;d=new cEb((f.d=b,f.c=BD(vNb(f.d,Swc),218),Pgc(f),Wgc(f),Vgc(f),f.a));aEb(d,a.b);switch(BD(vNb(b,rwc),422).g){case 1:$Db(d,new jfc(a.a));break;default:$Db(d,(ODb(),MDb));}switch(e.g){case 1:TDb(d);break;case 2:TDb(SDb(d,(ead(),bad)));break;case 3:TDb(_Db(SDb(TDb(d),(ead(),bad)),new Bgc));break;case 4:TDb(_Db(SDb(TDb(d),(ead(),bad)),new Dgc(f)));break;case 5:TDb(ZDb(d,pgc));}SDb(d,(ead(),aad));d.e=true;Mgc(f);Qdd(c)} +function mYc(a,b,c,d,e,f,g,h){var i,j,k,l;i=Ou(OC(GC(z_,1),Uhe,220,0,[b,c,d,e]));l=null;switch(a.b.g){case 1:l=Ou(OC(GC(o_,1),Uhe,526,0,[new uYc,new oYc,new qYc]));break;case 0:l=Ou(OC(GC(o_,1),Uhe,526,0,[new qYc,new oYc,new uYc]));break;case 2:l=Ou(OC(GC(o_,1),Uhe,526,0,[new oYc,new uYc,new qYc]));}for(k=new olb(l);k.a<k.c.c.length;){j=BD(mlb(k),526);i.c.length>1&&(i=j.mg(i,a.a,h))}if(i.c.length==1){return BD(Ikb(i,i.c.length-1),220)}if(i.c.length==2){return lYc((tCb(0,i.c.length),BD(i.c[0],220)),(tCb(1,i.c.length),BD(i.c[1],220)),g,f)}return null} +function JNb(a){var b,c,d,e,f,g;Hkb(a.a,new PNb);for(c=new olb(a.a);c.a<c.c.c.length;){b=BD(mlb(c),221);d=c7c(R6c(BD(a.b,65).c),BD(b.b,65).c);if(FNb){g=BD(a.b,65).b;f=BD(b.b,65).b;if($wnd.Math.abs(d.a)>=$wnd.Math.abs(d.b)){d.b=0;f.d+f.a>g.d&&f.d<g.d+g.a&&$6c(d,$wnd.Math.max(g.c-(f.c+f.b),f.c-(g.c+g.b)))}else{d.a=0;f.c+f.b>g.c&&f.c<g.c+g.b&&$6c(d,$wnd.Math.max(g.d-(f.d+f.a),f.d-(g.d+g.a)))}}else{$6c(d,_Nb(BD(a.b,65),BD(b.b,65)))}e=$wnd.Math.sqrt(d.a*d.a+d.b*d.b);e=LNb(GNb,b,e,d);$6c(d,e);$Nb(BD(b.b,65),d);Hkb(b.a,new RNb(d));BD(GNb.b,65);KNb(GNb,HNb,b)}} +function VJc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;a.f=new KFb;j=0;e=0;for(g=new olb(a.e.b);g.a<g.c.c.length;){f=BD(mlb(g),29);for(i=new olb(f.a);i.a<i.c.c.length;){h=BD(mlb(i),10);h.p=j++;for(d=new Sr(ur(U_b(h).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),17);c.p=e++}b=bKc(h);for(m=new olb(h.j);m.a<m.c.c.length;){l=BD(mlb(m),11);if(b){o=l.a.b;if(o!=$wnd.Math.floor(o)){k=o-Sbb(Cbb($wnd.Math.round(o)));l.a.b-=k}}n=l.n.b+l.a.b;if(n!=$wnd.Math.floor(n)){k=n-Sbb(Cbb($wnd.Math.round(n)));l.n.b-=k}}}}a.g=j;a.b=e;a.i=KC(xY,Uhe,401,j,0,1);a.c=KC(wY,Uhe,649,e,0,1);a.d.a.$b()} +function Uxd(a){var b,c,d,e,f,g,h,i,j;if(a.ej()){i=a.fj();if(a.i>0){b=new _zd(a.i,a.g);c=a.i;f=c<100?null:new Ixd(c);if(a.ij()){for(d=0;d<a.i;++d){g=a.g[d];f=a.kj(g,f)}}oud(a);e=c==1?a.Zi(4,qud(b,0),null,0,i):a.Zi(6,b,null,-1,i);if(a.bj()){for(d=new $yd(b);d.e!=d.i.gc();){f=a.dj(Zyd(d),f)}if(!f){a.$i(e)}else{f.Ei(e);f.Fi()}}else{if(!f){a.$i(e)}else{f.Ei(e);f.Fi()}}}else{oud(a);a.$i(a.Zi(6,(mmb(),jmb),null,-1,i))}}else if(a.bj()){if(a.i>0){h=a.g;j=a.i;oud(a);f=j<100?null:new Ixd(j);for(d=0;d<j;++d){g=h[d];f=a.dj(g,f)}!!f&&f.Fi()}else{oud(a)}}else{oud(a)}} +function ZQc(a,b,c){var d,e,f,g,h,i,j,k,l,m;TQc(this);c==(FQc(),DQc)?Qqb(this.r,a):Qqb(this.w,a);k=Pje;j=Qje;for(g=b.a.ec().Kc();g.Ob();){e=BD(g.Pb(),46);h=BD(e.a,455);d=BD(e.b,17);i=d.c;i==a&&(i=d.d);h==DQc?Qqb(this.r,i):Qqb(this.w,i);m=(Ucd(),Lcd).Hc(i.j)?Edb(ED(vNb(i,(wtc(),qtc)))):l7c(OC(GC(m1,1),nie,8,0,[i.i.n,i.n,i.a])).b;k=$wnd.Math.min(k,m);j=$wnd.Math.max(j,m)}l=(Ucd(),Lcd).Hc(a.j)?Edb(ED(vNb(a,(wtc(),qtc)))):l7c(OC(GC(m1,1),nie,8,0,[a.i.n,a.n,a.a])).b;XQc(this,l,k,j);for(f=b.a.ec().Kc();f.Ob();){e=BD(f.Pb(),46);UQc(this,BD(e.b,17))}this.o=false} +function gD(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G;c=a.l&8191;d=a.l>>13|(a.m&15)<<9;e=a.m>>4&8191;f=a.m>>17|(a.h&255)<<5;g=(a.h&1048320)>>8;h=b.l&8191;i=b.l>>13|(b.m&15)<<9;j=b.m>>4&8191;k=b.m>>17|(b.h&255)<<5;l=(b.h&1048320)>>8;B=c*h;C=d*h;D=e*h;F=f*h;G=g*h;if(i!=0){C+=c*i;D+=d*i;F+=e*i;G+=f*i}if(j!=0){D+=c*j;F+=d*j;G+=e*j}if(k!=0){F+=c*k;G+=d*k}l!=0&&(G+=c*l);n=B&Eje;o=(C&511)<<13;m=n+o;q=B>>22;r=C>>9;s=(D&262143)<<4;t=(F&31)<<17;p=q+r+s+t;v=D>>18;w=F>>5;A=(G&4095)<<8;u=v+w+A;p+=m>>22;m&=Eje;u+=p>>22;p&=Eje;u&=Fje;return TC(m,p,u)} +function o7b(a){var b,c,d,e,f,g,h;h=BD(Ikb(a.j,0),11);if(h.g.c.length!=0&&h.e.c.length!=0){throw vbb(new Zdb('Interactive layout does not support NORTH/SOUTH ports with incoming _and_ outgoing edges.'))}if(h.g.c.length!=0){f=Pje;for(c=new olb(h.g);c.a<c.c.c.length;){b=BD(mlb(c),17);g=b.d.i;d=BD(vNb(g,(Nyc(),txc)),142);f=$wnd.Math.min(f,g.n.a-d.b)}return new cc(Qb(f))}if(h.e.c.length!=0){e=Qje;for(c=new olb(h.e);c.a<c.c.c.length;){b=BD(mlb(c),17);g=b.c.i;d=BD(vNb(g,(Nyc(),txc)),142);e=$wnd.Math.max(e,g.n.a+g.o.a+d.c)}return new cc(Qb(e))}return wb(),wb(),vb} +function ELd(a,b){var c,d,e,f,g,h,i;if(a.Fk()){if(a.i>4){if(a.wj(b)){if(a.rk()){e=BD(b,49);d=e.Ug();i=d==a.e&&(a.Dk()?e.Og(e.Vg(),a.zk())==a.Ak():-1-e.Vg()==a.aj());if(a.Ek()&&!i&&!d&&!!e.Zg()){for(f=0;f<a.i;++f){c=a.Gk(BD(a.g[f],56));if(PD(c)===PD(b)){return true}}}return i}else if(a.Dk()&&!a.Ck()){g=BD(b,56).ah(zUd(BD(a.ak(),18)));if(PD(g)===PD(a.e)){return true}else if(g==null||!BD(g,56).kh()){return false}}}else{return false}}h=pud(a,b);if(a.Ek()&&!h){for(f=0;f<a.i;++f){e=a.Gk(BD(a.g[f],56));if(PD(e)===PD(b)){return true}}}return h}else{return pud(a,b)}} +function mHc(a,b){var c,d,e,f,g,h,i,j,k,l,m;k=new Rkb;m=new Tqb;g=b.b;for(e=0;e<g.c.length;e++){j=(tCb(e,g.c.length),BD(g.c[e],29)).a;k.c=KC(SI,Uhe,1,0,5,1);for(f=0;f<j.c.length;f++){h=a.a[e][f];h.p=f;h.k==(j0b(),i0b)&&(k.c[k.c.length]=h,true);Nkb(BD(Ikb(b.b,e),29).a,f,h);h.j.c=KC(SI,Uhe,1,0,5,1);Gkb(h.j,BD(BD(Ikb(a.b,e),15).Xb(f),14));ecd(BD(vNb(h,(Nyc(),Vxc)),98))||yNb(h,Vxc,(dcd(),Zbd))}for(d=new olb(k);d.a<d.c.c.length;){c=BD(mlb(d),10);l=kHc(c);m.a.zc(l,m);m.a.zc(c,m)}}for(i=m.a.ec().Kc();i.Ob();){h=BD(i.Pb(),10);mmb();Okb(h.j,(Occ(),Icc));h.i=true;N_b(h)}} +function g6b(a,b){var c,d,e,f,g,h,i,j,k,l;k=BD(vNb(a,(wtc(),Hsc)),61);d=BD(Ikb(a.j,0),11);k==(Ucd(),Acd)?G0b(d,Rcd):k==Rcd&&G0b(d,Acd);if(BD(vNb(b,(Nyc(),Fxc)),174).Hc((tdd(),sdd))){i=Edb(ED(vNb(a,tyc)));j=Edb(ED(vNb(a,uyc)));g=Edb(ED(vNb(a,ryc)));h=BD(vNb(b,Yxc),21);if(h.Hc((rcd(),ncd))){c=j;l=a.o.a/2-d.n.a;for(f=new olb(d.f);f.a<f.c.c.length;){e=BD(mlb(f),70);e.n.b=c;e.n.a=l-e.o.a/2;c+=e.o.b+g}}else if(h.Hc(pcd)){for(f=new olb(d.f);f.a<f.c.c.length;){e=BD(mlb(f),70);e.n.a=i+a.o.a-d.n.a}}WGb(new YGb((a$b(),new l$b(b,false,false,new T$b))),new x$b(null,a,false))}} +function Ugc(a,b){var c,d,e,f,g,h,i,j,k;if(b.c.length==0){return}mmb();Mlb(b.c,b.c.length,null);e=new olb(b);d=BD(mlb(e),145);while(e.a<e.c.c.length){c=BD(mlb(e),145);if(ADb(d.e.c,c.e.c)&&!(DDb(B6c(d.e).b,c.e.d)||DDb(B6c(c.e).b,d.e.d))){d=(Gkb(d.k,c.k),Gkb(d.b,c.b),Gkb(d.c,c.c),ye(d.i,c.i),Gkb(d.d,c.d),Gkb(d.j,c.j),f=$wnd.Math.min(d.e.c,c.e.c),g=$wnd.Math.min(d.e.d,c.e.d),h=$wnd.Math.max(d.e.c+d.e.b,c.e.c+c.e.b),i=h-f,j=$wnd.Math.max(d.e.d+d.e.a,c.e.d+c.e.a),k=j-g,G6c(d.e,f,g,i,k),hEb(d.f,c.f),!d.a&&(d.a=c.a),Gkb(d.g,c.g),Ekb(d.g,c),d)}else{Xgc(a,d);d=c}}Xgc(a,d)} +function e_b(a,b,c,d){var e,f,g,h,i,j;h=a.j;if(h==(Ucd(),Scd)&&b!=(dcd(),bcd)&&b!=(dcd(),ccd)){h=W$b(a,c);G0b(a,h);!(!a.q?(mmb(),mmb(),kmb):a.q)._b((Nyc(),Uxc))&&h!=Scd&&(a.n.a!=0||a.n.b!=0)&&yNb(a,Uxc,V$b(a,h))}if(b==(dcd(),_bd)){j=0;switch(h.g){case 1:case 3:f=a.i.o.a;f>0&&(j=a.n.a/f);break;case 2:case 4:e=a.i.o.b;e>0&&(j=a.n.b/e);}yNb(a,(wtc(),htc),j)}i=a.o;g=a.a;if(d){g.a=d.a;g.b=d.b;a.d=true}else if(b!=bcd&&b!=ccd&&h!=Scd){switch(h.g){case 1:g.a=i.a/2;break;case 2:g.a=i.a;g.b=i.b/2;break;case 3:g.a=i.a/2;g.b=i.b;break;case 4:g.b=i.b/2;}}else{g.a=i.a/2;g.b=i.b/2}} +function vwd(a){var b,c,d,e,f,g,h,i,j,k;if(a.ej()){k=a.Vi();i=a.fj();if(k>0){b=new Aud(a.Gi());c=k;f=c<100?null:new Ixd(c);Cvd(a,c,b.g);e=c==1?a.Zi(4,qud(b,0),null,0,i):a.Zi(6,b,null,-1,i);if(a.bj()){for(d=new Fyd(b);d.e!=d.i.gc();){f=a.dj(Dyd(d),f)}if(!f){a.$i(e)}else{f.Ei(e);f.Fi()}}else{if(!f){a.$i(e)}else{f.Ei(e);f.Fi()}}}else{Cvd(a,a.Vi(),a.Wi());a.$i(a.Zi(6,(mmb(),jmb),null,-1,i))}}else if(a.bj()){k=a.Vi();if(k>0){h=a.Wi();j=k;Cvd(a,k,h);f=j<100?null:new Ixd(j);for(d=0;d<j;++d){g=h[d];f=a.dj(g,f)}!!f&&f.Fi()}else{Cvd(a,a.Vi(),a.Wi())}}else{Cvd(a,a.Vi(),a.Wi())}} +function LEc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;for(h=new olb(b);h.a<h.c.c.length;){f=BD(mlb(h),233);f.e=null;f.c=0}i=null;for(g=new olb(b);g.a<g.c.c.length;){f=BD(mlb(g),233);l=f.d[0];if(c&&l.k!=(j0b(),h0b)){continue}for(n=BD(vNb(l,(wtc(),Qsc)),15).Kc();n.Ob();){m=BD(n.Pb(),10);if(!c||m.k==(j0b(),h0b)){(!f.e&&(f.e=new Rkb),f.e).Fc(a.b[m.c.p][m.p]);++a.b[m.c.p][m.p].c}}if(!c&&l.k==(j0b(),h0b)){if(i){for(k=BD(Qc(a.d,i),21).Kc();k.Ob();){j=BD(k.Pb(),10);for(e=BD(Qc(a.d,l),21).Kc();e.Ob();){d=BD(e.Pb(),10);YEc(a.b[j.c.p][j.p]).Fc(a.b[d.c.p][d.p]);++a.b[d.c.p][d.p].c}}}i=l}}} +function OHc(a,b){var c,d,e,f,g,h,i,j,k;c=0;k=new Rkb;for(h=new olb(b);h.a<h.c.c.length;){g=BD(mlb(h),11);AHc(a.b,a.d[g.p]);k.c=KC(SI,Uhe,1,0,5,1);switch(g.i.k.g){case 0:d=BD(vNb(g,(wtc(),gtc)),10);Hkb(d.j,new xIc(k));break;case 1:Ctb(KAb(JAb(new YAb(null,new Kub(g.i.j,16)),new zIc(g))),new CIc(k));break;case 3:e=BD(vNb(g,(wtc(),$sc)),11);Ekb(k,new vgd(e,meb(g.e.c.length+g.g.c.length)));}for(j=new olb(k);j.a<j.c.c.length;){i=BD(mlb(j),46);f=aIc(a,BD(i.a,11));if(f>a.d[g.p]){c+=zHc(a.b,f)*BD(i.b,19).a;Wjb(a.a,meb(f))}}while(!akb(a.a)){xHc(a.b,BD(fkb(a.a),19).a)}}return c} +function eed(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q;l=new g7c(BD(hkd(a,(X7c(),R7c)),8));l.a=$wnd.Math.max(l.a-c.b-c.c,0);l.b=$wnd.Math.max(l.b-c.d-c.a,0);e=ED(hkd(a,L7c));(e==null||(uCb(e),e)<=0)&&(e=1.3);h=new Rkb;for(o=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));o.e!=o.i.gc();){n=BD(Dyd(o),33);g=new xed(n);h.c[h.c.length]=g}m=BD(hkd(a,M7c),311);switch(m.g){case 3:q=bed(h,b,l.a,l.b,(j=d,uCb(e),e,j));break;case 1:q=aed(h,b,l.a,l.b,(k=d,uCb(e),e,k));break;default:q=ced(h,b,l.a,l.b,(i=d,uCb(e),e,i));}f=new wed(q);p=fed(f,b,c,l.a,l.b,d,(uCb(e),e));Afd(a,p.a,p.b,false,true)} +function vkc(a,b){var c,d,e,f;c=b.b;f=new Tkb(c.j);e=0;d=c.j;d.c=KC(SI,Uhe,1,0,5,1);hkc(BD(Si(a.b,(Ucd(),Acd),(Fkc(),Ekc)),15),c);e=ikc(f,e,new blc,d);hkc(BD(Si(a.b,Acd,Dkc),15),c);e=ikc(f,e,new dlc,d);hkc(BD(Si(a.b,Acd,Ckc),15),c);hkc(BD(Si(a.b,zcd,Ekc),15),c);hkc(BD(Si(a.b,zcd,Dkc),15),c);e=ikc(f,e,new flc,d);hkc(BD(Si(a.b,zcd,Ckc),15),c);hkc(BD(Si(a.b,Rcd,Ekc),15),c);e=ikc(f,e,new hlc,d);hkc(BD(Si(a.b,Rcd,Dkc),15),c);e=ikc(f,e,new jlc,d);hkc(BD(Si(a.b,Rcd,Ckc),15),c);hkc(BD(Si(a.b,Tcd,Ekc),15),c);e=ikc(f,e,new Pkc,d);hkc(BD(Si(a.b,Tcd,Dkc),15),c);hkc(BD(Si(a.b,Tcd,Ckc),15),c)} +function nbc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;Odd(b,'Layer size calculation',1);k=Pje;j=Qje;e=false;for(h=new olb(a.b);h.a<h.c.c.length;){g=BD(mlb(h),29);i=g.c;i.a=0;i.b=0;if(g.a.c.length==0){continue}e=true;for(m=new olb(g.a);m.a<m.c.c.length;){l=BD(mlb(m),10);o=l.o;n=l.d;i.a=$wnd.Math.max(i.a,o.a+n.b+n.c)}d=BD(Ikb(g.a,0),10);p=d.n.b-d.d.d;d.k==(j0b(),e0b)&&(p-=BD(vNb(a,(Nyc(),yyc)),142).d);f=BD(Ikb(g.a,g.a.c.length-1),10);c=f.n.b+f.o.b+f.d.a;f.k==e0b&&(c+=BD(vNb(a,(Nyc(),yyc)),142).a);i.b=c-p;k=$wnd.Math.min(k,p);j=$wnd.Math.max(j,c)}if(!e){k=0;j=0}a.f.b=j-k;a.c.b-=k;Qdd(b)} +function h_b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;f=0;g=0;for(j=new olb(a.a);j.a<j.c.c.length;){h=BD(mlb(j),10);f=$wnd.Math.max(f,h.d.b);g=$wnd.Math.max(g,h.d.c)}for(i=new olb(a.a);i.a<i.c.c.length;){h=BD(mlb(i),10);c=BD(vNb(h,(Nyc(),mwc)),248);switch(c.g){case 1:o=0;break;case 2:o=1;break;case 5:o=0.5;break;default:d=0;l=0;for(n=new olb(h.j);n.a<n.c.c.length;){m=BD(mlb(n),11);m.e.c.length==0||++d;m.g.c.length==0||++l}d+l==0?(o=0.5):(o=l/(d+l));}q=a.c;k=h.o.a;r=(q.a-k)*o;o>0.5?(r-=g*2*(o-0.5)):o<0.5&&(r+=f*2*(0.5-o));e=h.d.b;r<e&&(r=e);p=h.d.c;r>q.a-p-k&&(r=q.a-p-k);h.n.a=b+r}} +function ced(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q;h=KC(UD,Vje,25,a.c.length,15,1);m=new gub(new Ned);_tb(m,a);j=0;p=new Rkb;while(m.b.c.length!=0){g=BD(m.b.c.length==0?null:Ikb(m.b,0),157);if(j>1&&red(g)*qed(g)/2>h[0]){f=0;while(f<p.c.length-1&&red(g)*qed(g)/2>h[f]){++f}o=new Jib(p,0,f+1);l=new wed(o);k=red(g)/qed(g);i=fed(l,b,new p0b,c,d,e,k);P6c(X6c(l.e),i);zCb(cub(m,l));n=new Jib(p,f+1,p.c.length);_tb(m,n);p.c=KC(SI,Uhe,1,0,5,1);j=0;Dlb(h,h.length,0)}else{q=m.b.c.length==0?null:Ikb(m.b,0);q!=null&&fub(m,0);j>0&&(h[j]=h[j-1]);h[j]+=red(g)*qed(g);++j;p.c[p.c.length]=g}}return p} +function Wac(a){var b,c,d,e,f;d=BD(vNb(a,(Nyc(),mxc)),163);if(d==(Ctc(),ytc)){for(c=new Sr(ur(R_b(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),17);if(!Yac(b)){throw vbb(new y2c(Fne+P_b(a)+"' has its layer constraint set to FIRST_SEPARATE, but has at least one incoming edge. "+'FIRST_SEPARATE nodes must not have incoming edges.'))}}}else if(d==Atc){for(f=new Sr(ur(U_b(a).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);if(!Yac(e)){throw vbb(new y2c(Fne+P_b(a)+"' has its layer constraint set to LAST_SEPARATE, but has at least one outgoing edge. "+'LAST_SEPARATE nodes must not have outgoing edges.'))}}}} +function C9b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;Odd(b,'Label dummy removal',1);d=Edb(ED(vNb(a,(Nyc(),nyc))));e=Edb(ED(vNb(a,ryc)));j=BD(vNb(a,Lwc),103);for(i=new olb(a.b);i.a<i.c.c.length;){h=BD(mlb(i),29);l=new Bib(h.a,0);while(l.b<l.d.gc()){k=(sCb(l.b<l.d.gc()),BD(l.d.Xb(l.c=l.b++),10));if(k.k==(j0b(),f0b)){m=BD(vNb(k,(wtc(),$sc)),17);o=Edb(ED(vNb(m,Zwc)));g=PD(vNb(k,Ssc))===PD((rbd(),obd));c=new g7c(k.n);g&&(c.b+=o+d);f=new f7c(k.o.a,k.o.b-o-d);n=BD(vNb(k,ktc),15);j==(ead(),dad)||j==_9c?B9b(n,c,e,f,g,j):A9b(n,c,e,f);Gkb(m.b,n);sbc(k,PD(vNb(a,Swc))===PD((Aad(),xad)));uib(l)}}}Qdd(b)} +function tZb(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;i=new Rkb;for(f=new olb(b.a);f.a<f.c.c.length;){e=BD(mlb(f),10);for(h=new olb(e.j);h.a<h.c.c.length;){g=BD(mlb(h),11);k=null;for(t=k_b(g.g),u=0,v=t.length;u<v;++u){s=t[u];if(!f_b(s.d.i,c)){r=oZb(a,b,c,s,s.c,(KAc(),IAc),k);r!=k&&(i.c[i.c.length]=r,true);r.c&&(k=r)}}j=null;for(o=k_b(g.e),p=0,q=o.length;p<q;++p){n=o[p];if(!f_b(n.c.i,c)){r=oZb(a,b,c,n,n.d,(KAc(),HAc),j);r!=j&&(i.c[i.c.length]=r,true);r.c&&(j=r)}}}}for(m=new olb(i);m.a<m.c.c.length;){l=BD(mlb(m),441);Jkb(b.a,l.a,0)!=-1||Ekb(b.a,l.a);l.c&&(d.c[d.c.length]=l,true)}} +function jCc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q;Odd(c,'Interactive cycle breaking',1);l=new Rkb;for(n=new olb(b.a);n.a<n.c.c.length;){m=BD(mlb(n),10);m.p=1;o=T_b(m).a;for(k=W_b(m,(KAc(),IAc)).Kc();k.Ob();){j=BD(k.Pb(),11);for(f=new olb(j.g);f.a<f.c.c.length;){d=BD(mlb(f),17);p=d.d.i;if(p!=m){q=T_b(p).a;q<o&&(l.c[l.c.length]=d,true)}}}}for(g=new olb(l);g.a<g.c.c.length;){d=BD(mlb(g),17);PZb(d,true)}l.c=KC(SI,Uhe,1,0,5,1);for(i=new olb(b.a);i.a<i.c.c.length;){h=BD(mlb(i),10);h.p>0&&iCc(a,h,l)}for(e=new olb(l);e.a<e.c.c.length;){d=BD(mlb(e),17);PZb(d,true)}l.c=KC(SI,Uhe,1,0,5,1);Qdd(c)} +function _z(a,b){var c,d,e,f,g,h,i,j,k;j='';if(b.length==0){return a.de(Zie,Xie,-1,-1)}k=ufb(b);dfb(k.substr(0,3),'at ')&&(k=k.substr(3));k=k.replace(/\[.*?\]/g,'');g=k.indexOf('(');if(g==-1){g=k.indexOf('@');if(g==-1){j=k;k=''}else{j=ufb(k.substr(g+1));k=ufb(k.substr(0,g))}}else{c=k.indexOf(')',g);j=k.substr(g+1,c-(g+1));k=ufb(k.substr(0,g))}g=hfb(k,wfb(46));g!=-1&&(k=k.substr(g+1));(k.length==0||dfb(k,'Anonymous function'))&&(k=Xie);h=kfb(j,wfb(58));e=lfb(j,wfb(58),h-1);i=-1;d=-1;f=Zie;if(h!=-1&&e!=-1){f=j.substr(0,e);i=Vz(j.substr(e+1,h-(e+1)));d=Vz(j.substr(h+1))}return a.de(f,k,i,d)} +function UC(a,b,c){var d,e,f,g,h,i;if(b.l==0&&b.m==0&&b.h==0){throw vbb(new ocb('divide by zero'))}if(a.l==0&&a.m==0&&a.h==0){c&&(QC=TC(0,0,0));return TC(0,0,0)}if(b.h==Gje&&b.m==0&&b.l==0){return VC(a,c)}i=false;if(b.h>>19!=0){b=hD(b);i=!i}g=_C(b);f=false;e=false;d=false;if(a.h==Gje&&a.m==0&&a.l==0){e=true;f=true;if(g==-1){a=SC((wD(),sD));d=true;i=!i}else{h=lD(a,g);i&&ZC(h);c&&(QC=TC(0,0,0));return h}}else if(a.h>>19!=0){f=true;a=hD(a);d=true;i=!i}if(g!=-1){return WC(a,g,i,f,c)}if(eD(a,b)<0){c&&(f?(QC=hD(a)):(QC=TC(a.l,a.m,a.h)));return TC(0,0,0)}return XC(d?a:TC(a.l,a.m,a.h),b,i,f,e,c)} +function F2c(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;if(a.e&&a.c.c<a.f){throw vbb(new Zdb('Expected '+a.f+' phases to be configured; '+'only found '+a.c.c))}k=BD(gdb(a.g),9);n=Pu(a.f);for(f=k,h=0,j=f.length;h<j;++h){d=f[h];l=BD(B2c(a,d.g),246);l?Ekb(n,BD(I2c(a,l),123)):(n.c[n.c.length]=null,true)}o=new j3c;MAb(JAb(NAb(JAb(new YAb(null,new Kub(n,16)),new O2c),new Q2c(b)),new S2c),new U2c(o));d3c(o,a.a);c=new Rkb;for(e=k,g=0,i=e.length;g<i;++g){d=e[g];Gkb(c,J2c(a,Dx(BD(B2c(o,d.g),20))));m=BD(Ikb(n,d.g),123);!!m&&(c.c[c.c.length]=m,true)}Gkb(c,J2c(a,Dx(BD(B2c(o,k[k.length-1].g+1),20))));return c} +function qCc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q;Odd(c,'Model order cycle breaking',1);a.a=0;a.b=0;n=new Rkb;k=b.a.c.length;for(j=new olb(b.a);j.a<j.c.c.length;){i=BD(mlb(j),10);wNb(i,(wtc(),Zsc))&&(k=$wnd.Math.max(k,BD(vNb(i,Zsc),19).a+1))}for(p=new olb(b.a);p.a<p.c.c.length;){o=BD(mlb(p),10);g=pCc(a,o,k);for(m=W_b(o,(KAc(),IAc)).Kc();m.Ob();){l=BD(m.Pb(),11);for(f=new olb(l.g);f.a<f.c.c.length;){d=BD(mlb(f),17);q=d.d.i;h=pCc(a,q,k);h<g&&(n.c[n.c.length]=d,true)}}}for(e=new olb(n);e.a<e.c.c.length;){d=BD(mlb(e),17);PZb(d,true);yNb(b,(wtc(),Asc),(Bcb(),true))}n.c=KC(SI,Uhe,1,0,5,1);Qdd(c)} +function kQc(a,b){var c,d,e,f,g,h,i;if(a.g>b.f||b.g>a.f){return}c=0;d=0;for(g=a.w.a.ec().Kc();g.Ob();){e=BD(g.Pb(),11);aRc(l7c(OC(GC(m1,1),nie,8,0,[e.i.n,e.n,e.a])).b,b.g,b.f)&&++c}for(h=a.r.a.ec().Kc();h.Ob();){e=BD(h.Pb(),11);aRc(l7c(OC(GC(m1,1),nie,8,0,[e.i.n,e.n,e.a])).b,b.g,b.f)&&--c}for(i=b.w.a.ec().Kc();i.Ob();){e=BD(i.Pb(),11);aRc(l7c(OC(GC(m1,1),nie,8,0,[e.i.n,e.n,e.a])).b,a.g,a.f)&&++d}for(f=b.r.a.ec().Kc();f.Ob();){e=BD(f.Pb(),11);aRc(l7c(OC(GC(m1,1),nie,8,0,[e.i.n,e.n,e.a])).b,a.g,a.f)&&--d}if(c<d){new BQc(a,b,d-c)}else if(d<c){new BQc(b,a,c-d)}else{new BQc(b,a,0);new BQc(a,b,0)}} +function JPb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;j=b.c;e=IOb(a.e);l=Y6c(b7c(R6c(HOb(a.e)),a.d*a.a,a.c*a.b),-0.5);c=e.a-l.a;d=e.b-l.b;g=b.a;c=g.c-c;d=g.d-d;for(i=new olb(j);i.a<i.c.c.length;){h=BD(mlb(i),395);m=h.b;n=c+m.a;q=d+m.b;o=QD(n/a.a);r=QD(q/a.b);f=h.a;switch(f.g){case 0:k=(RMb(),OMb);break;case 1:k=(RMb(),NMb);break;case 2:k=(RMb(),PMb);break;default:k=(RMb(),QMb);}if(f.a){s=QD((q+h.c)/a.b);Ekb(a.f,new uOb(k,meb(r),meb(s)));f==(ROb(),QOb)?nNb(a,0,r,o,s):nNb(a,o,r,a.d-1,s)}else{p=QD((n+h.c)/a.a);Ekb(a.f,new uOb(k,meb(o),meb(p)));f==(ROb(),OOb)?nNb(a,o,0,p,r):nNb(a,o,r,p,a.c-1)}}} +function coc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;m=new Rkb;e=new Rkb;p=null;for(h=b.Kc();h.Ob();){g=BD(h.Pb(),19);f=new qoc(g.a);e.c[e.c.length]=f;if(p){f.d=p;p.e=f}p=f}t=boc(a);for(k=0;k<e.c.length;++k){n=null;q=poc((tCb(0,e.c.length),BD(e.c[0],652)));c=null;d=Pje;for(l=1;l<a.b.c.length;++l){r=q?$wnd.Math.abs(q.b-l):$wnd.Math.abs(l-n.b)+1;o=n?$wnd.Math.abs(l-n.b):r+1;if(o<r){j=n;i=o}else{j=q;i=r}s=(u=Edb(ED(vNb(a,(Nyc(),Hyc)))),t[l]+$wnd.Math.pow(i,u));if(s<d){d=s;c=j;c.c=l}if(!!q&&l==q.b){n=q;q=koc(q)}}if(c){Ekb(m,meb(c.c));c.a=true;loc(c)}}mmb();Mlb(m.c,m.c.length,null);return m} +function qNd(a){var b,c,d,e,f,g,h,i,j,k;b=new zNd;c=new zNd;j=dfb(Qve,(e=Dmd(a.b,Rve),!e?null:GD(AAd((!e.b&&(e.b=new sId((jGd(),fGd),x6,e)),e.b),Sve))));for(i=0;i<a.i;++i){h=BD(a.g[i],170);if(JD(h,99)){g=BD(h,18);(g.Bb&ote)!=0?((g.Bb&oie)==0||!j&&(f=Dmd(g,Rve),(!f?null:GD(AAd((!f.b&&(f.b=new sId((jGd(),fGd),x6,f)),f.b),eue)))==null))&&wtd(b,g):(k=zUd(g),!!k&&(k.Bb&ote)!=0||((g.Bb&oie)==0||!j&&(d=Dmd(g,Rve),(!d?null:GD(AAd((!d.b&&(d.b=new sId((jGd(),fGd),x6,d)),d.b),eue)))==null))&&wtd(c,g))}else{Q6d();if(BD(h,66).Oj()){if(!h.Jj()){wtd(b,h);wtd(c,h)}}}}vud(b);vud(c);a.a=BD(b.g,247);BD(c.g,247)} +function LTb(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;j=ITb(b);q=BD(vNb(b,(Nyc(),Iwc)),314);q!=(Rpc(),Ppc)&&reb(j,new STb);r=BD(vNb(b,Cwc),292);reb(j,new UTb(r));p=0;k=new Rkb;for(f=new xkb(j);f.a!=f.b;){e=BD(vkb(f),37);aUb(a.c,e);m=BD(vNb(e,(wtc(),itc)),15);p+=m.gc();d=m.Kc();Ekb(k,new vgd(e,d))}Odd(c,'Recursive hierarchical layout',p);o=0;n=BD(BD(Ikb(k,k.c.length-1),46).b,47);while(n.Ob()){for(i=new olb(k);i.a<i.c.c.length;){h=BD(mlb(i),46);m=BD(h.b,47);g=BD(h.a,37);while(m.Ob()){l=BD(m.Pb(),51);if(JD(l,507)){if(!g.e){l.pf(g,Udd(c,1));++o;break}else{break}}else{l.pf(g,Udd(c,1));++o}}}}Qdd(c)} +function rid(b,c){var d,e,f,g,h,i,j,k,l,m;j=c.length-1;i=(BCb(j,c.length),c.charCodeAt(j));if(i==93){h=hfb(c,wfb(91));if(h>=0){f=wid(b,c.substr(1,h-1));l=c.substr(h+1,j-(h+1));return pid(b,l,f)}}else{d=-1;Vcb==null&&(Vcb=new RegExp('\\d'));if(Vcb.test(String.fromCharCode(i))){d=lfb(c,wfb(46),j-1);if(d>=0){e=BD(hid(b,Bid(b,c.substr(1,d-1)),false),58);k=0;try{k=Icb(c.substr(d+1),Rie,Ohe)}catch(a){a=ubb(a);if(JD(a,127)){g=a;throw vbb(new rFd(g))}else throw vbb(a)}if(k<e.gc()){m=e.Xb(k);JD(m,72)&&(m=BD(m,72).dd());return BD(m,56)}}}if(d<0){return BD(hid(b,Bid(b,c.substr(1)),false),56)}}return null} +function e1d(a,b,c){var d,e,f,g,h,i,j,k,l;if(bLd(b,c)>=0){return c}switch($1d(q1d(a,c))){case 2:{if(dfb('',o1d(a,c.Hj()).ne())){i=b2d(q1d(a,c));h=a2d(q1d(a,c));k=r1d(a,b,i,h);if(k){return k}e=f1d(a,b);for(g=0,l=e.gc();g<l;++g){k=BD(e.Xb(g),170);if(x1d(c2d(q1d(a,k)),i)){return k}}}return null}case 4:{if(dfb('',o1d(a,c.Hj()).ne())){for(d=c;d;d=Z1d(q1d(a,d))){j=b2d(q1d(a,d));h=a2d(q1d(a,d));k=s1d(a,b,j,h);if(k){return k}}i=b2d(q1d(a,c));if(dfb(Ewe,i)){return t1d(a,b)}else{f=g1d(a,b);for(g=0,l=f.gc();g<l;++g){k=BD(f.Xb(g),170);if(x1d(c2d(q1d(a,k)),i)){return k}}}}return null}default:{return null}}} +function t2d(a,b,c){var d,e,f,g,h,i,j,k;if(c.gc()==0){return false}h=(Q6d(),BD(b,66).Oj());f=h?c:new zud(c.gc());if(T6d(a.e,b)){if(b.hi()){for(j=c.Kc();j.Ob();){i=j.Pb();if(!F2d(a,b,i,JD(b,99)&&(BD(b,18).Bb&Tje)!=0)){e=R6d(b,i);f.Hc(e)||f.Fc(e)}}}else if(!h){for(j=c.Kc();j.Ob();){i=j.Pb();e=R6d(b,i);f.Fc(e)}}}else{if(c.gc()>1){throw vbb(new Wdb(Hwe))}k=S6d(a.e.Tg(),b);d=BD(a.g,119);for(g=0;g<a.i;++g){e=d[g];if(k.rl(e.ak())){if(c.Hc(h?e:e.dd())){return false}else{for(j=c.Kc();j.Ob();){i=j.Pb();BD(Gtd(a,g,h?BD(i,72):R6d(b,i)),72)}return true}}}if(!h){e=R6d(b,c.Kc().Pb());f.Fc(e)}}return ytd(a,f)} +function qMc(a,b){var c,d,e,f,g,h,i,j,k;k=new Psb;for(h=(j=(new $ib(a.c)).a.vc().Kc(),new djb(j));h.a.Ob();){f=(e=BD(h.a.Pb(),42),BD(e.dd(),458));f.b==0&&(Gsb(k,f,k.c.b,k.c),true)}while(k.b!=0){f=BD(k.b==0?null:(sCb(k.b!=0),Nsb(k,k.a.a)),458);f.a==null&&(f.a=0);for(d=new olb(f.d);d.a<d.c.c.length;){c=BD(mlb(d),654);c.b.a==null?(c.b.a=Edb(f.a)+c.a):b.o==(eMc(),cMc)?(c.b.a=$wnd.Math.min(Edb(c.b.a),Edb(f.a)+c.a)):(c.b.a=$wnd.Math.max(Edb(c.b.a),Edb(f.a)+c.a));--c.b.b;c.b.b==0&&Dsb(k,c.b)}}for(g=(i=(new $ib(a.c)).a.vc().Kc(),new djb(i));g.a.Ob();){f=(e=BD(g.a.Pb(),42),BD(e.dd(),458));b.i[f.c.p]=f.a}} +function mTc(){mTc=ccb;dTc=new Lsd(Ime);new Lsd(Jme);new Msd('DEPTH',meb(0));ZSc=new Msd('FAN',meb(0));XSc=new Msd(Yqe,meb(0));jTc=new Msd('ROOT',(Bcb(),false));_Sc=new Msd('LEFTNEIGHBOR',null);hTc=new Msd('RIGHTNEIGHBOR',null);aTc=new Msd('LEFTSIBLING',null);iTc=new Msd('RIGHTSIBLING',null);YSc=new Msd('DUMMY',false);new Msd('LEVEL',meb(0));gTc=new Msd('REMOVABLE_EDGES',new Psb);kTc=new Msd('XCOOR',meb(0));lTc=new Msd('YCOOR',meb(0));bTc=new Msd('LEVELHEIGHT',0);$Sc=new Msd('ID','');eTc=new Msd('POSITION',meb(0));fTc=new Msd('PRELIM',0);cTc=new Msd('MODIFIER',0);WSc=new Lsd(Kme);VSc=new Lsd(Lme)} +function MNc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o;k=c+b.c.c.a;for(n=new olb(b.j);n.a<n.c.c.length;){m=BD(mlb(n),11);e=l7c(OC(GC(m1,1),nie,8,0,[m.i.n,m.n,m.a]));if(b.k==(j0b(),i0b)){h=BD(vNb(m,(wtc(),$sc)),11);e.a=l7c(OC(GC(m1,1),nie,8,0,[h.i.n,h.n,h.a])).a;b.n.a=e.a}g=new f7c(0,e.b);if(m.j==(Ucd(),zcd)){g.a=k}else if(m.j==Tcd){g.a=c}else{continue}o=$wnd.Math.abs(e.a-g.a);if(o<=d&&!JNc(b)){continue}f=m.g.c.length+m.e.c.length>1;for(j=new b1b(m.b);llb(j.a)||llb(j.b);){i=BD(llb(j.a)?mlb(j.a):mlb(j.b),17);l=i.c==m?i.d:i.c;$wnd.Math.abs(l7c(OC(GC(m1,1),nie,8,0,[l.i.n,l.n,l.a])).b-g.b)>1&&GNc(a,i,g,f,m)}}} +function XPc(a){var b,c,d,e,f,g;e=new Bib(a.e,0);d=new Bib(a.a,0);if(a.d){for(c=0;c<a.b;c++){sCb(e.b<e.d.gc());e.d.Xb(e.c=e.b++)}}else{for(c=0;c<a.b-1;c++){sCb(e.b<e.d.gc());e.d.Xb(e.c=e.b++);uib(e)}}b=Edb((sCb(e.b<e.d.gc()),ED(e.d.Xb(e.c=e.b++))));while(a.f-b>Oqe){f=b;g=0;while($wnd.Math.abs(b-f)<Oqe){++g;b=Edb((sCb(e.b<e.d.gc()),ED(e.d.Xb(e.c=e.b++))));sCb(d.b<d.d.gc());d.d.Xb(d.c=d.b++)}if(g<a.b){sCb(e.b>0);e.a.Xb(e.c=--e.b);WPc(a,a.b-g,f,d,e);sCb(e.b<e.d.gc());e.d.Xb(e.c=e.b++)}sCb(d.b>0);d.a.Xb(d.c=--d.b)}if(!a.d){for(c=0;c<a.b-1;c++){sCb(e.b<e.d.gc());e.d.Xb(e.c=e.b++);uib(e)}}a.d=true;a.c=true} +function Q8d(){Q8d=ccb;s8d=(r8d(),q8d).b;v8d=BD(qud(ZKd(q8d.b),0),34);t8d=BD(qud(ZKd(q8d.b),1),34);u8d=BD(qud(ZKd(q8d.b),2),34);F8d=q8d.bb;BD(qud(ZKd(q8d.bb),0),34);BD(qud(ZKd(q8d.bb),1),34);H8d=q8d.fb;I8d=BD(qud(ZKd(q8d.fb),0),34);BD(qud(ZKd(q8d.fb),1),34);BD(qud(ZKd(q8d.fb),2),18);K8d=q8d.qb;N8d=BD(qud(ZKd(q8d.qb),0),34);BD(qud(ZKd(q8d.qb),1),18);BD(qud(ZKd(q8d.qb),2),18);L8d=BD(qud(ZKd(q8d.qb),3),34);M8d=BD(qud(ZKd(q8d.qb),4),34);P8d=BD(qud(ZKd(q8d.qb),6),34);O8d=BD(qud(ZKd(q8d.qb),5),18);w8d=q8d.j;x8d=q8d.k;y8d=q8d.q;z8d=q8d.w;A8d=q8d.B;B8d=q8d.A;C8d=q8d.C;D8d=q8d.D;E8d=q8d._;G8d=q8d.cb;J8d=q8d.hb} +function $Dc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;a.c=0;a.b=0;d=2*b.c.a.c.length+1;o:for(l=c.Kc();l.Ob();){k=BD(l.Pb(),11);h=k.j==(Ucd(),Acd)||k.j==Rcd;n=0;if(h){m=BD(vNb(k,(wtc(),gtc)),10);if(!m){continue}n+=VDc(a,d,k,m)}else{for(j=new olb(k.g);j.a<j.c.c.length;){i=BD(mlb(j),17);e=i.d;if(e.i.c==b.c){Ekb(a.a,k);continue o}else{n+=a.g[e.p]}}for(g=new olb(k.e);g.a<g.c.c.length;){f=BD(mlb(g),17);e=f.c;if(e.i.c==b.c){Ekb(a.a,k);continue o}else{n-=a.g[e.p]}}}if(k.e.c.length+k.g.c.length>0){a.f[k.p]=n/(k.e.c.length+k.g.c.length);a.c=$wnd.Math.min(a.c,a.f[k.p]);a.b=$wnd.Math.max(a.b,a.f[k.p])}else h&&(a.f[k.p]=n)}} +function $9d(a){a.b=null;a.bb=null;a.fb=null;a.qb=null;a.a=null;a.c=null;a.d=null;a.e=null;a.f=null;a.n=null;a.M=null;a.L=null;a.Q=null;a.R=null;a.K=null;a.db=null;a.eb=null;a.g=null;a.i=null;a.j=null;a.k=null;a.gb=null;a.o=null;a.p=null;a.q=null;a.r=null;a.$=null;a.ib=null;a.S=null;a.T=null;a.t=null;a.s=null;a.u=null;a.v=null;a.w=null;a.B=null;a.A=null;a.C=null;a.D=null;a.F=null;a.G=null;a.H=null;a.I=null;a.J=null;a.P=null;a.Z=null;a.U=null;a.V=null;a.W=null;a.X=null;a.Y=null;a._=null;a.ab=null;a.cb=null;a.hb=null;a.nb=null;a.lb=null;a.mb=null;a.ob=null;a.pb=null;a.jb=null;a.kb=null;a.N=false;a.O=false} +function l5b(a,b,c){var d,e,f,g;Odd(c,'Graph transformation ('+a.a+')',1);g=Mu(b.a);for(f=new olb(b.b);f.a<f.c.c.length;){e=BD(mlb(f),29);Gkb(g,e.a)}d=BD(vNb(b,(Nyc(),Mwc)),419);if(d==(xqc(),vqc)){switch(BD(vNb(b,Lwc),103).g){case 2:_4b(b,g);break;case 3:p5b(b,g);break;case 4:if(a.a==(y5b(),x5b)){p5b(b,g);a5b(b,g)}else{a5b(b,g);p5b(b,g)}}}else{if(a.a==(y5b(),x5b)){switch(BD(vNb(b,Lwc),103).g){case 2:_4b(b,g);a5b(b,g);break;case 3:p5b(b,g);_4b(b,g);break;case 4:_4b(b,g);p5b(b,g);}}else{switch(BD(vNb(b,Lwc),103).g){case 2:_4b(b,g);a5b(b,g);break;case 3:_4b(b,g);p5b(b,g);break;case 4:p5b(b,g);_4b(b,g);}}}Qdd(c)} +function j6b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;j=new zsb;k=new zsb;o=new zsb;p=new zsb;i=Edb(ED(vNb(b,(Nyc(),vyc))));f=Edb(ED(vNb(b,lyc)));for(h=new olb(c);h.a<h.c.c.length;){g=BD(mlb(h),10);l=BD(vNb(g,(wtc(),Hsc)),61);if(l==(Ucd(),Acd)){k.a.zc(g,k);for(e=new Sr(ur(R_b(g).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);Qqb(j,d.c.i)}}else if(l==Rcd){p.a.zc(g,p);for(e=new Sr(ur(R_b(g).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);Qqb(o,d.c.i)}}}if(j.a.gc()!=0){m=new tPc(2,f);n=sPc(m,b,j,k,-i-b.c.b);if(n>0){a.a=i+(n-1)*f;b.c.b+=a.a;b.f.b+=a.a}}if(o.a.gc()!=0){m=new tPc(1,f);n=sPc(m,b,o,p,b.f.b+i-b.c.b);n>0&&(b.f.b+=i+(n-1)*f)}} +function kKd(a,b){var c,d,e,f;f=a.F;if(b==null){a.F=null;$Jd(a,null)}else{a.F=(uCb(b),b);d=hfb(b,wfb(60));if(d!=-1){e=b.substr(0,d);hfb(b,wfb(46))==-1&&!dfb(e,Khe)&&!dfb(e,Eve)&&!dfb(e,Fve)&&!dfb(e,Gve)&&!dfb(e,Hve)&&!dfb(e,Ive)&&!dfb(e,Jve)&&!dfb(e,Kve)&&(e=Lve);c=kfb(b,wfb(62));c!=-1&&(e+=''+b.substr(c+1));$Jd(a,e)}else{e=b;if(hfb(b,wfb(46))==-1){d=hfb(b,wfb(91));d!=-1&&(e=b.substr(0,d));if(!dfb(e,Khe)&&!dfb(e,Eve)&&!dfb(e,Fve)&&!dfb(e,Gve)&&!dfb(e,Hve)&&!dfb(e,Ive)&&!dfb(e,Jve)&&!dfb(e,Kve)){e=Lve;d!=-1&&(e+=''+b.substr(d))}else{e=b}}$Jd(a,e);e==b&&(a.F=a.D)}}(a.Db&4)!=0&&(a.Db&1)==0&&Uhd(a,new nSd(a,1,5,f,b))} +function AMc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;p=b.b.c.length;if(p<3){return}n=KC(WD,oje,25,p,15,1);l=0;for(k=new olb(b.b);k.a<k.c.c.length;){j=BD(mlb(k),29);n[l++]=j.a.c.length}m=new Bib(b.b,2);for(d=1;d<p-1;d++){c=(sCb(m.b<m.d.gc()),BD(m.d.Xb(m.c=m.b++),29));o=new olb(c.a);f=0;h=0;for(i=0;i<n[d+1];i++){t=BD(mlb(o),10);if(i==n[d+1]-1||zMc(a,t,d+1,d)){g=n[d]-1;zMc(a,t,d+1,d)&&(g=a.c.e[BD(BD(BD(Ikb(a.c.b,t.p),15).Xb(0),46).a,10).p]);while(h<=i){s=BD(Ikb(c.a,h),10);if(!zMc(a,s,d+1,d)){for(r=BD(Ikb(a.c.b,s.p),15).Kc();r.Ob();){q=BD(r.Pb(),46);e=a.c.e[BD(q.a,10).p];(e<f||e>g)&&Qqb(a.b,BD(q.b,17))}}++h}f=g}}}} +function o5c(b,c){var d;if(c==null||dfb(c,Xhe)){return null}if(c.length==0&&b.k!=(_5c(),W5c)){return null}switch(b.k.g){case 1:return efb(c,kse)?(Bcb(),Acb):efb(c,lse)?(Bcb(),zcb):null;case 2:try{return meb(Icb(c,Rie,Ohe))}catch(a){a=ubb(a);if(JD(a,127)){return null}else throw vbb(a)}case 4:try{return Hcb(c)}catch(a){a=ubb(a);if(JD(a,127)){return null}else throw vbb(a)}case 3:return c;case 5:j5c(b);return m5c(b,c);case 6:j5c(b);return n5c(b,b.a,c);case 7:try{d=l5c(b);d.Jf(c);return d}catch(a){a=ubb(a);if(JD(a,32)){return null}else throw vbb(a)}default:throw vbb(new Zdb('Invalid type set for this layout option.'));}} +function JWb(a){AWb();var b,c,d,e,f,g,h;h=new CWb;for(c=new olb(a);c.a<c.c.c.length;){b=BD(mlb(c),140);(!h.b||b.c>=h.b.c)&&(h.b=b);if(!h.c||b.c<=h.c.c){h.d=h.c;h.c=b}(!h.e||b.d>=h.e.d)&&(h.e=b);(!h.f||b.d<=h.f.d)&&(h.f=b)}d=new NWb((lWb(),hWb));rXb(a,yWb,new amb(OC(GC(bQ,1),Uhe,369,0,[d])));g=new NWb(kWb);rXb(a,xWb,new amb(OC(GC(bQ,1),Uhe,369,0,[g])));e=new NWb(iWb);rXb(a,wWb,new amb(OC(GC(bQ,1),Uhe,369,0,[e])));f=new NWb(jWb);rXb(a,vWb,new amb(OC(GC(bQ,1),Uhe,369,0,[f])));DWb(d.c,hWb);DWb(e.c,iWb);DWb(f.c,jWb);DWb(g.c,kWb);h.a.c=KC(SI,Uhe,1,0,5,1);Gkb(h.a,d.c);Gkb(h.a,Su(e.c));Gkb(h.a,f.c);Gkb(h.a,Su(g.c));return h} +function jxd(a){var b;switch(a.d){case 1:{if(a.hj()){return a.o!=-2}break}case 2:{if(a.hj()){return a.o==-2}break}case 3:case 5:case 4:case 6:case 7:{return a.o>-2}default:{return false}}b=a.gj();switch(a.p){case 0:return b!=null&&Ccb(DD(b))!=Kbb(a.k,0);case 1:return b!=null&&BD(b,217).a!=Tbb(a.k)<<24>>24;case 2:return b!=null&&BD(b,172).a!=(Tbb(a.k)&aje);case 6:return b!=null&&Kbb(BD(b,162).a,a.k);case 5:return b!=null&&BD(b,19).a!=Tbb(a.k);case 7:return b!=null&&BD(b,184).a!=Tbb(a.k)<<16>>16;case 3:return b!=null&&Edb(ED(b))!=a.j;case 4:return b!=null&&BD(b,155).a!=a.j;default:return b==null?a.n!=null:!pb(b,a.n);}} +function nOd(a,b,c){var d,e,f,g;if(a.Fk()&&a.Ek()){g=oOd(a,BD(c,56));if(PD(g)!==PD(c)){a.Oi(b);a.Ui(b,pOd(a,b,g));if(a.rk()){f=(e=BD(c,49),a.Dk()?a.Bk()?e.ih(a.b,zUd(BD(XKd(wjd(a.b),a.aj()),18)).n,BD(XKd(wjd(a.b),a.aj()).Yj(),26).Bj(),null):e.ih(a.b,bLd(e.Tg(),zUd(BD(XKd(wjd(a.b),a.aj()),18))),null,null):e.ih(a.b,-1-a.aj(),null,null));!BD(g,49).eh()&&(f=(d=BD(g,49),a.Dk()?a.Bk()?d.gh(a.b,zUd(BD(XKd(wjd(a.b),a.aj()),18)).n,BD(XKd(wjd(a.b),a.aj()).Yj(),26).Bj(),f):d.gh(a.b,bLd(d.Tg(),zUd(BD(XKd(wjd(a.b),a.aj()),18))),null,f):d.gh(a.b,-1-a.aj(),null,f)));!!f&&f.Fi()}oid(a.b)&&a.$i(a.Zi(9,c,g,b,false));return g}}return c} +function Noc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;k=Edb(ED(vNb(a,(Nyc(),oyc))));d=Edb(ED(vNb(a,Cyc)));m=new _fd;yNb(m,oyc,k+d);j=b;r=j.d;p=j.c.i;s=j.d.i;q=G1b(p.c);t=G1b(s.c);e=new Rkb;for(l=q;l<=t;l++){h=new b0b(a);__b(h,(j0b(),g0b));yNb(h,(wtc(),$sc),j);yNb(h,Vxc,(dcd(),$bd));yNb(h,qyc,m);n=BD(Ikb(a.b,l),29);l==q?Z_b(h,n.a.c.length-c,n):$_b(h,n);u=Edb(ED(vNb(j,Zwc)));if(u<0){u=0;yNb(j,Zwc,u)}h.o.b=u;o=$wnd.Math.floor(u/2);g=new H0b;G0b(g,(Ucd(),Tcd));F0b(g,h);g.n.b=o;i=new H0b;G0b(i,zcd);F0b(i,h);i.n.b=o;RZb(j,g);f=new UZb;tNb(f,j);yNb(f,jxc,null);QZb(f,i);RZb(f,r);Ooc(h,j,f);e.c[e.c.length]=f;j=f}return e} +function sbc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;i=BD(Y_b(a,(Ucd(),Tcd)).Kc().Pb(),11).e;n=BD(Y_b(a,zcd).Kc().Pb(),11).g;h=i.c.length;t=A0b(BD(Ikb(a.j,0),11));while(h-->0){p=(tCb(0,i.c.length),BD(i.c[0],17));e=(tCb(0,n.c.length),BD(n.c[0],17));s=e.d.e;f=Jkb(s,e,0);SZb(p,e.d,f);QZb(e,null);RZb(e,null);o=p.a;b&&Dsb(o,new g7c(t));for(d=Jsb(e.a,0);d.b!=d.d.c;){c=BD(Xsb(d),8);Dsb(o,new g7c(c))}r=p.b;for(m=new olb(e.b);m.a<m.c.c.length;){l=BD(mlb(m),70);r.c[r.c.length]=l}q=BD(vNb(p,(Nyc(),jxc)),74);g=BD(vNb(e,jxc),74);if(g){if(!q){q=new s7c;yNb(p,jxc,q)}for(k=Jsb(g,0);k.b!=k.d.c;){j=BD(Xsb(k),8);Dsb(q,new g7c(j))}}}} +function EJb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;c=BD(Mpb(a.b,b),124);i=BD(BD(Qc(a.r,b),21),84);if(i.dc()){c.n.b=0;c.n.c=0;return}j=a.u.Hc((rcd(),ncd));g=0;h=i.Kc();k=null;l=0;m=0;while(h.Ob()){d=BD(h.Pb(),111);e=Edb(ED(d.b.We((CKb(),BKb))));f=d.b.rf().a;a.A.Hc((tdd(),sdd))&&KJb(a,b);if(!k){!!a.C&&a.C.b>0&&(g=$wnd.Math.max(g,IJb(a.C.b+d.d.b,e)))}else{n=m+k.d.c+a.w+d.d.b;g=$wnd.Math.max(g,(Iy(),My(ple),$wnd.Math.abs(l-e)<=ple||l==e||isNaN(l)&&isNaN(e)?0:n/(e-l)))}k=d;l=e;m=f}if(!!a.C&&a.C.c>0){n=m+a.C.c;j&&(n+=k.d.c);g=$wnd.Math.max(g,(Iy(),My(ple),$wnd.Math.abs(l-1)<=ple||l==1||isNaN(l)&&isNaN(1)?0:n/(1-l)))}c.n.b=0;c.a.a=g} +function NKb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;c=BD(Mpb(a.b,b),124);i=BD(BD(Qc(a.r,b),21),84);if(i.dc()){c.n.d=0;c.n.a=0;return}j=a.u.Hc((rcd(),ncd));g=0;a.A.Hc((tdd(),sdd))&&SKb(a,b);h=i.Kc();k=null;m=0;l=0;while(h.Ob()){d=BD(h.Pb(),111);f=Edb(ED(d.b.We((CKb(),BKb))));e=d.b.rf().b;if(!k){!!a.C&&a.C.d>0&&(g=$wnd.Math.max(g,IJb(a.C.d+d.d.d,f)))}else{n=l+k.d.a+a.w+d.d.d;g=$wnd.Math.max(g,(Iy(),My(ple),$wnd.Math.abs(m-f)<=ple||m==f||isNaN(m)&&isNaN(f)?0:n/(f-m)))}k=d;m=f;l=e}if(!!a.C&&a.C.a>0){n=l+a.C.a;j&&(n+=k.d.a);g=$wnd.Math.max(g,(Iy(),My(ple),$wnd.Math.abs(m-1)<=ple||m==1||isNaN(m)&&isNaN(1)?0:n/(1-m)))}c.n.d=0;c.a.b=g} +function _Ec(a,b,c){var d,e,f,g,h,i;this.g=a;h=b.d.length;i=c.d.length;this.d=KC(OQ,kne,10,h+i,0,1);for(g=0;g<h;g++){this.d[g]=b.d[g]}for(f=0;f<i;f++){this.d[h+f]=c.d[f]}if(b.e){this.e=Ru(b.e);this.e.Mc(c);if(c.e){for(e=c.e.Kc();e.Ob();){d=BD(e.Pb(),233);if(d==b){continue}else this.e.Hc(d)?--d.c:this.e.Fc(d)}}}else if(c.e){this.e=Ru(c.e);this.e.Mc(b)}this.f=b.f+c.f;this.a=b.a+c.a;this.a>0?ZEc(this,this.f/this.a):REc(b.g,b.d[0]).a!=null&&REc(c.g,c.d[0]).a!=null?ZEc(this,(Edb(REc(b.g,b.d[0]).a)+Edb(REc(c.g,c.d[0]).a))/2):REc(b.g,b.d[0]).a!=null?ZEc(this,REc(b.g,b.d[0]).a):REc(c.g,c.d[0]).a!=null&&ZEc(this,REc(c.g,c.d[0]).a)} +function BUb(a,b){var c,d,e,f,g,h,i,j,k,l;a.a=new dVb(oqb(t1));for(d=new olb(b.a);d.a<d.c.c.length;){c=BD(mlb(d),841);h=new gVb(OC(GC(IP,1),Uhe,81,0,[]));Ekb(a.a.a,h);for(j=new olb(c.d);j.a<j.c.c.length;){i=BD(mlb(j),110);k=new GUb(a,i);AUb(k,BD(vNb(c.c,(wtc(),Esc)),21));if(!Mhb(a.g,c)){Rhb(a.g,c,new f7c(i.c,i.d));Rhb(a.f,c,k)}Ekb(a.a.b,k);eVb(h,k)}for(g=new olb(c.b);g.a<g.c.c.length;){f=BD(mlb(g),594);k=new GUb(a,f.kf());Rhb(a.b,f,new vgd(h,k));AUb(k,BD(vNb(c.c,(wtc(),Esc)),21));if(f.hf()){l=new HUb(a,f.hf(),1);AUb(l,BD(vNb(c.c,Esc),21));e=new gVb(OC(GC(IP,1),Uhe,81,0,[]));eVb(e,l);Rc(a.c,f.gf(),new vgd(h,l))}}}return a.a} +function oBc(a){var b;this.a=a;b=(j0b(),OC(GC(NQ,1),Kie,267,0,[h0b,g0b,e0b,i0b,f0b,d0b])).length;this.b=IC(Q3,[nie,zqe],[593,146],0,[b,b],2);this.c=IC(Q3,[nie,zqe],[593,146],0,[b,b],2);nBc(this,h0b,(Nyc(),vyc),wyc);lBc(this,h0b,g0b,oyc,pyc);kBc(this,h0b,i0b,oyc);kBc(this,h0b,e0b,oyc);lBc(this,h0b,f0b,vyc,wyc);nBc(this,g0b,lyc,myc);kBc(this,g0b,i0b,lyc);kBc(this,g0b,e0b,lyc);lBc(this,g0b,f0b,oyc,pyc);mBc(this,i0b,lyc);kBc(this,i0b,e0b,lyc);kBc(this,i0b,f0b,syc);mBc(this,e0b,zyc);lBc(this,e0b,f0b,uyc,tyc);nBc(this,f0b,lyc,lyc);nBc(this,d0b,lyc,myc);lBc(this,d0b,h0b,oyc,pyc);lBc(this,d0b,f0b,oyc,pyc);lBc(this,d0b,g0b,oyc,pyc)} +function _2d(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q;g=c.ak();if(JD(g,99)&&(BD(g,18).Bb&Tje)!=0){m=BD(c.dd(),49);p=xid(a.e,m);if(p!=m){k=R6d(g,p);mud(a,b,t3d(a,b,k));l=null;if(oid(a.e)){d=e1d((O6d(),M6d),a.e.Tg(),g);if(d!=XKd(a.e.Tg(),a.c)){q=S6d(a.e.Tg(),g);h=0;f=BD(a.g,119);for(i=0;i<b;++i){e=f[i];q.rl(e.ak())&&++h}l=new O7d(a.e,9,d,m,p,h,false);l.Ei(new pSd(a.e,9,a.c,c,k,b,false))}}o=BD(g,18);n=zUd(o);if(n){l=m.ih(a.e,bLd(m.Tg(),n),null,l);l=BD(p,49).gh(a.e,bLd(p.Tg(),n),null,l)}else if((o.Bb&ote)!=0){j=-1-bLd(a.e.Tg(),o);l=m.ih(a.e,j,null,null);!BD(p,49).eh()&&(l=BD(p,49).gh(a.e,j,null,l))}!!l&&l.Fi();return k}}return c} +function yUb(a){var b,c,d,e,f,g,h,i;for(f=new olb(a.a.b);f.a<f.c.c.length;){e=BD(mlb(f),81);e.b.c=e.g.c;e.b.d=e.g.d}i=new f7c(Pje,Pje);b=new f7c(Qje,Qje);for(d=new olb(a.a.b);d.a<d.c.c.length;){c=BD(mlb(d),81);i.a=$wnd.Math.min(i.a,c.g.c);i.b=$wnd.Math.min(i.b,c.g.d);b.a=$wnd.Math.max(b.a,c.g.c+c.g.b);b.b=$wnd.Math.max(b.b,c.g.d+c.g.a)}for(h=Uc(a.c).a.nc();h.Ob();){g=BD(h.Pb(),46);c=BD(g.b,81);i.a=$wnd.Math.min(i.a,c.g.c);i.b=$wnd.Math.min(i.b,c.g.d);b.a=$wnd.Math.max(b.a,c.g.c+c.g.b);b.b=$wnd.Math.max(b.b,c.g.d+c.g.a)}a.d=V6c(new f7c(i.a,i.b));a.e=c7c(new f7c(b.a,b.b),i);a.a.a.c=KC(SI,Uhe,1,0,5,1);a.a.b.c=KC(SI,Uhe,1,0,5,1)} +function svd(a){var b,c,d;l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new Z9c]));c=new xB(a);for(d=0;d<c.a.length;++d){b=tB(c,d).je().a;dfb(b,'layered')?l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new kwc])):dfb(b,'force')?l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new TRb])):dfb(b,'stress')?l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new PSb])):dfb(b,'mrtree')?l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new sTc])):dfb(b,'radial')?l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new IWc])):dfb(b,'disco')?l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new gFb,new oPb])):dfb(b,'sporeOverlap')||dfb(b,'sporeCompaction')?l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new B0c])):dfb(b,'rectpacking')&&l4c(lvd,OC(GC(C0,1),Uhe,130,0,[new PYc]))}} +function j_b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;m=new g7c(a.o);r=b.a/m.a;h=b.b/m.b;p=b.a-m.a;f=b.b-m.b;if(c){e=PD(vNb(a,(Nyc(),Vxc)))===PD((dcd(),$bd));for(o=new olb(a.j);o.a<o.c.c.length;){n=BD(mlb(o),11);switch(n.j.g){case 1:e||(n.n.a*=r);break;case 2:n.n.a+=p;e||(n.n.b*=h);break;case 3:e||(n.n.a*=r);n.n.b+=f;break;case 4:e||(n.n.b*=h);}}}for(j=new olb(a.b);j.a<j.c.c.length;){i=BD(mlb(j),70);k=i.n.a+i.o.a/2;l=i.n.b+i.o.b/2;q=k/m.a;g=l/m.b;if(q+g>=1){if(q-g>0&&l>=0){i.n.a+=p;i.n.b+=f*g}else if(q-g<0&&k>=0){i.n.a+=p*q;i.n.b+=f}}}a.o.a=b.a;a.o.b=b.b;yNb(a,(Nyc(),Fxc),(tdd(),d=BD(gdb(I1),9),new xqb(d,BD(_Bb(d,d.length),9),0)))} +function iFd(a,b,c,d,e,f){var g;if(!(b==null||!OEd(b,zEd,AEd))){throw vbb(new Wdb('invalid scheme: '+b))}if(!a&&!(c!=null&&hfb(c,wfb(35))==-1&&c.length>0&&(BCb(0,c.length),c.charCodeAt(0)!=47))){throw vbb(new Wdb('invalid opaquePart: '+c))}if(a&&!(b!=null&&hnb(GEd,b.toLowerCase()))&&!(c==null||!OEd(c,CEd,DEd))){throw vbb(new Wdb(mve+c))}if(a&&b!=null&&hnb(GEd,b.toLowerCase())&&!eFd(c)){throw vbb(new Wdb(mve+c))}if(!fFd(d)){throw vbb(new Wdb('invalid device: '+d))}if(!hFd(e)){g=e==null?'invalid segments: null':'invalid segment: '+VEd(e);throw vbb(new Wdb(g))}if(!(f==null||hfb(f,wfb(35))==-1)){throw vbb(new Wdb('invalid query: '+f))}} +function nVc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;Odd(b,'Calculate Graph Size',1);b.n&&!!a&&Tdd(b,i6d(a),(pgd(),mgd));h=dme;i=dme;f=ere;g=ere;for(l=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));l.e!=l.i.gc();){j=BD(Dyd(l),33);o=j.i;p=j.j;r=j.g;d=j.f;e=BD(hkd(j,(Y9c(),S8c)),142);h=$wnd.Math.min(h,o-e.b);i=$wnd.Math.min(i,p-e.d);f=$wnd.Math.max(f,o+r+e.c);g=$wnd.Math.max(g,p+d+e.a)}n=BD(hkd(a,(Y9c(),f9c)),116);m=new f7c(h-n.b,i-n.d);for(k=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));k.e!=k.i.gc();){j=BD(Dyd(k),33);dld(j,j.i-m.a);eld(j,j.j-m.b)}q=f-h+(n.b+n.c);c=g-i+(n.d+n.a);cld(a,q);ald(a,c);b.n&&!!a&&Tdd(b,i6d(a),(pgd(),mgd))} +function rGb(a){var b,c,d,e,f,g,h,i,j,k;d=new Rkb;for(g=new olb(a.e.a);g.a<g.c.c.length;){e=BD(mlb(g),121);k=0;e.k.c=KC(SI,Uhe,1,0,5,1);for(c=new olb(LFb(e));c.a<c.c.c.length;){b=BD(mlb(c),213);if(b.f){Ekb(e.k,b);++k}}k==1&&(d.c[d.c.length]=e,true)}for(f=new olb(d);f.a<f.c.c.length;){e=BD(mlb(f),121);while(e.k.c.length==1){j=BD(mlb(new olb(e.k)),213);a.b[j.c]=j.g;h=j.d;i=j.e;for(c=new olb(LFb(e));c.a<c.c.c.length;){b=BD(mlb(c),213);pb(b,j)||(b.f?h==b.d||i==b.e?(a.b[j.c]-=a.b[b.c]-b.g):(a.b[j.c]+=a.b[b.c]-b.g):e==h?b.d==e?(a.b[j.c]+=b.g):(a.b[j.c]-=b.g):b.d==e?(a.b[j.c]-=b.g):(a.b[j.c]+=b.g))}Lkb(h.k,j);Lkb(i.k,j);h==e?(e=j.e):(e=j.d)}}} +function k4c(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;if(b==null||b.length==0){return null}f=BD(Phb(a.f,b),23);if(!f){for(e=(n=(new $ib(a.d)).a.vc().Kc(),new djb(n));e.a.Ob();){c=(g=BD(e.a.Pb(),42),BD(g.dd(),23));h=c.f;o=b.length;if(dfb(h.substr(h.length-o,o),b)&&(b.length==h.length||bfb(h,h.length-b.length-1)==46)){if(f){return null}f=c}}if(!f){for(d=(m=(new $ib(a.d)).a.vc().Kc(),new djb(m));d.a.Ob();){c=(g=BD(d.a.Pb(),42),BD(g.dd(),23));l=c.g;if(l!=null){for(i=l,j=0,k=i.length;j<k;++j){h=i[j];o=b.length;if(dfb(h.substr(h.length-o,o),b)&&(b.length==h.length||bfb(h,h.length-b.length-1)==46)){if(f){return null}f=c}}}}}!!f&&Shb(a.f,b,f)}return f} +function sA(a,b){var c,d,e,f,g;c=new Vfb;g=false;for(f=0;f<b.length;f++){d=(BCb(f,b.length),b.charCodeAt(f));if(d==32){gA(a,c,0);c.a+=' ';gA(a,c,0);while(f+1<b.length&&(BCb(f+1,b.length),b.charCodeAt(f+1)==32)){++f}continue}if(g){if(d==39){if(f+1<b.length&&(BCb(f+1,b.length),b.charCodeAt(f+1)==39)){c.a+=String.fromCharCode(d);++f}else{g=false}}else{c.a+=String.fromCharCode(d)}continue}if(hfb('GyMLdkHmsSEcDahKzZv',wfb(d))>0){gA(a,c,0);c.a+=String.fromCharCode(d);e=lA(b,f);gA(a,c,e);f+=e-1;continue}if(d==39){if(f+1<b.length&&(BCb(f+1,b.length),b.charCodeAt(f+1)==39)){c.a+="'";++f}else{g=true}}else{c.a+=String.fromCharCode(d)}}gA(a,c,0);mA(a)} +function wDc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;Odd(c,'Network simplex layering',1);a.b=b;r=BD(vNb(b,(Nyc(),Ayc)),19).a*4;q=a.b.a;if(q.c.length<1){Qdd(c);return}f=sDc(a,q);p=null;for(e=Jsb(f,0);e.b!=e.d.c;){d=BD(Xsb(e),15);h=r*QD($wnd.Math.sqrt(d.gc()));g=vDc(d);uGb(HGb(JGb(IGb(LGb(g),h),p),true),Udd(c,1));m=a.b.b;for(o=new olb(g.a);o.a<o.c.c.length;){n=BD(mlb(o),121);while(m.c.length<=n.e){Dkb(m,m.c.length,new H1b(a.b))}k=BD(n.f,10);$_b(k,BD(Ikb(m,n.e),29))}if(f.b>1){p=KC(WD,oje,25,a.b.b.c.length,15,1);l=0;for(j=new olb(a.b.b);j.a<j.c.c.length;){i=BD(mlb(j),29);p[l++]=i.a.c.length}}}q.c=KC(SI,Uhe,1,0,5,1);a.a=null;a.b=null;a.c=null;Qdd(c)} +function OUb(a){var b,c,d,e,f,g,h;b=0;for(f=new olb(a.b.a);f.a<f.c.c.length;){d=BD(mlb(f),189);d.b=0;d.c=0}NUb(a,0);MUb(a,a.g);sVb(a.c);wVb(a.c);c=(ead(),aad);uVb(oVb(tVb(uVb(oVb(tVb(uVb(tVb(a.c,c)),had(c)))),c)));tVb(a.c,aad);RUb(a,a.g);SUb(a,0);TUb(a,0);UUb(a,1);NUb(a,1);MUb(a,a.d);sVb(a.c);for(g=new olb(a.b.a);g.a<g.c.c.length;){d=BD(mlb(g),189);b+=$wnd.Math.abs(d.c)}for(h=new olb(a.b.a);h.a<h.c.c.length;){d=BD(mlb(h),189);d.b=0;d.c=0}c=dad;uVb(oVb(tVb(uVb(oVb(tVb(uVb(wVb(tVb(a.c,c))),had(c)))),c)));tVb(a.c,aad);RUb(a,a.d);SUb(a,1);TUb(a,1);UUb(a,0);wVb(a.c);for(e=new olb(a.b.a);e.a<e.c.c.length;){d=BD(mlb(e),189);b+=$wnd.Math.abs(d.c)}return b} +function Wfe(a,b){var c,d,e,f,g,h,i,j,k;j=b;if(j.b==null||a.b==null)return;Yfe(a);Vfe(a);Yfe(j);Vfe(j);c=KC(WD,oje,25,a.b.length+j.b.length,15,1);k=0;d=0;g=0;while(d<a.b.length&&g<j.b.length){e=a.b[d];f=a.b[d+1];h=j.b[g];i=j.b[g+1];if(f<h){d+=2}else if(f>=h&&e<=i){if(h<=e&&f<=i){c[k++]=e;c[k++]=f;d+=2}else if(h<=e){c[k++]=e;c[k++]=i;a.b[d]=i+1;g+=2}else if(f<=i){c[k++]=h;c[k++]=f;d+=2}else{c[k++]=h;c[k++]=i;a.b[d]=i+1}}else if(i<e){g+=2}else{throw vbb(new hz('Token#intersectRanges(): Internal Error: ['+a.b[d]+','+a.b[d+1]+'] & ['+j.b[g]+','+j.b[g+1]+']'))}}while(d<a.b.length){c[k++]=a.b[d++];c[k++]=a.b[d++]}a.b=KC(WD,oje,25,k,15,1);$fb(c,0,a.b,0,k)} +function PUb(a){var b,c,d,e,f,g,h;b=new Rkb;a.g=new Rkb;a.d=new Rkb;for(g=new nib((new eib(a.f.b)).a);g.b;){f=lib(g);Ekb(b,BD(BD(f.dd(),46).b,81));fad(BD(f.cd(),594).gf())?Ekb(a.d,BD(f.dd(),46)):Ekb(a.g,BD(f.dd(),46))}MUb(a,a.d);MUb(a,a.g);a.c=new CVb(a.b);AVb(a.c,(xUb(),wUb));RUb(a,a.d);RUb(a,a.g);Gkb(b,a.c.a.b);a.e=new f7c(Pje,Pje);a.a=new f7c(Qje,Qje);for(d=new olb(b);d.a<d.c.c.length;){c=BD(mlb(d),81);a.e.a=$wnd.Math.min(a.e.a,c.g.c);a.e.b=$wnd.Math.min(a.e.b,c.g.d);a.a.a=$wnd.Math.max(a.a.a,c.g.c+c.g.b);a.a.b=$wnd.Math.max(a.a.b,c.g.d+c.g.a)}zVb(a.c,new YUb);h=0;do{e=OUb(a);++h}while((h<2||e>Qie)&&h<10);zVb(a.c,new _Ub);OUb(a);vVb(a.c);yUb(a.f)} +function sZb(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q;if(!Ccb(DD(vNb(c,(Nyc(),fxc))))){return}for(h=new olb(c.j);h.a<h.c.c.length;){g=BD(mlb(h),11);m=k_b(g.g);for(j=m,k=0,l=j.length;k<l;++k){i=j[k];f=i.d.i==c;e=f&&Ccb(DD(vNb(i,gxc)));if(e){o=i.c;n=BD(Ohb(a.b,o),10);if(!n){n=Z$b(o,(dcd(),bcd),o.j,-1,null,null,o.o,BD(vNb(b,Lwc),103),b);yNb(n,(wtc(),$sc),o);Rhb(a.b,o,n);Ekb(b.a,n)}q=i.d;p=BD(Ohb(a.b,q),10);if(!p){p=Z$b(q,(dcd(),bcd),q.j,1,null,null,q.o,BD(vNb(b,Lwc),103),b);yNb(p,(wtc(),$sc),q);Rhb(a.b,q,p);Ekb(b.a,p)}d=kZb(i);QZb(d,BD(Ikb(n.j,0),11));RZb(d,BD(Ikb(p.j,0),11));Rc(a.a,i,new BZb(d,b,(KAc(),IAc)));BD(vNb(b,(wtc(),Ksc)),21).Fc((Orc(),Hrc))}}}} +function W9b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o;Odd(c,'Label dummy switching',1);d=BD(vNb(b,(Nyc(),Owc)),227);J9b(b);e=T9b(b,d);a.a=KC(UD,Vje,25,b.b.c.length,15,1);for(h=(Apc(),OC(GC(EW,1),Kie,227,0,[wpc,ypc,vpc,xpc,zpc,upc])),k=0,n=h.length;k<n;++k){f=h[k];if((f==zpc||f==upc||f==xpc)&&!BD(uqb(e.a,f)?e.b[f.g]:null,15).dc()){M9b(a,b);break}}for(i=OC(GC(EW,1),Kie,227,0,[wpc,ypc,vpc,xpc,zpc,upc]),l=0,o=i.length;l<o;++l){f=i[l];f==zpc||f==upc||f==xpc||X9b(a,BD(uqb(e.a,f)?e.b[f.g]:null,15))}for(g=OC(GC(EW,1),Kie,227,0,[wpc,ypc,vpc,xpc,zpc,upc]),j=0,m=g.length;j<m;++j){f=g[j];(f==zpc||f==upc||f==xpc)&&X9b(a,BD(uqb(e.a,f)?e.b[f.g]:null,15))}a.a=null;Qdd(c)} +function AFc(a,b){var c,d,e,f,g,h,i,j,k,l,m;switch(a.k.g){case 1:d=BD(vNb(a,(wtc(),$sc)),17);c=BD(vNb(d,_sc),74);!c?(c=new s7c):Ccb(DD(vNb(d,ltc)))&&(c=w7c(c));j=BD(vNb(a,Vsc),11);if(j){k=l7c(OC(GC(m1,1),nie,8,0,[j.i.n,j.n,j.a]));if(b<=k.a){return k.b}Gsb(c,k,c.a,c.a.a)}l=BD(vNb(a,Wsc),11);if(l){m=l7c(OC(GC(m1,1),nie,8,0,[l.i.n,l.n,l.a]));if(m.a<=b){return m.b}Gsb(c,m,c.c.b,c.c)}if(c.b>=2){i=Jsb(c,0);g=BD(Xsb(i),8);h=BD(Xsb(i),8);while(h.a<b&&i.b!=i.d.c){g=h;h=BD(Xsb(i),8)}return g.b+(b-g.a)/(h.a-g.a)*(h.b-g.b)}break;case 3:f=BD(vNb(BD(Ikb(a.j,0),11),(wtc(),$sc)),11);e=f.i;switch(f.j.g){case 1:return e.n.b;case 3:return e.n.b+e.o.b;}}return T_b(a).b} +function Wgc(a){var b,c,d,e,f,g,h,i,j,k,l;for(g=new olb(a.d.b);g.a<g.c.c.length;){f=BD(mlb(g),29);for(i=new olb(f.a);i.a<i.c.c.length;){h=BD(mlb(i),10);if(Ccb(DD(vNb(h,(Nyc(),pwc))))){if(!Qq(O_b(h))){d=BD(Oq(O_b(h)),17);k=d.c.i;k==h&&(k=d.d.i);l=new vgd(k,c7c(R6c(h.n),k.n));Rhb(a.b,h,l);continue}}e=new J6c(h.n.a-h.d.b,h.n.b-h.d.d,h.o.a+h.d.b+h.d.c,h.o.b+h.d.d+h.d.a);b=vDb(yDb(wDb(xDb(new zDb,h),e),Fgc),a.a);pDb(qDb(rDb(new sDb,OC(GC(PM,1),Uhe,57,0,[b])),b),a.a);j=new lEb;Rhb(a.e,b,j);c=sr(new Sr(ur(R_b(h).a.Kc(),new Sq)))-sr(new Sr(ur(U_b(h).a.Kc(),new Sq)));c<0?jEb(j,true,(ead(),aad)):c>0&&jEb(j,true,(ead(),bad));h.k==(j0b(),e0b)&&kEb(j);Rhb(a.f,h,b)}}} +function Bbc(a,b,c){var d,e,f,g,h,i,j,k,l,m;Odd(c,'Node promotion heuristic',1);a.g=b;Abc(a);a.q=BD(vNb(b,(Nyc(),rxc)),260);k=BD(vNb(a.g,qxc),19).a;f=new Jbc;switch(a.q.g){case 2:case 1:Dbc(a,f);break;case 3:a.q=(kAc(),jAc);Dbc(a,f);i=0;for(h=new olb(a.a);h.a<h.c.c.length;){g=BD(mlb(h),19);i=$wnd.Math.max(i,g.a)}if(i>a.j){a.q=dAc;Dbc(a,f)}break;case 4:a.q=(kAc(),jAc);Dbc(a,f);j=0;for(e=new olb(a.b);e.a<e.c.c.length;){d=ED(mlb(e));j=$wnd.Math.max(j,(uCb(d),d))}if(j>a.k){a.q=gAc;Dbc(a,f)}break;case 6:m=QD($wnd.Math.ceil(a.f.length*k/100));Dbc(a,new Mbc(m));break;case 5:l=QD($wnd.Math.ceil(a.d*k/100));Dbc(a,new Pbc(l));break;default:Dbc(a,f);}Ebc(a,b);Qdd(c)} +function fFc(a,b,c){var d,e,f,g;this.j=a;this.e=WZb(a);this.o=this.j.e;this.i=!!this.o;this.p=this.i?BD(Ikb(c,Q_b(this.o).p),214):null;e=BD(vNb(a,(wtc(),Ksc)),21);this.g=e.Hc((Orc(),Hrc));this.b=new Rkb;this.d=new rHc(this.e);g=BD(vNb(this.j,jtc),230);this.q=wFc(b,g,this.e);this.k=new BGc(this);f=Ou(OC(GC(qY,1),Uhe,225,0,[this,this.d,this.k,this.q]));if(b==(rGc(),oGc)&&!Ccb(DD(vNb(a,(Nyc(),Awc))))){d=new SEc(this.e);f.c[f.c.length]=d;this.c=new uEc(d,g,BD(this.q,402))}else if(b==oGc&&Ccb(DD(vNb(a,(Nyc(),Awc))))){d=new SEc(this.e);f.c[f.c.length]=d;this.c=new XGc(d,g,BD(this.q,402))}else{this.c=new Oic(b,this)}Ekb(f,this.c);$Ic(f,this.e);this.s=AGc(this.k)} +function xUc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;l=BD(pr((g=Jsb((new ZRc(b)).a.d,0),new aSc(g))),86);o=l?BD(vNb(l,(mTc(),_Sc)),86):null;e=1;while(!!l&&!!o){i=0;u=0;c=l;d=o;for(h=0;h<e;h++){c=VRc(c);d=VRc(d);u+=Edb(ED(vNb(c,(mTc(),cTc))));i+=Edb(ED(vNb(d,cTc)))}t=Edb(ED(vNb(o,(mTc(),fTc))));s=Edb(ED(vNb(l,fTc)));m=zUc(l,o);n=t+i+a.a+m-s-u;if(0<n){j=b;k=0;while(!!j&&j!=d){++k;j=BD(vNb(j,aTc),86)}if(j){r=n/k;j=b;while(j!=d){q=Edb(ED(vNb(j,fTc)))+n;yNb(j,fTc,q);p=Edb(ED(vNb(j,cTc)))+n;yNb(j,cTc,p);n-=r;j=BD(vNb(j,aTc),86)}}else{return}}++e;l.d.b==0?(l=JRc(new ZRc(b),e)):(l=BD(pr((f=Jsb((new ZRc(l)).a.d,0),new aSc(f))),86));o=l?BD(vNb(l,_Sc),86):null}} +function Cbc(a,b){var c,d,e,f,g,h,i,j,k,l;i=true;e=0;j=a.f[b.p];k=b.o.b+a.n;c=a.c[b.p][2];Nkb(a.a,j,meb(BD(Ikb(a.a,j),19).a-1+c));Nkb(a.b,j,Edb(ED(Ikb(a.b,j)))-k+c*a.e);++j;if(j>=a.i){++a.i;Ekb(a.a,meb(1));Ekb(a.b,k)}else{d=a.c[b.p][1];Nkb(a.a,j,meb(BD(Ikb(a.a,j),19).a+1-d));Nkb(a.b,j,Edb(ED(Ikb(a.b,j)))+k-d*a.e)}(a.q==(kAc(),dAc)&&(BD(Ikb(a.a,j),19).a>a.j||BD(Ikb(a.a,j-1),19).a>a.j)||a.q==gAc&&(Edb(ED(Ikb(a.b,j)))>a.k||Edb(ED(Ikb(a.b,j-1)))>a.k))&&(i=false);for(g=new Sr(ur(R_b(b).a.Kc(),new Sq));Qr(g);){f=BD(Rr(g),17);h=f.c.i;if(a.f[h.p]==j){l=Cbc(a,h);e=e+BD(l.a,19).a;i=i&&Ccb(DD(l.b))}}a.f[b.p]=j;e=e+a.c[b.p][0];return new vgd(meb(e),(Bcb(),i?true:false))} +function sPc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r;l=new Lqb;g=new Rkb;qPc(a,c,a.d.fg(),g,l);qPc(a,d,a.d.gg(),g,l);a.b=0.2*(p=rPc(LAb(new YAb(null,new Kub(g,16)),new xPc)),q=rPc(LAb(new YAb(null,new Kub(g,16)),new zPc)),$wnd.Math.min(p,q));f=0;for(h=0;h<g.c.length-1;h++){i=(tCb(h,g.c.length),BD(g.c[h],112));for(o=h+1;o<g.c.length;o++){f+=pPc(a,i,(tCb(o,g.c.length),BD(g.c[o],112)))}}m=BD(vNb(b,(wtc(),jtc)),230);f>=2&&(r=WNc(g,true,m),!a.e&&(a.e=new ZOc(a)),VOc(a.e,r,g,a.b),undefined);uPc(g,m);wPc(g);n=-1;for(k=new olb(g);k.a<k.c.c.length;){j=BD(mlb(k),112);if($wnd.Math.abs(j.s-j.c)<qme){continue}n=$wnd.Math.max(n,j.o);a.d.dg(j,e,a.c)}a.d.a.a.$b();return n+1} +function aUb(a,b){var c,d,e,f,g;c=Edb(ED(vNb(b,(Nyc(),lyc))));c<2&&yNb(b,lyc,2);d=BD(vNb(b,Lwc),103);d==(ead(),cad)&&yNb(b,Lwc,a_b(b));e=BD(vNb(b,fyc),19);e.a==0?yNb(b,(wtc(),jtc),new Gub):yNb(b,(wtc(),jtc),new Hub(e.a));f=DD(vNb(b,Axc));f==null&&yNb(b,Axc,(Bcb(),PD(vNb(b,Swc))===PD((Aad(),wad))?true:false));MAb(new YAb(null,new Kub(b.a,16)),new dUb(a));MAb(LAb(new YAb(null,new Kub(b.b,16)),new fUb),new hUb(a));g=new oBc(b);yNb(b,(wtc(),otc),g);H2c(a.a);K2c(a.a,(qUb(),lUb),BD(vNb(b,Jwc),246));K2c(a.a,mUb,BD(vNb(b,sxc),246));K2c(a.a,nUb,BD(vNb(b,Iwc),246));K2c(a.a,oUb,BD(vNb(b,Exc),246));K2c(a.a,pUb,kNc(BD(vNb(b,Swc),218)));E2c(a.a,_Tb(b));yNb(b,itc,F2c(a.a,b))} +function fjc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(m=a.c[b],n=a.c[c],(o=BD(vNb(m,(wtc(),Qsc)),15),!!o&&o.gc()!=0&&o.Hc(n))||(p=m.k!=(j0b(),g0b)&&n.k!=g0b,q=BD(vNb(m,Psc),10),r=BD(vNb(n,Psc),10),s=q!=r,t=!!q&&q!=m||!!r&&r!=n,u=gjc(m,(Ucd(),Acd)),v=gjc(n,Rcd),t=t|(gjc(m,Rcd)||gjc(n,Acd)),w=t&&s||u||v,p&&w)||m.k==(j0b(),i0b)&&n.k==h0b||n.k==(j0b(),i0b)&&m.k==h0b){return false}k=a.c[b];f=a.c[c];e=LHc(a.e,k,f,(Ucd(),Tcd));i=LHc(a.i,k,f,zcd);Yic(a.f,k,f);j=Hic(a.b,k,f)+BD(e.a,19).a+BD(i.a,19).a+a.f.d;h=Hic(a.b,f,k)+BD(e.b,19).a+BD(i.b,19).a+a.f.b;if(a.a){l=BD(vNb(k,$sc),11);g=BD(vNb(f,$sc),11);d=JHc(a.g,l,g);j+=BD(d.a,19).a;h+=BD(d.b,19).a}return j>h} +function k6b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;c=BD(vNb(a,(Nyc(),Vxc)),98);g=a.f;f=a.d;h=g.a+f.b+f.c;i=0-f.d-a.c.b;k=g.b+f.d+f.a-a.c.b;j=new Rkb;l=new Rkb;for(e=new olb(b);e.a<e.c.c.length;){d=BD(mlb(e),10);switch(c.g){case 1:case 2:case 3:a6b(d);break;case 4:m=BD(vNb(d,Txc),8);n=!m?0:m.a;d.n.a=h*Edb(ED(vNb(d,(wtc(),htc))))-n;M_b(d,true,false);break;case 5:o=BD(vNb(d,Txc),8);p=!o?0:o.a;d.n.a=Edb(ED(vNb(d,(wtc(),htc))))-p;M_b(d,true,false);g.a=$wnd.Math.max(g.a,d.n.a+d.o.a/2);}switch(BD(vNb(d,(wtc(),Hsc)),61).g){case 1:d.n.b=i;j.c[j.c.length]=d;break;case 3:d.n.b=k;l.c[l.c.length]=d;}}switch(c.g){case 1:case 2:c6b(j,a);c6b(l,a);break;case 3:i6b(j,a);i6b(l,a);}} +function VHc(a,b){var c,d,e,f,g,h,i,j,k,l;k=new Rkb;l=new jkb;f=null;e=0;for(d=0;d<b.length;++d){c=b[d];XHc(f,c)&&(e=QHc(a,l,k,EHc,e));wNb(c,(wtc(),Psc))&&(f=BD(vNb(c,Psc),10));switch(c.k.g){case 0:for(i=Vq(Nq(V_b(c,(Ucd(),Acd)),new GIc));xc(i);){g=BD(yc(i),11);a.d[g.p]=e++;k.c[k.c.length]=g}e=QHc(a,l,k,EHc,e);for(j=Vq(Nq(V_b(c,Rcd),new GIc));xc(j);){g=BD(yc(j),11);a.d[g.p]=e++;k.c[k.c.length]=g}break;case 3:if(!V_b(c,DHc).dc()){g=BD(V_b(c,DHc).Xb(0),11);a.d[g.p]=e++;k.c[k.c.length]=g}V_b(c,EHc).dc()||Wjb(l,c);break;case 1:for(h=V_b(c,(Ucd(),Tcd)).Kc();h.Ob();){g=BD(h.Pb(),11);a.d[g.p]=e++;k.c[k.c.length]=g}V_b(c,zcd).Jc(new EIc(l,c));}}QHc(a,l,k,EHc,e);return k} +function y$c(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;j=Pje;k=Pje;h=Qje;i=Qje;for(m=new olb(b.i);m.a<m.c.c.length;){l=BD(mlb(m),65);e=BD(BD(Ohb(a.g,l.a),46).b,33);bld(e,l.b.c,l.b.d);j=$wnd.Math.min(j,e.i);k=$wnd.Math.min(k,e.j);h=$wnd.Math.max(h,e.i+e.g);i=$wnd.Math.max(i,e.j+e.f)}n=BD(hkd(a.c,(d0c(),W_c)),116);Afd(a.c,h-j+(n.b+n.c),i-k+(n.d+n.a),true,true);Efd(a.c,-j+n.b,-k+n.d);for(d=new Fyd(Wod(a.c));d.e!=d.i.gc();){c=BD(Dyd(d),79);g=itd(c,true,true);o=jtd(c);q=ltd(c);p=new f7c(o.i+o.g/2,o.j+o.f/2);f=new f7c(q.i+q.g/2,q.j+q.f/2);r=c7c(new f7c(f.a,f.b),p);l6c(r,o.g,o.f);P6c(p,r);s=c7c(new f7c(p.a,p.b),f);l6c(s,q.g,q.f);P6c(f,s);nmd(g,p.a,p.b);gmd(g,f.a,f.b)}} +function EYb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;a.c=a.d;o=DD(vNb(b,(Nyc(),gyc)));n=o==null||(uCb(o),o);f=BD(vNb(b,(wtc(),Ksc)),21).Hc((Orc(),Hrc));e=BD(vNb(b,Vxc),98);c=!(e==(dcd(),Zbd)||e==_bd||e==$bd);if(n&&(c||!f)){for(l=new olb(b.a);l.a<l.c.c.length;){j=BD(mlb(l),10);j.p=0}m=new Rkb;for(k=new olb(b.a);k.a<k.c.c.length;){j=BD(mlb(k),10);d=DYb(a,j,null);if(d){i=new XZb;tNb(i,b);yNb(i,Esc,BD(d.b,21));u_b(i.d,b.d);yNb(i,Hxc,null);for(h=BD(d.a,15).Kc();h.Ob();){g=BD(h.Pb(),10);Ekb(i.a,g);g.a=i}m.Fc(i)}}f&&(PD(vNb(b,twc))===PD((RXb(),OXb))?(a.c=a.b):(a.c=a.a))}else{m=new amb(OC(GC(KQ,1),cne,37,0,[b]))}PD(vNb(b,twc))!==PD((RXb(),QXb))&&(mmb(),m.ad(new HYb));return m} +function KTc(a){r4c(a,new E3c(Q3c(L3c(P3c(M3c(O3c(N3c(new R3c,are),'ELK Mr. Tree'),"Tree-based algorithm provided by the Eclipse Layout Kernel. Computes a spanning tree of the input graph and arranges all nodes according to the resulting parent-children hierarchy. I pity the fool who doesn't use Mr. Tree Layout."),new NTc),bre),pqb((Csd(),wsd)))));p4c(a,are,ame,CTc);p4c(a,are,wme,20);p4c(a,are,_le,tme);p4c(a,are,vme,meb(1));p4c(a,are,zme,(Bcb(),true));p4c(a,are,Zpe,Ksd(vTc));p4c(a,are,Fme,Ksd(xTc));p4c(a,are,Tme,Ksd(yTc));p4c(a,are,Eme,Ksd(zTc));p4c(a,are,Gme,Ksd(wTc));p4c(a,are,Dme,Ksd(ATc));p4c(a,are,Hme,Ksd(DTc));p4c(a,are,Zqe,Ksd(ITc));p4c(a,are,$qe,Ksd(FTc))} +function zod(a){if(a.q)return;a.q=true;a.p=Lnd(a,0);a.a=Lnd(a,1);Qnd(a.a,0);a.f=Lnd(a,2);Qnd(a.f,1);Knd(a.f,2);a.n=Lnd(a,3);Knd(a.n,3);Knd(a.n,4);Knd(a.n,5);Knd(a.n,6);a.g=Lnd(a,4);Qnd(a.g,7);Knd(a.g,8);a.c=Lnd(a,5);Qnd(a.c,7);Qnd(a.c,8);a.i=Lnd(a,6);Qnd(a.i,9);Qnd(a.i,10);Qnd(a.i,11);Qnd(a.i,12);Knd(a.i,13);a.j=Lnd(a,7);Qnd(a.j,9);a.d=Lnd(a,8);Qnd(a.d,3);Qnd(a.d,4);Qnd(a.d,5);Qnd(a.d,6);Knd(a.d,7);Knd(a.d,8);Knd(a.d,9);Knd(a.d,10);a.b=Lnd(a,9);Knd(a.b,0);Knd(a.b,1);a.e=Lnd(a,10);Knd(a.e,1);Knd(a.e,2);Knd(a.e,3);Knd(a.e,4);Qnd(a.e,5);Qnd(a.e,6);Qnd(a.e,7);Qnd(a.e,8);Qnd(a.e,9);Qnd(a.e,10);Knd(a.e,11);a.k=Lnd(a,11);Knd(a.k,0);Knd(a.k,1);a.o=Mnd(a,12);a.s=Mnd(a,13)} +function AUb(a,b){b.dc()&&HVb(a.j,true,true,true,true);pb(b,(Ucd(),Gcd))&&HVb(a.j,true,true,true,false);pb(b,Bcd)&&HVb(a.j,false,true,true,true);pb(b,Ocd)&&HVb(a.j,true,true,false,true);pb(b,Qcd)&&HVb(a.j,true,false,true,true);pb(b,Hcd)&&HVb(a.j,false,true,true,false);pb(b,Ccd)&&HVb(a.j,false,true,false,true);pb(b,Pcd)&&HVb(a.j,true,false,false,true);pb(b,Ncd)&&HVb(a.j,true,false,true,false);pb(b,Lcd)&&HVb(a.j,true,true,true,true);pb(b,Ecd)&&HVb(a.j,true,true,true,true);pb(b,Lcd)&&HVb(a.j,true,true,true,true);pb(b,Dcd)&&HVb(a.j,true,true,true,true);pb(b,Mcd)&&HVb(a.j,true,true,true,true);pb(b,Kcd)&&HVb(a.j,true,true,true,true);pb(b,Jcd)&&HVb(a.j,true,true,true,true)} +function rZb(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q;f=new Rkb;for(j=new olb(d);j.a<j.c.c.length;){h=BD(mlb(j),441);g=null;if(h.f==(KAc(),IAc)){for(o=new olb(h.e);o.a<o.c.c.length;){n=BD(mlb(o),17);q=n.d.i;if(Q_b(q)==b){iZb(a,b,h,n,h.b,n.d)}else if(!c||f_b(q,c)){jZb(a,b,h,d,n)}else{m=oZb(a,b,c,n,h.b,IAc,g);m!=g&&(f.c[f.c.length]=m,true);m.c&&(g=m)}}}else{for(l=new olb(h.e);l.a<l.c.c.length;){k=BD(mlb(l),17);p=k.c.i;if(Q_b(p)==b){iZb(a,b,h,k,k.c,h.b)}else if(!c||f_b(p,c)){continue}else{m=oZb(a,b,c,k,h.b,HAc,g);m!=g&&(f.c[f.c.length]=m,true);m.c&&(g=m)}}}}for(i=new olb(f);i.a<i.c.c.length;){h=BD(mlb(i),441);Jkb(b.a,h.a,0)!=-1||Ekb(b.a,h.a);h.c&&(e.c[e.c.length]=h,true)}} +function SJc(a,b,c){var d,e,f,g,h,i,j,k,l,m;j=new Rkb;for(i=new olb(b.a);i.a<i.c.c.length;){g=BD(mlb(i),10);for(m=V_b(g,(Ucd(),zcd)).Kc();m.Ob();){l=BD(m.Pb(),11);for(e=new olb(l.g);e.a<e.c.c.length;){d=BD(mlb(e),17);if(!OZb(d)&&d.c.i.c==d.d.i.c||OZb(d)||d.d.i.c!=c){continue}j.c[j.c.length]=d}}}for(h=Su(c.a).Kc();h.Ob();){g=BD(h.Pb(),10);for(m=V_b(g,(Ucd(),Tcd)).Kc();m.Ob();){l=BD(m.Pb(),11);for(e=new olb(l.e);e.a<e.c.c.length;){d=BD(mlb(e),17);if(!OZb(d)&&d.c.i.c==d.d.i.c||OZb(d)||d.c.i.c!=b){continue}k=new Bib(j,j.c.length);f=(sCb(k.b>0),BD(k.a.Xb(k.c=--k.b),17));while(f!=d&&k.b>0){a.a[f.p]=true;a.a[d.p]=true;f=(sCb(k.b>0),BD(k.a.Xb(k.c=--k.b),17))}k.b>0&&uib(k)}}}} +function Vmd(b,c,d){var e,f,g,h,i,j,k,l,m;if(b.a!=c.Aj()){throw vbb(new Wdb(tte+c.ne()+ute))}e=o1d((O6d(),M6d),c).$k();if(e){return e.Aj().Nh().Ih(e,d)}h=o1d(M6d,c).al();if(h){if(d==null){return null}i=BD(d,15);if(i.dc()){return ''}m=new Hfb;for(g=i.Kc();g.Ob();){f=g.Pb();Efb(m,h.Aj().Nh().Ih(h,f));m.a+=' '}return lcb(m,m.a.length-1)}l=o1d(M6d,c).bl();if(!l.dc()){for(k=l.Kc();k.Ob();){j=BD(k.Pb(),148);if(j.wj(d)){try{m=j.Aj().Nh().Ih(j,d);if(m!=null){return m}}catch(a){a=ubb(a);if(!JD(a,102))throw vbb(a)}}}throw vbb(new Wdb("Invalid value: '"+d+"' for datatype :"+c.ne()))}BD(c,834).Fj();return d==null?null:JD(d,172)?''+BD(d,172).a:rb(d)==$J?CQd(Pmd[0],BD(d,199)):fcb(d)} +function zQc(a){var b,c,d,e,f,g,h,i,j,k;j=new Psb;h=new Psb;for(f=new olb(a);f.a<f.c.c.length;){d=BD(mlb(f),128);d.v=0;d.n=d.i.c.length;d.u=d.t.c.length;d.n==0&&(Gsb(j,d,j.c.b,j.c),true);d.u==0&&d.r.a.gc()==0&&(Gsb(h,d,h.c.b,h.c),true)}g=-1;while(j.b!=0){d=BD(Vt(j,0),128);for(c=new olb(d.t);c.a<c.c.c.length;){b=BD(mlb(c),268);k=b.b;k.v=$wnd.Math.max(k.v,d.v+1);g=$wnd.Math.max(g,k.v);--k.n;k.n==0&&(Gsb(j,k,j.c.b,j.c),true)}}if(g>-1){for(e=Jsb(h,0);e.b!=e.d.c;){d=BD(Xsb(e),128);d.v=g}while(h.b!=0){d=BD(Vt(h,0),128);for(c=new olb(d.i);c.a<c.c.c.length;){b=BD(mlb(c),268);i=b.a;if(i.r.a.gc()!=0){continue}i.v=$wnd.Math.min(i.v,d.v-1);--i.u;i.u==0&&(Gsb(h,i,h.c.b,h.c),true)}}}} +function A6c(a,b,c,d,e){var f,g,h,i;i=Pje;g=false;h=v6c(a,c7c(new f7c(b.a,b.b),a),P6c(new f7c(c.a,c.b),e),c7c(new f7c(d.a,d.b),c));f=!!h&&!($wnd.Math.abs(h.a-a.a)<=nse&&$wnd.Math.abs(h.b-a.b)<=nse||$wnd.Math.abs(h.a-b.a)<=nse&&$wnd.Math.abs(h.b-b.b)<=nse);h=v6c(a,c7c(new f7c(b.a,b.b),a),c,e);!!h&&(($wnd.Math.abs(h.a-a.a)<=nse&&$wnd.Math.abs(h.b-a.b)<=nse)==($wnd.Math.abs(h.a-b.a)<=nse&&$wnd.Math.abs(h.b-b.b)<=nse)||f?(i=$wnd.Math.min(i,U6c(c7c(h,c)))):(g=true));h=v6c(a,c7c(new f7c(b.a,b.b),a),d,e);!!h&&(g||($wnd.Math.abs(h.a-a.a)<=nse&&$wnd.Math.abs(h.b-a.b)<=nse)==($wnd.Math.abs(h.a-b.a)<=nse&&$wnd.Math.abs(h.b-b.b)<=nse)||f)&&(i=$wnd.Math.min(i,U6c(c7c(h,d))));return i} +function cTb(a){r4c(a,new E3c(L3c(P3c(M3c(O3c(N3c(new R3c,Rme),Sme),"Minimizes the stress within a layout using stress majorization. Stress exists if the euclidean distance between a pair of nodes doesn't match their graph theoretic distance, that is, the shortest path between the two nodes. The method allows to specify individual edge lengths."),new fTb),ume)));p4c(a,Rme,Ame,Ksd(VSb));p4c(a,Rme,Cme,(Bcb(),true));p4c(a,Rme,Fme,Ksd(YSb));p4c(a,Rme,Tme,Ksd(ZSb));p4c(a,Rme,Eme,Ksd($Sb));p4c(a,Rme,Gme,Ksd(XSb));p4c(a,Rme,Dme,Ksd(_Sb));p4c(a,Rme,Hme,Ksd(aTb));p4c(a,Rme,Mme,Ksd(USb));p4c(a,Rme,Ome,Ksd(SSb));p4c(a,Rme,Pme,Ksd(TSb));p4c(a,Rme,Qme,Ksd(WSb));p4c(a,Rme,Nme,Ksd(RSb))} +function BFc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;Odd(b,'Interactive crossing minimization',1);g=0;for(f=new olb(a.b);f.a<f.c.c.length;){d=BD(mlb(f),29);d.p=g++}m=WZb(a);q=new iHc(m.length);$Ic(new amb(OC(GC(qY,1),Uhe,225,0,[q])),m);p=0;g=0;for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),29);c=0;l=0;for(k=new olb(d.a);k.a<k.c.c.length;){i=BD(mlb(k),10);if(i.n.a>0){c+=i.n.a+i.o.a/2;++l}for(o=new olb(i.j);o.a<o.c.c.length;){n=BD(mlb(o),11);n.p=p++}}l>0&&(c/=l);r=KC(UD,Vje,25,d.a.c.length,15,1);h=0;for(j=new olb(d.a);j.a<j.c.c.length;){i=BD(mlb(j),10);i.p=h++;r[i.p]=AFc(i,c);i.k==(j0b(),g0b)&&yNb(i,(wtc(),atc),r[i.p])}mmb();Okb(d.a,new GFc(r));YDc(q,m,g,true);++g}Qdd(b)} +function Zfe(a,b){var c,d,e,f,g,h,i,j,k;if(b.e==5){Wfe(a,b);return}j=b;if(j.b==null||a.b==null)return;Yfe(a);Vfe(a);Yfe(j);Vfe(j);c=KC(WD,oje,25,a.b.length+j.b.length,15,1);k=0;d=0;g=0;while(d<a.b.length&&g<j.b.length){e=a.b[d];f=a.b[d+1];h=j.b[g];i=j.b[g+1];if(f<h){c[k++]=a.b[d++];c[k++]=a.b[d++]}else if(f>=h&&e<=i){if(h<=e&&f<=i){d+=2}else if(h<=e){a.b[d]=i+1;g+=2}else if(f<=i){c[k++]=e;c[k++]=h-1;d+=2}else{c[k++]=e;c[k++]=h-1;a.b[d]=i+1;g+=2}}else if(i<e){g+=2}else{throw vbb(new hz('Token#subtractRanges(): Internal Error: ['+a.b[d]+','+a.b[d+1]+'] - ['+j.b[g]+','+j.b[g+1]+']'))}}while(d<a.b.length){c[k++]=a.b[d++];c[k++]=a.b[d++]}a.b=KC(WD,oje,25,k,15,1);$fb(c,0,a.b,0,k)} +function BJb(a){var b,c,d,e,f,g,h;if(a.A.dc()){return}if(a.A.Hc((tdd(),rdd))){BD(Mpb(a.b,(Ucd(),Acd)),124).k=true;BD(Mpb(a.b,Rcd),124).k=true;b=a.q!=(dcd(),_bd)&&a.q!=$bd;ZGb(BD(Mpb(a.b,zcd),124),b);ZGb(BD(Mpb(a.b,Tcd),124),b);ZGb(a.g,b);if(a.A.Hc(sdd)){BD(Mpb(a.b,Acd),124).j=true;BD(Mpb(a.b,Rcd),124).j=true;BD(Mpb(a.b,zcd),124).k=true;BD(Mpb(a.b,Tcd),124).k=true;a.g.k=true}}if(a.A.Hc(qdd)){a.a.j=true;a.a.k=true;a.g.j=true;a.g.k=true;h=a.B.Hc((Idd(),Edd));for(e=wJb(),f=0,g=e.length;f<g;++f){d=e[f];c=BD(Mpb(a.i,d),306);if(c){if(sJb(d)){c.j=true;c.k=true}else{c.j=!h;c.k=!h}}}}if(a.A.Hc(pdd)&&a.B.Hc((Idd(),Ddd))){a.g.j=true;a.g.j=true;if(!a.a.j){a.a.j=true;a.a.k=true;a.a.e=true}}} +function GJc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;for(d=new olb(a.e.b);d.a<d.c.c.length;){c=BD(mlb(d),29);for(f=new olb(c.a);f.a<f.c.c.length;){e=BD(mlb(f),10);n=a.i[e.p];j=n.a.e;i=n.d.e;e.n.b=j;r=i-j-e.o.b;b=bKc(e);m=(Izc(),(!e.q?(mmb(),mmb(),kmb):e.q)._b((Nyc(),Cxc))?(l=BD(vNb(e,Cxc),197)):(l=BD(vNb(Q_b(e),Dxc),197)),l);b&&(m==Fzc||m==Ezc)&&(e.o.b+=r);if(b&&(m==Hzc||m==Fzc||m==Ezc)){for(p=new olb(e.j);p.a<p.c.c.length;){o=BD(mlb(p),11);if((Ucd(),Ecd).Hc(o.j)){k=BD(Ohb(a.k,o),121);o.n.b=k.e-j}}for(h=new olb(e.b);h.a<h.c.c.length;){g=BD(mlb(h),70);q=BD(vNb(e,xxc),21);q.Hc((Hbd(),Ebd))?(g.n.b+=r):q.Hc(Fbd)&&(g.n.b+=r/2)}(m==Fzc||m==Ezc)&&V_b(e,(Ucd(),Rcd)).Jc(new $Kc(r))}}}} +function Lwb(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;if(!a.b){return false}g=null;m=null;i=new exb(null,null);e=1;i.a[1]=a.b;l=i;while(l.a[e]){j=e;h=m;m=l;l=l.a[e];d=a.a.ue(b,l.d);e=d<0?0:1;d==0&&(!c.c||wtb(l.e,c.d))&&(g=l);if(!(!!l&&l.b)&&!Hwb(l.a[e])){if(Hwb(l.a[1-e])){m=m.a[j]=Owb(l,e)}else if(!Hwb(l.a[1-e])){n=m.a[1-j];if(n){if(!Hwb(n.a[1-j])&&!Hwb(n.a[j])){m.b=false;n.b=true;l.b=true}else{f=h.a[1]==m?1:0;Hwb(n.a[j])?(h.a[f]=Nwb(m,j)):Hwb(n.a[1-j])&&(h.a[f]=Owb(m,j));l.b=h.a[f].b=true;h.a[f].a[0].b=false;h.a[f].a[1].b=false}}}}}if(g){c.b=true;c.d=g.e;if(l!=g){k=new exb(l.d,l.e);Mwb(a,i,g,k);m==g&&(m=k)}m.a[m.a[1]==l?1:0]=l.a[!l.a[0]?1:0];--a.c}a.b=i.a[1];!!a.b&&(a.b.b=false);return c.b} +function cic(a){var b,c,d,e,f,g,h,i,j,k,l,m;for(e=new olb(a.a.a.b);e.a<e.c.c.length;){d=BD(mlb(e),57);for(i=d.c.Kc();i.Ob();){h=BD(i.Pb(),57);if(d.a==h.a){continue}fad(a.a.d)?(l=a.a.g.Oe(d,h)):(l=a.a.g.Pe(d,h));f=d.b.a+d.d.b+l-h.b.a;f=$wnd.Math.ceil(f);f=$wnd.Math.max(0,f);if(vgc(d,h)){g=nGb(new pGb,a.d);j=QD($wnd.Math.ceil(h.b.a-d.b.a));b=j-(h.b.a-d.b.a);k=ugc(d).a;c=d;if(!k){k=ugc(h).a;b=-b;c=h}if(k){c.b.a-=b;k.n.a-=b}AFb(DFb(CFb(EFb(BFb(new FFb,$wnd.Math.max(0,j)),1),g),a.c[d.a.d]));AFb(DFb(CFb(EFb(BFb(new FFb,$wnd.Math.max(0,-j)),1),g),a.c[h.a.d]))}else{m=1;(JD(d.g,145)&&JD(h.g,10)||JD(h.g,145)&&JD(d.g,10))&&(m=2);AFb(DFb(CFb(EFb(BFb(new FFb,QD(f)),m),a.c[d.a.d]),a.c[h.a.d]))}}}} +function pEc(a,b,c){var d,e,f,g,h,i,j,k,l,m;if(c){d=-1;k=new Bib(b,0);while(k.b<k.d.gc()){h=(sCb(k.b<k.d.gc()),BD(k.d.Xb(k.c=k.b++),10));l=a.c[h.c.p][h.p].a;if(l==null){g=d+1;f=new Bib(b,k.b);while(f.b<f.d.gc()){m=tEc(a,(sCb(f.b<f.d.gc()),BD(f.d.Xb(f.c=f.b++),10))).a;if(m!=null){g=(uCb(m),m);break}}l=(d+g)/2;a.c[h.c.p][h.p].a=l;a.c[h.c.p][h.p].d=(uCb(l),l);a.c[h.c.p][h.p].b=1}d=(uCb(l),l)}}else{e=0;for(j=new olb(b);j.a<j.c.c.length;){h=BD(mlb(j),10);a.c[h.c.p][h.p].a!=null&&(e=$wnd.Math.max(e,Edb(a.c[h.c.p][h.p].a)))}e+=2;for(i=new olb(b);i.a<i.c.c.length;){h=BD(mlb(i),10);if(a.c[h.c.p][h.p].a==null){l=Cub(a.i,24)*lke*e-1;a.c[h.c.p][h.p].a=l;a.c[h.c.p][h.p].d=l;a.c[h.c.p][h.p].b=1}}}} +function CZd(){rEd(b5,new i$d);rEd(a5,new P$d);rEd(c5,new u_d);rEd(d5,new M_d);rEd(f5,new P_d);rEd(h5,new S_d);rEd(g5,new V_d);rEd(i5,new Y_d);rEd(k5,new GZd);rEd(l5,new JZd);rEd(m5,new MZd);rEd(n5,new PZd);rEd(o5,new SZd);rEd(p5,new VZd);rEd(q5,new YZd);rEd(t5,new _Zd);rEd(v5,new c$d);rEd(x6,new f$d);rEd(j5,new l$d);rEd(u5,new o$d);rEd(wI,new r$d);rEd(GC(SD,1),new u$d);rEd(xI,new x$d);rEd(yI,new A$d);rEd($J,new D$d);rEd(O4,new G$d);rEd(BI,new J$d);rEd(T4,new M$d);rEd(U4,new S$d);rEd(O9,new V$d);rEd(E9,new Y$d);rEd(FI,new _$d);rEd(JI,new c_d);rEd(AI,new f_d);rEd(MI,new i_d);rEd(DK,new l_d);rEd(v8,new o_d);rEd(u8,new r_d);rEd(UI,new x_d);rEd(ZI,new A_d);rEd(X4,new D_d);rEd(V4,new G_d)} +function hA(a,b,c){var d,e,f,g,h,i,j,k,l;!c&&(c=TA(b.q.getTimezoneOffset()));e=(b.q.getTimezoneOffset()-c.a)*60000;h=new gB(wbb(Cbb(b.q.getTime()),e));i=h;if(h.q.getTimezoneOffset()!=b.q.getTimezoneOffset()){e>0?(e-=86400000):(e+=86400000);i=new gB(wbb(Cbb(b.q.getTime()),e))}k=new Vfb;j=a.a.length;for(f=0;f<j;){d=bfb(a.a,f);if(d>=97&&d<=122||d>=65&&d<=90){for(g=f+1;g<j&&bfb(a.a,g)==d;++g);vA(k,d,g-f,h,i,c);f=g}else if(d==39){++f;if(f<j&&bfb(a.a,f)==39){k.a+="'";++f;continue}l=false;while(!l){g=f;while(g<j&&bfb(a.a,g)!=39){++g}if(g>=j){throw vbb(new Wdb("Missing trailing '"))}g+1<j&&bfb(a.a,g+1)==39?++g:(l=true);Qfb(k,qfb(a.a,f,g));f=g+1}}else{k.a+=String.fromCharCode(d);++f}}return k.a} +function MEc(a){var b,c,d,e,f,g,h,i;b=null;for(d=new olb(a);d.a<d.c.c.length;){c=BD(mlb(d),233);Edb(REc(c.g,c.d[0]).a);c.b=null;if(!!c.e&&c.e.gc()>0&&c.c==0){!b&&(b=new Rkb);b.c[b.c.length]=c}}if(b){while(b.c.length!=0){c=BD(Kkb(b,0),233);if(!!c.b&&c.b.c.length>0){for(f=(!c.b&&(c.b=new Rkb),new olb(c.b));f.a<f.c.c.length;){e=BD(mlb(f),233);if(Gdb(REc(e.g,e.d[0]).a)==Gdb(REc(c.g,c.d[0]).a)){if(Jkb(a,e,0)>Jkb(a,c,0)){return new vgd(e,c)}}else if(Edb(REc(e.g,e.d[0]).a)>Edb(REc(c.g,c.d[0]).a)){return new vgd(e,c)}}}for(h=(!c.e&&(c.e=new Rkb),c.e).Kc();h.Ob();){g=BD(h.Pb(),233);i=(!g.b&&(g.b=new Rkb),g.b);wCb(0,i.c.length);aCb(i.c,0,c);g.c==i.c.length&&(b.c[b.c.length]=g,true)}}}return null} +function wlb(a,b){var c,d,e,f,g,h,i,j,k;if(a==null){return Xhe}i=b.a.zc(a,b);if(i!=null){return '[...]'}c=new xwb(She,'[',']');for(e=a,f=0,g=e.length;f<g;++f){d=e[f];if(d!=null&&(rb(d).i&4)!=0){if(Array.isArray(d)&&(k=HC(d),!(k>=14&&k<=16))){if(b.a._b(d)){!c.a?(c.a=new Wfb(c.d)):Qfb(c.a,c.b);Nfb(c.a,'[...]')}else{h=CD(d);j=new Vqb(b);uwb(c,wlb(h,j))}}else JD(d,177)?uwb(c,Xlb(BD(d,177))):JD(d,190)?uwb(c,Qlb(BD(d,190))):JD(d,195)?uwb(c,Rlb(BD(d,195))):JD(d,2012)?uwb(c,Wlb(BD(d,2012))):JD(d,48)?uwb(c,Ulb(BD(d,48))):JD(d,364)?uwb(c,Vlb(BD(d,364))):JD(d,832)?uwb(c,Tlb(BD(d,832))):JD(d,104)&&uwb(c,Slb(BD(d,104)))}else{uwb(c,d==null?Xhe:fcb(d))}}return !c.a?c.c:c.e.length==0?c.a.a:c.a.a+(''+c.e)} +function xQb(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;h=itd(b,false,false);r=ofd(h);d&&(r=w7c(r));t=Edb(ED(hkd(b,(CPb(),vPb))));q=(sCb(r.b!=0),BD(r.a.a.c,8));l=BD(Ut(r,1),8);if(r.b>2){k=new Rkb;Gkb(k,new Jib(r,1,r.b));f=sQb(k,t+a.a);s=new XOb(f);tNb(s,b);c.c[c.c.length]=s}else{d?(s=BD(Ohb(a.b,jtd(b)),266)):(s=BD(Ohb(a.b,ltd(b)),266))}i=jtd(b);d&&(i=ltd(b));g=zQb(q,i);j=t+a.a;if(g.a){j+=$wnd.Math.abs(q.b-l.b);p=new f7c(l.a,(l.b+q.b)/2)}else{j+=$wnd.Math.abs(q.a-l.a);p=new f7c((l.a+q.a)/2,l.b)}d?Rhb(a.d,b,new ZOb(s,g,p,j)):Rhb(a.c,b,new ZOb(s,g,p,j));Rhb(a.b,b,s);o=(!b.n&&(b.n=new cUd(D2,b,1,7)),b.n);for(n=new Fyd(o);n.e!=n.i.gc();){m=BD(Dyd(n),137);e=wQb(a,m,true,0,0);c.c[c.c.length]=e}} +function wPc(a){var b,c,d,e,f,g,h,i,j,k;j=new Rkb;h=new Rkb;for(g=new olb(a);g.a<g.c.c.length;){e=BD(mlb(g),112);pOc(e,e.f.c.length);qOc(e,e.k.c.length);e.d==0&&(j.c[j.c.length]=e,true);e.i==0&&e.e.b==0&&(h.c[h.c.length]=e,true)}d=-1;while(j.c.length!=0){e=BD(Kkb(j,0),112);for(c=new olb(e.k);c.a<c.c.c.length;){b=BD(mlb(c),129);k=b.b;rOc(k,$wnd.Math.max(k.o,e.o+1));d=$wnd.Math.max(d,k.o);pOc(k,k.d-1);k.d==0&&(j.c[j.c.length]=k,true)}}if(d>-1){for(f=new olb(h);f.a<f.c.c.length;){e=BD(mlb(f),112);e.o=d}while(h.c.length!=0){e=BD(Kkb(h,0),112);for(c=new olb(e.f);c.a<c.c.c.length;){b=BD(mlb(c),129);i=b.a;if(i.e.b>0){continue}rOc(i,$wnd.Math.min(i.o,e.o-1));qOc(i,i.i-1);i.i==0&&(h.c[h.c.length]=i,true)}}}} +function QQd(a,b,c){var d,e,f,g,h,i,j;j=a.c;!b&&(b=FQd);a.c=b;if((a.Db&4)!=0&&(a.Db&1)==0){i=new nSd(a,1,2,j,a.c);!c?(c=i):c.Ei(i)}if(j!=b){if(JD(a.Cb,284)){if(a.Db>>16==-10){c=BD(a.Cb,284).nk(b,c)}else if(a.Db>>16==-15){!b&&(b=(jGd(),YFd));!j&&(j=(jGd(),YFd));if(a.Cb.nh()){i=new pSd(a.Cb,1,13,j,b,HLd(QSd(BD(a.Cb,59)),a),false);!c?(c=i):c.Ei(i)}}}else if(JD(a.Cb,88)){if(a.Db>>16==-23){JD(b,88)||(b=(jGd(),_Fd));JD(j,88)||(j=(jGd(),_Fd));if(a.Cb.nh()){i=new pSd(a.Cb,1,10,j,b,HLd(VKd(BD(a.Cb,26)),a),false);!c?(c=i):c.Ei(i)}}}else if(JD(a.Cb,444)){h=BD(a.Cb,836);g=(!h.b&&(h.b=new RYd(new NYd)),h.b);for(f=(d=new nib((new eib(g.a)).a),new ZYd(d));f.a.b;){e=BD(lib(f.a).cd(),87);c=QQd(e,MQd(e,h),c)}}}return c} +function O1b(a,b){var c,d,e,f,g,h,i,j,k,l,m;g=Ccb(DD(hkd(a,(Nyc(),fxc))));m=BD(hkd(a,Yxc),21);i=false;j=false;l=new Fyd((!a.c&&(a.c=new cUd(F2,a,9,9)),a.c));while(l.e!=l.i.gc()&&(!i||!j)){f=BD(Dyd(l),118);h=0;for(e=ul(pl(OC(GC(KI,1),Uhe,20,0,[(!f.d&&(f.d=new y5d(B2,f,8,5)),f.d),(!f.e&&(f.e=new y5d(B2,f,7,4)),f.e)])));Qr(e);){d=BD(Rr(e),79);k=g&&Qld(d)&&Ccb(DD(hkd(d,gxc)));c=ELd((!d.b&&(d.b=new y5d(z2,d,4,7)),d.b),f)?a==Xod(atd(BD(qud((!d.c&&(d.c=new y5d(z2,d,5,8)),d.c),0),82))):a==Xod(atd(BD(qud((!d.b&&(d.b=new y5d(z2,d,4,7)),d.b),0),82)));if(k||c){++h;if(h>1){break}}}h>0?(i=true):m.Hc((rcd(),ncd))&&(!f.n&&(f.n=new cUd(D2,f,1,7)),f.n).i>0&&(i=true);h>1&&(j=true)}i&&b.Fc((Orc(),Hrc));j&&b.Fc((Orc(),Irc))} +function zfd(a){var b,c,d,e,f,g,h,i,j,k,l,m;m=BD(hkd(a,(Y9c(),Y8c)),21);if(m.dc()){return null}h=0;g=0;if(m.Hc((tdd(),rdd))){k=BD(hkd(a,t9c),98);d=2;c=2;e=2;f=2;b=!Xod(a)?BD(hkd(a,z8c),103):BD(hkd(Xod(a),z8c),103);for(j=new Fyd((!a.c&&(a.c=new cUd(F2,a,9,9)),a.c));j.e!=j.i.gc();){i=BD(Dyd(j),118);l=BD(hkd(i,A9c),61);if(l==(Ucd(),Scd)){l=lfd(i,b);jkd(i,A9c,l)}if(k==(dcd(),$bd)){switch(l.g){case 1:d=$wnd.Math.max(d,i.i+i.g);break;case 2:c=$wnd.Math.max(c,i.j+i.f);break;case 3:e=$wnd.Math.max(e,i.i+i.g);break;case 4:f=$wnd.Math.max(f,i.j+i.f);}}else{switch(l.g){case 1:d+=i.g+2;break;case 2:c+=i.f+2;break;case 3:e+=i.g+2;break;case 4:f+=i.f+2;}}}h=$wnd.Math.max(d,e);g=$wnd.Math.max(c,f)}return Afd(a,h,g,true,true)} +function lnc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;s=BD(GAb(VAb(JAb(new YAb(null,new Kub(b.d,16)),new pnc(c)),new rnc(c)),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)]))),15);l=Ohe;k=Rie;for(i=new olb(b.b.j);i.a<i.c.c.length;){h=BD(mlb(i),11);if(h.j==c){l=$wnd.Math.min(l,h.p);k=$wnd.Math.max(k,h.p)}}if(l==Ohe){for(g=0;g<s.gc();g++){ojc(BD(s.Xb(g),101),c,g)}}else{t=KC(WD,oje,25,e.length,15,1);Elb(t,t.length);for(r=s.Kc();r.Ob();){q=BD(r.Pb(),101);f=BD(Ohb(a.b,q),177);j=0;for(p=l;p<=k;p++){f[p]&&(j=$wnd.Math.max(j,d[p]))}if(q.i){n=q.i.c;u=new Tqb;for(m=0;m<e.length;m++){e[n][m]&&Qqb(u,meb(t[m]))}while(Rqb(u,meb(j))){++j}}ojc(q,c,j);for(o=l;o<=k;o++){f[o]&&(d[o]=j+1)}!!q.i&&(t[q.i.c]=j)}}} +function YJc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;e=null;for(d=new olb(b.a);d.a<d.c.c.length;){c=BD(mlb(d),10);bKc(c)?(f=(h=nGb(oGb(new pGb,c),a.f),i=nGb(oGb(new pGb,c),a.f),j=new rKc(c,true,h,i),k=c.o.b,l=(Izc(),(!c.q?(mmb(),mmb(),kmb):c.q)._b((Nyc(),Cxc))?(m=BD(vNb(c,Cxc),197)):(m=BD(vNb(Q_b(c),Dxc),197)),m),n=10000,l==Ezc&&(n=1),o=AFb(DFb(CFb(BFb(EFb(new FFb,n),QD($wnd.Math.ceil(k))),h),i)),l==Fzc&&Qqb(a.d,o),ZJc(a,Su(V_b(c,(Ucd(),Tcd))),j),ZJc(a,V_b(c,zcd),j),j)):(f=(p=nGb(oGb(new pGb,c),a.f),MAb(JAb(new YAb(null,new Kub(c.j,16)),new EKc),new GKc(a,p)),new rKc(c,false,p,p)));a.i[c.p]=f;if(e){g=e.c.d.a+jBc(a.n,e.c,c)+c.d.d;e.b||(g+=e.c.o.b);AFb(DFb(CFb(EFb(BFb(new FFb,QD($wnd.Math.ceil(g))),0),e.d),f.a))}e=f}} +function s9b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;Odd(b,'Label dummy insertions',1);l=new Rkb;g=Edb(ED(vNb(a,(Nyc(),nyc))));j=Edb(ED(vNb(a,ryc)));k=BD(vNb(a,Lwc),103);for(n=new olb(a.a);n.a<n.c.c.length;){m=BD(mlb(n),10);for(f=new Sr(ur(U_b(m).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);if(e.c.i!=e.d.i&&Lq(e.b,p9b)){p=t9b(e);o=Pu(e.b.c.length);c=r9b(a,e,p,o);l.c[l.c.length]=c;d=c.o;h=new Bib(e.b,0);while(h.b<h.d.gc()){i=(sCb(h.b<h.d.gc()),BD(h.d.Xb(h.c=h.b++),70));if(PD(vNb(i,Qwc))===PD((qad(),nad))){if(k==(ead(),dad)||k==_9c){d.a+=i.o.a+j;d.b=$wnd.Math.max(d.b,i.o.b)}else{d.a=$wnd.Math.max(d.a,i.o.a);d.b+=i.o.b+j}o.c[o.c.length]=i;uib(h)}}if(k==(ead(),dad)||k==_9c){d.a-=j;d.b+=g+p}else{d.b+=g-j+p}}}}Gkb(a.a,l);Qdd(b)} +function eYb(a,b,c,d){var e,f,g,h,i,j,k,l,m,n;f=new qYb(b);l=_Xb(a,b,f);n=$wnd.Math.max(Edb(ED(vNb(b,(Nyc(),Zwc)))),1);for(k=new olb(l.a);k.a<k.c.c.length;){j=BD(mlb(k),46);i=dYb(BD(j.a,8),BD(j.b,8),n);o=true;o=o&iYb(c,new f7c(i.c,i.d));o=o&iYb(c,O6c(new f7c(i.c,i.d),i.b,0));o=o&iYb(c,O6c(new f7c(i.c,i.d),0,i.a));o&iYb(c,O6c(new f7c(i.c,i.d),i.b,i.a))}m=f.d;h=dYb(BD(l.b.a,8),BD(l.b.b,8),n);if(m==(Ucd(),Tcd)||m==zcd){d.c[m.g]=$wnd.Math.min(d.c[m.g],h.d);d.b[m.g]=$wnd.Math.max(d.b[m.g],h.d+h.a)}else{d.c[m.g]=$wnd.Math.min(d.c[m.g],h.c);d.b[m.g]=$wnd.Math.max(d.b[m.g],h.c+h.b)}e=Qje;g=f.c.i.d;switch(m.g){case 4:e=g.c;break;case 2:e=g.b;break;case 1:e=g.a;break;case 3:e=g.d;}d.a[m.g]=$wnd.Math.max(d.a[m.g],e);return f} +function eKd(b){var c,d,e,f;d=b.D!=null?b.D:b.B;c=hfb(d,wfb(91));if(c!=-1){e=d.substr(0,c);f=new Hfb;do f.a+='[';while((c=gfb(d,91,++c))!=-1);if(dfb(e,Khe))f.a+='Z';else if(dfb(e,Eve))f.a+='B';else if(dfb(e,Fve))f.a+='C';else if(dfb(e,Gve))f.a+='D';else if(dfb(e,Hve))f.a+='F';else if(dfb(e,Ive))f.a+='I';else if(dfb(e,Jve))f.a+='J';else if(dfb(e,Kve))f.a+='S';else{f.a+='L';f.a+=''+e;f.a+=';'}try{return null}catch(a){a=ubb(a);if(!JD(a,60))throw vbb(a)}}else if(hfb(d,wfb(46))==-1){if(dfb(d,Khe))return sbb;else if(dfb(d,Eve))return SD;else if(dfb(d,Fve))return TD;else if(dfb(d,Gve))return UD;else if(dfb(d,Hve))return VD;else if(dfb(d,Ive))return WD;else if(dfb(d,Jve))return XD;else if(dfb(d,Kve))return rbb}return null} +function $1b(a,b,c){var d,e,f,g,h,i,j,k;j=new b0b(c);tNb(j,b);yNb(j,(wtc(),$sc),b);j.o.a=b.g;j.o.b=b.f;j.n.a=b.i;j.n.b=b.j;Ekb(c.a,j);Rhb(a.a,b,j);((!b.a&&(b.a=new cUd(E2,b,10,11)),b.a).i!=0||Ccb(DD(hkd(b,(Nyc(),fxc)))))&&yNb(j,wsc,(Bcb(),true));i=BD(vNb(c,Ksc),21);k=BD(vNb(j,(Nyc(),Vxc)),98);k==(dcd(),ccd)?yNb(j,Vxc,bcd):k!=bcd&&i.Fc((Orc(),Krc));d=BD(vNb(c,Lwc),103);for(h=new Fyd((!b.c&&(b.c=new cUd(F2,b,9,9)),b.c));h.e!=h.i.gc();){g=BD(Dyd(h),118);Ccb(DD(hkd(g,Jxc)))||_1b(a,g,j,i,d,k)}for(f=new Fyd((!b.n&&(b.n=new cUd(D2,b,1,7)),b.n));f.e!=f.i.gc();){e=BD(Dyd(f),137);!Ccb(DD(hkd(e,Jxc)))&&!!e.a&&Ekb(j.b,Z1b(e))}Ccb(DD(vNb(j,pwc)))&&i.Fc((Orc(),Frc));if(Ccb(DD(vNb(j,exc)))){i.Fc((Orc(),Jrc));i.Fc(Irc);yNb(j,Vxc,bcd)}return j} +function F4b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;h=BD(Ohb(b.c,a),459);s=b.a.c;i=b.a.c+b.a.b;C=h.f;D=h.a;g=C<D;p=new f7c(s,C);t=new f7c(i,D);e=(s+i)/2;q=new f7c(e,C);u=new f7c(e,D);f=G4b(a,C,D);w=A0b(b.B);A=new f7c(e,f);B=A0b(b.D);c=j6c(OC(GC(m1,1),nie,8,0,[w,A,B]));n=false;r=b.B.i;if(!!r&&!!r.c&&h.d){j=g&&r.p<r.c.a.c.length-1||!g&&r.p>0;if(j){if(j){m=r.p;g?++m:--m;l=BD(Ikb(r.c.a,m),10);d=I4b(l);n=!(s6c(d,w,c[0])||n6c(d,w,c[0]))}}else{n=true}}o=false;v=b.D.i;if(!!v&&!!v.c&&h.e){k=g&&v.p>0||!g&&v.p<v.c.a.c.length-1;if(k){m=v.p;g?--m:++m;l=BD(Ikb(v.c.a,m),10);d=I4b(l);o=!(s6c(d,c[0],B)||n6c(d,c[0],B))}else{o=true}}n&&o&&Dsb(a.a,A);n||n7c(a.a,OC(GC(m1,1),nie,8,0,[p,q]));o||n7c(a.a,OC(GC(m1,1),nie,8,0,[u,t]))} +function yfd(a,b){var c,d,e,f,g,h,i,j;if(JD(a.Ug(),160)){yfd(BD(a.Ug(),160),b);b.a+=' > '}else{b.a+='Root '}c=a.Tg().zb;dfb(c.substr(0,3),'Elk')?Qfb(b,c.substr(3)):(b.a+=''+c,b);e=a.zg();if(e){Qfb((b.a+=' ',b),e);return}if(JD(a,354)){j=BD(a,137).a;if(j){Qfb((b.a+=' ',b),j);return}}for(g=new Fyd(a.Ag());g.e!=g.i.gc();){f=BD(Dyd(g),137);j=f.a;if(j){Qfb((b.a+=' ',b),j);return}}if(JD(a,352)){d=BD(a,79);!d.b&&(d.b=new y5d(z2,d,4,7));if(d.b.i!=0&&(!d.c&&(d.c=new y5d(z2,d,5,8)),d.c.i!=0)){b.a+=' (';h=new Oyd((!d.b&&(d.b=new y5d(z2,d,4,7)),d.b));while(h.e!=h.i.gc()){h.e>0&&(b.a+=She,b);yfd(BD(Dyd(h),160),b)}b.a+=gne;i=new Oyd((!d.c&&(d.c=new y5d(z2,d,5,8)),d.c));while(i.e!=i.i.gc()){i.e>0&&(b.a+=She,b);yfd(BD(Dyd(i),160),b)}b.a+=')'}}} +function y2b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;f=BD(vNb(a,(wtc(),$sc)),79);if(!f){return}d=a.a;e=new g7c(c);P6c(e,C2b(a));if(f_b(a.d.i,a.c.i)){m=a.c;l=l7c(OC(GC(m1,1),nie,8,0,[m.n,m.a]));c7c(l,c)}else{l=A0b(a.c)}Gsb(d,l,d.a,d.a.a);n=A0b(a.d);vNb(a,utc)!=null&&P6c(n,BD(vNb(a,utc),8));Gsb(d,n,d.c.b,d.c);q7c(d,e);g=itd(f,true,true);kmd(g,BD(qud((!f.b&&(f.b=new y5d(z2,f,4,7)),f.b),0),82));lmd(g,BD(qud((!f.c&&(f.c=new y5d(z2,f,5,8)),f.c),0),82));ifd(d,g);for(k=new olb(a.b);k.a<k.c.c.length;){j=BD(mlb(k),70);h=BD(vNb(j,$sc),137);cld(h,j.o.a);ald(h,j.o.b);bld(h,j.n.a+e.a,j.n.b+e.b);jkd(h,(I9b(),H9b),DD(vNb(j,H9b)))}i=BD(vNb(a,(Nyc(),jxc)),74);if(i){q7c(i,e);jkd(f,jxc,i)}else{jkd(f,jxc,null)}b==(Aad(),yad)?jkd(f,Swc,yad):jkd(f,Swc,null)} +function mJc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;n=b.c.length;m=0;for(l=new olb(a.b);l.a<l.c.c.length;){k=BD(mlb(l),29);r=k.a;if(r.c.length==0){continue}q=new olb(r);j=0;s=null;e=BD(mlb(q),10);f=null;while(e){f=BD(Ikb(b,e.p),257);if(f.c>=0){i=null;h=new Bib(k.a,j+1);while(h.b<h.d.gc()){g=(sCb(h.b<h.d.gc()),BD(h.d.Xb(h.c=h.b++),10));i=BD(Ikb(b,g.p),257);if(i.d==f.d&&i.c<f.c){break}else{i=null}}if(i){if(s){Nkb(d,e.p,meb(BD(Ikb(d,e.p),19).a-1));BD(Ikb(c,s.p),15).Mc(f)}f=yJc(f,e,n++);b.c[b.c.length]=f;Ekb(c,new Rkb);if(s){BD(Ikb(c,s.p),15).Fc(f);Ekb(d,meb(1))}else{Ekb(d,meb(0))}}}o=null;if(q.a<q.c.c.length){o=BD(mlb(q),10);p=BD(Ikb(b,o.p),257);BD(Ikb(c,e.p),15).Fc(p);Nkb(d,o.p,meb(BD(Ikb(d,o.p),19).a+1))}f.d=m;f.c=j++;s=e;e=o}++m}} +function u6c(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;i=a;k=c7c(new f7c(b.a,b.b),a);j=c;l=c7c(new f7c(d.a,d.b),c);m=i.a;q=i.b;o=j.a;s=j.b;n=k.a;r=k.b;p=l.a;t=l.b;e=p*r-n*t;Iy();My(Jqe);if($wnd.Math.abs(0-e)<=Jqe||0==e||isNaN(0)&&isNaN(e)){return false}g=1/e*((m-o)*r-(q-s)*n);h=1/e*-(-(m-o)*t+(q-s)*p);f=(null,My(Jqe),($wnd.Math.abs(0-g)<=Jqe||0==g||isNaN(0)&&isNaN(g)?0:0<g?-1:0>g?1:Ny(isNaN(0),isNaN(g)))<0&&(null,My(Jqe),($wnd.Math.abs(g-1)<=Jqe||g==1||isNaN(g)&&isNaN(1)?0:g<1?-1:g>1?1:Ny(isNaN(g),isNaN(1)))<0)&&(null,My(Jqe),($wnd.Math.abs(0-h)<=Jqe||0==h||isNaN(0)&&isNaN(h)?0:0<h?-1:0>h?1:Ny(isNaN(0),isNaN(h)))<0)&&(null,My(Jqe),($wnd.Math.abs(h-1)<=Jqe||h==1||isNaN(h)&&isNaN(1)?0:h<1?-1:h>1?1:Ny(isNaN(h),isNaN(1)))<0));return f} +function z6d(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;for(l=new usb(new nsb(a));l.b!=l.c.a.d;){k=tsb(l);h=BD(k.d,56);b=BD(k.e,56);g=h.Tg();for(p=0,u=(g.i==null&&TKd(g),g.i).length;p<u;++p){j=(f=(g.i==null&&TKd(g),g.i),p>=0&&p<f.length?f[p]:null);if(j.Ij()&&!j.Jj()){if(JD(j,99)){i=BD(j,18);(i.Bb&ote)==0&&(w=zUd(i),!(!!w&&(w.Bb&ote)!=0))&&y6d(a,i,h,b)}else{Q6d();if(BD(j,66).Oj()){c=(v=j,BD(!v?null:BD(b,49).xh(v),153));if(c){n=BD(h.ah(j),153);d=c.gc();for(q=0,o=n.gc();q<o;++q){m=n.il(q);if(JD(m,99)){t=n.jl(q);e=Wrb(a,t);if(e==null&&t!=null){s=BD(m,18);if(!a.b||(s.Bb&ote)!=0||!!zUd(s)){continue}e=t}if(!c.dl(m,e)){for(r=0;r<d;++r){if(c.il(r)==m&&PD(c.jl(r))===PD(e)){c.ii(c.gc()-1,r);--d;break}}}}else{c.dl(n.il(q),n.jl(q))}}}}}}}}} +function CZc(a,b,c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r,s,t;r=xZc(b,c,a.g);e.n&&e.n&&!!f&&Tdd(e,i6d(f),(pgd(),mgd));if(a.b){for(q=0;q<r.c.length;q++){l=(tCb(q,r.c.length),BD(r.c[q],200));if(q!=0){n=(tCb(q-1,r.c.length),BD(r.c[q-1],200));w$c(l,n.f+n.b+a.g)}tZc(q,r,c,a.g);AZc(a,l);e.n&&!!f&&Tdd(e,i6d(f),(pgd(),mgd))}}else{for(p=new olb(r);p.a<p.c.c.length;){o=BD(mlb(p),200);for(k=new olb(o.a);k.a<k.c.c.length;){j=BD(mlb(k),187);s=new b$c(j.s,j.t,a.g);WZc(s,j);Ekb(o.d,s)}}}BZc(a,r);e.n&&e.n&&!!f&&Tdd(e,i6d(f),(pgd(),mgd));t=$wnd.Math.max(a.d,d.a-(g.b+g.c));m=$wnd.Math.max(a.c,d.b-(g.d+g.a));h=m-a.c;if(a.e&&a.f){i=t/m;i<a.a?(t=m*a.a):(h+=t/a.a-m)}a.e&&zZc(r,t,h);e.n&&e.n&&!!f&&Tdd(e,i6d(f),(pgd(),mgd));return new d$c(a.a,t,a.c+h,(k$c(),j$c))} +function UJc(a){var b,c,d,e,f,g,h,i,j,k,l;a.j=KC(WD,oje,25,a.g,15,1);a.o=new Rkb;MAb(LAb(new YAb(null,new Kub(a.e.b,16)),new aLc),new cLc(a));a.a=KC(sbb,dle,25,a.b,16,1);TAb(new YAb(null,new Kub(a.e.b,16)),new rLc(a));d=(l=new Rkb,MAb(JAb(LAb(new YAb(null,new Kub(a.e.b,16)),new hLc),new jLc(a)),new lLc(a,l)),l);for(i=new olb(d);i.a<i.c.c.length;){h=BD(mlb(i),508);if(h.c.length<=1){continue}if(h.c.length==2){uKc(h);bKc((tCb(0,h.c.length),BD(h.c[0],17)).d.i)||Ekb(a.o,h);continue}if(tKc(h)||sKc(h,new fLc)){continue}j=new olb(h);e=null;while(j.a<j.c.c.length){b=BD(mlb(j),17);c=a.c[b.p];!e||j.a>=j.c.c.length?(k=JJc((j0b(),h0b),g0b)):(k=JJc((j0b(),g0b),g0b));k*=2;f=c.a.g;c.a.g=$wnd.Math.max(f,f+(k-f));g=c.b.g;c.b.g=$wnd.Math.max(g,g+(k-g));e=b}}} +function VNc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;v=Hx(a);k=new Rkb;h=a.c.length;l=h-1;m=h+1;while(v.a.c!=0){while(c.b!=0){t=(sCb(c.b!=0),BD(Nsb(c,c.a.a),112));Jwb(v.a,t)!=null;t.g=l--;YNc(t,b,c,d)}while(b.b!=0){u=(sCb(b.b!=0),BD(Nsb(b,b.a.a),112));Jwb(v.a,u)!=null;u.g=m++;YNc(u,b,c,d)}j=Rie;for(r=(g=new Ywb((new cxb((new Gjb(v.a)).a)).b),new Njb(g));sib(r.a.a);){q=(f=Wwb(r.a),BD(f.cd(),112));if(!d&&q.b>0&&q.a<=0){k.c=KC(SI,Uhe,1,0,5,1);k.c[k.c.length]=q;break}p=q.i-q.d;if(p>=j){if(p>j){k.c=KC(SI,Uhe,1,0,5,1);j=p}k.c[k.c.length]=q}}if(k.c.length!=0){i=BD(Ikb(k,Bub(e,k.c.length)),112);Jwb(v.a,i)!=null;i.g=m++;YNc(i,b,c,d);k.c=KC(SI,Uhe,1,0,5,1)}}s=a.c.length+1;for(o=new olb(a);o.a<o.c.c.length;){n=BD(mlb(o),112);n.g<h&&(n.g=n.g+s)}} +function SDb(a,b){var c;if(a.e){throw vbb(new Zdb((fdb(TM),Jke+TM.k+Kke)))}if(!lDb(a.a,b)){throw vbb(new hz(Lke+b+Mke))}if(b==a.d){return a}c=a.d;a.d=b;switch(c.g){case 0:switch(b.g){case 2:PDb(a);break;case 1:XDb(a);PDb(a);break;case 4:bEb(a);PDb(a);break;case 3:bEb(a);XDb(a);PDb(a);}break;case 2:switch(b.g){case 1:XDb(a);YDb(a);break;case 4:bEb(a);PDb(a);break;case 3:bEb(a);XDb(a);PDb(a);}break;case 1:switch(b.g){case 2:XDb(a);YDb(a);break;case 4:XDb(a);bEb(a);PDb(a);break;case 3:XDb(a);bEb(a);XDb(a);PDb(a);}break;case 4:switch(b.g){case 2:bEb(a);PDb(a);break;case 1:bEb(a);XDb(a);PDb(a);break;case 3:XDb(a);YDb(a);}break;case 3:switch(b.g){case 2:XDb(a);bEb(a);PDb(a);break;case 1:XDb(a);bEb(a);XDb(a);PDb(a);break;case 4:XDb(a);YDb(a);}}return a} +function tVb(a,b){var c;if(a.d){throw vbb(new Zdb((fdb(LP),Jke+LP.k+Kke)))}if(!cVb(a.a,b)){throw vbb(new hz(Lke+b+Mke))}if(b==a.c){return a}c=a.c;a.c=b;switch(c.g){case 0:switch(b.g){case 2:qVb(a);break;case 1:xVb(a);qVb(a);break;case 4:BVb(a);qVb(a);break;case 3:BVb(a);xVb(a);qVb(a);}break;case 2:switch(b.g){case 1:xVb(a);yVb(a);break;case 4:BVb(a);qVb(a);break;case 3:BVb(a);xVb(a);qVb(a);}break;case 1:switch(b.g){case 2:xVb(a);yVb(a);break;case 4:xVb(a);BVb(a);qVb(a);break;case 3:xVb(a);BVb(a);xVb(a);qVb(a);}break;case 4:switch(b.g){case 2:BVb(a);qVb(a);break;case 1:BVb(a);xVb(a);qVb(a);break;case 3:xVb(a);yVb(a);}break;case 3:switch(b.g){case 2:xVb(a);BVb(a);qVb(a);break;case 1:xVb(a);BVb(a);xVb(a);qVb(a);break;case 4:xVb(a);yVb(a);}}return a} +function UQb(a,b,c){var d,e,f,g,h,i,j,k;for(i=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));i.e!=i.i.gc();){h=BD(Dyd(i),33);for(e=new Sr(ur(_sd(h).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),79);!d.b&&(d.b=new y5d(z2,d,4,7));if(!(d.b.i<=1&&(!d.c&&(d.c=new y5d(z2,d,5,8)),d.c.i<=1))){throw vbb(new z2c('Graph must not contain hyperedges.'))}if(!Pld(d)&&h!=atd(BD(qud((!d.c&&(d.c=new y5d(z2,d,5,8)),d.c),0),82))){j=new gRb;tNb(j,d);yNb(j,(HSb(),FSb),d);dRb(j,BD(Wd(irb(c.f,h)),144));eRb(j,BD(Ohb(c,atd(BD(qud((!d.c&&(d.c=new y5d(z2,d,5,8)),d.c),0),82))),144));Ekb(b.c,j);for(g=new Fyd((!d.n&&(d.n=new cUd(D2,d,1,7)),d.n));g.e!=g.i.gc();){f=BD(Dyd(g),137);k=new mRb(j,f.a);tNb(k,f);yNb(k,FSb,f);k.e.a=$wnd.Math.max(f.g,1);k.e.b=$wnd.Math.max(f.f,1);lRb(k);Ekb(b.d,k)}}}}} +function OGb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;l=new LIb(a);iKb(l,!(b==(ead(),dad)||b==_9c));k=l.a;m=new p0b;for(e=(gHb(),OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb])),g=0,i=e.length;g<i;++g){c=e[g];j=xHb(k,dHb,c);!!j&&(m.d=$wnd.Math.max(m.d,j.Re()))}for(d=OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb]),f=0,h=d.length;f<h;++f){c=d[f];j=xHb(k,fHb,c);!!j&&(m.a=$wnd.Math.max(m.a,j.Re()))}for(p=OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb]),r=0,t=p.length;r<t;++r){n=p[r];j=xHb(k,n,dHb);!!j&&(m.b=$wnd.Math.max(m.b,j.Se()))}for(o=OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb]),q=0,s=o.length;q<s;++q){n=o[q];j=xHb(k,n,fHb);!!j&&(m.c=$wnd.Math.max(m.c,j.Se()))}if(m.d>0){m.d+=k.n.d;m.d+=k.d}if(m.a>0){m.a+=k.n.a;m.a+=k.d}if(m.b>0){m.b+=k.n.b;m.b+=k.d}if(m.c>0){m.c+=k.n.c;m.c+=k.d}return m} +function d6b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o;m=c.d;l=c.c;f=new f7c(c.f.a+c.d.b+c.d.c,c.f.b+c.d.d+c.d.a);g=f.b;for(j=new olb(a.a);j.a<j.c.c.length;){h=BD(mlb(j),10);if(h.k!=(j0b(),e0b)){continue}d=BD(vNb(h,(wtc(),Hsc)),61);e=BD(vNb(h,Isc),8);k=h.n;switch(d.g){case 2:k.a=c.f.a+m.c-l.a;break;case 4:k.a=-l.a-m.b;}o=0;switch(d.g){case 2:case 4:if(b==(dcd(),_bd)){n=Edb(ED(vNb(h,htc)));k.b=f.b*n-BD(vNb(h,(Nyc(),Txc)),8).b;o=k.b+e.b;M_b(h,false,true)}else if(b==$bd){k.b=Edb(ED(vNb(h,htc)))-BD(vNb(h,(Nyc(),Txc)),8).b;o=k.b+e.b;M_b(h,false,true)}}g=$wnd.Math.max(g,o)}c.f.b+=g-f.b;for(i=new olb(a.a);i.a<i.c.c.length;){h=BD(mlb(i),10);if(h.k!=(j0b(),e0b)){continue}d=BD(vNb(h,(wtc(),Hsc)),61);k=h.n;switch(d.g){case 1:k.b=-l.b-m.d;break;case 3:k.b=c.f.b+m.a-l.b;}}} +function nRc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B;e=BD(vNb(a,(mTc(),dTc)),33);j=Ohe;k=Ohe;h=Rie;i=Rie;for(w=Jsb(a.b,0);w.b!=w.d.c;){u=BD(Xsb(w),86);p=u.e;q=u.f;j=$wnd.Math.min(j,p.a-q.a/2);k=$wnd.Math.min(k,p.b-q.b/2);h=$wnd.Math.max(h,p.a+q.a/2);i=$wnd.Math.max(i,p.b+q.b/2)}o=BD(hkd(e,(JTc(),BTc)),116);n=new f7c(o.b-j,o.d-k);for(v=Jsb(a.b,0);v.b!=v.d.c;){u=BD(Xsb(v),86);m=vNb(u,dTc);if(JD(m,239)){f=BD(m,33);l=P6c(u.e,n);bld(f,l.a-f.g/2,l.b-f.f/2)}}for(t=Jsb(a.a,0);t.b!=t.d.c;){s=BD(Xsb(t),188);d=BD(vNb(s,dTc),79);if(d){b=s.a;r=new g7c(s.b.e);Gsb(b,r,b.a,b.a.a);A=new g7c(s.c.e);Gsb(b,A,b.c.b,b.c);qRc(r,BD(Ut(b,1),8),s.b.f);qRc(A,BD(Ut(b,b.b-2),8),s.c.f);c=itd(d,true,true);ifd(b,c)}}B=h-j+(o.b+o.c);g=i-k+(o.d+o.a);Afd(e,B,g,false,false)} +function xoc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;l=a.b;k=new Bib(l,0);Aib(k,new H1b(a));s=false;g=1;while(k.b<k.d.gc()){j=(sCb(k.b<k.d.gc()),BD(k.d.Xb(k.c=k.b++),29));p=(tCb(g,l.c.length),BD(l.c[g],29));q=Mu(j.a);r=q.c.length;for(o=new olb(q);o.a<o.c.c.length;){m=BD(mlb(o),10);$_b(m,p)}if(s){for(n=av(new ov(q),0);n.c.Sb();){m=BD(pv(n),10);for(f=new olb(Mu(R_b(m)));f.a<f.c.c.length;){e=BD(mlb(f),17);PZb(e,true);yNb(a,(wtc(),Asc),(Bcb(),true));d=Noc(a,e,r);c=BD(vNb(m,usc),305);t=BD(Ikb(d,d.c.length-1),17);c.k=t.c.i;c.n=t;c.b=e.d.i;c.c=e}}s=false}else{if(q.c.length!=0){b=(tCb(0,q.c.length),BD(q.c[0],10));if(b.k==(j0b(),d0b)){s=true;g=-1}}}++g}h=new Bib(a.b,0);while(h.b<h.d.gc()){i=(sCb(h.b<h.d.gc()),BD(h.d.Xb(h.c=h.b++),29));i.a.c.length==0&&uib(h)}} +function wKb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;k=BD(BD(Qc(a.r,b),21),84);if(k.gc()<=2||b==(Ucd(),zcd)||b==(Ucd(),Tcd)){AKb(a,b);return}p=a.u.Hc((rcd(),qcd));c=b==(Ucd(),Acd)?(vLb(),uLb):(vLb(),rLb);r=b==Acd?(EIb(),BIb):(EIb(),DIb);d=dLb(iLb(c),a.s);q=b==Acd?Pje:Qje;for(j=k.Kc();j.Ob();){h=BD(j.Pb(),111);if(!h.c||h.c.d.c.length<=0){continue}o=h.b.rf();n=h.e;l=h.c;m=l.i;m.b=(f=l.n,l.e.a+f.b+f.c);m.a=(g=l.n,l.e.b+g.d+g.a);if(p){m.c=n.a-(e=l.n,l.e.a+e.b+e.c)-a.s;p=false}else{m.c=n.a+o.a+a.s}ytb(r,lle);l.f=r;$Hb(l,(NHb(),MHb));Ekb(d.d,new BLb(m,bLb(d,m)));q=b==Acd?$wnd.Math.min(q,n.b):$wnd.Math.max(q,n.b+h.b.rf().b)}q+=b==Acd?-a.t:a.t;cLb((d.e=q,d));for(i=k.Kc();i.Ob();){h=BD(i.Pb(),111);if(!h.c||h.c.d.c.length<=0){continue}m=h.c.i;m.c-=h.e.a;m.d-=h.e.b}} +function IDc(a,b,c){var d;Odd(c,'StretchWidth layering',1);if(b.a.c.length==0){Qdd(c);return}a.c=b;a.t=0;a.u=0;a.i=Pje;a.g=Qje;a.d=Edb(ED(vNb(b,(Nyc(),lyc))));CDc(a);DDc(a);ADc(a);HDc(a);BDc(a);a.i=$wnd.Math.max(1,a.i);a.g=$wnd.Math.max(1,a.g);a.d=a.d/a.i;a.f=a.g/a.i;a.s=FDc(a);d=new H1b(a.c);Ekb(a.c.b,d);a.r=Mu(a.p);a.n=tlb(a.k,a.k.length);while(a.r.c.length!=0){a.o=JDc(a);if(!a.o||EDc(a)&&a.b.a.gc()!=0){KDc(a,d);d=new H1b(a.c);Ekb(a.c.b,d);ye(a.a,a.b);a.b.a.$b();a.t=a.u;a.u=0}else{if(EDc(a)){a.c.b.c=KC(SI,Uhe,1,0,5,1);d=new H1b(a.c);Ekb(a.c.b,d);a.t=0;a.u=0;a.b.a.$b();a.a.a.$b();++a.f;a.r=Mu(a.p);a.n=tlb(a.k,a.k.length)}else{$_b(a.o,d);Lkb(a.r,a.o);Qqb(a.b,a.o);a.t=a.t-a.k[a.o.p]*a.d+a.j[a.o.p];a.u+=a.e[a.o.p]*a.d}}}b.a.c=KC(SI,Uhe,1,0,5,1);smb(b.b);Qdd(c)} +function Mgc(a){var b,c,d,e;MAb(JAb(new YAb(null,new Kub(a.a.b,16)),new khc),new mhc);Kgc(a);MAb(JAb(new YAb(null,new Kub(a.a.b,16)),new ohc),new qhc);if(a.c==(Aad(),yad)){MAb(JAb(LAb(new YAb(null,new Kub(new Pib(a.f),1)),new yhc),new Ahc),new Chc(a));MAb(JAb(NAb(LAb(LAb(new YAb(null,new Kub(a.d.b,16)),new Ghc),new Ihc),new Khc),new Mhc),new Ohc(a))}e=new f7c(Pje,Pje);b=new f7c(Qje,Qje);for(d=new olb(a.a.b);d.a<d.c.c.length;){c=BD(mlb(d),57);e.a=$wnd.Math.min(e.a,c.d.c);e.b=$wnd.Math.min(e.b,c.d.d);b.a=$wnd.Math.max(b.a,c.d.c+c.d.b);b.b=$wnd.Math.max(b.b,c.d.d+c.d.a)}P6c(X6c(a.d.c),V6c(new f7c(e.a,e.b)));P6c(X6c(a.d.f),c7c(new f7c(b.a,b.b),e));Lgc(a,e,b);Uhb(a.f);Uhb(a.b);Uhb(a.g);Uhb(a.e);a.a.a.c=KC(SI,Uhe,1,0,5,1);a.a.b.c=KC(SI,Uhe,1,0,5,1);a.a=null;a.d=null} +function vZb(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;e=new Rkb;for(p=new olb(b.a);p.a<p.c.c.length;){o=BD(mlb(p),10);n=o.e;if(n){d=vZb(a,n,o);Gkb(e,d);sZb(a,n,o);if(BD(vNb(n,(wtc(),Ksc)),21).Hc((Orc(),Hrc))){s=BD(vNb(o,(Nyc(),Vxc)),98);m=BD(vNb(o,Yxc),174).Hc((rcd(),ncd));for(r=new olb(o.j);r.a<r.c.c.length;){q=BD(mlb(r),11);f=BD(Ohb(a.b,q),10);if(!f){f=Z$b(q,s,q.j,-(q.e.c.length-q.g.c.length),null,new d7c,q.o,BD(vNb(n,Lwc),103),n);yNb(f,$sc,q);Rhb(a.b,q,f);Ekb(n.a,f)}g=BD(Ikb(f.j,0),11);for(k=new olb(q.f);k.a<k.c.c.length;){j=BD(mlb(k),70);h=new p_b;h.o.a=j.o.a;h.o.b=j.o.b;Ekb(g.f,h);if(!m){t=q.j;l=0;tcd(BD(vNb(o,Yxc),21))&&(l=mfd(j.n,j.o,q.o,0,t));s==(dcd(),bcd)||(Ucd(),Ecd).Hc(t)?(h.o.a=l):(h.o.b=l)}}}}}}i=new Rkb;rZb(a,b,c,e,i);!!c&&tZb(a,b,c,i);return i} +function nEc(a,b,c){var d,e,f,g,h,i,j,k,l;if(a.c[b.c.p][b.p].e){return}else{a.c[b.c.p][b.p].e=true}a.c[b.c.p][b.p].b=0;a.c[b.c.p][b.p].d=0;a.c[b.c.p][b.p].a=null;for(k=new olb(b.j);k.a<k.c.c.length;){j=BD(mlb(k),11);l=c?new J0b(j):new R0b(j);for(i=l.Kc();i.Ob();){h=BD(i.Pb(),11);g=h.i;if(g.c==b.c){if(g!=b){nEc(a,g,c);a.c[b.c.p][b.p].b+=a.c[g.c.p][g.p].b;a.c[b.c.p][b.p].d+=a.c[g.c.p][g.p].d}}else{a.c[b.c.p][b.p].d+=a.g[h.p];++a.c[b.c.p][b.p].b}}}f=BD(vNb(b,(wtc(),ssc)),15);if(f){for(e=f.Kc();e.Ob();){d=BD(e.Pb(),10);if(b.c==d.c){nEc(a,d,c);a.c[b.c.p][b.p].b+=a.c[d.c.p][d.p].b;a.c[b.c.p][b.p].d+=a.c[d.c.p][d.p].d}}}if(a.c[b.c.p][b.p].b>0){a.c[b.c.p][b.p].d+=Cub(a.i,24)*lke*0.07000000029802322-0.03500000014901161;a.c[b.c.p][b.p].a=a.c[b.c.p][b.p].d/a.c[b.c.p][b.p].b}} +function m5b(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;for(o=new olb(a);o.a<o.c.c.length;){n=BD(mlb(o),10);n5b(n.n);n5b(n.o);o5b(n.f);r5b(n);t5b(n);for(q=new olb(n.j);q.a<q.c.c.length;){p=BD(mlb(q),11);n5b(p.n);n5b(p.a);n5b(p.o);G0b(p,s5b(p.j));f=BD(vNb(p,(Nyc(),Wxc)),19);!!f&&yNb(p,Wxc,meb(-f.a));for(e=new olb(p.g);e.a<e.c.c.length;){d=BD(mlb(e),17);for(c=Jsb(d.a,0);c.b!=c.d.c;){b=BD(Xsb(c),8);n5b(b)}i=BD(vNb(d,jxc),74);if(i){for(h=Jsb(i,0);h.b!=h.d.c;){g=BD(Xsb(h),8);n5b(g)}}for(l=new olb(d.b);l.a<l.c.c.length;){j=BD(mlb(l),70);n5b(j.n);n5b(j.o)}}for(m=new olb(p.f);m.a<m.c.c.length;){j=BD(mlb(m),70);n5b(j.n);n5b(j.o)}}if(n.k==(j0b(),e0b)){yNb(n,(wtc(),Hsc),s5b(BD(vNb(n,Hsc),61)));q5b(n)}for(k=new olb(n.b);k.a<k.c.c.length;){j=BD(mlb(k),70);r5b(j);n5b(j.o);n5b(j.n)}}} +function yQb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A;a.e=b;h=$Pb(b);w=new Rkb;for(d=new olb(h);d.a<d.c.c.length;){c=BD(mlb(d),15);A=new Rkb;w.c[w.c.length]=A;i=new Tqb;for(o=c.Kc();o.Ob();){n=BD(o.Pb(),33);f=wQb(a,n,true,0,0);A.c[A.c.length]=f;p=n.i;q=n.j;new f7c(p,q);m=(!n.n&&(n.n=new cUd(D2,n,1,7)),n.n);for(l=new Fyd(m);l.e!=l.i.gc();){j=BD(Dyd(l),137);e=wQb(a,j,false,p,q);A.c[A.c.length]=e}v=(!n.c&&(n.c=new cUd(F2,n,9,9)),n.c);for(s=new Fyd(v);s.e!=s.i.gc();){r=BD(Dyd(s),118);g=wQb(a,r,false,p,q);A.c[A.c.length]=g;t=r.i+p;u=r.j+q;m=(!r.n&&(r.n=new cUd(D2,r,1,7)),r.n);for(k=new Fyd(m);k.e!=k.i.gc();){j=BD(Dyd(k),137);e=wQb(a,j,false,t,u);A.c[A.c.length]=e}}ye(i,Dx(pl(OC(GC(KI,1),Uhe,20,0,[_sd(n),$sd(n)]))))}vQb(a,i,A)}a.f=new aPb(w);tNb(a.f,b);return a.f} +function Kqd(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G;D=Ohb(a.e,d);if(D==null){D=new eC;n=BD(D,183);s=b+'_s';t=s+e;m=new yC(t);cC(n,Vte,m)}C=BD(D,183);Qpd(c,C);G=new eC;Spd(G,'x',d.j);Spd(G,'y',d.k);cC(C,Yte,G);A=new eC;Spd(A,'x',d.b);Spd(A,'y',d.c);cC(C,'endPoint',A);l=Fhe((!d.a&&(d.a=new xMd(y2,d,5)),d.a));o=!l;if(o){w=new wB;f=new Srd(w);reb((!d.a&&(d.a=new xMd(y2,d,5)),d.a),f);cC(C,Ote,w)}i=dmd(d);u=!!i;u&&Tpd(a.a,C,Qte,kqd(a,dmd(d)));r=emd(d);v=!!r;v&&Tpd(a.a,C,Pte,kqd(a,emd(d)));j=(!d.e&&(d.e=new y5d(A2,d,10,9)),d.e).i==0;p=!j;if(p){B=new wB;g=new Urd(a,B);reb((!d.e&&(d.e=new y5d(A2,d,10,9)),d.e),g);cC(C,Ste,B)}k=(!d.g&&(d.g=new y5d(A2,d,9,10)),d.g).i==0;q=!k;if(q){F=new wB;h=new Wrd(a,F);reb((!d.g&&(d.g=new y5d(A2,d,9,10)),d.g),h);cC(C,Rte,F)}} +function eKb(a){$Jb();var b,c,d,e,f,g,h;d=a.f.n;for(g=ci(a.r).a.nc();g.Ob();){f=BD(g.Pb(),111);e=0;if(f.b.Xe((Y9c(),s9c))){e=Edb(ED(f.b.We(s9c)));if(e<0){switch(f.b.Hf().g){case 1:d.d=$wnd.Math.max(d.d,-e);break;case 3:d.a=$wnd.Math.max(d.a,-e);break;case 2:d.c=$wnd.Math.max(d.c,-e);break;case 4:d.b=$wnd.Math.max(d.b,-e);}}}if(tcd(a.u)){b=nfd(f.b,e);h=!BD(a.e.We(b9c),174).Hc((Idd(),zdd));c=false;switch(f.b.Hf().g){case 1:c=b>d.d;d.d=$wnd.Math.max(d.d,b);if(h&&c){d.d=$wnd.Math.max(d.d,d.a);d.a=d.d+e}break;case 3:c=b>d.a;d.a=$wnd.Math.max(d.a,b);if(h&&c){d.a=$wnd.Math.max(d.a,d.d);d.d=d.a+e}break;case 2:c=b>d.c;d.c=$wnd.Math.max(d.c,b);if(h&&c){d.c=$wnd.Math.max(d.b,d.c);d.b=d.c+e}break;case 4:c=b>d.b;d.b=$wnd.Math.max(d.b,b);if(h&&c){d.b=$wnd.Math.max(d.b,d.c);d.c=d.b+e}}}}} +function l3b(a){var b,c,d,e,f,g,h,i,j,k,l;for(j=new olb(a);j.a<j.c.c.length;){i=BD(mlb(j),10);g=BD(vNb(i,(Nyc(),mxc)),163);f=null;switch(g.g){case 1:case 2:f=(Gqc(),Fqc);break;case 3:case 4:f=(Gqc(),Dqc);}if(f){yNb(i,(wtc(),Bsc),(Gqc(),Fqc));f==Dqc?o3b(i,g,(KAc(),HAc)):f==Fqc&&o3b(i,g,(KAc(),IAc))}else{if(fcd(BD(vNb(i,Vxc),98))&&i.j.c.length!=0){b=true;for(l=new olb(i.j);l.a<l.c.c.length;){k=BD(mlb(l),11);if(!(k.j==(Ucd(),zcd)&&k.e.c.length-k.g.c.length>0||k.j==Tcd&&k.e.c.length-k.g.c.length<0)){b=false;break}for(e=new olb(k.g);e.a<e.c.c.length;){c=BD(mlb(e),17);h=BD(vNb(c.d.i,mxc),163);if(h==(Ctc(),ztc)||h==Atc){b=false;break}}for(d=new olb(k.e);d.a<d.c.c.length;){c=BD(mlb(d),17);h=BD(vNb(c.c.i,mxc),163);if(h==(Ctc(),xtc)||h==ytc){b=false;break}}}b&&o3b(i,g,(KAc(),JAc))}}}} +function lJc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;w=0;n=0;for(l=new olb(b.e);l.a<l.c.c.length;){k=BD(mlb(l),10);m=0;h=0;i=c?BD(vNb(k,hJc),19).a:Rie;r=d?BD(vNb(k,iJc),19).a:Rie;j=$wnd.Math.max(i,r);for(t=new olb(k.j);t.a<t.c.c.length;){s=BD(mlb(t),11);u=k.n.b+s.n.b+s.a.b;if(d){for(g=new olb(s.g);g.a<g.c.c.length;){f=BD(mlb(g),17);p=f.d;o=p.i;if(b!=a.a[o.p]){q=$wnd.Math.max(BD(vNb(o,hJc),19).a,BD(vNb(o,iJc),19).a);v=BD(vNb(f,(Nyc(),eyc)),19).a;if(v>=j&&v>=q){m+=o.n.b+p.n.b+p.a.b-u;++h}}}}if(c){for(g=new olb(s.e);g.a<g.c.c.length;){f=BD(mlb(g),17);p=f.c;o=p.i;if(b!=a.a[o.p]){q=$wnd.Math.max(BD(vNb(o,hJc),19).a,BD(vNb(o,iJc),19).a);v=BD(vNb(f,(Nyc(),eyc)),19).a;if(v>=j&&v>=q){m+=o.n.b+p.n.b+p.a.b-u;++h}}}}}if(h>0){w+=m/h;++n}}if(n>0){b.a=e*w/n;b.g=n}else{b.a=0;b.g=0}} +function oMc(a,b){var c,d,e,f,g,h,i,j,k,l,m;for(e=new olb(a.a.b);e.a<e.c.c.length;){c=BD(mlb(e),29);for(i=new olb(c.a);i.a<i.c.c.length;){h=BD(mlb(i),10);b.j[h.p]=h;b.i[h.p]=b.o==(eMc(),dMc)?Qje:Pje}}Uhb(a.c);g=a.a.b;b.c==(YLc(),WLc)&&(g=JD(g,152)?km(BD(g,152)):JD(g,131)?BD(g,131).a:JD(g,54)?new ov(g):new dv(g));UMc(a.e,b,a.b);Alb(b.p,null);for(f=g.Kc();f.Ob();){c=BD(f.Pb(),29);j=c.a;b.o==(eMc(),dMc)&&(j=JD(j,152)?km(BD(j,152)):JD(j,131)?BD(j,131).a:JD(j,54)?new ov(j):new dv(j));for(m=j.Kc();m.Ob();){l=BD(m.Pb(),10);b.g[l.p]==l&&pMc(a,l,b)}}qMc(a,b);for(d=g.Kc();d.Ob();){c=BD(d.Pb(),29);for(m=new olb(c.a);m.a<m.c.c.length;){l=BD(mlb(m),10);b.p[l.p]=b.p[b.g[l.p].p];if(l==b.g[l.p]){k=Edb(b.i[b.j[l.p].p]);(b.o==(eMc(),dMc)&&k>Qje||b.o==cMc&&k<Pje)&&(b.p[l.p]=Edb(b.p[l.p])+k)}}}a.e.cg()} +function PGb(a,b,c,d){var e,f,g,h,i;h=new LIb(b);rKb(h,d);e=true;if(!!a&&a.Xe((Y9c(),z8c))){f=BD(a.We((Y9c(),z8c)),103);e=f==(ead(),cad)||f==aad||f==bad}hKb(h,false);Hkb(h.e.wf(),new mKb(h,false,e));NJb(h,h.f,(gHb(),dHb),(Ucd(),Acd));NJb(h,h.f,fHb,Rcd);NJb(h,h.g,dHb,Tcd);NJb(h,h.g,fHb,zcd);PJb(h,Acd);PJb(h,Rcd);OJb(h,zcd);OJb(h,Tcd);$Jb();g=h.A.Hc((tdd(),pdd))&&h.B.Hc((Idd(),Ddd))?_Jb(h):null;!!g&&DHb(h.a,g);eKb(h);GJb(h);PKb(h);BJb(h);pKb(h);HKb(h);xKb(h,Acd);xKb(h,Rcd);CJb(h);oKb(h);if(!c){return h.o}cKb(h);LKb(h);xKb(h,zcd);xKb(h,Tcd);i=h.B.Hc((Idd(),Edd));RJb(h,i,Acd);RJb(h,i,Rcd);SJb(h,i,zcd);SJb(h,i,Tcd);MAb(new YAb(null,new Kub(new $ib(h.i),0)),new TJb);MAb(JAb(new YAb(null,ci(h.r).a.oc()),new VJb),new XJb);dKb(h);h.e.uf(h.o);MAb(new YAb(null,ci(h.r).a.oc()),new fKb);return h.o} +function JVb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;j=Pje;for(d=new olb(a.a.b);d.a<d.c.c.length;){b=BD(mlb(d),81);j=$wnd.Math.min(j,b.d.f.g.c+b.e.a)}n=new Psb;for(g=new olb(a.a.a);g.a<g.c.c.length;){f=BD(mlb(g),189);f.i=j;f.e==0&&(Gsb(n,f,n.c.b,n.c),true)}while(n.b!=0){f=BD(n.b==0?null:(sCb(n.b!=0),Nsb(n,n.a.a)),189);e=f.f.g.c;for(m=f.a.a.ec().Kc();m.Ob();){k=BD(m.Pb(),81);p=f.i+k.e.a;k.d.g||k.g.c<p?(k.o=p):(k.o=k.g.c)}e-=f.f.o;f.b+=e;a.c==(ead(),bad)||a.c==_9c?(f.c+=e):(f.c-=e);for(l=f.a.a.ec().Kc();l.Ob();){k=BD(l.Pb(),81);for(i=k.f.Kc();i.Ob();){h=BD(i.Pb(),81);fad(a.c)?(o=a.f.ef(k,h)):(o=a.f.ff(k,h));h.d.i=$wnd.Math.max(h.d.i,k.o+k.g.b+o-h.e.a);h.k||(h.d.i=$wnd.Math.max(h.d.i,h.g.c-h.e.a));--h.d.e;h.d.e==0&&Dsb(n,h.d)}}}for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),81);b.g.c=b.o}} +function ELb(a){var b,c,d,e,f,g,h,i;h=a.b;b=a.a;switch(BD(vNb(a,(fFb(),bFb)),427).g){case 0:Okb(h,new tpb(new bMb));break;case 1:default:Okb(h,new tpb(new gMb));}switch(BD(vNb(a,_Eb),428).g){case 1:Okb(h,new YLb);Okb(h,new lMb);Okb(h,new GLb);break;case 0:default:Okb(h,new YLb);Okb(h,new RLb);}switch(BD(vNb(a,dFb),250).g){case 0:i=new FMb;break;case 1:i=new zMb;break;case 2:i=new CMb;break;case 3:i=new wMb;break;case 5:i=new JMb(new CMb);break;case 4:i=new JMb(new zMb);break;case 7:i=new tMb(new JMb(new zMb),new JMb(new CMb));break;case 8:i=new tMb(new JMb(new wMb),new JMb(new CMb));break;case 6:default:i=new JMb(new wMb);}for(g=new olb(h);g.a<g.c.c.length;){f=BD(mlb(g),167);d=0;e=0;c=new vgd(meb(d),meb(e));while(gNb(b,f,d,e)){c=BD(i.Ce(c,f),46);d=BD(c.a,19).a;e=BD(c.b,19).a}dNb(b,f,d,e)}} +function qQb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A;f=a.f.b;m=f.a;k=f.b;o=a.e.g;n=a.e.f;_kd(a.e,f.a,f.b);w=m/o;A=k/n;for(j=new Fyd(Kkd(a.e));j.e!=j.i.gc();){i=BD(Dyd(j),137);dld(i,i.i*w);eld(i,i.j*A)}for(s=new Fyd(Yod(a.e));s.e!=s.i.gc();){r=BD(Dyd(s),118);u=r.i;v=r.j;u>0&&dld(r,u*w);v>0&&eld(r,v*A)}stb(a.b,new CQb);b=new Rkb;for(h=new nib((new eib(a.c)).a);h.b;){g=lib(h);d=BD(g.cd(),79);c=BD(g.dd(),395).a;e=itd(d,false,false);l=oQb(jtd(d),ofd(e),c);ifd(l,e);t=ktd(d);if(!!t&&Jkb(b,t,0)==-1){b.c[b.c.length]=t;pQb(t,(sCb(l.b!=0),BD(l.a.a.c,8)),c)}}for(q=new nib((new eib(a.d)).a);q.b;){p=lib(q);d=BD(p.cd(),79);c=BD(p.dd(),395).a;e=itd(d,false,false);l=oQb(ltd(d),w7c(ofd(e)),c);l=w7c(l);ifd(l,e);t=mtd(d);if(!!t&&Jkb(b,t,0)==-1){b.c[b.c.length]=t;pQb(t,(sCb(l.b!=0),BD(l.c.b.c,8)),c)}}} +function _Vc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B;if(c.c.length!=0){o=new Rkb;for(n=new olb(c);n.a<n.c.c.length;){m=BD(mlb(n),33);Ekb(o,new f7c(m.i,m.j))}d.n&&!!b&&Tdd(d,i6d(b),(pgd(),mgd));while(CVc(a,c)){AVc(a,c,false)}d.n&&!!b&&Tdd(d,i6d(b),(pgd(),mgd));h=0;i=0;e=null;if(c.c.length!=0){e=(tCb(0,c.c.length),BD(c.c[0],33));h=e.i-(tCb(0,o.c.length),BD(o.c[0],8)).a;i=e.j-(tCb(0,o.c.length),BD(o.c[0],8)).b}g=$wnd.Math.sqrt(h*h+i*i);l=cVc(c);f=1;while(l.a.gc()!=0){for(k=l.a.ec().Kc();k.Ob();){j=BD(k.Pb(),33);p=a.f;q=p.i+p.g/2;r=p.j+p.f/2;s=j.i+j.g/2;t=j.j+j.f/2;u=s-q;v=t-r;w=$wnd.Math.sqrt(u*u+v*v);A=u/w;B=v/w;dld(j,j.i+A*g);eld(j,j.j+B*g)}d.n&&!!b&&Tdd(d,i6d(b),(pgd(),mgd));l=cVc(new Tkb(l));++f}!!a.a&&a.a.lg(new Tkb(l));d.n&&!!b&&Tdd(d,i6d(b),(pgd(),mgd));_Vc(a,b,new Tkb(l),d)}} +function $2b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;p=a.n;q=a.o;m=a.d;l=Edb(ED(pBc(a,(Nyc(),iyc))));if(b){k=l*(b.gc()-1);n=0;for(i=b.Kc();i.Ob();){g=BD(i.Pb(),10);k+=g.o.a;n=$wnd.Math.max(n,g.o.b)}r=p.a-(k-q.a)/2;f=p.b-m.d+n;d=q.a/(b.gc()+1);e=d;for(h=b.Kc();h.Ob();){g=BD(h.Pb(),10);g.n.a=r;g.n.b=f-g.o.b;r+=g.o.a+l;j=Y2b(g);j.n.a=g.o.a/2-j.a.a;j.n.b=g.o.b;o=BD(vNb(g,(wtc(),vsc)),11);if(o.e.c.length+o.g.c.length==1){o.n.a=e-o.a.a;o.n.b=0;F0b(o,a)}e+=d}}if(c){k=l*(c.gc()-1);n=0;for(i=c.Kc();i.Ob();){g=BD(i.Pb(),10);k+=g.o.a;n=$wnd.Math.max(n,g.o.b)}r=p.a-(k-q.a)/2;f=p.b+q.b+m.a-n;d=q.a/(c.gc()+1);e=d;for(h=c.Kc();h.Ob();){g=BD(h.Pb(),10);g.n.a=r;g.n.b=f;r+=g.o.a+l;j=Y2b(g);j.n.a=g.o.a/2-j.a.a;j.n.b=0;o=BD(vNb(g,(wtc(),vsc)),11);if(o.e.c.length+o.g.c.length==1){o.n.a=e-o.a.a;o.n.b=q.b;F0b(o,a)}e+=d}}} +function q7b(a,b){var c,d,e,f,g,h;if(!BD(vNb(b,(wtc(),Ksc)),21).Hc((Orc(),Hrc))){return}for(h=new olb(b.a);h.a<h.c.c.length;){f=BD(mlb(h),10);if(f.k==(j0b(),h0b)){e=BD(vNb(f,(Nyc(),txc)),142);a.c=$wnd.Math.min(a.c,f.n.a-e.b);a.a=$wnd.Math.max(a.a,f.n.a+f.o.a+e.c);a.d=$wnd.Math.min(a.d,f.n.b-e.d);a.b=$wnd.Math.max(a.b,f.n.b+f.o.b+e.a)}}for(g=new olb(b.a);g.a<g.c.c.length;){f=BD(mlb(g),10);if(f.k!=(j0b(),h0b)){switch(f.k.g){case 2:d=BD(vNb(f,(Nyc(),mxc)),163);if(d==(Ctc(),ytc)){f.n.a=a.c-10;p7b(f,new x7b).Jb(new A7b(f));break}if(d==Atc){f.n.a=a.a+10;p7b(f,new D7b).Jb(new G7b(f));break}c=BD(vNb(f,Osc),303);if(c==(esc(),dsc)){o7b(f).Jb(new J7b(f));f.n.b=a.d-10;break}if(c==bsc){o7b(f).Jb(new M7b(f));f.n.b=a.b+10;break}break;default:throw vbb(new Wdb('The node type '+f.k+' is not supported by the '+zS));}}}} +function Y1b(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q;i=new f7c(d.i+d.g/2,d.j+d.f/2);n=M1b(d);o=BD(hkd(b,(Nyc(),Vxc)),98);q=BD(hkd(d,$xc),61);if(!hCd(gkd(d),Uxc)){d.i==0&&d.j==0?(p=0):(p=kfd(d,q));jkd(d,Uxc,p)}j=new f7c(b.g,b.f);e=Z$b(d,o,q,n,j,i,new f7c(d.g,d.f),BD(vNb(c,Lwc),103),c);yNb(e,(wtc(),$sc),d);f=BD(Ikb(e.j,0),11);E0b(f,W1b(d));yNb(e,Yxc,(rcd(),pqb(pcd)));l=BD(hkd(b,Yxc),174).Hc(ncd);for(h=new Fyd((!d.n&&(d.n=new cUd(D2,d,1,7)),d.n));h.e!=h.i.gc();){g=BD(Dyd(h),137);if(!Ccb(DD(hkd(g,Jxc)))&&!!g.a){m=Z1b(g);Ekb(f.f,m);if(!l){k=0;tcd(BD(hkd(b,Yxc),21))&&(k=mfd(new f7c(g.i,g.j),new f7c(g.g,g.f),new f7c(d.g,d.f),0,q));switch(q.g){case 2:case 4:m.o.a=k;break;case 1:case 3:m.o.b=k;}}}}yNb(e,tyc,ED(hkd(Xod(b),tyc)));yNb(e,uyc,ED(hkd(Xod(b),uyc)));yNb(e,ryc,ED(hkd(Xod(b),ryc)));Ekb(c.a,e);Rhb(a.a,d,e)} +function qUc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;Odd(c,'Processor arrange level',1);k=0;mmb();ktb(b,new Wsd((mTc(),ZSc)));f=b.b;h=Jsb(b,b.b);j=true;while(j&&h.b.b!=h.d.a){r=BD(Ysb(h),86);BD(vNb(r,ZSc),19).a==0?--f:(j=false)}v=new Jib(b,0,f);g=new Qsb(v);v=new Jib(b,f,b.b);i=new Qsb(v);if(g.b==0){for(o=Jsb(i,0);o.b!=o.d.c;){n=BD(Xsb(o),86);yNb(n,eTc,meb(k++))}}else{l=g.b;for(u=Jsb(g,0);u.b!=u.d.c;){t=BD(Xsb(u),86);yNb(t,eTc,meb(k++));d=URc(t);qUc(a,d,Udd(c,1/l|0));ktb(d,tmb(new Wsd(eTc)));m=new Psb;for(s=Jsb(d,0);s.b!=s.d.c;){r=BD(Xsb(s),86);for(q=Jsb(t.d,0);q.b!=q.d.c;){p=BD(Xsb(q),188);p.c==r&&(Gsb(m,p,m.c.b,m.c),true)}}Osb(t.d);ye(t.d,m);h=Jsb(i,i.b);e=t.d.b;j=true;while(0<e&&j&&h.b.b!=h.d.a){r=BD(Ysb(h),86);if(BD(vNb(r,ZSc),19).a==0){yNb(r,eTc,meb(k++));--e;Zsb(h)}else{j=false}}}}Qdd(c)} +function _8b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;Odd(b,'Inverted port preprocessing',1);k=a.b;j=new Bib(k,0);c=null;t=new Rkb;while(j.b<j.d.gc()){s=c;c=(sCb(j.b<j.d.gc()),BD(j.d.Xb(j.c=j.b++),29));for(n=new olb(t);n.a<n.c.c.length;){l=BD(mlb(n),10);$_b(l,s)}t.c=KC(SI,Uhe,1,0,5,1);for(o=new olb(c.a);o.a<o.c.c.length;){l=BD(mlb(o),10);if(l.k!=(j0b(),h0b)){continue}if(!fcd(BD(vNb(l,(Nyc(),Vxc)),98))){continue}for(r=X_b(l,(KAc(),HAc),(Ucd(),zcd)).Kc();r.Ob();){p=BD(r.Pb(),11);i=p.e;h=BD(Qkb(i,KC(AQ,jne,17,i.c.length,0,1)),474);for(e=h,f=0,g=e.length;f<g;++f){d=e[f];Z8b(a,p,d,t)}}for(q=X_b(l,IAc,Tcd).Kc();q.Ob();){p=BD(q.Pb(),11);i=p.g;h=BD(Qkb(i,KC(AQ,jne,17,i.c.length,0,1)),474);for(e=h,f=0,g=e.length;f<g;++f){d=e[f];$8b(a,p,d,t)}}}}for(m=new olb(t);m.a<m.c.c.length;){l=BD(mlb(m),10);$_b(l,c)}Qdd(b)} +function _1b(a,b,c,d,e,f){var g,h,i,j,k,l;j=new H0b;tNb(j,b);G0b(j,BD(hkd(b,(Nyc(),$xc)),61));yNb(j,(wtc(),$sc),b);F0b(j,c);l=j.o;l.a=b.g;l.b=b.f;k=j.n;k.a=b.i;k.b=b.j;Rhb(a.a,b,j);g=FAb(NAb(LAb(new YAb(null,(!b.e&&(b.e=new y5d(B2,b,7,4)),new Kub(b.e,16))),new m2b),new e2b),new o2b(b));g||(g=FAb(NAb(LAb(new YAb(null,(!b.d&&(b.d=new y5d(B2,b,8,5)),new Kub(b.d,16))),new q2b),new g2b),new s2b(b)));g||(g=FAb(new YAb(null,(!b.e&&(b.e=new y5d(B2,b,7,4)),new Kub(b.e,16))),new u2b));yNb(j,Nsc,(Bcb(),g?true:false));e_b(j,f,e,BD(hkd(b,Txc),8));for(i=new Fyd((!b.n&&(b.n=new cUd(D2,b,1,7)),b.n));i.e!=i.i.gc();){h=BD(Dyd(i),137);!Ccb(DD(hkd(h,Jxc)))&&!!h.a&&Ekb(j.f,Z1b(h))}switch(e.g){case 2:case 1:(j.j==(Ucd(),Acd)||j.j==Rcd)&&d.Fc((Orc(),Lrc));break;case 4:case 3:(j.j==(Ucd(),zcd)||j.j==Tcd)&&d.Fc((Orc(),Lrc));}return j} +function nQc(a,b,c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r,s,t;m=null;d==(FQc(),DQc)?(m=b):d==EQc&&(m=c);for(p=m.a.ec().Kc();p.Ob();){o=BD(p.Pb(),11);q=l7c(OC(GC(m1,1),nie,8,0,[o.i.n,o.n,o.a])).b;t=new Tqb;h=new Tqb;for(j=new b1b(o.b);llb(j.a)||llb(j.b);){i=BD(llb(j.a)?mlb(j.a):mlb(j.b),17);if(Ccb(DD(vNb(i,(wtc(),ltc))))!=e){continue}if(Jkb(f,i,0)!=-1){i.d==o?(r=i.c):(r=i.d);s=l7c(OC(GC(m1,1),nie,8,0,[r.i.n,r.n,r.a])).b;if($wnd.Math.abs(s-q)<0.2){continue}s<q?b.a._b(r)?Qqb(t,new vgd(DQc,i)):Qqb(t,new vgd(EQc,i)):b.a._b(r)?Qqb(h,new vgd(DQc,i)):Qqb(h,new vgd(EQc,i))}}if(t.a.gc()>1){n=new ZQc(o,t,d);reb(t,new PQc(a,n));g.c[g.c.length]=n;for(l=t.a.ec().Kc();l.Ob();){k=BD(l.Pb(),46);Lkb(f,k.b)}}if(h.a.gc()>1){n=new ZQc(o,h,d);reb(h,new RQc(a,n));g.c[g.c.length]=n;for(l=h.a.ec().Kc();l.Ob();){k=BD(l.Pb(),46);Lkb(f,k.b)}}}} +function $Wc(a){r4c(a,new E3c(L3c(P3c(M3c(O3c(N3c(new R3c,sre),'ELK Radial'),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new bXc),sre)));p4c(a,sre,uqe,Ksd(UWc));p4c(a,sre,wme,Ksd(XWc));p4c(a,sre,Fme,Ksd(NWc));p4c(a,sre,Tme,Ksd(OWc));p4c(a,sre,Eme,Ksd(PWc));p4c(a,sre,Gme,Ksd(MWc));p4c(a,sre,Dme,Ksd(QWc));p4c(a,sre,Hme,Ksd(TWc));p4c(a,sre,ore,Ksd(KWc));p4c(a,sre,nre,Ksd(LWc));p4c(a,sre,rre,Ksd(RWc));p4c(a,sre,lre,Ksd(SWc));p4c(a,sre,mre,Ksd(VWc));p4c(a,sre,pre,Ksd(WWc));p4c(a,sre,qre,Ksd(YWc))} +function LIb(a){var b;this.r=Cy(new OIb,new SIb);this.b=new Rpb(BD(Qb(F1),290));this.p=new Rpb(BD(Qb(F1),290));this.i=new Rpb(BD(Qb(DN),290));this.e=a;this.o=new g7c(a.rf());this.D=a.Df()||Ccb(DD(a.We((Y9c(),M8c))));this.A=BD(a.We((Y9c(),Y8c)),21);this.B=BD(a.We(b9c),21);this.q=BD(a.We(t9c),98);this.u=BD(a.We(x9c),21);if(!ucd(this.u)){throw vbb(new y2c('Invalid port label placement: '+this.u))}this.v=Ccb(DD(a.We(z9c)));this.j=BD(a.We(W8c),21);if(!Jbd(this.j)){throw vbb(new y2c('Invalid node label placement: '+this.j))}this.n=BD(bgd(a,U8c),116);this.k=Edb(ED(bgd(a,Q9c)));this.d=Edb(ED(bgd(a,P9c)));this.w=Edb(ED(bgd(a,X9c)));this.s=Edb(ED(bgd(a,R9c)));this.t=Edb(ED(bgd(a,S9c)));this.C=BD(bgd(a,V9c),142);this.c=2*this.d;b=!this.B.Hc((Idd(),zdd));this.f=new mIb(0,b,0);this.g=new mIb(1,b,0);lIb(this.f,(gHb(),eHb),this.g)} +function Lgd(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;t=0;o=0;n=0;m=1;for(s=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));s.e!=s.i.gc();){q=BD(Dyd(s),33);m+=sr(new Sr(ur(_sd(q).a.Kc(),new Sq)));B=q.g;o=$wnd.Math.max(o,B);l=q.f;n=$wnd.Math.max(n,l);t+=B*l}p=(!a.a&&(a.a=new cUd(E2,a,10,11)),a.a).i;g=t+2*d*d*m*p;f=$wnd.Math.sqrt(g);i=$wnd.Math.max(f*c,o);h=$wnd.Math.max(f/c,n);for(r=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));r.e!=r.i.gc();){q=BD(Dyd(r),33);C=e.b+(Cub(b,26)*ike+Cub(b,27)*jke)*(i-q.g);D=e.b+(Cub(b,26)*ike+Cub(b,27)*jke)*(h-q.f);dld(q,C);eld(q,D)}A=i+(e.b+e.c);w=h+(e.d+e.a);for(v=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));v.e!=v.i.gc();){u=BD(Dyd(v),33);for(k=new Sr(ur(_sd(u).a.Kc(),new Sq));Qr(k);){j=BD(Rr(k),79);Pld(j)||Kgd(j,b,A,w)}}A+=e.b+e.c;w+=e.d+e.a;Afd(a,A,w,false,true)} +function Jcb(a){var b,c,d,e,f,g,h,i,j,k,l;if(a==null){throw vbb(new Oeb(Xhe))}j=a;f=a.length;i=false;if(f>0){b=(BCb(0,a.length),a.charCodeAt(0));if(b==45||b==43){a=a.substr(1);--f;i=b==45}}if(f==0){throw vbb(new Oeb(Oje+j+'"'))}while(a.length>0&&(BCb(0,a.length),a.charCodeAt(0)==48)){a=a.substr(1);--f}if(f>(Neb(),Leb)[10]){throw vbb(new Oeb(Oje+j+'"'))}for(e=0;e<f;e++){if(Zcb((BCb(e,a.length),a.charCodeAt(e)))==-1){throw vbb(new Oeb(Oje+j+'"'))}}l=0;g=Jeb[10];k=Keb[10];h=Jbb(Meb[10]);c=true;d=f%g;if(d>0){l=-parseInt(a.substr(0,d),10);a=a.substr(d);f-=d;c=false}while(f>=g){d=parseInt(a.substr(0,g),10);a=a.substr(g);f-=g;if(c){c=false}else{if(ybb(l,h)<0){throw vbb(new Oeb(Oje+j+'"'))}l=Ibb(l,k)}l=Qbb(l,d)}if(ybb(l,0)>0){throw vbb(new Oeb(Oje+j+'"'))}if(!i){l=Jbb(l);if(ybb(l,0)<0){throw vbb(new Oeb(Oje+j+'"'))}}return l} +function Z6d(a,b){X6d();var c,d,e,f,g,h,i;this.a=new a7d(this);this.b=a;this.c=b;this.f=c2d(q1d((O6d(),M6d),b));if(this.f.dc()){if((h=t1d(M6d,a))==b){this.e=true;this.d=new Rkb;this.f=new oFd;this.f.Fc(Ewe);BD(V1d(p1d(M6d,bKd(a)),''),26)==a&&this.f.Fc(u1d(M6d,bKd(a)));for(e=g1d(M6d,a).Kc();e.Ob();){d=BD(e.Pb(),170);switch($1d(q1d(M6d,d))){case 4:{this.d.Fc(d);break}case 5:{this.f.Gc(c2d(q1d(M6d,d)));break}}}}else{Q6d();if(BD(b,66).Oj()){this.e=true;this.f=null;this.d=new Rkb;for(g=0,i=(a.i==null&&TKd(a),a.i).length;g<i;++g){d=(c=(a.i==null&&TKd(a),a.i),g>=0&&g<c.length?c[g]:null);for(f=_1d(q1d(M6d,d));f;f=_1d(q1d(M6d,f))){f==b&&this.d.Fc(d)}}}else if($1d(q1d(M6d,b))==1&&!!h){this.f=null;this.d=(m8d(),l8d)}else{this.f=null;this.e=true;this.d=(mmb(),new anb(b))}}}else{this.e=$1d(q1d(M6d,b))==5;this.f.Fb(W6d)&&(this.f=W6d)}} +function zKb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;c=0;d=yKb(a,b);m=a.s;n=a.t;for(j=BD(BD(Qc(a.r,b),21),84).Kc();j.Ob();){i=BD(j.Pb(),111);if(!i.c||i.c.d.c.length<=0){continue}o=i.b.rf();h=i.b.Xe((Y9c(),s9c))?Edb(ED(i.b.We(s9c))):0;k=i.c;l=k.i;l.b=(g=k.n,k.e.a+g.b+g.c);l.a=(f=k.n,k.e.b+f.d+f.a);switch(b.g){case 1:l.c=i.a?(o.a-l.b)/2:o.a+m;l.d=o.b+h+d;$Hb(k,(NHb(),KHb));_Hb(k,(EIb(),DIb));break;case 3:l.c=i.a?(o.a-l.b)/2:o.a+m;l.d=-h-d-l.a;$Hb(k,(NHb(),KHb));_Hb(k,(EIb(),BIb));break;case 2:l.c=-h-d-l.b;if(i.a){e=a.v?l.a:BD(Ikb(k.d,0),181).rf().b;l.d=(o.b-e)/2}else{l.d=o.b+n}$Hb(k,(NHb(),MHb));_Hb(k,(EIb(),CIb));break;case 4:l.c=o.a+h+d;if(i.a){e=a.v?l.a:BD(Ikb(k.d,0),181).rf().b;l.d=(o.b-e)/2}else{l.d=o.b+n}$Hb(k,(NHb(),LHb));_Hb(k,(EIb(),CIb));}(b==(Ucd(),Acd)||b==Rcd)&&(c=$wnd.Math.max(c,l.a))}c>0&&(BD(Mpb(a.b,b),124).a.b=c)} +function b3b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;Odd(b,'Comment pre-processing',1);c=0;i=new olb(a.a);while(i.a<i.c.c.length){h=BD(mlb(i),10);if(Ccb(DD(vNb(h,(Nyc(),pwc))))){++c;e=0;d=null;j=null;for(o=new olb(h.j);o.a<o.c.c.length;){m=BD(mlb(o),11);e+=m.e.c.length+m.g.c.length;if(m.e.c.length==1){d=BD(Ikb(m.e,0),17);j=d.c}if(m.g.c.length==1){d=BD(Ikb(m.g,0),17);j=d.d}}if(e==1&&j.e.c.length+j.g.c.length==1&&!Ccb(DD(vNb(j.i,pwc)))){c3b(h,d,j,j.i);nlb(i)}else{r=new Rkb;for(n=new olb(h.j);n.a<n.c.c.length;){m=BD(mlb(n),11);for(l=new olb(m.g);l.a<l.c.c.length;){k=BD(mlb(l),17);k.d.g.c.length==0||(r.c[r.c.length]=k,true)}for(g=new olb(m.e);g.a<g.c.c.length;){f=BD(mlb(g),17);f.c.e.c.length==0||(r.c[r.c.length]=f,true)}}for(q=new olb(r);q.a<q.c.c.length;){p=BD(mlb(q),17);PZb(p,true)}}}}b.n&&Sdd(b,'Found '+c+' comment boxes');Qdd(b)} +function f9b(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p;m=Edb(ED(vNb(a,(Nyc(),tyc))));n=Edb(ED(vNb(a,uyc)));l=Edb(ED(vNb(a,ryc)));h=a.o;f=BD(Ikb(a.j,0),11);g=f.n;p=d9b(f,l);if(!p){return}if(b.Hc((rcd(),ncd))){switch(BD(vNb(a,(wtc(),Hsc)),61).g){case 1:p.c=(h.a-p.b)/2-g.a;p.d=n;break;case 3:p.c=(h.a-p.b)/2-g.a;p.d=-n-p.a;break;case 2:if(c&&f.e.c.length==0&&f.g.c.length==0){k=d?p.a:BD(Ikb(f.f,0),70).o.b;p.d=(h.b-k)/2-g.b}else{p.d=h.b+n-g.b}p.c=-m-p.b;break;case 4:if(c&&f.e.c.length==0&&f.g.c.length==0){k=d?p.a:BD(Ikb(f.f,0),70).o.b;p.d=(h.b-k)/2-g.b}else{p.d=h.b+n-g.b}p.c=m;}}else if(b.Hc(pcd)){switch(BD(vNb(a,(wtc(),Hsc)),61).g){case 1:case 3:p.c=g.a+m;break;case 2:case 4:if(c&&!f.c){k=d?p.a:BD(Ikb(f.f,0),70).o.b;p.d=(h.b-k)/2-g.b}else{p.d=g.b+n}}}e=p.d;for(j=new olb(f.f);j.a<j.c.c.length;){i=BD(mlb(j),70);o=i.n;o.a=p.c;o.b=e;e+=i.o.b+l}} +function eae(){rEd(Q9,new Lae);rEd(S9,new qbe);rEd(T9,new Xbe);rEd(U9,new Cce);rEd(ZI,new Oce);rEd(GC(SD,1),new Rce);rEd(wI,new Uce);rEd(xI,new Xce);rEd(ZI,new hae);rEd(ZI,new kae);rEd(ZI,new nae);rEd(BI,new qae);rEd(ZI,new tae);rEd(yK,new wae);rEd(yK,new zae);rEd(ZI,new Cae);rEd(FI,new Fae);rEd(ZI,new Iae);rEd(ZI,new Oae);rEd(ZI,new Rae);rEd(ZI,new Uae);rEd(ZI,new Xae);rEd(GC(SD,1),new $ae);rEd(ZI,new bbe);rEd(ZI,new ebe);rEd(yK,new hbe);rEd(yK,new kbe);rEd(ZI,new nbe);rEd(JI,new tbe);rEd(ZI,new wbe);rEd(MI,new zbe);rEd(ZI,new Cbe);rEd(ZI,new Fbe);rEd(ZI,new Ibe);rEd(ZI,new Lbe);rEd(yK,new Obe);rEd(yK,new Rbe);rEd(ZI,new Ube);rEd(ZI,new $be);rEd(ZI,new bce);rEd(ZI,new ece);rEd(ZI,new hce);rEd(ZI,new kce);rEd(UI,new nce);rEd(ZI,new qce);rEd(ZI,new tce);rEd(ZI,new wce);rEd(UI,new zce);rEd(MI,new Fce);rEd(ZI,new Ice);rEd(JI,new Lce)} +function Bmd(b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;n=c.length;if(n>0){j=(BCb(0,c.length),c.charCodeAt(0));if(j!=64){if(j==37){m=c.lastIndexOf('%');k=false;if(m!=0&&(m==n-1||(k=(BCb(m+1,c.length),c.charCodeAt(m+1)==46)))){h=c.substr(1,m-1);u=dfb('%',h)?null:QEd(h);e=0;if(k){try{e=Icb(c.substr(m+2),Rie,Ohe)}catch(a){a=ubb(a);if(JD(a,127)){i=a;throw vbb(new rFd(i))}else throw vbb(a)}}for(r=pRd(b.Wg());r.Ob();){p=MRd(r);if(JD(p,510)){f=BD(p,590);t=f.d;if((u==null?t==null:dfb(u,t))&&e--==0){return f}}}return null}}l=c.lastIndexOf('.');o=l==-1?c:c.substr(0,l);d=0;if(l!=-1){try{d=Icb(c.substr(l+1),Rie,Ohe)}catch(a){a=ubb(a);if(JD(a,127)){o=c}else throw vbb(a)}}o=dfb('%',o)?null:QEd(o);for(q=pRd(b.Wg());q.Ob();){p=MRd(q);if(JD(p,191)){g=BD(p,191);s=g.ne();if((o==null?s==null:dfb(o,s))&&d--==0){return g}}}return null}}return rid(b,c)} +function f6b(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F;w=new Rkb;for(o=new olb(a.b);o.a<o.c.c.length;){n=BD(mlb(o),29);for(r=new olb(n.a);r.a<r.c.c.length;){p=BD(mlb(r),10);if(p.k!=(j0b(),e0b)){continue}if(!wNb(p,(wtc(),Gsc))){continue}s=null;u=null;t=null;for(C=new olb(p.j);C.a<C.c.c.length;){B=BD(mlb(C),11);switch(B.j.g){case 4:s=B;break;case 2:u=B;break;default:t=B;}}v=BD(Ikb(t.g,0),17);k=new t7c(v.a);j=new g7c(t.n);P6c(j,p.n);l=Jsb(k,0);Vsb(l,j);A=w7c(v.a);m=new g7c(t.n);P6c(m,p.n);Gsb(A,m,A.c.b,A.c);D=BD(vNb(p,Gsc),10);F=BD(Ikb(D.j,0),11);i=BD(Qkb(s.e,KC(AQ,jne,17,0,0,1)),474);for(d=i,f=0,h=d.length;f<h;++f){b=d[f];RZb(b,F);o7c(b.a,b.a.b,k)}i=k_b(u.g);for(c=i,e=0,g=c.length;e<g;++e){b=c[e];QZb(b,F);o7c(b.a,0,A)}QZb(v,null);RZb(v,null);w.c[w.c.length]=p}}for(q=new olb(w);q.a<q.c.c.length;){p=BD(mlb(q),10);$_b(p,null)}} +function lgb(){lgb=ccb;var a,b,c;new sgb(1,0);new sgb(10,0);new sgb(0,0);dgb=KC(bJ,nie,240,11,0,1);egb=KC(TD,$ie,25,100,15,1);fgb=OC(GC(UD,1),Vje,25,15,[1,5,25,125,625,3125,15625,78125,390625,1953125,9765625,48828125,244140625,1220703125,6103515625,30517578125,152587890625,762939453125,3814697265625,19073486328125,95367431640625,476837158203125,2384185791015625]);ggb=KC(WD,oje,25,fgb.length,15,1);hgb=OC(GC(UD,1),Vje,25,15,[1,10,100,_ie,10000,Wje,1000000,10000000,100000000,Jje,10000000000,100000000000,1000000000000,10000000000000,100000000000000,1000000000000000,10000000000000000]);igb=KC(WD,oje,25,hgb.length,15,1);jgb=KC(bJ,nie,240,11,0,1);a=0;for(;a<jgb.length;a++){dgb[a]=new sgb(a,0);jgb[a]=new sgb(0,a);egb[a]=48}for(;a<egb.length;a++){egb[a]=48}for(c=0;c<ggb.length;c++){ggb[c]=ugb(fgb[c])}for(b=0;b<igb.length;b++){igb[b]=ugb(hgb[b])}Dhb()} +function zrb(){function e(){this.obj=this.createObject()} +;e.prototype.createObject=function(a){return Object.create(null)};e.prototype.get=function(a){return this.obj[a]};e.prototype.set=function(a,b){this.obj[a]=b};e.prototype[hke]=function(a){delete this.obj[a]};e.prototype.keys=function(){return Object.getOwnPropertyNames(this.obj)};e.prototype.entries=function(){var b=this.keys();var c=this;var d=0;return {next:function(){if(d>=b.length)return {done:true};var a=b[d++];return {value:[a,c.get(a)],done:false}}}};if(!xrb()){e.prototype.createObject=function(){return {}};e.prototype.get=function(a){return this.obj[':'+a]};e.prototype.set=function(a,b){this.obj[':'+a]=b};e.prototype[hke]=function(a){delete this.obj[':'+a]};e.prototype.keys=function(){var a=[];for(var b in this.obj){b.charCodeAt(0)==58&&a.push(b.substring(1))}return a}}return e} +function cde(a){ade();var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;if(a==null)return null;l=a.length*8;if(l==0){return ''}h=l%24;n=l/24|0;m=h!=0?n+1:n;f=null;f=KC(TD,$ie,25,m*4,15,1);j=0;k=0;b=0;c=0;d=0;g=0;e=0;for(i=0;i<n;i++){b=a[e++];c=a[e++];d=a[e++];k=(c&15)<<24>>24;j=(b&3)<<24>>24;o=(b&-128)==0?b>>2<<24>>24:(b>>2^192)<<24>>24;p=(c&-128)==0?c>>4<<24>>24:(c>>4^240)<<24>>24;q=(d&-128)==0?d>>6<<24>>24:(d>>6^252)<<24>>24;f[g++]=_ce[o];f[g++]=_ce[p|j<<4];f[g++]=_ce[k<<2|q];f[g++]=_ce[d&63]}if(h==8){b=a[e];j=(b&3)<<24>>24;o=(b&-128)==0?b>>2<<24>>24:(b>>2^192)<<24>>24;f[g++]=_ce[o];f[g++]=_ce[j<<4];f[g++]=61;f[g++]=61}else if(h==16){b=a[e];c=a[e+1];k=(c&15)<<24>>24;j=(b&3)<<24>>24;o=(b&-128)==0?b>>2<<24>>24:(b>>2^192)<<24>>24;p=(c&-128)==0?c>>4<<24>>24:(c>>4^240)<<24>>24;f[g++]=_ce[o];f[g++]=_ce[p|j<<4];f[g++]=_ce[k<<2];f[g++]=61}return zfb(f,0,f.length)} +function mB(a,b){var c,d,e,f,g,h,i;a.e==0&&a.p>0&&(a.p=-(a.p-1));a.p>Rie&&dB(b,a.p-nje);g=b.q.getDate();ZA(b,1);a.k>=0&&aB(b,a.k);if(a.c>=0){ZA(b,a.c)}else if(a.k>=0){i=new fB(b.q.getFullYear()-nje,b.q.getMonth(),35);d=35-i.q.getDate();ZA(b,$wnd.Math.min(d,g))}else{ZA(b,g)}a.f<0&&(a.f=b.q.getHours());a.b>0&&a.f<12&&(a.f+=12);$A(b,a.f==24&&a.g?0:a.f);a.j>=0&&_A(b,a.j);a.n>=0&&bB(b,a.n);a.i>=0&&cB(b,wbb(Ibb(Abb(Cbb(b.q.getTime()),_ie),_ie),a.i));if(a.a){e=new eB;dB(e,e.q.getFullYear()-nje-80);Gbb(Cbb(b.q.getTime()),Cbb(e.q.getTime()))&&dB(b,e.q.getFullYear()-nje+100)}if(a.d>=0){if(a.c==-1){c=(7+a.d-b.q.getDay())%7;c>3&&(c-=7);h=b.q.getMonth();ZA(b,b.q.getDate()+c);b.q.getMonth()!=h&&ZA(b,b.q.getDate()+(c>0?-7:7))}else{if(b.q.getDay()!=a.d){return false}}}if(a.o>Rie){f=b.q.getTimezoneOffset();cB(b,wbb(Cbb(b.q.getTime()),(a.o-f)*60*_ie))}return true} +function z2b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;e=vNb(b,(wtc(),$sc));if(!JD(e,239)){return}o=BD(e,33);p=b.e;m=new g7c(b.c);f=b.d;m.a+=f.b;m.b+=f.d;u=BD(hkd(o,(Nyc(),Ixc)),174);if(uqb(u,(Idd(),Add))){n=BD(hkd(o,Kxc),116);w_b(n,f.a);z_b(n,f.d);x_b(n,f.b);y_b(n,f.c)}c=new Rkb;for(k=new olb(b.a);k.a<k.c.c.length;){i=BD(mlb(k),10);if(JD(vNb(i,$sc),239)){A2b(i,m)}else if(JD(vNb(i,$sc),186)&&!p){d=BD(vNb(i,$sc),118);s=b_b(b,i,d.g,d.f);bld(d,s.a,s.b)}for(r=new olb(i.j);r.a<r.c.c.length;){q=BD(mlb(r),11);MAb(JAb(new YAb(null,new Kub(q.g,16)),new G2b(i)),new I2b(c))}}if(p){for(r=new olb(p.j);r.a<r.c.c.length;){q=BD(mlb(r),11);MAb(JAb(new YAb(null,new Kub(q.g,16)),new K2b(p)),new M2b(c))}}t=BD(hkd(o,Swc),218);for(h=new olb(c);h.a<h.c.c.length;){g=BD(mlb(h),17);y2b(g,t,m)}B2b(b);for(j=new olb(b.a);j.a<j.c.c.length;){i=BD(mlb(j),10);l=i.e;!!l&&z2b(a,l)}} +function xSb(a){r4c(a,new E3c(Q3c(L3c(P3c(M3c(O3c(N3c(new R3c,ume),'ELK Force'),'Force-based algorithm provided by the Eclipse Layout Kernel. Implements methods that follow physical analogies by simulating forces that move the nodes into a balanced distribution. Currently the original Eades model and the Fruchterman - Reingold model are supported.'),new ASb),ume),qqb((Csd(),zsd),OC(GC(O3,1),Kie,237,0,[xsd])))));p4c(a,ume,vme,meb(1));p4c(a,ume,wme,80);p4c(a,ume,xme,5);p4c(a,ume,_le,tme);p4c(a,ume,yme,meb(1));p4c(a,ume,zme,(Bcb(),true));p4c(a,ume,ame,lSb);p4c(a,ume,Ame,Ksd(dSb));p4c(a,ume,Bme,Ksd(mSb));p4c(a,ume,Cme,false);p4c(a,ume,Dme,Ksd(jSb));p4c(a,ume,Eme,Ksd(iSb));p4c(a,ume,Fme,Ksd(hSb));p4c(a,ume,Gme,Ksd(gSb));p4c(a,ume,Hme,Ksd(nSb));p4c(a,ume,mme,Ksd(fSb));p4c(a,ume,pme,Ksd(vSb));p4c(a,ume,nme,Ksd(eSb));p4c(a,ume,rme,Ksd(qSb));p4c(a,ume,ome,Ksd(rSb))} +function GKb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;if(BD(BD(Qc(a.r,b),21),84).dc()){return}g=BD(Mpb(a.b,b),124);i=g.i;h=g.n;k=KIb(a,b);d=i.b-h.b-h.c;e=g.a.a;f=i.c+h.b;n=a.w;if((k==(Tbd(),Qbd)||k==Sbd)&&BD(BD(Qc(a.r,b),21),84).gc()==1){e=k==Qbd?e-2*a.w:e;k=Pbd}if(d<e&&!a.B.Hc((Idd(),Fdd))){if(k==Qbd){n+=(d-e)/(BD(BD(Qc(a.r,b),21),84).gc()+1);f+=n}else{n+=(d-e)/(BD(BD(Qc(a.r,b),21),84).gc()-1)}}else{if(d<e){e=k==Qbd?e-2*a.w:e;k=Pbd}switch(k.g){case 3:f+=(d-e)/2;break;case 4:f+=d-e;break;case 0:c=(d-e)/(BD(BD(Qc(a.r,b),21),84).gc()+1);n+=$wnd.Math.max(0,c);f+=n;break;case 1:c=(d-e)/(BD(BD(Qc(a.r,b),21),84).gc()-1);n+=$wnd.Math.max(0,c);}}for(m=BD(BD(Qc(a.r,b),21),84).Kc();m.Ob();){l=BD(m.Pb(),111);l.e.a=f+l.d.b;l.e.b=(j=l.b,j.Xe((Y9c(),s9c))?j.Hf()==(Ucd(),Acd)?-j.rf().b-Edb(ED(j.We(s9c))):Edb(ED(j.We(s9c))):j.Hf()==(Ucd(),Acd)?-j.rf().b:0);f+=l.d.b+l.b.rf().a+l.d.c+n}} +function KKb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;if(BD(BD(Qc(a.r,b),21),84).dc()){return}g=BD(Mpb(a.b,b),124);i=g.i;h=g.n;l=KIb(a,b);d=i.a-h.d-h.a;e=g.a.b;f=i.d+h.d;o=a.w;j=a.o.a;if((l==(Tbd(),Qbd)||l==Sbd)&&BD(BD(Qc(a.r,b),21),84).gc()==1){e=l==Qbd?e-2*a.w:e;l=Pbd}if(d<e&&!a.B.Hc((Idd(),Fdd))){if(l==Qbd){o+=(d-e)/(BD(BD(Qc(a.r,b),21),84).gc()+1);f+=o}else{o+=(d-e)/(BD(BD(Qc(a.r,b),21),84).gc()-1)}}else{if(d<e){e=l==Qbd?e-2*a.w:e;l=Pbd}switch(l.g){case 3:f+=(d-e)/2;break;case 4:f+=d-e;break;case 0:c=(d-e)/(BD(BD(Qc(a.r,b),21),84).gc()+1);o+=$wnd.Math.max(0,c);f+=o;break;case 1:c=(d-e)/(BD(BD(Qc(a.r,b),21),84).gc()-1);o+=$wnd.Math.max(0,c);}}for(n=BD(BD(Qc(a.r,b),21),84).Kc();n.Ob();){m=BD(n.Pb(),111);m.e.a=(k=m.b,k.Xe((Y9c(),s9c))?k.Hf()==(Ucd(),Tcd)?-k.rf().a-Edb(ED(k.We(s9c))):j+Edb(ED(k.We(s9c))):k.Hf()==(Ucd(),Tcd)?-k.rf().a:j);m.e.b=f+m.d.d;f+=m.d.d+m.b.rf().b+m.d.a+o}} +function Abc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;a.n=Edb(ED(vNb(a.g,(Nyc(),vyc))));a.e=Edb(ED(vNb(a.g,pyc)));a.i=a.g.b.c.length;h=a.i-1;m=0;a.j=0;a.k=0;a.a=Ou(KC(JI,nie,19,a.i,0,1));a.b=Ou(KC(BI,nie,333,a.i,7,1));for(g=new olb(a.g.b);g.a<g.c.c.length;){e=BD(mlb(g),29);e.p=h;for(l=new olb(e.a);l.a<l.c.c.length;){k=BD(mlb(l),10);k.p=m;++m}--h}a.f=KC(WD,oje,25,m,15,1);a.c=IC(WD,[nie,oje],[48,25],15,[m,3],2);a.o=new Rkb;a.p=new Rkb;b=0;a.d=0;for(f=new olb(a.g.b);f.a<f.c.c.length;){e=BD(mlb(f),29);h=e.p;d=0;p=0;i=e.a.c.length;j=0;for(l=new olb(e.a);l.a<l.c.c.length;){k=BD(mlb(l),10);m=k.p;a.f[m]=k.c.p;j+=k.o.b+a.n;c=sr(new Sr(ur(R_b(k).a.Kc(),new Sq)));o=sr(new Sr(ur(U_b(k).a.Kc(),new Sq)));a.c[m][0]=o-c;a.c[m][1]=c;a.c[m][2]=o;d+=c;p+=o;c>0&&Ekb(a.p,k);Ekb(a.o,k)}b-=d;n=i+b;j+=b*a.e;Nkb(a.a,h,meb(n));Nkb(a.b,h,j);a.j=$wnd.Math.max(a.j,n);a.k=$wnd.Math.max(a.k,j);a.d+=b;b+=p}} +function Ucd(){Ucd=ccb;var a;Scd=new Ycd(ole,0);Acd=new Ycd(xle,1);zcd=new Ycd(yle,2);Rcd=new Ycd(zle,3);Tcd=new Ycd(Ale,4);Fcd=(mmb(),new zob((a=BD(gdb(F1),9),new xqb(a,BD(_Bb(a,a.length),9),0))));Gcd=Up(qqb(Acd,OC(GC(F1,1),bne,61,0,[])));Bcd=Up(qqb(zcd,OC(GC(F1,1),bne,61,0,[])));Ocd=Up(qqb(Rcd,OC(GC(F1,1),bne,61,0,[])));Qcd=Up(qqb(Tcd,OC(GC(F1,1),bne,61,0,[])));Lcd=Up(qqb(Acd,OC(GC(F1,1),bne,61,0,[Rcd])));Ecd=Up(qqb(zcd,OC(GC(F1,1),bne,61,0,[Tcd])));Ncd=Up(qqb(Acd,OC(GC(F1,1),bne,61,0,[Tcd])));Hcd=Up(qqb(Acd,OC(GC(F1,1),bne,61,0,[zcd])));Pcd=Up(qqb(Rcd,OC(GC(F1,1),bne,61,0,[Tcd])));Ccd=Up(qqb(zcd,OC(GC(F1,1),bne,61,0,[Rcd])));Kcd=Up(qqb(Acd,OC(GC(F1,1),bne,61,0,[zcd,Tcd])));Dcd=Up(qqb(zcd,OC(GC(F1,1),bne,61,0,[Rcd,Tcd])));Mcd=Up(qqb(Acd,OC(GC(F1,1),bne,61,0,[Rcd,Tcd])));Icd=Up(qqb(Acd,OC(GC(F1,1),bne,61,0,[zcd,Rcd])));Jcd=Up(qqb(Acd,OC(GC(F1,1),bne,61,0,[zcd,Rcd,Tcd])))} +function fSc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;if(b.b!=0){n=new Psb;h=null;o=null;d=QD($wnd.Math.floor($wnd.Math.log(b.b)*$wnd.Math.LOG10E)+1);i=0;for(t=Jsb(b,0);t.b!=t.d.c;){r=BD(Xsb(t),86);if(PD(o)!==PD(vNb(r,(mTc(),$Sc)))){o=GD(vNb(r,$Sc));i=0}o!=null?(h=o+iSc(i++,d)):(h=iSc(i++,d));yNb(r,$Sc,h);for(q=(e=Jsb((new ZRc(r)).a.d,0),new aSc(e));Wsb(q.a);){p=BD(Xsb(q.a),188).c;Gsb(n,p,n.c.b,n.c);yNb(p,$Sc,h)}}m=new Lqb;for(g=0;g<h.length-d;g++){for(s=Jsb(b,0);s.b!=s.d.c;){r=BD(Xsb(s),86);j=qfb(GD(vNb(r,(mTc(),$Sc))),0,g+1);c=(j==null?Wd(irb(m.f,null)):Crb(m.g,j))!=null?BD(j==null?Wd(irb(m.f,null)):Crb(m.g,j),19).a+1:1;Shb(m,j,meb(c))}}for(l=new nib((new eib(m)).a);l.b;){k=lib(l);f=meb(Ohb(a.a,k.cd())!=null?BD(Ohb(a.a,k.cd()),19).a:0);Shb(a.a,GD(k.cd()),meb(BD(k.dd(),19).a+f.a));f=BD(Ohb(a.b,k.cd()),19);(!f||f.a<BD(k.dd(),19).a)&&Shb(a.b,GD(k.cd()),BD(k.dd(),19))}fSc(a,n)}} +function PCc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;Odd(c,'Interactive node layering',1);d=new Rkb;for(n=new olb(b.a);n.a<n.c.c.length;){l=BD(mlb(n),10);j=l.n.a;i=j+l.o.a;i=$wnd.Math.max(j+1,i);r=new Bib(d,0);e=null;while(r.b<r.d.gc()){p=(sCb(r.b<r.d.gc()),BD(r.d.Xb(r.c=r.b++),569));if(p.c>=i){sCb(r.b>0);r.a.Xb(r.c=--r.b);break}else if(p.a>j){if(!e){Ekb(p.b,l);p.c=$wnd.Math.min(p.c,j);p.a=$wnd.Math.max(p.a,i);e=p}else{Gkb(e.b,p.b);e.a=$wnd.Math.max(e.a,p.a);uib(r)}}}if(!e){e=new TCc;e.c=j;e.a=i;Aib(r,e);Ekb(e.b,l)}}h=b.b;k=0;for(q=new olb(d);q.a<q.c.c.length;){p=BD(mlb(q),569);f=new H1b(b);f.p=k++;h.c[h.c.length]=f;for(o=new olb(p.b);o.a<o.c.c.length;){l=BD(mlb(o),10);$_b(l,f);l.p=0}}for(m=new olb(b.a);m.a<m.c.c.length;){l=BD(mlb(m),10);l.p==0&&OCc(a,l,b)}g=new Bib(h,0);while(g.b<g.d.gc()){(sCb(g.b<g.d.gc()),BD(g.d.Xb(g.c=g.b++),29)).a.c.length==0&&uib(g)}b.a.c=KC(SI,Uhe,1,0,5,1);Qdd(c)} +function Snc(a,b,c){var d,e,f,g,h,i,j,k,l,m;if(b.e.c.length!=0&&c.e.c.length!=0){d=BD(Ikb(b.e,0),17).c.i;g=BD(Ikb(c.e,0),17).c.i;if(d==g){return beb(BD(vNb(BD(Ikb(b.e,0),17),(wtc(),Zsc)),19).a,BD(vNb(BD(Ikb(c.e,0),17),Zsc),19).a)}for(k=a.a,l=0,m=k.length;l<m;++l){j=k[l];if(j==d){return 1}else if(j==g){return -1}}}if(b.g.c.length!=0&&c.g.c.length!=0){f=BD(vNb(b,(wtc(),Xsc)),10);i=BD(vNb(c,Xsc),10);e=0;h=0;wNb(BD(Ikb(b.g,0),17),Zsc)&&(e=BD(vNb(BD(Ikb(b.g,0),17),Zsc),19).a);wNb(BD(Ikb(c.g,0),17),Zsc)&&(h=BD(vNb(BD(Ikb(b.g,0),17),Zsc),19).a);if(!!f&&f==i){if(Ccb(DD(vNb(BD(Ikb(b.g,0),17),ltc)))&&!Ccb(DD(vNb(BD(Ikb(c.g,0),17),ltc)))){return 1}else if(!Ccb(DD(vNb(BD(Ikb(b.g,0),17),ltc)))&&Ccb(DD(vNb(BD(Ikb(c.g,0),17),ltc)))){return -1}return e<h?-1:e>h?1:0}if(a.b){a.b._b(f)&&(e=BD(a.b.xc(f),19).a);a.b._b(i)&&(h=BD(a.b.xc(i),19).a)}return e<h?-1:e>h?1:0}return b.e.c.length!=0&&c.g.c.length!=0?1:-1} +function acc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A;Odd(b,Ine,1);p=new Rkb;w=new Rkb;for(j=new olb(a.b);j.a<j.c.c.length;){i=BD(mlb(j),29);r=-1;o=l_b(i.a);for(l=o,m=0,n=l.length;m<n;++m){k=l[m];++r;if(!(k.k==(j0b(),h0b)&&fcd(BD(vNb(k,(Nyc(),Vxc)),98)))){continue}ecd(BD(vNb(k,(Nyc(),Vxc)),98))||bcc(k);yNb(k,(wtc(),Psc),k);p.c=KC(SI,Uhe,1,0,5,1);w.c=KC(SI,Uhe,1,0,5,1);c=new Rkb;u=new Psb;Jq(u,Y_b(k,(Ucd(),Acd)));$bc(a,u,p,w,c);h=r;A=k;for(f=new olb(p);f.a<f.c.c.length;){d=BD(mlb(f),10);Z_b(d,h,i);++r;yNb(d,Psc,k);g=BD(Ikb(d.j,0),11);q=BD(vNb(g,$sc),11);Ccb(DD(vNb(q,nwc)))||BD(vNb(d,Qsc),15).Fc(A)}Osb(u);for(t=Y_b(k,Rcd).Kc();t.Ob();){s=BD(t.Pb(),11);Gsb(u,s,u.a,u.a.a)}$bc(a,u,w,null,c);v=k;for(e=new olb(w);e.a<e.c.c.length;){d=BD(mlb(e),10);Z_b(d,++r,i);yNb(d,Psc,k);g=BD(Ikb(d.j,0),11);q=BD(vNb(g,$sc),11);Ccb(DD(vNb(q,nwc)))||BD(vNb(v,Qsc),15).Fc(d)}c.c.length==0||yNb(k,ssc,c)}}Qdd(b)} +function SQb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I;l=BD(vNb(a,(HSb(),FSb)),33);r=Ohe;s=Ohe;p=Rie;q=Rie;for(u=new olb(a.e);u.a<u.c.c.length;){t=BD(mlb(u),144);C=t.d;D=t.e;r=$wnd.Math.min(r,C.a-D.a/2);s=$wnd.Math.min(s,C.b-D.b/2);p=$wnd.Math.max(p,C.a+D.a/2);q=$wnd.Math.max(q,C.b+D.b/2)}B=BD(hkd(l,(wSb(),kSb)),116);A=new f7c(B.b-r,B.d-s);for(h=new olb(a.e);h.a<h.c.c.length;){g=BD(mlb(h),144);w=vNb(g,FSb);if(JD(w,239)){n=BD(w,33);v=P6c(g.d,A);bld(n,v.a-n.g/2,v.b-n.f/2)}}for(d=new olb(a.c);d.a<d.c.c.length;){c=BD(mlb(d),282);j=BD(vNb(c,FSb),79);k=itd(j,true,true);F=(H=c7c(R6c(c.d.d),c.c.d),l6c(H,c.c.e.a,c.c.e.b),P6c(H,c.c.d));nmd(k,F.a,F.b);b=(I=c7c(R6c(c.c.d),c.d.d),l6c(I,c.d.e.a,c.d.e.b),P6c(I,c.d.d));gmd(k,b.a,b.b)}for(f=new olb(a.d);f.a<f.c.c.length;){e=BD(mlb(f),447);m=BD(vNb(e,FSb),137);o=P6c(e.d,A);bld(m,o.a,o.b)}G=p-r+(B.b+B.c);i=q-s+(B.d+B.a);Afd(l,G,i,false,true)} +function bmc(a){var b,c,d,e,f,g,h,i,j,k,l,m;c=null;i=null;e=BD(vNb(a.b,(Nyc(),Wwc)),376);if(e==(_Ac(),ZAc)){c=new Rkb;i=new Rkb}for(h=new olb(a.d);h.a<h.c.c.length;){g=BD(mlb(h),101);f=g.i;if(!f){continue}switch(g.e.g){case 0:b=BD(Fqb(new Gqb(g.b)),61);e==ZAc&&b==(Ucd(),Acd)?(c.c[c.c.length]=g,true):e==ZAc&&b==(Ucd(),Rcd)?(i.c[i.c.length]=g,true):_lc(g,b);break;case 1:j=g.a.d.j;k=g.c.d.j;j==(Ucd(),Acd)?amc(g,Acd,(Ajc(),xjc),g.a):k==Acd?amc(g,Acd,(Ajc(),yjc),g.c):j==Rcd?amc(g,Rcd,(Ajc(),yjc),g.a):k==Rcd&&amc(g,Rcd,(Ajc(),xjc),g.c);break;case 2:case 3:d=g.b;uqb(d,(Ucd(),Acd))?uqb(d,Rcd)?uqb(d,Tcd)?uqb(d,zcd)||amc(g,Acd,(Ajc(),yjc),g.c):amc(g,Acd,(Ajc(),xjc),g.a):amc(g,Acd,(Ajc(),wjc),null):amc(g,Rcd,(Ajc(),wjc),null);break;case 4:l=g.a.d.j;m=g.a.d.j;l==(Ucd(),Acd)||m==Acd?amc(g,Rcd,(Ajc(),wjc),null):amc(g,Acd,(Ajc(),wjc),null);}}if(c){c.c.length==0||$lc(c,(Ucd(),Acd));i.c.length==0||$lc(i,(Ucd(),Rcd))}} +function A2b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p;d=BD(vNb(a,(wtc(),$sc)),33);o=BD(vNb(a,(Nyc(),Gwc)),19).a;f=BD(vNb(a,nxc),19).a;jkd(d,Gwc,meb(o));jkd(d,nxc,meb(f));dld(d,a.n.a+b.a);eld(d,a.n.b+b.b);if(BD(hkd(d,Fxc),174).gc()!=0||!!a.e||PD(vNb(Q_b(a),Exc))===PD((Vzc(),Tzc))&&Jzc((Izc(),(!a.q?(mmb(),mmb(),kmb):a.q)._b(Cxc)?(m=BD(vNb(a,Cxc),197)):(m=BD(vNb(Q_b(a),Dxc),197)),m))){cld(d,a.o.a);ald(d,a.o.b)}for(l=new olb(a.j);l.a<l.c.c.length;){j=BD(mlb(l),11);p=vNb(j,$sc);if(JD(p,186)){e=BD(p,118);bld(e,j.n.a,j.n.b);jkd(e,$xc,j.j)}}n=BD(vNb(a,xxc),174).gc()!=0;for(i=new olb(a.b);i.a<i.c.c.length;){g=BD(mlb(i),70);if(n||BD(vNb(g,xxc),174).gc()!=0){c=BD(vNb(g,$sc),137);_kd(c,g.o.a,g.o.b);bld(c,g.n.a,g.n.b)}}if(!tcd(BD(vNb(a,Yxc),21))){for(k=new olb(a.j);k.a<k.c.c.length;){j=BD(mlb(k),11);for(h=new olb(j.f);h.a<h.c.c.length;){g=BD(mlb(h),70);c=BD(vNb(g,$sc),137);cld(c,g.o.a);ald(c,g.o.b);bld(c,g.n.a,g.n.b)}}}} +function gtd(a){var b,c,d,e,f;ytb(a,hue);switch((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b).i+(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c).i){case 0:throw vbb(new Wdb('The edge must have at least one source or target.'));case 1:return (!a.b&&(a.b=new y5d(z2,a,4,7)),a.b).i==0?Xod(atd(BD(qud((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c),0),82))):Xod(atd(BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82)));}if((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b).i==1&&(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c).i==1){e=atd(BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82));f=atd(BD(qud((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c),0),82));if(Xod(e)==Xod(f)){return Xod(e)}else if(e==Xod(f)){return e}else if(f==Xod(e)){return f}}d=ul(pl(OC(GC(KI,1),Uhe,20,0,[(!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),(!a.c&&(a.c=new y5d(z2,a,5,8)),a.c)])));b=atd(BD(Rr(d),82));while(Qr(d)){c=atd(BD(Rr(d),82));if(c!=b&&!ntd(c,b)){if(Xod(c)==Xod(b)){b=Xod(c)}else{b=htd(b,c);if(!b){return null}}}}return b} +function KNc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;Odd(c,'Polyline edge routing',1);q=Edb(ED(vNb(b,(Nyc(),Uwc))));n=Edb(ED(vNb(b,wyc)));e=Edb(ED(vNb(b,myc)));d=$wnd.Math.min(1,e/n);t=0;i=0;if(b.b.c.length!=0){u=HNc(BD(Ikb(b.b,0),29));t=0.4*d*u}h=new Bib(b.b,0);while(h.b<h.d.gc()){g=(sCb(h.b<h.d.gc()),BD(h.d.Xb(h.c=h.b++),29));f=Kq(g,DNc);f&&t>0&&(t-=n);h_b(g,t);k=0;for(m=new olb(g.a);m.a<m.c.c.length;){l=BD(mlb(m),10);j=0;for(p=new Sr(ur(U_b(l).a.Kc(),new Sq));Qr(p);){o=BD(Rr(p),17);r=A0b(o.c).b;s=A0b(o.d).b;if(g==o.d.i.c&&!OZb(o)){LNc(o,t,0.4*d*$wnd.Math.abs(r-s));if(o.c.j==(Ucd(),Tcd)){r=0;s=0}}j=$wnd.Math.max(j,$wnd.Math.abs(s-r))}switch(l.k.g){case 0:case 4:case 1:case 3:case 5:MNc(a,l,t,q);}k=$wnd.Math.max(k,j)}if(h.b<h.d.gc()){u=HNc((sCb(h.b<h.d.gc()),BD(h.d.Xb(h.c=h.b++),29)));k=$wnd.Math.max(k,u);sCb(h.b>0);h.a.Xb(h.c=--h.b)}i=0.4*d*k;!f&&h.b<h.d.gc()&&(i+=n);t+=g.c.a+i}a.a.a.$b();b.f.a=t;Qdd(c)} +function bic(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;k=new Lqb;i=new Hp;for(d=new olb(a.a.a.b);d.a<d.c.c.length;){b=BD(mlb(d),57);j=tgc(b);if(j){jrb(k.f,j,b)}else{s=ugc(b);if(s){for(f=new olb(s.k);f.a<f.c.c.length;){e=BD(mlb(f),17);Rc(i,e,b)}}}}for(c=new olb(a.a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),57);j=tgc(b);if(j){for(h=new Sr(ur(U_b(j).a.Kc(),new Sq));Qr(h);){g=BD(Rr(h),17);if(OZb(g)){continue}o=g.c;r=g.d;if((Ucd(),Lcd).Hc(g.c.j)&&Lcd.Hc(g.d.j)){continue}p=BD(Ohb(k,g.d.i),57);AFb(DFb(CFb(EFb(BFb(new FFb,0),100),a.c[b.a.d]),a.c[p.a.d]));if(o.j==Tcd&&l1b((z0b(),w0b,o))){for(m=BD(Qc(i,g),21).Kc();m.Ob();){l=BD(m.Pb(),57);if(l.d.c<b.d.c){n=a.c[l.a.d];q=a.c[b.a.d];if(n==q){continue}AFb(DFb(CFb(EFb(BFb(new FFb,1),100),n),q))}}}if(r.j==zcd&&g1b((z0b(),u0b,r))){for(m=BD(Qc(i,g),21).Kc();m.Ob();){l=BD(m.Pb(),57);if(l.d.c>b.d.c){n=a.c[b.a.d];q=a.c[l.a.d];if(n==q){continue}AFb(DFb(CFb(EFb(BFb(new FFb,1),100),n),q))}}}}}}} +function QEd(a){IEd();var b,c,d,e,f,g,h,i;if(a==null)return null;e=hfb(a,wfb(37));if(e<0){return a}else{i=new Wfb(a.substr(0,e));b=KC(SD,wte,25,4,15,1);h=0;d=0;for(g=a.length;e<g;e++){BCb(e,a.length);if(a.charCodeAt(e)==37&&a.length>e+2&&_Ed((BCb(e+1,a.length),a.charCodeAt(e+1)),xEd,yEd)&&_Ed((BCb(e+2,a.length),a.charCodeAt(e+2)),xEd,yEd)){c=dFd((BCb(e+1,a.length),a.charCodeAt(e+1)),(BCb(e+2,a.length),a.charCodeAt(e+2)));e+=2;if(d>0){(c&192)==128?(b[h++]=c<<24>>24):(d=0)}else if(c>=128){if((c&224)==192){b[h++]=c<<24>>24;d=2}else if((c&240)==224){b[h++]=c<<24>>24;d=3}else if((c&248)==240){b[h++]=c<<24>>24;d=4}}if(d>0){if(h==d){switch(h){case 2:{Kfb(i,((b[0]&31)<<6|b[1]&63)&aje);break}case 3:{Kfb(i,((b[0]&15)<<12|(b[1]&63)<<6|b[2]&63)&aje);break}}h=0;d=0}}else{for(f=0;f<h;++f){Kfb(i,b[f]&aje)}h=0;i.a+=String.fromCharCode(c)}}else{for(f=0;f<h;++f){Kfb(i,b[f]&aje)}h=0;Kfb(i,(BCb(e,a.length),a.charCodeAt(e)))}}return i.a}} +function wA(a,b,c,d,e){var f,g,h;uA(a,b);g=b[0];f=bfb(c.c,0);h=-1;if(nA(c)){if(d>0){if(g+d>a.length){return false}h=rA(a.substr(0,g+d),b)}else{h=rA(a,b)}}switch(f){case 71:h=oA(a,g,OC(GC(ZI,1),nie,2,6,[pje,qje]),b);e.e=h;return true;case 77:return zA(a,b,e,h,g);case 76:return BA(a,b,e,h,g);case 69:return xA(a,b,g,e);case 99:return AA(a,b,g,e);case 97:h=oA(a,g,OC(GC(ZI,1),nie,2,6,['AM','PM']),b);e.b=h;return true;case 121:return DA(a,b,g,h,c,e);case 100:if(h<=0){return false}e.c=h;return true;case 83:if(h<0){return false}return yA(h,g,b[0],e);case 104:h==12&&(h=0);case 75:case 72:if(h<0){return false}e.f=h;e.g=false;return true;case 107:if(h<0){return false}e.f=h;e.g=true;return true;case 109:if(h<0){return false}e.j=h;return true;case 115:if(h<0){return false}e.n=h;return true;case 90:if(g<a.length&&(BCb(g,a.length),a.charCodeAt(g)==90)){++b[0];e.o=0;return true}case 122:case 118:return CA(a,g,b,e);default:return false;}} +function vKb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;m=BD(BD(Qc(a.r,b),21),84);if(b==(Ucd(),zcd)||b==Tcd){zKb(a,b);return}f=b==Acd?(vLb(),rLb):(vLb(),uLb);u=b==Acd?(EIb(),DIb):(EIb(),BIb);c=BD(Mpb(a.b,b),124);d=c.i;e=d.c+w6c(OC(GC(UD,1),Vje,25,15,[c.n.b,a.C.b,a.k]));r=d.c+d.b-w6c(OC(GC(UD,1),Vje,25,15,[c.n.c,a.C.c,a.k]));g=dLb(iLb(f),a.t);s=b==Acd?Qje:Pje;for(l=m.Kc();l.Ob();){j=BD(l.Pb(),111);if(!j.c||j.c.d.c.length<=0){continue}q=j.b.rf();p=j.e;n=j.c;o=n.i;o.b=(i=n.n,n.e.a+i.b+i.c);o.a=(h=n.n,n.e.b+h.d+h.a);ytb(u,lle);n.f=u;$Hb(n,(NHb(),MHb));o.c=p.a-(o.b-q.a)/2;v=$wnd.Math.min(e,p.a);w=$wnd.Math.max(r,p.a+q.a);o.c<v?(o.c=v):o.c+o.b>w&&(o.c=w-o.b);Ekb(g.d,new BLb(o,bLb(g,o)));s=b==Acd?$wnd.Math.max(s,p.b+j.b.rf().b):$wnd.Math.min(s,p.b)}s+=b==Acd?a.t:-a.t;t=cLb((g.e=s,g));t>0&&(BD(Mpb(a.b,b),124).a.b=t);for(k=m.Kc();k.Ob();){j=BD(k.Pb(),111);if(!j.c||j.c.d.c.length<=0){continue}o=j.c.i;o.c-=j.e.a;o.d-=j.e.b}} +function SPb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;b=new Lqb;for(i=new Fyd(a);i.e!=i.i.gc();){h=BD(Dyd(i),33);c=new Tqb;Rhb(OPb,h,c);n=new aQb;e=BD(GAb(new YAb(null,new Lub(new Sr(ur($sd(h).a.Kc(),new Sq)))),Wyb(n,Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[(Fyb(),Dyb)])))),83);RPb(c,BD(e.xc((Bcb(),true)),14),new cQb);d=BD(GAb(JAb(BD(e.xc(false),15).Lc(),new eQb),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[Dyb]))),15);for(g=d.Kc();g.Ob();){f=BD(g.Pb(),79);m=ktd(f);if(m){j=BD(Wd(irb(b.f,m)),21);if(!j){j=UPb(m);jrb(b.f,m,j)}ye(c,j)}}e=BD(GAb(new YAb(null,new Lub(new Sr(ur(_sd(h).a.Kc(),new Sq)))),Wyb(n,Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[Dyb])))),83);RPb(c,BD(e.xc(true),14),new gQb);d=BD(GAb(JAb(BD(e.xc(false),15).Lc(),new iQb),Byb(new fzb,new dzb,new Ezb,OC(GC(xL,1),Kie,132,0,[Dyb]))),15);for(l=d.Kc();l.Ob();){k=BD(l.Pb(),79);m=mtd(k);if(m){j=BD(Wd(irb(b.f,m)),21);if(!j){j=UPb(m);jrb(b.f,m,j)}ye(c,j)}}}} +function rhb(a,b){phb();var c,d,e,f,g,h,i,j,k,l,m,n,o,p;i=ybb(a,0)<0;i&&(a=Jbb(a));if(ybb(a,0)==0){switch(b){case 0:return '0';case 1:return $je;case 2:return '0.00';case 3:return '0.000';case 4:return '0.0000';case 5:return '0.00000';case 6:return '0.000000';default:n=new Ufb;b<0?(n.a+='0E+',n):(n.a+='0E',n);n.a+=b==Rie?'2147483648':''+-b;return n.a;}}k=18;l=KC(TD,$ie,25,k+1,15,1);c=k;p=a;do{j=p;p=Abb(p,10);l[--c]=Tbb(wbb(48,Qbb(j,Ibb(p,10))))&aje}while(ybb(p,0)!=0);e=Qbb(Qbb(Qbb(k,c),b),1);if(b==0){i&&(l[--c]=45);return zfb(l,c,k-c)}if(b>0&&ybb(e,-6)>=0){if(ybb(e,0)>=0){f=c+Tbb(e);for(h=k-1;h>=f;h--){l[h+1]=l[h]}l[++f]=46;i&&(l[--c]=45);return zfb(l,c,k-c+1)}for(g=2;Gbb(g,wbb(Jbb(e),1));g++){l[--c]=48}l[--c]=46;l[--c]=48;i&&(l[--c]=45);return zfb(l,c,k-c)}o=c+1;d=k;m=new Vfb;i&&(m.a+='-',m);if(d-o>=1){Kfb(m,l[c]);m.a+='.';m.a+=zfb(l,c+1,k-c-1)}else{m.a+=zfb(l,c,k-c)}m.a+='E';ybb(e,0)>0&&(m.a+='+',m);m.a+=''+Ubb(e);return m.a} +function iQc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;a.e.a.$b();a.f.a.$b();a.c.c=KC(SI,Uhe,1,0,5,1);a.i.c=KC(SI,Uhe,1,0,5,1);a.g.a.$b();if(b){for(g=new olb(b.a);g.a<g.c.c.length;){f=BD(mlb(g),10);for(l=Y_b(f,(Ucd(),zcd)).Kc();l.Ob();){k=BD(l.Pb(),11);Qqb(a.e,k);for(e=new olb(k.g);e.a<e.c.c.length;){d=BD(mlb(e),17);if(OZb(d)){continue}Ekb(a.c,d);oQc(a,d);h=d.c.i.k;(h==(j0b(),h0b)||h==i0b||h==e0b||h==d0b)&&Ekb(a.j,d);n=d.d;m=n.i.c;m==c?Qqb(a.f,n):m==b?Qqb(a.e,n):Lkb(a.c,d)}}}}if(c){for(g=new olb(c.a);g.a<g.c.c.length;){f=BD(mlb(g),10);for(j=new olb(f.j);j.a<j.c.c.length;){i=BD(mlb(j),11);for(e=new olb(i.g);e.a<e.c.c.length;){d=BD(mlb(e),17);OZb(d)&&Qqb(a.g,d)}}for(l=Y_b(f,(Ucd(),Tcd)).Kc();l.Ob();){k=BD(l.Pb(),11);Qqb(a.f,k);for(e=new olb(k.g);e.a<e.c.c.length;){d=BD(mlb(e),17);if(OZb(d)){continue}Ekb(a.c,d);oQc(a,d);h=d.c.i.k;(h==(j0b(),h0b)||h==i0b||h==e0b||h==d0b)&&Ekb(a.j,d);n=d.d;m=n.i.c;m==c?Qqb(a.f,n):m==b?Qqb(a.e,n):Lkb(a.c,d)}}}}} +function Afd(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;q=new f7c(a.g,a.f);p=rfd(a);p.a=$wnd.Math.max(p.a,b);p.b=$wnd.Math.max(p.b,c);w=p.a/q.a;k=p.b/q.b;u=p.a-q.a;i=p.b-q.b;if(d){g=!Xod(a)?BD(hkd(a,(Y9c(),z8c)),103):BD(hkd(Xod(a),(Y9c(),z8c)),103);h=PD(hkd(a,(Y9c(),t9c)))===PD((dcd(),$bd));for(s=new Fyd((!a.c&&(a.c=new cUd(F2,a,9,9)),a.c));s.e!=s.i.gc();){r=BD(Dyd(s),118);t=BD(hkd(r,A9c),61);if(t==(Ucd(),Scd)){t=lfd(r,g);jkd(r,A9c,t)}switch(t.g){case 1:h||dld(r,r.i*w);break;case 2:dld(r,r.i+u);h||eld(r,r.j*k);break;case 3:h||dld(r,r.i*w);eld(r,r.j+i);break;case 4:h||eld(r,r.j*k);}}}_kd(a,p.a,p.b);if(e){for(m=new Fyd((!a.n&&(a.n=new cUd(D2,a,1,7)),a.n));m.e!=m.i.gc();){l=BD(Dyd(m),137);n=l.i+l.g/2;o=l.j+l.f/2;v=n/q.a;j=o/q.b;if(v+j>=1){if(v-j>0&&o>=0){dld(l,l.i+u);eld(l,l.j+i*j)}else if(v-j<0&&n>=0){dld(l,l.i+u*v);eld(l,l.j+i)}}}}jkd(a,(Y9c(),Y8c),(tdd(),f=BD(gdb(I1),9),new xqb(f,BD(_Bb(f,f.length),9),0)));return new f7c(w,k)} +function Yfd(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o;n=Xod(atd(BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82)));o=Xod(atd(BD(qud((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c),0),82)));l=n==o;h=new d7c;b=BD(hkd(a,(Zad(),Sad)),74);if(!!b&&b.b>=2){if((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i==0){c=(Fhd(),e=new rmd,e);wtd((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a),c)}else if((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i>1){m=new Oyd((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a));while(m.e!=m.i.gc()){Eyd(m)}}ifd(b,BD(qud((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a),0),202))}if(l){for(d=new Fyd((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a));d.e!=d.i.gc();){c=BD(Dyd(d),202);for(j=new Fyd((!c.a&&(c.a=new xMd(y2,c,5)),c.a));j.e!=j.i.gc();){i=BD(Dyd(j),469);h.a=$wnd.Math.max(h.a,i.a);h.b=$wnd.Math.max(h.b,i.b)}}}for(g=new Fyd((!a.n&&(a.n=new cUd(D2,a,1,7)),a.n));g.e!=g.i.gc();){f=BD(Dyd(g),137);k=BD(hkd(f,Yad),8);!!k&&bld(f,k.a,k.b);if(l){h.a=$wnd.Math.max(h.a,f.i+f.g);h.b=$wnd.Math.max(h.b,f.j+f.f)}}return h} +function yMc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B;t=b.c.length;e=new ULc(a.a,c,null,null);B=KC(UD,Vje,25,t,15,1);p=KC(UD,Vje,25,t,15,1);o=KC(UD,Vje,25,t,15,1);q=0;for(h=0;h<t;h++){p[h]=Ohe;o[h]=Rie}for(i=0;i<t;i++){d=(tCb(i,b.c.length),BD(b.c[i],180));B[i]=SLc(d);B[q]>B[i]&&(q=i);for(l=new olb(a.a.b);l.a<l.c.c.length;){k=BD(mlb(l),29);for(s=new olb(k.a);s.a<s.c.c.length;){r=BD(mlb(s),10);w=Edb(d.p[r.p])+Edb(d.d[r.p]);p[i]=$wnd.Math.min(p[i],w);o[i]=$wnd.Math.max(o[i],w+r.o.b)}}}A=KC(UD,Vje,25,t,15,1);for(j=0;j<t;j++){(tCb(j,b.c.length),BD(b.c[j],180)).o==(eMc(),cMc)?(A[j]=p[q]-p[j]):(A[j]=o[q]-o[j])}f=KC(UD,Vje,25,t,15,1);for(n=new olb(a.a.b);n.a<n.c.c.length;){m=BD(mlb(n),29);for(v=new olb(m.a);v.a<v.c.c.length;){u=BD(mlb(v),10);for(g=0;g<t;g++){f[g]=Edb((tCb(g,b.c.length),BD(b.c[g],180)).p[u.p])+Edb((tCb(g,b.c.length),BD(b.c[g],180)).d[u.p])+A[g]}f.sort(dcb(Ylb.prototype.te,Ylb,[]));e.p[u.p]=(f[1]+f[2])/2;e.d[u.p]=0}}return e} +function G3b(a,b,c){var d,e,f,g,h;d=b.i;f=a.i.o;e=a.i.d;h=a.n;g=l7c(OC(GC(m1,1),nie,8,0,[h,a.a]));switch(a.j.g){case 1:_Hb(b,(EIb(),BIb));d.d=-e.d-c-d.a;if(BD(BD(Ikb(b.d,0),181).We((wtc(),Ssc)),285)==(rbd(),nbd)){$Hb(b,(NHb(),MHb));d.c=g.a-Edb(ED(vNb(a,Ysc)))-c-d.b}else{$Hb(b,(NHb(),LHb));d.c=g.a+Edb(ED(vNb(a,Ysc)))+c}break;case 2:$Hb(b,(NHb(),LHb));d.c=f.a+e.c+c;if(BD(BD(Ikb(b.d,0),181).We((wtc(),Ssc)),285)==(rbd(),nbd)){_Hb(b,(EIb(),BIb));d.d=g.b-Edb(ED(vNb(a,Ysc)))-c-d.a}else{_Hb(b,(EIb(),DIb));d.d=g.b+Edb(ED(vNb(a,Ysc)))+c}break;case 3:_Hb(b,(EIb(),DIb));d.d=f.b+e.a+c;if(BD(BD(Ikb(b.d,0),181).We((wtc(),Ssc)),285)==(rbd(),nbd)){$Hb(b,(NHb(),MHb));d.c=g.a-Edb(ED(vNb(a,Ysc)))-c-d.b}else{$Hb(b,(NHb(),LHb));d.c=g.a+Edb(ED(vNb(a,Ysc)))+c}break;case 4:$Hb(b,(NHb(),MHb));d.c=-e.b-c-d.b;if(BD(BD(Ikb(b.d,0),181).We((wtc(),Ssc)),285)==(rbd(),nbd)){_Hb(b,(EIb(),BIb));d.d=g.b-Edb(ED(vNb(a,Ysc)))-c-d.a}else{_Hb(b,(EIb(),DIb));d.d=g.b+Edb(ED(vNb(a,Ysc)))+c}}} +function ded(a,b,c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I;n=0;D=0;for(i=new olb(a);i.a<i.c.c.length;){h=BD(mlb(i),33);zfd(h);n=$wnd.Math.max(n,h.g);D+=h.g*h.f}o=D/a.c.length;C=$dd(a,o);D+=a.c.length*C;n=$wnd.Math.max(n,$wnd.Math.sqrt(D*g))+c.b;H=c.b;I=c.d;m=0;k=c.b+c.c;B=new Psb;Dsb(B,meb(0));w=new Psb;j=new Bib(a,0);while(j.b<j.d.gc()){h=(sCb(j.b<j.d.gc()),BD(j.d.Xb(j.c=j.b++),33));G=h.g;l=h.f;if(H+G>n){if(f){Fsb(w,m);Fsb(B,meb(j.b-1))}H=c.b;I+=m+b;m=0;k=$wnd.Math.max(k,c.b+c.c+G)}dld(h,H);eld(h,I);k=$wnd.Math.max(k,H+G+c.c);m=$wnd.Math.max(m,l);H+=G+b}k=$wnd.Math.max(k,d);F=I+m+c.a;if(F<e){m+=e-F;F=e}if(f){H=c.b;j=new Bib(a,0);Fsb(B,meb(a.c.length));A=Jsb(B,0);r=BD(Xsb(A),19).a;Fsb(w,m);v=Jsb(w,0);u=0;while(j.b<j.d.gc()){if(j.b==r){H=c.b;u=Edb(ED(Xsb(v)));r=BD(Xsb(A),19).a}h=(sCb(j.b<j.d.gc()),BD(j.d.Xb(j.c=j.b++),33));s=h.f;ald(h,u);p=u;if(j.b==r){q=k-H-c.c;t=h.g;cld(h,q);Ffd(h,new f7c(q,p),new f7c(t,s))}H+=h.g+b}}return new f7c(k,F)} +function _Yb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C;Odd(b,'Compound graph postprocessor',1);c=Ccb(DD(vNb(a,(Nyc(),Byc))));h=BD(vNb(a,(wtc(),zsc)),224);k=new Tqb;for(r=h.ec().Kc();r.Ob();){q=BD(r.Pb(),17);g=new Tkb(h.cc(q));mmb();Okb(g,new EZb(a));v=zZb((tCb(0,g.c.length),BD(g.c[0],243)));A=AZb(BD(Ikb(g,g.c.length-1),243));t=v.i;f_b(A.i,t)?(s=t.e):(s=Q_b(t));l=aZb(q,g);Osb(q.a);m=null;for(f=new olb(g);f.a<f.c.c.length;){e=BD(mlb(f),243);p=new d7c;Y$b(p,e.a,s);n=e.b;d=new s7c;o7c(d,0,n.a);q7c(d,p);u=new g7c(A0b(n.c));w=new g7c(A0b(n.d));P6c(u,p);P6c(w,p);if(m){d.b==0?(o=w):(o=(sCb(d.b!=0),BD(d.a.a.c,8)));B=$wnd.Math.abs(m.a-o.a)>qme;C=$wnd.Math.abs(m.b-o.b)>qme;(!c&&B&&C||c&&(B||C))&&Dsb(q.a,u)}ye(q.a,d);d.b==0?(m=u):(m=(sCb(d.b!=0),BD(d.c.b.c,8)));bZb(n,l,p);if(AZb(e)==A){if(Q_b(A.i)!=e.a){p=new d7c;Y$b(p,Q_b(A.i),s)}yNb(q,utc,p)}cZb(n,q,s);k.a.zc(n,k)}QZb(q,v);RZb(q,A)}for(j=k.a.ec().Kc();j.Ob();){i=BD(j.Pb(),17);QZb(i,null);RZb(i,null)}Qdd(b)} +function KQb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;if(a.gc()==1){return BD(a.Xb(0),231)}else if(a.gc()<=0){return new kRb}for(e=a.Kc();e.Ob();){c=BD(e.Pb(),231);o=0;k=Ohe;l=Ohe;i=Rie;j=Rie;for(n=new olb(c.e);n.a<n.c.c.length;){m=BD(mlb(n),144);o+=BD(vNb(m,(wSb(),oSb)),19).a;k=$wnd.Math.min(k,m.d.a-m.e.a/2);l=$wnd.Math.min(l,m.d.b-m.e.b/2);i=$wnd.Math.max(i,m.d.a+m.e.a/2);j=$wnd.Math.max(j,m.d.b+m.e.b/2)}yNb(c,(wSb(),oSb),meb(o));yNb(c,(HSb(),ESb),new f7c(k,l));yNb(c,DSb,new f7c(i,j))}mmb();a.ad(new OQb);p=new kRb;tNb(p,BD(a.Xb(0),94));h=0;s=0;for(f=a.Kc();f.Ob();){c=BD(f.Pb(),231);q=c7c(R6c(BD(vNb(c,(HSb(),DSb)),8)),BD(vNb(c,ESb),8));h=$wnd.Math.max(h,q.a);s+=q.a*q.b}h=$wnd.Math.max(h,$wnd.Math.sqrt(s)*Edb(ED(vNb(p,(wSb(),bSb)))));r=Edb(ED(vNb(p,uSb)));t=0;u=0;g=0;b=r;for(d=a.Kc();d.Ob();){c=BD(d.Pb(),231);q=c7c(R6c(BD(vNb(c,(HSb(),DSb)),8)),BD(vNb(c,ESb),8));if(t+q.a>h){t=0;u+=g+r;g=0}JQb(p,c,t,u);b=$wnd.Math.max(b,t+q.a);g=$wnd.Math.max(g,q.b);t+=q.a+r}return p} +function Ioc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;k=new s7c;switch(a.a.g){case 3:m=BD(vNb(b.e,(wtc(),rtc)),15);n=BD(vNb(b.j,rtc),15);o=BD(vNb(b.f,rtc),15);c=BD(vNb(b.e,ptc),15);d=BD(vNb(b.j,ptc),15);e=BD(vNb(b.f,ptc),15);g=new Rkb;Gkb(g,m);n.Jc(new Loc);Gkb(g,JD(n,152)?km(BD(n,152)):JD(n,131)?BD(n,131).a:JD(n,54)?new ov(n):new dv(n));Gkb(g,o);f=new Rkb;Gkb(f,c);Gkb(f,JD(d,152)?km(BD(d,152)):JD(d,131)?BD(d,131).a:JD(d,54)?new ov(d):new dv(d));Gkb(f,e);yNb(b.f,rtc,g);yNb(b.f,ptc,f);yNb(b.f,stc,b.f);yNb(b.e,rtc,null);yNb(b.e,ptc,null);yNb(b.j,rtc,null);yNb(b.j,ptc,null);break;case 1:ye(k,b.e.a);Dsb(k,b.i.n);ye(k,Su(b.j.a));Dsb(k,b.a.n);ye(k,b.f.a);break;default:ye(k,b.e.a);ye(k,Su(b.j.a));ye(k,b.f.a);}Osb(b.f.a);ye(b.f.a,k);QZb(b.f,b.e.c);h=BD(vNb(b.e,(Nyc(),jxc)),74);j=BD(vNb(b.j,jxc),74);i=BD(vNb(b.f,jxc),74);if(!!h||!!j||!!i){l=new s7c;Goc(l,i);Goc(l,j);Goc(l,h);yNb(b.f,jxc,l)}QZb(b.j,null);RZb(b.j,null);QZb(b.e,null);RZb(b.e,null);$_b(b.a,null);$_b(b.i,null);!!b.g&&Ioc(a,b.g)} +function bde(a){ade();var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;if(a==null)return null;f=rfb(a);o=ede(f);if(o%4!=0){return null}p=o/4|0;if(p==0)return KC(SD,wte,25,0,15,1);l=null;b=0;c=0;d=0;e=0;g=0;h=0;i=0;j=0;n=0;m=0;k=0;l=KC(SD,wte,25,p*3,15,1);for(;n<p-1;n++){if(!dde(g=f[k++])||!dde(h=f[k++])||!dde(i=f[k++])||!dde(j=f[k++]))return null;b=$ce[g];c=$ce[h];d=$ce[i];e=$ce[j];l[m++]=(b<<2|c>>4)<<24>>24;l[m++]=((c&15)<<4|d>>2&15)<<24>>24;l[m++]=(d<<6|e)<<24>>24}if(!dde(g=f[k++])||!dde(h=f[k++])){return null}b=$ce[g];c=$ce[h];i=f[k++];j=f[k++];if($ce[i]==-1||$ce[j]==-1){if(i==61&&j==61){if((c&15)!=0)return null;q=KC(SD,wte,25,n*3+1,15,1);$fb(l,0,q,0,n*3);q[m]=(b<<2|c>>4)<<24>>24;return q}else if(i!=61&&j==61){d=$ce[i];if((d&3)!=0)return null;q=KC(SD,wte,25,n*3+2,15,1);$fb(l,0,q,0,n*3);q[m++]=(b<<2|c>>4)<<24>>24;q[m]=((c&15)<<4|d>>2&15)<<24>>24;return q}else{return null}}else{d=$ce[i];e=$ce[j];l[m++]=(b<<2|c>>4)<<24>>24;l[m++]=((c&15)<<4|d>>2&15)<<24>>24;l[m++]=(d<<6|e)<<24>>24}return l} +function Sbc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;Odd(b,Ine,1);o=BD(vNb(a,(Nyc(),Swc)),218);for(e=new olb(a.b);e.a<e.c.c.length;){d=BD(mlb(e),29);j=l_b(d.a);for(g=j,h=0,i=g.length;h<i;++h){f=g[h];if(f.k!=(j0b(),i0b)){continue}if(o==(Aad(),yad)){for(l=new olb(f.j);l.a<l.c.c.length;){k=BD(mlb(l),11);k.e.c.length==0||Vbc(k);k.g.c.length==0||Wbc(k)}}else if(JD(vNb(f,(wtc(),$sc)),17)){q=BD(vNb(f,$sc),17);r=BD(Y_b(f,(Ucd(),Tcd)).Kc().Pb(),11);s=BD(Y_b(f,zcd).Kc().Pb(),11);t=BD(vNb(r,$sc),11);u=BD(vNb(s,$sc),11);QZb(q,u);RZb(q,t);v=new g7c(s.i.n);v.a=l7c(OC(GC(m1,1),nie,8,0,[u.i.n,u.n,u.a])).a;Dsb(q.a,v);v=new g7c(r.i.n);v.a=l7c(OC(GC(m1,1),nie,8,0,[t.i.n,t.n,t.a])).a;Dsb(q.a,v)}else{if(f.j.c.length>=2){p=true;m=new olb(f.j);c=BD(mlb(m),11);n=null;while(m.a<m.c.c.length){n=c;c=BD(mlb(m),11);if(!pb(vNb(n,$sc),vNb(c,$sc))){p=false;break}}}else{p=false}for(l=new olb(f.j);l.a<l.c.c.length;){k=BD(mlb(l),11);k.e.c.length==0||Tbc(k,p);k.g.c.length==0||Ubc(k,p)}}$_b(f,null)}}Qdd(b)} +function KJc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B;t=a.c[(tCb(0,b.c.length),BD(b.c[0],17)).p];A=a.c[(tCb(1,b.c.length),BD(b.c[1],17)).p];if(t.a.e.e-t.a.a-(t.b.e.e-t.b.a)==0&&A.a.e.e-A.a.a-(A.b.e.e-A.b.a)==0){return false}r=t.b.e.f;if(!JD(r,10)){return false}q=BD(r,10);v=a.i[q.p];w=!q.c?-1:Jkb(q.c.a,q,0);f=Pje;if(w>0){e=BD(Ikb(q.c.a,w-1),10);g=a.i[e.p];B=$wnd.Math.ceil(jBc(a.n,e,q));f=v.a.e-q.d.d-(g.a.e+e.o.b+e.d.a)-B}j=Pje;if(w<q.c.a.c.length-1){i=BD(Ikb(q.c.a,w+1),10);k=a.i[i.p];B=$wnd.Math.ceil(jBc(a.n,i,q));j=k.a.e-i.d.d-(v.a.e+q.o.b+q.d.a)-B}if(c&&(Iy(),My(Jqe),$wnd.Math.abs(f-j)<=Jqe||f==j||isNaN(f)&&isNaN(j))){return true}d=gKc(t.a);h=-gKc(t.b);l=-gKc(A.a);s=gKc(A.b);p=t.a.e.e-t.a.a-(t.b.e.e-t.b.a)>0&&A.a.e.e-A.a.a-(A.b.e.e-A.b.a)<0;o=t.a.e.e-t.a.a-(t.b.e.e-t.b.a)<0&&A.a.e.e-A.a.a-(A.b.e.e-A.b.a)>0;n=t.a.e.e+t.b.a<A.b.e.e+A.a.a;m=t.a.e.e+t.b.a>A.b.e.e+A.a.a;u=0;!p&&!o&&(m?f+l>0?(u=l):j-d>0&&(u=d):n&&(f+h>0?(u=h):j-s>0&&(u=s)));v.a.e+=u;v.b&&(v.d.e+=u);return false} +function XGb(a,b,c){var d,e,f,g,h,i,j,k,l,m;d=new J6c(b.qf().a,b.qf().b,b.rf().a,b.rf().b);e=new I6c;if(a.c){for(g=new olb(b.wf());g.a<g.c.c.length;){f=BD(mlb(g),181);e.c=f.qf().a+b.qf().a;e.d=f.qf().b+b.qf().b;e.b=f.rf().a;e.a=f.rf().b;H6c(d,e)}}for(j=new olb(b.Cf());j.a<j.c.c.length;){i=BD(mlb(j),838);k=i.qf().a+b.qf().a;l=i.qf().b+b.qf().b;if(a.e){e.c=k;e.d=l;e.b=i.rf().a;e.a=i.rf().b;H6c(d,e)}if(a.d){for(g=new olb(i.wf());g.a<g.c.c.length;){f=BD(mlb(g),181);e.c=f.qf().a+k;e.d=f.qf().b+l;e.b=f.rf().a;e.a=f.rf().b;H6c(d,e)}}if(a.b){m=new f7c(-c,-c);if(BD(b.We((Y9c(),x9c)),174).Hc((rcd(),pcd))){for(g=new olb(i.wf());g.a<g.c.c.length;){f=BD(mlb(g),181);m.a+=f.rf().a+c;m.b+=f.rf().b+c}}m.a=$wnd.Math.max(m.a,0);m.b=$wnd.Math.max(m.b,0);VGb(d,i.Bf(),i.zf(),b,i,m,c)}}a.b&&VGb(d,b.Bf(),b.zf(),b,null,null,c);h=new K_b(b.Af());h.d=$wnd.Math.max(0,b.qf().b-d.d);h.a=$wnd.Math.max(0,d.d+d.a-(b.qf().b+b.rf().b));h.b=$wnd.Math.max(0,b.qf().a-d.c);h.c=$wnd.Math.max(0,d.c+d.b-(b.qf().a+b.rf().a));b.Ef(h)} +function wz(){var a=['\\u0000','\\u0001','\\u0002','\\u0003','\\u0004','\\u0005','\\u0006','\\u0007','\\b','\\t','\\n','\\u000B','\\f','\\r','\\u000E','\\u000F','\\u0010','\\u0011','\\u0012','\\u0013','\\u0014','\\u0015','\\u0016','\\u0017','\\u0018','\\u0019','\\u001A','\\u001B','\\u001C','\\u001D','\\u001E','\\u001F'];a[34]='\\"';a[92]='\\\\';a[173]='\\u00ad';a[1536]='\\u0600';a[1537]='\\u0601';a[1538]='\\u0602';a[1539]='\\u0603';a[1757]='\\u06dd';a[1807]='\\u070f';a[6068]='\\u17b4';a[6069]='\\u17b5';a[8203]='\\u200b';a[8204]='\\u200c';a[8205]='\\u200d';a[8206]='\\u200e';a[8207]='\\u200f';a[8232]='\\u2028';a[8233]='\\u2029';a[8234]='\\u202a';a[8235]='\\u202b';a[8236]='\\u202c';a[8237]='\\u202d';a[8238]='\\u202e';a[8288]='\\u2060';a[8289]='\\u2061';a[8290]='\\u2062';a[8291]='\\u2063';a[8292]='\\u2064';a[8298]='\\u206a';a[8299]='\\u206b';a[8300]='\\u206c';a[8301]='\\u206d';a[8302]='\\u206e';a[8303]='\\u206f';a[65279]='\\ufeff';a[65529]='\\ufff9';a[65530]='\\ufffa';a[65531]='\\ufffb';return a} +function pid(a,b,c){var d,e,f,g,h,i,j,k,l,m;i=new Rkb;l=b.length;g=AUd(c);for(j=0;j<l;++j){k=ifb(b,wfb(61),j);d=$hd(g,b.substr(j,k-j));e=KJd(d);f=e.Aj().Nh();switch(bfb(b,++k)){case 39:{h=gfb(b,39,++k);Ekb(i,new kGd(d,Pid(b.substr(k,h-k),f,e)));j=h+1;break}case 34:{h=gfb(b,34,++k);Ekb(i,new kGd(d,Pid(b.substr(k,h-k),f,e)));j=h+1;break}case 91:{m=new Rkb;Ekb(i,new kGd(d,m));n:for(;;){switch(bfb(b,++k)){case 39:{h=gfb(b,39,++k);Ekb(m,Pid(b.substr(k,h-k),f,e));k=h+1;break}case 34:{h=gfb(b,34,++k);Ekb(m,Pid(b.substr(k,h-k),f,e));k=h+1;break}case 110:{++k;if(b.indexOf('ull',k)==k){m.c[m.c.length]=null}else{throw vbb(new hz(kte))}k+=3;break}}if(k<l){switch(BCb(k,b.length),b.charCodeAt(k)){case 44:{break}case 93:{break n}default:{throw vbb(new hz('Expecting , or ]'))}}}else{break}}j=k+1;break}case 110:{++k;if(b.indexOf('ull',k)==k){Ekb(i,new kGd(d,null))}else{throw vbb(new hz(kte))}j=k+3;break}}if(j<l){BCb(j,b.length);if(b.charCodeAt(j)!=44){throw vbb(new hz('Expecting ,'))}}else{break}}return qid(a,i,c)} +function AKb(a,b){var c,d,e,f,g,h,i,j,k,l,m;j=BD(BD(Qc(a.r,b),21),84);g=bKb(a,b);c=a.u.Hc((rcd(),lcd));for(i=j.Kc();i.Ob();){h=BD(i.Pb(),111);if(!h.c||h.c.d.c.length<=0){continue}m=h.b.rf();k=h.c;l=k.i;l.b=(f=k.n,k.e.a+f.b+f.c);l.a=(e=k.n,k.e.b+e.d+e.a);switch(b.g){case 1:if(h.a){l.c=(m.a-l.b)/2;$Hb(k,(NHb(),KHb))}else if(g||c){l.c=-l.b-a.s;$Hb(k,(NHb(),MHb))}else{l.c=m.a+a.s;$Hb(k,(NHb(),LHb))}l.d=-l.a-a.t;_Hb(k,(EIb(),BIb));break;case 3:if(h.a){l.c=(m.a-l.b)/2;$Hb(k,(NHb(),KHb))}else if(g||c){l.c=-l.b-a.s;$Hb(k,(NHb(),MHb))}else{l.c=m.a+a.s;$Hb(k,(NHb(),LHb))}l.d=m.b+a.t;_Hb(k,(EIb(),DIb));break;case 2:if(h.a){d=a.v?l.a:BD(Ikb(k.d,0),181).rf().b;l.d=(m.b-d)/2;_Hb(k,(EIb(),CIb))}else if(g||c){l.d=-l.a-a.t;_Hb(k,(EIb(),BIb))}else{l.d=m.b+a.t;_Hb(k,(EIb(),DIb))}l.c=m.a+a.s;$Hb(k,(NHb(),LHb));break;case 4:if(h.a){d=a.v?l.a:BD(Ikb(k.d,0),181).rf().b;l.d=(m.b-d)/2;_Hb(k,(EIb(),CIb))}else if(g||c){l.d=-l.a-a.t;_Hb(k,(EIb(),BIb))}else{l.d=m.b+a.t;_Hb(k,(EIb(),DIb))}l.c=-l.b-a.s;$Hb(k,(NHb(),MHb));}g=false}} +function Kfe(a,b){wfe();var c,d,e,f,g,h,i,j,k,l,m,n,o;if(Vhb(Zee)==0){l=KC(lbb,nie,117,_ee.length,0,1);for(g=0;g<l.length;g++){l[g]=(++vfe,new $fe(4))}d=new Ifb;for(f=0;f<Yee.length;f++){k=(++vfe,new $fe(4));if(f<84){h=f*2;n=(BCb(h,wxe.length),wxe.charCodeAt(h));m=(BCb(h+1,wxe.length),wxe.charCodeAt(h+1));Ufe(k,n,m)}else{h=(f-84)*2;Ufe(k,afe[h],afe[h+1])}i=Yee[f];dfb(i,'Specials')&&Ufe(k,65520,65533);if(dfb(i,uxe)){Ufe(k,983040,1048573);Ufe(k,1048576,1114109)}Shb(Zee,i,k);Shb($ee,i,_fe(k));j=d.a.length;0<j?(d.a=d.a.substr(0,0)):0>j&&(d.a+=yfb(KC(TD,$ie,25,-j,15,1)));d.a+='Is';if(hfb(i,wfb(32))>=0){for(e=0;e<i.length;e++){BCb(e,i.length);i.charCodeAt(e)!=32&&Afb(d,(BCb(e,i.length),i.charCodeAt(e)))}}else{d.a+=''+i}Ofe(d.a,i,true)}Ofe(vxe,'Cn',false);Ofe(xxe,'Cn',true);c=(++vfe,new $fe(4));Ufe(c,0,lxe);Shb(Zee,'ALL',c);Shb($ee,'ALL',_fe(c));!bfe&&(bfe=new Lqb);Shb(bfe,vxe,vxe);!bfe&&(bfe=new Lqb);Shb(bfe,xxe,xxe);!bfe&&(bfe=new Lqb);Shb(bfe,'ALL','ALL')}o=b?BD(Phb(Zee,a),136):BD(Phb($ee,a),136);return o} +function c3b(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;m=false;l=false;if(fcd(BD(vNb(d,(Nyc(),Vxc)),98))){g=false;h=false;t:for(o=new olb(d.j);o.a<o.c.c.length;){n=BD(mlb(o),11);for(q=ul(pl(OC(GC(KI,1),Uhe,20,0,[new J0b(n),new R0b(n)])));Qr(q);){p=BD(Rr(q),11);if(!Ccb(DD(vNb(p.i,pwc)))){if(n.j==(Ucd(),Acd)){g=true;break t}if(n.j==Rcd){h=true;break t}}}}m=h&&!g;l=g&&!h}if(!m&&!l&&d.b.c.length!=0){k=0;for(j=new olb(d.b);j.a<j.c.c.length;){i=BD(mlb(j),70);k+=i.n.b+i.o.b/2}k/=d.b.c.length;s=k>=d.o.b/2}else{s=!l}if(s){r=BD(vNb(d,(wtc(),vtc)),15);if(!r){f=new Rkb;yNb(d,vtc,f)}else if(m){f=r}else{e=BD(vNb(d,tsc),15);if(!e){f=new Rkb;yNb(d,tsc,f)}else{r.gc()<=e.gc()?(f=r):(f=e)}}}else{e=BD(vNb(d,(wtc(),tsc)),15);if(!e){f=new Rkb;yNb(d,tsc,f)}else if(l){f=e}else{r=BD(vNb(d,vtc),15);if(!r){f=new Rkb;yNb(d,vtc,f)}else{e.gc()<=r.gc()?(f=e):(f=r)}}}f.Fc(a);yNb(a,(wtc(),vsc),c);if(b.d==c){RZb(b,null);c.e.c.length+c.g.c.length==0&&F0b(c,null);d3b(c)}else{QZb(b,null);c.e.c.length+c.g.c.length==0&&F0b(c,null)}Osb(b.a)} +function aoc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H;s=new Bib(a.b,0);k=b.Kc();o=0;j=BD(k.Pb(),19).a;v=0;c=new Tqb;A=new zsb;while(s.b<s.d.gc()){r=(sCb(s.b<s.d.gc()),BD(s.d.Xb(s.c=s.b++),29));for(u=new olb(r.a);u.a<u.c.c.length;){t=BD(mlb(u),10);for(n=new Sr(ur(U_b(t).a.Kc(),new Sq));Qr(n);){l=BD(Rr(n),17);A.a.zc(l,A)}for(m=new Sr(ur(R_b(t).a.Kc(),new Sq));Qr(m);){l=BD(Rr(m),17);A.a.Bc(l)!=null}}if(o+1==j){e=new H1b(a);Aib(s,e);f=new H1b(a);Aib(s,f);for(C=A.a.ec().Kc();C.Ob();){B=BD(C.Pb(),17);if(!c.a._b(B)){++v;c.a.zc(B,c)}g=new b0b(a);yNb(g,(Nyc(),Vxc),(dcd(),acd));$_b(g,e);__b(g,(j0b(),d0b));p=new H0b;F0b(p,g);G0b(p,(Ucd(),Tcd));D=new H0b;F0b(D,g);G0b(D,zcd);d=new b0b(a);yNb(d,Vxc,acd);$_b(d,f);__b(d,d0b);q=new H0b;F0b(q,d);G0b(q,Tcd);F=new H0b;F0b(F,d);G0b(F,zcd);w=new UZb;QZb(w,B.c);RZb(w,p);H=new UZb;QZb(H,D);RZb(H,q);QZb(B,F);h=new goc(g,d,w,H,B);yNb(g,(wtc(),usc),h);yNb(d,usc,h);G=w.c.i;if(G.k==d0b){i=BD(vNb(G,usc),305);i.d=h;h.g=i}}if(k.Ob()){j=BD(k.Pb(),19).a}else{break}}++o}return meb(v)} +function T1b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;l=0;for(e=new Fyd((!b.a&&(b.a=new cUd(E2,b,10,11)),b.a));e.e!=e.i.gc();){d=BD(Dyd(e),33);if(!Ccb(DD(hkd(d,(Nyc(),Jxc))))){if((PD(hkd(b,ywc))!==PD((tAc(),rAc))||PD(hkd(b,Jwc))===PD((mqc(),lqc))||PD(hkd(b,Jwc))===PD((mqc(),jqc))||Ccb(DD(hkd(b,Awc)))||PD(hkd(b,twc))!==PD((RXb(),QXb)))&&!Ccb(DD(hkd(d,xwc)))){jkd(d,(wtc(),Zsc),meb(l));++l}$1b(a,d,c)}}l=0;for(j=new Fyd((!b.b&&(b.b=new cUd(B2,b,12,3)),b.b));j.e!=j.i.gc();){h=BD(Dyd(j),79);if(PD(hkd(b,(Nyc(),ywc)))!==PD((tAc(),rAc))||PD(hkd(b,Jwc))===PD((mqc(),lqc))||PD(hkd(b,Jwc))===PD((mqc(),jqc))||Ccb(DD(hkd(b,Awc)))||PD(hkd(b,twc))!==PD((RXb(),QXb))){jkd(h,(wtc(),Zsc),meb(l));++l}o=jtd(h);p=ltd(h);k=Ccb(DD(hkd(o,fxc)));n=!Ccb(DD(hkd(h,Jxc)));m=k&&Qld(h)&&Ccb(DD(hkd(h,gxc)));f=Xod(o)==b&&Xod(o)==Xod(p);g=(Xod(o)==b&&p==b)^(Xod(p)==b&&o==b);n&&!m&&(g||f)&&X1b(a,h,b,c)}if(Xod(b)){for(i=new Fyd(Wod(Xod(b)));i.e!=i.i.gc();){h=BD(Dyd(i),79);o=jtd(h);if(o==b&&Qld(h)){m=Ccb(DD(hkd(o,(Nyc(),fxc))))&&Ccb(DD(hkd(h,gxc)));m&&X1b(a,h,b,c)}}}} +function gDc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I;Odd(c,'MinWidth layering',1);n=b.b;A=b.a;I=BD(vNb(b,(Nyc(),oxc)),19).a;h=BD(vNb(b,pxc),19).a;a.b=Edb(ED(vNb(b,lyc)));a.d=Pje;for(u=new olb(A);u.a<u.c.c.length;){s=BD(mlb(u),10);if(s.k!=(j0b(),h0b)){continue}D=s.o.b;a.d=$wnd.Math.min(a.d,D)}a.d=$wnd.Math.max(1,a.d);B=A.c.length;a.c=KC(WD,oje,25,B,15,1);a.f=KC(WD,oje,25,B,15,1);a.e=KC(UD,Vje,25,B,15,1);j=0;a.a=0;for(v=new olb(A);v.a<v.c.c.length;){s=BD(mlb(v),10);s.p=j++;a.c[s.p]=eDc(R_b(s));a.f[s.p]=eDc(U_b(s));a.e[s.p]=s.o.b/a.d;a.a+=a.e[s.p]}a.b/=a.d;a.a/=B;w=fDc(A);Okb(A,tmb(new mDc(a)));p=Pje;o=Ohe;g=null;H=I;G=I;f=h;e=h;if(I<0){H=BD(bDc.a.zd(),19).a;G=BD(bDc.b.zd(),19).a}if(h<0){f=BD(aDc.a.zd(),19).a;e=BD(aDc.b.zd(),19).a}for(F=H;F<=G;F++){for(d=f;d<=e;d++){C=dDc(a,F,d,A,w);r=Edb(ED(C.a));m=BD(C.b,15);q=m.gc();if(r<p||r==p&&q<o){p=r;o=q;g=m}}}for(l=g.Kc();l.Ob();){k=BD(l.Pb(),15);i=new H1b(b);for(t=k.Kc();t.Ob();){s=BD(t.Pb(),10);$_b(s,i)}n.c[n.c.length]=i}smb(n);A.c=KC(SI,Uhe,1,0,5,1);Qdd(c)} +function I6b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;a.b=b;a.a=BD(vNb(b,(Nyc(),bxc)),19).a;a.c=BD(vNb(b,dxc),19).a;a.c==0&&(a.c=Ohe);q=new Bib(b.b,0);while(q.b<q.d.gc()){p=(sCb(q.b<q.d.gc()),BD(q.d.Xb(q.c=q.b++),29));h=new Rkb;k=-1;u=-1;for(t=new olb(p.a);t.a<t.c.c.length;){s=BD(mlb(t),10);if(sr((D6b(),new Sr(ur(O_b(s).a.Kc(),new Sq))))>=a.a){d=E6b(a,s);k=$wnd.Math.max(k,d.b);u=$wnd.Math.max(u,d.d);Ekb(h,new vgd(s,d))}}B=new Rkb;for(j=0;j<k;++j){Dkb(B,0,(sCb(q.b>0),q.a.Xb(q.c=--q.b),C=new H1b(a.b),Aib(q,C),sCb(q.b<q.d.gc()),q.d.Xb(q.c=q.b++),C))}for(g=new olb(h);g.a<g.c.c.length;){e=BD(mlb(g),46);n=BD(e.b,571).a;if(!n){continue}for(m=new olb(n);m.a<m.c.c.length;){l=BD(mlb(m),10);H6b(a,l,B6b,B)}}c=new Rkb;for(i=0;i<u;++i){Ekb(c,(D=new H1b(a.b),Aib(q,D),D))}for(f=new olb(h);f.a<f.c.c.length;){e=BD(mlb(f),46);A=BD(e.b,571).c;if(!A){continue}for(w=new olb(A);w.a<w.c.c.length;){v=BD(mlb(w),10);H6b(a,v,C6b,c)}}}r=new Bib(b.b,0);while(r.b<r.d.gc()){o=(sCb(r.b<r.d.gc()),BD(r.d.Xb(r.c=r.b++),29));o.a.c.length==0&&uib(r)}} +function uQc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G;Odd(c,'Spline edge routing',1);if(b.b.c.length==0){b.f.a=0;Qdd(c);return}s=Edb(ED(vNb(b,(Nyc(),wyc))));h=Edb(ED(vNb(b,pyc)));g=Edb(ED(vNb(b,myc)));r=BD(vNb(b,Xwc),336);B=r==(tBc(),sBc);A=Edb(ED(vNb(b,Ywc)));a.d=b;a.j.c=KC(SI,Uhe,1,0,5,1);a.a.c=KC(SI,Uhe,1,0,5,1);Uhb(a.k);i=BD(Ikb(b.b,0),29);k=Kq(i.a,(FNc(),DNc));o=BD(Ikb(b.b,b.b.c.length-1),29);l=Kq(o.a,DNc);p=new olb(b.b);q=null;G=0;do{t=p.a<p.c.c.length?BD(mlb(p),29):null;iQc(a,q,t);lQc(a);C=Vtb(uAb(PAb(JAb(new YAb(null,new Kub(a.i,16)),new LQc),new NQc)));F=0;u=G;m=!q||k&&q==i;n=!t||l&&t==o;if(C>0){j=0;!!q&&(j+=h);j+=(C-1)*g;!!t&&(j+=h);B&&!!t&&(j=$wnd.Math.max(j,jQc(t,g,s,A)));if(j<s&&!m&&!n){F=(s-j)/2;j=s}u+=j}else !m&&!n&&(u+=s);!!t&&h_b(t,u);for(w=new olb(a.i);w.a<w.c.c.length;){v=BD(mlb(w),128);v.a.c=G;v.a.b=u-G;v.F=F;v.p=!q}Gkb(a.a,a.i);G=u;!!t&&(G+=t.c.a);q=t;m=n}while(t);for(e=new olb(a.j);e.a<e.c.c.length;){d=BD(mlb(e),17);f=pQc(a,d);yNb(d,(wtc(),ptc),f);D=rQc(a,d);yNb(d,rtc,D)}b.f.a=G;a.d=null;Qdd(c)} +function Yxd(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;p=a.i!=0;t=false;r=null;if(oid(a.e)){k=b.gc();if(k>0){m=k<100?null:new Ixd(k);j=new Aud(b);o=j.g;r=KC(WD,oje,25,k,15,1);d=0;u=new zud(k);for(e=0;e<a.i;++e){h=a.g[e];n=h;v:for(s=0;s<2;++s){for(i=k;--i>=0;){if(n!=null?pb(n,o[i]):PD(n)===PD(o[i])){if(r.length<=d){q=r;r=KC(WD,oje,25,2*r.length,15,1);$fb(q,0,r,0,d)}r[d++]=e;wtd(u,o[i]);break v}}n=n;if(PD(n)===PD(h)){break}}}j=u;o=u.g;k=d;if(d>r.length){q=r;r=KC(WD,oje,25,d,15,1);$fb(q,0,r,0,d)}if(d>0){t=true;for(f=0;f<d;++f){n=o[f];m=k3d(a,BD(n,72),m)}for(g=d;--g>=0;){tud(a,r[g])}if(d!=k){for(e=k;--e>=d;){tud(j,e)}q=r;r=KC(WD,oje,25,d,15,1);$fb(q,0,r,0,d)}b=j}}}else{b=Ctd(a,b);for(e=a.i;--e>=0;){if(b.Hc(a.g[e])){tud(a,e);t=true}}}if(t){if(r!=null){c=b.gc();l=c==1?FLd(a,4,b.Kc().Pb(),null,r[0],p):FLd(a,6,b,r,r[0],p);m=c<100?null:new Ixd(c);for(e=b.Kc();e.Ob();){n=e.Pb();m=Q2d(a,BD(n,72),m)}if(!m){Uhd(a.e,l)}else{m.Ei(l);m.Fi()}}else{m=Vxd(b.gc());for(e=b.Kc();e.Ob();){n=e.Pb();m=Q2d(a,BD(n,72),m)}!!m&&m.Fi()}return true}else{return false}} +function fYb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;c=new mYb(b);c.a||$Xb(b);j=ZXb(b);i=new Hp;q=new AYb;for(p=new olb(b.a);p.a<p.c.c.length;){o=BD(mlb(p),10);for(e=new Sr(ur(U_b(o).a.Kc(),new Sq));Qr(e);){d=BD(Rr(e),17);if(d.c.i.k==(j0b(),e0b)||d.d.i.k==e0b){k=eYb(a,d,j,q);Rc(i,cYb(k.d),k.a)}}}g=new Rkb;for(t=BD(vNb(c.c,(wtc(),Esc)),21).Kc();t.Ob();){s=BD(t.Pb(),61);n=q.c[s.g];m=q.b[s.g];h=q.a[s.g];f=null;r=null;switch(s.g){case 4:f=new J6c(a.d.a,n,j.b.a-a.d.a,m-n);r=new J6c(a.d.a,n,h,m-n);iYb(j,new f7c(f.c+f.b,f.d));iYb(j,new f7c(f.c+f.b,f.d+f.a));break;case 2:f=new J6c(j.a.a,n,a.c.a-j.a.a,m-n);r=new J6c(a.c.a-h,n,h,m-n);iYb(j,new f7c(f.c,f.d));iYb(j,new f7c(f.c,f.d+f.a));break;case 1:f=new J6c(n,a.d.b,m-n,j.b.b-a.d.b);r=new J6c(n,a.d.b,m-n,h);iYb(j,new f7c(f.c,f.d+f.a));iYb(j,new f7c(f.c+f.b,f.d+f.a));break;case 3:f=new J6c(n,j.a.b,m-n,a.c.b-j.a.b);r=new J6c(n,a.c.b-h,m-n,h);iYb(j,new f7c(f.c,f.d));iYb(j,new f7c(f.c+f.b,f.d));}if(f){l=new vYb;l.d=s;l.b=f;l.c=r;l.a=Dx(BD(Qc(i,cYb(s)),21));g.c[g.c.length]=l}}Gkb(c.b,g);c.d=BWb(JWb(j));return c} +function pMc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;if(c.p[b.p]!=null){return}h=true;c.p[b.p]=0;g=b;p=c.o==(eMc(),cMc)?Qje:Pje;do{e=a.b.e[g.p];f=g.c.a.c.length;if(c.o==cMc&&e>0||c.o==dMc&&e<f-1){i=null;j=null;c.o==dMc?(i=BD(Ikb(g.c.a,e+1),10)):(i=BD(Ikb(g.c.a,e-1),10));j=c.g[i.p];pMc(a,j,c);p=a.e.bg(p,b,g);c.j[b.p]==b&&(c.j[b.p]=c.j[j.p]);if(c.j[b.p]==c.j[j.p]){o=jBc(a.d,g,i);if(c.o==dMc){d=Edb(c.p[b.p]);l=Edb(c.p[j.p])+Edb(c.d[i.p])-i.d.d-o-g.d.a-g.o.b-Edb(c.d[g.p]);if(h){h=false;c.p[b.p]=$wnd.Math.min(l,p)}else{c.p[b.p]=$wnd.Math.min(d,$wnd.Math.min(l,p))}}else{d=Edb(c.p[b.p]);l=Edb(c.p[j.p])+Edb(c.d[i.p])+i.o.b+i.d.a+o+g.d.d-Edb(c.d[g.p]);if(h){h=false;c.p[b.p]=$wnd.Math.max(l,p)}else{c.p[b.p]=$wnd.Math.max(d,$wnd.Math.max(l,p))}}}else{o=Edb(ED(vNb(a.a,(Nyc(),vyc))));n=nMc(a,c.j[b.p]);k=nMc(a,c.j[j.p]);if(c.o==dMc){m=Edb(c.p[b.p])+Edb(c.d[g.p])+g.o.b+g.d.a+o-(Edb(c.p[j.p])+Edb(c.d[i.p])-i.d.d);tMc(n,k,m)}else{m=Edb(c.p[b.p])+Edb(c.d[g.p])-g.d.d-Edb(c.p[j.p])-Edb(c.d[i.p])-i.o.b-i.d.a-o;tMc(n,k,m)}}}else{p=a.e.bg(p,b,g)}g=c.a[g.p]}while(g!=b);SMc(a.e,b)} +function _qd(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G;t=b;s=new Hp;u=new Hp;k=Ypd(t,Nte);d=new ord(a,c,s,u);qqd(d.a,d.b,d.c,d.d,k);i=(A=s.i,!A?(s.i=new zf(s,s.c)):A);for(C=i.Kc();C.Ob();){B=BD(C.Pb(),202);e=BD(Qc(s,B),21);for(p=e.Kc();p.Ob();){o=p.Pb();v=BD(oo(a.d,o),202);if(v){h=(!B.e&&(B.e=new y5d(A2,B,10,9)),B.e);wtd(h,v)}else{g=_pd(t,Vte);m=_te+o+aue+g;n=m+$te;throw vbb(new cqd(n))}}}j=(w=u.i,!w?(u.i=new zf(u,u.c)):w);for(F=j.Kc();F.Ob();){D=BD(F.Pb(),202);f=BD(Qc(u,D),21);for(r=f.Kc();r.Ob();){q=r.Pb();v=BD(oo(a.d,q),202);if(v){l=(!D.g&&(D.g=new y5d(A2,D,9,10)),D.g);wtd(l,v)}else{g=_pd(t,Vte);m=_te+q+aue+g;n=m+$te;throw vbb(new cqd(n))}}}!c.b&&(c.b=new y5d(z2,c,4,7));if(c.b.i!=0&&(!c.c&&(c.c=new y5d(z2,c,5,8)),c.c.i!=0)&&(!c.b&&(c.b=new y5d(z2,c,4,7)),c.b.i<=1&&(!c.c&&(c.c=new y5d(z2,c,5,8)),c.c.i<=1))&&(!c.a&&(c.a=new cUd(A2,c,6,6)),c.a).i==1){G=BD(qud((!c.a&&(c.a=new cUd(A2,c,6,6)),c.a),0),202);if(!dmd(G)&&!emd(G)){kmd(G,BD(qud((!c.b&&(c.b=new y5d(z2,c,4,7)),c.b),0),82));lmd(G,BD(qud((!c.c&&(c.c=new y5d(z2,c,5,8)),c.c),0),82))}}} +function qJc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;for(t=a.a,u=0,v=t.length;u<v;++u){s=t[u];j=Ohe;k=Ohe;for(o=new olb(s.e);o.a<o.c.c.length;){m=BD(mlb(o),10);g=!m.c?-1:Jkb(m.c.a,m,0);if(g>0){l=BD(Ikb(m.c.a,g-1),10);B=jBc(a.b,m,l);q=m.n.b-m.d.d-(l.n.b+l.o.b+l.d.a+B)}else{q=m.n.b-m.d.d}j=$wnd.Math.min(q,j);if(g<m.c.a.c.length-1){l=BD(Ikb(m.c.a,g+1),10);B=jBc(a.b,m,l);r=l.n.b-l.d.d-(m.n.b+m.o.b+m.d.a+B)}else{r=2*m.n.b}k=$wnd.Math.min(r,k)}i=Ohe;f=false;e=BD(Ikb(s.e,0),10);for(D=new olb(e.j);D.a<D.c.c.length;){C=BD(mlb(D),11);p=e.n.b+C.n.b+C.a.b;for(d=new olb(C.e);d.a<d.c.c.length;){c=BD(mlb(d),17);w=c.c;b=w.i.n.b+w.n.b+w.a.b-p;if($wnd.Math.abs(b)<$wnd.Math.abs(i)&&$wnd.Math.abs(b)<(b<0?j:k)){i=b;f=true}}}h=BD(Ikb(s.e,s.e.c.length-1),10);for(A=new olb(h.j);A.a<A.c.c.length;){w=BD(mlb(A),11);p=h.n.b+w.n.b+w.a.b;for(d=new olb(w.g);d.a<d.c.c.length;){c=BD(mlb(d),17);C=c.d;b=C.i.n.b+C.n.b+C.a.b-p;if($wnd.Math.abs(b)<$wnd.Math.abs(i)&&$wnd.Math.abs(b)<(b<0?j:k)){i=b;f=true}}}if(f&&i!=0){for(n=new olb(s.e);n.a<n.c.c.length;){m=BD(mlb(n),10);m.n.b+=i}}}} +function ync(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q;if(Mhb(a.a,b)){if(Rqb(BD(Ohb(a.a,b),53),c)){return 1}}else{Rhb(a.a,b,new Tqb)}if(Mhb(a.a,c)){if(Rqb(BD(Ohb(a.a,c),53),b)){return -1}}else{Rhb(a.a,c,new Tqb)}if(Mhb(a.e,b)){if(Rqb(BD(Ohb(a.e,b),53),c)){return -1}}else{Rhb(a.e,b,new Tqb)}if(Mhb(a.e,c)){if(Rqb(BD(Ohb(a.a,c),53),b)){return 1}}else{Rhb(a.e,c,new Tqb)}if(a.c==(tAc(),sAc)||!wNb(b,(wtc(),Zsc))||!wNb(c,(wtc(),Zsc))){i=BD(Etb(Dtb(KAb(JAb(new YAb(null,new Kub(b.j,16)),new Hnc)),new Jnc)),11);k=BD(Etb(Dtb(KAb(JAb(new YAb(null,new Kub(c.j,16)),new Lnc)),new Nnc)),11);if(!!i&&!!k){h=i.i;j=k.i;if(!!h&&h==j){for(m=new olb(h.j);m.a<m.c.c.length;){l=BD(mlb(m),11);if(l==i){Anc(a,c,b);return -1}else if(l==k){Anc(a,b,c);return 1}}return beb(znc(a,b),znc(a,c))}for(o=a.d,p=0,q=o.length;p<q;++p){n=o[p];if(n==h){Anc(a,c,b);return -1}else if(n==j){Anc(a,b,c);return 1}}}if(!wNb(b,(wtc(),Zsc))||!wNb(c,Zsc)){e=znc(a,b);g=znc(a,c);e>g?Anc(a,b,c):Anc(a,c,b);return e<g?-1:e>g?1:0}}d=BD(vNb(b,(wtc(),Zsc)),19).a;f=BD(vNb(c,Zsc),19).a;d>f?Anc(a,b,c):Anc(a,c,b);return d<f?-1:d>f?1:0} +function u2c(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s;if(Ccb(DD(hkd(b,(Y9c(),d9c))))){return mmb(),mmb(),jmb}j=(!b.a&&(b.a=new cUd(E2,b,10,11)),b.a).i!=0;l=s2c(b);k=!l.dc();if(j||k){e=BD(hkd(b,F9c),149);if(!e){throw vbb(new y2c('Resolved algorithm is not set; apply a LayoutAlgorithmResolver before computing layout.'))}s=D3c(e,(Csd(),ysd));q2c(b);if(!j&&k&&!s){return mmb(),mmb(),jmb}i=new Rkb;if(PD(hkd(b,J8c))===PD((hbd(),ebd))&&(D3c(e,vsd)||D3c(e,usd))){n=p2c(a,b);o=new Psb;ye(o,(!b.a&&(b.a=new cUd(E2,b,10,11)),b.a));while(o.b!=0){m=BD(o.b==0?null:(sCb(o.b!=0),Nsb(o,o.a.a)),33);q2c(m);r=PD(hkd(m,J8c))===PD(gbd);if(r||ikd(m,o8c)&&!C3c(e,hkd(m,F9c))){h=u2c(a,m,c,d);Gkb(i,h);jkd(m,J8c,gbd);hfd(m)}else{ye(o,(!m.a&&(m.a=new cUd(E2,m,10,11)),m.a))}}}else{n=(!b.a&&(b.a=new cUd(E2,b,10,11)),b.a).i;for(g=new Fyd((!b.a&&(b.a=new cUd(E2,b,10,11)),b.a));g.e!=g.i.gc();){f=BD(Dyd(g),33);h=u2c(a,f,c,d);Gkb(i,h);hfd(f)}}for(q=new olb(i);q.a<q.c.c.length;){p=BD(mlb(q),79);jkd(p,d9c,(Bcb(),true))}r2c(b,e,Udd(d,n));v2c(i);return k&&s?l:(mmb(),mmb(),jmb)}else{return mmb(),mmb(),jmb}} +function Z$b(a,b,c,d,e,f,g,h,i){var j,k,l,m,n,o,p;n=c;k=new b0b(i);__b(k,(j0b(),e0b));yNb(k,(wtc(),Isc),g);yNb(k,(Nyc(),Vxc),(dcd(),$bd));p=Edb(ED(a.We(Uxc)));yNb(k,Uxc,p);l=new H0b;F0b(l,k);if(!(b!=bcd&&b!=ccd)){d>=0?(n=Zcd(h)):(n=Wcd(Zcd(h)));a.Ye($xc,n)}j=new d7c;m=false;if(a.Xe(Txc)){a7c(j,BD(a.We(Txc),8));m=true}else{_6c(j,g.a/2,g.b/2)}switch(n.g){case 4:yNb(k,mxc,(Ctc(),ytc));yNb(k,Bsc,(Gqc(),Fqc));k.o.b=g.b;p<0&&(k.o.a=-p);G0b(l,(Ucd(),zcd));m||(j.a=g.a);j.a-=g.a;break;case 2:yNb(k,mxc,(Ctc(),Atc));yNb(k,Bsc,(Gqc(),Dqc));k.o.b=g.b;p<0&&(k.o.a=-p);G0b(l,(Ucd(),Tcd));m||(j.a=0);break;case 1:yNb(k,Osc,(esc(),dsc));k.o.a=g.a;p<0&&(k.o.b=-p);G0b(l,(Ucd(),Rcd));m||(j.b=g.b);j.b-=g.b;break;case 3:yNb(k,Osc,(esc(),bsc));k.o.a=g.a;p<0&&(k.o.b=-p);G0b(l,(Ucd(),Acd));m||(j.b=0);}a7c(l.n,j);yNb(k,Txc,j);if(b==Zbd||b==_bd||b==$bd){o=0;if(b==Zbd&&a.Xe(Wxc)){switch(n.g){case 1:case 2:o=BD(a.We(Wxc),19).a;break;case 3:case 4:o=-BD(a.We(Wxc),19).a;}}else{switch(n.g){case 4:case 2:o=f.b;b==_bd&&(o/=e.b);break;case 1:case 3:o=f.a;b==_bd&&(o/=e.a);}}yNb(k,htc,o)}yNb(k,Hsc,n);return k} +function AGc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C;c=Edb(ED(vNb(a.a.j,(Nyc(),Ewc))));if(c<-1||!a.a.i||ecd(BD(vNb(a.a.o,Vxc),98))||V_b(a.a.o,(Ucd(),zcd)).gc()<2&&V_b(a.a.o,Tcd).gc()<2){return true}if(a.a.c.Rf()){return false}v=0;u=0;t=new Rkb;for(i=a.a.e,j=0,k=i.length;j<k;++j){h=i[j];for(m=h,n=0,p=m.length;n<p;++n){l=m[n];if(l.k==(j0b(),i0b)){t.c[t.c.length]=l;continue}d=a.b[l.c.p][l.p];if(l.k==e0b){d.b=1;BD(vNb(l,(wtc(),$sc)),11).j==(Ucd(),zcd)&&(u+=d.a)}else{C=V_b(l,(Ucd(),Tcd));C.dc()||!Lq(C,new NGc)?(d.c=1):(e=V_b(l,zcd),(e.dc()||!Lq(e,new JGc))&&(v+=d.a))}for(g=new Sr(ur(U_b(l).a.Kc(),new Sq));Qr(g);){f=BD(Rr(g),17);v+=d.c;u+=d.b;B=f.d.i;zGc(a,d,B)}r=pl(OC(GC(KI,1),Uhe,20,0,[V_b(l,(Ucd(),Acd)),V_b(l,Rcd)]));for(A=new Sr(new xl(r.a.length,r.a));Qr(A);){w=BD(Rr(A),11);s=BD(vNb(w,(wtc(),gtc)),10);if(s){v+=d.c;u+=d.b;zGc(a,d,s)}}}for(o=new olb(t);o.a<o.c.c.length;){l=BD(mlb(o),10);d=a.b[l.c.p][l.p];for(g=new Sr(ur(U_b(l).a.Kc(),new Sq));Qr(g);){f=BD(Rr(g),17);v+=d.c;u+=d.b;B=f.d.i;zGc(a,d,B)}}t.c=KC(SI,Uhe,1,0,5,1)}b=v+u;q=b==0?Pje:(v-u)/b;return q>=c} +function ovd(){mvd();function h(f){var g=this;this.dispatch=function(a){var b=a.data;switch(b.cmd){case 'algorithms':var c=pvd((mmb(),new lnb(new $ib(lvd.b))));f.postMessage({id:b.id,data:c});break;case 'categories':var d=pvd((mmb(),new lnb(new $ib(lvd.c))));f.postMessage({id:b.id,data:d});break;case 'options':var e=pvd((mmb(),new lnb(new $ib(lvd.d))));f.postMessage({id:b.id,data:e});break;case 'register':svd(b.algorithms);f.postMessage({id:b.id});break;case 'layout':qvd(b.graph,b.layoutOptions||{},b.options||{});f.postMessage({id:b.id,data:b.graph});break;}};this.saveDispatch=function(b){try{g.dispatch(b)}catch(a){f.postMessage({id:b.data.id,error:a})}}} +function j(b){var c=this;this.dispatcher=new h({postMessage:function(a){c.onmessage({data:a})}});this.postMessage=function(a){setTimeout(function(){c.dispatcher.saveDispatch({data:a})},0)}} +if(typeof document===uke&&typeof self!==uke){var i=new h(self);self.onmessage=i.saveDispatch}else if(typeof module!==uke&&module.exports){Object.defineProperty(exports,'__esModule',{value:true});module.exports={'default':j,Worker:j}}} +function aae(a){if(a.N)return;a.N=true;a.b=Lnd(a,0);Knd(a.b,0);Knd(a.b,1);Knd(a.b,2);a.bb=Lnd(a,1);Knd(a.bb,0);Knd(a.bb,1);a.fb=Lnd(a,2);Knd(a.fb,3);Knd(a.fb,4);Qnd(a.fb,5);a.qb=Lnd(a,3);Knd(a.qb,0);Qnd(a.qb,1);Qnd(a.qb,2);Knd(a.qb,3);Knd(a.qb,4);Qnd(a.qb,5);Knd(a.qb,6);a.a=Mnd(a,4);a.c=Mnd(a,5);a.d=Mnd(a,6);a.e=Mnd(a,7);a.f=Mnd(a,8);a.g=Mnd(a,9);a.i=Mnd(a,10);a.j=Mnd(a,11);a.k=Mnd(a,12);a.n=Mnd(a,13);a.o=Mnd(a,14);a.p=Mnd(a,15);a.q=Mnd(a,16);a.s=Mnd(a,17);a.r=Mnd(a,18);a.t=Mnd(a,19);a.u=Mnd(a,20);a.v=Mnd(a,21);a.w=Mnd(a,22);a.B=Mnd(a,23);a.A=Mnd(a,24);a.C=Mnd(a,25);a.D=Mnd(a,26);a.F=Mnd(a,27);a.G=Mnd(a,28);a.H=Mnd(a,29);a.J=Mnd(a,30);a.I=Mnd(a,31);a.K=Mnd(a,32);a.M=Mnd(a,33);a.L=Mnd(a,34);a.P=Mnd(a,35);a.Q=Mnd(a,36);a.R=Mnd(a,37);a.S=Mnd(a,38);a.T=Mnd(a,39);a.U=Mnd(a,40);a.V=Mnd(a,41);a.X=Mnd(a,42);a.W=Mnd(a,43);a.Y=Mnd(a,44);a.Z=Mnd(a,45);a.$=Mnd(a,46);a._=Mnd(a,47);a.ab=Mnd(a,48);a.cb=Mnd(a,49);a.db=Mnd(a,50);a.eb=Mnd(a,51);a.gb=Mnd(a,52);a.hb=Mnd(a,53);a.ib=Mnd(a,54);a.jb=Mnd(a,55);a.kb=Mnd(a,56);a.lb=Mnd(a,57);a.mb=Mnd(a,58);a.nb=Mnd(a,59);a.ob=Mnd(a,60);a.pb=Mnd(a,61)} +function f5b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;s=0;if(b.f.a==0){for(q=new olb(a);q.a<q.c.c.length;){o=BD(mlb(q),10);s=$wnd.Math.max(s,o.n.a+o.o.a+o.d.c)}}else{s=b.f.a-b.c.a}s-=b.c.a;for(p=new olb(a);p.a<p.c.c.length;){o=BD(mlb(p),10);g5b(o.n,s-o.o.a);h5b(o.f);d5b(o);(!o.q?(mmb(),mmb(),kmb):o.q)._b((Nyc(),ayc))&&g5b(BD(vNb(o,ayc),8),s-o.o.a);switch(BD(vNb(o,mwc),248).g){case 1:yNb(o,mwc,(F7c(),D7c));break;case 2:yNb(o,mwc,(F7c(),C7c));}r=o.o;for(u=new olb(o.j);u.a<u.c.c.length;){t=BD(mlb(u),11);g5b(t.n,r.a-t.o.a);g5b(t.a,t.o.a);G0b(t,Z4b(t.j));g=BD(vNb(t,Wxc),19);!!g&&yNb(t,Wxc,meb(-g.a));for(f=new olb(t.g);f.a<f.c.c.length;){e=BD(mlb(f),17);for(d=Jsb(e.a,0);d.b!=d.d.c;){c=BD(Xsb(d),8);c.a=s-c.a}j=BD(vNb(e,jxc),74);if(j){for(i=Jsb(j,0);i.b!=i.d.c;){h=BD(Xsb(i),8);h.a=s-h.a}}for(m=new olb(e.b);m.a<m.c.c.length;){k=BD(mlb(m),70);g5b(k.n,s-k.o.a)}}for(n=new olb(t.f);n.a<n.c.c.length;){k=BD(mlb(n),70);g5b(k.n,t.o.a-k.o.a)}}if(o.k==(j0b(),e0b)){yNb(o,(wtc(),Hsc),Z4b(BD(vNb(o,Hsc),61)));c5b(o)}for(l=new olb(o.b);l.a<l.c.c.length;){k=BD(mlb(l),70);d5b(k);g5b(k.n,r.a-k.o.a)}}} +function i5b(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;s=0;if(b.f.b==0){for(q=new olb(a);q.a<q.c.c.length;){o=BD(mlb(q),10);s=$wnd.Math.max(s,o.n.b+o.o.b+o.d.a)}}else{s=b.f.b-b.c.b}s-=b.c.b;for(p=new olb(a);p.a<p.c.c.length;){o=BD(mlb(p),10);j5b(o.n,s-o.o.b);k5b(o.f);e5b(o);(!o.q?(mmb(),mmb(),kmb):o.q)._b((Nyc(),ayc))&&j5b(BD(vNb(o,ayc),8),s-o.o.b);switch(BD(vNb(o,mwc),248).g){case 3:yNb(o,mwc,(F7c(),A7c));break;case 4:yNb(o,mwc,(F7c(),E7c));}r=o.o;for(u=new olb(o.j);u.a<u.c.c.length;){t=BD(mlb(u),11);j5b(t.n,r.b-t.o.b);j5b(t.a,t.o.b);G0b(t,$4b(t.j));g=BD(vNb(t,Wxc),19);!!g&&yNb(t,Wxc,meb(-g.a));for(f=new olb(t.g);f.a<f.c.c.length;){e=BD(mlb(f),17);for(d=Jsb(e.a,0);d.b!=d.d.c;){c=BD(Xsb(d),8);c.b=s-c.b}j=BD(vNb(e,jxc),74);if(j){for(i=Jsb(j,0);i.b!=i.d.c;){h=BD(Xsb(i),8);h.b=s-h.b}}for(m=new olb(e.b);m.a<m.c.c.length;){k=BD(mlb(m),70);j5b(k.n,s-k.o.b)}}for(n=new olb(t.f);n.a<n.c.c.length;){k=BD(mlb(n),70);j5b(k.n,t.o.b-k.o.b)}}if(o.k==(j0b(),e0b)){yNb(o,(wtc(),Hsc),$4b(BD(vNb(o,Hsc),61)));b5b(o)}for(l=new olb(o.b);l.a<l.c.c.length;){k=BD(mlb(l),70);e5b(k);j5b(k.n,r.b-k.o.b)}}} +function tZc(a,b,c,d){var e,f,g,h,i,j,k,l,m,n;l=false;j=a+1;k=(tCb(a,b.c.length),BD(b.c[a],200));g=k.a;h=null;for(f=0;f<k.a.c.length;f++){e=(tCb(f,g.c.length),BD(g.c[f],187));if(e.c){continue}if(e.b.c.length==0){Zfb();v$c(k,e);--f;l=true;continue}if(!e.k){!!h&&a$c(h);h=new b$c(!h?0:h.e+h.d+d,k.f,d);OZc(e,h.e+h.d,k.f);Ekb(k.d,h);WZc(h,e);e.k=true}i=null;i=(n=null,f<k.a.c.length-1?(n=BD(Ikb(k.a,f+1),187)):j<b.c.length&&(tCb(j,b.c.length),BD(b.c[j],200)).a.c.length!=0&&(n=BD(Ikb((tCb(j,b.c.length),BD(b.c[j],200)).a,0),187)),n);m=false;!!i&&(m=!pb(i.j,k));if(i){if(i.b.c.length==0){v$c(k,i);break}else{KZc(e,c-e.s);a$c(e.q);l=l|sZc(k,e,i,c,d)}if(i.b.c.length==0){v$c((tCb(j,b.c.length),BD(b.c[j],200)),i);i=null;while(b.c.length>j&&(tCb(j,b.c.length),BD(b.c[j],200)).a.c.length==0){Lkb(b,(tCb(j,b.c.length),b.c[j]))}}if(!i){--f;continue}if(uZc(b,k,e,i,m,c,j,d)){l=true;continue}if(m){if(vZc(b,k,e,i,c,j,d)){l=true;continue}else if(wZc(k,e)){e.c=true;l=true;continue}}else if(wZc(k,e)){e.c=true;l=true;continue}if(l){continue}}if(wZc(k,e)){e.c=true;l=true;!!i&&(i.k=false);continue}else{a$c(e.q)}}return l} +function fed(a,b,c,d,e,f,g){var h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I;p=0;D=0;for(j=new olb(a.b);j.a<j.c.c.length;){i=BD(mlb(j),157);!!i.c&&zfd(i.c);p=$wnd.Math.max(p,red(i));D+=red(i)*qed(i)}q=D/a.b.c.length;C=_dd(a.b,q);D+=a.b.c.length*C;p=$wnd.Math.max(p,$wnd.Math.sqrt(D*g))+c.b;H=c.b;I=c.d;n=0;l=c.b+c.c;B=new Psb;Dsb(B,meb(0));w=new Psb;k=new Bib(a.b,0);o=null;h=new Rkb;while(k.b<k.d.gc()){i=(sCb(k.b<k.d.gc()),BD(k.d.Xb(k.c=k.b++),157));G=red(i);m=qed(i);if(H+G>p){if(f){Fsb(w,n);Fsb(B,meb(k.b-1));Ekb(a.d,o);h.c=KC(SI,Uhe,1,0,5,1)}H=c.b;I+=n+b;n=0;l=$wnd.Math.max(l,c.b+c.c+G)}h.c[h.c.length]=i;ued(i,H,I);l=$wnd.Math.max(l,H+G+c.c);n=$wnd.Math.max(n,m);H+=G+b;o=i}Gkb(a.a,h);Ekb(a.d,BD(Ikb(h,h.c.length-1),157));l=$wnd.Math.max(l,d);F=I+n+c.a;if(F<e){n+=e-F;F=e}if(f){H=c.b;k=new Bib(a.b,0);Fsb(B,meb(a.b.c.length));A=Jsb(B,0);s=BD(Xsb(A),19).a;Fsb(w,n);v=Jsb(w,0);u=0;while(k.b<k.d.gc()){if(k.b==s){H=c.b;u=Edb(ED(Xsb(v)));s=BD(Xsb(A),19).a}i=(sCb(k.b<k.d.gc()),BD(k.d.Xb(k.c=k.b++),157));sed(i,u);if(k.b==s){r=l-H-c.c;t=red(i);ted(i,r);ved(i,(r-t)/2,0)}H+=red(i)+b}}return new f7c(l,F)} +function pde(a){var b,c,d,e,f;b=a.c;f=null;switch(b){case 6:return a.Vl();case 13:return a.Wl();case 23:return a.Nl();case 22:return a.Sl();case 18:return a.Pl();case 8:nde(a);f=(wfe(),efe);break;case 9:return a.vl(true);case 19:return a.wl();case 10:switch(a.a){case 100:case 68:case 119:case 87:case 115:case 83:f=a.ul(a.a);nde(a);return f;case 101:case 102:case 110:case 114:case 116:case 117:case 118:case 120:{c=a.tl();c<Tje?(f=(wfe(),wfe(),++vfe,new ige(0,c))):(f=Ffe(Tee(c)))}break;case 99:return a.Fl();case 67:return a.Al();case 105:return a.Il();case 73:return a.Bl();case 103:return a.Gl();case 88:return a.Cl();case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return a.xl();case 80:case 112:f=tde(a,a.a);if(!f)throw vbb(new mde(tvd((h0d(),Iue))));break;default:f=zfe(a.a);}nde(a);break;case 0:if(a.a==93||a.a==123||a.a==125)throw vbb(new mde(tvd((h0d(),Hue))));f=zfe(a.a);d=a.a;nde(a);if((d&64512)==Uje&&a.c==0&&(a.a&64512)==56320){e=KC(TD,$ie,25,2,15,1);e[0]=d&aje;e[1]=a.a&aje;f=Efe(Ffe(zfb(e,0,e.length)),0);nde(a)}break;default:throw vbb(new mde(tvd((h0d(),Hue))));}return f} +function e7b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;d=new Rkb;e=Ohe;f=Ohe;g=Ohe;if(c){e=a.f.a;for(p=new olb(b.j);p.a<p.c.c.length;){o=BD(mlb(p),11);for(i=new olb(o.g);i.a<i.c.c.length;){h=BD(mlb(i),17);if(h.a.b!=0){k=BD(Hsb(h.a),8);if(k.a<e){f=e-k.a;g=Ohe;d.c=KC(SI,Uhe,1,0,5,1);e=k.a}if(k.a<=e){d.c[d.c.length]=h;h.a.b>1&&(g=$wnd.Math.min(g,$wnd.Math.abs(BD(Ut(h.a,1),8).b-k.b)))}}}}}else{for(p=new olb(b.j);p.a<p.c.c.length;){o=BD(mlb(p),11);for(i=new olb(o.e);i.a<i.c.c.length;){h=BD(mlb(i),17);if(h.a.b!=0){m=BD(Isb(h.a),8);if(m.a>e){f=m.a-e;g=Ohe;d.c=KC(SI,Uhe,1,0,5,1);e=m.a}if(m.a>=e){d.c[d.c.length]=h;h.a.b>1&&(g=$wnd.Math.min(g,$wnd.Math.abs(BD(Ut(h.a,h.a.b-2),8).b-m.b)))}}}}}if(d.c.length!=0&&f>b.o.a/2&&g>b.o.b/2){n=new H0b;F0b(n,b);G0b(n,(Ucd(),Acd));n.n.a=b.o.a/2;r=new H0b;F0b(r,b);G0b(r,Rcd);r.n.a=b.o.a/2;r.n.b=b.o.b;for(i=new olb(d);i.a<i.c.c.length;){h=BD(mlb(i),17);if(c){j=BD(Lsb(h.a),8);q=h.a.b==0?A0b(h.d):BD(Hsb(h.a),8);q.b>=j.b?QZb(h,r):QZb(h,n)}else{j=BD(Msb(h.a),8);q=h.a.b==0?A0b(h.c):BD(Isb(h.a),8);q.b>=j.b?RZb(h,r):RZb(h,n)}l=BD(vNb(h,(Nyc(),jxc)),74);!!l&&ze(l,j,true)}b.n.a=e-b.o.a/2}} +function erd(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I,J,K;D=null;G=b;F=Rqd(a,dtd(c),G);Lkd(F,_pd(G,Vte));H=BD(oo(a.g,Vpd(aC(G,Cte))),33);m=aC(G,'sourcePort');d=null;!!m&&(d=Vpd(m));I=BD(oo(a.j,d),118);if(!H){h=Wpd(G);o="An edge must have a source node (edge id: '"+h;p=o+$te;throw vbb(new cqd(p))}if(!!I&&!Hb(mpd(I),H)){i=_pd(G,Vte);q="The source port of an edge must be a port of the edge's source node (edge id: '"+i;r=q+$te;throw vbb(new cqd(r))}B=(!F.b&&(F.b=new y5d(z2,F,4,7)),F.b);f=null;I?(f=I):(f=H);wtd(B,f);J=BD(oo(a.g,Vpd(aC(G,bue))),33);n=aC(G,'targetPort');e=null;!!n&&(e=Vpd(n));K=BD(oo(a.j,e),118);if(!J){l=Wpd(G);s="An edge must have a target node (edge id: '"+l;t=s+$te;throw vbb(new cqd(t))}if(!!K&&!Hb(mpd(K),J)){j=_pd(G,Vte);u="The target port of an edge must be a port of the edge's target node (edge id: '"+j;v=u+$te;throw vbb(new cqd(v))}C=(!F.c&&(F.c=new y5d(z2,F,5,8)),F.c);g=null;K?(g=K):(g=J);wtd(C,g);if((!F.b&&(F.b=new y5d(z2,F,4,7)),F.b).i==0||(!F.c&&(F.c=new y5d(z2,F,5,8)),F.c).i==0){k=_pd(G,Vte);w=Zte+k;A=w+$te;throw vbb(new cqd(A))}grd(G,F);frd(G,F);D=crd(a,G,F);return D} +function DXb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;l=FXb(zXb(a,(Ucd(),Fcd)),b);o=EXb(zXb(a,Gcd),b);u=EXb(zXb(a,Ocd),b);B=GXb(zXb(a,Qcd),b);m=GXb(zXb(a,Bcd),b);s=EXb(zXb(a,Ncd),b);p=EXb(zXb(a,Hcd),b);w=EXb(zXb(a,Pcd),b);v=EXb(zXb(a,Ccd),b);C=GXb(zXb(a,Ecd),b);r=EXb(zXb(a,Lcd),b);t=EXb(zXb(a,Kcd),b);A=EXb(zXb(a,Dcd),b);D=GXb(zXb(a,Mcd),b);n=GXb(zXb(a,Icd),b);q=EXb(zXb(a,Jcd),b);c=w6c(OC(GC(UD,1),Vje,25,15,[s.a,B.a,w.a,D.a]));d=w6c(OC(GC(UD,1),Vje,25,15,[o.a,l.a,u.a,q.a]));e=r.a;f=w6c(OC(GC(UD,1),Vje,25,15,[p.a,m.a,v.a,n.a]));j=w6c(OC(GC(UD,1),Vje,25,15,[s.b,o.b,p.b,t.b]));i=w6c(OC(GC(UD,1),Vje,25,15,[B.b,l.b,m.b,q.b]));k=C.b;h=w6c(OC(GC(UD,1),Vje,25,15,[w.b,u.b,v.b,A.b]));vXb(zXb(a,Fcd),c+e,j+k);vXb(zXb(a,Jcd),c+e,j+k);vXb(zXb(a,Gcd),c+e,0);vXb(zXb(a,Ocd),c+e,j+k+i);vXb(zXb(a,Qcd),0,j+k);vXb(zXb(a,Bcd),c+e+d,j+k);vXb(zXb(a,Hcd),c+e+d,0);vXb(zXb(a,Pcd),0,j+k+i);vXb(zXb(a,Ccd),c+e+d,j+k+i);vXb(zXb(a,Ecd),0,j);vXb(zXb(a,Lcd),c,0);vXb(zXb(a,Dcd),0,j+k+i);vXb(zXb(a,Icd),c+e+d,0);g=new d7c;g.a=w6c(OC(GC(UD,1),Vje,25,15,[c+d+e+f,C.a,t.a,A.a]));g.b=w6c(OC(GC(UD,1),Vje,25,15,[j+i+k+h,r.b,D.b,n.b]));return g} +function Ngc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;p=new Rkb;for(m=new olb(a.d.b);m.a<m.c.c.length;){l=BD(mlb(m),29);for(o=new olb(l.a);o.a<o.c.c.length;){n=BD(mlb(o),10);e=BD(Ohb(a.f,n),57);for(i=new Sr(ur(U_b(n).a.Kc(),new Sq));Qr(i);){g=BD(Rr(i),17);d=Jsb(g.a,0);j=true;k=null;if(d.b!=d.d.c){b=BD(Xsb(d),8);c=null;if(g.c.j==(Ucd(),Acd)){q=new hic(b,new f7c(b.a,e.d.d),e,g);q.f.a=true;q.a=g.c;p.c[p.c.length]=q}if(g.c.j==Rcd){q=new hic(b,new f7c(b.a,e.d.d+e.d.a),e,g);q.f.d=true;q.a=g.c;p.c[p.c.length]=q}while(d.b!=d.d.c){c=BD(Xsb(d),8);if(!ADb(b.b,c.b)){k=new hic(b,c,null,g);p.c[p.c.length]=k;if(j){j=false;if(c.b<e.d.d){k.f.a=true}else if(c.b>e.d.d+e.d.a){k.f.d=true}else{k.f.d=true;k.f.a=true}}}d.b!=d.d.c&&(b=c)}if(k){f=BD(Ohb(a.f,g.d.i),57);if(b.b<f.d.d){k.f.a=true}else if(b.b>f.d.d+f.d.a){k.f.d=true}else{k.f.d=true;k.f.a=true}}}}for(h=new Sr(ur(R_b(n).a.Kc(),new Sq));Qr(h);){g=BD(Rr(h),17);if(g.a.b!=0){b=BD(Isb(g.a),8);if(g.d.j==(Ucd(),Acd)){q=new hic(b,new f7c(b.a,e.d.d),e,g);q.f.a=true;q.a=g.d;p.c[p.c.length]=q}if(g.d.j==Rcd){q=new hic(b,new f7c(b.a,e.d.d+e.d.a),e,g);q.f.d=true;q.a=g.d;p.c[p.c.length]=q}}}}}return p} +function WJc(a,b,c){var d,e,f,g,h,i,j,k,l;Odd(c,'Network simplex node placement',1);a.e=b;a.n=BD(vNb(b,(wtc(),otc)),304);VJc(a);HJc(a);MAb(LAb(new YAb(null,new Kub(a.e.b,16)),new KKc),new MKc(a));MAb(JAb(LAb(JAb(LAb(new YAb(null,new Kub(a.e.b,16)),new zLc),new BLc),new DLc),new FLc),new IKc(a));if(Ccb(DD(vNb(a.e,(Nyc(),Axc))))){g=Udd(c,1);Odd(g,'Straight Edges Pre-Processing',1);UJc(a);Qdd(g)}JFb(a.f);f=BD(vNb(b,Ayc),19).a*a.f.a.c.length;uGb(HGb(IGb(LGb(a.f),f),false),Udd(c,1));if(a.d.a.gc()!=0){g=Udd(c,1);Odd(g,'Flexible Where Space Processing',1);h=BD(Btb(RAb(NAb(new YAb(null,new Kub(a.f.a,16)),new OKc),new iKc)),19).a;i=BD(Btb(QAb(NAb(new YAb(null,new Kub(a.f.a,16)),new QKc),new mKc)),19).a;j=i-h;k=nGb(new pGb,a.f);l=nGb(new pGb,a.f);AFb(DFb(CFb(BFb(EFb(new FFb,20000),j),k),l));MAb(JAb(JAb(Plb(a.i),new SKc),new UKc),new WKc(h,k,j,l));for(e=a.d.a.ec().Kc();e.Ob();){d=BD(e.Pb(),213);d.g=1}uGb(HGb(IGb(LGb(a.f),f),false),Udd(g,1));Qdd(g)}if(Ccb(DD(vNb(b,Axc)))){g=Udd(c,1);Odd(g,'Straight Edges Post-Processing',1);TJc(a);Qdd(g)}GJc(a);a.e=null;a.f=null;a.i=null;a.c=null;Uhb(a.k);a.j=null;a.a=null;a.o=null;a.d.a.$b();Qdd(c)} +function lMc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;for(h=new olb(a.a.b);h.a<h.c.c.length;){f=BD(mlb(h),29);for(t=new olb(f.a);t.a<t.c.c.length;){s=BD(mlb(t),10);b.g[s.p]=s;b.a[s.p]=s;b.d[s.p]=0}}i=a.a.b;b.c==(YLc(),WLc)&&(i=JD(i,152)?km(BD(i,152)):JD(i,131)?BD(i,131).a:JD(i,54)?new ov(i):new dv(i));for(g=i.Kc();g.Ob();){f=BD(g.Pb(),29);n=-1;m=f.a;if(b.o==(eMc(),dMc)){n=Ohe;m=JD(m,152)?km(BD(m,152)):JD(m,131)?BD(m,131).a:JD(m,54)?new ov(m):new dv(m)}for(v=m.Kc();v.Ob();){u=BD(v.Pb(),10);l=null;b.c==WLc?(l=BD(Ikb(a.b.f,u.p),15)):(l=BD(Ikb(a.b.b,u.p),15));if(l.gc()>0){d=l.gc();j=QD($wnd.Math.floor((d+1)/2))-1;e=QD($wnd.Math.ceil((d+1)/2))-1;if(b.o==dMc){for(k=e;k>=j;k--){if(b.a[u.p]==u){p=BD(l.Xb(k),46);o=BD(p.a,10);if(!Rqb(c,p.b)&&n>a.b.e[o.p]){b.a[o.p]=u;b.g[u.p]=b.g[o.p];b.a[u.p]=b.g[u.p];b.f[b.g[u.p].p]=(Bcb(),Ccb(b.f[b.g[u.p].p])&u.k==(j0b(),g0b)?true:false);n=a.b.e[o.p]}}}}else{for(k=j;k<=e;k++){if(b.a[u.p]==u){r=BD(l.Xb(k),46);q=BD(r.a,10);if(!Rqb(c,r.b)&&n<a.b.e[q.p]){b.a[q.p]=u;b.g[u.p]=b.g[q.p];b.a[u.p]=b.g[u.p];b.f[b.g[u.p].p]=(Bcb(),Ccb(b.f[b.g[u.p].p])&u.k==(j0b(),g0b)?true:false);n=a.b.e[q.p]}}}}}}}} +function Thd(){Thd=ccb;Hhd();Shd=Ghd.a;BD(qud(ZKd(Ghd.a),0),18);Mhd=Ghd.f;BD(qud(ZKd(Ghd.f),0),18);BD(qud(ZKd(Ghd.f),1),34);Rhd=Ghd.n;BD(qud(ZKd(Ghd.n),0),34);BD(qud(ZKd(Ghd.n),1),34);BD(qud(ZKd(Ghd.n),2),34);BD(qud(ZKd(Ghd.n),3),34);Nhd=Ghd.g;BD(qud(ZKd(Ghd.g),0),18);BD(qud(ZKd(Ghd.g),1),34);Jhd=Ghd.c;BD(qud(ZKd(Ghd.c),0),18);BD(qud(ZKd(Ghd.c),1),18);Ohd=Ghd.i;BD(qud(ZKd(Ghd.i),0),18);BD(qud(ZKd(Ghd.i),1),18);BD(qud(ZKd(Ghd.i),2),18);BD(qud(ZKd(Ghd.i),3),18);BD(qud(ZKd(Ghd.i),4),34);Phd=Ghd.j;BD(qud(ZKd(Ghd.j),0),18);Khd=Ghd.d;BD(qud(ZKd(Ghd.d),0),18);BD(qud(ZKd(Ghd.d),1),18);BD(qud(ZKd(Ghd.d),2),18);BD(qud(ZKd(Ghd.d),3),18);BD(qud(ZKd(Ghd.d),4),34);BD(qud(ZKd(Ghd.d),5),34);BD(qud(ZKd(Ghd.d),6),34);BD(qud(ZKd(Ghd.d),7),34);Ihd=Ghd.b;BD(qud(ZKd(Ghd.b),0),34);BD(qud(ZKd(Ghd.b),1),34);Lhd=Ghd.e;BD(qud(ZKd(Ghd.e),0),34);BD(qud(ZKd(Ghd.e),1),34);BD(qud(ZKd(Ghd.e),2),34);BD(qud(ZKd(Ghd.e),3),34);BD(qud(ZKd(Ghd.e),4),18);BD(qud(ZKd(Ghd.e),5),18);BD(qud(ZKd(Ghd.e),6),18);BD(qud(ZKd(Ghd.e),7),18);BD(qud(ZKd(Ghd.e),8),18);BD(qud(ZKd(Ghd.e),9),18);BD(qud(ZKd(Ghd.e),10),34);Qhd=Ghd.k;BD(qud(ZKd(Ghd.k),0),34);BD(qud(ZKd(Ghd.k),1),34)} +function wQc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F;C=new Psb;w=new Psb;q=-1;for(i=new olb(a);i.a<i.c.c.length;){g=BD(mlb(i),128);g.s=q--;k=0;t=0;for(f=new olb(g.t);f.a<f.c.c.length;){d=BD(mlb(f),268);t+=d.c}for(e=new olb(g.i);e.a<e.c.c.length;){d=BD(mlb(e),268);k+=d.c}g.n=k;g.u=t;t==0?(Gsb(w,g,w.c.b,w.c),true):k==0&&(Gsb(C,g,C.c.b,C.c),true)}F=Gx(a);l=a.c.length;p=l+1;r=l-1;n=new Rkb;while(F.a.gc()!=0){while(w.b!=0){v=(sCb(w.b!=0),BD(Nsb(w,w.a.a),128));F.a.Bc(v)!=null;v.s=r--;AQc(v,C,w)}while(C.b!=0){A=(sCb(C.b!=0),BD(Nsb(C,C.a.a),128));F.a.Bc(A)!=null;A.s=p++;AQc(A,C,w)}o=Rie;for(j=F.a.ec().Kc();j.Ob();){g=BD(j.Pb(),128);s=g.u-g.n;if(s>=o){if(s>o){n.c=KC(SI,Uhe,1,0,5,1);o=s}n.c[n.c.length]=g}}if(n.c.length!=0){m=BD(Ikb(n,Bub(b,n.c.length)),128);F.a.Bc(m)!=null;m.s=p++;AQc(m,C,w);n.c=KC(SI,Uhe,1,0,5,1)}}u=a.c.length+1;for(h=new olb(a);h.a<h.c.c.length;){g=BD(mlb(h),128);g.s<l&&(g.s+=u)}for(B=new olb(a);B.a<B.c.c.length;){A=BD(mlb(B),128);c=new Bib(A.t,0);while(c.b<c.d.gc()){d=(sCb(c.b<c.d.gc()),BD(c.d.Xb(c.c=c.b++),268));D=d.b;if(A.s>D.s){uib(c);Lkb(D.i,d);if(d.c>0){d.a=D;Ekb(D.t,d);d.b=A;Ekb(A.i,d)}}}}} +function qde(a){var b,c,d,e,f;b=a.c;switch(b){case 11:return a.Ml();case 12:return a.Ol();case 14:return a.Ql();case 15:return a.Tl();case 16:return a.Rl();case 17:return a.Ul();case 21:nde(a);return wfe(),wfe(),ffe;case 10:switch(a.a){case 65:return a.yl();case 90:return a.Dl();case 122:return a.Kl();case 98:return a.El();case 66:return a.zl();case 60:return a.Jl();case 62:return a.Hl();}}f=pde(a);b=a.c;switch(b){case 3:return a.Zl(f);case 4:return a.Xl(f);case 5:return a.Yl(f);case 0:if(a.a==123&&a.d<a.j){e=a.d;d=0;c=-1;if((b=bfb(a.i,e++))>=48&&b<=57){d=b-48;while(e<a.j&&(b=bfb(a.i,e++))>=48&&b<=57){d=d*10+b-48;if(d<0)throw vbb(new mde(tvd((h0d(),bve))))}}else{throw vbb(new mde(tvd((h0d(),Zue))))}c=d;if(b==44){if(e>=a.j){throw vbb(new mde(tvd((h0d(),_ue))))}else if((b=bfb(a.i,e++))>=48&&b<=57){c=b-48;while(e<a.j&&(b=bfb(a.i,e++))>=48&&b<=57){c=c*10+b-48;if(c<0)throw vbb(new mde(tvd((h0d(),bve))))}if(d>c)throw vbb(new mde(tvd((h0d(),ave))))}else{c=-1}}if(b!=125)throw vbb(new mde(tvd((h0d(),$ue))));if(a.sl(e)){f=(wfe(),wfe(),++vfe,new lge(9,f));a.d=e+1}else{f=(wfe(),wfe(),++vfe,new lge(3,f));a.d=e}f.dm(d);f.cm(c);nde(a)}}return f} +function $bc(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F;p=new Skb(b.b);u=new Skb(b.b);m=new Skb(b.b);B=new Skb(b.b);q=new Skb(b.b);for(A=Jsb(b,0);A.b!=A.d.c;){v=BD(Xsb(A),11);for(h=new olb(v.g);h.a<h.c.c.length;){f=BD(mlb(h),17);if(f.c.i==f.d.i){if(v.j==f.d.j){B.c[B.c.length]=f;continue}else if(v.j==(Ucd(),Acd)&&f.d.j==Rcd){q.c[q.c.length]=f;continue}}}}for(i=new olb(q);i.a<i.c.c.length;){f=BD(mlb(i),17);_bc(a,f,c,d,(Ucd(),zcd))}for(g=new olb(B);g.a<g.c.c.length;){f=BD(mlb(g),17);C=new b0b(a);__b(C,(j0b(),i0b));yNb(C,(Nyc(),Vxc),(dcd(),$bd));yNb(C,(wtc(),$sc),f);D=new H0b;yNb(D,$sc,f.d);G0b(D,(Ucd(),Tcd));F0b(D,C);F=new H0b;yNb(F,$sc,f.c);G0b(F,zcd);F0b(F,C);yNb(f.c,gtc,C);yNb(f.d,gtc,C);QZb(f,null);RZb(f,null);c.c[c.c.length]=C;yNb(C,ysc,meb(2))}for(w=Jsb(b,0);w.b!=w.d.c;){v=BD(Xsb(w),11);j=v.e.c.length>0;r=v.g.c.length>0;j&&r?(m.c[m.c.length]=v,true):j?(p.c[p.c.length]=v,true):r&&(u.c[u.c.length]=v,true)}for(o=new olb(p);o.a<o.c.c.length;){n=BD(mlb(o),11);Ekb(e,Zbc(a,n,null,c))}for(t=new olb(u);t.a<t.c.c.length;){s=BD(mlb(t),11);Ekb(e,Zbc(a,null,s,c))}for(l=new olb(m);l.a<l.c.c.length;){k=BD(mlb(l),11);Ekb(e,Zbc(a,k,k,c))}} +function NCb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D;s=new f7c(Pje,Pje);b=new f7c(Qje,Qje);for(B=new olb(a);B.a<B.c.c.length;){A=BD(mlb(B),8);s.a=$wnd.Math.min(s.a,A.a);s.b=$wnd.Math.min(s.b,A.b);b.a=$wnd.Math.max(b.a,A.a);b.b=$wnd.Math.max(b.b,A.b)}m=new f7c(b.a-s.a,b.b-s.b);j=new f7c(s.a-50,s.b-m.a-50);k=new f7c(s.a-50,b.b+m.a+50);l=new f7c(b.a+m.b/2+50,s.b+m.b/2);n=new eDb(j,k,l);w=new Tqb;f=new Rkb;c=new Rkb;w.a.zc(n,w);for(D=new olb(a);D.a<D.c.c.length;){C=BD(mlb(D),8);f.c=KC(SI,Uhe,1,0,5,1);for(v=w.a.ec().Kc();v.Ob();){t=BD(v.Pb(),308);d=t.d;S6c(d,t.a);Jy(S6c(t.d,C),S6c(t.d,t.a))<0&&(f.c[f.c.length]=t,true)}c.c=KC(SI,Uhe,1,0,5,1);for(u=new olb(f);u.a<u.c.c.length;){t=BD(mlb(u),308);for(q=new olb(t.e);q.a<q.c.c.length;){o=BD(mlb(q),168);g=true;for(i=new olb(f);i.a<i.c.c.length;){h=BD(mlb(i),308);h!=t&&(wtb(o,Ikb(h.e,0))||wtb(o,Ikb(h.e,1))||wtb(o,Ikb(h.e,2)))&&(g=false)}g&&(c.c[c.c.length]=o,true)}}Ve(w,f);reb(w,new OCb);for(p=new olb(c);p.a<p.c.c.length;){o=BD(mlb(p),168);Qqb(w,new eDb(C,o.a,o.b))}}r=new Tqb;reb(w,new QCb(r));e=r.a.ec().Kc();while(e.Ob()){o=BD(e.Pb(),168);(dDb(n,o.a)||dDb(n,o.b))&&e.Qb()}reb(r,new SCb);return r} +function _Tb(a){var b,c,d,e,f;c=BD(vNb(a,(wtc(),Ksc)),21);b=k3c(WTb);e=BD(vNb(a,(Nyc(),axc)),334);e==(hbd(),ebd)&&d3c(b,XTb);Ccb(DD(vNb(a,$wc)))?e3c(b,(qUb(),lUb),(S8b(),I8b)):e3c(b,(qUb(),nUb),(S8b(),I8b));vNb(a,(g6c(),f6c))!=null&&d3c(b,YTb);(Ccb(DD(vNb(a,hxc)))||Ccb(DD(vNb(a,_wc))))&&c3c(b,(qUb(),pUb),(S8b(),W7b));switch(BD(vNb(a,Lwc),103).g){case 2:case 3:case 4:c3c(e3c(b,(qUb(),lUb),(S8b(),Y7b)),pUb,X7b);}c.Hc((Orc(),Frc))&&c3c(e3c(e3c(b,(qUb(),lUb),(S8b(),V7b)),oUb,T7b),pUb,U7b);PD(vNb(a,rxc))!==PD((kAc(),iAc))&&e3c(b,(qUb(),nUb),(S8b(),A8b));if(c.Hc(Mrc)){e3c(b,(qUb(),lUb),(S8b(),G8b));e3c(b,mUb,E8b);e3c(b,nUb,F8b)}PD(vNb(a,swc))!==PD((yrc(),wrc))&&PD(vNb(a,Swc))!==PD((Aad(),xad))&&c3c(b,(qUb(),pUb),(S8b(),j8b));Ccb(DD(vNb(a,cxc)))&&e3c(b,(qUb(),nUb),(S8b(),i8b));Ccb(DD(vNb(a,Hwc)))&&e3c(b,(qUb(),nUb),(S8b(),O8b));if(cUb(a)){PD(vNb(a,axc))===PD(ebd)?(d=BD(vNb(a,Cwc),292)):(d=BD(vNb(a,Dwc),292));f=d==(Xrc(),Vrc)?(S8b(),D8b):(S8b(),R8b);e3c(b,(qUb(),oUb),f)}switch(BD(vNb(a,Kyc),377).g){case 1:e3c(b,(qUb(),oUb),(S8b(),P8b));break;case 2:c3c(e3c(e3c(b,(qUb(),nUb),(S8b(),P7b)),oUb,Q7b),pUb,R7b);}PD(vNb(a,ywc))!==PD((tAc(),rAc))&&e3c(b,(qUb(),nUb),(S8b(),Q8b));return b} +function mZc(a){r4c(a,new E3c(P3c(M3c(O3c(N3c(new R3c,Kre),'ELK Rectangle Packing'),'Algorithm for packing of unconnected boxes, i.e. graphs without edges. The given order of the boxes is always preserved and the main reading direction of the boxes is left to right. The algorithm is divided into two phases. One phase approximates the width in which the rectangles can be placed. The next phase places the rectangles in rows using the previously calculated width as bounding width and bundles rectangles with a similar height in blocks. A compaction step reduces the size of the drawing. Finally, the rectangles are expanded to fill their bounding box and eliminate empty unused spaces.'),new pZc)));p4c(a,Kre,_le,1.3);p4c(a,Kre,Jre,Ksd(VYc));p4c(a,Kre,ame,gZc);p4c(a,Kre,wme,15);p4c(a,Kre,lqe,Ksd(SYc));p4c(a,Kre,Fme,Ksd(_Yc));p4c(a,Kre,Tme,Ksd(aZc));p4c(a,Kre,Eme,Ksd(bZc));p4c(a,Kre,Gme,Ksd($Yc));p4c(a,Kre,Dme,Ksd(cZc));p4c(a,Kre,Hme,Ksd(hZc));p4c(a,Kre,Bre,Ksd(eZc));p4c(a,Kre,Cre,Ksd(ZYc));p4c(a,Kre,Fre,Ksd(dZc));p4c(a,Kre,Gre,Ksd(iZc));p4c(a,Kre,Hre,Ksd(WYc));p4c(a,Kre,Ame,Ksd(XYc));p4c(a,Kre,xqe,Ksd(YYc));p4c(a,Kre,Ere,Ksd(UYc));p4c(a,Kre,Dre,Ksd(TYc));p4c(a,Kre,Ire,Ksd(kZc))} +function Wmd(b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r;if(d==null){return null}if(b.a!=c.Aj()){throw vbb(new Wdb(tte+c.ne()+ute))}if(JD(c,457)){r=_Pd(BD(c,671),d);if(!r){throw vbb(new Wdb(vte+d+"' is not a valid enumerator of '"+c.ne()+"'"))}return r}switch(o1d((O6d(),M6d),c).cl()){case 2:{d=Qge(d,false);break}case 3:{d=Qge(d,true);break}}e=o1d(M6d,c).$k();if(e){return e.Aj().Nh().Kh(e,d)}n=o1d(M6d,c).al();if(n){r=new Rkb;for(k=Zmd(d),l=0,m=k.length;l<m;++l){j=k[l];Ekb(r,n.Aj().Nh().Kh(n,j))}return r}q=o1d(M6d,c).bl();if(!q.dc()){for(p=q.Kc();p.Ob();){o=BD(p.Pb(),148);try{r=o.Aj().Nh().Kh(o,d);if(r!=null){return r}}catch(a){a=ubb(a);if(!JD(a,60))throw vbb(a)}}throw vbb(new Wdb(vte+d+"' does not match any member types of the union datatype '"+c.ne()+"'"))}BD(c,834).Fj();f=r6d(c.Bj());if(!f)return null;if(f==yI){h=0;try{h=Icb(d,Rie,Ohe)&aje}catch(a){a=ubb(a);if(JD(a,127)){g=rfb(d);h=g[0]}else throw vbb(a)}return bdb(h)}if(f==$J){for(i=0;i<Pmd.length;++i){try{return DQd(Pmd[i],d)}catch(a){a=ubb(a);if(!JD(a,32))throw vbb(a)}}throw vbb(new Wdb(vte+d+"' is not a date formatted string of the form yyyy-MM-dd'T'HH:mm:ss'.'SSSZ or a valid subset thereof"))}throw vbb(new Wdb(vte+d+"' is invalid. "))} +function ngb(a,b){var c,d,e,f,g,h,i,j;c=0;g=0;f=b.length;h=null;j=new Vfb;if(g<f&&(BCb(g,b.length),b.charCodeAt(g)==43)){++g;++c;if(g<f&&(BCb(g,b.length),b.charCodeAt(g)==43||(BCb(g,b.length),b.charCodeAt(g)==45))){throw vbb(new Oeb(Oje+b+'"'))}}while(g<f&&(BCb(g,b.length),b.charCodeAt(g)!=46)&&(BCb(g,b.length),b.charCodeAt(g)!=101)&&(BCb(g,b.length),b.charCodeAt(g)!=69)){++g}j.a+=''+qfb(b==null?Xhe:(uCb(b),b),c,g);if(g<f&&(BCb(g,b.length),b.charCodeAt(g)==46)){++g;c=g;while(g<f&&(BCb(g,b.length),b.charCodeAt(g)!=101)&&(BCb(g,b.length),b.charCodeAt(g)!=69)){++g}a.e=g-c;j.a+=''+qfb(b==null?Xhe:(uCb(b),b),c,g)}else{a.e=0}if(g<f&&(BCb(g,b.length),b.charCodeAt(g)==101||(BCb(g,b.length),b.charCodeAt(g)==69))){++g;c=g;if(g<f&&(BCb(g,b.length),b.charCodeAt(g)==43)){++g;g<f&&(BCb(g,b.length),b.charCodeAt(g)!=45)&&++c}h=b.substr(c,f-c);a.e=a.e-Icb(h,Rie,Ohe);if(a.e!=QD(a.e)){throw vbb(new Oeb('Scale out of range.'))}}i=j.a;if(i.length<16){a.f=(kgb==null&&(kgb=new RegExp('^[+-]?\\d*$','i')),kgb.test(i)?parseInt(i,10):NaN);if(isNaN(a.f)){throw vbb(new Oeb(Oje+b+'"'))}a.a=ugb(a.f)}else{ogb(a,new Ygb(i))}a.d=j.a.length;for(e=0;e<j.a.length;++e){d=bfb(j.a,e);if(d!=45&&d!=48){break}--a.d}a.d==0&&(a.d=1)} +function xXb(){xXb=ccb;wXb=new Hp;Rc(wXb,(Ucd(),Fcd),Jcd);Rc(wXb,Qcd,Jcd);Rc(wXb,Qcd,Mcd);Rc(wXb,Bcd,Icd);Rc(wXb,Bcd,Jcd);Rc(wXb,Gcd,Jcd);Rc(wXb,Gcd,Kcd);Rc(wXb,Ocd,Dcd);Rc(wXb,Ocd,Jcd);Rc(wXb,Lcd,Ecd);Rc(wXb,Lcd,Jcd);Rc(wXb,Lcd,Kcd);Rc(wXb,Lcd,Dcd);Rc(wXb,Ecd,Lcd);Rc(wXb,Ecd,Mcd);Rc(wXb,Ecd,Icd);Rc(wXb,Ecd,Jcd);Rc(wXb,Ncd,Ncd);Rc(wXb,Ncd,Kcd);Rc(wXb,Ncd,Mcd);Rc(wXb,Hcd,Hcd);Rc(wXb,Hcd,Kcd);Rc(wXb,Hcd,Icd);Rc(wXb,Pcd,Pcd);Rc(wXb,Pcd,Dcd);Rc(wXb,Pcd,Mcd);Rc(wXb,Ccd,Ccd);Rc(wXb,Ccd,Dcd);Rc(wXb,Ccd,Icd);Rc(wXb,Kcd,Gcd);Rc(wXb,Kcd,Lcd);Rc(wXb,Kcd,Ncd);Rc(wXb,Kcd,Hcd);Rc(wXb,Kcd,Jcd);Rc(wXb,Kcd,Kcd);Rc(wXb,Kcd,Mcd);Rc(wXb,Kcd,Icd);Rc(wXb,Dcd,Ocd);Rc(wXb,Dcd,Lcd);Rc(wXb,Dcd,Pcd);Rc(wXb,Dcd,Ccd);Rc(wXb,Dcd,Dcd);Rc(wXb,Dcd,Mcd);Rc(wXb,Dcd,Icd);Rc(wXb,Dcd,Jcd);Rc(wXb,Mcd,Qcd);Rc(wXb,Mcd,Ecd);Rc(wXb,Mcd,Ncd);Rc(wXb,Mcd,Pcd);Rc(wXb,Mcd,Kcd);Rc(wXb,Mcd,Dcd);Rc(wXb,Mcd,Mcd);Rc(wXb,Mcd,Jcd);Rc(wXb,Icd,Bcd);Rc(wXb,Icd,Ecd);Rc(wXb,Icd,Hcd);Rc(wXb,Icd,Ccd);Rc(wXb,Icd,Kcd);Rc(wXb,Icd,Dcd);Rc(wXb,Icd,Icd);Rc(wXb,Icd,Jcd);Rc(wXb,Jcd,Fcd);Rc(wXb,Jcd,Qcd);Rc(wXb,Jcd,Bcd);Rc(wXb,Jcd,Gcd);Rc(wXb,Jcd,Ocd);Rc(wXb,Jcd,Lcd);Rc(wXb,Jcd,Ecd);Rc(wXb,Jcd,Kcd);Rc(wXb,Jcd,Dcd);Rc(wXb,Jcd,Mcd);Rc(wXb,Jcd,Icd);Rc(wXb,Jcd,Jcd)} +function YXb(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B;a.d=new f7c(Pje,Pje);a.c=new f7c(Qje,Qje);for(m=b.Kc();m.Ob();){k=BD(m.Pb(),37);for(t=new olb(k.a);t.a<t.c.c.length;){s=BD(mlb(t),10);a.d.a=$wnd.Math.min(a.d.a,s.n.a-s.d.b);a.d.b=$wnd.Math.min(a.d.b,s.n.b-s.d.d);a.c.a=$wnd.Math.max(a.c.a,s.n.a+s.o.a+s.d.c);a.c.b=$wnd.Math.max(a.c.b,s.n.b+s.o.b+s.d.a)}}h=new nYb;for(l=b.Kc();l.Ob();){k=BD(l.Pb(),37);d=fYb(a,k);Ekb(h.a,d);d.a=d.a|!BD(vNb(d.c,(wtc(),Esc)),21).dc()}a.b=(LUb(),B=new VUb,B.f=new CUb(c),B.b=BUb(B.f,h),B);PUb((o=a.b,new Zdd,o));a.e=new d7c;a.a=a.b.f.e;for(g=new olb(h.a);g.a<g.c.c.length;){e=BD(mlb(g),841);u=QUb(a.b,e);g_b(e.c,u.a,u.b);for(q=new olb(e.c.a);q.a<q.c.c.length;){p=BD(mlb(q),10);if(p.k==(j0b(),e0b)){r=aYb(a,p.n,BD(vNb(p,(wtc(),Hsc)),61));P6c(X6c(p.n),r)}}}for(f=new olb(h.a);f.a<f.c.c.length;){e=BD(mlb(f),841);for(j=new olb(lYb(e));j.a<j.c.c.length;){i=BD(mlb(j),17);A=new t7c(i.a);St(A,0,A0b(i.c));Dsb(A,A0b(i.d));n=null;for(w=Jsb(A,0);w.b!=w.d.c;){v=BD(Xsb(w),8);if(!n){n=v;continue}if(Ky(n.a,v.a)){a.e.a=$wnd.Math.min(a.e.a,n.a);a.a.a=$wnd.Math.max(a.a.a,n.a)}else if(Ky(n.b,v.b)){a.e.b=$wnd.Math.min(a.e.b,n.b);a.a.b=$wnd.Math.max(a.a.b,n.b)}n=v}}}V6c(a.e);P6c(a.a,a.e)} +function wZd(a){Bnd(a.b,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'ConsistentTransient']));Bnd(a.a,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'WellFormedSourceURI']));Bnd(a.o,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'InterfaceIsAbstract AtMostOneID UniqueFeatureNames UniqueOperationSignatures NoCircularSuperTypes WellFormedMapEntryClass ConsistentSuperTypes DisjointFeatureAndOperationSignatures']));Bnd(a.p,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'WellFormedInstanceTypeName UniqueTypeParameterNames']));Bnd(a.v,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'UniqueEnumeratorNames UniqueEnumeratorLiterals']));Bnd(a.R,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'WellFormedName']));Bnd(a.T,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'UniqueParameterNames UniqueTypeParameterNames NoRepeatingVoid']));Bnd(a.U,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'WellFormedNsURI WellFormedNsPrefix UniqueSubpackageNames UniqueClassifierNames UniqueNsURIs']));Bnd(a.W,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'ConsistentOpposite SingleContainer ConsistentKeys ConsistentUnique ConsistentContainer']));Bnd(a.bb,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'ValidDefaultValueLiteral']));Bnd(a.eb,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'ValidLowerBound ValidUpperBound ConsistentBounds ValidType']));Bnd(a.H,_ve,OC(GC(ZI,1),nie,2,6,[bwe,'ConsistentType ConsistentBounds ConsistentArguments']))} +function B4b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C;if(b.dc()){return}e=new s7c;h=c?c:BD(b.Xb(0),17);o=h.c;hQc();m=o.i.k;if(!(m==(j0b(),h0b)||m==i0b||m==e0b||m==d0b)){throw vbb(new Wdb('The target node of the edge must be a normal node or a northSouthPort.'))}Fsb(e,l7c(OC(GC(m1,1),nie,8,0,[o.i.n,o.n,o.a])));if((Ucd(),Lcd).Hc(o.j)){q=Edb(ED(vNb(o,(wtc(),qtc))));l=new f7c(l7c(OC(GC(m1,1),nie,8,0,[o.i.n,o.n,o.a])).a,q);Gsb(e,l,e.c.b,e.c)}k=null;d=false;i=b.Kc();while(i.Ob()){g=BD(i.Pb(),17);f=g.a;if(f.b!=0){if(d){j=Y6c(P6c(k,(sCb(f.b!=0),BD(f.a.a.c,8))),0.5);Gsb(e,j,e.c.b,e.c);d=false}else{d=true}k=R6c((sCb(f.b!=0),BD(f.c.b.c,8)));ye(e,f);Osb(f)}}p=h.d;if(Lcd.Hc(p.j)){q=Edb(ED(vNb(p,(wtc(),qtc))));l=new f7c(l7c(OC(GC(m1,1),nie,8,0,[p.i.n,p.n,p.a])).a,q);Gsb(e,l,e.c.b,e.c)}Fsb(e,l7c(OC(GC(m1,1),nie,8,0,[p.i.n,p.n,p.a])));a.d==(tBc(),qBc)&&(r=(sCb(e.b!=0),BD(e.a.a.c,8)),s=BD(Ut(e,1),8),t=new e7c(bRc(o.j)),t.a*=5,t.b*=5,u=c7c(new f7c(s.a,s.b),r),v=new f7c(A4b(t.a,u.a),A4b(t.b,u.b)),P6c(v,r),w=Jsb(e,1),Vsb(w,v),A=(sCb(e.b!=0),BD(e.c.b.c,8)),B=BD(Ut(e,e.b-2),8),t=new e7c(bRc(p.j)),t.a*=5,t.b*=5,u=c7c(new f7c(B.a,B.b),A),C=new f7c(A4b(t.a,u.a),A4b(t.b,u.b)),P6c(C,A),St(e,e.b-1,C),undefined);n=new YPc(e);ye(h.a,UPc(n))} +function Kgd(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I,J,K,L,M,N,O,P;t=BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82);v=t.Dg();w=t.Eg();u=t.Cg()/2;p=t.Bg()/2;if(JD(t,186)){s=BD(t,118);v+=mpd(s).i;v+=mpd(s).i}v+=u;w+=p;F=BD(qud((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b),0),82);H=F.Dg();I=F.Eg();G=F.Cg()/2;A=F.Bg()/2;if(JD(F,186)){D=BD(F,118);H+=mpd(D).i;H+=mpd(D).i}H+=G;I+=A;if((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i==0){h=(Fhd(),j=new rmd,j);wtd((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a),h)}else if((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i>1){o=new Oyd((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a));while(o.e!=o.i.gc()){Eyd(o)}}g=BD(qud((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a),0),202);q=H;H>v+u?(q=v+u):H<v-u&&(q=v-u);r=I;I>w+p?(r=w+p):I<w-p&&(r=w-p);q>v-u&&q<v+u&&r>w-p&&r<w+p&&(q=v+u);omd(g,q);pmd(g,r);B=v;v>H+G?(B=H+G):v<H-G&&(B=H-G);C=w;w>I+A?(C=I+A):w<I-A&&(C=I-A);B>H-G&&B<H+G&&C>I-A&&C<I+A&&(C=I+A);hmd(g,B);imd(g,C);Uxd((!g.a&&(g.a=new xMd(y2,g,5)),g.a));f=Bub(b,5);t==F&&++f;L=B-q;O=C-r;J=$wnd.Math.sqrt(L*L+O*O);l=J*0.20000000298023224;M=L/(f+1);P=O/(f+1);K=q;N=r;for(k=0;k<f;k++){K+=M;N+=P;m=K+Cub(b,24)*lke*l-l/2;m<0?(m=1):m>c&&(m=c-1);n=N+Cub(b,24)*lke*l-l/2;n<0?(n=1):n>d&&(n=d-1);e=(Fhd(),i=new xkd,i);vkd(e,m);wkd(e,n);wtd((!g.a&&(g.a=new xMd(y2,g,5)),g.a),e)}} +function Nyc(){Nyc=ccb;iyc=(Y9c(),I9c);jyc=J9c;kyc=K9c;lyc=L9c;nyc=M9c;oyc=N9c;ryc=P9c;tyc=R9c;uyc=S9c;syc=Q9c;vyc=T9c;xyc=U9c;zyc=X9c;qyc=O9c;hyc=(jwc(),Bvc);myc=Cvc;pyc=Dvc;wyc=Evc;byc=new Osd(D9c,meb(0));cyc=yvc;dyc=zvc;eyc=Avc;Kyc=awc;Cyc=Hvc;Dyc=Kvc;Gyc=Svc;Eyc=Nvc;Fyc=Pvc;Myc=fwc;Lyc=cwc;Iyc=Yvc;Hyc=Wvc;Jyc=$vc;Cxc=pvc;Dxc=qvc;Xwc=Auc;Ywc=Duc;Lxc=new q0b(12);Kxc=new Osd(f9c,Lxc);Twc=(Aad(),wad);Swc=new Osd(E8c,Twc);Uxc=new Osd(s9c,0);fyc=new Osd(E9c,meb(1));owc=new Osd(r8c,tme);Jxc=d9c;Vxc=t9c;$xc=A9c;Kwc=y8c;mwc=p8c;axc=J8c;gyc=new Osd(H9c,(Bcb(),true));fxc=M8c;gxc=N8c;Fxc=Y8c;Ixc=b9c;Gxc=$8c;Nwc=(ead(),cad);Lwc=new Osd(z8c,Nwc);xxc=W8c;wxc=U8c;Yxc=x9c;Xxc=w9c;Zxc=z9c;Oxc=(Tbd(),Sbd);new Osd(l9c,Oxc);Qxc=o9c;Rxc=p9c;Sxc=q9c;Pxc=n9c;Byc=Gvc;sxc=avc;rxc=$uc;Ayc=Fvc;mxc=Suc;Jwc=muc;Iwc=kuc;Awc=Xtc;Bwc=Ytc;Dwc=buc;Cwc=Ztc;Hwc=iuc;uxc=cvc;vxc=dvc;ixc=Luc;Exc=uvc;zxc=hvc;$wc=Guc;Bxc=nvc;Vwc=wuc;Wwc=yuc;zwc=w8c;yxc=evc;swc=Mtc;rwc=Ktc;qwc=Jtc;cxc=Juc;bxc=Iuc;dxc=Kuc;Hxc=_8c;jxc=Q8c;Zwc=G8c;Qwc=C8c;Pwc=B8c;Ewc=euc;Wxc=v9c;pwc=v8c;exc=L8c;Txc=r9c;Mxc=h9c;Nxc=j9c;oxc=Vuc;pxc=Xuc;ayc=C9c;nwc=Itc;qxc=Zuc;Rwc=suc;Owc=quc;txc=S8c;kxc=Puc;Axc=kvc;yyc=V9c;Mwc=ouc;_xc=wvc;Uwc=uuc;lxc=Ruc;Fwc=guc;hxc=P8c;nxc=Uuc;Gwc=huc;ywc=Vtc;wwc=Stc;uwc=Qtc;vwc=Rtc;xwc=Utc;twc=Otc;_wc=Huc} +function shb(a,b){phb();var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H;B=a.e;o=a.d;e=a.a;if(B==0){switch(b){case 0:return '0';case 1:return $je;case 2:return '0.00';case 3:return '0.000';case 4:return '0.0000';case 5:return '0.00000';case 6:return '0.000000';default:w=new Ufb;b<0?(w.a+='0E+',w):(w.a+='0E',w);w.a+=-b;return w.a;}}t=o*10+1+7;u=KC(TD,$ie,25,t+1,15,1);c=t;if(o==1){h=e[0];if(h<0){H=xbb(h,Yje);do{p=H;H=Abb(H,10);u[--c]=48+Tbb(Qbb(p,Ibb(H,10)))&aje}while(ybb(H,0)!=0)}else{H=h;do{p=H;H=H/10|0;u[--c]=48+(p-H*10)&aje}while(H!=0)}}else{D=KC(WD,oje,25,o,15,1);G=o;$fb(e,0,D,0,G);I:while(true){A=0;for(j=G-1;j>=0;j--){F=wbb(Nbb(A,32),xbb(D[j],Yje));r=qhb(F);D[j]=Tbb(r);A=Tbb(Obb(r,32))}s=Tbb(A);q=c;do{u[--c]=48+s%10&aje}while((s=s/10|0)!=0&&c!=0);d=9-q+c;for(i=0;i<d&&c>0;i++){u[--c]=48}l=G-1;for(;D[l]==0;l--){if(l==0){break I}}G=l+1}while(u[c]==48){++c}}n=B<0;g=t-c-b-1;if(b==0){n&&(u[--c]=45);return zfb(u,c,t-c)}if(b>0&&g>=-6){if(g>=0){k=c+g;for(m=t-1;m>=k;m--){u[m+1]=u[m]}u[++k]=46;n&&(u[--c]=45);return zfb(u,c,t-c+1)}for(l=2;l<-g+1;l++){u[--c]=48}u[--c]=46;u[--c]=48;n&&(u[--c]=45);return zfb(u,c,t-c)}C=c+1;f=t;v=new Vfb;n&&(v.a+='-',v);if(f-C>=1){Kfb(v,u[c]);v.a+='.';v.a+=zfb(u,c+1,t-c-1)}else{v.a+=zfb(u,c,t-c)}v.a+='E';g>0&&(v.a+='+',v);v.a+=''+g;return v.a} +function z$c(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;a.c=b;a.g=new Lqb;c=(Pgd(),new bhd(a.c));d=new YGb(c);UGb(d);t=GD(hkd(a.c,(d0c(),Y_c)));i=BD(hkd(a.c,$_c),316);v=BD(hkd(a.c,__c),429);g=BD(hkd(a.c,T_c),482);u=BD(hkd(a.c,Z_c),430);a.j=Edb(ED(hkd(a.c,a0c)));h=a.a;switch(i.g){case 0:h=a.a;break;case 1:h=a.b;break;case 2:h=a.i;break;case 3:h=a.e;break;case 4:h=a.f;break;default:throw vbb(new Wdb(Mre+(i.f!=null?i.f:''+i.g)));}a.d=new g_c(h,v,g);yNb(a.d,(XNb(),VNb),DD(hkd(a.c,V_c)));a.d.c=Ccb(DD(hkd(a.c,U_c)));if(Vod(a.c).i==0){return a.d}for(l=new Fyd(Vod(a.c));l.e!=l.i.gc();){k=BD(Dyd(l),33);n=k.g/2;m=k.f/2;w=new f7c(k.i+n,k.j+m);while(Mhb(a.g,w)){O6c(w,($wnd.Math.random()-0.5)*qme,($wnd.Math.random()-0.5)*qme)}p=BD(hkd(k,(Y9c(),S8c)),142);q=new aOb(w,new J6c(w.a-n-a.j/2-p.b,w.b-m-a.j/2-p.d,k.g+a.j+(p.b+p.c),k.f+a.j+(p.d+p.a)));Ekb(a.d.i,q);Rhb(a.g,w,new vgd(q,k))}switch(u.g){case 0:if(t==null){a.d.d=BD(Ikb(a.d.i,0),65)}else{for(s=new olb(a.d.i);s.a<s.c.c.length;){q=BD(mlb(s),65);o=BD(BD(Ohb(a.g,q.a),46).b,33).zg();o!=null&&dfb(o,t)&&(a.d.d=q)}}break;case 1:e=new f7c(a.c.g,a.c.f);e.a*=0.5;e.b*=0.5;O6c(e,a.c.i,a.c.j);f=Pje;for(r=new olb(a.d.i);r.a<r.c.c.length;){q=BD(mlb(r),65);j=S6c(q.a,e);if(j<f){f=j;a.d.d=q}}break;default:throw vbb(new Wdb(Mre+(u.f!=null?u.f:''+u.g)));}return a.d} +function qfd(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;v=BD(qud((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a),0),202);k=new s7c;u=new Lqb;w=tfd(v);jrb(u.f,v,w);m=new Lqb;d=new Psb;for(o=ul(pl(OC(GC(KI,1),Uhe,20,0,[(!b.d&&(b.d=new y5d(B2,b,8,5)),b.d),(!b.e&&(b.e=new y5d(B2,b,7,4)),b.e)])));Qr(o);){n=BD(Rr(o),79);if((!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i!=1){throw vbb(new Wdb(Tse+(!a.a&&(a.a=new cUd(A2,a,6,6)),a.a).i))}if(n!=a){q=BD(qud((!n.a&&(n.a=new cUd(A2,n,6,6)),n.a),0),202);Gsb(d,q,d.c.b,d.c);p=BD(Wd(irb(u.f,q)),12);if(!p){p=tfd(q);jrb(u.f,q,p)}l=c?c7c(new g7c(BD(Ikb(w,w.c.length-1),8)),BD(Ikb(p,p.c.length-1),8)):c7c(new g7c((tCb(0,w.c.length),BD(w.c[0],8))),(tCb(0,p.c.length),BD(p.c[0],8)));jrb(m.f,q,l)}}if(d.b!=0){r=BD(Ikb(w,c?w.c.length-1:0),8);for(j=1;j<w.c.length;j++){s=BD(Ikb(w,c?w.c.length-1-j:j),8);e=Jsb(d,0);while(e.b!=e.d.c){q=BD(Xsb(e),202);p=BD(Wd(irb(u.f,q)),12);if(p.c.length<=j){Zsb(e)}else{t=P6c(new g7c(BD(Ikb(p,c?p.c.length-1-j:j),8)),BD(Wd(irb(m.f,q)),8));if(s.a!=t.a||s.b!=t.b){f=s.a-r.a;h=s.b-r.b;g=t.a-r.a;i=t.b-r.b;g*h==i*f&&(f==0||isNaN(f)?f:f<0?-1:1)==(g==0||isNaN(g)?g:g<0?-1:1)&&(h==0||isNaN(h)?h:h<0?-1:1)==(i==0||isNaN(i)?i:i<0?-1:1)?($wnd.Math.abs(f)<$wnd.Math.abs(g)||$wnd.Math.abs(h)<$wnd.Math.abs(i))&&(Gsb(k,s,k.c.b,k.c),true):j>1&&(Gsb(k,r,k.c.b,k.c),true);Zsb(e)}}}r=s}}return k} +function $Bc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I,J,K,L;Odd(c,'Greedy cycle removal',1);t=b.a;L=t.c.length;a.a=KC(WD,oje,25,L,15,1);a.c=KC(WD,oje,25,L,15,1);a.b=KC(WD,oje,25,L,15,1);j=0;for(r=new olb(t);r.a<r.c.c.length;){p=BD(mlb(r),10);p.p=j;for(C=new olb(p.j);C.a<C.c.c.length;){w=BD(mlb(C),11);for(h=new olb(w.e);h.a<h.c.c.length;){d=BD(mlb(h),17);if(d.c.i==p){continue}G=BD(vNb(d,(Nyc(),cyc)),19).a;a.a[j]+=G>0?G+1:1}for(g=new olb(w.g);g.a<g.c.c.length;){d=BD(mlb(g),17);if(d.d.i==p){continue}G=BD(vNb(d,(Nyc(),cyc)),19).a;a.c[j]+=G>0?G+1:1}}a.c[j]==0?Dsb(a.e,p):a.a[j]==0&&Dsb(a.f,p);++j}o=-1;n=1;l=new Rkb;a.d=BD(vNb(b,(wtc(),jtc)),230);while(L>0){while(a.e.b!=0){I=BD(Lsb(a.e),10);a.b[I.p]=o--;_Bc(a,I);--L}while(a.f.b!=0){J=BD(Lsb(a.f),10);a.b[J.p]=n++;_Bc(a,J);--L}if(L>0){m=Rie;for(s=new olb(t);s.a<s.c.c.length;){p=BD(mlb(s),10);if(a.b[p.p]==0){u=a.c[p.p]-a.a[p.p];if(u>=m){if(u>m){l.c=KC(SI,Uhe,1,0,5,1);m=u}l.c[l.c.length]=p}}}k=a.Zf(l);a.b[k.p]=n++;_Bc(a,k);--L}}H=t.c.length+1;for(j=0;j<t.c.length;j++){a.b[j]<0&&(a.b[j]+=H)}for(q=new olb(t);q.a<q.c.c.length;){p=BD(mlb(q),10);F=m_b(p.j);for(A=F,B=0,D=A.length;B<D;++B){w=A[B];v=k_b(w.g);for(e=v,f=0,i=e.length;f<i;++f){d=e[f];K=d.d.i.p;if(a.b[p.p]>a.b[K]){PZb(d,true);yNb(b,Asc,(Bcb(),true))}}}}a.a=null;a.c=null;a.b=null;Osb(a.f);Osb(a.e);Qdd(c)} +function sQb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;d=new Rkb;h=new Rkb;q=b/2;n=a.gc();e=BD(a.Xb(0),8);r=BD(a.Xb(1),8);o=tQb(e.a,e.b,r.a,r.b,q);Ekb(d,(tCb(0,o.c.length),BD(o.c[0],8)));Ekb(h,(tCb(1,o.c.length),BD(o.c[1],8)));for(j=2;j<n;j++){p=e;e=r;r=BD(a.Xb(j),8);o=tQb(e.a,e.b,p.a,p.b,q);Ekb(d,(tCb(1,o.c.length),BD(o.c[1],8)));Ekb(h,(tCb(0,o.c.length),BD(o.c[0],8)));o=tQb(e.a,e.b,r.a,r.b,q);Ekb(d,(tCb(0,o.c.length),BD(o.c[0],8)));Ekb(h,(tCb(1,o.c.length),BD(o.c[1],8)))}o=tQb(r.a,r.b,e.a,e.b,q);Ekb(d,(tCb(1,o.c.length),BD(o.c[1],8)));Ekb(h,(tCb(0,o.c.length),BD(o.c[0],8)));c=new s7c;g=new Rkb;Dsb(c,(tCb(0,d.c.length),BD(d.c[0],8)));for(k=1;k<d.c.length-2;k+=2){f=(tCb(k,d.c.length),BD(d.c[k],8));m=rQb((tCb(k-1,d.c.length),BD(d.c[k-1],8)),f,(tCb(k+1,d.c.length),BD(d.c[k+1],8)),(tCb(k+2,d.c.length),BD(d.c[k+2],8)));!isFinite(m.a)||!isFinite(m.b)?(Gsb(c,f,c.c.b,c.c),true):(Gsb(c,m,c.c.b,c.c),true)}Dsb(c,BD(Ikb(d,d.c.length-1),8));Ekb(g,(tCb(0,h.c.length),BD(h.c[0],8)));for(l=1;l<h.c.length-2;l+=2){f=(tCb(l,h.c.length),BD(h.c[l],8));m=rQb((tCb(l-1,h.c.length),BD(h.c[l-1],8)),f,(tCb(l+1,h.c.length),BD(h.c[l+1],8)),(tCb(l+2,h.c.length),BD(h.c[l+2],8)));!isFinite(m.a)||!isFinite(m.b)?(g.c[g.c.length]=f,true):(g.c[g.c.length]=m,true)}Ekb(g,BD(Ikb(h,h.c.length-1),8));for(i=g.c.length-1;i>=0;i--){Dsb(c,(tCb(i,g.c.length),BD(g.c[i],8)))}return c} +function aFd(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;g=true;l=null;d=null;e=null;b=false;n=BEd;j=null;f=null;h=0;i=UEd(a,h,zEd,AEd);if(i<a.length&&(BCb(i,a.length),a.charCodeAt(i)==58)){l=a.substr(h,i-h);h=i+1}c=l!=null&&hnb(GEd,l.toLowerCase());if(c){i=a.lastIndexOf('!/');if(i==-1){throw vbb(new Wdb('no archive separator'))}g=true;d=qfb(a,h,++i);h=i}else if(h>=0&&dfb(a.substr(h,'//'.length),'//')){h+=2;i=UEd(a,h,CEd,DEd);d=a.substr(h,i-h);h=i}else if(l!=null&&(h==a.length||(BCb(h,a.length),a.charCodeAt(h)!=47))){g=false;i=ifb(a,wfb(35),h);i==-1&&(i=a.length);d=a.substr(h,i-h);h=i}if(!c&&h<a.length&&(BCb(h,a.length),a.charCodeAt(h)==47)){i=UEd(a,h+1,CEd,DEd);k=a.substr(h+1,i-(h+1));if(k.length>0&&bfb(k,k.length-1)==58){e=k;h=i}}if(h<a.length&&(BCb(h,a.length),a.charCodeAt(h)==47)){++h;b=true}if(h<a.length&&(BCb(h,a.length),a.charCodeAt(h)!=63)&&(BCb(h,a.length),a.charCodeAt(h)!=35)){m=new Rkb;while(h<a.length&&(BCb(h,a.length),a.charCodeAt(h)!=63)&&(BCb(h,a.length),a.charCodeAt(h)!=35)){i=UEd(a,h,CEd,DEd);Ekb(m,a.substr(h,i-h));h=i;h<a.length&&(BCb(h,a.length),a.charCodeAt(h)==47)&&(bFd(a,++h)||(m.c[m.c.length]='',true))}n=KC(ZI,nie,2,m.c.length,6,1);Qkb(m,n)}if(h<a.length&&(BCb(h,a.length),a.charCodeAt(h)==63)){i=gfb(a,35,++h);i==-1&&(i=a.length);j=a.substr(h,i-h);h=i}h<a.length&&(f=pfb(a,++h));iFd(g,l,d,e,n,j);return new NEd(g,l,d,e,b,n,j,f)} +function sJc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I,J,K;I=new Rkb;for(o=new olb(b.b);o.a<o.c.c.length;){m=BD(mlb(o),29);for(v=new olb(m.a);v.a<v.c.c.length;){u=BD(mlb(v),10);u.p=-1;l=Rie;B=Rie;for(D=new olb(u.j);D.a<D.c.c.length;){C=BD(mlb(D),11);for(e=new olb(C.e);e.a<e.c.c.length;){c=BD(mlb(e),17);F=BD(vNb(c,(Nyc(),eyc)),19).a;l=$wnd.Math.max(l,F)}for(d=new olb(C.g);d.a<d.c.c.length;){c=BD(mlb(d),17);F=BD(vNb(c,(Nyc(),eyc)),19).a;B=$wnd.Math.max(B,F)}}yNb(u,hJc,meb(l));yNb(u,iJc,meb(B))}}r=0;for(n=new olb(b.b);n.a<n.c.c.length;){m=BD(mlb(n),29);for(v=new olb(m.a);v.a<v.c.c.length;){u=BD(mlb(v),10);if(u.p<0){H=new zJc;H.b=r++;oJc(a,u,H);I.c[I.c.length]=H}}}A=Pu(I.c.length);k=Pu(I.c.length);for(g=0;g<I.c.length;g++){Ekb(A,new Rkb);Ekb(k,meb(0))}mJc(b,I,A,k);J=BD(Qkb(I,KC(sY,Iqe,257,I.c.length,0,1)),840);w=BD(Qkb(A,KC(yK,eme,15,A.c.length,0,1)),192);j=KC(WD,oje,25,k.c.length,15,1);for(h=0;h<j.length;h++){j[h]=(tCb(h,k.c.length),BD(k.c[h],19)).a}s=0;t=new Rkb;for(i=0;i<J.length;i++){j[i]==0&&Ekb(t,J[i])}q=KC(WD,oje,25,J.length,15,1);while(t.c.length!=0){H=BD(Kkb(t,0),257);q[H.b]=s++;while(!w[H.b].dc()){K=BD(w[H.b].$c(0),257);--j[K.b];j[K.b]==0&&(t.c[t.c.length]=K,true)}}a.a=KC(sY,Iqe,257,J.length,0,1);for(f=0;f<J.length;f++){p=J[f];G=q[f];a.a[G]=p;p.b=G;for(v=new olb(p.e);v.a<v.c.c.length;){u=BD(mlb(v),10);u.p=G}}return a.a} +function nde(a){var b,c,d;if(a.d>=a.j){a.a=-1;a.c=1;return}b=bfb(a.i,a.d++);a.a=b;if(a.b==1){switch(b){case 92:d=10;if(a.d>=a.j)throw vbb(new mde(tvd((h0d(),uue))));a.a=bfb(a.i,a.d++);break;case 45:if((a.e&512)==512&&a.d<a.j&&bfb(a.i,a.d)==91){++a.d;d=24}else d=0;break;case 91:if((a.e&512)!=512&&a.d<a.j&&bfb(a.i,a.d)==58){++a.d;d=20;break}default:if((b&64512)==Uje&&a.d<a.j){c=bfb(a.i,a.d);if((c&64512)==56320){a.a=Tje+(b-Uje<<10)+c-56320;++a.d}}d=0;}a.c=d;return}switch(b){case 124:d=2;break;case 42:d=3;break;case 43:d=4;break;case 63:d=5;break;case 41:d=7;break;case 46:d=8;break;case 91:d=9;break;case 94:d=11;break;case 36:d=12;break;case 40:d=6;if(a.d>=a.j)break;if(bfb(a.i,a.d)!=63)break;if(++a.d>=a.j)throw vbb(new mde(tvd((h0d(),vue))));b=bfb(a.i,a.d++);switch(b){case 58:d=13;break;case 61:d=14;break;case 33:d=15;break;case 91:d=19;break;case 62:d=18;break;case 60:if(a.d>=a.j)throw vbb(new mde(tvd((h0d(),vue))));b=bfb(a.i,a.d++);if(b==61){d=16}else if(b==33){d=17}else throw vbb(new mde(tvd((h0d(),wue))));break;case 35:while(a.d<a.j){b=bfb(a.i,a.d++);if(b==41)break}if(b!=41)throw vbb(new mde(tvd((h0d(),xue))));d=21;break;default:if(b==45||97<=b&&b<=122||65<=b&&b<=90){--a.d;d=22;break}else if(b==40){d=23;break}throw vbb(new mde(tvd((h0d(),vue))));}break;case 92:d=10;if(a.d>=a.j)throw vbb(new mde(tvd((h0d(),uue))));a.a=bfb(a.i,a.d++);break;default:d=0;}a.c=d} +function P5b(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G;A=BD(vNb(a,(Nyc(),Vxc)),98);if(!(A!=(dcd(),bcd)&&A!=ccd)){return}o=a.b;n=o.c.length;k=new Skb((Xj(n+2,Mie),Oy(wbb(wbb(5,n+2),(n+2)/10|0))));p=new Skb((Xj(n+2,Mie),Oy(wbb(wbb(5,n+2),(n+2)/10|0))));Ekb(k,new Lqb);Ekb(k,new Lqb);Ekb(p,new Rkb);Ekb(p,new Rkb);w=new Rkb;for(b=0;b<n;b++){c=(tCb(b,o.c.length),BD(o.c[b],29));B=(tCb(b,k.c.length),BD(k.c[b],83));q=new Lqb;k.c[k.c.length]=q;D=(tCb(b,p.c.length),BD(p.c[b],15));s=new Rkb;p.c[p.c.length]=s;for(e=new olb(c.a);e.a<e.c.c.length;){d=BD(mlb(e),10);if(L5b(d)){w.c[w.c.length]=d;continue}for(j=new Sr(ur(R_b(d).a.Kc(),new Sq));Qr(j);){h=BD(Rr(j),17);F=h.c.i;if(!L5b(F)){continue}C=BD(B.xc(vNb(F,(wtc(),$sc))),10);if(!C){C=K5b(a,F);B.zc(vNb(F,$sc),C);D.Fc(C)}QZb(h,BD(Ikb(C.j,1),11))}for(i=new Sr(ur(U_b(d).a.Kc(),new Sq));Qr(i);){h=BD(Rr(i),17);G=h.d.i;if(!L5b(G)){continue}r=BD(Ohb(q,vNb(G,(wtc(),$sc))),10);if(!r){r=K5b(a,G);Rhb(q,vNb(G,$sc),r);s.c[s.c.length]=r}RZb(h,BD(Ikb(r.j,0),11))}}}for(l=0;l<p.c.length;l++){t=(tCb(l,p.c.length),BD(p.c[l],15));if(t.dc()){continue}m=null;if(l==0){m=new H1b(a);wCb(0,o.c.length);aCb(o.c,0,m)}else if(l==k.c.length-1){m=new H1b(a);o.c[o.c.length]=m}else{m=(tCb(l-1,o.c.length),BD(o.c[l-1],29))}for(g=t.Kc();g.Ob();){f=BD(g.Pb(),10);$_b(f,m)}}for(v=new olb(w);v.a<v.c.c.length;){u=BD(mlb(v),10);$_b(u,null)}yNb(a,(wtc(),Fsc),w)} +function BCc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v;Odd(c,'Coffman-Graham Layering',1);if(b.a.c.length==0){Qdd(c);return}v=BD(vNb(b,(Nyc(),kxc)),19).a;i=0;g=0;for(m=new olb(b.a);m.a<m.c.c.length;){l=BD(mlb(m),10);l.p=i++;for(f=new Sr(ur(U_b(l).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);e.p=g++}}a.d=KC(sbb,dle,25,i,16,1);a.a=KC(sbb,dle,25,g,16,1);a.b=KC(WD,oje,25,i,15,1);a.e=KC(WD,oje,25,i,15,1);a.f=KC(WD,oje,25,i,15,1);Nc(a.c);CCc(a,b);o=new gub(new GCc(a));for(u=new olb(b.a);u.a<u.c.c.length;){s=BD(mlb(u),10);for(f=new Sr(ur(R_b(s).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);a.a[e.p]||++a.b[s.p]}a.b[s.p]==0&&(zCb(cub(o,s)),true)}h=0;while(o.b.c.length!=0){s=BD(dub(o),10);a.f[s.p]=h++;for(f=new Sr(ur(U_b(s).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);if(a.a[e.p]){continue}q=e.d.i;--a.b[q.p];Rc(a.c,q,meb(a.f[s.p]));a.b[q.p]==0&&(zCb(cub(o,q)),true)}}n=new gub(new KCc(a));for(t=new olb(b.a);t.a<t.c.c.length;){s=BD(mlb(t),10);for(f=new Sr(ur(U_b(s).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);a.a[e.p]||++a.e[s.p]}a.e[s.p]==0&&(zCb(cub(n,s)),true)}k=new Rkb;d=yCc(b,k);while(n.b.c.length!=0){r=BD(dub(n),10);(d.a.c.length>=v||!wCc(r,d))&&(d=yCc(b,k));$_b(r,d);for(f=new Sr(ur(R_b(r).a.Kc(),new Sq));Qr(f);){e=BD(Rr(f),17);if(a.a[e.p]){continue}p=e.c.i;--a.e[p.p];a.e[p.p]==0&&(zCb(cub(n,p)),true)}}for(j=k.c.length-1;j>=0;--j){Ekb(b.b,(tCb(j,k.c.length),BD(k.c[j],29)))}b.a.c=KC(SI,Uhe,1,0,5,1);Qdd(c)} +function gee(a){var b,c,d,e,f,g,h,i,j;a.b=1;nde(a);b=null;if(a.c==0&&a.a==94){nde(a);b=(wfe(),wfe(),++vfe,new $fe(4));Ufe(b,0,lxe);h=(null,++vfe,new $fe(4))}else{h=(wfe(),wfe(),++vfe,new $fe(4))}e=true;while((j=a.c)!=1){if(j==0&&a.a==93&&!e){if(b){Zfe(b,h);h=b}break}c=a.a;d=false;if(j==10){switch(c){case 100:case 68:case 119:case 87:case 115:case 83:Xfe(h,fee(c));d=true;break;case 105:case 73:case 99:case 67:c=(Xfe(h,fee(c)),-1);c<0&&(d=true);break;case 112:case 80:i=tde(a,c);if(!i)throw vbb(new mde(tvd((h0d(),Iue))));Xfe(h,i);d=true;break;default:c=eee(a);}}else if(j==24&&!e){if(b){Zfe(b,h);h=b}f=gee(a);Zfe(h,f);if(a.c!=0||a.a!=93)throw vbb(new mde(tvd((h0d(),Mue))));break}nde(a);if(!d){if(j==0){if(c==91)throw vbb(new mde(tvd((h0d(),Nue))));if(c==93)throw vbb(new mde(tvd((h0d(),Oue))));if(c==45&&!e&&a.a!=93)throw vbb(new mde(tvd((h0d(),Pue))))}if(a.c!=0||a.a!=45||c==45&&e){Ufe(h,c,c)}else{nde(a);if((j=a.c)==1)throw vbb(new mde(tvd((h0d(),Kue))));if(j==0&&a.a==93){Ufe(h,c,c);Ufe(h,45,45)}else if(j==0&&a.a==93||j==24){throw vbb(new mde(tvd((h0d(),Pue))))}else{g=a.a;if(j==0){if(g==91)throw vbb(new mde(tvd((h0d(),Nue))));if(g==93)throw vbb(new mde(tvd((h0d(),Oue))));if(g==45)throw vbb(new mde(tvd((h0d(),Pue))))}else j==10&&(g=eee(a));nde(a);if(c>g)throw vbb(new mde(tvd((h0d(),Sue))));Ufe(h,c,g)}}}e=false}if(a.c==1)throw vbb(new mde(tvd((h0d(),Kue))));Yfe(h);Vfe(h);a.b=0;nde(a);return h} +function xZd(a){Bnd(a.c,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#decimal']));Bnd(a.d,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#integer']));Bnd(a.e,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#boolean']));Bnd(a.f,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'EBoolean',fue,'EBoolean:Object']));Bnd(a.i,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#byte']));Bnd(a.g,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#hexBinary']));Bnd(a.j,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'EByte',fue,'EByte:Object']));Bnd(a.n,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'EChar',fue,'EChar:Object']));Bnd(a.t,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#double']));Bnd(a.u,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'EDouble',fue,'EDouble:Object']));Bnd(a.F,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#float']));Bnd(a.G,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'EFloat',fue,'EFloat:Object']));Bnd(a.I,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#int']));Bnd(a.J,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'EInt',fue,'EInt:Object']));Bnd(a.N,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#long']));Bnd(a.O,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'ELong',fue,'ELong:Object']));Bnd(a.Z,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#short']));Bnd(a.$,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'EShort',fue,'EShort:Object']));Bnd(a._,Rve,OC(GC(ZI,1),nie,2,6,[cwe,'http://www.w3.org/2001/XMLSchema#string']))} +function fRc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G;if(a.c.length==1){return tCb(0,a.c.length),BD(a.c[0],135)}else if(a.c.length<=0){return new SRc}for(i=new olb(a);i.a<i.c.c.length;){g=BD(mlb(i),135);s=0;o=Ohe;p=Ohe;m=Rie;n=Rie;for(r=Jsb(g.b,0);r.b!=r.d.c;){q=BD(Xsb(r),86);s+=BD(vNb(q,(JTc(),ETc)),19).a;o=$wnd.Math.min(o,q.e.a);p=$wnd.Math.min(p,q.e.b);m=$wnd.Math.max(m,q.e.a+q.f.a);n=$wnd.Math.max(n,q.e.b+q.f.b)}yNb(g,(JTc(),ETc),meb(s));yNb(g,(mTc(),WSc),new f7c(o,p));yNb(g,VSc,new f7c(m,n))}mmb();Okb(a,new jRc);v=new SRc;tNb(v,(tCb(0,a.c.length),BD(a.c[0],94)));l=0;D=0;for(j=new olb(a);j.a<j.c.c.length;){g=BD(mlb(j),135);w=c7c(R6c(BD(vNb(g,(mTc(),VSc)),8)),BD(vNb(g,WSc),8));l=$wnd.Math.max(l,w.a);D+=w.a*w.b}l=$wnd.Math.max(l,$wnd.Math.sqrt(D)*Edb(ED(vNb(v,(JTc(),uTc)))));A=Edb(ED(vNb(v,HTc)));F=0;G=0;k=0;b=A;for(h=new olb(a);h.a<h.c.c.length;){g=BD(mlb(h),135);w=c7c(R6c(BD(vNb(g,(mTc(),VSc)),8)),BD(vNb(g,WSc),8));if(F+w.a>l){F=0;G+=k+A;k=0}eRc(v,g,F,G);b=$wnd.Math.max(b,F+w.a);k=$wnd.Math.max(k,w.b);F+=w.a+A}u=new Lqb;c=new Lqb;for(C=new olb(a);C.a<C.c.c.length;){B=BD(mlb(C),135);d=Ccb(DD(vNb(B,(Y9c(),y8c))));t=!B.q?(null,kmb):B.q;for(f=t.vc().Kc();f.Ob();){e=BD(f.Pb(),42);if(Mhb(u,e.cd())){if(PD(BD(e.cd(),146).wg())!==PD(e.dd())){if(d&&Mhb(c,e.cd())){Zfb();'Found different values for property '+BD(e.cd(),146).tg()+' in components.'}else{Rhb(u,BD(e.cd(),146),e.dd());yNb(v,BD(e.cd(),146),e.dd());d&&Rhb(c,BD(e.cd(),146),e.dd())}}}else{Rhb(u,BD(e.cd(),146),e.dd());yNb(v,BD(e.cd(),146),e.dd())}}}return v} +function MYb(){MYb=ccb;xXb();LYb=new Hp;Rc(LYb,(Ucd(),Gcd),Fcd);Rc(LYb,Qcd,Fcd);Rc(LYb,Hcd,Fcd);Rc(LYb,Ncd,Fcd);Rc(LYb,Mcd,Fcd);Rc(LYb,Kcd,Fcd);Rc(LYb,Ncd,Gcd);Rc(LYb,Fcd,Bcd);Rc(LYb,Gcd,Bcd);Rc(LYb,Qcd,Bcd);Rc(LYb,Hcd,Bcd);Rc(LYb,Lcd,Bcd);Rc(LYb,Ncd,Bcd);Rc(LYb,Mcd,Bcd);Rc(LYb,Kcd,Bcd);Rc(LYb,Ecd,Bcd);Rc(LYb,Fcd,Ocd);Rc(LYb,Gcd,Ocd);Rc(LYb,Bcd,Ocd);Rc(LYb,Qcd,Ocd);Rc(LYb,Hcd,Ocd);Rc(LYb,Lcd,Ocd);Rc(LYb,Ncd,Ocd);Rc(LYb,Ecd,Ocd);Rc(LYb,Pcd,Ocd);Rc(LYb,Mcd,Ocd);Rc(LYb,Icd,Ocd);Rc(LYb,Kcd,Ocd);Rc(LYb,Gcd,Qcd);Rc(LYb,Hcd,Qcd);Rc(LYb,Ncd,Qcd);Rc(LYb,Kcd,Qcd);Rc(LYb,Gcd,Hcd);Rc(LYb,Qcd,Hcd);Rc(LYb,Ncd,Hcd);Rc(LYb,Hcd,Hcd);Rc(LYb,Mcd,Hcd);Rc(LYb,Fcd,Ccd);Rc(LYb,Gcd,Ccd);Rc(LYb,Bcd,Ccd);Rc(LYb,Ocd,Ccd);Rc(LYb,Qcd,Ccd);Rc(LYb,Hcd,Ccd);Rc(LYb,Lcd,Ccd);Rc(LYb,Ncd,Ccd);Rc(LYb,Pcd,Ccd);Rc(LYb,Ecd,Ccd);Rc(LYb,Kcd,Ccd);Rc(LYb,Mcd,Ccd);Rc(LYb,Jcd,Ccd);Rc(LYb,Fcd,Pcd);Rc(LYb,Gcd,Pcd);Rc(LYb,Bcd,Pcd);Rc(LYb,Qcd,Pcd);Rc(LYb,Hcd,Pcd);Rc(LYb,Lcd,Pcd);Rc(LYb,Ncd,Pcd);Rc(LYb,Ecd,Pcd);Rc(LYb,Kcd,Pcd);Rc(LYb,Icd,Pcd);Rc(LYb,Jcd,Pcd);Rc(LYb,Gcd,Ecd);Rc(LYb,Qcd,Ecd);Rc(LYb,Hcd,Ecd);Rc(LYb,Ncd,Ecd);Rc(LYb,Pcd,Ecd);Rc(LYb,Kcd,Ecd);Rc(LYb,Mcd,Ecd);Rc(LYb,Fcd,Dcd);Rc(LYb,Gcd,Dcd);Rc(LYb,Bcd,Dcd);Rc(LYb,Qcd,Dcd);Rc(LYb,Hcd,Dcd);Rc(LYb,Lcd,Dcd);Rc(LYb,Ncd,Dcd);Rc(LYb,Ecd,Dcd);Rc(LYb,Kcd,Dcd);Rc(LYb,Gcd,Mcd);Rc(LYb,Bcd,Mcd);Rc(LYb,Ocd,Mcd);Rc(LYb,Hcd,Mcd);Rc(LYb,Fcd,Icd);Rc(LYb,Gcd,Icd);Rc(LYb,Ocd,Icd);Rc(LYb,Qcd,Icd);Rc(LYb,Hcd,Icd);Rc(LYb,Lcd,Icd);Rc(LYb,Ncd,Icd);Rc(LYb,Ncd,Jcd);Rc(LYb,Hcd,Jcd);Rc(LYb,Ecd,Fcd);Rc(LYb,Ecd,Qcd);Rc(LYb,Ecd,Bcd);Rc(LYb,Lcd,Fcd);Rc(LYb,Lcd,Gcd);Rc(LYb,Lcd,Ocd)} +function HVd(a,b){switch(a.e){case 0:case 2:case 4:case 6:case 42:case 44:case 46:case 48:case 8:case 10:case 12:case 14:case 16:case 18:case 20:case 22:case 24:case 26:case 28:case 30:case 32:case 34:case 36:case 38:return new U5d(a.b,a.a,b,a.c);case 1:return new BMd(a.a,b,bLd(b.Tg(),a.c));case 43:return new N4d(a.a,b,bLd(b.Tg(),a.c));case 3:return new xMd(a.a,b,bLd(b.Tg(),a.c));case 45:return new K4d(a.a,b,bLd(b.Tg(),a.c));case 41:return new dId(BD(wId(a.c),26),a.a,b,bLd(b.Tg(),a.c));case 50:return new c6d(BD(wId(a.c),26),a.a,b,bLd(b.Tg(),a.c));case 5:return new Q4d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 47:return new U4d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 7:return new cUd(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 49:return new gUd(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 9:return new I4d(a.a,b,bLd(b.Tg(),a.c));case 11:return new G4d(a.a,b,bLd(b.Tg(),a.c));case 13:return new C4d(a.a,b,bLd(b.Tg(),a.c));case 15:return new k2d(a.a,b,bLd(b.Tg(),a.c));case 17:return new c5d(a.a,b,bLd(b.Tg(),a.c));case 19:return new _4d(a.a,b,bLd(b.Tg(),a.c));case 21:return new X4d(a.a,b,bLd(b.Tg(),a.c));case 23:return new pMd(a.a,b,bLd(b.Tg(),a.c));case 25:return new D5d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 27:return new y5d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 29:return new t5d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 31:return new n5d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 33:return new A5d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 35:return new v5d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 37:return new p5d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 39:return new i5d(a.a,b,bLd(b.Tg(),a.c),a.d.n);case 40:return new u3d(b,bLd(b.Tg(),a.c));default:throw vbb(new hz('Unknown feature style: '+a.e));}} +function BMc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;Odd(c,'Brandes & Koepf node placement',1);a.a=b;a.c=KMc(b);d=BD(vNb(b,(Nyc(),zxc)),274);n=Ccb(DD(vNb(b,Axc)));a.d=d==(lrc(),irc)&&!n||d==frc;AMc(a,b);v=null;w=null;r=null;s=null;q=(Xj(4,Jie),new Skb(4));switch(BD(vNb(b,zxc),274).g){case 3:r=new ULc(b,a.c.d,(eMc(),cMc),(YLc(),WLc));q.c[q.c.length]=r;break;case 1:s=new ULc(b,a.c.d,(eMc(),dMc),(YLc(),WLc));q.c[q.c.length]=s;break;case 4:v=new ULc(b,a.c.d,(eMc(),cMc),(YLc(),XLc));q.c[q.c.length]=v;break;case 2:w=new ULc(b,a.c.d,(eMc(),dMc),(YLc(),XLc));q.c[q.c.length]=w;break;default:r=new ULc(b,a.c.d,(eMc(),cMc),(YLc(),WLc));s=new ULc(b,a.c.d,dMc,WLc);v=new ULc(b,a.c.d,cMc,XLc);w=new ULc(b,a.c.d,dMc,XLc);q.c[q.c.length]=v;q.c[q.c.length]=w;q.c[q.c.length]=r;q.c[q.c.length]=s;}e=new mMc(b,a.c);for(h=new olb(q);h.a<h.c.c.length;){f=BD(mlb(h),180);lMc(e,f,a.b);kMc(f)}m=new rMc(b,a.c);for(i=new olb(q);i.a<i.c.c.length;){f=BD(mlb(i),180);oMc(m,f)}if(c.n){for(j=new olb(q);j.a<j.c.c.length;){f=BD(mlb(j),180);Sdd(c,f+' size is '+SLc(f))}}l=null;if(a.d){k=yMc(a,q,a.c.d);xMc(b,k,c)&&(l=k)}if(!l){for(j=new olb(q);j.a<j.c.c.length;){f=BD(mlb(j),180);xMc(b,f,c)&&(!l||SLc(l)>SLc(f))&&(l=f)}}!l&&(l=(tCb(0,q.c.length),BD(q.c[0],180)));for(p=new olb(b.b);p.a<p.c.c.length;){o=BD(mlb(p),29);for(u=new olb(o.a);u.a<u.c.c.length;){t=BD(mlb(u),10);t.n.b=Edb(l.p[t.p])+Edb(l.d[t.p])}}if(c.n){Sdd(c,'Chosen node placement: '+l);Sdd(c,'Blocks: '+DMc(l));Sdd(c,'Classes: '+EMc(l,c));Sdd(c,'Marked edges: '+a.b)}for(g=new olb(q);g.a<g.c.c.length;){f=BD(mlb(g),180);f.g=null;f.b=null;f.a=null;f.d=null;f.j=null;f.i=null;f.p=null}IMc(a.c);a.b.a.$b();Qdd(c)} +function V1b(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F;g=new Psb;v=BD(vNb(c,(Nyc(),Lwc)),103);o=0;ye(g,(!b.a&&(b.a=new cUd(E2,b,10,11)),b.a));while(g.b!=0){j=BD(g.b==0?null:(sCb(g.b!=0),Nsb(g,g.a.a)),33);(PD(hkd(b,ywc))!==PD((tAc(),rAc))||PD(hkd(b,Jwc))===PD((mqc(),lqc))||PD(hkd(b,Jwc))===PD((mqc(),jqc))||Ccb(DD(hkd(b,Awc)))||PD(hkd(b,twc))!==PD((RXb(),QXb)))&&!Ccb(DD(hkd(j,xwc)))&&jkd(j,(wtc(),Zsc),meb(o++));q=!Ccb(DD(hkd(j,Jxc)));if(q){l=(!j.a&&(j.a=new cUd(E2,j,10,11)),j.a).i!=0;n=S1b(j);m=PD(hkd(j,axc))===PD((hbd(),ebd));F=!ikd(j,(Y9c(),o8c))||dfb(GD(hkd(j,o8c)),sne);t=null;if(F&&m&&(l||n)){t=P1b(j);yNb(t,Lwc,v);wNb(t,hyc)&&Wyc(new ezc(Edb(ED(vNb(t,hyc)))),t);if(BD(hkd(j,Fxc),174).gc()!=0){k=t;MAb(new YAb(null,(!j.c&&(j.c=new cUd(F2,j,9,9)),new Kub(j.c,16))),new k2b(k));L1b(j,t)}}w=c;A=BD(Ohb(a.a,Xod(j)),10);!!A&&(w=A.e);s=$1b(a,j,w);if(t){s.e=t;t.e=s;ye(g,(!j.a&&(j.a=new cUd(E2,j,10,11)),j.a))}}}o=0;Gsb(g,b,g.c.b,g.c);while(g.b!=0){f=BD(g.b==0?null:(sCb(g.b!=0),Nsb(g,g.a.a)),33);for(i=new Fyd((!f.b&&(f.b=new cUd(B2,f,12,3)),f.b));i.e!=i.i.gc();){h=BD(Dyd(i),79);N1b(h);(PD(hkd(b,ywc))!==PD((tAc(),rAc))||PD(hkd(b,Jwc))===PD((mqc(),lqc))||PD(hkd(b,Jwc))===PD((mqc(),jqc))||Ccb(DD(hkd(b,Awc)))||PD(hkd(b,twc))!==PD((RXb(),QXb)))&&jkd(h,(wtc(),Zsc),meb(o++));C=atd(BD(qud((!h.b&&(h.b=new y5d(z2,h,4,7)),h.b),0),82));D=atd(BD(qud((!h.c&&(h.c=new y5d(z2,h,5,8)),h.c),0),82));if(Ccb(DD(hkd(h,Jxc)))||Ccb(DD(hkd(C,Jxc)))||Ccb(DD(hkd(D,Jxc)))){continue}p=Qld(h)&&Ccb(DD(hkd(C,fxc)))&&Ccb(DD(hkd(h,gxc)));u=f;p||ntd(D,C)?(u=C):ntd(C,D)&&(u=D);w=c;A=BD(Ohb(a.a,u),10);!!A&&(w=A.e);r=X1b(a,h,u,w);yNb(r,(wtc(),xsc),R1b(a,h,b,c))}m=PD(hkd(f,axc))===PD((hbd(),ebd));if(m){for(e=new Fyd((!f.a&&(f.a=new cUd(E2,f,10,11)),f.a));e.e!=e.i.gc();){d=BD(Dyd(e),33);F=!ikd(d,(Y9c(),o8c))||dfb(GD(hkd(d,o8c)),sne);B=PD(hkd(d,axc))===PD(ebd);F&&B&&(Gsb(g,d,g.c.b,g.c),true)}}}} +function vA(a,b,c,d,e,f){var g,h,i,j,k,l,m,n,o,p,q,r;switch(b){case 71:h=d.q.getFullYear()-nje>=-1900?1:0;c>=4?Qfb(a,OC(GC(ZI,1),nie,2,6,[pje,qje])[h]):Qfb(a,OC(GC(ZI,1),nie,2,6,['BC','AD'])[h]);break;case 121:kA(a,c,d);break;case 77:jA(a,c,d);break;case 107:i=e.q.getHours();i==0?EA(a,24,c):EA(a,i,c);break;case 83:iA(a,c,e);break;case 69:k=d.q.getDay();c==5?Qfb(a,OC(GC(ZI,1),nie,2,6,['S','M','T','W','T','F','S'])[k]):c==4?Qfb(a,OC(GC(ZI,1),nie,2,6,[rje,sje,tje,uje,vje,wje,xje])[k]):Qfb(a,OC(GC(ZI,1),nie,2,6,['Sun','Mon','Tue','Wed','Thu','Fri','Sat'])[k]);break;case 97:e.q.getHours()>=12&&e.q.getHours()<24?Qfb(a,OC(GC(ZI,1),nie,2,6,['AM','PM'])[1]):Qfb(a,OC(GC(ZI,1),nie,2,6,['AM','PM'])[0]);break;case 104:l=e.q.getHours()%12;l==0?EA(a,12,c):EA(a,l,c);break;case 75:m=e.q.getHours()%12;EA(a,m,c);break;case 72:n=e.q.getHours();EA(a,n,c);break;case 99:o=d.q.getDay();c==5?Qfb(a,OC(GC(ZI,1),nie,2,6,['S','M','T','W','T','F','S'])[o]):c==4?Qfb(a,OC(GC(ZI,1),nie,2,6,[rje,sje,tje,uje,vje,wje,xje])[o]):c==3?Qfb(a,OC(GC(ZI,1),nie,2,6,['Sun','Mon','Tue','Wed','Thu','Fri','Sat'])[o]):EA(a,o,1);break;case 76:p=d.q.getMonth();c==5?Qfb(a,OC(GC(ZI,1),nie,2,6,['J','F','M','A','M','J','J','A','S','O','N','D'])[p]):c==4?Qfb(a,OC(GC(ZI,1),nie,2,6,[bje,cje,dje,eje,fje,gje,hje,ije,jje,kje,lje,mje])[p]):c==3?Qfb(a,OC(GC(ZI,1),nie,2,6,['Jan','Feb','Mar','Apr',fje,'Jun','Jul','Aug','Sep','Oct','Nov','Dec'])[p]):EA(a,p+1,c);break;case 81:q=d.q.getMonth()/3|0;c<4?Qfb(a,OC(GC(ZI,1),nie,2,6,['Q1','Q2','Q3','Q4'])[q]):Qfb(a,OC(GC(ZI,1),nie,2,6,['1st quarter','2nd quarter','3rd quarter','4th quarter'])[q]);break;case 100:r=d.q.getDate();EA(a,r,c);break;case 109:j=e.q.getMinutes();EA(a,j,c);break;case 115:g=e.q.getSeconds();EA(a,g,c);break;case 122:c<4?Qfb(a,f.c[0]):Qfb(a,f.c[1]);break;case 118:Qfb(a,f.b);break;case 90:c<3?Qfb(a,OA(f)):c==3?Qfb(a,NA(f)):Qfb(a,QA(f.a));break;default:return false;}return true} +function X1b(a,b,c,d){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H;N1b(b);i=BD(qud((!b.b&&(b.b=new y5d(z2,b,4,7)),b.b),0),82);k=BD(qud((!b.c&&(b.c=new y5d(z2,b,5,8)),b.c),0),82);h=atd(i);j=atd(k);g=(!b.a&&(b.a=new cUd(A2,b,6,6)),b.a).i==0?null:BD(qud((!b.a&&(b.a=new cUd(A2,b,6,6)),b.a),0),202);A=BD(Ohb(a.a,h),10);F=BD(Ohb(a.a,j),10);B=null;G=null;if(JD(i,186)){w=BD(Ohb(a.a,i),299);if(JD(w,11)){B=BD(w,11)}else if(JD(w,10)){A=BD(w,10);B=BD(Ikb(A.j,0),11)}}if(JD(k,186)){D=BD(Ohb(a.a,k),299);if(JD(D,11)){G=BD(D,11)}else if(JD(D,10)){F=BD(D,10);G=BD(Ikb(F.j,0),11)}}if(!A||!F){throw vbb(new z2c('The source or the target of edge '+b+' could not be found. '+'This usually happens when an edge connects a node laid out by ELK Layered to a node in '+'another level of hierarchy laid out by either another instance of ELK Layered or another '+'layout algorithm alltogether. The former can be solved by setting the hierarchyHandling '+'option to INCLUDE_CHILDREN.'))}p=new UZb;tNb(p,b);yNb(p,(wtc(),$sc),b);yNb(p,(Nyc(),jxc),null);n=BD(vNb(d,Ksc),21);A==F&&n.Fc((Orc(),Nrc));if(!B){v=(KAc(),IAc);C=null;if(!!g&&fcd(BD(vNb(A,Vxc),98))){C=new f7c(g.j,g.k);Bfd(C,Mld(b));Cfd(C,c);if(ntd(j,h)){v=HAc;P6c(C,A.n)}}B=$$b(A,C,v,d)}if(!G){v=(KAc(),HAc);H=null;if(!!g&&fcd(BD(vNb(F,Vxc),98))){H=new f7c(g.b,g.c);Bfd(H,Mld(b));Cfd(H,c)}G=$$b(F,H,v,Q_b(F))}QZb(p,B);RZb(p,G);(B.e.c.length>1||B.g.c.length>1||G.e.c.length>1||G.g.c.length>1)&&n.Fc((Orc(),Irc));for(m=new Fyd((!b.n&&(b.n=new cUd(D2,b,1,7)),b.n));m.e!=m.i.gc();){l=BD(Dyd(m),137);if(!Ccb(DD(hkd(l,Jxc)))&&!!l.a){q=Z1b(l);Ekb(p.b,q);switch(BD(vNb(q,Qwc),272).g){case 1:case 2:n.Fc((Orc(),Grc));break;case 0:n.Fc((Orc(),Erc));yNb(q,Qwc,(qad(),nad));}}}f=BD(vNb(d,Iwc),314);r=BD(vNb(d,Exc),315);e=f==(Rpc(),Opc)||r==(Vzc(),Rzc);if(!!g&&(!g.a&&(g.a=new xMd(y2,g,5)),g.a).i!=0&&e){s=ofd(g);o=new s7c;for(u=Jsb(s,0);u.b!=u.d.c;){t=BD(Xsb(u),8);Dsb(o,new g7c(t))}yNb(p,_sc,o)}return p} +function yZd(a){if(a.gb)return;a.gb=true;a.b=Lnd(a,0);Knd(a.b,18);Qnd(a.b,19);a.a=Lnd(a,1);Knd(a.a,1);Qnd(a.a,2);Qnd(a.a,3);Qnd(a.a,4);Qnd(a.a,5);a.o=Lnd(a,2);Knd(a.o,8);Knd(a.o,9);Qnd(a.o,10);Qnd(a.o,11);Qnd(a.o,12);Qnd(a.o,13);Qnd(a.o,14);Qnd(a.o,15);Qnd(a.o,16);Qnd(a.o,17);Qnd(a.o,18);Qnd(a.o,19);Qnd(a.o,20);Qnd(a.o,21);Qnd(a.o,22);Qnd(a.o,23);Pnd(a.o);Pnd(a.o);Pnd(a.o);Pnd(a.o);Pnd(a.o);Pnd(a.o);Pnd(a.o);Pnd(a.o);Pnd(a.o);Pnd(a.o);a.p=Lnd(a,3);Knd(a.p,2);Knd(a.p,3);Knd(a.p,4);Knd(a.p,5);Qnd(a.p,6);Qnd(a.p,7);Pnd(a.p);Pnd(a.p);a.q=Lnd(a,4);Knd(a.q,8);a.v=Lnd(a,5);Qnd(a.v,9);Pnd(a.v);Pnd(a.v);Pnd(a.v);a.w=Lnd(a,6);Knd(a.w,2);Knd(a.w,3);Knd(a.w,4);Qnd(a.w,5);a.B=Lnd(a,7);Qnd(a.B,1);Pnd(a.B);Pnd(a.B);Pnd(a.B);a.Q=Lnd(a,8);Qnd(a.Q,0);Pnd(a.Q);a.R=Lnd(a,9);Knd(a.R,1);a.S=Lnd(a,10);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);Pnd(a.S);a.T=Lnd(a,11);Qnd(a.T,10);Qnd(a.T,11);Qnd(a.T,12);Qnd(a.T,13);Qnd(a.T,14);Pnd(a.T);Pnd(a.T);a.U=Lnd(a,12);Knd(a.U,2);Knd(a.U,3);Qnd(a.U,4);Qnd(a.U,5);Qnd(a.U,6);Qnd(a.U,7);Pnd(a.U);a.V=Lnd(a,13);Qnd(a.V,10);a.W=Lnd(a,14);Knd(a.W,18);Knd(a.W,19);Knd(a.W,20);Qnd(a.W,21);Qnd(a.W,22);Qnd(a.W,23);a.bb=Lnd(a,15);Knd(a.bb,10);Knd(a.bb,11);Knd(a.bb,12);Knd(a.bb,13);Knd(a.bb,14);Knd(a.bb,15);Knd(a.bb,16);Qnd(a.bb,17);Pnd(a.bb);Pnd(a.bb);a.eb=Lnd(a,16);Knd(a.eb,2);Knd(a.eb,3);Knd(a.eb,4);Knd(a.eb,5);Knd(a.eb,6);Knd(a.eb,7);Qnd(a.eb,8);Qnd(a.eb,9);a.ab=Lnd(a,17);Knd(a.ab,0);Knd(a.ab,1);a.H=Lnd(a,18);Qnd(a.H,0);Qnd(a.H,1);Qnd(a.H,2);Qnd(a.H,3);Qnd(a.H,4);Qnd(a.H,5);Pnd(a.H);a.db=Lnd(a,19);Qnd(a.db,2);a.c=Mnd(a,20);a.d=Mnd(a,21);a.e=Mnd(a,22);a.f=Mnd(a,23);a.i=Mnd(a,24);a.g=Mnd(a,25);a.j=Mnd(a,26);a.k=Mnd(a,27);a.n=Mnd(a,28);a.r=Mnd(a,29);a.s=Mnd(a,30);a.t=Mnd(a,31);a.u=Mnd(a,32);a.fb=Mnd(a,33);a.A=Mnd(a,34);a.C=Mnd(a,35);a.D=Mnd(a,36);a.F=Mnd(a,37);a.G=Mnd(a,38);a.I=Mnd(a,39);a.J=Mnd(a,40);a.L=Mnd(a,41);a.M=Mnd(a,42);a.N=Mnd(a,43);a.O=Mnd(a,44);a.P=Mnd(a,45);a.X=Mnd(a,46);a.Y=Mnd(a,47);a.Z=Mnd(a,48);a.$=Mnd(a,49);a._=Mnd(a,50);a.cb=Mnd(a,51);a.K=Mnd(a,52)} +function Y9c(){Y9c=ccb;var a,b;o8c=new Lsd(sse);F9c=new Lsd(tse);q8c=(F7c(),z7c);p8c=new Nsd($pe,q8c);new Tfd;r8c=new Nsd(_le,null);s8c=new Lsd(use);x8c=(i8c(),qqb(h8c,OC(GC(r1,1),Kie,291,0,[d8c])));w8c=new Nsd(lqe,x8c);y8c=new Nsd(Zpe,(Bcb(),false));A8c=(ead(),cad);z8c=new Nsd(cqe,A8c);F8c=(Aad(),zad);E8c=new Nsd(ype,F8c);I8c=new Nsd(Jre,false);K8c=(hbd(),fbd);J8c=new Nsd(tpe,K8c);g9c=new q0b(12);f9c=new Nsd(ame,g9c);O8c=new Nsd(Ame,false);P8c=new Nsd(xqe,false);e9c=new Nsd(Dme,false);u9c=(dcd(),ccd);t9c=new Nsd(Bme,u9c);C9c=new Lsd(uqe);D9c=new Lsd(vme);E9c=new Lsd(yme);H9c=new Lsd(zme);R8c=new s7c;Q8c=new Nsd(mqe,R8c);v8c=new Nsd(pqe,false);L8c=new Nsd(qqe,false);new Lsd(vse);T8c=new H_b;S8c=new Nsd(vqe,T8c);d9c=new Nsd(Xpe,false);new Tfd;G9c=new Nsd(wse,1);new Nsd(xse,true);meb(0);new Nsd(yse,meb(100));new Nsd(zse,false);meb(0);new Nsd(Ase,meb(4000));meb(0);new Nsd(Bse,meb(400));new Nsd(Cse,false);new Nsd(Dse,false);new Nsd(Ese,true);new Nsd(Fse,false);u8c=(Ded(),Ced);t8c=new Nsd(rse,u8c);I9c=new Nsd(Lpe,10);J9c=new Nsd(Mpe,10);K9c=new Nsd(Zle,20);L9c=new Nsd(Npe,10);M9c=new Nsd(xme,2);N9c=new Nsd(Ope,10);P9c=new Nsd(Ppe,0);Q9c=new Nsd(Spe,5);R9c=new Nsd(Qpe,1);S9c=new Nsd(Rpe,1);T9c=new Nsd(wme,20);U9c=new Nsd(Tpe,10);X9c=new Nsd(Upe,10);O9c=new Lsd(Vpe);W9c=new I_b;V9c=new Nsd(wqe,W9c);j9c=new Lsd(tqe);i9c=false;h9c=new Nsd(sqe,i9c);V8c=new q0b(5);U8c=new Nsd(dqe,V8c);X8c=(Hbd(),b=BD(gdb(B1),9),new xqb(b,BD(_Bb(b,b.length),9),0));W8c=new Nsd(Gme,X8c);m9c=(Tbd(),Qbd);l9c=new Nsd(gqe,m9c);o9c=new Lsd(hqe);p9c=new Lsd(iqe);q9c=new Lsd(jqe);n9c=new Lsd(kqe);Z8c=(a=BD(gdb(I1),9),new xqb(a,BD(_Bb(a,a.length),9),0));Y8c=new Nsd(Fme,Z8c);c9c=pqb((Idd(),Bdd));b9c=new Nsd(Eme,c9c);a9c=new f7c(0,0);_8c=new Nsd(Tme,a9c);$8c=new Nsd(bqe,false);D8c=(qad(),nad);C8c=new Nsd(nqe,D8c);B8c=new Nsd(Cme,false);new Lsd(Gse);meb(1);new Nsd(Hse,null);r9c=new Lsd(rqe);v9c=new Lsd(oqe);B9c=(Ucd(),Scd);A9c=new Nsd(Ype,B9c);s9c=new Lsd(Wpe);y9c=(rcd(),pqb(pcd));x9c=new Nsd(Hme,y9c);w9c=new Nsd(eqe,false);z9c=new Nsd(fqe,true);M8c=new Nsd(_pe,false);N8c=new Nsd(aqe,false);G8c=new Nsd($le,1);H8c=(Mad(),Kad);new Nsd(Ise,H8c);k9c=true} +function wtc(){wtc=ccb;var a,b;$sc=new Lsd(Ime);xsc=new Lsd('coordinateOrigin');itc=new Lsd('processors');wsc=new Msd('compoundNode',(Bcb(),false));Nsc=new Msd('insideConnections',false);_sc=new Lsd('originalBendpoints');atc=new Lsd('originalDummyNodePosition');btc=new Lsd('originalLabelEdge');ktc=new Lsd('representedLabels');Csc=new Lsd('endLabels');Dsc=new Lsd('endLabel.origin');Ssc=new Msd('labelSide',(rbd(),qbd));Ysc=new Msd('maxEdgeThickness',0);ltc=new Msd('reversed',false);jtc=new Lsd(Jme);Vsc=new Msd('longEdgeSource',null);Wsc=new Msd('longEdgeTarget',null);Usc=new Msd('longEdgeHasLabelDummies',false);Tsc=new Msd('longEdgeBeforeLabelDummy',false);Bsc=new Msd('edgeConstraint',(Gqc(),Eqc));Psc=new Lsd('inLayerLayoutUnit');Osc=new Msd('inLayerConstraint',(esc(),csc));Qsc=new Msd('inLayerSuccessorConstraint',new Rkb);Rsc=new Msd('inLayerSuccessorConstraintBetweenNonDummies',false);gtc=new Lsd('portDummy');ysc=new Msd('crossingHint',meb(0));Ksc=new Msd('graphProperties',(b=BD(gdb(PW),9),new xqb(b,BD(_Bb(b,b.length),9),0)));Hsc=new Msd('externalPortSide',(Ucd(),Scd));Isc=new Msd('externalPortSize',new d7c);Fsc=new Lsd('externalPortReplacedDummies');Gsc=new Lsd('externalPortReplacedDummy');Esc=new Msd('externalPortConnections',(a=BD(gdb(F1),9),new xqb(a,BD(_Bb(a,a.length),9),0)));htc=new Msd(tle,0);ssc=new Lsd('barycenterAssociates');vtc=new Lsd('TopSideComments');tsc=new Lsd('BottomSideComments');vsc=new Lsd('CommentConnectionPort');Msc=new Msd('inputCollect',false);etc=new Msd('outputCollect',false);Asc=new Msd('cyclic',false);zsc=new Lsd('crossHierarchyMap');utc=new Lsd('targetOffset');new Msd('splineLabelSize',new d7c);otc=new Lsd('spacings');ftc=new Msd('partitionConstraint',false);usc=new Lsd('breakingPoint.info');stc=new Lsd('splines.survivingEdge');rtc=new Lsd('splines.route.start');ptc=new Lsd('splines.edgeChain');dtc=new Lsd('originalPortConstraints');ntc=new Lsd('selfLoopHolder');qtc=new Lsd('splines.nsPortY');Zsc=new Lsd('modelOrder');Xsc=new Lsd('longEdgeTargetNode');Jsc=new Msd(Xne,false);mtc=new Msd(Xne,false);Lsc=new Lsd('layerConstraints.hiddenNodes');ctc=new Lsd('layerConstraints.opposidePort');ttc=new Lsd('targetNode.modelOrder')} +function jwc(){jwc=ccb;puc=(xqc(),vqc);ouc=new Nsd(Yne,puc);Guc=new Nsd(Zne,(Bcb(),false));Muc=(msc(),ksc);Luc=new Nsd($ne,Muc);cvc=new Nsd(_ne,false);dvc=new Nsd(aoe,true);Itc=new Nsd(boe,false);xvc=(BAc(),zAc);wvc=new Nsd(coe,xvc);meb(1);Fvc=new Nsd(doe,meb(7));Gvc=new Nsd(eoe,false);Huc=new Nsd(foe,false);nuc=(mqc(),iqc);muc=new Nsd(goe,nuc);bvc=(lzc(),jzc);avc=new Nsd(hoe,bvc);Tuc=(Ctc(),Btc);Suc=new Nsd(ioe,Tuc);meb(-1);Ruc=new Nsd(joe,meb(-1));meb(-1);Uuc=new Nsd(koe,meb(-1));meb(-1);Vuc=new Nsd(loe,meb(4));meb(-1);Xuc=new Nsd(moe,meb(2));_uc=(kAc(),iAc);$uc=new Nsd(noe,_uc);meb(0);Zuc=new Nsd(ooe,meb(0));Puc=new Nsd(poe,meb(Ohe));luc=(Rpc(),Ppc);kuc=new Nsd(qoe,luc);Xtc=new Nsd(roe,false);euc=new Nsd(soe,0.1);iuc=new Nsd(toe,false);meb(-1);guc=new Nsd(uoe,meb(-1));meb(-1);huc=new Nsd(voe,meb(-1));meb(0);Ytc=new Nsd(woe,meb(40));cuc=(Xrc(),Wrc);buc=new Nsd(xoe,cuc);$tc=Urc;Ztc=new Nsd(yoe,$tc);vvc=(Vzc(),Qzc);uvc=new Nsd(zoe,vvc);kvc=new Lsd(Aoe);fvc=(_qc(),Zqc);evc=new Nsd(Boe,fvc);ivc=(lrc(),irc);hvc=new Nsd(Coe,ivc);new Tfd;nvc=new Nsd(Doe,0.3);pvc=new Lsd(Eoe);rvc=(Izc(),Gzc);qvc=new Nsd(Foe,rvc);xuc=(TAc(),RAc);wuc=new Nsd(Goe,xuc);zuc=(_Ac(),$Ac);yuc=new Nsd(Hoe,zuc);Buc=(tBc(),sBc);Auc=new Nsd(Ioe,Buc);Duc=new Nsd(Joe,0.2);uuc=new Nsd(Koe,2);Bvc=new Nsd(Loe,null);Dvc=new Nsd(Moe,10);Cvc=new Nsd(Noe,10);Evc=new Nsd(Ooe,20);meb(0);yvc=new Nsd(Poe,meb(0));meb(0);zvc=new Nsd(Qoe,meb(0));meb(0);Avc=new Nsd(Roe,meb(0));Jtc=new Nsd(Soe,false);Ntc=(yrc(),wrc);Mtc=new Nsd(Toe,Ntc);Ltc=(Ipc(),Hpc);Ktc=new Nsd(Uoe,Ltc);Juc=new Nsd(Voe,false);meb(0);Iuc=new Nsd(Woe,meb(16));meb(0);Kuc=new Nsd(Xoe,meb(5));bwc=(LBc(),JBc);awc=new Nsd(Yoe,bwc);Hvc=new Nsd(Zoe,10);Kvc=new Nsd($oe,1);Tvc=(bqc(),aqc);Svc=new Nsd(_oe,Tvc);Nvc=new Lsd(ape);Qvc=meb(1);meb(0);Pvc=new Nsd(bpe,Qvc);gwc=(CBc(),zBc);fwc=new Nsd(cpe,gwc);cwc=new Lsd(dpe);Yvc=new Nsd(epe,true);Wvc=new Nsd(fpe,2);$vc=new Nsd(gpe,true);tuc=(Sqc(),Qqc);suc=new Nsd(hpe,tuc);ruc=(Apc(),wpc);quc=new Nsd(ipe,ruc);Wtc=(tAc(),rAc);Vtc=new Nsd(jpe,Wtc);Utc=new Nsd(kpe,false);Ptc=(RXb(),QXb);Otc=new Nsd(lpe,Ptc);Ttc=(xzc(),uzc);Stc=new Nsd(mpe,Ttc);Qtc=new Nsd(npe,0);Rtc=new Nsd(ope,0);Ouc=kqc;Nuc=Opc;Wuc=izc;Yuc=izc;Quc=fzc;fuc=(hbd(),ebd);juc=Ppc;duc=Ppc;_tc=Ppc;auc=ebd;lvc=Tzc;mvc=Qzc;gvc=Qzc;jvc=Qzc;ovc=Szc;tvc=Tzc;svc=Tzc;Cuc=(Aad(),yad);Euc=yad;Fuc=sBc;vuc=xad;Ivc=KBc;Jvc=IBc;Lvc=KBc;Mvc=IBc;Uvc=KBc;Vvc=IBc;Ovc=_pc;Rvc=aqc;hwc=KBc;iwc=IBc;dwc=KBc;ewc=IBc;Zvc=IBc;Xvc=IBc;_vc=IBc} +function S8b(){S8b=ccb;Y7b=new T8b('DIRECTION_PREPROCESSOR',0);V7b=new T8b('COMMENT_PREPROCESSOR',1);Z7b=new T8b('EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER',2);n8b=new T8b('INTERACTIVE_EXTERNAL_PORT_POSITIONER',3);G8b=new T8b('PARTITION_PREPROCESSOR',4);r8b=new T8b('LABEL_DUMMY_INSERTER',5);M8b=new T8b('SELF_LOOP_PREPROCESSOR',6);w8b=new T8b('LAYER_CONSTRAINT_PREPROCESSOR',7);E8b=new T8b('PARTITION_MIDPROCESSOR',8);i8b=new T8b('HIGH_DEGREE_NODE_LAYER_PROCESSOR',9);A8b=new T8b('NODE_PROMOTION',10);v8b=new T8b('LAYER_CONSTRAINT_POSTPROCESSOR',11);F8b=new T8b('PARTITION_POSTPROCESSOR',12);e8b=new T8b('HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR',13);O8b=new T8b('SEMI_INTERACTIVE_CROSSMIN_PROCESSOR',14);P7b=new T8b('BREAKING_POINT_INSERTER',15);z8b=new T8b('LONG_EDGE_SPLITTER',16);I8b=new T8b('PORT_SIDE_PROCESSOR',17);o8b=new T8b('INVERTED_PORT_PROCESSOR',18);H8b=new T8b('PORT_LIST_SORTER',19);Q8b=new T8b('SORT_BY_INPUT_ORDER_OF_MODEL',20);C8b=new T8b('NORTH_SOUTH_PORT_PREPROCESSOR',21);Q7b=new T8b('BREAKING_POINT_PROCESSOR',22);D8b=new T8b(Bne,23);R8b=new T8b(Cne,24);K8b=new T8b('SELF_LOOP_PORT_RESTORER',25);P8b=new T8b('SINGLE_EDGE_GRAPH_WRAPPER',26);p8b=new T8b('IN_LAYER_CONSTRAINT_PROCESSOR',27);b8b=new T8b('END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR',28);q8b=new T8b('LABEL_AND_NODE_SIZE_PROCESSOR',29);m8b=new T8b('INNERMOST_NODE_MARGIN_CALCULATOR',30);N8b=new T8b('SELF_LOOP_ROUTER',31);T7b=new T8b('COMMENT_NODE_MARGIN_CALCULATOR',32);_7b=new T8b('END_LABEL_PREPROCESSOR',33);t8b=new T8b('LABEL_DUMMY_SWITCHER',34);S7b=new T8b('CENTER_LABEL_MANAGEMENT_PROCESSOR',35);u8b=new T8b('LABEL_SIDE_SELECTOR',36);k8b=new T8b('HYPEREDGE_DUMMY_MERGER',37);f8b=new T8b('HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR',38);x8b=new T8b('LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR',39);h8b=new T8b('HIERARCHICAL_PORT_POSITION_PROCESSOR',40);W7b=new T8b('CONSTRAINTS_POSTPROCESSOR',41);U7b=new T8b('COMMENT_POSTPROCESSOR',42);l8b=new T8b('HYPERNODE_PROCESSOR',43);g8b=new T8b('HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER',44);y8b=new T8b('LONG_EDGE_JOINER',45);L8b=new T8b('SELF_LOOP_POSTPROCESSOR',46);R7b=new T8b('BREAKING_POINT_REMOVER',47);B8b=new T8b('NORTH_SOUTH_PORT_POSTPROCESSOR',48);j8b=new T8b('HORIZONTAL_COMPACTOR',49);s8b=new T8b('LABEL_DUMMY_REMOVER',50);c8b=new T8b('FINAL_SPLINE_BENDPOINTS_CALCULATOR',51);a8b=new T8b('END_LABEL_SORTER',52);J8b=new T8b('REVERSED_EDGE_RESTORER',53);$7b=new T8b('END_LABEL_POSTPROCESSOR',54);d8b=new T8b('HIERARCHICAL_NODE_RESIZER',55);X7b=new T8b('DIRECTION_POSTPROCESSOR',56)} +function KIc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,ab,bb,cb,db,eb,fb,gb,hb,ib,jb,kb,lb;cb=0;for(H=b,K=0,N=H.length;K<N;++K){F=H[K];for(V=new olb(F.j);V.a<V.c.c.length;){U=BD(mlb(V),11);X=0;for(h=new olb(U.g);h.a<h.c.c.length;){g=BD(mlb(h),17);F.c!=g.d.i.c&&++X}X>0&&(a.a[U.p]=cb++)}}hb=0;for(I=c,L=0,O=I.length;L<O;++L){F=I[L];P=0;for(V=new olb(F.j);V.a<V.c.c.length;){U=BD(mlb(V),11);if(U.j==(Ucd(),Acd)){for(h=new olb(U.e);h.a<h.c.c.length;){g=BD(mlb(h),17);if(F.c!=g.c.i.c){++P;break}}}else{break}}R=0;Y=new Bib(F.j,F.j.c.length);while(Y.b>0){U=(sCb(Y.b>0),BD(Y.a.Xb(Y.c=--Y.b),11));X=0;for(h=new olb(U.e);h.a<h.c.c.length;){g=BD(mlb(h),17);F.c!=g.c.i.c&&++X}if(X>0){if(U.j==(Ucd(),Acd)){a.a[U.p]=hb;++hb}else{a.a[U.p]=hb+P+R;++R}}}hb+=R}W=new Lqb;o=new zsb;for(G=b,J=0,M=G.length;J<M;++J){F=G[J];for(fb=new olb(F.j);fb.a<fb.c.c.length;){eb=BD(mlb(fb),11);for(h=new olb(eb.g);h.a<h.c.c.length;){g=BD(mlb(h),17);jb=g.d;if(F.c!=jb.i.c){db=BD(Wd(irb(W.f,eb)),467);ib=BD(Wd(irb(W.f,jb)),467);if(!db&&!ib){n=new NIc;o.a.zc(n,o);Ekb(n.a,g);Ekb(n.d,eb);jrb(W.f,eb,n);Ekb(n.d,jb);jrb(W.f,jb,n)}else if(!db){Ekb(ib.a,g);Ekb(ib.d,eb);jrb(W.f,eb,ib)}else if(!ib){Ekb(db.a,g);Ekb(db.d,jb);jrb(W.f,jb,db)}else if(db==ib){Ekb(db.a,g)}else{Ekb(db.a,g);for(T=new olb(ib.d);T.a<T.c.c.length;){S=BD(mlb(T),11);jrb(W.f,S,db)}Gkb(db.a,ib.a);Gkb(db.d,ib.d);o.a.Bc(ib)!=null}}}}}p=BD(Ee(o,KC(oY,{3:1,4:1,5:1,1946:1},467,o.a.gc(),0,1)),1946);D=b[0].c;bb=c[0].c;for(k=p,l=0,m=k.length;l<m;++l){j=k[l];j.e=cb;j.f=hb;for(V=new olb(j.d);V.a<V.c.c.length;){U=BD(mlb(V),11);Z=a.a[U.p];if(U.i.c==D){Z<j.e&&(j.e=Z);Z>j.b&&(j.b=Z)}else if(U.i.c==bb){Z<j.f&&(j.f=Z);Z>j.c&&(j.c=Z)}}}Klb(p,0,p.length,null);gb=KC(WD,oje,25,p.length,15,1);d=KC(WD,oje,25,hb+1,15,1);for(r=0;r<p.length;r++){gb[r]=p[r].f;d[gb[r]]=1}f=0;for(s=0;s<d.length;s++){d[s]==1?(d[s]=f):--f}$=0;for(t=0;t<gb.length;t++){gb[t]+=d[gb[t]];$=$wnd.Math.max($,gb[t]+1)}i=1;while(i<$){i*=2}lb=2*i-1;i-=1;kb=KC(WD,oje,25,lb,15,1);e=0;for(B=0;B<gb.length;B++){A=gb[B]+i;++kb[A];while(A>0){A%2>0&&(e+=kb[A+1]);A=(A-1)/2|0;++kb[A]}}C=KC(nY,Uhe,362,p.length*2,0,1);for(u=0;u<p.length;u++){C[2*u]=new QIc(p[u],p[u].e,p[u].b,(UIc(),TIc));C[2*u+1]=new QIc(p[u],p[u].b,p[u].e,SIc)}Klb(C,0,C.length,null);Q=0;for(v=0;v<C.length;v++){switch(C[v].d.g){case 0:++Q;break;case 1:--Q;e+=Q;}}ab=KC(nY,Uhe,362,p.length*2,0,1);for(w=0;w<p.length;w++){ab[2*w]=new QIc(p[w],p[w].f,p[w].c,(UIc(),TIc));ab[2*w+1]=new QIc(p[w],p[w].c,p[w].f,SIc)}Klb(ab,0,ab.length,null);Q=0;for(q=0;q<ab.length;q++){switch(ab[q].d.g){case 0:++Q;break;case 1:--Q;e+=Q;}}return e} +function wfe(){wfe=ccb;ffe=new xfe(7);hfe=(++vfe,new ige(8,94));++vfe;new ige(8,64);ife=(++vfe,new ige(8,36));ofe=(++vfe,new ige(8,65));pfe=(++vfe,new ige(8,122));qfe=(++vfe,new ige(8,90));tfe=(++vfe,new ige(8,98));mfe=(++vfe,new ige(8,66));rfe=(++vfe,new ige(8,60));ufe=(++vfe,new ige(8,62));efe=new xfe(11);cfe=(++vfe,new $fe(4));Ufe(cfe,48,57);sfe=(++vfe,new $fe(4));Ufe(sfe,48,57);Ufe(sfe,65,90);Ufe(sfe,95,95);Ufe(sfe,97,122);nfe=(++vfe,new $fe(4));Ufe(nfe,9,9);Ufe(nfe,10,10);Ufe(nfe,12,12);Ufe(nfe,13,13);Ufe(nfe,32,32);jfe=_fe(cfe);lfe=_fe(sfe);kfe=_fe(nfe);Zee=new Lqb;$ee=new Lqb;_ee=OC(GC(ZI,1),nie,2,6,['Cn','Lu','Ll','Lt','Lm','Lo','Mn','Me','Mc','Nd','Nl','No','Zs','Zl','Zp','Cc','Cf',null,'Co','Cs','Pd','Ps','Pe','Pc','Po','Sm','Sc','Sk','So','Pi','Pf','L','M','N','Z','C','P','S']);Yee=OC(GC(ZI,1),nie,2,6,['Basic Latin','Latin-1 Supplement','Latin Extended-A','Latin Extended-B','IPA Extensions','Spacing Modifier Letters','Combining Diacritical Marks','Greek','Cyrillic','Armenian','Hebrew','Arabic','Syriac','Thaana','Devanagari','Bengali','Gurmukhi','Gujarati','Oriya','Tamil','Telugu','Kannada','Malayalam','Sinhala','Thai','Lao','Tibetan','Myanmar','Georgian','Hangul Jamo','Ethiopic','Cherokee','Unified Canadian Aboriginal Syllabics','Ogham','Runic','Khmer','Mongolian','Latin Extended Additional','Greek Extended','General Punctuation','Superscripts and Subscripts','Currency Symbols','Combining Marks for Symbols','Letterlike Symbols','Number Forms','Arrows','Mathematical Operators','Miscellaneous Technical','Control Pictures','Optical Character Recognition','Enclosed Alphanumerics','Box Drawing','Block Elements','Geometric Shapes','Miscellaneous Symbols','Dingbats','Braille Patterns','CJK Radicals Supplement','Kangxi Radicals','Ideographic Description Characters','CJK Symbols and Punctuation','Hiragana','Katakana','Bopomofo','Hangul Compatibility Jamo','Kanbun','Bopomofo Extended','Enclosed CJK Letters and Months','CJK Compatibility','CJK Unified Ideographs Extension A','CJK Unified Ideographs','Yi Syllables','Yi Radicals','Hangul Syllables',uxe,'CJK Compatibility Ideographs','Alphabetic Presentation Forms','Arabic Presentation Forms-A','Combining Half Marks','CJK Compatibility Forms','Small Form Variants','Arabic Presentation Forms-B','Specials','Halfwidth and Fullwidth Forms','Old Italic','Gothic','Deseret','Byzantine Musical Symbols','Musical Symbols','Mathematical Alphanumeric Symbols','CJK Unified Ideographs Extension B','CJK Compatibility Ideographs Supplement','Tags']);afe=OC(GC(WD,1),oje,25,15,[66304,66351,66352,66383,66560,66639,118784,119039,119040,119295,119808,120831,131072,173782,194560,195103,917504,917631])} +function qJb(){qJb=ccb;nJb=new tJb('OUT_T_L',0,(NHb(),LHb),(EIb(),BIb),(gHb(),dHb),dHb,OC(GC(LK,1),Uhe,21,0,[qqb((Hbd(),Dbd),OC(GC(B1,1),Kie,93,0,[Gbd,zbd]))]));mJb=new tJb('OUT_T_C',1,KHb,BIb,dHb,eHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Gbd,ybd])),qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Gbd,ybd,Abd]))]));oJb=new tJb('OUT_T_R',2,MHb,BIb,dHb,fHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Gbd,Bbd]))]));eJb=new tJb('OUT_B_L',3,LHb,DIb,fHb,dHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Ebd,zbd]))]));dJb=new tJb('OUT_B_C',4,KHb,DIb,fHb,eHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Ebd,ybd])),qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Ebd,ybd,Abd]))]));fJb=new tJb('OUT_B_R',5,MHb,DIb,fHb,fHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Ebd,Bbd]))]));iJb=new tJb('OUT_L_T',6,MHb,DIb,dHb,dHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[zbd,Gbd,Abd]))]));hJb=new tJb('OUT_L_C',7,MHb,CIb,eHb,dHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[zbd,Fbd])),qqb(Dbd,OC(GC(B1,1),Kie,93,0,[zbd,Fbd,Abd]))]));gJb=new tJb('OUT_L_B',8,MHb,BIb,fHb,dHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[zbd,Ebd,Abd]))]));lJb=new tJb('OUT_R_T',9,LHb,DIb,dHb,fHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Bbd,Gbd,Abd]))]));kJb=new tJb('OUT_R_C',10,LHb,CIb,eHb,fHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Bbd,Fbd])),qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Bbd,Fbd,Abd]))]));jJb=new tJb('OUT_R_B',11,LHb,BIb,fHb,fHb,OC(GC(LK,1),Uhe,21,0,[qqb(Dbd,OC(GC(B1,1),Kie,93,0,[Bbd,Ebd,Abd]))]));bJb=new tJb('IN_T_L',12,LHb,DIb,dHb,dHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Gbd,zbd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Gbd,zbd,Abd]))]));aJb=new tJb('IN_T_C',13,KHb,DIb,dHb,eHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Gbd,ybd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Gbd,ybd,Abd]))]));cJb=new tJb('IN_T_R',14,MHb,DIb,dHb,fHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Gbd,Bbd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Gbd,Bbd,Abd]))]));$Ib=new tJb('IN_C_L',15,LHb,CIb,eHb,dHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Fbd,zbd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Fbd,zbd,Abd]))]));ZIb=new tJb('IN_C_C',16,KHb,CIb,eHb,eHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Fbd,ybd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Fbd,ybd,Abd]))]));_Ib=new tJb('IN_C_R',17,MHb,CIb,eHb,fHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Fbd,Bbd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Fbd,Bbd,Abd]))]));XIb=new tJb('IN_B_L',18,LHb,BIb,fHb,dHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Ebd,zbd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Ebd,zbd,Abd]))]));WIb=new tJb('IN_B_C',19,KHb,BIb,fHb,eHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Ebd,ybd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Ebd,ybd,Abd]))]));YIb=new tJb('IN_B_R',20,MHb,BIb,fHb,fHb,OC(GC(LK,1),Uhe,21,0,[qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Ebd,Bbd])),qqb(Cbd,OC(GC(B1,1),Kie,93,0,[Ebd,Bbd,Abd]))]));pJb=new tJb(ole,21,null,null,null,null,OC(GC(LK,1),Uhe,21,0,[]))} +function jGd(){jGd=ccb;PFd=(NFd(),MFd).b;BD(qud(ZKd(MFd.b),0),34);BD(qud(ZKd(MFd.b),1),18);OFd=MFd.a;BD(qud(ZKd(MFd.a),0),34);BD(qud(ZKd(MFd.a),1),18);BD(qud(ZKd(MFd.a),2),18);BD(qud(ZKd(MFd.a),3),18);BD(qud(ZKd(MFd.a),4),18);QFd=MFd.o;BD(qud(ZKd(MFd.o),0),34);BD(qud(ZKd(MFd.o),1),34);SFd=BD(qud(ZKd(MFd.o),2),18);BD(qud(ZKd(MFd.o),3),18);BD(qud(ZKd(MFd.o),4),18);BD(qud(ZKd(MFd.o),5),18);BD(qud(ZKd(MFd.o),6),18);BD(qud(ZKd(MFd.o),7),18);BD(qud(ZKd(MFd.o),8),18);BD(qud(ZKd(MFd.o),9),18);BD(qud(ZKd(MFd.o),10),18);BD(qud(ZKd(MFd.o),11),18);BD(qud(ZKd(MFd.o),12),18);BD(qud(ZKd(MFd.o),13),18);BD(qud(ZKd(MFd.o),14),18);BD(qud(ZKd(MFd.o),15),18);BD(qud(WKd(MFd.o),0),59);BD(qud(WKd(MFd.o),1),59);BD(qud(WKd(MFd.o),2),59);BD(qud(WKd(MFd.o),3),59);BD(qud(WKd(MFd.o),4),59);BD(qud(WKd(MFd.o),5),59);BD(qud(WKd(MFd.o),6),59);BD(qud(WKd(MFd.o),7),59);BD(qud(WKd(MFd.o),8),59);BD(qud(WKd(MFd.o),9),59);RFd=MFd.p;BD(qud(ZKd(MFd.p),0),34);BD(qud(ZKd(MFd.p),1),34);BD(qud(ZKd(MFd.p),2),34);BD(qud(ZKd(MFd.p),3),34);BD(qud(ZKd(MFd.p),4),18);BD(qud(ZKd(MFd.p),5),18);BD(qud(WKd(MFd.p),0),59);BD(qud(WKd(MFd.p),1),59);TFd=MFd.q;BD(qud(ZKd(MFd.q),0),34);UFd=MFd.v;BD(qud(ZKd(MFd.v),0),18);BD(qud(WKd(MFd.v),0),59);BD(qud(WKd(MFd.v),1),59);BD(qud(WKd(MFd.v),2),59);VFd=MFd.w;BD(qud(ZKd(MFd.w),0),34);BD(qud(ZKd(MFd.w),1),34);BD(qud(ZKd(MFd.w),2),34);BD(qud(ZKd(MFd.w),3),18);WFd=MFd.B;BD(qud(ZKd(MFd.B),0),18);BD(qud(WKd(MFd.B),0),59);BD(qud(WKd(MFd.B),1),59);BD(qud(WKd(MFd.B),2),59);ZFd=MFd.Q;BD(qud(ZKd(MFd.Q),0),18);BD(qud(WKd(MFd.Q),0),59);$Fd=MFd.R;BD(qud(ZKd(MFd.R),0),34);_Fd=MFd.S;BD(qud(WKd(MFd.S),0),59);BD(qud(WKd(MFd.S),1),59);BD(qud(WKd(MFd.S),2),59);BD(qud(WKd(MFd.S),3),59);BD(qud(WKd(MFd.S),4),59);BD(qud(WKd(MFd.S),5),59);BD(qud(WKd(MFd.S),6),59);BD(qud(WKd(MFd.S),7),59);BD(qud(WKd(MFd.S),8),59);BD(qud(WKd(MFd.S),9),59);BD(qud(WKd(MFd.S),10),59);BD(qud(WKd(MFd.S),11),59);BD(qud(WKd(MFd.S),12),59);BD(qud(WKd(MFd.S),13),59);BD(qud(WKd(MFd.S),14),59);aGd=MFd.T;BD(qud(ZKd(MFd.T),0),18);BD(qud(ZKd(MFd.T),2),18);bGd=BD(qud(ZKd(MFd.T),3),18);BD(qud(ZKd(MFd.T),4),18);BD(qud(WKd(MFd.T),0),59);BD(qud(WKd(MFd.T),1),59);BD(qud(ZKd(MFd.T),1),18);cGd=MFd.U;BD(qud(ZKd(MFd.U),0),34);BD(qud(ZKd(MFd.U),1),34);BD(qud(ZKd(MFd.U),2),18);BD(qud(ZKd(MFd.U),3),18);BD(qud(ZKd(MFd.U),4),18);BD(qud(ZKd(MFd.U),5),18);BD(qud(WKd(MFd.U),0),59);dGd=MFd.V;BD(qud(ZKd(MFd.V),0),18);eGd=MFd.W;BD(qud(ZKd(MFd.W),0),34);BD(qud(ZKd(MFd.W),1),34);BD(qud(ZKd(MFd.W),2),34);BD(qud(ZKd(MFd.W),3),18);BD(qud(ZKd(MFd.W),4),18);BD(qud(ZKd(MFd.W),5),18);gGd=MFd.bb;BD(qud(ZKd(MFd.bb),0),34);BD(qud(ZKd(MFd.bb),1),34);BD(qud(ZKd(MFd.bb),2),34);BD(qud(ZKd(MFd.bb),3),34);BD(qud(ZKd(MFd.bb),4),34);BD(qud(ZKd(MFd.bb),5),34);BD(qud(ZKd(MFd.bb),6),34);BD(qud(ZKd(MFd.bb),7),18);BD(qud(WKd(MFd.bb),0),59);BD(qud(WKd(MFd.bb),1),59);hGd=MFd.eb;BD(qud(ZKd(MFd.eb),0),34);BD(qud(ZKd(MFd.eb),1),34);BD(qud(ZKd(MFd.eb),2),34);BD(qud(ZKd(MFd.eb),3),34);BD(qud(ZKd(MFd.eb),4),34);BD(qud(ZKd(MFd.eb),5),34);BD(qud(ZKd(MFd.eb),6),18);BD(qud(ZKd(MFd.eb),7),18);fGd=MFd.ab;BD(qud(ZKd(MFd.ab),0),34);BD(qud(ZKd(MFd.ab),1),34);XFd=MFd.H;BD(qud(ZKd(MFd.H),0),18);BD(qud(ZKd(MFd.H),1),18);BD(qud(ZKd(MFd.H),2),18);BD(qud(ZKd(MFd.H),3),18);BD(qud(ZKd(MFd.H),4),18);BD(qud(ZKd(MFd.H),5),18);BD(qud(WKd(MFd.H),0),59);iGd=MFd.db;BD(qud(ZKd(MFd.db),0),18);YFd=MFd.M} +function bae(a){var b;if(a.O)return;a.O=true;pnd(a,'type');cod(a,'ecore.xml.type');dod(a,Ewe);b=BD(nUd((yFd(),xFd),Ewe),1945);wtd(_Kd(a.fb),a.b);Xnd(a.b,Q9,'AnyType',false,false,true);Vnd(BD(qud(ZKd(a.b),0),34),a.wb.D,Qve,null,0,-1,Q9,false,false,true,false,false,false);Vnd(BD(qud(ZKd(a.b),1),34),a.wb.D,'any',null,0,-1,Q9,true,true,true,false,false,true);Vnd(BD(qud(ZKd(a.b),2),34),a.wb.D,'anyAttribute',null,0,-1,Q9,false,false,true,false,false,false);Xnd(a.bb,S9,Jwe,false,false,true);Vnd(BD(qud(ZKd(a.bb),0),34),a.gb,'data',null,0,1,S9,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.bb),1),34),a.gb,bue,null,1,1,S9,false,false,true,false,true,false);Xnd(a.fb,T9,Kwe,false,false,true);Vnd(BD(qud(ZKd(a.fb),0),34),b.gb,'rawValue',null,0,1,T9,true,true,true,false,true,true);Vnd(BD(qud(ZKd(a.fb),1),34),b.a,Bte,null,0,1,T9,true,true,true,false,true,true);_nd(BD(qud(ZKd(a.fb),2),18),a.wb.q,null,'instanceType',1,1,T9,false,false,true,false,false,false,false);Xnd(a.qb,U9,Lwe,false,false,true);Vnd(BD(qud(ZKd(a.qb),0),34),a.wb.D,Qve,null,0,-1,null,false,false,true,false,false,false);_nd(BD(qud(ZKd(a.qb),1),18),a.wb.ab,null,'xMLNSPrefixMap',0,-1,null,true,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.qb),2),18),a.wb.ab,null,'xSISchemaLocation',0,-1,null,true,false,true,true,false,false,false);Vnd(BD(qud(ZKd(a.qb),3),34),a.gb,'cDATA',null,0,-2,null,true,true,true,false,false,true);Vnd(BD(qud(ZKd(a.qb),4),34),a.gb,'comment',null,0,-2,null,true,true,true,false,false,true);_nd(BD(qud(ZKd(a.qb),5),18),a.bb,null,jxe,0,-2,null,true,true,true,true,false,false,true);Vnd(BD(qud(ZKd(a.qb),6),34),a.gb,Ite,null,0,-2,null,true,true,true,false,false,true);Znd(a.a,SI,'AnySimpleType',true);Znd(a.c,ZI,'AnyURI',true);Znd(a.d,GC(SD,1),'Base64Binary',true);Znd(a.e,sbb,'Boolean',true);Znd(a.f,wI,'BooleanObject',true);Znd(a.g,SD,'Byte',true);Znd(a.i,xI,'ByteObject',true);Znd(a.j,ZI,'Date',true);Znd(a.k,ZI,'DateTime',true);Znd(a.n,bJ,'Decimal',true);Znd(a.o,UD,'Double',true);Znd(a.p,BI,'DoubleObject',true);Znd(a.q,ZI,'Duration',true);Znd(a.s,yK,'ENTITIES',true);Znd(a.r,yK,'ENTITIESBase',true);Znd(a.t,ZI,Rwe,true);Znd(a.u,VD,'Float',true);Znd(a.v,FI,'FloatObject',true);Znd(a.w,ZI,'GDay',true);Znd(a.B,ZI,'GMonth',true);Znd(a.A,ZI,'GMonthDay',true);Znd(a.C,ZI,'GYear',true);Znd(a.D,ZI,'GYearMonth',true);Znd(a.F,GC(SD,1),'HexBinary',true);Znd(a.G,ZI,'ID',true);Znd(a.H,ZI,'IDREF',true);Znd(a.J,yK,'IDREFS',true);Znd(a.I,yK,'IDREFSBase',true);Znd(a.K,WD,'Int',true);Znd(a.M,cJ,'Integer',true);Znd(a.L,JI,'IntObject',true);Znd(a.P,ZI,'Language',true);Znd(a.Q,XD,'Long',true);Znd(a.R,MI,'LongObject',true);Znd(a.S,ZI,'Name',true);Znd(a.T,ZI,Swe,true);Znd(a.U,cJ,'NegativeInteger',true);Znd(a.V,ZI,axe,true);Znd(a.X,yK,'NMTOKENS',true);Znd(a.W,yK,'NMTOKENSBase',true);Znd(a.Y,cJ,'NonNegativeInteger',true);Znd(a.Z,cJ,'NonPositiveInteger',true);Znd(a.$,ZI,'NormalizedString',true);Znd(a._,ZI,'NOTATION',true);Znd(a.ab,ZI,'PositiveInteger',true);Znd(a.cb,ZI,'QName',true);Znd(a.db,rbb,'Short',true);Znd(a.eb,UI,'ShortObject',true);Znd(a.gb,ZI,Vie,true);Znd(a.hb,ZI,'Time',true);Znd(a.ib,ZI,'Token',true);Znd(a.jb,rbb,'UnsignedByte',true);Znd(a.kb,UI,'UnsignedByteObject',true);Znd(a.lb,XD,'UnsignedInt',true);Znd(a.mb,MI,'UnsignedIntObject',true);Znd(a.nb,cJ,'UnsignedLong',true);Znd(a.ob,WD,'UnsignedShort',true);Znd(a.pb,JI,'UnsignedShortObject',true);Rnd(a,Ewe);_9d(a)} +function Oyc(a){r4c(a,new E3c(Q3c(L3c(P3c(M3c(O3c(N3c(new R3c,sne),'ELK Layered'),'Layer-based algorithm provided by the Eclipse Layout Kernel. Arranges as many edges as possible into one direction by placing nodes into subsequent layers. This implementation supports different routing styles (straight, orthogonal, splines); if orthogonal routing is selected, arbitrary port constraints are respected, thus enabling the layout of block diagrams such as actor-oriented models or circuit schematics. Furthermore, full layout of compound graphs with cross-hierarchy edges is supported when the respective option is activated on the top level.'),new Ryc),sne),qqb((Csd(),Bsd),OC(GC(O3,1),Kie,237,0,[ysd,zsd,xsd,Asd,vsd,usd])))));p4c(a,sne,Lpe,Ksd(iyc));p4c(a,sne,Mpe,Ksd(jyc));p4c(a,sne,Zle,Ksd(kyc));p4c(a,sne,Npe,Ksd(lyc));p4c(a,sne,xme,Ksd(nyc));p4c(a,sne,Ope,Ksd(oyc));p4c(a,sne,Ppe,Ksd(ryc));p4c(a,sne,Qpe,Ksd(tyc));p4c(a,sne,Rpe,Ksd(uyc));p4c(a,sne,Spe,Ksd(syc));p4c(a,sne,wme,Ksd(vyc));p4c(a,sne,Tpe,Ksd(xyc));p4c(a,sne,Upe,Ksd(zyc));p4c(a,sne,Vpe,Ksd(qyc));p4c(a,sne,Loe,Ksd(hyc));p4c(a,sne,Noe,Ksd(myc));p4c(a,sne,Moe,Ksd(pyc));p4c(a,sne,Ooe,Ksd(wyc));p4c(a,sne,vme,meb(0));p4c(a,sne,Poe,Ksd(cyc));p4c(a,sne,Qoe,Ksd(dyc));p4c(a,sne,Roe,Ksd(eyc));p4c(a,sne,Yoe,Ksd(Kyc));p4c(a,sne,Zoe,Ksd(Cyc));p4c(a,sne,$oe,Ksd(Dyc));p4c(a,sne,_oe,Ksd(Gyc));p4c(a,sne,ape,Ksd(Eyc));p4c(a,sne,bpe,Ksd(Fyc));p4c(a,sne,cpe,Ksd(Myc));p4c(a,sne,dpe,Ksd(Lyc));p4c(a,sne,epe,Ksd(Iyc));p4c(a,sne,fpe,Ksd(Hyc));p4c(a,sne,gpe,Ksd(Jyc));p4c(a,sne,Eoe,Ksd(Cxc));p4c(a,sne,Foe,Ksd(Dxc));p4c(a,sne,Ioe,Ksd(Xwc));p4c(a,sne,Joe,Ksd(Ywc));p4c(a,sne,ame,Lxc);p4c(a,sne,ype,Twc);p4c(a,sne,Wpe,0);p4c(a,sne,yme,meb(1));p4c(a,sne,_le,tme);p4c(a,sne,Xpe,Ksd(Jxc));p4c(a,sne,Bme,Ksd(Vxc));p4c(a,sne,Ype,Ksd($xc));p4c(a,sne,Zpe,Ksd(Kwc));p4c(a,sne,$pe,Ksd(mwc));p4c(a,sne,tpe,Ksd(axc));p4c(a,sne,zme,(Bcb(),true));p4c(a,sne,_pe,Ksd(fxc));p4c(a,sne,aqe,Ksd(gxc));p4c(a,sne,Fme,Ksd(Fxc));p4c(a,sne,Eme,Ksd(Ixc));p4c(a,sne,bqe,Ksd(Gxc));p4c(a,sne,cqe,Nwc);p4c(a,sne,Gme,Ksd(xxc));p4c(a,sne,dqe,Ksd(wxc));p4c(a,sne,Hme,Ksd(Yxc));p4c(a,sne,eqe,Ksd(Xxc));p4c(a,sne,fqe,Ksd(Zxc));p4c(a,sne,gqe,Oxc);p4c(a,sne,hqe,Ksd(Qxc));p4c(a,sne,iqe,Ksd(Rxc));p4c(a,sne,jqe,Ksd(Sxc));p4c(a,sne,kqe,Ksd(Pxc));p4c(a,sne,eoe,Ksd(Byc));p4c(a,sne,hoe,Ksd(sxc));p4c(a,sne,noe,Ksd(rxc));p4c(a,sne,doe,Ksd(Ayc));p4c(a,sne,ioe,Ksd(mxc));p4c(a,sne,goe,Ksd(Jwc));p4c(a,sne,qoe,Ksd(Iwc));p4c(a,sne,roe,Ksd(Awc));p4c(a,sne,woe,Ksd(Bwc));p4c(a,sne,xoe,Ksd(Dwc));p4c(a,sne,yoe,Ksd(Cwc));p4c(a,sne,toe,Ksd(Hwc));p4c(a,sne,_ne,Ksd(uxc));p4c(a,sne,aoe,Ksd(vxc));p4c(a,sne,$ne,Ksd(ixc));p4c(a,sne,zoe,Ksd(Exc));p4c(a,sne,Coe,Ksd(zxc));p4c(a,sne,Zne,Ksd($wc));p4c(a,sne,Doe,Ksd(Bxc));p4c(a,sne,Goe,Ksd(Vwc));p4c(a,sne,Hoe,Ksd(Wwc));p4c(a,sne,lqe,Ksd(zwc));p4c(a,sne,Boe,Ksd(yxc));p4c(a,sne,Toe,Ksd(swc));p4c(a,sne,Uoe,Ksd(rwc));p4c(a,sne,Soe,Ksd(qwc));p4c(a,sne,Voe,Ksd(cxc));p4c(a,sne,Woe,Ksd(bxc));p4c(a,sne,Xoe,Ksd(dxc));p4c(a,sne,Tme,Ksd(Hxc));p4c(a,sne,mqe,Ksd(jxc));p4c(a,sne,$le,Ksd(Zwc));p4c(a,sne,nqe,Ksd(Qwc));p4c(a,sne,Cme,Ksd(Pwc));p4c(a,sne,soe,Ksd(Ewc));p4c(a,sne,oqe,Ksd(Wxc));p4c(a,sne,pqe,Ksd(pwc));p4c(a,sne,qqe,Ksd(exc));p4c(a,sne,rqe,Ksd(Txc));p4c(a,sne,sqe,Ksd(Mxc));p4c(a,sne,tqe,Ksd(Nxc));p4c(a,sne,loe,Ksd(oxc));p4c(a,sne,moe,Ksd(pxc));p4c(a,sne,uqe,Ksd(ayc));p4c(a,sne,boe,Ksd(nwc));p4c(a,sne,ooe,Ksd(qxc));p4c(a,sne,hpe,Ksd(Rwc));p4c(a,sne,ipe,Ksd(Owc));p4c(a,sne,vqe,Ksd(txc));p4c(a,sne,poe,Ksd(kxc));p4c(a,sne,Aoe,Ksd(Axc));p4c(a,sne,wqe,Ksd(yyc));p4c(a,sne,Yne,Ksd(Mwc));p4c(a,sne,coe,Ksd(_xc));p4c(a,sne,Koe,Ksd(Uwc));p4c(a,sne,joe,Ksd(lxc));p4c(a,sne,uoe,Ksd(Fwc));p4c(a,sne,xqe,Ksd(hxc));p4c(a,sne,koe,Ksd(nxc));p4c(a,sne,voe,Ksd(Gwc));p4c(a,sne,jpe,Ksd(ywc));p4c(a,sne,mpe,Ksd(wwc));p4c(a,sne,npe,Ksd(uwc));p4c(a,sne,ope,Ksd(vwc));p4c(a,sne,kpe,Ksd(xwc));p4c(a,sne,lpe,Ksd(twc));p4c(a,sne,foe,Ksd(_wc))} +function kee(a,b){var c,d;if(!cee){cee=new Lqb;dee=new Lqb;d=(wfe(),wfe(),++vfe,new $fe(4));Ree(d,'\t\n\r\r ');Shb(cee,pxe,d);Shb(dee,pxe,_fe(d));d=(null,++vfe,new $fe(4));Ree(d,sxe);Shb(cee,nxe,d);Shb(dee,nxe,_fe(d));d=(null,++vfe,new $fe(4));Ree(d,sxe);Shb(cee,nxe,d);Shb(dee,nxe,_fe(d));d=(null,++vfe,new $fe(4));Ree(d,txe);Xfe(d,BD(Phb(cee,nxe),117));Shb(cee,oxe,d);Shb(dee,oxe,_fe(d));d=(null,++vfe,new $fe(4));Ree(d,'-.0:AZ__az\xB7\xB7\xC0\xD6\xD8\xF6\xF8\u0131\u0134\u013E\u0141\u0148\u014A\u017E\u0180\u01C3\u01CD\u01F0\u01F4\u01F5\u01FA\u0217\u0250\u02A8\u02BB\u02C1\u02D0\u02D1\u0300\u0345\u0360\u0361\u0386\u038A\u038C\u038C\u038E\u03A1\u03A3\u03CE\u03D0\u03D6\u03DA\u03DA\u03DC\u03DC\u03DE\u03DE\u03E0\u03E0\u03E2\u03F3\u0401\u040C\u040E\u044F\u0451\u045C\u045E\u0481\u0483\u0486\u0490\u04C4\u04C7\u04C8\u04CB\u04CC\u04D0\u04EB\u04EE\u04F5\u04F8\u04F9\u0531\u0556\u0559\u0559\u0561\u0586\u0591\u05A1\u05A3\u05B9\u05BB\u05BD\u05BF\u05BF\u05C1\u05C2\u05C4\u05C4\u05D0\u05EA\u05F0\u05F2\u0621\u063A\u0640\u0652\u0660\u0669\u0670\u06B7\u06BA\u06BE\u06C0\u06CE\u06D0\u06D3\u06D5\u06E8\u06EA\u06ED\u06F0\u06F9\u0901\u0903\u0905\u0939\u093C\u094D\u0951\u0954\u0958\u0963\u0966\u096F\u0981\u0983\u0985\u098C\u098F\u0990\u0993\u09A8\u09AA\u09B0\u09B2\u09B2\u09B6\u09B9\u09BC\u09BC\u09BE\u09C4\u09C7\u09C8\u09CB\u09CD\u09D7\u09D7\u09DC\u09DD\u09DF\u09E3\u09E6\u09F1\u0A02\u0A02\u0A05\u0A0A\u0A0F\u0A10\u0A13\u0A28\u0A2A\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3C\u0A3E\u0A42\u0A47\u0A48\u0A4B\u0A4D\u0A59\u0A5C\u0A5E\u0A5E\u0A66\u0A74\u0A81\u0A83\u0A85\u0A8B\u0A8D\u0A8D\u0A8F\u0A91\u0A93\u0AA8\u0AAA\u0AB0\u0AB2\u0AB3\u0AB5\u0AB9\u0ABC\u0AC5\u0AC7\u0AC9\u0ACB\u0ACD\u0AE0\u0AE0\u0AE6\u0AEF\u0B01\u0B03\u0B05\u0B0C\u0B0F\u0B10\u0B13\u0B28\u0B2A\u0B30\u0B32\u0B33\u0B36\u0B39\u0B3C\u0B43\u0B47\u0B48\u0B4B\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F\u0B61\u0B66\u0B6F\u0B82\u0B83\u0B85\u0B8A\u0B8E\u0B90\u0B92\u0B95\u0B99\u0B9A\u0B9C\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8\u0BAA\u0BAE\u0BB5\u0BB7\u0BB9\u0BBE\u0BC2\u0BC6\u0BC8\u0BCA\u0BCD\u0BD7\u0BD7\u0BE7\u0BEF\u0C01\u0C03\u0C05\u0C0C\u0C0E\u0C10\u0C12\u0C28\u0C2A\u0C33\u0C35\u0C39\u0C3E\u0C44\u0C46\u0C48\u0C4A\u0C4D\u0C55\u0C56\u0C60\u0C61\u0C66\u0C6F\u0C82\u0C83\u0C85\u0C8C\u0C8E\u0C90\u0C92\u0CA8\u0CAA\u0CB3\u0CB5\u0CB9\u0CBE\u0CC4\u0CC6\u0CC8\u0CCA\u0CCD\u0CD5\u0CD6\u0CDE\u0CDE\u0CE0\u0CE1\u0CE6\u0CEF\u0D02\u0D03\u0D05\u0D0C\u0D0E\u0D10\u0D12\u0D28\u0D2A\u0D39\u0D3E\u0D43\u0D46\u0D48\u0D4A\u0D4D\u0D57\u0D57\u0D60\u0D61\u0D66\u0D6F\u0E01\u0E2E\u0E30\u0E3A\u0E40\u0E4E\u0E50\u0E59\u0E81\u0E82\u0E84\u0E84\u0E87\u0E88\u0E8A\u0E8A\u0E8D\u0E8D\u0E94\u0E97\u0E99\u0E9F\u0EA1\u0EA3\u0EA5\u0EA5\u0EA7\u0EA7\u0EAA\u0EAB\u0EAD\u0EAE\u0EB0\u0EB9\u0EBB\u0EBD\u0EC0\u0EC4\u0EC6\u0EC6\u0EC8\u0ECD\u0ED0\u0ED9\u0F18\u0F19\u0F20\u0F29\u0F35\u0F35\u0F37\u0F37\u0F39\u0F39\u0F3E\u0F47\u0F49\u0F69\u0F71\u0F84\u0F86\u0F8B\u0F90\u0F95\u0F97\u0F97\u0F99\u0FAD\u0FB1\u0FB7\u0FB9\u0FB9\u10A0\u10C5\u10D0\u10F6\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110B\u110C\u110E\u1112\u113C\u113C\u113E\u113E\u1140\u1140\u114C\u114C\u114E\u114E\u1150\u1150\u1154\u1155\u1159\u1159\u115F\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116D\u116E\u1172\u1173\u1175\u1175\u119E\u119E\u11A8\u11A8\u11AB\u11AB\u11AE\u11AF\u11B7\u11B8\u11BA\u11BA\u11BC\u11C2\u11EB\u11EB\u11F0\u11F0\u11F9\u11F9\u1E00\u1E9B\u1EA0\u1EF9\u1F00\u1F15\u1F18\u1F1D\u1F20\u1F45\u1F48\u1F4D\u1F50\u1F57\u1F59\u1F59\u1F5B\u1F5B\u1F5D\u1F5D\u1F5F\u1F7D\u1F80\u1FB4\u1FB6\u1FBC\u1FBE\u1FBE\u1FC2\u1FC4\u1FC6\u1FCC\u1FD0\u1FD3\u1FD6\u1FDB\u1FE0\u1FEC\u1FF2\u1FF4\u1FF6\u1FFC\u20D0\u20DC\u20E1\u20E1\u2126\u2126\u212A\u212B\u212E\u212E\u2180\u2182\u3005\u3005\u3007\u3007\u3021\u302F\u3031\u3035\u3041\u3094\u3099\u309A\u309D\u309E\u30A1\u30FA\u30FC\u30FE\u3105\u312C\u4E00\u9FA5\uAC00\uD7A3');Shb(cee,qxe,d);Shb(dee,qxe,_fe(d));d=(null,++vfe,new $fe(4));Ree(d,txe);Ufe(d,95,95);Ufe(d,58,58);Shb(cee,rxe,d);Shb(dee,rxe,_fe(d))}c=b?BD(Phb(cee,a),136):BD(Phb(dee,a),136);return c} +function _9d(a){Bnd(a.a,Rve,OC(GC(ZI,1),nie,2,6,[fue,'anySimpleType']));Bnd(a.b,Rve,OC(GC(ZI,1),nie,2,6,[fue,'anyType',Sve,Qve]));Bnd(BD(qud(ZKd(a.b),0),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,xwe,fue,':mixed']));Bnd(BD(qud(ZKd(a.b),1),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,xwe,Dwe,Fwe,fue,':1',Owe,'lax']));Bnd(BD(qud(ZKd(a.b),2),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,vwe,Dwe,Fwe,fue,':2',Owe,'lax']));Bnd(a.c,Rve,OC(GC(ZI,1),nie,2,6,[fue,'anyURI',Cwe,ywe]));Bnd(a.d,Rve,OC(GC(ZI,1),nie,2,6,[fue,'base64Binary',Cwe,ywe]));Bnd(a.e,Rve,OC(GC(ZI,1),nie,2,6,[fue,Khe,Cwe,ywe]));Bnd(a.f,Rve,OC(GC(ZI,1),nie,2,6,[fue,'boolean:Object',cwe,Khe]));Bnd(a.g,Rve,OC(GC(ZI,1),nie,2,6,[fue,Eve]));Bnd(a.i,Rve,OC(GC(ZI,1),nie,2,6,[fue,'byte:Object',cwe,Eve]));Bnd(a.j,Rve,OC(GC(ZI,1),nie,2,6,[fue,'date',Cwe,ywe]));Bnd(a.k,Rve,OC(GC(ZI,1),nie,2,6,[fue,'dateTime',Cwe,ywe]));Bnd(a.n,Rve,OC(GC(ZI,1),nie,2,6,[fue,'decimal',Cwe,ywe]));Bnd(a.o,Rve,OC(GC(ZI,1),nie,2,6,[fue,Gve,Cwe,ywe]));Bnd(a.p,Rve,OC(GC(ZI,1),nie,2,6,[fue,'double:Object',cwe,Gve]));Bnd(a.q,Rve,OC(GC(ZI,1),nie,2,6,[fue,'duration',Cwe,ywe]));Bnd(a.s,Rve,OC(GC(ZI,1),nie,2,6,[fue,'ENTITIES',cwe,Pwe,Qwe,'1']));Bnd(a.r,Rve,OC(GC(ZI,1),nie,2,6,[fue,Pwe,zwe,Rwe]));Bnd(a.t,Rve,OC(GC(ZI,1),nie,2,6,[fue,Rwe,cwe,Swe]));Bnd(a.u,Rve,OC(GC(ZI,1),nie,2,6,[fue,Hve,Cwe,ywe]));Bnd(a.v,Rve,OC(GC(ZI,1),nie,2,6,[fue,'float:Object',cwe,Hve]));Bnd(a.w,Rve,OC(GC(ZI,1),nie,2,6,[fue,'gDay',Cwe,ywe]));Bnd(a.B,Rve,OC(GC(ZI,1),nie,2,6,[fue,'gMonth',Cwe,ywe]));Bnd(a.A,Rve,OC(GC(ZI,1),nie,2,6,[fue,'gMonthDay',Cwe,ywe]));Bnd(a.C,Rve,OC(GC(ZI,1),nie,2,6,[fue,'gYear',Cwe,ywe]));Bnd(a.D,Rve,OC(GC(ZI,1),nie,2,6,[fue,'gYearMonth',Cwe,ywe]));Bnd(a.F,Rve,OC(GC(ZI,1),nie,2,6,[fue,'hexBinary',Cwe,ywe]));Bnd(a.G,Rve,OC(GC(ZI,1),nie,2,6,[fue,'ID',cwe,Swe]));Bnd(a.H,Rve,OC(GC(ZI,1),nie,2,6,[fue,'IDREF',cwe,Swe]));Bnd(a.J,Rve,OC(GC(ZI,1),nie,2,6,[fue,'IDREFS',cwe,Twe,Qwe,'1']));Bnd(a.I,Rve,OC(GC(ZI,1),nie,2,6,[fue,Twe,zwe,'IDREF']));Bnd(a.K,Rve,OC(GC(ZI,1),nie,2,6,[fue,Ive]));Bnd(a.M,Rve,OC(GC(ZI,1),nie,2,6,[fue,Uwe]));Bnd(a.L,Rve,OC(GC(ZI,1),nie,2,6,[fue,'int:Object',cwe,Ive]));Bnd(a.P,Rve,OC(GC(ZI,1),nie,2,6,[fue,'language',cwe,Vwe,Wwe,Xwe]));Bnd(a.Q,Rve,OC(GC(ZI,1),nie,2,6,[fue,Jve]));Bnd(a.R,Rve,OC(GC(ZI,1),nie,2,6,[fue,'long:Object',cwe,Jve]));Bnd(a.S,Rve,OC(GC(ZI,1),nie,2,6,[fue,'Name',cwe,Vwe,Wwe,Ywe]));Bnd(a.T,Rve,OC(GC(ZI,1),nie,2,6,[fue,Swe,cwe,'Name',Wwe,Zwe]));Bnd(a.U,Rve,OC(GC(ZI,1),nie,2,6,[fue,'negativeInteger',cwe,$we,_we,'-1']));Bnd(a.V,Rve,OC(GC(ZI,1),nie,2,6,[fue,axe,cwe,Vwe,Wwe,'\\c+']));Bnd(a.X,Rve,OC(GC(ZI,1),nie,2,6,[fue,'NMTOKENS',cwe,bxe,Qwe,'1']));Bnd(a.W,Rve,OC(GC(ZI,1),nie,2,6,[fue,bxe,zwe,axe]));Bnd(a.Y,Rve,OC(GC(ZI,1),nie,2,6,[fue,cxe,cwe,Uwe,dxe,'0']));Bnd(a.Z,Rve,OC(GC(ZI,1),nie,2,6,[fue,$we,cwe,Uwe,_we,'0']));Bnd(a.$,Rve,OC(GC(ZI,1),nie,2,6,[fue,exe,cwe,Mhe,Cwe,'replace']));Bnd(a._,Rve,OC(GC(ZI,1),nie,2,6,[fue,'NOTATION',Cwe,ywe]));Bnd(a.ab,Rve,OC(GC(ZI,1),nie,2,6,[fue,'positiveInteger',cwe,cxe,dxe,'1']));Bnd(a.bb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'processingInstruction_._type',Sve,'empty']));Bnd(BD(qud(ZKd(a.bb),0),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,uwe,fue,'data']));Bnd(BD(qud(ZKd(a.bb),1),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,uwe,fue,bue]));Bnd(a.cb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'QName',Cwe,ywe]));Bnd(a.db,Rve,OC(GC(ZI,1),nie,2,6,[fue,Kve]));Bnd(a.eb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'short:Object',cwe,Kve]));Bnd(a.fb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'simpleAnyType',Sve,twe]));Bnd(BD(qud(ZKd(a.fb),0),34),Rve,OC(GC(ZI,1),nie,2,6,[fue,':3',Sve,twe]));Bnd(BD(qud(ZKd(a.fb),1),34),Rve,OC(GC(ZI,1),nie,2,6,[fue,':4',Sve,twe]));Bnd(BD(qud(ZKd(a.fb),2),18),Rve,OC(GC(ZI,1),nie,2,6,[fue,':5',Sve,twe]));Bnd(a.gb,Rve,OC(GC(ZI,1),nie,2,6,[fue,Mhe,Cwe,'preserve']));Bnd(a.hb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'time',Cwe,ywe]));Bnd(a.ib,Rve,OC(GC(ZI,1),nie,2,6,[fue,Vwe,cwe,exe,Cwe,ywe]));Bnd(a.jb,Rve,OC(GC(ZI,1),nie,2,6,[fue,fxe,_we,'255',dxe,'0']));Bnd(a.kb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'unsignedByte:Object',cwe,fxe]));Bnd(a.lb,Rve,OC(GC(ZI,1),nie,2,6,[fue,gxe,_we,'4294967295',dxe,'0']));Bnd(a.mb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'unsignedInt:Object',cwe,gxe]));Bnd(a.nb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'unsignedLong',cwe,cxe,_we,hxe,dxe,'0']));Bnd(a.ob,Rve,OC(GC(ZI,1),nie,2,6,[fue,ixe,_we,'65535',dxe,'0']));Bnd(a.pb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'unsignedShort:Object',cwe,ixe]));Bnd(a.qb,Rve,OC(GC(ZI,1),nie,2,6,[fue,'',Sve,Qve]));Bnd(BD(qud(ZKd(a.qb),0),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,xwe,fue,':mixed']));Bnd(BD(qud(ZKd(a.qb),1),18),Rve,OC(GC(ZI,1),nie,2,6,[Sve,uwe,fue,'xmlns:prefix']));Bnd(BD(qud(ZKd(a.qb),2),18),Rve,OC(GC(ZI,1),nie,2,6,[Sve,uwe,fue,'xsi:schemaLocation']));Bnd(BD(qud(ZKd(a.qb),3),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,wwe,fue,'cDATA',Awe,Bwe]));Bnd(BD(qud(ZKd(a.qb),4),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,wwe,fue,'comment',Awe,Bwe]));Bnd(BD(qud(ZKd(a.qb),5),18),Rve,OC(GC(ZI,1),nie,2,6,[Sve,wwe,fue,jxe,Awe,Bwe]));Bnd(BD(qud(ZKd(a.qb),6),34),Rve,OC(GC(ZI,1),nie,2,6,[Sve,wwe,fue,Ite,Awe,Bwe]))} +function tvd(a){return dfb('_UI_EMFDiagnostic_marker',a)?'EMF Problem':dfb('_UI_CircularContainment_diagnostic',a)?'An object may not circularly contain itself':dfb(sue,a)?'Wrong character.':dfb(tue,a)?'Invalid reference number.':dfb(uue,a)?'A character is required after \\.':dfb(vue,a)?"'?' is not expected. '(?:' or '(?=' or '(?!' or '(?<' or '(?#' or '(?>'?":dfb(wue,a)?"'(?<' or '(?<!' is expected.":dfb(xue,a)?'A comment is not terminated.':dfb(yue,a)?"')' is expected.":dfb(zue,a)?'Unexpected end of the pattern in a modifier group.':dfb(Aue,a)?"':' is expected.":dfb(Bue,a)?'Unexpected end of the pattern in a conditional group.':dfb(Cue,a)?'A back reference or an anchor or a lookahead or a look-behind is expected in a conditional pattern.':dfb(Due,a)?'There are more than three choices in a conditional group.':dfb(Eue,a)?'A character in U+0040-U+005f must follow \\c.':dfb(Fue,a)?"A '{' is required before a character category.":dfb(Gue,a)?"A property name is not closed by '}'.":dfb(Hue,a)?'Unexpected meta character.':dfb(Iue,a)?'Unknown property.':dfb(Jue,a)?"A POSIX character class must be closed by ':]'.":dfb(Kue,a)?'Unexpected end of the pattern in a character class.':dfb(Lue,a)?'Unknown name for a POSIX character class.':dfb('parser.cc.4',a)?"'-' is invalid here.":dfb(Mue,a)?"']' is expected.":dfb(Nue,a)?"'[' is invalid in a character class. Write '\\['.":dfb(Oue,a)?"']' is invalid in a character class. Write '\\]'.":dfb(Pue,a)?"'-' is an invalid character range. Write '\\-'.":dfb(Que,a)?"'[' is expected.":dfb(Rue,a)?"')' or '-[' or '+[' or '&[' is expected.":dfb(Sue,a)?'The range end code point is less than the start code point.':dfb(Tue,a)?'Invalid Unicode hex notation.':dfb(Uue,a)?'Overflow in a hex notation.':dfb(Vue,a)?"'\\x{' must be closed by '}'.":dfb(Wue,a)?'Invalid Unicode code point.':dfb(Xue,a)?'An anchor must not be here.':dfb(Yue,a)?'This expression is not supported in the current option setting.':dfb(Zue,a)?'Invalid quantifier. A digit is expected.':dfb($ue,a)?"Invalid quantifier. Invalid quantity or a '}' is missing.":dfb(_ue,a)?"Invalid quantifier. A digit or '}' is expected.":dfb(ave,a)?'Invalid quantifier. A min quantity must be <= a max quantity.':dfb(bve,a)?'Invalid quantifier. A quantity value overflow.':dfb('_UI_PackageRegistry_extensionpoint',a)?'Ecore Package Registry for Generated Packages':dfb('_UI_DynamicPackageRegistry_extensionpoint',a)?'Ecore Package Registry for Dynamic Packages':dfb('_UI_FactoryRegistry_extensionpoint',a)?'Ecore Factory Override Registry':dfb('_UI_URIExtensionParserRegistry_extensionpoint',a)?'URI Extension Parser Registry':dfb('_UI_URIProtocolParserRegistry_extensionpoint',a)?'URI Protocol Parser Registry':dfb('_UI_URIContentParserRegistry_extensionpoint',a)?'URI Content Parser Registry':dfb('_UI_ContentHandlerRegistry_extensionpoint',a)?'Content Handler Registry':dfb('_UI_URIMappingRegistry_extensionpoint',a)?'URI Converter Mapping Registry':dfb('_UI_PackageRegistryImplementation_extensionpoint',a)?'Ecore Package Registry Implementation':dfb('_UI_ValidationDelegateRegistry_extensionpoint',a)?'Validation Delegate Registry':dfb('_UI_SettingDelegateRegistry_extensionpoint',a)?'Feature Setting Delegate Factory Registry':dfb('_UI_InvocationDelegateRegistry_extensionpoint',a)?'Operation Invocation Delegate Factory Registry':dfb('_UI_EClassInterfaceNotAbstract_diagnostic',a)?'A class that is an interface must also be abstract':dfb('_UI_EClassNoCircularSuperTypes_diagnostic',a)?'A class may not be a super type of itself':dfb('_UI_EClassNotWellFormedMapEntryNoInstanceClassName_diagnostic',a)?"A class that inherits from a map entry class must have instance class name 'java.util.Map$Entry'":dfb('_UI_EReferenceOppositeOfOppositeInconsistent_diagnostic',a)?'The opposite of the opposite may not be a reference different from this one':dfb('_UI_EReferenceOppositeNotFeatureOfType_diagnostic',a)?"The opposite must be a feature of the reference's type":dfb('_UI_EReferenceTransientOppositeNotTransient_diagnostic',a)?'The opposite of a transient reference must be transient if it is proxy resolving':dfb('_UI_EReferenceOppositeBothContainment_diagnostic',a)?'The opposite of a containment reference must not be a containment reference':dfb('_UI_EReferenceConsistentUnique_diagnostic',a)?'A containment or bidirectional reference must be unique if its upper bound is different from 1':dfb('_UI_ETypedElementNoType_diagnostic',a)?'The typed element must have a type':dfb('_UI_EAttributeNoDataType_diagnostic',a)?'The generic attribute type must not refer to a class':dfb('_UI_EReferenceNoClass_diagnostic',a)?'The generic reference type must not refer to a data type':dfb('_UI_EGenericTypeNoTypeParameterAndClassifier_diagnostic',a)?"A generic type can't refer to both a type parameter and a classifier":dfb('_UI_EGenericTypeNoClass_diagnostic',a)?'A generic super type must refer to a class':dfb('_UI_EGenericTypeNoTypeParameterOrClassifier_diagnostic',a)?'A generic type in this context must refer to a classifier or a type parameter':dfb('_UI_EGenericTypeBoundsOnlyForTypeArgument_diagnostic',a)?'A generic type may have bounds only when used as a type argument':dfb('_UI_EGenericTypeNoUpperAndLowerBound_diagnostic',a)?'A generic type must not have both a lower and an upper bound':dfb('_UI_EGenericTypeNoTypeParameterOrClassifierAndBound_diagnostic',a)?'A generic type with bounds must not also refer to a type parameter or classifier':dfb('_UI_EGenericTypeNoArguments_diagnostic',a)?'A generic type may have arguments only if it refers to a classifier':dfb('_UI_EGenericTypeOutOfScopeTypeParameter_diagnostic',a)?'A generic type may only refer to a type parameter that is in scope':a} +function Aod(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;if(a.r)return;a.r=true;pnd(a,'graph');cod(a,'graph');dod(a,yte);Gnd(a.o,'T');wtd(_Kd(a.a),a.p);wtd(_Kd(a.f),a.a);wtd(_Kd(a.n),a.f);wtd(_Kd(a.g),a.n);wtd(_Kd(a.c),a.n);wtd(_Kd(a.i),a.c);wtd(_Kd(a.j),a.c);wtd(_Kd(a.d),a.f);wtd(_Kd(a.e),a.a);Xnd(a.p,P3,Ile,true,true,false);o=Dnd(a.p,a.p,'setProperty');p=Hnd(o);j=Nnd(a.o);k=(c=(d=new UQd,d),c);wtd((!j.d&&(j.d=new xMd(j5,j,1)),j.d),k);l=Ond(p);PQd(k,l);Fnd(o,j,Ate);j=Ond(p);Fnd(o,j,Bte);o=Dnd(a.p,null,'getProperty');p=Hnd(o);j=Nnd(a.o);k=Ond(p);wtd((!j.d&&(j.d=new xMd(j5,j,1)),j.d),k);Fnd(o,j,Ate);j=Ond(p);n=xId(o,j,null);!!n&&n.Fi();o=Dnd(a.p,a.wb.e,'hasProperty');j=Nnd(a.o);k=(e=(f=new UQd,f),e);wtd((!j.d&&(j.d=new xMd(j5,j,1)),j.d),k);Fnd(o,j,Ate);o=Dnd(a.p,a.p,'copyProperties');End(o,a.p,Cte);o=Dnd(a.p,null,'getAllProperties');j=Nnd(a.wb.P);k=Nnd(a.o);wtd((!j.d&&(j.d=new xMd(j5,j,1)),j.d),k);l=(g=(h=new UQd,h),g);wtd((!k.d&&(k.d=new xMd(j5,k,1)),k.d),l);k=Nnd(a.wb.M);wtd((!j.d&&(j.d=new xMd(j5,j,1)),j.d),k);m=xId(o,j,null);!!m&&m.Fi();Xnd(a.a,x2,Xse,true,false,true);_nd(BD(qud(ZKd(a.a),0),18),a.k,null,Dte,0,-1,x2,false,false,true,true,false,false,false);Xnd(a.f,C2,Zse,true,false,true);_nd(BD(qud(ZKd(a.f),0),18),a.g,BD(qud(ZKd(a.g),0),18),'labels',0,-1,C2,false,false,true,true,false,false,false);Vnd(BD(qud(ZKd(a.f),1),34),a.wb._,Ete,null,0,1,C2,false,false,true,false,true,false);Xnd(a.n,G2,'ElkShape',true,false,true);Vnd(BD(qud(ZKd(a.n),0),34),a.wb.t,Fte,$je,1,1,G2,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.n),1),34),a.wb.t,Gte,$je,1,1,G2,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.n),2),34),a.wb.t,'x',$je,1,1,G2,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.n),3),34),a.wb.t,'y',$je,1,1,G2,false,false,true,false,true,false);o=Dnd(a.n,null,'setDimensions');End(o,a.wb.t,Gte);End(o,a.wb.t,Fte);o=Dnd(a.n,null,'setLocation');End(o,a.wb.t,'x');End(o,a.wb.t,'y');Xnd(a.g,D2,dte,false,false,true);_nd(BD(qud(ZKd(a.g),0),18),a.f,BD(qud(ZKd(a.f),0),18),Hte,0,1,D2,false,false,true,false,false,false,false);Vnd(BD(qud(ZKd(a.g),1),34),a.wb._,Ite,'',0,1,D2,false,false,true,false,true,false);Xnd(a.c,z2,$se,true,false,true);_nd(BD(qud(ZKd(a.c),0),18),a.d,BD(qud(ZKd(a.d),1),18),'outgoingEdges',0,-1,z2,false,false,true,false,true,false,false);_nd(BD(qud(ZKd(a.c),1),18),a.d,BD(qud(ZKd(a.d),2),18),'incomingEdges',0,-1,z2,false,false,true,false,true,false,false);Xnd(a.i,E2,ete,false,false,true);_nd(BD(qud(ZKd(a.i),0),18),a.j,BD(qud(ZKd(a.j),0),18),'ports',0,-1,E2,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.i),1),18),a.i,BD(qud(ZKd(a.i),2),18),Jte,0,-1,E2,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.i),2),18),a.i,BD(qud(ZKd(a.i),1),18),Hte,0,1,E2,false,false,true,false,false,false,false);_nd(BD(qud(ZKd(a.i),3),18),a.d,BD(qud(ZKd(a.d),0),18),'containedEdges',0,-1,E2,false,false,true,true,false,false,false);Vnd(BD(qud(ZKd(a.i),4),34),a.wb.e,Kte,null,0,1,E2,true,true,false,false,true,true);Xnd(a.j,F2,fte,false,false,true);_nd(BD(qud(ZKd(a.j),0),18),a.i,BD(qud(ZKd(a.i),0),18),Hte,0,1,F2,false,false,true,false,false,false,false);Xnd(a.d,B2,_se,false,false,true);_nd(BD(qud(ZKd(a.d),0),18),a.i,BD(qud(ZKd(a.i),3),18),'containingNode',0,1,B2,false,false,true,false,false,false,false);_nd(BD(qud(ZKd(a.d),1),18),a.c,BD(qud(ZKd(a.c),0),18),Lte,0,-1,B2,false,false,true,false,true,false,false);_nd(BD(qud(ZKd(a.d),2),18),a.c,BD(qud(ZKd(a.c),1),18),Mte,0,-1,B2,false,false,true,false,true,false,false);_nd(BD(qud(ZKd(a.d),3),18),a.e,BD(qud(ZKd(a.e),5),18),Nte,0,-1,B2,false,false,true,true,false,false,false);Vnd(BD(qud(ZKd(a.d),4),34),a.wb.e,'hyperedge',null,0,1,B2,true,true,false,false,true,true);Vnd(BD(qud(ZKd(a.d),5),34),a.wb.e,Kte,null,0,1,B2,true,true,false,false,true,true);Vnd(BD(qud(ZKd(a.d),6),34),a.wb.e,'selfloop',null,0,1,B2,true,true,false,false,true,true);Vnd(BD(qud(ZKd(a.d),7),34),a.wb.e,'connected',null,0,1,B2,true,true,false,false,true,true);Xnd(a.b,y2,Yse,false,false,true);Vnd(BD(qud(ZKd(a.b),0),34),a.wb.t,'x',$je,1,1,y2,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.b),1),34),a.wb.t,'y',$je,1,1,y2,false,false,true,false,true,false);o=Dnd(a.b,null,'set');End(o,a.wb.t,'x');End(o,a.wb.t,'y');Xnd(a.e,A2,ate,false,false,true);Vnd(BD(qud(ZKd(a.e),0),34),a.wb.t,'startX',null,0,1,A2,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.e),1),34),a.wb.t,'startY',null,0,1,A2,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.e),2),34),a.wb.t,'endX',null,0,1,A2,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.e),3),34),a.wb.t,'endY',null,0,1,A2,false,false,true,false,true,false);_nd(BD(qud(ZKd(a.e),4),18),a.b,null,Ote,0,-1,A2,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.e),5),18),a.d,BD(qud(ZKd(a.d),3),18),Hte,0,1,A2,false,false,true,false,false,false,false);_nd(BD(qud(ZKd(a.e),6),18),a.c,null,Pte,0,1,A2,false,false,true,false,true,false,false);_nd(BD(qud(ZKd(a.e),7),18),a.c,null,Qte,0,1,A2,false,false,true,false,true,false,false);_nd(BD(qud(ZKd(a.e),8),18),a.e,BD(qud(ZKd(a.e),9),18),Rte,0,-1,A2,false,false,true,false,true,false,false);_nd(BD(qud(ZKd(a.e),9),18),a.e,BD(qud(ZKd(a.e),8),18),Ste,0,-1,A2,false,false,true,false,true,false,false);Vnd(BD(qud(ZKd(a.e),10),34),a.wb._,Ete,null,0,1,A2,false,false,true,false,true,false);o=Dnd(a.e,null,'setStartLocation');End(o,a.wb.t,'x');End(o,a.wb.t,'y');o=Dnd(a.e,null,'setEndLocation');End(o,a.wb.t,'x');End(o,a.wb.t,'y');Xnd(a.k,CK,'ElkPropertyToValueMapEntry',false,false,false);j=Nnd(a.o);k=(i=(b=new UQd,b),i);wtd((!j.d&&(j.d=new xMd(j5,j,1)),j.d),k);Wnd(BD(qud(ZKd(a.k),0),34),j,'key',CK,false,false,true,false);Vnd(BD(qud(ZKd(a.k),1),34),a.s,Bte,null,0,1,CK,false,false,true,false,true,false);Znd(a.o,Q3,'IProperty',true);Znd(a.s,SI,'PropertyValue',true);Rnd(a,yte)} +function lde(){lde=ccb;kde=KC(SD,wte,25,Tje,15,1);kde[9]=35;kde[10]=19;kde[13]=19;kde[32]=51;kde[33]=49;kde[34]=33;ylb(kde,35,38,49);kde[38]=1;ylb(kde,39,45,49);ylb(kde,45,47,-71);kde[47]=49;ylb(kde,48,58,-71);kde[58]=61;kde[59]=49;kde[60]=1;kde[61]=49;kde[62]=33;ylb(kde,63,65,49);ylb(kde,65,91,-3);ylb(kde,91,93,33);kde[93]=1;kde[94]=33;kde[95]=-3;kde[96]=33;ylb(kde,97,123,-3);ylb(kde,123,183,33);kde[183]=-87;ylb(kde,184,192,33);ylb(kde,192,215,-19);kde[215]=33;ylb(kde,216,247,-19);kde[247]=33;ylb(kde,248,306,-19);ylb(kde,306,308,33);ylb(kde,308,319,-19);ylb(kde,319,321,33);ylb(kde,321,329,-19);kde[329]=33;ylb(kde,330,383,-19);kde[383]=33;ylb(kde,384,452,-19);ylb(kde,452,461,33);ylb(kde,461,497,-19);ylb(kde,497,500,33);ylb(kde,500,502,-19);ylb(kde,502,506,33);ylb(kde,506,536,-19);ylb(kde,536,592,33);ylb(kde,592,681,-19);ylb(kde,681,699,33);ylb(kde,699,706,-19);ylb(kde,706,720,33);ylb(kde,720,722,-87);ylb(kde,722,768,33);ylb(kde,768,838,-87);ylb(kde,838,864,33);ylb(kde,864,866,-87);ylb(kde,866,902,33);kde[902]=-19;kde[903]=-87;ylb(kde,904,907,-19);kde[907]=33;kde[908]=-19;kde[909]=33;ylb(kde,910,930,-19);kde[930]=33;ylb(kde,931,975,-19);kde[975]=33;ylb(kde,976,983,-19);ylb(kde,983,986,33);kde[986]=-19;kde[987]=33;kde[988]=-19;kde[989]=33;kde[990]=-19;kde[991]=33;kde[992]=-19;kde[993]=33;ylb(kde,994,1012,-19);ylb(kde,1012,1025,33);ylb(kde,1025,1037,-19);kde[1037]=33;ylb(kde,1038,1104,-19);kde[1104]=33;ylb(kde,1105,1117,-19);kde[1117]=33;ylb(kde,1118,1154,-19);kde[1154]=33;ylb(kde,1155,1159,-87);ylb(kde,1159,1168,33);ylb(kde,1168,1221,-19);ylb(kde,1221,1223,33);ylb(kde,1223,1225,-19);ylb(kde,1225,1227,33);ylb(kde,1227,1229,-19);ylb(kde,1229,1232,33);ylb(kde,1232,1260,-19);ylb(kde,1260,1262,33);ylb(kde,1262,1270,-19);ylb(kde,1270,1272,33);ylb(kde,1272,1274,-19);ylb(kde,1274,1329,33);ylb(kde,1329,1367,-19);ylb(kde,1367,1369,33);kde[1369]=-19;ylb(kde,1370,1377,33);ylb(kde,1377,1415,-19);ylb(kde,1415,1425,33);ylb(kde,1425,1442,-87);kde[1442]=33;ylb(kde,1443,1466,-87);kde[1466]=33;ylb(kde,1467,1470,-87);kde[1470]=33;kde[1471]=-87;kde[1472]=33;ylb(kde,1473,1475,-87);kde[1475]=33;kde[1476]=-87;ylb(kde,1477,1488,33);ylb(kde,1488,1515,-19);ylb(kde,1515,1520,33);ylb(kde,1520,1523,-19);ylb(kde,1523,1569,33);ylb(kde,1569,1595,-19);ylb(kde,1595,1600,33);kde[1600]=-87;ylb(kde,1601,1611,-19);ylb(kde,1611,1619,-87);ylb(kde,1619,1632,33);ylb(kde,1632,1642,-87);ylb(kde,1642,1648,33);kde[1648]=-87;ylb(kde,1649,1720,-19);ylb(kde,1720,1722,33);ylb(kde,1722,1727,-19);kde[1727]=33;ylb(kde,1728,1743,-19);kde[1743]=33;ylb(kde,1744,1748,-19);kde[1748]=33;kde[1749]=-19;ylb(kde,1750,1765,-87);ylb(kde,1765,1767,-19);ylb(kde,1767,1769,-87);kde[1769]=33;ylb(kde,1770,1774,-87);ylb(kde,1774,1776,33);ylb(kde,1776,1786,-87);ylb(kde,1786,2305,33);ylb(kde,2305,2308,-87);kde[2308]=33;ylb(kde,2309,2362,-19);ylb(kde,2362,2364,33);kde[2364]=-87;kde[2365]=-19;ylb(kde,2366,2382,-87);ylb(kde,2382,2385,33);ylb(kde,2385,2389,-87);ylb(kde,2389,2392,33);ylb(kde,2392,2402,-19);ylb(kde,2402,2404,-87);ylb(kde,2404,2406,33);ylb(kde,2406,2416,-87);ylb(kde,2416,2433,33);ylb(kde,2433,2436,-87);kde[2436]=33;ylb(kde,2437,2445,-19);ylb(kde,2445,2447,33);ylb(kde,2447,2449,-19);ylb(kde,2449,2451,33);ylb(kde,2451,2473,-19);kde[2473]=33;ylb(kde,2474,2481,-19);kde[2481]=33;kde[2482]=-19;ylb(kde,2483,2486,33);ylb(kde,2486,2490,-19);ylb(kde,2490,2492,33);kde[2492]=-87;kde[2493]=33;ylb(kde,2494,2501,-87);ylb(kde,2501,2503,33);ylb(kde,2503,2505,-87);ylb(kde,2505,2507,33);ylb(kde,2507,2510,-87);ylb(kde,2510,2519,33);kde[2519]=-87;ylb(kde,2520,2524,33);ylb(kde,2524,2526,-19);kde[2526]=33;ylb(kde,2527,2530,-19);ylb(kde,2530,2532,-87);ylb(kde,2532,2534,33);ylb(kde,2534,2544,-87);ylb(kde,2544,2546,-19);ylb(kde,2546,2562,33);kde[2562]=-87;ylb(kde,2563,2565,33);ylb(kde,2565,2571,-19);ylb(kde,2571,2575,33);ylb(kde,2575,2577,-19);ylb(kde,2577,2579,33);ylb(kde,2579,2601,-19);kde[2601]=33;ylb(kde,2602,2609,-19);kde[2609]=33;ylb(kde,2610,2612,-19);kde[2612]=33;ylb(kde,2613,2615,-19);kde[2615]=33;ylb(kde,2616,2618,-19);ylb(kde,2618,2620,33);kde[2620]=-87;kde[2621]=33;ylb(kde,2622,2627,-87);ylb(kde,2627,2631,33);ylb(kde,2631,2633,-87);ylb(kde,2633,2635,33);ylb(kde,2635,2638,-87);ylb(kde,2638,2649,33);ylb(kde,2649,2653,-19);kde[2653]=33;kde[2654]=-19;ylb(kde,2655,2662,33);ylb(kde,2662,2674,-87);ylb(kde,2674,2677,-19);ylb(kde,2677,2689,33);ylb(kde,2689,2692,-87);kde[2692]=33;ylb(kde,2693,2700,-19);kde[2700]=33;kde[2701]=-19;kde[2702]=33;ylb(kde,2703,2706,-19);kde[2706]=33;ylb(kde,2707,2729,-19);kde[2729]=33;ylb(kde,2730,2737,-19);kde[2737]=33;ylb(kde,2738,2740,-19);kde[2740]=33;ylb(kde,2741,2746,-19);ylb(kde,2746,2748,33);kde[2748]=-87;kde[2749]=-19;ylb(kde,2750,2758,-87);kde[2758]=33;ylb(kde,2759,2762,-87);kde[2762]=33;ylb(kde,2763,2766,-87);ylb(kde,2766,2784,33);kde[2784]=-19;ylb(kde,2785,2790,33);ylb(kde,2790,2800,-87);ylb(kde,2800,2817,33);ylb(kde,2817,2820,-87);kde[2820]=33;ylb(kde,2821,2829,-19);ylb(kde,2829,2831,33);ylb(kde,2831,2833,-19);ylb(kde,2833,2835,33);ylb(kde,2835,2857,-19);kde[2857]=33;ylb(kde,2858,2865,-19);kde[2865]=33;ylb(kde,2866,2868,-19);ylb(kde,2868,2870,33);ylb(kde,2870,2874,-19);ylb(kde,2874,2876,33);kde[2876]=-87;kde[2877]=-19;ylb(kde,2878,2884,-87);ylb(kde,2884,2887,33);ylb(kde,2887,2889,-87);ylb(kde,2889,2891,33);ylb(kde,2891,2894,-87);ylb(kde,2894,2902,33);ylb(kde,2902,2904,-87);ylb(kde,2904,2908,33);ylb(kde,2908,2910,-19);kde[2910]=33;ylb(kde,2911,2914,-19);ylb(kde,2914,2918,33);ylb(kde,2918,2928,-87);ylb(kde,2928,2946,33);ylb(kde,2946,2948,-87);kde[2948]=33;ylb(kde,2949,2955,-19);ylb(kde,2955,2958,33);ylb(kde,2958,2961,-19);kde[2961]=33;ylb(kde,2962,2966,-19);ylb(kde,2966,2969,33);ylb(kde,2969,2971,-19);kde[2971]=33;kde[2972]=-19;kde[2973]=33;ylb(kde,2974,2976,-19);ylb(kde,2976,2979,33);ylb(kde,2979,2981,-19);ylb(kde,2981,2984,33);ylb(kde,2984,2987,-19);ylb(kde,2987,2990,33);ylb(kde,2990,2998,-19);kde[2998]=33;ylb(kde,2999,3002,-19);ylb(kde,3002,3006,33);ylb(kde,3006,3011,-87);ylb(kde,3011,3014,33);ylb(kde,3014,3017,-87);kde[3017]=33;ylb(kde,3018,3022,-87);ylb(kde,3022,3031,33);kde[3031]=-87;ylb(kde,3032,3047,33);ylb(kde,3047,3056,-87);ylb(kde,3056,3073,33);ylb(kde,3073,3076,-87);kde[3076]=33;ylb(kde,3077,3085,-19);kde[3085]=33;ylb(kde,3086,3089,-19);kde[3089]=33;ylb(kde,3090,3113,-19);kde[3113]=33;ylb(kde,3114,3124,-19);kde[3124]=33;ylb(kde,3125,3130,-19);ylb(kde,3130,3134,33);ylb(kde,3134,3141,-87);kde[3141]=33;ylb(kde,3142,3145,-87);kde[3145]=33;ylb(kde,3146,3150,-87);ylb(kde,3150,3157,33);ylb(kde,3157,3159,-87);ylb(kde,3159,3168,33);ylb(kde,3168,3170,-19);ylb(kde,3170,3174,33);ylb(kde,3174,3184,-87);ylb(kde,3184,3202,33);ylb(kde,3202,3204,-87);kde[3204]=33;ylb(kde,3205,3213,-19);kde[3213]=33;ylb(kde,3214,3217,-19);kde[3217]=33;ylb(kde,3218,3241,-19);kde[3241]=33;ylb(kde,3242,3252,-19);kde[3252]=33;ylb(kde,3253,3258,-19);ylb(kde,3258,3262,33);ylb(kde,3262,3269,-87);kde[3269]=33;ylb(kde,3270,3273,-87);kde[3273]=33;ylb(kde,3274,3278,-87);ylb(kde,3278,3285,33);ylb(kde,3285,3287,-87);ylb(kde,3287,3294,33);kde[3294]=-19;kde[3295]=33;ylb(kde,3296,3298,-19);ylb(kde,3298,3302,33);ylb(kde,3302,3312,-87);ylb(kde,3312,3330,33);ylb(kde,3330,3332,-87);kde[3332]=33;ylb(kde,3333,3341,-19);kde[3341]=33;ylb(kde,3342,3345,-19);kde[3345]=33;ylb(kde,3346,3369,-19);kde[3369]=33;ylb(kde,3370,3386,-19);ylb(kde,3386,3390,33);ylb(kde,3390,3396,-87);ylb(kde,3396,3398,33);ylb(kde,3398,3401,-87);kde[3401]=33;ylb(kde,3402,3406,-87);ylb(kde,3406,3415,33);kde[3415]=-87;ylb(kde,3416,3424,33);ylb(kde,3424,3426,-19);ylb(kde,3426,3430,33);ylb(kde,3430,3440,-87);ylb(kde,3440,3585,33);ylb(kde,3585,3631,-19);kde[3631]=33;kde[3632]=-19;kde[3633]=-87;ylb(kde,3634,3636,-19);ylb(kde,3636,3643,-87);ylb(kde,3643,3648,33);ylb(kde,3648,3654,-19);ylb(kde,3654,3663,-87);kde[3663]=33;ylb(kde,3664,3674,-87);ylb(kde,3674,3713,33);ylb(kde,3713,3715,-19);kde[3715]=33;kde[3716]=-19;ylb(kde,3717,3719,33);ylb(kde,3719,3721,-19);kde[3721]=33;kde[3722]=-19;ylb(kde,3723,3725,33);kde[3725]=-19;ylb(kde,3726,3732,33);ylb(kde,3732,3736,-19);kde[3736]=33;ylb(kde,3737,3744,-19);kde[3744]=33;ylb(kde,3745,3748,-19);kde[3748]=33;kde[3749]=-19;kde[3750]=33;kde[3751]=-19;ylb(kde,3752,3754,33);ylb(kde,3754,3756,-19);kde[3756]=33;ylb(kde,3757,3759,-19);kde[3759]=33;kde[3760]=-19;kde[3761]=-87;ylb(kde,3762,3764,-19);ylb(kde,3764,3770,-87);kde[3770]=33;ylb(kde,3771,3773,-87);kde[3773]=-19;ylb(kde,3774,3776,33);ylb(kde,3776,3781,-19);kde[3781]=33;kde[3782]=-87;kde[3783]=33;ylb(kde,3784,3790,-87);ylb(kde,3790,3792,33);ylb(kde,3792,3802,-87);ylb(kde,3802,3864,33);ylb(kde,3864,3866,-87);ylb(kde,3866,3872,33);ylb(kde,3872,3882,-87);ylb(kde,3882,3893,33);kde[3893]=-87;kde[3894]=33;kde[3895]=-87;kde[3896]=33;kde[3897]=-87;ylb(kde,3898,3902,33);ylb(kde,3902,3904,-87);ylb(kde,3904,3912,-19);kde[3912]=33;ylb(kde,3913,3946,-19);ylb(kde,3946,3953,33);ylb(kde,3953,3973,-87);kde[3973]=33;ylb(kde,3974,3980,-87);ylb(kde,3980,3984,33);ylb(kde,3984,3990,-87);kde[3990]=33;kde[3991]=-87;kde[3992]=33;ylb(kde,3993,4014,-87);ylb(kde,4014,4017,33);ylb(kde,4017,4024,-87);kde[4024]=33;kde[4025]=-87;ylb(kde,4026,4256,33);ylb(kde,4256,4294,-19);ylb(kde,4294,4304,33);ylb(kde,4304,4343,-19);ylb(kde,4343,4352,33);kde[4352]=-19;kde[4353]=33;ylb(kde,4354,4356,-19);kde[4356]=33;ylb(kde,4357,4360,-19);kde[4360]=33;kde[4361]=-19;kde[4362]=33;ylb(kde,4363,4365,-19);kde[4365]=33;ylb(kde,4366,4371,-19);ylb(kde,4371,4412,33);kde[4412]=-19;kde[4413]=33;kde[4414]=-19;kde[4415]=33;kde[4416]=-19;ylb(kde,4417,4428,33);kde[4428]=-19;kde[4429]=33;kde[4430]=-19;kde[4431]=33;kde[4432]=-19;ylb(kde,4433,4436,33);ylb(kde,4436,4438,-19);ylb(kde,4438,4441,33);kde[4441]=-19;ylb(kde,4442,4447,33);ylb(kde,4447,4450,-19);kde[4450]=33;kde[4451]=-19;kde[4452]=33;kde[4453]=-19;kde[4454]=33;kde[4455]=-19;kde[4456]=33;kde[4457]=-19;ylb(kde,4458,4461,33);ylb(kde,4461,4463,-19);ylb(kde,4463,4466,33);ylb(kde,4466,4468,-19);kde[4468]=33;kde[4469]=-19;ylb(kde,4470,4510,33);kde[4510]=-19;ylb(kde,4511,4520,33);kde[4520]=-19;ylb(kde,4521,4523,33);kde[4523]=-19;ylb(kde,4524,4526,33);ylb(kde,4526,4528,-19);ylb(kde,4528,4535,33);ylb(kde,4535,4537,-19);kde[4537]=33;kde[4538]=-19;kde[4539]=33;ylb(kde,4540,4547,-19);ylb(kde,4547,4587,33);kde[4587]=-19;ylb(kde,4588,4592,33);kde[4592]=-19;ylb(kde,4593,4601,33);kde[4601]=-19;ylb(kde,4602,7680,33);ylb(kde,7680,7836,-19);ylb(kde,7836,7840,33);ylb(kde,7840,7930,-19);ylb(kde,7930,7936,33);ylb(kde,7936,7958,-19);ylb(kde,7958,7960,33);ylb(kde,7960,7966,-19);ylb(kde,7966,7968,33);ylb(kde,7968,8006,-19);ylb(kde,8006,8008,33);ylb(kde,8008,8014,-19);ylb(kde,8014,8016,33);ylb(kde,8016,8024,-19);kde[8024]=33;kde[8025]=-19;kde[8026]=33;kde[8027]=-19;kde[8028]=33;kde[8029]=-19;kde[8030]=33;ylb(kde,8031,8062,-19);ylb(kde,8062,8064,33);ylb(kde,8064,8117,-19);kde[8117]=33;ylb(kde,8118,8125,-19);kde[8125]=33;kde[8126]=-19;ylb(kde,8127,8130,33);ylb(kde,8130,8133,-19);kde[8133]=33;ylb(kde,8134,8141,-19);ylb(kde,8141,8144,33);ylb(kde,8144,8148,-19);ylb(kde,8148,8150,33);ylb(kde,8150,8156,-19);ylb(kde,8156,8160,33);ylb(kde,8160,8173,-19);ylb(kde,8173,8178,33);ylb(kde,8178,8181,-19);kde[8181]=33;ylb(kde,8182,8189,-19);ylb(kde,8189,8400,33);ylb(kde,8400,8413,-87);ylb(kde,8413,8417,33);kde[8417]=-87;ylb(kde,8418,8486,33);kde[8486]=-19;ylb(kde,8487,8490,33);ylb(kde,8490,8492,-19);ylb(kde,8492,8494,33);kde[8494]=-19;ylb(kde,8495,8576,33);ylb(kde,8576,8579,-19);ylb(kde,8579,12293,33);kde[12293]=-87;kde[12294]=33;kde[12295]=-19;ylb(kde,12296,12321,33);ylb(kde,12321,12330,-19);ylb(kde,12330,12336,-87);kde[12336]=33;ylb(kde,12337,12342,-87);ylb(kde,12342,12353,33);ylb(kde,12353,12437,-19);ylb(kde,12437,12441,33);ylb(kde,12441,12443,-87);ylb(kde,12443,12445,33);ylb(kde,12445,12447,-87);ylb(kde,12447,12449,33);ylb(kde,12449,12539,-19);kde[12539]=33;ylb(kde,12540,12543,-87);ylb(kde,12543,12549,33);ylb(kde,12549,12589,-19);ylb(kde,12589,19968,33);ylb(kde,19968,40870,-19);ylb(kde,40870,44032,33);ylb(kde,44032,55204,-19);ylb(kde,55204,Uje,33);ylb(kde,57344,65534,33)} +function zZd(a){var b,c,d,e,f,g,h;if(a.hb)return;a.hb=true;pnd(a,'ecore');cod(a,'ecore');dod(a,_ve);Gnd(a.fb,'E');Gnd(a.L,'T');Gnd(a.P,'K');Gnd(a.P,'V');Gnd(a.cb,'E');wtd(_Kd(a.b),a.bb);wtd(_Kd(a.a),a.Q);wtd(_Kd(a.o),a.p);wtd(_Kd(a.p),a.R);wtd(_Kd(a.q),a.p);wtd(_Kd(a.v),a.q);wtd(_Kd(a.w),a.R);wtd(_Kd(a.B),a.Q);wtd(_Kd(a.R),a.Q);wtd(_Kd(a.T),a.eb);wtd(_Kd(a.U),a.R);wtd(_Kd(a.V),a.eb);wtd(_Kd(a.W),a.bb);wtd(_Kd(a.bb),a.eb);wtd(_Kd(a.eb),a.R);wtd(_Kd(a.db),a.R);Xnd(a.b,b5,qve,false,false,true);Vnd(BD(qud(ZKd(a.b),0),34),a.e,'iD',null,0,1,b5,false,false,true,false,true,false);_nd(BD(qud(ZKd(a.b),1),18),a.q,null,'eAttributeType',1,1,b5,true,true,false,false,true,false,true);Xnd(a.a,a5,nve,false,false,true);Vnd(BD(qud(ZKd(a.a),0),34),a._,Cte,null,0,1,a5,false,false,true,false,true,false);_nd(BD(qud(ZKd(a.a),1),18),a.ab,null,'details',0,-1,a5,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.a),2),18),a.Q,BD(qud(ZKd(a.Q),0),18),'eModelElement',0,1,a5,true,false,true,false,false,false,false);_nd(BD(qud(ZKd(a.a),3),18),a.S,null,'contents',0,-1,a5,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.a),4),18),a.S,null,'references',0,-1,a5,false,false,true,false,true,false,false);Xnd(a.o,c5,'EClass',false,false,true);Vnd(BD(qud(ZKd(a.o),0),34),a.e,'abstract',null,0,1,c5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.o),1),34),a.e,'interface',null,0,1,c5,false,false,true,false,true,false);_nd(BD(qud(ZKd(a.o),2),18),a.o,null,'eSuperTypes',0,-1,c5,false,false,true,false,true,true,false);_nd(BD(qud(ZKd(a.o),3),18),a.T,BD(qud(ZKd(a.T),0),18),'eOperations',0,-1,c5,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.o),4),18),a.b,null,'eAllAttributes',0,-1,c5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.o),5),18),a.W,null,'eAllReferences',0,-1,c5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.o),6),18),a.W,null,'eReferences',0,-1,c5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.o),7),18),a.b,null,'eAttributes',0,-1,c5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.o),8),18),a.W,null,'eAllContainments',0,-1,c5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.o),9),18),a.T,null,'eAllOperations',0,-1,c5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.o),10),18),a.bb,null,'eAllStructuralFeatures',0,-1,c5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.o),11),18),a.o,null,'eAllSuperTypes',0,-1,c5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.o),12),18),a.b,null,'eIDAttribute',0,1,c5,true,true,false,false,false,false,true);_nd(BD(qud(ZKd(a.o),13),18),a.bb,BD(qud(ZKd(a.bb),7),18),'eStructuralFeatures',0,-1,c5,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.o),14),18),a.H,null,'eGenericSuperTypes',0,-1,c5,false,false,true,true,false,true,false);_nd(BD(qud(ZKd(a.o),15),18),a.H,null,'eAllGenericSuperTypes',0,-1,c5,true,true,false,false,true,false,true);h=$nd(BD(qud(WKd(a.o),0),59),a.e,'isSuperTypeOf');End(h,a.o,'someClass');$nd(BD(qud(WKd(a.o),1),59),a.I,'getFeatureCount');h=$nd(BD(qud(WKd(a.o),2),59),a.bb,dwe);End(h,a.I,'featureID');h=$nd(BD(qud(WKd(a.o),3),59),a.I,ewe);End(h,a.bb,fwe);h=$nd(BD(qud(WKd(a.o),4),59),a.bb,dwe);End(h,a._,'featureName');$nd(BD(qud(WKd(a.o),5),59),a.I,'getOperationCount');h=$nd(BD(qud(WKd(a.o),6),59),a.T,'getEOperation');End(h,a.I,'operationID');h=$nd(BD(qud(WKd(a.o),7),59),a.I,gwe);End(h,a.T,hwe);h=$nd(BD(qud(WKd(a.o),8),59),a.T,'getOverride');End(h,a.T,hwe);h=$nd(BD(qud(WKd(a.o),9),59),a.H,'getFeatureType');End(h,a.bb,fwe);Xnd(a.p,d5,rve,true,false,true);Vnd(BD(qud(ZKd(a.p),0),34),a._,'instanceClassName',null,0,1,d5,false,true,true,true,true,false);b=Nnd(a.L);c=vZd();wtd((!b.d&&(b.d=new xMd(j5,b,1)),b.d),c);Wnd(BD(qud(ZKd(a.p),1),34),b,'instanceClass',d5,true,true,false,true);Vnd(BD(qud(ZKd(a.p),2),34),a.M,iwe,null,0,1,d5,true,true,false,false,true,true);Vnd(BD(qud(ZKd(a.p),3),34),a._,'instanceTypeName',null,0,1,d5,false,true,true,true,true,false);_nd(BD(qud(ZKd(a.p),4),18),a.U,BD(qud(ZKd(a.U),3),18),'ePackage',0,1,d5,true,false,false,false,true,false,false);_nd(BD(qud(ZKd(a.p),5),18),a.db,null,jwe,0,-1,d5,false,false,true,true,true,false,false);h=$nd(BD(qud(WKd(a.p),0),59),a.e,kwe);End(h,a.M,Jhe);$nd(BD(qud(WKd(a.p),1),59),a.I,'getClassifierID');Xnd(a.q,f5,'EDataType',false,false,true);Vnd(BD(qud(ZKd(a.q),0),34),a.e,'serializable',kse,0,1,f5,false,false,true,false,true,false);Xnd(a.v,h5,'EEnum',false,false,true);_nd(BD(qud(ZKd(a.v),0),18),a.w,BD(qud(ZKd(a.w),3),18),'eLiterals',0,-1,h5,false,false,true,true,false,false,false);h=$nd(BD(qud(WKd(a.v),0),59),a.w,lwe);End(h,a._,fue);h=$nd(BD(qud(WKd(a.v),1),59),a.w,lwe);End(h,a.I,Bte);h=$nd(BD(qud(WKd(a.v),2),59),a.w,'getEEnumLiteralByLiteral');End(h,a._,'literal');Xnd(a.w,g5,sve,false,false,true);Vnd(BD(qud(ZKd(a.w),0),34),a.I,Bte,null,0,1,g5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.w),1),34),a.A,'instance',null,0,1,g5,true,false,true,false,true,false);Vnd(BD(qud(ZKd(a.w),2),34),a._,'literal',null,0,1,g5,false,false,true,false,true,false);_nd(BD(qud(ZKd(a.w),3),18),a.v,BD(qud(ZKd(a.v),0),18),'eEnum',0,1,g5,true,false,false,false,false,false,false);Xnd(a.B,i5,'EFactory',false,false,true);_nd(BD(qud(ZKd(a.B),0),18),a.U,BD(qud(ZKd(a.U),2),18),'ePackage',1,1,i5,true,false,true,false,false,false,false);h=$nd(BD(qud(WKd(a.B),0),59),a.S,'create');End(h,a.o,'eClass');h=$nd(BD(qud(WKd(a.B),1),59),a.M,'createFromString');End(h,a.q,'eDataType');End(h,a._,'literalValue');h=$nd(BD(qud(WKd(a.B),2),59),a._,'convertToString');End(h,a.q,'eDataType');End(h,a.M,'instanceValue');Xnd(a.Q,k5,bte,true,false,true);_nd(BD(qud(ZKd(a.Q),0),18),a.a,BD(qud(ZKd(a.a),2),18),'eAnnotations',0,-1,k5,false,false,true,true,false,false,false);h=$nd(BD(qud(WKd(a.Q),0),59),a.a,'getEAnnotation');End(h,a._,Cte);Xnd(a.R,l5,cte,true,false,true);Vnd(BD(qud(ZKd(a.R),0),34),a._,fue,null,0,1,l5,false,false,true,false,true,false);Xnd(a.S,m5,'EObject',false,false,true);$nd(BD(qud(WKd(a.S),0),59),a.o,'eClass');$nd(BD(qud(WKd(a.S),1),59),a.e,'eIsProxy');$nd(BD(qud(WKd(a.S),2),59),a.X,'eResource');$nd(BD(qud(WKd(a.S),3),59),a.S,'eContainer');$nd(BD(qud(WKd(a.S),4),59),a.bb,'eContainingFeature');$nd(BD(qud(WKd(a.S),5),59),a.W,'eContainmentFeature');h=$nd(BD(qud(WKd(a.S),6),59),null,'eContents');b=Nnd(a.fb);c=Nnd(a.S);wtd((!b.d&&(b.d=new xMd(j5,b,1)),b.d),c);e=xId(h,b,null);!!e&&e.Fi();h=$nd(BD(qud(WKd(a.S),7),59),null,'eAllContents');b=Nnd(a.cb);c=Nnd(a.S);wtd((!b.d&&(b.d=new xMd(j5,b,1)),b.d),c);f=xId(h,b,null);!!f&&f.Fi();h=$nd(BD(qud(WKd(a.S),8),59),null,'eCrossReferences');b=Nnd(a.fb);c=Nnd(a.S);wtd((!b.d&&(b.d=new xMd(j5,b,1)),b.d),c);g=xId(h,b,null);!!g&&g.Fi();h=$nd(BD(qud(WKd(a.S),9),59),a.M,'eGet');End(h,a.bb,fwe);h=$nd(BD(qud(WKd(a.S),10),59),a.M,'eGet');End(h,a.bb,fwe);End(h,a.e,'resolve');h=$nd(BD(qud(WKd(a.S),11),59),null,'eSet');End(h,a.bb,fwe);End(h,a.M,'newValue');h=$nd(BD(qud(WKd(a.S),12),59),a.e,'eIsSet');End(h,a.bb,fwe);h=$nd(BD(qud(WKd(a.S),13),59),null,'eUnset');End(h,a.bb,fwe);h=$nd(BD(qud(WKd(a.S),14),59),a.M,'eInvoke');End(h,a.T,hwe);b=Nnd(a.fb);c=vZd();wtd((!b.d&&(b.d=new xMd(j5,b,1)),b.d),c);Fnd(h,b,'arguments');Cnd(h,a.K);Xnd(a.T,n5,uve,false,false,true);_nd(BD(qud(ZKd(a.T),0),18),a.o,BD(qud(ZKd(a.o),3),18),mwe,0,1,n5,true,false,false,false,false,false,false);_nd(BD(qud(ZKd(a.T),1),18),a.db,null,jwe,0,-1,n5,false,false,true,true,true,false,false);_nd(BD(qud(ZKd(a.T),2),18),a.V,BD(qud(ZKd(a.V),0),18),'eParameters',0,-1,n5,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.T),3),18),a.p,null,'eExceptions',0,-1,n5,false,false,true,false,true,true,false);_nd(BD(qud(ZKd(a.T),4),18),a.H,null,'eGenericExceptions',0,-1,n5,false,false,true,true,false,true,false);$nd(BD(qud(WKd(a.T),0),59),a.I,gwe);h=$nd(BD(qud(WKd(a.T),1),59),a.e,'isOverrideOf');End(h,a.T,'someOperation');Xnd(a.U,o5,'EPackage',false,false,true);Vnd(BD(qud(ZKd(a.U),0),34),a._,'nsURI',null,0,1,o5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.U),1),34),a._,'nsPrefix',null,0,1,o5,false,false,true,false,true,false);_nd(BD(qud(ZKd(a.U),2),18),a.B,BD(qud(ZKd(a.B),0),18),'eFactoryInstance',1,1,o5,true,false,true,false,false,false,false);_nd(BD(qud(ZKd(a.U),3),18),a.p,BD(qud(ZKd(a.p),4),18),'eClassifiers',0,-1,o5,false,false,true,true,true,false,false);_nd(BD(qud(ZKd(a.U),4),18),a.U,BD(qud(ZKd(a.U),5),18),'eSubpackages',0,-1,o5,false,false,true,true,true,false,false);_nd(BD(qud(ZKd(a.U),5),18),a.U,BD(qud(ZKd(a.U),4),18),'eSuperPackage',0,1,o5,true,false,false,false,true,false,false);h=$nd(BD(qud(WKd(a.U),0),59),a.p,'getEClassifier');End(h,a._,fue);Xnd(a.V,p5,vve,false,false,true);_nd(BD(qud(ZKd(a.V),0),18),a.T,BD(qud(ZKd(a.T),2),18),'eOperation',0,1,p5,true,false,false,false,false,false,false);Xnd(a.W,q5,wve,false,false,true);Vnd(BD(qud(ZKd(a.W),0),34),a.e,'containment',null,0,1,q5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.W),1),34),a.e,'container',null,0,1,q5,true,true,false,false,true,true);Vnd(BD(qud(ZKd(a.W),2),34),a.e,'resolveProxies',kse,0,1,q5,false,false,true,false,true,false);_nd(BD(qud(ZKd(a.W),3),18),a.W,null,'eOpposite',0,1,q5,false,false,true,false,true,false,false);_nd(BD(qud(ZKd(a.W),4),18),a.o,null,'eReferenceType',1,1,q5,true,true,false,false,true,false,true);_nd(BD(qud(ZKd(a.W),5),18),a.b,null,'eKeys',0,-1,q5,false,false,true,false,true,false,false);Xnd(a.bb,t5,pve,true,false,true);Vnd(BD(qud(ZKd(a.bb),0),34),a.e,'changeable',kse,0,1,t5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.bb),1),34),a.e,'volatile',null,0,1,t5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.bb),2),34),a.e,'transient',null,0,1,t5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.bb),3),34),a._,'defaultValueLiteral',null,0,1,t5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.bb),4),34),a.M,iwe,null,0,1,t5,true,true,false,false,true,true);Vnd(BD(qud(ZKd(a.bb),5),34),a.e,'unsettable',null,0,1,t5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.bb),6),34),a.e,'derived',null,0,1,t5,false,false,true,false,true,false);_nd(BD(qud(ZKd(a.bb),7),18),a.o,BD(qud(ZKd(a.o),13),18),mwe,0,1,t5,true,false,false,false,false,false,false);$nd(BD(qud(WKd(a.bb),0),59),a.I,ewe);h=$nd(BD(qud(WKd(a.bb),1),59),null,'getContainerClass');b=Nnd(a.L);c=vZd();wtd((!b.d&&(b.d=new xMd(j5,b,1)),b.d),c);d=xId(h,b,null);!!d&&d.Fi();Xnd(a.eb,v5,ove,true,false,true);Vnd(BD(qud(ZKd(a.eb),0),34),a.e,'ordered',kse,0,1,v5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.eb),1),34),a.e,'unique',kse,0,1,v5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.eb),2),34),a.I,'lowerBound',null,0,1,v5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.eb),3),34),a.I,'upperBound','1',0,1,v5,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.eb),4),34),a.e,'many',null,0,1,v5,true,true,false,false,true,true);Vnd(BD(qud(ZKd(a.eb),5),34),a.e,'required',null,0,1,v5,true,true,false,false,true,true);_nd(BD(qud(ZKd(a.eb),6),18),a.p,null,'eType',0,1,v5,false,true,true,false,true,true,false);_nd(BD(qud(ZKd(a.eb),7),18),a.H,null,'eGenericType',0,1,v5,false,true,true,true,false,true,false);Xnd(a.ab,CK,'EStringToStringMapEntry',false,false,false);Vnd(BD(qud(ZKd(a.ab),0),34),a._,'key',null,0,1,CK,false,false,true,false,true,false);Vnd(BD(qud(ZKd(a.ab),1),34),a._,Bte,null,0,1,CK,false,false,true,false,true,false);Xnd(a.H,j5,tve,false,false,true);_nd(BD(qud(ZKd(a.H),0),18),a.H,null,'eUpperBound',0,1,j5,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.H),1),18),a.H,null,'eTypeArguments',0,-1,j5,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.H),2),18),a.p,null,'eRawType',1,1,j5,true,false,false,false,true,false,true);_nd(BD(qud(ZKd(a.H),3),18),a.H,null,'eLowerBound',0,1,j5,false,false,true,true,false,false,false);_nd(BD(qud(ZKd(a.H),4),18),a.db,null,'eTypeParameter',0,1,j5,false,false,true,false,false,false,false);_nd(BD(qud(ZKd(a.H),5),18),a.p,null,'eClassifier',0,1,j5,false,false,true,false,true,false,false);h=$nd(BD(qud(WKd(a.H),0),59),a.e,kwe);End(h,a.M,Jhe);Xnd(a.db,u5,xve,false,false,true);_nd(BD(qud(ZKd(a.db),0),18),a.H,null,'eBounds',0,-1,u5,false,false,true,true,false,false,false);Znd(a.c,bJ,'EBigDecimal',true);Znd(a.d,cJ,'EBigInteger',true);Znd(a.e,sbb,'EBoolean',true);Znd(a.f,wI,'EBooleanObject',true);Znd(a.i,SD,'EByte',true);Znd(a.g,GC(SD,1),'EByteArray',true);Znd(a.j,xI,'EByteObject',true);Znd(a.k,TD,'EChar',true);Znd(a.n,yI,'ECharacterObject',true);Znd(a.r,$J,'EDate',true);Znd(a.s,O4,'EDiagnosticChain',false);Znd(a.t,UD,'EDouble',true);Znd(a.u,BI,'EDoubleObject',true);Znd(a.fb,T4,'EEList',false);Znd(a.A,U4,'EEnumerator',false);Znd(a.C,O9,'EFeatureMap',false);Znd(a.D,E9,'EFeatureMapEntry',false);Znd(a.F,VD,'EFloat',true);Znd(a.G,FI,'EFloatObject',true);Znd(a.I,WD,'EInt',true);Znd(a.J,JI,'EIntegerObject',true);Znd(a.L,AI,'EJavaClass',true);Znd(a.M,SI,'EJavaObject',true);Znd(a.N,XD,'ELong',true);Znd(a.O,MI,'ELongObject',true);Znd(a.P,DK,'EMap',false);Znd(a.X,v8,'EResource',false);Znd(a.Y,u8,'EResourceSet',false);Znd(a.Z,rbb,'EShort',true);Znd(a.$,UI,'EShortObject',true);Znd(a._,ZI,'EString',true);Znd(a.cb,X4,'ETreeIterator',false);Znd(a.K,V4,'EInvocationTargetException',false);Rnd(a,_ve)} +var Jhe='object',Khe='boolean',Lhe='number',Mhe='string',Nhe='function',Ohe=2147483647,Phe='java.lang',Qhe={3:1},Rhe='com.google.common.base',She=', ',The='%s (%s) must not be negative',Uhe={3:1,4:1,5:1},Vhe='negative size: ',Whe='Optional.of(',Xhe='null',Yhe={198:1,47:1},Zhe='com.google.common.collect',$he={198:1,47:1,125:1},_he={224:1,3:1},aie={47:1},bie='java.util',cie={83:1},die={20:1,28:1,14:1},eie=1965,fie={20:1,28:1,14:1,21:1},gie={83:1,171:1,161:1},hie={20:1,28:1,14:1,21:1,84:1},iie={20:1,28:1,14:1,271:1,21:1,84:1},jie={47:1,125:1},kie={345:1,42:1},lie='AbstractMapEntry',mie='expectedValuesPerKey',nie={3:1,6:1,4:1,5:1},oie=16384,pie={164:1},qie={38:1},rie={l:4194303,m:4194303,h:524287},sie={196:1},tie={245:1,3:1,35:1},uie='range unbounded on this side',vie={20:1},wie={20:1,14:1},xie={3:1,20:1,28:1,14:1},yie={152:1,3:1,20:1,28:1,14:1,15:1,54:1},zie={3:1,4:1,5:1,165:1},Aie={3:1,83:1},Bie={20:1,14:1,21:1},Cie={3:1,20:1,28:1,14:1,21:1},Die={20:1,14:1,21:1,84:1},Eie=461845907,Fie=-862048943,Gie={3:1,6:1,4:1,5:1,165:1},Hie='expectedSize',Iie=1073741824,Jie='initialArraySize',Kie={3:1,6:1,4:1,9:1,5:1},Lie={20:1,28:1,52:1,14:1,15:1},Mie='arraySize',Nie={20:1,28:1,52:1,14:1,15:1,54:1},Oie={45:1},Pie={365:1},Qie=1.0E-4,Rie=-2147483648,Sie='__noinit__',Tie={3:1,102:1,60:1,78:1},Uie='com.google.gwt.core.client.impl',Vie='String',Wie='com.google.gwt.core.client',Xie='anonymous',Yie='fnStack',Zie='Unknown',$ie={195:1,3:1,4:1},_ie=1000,aje=65535,bje='January',cje='February',dje='March',eje='April',fje='May',gje='June',hje='July',ije='August',jje='September',kje='October',lje='November',mje='December',nje=1900,oje={48:1,3:1,4:1},pje='Before Christ',qje='Anno Domini',rje='Sunday',sje='Monday',tje='Tuesday',uje='Wednesday',vje='Thursday',wje='Friday',xje='Saturday',yje='com.google.gwt.i18n.shared',zje='DateTimeFormat',Aje='com.google.gwt.i18n.client',Bje='DefaultDateTimeFormatInfo',Cje={3:1,4:1,35:1,199:1},Dje='com.google.gwt.json.client',Eje=4194303,Fje=1048575,Gje=524288,Hje=4194304,Ije=17592186044416,Jje=1000000000,Kje=-17592186044416,Lje='java.io',Mje={3:1,102:1,73:1,60:1,78:1},Nje={3:1,289:1,78:1},Oje='For input string: "',Pje=Infinity,Qje=-Infinity,Rje=4096,Sje={3:1,4:1,364:1},Tje=65536,Uje=55296,Vje={104:1,3:1,4:1},Wje=100000,Xje=0.3010299956639812,Yje=4294967295,Zje=4294967296,$je='0.0',_je={42:1},ake={3:1,4:1,20:1,28:1,52:1,12:1,14:1,15:1,54:1},bke={3:1,20:1,28:1,52:1,14:1,15:1,54:1},cke={20:1,14:1,15:1},dke={3:1,62:1},eke={182:1},fke={3:1,4:1,83:1},gke={3:1,4:1,20:1,28:1,14:1,53:1,21:1},hke='delete',ike=1.4901161193847656E-8,jke=1.1102230246251565E-16,kke=15525485,lke=5.9604644775390625E-8,mke=16777216,nke=16777215,oke=', length: ',pke={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1},qke={3:1,35:1,22:1,297:1},rke='java.util.function',ske='java.util.logging',tke={3:1,4:1,5:1,842:1},uke='undefined',vke='java.util.stream',wke={525:1,670:1},xke='fromIndex: ',yke=' > toIndex: ',zke=', toIndex: ',Ake='Index: ',Bke=', Size: ',Cke='org.eclipse.elk.alg.common',Dke={62:1},Eke='org.eclipse.elk.alg.common.compaction',Fke='Scanline/EventHandler',Gke='org.eclipse.elk.alg.common.compaction.oned',Hke='CNode belongs to another CGroup.',Ike='ISpacingsHandler/1',Jke='The ',Kke=' instance has been finished already.',Lke='The direction ',Mke=' is not supported by the CGraph instance.',Nke='OneDimensionalCompactor',Oke='OneDimensionalCompactor/lambda$0$Type',Pke='Quadruplet',Qke='ScanlineConstraintCalculator',Rke='ScanlineConstraintCalculator/ConstraintsScanlineHandler',Ske='ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type',Tke='ScanlineConstraintCalculator/Timestamp',Uke='ScanlineConstraintCalculator/lambda$0$Type',Vke={169:1,45:1},Wke='org.eclipse.elk.alg.common.compaction.options',Xke='org.eclipse.elk.core.data',Yke='org.eclipse.elk.polyomino.traversalStrategy',Zke='org.eclipse.elk.polyomino.lowLevelSort',$ke='org.eclipse.elk.polyomino.highLevelSort',_ke='org.eclipse.elk.polyomino.fill',ale={130:1},ble='polyomino',cle='org.eclipse.elk.alg.common.networksimplex',dle={177:1,3:1,4:1},ele='org.eclipse.elk.alg.common.nodespacing',fle='org.eclipse.elk.alg.common.nodespacing.cellsystem',gle='CENTER',hle={212:1,326:1},ile={3:1,4:1,5:1,595:1},jle='LEFT',kle='RIGHT',lle='Vertical alignment cannot be null',mle='BOTTOM',nle='org.eclipse.elk.alg.common.nodespacing.internal',ole='UNDEFINED',ple=0.01,qle='org.eclipse.elk.alg.common.nodespacing.internal.algorithm',rle='LabelPlacer/lambda$0$Type',sle='LabelPlacer/lambda$1$Type',tle='portRatioOrPosition',ule='org.eclipse.elk.alg.common.overlaps',vle='DOWN',wle='org.eclipse.elk.alg.common.polyomino',xle='NORTH',yle='EAST',zle='SOUTH',Ale='WEST',Ble='org.eclipse.elk.alg.common.polyomino.structures',Cle='Direction',Dle='Grid is only of size ',Ele='. Requested point (',Fle=') is out of bounds.',Gle=' Given center based coordinates were (',Hle='org.eclipse.elk.graph.properties',Ile='IPropertyHolder',Jle={3:1,94:1,134:1},Kle='org.eclipse.elk.alg.common.spore',Lle='org.eclipse.elk.alg.common.utils',Mle={209:1},Nle='org.eclipse.elk.core',Ole='Connected Components Compaction',Ple='org.eclipse.elk.alg.disco',Qle='org.eclipse.elk.alg.disco.graph',Rle='org.eclipse.elk.alg.disco.options',Sle='CompactionStrategy',Tle='org.eclipse.elk.disco.componentCompaction.strategy',Ule='org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm',Vle='org.eclipse.elk.disco.debug.discoGraph',Wle='org.eclipse.elk.disco.debug.discoPolys',Xle='componentCompaction',Yle='org.eclipse.elk.disco',Zle='org.eclipse.elk.spacing.componentComponent',$le='org.eclipse.elk.edge.thickness',_le='org.eclipse.elk.aspectRatio',ame='org.eclipse.elk.padding',bme='org.eclipse.elk.alg.disco.transform',cme=1.5707963267948966,dme=1.7976931348623157E308,eme={3:1,4:1,5:1,192:1},fme={3:1,6:1,4:1,5:1,106:1,120:1},gme='org.eclipse.elk.alg.force',hme='ComponentsProcessor',ime='ComponentsProcessor/1',jme='org.eclipse.elk.alg.force.graph',kme='Component Layout',lme='org.eclipse.elk.alg.force.model',mme='org.eclipse.elk.force.model',nme='org.eclipse.elk.force.iterations',ome='org.eclipse.elk.force.repulsivePower',pme='org.eclipse.elk.force.temperature',qme=0.001,rme='org.eclipse.elk.force.repulsion',sme='org.eclipse.elk.alg.force.options',tme=1.600000023841858,ume='org.eclipse.elk.force',vme='org.eclipse.elk.priority',wme='org.eclipse.elk.spacing.nodeNode',xme='org.eclipse.elk.spacing.edgeLabel',yme='org.eclipse.elk.randomSeed',zme='org.eclipse.elk.separateConnectedComponents',Ame='org.eclipse.elk.interactive',Bme='org.eclipse.elk.portConstraints',Cme='org.eclipse.elk.edgeLabels.inline',Dme='org.eclipse.elk.omitNodeMicroLayout',Eme='org.eclipse.elk.nodeSize.options',Fme='org.eclipse.elk.nodeSize.constraints',Gme='org.eclipse.elk.nodeLabels.placement',Hme='org.eclipse.elk.portLabels.placement',Ime='origin',Jme='random',Kme='boundingBox.upLeft',Lme='boundingBox.lowRight',Mme='org.eclipse.elk.stress.fixed',Nme='org.eclipse.elk.stress.desiredEdgeLength',Ome='org.eclipse.elk.stress.dimension',Pme='org.eclipse.elk.stress.epsilon',Qme='org.eclipse.elk.stress.iterationLimit',Rme='org.eclipse.elk.stress',Sme='ELK Stress',Tme='org.eclipse.elk.nodeSize.minimum',Ume='org.eclipse.elk.alg.force.stress',Vme='Layered layout',Wme='org.eclipse.elk.alg.layered',Xme='org.eclipse.elk.alg.layered.compaction.components',Yme='org.eclipse.elk.alg.layered.compaction.oned',Zme='org.eclipse.elk.alg.layered.compaction.oned.algs',$me='org.eclipse.elk.alg.layered.compaction.recthull',_me='org.eclipse.elk.alg.layered.components',ane='NONE',bne={3:1,6:1,4:1,9:1,5:1,122:1},cne={3:1,6:1,4:1,5:1,141:1,106:1,120:1},dne='org.eclipse.elk.alg.layered.compound',ene={51:1},fne='org.eclipse.elk.alg.layered.graph',gne=' -> ',hne='Not supported by LGraph',ine='Port side is undefined',jne={3:1,6:1,4:1,5:1,474:1,141:1,106:1,120:1},kne={3:1,6:1,4:1,5:1,141:1,193:1,203:1,106:1,120:1},lne={3:1,6:1,4:1,5:1,141:1,1943:1,203:1,106:1,120:1},mne='([{"\' \t\r\n',nne=')]}"\' \t\r\n',one='The given string contains parts that cannot be parsed as numbers.',pne='org.eclipse.elk.core.math',qne={3:1,4:1,142:1,207:1,414:1},rne={3:1,4:1,116:1,207:1,414:1},sne='org.eclipse.elk.layered',tne='org.eclipse.elk.alg.layered.graph.transform',une='ElkGraphImporter',vne='ElkGraphImporter/lambda$0$Type',wne='ElkGraphImporter/lambda$1$Type',xne='ElkGraphImporter/lambda$2$Type',yne='ElkGraphImporter/lambda$4$Type',zne='Node margin calculation',Ane='org.eclipse.elk.alg.layered.intermediate',Bne='ONE_SIDED_GREEDY_SWITCH',Cne='TWO_SIDED_GREEDY_SWITCH',Dne='No implementation is available for the layout processor ',Ene='IntermediateProcessorStrategy',Fne="Node '",Gne='FIRST_SEPARATE',Hne='LAST_SEPARATE',Ine='Odd port side processing',Jne='org.eclipse.elk.alg.layered.intermediate.compaction',Kne='org.eclipse.elk.alg.layered.intermediate.greedyswitch',Lne='org.eclipse.elk.alg.layered.p3order.counting',Mne={225:1},Nne='org.eclipse.elk.alg.layered.intermediate.loops',One='org.eclipse.elk.alg.layered.intermediate.loops.ordering',Pne='org.eclipse.elk.alg.layered.intermediate.loops.routing',Qne='org.eclipse.elk.alg.layered.intermediate.preserveorder',Rne='org.eclipse.elk.alg.layered.intermediate.wrapping',Sne='org.eclipse.elk.alg.layered.options',Tne='INTERACTIVE',Une='DEPTH_FIRST',Vne='EDGE_LENGTH',Wne='SELF_LOOPS',Xne='firstTryWithInitialOrder',Yne='org.eclipse.elk.layered.directionCongruency',Zne='org.eclipse.elk.layered.feedbackEdges',$ne='org.eclipse.elk.layered.interactiveReferencePoint',_ne='org.eclipse.elk.layered.mergeEdges',aoe='org.eclipse.elk.layered.mergeHierarchyEdges',boe='org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides',coe='org.eclipse.elk.layered.portSortingStrategy',doe='org.eclipse.elk.layered.thoroughness',eoe='org.eclipse.elk.layered.unnecessaryBendpoints',foe='org.eclipse.elk.layered.generatePositionAndLayerIds',goe='org.eclipse.elk.layered.cycleBreaking.strategy',hoe='org.eclipse.elk.layered.layering.strategy',ioe='org.eclipse.elk.layered.layering.layerConstraint',joe='org.eclipse.elk.layered.layering.layerChoiceConstraint',koe='org.eclipse.elk.layered.layering.layerId',loe='org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth',moe='org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor',noe='org.eclipse.elk.layered.layering.nodePromotion.strategy',ooe='org.eclipse.elk.layered.layering.nodePromotion.maxIterations',poe='org.eclipse.elk.layered.layering.coffmanGraham.layerBound',qoe='org.eclipse.elk.layered.crossingMinimization.strategy',roe='org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder',soe='org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness',toe='org.eclipse.elk.layered.crossingMinimization.semiInteractive',uoe='org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint',voe='org.eclipse.elk.layered.crossingMinimization.positionId',woe='org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold',xoe='org.eclipse.elk.layered.crossingMinimization.greedySwitch.type',yoe='org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type',zoe='org.eclipse.elk.layered.nodePlacement.strategy',Aoe='org.eclipse.elk.layered.nodePlacement.favorStraightEdges',Boe='org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening',Coe='org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment',Doe='org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening',Eoe='org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility',Foe='org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default',Goe='org.eclipse.elk.layered.edgeRouting.selfLoopDistribution',Hoe='org.eclipse.elk.layered.edgeRouting.selfLoopOrdering',Ioe='org.eclipse.elk.layered.edgeRouting.splines.mode',Joe='org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor',Koe='org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth',Loe='org.eclipse.elk.layered.spacing.baseValue',Moe='org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers',Noe='org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers',Ooe='org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers',Poe='org.eclipse.elk.layered.priority.direction',Qoe='org.eclipse.elk.layered.priority.shortness',Roe='org.eclipse.elk.layered.priority.straightness',Soe='org.eclipse.elk.layered.compaction.connectedComponents',Toe='org.eclipse.elk.layered.compaction.postCompaction.strategy',Uoe='org.eclipse.elk.layered.compaction.postCompaction.constraints',Voe='org.eclipse.elk.layered.highDegreeNodes.treatment',Woe='org.eclipse.elk.layered.highDegreeNodes.threshold',Xoe='org.eclipse.elk.layered.highDegreeNodes.treeHeight',Yoe='org.eclipse.elk.layered.wrapping.strategy',Zoe='org.eclipse.elk.layered.wrapping.additionalEdgeSpacing',$oe='org.eclipse.elk.layered.wrapping.correctionFactor',_oe='org.eclipse.elk.layered.wrapping.cutting.strategy',ape='org.eclipse.elk.layered.wrapping.cutting.cuts',bpe='org.eclipse.elk.layered.wrapping.cutting.msd.freedom',cpe='org.eclipse.elk.layered.wrapping.validify.strategy',dpe='org.eclipse.elk.layered.wrapping.validify.forbiddenIndices',epe='org.eclipse.elk.layered.wrapping.multiEdge.improveCuts',fpe='org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty',gpe='org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges',hpe='org.eclipse.elk.layered.edgeLabels.sideSelection',ipe='org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy',jpe='org.eclipse.elk.layered.considerModelOrder.strategy',kpe='org.eclipse.elk.layered.considerModelOrder.noModelOrder',lpe='org.eclipse.elk.layered.considerModelOrder.components',mpe='org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy',npe='org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence',ope='org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence',ppe='layering',qpe='layering.minWidth',rpe='layering.nodePromotion',spe='crossingMinimization',tpe='org.eclipse.elk.hierarchyHandling',upe='crossingMinimization.greedySwitch',vpe='nodePlacement',wpe='nodePlacement.bk',xpe='edgeRouting',ype='org.eclipse.elk.edgeRouting',zpe='spacing',Ape='priority',Bpe='compaction',Cpe='compaction.postCompaction',Dpe='Specifies whether and how post-process compaction is applied.',Epe='highDegreeNodes',Fpe='wrapping',Gpe='wrapping.cutting',Hpe='wrapping.validify',Ipe='wrapping.multiEdge',Jpe='edgeLabels',Kpe='considerModelOrder',Lpe='org.eclipse.elk.spacing.commentComment',Mpe='org.eclipse.elk.spacing.commentNode',Npe='org.eclipse.elk.spacing.edgeEdge',Ope='org.eclipse.elk.spacing.edgeNode',Ppe='org.eclipse.elk.spacing.labelLabel',Qpe='org.eclipse.elk.spacing.labelPortHorizontal',Rpe='org.eclipse.elk.spacing.labelPortVertical',Spe='org.eclipse.elk.spacing.labelNode',Tpe='org.eclipse.elk.spacing.nodeSelfLoop',Upe='org.eclipse.elk.spacing.portPort',Vpe='org.eclipse.elk.spacing.individual',Wpe='org.eclipse.elk.port.borderOffset',Xpe='org.eclipse.elk.noLayout',Ype='org.eclipse.elk.port.side',Zpe='org.eclipse.elk.debugMode',$pe='org.eclipse.elk.alignment',_pe='org.eclipse.elk.insideSelfLoops.activate',aqe='org.eclipse.elk.insideSelfLoops.yo',bqe='org.eclipse.elk.nodeSize.fixedGraphSize',cqe='org.eclipse.elk.direction',dqe='org.eclipse.elk.nodeLabels.padding',eqe='org.eclipse.elk.portLabels.nextToPortIfPossible',fqe='org.eclipse.elk.portLabels.treatAsGroup',gqe='org.eclipse.elk.portAlignment.default',hqe='org.eclipse.elk.portAlignment.north',iqe='org.eclipse.elk.portAlignment.south',jqe='org.eclipse.elk.portAlignment.west',kqe='org.eclipse.elk.portAlignment.east',lqe='org.eclipse.elk.contentAlignment',mqe='org.eclipse.elk.junctionPoints',nqe='org.eclipse.elk.edgeLabels.placement',oqe='org.eclipse.elk.port.index',pqe='org.eclipse.elk.commentBox',qqe='org.eclipse.elk.hypernode',rqe='org.eclipse.elk.port.anchor',sqe='org.eclipse.elk.partitioning.activate',tqe='org.eclipse.elk.partitioning.partition',uqe='org.eclipse.elk.position',vqe='org.eclipse.elk.margins',wqe='org.eclipse.elk.spacing.portsSurrounding',xqe='org.eclipse.elk.interactiveLayout',yqe='org.eclipse.elk.core.util',zqe={3:1,4:1,5:1,593:1},Aqe='NETWORK_SIMPLEX',Bqe={123:1,51:1},Cqe='org.eclipse.elk.alg.layered.p1cycles',Dqe='org.eclipse.elk.alg.layered.p2layers',Eqe={402:1,225:1},Fqe={832:1,3:1,4:1},Gqe='org.eclipse.elk.alg.layered.p3order',Hqe='org.eclipse.elk.alg.layered.p4nodes',Iqe={3:1,4:1,5:1,840:1},Jqe=1.0E-5,Kqe='org.eclipse.elk.alg.layered.p4nodes.bk',Lqe='org.eclipse.elk.alg.layered.p5edges',Mqe='org.eclipse.elk.alg.layered.p5edges.orthogonal',Nqe='org.eclipse.elk.alg.layered.p5edges.orthogonal.direction',Oqe=1.0E-6,Pqe='org.eclipse.elk.alg.layered.p5edges.splines',Qqe=0.09999999999999998,Rqe=1.0E-8,Sqe=4.71238898038469,Tqe=3.141592653589793,Uqe='org.eclipse.elk.alg.mrtree',Vqe='org.eclipse.elk.alg.mrtree.graph',Wqe='org.eclipse.elk.alg.mrtree.intermediate',Xqe='Set neighbors in level',Yqe='DESCENDANTS',Zqe='org.eclipse.elk.mrtree.weighting',$qe='org.eclipse.elk.mrtree.searchOrder',_qe='org.eclipse.elk.alg.mrtree.options',are='org.eclipse.elk.mrtree',bre='org.eclipse.elk.tree',cre='org.eclipse.elk.alg.radial',dre=6.283185307179586,ere=4.9E-324,fre='org.eclipse.elk.alg.radial.intermediate',gre='org.eclipse.elk.alg.radial.intermediate.compaction',hre={3:1,4:1,5:1,106:1},ire='org.eclipse.elk.alg.radial.intermediate.optimization',jre='No implementation is available for the layout option ',kre='org.eclipse.elk.alg.radial.options',lre='org.eclipse.elk.radial.orderId',mre='org.eclipse.elk.radial.radius',nre='org.eclipse.elk.radial.compactor',ore='org.eclipse.elk.radial.compactionStepSize',pre='org.eclipse.elk.radial.sorter',qre='org.eclipse.elk.radial.wedgeCriteria',rre='org.eclipse.elk.radial.optimizationCriteria',sre='org.eclipse.elk.radial',tre='org.eclipse.elk.alg.radial.p1position.wedge',ure='org.eclipse.elk.alg.radial.sorting',vre=5.497787143782138,wre=3.9269908169872414,xre=2.356194490192345,yre='org.eclipse.elk.alg.rectpacking',zre='org.eclipse.elk.alg.rectpacking.firstiteration',Are='org.eclipse.elk.alg.rectpacking.options',Bre='org.eclipse.elk.rectpacking.optimizationGoal',Cre='org.eclipse.elk.rectpacking.lastPlaceShift',Dre='org.eclipse.elk.rectpacking.currentPosition',Ere='org.eclipse.elk.rectpacking.desiredPosition',Fre='org.eclipse.elk.rectpacking.onlyFirstIteration',Gre='org.eclipse.elk.rectpacking.rowCompaction',Hre='org.eclipse.elk.rectpacking.expandToAspectRatio',Ire='org.eclipse.elk.rectpacking.targetWidth',Jre='org.eclipse.elk.expandNodes',Kre='org.eclipse.elk.rectpacking',Lre='org.eclipse.elk.alg.rectpacking.util',Mre='No implementation available for ',Nre='org.eclipse.elk.alg.spore',Ore='org.eclipse.elk.alg.spore.options',Pre='org.eclipse.elk.sporeCompaction',Qre='org.eclipse.elk.underlyingLayoutAlgorithm',Rre='org.eclipse.elk.processingOrder.treeConstruction',Sre='org.eclipse.elk.processingOrder.spanningTreeCostFunction',Tre='org.eclipse.elk.processingOrder.preferredRoot',Ure='org.eclipse.elk.processingOrder.rootSelection',Vre='org.eclipse.elk.structure.structureExtractionStrategy',Wre='org.eclipse.elk.compaction.compactionStrategy',Xre='org.eclipse.elk.compaction.orthogonal',Yre='org.eclipse.elk.overlapRemoval.maxIterations',Zre='org.eclipse.elk.overlapRemoval.runScanline',$re='processingOrder',_re='overlapRemoval',ase='org.eclipse.elk.sporeOverlap',bse='org.eclipse.elk.alg.spore.p1structure',cse='org.eclipse.elk.alg.spore.p2processingorder',dse='org.eclipse.elk.alg.spore.p3execution',ese='Invalid index: ',fse='org.eclipse.elk.core.alg',gse={331:1},hse={288:1},ise='Make sure its type is registered with the ',jse=' utility class.',kse='true',lse='false',mse="Couldn't clone property '",nse=0.05,ose='org.eclipse.elk.core.options',pse=1.2999999523162842,qse='org.eclipse.elk.box',rse='org.eclipse.elk.box.packingMode',sse='org.eclipse.elk.algorithm',tse='org.eclipse.elk.resolvedAlgorithm',use='org.eclipse.elk.bendPoints',vse='org.eclipse.elk.labelManager',wse='org.eclipse.elk.scaleFactor',xse='org.eclipse.elk.animate',yse='org.eclipse.elk.animTimeFactor',zse='org.eclipse.elk.layoutAncestors',Ase='org.eclipse.elk.maxAnimTime',Bse='org.eclipse.elk.minAnimTime',Cse='org.eclipse.elk.progressBar',Dse='org.eclipse.elk.validateGraph',Ese='org.eclipse.elk.validateOptions',Fse='org.eclipse.elk.zoomToFit',Gse='org.eclipse.elk.font.name',Hse='org.eclipse.elk.font.size',Ise='org.eclipse.elk.edge.type',Jse='partitioning',Kse='nodeLabels',Lse='portAlignment',Mse='nodeSize',Nse='port',Ose='portLabels',Pse='insideSelfLoops',Qse='org.eclipse.elk.fixed',Rse='org.eclipse.elk.random',Sse='port must have a parent node to calculate the port side',Tse='The edge needs to have exactly one edge section. Found: ',Use='org.eclipse.elk.core.util.adapters',Vse='org.eclipse.emf.ecore',Wse='org.eclipse.elk.graph',Xse='EMapPropertyHolder',Yse='ElkBendPoint',Zse='ElkGraphElement',$se='ElkConnectableShape',_se='ElkEdge',ate='ElkEdgeSection',bte='EModelElement',cte='ENamedElement',dte='ElkLabel',ete='ElkNode',fte='ElkPort',gte={92:1,90:1},hte='org.eclipse.emf.common.notify.impl',ite="The feature '",jte="' is not a valid changeable feature",kte='Expecting null',lte="' is not a valid feature",mte='The feature ID',nte=' is not a valid feature ID',ote=32768,pte={105:1,92:1,90:1,56:1,49:1,97:1},qte='org.eclipse.emf.ecore.impl',rte='org.eclipse.elk.graph.impl',ste='Recursive containment not allowed for ',tte="The datatype '",ute="' is not a valid classifier",vte="The value '",wte={190:1,3:1,4:1},xte="The class '",yte='http://www.eclipse.org/elk/ElkGraph',zte=1024,Ate='property',Bte='value',Cte='source',Dte='properties',Ete='identifier',Fte='height',Gte='width',Hte='parent',Ite='text',Jte='children',Kte='hierarchical',Lte='sources',Mte='targets',Nte='sections',Ote='bendPoints',Pte='outgoingShape',Qte='incomingShape',Rte='outgoingSections',Ste='incomingSections',Tte='org.eclipse.emf.common.util',Ute='Severe implementation error in the Json to ElkGraph importer.',Vte='id',Wte='org.eclipse.elk.graph.json',Xte='Unhandled parameter types: ',Yte='startPoint',Zte="An edge must have at least one source and one target (edge id: '",$te="').",_te='Referenced edge section does not exist: ',aue=" (edge id: '",bue='target',cue='sourcePoint',due='targetPoint',eue='group',fue='name',gue='connectableShape cannot be null',hue='edge cannot be null',iue="Passed edge is not 'simple'.",jue='org.eclipse.elk.graph.util',kue="The 'no duplicates' constraint is violated",lue='targetIndex=',mue=', size=',nue='sourceIndex=',oue={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1},pue={3:1,4:1,20:1,28:1,52:1,14:1,47:1,15:1,54:1,67:1,63:1,58:1,588:1},que='logging',rue='measureExecutionTime',sue='parser.parse.1',tue='parser.parse.2',uue='parser.next.1',vue='parser.next.2',wue='parser.next.3',xue='parser.next.4',yue='parser.factor.1',zue='parser.factor.2',Aue='parser.factor.3',Bue='parser.factor.4',Cue='parser.factor.5',Due='parser.factor.6',Eue='parser.atom.1',Fue='parser.atom.2',Gue='parser.atom.3',Hue='parser.atom.4',Iue='parser.atom.5',Jue='parser.cc.1',Kue='parser.cc.2',Lue='parser.cc.3',Mue='parser.cc.5',Nue='parser.cc.6',Oue='parser.cc.7',Pue='parser.cc.8',Que='parser.ope.1',Rue='parser.ope.2',Sue='parser.ope.3',Tue='parser.descape.1',Uue='parser.descape.2',Vue='parser.descape.3',Wue='parser.descape.4',Xue='parser.descape.5',Yue='parser.process.1',Zue='parser.quantifier.1',$ue='parser.quantifier.2',_ue='parser.quantifier.3',ave='parser.quantifier.4',bve='parser.quantifier.5',cve='org.eclipse.emf.common.notify',dve={415:1,672:1},eve={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1},fve={366:1,143:1},gve='index=',hve={3:1,4:1,5:1,126:1},ive={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,58:1},jve={3:1,6:1,4:1,5:1,192:1},kve={3:1,4:1,5:1,165:1,367:1},lve=';/?:@&=+$,',mve='invalid authority: ',nve='EAnnotation',ove='ETypedElement',pve='EStructuralFeature',qve='EAttribute',rve='EClassifier',sve='EEnumLiteral',tve='EGenericType',uve='EOperation',vve='EParameter',wve='EReference',xve='ETypeParameter',yve='org.eclipse.emf.ecore.util',zve={76:1},Ave={3:1,20:1,14:1,15:1,58:1,589:1,76:1,69:1,95:1},Bve='org.eclipse.emf.ecore.util.FeatureMap$Entry',Cve=8192,Dve=2048,Eve='byte',Fve='char',Gve='double',Hve='float',Ive='int',Jve='long',Kve='short',Lve='java.lang.Object',Mve={3:1,4:1,5:1,247:1},Nve={3:1,4:1,5:1,673:1},Ove={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,69:1},Pve={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,69:1,95:1},Qve='mixed',Rve='http:///org/eclipse/emf/ecore/util/ExtendedMetaData',Sve='kind',Tve={3:1,4:1,5:1,674:1},Uve={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1,76:1,69:1,95:1},Vve={20:1,28:1,52:1,14:1,15:1,58:1,69:1},Wve={47:1,125:1,279:1},Xve={72:1,332:1},Yve="The value of type '",Zve="' must be of type '",$ve=1316,_ve='http://www.eclipse.org/emf/2002/Ecore',awe=-32768,bwe='constraints',cwe='baseType',dwe='getEStructuralFeature',ewe='getFeatureID',fwe='feature',gwe='getOperationID',hwe='operation',iwe='defaultValue',jwe='eTypeParameters',kwe='isInstance',lwe='getEEnumLiteral',mwe='eContainingClass',nwe={55:1},owe={3:1,4:1,5:1,119:1},pwe='org.eclipse.emf.ecore.resource',qwe={92:1,90:1,591:1,1935:1},rwe='org.eclipse.emf.ecore.resource.impl',swe='unspecified',twe='simple',uwe='attribute',vwe='attributeWildcard',wwe='element',xwe='elementWildcard',ywe='collapse',zwe='itemType',Awe='namespace',Bwe='##targetNamespace',Cwe='whiteSpace',Dwe='wildcards',Ewe='http://www.eclipse.org/emf/2003/XMLType',Fwe='##any',Gwe='uninitialized',Hwe='The multiplicity constraint is violated',Iwe='org.eclipse.emf.ecore.xml.type',Jwe='ProcessingInstruction',Kwe='SimpleAnyType',Lwe='XMLTypeDocumentRoot',Mwe='org.eclipse.emf.ecore.xml.type.impl',Nwe='INF',Owe='processing',Pwe='ENTITIES_._base',Qwe='minLength',Rwe='ENTITY',Swe='NCName',Twe='IDREFS_._base',Uwe='integer',Vwe='token',Wwe='pattern',Xwe='[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*',Ywe='\\i\\c*',Zwe='[\\i-[:]][\\c-[:]]*',$we='nonPositiveInteger',_we='maxInclusive',axe='NMTOKEN',bxe='NMTOKENS_._base',cxe='nonNegativeInteger',dxe='minInclusive',exe='normalizedString',fxe='unsignedByte',gxe='unsignedInt',hxe='18446744073709551615',ixe='unsignedShort',jxe='processingInstruction',kxe='org.eclipse.emf.ecore.xml.type.internal',lxe=1114111,mxe='Internal Error: shorthands: \\u',nxe='xml:isDigit',oxe='xml:isWord',pxe='xml:isSpace',qxe='xml:isNameChar',rxe='xml:isInitialNameChar',sxe='09\u0660\u0669\u06F0\u06F9\u0966\u096F\u09E6\u09EF\u0A66\u0A6F\u0AE6\u0AEF\u0B66\u0B6F\u0BE7\u0BEF\u0C66\u0C6F\u0CE6\u0CEF\u0D66\u0D6F\u0E50\u0E59\u0ED0\u0ED9\u0F20\u0F29',txe='AZaz\xC0\xD6\xD8\xF6\xF8\u0131\u0134\u013E\u0141\u0148\u014A\u017E\u0180\u01C3\u01CD\u01F0\u01F4\u01F5\u01FA\u0217\u0250\u02A8\u02BB\u02C1\u0386\u0386\u0388\u038A\u038C\u038C\u038E\u03A1\u03A3\u03CE\u03D0\u03D6\u03DA\u03DA\u03DC\u03DC\u03DE\u03DE\u03E0\u03E0\u03E2\u03F3\u0401\u040C\u040E\u044F\u0451\u045C\u045E\u0481\u0490\u04C4\u04C7\u04C8\u04CB\u04CC\u04D0\u04EB\u04EE\u04F5\u04F8\u04F9\u0531\u0556\u0559\u0559\u0561\u0586\u05D0\u05EA\u05F0\u05F2\u0621\u063A\u0641\u064A\u0671\u06B7\u06BA\u06BE\u06C0\u06CE\u06D0\u06D3\u06D5\u06D5\u06E5\u06E6\u0905\u0939\u093D\u093D\u0958\u0961\u0985\u098C\u098F\u0990\u0993\u09A8\u09AA\u09B0\u09B2\u09B2\u09B6\u09B9\u09DC\u09DD\u09DF\u09E1\u09F0\u09F1\u0A05\u0A0A\u0A0F\u0A10\u0A13\u0A28\u0A2A\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59\u0A5C\u0A5E\u0A5E\u0A72\u0A74\u0A85\u0A8B\u0A8D\u0A8D\u0A8F\u0A91\u0A93\u0AA8\u0AAA\u0AB0\u0AB2\u0AB3\u0AB5\u0AB9\u0ABD\u0ABD\u0AE0\u0AE0\u0B05\u0B0C\u0B0F\u0B10\u0B13\u0B28\u0B2A\u0B30\u0B32\u0B33\u0B36\u0B39\u0B3D\u0B3D\u0B5C\u0B5D\u0B5F\u0B61\u0B85\u0B8A\u0B8E\u0B90\u0B92\u0B95\u0B99\u0B9A\u0B9C\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8\u0BAA\u0BAE\u0BB5\u0BB7\u0BB9\u0C05\u0C0C\u0C0E\u0C10\u0C12\u0C28\u0C2A\u0C33\u0C35\u0C39\u0C60\u0C61\u0C85\u0C8C\u0C8E\u0C90\u0C92\u0CA8\u0CAA\u0CB3\u0CB5\u0CB9\u0CDE\u0CDE\u0CE0\u0CE1\u0D05\u0D0C\u0D0E\u0D10\u0D12\u0D28\u0D2A\u0D39\u0D60\u0D61\u0E01\u0E2E\u0E30\u0E30\u0E32\u0E33\u0E40\u0E45\u0E81\u0E82\u0E84\u0E84\u0E87\u0E88\u0E8A\u0E8A\u0E8D\u0E8D\u0E94\u0E97\u0E99\u0E9F\u0EA1\u0EA3\u0EA5\u0EA5\u0EA7\u0EA7\u0EAA\u0EAB\u0EAD\u0EAE\u0EB0\u0EB0\u0EB2\u0EB3\u0EBD\u0EBD\u0EC0\u0EC4\u0F40\u0F47\u0F49\u0F69\u10A0\u10C5\u10D0\u10F6\u1100\u1100\u1102\u1103\u1105\u1107\u1109\u1109\u110B\u110C\u110E\u1112\u113C\u113C\u113E\u113E\u1140\u1140\u114C\u114C\u114E\u114E\u1150\u1150\u1154\u1155\u1159\u1159\u115F\u1161\u1163\u1163\u1165\u1165\u1167\u1167\u1169\u1169\u116D\u116E\u1172\u1173\u1175\u1175\u119E\u119E\u11A8\u11A8\u11AB\u11AB\u11AE\u11AF\u11B7\u11B8\u11BA\u11BA\u11BC\u11C2\u11EB\u11EB\u11F0\u11F0\u11F9\u11F9\u1E00\u1E9B\u1EA0\u1EF9\u1F00\u1F15\u1F18\u1F1D\u1F20\u1F45\u1F48\u1F4D\u1F50\u1F57\u1F59\u1F59\u1F5B\u1F5B\u1F5D\u1F5D\u1F5F\u1F7D\u1F80\u1FB4\u1FB6\u1FBC\u1FBE\u1FBE\u1FC2\u1FC4\u1FC6\u1FCC\u1FD0\u1FD3\u1FD6\u1FDB\u1FE0\u1FEC\u1FF2\u1FF4\u1FF6\u1FFC\u2126\u2126\u212A\u212B\u212E\u212E\u2180\u2182\u3007\u3007\u3021\u3029\u3041\u3094\u30A1\u30FA\u3105\u312C\u4E00\u9FA5\uAC00\uD7A3',uxe='Private Use',vxe='ASSIGNED',wxe='\x00\x7F\x80\xFF\u0100\u017F\u0180\u024F\u0250\u02AF\u02B0\u02FF\u0300\u036F\u0370\u03FF\u0400\u04FF\u0530\u058F\u0590\u05FF\u0600\u06FF\u0700\u074F\u0780\u07BF\u0900\u097F\u0980\u09FF\u0A00\u0A7F\u0A80\u0AFF\u0B00\u0B7F\u0B80\u0BFF\u0C00\u0C7F\u0C80\u0CFF\u0D00\u0D7F\u0D80\u0DFF\u0E00\u0E7F\u0E80\u0EFF\u0F00\u0FFF\u1000\u109F\u10A0\u10FF\u1100\u11FF\u1200\u137F\u13A0\u13FF\u1400\u167F\u1680\u169F\u16A0\u16FF\u1780\u17FF\u1800\u18AF\u1E00\u1EFF\u1F00\u1FFF\u2000\u206F\u2070\u209F\u20A0\u20CF\u20D0\u20FF\u2100\u214F\u2150\u218F\u2190\u21FF\u2200\u22FF\u2300\u23FF\u2400\u243F\u2440\u245F\u2460\u24FF\u2500\u257F\u2580\u259F\u25A0\u25FF\u2600\u26FF\u2700\u27BF\u2800\u28FF\u2E80\u2EFF\u2F00\u2FDF\u2FF0\u2FFF\u3000\u303F\u3040\u309F\u30A0\u30FF\u3100\u312F\u3130\u318F\u3190\u319F\u31A0\u31BF\u3200\u32FF\u3300\u33FF\u3400\u4DB5\u4E00\u9FFF\uA000\uA48F\uA490\uA4CF\uAC00\uD7A3\uE000\uF8FF\uF900\uFAFF\uFB00\uFB4F\uFB50\uFDFF\uFE20\uFE2F\uFE30\uFE4F\uFE50\uFE6F\uFE70\uFEFE\uFEFF\uFEFF\uFF00\uFFEF',xxe='UNASSIGNED',yxe={3:1,117:1},zxe='org.eclipse.emf.ecore.xml.type.util',Axe={3:1,4:1,5:1,368:1},Bxe='org.eclipse.xtext.xbase.lib',Cxe='Cannot add elements to a Range',Dxe='Cannot set elements in a Range',Exe='Cannot remove elements from a Range',Fxe='locale',Gxe='default',Hxe='user.agent';var _,_bb,Wbb,tbb=-1;$wnd.goog=$wnd.goog||{};$wnd.goog.global=$wnd.goog.global||$wnd;acb();bcb(1,null,{},nb);_.Fb=function ob(a){return mb(this,a)};_.Gb=function qb(){return this.gm};_.Hb=function sb(){return FCb(this)};_.Ib=function ub(){var a;return hdb(rb(this))+'@'+(a=tb(this)>>>0,a.toString(16))};_.equals=function(a){return this.Fb(a)};_.hashCode=function(){return this.Hb()};_.toString=function(){return this.Ib()};var xD,yD,zD;bcb(290,1,{290:1,2026:1},jdb);_.le=function kdb(a){var b;b=new jdb;b.i=4;a>1?(b.c=rdb(this,a-1)):(b.c=this);return b};_.me=function qdb(){fdb(this);return this.b};_.ne=function sdb(){return hdb(this)};_.oe=function udb(){return fdb(this),this.k};_.pe=function wdb(){return (this.i&4)!=0};_.qe=function xdb(){return (this.i&1)!=0};_.Ib=function Adb(){return idb(this)};_.i=0;var edb=1;var SI=mdb(Phe,'Object',1);var AI=mdb(Phe,'Class',290);bcb(1998,1,Qhe);var $D=mdb(Rhe,'Optional',1998);bcb(1170,1998,Qhe,xb);_.Fb=function yb(a){return a===this};_.Hb=function zb(){return 2040732332};_.Ib=function Ab(){return 'Optional.absent()'};_.Jb=function Bb(a){Qb(a);return wb(),vb};var vb;var YD=mdb(Rhe,'Absent',1170);bcb(628,1,{},Gb);var ZD=mdb(Rhe,'Joiner',628);var _D=odb(Rhe,'Predicate');bcb(582,1,{169:1,582:1,3:1,45:1},Yb);_.Mb=function ac(a){return Xb(this,a)};_.Lb=function Zb(a){return Xb(this,a)};_.Fb=function $b(a){var b;if(JD(a,582)){b=BD(a,582);return At(this.a,b.a)}return false};_.Hb=function _b(){return qmb(this.a)+306654252};_.Ib=function bc(){return Wb(this.a)};var aE=mdb(Rhe,'Predicates/AndPredicate',582);bcb(408,1998,{408:1,3:1},cc);_.Fb=function dc(a){var b;if(JD(a,408)){b=BD(a,408);return pb(this.a,b.a)}return false};_.Hb=function ec(){return 1502476572+tb(this.a)};_.Ib=function fc(){return Whe+this.a+')'};_.Jb=function gc(a){return new cc(Rb(a.Kb(this.a),'the Function passed to Optional.transform() must not return null.'))};var bE=mdb(Rhe,'Present',408);bcb(198,1,Yhe);_.Nb=function kc(a){Rrb(this,a)};_.Qb=function lc(){jc()};var MH=mdb(Zhe,'UnmodifiableIterator',198);bcb(1978,198,$he);_.Qb=function nc(){jc()};_.Rb=function mc(a){throw vbb(new bgb)};_.Wb=function oc(a){throw vbb(new bgb)};var NH=mdb(Zhe,'UnmodifiableListIterator',1978);bcb(386,1978,$he);_.Ob=function rc(){return this.c<this.d};_.Sb=function sc(){return this.c>0};_.Pb=function tc(){if(this.c>=this.d){throw vbb(new utb)}return this.Xb(this.c++)};_.Tb=function uc(){return this.c};_.Ub=function vc(){if(this.c<=0){throw vbb(new utb)}return this.Xb(--this.c)};_.Vb=function wc(){return this.c-1};_.c=0;_.d=0;var cE=mdb(Zhe,'AbstractIndexedListIterator',386);bcb(699,198,Yhe);_.Ob=function Ac(){return xc(this)};_.Pb=function Bc(){return yc(this)};_.e=1;var dE=mdb(Zhe,'AbstractIterator',699);bcb(1986,1,{224:1});_.Zb=function Hc(){var a;return a=this.f,!a?(this.f=this.ac()):a};_.Fb=function Ic(a){return hw(this,a)};_.Hb=function Jc(){return tb(this.Zb())};_.dc=function Kc(){return this.gc()==0};_.ec=function Lc(){return Ec(this)};_.Ib=function Mc(){return fcb(this.Zb())};var IE=mdb(Zhe,'AbstractMultimap',1986);bcb(726,1986,_he);_.$b=function Xc(){Nc(this)};_._b=function Yc(a){return Oc(this,a)};_.ac=function Zc(){return new ne(this,this.c)};_.ic=function $c(a){return this.hc()};_.bc=function _c(){return new zf(this,this.c)};_.jc=function ad(){return this.mc(this.hc())};_.kc=function bd(){return new Hd(this)};_.lc=function cd(){return Yj(this.c.vc().Nc(),new $g,64,this.d)};_.cc=function dd(a){return Qc(this,a)};_.fc=function gd(a){return Sc(this,a)};_.gc=function hd(){return this.d};_.mc=function jd(a){return mmb(),new lnb(a)};_.nc=function kd(){return new Dd(this)};_.oc=function ld(){return Yj(this.c.Cc().Nc(),new Fd,64,this.d)};_.pc=function md(a,b){return new dg(this,a,b,null)};_.d=0;var DE=mdb(Zhe,'AbstractMapBasedMultimap',726);bcb(1631,726,_he);_.hc=function pd(){return new Skb(this.a)};_.jc=function qd(){return mmb(),mmb(),jmb};_.cc=function sd(a){return BD(Qc(this,a),15)};_.fc=function ud(a){return BD(Sc(this,a),15)};_.Zb=function od(){return nd(this)};_.Fb=function rd(a){return hw(this,a)};_.qc=function td(a){return BD(Qc(this,a),15)};_.rc=function vd(a){return BD(Sc(this,a),15)};_.mc=function wd(a){return vmb(BD(a,15))};_.pc=function xd(a,b){return Vc(this,a,BD(b,15),null)};var eE=mdb(Zhe,'AbstractListMultimap',1631);bcb(732,1,aie);_.Nb=function zd(a){Rrb(this,a)};_.Ob=function Ad(){return this.c.Ob()||this.e.Ob()};_.Pb=function Bd(){var a;if(!this.e.Ob()){a=BD(this.c.Pb(),42);this.b=a.cd();this.a=BD(a.dd(),14);this.e=this.a.Kc()}return this.sc(this.b,this.e.Pb())};_.Qb=function Cd(){this.e.Qb();this.a.dc()&&this.c.Qb();--this.d.d};var mE=mdb(Zhe,'AbstractMapBasedMultimap/Itr',732);bcb(1099,732,aie,Dd);_.sc=function Ed(a,b){return b};var fE=mdb(Zhe,'AbstractMapBasedMultimap/1',1099);bcb(1100,1,{},Fd);_.Kb=function Gd(a){return BD(a,14).Nc()};var gE=mdb(Zhe,'AbstractMapBasedMultimap/1methodref$spliterator$Type',1100);bcb(1101,732,aie,Hd);_.sc=function Id(a,b){return new Wo(a,b)};var hE=mdb(Zhe,'AbstractMapBasedMultimap/2',1101);var DK=odb(bie,'Map');bcb(1967,1,cie);_.wc=function Td(a){stb(this,a)};_.yc=function $d(a,b,c){return ttb(this,a,b,c)};_.$b=function Od(){this.vc().$b()};_.tc=function Pd(a){return Jd(this,a)};_._b=function Qd(a){return !!Kd(this,a,false)};_.uc=function Rd(a){var b,c,d;for(c=this.vc().Kc();c.Ob();){b=BD(c.Pb(),42);d=b.dd();if(PD(a)===PD(d)||a!=null&&pb(a,d)){return true}}return false};_.Fb=function Sd(a){var b,c,d;if(a===this){return true}if(!JD(a,83)){return false}d=BD(a,83);if(this.gc()!=d.gc()){return false}for(c=d.vc().Kc();c.Ob();){b=BD(c.Pb(),42);if(!this.tc(b)){return false}}return true};_.xc=function Ud(a){return Wd(Kd(this,a,false))};_.Hb=function Xd(){return pmb(this.vc())};_.dc=function Yd(){return this.gc()==0};_.ec=function Zd(){return new Pib(this)};_.zc=function _d(a,b){throw vbb(new cgb('Put not supported on this map'))};_.Ac=function ae(a){Ld(this,a)};_.Bc=function be(a){return Wd(Kd(this,a,true))};_.gc=function ce(){return this.vc().gc()};_.Ib=function de(){return Md(this)};_.Cc=function ee(){return new $ib(this)};var sJ=mdb(bie,'AbstractMap',1967);bcb(1987,1967,cie);_.bc=function ge(){return new rf(this)};_.vc=function he(){return fe(this)};_.ec=function ie(){var a;a=this.g;return !a?(this.g=this.bc()):a};_.Cc=function je(){var a;a=this.i;return !a?(this.i=new Zv(this)):a};var bH=mdb(Zhe,'Maps/ViewCachingAbstractMap',1987);bcb(389,1987,cie,ne);_.xc=function se(a){return ke(this,a)};_.Bc=function ve(a){return le(this,a)};_.$b=function oe(){this.d==this.e.c?this.e.$b():ir(new mf(this))};_._b=function pe(a){return Gv(this.d,a)};_.Ec=function qe(){return new df(this)};_.Dc=function(){return this.Ec()};_.Fb=function re(a){return this===a||pb(this.d,a)};_.Hb=function te(){return tb(this.d)};_.ec=function ue(){return this.e.ec()};_.gc=function we(){return this.d.gc()};_.Ib=function xe(){return fcb(this.d)};var lE=mdb(Zhe,'AbstractMapBasedMultimap/AsMap',389);var KI=odb(Phe,'Iterable');bcb(28,1,die);_.Jc=function Le(a){reb(this,a)};_.Lc=function Ne(){return this.Oc()};_.Nc=function Pe(){return new Kub(this,0)};_.Oc=function Qe(){return new YAb(null,this.Nc())};_.Fc=function Ge(a){throw vbb(new cgb('Add not supported on this collection'))};_.Gc=function He(a){return ye(this,a)};_.$b=function Ie(){Ae(this)};_.Hc=function Je(a){return ze(this,a,false)};_.Ic=function Ke(a){return Be(this,a)};_.dc=function Me(){return this.gc()==0};_.Mc=function Oe(a){return ze(this,a,true)};_.Pc=function Re(){return De(this)};_.Qc=function Se(a){return Ee(this,a)};_.Ib=function Te(){return Fe(this)};var dJ=mdb(bie,'AbstractCollection',28);var LK=odb(bie,'Set');bcb(eie,28,fie);_.Nc=function Ye(){return new Kub(this,1)};_.Fb=function We(a){return Ue(this,a)};_.Hb=function Xe(){return pmb(this)};var zJ=mdb(bie,'AbstractSet',eie);bcb(1970,eie,fie);var BH=mdb(Zhe,'Sets/ImprovedAbstractSet',1970);bcb(1971,1970,fie);_.$b=function $e(){this.Rc().$b()};_.Hc=function _e(a){return Ze(this,a)};_.dc=function af(){return this.Rc().dc()};_.Mc=function bf(a){var b;if(this.Hc(a)){b=BD(a,42);return this.Rc().ec().Mc(b.cd())}return false};_.gc=function cf(){return this.Rc().gc()};var WG=mdb(Zhe,'Maps/EntrySet',1971);bcb(1097,1971,fie,df);_.Hc=function ef(a){return Ck(this.a.d.vc(),a)};_.Kc=function ff(){return new mf(this.a)};_.Rc=function gf(){return this.a};_.Mc=function hf(a){var b;if(!Ck(this.a.d.vc(),a)){return false}b=BD(a,42);Tc(this.a.e,b.cd());return true};_.Nc=function jf(){return $j(this.a.d.vc().Nc(),new kf(this.a))};var jE=mdb(Zhe,'AbstractMapBasedMultimap/AsMap/AsMapEntries',1097);bcb(1098,1,{},kf);_.Kb=function lf(a){return me(this.a,BD(a,42))};var iE=mdb(Zhe,'AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type',1098);bcb(730,1,aie,mf);_.Nb=function nf(a){Rrb(this,a)};_.Pb=function pf(){var a;return a=BD(this.b.Pb(),42),this.a=BD(a.dd(),14),me(this.c,a)};_.Ob=function of(){return this.b.Ob()};_.Qb=function qf(){Vb(!!this.a);this.b.Qb();this.c.e.d-=this.a.gc();this.a.$b();this.a=null};var kE=mdb(Zhe,'AbstractMapBasedMultimap/AsMap/AsMapIterator',730);bcb(532,1970,fie,rf);_.$b=function sf(){this.b.$b()};_.Hc=function tf(a){return this.b._b(a)};_.Jc=function uf(a){Qb(a);this.b.wc(new Xv(a))};_.dc=function vf(){return this.b.dc()};_.Kc=function wf(){return new Mv(this.b.vc().Kc())};_.Mc=function xf(a){if(this.b._b(a)){this.b.Bc(a);return true}return false};_.gc=function yf(){return this.b.gc()};var $G=mdb(Zhe,'Maps/KeySet',532);bcb(318,532,fie,zf);_.$b=function Af(){var a;ir((a=this.b.vc().Kc(),new Hf(this,a)))};_.Ic=function Bf(a){return this.b.ec().Ic(a)};_.Fb=function Cf(a){return this===a||pb(this.b.ec(),a)};_.Hb=function Df(){return tb(this.b.ec())};_.Kc=function Ef(){var a;return a=this.b.vc().Kc(),new Hf(this,a)};_.Mc=function Ff(a){var b,c;c=0;b=BD(this.b.Bc(a),14);if(b){c=b.gc();b.$b();this.a.d-=c}return c>0};_.Nc=function Gf(){return this.b.ec().Nc()};var oE=mdb(Zhe,'AbstractMapBasedMultimap/KeySet',318);bcb(731,1,aie,Hf);_.Nb=function If(a){Rrb(this,a)};_.Ob=function Jf(){return this.c.Ob()};_.Pb=function Kf(){this.a=BD(this.c.Pb(),42);return this.a.cd()};_.Qb=function Lf(){var a;Vb(!!this.a);a=BD(this.a.dd(),14);this.c.Qb();this.b.a.d-=a.gc();a.$b();this.a=null};var nE=mdb(Zhe,'AbstractMapBasedMultimap/KeySet/1',731);bcb(491,389,{83:1,161:1},Mf);_.bc=function Nf(){return this.Sc()};_.ec=function Pf(){return this.Tc()};_.Sc=function Of(){return new Yf(this.c,this.Uc())};_.Tc=function Qf(){var a;return a=this.b,!a?(this.b=this.Sc()):a};_.Uc=function Rf(){return BD(this.d,161)};var sE=mdb(Zhe,'AbstractMapBasedMultimap/SortedAsMap',491);bcb(542,491,gie,Sf);_.bc=function Tf(){return new $f(this.a,BD(BD(this.d,161),171))};_.Sc=function Uf(){return new $f(this.a,BD(BD(this.d,161),171))};_.ec=function Vf(){var a;return a=this.b,BD(!a?(this.b=new $f(this.a,BD(BD(this.d,161),171))):a,271)};_.Tc=function Wf(){var a;return a=this.b,BD(!a?(this.b=new $f(this.a,BD(BD(this.d,161),171))):a,271)};_.Uc=function Xf(){return BD(BD(this.d,161),171)};var pE=mdb(Zhe,'AbstractMapBasedMultimap/NavigableAsMap',542);bcb(490,318,hie,Yf);_.Nc=function Zf(){return this.b.ec().Nc()};var tE=mdb(Zhe,'AbstractMapBasedMultimap/SortedKeySet',490);bcb(388,490,iie,$f);var qE=mdb(Zhe,'AbstractMapBasedMultimap/NavigableKeySet',388);bcb(541,28,die,dg);_.Fc=function eg(a){var b,c;ag(this);c=this.d.dc();b=this.d.Fc(a);if(b){++this.f.d;c&&_f(this)}return b};_.Gc=function fg(a){var b,c,d;if(a.dc()){return false}d=(ag(this),this.d.gc());b=this.d.Gc(a);if(b){c=this.d.gc();this.f.d+=c-d;d==0&&_f(this)}return b};_.$b=function gg(){var a;a=(ag(this),this.d.gc());if(a==0){return}this.d.$b();this.f.d-=a;bg(this)};_.Hc=function hg(a){ag(this);return this.d.Hc(a)};_.Ic=function ig(a){ag(this);return this.d.Ic(a)};_.Fb=function jg(a){if(a===this){return true}ag(this);return pb(this.d,a)};_.Hb=function kg(){ag(this);return tb(this.d)};_.Kc=function lg(){ag(this);return new Gg(this)};_.Mc=function mg(a){var b;ag(this);b=this.d.Mc(a);if(b){--this.f.d;bg(this)}return b};_.gc=function ng(){return cg(this)};_.Nc=function og(){return ag(this),this.d.Nc()};_.Ib=function pg(){ag(this);return fcb(this.d)};var vE=mdb(Zhe,'AbstractMapBasedMultimap/WrappedCollection',541);var yK=odb(bie,'List');bcb(728,541,{20:1,28:1,14:1,15:1},qg);_.ad=function zg(a){ktb(this,a)};_.Nc=function Ag(){return ag(this),this.d.Nc()};_.Vc=function rg(a,b){var c;ag(this);c=this.d.dc();BD(this.d,15).Vc(a,b);++this.a.d;c&&_f(this)};_.Wc=function sg(a,b){var c,d,e;if(b.dc()){return false}e=(ag(this),this.d.gc());c=BD(this.d,15).Wc(a,b);if(c){d=this.d.gc();this.a.d+=d-e;e==0&&_f(this)}return c};_.Xb=function tg(a){ag(this);return BD(this.d,15).Xb(a)};_.Xc=function ug(a){ag(this);return BD(this.d,15).Xc(a)};_.Yc=function vg(){ag(this);return new Mg(this)};_.Zc=function wg(a){ag(this);return new Ng(this,a)};_.$c=function xg(a){var b;ag(this);b=BD(this.d,15).$c(a);--this.a.d;bg(this);return b};_._c=function yg(a,b){ag(this);return BD(this.d,15)._c(a,b)};_.bd=function Bg(a,b){ag(this);return Vc(this.a,this.e,BD(this.d,15).bd(a,b),!this.b?this:this.b)};var xE=mdb(Zhe,'AbstractMapBasedMultimap/WrappedList',728);bcb(1096,728,{20:1,28:1,14:1,15:1,54:1},Cg);var rE=mdb(Zhe,'AbstractMapBasedMultimap/RandomAccessWrappedList',1096);bcb(620,1,aie,Gg);_.Nb=function Ig(a){Rrb(this,a)};_.Ob=function Jg(){Fg(this);return this.b.Ob()};_.Pb=function Kg(){Fg(this);return this.b.Pb()};_.Qb=function Lg(){Eg(this)};var uE=mdb(Zhe,'AbstractMapBasedMultimap/WrappedCollection/WrappedIterator',620);bcb(729,620,jie,Mg,Ng);_.Qb=function Tg(){Eg(this)};_.Rb=function Og(a){var b;b=cg(this.a)==0;(Fg(this),BD(this.b,125)).Rb(a);++this.a.a.d;b&&_f(this.a)};_.Sb=function Pg(){return (Fg(this),BD(this.b,125)).Sb()};_.Tb=function Qg(){return (Fg(this),BD(this.b,125)).Tb()};_.Ub=function Rg(){return (Fg(this),BD(this.b,125)).Ub()};_.Vb=function Sg(){return (Fg(this),BD(this.b,125)).Vb()};_.Wb=function Ug(a){(Fg(this),BD(this.b,125)).Wb(a)};var wE=mdb(Zhe,'AbstractMapBasedMultimap/WrappedList/WrappedListIterator',729);bcb(727,541,hie,Vg);_.Nc=function Wg(){return ag(this),this.d.Nc()};var AE=mdb(Zhe,'AbstractMapBasedMultimap/WrappedSortedSet',727);bcb(1095,727,iie,Xg);var yE=mdb(Zhe,'AbstractMapBasedMultimap/WrappedNavigableSet',1095);bcb(1094,541,fie,Yg);_.Nc=function Zg(){return ag(this),this.d.Nc()};var zE=mdb(Zhe,'AbstractMapBasedMultimap/WrappedSet',1094);bcb(1103,1,{},$g);_.Kb=function _g(a){return fd(BD(a,42))};var BE=mdb(Zhe,'AbstractMapBasedMultimap/lambda$1$Type',1103);bcb(1102,1,{},ah);_.Kb=function bh(a){return new Wo(this.a,a)};var CE=mdb(Zhe,'AbstractMapBasedMultimap/lambda$2$Type',1102);var CK=odb(bie,'Map/Entry');bcb(345,1,kie);_.Fb=function dh(a){var b;if(JD(a,42)){b=BD(a,42);return Hb(this.cd(),b.cd())&&Hb(this.dd(),b.dd())}return false};_.Hb=function eh(){var a,b;a=this.cd();b=this.dd();return (a==null?0:tb(a))^(b==null?0:tb(b))};_.ed=function fh(a){throw vbb(new bgb)};_.Ib=function gh(){return this.cd()+'='+this.dd()};var EE=mdb(Zhe,lie,345);bcb(1988,28,die);_.$b=function hh(){this.fd().$b()};_.Hc=function ih(a){var b;if(JD(a,42)){b=BD(a,42);return Cc(this.fd(),b.cd(),b.dd())}return false};_.Mc=function jh(a){var b;if(JD(a,42)){b=BD(a,42);return Gc(this.fd(),b.cd(),b.dd())}return false};_.gc=function kh(){return this.fd().d};var fH=mdb(Zhe,'Multimaps/Entries',1988);bcb(733,1988,die,lh);_.Kc=function mh(){return this.a.kc()};_.fd=function nh(){return this.a};_.Nc=function oh(){return this.a.lc()};var FE=mdb(Zhe,'AbstractMultimap/Entries',733);bcb(734,733,fie,ph);_.Nc=function sh(){return this.a.lc()};_.Fb=function qh(a){return Ax(this,a)};_.Hb=function rh(){return Bx(this)};var GE=mdb(Zhe,'AbstractMultimap/EntrySet',734);bcb(735,28,die,th);_.$b=function uh(){this.a.$b()};_.Hc=function vh(a){return Dc(this.a,a)};_.Kc=function wh(){return this.a.nc()};_.gc=function xh(){return this.a.d};_.Nc=function yh(){return this.a.oc()};var HE=mdb(Zhe,'AbstractMultimap/Values',735);bcb(1989,28,{835:1,20:1,28:1,14:1});_.Jc=function Gh(a){Qb(a);Ah(this).Jc(new Xw(a))};_.Nc=function Kh(){var a;return a=Ah(this).Nc(),Yj(a,new cx,64|a.qd()&1296,this.a.d)};_.Fc=function Ch(a){zh();return true};_.Gc=function Dh(a){return Qb(this),Qb(a),JD(a,543)?Zw(BD(a,835)):!a.dc()&&fr(this,a.Kc())};_.Hc=function Eh(a){var b;return b=BD(Hv(nd(this.a),a),14),(!b?0:b.gc())>0};_.Fb=function Fh(a){return $w(this,a)};_.Hb=function Hh(){return tb(Ah(this))};_.dc=function Ih(){return Ah(this).dc()};_.Mc=function Jh(a){return Bw(this,a,1)>0};_.Ib=function Lh(){return fcb(Ah(this))};var KE=mdb(Zhe,'AbstractMultiset',1989);bcb(1991,1970,fie);_.$b=function Mh(){Nc(this.a.a)};_.Hc=function Nh(a){var b,c;if(JD(a,492)){c=BD(a,416);if(BD(c.a.dd(),14).gc()<=0){return false}b=Aw(this.a,c.a.cd());return b==BD(c.a.dd(),14).gc()}return false};_.Mc=function Oh(a){var b,c,d,e;if(JD(a,492)){c=BD(a,416);b=c.a.cd();d=BD(c.a.dd(),14).gc();if(d!=0){e=this.a;return ax(e,b,d)}}return false};var pH=mdb(Zhe,'Multisets/EntrySet',1991);bcb(1109,1991,fie,Ph);_.Kc=function Qh(){return new Lw(fe(nd(this.a.a)).Kc())};_.gc=function Rh(){return nd(this.a.a).gc()};var JE=mdb(Zhe,'AbstractMultiset/EntrySet',1109);bcb(619,726,_he);_.hc=function Uh(){return this.gd()};_.jc=function Vh(){return this.hd()};_.cc=function Yh(a){return this.jd(a)};_.fc=function $h(a){return this.kd(a)};_.Zb=function Th(){var a;return a=this.f,!a?(this.f=this.ac()):a};_.hd=function Wh(){return mmb(),mmb(),lmb};_.Fb=function Xh(a){return hw(this,a)};_.jd=function Zh(a){return BD(Qc(this,a),21)};_.kd=function _h(a){return BD(Sc(this,a),21)};_.mc=function ai(a){return mmb(),new zob(BD(a,21))};_.pc=function bi(a,b){return new Yg(this,a,BD(b,21))};var LE=mdb(Zhe,'AbstractSetMultimap',619);bcb(1657,619,_he);_.hc=function ei(){return new Hxb(this.b)};_.gd=function fi(){return new Hxb(this.b)};_.jc=function gi(){return Ix(new Hxb(this.b))};_.hd=function hi(){return Ix(new Hxb(this.b))};_.cc=function ii(a){return BD(BD(Qc(this,a),21),84)};_.jd=function ji(a){return BD(BD(Qc(this,a),21),84)};_.fc=function ki(a){return BD(BD(Sc(this,a),21),84)};_.kd=function li(a){return BD(BD(Sc(this,a),21),84)};_.mc=function mi(a){return JD(a,271)?Ix(BD(a,271)):(mmb(),new Zob(BD(a,84)))};_.Zb=function di(){var a;return a=this.f,!a?(this.f=JD(this.c,171)?new Sf(this,BD(this.c,171)):JD(this.c,161)?new Mf(this,BD(this.c,161)):new ne(this,this.c)):a};_.pc=function ni(a,b){return JD(b,271)?new Xg(this,a,BD(b,271)):new Vg(this,a,BD(b,84))};var NE=mdb(Zhe,'AbstractSortedSetMultimap',1657);bcb(1658,1657,_he);_.Zb=function pi(){var a;return a=this.f,BD(BD(!a?(this.f=JD(this.c,171)?new Sf(this,BD(this.c,171)):JD(this.c,161)?new Mf(this,BD(this.c,161)):new ne(this,this.c)):a,161),171)};_.ec=function ri(){var a;return a=this.i,BD(BD(!a?(this.i=JD(this.c,171)?new $f(this,BD(this.c,171)):JD(this.c,161)?new Yf(this,BD(this.c,161)):new zf(this,this.c)):a,84),271)};_.bc=function qi(){return JD(this.c,171)?new $f(this,BD(this.c,171)):JD(this.c,161)?new Yf(this,BD(this.c,161)):new zf(this,this.c)};var ME=mdb(Zhe,'AbstractSortedKeySortedSetMultimap',1658);bcb(2010,1,{1947:1});_.Fb=function si(a){return zy(this,a)};_.Hb=function ti(){var a;return pmb((a=this.g,!a?(this.g=new vi(this)):a))};_.Ib=function ui(){var a;return Md((a=this.f,!a?(this.f=new Rj(this)):a))};var QE=mdb(Zhe,'AbstractTable',2010);bcb(665,eie,fie,vi);_.$b=function wi(){Pi()};_.Hc=function xi(a){var b,c;if(JD(a,468)){b=BD(a,682);c=BD(Hv(Vi(this.a),Em(b.c.e,b.b)),83);return !!c&&Ck(c.vc(),new Wo(Em(b.c.c,b.a),Mi(b.c,b.b,b.a)))}return false};_.Kc=function yi(){return Ni(this.a)};_.Mc=function zi(a){var b,c;if(JD(a,468)){b=BD(a,682);c=BD(Hv(Vi(this.a),Em(b.c.e,b.b)),83);return !!c&&Dk(c.vc(),new Wo(Em(b.c.c,b.a),Mi(b.c,b.b,b.a)))}return false};_.gc=function Ai(){return Xi(this.a)};_.Nc=function Bi(){return Oi(this.a)};var OE=mdb(Zhe,'AbstractTable/CellSet',665);bcb(1928,28,die,Ci);_.$b=function Di(){Pi()};_.Hc=function Ei(a){return Qi(this.a,a)};_.Kc=function Fi(){return Zi(this.a)};_.gc=function Gi(){return Xi(this.a)};_.Nc=function Hi(){return $i(this.a)};var PE=mdb(Zhe,'AbstractTable/Values',1928);bcb(1632,1631,_he);var RE=mdb(Zhe,'ArrayListMultimapGwtSerializationDependencies',1632);bcb(513,1632,_he,Ji,Ki);_.hc=function Li(){return new Skb(this.a)};_.a=0;var SE=mdb(Zhe,'ArrayListMultimap',513);bcb(664,2010,{664:1,1947:1,3:1},_i);var cF=mdb(Zhe,'ArrayTable',664);bcb(1924,386,$he,aj);_.Xb=function bj(a){return new hj(this.a,a)};var TE=mdb(Zhe,'ArrayTable/1',1924);bcb(1925,1,{},cj);_.ld=function dj(a){return new hj(this.a,a)};var UE=mdb(Zhe,'ArrayTable/1methodref$getCell$Type',1925);bcb(2011,1,{682:1});_.Fb=function ej(a){var b;if(a===this){return true}if(JD(a,468)){b=BD(a,682);return Hb(Em(this.c.e,this.b),Em(b.c.e,b.b))&&Hb(Em(this.c.c,this.a),Em(b.c.c,b.a))&&Hb(Mi(this.c,this.b,this.a),Mi(b.c,b.b,b.a))}return false};_.Hb=function fj(){return Hlb(OC(GC(SI,1),Uhe,1,5,[Em(this.c.e,this.b),Em(this.c.c,this.a),Mi(this.c,this.b,this.a)]))};_.Ib=function gj(){return '('+Em(this.c.e,this.b)+','+Em(this.c.c,this.a)+')='+Mi(this.c,this.b,this.a)};var JH=mdb(Zhe,'Tables/AbstractCell',2011);bcb(468,2011,{468:1,682:1},hj);_.a=0;_.b=0;_.d=0;var VE=mdb(Zhe,'ArrayTable/2',468);bcb(1927,1,{},ij);_.ld=function jj(a){return Ti(this.a,a)};var WE=mdb(Zhe,'ArrayTable/2methodref$getValue$Type',1927);bcb(1926,386,$he,kj);_.Xb=function lj(a){return Ti(this.a,a)};var XE=mdb(Zhe,'ArrayTable/3',1926);bcb(1979,1967,cie);_.$b=function nj(){ir(this.kc())};_.vc=function oj(){return new Sv(this)};_.lc=function pj(){return new Mub(this.kc(),this.gc())};var YG=mdb(Zhe,'Maps/IteratorBasedAbstractMap',1979);bcb(828,1979,cie);_.$b=function tj(){throw vbb(new bgb)};_._b=function uj(a){return sn(this.c,a)};_.kc=function vj(){return new Jj(this,this.c.b.c.gc())};_.lc=function wj(){return Zj(this.c.b.c.gc(),16,new Dj(this))};_.xc=function xj(a){var b;b=BD(tn(this.c,a),19);return !b?null:this.nd(b.a)};_.dc=function yj(){return this.c.b.c.dc()};_.ec=function zj(){return Xm(this.c)};_.zc=function Aj(a,b){var c;c=BD(tn(this.c,a),19);if(!c){throw vbb(new Wdb(this.md()+' '+a+' not in '+Xm(this.c)))}return this.od(c.a,b)};_.Bc=function Bj(a){throw vbb(new bgb)};_.gc=function Cj(){return this.c.b.c.gc()};var _E=mdb(Zhe,'ArrayTable/ArrayMap',828);bcb(1923,1,{},Dj);_.ld=function Ej(a){return qj(this.a,a)};var YE=mdb(Zhe,'ArrayTable/ArrayMap/0methodref$getEntry$Type',1923);bcb(1921,345,kie,Fj);_.cd=function Gj(){return rj(this.a,this.b)};_.dd=function Hj(){return this.a.nd(this.b)};_.ed=function Ij(a){return this.a.od(this.b,a)};_.b=0;var ZE=mdb(Zhe,'ArrayTable/ArrayMap/1',1921);bcb(1922,386,$he,Jj);_.Xb=function Kj(a){return qj(this.a,a)};var $E=mdb(Zhe,'ArrayTable/ArrayMap/2',1922);bcb(1920,828,cie,Lj);_.md=function Mj(){return 'Column'};_.nd=function Nj(a){return Mi(this.b,this.a,a)};_.od=function Oj(a,b){return Wi(this.b,this.a,a,b)};_.a=0;var bF=mdb(Zhe,'ArrayTable/Row',1920);bcb(829,828,cie,Rj);_.nd=function Tj(a){return new Lj(this.a,a)};_.zc=function Uj(a,b){return BD(b,83),Pj()};_.od=function Vj(a,b){return BD(b,83),Qj()};_.md=function Sj(){return 'Row'};var aF=mdb(Zhe,'ArrayTable/RowMap',829);bcb(1120,1,pie,_j);_.qd=function ak(){return this.a.qd()&-262};_.rd=function bk(){return this.a.rd()};_.Nb=function ck(a){this.a.Nb(new gk(a,this.b))};_.sd=function dk(a){return this.a.sd(new ek(a,this.b))};var lF=mdb(Zhe,'CollectSpliterators/1',1120);bcb(1121,1,qie,ek);_.td=function fk(a){this.a.td(this.b.Kb(a))};var dF=mdb(Zhe,'CollectSpliterators/1/lambda$0$Type',1121);bcb(1122,1,qie,gk);_.td=function hk(a){this.a.td(this.b.Kb(a))};var eF=mdb(Zhe,'CollectSpliterators/1/lambda$1$Type',1122);bcb(1123,1,pie,jk);_.qd=function kk(){return this.a};_.rd=function lk(){!!this.d&&(this.b=Deb(this.b,this.d.rd()));return Deb(this.b,0)};_.Nb=function mk(a){if(this.d){this.d.Nb(a);this.d=null}this.c.Nb(new rk(this.e,a));this.b=0};_.sd=function ok(a){while(true){if(!!this.d&&this.d.sd(a)){Kbb(this.b,rie)&&(this.b=Qbb(this.b,1));return true}else{this.d=null}if(!this.c.sd(new pk(this,this.e))){return false}}};_.a=0;_.b=0;var hF=mdb(Zhe,'CollectSpliterators/1FlatMapSpliterator',1123);bcb(1124,1,qie,pk);_.td=function qk(a){ik(this.a,this.b,a)};var fF=mdb(Zhe,'CollectSpliterators/1FlatMapSpliterator/lambda$0$Type',1124);bcb(1125,1,qie,rk);_.td=function sk(a){nk(this.b,this.a,a)};var gF=mdb(Zhe,'CollectSpliterators/1FlatMapSpliterator/lambda$1$Type',1125);bcb(1117,1,pie,tk);_.qd=function uk(){return 16464|this.b};_.rd=function vk(){return this.a.rd()};_.Nb=function wk(a){this.a.xe(new Ak(a,this.c))};_.sd=function xk(a){return this.a.ye(new yk(a,this.c))};_.b=0;var kF=mdb(Zhe,'CollectSpliterators/1WithCharacteristics',1117);bcb(1118,1,sie,yk);_.ud=function zk(a){this.a.td(this.b.ld(a))};var iF=mdb(Zhe,'CollectSpliterators/1WithCharacteristics/lambda$0$Type',1118);bcb(1119,1,sie,Ak);_.ud=function Bk(a){this.a.td(this.b.ld(a))};var jF=mdb(Zhe,'CollectSpliterators/1WithCharacteristics/lambda$1$Type',1119);bcb(245,1,tie);_.wd=function Hk(a){return this.vd(BD(a,245))};_.vd=function Gk(a){var b;if(a==(_k(),$k)){return 1}if(a==(Lk(),Kk)){return -1}b=(ex(),Fcb(this.a,a.a));if(b!=0){return b}return JD(this,519)==JD(a,519)?0:JD(this,519)?1:-1};_.zd=function Ik(){return this.a};_.Fb=function Jk(a){return Ek(this,a)};var qF=mdb(Zhe,'Cut',245);bcb(1761,245,tie,Mk);_.vd=function Nk(a){return a==this?0:1};_.xd=function Ok(a){throw vbb(new xcb)};_.yd=function Pk(a){a.a+='+\u221E)'};_.zd=function Qk(){throw vbb(new Zdb(uie))};_.Hb=function Rk(){return Zfb(),kCb(this)};_.Ad=function Sk(a){return false};_.Ib=function Tk(){return '+\u221E'};var Kk;var mF=mdb(Zhe,'Cut/AboveAll',1761);bcb(519,245,{245:1,519:1,3:1,35:1},Uk);_.xd=function Vk(a){Pfb((a.a+='(',a),this.a)};_.yd=function Wk(a){Kfb(Pfb(a,this.a),93)};_.Hb=function Xk(){return ~tb(this.a)};_.Ad=function Yk(a){return ex(),Fcb(this.a,a)<0};_.Ib=function Zk(){return '/'+this.a+'\\'};var nF=mdb(Zhe,'Cut/AboveValue',519);bcb(1760,245,tie,al);_.vd=function bl(a){return a==this?0:-1};_.xd=function cl(a){a.a+='(-\u221E'};_.yd=function dl(a){throw vbb(new xcb)};_.zd=function el(){throw vbb(new Zdb(uie))};_.Hb=function fl(){return Zfb(),kCb(this)};_.Ad=function gl(a){return true};_.Ib=function hl(){return '-\u221E'};var $k;var oF=mdb(Zhe,'Cut/BelowAll',1760);bcb(1762,245,tie,il);_.xd=function jl(a){Pfb((a.a+='[',a),this.a)};_.yd=function kl(a){Kfb(Pfb(a,this.a),41)};_.Hb=function ll(){return tb(this.a)};_.Ad=function ml(a){return ex(),Fcb(this.a,a)<=0};_.Ib=function nl(){return '\\'+this.a+'/'};var pF=mdb(Zhe,'Cut/BelowValue',1762);bcb(537,1,vie);_.Jc=function ql(a){reb(this,a)};_.Ib=function rl(){return tr(BD(Rb(this,'use Optional.orNull() instead of Optional.or(null)'),20).Kc())};var uF=mdb(Zhe,'FluentIterable',537);bcb(433,537,vie,sl);_.Kc=function tl(){return new Sr(ur(this.a.Kc(),new Sq))};var rF=mdb(Zhe,'FluentIterable/2',433);bcb(1046,537,vie,vl);_.Kc=function wl(){return ul(this)};var tF=mdb(Zhe,'FluentIterable/3',1046);bcb(708,386,$he,xl);_.Xb=function yl(a){return this.a[a].Kc()};var sF=mdb(Zhe,'FluentIterable/3/1',708);bcb(1972,1,{});_.Ib=function zl(){return fcb(this.Bd().b)};var BF=mdb(Zhe,'ForwardingObject',1972);bcb(1973,1972,wie);_.Bd=function Fl(){return this.Cd()};_.Jc=function Gl(a){reb(this,a)};_.Lc=function Jl(){return this.Oc()};_.Nc=function Ml(){return new Kub(this,0)};_.Oc=function Nl(){return new YAb(null,this.Nc())};_.Fc=function Al(a){return this.Cd(),enb()};_.Gc=function Bl(a){return this.Cd(),fnb()};_.$b=function Cl(){this.Cd(),gnb()};_.Hc=function Dl(a){return this.Cd().Hc(a)};_.Ic=function El(a){return this.Cd().Ic(a)};_.dc=function Hl(){return this.Cd().b.dc()};_.Kc=function Il(){return this.Cd().Kc()};_.Mc=function Kl(a){return this.Cd(),jnb()};_.gc=function Ll(){return this.Cd().b.gc()};_.Pc=function Ol(){return this.Cd().Pc()};_.Qc=function Pl(a){return this.Cd().Qc(a)};var vF=mdb(Zhe,'ForwardingCollection',1973);bcb(1980,28,xie);_.Kc=function Xl(){return this.Ed()};_.Fc=function Sl(a){throw vbb(new bgb)};_.Gc=function Tl(a){throw vbb(new bgb)};_.$b=function Ul(){throw vbb(new bgb)};_.Hc=function Vl(a){return a!=null&&ze(this,a,false)};_.Dd=function Wl(){switch(this.gc()){case 0:return im(),im(),hm;case 1:return im(),new my(Qb(this.Ed().Pb()));default:return new px(this,this.Pc());}};_.Mc=function Yl(a){throw vbb(new bgb)};var WF=mdb(Zhe,'ImmutableCollection',1980);bcb(712,1980,xie,Zl);_.Kc=function cm(){return vr(this.a.Kc())};_.Hc=function $l(a){return a!=null&&this.a.Hc(a)};_.Ic=function _l(a){return this.a.Ic(a)};_.dc=function am(){return this.a.dc()};_.Ed=function bm(){return vr(this.a.Kc())};_.gc=function dm(){return this.a.gc()};_.Pc=function em(){return this.a.Pc()};_.Qc=function fm(a){return this.a.Qc(a)};_.Ib=function gm(){return fcb(this.a)};var wF=mdb(Zhe,'ForwardingImmutableCollection',712);bcb(152,1980,yie);_.Kc=function sm(){return this.Ed()};_.Yc=function tm(){return this.Fd(0)};_.Zc=function vm(a){return this.Fd(a)};_.ad=function zm(a){ktb(this,a)};_.Nc=function Am(){return new Kub(this,16)};_.bd=function Cm(a,b){return this.Gd(a,b)};_.Vc=function lm(a,b){throw vbb(new bgb)};_.Wc=function mm(a,b){throw vbb(new bgb)};_.Fb=function om(a){return Ju(this,a)};_.Hb=function pm(){return Ku(this)};_.Xc=function qm(a){return a==null?-1:Lu(this,a)};_.Ed=function rm(){return this.Fd(0)};_.Fd=function um(a){return jm(this,a)};_.$c=function xm(a){throw vbb(new bgb)};_._c=function ym(a,b){throw vbb(new bgb)};_.Gd=function Bm(a,b){var c;return Dm((c=new $u(this),new Jib(c,a,b)))};var hm;var _F=mdb(Zhe,'ImmutableList',152);bcb(2006,152,yie);_.Kc=function Nm(){return vr(this.Hd().Kc())};_.bd=function Qm(a,b){return Dm(this.Hd().bd(a,b))};_.Hc=function Fm(a){return a!=null&&this.Hd().Hc(a)};_.Ic=function Gm(a){return this.Hd().Ic(a)};_.Fb=function Hm(a){return pb(this.Hd(),a)};_.Xb=function Im(a){return Em(this,a)};_.Hb=function Jm(){return tb(this.Hd())};_.Xc=function Km(a){return this.Hd().Xc(a)};_.dc=function Lm(){return this.Hd().dc()};_.Ed=function Mm(){return vr(this.Hd().Kc())};_.gc=function Om(){return this.Hd().gc()};_.Gd=function Pm(a,b){return Dm(this.Hd().bd(a,b))};_.Pc=function Rm(){return this.Hd().Qc(KC(SI,Uhe,1,this.Hd().gc(),5,1))};_.Qc=function Sm(a){return this.Hd().Qc(a)};_.Ib=function Tm(){return fcb(this.Hd())};var xF=mdb(Zhe,'ForwardingImmutableList',2006);bcb(714,1,Aie);_.vc=function cn(){return Wm(this)};_.wc=function en(a){stb(this,a)};_.ec=function jn(){return Xm(this)};_.yc=function kn(a,b,c){return ttb(this,a,b,c)};_.Cc=function rn(){return this.Ld()};_.$b=function Zm(){throw vbb(new bgb)};_._b=function $m(a){return this.xc(a)!=null};_.uc=function _m(a){return this.Ld().Hc(a)};_.Jd=function an(){return new jq(this)};_.Kd=function bn(){return new sq(this)};_.Fb=function dn(a){return Dv(this,a)};_.Hb=function gn(){return Wm(this).Hb()};_.dc=function hn(){return this.gc()==0};_.zc=function nn(a,b){return Ym()};_.Bc=function on(a){throw vbb(new bgb)};_.Ib=function pn(){return Jv(this)};_.Ld=function qn(){if(this.e){return this.e}return this.e=this.Kd()};_.c=null;_.d=null;_.e=null;var Um;var iG=mdb(Zhe,'ImmutableMap',714);bcb(715,714,Aie);_._b=function vn(a){return sn(this,a)};_.uc=function wn(a){return dob(this.b,a)};_.Id=function xn(){return Vn(new Ln(this))};_.Jd=function yn(){return Vn(gob(this.b))};_.Kd=function zn(){return Ql(),new Zl(hob(this.b))};_.Fb=function An(a){return fob(this.b,a)};_.xc=function Bn(a){return tn(this,a)};_.Hb=function Cn(){return tb(this.b.c)};_.dc=function Dn(){return this.b.c.dc()};_.gc=function En(){return this.b.c.gc()};_.Ib=function Fn(){return fcb(this.b.c)};var zF=mdb(Zhe,'ForwardingImmutableMap',715);bcb(1974,1973,Bie);_.Bd=function Gn(){return this.Md()};_.Cd=function Hn(){return this.Md()};_.Nc=function Kn(){return new Kub(this,1)};_.Fb=function In(a){return a===this||this.Md().Fb(a)};_.Hb=function Jn(){return this.Md().Hb()};var CF=mdb(Zhe,'ForwardingSet',1974);bcb(1069,1974,Bie,Ln);_.Bd=function Nn(){return eob(this.a.b)};_.Cd=function On(){return eob(this.a.b)};_.Hc=function Mn(b){if(JD(b,42)&&BD(b,42).cd()==null){return false}try{return Dob(eob(this.a.b),b)}catch(a){a=ubb(a);if(JD(a,205)){return false}else throw vbb(a)}};_.Md=function Pn(){return eob(this.a.b)};_.Qc=function Qn(a){var b;b=Eob(eob(this.a.b),a);eob(this.a.b).b.gc()<b.length&&NC(b,eob(this.a.b).b.gc(),null);return b};var yF=mdb(Zhe,'ForwardingImmutableMap/1',1069);bcb(1981,1980,Cie);_.Kc=function Tn(){return this.Ed()};_.Nc=function Un(){return new Kub(this,1)};_.Fb=function Rn(a){return Ax(this,a)};_.Hb=function Sn(){return Bx(this)};var jG=mdb(Zhe,'ImmutableSet',1981);bcb(703,1981,Cie);_.Kc=function ao(){return vr(new Dnb(this.a.b.Kc()))};_.Hc=function Xn(a){return a!=null&&hnb(this.a,a)};_.Ic=function Yn(a){return inb(this.a,a)};_.Hb=function Zn(){return tb(this.a.b)};_.dc=function $n(){return this.a.b.dc()};_.Ed=function _n(){return vr(new Dnb(this.a.b.Kc()))};_.gc=function bo(){return this.a.b.gc()};_.Pc=function co(){return this.a.b.Pc()};_.Qc=function eo(a){return knb(this.a,a)};_.Ib=function fo(){return fcb(this.a.b)};var AF=mdb(Zhe,'ForwardingImmutableSet',703);bcb(1975,1974,Die);_.Bd=function go(){return this.b};_.Cd=function ho(){return this.b};_.Md=function io(){return this.b};_.Nc=function jo(){return new Rub(this)};var DF=mdb(Zhe,'ForwardingSortedSet',1975);bcb(533,1979,Aie,wo);_.Ac=function Fo(a){Ld(this,a)};_.Cc=function Io(){var a;return a=this.d,new up(!a?(this.d=new ap(this)):a)};_.$b=function xo(){ko(this)};_._b=function yo(a){return !!uo(this,a,Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15))))};_.uc=function zo(a){return lo(this,a)};_.kc=function Ao(){return new Qo(this,this)};_.wc=function Bo(a){no(this,a)};_.xc=function Co(a){return oo(this,a)};_.ec=function Do(){return new Bp(this)};_.zc=function Eo(a,b){return ro(this,a,b)};_.Bc=function Go(a){var b;b=uo(this,a,Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15))));if(!b){return null}else{mo(this,b);b.e=null;b.c=null;return b.i}};_.gc=function Ho(){return this.i};_.pd=function Jo(){var a;return a=this.d,new up(!a?(this.d=new ap(this)):a)};_.f=0;_.g=0;_.i=0;var QF=mdb(Zhe,'HashBiMap',533);bcb(534,1,aie);_.Nb=function Mo(a){Rrb(this,a)};_.Ob=function No(){return Ko(this)};_.Pb=function Oo(){var a;if(!Ko(this)){throw vbb(new utb)}a=this.c;this.c=a.c;this.f=a;--this.d;return this.Nd(a)};_.Qb=function Po(){if(this.e.g!=this.b){throw vbb(new Apb)}Vb(!!this.f);mo(this.e,this.f);this.b=this.e.g;this.f=null};_.b=0;_.d=0;_.f=null;var NF=mdb(Zhe,'HashBiMap/Itr',534);bcb(1011,534,aie,Qo);_.Nd=function Ro(a){return new So(this,a)};var FF=mdb(Zhe,'HashBiMap/1',1011);bcb(1012,345,kie,So);_.cd=function To(){return this.a.g};_.dd=function Uo(){return this.a.i};_.ed=function Vo(a){var b,c,d;c=this.a.i;d=Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15)));if(d==this.a.f&&(PD(a)===PD(c)||a!=null&&pb(a,c))){return a}Nb(!vo(this.b.a,a,d),a);mo(this.b.a,this.a);b=new $o(this.a.g,this.a.a,a,d);po(this.b.a,b,this.a);this.a.e=null;this.a.c=null;this.b.b=this.b.a.g;this.b.f==this.a&&(this.b.f=b);this.a=b;return c};var EF=mdb(Zhe,'HashBiMap/1/MapEntry',1012);bcb(238,345,{345:1,238:1,3:1,42:1},Wo);_.cd=function Xo(){return this.g};_.dd=function Yo(){return this.i};_.ed=function Zo(a){throw vbb(new bgb)};var XF=mdb(Zhe,'ImmutableEntry',238);bcb(317,238,{345:1,317:1,238:1,3:1,42:1},$o);_.a=0;_.f=0;var GF=mdb(Zhe,'HashBiMap/BiEntry',317);bcb(610,1979,Aie,ap);_.Ac=function jp(a){Ld(this,a)};_.Cc=function mp(){return new Bp(this.a)};_.$b=function bp(){ko(this.a)};_._b=function cp(a){return lo(this.a,a)};_.kc=function dp(){return new op(this,this.a)};_.wc=function ep(a){Qb(a);no(this.a,new zp(a))};_.xc=function fp(a){return _o(this,a)};_.ec=function gp(){return new up(this)};_.zc=function ip(a,b){return so(this.a,a,b,false)};_.Bc=function kp(a){var b;b=vo(this.a,a,Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15))));if(!b){return null}else{mo(this.a,b);b.e=null;b.c=null;return b.g}};_.gc=function lp(){return this.a.i};_.pd=function np(){return new Bp(this.a)};var MF=mdb(Zhe,'HashBiMap/Inverse',610);bcb(1008,534,aie,op);_.Nd=function pp(a){return new qp(this,a)};var IF=mdb(Zhe,'HashBiMap/Inverse/1',1008);bcb(1009,345,kie,qp);_.cd=function rp(){return this.a.i};_.dd=function sp(){return this.a.g};_.ed=function tp(a){var b,c,d;d=this.a.g;b=Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15)));if(b==this.a.a&&(PD(a)===PD(d)||a!=null&&pb(a,d))){return a}Nb(!uo(this.b.a.a,a,b),a);mo(this.b.a.a,this.a);c=new $o(a,b,this.a.i,this.a.f);this.a=c;po(this.b.a.a,c,null);this.b.b=this.b.a.a.g;return d};var HF=mdb(Zhe,'HashBiMap/Inverse/1/InverseEntry',1009);bcb(611,532,fie,up);_.Kc=function vp(){return new xp(this.a.a)};_.Mc=function wp(a){var b;b=vo(this.a.a,a,Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15))));if(!b){return false}else{mo(this.a.a,b);return true}};var KF=mdb(Zhe,'HashBiMap/Inverse/InverseKeySet',611);bcb(1007,534,aie,xp);_.Nd=function yp(a){return a.i};var JF=mdb(Zhe,'HashBiMap/Inverse/InverseKeySet/1',1007);bcb(1010,1,{},zp);_.Od=function Ap(a,b){hp(this.a,a,b)};var LF=mdb(Zhe,'HashBiMap/Inverse/lambda$0$Type',1010);bcb(609,532,fie,Bp);_.Kc=function Cp(){return new Ep(this.a)};_.Mc=function Dp(a){var b;b=uo(this.a,a,Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15))));if(!b){return false}else{mo(this.a,b);b.e=null;b.c=null;return true}};var PF=mdb(Zhe,'HashBiMap/KeySet',609);bcb(1006,534,aie,Ep);_.Nd=function Fp(a){return a.g};var OF=mdb(Zhe,'HashBiMap/KeySet/1',1006);bcb(1093,619,_he);var RF=mdb(Zhe,'HashMultimapGwtSerializationDependencies',1093);bcb(265,1093,_he,Hp);_.hc=function Ip(){return new Uqb(Cv(this.a))};_.gd=function Jp(){return new Uqb(Cv(this.a))};_.a=2;var SF=mdb(Zhe,'HashMultimap',265);bcb(1999,152,yie);_.Hc=function Mp(a){return this.Pd().Hc(a)};_.dc=function Np(){return this.Pd().dc()};_.gc=function Op(){return this.Pd().gc()};var TF=mdb(Zhe,'ImmutableAsList',1999);bcb(1931,715,Aie);_.Ld=function Qp(){return Ql(),new oy(this.a)};_.Cc=function Rp(){return Ql(),new oy(this.a)};_.pd=function Sp(){return Ql(),new oy(this.a)};var UF=mdb(Zhe,'ImmutableBiMap',1931);bcb(1977,1,{});var VF=mdb(Zhe,'ImmutableCollection/Builder',1977);bcb(1022,703,Cie,Tp);var YF=mdb(Zhe,'ImmutableEnumSet',1022);bcb(969,386,$he,Vp);_.Xb=function Wp(a){return this.a.Xb(a)};var ZF=mdb(Zhe,'ImmutableList/1',969);bcb(968,1977,{},Xp);var $F=mdb(Zhe,'ImmutableList/Builder',968);bcb(614,198,Yhe,Yp);_.Ob=function Zp(){return this.a.Ob()};_.Pb=function $p(){return BD(this.a.Pb(),42).cd()};var aG=mdb(Zhe,'ImmutableMap/1',614);bcb(1041,1,{},_p);_.Kb=function aq(a){return BD(a,42).cd()};var bG=mdb(Zhe,'ImmutableMap/2methodref$getKey$Type',1041);bcb(1040,1,{},cq);var cG=mdb(Zhe,'ImmutableMap/Builder',1040);bcb(2000,1981,Cie);_.Kc=function gq(){var a;return a=Wm(this.a).Ed(),new Yp(a)};_.Dd=function dq(){return new Fq(this)};_.Jc=function eq(a){var b,c;Qb(a);c=this.gc();for(b=0;b<c;b++){a.td(BD(Rl(Wm(this.a)).Xb(b),42).cd())}};_.Ed=function fq(){var a;return (a=this.c,!a?(this.c=new Fq(this)):a).Ed()};_.Nc=function hq(){return Zj(this.gc(),1296,new Dq(this))};var mG=mdb(Zhe,'IndexedImmutableSet',2000);bcb(1180,2000,Cie,jq);_.Kc=function nq(){var a;return a=Wm(this.a).Ed(),new Yp(a)};_.Hc=function kq(a){return this.a._b(a)};_.Jc=function lq(a){Qb(a);stb(this.a,new qq(a))};_.Ed=function mq(){var a;return a=Wm(this.a).Ed(),new Yp(a)};_.gc=function oq(){return this.a.gc()};_.Nc=function pq(){return $j(Wm(this.a).Nc(),new _p)};var eG=mdb(Zhe,'ImmutableMapKeySet',1180);bcb(1181,1,{},qq);_.Od=function rq(a,b){Ql();this.a.td(a)};var dG=mdb(Zhe,'ImmutableMapKeySet/lambda$0$Type',1181);bcb(1178,1980,xie,sq);_.Kc=function vq(){return new Aq(this)};_.Hc=function tq(a){return a!=null&&jr(new Aq(this),a)};_.Ed=function uq(){return new Aq(this)};_.gc=function wq(){return this.a.gc()};_.Nc=function xq(){return $j(Wm(this.a).Nc(),new yq)};var hG=mdb(Zhe,'ImmutableMapValues',1178);bcb(1179,1,{},yq);_.Kb=function zq(a){return BD(a,42).dd()};var fG=mdb(Zhe,'ImmutableMapValues/0methodref$getValue$Type',1179);bcb(626,198,Yhe,Aq);_.Ob=function Bq(){return this.a.Ob()};_.Pb=function Cq(){return BD(this.a.Pb(),42).dd()};var gG=mdb(Zhe,'ImmutableMapValues/1',626);bcb(1182,1,{},Dq);_.ld=function Eq(a){return iq(this.a,a)};var kG=mdb(Zhe,'IndexedImmutableSet/0methodref$get$Type',1182);bcb(752,1999,yie,Fq);_.Pd=function Gq(){return this.a};_.Xb=function Hq(a){return iq(this.a,a)};_.gc=function Iq(){return this.a.a.gc()};var lG=mdb(Zhe,'IndexedImmutableSet/1',752);bcb(44,1,{},Sq);_.Kb=function Tq(a){return BD(a,20).Kc()};_.Fb=function Uq(a){return this===a};var nG=mdb(Zhe,'Iterables/10',44);bcb(1042,537,vie,Wq);_.Jc=function Xq(a){Qb(a);this.b.Jc(new $q(this.a,a))};_.Kc=function Yq(){return Vq(this)};var pG=mdb(Zhe,'Iterables/4',1042);bcb(1043,1,qie,$q);_.td=function _q(a){Zq(this.b,this.a,a)};var oG=mdb(Zhe,'Iterables/4/lambda$0$Type',1043);bcb(1044,537,vie,ar);_.Jc=function br(a){Qb(a);reb(this.a,new dr(a,this.b))};_.Kc=function cr(){return ur(new Fyd(this.a),this.b)};var rG=mdb(Zhe,'Iterables/5',1044);bcb(1045,1,qie,dr);_.td=function er(a){this.a.td(Gfd(a))};var qG=mdb(Zhe,'Iterables/5/lambda$0$Type',1045);bcb(1071,198,Yhe,wr);_.Ob=function xr(){return this.a.Ob()};_.Pb=function yr(){return this.a.Pb()};var sG=mdb(Zhe,'Iterators/1',1071);bcb(1072,699,Yhe,zr);_.Yb=function Ar(){var a;while(this.b.Ob()){a=this.b.Pb();if(this.a.Lb(a)){return a}}return this.e=2,null};var tG=mdb(Zhe,'Iterators/5',1072);bcb(487,1,aie);_.Nb=function Cr(a){Rrb(this,a)};_.Ob=function Dr(){return this.b.Ob()};_.Pb=function Er(){return this.Qd(this.b.Pb())};_.Qb=function Fr(){this.b.Qb()};var KH=mdb(Zhe,'TransformedIterator',487);bcb(1073,487,aie,Gr);_.Qd=function Hr(a){return this.a.Kb(a)};var uG=mdb(Zhe,'Iterators/6',1073);bcb(717,198,Yhe,Ir);_.Ob=function Jr(){return !this.a};_.Pb=function Kr(){if(this.a){throw vbb(new utb)}this.a=true;return this.b};_.a=false;var vG=mdb(Zhe,'Iterators/9',717);bcb(1070,386,$he,Nr);_.Xb=function Or(a){return this.a[this.b+a]};_.b=0;var Lr;var wG=mdb(Zhe,'Iterators/ArrayItr',1070);bcb(39,1,{39:1,47:1},Sr);_.Nb=function Tr(a){Rrb(this,a)};_.Ob=function Ur(){return Qr(this)};_.Pb=function Vr(){return Rr(this)};_.Qb=function Wr(){Vb(!!this.c);this.c.Qb();this.c=null};var xG=mdb(Zhe,'Iterators/ConcatenatedIterator',39);bcb(22,1,{3:1,35:1,22:1});_.wd=function _r(a){return Xr(this,BD(a,22))};_.Fb=function bs(a){return this===a};_.Hb=function cs(){return FCb(this)};_.Ib=function ds(){return Zr(this)};_.g=0;var CI=mdb(Phe,'Enum',22);bcb(538,22,{538:1,3:1,35:1,22:1,47:1},is);_.Nb=function js(a){Rrb(this,a)};_.Ob=function ks(){return false};_.Pb=function ls(){throw vbb(new utb)};_.Qb=function ms(){Vb(false)};var gs;var yG=ndb(Zhe,'Iterators/EmptyModifiableIterator',538,CI,os,ns);var ps;bcb(1834,619,_he);var EG=mdb(Zhe,'LinkedHashMultimapGwtSerializationDependencies',1834);bcb(1835,1834,_he,ss);_.hc=function us(){return new Asb(Cv(this.b))};_.$b=function ts(){Nc(this);As(this.a,this.a)};_.gd=function vs(){return new Asb(Cv(this.b))};_.ic=function ws(a){return new Ss(this,a,this.b)};_.kc=function xs(){return new Hs(this)};_.lc=function ys(){var a;return new Kub((a=this.g,BD(!a?(this.g=new ph(this)):a,21)),17)};_.ec=function zs(){var a;return a=this.i,!a?(this.i=new zf(this,this.c)):a};_.nc=function Cs(){return new Ov(new Hs(this))};_.oc=function Ds(){var a;return $j(new Kub((a=this.g,BD(!a?(this.g=new ph(this)):a,21)),17),new Es)};_.b=2;var FG=mdb(Zhe,'LinkedHashMultimap',1835);bcb(1838,1,{},Es);_.Kb=function Fs(a){return BD(a,42).dd()};var zG=mdb(Zhe,'LinkedHashMultimap/0methodref$getValue$Type',1838);bcb(824,1,aie,Hs);_.Nb=function Is(a){Rrb(this,a)};_.Pb=function Ks(){return Gs(this)};_.Ob=function Js(){return this.a!=this.b.a};_.Qb=function Ls(){Vb(!!this.c);Gc(this.b,this.c.g,this.c.i);this.c=null};var AG=mdb(Zhe,'LinkedHashMultimap/1',824);bcb(330,238,{345:1,238:1,330:1,2020:1,3:1,42:1},Ms);_.Rd=function Ns(){return this.f};_.Sd=function Os(a){this.c=a};_.Td=function Ps(a){this.f=a};_.d=0;var BG=mdb(Zhe,'LinkedHashMultimap/ValueEntry',330);bcb(1836,1970,{2020:1,20:1,28:1,14:1,21:1},Ss);_.Fc=function Ts(a){var b,c,d,e,f;f=Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15)));b=f&this.b.length-1;e=this.b[b];for(c=e;c;c=c.a){if(c.d==f&&Hb(c.i,a)){return false}}d=new Ms(this.c,a,f,e);Bs(this.d,d);d.f=this;this.d=d;As(this.g.a.b,d);As(d,this.g.a);this.b[b]=d;++this.f;++this.e;Qs(this);return true};_.$b=function Us(){var a,b;Alb(this.b,null);this.f=0;for(a=this.a;a!=this;a=a.Rd()){b=BD(a,330);As(b.b,b.e)}this.a=this;this.d=this;++this.e};_.Hc=function Vs(a){var b,c;c=Tbb(Ibb(Eie,keb(Tbb(Ibb(a==null?0:tb(a),Fie)),15)));for(b=this.b[c&this.b.length-1];b;b=b.a){if(b.d==c&&Hb(b.i,a)){return true}}return false};_.Jc=function Ws(a){var b;Qb(a);for(b=this.a;b!=this;b=b.Rd()){a.td(BD(b,330).i)}};_.Rd=function Xs(){return this.a};_.Kc=function Ys(){return new ct(this)};_.Mc=function Zs(a){return Rs(this,a)};_.Sd=function $s(a){this.d=a};_.Td=function _s(a){this.a=a};_.gc=function at(){return this.f};_.e=0;_.f=0;var DG=mdb(Zhe,'LinkedHashMultimap/ValueSet',1836);bcb(1837,1,aie,ct);_.Nb=function dt(a){Rrb(this,a)};_.Ob=function et(){return bt(this),this.b!=this.c};_.Pb=function ft(){var a,b;bt(this);if(this.b==this.c){throw vbb(new utb)}a=BD(this.b,330);b=a.i;this.d=a;this.b=a.f;return b};_.Qb=function gt(){bt(this);Vb(!!this.d);Rs(this.c,this.d.i);this.a=this.c.e;this.d=null};_.a=0;var CG=mdb(Zhe,'LinkedHashMultimap/ValueSet/1',1837);bcb(766,1986,_he,mt);_.Zb=function nt(){var a;return a=this.f,!a?(this.f=new jw(this)):a};_.Fb=function tt(a){return hw(this,a)};_.cc=function ut(a){return new bu(this,a)};_.fc=function xt(a){return kt(this,a)};_.$b=function pt(){it(this)};_._b=function qt(a){return jt(this,a)};_.ac=function rt(){return new jw(this)};_.bc=function st(){return new eu(this)};_.qc=function vt(a){return new bu(this,a)};_.dc=function wt(){return !this.a};_.rc=function yt(a){return kt(this,a)};_.gc=function zt(){return this.d};_.c=0;_.d=0;var MG=mdb(Zhe,'LinkedListMultimap',766);bcb(52,28,Lie);_.ad=function Pt(a){ktb(this,a)};_.Nc=function Qt(){return new Kub(this,16)};_.Vc=function Ct(a,b){throw vbb(new cgb('Add not supported on this list'))};_.Fc=function Dt(a){this.Vc(this.gc(),a);return true};_.Wc=function Et(a,b){var c,d,e;uCb(b);c=false;for(e=b.Kc();e.Ob();){d=e.Pb();this.Vc(a++,d);c=true}return c};_.$b=function Ft(){this.Ud(0,this.gc())};_.Fb=function Gt(a){return At(this,a)};_.Hb=function Ht(){return qmb(this)};_.Xc=function It(a){return Bt(this,a)};_.Kc=function Jt(){return new vib(this)};_.Yc=function Kt(){return this.Zc(0)};_.Zc=function Lt(a){return new Bib(this,a)};_.$c=function Mt(a){throw vbb(new cgb('Remove not supported on this list'))};_.Ud=function Nt(a,b){var c,d;d=this.Zc(a);for(c=a;c<b;++c){d.Pb();d.Qb()}};_._c=function Ot(a,b){throw vbb(new cgb('Set not supported on this list'))};_.bd=function Rt(a,b){return new Jib(this,a,b)};_.j=0;var kJ=mdb(bie,'AbstractList',52);bcb(1964,52,Lie);_.Vc=function Wt(a,b){St(this,a,b)};_.Wc=function Xt(a,b){return Tt(this,a,b)};_.Xb=function Yt(a){return Ut(this,a)};_.Kc=function Zt(){return this.Zc(0)};_.$c=function $t(a){return Vt(this,a)};_._c=function _t(b,c){var d,e;d=this.Zc(b);try{e=d.Pb();d.Wb(c);return e}catch(a){a=ubb(a);if(JD(a,109)){throw vbb(new qcb("Can't set element "+b))}else throw vbb(a)}};var yJ=mdb(bie,'AbstractSequentialList',1964);bcb(636,1964,Lie,bu);_.Zc=function cu(a){return au(this,a)};_.gc=function du(){var a;a=BD(Ohb(this.a.b,this.b),283);return !a?0:a.a};var HG=mdb(Zhe,'LinkedListMultimap/1',636);bcb(1297,1970,fie,eu);_.Hc=function fu(a){return jt(this.a,a)};_.Kc=function gu(){return new ku(this.a)};_.Mc=function hu(a){return !kt(this.a,a).a.dc()};_.gc=function iu(){return Vhb(this.a.b)};var GG=mdb(Zhe,'LinkedListMultimap/1KeySetImpl',1297);bcb(1296,1,aie,ku);_.Nb=function lu(a){Rrb(this,a)};_.Ob=function mu(){ju(this);return !!this.c};_.Pb=function nu(){ju(this);ot(this.c);this.a=this.c;Qqb(this.d,this.a.a);do{this.c=this.c.b}while(!!this.c&&!Qqb(this.d,this.c.a));return this.a.a};_.Qb=function ou(){ju(this);Vb(!!this.a);ir(new wu(this.e,this.a.a));this.a=null;this.b=this.e.c};_.b=0;var IG=mdb(Zhe,'LinkedListMultimap/DistinctKeyIterator',1296);bcb(283,1,{283:1},pu);_.a=0;var JG=mdb(Zhe,'LinkedListMultimap/KeyList',283);bcb(1295,345,kie,qu);_.cd=function ru(){return this.a};_.dd=function su(){return this.f};_.ed=function tu(a){var b;b=this.f;this.f=a;return b};var KG=mdb(Zhe,'LinkedListMultimap/Node',1295);bcb(560,1,jie,wu,xu);_.Nb=function zu(a){Rrb(this,a)};_.Rb=function yu(a){this.e=ht(this.f,this.b,a,this.c);++this.d;this.a=null};_.Ob=function Au(){return !!this.c};_.Sb=function Bu(){return !!this.e};_.Pb=function Cu(){return uu(this)};_.Tb=function Du(){return this.d};_.Ub=function Eu(){return vu(this)};_.Vb=function Fu(){return this.d-1};_.Qb=function Gu(){Vb(!!this.a);if(this.a!=this.c){this.e=this.a.e;--this.d}else{this.c=this.a.c}lt(this.f,this.a);this.a=null};_.Wb=function Hu(a){Ub(!!this.a);this.a.f=a};_.d=0;var LG=mdb(Zhe,'LinkedListMultimap/ValueForKeyIterator',560);bcb(1018,52,Lie);_.Vc=function Tu(a,b){this.a.Vc(a,b)};_.Wc=function Uu(a,b){return this.a.Wc(a,b)};_.Hc=function Vu(a){return this.a.Hc(a)};_.Xb=function Wu(a){return this.a.Xb(a)};_.$c=function Xu(a){return this.a.$c(a)};_._c=function Yu(a,b){return this.a._c(a,b)};_.gc=function Zu(){return this.a.gc()};var OG=mdb(Zhe,'Lists/AbstractListWrapper',1018);bcb(1019,1018,Nie);var PG=mdb(Zhe,'Lists/RandomAccessListWrapper',1019);bcb(1021,1019,Nie,$u);_.Zc=function _u(a){return this.a.Zc(a)};var NG=mdb(Zhe,'Lists/1',1021);bcb(131,52,{131:1,20:1,28:1,52:1,14:1,15:1},dv);_.Vc=function ev(a,b){this.a.Vc(cv(this,a),b)};_.$b=function fv(){this.a.$b()};_.Xb=function gv(a){return this.a.Xb(bv(this,a))};_.Kc=function hv(){return av(this,0)};_.Zc=function iv(a){return av(this,a)};_.$c=function jv(a){return this.a.$c(bv(this,a))};_.Ud=function kv(a,b){(Tb(a,b,this.a.gc()),Su(this.a.bd(cv(this,b),cv(this,a)))).$b()};_._c=function lv(a,b){return this.a._c(bv(this,a),b)};_.gc=function mv(){return this.a.gc()};_.bd=function nv(a,b){return Tb(a,b,this.a.gc()),Su(this.a.bd(cv(this,b),cv(this,a)))};var SG=mdb(Zhe,'Lists/ReverseList',131);bcb(280,131,{131:1,20:1,28:1,52:1,14:1,15:1,54:1},ov);var QG=mdb(Zhe,'Lists/RandomAccessReverseList',280);bcb(1020,1,jie,qv);_.Nb=function sv(a){Rrb(this,a)};_.Rb=function rv(a){this.c.Rb(a);this.c.Ub();this.a=false};_.Ob=function tv(){return this.c.Sb()};_.Sb=function uv(){return this.c.Ob()};_.Pb=function vv(){return pv(this)};_.Tb=function wv(){return cv(this.b,this.c.Tb())};_.Ub=function xv(){if(!this.c.Ob()){throw vbb(new utb)}this.a=true;return this.c.Pb()};_.Vb=function yv(){return cv(this.b,this.c.Tb())-1};_.Qb=function zv(){Vb(this.a);this.c.Qb();this.a=false};_.Wb=function Av(a){Ub(this.a);this.c.Wb(a)};_.a=false;var RG=mdb(Zhe,'Lists/ReverseList/1',1020);bcb(432,487,aie,Mv);_.Qd=function Nv(a){return Lv(a)};var TG=mdb(Zhe,'Maps/1',432);bcb(698,487,aie,Ov);_.Qd=function Pv(a){return BD(a,42).dd()};var UG=mdb(Zhe,'Maps/2',698);bcb(962,487,aie,Qv);_.Qd=function Rv(a){return new Wo(a,ww(this.a,a))};var VG=mdb(Zhe,'Maps/3',962);bcb(959,1971,fie,Sv);_.Jc=function Tv(a){mj(this.a,a)};_.Kc=function Uv(){return this.a.kc()};_.Rc=function Vv(){return this.a};_.Nc=function Wv(){return this.a.lc()};var XG=mdb(Zhe,'Maps/IteratorBasedAbstractMap/1',959);bcb(960,1,{},Xv);_.Od=function Yv(a,b){this.a.td(a)};var ZG=mdb(Zhe,'Maps/KeySet/lambda$0$Type',960);bcb(958,28,die,Zv);_.$b=function $v(){this.a.$b()};_.Hc=function _v(a){return this.a.uc(a)};_.Jc=function aw(a){Qb(a);this.a.wc(new fw(a))};_.dc=function bw(){return this.a.dc()};_.Kc=function cw(){return new Ov(this.a.vc().Kc())};_.Mc=function dw(b){var c,d;try{return ze(this,b,true)}catch(a){a=ubb(a);if(JD(a,41)){for(d=this.a.vc().Kc();d.Ob();){c=BD(d.Pb(),42);if(Hb(b,c.dd())){this.a.Bc(c.cd());return true}}return false}else throw vbb(a)}};_.gc=function ew(){return this.a.gc()};var aH=mdb(Zhe,'Maps/Values',958);bcb(961,1,{},fw);_.Od=function gw(a,b){this.a.td(b)};var _G=mdb(Zhe,'Maps/Values/lambda$0$Type',961);bcb(736,1987,cie,jw);_.xc=function nw(a){return this.a._b(a)?this.a.cc(a):null};_.Bc=function qw(a){return this.a._b(a)?this.a.fc(a):null};_.$b=function kw(){this.a.$b()};_._b=function lw(a){return this.a._b(a)};_.Ec=function mw(){return new sw(this)};_.Dc=function(){return this.Ec()};_.dc=function ow(){return this.a.dc()};_.ec=function pw(){return this.a.ec()};_.gc=function rw(){return this.a.ec().gc()};var eH=mdb(Zhe,'Multimaps/AsMap',736);bcb(1104,1971,fie,sw);_.Kc=function tw(){return Bv(this.a.a.ec(),new xw(this))};_.Rc=function uw(){return this.a};_.Mc=function vw(a){var b;if(!Ze(this,a)){return false}b=BD(a,42);iw(this.a,b.cd());return true};var dH=mdb(Zhe,'Multimaps/AsMap/EntrySet',1104);bcb(1108,1,{},xw);_.Kb=function yw(a){return ww(this,a)};_.Fb=function zw(a){return this===a};var cH=mdb(Zhe,'Multimaps/AsMap/EntrySet/1',1108);bcb(543,1989,{543:1,835:1,20:1,28:1,14:1},Cw);_.$b=function Dw(){Nc(this.a)};_.Hc=function Ew(a){return Oc(this.a,a)};_.Jc=function Fw(a){Qb(a);reb(Pc(this.a),new Rw(a))};_.Kc=function Gw(){return new Mv(Pc(this.a).a.kc())};_.gc=function Hw(){return this.a.d};_.Nc=function Iw(){return $j(Pc(this.a).Nc(),new Jw)};var kH=mdb(Zhe,'Multimaps/Keys',543);bcb(1106,1,{},Jw);_.Kb=function Kw(a){return BD(a,42).cd()};var gH=mdb(Zhe,'Multimaps/Keys/0methodref$getKey$Type',1106);bcb(1105,487,aie,Lw);_.Qd=function Mw(a){return new Qw(BD(a,42))};var iH=mdb(Zhe,'Multimaps/Keys/1',1105);bcb(1990,1,{416:1});_.Fb=function Nw(a){var b;if(JD(a,492)){b=BD(a,416);return BD(this.a.dd(),14).gc()==BD(b.a.dd(),14).gc()&&Hb(this.a.cd(),b.a.cd())}return false};_.Hb=function Ow(){var a;a=this.a.cd();return (a==null?0:tb(a))^BD(this.a.dd(),14).gc()};_.Ib=function Pw(){var a,b;b=xfb(this.a.cd());a=BD(this.a.dd(),14).gc();return a==1?b:b+' x '+a};var oH=mdb(Zhe,'Multisets/AbstractEntry',1990);bcb(492,1990,{492:1,416:1},Qw);var hH=mdb(Zhe,'Multimaps/Keys/1/1',492);bcb(1107,1,qie,Rw);_.td=function Sw(a){this.a.td(BD(a,42).cd())};var jH=mdb(Zhe,'Multimaps/Keys/lambda$1$Type',1107);bcb(1110,1,qie,Vw);_.td=function Ww(a){Tw(BD(a,416))};var lH=mdb(Zhe,'Multiset/lambda$0$Type',1110);bcb(737,1,qie,Xw);_.td=function Yw(a){Uw(this.a,BD(a,416))};var mH=mdb(Zhe,'Multiset/lambda$1$Type',737);bcb(1111,1,{},bx);var nH=mdb(Zhe,'Multisets/0methodref$add$Type',1111);bcb(738,1,{},cx);_.Kb=function dx(a){return _w(BD(a,416))};var qH=mdb(Zhe,'Multisets/lambda$3$Type',738);bcb(2008,1,Qhe);var rH=mdb(Zhe,'RangeGwtSerializationDependencies',2008);bcb(514,2008,{169:1,514:1,3:1,45:1},gx);_.Lb=function hx(a){return fx(this,BD(a,35))};_.Mb=function lx(a){return fx(this,BD(a,35))};_.Fb=function jx(a){var b;if(JD(a,514)){b=BD(a,514);return Ek(this.a,b.a)&&Ek(this.b,b.b)}return false};_.Hb=function kx(){return this.a.Hb()*31+this.b.Hb()};_.Ib=function mx(){return nx(this.a,this.b)};var sH=mdb(Zhe,'Range',514);bcb(778,1999,yie,px);_.Zc=function tx(a){return jm(this.b,a)};_.Pd=function qx(){return this.a};_.Xb=function rx(a){return Em(this.b,a)};_.Fd=function sx(a){return jm(this.b,a)};var tH=mdb(Zhe,'RegularImmutableAsList',778);bcb(646,2006,yie,ux);_.Hd=function vx(){return this.a};var uH=mdb(Zhe,'RegularImmutableList',646);bcb(616,715,Aie,wx);var vH=mdb(Zhe,'RegularImmutableMap',616);bcb(716,703,Cie,zx);var xx;var wH=mdb(Zhe,'RegularImmutableSet',716);bcb(1976,eie,fie);_.Kc=function Mx(){return new Xx(this.a,this.b)};_.Fc=function Jx(a){throw vbb(new bgb)};_.Gc=function Kx(a){throw vbb(new bgb)};_.$b=function Lx(){throw vbb(new bgb)};_.Mc=function Nx(a){throw vbb(new bgb)};var CH=mdb(Zhe,'Sets/SetView',1976);bcb(963,1976,fie,Px);_.Kc=function Tx(){return new Xx(this.a,this.b)};_.Hc=function Qx(a){return tqb(this.a,a)&&this.b.Hc(a)};_.Ic=function Rx(a){return Be(this.a,a)&&this.b.Ic(a)};_.dc=function Sx(){return omb(this.b,this.a)};_.Lc=function Ux(){return JAb(new YAb(null,new Kub(this.a,1)),new _x(this.b))};_.gc=function Vx(){return Ox(this)};_.Oc=function Wx(){return JAb(new YAb(null,new Kub(this.a,1)),new Zx(this.b))};var AH=mdb(Zhe,'Sets/2',963);bcb(700,699,Yhe,Xx);_.Yb=function Yx(){var a;while(Eqb(this.a)){a=Fqb(this.a);if(this.c.Hc(a)){return a}}return this.e=2,null};var xH=mdb(Zhe,'Sets/2/1',700);bcb(964,1,Oie,Zx);_.Mb=function $x(a){return this.a.Hc(a)};var yH=mdb(Zhe,'Sets/2/4methodref$contains$Type',964);bcb(965,1,Oie,_x);_.Mb=function ay(a){return this.a.Hc(a)};var zH=mdb(Zhe,'Sets/2/5methodref$contains$Type',965);bcb(607,1975,{607:1,3:1,20:1,14:1,271:1,21:1,84:1},by);_.Bd=function cy(){return this.b};_.Cd=function dy(){return this.b};_.Md=function ey(){return this.b};_.Jc=function fy(a){this.a.Jc(a)};_.Lc=function gy(){return this.a.Lc()};_.Oc=function hy(){return this.a.Oc()};var DH=mdb(Zhe,'Sets/UnmodifiableNavigableSet',607);bcb(1932,1931,Aie,iy);_.Ld=function jy(){return Ql(),new oy(this.a)};_.Cc=function ky(){return Ql(),new oy(this.a)};_.pd=function ly(){return Ql(),new oy(this.a)};var EH=mdb(Zhe,'SingletonImmutableBiMap',1932);bcb(647,2006,yie,my);_.Hd=function ny(){return this.a};var FH=mdb(Zhe,'SingletonImmutableList',647);bcb(350,1981,Cie,oy);_.Kc=function ry(){return new Ir(this.a)};_.Hc=function py(a){return pb(this.a,a)};_.Ed=function qy(){return new Ir(this.a)};_.gc=function sy(){return 1};var GH=mdb(Zhe,'SingletonImmutableSet',350);bcb(1115,1,{},vy);_.Kb=function wy(a){return BD(a,164)};var HH=mdb(Zhe,'Streams/lambda$0$Type',1115);bcb(1116,1,Pie,xy);_.Vd=function yy(){uy(this.a)};var IH=mdb(Zhe,'Streams/lambda$1$Type',1116);bcb(1659,1658,_he,Ay);_.Zb=function By(){var a;return a=this.f,BD(BD(!a?(this.f=JD(this.c,171)?new Sf(this,BD(this.c,171)):JD(this.c,161)?new Mf(this,BD(this.c,161)):new ne(this,this.c)):a,161),171)};_.hc=function Ey(){return new Hxb(this.b)};_.gd=function Fy(){return new Hxb(this.b)};_.ec=function Hy(){var a;return a=this.i,BD(BD(!a?(this.i=JD(this.c,171)?new $f(this,BD(this.c,171)):JD(this.c,161)?new Yf(this,BD(this.c,161)):new zf(this,this.c)):a,84),271)};_.ac=function Dy(){return JD(this.c,171)?new Sf(this,BD(this.c,171)):JD(this.c,161)?new Mf(this,BD(this.c,161)):new ne(this,this.c)};_.ic=function Gy(a){a==null&&this.a.ue(a,a);return new Hxb(this.b)};var LH=mdb(Zhe,'TreeMultimap',1659);bcb(78,1,{3:1,78:1});_.Wd=function $y(a){return new Error(a)};_.Xd=function az(){return this.e};_.Yd=function bz(){return XAb(NAb(Plb((this.k==null&&(this.k=KC(_I,nie,78,0,0,1)),this.k)),new _fb),new bBb)};_.Zd=function cz(){return this.f};_.$d=function dz(){return this.g};_._d=function ez(){Vy(this,_y(this.Wd(Wy(this,this.g))));Sz(this)};_.Ib=function fz(){return Wy(this,this.$d())};_.e=Sie;_.i=false;_.n=true;var _I=mdb(Phe,'Throwable',78);bcb(102,78,{3:1,102:1,78:1});var EI=mdb(Phe,'Exception',102);bcb(60,102,Tie,gz,hz);var TI=mdb(Phe,'RuntimeException',60);bcb(598,60,Tie);var LI=mdb(Phe,'JsException',598);bcb(863,598,Tie);var RH=mdb(Uie,'JavaScriptExceptionBase',863);bcb(477,863,{477:1,3:1,102:1,60:1,78:1},lz);_.$d=function oz(){kz(this);return this.c};_.ae=function pz(){return PD(this.b)===PD(iz)?null:this.b};var iz;var OH=mdb(Wie,'JavaScriptException',477);var PH=mdb(Wie,'JavaScriptObject$',0);var tz;bcb(1948,1,{});var QH=mdb(Wie,'Scheduler',1948);var xz=0,yz=0,zz=-1;bcb(890,1948,{},Nz);var Jz;var SH=mdb(Uie,'SchedulerImpl',890);var Qz;bcb(1960,1,{});var WH=mdb(Uie,'StackTraceCreator/Collector',1960);bcb(864,1960,{},Yz);_.be=function Zz(a){var b={},j;var c=[];a[Yie]=c;var d=arguments.callee.caller;while(d){var e=(Rz(),d.name||(d.name=Uz(d.toString())));c.push(e);var f=':'+e;var g=b[f];if(g){var h,i;for(h=0,i=g.length;h<i;h++){if(g[h]===d){return}}}(g||(b[f]=[])).push(d);d=d.caller}};_.ce=function $z(a){var b,c,d,e;d=(Rz(),a&&a[Yie]?a[Yie]:[]);c=d.length;e=KC(VI,nie,310,c,0,1);for(b=0;b<c;b++){e[b]=new Zeb(d[b],null,-1)}return e};var TH=mdb(Uie,'StackTraceCreator/CollectorLegacy',864);bcb(1961,1960,{});_.be=function aA(a){};_.de=function bA(a,b,c,d){return new Zeb(b,a+'@'+d,c<0?-1:c)};_.ce=function cA(a){var b,c,d,e,f,g;e=Wz(a);f=KC(VI,nie,310,0,0,1);b=0;d=e.length;if(d==0){return f}g=_z(this,e[0]);dfb(g.d,Xie)||(f[b++]=g);for(c=1;c<d;c++){f[b++]=_z(this,e[c])}return f};var VH=mdb(Uie,'StackTraceCreator/CollectorModern',1961);bcb(865,1961,{},dA);_.de=function eA(a,b,c,d){return new Zeb(b,a,-1)};var UH=mdb(Uie,'StackTraceCreator/CollectorModernNoSourceMap',865);bcb(1050,1,{});var cI=mdb(yje,zje,1050);bcb(615,1050,{615:1},HA);var FA;var XH=mdb(Aje,zje,615);bcb(2001,1,{});var dI=mdb(yje,Bje,2001);bcb(2002,2001,{});var YH=mdb(Aje,Bje,2002);bcb(1090,1,{},MA);var JA;var ZH=mdb(Aje,'LocaleInfo',1090);bcb(1918,1,{},PA);_.a=0;var _H=mdb(Aje,'TimeZone',1918);bcb(1258,2002,{},VA);var aI=mdb('com.google.gwt.i18n.client.impl.cldr','DateTimeFormatInfoImpl',1258);bcb(434,1,{434:1},WA);_.a=false;_.b=0;var bI=mdb(yje,'DateTimeFormat/PatternPart',434);bcb(199,1,Cje,eB,fB,gB);_.wd=function hB(a){return XA(this,BD(a,199))};_.Fb=function iB(a){return JD(a,199)&&Bbb(Cbb(this.q.getTime()),Cbb(BD(a,199).q.getTime()))};_.Hb=function jB(){var a;a=Cbb(this.q.getTime());return Tbb(Vbb(a,Pbb(a,32)))};_.Ib=function lB(){var a,b,c;c=-this.q.getTimezoneOffset();a=(c>=0?'+':'')+(c/60|0);b=kB($wnd.Math.abs(c)%60);return (Dpb(),Bpb)[this.q.getDay()]+' '+Cpb[this.q.getMonth()]+' '+kB(this.q.getDate())+' '+kB(this.q.getHours())+':'+kB(this.q.getMinutes())+':'+kB(this.q.getSeconds())+' GMT'+a+b+' '+this.q.getFullYear()};var $J=mdb(bie,'Date',199);bcb(1915,199,Cje,nB);_.a=false;_.b=0;_.c=0;_.d=0;_.e=0;_.f=0;_.g=false;_.i=0;_.j=0;_.k=0;_.n=0;_.o=0;_.p=0;var eI=mdb('com.google.gwt.i18n.shared.impl','DateRecord',1915);bcb(1966,1,{});_.fe=function oB(){return null};_.ge=function pB(){return null};_.he=function qB(){return null};_.ie=function rB(){return null};_.je=function sB(){return null};var nI=mdb(Dje,'JSONValue',1966);bcb(216,1966,{216:1},wB,xB);_.Fb=function yB(a){if(!JD(a,216)){return false}return qz(this.a,BD(a,216).a)};_.ee=function zB(){return DB};_.Hb=function AB(){return rz(this.a)};_.fe=function BB(){return this};_.Ib=function CB(){var a,b,c;c=new Wfb('[');for(b=0,a=this.a.length;b<a;b++){b>0&&(c.a+=',',c);Pfb(c,tB(this,b))}c.a+=']';return c.a};var fI=mdb(Dje,'JSONArray',216);bcb(483,1966,{483:1},HB);_.ee=function IB(){return LB};_.ge=function JB(){return this};_.Ib=function KB(){return Bcb(),''+this.a};_.a=false;var EB,FB;var gI=mdb(Dje,'JSONBoolean',483);bcb(985,60,Tie,MB);var hI=mdb(Dje,'JSONException',985);bcb(1023,1966,{},PB);_.ee=function QB(){return SB};_.Ib=function RB(){return Xhe};var NB;var iI=mdb(Dje,'JSONNull',1023);bcb(258,1966,{258:1},TB);_.Fb=function UB(a){if(!JD(a,258)){return false}return this.a==BD(a,258).a};_.ee=function VB(){return ZB};_.Hb=function WB(){return Hdb(this.a)};_.he=function XB(){return this};_.Ib=function YB(){return this.a+''};_.a=0;var jI=mdb(Dje,'JSONNumber',258);bcb(183,1966,{183:1},eC,fC);_.Fb=function gC(a){if(!JD(a,183)){return false}return qz(this.a,BD(a,183).a)};_.ee=function hC(){return lC};_.Hb=function iC(){return rz(this.a)};_.ie=function jC(){return this};_.Ib=function kC(){var a,b,c,d,e,f,g;g=new Wfb('{');a=true;f=$B(this,KC(ZI,nie,2,0,6,1));for(c=f,d=0,e=c.length;d<e;++d){b=c[d];a?(a=false):(g.a+=She,g);Qfb(g,vz(b));g.a+=':';Pfb(g,aC(this,b))}g.a+='}';return g.a};var lI=mdb(Dje,'JSONObject',183);bcb(596,eie,fie,mC);_.Hc=function nC(a){return ND(a)&&_B(this.a,GD(a))};_.Kc=function oC(){return new vib(new amb(this.b))};_.gc=function pC(){return this.b.length};var kI=mdb(Dje,'JSONObject/1',596);var qC;bcb(204,1966,{204:1},yC);_.Fb=function zC(a){if(!JD(a,204)){return false}return dfb(this.a,BD(a,204).a)};_.ee=function AC(){return EC};_.Hb=function BC(){return LCb(this.a)};_.je=function CC(){return this};_.Ib=function DC(){return vz(this.a)};var mI=mdb(Dje,'JSONString',204);var QC;var sD,tD,uD,vD;bcb(1962,1,{525:1});var pI=mdb(Lje,'OutputStream',1962);bcb(1963,1962,{525:1});var oI=mdb(Lje,'FilterOutputStream',1963);bcb(866,1963,{525:1},jcb);var qI=mdb(Lje,'PrintStream',866);bcb(418,1,{475:1});_.Ib=function ncb(){return this.a};var rI=mdb(Phe,'AbstractStringBuilder',418);bcb(529,60,Tie,ocb);var sI=mdb(Phe,'ArithmeticException',529);bcb(73,60,Mje,pcb,qcb);var II=mdb(Phe,'IndexOutOfBoundsException',73);bcb(320,73,{3:1,320:1,102:1,73:1,60:1,78:1},rcb,scb);var tI=mdb(Phe,'ArrayIndexOutOfBoundsException',320);bcb(528,60,Tie,tcb,ucb);var uI=mdb(Phe,'ArrayStoreException',528);bcb(289,78,Nje,vcb);var DI=mdb(Phe,'Error',289);bcb(194,289,Nje,xcb,ycb);var vI=mdb(Phe,'AssertionError',194);xD={3:1,476:1,35:1};var zcb,Acb;var wI=mdb(Phe,'Boolean',476);bcb(236,1,{3:1,236:1});var Gcb;var RI=mdb(Phe,'Number',236);bcb(217,236,{3:1,217:1,35:1,236:1},Mcb);_.wd=function Ncb(a){return Lcb(this,BD(a,217))};_.ke=function Ocb(){return this.a};_.Fb=function Pcb(a){return JD(a,217)&&BD(a,217).a==this.a};_.Hb=function Qcb(){return this.a};_.Ib=function Rcb(){return ''+this.a};_.a=0;var xI=mdb(Phe,'Byte',217);var Tcb;bcb(172,1,{3:1,172:1,35:1},Xcb);_.wd=function Ycb(a){return Wcb(this,BD(a,172))};_.Fb=function $cb(a){return JD(a,172)&&BD(a,172).a==this.a};_.Hb=function _cb(){return this.a};_.Ib=function adb(){return String.fromCharCode(this.a)};_.a=0;var Vcb;var yI=mdb(Phe,'Character',172);var cdb;bcb(205,60,{3:1,205:1,102:1,60:1,78:1},Bdb,Cdb);var zI=mdb(Phe,'ClassCastException',205);yD={3:1,35:1,333:1,236:1};var BI=mdb(Phe,'Double',333);bcb(155,236,{3:1,35:1,155:1,236:1},Ndb,Odb);_.wd=function Pdb(a){return Mdb(this,BD(a,155))};_.ke=function Qdb(){return this.a};_.Fb=function Rdb(a){return JD(a,155)&&Fdb(this.a,BD(a,155).a)};_.Hb=function Sdb(){return QD(this.a)};_.Ib=function Udb(){return ''+this.a};_.a=0;var FI=mdb(Phe,'Float',155);bcb(32,60,{3:1,102:1,32:1,60:1,78:1},Vdb,Wdb,Xdb);var GI=mdb(Phe,'IllegalArgumentException',32);bcb(71,60,Tie,Ydb,Zdb);var HI=mdb(Phe,'IllegalStateException',71);bcb(19,236,{3:1,35:1,19:1,236:1},_db);_.wd=function ceb(a){return $db(this,BD(a,19))};_.ke=function deb(){return this.a};_.Fb=function eeb(a){return JD(a,19)&&BD(a,19).a==this.a};_.Hb=function feb(){return this.a};_.Ib=function leb(){return ''+this.a};_.a=0;var JI=mdb(Phe,'Integer',19);var neb;var peb;bcb(162,236,{3:1,35:1,162:1,236:1},teb);_.wd=function veb(a){return seb(this,BD(a,162))};_.ke=function web(){return Sbb(this.a)};_.Fb=function xeb(a){return JD(a,162)&&Bbb(BD(a,162).a,this.a)};_.Hb=function yeb(){return Tbb(this.a)};_.Ib=function zeb(){return ''+Ubb(this.a)};_.a=0;var MI=mdb(Phe,'Long',162);var Beb;bcb(2039,1,{});bcb(1831,60,Tie,Feb);var NI=mdb(Phe,'NegativeArraySizeException',1831);bcb(173,598,{3:1,102:1,173:1,60:1,78:1},Geb,Heb);_.Wd=function Ieb(a){return new TypeError(a)};var OI=mdb(Phe,'NullPointerException',173);var Jeb,Keb,Leb,Meb;bcb(127,32,{3:1,102:1,32:1,127:1,60:1,78:1},Oeb);var QI=mdb(Phe,'NumberFormatException',127);bcb(184,236,{3:1,35:1,236:1,184:1},Qeb);_.wd=function Reb(a){return Peb(this,BD(a,184))};_.ke=function Seb(){return this.a};_.Fb=function Teb(a){return JD(a,184)&&BD(a,184).a==this.a};_.Hb=function Ueb(){return this.a};_.Ib=function Veb(){return ''+this.a};_.a=0;var UI=mdb(Phe,'Short',184);var Xeb;bcb(310,1,{3:1,310:1},Zeb);_.Fb=function $eb(a){var b;if(JD(a,310)){b=BD(a,310);return this.c==b.c&&this.d==b.d&&this.a==b.a&&this.b==b.b}return false};_.Hb=function _eb(){return Hlb(OC(GC(SI,1),Uhe,1,5,[meb(this.c),this.a,this.d,this.b]))};_.Ib=function afb(){return this.a+'.'+this.d+'('+(this.b!=null?this.b:'Unknown Source')+(this.c>=0?':'+this.c:'')+')'};_.c=0;var VI=mdb(Phe,'StackTraceElement',310);zD={3:1,475:1,35:1,2:1};var ZI=mdb(Phe,Vie,2);bcb(107,418,{475:1},Hfb,Ifb,Jfb);var WI=mdb(Phe,'StringBuffer',107);bcb(100,418,{475:1},Ufb,Vfb,Wfb);var XI=mdb(Phe,'StringBuilder',100);bcb(687,73,Mje,Xfb);var YI=mdb(Phe,'StringIndexOutOfBoundsException',687);bcb(2043,1,{});var Yfb;bcb(844,1,{},_fb);_.Kb=function agb(a){return BD(a,78).e};var $I=mdb(Phe,'Throwable/lambda$0$Type',844);bcb(41,60,{3:1,102:1,60:1,78:1,41:1},bgb,cgb);var aJ=mdb(Phe,'UnsupportedOperationException',41);bcb(240,236,{3:1,35:1,236:1,240:1},sgb,tgb);_.wd=function wgb(a){return mgb(this,BD(a,240))};_.ke=function xgb(){return Hcb(rgb(this))};_.Fb=function ygb(a){var b;if(this===a){return true}if(JD(a,240)){b=BD(a,240);return this.e==b.e&&mgb(this,b)==0}return false};_.Hb=function zgb(){var a;if(this.b!=0){return this.b}if(this.a<54){a=Cbb(this.f);this.b=Tbb(xbb(a,-1));this.b=33*this.b+Tbb(xbb(Obb(a,32),-1));this.b=17*this.b+QD(this.e);return this.b}this.b=17*Ngb(this.c)+QD(this.e);return this.b};_.Ib=function Agb(){return rgb(this)};_.a=0;_.b=0;_.d=0;_.e=0;_.f=0;var dgb,egb,fgb,ggb,hgb,igb,jgb,kgb;var bJ=mdb('java.math','BigDecimal',240);bcb(91,236,{3:1,35:1,236:1,91:1},Tgb,Ugb,Vgb,Wgb,Xgb,Ygb);_.wd=function $gb(a){return Igb(this,BD(a,91))};_.ke=function _gb(){return Hcb(shb(this,0))};_.Fb=function ahb(a){return Kgb(this,a)};_.Hb=function chb(){return Ngb(this)};_.Ib=function ehb(){return shb(this,0)};_.b=-2;_.c=0;_.d=0;_.e=0;var Bgb,Cgb,Dgb,Egb,Fgb,Ggb;var cJ=mdb('java.math','BigInteger',91);var nhb,ohb;var Bhb,Chb;bcb(488,1967,cie);_.$b=function Xhb(){Uhb(this)};_._b=function Yhb(a){return Mhb(this,a)};_.uc=function Zhb(a){return Nhb(this,a,this.g)||Nhb(this,a,this.f)};_.vc=function $hb(){return new eib(this)};_.xc=function _hb(a){return Ohb(this,a)};_.zc=function aib(a,b){return Rhb(this,a,b)};_.Bc=function bib(a){return Thb(this,a)};_.gc=function cib(){return Vhb(this)};var gJ=mdb(bie,'AbstractHashMap',488);bcb(261,eie,fie,eib);_.$b=function fib(){this.a.$b()};_.Hc=function gib(a){return dib(this,a)};_.Kc=function hib(){return new nib(this.a)};_.Mc=function iib(a){var b;if(dib(this,a)){b=BD(a,42).cd();this.a.Bc(b);return true}return false};_.gc=function jib(){return this.a.gc()};var fJ=mdb(bie,'AbstractHashMap/EntrySet',261);bcb(262,1,aie,nib);_.Nb=function oib(a){Rrb(this,a)};_.Pb=function qib(){return lib(this)};_.Ob=function pib(){return this.b};_.Qb=function rib(){mib(this)};_.b=false;var eJ=mdb(bie,'AbstractHashMap/EntrySetIterator',262);bcb(417,1,aie,vib);_.Nb=function wib(a){Rrb(this,a)};_.Ob=function xib(){return sib(this)};_.Pb=function yib(){return tib(this)};_.Qb=function zib(){uib(this)};_.b=0;_.c=-1;var hJ=mdb(bie,'AbstractList/IteratorImpl',417);bcb(96,417,jie,Bib);_.Qb=function Hib(){uib(this)};_.Rb=function Cib(a){Aib(this,a)};_.Sb=function Dib(){return this.b>0};_.Tb=function Eib(){return this.b};_.Ub=function Fib(){return sCb(this.b>0),this.a.Xb(this.c=--this.b)};_.Vb=function Gib(){return this.b-1};_.Wb=function Iib(a){yCb(this.c!=-1);this.a._c(this.c,a)};var iJ=mdb(bie,'AbstractList/ListIteratorImpl',96);bcb(219,52,Lie,Jib);_.Vc=function Kib(a,b){wCb(a,this.b);this.c.Vc(this.a+a,b);++this.b};_.Xb=function Lib(a){tCb(a,this.b);return this.c.Xb(this.a+a)};_.$c=function Mib(a){var b;tCb(a,this.b);b=this.c.$c(this.a+a);--this.b;return b};_._c=function Nib(a,b){tCb(a,this.b);return this.c._c(this.a+a,b)};_.gc=function Oib(){return this.b};_.a=0;_.b=0;var jJ=mdb(bie,'AbstractList/SubList',219);bcb(384,eie,fie,Pib);_.$b=function Qib(){this.a.$b()};_.Hc=function Rib(a){return this.a._b(a)};_.Kc=function Sib(){var a;return a=this.a.vc().Kc(),new Vib(a)};_.Mc=function Tib(a){if(this.a._b(a)){this.a.Bc(a);return true}return false};_.gc=function Uib(){return this.a.gc()};var mJ=mdb(bie,'AbstractMap/1',384);bcb(691,1,aie,Vib);_.Nb=function Wib(a){Rrb(this,a)};_.Ob=function Xib(){return this.a.Ob()};_.Pb=function Yib(){var a;return a=BD(this.a.Pb(),42),a.cd()};_.Qb=function Zib(){this.a.Qb()};var lJ=mdb(bie,'AbstractMap/1/1',691);bcb(226,28,die,$ib);_.$b=function _ib(){this.a.$b()};_.Hc=function ajb(a){return this.a.uc(a)};_.Kc=function bjb(){var a;return a=this.a.vc().Kc(),new djb(a)};_.gc=function cjb(){return this.a.gc()};var oJ=mdb(bie,'AbstractMap/2',226);bcb(294,1,aie,djb);_.Nb=function ejb(a){Rrb(this,a)};_.Ob=function fjb(){return this.a.Ob()};_.Pb=function gjb(){var a;return a=BD(this.a.Pb(),42),a.dd()};_.Qb=function hjb(){this.a.Qb()};var nJ=mdb(bie,'AbstractMap/2/1',294);bcb(484,1,{484:1,42:1});_.Fb=function jjb(a){var b;if(!JD(a,42)){return false}b=BD(a,42);return wtb(this.d,b.cd())&&wtb(this.e,b.dd())};_.cd=function kjb(){return this.d};_.dd=function ljb(){return this.e};_.Hb=function mjb(){return xtb(this.d)^xtb(this.e)};_.ed=function njb(a){return ijb(this,a)};_.Ib=function ojb(){return this.d+'='+this.e};var pJ=mdb(bie,'AbstractMap/AbstractEntry',484);bcb(383,484,{484:1,383:1,42:1},pjb);var qJ=mdb(bie,'AbstractMap/SimpleEntry',383);bcb(1984,1,_je);_.Fb=function qjb(a){var b;if(!JD(a,42)){return false}b=BD(a,42);return wtb(this.cd(),b.cd())&&wtb(this.dd(),b.dd())};_.Hb=function rjb(){return xtb(this.cd())^xtb(this.dd())};_.Ib=function sjb(){return this.cd()+'='+this.dd()};var rJ=mdb(bie,lie,1984);bcb(1992,1967,gie);_.tc=function vjb(a){return tjb(this,a)};_._b=function wjb(a){return ujb(this,a)};_.vc=function xjb(){return new Bjb(this)};_.xc=function yjb(a){var b;b=a;return Wd(Awb(this,b))};_.ec=function Ajb(){return new Gjb(this)};var wJ=mdb(bie,'AbstractNavigableMap',1992);bcb(739,eie,fie,Bjb);_.Hc=function Cjb(a){return JD(a,42)&&tjb(this.b,BD(a,42))};_.Kc=function Djb(){return new Ywb(this.b)};_.Mc=function Ejb(a){var b;if(JD(a,42)){b=BD(a,42);return Kwb(this.b,b)}return false};_.gc=function Fjb(){return this.b.c};var tJ=mdb(bie,'AbstractNavigableMap/EntrySet',739);bcb(493,eie,iie,Gjb);_.Nc=function Mjb(){return new Rub(this)};_.$b=function Hjb(){zwb(this.a)};_.Hc=function Ijb(a){return ujb(this.a,a)};_.Kc=function Jjb(){var a;return a=new Ywb((new cxb(this.a)).b),new Njb(a)};_.Mc=function Kjb(a){if(ujb(this.a,a)){Jwb(this.a,a);return true}return false};_.gc=function Ljb(){return this.a.c};var vJ=mdb(bie,'AbstractNavigableMap/NavigableKeySet',493);bcb(494,1,aie,Njb);_.Nb=function Ojb(a){Rrb(this,a)};_.Ob=function Pjb(){return sib(this.a.a)};_.Pb=function Qjb(){var a;return a=Wwb(this.a),a.cd()};_.Qb=function Rjb(){Xwb(this.a)};var uJ=mdb(bie,'AbstractNavigableMap/NavigableKeySet/1',494);bcb(2004,28,die);_.Fc=function Sjb(a){return zCb(cub(this,a)),true};_.Gc=function Tjb(a){uCb(a);mCb(a!=this,"Can't add a queue to itself");return ye(this,a)};_.$b=function Ujb(){while(dub(this)!=null);};var xJ=mdb(bie,'AbstractQueue',2004);bcb(302,28,{4:1,20:1,28:1,14:1},jkb,kkb);_.Fc=function lkb(a){return Xjb(this,a),true};_.$b=function nkb(){Yjb(this)};_.Hc=function okb(a){return Zjb(new xkb(this),a)};_.dc=function pkb(){return akb(this)};_.Kc=function qkb(){return new xkb(this)};_.Mc=function rkb(a){return dkb(new xkb(this),a)};_.gc=function skb(){return this.c-this.b&this.a.length-1};_.Nc=function tkb(){return new Kub(this,272)};_.Qc=function ukb(a){var b;b=this.c-this.b&this.a.length-1;a.length<b&&(a=eCb(new Array(b),a));$jb(this,a,b);a.length>b&&NC(a,b,null);return a};_.b=0;_.c=0;var BJ=mdb(bie,'ArrayDeque',302);bcb(446,1,aie,xkb);_.Nb=function ykb(a){Rrb(this,a)};_.Ob=function zkb(){return this.a!=this.b};_.Pb=function Akb(){return vkb(this)};_.Qb=function Bkb(){wkb(this)};_.a=0;_.b=0;_.c=-1;var AJ=mdb(bie,'ArrayDeque/IteratorImpl',446);bcb(12,52,ake,Rkb,Skb,Tkb);_.Vc=function Ukb(a,b){Dkb(this,a,b)};_.Fc=function Vkb(a){return Ekb(this,a)};_.Wc=function Wkb(a,b){return Fkb(this,a,b)};_.Gc=function Xkb(a){return Gkb(this,a)};_.$b=function Ykb(){this.c=KC(SI,Uhe,1,0,5,1)};_.Hc=function Zkb(a){return Jkb(this,a,0)!=-1};_.Jc=function $kb(a){Hkb(this,a)};_.Xb=function _kb(a){return Ikb(this,a)};_.Xc=function alb(a){return Jkb(this,a,0)};_.dc=function blb(){return this.c.length==0};_.Kc=function clb(){return new olb(this)};_.$c=function dlb(a){return Kkb(this,a)};_.Mc=function elb(a){return Lkb(this,a)};_.Ud=function flb(a,b){Mkb(this,a,b)};_._c=function glb(a,b){return Nkb(this,a,b)};_.gc=function hlb(){return this.c.length};_.ad=function ilb(a){Okb(this,a)};_.Pc=function jlb(){return Pkb(this)};_.Qc=function klb(a){return Qkb(this,a)};var DJ=mdb(bie,'ArrayList',12);bcb(7,1,aie,olb);_.Nb=function plb(a){Rrb(this,a)};_.Ob=function qlb(){return llb(this)};_.Pb=function rlb(){return mlb(this)};_.Qb=function slb(){nlb(this)};_.a=0;_.b=-1;var CJ=mdb(bie,'ArrayList/1',7);bcb(2013,$wnd.Function,{},Ylb);_.te=function Zlb(a,b){return Kdb(a,b)};bcb(154,52,bke,amb);_.Hc=function bmb(a){return Bt(this,a)!=-1};_.Jc=function cmb(a){var b,c,d,e;uCb(a);for(c=this.a,d=0,e=c.length;d<e;++d){b=c[d];a.td(b)}};_.Xb=function dmb(a){return $lb(this,a)};_._c=function emb(a,b){var c;c=(tCb(a,this.a.length),this.a[a]);NC(this.a,a,b);return c};_.gc=function fmb(){return this.a.length};_.ad=function gmb(a){Mlb(this.a,this.a.length,a)};_.Pc=function hmb(){return _lb(this,KC(SI,Uhe,1,this.a.length,5,1))};_.Qc=function imb(a){return _lb(this,a)};var EJ=mdb(bie,'Arrays/ArrayList',154);var jmb,kmb,lmb;bcb(940,52,bke,xmb);_.Hc=function ymb(a){return false};_.Xb=function zmb(a){return wmb(a)};_.Kc=function Amb(){return mmb(),Emb(),Dmb};_.Yc=function Bmb(){return mmb(),Emb(),Dmb};_.gc=function Cmb(){return 0};var GJ=mdb(bie,'Collections/EmptyList',940);bcb(941,1,jie,Fmb);_.Nb=function Hmb(a){Rrb(this,a)};_.Rb=function Gmb(a){throw vbb(new bgb)};_.Ob=function Imb(){return false};_.Sb=function Jmb(){return false};_.Pb=function Kmb(){throw vbb(new utb)};_.Tb=function Lmb(){return 0};_.Ub=function Mmb(){throw vbb(new utb)};_.Vb=function Nmb(){return -1};_.Qb=function Omb(){throw vbb(new Ydb)};_.Wb=function Pmb(a){throw vbb(new Ydb)};var Dmb;var FJ=mdb(bie,'Collections/EmptyListIterator',941);bcb(943,1967,Aie,Qmb);_._b=function Rmb(a){return false};_.uc=function Smb(a){return false};_.vc=function Tmb(){return mmb(),lmb};_.xc=function Umb(a){return null};_.ec=function Vmb(){return mmb(),lmb};_.gc=function Wmb(){return 0};_.Cc=function Xmb(){return mmb(),jmb};var HJ=mdb(bie,'Collections/EmptyMap',943);bcb(942,eie,Cie,Ymb);_.Hc=function Zmb(a){return false};_.Kc=function $mb(){return mmb(),Emb(),Dmb};_.gc=function _mb(){return 0};var IJ=mdb(bie,'Collections/EmptySet',942);bcb(599,52,{3:1,20:1,28:1,52:1,14:1,15:1},anb);_.Hc=function bnb(a){return wtb(this.a,a)};_.Xb=function cnb(a){tCb(a,1);return this.a};_.gc=function dnb(){return 1};var JJ=mdb(bie,'Collections/SingletonList',599);bcb(372,1,wie,lnb);_.Jc=function rnb(a){reb(this,a)};_.Lc=function unb(){return new YAb(null,this.Nc())};_.Nc=function xnb(){return new Kub(this,0)};_.Oc=function ynb(){return new YAb(null,this.Nc())};_.Fc=function mnb(a){return enb()};_.Gc=function nnb(a){return fnb()};_.$b=function onb(){gnb()};_.Hc=function pnb(a){return hnb(this,a)};_.Ic=function qnb(a){return inb(this,a)};_.dc=function snb(){return this.b.dc()};_.Kc=function tnb(){return new Dnb(this.b.Kc())};_.Mc=function vnb(a){return jnb()};_.gc=function wnb(){return this.b.gc()};_.Pc=function znb(){return this.b.Pc()};_.Qc=function Anb(a){return knb(this,a)};_.Ib=function Bnb(){return fcb(this.b)};var LJ=mdb(bie,'Collections/UnmodifiableCollection',372);bcb(371,1,aie,Dnb);_.Nb=function Enb(a){Rrb(this,a)};_.Ob=function Fnb(){return this.b.Ob()};_.Pb=function Gnb(){return this.b.Pb()};_.Qb=function Hnb(){Cnb()};var KJ=mdb(bie,'Collections/UnmodifiableCollectionIterator',371);bcb(531,372,cke,Inb);_.Nc=function Vnb(){return new Kub(this,16)};_.Vc=function Jnb(a,b){throw vbb(new bgb)};_.Wc=function Knb(a,b){throw vbb(new bgb)};_.Fb=function Lnb(a){return pb(this.a,a)};_.Xb=function Mnb(a){return this.a.Xb(a)};_.Hb=function Nnb(){return tb(this.a)};_.Xc=function Onb(a){return this.a.Xc(a)};_.dc=function Pnb(){return this.a.dc()};_.Yc=function Qnb(){return new Xnb(this.a.Zc(0))};_.Zc=function Rnb(a){return new Xnb(this.a.Zc(a))};_.$c=function Snb(a){throw vbb(new bgb)};_._c=function Tnb(a,b){throw vbb(new bgb)};_.ad=function Unb(a){throw vbb(new bgb)};_.bd=function Wnb(a,b){return new Inb(this.a.bd(a,b))};var NJ=mdb(bie,'Collections/UnmodifiableList',531);bcb(690,371,jie,Xnb);_.Qb=function bob(){Cnb()};_.Rb=function Ynb(a){throw vbb(new bgb)};_.Sb=function Znb(){return this.a.Sb()};_.Tb=function $nb(){return this.a.Tb()};_.Ub=function _nb(){return this.a.Ub()};_.Vb=function aob(){return this.a.Vb()};_.Wb=function cob(a){throw vbb(new bgb)};var MJ=mdb(bie,'Collections/UnmodifiableListIterator',690);bcb(600,1,cie,iob);_.wc=function oob(a){stb(this,a)};_.yc=function tob(a,b,c){return ttb(this,a,b,c)};_.$b=function job(){throw vbb(new bgb)};_._b=function kob(a){return this.c._b(a)};_.uc=function lob(a){return dob(this,a)};_.vc=function mob(){return eob(this)};_.Fb=function nob(a){return fob(this,a)};_.xc=function pob(a){return this.c.xc(a)};_.Hb=function qob(){return tb(this.c)};_.dc=function rob(){return this.c.dc()};_.ec=function sob(){return gob(this)};_.zc=function uob(a,b){throw vbb(new bgb)};_.Bc=function vob(a){throw vbb(new bgb)};_.gc=function wob(){return this.c.gc()};_.Ib=function xob(){return fcb(this.c)};_.Cc=function yob(){return hob(this)};var RJ=mdb(bie,'Collections/UnmodifiableMap',600);bcb(382,372,Bie,zob);_.Nc=function Cob(){return new Kub(this,1)};_.Fb=function Aob(a){return pb(this.b,a)};_.Hb=function Bob(){return tb(this.b)};var TJ=mdb(bie,'Collections/UnmodifiableSet',382);bcb(944,382,Bie,Gob);_.Hc=function Hob(a){return Dob(this,a)};_.Ic=function Iob(a){return this.b.Ic(a)};_.Kc=function Job(){var a;a=this.b.Kc();return new Mob(a)};_.Pc=function Kob(){var a;a=this.b.Pc();Fob(a,a.length);return a};_.Qc=function Lob(a){return Eob(this,a)};var QJ=mdb(bie,'Collections/UnmodifiableMap/UnmodifiableEntrySet',944);bcb(945,1,aie,Mob);_.Nb=function Nob(a){Rrb(this,a)};_.Pb=function Pob(){return new Rob(BD(this.a.Pb(),42))};_.Ob=function Oob(){return this.a.Ob()};_.Qb=function Qob(){throw vbb(new bgb)};var OJ=mdb(bie,'Collections/UnmodifiableMap/UnmodifiableEntrySet/1',945);bcb(688,1,_je,Rob);_.Fb=function Sob(a){return this.a.Fb(a)};_.cd=function Tob(){return this.a.cd()};_.dd=function Uob(){return this.a.dd()};_.Hb=function Vob(){return this.a.Hb()};_.ed=function Wob(a){throw vbb(new bgb)};_.Ib=function Xob(){return fcb(this.a)};var PJ=mdb(bie,'Collections/UnmodifiableMap/UnmodifiableEntrySet/UnmodifiableEntry',688);bcb(601,531,{20:1,14:1,15:1,54:1},Yob);var SJ=mdb(bie,'Collections/UnmodifiableRandomAccessList',601);bcb(689,382,Die,Zob);_.Nc=function apb(){return new Rub(this)};_.Fb=function $ob(a){return pb(this.a,a)};_.Hb=function _ob(){return tb(this.a)};var UJ=mdb(bie,'Collections/UnmodifiableSortedSet',689);bcb(847,1,dke,bpb);_.ue=function cpb(a,b){var c;return c=Ucc(BD(a,11),BD(b,11)),c!=0?c:Wcc(BD(a,11),BD(b,11))};_.Fb=function dpb(a){return this===a};_.ve=function epb(){return new tpb(this)};var VJ=mdb(bie,'Comparator/lambda$0$Type',847);var fpb,gpb,hpb;bcb(751,1,dke,kpb);_.ue=function lpb(a,b){return jpb(BD(a,35),BD(b,35))};_.Fb=function mpb(a){return this===a};_.ve=function npb(){return ipb(),hpb};var WJ=mdb(bie,'Comparators/NaturalOrderComparator',751);bcb(1177,1,dke,ppb);_.ue=function qpb(a,b){return opb(BD(a,35),BD(b,35))};_.Fb=function rpb(a){return this===a};_.ve=function spb(){return ipb(),gpb};var XJ=mdb(bie,'Comparators/ReverseNaturalOrderComparator',1177);bcb(64,1,dke,tpb);_.Fb=function vpb(a){return this===a};_.ue=function upb(a,b){return this.a.ue(b,a)};_.ve=function wpb(){return this.a};var YJ=mdb(bie,'Comparators/ReversedComparator',64);bcb(166,60,Tie,Apb);var ZJ=mdb(bie,'ConcurrentModificationException',166);var Bpb,Cpb;bcb(1904,1,eke,Gpb);_.we=function Hpb(a){Epb(this,a)};_.Ib=function Ipb(){return 'DoubleSummaryStatistics[count = '+Ubb(this.a)+', avg = '+(Dbb(this.a,0)?Fpb(this)/Sbb(this.a):0)+', min = '+this.c+', max = '+this.b+', sum = '+Fpb(this)+']'};_.a=0;_.b=Qje;_.c=Pje;_.d=0;_.e=0;_.f=0;var _J=mdb(bie,'DoubleSummaryStatistics',1904);bcb(1805,60,Tie,Jpb);var aK=mdb(bie,'EmptyStackException',1805);bcb(451,1967,cie,Rpb);_.zc=function Xpb(a,b){return Opb(this,a,b)};_.$b=function Spb(){Kpb(this)};_._b=function Tpb(a){return Lpb(this,a)};_.uc=function Upb(a){var b,c;for(c=new Gqb(this.a);c.a<c.c.a.length;){b=Fqb(c);if(wtb(a,this.b[b.g])){return true}}return false};_.vc=function Vpb(){return new _pb(this)};_.xc=function Wpb(a){return Mpb(this,a)};_.Bc=function Ypb(a){return Ppb(this,a)};_.gc=function Zpb(){return this.a.c};var eK=mdb(bie,'EnumMap',451);bcb(1352,eie,fie,_pb);_.$b=function aqb(){Kpb(this.a)};_.Hc=function bqb(a){return $pb(this,a)};_.Kc=function cqb(){return new fqb(this.a)};_.Mc=function dqb(a){var b;if($pb(this,a)){b=BD(a,42).cd();Ppb(this.a,b);return true}return false};_.gc=function eqb(){return this.a.a.c};var cK=mdb(bie,'EnumMap/EntrySet',1352);bcb(1353,1,aie,fqb);_.Nb=function gqb(a){Rrb(this,a)};_.Pb=function iqb(){return this.b=Fqb(this.a),new kqb(this.c,this.b)};_.Ob=function hqb(){return Eqb(this.a)};_.Qb=function jqb(){yCb(!!this.b);Ppb(this.c,this.b);this.b=null};var bK=mdb(bie,'EnumMap/EntrySetIterator',1353);bcb(1354,1984,_je,kqb);_.cd=function lqb(){return this.a};_.dd=function mqb(){return this.b.b[this.a.g]};_.ed=function nqb(a){return Qpb(this.b,this.a.g,a)};var dK=mdb(bie,'EnumMap/MapEntry',1354);bcb(174,eie,{20:1,28:1,14:1,174:1,21:1});var hK=mdb(bie,'EnumSet',174);bcb(156,174,{20:1,28:1,14:1,174:1,156:1,21:1},xqb);_.Fc=function yqb(a){return rqb(this,BD(a,22))};_.Hc=function zqb(a){return tqb(this,a)};_.Kc=function Aqb(){return new Gqb(this)};_.Mc=function Bqb(a){return vqb(this,a)};_.gc=function Cqb(){return this.c};_.c=0;var gK=mdb(bie,'EnumSet/EnumSetImpl',156);bcb(343,1,aie,Gqb);_.Nb=function Hqb(a){Rrb(this,a)};_.Pb=function Jqb(){return Fqb(this)};_.Ob=function Iqb(){return Eqb(this)};_.Qb=function Kqb(){yCb(this.b!=-1);NC(this.c.b,this.b,null);--this.c.c;this.b=-1};_.a=-1;_.b=-1;var fK=mdb(bie,'EnumSet/EnumSetImpl/IteratorImpl',343);bcb(43,488,fke,Lqb,Mqb,Nqb);_.re=function Oqb(a,b){return PD(a)===PD(b)||a!=null&&pb(a,b)};_.se=function Pqb(a){var b;b=tb(a);return b|0};var iK=mdb(bie,'HashMap',43);bcb(53,eie,gke,Tqb,Uqb,Vqb);_.Fc=function Xqb(a){return Qqb(this,a)};_.$b=function Yqb(){this.a.$b()};_.Hc=function Zqb(a){return Rqb(this,a)};_.dc=function $qb(){return this.a.gc()==0};_.Kc=function _qb(){return this.a.ec().Kc()};_.Mc=function arb(a){return Sqb(this,a)};_.gc=function brb(){return this.a.gc()};var jK=mdb(bie,'HashSet',53);bcb(1781,1,sie,drb);_.ud=function erb(a){crb(this,a)};_.Ib=function frb(){return 'IntSummaryStatistics[count = '+Ubb(this.a)+', avg = '+(Dbb(this.a,0)?Sbb(this.d)/Sbb(this.a):0)+', min = '+this.c+', max = '+this.b+', sum = '+Ubb(this.d)+']'};_.a=0;_.b=Rie;_.c=Ohe;_.d=0;var kK=mdb(bie,'IntSummaryStatistics',1781);bcb(1049,1,vie,lrb);_.Jc=function mrb(a){reb(this,a)};_.Kc=function nrb(){return new orb(this)};_.c=0;var mK=mdb(bie,'InternalHashCodeMap',1049);bcb(711,1,aie,orb);_.Nb=function prb(a){Rrb(this,a)};_.Pb=function rrb(){return this.d=this.a[this.c++],this.d};_.Ob=function qrb(){var a;if(this.c<this.a.length){return true}a=this.b.next();if(!a.done){this.a=a.value[1];this.c=0;return true}return false};_.Qb=function srb(){krb(this.e,this.d.cd());this.c!=0&&--this.c};_.c=0;_.d=null;var lK=mdb(bie,'InternalHashCodeMap/1',711);var vrb;bcb(1047,1,vie,Frb);_.Jc=function Grb(a){reb(this,a)};_.Kc=function Hrb(){return new Irb(this)};_.c=0;_.d=0;var pK=mdb(bie,'InternalStringMap',1047);bcb(710,1,aie,Irb);_.Nb=function Jrb(a){Rrb(this,a)};_.Pb=function Lrb(){return this.c=this.a,this.a=this.b.next(),new Nrb(this.d,this.c,this.d.d)};_.Ob=function Krb(){return !this.a.done};_.Qb=function Mrb(){Erb(this.d,this.c.value[0])};var nK=mdb(bie,'InternalStringMap/1',710);bcb(1048,1984,_je,Nrb);_.cd=function Orb(){return this.b.value[0]};_.dd=function Prb(){if(this.a.d!=this.c){return Crb(this.a,this.b.value[0])}return this.b.value[1]};_.ed=function Qrb(a){return Drb(this.a,this.b.value[0],a)};_.c=0;var oK=mdb(bie,'InternalStringMap/2',1048);bcb(228,43,fke,$rb,_rb);_.$b=function asb(){Urb(this)};_._b=function bsb(a){return Vrb(this,a)};_.uc=function csb(a){var b;b=this.d.a;while(b!=this.d){if(wtb(b.e,a)){return true}b=b.a}return false};_.vc=function dsb(){return new nsb(this)};_.xc=function esb(a){return Wrb(this,a)};_.zc=function fsb(a,b){return Xrb(this,a,b)};_.Bc=function gsb(a){return Zrb(this,a)};_.gc=function hsb(){return Vhb(this.e)};_.c=false;var tK=mdb(bie,'LinkedHashMap',228);bcb(387,383,{484:1,383:1,387:1,42:1},ksb,lsb);var qK=mdb(bie,'LinkedHashMap/ChainEntry',387);bcb(701,eie,fie,nsb);_.$b=function osb(){Urb(this.a)};_.Hc=function psb(a){return msb(this,a)};_.Kc=function qsb(){return new usb(this)};_.Mc=function rsb(a){var b;if(msb(this,a)){b=BD(a,42).cd();Zrb(this.a,b);return true}return false};_.gc=function ssb(){return Vhb(this.a.e)};var sK=mdb(bie,'LinkedHashMap/EntrySet',701);bcb(702,1,aie,usb);_.Nb=function vsb(a){Rrb(this,a)};_.Pb=function xsb(){return tsb(this)};_.Ob=function wsb(){return this.b!=this.c.a.d};_.Qb=function ysb(){yCb(!!this.a);xpb(this.c.a.e,this);jsb(this.a);Thb(this.c.a.e,this.a.d);ypb(this.c.a.e,this);this.a=null};var rK=mdb(bie,'LinkedHashMap/EntrySet/EntryIterator',702);bcb(178,53,gke,zsb,Asb,Bsb);var uK=mdb(bie,'LinkedHashSet',178);bcb(68,1964,{3:1,4:1,20:1,28:1,52:1,14:1,68:1,15:1},Psb,Qsb);_.Fc=function Rsb(a){return Dsb(this,a)};_.$b=function Ssb(){Osb(this)};_.Zc=function Tsb(a){return Jsb(this,a)};_.gc=function Usb(){return this.b};_.b=0;var xK=mdb(bie,'LinkedList',68);bcb(970,1,jie,$sb);_.Nb=function atb(a){Rrb(this,a)};_.Rb=function _sb(a){Vsb(this,a)};_.Ob=function btb(){return Wsb(this)};_.Sb=function ctb(){return this.b.b!=this.d.a};_.Pb=function dtb(){return Xsb(this)};_.Tb=function etb(){return this.a};_.Ub=function ftb(){return Ysb(this)};_.Vb=function gtb(){return this.a-1};_.Qb=function htb(){Zsb(this)};_.Wb=function itb(a){yCb(!!this.c);this.c.c=a};_.a=0;_.c=null;var vK=mdb(bie,'LinkedList/ListIteratorImpl',970);bcb(608,1,{},jtb);var wK=mdb(bie,'LinkedList/Node',608);bcb(1959,1,{});var ltb,mtb;var BK=mdb(bie,'Locale',1959);bcb(861,1959,{},otb);_.Ib=function ptb(){return ''};var zK=mdb(bie,'Locale/1',861);bcb(862,1959,{},qtb);_.Ib=function rtb(){return 'unknown'};var AK=mdb(bie,'Locale/4',862);bcb(109,60,{3:1,102:1,60:1,78:1,109:1},utb,vtb);var EK=mdb(bie,'NoSuchElementException',109);bcb(404,1,{404:1},Ftb);_.Fb=function Gtb(a){var b;if(a===this){return true}if(!JD(a,404)){return false}b=BD(a,404);return wtb(this.a,b.a)};_.Hb=function Htb(){return xtb(this.a)};_.Ib=function Jtb(){return this.a!=null?Whe+xfb(this.a)+')':'Optional.empty()'};var ztb;var HK=mdb(bie,'Optional',404);bcb(463,1,{463:1},Otb,Ptb);_.Fb=function Qtb(a){var b;if(a===this){return true}if(!JD(a,463)){return false}b=BD(a,463);return this.a==b.a&&Kdb(this.b,b.b)==0};_.Hb=function Rtb(){return this.a?QD(this.b):0};_.Ib=function Stb(){return this.a?'OptionalDouble.of('+(''+this.b)+')':'OptionalDouble.empty()'};_.a=false;_.b=0;var Ktb;var FK=mdb(bie,'OptionalDouble',463);bcb(517,1,{517:1},Wtb,Xtb);_.Fb=function Ytb(a){var b;if(a===this){return true}if(!JD(a,517)){return false}b=BD(a,517);return this.a==b.a&&beb(this.b,b.b)==0};_.Hb=function Ztb(){return this.a?this.b:0};_.Ib=function $tb(){return this.a?'OptionalInt.of('+(''+this.b)+')':'OptionalInt.empty()'};_.a=false;_.b=0;var Ttb;var GK=mdb(bie,'OptionalInt',517);bcb(503,2004,die,gub);_.Gc=function hub(a){return _tb(this,a)};_.$b=function iub(){this.b.c=KC(SI,Uhe,1,0,5,1)};_.Hc=function jub(a){return (a==null?-1:Jkb(this.b,a,0))!=-1};_.Kc=function kub(){return new qub(this)};_.Mc=function lub(a){return eub(this,a)};_.gc=function mub(){return this.b.c.length};_.Nc=function nub(){return new Kub(this,256)};_.Pc=function oub(){return Pkb(this.b)};_.Qc=function pub(a){return Qkb(this.b,a)};var JK=mdb(bie,'PriorityQueue',503);bcb(1277,1,aie,qub);_.Nb=function rub(a){Rrb(this,a)};_.Ob=function tub(){return this.a<this.c.b.c.length};_.Pb=function uub(){sCb(this.a<this.c.b.c.length);this.b=this.a++;return Ikb(this.c.b,this.b)};_.Qb=function vub(){yCb(this.b!=-1);fub(this.c,this.a=this.b);this.b=-1};_.a=0;_.b=-1;var IK=mdb(bie,'PriorityQueue/1',1277);bcb(230,1,{230:1},Gub,Hub);_.a=0;_.b=0;var wub,xub,yub=0;var KK=mdb(bie,'Random',230);bcb(27,1,pie,Kub,Lub,Mub);_.qd=function Nub(){return this.a};_.rd=function Oub(){Iub(this);return this.c};_.Nb=function Pub(a){Iub(this);this.d.Nb(a)};_.sd=function Qub(a){return Jub(this,a)};_.a=0;_.c=0;var $K=mdb(bie,'Spliterators/IteratorSpliterator',27);bcb(485,27,pie,Rub);var MK=mdb(bie,'SortedSet/1',485);bcb(602,1,eke,Tub);_.we=function Uub(a){this.a.td(a)};var NK=mdb(bie,'Spliterator/OfDouble/0methodref$accept$Type',602);bcb(603,1,eke,Vub);_.we=function Wub(a){this.a.td(a)};var OK=mdb(bie,'Spliterator/OfDouble/1methodref$accept$Type',603);bcb(604,1,sie,Xub);_.ud=function Yub(a){this.a.td(meb(a))};var PK=mdb(bie,'Spliterator/OfInt/2methodref$accept$Type',604);bcb(605,1,sie,Zub);_.ud=function $ub(a){this.a.td(meb(a))};var QK=mdb(bie,'Spliterator/OfInt/3methodref$accept$Type',605);bcb(617,1,pie);_.Nb=function evb(a){Sub(this,a)};_.qd=function cvb(){return this.d};_.rd=function dvb(){return this.e};_.d=0;_.e=0;var WK=mdb(bie,'Spliterators/BaseSpliterator',617);bcb(721,617,pie);_.xe=function gvb(a){_ub(this,a)};_.Nb=function hvb(a){JD(a,182)?_ub(this,BD(a,182)):_ub(this,new Vub(a))};_.sd=function ivb(a){return JD(a,182)?this.ye(BD(a,182)):this.ye(new Tub(a))};var RK=mdb(bie,'Spliterators/AbstractDoubleSpliterator',721);bcb(720,617,pie);_.xe=function kvb(a){_ub(this,a)};_.Nb=function lvb(a){JD(a,196)?_ub(this,BD(a,196)):_ub(this,new Zub(a))};_.sd=function mvb(a){return JD(a,196)?this.ye(BD(a,196)):this.ye(new Xub(a))};var SK=mdb(bie,'Spliterators/AbstractIntSpliterator',720);bcb(540,617,pie);var TK=mdb(bie,'Spliterators/AbstractSpliterator',540);bcb(692,1,pie);_.Nb=function tvb(a){Sub(this,a)};_.qd=function rvb(){return this.b};_.rd=function svb(){return this.d-this.c};_.b=0;_.c=0;_.d=0;var VK=mdb(bie,'Spliterators/BaseArraySpliterator',692);bcb(947,692,pie,vvb);_.ze=function wvb(a,b){uvb(this,BD(a,38),b)};_.Nb=function xvb(a){ovb(this,a)};_.sd=function yvb(a){return pvb(this,a)};var UK=mdb(bie,'Spliterators/ArraySpliterator',947);bcb(693,692,pie,Avb);_.ze=function Cvb(a,b){zvb(this,BD(a,182),b)};_.xe=function Dvb(a){ovb(this,a)};_.Nb=function Evb(a){JD(a,182)?ovb(this,BD(a,182)):ovb(this,new Vub(a))};_.ye=function Fvb(a){return pvb(this,a)};_.sd=function Gvb(a){return JD(a,182)?pvb(this,BD(a,182)):pvb(this,new Tub(a))};var XK=mdb(bie,'Spliterators/DoubleArraySpliterator',693);bcb(1968,1,pie);_.Nb=function Lvb(a){Sub(this,a)};_.qd=function Jvb(){return 16448};_.rd=function Kvb(){return 0};var Hvb;var ZK=mdb(bie,'Spliterators/EmptySpliterator',1968);bcb(946,1968,pie,Ovb);_.xe=function Pvb(a){Mvb(a)};_.Nb=function Qvb(a){JD(a,196)?Mvb(BD(a,196)):Mvb(new Zub(a))};_.ye=function Rvb(a){return Nvb(a)};_.sd=function Svb(a){return JD(a,196)?Nvb(BD(a,196)):Nvb(new Xub(a))};var YK=mdb(bie,'Spliterators/EmptySpliterator/OfInt',946);bcb(580,52,pke,Wvb);_.Vc=function Xvb(a,b){_vb(a,this.a.c.length+1);Dkb(this.a,a,b)};_.Fc=function Yvb(a){return Ekb(this.a,a)};_.Wc=function Zvb(a,b){_vb(a,this.a.c.length+1);return Fkb(this.a,a,b)};_.Gc=function $vb(a){return Gkb(this.a,a)};_.$b=function awb(){this.a.c=KC(SI,Uhe,1,0,5,1)};_.Hc=function bwb(a){return Jkb(this.a,a,0)!=-1};_.Ic=function cwb(a){return Be(this.a,a)};_.Jc=function dwb(a){Hkb(this.a,a)};_.Xb=function ewb(a){return _vb(a,this.a.c.length),Ikb(this.a,a)};_.Xc=function fwb(a){return Jkb(this.a,a,0)};_.dc=function gwb(){return this.a.c.length==0};_.Kc=function hwb(){return new olb(this.a)};_.$c=function iwb(a){return _vb(a,this.a.c.length),Kkb(this.a,a)};_.Ud=function jwb(a,b){Mkb(this.a,a,b)};_._c=function kwb(a,b){return _vb(a,this.a.c.length),Nkb(this.a,a,b)};_.gc=function lwb(){return this.a.c.length};_.ad=function mwb(a){Okb(this.a,a)};_.bd=function nwb(a,b){return new Jib(this.a,a,b)};_.Pc=function owb(){return Pkb(this.a)};_.Qc=function pwb(a){return Qkb(this.a,a)};_.Ib=function qwb(){return Fe(this.a)};var lL=mdb(bie,'Vector',580);bcb(809,580,pke,twb);var _K=mdb(bie,'Stack',809);bcb(206,1,{206:1},xwb);_.Ib=function ywb(){return wwb(this)};var aL=mdb(bie,'StringJoiner',206);bcb(544,1992,{3:1,83:1,171:1,161:1},Pwb,Qwb);_.$b=function Rwb(){zwb(this)};_.vc=function Swb(){return new cxb(this)};_.zc=function Twb(a,b){return Iwb(this,a,b)};_.Bc=function Uwb(a){return Jwb(this,a)};_.gc=function Vwb(){return this.c};_.c=0;var jL=mdb(bie,'TreeMap',544);bcb(390,1,aie,Ywb);_.Nb=function $wb(a){Rrb(this,a)};_.Pb=function axb(){return Wwb(this)};_.Ob=function _wb(){return sib(this.a)};_.Qb=function bxb(){Xwb(this)};var bL=mdb(bie,'TreeMap/EntryIterator',390);bcb(435,739,fie,cxb);_.$b=function dxb(){zwb(this.a)};var cL=mdb(bie,'TreeMap/EntrySet',435);bcb(436,383,{484:1,383:1,42:1,436:1},exb);_.b=false;var dL=mdb(bie,'TreeMap/Node',436);bcb(621,1,{},fxb);_.Ib=function gxb(){return 'State: mv='+this.c+' value='+this.d+' done='+this.a+' found='+this.b};_.a=false;_.b=false;_.c=false;var eL=mdb(bie,'TreeMap/State',621);bcb(297,22,qke,mxb);_.Ae=function nxb(){return false};_.Be=function oxb(){return false};var hxb,ixb,jxb,kxb;var iL=ndb(bie,'TreeMap/SubMapType',297,CI,qxb,pxb);bcb(1112,297,qke,rxb);_.Be=function sxb(){return true};var fL=ndb(bie,'TreeMap/SubMapType/1',1112,iL,null,null);bcb(1113,297,qke,txb);_.Ae=function uxb(){return true};_.Be=function vxb(){return true};var gL=ndb(bie,'TreeMap/SubMapType/2',1113,iL,null,null);bcb(1114,297,qke,wxb);_.Ae=function xxb(){return true};var hL=ndb(bie,'TreeMap/SubMapType/3',1114,iL,null,null);var yxb;bcb(208,eie,{3:1,20:1,28:1,14:1,271:1,21:1,84:1,208:1},Gxb,Hxb);_.Nc=function Oxb(){return new Rub(this)};_.Fc=function Ixb(a){return Axb(this,a)};_.$b=function Jxb(){zwb(this.a)};_.Hc=function Kxb(a){return ujb(this.a,a)};_.Kc=function Lxb(){var a;return a=new Ywb((new cxb((new Gjb(this.a)).a)).b),new Njb(a)};_.Mc=function Mxb(a){return Fxb(this,a)};_.gc=function Nxb(){return this.a.c};var kL=mdb(bie,'TreeSet',208);bcb(966,1,{},Rxb);_.Ce=function Sxb(a,b){return Pxb(this.a,a,b)};var mL=mdb(rke,'BinaryOperator/lambda$0$Type',966);bcb(967,1,{},Txb);_.Ce=function Uxb(a,b){return Qxb(this.a,a,b)};var nL=mdb(rke,'BinaryOperator/lambda$1$Type',967);bcb(846,1,{},Vxb);_.Kb=function Wxb(a){return a};var oL=mdb(rke,'Function/lambda$0$Type',846);bcb(431,1,Oie,Xxb);_.Mb=function Yxb(a){return !this.a.Mb(a)};var pL=mdb(rke,'Predicate/lambda$2$Type',431);bcb(572,1,{572:1});var qL=mdb(ske,'Handler',572);bcb(2007,1,Qhe);_.ne=function _xb(){return 'DUMMY'};_.Ib=function ayb(){return this.ne()};var Zxb;var sL=mdb(ske,'Level',2007);bcb(1621,2007,Qhe,byb);_.ne=function cyb(){return 'INFO'};var rL=mdb(ske,'Level/LevelInfo',1621);bcb(1640,1,{},gyb);var dyb;var tL=mdb(ske,'LogManager',1640);bcb(1780,1,Qhe,iyb);_.b=null;var uL=mdb(ske,'LogRecord',1780);bcb(512,1,{512:1},wyb);_.e=false;var jyb=false,kyb=false,lyb=false,myb=false,nyb=false;var vL=mdb(ske,'Logger',512);bcb(819,572,{572:1},zyb);var wL=mdb(ske,'SimpleConsoleLogHandler',819);bcb(132,22,{3:1,35:1,22:1,132:1},Gyb);var Cyb,Dyb,Eyb;var xL=ndb(vke,'Collector/Characteristics',132,CI,Iyb,Hyb);var Jyb;bcb(744,1,{},Lyb);var yL=mdb(vke,'CollectorImpl',744);bcb(1060,1,{},Zyb);_.Ce=function $yb(a,b){return vwb(BD(a,206),BD(b,206))};var zL=mdb(vke,'Collectors/10methodref$merge$Type',1060);bcb(1061,1,{},_yb);_.Kb=function azb(a){return wwb(BD(a,206))};var AL=mdb(vke,'Collectors/11methodref$toString$Type',1061);bcb(1062,1,{},bzb);_.Kb=function czb(a){return Bcb(),_Pb(a)?true:false};var BL=mdb(vke,'Collectors/12methodref$test$Type',1062);bcb(251,1,{},dzb);_.Od=function ezb(a,b){BD(a,14).Fc(b)};var CL=mdb(vke,'Collectors/20methodref$add$Type',251);bcb(253,1,{},fzb);_.Ee=function gzb(){return new Rkb};var DL=mdb(vke,'Collectors/21methodref$ctor$Type',253);bcb(346,1,{},hzb);_.Ee=function izb(){return new Tqb};var EL=mdb(vke,'Collectors/23methodref$ctor$Type',346);bcb(347,1,{},jzb);_.Od=function kzb(a,b){Qqb(BD(a,53),b)};var FL=mdb(vke,'Collectors/24methodref$add$Type',347);bcb(1055,1,{},lzb);_.Ce=function mzb(a,b){return Myb(BD(a,15),BD(b,14))};var GL=mdb(vke,'Collectors/4methodref$addAll$Type',1055);bcb(1059,1,{},nzb);_.Od=function ozb(a,b){uwb(BD(a,206),BD(b,475))};var HL=mdb(vke,'Collectors/9methodref$add$Type',1059);bcb(1058,1,{},pzb);_.Ee=function qzb(){return new xwb(this.a,this.b,this.c)};var IL=mdb(vke,'Collectors/lambda$15$Type',1058);bcb(1063,1,{},rzb);_.Ee=function szb(){var a;return a=new $rb,Xrb(a,(Bcb(),false),new Rkb),Xrb(a,true,new Rkb),a};var JL=mdb(vke,'Collectors/lambda$22$Type',1063);bcb(1064,1,{},tzb);_.Ee=function uzb(){return OC(GC(SI,1),Uhe,1,5,[this.a])};var KL=mdb(vke,'Collectors/lambda$25$Type',1064);bcb(1065,1,{},vzb);_.Od=function wzb(a,b){Oyb(this.a,CD(a))};var LL=mdb(vke,'Collectors/lambda$26$Type',1065);bcb(1066,1,{},xzb);_.Ce=function yzb(a,b){return Pyb(this.a,CD(a),CD(b))};var ML=mdb(vke,'Collectors/lambda$27$Type',1066);bcb(1067,1,{},zzb);_.Kb=function Azb(a){return CD(a)[0]};var NL=mdb(vke,'Collectors/lambda$28$Type',1067);bcb(713,1,{},Czb);_.Ce=function Dzb(a,b){return Bzb(a,b)};var OL=mdb(vke,'Collectors/lambda$4$Type',713);bcb(252,1,{},Ezb);_.Ce=function Fzb(a,b){return Ryb(BD(a,14),BD(b,14))};var PL=mdb(vke,'Collectors/lambda$42$Type',252);bcb(348,1,{},Gzb);_.Ce=function Hzb(a,b){return Syb(BD(a,53),BD(b,53))};var QL=mdb(vke,'Collectors/lambda$50$Type',348);bcb(349,1,{},Izb);_.Kb=function Jzb(a){return BD(a,53)};var RL=mdb(vke,'Collectors/lambda$51$Type',349);bcb(1054,1,{},Kzb);_.Od=function Lzb(a,b){Tyb(this.a,BD(a,83),b)};var SL=mdb(vke,'Collectors/lambda$7$Type',1054);bcb(1056,1,{},Mzb);_.Ce=function Nzb(a,b){return Vyb(BD(a,83),BD(b,83),new lzb)};var TL=mdb(vke,'Collectors/lambda$8$Type',1056);bcb(1057,1,{},Ozb);_.Kb=function Pzb(a){return Uyb(this.a,BD(a,83))};var UL=mdb(vke,'Collectors/lambda$9$Type',1057);bcb(539,1,{});_.He=function Wzb(){Qzb(this)};_.d=false;var zM=mdb(vke,'TerminatableStream',539);bcb(812,539,wke,bAb);_.He=function cAb(){Qzb(this)};var ZL=mdb(vke,'DoubleStreamImpl',812);bcb(1784,721,pie,fAb);_.ye=function hAb(a){return eAb(this,BD(a,182))};_.a=null;var WL=mdb(vke,'DoubleStreamImpl/2',1784);bcb(1785,1,eke,iAb);_.we=function jAb(a){gAb(this.a,a)};var VL=mdb(vke,'DoubleStreamImpl/2/lambda$0$Type',1785);bcb(1782,1,eke,kAb);_.we=function lAb(a){dAb(this.a,a)};var XL=mdb(vke,'DoubleStreamImpl/lambda$0$Type',1782);bcb(1783,1,eke,mAb);_.we=function nAb(a){Epb(this.a,a)};var YL=mdb(vke,'DoubleStreamImpl/lambda$2$Type',1783);bcb(1358,720,pie,rAb);_.ye=function sAb(a){return qAb(this,BD(a,196))};_.a=0;_.b=0;_.c=0;var $L=mdb(vke,'IntStream/5',1358);bcb(787,539,wke,vAb);_.He=function wAb(){Qzb(this)};_.Ie=function xAb(){return Tzb(this),this.a};var bM=mdb(vke,'IntStreamImpl',787);bcb(788,539,wke,yAb);_.He=function zAb(){Qzb(this)};_.Ie=function AAb(){return Tzb(this),Ivb(),Hvb};var _L=mdb(vke,'IntStreamImpl/Empty',788);bcb(1463,1,sie,BAb);_.ud=function CAb(a){crb(this.a,a)};var aM=mdb(vke,'IntStreamImpl/lambda$4$Type',1463);var xM=odb(vke,'Stream');bcb(30,539,{525:1,670:1,833:1},YAb);_.He=function ZAb(){Qzb(this)};var DAb;var wM=mdb(vke,'StreamImpl',30);bcb(845,1,{},bBb);_.ld=function cBb(a){return aBb(a)};var cM=mdb(vke,'StreamImpl/0methodref$lambda$2$Type',845);bcb(1084,540,pie,fBb);_.sd=function gBb(a){while(dBb(this)){if(this.a.sd(a)){return true}else{Qzb(this.b);this.b=null;this.a=null}}return false};var eM=mdb(vke,'StreamImpl/1',1084);bcb(1085,1,qie,hBb);_.td=function iBb(a){eBb(this.a,BD(a,833))};var dM=mdb(vke,'StreamImpl/1/lambda$0$Type',1085);bcb(1086,1,Oie,jBb);_.Mb=function kBb(a){return Qqb(this.a,a)};var fM=mdb(vke,'StreamImpl/1methodref$add$Type',1086);bcb(1087,540,pie,lBb);_.sd=function mBb(a){var b;if(!this.a){b=new Rkb;this.b.a.Nb(new nBb(b));mmb();Okb(b,this.c);this.a=new Kub(b,16)}return Jub(this.a,a)};_.a=null;var hM=mdb(vke,'StreamImpl/5',1087);bcb(1088,1,qie,nBb);_.td=function oBb(a){Ekb(this.a,a)};var gM=mdb(vke,'StreamImpl/5/2methodref$add$Type',1088);bcb(722,540,pie,qBb);_.sd=function rBb(a){this.b=false;while(!this.b&&this.c.sd(new sBb(this,a)));return this.b};_.b=false;var jM=mdb(vke,'StreamImpl/FilterSpliterator',722);bcb(1079,1,qie,sBb);_.td=function tBb(a){pBb(this.a,this.b,a)};var iM=mdb(vke,'StreamImpl/FilterSpliterator/lambda$0$Type',1079);bcb(1075,721,pie,wBb);_.ye=function xBb(a){return vBb(this,BD(a,182))};var lM=mdb(vke,'StreamImpl/MapToDoubleSpliterator',1075);bcb(1078,1,qie,yBb);_.td=function zBb(a){uBb(this.a,this.b,a)};var kM=mdb(vke,'StreamImpl/MapToDoubleSpliterator/lambda$0$Type',1078);bcb(1074,720,pie,CBb);_.ye=function DBb(a){return BBb(this,BD(a,196))};var nM=mdb(vke,'StreamImpl/MapToIntSpliterator',1074);bcb(1077,1,qie,EBb);_.td=function FBb(a){ABb(this.a,this.b,a)};var mM=mdb(vke,'StreamImpl/MapToIntSpliterator/lambda$0$Type',1077);bcb(719,540,pie,IBb);_.sd=function JBb(a){return HBb(this,a)};var pM=mdb(vke,'StreamImpl/MapToObjSpliterator',719);bcb(1076,1,qie,KBb);_.td=function LBb(a){GBb(this.a,this.b,a)};var oM=mdb(vke,'StreamImpl/MapToObjSpliterator/lambda$0$Type',1076);bcb(618,1,qie,NBb);_.td=function OBb(a){MBb(this,a)};var qM=mdb(vke,'StreamImpl/ValueConsumer',618);bcb(1080,1,qie,PBb);_.td=function QBb(a){EAb()};var rM=mdb(vke,'StreamImpl/lambda$0$Type',1080);bcb(1081,1,qie,RBb);_.td=function SBb(a){EAb()};var sM=mdb(vke,'StreamImpl/lambda$1$Type',1081);bcb(1082,1,{},TBb);_.Ce=function UBb(a,b){return $Ab(this.a,a,b)};var uM=mdb(vke,'StreamImpl/lambda$4$Type',1082);bcb(1083,1,qie,VBb);_.td=function WBb(a){_Ab(this.b,this.a,a)};var vM=mdb(vke,'StreamImpl/lambda$5$Type',1083);bcb(1089,1,qie,XBb);_.td=function YBb(a){Xzb(this.a,BD(a,365))};var yM=mdb(vke,'TerminatableStream/lambda$0$Type',1089);bcb(2041,1,{});bcb(1914,1,{},iCb);var AM=mdb('javaemul.internal','ConsoleLogger',1914);bcb(2038,1,{});var ECb=0;var GCb,HCb=0,ICb;bcb(1768,1,qie,OCb);_.td=function PCb(a){BD(a,308)};var BM=mdb(Cke,'BowyerWatsonTriangulation/lambda$0$Type',1768);bcb(1769,1,qie,QCb);_.td=function RCb(a){ye(this.a,BD(a,308).e)};var CM=mdb(Cke,'BowyerWatsonTriangulation/lambda$1$Type',1769);bcb(1770,1,qie,SCb);_.td=function TCb(a){BD(a,168)};var DM=mdb(Cke,'BowyerWatsonTriangulation/lambda$2$Type',1770);bcb(1765,1,Dke,WCb);_.ue=function XCb(a,b){return VCb(this.a,BD(a,168),BD(b,168))};_.Fb=function YCb(a){return this===a};_.ve=function ZCb(){return new tpb(this)};var EM=mdb(Cke,'NaiveMinST/lambda$0$Type',1765);bcb(499,1,{},_Cb);var FM=mdb(Cke,'NodeMicroLayout',499);bcb(168,1,{168:1},aDb);_.Fb=function bDb(a){var b;if(JD(a,168)){b=BD(a,168);return wtb(this.a,b.a)&&wtb(this.b,b.b)||wtb(this.a,b.b)&&wtb(this.b,b.a)}else{return false}};_.Hb=function cDb(){return xtb(this.a)+xtb(this.b)};var GM=mdb(Cke,'TEdge',168);bcb(308,1,{308:1},eDb);_.Fb=function fDb(a){var b;if(JD(a,308)){b=BD(a,308);return dDb(this,b.a)&&dDb(this,b.b)&&dDb(this,b.c)}else{return false}};_.Hb=function gDb(){return xtb(this.a)+xtb(this.b)+xtb(this.c)};var HM=mdb(Cke,'TTriangle',308);bcb(221,1,{221:1},hDb);var IM=mdb(Cke,'Tree',221);bcb(1254,1,{},jDb);var KM=mdb(Eke,'Scanline',1254);var JM=odb(Eke,Fke);bcb(1692,1,{},mDb);var LM=mdb(Gke,'CGraph',1692);bcb(307,1,{307:1},oDb);_.b=0;_.c=0;_.d=0;_.g=0;_.i=0;_.k=Qje;var NM=mdb(Gke,'CGroup',307);bcb(815,1,{},sDb);var MM=mdb(Gke,'CGroup/CGroupBuilder',815);bcb(57,1,{57:1},tDb);_.Ib=function uDb(){var a;if(this.j){return GD(this.j.Kb(this))}return fdb(PM),PM.o+'@'+(a=FCb(this)>>>0,a.toString(16))};_.f=0;_.i=Qje;var PM=mdb(Gke,'CNode',57);bcb(814,1,{},zDb);var OM=mdb(Gke,'CNode/CNodeBuilder',814);var EDb;bcb(1525,1,{},GDb);_.Oe=function HDb(a,b){return 0};_.Pe=function IDb(a,b){return 0};var QM=mdb(Gke,Ike,1525);bcb(1790,1,{},JDb);_.Le=function KDb(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p;j=Pje;for(d=new olb(a.a.b);d.a<d.c.c.length;){b=BD(mlb(d),57);j=$wnd.Math.min(j,b.a.j.d.c+b.b.a)}n=new Psb;for(g=new olb(a.a.a);g.a<g.c.c.length;){f=BD(mlb(g),307);f.k=j;f.g==0&&(Gsb(n,f,n.c.b,n.c),true)}while(n.b!=0){f=BD(n.b==0?null:(sCb(n.b!=0),Nsb(n,n.a.a)),307);e=f.j.d.c;for(m=f.a.a.ec().Kc();m.Ob();){k=BD(m.Pb(),57);p=f.k+k.b.a;!UDb(a,f,a.d)||k.d.c<p?(k.i=p):(k.i=k.d.c)}e-=f.j.i;f.b+=e;a.d==(ead(),bad)||a.d==_9c?(f.c+=e):(f.c-=e);for(l=f.a.a.ec().Kc();l.Ob();){k=BD(l.Pb(),57);for(i=k.c.Kc();i.Ob();){h=BD(i.Pb(),57);fad(a.d)?(o=a.g.Oe(k,h)):(o=a.g.Pe(k,h));h.a.k=$wnd.Math.max(h.a.k,k.i+k.d.b+o-h.b.a);VDb(a,h,a.d)&&(h.a.k=$wnd.Math.max(h.a.k,h.d.c-h.b.a));--h.a.g;h.a.g==0&&Dsb(n,h.a)}}}for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),57);b.d.c=b.i}};var RM=mdb(Gke,'LongestPathCompaction',1790);bcb(1690,1,{},cEb);_.e=false;var LDb,MDb,NDb;var TM=mdb(Gke,Nke,1690);bcb(1691,1,qie,dEb);_.td=function eEb(a){WDb(this.a,BD(a,46))};var SM=mdb(Gke,Oke,1691);bcb(1791,1,{},fEb);_.Me=function gEb(a){var b,c,d,e,f,g,h;for(c=new olb(a.a.b);c.a<c.c.c.length;){b=BD(mlb(c),57);b.c.$b()}for(e=new olb(a.a.b);e.a<e.c.c.length;){d=BD(mlb(e),57);for(g=new olb(a.a.b);g.a<g.c.c.length;){f=BD(mlb(g),57);if(d==f){continue}if(!!d.a&&d.a==f.a){continue}fad(a.d)?(h=a.g.Pe(d,f)):(h=a.g.Oe(d,f));(f.d.c>d.d.c||d.d.c==f.d.c&&d.d.b<f.d.b)&&BDb(f.d.d+f.d.a+h,d.d.d)&&DDb(f.d.d,d.d.d+d.d.a+h)&&d.c.Fc(f)}}};var UM=mdb(Gke,'QuadraticConstraintCalculation',1791);bcb(522,1,{522:1},lEb);_.a=false;_.b=false;_.c=false;_.d=false;var VM=mdb(Gke,Pke,522);bcb(803,1,{},oEb);_.Me=function pEb(a){this.c=a;nEb(this,new GEb)};var _M=mdb(Gke,Qke,803);bcb(1718,1,{679:1},uEb);_.Ke=function vEb(a){rEb(this,BD(a,464))};var XM=mdb(Gke,Rke,1718);bcb(1719,1,Dke,xEb);_.ue=function yEb(a,b){return wEb(BD(a,57),BD(b,57))};_.Fb=function zEb(a){return this===a};_.ve=function AEb(){return new tpb(this)};var WM=mdb(Gke,Ske,1719);bcb(464,1,{464:1},BEb);_.a=false;var YM=mdb(Gke,Tke,464);bcb(1720,1,Dke,CEb);_.ue=function DEb(a,b){return qEb(BD(a,464),BD(b,464))};_.Fb=function EEb(a){return this===a};_.ve=function FEb(){return new tpb(this)};var ZM=mdb(Gke,Uke,1720);bcb(1721,1,Vke,GEb);_.Lb=function HEb(a){return BD(a,57),true};_.Fb=function IEb(a){return this===a};_.Mb=function JEb(a){return BD(a,57),true};var $M=mdb(Gke,'ScanlineConstraintCalculator/lambda$1$Type',1721);bcb(428,22,{3:1,35:1,22:1,428:1},NEb);var KEb,LEb;var aN=ndb(Wke,'HighLevelSortingCriterion',428,CI,PEb,OEb);var QEb;bcb(427,22,{3:1,35:1,22:1,427:1},VEb);var SEb,TEb;var bN=ndb(Wke,'LowLevelSortingCriterion',427,CI,XEb,WEb);var YEb;var C0=odb(Xke,'ILayoutMetaDataProvider');bcb(853,1,ale,gFb);_.Qe=function hFb(a){t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Yke),ble),'Polyomino Traversal Strategy'),'Traversal strategy for trying different candidate positions for polyominoes.'),eFb),(_5c(),V5c)),dN),pqb((N5c(),L5c)))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Zke),ble),'Polyomino Secondary Sorting Criterion'),'Possible secondary sorting criteria for the processing order of polyominoes. They are used when polyominoes are equal according to the primary sorting criterion HighLevelSortingCriterion.'),cFb),V5c),bN),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,$ke),ble),'Polyomino Primary Sorting Criterion'),'Possible primary sorting criteria for the processing order of polyominoes.'),aFb),V5c),aN),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,_ke),ble),'Fill Polyominoes'),'Use the Profile Fill algorithm to fill polyominoes to prevent small polyominoes from being placed inside of big polyominoes with large holes. Might increase packing area.'),(Bcb(),true)),T5c),wI),pqb(L5c))))};var $Eb,_Eb,aFb,bFb,cFb,dFb,eFb;var cN=mdb(Wke,'PolyominoOptions',853);bcb(250,22,{3:1,35:1,22:1,250:1},sFb);var iFb,jFb,kFb,lFb,mFb,nFb,oFb,pFb,qFb;var dN=ndb(Wke,'TraversalStrategy',250,CI,uFb,tFb);var vFb;bcb(213,1,{213:1},yFb);_.Ib=function zFb(){return 'NEdge[id='+this.b+' w='+this.g+' d='+this.a+']'};_.a=1;_.b=0;_.c=0;_.f=false;_.g=0;var fN=mdb(cle,'NEdge',213);bcb(176,1,{},FFb);var eN=mdb(cle,'NEdge/NEdgeBuilder',176);bcb(653,1,{},KFb);var gN=mdb(cle,'NGraph',653);bcb(121,1,{121:1},MFb);_.c=-1;_.d=0;_.e=0;_.i=-1;_.j=false;var jN=mdb(cle,'NNode',121);bcb(795,1,cke,PFb);_.Jc=function XFb(a){reb(this,a)};_.Lc=function cGb(){return new YAb(null,new Kub(this,16))};_.ad=function hGb(a){ktb(this,a)};_.Nc=function iGb(){return new Kub(this,16)};_.Oc=function jGb(){return new YAb(null,new Kub(this,16))};_.Vc=function QFb(a,b){++this.b;Dkb(this.a,a,b)};_.Fc=function RFb(a){return NFb(this,a)};_.Wc=function SFb(a,b){++this.b;return Fkb(this.a,a,b)};_.Gc=function TFb(a){++this.b;return Gkb(this.a,a)};_.$b=function UFb(){++this.b;this.a.c=KC(SI,Uhe,1,0,5,1)};_.Hc=function VFb(a){return Jkb(this.a,a,0)!=-1};_.Ic=function WFb(a){return Be(this.a,a)};_.Xb=function YFb(a){return Ikb(this.a,a)};_.Xc=function ZFb(a){return Jkb(this.a,a,0)};_.dc=function $Fb(){return this.a.c.length==0};_.Kc=function _Fb(){return vr(new olb(this.a))};_.Yc=function aGb(){throw vbb(new bgb)};_.Zc=function bGb(a){throw vbb(new bgb)};_.$c=function dGb(a){++this.b;return Kkb(this.a,a)};_.Mc=function eGb(a){return OFb(this,a)};_._c=function fGb(a,b){++this.b;return Nkb(this.a,a,b)};_.gc=function gGb(){return this.a.c.length};_.bd=function kGb(a,b){return new Jib(this.a,a,b)};_.Pc=function lGb(){return Pkb(this.a)};_.Qc=function mGb(a){return Qkb(this.a,a)};_.b=0;var hN=mdb(cle,'NNode/ChangeAwareArrayList',795);bcb(269,1,{},pGb);var iN=mdb(cle,'NNode/NNodeBuilder',269);bcb(1630,1,{},KGb);_.a=false;_.f=Ohe;_.j=0;var kN=mdb(cle,'NetworkSimplex',1630);bcb(1294,1,qie,QGb);_.td=function RGb(a){PGb(this.a,BD(a,680),true,false)};var lN=mdb(ele,'NodeLabelAndSizeCalculator/lambda$0$Type',1294);bcb(558,1,{},YGb);_.b=true;_.c=true;_.d=true;_.e=true;var mN=mdb(ele,'NodeMarginCalculator',558);bcb(212,1,{212:1});_.j=false;_.k=false;var oN=mdb(fle,'Cell',212);bcb(124,212,{124:1,212:1},aHb);_.Re=function bHb(){return _Gb(this)};_.Se=function cHb(){var a;a=this.n;return this.a.a+a.b+a.c};var nN=mdb(fle,'AtomicCell',124);bcb(232,22,{3:1,35:1,22:1,232:1},hHb);var dHb,eHb,fHb;var pN=ndb(fle,'ContainerArea',232,CI,jHb,iHb);var kHb;bcb(326,212,hle);var qN=mdb(fle,'ContainerCell',326);bcb(1473,326,hle,FHb);_.Re=function GHb(){var a;a=0;this.e?this.b?(a=this.b.b):!!this.a[1][1]&&(a=this.a[1][1].Re()):(a=EHb(this,AHb(this,true)));return a>0?a+this.n.d+this.n.a:0};_.Se=function HHb(){var a,b,c,d,e;e=0;if(this.e){this.b?(e=this.b.a):!!this.a[1][1]&&(e=this.a[1][1].Se())}else if(this.g){e=EHb(this,yHb(this,null,true))}else{for(b=(gHb(),OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb])),c=0,d=b.length;c<d;++c){a=b[c];e=$wnd.Math.max(e,EHb(this,yHb(this,a,true)))}}return e>0?e+this.n.b+this.n.c:0};_.Te=function IHb(){var a,b,c,d,e;if(this.g){a=yHb(this,null,false);for(c=(gHb(),OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb])),d=0,e=c.length;d<e;++d){b=c[d];wHb(this,b,a)}}else{for(c=(gHb(),OC(GC(pN,1),Kie,232,0,[dHb,eHb,fHb])),d=0,e=c.length;d<e;++d){b=c[d];a=yHb(this,b,false);wHb(this,b,a)}}};_.Ue=function JHb(){var a,b,c,d;b=this.i;a=this.n;d=AHb(this,false);uHb(this,(gHb(),dHb),b.d+a.d,d);uHb(this,fHb,b.d+b.a-a.a-d[2],d);c=b.a-a.d-a.a;if(d[0]>0){d[0]+=this.d;c-=d[0]}if(d[2]>0){d[2]+=this.d;c-=d[2]}this.c.a=$wnd.Math.max(0,c);this.c.d=b.d+a.d+(this.c.a-c)/2;d[1]=$wnd.Math.max(d[1],c);uHb(this,eHb,b.d+a.d+d[0]-(d[1]-c)/2,d)};_.b=null;_.d=0;_.e=false;_.f=false;_.g=false;var rHb=0,sHb=0;var rN=mdb(fle,'GridContainerCell',1473);bcb(461,22,{3:1,35:1,22:1,461:1},OHb);var KHb,LHb,MHb;var sN=ndb(fle,'HorizontalLabelAlignment',461,CI,QHb,PHb);var RHb;bcb(306,212,{212:1,306:1},aIb,bIb,cIb);_.Re=function dIb(){return YHb(this)};_.Se=function eIb(){return ZHb(this)};_.a=0;_.c=false;var tN=mdb(fle,'LabelCell',306);bcb(244,326,{212:1,326:1,244:1},mIb);_.Re=function nIb(){return fIb(this)};_.Se=function oIb(){return gIb(this)};_.Te=function rIb(){hIb(this)};_.Ue=function sIb(){iIb(this)};_.b=0;_.c=0;_.d=false;var yN=mdb(fle,'StripContainerCell',244);bcb(1626,1,Oie,tIb);_.Mb=function uIb(a){return pIb(BD(a,212))};var uN=mdb(fle,'StripContainerCell/lambda$0$Type',1626);bcb(1627,1,{},vIb);_.Fe=function wIb(a){return BD(a,212).Se()};var vN=mdb(fle,'StripContainerCell/lambda$1$Type',1627);bcb(1628,1,Oie,xIb);_.Mb=function yIb(a){return qIb(BD(a,212))};var wN=mdb(fle,'StripContainerCell/lambda$2$Type',1628);bcb(1629,1,{},zIb);_.Fe=function AIb(a){return BD(a,212).Re()};var xN=mdb(fle,'StripContainerCell/lambda$3$Type',1629);bcb(462,22,{3:1,35:1,22:1,462:1},FIb);var BIb,CIb,DIb;var zN=ndb(fle,'VerticalLabelAlignment',462,CI,HIb,GIb);var IIb;bcb(789,1,{},LIb);_.c=0;_.d=0;_.k=0;_.s=0;_.t=0;_.v=false;_.w=0;_.D=false;var CN=mdb(nle,'NodeContext',789);bcb(1471,1,Dke,OIb);_.ue=function PIb(a,b){return NIb(BD(a,61),BD(b,61))};_.Fb=function QIb(a){return this===a};_.ve=function RIb(){return new tpb(this)};var AN=mdb(nle,'NodeContext/0methodref$comparePortSides$Type',1471);bcb(1472,1,Dke,SIb);_.ue=function TIb(a,b){return MIb(BD(a,111),BD(b,111))};_.Fb=function UIb(a){return this===a};_.ve=function VIb(){return new tpb(this)};var BN=mdb(nle,'NodeContext/1methodref$comparePortContexts$Type',1472);bcb(159,22,{3:1,35:1,22:1,159:1},tJb);var WIb,XIb,YIb,ZIb,$Ib,_Ib,aJb,bJb,cJb,dJb,eJb,fJb,gJb,hJb,iJb,jJb,kJb,lJb,mJb,nJb,oJb,pJb;var DN=ndb(nle,'NodeLabelLocation',159,CI,wJb,vJb);var xJb;bcb(111,1,{111:1},AJb);_.a=false;var EN=mdb(nle,'PortContext',111);bcb(1476,1,qie,TJb);_.td=function UJb(a){WHb(BD(a,306))};var FN=mdb(qle,rle,1476);bcb(1477,1,Oie,VJb);_.Mb=function WJb(a){return !!BD(a,111).c};var GN=mdb(qle,sle,1477);bcb(1478,1,qie,XJb);_.td=function YJb(a){WHb(BD(a,111).c)};var HN=mdb(qle,'LabelPlacer/lambda$2$Type',1478);var ZJb;bcb(1475,1,qie,fKb);_.td=function gKb(a){$Jb();zJb(BD(a,111))};var IN=mdb(qle,'NodeLabelAndSizeUtilities/lambda$0$Type',1475);bcb(790,1,qie,mKb);_.td=function nKb(a){kKb(this.b,this.c,this.a,BD(a,181))};_.a=false;_.c=false;var JN=mdb(qle,'NodeLabelCellCreator/lambda$0$Type',790);bcb(1474,1,qie,tKb);_.td=function uKb(a){sKb(this.a,BD(a,181))};var KN=mdb(qle,'PortContextCreator/lambda$0$Type',1474);var BKb;bcb(1829,1,{},VKb);var MN=mdb(ule,'GreedyRectangleStripOverlapRemover',1829);bcb(1830,1,Dke,XKb);_.ue=function YKb(a,b){return WKb(BD(a,222),BD(b,222))};_.Fb=function ZKb(a){return this===a};_.ve=function $Kb(){return new tpb(this)};var LN=mdb(ule,'GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type',1830);bcb(1786,1,{},fLb);_.a=5;_.e=0;var SN=mdb(ule,'RectangleStripOverlapRemover',1786);bcb(1787,1,Dke,jLb);_.ue=function kLb(a,b){return gLb(BD(a,222),BD(b,222))};_.Fb=function lLb(a){return this===a};_.ve=function mLb(){return new tpb(this)};var NN=mdb(ule,'RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type',1787);bcb(1789,1,Dke,nLb);_.ue=function oLb(a,b){return hLb(BD(a,222),BD(b,222))};_.Fb=function pLb(a){return this===a};_.ve=function qLb(){return new tpb(this)};var ON=mdb(ule,'RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type',1789);bcb(406,22,{3:1,35:1,22:1,406:1},wLb);var rLb,sLb,tLb,uLb;var PN=ndb(ule,'RectangleStripOverlapRemover/OverlapRemovalDirection',406,CI,yLb,xLb);var zLb;bcb(222,1,{222:1},BLb);var QN=mdb(ule,'RectangleStripOverlapRemover/RectangleNode',222);bcb(1788,1,qie,CLb);_.td=function DLb(a){aLb(this.a,BD(a,222))};var RN=mdb(ule,'RectangleStripOverlapRemover/lambda$1$Type',1788);bcb(1304,1,Dke,GLb);_.ue=function HLb(a,b){return FLb(BD(a,167),BD(b,167))};_.Fb=function ILb(a){return this===a};_.ve=function JLb(){return new tpb(this)};var WN=mdb(wle,'PolyominoCompactor/CornerCasesGreaterThanRestComparator',1304);bcb(1307,1,{},KLb);_.Kb=function LLb(a){return BD(a,324).a};var TN=mdb(wle,'PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$0$Type',1307);bcb(1308,1,Oie,MLb);_.Mb=function NLb(a){return BD(a,323).a};var UN=mdb(wle,'PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$1$Type',1308);bcb(1309,1,Oie,OLb);_.Mb=function PLb(a){return BD(a,323).a};var VN=mdb(wle,'PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$2$Type',1309);bcb(1302,1,Dke,RLb);_.ue=function SLb(a,b){return QLb(BD(a,167),BD(b,167))};_.Fb=function TLb(a){return this===a};_.ve=function ULb(){return new tpb(this)};var YN=mdb(wle,'PolyominoCompactor/MinNumOfExtensionDirectionsComparator',1302);bcb(1305,1,{},VLb);_.Kb=function WLb(a){return BD(a,324).a};var XN=mdb(wle,'PolyominoCompactor/MinNumOfExtensionDirectionsComparator/lambda$0$Type',1305);bcb(767,1,Dke,YLb);_.ue=function ZLb(a,b){return XLb(BD(a,167),BD(b,167))};_.Fb=function $Lb(a){return this===a};_.ve=function _Lb(){return new tpb(this)};var ZN=mdb(wle,'PolyominoCompactor/MinNumOfExtensionsComparator',767);bcb(1300,1,Dke,bMb);_.ue=function cMb(a,b){return aMb(BD(a,321),BD(b,321))};_.Fb=function dMb(a){return this===a};_.ve=function eMb(){return new tpb(this)};var _N=mdb(wle,'PolyominoCompactor/MinPerimeterComparator',1300);bcb(1301,1,Dke,gMb);_.ue=function hMb(a,b){return fMb(BD(a,321),BD(b,321))};_.Fb=function iMb(a){return this===a};_.ve=function jMb(){return new tpb(this)};var $N=mdb(wle,'PolyominoCompactor/MinPerimeterComparatorWithShape',1301);bcb(1303,1,Dke,lMb);_.ue=function mMb(a,b){return kMb(BD(a,167),BD(b,167))};_.Fb=function nMb(a){return this===a};_.ve=function oMb(){return new tpb(this)};var bO=mdb(wle,'PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator',1303);bcb(1306,1,{},pMb);_.Kb=function qMb(a){return BD(a,324).a};var aO=mdb(wle,'PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator/lambda$0$Type',1306);bcb(777,1,{},tMb);_.Ce=function uMb(a,b){return sMb(this,BD(a,46),BD(b,167))};var cO=mdb(wle,'SuccessorCombination',777);bcb(644,1,{},wMb);_.Ce=function xMb(a,b){var c;return vMb((c=BD(a,46),BD(b,167),c))};var dO=mdb(wle,'SuccessorJitter',644);bcb(643,1,{},zMb);_.Ce=function AMb(a,b){var c;return yMb((c=BD(a,46),BD(b,167),c))};var eO=mdb(wle,'SuccessorLineByLine',643);bcb(568,1,{},CMb);_.Ce=function DMb(a,b){var c;return BMb((c=BD(a,46),BD(b,167),c))};var fO=mdb(wle,'SuccessorManhattan',568);bcb(1356,1,{},FMb);_.Ce=function GMb(a,b){var c;return EMb((c=BD(a,46),BD(b,167),c))};var gO=mdb(wle,'SuccessorMaxNormWindingInMathPosSense',1356);bcb(400,1,{},JMb);_.Ce=function KMb(a,b){return HMb(this,a,b)};_.c=false;_.d=false;_.e=false;_.f=false;var iO=mdb(wle,'SuccessorQuadrantsGeneric',400);bcb(1357,1,{},LMb);_.Kb=function MMb(a){return BD(a,324).a};var hO=mdb(wle,'SuccessorQuadrantsGeneric/lambda$0$Type',1357);bcb(323,22,{3:1,35:1,22:1,323:1},SMb);_.a=false;var NMb,OMb,PMb,QMb;var jO=ndb(Ble,Cle,323,CI,UMb,TMb);var VMb;bcb(1298,1,{});_.Ib=function bNb(){var a,b,c,d,e,f;c=' ';a=meb(0);for(e=0;e<this.o;e++){c+=''+a.a;a=meb(XMb(a.a))}c+='\n';a=meb(0);for(f=0;f<this.p;f++){c+=''+a.a;a=meb(XMb(a.a));for(d=0;d<this.o;d++){b=_Mb(this,d,f);ybb(b,0)==0?(c+='_'):ybb(b,1)==0?(c+='X'):(c+='0')}c+='\n'}return qfb(c,0,c.length-1)};_.o=0;_.p=0;var nO=mdb(Ble,'TwoBitGrid',1298);bcb(321,1298,{321:1},pNb);_.j=0;_.k=0;var kO=mdb(Ble,'PlanarGrid',321);bcb(167,321,{321:1,167:1});_.g=0;_.i=0;var lO=mdb(Ble,'Polyomino',167);var P3=odb(Hle,Ile);bcb(134,1,Jle,zNb);_.Ye=function DNb(a,b){return xNb(this,a,b)};_.Ve=function ANb(){return uNb(this)};_.We=function BNb(a){return vNb(this,a)};_.Xe=function CNb(a){return wNb(this,a)};var R3=mdb(Hle,'MapPropertyHolder',134);bcb(1299,134,Jle,ENb);var mO=mdb(Ble,'Polyominoes',1299);var FNb=false,GNb,HNb;bcb(1766,1,qie,PNb);_.td=function QNb(a){JNb(BD(a,221))};var oO=mdb(Kle,'DepthFirstCompaction/0methodref$compactTree$Type',1766);bcb(810,1,qie,RNb);_.td=function SNb(a){MNb(this.a,BD(a,221))};var pO=mdb(Kle,'DepthFirstCompaction/lambda$1$Type',810);bcb(1767,1,qie,TNb);_.td=function UNb(a){NNb(this.a,this.b,this.c,BD(a,221))};var qO=mdb(Kle,'DepthFirstCompaction/lambda$2$Type',1767);var VNb,WNb;bcb(65,1,{65:1},aOb);var rO=mdb(Kle,'Node',65);bcb(1250,1,{},dOb);var wO=mdb(Kle,'ScanlineOverlapCheck',1250);bcb(1251,1,{679:1},hOb);_.Ke=function iOb(a){fOb(this,BD(a,440))};var tO=mdb(Kle,'ScanlineOverlapCheck/OverlapsScanlineHandler',1251);bcb(1252,1,Dke,kOb);_.ue=function lOb(a,b){return jOb(BD(a,65),BD(b,65))};_.Fb=function mOb(a){return this===a};_.ve=function nOb(){return new tpb(this)};var sO=mdb(Kle,'ScanlineOverlapCheck/OverlapsScanlineHandler/lambda$0$Type',1252);bcb(440,1,{440:1},oOb);_.a=false;var uO=mdb(Kle,'ScanlineOverlapCheck/Timestamp',440);bcb(1253,1,Dke,pOb);_.ue=function qOb(a,b){return eOb(BD(a,440),BD(b,440))};_.Fb=function rOb(a){return this===a};_.ve=function sOb(){return new tpb(this)};var vO=mdb(Kle,'ScanlineOverlapCheck/lambda$0$Type',1253);bcb(550,1,{},tOb);var xO=mdb(Lle,'SVGImage',550);bcb(324,1,{324:1},uOb);_.Ib=function vOb(){return '('+this.a+She+this.b+She+this.c+')'};var yO=mdb(Lle,'UniqueTriple',324);bcb(209,1,Mle);var g0=mdb(Nle,'AbstractLayoutProvider',209);bcb(1132,209,Mle,yOb);_.Ze=function zOb(a,b){var c,d,e,f;Odd(b,Ole,1);this.a=Edb(ED(hkd(a,(CPb(),BPb))));if(ikd(a,rPb)){e=GD(hkd(a,rPb));c=h4c(n4c(),e);if(c){d=BD(hgd(c.f),209);d.Ze(a,Udd(b,1))}}f=new AQb(this.a);this.b=yQb(f,a);switch(BD(hkd(a,(nPb(),jPb)),481).g){case 0:BOb(new FOb,this.b);jkd(a,uPb,vNb(this.b,uPb));break;default:Zfb();}qQb(f);jkd(a,tPb,this.b);Qdd(b)};_.a=0;var zO=mdb(Ple,'DisCoLayoutProvider',1132);bcb(1244,1,{},FOb);_.c=false;_.e=0;_.f=0;var AO=mdb(Ple,'DisCoPolyominoCompactor',1244);bcb(561,1,{561:1},MOb);_.b=true;var BO=mdb(Qle,'DCComponent',561);bcb(394,22,{3:1,35:1,22:1,394:1},SOb);_.a=false;var NOb,OOb,POb,QOb;var CO=ndb(Qle,'DCDirection',394,CI,UOb,TOb);var VOb;bcb(266,134,{3:1,266:1,94:1,134:1},XOb);var DO=mdb(Qle,'DCElement',266);bcb(395,1,{395:1},ZOb);_.c=0;var EO=mdb(Qle,'DCExtension',395);bcb(755,134,Jle,aPb);var FO=mdb(Qle,'DCGraph',755);bcb(481,22,{3:1,35:1,22:1,481:1},dPb);var bPb;var GO=ndb(Rle,Sle,481,CI,fPb,ePb);var gPb;bcb(854,1,ale,oPb);_.Qe=function pPb(a){t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Tle),Xle),'Connected Components Compaction Strategy'),'Strategy for packing different connected components in order to save space and enhance readability of a graph.'),kPb),(_5c(),V5c)),GO),pqb((N5c(),L5c)))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Ule),Xle),'Connected Components Layout Algorithm'),"A layout algorithm that is to be applied to each connected component before the components themselves are compacted. If unspecified, the positions of the components' nodes are not altered."),Z5c),ZI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Vle),'debug'),'DCGraph'),'Access to the DCGraph is intended for the debug view,'),Y5c),SI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Wle),'debug'),'List of Polyominoes'),'Access to the polyominoes is intended for the debug view,'),Y5c),SI),pqb(L5c))));DPb((new EPb,a))};var iPb,jPb,kPb,lPb,mPb;var HO=mdb(Rle,'DisCoMetaDataProvider',854);bcb(998,1,ale,EPb);_.Qe=function FPb(a){DPb(a)};var qPb,rPb,sPb,tPb,uPb,vPb,wPb,xPb,yPb,zPb,APb,BPb;var JO=mdb(Rle,'DisCoOptions',998);bcb(999,1,{},GPb);_.$e=function HPb(){var a;return a=new yOb,a};_._e=function IPb(a){};var IO=mdb(Rle,'DisCoOptions/DiscoFactory',999);bcb(562,167,{321:1,167:1,562:1},MPb);_.a=0;_.b=0;_.c=0;_.d=0;var KO=mdb('org.eclipse.elk.alg.disco.structures','DCPolyomino',562);var NPb,OPb,PPb;bcb(1268,1,Oie,aQb);_.Mb=function bQb(a){return _Pb(a)};var LO=mdb(bme,'ElkGraphComponentsProcessor/lambda$0$Type',1268);bcb(1269,1,{},cQb);_.Kb=function dQb(a){return QPb(),jtd(BD(a,79))};var MO=mdb(bme,'ElkGraphComponentsProcessor/lambda$1$Type',1269);bcb(1270,1,Oie,eQb);_.Mb=function fQb(a){return WPb(BD(a,79))};var NO=mdb(bme,'ElkGraphComponentsProcessor/lambda$2$Type',1270);bcb(1271,1,{},gQb);_.Kb=function hQb(a){return QPb(),ltd(BD(a,79))};var OO=mdb(bme,'ElkGraphComponentsProcessor/lambda$3$Type',1271);bcb(1272,1,Oie,iQb);_.Mb=function jQb(a){return XPb(BD(a,79))};var PO=mdb(bme,'ElkGraphComponentsProcessor/lambda$4$Type',1272);bcb(1273,1,Oie,kQb);_.Mb=function lQb(a){return YPb(this.a,BD(a,79))};var QO=mdb(bme,'ElkGraphComponentsProcessor/lambda$5$Type',1273);bcb(1274,1,{},mQb);_.Kb=function nQb(a){return ZPb(this.a,BD(a,79))};var RO=mdb(bme,'ElkGraphComponentsProcessor/lambda$6$Type',1274);bcb(1241,1,{},AQb);_.a=0;var UO=mdb(bme,'ElkGraphTransformer',1241);bcb(1242,1,{},CQb);_.Od=function DQb(a,b){BQb(this,BD(a,160),BD(b,266))};var TO=mdb(bme,'ElkGraphTransformer/OffsetApplier',1242);bcb(1243,1,qie,FQb);_.td=function GQb(a){EQb(this,BD(a,8))};var SO=mdb(bme,'ElkGraphTransformer/OffsetApplier/OffSetToChainApplier',1243);bcb(753,1,{},MQb);var WO=mdb(gme,hme,753);bcb(1232,1,Dke,OQb);_.ue=function PQb(a,b){return NQb(BD(a,231),BD(b,231))};_.Fb=function QQb(a){return this===a};_.ve=function RQb(){return new tpb(this)};var VO=mdb(gme,ime,1232);bcb(740,209,Mle,ZQb);_.Ze=function $Qb(a,b){WQb(this,a,b)};var XO=mdb(gme,'ForceLayoutProvider',740);bcb(357,134,{3:1,357:1,94:1,134:1});var bP=mdb(jme,'FParticle',357);bcb(559,357,{3:1,559:1,357:1,94:1,134:1},aRb);_.Ib=function bRb(){var a;if(this.a){a=Jkb(this.a.a,this,0);return a>=0?'b'+a+'['+fRb(this.a)+']':'b['+fRb(this.a)+']'}return 'b_'+FCb(this)};var YO=mdb(jme,'FBendpoint',559);bcb(282,134,{3:1,282:1,94:1,134:1},gRb);_.Ib=function hRb(){return fRb(this)};var ZO=mdb(jme,'FEdge',282);bcb(231,134,{3:1,231:1,94:1,134:1},kRb);var $O=mdb(jme,'FGraph',231);bcb(447,357,{3:1,447:1,357:1,94:1,134:1},mRb);_.Ib=function nRb(){return this.b==null||this.b.length==0?'l['+fRb(this.a)+']':'l_'+this.b};var _O=mdb(jme,'FLabel',447);bcb(144,357,{3:1,144:1,357:1,94:1,134:1},pRb);_.Ib=function qRb(){return oRb(this)};_.b=0;var aP=mdb(jme,'FNode',144);bcb(2003,1,{});_.bf=function vRb(a){rRb(this,a)};_.cf=function wRb(){sRb(this)};_.d=0;var cP=mdb(lme,'AbstractForceModel',2003);bcb(631,2003,{631:1},xRb);_.af=function zRb(a,b){var c,d,e,f,g;uRb(this.f,a,b);e=c7c(R6c(b.d),a.d);g=$wnd.Math.sqrt(e.a*e.a+e.b*e.b);d=$wnd.Math.max(0,g-U6c(a.e)/2-U6c(b.e)/2);c=jRb(this.e,a,b);c>0?(f=-yRb(d,this.c)*c):(f=CRb(d,this.b)*BD(vNb(a,(wSb(),oSb)),19).a);Y6c(e,f/g);return e};_.bf=function ARb(a){rRb(this,a);this.a=BD(vNb(a,(wSb(),eSb)),19).a;this.c=Edb(ED(vNb(a,uSb)));this.b=Edb(ED(vNb(a,qSb)))};_.df=function BRb(a){return a<this.a};_.a=0;_.b=0;_.c=0;var dP=mdb(lme,'EadesModel',631);bcb(632,2003,{632:1},DRb);_.af=function FRb(a,b){var c,d,e,f,g;uRb(this.f,a,b);e=c7c(R6c(b.d),a.d);g=$wnd.Math.sqrt(e.a*e.a+e.b*e.b);d=$wnd.Math.max(0,g-U6c(a.e)/2-U6c(b.e)/2);f=JRb(d,this.a)*BD(vNb(a,(wSb(),oSb)),19).a;c=jRb(this.e,a,b);c>0&&(f-=ERb(d,this.a)*c);Y6c(e,f*this.b/g);return e};_.bf=function GRb(a){var b,c,d,e,f,g,h;rRb(this,a);this.b=Edb(ED(vNb(a,(wSb(),vSb))));this.c=this.b/BD(vNb(a,eSb),19).a;d=a.e.c.length;f=0;e=0;for(h=new olb(a.e);h.a<h.c.c.length;){g=BD(mlb(h),144);f+=g.e.a;e+=g.e.b}b=f*e;c=Edb(ED(vNb(a,uSb)))*ple;this.a=$wnd.Math.sqrt(b/(2*d))*c};_.cf=function HRb(){sRb(this);this.b-=this.c};_.df=function IRb(a){return this.b>0};_.a=0;_.b=0;_.c=0;var eP=mdb(lme,'FruchtermanReingoldModel',632);bcb(849,1,ale,TRb);_.Qe=function URb(a){t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,mme),''),'Force Model'),'Determines the model for force calculation.'),MRb),(_5c(),V5c)),gP),pqb((N5c(),L5c)))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,nme),''),'Iterations'),'The number of iterations on the force model.'),meb(300)),X5c),JI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,ome),''),'Repulsive Power'),'Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model'),meb(0)),X5c),JI),pqb(I5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,pme),''),'FR Temperature'),'The temperature is used as a scaling factor for particle displacements.'),qme),U5c),BI),pqb(L5c))));o4c(a,pme,mme,RRb);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,rme),''),'Eades Repulsion'),"Factor for repulsive forces in Eades' model."),5),U5c),BI),pqb(L5c))));o4c(a,rme,mme,ORb);xSb((new ySb,a))};var KRb,LRb,MRb,NRb,ORb,PRb,QRb,RRb;var fP=mdb(sme,'ForceMetaDataProvider',849);bcb(424,22,{3:1,35:1,22:1,424:1},YRb);var VRb,WRb;var gP=ndb(sme,'ForceModelStrategy',424,CI,$Rb,ZRb);var _Rb;bcb(988,1,ale,ySb);_.Qe=function zSb(a){xSb(a)};var bSb,cSb,dSb,eSb,fSb,gSb,hSb,iSb,jSb,kSb,lSb,mSb,nSb,oSb,pSb,qSb,rSb,sSb,tSb,uSb,vSb;var iP=mdb(sme,'ForceOptions',988);bcb(989,1,{},ASb);_.$e=function BSb(){var a;return a=new ZQb,a};_._e=function CSb(a){};var hP=mdb(sme,'ForceOptions/ForceFactory',989);var DSb,ESb,FSb,GSb;bcb(850,1,ale,PSb);_.Qe=function QSb(a){t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Mme),''),'Fixed Position'),'Prevent that the node is moved by the layout algorithm.'),(Bcb(),false)),(_5c(),T5c)),wI),pqb((N5c(),K5c)))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Nme),''),'Desired Edge Length'),'Either specified for parent nodes or for individual edges, where the latter takes higher precedence.'),100),U5c),BI),qqb(L5c,OC(GC(e1,1),Kie,175,0,[I5c])))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ome),''),'Layout Dimension'),'Dimensions that are permitted to be altered during layout.'),KSb),V5c),oP),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Pme),''),'Stress Epsilon'),'Termination criterion for the iterative process.'),qme),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Qme),''),'Iteration Limit'),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),meb(Ohe)),X5c),JI),pqb(L5c))));cTb((new dTb,a))};var ISb,JSb,KSb,LSb,MSb,NSb;var jP=mdb(sme,'StressMetaDataProvider',850);bcb(992,1,ale,dTb);_.Qe=function eTb(a){cTb(a)};var RSb,SSb,TSb,USb,VSb,WSb,XSb,YSb,ZSb,$Sb,_Sb,aTb;var lP=mdb(sme,'StressOptions',992);bcb(993,1,{},fTb);_.$e=function gTb(){var a;return a=new iTb,a};_._e=function hTb(a){};var kP=mdb(sme,'StressOptions/StressFactory',993);bcb(1128,209,Mle,iTb);_.Ze=function jTb(a,b){var c,d,e,f,g;Odd(b,Sme,1);Ccb(DD(hkd(a,(bTb(),VSb))))?Ccb(DD(hkd(a,_Sb)))||$Cb((c=new _Cb((Pgd(),new bhd(a))),c)):WQb(new ZQb,a,Udd(b,1));e=TQb(a);d=LQb(this.a,e);for(g=d.Kc();g.Ob();){f=BD(g.Pb(),231);if(f.e.c.length<=1){continue}sTb(this.b,f);qTb(this.b);Hkb(f.d,new kTb)}e=KQb(d);SQb(e);Qdd(b)};var nP=mdb(Ume,'StressLayoutProvider',1128);bcb(1129,1,qie,kTb);_.td=function lTb(a){lRb(BD(a,447))};var mP=mdb(Ume,'StressLayoutProvider/lambda$0$Type',1129);bcb(990,1,{},tTb);_.c=0;_.e=0;_.g=0;var qP=mdb(Ume,'StressMajorization',990);bcb(379,22,{3:1,35:1,22:1,379:1},zTb);var vTb,wTb,xTb;var oP=ndb(Ume,'StressMajorization/Dimension',379,CI,BTb,ATb);var CTb;bcb(991,1,Dke,ETb);_.ue=function FTb(a,b){return uTb(this.a,BD(a,144),BD(b,144))};_.Fb=function GTb(a){return this===a};_.ve=function HTb(){return new tpb(this)};var pP=mdb(Ume,'StressMajorization/lambda$0$Type',991);bcb(1229,1,{},PTb);var tP=mdb(Wme,'ElkLayered',1229);bcb(1230,1,qie,STb);_.td=function TTb(a){QTb(BD(a,37))};var rP=mdb(Wme,'ElkLayered/lambda$0$Type',1230);bcb(1231,1,qie,UTb);_.td=function VTb(a){RTb(this.a,BD(a,37))};var sP=mdb(Wme,'ElkLayered/lambda$1$Type',1231);bcb(1263,1,{},bUb);var WTb,XTb,YTb;var xP=mdb(Wme,'GraphConfigurator',1263);bcb(759,1,qie,dUb);_.td=function eUb(a){$Tb(this.a,BD(a,10))};var uP=mdb(Wme,'GraphConfigurator/lambda$0$Type',759);bcb(760,1,{},fUb);_.Kb=function gUb(a){return ZTb(),new YAb(null,new Kub(BD(a,29).a,16))};var vP=mdb(Wme,'GraphConfigurator/lambda$1$Type',760);bcb(761,1,qie,hUb);_.td=function iUb(a){$Tb(this.a,BD(a,10))};var wP=mdb(Wme,'GraphConfigurator/lambda$2$Type',761);bcb(1127,209,Mle,jUb);_.Ze=function kUb(a,b){var c;c=U1b(new a2b,a);PD(hkd(a,(Nyc(),axc)))===PD((hbd(),ebd))?JTb(this.a,c,b):KTb(this.a,c,b);z2b(new D2b,c)};var yP=mdb(Wme,'LayeredLayoutProvider',1127);bcb(356,22,{3:1,35:1,22:1,356:1},rUb);var lUb,mUb,nUb,oUb,pUb;var zP=ndb(Wme,'LayeredPhases',356,CI,tUb,sUb);var uUb;bcb(1651,1,{},CUb);_.i=0;var wUb;var CP=mdb(Xme,'ComponentsToCGraphTransformer',1651);var hVb;bcb(1652,1,{},DUb);_.ef=function EUb(a,b){return $wnd.Math.min(a.a!=null?Edb(a.a):a.c.i,b.a!=null?Edb(b.a):b.c.i)};_.ff=function FUb(a,b){return $wnd.Math.min(a.a!=null?Edb(a.a):a.c.i,b.a!=null?Edb(b.a):b.c.i)};var AP=mdb(Xme,'ComponentsToCGraphTransformer/1',1652);bcb(81,1,{81:1});_.i=0;_.k=true;_.o=Qje;var IP=mdb(Yme,'CNode',81);bcb(460,81,{460:1,81:1},GUb,HUb);_.Ib=function IUb(){return ''};var BP=mdb(Xme,'ComponentsToCGraphTransformer/CRectNode',460);bcb(1623,1,{},VUb);var JUb,KUb;var FP=mdb(Xme,'OneDimensionalComponentsCompaction',1623);bcb(1624,1,{},YUb);_.Kb=function ZUb(a){return WUb(BD(a,46))};_.Fb=function $Ub(a){return this===a};var DP=mdb(Xme,'OneDimensionalComponentsCompaction/lambda$0$Type',1624);bcb(1625,1,{},_Ub);_.Kb=function aVb(a){return XUb(BD(a,46))};_.Fb=function bVb(a){return this===a};var EP=mdb(Xme,'OneDimensionalComponentsCompaction/lambda$1$Type',1625);bcb(1654,1,{},dVb);var GP=mdb(Yme,'CGraph',1654);bcb(189,1,{189:1},gVb);_.b=0;_.c=0;_.e=0;_.g=true;_.i=Qje;var HP=mdb(Yme,'CGroup',189);bcb(1653,1,{},jVb);_.ef=function kVb(a,b){return $wnd.Math.max(a.a!=null?Edb(a.a):a.c.i,b.a!=null?Edb(b.a):b.c.i)};_.ff=function lVb(a,b){return $wnd.Math.max(a.a!=null?Edb(a.a):a.c.i,b.a!=null?Edb(b.a):b.c.i)};var JP=mdb(Yme,Ike,1653);bcb(1655,1,{},CVb);_.d=false;var mVb;var LP=mdb(Yme,Nke,1655);bcb(1656,1,{},DVb);_.Kb=function EVb(a){return nVb(),Bcb(),BD(BD(a,46).a,81).d.e!=0?true:false};_.Fb=function FVb(a){return this===a};var KP=mdb(Yme,Oke,1656);bcb(823,1,{},IVb);_.a=false;_.b=false;_.c=false;_.d=false;var MP=mdb(Yme,Pke,823);bcb(1825,1,{},OVb);var RP=mdb(Zme,Qke,1825);var bQ=odb($me,Fke);bcb(1826,1,{369:1},SVb);_.Ke=function TVb(a){QVb(this,BD(a,466))};var OP=mdb(Zme,Rke,1826);bcb(1827,1,Dke,VVb);_.ue=function WVb(a,b){return UVb(BD(a,81),BD(b,81))};_.Fb=function XVb(a){return this===a};_.ve=function YVb(){return new tpb(this)};var NP=mdb(Zme,Ske,1827);bcb(466,1,{466:1},ZVb);_.a=false;var PP=mdb(Zme,Tke,466);bcb(1828,1,Dke,$Vb);_.ue=function _Vb(a,b){return PVb(BD(a,466),BD(b,466))};_.Fb=function aWb(a){return this===a};_.ve=function bWb(){return new tpb(this)};var QP=mdb(Zme,Uke,1828);bcb(140,1,{140:1},cWb,dWb);_.Fb=function eWb(a){var b;if(a==null){return false}if(TP!=rb(a)){return false}b=BD(a,140);return wtb(this.c,b.c)&&wtb(this.d,b.d)};_.Hb=function fWb(){return Hlb(OC(GC(SI,1),Uhe,1,5,[this.c,this.d]))};_.Ib=function gWb(){return '('+this.c+She+this.d+(this.a?'cx':'')+this.b+')'};_.a=true;_.c=0;_.d=0;var TP=mdb($me,'Point',140);bcb(405,22,{3:1,35:1,22:1,405:1},oWb);var hWb,iWb,jWb,kWb;var SP=ndb($me,'Point/Quadrant',405,CI,sWb,rWb);var tWb;bcb(1642,1,{},CWb);_.b=null;_.c=null;_.d=null;_.e=null;_.f=null;var vWb,wWb,xWb,yWb,zWb;var aQ=mdb($me,'RectilinearConvexHull',1642);bcb(574,1,{369:1},NWb);_.Ke=function OWb(a){MWb(this,BD(a,140))};_.b=0;var KWb;var VP=mdb($me,'RectilinearConvexHull/MaximalElementsEventHandler',574);bcb(1644,1,Dke,QWb);_.ue=function RWb(a,b){return PWb(ED(a),ED(b))};_.Fb=function SWb(a){return this===a};_.ve=function TWb(){return new tpb(this)};var UP=mdb($me,'RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type',1644);bcb(1643,1,{369:1},VWb);_.Ke=function WWb(a){UWb(this,BD(a,140))};_.a=0;_.b=null;_.c=null;_.d=null;_.e=null;var WP=mdb($me,'RectilinearConvexHull/RectangleEventHandler',1643);bcb(1645,1,Dke,XWb);_.ue=function YWb(a,b){return EWb(BD(a,140),BD(b,140))};_.Fb=function ZWb(a){return this===a};_.ve=function $Wb(){return new tpb(this)};var XP=mdb($me,'RectilinearConvexHull/lambda$0$Type',1645);bcb(1646,1,Dke,_Wb);_.ue=function aXb(a,b){return FWb(BD(a,140),BD(b,140))};_.Fb=function bXb(a){return this===a};_.ve=function cXb(){return new tpb(this)};var YP=mdb($me,'RectilinearConvexHull/lambda$1$Type',1646);bcb(1647,1,Dke,dXb);_.ue=function eXb(a,b){return GWb(BD(a,140),BD(b,140))};_.Fb=function fXb(a){return this===a};_.ve=function gXb(){return new tpb(this)};var ZP=mdb($me,'RectilinearConvexHull/lambda$2$Type',1647);bcb(1648,1,Dke,hXb);_.ue=function iXb(a,b){return HWb(BD(a,140),BD(b,140))};_.Fb=function jXb(a){return this===a};_.ve=function kXb(){return new tpb(this)};var $P=mdb($me,'RectilinearConvexHull/lambda$3$Type',1648);bcb(1649,1,Dke,lXb);_.ue=function mXb(a,b){return IWb(BD(a,140),BD(b,140))};_.Fb=function nXb(a){return this===a};_.ve=function oXb(){return new tpb(this)};var _P=mdb($me,'RectilinearConvexHull/lambda$4$Type',1649);bcb(1650,1,{},qXb);var cQ=mdb($me,'Scanline',1650);bcb(2005,1,{});var dQ=mdb(_me,'AbstractGraphPlacer',2005);bcb(325,1,{325:1},AXb);_.mf=function BXb(a){if(this.nf(a)){Rc(this.b,BD(vNb(a,(wtc(),Esc)),21),a);return true}else{return false}};_.nf=function CXb(a){var b,c,d,e;b=BD(vNb(a,(wtc(),Esc)),21);e=BD(Qc(wXb,b),21);for(d=e.Kc();d.Ob();){c=BD(d.Pb(),21);if(!BD(Qc(this.b,c),15).dc()){return false}}return true};var wXb;var gQ=mdb(_me,'ComponentGroup',325);bcb(765,2005,{},HXb);_.of=function IXb(a){var b,c;for(c=new olb(this.a);c.a<c.c.c.length;){b=BD(mlb(c),325);if(b.mf(a)){return}}Ekb(this.a,new AXb(a))};_.lf=function JXb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o;this.a.c=KC(SI,Uhe,1,0,5,1);b.a.c=KC(SI,Uhe,1,0,5,1);if(a.dc()){b.f.a=0;b.f.b=0;return}g=BD(a.Xb(0),37);tNb(b,g);for(e=a.Kc();e.Ob();){d=BD(e.Pb(),37);this.of(d)}o=new d7c;f=Edb(ED(vNb(g,(Nyc(),kyc))));for(j=new olb(this.a);j.a<j.c.c.length;){h=BD(mlb(j),325);k=DXb(h,f);vXb(Uc(h.b),o.a,o.b);o.a+=k.a;o.b+=k.b}b.f.a=o.a-f;b.f.b=o.b-f;if(Ccb(DD(vNb(g,qwc)))&&PD(vNb(g,Swc))===PD((Aad(),wad))){for(n=a.Kc();n.Ob();){l=BD(n.Pb(),37);uXb(l,l.c.a,l.c.b)}c=new gYb;YXb(c,a,f);for(m=a.Kc();m.Ob();){l=BD(m.Pb(),37);P6c(X6c(l.c),c.e)}P6c(X6c(b.f),c.a)}for(i=new olb(this.a);i.a<i.c.c.length;){h=BD(mlb(i),325);tXb(b,Uc(h.b))}};var eQ=mdb(_me,'ComponentGroupGraphPlacer',765);bcb(1293,765,{},LXb);_.of=function MXb(a){KXb(this,a)};_.lf=function NXb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t;this.a.c=KC(SI,Uhe,1,0,5,1);b.a.c=KC(SI,Uhe,1,0,5,1);if(a.dc()){b.f.a=0;b.f.b=0;return}g=BD(a.Xb(0),37);tNb(b,g);for(e=a.Kc();e.Ob();){d=BD(e.Pb(),37);KXb(this,d)}t=new d7c;s=new d7c;p=new d7c;o=new d7c;f=Edb(ED(vNb(g,(Nyc(),kyc))));for(j=new olb(this.a);j.a<j.c.c.length;){h=BD(mlb(j),325);if(fad(BD(vNb(b,(Y9c(),z8c)),103))){p.a=t.a;for(r=new Mv(Pc(Fc(h.b).a).a.kc());r.b.Ob();){q=BD(Lv(r.b.Pb()),21);if(q.Hc((Ucd(),Acd))){p.a=s.a;break}}}else if(gad(BD(vNb(b,z8c),103))){p.b=t.b;for(r=new Mv(Pc(Fc(h.b).a).a.kc());r.b.Ob();){q=BD(Lv(r.b.Pb()),21);if(q.Hc((Ucd(),Tcd))){p.b=s.b;break}}}k=DXb(BD(h,570),f);vXb(Uc(h.b),p.a,p.b);if(fad(BD(vNb(b,z8c),103))){s.a=p.a+k.a;o.a=$wnd.Math.max(o.a,s.a);for(r=new Mv(Pc(Fc(h.b).a).a.kc());r.b.Ob();){q=BD(Lv(r.b.Pb()),21);if(q.Hc((Ucd(),Rcd))){t.a=p.a+k.a;break}}s.b=p.b+k.b;p.b=s.b;o.b=$wnd.Math.max(o.b,p.b)}else if(gad(BD(vNb(b,z8c),103))){s.b=p.b+k.b;o.b=$wnd.Math.max(o.b,s.b);for(r=new Mv(Pc(Fc(h.b).a).a.kc());r.b.Ob();){q=BD(Lv(r.b.Pb()),21);if(q.Hc((Ucd(),zcd))){t.b=p.b+k.b;break}}s.a=p.a+k.a;p.a=s.a;o.a=$wnd.Math.max(o.a,p.a)}}b.f.a=o.a-f;b.f.b=o.b-f;if(Ccb(DD(vNb(g,qwc)))&&PD(vNb(g,Swc))===PD((Aad(),wad))){for(n=a.Kc();n.Ob();){l=BD(n.Pb(),37);uXb(l,l.c.a,l.c.b)}c=new gYb;YXb(c,a,f);for(m=a.Kc();m.Ob();){l=BD(m.Pb(),37);P6c(X6c(l.c),c.e)}P6c(X6c(b.f),c.a)}for(i=new olb(this.a);i.a<i.c.c.length;){h=BD(mlb(i),325);tXb(b,Uc(h.b))}};var fQ=mdb(_me,'ComponentGroupModelOrderGraphPlacer',1293);bcb(423,22,{3:1,35:1,22:1,423:1},SXb);var OXb,PXb,QXb;var hQ=ndb(_me,'ComponentOrderingStrategy',423,CI,UXb,TXb);var VXb;bcb(650,1,{},gYb);var pQ=mdb(_me,'ComponentsCompactor',650);bcb(1468,12,ake,jYb);_.Fc=function kYb(a){return hYb(this,BD(a,140))};var iQ=mdb(_me,'ComponentsCompactor/Hullpoints',1468);bcb(1465,1,{841:1},mYb);_.a=false;var jQ=mdb(_me,'ComponentsCompactor/InternalComponent',1465);bcb(1464,1,vie,nYb);_.Jc=function oYb(a){reb(this,a)};_.Kc=function pYb(){return new olb(this.a)};var kQ=mdb(_me,'ComponentsCompactor/InternalConnectedComponents',1464);bcb(1467,1,{594:1},qYb);_.hf=function sYb(){return null};_.jf=function tYb(){return this.a};_.gf=function rYb(){return cYb(this.d)};_.kf=function uYb(){return this.b};var lQ=mdb(_me,'ComponentsCompactor/InternalExternalExtension',1467);bcb(1466,1,{594:1},vYb);_.jf=function yYb(){return this.a};_.gf=function wYb(){return cYb(this.d)};_.hf=function xYb(){return this.c};_.kf=function zYb(){return this.b};var mQ=mdb(_me,'ComponentsCompactor/InternalUnionExternalExtension',1466);bcb(1470,1,{},AYb);var nQ=mdb(_me,'ComponentsCompactor/OuterSegments',1470);bcb(1469,1,{},BYb);var oQ=mdb(_me,'ComponentsCompactor/Segments',1469);bcb(1264,1,{},FYb);var rQ=mdb(_me,hme,1264);bcb(1265,1,Dke,HYb);_.ue=function IYb(a,b){return GYb(BD(a,37),BD(b,37))};_.Fb=function JYb(a){return this===a};_.ve=function KYb(){return new tpb(this)};var qQ=mdb(_me,'ComponentsProcessor/lambda$0$Type',1265);bcb(570,325,{325:1,570:1},PYb);_.mf=function QYb(a){return NYb(this,a)};_.nf=function RYb(a){return OYb(this,a)};var LYb;var sQ=mdb(_me,'ModelOrderComponentGroup',570);bcb(1291,2005,{},SYb);_.lf=function TYb(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w;if(a.gc()==1){t=BD(a.Xb(0),37);if(t!=b){b.a.c=KC(SI,Uhe,1,0,5,1);sXb(b,t,0,0);tNb(b,t);u_b(b.d,t.d);b.f.a=t.f.a;b.f.b=t.f.b}return}else if(a.dc()){b.a.c=KC(SI,Uhe,1,0,5,1);b.f.a=0;b.f.b=0;return}if(PD(vNb(b,(Nyc(),twc)))===PD((RXb(),QXb))){for(i=a.Kc();i.Ob();){g=BD(i.Pb(),37);r=0;for(p=new olb(g.a);p.a<p.c.c.length;){o=BD(mlb(p),10);r+=BD(vNb(o,byc),19).a}g.p=r}mmb();a.ad(new VYb)}f=BD(a.Xb(0),37);b.a.c=KC(SI,Uhe,1,0,5,1);tNb(b,f);n=0;u=0;for(j=a.Kc();j.Ob();){g=BD(j.Pb(),37);s=g.f;n=$wnd.Math.max(n,s.a);u+=s.a*s.b}n=$wnd.Math.max(n,$wnd.Math.sqrt(u)*Edb(ED(vNb(b,owc))));e=Edb(ED(vNb(b,kyc)));v=0;w=0;m=0;c=e;for(h=a.Kc();h.Ob();){g=BD(h.Pb(),37);s=g.f;if(v+s.a>n){v=0;w+=m+e;m=0}q=g.c;uXb(g,v+q.a,w+q.b);X6c(q);c=$wnd.Math.max(c,v+s.a);m=$wnd.Math.max(m,s.b);v+=s.a+e}b.f.a=c;b.f.b=w+m;if(Ccb(DD(vNb(f,qwc)))){d=new gYb;YXb(d,a,e);for(l=a.Kc();l.Ob();){k=BD(l.Pb(),37);P6c(X6c(k.c),d.e)}P6c(X6c(b.f),d.a)}tXb(b,a)};var uQ=mdb(_me,'SimpleRowGraphPlacer',1291);bcb(1292,1,Dke,VYb);_.ue=function WYb(a,b){return UYb(BD(a,37),BD(b,37))};_.Fb=function XYb(a){return this===a};_.ve=function YYb(){return new tpb(this)};var tQ=mdb(_me,'SimpleRowGraphPlacer/1',1292);var ZYb;bcb(1262,1,Vke,dZb);_.Lb=function eZb(a){var b;return b=BD(vNb(BD(a,243).b,(Nyc(),jxc)),74),!!b&&b.b!=0};_.Fb=function fZb(a){return this===a};_.Mb=function gZb(a){var b;return b=BD(vNb(BD(a,243).b,(Nyc(),jxc)),74),!!b&&b.b!=0};var vQ=mdb(dne,'CompoundGraphPostprocessor/1',1262);bcb(1261,1,ene,wZb);_.pf=function xZb(a,b){qZb(this,BD(a,37),b)};var xQ=mdb(dne,'CompoundGraphPreprocessor',1261);bcb(441,1,{441:1},yZb);_.c=false;var wQ=mdb(dne,'CompoundGraphPreprocessor/ExternalPort',441);bcb(243,1,{243:1},BZb);_.Ib=function CZb(){return Zr(this.c)+':'+TZb(this.b)};var zQ=mdb(dne,'CrossHierarchyEdge',243);bcb(763,1,Dke,EZb);_.ue=function FZb(a,b){return DZb(this,BD(a,243),BD(b,243))};_.Fb=function GZb(a){return this===a};_.ve=function IZb(){return new tpb(this)};var yQ=mdb(dne,'CrossHierarchyEdgeComparator',763);bcb(299,134,{3:1,299:1,94:1,134:1});_.p=0;var JQ=mdb(fne,'LGraphElement',299);bcb(17,299,{3:1,17:1,299:1,94:1,134:1},UZb);_.Ib=function VZb(){return TZb(this)};var AQ=mdb(fne,'LEdge',17);bcb(37,299,{3:1,20:1,37:1,299:1,94:1,134:1},XZb);_.Jc=function YZb(a){reb(this,a)};_.Kc=function ZZb(){return new olb(this.b)};_.Ib=function $Zb(){if(this.b.c.length==0){return 'G-unlayered'+Fe(this.a)}else if(this.a.c.length==0){return 'G-layered'+Fe(this.b)}return 'G[layerless'+Fe(this.a)+', layers'+Fe(this.b)+']'};var KQ=mdb(fne,'LGraph',37);var _Zb;bcb(657,1,{});_.qf=function b$b(){return this.e.n};_.We=function c$b(a){return vNb(this.e,a)};_.rf=function d$b(){return this.e.o};_.sf=function e$b(){return this.e.p};_.Xe=function f$b(a){return wNb(this.e,a)};_.tf=function g$b(a){this.e.n.a=a.a;this.e.n.b=a.b};_.uf=function h$b(a){this.e.o.a=a.a;this.e.o.b=a.b};_.vf=function i$b(a){this.e.p=a};var BQ=mdb(fne,'LGraphAdapters/AbstractLShapeAdapter',657);bcb(577,1,{839:1},j$b);_.wf=function k$b(){var a,b;if(!this.b){this.b=Pu(this.a.b.c.length);for(b=new olb(this.a.b);b.a<b.c.c.length;){a=BD(mlb(b),70);Ekb(this.b,new v$b(a))}}return this.b};_.b=null;var CQ=mdb(fne,'LGraphAdapters/LEdgeAdapter',577);bcb(656,1,{},l$b);_.xf=function m$b(){var a,b,c,d,e,f;if(!this.b){this.b=new Rkb;for(d=new olb(this.a.b);d.a<d.c.c.length;){c=BD(mlb(d),29);for(f=new olb(c.a);f.a<f.c.c.length;){e=BD(mlb(f),10);if(this.c.Mb(e)){Ekb(this.b,new x$b(this,e,this.e));if(this.d){if(wNb(e,(wtc(),vtc))){for(b=BD(vNb(e,vtc),15).Kc();b.Ob();){a=BD(b.Pb(),10);Ekb(this.b,new x$b(this,a,false))}}if(wNb(e,tsc)){for(b=BD(vNb(e,tsc),15).Kc();b.Ob();){a=BD(b.Pb(),10);Ekb(this.b,new x$b(this,a,false))}}}}}}}return this.b};_.qf=function n$b(){throw vbb(new cgb(hne))};_.We=function o$b(a){return vNb(this.a,a)};_.rf=function p$b(){return this.a.f};_.sf=function q$b(){return this.a.p};_.Xe=function r$b(a){return wNb(this.a,a)};_.tf=function s$b(a){throw vbb(new cgb(hne))};_.uf=function t$b(a){this.a.f.a=a.a;this.a.f.b=a.b};_.vf=function u$b(a){this.a.p=a};_.b=null;_.d=false;_.e=false;var DQ=mdb(fne,'LGraphAdapters/LGraphAdapter',656);bcb(576,657,{181:1},v$b);var EQ=mdb(fne,'LGraphAdapters/LLabelAdapter',576);bcb(575,657,{680:1},x$b);_.yf=function y$b(){return this.b};_.zf=function z$b(){return mmb(),mmb(),jmb};_.wf=function A$b(){var a,b;if(!this.a){this.a=Pu(BD(this.e,10).b.c.length);for(b=new olb(BD(this.e,10).b);b.a<b.c.c.length;){a=BD(mlb(b),70);Ekb(this.a,new v$b(a))}}return this.a};_.Af=function B$b(){var a;a=BD(this.e,10).d;return new J_b(a.d,a.c,a.a,a.b)};_.Bf=function C$b(){return mmb(),mmb(),jmb};_.Cf=function D$b(){var a,b;if(!this.c){this.c=Pu(BD(this.e,10).j.c.length);for(b=new olb(BD(this.e,10).j);b.a<b.c.c.length;){a=BD(mlb(b),11);Ekb(this.c,new I$b(a,this.d))}}return this.c};_.Df=function E$b(){return Ccb(DD(vNb(BD(this.e,10),(wtc(),wsc))))};_.Ef=function F$b(a){BD(this.e,10).d.b=a.b;BD(this.e,10).d.d=a.d;BD(this.e,10).d.c=a.c;BD(this.e,10).d.a=a.a};_.Ff=function G$b(a){BD(this.e,10).f.b=a.b;BD(this.e,10).f.d=a.d;BD(this.e,10).f.c=a.c;BD(this.e,10).f.a=a.a};_.Gf=function H$b(){w$b(this,(a$b(),_Zb))};_.a=null;_.b=null;_.c=null;_.d=false;var FQ=mdb(fne,'LGraphAdapters/LNodeAdapter',575);bcb(1722,657,{838:1},I$b);_.zf=function J$b(){var a,b,c,d;if(this.d&&BD(this.e,11).i.k==(j0b(),i0b)){return mmb(),mmb(),jmb}else if(!this.a){this.a=new Rkb;for(c=new olb(BD(this.e,11).e);c.a<c.c.c.length;){a=BD(mlb(c),17);Ekb(this.a,new j$b(a))}if(this.d){d=BD(vNb(BD(this.e,11),(wtc(),gtc)),10);if(d){for(b=new Sr(ur(R_b(d).a.Kc(),new Sq));Qr(b);){a=BD(Rr(b),17);Ekb(this.a,new j$b(a))}}}}return this.a};_.wf=function K$b(){var a,b;if(!this.b){this.b=Pu(BD(this.e,11).f.c.length);for(b=new olb(BD(this.e,11).f);b.a<b.c.c.length;){a=BD(mlb(b),70);Ekb(this.b,new v$b(a))}}return this.b};_.Bf=function L$b(){var a,b,c,d;if(this.d&&BD(this.e,11).i.k==(j0b(),i0b)){return mmb(),mmb(),jmb}else if(!this.c){this.c=new Rkb;for(c=new olb(BD(this.e,11).g);c.a<c.c.c.length;){a=BD(mlb(c),17);Ekb(this.c,new j$b(a))}if(this.d){d=BD(vNb(BD(this.e,11),(wtc(),gtc)),10);if(d){for(b=new Sr(ur(U_b(d).a.Kc(),new Sq));Qr(b);){a=BD(Rr(b),17);Ekb(this.c,new j$b(a))}}}}return this.c};_.Hf=function M$b(){return BD(this.e,11).j};_.If=function N$b(){return Ccb(DD(vNb(BD(this.e,11),(wtc(),Nsc))))};_.a=null;_.b=null;_.c=null;_.d=false;var GQ=mdb(fne,'LGraphAdapters/LPortAdapter',1722);bcb(1723,1,Dke,P$b);_.ue=function Q$b(a,b){return O$b(BD(a,11),BD(b,11))};_.Fb=function R$b(a){return this===a};_.ve=function S$b(){return new tpb(this)};var HQ=mdb(fne,'LGraphAdapters/PortComparator',1723);bcb(804,1,Oie,T$b);_.Mb=function U$b(a){return BD(a,10),a$b(),true};var IQ=mdb(fne,'LGraphAdapters/lambda$0$Type',804);bcb(392,299,{3:1,299:1,392:1,94:1,134:1});var bR=mdb(fne,'LShape',392);bcb(70,392,{3:1,299:1,70:1,392:1,94:1,134:1},p_b,q_b);_.Ib=function r_b(){var a;a=o_b(this);return a==null?'label':'l_'+a};var LQ=mdb(fne,'LLabel',70);bcb(207,1,{3:1,4:1,207:1,414:1});_.Fb=function C_b(a){var b;if(JD(a,207)){b=BD(a,207);return this.d==b.d&&this.a==b.a&&this.b==b.b&&this.c==b.c}else{return false}};_.Hb=function D_b(){var a,b;a=Hdb(this.b)<<16;a|=Hdb(this.a)&aje;b=Hdb(this.c)<<16;b|=Hdb(this.d)&aje;return a^b};_.Jf=function F_b(b){var c,d,e,f,g,h,i,j,k,l,m;g=0;while(g<b.length&&E_b((BCb(g,b.length),b.charCodeAt(g)),mne)){++g}c=b.length;while(c>0&&E_b((BCb(c-1,b.length),b.charCodeAt(c-1)),nne)){--c}if(g<c){l=mfb(b.substr(g,c-g),',|;');try{for(i=l,j=0,k=i.length;j<k;++j){h=i[j];f=mfb(h,'=');if(f.length!=2){throw vbb(new Wdb('Expecting a list of key-value pairs.'))}e=ufb(f[0]);m=Hcb(ufb(f[1]));dfb(e,'top')?(this.d=m):dfb(e,'left')?(this.b=m):dfb(e,'bottom')?(this.a=m):dfb(e,'right')&&(this.c=m)}}catch(a){a=ubb(a);if(JD(a,127)){d=a;throw vbb(new Wdb(one+d))}else throw vbb(a)}}};_.Ib=function G_b(){return '[top='+this.d+',left='+this.b+',bottom='+this.a+',right='+this.c+']'};_.a=0;_.b=0;_.c=0;_.d=0;var n1=mdb(pne,'Spacing',207);bcb(142,207,qne,H_b,I_b,J_b,K_b);var i1=mdb(pne,'ElkMargin',142);bcb(651,142,qne,L_b);var MQ=mdb(fne,'LMargin',651);bcb(10,392,{3:1,299:1,10:1,392:1,94:1,134:1},b0b);_.Ib=function c0b(){return a0b(this)};_.i=false;var OQ=mdb(fne,'LNode',10);bcb(267,22,{3:1,35:1,22:1,267:1},k0b);var d0b,e0b,f0b,g0b,h0b,i0b;var NQ=ndb(fne,'LNode/NodeType',267,CI,m0b,l0b);var n0b;bcb(116,207,rne,p0b,q0b,r0b);var j1=mdb(pne,'ElkPadding',116);bcb(764,116,rne,s0b);var PQ=mdb(fne,'LPadding',764);bcb(11,392,{3:1,299:1,11:1,392:1,94:1,134:1},H0b);_.Ib=function I0b(){var a,b,c;a=new Ufb;Qfb((a.a+='p_',a),C0b(this));!!this.i&&Qfb(Pfb((a.a+='[',a),this.i),']');if(this.e.c.length==1&&this.g.c.length==0&&BD(Ikb(this.e,0),17).c!=this){b=BD(Ikb(this.e,0),17).c;Qfb((a.a+=' << ',a),C0b(b));Qfb(Pfb((a.a+='[',a),b.i),']')}if(this.e.c.length==0&&this.g.c.length==1&&BD(Ikb(this.g,0),17).d!=this){c=BD(Ikb(this.g,0),17).d;Qfb((a.a+=' >> ',a),C0b(c));Qfb(Pfb((a.a+='[',a),c.i),']')}return a.a};_.c=true;_.d=false;var t0b,u0b,v0b,w0b,x0b,y0b;var aR=mdb(fne,'LPort',11);bcb(397,1,vie,J0b);_.Jc=function K0b(a){reb(this,a)};_.Kc=function L0b(){var a;a=new olb(this.a.e);return new M0b(a)};var RQ=mdb(fne,'LPort/1',397);bcb(1290,1,aie,M0b);_.Nb=function N0b(a){Rrb(this,a)};_.Pb=function P0b(){return BD(mlb(this.a),17).c};_.Ob=function O0b(){return llb(this.a)};_.Qb=function Q0b(){nlb(this.a)};var QQ=mdb(fne,'LPort/1/1',1290);bcb(359,1,vie,R0b);_.Jc=function S0b(a){reb(this,a)};_.Kc=function T0b(){var a;return a=new olb(this.a.g),new U0b(a)};var TQ=mdb(fne,'LPort/2',359);bcb(762,1,aie,U0b);_.Nb=function V0b(a){Rrb(this,a)};_.Pb=function X0b(){return BD(mlb(this.a),17).d};_.Ob=function W0b(){return llb(this.a)};_.Qb=function Y0b(){nlb(this.a)};var SQ=mdb(fne,'LPort/2/1',762);bcb(1283,1,vie,Z0b);_.Jc=function $0b(a){reb(this,a)};_.Kc=function _0b(){return new b1b(this)};var VQ=mdb(fne,'LPort/CombineIter',1283);bcb(201,1,aie,b1b);_.Nb=function c1b(a){Rrb(this,a)};_.Qb=function f1b(){Srb()};_.Ob=function d1b(){return a1b(this)};_.Pb=function e1b(){return llb(this.a)?mlb(this.a):mlb(this.b)};var UQ=mdb(fne,'LPort/CombineIter/1',201);bcb(1285,1,Vke,h1b);_.Lb=function i1b(a){return g1b(a)};_.Fb=function j1b(a){return this===a};_.Mb=function k1b(a){return z0b(),BD(a,11).e.c.length!=0};var WQ=mdb(fne,'LPort/lambda$0$Type',1285);bcb(1284,1,Vke,m1b);_.Lb=function n1b(a){return l1b(a)};_.Fb=function o1b(a){return this===a};_.Mb=function p1b(a){return z0b(),BD(a,11).g.c.length!=0};var XQ=mdb(fne,'LPort/lambda$1$Type',1284);bcb(1286,1,Vke,q1b);_.Lb=function r1b(a){return z0b(),BD(a,11).j==(Ucd(),Acd)};_.Fb=function s1b(a){return this===a};_.Mb=function t1b(a){return z0b(),BD(a,11).j==(Ucd(),Acd)};var YQ=mdb(fne,'LPort/lambda$2$Type',1286);bcb(1287,1,Vke,u1b);_.Lb=function v1b(a){return z0b(),BD(a,11).j==(Ucd(),zcd)};_.Fb=function w1b(a){return this===a};_.Mb=function x1b(a){return z0b(),BD(a,11).j==(Ucd(),zcd)};var ZQ=mdb(fne,'LPort/lambda$3$Type',1287);bcb(1288,1,Vke,y1b);_.Lb=function z1b(a){return z0b(),BD(a,11).j==(Ucd(),Rcd)};_.Fb=function A1b(a){return this===a};_.Mb=function B1b(a){return z0b(),BD(a,11).j==(Ucd(),Rcd)};var $Q=mdb(fne,'LPort/lambda$4$Type',1288);bcb(1289,1,Vke,C1b);_.Lb=function D1b(a){return z0b(),BD(a,11).j==(Ucd(),Tcd)};_.Fb=function E1b(a){return this===a};_.Mb=function F1b(a){return z0b(),BD(a,11).j==(Ucd(),Tcd)};var _Q=mdb(fne,'LPort/lambda$5$Type',1289);bcb(29,299,{3:1,20:1,299:1,29:1,94:1,134:1},H1b);_.Jc=function I1b(a){reb(this,a)};_.Kc=function J1b(){return new olb(this.a)};_.Ib=function K1b(){return 'L_'+Jkb(this.b.b,this,0)+Fe(this.a)};var cR=mdb(fne,'Layer',29);bcb(1342,1,{},a2b);var mR=mdb(tne,une,1342);bcb(1346,1,{},e2b);_.Kb=function f2b(a){return atd(BD(a,82))};var dR=mdb(tne,'ElkGraphImporter/0methodref$connectableShapeToNode$Type',1346);bcb(1349,1,{},g2b);_.Kb=function h2b(a){return atd(BD(a,82))};var eR=mdb(tne,'ElkGraphImporter/1methodref$connectableShapeToNode$Type',1349);bcb(1343,1,qie,i2b);_.td=function j2b(a){Q1b(this.a,BD(a,118))};var fR=mdb(tne,vne,1343);bcb(1344,1,qie,k2b);_.td=function l2b(a){Q1b(this.a,BD(a,118))};var gR=mdb(tne,wne,1344);bcb(1345,1,{},m2b);_.Kb=function n2b(a){return new YAb(null,new Kub(Old(BD(a,79)),16))};var hR=mdb(tne,xne,1345);bcb(1347,1,Oie,o2b);_.Mb=function p2b(a){return b2b(this.a,BD(a,33))};var iR=mdb(tne,yne,1347);bcb(1348,1,{},q2b);_.Kb=function r2b(a){return new YAb(null,new Kub(Nld(BD(a,79)),16))};var jR=mdb(tne,'ElkGraphImporter/lambda$5$Type',1348);bcb(1350,1,Oie,s2b);_.Mb=function t2b(a){return c2b(this.a,BD(a,33))};var kR=mdb(tne,'ElkGraphImporter/lambda$7$Type',1350);bcb(1351,1,Oie,u2b);_.Mb=function v2b(a){return d2b(BD(a,79))};var lR=mdb(tne,'ElkGraphImporter/lambda$8$Type',1351);bcb(1278,1,{},D2b);var w2b;var rR=mdb(tne,'ElkGraphLayoutTransferrer',1278);bcb(1279,1,Oie,G2b);_.Mb=function H2b(a){return E2b(this.a,BD(a,17))};var nR=mdb(tne,'ElkGraphLayoutTransferrer/lambda$0$Type',1279);bcb(1280,1,qie,I2b);_.td=function J2b(a){x2b();Ekb(this.a,BD(a,17))};var oR=mdb(tne,'ElkGraphLayoutTransferrer/lambda$1$Type',1280);bcb(1281,1,Oie,K2b);_.Mb=function L2b(a){return F2b(this.a,BD(a,17))};var pR=mdb(tne,'ElkGraphLayoutTransferrer/lambda$2$Type',1281);bcb(1282,1,qie,M2b);_.td=function N2b(a){x2b();Ekb(this.a,BD(a,17))};var qR=mdb(tne,'ElkGraphLayoutTransferrer/lambda$3$Type',1282);bcb(1485,1,ene,S2b);_.pf=function T2b(a,b){Q2b(BD(a,37),b)};var uR=mdb(Ane,'CommentNodeMarginCalculator',1485);bcb(1486,1,{},U2b);_.Kb=function V2b(a){return new YAb(null,new Kub(BD(a,29).a,16))};var sR=mdb(Ane,'CommentNodeMarginCalculator/lambda$0$Type',1486);bcb(1487,1,qie,W2b);_.td=function X2b(a){R2b(BD(a,10))};var tR=mdb(Ane,'CommentNodeMarginCalculator/lambda$1$Type',1487);bcb(1488,1,ene,_2b);_.pf=function a3b(a,b){Z2b(BD(a,37),b)};var vR=mdb(Ane,'CommentPostprocessor',1488);bcb(1489,1,ene,e3b);_.pf=function f3b(a,b){b3b(BD(a,37),b)};var wR=mdb(Ane,'CommentPreprocessor',1489);bcb(1490,1,ene,h3b);_.pf=function i3b(a,b){g3b(BD(a,37),b)};var xR=mdb(Ane,'ConstraintsPostprocessor',1490);bcb(1491,1,ene,p3b);_.pf=function q3b(a,b){n3b(BD(a,37),b)};var yR=mdb(Ane,'EdgeAndLayerConstraintEdgeReverser',1491);bcb(1492,1,ene,t3b);_.pf=function v3b(a,b){r3b(BD(a,37),b)};var CR=mdb(Ane,'EndLabelPostprocessor',1492);bcb(1493,1,{},w3b);_.Kb=function x3b(a){return new YAb(null,new Kub(BD(a,29).a,16))};var zR=mdb(Ane,'EndLabelPostprocessor/lambda$0$Type',1493);bcb(1494,1,Oie,y3b);_.Mb=function z3b(a){return u3b(BD(a,10))};var AR=mdb(Ane,'EndLabelPostprocessor/lambda$1$Type',1494);bcb(1495,1,qie,A3b);_.td=function B3b(a){s3b(BD(a,10))};var BR=mdb(Ane,'EndLabelPostprocessor/lambda$2$Type',1495);bcb(1496,1,ene,M3b);_.pf=function P3b(a,b){I3b(BD(a,37),b)};var JR=mdb(Ane,'EndLabelPreprocessor',1496);bcb(1497,1,{},Q3b);_.Kb=function R3b(a){return new YAb(null,new Kub(BD(a,29).a,16))};var DR=mdb(Ane,'EndLabelPreprocessor/lambda$0$Type',1497);bcb(1498,1,qie,S3b);_.td=function T3b(a){E3b(this.a,this.b,this.c,BD(a,10))};_.a=0;_.b=0;_.c=false;var ER=mdb(Ane,'EndLabelPreprocessor/lambda$1$Type',1498);bcb(1499,1,Oie,U3b);_.Mb=function V3b(a){return PD(vNb(BD(a,70),(Nyc(),Qwc)))===PD((qad(),pad))};var FR=mdb(Ane,'EndLabelPreprocessor/lambda$2$Type',1499);bcb(1500,1,qie,W3b);_.td=function X3b(a){Dsb(this.a,BD(a,70))};var GR=mdb(Ane,'EndLabelPreprocessor/lambda$3$Type',1500);bcb(1501,1,Oie,Y3b);_.Mb=function Z3b(a){return PD(vNb(BD(a,70),(Nyc(),Qwc)))===PD((qad(),oad))};var HR=mdb(Ane,'EndLabelPreprocessor/lambda$4$Type',1501);bcb(1502,1,qie,$3b);_.td=function _3b(a){Dsb(this.a,BD(a,70))};var IR=mdb(Ane,'EndLabelPreprocessor/lambda$5$Type',1502);bcb(1551,1,ene,i4b);_.pf=function j4b(a,b){f4b(BD(a,37),b)};var a4b;var RR=mdb(Ane,'EndLabelSorter',1551);bcb(1552,1,Dke,l4b);_.ue=function m4b(a,b){return k4b(BD(a,456),BD(b,456))};_.Fb=function n4b(a){return this===a};_.ve=function o4b(){return new tpb(this)};var KR=mdb(Ane,'EndLabelSorter/1',1552);bcb(456,1,{456:1},p4b);var LR=mdb(Ane,'EndLabelSorter/LabelGroup',456);bcb(1553,1,{},q4b);_.Kb=function r4b(a){return b4b(),new YAb(null,new Kub(BD(a,29).a,16))};var MR=mdb(Ane,'EndLabelSorter/lambda$0$Type',1553);bcb(1554,1,Oie,s4b);_.Mb=function t4b(a){return b4b(),BD(a,10).k==(j0b(),h0b)};var NR=mdb(Ane,'EndLabelSorter/lambda$1$Type',1554);bcb(1555,1,qie,u4b);_.td=function v4b(a){g4b(BD(a,10))};var OR=mdb(Ane,'EndLabelSorter/lambda$2$Type',1555);bcb(1556,1,Oie,w4b);_.Mb=function x4b(a){return b4b(),PD(vNb(BD(a,70),(Nyc(),Qwc)))===PD((qad(),oad))};var PR=mdb(Ane,'EndLabelSorter/lambda$3$Type',1556);bcb(1557,1,Oie,y4b);_.Mb=function z4b(a){return b4b(),PD(vNb(BD(a,70),(Nyc(),Qwc)))===PD((qad(),pad))};var QR=mdb(Ane,'EndLabelSorter/lambda$4$Type',1557);bcb(1503,1,ene,L4b);_.pf=function M4b(a,b){J4b(this,BD(a,37))};_.b=0;_.c=0;var YR=mdb(Ane,'FinalSplineBendpointsCalculator',1503);bcb(1504,1,{},N4b);_.Kb=function O4b(a){return new YAb(null,new Kub(BD(a,29).a,16))};var SR=mdb(Ane,'FinalSplineBendpointsCalculator/lambda$0$Type',1504);bcb(1505,1,{},P4b);_.Kb=function Q4b(a){return new YAb(null,new Lub(new Sr(ur(U_b(BD(a,10)).a.Kc(),new Sq))))};var TR=mdb(Ane,'FinalSplineBendpointsCalculator/lambda$1$Type',1505);bcb(1506,1,Oie,R4b);_.Mb=function S4b(a){return !OZb(BD(a,17))};var UR=mdb(Ane,'FinalSplineBendpointsCalculator/lambda$2$Type',1506);bcb(1507,1,Oie,T4b);_.Mb=function U4b(a){return wNb(BD(a,17),(wtc(),rtc))};var VR=mdb(Ane,'FinalSplineBendpointsCalculator/lambda$3$Type',1507);bcb(1508,1,qie,V4b);_.td=function W4b(a){C4b(this.a,BD(a,128))};var WR=mdb(Ane,'FinalSplineBendpointsCalculator/lambda$4$Type',1508);bcb(1509,1,qie,X4b);_.td=function Y4b(a){smb(BD(a,17).a)};var XR=mdb(Ane,'FinalSplineBendpointsCalculator/lambda$5$Type',1509);bcb(792,1,ene,u5b);_.pf=function v5b(a,b){l5b(this,BD(a,37),b)};var $R=mdb(Ane,'GraphTransformer',792);bcb(511,22,{3:1,35:1,22:1,511:1},z5b);var w5b,x5b;var ZR=ndb(Ane,'GraphTransformer/Mode',511,CI,B5b,A5b);var C5b;bcb(1510,1,ene,I5b);_.pf=function J5b(a,b){F5b(BD(a,37),b)};var _R=mdb(Ane,'HierarchicalNodeResizingProcessor',1510);bcb(1511,1,ene,Q5b);_.pf=function R5b(a,b){M5b(BD(a,37),b)};var bS=mdb(Ane,'HierarchicalPortConstraintProcessor',1511);bcb(1512,1,Dke,T5b);_.ue=function U5b(a,b){return S5b(BD(a,10),BD(b,10))};_.Fb=function V5b(a){return this===a};_.ve=function W5b(){return new tpb(this)};var aS=mdb(Ane,'HierarchicalPortConstraintProcessor/NodeComparator',1512);bcb(1513,1,ene,Z5b);_.pf=function $5b(a,b){X5b(BD(a,37),b)};var cS=mdb(Ane,'HierarchicalPortDummySizeProcessor',1513);bcb(1514,1,ene,l6b);_.pf=function m6b(a,b){e6b(this,BD(a,37),b)};_.a=0;var fS=mdb(Ane,'HierarchicalPortOrthogonalEdgeRouter',1514);bcb(1515,1,Dke,o6b);_.ue=function p6b(a,b){return n6b(BD(a,10),BD(b,10))};_.Fb=function q6b(a){return this===a};_.ve=function r6b(){return new tpb(this)};var dS=mdb(Ane,'HierarchicalPortOrthogonalEdgeRouter/1',1515);bcb(1516,1,Dke,t6b);_.ue=function u6b(a,b){return s6b(BD(a,10),BD(b,10))};_.Fb=function v6b(a){return this===a};_.ve=function w6b(){return new tpb(this)};var eS=mdb(Ane,'HierarchicalPortOrthogonalEdgeRouter/2',1516);bcb(1517,1,ene,z6b);_.pf=function A6b(a,b){y6b(BD(a,37),b)};var gS=mdb(Ane,'HierarchicalPortPositionProcessor',1517);bcb(1518,1,ene,J6b);_.pf=function K6b(a,b){I6b(this,BD(a,37))};_.a=0;_.c=0;var B6b,C6b;var kS=mdb(Ane,'HighDegreeNodeLayeringProcessor',1518);bcb(571,1,{571:1},L6b);_.b=-1;_.d=-1;var hS=mdb(Ane,'HighDegreeNodeLayeringProcessor/HighDegreeNodeInformation',571);bcb(1519,1,{},M6b);_.Kb=function N6b(a){return D6b(),R_b(BD(a,10))};_.Fb=function O6b(a){return this===a};var iS=mdb(Ane,'HighDegreeNodeLayeringProcessor/lambda$0$Type',1519);bcb(1520,1,{},P6b);_.Kb=function Q6b(a){return D6b(),U_b(BD(a,10))};_.Fb=function R6b(a){return this===a};var jS=mdb(Ane,'HighDegreeNodeLayeringProcessor/lambda$1$Type',1520);bcb(1526,1,ene,X6b);_.pf=function Y6b(a,b){W6b(this,BD(a,37),b)};var pS=mdb(Ane,'HyperedgeDummyMerger',1526);bcb(793,1,{},Z6b);_.a=false;_.b=false;_.c=false;var lS=mdb(Ane,'HyperedgeDummyMerger/MergeState',793);bcb(1527,1,{},$6b);_.Kb=function _6b(a){return new YAb(null,new Kub(BD(a,29).a,16))};var mS=mdb(Ane,'HyperedgeDummyMerger/lambda$0$Type',1527);bcb(1528,1,{},a7b);_.Kb=function b7b(a){return new YAb(null,new Kub(BD(a,10).j,16))};var nS=mdb(Ane,'HyperedgeDummyMerger/lambda$1$Type',1528);bcb(1529,1,qie,c7b);_.td=function d7b(a){BD(a,11).p=-1};var oS=mdb(Ane,'HyperedgeDummyMerger/lambda$2$Type',1529);bcb(1530,1,ene,g7b);_.pf=function h7b(a,b){f7b(BD(a,37),b)};var qS=mdb(Ane,'HypernodesProcessor',1530);bcb(1531,1,ene,j7b);_.pf=function k7b(a,b){i7b(BD(a,37),b)};var rS=mdb(Ane,'InLayerConstraintProcessor',1531);bcb(1532,1,ene,m7b);_.pf=function n7b(a,b){l7b(BD(a,37),b)};var sS=mdb(Ane,'InnermostNodeMarginCalculator',1532);bcb(1533,1,ene,r7b);_.pf=function w7b(a,b){q7b(this,BD(a,37))};_.a=Qje;_.b=Qje;_.c=Pje;_.d=Pje;var zS=mdb(Ane,'InteractiveExternalPortPositioner',1533);bcb(1534,1,{},x7b);_.Kb=function y7b(a){return BD(a,17).d.i};_.Fb=function z7b(a){return this===a};var tS=mdb(Ane,'InteractiveExternalPortPositioner/lambda$0$Type',1534);bcb(1535,1,{},A7b);_.Kb=function B7b(a){return s7b(this.a,ED(a))};_.Fb=function C7b(a){return this===a};var uS=mdb(Ane,'InteractiveExternalPortPositioner/lambda$1$Type',1535);bcb(1536,1,{},D7b);_.Kb=function E7b(a){return BD(a,17).c.i};_.Fb=function F7b(a){return this===a};var vS=mdb(Ane,'InteractiveExternalPortPositioner/lambda$2$Type',1536);bcb(1537,1,{},G7b);_.Kb=function H7b(a){return t7b(this.a,ED(a))};_.Fb=function I7b(a){return this===a};var wS=mdb(Ane,'InteractiveExternalPortPositioner/lambda$3$Type',1537);bcb(1538,1,{},J7b);_.Kb=function K7b(a){return u7b(this.a,ED(a))};_.Fb=function L7b(a){return this===a};var xS=mdb(Ane,'InteractiveExternalPortPositioner/lambda$4$Type',1538);bcb(1539,1,{},M7b);_.Kb=function N7b(a){return v7b(this.a,ED(a))};_.Fb=function O7b(a){return this===a};var yS=mdb(Ane,'InteractiveExternalPortPositioner/lambda$5$Type',1539);bcb(77,22,{3:1,35:1,22:1,77:1,234:1},T8b);_.Kf=function U8b(){switch(this.g){case 15:return new eoc;case 22:return new Aoc;case 47:return new Joc;case 28:case 35:return new uac;case 32:return new S2b;case 42:return new _2b;case 1:return new e3b;case 41:return new h3b;case 56:return new u5b((y5b(),x5b));case 0:return new u5b((y5b(),w5b));case 2:return new p3b;case 54:return new t3b;case 33:return new M3b;case 51:return new L4b;case 55:return new I5b;case 13:return new Q5b;case 38:return new Z5b;case 44:return new l6b;case 40:return new z6b;case 9:return new J6b;case 49:return new sgc;case 37:return new X6b;case 43:return new g7b;case 27:return new j7b;case 30:return new m7b;case 3:return new r7b;case 18:return new b9b;case 29:return new h9b;case 5:return new u9b;case 50:return new D9b;case 34:return new $9b;case 36:return new Iac;case 52:return new i4b;case 11:return new Sac;case 7:return new abc;case 39:return new obc;case 45:return new rbc;case 16:return new vbc;case 10:return new Fbc;case 48:return new Xbc;case 21:return new ccc;case 23:return new fGc((rGc(),pGc));case 8:return new lcc;case 12:return new tcc;case 4:return new ycc;case 19:return new Tcc;case 17:return new pdc;case 53:return new sdc;case 6:return new hec;case 25:return new wdc;case 46:return new Ndc;case 31:return new sec;case 14:return new Fec;case 26:return new ppc;case 20:return new Uec;case 24:return new fGc((rGc(),qGc));default:throw vbb(new Wdb(Dne+(this.f!=null?this.f:''+this.g)));}};var P7b,Q7b,R7b,S7b,T7b,U7b,V7b,W7b,X7b,Y7b,Z7b,$7b,_7b,a8b,b8b,c8b,d8b,e8b,f8b,g8b,h8b,i8b,j8b,k8b,l8b,m8b,n8b,o8b,p8b,q8b,r8b,s8b,t8b,u8b,v8b,w8b,x8b,y8b,z8b,A8b,B8b,C8b,D8b,E8b,F8b,G8b,H8b,I8b,J8b,K8b,L8b,M8b,N8b,O8b,P8b,Q8b,R8b;var AS=ndb(Ane,Ene,77,CI,W8b,V8b);var X8b;bcb(1540,1,ene,b9b);_.pf=function c9b(a,b){_8b(BD(a,37),b)};var BS=mdb(Ane,'InvertedPortProcessor',1540);bcb(1541,1,ene,h9b);_.pf=function i9b(a,b){g9b(BD(a,37),b)};var FS=mdb(Ane,'LabelAndNodeSizeProcessor',1541);bcb(1542,1,Oie,j9b);_.Mb=function k9b(a){return BD(a,10).k==(j0b(),h0b)};var CS=mdb(Ane,'LabelAndNodeSizeProcessor/lambda$0$Type',1542);bcb(1543,1,Oie,l9b);_.Mb=function m9b(a){return BD(a,10).k==(j0b(),e0b)};var DS=mdb(Ane,'LabelAndNodeSizeProcessor/lambda$1$Type',1543);bcb(1544,1,qie,n9b);_.td=function o9b(a){e9b(this.b,this.a,this.c,BD(a,10))};_.a=false;_.c=false;var ES=mdb(Ane,'LabelAndNodeSizeProcessor/lambda$2$Type',1544);bcb(1545,1,ene,u9b);_.pf=function v9b(a,b){s9b(BD(a,37),b)};var p9b;var HS=mdb(Ane,'LabelDummyInserter',1545);bcb(1546,1,Vke,w9b);_.Lb=function x9b(a){return PD(vNb(BD(a,70),(Nyc(),Qwc)))===PD((qad(),nad))};_.Fb=function y9b(a){return this===a};_.Mb=function z9b(a){return PD(vNb(BD(a,70),(Nyc(),Qwc)))===PD((qad(),nad))};var GS=mdb(Ane,'LabelDummyInserter/1',1546);bcb(1547,1,ene,D9b);_.pf=function E9b(a,b){C9b(BD(a,37),b)};var JS=mdb(Ane,'LabelDummyRemover',1547);bcb(1548,1,Oie,F9b);_.Mb=function G9b(a){return Ccb(DD(vNb(BD(a,70),(Nyc(),Pwc))))};var IS=mdb(Ane,'LabelDummyRemover/lambda$0$Type',1548);bcb(1359,1,ene,$9b);_.pf=function cac(a,b){W9b(this,BD(a,37),b)};_.a=null;var H9b;var QS=mdb(Ane,'LabelDummySwitcher',1359);bcb(286,1,{286:1},gac);_.c=0;_.d=null;_.f=0;var KS=mdb(Ane,'LabelDummySwitcher/LabelDummyInfo',286);bcb(1360,1,{},hac);_.Kb=function iac(a){return I9b(),new YAb(null,new Kub(BD(a,29).a,16))};var LS=mdb(Ane,'LabelDummySwitcher/lambda$0$Type',1360);bcb(1361,1,Oie,jac);_.Mb=function kac(a){return I9b(),BD(a,10).k==(j0b(),f0b)};var MS=mdb(Ane,'LabelDummySwitcher/lambda$1$Type',1361);bcb(1362,1,{},lac);_.Kb=function mac(a){return _9b(this.a,BD(a,10))};var NS=mdb(Ane,'LabelDummySwitcher/lambda$2$Type',1362);bcb(1363,1,qie,nac);_.td=function oac(a){aac(this.a,BD(a,286))};var OS=mdb(Ane,'LabelDummySwitcher/lambda$3$Type',1363);bcb(1364,1,Dke,pac);_.ue=function qac(a,b){return bac(BD(a,286),BD(b,286))};_.Fb=function rac(a){return this===a};_.ve=function sac(){return new tpb(this)};var PS=mdb(Ane,'LabelDummySwitcher/lambda$4$Type',1364);bcb(791,1,ene,uac);_.pf=function vac(a,b){tac(BD(a,37),b)};var RS=mdb(Ane,'LabelManagementProcessor',791);bcb(1549,1,ene,Iac);_.pf=function Jac(a,b){Cac(BD(a,37),b)};var TS=mdb(Ane,'LabelSideSelector',1549);bcb(1550,1,Oie,Kac);_.Mb=function Lac(a){return Ccb(DD(vNb(BD(a,70),(Nyc(),Pwc))))};var SS=mdb(Ane,'LabelSideSelector/lambda$0$Type',1550);bcb(1558,1,ene,Sac);_.pf=function Tac(a,b){Oac(BD(a,37),b)};var US=mdb(Ane,'LayerConstraintPostprocessor',1558);bcb(1559,1,ene,abc);_.pf=function bbc(a,b){$ac(BD(a,37),b)};var Uac;var WS=mdb(Ane,'LayerConstraintPreprocessor',1559);bcb(360,22,{3:1,35:1,22:1,360:1},ibc);var cbc,dbc,ebc,fbc;var VS=ndb(Ane,'LayerConstraintPreprocessor/HiddenNodeConnections',360,CI,kbc,jbc);var lbc;bcb(1560,1,ene,obc);_.pf=function pbc(a,b){nbc(BD(a,37),b)};var XS=mdb(Ane,'LayerSizeAndGraphHeightCalculator',1560);bcb(1561,1,ene,rbc);_.pf=function tbc(a,b){qbc(BD(a,37),b)};var YS=mdb(Ane,'LongEdgeJoiner',1561);bcb(1562,1,ene,vbc);_.pf=function xbc(a,b){ubc(BD(a,37),b)};var ZS=mdb(Ane,'LongEdgeSplitter',1562);bcb(1563,1,ene,Fbc);_.pf=function Ibc(a,b){Bbc(this,BD(a,37),b)};_.d=0;_.e=0;_.i=0;_.j=0;_.k=0;_.n=0;var bT=mdb(Ane,'NodePromotion',1563);bcb(1564,1,{},Jbc);_.Kb=function Kbc(a){return BD(a,46),Bcb(),true};_.Fb=function Lbc(a){return this===a};var $S=mdb(Ane,'NodePromotion/lambda$0$Type',1564);bcb(1565,1,{},Mbc);_.Kb=function Nbc(a){return Gbc(this.a,BD(a,46))};_.Fb=function Obc(a){return this===a};_.a=0;var _S=mdb(Ane,'NodePromotion/lambda$1$Type',1565);bcb(1566,1,{},Pbc);_.Kb=function Qbc(a){return Hbc(this.a,BD(a,46))};_.Fb=function Rbc(a){return this===a};_.a=0;var aT=mdb(Ane,'NodePromotion/lambda$2$Type',1566);bcb(1567,1,ene,Xbc);_.pf=function Ybc(a,b){Sbc(BD(a,37),b)};var cT=mdb(Ane,'NorthSouthPortPostprocessor',1567);bcb(1568,1,ene,ccc);_.pf=function ecc(a,b){acc(BD(a,37),b)};var eT=mdb(Ane,'NorthSouthPortPreprocessor',1568);bcb(1569,1,Dke,fcc);_.ue=function gcc(a,b){return dcc(BD(a,11),BD(b,11))};_.Fb=function hcc(a){return this===a};_.ve=function icc(){return new tpb(this)};var dT=mdb(Ane,'NorthSouthPortPreprocessor/lambda$0$Type',1569);bcb(1570,1,ene,lcc);_.pf=function ncc(a,b){kcc(BD(a,37),b)};var hT=mdb(Ane,'PartitionMidprocessor',1570);bcb(1571,1,Oie,occ);_.Mb=function pcc(a){return wNb(BD(a,10),(Nyc(),Nxc))};var fT=mdb(Ane,'PartitionMidprocessor/lambda$0$Type',1571);bcb(1572,1,qie,qcc);_.td=function rcc(a){mcc(this.a,BD(a,10))};var gT=mdb(Ane,'PartitionMidprocessor/lambda$1$Type',1572);bcb(1573,1,ene,tcc);_.pf=function ucc(a,b){scc(BD(a,37),b)};var iT=mdb(Ane,'PartitionPostprocessor',1573);bcb(1574,1,ene,ycc);_.pf=function zcc(a,b){wcc(BD(a,37),b)};var nT=mdb(Ane,'PartitionPreprocessor',1574);bcb(1575,1,Oie,Acc);_.Mb=function Bcc(a){return wNb(BD(a,10),(Nyc(),Nxc))};var jT=mdb(Ane,'PartitionPreprocessor/lambda$0$Type',1575);bcb(1576,1,{},Ccc);_.Kb=function Dcc(a){return new YAb(null,new Lub(new Sr(ur(U_b(BD(a,10)).a.Kc(),new Sq))))};var kT=mdb(Ane,'PartitionPreprocessor/lambda$1$Type',1576);bcb(1577,1,Oie,Ecc);_.Mb=function Fcc(a){return vcc(BD(a,17))};var lT=mdb(Ane,'PartitionPreprocessor/lambda$2$Type',1577);bcb(1578,1,qie,Gcc);_.td=function Hcc(a){xcc(BD(a,17))};var mT=mdb(Ane,'PartitionPreprocessor/lambda$3$Type',1578);bcb(1579,1,ene,Tcc);_.pf=function Xcc(a,b){Qcc(BD(a,37),b)};var Icc,Jcc,Kcc,Lcc,Mcc,Ncc;var tT=mdb(Ane,'PortListSorter',1579);bcb(1580,1,{},Zcc);_.Kb=function $cc(a){return Occ(),BD(a,11).e};var oT=mdb(Ane,'PortListSorter/lambda$0$Type',1580);bcb(1581,1,{},_cc);_.Kb=function adc(a){return Occ(),BD(a,11).g};var pT=mdb(Ane,'PortListSorter/lambda$1$Type',1581);bcb(1582,1,Dke,bdc);_.ue=function cdc(a,b){return Ucc(BD(a,11),BD(b,11))};_.Fb=function ddc(a){return this===a};_.ve=function edc(){return new tpb(this)};var qT=mdb(Ane,'PortListSorter/lambda$2$Type',1582);bcb(1583,1,Dke,fdc);_.ue=function gdc(a,b){return Vcc(BD(a,11),BD(b,11))};_.Fb=function hdc(a){return this===a};_.ve=function idc(){return new tpb(this)};var rT=mdb(Ane,'PortListSorter/lambda$3$Type',1583);bcb(1584,1,Dke,jdc);_.ue=function kdc(a,b){return Wcc(BD(a,11),BD(b,11))};_.Fb=function ldc(a){return this===a};_.ve=function mdc(){return new tpb(this)};var sT=mdb(Ane,'PortListSorter/lambda$4$Type',1584);bcb(1585,1,ene,pdc);_.pf=function qdc(a,b){ndc(BD(a,37),b)};var uT=mdb(Ane,'PortSideProcessor',1585);bcb(1586,1,ene,sdc);_.pf=function tdc(a,b){rdc(BD(a,37),b)};var vT=mdb(Ane,'ReversedEdgeRestorer',1586);bcb(1591,1,ene,wdc);_.pf=function xdc(a,b){udc(this,BD(a,37),b)};var CT=mdb(Ane,'SelfLoopPortRestorer',1591);bcb(1592,1,{},ydc);_.Kb=function zdc(a){return new YAb(null,new Kub(BD(a,29).a,16))};var wT=mdb(Ane,'SelfLoopPortRestorer/lambda$0$Type',1592);bcb(1593,1,Oie,Adc);_.Mb=function Bdc(a){return BD(a,10).k==(j0b(),h0b)};var xT=mdb(Ane,'SelfLoopPortRestorer/lambda$1$Type',1593);bcb(1594,1,Oie,Cdc);_.Mb=function Ddc(a){return wNb(BD(a,10),(wtc(),ntc))};var yT=mdb(Ane,'SelfLoopPortRestorer/lambda$2$Type',1594);bcb(1595,1,{},Edc);_.Kb=function Fdc(a){return BD(vNb(BD(a,10),(wtc(),ntc)),403)};var zT=mdb(Ane,'SelfLoopPortRestorer/lambda$3$Type',1595);bcb(1596,1,qie,Gdc);_.td=function Hdc(a){vdc(this.a,BD(a,403))};var AT=mdb(Ane,'SelfLoopPortRestorer/lambda$4$Type',1596);bcb(794,1,qie,Idc);_.td=function Jdc(a){ljc(BD(a,101))};var BT=mdb(Ane,'SelfLoopPortRestorer/lambda$5$Type',794);bcb(1597,1,ene,Ndc);_.pf=function Pdc(a,b){Kdc(BD(a,37),b)};var LT=mdb(Ane,'SelfLoopPostProcessor',1597);bcb(1598,1,{},Qdc);_.Kb=function Rdc(a){return new YAb(null,new Kub(BD(a,29).a,16))};var DT=mdb(Ane,'SelfLoopPostProcessor/lambda$0$Type',1598);bcb(1599,1,Oie,Sdc);_.Mb=function Tdc(a){return BD(a,10).k==(j0b(),h0b)};var ET=mdb(Ane,'SelfLoopPostProcessor/lambda$1$Type',1599);bcb(1600,1,Oie,Udc);_.Mb=function Vdc(a){return wNb(BD(a,10),(wtc(),ntc))};var FT=mdb(Ane,'SelfLoopPostProcessor/lambda$2$Type',1600);bcb(1601,1,qie,Wdc);_.td=function Xdc(a){Ldc(BD(a,10))};var GT=mdb(Ane,'SelfLoopPostProcessor/lambda$3$Type',1601);bcb(1602,1,{},Ydc);_.Kb=function Zdc(a){return new YAb(null,new Kub(BD(a,101).f,1))};var HT=mdb(Ane,'SelfLoopPostProcessor/lambda$4$Type',1602);bcb(1603,1,qie,$dc);_.td=function _dc(a){Mdc(this.a,BD(a,409))};var IT=mdb(Ane,'SelfLoopPostProcessor/lambda$5$Type',1603);bcb(1604,1,Oie,aec);_.Mb=function bec(a){return !!BD(a,101).i};var JT=mdb(Ane,'SelfLoopPostProcessor/lambda$6$Type',1604);bcb(1605,1,qie,cec);_.td=function dec(a){Odc(this.a,BD(a,101))};var KT=mdb(Ane,'SelfLoopPostProcessor/lambda$7$Type',1605);bcb(1587,1,ene,hec);_.pf=function iec(a,b){gec(BD(a,37),b)};var PT=mdb(Ane,'SelfLoopPreProcessor',1587);bcb(1588,1,{},jec);_.Kb=function kec(a){return new YAb(null,new Kub(BD(a,101).f,1))};var MT=mdb(Ane,'SelfLoopPreProcessor/lambda$0$Type',1588);bcb(1589,1,{},lec);_.Kb=function mec(a){return BD(a,409).a};var NT=mdb(Ane,'SelfLoopPreProcessor/lambda$1$Type',1589);bcb(1590,1,qie,nec);_.td=function oec(a){fec(BD(a,17))};var OT=mdb(Ane,'SelfLoopPreProcessor/lambda$2$Type',1590);bcb(1606,1,ene,sec);_.pf=function tec(a,b){qec(this,BD(a,37),b)};var VT=mdb(Ane,'SelfLoopRouter',1606);bcb(1607,1,{},uec);_.Kb=function vec(a){return new YAb(null,new Kub(BD(a,29).a,16))};var QT=mdb(Ane,'SelfLoopRouter/lambda$0$Type',1607);bcb(1608,1,Oie,wec);_.Mb=function xec(a){return BD(a,10).k==(j0b(),h0b)};var RT=mdb(Ane,'SelfLoopRouter/lambda$1$Type',1608);bcb(1609,1,Oie,yec);_.Mb=function zec(a){return wNb(BD(a,10),(wtc(),ntc))};var ST=mdb(Ane,'SelfLoopRouter/lambda$2$Type',1609);bcb(1610,1,{},Aec);_.Kb=function Bec(a){return BD(vNb(BD(a,10),(wtc(),ntc)),403)};var TT=mdb(Ane,'SelfLoopRouter/lambda$3$Type',1610);bcb(1611,1,qie,Cec);_.td=function Dec(a){pec(this.a,this.b,BD(a,403))};var UT=mdb(Ane,'SelfLoopRouter/lambda$4$Type',1611);bcb(1612,1,ene,Fec);_.pf=function Iec(a,b){Eec(BD(a,37),b)};var $T=mdb(Ane,'SemiInteractiveCrossMinProcessor',1612);bcb(1613,1,Oie,Jec);_.Mb=function Kec(a){return BD(a,10).k==(j0b(),h0b)};var WT=mdb(Ane,'SemiInteractiveCrossMinProcessor/lambda$0$Type',1613);bcb(1614,1,Oie,Lec);_.Mb=function Mec(a){return uNb(BD(a,10))._b((Nyc(),ayc))};var XT=mdb(Ane,'SemiInteractiveCrossMinProcessor/lambda$1$Type',1614);bcb(1615,1,Dke,Nec);_.ue=function Oec(a,b){return Gec(BD(a,10),BD(b,10))};_.Fb=function Pec(a){return this===a};_.ve=function Qec(){return new tpb(this)};var YT=mdb(Ane,'SemiInteractiveCrossMinProcessor/lambda$2$Type',1615);bcb(1616,1,{},Rec);_.Ce=function Sec(a,b){return Hec(BD(a,10),BD(b,10))};var ZT=mdb(Ane,'SemiInteractiveCrossMinProcessor/lambda$3$Type',1616);bcb(1618,1,ene,Uec);_.pf=function Yec(a,b){Tec(BD(a,37),b)};var bU=mdb(Ane,'SortByInputModelProcessor',1618);bcb(1619,1,Oie,Zec);_.Mb=function $ec(a){return BD(a,11).g.c.length!=0};var _T=mdb(Ane,'SortByInputModelProcessor/lambda$0$Type',1619);bcb(1620,1,qie,_ec);_.td=function afc(a){Wec(this.a,BD(a,11))};var aU=mdb(Ane,'SortByInputModelProcessor/lambda$1$Type',1620);bcb(1693,803,{},jfc);_.Me=function kfc(a){var b,c,d,e;this.c=a;switch(this.a.g){case 2:b=new Rkb;MAb(JAb(new YAb(null,new Kub(this.c.a.b,16)),new lgc),new ngc(this,b));nEb(this,new tfc);Hkb(b,new xfc);b.c=KC(SI,Uhe,1,0,5,1);MAb(JAb(new YAb(null,new Kub(this.c.a.b,16)),new zfc),new Bfc(b));nEb(this,new Ffc);Hkb(b,new Jfc);b.c=KC(SI,Uhe,1,0,5,1);c=Ntb($zb(OAb(new YAb(null,new Kub(this.c.a.b,16)),new Lfc(this))),new Nfc);MAb(new YAb(null,new Kub(this.c.a.a,16)),new Rfc(c,b));nEb(this,new Vfc);Hkb(b,new Zfc);b.c=KC(SI,Uhe,1,0,5,1);break;case 3:d=new Rkb;nEb(this,new lfc);e=Ntb($zb(OAb(new YAb(null,new Kub(this.c.a.b,16)),new pfc(this))),new Pfc);MAb(JAb(new YAb(null,new Kub(this.c.a.b,16)),new _fc),new bgc(e,d));nEb(this,new fgc);Hkb(d,new jgc);d.c=KC(SI,Uhe,1,0,5,1);break;default:throw vbb(new x2c);}};_.b=0;var AU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation',1693);bcb(1694,1,Vke,lfc);_.Lb=function mfc(a){return JD(BD(a,57).g,145)};_.Fb=function nfc(a){return this===a};_.Mb=function ofc(a){return JD(BD(a,57).g,145)};var cU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$0$Type',1694);bcb(1695,1,{},pfc);_.Fe=function qfc(a){return dfc(this.a,BD(a,57))};var dU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$1$Type',1695);bcb(1703,1,Pie,rfc);_.Vd=function sfc(){cfc(this.a,this.b,-1)};_.b=0;var eU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$10$Type',1703);bcb(1705,1,Vke,tfc);_.Lb=function ufc(a){return JD(BD(a,57).g,145)};_.Fb=function vfc(a){return this===a};_.Mb=function wfc(a){return JD(BD(a,57).g,145)};var fU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$11$Type',1705);bcb(1706,1,qie,xfc);_.td=function yfc(a){BD(a,365).Vd()};var gU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$12$Type',1706);bcb(1707,1,Oie,zfc);_.Mb=function Afc(a){return JD(BD(a,57).g,10)};var hU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$13$Type',1707);bcb(1709,1,qie,Bfc);_.td=function Cfc(a){efc(this.a,BD(a,57))};var iU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$14$Type',1709);bcb(1708,1,Pie,Dfc);_.Vd=function Efc(){cfc(this.b,this.a,-1)};_.a=0;var jU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$15$Type',1708);bcb(1710,1,Vke,Ffc);_.Lb=function Gfc(a){return JD(BD(a,57).g,10)};_.Fb=function Hfc(a){return this===a};_.Mb=function Ifc(a){return JD(BD(a,57).g,10)};var kU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$16$Type',1710);bcb(1711,1,qie,Jfc);_.td=function Kfc(a){BD(a,365).Vd()};var lU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$17$Type',1711);bcb(1712,1,{},Lfc);_.Fe=function Mfc(a){return ffc(this.a,BD(a,57))};var mU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$18$Type',1712);bcb(1713,1,{},Nfc);_.De=function Ofc(){return 0};var nU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$19$Type',1713);bcb(1696,1,{},Pfc);_.De=function Qfc(){return 0};var oU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$2$Type',1696);bcb(1715,1,qie,Rfc);_.td=function Sfc(a){gfc(this.a,this.b,BD(a,307))};_.a=0;var pU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$20$Type',1715);bcb(1714,1,Pie,Tfc);_.Vd=function Ufc(){bfc(this.a,this.b,-1)};_.b=0;var qU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$21$Type',1714);bcb(1716,1,Vke,Vfc);_.Lb=function Wfc(a){return BD(a,57),true};_.Fb=function Xfc(a){return this===a};_.Mb=function Yfc(a){return BD(a,57),true};var rU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$22$Type',1716);bcb(1717,1,qie,Zfc);_.td=function $fc(a){BD(a,365).Vd()};var sU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$23$Type',1717);bcb(1697,1,Oie,_fc);_.Mb=function agc(a){return JD(BD(a,57).g,10)};var tU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$3$Type',1697);bcb(1699,1,qie,bgc);_.td=function cgc(a){hfc(this.a,this.b,BD(a,57))};_.a=0;var uU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$4$Type',1699);bcb(1698,1,Pie,dgc);_.Vd=function egc(){cfc(this.b,this.a,-1)};_.a=0;var vU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$5$Type',1698);bcb(1700,1,Vke,fgc);_.Lb=function ggc(a){return BD(a,57),true};_.Fb=function hgc(a){return this===a};_.Mb=function igc(a){return BD(a,57),true};var wU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$6$Type',1700);bcb(1701,1,qie,jgc);_.td=function kgc(a){BD(a,365).Vd()};var xU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$7$Type',1701);bcb(1702,1,Oie,lgc);_.Mb=function mgc(a){return JD(BD(a,57).g,145)};var yU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$8$Type',1702);bcb(1704,1,qie,ngc);_.td=function ogc(a){ifc(this.a,this.b,BD(a,57))};var zU=mdb(Jne,'EdgeAwareScanlineConstraintCalculation/lambda$9$Type',1704);bcb(1521,1,ene,sgc);_.pf=function xgc(a,b){rgc(this,BD(a,37),b)};var pgc;var EU=mdb(Jne,'HorizontalGraphCompactor',1521);bcb(1522,1,{},ygc);_.Oe=function zgc(a,b){var c,d,e;if(vgc(a,b)){return 0}c=tgc(a);d=tgc(b);if(!!c&&c.k==(j0b(),e0b)||!!d&&d.k==(j0b(),e0b)){return 0}e=BD(vNb(this.a.a,(wtc(),otc)),304);return fBc(e,c?c.k:(j0b(),g0b),d?d.k:(j0b(),g0b))};_.Pe=function Agc(a,b){var c,d,e;if(vgc(a,b)){return 1}c=tgc(a);d=tgc(b);e=BD(vNb(this.a.a,(wtc(),otc)),304);return iBc(e,c?c.k:(j0b(),g0b),d?d.k:(j0b(),g0b))};var BU=mdb(Jne,'HorizontalGraphCompactor/1',1522);bcb(1523,1,{},Bgc);_.Ne=function Cgc(a,b){return qgc(),a.a.i==0};var CU=mdb(Jne,'HorizontalGraphCompactor/lambda$0$Type',1523);bcb(1524,1,{},Dgc);_.Ne=function Egc(a,b){return wgc(this.a,a,b)};var DU=mdb(Jne,'HorizontalGraphCompactor/lambda$1$Type',1524);bcb(1664,1,{},Ygc);var Fgc,Ggc;var cV=mdb(Jne,'LGraphToCGraphTransformer',1664);bcb(1672,1,Oie,ehc);_.Mb=function fhc(a){return a!=null};var FU=mdb(Jne,'LGraphToCGraphTransformer/0methodref$nonNull$Type',1672);bcb(1665,1,{},ghc);_.Kb=function hhc(a){return Hgc(),fcb(vNb(BD(BD(a,57).g,10),(wtc(),$sc)))};var GU=mdb(Jne,'LGraphToCGraphTransformer/lambda$0$Type',1665);bcb(1666,1,{},ihc);_.Kb=function jhc(a){return Hgc(),gic(BD(BD(a,57).g,145))};var HU=mdb(Jne,'LGraphToCGraphTransformer/lambda$1$Type',1666);bcb(1675,1,Oie,khc);_.Mb=function lhc(a){return Hgc(),JD(BD(a,57).g,10)};var IU=mdb(Jne,'LGraphToCGraphTransformer/lambda$10$Type',1675);bcb(1676,1,qie,mhc);_.td=function nhc(a){Zgc(BD(a,57))};var JU=mdb(Jne,'LGraphToCGraphTransformer/lambda$11$Type',1676);bcb(1677,1,Oie,ohc);_.Mb=function phc(a){return Hgc(),JD(BD(a,57).g,145)};var KU=mdb(Jne,'LGraphToCGraphTransformer/lambda$12$Type',1677);bcb(1681,1,qie,qhc);_.td=function rhc(a){$gc(BD(a,57))};var LU=mdb(Jne,'LGraphToCGraphTransformer/lambda$13$Type',1681);bcb(1678,1,qie,shc);_.td=function thc(a){_gc(this.a,BD(a,8))};_.a=0;var MU=mdb(Jne,'LGraphToCGraphTransformer/lambda$14$Type',1678);bcb(1679,1,qie,uhc);_.td=function vhc(a){ahc(this.a,BD(a,110))};_.a=0;var NU=mdb(Jne,'LGraphToCGraphTransformer/lambda$15$Type',1679);bcb(1680,1,qie,whc);_.td=function xhc(a){bhc(this.a,BD(a,8))};_.a=0;var OU=mdb(Jne,'LGraphToCGraphTransformer/lambda$16$Type',1680);bcb(1682,1,{},yhc);_.Kb=function zhc(a){return Hgc(),new YAb(null,new Lub(new Sr(ur(U_b(BD(a,10)).a.Kc(),new Sq))))};var PU=mdb(Jne,'LGraphToCGraphTransformer/lambda$17$Type',1682);bcb(1683,1,Oie,Ahc);_.Mb=function Bhc(a){return Hgc(),OZb(BD(a,17))};var QU=mdb(Jne,'LGraphToCGraphTransformer/lambda$18$Type',1683);bcb(1684,1,qie,Chc);_.td=function Dhc(a){Qgc(this.a,BD(a,17))};var RU=mdb(Jne,'LGraphToCGraphTransformer/lambda$19$Type',1684);bcb(1668,1,qie,Ehc);_.td=function Fhc(a){Rgc(this.a,BD(a,145))};var SU=mdb(Jne,'LGraphToCGraphTransformer/lambda$2$Type',1668);bcb(1685,1,{},Ghc);_.Kb=function Hhc(a){return Hgc(),new YAb(null,new Kub(BD(a,29).a,16))};var TU=mdb(Jne,'LGraphToCGraphTransformer/lambda$20$Type',1685);bcb(1686,1,{},Ihc);_.Kb=function Jhc(a){return Hgc(),new YAb(null,new Lub(new Sr(ur(U_b(BD(a,10)).a.Kc(),new Sq))))};var UU=mdb(Jne,'LGraphToCGraphTransformer/lambda$21$Type',1686);bcb(1687,1,{},Khc);_.Kb=function Lhc(a){return Hgc(),BD(vNb(BD(a,17),(wtc(),rtc)),15)};var VU=mdb(Jne,'LGraphToCGraphTransformer/lambda$22$Type',1687);bcb(1688,1,Oie,Mhc);_.Mb=function Nhc(a){return chc(BD(a,15))};var WU=mdb(Jne,'LGraphToCGraphTransformer/lambda$23$Type',1688);bcb(1689,1,qie,Ohc);_.td=function Phc(a){Jgc(this.a,BD(a,15))};var XU=mdb(Jne,'LGraphToCGraphTransformer/lambda$24$Type',1689);bcb(1667,1,qie,Qhc);_.td=function Rhc(a){Sgc(this.a,this.b,BD(a,145))};var YU=mdb(Jne,'LGraphToCGraphTransformer/lambda$3$Type',1667);bcb(1669,1,{},Shc);_.Kb=function Thc(a){return Hgc(),new YAb(null,new Kub(BD(a,29).a,16))};var ZU=mdb(Jne,'LGraphToCGraphTransformer/lambda$4$Type',1669);bcb(1670,1,{},Uhc);_.Kb=function Vhc(a){return Hgc(),new YAb(null,new Lub(new Sr(ur(U_b(BD(a,10)).a.Kc(),new Sq))))};var $U=mdb(Jne,'LGraphToCGraphTransformer/lambda$5$Type',1670);bcb(1671,1,{},Whc);_.Kb=function Xhc(a){return Hgc(),BD(vNb(BD(a,17),(wtc(),rtc)),15)};var _U=mdb(Jne,'LGraphToCGraphTransformer/lambda$6$Type',1671);bcb(1673,1,qie,Yhc);_.td=function Zhc(a){dhc(this.a,BD(a,15))};var aV=mdb(Jne,'LGraphToCGraphTransformer/lambda$8$Type',1673);bcb(1674,1,qie,$hc);_.td=function _hc(a){Tgc(this.a,this.b,BD(a,145))};var bV=mdb(Jne,'LGraphToCGraphTransformer/lambda$9$Type',1674);bcb(1663,1,{},dic);_.Le=function eic(a){var b,c,d,e,f;this.a=a;this.d=new KFb;this.c=KC(jN,Uhe,121,this.a.a.a.c.length,0,1);this.b=0;for(c=new olb(this.a.a.a);c.a<c.c.c.length;){b=BD(mlb(c),307);b.d=this.b;f=nGb(oGb(new pGb,b),this.d);this.c[this.b]=f;++this.b}cic(this);bic(this);aic(this);uGb(LGb(this.d),new Zdd);for(e=new olb(this.a.a.b);e.a<e.c.c.length;){d=BD(mlb(e),57);d.d.c=this.c[d.a.d].e+d.b.a}};_.b=0;var dV=mdb(Jne,'NetworkSimplexCompaction',1663);bcb(145,1,{35:1,145:1},hic);_.wd=function iic(a){return fic(this,BD(a,145))};_.Ib=function jic(){return gic(this)};var eV=mdb(Jne,'VerticalSegment',145);bcb(827,1,{},sic);_.c=0;_.e=0;_.i=0;var hV=mdb(Kne,'BetweenLayerEdgeTwoNodeCrossingsCounter',827);bcb(663,1,{663:1},zic);_.Ib=function Aic(){return 'AdjacencyList [node='+this.d+', adjacencies= '+this.a+']'};_.b=0;_.c=0;_.f=0;var gV=mdb(Kne,'BetweenLayerEdgeTwoNodeCrossingsCounter/AdjacencyList',663);bcb(287,1,{35:1,287:1},Dic);_.wd=function Eic(a){return Bic(this,BD(a,287))};_.Ib=function Fic(){return 'Adjacency [position='+this.c+', cardinality='+this.a+', currentCardinality='+this.b+']'};_.a=0;_.b=0;_.c=0;var fV=mdb(Kne,'BetweenLayerEdgeTwoNodeCrossingsCounter/AdjacencyList/Adjacency',287);bcb(1929,1,{},Iic);_.b=0;_.e=false;var iV=mdb(Kne,'CrossingMatrixFiller',1929);var qY=odb(Lne,'IInitializable');bcb(1804,1,Mne,Oic);_.Nf=function Ric(a,b,c,d,e,f){};_.Pf=function Tic(a,b,c){};_.Lf=function Pic(){return this.c!=(rGc(),pGc)};_.Mf=function Qic(){this.e=KC(WD,oje,25,this.d,15,1)};_.Of=function Sic(a,b){b[a][0].c.p=a};_.Qf=function Uic(a,b,c,d){++this.d};_.Rf=function Vic(){return true};_.Sf=function Wic(a,b,c,d){Kic(this,a,b,c);return Jic(this,b)};_.Tf=function Xic(a,b){var c;c=Lic(b,a.length);Kic(this,a,c,b);return Mic(this,c)};_.d=0;var jV=mdb(Kne,'GreedySwitchHeuristic',1804);bcb(1930,1,{},ejc);_.b=0;_.d=0;var kV=mdb(Kne,'NorthSouthEdgeNeighbouringNodeCrossingsCounter',1930);bcb(1917,1,{},jjc);_.a=false;var lV=mdb(Kne,'SwitchDecider',1917);bcb(101,1,{101:1},pjc);_.a=null;_.c=null;_.i=null;var oV=mdb(Nne,'SelfHyperLoop',101);bcb(1916,1,{},vjc);_.c=0;_.e=0;var nV=mdb(Nne,'SelfHyperLoopLabels',1916);bcb(411,22,{3:1,35:1,22:1,411:1},Bjc);var wjc,xjc,yjc,zjc;var mV=ndb(Nne,'SelfHyperLoopLabels/Alignment',411,CI,Djc,Cjc);var Ejc;bcb(409,1,{409:1},Gjc);var pV=mdb(Nne,'SelfLoopEdge',409);bcb(403,1,{403:1},Kjc);_.a=false;var rV=mdb(Nne,'SelfLoopHolder',403);bcb(1724,1,Oie,Mjc);_.Mb=function Njc(a){return OZb(BD(a,17))};var qV=mdb(Nne,'SelfLoopHolder/lambda$0$Type',1724);bcb(113,1,{113:1},Pjc);_.a=false;_.c=false;var tV=mdb(Nne,'SelfLoopPort',113);bcb(1792,1,Oie,Qjc);_.Mb=function Rjc(a){return OZb(BD(a,17))};var sV=mdb(Nne,'SelfLoopPort/lambda$0$Type',1792);bcb(363,22,{3:1,35:1,22:1,363:1},Yjc);var Sjc,Tjc,Ujc,Vjc,Wjc;var uV=ndb(Nne,'SelfLoopType',363,CI,_jc,$jc);var akc;bcb(1732,1,{},xkc);var ckc,dkc,ekc,fkc;var JV=mdb(One,'PortRestorer',1732);bcb(361,22,{3:1,35:1,22:1,361:1},Gkc);var Ckc,Dkc,Ekc;var vV=ndb(One,'PortRestorer/PortSideArea',361,CI,Ikc,Hkc);var Jkc;bcb(1733,1,{},Lkc);_.Kb=function Mkc(a){return gkc(),BD(a,15).Oc()};var wV=mdb(One,'PortRestorer/lambda$0$Type',1733);bcb(1734,1,qie,Nkc);_.td=function Okc(a){gkc();BD(a,113).c=false};var xV=mdb(One,'PortRestorer/lambda$1$Type',1734);bcb(1743,1,Oie,Pkc);_.Mb=function Qkc(a){return gkc(),BD(a,11).j==(Ucd(),Tcd)};var yV=mdb(One,'PortRestorer/lambda$10$Type',1743);bcb(1744,1,{},Rkc);_.Kb=function Skc(a){return gkc(),BD(a,113).d};var zV=mdb(One,'PortRestorer/lambda$11$Type',1744);bcb(1745,1,qie,Tkc);_.td=function Ukc(a){ykc(this.a,BD(a,11))};var AV=mdb(One,'PortRestorer/lambda$12$Type',1745);bcb(1735,1,qie,Vkc);_.td=function Wkc(a){zkc(this.a,BD(a,101))};var BV=mdb(One,'PortRestorer/lambda$2$Type',1735);bcb(1736,1,Dke,Xkc);_.ue=function Ykc(a,b){return Akc(BD(a,113),BD(b,113))};_.Fb=function Zkc(a){return this===a};_.ve=function $kc(){return new tpb(this)};var CV=mdb(One,'PortRestorer/lambda$3$Type',1736);bcb(1737,1,Oie,_kc);_.Mb=function alc(a){return gkc(),BD(a,113).c};var DV=mdb(One,'PortRestorer/lambda$4$Type',1737);bcb(1738,1,Oie,blc);_.Mb=function clc(a){return nkc(BD(a,11))};var EV=mdb(One,'PortRestorer/lambda$5$Type',1738);bcb(1739,1,Oie,dlc);_.Mb=function elc(a){return gkc(),BD(a,11).j==(Ucd(),Acd)};var FV=mdb(One,'PortRestorer/lambda$6$Type',1739);bcb(1740,1,Oie,flc);_.Mb=function glc(a){return gkc(),BD(a,11).j==(Ucd(),zcd)};var GV=mdb(One,'PortRestorer/lambda$7$Type',1740);bcb(1741,1,Oie,hlc);_.Mb=function ilc(a){return okc(BD(a,11))};var HV=mdb(One,'PortRestorer/lambda$8$Type',1741);bcb(1742,1,Oie,jlc);_.Mb=function klc(a){return gkc(),BD(a,11).j==(Ucd(),Rcd)};var IV=mdb(One,'PortRestorer/lambda$9$Type',1742);bcb(270,22,{3:1,35:1,22:1,270:1},Blc);var slc,tlc,ulc,vlc,wlc,xlc,ylc,zlc;var KV=ndb(One,'PortSideAssigner/Target',270,CI,Dlc,Clc);var Elc;bcb(1725,1,{},Glc);_.Kb=function Hlc(a){return JAb(new YAb(null,new Kub(BD(a,101).j,16)),new Ylc)};var LV=mdb(One,'PortSideAssigner/lambda$1$Type',1725);bcb(1726,1,{},Ilc);_.Kb=function Jlc(a){return BD(a,113).d};var MV=mdb(One,'PortSideAssigner/lambda$2$Type',1726);bcb(1727,1,qie,Klc);_.td=function Llc(a){G0b(BD(a,11),(Ucd(),Acd))};var NV=mdb(One,'PortSideAssigner/lambda$3$Type',1727);bcb(1728,1,{},Mlc);_.Kb=function Nlc(a){return BD(a,113).d};var OV=mdb(One,'PortSideAssigner/lambda$4$Type',1728);bcb(1729,1,qie,Olc);_.td=function Plc(a){plc(this.a,BD(a,11))};var PV=mdb(One,'PortSideAssigner/lambda$5$Type',1729);bcb(1730,1,Dke,Qlc);_.ue=function Rlc(a,b){return qlc(BD(a,101),BD(b,101))};_.Fb=function Slc(a){return this===a};_.ve=function Tlc(){return new tpb(this)};var QV=mdb(One,'PortSideAssigner/lambda$6$Type',1730);bcb(1731,1,Dke,Ulc);_.ue=function Vlc(a,b){return rlc(BD(a,113),BD(b,113))};_.Fb=function Wlc(a){return this===a};_.ve=function Xlc(){return new tpb(this)};var RV=mdb(One,'PortSideAssigner/lambda$7$Type',1731);bcb(805,1,Oie,Ylc);_.Mb=function Zlc(a){return BD(a,113).c};var SV=mdb(One,'PortSideAssigner/lambda$8$Type',805);bcb(2009,1,{});var TV=mdb(Pne,'AbstractSelfLoopRouter',2009);bcb(1750,1,Dke,gmc);_.ue=function hmc(a,b){return emc(BD(a,101),BD(b,101))};_.Fb=function imc(a){return this===a};_.ve=function jmc(){return new tpb(this)};var UV=mdb(Pne,rle,1750);bcb(1751,1,Dke,kmc);_.ue=function lmc(a,b){return fmc(BD(a,101),BD(b,101))};_.Fb=function mmc(a){return this===a};_.ve=function nmc(){return new tpb(this)};var VV=mdb(Pne,sle,1751);bcb(1793,2009,{},zmc);_.Uf=function Amc(a,b,c){return c};var XV=mdb(Pne,'OrthogonalSelfLoopRouter',1793);bcb(1795,1,qie,Bmc);_.td=function Cmc(a){ymc(this.b,this.a,BD(a,8))};var WV=mdb(Pne,'OrthogonalSelfLoopRouter/lambda$0$Type',1795);bcb(1794,1793,{},Fmc);_.Uf=function Gmc(a,b,c){var d,e;d=a.c.d;St(c,0,P6c(R6c(d.n),d.a));e=a.d.d;Dsb(c,P6c(R6c(e.n),e.a));return Dmc(c)};var YV=mdb(Pne,'PolylineSelfLoopRouter',1794);bcb(1746,1,{},Umc);_.a=null;var Hmc;var aW=mdb(Pne,'RoutingDirector',1746);bcb(1747,1,Dke,Wmc);_.ue=function Xmc(a,b){return Vmc(BD(a,113),BD(b,113))};_.Fb=function Ymc(a){return this===a};_.ve=function Zmc(){return new tpb(this)};var ZV=mdb(Pne,'RoutingDirector/lambda$0$Type',1747);bcb(1748,1,{},$mc);_.Kb=function _mc(a){return Imc(),BD(a,101).j};var $V=mdb(Pne,'RoutingDirector/lambda$1$Type',1748);bcb(1749,1,qie,anc);_.td=function bnc(a){Imc();BD(a,15).ad(Hmc)};var _V=mdb(Pne,'RoutingDirector/lambda$2$Type',1749);bcb(1752,1,{},mnc);var dW=mdb(Pne,'RoutingSlotAssigner',1752);bcb(1753,1,Oie,pnc);_.Mb=function qnc(a){return nnc(this.a,BD(a,101))};var bW=mdb(Pne,'RoutingSlotAssigner/lambda$0$Type',1753);bcb(1754,1,Dke,rnc);_.ue=function snc(a,b){return onc(this.a,BD(a,101),BD(b,101))};_.Fb=function tnc(a){return this===a};_.ve=function unc(){return new tpb(this)};var cW=mdb(Pne,'RoutingSlotAssigner/lambda$1$Type',1754);bcb(1796,1793,{},wnc);_.Uf=function xnc(a,b,c){var d,e,f,g;d=Edb(ED(c_b(a.b.g.b,(Nyc(),nyc))));g=new u7c(OC(GC(m1,1),nie,8,0,[(f=a.c.d,P6c(new g7c(f.n),f.a))]));vnc(a,b,c,g,d);Dsb(g,(e=a.d.d,P6c(new g7c(e.n),e.a)));return UPc(new YPc(g))};var eW=mdb(Pne,'SplineSelfLoopRouter',1796);bcb(578,1,Dke,Bnc,Dnc);_.ue=function Enc(a,b){return ync(this,BD(a,10),BD(b,10))};_.Fb=function Fnc(a){return this===a};_.ve=function Gnc(){return new tpb(this)};var kW=mdb(Qne,'ModelOrderNodeComparator',578);bcb(1755,1,Oie,Hnc);_.Mb=function Inc(a){return BD(a,11).e.c.length!=0};var fW=mdb(Qne,'ModelOrderNodeComparator/lambda$0$Type',1755);bcb(1756,1,{},Jnc);_.Kb=function Knc(a){return BD(Ikb(BD(a,11).e,0),17).c};var gW=mdb(Qne,'ModelOrderNodeComparator/lambda$1$Type',1756);bcb(1757,1,Oie,Lnc);_.Mb=function Mnc(a){return BD(a,11).e.c.length!=0};var hW=mdb(Qne,'ModelOrderNodeComparator/lambda$2$Type',1757);bcb(1758,1,{},Nnc);_.Kb=function Onc(a){return BD(Ikb(BD(a,11).e,0),17).c};var iW=mdb(Qne,'ModelOrderNodeComparator/lambda$3$Type',1758);bcb(1759,1,Oie,Pnc);_.Mb=function Qnc(a){return BD(a,11).e.c.length!=0};var jW=mdb(Qne,'ModelOrderNodeComparator/lambda$4$Type',1759);bcb(806,1,Dke,Tnc,Unc);_.ue=function Vnc(a,b){return Rnc(this,a,b)};_.Fb=function Wnc(a){return this===a};_.ve=function Xnc(){return new tpb(this)};var lW=mdb(Qne,'ModelOrderPortComparator',806);bcb(801,1,{},Ync);_.Vf=function $nc(a,b){var c,d,e,f;e=Znc(b);c=new Rkb;f=b.f/e;for(d=1;d<e;++d){Ekb(c,meb(Tbb(Cbb($wnd.Math.round(d*f)))))}return c};_.Wf=function _nc(){return false};var mW=mdb(Rne,'ARDCutIndexHeuristic',801);bcb(1479,1,ene,eoc);_.pf=function foc(a,b){doc(BD(a,37),b)};var pW=mdb(Rne,'BreakingPointInserter',1479);bcb(305,1,{305:1},goc);_.Ib=function joc(){var a;a=new Ufb;a.a+='BPInfo[';a.a+='\n\tstart=';Pfb(a,this.i);a.a+='\n\tend=';Pfb(a,this.a);a.a+='\n\tnodeStartEdge=';Pfb(a,this.e);a.a+='\n\tstartEndEdge=';Pfb(a,this.j);a.a+='\n\toriginalEdge=';Pfb(a,this.f);a.a+='\n\tstartInLayerDummy=';Pfb(a,this.k);a.a+='\n\tstartInLayerEdge=';Pfb(a,this.n);a.a+='\n\tendInLayerDummy=';Pfb(a,this.b);a.a+='\n\tendInLayerEdge=';Pfb(a,this.c);return a.a};var nW=mdb(Rne,'BreakingPointInserter/BPInfo',305);bcb(652,1,{652:1},qoc);_.a=false;_.b=0;_.c=0;var oW=mdb(Rne,'BreakingPointInserter/Cut',652);bcb(1480,1,ene,Aoc);_.pf=function Boc(a,b){yoc(BD(a,37),b)};var sW=mdb(Rne,'BreakingPointProcessor',1480);bcb(1481,1,Oie,Coc);_.Mb=function Doc(a){return hoc(BD(a,10))};var qW=mdb(Rne,'BreakingPointProcessor/0methodref$isEnd$Type',1481);bcb(1482,1,Oie,Eoc);_.Mb=function Foc(a){return ioc(BD(a,10))};var rW=mdb(Rne,'BreakingPointProcessor/1methodref$isStart$Type',1482);bcb(1483,1,ene,Joc);_.pf=function Koc(a,b){Hoc(this,BD(a,37),b)};var uW=mdb(Rne,'BreakingPointRemover',1483);bcb(1484,1,qie,Loc);_.td=function Moc(a){BD(a,128).k=true};var tW=mdb(Rne,'BreakingPointRemover/lambda$0$Type',1484);bcb(797,1,{},Xoc);_.b=0;_.e=0;_.f=0;_.j=0;var AW=mdb(Rne,'GraphStats',797);bcb(798,1,{},Zoc);_.Ce=function $oc(a,b){return $wnd.Math.max(Edb(ED(a)),Edb(ED(b)))};var vW=mdb(Rne,'GraphStats/0methodref$max$Type',798);bcb(799,1,{},_oc);_.Ce=function apc(a,b){return $wnd.Math.max(Edb(ED(a)),Edb(ED(b)))};var wW=mdb(Rne,'GraphStats/2methodref$max$Type',799);bcb(1660,1,{},bpc);_.Ce=function cpc(a,b){return Yoc(ED(a),ED(b))};var xW=mdb(Rne,'GraphStats/lambda$1$Type',1660);bcb(1661,1,{},dpc);_.Kb=function epc(a){return Roc(this.a,BD(a,29))};var yW=mdb(Rne,'GraphStats/lambda$2$Type',1661);bcb(1662,1,{},fpc);_.Kb=function gpc(a){return Qoc(this.a,BD(a,29))};var zW=mdb(Rne,'GraphStats/lambda$6$Type',1662);bcb(800,1,{},hpc);_.Vf=function ipc(a,b){var c;c=BD(vNb(a,(Nyc(),Eyc)),15);return c?c:(mmb(),mmb(),jmb)};_.Wf=function jpc(){return false};var BW=mdb(Rne,'ICutIndexCalculator/ManualCutIndexCalculator',800);bcb(802,1,{},kpc);_.Vf=function lpc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;u=(b.n==null&&Uoc(b),b.n);i=(b.d==null&&Uoc(b),b.d);t=KC(UD,Vje,25,u.length,15,1);t[0]=u[0];r=u[0];for(j=1;j<u.length;j++){t[j]=t[j-1]+u[j];r+=u[j]}e=Znc(b)-1;g=BD(vNb(a,(Nyc(),Fyc)),19).a;d=Qje;c=new Rkb;for(m=$wnd.Math.max(0,e-g);m<=$wnd.Math.min(b.f-1,e+g);m++){p=r/(m+1);q=0;k=1;f=new Rkb;s=Qje;l=0;h=0;o=i[0];if(m==0){s=r;h=(b.g==null&&(b.g=Poc(b,new _oc)),Edb(b.g))}else{while(k<b.f){if(t[k-1]-q>=p){Ekb(f,meb(k));s=$wnd.Math.max(s,t[k-1]-l);h+=o;q+=t[k-1]-q;l=t[k-1];o=i[k]}o=$wnd.Math.max(o,i[k]);++k}h+=o}n=$wnd.Math.min(1/s,1/b.b/h);if(n>d){d=n;c=f}}return c};_.Wf=function mpc(){return false};var CW=mdb(Rne,'MSDCutIndexHeuristic',802);bcb(1617,1,ene,ppc);_.pf=function qpc(a,b){opc(BD(a,37),b)};var DW=mdb(Rne,'SingleEdgeGraphWrapper',1617);bcb(227,22,{3:1,35:1,22:1,227:1},Bpc);var upc,vpc,wpc,xpc,ypc,zpc;var EW=ndb(Sne,'CenterEdgeLabelPlacementStrategy',227,CI,Dpc,Cpc);var Epc;bcb(422,22,{3:1,35:1,22:1,422:1},Jpc);var Gpc,Hpc;var FW=ndb(Sne,'ConstraintCalculationStrategy',422,CI,Lpc,Kpc);var Mpc;bcb(314,22,{3:1,35:1,22:1,314:1,246:1,234:1},Tpc);_.Kf=function Vpc(){return Spc(this)};_.Xf=function Upc(){return Spc(this)};var Opc,Ppc,Qpc;var GW=ndb(Sne,'CrossingMinimizationStrategy',314,CI,Xpc,Wpc);var Ypc;bcb(337,22,{3:1,35:1,22:1,337:1},cqc);var $pc,_pc,aqc;var HW=ndb(Sne,'CuttingStrategy',337,CI,eqc,dqc);var fqc;bcb(335,22,{3:1,35:1,22:1,335:1,246:1,234:1},oqc);_.Kf=function qqc(){return nqc(this)};_.Xf=function pqc(){return nqc(this)};var hqc,iqc,jqc,kqc,lqc;var IW=ndb(Sne,'CycleBreakingStrategy',335,CI,sqc,rqc);var tqc;bcb(419,22,{3:1,35:1,22:1,419:1},yqc);var vqc,wqc;var JW=ndb(Sne,'DirectionCongruency',419,CI,Aqc,zqc);var Bqc;bcb(450,22,{3:1,35:1,22:1,450:1},Hqc);var Dqc,Eqc,Fqc;var KW=ndb(Sne,'EdgeConstraint',450,CI,Jqc,Iqc);var Kqc;bcb(276,22,{3:1,35:1,22:1,276:1},Uqc);var Mqc,Nqc,Oqc,Pqc,Qqc,Rqc;var LW=ndb(Sne,'EdgeLabelSideSelection',276,CI,Wqc,Vqc);var Xqc;bcb(479,22,{3:1,35:1,22:1,479:1},arc);var Zqc,$qc;var MW=ndb(Sne,'EdgeStraighteningStrategy',479,CI,crc,brc);var drc;bcb(274,22,{3:1,35:1,22:1,274:1},mrc);var frc,grc,hrc,irc,jrc,krc;var NW=ndb(Sne,'FixedAlignment',274,CI,orc,nrc);var prc;bcb(275,22,{3:1,35:1,22:1,275:1},zrc);var rrc,trc,urc,vrc,wrc,xrc;var OW=ndb(Sne,'GraphCompactionStrategy',275,CI,Brc,Arc);var Crc;bcb(256,22,{3:1,35:1,22:1,256:1},Prc);var Erc,Frc,Grc,Hrc,Irc,Jrc,Krc,Lrc,Mrc,Nrc;var PW=ndb(Sne,'GraphProperties',256,CI,Rrc,Qrc);var Src;bcb(292,22,{3:1,35:1,22:1,292:1},Yrc);var Urc,Vrc,Wrc;var QW=ndb(Sne,'GreedySwitchType',292,CI,$rc,Zrc);var _rc;bcb(303,22,{3:1,35:1,22:1,303:1},fsc);var bsc,csc,dsc;var RW=ndb(Sne,'InLayerConstraint',303,CI,hsc,gsc);var isc;bcb(420,22,{3:1,35:1,22:1,420:1},nsc);var ksc,lsc;var SW=ndb(Sne,'InteractiveReferencePoint',420,CI,psc,osc);var qsc;var ssc,tsc,usc,vsc,wsc,xsc,ysc,zsc,Asc,Bsc,Csc,Dsc,Esc,Fsc,Gsc,Hsc,Isc,Jsc,Ksc,Lsc,Msc,Nsc,Osc,Psc,Qsc,Rsc,Ssc,Tsc,Usc,Vsc,Wsc,Xsc,Ysc,Zsc,$sc,_sc,atc,btc,ctc,dtc,etc,ftc,gtc,htc,itc,jtc,ktc,ltc,mtc,ntc,otc,ptc,qtc,rtc,stc,ttc,utc,vtc;bcb(163,22,{3:1,35:1,22:1,163:1},Dtc);var xtc,ytc,ztc,Atc,Btc;var TW=ndb(Sne,'LayerConstraint',163,CI,Ftc,Etc);var Gtc;bcb(848,1,ale,kwc);_.Qe=function lwc(a){t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Yne),''),'Direction Congruency'),'Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other.'),puc),(_5c(),V5c)),JW),pqb((N5c(),L5c)))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Zne),''),'Feedback Edges'),'Whether feedback edges should be highlighted by routing around the nodes.'),(Bcb(),false)),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,$ne),''),'Interactive Reference Point'),'Determines which point of a node is considered by interactive layout phases.'),Muc),V5c),SW),pqb(L5c))));o4c(a,$ne,goe,Ouc);o4c(a,$ne,qoe,Nuc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,_ne),''),'Merge Edges'),'Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,aoe),''),'Merge Hierarchy-Crossing Edges'),'If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port.'),true),T5c),wI),pqb(L5c))));t4c(a,new p5c(C5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,boe),''),'Allow Non-Flow Ports To Switch Sides'),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),false),T5c),wI),pqb(M5c)),OC(GC(ZI,1),nie,2,6,['org.eclipse.elk.layered.northOrSouthPort']))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,coe),''),'Port Sorting Strategy'),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),xvc),V5c),cX),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,doe),''),'Thoroughness'),'How much effort should be spent to produce a nice layout.'),meb(7)),X5c),JI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,eoe),''),'Add Unnecessary Bendpoints'),'Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,foe),''),'Generate Position and Layer IDs'),'If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,goe),'cycleBreaking'),'Cycle Breaking Strategy'),'Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right).'),nuc),V5c),IW),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,hoe),ppe),'Node Layering Strategy'),'Strategy for node layering.'),bvc),V5c),YW),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,ioe),ppe),'Layer Constraint'),'Determines a constraint on the placement of the node regarding the layering.'),Tuc),V5c),TW),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,joe),ppe),'Layer Choice Constraint'),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),meb(-1)),X5c),JI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,koe),ppe),'Layer ID'),'Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set.'),meb(-1)),X5c),JI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,loe),qpe),'Upper Bound On Width [MinWidth Layerer]'),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),meb(4)),X5c),JI),pqb(L5c))));o4c(a,loe,hoe,Wuc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,moe),qpe),'Upper Layer Estimation Scaling Factor [MinWidth Layerer]'),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),meb(2)),X5c),JI),pqb(L5c))));o4c(a,moe,hoe,Yuc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,noe),rpe),'Node Promotion Strategy'),'Reduces number of dummy nodes after layering phase (if possible).'),_uc),V5c),aX),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,ooe),rpe),'Max Node Promotion Iterations'),'Limits the number of iterations for node promotion.'),meb(0)),X5c),JI),pqb(L5c))));o4c(a,ooe,noe,null);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,poe),'layering.coffmanGraham'),'Layer Bound'),'The maximum number of nodes allowed per layer.'),meb(Ohe)),X5c),JI),pqb(L5c))));o4c(a,poe,hoe,Quc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,qoe),spe),'Crossing Minimization Strategy'),'Strategy for crossing minimization.'),luc),V5c),GW),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,roe),spe),'Force Node Model Order'),'The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,soe),spe),'Hierarchical Sweepiness'),'How likely it is to use cross-hierarchy (1) vs bottom-up (-1).'),0.1),U5c),BI),pqb(L5c))));o4c(a,soe,tpe,fuc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,toe),spe),'Semi-Interactive Crossing Minimization'),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),false),T5c),wI),pqb(L5c))));o4c(a,toe,qoe,juc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,uoe),spe),'Position Choice Constraint'),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),meb(-1)),X5c),JI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,voe),spe),'Position ID'),'Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set.'),meb(-1)),X5c),JI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,woe),upe),'Greedy Switch Activation Threshold'),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),meb(40)),X5c),JI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,xoe),upe),'Greedy Switch Crossing Minimization'),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),cuc),V5c),QW),pqb(L5c))));o4c(a,xoe,qoe,duc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,yoe),'crossingMinimization.greedySwitchHierarchical'),'Greedy Switch Crossing Minimization (hierarchical)'),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),$tc),V5c),QW),pqb(L5c))));o4c(a,yoe,qoe,_tc);o4c(a,yoe,tpe,auc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,zoe),vpe),'Node Placement Strategy'),'Strategy for node placement.'),vvc),V5c),_W),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Aoe),vpe),'Favor Straight Edges Over Balancing'),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),T5c),wI),pqb(L5c))));o4c(a,Aoe,zoe,lvc);o4c(a,Aoe,zoe,mvc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Boe),wpe),'BK Edge Straightening'),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),fvc),V5c),MW),pqb(L5c))));o4c(a,Boe,zoe,gvc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Coe),wpe),'BK Fixed Alignment'),'Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four.'),ivc),V5c),NW),pqb(L5c))));o4c(a,Coe,zoe,jvc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Doe),'nodePlacement.linearSegments'),'Linear Segments Deflection Dampening'),'Dampens the movement of nodes to keep the diagram from getting too large.'),0.3),U5c),BI),pqb(L5c))));o4c(a,Doe,zoe,ovc);t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Eoe),'nodePlacement.networkSimplex'),'Node Flexibility'),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),V5c),$W),pqb(K5c))));o4c(a,Eoe,zoe,tvc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Foe),'nodePlacement.networkSimplex.nodeFlexibility'),'Node Flexibility Default'),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),rvc),V5c),$W),pqb(L5c))));o4c(a,Foe,zoe,svc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Goe),xpe),'Self-Loop Distribution'),'Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE.'),xuc),V5c),eX),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Hoe),xpe),'Self-Loop Ordering'),'Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE.'),zuc),V5c),fX),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ioe),'edgeRouting.splines'),'Spline Routing Mode'),'Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes.'),Buc),V5c),hX),pqb(L5c))));o4c(a,Ioe,ype,Cuc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Joe),'edgeRouting.splines.sloppy'),'Sloppy Spline Layer Spacing Factor'),'Spacing factor for routing area between layers when using sloppy spline routing.'),0.2),U5c),BI),pqb(L5c))));o4c(a,Joe,ype,Euc);o4c(a,Joe,Ioe,Fuc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Koe),'edgeRouting.polyline'),'Sloped Edge Zone Width'),'Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer.'),2),U5c),BI),pqb(L5c))));o4c(a,Koe,ype,vuc);t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Loe),zpe),'Spacing Base Value'),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Moe),zpe),'Edge Node Between Layers Spacing'),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Noe),zpe),'Edge Edge Between Layer Spacing'),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ooe),zpe),'Node Node Between Layers Spacing'),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Poe),Ape),'Direction Priority'),'Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase.'),meb(0)),X5c),JI),pqb(I5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Qoe),Ape),'Shortness Priority'),'Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase.'),meb(0)),X5c),JI),pqb(I5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Roe),Ape),'Straightness Priority'),'Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement.'),meb(0)),X5c),JI),pqb(I5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Soe),Bpe),Ole),'Tries to further compact components (disconnected sub-graphs).'),false),T5c),wI),pqb(L5c))));o4c(a,Soe,zme,true);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Toe),Cpe),'Post Compaction Strategy'),Dpe),Ntc),V5c),OW),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Uoe),Cpe),'Post Compaction Constraint Calculation'),Dpe),Ltc),V5c),FW),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Voe),Epe),'High Degree Node Treatment'),'Makes room around high degree nodes to place leafs and trees.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Woe),Epe),'High Degree Node Threshold'),'Whether a node is considered to have a high degree.'),meb(16)),X5c),JI),pqb(L5c))));o4c(a,Woe,Voe,true);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Xoe),Epe),'High Degree Node Maximum Tree Height'),'Maximum height of a subtree connected to a high degree node to be moved to separate layers.'),meb(5)),X5c),JI),pqb(L5c))));o4c(a,Xoe,Voe,true);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Yoe),Fpe),'Graph Wrapping Strategy'),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),bwc),V5c),jX),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Zoe),Fpe),'Additional Wrapped Edges Spacing'),'To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing.'),10),U5c),BI),pqb(L5c))));o4c(a,Zoe,Yoe,Ivc);o4c(a,Zoe,Yoe,Jvc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,$oe),Fpe),'Correction Factor for Wrapping'),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),U5c),BI),pqb(L5c))));o4c(a,$oe,Yoe,Lvc);o4c(a,$oe,Yoe,Mvc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,_oe),Gpe),'Cutting Strategy'),'The strategy by which the layer indexes are determined at which the layering crumbles into chunks.'),Tvc),V5c),HW),pqb(L5c))));o4c(a,_oe,Yoe,Uvc);o4c(a,_oe,Yoe,Vvc);t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,ape),Gpe),'Manually Specified Cuts'),'Allows the user to specify her own cuts for a certain graph.'),Y5c),yK),pqb(L5c))));o4c(a,ape,_oe,Ovc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,bpe),'wrapping.cutting.msd'),'MSD Freedom'),'The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts.'),Qvc),X5c),JI),pqb(L5c))));o4c(a,bpe,_oe,Rvc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,cpe),Hpe),'Validification Strategy'),'When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed.'),gwc),V5c),iX),pqb(L5c))));o4c(a,cpe,Yoe,hwc);o4c(a,cpe,Yoe,iwc);t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,dpe),Hpe),'Valid Indices for Wrapping'),null),Y5c),yK),pqb(L5c))));o4c(a,dpe,Yoe,dwc);o4c(a,dpe,Yoe,ewc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,epe),Ipe),'Improve Cuts'),'For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought.'),true),T5c),wI),pqb(L5c))));o4c(a,epe,Yoe,Zvc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,fpe),Ipe),'Distance Penalty When Improving Cuts'),null),2),U5c),BI),pqb(L5c))));o4c(a,fpe,Yoe,Xvc);o4c(a,fpe,epe,true);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,gpe),Ipe),'Improve Wrapped Edges'),'The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges.'),true),T5c),wI),pqb(L5c))));o4c(a,gpe,Yoe,_vc);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,hpe),Jpe),'Edge Label Side Selection'),'Method to decide on edge label sides.'),tuc),V5c),LW),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,ipe),Jpe),'Edge Center Label Placement Strategy'),'Determines in which layer center labels of long edges should be placed.'),ruc),V5c),EW),qqb(L5c,OC(GC(e1,1),Kie,175,0,[J5c])))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,jpe),Kpe),'Consider Model Order'),'Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting.'),Wtc),V5c),bX),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,kpe),Kpe),'No Model Order'),'Set on a node to not set a model order for this node even though it is a real node.'),false),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,lpe),Kpe),'Consider Model Order for Components'),'If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected.'),Ptc),V5c),hQ),pqb(L5c))));o4c(a,lpe,zme,null);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,mpe),Kpe),'Long Edge Ordering Strategy'),'Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout.'),Ttc),V5c),ZW),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,npe),Kpe),'Crossing Counter Node Order Influence'),'Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0).'),0),U5c),BI),pqb(L5c))));o4c(a,npe,jpe,null);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,ope),Kpe),'Crossing Counter Port Order Influence'),'Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0).'),0),U5c),BI),pqb(L5c))));o4c(a,ope,jpe,null);Oyc((new Pyc,a))};var Itc,Jtc,Ktc,Ltc,Mtc,Ntc,Otc,Ptc,Qtc,Rtc,Stc,Ttc,Utc,Vtc,Wtc,Xtc,Ytc,Ztc,$tc,_tc,auc,buc,cuc,duc,euc,fuc,guc,huc,iuc,juc,kuc,luc,muc,nuc,ouc,puc,quc,ruc,suc,tuc,uuc,vuc,wuc,xuc,yuc,zuc,Auc,Buc,Cuc,Duc,Euc,Fuc,Guc,Huc,Iuc,Juc,Kuc,Luc,Muc,Nuc,Ouc,Puc,Quc,Ruc,Suc,Tuc,Uuc,Vuc,Wuc,Xuc,Yuc,Zuc,$uc,_uc,avc,bvc,cvc,dvc,evc,fvc,gvc,hvc,ivc,jvc,kvc,lvc,mvc,nvc,ovc,pvc,qvc,rvc,svc,tvc,uvc,vvc,wvc,xvc,yvc,zvc,Avc,Bvc,Cvc,Dvc,Evc,Fvc,Gvc,Hvc,Ivc,Jvc,Kvc,Lvc,Mvc,Nvc,Ovc,Pvc,Qvc,Rvc,Svc,Tvc,Uvc,Vvc,Wvc,Xvc,Yvc,Zvc,$vc,_vc,awc,bwc,cwc,dwc,ewc,fwc,gwc,hwc,iwc;var UW=mdb(Sne,'LayeredMetaDataProvider',848);bcb(986,1,ale,Pyc);_.Qe=function Qyc(a){Oyc(a)};var mwc,nwc,owc,pwc,qwc,rwc,swc,twc,uwc,vwc,wwc,xwc,ywc,zwc,Awc,Bwc,Cwc,Dwc,Ewc,Fwc,Gwc,Hwc,Iwc,Jwc,Kwc,Lwc,Mwc,Nwc,Owc,Pwc,Qwc,Rwc,Swc,Twc,Uwc,Vwc,Wwc,Xwc,Ywc,Zwc,$wc,_wc,axc,bxc,cxc,dxc,exc,fxc,gxc,hxc,ixc,jxc,kxc,lxc,mxc,nxc,oxc,pxc,qxc,rxc,sxc,txc,uxc,vxc,wxc,xxc,yxc,zxc,Axc,Bxc,Cxc,Dxc,Exc,Fxc,Gxc,Hxc,Ixc,Jxc,Kxc,Lxc,Mxc,Nxc,Oxc,Pxc,Qxc,Rxc,Sxc,Txc,Uxc,Vxc,Wxc,Xxc,Yxc,Zxc,$xc,_xc,ayc,byc,cyc,dyc,eyc,fyc,gyc,hyc,iyc,jyc,kyc,lyc,myc,nyc,oyc,pyc,qyc,ryc,syc,tyc,uyc,vyc,wyc,xyc,yyc,zyc,Ayc,Byc,Cyc,Dyc,Eyc,Fyc,Gyc,Hyc,Iyc,Jyc,Kyc,Lyc,Myc;var WW=mdb(Sne,'LayeredOptions',986);bcb(987,1,{},Ryc);_.$e=function Syc(){var a;return a=new jUb,a};_._e=function Tyc(a){};var VW=mdb(Sne,'LayeredOptions/LayeredFactory',987);bcb(1372,1,{});_.a=0;var Uyc;var $1=mdb(yqe,'ElkSpacings/AbstractSpacingsBuilder',1372);bcb(779,1372,{},ezc);var bzc,czc;var XW=mdb(Sne,'LayeredSpacings/LayeredSpacingsBuilder',779);bcb(313,22,{3:1,35:1,22:1,313:1,246:1,234:1},nzc);_.Kf=function pzc(){return mzc(this)};_.Xf=function ozc(){return mzc(this)};var fzc,gzc,hzc,izc,jzc,kzc;var YW=ndb(Sne,'LayeringStrategy',313,CI,rzc,qzc);var szc;bcb(378,22,{3:1,35:1,22:1,378:1},zzc);var uzc,vzc,wzc;var ZW=ndb(Sne,'LongEdgeOrderingStrategy',378,CI,Bzc,Azc);var Czc;bcb(197,22,{3:1,35:1,22:1,197:1},Kzc);var Ezc,Fzc,Gzc,Hzc;var $W=ndb(Sne,'NodeFlexibility',197,CI,Nzc,Mzc);var Ozc;bcb(315,22,{3:1,35:1,22:1,315:1,246:1,234:1},Xzc);_.Kf=function Zzc(){return Wzc(this)};_.Xf=function Yzc(){return Wzc(this)};var Qzc,Rzc,Szc,Tzc,Uzc;var _W=ndb(Sne,'NodePlacementStrategy',315,CI,_zc,$zc);var aAc;bcb(260,22,{3:1,35:1,22:1,260:1},lAc);var cAc,dAc,eAc,fAc,gAc,hAc,iAc,jAc;var aX=ndb(Sne,'NodePromotionStrategy',260,CI,nAc,mAc);var oAc;bcb(339,22,{3:1,35:1,22:1,339:1},uAc);var qAc,rAc,sAc;var bX=ndb(Sne,'OrderingStrategy',339,CI,wAc,vAc);var xAc;bcb(421,22,{3:1,35:1,22:1,421:1},CAc);var zAc,AAc;var cX=ndb(Sne,'PortSortingStrategy',421,CI,EAc,DAc);var FAc;bcb(452,22,{3:1,35:1,22:1,452:1},LAc);var HAc,IAc,JAc;var dX=ndb(Sne,'PortType',452,CI,NAc,MAc);var OAc;bcb(375,22,{3:1,35:1,22:1,375:1},UAc);var QAc,RAc,SAc;var eX=ndb(Sne,'SelfLoopDistributionStrategy',375,CI,WAc,VAc);var XAc;bcb(376,22,{3:1,35:1,22:1,376:1},aBc);var ZAc,$Ac;var fX=ndb(Sne,'SelfLoopOrderingStrategy',376,CI,cBc,bBc);var dBc;bcb(304,1,{304:1},oBc);var gX=mdb(Sne,'Spacings',304);bcb(336,22,{3:1,35:1,22:1,336:1},uBc);var qBc,rBc,sBc;var hX=ndb(Sne,'SplineRoutingMode',336,CI,wBc,vBc);var xBc;bcb(338,22,{3:1,35:1,22:1,338:1},DBc);var zBc,ABc,BBc;var iX=ndb(Sne,'ValidifyStrategy',338,CI,FBc,EBc);var GBc;bcb(377,22,{3:1,35:1,22:1,377:1},MBc);var IBc,JBc,KBc;var jX=ndb(Sne,'WrappingStrategy',377,CI,OBc,NBc);var PBc;bcb(1383,1,Bqe,VBc);_.Yf=function WBc(a){return BD(a,37),RBc};_.pf=function XBc(a,b){UBc(this,BD(a,37),b)};var RBc;var kX=mdb(Cqe,'DepthFirstCycleBreaker',1383);bcb(782,1,Bqe,aCc);_.Yf=function cCc(a){return BD(a,37),YBc};_.pf=function dCc(a,b){$Bc(this,BD(a,37),b)};_.Zf=function bCc(a){return BD(Ikb(a,Bub(this.d,a.c.length)),10)};var YBc;var lX=mdb(Cqe,'GreedyCycleBreaker',782);bcb(1386,782,Bqe,eCc);_.Zf=function fCc(a){var b,c,d,e;e=null;b=Ohe;for(d=new olb(a);d.a<d.c.c.length;){c=BD(mlb(d),10);if(wNb(c,(wtc(),Zsc))&&BD(vNb(c,Zsc),19).a<b){b=BD(vNb(c,Zsc),19).a;e=c}}if(!e){return BD(Ikb(a,Bub(this.d,a.c.length)),10)}return e};var mX=mdb(Cqe,'GreedyModelOrderCycleBreaker',1386);bcb(1384,1,Bqe,kCc);_.Yf=function lCc(a){return BD(a,37),gCc};_.pf=function mCc(a,b){jCc(this,BD(a,37),b)};var gCc;var nX=mdb(Cqe,'InteractiveCycleBreaker',1384);bcb(1385,1,Bqe,rCc);_.Yf=function sCc(a){return BD(a,37),nCc};_.pf=function tCc(a,b){qCc(this,BD(a,37),b)};_.a=0;_.b=0;var nCc;var oX=mdb(Cqe,'ModelOrderCycleBreaker',1385);bcb(1389,1,Bqe,DCc);_.Yf=function ECc(a){return BD(a,37),uCc};_.pf=function FCc(a,b){BCc(this,BD(a,37),b)};var uCc;var rX=mdb(Dqe,'CoffmanGrahamLayerer',1389);bcb(1390,1,Dke,GCc);_.ue=function HCc(a,b){return xCc(this.a,BD(a,10),BD(b,10))};_.Fb=function ICc(a){return this===a};_.ve=function JCc(){return new tpb(this)};var pX=mdb(Dqe,'CoffmanGrahamLayerer/0methodref$compareNodesInTopo$Type',1390);bcb(1391,1,Dke,KCc);_.ue=function LCc(a,b){return ACc(this.a,BD(a,10),BD(b,10))};_.Fb=function MCc(a){return this===a};_.ve=function NCc(){return new tpb(this)};var qX=mdb(Dqe,'CoffmanGrahamLayerer/lambda$1$Type',1391);bcb(1392,1,Bqe,QCc);_.Yf=function RCc(a){return BD(a,37),e3c(e3c(e3c(new j3c,(qUb(),lUb),(S8b(),n8b)),mUb,w8b),nUb,v8b)};_.pf=function SCc(a,b){PCc(this,BD(a,37),b)};var tX=mdb(Dqe,'InteractiveLayerer',1392);bcb(569,1,{569:1},TCc);_.a=0;_.c=0;var sX=mdb(Dqe,'InteractiveLayerer/LayerSpan',569);bcb(1388,1,Bqe,ZCc);_.Yf=function $Cc(a){return BD(a,37),UCc};_.pf=function _Cc(a,b){WCc(this,BD(a,37),b)};var UCc;var uX=mdb(Dqe,'LongestPathLayerer',1388);bcb(1395,1,Bqe,iDc);_.Yf=function jDc(a){return BD(a,37),e3c(e3c(e3c(new j3c,(qUb(),lUb),(S8b(),Z7b)),mUb,w8b),nUb,v8b)};_.pf=function kDc(a,b){gDc(this,BD(a,37),b)};_.a=0;_.b=0;_.d=0;var aDc,bDc;var wX=mdb(Dqe,'MinWidthLayerer',1395);bcb(1396,1,Dke,mDc);_.ue=function nDc(a,b){return lDc(this,BD(a,10),BD(b,10))};_.Fb=function oDc(a){return this===a};_.ve=function pDc(){return new tpb(this)};var vX=mdb(Dqe,'MinWidthLayerer/MinOutgoingEdgesComparator',1396);bcb(1387,1,Bqe,xDc);_.Yf=function yDc(a){return BD(a,37),qDc};_.pf=function zDc(a,b){wDc(this,BD(a,37),b)};var qDc;var xX=mdb(Dqe,'NetworkSimplexLayerer',1387);bcb(1393,1,Bqe,LDc);_.Yf=function MDc(a){return BD(a,37),e3c(e3c(e3c(new j3c,(qUb(),lUb),(S8b(),Z7b)),mUb,w8b),nUb,v8b)};_.pf=function NDc(a,b){IDc(this,BD(a,37),b)};_.d=0;_.f=0;_.g=0;_.i=0;_.s=0;_.t=0;_.u=0;var zX=mdb(Dqe,'StretchWidthLayerer',1393);bcb(1394,1,Dke,PDc);_.ue=function QDc(a,b){return ODc(BD(a,10),BD(b,10))};_.Fb=function RDc(a){return this===a};_.ve=function SDc(){return new tpb(this)};var yX=mdb(Dqe,'StretchWidthLayerer/1',1394);bcb(402,1,Eqe);_.Nf=function fEc(a,b,c,d,e,f){};_._f=function dEc(a,b,c){return YDc(this,a,b,c)};_.Mf=function eEc(){this.g=KC(VD,Fqe,25,this.d,15,1);this.f=KC(VD,Fqe,25,this.d,15,1)};_.Of=function gEc(a,b){this.e[a]=KC(WD,oje,25,b[a].length,15,1)};_.Pf=function hEc(a,b,c){var d;d=c[a][b];d.p=b;this.e[a][b]=b};_.Qf=function iEc(a,b,c,d){BD(Ikb(d[a][b].j,c),11).p=this.d++};_.b=0;_.c=0;_.d=0;var BX=mdb(Gqe,'AbstractBarycenterPortDistributor',402);bcb(1633,1,Dke,jEc);_.ue=function kEc(a,b){return _Dc(this.a,BD(a,11),BD(b,11))};_.Fb=function lEc(a){return this===a};_.ve=function mEc(){return new tpb(this)};var AX=mdb(Gqe,'AbstractBarycenterPortDistributor/lambda$0$Type',1633);bcb(817,1,Mne,uEc);_.Nf=function xEc(a,b,c,d,e,f){};_.Pf=function zEc(a,b,c){};_.Qf=function AEc(a,b,c,d){};_.Lf=function vEc(){return false};_.Mf=function wEc(){this.c=this.e.a;this.g=this.f.g};_.Of=function yEc(a,b){b[a][0].c.p=a};_.Rf=function BEc(){return false};_.ag=function CEc(a,b,c,d){if(c){rEc(this,a)}else{oEc(this,a,d);pEc(this,a,b)}if(a.c.length>1){Ccb(DD(vNb(Q_b((tCb(0,a.c.length),BD(a.c[0],10))),(Nyc(),Awc))))?YGc(a,this.d,BD(this,660)):(mmb(),Okb(a,this.d));PEc(this.e,a)}};_.Sf=function DEc(a,b,c,d){var e,f,g,h,i,j,k;if(b!=sEc(c,a.length)){f=a[b-(c?1:-1)];UDc(this.f,f,c?(KAc(),IAc):(KAc(),HAc))}e=a[b][0];k=!d||e.k==(j0b(),e0b);j=Ou(a[b]);this.ag(j,k,false,c);g=0;for(i=new olb(j);i.a<i.c.c.length;){h=BD(mlb(i),10);a[b][g++]=h}return false};_.Tf=function EEc(a,b){var c,d,e,f,g;g=sEc(b,a.length);f=Ou(a[g]);this.ag(f,false,true,b);c=0;for(e=new olb(f);e.a<e.c.c.length;){d=BD(mlb(e),10);a[g][c++]=d}return false};var EX=mdb(Gqe,'BarycenterHeuristic',817);bcb(658,1,{658:1},FEc);_.Ib=function GEc(){return 'BarycenterState [node='+this.c+', summedWeight='+this.d+', degree='+this.b+', barycenter='+this.a+', visited='+this.e+']'};_.b=0;_.d=0;_.e=false;var CX=mdb(Gqe,'BarycenterHeuristic/BarycenterState',658);bcb(1802,1,Dke,HEc);_.ue=function IEc(a,b){return qEc(this.a,BD(a,10),BD(b,10))};_.Fb=function JEc(a){return this===a};_.ve=function KEc(){return new tpb(this)};var DX=mdb(Gqe,'BarycenterHeuristic/lambda$0$Type',1802);bcb(816,1,Mne,SEc);_.Mf=function TEc(){};_.Nf=function UEc(a,b,c,d,e,f){};_.Qf=function XEc(a,b,c,d){};_.Of=function VEc(a,b){this.a[a]=KC(CX,{3:1,4:1,5:1,2018:1},658,b[a].length,0,1);this.b[a]=KC(FX,{3:1,4:1,5:1,2019:1},233,b[a].length,0,1)};_.Pf=function WEc(a,b,c){OEc(this,c[a][b],true)};_.c=false;var HX=mdb(Gqe,'ForsterConstraintResolver',816);bcb(233,1,{233:1},$Ec,_Ec);_.Ib=function aFc(){var a,b;b=new Ufb;b.a+='[';for(a=0;a<this.d.length;a++){Qfb(b,a0b(this.d[a]));REc(this.g,this.d[0]).a!=null&&Qfb(Qfb((b.a+='<',b),Jdb(REc(this.g,this.d[0]).a)),'>');a<this.d.length-1&&(b.a+=She,b)}return (b.a+=']',b).a};_.a=0;_.c=0;_.f=0;var FX=mdb(Gqe,'ForsterConstraintResolver/ConstraintGroup',233);bcb(1797,1,qie,bFc);_.td=function cFc(a){OEc(this.a,BD(a,10),false)};var GX=mdb(Gqe,'ForsterConstraintResolver/lambda$0$Type',1797);bcb(214,1,{214:1,225:1},fFc);_.Nf=function hFc(a,b,c,d,e,f){};_.Of=function iFc(a,b){};_.Mf=function gFc(){this.r=KC(WD,oje,25,this.n,15,1)};_.Pf=function jFc(a,b,c){var d,e;e=c[a][b];d=e.e;!!d&&Ekb(this.b,d)};_.Qf=function kFc(a,b,c,d){++this.n};_.Ib=function lFc(){return wlb(this.e,new Tqb)};_.g=false;_.i=false;_.n=0;_.s=false;var IX=mdb(Gqe,'GraphInfoHolder',214);bcb(1832,1,Mne,pFc);_.Nf=function sFc(a,b,c,d,e,f){};_.Of=function tFc(a,b){};_.Qf=function vFc(a,b,c,d){};_._f=function qFc(a,b,c){c&&b>0?(RHc(this.a,a[b-1],a[b]),undefined):!c&&b<a.length-1?(RHc(this.a,a[b],a[b+1]),undefined):THc(this.a,a[b],c?(Ucd(),Tcd):(Ucd(),zcd));return mFc(this,a,b,c)};_.Mf=function rFc(){this.d=KC(WD,oje,25,this.c,15,1);this.a=new dIc(this.d)};_.Pf=function uFc(a,b,c){var d;d=c[a][b];this.c+=d.j.c.length};_.c=0;var JX=mdb(Gqe,'GreedyPortDistributor',1832);bcb(1401,1,Bqe,CFc);_.Yf=function DFc(a){return zFc(BD(a,37))};_.pf=function EFc(a,b){BFc(BD(a,37),b)};var xFc;var LX=mdb(Gqe,'InteractiveCrossingMinimizer',1401);bcb(1402,1,Dke,GFc);_.ue=function HFc(a,b){return FFc(this,BD(a,10),BD(b,10))};_.Fb=function IFc(a){return this===a};_.ve=function JFc(){return new tpb(this)};var KX=mdb(Gqe,'InteractiveCrossingMinimizer/1',1402);bcb(507,1,{507:1,123:1,51:1},fGc);_.Yf=function gGc(a){var b;return BD(a,37),b=k3c(KFc),e3c(b,(qUb(),nUb),(S8b(),H8b)),b};_.pf=function hGc(a,b){YFc(this,BD(a,37),b)};_.e=0;var KFc;var RX=mdb(Gqe,'LayerSweepCrossingMinimizer',507);bcb(1398,1,qie,iGc);_.td=function jGc(a){MFc(this.a,BD(a,214))};var MX=mdb(Gqe,'LayerSweepCrossingMinimizer/0methodref$compareDifferentRandomizedLayouts$Type',1398);bcb(1399,1,qie,kGc);_.td=function lGc(a){VFc(this.a,BD(a,214))};var NX=mdb(Gqe,'LayerSweepCrossingMinimizer/1methodref$minimizeCrossingsNoCounter$Type',1399);bcb(1400,1,qie,mGc);_.td=function nGc(a){XFc(this.a,BD(a,214))};var OX=mdb(Gqe,'LayerSweepCrossingMinimizer/2methodref$minimizeCrossingsWithCounter$Type',1400);bcb(454,22,{3:1,35:1,22:1,454:1},sGc);var oGc,pGc,qGc;var PX=ndb(Gqe,'LayerSweepCrossingMinimizer/CrossMinType',454,CI,uGc,tGc);var vGc;bcb(1397,1,Oie,xGc);_.Mb=function yGc(a){return LFc(),BD(a,29).a.c.length==0};var QX=mdb(Gqe,'LayerSweepCrossingMinimizer/lambda$0$Type',1397);bcb(1799,1,Mne,BGc);_.Mf=function CGc(){};_.Nf=function DGc(a,b,c,d,e,f){};_.Qf=function GGc(a,b,c,d){};_.Of=function EGc(a,b){b[a][0].c.p=a;this.b[a]=KC(SX,{3:1,4:1,5:1,1944:1},659,b[a].length,0,1)};_.Pf=function FGc(a,b,c){var d;d=c[a][b];d.p=b;NC(this.b[a],b,new HGc)};var VX=mdb(Gqe,'LayerSweepTypeDecider',1799);bcb(659,1,{659:1},HGc);_.Ib=function IGc(){return 'NodeInfo [connectedEdges='+this.a+', hierarchicalInfluence='+this.b+', randomInfluence='+this.c+']'};_.a=0;_.b=0;_.c=0;var SX=mdb(Gqe,'LayerSweepTypeDecider/NodeInfo',659);bcb(1800,1,Vke,JGc);_.Lb=function KGc(a){return a1b(new b1b(BD(a,11).b))};_.Fb=function LGc(a){return this===a};_.Mb=function MGc(a){return a1b(new b1b(BD(a,11).b))};var TX=mdb(Gqe,'LayerSweepTypeDecider/lambda$0$Type',1800);bcb(1801,1,Vke,NGc);_.Lb=function OGc(a){return a1b(new b1b(BD(a,11).b))};_.Fb=function PGc(a){return this===a};_.Mb=function QGc(a){return a1b(new b1b(BD(a,11).b))};var UX=mdb(Gqe,'LayerSweepTypeDecider/lambda$1$Type',1801);bcb(1833,402,Eqe,RGc);_.$f=function SGc(a,b,c){var d,e,f,g,h,i,j,k,l;j=this.g;switch(c.g){case 1:{d=0;e=0;for(i=new olb(a.j);i.a<i.c.c.length;){g=BD(mlb(i),11);if(g.e.c.length!=0){++d;g.j==(Ucd(),Acd)&&++e}}f=b+e;l=b+d;for(h=W_b(a,(KAc(),HAc)).Kc();h.Ob();){g=BD(h.Pb(),11);if(g.j==(Ucd(),Acd)){j[g.p]=f;--f}else{j[g.p]=l;--l}}return d}case 2:{k=0;for(h=W_b(a,(KAc(),IAc)).Kc();h.Ob();){g=BD(h.Pb(),11);++k;j[g.p]=b+k}return k}default:throw vbb(new Vdb);}};var WX=mdb(Gqe,'LayerTotalPortDistributor',1833);bcb(660,817,{660:1,225:1},XGc);_.ag=function ZGc(a,b,c,d){if(c){rEc(this,a)}else{oEc(this,a,d);pEc(this,a,b)}if(a.c.length>1){Ccb(DD(vNb(Q_b((tCb(0,a.c.length),BD(a.c[0],10))),(Nyc(),Awc))))?YGc(a,this.d,this):(mmb(),Okb(a,this.d));Ccb(DD(vNb(Q_b((tCb(0,a.c.length),BD(a.c[0],10))),Awc)))||PEc(this.e,a)}};var YX=mdb(Gqe,'ModelOrderBarycenterHeuristic',660);bcb(1803,1,Dke,$Gc);_.ue=function _Gc(a,b){return VGc(this.a,BD(a,10),BD(b,10))};_.Fb=function aHc(a){return this===a};_.ve=function bHc(){return new tpb(this)};var XX=mdb(Gqe,'ModelOrderBarycenterHeuristic/lambda$0$Type',1803);bcb(1403,1,Bqe,fHc);_.Yf=function gHc(a){var b;return BD(a,37),b=k3c(cHc),e3c(b,(qUb(),nUb),(S8b(),H8b)),b};_.pf=function hHc(a,b){eHc((BD(a,37),b))};var cHc;var ZX=mdb(Gqe,'NoCrossingMinimizer',1403);bcb(796,402,Eqe,iHc);_.$f=function jHc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n;l=this.g;switch(c.g){case 1:{e=0;f=0;for(k=new olb(a.j);k.a<k.c.c.length;){i=BD(mlb(k),11);if(i.e.c.length!=0){++e;i.j==(Ucd(),Acd)&&++f}}d=1/(e+1);g=b+f*d;n=b+1-d;for(j=W_b(a,(KAc(),HAc)).Kc();j.Ob();){i=BD(j.Pb(),11);if(i.j==(Ucd(),Acd)){l[i.p]=g;g-=d}else{l[i.p]=n;n-=d}}break}case 2:{h=0;for(k=new olb(a.j);k.a<k.c.c.length;){i=BD(mlb(k),11);i.g.c.length==0||++h}d=1/(h+1);m=b+d;for(j=W_b(a,(KAc(),IAc)).Kc();j.Ob();){i=BD(j.Pb(),11);l[i.p]=m;m+=d}break}default:throw vbb(new Wdb('Port type is undefined'));}return 1};var $X=mdb(Gqe,'NodeRelativePortDistributor',796);bcb(807,1,{},nHc,oHc);var _X=mdb(Gqe,'SweepCopy',807);bcb(1798,1,Mne,rHc);_.Of=function uHc(a,b){};_.Mf=function sHc(){var a;a=KC(WD,oje,25,this.f,15,1);this.d=new LIc(a);this.a=new dIc(a)};_.Nf=function tHc(a,b,c,d,e,f){var g;g=BD(Ikb(f[a][b].j,c),11);e.c==g&&e.c.i.c==e.d.i.c&&++this.e[a]};_.Pf=function vHc(a,b,c){var d;d=c[a][b];this.c[a]=this.c[a]|d.k==(j0b(),i0b)};_.Qf=function wHc(a,b,c,d){var e;e=BD(Ikb(d[a][b].j,c),11);e.p=this.f++;e.g.c.length+e.e.c.length>1&&(e.j==(Ucd(),zcd)?(this.b[a]=true):e.j==Tcd&&a>0&&(this.b[a-1]=true))};_.f=0;var aY=mdb(Lne,'AllCrossingsCounter',1798);bcb(587,1,{},BHc);_.b=0;_.d=0;var bY=mdb(Lne,'BinaryIndexedTree',587);bcb(524,1,{},dIc);var DHc,EHc;var lY=mdb(Lne,'CrossingsCounter',524);bcb(1906,1,Dke,hIc);_.ue=function iIc(a,b){return YHc(this.a,BD(a,11),BD(b,11))};_.Fb=function jIc(a){return this===a};_.ve=function kIc(){return new tpb(this)};var cY=mdb(Lne,'CrossingsCounter/lambda$0$Type',1906);bcb(1907,1,Dke,lIc);_.ue=function mIc(a,b){return ZHc(this.a,BD(a,11),BD(b,11))};_.Fb=function nIc(a){return this===a};_.ve=function oIc(){return new tpb(this)};var dY=mdb(Lne,'CrossingsCounter/lambda$1$Type',1907);bcb(1908,1,Dke,pIc);_.ue=function qIc(a,b){return $Hc(this.a,BD(a,11),BD(b,11))};_.Fb=function rIc(a){return this===a};_.ve=function sIc(){return new tpb(this)};var eY=mdb(Lne,'CrossingsCounter/lambda$2$Type',1908);bcb(1909,1,Dke,tIc);_.ue=function uIc(a,b){return _Hc(this.a,BD(a,11),BD(b,11))};_.Fb=function vIc(a){return this===a};_.ve=function wIc(){return new tpb(this)};var fY=mdb(Lne,'CrossingsCounter/lambda$3$Type',1909);bcb(1910,1,qie,xIc);_.td=function yIc(a){eIc(this.a,BD(a,11))};var gY=mdb(Lne,'CrossingsCounter/lambda$4$Type',1910);bcb(1911,1,Oie,zIc);_.Mb=function AIc(a){return fIc(this.a,BD(a,11))};var hY=mdb(Lne,'CrossingsCounter/lambda$5$Type',1911);bcb(1912,1,qie,CIc);_.td=function DIc(a){BIc(this,a)};var iY=mdb(Lne,'CrossingsCounter/lambda$6$Type',1912);bcb(1913,1,qie,EIc);_.td=function FIc(a){var b;FHc();Wjb(this.b,(b=this.a,BD(a,11),b))};var jY=mdb(Lne,'CrossingsCounter/lambda$7$Type',1913);bcb(826,1,Vke,GIc);_.Lb=function HIc(a){return FHc(),wNb(BD(a,11),(wtc(),gtc))};_.Fb=function IIc(a){return this===a};_.Mb=function JIc(a){return FHc(),wNb(BD(a,11),(wtc(),gtc))};var kY=mdb(Lne,'CrossingsCounter/lambda$8$Type',826);bcb(1905,1,{},LIc);var pY=mdb(Lne,'HyperedgeCrossingsCounter',1905);bcb(467,1,{35:1,467:1},NIc);_.wd=function OIc(a){return MIc(this,BD(a,467))};_.b=0;_.c=0;_.e=0;_.f=0;var oY=mdb(Lne,'HyperedgeCrossingsCounter/Hyperedge',467);bcb(362,1,{35:1,362:1},QIc);_.wd=function RIc(a){return PIc(this,BD(a,362))};_.b=0;_.c=0;var nY=mdb(Lne,'HyperedgeCrossingsCounter/HyperedgeCorner',362);bcb(523,22,{3:1,35:1,22:1,523:1},VIc);var SIc,TIc;var mY=ndb(Lne,'HyperedgeCrossingsCounter/HyperedgeCorner/Type',523,CI,XIc,WIc);var YIc;bcb(1405,1,Bqe,dJc);_.Yf=function eJc(a){return BD(vNb(BD(a,37),(wtc(),Ksc)),21).Hc((Orc(),Hrc))?_Ic:null};_.pf=function fJc(a,b){cJc(this,BD(a,37),b)};var _Ic;var rY=mdb(Hqe,'InteractiveNodePlacer',1405);bcb(1406,1,Bqe,tJc);_.Yf=function uJc(a){return BD(vNb(BD(a,37),(wtc(),Ksc)),21).Hc((Orc(),Hrc))?gJc:null};_.pf=function vJc(a,b){rJc(this,BD(a,37),b)};var gJc,hJc,iJc;var tY=mdb(Hqe,'LinearSegmentsNodePlacer',1406);bcb(257,1,{35:1,257:1},zJc);_.wd=function AJc(a){return wJc(this,BD(a,257))};_.Fb=function BJc(a){var b;if(JD(a,257)){b=BD(a,257);return this.b==b.b}return false};_.Hb=function CJc(){return this.b};_.Ib=function DJc(){return 'ls'+Fe(this.e)};_.a=0;_.b=0;_.c=-1;_.d=-1;_.g=0;var sY=mdb(Hqe,'LinearSegmentsNodePlacer/LinearSegment',257);bcb(1408,1,Bqe,$Jc);_.Yf=function _Jc(a){return BD(vNb(BD(a,37),(wtc(),Ksc)),21).Hc((Orc(),Hrc))?EJc:null};_.pf=function hKc(a,b){WJc(this,BD(a,37),b)};_.b=0;_.g=0;var EJc;var dZ=mdb(Hqe,'NetworkSimplexPlacer',1408);bcb(1427,1,Dke,iKc);_.ue=function jKc(a,b){return beb(BD(a,19).a,BD(b,19).a)};_.Fb=function kKc(a){return this===a};_.ve=function lKc(){return new tpb(this)};var uY=mdb(Hqe,'NetworkSimplexPlacer/0methodref$compare$Type',1427);bcb(1429,1,Dke,mKc);_.ue=function nKc(a,b){return beb(BD(a,19).a,BD(b,19).a)};_.Fb=function oKc(a){return this===a};_.ve=function pKc(){return new tpb(this)};var vY=mdb(Hqe,'NetworkSimplexPlacer/1methodref$compare$Type',1429);bcb(649,1,{649:1},qKc);var wY=mdb(Hqe,'NetworkSimplexPlacer/EdgeRep',649);bcb(401,1,{401:1},rKc);_.b=false;var xY=mdb(Hqe,'NetworkSimplexPlacer/NodeRep',401);bcb(508,12,{3:1,4:1,20:1,28:1,52:1,12:1,14:1,15:1,54:1,508:1},vKc);var CY=mdb(Hqe,'NetworkSimplexPlacer/Path',508);bcb(1409,1,{},wKc);_.Kb=function xKc(a){return BD(a,17).d.i.k};var yY=mdb(Hqe,'NetworkSimplexPlacer/Path/lambda$0$Type',1409);bcb(1410,1,Oie,yKc);_.Mb=function zKc(a){return BD(a,267)==(j0b(),g0b)};var zY=mdb(Hqe,'NetworkSimplexPlacer/Path/lambda$1$Type',1410);bcb(1411,1,{},AKc);_.Kb=function BKc(a){return BD(a,17).d.i};var AY=mdb(Hqe,'NetworkSimplexPlacer/Path/lambda$2$Type',1411);bcb(1412,1,Oie,CKc);_.Mb=function DKc(a){return eLc(Lzc(BD(a,10)))};var BY=mdb(Hqe,'NetworkSimplexPlacer/Path/lambda$3$Type',1412);bcb(1413,1,Oie,EKc);_.Mb=function FKc(a){return dKc(BD(a,11))};var DY=mdb(Hqe,'NetworkSimplexPlacer/lambda$0$Type',1413);bcb(1414,1,qie,GKc);_.td=function HKc(a){LJc(this.a,this.b,BD(a,11))};var EY=mdb(Hqe,'NetworkSimplexPlacer/lambda$1$Type',1414);bcb(1423,1,qie,IKc);_.td=function JKc(a){MJc(this.a,BD(a,17))};var FY=mdb(Hqe,'NetworkSimplexPlacer/lambda$10$Type',1423);bcb(1424,1,{},KKc);_.Kb=function LKc(a){return FJc(),new YAb(null,new Kub(BD(a,29).a,16))};var GY=mdb(Hqe,'NetworkSimplexPlacer/lambda$11$Type',1424);bcb(1425,1,qie,MKc);_.td=function NKc(a){NJc(this.a,BD(a,10))};var HY=mdb(Hqe,'NetworkSimplexPlacer/lambda$12$Type',1425);bcb(1426,1,{},OKc);_.Kb=function PKc(a){return FJc(),meb(BD(a,121).e)};var IY=mdb(Hqe,'NetworkSimplexPlacer/lambda$13$Type',1426);bcb(1428,1,{},QKc);_.Kb=function RKc(a){return FJc(),meb(BD(a,121).e)};var JY=mdb(Hqe,'NetworkSimplexPlacer/lambda$15$Type',1428);bcb(1430,1,Oie,SKc);_.Mb=function TKc(a){return FJc(),BD(a,401).c.k==(j0b(),h0b)};var KY=mdb(Hqe,'NetworkSimplexPlacer/lambda$17$Type',1430);bcb(1431,1,Oie,UKc);_.Mb=function VKc(a){return FJc(),BD(a,401).c.j.c.length>1};var LY=mdb(Hqe,'NetworkSimplexPlacer/lambda$18$Type',1431);bcb(1432,1,qie,WKc);_.td=function XKc(a){eKc(this.c,this.b,this.d,this.a,BD(a,401))};_.c=0;_.d=0;var MY=mdb(Hqe,'NetworkSimplexPlacer/lambda$19$Type',1432);bcb(1415,1,{},YKc);_.Kb=function ZKc(a){return FJc(),new YAb(null,new Kub(BD(a,29).a,16))};var NY=mdb(Hqe,'NetworkSimplexPlacer/lambda$2$Type',1415);bcb(1433,1,qie,$Kc);_.td=function _Kc(a){fKc(this.a,BD(a,11))};_.a=0;var OY=mdb(Hqe,'NetworkSimplexPlacer/lambda$20$Type',1433);bcb(1434,1,{},aLc);_.Kb=function bLc(a){return FJc(),new YAb(null,new Kub(BD(a,29).a,16))};var PY=mdb(Hqe,'NetworkSimplexPlacer/lambda$21$Type',1434);bcb(1435,1,qie,cLc);_.td=function dLc(a){OJc(this.a,BD(a,10))};var QY=mdb(Hqe,'NetworkSimplexPlacer/lambda$22$Type',1435);bcb(1436,1,Oie,fLc);_.Mb=function gLc(a){return eLc(a)};var RY=mdb(Hqe,'NetworkSimplexPlacer/lambda$23$Type',1436);bcb(1437,1,{},hLc);_.Kb=function iLc(a){return FJc(),new YAb(null,new Kub(BD(a,29).a,16))};var SY=mdb(Hqe,'NetworkSimplexPlacer/lambda$24$Type',1437);bcb(1438,1,Oie,jLc);_.Mb=function kLc(a){return PJc(this.a,BD(a,10))};var TY=mdb(Hqe,'NetworkSimplexPlacer/lambda$25$Type',1438);bcb(1439,1,qie,lLc);_.td=function mLc(a){QJc(this.a,this.b,BD(a,10))};var UY=mdb(Hqe,'NetworkSimplexPlacer/lambda$26$Type',1439);bcb(1440,1,Oie,nLc);_.Mb=function oLc(a){return FJc(),!OZb(BD(a,17))};var VY=mdb(Hqe,'NetworkSimplexPlacer/lambda$27$Type',1440);bcb(1441,1,Oie,pLc);_.Mb=function qLc(a){return FJc(),!OZb(BD(a,17))};var WY=mdb(Hqe,'NetworkSimplexPlacer/lambda$28$Type',1441);bcb(1442,1,{},rLc);_.Ce=function sLc(a,b){return RJc(this.a,BD(a,29),BD(b,29))};var XY=mdb(Hqe,'NetworkSimplexPlacer/lambda$29$Type',1442);bcb(1416,1,{},tLc);_.Kb=function uLc(a){return FJc(),new YAb(null,new Lub(new Sr(ur(U_b(BD(a,10)).a.Kc(),new Sq))))};var YY=mdb(Hqe,'NetworkSimplexPlacer/lambda$3$Type',1416);bcb(1417,1,Oie,vLc);_.Mb=function wLc(a){return FJc(),cKc(BD(a,17))};var ZY=mdb(Hqe,'NetworkSimplexPlacer/lambda$4$Type',1417);bcb(1418,1,qie,xLc);_.td=function yLc(a){XJc(this.a,BD(a,17))};var $Y=mdb(Hqe,'NetworkSimplexPlacer/lambda$5$Type',1418);bcb(1419,1,{},zLc);_.Kb=function ALc(a){return FJc(),new YAb(null,new Kub(BD(a,29).a,16))};var _Y=mdb(Hqe,'NetworkSimplexPlacer/lambda$6$Type',1419);bcb(1420,1,Oie,BLc);_.Mb=function CLc(a){return FJc(),BD(a,10).k==(j0b(),h0b)};var aZ=mdb(Hqe,'NetworkSimplexPlacer/lambda$7$Type',1420);bcb(1421,1,{},DLc);_.Kb=function ELc(a){return FJc(),new YAb(null,new Lub(new Sr(ur(O_b(BD(a,10)).a.Kc(),new Sq))))};var bZ=mdb(Hqe,'NetworkSimplexPlacer/lambda$8$Type',1421);bcb(1422,1,Oie,FLc);_.Mb=function GLc(a){return FJc(),NZb(BD(a,17))};var cZ=mdb(Hqe,'NetworkSimplexPlacer/lambda$9$Type',1422);bcb(1404,1,Bqe,KLc);_.Yf=function LLc(a){return BD(vNb(BD(a,37),(wtc(),Ksc)),21).Hc((Orc(),Hrc))?HLc:null};_.pf=function MLc(a,b){JLc(BD(a,37),b)};var HLc;var eZ=mdb(Hqe,'SimpleNodePlacer',1404);bcb(180,1,{180:1},ULc);_.Ib=function VLc(){var a;a='';this.c==(YLc(),XLc)?(a+=kle):this.c==WLc&&(a+=jle);this.o==(eMc(),cMc)?(a+=vle):this.o==dMc?(a+='UP'):(a+='BALANCED');return a};var hZ=mdb(Kqe,'BKAlignedLayout',180);bcb(516,22,{3:1,35:1,22:1,516:1},ZLc);var WLc,XLc;var fZ=ndb(Kqe,'BKAlignedLayout/HDirection',516,CI,_Lc,$Lc);var aMc;bcb(515,22,{3:1,35:1,22:1,515:1},fMc);var cMc,dMc;var gZ=ndb(Kqe,'BKAlignedLayout/VDirection',515,CI,hMc,gMc);var iMc;bcb(1634,1,{},mMc);var iZ=mdb(Kqe,'BKAligner',1634);bcb(1637,1,{},rMc);var lZ=mdb(Kqe,'BKCompactor',1637);bcb(654,1,{654:1},sMc);_.a=0;var jZ=mdb(Kqe,'BKCompactor/ClassEdge',654);bcb(458,1,{458:1},uMc);_.a=null;_.b=0;var kZ=mdb(Kqe,'BKCompactor/ClassNode',458);bcb(1407,1,Bqe,CMc);_.Yf=function GMc(a){return BD(vNb(BD(a,37),(wtc(),Ksc)),21).Hc((Orc(),Hrc))?vMc:null};_.pf=function HMc(a,b){BMc(this,BD(a,37),b)};_.d=false;var vMc;var mZ=mdb(Kqe,'BKNodePlacer',1407);bcb(1635,1,{},JMc);_.d=0;var oZ=mdb(Kqe,'NeighborhoodInformation',1635);bcb(1636,1,Dke,OMc);_.ue=function PMc(a,b){return NMc(this,BD(a,46),BD(b,46))};_.Fb=function QMc(a){return this===a};_.ve=function RMc(){return new tpb(this)};var nZ=mdb(Kqe,'NeighborhoodInformation/NeighborComparator',1636);bcb(808,1,{});var sZ=mdb(Kqe,'ThresholdStrategy',808);bcb(1763,808,{},WMc);_.bg=function XMc(a,b,c){return this.a.o==(eMc(),dMc)?Pje:Qje};_.cg=function YMc(){};var pZ=mdb(Kqe,'ThresholdStrategy/NullThresholdStrategy',1763);bcb(579,1,{579:1},ZMc);_.c=false;_.d=false;var qZ=mdb(Kqe,'ThresholdStrategy/Postprocessable',579);bcb(1764,808,{},bNc);_.bg=function cNc(a,b,c){var d,e,f;e=b==c;d=this.a.a[c.p]==b;if(!(e||d)){return a}f=a;if(this.a.c==(YLc(),XLc)){e&&(f=$Mc(this,b,true));!isNaN(f)&&!isFinite(f)&&d&&(f=$Mc(this,c,false))}else{e&&(f=$Mc(this,b,true));!isNaN(f)&&!isFinite(f)&&d&&(f=$Mc(this,c,false))}return f};_.cg=function dNc(){var a,b,c,d,e;while(this.d.b!=0){e=BD(Ksb(this.d),579);d=_Mc(this,e);if(!d.a){continue}a=d.a;c=Ccb(this.a.f[this.a.g[e.b.p].p]);if(!c&&!OZb(a)&&a.c.i.c==a.d.i.c){continue}b=aNc(this,e);b||swb(this.e,e)}while(this.e.a.c.length!=0){aNc(this,BD(rwb(this.e),579))}};var rZ=mdb(Kqe,'ThresholdStrategy/SimpleThresholdStrategy',1764);bcb(635,1,{635:1,246:1,234:1},hNc);_.Kf=function jNc(){return gNc(this)};_.Xf=function iNc(){return gNc(this)};var eNc;var tZ=mdb(Lqe,'EdgeRouterFactory',635);bcb(1458,1,Bqe,wNc);_.Yf=function xNc(a){return uNc(BD(a,37))};_.pf=function yNc(a,b){vNc(BD(a,37),b)};var lNc,mNc,nNc,oNc,pNc,qNc,rNc,sNc;var uZ=mdb(Lqe,'OrthogonalEdgeRouter',1458);bcb(1451,1,Bqe,NNc);_.Yf=function ONc(a){return INc(BD(a,37))};_.pf=function PNc(a,b){KNc(this,BD(a,37),b)};var zNc,ANc,BNc,CNc,DNc,ENc;var wZ=mdb(Lqe,'PolylineEdgeRouter',1451);bcb(1452,1,Vke,RNc);_.Lb=function SNc(a){return QNc(BD(a,10))};_.Fb=function TNc(a){return this===a};_.Mb=function UNc(a){return QNc(BD(a,10))};var vZ=mdb(Lqe,'PolylineEdgeRouter/1',1452);bcb(1809,1,Oie,ZNc);_.Mb=function $Nc(a){return BD(a,129).c==(HOc(),FOc)};var xZ=mdb(Mqe,'HyperEdgeCycleDetector/lambda$0$Type',1809);bcb(1810,1,{},_Nc);_.Ge=function aOc(a){return BD(a,129).d};var yZ=mdb(Mqe,'HyperEdgeCycleDetector/lambda$1$Type',1810);bcb(1811,1,Oie,bOc);_.Mb=function cOc(a){return BD(a,129).c==(HOc(),FOc)};var zZ=mdb(Mqe,'HyperEdgeCycleDetector/lambda$2$Type',1811);bcb(1812,1,{},dOc);_.Ge=function eOc(a){return BD(a,129).d};var AZ=mdb(Mqe,'HyperEdgeCycleDetector/lambda$3$Type',1812);bcb(1813,1,{},fOc);_.Ge=function gOc(a){return BD(a,129).d};var BZ=mdb(Mqe,'HyperEdgeCycleDetector/lambda$4$Type',1813);bcb(1814,1,{},hOc);_.Ge=function iOc(a){return BD(a,129).d};var CZ=mdb(Mqe,'HyperEdgeCycleDetector/lambda$5$Type',1814);bcb(112,1,{35:1,112:1},uOc);_.wd=function vOc(a){return kOc(this,BD(a,112))};_.Fb=function wOc(a){var b;if(JD(a,112)){b=BD(a,112);return this.g==b.g}return false};_.Hb=function xOc(){return this.g};_.Ib=function zOc(){var a,b,c,d;a=new Wfb('{');d=new olb(this.n);while(d.a<d.c.c.length){c=BD(mlb(d),11);b=P_b(c.i);b==null&&(b='n'+S_b(c.i));a.a+=''+b;d.a<d.c.c.length&&(a.a+=',',a)}a.a+='}';return a.a};_.a=0;_.b=0;_.c=NaN;_.d=0;_.g=0;_.i=0;_.o=0;_.s=NaN;var NZ=mdb(Mqe,'HyperEdgeSegment',112);bcb(129,1,{129:1},DOc);_.Ib=function EOc(){return this.a+'->'+this.b+' ('+Yr(this.c)+')'};_.d=0;var EZ=mdb(Mqe,'HyperEdgeSegmentDependency',129);bcb(520,22,{3:1,35:1,22:1,520:1},IOc);var FOc,GOc;var DZ=ndb(Mqe,'HyperEdgeSegmentDependency/DependencyType',520,CI,KOc,JOc);var LOc;bcb(1815,1,{},ZOc);var MZ=mdb(Mqe,'HyperEdgeSegmentSplitter',1815);bcb(1816,1,{},aPc);_.a=0;_.b=0;var FZ=mdb(Mqe,'HyperEdgeSegmentSplitter/AreaRating',1816);bcb(329,1,{329:1},bPc);_.a=0;_.b=0;_.c=0;var GZ=mdb(Mqe,'HyperEdgeSegmentSplitter/FreeArea',329);bcb(1817,1,Dke,cPc);_.ue=function dPc(a,b){return _Oc(BD(a,112),BD(b,112))};_.Fb=function ePc(a){return this===a};_.ve=function fPc(){return new tpb(this)};var HZ=mdb(Mqe,'HyperEdgeSegmentSplitter/lambda$0$Type',1817);bcb(1818,1,qie,gPc);_.td=function hPc(a){TOc(this.a,this.d,this.c,this.b,BD(a,112))};_.b=0;var IZ=mdb(Mqe,'HyperEdgeSegmentSplitter/lambda$1$Type',1818);bcb(1819,1,{},iPc);_.Kb=function jPc(a){return new YAb(null,new Kub(BD(a,112).e,16))};var JZ=mdb(Mqe,'HyperEdgeSegmentSplitter/lambda$2$Type',1819);bcb(1820,1,{},kPc);_.Kb=function lPc(a){return new YAb(null,new Kub(BD(a,112).j,16))};var KZ=mdb(Mqe,'HyperEdgeSegmentSplitter/lambda$3$Type',1820);bcb(1821,1,{},mPc);_.Fe=function nPc(a){return Edb(ED(a))};var LZ=mdb(Mqe,'HyperEdgeSegmentSplitter/lambda$4$Type',1821);bcb(655,1,{},tPc);_.a=0;_.b=0;_.c=0;var QZ=mdb(Mqe,'OrthogonalRoutingGenerator',655);bcb(1638,1,{},xPc);_.Kb=function yPc(a){return new YAb(null,new Kub(BD(a,112).e,16))};var OZ=mdb(Mqe,'OrthogonalRoutingGenerator/lambda$0$Type',1638);bcb(1639,1,{},zPc);_.Kb=function APc(a){return new YAb(null,new Kub(BD(a,112).j,16))};var PZ=mdb(Mqe,'OrthogonalRoutingGenerator/lambda$1$Type',1639);bcb(661,1,{});var RZ=mdb(Nqe,'BaseRoutingDirectionStrategy',661);bcb(1807,661,{},EPc);_.dg=function FPc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;if(!!a.r&&!a.q){return}k=b+a.o*c;for(j=new olb(a.n);j.a<j.c.c.length;){i=BD(mlb(j),11);l=l7c(OC(GC(m1,1),nie,8,0,[i.i.n,i.n,i.a])).a;for(h=new olb(i.g);h.a<h.c.c.length;){g=BD(mlb(h),17);if(!OZb(g)){o=g.d;p=l7c(OC(GC(m1,1),nie,8,0,[o.i.n,o.n,o.a])).a;if($wnd.Math.abs(l-p)>qme){f=k;e=a;d=new f7c(l,f);Dsb(g.a,d);BPc(this,g,e,d,false);m=a.r;if(m){n=Edb(ED(Ut(m.e,0)));d=new f7c(n,f);Dsb(g.a,d);BPc(this,g,e,d,false);f=b+m.o*c;e=m;d=new f7c(n,f);Dsb(g.a,d);BPc(this,g,e,d,false)}d=new f7c(p,f);Dsb(g.a,d);BPc(this,g,e,d,false)}}}}};_.eg=function GPc(a){return a.i.n.a+a.n.a+a.a.a};_.fg=function HPc(){return Ucd(),Rcd};_.gg=function IPc(){return Ucd(),Acd};var SZ=mdb(Nqe,'NorthToSouthRoutingStrategy',1807);bcb(1808,661,{},JPc);_.dg=function KPc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;if(!!a.r&&!a.q){return}k=b-a.o*c;for(j=new olb(a.n);j.a<j.c.c.length;){i=BD(mlb(j),11);l=l7c(OC(GC(m1,1),nie,8,0,[i.i.n,i.n,i.a])).a;for(h=new olb(i.g);h.a<h.c.c.length;){g=BD(mlb(h),17);if(!OZb(g)){o=g.d;p=l7c(OC(GC(m1,1),nie,8,0,[o.i.n,o.n,o.a])).a;if($wnd.Math.abs(l-p)>qme){f=k;e=a;d=new f7c(l,f);Dsb(g.a,d);BPc(this,g,e,d,false);m=a.r;if(m){n=Edb(ED(Ut(m.e,0)));d=new f7c(n,f);Dsb(g.a,d);BPc(this,g,e,d,false);f=b-m.o*c;e=m;d=new f7c(n,f);Dsb(g.a,d);BPc(this,g,e,d,false)}d=new f7c(p,f);Dsb(g.a,d);BPc(this,g,e,d,false)}}}}};_.eg=function LPc(a){return a.i.n.a+a.n.a+a.a.a};_.fg=function MPc(){return Ucd(),Acd};_.gg=function NPc(){return Ucd(),Rcd};var TZ=mdb(Nqe,'SouthToNorthRoutingStrategy',1808);bcb(1806,661,{},OPc);_.dg=function PPc(a,b,c){var d,e,f,g,h,i,j,k,l,m,n,o,p;if(!!a.r&&!a.q){return}k=b+a.o*c;for(j=new olb(a.n);j.a<j.c.c.length;){i=BD(mlb(j),11);l=l7c(OC(GC(m1,1),nie,8,0,[i.i.n,i.n,i.a])).b;for(h=new olb(i.g);h.a<h.c.c.length;){g=BD(mlb(h),17);if(!OZb(g)){o=g.d;p=l7c(OC(GC(m1,1),nie,8,0,[o.i.n,o.n,o.a])).b;if($wnd.Math.abs(l-p)>qme){f=k;e=a;d=new f7c(f,l);Dsb(g.a,d);BPc(this,g,e,d,true);m=a.r;if(m){n=Edb(ED(Ut(m.e,0)));d=new f7c(f,n);Dsb(g.a,d);BPc(this,g,e,d,true);f=b+m.o*c;e=m;d=new f7c(f,n);Dsb(g.a,d);BPc(this,g,e,d,true)}d=new f7c(f,p);Dsb(g.a,d);BPc(this,g,e,d,true)}}}}};_.eg=function QPc(a){return a.i.n.b+a.n.b+a.a.b};_.fg=function RPc(){return Ucd(),zcd};_.gg=function SPc(){return Ucd(),Tcd};var UZ=mdb(Nqe,'WestToEastRoutingStrategy',1806);bcb(813,1,{},YPc);_.Ib=function ZPc(){return Fe(this.a)};_.b=0;_.c=false;_.d=false;_.f=0;var WZ=mdb(Pqe,'NubSpline',813);bcb(407,1,{407:1},aQc,bQc);var VZ=mdb(Pqe,'NubSpline/PolarCP',407);bcb(1453,1,Bqe,vQc);_.Yf=function xQc(a){return qQc(BD(a,37))};_.pf=function yQc(a,b){uQc(this,BD(a,37),b)};var cQc,dQc,eQc,fQc,gQc;var b$=mdb(Pqe,'SplineEdgeRouter',1453);bcb(268,1,{268:1},BQc);_.Ib=function CQc(){return this.a+' ->('+this.c+') '+this.b};_.c=0;var XZ=mdb(Pqe,'SplineEdgeRouter/Dependency',268);bcb(455,22,{3:1,35:1,22:1,455:1},GQc);var DQc,EQc;var YZ=ndb(Pqe,'SplineEdgeRouter/SideToProcess',455,CI,IQc,HQc);var JQc;bcb(1454,1,Oie,LQc);_.Mb=function MQc(a){return hQc(),!BD(a,128).o};var ZZ=mdb(Pqe,'SplineEdgeRouter/lambda$0$Type',1454);bcb(1455,1,{},NQc);_.Ge=function OQc(a){return hQc(),BD(a,128).v+1};var $Z=mdb(Pqe,'SplineEdgeRouter/lambda$1$Type',1455);bcb(1456,1,qie,PQc);_.td=function QQc(a){sQc(this.a,this.b,BD(a,46))};var _Z=mdb(Pqe,'SplineEdgeRouter/lambda$2$Type',1456);bcb(1457,1,qie,RQc);_.td=function SQc(a){tQc(this.a,this.b,BD(a,46))};var a$=mdb(Pqe,'SplineEdgeRouter/lambda$3$Type',1457);bcb(128,1,{35:1,128:1},YQc,ZQc);_.wd=function $Qc(a){return WQc(this,BD(a,128))};_.b=0;_.e=false;_.f=0;_.g=0;_.j=false;_.k=false;_.n=0;_.o=false;_.p=false;_.q=false;_.s=0;_.u=0;_.v=0;_.F=0;var d$=mdb(Pqe,'SplineSegment',128);bcb(459,1,{459:1},_Qc);_.a=0;_.b=false;_.c=false;_.d=false;_.e=false;_.f=0;var c$=mdb(Pqe,'SplineSegment/EdgeInformation',459);bcb(1234,1,{},hRc);var f$=mdb(Uqe,hme,1234);bcb(1235,1,Dke,jRc);_.ue=function kRc(a,b){return iRc(BD(a,135),BD(b,135))};_.Fb=function lRc(a){return this===a};_.ve=function mRc(){return new tpb(this)};var e$=mdb(Uqe,ime,1235);bcb(1233,1,{},tRc);var g$=mdb(Uqe,'MrTree',1233);bcb(393,22,{3:1,35:1,22:1,393:1,246:1,234:1},ARc);_.Kf=function CRc(){return zRc(this)};_.Xf=function BRc(){return zRc(this)};var uRc,vRc,wRc,xRc;var h$=ndb(Uqe,'TreeLayoutPhases',393,CI,ERc,DRc);var FRc;bcb(1130,209,Mle,HRc);_.Ze=function IRc(a,b){var c,d,e,f,g,h,i;Ccb(DD(hkd(a,(JTc(),ATc))))||$Cb((c=new _Cb((Pgd(),new bhd(a))),c));g=(h=new SRc,tNb(h,a),yNb(h,(mTc(),dTc),a),i=new Lqb,pRc(a,h,i),oRc(a,h,i),h);f=gRc(this.a,g);for(e=new olb(f);e.a<e.c.c.length;){d=BD(mlb(e),135);rRc(this.b,d,Udd(b,1/f.c.length))}g=fRc(f);nRc(g)};var i$=mdb(Uqe,'TreeLayoutProvider',1130);bcb(1847,1,vie,KRc);_.Jc=function LRc(a){reb(this,a)};_.Kc=function MRc(){return mmb(),Emb(),Dmb};var j$=mdb(Uqe,'TreeUtil/1',1847);bcb(1848,1,vie,NRc);_.Jc=function ORc(a){reb(this,a)};_.Kc=function PRc(){return mmb(),Emb(),Dmb};var k$=mdb(Uqe,'TreeUtil/2',1848);bcb(502,134,{3:1,502:1,94:1,134:1});_.g=0;var m$=mdb(Vqe,'TGraphElement',502);bcb(188,502,{3:1,188:1,502:1,94:1,134:1},QRc);_.Ib=function RRc(){return !!this.b&&!!this.c?WRc(this.b)+'->'+WRc(this.c):'e_'+tb(this)};var l$=mdb(Vqe,'TEdge',188);bcb(135,134,{3:1,135:1,94:1,134:1},SRc);_.Ib=function TRc(){var a,b,c,d,e;e=null;for(d=Jsb(this.b,0);d.b!=d.d.c;){c=BD(Xsb(d),86);e+=(c.c==null||c.c.length==0?'n_'+c.g:'n_'+c.c)+'\n'}for(b=Jsb(this.a,0);b.b!=b.d.c;){a=BD(Xsb(b),188);e+=(!!a.b&&!!a.c?WRc(a.b)+'->'+WRc(a.c):'e_'+tb(a))+'\n'}return e};var n$=mdb(Vqe,'TGraph',135);bcb(633,502,{3:1,502:1,633:1,94:1,134:1});var r$=mdb(Vqe,'TShape',633);bcb(86,633,{3:1,502:1,86:1,633:1,94:1,134:1},XRc);_.Ib=function YRc(){return WRc(this)};var q$=mdb(Vqe,'TNode',86);bcb(255,1,vie,ZRc);_.Jc=function $Rc(a){reb(this,a)};_.Kc=function _Rc(){var a;return a=Jsb(this.a.d,0),new aSc(a)};var p$=mdb(Vqe,'TNode/2',255);bcb(358,1,aie,aSc);_.Nb=function bSc(a){Rrb(this,a)};_.Pb=function dSc(){return BD(Xsb(this.a),188).c};_.Ob=function cSc(){return Wsb(this.a)};_.Qb=function eSc(){Zsb(this.a)};var o$=mdb(Vqe,'TNode/2/1',358);bcb(1840,1,ene,hSc);_.pf=function jSc(a,b){gSc(this,BD(a,135),b)};var s$=mdb(Wqe,'FanProcessor',1840);bcb(327,22,{3:1,35:1,22:1,327:1,234:1},rSc);_.Kf=function sSc(){switch(this.g){case 0:return new QSc;case 1:return new hSc;case 2:return new GSc;case 3:return new zSc;case 4:return new NSc;case 5:return new TSc;default:throw vbb(new Wdb(Dne+(this.f!=null?this.f:''+this.g)));}};var kSc,lSc,mSc,nSc,oSc,pSc;var t$=ndb(Wqe,Ene,327,CI,uSc,tSc);var vSc;bcb(1843,1,ene,zSc);_.pf=function ASc(a,b){xSc(this,BD(a,135),b)};_.a=0;var v$=mdb(Wqe,'LevelHeightProcessor',1843);bcb(1844,1,vie,BSc);_.Jc=function CSc(a){reb(this,a)};_.Kc=function DSc(){return mmb(),Emb(),Dmb};var u$=mdb(Wqe,'LevelHeightProcessor/1',1844);bcb(1841,1,ene,GSc);_.pf=function HSc(a,b){ESc(this,BD(a,135),b)};_.a=0;var x$=mdb(Wqe,'NeighborsProcessor',1841);bcb(1842,1,vie,ISc);_.Jc=function JSc(a){reb(this,a)};_.Kc=function KSc(){return mmb(),Emb(),Dmb};var w$=mdb(Wqe,'NeighborsProcessor/1',1842);bcb(1845,1,ene,NSc);_.pf=function OSc(a,b){LSc(this,BD(a,135),b)};_.a=0;var y$=mdb(Wqe,'NodePositionProcessor',1845);bcb(1839,1,ene,QSc);_.pf=function RSc(a,b){PSc(this,BD(a,135))};var z$=mdb(Wqe,'RootProcessor',1839);bcb(1846,1,ene,TSc);_.pf=function USc(a,b){SSc(BD(a,135))};var A$=mdb(Wqe,'Untreeifyer',1846);var VSc,WSc,XSc,YSc,ZSc,$Sc,_Sc,aTc,bTc,cTc,dTc,eTc,fTc,gTc,hTc,iTc,jTc,kTc,lTc;bcb(851,1,ale,sTc);_.Qe=function tTc(a){t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Zqe),''),'Weighting of Nodes'),'Which weighting to use when computing a node order.'),qTc),(_5c(),V5c)),E$),pqb((N5c(),L5c)))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,$qe),''),'Search Order'),'Which search order to use when computing a spanning tree.'),oTc),V5c),F$),pqb(L5c))));KTc((new LTc,a))};var nTc,oTc,pTc,qTc;var B$=mdb(_qe,'MrTreeMetaDataProvider',851);bcb(994,1,ale,LTc);_.Qe=function MTc(a){KTc(a)};var uTc,vTc,wTc,xTc,yTc,zTc,ATc,BTc,CTc,DTc,ETc,FTc,GTc,HTc,ITc;var D$=mdb(_qe,'MrTreeOptions',994);bcb(995,1,{},NTc);_.$e=function OTc(){var a;return a=new HRc,a};_._e=function PTc(a){};var C$=mdb(_qe,'MrTreeOptions/MrtreeFactory',995);bcb(480,22,{3:1,35:1,22:1,480:1},TTc);var QTc,RTc;var E$=ndb(_qe,'OrderWeighting',480,CI,VTc,UTc);var WTc;bcb(425,22,{3:1,35:1,22:1,425:1},_Tc);var YTc,ZTc;var F$=ndb(_qe,'TreeifyingOrder',425,CI,bUc,aUc);var cUc;bcb(1459,1,Bqe,lUc);_.Yf=function mUc(a){return BD(a,135),eUc};_.pf=function nUc(a,b){kUc(this,BD(a,135),b)};var eUc;var G$=mdb('org.eclipse.elk.alg.mrtree.p1treeify','DFSTreeifyer',1459);bcb(1460,1,Bqe,sUc);_.Yf=function tUc(a){return BD(a,135),oUc};_.pf=function uUc(a,b){rUc(this,BD(a,135),b)};var oUc;var H$=mdb('org.eclipse.elk.alg.mrtree.p2order','NodeOrderer',1460);bcb(1461,1,Bqe,CUc);_.Yf=function DUc(a){return BD(a,135),vUc};_.pf=function EUc(a,b){AUc(this,BD(a,135),b)};_.a=0;var vUc;var I$=mdb('org.eclipse.elk.alg.mrtree.p3place','NodePlacer',1461);bcb(1462,1,Bqe,IUc);_.Yf=function JUc(a){return BD(a,135),FUc};_.pf=function KUc(a,b){HUc(BD(a,135),b)};var FUc;var J$=mdb('org.eclipse.elk.alg.mrtree.p4route','EdgeRouter',1462);var LUc;bcb(495,22,{3:1,35:1,22:1,495:1,246:1,234:1},RUc);_.Kf=function TUc(){return QUc(this)};_.Xf=function SUc(){return QUc(this)};var NUc,OUc;var K$=ndb(cre,'RadialLayoutPhases',495,CI,VUc,UUc);var WUc;bcb(1131,209,Mle,ZUc);_.Ze=function $Uc(a,b){var c,d,e,f,g,h;c=YUc(this,a);Odd(b,'Radial layout',c.c.length);Ccb(DD(hkd(a,(ZWc(),QWc))))||$Cb((d=new _Cb((Pgd(),new bhd(a))),d));h=aVc(a);jkd(a,(MUc(),LUc),h);if(!h){throw vbb(new Wdb('The given graph is not a tree!'))}e=Edb(ED(hkd(a,VWc)));e==0&&(e=_Uc(a));jkd(a,VWc,e);for(g=new olb(YUc(this,a));g.a<g.c.c.length;){f=BD(mlb(g),51);f.pf(a,Udd(b,1))}Qdd(b)};var L$=mdb(cre,'RadialLayoutProvider',1131);bcb(549,1,Dke,jVc);_.ue=function kVc(a,b){return iVc(this.a,this.b,BD(a,33),BD(b,33))};_.Fb=function lVc(a){return this===a};_.ve=function mVc(){return new tpb(this)};_.a=0;_.b=0;var M$=mdb(cre,'RadialUtil/lambda$0$Type',549);bcb(1375,1,ene,oVc);_.pf=function pVc(a,b){nVc(BD(a,33),b)};var N$=mdb(fre,'CalculateGraphSize',1375);bcb(442,22,{3:1,35:1,22:1,442:1,234:1},uVc);_.Kf=function vVc(){switch(this.g){case 0:return new bWc;case 1:return new NVc;case 2:return new oVc;default:throw vbb(new Wdb(Dne+(this.f!=null?this.f:''+this.g)));}};var qVc,rVc,sVc;var O$=ndb(fre,Ene,442,CI,xVc,wVc);var yVc;bcb(645,1,{});_.e=1;_.g=0;var P$=mdb(gre,'AbstractRadiusExtensionCompaction',645);bcb(1772,645,{},KVc);_.hg=function LVc(a){var b,c,d,e,f,g,h,i,j;this.c=BD(hkd(a,(MUc(),LUc)),33);EVc(this,this.c);this.d=tXc(BD(hkd(a,(ZWc(),WWc)),293));i=BD(hkd(a,KWc),19);!!i&&DVc(this,i.a);h=ED(hkd(a,(Y9c(),T9c)));FVc(this,(uCb(h),h));j=gVc(this.c);!!this.d&&this.d.lg(j);GVc(this,j);g=new amb(OC(GC(E2,1),hre,33,0,[this.c]));for(c=0;c<2;c++){for(b=0;b<j.c.length;b++){e=new amb(OC(GC(E2,1),hre,33,0,[(tCb(b,j.c.length),BD(j.c[b],33))]));f=b<j.c.length-1?(tCb(b+1,j.c.length),BD(j.c[b+1],33)):(tCb(0,j.c.length),BD(j.c[0],33));d=b==0?BD(Ikb(j,j.c.length-1),33):(tCb(b-1,j.c.length),BD(j.c[b-1],33));IVc(this,(tCb(b,j.c.length),BD(j.c[b],33),g),d,f,e)}}};var Q$=mdb(gre,'AnnulusWedgeCompaction',1772);bcb(1374,1,ene,NVc);_.pf=function OVc(a,b){MVc(BD(a,33),b)};var R$=mdb(gre,'GeneralCompactor',1374);bcb(1771,645,{},SVc);_.hg=function TVc(a){var b,c,d,e;c=BD(hkd(a,(MUc(),LUc)),33);this.f=c;this.b=tXc(BD(hkd(a,(ZWc(),WWc)),293));e=BD(hkd(a,KWc),19);!!e&&DVc(this,e.a);d=ED(hkd(a,(Y9c(),T9c)));FVc(this,(uCb(d),d));b=gVc(c);!!this.b&&this.b.lg(b);QVc(this,b)};_.a=0;var S$=mdb(gre,'RadialCompaction',1771);bcb(1779,1,{},VVc);_.ig=function WVc(a){var b,c,d,e,f,g;this.a=a;b=0;g=gVc(a);d=0;for(f=new olb(g);f.a<f.c.c.length;){e=BD(mlb(f),33);++d;for(c=d;c<g.c.length;c++){UVc(this,e,(tCb(c,g.c.length),BD(g.c[c],33)))&&(b+=1)}}return b};var T$=mdb(ire,'CrossingMinimizationPosition',1779);bcb(1777,1,{},XVc);_.ig=function YVc(a){var b,c,d,e,f,g,h,i,j,k,l,m,n;d=0;for(c=new Sr(ur(_sd(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),79);h=atd(BD(qud((!b.c&&(b.c=new y5d(z2,b,5,8)),b.c),0),82));j=h.i+h.g/2;k=h.j+h.f/2;e=a.i+a.g/2;f=a.j+a.f/2;l=new d7c;l.a=j-e;l.b=k-f;g=new f7c(l.a,l.b);l6c(g,a.g,a.f);l.a-=g.a;l.b-=g.b;e=j-l.a;f=k-l.b;i=new f7c(l.a,l.b);l6c(i,h.g,h.f);l.a-=i.a;l.b-=i.b;j=e+l.a;k=f+l.b;m=j-e;n=k-f;d+=$wnd.Math.sqrt(m*m+n*n)}return d};var U$=mdb(ire,'EdgeLengthOptimization',1777);bcb(1778,1,{},ZVc);_.ig=function $Vc(a){var b,c,d,e,f,g,h,i,j,k,l;d=0;for(c=new Sr(ur(_sd(a).a.Kc(),new Sq));Qr(c);){b=BD(Rr(c),79);h=atd(BD(qud((!b.c&&(b.c=new y5d(z2,b,5,8)),b.c),0),82));i=h.i+h.g/2;j=h.j+h.f/2;e=BD(hkd(h,(Y9c(),C9c)),8);f=a.i+e.a+a.g/2;g=a.j+e.b+a.f;k=i-f;l=j-g;d+=$wnd.Math.sqrt(k*k+l*l)}return d};var V$=mdb(ire,'EdgeLengthPositionOptimization',1778);bcb(1373,645,ene,bWc);_.pf=function cWc(a,b){aWc(this,BD(a,33),b)};var W$=mdb('org.eclipse.elk.alg.radial.intermediate.overlaps','RadiusExtensionOverlapRemoval',1373);bcb(426,22,{3:1,35:1,22:1,426:1},hWc);var dWc,eWc;var X$=ndb(kre,'AnnulusWedgeCriteria',426,CI,jWc,iWc);var kWc;bcb(380,22,{3:1,35:1,22:1,380:1},rWc);var mWc,nWc,oWc;var Y$=ndb(kre,Sle,380,CI,tWc,sWc);var uWc;bcb(852,1,ale,IWc);_.Qe=function JWc(a){t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,lre),''),'Order ID'),'The id can be used to define an order for nodes of one radius. This can be used to sort them in the layer accordingly.'),meb(0)),(_5c(),X5c)),JI),pqb((N5c(),K5c)))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,mre),''),'Radius'),'The radius option can be used to set the initial radius for the radial layouter.'),0),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,nre),''),'Compaction'),'With the compacter option it can be determined how compaction on the graph is done. It can be chosen between none, the radial compaction or the compaction of wedges separately.'),yWc),V5c),Y$),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,ore),''),'Compaction Step Size'),'Determine the size of steps with which the compaction is done. Step size 1 correlates to a compaction of 1 pixel per Iteration.'),meb(1)),X5c),JI),pqb(L5c))));o4c(a,ore,nre,null);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,pre),''),'Sorter'),'Sort the nodes per radius according to the sorting algorithm. The strategies are none, by the given order id, or sorting them by polar coordinates.'),EWc),V5c),b_),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,qre),''),'Annulus Wedge Criteria'),'Determine how the wedge for the node placement is calculated. It can be chosen between wedge determination by the number of leaves or by the maximum sum of diagonals.'),GWc),V5c),X$),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,rre),''),'Translation Optimization'),'Find the optimal translation of the nodes of the first radii according to this criteria. For example edge crossings can be minimized.'),AWc),V5c),a_),pqb(L5c))));$Wc((new _Wc,a))};var wWc,xWc,yWc,zWc,AWc,BWc,CWc,DWc,EWc,FWc,GWc;var Z$=mdb(kre,'RadialMetaDataProvider',852);bcb(996,1,ale,_Wc);_.Qe=function aXc(a){$Wc(a)};var KWc,LWc,MWc,NWc,OWc,PWc,QWc,RWc,SWc,TWc,UWc,VWc,WWc,XWc,YWc;var _$=mdb(kre,'RadialOptions',996);bcb(997,1,{},bXc);_.$e=function cXc(){var a;return a=new ZUc,a};_._e=function dXc(a){};var $$=mdb(kre,'RadialOptions/RadialFactory',997);bcb(340,22,{3:1,35:1,22:1,340:1},kXc);var eXc,fXc,gXc,hXc;var a_=ndb(kre,'RadialTranslationStrategy',340,CI,mXc,lXc);var nXc;bcb(293,22,{3:1,35:1,22:1,293:1},uXc);var pXc,qXc,rXc;var b_=ndb(kre,'SortingStrategy',293,CI,wXc,vXc);var xXc;bcb(1449,1,Bqe,CXc);_.Yf=function DXc(a){return BD(a,33),null};_.pf=function EXc(a,b){AXc(this,BD(a,33),b)};_.c=0;var c_=mdb('org.eclipse.elk.alg.radial.p1position','EadesRadial',1449);bcb(1775,1,{},FXc);_.jg=function GXc(a){return eVc(a)};var d_=mdb(tre,'AnnulusWedgeByLeafs',1775);bcb(1776,1,{},IXc);_.jg=function JXc(a){return HXc(this,a)};var e_=mdb(tre,'AnnulusWedgeByNodeSpace',1776);bcb(1450,1,Bqe,MXc);_.Yf=function NXc(a){return BD(a,33),null};_.pf=function OXc(a,b){KXc(this,BD(a,33),b)};var f_=mdb('org.eclipse.elk.alg.radial.p2routing','StraightLineEdgeRouter',1450);bcb(811,1,{},QXc);_.kg=function RXc(a){};_.lg=function TXc(a){PXc(this,a)};var h_=mdb(ure,'IDSorter',811);bcb(1774,1,Dke,UXc);_.ue=function VXc(a,b){return SXc(BD(a,33),BD(b,33))};_.Fb=function WXc(a){return this===a};_.ve=function XXc(){return new tpb(this)};var g_=mdb(ure,'IDSorter/lambda$0$Type',1774);bcb(1773,1,{},$Xc);_.kg=function _Xc(a){YXc(this,a)};_.lg=function aYc(a){var b;if(!a.dc()){if(!this.e){b=bVc(BD(a.Xb(0),33));YXc(this,b)}PXc(this.e,a)}};var i_=mdb(ure,'PolarCoordinateSorter',1773);bcb(1136,209,Mle,bYc);_.Ze=function eYc(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B,C,D,F;Odd(b,'Rectangle Packing',1);b.n&&b.n&&!!a&&Tdd(b,i6d(a),(pgd(),mgd));c=Edb(ED(hkd(a,(lZc(),RYc))));p=BD(hkd(a,eZc),381);s=Ccb(DD(hkd(a,ZYc)));w=Ccb(DD(hkd(a,dZc)));l=Ccb(DD(hkd(a,VYc)));A=BD(hkd(a,fZc),116);v=Edb(ED(hkd(a,jZc)));e=Ccb(DD(hkd(a,iZc)));m=Ccb(DD(hkd(a,WYc)));r=Ccb(DD(hkd(a,XYc)));F=Edb(ED(hkd(a,kZc)));C=(!a.a&&(a.a=new cUd(E2,a,10,11)),a.a);r$c(C);if(r){o=new Rkb;for(i=new Fyd(C);i.e!=i.i.gc();){g=BD(Dyd(i),33);ikd(g,UYc)&&(o.c[o.c.length]=g,true)}for(j=new olb(o);j.a<j.c.c.length;){g=BD(mlb(j),33);Ftd(C,g)}mmb();Okb(o,new fYc);for(k=new olb(o);k.a<k.c.c.length;){g=BD(mlb(k),33);B=BD(hkd(g,UYc),19).a;B=$wnd.Math.min(B,C.i);vtd(C,B,g)}q=0;for(h=new Fyd(C);h.e!=h.i.gc();){g=BD(Dyd(h),33);jkd(g,TYc,meb(q));++q}}u=rfd(a);u.a-=A.b+A.c;u.b-=A.d+A.a;t=u.a;if(F<0||F<u.a){n=new nYc(c,p,s);f=jYc(n,C,v,A);b.n&&b.n&&!!a&&Tdd(b,i6d(a),(pgd(),mgd))}else{f=new d$c(c,F,0,(k$c(),j$c))}u.a+=A.b+A.c;u.b+=A.d+A.a;if(!w){r$c(C);D=new DZc(c,l,m,e,v);t=$wnd.Math.max(u.a,f.c);f=CZc(D,C,t,u,b,a,A)}cYc(C,A);Afd(a,f.c+(A.b+A.c),f.b+(A.d+A.a),false,true);Ccb(DD(hkd(a,cZc)))||$Cb((d=new _Cb((Pgd(),new bhd(a))),d));b.n&&b.n&&!!a&&Tdd(b,i6d(a),(pgd(),mgd));Qdd(b)};var k_=mdb(yre,'RectPackingLayoutProvider',1136);bcb(1137,1,Dke,fYc);_.ue=function gYc(a,b){return dYc(BD(a,33),BD(b,33))};_.Fb=function hYc(a){return this===a};_.ve=function iYc(){return new tpb(this)};var j_=mdb(yre,'RectPackingLayoutProvider/lambda$0$Type',1137);bcb(1256,1,{},nYc);_.a=0;_.c=false;var l_=mdb(zre,'AreaApproximation',1256);var o_=odb(zre,'BestCandidateFilter');bcb(638,1,{526:1},oYc);_.mg=function pYc(a,b,c){var d,e,f,g,h,i;i=new Rkb;f=Pje;for(h=new olb(a);h.a<h.c.c.length;){g=BD(mlb(h),220);f=$wnd.Math.min(f,(g.c+(c.b+c.c))*(g.b+(c.d+c.a)))}for(e=new olb(a);e.a<e.c.c.length;){d=BD(mlb(e),220);(d.c+(c.b+c.c))*(d.b+(c.d+c.a))==f&&(i.c[i.c.length]=d,true)}return i};var m_=mdb(zre,'AreaFilter',638);bcb(639,1,{526:1},qYc);_.mg=function rYc(a,b,c){var d,e,f,g,h,i;h=new Rkb;i=Pje;for(g=new olb(a);g.a<g.c.c.length;){f=BD(mlb(g),220);i=$wnd.Math.min(i,$wnd.Math.abs((f.c+(c.b+c.c))/(f.b+(c.d+c.a))-b))}for(e=new olb(a);e.a<e.c.c.length;){d=BD(mlb(e),220);$wnd.Math.abs((d.c+(c.b+c.c))/(d.b+(c.d+c.a))-b)==i&&(h.c[h.c.length]=d,true)}return h};var n_=mdb(zre,'AspectRatioFilter',639);bcb(637,1,{526:1},uYc);_.mg=function vYc(a,b,c){var d,e,f,g,h,i;i=new Rkb;f=Qje;for(h=new olb(a);h.a<h.c.c.length;){g=BD(mlb(h),220);f=$wnd.Math.max(f,q$c(g.c+(c.b+c.c),g.b+(c.d+c.a),g.a))}for(e=new olb(a);e.a<e.c.c.length;){d=BD(mlb(e),220);q$c(d.c+(c.b+c.c),d.b+(c.d+c.a),d.a)==f&&(i.c[i.c.length]=d,true)}return i};var p_=mdb(zre,'ScaleMeasureFilter',637);bcb(381,22,{3:1,35:1,22:1,381:1},AYc);var wYc,xYc,yYc;var q_=ndb(Are,'OptimizationGoal',381,CI,CYc,BYc);var DYc;bcb(856,1,ale,PYc);_.Qe=function QYc(a){t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Bre),''),'Optimization Goal'),'Optimization goal for approximation of the bounding box given by the first iteration. Determines whether layout is sorted by the maximum scaling, aspect ratio, or area. Depending on the strategy the aspect ratio might be nearly ignored.'),LYc),(_5c(),V5c)),q_),pqb((N5c(),K5c)))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Cre),''),'Shift Last Placed.'),'When placing a rectangle behind or below the last placed rectangle in the first iteration, it is sometimes possible to shift the rectangle further to the left or right, resulting in less whitespace. True (default) enables the shift and false disables it. Disabling the shift produces a greater approximated area by the first iteration and a layout, when using ONLY the first iteration (default not the case), where it is sometimes impossible to implement a size transformation of rectangles that will fill the bounding box and eliminate empty spaces.'),(Bcb(),true)),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Dre),''),'Current position of a node in the order of nodes'),'The rectangles are ordered. Normally according to their definition the the model. This option specifies the current position of a node.'),meb(-1)),X5c),JI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ere),''),'Desired index of node'),'The rectangles are ordered. Normally according to their definition the the model. This option allows to specify a desired position that has preference over the original position.'),meb(-1)),X5c),JI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Fre),''),'Only Area Approximation'),'If enabled only the width approximation step is executed and the nodes are placed accordingly. The nodes are layouted according to the packingStrategy. If set to true not expansion of nodes is taking place.'),false),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Gre),''),'Compact Rows'),'Enables compaction. Compacts blocks if they do not use the full height of the row. This option allows to have a smaller drawing. If this option is disabled all nodes are placed next to each other in rows.'),true),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Hre),''),'Fit Aspect Ratio'),'Expands nodes if expandNodes is true to fit the aspect ratio instead of only in their bounds. The option is only useful if the used packingStrategy is ASPECT_RATIO_DRIVEN, otherwise this may result in unreasonable ndoe expansion.'),false),T5c),wI),pqb(K5c))));o4c(a,Hre,Jre,null);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ire),''),'Target Width'),'Option to place the rectangles in the given target width instead of approximating the width using the desired aspect ratio. The padding is not included in this. Meaning a drawing will have width of targetwidth + horizontal padding.'),-1),U5c),BI),pqb(K5c))));mZc((new nZc,a))};var FYc,GYc,HYc,IYc,JYc,KYc,LYc,MYc,NYc;var r_=mdb(Are,'RectPackingMetaDataProvider',856);bcb(1004,1,ale,nZc);_.Qe=function oZc(a){mZc(a)};var RYc,SYc,TYc,UYc,VYc,WYc,XYc,YYc,ZYc,$Yc,_Yc,aZc,bZc,cZc,dZc,eZc,fZc,gZc,hZc,iZc,jZc,kZc;var t_=mdb(Are,'RectPackingOptions',1004);bcb(1005,1,{},pZc);_.$e=function qZc(){var a;return a=new bYc,a};_._e=function rZc(a){};var s_=mdb(Are,'RectPackingOptions/RectpackingFactory',1005);bcb(1257,1,{},DZc);_.a=0;_.b=false;_.c=0;_.d=0;_.e=false;_.f=false;_.g=0;var u_=mdb('org.eclipse.elk.alg.rectpacking.seconditeration','RowFillingAndCompaction',1257);bcb(187,1,{187:1},PZc);_.a=0;_.c=false;_.d=0;_.e=0;_.f=0;_.g=0;_.i=0;_.k=false;_.o=Pje;_.p=Pje;_.r=0;_.s=0;_.t=0;var x_=mdb(Lre,'Block',187);bcb(211,1,{211:1},VZc);_.a=0;_.b=0;_.d=0;_.e=0;_.f=0;var v_=mdb(Lre,'BlockRow',211);bcb(443,1,{443:1},b$c);_.b=0;_.c=0;_.d=0;_.e=0;_.f=0;var w_=mdb(Lre,'BlockStack',443);bcb(220,1,{220:1},d$c,e$c);_.a=0;_.b=0;_.c=0;_.d=0;_.e=0;var z_=mdb(Lre,'DrawingData',220);bcb(355,22,{3:1,35:1,22:1,355:1},l$c);var f$c,g$c,h$c,i$c,j$c;var y_=ndb(Lre,'DrawingDataDescriptor',355,CI,n$c,m$c);var o$c;bcb(200,1,{200:1},x$c);_.b=0;_.c=0;_.e=0;_.f=0;var A_=mdb(Lre,'RectRow',200);bcb(756,1,{},F$c);_.j=0;var G_=mdb(Nre,une,756);bcb(1245,1,{},G$c);_.Je=function H$c(a){return S6c(a.a,a.b)};var B_=mdb(Nre,vne,1245);bcb(1246,1,{},I$c);_.Je=function J$c(a){return A$c(this.a,a)};var C_=mdb(Nre,wne,1246);bcb(1247,1,{},K$c);_.Je=function L$c(a){return B$c(this.a,a)};var D_=mdb(Nre,xne,1247);bcb(1248,1,{},M$c);_.Je=function N$c(a){return C$c(this.a,a)};var E_=mdb(Nre,'ElkGraphImporter/lambda$3$Type',1248);bcb(1249,1,{},O$c);_.Je=function P$c(a){return D$c(this.a,a)};var F_=mdb(Nre,yne,1249);bcb(1133,209,Mle,Q$c);_.Ze=function S$c(a,b){var c,d,e,f,g,h,i,j,k,l,m,n;if(ikd(a,(d0c(),c0c))){n=GD(hkd(a,(J0c(),I0c)));f=h4c(n4c(),n);if(f){g=BD(hgd(f.f),209);g.Ze(a,Udd(b,1))}}jkd(a,Z_c,(C_c(),A_c));jkd(a,$_c,(N_c(),K_c));jkd(a,__c,(a1c(),_0c));h=BD(hkd(a,(J0c(),E0c)),19).a;Odd(b,'Overlap removal',1);Ccb(DD(hkd(a,D0c)))&&'null45scanlineOverlaps';i=new Tqb;j=new U$c(i);d=new F$c;c=z$c(d,a);k=true;e=0;while(e<h&&k){if(Ccb(DD(hkd(a,F0c)))){i.a.$b();cOb(new dOb(j),c.i);if(i.a.gc()==0){break}c.e=i}H2c(this.b);K2c(this.b,(Y$c(),V$c),(R0c(),Q0c));K2c(this.b,W$c,c.g);K2c(this.b,X$c,(s_c(),r_c));this.a=F2c(this.b,c);for(m=new olb(this.a);m.a<m.c.c.length;){l=BD(mlb(m),51);l.pf(c,Udd(b,1))}E$c(d,c);k=Ccb(DD(vNb(c,(XNb(),WNb))));++e}y$c(d,c);Qdd(b)};var I_=mdb(Nre,'OverlapRemovalLayoutProvider',1133);bcb(1134,1,{},U$c);var H_=mdb(Nre,'OverlapRemovalLayoutProvider/lambda$0$Type',1134);bcb(437,22,{3:1,35:1,22:1,437:1},Z$c);var V$c,W$c,X$c;var J_=ndb(Nre,'SPOrEPhases',437,CI,_$c,$$c);var a_c;bcb(1255,1,{},d_c);var L_=mdb(Nre,'ShrinkTree',1255);bcb(1135,209,Mle,e_c);_.Ze=function f_c(a,b){var c,d,e,f,g;if(ikd(a,(d0c(),c0c))){g=GD(hkd(a,c0c));e=h4c(n4c(),g);if(e){f=BD(hgd(e.f),209);f.Ze(a,Udd(b,1))}}d=new F$c;c=z$c(d,a);c_c(this.a,c,Udd(b,1));y$c(d,c)};var K_=mdb(Nre,'ShrinkTreeLayoutProvider',1135);bcb(300,134,{3:1,300:1,94:1,134:1},g_c);_.c=false;var M_=mdb('org.eclipse.elk.alg.spore.graph','Graph',300);bcb(482,22,{3:1,35:1,22:1,482:1,246:1,234:1},k_c);_.Kf=function m_c(){return j_c(this)};_.Xf=function l_c(){return j_c(this)};var h_c;var N_=ndb(Ore,Sle,482,CI,o_c,n_c);var p_c;bcb(551,22,{3:1,35:1,22:1,551:1,246:1,234:1},t_c);_.Kf=function v_c(){return new I1c};_.Xf=function u_c(){return new I1c};var r_c;var O_=ndb(Ore,'OverlapRemovalStrategy',551,CI,x_c,w_c);var y_c;bcb(430,22,{3:1,35:1,22:1,430:1},D_c);var A_c,B_c;var P_=ndb(Ore,'RootSelection',430,CI,F_c,E_c);var G_c;bcb(316,22,{3:1,35:1,22:1,316:1},O_c);var I_c,J_c,K_c,L_c,M_c;var Q_=ndb(Ore,'SpanningTreeCostFunction',316,CI,Q_c,P_c);var R_c;bcb(1002,1,ale,f0c);_.Qe=function g0c(a){e0c(a)};var T_c,U_c,V_c,W_c,X_c,Y_c,Z_c,$_c,__c,a0c,b0c,c0c;var S_=mdb(Ore,'SporeCompactionOptions',1002);bcb(1003,1,{},h0c);_.$e=function i0c(){var a;return a=new e_c,a};_._e=function j0c(a){};var R_=mdb(Ore,'SporeCompactionOptions/SporeCompactionFactory',1003);bcb(855,1,ale,B0c);_.Qe=function C0c(a){t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Qre),''),'Underlying Layout Algorithm'),'A layout algorithm that is applied to the graph before it is compacted. If this is null, nothing is applied before compaction.'),(_5c(),Z5c)),ZI),pqb((N5c(),L5c)))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Vre),'structure'),'Structure Extraction Strategy'),'This option defines what kind of triangulation or other partitioning of the plane is applied to the vertices.'),y0c),V5c),W_),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Rre),$re),'Tree Construction Strategy'),'Whether a minimum spanning tree or a maximum spanning tree should be constructed.'),w0c),V5c),X_),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Sre),$re),'Cost Function for Spanning Tree'),'The cost function is used in the creation of the spanning tree.'),u0c),V5c),Q_),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Tre),$re),'Root node for spanning tree construction'),'The identifier of the node that is preferred as the root of the spanning tree. If this is null, the first node is chosen.'),null),Z5c),ZI),pqb(L5c))));o4c(a,Tre,Ure,q0c);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ure),$re),'Root selection for spanning tree'),'This sets the method used to select a root node for the construction of a spanning tree'),s0c),V5c),P_),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Wre),Bpe),'Compaction Strategy'),'This option defines how the compaction is applied.'),l0c),V5c),N_),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Xre),Bpe),'Orthogonal Compaction'),'Restricts the translation of nodes to orthogonal directions in the compaction phase.'),(Bcb(),false)),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Yre),_re),'Upper limit for iterations of overlap removal'),null),meb(64)),X5c),JI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Zre),_re),'Whether to run a supplementary scanline overlap check.'),null),true),T5c),wI),pqb(L5c))));K0c((new L0c,a));e0c((new f0c,a))};var k0c,l0c,m0c,n0c,o0c,p0c,q0c,r0c,s0c,t0c,u0c,v0c,w0c,x0c,y0c,z0c;var T_=mdb(Ore,'SporeMetaDataProvider',855);bcb(_ie,1,ale,L0c);_.Qe=function M0c(a){K0c(a)};var D0c,E0c,F0c,G0c,H0c,I0c;var V_=mdb(Ore,'SporeOverlapRemovalOptions',_ie);bcb(1001,1,{},N0c);_.$e=function O0c(){var a;return a=new Q$c,a};_._e=function P0c(a){};var U_=mdb(Ore,'SporeOverlapRemovalOptions/SporeOverlapFactory',1001);bcb(530,22,{3:1,35:1,22:1,530:1,246:1,234:1},T0c);_.Kf=function V0c(){return S0c(this)};_.Xf=function U0c(){return S0c(this)};var Q0c;var W_=ndb(Ore,'StructureExtractionStrategy',530,CI,X0c,W0c);var Y0c;bcb(429,22,{3:1,35:1,22:1,429:1,246:1,234:1},c1c);_.Kf=function e1c(){return b1c(this)};_.Xf=function d1c(){return b1c(this)};var $0c,_0c;var X_=ndb(Ore,'TreeConstructionStrategy',429,CI,g1c,f1c);var h1c;bcb(1443,1,Bqe,k1c);_.Yf=function l1c(a){return BD(a,300),new j3c};_.pf=function m1c(a,b){j1c(BD(a,300),b)};var Z_=mdb(bse,'DelaunayTriangulationPhase',1443);bcb(1444,1,qie,n1c);_.td=function o1c(a){Ekb(this.a,BD(a,65).a)};var Y_=mdb(bse,'DelaunayTriangulationPhase/lambda$0$Type',1444);bcb(783,1,Bqe,s1c);_.Yf=function t1c(a){return BD(a,300),new j3c};_.pf=function u1c(a,b){this.ng(BD(a,300),b)};_.ng=function v1c(a,b){var c,d,e;Odd(b,'Minimum spanning tree construction',1);a.d?(d=a.d.a):(d=BD(Ikb(a.i,0),65).a);Ccb(DD(vNb(a,(XNb(),VNb))))?(e=UCb(a.e,d,(c=a.b,c))):(e=UCb(a.e,d,a.b));q1c(this,e,a);Qdd(b)};var b0=mdb(cse,'MinSTPhase',783);bcb(1446,783,Bqe,w1c);_.ng=function y1c(a,b){var c,d,e,f;Odd(b,'Maximum spanning tree construction',1);c=new z1c(a);a.d?(e=a.d.c):(e=BD(Ikb(a.i,0),65).c);Ccb(DD(vNb(a,(XNb(),VNb))))?(f=UCb(a.e,e,(d=c,d))):(f=UCb(a.e,e,c));q1c(this,f,a);Qdd(b)};var __=mdb(cse,'MaxSTPhase',1446);bcb(1447,1,{},z1c);_.Je=function A1c(a){return x1c(this.a,a)};var $_=mdb(cse,'MaxSTPhase/lambda$0$Type',1447);bcb(1445,1,qie,B1c);_.td=function C1c(a){r1c(this.a,BD(a,65))};var a0=mdb(cse,'MinSTPhase/lambda$0$Type',1445);bcb(785,1,Bqe,I1c);_.Yf=function J1c(a){return BD(a,300),new j3c};_.pf=function K1c(a,b){H1c(this,BD(a,300),b)};_.a=false;var d0=mdb(dse,'GrowTreePhase',785);bcb(786,1,qie,L1c);_.td=function M1c(a){G1c(this.a,this.b,this.c,BD(a,221))};var c0=mdb(dse,'GrowTreePhase/lambda$0$Type',786);bcb(1448,1,Bqe,Q1c);_.Yf=function R1c(a){return BD(a,300),new j3c};_.pf=function S1c(a,b){P1c(this,BD(a,300),b)};var f0=mdb(dse,'ShrinkTreeCompactionPhase',1448);bcb(784,1,qie,T1c);_.td=function U1c(a){O1c(this.a,this.b,this.c,BD(a,221))};var e0=mdb(dse,'ShrinkTreeCompactionPhase/lambda$0$Type',784);var g2=odb(yqe,'IGraphElementVisitor');bcb(860,1,{527:1},b2c);_.og=function e2c(a){var b;b=a2c(this,a);tNb(b,BD(Ohb(this.b,a),94));$1c(this,a,b)};var V1c,W1c,X1c;var m0=mdb(Nle,'LayoutConfigurator',860);var h0=odb(Nle,'LayoutConfigurator/IPropertyHolderOptionFilter');bcb(932,1,{1933:1},f2c);_.pg=function g2c(a,b){return Y1c(),!a.Xe(b)};var i0=mdb(Nle,'LayoutConfigurator/lambda$0$Type',932);bcb(933,1,{1933:1},i2c);_.pg=function j2c(a,b){return h2c(a,b)};var j0=mdb(Nle,'LayoutConfigurator/lambda$1$Type',933);bcb(931,1,{831:1},k2c);_.qg=function l2c(a,b){return Y1c(),!a.Xe(b)};var k0=mdb(Nle,'LayoutConfigurator/lambda$2$Type',931);bcb(934,1,Oie,m2c);_.Mb=function n2c(a){return d2c(this.a,this.b,BD(a,1933))};var l0=mdb(Nle,'LayoutConfigurator/lambda$3$Type',934);bcb(858,1,{},w2c);var n0=mdb(Nle,'RecursiveGraphLayoutEngine',858);bcb(296,60,Tie,x2c,y2c);var o0=mdb(Nle,'UnsupportedConfigurationException',296);bcb(453,60,Tie,z2c);var p0=mdb(Nle,'UnsupportedGraphException',453);bcb(754,1,{});var K1=mdb(yqe,'AbstractRandomListAccessor',754);bcb(500,754,{},L2c);_.rg=function N2c(){return null};_.d=true;_.e=true;_.f=0;var v0=mdb(fse,'AlgorithmAssembler',500);bcb(1236,1,Oie,O2c);_.Mb=function P2c(a){return !!BD(a,123)};var q0=mdb(fse,'AlgorithmAssembler/lambda$0$Type',1236);bcb(1237,1,{},Q2c);_.Kb=function R2c(a){return M2c(this.a,BD(a,123))};var r0=mdb(fse,'AlgorithmAssembler/lambda$1$Type',1237);bcb(1238,1,Oie,S2c);_.Mb=function T2c(a){return !!BD(a,80)};var s0=mdb(fse,'AlgorithmAssembler/lambda$2$Type',1238);bcb(1239,1,qie,U2c);_.td=function V2c(a){d3c(this.a,BD(a,80))};var t0=mdb(fse,'AlgorithmAssembler/lambda$3$Type',1239);bcb(1240,1,qie,W2c);_.td=function X2c(a){G2c(this.a,this.b,BD(a,234))};var u0=mdb(fse,'AlgorithmAssembler/lambda$4$Type',1240);bcb(1355,1,Dke,Z2c);_.ue=function $2c(a,b){return Y2c(BD(a,234),BD(b,234))};_.Fb=function _2c(a){return this===a};_.ve=function a3c(){return new tpb(this)};var w0=mdb(fse,'EnumBasedFactoryComparator',1355);bcb(80,754,{80:1},j3c);_.rg=function l3c(){return new Tqb};_.a=0;var x0=mdb(fse,'LayoutProcessorConfiguration',80);bcb(1013,1,{527:1},q3c);_.og=function u3c(a){stb(n3c,new z3c(a))};var m3c,n3c,o3c;var B0=mdb(Xke,'DeprecatedLayoutOptionReplacer',1013);bcb(1014,1,qie,v3c);_.td=function w3c(a){r3c(BD(a,160))};var y0=mdb(Xke,'DeprecatedLayoutOptionReplacer/lambda$0$Type',1014);bcb(1015,1,qie,x3c);_.td=function y3c(a){s3c(BD(a,160))};var z0=mdb(Xke,'DeprecatedLayoutOptionReplacer/lambda$1$Type',1015);bcb(1016,1,{},z3c);_.Od=function A3c(a,b){t3c(this.a,BD(a,146),BD(b,38))};var A0=mdb(Xke,'DeprecatedLayoutOptionReplacer/lambda$2$Type',1016);bcb(149,1,{686:1,149:1},E3c);_.Fb=function F3c(a){return C3c(this,a)};_.sg=function G3c(){return this.b};_.tg=function H3c(){return this.c};_.ne=function I3c(){return this.e};_.Hb=function J3c(){return LCb(this.c)};_.Ib=function K3c(){return 'Layout Algorithm: '+this.c};var E0=mdb(Xke,'LayoutAlgorithmData',149);bcb(263,1,{},R3c);var D0=mdb(Xke,'LayoutAlgorithmData/Builder',263);bcb(1017,1,{527:1},U3c);_.og=function V3c(a){JD(a,239)&&!Ccb(DD(a.We((Y9c(),d9c))))&&S3c(BD(a,33))};var F0=mdb(Xke,'LayoutAlgorithmResolver',1017);bcb(229,1,{686:1,229:1},W3c);_.Fb=function X3c(a){if(JD(a,229)){return dfb(this.b,BD(a,229).b)}return false};_.sg=function Y3c(){return this.a};_.tg=function Z3c(){return this.b};_.ne=function $3c(){return this.d};_.Hb=function _3c(){return LCb(this.b)};_.Ib=function a4c(){return 'Layout Type: '+this.b};var H0=mdb(Xke,'LayoutCategoryData',229);bcb(344,1,{},e4c);var G0=mdb(Xke,'LayoutCategoryData/Builder',344);bcb(867,1,{},m4c);var f4c;var c1=mdb(Xke,'LayoutMetaDataService',867);bcb(868,1,{},v4c);var J0=mdb(Xke,'LayoutMetaDataService/Registry',868);bcb(478,1,{478:1},w4c);var I0=mdb(Xke,'LayoutMetaDataService/Registry/Triple',478);bcb(869,1,gse,x4c);_.ug=function y4c(){return new d7c};var K0=mdb(Xke,'LayoutMetaDataService/lambda$0$Type',869);bcb(870,1,hse,z4c);_.vg=function A4c(a){return R6c(BD(a,8))};var L0=mdb(Xke,'LayoutMetaDataService/lambda$1$Type',870);bcb(879,1,gse,B4c);_.ug=function C4c(){return new Rkb};var M0=mdb(Xke,'LayoutMetaDataService/lambda$10$Type',879);bcb(880,1,hse,D4c);_.vg=function E4c(a){return new Tkb(BD(a,12))};var N0=mdb(Xke,'LayoutMetaDataService/lambda$11$Type',880);bcb(881,1,gse,F4c);_.ug=function G4c(){return new Psb};var O0=mdb(Xke,'LayoutMetaDataService/lambda$12$Type',881);bcb(882,1,hse,H4c);_.vg=function I4c(a){return Ru(BD(a,68))};var P0=mdb(Xke,'LayoutMetaDataService/lambda$13$Type',882);bcb(883,1,gse,J4c);_.ug=function K4c(){return new Tqb};var Q0=mdb(Xke,'LayoutMetaDataService/lambda$14$Type',883);bcb(884,1,hse,L4c);_.vg=function M4c(a){return Dx(BD(a,53))};var R0=mdb(Xke,'LayoutMetaDataService/lambda$15$Type',884);bcb(885,1,gse,N4c);_.ug=function O4c(){return new zsb};var S0=mdb(Xke,'LayoutMetaDataService/lambda$16$Type',885);bcb(886,1,hse,P4c);_.vg=function Q4c(a){return Gx(BD(a,53))};var T0=mdb(Xke,'LayoutMetaDataService/lambda$17$Type',886);bcb(887,1,gse,R4c);_.ug=function S4c(){return new Gxb};var U0=mdb(Xke,'LayoutMetaDataService/lambda$18$Type',887);bcb(888,1,hse,T4c);_.vg=function U4c(a){return Hx(BD(a,208))};var V0=mdb(Xke,'LayoutMetaDataService/lambda$19$Type',888);bcb(871,1,gse,V4c);_.ug=function W4c(){return new s7c};var W0=mdb(Xke,'LayoutMetaDataService/lambda$2$Type',871);bcb(872,1,hse,X4c);_.vg=function Y4c(a){return new t7c(BD(a,74))};var X0=mdb(Xke,'LayoutMetaDataService/lambda$3$Type',872);bcb(873,1,gse,Z4c);_.ug=function $4c(){return new H_b};var Y0=mdb(Xke,'LayoutMetaDataService/lambda$4$Type',873);bcb(874,1,hse,_4c);_.vg=function a5c(a){return new K_b(BD(a,142))};var Z0=mdb(Xke,'LayoutMetaDataService/lambda$5$Type',874);bcb(875,1,gse,b5c);_.ug=function c5c(){return new p0b};var $0=mdb(Xke,'LayoutMetaDataService/lambda$6$Type',875);bcb(876,1,hse,d5c);_.vg=function e5c(a){return new r0b(BD(a,116))};var _0=mdb(Xke,'LayoutMetaDataService/lambda$7$Type',876);bcb(877,1,gse,f5c);_.ug=function g5c(){return new _fd};var a1=mdb(Xke,'LayoutMetaDataService/lambda$8$Type',877);bcb(878,1,hse,h5c);_.vg=function i5c(a){return new agd(BD(a,373))};var b1=mdb(Xke,'LayoutMetaDataService/lambda$9$Type',878);var Q3=odb(Hle,'IProperty');bcb(23,1,{35:1,686:1,23:1,146:1},p5c);_.wd=function q5c(a){return k5c(this,BD(a,146))};_.Fb=function r5c(a){return JD(a,23)?dfb(this.f,BD(a,23).f):JD(a,146)&&dfb(this.f,BD(a,146).tg())};_.wg=function s5c(){var a;if(JD(this.b,4)){a=fvd(this.b);if(a==null){throw vbb(new Zdb(mse+this.f+"'. "+"Make sure it's type is registered with the "+(fdb(Y3),Y3.k)+jse))}return a}else{return this.b}};_.sg=function t5c(){return this.d};_.tg=function u5c(){return this.f};_.ne=function v5c(){return this.i};_.Hb=function w5c(){return LCb(this.f)};_.Ib=function x5c(){return 'Layout Option: '+this.f};var g1=mdb(Xke,'LayoutOptionData',23);bcb(24,1,{},H5c);var d1=mdb(Xke,'LayoutOptionData/Builder',24);bcb(175,22,{3:1,35:1,22:1,175:1},O5c);var I5c,J5c,K5c,L5c,M5c;var e1=ndb(Xke,'LayoutOptionData/Target',175,CI,Q5c,P5c);var R5c;bcb(277,22,{3:1,35:1,22:1,277:1},a6c);var T5c,U5c,V5c,W5c,X5c,Y5c,Z5c,$5c;var f1=ndb(Xke,'LayoutOptionData/Type',277,CI,c6c,b6c);var d6c;var f6c;var h6c;bcb(110,1,{110:1},I6c,J6c,K6c);_.Fb=function L6c(a){var b;if(a==null||!JD(a,110)){return false}b=BD(a,110);return wtb(this.c,b.c)&&wtb(this.d,b.d)&&wtb(this.b,b.b)&&wtb(this.a,b.a)};_.Hb=function M6c(){return Hlb(OC(GC(SI,1),Uhe,1,5,[this.c,this.d,this.b,this.a]))};_.Ib=function N6c(){return 'Rect[x='+this.c+',y='+this.d+',w='+this.b+',h='+this.a+']'};_.a=0;_.b=0;_.c=0;_.d=0;var k1=mdb(pne,'ElkRectangle',110);bcb(8,1,{3:1,4:1,8:1,414:1},d7c,e7c,f7c,g7c);_.Fb=function h7c(a){return T6c(this,a)};_.Hb=function i7c(){return Hdb(this.a)+jeb(Hdb(this.b))};_.Jf=function k7c(b){var c,d,e,f;e=0;while(e<b.length&&j7c((BCb(e,b.length),b.charCodeAt(e)),mne)){++e}c=b.length;while(c>0&&j7c((BCb(c-1,b.length),b.charCodeAt(c-1)),nne)){--c}if(e>=c){throw vbb(new Wdb('The given string does not contain any numbers.'))}f=mfb(b.substr(e,c-e),',|;|\r|\n');if(f.length!=2){throw vbb(new Wdb('Exactly two numbers are expected, '+f.length+' were found.'))}try{this.a=Hcb(ufb(f[0]));this.b=Hcb(ufb(f[1]))}catch(a){a=ubb(a);if(JD(a,127)){d=a;throw vbb(new Wdb(one+d))}else throw vbb(a)}};_.Ib=function m7c(){return '('+this.a+','+this.b+')'};_.a=0;_.b=0;var m1=mdb(pne,'KVector',8);bcb(74,68,{3:1,4:1,20:1,28:1,52:1,14:1,68:1,15:1,74:1,414:1},s7c,t7c,u7c);_.Pc=function x7c(){return r7c(this)};_.Jf=function v7c(b){var c,d,e,f,g,h;e=mfb(b,',|;|\\(|\\)|\\[|\\]|\\{|\\}| |\t|\n');Osb(this);try{d=0;g=0;f=0;h=0;while(d<e.length){if(e[d]!=null&&ufb(e[d]).length>0){g%2==0?(f=Hcb(e[d])):(h=Hcb(e[d]));g>0&&g%2!=0&&Dsb(this,new f7c(f,h));++g}++d}}catch(a){a=ubb(a);if(JD(a,127)){c=a;throw vbb(new Wdb('The given string does not match the expected format for vectors.'+c))}else throw vbb(a)}};_.Ib=function y7c(){var a,b,c;a=new Wfb('(');b=Jsb(this,0);while(b.b!=b.d.c){c=BD(Xsb(b),8);Qfb(a,c.a+','+c.b);b.b!=b.d.c&&(a.a+='; ',a)}return (a.a+=')',a).a};var l1=mdb(pne,'KVectorChain',74);bcb(248,22,{3:1,35:1,22:1,248:1},G7c);var z7c,A7c,B7c,C7c,D7c,E7c;var o1=ndb(ose,'Alignment',248,CI,I7c,H7c);var J7c;bcb(979,1,ale,Z7c);_.Qe=function $7c(a){Y7c(a)};var L7c,M7c,N7c,O7c,P7c,Q7c,R7c,S7c,T7c,U7c,V7c,W7c;var q1=mdb(ose,'BoxLayouterOptions',979);bcb(980,1,{},_7c);_.$e=function a8c(){var a;return a=new ged,a};_._e=function b8c(a){};var p1=mdb(ose,'BoxLayouterOptions/BoxFactory',980);bcb(291,22,{3:1,35:1,22:1,291:1},j8c);var c8c,d8c,e8c,f8c,g8c,h8c;var r1=ndb(ose,'ContentAlignment',291,CI,l8c,k8c);var m8c;bcb(684,1,ale,Z9c);_.Qe=function $9c(a){t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,sse),''),'Layout Algorithm'),'Select a specific layout algorithm.'),(_5c(),Z5c)),ZI),pqb((N5c(),L5c)))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,tse),''),'Resolved Layout Algorithm'),'Meta data associated with the selected algorithm.'),Y5c),E0),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,$pe),''),'Alignment'),'Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm.'),q8c),V5c),o1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,_le),''),'Aspect Ratio'),'The desired aspect ratio of the drawing, that is the quotient of width by height.'),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,use),''),'Bend Points'),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),Y5c),l1),pqb(I5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,lqe),''),'Content Alignment'),'Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option.'),x8c),W5c),r1),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Zpe),''),'Debug Mode'),'Whether additional debug information shall be generated.'),(Bcb(),false)),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,cqe),''),Cle),'Overall direction of edges: horizontal (right / left) or vertical (down / up).'),A8c),V5c),t1),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,ype),''),'Edge Routing'),'What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline.'),F8c),V5c),v1),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Jre),''),'Expand Nodes'),'If active, nodes are expanded to fill the area of their parent.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,tpe),''),'Hierarchy Handling'),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),K8c),V5c),z1),qqb(L5c,OC(GC(e1,1),Kie,175,0,[K5c])))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,ame),''),'Padding'),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),g9c),Y5c),j1),qqb(L5c,OC(GC(e1,1),Kie,175,0,[K5c])))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ame),''),'Interactive'),'Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,xqe),''),'interactive Layout'),'Whether the graph should be changeable interactively and by setting constraints'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Dme),''),'Omit Node Micro Layout'),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Bme),''),'Port Constraints'),'Defines constraints of the position of the ports of a node.'),u9c),V5c),D1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,uqe),''),'Position'),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),Y5c),m1),qqb(K5c,OC(GC(e1,1),Kie,175,0,[M5c,J5c])))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,vme),''),'Priority'),'Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used.'),X5c),JI),qqb(K5c,OC(GC(e1,1),Kie,175,0,[I5c])))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,yme),''),'Randomization Seed'),'Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time).'),X5c),JI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,zme),''),'Separate Connected Components'),'Whether each connected component should be processed separately.'),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,mqe),''),'Junction Points'),'This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order.'),R8c),Y5c),l1),pqb(I5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,pqe),''),'Comment Box'),'Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related.'),false),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,qqe),''),'Hypernode'),'Whether the node should be handled as a hypernode.'),false),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,vse),''),'Label Manager'),"Label managers can shorten labels upon a layout algorithm's request."),Y5c),h1),qqb(L5c,OC(GC(e1,1),Kie,175,0,[J5c])))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,vqe),''),'Margins'),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),T8c),Y5c),i1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Xpe),''),'No Layout'),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),false),T5c),wI),qqb(K5c,OC(GC(e1,1),Kie,175,0,[I5c,M5c,J5c])))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,wse),''),'Scale Factor'),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),U5c),BI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,xse),''),'Animate'),'Whether the shift from the old layout to the new computed layout shall be animated.'),true),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,yse),''),'Animation Time Factor'),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),meb(100)),X5c),JI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,zse),''),'Layout Ancestors'),'Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ase),''),'Maximal Animation Time'),'The maximal time for animations, in milliseconds.'),meb(4000)),X5c),JI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Bse),''),'Minimal Animation Time'),'The minimal time for animations, in milliseconds.'),meb(400)),X5c),JI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Cse),''),'Progress Bar'),'Whether a progress bar shall be displayed during layout computations.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Dse),''),'Validate Graph'),'Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ese),''),'Validate Options'),'Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user.'),true),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Fse),''),'Zoom to Fit'),'Whether the zoom level shall be set to view the whole diagram after layout.'),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,rse),'box'),'Box Layout Mode'),'Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better.'),u8c),V5c),O1),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Lpe),zpe),'Comment Comment Spacing'),'Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing.'),10),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Mpe),zpe),'Comment Node Spacing'),'Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing.'),10),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Zle),zpe),'Components Spacing'),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Npe),zpe),'Edge Spacing'),'Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines.'),10),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,xme),zpe),'Edge Label Spacing'),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ope),zpe),'Edge Node Spacing'),'Spacing to be preserved between nodes and edges.'),10),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ppe),zpe),'Label Spacing'),'Determines the amount of space to be left between two labels of the same graph element.'),0),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Spe),zpe),'Label Node Spacing'),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Qpe),zpe),'Horizontal spacing between Label and Port'),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Rpe),zpe),'Vertical spacing between Label and Port'),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,wme),zpe),'Node Spacing'),'The minimal distance to be preserved between each two nodes.'),20),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Tpe),zpe),'Node Self Loop Spacing'),'Spacing to be preserved between a node and its self loops.'),10),U5c),BI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Upe),zpe),'Port Spacing'),'Spacing between pairs of ports of the same node.'),10),U5c),BI),qqb(L5c,OC(GC(e1,1),Kie,175,0,[K5c])))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Vpe),zpe),'Individual Spacing'),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),Y5c),i2),qqb(K5c,OC(GC(e1,1),Kie,175,0,[I5c,M5c,J5c])))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,wqe),zpe),'Additional Port Space'),'Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border.'),W9c),Y5c),i1),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,tqe),Jse),'Layout Partition'),'Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction).'),X5c),JI),qqb(L5c,OC(GC(e1,1),Kie,175,0,[K5c])))));o4c(a,tqe,sqe,k9c);t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,sqe),Jse),'Layout Partitioning'),'Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle.'),i9c),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,dqe),Kse),'Node Label Padding'),'Define padding for node labels that are placed inside of a node.'),V8c),Y5c),j1),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Gme),Kse),'Node Label Placement'),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),X8c),W5c),B1),qqb(K5c,OC(GC(e1,1),Kie,175,0,[J5c])))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,gqe),Lse),'Port Alignment'),'Defines the default port distribution for a node. May be overridden for each side individually.'),m9c),V5c),C1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,hqe),Lse),'Port Alignment (North)'),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),V5c),C1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,iqe),Lse),'Port Alignment (South)'),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),V5c),C1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,jqe),Lse),'Port Alignment (West)'),"Defines how ports on the western side are placed, overriding the node's general port alignment."),V5c),C1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,kqe),Lse),'Port Alignment (East)'),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),V5c),C1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Fme),Mse),'Node Size Constraints'),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),Z8c),W5c),I1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Eme),Mse),'Node Size Options'),'Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications.'),c9c),W5c),J1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Tme),Mse),'Node Size Minimum'),'The minimal size to which a node can be reduced.'),a9c),Y5c),m1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,bqe),Mse),'Fixed Graph Size'),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),false),T5c),wI),pqb(L5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,nqe),Jpe),'Edge Label Placement'),'Gives a hint on where to put edge labels.'),D8c),V5c),u1),pqb(J5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Cme),Jpe),'Inline Edge Labels'),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),false),T5c),wI),pqb(J5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Gse),'font'),'Font Name'),'Font name used for a label.'),Z5c),ZI),pqb(J5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Hse),'font'),'Font Size'),'Font size used for a label.'),X5c),JI),pqb(J5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,rqe),Nse),'Port Anchor Offset'),'The offset to the port position where connections shall be attached.'),Y5c),m1),pqb(M5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,oqe),Nse),'Port Index'),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),X5c),JI),pqb(M5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ype),Nse),'Port Side'),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),B9c),V5c),F1),pqb(M5c))));t4c(a,new p5c(F5c(E5c(G5c(z5c(D5c(A5c(B5c(new H5c,Wpe),Nse),'Port Border Offset'),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),U5c),BI),pqb(M5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Hme),Ose),'Port Label Placement'),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),y9c),W5c),E1),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,eqe),Ose),'Port Labels Next to Port'),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),false),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,fqe),Ose),'Treat Port Labels as Group'),'If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port.'),true),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,_pe),Pse),'Activate Inside Self Loops'),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),false),T5c),wI),pqb(K5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,aqe),Pse),'Inside Self Loop'),'Whether a self loop should be routed inside a node instead of around that node.'),false),T5c),wI),pqb(I5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,$le),'edge'),'Edge Thickness'),'The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it.'),1),U5c),BI),pqb(I5c))));t4c(a,new p5c(F5c(E5c(G5c(y5c(z5c(D5c(A5c(B5c(new H5c,Ise),'edge'),'Edge Type'),'The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations.'),H8c),V5c),w1),pqb(I5c))));s4c(a,new W3c(b4c(d4c(c4c(new e4c,sne),'Layered'),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.')));s4c(a,new W3c(b4c(d4c(c4c(new e4c,'org.eclipse.elk.orthogonal'),'Orthogonal'),'Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.')));s4c(a,new W3c(b4c(d4c(c4c(new e4c,ume),'Force'),'Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984.')));s4c(a,new W3c(b4c(d4c(c4c(new e4c,'org.eclipse.elk.circle'),'Circle'),'Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph.')));s4c(a,new W3c(b4c(d4c(c4c(new e4c,bre),'Tree'),'Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type.')));s4c(a,new W3c(b4c(d4c(c4c(new e4c,'org.eclipse.elk.planar'),'Planar'),'Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable.')));s4c(a,new W3c(b4c(d4c(c4c(new e4c,sre),'Radial'),'Radial layout algorithms usually position the nodes of the graph on concentric circles.')));$ad((new _ad,a));Y7c((new Z7c,a));jdd((new kdd,a))};var o8c,p8c,q8c,r8c,s8c,t8c,u8c,v8c,w8c,x8c,y8c,z8c,A8c,B8c,C8c,D8c,E8c,F8c,G8c,H8c,I8c,J8c,K8c,L8c,M8c,N8c,O8c,P8c,Q8c,R8c,S8c,T8c,U8c,V8c,W8c,X8c,Y8c,Z8c,$8c,_8c,a9c,b9c,c9c,d9c,e9c,f9c,g9c,h9c,i9c,j9c,k9c,l9c,m9c,n9c,o9c,p9c,q9c,r9c,s9c,t9c,u9c,v9c,w9c,x9c,y9c,z9c,A9c,B9c,C9c,D9c,E9c,F9c,G9c,H9c,I9c,J9c,K9c,L9c,M9c,N9c,O9c,P9c,Q9c,R9c,S9c,T9c,U9c,V9c,W9c,X9c;var s1=mdb(ose,'CoreOptions',684);bcb(103,22,{3:1,35:1,22:1,103:1},iad);var _9c,aad,bad,cad,dad;var t1=ndb(ose,Cle,103,CI,kad,jad);var lad;bcb(272,22,{3:1,35:1,22:1,272:1},rad);var nad,oad,pad;var u1=ndb(ose,'EdgeLabelPlacement',272,CI,tad,sad);var uad;bcb(218,22,{3:1,35:1,22:1,218:1},Bad);var wad,xad,yad,zad;var v1=ndb(ose,'EdgeRouting',218,CI,Dad,Cad);var Ead;bcb(312,22,{3:1,35:1,22:1,312:1},Nad);var Gad,Had,Iad,Jad,Kad,Lad;var w1=ndb(ose,'EdgeType',312,CI,Pad,Oad);var Qad;bcb(977,1,ale,_ad);_.Qe=function abd(a){$ad(a)};var Sad,Tad,Uad,Vad,Wad,Xad,Yad;var y1=mdb(ose,'FixedLayouterOptions',977);bcb(978,1,{},bbd);_.$e=function cbd(){var a;return a=new Zfd,a};_._e=function dbd(a){};var x1=mdb(ose,'FixedLayouterOptions/FixedFactory',978);bcb(334,22,{3:1,35:1,22:1,334:1},ibd);var ebd,fbd,gbd;var z1=ndb(ose,'HierarchyHandling',334,CI,kbd,jbd);var lbd;bcb(285,22,{3:1,35:1,22:1,285:1},tbd);var nbd,obd,pbd,qbd;var A1=ndb(ose,'LabelSide',285,CI,vbd,ubd);var wbd;bcb(93,22,{3:1,35:1,22:1,93:1},Ibd);var ybd,zbd,Abd,Bbd,Cbd,Dbd,Ebd,Fbd,Gbd;var B1=ndb(ose,'NodeLabelPlacement',93,CI,Lbd,Kbd);var Mbd;bcb(249,22,{3:1,35:1,22:1,249:1},Ubd);var Obd,Pbd,Qbd,Rbd,Sbd;var C1=ndb(ose,'PortAlignment',249,CI,Wbd,Vbd);var Xbd;bcb(98,22,{3:1,35:1,22:1,98:1},gcd);var Zbd,$bd,_bd,acd,bcd,ccd;var D1=ndb(ose,'PortConstraints',98,CI,icd,hcd);var jcd;bcb(273,22,{3:1,35:1,22:1,273:1},scd);var lcd,mcd,ncd,ocd,pcd,qcd;var E1=ndb(ose,'PortLabelPlacement',273,CI,wcd,vcd);var xcd;bcb(61,22,{3:1,35:1,22:1,61:1},Ycd);var zcd,Acd,Bcd,Ccd,Dcd,Ecd,Fcd,Gcd,Hcd,Icd,Jcd,Kcd,Lcd,Mcd,Ncd,Ocd,Pcd,Qcd,Rcd,Scd,Tcd;var F1=ndb(ose,'PortSide',61,CI,_cd,$cd);var bdd;bcb(981,1,ale,kdd);_.Qe=function ldd(a){jdd(a)};var ddd,edd,fdd,gdd,hdd;var H1=mdb(ose,'RandomLayouterOptions',981);bcb(982,1,{},mdd);_.$e=function ndd(){var a;return a=new Mgd,a};_._e=function odd(a){};var G1=mdb(ose,'RandomLayouterOptions/RandomFactory',982);bcb(374,22,{3:1,35:1,22:1,374:1},udd);var pdd,qdd,rdd,sdd;var I1=ndb(ose,'SizeConstraint',374,CI,wdd,vdd);var xdd;bcb(259,22,{3:1,35:1,22:1,259:1},Jdd);var zdd,Add,Bdd,Cdd,Ddd,Edd,Fdd,Gdd,Hdd;var J1=ndb(ose,'SizeOptions',259,CI,Ldd,Kdd);var Mdd;bcb(370,1,{1949:1},Zdd);_.b=false;_.c=0;_.d=-1;_.e=null;_.f=null;_.g=-1;_.j=false;_.k=false;_.n=false;_.o=0;_.q=0;_.r=0;var L1=mdb(yqe,'BasicProgressMonitor',370);bcb(972,209,Mle,ged);_.Ze=function ked(a,b){var c,d,e,f,g,h,i,j,k;Odd(b,'Box layout',2);e=Gdb(ED(hkd(a,(X7c(),W7c))));f=BD(hkd(a,T7c),116);c=Ccb(DD(hkd(a,O7c)));d=Ccb(DD(hkd(a,P7c)));switch(BD(hkd(a,M7c),311).g){case 0:g=(h=new Tkb((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a)),mmb(),Okb(h,new med(d)),h);i=rfd(a);j=ED(hkd(a,L7c));(j==null||(uCb(j),j)<=0)&&(j=1.3);k=ded(g,e,f,i.a,i.b,c,(uCb(j),j));Afd(a,k.a,k.b,false,true);break;default:eed(a,e,f,c);}Qdd(b)};var S1=mdb(yqe,'BoxLayoutProvider',972);bcb(973,1,Dke,med);_.ue=function ned(a,b){return led(this,BD(a,33),BD(b,33))};_.Fb=function oed(a){return this===a};_.ve=function ped(){return new tpb(this)};_.a=false;var M1=mdb(yqe,'BoxLayoutProvider/1',973);bcb(157,1,{157:1},wed,xed);_.Ib=function yed(){return this.c?_od(this.c):Fe(this.b)};var N1=mdb(yqe,'BoxLayoutProvider/Group',157);bcb(311,22,{3:1,35:1,22:1,311:1},Eed);var zed,Aed,Bed,Ced;var O1=ndb(yqe,'BoxLayoutProvider/PackingMode',311,CI,Ged,Fed);var Hed;bcb(974,1,Dke,Jed);_.ue=function Ked(a,b){return hed(BD(a,157),BD(b,157))};_.Fb=function Led(a){return this===a};_.ve=function Med(){return new tpb(this)};var P1=mdb(yqe,'BoxLayoutProvider/lambda$0$Type',974);bcb(975,1,Dke,Ned);_.ue=function Oed(a,b){return ied(BD(a,157),BD(b,157))};_.Fb=function Ped(a){return this===a};_.ve=function Qed(){return new tpb(this)};var Q1=mdb(yqe,'BoxLayoutProvider/lambda$1$Type',975);bcb(976,1,Dke,Red);_.ue=function Sed(a,b){return jed(BD(a,157),BD(b,157))};_.Fb=function Ted(a){return this===a};_.ve=function Ued(){return new tpb(this)};var R1=mdb(yqe,'BoxLayoutProvider/lambda$2$Type',976);bcb(1365,1,{831:1},Ved);_.qg=function Wed(a,b){return Vyc(),!JD(b,160)||h2c((Y1c(),X1c,BD(a,160)),b)};var T1=mdb(yqe,'ElkSpacings/AbstractSpacingsBuilder/lambda$0$Type',1365);bcb(1366,1,qie,Xed);_.td=function Yed(a){Yyc(this.a,BD(a,146))};var U1=mdb(yqe,'ElkSpacings/AbstractSpacingsBuilder/lambda$1$Type',1366);bcb(1367,1,qie,Zed);_.td=function $ed(a){BD(a,94);Vyc()};var V1=mdb(yqe,'ElkSpacings/AbstractSpacingsBuilder/lambda$2$Type',1367);bcb(1371,1,qie,_ed);_.td=function afd(a){Zyc(this.a,BD(a,94))};var W1=mdb(yqe,'ElkSpacings/AbstractSpacingsBuilder/lambda$3$Type',1371);bcb(1369,1,Oie,bfd);_.Mb=function cfd(a){return $yc(this.a,this.b,BD(a,146))};var X1=mdb(yqe,'ElkSpacings/AbstractSpacingsBuilder/lambda$4$Type',1369);bcb(1368,1,Oie,dfd);_.Mb=function efd(a){return azc(this.a,this.b,BD(a,831))};var Y1=mdb(yqe,'ElkSpacings/AbstractSpacingsBuilder/lambda$5$Type',1368);bcb(1370,1,qie,ffd);_.td=function gfd(a){_yc(this.a,this.b,BD(a,146))};var Z1=mdb(yqe,'ElkSpacings/AbstractSpacingsBuilder/lambda$6$Type',1370);bcb(935,1,{},Hfd);_.Kb=function Ifd(a){return Gfd(a)};_.Fb=function Jfd(a){return this===a};var _1=mdb(yqe,'ElkUtil/lambda$0$Type',935);bcb(936,1,qie,Kfd);_.td=function Lfd(a){ufd(this.a,this.b,BD(a,79))};_.a=0;_.b=0;var a2=mdb(yqe,'ElkUtil/lambda$1$Type',936);bcb(937,1,qie,Mfd);_.td=function Nfd(a){vfd(this.a,this.b,BD(a,202))};_.a=0;_.b=0;var b2=mdb(yqe,'ElkUtil/lambda$2$Type',937);bcb(938,1,qie,Ofd);_.td=function Pfd(a){wfd(this.a,this.b,BD(a,137))};_.a=0;_.b=0;var c2=mdb(yqe,'ElkUtil/lambda$3$Type',938);bcb(939,1,qie,Qfd);_.td=function Rfd(a){xfd(this.a,BD(a,469))};var d2=mdb(yqe,'ElkUtil/lambda$4$Type',939);bcb(342,1,{35:1,342:1},Tfd);_.wd=function Ufd(a){return Sfd(this,BD(a,236))};_.Fb=function Vfd(a){var b;if(JD(a,342)){b=BD(a,342);return this.a==b.a}return false};_.Hb=function Wfd(){return QD(this.a)};_.Ib=function Xfd(){return this.a+' (exclusive)'};_.a=0;var e2=mdb(yqe,'ExclusiveBounds/ExclusiveLowerBound',342);bcb(1138,209,Mle,Zfd);_.Ze=function $fd(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,A,B;Odd(b,'Fixed Layout',1);f=BD(hkd(a,(Y9c(),E8c)),218);l=0;m=0;for(s=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));s.e!=s.i.gc();){q=BD(Dyd(s),33);B=BD(hkd(q,(Zad(),Yad)),8);if(B){bld(q,B.a,B.b);if(BD(hkd(q,Tad),174).Hc((tdd(),pdd))){n=BD(hkd(q,Vad),8);n.a>0&&n.b>0&&Afd(q,n.a,n.b,true,true)}}l=$wnd.Math.max(l,q.i+q.g);m=$wnd.Math.max(m,q.j+q.f);for(j=new Fyd((!q.n&&(q.n=new cUd(D2,q,1,7)),q.n));j.e!=j.i.gc();){h=BD(Dyd(j),137);B=BD(hkd(h,Yad),8);!!B&&bld(h,B.a,B.b);l=$wnd.Math.max(l,q.i+h.i+h.g);m=$wnd.Math.max(m,q.j+h.j+h.f)}for(v=new Fyd((!q.c&&(q.c=new cUd(F2,q,9,9)),q.c));v.e!=v.i.gc();){u=BD(Dyd(v),118);B=BD(hkd(u,Yad),8);!!B&&bld(u,B.a,B.b);w=q.i+u.i;A=q.j+u.j;l=$wnd.Math.max(l,w+u.g);m=$wnd.Math.max(m,A+u.f);for(i=new Fyd((!u.n&&(u.n=new cUd(D2,u,1,7)),u.n));i.e!=i.i.gc();){h=BD(Dyd(i),137);B=BD(hkd(h,Yad),8);!!B&&bld(h,B.a,B.b);l=$wnd.Math.max(l,w+h.i+h.g);m=$wnd.Math.max(m,A+h.j+h.f)}}for(e=new Sr(ur(_sd(q).a.Kc(),new Sq));Qr(e);){c=BD(Rr(e),79);k=Yfd(c);l=$wnd.Math.max(l,k.a);m=$wnd.Math.max(m,k.b)}for(d=new Sr(ur($sd(q).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),79);if(Xod(jtd(c))!=a){k=Yfd(c);l=$wnd.Math.max(l,k.a);m=$wnd.Math.max(m,k.b)}}}if(f==(Aad(),wad)){for(r=new Fyd((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a));r.e!=r.i.gc();){q=BD(Dyd(r),33);for(d=new Sr(ur(_sd(q).a.Kc(),new Sq));Qr(d);){c=BD(Rr(d),79);g=pfd(c);g.b==0?jkd(c,Q8c,null):jkd(c,Q8c,g)}}}if(!Ccb(DD(hkd(a,(Zad(),Uad))))){t=BD(hkd(a,Wad),116);p=l+t.b+t.c;o=m+t.d+t.a;Afd(a,p,o,true,true)}Qdd(b)};var f2=mdb(yqe,'FixedLayoutProvider',1138);bcb(373,134,{3:1,414:1,373:1,94:1,134:1},_fd,agd);_.Jf=function dgd(b){var c,d,e,f,g,h,i,j,k;if(!b){return}try{j=mfb(b,';,;');for(g=j,h=0,i=g.length;h<i;++h){f=g[h];d=mfb(f,'\\:');e=k4c(n4c(),d[0]);if(!e){throw vbb(new Wdb('Invalid option id: '+d[0]))}k=o5c(e,d[1]);if(k==null){throw vbb(new Wdb('Invalid option value: '+d[1]))}k==null?(!this.q&&(this.q=new Lqb),Thb(this.q,e)):(!this.q&&(this.q=new Lqb),Rhb(this.q,e,k))}}catch(a){a=ubb(a);if(JD(a,102)){c=a;throw vbb(new Xdb(c))}else throw vbb(a)}};_.Ib=function egd(){var a;a=GD(GAb(NAb((!this.q?(mmb(),mmb(),kmb):this.q).vc().Oc(),new fgd),Ayb(new pzb,new nzb,new Zyb,new _yb,OC(GC(xL,1),Kie,132,0,[]))));return a};var i2=mdb(yqe,'IndividualSpacings',373);bcb(971,1,{},fgd);_.Kb=function ggd(a){return cgd(BD(a,42))};var h2=mdb(yqe,'IndividualSpacings/lambda$0$Type',971);bcb(709,1,{},jgd);_.c=0;var j2=mdb(yqe,'InstancePool',709);bcb(1275,1,{},kgd);var l2=mdb(yqe,'LoggedGraph',1275);bcb(396,22,{3:1,35:1,22:1,396:1},qgd);var lgd,mgd,ngd,ogd;var k2=ndb(yqe,'LoggedGraph/Type',396,CI,sgd,rgd);var tgd;bcb(46,1,{20:1,46:1},vgd);_.Jc=function xgd(a){reb(this,a)};_.Fb=function wgd(a){var b,c,d;if(JD(a,46)){c=BD(a,46);b=this.a==null?c.a==null:pb(this.a,c.a);d=this.b==null?c.b==null:pb(this.b,c.b);return b&&d}else{return false}};_.Hb=function ygd(){var a,b,c,d,e,f;c=this.a==null?0:tb(this.a);a=c&aje;b=c&-65536;f=this.b==null?0:tb(this.b);d=f&aje;e=f&-65536;return a^e>>16&aje|b^d<<16};_.Kc=function zgd(){return new Bgd(this)};_.Ib=function Agd(){return this.a==null&&this.b==null?'pair(null,null)':this.a==null?'pair(null,'+fcb(this.b)+')':this.b==null?'pair('+fcb(this.a)+',null)':'pair('+fcb(this.a)+','+fcb(this.b)+')'};var n2=mdb(yqe,'Pair',46);bcb(983,1,aie,Bgd);_.Nb=function Cgd(a){Rrb(this,a)};_.Ob=function Dgd(){return !this.c&&(!this.b&&this.a.a!=null||this.a.b!=null)};_.Pb=function Egd(){if(!this.c&&!this.b&&this.a.a!=null){this.b=true;return this.a.a}else if(!this.c&&this.a.b!=null){this.c=true;return this.a.b}throw vbb(new utb)};_.Qb=function Fgd(){this.c&&this.a.b!=null?(this.a.b=null):this.b&&this.a.a!=null&&(this.a.a=null);throw vbb(new Ydb)};_.b=false;_.c=false;var m2=mdb(yqe,'Pair/1',983);bcb(448,1,{448:1},Ggd);_.Fb=function Hgd(a){return wtb(this.a,BD(a,448).a)&&wtb(this.c,BD(a,448).c)&&wtb(this.d,BD(a,448).d)&&wtb(this.b,BD(a,448).b)};_.Hb=function Igd(){return Hlb(OC(GC(SI,1),Uhe,1,5,[this.a,this.c,this.d,this.b]))};_.Ib=function Jgd(){return '('+this.a+She+this.c+She+this.d+She+this.b+')'};var o2=mdb(yqe,'Quadruple',448);bcb(1126,209,Mle,Mgd);_.Ze=function Ngd(a,b){var c,d,e,f,g;Odd(b,'Random Layout',1);if((!a.a&&(a.a=new cUd(E2,a,10,11)),a.a).i==0){Qdd(b);return}f=BD(hkd(a,(idd(),gdd)),19);!!f&&f.a!=0?(e=new Hub(f.a)):(e=new Gub);c=Gdb(ED(hkd(a,ddd)));g=Gdb(ED(hkd(a,hdd)));d=BD(hkd(a,edd),116);Lgd(a,e,c,g,d);Qdd(b)};var p2=mdb(yqe,'RandomLayoutProvider',1126);var Ogd;bcb(553,1,{});_.qf=function Sgd(){return new f7c(this.f.i,this.f.j)};_.We=function Tgd(a){if(Jsd(a,(Y9c(),s9c))){return hkd(this.f,Qgd)}return hkd(this.f,a)};_.rf=function Ugd(){return new f7c(this.f.g,this.f.f)};_.sf=function Vgd(){return this.g};_.Xe=function Wgd(a){return ikd(this.f,a)};_.tf=function Xgd(a){dld(this.f,a.a);eld(this.f,a.b)};_.uf=function Ygd(a){cld(this.f,a.a);ald(this.f,a.b)};_.vf=function Zgd(a){this.g=a};_.g=0;var Qgd;var q2=mdb(Use,'ElkGraphAdapters/AbstractElkGraphElementAdapter',553);bcb(554,1,{839:1},$gd);_.wf=function _gd(){var a,b;if(!this.b){this.b=Qu(Kkd(this.a).i);for(b=new Fyd(Kkd(this.a));b.e!=b.i.gc();){a=BD(Dyd(b),137);Ekb(this.b,new dhd(a))}}return this.b};_.b=null;var r2=mdb(Use,'ElkGraphAdapters/ElkEdgeAdapter',554);bcb(301,553,{},bhd);_.xf=function chd(){return ahd(this)};_.a=null;var s2=mdb(Use,'ElkGraphAdapters/ElkGraphAdapter',301);bcb(630,553,{181:1},dhd);var t2=mdb(Use,'ElkGraphAdapters/ElkLabelAdapter',630);bcb(629,553,{680:1},hhd);_.wf=function khd(){return ehd(this)};_.Af=function lhd(){var a;return a=BD(hkd(this.f,(Y9c(),S8c)),142),!a&&(a=new H_b),a};_.Cf=function nhd(){return fhd(this)};_.Ef=function phd(a){var b;b=new K_b(a);jkd(this.f,(Y9c(),S8c),b)};_.Ff=function qhd(a){jkd(this.f,(Y9c(),f9c),new r0b(a))};_.yf=function ihd(){return this.d};_.zf=function jhd(){var a,b;if(!this.a){this.a=new Rkb;for(b=new Sr(ur($sd(BD(this.f,33)).a.Kc(),new Sq));Qr(b);){a=BD(Rr(b),79);Ekb(this.a,new $gd(a))}}return this.a};_.Bf=function mhd(){var a,b;if(!this.c){this.c=new Rkb;for(b=new Sr(ur(_sd(BD(this.f,33)).a.Kc(),new Sq));Qr(b);){a=BD(Rr(b),79);Ekb(this.c,new $gd(a))}}return this.c};_.Df=function ohd(){return Vod(BD(this.f,33)).i!=0||Ccb(DD(BD(this.f,33).We((Y9c(),M8c))))};_.Gf=function rhd(){ghd(this,(Pgd(),Ogd))};_.a=null;_.b=null;_.c=null;_.d=null;_.e=null;var u2=mdb(Use,'ElkGraphAdapters/ElkNodeAdapter',629);bcb(1266,553,{838:1},thd);_.wf=function vhd(){return shd(this)};_.zf=function uhd(){var a,b;if(!this.a){this.a=Pu(BD(this.f,118).xg().i);for(b=new Fyd(BD(this.f,118).xg());b.e!=b.i.gc();){a=BD(Dyd(b),79);Ekb(this.a,new $gd(a))}}return this.a};_.Bf=function whd(){var a,b;if(!this.c){this.c=Pu(BD(this.f,118).yg().i);for(b=new Fyd(BD(this.f,118).yg());b.e!=b.i.gc();){a=BD(Dyd(b),79);Ekb(this.c,new $gd(a))}}return this.c};_.Hf=function xhd(){return BD(BD(this.f,118).We((Y9c(),A9c)),61)};_.If=function yhd(){var a,b,c,d,e,f,g,h;d=mpd(BD(this.f,118));for(c=new Fyd(BD(this.f,118).yg());c.e!=c.i.gc();){a=BD(Dyd(c),79);for(h=new Fyd((!a.c&&(a.c=new y5d(z2,a,5,8)),a.c));h.e!=h.i.gc();){g=BD(Dyd(h),82);if(ntd(atd(g),d)){return true}else if(atd(g)==d&&Ccb(DD(hkd(a,(Y9c(),N8c))))){return true}}}for(b=new Fyd(BD(this.f,118).xg());b.e!=b.i.gc();){a=BD(Dyd(b),79);for(f=new Fyd((!a.b&&(a.b=new y5d(z2,a,4,7)),a.b));f.e!=f.i.gc();){e=BD(Dyd(f),82);if(ntd(atd(e),d)){return true}}}return false};_.a=null;_.b=null;_.c=null;var v2=mdb(Use,'ElkGraphAdapters/ElkPortAdapter',1266);bcb(1267,1,Dke,Ahd);_.ue=function Bhd(a,b){return zhd(BD(a,118),BD(b,118))};_.Fb=function Chd(a){return this===a};_.ve=function Dhd(){return new tpb(this)};var w2=mdb(Use,'ElkGraphAdapters/PortComparator',1267);var m5=odb(Vse,'EObject');var x2=odb(Wse,Xse);var y2=odb(Wse,Yse);var C2=odb(Wse,Zse);var G2=odb(Wse,'ElkShape');var z2=odb(Wse,$se);var B2=odb(Wse,_se);var A2=odb(Wse,ate);var k5=odb(Vse,bte);var i5=odb(Vse,'EFactory');var Ehd;var l5=odb(Vse,cte);var o5=odb(Vse,'EPackage');var Ghd;var Ihd,Jhd,Khd,Lhd,Mhd,Nhd,Ohd,Phd,Qhd,Rhd,Shd;var D2=odb(Wse,dte);var E2=odb(Wse,ete);var F2=odb(Wse,fte);bcb(90,1,gte);_.Jg=function Vhd(){this.Kg();return null};_.Kg=function Whd(){return null};_.Lg=function Xhd(){return this.Kg(),false};_.Mg=function Yhd(){return false};_.Ng=function Zhd(a){Uhd(this,a)};var b4=mdb(hte,'BasicNotifierImpl',90);bcb(97,90,pte);_.nh=function fjd(){return oid(this)};_.Og=function Fid(a,b){return a};_.Pg=function Gid(){throw vbb(new bgb)};_.Qg=function Hid(a){var b;return b=zUd(BD(XKd(this.Tg(),this.Vg()),18)),this.eh().ih(this,b.n,b.f,a)};_.Rg=function Iid(a,b){throw vbb(new bgb)};_.Sg=function Jid(a,b,c){return _hd(this,a,b,c)};_.Tg=function Kid(){var a;if(this.Pg()){a=this.Pg().ck();if(a){return a}}return this.zh()};_.Ug=function Lid(){return aid(this)};_.Vg=function Mid(){throw vbb(new bgb)};_.Wg=function Oid(){var a,b;b=this.ph().dk();!b&&this.Pg().ik(b=(nRd(),a=pNd(TKd(this.Tg())),a==null?mRd:new qRd(this,a)));return b};_.Xg=function Qid(a,b){return a};_.Yg=function Rid(a){var b;b=a.Gj();return !b?bLd(this.Tg(),a):a.aj()};_.Zg=function Sid(){var a;a=this.Pg();return !a?null:a.fk()};_.$g=function Tid(){return !this.Pg()?null:this.Pg().ck()};_._g=function Uid(a,b,c){return fid(this,a,b,c)};_.ah=function Vid(a){return gid(this,a)};_.bh=function Wid(a,b){return hid(this,a,b)};_.dh=function Xid(){var a;a=this.Pg();return !!a&&a.gk()};_.eh=function Yid(){throw vbb(new bgb)};_.fh=function Zid(){return jid(this)};_.gh=function $id(a,b,c,d){return kid(this,a,b,d)};_.hh=function _id(a,b,c){var d;return d=BD(XKd(this.Tg(),b),66),d.Nj().Qj(this,this.yh(),b-this.Ah(),a,c)};_.ih=function ajd(a,b,c,d){return lid(this,a,b,d)};_.jh=function bjd(a,b,c){var d;return d=BD(XKd(this.Tg(),b),66),d.Nj().Rj(this,this.yh(),b-this.Ah(),a,c)};_.kh=function cjd(){return !!this.Pg()&&!!this.Pg().ek()};_.lh=function djd(a){return mid(this,a)};_.mh=function ejd(a){return nid(this,a)};_.oh=function gjd(a){return rid(this,a)};_.ph=function hjd(){throw vbb(new bgb)};_.qh=function ijd(){return !this.Pg()?null:this.Pg().ek()};_.rh=function jjd(){return jid(this)};_.sh=function kjd(a,b){yid(this,a,b)};_.th=function ljd(a){this.ph().hk(a)};_.uh=function mjd(a){this.ph().kk(a)};_.vh=function njd(a){this.ph().jk(a)};_.wh=function ojd(a,b){var c,d,e,f;f=this.Zg();if(!!f&&!!a){b=Txd(f.Vk(),this,b);f.Zk(this)}d=this.eh();if(d){if((Nid(this,this.eh(),this.Vg()).Bb&Tje)!=0){e=d.fh();!!e&&(!a?e.Yk(this):!f&&e.Zk(this))}else{b=(c=this.Vg(),c>=0?this.Qg(b):this.eh().ih(this,-1-c,null,b));b=this.Sg(null,-1,b)}}this.uh(a);return b};_.xh=function pjd(a){var b,c,d,e,f,g,h,i;c=this.Tg();f=bLd(c,a);b=this.Ah();if(f>=b){return BD(a,66).Nj().Uj(this,this.yh(),f-b)}else if(f<=-1){g=e1d((O6d(),M6d),c,a);if(g){Q6d();BD(g,66).Oj()||(g=_1d(q1d(M6d,g)));e=(d=this.Yg(g),BD(d>=0?this._g(d,true,true):sid(this,g,true),153));i=g.Zj();if(i>1||i==-1){return BD(BD(e,215).hl(a,false),76)}}else{throw vbb(new Wdb(ite+a.ne()+lte))}}else if(a.$j()){return d=this.Yg(a),BD(d>=0?this._g(d,false,true):sid(this,a,false),76)}h=new nGd(this,a);return h};_.yh=function qjd(){return Aid(this)};_.zh=function rjd(){return (NFd(),MFd).S};_.Ah=function sjd(){return aLd(this.zh())};_.Bh=function tjd(a){Cid(this,a)};_.Ib=function ujd(){return Eid(this)};var B5=mdb(qte,'BasicEObjectImpl',97);var zFd;bcb(114,97,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1});_.Ch=function Djd(a){var b;b=xjd(this);return b[a]};_.Dh=function Ejd(a,b){var c;c=xjd(this);NC(c,a,b)};_.Eh=function Fjd(a){var b;b=xjd(this);NC(b,a,null)};_.Jg=function Gjd(){return BD(Ajd(this,4),126)};_.Kg=function Hjd(){throw vbb(new bgb)};_.Lg=function Ijd(){return (this.Db&4)!=0};_.Pg=function Jjd(){throw vbb(new bgb)};_.Fh=function Kjd(a){Cjd(this,2,a)};_.Rg=function Ljd(a,b){this.Db=b<<16|this.Db&255;this.Fh(a)};_.Tg=function Mjd(){return wjd(this)};_.Vg=function Njd(){return this.Db>>16};_.Wg=function Ojd(){var a,b;return nRd(),b=pNd(TKd((a=BD(Ajd(this,16),26),!a?this.zh():a))),b==null?(null,mRd):new qRd(this,b)};_.Mg=function Pjd(){return (this.Db&1)==0};_.Zg=function Qjd(){return BD(Ajd(this,128),1935)};_.$g=function Rjd(){return BD(Ajd(this,16),26)};_.dh=function Sjd(){return (this.Db&32)!=0};_.eh=function Tjd(){return BD(Ajd(this,2),49)};_.kh=function Ujd(){return (this.Db&64)!=0};_.ph=function Vjd(){throw vbb(new bgb)};_.qh=function Wjd(){return BD(Ajd(this,64),281)};_.th=function Xjd(a){Cjd(this,16,a)};_.uh=function Yjd(a){Cjd(this,128,a)};_.vh=function Zjd(a){Cjd(this,64,a)};_.yh=function $jd(){return yjd(this)};_.Db=0;var s8=mdb(qte,'MinimalEObjectImpl',114);bcb(115,114,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1});_.Fh=function _jd(a){this.Cb=a};_.eh=function akd(){return this.Cb};var r8=mdb(qte,'MinimalEObjectImpl/Container',115);bcb(1985,115,{105:1,413:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1});_._g=function kkd(a,b,c){return bkd(this,a,b,c)};_.jh=function lkd(a,b,c){return ckd(this,a,b,c)};_.lh=function mkd(a){return dkd(this,a)};_.sh=function nkd(a,b){ekd(this,a,b)};_.zh=function okd(){return Thd(),Shd};_.Bh=function pkd(a){fkd(this,a)};_.Ve=function qkd(){return gkd(this)};_.We=function rkd(a){return hkd(this,a)};_.Xe=function skd(a){return ikd(this,a)};_.Ye=function tkd(a,b){return jkd(this,a,b)};var H2=mdb(rte,'EMapPropertyHolderImpl',1985);bcb(567,115,{105:1,469:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},xkd);_._g=function ykd(a,b,c){switch(a){case 0:return this.a;case 1:return this.b;}return fid(this,a,b,c)};_.lh=function zkd(a){switch(a){case 0:return this.a!=0;case 1:return this.b!=0;}return mid(this,a)};_.sh=function Akd(a,b){switch(a){case 0:vkd(this,Edb(ED(b)));return;case 1:wkd(this,Edb(ED(b)));return;}yid(this,a,b)};_.zh=function Bkd(){return Thd(),Ihd};_.Bh=function Ckd(a){switch(a){case 0:vkd(this,0);return;case 1:wkd(this,0);return;}Cid(this,a)};_.Ib=function Dkd(){var a;if((this.Db&64)!=0)return Eid(this);a=new Jfb(Eid(this));a.a+=' (x: ';Bfb(a,this.a);a.a+=', y: ';Bfb(a,this.b);a.a+=')';return a.a};_.a=0;_.b=0;var I2=mdb(rte,'ElkBendPointImpl',567);bcb(723,1985,{105:1,413:1,160:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1});_._g=function Nkd(a,b,c){return Ekd(this,a,b,c)};_.hh=function Okd(a,b,c){return Fkd(this,a,b,c)};_.jh=function Pkd(a,b,c){return Gkd(this,a,b,c)};_.lh=function Qkd(a){return Hkd(this,a)};_.sh=function Rkd(a,b){Ikd(this,a,b)};_.zh=function Skd(){return Thd(),Mhd};_.Bh=function Tkd(a){Jkd(this,a)};_.zg=function Ukd(){return this.k};_.Ag=function Vkd(){return Kkd(this)};_.Ib=function Wkd(){return Mkd(this)};_.k=null;var M2=mdb(rte,'ElkGraphElementImpl',723);bcb(724,723,{105:1,413:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1});_._g=function gld(a,b,c){return Xkd(this,a,b,c)};_.lh=function hld(a){return Ykd(this,a)};_.sh=function ild(a,b){Zkd(this,a,b)};_.zh=function jld(){return Thd(),Rhd};_.Bh=function kld(a){$kd(this,a)};_.Bg=function lld(){return this.f};_.Cg=function mld(){return this.g};_.Dg=function nld(){return this.i};_.Eg=function old(){return this.j};_.Fg=function pld(a,b){_kd(this,a,b)};_.Gg=function qld(a,b){bld(this,a,b)};_.Hg=function rld(a){dld(this,a)};_.Ig=function sld(a){eld(this,a)};_.Ib=function tld(){return fld(this)};_.f=0;_.g=0;_.i=0;_.j=0;var T2=mdb(rte,'ElkShapeImpl',724);bcb(725,724,{105:1,413:1,82:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1});_._g=function Bld(a,b,c){return uld(this,a,b,c)};_.hh=function Cld(a,b,c){return vld(this,a,b,c)};_.jh=function Dld(a,b,c){return wld(this,a,b,c)};_.lh=function Eld(a){return xld(this,a)};_.sh=function Fld(a,b){yld(this,a,b)};_.zh=function Gld(){return Thd(),Jhd};_.Bh=function Hld(a){zld(this,a)};_.xg=function Ild(){return !this.d&&(this.d=new y5d(B2,this,8,5)),this.d};_.yg=function Jld(){return !this.e&&(this.e=new y5d(B2,this,7,4)),this.e};var J2=mdb(rte,'ElkConnectableShapeImpl',725);bcb(352,723,{105:1,413:1,79:1,160:1,352:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},Tld);_.Qg=function Uld(a){return Lld(this,a)};_._g=function Vld(a,b,c){switch(a){case 3:return Mld(this);case 4:return !this.b&&(this.b=new y5d(z2,this,4,7)),this.b;case 5:return !this.c&&(this.c=new y5d(z2,this,5,8)),this.c;case 6:return !this.a&&(this.a=new cUd(A2,this,6,6)),this.a;case 7:return Bcb(),!this.b&&(this.b=new y5d(z2,this,4,7)),this.b.i<=1&&(!this.c&&(this.c=new y5d(z2,this,5,8)),this.c.i<=1)?false:true;case 8:return Bcb(),Pld(this)?true:false;case 9:return Bcb(),Qld(this)?true:false;case 10:return Bcb(),!this.b&&(this.b=new y5d(z2,this,4,7)),this.b.i!=0&&(!this.c&&(this.c=new y5d(z2,this,5,8)),this.c.i!=0)?true:false;}return Ekd(this,a,b,c)};_.hh=function Wld(a,b,c){var d;switch(b){case 3:!!this.Cb&&(c=(d=this.Db>>16,d>=0?Lld(this,c):this.Cb.ih(this,-1-d,null,c)));return Kld(this,BD(a,33),c);case 4:return !this.b&&(this.b=new y5d(z2,this,4,7)),Sxd(this.b,a,c);case 5:return !this.c&&(this.c=new y5d(z2,this,5,8)),Sxd(this.c,a,c);case 6:return !this.a&&(this.a=new cUd(A2,this,6,6)),Sxd(this.a,a,c);}return Fkd(this,a,b,c)};_.jh=function Xld(a,b,c){switch(b){case 3:return Kld(this,null,c);case 4:return !this.b&&(this.b=new y5d(z2,this,4,7)),Txd(this.b,a,c);case 5:return !this.c&&(this.c=new y5d(z2,this,5,8)),Txd(this.c,a,c);case 6:return !this.a&&(this.a=new cUd(A2,this,6,6)),Txd(this.a,a,c);}return Gkd(this,a,b,c)};_.lh=function Yld(a){switch(a){case 3:return !!Mld(this);case 4:return !!this.b&&this.b.i!=0;case 5:return !!this.c&&this.c.i!=0;case 6:return !!this.a&&this.a.i!=0;case 7:return !this.b&&(this.b=new y5d(z2,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new y5d(z2,this,5,8)),this.c.i<=1));case 8:return Pld(this);case 9:return Qld(this);case 10:return !this.b&&(this.b=new y5d(z2,this,4,7)),this.b.i!=0&&(!this.c&&(this.c=new y5d(z2,this,5,8)),this.c.i!=0);}return Hkd(this,a)};_.sh=function Zld(a,b){switch(a){case 3:Rld(this,BD(b,33));return;case 4:!this.b&&(this.b=new y5d(z2,this,4,7));Uxd(this.b);!this.b&&(this.b=new y5d(z2,this,4,7));ytd(this.b,BD(b,14));return;case 5:!this.c&&(this.c=new y5d(z2,this,5,8));Uxd(this.c);!this.c&&(this.c=new y5d(z2,this,5,8));ytd(this.c,BD(b,14));return;case 6:!this.a&&(this.a=new cUd(A2,this,6,6));Uxd(this.a);!this.a&&(this.a=new cUd(A2,this,6,6));ytd(this.a,BD(b,14));return;}Ikd(this,a,b)};_.zh=function $ld(){return Thd(),Khd};_.Bh=function _ld(a){switch(a){case 3:Rld(this,null);return;case 4:!this.b&&(this.b=new y5d(z2,this,4,7));Uxd(this.b);return;case 5:!this.c&&(this.c=new y5d(z2,this,5,8));Uxd(this.c);return;case 6:!this.a&&(this.a=new cUd(A2,this,6,6));Uxd(this.a);return;}Jkd(this,a)};_.Ib=function amd(){return Sld(this)};var K2=mdb(rte,'ElkEdgeImpl',352);bcb(439,1985,{105:1,413:1,202:1,439:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},rmd);_.Qg=function smd(a){return cmd(this,a)};_._g=function tmd(a,b,c){switch(a){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return !this.a&&(this.a=new xMd(y2,this,5)),this.a;case 6:return fmd(this);case 7:if(b)return emd(this);return this.i;case 8:if(b)return dmd(this);return this.f;case 9:return !this.g&&(this.g=new y5d(A2,this,9,10)),this.g;case 10:return !this.e&&(this.e=new y5d(A2,this,10,9)),this.e;case 11:return this.d;}return bkd(this,a,b,c)};_.hh=function umd(a,b,c){var d,e,f;switch(b){case 6:!!this.Cb&&(c=(e=this.Db>>16,e>=0?cmd(this,c):this.Cb.ih(this,-1-e,null,c)));return bmd(this,BD(a,79),c);case 9:return !this.g&&(this.g=new y5d(A2,this,9,10)),Sxd(this.g,a,c);case 10:return !this.e&&(this.e=new y5d(A2,this,10,9)),Sxd(this.e,a,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?(Thd(),Lhd):d),b),66),f.Nj().Qj(this,yjd(this),b-aLd((Thd(),Lhd)),a,c)};_.jh=function vmd(a,b,c){switch(b){case 5:return !this.a&&(this.a=new xMd(y2,this,5)),Txd(this.a,a,c);case 6:return bmd(this,null,c);case 9:return !this.g&&(this.g=new y5d(A2,this,9,10)),Txd(this.g,a,c);case 10:return !this.e&&(this.e=new y5d(A2,this,10,9)),Txd(this.e,a,c);}return ckd(this,a,b,c)};_.lh=function wmd(a){switch(a){case 1:return this.j!=0;case 2:return this.k!=0;case 3:return this.b!=0;case 4:return this.c!=0;case 5:return !!this.a&&this.a.i!=0;case 6:return !!fmd(this);case 7:return !!this.i;case 8:return !!this.f;case 9:return !!this.g&&this.g.i!=0;case 10:return !!this.e&&this.e.i!=0;case 11:return this.d!=null;}return dkd(this,a)};_.sh=function xmd(a,b){switch(a){case 1:omd(this,Edb(ED(b)));return;case 2:pmd(this,Edb(ED(b)));return;case 3:hmd(this,Edb(ED(b)));return;case 4:imd(this,Edb(ED(b)));return;case 5:!this.a&&(this.a=new xMd(y2,this,5));Uxd(this.a);!this.a&&(this.a=new xMd(y2,this,5));ytd(this.a,BD(b,14));return;case 6:mmd(this,BD(b,79));return;case 7:lmd(this,BD(b,82));return;case 8:kmd(this,BD(b,82));return;case 9:!this.g&&(this.g=new y5d(A2,this,9,10));Uxd(this.g);!this.g&&(this.g=new y5d(A2,this,9,10));ytd(this.g,BD(b,14));return;case 10:!this.e&&(this.e=new y5d(A2,this,10,9));Uxd(this.e);!this.e&&(this.e=new y5d(A2,this,10,9));ytd(this.e,BD(b,14));return;case 11:jmd(this,GD(b));return;}ekd(this,a,b)};_.zh=function ymd(){return Thd(),Lhd};_.Bh=function zmd(a){switch(a){case 1:omd(this,0);return;case 2:pmd(this,0);return;case 3:hmd(this,0);return;case 4:imd(this,0);return;case 5:!this.a&&(this.a=new xMd(y2,this,5));Uxd(this.a);return;case 6:mmd(this,null);return;case 7:lmd(this,null);return;case 8:kmd(this,null);return;case 9:!this.g&&(this.g=new y5d(A2,this,9,10));Uxd(this.g);return;case 10:!this.e&&(this.e=new y5d(A2,this,10,9));Uxd(this.e);return;case 11:jmd(this,null);return;}fkd(this,a)};_.Ib=function Amd(){return qmd(this)};_.b=0;_.c=0;_.d=null;_.j=0;_.k=0;var L2=mdb(rte,'ElkEdgeSectionImpl',439);bcb(150,115,{105:1,92:1,90:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1});_._g=function Emd(a,b,c){var d;if(a==0){return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab}return bid(this,a-aLd(this.zh()),XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),a),b,c)};_.hh=function Fmd(a,b,c){var d,e;if(b==0){return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c)}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),b),66),e.Nj().Qj(this,yjd(this),b-aLd(this.zh()),a,c)};_.jh=function Gmd(a,b,c){var d,e;if(b==0){return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c)}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),b),66),e.Nj().Rj(this,yjd(this),b-aLd(this.zh()),a,c)};_.lh=function Hmd(a){var b;if(a==0){return !!this.Ab&&this.Ab.i!=0}return cid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.oh=function Imd(a){return Bmd(this,a)};_.sh=function Jmd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;}did(this,a-aLd(this.zh()),XKd((c=BD(Ajd(this,16),26),!c?this.zh():c),a),b)};_.uh=function Kmd(a){Cjd(this,128,a)};_.zh=function Lmd(){return jGd(),ZFd};_.Bh=function Mmd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;}eid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.Gh=function Nmd(){this.Bb|=1};_.Hh=function Omd(a){return Dmd(this,a)};_.Bb=0;var f6=mdb(qte,'EModelElementImpl',150);bcb(704,150,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},$md);_.Ih=function _md(a,b){return Vmd(this,a,b)};_.Jh=function and(a){var b,c,d,e,f;if(this.a!=bKd(a)||(a.Bb&256)!=0){throw vbb(new Wdb(xte+a.zb+ute))}for(d=_Kd(a);VKd(d.a).i!=0;){c=BD(nOd(d,0,(b=BD(qud(VKd(d.a),0),87),f=b.c,JD(f,88)?BD(f,26):(jGd(),_Fd))),26);if(dKd(c)){e=bKd(c).Nh().Jh(c);BD(e,49).th(a);return e}d=_Kd(c)}return (a.D!=null?a.D:a.B)=='java.util.Map$Entry'?new lHd(a):new _Gd(a)};_.Kh=function bnd(a,b){return Wmd(this,a,b)};_._g=function cnd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.a;}return bid(this,a-aLd((jGd(),WFd)),XKd((d=BD(Ajd(this,16),26),!d?WFd:d),a),b,c)};_.hh=function dnd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 1:!!this.a&&(c=BD(this.a,49).ih(this,4,o5,c));return Tmd(this,BD(a,235),c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),WFd):d),b),66),e.Nj().Qj(this,yjd(this),b-aLd((jGd(),WFd)),a,c)};_.jh=function end(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 1:return Tmd(this,null,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),WFd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),WFd)),a,c)};_.lh=function fnd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return !!this.a;}return cid(this,a-aLd((jGd(),WFd)),XKd((b=BD(Ajd(this,16),26),!b?WFd:b),a))};_.sh=function gnd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:Ymd(this,BD(b,235));return;}did(this,a-aLd((jGd(),WFd)),XKd((c=BD(Ajd(this,16),26),!c?WFd:c),a),b)};_.zh=function hnd(){return jGd(),WFd};_.Bh=function ind(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:Ymd(this,null);return;}eid(this,a-aLd((jGd(),WFd)),XKd((b=BD(Ajd(this,16),26),!b?WFd:b),a))};var Pmd,Qmd,Rmd;var d6=mdb(qte,'EFactoryImpl',704);bcb(zte,704,{105:1,2014:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},knd);_.Ih=function lnd(a,b){switch(a.yj()){case 12:return BD(b,146).tg();case 13:return fcb(b);default:throw vbb(new Wdb(tte+a.ne()+ute));}};_.Jh=function mnd(a){var b,c,d,e,f,g,h,i;switch(a.G==-1&&(a.G=(b=bKd(a),b?HLd(b.Mh(),a):-1)),a.G){case 4:return f=new Jod,f;case 6:return g=new apd,g;case 7:return h=new ppd,h;case 8:return d=new Tld,d;case 9:return c=new xkd,c;case 10:return e=new rmd,e;case 11:return i=new Bpd,i;default:throw vbb(new Wdb(xte+a.zb+ute));}};_.Kh=function nnd(a,b){switch(a.yj()){case 13:case 12:return null;default:throw vbb(new Wdb(tte+a.ne()+ute));}};var N2=mdb(rte,'ElkGraphFactoryImpl',zte);bcb(438,150,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1});_.Wg=function rnd(){var a,b;b=(a=BD(Ajd(this,16),26),pNd(TKd(!a?this.zh():a)));return b==null?(nRd(),nRd(),mRd):new GRd(this,b)};_._g=function snd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.ne();}return bid(this,a-aLd(this.zh()),XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),a),b,c)};_.lh=function tnd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;}return cid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.sh=function und(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:this.Lh(GD(b));return;}did(this,a-aLd(this.zh()),XKd((c=BD(Ajd(this,16),26),!c?this.zh():c),a),b)};_.zh=function vnd(){return jGd(),$Fd};_.Bh=function wnd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:this.Lh(null);return;}eid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.ne=function xnd(){return this.zb};_.Lh=function ynd(a){pnd(this,a)};_.Ib=function znd(){return qnd(this)};_.zb=null;var j6=mdb(qte,'ENamedElementImpl',438);bcb(179,438,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},eod);_.Qg=function god(a){return Snd(this,a)};_._g=function hod(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return !this.rb&&(this.rb=new jUd(this,d5,this)),this.rb;case 6:return !this.vb&&(this.vb=new gUd(o5,this,6,7)),this.vb;case 7:if(b)return this.Db>>16==7?BD(this.Cb,235):null;return Ind(this);}return bid(this,a-aLd((jGd(),cGd)),XKd((d=BD(Ajd(this,16),26),!d?cGd:d),a),b,c)};_.hh=function iod(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 4:!!this.sb&&(c=BD(this.sb,49).ih(this,1,i5,c));return Jnd(this,BD(a,471),c);case 5:return !this.rb&&(this.rb=new jUd(this,d5,this)),Sxd(this.rb,a,c);case 6:return !this.vb&&(this.vb=new gUd(o5,this,6,7)),Sxd(this.vb,a,c);case 7:!!this.Cb&&(c=(e=this.Db>>16,e>=0?Snd(this,c):this.Cb.ih(this,-1-e,null,c)));return _hd(this,a,7,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),cGd):d),b),66),f.Nj().Qj(this,yjd(this),b-aLd((jGd(),cGd)),a,c)};_.jh=function jod(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 4:return Jnd(this,null,c);case 5:return !this.rb&&(this.rb=new jUd(this,d5,this)),Txd(this.rb,a,c);case 6:return !this.vb&&(this.vb=new gUd(o5,this,6,7)),Txd(this.vb,a,c);case 7:return _hd(this,null,7,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),cGd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),cGd)),a,c)};_.lh=function kod(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.yb!=null;case 3:return this.xb!=null;case 4:return !!this.sb;case 5:return !!this.rb&&this.rb.i!=0;case 6:return !!this.vb&&this.vb.i!=0;case 7:return !!Ind(this);}return cid(this,a-aLd((jGd(),cGd)),XKd((b=BD(Ajd(this,16),26),!b?cGd:b),a))};_.oh=function lod(a){var b;b=Und(this,a);return b?b:Bmd(this,a)};_.sh=function mod(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:pnd(this,GD(b));return;case 2:dod(this,GD(b));return;case 3:cod(this,GD(b));return;case 4:bod(this,BD(b,471));return;case 5:!this.rb&&(this.rb=new jUd(this,d5,this));Uxd(this.rb);!this.rb&&(this.rb=new jUd(this,d5,this));ytd(this.rb,BD(b,14));return;case 6:!this.vb&&(this.vb=new gUd(o5,this,6,7));Uxd(this.vb);!this.vb&&(this.vb=new gUd(o5,this,6,7));ytd(this.vb,BD(b,14));return;}did(this,a-aLd((jGd(),cGd)),XKd((c=BD(Ajd(this,16),26),!c?cGd:c),a),b)};_.vh=function nod(a){var b,c;if(!!a&&!!this.rb){for(c=new Fyd(this.rb);c.e!=c.i.gc();){b=Dyd(c);JD(b,351)&&(BD(b,351).w=null)}}Cjd(this,64,a)};_.zh=function ood(){return jGd(),cGd};_.Bh=function pod(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:pnd(this,null);return;case 2:dod(this,null);return;case 3:cod(this,null);return;case 4:bod(this,null);return;case 5:!this.rb&&(this.rb=new jUd(this,d5,this));Uxd(this.rb);return;case 6:!this.vb&&(this.vb=new gUd(o5,this,6,7));Uxd(this.vb);return;}eid(this,a-aLd((jGd(),cGd)),XKd((b=BD(Ajd(this,16),26),!b?cGd:b),a))};_.Gh=function qod(){Tnd(this)};_.Mh=function rod(){return !this.rb&&(this.rb=new jUd(this,d5,this)),this.rb};_.Nh=function sod(){return this.sb};_.Oh=function tod(){return this.ub};_.Ph=function uod(){return this.xb};_.Qh=function vod(){return this.yb};_.Rh=function wod(a){this.ub=a};_.Ib=function xod(){var a;if((this.Db&64)!=0)return qnd(this);a=new Jfb(qnd(this));a.a+=' (nsURI: ';Efb(a,this.yb);a.a+=', nsPrefix: ';Efb(a,this.xb);a.a+=')';return a.a};_.xb=null;_.yb=null;var And;var t6=mdb(qte,'EPackageImpl',179);bcb(555,179,{105:1,2016:1,555:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},Bod);_.q=false;_.r=false;var yod=false;var O2=mdb(rte,'ElkGraphPackageImpl',555);bcb(354,724,{105:1,413:1,160:1,137:1,470:1,354:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},Jod);_.Qg=function Kod(a){return Eod(this,a)};_._g=function Lod(a,b,c){switch(a){case 7:return Fod(this);case 8:return this.a;}return Xkd(this,a,b,c)};_.hh=function Mod(a,b,c){var d;switch(b){case 7:!!this.Cb&&(c=(d=this.Db>>16,d>=0?Eod(this,c):this.Cb.ih(this,-1-d,null,c)));return Dod(this,BD(a,160),c);}return Fkd(this,a,b,c)};_.jh=function Nod(a,b,c){if(b==7){return Dod(this,null,c)}return Gkd(this,a,b,c)};_.lh=function Ood(a){switch(a){case 7:return !!Fod(this);case 8:return !dfb('',this.a);}return Ykd(this,a)};_.sh=function Pod(a,b){switch(a){case 7:God(this,BD(b,160));return;case 8:Hod(this,GD(b));return;}Zkd(this,a,b)};_.zh=function Qod(){return Thd(),Nhd};_.Bh=function Rod(a){switch(a){case 7:God(this,null);return;case 8:Hod(this,'');return;}$kd(this,a)};_.Ib=function Sod(){return Iod(this)};_.a='';var P2=mdb(rte,'ElkLabelImpl',354);bcb(239,725,{105:1,413:1,82:1,160:1,33:1,470:1,239:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},apd);_.Qg=function bpd(a){return Uod(this,a)};_._g=function cpd(a,b,c){switch(a){case 9:return !this.c&&(this.c=new cUd(F2,this,9,9)),this.c;case 10:return !this.a&&(this.a=new cUd(E2,this,10,11)),this.a;case 11:return Xod(this);case 12:return !this.b&&(this.b=new cUd(B2,this,12,3)),this.b;case 13:return Bcb(),!this.a&&(this.a=new cUd(E2,this,10,11)),this.a.i>0?true:false;}return uld(this,a,b,c)};_.hh=function dpd(a,b,c){var d;switch(b){case 9:return !this.c&&(this.c=new cUd(F2,this,9,9)),Sxd(this.c,a,c);case 10:return !this.a&&(this.a=new cUd(E2,this,10,11)),Sxd(this.a,a,c);case 11:!!this.Cb&&(c=(d=this.Db>>16,d>=0?Uod(this,c):this.Cb.ih(this,-1-d,null,c)));return Tod(this,BD(a,33),c);case 12:return !this.b&&(this.b=new cUd(B2,this,12,3)),Sxd(this.b,a,c);}return vld(this,a,b,c)};_.jh=function epd(a,b,c){switch(b){case 9:return !this.c&&(this.c=new cUd(F2,this,9,9)),Txd(this.c,a,c);case 10:return !this.a&&(this.a=new cUd(E2,this,10,11)),Txd(this.a,a,c);case 11:return Tod(this,null,c);case 12:return !this.b&&(this.b=new cUd(B2,this,12,3)),Txd(this.b,a,c);}return wld(this,a,b,c)};_.lh=function fpd(a){switch(a){case 9:return !!this.c&&this.c.i!=0;case 10:return !!this.a&&this.a.i!=0;case 11:return !!Xod(this);case 12:return !!this.b&&this.b.i!=0;case 13:return !this.a&&(this.a=new cUd(E2,this,10,11)),this.a.i>0;}return xld(this,a)};_.sh=function gpd(a,b){switch(a){case 9:!this.c&&(this.c=new cUd(F2,this,9,9));Uxd(this.c);!this.c&&(this.c=new cUd(F2,this,9,9));ytd(this.c,BD(b,14));return;case 10:!this.a&&(this.a=new cUd(E2,this,10,11));Uxd(this.a);!this.a&&(this.a=new cUd(E2,this,10,11));ytd(this.a,BD(b,14));return;case 11:$od(this,BD(b,33));return;case 12:!this.b&&(this.b=new cUd(B2,this,12,3));Uxd(this.b);!this.b&&(this.b=new cUd(B2,this,12,3));ytd(this.b,BD(b,14));return;}yld(this,a,b)};_.zh=function hpd(){return Thd(),Ohd};_.Bh=function ipd(a){switch(a){case 9:!this.c&&(this.c=new cUd(F2,this,9,9));Uxd(this.c);return;case 10:!this.a&&(this.a=new cUd(E2,this,10,11));Uxd(this.a);return;case 11:$od(this,null);return;case 12:!this.b&&(this.b=new cUd(B2,this,12,3));Uxd(this.b);return;}zld(this,a)};_.Ib=function jpd(){return _od(this)};var Q2=mdb(rte,'ElkNodeImpl',239);bcb(186,725,{105:1,413:1,82:1,160:1,118:1,470:1,186:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},ppd);_.Qg=function qpd(a){return lpd(this,a)};_._g=function rpd(a,b,c){if(a==9){return mpd(this)}return uld(this,a,b,c)};_.hh=function spd(a,b,c){var d;switch(b){case 9:!!this.Cb&&(c=(d=this.Db>>16,d>=0?lpd(this,c):this.Cb.ih(this,-1-d,null,c)));return kpd(this,BD(a,33),c);}return vld(this,a,b,c)};_.jh=function tpd(a,b,c){if(b==9){return kpd(this,null,c)}return wld(this,a,b,c)};_.lh=function upd(a){if(a==9){return !!mpd(this)}return xld(this,a)};_.sh=function vpd(a,b){switch(a){case 9:npd(this,BD(b,33));return;}yld(this,a,b)};_.zh=function wpd(){return Thd(),Phd};_.Bh=function xpd(a){switch(a){case 9:npd(this,null);return;}zld(this,a)};_.Ib=function ypd(){return opd(this)};var R2=mdb(rte,'ElkPortImpl',186);var J4=odb(Tte,'BasicEMap/Entry');bcb(1092,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,114:1,115:1},Bpd);_.Fb=function Hpd(a){return this===a};_.cd=function Jpd(){return this.b};_.Hb=function Lpd(){return FCb(this)};_.Uh=function Npd(a){zpd(this,BD(a,146))};_._g=function Cpd(a,b,c){switch(a){case 0:return this.b;case 1:return this.c;}return fid(this,a,b,c)};_.lh=function Dpd(a){switch(a){case 0:return !!this.b;case 1:return this.c!=null;}return mid(this,a)};_.sh=function Epd(a,b){switch(a){case 0:zpd(this,BD(b,146));return;case 1:Apd(this,b);return;}yid(this,a,b)};_.zh=function Fpd(){return Thd(),Qhd};_.Bh=function Gpd(a){switch(a){case 0:zpd(this,null);return;case 1:Apd(this,null);return;}Cid(this,a)};_.Sh=function Ipd(){var a;if(this.a==-1){a=this.b;this.a=!a?0:tb(a)}return this.a};_.dd=function Kpd(){return this.c};_.Th=function Mpd(a){this.a=a};_.ed=function Opd(a){var b;b=this.c;Apd(this,a);return b};_.Ib=function Ppd(){var a;if((this.Db&64)!=0)return Eid(this);a=new Ufb;Qfb(Qfb(Qfb(a,this.b?this.b.tg():Xhe),gne),xfb(this.c));return a.a};_.a=-1;_.c=null;var S2=mdb(rte,'ElkPropertyToValueMapEntryImpl',1092);bcb(984,1,{},bqd);var U2=mdb(Wte,'JsonAdapter',984);bcb(210,60,Tie,cqd);var V2=mdb(Wte,'JsonImportException',210);bcb(857,1,{},ird);var J3=mdb(Wte,'JsonImporter',857);bcb(891,1,{},jrd);var W2=mdb(Wte,'JsonImporter/lambda$0$Type',891);bcb(892,1,{},krd);var X2=mdb(Wte,'JsonImporter/lambda$1$Type',892);bcb(900,1,{},lrd);var Y2=mdb(Wte,'JsonImporter/lambda$10$Type',900);bcb(902,1,{},mrd);var Z2=mdb(Wte,'JsonImporter/lambda$11$Type',902);bcb(903,1,{},nrd);var $2=mdb(Wte,'JsonImporter/lambda$12$Type',903);bcb(909,1,{},ord);var _2=mdb(Wte,'JsonImporter/lambda$13$Type',909);bcb(908,1,{},prd);var a3=mdb(Wte,'JsonImporter/lambda$14$Type',908);bcb(904,1,{},qrd);var b3=mdb(Wte,'JsonImporter/lambda$15$Type',904);bcb(905,1,{},rrd);var c3=mdb(Wte,'JsonImporter/lambda$16$Type',905);bcb(906,1,{},srd);var d3=mdb(Wte,'JsonImporter/lambda$17$Type',906);bcb(907,1,{},trd);var e3=mdb(Wte,'JsonImporter/lambda$18$Type',907);bcb(912,1,{},urd);var f3=mdb(Wte,'JsonImporter/lambda$19$Type',912);bcb(893,1,{},vrd);var g3=mdb(Wte,'JsonImporter/lambda$2$Type',893);bcb(910,1,{},wrd);var h3=mdb(Wte,'JsonImporter/lambda$20$Type',910);bcb(911,1,{},xrd);var i3=mdb(Wte,'JsonImporter/lambda$21$Type',911);bcb(915,1,{},yrd);var j3=mdb(Wte,'JsonImporter/lambda$22$Type',915);bcb(913,1,{},zrd);var k3=mdb(Wte,'JsonImporter/lambda$23$Type',913);bcb(914,1,{},Ard);var l3=mdb(Wte,'JsonImporter/lambda$24$Type',914);bcb(917,1,{},Brd);var m3=mdb(Wte,'JsonImporter/lambda$25$Type',917);bcb(916,1,{},Crd);var n3=mdb(Wte,'JsonImporter/lambda$26$Type',916);bcb(918,1,qie,Drd);_.td=function Erd(a){Bqd(this.b,this.a,GD(a))};var o3=mdb(Wte,'JsonImporter/lambda$27$Type',918);bcb(919,1,qie,Frd);_.td=function Grd(a){Cqd(this.b,this.a,GD(a))};var p3=mdb(Wte,'JsonImporter/lambda$28$Type',919);bcb(920,1,{},Hrd);var q3=mdb(Wte,'JsonImporter/lambda$29$Type',920);bcb(896,1,{},Ird);var r3=mdb(Wte,'JsonImporter/lambda$3$Type',896);bcb(921,1,{},Jrd);var s3=mdb(Wte,'JsonImporter/lambda$30$Type',921);bcb(922,1,{},Krd);var t3=mdb(Wte,'JsonImporter/lambda$31$Type',922);bcb(923,1,{},Lrd);var u3=mdb(Wte,'JsonImporter/lambda$32$Type',923);bcb(924,1,{},Mrd);var v3=mdb(Wte,'JsonImporter/lambda$33$Type',924);bcb(925,1,{},Nrd);var w3=mdb(Wte,'JsonImporter/lambda$34$Type',925);bcb(859,1,{},Prd);var x3=mdb(Wte,'JsonImporter/lambda$35$Type',859);bcb(929,1,{},Rrd);var y3=mdb(Wte,'JsonImporter/lambda$36$Type',929);bcb(926,1,qie,Srd);_.td=function Trd(a){Lqd(this.a,BD(a,469))};var z3=mdb(Wte,'JsonImporter/lambda$37$Type',926);bcb(927,1,qie,Urd);_.td=function Vrd(a){Mqd(this.a,this.b,BD(a,202))};var A3=mdb(Wte,'JsonImporter/lambda$38$Type',927);bcb(928,1,qie,Wrd);_.td=function Xrd(a){Nqd(this.a,this.b,BD(a,202))};var B3=mdb(Wte,'JsonImporter/lambda$39$Type',928);bcb(894,1,{},Yrd);var C3=mdb(Wte,'JsonImporter/lambda$4$Type',894);bcb(930,1,qie,Zrd);_.td=function $rd(a){Oqd(this.a,BD(a,8))};var D3=mdb(Wte,'JsonImporter/lambda$40$Type',930);bcb(895,1,{},_rd);var E3=mdb(Wte,'JsonImporter/lambda$5$Type',895);bcb(899,1,{},asd);var F3=mdb(Wte,'JsonImporter/lambda$6$Type',899);bcb(897,1,{},bsd);var G3=mdb(Wte,'JsonImporter/lambda$7$Type',897);bcb(898,1,{},csd);var H3=mdb(Wte,'JsonImporter/lambda$8$Type',898);bcb(901,1,{},dsd);var I3=mdb(Wte,'JsonImporter/lambda$9$Type',901);bcb(948,1,qie,msd);_.td=function nsd(a){Qpd(this.a,new yC(GD(a)))};var K3=mdb(Wte,'JsonMetaDataConverter/lambda$0$Type',948);bcb(949,1,qie,osd);_.td=function psd(a){isd(this.a,BD(a,237))};var L3=mdb(Wte,'JsonMetaDataConverter/lambda$1$Type',949);bcb(950,1,qie,qsd);_.td=function rsd(a){jsd(this.a,BD(a,149))};var M3=mdb(Wte,'JsonMetaDataConverter/lambda$2$Type',950);bcb(951,1,qie,ssd);_.td=function tsd(a){ksd(this.a,BD(a,175))};var N3=mdb(Wte,'JsonMetaDataConverter/lambda$3$Type',951);bcb(237,22,{3:1,35:1,22:1,237:1},Dsd);var usd,vsd,wsd,xsd,ysd,zsd,Asd,Bsd;var O3=ndb(Hle,'GraphFeature',237,CI,Fsd,Esd);var Gsd;bcb(13,1,{35:1,146:1},Lsd,Msd,Nsd,Osd);_.wd=function Psd(a){return Isd(this,BD(a,146))};_.Fb=function Qsd(a){return Jsd(this,a)};_.wg=function Rsd(){return Ksd(this)};_.tg=function Ssd(){return this.b};_.Hb=function Tsd(){return LCb(this.b)};_.Ib=function Usd(){return this.b};var T3=mdb(Hle,'Property',13);bcb(818,1,Dke,Wsd);_.ue=function Xsd(a,b){return Vsd(this,BD(a,94),BD(b,94))};_.Fb=function Ysd(a){return this===a};_.ve=function Zsd(){return new tpb(this)};var S3=mdb(Hle,'PropertyHolderComparator',818);bcb(695,1,aie,qtd);_.Nb=function rtd(a){Rrb(this,a)};_.Pb=function ttd(){return ptd(this)};_.Qb=function utd(){Srb()};_.Ob=function std(){return !!this.a};var U3=mdb(jue,'ElkGraphUtil/AncestorIterator',695);var T4=odb(Tte,'EList');bcb(67,52,{20:1,28:1,52:1,14:1,15:1,67:1,58:1});_.Vc=function Jtd(a,b){vtd(this,a,b)};_.Fc=function Ktd(a){return wtd(this,a)};_.Wc=function Ltd(a,b){return xtd(this,a,b)};_.Gc=function Mtd(a){return ytd(this,a)};_.Zh=function Ntd(){return new $yd(this)};_.$h=function Otd(){return new bzd(this)};_._h=function Ptd(a){return ztd(this,a)};_.ai=function Qtd(){return true};_.bi=function Rtd(a,b){};_.ci=function Std(){};_.di=function Ttd(a,b){Atd(this,a,b)};_.ei=function Utd(a,b,c){};_.fi=function Vtd(a,b){};_.gi=function Wtd(a,b,c){};_.Fb=function Xtd(a){return Btd(this,a)};_.Hb=function Ytd(){return Etd(this)};_.hi=function Ztd(){return false};_.Kc=function $td(){return new Fyd(this)};_.Yc=function _td(){return new Oyd(this)};_.Zc=function aud(a){var b;b=this.gc();if(a<0||a>b)throw vbb(new Cyd(a,b));return new Pyd(this,a)};_.ji=function bud(a,b){this.ii(a,this.Xc(b))};_.Mc=function cud(a){return Ftd(this,a)};_.li=function dud(a,b){return b};_._c=function eud(a,b){return Gtd(this,a,b)};_.Ib=function fud(){return Htd(this)};_.ni=function gud(){return true};_.oi=function hud(a,b){return Itd(this,b)};var p4=mdb(Tte,'AbstractEList',67);bcb(63,67,oue,yud,zud,Aud);_.Vh=function Bud(a,b){return iud(this,a,b)};_.Wh=function Cud(a){return jud(this,a)};_.Xh=function Dud(a,b){kud(this,a,b)};_.Yh=function Eud(a){lud(this,a)};_.pi=function Fud(a){return nud(this,a)};_.$b=function Gud(){oud(this)};_.Hc=function Hud(a){return pud(this,a)};_.Xb=function Iud(a){return qud(this,a)};_.qi=function Jud(a){var b,c,d;++this.j;c=this.g==null?0:this.g.length;if(a>c){d=this.g;b=c+(c/2|0)+4;b<a&&(b=a);this.g=this.ri(b);d!=null&&$fb(d,0,this.g,0,this.i)}};_.Xc=function Kud(a){return rud(this,a)};_.dc=function Lud(){return this.i==0};_.ii=function Mud(a,b){return sud(this,a,b)};_.ri=function Nud(a){return KC(SI,Uhe,1,a,5,1)};_.ki=function Oud(a){return this.g[a]};_.$c=function Pud(a){return tud(this,a)};_.mi=function Qud(a,b){return uud(this,a,b)};_.gc=function Rud(){return this.i};_.Pc=function Sud(){return wud(this)};_.Qc=function Tud(a){return xud(this,a)};_.i=0;var y4=mdb(Tte,'BasicEList',63);var X4=odb(Tte,'TreeIterator');bcb(694,63,pue);_.Nb=function Xud(a){Rrb(this,a)};_.Ob=function Yud(){return this.g==null&&!this.c?Uud(this):this.g==null||this.i!=0&&BD(this.g[this.i-1],47).Ob()};_.Pb=function Zud(){return Vud(this)};_.Qb=function $ud(){if(!this.e){throw vbb(new Zdb('There is no valid object to remove.'))}this.e.Qb()};_.c=false;var q4=mdb(Tte,'AbstractTreeIterator',694);bcb(685,694,pue,_ud);_.si=function avd(a){var b;b=BD(a,56).Wg().Kc();JD(b,279)&&BD(b,279).Nk(new bvd);return b};var W3=mdb(jue,'ElkGraphUtil/PropertiesSkippingTreeIterator',685);bcb(952,1,{},bvd);var V3=mdb(jue,'ElkGraphUtil/PropertiesSkippingTreeIterator/1',952);var cvd,dvd;var Y3=mdb(jue,'ElkReflect',null);bcb(889,1,hse,jvd);_.vg=function kvd(a){return evd(),sqb(BD(a,174))};var X3=mdb(jue,'ElkReflect/lambda$0$Type',889);var lvd;var W4=odb(Tte,'ResourceLocator');bcb(1051,1,{});var N4=mdb(Tte,'DelegatingResourceLocator',1051);bcb(1052,1051,{});var Z3=mdb('org.eclipse.emf.common','EMFPlugin',1052);var $3=odb(cve,'Adapter');var _3=odb(cve,'Notification');bcb(1153,1,dve);_.ti=function vvd(){return this.d};_.ui=function wvd(a){};_.vi=function xvd(a){this.d=a};_.wi=function yvd(a){this.d==a&&(this.d=null)};_.d=null;var a4=mdb(hte,'AdapterImpl',1153);bcb(1995,67,eve);_.Vh=function Fvd(a,b){return zvd(this,a,b)};_.Wh=function Gvd(a){var b,c,d;++this.j;if(a.dc()){return false}else{b=this.Vi();for(d=a.Kc();d.Ob();){c=d.Pb();this.Ii(this.oi(b,c));++b}return true}};_.Xh=function Hvd(a,b){Avd(this,a,b)};_.Yh=function Ivd(a){Bvd(this,a)};_.Gi=function Jvd(){return this.Ji()};_.$b=function Kvd(){Cvd(this,this.Vi(),this.Wi())};_.Hc=function Lvd(a){return this.Li(a)};_.Ic=function Mvd(a){return this.Mi(a)};_.Hi=function Nvd(a,b){this.Si().jm()};_.Ii=function Ovd(a){this.Si().jm()};_.Ji=function Pvd(){return this.Si()};_.Ki=function Qvd(){this.Si().jm()};_.Li=function Rvd(a){return this.Si().jm()};_.Mi=function Svd(a){return this.Si().jm()};_.Ni=function Tvd(a){return this.Si().jm()};_.Oi=function Uvd(a){return this.Si().jm()};_.Pi=function Vvd(){return this.Si().jm()};_.Qi=function Wvd(a){return this.Si().jm()};_.Ri=function Xvd(){return this.Si().jm()};_.Ti=function Yvd(a){return this.Si().jm()};_.Ui=function Zvd(a,b){return this.Si().jm()};_.Vi=function $vd(){return this.Si().jm()};_.Wi=function _vd(){return this.Si().jm()};_.Xi=function awd(a){return this.Si().jm()};_.Yi=function bwd(){return this.Si().jm()};_.Fb=function cwd(a){return this.Ni(a)};_.Xb=function dwd(a){return this.li(a,this.Oi(a))};_.Hb=function ewd(){return this.Pi()};_.Xc=function fwd(a){return this.Qi(a)};_.dc=function gwd(){return this.Ri()};_.ii=function hwd(a,b){return Dvd(this,a,b)};_.ki=function iwd(a){return this.Oi(a)};_.$c=function jwd(a){return Evd(this,a)};_.Mc=function kwd(a){var b;b=this.Xc(a);if(b>=0){this.$c(b);return true}else{return false}};_.mi=function lwd(a,b){return this.Ui(a,this.oi(a,b))};_.gc=function mwd(){return this.Vi()};_.Pc=function nwd(){return this.Wi()};_.Qc=function owd(a){return this.Xi(a)};_.Ib=function pwd(){return this.Yi()};var M4=mdb(Tte,'DelegatingEList',1995);bcb(1996,1995,eve);_.Vh=function xwd(a,b){return qwd(this,a,b)};_.Wh=function ywd(a){return this.Vh(this.Vi(),a)};_.Xh=function zwd(a,b){rwd(this,a,b)};_.Yh=function Awd(a){swd(this,a)};_.ai=function Bwd(){return !this.bj()};_.$b=function Cwd(){vwd(this)};_.Zi=function Dwd(a,b,c,d,e){return new Cxd(this,a,b,c,d,e)};_.$i=function Ewd(a){Uhd(this.Ai(),a)};_._i=function Fwd(){return null};_.aj=function Gwd(){return -1};_.Ai=function Hwd(){return null};_.bj=function Iwd(){return false};_.cj=function Jwd(a,b){return b};_.dj=function Kwd(a,b){return b};_.ej=function Lwd(){return false};_.fj=function Mwd(){return !this.Ri()};_.ii=function Nwd(a,b){var c,d;if(this.ej()){d=this.fj();c=Dvd(this,a,b);this.$i(this.Zi(7,meb(b),c,a,d));return c}else{return Dvd(this,a,b)}};_.$c=function Owd(a){var b,c,d,e;if(this.ej()){c=null;d=this.fj();b=this.Zi(4,e=Evd(this,a),null,a,d);if(this.bj()&&!!e){c=this.dj(e,c);if(!c){this.$i(b)}else{c.Ei(b);c.Fi()}}else{if(!c){this.$i(b)}else{c.Ei(b);c.Fi()}}return e}else{e=Evd(this,a);if(this.bj()&&!!e){c=this.dj(e,null);!!c&&c.Fi()}return e}};_.mi=function Pwd(a,b){return wwd(this,a,b)};var d4=mdb(hte,'DelegatingNotifyingListImpl',1996);bcb(143,1,fve);_.Ei=function pxd(a){return Qwd(this,a)};_.Fi=function qxd(){Rwd(this)};_.xi=function rxd(){return this.d};_._i=function sxd(){return null};_.gj=function txd(){return null};_.yi=function uxd(a){return -1};_.zi=function vxd(){return $wd(this)};_.Ai=function wxd(){return null};_.Bi=function xxd(){return hxd(this)};_.Ci=function yxd(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o};_.hj=function zxd(){return false};_.Di=function Axd(a){var b,c,d,e,f,g,h,i,j,k,l;switch(this.d){case 1:case 2:{e=a.xi();switch(e){case 1:case 2:{f=a.Ai();if(PD(f)===PD(this.Ai())&&this.yi(null)==a.yi(null)){this.g=a.zi();a.xi()==1&&(this.d=1);return true}}}}case 4:{e=a.xi();switch(e){case 4:{f=a.Ai();if(PD(f)===PD(this.Ai())&&this.yi(null)==a.yi(null)){j=jxd(this);i=this.o<0?this.o<-2?-2-this.o-1:-1:this.o;g=a.Ci();this.d=6;l=new zud(2);if(i<=g){wtd(l,this.n);wtd(l,a.Bi());this.g=OC(GC(WD,1),oje,25,15,[this.o=i,g+1])}else{wtd(l,a.Bi());wtd(l,this.n);this.g=OC(GC(WD,1),oje,25,15,[this.o=g,i])}this.n=l;j||(this.o=-2-this.o-1);return true}break}}break}case 6:{e=a.xi();switch(e){case 4:{f=a.Ai();if(PD(f)===PD(this.Ai())&&this.yi(null)==a.yi(null)){j=jxd(this);g=a.Ci();k=BD(this.g,48);d=KC(WD,oje,25,k.length+1,15,1);b=0;while(b<k.length){h=k[b];if(h<=g){d[b++]=h;++g}else{break}}c=BD(this.n,15);c.Vc(b,a.Bi());d[b]=g;while(++b<d.length){d[b]=k[b-1]}this.g=d;j||(this.o=-2-d[0]);return true}break}}break}}return false};_.Ib=function Bxd(){var a,b,c,d;d=new Jfb(hdb(this.gm)+'@'+(b=tb(this)>>>0,b.toString(16)));d.a+=' (eventType: ';switch(this.d){case 1:{d.a+='SET';break}case 2:{d.a+='UNSET';break}case 3:{d.a+='ADD';break}case 5:{d.a+='ADD_MANY';break}case 4:{d.a+='REMOVE';break}case 6:{d.a+='REMOVE_MANY';break}case 7:{d.a+='MOVE';break}case 8:{d.a+='REMOVING_ADAPTER';break}case 9:{d.a+='RESOLVE';break}default:{Cfb(d,this.d);break}}ixd(this)&&(d.a+=', touch: true',d);d.a+=', position: ';Cfb(d,this.o<0?this.o<-2?-2-this.o-1:-1:this.o);d.a+=', notifier: ';Dfb(d,this.Ai());d.a+=', feature: ';Dfb(d,this._i());d.a+=', oldValue: ';Dfb(d,hxd(this));d.a+=', newValue: ';if(this.d==6&&JD(this.g,48)){c=BD(this.g,48);d.a+='[';for(a=0;a<c.length;){d.a+=c[a];++a<c.length&&(d.a+=She,d)}d.a+=']'}else{Dfb(d,$wd(this))}d.a+=', isTouch: ';Ffb(d,ixd(this));d.a+=', wasSet: ';Ffb(d,jxd(this));d.a+=')';return d.a};_.d=0;_.e=0;_.f=0;_.j=0;_.k=0;_.o=0;_.p=0;var f4=mdb(hte,'NotificationImpl',143);bcb(1167,143,fve,Cxd);_._i=function Dxd(){return this.a._i()};_.yi=function Exd(a){return this.a.aj()};_.Ai=function Fxd(){return this.a.Ai()};var c4=mdb(hte,'DelegatingNotifyingListImpl/1',1167);bcb(242,63,oue,Hxd,Ixd);_.Fc=function Jxd(a){return Gxd(this,BD(a,366))};_.Ei=function Kxd(a){return Gxd(this,a)};_.Fi=function Lxd(){var a,b,c;for(a=0;a<this.i;++a){b=BD(this.g[a],366);c=b.Ai();c!=null&&b.xi()!=-1&&BD(c,92).Ng(b)}};_.ri=function Mxd(a){return KC(_3,Uhe,366,a,0,1)};var e4=mdb(hte,'NotificationChainImpl',242);bcb(1378,90,gte);_.Kg=function Nxd(){return this.e};_.Mg=function Oxd(){return (this.f&1)!=0};_.f=1;var g4=mdb(hte,'NotifierImpl',1378);bcb(1993,63,oue);_.Vh=function $xd(a,b){return Pxd(this,a,b)};_.Wh=function _xd(a){return this.Vh(this.i,a)};_.Xh=function ayd(a,b){Qxd(this,a,b)};_.Yh=function byd(a){Rxd(this,a)};_.ai=function cyd(){return !this.bj()};_.$b=function dyd(){Uxd(this)};_.Zi=function eyd(a,b,c,d,e){return new vyd(this,a,b,c,d,e)};_.$i=function fyd(a){Uhd(this.Ai(),a)};_._i=function gyd(){return null};_.aj=function hyd(){return -1};_.Ai=function iyd(){return null};_.bj=function jyd(){return false};_.ij=function kyd(){return false};_.cj=function lyd(a,b){return b};_.dj=function myd(a,b){return b};_.ej=function nyd(){return false};_.fj=function oyd(){return this.i!=0};_.ii=function pyd(a,b){return Wxd(this,a,b)};_.$c=function qyd(a){return Xxd(this,a)};_.mi=function ryd(a,b){return Zxd(this,a,b)};_.jj=function syd(a,b){return b};_.kj=function tyd(a,b){return b};_.lj=function uyd(a,b,c){return c};var i4=mdb(hte,'NotifyingListImpl',1993);bcb(1166,143,fve,vyd);_._i=function wyd(){return this.a._i()};_.yi=function xyd(a){return this.a.aj()};_.Ai=function yyd(){return this.a.Ai()};var h4=mdb(hte,'NotifyingListImpl/1',1166);bcb(953,63,oue,zyd);_.Hc=function Ayd(a){if(this.i>10){if(!this.b||this.c.j!=this.a){this.b=new Vqb(this);this.a=this.j}return Rqb(this.b,a)}else{return pud(this,a)}};_.ni=function Byd(){return true};_.a=0;var j4=mdb(Tte,'AbstractEList/1',953);bcb(295,73,Mje,Cyd);var k4=mdb(Tte,'AbstractEList/BasicIndexOutOfBoundsException',295);bcb(40,1,aie,Fyd);_.Nb=function Iyd(a){Rrb(this,a)};_.mj=function Gyd(){if(this.i.j!=this.f){throw vbb(new Apb)}};_.nj=function Hyd(){return Dyd(this)};_.Ob=function Jyd(){return this.e!=this.i.gc()};_.Pb=function Kyd(){return this.nj()};_.Qb=function Lyd(){Eyd(this)};_.e=0;_.f=0;_.g=-1;var l4=mdb(Tte,'AbstractEList/EIterator',40);bcb(278,40,jie,Oyd,Pyd);_.Qb=function Xyd(){Eyd(this)};_.Rb=function Qyd(a){Myd(this,a)};_.oj=function Ryd(){var b;try{b=this.d.Xb(--this.e);this.mj();this.g=this.e;return b}catch(a){a=ubb(a);if(JD(a,73)){this.mj();throw vbb(new utb)}else throw vbb(a)}};_.pj=function Syd(a){Nyd(this,a)};_.Sb=function Tyd(){return this.e!=0};_.Tb=function Uyd(){return this.e};_.Ub=function Vyd(){return this.oj()};_.Vb=function Wyd(){return this.e-1};_.Wb=function Yyd(a){this.pj(a)};var m4=mdb(Tte,'AbstractEList/EListIterator',278);bcb(341,40,aie,$yd);_.nj=function _yd(){return Zyd(this)};_.Qb=function azd(){throw vbb(new bgb)};var n4=mdb(Tte,'AbstractEList/NonResolvingEIterator',341);bcb(385,278,jie,bzd,czd);_.Rb=function dzd(a){throw vbb(new bgb)};_.nj=function ezd(){var b;try{b=this.c.ki(this.e);this.mj();this.g=this.e++;return b}catch(a){a=ubb(a);if(JD(a,73)){this.mj();throw vbb(new utb)}else throw vbb(a)}};_.oj=function fzd(){var b;try{b=this.c.ki(--this.e);this.mj();this.g=this.e;return b}catch(a){a=ubb(a);if(JD(a,73)){this.mj();throw vbb(new utb)}else throw vbb(a)}};_.Qb=function gzd(){throw vbb(new bgb)};_.Wb=function hzd(a){throw vbb(new bgb)};var o4=mdb(Tte,'AbstractEList/NonResolvingEListIterator',385);bcb(1982,67,ive);_.Vh=function pzd(a,b){var c,d,e,f,g,h,i,j,k,l,m;e=b.gc();if(e!=0){j=BD(Ajd(this.a,4),126);k=j==null?0:j.length;m=k+e;d=nzd(this,m);l=k-a;l>0&&$fb(j,a,d,a+e,l);i=b.Kc();for(g=0;g<e;++g){h=i.Pb();c=a+g;lzd(d,c,Itd(this,h))}b0d(this,d);for(f=0;f<e;++f){h=d[a];this.bi(a,h);++a}return true}else{++this.j;return false}};_.Wh=function qzd(a){var b,c,d,e,f,g,h,i,j;d=a.gc();if(d!=0){i=(c=BD(Ajd(this.a,4),126),c==null?0:c.length);j=i+d;b=nzd(this,j);h=a.Kc();for(f=i;f<j;++f){g=h.Pb();lzd(b,f,Itd(this,g))}b0d(this,b);for(e=i;e<j;++e){g=b[e];this.bi(e,g)}return true}else{++this.j;return false}};_.Xh=function rzd(a,b){var c,d,e,f;d=BD(Ajd(this.a,4),126);e=d==null?0:d.length;c=nzd(this,e+1);f=Itd(this,b);a!=e&&$fb(d,a,c,a+1,e-a);NC(c,a,f);b0d(this,c);this.bi(a,b)};_.Yh=function szd(a){var b,c,d;d=(c=BD(Ajd(this.a,4),126),c==null?0:c.length);b=nzd(this,d+1);lzd(b,d,Itd(this,a));b0d(this,b);this.bi(d,a)};_.Zh=function tzd(){return new Uzd(this)};_.$h=function uzd(){return new Xzd(this)};_._h=function vzd(a){var b,c;c=(b=BD(Ajd(this.a,4),126),b==null?0:b.length);if(a<0||a>c)throw vbb(new Cyd(a,c));return new Yzd(this,a)};_.$b=function wzd(){var a,b;++this.j;a=BD(Ajd(this.a,4),126);b=a==null?0:a.length;b0d(this,null);Atd(this,b,a)};_.Hc=function xzd(a){var b,c,d,e,f;b=BD(Ajd(this.a,4),126);if(b!=null){if(a!=null){for(d=b,e=0,f=d.length;e<f;++e){c=d[e];if(pb(a,c)){return true}}}else{for(d=b,e=0,f=d.length;e<f;++e){c=d[e];if(PD(c)===PD(a)){return true}}}}return false};_.Xb=function yzd(a){var b,c;b=BD(Ajd(this.a,4),126);c=b==null?0:b.length;if(a>=c)throw vbb(new Cyd(a,c));return b[a]};_.Xc=function zzd(a){var b,c,d;b=BD(Ajd(this.a,4),126);if(b!=null){if(a!=null){for(c=0,d=b.length;c<d;++c){if(pb(a,b[c])){return c}}}else{for(c=0,d=b.length;c<d;++c){if(PD(b[c])===PD(a)){return c}}}}return -1};_.dc=function Azd(){return BD(Ajd(this.a,4),126)==null};_.Kc=function Bzd(){return new Lzd(this)};_.Yc=function Czd(){return new Pzd(this)};_.Zc=function Dzd(a){var b,c;c=(b=BD(Ajd(this.a,4),126),b==null?0:b.length);if(a<0||a>c)throw vbb(new Cyd(a,c));return new Qzd(this,a)};_.ii=function Ezd(a,b){var c,d,e;c=mzd(this);e=c==null?0:c.length;if(a>=e)throw vbb(new qcb(lue+a+mue+e));if(b>=e)throw vbb(new qcb(nue+b+mue+e));d=c[b];if(a!=b){a<b?$fb(c,a,c,a+1,b-a):$fb(c,b+1,c,b,a-b);NC(c,a,d);b0d(this,c)}return d};_.ki=function Fzd(a){return BD(Ajd(this.a,4),126)[a]};_.$c=function Gzd(a){return ozd(this,a)};_.mi=function Hzd(a,b){var c,d;c=mzd(this);d=c[a];lzd(c,a,Itd(this,b));b0d(this,c);return d};_.gc=function Izd(){var a;return a=BD(Ajd(this.a,4),126),a==null?0:a.length};_.Pc=function Jzd(){var a,b,c;a=BD(Ajd(this.a,4),126);c=a==null?0:a.length;b=KC($3,hve,415,c,0,1);c>0&&$fb(a,0,b,0,c);return b};_.Qc=function Kzd(a){var b,c,d;b=BD(Ajd(this.a,4),126);d=b==null?0:b.length;if(d>0){if(a.length<d){c=izd(rb(a).c,d);a=c}$fb(b,0,a,0,d)}a.length>d&&NC(a,d,null);return a};var jzd;var v4=mdb(Tte,'ArrayDelegatingEList',1982);bcb(1038,40,aie,Lzd);_.mj=function Mzd(){if(this.b.j!=this.f||PD(BD(Ajd(this.b.a,4),126))!==PD(this.a)){throw vbb(new Apb)}};_.Qb=function Nzd(){Eyd(this);this.a=BD(Ajd(this.b.a,4),126)};var r4=mdb(Tte,'ArrayDelegatingEList/EIterator',1038);bcb(706,278,jie,Pzd,Qzd);_.mj=function Rzd(){if(this.b.j!=this.f||PD(BD(Ajd(this.b.a,4),126))!==PD(this.a)){throw vbb(new Apb)}};_.pj=function Szd(a){Nyd(this,a);this.a=BD(Ajd(this.b.a,4),126)};_.Qb=function Tzd(){Eyd(this);this.a=BD(Ajd(this.b.a,4),126)};var s4=mdb(Tte,'ArrayDelegatingEList/EListIterator',706);bcb(1039,341,aie,Uzd);_.mj=function Vzd(){if(this.b.j!=this.f||PD(BD(Ajd(this.b.a,4),126))!==PD(this.a)){throw vbb(new Apb)}};var t4=mdb(Tte,'ArrayDelegatingEList/NonResolvingEIterator',1039);bcb(707,385,jie,Xzd,Yzd);_.mj=function Zzd(){if(this.b.j!=this.f||PD(BD(Ajd(this.b.a,4),126))!==PD(this.a)){throw vbb(new Apb)}};var u4=mdb(Tte,'ArrayDelegatingEList/NonResolvingEListIterator',707);bcb(606,295,Mje,$zd);var w4=mdb(Tte,'BasicEList/BasicIndexOutOfBoundsException',606);bcb(696,63,oue,_zd);_.Vc=function aAd(a,b){throw vbb(new bgb)};_.Fc=function bAd(a){throw vbb(new bgb)};_.Wc=function cAd(a,b){throw vbb(new bgb)};_.Gc=function dAd(a){throw vbb(new bgb)};_.$b=function eAd(){throw vbb(new bgb)};_.qi=function fAd(a){throw vbb(new bgb)};_.Kc=function gAd(){return this.Zh()};_.Yc=function hAd(){return this.$h()};_.Zc=function iAd(a){return this._h(a)};_.ii=function jAd(a,b){throw vbb(new bgb)};_.ji=function kAd(a,b){throw vbb(new bgb)};_.$c=function lAd(a){throw vbb(new bgb)};_.Mc=function mAd(a){throw vbb(new bgb)};_._c=function nAd(a,b){throw vbb(new bgb)};var x4=mdb(Tte,'BasicEList/UnmodifiableEList',696);bcb(705,1,{3:1,20:1,14:1,15:1,58:1,589:1});_.Vc=function OAd(a,b){oAd(this,a,BD(b,42))};_.Fc=function PAd(a){return pAd(this,BD(a,42))};_.Jc=function XAd(a){reb(this,a)};_.Xb=function YAd(a){return BD(qud(this.c,a),133)};_.ii=function fBd(a,b){return BD(this.c.ii(a,b),42)};_.ji=function gBd(a,b){GAd(this,a,BD(b,42))};_.Lc=function jBd(){return new YAb(null,new Kub(this,16))};_.$c=function kBd(a){return BD(this.c.$c(a),42)};_._c=function mBd(a,b){return MAd(this,a,BD(b,42))};_.ad=function oBd(a){ktb(this,a)};_.Nc=function pBd(){return new Kub(this,16)};_.Oc=function qBd(){return new YAb(null,new Kub(this,16))};_.Wc=function QAd(a,b){return this.c.Wc(a,b)};_.Gc=function RAd(a){return this.c.Gc(a)};_.$b=function SAd(){this.c.$b()};_.Hc=function TAd(a){return this.c.Hc(a)};_.Ic=function UAd(a){return Be(this.c,a)};_.qj=function VAd(){var a,b,c;if(this.d==null){this.d=KC(y4,jve,63,2*this.f+1,0,1);c=this.e;this.f=0;for(b=this.c.Kc();b.e!=b.i.gc();){a=BD(b.nj(),133);uAd(this,a)}this.e=c}};_.Fb=function WAd(a){return zAd(this,a)};_.Hb=function ZAd(){return Etd(this.c)};_.Xc=function $Ad(a){return this.c.Xc(a)};_.rj=function _Ad(){this.c=new yBd(this)};_.dc=function aBd(){return this.f==0};_.Kc=function bBd(){return this.c.Kc()};_.Yc=function cBd(){return this.c.Yc()};_.Zc=function dBd(a){return this.c.Zc(a)};_.sj=function eBd(){return FAd(this)};_.tj=function hBd(a,b,c){return new zCd(a,b,c)};_.uj=function iBd(){return new EBd};_.Mc=function lBd(a){return JAd(this,a)};_.gc=function nBd(){return this.f};_.bd=function rBd(a,b){return new Jib(this.c,a,b)};_.Pc=function sBd(){return this.c.Pc()};_.Qc=function tBd(a){return this.c.Qc(a)};_.Ib=function uBd(){return Htd(this.c)};_.e=0;_.f=0;var L4=mdb(Tte,'BasicEMap',705);bcb(1033,63,oue,yBd);_.bi=function zBd(a,b){vBd(this,BD(b,133))};_.ei=function BBd(a,b,c){var d;++(d=this,BD(b,133),d).a.e};_.fi=function CBd(a,b){wBd(this,BD(b,133))};_.gi=function DBd(a,b,c){xBd(this,BD(b,133),BD(c,133))};_.di=function ABd(a,b){tAd(this.a)};var z4=mdb(Tte,'BasicEMap/1',1033);bcb(1034,63,oue,EBd);_.ri=function FBd(a){return KC(I4,kve,612,a,0,1)};var A4=mdb(Tte,'BasicEMap/2',1034);bcb(1035,eie,fie,GBd);_.$b=function HBd(){this.a.c.$b()};_.Hc=function IBd(a){return qAd(this.a,a)};_.Kc=function JBd(){return this.a.f==0?(LCd(),KCd.a):new dCd(this.a)};_.Mc=function KBd(a){var b;b=this.a.f;LAd(this.a,a);return this.a.f!=b};_.gc=function LBd(){return this.a.f};var B4=mdb(Tte,'BasicEMap/3',1035);bcb(1036,28,die,MBd);_.$b=function NBd(){this.a.c.$b()};_.Hc=function OBd(a){return rAd(this.a,a)};_.Kc=function PBd(){return this.a.f==0?(LCd(),KCd.a):new fCd(this.a)};_.gc=function QBd(){return this.a.f};var C4=mdb(Tte,'BasicEMap/4',1036);bcb(1037,eie,fie,SBd);_.$b=function TBd(){this.a.c.$b()};_.Hc=function UBd(a){var b,c,d,e,f,g,h,i,j;if(this.a.f>0&&JD(a,42)){this.a.qj();i=BD(a,42);h=i.cd();e=h==null?0:tb(h);f=DAd(this.a,e);b=this.a.d[f];if(b){c=BD(b.g,367);j=b.i;for(g=0;g<j;++g){d=c[g];if(d.Sh()==e&&d.Fb(i)){return true}}}}return false};_.Kc=function VBd(){return this.a.f==0?(LCd(),KCd.a):new ZBd(this.a)};_.Mc=function WBd(a){return RBd(this,a)};_.gc=function XBd(){return this.a.f};var D4=mdb(Tte,'BasicEMap/5',1037);bcb(613,1,aie,ZBd);_.Nb=function $Bd(a){Rrb(this,a)};_.Ob=function _Bd(){return this.b!=-1};_.Pb=function aCd(){var a;if(this.f.e!=this.c){throw vbb(new Apb)}if(this.b==-1){throw vbb(new utb)}this.d=this.a;this.e=this.b;YBd(this);a=BD(this.f.d[this.d].g[this.e],133);return this.vj(a)};_.Qb=function bCd(){if(this.f.e!=this.c){throw vbb(new Apb)}if(this.e==-1){throw vbb(new Ydb)}this.f.c.Mc(qud(this.f.d[this.d],this.e));this.c=this.f.e;this.e=-1;this.a==this.d&&this.b!=-1&&--this.b};_.vj=function cCd(a){return a};_.a=0;_.b=-1;_.c=0;_.d=0;_.e=0;var E4=mdb(Tte,'BasicEMap/BasicEMapIterator',613);bcb(1031,613,aie,dCd);_.vj=function eCd(a){return a.cd()};var F4=mdb(Tte,'BasicEMap/BasicEMapKeyIterator',1031);bcb(1032,613,aie,fCd);_.vj=function gCd(a){return a.dd()};var G4=mdb(Tte,'BasicEMap/BasicEMapValueIterator',1032);bcb(1030,1,cie,iCd);_.wc=function oCd(a){stb(this,a)};_.yc=function tCd(a,b,c){return ttb(this,a,b,c)};_.$b=function jCd(){this.a.c.$b()};_._b=function kCd(a){return hCd(this,a)};_.uc=function lCd(a){return rAd(this.a,a)};_.vc=function mCd(){return yAd(this.a)};_.Fb=function nCd(a){return zAd(this.a,a)};_.xc=function pCd(a){return AAd(this.a,a)};_.Hb=function qCd(){return Etd(this.a.c)};_.dc=function rCd(){return this.a.f==0};_.ec=function sCd(){return EAd(this.a)};_.zc=function uCd(a,b){return HAd(this.a,a,b)};_.Bc=function vCd(a){return LAd(this.a,a)};_.gc=function wCd(){return this.a.f};_.Ib=function xCd(){return Htd(this.a.c)};_.Cc=function yCd(){return NAd(this.a)};var H4=mdb(Tte,'BasicEMap/DelegatingMap',1030);bcb(612,1,{42:1,133:1,612:1},zCd);_.Fb=function ACd(a){var b;if(JD(a,42)){b=BD(a,42);return (this.b!=null?pb(this.b,b.cd()):PD(this.b)===PD(b.cd()))&&(this.c!=null?pb(this.c,b.dd()):PD(this.c)===PD(b.dd()))}else{return false}};_.Sh=function BCd(){return this.a};_.cd=function CCd(){return this.b};_.dd=function DCd(){return this.c};_.Hb=function ECd(){return this.a^(this.c==null?0:tb(this.c))};_.Th=function FCd(a){this.a=a};_.Uh=function GCd(a){throw vbb(new gz)};_.ed=function HCd(a){var b;b=this.c;this.c=a;return b};_.Ib=function ICd(){return this.b+'->'+this.c};_.a=0;var I4=mdb(Tte,'BasicEMap/EntryImpl',612);bcb(536,1,{},JCd);var K4=mdb(Tte,'BasicEMap/View',536);var KCd;bcb(768,1,{});_.Fb=function ZCd(a){return At((mmb(),jmb),a)};_.Hb=function $Cd(){return qmb((mmb(),jmb))};_.Ib=function _Cd(){return Fe((mmb(),jmb))};var Q4=mdb(Tte,'ECollections/BasicEmptyUnmodifiableEList',768);bcb(1312,1,jie,aDd);_.Nb=function cDd(a){Rrb(this,a)};_.Rb=function bDd(a){throw vbb(new bgb)};_.Ob=function dDd(){return false};_.Sb=function eDd(){return false};_.Pb=function fDd(){throw vbb(new utb)};_.Tb=function gDd(){return 0};_.Ub=function hDd(){throw vbb(new utb)};_.Vb=function iDd(){return -1};_.Qb=function jDd(){throw vbb(new bgb)};_.Wb=function kDd(a){throw vbb(new bgb)};var P4=mdb(Tte,'ECollections/BasicEmptyUnmodifiableEList/1',1312);bcb(1310,768,{20:1,14:1,15:1,58:1},lDd);_.Vc=function mDd(a,b){OCd()};_.Fc=function nDd(a){return PCd()};_.Wc=function oDd(a,b){return QCd()};_.Gc=function pDd(a){return RCd()};_.$b=function qDd(){SCd()};_.Hc=function rDd(a){return false};_.Ic=function sDd(a){return false};_.Jc=function tDd(a){reb(this,a)};_.Xb=function uDd(a){return wmb((mmb(),jmb,a)),null};_.Xc=function vDd(a){return -1};_.dc=function wDd(){return true};_.Kc=function xDd(){return this.a};_.Yc=function yDd(){return this.a};_.Zc=function zDd(a){return this.a};_.ii=function ADd(a,b){return TCd()};_.ji=function BDd(a,b){UCd()};_.Lc=function CDd(){return new YAb(null,new Kub(this,16))};_.$c=function DDd(a){return VCd()};_.Mc=function EDd(a){return WCd()};_._c=function FDd(a,b){return XCd()};_.gc=function GDd(){return 0};_.ad=function HDd(a){ktb(this,a)};_.Nc=function IDd(){return new Kub(this,16)};_.Oc=function JDd(){return new YAb(null,new Kub(this,16))};_.bd=function KDd(a,b){return mmb(),new Jib(jmb,a,b)};_.Pc=function LDd(){return De((mmb(),jmb))};_.Qc=function MDd(a){return mmb(),Ee(jmb,a)};var R4=mdb(Tte,'ECollections/EmptyUnmodifiableEList',1310);bcb(1311,768,{20:1,14:1,15:1,58:1,589:1},NDd);_.Vc=function ODd(a,b){OCd()};_.Fc=function PDd(a){return PCd()};_.Wc=function QDd(a,b){return QCd()};_.Gc=function RDd(a){return RCd()};_.$b=function SDd(){SCd()};_.Hc=function TDd(a){return false};_.Ic=function UDd(a){return false};_.Jc=function VDd(a){reb(this,a)};_.Xb=function WDd(a){return wmb((mmb(),jmb,a)),null};_.Xc=function XDd(a){return -1};_.dc=function YDd(){return true};_.Kc=function ZDd(){return this.a};_.Yc=function $Dd(){return this.a};_.Zc=function _Dd(a){return this.a};_.ii=function bEd(a,b){return TCd()};_.ji=function cEd(a,b){UCd()};_.Lc=function dEd(){return new YAb(null,new Kub(this,16))};_.$c=function eEd(a){return VCd()};_.Mc=function fEd(a){return WCd()};_._c=function gEd(a,b){return XCd()};_.gc=function hEd(){return 0};_.ad=function iEd(a){ktb(this,a)};_.Nc=function jEd(){return new Kub(this,16)};_.Oc=function kEd(){return new YAb(null,new Kub(this,16))};_.bd=function lEd(a,b){return mmb(),new Jib(jmb,a,b)};_.Pc=function mEd(){return De((mmb(),jmb))};_.Qc=function nEd(a){return mmb(),Ee(jmb,a)};_.sj=function aEd(){return mmb(),mmb(),kmb};var S4=mdb(Tte,'ECollections/EmptyUnmodifiableEMap',1311);var U4=odb(Tte,'Enumerator');var oEd;bcb(281,1,{281:1},NEd);_.Fb=function REd(a){var b;if(this===a)return true;if(!JD(a,281))return false;b=BD(a,281);return this.f==b.f&&TEd(this.i,b.i)&&SEd(this.a,(this.f&256)!=0?(b.f&256)!=0?b.a:null:(b.f&256)!=0?null:b.a)&&SEd(this.d,b.d)&&SEd(this.g,b.g)&&SEd(this.e,b.e)&&KEd(this,b)};_.Hb=function WEd(){return this.f};_.Ib=function cFd(){return LEd(this)};_.f=0;var sEd=0,tEd=0,uEd=0,vEd=0,wEd=0,xEd=0,yEd=0,zEd=0,AEd=0,BEd,CEd=0,DEd=0,EEd=0,FEd=0,GEd,HEd;var Z4=mdb(Tte,'URI',281);bcb(1091,43,fke,mFd);_.zc=function nFd(a,b){return BD(Shb(this,GD(a),BD(b,281)),281)};var Y4=mdb(Tte,'URI/URICache',1091);bcb(497,63,oue,oFd,pFd);_.hi=function qFd(){return true};var $4=mdb(Tte,'UniqueEList',497);bcb(581,60,Tie,rFd);var _4=mdb(Tte,'WrappedException',581);var a5=odb(Vse,nve);var v5=odb(Vse,ove);var t5=odb(Vse,pve);var b5=odb(Vse,qve);var d5=odb(Vse,rve);var c5=odb(Vse,'EClass');var f5=odb(Vse,'EDataType');var sFd;bcb(1183,43,fke,vFd);_.xc=function wFd(a){return ND(a)?Phb(this,a):Wd(irb(this.f,a))};var e5=mdb(Vse,'EDataType/Internal/ConversionDelegate/Factory/Registry/Impl',1183);var h5=odb(Vse,'EEnum');var g5=odb(Vse,sve);var j5=odb(Vse,tve);var n5=odb(Vse,uve);var xFd;var p5=odb(Vse,vve);var q5=odb(Vse,wve);bcb(1029,1,{},BFd);_.Ib=function CFd(){return 'NIL'};var r5=mdb(Vse,'EStructuralFeature/Internal/DynamicValueHolder/1',1029);var DFd;bcb(1028,43,fke,GFd);_.xc=function HFd(a){return ND(a)?Phb(this,a):Wd(irb(this.f,a))};var s5=mdb(Vse,'EStructuralFeature/Internal/SettingDelegate/Factory/Registry/Impl',1028);var u5=odb(Vse,xve);var w5=odb(Vse,'EValidator/PatternMatcher');var IFd;var KFd;var MFd;var OFd,PFd,QFd,RFd,SFd,TFd,UFd,VFd,WFd,XFd,YFd,ZFd,$Fd,_Fd,aGd,bGd,cGd,dGd,eGd,fGd,gGd,hGd,iGd;var E9=odb(yve,'FeatureMap/Entry');bcb(535,1,{72:1},kGd);_.ak=function lGd(){return this.a};_.dd=function mGd(){return this.b};var x5=mdb(qte,'BasicEObjectImpl/1',535);bcb(1027,1,zve,nGd);_.Wj=function oGd(a){return hid(this.a,this.b,a)};_.fj=function pGd(){return nid(this.a,this.b)};_.Wb=function qGd(a){zid(this.a,this.b,a)};_.Xj=function rGd(){Did(this.a,this.b)};var y5=mdb(qte,'BasicEObjectImpl/4',1027);bcb(1983,1,{108:1});_.bk=function uGd(a){this.e=a==0?sGd:KC(SI,Uhe,1,a,5,1)};_.Ch=function vGd(a){return this.e[a]};_.Dh=function wGd(a,b){this.e[a]=b};_.Eh=function xGd(a){this.e[a]=null};_.ck=function yGd(){return this.c};_.dk=function zGd(){throw vbb(new bgb)};_.ek=function AGd(){throw vbb(new bgb)};_.fk=function BGd(){return this.d};_.gk=function CGd(){return this.e!=null};_.hk=function DGd(a){this.c=a};_.ik=function EGd(a){throw vbb(new bgb)};_.jk=function FGd(a){throw vbb(new bgb)};_.kk=function GGd(a){this.d=a};var sGd;var z5=mdb(qte,'BasicEObjectImpl/EPropertiesHolderBaseImpl',1983);bcb(185,1983,{108:1},HGd);_.dk=function IGd(){return this.a};_.ek=function JGd(){return this.b};_.ik=function KGd(a){this.a=a};_.jk=function LGd(a){this.b=a};var A5=mdb(qte,'BasicEObjectImpl/EPropertiesHolderImpl',185);bcb(506,97,pte,MGd);_.Kg=function NGd(){return this.f};_.Pg=function OGd(){return this.k};_.Rg=function PGd(a,b){this.g=a;this.i=b};_.Tg=function QGd(){return (this.j&2)==0?this.zh():this.ph().ck()};_.Vg=function RGd(){return this.i};_.Mg=function SGd(){return (this.j&1)!=0};_.eh=function TGd(){return this.g};_.kh=function UGd(){return (this.j&4)!=0};_.ph=function VGd(){return !this.k&&(this.k=new HGd),this.k};_.th=function WGd(a){this.ph().hk(a);a?(this.j|=2):(this.j&=-3)};_.vh=function XGd(a){this.ph().jk(a);a?(this.j|=4):(this.j&=-5)};_.zh=function YGd(){return (NFd(),MFd).S};_.i=0;_.j=1;var l6=mdb(qte,'EObjectImpl',506);bcb(780,506,{105:1,92:1,90:1,56:1,108:1,49:1,97:1},_Gd);_.Ch=function aHd(a){return this.e[a]};_.Dh=function bHd(a,b){this.e[a]=b};_.Eh=function cHd(a){this.e[a]=null};_.Tg=function dHd(){return this.d};_.Yg=function eHd(a){return bLd(this.d,a)};_.$g=function fHd(){return this.d};_.dh=function gHd(){return this.e!=null};_.ph=function hHd(){!this.k&&(this.k=new vHd);return this.k};_.th=function iHd(a){this.d=a};_.yh=function jHd(){var a;if(this.e==null){a=aLd(this.d);this.e=a==0?ZGd:KC(SI,Uhe,1,a,5,1)}return this};_.Ah=function kHd(){return 0};var ZGd;var E5=mdb(qte,'DynamicEObjectImpl',780);bcb(1376,780,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1},lHd);_.Fb=function nHd(a){return this===a};_.Hb=function rHd(){return FCb(this)};_.th=function mHd(a){this.d=a;this.b=YKd(a,'key');this.c=YKd(a,Bte)};_.Sh=function oHd(){var a;if(this.a==-1){a=iid(this,this.b);this.a=a==null?0:tb(a)}return this.a};_.cd=function pHd(){return iid(this,this.b)};_.dd=function qHd(){return iid(this,this.c)};_.Th=function sHd(a){this.a=a};_.Uh=function tHd(a){zid(this,this.b,a)};_.ed=function uHd(a){var b;b=iid(this,this.c);zid(this,this.c,a);return b};_.a=0;var C5=mdb(qte,'DynamicEObjectImpl/BasicEMapEntry',1376);bcb(1377,1,{108:1},vHd);_.bk=function wHd(a){throw vbb(new bgb)};_.Ch=function xHd(a){throw vbb(new bgb)};_.Dh=function yHd(a,b){throw vbb(new bgb)};_.Eh=function zHd(a){throw vbb(new bgb)};_.ck=function AHd(){throw vbb(new bgb)};_.dk=function BHd(){return this.a};_.ek=function CHd(){return this.b};_.fk=function DHd(){return this.c};_.gk=function EHd(){throw vbb(new bgb)};_.hk=function FHd(a){throw vbb(new bgb)};_.ik=function GHd(a){this.a=a};_.jk=function HHd(a){this.b=a};_.kk=function IHd(a){this.c=a};var D5=mdb(qte,'DynamicEObjectImpl/DynamicEPropertiesHolderImpl',1377);bcb(510,150,{105:1,92:1,90:1,590:1,147:1,56:1,108:1,49:1,97:1,510:1,150:1,114:1,115:1},RHd);_.Qg=function SHd(a){return KHd(this,a)};_._g=function THd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.d;case 2:return c?(!this.b&&(this.b=new sId((jGd(),fGd),x6,this)),this.b):(!this.b&&(this.b=new sId((jGd(),fGd),x6,this)),FAd(this.b));case 3:return MHd(this);case 4:return !this.a&&(this.a=new xMd(m5,this,4)),this.a;case 5:return !this.c&&(this.c=new _4d(m5,this,5)),this.c;}return bid(this,a-aLd((jGd(),OFd)),XKd((d=BD(Ajd(this,16),26),!d?OFd:d),a),b,c)};_.hh=function UHd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 3:!!this.Cb&&(c=(e=this.Db>>16,e>=0?KHd(this,c):this.Cb.ih(this,-1-e,null,c)));return JHd(this,BD(a,147),c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),OFd):d),b),66),f.Nj().Qj(this,yjd(this),b-aLd((jGd(),OFd)),a,c)};_.jh=function VHd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 2:return !this.b&&(this.b=new sId((jGd(),fGd),x6,this)),bId(this.b,a,c);case 3:return JHd(this,null,c);case 4:return !this.a&&(this.a=new xMd(m5,this,4)),Txd(this.a,a,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),OFd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),OFd)),a,c)};_.lh=function WHd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.d!=null;case 2:return !!this.b&&this.b.f!=0;case 3:return !!MHd(this);case 4:return !!this.a&&this.a.i!=0;case 5:return !!this.c&&this.c.i!=0;}return cid(this,a-aLd((jGd(),OFd)),XKd((b=BD(Ajd(this,16),26),!b?OFd:b),a))};_.sh=function XHd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:OHd(this,GD(b));return;case 2:!this.b&&(this.b=new sId((jGd(),fGd),x6,this));cId(this.b,b);return;case 3:NHd(this,BD(b,147));return;case 4:!this.a&&(this.a=new xMd(m5,this,4));Uxd(this.a);!this.a&&(this.a=new xMd(m5,this,4));ytd(this.a,BD(b,14));return;case 5:!this.c&&(this.c=new _4d(m5,this,5));Uxd(this.c);!this.c&&(this.c=new _4d(m5,this,5));ytd(this.c,BD(b,14));return;}did(this,a-aLd((jGd(),OFd)),XKd((c=BD(Ajd(this,16),26),!c?OFd:c),a),b)};_.zh=function YHd(){return jGd(),OFd};_.Bh=function ZHd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:PHd(this,null);return;case 2:!this.b&&(this.b=new sId((jGd(),fGd),x6,this));this.b.c.$b();return;case 3:NHd(this,null);return;case 4:!this.a&&(this.a=new xMd(m5,this,4));Uxd(this.a);return;case 5:!this.c&&(this.c=new _4d(m5,this,5));Uxd(this.c);return;}eid(this,a-aLd((jGd(),OFd)),XKd((b=BD(Ajd(this,16),26),!b?OFd:b),a))};_.Ib=function $Hd(){return QHd(this)};_.d=null;var G5=mdb(qte,'EAnnotationImpl',510);bcb(151,705,Ave,dId);_.Xh=function eId(a,b){_Hd(this,a,BD(b,42))};_.lk=function fId(a,b){return aId(this,BD(a,42),b)};_.pi=function gId(a){return BD(BD(this.c,69).pi(a),133)};_.Zh=function hId(){return BD(this.c,69).Zh()};_.$h=function iId(){return BD(this.c,69).$h()};_._h=function jId(a){return BD(this.c,69)._h(a)};_.mk=function kId(a,b){return bId(this,a,b)};_.Wj=function lId(a){return BD(this.c,76).Wj(a)};_.rj=function mId(){};_.fj=function nId(){return BD(this.c,76).fj()};_.tj=function oId(a,b,c){var d;d=BD(bKd(this.b).Nh().Jh(this.b),133);d.Th(a);d.Uh(b);d.ed(c);return d};_.uj=function pId(){return new W5d(this)};_.Wb=function qId(a){cId(this,a)};_.Xj=function rId(){BD(this.c,76).Xj()};var y9=mdb(yve,'EcoreEMap',151);bcb(158,151,Ave,sId);_.qj=function tId(){var a,b,c,d,e,f;if(this.d==null){f=KC(y4,jve,63,2*this.f+1,0,1);for(c=this.c.Kc();c.e!=c.i.gc();){b=BD(c.nj(),133);d=b.Sh();e=(d&Ohe)%f.length;a=f[e];!a&&(a=f[e]=new W5d(this));a.Fc(b)}this.d=f}};var F5=mdb(qte,'EAnnotationImpl/1',158);bcb(284,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,472:1,49:1,97:1,150:1,284:1,114:1,115:1});_._g=function GId(a,b,c){var d,e;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Bcb(),(this.Bb&256)!=0?true:false;case 3:return Bcb(),(this.Bb&512)!=0?true:false;case 4:return meb(this.s);case 5:return meb(this.t);case 6:return Bcb(),this.$j()?true:false;case 7:return Bcb(),e=this.s,e>=1?true:false;case 8:if(b)return wId(this);return this.r;case 9:return this.q;}return bid(this,a-aLd(this.zh()),XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),a),b,c)};_.jh=function HId(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 9:return vId(this,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),b),66),e.Nj().Rj(this,yjd(this),b-aLd(this.zh()),a,c)};_.lh=function IId(a){var b,c;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return this.$j();case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&LQd(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&LQd(this.q).i==0);}return cid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.sh=function JId(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:this.Lh(GD(b));return;case 2:BId(this,Ccb(DD(b)));return;case 3:CId(this,Ccb(DD(b)));return;case 4:AId(this,BD(b,19).a);return;case 5:this.ok(BD(b,19).a);return;case 8:yId(this,BD(b,138));return;case 9:d=xId(this,BD(b,87),null);!!d&&d.Fi();return;}did(this,a-aLd(this.zh()),XKd((c=BD(Ajd(this,16),26),!c?this.zh():c),a),b)};_.zh=function KId(){return jGd(),hGd};_.Bh=function LId(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:this.Lh(null);return;case 2:BId(this,true);return;case 3:CId(this,true);return;case 4:AId(this,0);return;case 5:this.ok(1);return;case 8:yId(this,null);return;case 9:c=xId(this,null,null);!!c&&c.Fi();return;}eid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.Gh=function MId(){wId(this);this.Bb|=1};_.Yj=function NId(){return wId(this)};_.Zj=function OId(){return this.t};_.$j=function PId(){var a;return a=this.t,a>1||a==-1};_.hi=function QId(){return (this.Bb&512)!=0};_.nk=function RId(a,b){return zId(this,a,b)};_.ok=function SId(a){DId(this,a)};_.Ib=function TId(){return EId(this)};_.s=0;_.t=1;var v7=mdb(qte,'ETypedElementImpl',284);bcb(449,284,{105:1,92:1,90:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,449:1,284:1,114:1,115:1,677:1});_.Qg=function iJd(a){return UId(this,a)};_._g=function jJd(a,b,c){var d,e;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Bcb(),(this.Bb&256)!=0?true:false;case 3:return Bcb(),(this.Bb&512)!=0?true:false;case 4:return meb(this.s);case 5:return meb(this.t);case 6:return Bcb(),this.$j()?true:false;case 7:return Bcb(),e=this.s,e>=1?true:false;case 8:if(b)return wId(this);return this.r;case 9:return this.q;case 10:return Bcb(),(this.Bb&zte)!=0?true:false;case 11:return Bcb(),(this.Bb&Dve)!=0?true:false;case 12:return Bcb(),(this.Bb&Rje)!=0?true:false;case 13:return this.j;case 14:return VId(this);case 15:return Bcb(),(this.Bb&Cve)!=0?true:false;case 16:return Bcb(),(this.Bb&oie)!=0?true:false;case 17:return WId(this);}return bid(this,a-aLd(this.zh()),XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),a),b,c)};_.hh=function kJd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 17:!!this.Cb&&(c=(e=this.Db>>16,e>=0?UId(this,c):this.Cb.ih(this,-1-e,null,c)));return _hd(this,a,17,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),b),66),f.Nj().Qj(this,yjd(this),b-aLd(this.zh()),a,c)};_.jh=function lJd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 9:return vId(this,c);case 17:return _hd(this,null,17,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),b),66),e.Nj().Rj(this,yjd(this),b-aLd(this.zh()),a,c)};_.lh=function mJd(a){var b,c;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return this.$j();case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&LQd(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&LQd(this.q).i==0);case 10:return (this.Bb&zte)==0;case 11:return (this.Bb&Dve)!=0;case 12:return (this.Bb&Rje)!=0;case 13:return this.j!=null;case 14:return VId(this)!=null;case 15:return (this.Bb&Cve)!=0;case 16:return (this.Bb&oie)!=0;case 17:return !!WId(this);}return cid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.sh=function nJd(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:cJd(this,GD(b));return;case 2:BId(this,Ccb(DD(b)));return;case 3:CId(this,Ccb(DD(b)));return;case 4:AId(this,BD(b,19).a);return;case 5:this.ok(BD(b,19).a);return;case 8:yId(this,BD(b,138));return;case 9:d=xId(this,BD(b,87),null);!!d&&d.Fi();return;case 10:ZId(this,Ccb(DD(b)));return;case 11:fJd(this,Ccb(DD(b)));return;case 12:dJd(this,Ccb(DD(b)));return;case 13:$Id(this,GD(b));return;case 15:eJd(this,Ccb(DD(b)));return;case 16:aJd(this,Ccb(DD(b)));return;}did(this,a-aLd(this.zh()),XKd((c=BD(Ajd(this,16),26),!c?this.zh():c),a),b)};_.zh=function oJd(){return jGd(),gGd};_.Bh=function pJd(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:JD(this.Cb,88)&&XMd($Kd(BD(this.Cb,88)),4);pnd(this,null);return;case 2:BId(this,true);return;case 3:CId(this,true);return;case 4:AId(this,0);return;case 5:this.ok(1);return;case 8:yId(this,null);return;case 9:c=xId(this,null,null);!!c&&c.Fi();return;case 10:ZId(this,true);return;case 11:fJd(this,false);return;case 12:dJd(this,false);return;case 13:this.i=null;_Id(this,null);return;case 15:eJd(this,false);return;case 16:aJd(this,false);return;}eid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.Gh=function qJd(){a2d(q1d((O6d(),M6d),this));wId(this);this.Bb|=1};_.Gj=function rJd(){return this.f};_.zj=function sJd(){return VId(this)};_.Hj=function tJd(){return WId(this)};_.Lj=function uJd(){return null};_.pk=function vJd(){return this.k};_.aj=function wJd(){return this.n};_.Mj=function xJd(){return XId(this)};_.Nj=function yJd(){var a,b,c,d,e,f,g,h,i;if(!this.p){c=WId(this);(c.i==null&&TKd(c),c.i).length;d=this.Lj();!!d&&aLd(WId(d));e=wId(this);g=e.Bj();a=!g?null:(g.i&1)!=0?g==sbb?wI:g==WD?JI:g==VD?FI:g==UD?BI:g==XD?MI:g==rbb?UI:g==SD?xI:yI:g;b=VId(this);h=e.zj();n6d(this);(this.Bb&oie)!=0&&(!!(f=t1d((O6d(),M6d),c))&&f!=this||!!(f=_1d(q1d(M6d,this))))?(this.p=new zVd(this,f)):this.$j()?this.rk()?!d?(this.Bb&Cve)!=0?!a?this.sk()?(this.p=new KVd(42,this)):(this.p=new KVd(0,this)):a==CK?(this.p=new IVd(50,J4,this)):this.sk()?(this.p=new IVd(43,a,this)):(this.p=new IVd(1,a,this)):!a?this.sk()?(this.p=new KVd(44,this)):(this.p=new KVd(2,this)):a==CK?(this.p=new IVd(41,J4,this)):this.sk()?(this.p=new IVd(45,a,this)):(this.p=new IVd(3,a,this)):(this.Bb&Cve)!=0?!a?this.sk()?(this.p=new LVd(46,this,d)):(this.p=new LVd(4,this,d)):this.sk()?(this.p=new JVd(47,a,this,d)):(this.p=new JVd(5,a,this,d)):!a?this.sk()?(this.p=new LVd(48,this,d)):(this.p=new LVd(6,this,d)):this.sk()?(this.p=new JVd(49,a,this,d)):(this.p=new JVd(7,a,this,d)):JD(e,148)?a==E9?(this.p=new KVd(40,this)):(this.Bb&512)!=0?(this.Bb&Cve)!=0?!a?(this.p=new KVd(8,this)):(this.p=new IVd(9,a,this)):!a?(this.p=new KVd(10,this)):(this.p=new IVd(11,a,this)):(this.Bb&Cve)!=0?!a?(this.p=new KVd(12,this)):(this.p=new IVd(13,a,this)):!a?(this.p=new KVd(14,this)):(this.p=new IVd(15,a,this)):!d?this.sk()?(this.Bb&Cve)!=0?!a?(this.p=new KVd(16,this)):(this.p=new IVd(17,a,this)):!a?(this.p=new KVd(18,this)):(this.p=new IVd(19,a,this)):(this.Bb&Cve)!=0?!a?(this.p=new KVd(20,this)):(this.p=new IVd(21,a,this)):!a?(this.p=new KVd(22,this)):(this.p=new IVd(23,a,this)):(i=d.t,i>1||i==-1?this.sk()?(this.Bb&Cve)!=0?!a?(this.p=new LVd(24,this,d)):(this.p=new JVd(25,a,this,d)):!a?(this.p=new LVd(26,this,d)):(this.p=new JVd(27,a,this,d)):(this.Bb&Cve)!=0?!a?(this.p=new LVd(28,this,d)):(this.p=new JVd(29,a,this,d)):!a?(this.p=new LVd(30,this,d)):(this.p=new JVd(31,a,this,d)):this.sk()?(this.Bb&Cve)!=0?!a?(this.p=new LVd(32,this,d)):(this.p=new JVd(33,a,this,d)):!a?(this.p=new LVd(34,this,d)):(this.p=new JVd(35,a,this,d)):(this.Bb&Cve)!=0?!a?(this.p=new LVd(36,this,d)):(this.p=new JVd(37,a,this,d)):!a?(this.p=new LVd(38,this,d)):(this.p=new JVd(39,a,this,d))):this.qk()?this.sk()?(this.p=new kWd(BD(e,26),this,d)):(this.p=new cWd(BD(e,26),this,d)):JD(e,148)?a==E9?(this.p=new KVd(40,this)):(this.Bb&Cve)!=0?!a?(this.p=new jXd(BD(e,148),b,h,this)):(this.p=new lXd(b,h,this,(CWd(),g==WD?yWd:g==sbb?tWd:g==XD?zWd:g==VD?xWd:g==UD?wWd:g==rbb?BWd:g==SD?uWd:g==TD?vWd:AWd))):!a?(this.p=new cXd(BD(e,148),b,h,this)):(this.p=new eXd(b,h,this,(CWd(),g==WD?yWd:g==sbb?tWd:g==XD?zWd:g==VD?xWd:g==UD?wWd:g==rbb?BWd:g==SD?uWd:g==TD?vWd:AWd))):this.rk()?!d?(this.Bb&Cve)!=0?this.sk()?(this.p=new FXd(BD(e,26),this)):(this.p=new DXd(BD(e,26),this)):this.sk()?(this.p=new BXd(BD(e,26),this)):(this.p=new zXd(BD(e,26),this)):(this.Bb&Cve)!=0?this.sk()?(this.p=new NXd(BD(e,26),this,d)):(this.p=new LXd(BD(e,26),this,d)):this.sk()?(this.p=new JXd(BD(e,26),this,d)):(this.p=new HXd(BD(e,26),this,d)):this.sk()?!d?(this.Bb&Cve)!=0?(this.p=new RXd(BD(e,26),this)):(this.p=new PXd(BD(e,26),this)):(this.Bb&Cve)!=0?(this.p=new VXd(BD(e,26),this,d)):(this.p=new TXd(BD(e,26),this,d)):!d?(this.Bb&Cve)!=0?(this.p=new XXd(BD(e,26),this)):(this.p=new nXd(BD(e,26),this)):(this.Bb&Cve)!=0?(this.p=new _Xd(BD(e,26),this,d)):(this.p=new ZXd(BD(e,26),this,d))}return this.p};_.Ij=function zJd(){return (this.Bb&zte)!=0};_.qk=function AJd(){return false};_.rk=function BJd(){return false};_.Jj=function CJd(){return (this.Bb&oie)!=0};_.Oj=function DJd(){return YId(this)};_.sk=function EJd(){return false};_.Kj=function FJd(){return (this.Bb&Cve)!=0};_.tk=function GJd(a){this.k=a};_.Lh=function HJd(a){cJd(this,a)};_.Ib=function IJd(){return gJd(this)};_.e=false;_.n=0;var n7=mdb(qte,'EStructuralFeatureImpl',449);bcb(322,449,{105:1,92:1,90:1,34:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,322:1,150:1,449:1,284:1,114:1,115:1,677:1},OJd);_._g=function PJd(a,b,c){var d,e;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Bcb(),(this.Bb&256)!=0?true:false;case 3:return Bcb(),(this.Bb&512)!=0?true:false;case 4:return meb(this.s);case 5:return meb(this.t);case 6:return Bcb(),LJd(this)?true:false;case 7:return Bcb(),e=this.s,e>=1?true:false;case 8:if(b)return wId(this);return this.r;case 9:return this.q;case 10:return Bcb(),(this.Bb&zte)!=0?true:false;case 11:return Bcb(),(this.Bb&Dve)!=0?true:false;case 12:return Bcb(),(this.Bb&Rje)!=0?true:false;case 13:return this.j;case 14:return VId(this);case 15:return Bcb(),(this.Bb&Cve)!=0?true:false;case 16:return Bcb(),(this.Bb&oie)!=0?true:false;case 17:return WId(this);case 18:return Bcb(),(this.Bb&ote)!=0?true:false;case 19:if(b)return KJd(this);return JJd(this);}return bid(this,a-aLd((jGd(),PFd)),XKd((d=BD(Ajd(this,16),26),!d?PFd:d),a),b,c)};_.lh=function QJd(a){var b,c;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return LJd(this);case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&LQd(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&LQd(this.q).i==0);case 10:return (this.Bb&zte)==0;case 11:return (this.Bb&Dve)!=0;case 12:return (this.Bb&Rje)!=0;case 13:return this.j!=null;case 14:return VId(this)!=null;case 15:return (this.Bb&Cve)!=0;case 16:return (this.Bb&oie)!=0;case 17:return !!WId(this);case 18:return (this.Bb&ote)!=0;case 19:return !!JJd(this);}return cid(this,a-aLd((jGd(),PFd)),XKd((b=BD(Ajd(this,16),26),!b?PFd:b),a))};_.sh=function RJd(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:cJd(this,GD(b));return;case 2:BId(this,Ccb(DD(b)));return;case 3:CId(this,Ccb(DD(b)));return;case 4:AId(this,BD(b,19).a);return;case 5:NJd(this,BD(b,19).a);return;case 8:yId(this,BD(b,138));return;case 9:d=xId(this,BD(b,87),null);!!d&&d.Fi();return;case 10:ZId(this,Ccb(DD(b)));return;case 11:fJd(this,Ccb(DD(b)));return;case 12:dJd(this,Ccb(DD(b)));return;case 13:$Id(this,GD(b));return;case 15:eJd(this,Ccb(DD(b)));return;case 16:aJd(this,Ccb(DD(b)));return;case 18:MJd(this,Ccb(DD(b)));return;}did(this,a-aLd((jGd(),PFd)),XKd((c=BD(Ajd(this,16),26),!c?PFd:c),a),b)};_.zh=function SJd(){return jGd(),PFd};_.Bh=function TJd(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:JD(this.Cb,88)&&XMd($Kd(BD(this.Cb,88)),4);pnd(this,null);return;case 2:BId(this,true);return;case 3:CId(this,true);return;case 4:AId(this,0);return;case 5:this.b=0;DId(this,1);return;case 8:yId(this,null);return;case 9:c=xId(this,null,null);!!c&&c.Fi();return;case 10:ZId(this,true);return;case 11:fJd(this,false);return;case 12:dJd(this,false);return;case 13:this.i=null;_Id(this,null);return;case 15:eJd(this,false);return;case 16:aJd(this,false);return;case 18:MJd(this,false);return;}eid(this,a-aLd((jGd(),PFd)),XKd((b=BD(Ajd(this,16),26),!b?PFd:b),a))};_.Gh=function UJd(){KJd(this);a2d(q1d((O6d(),M6d),this));wId(this);this.Bb|=1};_.$j=function VJd(){return LJd(this)};_.nk=function WJd(a,b){this.b=0;this.a=null;return zId(this,a,b)};_.ok=function XJd(a){NJd(this,a)};_.Ib=function YJd(){var a;if((this.Db&64)!=0)return gJd(this);a=new Jfb(gJd(this));a.a+=' (iD: ';Ffb(a,(this.Bb&ote)!=0);a.a+=')';return a.a};_.b=0;var H5=mdb(qte,'EAttributeImpl',322);bcb(351,438,{105:1,92:1,90:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,150:1,114:1,115:1,676:1});_.uk=function nKd(a){return a.Tg()==this};_.Qg=function oKd(a){return aKd(this,a)};_.Rg=function pKd(a,b){this.w=null;this.Db=b<<16|this.Db&255;this.Cb=a};_._g=function qKd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.D!=null?this.D:this.B;case 3:return dKd(this);case 4:return this.zj();case 5:return this.F;case 6:if(b)return bKd(this);return ZJd(this);case 7:return !this.A&&(this.A=new K4d(u5,this,7)),this.A;}return bid(this,a-aLd(this.zh()),XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),a),b,c)};_.hh=function rKd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 6:!!this.Cb&&(c=(e=this.Db>>16,e>=0?aKd(this,c):this.Cb.ih(this,-1-e,null,c)));return _hd(this,a,6,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),b),66),f.Nj().Qj(this,yjd(this),b-aLd(this.zh()),a,c)};_.jh=function sKd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 6:return _hd(this,null,6,c);case 7:return !this.A&&(this.A=new K4d(u5,this,7)),Txd(this.A,a,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),b),66),e.Nj().Rj(this,yjd(this),b-aLd(this.zh()),a,c)};_.lh=function tKd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return !!dKd(this);case 4:return this.zj()!=null;case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return !!ZJd(this);case 7:return !!this.A&&this.A.i!=0;}return cid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.sh=function uKd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:lKd(this,GD(b));return;case 2:iKd(this,GD(b));return;case 5:kKd(this,GD(b));return;case 7:!this.A&&(this.A=new K4d(u5,this,7));Uxd(this.A);!this.A&&(this.A=new K4d(u5,this,7));ytd(this.A,BD(b,14));return;}did(this,a-aLd(this.zh()),XKd((c=BD(Ajd(this,16),26),!c?this.zh():c),a),b)};_.zh=function vKd(){return jGd(),RFd};_.Bh=function wKd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:JD(this.Cb,179)&&(BD(this.Cb,179).tb=null);pnd(this,null);return;case 2:$Jd(this,null);_Jd(this,this.D);return;case 5:kKd(this,null);return;case 7:!this.A&&(this.A=new K4d(u5,this,7));Uxd(this.A);return;}eid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.yj=function xKd(){var a;return this.G==-1&&(this.G=(a=bKd(this),a?HLd(a.Mh(),this):-1)),this.G};_.zj=function yKd(){return null};_.Aj=function zKd(){return bKd(this)};_.vk=function AKd(){return this.v};_.Bj=function BKd(){return dKd(this)};_.Cj=function CKd(){return this.D!=null?this.D:this.B};_.Dj=function DKd(){return this.F};_.wj=function EKd(a){return fKd(this,a)};_.wk=function FKd(a){this.v=a};_.xk=function GKd(a){gKd(this,a)};_.yk=function HKd(a){this.C=a};_.Lh=function IKd(a){lKd(this,a)};_.Ib=function JKd(){return mKd(this)};_.C=null;_.D=null;_.G=-1;var Z5=mdb(qte,'EClassifierImpl',351);bcb(88,351,{105:1,92:1,90:1,26:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,88:1,351:1,150:1,473:1,114:1,115:1,676:1},hLd);_.uk=function iLd(a){return dLd(this,a.Tg())};_._g=function jLd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.D!=null?this.D:this.B;case 3:return dKd(this);case 4:return null;case 5:return this.F;case 6:if(b)return bKd(this);return ZJd(this);case 7:return !this.A&&(this.A=new K4d(u5,this,7)),this.A;case 8:return Bcb(),(this.Bb&256)!=0?true:false;case 9:return Bcb(),(this.Bb&512)!=0?true:false;case 10:return _Kd(this);case 11:return !this.q&&(this.q=new cUd(n5,this,11,10)),this.q;case 12:return OKd(this);case 13:return SKd(this);case 14:return SKd(this),this.r;case 15:return OKd(this),this.k;case 16:return PKd(this);case 17:return RKd(this);case 18:return TKd(this);case 19:return UKd(this);case 20:return OKd(this),this.o;case 21:return !this.s&&(this.s=new cUd(t5,this,21,17)),this.s;case 22:return VKd(this);case 23:return QKd(this);}return bid(this,a-aLd((jGd(),QFd)),XKd((d=BD(Ajd(this,16),26),!d?QFd:d),a),b,c)};_.hh=function kLd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 6:!!this.Cb&&(c=(e=this.Db>>16,e>=0?aKd(this,c):this.Cb.ih(this,-1-e,null,c)));return _hd(this,a,6,c);case 11:return !this.q&&(this.q=new cUd(n5,this,11,10)),Sxd(this.q,a,c);case 21:return !this.s&&(this.s=new cUd(t5,this,21,17)),Sxd(this.s,a,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),QFd):d),b),66),f.Nj().Qj(this,yjd(this),b-aLd((jGd(),QFd)),a,c)};_.jh=function lLd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 6:return _hd(this,null,6,c);case 7:return !this.A&&(this.A=new K4d(u5,this,7)),Txd(this.A,a,c);case 11:return !this.q&&(this.q=new cUd(n5,this,11,10)),Txd(this.q,a,c);case 21:return !this.s&&(this.s=new cUd(t5,this,21,17)),Txd(this.s,a,c);case 22:return Txd(VKd(this),a,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),QFd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),QFd)),a,c)};_.lh=function mLd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return !!dKd(this);case 4:return false;case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return !!ZJd(this);case 7:return !!this.A&&this.A.i!=0;case 8:return (this.Bb&256)!=0;case 9:return (this.Bb&512)!=0;case 10:return !!this.u&&VKd(this.u.a).i!=0&&!(!!this.n&&FMd(this.n));case 11:return !!this.q&&this.q.i!=0;case 12:return OKd(this).i!=0;case 13:return SKd(this).i!=0;case 14:return SKd(this),this.r.i!=0;case 15:return OKd(this),this.k.i!=0;case 16:return PKd(this).i!=0;case 17:return RKd(this).i!=0;case 18:return TKd(this).i!=0;case 19:return UKd(this).i!=0;case 20:return OKd(this),!!this.o;case 21:return !!this.s&&this.s.i!=0;case 22:return !!this.n&&FMd(this.n);case 23:return QKd(this).i!=0;}return cid(this,a-aLd((jGd(),QFd)),XKd((b=BD(Ajd(this,16),26),!b?QFd:b),a))};_.oh=function nLd(a){var b;b=this.i==null||!!this.q&&this.q.i!=0?null:YKd(this,a);return b?b:Bmd(this,a)};_.sh=function oLd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:lKd(this,GD(b));return;case 2:iKd(this,GD(b));return;case 5:kKd(this,GD(b));return;case 7:!this.A&&(this.A=new K4d(u5,this,7));Uxd(this.A);!this.A&&(this.A=new K4d(u5,this,7));ytd(this.A,BD(b,14));return;case 8:eLd(this,Ccb(DD(b)));return;case 9:fLd(this,Ccb(DD(b)));return;case 10:vwd(_Kd(this));ytd(_Kd(this),BD(b,14));return;case 11:!this.q&&(this.q=new cUd(n5,this,11,10));Uxd(this.q);!this.q&&(this.q=new cUd(n5,this,11,10));ytd(this.q,BD(b,14));return;case 21:!this.s&&(this.s=new cUd(t5,this,21,17));Uxd(this.s);!this.s&&(this.s=new cUd(t5,this,21,17));ytd(this.s,BD(b,14));return;case 22:Uxd(VKd(this));ytd(VKd(this),BD(b,14));return;}did(this,a-aLd((jGd(),QFd)),XKd((c=BD(Ajd(this,16),26),!c?QFd:c),a),b)};_.zh=function pLd(){return jGd(),QFd};_.Bh=function qLd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:JD(this.Cb,179)&&(BD(this.Cb,179).tb=null);pnd(this,null);return;case 2:$Jd(this,null);_Jd(this,this.D);return;case 5:kKd(this,null);return;case 7:!this.A&&(this.A=new K4d(u5,this,7));Uxd(this.A);return;case 8:eLd(this,false);return;case 9:fLd(this,false);return;case 10:!!this.u&&vwd(this.u);return;case 11:!this.q&&(this.q=new cUd(n5,this,11,10));Uxd(this.q);return;case 21:!this.s&&(this.s=new cUd(t5,this,21,17));Uxd(this.s);return;case 22:!!this.n&&Uxd(this.n);return;}eid(this,a-aLd((jGd(),QFd)),XKd((b=BD(Ajd(this,16),26),!b?QFd:b),a))};_.Gh=function rLd(){var a,b;OKd(this);SKd(this);PKd(this);RKd(this);TKd(this);UKd(this);QKd(this);oud(SMd($Kd(this)));if(this.s){for(a=0,b=this.s.i;a<b;++a){Cmd(qud(this.s,a))}}if(this.q){for(a=0,b=this.q.i;a<b;++a){Cmd(qud(this.q,a))}}o1d((O6d(),M6d),this).ne();this.Bb|=1};_.Ib=function sLd(){return gLd(this)};_.k=null;_.r=null;var KKd,LKd,MKd;var Y5=mdb(qte,'EClassImpl',88);bcb(1994,1993,Ove);_.Vh=function tLd(a,b){return Pxd(this,a,b)};_.Wh=function uLd(a){return Pxd(this,this.i,a)};_.Xh=function vLd(a,b){Qxd(this,a,b)};_.Yh=function wLd(a){Rxd(this,a)};_.lk=function xLd(a,b){return Sxd(this,a,b)};_.pi=function yLd(a){return nud(this,a)};_.mk=function CLd(a,b){return Txd(this,a,b)};_.mi=function DLd(a,b){return Zxd(this,a,b)};_.Zh=function zLd(){return new $yd(this)};_.$h=function ALd(){return new bzd(this)};_._h=function BLd(a){return ztd(this,a)};var P9=mdb(yve,'NotifyingInternalEListImpl',1994);bcb(622,1994,Pve);_.Hc=function NLd(a){return ELd(this,a)};_.Zi=function OLd(a,b,c,d,e){return FLd(this,a,b,c,d,e)};_.$i=function PLd(a){GLd(this,a)};_.Wj=function QLd(a){return this};_.ak=function RLd(){return XKd(this.e.Tg(),this.aj())};_._i=function SLd(){return this.ak()};_.aj=function TLd(){return bLd(this.e.Tg(),this.ak())};_.zk=function ULd(){return BD(this.ak().Yj(),26).Bj()};_.Ak=function VLd(){return zUd(BD(this.ak(),18)).n};_.Ai=function WLd(){return this.e};_.Bk=function XLd(){return true};_.Ck=function YLd(){return false};_.Dk=function ZLd(){return false};_.Ek=function $Ld(){return false};_.Xc=function _Ld(a){return HLd(this,a)};_.cj=function aMd(a,b){var c;return c=BD(a,49),this.Dk()?this.Bk()?c.gh(this.e,this.Ak(),this.zk(),b):c.gh(this.e,bLd(c.Tg(),zUd(BD(this.ak(),18))),null,b):c.gh(this.e,-1-this.aj(),null,b)};_.dj=function bMd(a,b){var c;return c=BD(a,49),this.Dk()?this.Bk()?c.ih(this.e,this.Ak(),this.zk(),b):c.ih(this.e,bLd(c.Tg(),zUd(BD(this.ak(),18))),null,b):c.ih(this.e,-1-this.aj(),null,b)};_.rk=function cMd(){return false};_.Fk=function dMd(){return true};_.wj=function eMd(a){return qEd(this.d,a)};_.ej=function fMd(){return oid(this.e)};_.fj=function gMd(){return this.i!=0};_.ri=function hMd(a){return izd(this.d,a)};_.li=function iMd(a,b){return this.Fk()&&this.Ek()?ILd(this,a,BD(b,56)):b};_.Gk=function jMd(a){return a.kh()?xid(this.e,BD(a,49)):a};_.Wb=function kMd(a){JLd(this,a)};_.Pc=function lMd(){return KLd(this)};_.Qc=function mMd(a){var b;if(this.Ek()){for(b=this.i-1;b>=0;--b){qud(this,b)}}return xud(this,a)};_.Xj=function nMd(){Uxd(this)};_.oi=function oMd(a,b){return LLd(this,a,b)};var t9=mdb(yve,'EcoreEList',622);bcb(496,622,Pve,pMd);_.ai=function qMd(){return false};_.aj=function rMd(){return this.c};_.bj=function sMd(){return false};_.Fk=function tMd(){return true};_.hi=function uMd(){return true};_.li=function vMd(a,b){return b};_.ni=function wMd(){return false};_.c=0;var d9=mdb(yve,'EObjectEList',496);bcb(85,496,Pve,xMd);_.bj=function yMd(){return true};_.Dk=function zMd(){return false};_.rk=function AMd(){return true};var Z8=mdb(yve,'EObjectContainmentEList',85);bcb(545,85,Pve,BMd);_.ci=function CMd(){this.b=true};_.fj=function DMd(){return this.b};_.Xj=function EMd(){var a;Uxd(this);if(oid(this.e)){a=this.b;this.b=false;Uhd(this.e,new qSd(this.e,2,this.c,a,false))}else{this.b=false}};_.b=false;var Y8=mdb(yve,'EObjectContainmentEList/Unsettable',545);bcb(1140,545,Pve,JMd);_.ii=function NMd(a,b){var c,d;return c=BD(Wxd(this,a,b),87),oid(this.e)&&GLd(this,new ESd(this.a,7,(jGd(),SFd),meb(b),(d=c.c,JD(d,88)?BD(d,26):_Fd),a)),c};_.jj=function OMd(a,b){return GMd(this,BD(a,87),b)};_.kj=function PMd(a,b){return HMd(this,BD(a,87),b)};_.lj=function QMd(a,b,c){return IMd(this,BD(a,87),BD(b,87),c)};_.Zi=function KMd(a,b,c,d,e){switch(a){case 3:{return FLd(this,a,b,c,d,this.i>1)}case 5:{return FLd(this,a,b,c,d,this.i-BD(c,15).gc()>0)}default:{return new pSd(this.e,a,this.c,b,c,d,true)}}};_.ij=function LMd(){return true};_.fj=function MMd(){return FMd(this)};_.Xj=function RMd(){Uxd(this)};var N5=mdb(qte,'EClassImpl/1',1140);bcb(1154,1153,dve);_.ui=function VMd(a){var b,c,d,e,f,g,h;c=a.xi();if(c!=8){d=UMd(a);if(d==0){switch(c){case 1:case 9:{h=a.Bi();if(h!=null){b=$Kd(BD(h,473));!b.c&&(b.c=new xYd);Ftd(b.c,a.Ai())}g=a.zi();if(g!=null){e=BD(g,473);if((e.Bb&1)==0){b=$Kd(e);!b.c&&(b.c=new xYd);wtd(b.c,BD(a.Ai(),26))}}break}case 3:{g=a.zi();if(g!=null){e=BD(g,473);if((e.Bb&1)==0){b=$Kd(e);!b.c&&(b.c=new xYd);wtd(b.c,BD(a.Ai(),26))}}break}case 5:{g=a.zi();if(g!=null){for(f=BD(g,14).Kc();f.Ob();){e=BD(f.Pb(),473);if((e.Bb&1)==0){b=$Kd(e);!b.c&&(b.c=new xYd);wtd(b.c,BD(a.Ai(),26))}}}break}case 4:{h=a.Bi();if(h!=null){e=BD(h,473);if((e.Bb&1)==0){b=$Kd(e);!b.c&&(b.c=new xYd);Ftd(b.c,a.Ai())}}break}case 6:{h=a.Bi();if(h!=null){for(f=BD(h,14).Kc();f.Ob();){e=BD(f.Pb(),473);if((e.Bb&1)==0){b=$Kd(e);!b.c&&(b.c=new xYd);Ftd(b.c,a.Ai())}}}break}}}this.Hk(d)}};_.Hk=function WMd(a){TMd(this,a)};_.b=63;var p7=mdb(qte,'ESuperAdapter',1154);bcb(1155,1154,dve,YMd);_.Hk=function ZMd(a){XMd(this,a)};var I5=mdb(qte,'EClassImpl/10',1155);bcb(1144,696,Pve);_.Vh=function $Md(a,b){return iud(this,a,b)};_.Wh=function _Md(a){return jud(this,a)};_.Xh=function aNd(a,b){kud(this,a,b)};_.Yh=function bNd(a){lud(this,a)};_.pi=function dNd(a){return nud(this,a)};_.mi=function lNd(a,b){return uud(this,a,b)};_.lk=function cNd(a,b){throw vbb(new bgb)};_.Zh=function eNd(){return new $yd(this)};_.$h=function fNd(){return new bzd(this)};_._h=function gNd(a){return ztd(this,a)};_.mk=function hNd(a,b){throw vbb(new bgb)};_.Wj=function iNd(a){return this};_.fj=function jNd(){return this.i!=0};_.Wb=function kNd(a){throw vbb(new bgb)};_.Xj=function mNd(){throw vbb(new bgb)};var s9=mdb(yve,'EcoreEList/UnmodifiableEList',1144);bcb(319,1144,Pve,nNd);_.ni=function oNd(){return false};var r9=mdb(yve,'EcoreEList/UnmodifiableEList/FastCompare',319);bcb(1147,319,Pve,rNd);_.Xc=function sNd(a){var b,c,d;if(JD(a,170)){b=BD(a,170);c=b.aj();if(c!=-1){for(d=this.i;c<d;++c){if(PD(this.g[c])===PD(a)){return c}}}}return -1};var J5=mdb(qte,'EClassImpl/1EAllStructuralFeaturesList',1147);bcb(1141,497,oue,wNd);_.ri=function xNd(a){return KC(j5,Tve,87,a,0,1)};_.ni=function yNd(){return false};var K5=mdb(qte,'EClassImpl/1EGenericSuperTypeEList',1141);bcb(623,497,oue,zNd);_.ri=function ANd(a){return KC(t5,Mve,170,a,0,1)};_.ni=function BNd(){return false};var L5=mdb(qte,'EClassImpl/1EStructuralFeatureUniqueEList',623);bcb(741,497,oue,CNd);_.ri=function DNd(a){return KC(q5,Mve,18,a,0,1)};_.ni=function ENd(){return false};var M5=mdb(qte,'EClassImpl/1ReferenceList',741);bcb(1142,497,oue,GNd);_.bi=function HNd(a,b){FNd(this,BD(b,34))};_.ri=function INd(a){return KC(b5,Mve,34,a,0,1)};_.ni=function JNd(){return false};var O5=mdb(qte,'EClassImpl/2',1142);bcb(1143,497,oue,KNd);_.ri=function LNd(a){return KC(b5,Mve,34,a,0,1)};_.ni=function MNd(){return false};var P5=mdb(qte,'EClassImpl/3',1143);bcb(1145,319,Pve,PNd);_.Fc=function QNd(a){return NNd(this,BD(a,34))};_.Yh=function RNd(a){ONd(this,BD(a,34))};var Q5=mdb(qte,'EClassImpl/4',1145);bcb(1146,319,Pve,UNd);_.Fc=function VNd(a){return SNd(this,BD(a,18))};_.Yh=function WNd(a){TNd(this,BD(a,18))};var R5=mdb(qte,'EClassImpl/5',1146);bcb(1148,497,oue,XNd);_.ri=function YNd(a){return KC(n5,Nve,59,a,0,1)};_.ni=function ZNd(){return false};var S5=mdb(qte,'EClassImpl/6',1148);bcb(1149,497,oue,$Nd);_.ri=function _Nd(a){return KC(q5,Mve,18,a,0,1)};_.ni=function aOd(){return false};var T5=mdb(qte,'EClassImpl/7',1149);bcb(1997,1996,{3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1,69:1});_.Vh=function bOd(a,b){return qwd(this,a,b)};_.Wh=function cOd(a){return qwd(this,this.Vi(),a)};_.Xh=function dOd(a,b){rwd(this,a,b)};_.Yh=function eOd(a){swd(this,a)};_.lk=function fOd(a,b){return twd(this,a,b)};_.mk=function lOd(a,b){return uwd(this,a,b)};_.mi=function mOd(a,b){return wwd(this,a,b)};_.pi=function gOd(a){return this.Oi(a)};_.Zh=function hOd(){return new $yd(this)};_.Gi=function iOd(){return this.Ji()};_.$h=function jOd(){return new bzd(this)};_._h=function kOd(a){return ztd(this,a)};var L8=mdb(yve,'DelegatingNotifyingInternalEListImpl',1997);bcb(742,1997,Uve);_.ai=function rOd(){var a;a=XKd(wjd(this.b),this.aj()).Yj();return JD(a,148)&&!JD(a,457)&&(a.Bj().i&1)==0};_.Hc=function sOd(a){var b,c,d,e,f,g,h,i;if(this.Fk()){i=this.Vi();if(i>4){if(this.wj(a)){if(this.rk()){d=BD(a,49);c=d.Ug();h=c==this.b&&(this.Dk()?d.Og(d.Vg(),BD(XKd(wjd(this.b),this.aj()).Yj(),26).Bj())==zUd(BD(XKd(wjd(this.b),this.aj()),18)).n:-1-d.Vg()==this.aj());if(this.Ek()&&!h&&!c&&!!d.Zg()){for(e=0;e<i;++e){b=oOd(this,this.Oi(e));if(PD(b)===PD(a)){return true}}}return h}else if(this.Dk()&&!this.Ck()){f=BD(a,56).ah(zUd(BD(XKd(wjd(this.b),this.aj()),18)));if(PD(f)===PD(this.b)){return true}else if(f==null||!BD(f,56).kh()){return false}}}else{return false}}g=this.Li(a);if(this.Ek()&&!g){for(e=0;e<i;++e){d=oOd(this,this.Oi(e));if(PD(d)===PD(a)){return true}}}return g}else{return this.Li(a)}};_.Zi=function tOd(a,b,c,d,e){return new pSd(this.b,a,this.aj(),b,c,d,e)};_.$i=function uOd(a){Uhd(this.b,a)};_.Wj=function vOd(a){return this};_._i=function wOd(){return XKd(wjd(this.b),this.aj())};_.aj=function xOd(){return bLd(wjd(this.b),XKd(wjd(this.b),this.aj()))};_.Ai=function yOd(){return this.b};_.Bk=function zOd(){return !!XKd(wjd(this.b),this.aj()).Yj().Bj()};_.bj=function AOd(){var a,b;b=XKd(wjd(this.b),this.aj());if(JD(b,99)){a=BD(b,18);return (a.Bb&ote)!=0||!!zUd(BD(b,18))}else{return false}};_.Ck=function BOd(){var a,b,c,d;b=XKd(wjd(this.b),this.aj());if(JD(b,99)){a=BD(b,18);c=zUd(a);return !!c&&(d=c.t,d>1||d==-1)}else{return false}};_.Dk=function COd(){var a,b,c;b=XKd(wjd(this.b),this.aj());if(JD(b,99)){a=BD(b,18);c=zUd(a);return !!c}else{return false}};_.Ek=function DOd(){var a,b;b=XKd(wjd(this.b),this.aj());if(JD(b,99)){a=BD(b,18);return (a.Bb&Tje)!=0}else{return false}};_.Xc=function EOd(a){var b,c,d,e;d=this.Qi(a);if(d>=0)return d;if(this.Fk()){for(c=0,e=this.Vi();c<e;++c){b=oOd(this,this.Oi(c));if(PD(b)===PD(a)){return c}}}return -1};_.cj=function FOd(a,b){var c;return c=BD(a,49),this.Dk()?this.Bk()?c.gh(this.b,zUd(BD(XKd(wjd(this.b),this.aj()),18)).n,BD(XKd(wjd(this.b),this.aj()).Yj(),26).Bj(),b):c.gh(this.b,bLd(c.Tg(),zUd(BD(XKd(wjd(this.b),this.aj()),18))),null,b):c.gh(this.b,-1-this.aj(),null,b)};_.dj=function GOd(a,b){var c;return c=BD(a,49),this.Dk()?this.Bk()?c.ih(this.b,zUd(BD(XKd(wjd(this.b),this.aj()),18)).n,BD(XKd(wjd(this.b),this.aj()).Yj(),26).Bj(),b):c.ih(this.b,bLd(c.Tg(),zUd(BD(XKd(wjd(this.b),this.aj()),18))),null,b):c.ih(this.b,-1-this.aj(),null,b)};_.rk=function HOd(){var a,b;b=XKd(wjd(this.b),this.aj());if(JD(b,99)){a=BD(b,18);return (a.Bb&ote)!=0}else{return false}};_.Fk=function IOd(){return JD(XKd(wjd(this.b),this.aj()).Yj(),88)};_.wj=function JOd(a){return XKd(wjd(this.b),this.aj()).Yj().wj(a)};_.ej=function KOd(){return oid(this.b)};_.fj=function LOd(){return !this.Ri()};_.hi=function MOd(){return XKd(wjd(this.b),this.aj()).hi()};_.li=function NOd(a,b){return nOd(this,a,b)};_.Wb=function OOd(a){vwd(this);ytd(this,BD(a,15))};_.Pc=function POd(){var a;if(this.Ek()){for(a=this.Vi()-1;a>=0;--a){nOd(this,a,this.Oi(a))}}return this.Wi()};_.Qc=function QOd(a){var b;if(this.Ek()){for(b=this.Vi()-1;b>=0;--b){nOd(this,b,this.Oi(b))}}return this.Xi(a)};_.Xj=function ROd(){vwd(this)};_.oi=function SOd(a,b){return pOd(this,a,b)};var K8=mdb(yve,'DelegatingEcoreEList',742);bcb(1150,742,Uve,YOd);_.Hi=function _Od(a,b){TOd(this,a,BD(b,26))};_.Ii=function aPd(a){UOd(this,BD(a,26))};_.Oi=function gPd(a){var b,c;return b=BD(qud(VKd(this.a),a),87),c=b.c,JD(c,88)?BD(c,26):(jGd(),_Fd)};_.Ti=function lPd(a){var b,c;return b=BD(Xxd(VKd(this.a),a),87),c=b.c,JD(c,88)?BD(c,26):(jGd(),_Fd)};_.Ui=function mPd(a,b){return WOd(this,a,BD(b,26))};_.ai=function ZOd(){return false};_.Zi=function $Od(a,b,c,d,e){return null};_.Ji=function bPd(){return new EPd(this)};_.Ki=function cPd(){Uxd(VKd(this.a))};_.Li=function dPd(a){return VOd(this,a)};_.Mi=function ePd(a){var b,c;for(c=a.Kc();c.Ob();){b=c.Pb();if(!VOd(this,b)){return false}}return true};_.Ni=function fPd(a){var b,c,d;if(JD(a,15)){d=BD(a,15);if(d.gc()==VKd(this.a).i){for(b=d.Kc(),c=new Fyd(this);b.Ob();){if(PD(b.Pb())!==PD(Dyd(c))){return false}}return true}}return false};_.Pi=function hPd(){var a,b,c,d,e;c=1;for(b=new Fyd(VKd(this.a));b.e!=b.i.gc();){a=BD(Dyd(b),87);d=(e=a.c,JD(e,88)?BD(e,26):(jGd(),_Fd));c=31*c+(!d?0:FCb(d))}return c};_.Qi=function iPd(a){var b,c,d,e;d=0;for(c=new Fyd(VKd(this.a));c.e!=c.i.gc();){b=BD(Dyd(c),87);if(PD(a)===PD((e=b.c,JD(e,88)?BD(e,26):(jGd(),_Fd)))){return d}++d}return -1};_.Ri=function jPd(){return VKd(this.a).i==0};_.Si=function kPd(){return null};_.Vi=function nPd(){return VKd(this.a).i};_.Wi=function oPd(){var a,b,c,d,e,f;f=VKd(this.a).i;e=KC(SI,Uhe,1,f,5,1);c=0;for(b=new Fyd(VKd(this.a));b.e!=b.i.gc();){a=BD(Dyd(b),87);e[c++]=(d=a.c,JD(d,88)?BD(d,26):(jGd(),_Fd))}return e};_.Xi=function pPd(a){var b,c,d,e,f,g,h;h=VKd(this.a).i;if(a.length<h){e=izd(rb(a).c,h);a=e}a.length>h&&NC(a,h,null);d=0;for(c=new Fyd(VKd(this.a));c.e!=c.i.gc();){b=BD(Dyd(c),87);f=(g=b.c,JD(g,88)?BD(g,26):(jGd(),_Fd));NC(a,d++,f)}return a};_.Yi=function qPd(){var a,b,c,d,e;e=new Hfb;e.a+='[';a=VKd(this.a);for(b=0,d=VKd(this.a).i;b<d;){Efb(e,xfb((c=BD(qud(a,b),87).c,JD(c,88)?BD(c,26):(jGd(),_Fd))));++b<d&&(e.a+=She,e)}e.a+=']';return e.a};_.$i=function rPd(a){};_.aj=function sPd(){return 10};_.Bk=function tPd(){return true};_.bj=function uPd(){return false};_.Ck=function vPd(){return false};_.Dk=function wPd(){return false};_.Ek=function xPd(){return true};_.rk=function yPd(){return false};_.Fk=function zPd(){return true};_.wj=function APd(a){return JD(a,88)};_.fj=function BPd(){return cLd(this.a)};_.hi=function CPd(){return true};_.ni=function DPd(){return true};var V5=mdb(qte,'EClassImpl/8',1150);bcb(1151,1964,Lie,EPd);_.Zc=function FPd(a){return ztd(this.a,a)};_.gc=function GPd(){return VKd(this.a.a).i};var U5=mdb(qte,'EClassImpl/8/1',1151);bcb(1152,497,oue,HPd);_.ri=function IPd(a){return KC(d5,Uhe,138,a,0,1)};_.ni=function JPd(){return false};var W5=mdb(qte,'EClassImpl/9',1152);bcb(1139,53,gke,KPd);var X5=mdb(qte,'EClassImpl/MyHashSet',1139);bcb(566,351,{105:1,92:1,90:1,138:1,148:1,834:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,150:1,114:1,115:1,676:1},MPd);_._g=function NPd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.D!=null?this.D:this.B;case 3:return dKd(this);case 4:return this.zj();case 5:return this.F;case 6:if(b)return bKd(this);return ZJd(this);case 7:return !this.A&&(this.A=new K4d(u5,this,7)),this.A;case 8:return Bcb(),(this.Bb&256)!=0?true:false;}return bid(this,a-aLd(this.zh()),XKd((d=BD(Ajd(this,16),26),!d?this.zh():d),a),b,c)};_.lh=function OPd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return !!dKd(this);case 4:return this.zj()!=null;case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return !!ZJd(this);case 7:return !!this.A&&this.A.i!=0;case 8:return (this.Bb&256)==0;}return cid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.sh=function PPd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:lKd(this,GD(b));return;case 2:iKd(this,GD(b));return;case 5:kKd(this,GD(b));return;case 7:!this.A&&(this.A=new K4d(u5,this,7));Uxd(this.A);!this.A&&(this.A=new K4d(u5,this,7));ytd(this.A,BD(b,14));return;case 8:LPd(this,Ccb(DD(b)));return;}did(this,a-aLd(this.zh()),XKd((c=BD(Ajd(this,16),26),!c?this.zh():c),a),b)};_.zh=function QPd(){return jGd(),TFd};_.Bh=function RPd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:JD(this.Cb,179)&&(BD(this.Cb,179).tb=null);pnd(this,null);return;case 2:$Jd(this,null);_Jd(this,this.D);return;case 5:kKd(this,null);return;case 7:!this.A&&(this.A=new K4d(u5,this,7));Uxd(this.A);return;case 8:LPd(this,true);return;}eid(this,a-aLd(this.zh()),XKd((b=BD(Ajd(this,16),26),!b?this.zh():b),a))};_.Gh=function SPd(){o1d((O6d(),M6d),this).ne();this.Bb|=1};_.Fj=function TPd(){var a,b,c;if(!this.c){a=l6d(bKd(this));if(!a.dc()){for(c=a.Kc();c.Ob();){b=GD(c.Pb());!!Dmd(this,b)&&k6d(this)}}}return this.b};_.zj=function UPd(){var b;if(!this.e){b=null;try{b=dKd(this)}catch(a){a=ubb(a);if(!JD(a,102))throw vbb(a)}this.d=null;!!b&&(b.i&1)!=0&&(b==sbb?(this.d=(Bcb(),zcb)):b==WD?(this.d=meb(0)):b==VD?(this.d=new Ndb(0)):b==UD?(this.d=0):b==XD?(this.d=Aeb(0)):b==rbb?(this.d=Web(0)):b==SD?(this.d=Scb(0)):(this.d=bdb(0)));this.e=true}return this.d};_.Ej=function VPd(){return (this.Bb&256)!=0};_.Ik=function WPd(a){a&&(this.D='org.eclipse.emf.common.util.AbstractEnumerator')};_.xk=function XPd(a){gKd(this,a);this.Ik(a)};_.yk=function YPd(a){this.C=a;this.e=false};_.Ib=function ZPd(){var a;if((this.Db&64)!=0)return mKd(this);a=new Jfb(mKd(this));a.a+=' (serializable: ';Ffb(a,(this.Bb&256)!=0);a.a+=')';return a.a};_.c=false;_.d=null;_.e=false;var $5=mdb(qte,'EDataTypeImpl',566);bcb(457,566,{105:1,92:1,90:1,138:1,148:1,834:1,671:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,457:1,150:1,114:1,115:1,676:1},aQd);_._g=function bQd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.D!=null?this.D:this.B;case 3:return dKd(this);case 4:return $Pd(this);case 5:return this.F;case 6:if(b)return bKd(this);return ZJd(this);case 7:return !this.A&&(this.A=new K4d(u5,this,7)),this.A;case 8:return Bcb(),(this.Bb&256)!=0?true:false;case 9:return !this.a&&(this.a=new cUd(g5,this,9,5)),this.a;}return bid(this,a-aLd((jGd(),UFd)),XKd((d=BD(Ajd(this,16),26),!d?UFd:d),a),b,c)};_.hh=function cQd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 6:!!this.Cb&&(c=(e=this.Db>>16,e>=0?aKd(this,c):this.Cb.ih(this,-1-e,null,c)));return _hd(this,a,6,c);case 9:return !this.a&&(this.a=new cUd(g5,this,9,5)),Sxd(this.a,a,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),UFd):d),b),66),f.Nj().Qj(this,yjd(this),b-aLd((jGd(),UFd)),a,c)};_.jh=function dQd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 6:return _hd(this,null,6,c);case 7:return !this.A&&(this.A=new K4d(u5,this,7)),Txd(this.A,a,c);case 9:return !this.a&&(this.a=new cUd(g5,this,9,5)),Txd(this.a,a,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),UFd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),UFd)),a,c)};_.lh=function eQd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.D!=null&&this.D==this.F;case 3:return !!dKd(this);case 4:return !!$Pd(this);case 5:return this.F!=null&&this.F!=this.D&&this.F!=this.B;case 6:return !!ZJd(this);case 7:return !!this.A&&this.A.i!=0;case 8:return (this.Bb&256)==0;case 9:return !!this.a&&this.a.i!=0;}return cid(this,a-aLd((jGd(),UFd)),XKd((b=BD(Ajd(this,16),26),!b?UFd:b),a))};_.sh=function fQd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:lKd(this,GD(b));return;case 2:iKd(this,GD(b));return;case 5:kKd(this,GD(b));return;case 7:!this.A&&(this.A=new K4d(u5,this,7));Uxd(this.A);!this.A&&(this.A=new K4d(u5,this,7));ytd(this.A,BD(b,14));return;case 8:LPd(this,Ccb(DD(b)));return;case 9:!this.a&&(this.a=new cUd(g5,this,9,5));Uxd(this.a);!this.a&&(this.a=new cUd(g5,this,9,5));ytd(this.a,BD(b,14));return;}did(this,a-aLd((jGd(),UFd)),XKd((c=BD(Ajd(this,16),26),!c?UFd:c),a),b)};_.zh=function gQd(){return jGd(),UFd};_.Bh=function hQd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:JD(this.Cb,179)&&(BD(this.Cb,179).tb=null);pnd(this,null);return;case 2:$Jd(this,null);_Jd(this,this.D);return;case 5:kKd(this,null);return;case 7:!this.A&&(this.A=new K4d(u5,this,7));Uxd(this.A);return;case 8:LPd(this,true);return;case 9:!this.a&&(this.a=new cUd(g5,this,9,5));Uxd(this.a);return;}eid(this,a-aLd((jGd(),UFd)),XKd((b=BD(Ajd(this,16),26),!b?UFd:b),a))};_.Gh=function iQd(){var a,b;if(this.a){for(a=0,b=this.a.i;a<b;++a){Cmd(qud(this.a,a))}}o1d((O6d(),M6d),this).ne();this.Bb|=1};_.zj=function jQd(){return $Pd(this)};_.wj=function kQd(a){if(a!=null){return true}return false};_.Ik=function lQd(a){};var _5=mdb(qte,'EEnumImpl',457);bcb(573,438,{105:1,92:1,90:1,1940:1,678:1,147:1,191:1,56:1,108:1,49:1,97:1,573:1,150:1,114:1,115:1},rQd);_.ne=function AQd(){return this.zb};_.Qg=function sQd(a){return mQd(this,a)};_._g=function tQd(a,b,c){var d,e;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return meb(this.d);case 3:return this.b?this.b:this.a;case 4:return e=this.c,e==null?this.zb:e;case 5:return this.Db>>16==5?BD(this.Cb,671):null;}return bid(this,a-aLd((jGd(),VFd)),XKd((d=BD(Ajd(this,16),26),!d?VFd:d),a),b,c)};_.hh=function uQd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 5:!!this.Cb&&(c=(e=this.Db>>16,e>=0?mQd(this,c):this.Cb.ih(this,-1-e,null,c)));return _hd(this,a,5,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),VFd):d),b),66),f.Nj().Qj(this,yjd(this),b-aLd((jGd(),VFd)),a,c)};_.jh=function vQd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 5:return _hd(this,null,5,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),VFd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),VFd)),a,c)};_.lh=function wQd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return this.d!=0;case 3:return !!this.b;case 4:return this.c!=null;case 5:return !!(this.Db>>16==5?BD(this.Cb,671):null);}return cid(this,a-aLd((jGd(),VFd)),XKd((b=BD(Ajd(this,16),26),!b?VFd:b),a))};_.sh=function xQd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:pnd(this,GD(b));return;case 2:qQd(this,BD(b,19).a);return;case 3:oQd(this,BD(b,1940));return;case 4:pQd(this,GD(b));return;}did(this,a-aLd((jGd(),VFd)),XKd((c=BD(Ajd(this,16),26),!c?VFd:c),a),b)};_.zh=function yQd(){return jGd(),VFd};_.Bh=function zQd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:pnd(this,null);return;case 2:qQd(this,0);return;case 3:oQd(this,null);return;case 4:pQd(this,null);return;}eid(this,a-aLd((jGd(),VFd)),XKd((b=BD(Ajd(this,16),26),!b?VFd:b),a))};_.Ib=function BQd(){var a;return a=this.c,a==null?this.zb:a};_.b=null;_.c=null;_.d=0;var a6=mdb(qte,'EEnumLiteralImpl',573);var c6=odb(qte,'EFactoryImpl/InternalEDateTimeFormat');bcb(489,1,{2015:1},EQd);var b6=mdb(qte,'EFactoryImpl/1ClientInternalEDateTimeFormat',489);bcb(241,115,{105:1,92:1,90:1,87:1,56:1,108:1,49:1,97:1,241:1,114:1,115:1},UQd);_.Sg=function VQd(a,b,c){var d;c=_hd(this,a,b,c);if(!!this.e&&JD(a,170)){d=MQd(this,this.e);d!=this.c&&(c=QQd(this,d,c))}return c};_._g=function WQd(a,b,c){var d;switch(a){case 0:return this.f;case 1:return !this.d&&(this.d=new xMd(j5,this,1)),this.d;case 2:if(b)return KQd(this);return this.c;case 3:return this.b;case 4:return this.e;case 5:if(b)return JQd(this);return this.a;}return bid(this,a-aLd((jGd(),XFd)),XKd((d=BD(Ajd(this,16),26),!d?XFd:d),a),b,c)};_.jh=function XQd(a,b,c){var d,e;switch(b){case 0:return IQd(this,null,c);case 1:return !this.d&&(this.d=new xMd(j5,this,1)),Txd(this.d,a,c);case 3:return GQd(this,null,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),XFd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),XFd)),a,c)};_.lh=function YQd(a){var b;switch(a){case 0:return !!this.f;case 1:return !!this.d&&this.d.i!=0;case 2:return !!this.c;case 3:return !!this.b;case 4:return !!this.e;case 5:return !!this.a;}return cid(this,a-aLd((jGd(),XFd)),XKd((b=BD(Ajd(this,16),26),!b?XFd:b),a))};_.sh=function ZQd(a,b){var c;switch(a){case 0:SQd(this,BD(b,87));return;case 1:!this.d&&(this.d=new xMd(j5,this,1));Uxd(this.d);!this.d&&(this.d=new xMd(j5,this,1));ytd(this.d,BD(b,14));return;case 3:PQd(this,BD(b,87));return;case 4:RQd(this,BD(b,836));return;case 5:NQd(this,BD(b,138));return;}did(this,a-aLd((jGd(),XFd)),XKd((c=BD(Ajd(this,16),26),!c?XFd:c),a),b)};_.zh=function $Qd(){return jGd(),XFd};_.Bh=function _Qd(a){var b;switch(a){case 0:SQd(this,null);return;case 1:!this.d&&(this.d=new xMd(j5,this,1));Uxd(this.d);return;case 3:PQd(this,null);return;case 4:RQd(this,null);return;case 5:NQd(this,null);return;}eid(this,a-aLd((jGd(),XFd)),XKd((b=BD(Ajd(this,16),26),!b?XFd:b),a))};_.Ib=function aRd(){var a;a=new Wfb(Eid(this));a.a+=' (expression: ';TQd(this,a);a.a+=')';return a.a};var FQd;var e6=mdb(qte,'EGenericTypeImpl',241);bcb(1969,1964,Vve);_.Xh=function cRd(a,b){bRd(this,a,b)};_.lk=function dRd(a,b){bRd(this,this.gc(),a);return b};_.pi=function eRd(a){return Ut(this.Gi(),a)};_.Zh=function fRd(){return this.$h()};_.Gi=function gRd(){return new O0d(this)};_.$h=function hRd(){return this._h(0)};_._h=function iRd(a){return this.Gi().Zc(a)};_.mk=function jRd(a,b){ze(this,a,true);return b};_.ii=function kRd(a,b){var c,d;d=Vt(this,b);c=this.Zc(a);c.Rb(d);return d};_.ji=function lRd(a,b){var c;ze(this,b,true);c=this.Zc(a);c.Rb(b)};var B8=mdb(yve,'AbstractSequentialInternalEList',1969);bcb(486,1969,Vve,qRd);_.pi=function rRd(a){return Ut(this.Gi(),a)};_.Zh=function sRd(){if(this.b==null){return LRd(),LRd(),KRd}return this.Jk()};_.Gi=function tRd(){return new w4d(this.a,this.b)};_.$h=function uRd(){if(this.b==null){return LRd(),LRd(),KRd}return this.Jk()};_._h=function vRd(a){var b,c;if(this.b==null){if(a<0||a>1){throw vbb(new qcb(gve+a+', size=0'))}return LRd(),LRd(),KRd}c=this.Jk();for(b=0;b<a;++b){MRd(c)}return c};_.dc=function wRd(){var a,b,c,d,e,f;if(this.b!=null){for(c=0;c<this.b.length;++c){a=this.b[c];if(!this.Mk()||this.a.mh(a)){f=this.a.bh(a,false);Q6d();if(BD(a,66).Oj()){b=BD(f,153);for(d=0,e=b.gc();d<e;++d){if(oRd(b.il(d))&&b.jl(d)!=null){return false}}}else if(a.$j()){if(!BD(f,14).dc()){return false}}else if(f!=null){return false}}}}return true};_.Kc=function xRd(){return pRd(this)};_.Zc=function yRd(a){var b,c;if(this.b==null){if(a!=0){throw vbb(new qcb(gve+a+', size=0'))}return LRd(),LRd(),KRd}c=this.Lk()?this.Kk():this.Jk();for(b=0;b<a;++b){MRd(c)}return c};_.ii=function zRd(a,b){throw vbb(new bgb)};_.ji=function ARd(a,b){throw vbb(new bgb)};_.Jk=function BRd(){return new RRd(this.a,this.b)};_.Kk=function CRd(){return new dSd(this.a,this.b)};_.Lk=function DRd(){return true};_.gc=function ERd(){var a,b,c,d,e,f,g;e=0;if(this.b!=null){for(c=0;c<this.b.length;++c){a=this.b[c];if(!this.Mk()||this.a.mh(a)){g=this.a.bh(a,false);Q6d();if(BD(a,66).Oj()){b=BD(g,153);for(d=0,f=b.gc();d<f;++d){oRd(b.il(d))&&b.jl(d)!=null&&++e}}else a.$j()?(e+=BD(g,14).gc()):g!=null&&++e}}}return e};_.Mk=function FRd(){return true};var mRd;var R8=mdb(yve,'EContentsEList',486);bcb(1156,486,Vve,GRd);_.Jk=function HRd(){return new hSd(this.a,this.b)};_.Kk=function IRd(){return new fSd(this.a,this.b)};_.Mk=function JRd(){return false};var i6=mdb(qte,'ENamedElementImpl/1',1156);bcb(279,1,Wve,RRd);_.Nb=function URd(a){Rrb(this,a)};_.Rb=function SRd(a){throw vbb(new bgb)};_.Nk=function TRd(a){if(this.g!=0||!!this.e){throw vbb(new Zdb('Iterator already in use or already filtered'))}this.e=a};_.Ob=function VRd(){var a,b,c,d,e,f;switch(this.g){case 3:case 2:{return true}case 1:{return false}case -3:{!this.p?++this.n:this.p.Pb()}default:{if(!this.k||(!this.p?!NRd(this):!ORd(this,this.p))){while(this.d<this.c.length){b=this.c[this.d++];if((!this.e||b.Gj()!=x2||b.aj()!=0)&&(!this.Mk()||this.b.mh(b))){f=this.b.bh(b,this.Lk());this.f=(Q6d(),BD(b,66).Oj());if(this.f||b.$j()){if(this.Lk()){d=BD(f,15);this.k=d}else{d=BD(f,69);this.k=this.j=d}if(JD(this.k,54)){this.p=null;this.o=this.k.gc();this.n=0}else{this.p=!this.j?this.k.Yc():this.j.$h()}if(!this.p?NRd(this):ORd(this,this.p)){e=!this.p?!this.j?this.k.Xb(this.n++):this.j.pi(this.n++):this.p.Pb();if(this.f){a=BD(e,72);a.ak();c=a.dd();this.i=c}else{c=e;this.i=c}this.g=3;return true}}else if(f!=null){this.k=null;this.p=null;c=f;this.i=c;this.g=2;return true}}}this.k=null;this.p=null;this.f=false;this.g=1;return false}else{e=!this.p?!this.j?this.k.Xb(this.n++):this.j.pi(this.n++):this.p.Pb();if(this.f){a=BD(e,72);a.ak();c=a.dd();this.i=c}else{c=e;this.i=c}this.g=3;return true}}}};_.Sb=function WRd(){var a,b,c,d,e,f;switch(this.g){case -3:case -2:{return true}case -1:{return false}case 3:{!this.p?--this.n:this.p.Ub()}default:{if(!this.k||(!this.p?!PRd(this):!QRd(this,this.p))){while(this.d>0){b=this.c[--this.d];if((!this.e||b.Gj()!=x2||b.aj()!=0)&&(!this.Mk()||this.b.mh(b))){f=this.b.bh(b,this.Lk());this.f=(Q6d(),BD(b,66).Oj());if(this.f||b.$j()){if(this.Lk()){d=BD(f,15);this.k=d}else{d=BD(f,69);this.k=this.j=d}if(JD(this.k,54)){this.o=this.k.gc();this.n=this.o}else{this.p=!this.j?this.k.Zc(this.k.gc()):this.j._h(this.k.gc())}if(!this.p?PRd(this):QRd(this,this.p)){e=!this.p?!this.j?this.k.Xb(--this.n):this.j.pi(--this.n):this.p.Ub();if(this.f){a=BD(e,72);a.ak();c=a.dd();this.i=c}else{c=e;this.i=c}this.g=-3;return true}}else if(f!=null){this.k=null;this.p=null;c=f;this.i=c;this.g=-2;return true}}}this.k=null;this.p=null;this.g=-1;return false}else{e=!this.p?!this.j?this.k.Xb(--this.n):this.j.pi(--this.n):this.p.Ub();if(this.f){a=BD(e,72);a.ak();c=a.dd();this.i=c}else{c=e;this.i=c}this.g=-3;return true}}}};_.Pb=function XRd(){return MRd(this)};_.Tb=function YRd(){return this.a};_.Ub=function ZRd(){var a;if(this.g<-1||this.Sb()){--this.a;this.g=0;a=this.i;this.Sb();return a}else{throw vbb(new utb)}};_.Vb=function $Rd(){return this.a-1};_.Qb=function _Rd(){throw vbb(new bgb)};_.Lk=function aSd(){return false};_.Wb=function bSd(a){throw vbb(new bgb)};_.Mk=function cSd(){return true};_.a=0;_.d=0;_.f=false;_.g=0;_.n=0;_.o=0;var KRd;var P8=mdb(yve,'EContentsEList/FeatureIteratorImpl',279);bcb(697,279,Wve,dSd);_.Lk=function eSd(){return true};var Q8=mdb(yve,'EContentsEList/ResolvingFeatureIteratorImpl',697);bcb(1157,697,Wve,fSd);_.Mk=function gSd(){return false};var g6=mdb(qte,'ENamedElementImpl/1/1',1157);bcb(1158,279,Wve,hSd);_.Mk=function iSd(){return false};var h6=mdb(qte,'ENamedElementImpl/1/2',1158);bcb(36,143,fve,lSd,mSd,nSd,oSd,pSd,qSd,rSd,sSd,tSd,uSd,vSd,wSd,xSd,ySd,zSd,ASd,BSd,CSd,DSd,ESd,FSd,GSd,HSd,ISd,JSd);_._i=function KSd(){return kSd(this)};_.gj=function LSd(){var a;a=kSd(this);if(a){return a.zj()}return null};_.yi=function MSd(a){this.b==-1&&!!this.a&&(this.b=this.c.Xg(this.a.aj(),this.a.Gj()));return this.c.Og(this.b,a)};_.Ai=function NSd(){return this.c};_.hj=function OSd(){var a;a=kSd(this);if(a){return a.Kj()}return false};_.b=-1;var k6=mdb(qte,'ENotificationImpl',36);bcb(399,284,{105:1,92:1,90:1,147:1,191:1,56:1,59:1,108:1,472:1,49:1,97:1,150:1,399:1,284:1,114:1,115:1},SSd);_.Qg=function TSd(a){return PSd(this,a)};_._g=function USd(a,b,c){var d,e,f;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Bcb(),(this.Bb&256)!=0?true:false;case 3:return Bcb(),(this.Bb&512)!=0?true:false;case 4:return meb(this.s);case 5:return meb(this.t);case 6:return Bcb(),f=this.t,f>1||f==-1?true:false;case 7:return Bcb(),e=this.s,e>=1?true:false;case 8:if(b)return wId(this);return this.r;case 9:return this.q;case 10:return this.Db>>16==10?BD(this.Cb,26):null;case 11:return !this.d&&(this.d=new K4d(u5,this,11)),this.d;case 12:return !this.c&&(this.c=new cUd(p5,this,12,10)),this.c;case 13:return !this.a&&(this.a=new fTd(this,this)),this.a;case 14:return QSd(this);}return bid(this,a-aLd((jGd(),aGd)),XKd((d=BD(Ajd(this,16),26),!d?aGd:d),a),b,c)};_.hh=function VSd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 10:!!this.Cb&&(c=(e=this.Db>>16,e>=0?PSd(this,c):this.Cb.ih(this,-1-e,null,c)));return _hd(this,a,10,c);case 12:return !this.c&&(this.c=new cUd(p5,this,12,10)),Sxd(this.c,a,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),aGd):d),b),66),f.Nj().Qj(this,yjd(this),b-aLd((jGd(),aGd)),a,c)};_.jh=function WSd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 9:return vId(this,c);case 10:return _hd(this,null,10,c);case 11:return !this.d&&(this.d=new K4d(u5,this,11)),Txd(this.d,a,c);case 12:return !this.c&&(this.c=new cUd(p5,this,12,10)),Txd(this.c,a,c);case 14:return Txd(QSd(this),a,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),aGd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),aGd)),a,c)};_.lh=function XSd(a){var b,c,d;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return d=this.t,d>1||d==-1;case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&LQd(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&LQd(this.q).i==0);case 10:return !!(this.Db>>16==10?BD(this.Cb,26):null);case 11:return !!this.d&&this.d.i!=0;case 12:return !!this.c&&this.c.i!=0;case 13:return !!this.a&&QSd(this.a.a).i!=0&&!(!!this.b&&QTd(this.b));case 14:return !!this.b&&QTd(this.b);}return cid(this,a-aLd((jGd(),aGd)),XKd((b=BD(Ajd(this,16),26),!b?aGd:b),a))};_.sh=function YSd(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:pnd(this,GD(b));return;case 2:BId(this,Ccb(DD(b)));return;case 3:CId(this,Ccb(DD(b)));return;case 4:AId(this,BD(b,19).a);return;case 5:DId(this,BD(b,19).a);return;case 8:yId(this,BD(b,138));return;case 9:d=xId(this,BD(b,87),null);!!d&&d.Fi();return;case 11:!this.d&&(this.d=new K4d(u5,this,11));Uxd(this.d);!this.d&&(this.d=new K4d(u5,this,11));ytd(this.d,BD(b,14));return;case 12:!this.c&&(this.c=new cUd(p5,this,12,10));Uxd(this.c);!this.c&&(this.c=new cUd(p5,this,12,10));ytd(this.c,BD(b,14));return;case 13:!this.a&&(this.a=new fTd(this,this));vwd(this.a);!this.a&&(this.a=new fTd(this,this));ytd(this.a,BD(b,14));return;case 14:Uxd(QSd(this));ytd(QSd(this),BD(b,14));return;}did(this,a-aLd((jGd(),aGd)),XKd((c=BD(Ajd(this,16),26),!c?aGd:c),a),b)};_.zh=function ZSd(){return jGd(),aGd};_.Bh=function $Sd(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:pnd(this,null);return;case 2:BId(this,true);return;case 3:CId(this,true);return;case 4:AId(this,0);return;case 5:DId(this,1);return;case 8:yId(this,null);return;case 9:c=xId(this,null,null);!!c&&c.Fi();return;case 11:!this.d&&(this.d=new K4d(u5,this,11));Uxd(this.d);return;case 12:!this.c&&(this.c=new cUd(p5,this,12,10));Uxd(this.c);return;case 13:!!this.a&&vwd(this.a);return;case 14:!!this.b&&Uxd(this.b);return;}eid(this,a-aLd((jGd(),aGd)),XKd((b=BD(Ajd(this,16),26),!b?aGd:b),a))};_.Gh=function _Sd(){var a,b;if(this.c){for(a=0,b=this.c.i;a<b;++a){Cmd(qud(this.c,a))}}wId(this);this.Bb|=1};var p6=mdb(qte,'EOperationImpl',399);bcb(505,742,Uve,fTd);_.Hi=function iTd(a,b){aTd(this,a,BD(b,138))};_.Ii=function jTd(a){bTd(this,BD(a,138))};_.Oi=function pTd(a){var b,c;return b=BD(qud(QSd(this.a),a),87),c=b.c,c?c:(jGd(),YFd)};_.Ti=function uTd(a){var b,c;return b=BD(Xxd(QSd(this.a),a),87),c=b.c,c?c:(jGd(),YFd)};_.Ui=function vTd(a,b){return dTd(this,a,BD(b,138))};_.ai=function gTd(){return false};_.Zi=function hTd(a,b,c,d,e){return null};_.Ji=function kTd(){return new NTd(this)};_.Ki=function lTd(){Uxd(QSd(this.a))};_.Li=function mTd(a){return cTd(this,a)};_.Mi=function nTd(a){var b,c;for(c=a.Kc();c.Ob();){b=c.Pb();if(!cTd(this,b)){return false}}return true};_.Ni=function oTd(a){var b,c,d;if(JD(a,15)){d=BD(a,15);if(d.gc()==QSd(this.a).i){for(b=d.Kc(),c=new Fyd(this);b.Ob();){if(PD(b.Pb())!==PD(Dyd(c))){return false}}return true}}return false};_.Pi=function qTd(){var a,b,c,d,e;c=1;for(b=new Fyd(QSd(this.a));b.e!=b.i.gc();){a=BD(Dyd(b),87);d=(e=a.c,e?e:(jGd(),YFd));c=31*c+(!d?0:tb(d))}return c};_.Qi=function rTd(a){var b,c,d,e;d=0;for(c=new Fyd(QSd(this.a));c.e!=c.i.gc();){b=BD(Dyd(c),87);if(PD(a)===PD((e=b.c,e?e:(jGd(),YFd)))){return d}++d}return -1};_.Ri=function sTd(){return QSd(this.a).i==0};_.Si=function tTd(){return null};_.Vi=function wTd(){return QSd(this.a).i};_.Wi=function xTd(){var a,b,c,d,e,f;f=QSd(this.a).i;e=KC(SI,Uhe,1,f,5,1);c=0;for(b=new Fyd(QSd(this.a));b.e!=b.i.gc();){a=BD(Dyd(b),87);e[c++]=(d=a.c,d?d:(jGd(),YFd))}return e};_.Xi=function yTd(a){var b,c,d,e,f,g,h;h=QSd(this.a).i;if(a.length<h){e=izd(rb(a).c,h);a=e}a.length>h&&NC(a,h,null);d=0;for(c=new Fyd(QSd(this.a));c.e!=c.i.gc();){b=BD(Dyd(c),87);f=(g=b.c,g?g:(jGd(),YFd));NC(a,d++,f)}return a};_.Yi=function zTd(){var a,b,c,d,e;e=new Hfb;e.a+='[';a=QSd(this.a);for(b=0,d=QSd(this.a).i;b<d;){Efb(e,xfb((c=BD(qud(a,b),87).c,c?c:(jGd(),YFd))));++b<d&&(e.a+=She,e)}e.a+=']';return e.a};_.$i=function ATd(a){};_.aj=function BTd(){return 13};_.Bk=function CTd(){return true};_.bj=function DTd(){return false};_.Ck=function ETd(){return false};_.Dk=function FTd(){return false};_.Ek=function GTd(){return true};_.rk=function HTd(){return false};_.Fk=function ITd(){return true};_.wj=function JTd(a){return JD(a,138)};_.fj=function KTd(){return RSd(this.a)};_.hi=function LTd(){return true};_.ni=function MTd(){return true};var n6=mdb(qte,'EOperationImpl/1',505);bcb(1340,1964,Lie,NTd);_.Zc=function OTd(a){return ztd(this.a,a)};_.gc=function PTd(){return QSd(this.a.a).i};var m6=mdb(qte,'EOperationImpl/1/1',1340);bcb(1341,545,Pve,UTd);_.ii=function YTd(a,b){var c,d;return c=BD(Wxd(this,a,b),87),oid(this.e)&&GLd(this,new ESd(this.a,7,(jGd(),bGd),meb(b),(d=c.c,d?d:YFd),a)),c};_.jj=function ZTd(a,b){return RTd(this,BD(a,87),b)};_.kj=function $Td(a,b){return STd(this,BD(a,87),b)};_.lj=function _Td(a,b,c){return TTd(this,BD(a,87),BD(b,87),c)};_.Zi=function VTd(a,b,c,d,e){switch(a){case 3:{return FLd(this,a,b,c,d,this.i>1)}case 5:{return FLd(this,a,b,c,d,this.i-BD(c,15).gc()>0)}default:{return new pSd(this.e,a,this.c,b,c,d,true)}}};_.ij=function WTd(){return true};_.fj=function XTd(){return QTd(this)};_.Xj=function aUd(){Uxd(this)};var o6=mdb(qte,'EOperationImpl/2',1341);bcb(498,1,{1938:1,498:1},bUd);var q6=mdb(qte,'EPackageImpl/1',498);bcb(16,85,Pve,cUd);_.zk=function dUd(){return this.d};_.Ak=function eUd(){return this.b};_.Dk=function fUd(){return true};_.b=0;var b9=mdb(yve,'EObjectContainmentWithInverseEList',16);bcb(353,16,Pve,gUd);_.Ek=function hUd(){return true};_.li=function iUd(a,b){return ILd(this,a,BD(b,56))};var $8=mdb(yve,'EObjectContainmentWithInverseEList/Resolving',353);bcb(298,353,Pve,jUd);_.ci=function kUd(){this.a.tb=null};var r6=mdb(qte,'EPackageImpl/2',298);bcb(1228,1,{},lUd);var s6=mdb(qte,'EPackageImpl/3',1228);bcb(718,43,fke,oUd);_._b=function pUd(a){return ND(a)?Qhb(this,a):!!irb(this.f,a)};var u6=mdb(qte,'EPackageRegistryImpl',718);bcb(509,284,{105:1,92:1,90:1,147:1,191:1,56:1,2017:1,108:1,472:1,49:1,97:1,150:1,509:1,284:1,114:1,115:1},rUd);_.Qg=function sUd(a){return qUd(this,a)};_._g=function tUd(a,b,c){var d,e,f;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Bcb(),(this.Bb&256)!=0?true:false;case 3:return Bcb(),(this.Bb&512)!=0?true:false;case 4:return meb(this.s);case 5:return meb(this.t);case 6:return Bcb(),f=this.t,f>1||f==-1?true:false;case 7:return Bcb(),e=this.s,e>=1?true:false;case 8:if(b)return wId(this);return this.r;case 9:return this.q;case 10:return this.Db>>16==10?BD(this.Cb,59):null;}return bid(this,a-aLd((jGd(),dGd)),XKd((d=BD(Ajd(this,16),26),!d?dGd:d),a),b,c)};_.hh=function uUd(a,b,c){var d,e,f;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Sxd(this.Ab,a,c);case 10:!!this.Cb&&(c=(e=this.Db>>16,e>=0?qUd(this,c):this.Cb.ih(this,-1-e,null,c)));return _hd(this,a,10,c);}return f=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),dGd):d),b),66),f.Nj().Qj(this,yjd(this),b-aLd((jGd(),dGd)),a,c)};_.jh=function vUd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 9:return vId(this,c);case 10:return _hd(this,null,10,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),dGd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),dGd)),a,c)};_.lh=function wUd(a){var b,c,d;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return d=this.t,d>1||d==-1;case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&LQd(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&LQd(this.q).i==0);case 10:return !!(this.Db>>16==10?BD(this.Cb,59):null);}return cid(this,a-aLd((jGd(),dGd)),XKd((b=BD(Ajd(this,16),26),!b?dGd:b),a))};_.zh=function xUd(){return jGd(),dGd};var v6=mdb(qte,'EParameterImpl',509);bcb(99,449,{105:1,92:1,90:1,147:1,191:1,56:1,18:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,99:1,449:1,284:1,114:1,115:1,677:1},FUd);_._g=function GUd(a,b,c){var d,e,f,g;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return Bcb(),(this.Bb&256)!=0?true:false;case 3:return Bcb(),(this.Bb&512)!=0?true:false;case 4:return meb(this.s);case 5:return meb(this.t);case 6:return Bcb(),g=this.t,g>1||g==-1?true:false;case 7:return Bcb(),e=this.s,e>=1?true:false;case 8:if(b)return wId(this);return this.r;case 9:return this.q;case 10:return Bcb(),(this.Bb&zte)!=0?true:false;case 11:return Bcb(),(this.Bb&Dve)!=0?true:false;case 12:return Bcb(),(this.Bb&Rje)!=0?true:false;case 13:return this.j;case 14:return VId(this);case 15:return Bcb(),(this.Bb&Cve)!=0?true:false;case 16:return Bcb(),(this.Bb&oie)!=0?true:false;case 17:return WId(this);case 18:return Bcb(),(this.Bb&ote)!=0?true:false;case 19:return Bcb(),f=zUd(this),!!f&&(f.Bb&ote)!=0?true:false;case 20:return Bcb(),(this.Bb&Tje)!=0?true:false;case 21:if(b)return zUd(this);return this.b;case 22:if(b)return AUd(this);return yUd(this);case 23:return !this.a&&(this.a=new _4d(b5,this,23)),this.a;}return bid(this,a-aLd((jGd(),eGd)),XKd((d=BD(Ajd(this,16),26),!d?eGd:d),a),b,c)};_.lh=function HUd(a){var b,c,d,e;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return (this.Bb&256)==0;case 3:return (this.Bb&512)==0;case 4:return this.s!=0;case 5:return this.t!=1;case 6:return e=this.t,e>1||e==-1;case 7:return c=this.s,c>=1;case 8:return !!this.r&&!this.q.e&&LQd(this.q).i==0;case 9:return !!this.q&&!(!!this.r&&!this.q.e&&LQd(this.q).i==0);case 10:return (this.Bb&zte)==0;case 11:return (this.Bb&Dve)!=0;case 12:return (this.Bb&Rje)!=0;case 13:return this.j!=null;case 14:return VId(this)!=null;case 15:return (this.Bb&Cve)!=0;case 16:return (this.Bb&oie)!=0;case 17:return !!WId(this);case 18:return (this.Bb&ote)!=0;case 19:return d=zUd(this),!!d&&(d.Bb&ote)!=0;case 20:return (this.Bb&Tje)==0;case 21:return !!this.b;case 22:return !!yUd(this);case 23:return !!this.a&&this.a.i!=0;}return cid(this,a-aLd((jGd(),eGd)),XKd((b=BD(Ajd(this,16),26),!b?eGd:b),a))};_.sh=function IUd(a,b){var c,d;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:cJd(this,GD(b));return;case 2:BId(this,Ccb(DD(b)));return;case 3:CId(this,Ccb(DD(b)));return;case 4:AId(this,BD(b,19).a);return;case 5:DId(this,BD(b,19).a);return;case 8:yId(this,BD(b,138));return;case 9:d=xId(this,BD(b,87),null);!!d&&d.Fi();return;case 10:ZId(this,Ccb(DD(b)));return;case 11:fJd(this,Ccb(DD(b)));return;case 12:dJd(this,Ccb(DD(b)));return;case 13:$Id(this,GD(b));return;case 15:eJd(this,Ccb(DD(b)));return;case 16:aJd(this,Ccb(DD(b)));return;case 18:BUd(this,Ccb(DD(b)));return;case 20:EUd(this,Ccb(DD(b)));return;case 21:DUd(this,BD(b,18));return;case 23:!this.a&&(this.a=new _4d(b5,this,23));Uxd(this.a);!this.a&&(this.a=new _4d(b5,this,23));ytd(this.a,BD(b,14));return;}did(this,a-aLd((jGd(),eGd)),XKd((c=BD(Ajd(this,16),26),!c?eGd:c),a),b)};_.zh=function JUd(){return jGd(),eGd};_.Bh=function KUd(a){var b,c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:JD(this.Cb,88)&&XMd($Kd(BD(this.Cb,88)),4);pnd(this,null);return;case 2:BId(this,true);return;case 3:CId(this,true);return;case 4:AId(this,0);return;case 5:DId(this,1);return;case 8:yId(this,null);return;case 9:c=xId(this,null,null);!!c&&c.Fi();return;case 10:ZId(this,true);return;case 11:fJd(this,false);return;case 12:dJd(this,false);return;case 13:this.i=null;_Id(this,null);return;case 15:eJd(this,false);return;case 16:aJd(this,false);return;case 18:CUd(this,false);JD(this.Cb,88)&&XMd($Kd(BD(this.Cb,88)),2);return;case 20:EUd(this,true);return;case 21:DUd(this,null);return;case 23:!this.a&&(this.a=new _4d(b5,this,23));Uxd(this.a);return;}eid(this,a-aLd((jGd(),eGd)),XKd((b=BD(Ajd(this,16),26),!b?eGd:b),a))};_.Gh=function LUd(){AUd(this);a2d(q1d((O6d(),M6d),this));wId(this);this.Bb|=1};_.Lj=function MUd(){return zUd(this)};_.qk=function NUd(){var a;return a=zUd(this),!!a&&(a.Bb&ote)!=0};_.rk=function OUd(){return (this.Bb&ote)!=0};_.sk=function PUd(){return (this.Bb&Tje)!=0};_.nk=function QUd(a,b){this.c=null;return zId(this,a,b)};_.Ib=function RUd(){var a;if((this.Db&64)!=0)return gJd(this);a=new Jfb(gJd(this));a.a+=' (containment: ';Ffb(a,(this.Bb&ote)!=0);a.a+=', resolveProxies: ';Ffb(a,(this.Bb&Tje)!=0);a.a+=')';return a.a};var w6=mdb(qte,'EReferenceImpl',99);bcb(548,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,548:1,114:1,115:1},XUd);_.Fb=function bVd(a){return this===a};_.cd=function dVd(){return this.b};_.dd=function eVd(){return this.c};_.Hb=function fVd(){return FCb(this)};_.Uh=function hVd(a){SUd(this,GD(a))};_.ed=function iVd(a){return WUd(this,GD(a))};_._g=function YUd(a,b,c){var d;switch(a){case 0:return this.b;case 1:return this.c;}return bid(this,a-aLd((jGd(),fGd)),XKd((d=BD(Ajd(this,16),26),!d?fGd:d),a),b,c)};_.lh=function ZUd(a){var b;switch(a){case 0:return this.b!=null;case 1:return this.c!=null;}return cid(this,a-aLd((jGd(),fGd)),XKd((b=BD(Ajd(this,16),26),!b?fGd:b),a))};_.sh=function $Ud(a,b){var c;switch(a){case 0:TUd(this,GD(b));return;case 1:VUd(this,GD(b));return;}did(this,a-aLd((jGd(),fGd)),XKd((c=BD(Ajd(this,16),26),!c?fGd:c),a),b)};_.zh=function _Ud(){return jGd(),fGd};_.Bh=function aVd(a){var b;switch(a){case 0:UUd(this,null);return;case 1:VUd(this,null);return;}eid(this,a-aLd((jGd(),fGd)),XKd((b=BD(Ajd(this,16),26),!b?fGd:b),a))};_.Sh=function cVd(){var a;if(this.a==-1){a=this.b;this.a=a==null?0:LCb(a)}return this.a};_.Th=function gVd(a){this.a=a};_.Ib=function jVd(){var a;if((this.Db&64)!=0)return Eid(this);a=new Jfb(Eid(this));a.a+=' (key: ';Efb(a,this.b);a.a+=', value: ';Efb(a,this.c);a.a+=')';return a.a};_.a=-1;_.b=null;_.c=null;var x6=mdb(qte,'EStringToStringMapEntryImpl',548);var D9=odb(yve,'FeatureMap/Entry/Internal');bcb(565,1,Xve);_.Ok=function mVd(a){return this.Pk(BD(a,49))};_.Pk=function nVd(a){return this.Ok(a)};_.Fb=function oVd(a){var b,c;if(this===a){return true}else if(JD(a,72)){b=BD(a,72);if(b.ak()==this.c){c=this.dd();return c==null?b.dd()==null:pb(c,b.dd())}else{return false}}else{return false}};_.ak=function pVd(){return this.c};_.Hb=function qVd(){var a;a=this.dd();return tb(this.c)^(a==null?0:tb(a))};_.Ib=function rVd(){var a,b;a=this.c;b=bKd(a.Hj()).Ph();a.ne();return (b!=null&&b.length!=0?b+':'+a.ne():a.ne())+'='+this.dd()};var y6=mdb(qte,'EStructuralFeatureImpl/BasicFeatureMapEntry',565);bcb(776,565,Xve,uVd);_.Pk=function vVd(a){return new uVd(this.c,a)};_.dd=function wVd(){return this.a};_.Qk=function xVd(a,b,c){return sVd(this,a,this.a,b,c)};_.Rk=function yVd(a,b,c){return tVd(this,a,this.a,b,c)};var z6=mdb(qte,'EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry',776);bcb(1314,1,{},zVd);_.Pj=function AVd(a,b,c,d,e){var f;f=BD(gid(a,this.b),215);return f.nl(this.a).Wj(d)};_.Qj=function BVd(a,b,c,d,e){var f;f=BD(gid(a,this.b),215);return f.el(this.a,d,e)};_.Rj=function CVd(a,b,c,d,e){var f;f=BD(gid(a,this.b),215);return f.fl(this.a,d,e)};_.Sj=function DVd(a,b,c){var d;d=BD(gid(a,this.b),215);return d.nl(this.a).fj()};_.Tj=function EVd(a,b,c,d){var e;e=BD(gid(a,this.b),215);e.nl(this.a).Wb(d)};_.Uj=function FVd(a,b,c){return BD(gid(a,this.b),215).nl(this.a)};_.Vj=function GVd(a,b,c){var d;d=BD(gid(a,this.b),215);d.nl(this.a).Xj()};var A6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator',1314);bcb(89,1,{},IVd,JVd,KVd,LVd);_.Pj=function MVd(a,b,c,d,e){var f;f=b.Ch(c);f==null&&b.Dh(c,f=HVd(this,a));if(!e){switch(this.e){case 50:case 41:return BD(f,589).sj();case 40:return BD(f,215).kl();}}return f};_.Qj=function NVd(a,b,c,d,e){var f,g;g=b.Ch(c);g==null&&b.Dh(c,g=HVd(this,a));f=BD(g,69).lk(d,e);return f};_.Rj=function OVd(a,b,c,d,e){var f;f=b.Ch(c);f!=null&&(e=BD(f,69).mk(d,e));return e};_.Sj=function PVd(a,b,c){var d;d=b.Ch(c);return d!=null&&BD(d,76).fj()};_.Tj=function QVd(a,b,c,d){var e;e=BD(b.Ch(c),76);!e&&b.Dh(c,e=HVd(this,a));e.Wb(d)};_.Uj=function RVd(a,b,c){var d,e;e=b.Ch(c);e==null&&b.Dh(c,e=HVd(this,a));if(JD(e,76)){return BD(e,76)}else{d=BD(b.Ch(c),15);return new iYd(d)}};_.Vj=function SVd(a,b,c){var d;d=BD(b.Ch(c),76);!d&&b.Dh(c,d=HVd(this,a));d.Xj()};_.b=0;_.e=0;var B6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateMany',89);bcb(504,1,{});_.Qj=function WVd(a,b,c,d,e){throw vbb(new bgb)};_.Rj=function XVd(a,b,c,d,e){throw vbb(new bgb)};_.Uj=function YVd(a,b,c){return new ZVd(this,a,b,c)};var TVd;var i7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingle',504);bcb(1331,1,zve,ZVd);_.Wj=function $Vd(a){return this.a.Pj(this.c,this.d,this.b,a,true)};_.fj=function _Vd(){return this.a.Sj(this.c,this.d,this.b)};_.Wb=function aWd(a){this.a.Tj(this.c,this.d,this.b,a)};_.Xj=function bWd(){this.a.Vj(this.c,this.d,this.b)};_.b=0;var C6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingle/1',1331);bcb(769,504,{},cWd);_.Pj=function dWd(a,b,c,d,e){return Nid(a,a.eh(),a.Vg())==this.b?this.sk()&&d?aid(a):a.eh():null};_.Qj=function eWd(a,b,c,d,e){var f,g;!!a.eh()&&(e=(f=a.Vg(),f>=0?a.Qg(e):a.eh().ih(a,-1-f,null,e)));g=bLd(a.Tg(),this.e);return a.Sg(d,g,e)};_.Rj=function fWd(a,b,c,d,e){var f;f=bLd(a.Tg(),this.e);return a.Sg(null,f,e)};_.Sj=function gWd(a,b,c){var d;d=bLd(a.Tg(),this.e);return !!a.eh()&&a.Vg()==d};_.Tj=function hWd(a,b,c,d){var e,f,g,h,i;if(d!=null&&!fKd(this.a,d)){throw vbb(new Cdb(Yve+(JD(d,56)?gLd(BD(d,56).Tg()):idb(rb(d)))+Zve+this.a+"'"))}e=a.eh();g=bLd(a.Tg(),this.e);if(PD(d)!==PD(e)||a.Vg()!=g&&d!=null){if(p6d(a,BD(d,56)))throw vbb(new Wdb(ste+a.Ib()));i=null;!!e&&(i=(f=a.Vg(),f>=0?a.Qg(i):a.eh().ih(a,-1-f,null,i)));h=BD(d,49);!!h&&(i=h.gh(a,bLd(h.Tg(),this.b),null,i));i=a.Sg(h,g,i);!!i&&i.Fi()}else{a.Lg()&&a.Mg()&&Uhd(a,new nSd(a,1,g,d,d))}};_.Vj=function iWd(a,b,c){var d,e,f,g;d=a.eh();if(d){g=(e=a.Vg(),e>=0?a.Qg(null):a.eh().ih(a,-1-e,null,null));f=bLd(a.Tg(),this.e);g=a.Sg(null,f,g);!!g&&g.Fi()}else{a.Lg()&&a.Mg()&&Uhd(a,new DSd(a,1,this.e,null,null))}};_.sk=function jWd(){return false};var E6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleContainer',769);bcb(1315,769,{},kWd);_.sk=function lWd(){return true};var D6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving',1315);bcb(563,504,{});_.Pj=function oWd(a,b,c,d,e){var f;return f=b.Ch(c),f==null?this.b:PD(f)===PD(TVd)?null:f};_.Sj=function pWd(a,b,c){var d;d=b.Ch(c);return d!=null&&(PD(d)===PD(TVd)||!pb(d,this.b))};_.Tj=function qWd(a,b,c,d){var e,f;if(a.Lg()&&a.Mg()){e=(f=b.Ch(c),f==null?this.b:PD(f)===PD(TVd)?null:f);if(d==null){if(this.c!=null){b.Dh(c,null);d=this.b}else this.b!=null?b.Dh(c,TVd):b.Dh(c,null)}else{this.Sk(d);b.Dh(c,d)}Uhd(a,this.d.Tk(a,1,this.e,e,d))}else{if(d==null){this.c!=null?b.Dh(c,null):this.b!=null?b.Dh(c,TVd):b.Dh(c,null)}else{this.Sk(d);b.Dh(c,d)}}};_.Vj=function rWd(a,b,c){var d,e;if(a.Lg()&&a.Mg()){d=(e=b.Ch(c),e==null?this.b:PD(e)===PD(TVd)?null:e);b.Eh(c);Uhd(a,this.d.Tk(a,1,this.e,d,this.b))}else{b.Eh(c)}};_.Sk=function sWd(a){throw vbb(new Bdb)};var T6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData',563);bcb($ve,1,{},DWd);_.Tk=function EWd(a,b,c,d,e){return new DSd(a,b,c,d,e)};_.Uk=function FWd(a,b,c,d,e,f){return new FSd(a,b,c,d,e,f)};var tWd,uWd,vWd,wWd,xWd,yWd,zWd,AWd,BWd;var N6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator',$ve);bcb(1332,$ve,{},GWd);_.Tk=function HWd(a,b,c,d,e){return new ISd(a,b,c,Ccb(DD(d)),Ccb(DD(e)))};_.Uk=function IWd(a,b,c,d,e,f){return new JSd(a,b,c,Ccb(DD(d)),Ccb(DD(e)),f)};var F6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1',1332);bcb(1333,$ve,{},JWd);_.Tk=function KWd(a,b,c,d,e){return new rSd(a,b,c,BD(d,217).a,BD(e,217).a)};_.Uk=function LWd(a,b,c,d,e,f){return new sSd(a,b,c,BD(d,217).a,BD(e,217).a,f)};var G6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2',1333);bcb(1334,$ve,{},MWd);_.Tk=function NWd(a,b,c,d,e){return new tSd(a,b,c,BD(d,172).a,BD(e,172).a)};_.Uk=function OWd(a,b,c,d,e,f){return new uSd(a,b,c,BD(d,172).a,BD(e,172).a,f)};var H6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3',1334);bcb(1335,$ve,{},PWd);_.Tk=function QWd(a,b,c,d,e){return new vSd(a,b,c,Edb(ED(d)),Edb(ED(e)))};_.Uk=function RWd(a,b,c,d,e,f){return new wSd(a,b,c,Edb(ED(d)),Edb(ED(e)),f)};var I6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4',1335);bcb(1336,$ve,{},SWd);_.Tk=function TWd(a,b,c,d,e){return new xSd(a,b,c,BD(d,155).a,BD(e,155).a)};_.Uk=function UWd(a,b,c,d,e,f){return new ySd(a,b,c,BD(d,155).a,BD(e,155).a,f)};var J6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5',1336);bcb(1337,$ve,{},VWd);_.Tk=function WWd(a,b,c,d,e){return new zSd(a,b,c,BD(d,19).a,BD(e,19).a)};_.Uk=function XWd(a,b,c,d,e,f){return new ASd(a,b,c,BD(d,19).a,BD(e,19).a,f)};var K6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6',1337);bcb(1338,$ve,{},YWd);_.Tk=function ZWd(a,b,c,d,e){return new BSd(a,b,c,BD(d,162).a,BD(e,162).a)};_.Uk=function $Wd(a,b,c,d,e,f){return new CSd(a,b,c,BD(d,162).a,BD(e,162).a,f)};var L6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7',1338);bcb(1339,$ve,{},_Wd);_.Tk=function aXd(a,b,c,d,e){return new GSd(a,b,c,BD(d,184).a,BD(e,184).a)};_.Uk=function bXd(a,b,c,d,e,f){return new HSd(a,b,c,BD(d,184).a,BD(e,184).a,f)};var M6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8',1339);bcb(1317,563,{},cXd);_.Sk=function dXd(a){if(!this.a.wj(a)){throw vbb(new Cdb(Yve+rb(a)+Zve+this.a+"'"))}};var O6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic',1317);bcb(1318,563,{},eXd);_.Sk=function fXd(a){};var P6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic',1318);bcb(770,563,{});_.Sj=function gXd(a,b,c){var d;d=b.Ch(c);return d!=null};_.Tj=function hXd(a,b,c,d){var e,f;if(a.Lg()&&a.Mg()){e=true;f=b.Ch(c);if(f==null){e=false;f=this.b}else PD(f)===PD(TVd)&&(f=null);if(d==null){if(this.c!=null){b.Dh(c,null);d=this.b}else{b.Dh(c,TVd)}}else{this.Sk(d);b.Dh(c,d)}Uhd(a,this.d.Uk(a,1,this.e,f,d,!e))}else{if(d==null){this.c!=null?b.Dh(c,null):b.Dh(c,TVd)}else{this.Sk(d);b.Dh(c,d)}}};_.Vj=function iXd(a,b,c){var d,e;if(a.Lg()&&a.Mg()){d=true;e=b.Ch(c);if(e==null){d=false;e=this.b}else PD(e)===PD(TVd)&&(e=null);b.Eh(c);Uhd(a,this.d.Uk(a,2,this.e,e,this.b,d))}else{b.Eh(c)}};var S6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable',770);bcb(1319,770,{},jXd);_.Sk=function kXd(a){if(!this.a.wj(a)){throw vbb(new Cdb(Yve+rb(a)+Zve+this.a+"'"))}};var Q6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic',1319);bcb(1320,770,{},lXd);_.Sk=function mXd(a){};var R6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic',1320);bcb(398,504,{},nXd);_.Pj=function pXd(a,b,c,d,e){var f,g,h,i,j;j=b.Ch(c);if(this.Kj()&&PD(j)===PD(TVd)){return null}else if(this.sk()&&d&&j!=null){h=BD(j,49);if(h.kh()){i=xid(a,h);if(h!=i){if(!fKd(this.a,i)){throw vbb(new Cdb(Yve+rb(i)+Zve+this.a+"'"))}b.Dh(c,j=i);if(this.rk()){f=BD(i,49);g=h.ih(a,!this.b?-1-bLd(a.Tg(),this.e):bLd(h.Tg(),this.b),null,null);!f.eh()&&(g=f.gh(a,!this.b?-1-bLd(a.Tg(),this.e):bLd(f.Tg(),this.b),null,g));!!g&&g.Fi()}a.Lg()&&a.Mg()&&Uhd(a,new DSd(a,9,this.e,h,i))}}return j}else{return j}};_.Qj=function qXd(a,b,c,d,e){var f,g;g=b.Ch(c);PD(g)===PD(TVd)&&(g=null);b.Dh(c,d);if(this.bj()){if(PD(g)!==PD(d)&&g!=null){f=BD(g,49);e=f.ih(a,bLd(f.Tg(),this.b),null,e)}}else this.rk()&&g!=null&&(e=BD(g,49).ih(a,-1-bLd(a.Tg(),this.e),null,e));if(a.Lg()&&a.Mg()){!e&&(e=new Ixd(4));e.Ei(new DSd(a,1,this.e,g,d))}return e};_.Rj=function rXd(a,b,c,d,e){var f;f=b.Ch(c);PD(f)===PD(TVd)&&(f=null);b.Eh(c);if(a.Lg()&&a.Mg()){!e&&(e=new Ixd(4));this.Kj()?e.Ei(new DSd(a,2,this.e,f,null)):e.Ei(new DSd(a,1,this.e,f,null))}return e};_.Sj=function sXd(a,b,c){var d;d=b.Ch(c);return d!=null};_.Tj=function tXd(a,b,c,d){var e,f,g,h,i;if(d!=null&&!fKd(this.a,d)){throw vbb(new Cdb(Yve+(JD(d,56)?gLd(BD(d,56).Tg()):idb(rb(d)))+Zve+this.a+"'"))}i=b.Ch(c);h=i!=null;this.Kj()&&PD(i)===PD(TVd)&&(i=null);g=null;if(this.bj()){if(PD(i)!==PD(d)){if(i!=null){e=BD(i,49);g=e.ih(a,bLd(e.Tg(),this.b),null,g)}if(d!=null){e=BD(d,49);g=e.gh(a,bLd(e.Tg(),this.b),null,g)}}}else if(this.rk()){if(PD(i)!==PD(d)){i!=null&&(g=BD(i,49).ih(a,-1-bLd(a.Tg(),this.e),null,g));d!=null&&(g=BD(d,49).gh(a,-1-bLd(a.Tg(),this.e),null,g))}}d==null&&this.Kj()?b.Dh(c,TVd):b.Dh(c,d);if(a.Lg()&&a.Mg()){f=new FSd(a,1,this.e,i,d,this.Kj()&&!h);if(!g){Uhd(a,f)}else{g.Ei(f);g.Fi()}}else !!g&&g.Fi()};_.Vj=function uXd(a,b,c){var d,e,f,g,h;h=b.Ch(c);g=h!=null;this.Kj()&&PD(h)===PD(TVd)&&(h=null);f=null;if(h!=null){if(this.bj()){d=BD(h,49);f=d.ih(a,bLd(d.Tg(),this.b),null,f)}else this.rk()&&(f=BD(h,49).ih(a,-1-bLd(a.Tg(),this.e),null,f))}b.Eh(c);if(a.Lg()&&a.Mg()){e=new FSd(a,this.Kj()?2:1,this.e,h,null,g);if(!f){Uhd(a,e)}else{f.Ei(e);f.Fi()}}else !!f&&f.Fi()};_.bj=function vXd(){return false};_.rk=function wXd(){return false};_.sk=function xXd(){return false};_.Kj=function yXd(){return false};var h7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObject',398);bcb(564,398,{},zXd);_.rk=function AXd(){return true};var _6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment',564);bcb(1323,564,{},BXd);_.sk=function CXd(){return true};var U6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving',1323);bcb(772,564,{},DXd);_.Kj=function EXd(){return true};var W6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable',772);bcb(1325,772,{},FXd);_.sk=function GXd(){return true};var V6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving',1325);bcb(640,564,{},HXd);_.bj=function IXd(){return true};var $6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse',640);bcb(1324,640,{},JXd);_.sk=function KXd(){return true};var X6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving',1324);bcb(773,640,{},LXd);_.Kj=function MXd(){return true};var Z6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable',773);bcb(1326,773,{},NXd);_.sk=function OXd(){return true};var Y6=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving',1326);bcb(641,398,{},PXd);_.sk=function QXd(){return true};var d7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving',641);bcb(1327,641,{},RXd);_.Kj=function SXd(){return true};var a7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable',1327);bcb(774,641,{},TXd);_.bj=function UXd(){return true};var c7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse',774);bcb(1328,774,{},VXd);_.Kj=function WXd(){return true};var b7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable',1328);bcb(1321,398,{},XXd);_.Kj=function YXd(){return true};var e7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable',1321);bcb(771,398,{},ZXd);_.bj=function $Xd(){return true};var g7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse',771);bcb(1322,771,{},_Xd);_.Kj=function aYd(){return true};var f7=mdb(qte,'EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable',1322);bcb(775,565,Xve,dYd);_.Pk=function eYd(a){return new dYd(this.a,this.c,a)};_.dd=function fYd(){return this.b};_.Qk=function gYd(a,b,c){return bYd(this,a,this.b,c)};_.Rk=function hYd(a,b,c){return cYd(this,a,this.b,c)};var j7=mdb(qte,'EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry',775);bcb(1329,1,zve,iYd);_.Wj=function jYd(a){return this.a};_.fj=function kYd(){return JD(this.a,95)?BD(this.a,95).fj():!this.a.dc()};_.Wb=function lYd(a){this.a.$b();this.a.Gc(BD(a,15))};_.Xj=function mYd(){JD(this.a,95)?BD(this.a,95).Xj():this.a.$b()};var k7=mdb(qte,'EStructuralFeatureImpl/SettingMany',1329);bcb(1330,565,Xve,nYd);_.Ok=function oYd(a){return new sYd((Q8d(),P8d),this.b.Ih(this.a,a))};_.dd=function pYd(){return null};_.Qk=function qYd(a,b,c){return c};_.Rk=function rYd(a,b,c){return c};var l7=mdb(qte,'EStructuralFeatureImpl/SimpleContentFeatureMapEntry',1330);bcb(642,565,Xve,sYd);_.Ok=function tYd(a){return new sYd(this.c,a)};_.dd=function uYd(){return this.a};_.Qk=function vYd(a,b,c){return c};_.Rk=function wYd(a,b,c){return c};var m7=mdb(qte,'EStructuralFeatureImpl/SimpleFeatureMapEntry',642);bcb(391,497,oue,xYd);_.ri=function yYd(a){return KC(c5,Uhe,26,a,0,1)};_.ni=function zYd(){return false};var o7=mdb(qte,'ESuperAdapter/1',391);bcb(444,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,836:1,49:1,97:1,150:1,444:1,114:1,115:1},BYd);_._g=function CYd(a,b,c){var d;switch(a){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),this.Ab;case 1:return this.zb;case 2:return !this.a&&(this.a=new KYd(this,j5,this)),this.a;}return bid(this,a-aLd((jGd(),iGd)),XKd((d=BD(Ajd(this,16),26),!d?iGd:d),a),b,c)};_.jh=function DYd(a,b,c){var d,e;switch(b){case 0:return !this.Ab&&(this.Ab=new cUd(a5,this,0,3)),Txd(this.Ab,a,c);case 2:return !this.a&&(this.a=new KYd(this,j5,this)),Txd(this.a,a,c);}return e=BD(XKd((d=BD(Ajd(this,16),26),!d?(jGd(),iGd):d),b),66),e.Nj().Rj(this,yjd(this),b-aLd((jGd(),iGd)),a,c)};_.lh=function EYd(a){var b;switch(a){case 0:return !!this.Ab&&this.Ab.i!=0;case 1:return this.zb!=null;case 2:return !!this.a&&this.a.i!=0;}return cid(this,a-aLd((jGd(),iGd)),XKd((b=BD(Ajd(this,16),26),!b?iGd:b),a))};_.sh=function FYd(a,b){var c;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);!this.Ab&&(this.Ab=new cUd(a5,this,0,3));ytd(this.Ab,BD(b,14));return;case 1:pnd(this,GD(b));return;case 2:!this.a&&(this.a=new KYd(this,j5,this));Uxd(this.a);!this.a&&(this.a=new KYd(this,j5,this));ytd(this.a,BD(b,14));return;}did(this,a-aLd((jGd(),iGd)),XKd((c=BD(Ajd(this,16),26),!c?iGd:c),a),b)};_.zh=function GYd(){return jGd(),iGd};_.Bh=function HYd(a){var b;switch(a){case 0:!this.Ab&&(this.Ab=new cUd(a5,this,0,3));Uxd(this.Ab);return;case 1:pnd(this,null);return;case 2:!this.a&&(this.a=new KYd(this,j5,this));Uxd(this.a);return;}eid(this,a-aLd((jGd(),iGd)),XKd((b=BD(Ajd(this,16),26),!b?iGd:b),a))};var u7=mdb(qte,'ETypeParameterImpl',444);bcb(445,85,Pve,KYd);_.cj=function LYd(a,b){return IYd(this,BD(a,87),b)};_.dj=function MYd(a,b){return JYd(this,BD(a,87),b)};var q7=mdb(qte,'ETypeParameterImpl/1',445);bcb(634,43,fke,NYd);_.ec=function OYd(){return new RYd(this)};var t7=mdb(qte,'ETypeParameterImpl/2',634);bcb(556,eie,fie,RYd);_.Fc=function SYd(a){return PYd(this,BD(a,87))};_.Gc=function TYd(a){var b,c,d;d=false;for(c=a.Kc();c.Ob();){b=BD(c.Pb(),87);Rhb(this.a,b,'')==null&&(d=true)}return d};_.$b=function UYd(){Uhb(this.a)};_.Hc=function VYd(a){return Mhb(this.a,a)};_.Kc=function WYd(){var a;return a=new nib((new eib(this.a)).a),new ZYd(a)};_.Mc=function XYd(a){return QYd(this,a)};_.gc=function YYd(){return Vhb(this.a)};var s7=mdb(qte,'ETypeParameterImpl/2/1',556);bcb(557,1,aie,ZYd);_.Nb=function $Yd(a){Rrb(this,a)};_.Pb=function aZd(){return BD(lib(this.a).cd(),87)};_.Ob=function _Yd(){return this.a.b};_.Qb=function bZd(){mib(this.a)};var r7=mdb(qte,'ETypeParameterImpl/2/1/1',557);bcb(1276,43,fke,cZd);_._b=function dZd(a){return ND(a)?Qhb(this,a):!!irb(this.f,a)};_.xc=function eZd(a){var b,c;b=ND(a)?Phb(this,a):Wd(irb(this.f,a));if(JD(b,837)){c=BD(b,837);b=c._j();Rhb(this,BD(a,235),b);return b}else return b!=null?b:a==null?(g5d(),f5d):null};var w7=mdb(qte,'EValidatorRegistryImpl',1276);bcb(1313,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,1941:1,49:1,97:1,150:1,114:1,115:1},mZd);_.Ih=function nZd(a,b){switch(a.yj()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return b==null?null:fcb(b);case 25:return gZd(b);case 27:return hZd(b);case 28:return iZd(b);case 29:return b==null?null:CQd(Pmd[0],BD(b,199));case 41:return b==null?'':hdb(BD(b,290));case 42:return fcb(b);case 50:return GD(b);default:throw vbb(new Wdb(tte+a.ne()+ute));}};_.Jh=function oZd(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q;switch(a.G==-1&&(a.G=(m=bKd(a),m?HLd(m.Mh(),a):-1)),a.G){case 0:return c=new OJd,c;case 1:return b=new RHd,b;case 2:return d=new hLd,d;case 4:return e=new MPd,e;case 5:return f=new aQd,f;case 6:return g=new rQd,g;case 7:return h=new $md,h;case 10:return j=new MGd,j;case 11:return k=new SSd,k;case 12:return l=new eod,l;case 13:return n=new rUd,n;case 14:return o=new FUd,o;case 17:return p=new XUd,p;case 18:return i=new UQd,i;case 19:return q=new BYd,q;default:throw vbb(new Wdb(xte+a.zb+ute));}};_.Kh=function pZd(a,b){switch(a.yj()){case 20:return b==null?null:new tgb(b);case 21:return b==null?null:new Ygb(b);case 23:case 22:return b==null?null:fZd(b);case 26:case 24:return b==null?null:Scb(Icb(b,-128,127)<<24>>24);case 25:return Xmd(b);case 27:return jZd(b);case 28:return kZd(b);case 29:return lZd(b);case 32:case 31:return b==null?null:Hcb(b);case 38:case 37:return b==null?null:new Odb(b);case 40:case 39:return b==null?null:meb(Icb(b,Rie,Ohe));case 41:return null;case 42:return b==null?null:null;case 44:case 43:return b==null?null:Aeb(Jcb(b));case 49:case 48:return b==null?null:Web(Icb(b,awe,32767)<<16>>16);case 50:return b;default:throw vbb(new Wdb(tte+a.ne()+ute));}};var x7=mdb(qte,'EcoreFactoryImpl',1313);bcb(547,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,1939:1,49:1,97:1,150:1,179:1,547:1,114:1,115:1,675:1},AZd);_.gb=false;_.hb=false;var rZd,sZd=false;var o8=mdb(qte,'EcorePackageImpl',547);bcb(1184,1,{837:1},EZd);_._j=function FZd(){return I6d(),H6d};var I7=mdb(qte,'EcorePackageImpl/1',1184);bcb(1193,1,nwe,GZd);_.wj=function HZd(a){return JD(a,147)};_.xj=function IZd(a){return KC(k5,Uhe,147,a,0,1)};var y7=mdb(qte,'EcorePackageImpl/10',1193);bcb(1194,1,nwe,JZd);_.wj=function KZd(a){return JD(a,191)};_.xj=function LZd(a){return KC(l5,Uhe,191,a,0,1)};var z7=mdb(qte,'EcorePackageImpl/11',1194);bcb(1195,1,nwe,MZd);_.wj=function NZd(a){return JD(a,56)};_.xj=function OZd(a){return KC(m5,Uhe,56,a,0,1)};var A7=mdb(qte,'EcorePackageImpl/12',1195);bcb(1196,1,nwe,PZd);_.wj=function QZd(a){return JD(a,399)};_.xj=function RZd(a){return KC(n5,Nve,59,a,0,1)};var B7=mdb(qte,'EcorePackageImpl/13',1196);bcb(1197,1,nwe,SZd);_.wj=function TZd(a){return JD(a,235)};_.xj=function UZd(a){return KC(o5,Uhe,235,a,0,1)};var C7=mdb(qte,'EcorePackageImpl/14',1197);bcb(1198,1,nwe,VZd);_.wj=function WZd(a){return JD(a,509)};_.xj=function XZd(a){return KC(p5,Uhe,2017,a,0,1)};var D7=mdb(qte,'EcorePackageImpl/15',1198);bcb(1199,1,nwe,YZd);_.wj=function ZZd(a){return JD(a,99)};_.xj=function $Zd(a){return KC(q5,Mve,18,a,0,1)};var E7=mdb(qte,'EcorePackageImpl/16',1199);bcb(1200,1,nwe,_Zd);_.wj=function a$d(a){return JD(a,170)};_.xj=function b$d(a){return KC(t5,Mve,170,a,0,1)};var F7=mdb(qte,'EcorePackageImpl/17',1200);bcb(1201,1,nwe,c$d);_.wj=function d$d(a){return JD(a,472)};_.xj=function e$d(a){return KC(v5,Uhe,472,a,0,1)};var G7=mdb(qte,'EcorePackageImpl/18',1201);bcb(1202,1,nwe,f$d);_.wj=function g$d(a){return JD(a,548)};_.xj=function h$d(a){return KC(x6,kve,548,a,0,1)};var H7=mdb(qte,'EcorePackageImpl/19',1202);bcb(1185,1,nwe,i$d);_.wj=function j$d(a){return JD(a,322)};_.xj=function k$d(a){return KC(b5,Mve,34,a,0,1)};var T7=mdb(qte,'EcorePackageImpl/2',1185);bcb(1203,1,nwe,l$d);_.wj=function m$d(a){return JD(a,241)};_.xj=function n$d(a){return KC(j5,Tve,87,a,0,1)};var J7=mdb(qte,'EcorePackageImpl/20',1203);bcb(1204,1,nwe,o$d);_.wj=function p$d(a){return JD(a,444)};_.xj=function q$d(a){return KC(u5,Uhe,836,a,0,1)};var K7=mdb(qte,'EcorePackageImpl/21',1204);bcb(1205,1,nwe,r$d);_.wj=function s$d(a){return KD(a)};_.xj=function t$d(a){return KC(wI,nie,476,a,8,1)};var L7=mdb(qte,'EcorePackageImpl/22',1205);bcb(1206,1,nwe,u$d);_.wj=function v$d(a){return JD(a,190)};_.xj=function w$d(a){return KC(SD,nie,190,a,0,2)};var M7=mdb(qte,'EcorePackageImpl/23',1206);bcb(1207,1,nwe,x$d);_.wj=function y$d(a){return JD(a,217)};_.xj=function z$d(a){return KC(xI,nie,217,a,0,1)};var N7=mdb(qte,'EcorePackageImpl/24',1207);bcb(1208,1,nwe,A$d);_.wj=function B$d(a){return JD(a,172)};_.xj=function C$d(a){return KC(yI,nie,172,a,0,1)};var O7=mdb(qte,'EcorePackageImpl/25',1208);bcb(1209,1,nwe,D$d);_.wj=function E$d(a){return JD(a,199)};_.xj=function F$d(a){return KC($J,nie,199,a,0,1)};var P7=mdb(qte,'EcorePackageImpl/26',1209);bcb(1210,1,nwe,G$d);_.wj=function H$d(a){return false};_.xj=function I$d(a){return KC(O4,Uhe,2110,a,0,1)};var Q7=mdb(qte,'EcorePackageImpl/27',1210);bcb(1211,1,nwe,J$d);_.wj=function K$d(a){return LD(a)};_.xj=function L$d(a){return KC(BI,nie,333,a,7,1)};var R7=mdb(qte,'EcorePackageImpl/28',1211);bcb(1212,1,nwe,M$d);_.wj=function N$d(a){return JD(a,58)};_.xj=function O$d(a){return KC(T4,eme,58,a,0,1)};var S7=mdb(qte,'EcorePackageImpl/29',1212);bcb(1186,1,nwe,P$d);_.wj=function Q$d(a){return JD(a,510)};_.xj=function R$d(a){return KC(a5,{3:1,4:1,5:1,1934:1},590,a,0,1)};var c8=mdb(qte,'EcorePackageImpl/3',1186);bcb(1213,1,nwe,S$d);_.wj=function T$d(a){return JD(a,573)};_.xj=function U$d(a){return KC(U4,Uhe,1940,a,0,1)};var U7=mdb(qte,'EcorePackageImpl/30',1213);bcb(1214,1,nwe,V$d);_.wj=function W$d(a){return JD(a,153)};_.xj=function X$d(a){return KC(O9,eme,153,a,0,1)};var V7=mdb(qte,'EcorePackageImpl/31',1214);bcb(1215,1,nwe,Y$d);_.wj=function Z$d(a){return JD(a,72)};_.xj=function $$d(a){return KC(E9,owe,72,a,0,1)};var W7=mdb(qte,'EcorePackageImpl/32',1215);bcb(1216,1,nwe,_$d);_.wj=function a_d(a){return JD(a,155)};_.xj=function b_d(a){return KC(FI,nie,155,a,0,1)};var X7=mdb(qte,'EcorePackageImpl/33',1216);bcb(1217,1,nwe,c_d);_.wj=function d_d(a){return JD(a,19)};_.xj=function e_d(a){return KC(JI,nie,19,a,0,1)};var Y7=mdb(qte,'EcorePackageImpl/34',1217);bcb(1218,1,nwe,f_d);_.wj=function g_d(a){return JD(a,290)};_.xj=function h_d(a){return KC(AI,Uhe,290,a,0,1)};var Z7=mdb(qte,'EcorePackageImpl/35',1218);bcb(1219,1,nwe,i_d);_.wj=function j_d(a){return JD(a,162)};_.xj=function k_d(a){return KC(MI,nie,162,a,0,1)};var $7=mdb(qte,'EcorePackageImpl/36',1219);bcb(1220,1,nwe,l_d);_.wj=function m_d(a){return JD(a,83)};_.xj=function n_d(a){return KC(DK,Uhe,83,a,0,1)};var _7=mdb(qte,'EcorePackageImpl/37',1220);bcb(1221,1,nwe,o_d);_.wj=function p_d(a){return JD(a,591)};_.xj=function q_d(a){return KC(v8,Uhe,591,a,0,1)};var a8=mdb(qte,'EcorePackageImpl/38',1221);bcb(1222,1,nwe,r_d);_.wj=function s_d(a){return false};_.xj=function t_d(a){return KC(u8,Uhe,2111,a,0,1)};var b8=mdb(qte,'EcorePackageImpl/39',1222);bcb(1187,1,nwe,u_d);_.wj=function v_d(a){return JD(a,88)};_.xj=function w_d(a){return KC(c5,Uhe,26,a,0,1)};var i8=mdb(qte,'EcorePackageImpl/4',1187);bcb(1223,1,nwe,x_d);_.wj=function y_d(a){return JD(a,184)};_.xj=function z_d(a){return KC(UI,nie,184,a,0,1)};var d8=mdb(qte,'EcorePackageImpl/40',1223);bcb(1224,1,nwe,A_d);_.wj=function B_d(a){return ND(a)};_.xj=function C_d(a){return KC(ZI,nie,2,a,6,1)};var e8=mdb(qte,'EcorePackageImpl/41',1224);bcb(1225,1,nwe,D_d);_.wj=function E_d(a){return JD(a,588)};_.xj=function F_d(a){return KC(X4,Uhe,588,a,0,1)};var f8=mdb(qte,'EcorePackageImpl/42',1225);bcb(1226,1,nwe,G_d);_.wj=function H_d(a){return false};_.xj=function I_d(a){return KC(V4,nie,2112,a,0,1)};var g8=mdb(qte,'EcorePackageImpl/43',1226);bcb(1227,1,nwe,J_d);_.wj=function K_d(a){return JD(a,42)};_.xj=function L_d(a){return KC(CK,zie,42,a,0,1)};var h8=mdb(qte,'EcorePackageImpl/44',1227);bcb(1188,1,nwe,M_d);_.wj=function N_d(a){return JD(a,138)};_.xj=function O_d(a){return KC(d5,Uhe,138,a,0,1)};var j8=mdb(qte,'EcorePackageImpl/5',1188);bcb(1189,1,nwe,P_d);_.wj=function Q_d(a){return JD(a,148)};_.xj=function R_d(a){return KC(f5,Uhe,148,a,0,1)};var k8=mdb(qte,'EcorePackageImpl/6',1189);bcb(1190,1,nwe,S_d);_.wj=function T_d(a){return JD(a,457)};_.xj=function U_d(a){return KC(h5,Uhe,671,a,0,1)};var l8=mdb(qte,'EcorePackageImpl/7',1190);bcb(1191,1,nwe,V_d);_.wj=function W_d(a){return JD(a,573)};_.xj=function X_d(a){return KC(g5,Uhe,678,a,0,1)};var m8=mdb(qte,'EcorePackageImpl/8',1191);bcb(1192,1,nwe,Y_d);_.wj=function Z_d(a){return JD(a,471)};_.xj=function $_d(a){return KC(i5,Uhe,471,a,0,1)};var n8=mdb(qte,'EcorePackageImpl/9',1192);bcb(1025,1982,ive,c0d);_.bi=function d0d(a,b){__d(this,BD(b,415))};_.fi=function e0d(a,b){a0d(this,a,BD(b,415))};var q8=mdb(qte,'MinimalEObjectImpl/1ArrayDelegatingAdapterList',1025);bcb(1026,143,fve,f0d);_.Ai=function g0d(){return this.a.a};var p8=mdb(qte,'MinimalEObjectImpl/1ArrayDelegatingAdapterList/1',1026);bcb(1053,1052,{},i0d);var t8=mdb('org.eclipse.emf.ecore.plugin','EcorePlugin',1053);var v8=odb(pwe,'Resource');bcb(781,1378,qwe);_.Yk=function m0d(a){};_.Zk=function n0d(a){};_.Vk=function o0d(){return !this.a&&(this.a=new z0d(this)),this.a};_.Wk=function p0d(a){var b,c,d,e,f;d=a.length;if(d>0){BCb(0,a.length);if(a.charCodeAt(0)==47){f=new Skb(4);e=1;for(b=1;b<d;++b){BCb(b,a.length);if(a.charCodeAt(b)==47){Ekb(f,e==b?'':a.substr(e,b-e));e=b+1}}Ekb(f,a.substr(e));return j0d(this,f)}else{BCb(d-1,a.length);if(a.charCodeAt(d-1)==63){c=lfb(a,wfb(63),d-2);c>0&&(a=a.substr(0,c))}}}return k0d(this,a)};_.Xk=function q0d(){return this.c};_.Ib=function r0d(){var a;return hdb(this.gm)+'@'+(a=tb(this)>>>0,a.toString(16))+" uri='"+this.d+"'"};_.b=false;var z8=mdb(rwe,'ResourceImpl',781);bcb(1379,781,qwe,s0d);var w8=mdb(rwe,'BinaryResourceImpl',1379);bcb(1169,694,pue);_.si=function v0d(a){return JD(a,56)?t0d(this,BD(a,56)):JD(a,591)?new Fyd(BD(a,591).Vk()):PD(a)===PD(this.f)?BD(a,14).Kc():(LCd(),KCd.a)};_.Ob=function w0d(){return u0d(this)};_.a=false;var z9=mdb(yve,'EcoreUtil/ContentTreeIterator',1169);bcb(1380,1169,pue,x0d);_.si=function y0d(a){return PD(a)===PD(this.f)?BD(a,15).Kc():new C6d(BD(a,56))};var x8=mdb(rwe,'ResourceImpl/5',1380);bcb(648,1994,Ove,z0d);_.Hc=function A0d(a){return this.i<=4?pud(this,a):JD(a,49)&&BD(a,49).Zg()==this.a};_.bi=function B0d(a,b){a==this.i-1&&(this.a.b||(this.a.b=true,null))};_.di=function C0d(a,b){a==0?this.a.b||(this.a.b=true,null):Atd(this,a,b)};_.fi=function D0d(a,b){};_.gi=function E0d(a,b,c){};_.aj=function F0d(){return 2};_.Ai=function G0d(){return this.a};_.bj=function H0d(){return true};_.cj=function I0d(a,b){var c;c=BD(a,49);b=c.wh(this.a,b);return b};_.dj=function J0d(a,b){var c;c=BD(a,49);return c.wh(null,b)};_.ej=function K0d(){return false};_.hi=function L0d(){return true};_.ri=function M0d(a){return KC(m5,Uhe,56,a,0,1)};_.ni=function N0d(){return false};var y8=mdb(rwe,'ResourceImpl/ContentsEList',648);bcb(957,1964,Lie,O0d);_.Zc=function P0d(a){return this.a._h(a)};_.gc=function Q0d(){return this.a.gc()};var A8=mdb(yve,'AbstractSequentialInternalEList/1',957);var K6d,L6d,M6d,N6d;bcb(624,1,{},y1d);var R0d,S0d;var G8=mdb(yve,'BasicExtendedMetaData',624);bcb(1160,1,{},C1d);_.$k=function D1d(){return null};_._k=function E1d(){this.a==-2&&A1d(this,W0d(this.d,this.b));return this.a};_.al=function F1d(){return null};_.bl=function G1d(){return mmb(),mmb(),jmb};_.ne=function H1d(){this.c==Gwe&&B1d(this,_0d(this.d,this.b));return this.c};_.cl=function I1d(){return 0};_.a=-2;_.c=Gwe;var C8=mdb(yve,'BasicExtendedMetaData/EClassExtendedMetaDataImpl',1160);bcb(1161,1,{},O1d);_.$k=function P1d(){this.a==(T0d(),R0d)&&J1d(this,V0d(this.f,this.b));return this.a};_._k=function Q1d(){return 0};_.al=function R1d(){this.c==(T0d(),R0d)&&K1d(this,Z0d(this.f,this.b));return this.c};_.bl=function S1d(){!this.d&&L1d(this,$0d(this.f,this.b));return this.d};_.ne=function T1d(){this.e==Gwe&&M1d(this,_0d(this.f,this.b));return this.e};_.cl=function U1d(){this.g==-2&&N1d(this,c1d(this.f,this.b));return this.g};_.e=Gwe;_.g=-2;var D8=mdb(yve,'BasicExtendedMetaData/EDataTypeExtendedMetaDataImpl',1161);bcb(1159,1,{},Y1d);_.b=false;_.c=false;var E8=mdb(yve,'BasicExtendedMetaData/EPackageExtendedMetaDataImpl',1159);bcb(1162,1,{},j2d);_.c=-2;_.e=Gwe;_.f=Gwe;var F8=mdb(yve,'BasicExtendedMetaData/EStructuralFeatureExtendedMetaDataImpl',1162);bcb(585,622,Pve,k2d);_.aj=function l2d(){return this.c};_.Fk=function m2d(){return false};_.li=function n2d(a,b){return b};_.c=0;var T8=mdb(yve,'EDataTypeEList',585);var O9=odb(yve,'FeatureMap');bcb(75,585,{3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,153:1,215:1,1937:1,69:1,95:1},u3d);_.Vc=function v3d(a,b){o2d(this,a,BD(b,72))};_.Fc=function w3d(a){return r2d(this,BD(a,72))};_.Yh=function B3d(a){w2d(this,BD(a,72))};_.cj=function M3d(a,b){return O2d(this,BD(a,72),b)};_.dj=function N3d(a,b){return Q2d(this,BD(a,72),b)};_.ii=function P3d(a,b){return W2d(this,a,b)};_.li=function R3d(a,b){return _2d(this,a,BD(b,72))};_._c=function T3d(a,b){return c3d(this,a,BD(b,72))};_.jj=function X3d(a,b){return i3d(this,BD(a,72),b)};_.kj=function Y3d(a,b){return k3d(this,BD(a,72),b)};_.lj=function Z3d(a,b,c){return l3d(this,BD(a,72),BD(b,72),c)};_.oi=function _3d(a,b){return t3d(this,a,BD(b,72))};_.dl=function x3d(a,b){return q2d(this,a,b)};_.Wc=function y3d(a,b){var c,d,e,f,g,h,i,j,k;j=new zud(b.gc());for(e=b.Kc();e.Ob();){d=BD(e.Pb(),72);f=d.ak();if(T6d(this.e,f)){(!f.hi()||!E2d(this,f,d.dd())&&!pud(j,d))&&wtd(j,d)}else{k=S6d(this.e.Tg(),f);c=BD(this.g,119);g=true;for(h=0;h<this.i;++h){i=c[h];if(k.rl(i.ak())){BD(Gtd(this,h,d),72);g=false;break}}g&&wtd(j,d)}}return xtd(this,a,j)};_.Gc=function z3d(a){var b,c,d,e,f,g,h,i,j;i=new zud(a.gc());for(d=a.Kc();d.Ob();){c=BD(d.Pb(),72);e=c.ak();if(T6d(this.e,e)){(!e.hi()||!E2d(this,e,c.dd())&&!pud(i,c))&&wtd(i,c)}else{j=S6d(this.e.Tg(),e);b=BD(this.g,119);f=true;for(g=0;g<this.i;++g){h=b[g];if(j.rl(h.ak())){BD(Gtd(this,g,c),72);f=false;break}}f&&wtd(i,c)}}return ytd(this,i)};_.Wh=function A3d(a){this.j=-1;return Pxd(this,this.i,a)};_.el=function C3d(a,b,c){return x2d(this,a,b,c)};_.mk=function D3d(a,b){return B2d(this,a,b)};_.fl=function E3d(a,b,c){return C2d(this,a,b,c)};_.gl=function F3d(){return this};_.hl=function G3d(a,b){return K2d(this,a,b)};_.il=function H3d(a){return BD(qud(this,a),72).ak()};_.jl=function I3d(a){return BD(qud(this,a),72).dd()};_.kl=function J3d(){return this.b};_.bj=function K3d(){return true};_.ij=function L3d(){return true};_.ll=function O3d(a){return !R2d(this,a)};_.ri=function Q3d(a){return KC(D9,owe,332,a,0,1)};_.Gk=function S3d(a){return a3d(this,a)};_.Wb=function U3d(a){d3d(this,a)};_.ml=function V3d(a,b){f3d(this,a,b)};_.nl=function W3d(a){return g3d(this,a)};_.ol=function $3d(a){s3d(this,a)};var J8=mdb(yve,'BasicFeatureMap',75);bcb(1851,1,jie);_.Nb=function f4d(a){Rrb(this,a)};_.Rb=function e4d(b){if(this.g==-1){throw vbb(new Ydb)}a4d(this);try{p2d(this.e,this.b,this.a,b);this.d=this.e.j;d4d(this)}catch(a){a=ubb(a);if(JD(a,73)){throw vbb(new Apb)}else throw vbb(a)}};_.Ob=function g4d(){return b4d(this)};_.Sb=function h4d(){return c4d(this)};_.Pb=function i4d(){return d4d(this)};_.Tb=function j4d(){return this.a};_.Ub=function k4d(){var a;if(c4d(this)){a4d(this);this.g=--this.a;if(this.Lk()){a=b3d(this.e,this.b,this.c,this.a,this.j);this.j=a}this.i=0;return this.j}else{throw vbb(new utb)}};_.Vb=function l4d(){return this.a-1};_.Qb=function m4d(){if(this.g==-1){throw vbb(new Ydb)}a4d(this);try{Z2d(this.e,this.b,this.g);this.d=this.e.j;if(this.g<this.a){--this.a;--this.c}--this.g}catch(a){a=ubb(a);if(JD(a,73)){throw vbb(new Apb)}else throw vbb(a)}};_.Lk=function n4d(){return false};_.Wb=function o4d(b){if(this.g==-1){throw vbb(new Ydb)}a4d(this);try{e3d(this.e,this.b,this.g,b);this.d=this.e.j}catch(a){a=ubb(a);if(JD(a,73)){throw vbb(new Apb)}else throw vbb(a)}};_.a=0;_.c=0;_.d=0;_.f=false;_.g=0;_.i=0;var G9=mdb(yve,'FeatureMapUtil/BasicFeatureEIterator',1851);bcb(410,1851,jie,p4d);_.pl=function q4d(){var a,b,c;c=this.e.i;a=BD(this.e.g,119);while(this.c<c){b=a[this.c];if(this.k.rl(b.ak())){this.j=this.f?b:b.dd();this.i=2;return true}++this.c}this.i=1;this.g=-1;return false};_.ql=function r4d(){var a,b;a=BD(this.e.g,119);while(--this.c>=0){b=a[this.c];if(this.k.rl(b.ak())){this.j=this.f?b:b.dd();this.i=-2;return true}}this.i=-1;this.g=-1;return false};var H8=mdb(yve,'BasicFeatureMap/FeatureEIterator',410);bcb(662,410,jie,s4d);_.Lk=function t4d(){return true};var I8=mdb(yve,'BasicFeatureMap/ResolvingFeatureEIterator',662);bcb(955,486,Vve,u4d);_.Gi=function v4d(){return this};var M8=mdb(yve,'EContentsEList/1',955);bcb(956,486,Vve,w4d);_.Lk=function x4d(){return false};var N8=mdb(yve,'EContentsEList/2',956);bcb(954,279,Wve,y4d);_.Nk=function z4d(a){};_.Ob=function A4d(){return false};_.Sb=function B4d(){return false};var O8=mdb(yve,'EContentsEList/FeatureIteratorImpl/1',954);bcb(825,585,Pve,C4d);_.ci=function D4d(){this.a=true};_.fj=function E4d(){return this.a};_.Xj=function F4d(){var a;Uxd(this);if(oid(this.e)){a=this.a;this.a=false;Uhd(this.e,new qSd(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var S8=mdb(yve,'EDataTypeEList/Unsettable',825);bcb(1849,585,Pve,G4d);_.hi=function H4d(){return true};var V8=mdb(yve,'EDataTypeUniqueEList',1849);bcb(1850,825,Pve,I4d);_.hi=function J4d(){return true};var U8=mdb(yve,'EDataTypeUniqueEList/Unsettable',1850);bcb(139,85,Pve,K4d);_.Ek=function L4d(){return true};_.li=function M4d(a,b){return ILd(this,a,BD(b,56))};var W8=mdb(yve,'EObjectContainmentEList/Resolving',139);bcb(1163,545,Pve,N4d);_.Ek=function O4d(){return true};_.li=function P4d(a,b){return ILd(this,a,BD(b,56))};var X8=mdb(yve,'EObjectContainmentEList/Unsettable/Resolving',1163);bcb(748,16,Pve,Q4d);_.ci=function R4d(){this.a=true};_.fj=function S4d(){return this.a};_.Xj=function T4d(){var a;Uxd(this);if(oid(this.e)){a=this.a;this.a=false;Uhd(this.e,new qSd(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var a9=mdb(yve,'EObjectContainmentWithInverseEList/Unsettable',748);bcb(1173,748,Pve,U4d);_.Ek=function V4d(){return true};_.li=function W4d(a,b){return ILd(this,a,BD(b,56))};var _8=mdb(yve,'EObjectContainmentWithInverseEList/Unsettable/Resolving',1173);bcb(743,496,Pve,X4d);_.ci=function Y4d(){this.a=true};_.fj=function Z4d(){return this.a};_.Xj=function $4d(){var a;Uxd(this);if(oid(this.e)){a=this.a;this.a=false;Uhd(this.e,new qSd(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var c9=mdb(yve,'EObjectEList/Unsettable',743);bcb(328,496,Pve,_4d);_.Ek=function a5d(){return true};_.li=function b5d(a,b){return ILd(this,a,BD(b,56))};var f9=mdb(yve,'EObjectResolvingEList',328);bcb(1641,743,Pve,c5d);_.Ek=function d5d(){return true};_.li=function e5d(a,b){return ILd(this,a,BD(b,56))};var e9=mdb(yve,'EObjectResolvingEList/Unsettable',1641);bcb(1381,1,{},h5d);var f5d;var g9=mdb(yve,'EObjectValidator',1381);bcb(546,496,Pve,i5d);_.zk=function j5d(){return this.d};_.Ak=function k5d(){return this.b};_.bj=function l5d(){return true};_.Dk=function m5d(){return true};_.b=0;var k9=mdb(yve,'EObjectWithInverseEList',546);bcb(1176,546,Pve,n5d);_.Ck=function o5d(){return true};var h9=mdb(yve,'EObjectWithInverseEList/ManyInverse',1176);bcb(625,546,Pve,p5d);_.ci=function q5d(){this.a=true};_.fj=function r5d(){return this.a};_.Xj=function s5d(){var a;Uxd(this);if(oid(this.e)){a=this.a;this.a=false;Uhd(this.e,new qSd(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var j9=mdb(yve,'EObjectWithInverseEList/Unsettable',625);bcb(1175,625,Pve,t5d);_.Ck=function u5d(){return true};var i9=mdb(yve,'EObjectWithInverseEList/Unsettable/ManyInverse',1175);bcb(749,546,Pve,v5d);_.Ek=function w5d(){return true};_.li=function x5d(a,b){return ILd(this,a,BD(b,56))};var o9=mdb(yve,'EObjectWithInverseResolvingEList',749);bcb(31,749,Pve,y5d);_.Ck=function z5d(){return true};var l9=mdb(yve,'EObjectWithInverseResolvingEList/ManyInverse',31);bcb(750,625,Pve,A5d);_.Ek=function B5d(){return true};_.li=function C5d(a,b){return ILd(this,a,BD(b,56))};var n9=mdb(yve,'EObjectWithInverseResolvingEList/Unsettable',750);bcb(1174,750,Pve,D5d);_.Ck=function E5d(){return true};var m9=mdb(yve,'EObjectWithInverseResolvingEList/Unsettable/ManyInverse',1174);bcb(1164,622,Pve);_.ai=function F5d(){return (this.b&1792)==0};_.ci=function G5d(){this.b|=1};_.Bk=function H5d(){return (this.b&4)!=0};_.bj=function I5d(){return (this.b&40)!=0};_.Ck=function J5d(){return (this.b&16)!=0};_.Dk=function K5d(){return (this.b&8)!=0};_.Ek=function L5d(){return (this.b&Dve)!=0};_.rk=function M5d(){return (this.b&32)!=0};_.Fk=function N5d(){return (this.b&zte)!=0};_.wj=function O5d(a){return !this.d?this.ak().Yj().wj(a):qEd(this.d,a)};_.fj=function P5d(){return (this.b&2)!=0?(this.b&1)!=0:this.i!=0};_.hi=function Q5d(){return (this.b&128)!=0};_.Xj=function S5d(){var a;Uxd(this);if((this.b&2)!=0){if(oid(this.e)){a=(this.b&1)!=0;this.b&=-2;GLd(this,new qSd(this.e,2,bLd(this.e.Tg(),this.ak()),a,false))}else{this.b&=-2}}};_.ni=function T5d(){return (this.b&1536)==0};_.b=0;var q9=mdb(yve,'EcoreEList/Generic',1164);bcb(1165,1164,Pve,U5d);_.ak=function V5d(){return this.a};var p9=mdb(yve,'EcoreEList/Dynamic',1165);bcb(747,63,oue,W5d);_.ri=function X5d(a){return izd(this.a.a,a)};var u9=mdb(yve,'EcoreEMap/1',747);bcb(746,85,Pve,Y5d);_.bi=function Z5d(a,b){uAd(this.b,BD(b,133))};_.di=function $5d(a,b){tAd(this.b)};_.ei=function _5d(a,b,c){var d;++(d=this.b,BD(b,133),d).e};_.fi=function a6d(a,b){vAd(this.b,BD(b,133))};_.gi=function b6d(a,b,c){vAd(this.b,BD(c,133));PD(c)===PD(b)&&BD(c,133).Th(CAd(BD(b,133).cd()));uAd(this.b,BD(b,133))};var v9=mdb(yve,'EcoreEMap/DelegateEObjectContainmentEList',746);bcb(1171,151,Ave,c6d);var x9=mdb(yve,'EcoreEMap/Unsettable',1171);bcb(1172,746,Pve,d6d);_.ci=function e6d(){this.a=true};_.fj=function f6d(){return this.a};_.Xj=function g6d(){var a;Uxd(this);if(oid(this.e)){a=this.a;this.a=false;Uhd(this.e,new qSd(this.e,2,this.c,a,false))}else{this.a=false}};_.a=false;var w9=mdb(yve,'EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList',1172);bcb(1168,228,fke,A6d);_.a=false;_.b=false;var A9=mdb(yve,'EcoreUtil/Copier',1168);bcb(745,1,aie,C6d);_.Nb=function D6d(a){Rrb(this,a)};_.Ob=function E6d(){return B6d(this)};_.Pb=function F6d(){var a;B6d(this);a=this.b;this.b=null;return a};_.Qb=function G6d(){this.a.Qb()};var B9=mdb(yve,'EcoreUtil/ProperContentIterator',745);bcb(1382,1381,{},J6d);var H6d;var C9=mdb(yve,'EcoreValidator',1382);var P6d;var N9=odb(yve,'FeatureMapUtil/Validator');bcb(1260,1,{1942:1},U6d);_.rl=function V6d(a){return true};var F9=mdb(yve,'FeatureMapUtil/1',1260);bcb(757,1,{1942:1},Z6d);_.rl=function $6d(a){var b;if(this.c==a)return true;b=DD(Ohb(this.a,a));if(b==null){if(Y6d(this,a)){_6d(this.a,a,(Bcb(),Acb));return true}else{_6d(this.a,a,(Bcb(),zcb));return false}}else{return b==(Bcb(),Acb)}};_.e=false;var W6d;var I9=mdb(yve,'FeatureMapUtil/BasicValidator',757);bcb(758,43,fke,a7d);var H9=mdb(yve,'FeatureMapUtil/BasicValidator/Cache',758);bcb(501,52,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,69:1,95:1},f7d);_.Vc=function g7d(a,b){p2d(this.c,this.b,a,b)};_.Fc=function h7d(a){return q2d(this.c,this.b,a)};_.Wc=function i7d(a,b){return s2d(this.c,this.b,a,b)};_.Gc=function j7d(a){return b7d(this,a)};_.Xh=function k7d(a,b){u2d(this.c,this.b,a,b)};_.lk=function l7d(a,b){return x2d(this.c,this.b,a,b)};_.pi=function m7d(a){return J2d(this.c,this.b,a,false)};_.Zh=function n7d(){return y2d(this.c,this.b)};_.$h=function o7d(){return z2d(this.c,this.b)};_._h=function p7d(a){return A2d(this.c,this.b,a)};_.mk=function q7d(a,b){return c7d(this,a,b)};_.$b=function r7d(){d7d(this)};_.Hc=function s7d(a){return E2d(this.c,this.b,a)};_.Ic=function t7d(a){return G2d(this.c,this.b,a)};_.Xb=function u7d(a){return J2d(this.c,this.b,a,true)};_.Wj=function v7d(a){return this};_.Xc=function w7d(a){return L2d(this.c,this.b,a)};_.dc=function x7d(){return e7d(this)};_.fj=function y7d(){return !R2d(this.c,this.b)};_.Kc=function z7d(){return S2d(this.c,this.b)};_.Yc=function A7d(){return U2d(this.c,this.b)};_.Zc=function B7d(a){return V2d(this.c,this.b,a)};_.ii=function C7d(a,b){return X2d(this.c,this.b,a,b)};_.ji=function D7d(a,b){Y2d(this.c,this.b,a,b)};_.$c=function E7d(a){return Z2d(this.c,this.b,a)};_.Mc=function F7d(a){return $2d(this.c,this.b,a)};_._c=function G7d(a,b){return e3d(this.c,this.b,a,b)};_.Wb=function H7d(a){D2d(this.c,this.b);b7d(this,BD(a,15))};_.gc=function I7d(){return n3d(this.c,this.b)};_.Pc=function J7d(){return o3d(this.c,this.b)};_.Qc=function K7d(a){return q3d(this.c,this.b,a)};_.Ib=function L7d(){var a,b;b=new Hfb;b.a+='[';for(a=y2d(this.c,this.b);b4d(a);){Efb(b,xfb(d4d(a)));b4d(a)&&(b.a+=She,b)}b.a+=']';return b.a};_.Xj=function M7d(){D2d(this.c,this.b)};var J9=mdb(yve,'FeatureMapUtil/FeatureEList',501);bcb(627,36,fve,O7d);_.yi=function P7d(a){return N7d(this,a)};_.Di=function Q7d(a){var b,c,d,e,f,g,h;switch(this.d){case 1:case 2:{f=a.Ai();if(PD(f)===PD(this.c)&&N7d(this,null)==a.yi(null)){this.g=a.zi();a.xi()==1&&(this.d=1);return true}break}case 3:{e=a.xi();switch(e){case 3:{f=a.Ai();if(PD(f)===PD(this.c)&&N7d(this,null)==a.yi(null)){this.d=5;b=new zud(2);wtd(b,this.g);wtd(b,a.zi());this.g=b;return true}break}}break}case 5:{e=a.xi();switch(e){case 3:{f=a.Ai();if(PD(f)===PD(this.c)&&N7d(this,null)==a.yi(null)){c=BD(this.g,14);c.Fc(a.zi());return true}break}}break}case 4:{e=a.xi();switch(e){case 3:{f=a.Ai();if(PD(f)===PD(this.c)&&N7d(this,null)==a.yi(null)){this.d=1;this.g=a.zi();return true}break}case 4:{f=a.Ai();if(PD(f)===PD(this.c)&&N7d(this,null)==a.yi(null)){this.d=6;h=new zud(2);wtd(h,this.n);wtd(h,a.Bi());this.n=h;g=OC(GC(WD,1),oje,25,15,[this.o,a.Ci()]);this.g=g;return true}break}}break}case 6:{e=a.xi();switch(e){case 4:{f=a.Ai();if(PD(f)===PD(this.c)&&N7d(this,null)==a.yi(null)){c=BD(this.n,14);c.Fc(a.Bi());g=BD(this.g,48);d=KC(WD,oje,25,g.length+1,15,1);$fb(g,0,d,0,g.length);d[g.length]=a.Ci();this.g=d;return true}break}}break}}return false};var K9=mdb(yve,'FeatureMapUtil/FeatureENotificationImpl',627);bcb(552,501,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,153:1,215:1,1937:1,69:1,95:1},R7d);_.dl=function S7d(a,b){return q2d(this.c,a,b)};_.el=function T7d(a,b,c){return x2d(this.c,a,b,c)};_.fl=function U7d(a,b,c){return C2d(this.c,a,b,c)};_.gl=function V7d(){return this};_.hl=function W7d(a,b){return K2d(this.c,a,b)};_.il=function X7d(a){return BD(J2d(this.c,this.b,a,false),72).ak()};_.jl=function Y7d(a){return BD(J2d(this.c,this.b,a,false),72).dd()};_.kl=function Z7d(){return this.a};_.ll=function $7d(a){return !R2d(this.c,a)};_.ml=function _7d(a,b){f3d(this.c,a,b)};_.nl=function a8d(a){return g3d(this.c,a)};_.ol=function b8d(a){s3d(this.c,a)};var L9=mdb(yve,'FeatureMapUtil/FeatureFeatureMap',552);bcb(1259,1,zve,c8d);_.Wj=function d8d(a){return J2d(this.b,this.a,-1,a)};_.fj=function e8d(){return !R2d(this.b,this.a)};_.Wb=function f8d(a){f3d(this.b,this.a,a)};_.Xj=function g8d(){D2d(this.b,this.a)};var M9=mdb(yve,'FeatureMapUtil/FeatureValue',1259);var h8d,i8d,j8d,k8d,l8d;var Q9=odb(Iwe,'AnyType');bcb(666,60,Tie,n8d);var R9=mdb(Iwe,'InvalidDatatypeValueException',666);var S9=odb(Iwe,Jwe);var T9=odb(Iwe,Kwe);var U9=odb(Iwe,Lwe);var o8d;var q8d;var s8d,t8d,u8d,v8d,w8d,x8d,y8d,z8d,A8d,B8d,C8d,D8d,E8d,F8d,G8d,H8d,I8d,J8d,K8d,L8d,M8d,N8d,O8d,P8d;bcb(830,506,{105:1,92:1,90:1,56:1,49:1,97:1,843:1},R8d);_._g=function S8d(a,b,c){switch(a){case 0:if(c)return !this.c&&(this.c=new u3d(this,0)),this.c;return !this.c&&(this.c=new u3d(this,0)),this.c.b;case 1:if(c)return !this.c&&(this.c=new u3d(this,0)),BD(T2d(this.c,(Q8d(),t8d)),153);return (!this.c&&(this.c=new u3d(this,0)),BD(BD(T2d(this.c,(Q8d(),t8d)),153),215)).kl();case 2:if(c)return !this.b&&(this.b=new u3d(this,2)),this.b;return !this.b&&(this.b=new u3d(this,2)),this.b.b;}return bid(this,a-aLd(this.zh()),XKd((this.j&2)==0?this.zh():(!this.k&&(this.k=new HGd),this.k).ck(),a),b,c)};_.jh=function T8d(a,b,c){var d;switch(b){case 0:return !this.c&&(this.c=new u3d(this,0)),B2d(this.c,a,c);case 1:return (!this.c&&(this.c=new u3d(this,0)),BD(BD(T2d(this.c,(Q8d(),t8d)),153),69)).mk(a,c);case 2:return !this.b&&(this.b=new u3d(this,2)),B2d(this.b,a,c);}return d=BD(XKd((this.j&2)==0?this.zh():(!this.k&&(this.k=new HGd),this.k).ck(),b),66),d.Nj().Rj(this,Aid(this),b-aLd(this.zh()),a,c)};_.lh=function U8d(a){switch(a){case 0:return !!this.c&&this.c.i!=0;case 1:return !(!this.c&&(this.c=new u3d(this,0)),BD(T2d(this.c,(Q8d(),t8d)),153)).dc();case 2:return !!this.b&&this.b.i!=0;}return cid(this,a-aLd(this.zh()),XKd((this.j&2)==0?this.zh():(!this.k&&(this.k=new HGd),this.k).ck(),a))};_.sh=function V8d(a,b){switch(a){case 0:!this.c&&(this.c=new u3d(this,0));d3d(this.c,b);return;case 1:(!this.c&&(this.c=new u3d(this,0)),BD(BD(T2d(this.c,(Q8d(),t8d)),153),215)).Wb(b);return;case 2:!this.b&&(this.b=new u3d(this,2));d3d(this.b,b);return;}did(this,a-aLd(this.zh()),XKd((this.j&2)==0?this.zh():(!this.k&&(this.k=new HGd),this.k).ck(),a),b)};_.zh=function W8d(){return Q8d(),s8d};_.Bh=function X8d(a){switch(a){case 0:!this.c&&(this.c=new u3d(this,0));Uxd(this.c);return;case 1:(!this.c&&(this.c=new u3d(this,0)),BD(T2d(this.c,(Q8d(),t8d)),153)).$b();return;case 2:!this.b&&(this.b=new u3d(this,2));Uxd(this.b);return;}eid(this,a-aLd(this.zh()),XKd((this.j&2)==0?this.zh():(!this.k&&(this.k=new HGd),this.k).ck(),a))};_.Ib=function Y8d(){var a;if((this.j&4)!=0)return Eid(this);a=new Jfb(Eid(this));a.a+=' (mixed: ';Dfb(a,this.c);a.a+=', anyAttribute: ';Dfb(a,this.b);a.a+=')';return a.a};var V9=mdb(Mwe,'AnyTypeImpl',830);bcb(667,506,{105:1,92:1,90:1,56:1,49:1,97:1,2021:1,667:1},_8d);_._g=function a9d(a,b,c){switch(a){case 0:return this.a;case 1:return this.b;}return bid(this,a-aLd((Q8d(),F8d)),XKd((this.j&2)==0?F8d:(!this.k&&(this.k=new HGd),this.k).ck(),a),b,c)};_.lh=function b9d(a){switch(a){case 0:return this.a!=null;case 1:return this.b!=null;}return cid(this,a-aLd((Q8d(),F8d)),XKd((this.j&2)==0?F8d:(!this.k&&(this.k=new HGd),this.k).ck(),a))};_.sh=function c9d(a,b){switch(a){case 0:Z8d(this,GD(b));return;case 1:$8d(this,GD(b));return;}did(this,a-aLd((Q8d(),F8d)),XKd((this.j&2)==0?F8d:(!this.k&&(this.k=new HGd),this.k).ck(),a),b)};_.zh=function d9d(){return Q8d(),F8d};_.Bh=function e9d(a){switch(a){case 0:this.a=null;return;case 1:this.b=null;return;}eid(this,a-aLd((Q8d(),F8d)),XKd((this.j&2)==0?F8d:(!this.k&&(this.k=new HGd),this.k).ck(),a))};_.Ib=function f9d(){var a;if((this.j&4)!=0)return Eid(this);a=new Jfb(Eid(this));a.a+=' (data: ';Efb(a,this.a);a.a+=', target: ';Efb(a,this.b);a.a+=')';return a.a};_.a=null;_.b=null;var W9=mdb(Mwe,'ProcessingInstructionImpl',667);bcb(668,830,{105:1,92:1,90:1,56:1,49:1,97:1,843:1,2022:1,668:1},i9d);_._g=function j9d(a,b,c){switch(a){case 0:if(c)return !this.c&&(this.c=new u3d(this,0)),this.c;return !this.c&&(this.c=new u3d(this,0)),this.c.b;case 1:if(c)return !this.c&&(this.c=new u3d(this,0)),BD(T2d(this.c,(Q8d(),t8d)),153);return (!this.c&&(this.c=new u3d(this,0)),BD(BD(T2d(this.c,(Q8d(),t8d)),153),215)).kl();case 2:if(c)return !this.b&&(this.b=new u3d(this,2)),this.b;return !this.b&&(this.b=new u3d(this,2)),this.b.b;case 3:return !this.c&&(this.c=new u3d(this,0)),GD(K2d(this.c,(Q8d(),I8d),true));case 4:return j6d(this.a,(!this.c&&(this.c=new u3d(this,0)),GD(K2d(this.c,(Q8d(),I8d),true))));case 5:return this.a;}return bid(this,a-aLd((Q8d(),H8d)),XKd((this.j&2)==0?H8d:(!this.k&&(this.k=new HGd),this.k).ck(),a),b,c)};_.lh=function k9d(a){switch(a){case 0:return !!this.c&&this.c.i!=0;case 1:return !(!this.c&&(this.c=new u3d(this,0)),BD(T2d(this.c,(Q8d(),t8d)),153)).dc();case 2:return !!this.b&&this.b.i!=0;case 3:return !this.c&&(this.c=new u3d(this,0)),GD(K2d(this.c,(Q8d(),I8d),true))!=null;case 4:return j6d(this.a,(!this.c&&(this.c=new u3d(this,0)),GD(K2d(this.c,(Q8d(),I8d),true))))!=null;case 5:return !!this.a;}return cid(this,a-aLd((Q8d(),H8d)),XKd((this.j&2)==0?H8d:(!this.k&&(this.k=new HGd),this.k).ck(),a))};_.sh=function l9d(a,b){switch(a){case 0:!this.c&&(this.c=new u3d(this,0));d3d(this.c,b);return;case 1:(!this.c&&(this.c=new u3d(this,0)),BD(BD(T2d(this.c,(Q8d(),t8d)),153),215)).Wb(b);return;case 2:!this.b&&(this.b=new u3d(this,2));d3d(this.b,b);return;case 3:h9d(this,GD(b));return;case 4:h9d(this,h6d(this.a,b));return;case 5:g9d(this,BD(b,148));return;}did(this,a-aLd((Q8d(),H8d)),XKd((this.j&2)==0?H8d:(!this.k&&(this.k=new HGd),this.k).ck(),a),b)};_.zh=function m9d(){return Q8d(),H8d};_.Bh=function n9d(a){switch(a){case 0:!this.c&&(this.c=new u3d(this,0));Uxd(this.c);return;case 1:(!this.c&&(this.c=new u3d(this,0)),BD(T2d(this.c,(Q8d(),t8d)),153)).$b();return;case 2:!this.b&&(this.b=new u3d(this,2));Uxd(this.b);return;case 3:!this.c&&(this.c=new u3d(this,0));f3d(this.c,(Q8d(),I8d),null);return;case 4:h9d(this,h6d(this.a,null));return;case 5:this.a=null;return;}eid(this,a-aLd((Q8d(),H8d)),XKd((this.j&2)==0?H8d:(!this.k&&(this.k=new HGd),this.k).ck(),a))};var X9=mdb(Mwe,'SimpleAnyTypeImpl',668);bcb(669,506,{105:1,92:1,90:1,56:1,49:1,97:1,2023:1,669:1},o9d);_._g=function p9d(a,b,c){switch(a){case 0:if(c)return !this.a&&(this.a=new u3d(this,0)),this.a;return !this.a&&(this.a=new u3d(this,0)),this.a.b;case 1:return c?(!this.b&&(this.b=new dId((jGd(),fGd),x6,this,1)),this.b):(!this.b&&(this.b=new dId((jGd(),fGd),x6,this,1)),FAd(this.b));case 2:return c?(!this.c&&(this.c=new dId((jGd(),fGd),x6,this,2)),this.c):(!this.c&&(this.c=new dId((jGd(),fGd),x6,this,2)),FAd(this.c));case 3:return !this.a&&(this.a=new u3d(this,0)),T2d(this.a,(Q8d(),L8d));case 4:return !this.a&&(this.a=new u3d(this,0)),T2d(this.a,(Q8d(),M8d));case 5:return !this.a&&(this.a=new u3d(this,0)),T2d(this.a,(Q8d(),O8d));case 6:return !this.a&&(this.a=new u3d(this,0)),T2d(this.a,(Q8d(),P8d));}return bid(this,a-aLd((Q8d(),K8d)),XKd((this.j&2)==0?K8d:(!this.k&&(this.k=new HGd),this.k).ck(),a),b,c)};_.jh=function q9d(a,b,c){var d;switch(b){case 0:return !this.a&&(this.a=new u3d(this,0)),B2d(this.a,a,c);case 1:return !this.b&&(this.b=new dId((jGd(),fGd),x6,this,1)),bId(this.b,a,c);case 2:return !this.c&&(this.c=new dId((jGd(),fGd),x6,this,2)),bId(this.c,a,c);case 5:return !this.a&&(this.a=new u3d(this,0)),c7d(T2d(this.a,(Q8d(),O8d)),a,c);}return d=BD(XKd((this.j&2)==0?(Q8d(),K8d):(!this.k&&(this.k=new HGd),this.k).ck(),b),66),d.Nj().Rj(this,Aid(this),b-aLd((Q8d(),K8d)),a,c)};_.lh=function r9d(a){switch(a){case 0:return !!this.a&&this.a.i!=0;case 1:return !!this.b&&this.b.f!=0;case 2:return !!this.c&&this.c.f!=0;case 3:return !this.a&&(this.a=new u3d(this,0)),!e7d(T2d(this.a,(Q8d(),L8d)));case 4:return !this.a&&(this.a=new u3d(this,0)),!e7d(T2d(this.a,(Q8d(),M8d)));case 5:return !this.a&&(this.a=new u3d(this,0)),!e7d(T2d(this.a,(Q8d(),O8d)));case 6:return !this.a&&(this.a=new u3d(this,0)),!e7d(T2d(this.a,(Q8d(),P8d)));}return cid(this,a-aLd((Q8d(),K8d)),XKd((this.j&2)==0?K8d:(!this.k&&(this.k=new HGd),this.k).ck(),a))};_.sh=function s9d(a,b){switch(a){case 0:!this.a&&(this.a=new u3d(this,0));d3d(this.a,b);return;case 1:!this.b&&(this.b=new dId((jGd(),fGd),x6,this,1));cId(this.b,b);return;case 2:!this.c&&(this.c=new dId((jGd(),fGd),x6,this,2));cId(this.c,b);return;case 3:!this.a&&(this.a=new u3d(this,0));d7d(T2d(this.a,(Q8d(),L8d)));!this.a&&(this.a=new u3d(this,0));b7d(T2d(this.a,L8d),BD(b,14));return;case 4:!this.a&&(this.a=new u3d(this,0));d7d(T2d(this.a,(Q8d(),M8d)));!this.a&&(this.a=new u3d(this,0));b7d(T2d(this.a,M8d),BD(b,14));return;case 5:!this.a&&(this.a=new u3d(this,0));d7d(T2d(this.a,(Q8d(),O8d)));!this.a&&(this.a=new u3d(this,0));b7d(T2d(this.a,O8d),BD(b,14));return;case 6:!this.a&&(this.a=new u3d(this,0));d7d(T2d(this.a,(Q8d(),P8d)));!this.a&&(this.a=new u3d(this,0));b7d(T2d(this.a,P8d),BD(b,14));return;}did(this,a-aLd((Q8d(),K8d)),XKd((this.j&2)==0?K8d:(!this.k&&(this.k=new HGd),this.k).ck(),a),b)};_.zh=function t9d(){return Q8d(),K8d};_.Bh=function u9d(a){switch(a){case 0:!this.a&&(this.a=new u3d(this,0));Uxd(this.a);return;case 1:!this.b&&(this.b=new dId((jGd(),fGd),x6,this,1));this.b.c.$b();return;case 2:!this.c&&(this.c=new dId((jGd(),fGd),x6,this,2));this.c.c.$b();return;case 3:!this.a&&(this.a=new u3d(this,0));d7d(T2d(this.a,(Q8d(),L8d)));return;case 4:!this.a&&(this.a=new u3d(this,0));d7d(T2d(this.a,(Q8d(),M8d)));return;case 5:!this.a&&(this.a=new u3d(this,0));d7d(T2d(this.a,(Q8d(),O8d)));return;case 6:!this.a&&(this.a=new u3d(this,0));d7d(T2d(this.a,(Q8d(),P8d)));return;}eid(this,a-aLd((Q8d(),K8d)),XKd((this.j&2)==0?K8d:(!this.k&&(this.k=new HGd),this.k).ck(),a))};_.Ib=function v9d(){var a;if((this.j&4)!=0)return Eid(this);a=new Jfb(Eid(this));a.a+=' (mixed: ';Dfb(a,this.a);a.a+=')';return a.a};var Y9=mdb(Mwe,'XMLTypeDocumentRootImpl',669);bcb(1919,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1,2024:1},U9d);_.Ih=function V9d(a,b){switch(a.yj()){case 7:case 8:case 9:case 10:case 16:case 22:case 23:case 24:case 25:case 26:case 32:case 33:case 34:case 36:case 37:case 44:case 45:case 50:case 51:case 53:case 55:case 56:case 57:case 58:case 60:case 61:case 4:return b==null?null:fcb(b);case 19:case 28:case 29:case 35:case 38:case 39:case 41:case 46:case 52:case 54:case 5:return GD(b);case 6:return C9d(BD(b,190));case 12:case 47:case 49:case 11:return Vmd(this,a,b);case 13:return b==null?null:qgb(BD(b,240));case 15:case 14:return b==null?null:D9d(Edb(ED(b)));case 17:return E9d((Q8d(),b));case 18:return E9d(b);case 21:case 20:return b==null?null:F9d(BD(b,155).a);case 27:return G9d(BD(b,190));case 30:return H9d((Q8d(),BD(b,15)));case 31:return H9d(BD(b,15));case 40:return K9d((Q8d(),b));case 42:return I9d((Q8d(),b));case 43:return I9d(b);case 59:case 48:return J9d((Q8d(),b));default:throw vbb(new Wdb(tte+a.ne()+ute));}};_.Jh=function W9d(a){var b,c,d,e,f;switch(a.G==-1&&(a.G=(c=bKd(a),c?HLd(c.Mh(),a):-1)),a.G){case 0:return b=new R8d,b;case 1:return d=new _8d,d;case 2:return e=new i9d,e;case 3:return f=new o9d,f;default:throw vbb(new Wdb(xte+a.zb+ute));}};_.Kh=function X9d(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;switch(a.yj()){case 5:case 52:case 4:return b;case 6:return L9d(b);case 8:case 7:return b==null?null:B9d(b);case 9:return b==null?null:Scb(Icb((d=Qge(b,true),d.length>0&&(BCb(0,d.length),d.charCodeAt(0)==43)?d.substr(1):d),-128,127)<<24>>24);case 10:return b==null?null:Scb(Icb((e=Qge(b,true),e.length>0&&(BCb(0,e.length),e.charCodeAt(0)==43)?e.substr(1):e),-128,127)<<24>>24);case 11:return GD(Wmd(this,(Q8d(),w8d),b));case 12:return GD(Wmd(this,(Q8d(),x8d),b));case 13:return b==null?null:new tgb(Qge(b,true));case 15:case 14:return M9d(b);case 16:return GD(Wmd(this,(Q8d(),y8d),b));case 17:return N9d((Q8d(),b));case 18:return N9d(b);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return Qge(b,true);case 21:case 20:return O9d(b);case 22:return GD(Wmd(this,(Q8d(),z8d),b));case 23:return GD(Wmd(this,(Q8d(),A8d),b));case 24:return GD(Wmd(this,(Q8d(),B8d),b));case 25:return GD(Wmd(this,(Q8d(),C8d),b));case 26:return GD(Wmd(this,(Q8d(),D8d),b));case 27:return P9d(b);case 30:return Q9d((Q8d(),b));case 31:return Q9d(b);case 32:return b==null?null:meb(Icb((k=Qge(b,true),k.length>0&&(BCb(0,k.length),k.charCodeAt(0)==43)?k.substr(1):k),Rie,Ohe));case 33:return b==null?null:new Ygb((l=Qge(b,true),l.length>0&&(BCb(0,l.length),l.charCodeAt(0)==43)?l.substr(1):l));case 34:return b==null?null:meb(Icb((m=Qge(b,true),m.length>0&&(BCb(0,m.length),m.charCodeAt(0)==43)?m.substr(1):m),Rie,Ohe));case 36:return b==null?null:Aeb(Jcb((n=Qge(b,true),n.length>0&&(BCb(0,n.length),n.charCodeAt(0)==43)?n.substr(1):n)));case 37:return b==null?null:Aeb(Jcb((o=Qge(b,true),o.length>0&&(BCb(0,o.length),o.charCodeAt(0)==43)?o.substr(1):o)));case 40:return T9d((Q8d(),b));case 42:return R9d((Q8d(),b));case 43:return R9d(b);case 44:return b==null?null:new Ygb((p=Qge(b,true),p.length>0&&(BCb(0,p.length),p.charCodeAt(0)==43)?p.substr(1):p));case 45:return b==null?null:new Ygb((q=Qge(b,true),q.length>0&&(BCb(0,q.length),q.charCodeAt(0)==43)?q.substr(1):q));case 46:return Qge(b,false);case 47:return GD(Wmd(this,(Q8d(),E8d),b));case 59:case 48:return S9d((Q8d(),b));case 49:return GD(Wmd(this,(Q8d(),G8d),b));case 50:return b==null?null:Web(Icb((r=Qge(b,true),r.length>0&&(BCb(0,r.length),r.charCodeAt(0)==43)?r.substr(1):r),awe,32767)<<16>>16);case 51:return b==null?null:Web(Icb((f=Qge(b,true),f.length>0&&(BCb(0,f.length),f.charCodeAt(0)==43)?f.substr(1):f),awe,32767)<<16>>16);case 53:return GD(Wmd(this,(Q8d(),J8d),b));case 55:return b==null?null:Web(Icb((g=Qge(b,true),g.length>0&&(BCb(0,g.length),g.charCodeAt(0)==43)?g.substr(1):g),awe,32767)<<16>>16);case 56:return b==null?null:Web(Icb((h=Qge(b,true),h.length>0&&(BCb(0,h.length),h.charCodeAt(0)==43)?h.substr(1):h),awe,32767)<<16>>16);case 57:return b==null?null:Aeb(Jcb((i=Qge(b,true),i.length>0&&(BCb(0,i.length),i.charCodeAt(0)==43)?i.substr(1):i)));case 58:return b==null?null:Aeb(Jcb((j=Qge(b,true),j.length>0&&(BCb(0,j.length),j.charCodeAt(0)==43)?j.substr(1):j)));case 60:return b==null?null:meb(Icb((c=Qge(b,true),c.length>0&&(BCb(0,c.length),c.charCodeAt(0)==43)?c.substr(1):c),Rie,Ohe));case 61:return b==null?null:meb(Icb(Qge(b,true),Rie,Ohe));default:throw vbb(new Wdb(tte+a.ne()+ute));}};var w9d,x9d,y9d,z9d;var Z9=mdb(Mwe,'XMLTypeFactoryImpl',1919);bcb(586,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1,1945:1,586:1},cae);_.N=false;_.O=false;var Z9d=false;var Yab=mdb(Mwe,'XMLTypePackageImpl',586);bcb(1852,1,{837:1},fae);_._j=function gae(){return Uge(),Tge};var iab=mdb(Mwe,'XMLTypePackageImpl/1',1852);bcb(1861,1,nwe,hae);_.wj=function iae(a){return ND(a)};_.xj=function jae(a){return KC(ZI,nie,2,a,6,1)};var $9=mdb(Mwe,'XMLTypePackageImpl/10',1861);bcb(1862,1,nwe,kae);_.wj=function lae(a){return ND(a)};_.xj=function mae(a){return KC(ZI,nie,2,a,6,1)};var _9=mdb(Mwe,'XMLTypePackageImpl/11',1862);bcb(1863,1,nwe,nae);_.wj=function oae(a){return ND(a)};_.xj=function pae(a){return KC(ZI,nie,2,a,6,1)};var aab=mdb(Mwe,'XMLTypePackageImpl/12',1863);bcb(1864,1,nwe,qae);_.wj=function rae(a){return LD(a)};_.xj=function sae(a){return KC(BI,nie,333,a,7,1)};var bab=mdb(Mwe,'XMLTypePackageImpl/13',1864);bcb(1865,1,nwe,tae);_.wj=function uae(a){return ND(a)};_.xj=function vae(a){return KC(ZI,nie,2,a,6,1)};var cab=mdb(Mwe,'XMLTypePackageImpl/14',1865);bcb(1866,1,nwe,wae);_.wj=function xae(a){return JD(a,15)};_.xj=function yae(a){return KC(yK,eme,15,a,0,1)};var dab=mdb(Mwe,'XMLTypePackageImpl/15',1866);bcb(1867,1,nwe,zae);_.wj=function Aae(a){return JD(a,15)};_.xj=function Bae(a){return KC(yK,eme,15,a,0,1)};var eab=mdb(Mwe,'XMLTypePackageImpl/16',1867);bcb(1868,1,nwe,Cae);_.wj=function Dae(a){return ND(a)};_.xj=function Eae(a){return KC(ZI,nie,2,a,6,1)};var fab=mdb(Mwe,'XMLTypePackageImpl/17',1868);bcb(1869,1,nwe,Fae);_.wj=function Gae(a){return JD(a,155)};_.xj=function Hae(a){return KC(FI,nie,155,a,0,1)};var gab=mdb(Mwe,'XMLTypePackageImpl/18',1869);bcb(1870,1,nwe,Iae);_.wj=function Jae(a){return ND(a)};_.xj=function Kae(a){return KC(ZI,nie,2,a,6,1)};var hab=mdb(Mwe,'XMLTypePackageImpl/19',1870);bcb(1853,1,nwe,Lae);_.wj=function Mae(a){return JD(a,843)};_.xj=function Nae(a){return KC(Q9,Uhe,843,a,0,1)};var tab=mdb(Mwe,'XMLTypePackageImpl/2',1853);bcb(1871,1,nwe,Oae);_.wj=function Pae(a){return ND(a)};_.xj=function Qae(a){return KC(ZI,nie,2,a,6,1)};var jab=mdb(Mwe,'XMLTypePackageImpl/20',1871);bcb(1872,1,nwe,Rae);_.wj=function Sae(a){return ND(a)};_.xj=function Tae(a){return KC(ZI,nie,2,a,6,1)};var kab=mdb(Mwe,'XMLTypePackageImpl/21',1872);bcb(1873,1,nwe,Uae);_.wj=function Vae(a){return ND(a)};_.xj=function Wae(a){return KC(ZI,nie,2,a,6,1)};var lab=mdb(Mwe,'XMLTypePackageImpl/22',1873);bcb(1874,1,nwe,Xae);_.wj=function Yae(a){return ND(a)};_.xj=function Zae(a){return KC(ZI,nie,2,a,6,1)};var mab=mdb(Mwe,'XMLTypePackageImpl/23',1874);bcb(1875,1,nwe,$ae);_.wj=function _ae(a){return JD(a,190)};_.xj=function abe(a){return KC(SD,nie,190,a,0,2)};var nab=mdb(Mwe,'XMLTypePackageImpl/24',1875);bcb(1876,1,nwe,bbe);_.wj=function cbe(a){return ND(a)};_.xj=function dbe(a){return KC(ZI,nie,2,a,6,1)};var oab=mdb(Mwe,'XMLTypePackageImpl/25',1876);bcb(1877,1,nwe,ebe);_.wj=function fbe(a){return ND(a)};_.xj=function gbe(a){return KC(ZI,nie,2,a,6,1)};var pab=mdb(Mwe,'XMLTypePackageImpl/26',1877);bcb(1878,1,nwe,hbe);_.wj=function ibe(a){return JD(a,15)};_.xj=function jbe(a){return KC(yK,eme,15,a,0,1)};var qab=mdb(Mwe,'XMLTypePackageImpl/27',1878);bcb(1879,1,nwe,kbe);_.wj=function lbe(a){return JD(a,15)};_.xj=function mbe(a){return KC(yK,eme,15,a,0,1)};var rab=mdb(Mwe,'XMLTypePackageImpl/28',1879);bcb(1880,1,nwe,nbe);_.wj=function obe(a){return ND(a)};_.xj=function pbe(a){return KC(ZI,nie,2,a,6,1)};var sab=mdb(Mwe,'XMLTypePackageImpl/29',1880);bcb(1854,1,nwe,qbe);_.wj=function rbe(a){return JD(a,667)};_.xj=function sbe(a){return KC(S9,Uhe,2021,a,0,1)};var Eab=mdb(Mwe,'XMLTypePackageImpl/3',1854);bcb(1881,1,nwe,tbe);_.wj=function ube(a){return JD(a,19)};_.xj=function vbe(a){return KC(JI,nie,19,a,0,1)};var uab=mdb(Mwe,'XMLTypePackageImpl/30',1881);bcb(1882,1,nwe,wbe);_.wj=function xbe(a){return ND(a)};_.xj=function ybe(a){return KC(ZI,nie,2,a,6,1)};var vab=mdb(Mwe,'XMLTypePackageImpl/31',1882);bcb(1883,1,nwe,zbe);_.wj=function Abe(a){return JD(a,162)};_.xj=function Bbe(a){return KC(MI,nie,162,a,0,1)};var wab=mdb(Mwe,'XMLTypePackageImpl/32',1883);bcb(1884,1,nwe,Cbe);_.wj=function Dbe(a){return ND(a)};_.xj=function Ebe(a){return KC(ZI,nie,2,a,6,1)};var xab=mdb(Mwe,'XMLTypePackageImpl/33',1884);bcb(1885,1,nwe,Fbe);_.wj=function Gbe(a){return ND(a)};_.xj=function Hbe(a){return KC(ZI,nie,2,a,6,1)};var yab=mdb(Mwe,'XMLTypePackageImpl/34',1885);bcb(1886,1,nwe,Ibe);_.wj=function Jbe(a){return ND(a)};_.xj=function Kbe(a){return KC(ZI,nie,2,a,6,1)};var zab=mdb(Mwe,'XMLTypePackageImpl/35',1886);bcb(1887,1,nwe,Lbe);_.wj=function Mbe(a){return ND(a)};_.xj=function Nbe(a){return KC(ZI,nie,2,a,6,1)};var Aab=mdb(Mwe,'XMLTypePackageImpl/36',1887);bcb(1888,1,nwe,Obe);_.wj=function Pbe(a){return JD(a,15)};_.xj=function Qbe(a){return KC(yK,eme,15,a,0,1)};var Bab=mdb(Mwe,'XMLTypePackageImpl/37',1888);bcb(1889,1,nwe,Rbe);_.wj=function Sbe(a){return JD(a,15)};_.xj=function Tbe(a){return KC(yK,eme,15,a,0,1)};var Cab=mdb(Mwe,'XMLTypePackageImpl/38',1889);bcb(1890,1,nwe,Ube);_.wj=function Vbe(a){return ND(a)};_.xj=function Wbe(a){return KC(ZI,nie,2,a,6,1)};var Dab=mdb(Mwe,'XMLTypePackageImpl/39',1890);bcb(1855,1,nwe,Xbe);_.wj=function Ybe(a){return JD(a,668)};_.xj=function Zbe(a){return KC(T9,Uhe,2022,a,0,1)};var Pab=mdb(Mwe,'XMLTypePackageImpl/4',1855);bcb(1891,1,nwe,$be);_.wj=function _be(a){return ND(a)};_.xj=function ace(a){return KC(ZI,nie,2,a,6,1)};var Fab=mdb(Mwe,'XMLTypePackageImpl/40',1891);bcb(1892,1,nwe,bce);_.wj=function cce(a){return ND(a)};_.xj=function dce(a){return KC(ZI,nie,2,a,6,1)};var Gab=mdb(Mwe,'XMLTypePackageImpl/41',1892);bcb(1893,1,nwe,ece);_.wj=function fce(a){return ND(a)};_.xj=function gce(a){return KC(ZI,nie,2,a,6,1)};var Hab=mdb(Mwe,'XMLTypePackageImpl/42',1893);bcb(1894,1,nwe,hce);_.wj=function ice(a){return ND(a)};_.xj=function jce(a){return KC(ZI,nie,2,a,6,1)};var Iab=mdb(Mwe,'XMLTypePackageImpl/43',1894);bcb(1895,1,nwe,kce);_.wj=function lce(a){return ND(a)};_.xj=function mce(a){return KC(ZI,nie,2,a,6,1)};var Jab=mdb(Mwe,'XMLTypePackageImpl/44',1895);bcb(1896,1,nwe,nce);_.wj=function oce(a){return JD(a,184)};_.xj=function pce(a){return KC(UI,nie,184,a,0,1)};var Kab=mdb(Mwe,'XMLTypePackageImpl/45',1896);bcb(1897,1,nwe,qce);_.wj=function rce(a){return ND(a)};_.xj=function sce(a){return KC(ZI,nie,2,a,6,1)};var Lab=mdb(Mwe,'XMLTypePackageImpl/46',1897);bcb(1898,1,nwe,tce);_.wj=function uce(a){return ND(a)};_.xj=function vce(a){return KC(ZI,nie,2,a,6,1)};var Mab=mdb(Mwe,'XMLTypePackageImpl/47',1898);bcb(1899,1,nwe,wce);_.wj=function xce(a){return ND(a)};_.xj=function yce(a){return KC(ZI,nie,2,a,6,1)};var Nab=mdb(Mwe,'XMLTypePackageImpl/48',1899);bcb(nje,1,nwe,zce);_.wj=function Ace(a){return JD(a,184)};_.xj=function Bce(a){return KC(UI,nie,184,a,0,1)};var Oab=mdb(Mwe,'XMLTypePackageImpl/49',nje);bcb(1856,1,nwe,Cce);_.wj=function Dce(a){return JD(a,669)};_.xj=function Ece(a){return KC(U9,Uhe,2023,a,0,1)};var Tab=mdb(Mwe,'XMLTypePackageImpl/5',1856);bcb(1901,1,nwe,Fce);_.wj=function Gce(a){return JD(a,162)};_.xj=function Hce(a){return KC(MI,nie,162,a,0,1)};var Qab=mdb(Mwe,'XMLTypePackageImpl/50',1901);bcb(1902,1,nwe,Ice);_.wj=function Jce(a){return ND(a)};_.xj=function Kce(a){return KC(ZI,nie,2,a,6,1)};var Rab=mdb(Mwe,'XMLTypePackageImpl/51',1902);bcb(1903,1,nwe,Lce);_.wj=function Mce(a){return JD(a,19)};_.xj=function Nce(a){return KC(JI,nie,19,a,0,1)};var Sab=mdb(Mwe,'XMLTypePackageImpl/52',1903);bcb(1857,1,nwe,Oce);_.wj=function Pce(a){return ND(a)};_.xj=function Qce(a){return KC(ZI,nie,2,a,6,1)};var Uab=mdb(Mwe,'XMLTypePackageImpl/6',1857);bcb(1858,1,nwe,Rce);_.wj=function Sce(a){return JD(a,190)};_.xj=function Tce(a){return KC(SD,nie,190,a,0,2)};var Vab=mdb(Mwe,'XMLTypePackageImpl/7',1858);bcb(1859,1,nwe,Uce);_.wj=function Vce(a){return KD(a)};_.xj=function Wce(a){return KC(wI,nie,476,a,8,1)};var Wab=mdb(Mwe,'XMLTypePackageImpl/8',1859);bcb(1860,1,nwe,Xce);_.wj=function Yce(a){return JD(a,217)};_.xj=function Zce(a){return KC(xI,nie,217,a,0,1)};var Xab=mdb(Mwe,'XMLTypePackageImpl/9',1860);var $ce,_ce;var fde,gde;var kde;bcb(50,60,Tie,mde);var Zab=mdb(kxe,'RegEx/ParseException',50);bcb(820,1,{},ude);_.sl=function vde(a){return a<this.j&&bfb(this.i,a)==63};_.tl=function wde(){var a,b,c,d,e;if(this.c!=10)throw vbb(new mde(tvd((h0d(),uue))));a=this.a;switch(a){case 101:a=27;break;case 102:a=12;break;case 110:a=10;break;case 114:a=13;break;case 116:a=9;break;case 120:nde(this);if(this.c!=0)throw vbb(new mde(tvd((h0d(),Tue))));if(this.a==123){e=0;c=0;do{nde(this);if(this.c!=0)throw vbb(new mde(tvd((h0d(),Tue))));if((e=yde(this.a))<0)break;if(c>c*16)throw vbb(new mde(tvd((h0d(),Uue))));c=c*16+e}while(true);if(this.a!=125)throw vbb(new mde(tvd((h0d(),Vue))));if(c>lxe)throw vbb(new mde(tvd((h0d(),Wue))));a=c}else{e=0;if(this.c!=0||(e=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));c=e;nde(this);if(this.c!=0||(e=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));c=c*16+e;a=c}break;case 117:d=0;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=d;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=b*16+d;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=b*16+d;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=b*16+d;a=b;break;case 118:nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=d;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=b*16+d;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=b*16+d;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=b*16+d;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=b*16+d;nde(this);if(this.c!=0||(d=yde(this.a))<0)throw vbb(new mde(tvd((h0d(),Tue))));b=b*16+d;if(b>lxe)throw vbb(new mde(tvd((h0d(),'parser.descappe.4'))));a=b;break;case 65:case 90:case 122:throw vbb(new mde(tvd((h0d(),Xue))));}return a};_.ul=function xde(a){var b,c;switch(a){case 100:c=(this.e&32)==32?Kfe('Nd',true):(wfe(),cfe);break;case 68:c=(this.e&32)==32?Kfe('Nd',false):(wfe(),jfe);break;case 119:c=(this.e&32)==32?Kfe('IsWord',true):(wfe(),sfe);break;case 87:c=(this.e&32)==32?Kfe('IsWord',false):(wfe(),lfe);break;case 115:c=(this.e&32)==32?Kfe('IsSpace',true):(wfe(),nfe);break;case 83:c=(this.e&32)==32?Kfe('IsSpace',false):(wfe(),kfe);break;default:throw vbb(new hz((b=a,mxe+b.toString(16))));}return c};_.vl=function zde(a){var b,c,d,e,f,g,h,i,j,k,l,m;this.b=1;nde(this);b=null;if(this.c==0&&this.a==94){nde(this);if(a){k=(wfe(),wfe(),++vfe,new $fe(5))}else{b=(wfe(),wfe(),++vfe,new $fe(4));Ufe(b,0,lxe);k=(null,++vfe,new $fe(4))}}else{k=(wfe(),wfe(),++vfe,new $fe(4))}e=true;while((m=this.c)!=1){if(m==0&&this.a==93&&!e)break;e=false;c=this.a;d=false;if(m==10){switch(c){case 100:case 68:case 119:case 87:case 115:case 83:Xfe(k,this.ul(c));d=true;break;case 105:case 73:case 99:case 67:c=this.Ll(k,c);c<0&&(d=true);break;case 112:case 80:l=tde(this,c);if(!l)throw vbb(new mde(tvd((h0d(),Iue))));Xfe(k,l);d=true;break;default:c=this.tl();}}else if(m==20){g=gfb(this.i,58,this.d);if(g<0)throw vbb(new mde(tvd((h0d(),Jue))));h=true;if(bfb(this.i,this.d)==94){++this.d;h=false}f=qfb(this.i,this.d,g);i=Lfe(f,h,(this.e&512)==512);if(!i)throw vbb(new mde(tvd((h0d(),Lue))));Xfe(k,i);d=true;if(g+1>=this.j||bfb(this.i,g+1)!=93)throw vbb(new mde(tvd((h0d(),Jue))));this.d=g+2}nde(this);if(!d){if(this.c!=0||this.a!=45){Ufe(k,c,c)}else{nde(this);if((m=this.c)==1)throw vbb(new mde(tvd((h0d(),Kue))));if(m==0&&this.a==93){Ufe(k,c,c);Ufe(k,45,45)}else{j=this.a;m==10&&(j=this.tl());nde(this);Ufe(k,c,j)}}}(this.e&zte)==zte&&this.c==0&&this.a==44&&nde(this)}if(this.c==1)throw vbb(new mde(tvd((h0d(),Kue))));if(b){Zfe(b,k);k=b}Yfe(k);Vfe(k);this.b=0;nde(this);return k};_.wl=function Ade(){var a,b,c,d;c=this.vl(false);while((d=this.c)!=7){a=this.a;if(d==0&&(a==45||a==38)||d==4){nde(this);if(this.c!=9)throw vbb(new mde(tvd((h0d(),Que))));b=this.vl(false);if(d==4)Xfe(c,b);else if(a==45)Zfe(c,b);else if(a==38)Wfe(c,b);else throw vbb(new hz('ASSERT'))}else{throw vbb(new mde(tvd((h0d(),Rue))))}}nde(this);return c};_.xl=function Bde(){var a,b;a=this.a-48;b=(wfe(),wfe(),++vfe,new Hge(12,null,a));!this.g&&(this.g=new Wvb);Tvb(this.g,new cge(a));nde(this);return b};_.yl=function Cde(){nde(this);return wfe(),ofe};_.zl=function Dde(){nde(this);return wfe(),mfe};_.Al=function Ede(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Bl=function Fde(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Cl=function Gde(){nde(this);return Ife()};_.Dl=function Hde(){nde(this);return wfe(),qfe};_.El=function Ide(){nde(this);return wfe(),tfe};_.Fl=function Jde(){var a;if(this.d>=this.j||((a=bfb(this.i,this.d++))&65504)!=64)throw vbb(new mde(tvd((h0d(),Eue))));nde(this);return wfe(),wfe(),++vfe,new ige(0,a-64)};_.Gl=function Kde(){nde(this);return Jfe()};_.Hl=function Lde(){nde(this);return wfe(),ufe};_.Il=function Mde(){var a;a=(wfe(),wfe(),++vfe,new ige(0,105));nde(this);return a};_.Jl=function Nde(){nde(this);return wfe(),rfe};_.Kl=function Ode(){nde(this);return wfe(),pfe};_.Ll=function Pde(a,b){return this.tl()};_.Ml=function Qde(){nde(this);return wfe(),hfe};_.Nl=function Rde(){var a,b,c,d,e;if(this.d+1>=this.j)throw vbb(new mde(tvd((h0d(),Bue))));d=-1;b=null;a=bfb(this.i,this.d);if(49<=a&&a<=57){d=a-48;!this.g&&(this.g=new Wvb);Tvb(this.g,new cge(d));++this.d;if(bfb(this.i,this.d)!=41)throw vbb(new mde(tvd((h0d(),yue))));++this.d}else{a==63&&--this.d;nde(this);b=qde(this);switch(b.e){case 20:case 21:case 22:case 23:break;case 8:if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));break;default:throw vbb(new mde(tvd((h0d(),Cue))));}}nde(this);e=rde(this);c=null;if(e.e==2){if(e.em()!=2)throw vbb(new mde(tvd((h0d(),Due))));c=e.am(1);e=e.am(0)}if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return wfe(),wfe(),++vfe,new vge(d,b,e,c)};_.Ol=function Sde(){nde(this);return wfe(),ife};_.Pl=function Tde(){var a;nde(this);a=Cfe(24,rde(this));if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return a};_.Ql=function Ude(){var a;nde(this);a=Cfe(20,rde(this));if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return a};_.Rl=function Vde(){var a;nde(this);a=Cfe(22,rde(this));if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return a};_.Sl=function Wde(){var a,b,c,d,e;a=0;c=0;b=-1;while(this.d<this.j){b=bfb(this.i,this.d);e=Uee(b);if(e==0)break;a|=e;++this.d}if(this.d>=this.j)throw vbb(new mde(tvd((h0d(),zue))));if(b==45){++this.d;while(this.d<this.j){b=bfb(this.i,this.d);e=Uee(b);if(e==0)break;c|=e;++this.d}if(this.d>=this.j)throw vbb(new mde(tvd((h0d(),zue))))}if(b==58){++this.d;nde(this);d=Dfe(rde(this),a,c);if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this)}else if(b==41){++this.d;nde(this);d=Dfe(rde(this),a,c)}else throw vbb(new mde(tvd((h0d(),Aue))));return d};_.Tl=function Xde(){var a;nde(this);a=Cfe(21,rde(this));if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return a};_.Ul=function Yde(){var a;nde(this);a=Cfe(23,rde(this));if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return a};_.Vl=function Zde(){var a,b;nde(this);a=this.f++;b=Efe(rde(this),a);if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return b};_.Wl=function $de(){var a;nde(this);a=Efe(rde(this),0);if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return a};_.Xl=function _de(a){nde(this);if(this.c==5){nde(this);return Bfe(a,(wfe(),wfe(),++vfe,new lge(9,a)))}else return Bfe(a,(wfe(),wfe(),++vfe,new lge(3,a)))};_.Yl=function aee(a){var b;nde(this);b=(wfe(),wfe(),++vfe,new Lge(2));if(this.c==5){nde(this);Kge(b,(null,ffe));Kge(b,a)}else{Kge(b,a);Kge(b,(null,ffe))}return b};_.Zl=function bee(a){nde(this);if(this.c==5){nde(this);return wfe(),wfe(),++vfe,new lge(9,a)}else return wfe(),wfe(),++vfe,new lge(3,a)};_.a=0;_.b=0;_.c=0;_.d=0;_.e=0;_.f=1;_.g=null;_.j=0;var bbb=mdb(kxe,'RegEx/RegexParser',820);bcb(1824,820,{},hee);_.sl=function iee(a){return false};_.tl=function jee(){return eee(this)};_.ul=function lee(a){return fee(a)};_.vl=function mee(a){return gee(this)};_.wl=function nee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.xl=function oee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.yl=function pee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.zl=function qee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Al=function ree(){nde(this);return fee(67)};_.Bl=function see(){nde(this);return fee(73)};_.Cl=function tee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Dl=function uee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.El=function vee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Fl=function wee(){nde(this);return fee(99)};_.Gl=function xee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Hl=function yee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Il=function zee(){nde(this);return fee(105)};_.Jl=function Aee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Kl=function Bee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Ll=function Cee(a,b){return Xfe(a,fee(b)),-1};_.Ml=function Dee(){nde(this);return wfe(),wfe(),++vfe,new ige(0,94)};_.Nl=function Eee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Ol=function Fee(){nde(this);return wfe(),wfe(),++vfe,new ige(0,36)};_.Pl=function Gee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Ql=function Hee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Rl=function Iee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Sl=function Jee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Tl=function Kee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Ul=function Lee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Vl=function Mee(){var a;nde(this);a=Efe(rde(this),0);if(this.c!=7)throw vbb(new mde(tvd((h0d(),yue))));nde(this);return a};_.Wl=function Nee(){throw vbb(new mde(tvd((h0d(),Yue))))};_.Xl=function Oee(a){nde(this);return Bfe(a,(wfe(),wfe(),++vfe,new lge(3,a)))};_.Yl=function Pee(a){var b;nde(this);b=(wfe(),wfe(),++vfe,new Lge(2));Kge(b,a);Kge(b,(null,ffe));return b};_.Zl=function Qee(a){nde(this);return wfe(),wfe(),++vfe,new lge(3,a)};var cee=null,dee=null;var $ab=mdb(kxe,'RegEx/ParserForXMLSchema',1824);bcb(117,1,yxe,xfe);_.$l=function yfe(a){throw vbb(new hz('Not supported.'))};_._l=function Gfe(){return -1};_.am=function Hfe(a){return null};_.bm=function Mfe(){return null};_.cm=function Pfe(a){};_.dm=function Qfe(a){};_.em=function Rfe(){return 0};_.Ib=function Sfe(){return this.fm(0)};_.fm=function Tfe(a){return this.e==11?'.':''};_.e=0;var Yee,Zee,$ee,_ee,afe,bfe=null,cfe,dfe=null,efe,ffe,gfe=null,hfe,ife,jfe,kfe,lfe,mfe,nfe,ofe,pfe,qfe,rfe,sfe,tfe,ufe,vfe=0;var lbb=mdb(kxe,'RegEx/Token',117);bcb(136,117,{3:1,136:1,117:1},$fe);_.fm=function bge(a){var b,c,d;if(this.e==4){if(this==efe)c='.';else if(this==cfe)c='\\d';else if(this==sfe)c='\\w';else if(this==nfe)c='\\s';else{d=new Hfb;d.a+='[';for(b=0;b<this.b.length;b+=2){(a&zte)!=0&&b>0&&(d.a+=',',d);if(this.b[b]===this.b[b+1]){Efb(d,age(this.b[b]))}else{Efb(d,age(this.b[b]));d.a+='-';Efb(d,age(this.b[b+1]))}}d.a+=']';c=d.a}}else{if(this==jfe)c='\\D';else if(this==lfe)c='\\W';else if(this==kfe)c='\\S';else{d=new Hfb;d.a+='[^';for(b=0;b<this.b.length;b+=2){(a&zte)!=0&&b>0&&(d.a+=',',d);if(this.b[b]===this.b[b+1]){Efb(d,age(this.b[b]))}else{Efb(d,age(this.b[b]));d.a+='-';Efb(d,age(this.b[b+1]))}}d.a+=']';c=d.a}}return c};_.a=false;_.c=false;var _ab=mdb(kxe,'RegEx/RangeToken',136);bcb(584,1,{584:1},cge);_.a=0;var abb=mdb(kxe,'RegEx/RegexParser/ReferencePosition',584);bcb(583,1,{3:1,583:1},ege);_.Fb=function fge(a){var b;if(a==null)return false;if(!JD(a,583))return false;b=BD(a,583);return dfb(this.b,b.b)&&this.a==b.a};_.Hb=function gge(){return LCb(this.b+'/'+See(this.a))};_.Ib=function hge(){return this.c.fm(this.a)};_.a=0;var cbb=mdb(kxe,'RegEx/RegularExpression',583);bcb(223,117,yxe,ige);_._l=function jge(){return this.a};_.fm=function kge(a){var b,c,d;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:d='\\'+HD(this.a&aje);break;case 12:d='\\f';break;case 10:d='\\n';break;case 13:d='\\r';break;case 9:d='\\t';break;case 27:d='\\e';break;default:if(this.a>=Tje){c=(b=this.a>>>0,'0'+b.toString(16));d='\\v'+qfb(c,c.length-6,c.length)}else d=''+HD(this.a&aje);}break;case 8:this==hfe||this==ife?(d=''+HD(this.a&aje)):(d='\\'+HD(this.a&aje));break;default:d=null;}return d};_.a=0;var dbb=mdb(kxe,'RegEx/Token/CharToken',223);bcb(309,117,yxe,lge);_.am=function mge(a){return this.a};_.cm=function nge(a){this.b=a};_.dm=function oge(a){this.c=a};_.em=function pge(){return 1};_.fm=function qge(a){var b;if(this.e==3){if(this.c<0&&this.b<0){b=this.a.fm(a)+'*'}else if(this.c==this.b){b=this.a.fm(a)+'{'+this.c+'}'}else if(this.c>=0&&this.b>=0){b=this.a.fm(a)+'{'+this.c+','+this.b+'}'}else if(this.c>=0&&this.b<0){b=this.a.fm(a)+'{'+this.c+',}'}else throw vbb(new hz('Token#toString(): CLOSURE '+this.c+She+this.b))}else{if(this.c<0&&this.b<0){b=this.a.fm(a)+'*?'}else if(this.c==this.b){b=this.a.fm(a)+'{'+this.c+'}?'}else if(this.c>=0&&this.b>=0){b=this.a.fm(a)+'{'+this.c+','+this.b+'}?'}else if(this.c>=0&&this.b<0){b=this.a.fm(a)+'{'+this.c+',}?'}else throw vbb(new hz('Token#toString(): NONGREEDYCLOSURE '+this.c+She+this.b))}return b};_.b=0;_.c=0;var ebb=mdb(kxe,'RegEx/Token/ClosureToken',309);bcb(821,117,yxe,rge);_.am=function sge(a){return a==0?this.a:this.b};_.em=function tge(){return 2};_.fm=function uge(a){var b;this.b.e==3&&this.b.am(0)==this.a?(b=this.a.fm(a)+'+'):this.b.e==9&&this.b.am(0)==this.a?(b=this.a.fm(a)+'+?'):(b=this.a.fm(a)+(''+this.b.fm(a)));return b};var fbb=mdb(kxe,'RegEx/Token/ConcatToken',821);bcb(1822,117,yxe,vge);_.am=function wge(a){if(a==0)return this.d;if(a==1)return this.b;throw vbb(new hz('Internal Error: '+a))};_.em=function xge(){return !this.b?1:2};_.fm=function yge(a){var b;this.c>0?(b='(?('+this.c+')'):this.a.e==8?(b='(?('+this.a+')'):(b='(?'+this.a);!this.b?(b+=this.d+')'):(b+=this.d+'|'+this.b+')');return b};_.c=0;var gbb=mdb(kxe,'RegEx/Token/ConditionToken',1822);bcb(1823,117,yxe,zge);_.am=function Age(a){return this.b};_.em=function Bge(){return 1};_.fm=function Cge(a){return '(?'+(this.a==0?'':See(this.a))+(this.c==0?'':See(this.c))+':'+this.b.fm(a)+')'};_.a=0;_.c=0;var hbb=mdb(kxe,'RegEx/Token/ModifierToken',1823);bcb(822,117,yxe,Dge);_.am=function Ege(a){return this.a};_.em=function Fge(){return 1};_.fm=function Gge(a){var b;b=null;switch(this.e){case 6:this.b==0?(b='(?:'+this.a.fm(a)+')'):(b='('+this.a.fm(a)+')');break;case 20:b='(?='+this.a.fm(a)+')';break;case 21:b='(?!'+this.a.fm(a)+')';break;case 22:b='(?<='+this.a.fm(a)+')';break;case 23:b='(?<!'+this.a.fm(a)+')';break;case 24:b='(?>'+this.a.fm(a)+')';}return b};_.b=0;var ibb=mdb(kxe,'RegEx/Token/ParenToken',822);bcb(521,117,{3:1,117:1,521:1},Hge);_.bm=function Ige(){return this.b};_.fm=function Jge(a){return this.e==12?'\\'+this.a:Wee(this.b)};_.a=0;var jbb=mdb(kxe,'RegEx/Token/StringToken',521);bcb(465,117,yxe,Lge);_.$l=function Mge(a){Kge(this,a)};_.am=function Nge(a){return BD(Uvb(this.a,a),117)};_.em=function Oge(){return !this.a?0:this.a.a.c.length};_.fm=function Pge(a){var b,c,d,e,f;if(this.e==1){if(this.a.a.c.length==2){b=BD(Uvb(this.a,0),117);c=BD(Uvb(this.a,1),117);c.e==3&&c.am(0)==b?(e=b.fm(a)+'+'):c.e==9&&c.am(0)==b?(e=b.fm(a)+'+?'):(e=b.fm(a)+(''+c.fm(a)))}else{f=new Hfb;for(d=0;d<this.a.a.c.length;d++){Efb(f,BD(Uvb(this.a,d),117).fm(a))}e=f.a}return e}if(this.a.a.c.length==2&&BD(Uvb(this.a,1),117).e==7){e=BD(Uvb(this.a,0),117).fm(a)+'?'}else if(this.a.a.c.length==2&&BD(Uvb(this.a,0),117).e==7){e=BD(Uvb(this.a,1),117).fm(a)+'??'}else{f=new Hfb;Efb(f,BD(Uvb(this.a,0),117).fm(a));for(d=1;d<this.a.a.c.length;d++){f.a+='|';Efb(f,BD(Uvb(this.a,d),117).fm(a))}e=f.a}return e};var kbb=mdb(kxe,'RegEx/Token/UnionToken',465);bcb(518,1,{592:1},Rge);_.Ib=function Sge(){return this.a.b};var mbb=mdb(zxe,'XMLTypeUtil/PatternMatcherImpl',518);bcb(1622,1381,{},Vge);var Tge;var nbb=mdb(zxe,'XMLTypeValidator',1622);bcb(264,1,vie,Yge);_.Jc=function Zge(a){reb(this,a)};_.Kc=function $ge(){return (this.b-this.a)*this.c<0?Wge:new she(this)};_.a=0;_.b=0;_.c=0;var Wge;var qbb=mdb(Bxe,'ExclusiveRange',264);bcb(1068,1,jie,dhe);_.Rb=function ehe(a){BD(a,19);_ge()};_.Nb=function fhe(a){Rrb(this,a)};_.Pb=function ihe(){return ahe()};_.Ub=function khe(){return bhe()};_.Wb=function nhe(a){BD(a,19);che()};_.Ob=function ghe(){return false};_.Sb=function hhe(){return false};_.Tb=function jhe(){return -1};_.Vb=function lhe(){return -1};_.Qb=function mhe(){throw vbb(new cgb(Exe))};var obb=mdb(Bxe,'ExclusiveRange/1',1068);bcb(254,1,jie,she);_.Rb=function the(a){BD(a,19);ohe()};_.Nb=function uhe(a){Rrb(this,a)};_.Pb=function xhe(){return phe(this)};_.Ub=function zhe(){return qhe(this)};_.Wb=function Che(a){BD(a,19);rhe()};_.Ob=function vhe(){return this.c.c<0?this.a>=this.c.b:this.a<=this.c.b};_.Sb=function whe(){return this.b>0};_.Tb=function yhe(){return this.b};_.Vb=function Ahe(){return this.b-1};_.Qb=function Bhe(){throw vbb(new cgb(Exe))};_.a=0;_.b=0;var pbb=mdb(Bxe,'ExclusiveRange/RangeIterator',254);var TD=pdb(Fve,'C');var WD=pdb(Ive,'I');var sbb=pdb(Khe,'Z');var XD=pdb(Jve,'J');var SD=pdb(Eve,'B');var UD=pdb(Gve,'D');var VD=pdb(Hve,'F');var rbb=pdb(Kve,'S');var h1=odb('org.eclipse.elk.core.labels','ILabelManager');var O4=odb(Tte,'DiagnosticChain');var u8=odb(pwe,'ResourceSet');var V4=mdb(Tte,'InvocationTargetException',null);var Ihe=(Az(),Dz);var gwtOnLoad=gwtOnLoad=Zbb;Xbb(hcb);$bb('permProps',[[[Fxe,Gxe],[Hxe,'gecko1_8']],[[Fxe,Gxe],[Hxe,'ie10']],[[Fxe,Gxe],[Hxe,'ie8']],[[Fxe,Gxe],[Hxe,'ie9']],[[Fxe,Gxe],[Hxe,'safari']]]); +// -------------- RUN GWT INITIALIZATION CODE -------------- +gwtOnLoad(null, 'elk', null); + +}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],3:[function(require,module,exports){ +'use strict'; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +/******************************************************************************* + * Copyright (c) 2021 Kiel University and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +var ELK = require('./elk-api.js').default; + +var ELKNode = function (_ELK) { + _inherits(ELKNode, _ELK); + + function ELKNode() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + _classCallCheck(this, ELKNode); + + var optionsClone = Object.assign({}, options); + + var workerThreadsExist = false; + try { + require.resolve('web-worker'); + workerThreadsExist = true; + } catch (e) {} + + // user requested a worker + if (options.workerUrl) { + if (workerThreadsExist) { + var Worker = require('web-worker'); + optionsClone.workerFactory = function (url) { + return new Worker(url); + }; + } else { + console.warn('Web worker requested but \'web-worker\' package not installed. \nConsider installing the package or pass your own \'workerFactory\' to ELK\'s constructor.\n... Falling back to non-web worker version.'); + } + } + + // unless no other workerFactory is registered, use the fake worker + if (!optionsClone.workerFactory) { + var _require = require('./elk-worker.min.js'), + _Worker = _require.Worker; + + optionsClone.workerFactory = function (url) { + return new _Worker(url); + }; + } + + return _possibleConstructorReturn(this, (ELKNode.__proto__ || Object.getPrototypeOf(ELKNode)).call(this, optionsClone)); + } + + return ELKNode; +}(ELK); + +Object.defineProperty(module.exports, "__esModule", { + value: true +}); +module.exports = ELKNode; +ELKNode.default = ELKNode; +},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(require,module,exports){ +/** + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = Worker; +},{}]},{},[3])(3) +}); + + +/***/ }), + +/***/ 64589: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array<unknown>} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array<string>} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array<Extension>} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record<string, unknown>} */ + const left = maybe || (all[hook] = {}) + /** @type {Record<string, unknown> | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array<unknown>} existing + * @param {Array<unknown>} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array<unknown>} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array<HtmlExtension>} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array<StackItem>} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function micromark_util_chunked_splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function micromark_util_chunked_push(list, items) { + if (list.length > 0) { + micromark_util_chunked_splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array<Event>} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record<string, number>} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array<Event>} */ + let parameters + /** @type {Array<Event>} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + micromark_util_chunked_splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array<Event>} events + * @param {number} eventIndex + * @returns {Record<string, number>} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array<number>} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record<string, number>} */ + const gaps = {} + /** @type {Array<Chunk>} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + micromark_util_chunked_splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array<Event>} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array<Event>} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array<Resolver>} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit<Point, '_bufferIndex' | '_index'> | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record<string, number>} */ + const columnStart = {} + /** @type {Array<Construct>} */ + const resolveAllConstructs = [] + /** @type {Array<Chunk>} */ + let chunks = [] + /** @type {Array<Token>} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array<Construct> | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array<Construct>} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array<Construct>} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array<Chunk>} chunks + * @param {Pick<Token, 'end' | 'start'>} token + * @returns {Array<Chunk>} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array<Chunk>} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array<Chunk>} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array<string>} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * <a> + * <a\>b> + * <a b> + * <a)> + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`<a>` or `b`). + * @param {TokenType} literalType + * Type when enclosed (`<a>`). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | <aa> + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | <a\*a> + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | <x /> + * ^ + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<!-`, inside a comment, at another `-`. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<![`, inside CDATA, expecting `CDATA[`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | </x> + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | <ab> + * ^^ + * > | </ab> + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > | <div/> + * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | <x/> + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | <a /> + * ^ + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * > | <a > + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | <a b> + * ^ + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | <a b=c> + * ^ + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | <a b="c"> + * ^ + * > | <a b='c'> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | <x> + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | <x> + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after `</`, in a raw tag name. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | <!--> + * ^ + * > | <?> + * ^ + * > | <!q> + * ^ + * > | <!--ab--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > | <div> + * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record<string, string>} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array<Event>} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + * <p>!<a href=\"b\">^a</a></p> + * <p>!<a href=\"c\">^a</a></p> + * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array<Event>} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | a<user.name@ex-ample.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code> | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a <b> c + * ^ + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * > | a <![CDATA[>&<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after `<!-`, at another `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After `<![`, in CDATA, expecting `CDATA[`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a <!b> c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After `</x`, in a tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After `<x`, in opening tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a <!--a + * ^ + * | b--> + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array<Chunk>} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array<Chunk>} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array<Event>} events + * @returns {Array<Event>} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract<Node, UnistParent>} Parent + * + * @typedef {Omit<UnistParent, 'type' | 'children'> & {type: 'fragment', children: Array<PhrasingContent>}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record<string, Handle>} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array<string>} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array<Transform>} transforms + * Tree transforms. + * + * @typedef {Partial<Config>} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array<Node | Fragment>} stack + * Stack of nodes. + * @property {Array<TokenTuple>} tokenStack + * Stack of tokens. + * @property {<Key extends keyof CompileData>(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {<Key extends keyof CompileData>(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {<Kind extends Node>(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array<Extension | Array<Extension>> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array<Event>} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit<CompileContext, 'sliceSerialize'>} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array<number>} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array<Event>} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array<StaticPhrasingContent>} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array<Extension | Array<Extension>>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(18464); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-62fc7601.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.Z)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "<br/>"); + } else if (node.type === "strong") { + return `<strong>${node.children.map(output).join("")}</strong>`; + } else if (node.type === "emphasis") { + return `<em>${node.children.map(output).join("")}</em>`; + } else if (node.type === "paragraph") { + return `<p>${node.children.map(output).join("")}</p>`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + <span class="${labelClass} ${classes}" ` + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_8af3addd.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_8af3addd.J)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 27707: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ a: () => (/* binding */ insertMarkers$1), +/* harmony export */ b: () => (/* binding */ clear$1), +/* harmony export */ c: () => (/* binding */ createLabel$1), +/* harmony export */ d: () => (/* binding */ clear), +/* harmony export */ e: () => (/* binding */ insertNode), +/* harmony export */ f: () => (/* binding */ insertEdgeLabel), +/* harmony export */ g: () => (/* binding */ insertEdge), +/* harmony export */ h: () => (/* binding */ positionEdgeLabel), +/* harmony export */ i: () => (/* binding */ intersectRect$1), +/* harmony export */ j: () => (/* binding */ getLineFunctionsWithOffset), +/* harmony export */ l: () => (/* binding */ labelHelper), +/* harmony export */ p: () => (/* binding */ positionNode), +/* harmony export */ s: () => (/* binding */ setNodeElem), +/* harmony export */ u: () => (/* binding */ updateNodeBounds) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(64589); + + + +const insertMarkers = (elem, markerArray, type, id) => { + markerArray.forEach((markerName) => { + markers[markerName](elem, type, id); + }); +}; +const extension = (elem, type, id) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Making markers for ", id); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionStart").attr("class", "marker extension " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 1,7 L18,13 V 1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-extensionEnd").attr("class", "marker extension " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 1,1 V 13 L18,7 Z"); +}; +const composition = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionStart").attr("class", "marker composition " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-compositionEnd").attr("class", "marker composition " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const aggregation = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationStart").attr("class", "marker aggregation " + type).attr("refX", 18).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-aggregationEnd").attr("class", "marker aggregation " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L1,7 L9,1 Z"); +}; +const dependency = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyStart").attr("class", "marker dependency " + type).attr("refX", 6).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("path").attr("d", "M 5,7 L9,13 L1,7 L9,1 Z"); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-dependencyEnd").attr("class", "marker dependency " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 18,7 L9,13 L14,7 L9,1 Z"); +}; +const lollipop = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopStart").attr("class", "marker lollipop " + type).attr("refX", 13).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); + elem.append("defs").append("marker").attr("id", id + "_" + type + "-lollipopEnd").attr("class", "marker lollipop " + type).attr("refX", 1).attr("refY", 7).attr("markerWidth", 190).attr("markerHeight", 240).attr("orient", "auto").append("circle").attr("stroke", "black").attr("fill", "transparent").attr("cx", 7).attr("cy", 7).attr("r", 6); +}; +const point = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-pointEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 6).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 0 L 10 5 L 0 10 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-pointStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 4.5).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 12).attr("markerHeight", 12).attr("orient", "auto").append("path").attr("d", "M 0 5 L 10 10 L 10 0 z").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const circle$1 = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-circleEnd").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", 11).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-circleStart").attr("class", "marker " + type).attr("viewBox", "0 0 10 10").attr("refX", -1).attr("refY", 5).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("circle").attr("cx", "5").attr("cy", "5").attr("r", "5").attr("class", "arrowMarkerPath").style("stroke-width", 1).style("stroke-dasharray", "1,0"); +}; +const cross = (elem, type, id) => { + elem.append("marker").attr("id", id + "_" + type + "-crossEnd").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", 12).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); + elem.append("marker").attr("id", id + "_" + type + "-crossStart").attr("class", "marker cross " + type).attr("viewBox", "0 0 11 11").attr("refX", -1).attr("refY", 5.2).attr("markerUnits", "userSpaceOnUse").attr("markerWidth", 11).attr("markerHeight", 11).attr("orient", "auto").append("path").attr("d", "M 1,1 l 9,9 M 10,1 l -9,9").attr("class", "arrowMarkerPath").style("stroke-width", 2).style("stroke-dasharray", "1,0"); +}; +const barb = (elem, type, id) => { + elem.append("defs").append("marker").attr("id", id + "_" + type + "-barbEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 14).attr("markerUnits", "strokeWidth").attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const markers = { + extension, + composition, + aggregation, + dependency, + lollipop, + point, + circle: circle$1, + cross, + barb +}; +const insertMarkers$1 = insertMarkers; +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlLabel(node) { + const fo = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(document.createElementNS("http://www.w3.org/2000/svg", "foreignObject")); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + '<span class="' + labelClass + '" ' + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "inline-block"); + div.style("white-space", "nowrap"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + return fo.node(); +} +const createLabel = (_vertexText, style, isTitle, isNode) => { + let vertexText = _vertexText || ""; + if (typeof vertexText === "object") { + vertexText = vertexText[0]; + } + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + vertexText = vertexText.replace(/\\n|\n/g, "<br />"); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("vertexText" + vertexText); + const node = { + isNode, + label: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(vertexText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + let vertexNode = addHtmlLabel(node); + return vertexNode; + } else { + const svgLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("style", style.replace("color:", "fill:")); + let rows = []; + if (typeof vertexText === "string") { + rows = vertexText.split(/\\n|\n|<br\s*\/?>/gi); + } else if (Array.isArray(vertexText)) { + rows = vertexText; + } else { + rows = []; + } + for (const row of rows) { + const tspan = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:space", "preserve"); + tspan.setAttribute("dy", "1em"); + tspan.setAttribute("x", "0"); + if (isTitle) { + tspan.setAttribute("class", "title-row"); + } else { + tspan.setAttribute("class", "row"); + } + tspan.textContent = row.trim(); + svgLabel.appendChild(tspan); + } + return svgLabel; + } +}; +const createLabel$1 = createLabel; +const labelHelper = async (parent, node, _classes, isNode) => { + let classes; + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + if (!_classes) { + classes = "node default"; + } else { + classes = _classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const label = shapeSvg.insert("g").attr("class", "label").attr("style", node.labelStyle); + let labelText; + if (node.labelText === void 0) { + labelText = ""; + } else { + labelText = typeof node.labelText === "string" ? node.labelText : node.labelText[0]; + } + const textNode = label.node(); + let text; + if (node.labelType === "markdown") { + text = (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(label, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), { + useHtmlLabels, + width: node.width || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.wrappingWidth, + classes: "markdown-node-label" + }); + } else { + text = textNode.appendChild( + createLabel$1( + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.d)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.J)(labelText), (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)()), + node.labelStyle, + false, + isNode + ) + ); + } + let bbox = text.getBBox(); + const halfPadding = node.padding / 2; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + const images = div.getElementsByTagName("img"); + if (images) { + const noImgText = labelText.replace(/<img[^>]*>/g, "").trim() === ""; + await Promise.all( + [...images].map( + (img) => new Promise((res) => { + function setupImage() { + img.style.display = "flex"; + img.style.flexDirection = "column"; + if (noImgText) { + const bodyFontSize = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize ? (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().fontSize : window.getComputedStyle(document.body).fontSize; + const enlargingFactor = 5; + img.style.width = parseInt(bodyFontSize, 10) * enlargingFactor + "px"; + } else { + img.style.width = "100%"; + } + res(img); + } + setTimeout(() => { + if (img.complete) { + setupImage(); + } + }); + img.addEventListener("error", setupImage); + img.addEventListener("load", setupImage); + }) + ) + ); + } + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (useHtmlLabels) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } else { + label.attr("transform", "translate(0, " + -bbox.height / 2 + ")"); + } + if (node.centerLabel) { + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + } + label.insert("rect", ":first-child"); + return { shapeSvg, bbox, halfPadding, label }; +}; +const updateNodeBounds = (node, element) => { + const bbox = element.node().getBBox(); + node.width = bbox.width; + node.height = bbox.height; +}; +function insertPolygonShape(parent, w, h, points) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("class", "label-container").attr("transform", "translate(" + -w / 2 + "," + h / 2 + ")"); +} +function intersectNode(node, point2) { + return node.intersect(point2); +} +function intersectEllipse(node, rx, ry, point2) { + var cx = node.x; + var cy = node.y; + var px = cx - point2.x; + var py = cy - point2.y; + var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); + var dx = Math.abs(rx * ry * px / det); + if (point2.x < cx) { + dx = -dx; + } + var dy = Math.abs(rx * ry * py / det); + if (point2.y < cy) { + dy = -dy; + } + return { x: cx + dx, y: cy + dy }; +} +function intersectCircle(node, rx, point2) { + return intersectEllipse(node, rx, rx, point2); +} +function intersectLine(p1, p2, q1, q2) { + var a1, a2, b1, b2, c1, c2; + var r1, r2, r3, r4; + var denom, offset, num; + var x, y; + a1 = p2.y - p1.y; + b1 = p1.x - p2.x; + c1 = p2.x * p1.y - p1.x * p2.y; + r3 = a1 * q1.x + b1 * q1.y + c1; + r4 = a1 * q2.x + b1 * q2.y + c1; + if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) { + return; + } + a2 = q2.y - q1.y; + b2 = q1.x - q2.x; + c2 = q2.x * q1.y - q1.x * q2.y; + r1 = a2 * p1.x + b2 * p1.y + c2; + r2 = a2 * p2.x + b2 * p2.y + c2; + if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) { + return; + } + denom = a1 * b2 - a2 * b1; + if (denom === 0) { + return; + } + offset = Math.abs(denom / 2); + num = b1 * c2 - b2 * c1; + x = num < 0 ? (num - offset) / denom : (num + offset) / denom; + num = a2 * c1 - a1 * c2; + y = num < 0 ? (num - offset) / denom : (num + offset) / denom; + return { x, y }; +} +function sameSign(r1, r2) { + return r1 * r2 > 0; +} +function intersectPolygon(node, polyPoints, point2) { + var x1 = node.x; + var y1 = node.y; + var intersections = []; + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + if (typeof polyPoints.forEach === "function") { + polyPoints.forEach(function(entry) { + minX = Math.min(minX, entry.x); + minY = Math.min(minY, entry.y); + }); + } else { + minX = Math.min(minX, polyPoints.x); + minY = Math.min(minY, polyPoints.y); + } + var left = x1 - node.width / 2 - minX; + var top = y1 - node.height / 2 - minY; + for (var i = 0; i < polyPoints.length; i++) { + var p1 = polyPoints[i]; + var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0]; + var intersect2 = intersectLine( + node, + point2, + { x: left + p1.x, y: top + p1.y }, + { x: left + p2.x, y: top + p2.y } + ); + if (intersect2) { + intersections.push(intersect2); + } + } + if (!intersections.length) { + return node; + } + if (intersections.length > 1) { + intersections.sort(function(p, q) { + var pdx = p.x - point2.x; + var pdy = p.y - point2.y; + var distp = Math.sqrt(pdx * pdx + pdy * pdy); + var qdx = q.x - point2.x; + var qdy = q.y - point2.y; + var distq = Math.sqrt(qdx * qdx + qdy * qdy); + return distp < distq ? -1 : distp === distq ? 0 : 1; + }); + } + return intersections[0]; +} +const intersectRect = (node, point2) => { + var x = node.x; + var y = node.y; + var dx = point2.x - x; + var dy = point2.y - y; + var w = node.width / 2; + var h = node.height / 2; + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + if (dy < 0) { + h = -h; + } + sx = dy === 0 ? 0 : h * dx / dy; + sy = h; + } else { + if (dx < 0) { + w = -w; + } + sx = w; + sy = dx === 0 ? 0 : w * dy / dx; + } + return { x: x + sx, y: y + sy }; +}; +const intersectRect$1 = intersectRect; +const intersect = { + node: intersectNode, + circle: intersectCircle, + ellipse: intersectEllipse, + polygon: intersectPolygon, + rect: intersectRect$1 +}; +const note = async (parent, node) => { + const useHtmlLabels = node.useHtmlLabels || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels; + if (!useHtmlLabels) { + node.centerLabel = true; + } + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes, + true + ); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Classes = ", node.classes); + const rect2 = shapeSvg.insert("rect", ":first-child"); + rect2.attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const note$1 = note; +const formatClass = (str) => { + if (str) { + return " " + str; + } + return ""; +}; +const getClassesFromNode = (node, otherClasses) => { + return `${otherClasses ? otherClasses : "node default"}${formatClass(node.classes)} ${formatClass( + node.class + )}`; +}; +const question = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const s = w + h; + const points = [ + { x: s / 2, y: 0 }, + { x: s, y: -s / 2 }, + { x: s / 2, y: -s }, + { x: 0, y: -s / 2 } + ]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Question main (Circle)"); + const questionElem = insertPolygonShape(shapeSvg, s, s, points); + questionElem.attr("style", node.style); + updateNodeBounds(node, questionElem); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("Intersect called"); + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const choice = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const s = 28; + const points = [ + { x: 0, y: s / 2 }, + { x: s / 2, y: 0 }, + { x: 0, y: -s / 2 }, + { x: -s / 2, y: 0 } + ]; + const choice2 = shapeSvg.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ); + choice2.attr("class", "state-start").attr("r", 7).attr("width", 28).attr("height", 28); + node.width = 28; + node.height = 28; + node.intersect = function(point2) { + return intersect.circle(node, 14, point2); + }; + return shapeSvg; +}; +const hexagon = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const f = 4; + const h = bbox.height + node.padding; + const m = h / f; + const w = bbox.width + 2 * m + node.padding; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + const hex = insertPolygonShape(shapeSvg, w, h, points); + hex.attr("style", node.style); + updateNodeBounds(node, hex); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_left_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -h / 2, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: -h / 2, y: -h }, + { x: 0, y: -h / 2 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + node.width = w + h; + node.height = h; + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_right = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const lean_left = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 2 * h / 6, y: 0 }, + { x: w + h / 6, y: 0 }, + { x: w - 2 * h / 6, y: -h }, + { x: -h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: -2 * h / 6, y: 0 }, + { x: w + 2 * h / 6, y: 0 }, + { x: w - h / 6, y: -h }, + { x: h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const inv_trapezoid = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: h / 6, y: 0 }, + { x: w - h / 6, y: 0 }, + { x: w + 2 * h / 6, y: -h }, + { x: -2 * h / 6, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const rect_right_inv_arrow = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w + h / 2, y: 0 }, + { x: w, y: -h / 2 }, + { x: w + h / 2, y: -h }, + { x: 0, y: -h } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const cylinder = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const rx = w / 2; + const ry = rx / (2.5 + w / 50); + const h = bbox.height + ry + node.padding; + const shape = "M 0," + ry + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 a " + rx + "," + ry + " 0,0,0 " + -w + " 0 l 0," + h + " a " + rx + "," + ry + " 0,0,0 " + w + " 0 l 0," + -h; + const el = shapeSvg.attr("label-offset-y", ry).insert("path", ":first-child").attr("style", node.style).attr("d", shape).attr("transform", "translate(" + -w / 2 + "," + -(h / 2 + ry) + ")"); + updateNodeBounds(node, el); + node.intersect = function(point2) { + const pos = intersect.rect(node, point2); + const x = pos.x - node.x; + if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) { + let y = ry * ry * (1 - x * x / (rx * rx)); + if (y != 0) { + y = Math.sqrt(y); + } + y = ry - y; + if (point2.y - node.y > 0) { + y = -y; + } + pos.y += y; + } + return pos; + }; + return shapeSvg; +}; +const rect = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + "node " + node.classes + " " + node.class, + true + ); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = bbox.width + node.padding; + const totalHeight = bbox.height + node.padding; + rect2.attr("class", "basic label-container").attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", totalWidth).attr("height", totalHeight); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const labelRect = async (parent, node) => { + const { shapeSvg } = await labelHelper(parent, node, "label", true); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace("Classes = ", node.class); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const totalWidth = 0; + const totalHeight = 0; + rect2.attr("width", totalWidth).attr("height", totalHeight); + shapeSvg.attr("class", "label edgeLabel"); + if (node.props) { + const propKeys = new Set(Object.keys(node.props)); + if (node.props.borders) { + applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight); + propKeys.delete("borders"); + } + propKeys.forEach((propKey) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`Unknown node property ${propKey}`); + }); + } + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +function applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) { + const strokeDashArray = []; + const addBorder = (length) => { + strokeDashArray.push(length, 0); + }; + const skipBorder = (length) => { + strokeDashArray.push(0, length); + }; + if (borders.includes("t")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add top border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("r")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add right border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + if (borders.includes("b")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add bottom border"); + addBorder(totalWidth); + } else { + skipBorder(totalWidth); + } + if (borders.includes("l")) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.debug("add left border"); + addBorder(totalHeight); + } else { + skipBorder(totalHeight); + } + rect2.attr("stroke-dasharray", strokeDashArray.join(" ")); +} +const rectWithTitle = (parent, node) => { + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const innerLine = shapeSvg.insert("line"); + const label = shapeSvg.insert("g").attr("class", "label"); + const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText; + let title = ""; + if (typeof text2 === "object") { + title = text2[0]; + } else { + title = text2; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Label text abc79", title, text2, typeof text2 === "object"); + const text = label.node().appendChild(createLabel$1(title, node.labelStyle, true, true)); + let bbox = { width: 0, height: 0 }; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = text.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Text 2", text2); + const textRows = text2.slice(1, text2.length); + let titleBox = text.getBBox(); + const descr = label.node().appendChild( + createLabel$1(textRows.join ? textRows.join("<br/>") : textRows, node.labelStyle, true, true) + ); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = descr.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + const halfPadding = node.padding / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(descr).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + ", " + (titleBox.height + halfPadding + 5) + ")" + ); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(text).attr( + "transform", + "translate( " + // (titleBox.width - bbox.width) / 2 + + (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + ", 0)" + ); + bbox = label.node().getBBox(); + label.attr( + "transform", + "translate(" + -bbox.width / 2 + ", " + (-bbox.height / 2 - halfPadding + 3) + ")" + ); + rect2.attr("class", "outer title-state").attr("x", -bbox.width / 2 - halfPadding).attr("y", -bbox.height / 2 - halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + innerLine.attr("class", "divider").attr("x1", -bbox.width / 2 - halfPadding).attr("x2", bbox.width / 2 + halfPadding).attr("y1", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr("y2", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const stadium = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const h = bbox.height + node.padding; + const w = bbox.width + h / 4 + node.padding; + const rect2 = shapeSvg.insert("rect", ":first-child").attr("style", node.style).attr("rx", h / 2).attr("ry", h / 2).attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const circle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle main"); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Circle intersect", node, bbox.width / 2 + halfPadding, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding, point2); + }; + return shapeSvg; +}; +const doublecircle = async (parent, node) => { + const { shapeSvg, bbox, halfPadding } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const gap = 5; + const circleGroup = shapeSvg.insert("g", ":first-child"); + const outerCircle = circleGroup.insert("circle"); + const innerCircle = circleGroup.insert("circle"); + circleGroup.attr("class", node.class); + outerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding + gap).attr("width", bbox.width + node.padding + gap * 2).attr("height", bbox.height + node.padding + gap * 2); + innerCircle.attr("style", node.style).attr("rx", node.rx).attr("ry", node.ry).attr("r", bbox.width / 2 + halfPadding).attr("width", bbox.width + node.padding).attr("height", bbox.height + node.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle main"); + updateNodeBounds(node, outerCircle); + node.intersect = function(point2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("DoubleCircle intersect", node, bbox.width / 2 + halfPadding + gap, point2); + return intersect.circle(node, bbox.width / 2 + halfPadding + gap, point2); + }; + return shapeSvg; +}; +const subroutine = async (parent, node) => { + const { shapeSvg, bbox } = await labelHelper( + parent, + node, + getClassesFromNode(node, void 0), + true + ); + const w = bbox.width + node.padding; + const h = bbox.height + node.padding; + const points = [ + { x: 0, y: 0 }, + { x: w, y: 0 }, + { x: w, y: -h }, + { x: 0, y: -h }, + { x: 0, y: 0 }, + { x: -8, y: 0 }, + { x: w + 8, y: 0 }, + { x: w + 8, y: -h }, + { x: -8, y: -h }, + { x: -8, y: 0 } + ]; + const el = insertPolygonShape(shapeSvg, w, h, points); + el.attr("style", node.style); + updateNodeBounds(node, el); + node.intersect = function(point2) { + return intersect.polygon(node, points, point2); + }; + return shapeSvg; +}; +const start = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const forkJoin = (parent, node, dir) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + let width = 70; + let height = 10; + if (dir === "LR") { + width = 10; + height = 70; + } + const shape = shapeSvg.append("rect").attr("x", -1 * width / 2).attr("y", -1 * height / 2).attr("width", width).attr("height", height).attr("class", "fork-join"); + updateNodeBounds(node, shape); + node.height = node.height + node.padding / 2; + node.width = node.width + node.padding / 2; + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const end = (parent, node) => { + const shapeSvg = parent.insert("g").attr("class", "node default").attr("id", node.domId || node.id); + const innerCircle = shapeSvg.insert("circle", ":first-child"); + const circle2 = shapeSvg.insert("circle", ":first-child"); + circle2.attr("class", "state-start").attr("r", 7).attr("width", 14).attr("height", 14); + innerCircle.attr("class", "state-end").attr("r", 5).attr("width", 10).attr("height", 10); + updateNodeBounds(node, circle2); + node.intersect = function(point2) { + return intersect.circle(node, 7, point2); + }; + return shapeSvg; +}; +const class_box = (parent, node) => { + const halfPadding = node.padding / 2; + const rowPadding = 4; + const lineHeight = 8; + let classes; + if (!node.classes) { + classes = "node default"; + } else { + classes = "node " + node.classes; + } + const shapeSvg = parent.insert("g").attr("class", classes).attr("id", node.domId || node.id); + const rect2 = shapeSvg.insert("rect", ":first-child"); + const topLine = shapeSvg.insert("line"); + const bottomLine = shapeSvg.insert("line"); + let maxWidth = 0; + let maxHeight = rowPadding; + const labelContainer = shapeSvg.insert("g").attr("class", "label"); + let verticalPos = 0; + const hasInterface = node.classData.annotations && node.classData.annotations[0]; + const interfaceLabelText = node.classData.annotations[0] ? "«" + node.classData.annotations[0] + "»" : ""; + const interfaceLabel = labelContainer.node().appendChild(createLabel$1(interfaceLabelText, node.labelStyle, true, true)); + let interfaceBBox = interfaceLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = interfaceLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel); + interfaceBBox = div.getBoundingClientRect(); + dv.attr("width", interfaceBBox.width); + dv.attr("height", interfaceBBox.height); + } + if (node.classData.annotations[0]) { + maxHeight += interfaceBBox.height + rowPadding; + maxWidth += interfaceBBox.width; + } + let classTitleString = node.classData.label; + if (node.classData.type !== void 0 && node.classData.type !== "") { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + classTitleString += "<" + node.classData.type + ">"; + } else { + classTitleString += "<" + node.classData.type + ">"; + } + } + const classTitleLabel = labelContainer.node().appendChild(createLabel$1(classTitleString, node.labelStyle, true, true)); + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr("class", "classTitle"); + let classTitleBBox = classTitleLabel.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = classTitleLabel.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel); + classTitleBBox = div.getBoundingClientRect(); + dv.attr("width", classTitleBBox.width); + dv.attr("height", classTitleBBox.height); + } + maxHeight += classTitleBBox.height + rowPadding; + if (classTitleBBox.width > maxWidth) { + maxWidth = classTitleBBox.width; + } + const classAttributes = []; + node.classData.members.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let parsedText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + parsedText = parsedText.replace(/</g, "<").replace(/>/g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + parsedText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classAttributes.push(lbl); + }); + maxHeight += lineHeight; + const classMethods = []; + node.classData.methods.forEach((member) => { + const parsedInfo = member.getDisplayDetails(); + let displayText = parsedInfo.displayText; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels) { + displayText = displayText.replace(/</g, "<").replace(/>/g, ">"); + } + const lbl = labelContainer.node().appendChild( + createLabel$1( + displayText, + parsedInfo.cssStyle ? parsedInfo.cssStyle : node.labelStyle, + true, + true + ) + ); + let bbox = lbl.getBBox(); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels)) { + const div = lbl.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + if (bbox.width > maxWidth) { + maxWidth = bbox.width; + } + maxHeight += bbox.height + rowPadding; + classMethods.push(lbl); + }); + maxHeight += lineHeight; + if (hasInterface) { + let diffX2 = (maxWidth - interfaceBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(interfaceLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX2) + ", " + -1 * maxHeight / 2 + ")" + ); + verticalPos = interfaceBBox.height + rowPadding; + } + let diffX = (maxWidth - classTitleBBox.width) / 2; + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(classTitleLabel).attr( + "transform", + "translate( " + (-1 * maxWidth / 2 + diffX) + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + verticalPos += classTitleBBox.height + rowPadding; + topLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classAttributes.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos + lineHeight / 2) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + verticalPos += lineHeight; + bottomLine.attr("class", "divider").attr("x1", -maxWidth / 2 - halfPadding).attr("x2", maxWidth / 2 + halfPadding).attr("y1", -maxHeight / 2 - halfPadding + lineHeight + verticalPos).attr("y2", -maxHeight / 2 - halfPadding + lineHeight + verticalPos); + verticalPos += lineHeight; + classMethods.forEach((lbl) => { + (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(lbl).attr( + "transform", + "translate( " + -maxWidth / 2 + ", " + (-1 * maxHeight / 2 + verticalPos) + ")" + ); + const memberBBox = lbl == null ? void 0 : lbl.getBBox(); + verticalPos += ((memberBBox == null ? void 0 : memberBBox.height) ?? 0) + rowPadding; + }); + rect2.attr("class", "outer title-state").attr("x", -maxWidth / 2 - halfPadding).attr("y", -(maxHeight / 2) - halfPadding).attr("width", maxWidth + node.padding).attr("height", maxHeight + node.padding); + updateNodeBounds(node, rect2); + node.intersect = function(point2) { + return intersect.rect(node, point2); + }; + return shapeSvg; +}; +const shapes = { + rhombus: question, + question, + rect, + labelRect, + rectWithTitle, + choice, + circle, + doublecircle, + stadium, + hexagon, + rect_left_inv_arrow, + lean_right, + lean_left, + trapezoid, + inv_trapezoid, + rect_right_inv_arrow, + cylinder, + start, + end, + note: note$1, + subroutine, + fork: forkJoin, + join: forkJoin, + class_box +}; +let nodeElems = {}; +const insertNode = async (elem, node, dir) => { + let newEl; + let el; + if (node.link) { + let target; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel === "sandbox") { + target = "_top"; + } else if (node.linkTarget) { + target = node.linkTarget || "_blank"; + } + newEl = elem.insert("svg:a").attr("xlink:href", node.link).attr("target", target); + el = await shapes[node.shape](newEl, node, dir); + } else { + el = await shapes[node.shape](elem, node, dir); + newEl = el; + } + if (node.tooltip) { + el.attr("title", node.tooltip); + } + if (node.class) { + el.attr("class", "node default " + node.class); + } + nodeElems[node.id] = newEl; + if (node.haveCallback) { + nodeElems[node.id].attr("class", nodeElems[node.id].attr("class") + " clickable"); + } + return newEl; +}; +const setNodeElem = (elem, node) => { + nodeElems[node.id] = elem; +}; +const clear$1 = () => { + nodeElems = {}; +}; +const positionNode = (node) => { + const el = nodeElems[node.id]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.trace( + "Transforming node", + node.diff, + node, + "translate(" + (node.x - node.width / 2 - 5) + ", " + node.width / 2 + ")" + ); + const padding = 8; + const diff = node.diff || 0; + if (node.clusterNode) { + el.attr( + "transform", + "translate(" + (node.x + diff - node.width / 2) + ", " + (node.y - node.height / 2 - padding) + ")" + ); + } else { + el.attr("transform", "translate(" + node.x + ", " + node.y + ")"); + } + return diff; +}; +const markerOffsets = { + aggregation: 18, + extension: 18, + composition: 18, + dependency: 6, + lollipop: 13.5, + arrow_point: 5.3 +}; +function calculateDeltaAndAngle(point1, point2) { + point1 = pointTransformer(point1); + point2 = pointTransformer(point2); + const [x1, y1] = [point1.x, point1.y]; + const [x2, y2] = [point2.x, point2.y]; + const deltaX = x2 - x1; + const deltaY = y2 - y1; + return { angle: Math.atan(deltaY / deltaX), deltaX, deltaY }; +} +const pointTransformer = (data) => { + if (Array.isArray(data)) { + return { x: data[0], y: data[1] }; + } + return data; +}; +const getLineFunctionsWithOffset = (edge) => { + return { + x: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaX } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaX } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.cos(angle) * (deltaX >= 0 ? 1 : -1); + } + return pointTransformer(d).x + offset; + }, + y: function(d, i, data) { + let offset = 0; + if (i === 0 && Object.hasOwn(markerOffsets, edge.arrowTypeStart)) { + const { angle, deltaY } = calculateDeltaAndAngle(data[0], data[1]); + offset = markerOffsets[edge.arrowTypeStart] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } else if (i === data.length - 1 && Object.hasOwn(markerOffsets, edge.arrowTypeEnd)) { + const { angle, deltaY } = calculateDeltaAndAngle( + data[data.length - 1], + data[data.length - 2] + ); + offset = markerOffsets[edge.arrowTypeEnd] * Math.abs(Math.sin(angle)) * (deltaY >= 0 ? 1 : -1); + } + return pointTransformer(d).y + offset; + } + }; +}; +let edgeLabels = {}; +let terminalLabels = {}; +const clear = () => { + edgeLabels = {}; + terminalLabels = {}; +}; +const insertEdgeLabel = (elem, edge) => { + const useHtmlLabels = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.m)((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels); + const labelElement = edge.labelType === "markdown" ? (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_2__.a)(elem, edge.label, { + style: edge.labelStyle, + useHtmlLabels, + addSvgBackground: true + }) : createLabel$1(edge.label, edge.labelStyle); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc82", edge, edge.labelType); + const edgeLabel = elem.insert("g").attr("class", "edgeLabel"); + const label = edgeLabel.insert("g").attr("class", "label"); + label.node().appendChild(labelElement); + let bbox = labelElement.getBBox(); + if (useHtmlLabels) { + const div = labelElement.children[0]; + const dv = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(labelElement); + bbox = div.getBoundingClientRect(); + dv.attr("width", bbox.width); + dv.attr("height", bbox.height); + } + label.attr("transform", "translate(" + -bbox.width / 2 + ", " + -bbox.height / 2 + ")"); + edgeLabels[edge.id] = edgeLabel; + edge.width = bbox.width; + edge.height = bbox.height; + let fo; + if (edge.startLabelLeft) { + const startLabelElement = createLabel$1(edge.startLabelLeft, edge.labelStyle); + const startEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startLeft = startEdgeLabelLeft; + setTerminalWidth(fo, edge.startLabelLeft); + } + if (edge.startLabelRight) { + const startLabelElement = createLabel$1(edge.startLabelRight, edge.labelStyle); + const startEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = startEdgeLabelRight.insert("g").attr("class", "inner"); + fo = startEdgeLabelRight.node().appendChild(startLabelElement); + inner.node().appendChild(startLabelElement); + const slBox = startLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].startRight = startEdgeLabelRight; + setTerminalWidth(fo, edge.startLabelRight); + } + if (edge.endLabelLeft) { + const endLabelElement = createLabel$1(edge.endLabelLeft, edge.labelStyle); + const endEdgeLabelLeft = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelLeft.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelLeft.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endLeft = endEdgeLabelLeft; + setTerminalWidth(fo, edge.endLabelLeft); + } + if (edge.endLabelRight) { + const endLabelElement = createLabel$1(edge.endLabelRight, edge.labelStyle); + const endEdgeLabelRight = elem.insert("g").attr("class", "edgeTerminals"); + const inner = endEdgeLabelRight.insert("g").attr("class", "inner"); + fo = inner.node().appendChild(endLabelElement); + const slBox = endLabelElement.getBBox(); + inner.attr("transform", "translate(" + -slBox.width / 2 + ", " + -slBox.height / 2 + ")"); + endEdgeLabelRight.node().appendChild(endLabelElement); + if (!terminalLabels[edge.id]) { + terminalLabels[edge.id] = {}; + } + terminalLabels[edge.id].endRight = endEdgeLabelRight; + setTerminalWidth(fo, edge.endLabelRight); + } + return labelElement; +}; +function setTerminalWidth(fo, value) { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.htmlLabels && fo) { + fo.style.width = value.length * 9 + "px"; + fo.style.height = "12px"; + } +} +const positionEdgeLabel = (edge, paths) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Moving label abc78 ", edge.id, edge.label, edgeLabels[edge.id]); + let path = paths.updatedPath ? paths.updatedPath : paths.originalPath; + if (edge.label) { + const el = edgeLabels[edge.id]; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcLabelPosition(path); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Moving label " + edge.label + " from (", + x, + ",", + y, + ") to (", + pos.x, + ",", + pos.y, + ") abc78" + ); + if (paths.updatedPath) { + x = pos.x; + y = pos.y; + } + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelLeft) { + const el = terminalLabels[edge.id].startLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, "start_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.startLabelRight) { + const el = terminalLabels[edge.id].startRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition( + edge.arrowTypeStart ? 10 : 0, + "start_right", + path + ); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelLeft) { + const el = terminalLabels[edge.id].endLeft; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_left", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } + if (edge.endLabelRight) { + const el = terminalLabels[edge.id].endRight; + let x = edge.x; + let y = edge.y; + if (path) { + const pos = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, "end_right", path); + x = pos.x; + y = pos.y; + } + el.attr("transform", "translate(" + x + ", " + y + ")"); + } +}; +const outsideNode = (node, point2) => { + const x = node.x; + const y = node.y; + const dx = Math.abs(point2.x - x); + const dy = Math.abs(point2.y - y); + const w = node.width / 2; + const h = node.height / 2; + if (dx >= w || dy >= h) { + return true; + } + return false; +}; +const intersection = (node, outsidePoint, insidePoint) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`intersection calc abc89: + outsidePoint: ${JSON.stringify(outsidePoint)} + insidePoint : ${JSON.stringify(insidePoint)} + node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`); + const x = node.x; + const y = node.y; + const dx = Math.abs(x - insidePoint.x); + const w = node.width / 2; + let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx; + const h = node.height / 2; + const Q = Math.abs(outsidePoint.y - insidePoint.y); + const R = Math.abs(outsidePoint.x - insidePoint.x); + if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) { + let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y; + r = R * q / Q; + const res = { + x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r, + y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q + }; + if (r === 0) { + res.x = outsidePoint.x; + res.y = outsidePoint.y; + } + if (R === 0) { + res.x = outsidePoint.x; + } + if (Q === 0) { + res.y = outsidePoint.y; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res); + return res; + } else { + if (insidePoint.x < outsidePoint.x) { + r = outsidePoint.x - w - x; + } else { + r = x - w - outsidePoint.x; + } + let q = Q * r / R; + let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r; + let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y }); + if (r === 0) { + _x = outsidePoint.x; + _y = outsidePoint.y; + } + if (R === 0) { + _x = outsidePoint.x; + } + if (Q === 0) { + _y = outsidePoint.y; + } + return { x: _x, y: _y }; + } +}; +const cutPathAtIntersect = (_points, boundryNode) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 cutPathAtIntersect", _points, boundryNode); + let points = []; + let lastPointOutside = _points[0]; + let isInside = false; + _points.forEach((point2) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 checking point", point2, boundryNode); + if (!outsideNode(boundryNode, point2) && !isInside) { + const inter = intersection(boundryNode, lastPointOutside, point2); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 inside", point2, lastPointOutside, inter); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 intersection", inter); + let pointPresent = false; + points.forEach((p) => { + pointPresent = pointPresent || p.x === inter.x && p.y === inter.y; + }); + if (!points.some((e) => e.x === inter.x && e.y === inter.y)) { + points.push(inter); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 no intersect", inter, points); + } + isInside = true; + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 outside", point2, lastPointOutside); + lastPointOutside = point2; + if (!isInside) { + points.push(point2); + } + } + }); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.warn("abc88 returning points", points); + return points; +}; +const insertEdge = function(elem, e, edge, clusterDb, diagramType, graph, id) { + let points = edge.points; + let pointsHasChanged = false; + const tail = graph.node(e.v); + var head = graph.node(e.w); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc88 InsertEdge: ", edge); + if (head.intersect && tail.intersect) { + points = points.slice(1, edge.points.length - 1); + points.unshift(tail.intersect(points[0])); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info( + "Last point", + points[points.length - 1], + head, + head.intersect(points[points.length - 1]) + ); + points.push(head.intersect(points[points.length - 1])); + } + if (edge.toCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("to cluster abc88", clusterDb[edge.toCluster]); + points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node); + pointsHasChanged = true; + } + if (edge.fromCluster) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("from cluster abc88", clusterDb[edge.fromCluster]); + points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse(); + pointsHasChanged = true; + } + const lineData = points.filter((p) => !Number.isNaN(p.y)); + let curve = d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .$0Z; + if (edge.curve && (diagramType === "graph" || diagramType === "flowchart")) { + curve = edge.curve; + } + const { x, y } = getLineFunctionsWithOffset(edge); + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(x).y(y).curve(curve); + let strokeClasses; + switch (edge.thickness) { + case "normal": + strokeClasses = "edge-thickness-normal"; + break; + case "thick": + strokeClasses = "edge-thickness-thick"; + break; + case "invisible": + strokeClasses = "edge-thickness-thick"; + break; + default: + strokeClasses = ""; + } + switch (edge.pattern) { + case "solid": + strokeClasses += " edge-pattern-solid"; + break; + case "dotted": + strokeClasses += " edge-pattern-dotted"; + break; + case "dashed": + strokeClasses += " edge-pattern-dashed"; + break; + } + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", edge.id).attr("class", " " + strokeClasses + (edge.classes ? " " + edge.classes : "")).attr("style", edge.style); + let url = ""; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().flowchart.arrowMarkerAbsolute || (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeStart", edge.arrowTypeStart); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("arrowTypeEnd", edge.arrowTypeEnd); + switch (edge.arrowTypeStart) { + case "arrow_cross": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-crossStart)" + ); + break; + case "arrow_point": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-pointStart)" + ); + break; + case "arrow_barb": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-barbStart)" + ); + break; + case "arrow_circle": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-circleStart)" + ); + break; + case "aggregation": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationStart)" + ); + break; + case "extension": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-extensionStart)" + ); + break; + case "composition": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-compositionStart)" + ); + break; + case "dependency": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyStart)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopStart)" + ); + break; + } + switch (edge.arrowTypeEnd) { + case "arrow_cross": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-crossEnd)"); + break; + case "arrow_point": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-pointEnd)"); + break; + case "arrow_barb": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-barbEnd)"); + break; + case "arrow_circle": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-circleEnd)"); + break; + case "aggregation": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationEnd)" + ); + break; + case "extension": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-extensionEnd)" + ); + break; + case "composition": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-compositionEnd)" + ); + break; + case "dependency": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyEnd)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopEnd)" + ); + break; + } + let paths = {}; + if (pointsHasChanged) { + paths.updatedPath = points; + } + paths.originalPath = edge.points; + return paths; +}; + + + +/***/ }), + +/***/ 75254: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ f: () => (/* binding */ flowDb), +/* harmony export */ p: () => (/* binding */ parser$1) +/* harmony export */ }); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56363); + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 4], $V1 = [1, 3], $V2 = [1, 5], $V3 = [1, 8, 9, 10, 11, 27, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $V4 = [2, 2], $V5 = [1, 13], $V6 = [1, 14], $V7 = [1, 15], $V8 = [1, 16], $V9 = [1, 23], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 49], $Ve = [1, 48], $Vf = [1, 29], $Vg = [1, 30], $Vh = [1, 31], $Vi = [1, 32], $Vj = [1, 33], $Vk = [1, 44], $Vl = [1, 46], $Vm = [1, 42], $Vn = [1, 47], $Vo = [1, 43], $Vp = [1, 50], $Vq = [1, 45], $Vr = [1, 51], $Vs = [1, 52], $Vt = [1, 34], $Vu = [1, 35], $Vv = [1, 36], $Vw = [1, 37], $Vx = [1, 57], $Vy = [1, 8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vz = [1, 61], $VA = [1, 60], $VB = [1, 62], $VC = [8, 9, 11, 73, 75], $VD = [1, 88], $VE = [1, 93], $VF = [1, 92], $VG = [1, 89], $VH = [1, 85], $VI = [1, 91], $VJ = [1, 87], $VK = [1, 94], $VL = [1, 90], $VM = [1, 95], $VN = [1, 86], $VO = [8, 9, 10, 11, 73, 75], $VP = [8, 9, 10, 11, 44, 73, 75], $VQ = [8, 9, 10, 11, 29, 42, 44, 46, 48, 50, 52, 54, 56, 58, 61, 63, 65, 66, 68, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VR = [8, 9, 11, 42, 58, 73, 75, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VS = [42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], $VT = [1, 121], $VU = [1, 120], $VV = [1, 128], $VW = [1, 142], $VX = [1, 143], $VY = [1, 144], $VZ = [1, 145], $V_ = [1, 130], $V$ = [1, 132], $V01 = [1, 136], $V11 = [1, 137], $V21 = [1, 138], $V31 = [1, 139], $V41 = [1, 140], $V51 = [1, 141], $V61 = [1, 146], $V71 = [1, 147], $V81 = [1, 126], $V91 = [1, 127], $Va1 = [1, 134], $Vb1 = [1, 129], $Vc1 = [1, 133], $Vd1 = [1, 131], $Ve1 = [8, 9, 10, 11, 27, 32, 34, 36, 38, 42, 58, 81, 82, 83, 84, 85, 86, 99, 102, 103, 106, 108, 111, 112, 113, 118, 119, 120, 121], $Vf1 = [1, 149], $Vg1 = [8, 9, 11], $Vh1 = [8, 9, 10, 11, 14, 42, 58, 86, 102, 103, 106, 108, 111, 112, 113], $Vi1 = [1, 169], $Vj1 = [1, 165], $Vk1 = [1, 166], $Vl1 = [1, 170], $Vm1 = [1, 167], $Vn1 = [1, 168], $Vo1 = [75, 113, 116], $Vp1 = [8, 9, 10, 11, 12, 14, 27, 29, 32, 42, 58, 73, 81, 82, 83, 84, 85, 86, 87, 102, 106, 108, 111, 112, 113], $Vq1 = [10, 103], $Vr1 = [31, 47, 49, 51, 53, 55, 60, 62, 64, 65, 67, 69, 113, 114, 115], $Vs1 = [1, 235], $Vt1 = [1, 233], $Vu1 = [1, 237], $Vv1 = [1, 231], $Vw1 = [1, 232], $Vx1 = [1, 234], $Vy1 = [1, 236], $Vz1 = [1, 238], $VA1 = [1, 255], $VB1 = [8, 9, 11, 103], $VC1 = [8, 9, 10, 11, 58, 81, 102, 103, 106, 107, 108, 109]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "graphConfig": 4, "document": 5, "line": 6, "statement": 7, "SEMI": 8, "NEWLINE": 9, "SPACE": 10, "EOF": 11, "GRAPH": 12, "NODIR": 13, "DIR": 14, "FirstStmtSeperator": 15, "ending": 16, "endToken": 17, "spaceList": 18, "spaceListNewline": 19, "verticeStatement": 20, "separator": 21, "styleStatement": 22, "linkStyleStatement": 23, "classDefStatement": 24, "classStatement": 25, "clickStatement": 26, "subgraph": 27, "textNoTags": 28, "SQS": 29, "text": 30, "SQE": 31, "end": 32, "direction": 33, "acc_title": 34, "acc_title_value": 35, "acc_descr": 36, "acc_descr_value": 37, "acc_descr_multiline_value": 38, "link": 39, "node": 40, "styledVertex": 41, "AMP": 42, "vertex": 43, "STYLE_SEPARATOR": 44, "idString": 45, "DOUBLECIRCLESTART": 46, "DOUBLECIRCLEEND": 47, "PS": 48, "PE": 49, "(-": 50, "-)": 51, "STADIUMSTART": 52, "STADIUMEND": 53, "SUBROUTINESTART": 54, "SUBROUTINEEND": 55, "VERTEX_WITH_PROPS_START": 56, "NODE_STRING[field]": 57, "COLON": 58, "NODE_STRING[value]": 59, "PIPE": 60, "CYLINDERSTART": 61, "CYLINDEREND": 62, "DIAMOND_START": 63, "DIAMOND_STOP": 64, "TAGEND": 65, "TRAPSTART": 66, "TRAPEND": 67, "INVTRAPSTART": 68, "INVTRAPEND": 69, "linkStatement": 70, "arrowText": 71, "TESTSTR": 72, "START_LINK": 73, "edgeText": 74, "LINK": 75, "edgeTextToken": 76, "STR": 77, "MD_STR": 78, "textToken": 79, "keywords": 80, "STYLE": 81, "LINKSTYLE": 82, "CLASSDEF": 83, "CLASS": 84, "CLICK": 85, "DOWN": 86, "UP": 87, "textNoTagsToken": 88, "stylesOpt": 89, "idString[vertex]": 90, "idString[class]": 91, "CALLBACKNAME": 92, "CALLBACKARGS": 93, "HREF": 94, "LINK_TARGET": 95, "STR[link]": 96, "STR[tooltip]": 97, "alphaNum": 98, "DEFAULT": 99, "numList": 100, "INTERPOLATE": 101, "NUM": 102, "COMMA": 103, "style": 104, "styleComponent": 105, "NODE_STRING": 106, "UNIT": 107, "BRKT": 108, "PCT": 109, "idStringToken": 110, "MINUS": 111, "MULT": 112, "UNICODE_TEXT": 113, "TEXT": 114, "TAGSTART": 115, "EDGE_TEXT": 116, "alphaNumToken": 117, "direction_tb": 118, "direction_bt": 119, "direction_rl": 120, "direction_lr": 121, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 8: "SEMI", 9: "NEWLINE", 10: "SPACE", 11: "EOF", 12: "GRAPH", 13: "NODIR", 14: "DIR", 27: "subgraph", 29: "SQS", 31: "SQE", 32: "end", 34: "acc_title", 35: "acc_title_value", 36: "acc_descr", 37: "acc_descr_value", 38: "acc_descr_multiline_value", 42: "AMP", 44: "STYLE_SEPARATOR", 46: "DOUBLECIRCLESTART", 47: "DOUBLECIRCLEEND", 48: "PS", 49: "PE", 50: "(-", 51: "-)", 52: "STADIUMSTART", 53: "STADIUMEND", 54: "SUBROUTINESTART", 55: "SUBROUTINEEND", 56: "VERTEX_WITH_PROPS_START", 57: "NODE_STRING[field]", 58: "COLON", 59: "NODE_STRING[value]", 60: "PIPE", 61: "CYLINDERSTART", 62: "CYLINDEREND", 63: "DIAMOND_START", 64: "DIAMOND_STOP", 65: "TAGEND", 66: "TRAPSTART", 67: "TRAPEND", 68: "INVTRAPSTART", 69: "INVTRAPEND", 72: "TESTSTR", 73: "START_LINK", 75: "LINK", 77: "STR", 78: "MD_STR", 81: "STYLE", 82: "LINKSTYLE", 83: "CLASSDEF", 84: "CLASS", 85: "CLICK", 86: "DOWN", 87: "UP", 90: "idString[vertex]", 91: "idString[class]", 92: "CALLBACKNAME", 93: "CALLBACKARGS", 94: "HREF", 95: "LINK_TARGET", 96: "STR[link]", 97: "STR[tooltip]", 99: "DEFAULT", 101: "INTERPOLATE", 102: "NUM", 103: "COMMA", 106: "NODE_STRING", 107: "UNIT", 108: "BRKT", 109: "PCT", 111: "MINUS", 112: "MULT", 113: "UNICODE_TEXT", 114: "TEXT", 115: "TAGSTART", 116: "EDGE_TEXT", 118: "direction_tb", 119: "direction_bt", 120: "direction_rl", 121: "direction_lr" }, + productions_: [0, [3, 2], [5, 0], [5, 2], [6, 1], [6, 1], [6, 1], [6, 1], [6, 1], [4, 2], [4, 2], [4, 2], [4, 3], [16, 2], [16, 1], [17, 1], [17, 1], [17, 1], [15, 1], [15, 1], [15, 2], [19, 2], [19, 2], [19, 1], [19, 1], [18, 2], [18, 1], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [7, 9], [7, 6], [7, 4], [7, 1], [7, 2], [7, 2], [7, 1], [21, 1], [21, 1], [21, 1], [20, 3], [20, 4], [20, 2], [20, 1], [40, 1], [40, 5], [41, 1], [41, 3], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 8], [43, 4], [43, 4], [43, 4], [43, 6], [43, 4], [43, 4], [43, 4], [43, 4], [43, 4], [43, 1], [39, 2], [39, 3], [39, 3], [39, 1], [39, 3], [74, 1], [74, 2], [74, 1], [74, 1], [70, 1], [71, 3], [30, 1], [30, 2], [30, 1], [30, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [80, 1], [28, 1], [28, 2], [28, 1], [28, 1], [24, 5], [25, 5], [26, 2], [26, 4], [26, 3], [26, 5], [26, 3], [26, 5], [26, 5], [26, 7], [26, 2], [26, 4], [26, 2], [26, 4], [26, 4], [26, 6], [22, 5], [23, 5], [23, 5], [23, 9], [23, 9], [23, 7], [23, 7], [100, 1], [100, 3], [89, 1], [89, 3], [104, 1], [104, 2], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [105, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [110, 1], [79, 1], [79, 1], [79, 1], [79, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [88, 1], [76, 1], [76, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [117, 1], [45, 1], [45, 2], [98, 1], [98, 2], [33, 1], [33, 1], [33, 1], [33, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 2: + this.$ = []; + break; + case 3: + if (!Array.isArray($$[$0]) || $$[$0].length > 0) { + $$[$0 - 1].push($$[$0]); + } + this.$ = $$[$0 - 1]; + break; + case 4: + case 176: + this.$ = $$[$0]; + break; + case 11: + yy.setDirection("TB"); + this.$ = "TB"; + break; + case 12: + yy.setDirection($$[$0 - 1]); + this.$ = $$[$0 - 1]; + break; + case 27: + this.$ = $$[$0 - 1].nodes; + break; + case 28: + case 29: + case 30: + case 31: + case 32: + this.$ = []; + break; + case 33: + this.$ = yy.addSubGraph($$[$0 - 6], $$[$0 - 1], $$[$0 - 4]); + break; + case 34: + this.$ = yy.addSubGraph($$[$0 - 3], $$[$0 - 1], $$[$0 - 3]); + break; + case 35: + this.$ = yy.addSubGraph(void 0, $$[$0 - 1], void 0); + break; + case 37: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 38: + case 39: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 43: + yy.addLink($$[$0 - 2].stmt, $$[$0], $$[$0 - 1]); + this.$ = { stmt: $$[$0], nodes: $$[$0].concat($$[$0 - 2].nodes) }; + break; + case 44: + yy.addLink($$[$0 - 3].stmt, $$[$0 - 1], $$[$0 - 2]); + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1].concat($$[$0 - 3].nodes) }; + break; + case 45: + this.$ = { stmt: $$[$0 - 1], nodes: $$[$0 - 1] }; + break; + case 46: + this.$ = { stmt: $$[$0], nodes: $$[$0] }; + break; + case 47: + this.$ = [$$[$0]]; + break; + case 48: + this.$ = $$[$0 - 4].concat($$[$0]); + break; + case 49: + this.$ = $$[$0]; + break; + case 50: + this.$ = $$[$0 - 2]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 51: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "square"); + break; + case 52: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "doublecircle"); + break; + case 53: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "circle"); + break; + case 54: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "ellipse"); + break; + case 55: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "stadium"); + break; + case 56: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "subroutine"); + break; + case 57: + this.$ = $$[$0 - 7]; + yy.addVertex($$[$0 - 7], $$[$0 - 1], "rect", void 0, void 0, void 0, Object.fromEntries([[$$[$0 - 5], $$[$0 - 3]]])); + break; + case 58: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "cylinder"); + break; + case 59: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "round"); + break; + case 60: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "diamond"); + break; + case 61: + this.$ = $$[$0 - 5]; + yy.addVertex($$[$0 - 5], $$[$0 - 2], "hexagon"); + break; + case 62: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "odd"); + break; + case 63: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "trapezoid"); + break; + case 64: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "inv_trapezoid"); + break; + case 65: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_right"); + break; + case 66: + this.$ = $$[$0 - 3]; + yy.addVertex($$[$0 - 3], $$[$0 - 1], "lean_left"); + break; + case 67: + this.$ = $$[$0]; + yy.addVertex($$[$0]); + break; + case 68: + $$[$0 - 1].text = $$[$0]; + this.$ = $$[$0 - 1]; + break; + case 69: + case 70: + $$[$0 - 2].text = $$[$0 - 1]; + this.$ = $$[$0 - 2]; + break; + case 71: + this.$ = $$[$0]; + break; + case 72: + var inf = yy.destructLink($$[$0], $$[$0 - 2]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length, "text": $$[$0 - 1] }; + break; + case 73: + this.$ = { text: $$[$0], type: "text" }; + break; + case 74: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 75: + this.$ = { text: $$[$0], type: "string" }; + break; + case 76: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 77: + var inf = yy.destructLink($$[$0]); + this.$ = { "type": inf.type, "stroke": inf.stroke, "length": inf.length }; + break; + case 78: + this.$ = $$[$0 - 1]; + break; + case 79: + this.$ = { text: $$[$0], type: "text" }; + break; + case 80: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 81: + this.$ = { text: $$[$0], type: "string" }; + break; + case 82: + case 97: + this.$ = { text: $$[$0], type: "markdown" }; + break; + case 94: + this.$ = { text: $$[$0], type: "text" }; + break; + case 95: + this.$ = { text: $$[$0 - 1].text + "" + $$[$0], type: $$[$0 - 1].type }; + break; + case 96: + this.$ = { text: $$[$0], type: "text" }; + break; + case 98: + this.$ = $$[$0 - 4]; + yy.addClass($$[$0 - 2], $$[$0]); + break; + case 99: + this.$ = $$[$0 - 4]; + yy.setClass($$[$0 - 2], $$[$0]); + break; + case 100: + case 108: + this.$ = $$[$0 - 1]; + yy.setClickEvent($$[$0 - 1], $$[$0]); + break; + case 101: + case 109: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 102: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 103: + this.$ = $$[$0 - 4]; + yy.setClickEvent($$[$0 - 4], $$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 104: + this.$ = $$[$0 - 2]; + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 105: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2]); + yy.setTooltip($$[$0 - 4], $$[$0]); + break; + case 106: + this.$ = $$[$0 - 4]; + yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]); + break; + case 107: + this.$ = $$[$0 - 6]; + yy.setLink($$[$0 - 6], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 6], $$[$0 - 2]); + break; + case 110: + this.$ = $$[$0 - 1]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 111: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2]); + yy.setTooltip($$[$0 - 3], $$[$0]); + break; + case 112: + this.$ = $$[$0 - 3]; + yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]); + break; + case 113: + this.$ = $$[$0 - 5]; + yy.setLink($$[$0 - 5], $$[$0 - 4], $$[$0]); + yy.setTooltip($$[$0 - 5], $$[$0 - 2]); + break; + case 114: + this.$ = $$[$0 - 4]; + yy.addVertex($$[$0 - 2], void 0, void 0, $$[$0]); + break; + case 115: + this.$ = $$[$0 - 4]; + yy.updateLink([$$[$0 - 2]], $$[$0]); + break; + case 116: + this.$ = $$[$0 - 4]; + yy.updateLink($$[$0 - 2], $$[$0]); + break; + case 117: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate([$$[$0 - 6]], $$[$0 - 2]); + yy.updateLink([$$[$0 - 6]], $$[$0]); + break; + case 118: + this.$ = $$[$0 - 8]; + yy.updateLinkInterpolate($$[$0 - 6], $$[$0 - 2]); + yy.updateLink($$[$0 - 6], $$[$0]); + break; + case 119: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate([$$[$0 - 4]], $$[$0]); + break; + case 120: + this.$ = $$[$0 - 6]; + yy.updateLinkInterpolate($$[$0 - 4], $$[$0]); + break; + case 121: + case 123: + this.$ = [$$[$0]]; + break; + case 122: + case 124: + $$[$0 - 2].push($$[$0]); + this.$ = $$[$0 - 2]; + break; + case 126: + this.$ = $$[$0 - 1] + $$[$0]; + break; + case 174: + this.$ = $$[$0]; + break; + case 175: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 177: + this.$ = $$[$0 - 1] + "" + $$[$0]; + break; + case 178: + this.$ = { stmt: "dir", value: "TB" }; + break; + case 179: + this.$ = { stmt: "dir", value: "BT" }; + break; + case 180: + this.$ = { stmt: "dir", value: "RL" }; + break; + case 181: + this.$ = { stmt: "dir", value: "LR" }; + break; + } + }, + table: [{ 3: 1, 4: 2, 9: $V0, 10: $V1, 12: $V2 }, { 1: [3] }, o($V3, $V4, { 5: 6 }), { 4: 7, 9: $V0, 10: $V1, 12: $V2 }, { 4: 8, 9: $V0, 10: $V1, 12: $V2 }, { 13: [1, 9], 14: [1, 10] }, { 1: [2, 1], 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($V3, [2, 9]), o($V3, [2, 10]), o($V3, [2, 11]), { 8: [1, 54], 9: [1, 55], 10: $Vx, 15: 53, 18: 56 }, o($Vy, [2, 3]), o($Vy, [2, 4]), o($Vy, [2, 5]), o($Vy, [2, 6]), o($Vy, [2, 7]), o($Vy, [2, 8]), { 8: $Vz, 9: $VA, 11: $VB, 21: 58, 39: 59, 70: 63, 73: [1, 64], 75: [1, 65] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 66 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 67 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 68 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 69 }, { 8: $Vz, 9: $VA, 11: $VB, 21: 70 }, { 8: $Vz, 9: $VA, 10: [1, 71], 11: $VB, 21: 72 }, o($Vy, [2, 36]), { 35: [1, 73] }, { 37: [1, 74] }, o($Vy, [2, 39]), o($VC, [2, 46], { 18: 75, 10: $Vx }), { 10: [1, 76] }, { 10: [1, 77] }, { 10: [1, 78] }, { 10: [1, 79] }, { 14: $VD, 42: $VE, 58: $VF, 77: [1, 83], 86: $VG, 92: [1, 80], 94: [1, 81], 98: 82, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, o($Vy, [2, 178]), o($Vy, [2, 179]), o($Vy, [2, 180]), o($Vy, [2, 181]), o($VO, [2, 47]), o($VO, [2, 49], { 44: [1, 96] }), o($VP, [2, 67], { 110: 109, 29: [1, 97], 42: $Vd, 46: [1, 98], 48: [1, 99], 50: [1, 100], 52: [1, 101], 54: [1, 102], 56: [1, 103], 58: $Ve, 61: [1, 104], 63: [1, 105], 65: [1, 106], 66: [1, 107], 68: [1, 108], 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($VQ, [2, 174]), o($VQ, [2, 135]), o($VQ, [2, 136]), o($VQ, [2, 137]), o($VQ, [2, 138]), o($VQ, [2, 139]), o($VQ, [2, 140]), o($VQ, [2, 141]), o($VQ, [2, 142]), o($VQ, [2, 143]), o($VQ, [2, 144]), o($VQ, [2, 145]), o($V3, [2, 12]), o($V3, [2, 18]), o($V3, [2, 19]), { 9: [1, 110] }, o($VR, [2, 26], { 18: 111, 10: $Vx }), o($Vy, [2, 27]), { 40: 112, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vy, [2, 40]), o($Vy, [2, 41]), o($Vy, [2, 42]), o($VS, [2, 71], { 71: 113, 60: [1, 115], 72: [1, 114] }), { 74: 116, 76: 117, 77: [1, 118], 78: [1, 119], 113: $VT, 116: $VU }, o([42, 58, 60, 72, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 77]), o($Vy, [2, 28]), o($Vy, [2, 29]), o($Vy, [2, 30]), o($Vy, [2, 31]), o($Vy, [2, 32]), { 10: $VV, 12: $VW, 14: $VX, 27: $VY, 28: 122, 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 77: [1, 124], 78: [1, 125], 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 123, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Ve1, $V4, { 5: 148 }), o($Vy, [2, 37]), o($Vy, [2, 38]), o($VC, [2, 45], { 42: $Vf1 }), { 42: $Vd, 45: 150, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 99: [1, 151], 100: 152, 102: [1, 153] }, { 42: $Vd, 45: 154, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 42: $Vd, 45: 155, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 100], { 10: [1, 156], 93: [1, 157] }), { 77: [1, 158] }, o($Vg1, [2, 108], { 117: 160, 10: [1, 159], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 110], { 10: [1, 161] }), o($Vh1, [2, 176]), o($Vh1, [2, 163]), o($Vh1, [2, 164]), o($Vh1, [2, 165]), o($Vh1, [2, 166]), o($Vh1, [2, 167]), o($Vh1, [2, 168]), o($Vh1, [2, 169]), o($Vh1, [2, 170]), o($Vh1, [2, 171]), o($Vh1, [2, 172]), o($Vh1, [2, 173]), { 42: $Vd, 45: 162, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 30: 163, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 171, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 173, 48: [1, 172], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 174, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 175, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 176, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 106: [1, 177] }, { 30: 178, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 179, 63: [1, 180], 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 181, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 182, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 183, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VQ, [2, 175]), o($V3, [2, 20]), o($VR, [2, 25]), o($VC, [2, 43], { 18: 184, 10: $Vx }), o($VS, [2, 68], { 10: [1, 185] }), { 10: [1, 186] }, { 30: 187, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 75: [1, 188], 76: 189, 113: $VT, 116: $VU }, o($Vo1, [2, 73]), o($Vo1, [2, 75]), o($Vo1, [2, 76]), o($Vo1, [2, 161]), o($Vo1, [2, 162]), { 8: $Vz, 9: $VA, 10: $VV, 11: $VB, 12: $VW, 14: $VX, 21: 191, 27: $VY, 29: [1, 190], 32: $VZ, 42: $V_, 58: $V$, 73: $V01, 80: 135, 81: $V11, 82: $V21, 83: $V31, 84: $V41, 85: $V51, 86: $V61, 87: $V71, 88: 192, 102: $V81, 106: $V91, 108: $Va1, 111: $Vb1, 112: $Vc1, 113: $Vd1 }, o($Vp1, [2, 94]), o($Vp1, [2, 96]), o($Vp1, [2, 97]), o($Vp1, [2, 150]), o($Vp1, [2, 151]), o($Vp1, [2, 152]), o($Vp1, [2, 153]), o($Vp1, [2, 154]), o($Vp1, [2, 155]), o($Vp1, [2, 156]), o($Vp1, [2, 157]), o($Vp1, [2, 158]), o($Vp1, [2, 159]), o($Vp1, [2, 160]), o($Vp1, [2, 83]), o($Vp1, [2, 84]), o($Vp1, [2, 85]), o($Vp1, [2, 86]), o($Vp1, [2, 87]), o($Vp1, [2, 88]), o($Vp1, [2, 89]), o($Vp1, [2, 90]), o($Vp1, [2, 91]), o($Vp1, [2, 92]), o($Vp1, [2, 93]), { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 193], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vx, 18: 194 }, { 10: [1, 195], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 196] }, { 10: [1, 197], 103: [1, 198] }, o($Vq1, [2, 121]), { 10: [1, 199], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: [1, 200], 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 109, 111: $Vq, 112: $Vr, 113: $Vs }, { 77: [1, 201] }, o($Vg1, [2, 102], { 10: [1, 202] }), o($Vg1, [2, 104], { 10: [1, 203] }), { 77: [1, 204] }, o($Vh1, [2, 177]), { 77: [1, 205], 95: [1, 206] }, o($VO, [2, 50], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), { 31: [1, 207], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Vr1, [2, 79]), o($Vr1, [2, 81]), o($Vr1, [2, 82]), o($Vr1, [2, 146]), o($Vr1, [2, 147]), o($Vr1, [2, 148]), o($Vr1, [2, 149]), { 47: [1, 209], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 210, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 49: [1, 211], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 51: [1, 212], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 53: [1, 213], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 55: [1, 214], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 58: [1, 215] }, { 62: [1, 216], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 64: [1, 217], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 30: 218, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 31: [1, 219], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 220], 69: [1, 221], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 65: $Vi1, 67: [1, 223], 69: [1, 222], 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VC, [2, 44], { 42: $Vf1 }), o($VS, [2, 70]), o($VS, [2, 69]), { 60: [1, 224], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VS, [2, 72]), o($Vo1, [2, 74]), { 30: 225, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($Ve1, $V4, { 5: 226 }), o($Vp1, [2, 95]), o($Vy, [2, 35]), { 41: 227, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 228, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 239, 101: [1, 240], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 241, 101: [1, 242], 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 102: [1, 243] }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 244, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 42: $Vd, 45: 245, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs }, o($Vg1, [2, 101]), { 77: [1, 246] }, { 77: [1, 247], 95: [1, 248] }, o($Vg1, [2, 109]), o($Vg1, [2, 111], { 10: [1, 249] }), o($Vg1, [2, 112]), o($VP, [2, 51]), o($Vr1, [2, 80]), o($VP, [2, 52]), { 49: [1, 250], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 59]), o($VP, [2, 54]), o($VP, [2, 55]), o($VP, [2, 56]), { 106: [1, 251] }, o($VP, [2, 58]), o($VP, [2, 60]), { 64: [1, 252], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 62]), o($VP, [2, 63]), o($VP, [2, 65]), o($VP, [2, 64]), o($VP, [2, 66]), o([10, 42, 58, 86, 99, 102, 103, 106, 108, 111, 112, 113], [2, 78]), { 31: [1, 253], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 254], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, o($VO, [2, 48]), o($Vg1, [2, 114], { 103: $VA1 }), o($VB1, [2, 123], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($VC1, [2, 125]), o($VC1, [2, 127]), o($VC1, [2, 128]), o($VC1, [2, 129]), o($VC1, [2, 130]), o($VC1, [2, 131]), o($VC1, [2, 132]), o($VC1, [2, 133]), o($VC1, [2, 134]), o($Vg1, [2, 115], { 103: $VA1 }), { 10: [1, 257] }, o($Vg1, [2, 116], { 103: $VA1 }), { 10: [1, 258] }, o($Vq1, [2, 122]), o($Vg1, [2, 98], { 103: $VA1 }), o($Vg1, [2, 99], { 110: 109, 42: $Vd, 58: $Ve, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 111: $Vq, 112: $Vr, 113: $Vs }), o($Vg1, [2, 103]), o($Vg1, [2, 105], { 10: [1, 259] }), o($Vg1, [2, 106]), { 95: [1, 260] }, { 49: [1, 261] }, { 60: [1, 262] }, { 64: [1, 263] }, { 8: $Vz, 9: $VA, 11: $VB, 21: 264 }, o($Vy, [2, 34]), { 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 104: 265, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VC1, [2, 126]), { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 266, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 14: $VD, 42: $VE, 58: $VF, 86: $VG, 98: 267, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN, 117: 84 }, { 95: [1, 268] }, o($Vg1, [2, 113]), o($VP, [2, 53]), { 30: 269, 65: $Vi1, 77: $Vj1, 78: $Vk1, 79: 164, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, o($VP, [2, 61]), o($Ve1, $V4, { 5: 270 }), o($VB1, [2, 124], { 105: 256, 10: $Vs1, 58: $Vt1, 81: $Vu1, 102: $Vv1, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }), o($Vg1, [2, 119], { 117: 160, 10: [1, 271], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 120], { 117: 160, 10: [1, 272], 14: $VD, 42: $VE, 58: $VF, 86: $VG, 102: $VH, 103: $VI, 106: $VJ, 108: $VK, 111: $VL, 112: $VM, 113: $VN }), o($Vg1, [2, 107]), { 31: [1, 273], 65: $Vi1, 79: 208, 113: $Vl1, 114: $Vm1, 115: $Vn1 }, { 6: 11, 7: 12, 8: $V5, 9: $V6, 10: $V7, 11: $V8, 20: 17, 22: 18, 23: 19, 24: 20, 25: 21, 26: 22, 27: $V9, 32: [1, 274], 33: 24, 34: $Va, 36: $Vb, 38: $Vc, 40: 28, 41: 38, 42: $Vd, 43: 39, 45: 40, 58: $Ve, 81: $Vf, 82: $Vg, 83: $Vh, 84: $Vi, 85: $Vj, 86: $Vk, 99: $Vl, 102: $Vm, 103: $Vn, 106: $Vo, 108: $Vp, 110: 41, 111: $Vq, 112: $Vr, 113: $Vs, 118: $Vt, 119: $Vu, 120: $Vv, 121: $Vw }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 275, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, { 10: $Vs1, 58: $Vt1, 81: $Vu1, 89: 276, 102: $Vv1, 104: 229, 105: 230, 106: $Vw1, 107: $Vx1, 108: $Vy1, 109: $Vz1 }, o($VP, [2, 57]), o($Vy, [2, 33]), o($Vg1, [2, 117], { 103: $VA1 }), o($Vg1, [2, 118], { 103: $VA1 })], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex2() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex2(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex2() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: {}, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("acc_title"); + return 34; + case 1: + this.popState(); + return "acc_title_value"; + case 2: + this.begin("acc_descr"); + return 36; + case 3: + this.popState(); + return "acc_descr_value"; + case 4: + this.begin("acc_descr_multiline"); + break; + case 5: + this.popState(); + break; + case 6: + return "acc_descr_multiline_value"; + case 7: + this.begin("callbackname"); + break; + case 8: + this.popState(); + break; + case 9: + this.popState(); + this.begin("callbackargs"); + break; + case 10: + return 92; + case 11: + this.popState(); + break; + case 12: + return 93; + case 13: + return "MD_STR"; + case 14: + this.popState(); + break; + case 15: + this.begin("md_string"); + break; + case 16: + return "STR"; + case 17: + this.popState(); + break; + case 18: + this.pushState("string"); + break; + case 19: + return 81; + case 20: + return 99; + case 21: + return 82; + case 22: + return 101; + case 23: + return 83; + case 24: + return 84; + case 25: + return 94; + case 26: + this.begin("click"); + break; + case 27: + this.popState(); + break; + case 28: + return 85; + case 29: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 30: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 31: + if (yy.lex.firstGraph()) { + this.begin("dir"); + } + return 12; + case 32: + return 27; + case 33: + return 32; + case 34: + return 95; + case 35: + return 95; + case 36: + return 95; + case 37: + return 95; + case 38: + this.popState(); + return 13; + case 39: + this.popState(); + return 14; + case 40: + this.popState(); + return 14; + case 41: + this.popState(); + return 14; + case 42: + this.popState(); + return 14; + case 43: + this.popState(); + return 14; + case 44: + this.popState(); + return 14; + case 45: + this.popState(); + return 14; + case 46: + this.popState(); + return 14; + case 47: + this.popState(); + return 14; + case 48: + this.popState(); + return 14; + case 49: + return 118; + case 50: + return 119; + case 51: + return 120; + case 52: + return 121; + case 53: + return 102; + case 54: + return 108; + case 55: + return 44; + case 56: + return 58; + case 57: + return 42; + case 58: + return 8; + case 59: + return 103; + case 60: + return 112; + case 61: + this.popState(); + return 75; + case 62: + this.pushState("edgeText"); + return 73; + case 63: + return 116; + case 64: + this.popState(); + return 75; + case 65: + this.pushState("thickEdgeText"); + return 73; + case 66: + return 116; + case 67: + this.popState(); + return 75; + case 68: + this.pushState("dottedEdgeText"); + return 73; + case 69: + return 116; + case 70: + return 75; + case 71: + this.popState(); + return 51; + case 72: + return "TEXT"; + case 73: + this.pushState("ellipseText"); + return 50; + case 74: + this.popState(); + return 53; + case 75: + this.pushState("text"); + return 52; + case 76: + this.popState(); + return 55; + case 77: + this.pushState("text"); + return 54; + case 78: + return 56; + case 79: + this.pushState("text"); + return 65; + case 80: + this.popState(); + return 62; + case 81: + this.pushState("text"); + return 61; + case 82: + this.popState(); + return 47; + case 83: + this.pushState("text"); + return 46; + case 84: + this.popState(); + return 67; + case 85: + this.popState(); + return 69; + case 86: + return 114; + case 87: + this.pushState("trapText"); + return 66; + case 88: + this.pushState("trapText"); + return 68; + case 89: + return 115; + case 90: + return 65; + case 91: + return 87; + case 92: + return "SEP"; + case 93: + return 86; + case 94: + return 112; + case 95: + return 108; + case 96: + return 42; + case 97: + return 106; + case 98: + return 111; + case 99: + return 113; + case 100: + this.popState(); + return 60; + case 101: + this.pushState("text"); + return 60; + case 102: + this.popState(); + return 49; + case 103: + this.pushState("text"); + return 48; + case 104: + this.popState(); + return 31; + case 105: + this.pushState("text"); + return 29; + case 106: + this.popState(); + return 64; + case 107: + this.pushState("text"); + return 63; + case 108: + return "TEXT"; + case 109: + return "QUOTE"; + case 110: + return 9; + case 111: + return 10; + case 112: + return 11; + } + }, + rules: [/^(?:accTitle\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*:\s*)/, /^(?:(?!\n||)*[^\n]*)/, /^(?:accDescr\s*\{\s*)/, /^(?:[\}])/, /^(?:[^\}]*)/, /^(?:call[\s]+)/, /^(?:\([\s]*\))/, /^(?:\()/, /^(?:[^(]*)/, /^(?:\))/, /^(?:[^)]*)/, /^(?:[^`"]+)/, /^(?:[`]["])/, /^(?:["][`])/, /^(?:[^"]+)/, /^(?:["])/, /^(?:["])/, /^(?:style\b)/, /^(?:default\b)/, /^(?:linkStyle\b)/, /^(?:interpolate\b)/, /^(?:classDef\b)/, /^(?:class\b)/, /^(?:href[\s])/, /^(?:click[\s]+)/, /^(?:[\s\n])/, /^(?:[^\s\n]*)/, /^(?:flowchart-elk\b)/, /^(?:graph\b)/, /^(?:flowchart\b)/, /^(?:subgraph\b)/, /^(?:end\b\s*)/, /^(?:_self\b)/, /^(?:_blank\b)/, /^(?:_parent\b)/, /^(?:_top\b)/, /^(?:(\r?\n)*\s*\n)/, /^(?:\s*LR\b)/, /^(?:\s*RL\b)/, /^(?:\s*TB\b)/, /^(?:\s*BT\b)/, /^(?:\s*TD\b)/, /^(?:\s*BR\b)/, /^(?:\s*<)/, /^(?:\s*>)/, /^(?:\s*\^)/, /^(?:\s*v\b)/, /^(?:.*direction\s+TB[^\n]*)/, /^(?:.*direction\s+BT[^\n]*)/, /^(?:.*direction\s+RL[^\n]*)/, /^(?:.*direction\s+LR[^\n]*)/, /^(?:[0-9]+)/, /^(?:#)/, /^(?::::)/, /^(?::)/, /^(?:&)/, /^(?:;)/, /^(?:,)/, /^(?:\*)/, /^(?:\s*[xo<]?--+[-xo>]\s*)/, /^(?:\s*[xo<]?--\s*)/, /^(?:[^-]|-(?!-)+)/, /^(?:\s*[xo<]?==+[=xo>]\s*)/, /^(?:\s*[xo<]?==\s*)/, /^(?:[^=]|=(?!))/, /^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/, /^(?:\s*[xo<]?-\.\s*)/, /^(?:[^\.]|\.(?!))/, /^(?:\s*~~[\~]+\s*)/, /^(?:[-/\)][\)])/, /^(?:[^\(\)\[\]\{\}]|(?!\)+))/, /^(?:\(-)/, /^(?:\]\))/, /^(?:\(\[)/, /^(?:\]\])/, /^(?:\[\[)/, /^(?:\[\|)/, /^(?:>)/, /^(?:\)\])/, /^(?:\[\()/, /^(?:\)\)\))/, /^(?:\(\(\()/, /^(?:[\\(?=\])][\]])/, /^(?:\/(?=\])\])/, /^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/, /^(?:\[\/)/, /^(?:\[\\)/, /^(?:<)/, /^(?:>)/, /^(?:\^)/, /^(?:\\\|)/, /^(?:v\b)/, /^(?:\*)/, /^(?:#)/, /^(?:&)/, /^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/, /^(?:-)/, /^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/, /^(?:\|)/, /^(?:\|)/, /^(?:\))/, /^(?:\()/, /^(?:\])/, /^(?:\[)/, /^(?:(\}))/, /^(?:\{)/, /^(?:[^\[\]\(\)\{\}\|\"]+)/, /^(?:")/, /^(?:(\r?\n)+)/, /^(?:\s)/, /^(?:$)/], + conditions: { "callbackargs": { "rules": [11, 12, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "callbackname": { "rules": [8, 9, 10, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "href": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "click": { "rules": [15, 18, 27, 28, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dottedEdgeText": { "rules": [15, 18, 67, 69, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "thickEdgeText": { "rules": [15, 18, 64, 66, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "edgeText": { "rules": [15, 18, 61, 63, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "trapText": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 84, 85, 86, 87, 88, 101, 103, 105, 107], "inclusive": false }, "ellipseText": { "rules": [15, 18, 70, 71, 72, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "text": { "rules": [15, 18, 70, 73, 74, 75, 76, 77, 80, 81, 82, 83, 87, 88, 100, 101, 102, 103, 104, 105, 106, 107, 108], "inclusive": false }, "vertex": { "rules": [15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "dir": { "rules": [15, 18, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr_multiline": { "rules": [5, 6, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_descr": { "rules": [3, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "acc_title": { "rules": [1, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "md_string": { "rules": [13, 14, 15, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "string": { "rules": [15, 16, 17, 18, 70, 73, 75, 77, 81, 83, 87, 88, 101, 103, 105, 107], "inclusive": false }, "INITIAL": { "rules": [0, 2, 4, 7, 15, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 64, 65, 67, 68, 70, 73, 75, 77, 78, 79, 81, 83, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 101, 103, 105, 107, 109, 110, 111, 112], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const MERMAID_DOM_ID_PREFIX = "flowchart-"; +let vertexCounter = 0; +let config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); +let vertices = {}; +let edges = []; +let classes = {}; +let subGraphs = []; +let subGraphLookup = {}; +let tooltips = {}; +let subCount = 0; +let firstGraphFlag = true; +let direction; +let version; +let funs = []; +const sanitizeText = (txt) => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.e.sanitizeText(txt, config); +const lookUpDomId = function(id) { + const veritceKeys = Object.keys(vertices); + for (const veritceKey of veritceKeys) { + if (vertices[veritceKey].id === id) { + return vertices[veritceKey].domId; + } + } + return id; +}; +const addVertex = function(_id, textObj, type, style, classes2, dir, props = {}) { + let txt; + let id = _id; + if (id === void 0) { + return; + } + if (id.trim().length === 0) { + return; + } + if (vertices[id] === void 0) { + vertices[id] = { + id, + labelType: "text", + domId: MERMAID_DOM_ID_PREFIX + id + "-" + vertexCounter, + styles: [], + classes: [] + }; + } + vertexCounter++; + if (textObj !== void 0) { + config = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)(); + txt = sanitizeText(textObj.text.trim()); + vertices[id].labelType = textObj.type; + if (txt[0] === '"' && txt[txt.length - 1] === '"') { + txt = txt.substring(1, txt.length - 1); + } + vertices[id].text = txt; + } else { + if (vertices[id].text === void 0) { + vertices[id].text = _id; + } + } + if (type !== void 0) { + vertices[id].type = type; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + vertices[id].styles.push(s); + }); + } + if (classes2 !== void 0 && classes2 !== null) { + classes2.forEach(function(s) { + vertices[id].classes.push(s); + }); + } + if (dir !== void 0) { + vertices[id].dir = dir; + } + if (vertices[id].props === void 0) { + vertices[id].props = props; + } else if (props !== void 0) { + Object.assign(vertices[id].props, props); + } +}; +const addSingleLink = function(_start, _end, type) { + let start = _start; + let end = _end; + const edge = { start, end, type: void 0, text: "", labelType: "text" }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 Got edge...", edge); + const linkTextObj = type.text; + if (linkTextObj !== void 0) { + edge.text = sanitizeText(linkTextObj.text.trim()); + if (edge.text[0] === '"' && edge.text[edge.text.length - 1] === '"') { + edge.text = edge.text.substring(1, edge.text.length - 1); + } + edge.labelType = linkTextObj.type; + } + if (type !== void 0) { + edge.type = type.type; + edge.stroke = type.stroke; + edge.length = type.length; + } + if ((edge == null ? void 0 : edge.length) > 10) { + edge.length = 10; + } + if (edges.length < 280) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("abc78 pushing edge..."); + edges.push(edge); + } else { + throw new Error("Too many edges"); + } +}; +const addLink = function(_start, _end, type) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("addLink (abc78)", _start, _end, type); + let i, j; + for (i = 0; i < _start.length; i++) { + for (j = 0; j < _end.length; j++) { + addSingleLink(_start[i], _end[j], type); + } + } +}; +const updateLinkInterpolate = function(positions, interp) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultInterpolate = interp; + } else { + edges[pos].interpolate = interp; + } + }); +}; +const updateLink = function(positions, style) { + positions.forEach(function(pos) { + if (pos === "default") { + edges.defaultStyle = style; + } else { + if (_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.isSubstringInArray("fill", style) === -1) { + style.push("fill:none"); + } + edges[pos].style = style; + } + }); +}; +const addClass = function(ids, style) { + ids.split(",").forEach(function(id) { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + if (style !== void 0 && style !== null) { + style.forEach(function(s) { + if (s.match("color")) { + const newStyle = s.replace("fill", "bgFill").replace("color", "fill"); + classes[id].textStyles.push(newStyle); + } + classes[id].styles.push(s); + }); + } + }); +}; +const setDirection = function(dir) { + direction = dir; + if (direction.match(/.*</)) { + direction = "RL"; + } + if (direction.match(/.*\^/)) { + direction = "BT"; + } + if (direction.match(/.*>/)) { + direction = "LR"; + } + if (direction.match(/.*v/)) { + direction = "TB"; + } + if (direction === "TD") { + direction = "TB"; + } +}; +const setClass = function(ids, className) { + ids.split(",").forEach(function(_id) { + let id = _id; + if (vertices[id] !== void 0) { + vertices[id].classes.push(className); + } + if (subGraphLookup[id] !== void 0) { + subGraphLookup[id].classes.push(className); + } + }); +}; +const setTooltip = function(ids, tooltip) { + ids.split(",").forEach(function(id) { + if (tooltip !== void 0) { + tooltips[version === "gen-1" ? lookUpDomId(id) : id] = sanitizeText(tooltip); + } + }); +}; +const setClickFun = function(id, functionName, functionArgs) { + let domId = lookUpDomId(id); + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.c)().securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(id); + } + if (vertices[id] !== void 0) { + vertices[id].haveCallback = true; + funs.push(function() { + const elem = document.querySelector(`[id="${domId}"]`); + if (elem !== null) { + elem.addEventListener( + "click", + function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.runFunc(functionName, ...argList); + }, + false + ); + } + }); + } +}; +const setLink = function(ids, linkStr, target) { + ids.split(",").forEach(function(id) { + if (vertices[id] !== void 0) { + vertices[id].link = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.u.formatUrl(linkStr, config); + vertices[id].linkTarget = target; + } + }); + setClass(ids, "clickable"); +}; +const getTooltip = function(id) { + if (tooltips.hasOwnProperty(id)) { + return tooltips[id]; + } + return void 0; +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFun(id, functionName, functionArgs); + }); + setClass(ids, "clickable"); +}; +const bindFunctions = function(element) { + funs.forEach(function(fun) { + fun(element); + }); +}; +const getDirection = function() { + return direction.trim(); +}; +const getVertices = function() { + return vertices; +}; +const getEdges = function() { + return edges; +}; +const getClasses = function() { + return classes; +}; +const setupToolTips = function(element) { + let tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(".mermaidTooltip"); + if ((tooltipElem._groups || tooltipElem)[0][0] === null) { + tooltipElem = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body").append("div").attr("class", "mermaidTooltip").style("opacity", 0); + } + const svg = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(element).select("svg"); + const nodes = svg.selectAll("g.node"); + nodes.on("mouseover", function() { + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + const title = el.attr("title"); + if (title === null) { + return; + } + const rect = this.getBoundingClientRect(); + tooltipElem.transition().duration(200).style("opacity", ".9"); + tooltipElem.text(el.attr("title")).style("left", window.scrollX + rect.left + (rect.right - rect.left) / 2 + "px").style("top", window.scrollY + rect.top - 14 + document.body.scrollTop + "px"); + tooltipElem.html(tooltipElem.html().replace(/<br\/>/g, "<br/>")); + el.classed("hover", true); + }).on("mouseout", function() { + tooltipElem.transition().duration(500).style("opacity", 0); + const el = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this); + el.classed("hover", false); + }); +}; +funs.push(setupToolTips); +const clear = function(ver = "gen-1") { + vertices = {}; + classes = {}; + edges = []; + funs = [setupToolTips]; + subGraphs = []; + subGraphLookup = {}; + subCount = 0; + tooltips = {}; + firstGraphFlag = true; + version = ver; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.t)(); +}; +const setGen = (ver) => { + version = ver || "gen-2"; +}; +const defaultStyle = function() { + return "fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"; +}; +const addSubGraph = function(_id, list, _title) { + let id = _id.text.trim(); + let title = _title.text; + if (_id === _title && _title.text.match(/\s/)) { + id = void 0; + } + function uniq(a) { + const prims = { boolean: {}, number: {}, string: {} }; + const objs = []; + let dir2; + const nodeList2 = a.filter(function(item) { + const type = typeof item; + if (item.stmt && item.stmt === "dir") { + dir2 = item.value; + return false; + } + if (item.trim() === "") { + return false; + } + if (type in prims) { + return prims[type].hasOwnProperty(item) ? false : prims[type][item] = true; + } else { + return objs.includes(item) ? false : objs.push(item); + } + }); + return { nodeList: nodeList2, dir: dir2 }; + } + let nodeList = []; + const { nodeList: nl, dir } = uniq(nodeList.concat.apply(nodeList, list)); + nodeList = nl; + if (version === "gen-1") { + for (let i = 0; i < nodeList.length; i++) { + nodeList[i] = lookUpDomId(nodeList[i]); + } + } + id = id || "subGraph" + subCount; + title = title || ""; + title = sanitizeText(title); + subCount = subCount + 1; + const subGraph = { + id, + nodes: nodeList, + title: title.trim(), + classes: [], + dir, + labelType: _title.type + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.l.info("Adding", subGraph.id, subGraph.nodes, subGraph.dir); + subGraph.nodes = makeUniq(subGraph, subGraphs).nodes; + subGraphs.push(subGraph); + subGraphLookup[id] = subGraph; + return id; +}; +const getPosForId = function(id) { + for (const [i, subGraph] of subGraphs.entries()) { + if (subGraph.id === id) { + return i; + } + } + return -1; +}; +let secCount = -1; +const posCrossRef = []; +const indexNodes2 = function(id, pos) { + const nodes = subGraphs[pos].nodes; + secCount = secCount + 1; + if (secCount > 2e3) { + return; + } + posCrossRef[secCount] = pos; + if (subGraphs[pos].id === id) { + return { + result: true, + count: 0 + }; + } + let count = 0; + let posCount = 1; + while (count < nodes.length) { + const childPos = getPosForId(nodes[count]); + if (childPos >= 0) { + const res = indexNodes2(id, childPos); + if (res.result) { + return { + result: true, + count: posCount + res.count + }; + } else { + posCount = posCount + res.count; + } + } + count = count + 1; + } + return { + result: false, + count: posCount + }; +}; +const getDepthFirstPos = function(pos) { + return posCrossRef[pos]; +}; +const indexNodes = function() { + secCount = -1; + if (subGraphs.length > 0) { + indexNodes2("none", subGraphs.length - 1); + } +}; +const getSubGraphs = function() { + return subGraphs; +}; +const firstGraph = () => { + if (firstGraphFlag) { + firstGraphFlag = false; + return true; + } + return false; +}; +const destructStartLink = (_str) => { + let str = _str.trim(); + let type = "arrow_open"; + switch (str[0]) { + case "<": + type = "arrow_point"; + str = str.slice(1); + break; + case "x": + type = "arrow_cross"; + str = str.slice(1); + break; + case "o": + type = "arrow_circle"; + str = str.slice(1); + break; + } + let stroke = "normal"; + if (str.includes("=")) { + stroke = "thick"; + } + if (str.includes(".")) { + stroke = "dotted"; + } + return { type, stroke }; +}; +const countChar = (char, str) => { + const length = str.length; + let count = 0; + for (let i = 0; i < length; ++i) { + if (str[i] === char) { + ++count; + } + } + return count; +}; +const destructEndLink = (_str) => { + const str = _str.trim(); + let line = str.slice(0, -1); + let type = "arrow_open"; + switch (str.slice(-1)) { + case "x": + type = "arrow_cross"; + if (str[0] === "x") { + type = "double_" + type; + line = line.slice(1); + } + break; + case ">": + type = "arrow_point"; + if (str[0] === "<") { + type = "double_" + type; + line = line.slice(1); + } + break; + case "o": + type = "arrow_circle"; + if (str[0] === "o") { + type = "double_" + type; + line = line.slice(1); + } + break; + } + let stroke = "normal"; + let length = line.length - 1; + if (line[0] === "=") { + stroke = "thick"; + } + if (line[0] === "~") { + stroke = "invisible"; + } + let dots = countChar(".", line); + if (dots) { + stroke = "dotted"; + length = dots; + } + return { type, stroke, length }; +}; +const destructLink = (_str, _startStr) => { + const info = destructEndLink(_str); + let startInfo; + if (_startStr) { + startInfo = destructStartLink(_startStr); + if (startInfo.stroke !== info.stroke) { + return { type: "INVALID", stroke: "INVALID" }; + } + if (startInfo.type === "arrow_open") { + startInfo.type = info.type; + } else { + if (startInfo.type !== info.type) { + return { type: "INVALID", stroke: "INVALID" }; + } + startInfo.type = "double_" + startInfo.type; + } + if (startInfo.type === "double_arrow") { + startInfo.type = "double_arrow_point"; + } + startInfo.length = info.length; + return startInfo; + } + return info; +}; +const exists = (allSgs, _id) => { + let res = false; + allSgs.forEach((sg) => { + const pos = sg.nodes.indexOf(_id); + if (pos >= 0) { + res = true; + } + }); + return res; +}; +const makeUniq = (sg, allSubgraphs) => { + const res = []; + sg.nodes.forEach((_id, pos) => { + if (!exists(allSubgraphs, _id)) { + res.push(sg.nodes[pos]); + } + }); + return { nodes: res }; +}; +const lex = { + firstGraph +}; +const flowDb = { + defaultConfig: () => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.I.flowchart, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.g, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.b, + addVertex, + lookUpDomId, + addLink, + updateLinkInterpolate, + updateLink, + addClass, + setDirection, + setClass, + setTooltip, + getTooltip, + setClickEvent, + setLink, + bindFunctions, + getDirection, + getVertices, + getEdges, + getClasses, + clear, + setGen, + defaultStyle, + addSubGraph, + getDepthFirstPos, + indexNodes, + getSubGraphs, + destructLink, + lex, + exists, + makeUniq, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_1__.r +}; +const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addClass, + addLink, + addSingleLink, + addSubGraph, + addVertex, + bindFunctions, + clear, + default: flowDb, + defaultStyle, + destructLink, + firstGraph, + getClasses, + getDepthFirstPos, + getDirection, + getEdges, + getSubGraphs, + getTooltip, + getVertices, + indexNodes, + lex, + lookUpDomId, + setClass, + setClickEvent, + setDirection, + setGen, + setLink, + updateLink, + updateLinkInterpolate +}, Symbol.toStringTag, { value: "Module" })); + + + +/***/ }), + +/***/ 47740: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _flowDb_1972c806_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(75254); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(27707); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(56363); +/* harmony import */ var elkjs_lib_elk_bundled_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17295); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20683); + + + + + + + + + + + + + + + + +const findCommonAncestor = (id1, id2, treeData) => { + const { parentById } = treeData; + const visited = /* @__PURE__ */ new Set(); + let currentId = id1; + while (currentId) { + visited.add(currentId); + if (currentId === id2) { + return currentId; + } + currentId = parentById[currentId]; + } + currentId = id2; + while (currentId) { + if (visited.has(currentId)) { + return currentId; + } + currentId = parentById[currentId]; + } + return "root"; +}; +const elk = new elkjs_lib_elk_bundled_js__WEBPACK_IMPORTED_MODULE_1__(); +let portPos = {}; +const conf = {}; +let nodeDb = {}; +const addVertices = async function(vert, svgId, root, doc, diagObj, parentLookupDb, graph) { + const svg = root.select(`[id="${svgId}"]`); + const nodes = svg.insert("g").attr("class", "nodes"); + const keys = Object.keys(vert); + await Promise.all( + keys.map(async function(id) { + const vertex = vert[id]; + let classStr = "default"; + if (vertex.classes.length > 0) { + classStr = vertex.classes.join(" "); + } + classStr = classStr + " flowchart-label"; + const styles2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.k)(vertex.styles); + let vertexText = vertex.text !== void 0 ? vertex.text : vertex.id; + const labelData = { width: 0, height: 0 }; + const ports = [ + { + id: vertex.id + "-west", + layoutOptions: { + "port.side": "WEST" + } + }, + { + id: vertex.id + "-east", + layoutOptions: { + "port.side": "EAST" + } + }, + { + id: vertex.id + "-south", + layoutOptions: { + "port.side": "SOUTH" + } + }, + { + id: vertex.id + "-north", + layoutOptions: { + "port.side": "NORTH" + } + } + ]; + let radious = 0; + let _shape = ""; + let layoutOptions = {}; + switch (vertex.type) { + case "round": + radious = 5; + _shape = "rect"; + break; + case "square": + _shape = "rect"; + break; + case "diamond": + _shape = "question"; + layoutOptions = { + portConstraints: "FIXED_SIDE" + }; + break; + case "hexagon": + _shape = "hexagon"; + break; + case "odd": + _shape = "rect_left_inv_arrow"; + break; + case "lean_right": + _shape = "lean_right"; + break; + case "lean_left": + _shape = "lean_left"; + break; + case "trapezoid": + _shape = "trapezoid"; + break; + case "inv_trapezoid": + _shape = "inv_trapezoid"; + break; + case "odd_right": + _shape = "rect_left_inv_arrow"; + break; + case "circle": + _shape = "circle"; + break; + case "ellipse": + _shape = "ellipse"; + break; + case "stadium": + _shape = "stadium"; + break; + case "subroutine": + _shape = "subroutine"; + break; + case "cylinder": + _shape = "cylinder"; + break; + case "group": + _shape = "rect"; + break; + case "doublecircle": + _shape = "doublecircle"; + break; + default: + _shape = "rect"; + } + const node = { + labelStyle: styles2.labelStyle, + shape: _shape, + labelText: vertexText, + labelType: vertex.labelType, + rx: radious, + ry: radious, + class: classStr, + style: styles2.style, + id: vertex.id, + link: vertex.link, + linkTarget: vertex.linkTarget, + tooltip: diagObj.db.getTooltip(vertex.id) || "", + domId: diagObj.db.lookUpDomId(vertex.id), + haveCallback: vertex.haveCallback, + width: vertex.type === "group" ? 500 : void 0, + dir: vertex.dir, + type: vertex.type, + props: vertex.props, + padding: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.E)().flowchart.padding + }; + let boundingBox; + let nodeEl; + if (node.type !== "group") { + nodeEl = await (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.e)(nodes, node, vertex.dir); + boundingBox = nodeEl.node().getBBox(); + } else { + doc.createElementNS("http://www.w3.org/2000/svg", "text"); + const { shapeSvg, bbox } = await (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.l)(nodes, node, void 0, true); + labelData.width = bbox.width; + labelData.wrappingWidth = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.E)().flowchart.wrappingWidth; + labelData.height = bbox.height; + labelData.labelNode = shapeSvg.node(); + node.labelData = labelData; + } + const data = { + id: vertex.id, + ports: vertex.type === "diamond" ? ports : [], + // labelStyle: styles.labelStyle, + // shape: _shape, + layoutOptions, + labelText: vertexText, + labelData, + // labels: [{ text: vertexText }], + // rx: radius, + // ry: radius, + // class: classStr, + // style: styles.style, + // link: vertex.link, + // linkTarget: vertex.linkTarget, + // tooltip: diagObj.db.getTooltip(vertex.id) || '', + domId: diagObj.db.lookUpDomId(vertex.id), + // haveCallback: vertex.haveCallback, + width: boundingBox == null ? void 0 : boundingBox.width, + height: boundingBox == null ? void 0 : boundingBox.height, + // dir: vertex.dir, + type: vertex.type, + // props: vertex.props, + // padding: getConfig().flowchart.padding, + // boundingBox, + el: nodeEl, + parent: parentLookupDb.parentById[vertex.id] + }; + nodeDb[node.id] = data; + }) + ); + return graph; +}; +const getNextPosition = (position, edgeDirection, graphDirection) => { + const portPos2 = { + TB: { + in: { + north: "north" + }, + out: { + south: "west", + west: "east", + east: "south" + } + }, + LR: { + in: { + west: "west" + }, + out: { + east: "south", + south: "north", + north: "east" + } + }, + RL: { + in: { + east: "east" + }, + out: { + west: "north", + north: "south", + south: "west" + } + }, + BT: { + in: { + south: "south" + }, + out: { + north: "east", + east: "west", + west: "north" + } + } + }; + portPos2.TD = portPos2.TB; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc88", graphDirection, edgeDirection, position); + return portPos2[graphDirection][edgeDirection][position]; +}; +const getNextPort = (node, edgeDirection, graphDirection) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("getNextPort abc88", { node, edgeDirection, graphDirection }); + if (!portPos[node]) { + switch (graphDirection) { + case "TB": + case "TD": + portPos[node] = { + inPosition: "north", + outPosition: "south" + }; + break; + case "BT": + portPos[node] = { + inPosition: "south", + outPosition: "north" + }; + break; + case "RL": + portPos[node] = { + inPosition: "east", + outPosition: "west" + }; + break; + case "LR": + portPos[node] = { + inPosition: "west", + outPosition: "east" + }; + break; + } + } + const result = edgeDirection === "in" ? portPos[node].inPosition : portPos[node].outPosition; + if (edgeDirection === "in") { + portPos[node].inPosition = getNextPosition( + portPos[node].inPosition, + edgeDirection, + graphDirection + ); + } else { + portPos[node].outPosition = getNextPosition( + portPos[node].outPosition, + edgeDirection, + graphDirection + ); + } + return result; +}; +const getEdgeStartEndPoint = (edge, dir) => { + let source = edge.start; + let target = edge.end; + const sourceId = source; + const targetId = target; + const startNode = nodeDb[source]; + const endNode = nodeDb[target]; + if (!startNode || !endNode) { + return { source, target }; + } + if (startNode.type === "diamond") { + source = `${source}-${getNextPort(source, "out", dir)}`; + } + if (endNode.type === "diamond") { + target = `${target}-${getNextPort(target, "in", dir)}`; + } + return { source, target, sourceId, targetId }; +}; +const addEdges = function(edges, diagObj, graph, svg) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc78 edges = ", edges); + const labelsEl = svg.insert("g").attr("class", "edgeLabels"); + let linkIdCnt = {}; + let dir = diagObj.db.getDirection(); + let defaultStyle; + let defaultLabelStyle; + if (edges.defaultStyle !== void 0) { + const defaultStyles = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.k)(edges.defaultStyle); + defaultStyle = defaultStyles.style; + defaultLabelStyle = defaultStyles.labelStyle; + } + edges.forEach(function(edge) { + const linkIdBase = "L-" + edge.start + "-" + edge.end; + if (linkIdCnt[linkIdBase] === void 0) { + linkIdCnt[linkIdBase] = 0; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } else { + linkIdCnt[linkIdBase]++; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc78 new entry", linkIdBase, linkIdCnt[linkIdBase]); + } + let linkId = linkIdBase + "-" + linkIdCnt[linkIdBase]; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("abc78 new link id to be used is", linkIdBase, linkId, linkIdCnt[linkIdBase]); + const linkNameStart = "LS-" + edge.start; + const linkNameEnd = "LE-" + edge.end; + const edgeData = { style: "", labelStyle: "" }; + edgeData.minlen = edge.length || 1; + if (edge.type === "arrow_open") { + edgeData.arrowhead = "none"; + } else { + edgeData.arrowhead = "normal"; + } + edgeData.arrowTypeStart = "arrow_open"; + edgeData.arrowTypeEnd = "arrow_open"; + switch (edge.type) { + case "double_arrow_cross": + edgeData.arrowTypeStart = "arrow_cross"; + case "arrow_cross": + edgeData.arrowTypeEnd = "arrow_cross"; + break; + case "double_arrow_point": + edgeData.arrowTypeStart = "arrow_point"; + case "arrow_point": + edgeData.arrowTypeEnd = "arrow_point"; + break; + case "double_arrow_circle": + edgeData.arrowTypeStart = "arrow_circle"; + case "arrow_circle": + edgeData.arrowTypeEnd = "arrow_circle"; + break; + } + let style = ""; + let labelStyle = ""; + switch (edge.stroke) { + case "normal": + style = "fill:none;"; + if (defaultStyle !== void 0) { + style = defaultStyle; + } + if (defaultLabelStyle !== void 0) { + labelStyle = defaultLabelStyle; + } + edgeData.thickness = "normal"; + edgeData.pattern = "solid"; + break; + case "dotted": + edgeData.thickness = "normal"; + edgeData.pattern = "dotted"; + edgeData.style = "fill:none;stroke-width:2px;stroke-dasharray:3;"; + break; + case "thick": + edgeData.thickness = "thick"; + edgeData.pattern = "solid"; + edgeData.style = "stroke-width: 3.5px;fill:none;"; + break; + } + if (edge.style !== void 0) { + const styles2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.k)(edge.style); + style = styles2.style; + labelStyle = styles2.labelStyle; + } + edgeData.style = edgeData.style += style; + edgeData.labelStyle = edgeData.labelStyle += labelStyle; + if (edge.interpolate !== void 0) { + edgeData.curve = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.n)(edge.interpolate, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .c_6); + } else if (edges.defaultInterpolate !== void 0) { + edgeData.curve = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.n)(edges.defaultInterpolate, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .c_6); + } else { + edgeData.curve = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.n)(conf.curve, d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .c_6); + } + if (edge.text === void 0) { + if (edge.style !== void 0) { + edgeData.arrowheadStyle = "fill: #333"; + } + } else { + edgeData.arrowheadStyle = "fill: #333"; + edgeData.labelpos = "c"; + } + edgeData.labelType = edge.labelType; + edgeData.label = edge.text.replace(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.e.lineBreakRegex, "\n"); + if (edge.style === void 0) { + edgeData.style = edgeData.style || "stroke: #333; stroke-width: 1.5px;fill:none;"; + } + edgeData.labelStyle = edgeData.labelStyle.replace("color:", "fill:"); + edgeData.id = linkId; + edgeData.classes = "flowchart-link " + linkNameStart + " " + linkNameEnd; + const labelEl = (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.f)(labelsEl, edgeData); + const { source, target, sourceId, targetId } = getEdgeStartEndPoint(edge, dir); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.debug("abc78 source and target", source, target); + graph.edges.push({ + id: "e" + edge.start + edge.end, + sources: [source], + targets: [target], + sourceId, + targetId, + labelEl, + labels: [ + { + width: edgeData.width, + height: edgeData.height, + orgWidth: edgeData.width, + orgHeight: edgeData.height, + text: edgeData.label, + layoutOptions: { + "edgeLabels.inline": "true", + "edgeLabels.placement": "CENTER" + } + } + ], + edgeData + }); + }); + return graph; +}; +const addMarkersToEdge = function(svgPath, edgeData, diagramType, arrowMarkerAbsolute, id) { + let url = ""; + if (arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + switch (edgeData.arrowTypeStart) { + case "arrow_cross": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-crossStart)" + ); + break; + case "arrow_point": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-pointStart)" + ); + break; + case "arrow_barb": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-barbStart)" + ); + break; + case "arrow_circle": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-circleStart)" + ); + break; + case "aggregation": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationStart)" + ); + break; + case "extension": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-extensionStart)" + ); + break; + case "composition": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-compositionStart)" + ); + break; + case "dependency": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyStart)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-start", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopStart)" + ); + break; + } + switch (edgeData.arrowTypeEnd) { + case "arrow_cross": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-crossEnd)"); + break; + case "arrow_point": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-pointEnd)"); + break; + case "arrow_barb": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-barbEnd)"); + break; + case "arrow_circle": + svgPath.attr("marker-end", "url(" + url + "#" + id + "_" + diagramType + "-circleEnd)"); + break; + case "aggregation": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-aggregationEnd)" + ); + break; + case "extension": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-extensionEnd)" + ); + break; + case "composition": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-compositionEnd)" + ); + break; + case "dependency": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-dependencyEnd)" + ); + break; + case "lollipop": + svgPath.attr( + "marker-end", + "url(" + url + "#" + id + "_" + diagramType + "-lollipopEnd)" + ); + break; + } +}; +const getClasses = function(text, diagObj) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Extracting classes"); + return diagObj.db.getClasses(); +}; +const addSubGraphs = function(db2) { + const parentLookupDb = { parentById: {}, childrenById: {} }; + const subgraphs = db2.getSubGraphs(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Subgraphs - ", subgraphs); + subgraphs.forEach(function(subgraph) { + subgraph.nodes.forEach(function(node) { + parentLookupDb.parentById[node] = subgraph.id; + if (parentLookupDb.childrenById[subgraph.id] === void 0) { + parentLookupDb.childrenById[subgraph.id] = []; + } + parentLookupDb.childrenById[subgraph.id].push(node); + }); + }); + subgraphs.forEach(function(subgraph) { + ({ id: subgraph.id }); + if (parentLookupDb.parentById[subgraph.id] !== void 0) { + parentLookupDb.parentById[subgraph.id]; + } + }); + return parentLookupDb; +}; +const calcOffset = function(src, dest, parentLookupDb) { + const ancestor = findCommonAncestor(src, dest, parentLookupDb); + if (ancestor === void 0 || ancestor === "root") { + return { x: 0, y: 0 }; + } + const ancestorOffset = nodeDb[ancestor].offset; + return { x: ancestorOffset.posX, y: ancestorOffset.posY }; +}; +const insertEdge = function(edgesEl, edge, edgeData, diagObj, parentLookupDb, id) { + const offset = calcOffset(edge.sourceId, edge.targetId, parentLookupDb); + const src = edge.sections[0].startPoint; + const dest = edge.sections[0].endPoint; + const segments = edge.sections[0].bendPoints ? edge.sections[0].bendPoints : []; + const segPoints = segments.map((segment) => [segment.x + offset.x, segment.y + offset.y]); + const points = [ + [src.x + offset.x, src.y + offset.y], + ...segPoints, + [dest.x + offset.x, dest.y + offset.y] + ]; + const { x, y } = (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.j)(edge.edgeData); + const curve = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(x).y(y).curve(d3__WEBPACK_IMPORTED_MODULE_0__/* .curveLinear */ .c_6); + const edgePath = edgesEl.insert("path").attr("d", curve(points)).attr("class", "path " + edgeData.classes).attr("fill", "none"); + const edgeG = edgesEl.insert("g").attr("class", "edgeLabel"); + const edgeWithLabel = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(edgeG.node().appendChild(edge.labelEl)); + const box = edgeWithLabel.node().firstChild.getBoundingClientRect(); + edgeWithLabel.attr("width", box.width); + edgeWithLabel.attr("height", box.height); + edgeG.attr( + "transform", + `translate(${edge.labels[0].x + offset.x}, ${edge.labels[0].y + offset.y})` + ); + addMarkersToEdge(edgePath, edgeData, diagObj.type, diagObj.arrowMarkerAbsolute, id); +}; +const insertChildren = (nodeArray, parentLookupDb) => { + nodeArray.forEach((node) => { + if (!node.children) { + node.children = []; + } + const childIds = parentLookupDb.childrenById[node.id]; + if (childIds) { + childIds.forEach((childId) => { + node.children.push(nodeDb[childId]); + }); + } + insertChildren(node.children, parentLookupDb); + }); +}; +const draw = async function(text, id, _version, diagObj) { + var _a; + diagObj.db.clear(); + nodeDb = {}; + portPos = {}; + diagObj.db.setGen("gen-2"); + diagObj.parser.parse(text); + const renderEl = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body").append("div").attr("style", "height:400px").attr("id", "cy"); + let graph = { + id: "root", + layoutOptions: { + "elk.hierarchyHandling": "INCLUDE_CHILDREN", + "org.eclipse.elk.padding": "[top=100, left=100, bottom=110, right=110]", + "elk.layered.spacing.edgeNodeBetweenLayers": "30", + // 'elk.layered.mergeEdges': 'true', + "elk.direction": "DOWN" + // 'elk.ports.sameLayerEdges': true, + // 'nodePlacement.strategy': 'SIMPLE', + }, + children: [], + edges: [] + }; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Drawing flowchart using v3 renderer", elk); + let dir = diagObj.db.getDirection(); + switch (dir) { + case "BT": + graph.layoutOptions["elk.direction"] = "UP"; + break; + case "TB": + graph.layoutOptions["elk.direction"] = "DOWN"; + break; + case "LR": + graph.layoutOptions["elk.direction"] = "RIGHT"; + break; + case "RL": + graph.layoutOptions["elk.direction"] = "LEFT"; + break; + } + const { securityLevel, flowchart: conf2 } = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.E)(); + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const svg = root.select(`[id="${id}"]`); + const markers = ["point", "circle", "cross"]; + (0,_edges_f2ad444c_js__WEBPACK_IMPORTED_MODULE_6__.a)(svg, markers, diagObj.type, id); + const vert = diagObj.db.getVertices(); + let subG; + const subGraphs = diagObj.db.getSubGraphs(); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Subgraphs - ", subGraphs); + for (let i = subGraphs.length - 1; i >= 0; i--) { + subG = subGraphs[i]; + diagObj.db.addVertex( + subG.id, + { text: subG.title, type: subG.labelType }, + "group", + void 0, + subG.classes, + subG.dir + ); + } + const subGraphsEl = svg.insert("g").attr("class", "subgraphs"); + const parentLookupDb = addSubGraphs(diagObj.db); + graph = await addVertices(vert, id, root, doc, diagObj, parentLookupDb, graph); + const edgesEl = svg.insert("g").attr("class", "edges edgePath"); + const edges = diagObj.db.getEdges(); + graph = addEdges(edges, diagObj, graph, svg); + const nodes = Object.keys(nodeDb); + nodes.forEach((nodeId) => { + const node = nodeDb[nodeId]; + if (!node.parent) { + graph.children.push(node); + } + if (parentLookupDb.childrenById[nodeId] !== void 0) { + node.labels = [ + { + text: node.labelText, + layoutOptions: { + "nodeLabels.placement": "[H_CENTER, V_TOP, INSIDE]" + }, + width: node.labelData.width, + height: node.labelData.height + // width: 100, + // height: 100, + } + ]; + delete node.x; + delete node.y; + delete node.width; + delete node.height; + } + }); + insertChildren(graph.children, parentLookupDb); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("after layout", JSON.stringify(graph, null, 2)); + const g = await elk.layout(graph); + drawNodes(0, 0, g.children, svg, subGraphsEl, diagObj, 0); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("after layout", g); + (_a = g.edges) == null ? void 0 : _a.map((edge) => { + insertEdge(edgesEl, edge, edge.edgeData, diagObj, parentLookupDb, id); + }); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.o)({}, svg, conf2.diagramPadding, conf2.useMaxWidth); + renderEl.remove(); +}; +const drawNodes = (relX, relY, nodeArray, svg, subgraphsEl, diagObj, depth) => { + nodeArray.forEach(function(node) { + if (node) { + nodeDb[node.id].offset = { + posX: node.x + relX, + posY: node.y + relY, + x: relX, + y: relY, + depth, + width: node.width, + height: node.height + }; + if (node.type === "group") { + const subgraphEl = subgraphsEl.insert("g").attr("class", "subgraph"); + subgraphEl.insert("rect").attr("class", "subgraph subgraph-lvl-" + depth % 5 + " node").attr("x", node.x + relX).attr("y", node.y + relY).attr("width", node.width).attr("height", node.height); + const label = subgraphEl.insert("g").attr("class", "label"); + const labelCentering = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.E)().flowchart.htmlLabels ? node.labelData.width / 2 : 0; + label.attr( + "transform", + `translate(${node.labels[0].x + relX + node.x + labelCentering}, ${node.labels[0].y + relY + node.y + 3})` + ); + label.node().appendChild(node.labelData.labelNode); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Id (UGH)= ", node.type, node.labels); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_5__.l.info("Id (UGH)= ", node.id); + node.el.attr( + "transform", + `translate(${node.x + relX + node.width / 2}, ${node.y + relY + node.height / 2})` + ); + } + } + }); + nodeArray.forEach(function(node) { + if (node && node.type === "group") { + drawNodes(relX + node.x, relY + node.y, node.children, svg, subgraphsEl, diagObj, depth + 1); + } + }); +}; +const renderer = { + getClasses, + draw +}; +const genSections = (options) => { + let sections = ""; + for (let i = 0; i < 5; i++) { + sections += ` + .subgraph-lvl-${i} { + fill: ${options[`surface${i}`]}; + stroke: ${options[`surfacePeer${i}`]}; + } + `; + } + return sections; +}; +const getStyles = (options) => `.label { + font-family: ${options.fontFamily}; + color: ${options.nodeTextColor || options.textColor}; + } + .cluster-label text { + fill: ${options.titleColor}; + } + .cluster-label span { + color: ${options.titleColor}; + } + + .label text,span { + fill: ${options.nodeTextColor || options.textColor}; + color: ${options.nodeTextColor || options.textColor}; + } + + .node rect, + .node circle, + .node ellipse, + .node polygon, + .node path { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; + stroke-width: 1px; + } + + .node .label { + text-align: center; + } + .node.clickable { + cursor: pointer; + } + + .arrowheadPath { + fill: ${options.arrowheadColor}; + } + + .edgePath .path { + stroke: ${options.lineColor}; + stroke-width: 2.0px; + } + + .flowchart-link { + stroke: ${options.lineColor}; + fill: none; + } + + .edgeLabel { + background-color: ${options.edgeLabelBackground}; + rect { + opacity: 0.85; + background-color: ${options.edgeLabelBackground}; + fill: ${options.edgeLabelBackground}; + } + text-align: center; + } + + .cluster rect { + fill: ${options.clusterBkg}; + stroke: ${options.clusterBorder}; + stroke-width: 1px; + } + + .cluster text { + fill: ${options.titleColor}; + } + + .cluster span { + color: ${options.titleColor}; + } + /* .cluster div { + color: ${options.titleColor}; + } */ + + div.mermaidTooltip { + position: absolute; + text-align: center; + max-width: 200px; + padding: 2px; + font-family: ${options.fontFamily}; + font-size: 12px; + background: ${options.tertiaryColor}; + border: 1px solid ${options.border2}; + border-radius: 2px; + pointer-events: none; + z-index: 100; + } + + .flowchartTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; + } + .subgraph { + stroke-width:2; + rx:3; + } + // .subgraph-lvl-1 { + // fill:#ccc; + // // stroke:black; + // } + + .flowchart-label text { + text-anchor: middle; + } + + ${genSections(options)} +`; +const styles = getStyles; +const diagram = { + db: _flowDb_1972c806_js__WEBPACK_IMPORTED_MODULE_7__.d, + renderer, + parser: _flowDb_1972c806_js__WEBPACK_IMPORTED_MODULE_7__.p, + styles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/75121fd5.27699af6.js b/assets/js/75121fd5.ed266578.js similarity index 87% rename from assets/js/75121fd5.27699af6.js rename to assets/js/75121fd5.ed266578.js index 444cea225..fcff1e6de 100644 --- a/assets/js/75121fd5.27699af6.js +++ b/assets/js/75121fd5.ed266578.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5335],{30674:e=>{e.exports=JSON.parse('{"label":"image","permalink":"/tags/image","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5335],{30674:e=>{e.exports=JSON.parse('{"label":"image","permalink":"/tags/image","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/762.2b229c76.js b/assets/js/762.2b229c76.js new file mode 100644 index 000000000..bc810bcf0 --- /dev/null +++ b/assets/js/762.2b229c76.js @@ -0,0 +1 @@ +(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[762],{28734:function(t){t.exports=function(){"use strict";return function(t,e){var n=e.prototype,i=n.format;n.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return i.bind(this)(t);var s=this.$utils(),r=(t||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(t){switch(t){case"Q":return Math.ceil((e.$M+1)/3);case"Do":return n.ordinal(e.$D);case"gggg":return e.weekYear();case"GGGG":return e.isoWeekYear();case"wo":return n.ordinal(e.week(),"W");case"w":case"ww":return s.s(e.week(),"w"===t?1:2,"0");case"W":case"WW":return s.s(e.isoWeek(),"W"===t?1:2,"0");case"k":case"kk":return s.s(String(0===e.$H?24:e.$H),"k"===t?1:2,"0");case"X":return Math.floor(e.$d.getTime()/1e3);case"x":return e.$d.getTime();case"z":return"["+e.offsetName()+"]";case"zzz":return"["+e.offsetName("long")+"]";default:return t}}));return i.bind(this)(r)}}}()},10285:function(t){t.exports=function(){"use strict";var t={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\d\d/,i=/\d\d?/,s=/\d*[^-_:/,()\s\d]+/,r={},a=function(t){return(t=+t)+(t>68?1900:2e3)},o=function(t){return function(e){this[t]=+e}},c=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],l=function(t){var e=r[t];return e&&(e.indexOf?e:e.s.concat(e.f))},d=function(t,e){var n,i=r.meridiem;if(i){for(var s=1;s<=24;s+=1)if(t.indexOf(i(s,0,e))>-1){n=s>12;break}}else n=t===(e?"pm":"PM");return n},u={A:[s,function(t){this.afternoon=d(t,!1)}],a:[s,function(t){this.afternoon=d(t,!0)}],S:[/\d/,function(t){this.milliseconds=100*+t}],SS:[n,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[i,o("seconds")],ss:[i,o("seconds")],m:[i,o("minutes")],mm:[i,o("minutes")],H:[i,o("hours")],h:[i,o("hours")],HH:[i,o("hours")],hh:[i,o("hours")],D:[i,o("day")],DD:[n,o("day")],Do:[s,function(t){var e=r.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var i=1;i<=31;i+=1)e(i).replace(/\[|\]/g,"")===t&&(this.day=i)}],M:[i,o("month")],MM:[n,o("month")],MMM:[s,function(t){var e=l("months"),n=(l("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[s,function(t){var e=l("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,o("year")],YY:[n,function(t){this.year=a(t)}],YYYY:[/\d{4}/,o("year")],Z:c,ZZ:c};function h(n){var i,s;i=n,s=r&&r.formats;for(var a=(n=i.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(e,n,i){var r=i&&i.toUpperCase();return n||s[i]||t[i]||s[r].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(e),o=a.length,c=0;c<o;c+=1){var l=a[c],d=u[l],h=d&&d[0],f=d&&d[1];a[c]=f?{regex:h,parser:f}:l.replace(/^\[|\]$/g,"")}return function(t){for(var e={},n=0,i=0;n<o;n+=1){var s=a[n];if("string"==typeof s)i+=s.length;else{var r=s.regex,c=s.parser,l=t.slice(i),d=r.exec(l)[0];c.call(e,d),t=t.replace(d,"")}}return function(t){var e=t.afternoon;if(void 0!==e){var n=t.hours;e?n<12&&(t.hours+=12):12===n&&(t.hours=0),delete t.afternoon}}(e),e}}return function(t,e,n){n.p.customParseFormat=!0,t&&t.parseTwoDigitYear&&(a=t.parseTwoDigitYear);var i=e.prototype,s=i.parse;i.parse=function(t){var e=t.date,i=t.utc,a=t.args;this.$u=i;var o=a[1];if("string"==typeof o){var c=!0===a[2],l=!0===a[3],d=c||l,u=a[2];l&&(u=a[2]),r=this.$locale(),!c&&u&&(r=n.Ls[u]),this.$d=function(t,e,n){try{if(["x","X"].indexOf(e)>-1)return new Date(("X"===e?1e3:1)*t);var i=h(e)(t),s=i.year,r=i.month,a=i.day,o=i.hours,c=i.minutes,l=i.seconds,d=i.milliseconds,u=i.zone,f=new Date,y=a||(s||r?1:f.getDate()),m=s||f.getFullYear(),k=0;s&&!r||(k=r>0?r-1:f.getMonth());var p=o||0,g=c||0,b=l||0,x=d||0;return u?new Date(Date.UTC(m,k,y,p,g,b,x+60*u.offset*1e3)):n?new Date(Date.UTC(m,k,y,p,g,b,x)):new Date(m,k,y,p,g,b,x)}catch(t){return new Date("")}}(e,o,i),this.init(),u&&!0!==u&&(this.$L=this.locale(u).$L),d&&e!=this.format(o)&&(this.$d=new Date("")),r={}}else if(o instanceof Array)for(var f=o.length,y=1;y<=f;y+=1){a[1]=o[y-1];var m=n.apply(this,a);if(m.isValid()){this.$d=m.$d,this.$L=m.$L,this.init();break}y===f&&(this.$d=new Date(""))}else s.call(this,t)}}}()},59542:function(t){t.exports=function(){"use strict";var t="day";return function(e,n,i){var s=function(e){return e.add(4-e.isoWeekday(),t)},r=n.prototype;r.isoWeekYear=function(){return s(this).year()},r.isoWeek=function(e){if(!this.$utils().u(e))return this.add(7*(e-this.isoWeek()),t);var n,r,a,o=s(this),c=(n=this.isoWeekYear(),a=4-(r=(this.$u?i.utc:i)().year(n).startOf("year")).isoWeekday(),r.isoWeekday()>4&&(a+=7),r.add(a,t));return o.diff(c,"week")+1},r.isoWeekday=function(t){return this.$utils().u(t)?this.day()||7:this.day(this.day()%7?t:t-7)};var a=r.startOf;r.startOf=function(t,e){var n=this.$utils(),i=!!n.u(e)||e;return"isoweek"===n.p(t)?i?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):a.bind(this)(t,e)}}}()},80762:(t,e,n)=>{"use strict";n.d(e,{diagram:()=>X});var i=n(17967),s=n(27484),r=n(59542),a=n(10285),o=n(28734),c=n(56363),l=n(64218),d=(n(27856),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,30,32,33,35,37],n=[1,25],i=[1,26],s=[1,27],r=[1,28],a=[1,29],o=[1,30],c=[1,31],l=[1,9],d=[1,10],u=[1,11],h=[1,12],f=[1,13],y=[1,14],m=[1,15],k=[1,16],p=[1,18],g=[1,19],b=[1,20],x=[1,21],T=[1,22],v=[1,24],_=[1,32],w={trace:function(){},yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,dateFormat:19,inclusiveEndDates:20,topAxis:21,axisFormat:22,tickInterval:23,excludes:24,includes:25,todayMarker:26,title:27,acc_title:28,acc_title_value:29,acc_descr:30,acc_descr_value:31,acc_descr_multiline_value:32,section:33,clickStatement:34,taskTxt:35,taskData:36,click:37,callbackname:38,callbackargs:39,href:40,clickStatementDebug:41,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",19:"dateFormat",20:"inclusiveEndDates",21:"topAxis",22:"axisFormat",23:"tickInterval",24:"excludes",25:"includes",26:"todayMarker",27:"title",28:"acc_title",29:"acc_title_value",30:"acc_descr",31:"acc_descr_value",32:"acc_descr_multiline_value",33:"section",35:"taskTxt",36:"taskData",37:"click",38:"callbackname",39:"callbackargs",40:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[34,2],[34,3],[34,3],[34,4],[34,3],[34,4],[34,2],[41,2],[41,3],[41,3],[41,4],[41,3],[41,4],[41,2]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setWeekday("monday");break;case 9:i.setWeekday("tuesday");break;case 10:i.setWeekday("wednesday");break;case 11:i.setWeekday("thursday");break;case 12:i.setWeekday("friday");break;case 13:i.setWeekday("saturday");break;case 14:i.setWeekday("sunday");break;case 15:i.setDateFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 16:i.enableInclusiveEndDates(),this.$=r[o].substr(18);break;case 17:i.TopAxis(),this.$=r[o].substr(8);break;case 18:i.setAxisFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 19:i.setTickInterval(r[o].substr(13)),this.$=r[o].substr(13);break;case 20:i.setExcludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 21:i.setIncludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 22:i.setTodayMarker(r[o].substr(12)),this.$=r[o].substr(12);break;case 24:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 25:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 26:case 27:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 28:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 30:i.addTask(r[o-1],r[o]),this.$="task";break;case 31:this.$=r[o-1],i.setClickEvent(r[o-1],r[o],null);break;case 32:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],r[o]);break;case 33:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],null),i.setLink(r[o-2],r[o]);break;case 34:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-2],r[o-1]),i.setLink(r[o-3],r[o]);break;case 35:this.$=r[o-2],i.setClickEvent(r[o-2],r[o],null),i.setLink(r[o-2],r[o-1]);break;case 36:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-1],r[o]),i.setLink(r[o-3],r[o-2]);break;case 37:this.$=r[o-1],i.setLink(r[o-1],r[o]);break;case 38:case 44:this.$=r[o-1]+" "+r[o];break;case 39:case 40:case 42:this.$=r[o-2]+" "+r[o-1]+" "+r[o];break;case 41:case 43:this.$=r[o-3]+" "+r[o-2]+" "+r[o-1]+" "+r[o]}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:i,14:s,15:r,16:a,17:o,18:c,19:l,20:d,21:u,22:h,23:f,24:y,25:m,26:k,27:p,28:g,30:b,32:x,33:T,34:23,35:v,37:_},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:33,11:17,12:n,13:i,14:s,15:r,16:a,17:o,18:c,19:l,20:d,21:u,22:h,23:f,24:y,25:m,26:k,27:p,28:g,30:b,32:x,33:T,34:23,35:v,37:_},t(e,[2,5]),t(e,[2,6]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),{29:[1,34]},{31:[1,35]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),{36:[1,36]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),{38:[1,37],40:[1,38]},t(e,[2,4]),t(e,[2,25]),t(e,[2,26]),t(e,[2,30]),t(e,[2,31],{39:[1,39],40:[1,40]}),t(e,[2,37],{38:[1,41]}),t(e,[2,32],{40:[1,42]}),t(e,[2,33]),t(e,[2,35],{39:[1,43]}),t(e,[2,34]),t(e,[2,36])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",c=0,l=0,d=r.slice.call(arguments,1),u=Object.create(this.lexer),h={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(h.yy[f]=this.yy[f]);u.setInput(t,h.yy),h.yy.lexer=u,h.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var y=u.yylloc;r.push(y);var m=u.options&&u.options.ranges;"function"==typeof h.yy.parseError?this.parseError=h.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,p,g,b,x,T,v,_,w,$={};;){if(p=n[n.length-1],this.defaultActions[p]?g=this.defaultActions[p]:(null==k&&(w=void 0,"number"!=typeof(w=i.pop()||u.lex()||1)&&(w instanceof Array&&(w=(i=w).pop()),w=e.symbols_[w]||w),k=w),g=a[p]&&a[p][k]),void 0===g||!g.length||!g[0]){var D="";for(x in _=[],a[p])this.terminals_[x]&&x>2&&_.push("'"+this.terminals_[x]+"'");D=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+_.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==k?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(D,{text:u.match,token:this.terminals_[k]||k,line:u.yylineno,loc:y,expected:_})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+k);switch(g[0]){case 1:n.push(k),s.push(u.yytext),r.push(u.yylloc),n.push(g[1]),k=null,l=u.yyleng,o=u.yytext,c=u.yylineno,y=u.yylloc;break;case 2:if(T=this.productions_[g[1]][1],$.$=s[s.length-T],$._$={first_line:r[r.length-(T||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(T||1)].first_column,last_column:r[r.length-1].last_column},m&&($._$.range=[r[r.length-(T||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply($,[o,l,c,h.yy,g[1],s,r].concat(d))))return b;T&&(n=n.slice(0,-1*T*2),s=s.slice(0,-1*T),r=r.slice(0,-1*T)),n.push(this.productions_[g[1]][0]),s.push($.$),r.push($._$),v=a[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},$={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),"open_directive";case 1:return this.begin("acc_title"),28;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),30;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 16:case 19:case 22:case 25:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:case 9:case 10:case 12:case 13:case 14:break;case 11:return 10;case 15:this.begin("href");break;case 17:return 40;case 18:this.begin("callbackname");break;case 20:this.popState(),this.begin("callbackargs");break;case 21:return 38;case 23:return 39;case 24:this.begin("click");break;case 26:return 37;case 27:return 4;case 28:return 19;case 29:return 20;case 30:return 21;case 31:return 22;case 32:return 23;case 33:return 25;case 34:return 24;case 35:return 26;case 36:return 12;case 37:return 13;case 38:return 14;case 39:return 15;case 40:return 16;case 41:return 17;case 42:return 18;case 43:return"date";case 44:return 27;case 45:return"accDescription";case 46:return 33;case 47:return 35;case 48:return 36;case 49:return":";case 50:return 6;case 51:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},callbackargs:{rules:[22,23],inclusive:!1},callbackname:{rules:[19,20,21],inclusive:!1},href:{rules:[16,17],inclusive:!1},click:{rules:[25,26],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,18,24,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],inclusive:!0}}};function D(){this.yy={}}return w.lexer=$,D.prototype=w,w.Parser=D,new D}());d.parser=d;const u=d;s.extend(r),s.extend(a),s.extend(o);let h,f="",y="",m="",k=[],p=[],g={},b=[],x=[],T="",v="";const _=["active","done","crit","milestone"];let w=[],$=!1,D=!1,S="sunday",C=0;const E=function(t,e,n,i){return!i.includes(t.format(e.trim()))&&(!!(t.isoWeekday()>=6&&n.includes("weekends"))||(!!n.includes(t.format("dddd").toLowerCase())||n.includes(t.format(e.trim()))))},M=function(t,e,n,i){if(!n.length||t.manualEndTime)return;let r,a;r=t.startTime instanceof Date?s(t.startTime):s(t.startTime,e,!0),r=r.add(1,"d"),a=t.endTime instanceof Date?s(t.endTime):s(t.endTime,e,!0);const[o,c]=Y(r,a,e,n,i);t.endTime=o.toDate(),t.renderEndTime=c},Y=function(t,e,n,i,s){let r=!1,a=null;for(;t<=e;)r||(a=e.toDate()),r=E(t,n,i,s),r&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,a]},A=function(t,e,n){n=n.trim();const i=/^after\s+([\d\w- ]+)/.exec(n.trim());if(null!==i){let t=null;if(i[1].split(" ").forEach((function(e){let n=N(e);void 0!==n&&(t?n.endTime>t.endTime&&(t=n):t=n)})),t)return t.endTime;{const t=new Date;return t.setHours(0,0,0,0),t}}let r=s(n,e.trim(),!0);if(r.isValid())return r.toDate();{c.l.debug("Invalid date:"+n),c.l.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime())||t.getFullYear()<-1e4||t.getFullYear()>1e4)throw new Error("Invalid date:"+n);return t}},L=function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},F=function(t,e,n,i=!1){n=n.trim();let r=s(n,e.trim(),!0);if(r.isValid())return i&&(r=r.add(1,"d")),r.toDate();let a=s(t);const[o,c]=L(n);if(!Number.isNaN(o)){const t=a.add(o,c);t.isValid()&&(a=t)}return a.toDate()};let I=0;const O=function(t){return void 0===t?(I+=1,"task"+I):t};let W,z,B=[];const P={},N=function(t){const e=P[t];return B[e]},H=function(){const t=function(t){const e=B[t];let n="";switch(B[t].raw.startTime.type){case"prevTaskEnd":{const t=N(e.prevTaskId);e.startTime=t.endTime;break}case"getStartDate":n=A(0,f,B[t].raw.startTime.startData),n&&(B[t].startTime=n)}return B[t].startTime&&(B[t].endTime=F(B[t].startTime,f,B[t].raw.endTime.data,$),B[t].endTime&&(B[t].processed=!0,B[t].manualEndTime=s(B[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),M(B[t],f,p,k))),B[t].processed};let e=!0;for(const[n,i]of B.entries())t(n),e=e&&i.processed;return e},j=function(t,e){t.split(",").forEach((function(t){let n=N(t);void 0!==n&&n.classes.push(e)}))},Z=function(t,e){w.push((function(){const n=document.querySelector(`[id="${t}"]`);null!==n&&n.addEventListener("click",(function(){e()}))}),(function(){const n=document.querySelector(`[id="${t}-text"]`);null!==n&&n.addEventListener("click",(function(){e()}))}))},G={getConfig:()=>(0,c.c)().gantt,clear:function(){b=[],x=[],T="",w=[],I=0,W=void 0,z=void 0,B=[],f="",y="",v="",h=void 0,m="",k=[],p=[],$=!1,D=!1,C=0,g={},(0,c.t)(),S="sunday"},setDateFormat:function(t){f=t},getDateFormat:function(){return f},enableInclusiveEndDates:function(){$=!0},endDatesAreInclusive:function(){return $},enableTopAxis:function(){D=!0},topAxisEnabled:function(){return D},setAxisFormat:function(t){y=t},getAxisFormat:function(){return y},setTickInterval:function(t){h=t},getTickInterval:function(){return h},setTodayMarker:function(t){m=t},getTodayMarker:function(){return m},setAccTitle:c.s,getAccTitle:c.g,setDiagramTitle:c.q,getDiagramTitle:c.r,setDisplayMode:function(t){v=t},getDisplayMode:function(){return v},setAccDescription:c.b,getAccDescription:c.a,addSection:function(t){T=t,b.push(t)},getSections:function(){return b},getTasks:function(){let t=H();let e=0;for(;!t&&e<10;)t=H(),e++;return x=B,x},addTask:function(t,e){const n={section:T,type:T,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},i=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),s={};V(i,s,_);for(let r=0;r<i.length;r++)i[r]=i[r].trim();switch(i.length){case 1:s.id=O(),s.startTime={type:"prevTaskEnd",id:t},s.endTime={data:i[0]};break;case 2:s.id=O(),s.startTime={type:"getStartDate",startData:i[0]},s.endTime={data:i[1]};break;case 3:s.id=O(i[0]),s.startTime={type:"getStartDate",startData:i[1]},s.endTime={data:i[2]}}return s}(z,e);n.raw.startTime=i.startTime,n.raw.endTime=i.endTime,n.id=i.id,n.prevTaskId=z,n.active=i.active,n.done=i.done,n.crit=i.crit,n.milestone=i.milestone,n.order=C,C++;const s=B.push(n);z=n.id,P[n.id]=s-1},findTaskById:N,addTaskOrg:function(t,e){const n={section:T,type:T,description:t,task:t,classes:[]},i=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const i=n.split(","),r={};V(i,r,_);for(let s=0;s<i.length;s++)i[s]=i[s].trim();let a="";switch(i.length){case 1:r.id=O(),r.startTime=t.endTime,a=i[0];break;case 2:r.id=O(),r.startTime=A(0,f,i[0]),a=i[1];break;case 3:r.id=O(i[0]),r.startTime=A(0,f,i[1]),a=i[2]}return a&&(r.endTime=F(r.startTime,f,a,$),r.manualEndTime=s(a,"YYYY-MM-DD",!0).isValid(),M(r,f,p,k)),r}(W,e);n.startTime=i.startTime,n.endTime=i.endTime,n.id=i.id,n.active=i.active,n.done=i.done,n.crit=i.crit,n.milestone=i.milestone,W=n,x.push(n)},setIncludes:function(t){k=t.toLowerCase().split(/[\s,]+/)},getIncludes:function(){return k},setExcludes:function(t){p=t.toLowerCase().split(/[\s,]+/)},getExcludes:function(){return p},setClickEvent:function(t,e,n){t.split(",").forEach((function(t){!function(t,e,n){if("loose"!==(0,c.c)().securityLevel)return;if(void 0===e)return;let i=[];if("string"==typeof n){i=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t<i.length;t++){let e=i[t].trim();'"'===e.charAt(0)&&'"'===e.charAt(e.length-1)&&(e=e.substr(1,e.length-2)),i[t]=e}}0===i.length&&i.push(t),void 0!==N(t)&&Z(t,(()=>{c.u.runFunc(e,...i)}))}(t,e,n)})),j(t,"clickable")},setLink:function(t,e){let n=e;"loose"!==(0,c.c)().securityLevel&&(n=(0,i.Nm)(e)),t.split(",").forEach((function(t){void 0!==N(t)&&(Z(t,(()=>{window.open(n,"_self")})),g[t]=n)})),j(t,"clickable")},getLinks:function(){return g},bindFunctions:function(t){w.forEach((function(e){e(t)}))},parseDuration:L,isInvalidDate:E,setWeekday:function(t){S=t},getWeekday:function(){return S}};function V(t,e,n){let i=!0;for(;i;)i=!1,n.forEach((function(n){const s=new RegExp("^\\s*"+n+"\\s*$");t[0].match(s)&&(e[n]=!0,t.shift(1),i=!0)}))}const q={monday:l.Ox9,tuesday:l.YDX,wednesday:l.EFj,thursday:l.Igq,friday:l.y2j,saturday:l.LqH,sunday:l.Zyz},R=(t,e)=>{let n=[...t].map((()=>-1/0)),i=[...t].sort(((t,e)=>t.startTime-e.startTime||t.order-e.order)),s=0;for(const r of i)for(let t=0;t<n.length;t++)if(r.startTime>=n[t]){n[t]=r.endTime,r.order=t+e,t>s&&(s=t);break}return s};let U;const X={parser:u,db:G,renderer:{setConf:function(){c.l.debug("Something is calling, setConf, remove the call")},draw:function(t,e,n,i){const r=(0,c.c)().gantt,a=(0,c.c)().securityLevel;let o;"sandbox"===a&&(o=(0,l.Ys)("#i"+e));const d="sandbox"===a?(0,l.Ys)(o.nodes()[0].contentDocument.body):(0,l.Ys)("body"),u="sandbox"===a?o.nodes()[0].contentDocument:document,h=u.getElementById(e);U=h.parentElement.offsetWidth,void 0===U&&(U=1200),void 0!==r.useWidth&&(U=r.useWidth);const f=i.db.getTasks();let y=[];for(const s of f)y.push(s.type);y=function(t){const e={},n=[];for(let i=0,s=t.length;i<s;++i)Object.prototype.hasOwnProperty.call(e,t[i])||(e[t[i]]=!0,n.push(t[i]));return n}(y);const m={};let k=2*r.topPadding;if("compact"===i.db.getDisplayMode()||"compact"===r.displayMode){const t={};for(const n of f)void 0===t[n.section]?t[n.section]=[n]:t[n.section].push(n);let e=0;for(const n of Object.keys(t)){const i=R(t[n],e)+1;e+=i,k+=i*(r.barHeight+r.barGap),m[n]=i}}else{k+=f.length*(r.barHeight+r.barGap);for(const t of y)m[t]=f.filter((e=>e.type===t)).length}h.setAttribute("viewBox","0 0 "+U+" "+k);const p=d.select(`[id="${e}"]`),g=(0,l.Xf)().domain([(0,l.VV$)(f,(function(t){return t.startTime})),(0,l.Fp7)(f,(function(t){return t.endTime}))]).rangeRound([0,U-r.leftPadding-r.rightPadding]);f.sort((function(t,e){const n=t.startTime,i=e.startTime;let s=0;return n>i?s=1:n<i&&(s=-1),s})),function(t,n,a){const o=r.barHeight,d=o+r.barGap,h=r.topPadding,f=r.leftPadding;(0,l.BYU)().domain([0,y.length]).range(["#00B9FA","#F95002"]).interpolate(l.JHv);(function(t,e,n,a,o,l,d,u){if(0===d.length&&0===u.length)return;let h,f;for(const{startTime:i,endTime:s}of l)(void 0===h||i<h)&&(h=i),(void 0===f||s>f)&&(f=s);if(!h||!f)return;if(s(f).diff(s(h),"year")>5)return void c.l.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");const y=i.db.getDateFormat(),m=[];let k=null,b=s(h);for(;b.valueOf()<=f;)i.db.isInvalidDate(b,y,d,u)?k?k.end=b:k={start:b,end:b}:k&&(m.push(k),k=null),b=b.add(1,"d");p.append("g").selectAll("rect").data(m).enter().append("rect").attr("id",(function(t){return"exclude-"+t.start.format("YYYY-MM-DD")})).attr("x",(function(t){return g(t.start)+n})).attr("y",r.gridLineStartPadding).attr("width",(function(t){const e=t.end.add(1,"day");return g(e)-g(t.start)})).attr("height",o-e-r.gridLineStartPadding).attr("transform-origin",(function(e,i){return(g(e.start)+n+.5*(g(e.end)-g(e.start))).toString()+"px "+(i*t+.5*o).toString()+"px"})).attr("class","exclude-range")})(d,h,f,0,a,t,i.db.getExcludes(),i.db.getIncludes()),function(t,e,n,s){let a=(0,l.LLu)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,l.i$Z)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));const o=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(i.db.getTickInterval()||r.tickInterval);if(null!==o){const t=o[1],e=o[2],n=i.db.getWeekday()||r.weekday;switch(e){case"millisecond":a.ticks(l.U8T.every(t));break;case"second":a.ticks(l.S1K.every(t));break;case"minute":a.ticks(l.Z_i.every(t));break;case"hour":a.ticks(l.WQD.every(t));break;case"day":a.ticks(l.rr1.every(t));break;case"week":a.ticks(q[n].every(t));break;case"month":a.ticks(l.F0B.every(t))}}if(p.append("g").attr("class","grid").attr("transform","translate("+t+", "+(s-50)+")").call(a).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),i.db.topAxisEnabled()||r.topAxis){let n=(0,l.F5q)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,l.i$Z)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));if(null!==o){const t=o[1],e=o[2],s=i.db.getWeekday()||r.weekday;switch(e){case"millisecond":n.ticks(l.U8T.every(t));break;case"second":n.ticks(l.S1K.every(t));break;case"minute":n.ticks(l.Z_i.every(t));break;case"hour":n.ticks(l.WQD.every(t));break;case"day":n.ticks(l.rr1.every(t));break;case"week":n.ticks(q[s].every(t));break;case"month":n.ticks(l.F0B.every(t))}}p.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}(f,h,0,a),function(t,n,s,a,o,d,u){const h=[...new Set(t.map((t=>t.order)))].map((e=>t.find((t=>t.order===e))));p.append("g").selectAll("rect").data(h).enter().append("rect").attr("x",0).attr("y",(function(t,e){return t.order*n+s-2})).attr("width",(function(){return u-r.rightPadding/2})).attr("height",n).attr("class",(function(t){for(const[e,n]of y.entries())if(t.type===n)return"section section"+e%r.numberSectionStyles;return"section section0"}));const f=p.append("g").selectAll("rect").data(t).enter(),m=i.db.getLinks();f.append("rect").attr("id",(function(t){return t.id})).attr("rx",3).attr("ry",3).attr("x",(function(t){return t.milestone?g(t.startTime)+a+.5*(g(t.endTime)-g(t.startTime))-.5*o:g(t.startTime)+a})).attr("y",(function(t,e){return t.order*n+s})).attr("width",(function(t){return t.milestone?o:g(t.renderEndTime||t.endTime)-g(t.startTime)})).attr("height",o).attr("transform-origin",(function(t,e){return e=t.order,(g(t.startTime)+a+.5*(g(t.endTime)-g(t.startTime))).toString()+"px "+(e*n+s+.5*o).toString()+"px"})).attr("class",(function(t){const e="task";let n="";t.classes.length>0&&(n=t.classes.join(" "));let i=0;for(const[a,o]of y.entries())t.type===o&&(i=a%r.numberSectionStyles);let s="";return t.active?t.crit?s+=" activeCrit":s=" active":t.done?s=t.crit?" doneCrit":" done":t.crit&&(s+=" crit"),0===s.length&&(s=" task"),t.milestone&&(s=" milestone "+s),s+=i,s+=" "+n,e+s})),f.append("text").attr("id",(function(t){return t.id+"-text"})).text((function(t){return t.task})).attr("font-size",r.fontSize).attr("x",(function(t){let e=g(t.startTime),n=g(t.renderEndTime||t.endTime);t.milestone&&(e+=.5*(g(t.endTime)-g(t.startTime))-.5*o),t.milestone&&(n=e+o);const i=this.getBBox().width;return i>n-e?n+i+1.5*r.leftPadding>u?e+a-5:n+a+5:(n-e)/2+e+a})).attr("y",(function(t,e){return t.order*n+r.barHeight/2+(r.fontSize/2-2)+s})).attr("text-height",o).attr("class",(function(t){const e=g(t.startTime);let n=g(t.endTime);t.milestone&&(n=e+o);const i=this.getBBox().width;let s="";t.classes.length>0&&(s=t.classes.join(" "));let a=0;for(const[o,l]of y.entries())t.type===l&&(a=o%r.numberSectionStyles);let c="";return t.active&&(c=t.crit?"activeCritText"+a:"activeText"+a),t.done?c=t.crit?c+" doneCritText"+a:c+" doneText"+a:t.crit&&(c=c+" critText"+a),t.milestone&&(c+=" milestoneText"),i>n-e?n+i+1.5*r.leftPadding>u?s+" taskTextOutsideLeft taskTextOutside"+a+" "+c:s+" taskTextOutsideRight taskTextOutside"+a+" "+c+" width-"+i:s+" taskText taskText"+a+" "+c+" width-"+i}));if("sandbox"===(0,c.c)().securityLevel){let t;t=(0,l.Ys)("#i"+e);const n=t.nodes()[0].contentDocument;f.filter((function(t){return void 0!==m[t.id]})).each((function(t){var e=n.querySelector("#"+t.id),i=n.querySelector("#"+t.id+"-text");const s=e.parentNode;var r=n.createElement("a");r.setAttribute("xlink:href",m[t.id]),r.setAttribute("target","_top"),s.appendChild(r),r.appendChild(e),r.appendChild(i)}))}}(t,d,h,f,o,0,n),function(t,e){let n=0;const i=Object.keys(m).map((t=>[t,m[t]]));p.append("g").selectAll("text").data(i).enter().append((function(t){const e=t[0].split(c.e.lineBreakRegex),n=-(e.length-1)/2,i=u.createElementNS("http://www.w3.org/2000/svg","text");i.setAttribute("dy",n+"em");for(const[s,r]of e.entries()){const t=u.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttribute("alignment-baseline","central"),t.setAttribute("x","10"),s>0&&t.setAttribute("dy","1em"),t.textContent=r,i.appendChild(t)}return i})).attr("x",10).attr("y",(function(s,r){if(!(r>0))return s[1]*t/2+e;for(let a=0;a<r;a++)return n+=i[r-1][1],s[1]*t/2+n*t+e})).attr("font-size",r.sectionFontSize).attr("class",(function(t){for(const[e,n]of y.entries())if(t[0]===n)return"sectionTitle sectionTitle"+e%r.numberSectionStyles;return"sectionTitle"}))}(d,h),function(t,e,n,s){const a=i.db.getTodayMarker();if("off"===a)return;const o=p.append("g").attr("class","today"),c=new Date,l=o.append("line");l.attr("x1",g(c)+t).attr("x2",g(c)+t).attr("y1",r.titleTopMargin).attr("y2",s-r.titleTopMargin).attr("class","today"),""!==a&&l.attr("style",a.replace(/,/g,";"))}(f,0,0,a)}(f,U,k),(0,c.i)(p,k,U,r.useMaxWidth),p.append("text").text(i.db.getDiagramTitle()).attr("x",U/2).attr("y",r.titleTopMargin).attr("class","titleText")}},styles:t=>`\n .mermaid-main-font {\n font-family: "trebuchet ms", verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n // text-height: 14px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n\n // .taskText:not([font-size]) {\n // font-size: ${t.ganttFontSize};\n // }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n // font-size: ${t.ganttFontSize};\n }\n\n /* Special case clickable */\n .task.clickable {\n cursor: pointer;\n }\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor} ;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/762.ba125ab2.js b/assets/js/762.ba125ab2.js new file mode 100644 index 000000000..29e2eb53e --- /dev/null +++ b/assets/js/762.ba125ab2.js @@ -0,0 +1,2106 @@ +exports.id = 762; +exports.ids = [762]; +exports.modules = { + +/***/ 28734: +/***/ (function(module) { + +!function(e,t){ true?module.exports=t():0}(this,(function(){"use strict";return function(e,t){var r=t.prototype,n=r.format;r.format=function(e){var t=this,r=this.$locale();if(!this.isValid())return n.bind(this)(e);var s=this.$utils(),a=(e||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(e){switch(e){case"Q":return Math.ceil((t.$M+1)/3);case"Do":return r.ordinal(t.$D);case"gggg":return t.weekYear();case"GGGG":return t.isoWeekYear();case"wo":return r.ordinal(t.week(),"W");case"w":case"ww":return s.s(t.week(),"w"===e?1:2,"0");case"W":case"WW":return s.s(t.isoWeek(),"W"===e?1:2,"0");case"k":case"kk":return s.s(String(0===t.$H?24:t.$H),"k"===e?1:2,"0");case"X":return Math.floor(t.$d.getTime()/1e3);case"x":return t.$d.getTime();case"z":return"["+t.offsetName()+"]";case"zzz":return"["+t.offsetName("long")+"]";default:return e}}));return n.bind(this)(a)}}})); + +/***/ }), + +/***/ 10285: +/***/ (function(module) { + +!function(e,t){ true?module.exports=t():0}(this,(function(){"use strict";var e={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},t=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\d\d/,r=/\d\d?/,i=/\d*[^-_:/,()\s\d]+/,o={},s=function(e){return(e=+e)+(e>68?1900:2e3)};var a=function(e){return function(t){this[e]=+t}},f=[/[+-]\d\d:?(\d\d)?|Z/,function(e){(this.zone||(this.zone={})).offset=function(e){if(!e)return 0;if("Z"===e)return 0;var t=e.match(/([+-]|\d\d)/g),n=60*t[1]+(+t[2]||0);return 0===n?0:"+"===t[0]?-n:n}(e)}],h=function(e){var t=o[e];return t&&(t.indexOf?t:t.s.concat(t.f))},u=function(e,t){var n,r=o.meridiem;if(r){for(var i=1;i<=24;i+=1)if(e.indexOf(r(i,0,t))>-1){n=i>12;break}}else n=e===(t?"pm":"PM");return n},d={A:[i,function(e){this.afternoon=u(e,!1)}],a:[i,function(e){this.afternoon=u(e,!0)}],S:[/\d/,function(e){this.milliseconds=100*+e}],SS:[n,function(e){this.milliseconds=10*+e}],SSS:[/\d{3}/,function(e){this.milliseconds=+e}],s:[r,a("seconds")],ss:[r,a("seconds")],m:[r,a("minutes")],mm:[r,a("minutes")],H:[r,a("hours")],h:[r,a("hours")],HH:[r,a("hours")],hh:[r,a("hours")],D:[r,a("day")],DD:[n,a("day")],Do:[i,function(e){var t=o.ordinal,n=e.match(/\d+/);if(this.day=n[0],t)for(var r=1;r<=31;r+=1)t(r).replace(/\[|\]/g,"")===e&&(this.day=r)}],M:[r,a("month")],MM:[n,a("month")],MMM:[i,function(e){var t=h("months"),n=(h("monthsShort")||t.map((function(e){return e.slice(0,3)}))).indexOf(e)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[i,function(e){var t=h("months").indexOf(e)+1;if(t<1)throw new Error;this.month=t%12||t}],Y:[/[+-]?\d+/,a("year")],YY:[n,function(e){this.year=s(e)}],YYYY:[/\d{4}/,a("year")],Z:f,ZZ:f};function c(n){var r,i;r=n,i=o&&o.formats;for(var s=(n=r.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,n,r){var o=r&&r.toUpperCase();return n||i[r]||e[r]||i[o].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,n){return t||n.slice(1)}))}))).match(t),a=s.length,f=0;f<a;f+=1){var h=s[f],u=d[h],c=u&&u[0],l=u&&u[1];s[f]=l?{regex:c,parser:l}:h.replace(/^\[|\]$/g,"")}return function(e){for(var t={},n=0,r=0;n<a;n+=1){var i=s[n];if("string"==typeof i)r+=i.length;else{var o=i.regex,f=i.parser,h=e.slice(r),u=o.exec(h)[0];f.call(t,u),e=e.replace(u,"")}}return function(e){var t=e.afternoon;if(void 0!==t){var n=e.hours;t?n<12&&(e.hours+=12):12===n&&(e.hours=0),delete e.afternoon}}(t),t}}return function(e,t,n){n.p.customParseFormat=!0,e&&e.parseTwoDigitYear&&(s=e.parseTwoDigitYear);var r=t.prototype,i=r.parse;r.parse=function(e){var t=e.date,r=e.utc,s=e.args;this.$u=r;var a=s[1];if("string"==typeof a){var f=!0===s[2],h=!0===s[3],u=f||h,d=s[2];h&&(d=s[2]),o=this.$locale(),!f&&d&&(o=n.Ls[d]),this.$d=function(e,t,n){try{if(["x","X"].indexOf(t)>-1)return new Date(("X"===t?1e3:1)*e);var r=c(t)(e),i=r.year,o=r.month,s=r.day,a=r.hours,f=r.minutes,h=r.seconds,u=r.milliseconds,d=r.zone,l=new Date,m=s||(i||o?1:l.getDate()),M=i||l.getFullYear(),Y=0;i&&!o||(Y=o>0?o-1:l.getMonth());var p=a||0,v=f||0,D=h||0,g=u||0;return d?new Date(Date.UTC(M,Y,m,p,v,D,g+60*d.offset*1e3)):n?new Date(Date.UTC(M,Y,m,p,v,D,g)):new Date(M,Y,m,p,v,D,g)}catch(e){return new Date("")}}(t,a,r),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&t!=this.format(a)&&(this.$d=new Date("")),o={}}else if(a instanceof Array)for(var l=a.length,m=1;m<=l;m+=1){s[1]=a[m-1];var M=n.apply(this,s);if(M.isValid()){this.$d=M.$d,this.$L=M.$L,this.init();break}m===l&&(this.$d=new Date(""))}else i.call(this,e)}}})); + +/***/ }), + +/***/ 59542: +/***/ (function(module) { + +!function(e,t){ true?module.exports=t():0}(this,(function(){"use strict";var e="day";return function(t,i,s){var a=function(t){return t.add(4-t.isoWeekday(),e)},d=i.prototype;d.isoWeekYear=function(){return a(this).year()},d.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),e);var i,d,n,o,r=a(this),u=(i=this.isoWeekYear(),d=this.$u,n=(d?s.utc:s)().year(i).startOf("year"),o=4-n.isoWeekday(),n.isoWeekday()>4&&(o+=7),n.add(o,e));return r.diff(u,"week")+1},d.isoWeekday=function(e){return this.$utils().u(e)?this.day()||7:this.day(this.day()%7?e:e-7)};var n=d.startOf;d.startOf=function(e,t){var i=this.$utils(),s=!!i.u(t)||t;return"isoweek"===i.p(e)?s?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):n.bind(this)(e,t)}}})); + +/***/ }), + +/***/ 80762: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(17967); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(27484); +/* harmony import */ var dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(59542); +/* harmony import */ var dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10285); +/* harmony import */ var dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(28734); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(64218); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(20683); + + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [6, 8, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 33, 35, 37], $V1 = [1, 25], $V2 = [1, 26], $V3 = [1, 27], $V4 = [1, 28], $V5 = [1, 29], $V6 = [1, 30], $V7 = [1, 31], $V8 = [1, 9], $V9 = [1, 10], $Va = [1, 11], $Vb = [1, 12], $Vc = [1, 13], $Vd = [1, 14], $Ve = [1, 15], $Vf = [1, 16], $Vg = [1, 18], $Vh = [1, 19], $Vi = [1, 20], $Vj = [1, 21], $Vk = [1, 22], $Vl = [1, 24], $Vm = [1, 32]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "gantt": 4, "document": 5, "EOF": 6, "line": 7, "SPACE": 8, "statement": 9, "NL": 10, "weekday": 11, "weekday_monday": 12, "weekday_tuesday": 13, "weekday_wednesday": 14, "weekday_thursday": 15, "weekday_friday": 16, "weekday_saturday": 17, "weekday_sunday": 18, "dateFormat": 19, "inclusiveEndDates": 20, "topAxis": 21, "axisFormat": 22, "tickInterval": 23, "excludes": 24, "includes": 25, "todayMarker": 26, "title": 27, "acc_title": 28, "acc_title_value": 29, "acc_descr": 30, "acc_descr_value": 31, "acc_descr_multiline_value": 32, "section": 33, "clickStatement": 34, "taskTxt": 35, "taskData": 36, "click": 37, "callbackname": 38, "callbackargs": 39, "href": 40, "clickStatementDebug": 41, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "gantt", 6: "EOF", 8: "SPACE", 10: "NL", 12: "weekday_monday", 13: "weekday_tuesday", 14: "weekday_wednesday", 15: "weekday_thursday", 16: "weekday_friday", 17: "weekday_saturday", 18: "weekday_sunday", 19: "dateFormat", 20: "inclusiveEndDates", 21: "topAxis", 22: "axisFormat", 23: "tickInterval", 24: "excludes", 25: "includes", 26: "todayMarker", 27: "title", 28: "acc_title", 29: "acc_title_value", 30: "acc_descr", 31: "acc_descr_value", 32: "acc_descr_multiline_value", 33: "section", 35: "taskTxt", 36: "taskData", 37: "click", 38: "callbackname", 39: "callbackargs", 40: "href" }, + productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 1], [9, 2], [34, 2], [34, 3], [34, 3], [34, 4], [34, 3], [34, 4], [34, 2], [41, 2], [41, 3], [41, 3], [41, 4], [41, 3], [41, 4], [41, 2]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 1: + return $$[$0 - 1]; + case 2: + this.$ = []; + break; + case 3: + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + break; + case 4: + case 5: + this.$ = $$[$0]; + break; + case 6: + case 7: + this.$ = []; + break; + case 8: + yy.setWeekday("monday"); + break; + case 9: + yy.setWeekday("tuesday"); + break; + case 10: + yy.setWeekday("wednesday"); + break; + case 11: + yy.setWeekday("thursday"); + break; + case 12: + yy.setWeekday("friday"); + break; + case 13: + yy.setWeekday("saturday"); + break; + case 14: + yy.setWeekday("sunday"); + break; + case 15: + yy.setDateFormat($$[$0].substr(11)); + this.$ = $$[$0].substr(11); + break; + case 16: + yy.enableInclusiveEndDates(); + this.$ = $$[$0].substr(18); + break; + case 17: + yy.TopAxis(); + this.$ = $$[$0].substr(8); + break; + case 18: + yy.setAxisFormat($$[$0].substr(11)); + this.$ = $$[$0].substr(11); + break; + case 19: + yy.setTickInterval($$[$0].substr(13)); + this.$ = $$[$0].substr(13); + break; + case 20: + yy.setExcludes($$[$0].substr(9)); + this.$ = $$[$0].substr(9); + break; + case 21: + yy.setIncludes($$[$0].substr(9)); + this.$ = $$[$0].substr(9); + break; + case 22: + yy.setTodayMarker($$[$0].substr(12)); + this.$ = $$[$0].substr(12); + break; + case 24: + yy.setDiagramTitle($$[$0].substr(6)); + this.$ = $$[$0].substr(6); + break; + case 25: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 26: + case 27: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 28: + yy.addSection($$[$0].substr(8)); + this.$ = $$[$0].substr(8); + break; + case 30: + yy.addTask($$[$0 - 1], $$[$0]); + this.$ = "task"; + break; + case 31: + this.$ = $$[$0 - 1]; + yy.setClickEvent($$[$0 - 1], $$[$0], null); + break; + case 32: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]); + break; + case 33: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0 - 1], null); + yy.setLink($$[$0 - 2], $$[$0]); + break; + case 34: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]); + yy.setLink($$[$0 - 3], $$[$0]); + break; + case 35: + this.$ = $$[$0 - 2]; + yy.setClickEvent($$[$0 - 2], $$[$0], null); + yy.setLink($$[$0 - 2], $$[$0 - 1]); + break; + case 36: + this.$ = $$[$0 - 3]; + yy.setClickEvent($$[$0 - 3], $$[$0 - 1], $$[$0]); + yy.setLink($$[$0 - 3], $$[$0 - 2]); + break; + case 37: + this.$ = $$[$0 - 1]; + yy.setLink($$[$0 - 1], $$[$0]); + break; + case 38: + case 44: + this.$ = $$[$0 - 1] + " " + $$[$0]; + break; + case 39: + case 40: + case 42: + this.$ = $$[$0 - 2] + " " + $$[$0 - 1] + " " + $$[$0]; + break; + case 41: + case 43: + this.$ = $$[$0 - 3] + " " + $$[$0 - 2] + " " + $$[$0 - 1] + " " + $$[$0]; + break; + } + }, + table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: 17, 12: $V1, 13: $V2, 14: $V3, 15: $V4, 16: $V5, 17: $V6, 18: $V7, 19: $V8, 20: $V9, 21: $Va, 22: $Vb, 23: $Vc, 24: $Vd, 25: $Ve, 26: $Vf, 27: $Vg, 28: $Vh, 30: $Vi, 32: $Vj, 33: $Vk, 34: 23, 35: $Vl, 37: $Vm }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 33, 11: 17, 12: $V1, 13: $V2, 14: $V3, 15: $V4, 16: $V5, 17: $V6, 18: $V7, 19: $V8, 20: $V9, 21: $Va, 22: $Vb, 23: $Vc, 24: $Vd, 25: $Ve, 26: $Vf, 27: $Vg, 28: $Vh, 30: $Vi, 32: $Vj, 33: $Vk, 34: 23, 35: $Vl, 37: $Vm }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 15]), o($V0, [2, 16]), o($V0, [2, 17]), o($V0, [2, 18]), o($V0, [2, 19]), o($V0, [2, 20]), o($V0, [2, 21]), o($V0, [2, 22]), o($V0, [2, 23]), o($V0, [2, 24]), { 29: [1, 34] }, { 31: [1, 35] }, o($V0, [2, 27]), o($V0, [2, 28]), o($V0, [2, 29]), { 36: [1, 36] }, o($V0, [2, 8]), o($V0, [2, 9]), o($V0, [2, 10]), o($V0, [2, 11]), o($V0, [2, 12]), o($V0, [2, 13]), o($V0, [2, 14]), { 38: [1, 37], 40: [1, 38] }, o($V0, [2, 4]), o($V0, [2, 25]), o($V0, [2, 26]), o($V0, [2, 30]), o($V0, [2, 31], { 39: [1, 39], 40: [1, 40] }), o($V0, [2, 37], { 38: [1, 41] }), o($V0, [2, 32], { 40: [1, 42] }), o($V0, [2, 33]), o($V0, [2, 35], { 39: [1, 43] }), o($V0, [2, 34]), o($V0, [2, 36])], + defaultActions: {}, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + this.begin("open_directive"); + return "open_directive"; + case 1: + this.begin("acc_title"); + return 28; + case 2: + this.popState(); + return "acc_title_value"; + case 3: + this.begin("acc_descr"); + return 30; + case 4: + this.popState(); + return "acc_descr_value"; + case 5: + this.begin("acc_descr_multiline"); + break; + case 6: + this.popState(); + break; + case 7: + return "acc_descr_multiline_value"; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + return 10; + case 12: + break; + case 13: + break; + case 14: + break; + case 15: + this.begin("href"); + break; + case 16: + this.popState(); + break; + case 17: + return 40; + case 18: + this.begin("callbackname"); + break; + case 19: + this.popState(); + break; + case 20: + this.popState(); + this.begin("callbackargs"); + break; + case 21: + return 38; + case 22: + this.popState(); + break; + case 23: + return 39; + case 24: + this.begin("click"); + break; + case 25: + this.popState(); + break; + case 26: + return 37; + case 27: + return 4; + case 28: + return 19; + case 29: + return 20; + case 30: + return 21; + case 31: + return 22; + case 32: + return 23; + case 33: + return 25; + case 34: + return 24; + case 35: + return 26; + case 36: + return 12; + case 37: + return 13; + case 38: + return 14; + case 39: + return 15; + case 40: + return 16; + case 41: + return 17; + case 42: + return 18; + case 43: + return "date"; + case 44: + return 27; + case 45: + return "accDescription"; + case 46: + return 33; + case 47: + return 35; + case 48: + return 36; + case 49: + return ":"; + case 50: + return 6; + case 51: + return "INVALID"; + } + }, + rules: [/^(?:%%\{)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:%%(?!\{)*[^\n]*)/i, /^(?:[^\}]%%*[^\n]*)/i, /^(?:%%*[^\n]*[\n]*)/i, /^(?:[\n]+)/i, /^(?:\s+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:href[\s]+["])/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:call[\s]+)/i, /^(?:\([\s]*\))/i, /^(?:\()/i, /^(?:[^(]*)/i, /^(?:\))/i, /^(?:[^)]*)/i, /^(?:click[\s]+)/i, /^(?:[\s\n])/i, /^(?:[^\s\n]*)/i, /^(?:gantt\b)/i, /^(?:dateFormat\s[^#\n;]+)/i, /^(?:inclusiveEndDates\b)/i, /^(?:topAxis\b)/i, /^(?:axisFormat\s[^#\n;]+)/i, /^(?:tickInterval\s[^#\n;]+)/i, /^(?:includes\s[^#\n;]+)/i, /^(?:excludes\s[^#\n;]+)/i, /^(?:todayMarker\s[^\n;]+)/i, /^(?:weekday\s+monday\b)/i, /^(?:weekday\s+tuesday\b)/i, /^(?:weekday\s+wednesday\b)/i, /^(?:weekday\s+thursday\b)/i, /^(?:weekday\s+friday\b)/i, /^(?:weekday\s+saturday\b)/i, /^(?:weekday\s+sunday\b)/i, /^(?:\d\d\d\d-\d\d-\d\d\b)/i, /^(?:title\s[^#\n;]+)/i, /^(?:accDescription\s[^#\n;]+)/i, /^(?:section\s[^#:\n;]+)/i, /^(?:[^#:\n;]+)/i, /^(?::[^#\n;]+)/i, /^(?::)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "acc_descr_multiline": { "rules": [6, 7], "inclusive": false }, "acc_descr": { "rules": [4], "inclusive": false }, "acc_title": { "rules": [2], "inclusive": false }, "callbackargs": { "rules": [22, 23], "inclusive": false }, "callbackname": { "rules": [19, 20, 21], "inclusive": false }, "href": { "rules": [16, 17], "inclusive": false }, "click": { "rules": [25, 26], "inclusive": false }, "INITIAL": { "rules": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 15, 18, 24, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const ganttParser = parser; +dayjs__WEBPACK_IMPORTED_MODULE_1__.extend(dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_2__); +dayjs__WEBPACK_IMPORTED_MODULE_1__.extend(dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_3__); +dayjs__WEBPACK_IMPORTED_MODULE_1__.extend(dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_4__); +let dateFormat = ""; +let axisFormat = ""; +let tickInterval = void 0; +let todayMarker = ""; +let includes = []; +let excludes = []; +let links = {}; +let sections = []; +let tasks = []; +let currentSection = ""; +let displayMode = ""; +const tags = ["active", "done", "crit", "milestone"]; +let funs = []; +let inclusiveEndDates = false; +let topAxis = false; +let weekday = "sunday"; +let lastOrder = 0; +const clear = function() { + sections = []; + tasks = []; + currentSection = ""; + funs = []; + taskCnt = 0; + lastTask = void 0; + lastTaskID = void 0; + rawTasks = []; + dateFormat = ""; + axisFormat = ""; + displayMode = ""; + tickInterval = void 0; + todayMarker = ""; + includes = []; + excludes = []; + inclusiveEndDates = false; + topAxis = false; + lastOrder = 0; + links = {}; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.t)(); + weekday = "sunday"; +}; +const setAxisFormat = function(txt) { + axisFormat = txt; +}; +const getAxisFormat = function() { + return axisFormat; +}; +const setTickInterval = function(txt) { + tickInterval = txt; +}; +const getTickInterval = function() { + return tickInterval; +}; +const setTodayMarker = function(txt) { + todayMarker = txt; +}; +const getTodayMarker = function() { + return todayMarker; +}; +const setDateFormat = function(txt) { + dateFormat = txt; +}; +const enableInclusiveEndDates = function() { + inclusiveEndDates = true; +}; +const endDatesAreInclusive = function() { + return inclusiveEndDates; +}; +const enableTopAxis = function() { + topAxis = true; +}; +const topAxisEnabled = function() { + return topAxis; +}; +const setDisplayMode = function(txt) { + displayMode = txt; +}; +const getDisplayMode = function() { + return displayMode; +}; +const getDateFormat = function() { + return dateFormat; +}; +const setIncludes = function(txt) { + includes = txt.toLowerCase().split(/[\s,]+/); +}; +const getIncludes = function() { + return includes; +}; +const setExcludes = function(txt) { + excludes = txt.toLowerCase().split(/[\s,]+/); +}; +const getExcludes = function() { + return excludes; +}; +const getLinks = function() { + return links; +}; +const addSection = function(txt) { + currentSection = txt; + sections.push(txt); +}; +const getSections = function() { + return sections; +}; +const getTasks = function() { + let allItemsProcessed = compileTasks(); + const maxDepth = 10; + let iterationCount = 0; + while (!allItemsProcessed && iterationCount < maxDepth) { + allItemsProcessed = compileTasks(); + iterationCount++; + } + tasks = rawTasks; + return tasks; +}; +const isInvalidDate = function(date, dateFormat2, excludes2, includes2) { + if (includes2.includes(date.format(dateFormat2.trim()))) { + return false; + } + if (date.isoWeekday() >= 6 && excludes2.includes("weekends")) { + return true; + } + if (excludes2.includes(date.format("dddd").toLowerCase())) { + return true; + } + return excludes2.includes(date.format(dateFormat2.trim())); +}; +const setWeekday = function(txt) { + weekday = txt; +}; +const getWeekday = function() { + return weekday; +}; +const checkTaskDates = function(task, dateFormat2, excludes2, includes2) { + if (!excludes2.length || task.manualEndTime) { + return; + } + let startTime; + if (task.startTime instanceof Date) { + startTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(task.startTime); + } else { + startTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(task.startTime, dateFormat2, true); + } + startTime = startTime.add(1, "d"); + let originalEndTime; + if (task.endTime instanceof Date) { + originalEndTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(task.endTime); + } else { + originalEndTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(task.endTime, dateFormat2, true); + } + const [fixedEndTime, renderEndTime] = fixTaskDates( + startTime, + originalEndTime, + dateFormat2, + excludes2, + includes2 + ); + task.endTime = fixedEndTime.toDate(); + task.renderEndTime = renderEndTime; +}; +const fixTaskDates = function(startTime, endTime, dateFormat2, excludes2, includes2) { + let invalid = false; + let renderEndTime = null; + while (startTime <= endTime) { + if (!invalid) { + renderEndTime = endTime.toDate(); + } + invalid = isInvalidDate(startTime, dateFormat2, excludes2, includes2); + if (invalid) { + endTime = endTime.add(1, "d"); + } + startTime = startTime.add(1, "d"); + } + return [endTime, renderEndTime]; +}; +const getStartDate = function(prevTime, dateFormat2, str) { + str = str.trim(); + const re = /^after\s+([\d\w- ]+)/; + const afterStatement = re.exec(str.trim()); + if (afterStatement !== null) { + let latestEndingTask = null; + afterStatement[1].split(" ").forEach(function(id) { + let task = findTaskById(id); + if (task !== void 0) { + if (!latestEndingTask) { + latestEndingTask = task; + } else { + if (task.endTime > latestEndingTask.endTime) { + latestEndingTask = task; + } + } + } + }); + if (!latestEndingTask) { + const dt = /* @__PURE__ */ new Date(); + dt.setHours(0, 0, 0, 0); + return dt; + } else { + return latestEndingTask.endTime; + } + } + let mDate = dayjs__WEBPACK_IMPORTED_MODULE_1__(str, dateFormat2.trim(), true); + if (mDate.isValid()) { + return mDate.toDate(); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.debug("Invalid date:" + str); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.debug("With date format:" + dateFormat2.trim()); + const d = new Date(str); + if (d === void 0 || isNaN(d.getTime()) || // WebKit browsers can mis-parse invalid dates to be ridiculously + // huge numbers, e.g. new Date('202304') gets parsed as January 1, 202304. + // This can cause virtually infinite loops while rendering, so for the + // purposes of Gantt charts we'll just treat any date beyond 10,000 AD/BC as + // invalid. + d.getFullYear() < -1e4 || d.getFullYear() > 1e4) { + throw new Error("Invalid date:" + str); + } + return d; + } +}; +const parseDuration = function(str) { + const statement = /^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(str.trim()); + if (statement !== null) { + return [Number.parseFloat(statement[1]), statement[2]]; + } + return [NaN, "ms"]; +}; +const getEndDate = function(prevTime, dateFormat2, str, inclusive = false) { + str = str.trim(); + let mDate = dayjs__WEBPACK_IMPORTED_MODULE_1__(str, dateFormat2.trim(), true); + if (mDate.isValid()) { + if (inclusive) { + mDate = mDate.add(1, "d"); + } + return mDate.toDate(); + } + let endTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(prevTime); + const [durationValue, durationUnit] = parseDuration(str); + if (!Number.isNaN(durationValue)) { + const newEndTime = endTime.add(durationValue, durationUnit); + if (newEndTime.isValid()) { + endTime = newEndTime; + } + } + return endTime.toDate(); +}; +let taskCnt = 0; +const parseId = function(idStr) { + if (idStr === void 0) { + taskCnt = taskCnt + 1; + return "task" + taskCnt; + } + return idStr; +}; +const compileData = function(prevTask, dataStr) { + let ds; + if (dataStr.substr(0, 1) === ":") { + ds = dataStr.substr(1, dataStr.length); + } else { + ds = dataStr; + } + const data = ds.split(","); + const task = {}; + getTaskTags(data, task, tags); + for (let i = 0; i < data.length; i++) { + data[i] = data[i].trim(); + } + let endTimeData = ""; + switch (data.length) { + case 1: + task.id = parseId(); + task.startTime = prevTask.endTime; + endTimeData = data[0]; + break; + case 2: + task.id = parseId(); + task.startTime = getStartDate(void 0, dateFormat, data[0]); + endTimeData = data[1]; + break; + case 3: + task.id = parseId(data[0]); + task.startTime = getStartDate(void 0, dateFormat, data[1]); + endTimeData = data[2]; + break; + } + if (endTimeData) { + task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates); + task.manualEndTime = dayjs__WEBPACK_IMPORTED_MODULE_1__(endTimeData, "YYYY-MM-DD", true).isValid(); + checkTaskDates(task, dateFormat, excludes, includes); + } + return task; +}; +const parseData = function(prevTaskId, dataStr) { + let ds; + if (dataStr.substr(0, 1) === ":") { + ds = dataStr.substr(1, dataStr.length); + } else { + ds = dataStr; + } + const data = ds.split(","); + const task = {}; + getTaskTags(data, task, tags); + for (let i = 0; i < data.length; i++) { + data[i] = data[i].trim(); + } + switch (data.length) { + case 1: + task.id = parseId(); + task.startTime = { + type: "prevTaskEnd", + id: prevTaskId + }; + task.endTime = { + data: data[0] + }; + break; + case 2: + task.id = parseId(); + task.startTime = { + type: "getStartDate", + startData: data[0] + }; + task.endTime = { + data: data[1] + }; + break; + case 3: + task.id = parseId(data[0]); + task.startTime = { + type: "getStartDate", + startData: data[1] + }; + task.endTime = { + data: data[2] + }; + break; + } + return task; +}; +let lastTask; +let lastTaskID; +let rawTasks = []; +const taskDb = {}; +const addTask = function(descr, data) { + const rawTask = { + section: currentSection, + type: currentSection, + processed: false, + manualEndTime: false, + renderEndTime: null, + raw: { data }, + task: descr, + classes: [] + }; + const taskInfo = parseData(lastTaskID, data); + rawTask.raw.startTime = taskInfo.startTime; + rawTask.raw.endTime = taskInfo.endTime; + rawTask.id = taskInfo.id; + rawTask.prevTaskId = lastTaskID; + rawTask.active = taskInfo.active; + rawTask.done = taskInfo.done; + rawTask.crit = taskInfo.crit; + rawTask.milestone = taskInfo.milestone; + rawTask.order = lastOrder; + lastOrder++; + const pos = rawTasks.push(rawTask); + lastTaskID = rawTask.id; + taskDb[rawTask.id] = pos - 1; +}; +const findTaskById = function(id) { + const pos = taskDb[id]; + return rawTasks[pos]; +}; +const addTaskOrg = function(descr, data) { + const newTask = { + section: currentSection, + type: currentSection, + description: descr, + task: descr, + classes: [] + }; + const taskInfo = compileData(lastTask, data); + newTask.startTime = taskInfo.startTime; + newTask.endTime = taskInfo.endTime; + newTask.id = taskInfo.id; + newTask.active = taskInfo.active; + newTask.done = taskInfo.done; + newTask.crit = taskInfo.crit; + newTask.milestone = taskInfo.milestone; + lastTask = newTask; + tasks.push(newTask); +}; +const compileTasks = function() { + const compileTask = function(pos) { + const task = rawTasks[pos]; + let startTime = ""; + switch (rawTasks[pos].raw.startTime.type) { + case "prevTaskEnd": { + const prevTask = findTaskById(task.prevTaskId); + task.startTime = prevTask.endTime; + break; + } + case "getStartDate": + startTime = getStartDate(void 0, dateFormat, rawTasks[pos].raw.startTime.startData); + if (startTime) { + rawTasks[pos].startTime = startTime; + } + break; + } + if (rawTasks[pos].startTime) { + rawTasks[pos].endTime = getEndDate( + rawTasks[pos].startTime, + dateFormat, + rawTasks[pos].raw.endTime.data, + inclusiveEndDates + ); + if (rawTasks[pos].endTime) { + rawTasks[pos].processed = true; + rawTasks[pos].manualEndTime = dayjs__WEBPACK_IMPORTED_MODULE_1__( + rawTasks[pos].raw.endTime.data, + "YYYY-MM-DD", + true + ).isValid(); + checkTaskDates(rawTasks[pos], dateFormat, excludes, includes); + } + } + return rawTasks[pos].processed; + }; + let allProcessed = true; + for (const [i, rawTask] of rawTasks.entries()) { + compileTask(i); + allProcessed = allProcessed && rawTask.processed; + } + return allProcessed; +}; +const setLink = function(ids, _linkStr) { + let linkStr = _linkStr; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel !== "loose") { + linkStr = (0,_braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_0__/* .sanitizeUrl */ .Nm)(_linkStr); + } + ids.split(",").forEach(function(id) { + let rawTask = findTaskById(id); + if (rawTask !== void 0) { + pushFun(id, () => { + window.open(linkStr, "_self"); + }); + links[id] = linkStr; + } + }); + setClass(ids, "clickable"); +}; +const setClass = function(ids, className) { + ids.split(",").forEach(function(id) { + let rawTask = findTaskById(id); + if (rawTask !== void 0) { + rawTask.classes.push(className); + } + }); +}; +const setClickFun = function(id, functionName, functionArgs) { + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel !== "loose") { + return; + } + if (functionName === void 0) { + return; + } + let argList = []; + if (typeof functionArgs === "string") { + argList = functionArgs.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); + for (let i = 0; i < argList.length; i++) { + let item = argList[i].trim(); + if (item.charAt(0) === '"' && item.charAt(item.length - 1) === '"') { + item = item.substr(1, item.length - 2); + } + argList[i] = item; + } + } + if (argList.length === 0) { + argList.push(id); + } + let rawTask = findTaskById(id); + if (rawTask !== void 0) { + pushFun(id, () => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.u.runFunc(functionName, ...argList); + }); + } +}; +const pushFun = function(id, callbackFunction) { + funs.push( + function() { + const elem = document.querySelector(`[id="${id}"]`); + if (elem !== null) { + elem.addEventListener("click", function() { + callbackFunction(); + }); + } + }, + function() { + const elem = document.querySelector(`[id="${id}-text"]`); + if (elem !== null) { + elem.addEventListener("click", function() { + callbackFunction(); + }); + } + } + ); +}; +const setClickEvent = function(ids, functionName, functionArgs) { + ids.split(",").forEach(function(id) { + setClickFun(id, functionName, functionArgs); + }); + setClass(ids, "clickable"); +}; +const bindFunctions = function(element) { + funs.forEach(function(fun) { + fun(element); + }); +}; +const ganttDb = { + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().gantt, + clear, + setDateFormat, + getDateFormat, + enableInclusiveEndDates, + endDatesAreInclusive, + enableTopAxis, + topAxisEnabled, + setAxisFormat, + getAxisFormat, + setTickInterval, + getTickInterval, + setTodayMarker, + getTodayMarker, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.s, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.g, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.r, + setDisplayMode, + getDisplayMode, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.b, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.a, + addSection, + getSections, + getTasks, + addTask, + findTaskById, + addTaskOrg, + setIncludes, + getIncludes, + setExcludes, + getExcludes, + setClickEvent, + setLink, + getLinks, + bindFunctions, + parseDuration, + isInvalidDate, + setWeekday, + getWeekday +}; +function getTaskTags(data, task, tags2) { + let matchFound = true; + while (matchFound) { + matchFound = false; + tags2.forEach(function(t) { + const pattern = "^\\s*" + t + "\\s*$"; + const regex = new RegExp(pattern); + if (data[0].match(regex)) { + task[t] = true; + data.shift(1); + matchFound = true; + } + }); + } +} +const setConf = function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.debug("Something is calling, setConf, remove the call"); +}; +const mapWeekdayToTimeFunction = { + monday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMonday */ .Ox9, + tuesday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeTuesday */ .YDX, + wednesday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeWednesday */ .EFj, + thursday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeThursday */ .Igq, + friday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeFriday */ .y2j, + saturday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeSaturday */ .LqH, + sunday: d3__WEBPACK_IMPORTED_MODULE_5__/* .timeSunday */ .Zyz +}; +const getMaxIntersections = (tasks2, orderOffset) => { + let timeline = [...tasks2].map(() => -Infinity); + let sorted = [...tasks2].sort((a, b) => a.startTime - b.startTime || a.order - b.order); + let maxIntersections = 0; + for (const element of sorted) { + for (let j = 0; j < timeline.length; j++) { + if (element.startTime >= timeline[j]) { + timeline[j] = element.endTime; + element.order = j + orderOffset; + if (j > maxIntersections) { + maxIntersections = j; + } + break; + } + } + } + return maxIntersections; +}; +let w; +const draw = function(text, id, version, diagObj) { + const conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().gantt; + const securityLevel = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .select */ .Ys)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + const elem = doc.getElementById(id); + w = elem.parentElement.offsetWidth; + if (w === void 0) { + w = 1200; + } + if (conf.useWidth !== void 0) { + w = conf.useWidth; + } + const taskArray = diagObj.db.getTasks(); + let categories = []; + for (const element of taskArray) { + categories.push(element.type); + } + categories = checkUnique(categories); + const categoryHeights = {}; + let h = 2 * conf.topPadding; + if (diagObj.db.getDisplayMode() === "compact" || conf.displayMode === "compact") { + const categoryElements = {}; + for (const element of taskArray) { + if (categoryElements[element.section] === void 0) { + categoryElements[element.section] = [element]; + } else { + categoryElements[element.section].push(element); + } + } + let intersections = 0; + for (const category of Object.keys(categoryElements)) { + const categoryHeight = getMaxIntersections(categoryElements[category], intersections) + 1; + intersections += categoryHeight; + h += categoryHeight * (conf.barHeight + conf.barGap); + categoryHeights[category] = categoryHeight; + } + } else { + h += taskArray.length * (conf.barHeight + conf.barGap); + for (const category of categories) { + categoryHeights[category] = taskArray.filter((task) => task.type === category).length; + } + } + elem.setAttribute("viewBox", "0 0 " + w + " " + h); + const svg = root.select(`[id="${id}"]`); + const timeScale = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .scaleTime */ .Xf)().domain([ + (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .min */ .VV$)(taskArray, function(d) { + return d.startTime; + }), + (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .max */ .Fp7)(taskArray, function(d) { + return d.endTime; + }) + ]).rangeRound([0, w - conf.leftPadding - conf.rightPadding]); + function taskCompare(a, b) { + const taskA = a.startTime; + const taskB = b.startTime; + let result = 0; + if (taskA > taskB) { + result = 1; + } else if (taskA < taskB) { + result = -1; + } + return result; + } + taskArray.sort(taskCompare); + makeGant(taskArray, w, h); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.i)(svg, h, w, conf.useMaxWidth); + svg.append("text").text(diagObj.db.getDiagramTitle()).attr("x", w / 2).attr("y", conf.titleTopMargin).attr("class", "titleText"); + function makeGant(tasks2, pageWidth, pageHeight) { + const barHeight = conf.barHeight; + const gap = barHeight + conf.barGap; + const topPadding = conf.topPadding; + const leftPadding = conf.leftPadding; + const colorScale = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .scaleLinear */ .BYU)().domain([0, categories.length]).range(["#00B9FA", "#F95002"]).interpolate(d3__WEBPACK_IMPORTED_MODULE_5__/* .interpolateHcl */ .JHv); + drawExcludeDays( + gap, + topPadding, + leftPadding, + pageWidth, + pageHeight, + tasks2, + diagObj.db.getExcludes(), + diagObj.db.getIncludes() + ); + makeGrid(leftPadding, topPadding, pageWidth, pageHeight); + drawRects(tasks2, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth); + vertLabels(gap, topPadding); + drawToday(leftPadding, topPadding, pageWidth, pageHeight); + } + function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w2) { + const uniqueTaskOrderIds = [...new Set(theArray.map((item) => item.order))]; + const uniqueTasks = uniqueTaskOrderIds.map((id2) => theArray.find((item) => item.order === id2)); + svg.append("g").selectAll("rect").data(uniqueTasks).enter().append("rect").attr("x", 0).attr("y", function(d, i) { + i = d.order; + return i * theGap + theTopPad - 2; + }).attr("width", function() { + return w2 - conf.rightPadding / 2; + }).attr("height", theGap).attr("class", function(d) { + for (const [i, category] of categories.entries()) { + if (d.type === category) { + return "section section" + i % conf.numberSectionStyles; + } + } + return "section section0"; + }); + const rectangles = svg.append("g").selectAll("rect").data(theArray).enter(); + const links2 = diagObj.db.getLinks(); + rectangles.append("rect").attr("id", function(d) { + return d.id; + }).attr("rx", 3).attr("ry", 3).attr("x", function(d) { + if (d.milestone) { + return timeScale(d.startTime) + theSidePad + 0.5 * (timeScale(d.endTime) - timeScale(d.startTime)) - 0.5 * theBarHeight; + } + return timeScale(d.startTime) + theSidePad; + }).attr("y", function(d, i) { + i = d.order; + return i * theGap + theTopPad; + }).attr("width", function(d) { + if (d.milestone) { + return theBarHeight; + } + return timeScale(d.renderEndTime || d.endTime) - timeScale(d.startTime); + }).attr("height", theBarHeight).attr("transform-origin", function(d, i) { + i = d.order; + return (timeScale(d.startTime) + theSidePad + 0.5 * (timeScale(d.endTime) - timeScale(d.startTime))).toString() + "px " + (i * theGap + theTopPad + 0.5 * theBarHeight).toString() + "px"; + }).attr("class", function(d) { + const res = "task"; + let classStr = ""; + if (d.classes.length > 0) { + classStr = d.classes.join(" "); + } + let secNum = 0; + for (const [i, category] of categories.entries()) { + if (d.type === category) { + secNum = i % conf.numberSectionStyles; + } + } + let taskClass = ""; + if (d.active) { + if (d.crit) { + taskClass += " activeCrit"; + } else { + taskClass = " active"; + } + } else if (d.done) { + if (d.crit) { + taskClass = " doneCrit"; + } else { + taskClass = " done"; + } + } else { + if (d.crit) { + taskClass += " crit"; + } + } + if (taskClass.length === 0) { + taskClass = " task"; + } + if (d.milestone) { + taskClass = " milestone " + taskClass; + } + taskClass += secNum; + taskClass += " " + classStr; + return res + taskClass; + }); + rectangles.append("text").attr("id", function(d) { + return d.id + "-text"; + }).text(function(d) { + return d.task; + }).attr("font-size", conf.fontSize).attr("x", function(d) { + let startX = timeScale(d.startTime); + let endX = timeScale(d.renderEndTime || d.endTime); + if (d.milestone) { + startX += 0.5 * (timeScale(d.endTime) - timeScale(d.startTime)) - 0.5 * theBarHeight; + } + if (d.milestone) { + endX = startX + theBarHeight; + } + const textWidth = this.getBBox().width; + if (textWidth > endX - startX) { + if (endX + textWidth + 1.5 * conf.leftPadding > w2) { + return startX + theSidePad - 5; + } else { + return endX + theSidePad + 5; + } + } else { + return (endX - startX) / 2 + startX + theSidePad; + } + }).attr("y", function(d, i) { + i = d.order; + return i * theGap + conf.barHeight / 2 + (conf.fontSize / 2 - 2) + theTopPad; + }).attr("text-height", theBarHeight).attr("class", function(d) { + const startX = timeScale(d.startTime); + let endX = timeScale(d.endTime); + if (d.milestone) { + endX = startX + theBarHeight; + } + const textWidth = this.getBBox().width; + let classStr = ""; + if (d.classes.length > 0) { + classStr = d.classes.join(" "); + } + let secNum = 0; + for (const [i, category] of categories.entries()) { + if (d.type === category) { + secNum = i % conf.numberSectionStyles; + } + } + let taskType = ""; + if (d.active) { + if (d.crit) { + taskType = "activeCritText" + secNum; + } else { + taskType = "activeText" + secNum; + } + } + if (d.done) { + if (d.crit) { + taskType = taskType + " doneCritText" + secNum; + } else { + taskType = taskType + " doneText" + secNum; + } + } else { + if (d.crit) { + taskType = taskType + " critText" + secNum; + } + } + if (d.milestone) { + taskType += " milestoneText"; + } + if (textWidth > endX - startX) { + if (endX + textWidth + 1.5 * conf.leftPadding > w2) { + return classStr + " taskTextOutsideLeft taskTextOutside" + secNum + " " + taskType; + } else { + return classStr + " taskTextOutsideRight taskTextOutside" + secNum + " " + taskType + " width-" + textWidth; + } + } else { + return classStr + " taskText taskText" + secNum + " " + taskType + " width-" + textWidth; + } + }); + const securityLevel2 = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.c)().securityLevel; + if (securityLevel2 === "sandbox") { + let sandboxElement2; + sandboxElement2 = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .select */ .Ys)("#i" + id); + const doc2 = sandboxElement2.nodes()[0].contentDocument; + rectangles.filter(function(d) { + return links2[d.id] !== void 0; + }).each(function(o) { + var taskRect = doc2.querySelector("#" + o.id); + var taskText = doc2.querySelector("#" + o.id + "-text"); + const oldParent = taskRect.parentNode; + var Link = doc2.createElement("a"); + Link.setAttribute("xlink:href", links2[o.id]); + Link.setAttribute("target", "_top"); + oldParent.appendChild(Link); + Link.appendChild(taskRect); + Link.appendChild(taskText); + }); + } + } + function drawExcludeDays(theGap, theTopPad, theSidePad, w2, h2, tasks2, excludes2, includes2) { + if (excludes2.length === 0 && includes2.length === 0) { + return; + } + let minTime; + let maxTime; + for (const { startTime, endTime } of tasks2) { + if (minTime === void 0 || startTime < minTime) { + minTime = startTime; + } + if (maxTime === void 0 || endTime > maxTime) { + maxTime = endTime; + } + } + if (!minTime || !maxTime) { + return; + } + if (dayjs__WEBPACK_IMPORTED_MODULE_1__(maxTime).diff(dayjs__WEBPACK_IMPORTED_MODULE_1__(minTime), "year") > 5) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.l.warn( + "The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days." + ); + return; + } + const dateFormat2 = diagObj.db.getDateFormat(); + const excludeRanges = []; + let range = null; + let d = dayjs__WEBPACK_IMPORTED_MODULE_1__(minTime); + while (d.valueOf() <= maxTime) { + if (diagObj.db.isInvalidDate(d, dateFormat2, excludes2, includes2)) { + if (!range) { + range = { + start: d, + end: d + }; + } else { + range.end = d; + } + } else { + if (range) { + excludeRanges.push(range); + range = null; + } + } + d = d.add(1, "d"); + } + const rectangles = svg.append("g").selectAll("rect").data(excludeRanges).enter(); + rectangles.append("rect").attr("id", function(d2) { + return "exclude-" + d2.start.format("YYYY-MM-DD"); + }).attr("x", function(d2) { + return timeScale(d2.start) + theSidePad; + }).attr("y", conf.gridLineStartPadding).attr("width", function(d2) { + const renderEnd = d2.end.add(1, "day"); + return timeScale(renderEnd) - timeScale(d2.start); + }).attr("height", h2 - theTopPad - conf.gridLineStartPadding).attr("transform-origin", function(d2, i) { + return (timeScale(d2.start) + theSidePad + 0.5 * (timeScale(d2.end) - timeScale(d2.start))).toString() + "px " + (i * theGap + 0.5 * h2).toString() + "px"; + }).attr("class", "exclude-range"); + } + function makeGrid(theSidePad, theTopPad, w2, h2) { + let bottomXAxis = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .axisBottom */ .LLu)(timeScale).tickSize(-h2 + theTopPad + conf.gridLineStartPadding).tickFormat((0,d3__WEBPACK_IMPORTED_MODULE_5__/* .timeFormat */ .i$Z)(diagObj.db.getAxisFormat() || conf.axisFormat || "%Y-%m-%d")); + const reTickInterval = /^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/; + const resultTickInterval = reTickInterval.exec( + diagObj.db.getTickInterval() || conf.tickInterval + ); + if (resultTickInterval !== null) { + const every = resultTickInterval[1]; + const interval = resultTickInterval[2]; + const weekday2 = diagObj.db.getWeekday() || conf.weekday; + switch (interval) { + case "millisecond": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMillisecond */ .U8T.every(every)); + break; + case "second": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeSecond */ .S1K.every(every)); + break; + case "minute": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMinute */ .Z_i.every(every)); + break; + case "hour": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeHour */ .WQD.every(every)); + break; + case "day": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeDay */ .rr1.every(every)); + break; + case "week": + bottomXAxis.ticks(mapWeekdayToTimeFunction[weekday2].every(every)); + break; + case "month": + bottomXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMonth */ .F0B.every(every)); + break; + } + } + svg.append("g").attr("class", "grid").attr("transform", "translate(" + theSidePad + ", " + (h2 - 50) + ")").call(bottomXAxis).selectAll("text").style("text-anchor", "middle").attr("fill", "#000").attr("stroke", "none").attr("font-size", 10).attr("dy", "1em"); + if (diagObj.db.topAxisEnabled() || conf.topAxis) { + let topXAxis = (0,d3__WEBPACK_IMPORTED_MODULE_5__/* .axisTop */ .F5q)(timeScale).tickSize(-h2 + theTopPad + conf.gridLineStartPadding).tickFormat((0,d3__WEBPACK_IMPORTED_MODULE_5__/* .timeFormat */ .i$Z)(diagObj.db.getAxisFormat() || conf.axisFormat || "%Y-%m-%d")); + if (resultTickInterval !== null) { + const every = resultTickInterval[1]; + const interval = resultTickInterval[2]; + const weekday2 = diagObj.db.getWeekday() || conf.weekday; + switch (interval) { + case "millisecond": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMillisecond */ .U8T.every(every)); + break; + case "second": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeSecond */ .S1K.every(every)); + break; + case "minute": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMinute */ .Z_i.every(every)); + break; + case "hour": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeHour */ .WQD.every(every)); + break; + case "day": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeDay */ .rr1.every(every)); + break; + case "week": + topXAxis.ticks(mapWeekdayToTimeFunction[weekday2].every(every)); + break; + case "month": + topXAxis.ticks(d3__WEBPACK_IMPORTED_MODULE_5__/* .timeMonth */ .F0B.every(every)); + break; + } + } + svg.append("g").attr("class", "grid").attr("transform", "translate(" + theSidePad + ", " + theTopPad + ")").call(topXAxis).selectAll("text").style("text-anchor", "middle").attr("fill", "#000").attr("stroke", "none").attr("font-size", 10); + } + } + function vertLabels(theGap, theTopPad) { + let prevGap = 0; + const numOccurances = Object.keys(categoryHeights).map((d) => [d, categoryHeights[d]]); + svg.append("g").selectAll("text").data(numOccurances).enter().append(function(d) { + const rows = d[0].split(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_7__.e.lineBreakRegex); + const dy = -(rows.length - 1) / 2; + const svgLabel = doc.createElementNS("http://www.w3.org/2000/svg", "text"); + svgLabel.setAttribute("dy", dy + "em"); + for (const [j, row] of rows.entries()) { + const tspan = doc.createElementNS("http://www.w3.org/2000/svg", "tspan"); + tspan.setAttribute("alignment-baseline", "central"); + tspan.setAttribute("x", "10"); + if (j > 0) { + tspan.setAttribute("dy", "1em"); + } + tspan.textContent = row; + svgLabel.appendChild(tspan); + } + return svgLabel; + }).attr("x", 10).attr("y", function(d, i) { + if (i > 0) { + for (let j = 0; j < i; j++) { + prevGap += numOccurances[i - 1][1]; + return d[1] * theGap / 2 + prevGap * theGap + theTopPad; + } + } else { + return d[1] * theGap / 2 + theTopPad; + } + }).attr("font-size", conf.sectionFontSize).attr("class", function(d) { + for (const [i, category] of categories.entries()) { + if (d[0] === category) { + return "sectionTitle sectionTitle" + i % conf.numberSectionStyles; + } + } + return "sectionTitle"; + }); + } + function drawToday(theSidePad, theTopPad, w2, h2) { + const todayMarker2 = diagObj.db.getTodayMarker(); + if (todayMarker2 === "off") { + return; + } + const todayG = svg.append("g").attr("class", "today"); + const today = /* @__PURE__ */ new Date(); + const todayLine = todayG.append("line"); + todayLine.attr("x1", timeScale(today) + theSidePad).attr("x2", timeScale(today) + theSidePad).attr("y1", conf.titleTopMargin).attr("y2", h2 - conf.titleTopMargin).attr("class", "today"); + if (todayMarker2 !== "") { + todayLine.attr("style", todayMarker2.replace(/,/g, ";")); + } + } + function checkUnique(arr) { + const hash = {}; + const result = []; + for (let i = 0, l = arr.length; i < l; ++i) { + if (!Object.prototype.hasOwnProperty.call(hash, arr[i])) { + hash[arr[i]] = true; + result.push(arr[i]); + } + } + return result; + } +}; +const ganttRenderer = { + setConf, + draw +}; +const getStyles = (options) => ` + .mermaid-main-font { + font-family: "trebuchet ms", verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + } + .exclude-range { + fill: ${options.excludeBkgColor}; + } + + .section { + stroke: none; + opacity: 0.2; + } + + .section0 { + fill: ${options.sectionBkgColor}; + } + + .section2 { + fill: ${options.sectionBkgColor2}; + } + + .section1, + .section3 { + fill: ${options.altSectionBkgColor}; + opacity: 0.2; + } + + .sectionTitle0 { + fill: ${options.titleColor}; + } + + .sectionTitle1 { + fill: ${options.titleColor}; + } + + .sectionTitle2 { + fill: ${options.titleColor}; + } + + .sectionTitle3 { + fill: ${options.titleColor}; + } + + .sectionTitle { + text-anchor: start; + // font-size: ${options.ganttFontSize}; + // text-height: 14px; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + + } + + + /* Grid and axis */ + + .grid .tick { + stroke: ${options.gridColor}; + opacity: 0.8; + shape-rendering: crispEdges; + text { + font-family: ${options.fontFamily}; + fill: ${options.textColor}; + } + } + + .grid path { + stroke-width: 0; + } + + + /* Today line */ + + .today { + fill: none; + stroke: ${options.todayLineColor}; + stroke-width: 2px; + } + + + /* Task styling */ + + /* Default task */ + + .task { + stroke-width: 2; + } + + .taskText { + text-anchor: middle; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + } + + // .taskText:not([font-size]) { + // font-size: ${options.ganttFontSize}; + // } + + .taskTextOutsideRight { + fill: ${options.taskTextDarkColor}; + text-anchor: start; + // font-size: ${options.ganttFontSize}; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + + } + + .taskTextOutsideLeft { + fill: ${options.taskTextDarkColor}; + text-anchor: end; + // font-size: ${options.ganttFontSize}; + } + + /* Special case clickable */ + .task.clickable { + cursor: pointer; + } + .taskText.clickable { + cursor: pointer; + fill: ${options.taskTextClickableColor} !important; + font-weight: bold; + } + + .taskTextOutsideLeft.clickable { + cursor: pointer; + fill: ${options.taskTextClickableColor} !important; + font-weight: bold; + } + + .taskTextOutsideRight.clickable { + cursor: pointer; + fill: ${options.taskTextClickableColor} !important; + font-weight: bold; + } + + /* Specific task settings for the sections*/ + + .taskText0, + .taskText1, + .taskText2, + .taskText3 { + fill: ${options.taskTextColor}; + } + + .task0, + .task1, + .task2, + .task3 { + fill: ${options.taskBkgColor}; + stroke: ${options.taskBorderColor}; + } + + .taskTextOutside0, + .taskTextOutside2 + { + fill: ${options.taskTextOutsideColor}; + } + + .taskTextOutside1, + .taskTextOutside3 { + fill: ${options.taskTextOutsideColor}; + } + + + /* Active task */ + + .active0, + .active1, + .active2, + .active3 { + fill: ${options.activeTaskBkgColor}; + stroke: ${options.activeTaskBorderColor}; + } + + .activeText0, + .activeText1, + .activeText2, + .activeText3 { + fill: ${options.taskTextDarkColor} !important; + } + + + /* Completed task */ + + .done0, + .done1, + .done2, + .done3 { + stroke: ${options.doneTaskBorderColor}; + fill: ${options.doneTaskBkgColor}; + stroke-width: 2; + } + + .doneText0, + .doneText1, + .doneText2, + .doneText3 { + fill: ${options.taskTextDarkColor} !important; + } + + + /* Tasks on the critical line */ + + .crit0, + .crit1, + .crit2, + .crit3 { + stroke: ${options.critBorderColor}; + fill: ${options.critBkgColor}; + stroke-width: 2; + } + + .activeCrit0, + .activeCrit1, + .activeCrit2, + .activeCrit3 { + stroke: ${options.critBorderColor}; + fill: ${options.activeTaskBkgColor}; + stroke-width: 2; + } + + .doneCrit0, + .doneCrit1, + .doneCrit2, + .doneCrit3 { + stroke: ${options.critBorderColor}; + fill: ${options.doneTaskBkgColor}; + stroke-width: 2; + cursor: pointer; + shape-rendering: crispEdges; + } + + .milestone { + transform: rotate(45deg) scale(0.8,0.8); + } + + .milestoneText { + font-style: italic; + } + .doneCritText0, + .doneCritText1, + .doneCritText2, + .doneCritText3 { + fill: ${options.taskTextDarkColor} !important; + } + + .activeCritText0, + .activeCritText1, + .activeCritText2, + .activeCritText3 { + fill: ${options.taskTextDarkColor} !important; + } + + .titleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor} ; + font-family: 'trebuchet ms', verdana, arial, sans-serif; + font-family: var(--mermaid-font-family); + } +`; +const ganttStyles = getStyles; +const diagram = { + parser: ganttParser, + db: ganttDb, + renderer: ganttRenderer, + styles: ganttStyles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/7707.6b080055.js b/assets/js/7707.6b080055.js new file mode 100644 index 000000000..795819761 --- /dev/null +++ b/assets/js/7707.6b080055.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7707],{27707:(t,e,r)=>{r.d(e,{a:()=>l,b:()=>M,c:()=>o,d:()=>H,e:()=>v,f:()=>I,g:()=>W,h:()=>X,i:()=>f,j:()=>Y,l:()=>d,p:()=>T,s:()=>_,u:()=>c});var a=r(56363),n=r(64218),i=r(74697);const s={extension:(t,e,r)=>{a.l.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},composition:(t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},aggregation:(t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},dependency:(t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},lollipop:(t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},point:(t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},circle:(t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},cross:(t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},barb:(t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")}},l=(t,e,r,a)=>{e.forEach((e=>{s[e](t,r,a)}))};const o=(t,e,r,i)=>{let s=t||"";if("object"==typeof s&&(s=s[0]),(0,a.m)((0,a.c)().flowchart.htmlLabels)){s=s.replace(/\\n|\n/g,"<br />"),a.l.info("vertexText"+s);let t=function(t){const e=(0,n.Ys)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),a=t.label,i=t.isNode?"nodeLabel":"edgeLabel";var s,l;return r.html('<span class="'+i+'" '+(t.labelStyle?'style="'+t.labelStyle+'"':"")+">"+a+"</span>"),s=r,(l=t.labelStyle)&&s.attr("style",l),r.style("display","inline-block"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}({isNode:i,label:(0,a.J)(s).replace(/fa[blrs]?:fa-[\w-]+/g,(t=>`<i class='${t.replace(":"," ")}'></i>`)),labelStyle:e.replace("fill:","color:")});return t}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let a=[];a="string"==typeof s?s.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(s)?s:[];for(const e of a){const a=document.createElementNS("http://www.w3.org/2000/svg","tspan");a.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),a.setAttribute("dy","1em"),a.setAttribute("x","0"),r?a.setAttribute("class","title-row"):a.setAttribute("class","row"),a.textContent=e.trim(),t.appendChild(a)}return t}},d=async(t,e,r,s)=>{let l;const d=e.useHtmlLabels||(0,a.m)((0,a.c)().flowchart.htmlLabels);l=r||"node default";const c=t.insert("g").attr("class",l).attr("id",e.domId||e.id),h=c.insert("g").attr("class","label").attr("style",e.labelStyle);let p;p=void 0===e.labelText?"":"string"==typeof e.labelText?e.labelText:e.labelText[0];const g=h.node();let y;y="markdown"===e.labelType?(0,i.a)(h,(0,a.d)((0,a.J)(p),(0,a.c)()),{useHtmlLabels:d,width:e.width||(0,a.c)().flowchart.wrappingWidth,classes:"markdown-node-label"}):g.appendChild(o((0,a.d)((0,a.J)(p),(0,a.c)()),e.labelStyle,!1,s));let f=y.getBBox();const w=e.padding/2;if((0,a.m)((0,a.c)().flowchart.htmlLabels)){const t=y.children[0],e=(0,n.Ys)(y),r=t.getElementsByTagName("img");if(r){const t=""===p.replace(/<img[^>]*>/g,"").trim();await Promise.all([...r].map((e=>new Promise((r=>{function n(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=(0,a.c)().fontSize?(0,a.c)().fontSize:window.getComputedStyle(document.body).fontSize,r=5;e.style.width=parseInt(t,10)*r+"px"}else e.style.width="100%";r(e)}setTimeout((()=>{e.complete&&n()})),e.addEventListener("error",n),e.addEventListener("load",n)})))))}f=t.getBoundingClientRect(),e.attr("width",f.width),e.attr("height",f.height)}return d?h.attr("transform","translate("+-f.width/2+", "+-f.height/2+")"):h.attr("transform","translate(0, "+-f.height/2+")"),e.centerLabel&&h.attr("transform","translate("+-f.width/2+", "+-f.height/2+")"),h.insert("rect",":first-child"),{shapeSvg:c,bbox:f,halfPadding:w,label:h}},c=(t,e)=>{const r=e.node().getBBox();t.width=r.width,t.height=r.height};function h(t,e,r,a){return t.insert("polygon",":first-child").attr("points",a.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}function p(t,e,r,a){var n=t.x,i=t.y,s=n-a.x,l=i-a.y,o=Math.sqrt(e*e*l*l+r*r*s*s),d=Math.abs(e*r*s/o);a.x<n&&(d=-d);var c=Math.abs(e*r*l/o);return a.y<i&&(c=-c),{x:n+d,y:i+c}}function g(t,e,r,a){var n,i,s,l,o,d,c,h,p,g,f,w,b;if(n=e.y-t.y,s=t.x-e.x,o=e.x*t.y-t.x*e.y,p=n*r.x+s*r.y+o,g=n*a.x+s*a.y+o,!(0!==p&&0!==g&&y(p,g)||(i=a.y-r.y,l=r.x-a.x,d=a.x*r.y-r.x*a.y,c=i*t.x+l*t.y+d,h=i*e.x+l*e.y+d,0!==c&&0!==h&&y(c,h)||0==(f=n*l-i*s))))return w=Math.abs(f/2),{x:(b=s*d-l*o)<0?(b-w)/f:(b+w)/f,y:(b=i*o-n*d)<0?(b-w)/f:(b+w)/f}}function y(t,e){return t*e>0}const f=(t,e)=>{var r,a,n=t.x,i=t.y,s=e.x-n,l=e.y-i,o=t.width/2,d=t.height/2;return Math.abs(l)*o>Math.abs(s)*d?(l<0&&(d=-d),r=0===l?0:d*s/l,a=d):(s<0&&(o=-o),r=o,a=0===s?0:o*l/s),{x:n+r,y:i+a}},w={node:function(t,e){return t.intersect(e)},circle:function(t,e,r){return p(t,e,e,r)},ellipse:p,polygon:function(t,e,r){var a=t.x,n=t.y,i=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){s=Math.min(s,t.x),l=Math.min(l,t.y)})):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var o=a-t.width/2-s,d=n-t.height/2-l,c=0;c<e.length;c++){var h=e[c],p=e[c<e.length-1?c+1:0],y=g(t,r,{x:o+h.x,y:d+h.y},{x:o+p.x,y:d+p.y});y&&i.push(y)}return i.length?(i.length>1&&i.sort((function(t,e){var a=t.x-r.x,n=t.y-r.y,i=Math.sqrt(a*a+n*n),s=e.x-r.x,l=e.y-r.y,o=Math.sqrt(s*s+l*l);return i<o?-1:i===o?0:1})),i[0]):t},rect:f},b=t=>t?" "+t:"",u=(t,e)=>`${e||"node default"}${b(t.classes)} ${b(t.class)}`,x=async(t,e)=>{const{shapeSvg:r,bbox:n}=await d(t,e,u(e,void 0),!0),i=n.width+e.padding+(n.height+e.padding),s=[{x:i/2,y:0},{x:i,y:-i/2},{x:i/2,y:-i},{x:0,y:-i/2}];a.l.info("Question main (Circle)");const l=h(r,i,i,s);return l.attr("style",e.style),c(e,l),e.intersect=function(t){return a.l.warn("Intersect called"),w.polygon(e,s,t)},r};function m(t,e,r,n){const i=[],s=t=>{i.push(t,0)},l=t=>{i.push(0,t)};e.includes("t")?(a.l.debug("add top border"),s(r)):l(r),e.includes("r")?(a.l.debug("add right border"),s(n)):l(n),e.includes("b")?(a.l.debug("add bottom border"),s(r)):l(r),e.includes("l")?(a.l.debug("add left border"),s(n)):l(n),t.attr("stroke-dasharray",i.join(" "))}const k=(t,e,r)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let n=70,i=10;"LR"===r&&(n=10,i=70);const s=a.append("rect").attr("x",-1*n/2).attr("y",-1*i/2).attr("width",n).attr("height",i).attr("class","fork-join");return c(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return w.rect(e,t)},a},L={rhombus:x,question:x,rect:async(t,e)=>{const{shapeSvg:r,bbox:n,halfPadding:i}=await d(t,e,"node "+e.classes+" "+e.class,!0),s=r.insert("rect",":first-child"),l=n.width+e.padding,o=n.height+e.padding;if(s.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",-n.width/2-i).attr("y",-n.height/2-i).attr("width",l).attr("height",o),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(m(s,e.props.borders,l,o),t.delete("borders")),t.forEach((t=>{a.l.warn(`Unknown node property ${t}`)}))}return c(e,s),e.intersect=function(t){return w.rect(e,t)},r},labelRect:async(t,e)=>{const{shapeSvg:r}=await d(t,e,"label",!0);a.l.trace("Classes = ",e.class);const n=r.insert("rect",":first-child");if(n.attr("width",0).attr("height",0),r.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(m(n,e.props.borders,0,0),t.delete("borders")),t.forEach((t=>{a.l.warn(`Unknown node property ${t}`)}))}return c(e,n),e.intersect=function(t){return w.rect(e,t)},r},rectWithTitle:(t,e)=>{let r;r=e.classes?"node "+e.classes:"node default";const i=t.insert("g").attr("class",r).attr("id",e.domId||e.id),s=i.insert("rect",":first-child"),l=i.insert("line"),d=i.insert("g").attr("class","label"),h=e.labelText.flat?e.labelText.flat():e.labelText;let p="";p="object"==typeof h?h[0]:h,a.l.info("Label text abc79",p,h,"object"==typeof h);const g=d.node().appendChild(o(p,e.labelStyle,!0,!0));let y={width:0,height:0};if((0,a.m)((0,a.c)().flowchart.htmlLabels)){const t=g.children[0],e=(0,n.Ys)(g);y=t.getBoundingClientRect(),e.attr("width",y.width),e.attr("height",y.height)}a.l.info("Text 2",h);const f=h.slice(1,h.length);let b=g.getBBox();const u=d.node().appendChild(o(f.join?f.join("<br/>"):f,e.labelStyle,!0,!0));if((0,a.m)((0,a.c)().flowchart.htmlLabels)){const t=u.children[0],e=(0,n.Ys)(u);y=t.getBoundingClientRect(),e.attr("width",y.width),e.attr("height",y.height)}const x=e.padding/2;return(0,n.Ys)(u).attr("transform","translate( "+(y.width>b.width?0:(b.width-y.width)/2)+", "+(b.height+x+5)+")"),(0,n.Ys)(g).attr("transform","translate( "+(y.width<b.width?0:-(b.width-y.width)/2)+", 0)"),y=d.node().getBBox(),d.attr("transform","translate("+-y.width/2+", "+(-y.height/2-x+3)+")"),s.attr("class","outer title-state").attr("x",-y.width/2-x).attr("y",-y.height/2-x).attr("width",y.width+e.padding).attr("height",y.height+e.padding),l.attr("class","divider").attr("x1",-y.width/2-x).attr("x2",y.width/2+x).attr("y1",-y.height/2-x+b.height+x).attr("y2",-y.height/2-x+b.height+x),c(e,s),e.intersect=function(t){return w.rect(e,t)},i},choice:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}];return r.insert("polygon",":first-child").attr("points",a.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return w.circle(e,14,t)},r},circle:async(t,e)=>{const{shapeSvg:r,bbox:n,halfPadding:i}=await d(t,e,u(e,void 0),!0),s=r.insert("circle",":first-child");return s.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),a.l.info("Circle main"),c(e,s),e.intersect=function(t){return a.l.info("Circle intersect",e,n.width/2+i,t),w.circle(e,n.width/2+i,t)},r},doublecircle:async(t,e)=>{const{shapeSvg:r,bbox:n,halfPadding:i}=await d(t,e,u(e,void 0),!0),s=r.insert("g",":first-child"),l=s.insert("circle"),o=s.insert("circle");return s.attr("class",e.class),l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i+5).attr("width",n.width+e.padding+10).attr("height",n.height+e.padding+10),o.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",n.width/2+i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),a.l.info("DoubleCircle main"),c(e,l),e.intersect=function(t){return a.l.info("DoubleCircle intersect",e,n.width/2+i+5,t),w.circle(e,n.width/2+i+5,t)},r},stadium:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.height+e.padding,i=a.width+n/4+e.padding,s=r.insert("rect",":first-child").attr("style",e.style).attr("rx",n/2).attr("ry",n/2).attr("x",-i/2).attr("y",-n/2).attr("width",i).attr("height",n);return c(e,s),e.intersect=function(t){return w.rect(e,t)},r},hexagon:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.height+e.padding,i=n/4,s=a.width+2*i+e.padding,l=[{x:i,y:0},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:i,y:-n},{x:0,y:-n/2}],o=h(r,s,n,l);return o.attr("style",e.style),c(e,o),e.intersect=function(t){return w.polygon(e,l,t)},r},rect_left_inv_arrow:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-i/2,y:0},{x:n,y:0},{x:n,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}];return h(r,n,i,s).attr("style",e.style),e.width=n+i,e.height=i,e.intersect=function(t){return w.polygon(e,s,t)},r},lean_right:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-2*i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:i/6,y:-i}],l=h(r,n,i,s);return l.attr("style",e.style),c(e,l),e.intersect=function(t){return w.polygon(e,s,t)},r},lean_left:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:2*i/6,y:0},{x:n+i/6,y:0},{x:n-2*i/6,y:-i},{x:-i/6,y:-i}],l=h(r,n,i,s);return l.attr("style",e.style),c(e,l),e.intersect=function(t){return w.polygon(e,s,t)},r},trapezoid:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-2*i/6,y:0},{x:n+2*i/6,y:0},{x:n-i/6,y:-i},{x:i/6,y:-i}],l=h(r,n,i,s);return l.attr("style",e.style),c(e,l),e.intersect=function(t){return w.polygon(e,s,t)},r},inv_trapezoid:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:-2*i/6,y:-i}],l=h(r,n,i,s);return l.attr("style",e.style),c(e,l),e.intersect=function(t){return w.polygon(e,s,t)},r},rect_right_inv_arrow:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:0,y:0},{x:n+i/2,y:0},{x:n,y:-i/2},{x:n+i/2,y:-i},{x:0,y:-i}],l=h(r,n,i,s);return l.attr("style",e.style),c(e,l),e.intersect=function(t){return w.polygon(e,s,t)},r},cylinder:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.width+e.padding,i=n/2,s=i/(2.5+n/50),l=a.height+s+e.padding,o="M 0,"+s+" a "+i+","+s+" 0,0,0 "+n+" 0 a "+i+","+s+" 0,0,0 "+-n+" 0 l 0,"+l+" a "+i+","+s+" 0,0,0 "+n+" 0 l 0,"+-l,h=r.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",o).attr("transform","translate("+-n/2+","+-(l/2+s)+")");return c(e,h),e.intersect=function(t){const r=w.rect(e,t),a=r.x-e.x;if(0!=i&&(Math.abs(a)<e.width/2||Math.abs(a)==e.width/2&&Math.abs(r.y-e.y)>e.height/2-s)){let n=s*s*(1-a*a/(i*i));0!=n&&(n=Math.sqrt(n)),n=s-n,t.y-e.y>0&&(n=-n),r.y+=n}return r},r},start:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child");return a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),c(e,a),e.intersect=function(t){return w.circle(e,7,t)},r},end:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child"),n=r.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),a.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),c(e,n),e.intersect=function(t){return w.circle(e,7,t)},r},note:async(t,e)=>{e.useHtmlLabels||(0,a.c)().flowchart.htmlLabels||(e.centerLabel=!0);const{shapeSvg:r,bbox:n,halfPadding:i}=await d(t,e,"node "+e.classes,!0);a.l.info("Classes = ",e.classes);const s=r.insert("rect",":first-child");return s.attr("rx",e.rx).attr("ry",e.ry).attr("x",-n.width/2-i).attr("y",-n.height/2-i).attr("width",n.width+e.padding).attr("height",n.height+e.padding),c(e,s),e.intersect=function(t){return w.rect(e,t)},r},subroutine:async(t,e)=>{const{shapeSvg:r,bbox:a}=await d(t,e,u(e,void 0),!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:0,y:0},{x:n,y:0},{x:n,y:-i},{x:0,y:-i},{x:0,y:0},{x:-8,y:0},{x:n+8,y:0},{x:n+8,y:-i},{x:-8,y:-i},{x:-8,y:0}],l=h(r,n,i,s);return l.attr("style",e.style),c(e,l),e.intersect=function(t){return w.polygon(e,s,t)},r},fork:k,join:k,class_box:(t,e)=>{const r=e.padding/2;let i;i=e.classes?"node "+e.classes:"node default";const s=t.insert("g").attr("class",i).attr("id",e.domId||e.id),l=s.insert("rect",":first-child"),d=s.insert("line"),h=s.insert("line");let p=0,g=4;const y=s.insert("g").attr("class","label");let f=0;const b=e.classData.annotations&&e.classData.annotations[0],u=e.classData.annotations[0]?"\xab"+e.classData.annotations[0]+"\xbb":"",x=y.node().appendChild(o(u,e.labelStyle,!0,!0));let m=x.getBBox();if((0,a.m)((0,a.c)().flowchart.htmlLabels)){const t=x.children[0],e=(0,n.Ys)(x);m=t.getBoundingClientRect(),e.attr("width",m.width),e.attr("height",m.height)}e.classData.annotations[0]&&(g+=m.height+4,p+=m.width);let k=e.classData.label;void 0!==e.classData.type&&""!==e.classData.type&&((0,a.c)().flowchart.htmlLabels?k+="<"+e.classData.type+">":k+="<"+e.classData.type+">");const L=y.node().appendChild(o(k,e.labelStyle,!0,!0));(0,n.Ys)(L).attr("class","classTitle");let S=L.getBBox();if((0,a.m)((0,a.c)().flowchart.htmlLabels)){const t=L.children[0],e=(0,n.Ys)(L);S=t.getBoundingClientRect(),e.attr("width",S.width),e.attr("height",S.height)}g+=S.height+4,S.width>p&&(p=S.width);const v=[];e.classData.members.forEach((t=>{const r=t.getDisplayDetails();let i=r.displayText;(0,a.c)().flowchart.htmlLabels&&(i=i.replace(/</g,"<").replace(/>/g,">"));const s=y.node().appendChild(o(i,r.cssStyle?r.cssStyle:e.labelStyle,!0,!0));let l=s.getBBox();if((0,a.m)((0,a.c)().flowchart.htmlLabels)){const t=s.children[0],e=(0,n.Ys)(s);l=t.getBoundingClientRect(),e.attr("width",l.width),e.attr("height",l.height)}l.width>p&&(p=l.width),g+=l.height+4,v.push(s)})),g+=8;const _=[];if(e.classData.methods.forEach((t=>{const r=t.getDisplayDetails();let i=r.displayText;(0,a.c)().flowchart.htmlLabels&&(i=i.replace(/</g,"<").replace(/>/g,">"));const s=y.node().appendChild(o(i,r.cssStyle?r.cssStyle:e.labelStyle,!0,!0));let l=s.getBBox();if((0,a.m)((0,a.c)().flowchart.htmlLabels)){const t=s.children[0],e=(0,n.Ys)(s);l=t.getBoundingClientRect(),e.attr("width",l.width),e.attr("height",l.height)}l.width>p&&(p=l.width),g+=l.height+4,_.push(s)})),g+=8,b){let t=(p-m.width)/2;(0,n.Ys)(x).attr("transform","translate( "+(-1*p/2+t)+", "+-1*g/2+")"),f=m.height+4}let M=(p-S.width)/2;return(0,n.Ys)(L).attr("transform","translate( "+(-1*p/2+M)+", "+(-1*g/2+f)+")"),f+=S.height+4,d.attr("class","divider").attr("x1",-p/2-r).attr("x2",p/2+r).attr("y1",-g/2-r+8+f).attr("y2",-g/2-r+8+f),f+=8,v.forEach((t=>{(0,n.Ys)(t).attr("transform","translate( "+-p/2+", "+(-1*g/2+f+4)+")");const e=null==t?void 0:t.getBBox();f+=((null==e?void 0:e.height)??0)+4})),f+=8,h.attr("class","divider").attr("x1",-p/2-r).attr("x2",p/2+r).attr("y1",-g/2-r+8+f).attr("y2",-g/2-r+8+f),f+=8,_.forEach((t=>{(0,n.Ys)(t).attr("transform","translate( "+-p/2+", "+(-1*g/2+f)+")");const e=null==t?void 0:t.getBBox();f+=((null==e?void 0:e.height)??0)+4})),l.attr("class","outer title-state").attr("x",-p/2-r).attr("y",-g/2-r).attr("width",p+e.padding).attr("height",g+e.padding),c(e,l),e.intersect=function(t){return w.rect(e,t)},s}};let S={};const v=async(t,e,r)=>{let n,i;if(e.link){let s;"sandbox"===(0,a.c)().securityLevel?s="_top":e.linkTarget&&(s=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",s),i=await L[e.shape](n,e,r)}else i=await L[e.shape](t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),e.class&&i.attr("class","node default "+e.class),S[e.id]=n,e.haveCallback&&S[e.id].attr("class",S[e.id].attr("class")+" clickable"),n},_=(t,e)=>{S[e.id]=t},M=()=>{S={}},T=t=>{const e=S[t.id];a.l.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const r=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+r-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),r},E={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:5.3};function B(t,e){t=C(t),e=C(e);const[r,a]=[t.x,t.y],[n,i]=[e.x,e.y],s=n-r,l=i-a;return{angle:Math.atan(l/s),deltaX:s,deltaY:l}}const C=t=>Array.isArray(t)?{x:t[0],y:t[1]}:t,Y=t=>({x:function(e,r,a){let n=0;if(0===r&&Object.hasOwn(E,t.arrowTypeStart)){const{angle:e,deltaX:r}=B(a[0],a[1]);n=E[t.arrowTypeStart]*Math.cos(e)*(r>=0?1:-1)}else if(r===a.length-1&&Object.hasOwn(E,t.arrowTypeEnd)){const{angle:e,deltaX:r}=B(a[a.length-1],a[a.length-2]);n=E[t.arrowTypeEnd]*Math.cos(e)*(r>=0?1:-1)}return C(e).x+n},y:function(e,r,a){let n=0;if(0===r&&Object.hasOwn(E,t.arrowTypeStart)){const{angle:e,deltaY:r}=B(a[0],a[1]);n=E[t.arrowTypeStart]*Math.abs(Math.sin(e))*(r>=0?1:-1)}else if(r===a.length-1&&Object.hasOwn(E,t.arrowTypeEnd)){const{angle:e,deltaY:r}=B(a[a.length-1],a[a.length-2]);n=E[t.arrowTypeEnd]*Math.abs(Math.sin(e))*(r>=0?1:-1)}return C(e).y+n}});let P={},R={};const H=()=>{P={},R={}},I=(t,e)=>{const r=(0,a.m)((0,a.c)().flowchart.htmlLabels),s="markdown"===e.labelType?(0,i.a)(t,e.label,{style:e.labelStyle,useHtmlLabels:r,addSvgBackground:!0}):o(e.label,e.labelStyle);a.l.info("abc82",e,e.labelType);const l=t.insert("g").attr("class","edgeLabel"),d=l.insert("g").attr("class","label");d.node().appendChild(s);let c,h=s.getBBox();if(r){const t=s.children[0],e=(0,n.Ys)(s);h=t.getBoundingClientRect(),e.attr("width",h.width),e.attr("height",h.height)}if(d.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"),P[e.id]=l,e.width=h.width,e.height=h.height,e.startLabelLeft){const r=o(e.startLabelLeft,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),n=a.insert("g").attr("class","inner");c=n.node().appendChild(r);const i=r.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),R[e.id]||(R[e.id]={}),R[e.id].startLeft=a,O(c,e.startLabelLeft)}if(e.startLabelRight){const r=o(e.startLabelRight,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),n=a.insert("g").attr("class","inner");c=a.node().appendChild(r),n.node().appendChild(r);const i=r.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),R[e.id]||(R[e.id]={}),R[e.id].startRight=a,O(c,e.startLabelRight)}if(e.endLabelLeft){const r=o(e.endLabelLeft,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),n=a.insert("g").attr("class","inner");c=n.node().appendChild(r);const i=r.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),a.node().appendChild(r),R[e.id]||(R[e.id]={}),R[e.id].endLeft=a,O(c,e.endLabelLeft)}if(e.endLabelRight){const r=o(e.endLabelRight,e.labelStyle),a=t.insert("g").attr("class","edgeTerminals"),n=a.insert("g").attr("class","inner");c=n.node().appendChild(r);const i=r.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),a.node().appendChild(r),R[e.id]||(R[e.id]={}),R[e.id].endRight=a,O(c,e.endLabelRight)}return s};function O(t,e){(0,a.c)().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}const X=(t,e)=>{a.l.info("Moving label abc78 ",t.id,t.label,P[t.id]);let r=e.updatedPath?e.updatedPath:e.originalPath;if(t.label){const n=P[t.id];let i=t.x,s=t.y;if(r){const n=a.u.calcLabelPosition(r);a.l.info("Moving label "+t.label+" from (",i,",",s,") to (",n.x,",",n.y,") abc78"),e.updatedPath&&(i=n.x,s=n.y)}n.attr("transform","translate("+i+", "+s+")")}if(t.startLabelLeft){const e=R[t.id].startLeft;let n=t.x,i=t.y;if(r){const e=a.u.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);n=e.x,i=e.y}e.attr("transform","translate("+n+", "+i+")")}if(t.startLabelRight){const e=R[t.id].startRight;let n=t.x,i=t.y;if(r){const e=a.u.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);n=e.x,i=e.y}e.attr("transform","translate("+n+", "+i+")")}if(t.endLabelLeft){const e=R[t.id].endLeft;let n=t.x,i=t.y;if(r){const e=a.u.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);n=e.x,i=e.y}e.attr("transform","translate("+n+", "+i+")")}if(t.endLabelRight){const e=R[t.id].endRight;let n=t.x,i=t.y;if(r){const e=a.u.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);n=e.x,i=e.y}e.attr("transform","translate("+n+", "+i+")")}},$=(t,e)=>{a.l.warn("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach((t=>{if(a.l.info("abc88 checking point",t,e),((t,e)=>{const r=t.x,a=t.y,n=Math.abs(e.x-r),i=Math.abs(e.y-a),s=t.width/2,l=t.height/2;return n>=s||i>=l})(e,t)||i)a.l.warn("abc88 outside",t,n),n=t,i||r.push(t);else{const s=((t,e,r)=>{a.l.warn(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(r)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const n=t.x,i=t.y,s=Math.abs(n-r.x),l=t.width/2;let o=r.x<e.x?l-s:l+s;const d=t.height/2,c=Math.abs(e.y-r.y),h=Math.abs(e.x-r.x);if(Math.abs(i-e.y)*l>Math.abs(n-e.x)*d){let t=r.y<e.y?e.y-d-i:i-d-e.y;o=h*t/c;const n={x:r.x<e.x?r.x+o:r.x-h+o,y:r.y<e.y?r.y+c-t:r.y-c+t};return 0===o&&(n.x=e.x,n.y=e.y),0===h&&(n.x=e.x),0===c&&(n.y=e.y),a.l.warn(`abc89 topp/bott calc, Q ${c}, q ${t}, R ${h}, r ${o}`,n),n}{o=r.x<e.x?e.x-l-n:n-l-e.x;let t=c*o/h,i=r.x<e.x?r.x+h-o:r.x-h+o,s=r.y<e.y?r.y+t:r.y-t;return a.l.warn(`sides calc abc89, Q ${c}, q ${t}, R ${h}, r ${o}`,{_x:i,_y:s}),0===o&&(i=e.x,s=e.y),0===h&&(i=e.x),0===c&&(s=e.y),{x:i,y:s}}})(e,n,t);a.l.warn("abc88 inside",t,n,s),a.l.warn("abc88 intersection",s);let l=!1;r.forEach((t=>{l=l||t.x===s.x&&t.y===s.y})),r.some((t=>t.x===s.x&&t.y===s.y))?a.l.warn("abc88 no intersect",s,r):r.push(s),i=!0}})),a.l.warn("abc88 returning points",r),r},W=function(t,e,r,i,s,l,o){let d=r.points,c=!1;const h=l.node(e.v);var p=l.node(e.w);a.l.info("abc88 InsertEdge: ",r),p.intersect&&h.intersect&&(d=d.slice(1,r.points.length-1),d.unshift(h.intersect(d[0])),a.l.info("Last point",d[d.length-1],p,p.intersect(d[d.length-1])),d.push(p.intersect(d[d.length-1]))),r.toCluster&&(a.l.info("to cluster abc88",i[r.toCluster]),d=$(r.points,i[r.toCluster].node),c=!0),r.fromCluster&&(a.l.info("from cluster abc88",i[r.fromCluster]),d=$(d.reverse(),i[r.fromCluster].node).reverse(),c=!0);const g=d.filter((t=>!Number.isNaN(t.y)));let y=n.$0Z;!r.curve||"graph"!==s&&"flowchart"!==s||(y=r.curve);const{x:f,y:w}=Y(r),b=(0,n.jvg)().x(f).y(w).curve(y);let u;switch(r.thickness){case"normal":u="edge-thickness-normal";break;case"thick":case"invisible":u="edge-thickness-thick";break;default:u=""}switch(r.pattern){case"solid":u+=" edge-pattern-solid";break;case"dotted":u+=" edge-pattern-dotted";break;case"dashed":u+=" edge-pattern-dashed"}const x=t.append("path").attr("d",b(g)).attr("id",r.id).attr("class"," "+u+(r.classes?" "+r.classes:"")).attr("style",r.style);let m="";switch(((0,a.c)().flowchart.arrowMarkerAbsolute||(0,a.c)().state.arrowMarkerAbsolute)&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),a.l.info("arrowTypeStart",r.arrowTypeStart),a.l.info("arrowTypeEnd",r.arrowTypeEnd),r.arrowTypeStart){case"arrow_cross":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-crossStart)");break;case"arrow_point":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-pointStart)");break;case"arrow_barb":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-barbStart)");break;case"arrow_circle":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-circleStart)");break;case"aggregation":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-aggregationStart)");break;case"extension":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-extensionStart)");break;case"composition":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-compositionStart)");break;case"dependency":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-dependencyStart)");break;case"lollipop":x.attr("marker-start","url("+m+"#"+o+"_"+s+"-lollipopStart)")}switch(r.arrowTypeEnd){case"arrow_cross":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-crossEnd)");break;case"arrow_point":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-pointEnd)");break;case"arrow_barb":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-barbEnd)");break;case"arrow_circle":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-circleEnd)");break;case"aggregation":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-aggregationEnd)");break;case"extension":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-extensionEnd)");break;case"composition":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-compositionEnd)");break;case"dependency":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-dependencyEnd)");break;case"lollipop":x.attr("marker-end","url("+m+"#"+o+"_"+s+"-lollipopEnd)")}let k={};return c&&(k.updatedPath=d),k.originalPath=r.points,k}}}]); \ No newline at end of file diff --git a/assets/js/7807.b82574b2.js b/assets/js/7807.b82574b2.js new file mode 100644 index 000000000..b6dd90e97 --- /dev/null +++ b/assets/js/7807.b82574b2.js @@ -0,0 +1,2 @@ +/*! For license information please see 7807.b82574b2.js.LICENSE.txt */ +(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7807],{84182:function(e,t,n){var r;r=function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(t,n){t.exports=e},function(e,t,n){"use strict";var r=n(0).FDLayoutConstants;function i(){}for(var a in r)i[a]=r[a];i.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,i.DEFAULT_RADIAL_SEPARATION=r.DEFAULT_EDGE_LENGTH,i.DEFAULT_COMPONENT_SEPERATION=60,i.TILE=!0,i.TILING_PADDING_VERTICAL=10,i.TILING_PADDING_HORIZONTAL=10,i.TREE_REDUCTION_ON_INCREMENTAL=!1,e.exports=i},function(e,t,n){"use strict";var r=n(0).FDLayoutEdge;function i(e,t,n){r.call(this,e,t,n)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).LGraph;function i(e,t,n){r.call(this,e,t,n)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).LGraphManager;function i(e){r.call(this,e)}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];e.exports=i},function(e,t,n){"use strict";var r=n(0).FDLayoutNode,i=n(0).IMath;function a(e,t,n,i){r.call(this,e,t,n,i)}for(var o in a.prototype=Object.create(r.prototype),r)a[o]=r[o];a.prototype.move=function(){var e=this.graphManager.getLayout();this.displacementX=e.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=e.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>e.coolingFactor*e.maxNodeDisplacement&&(this.displacementX=e.coolingFactor*e.maxNodeDisplacement*i.sign(this.displacementX)),Math.abs(this.displacementY)>e.coolingFactor*e.maxNodeDisplacement&&(this.displacementY=e.coolingFactor*e.maxNodeDisplacement*i.sign(this.displacementY)),null==this.child||0==this.child.getNodes().length?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),e.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},a.prototype.propogateDisplacementToChildren=function(e,t){for(var n,r=this.getChild().getNodes(),i=0;i<r.length;i++)null==(n=r[i]).getChild()?(n.moveBy(e,t),n.displacementX+=e,n.displacementY+=t):n.propogateDisplacementToChildren(e,t)},a.prototype.setPred1=function(e){this.pred1=e},a.prototype.getPred1=function(){return pred1},a.prototype.getPred2=function(){return pred2},a.prototype.setNext=function(e){this.next=e},a.prototype.getNext=function(){return next},a.prototype.setProcessed=function(e){this.processed=e},a.prototype.isProcessed=function(){return processed},e.exports=a},function(e,t,n){"use strict";var r=n(0).FDLayout,i=n(4),a=n(3),o=n(5),s=n(2),l=n(1),u=n(0).FDLayoutConstants,c=n(0).LayoutConstants,h=n(0).Point,d=n(0).PointD,p=n(0).Layout,g=n(0).Integer,f=n(0).IGeometry,v=n(0).LGraph,y=n(0).Transform;function m(){r.call(this),this.toBeTiled={}}for(var b in m.prototype=Object.create(r.prototype),r)m[b]=r[b];m.prototype.newGraphManager=function(){var e=new i(this);return this.graphManager=e,e},m.prototype.newGraph=function(e){return new a(null,this.graphManager,e)},m.prototype.newNode=function(e){return new o(this.graphManager,e)},m.prototype.newEdge=function(e){return new s(null,null,e)},m.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.isSubLayout||(l.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=l.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=l.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.springConstant=u.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=u.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=u.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=u.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=u.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=u.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1,this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/u.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=u.CONVERGENCE_CHECK_PERIOD/this.maxIterations,this.coolingAdjuster=1)},m.prototype.layout=function(){return c.DEFAULT_CREATE_BENDS_AS_NEEDED&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},m.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental)l.TREE_REDUCTION_ON_INCREMENTAL&&(this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation(),t=new Set(this.getAllNodes()),n=this.nodesWithGravity.filter((function(e){return t.has(e)})),this.graphManager.setAllNodesToApplyGravitation(n));else{var e=this.getFlatForest();if(e.length>0)this.positionNodesRadially(e);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var t=new Set(this.getAllNodes()),n=this.nodesWithGravity.filter((function(e){return t.has(e)}));this.graphManager.setAllNodesToApplyGravitation(n),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},m.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}if(this.totalIterations%u.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged()){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}this.coolingCycle++,0==this.layoutQuality?this.coolingAdjuster=this.coolingCycle:1==this.layoutQuality&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var e=new Set(this.getAllNodes()),t=this.nodesWithGravity.filter((function(t){return e.has(t)}));this.graphManager.setAllNodesToApplyGravitation(t),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=u.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=u.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var n=!this.isTreeGrowing&&!this.isGrowthFinished,r=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(n,r),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},m.prototype.getPositionsData=function(){for(var e=this.graphManager.getAllNodes(),t={},n=0;n<e.length;n++){var r=e[n].rect,i=e[n].id;t[i]={id:i,x:r.getCenterX(),y:r.getCenterY(),w:r.width,h:r.height}}return t},m.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var e=!1;if("during"===u.ANIMATE)this.emit("layoutstarted");else{for(;!e;)e=this.tick();this.graphManager.updateBounds()}},m.prototype.calculateNodesToApplyGravitationTo=function(){var e,t,n=[],r=this.graphManager.getGraphs(),i=r.length;for(t=0;t<i;t++)(e=r[t]).updateConnected(),e.isConnected||(n=n.concat(e.getNodes()));return n},m.prototype.createBendpoints=function(){var e=[];e=e.concat(this.graphManager.getAllEdges());var t,n=new Set;for(t=0;t<e.length;t++){var r=e[t];if(!n.has(r)){var i=r.getSource(),a=r.getTarget();if(i==a)r.getBendpoints().push(new d),r.getBendpoints().push(new d),this.createDummyNodesForBendpoints(r),n.add(r);else{var o=[];if(o=(o=o.concat(i.getEdgeListToNode(a))).concat(a.getEdgeListToNode(i)),!n.has(o[0])){var s;if(o.length>1)for(s=0;s<o.length;s++){var l=o[s];l.getBendpoints().push(new d),this.createDummyNodesForBendpoints(l)}o.forEach((function(e){n.add(e)}))}}}if(n.size==e.length)break}},m.prototype.positionNodesRadially=function(e){for(var t=new h(0,0),n=Math.ceil(Math.sqrt(e.length)),r=0,i=0,a=0,o=new d(0,0),s=0;s<e.length;s++){s%n==0&&(a=0,i=r,0!=s&&(i+=l.DEFAULT_COMPONENT_SEPERATION),r=0);var u=e[s],g=p.findCenterOfTree(u);t.x=a,t.y=i,(o=m.radialLayout(u,g,t)).y>r&&(r=Math.floor(o.y)),a=Math.floor(o.x+l.DEFAULT_COMPONENT_SEPERATION)}this.transform(new d(c.WORLD_CENTER_X-o.x/2,c.WORLD_CENTER_Y-o.y/2))},m.radialLayout=function(e,t,n){var r=Math.max(this.maxDiagonalInTree(e),l.DEFAULT_RADIAL_SEPARATION);m.branchRadialLayout(t,null,0,359,0,r);var i=v.calculateBounds(e),a=new y;a.setDeviceOrgX(i.getMinX()),a.setDeviceOrgY(i.getMinY()),a.setWorldOrgX(n.x),a.setWorldOrgY(n.y);for(var o=0;o<e.length;o++)e[o].transform(a);var s=new d(i.getMaxX(),i.getMaxY());return a.inverseTransformPoint(s)},m.branchRadialLayout=function(e,t,n,r,i,a){var o=(r-n+1)/2;o<0&&(o+=180);var s=(o+n)%360*f.TWO_PI/360,l=(Math.cos(s),i*Math.cos(s)),u=i*Math.sin(s);e.setCenter(l,u);var c=[],h=(c=c.concat(e.getEdges())).length;null!=t&&h--;for(var d,p=0,g=c.length,v=e.getEdgesBetween(t);v.length>1;){var y=v[0];v.splice(0,1);var b=c.indexOf(y);b>=0&&c.splice(b,1),g--,h--}d=null!=t?(c.indexOf(v[0])+1)%g:0;for(var x=Math.abs(r-n)/h,w=d;p!=h;w=++w%g){var E=c[w].getOtherEnd(e);if(E!=t){var T=(n+p*x)%360,_=(T+x)%360;m.branchRadialLayout(E,e,T,_,i+a,a),p++}}},m.maxDiagonalInTree=function(e){for(var t=g.MIN_VALUE,n=0;n<e.length;n++){var r=e[n].getDiagonal();r>t&&(t=r)}return t},m.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},m.prototype.groupZeroDegreeMembers=function(){var e=this,t={};this.memberGroups={},this.idToDummyNode={};for(var n=[],r=this.graphManager.getAllNodes(),i=0;i<r.length;i++){var a=(s=r[i]).getParent();0!==this.getNodeDegreeWithChildren(s)||null!=a.id&&this.getToBeTiled(a)||n.push(s)}for(i=0;i<n.length;i++){var s,l=(s=n[i]).getParent().id;void 0===t[l]&&(t[l]=[]),t[l]=t[l].concat(s)}Object.keys(t).forEach((function(n){if(t[n].length>1){var r="DummyCompound_"+n;e.memberGroups[r]=t[n];var i=t[n][0].getParent(),a=new o(e.graphManager);a.id=r,a.paddingLeft=i.paddingLeft||0,a.paddingRight=i.paddingRight||0,a.paddingBottom=i.paddingBottom||0,a.paddingTop=i.paddingTop||0,e.idToDummyNode[r]=a;var s=e.getGraphManager().add(e.newGraph(),a),l=i.getChild();l.add(a);for(var u=0;u<t[n].length;u++){var c=t[n][u];l.remove(c),s.add(c)}}}))},m.prototype.clearCompounds=function(){var e={},t={};this.performDFSOnCompounds();for(var n=0;n<this.compoundOrder.length;n++)t[this.compoundOrder[n].id]=this.compoundOrder[n],e[this.compoundOrder[n].id]=[].concat(this.compoundOrder[n].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[n].getChild()),this.compoundOrder[n].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(e,t)},m.prototype.clearZeroDegreeMembers=function(){var e=this,t=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach((function(n){var r=e.idToDummyNode[n];t[n]=e.tileNodes(e.memberGroups[n],r.paddingLeft+r.paddingRight),r.rect.width=t[n].width,r.rect.height=t[n].height}))},m.prototype.repopulateCompounds=function(){for(var e=this.compoundOrder.length-1;e>=0;e--){var t=this.compoundOrder[e],n=t.id,r=t.paddingLeft,i=t.paddingTop;this.adjustLocations(this.tiledMemberPack[n],t.rect.x,t.rect.y,r,i)}},m.prototype.repopulateZeroDegreeMembers=function(){var e=this,t=this.tiledZeroDegreePack;Object.keys(t).forEach((function(n){var r=e.idToDummyNode[n],i=r.paddingLeft,a=r.paddingTop;e.adjustLocations(t[n],r.rect.x,r.rect.y,i,a)}))},m.prototype.getToBeTiled=function(e){var t=e.id;if(null!=this.toBeTiled[t])return this.toBeTiled[t];var n=e.getChild();if(null==n)return this.toBeTiled[t]=!1,!1;for(var r=n.getNodes(),i=0;i<r.length;i++){var a=r[i];if(this.getNodeDegree(a)>0)return this.toBeTiled[t]=!1,!1;if(null!=a.getChild()){if(!this.getToBeTiled(a))return this.toBeTiled[t]=!1,!1}else this.toBeTiled[a.id]=!1}return this.toBeTiled[t]=!0,!0},m.prototype.getNodeDegree=function(e){e.id;for(var t=e.getEdges(),n=0,r=0;r<t.length;r++){var i=t[r];i.getSource().id!==i.getTarget().id&&(n+=1)}return n},m.prototype.getNodeDegreeWithChildren=function(e){var t=this.getNodeDegree(e);if(null==e.getChild())return t;for(var n=e.getChild().getNodes(),r=0;r<n.length;r++){var i=n[r];t+=this.getNodeDegreeWithChildren(i)}return t},m.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},m.prototype.fillCompexOrderByDFS=function(e){for(var t=0;t<e.length;t++){var n=e[t];null!=n.getChild()&&this.fillCompexOrderByDFS(n.getChild().getNodes()),this.getToBeTiled(n)&&this.compoundOrder.push(n)}},m.prototype.adjustLocations=function(e,t,n,r,i){n+=i;for(var a=t+=r,o=0;o<e.rows.length;o++){var s=e.rows[o];t=a;for(var l=0,u=0;u<s.length;u++){var c=s[u];c.rect.x=t,c.rect.y=n,t+=c.rect.width+e.horizontalPadding,c.rect.height>l&&(l=c.rect.height)}n+=l+e.verticalPadding}},m.prototype.tileCompoundMembers=function(e,t){var n=this;this.tiledMemberPack=[],Object.keys(e).forEach((function(r){var i=t[r];n.tiledMemberPack[r]=n.tileNodes(e[r],i.paddingLeft+i.paddingRight),i.rect.width=n.tiledMemberPack[r].width,i.rect.height=n.tiledMemberPack[r].height}))},m.prototype.tileNodes=function(e,t){var n={rows:[],rowWidth:[],rowHeight:[],width:0,height:t,verticalPadding:l.TILING_PADDING_VERTICAL,horizontalPadding:l.TILING_PADDING_HORIZONTAL};e.sort((function(e,t){return e.rect.width*e.rect.height>t.rect.width*t.rect.height?-1:e.rect.width*e.rect.height<t.rect.width*t.rect.height?1:0}));for(var r=0;r<e.length;r++){var i=e[r];0==n.rows.length?this.insertNodeToRow(n,i,0,t):this.canAddHorizontal(n,i.rect.width,i.rect.height)?this.insertNodeToRow(n,i,this.getShortestRowIndex(n),t):this.insertNodeToRow(n,i,n.rows.length,t),this.shiftToLastRow(n)}return n},m.prototype.insertNodeToRow=function(e,t,n,r){var i=r;n==e.rows.length&&(e.rows.push([]),e.rowWidth.push(i),e.rowHeight.push(0));var a=e.rowWidth[n]+t.rect.width;e.rows[n].length>0&&(a+=e.horizontalPadding),e.rowWidth[n]=a,e.width<a&&(e.width=a);var o=t.rect.height;n>0&&(o+=e.verticalPadding);var s=0;o>e.rowHeight[n]&&(s=e.rowHeight[n],e.rowHeight[n]=o,s=e.rowHeight[n]-s),e.height+=s,e.rows[n].push(t)},m.prototype.getShortestRowIndex=function(e){for(var t=-1,n=Number.MAX_VALUE,r=0;r<e.rows.length;r++)e.rowWidth[r]<n&&(t=r,n=e.rowWidth[r]);return t},m.prototype.getLongestRowIndex=function(e){for(var t=-1,n=Number.MIN_VALUE,r=0;r<e.rows.length;r++)e.rowWidth[r]>n&&(t=r,n=e.rowWidth[r]);return t},m.prototype.canAddHorizontal=function(e,t,n){var r=this.getShortestRowIndex(e);if(r<0)return!0;var i=e.rowWidth[r];if(i+e.horizontalPadding+t<=e.width)return!0;var a,o,s=0;return e.rowHeight[r]<n&&r>0&&(s=n+e.verticalPadding-e.rowHeight[r]),a=e.width-i>=t+e.horizontalPadding?(e.height+s)/(i+t+e.horizontalPadding):(e.height+s)/e.width,s=n+e.verticalPadding,(o=e.width<t?(e.height+s)/t:(e.height+s)/e.width)<1&&(o=1/o),a<1&&(a=1/a),a<o},m.prototype.shiftToLastRow=function(e){var t=this.getLongestRowIndex(e),n=e.rowWidth.length-1,r=e.rows[t],i=r[r.length-1],a=i.width+e.horizontalPadding;if(e.width-e.rowWidth[n]>a&&t!=n){r.splice(-1,1),e.rows[n].push(i),e.rowWidth[t]=e.rowWidth[t]-a,e.rowWidth[n]=e.rowWidth[n]+a,e.width=e.rowWidth[instance.getLongestRowIndex(e)];for(var o=Number.MIN_VALUE,s=0;s<r.length;s++)r[s].height>o&&(o=r[s].height);t>0&&(o+=e.verticalPadding);var l=e.rowHeight[t]+e.rowHeight[n];e.rowHeight[t]=o,e.rowHeight[n]<i.height+e.verticalPadding&&(e.rowHeight[n]=i.height+e.verticalPadding);var u=e.rowHeight[t]+e.rowHeight[n];e.height+=u-l,this.shiftToLastRow(e)}},m.prototype.tilingPreLayout=function(){l.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},m.prototype.tilingPostLayout=function(){l.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},m.prototype.reduceTrees=function(){for(var e,t=[],n=!0;n;){var r=this.graphManager.getAllNodes(),i=[];n=!1;for(var a=0;a<r.length;a++)1!=(e=r[a]).getEdges().length||e.getEdges()[0].isInterGraph||null!=e.getChild()||(i.push([e,e.getEdges()[0],e.getOwner()]),n=!0);if(1==n){for(var o=[],s=0;s<i.length;s++)1==i[s][0].getEdges().length&&(o.push(i[s]),i[s][0].getOwner().remove(i[s][0]));t.push(o),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=t},m.prototype.growTree=function(e){for(var t,n=e[e.length-1],r=0;r<n.length;r++)t=n[r],this.findPlaceforPrunedNode(t),t[2].add(t[0]),t[2].add(t[1],t[1].source,t[1].target);e.splice(e.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},m.prototype.findPlaceforPrunedNode=function(e){var t,n,r=e[0],i=(n=r==e[1].source?e[1].target:e[1].source).startX,a=n.finishX,o=n.startY,s=n.finishY,l=[0,0,0,0];if(o>0)for(var c=i;c<=a;c++)l[0]+=this.grid[c][o-1].length+this.grid[c][o].length-1;if(a<this.grid.length-1)for(c=o;c<=s;c++)l[1]+=this.grid[a+1][c].length+this.grid[a][c].length-1;if(s<this.grid[0].length-1)for(c=i;c<=a;c++)l[2]+=this.grid[c][s+1].length+this.grid[c][s].length-1;if(i>0)for(c=o;c<=s;c++)l[3]+=this.grid[i-1][c].length+this.grid[i][c].length-1;for(var h,d,p=g.MAX_VALUE,f=0;f<l.length;f++)l[f]<p?(p=l[f],h=1,d=f):l[f]==p&&h++;if(3==h&&0==p)0==l[0]&&0==l[1]&&0==l[2]?t=1:0==l[0]&&0==l[1]&&0==l[3]?t=0:0==l[0]&&0==l[2]&&0==l[3]?t=3:0==l[1]&&0==l[2]&&0==l[3]&&(t=2);else if(2==h&&0==p){var v=Math.floor(2*Math.random());t=0==l[0]&&0==l[1]?0==v?0:1:0==l[0]&&0==l[2]?0==v?0:2:0==l[0]&&0==l[3]?0==v?0:3:0==l[1]&&0==l[2]?0==v?1:2:0==l[1]&&0==l[3]?0==v?1:3:0==v?2:3}else t=4==h&&0==p?v=Math.floor(4*Math.random()):d;0==t?r.setCenter(n.getCenterX(),n.getCenterY()-n.getHeight()/2-u.DEFAULT_EDGE_LENGTH-r.getHeight()/2):1==t?r.setCenter(n.getCenterX()+n.getWidth()/2+u.DEFAULT_EDGE_LENGTH+r.getWidth()/2,n.getCenterY()):2==t?r.setCenter(n.getCenterX(),n.getCenterY()+n.getHeight()/2+u.DEFAULT_EDGE_LENGTH+r.getHeight()/2):r.setCenter(n.getCenterX()-n.getWidth()/2-u.DEFAULT_EDGE_LENGTH-r.getWidth()/2,n.getCenterY())},e.exports=m},function(e,t,n){"use strict";var r={};r.layoutBase=n(0),r.CoSEConstants=n(1),r.CoSEEdge=n(2),r.CoSEGraph=n(3),r.CoSEGraphManager=n(4),r.CoSELayout=n(6),r.CoSENode=n(5),e.exports=r}])},e.exports=r(n(82241))},14607:function(e,t,n){var r;r=function(e){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(t,n){t.exports=e},function(e,t,n){"use strict";var r=n(0).layoutBase.LayoutConstants,i=n(0).layoutBase.FDLayoutConstants,a=n(0).CoSEConstants,o=n(0).CoSELayout,s=n(0).CoSENode,l=n(0).layoutBase.PointD,u=n(0).layoutBase.DimensionD,c={ready:function(){},stop:function(){},quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function h(e){this.options=function(e,t){var n={};for(var r in e)n[r]=e[r];for(var r in t)n[r]=t[r];return n}(c,e),d(this.options)}var d=function(e){null!=e.nodeRepulsion&&(a.DEFAULT_REPULSION_STRENGTH=i.DEFAULT_REPULSION_STRENGTH=e.nodeRepulsion),null!=e.idealEdgeLength&&(a.DEFAULT_EDGE_LENGTH=i.DEFAULT_EDGE_LENGTH=e.idealEdgeLength),null!=e.edgeElasticity&&(a.DEFAULT_SPRING_STRENGTH=i.DEFAULT_SPRING_STRENGTH=e.edgeElasticity),null!=e.nestingFactor&&(a.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=e.nestingFactor),null!=e.gravity&&(a.DEFAULT_GRAVITY_STRENGTH=i.DEFAULT_GRAVITY_STRENGTH=e.gravity),null!=e.numIter&&(a.MAX_ITERATIONS=i.MAX_ITERATIONS=e.numIter),null!=e.gravityRange&&(a.DEFAULT_GRAVITY_RANGE_FACTOR=i.DEFAULT_GRAVITY_RANGE_FACTOR=e.gravityRange),null!=e.gravityCompound&&(a.DEFAULT_COMPOUND_GRAVITY_STRENGTH=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=e.gravityCompound),null!=e.gravityRangeCompound&&(a.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=e.gravityRangeCompound),null!=e.initialEnergyOnIncremental&&(a.DEFAULT_COOLING_FACTOR_INCREMENTAL=i.DEFAULT_COOLING_FACTOR_INCREMENTAL=e.initialEnergyOnIncremental),"draft"==e.quality?r.QUALITY=0:"proof"==e.quality?r.QUALITY=2:r.QUALITY=1,a.NODE_DIMENSIONS_INCLUDE_LABELS=i.NODE_DIMENSIONS_INCLUDE_LABELS=r.NODE_DIMENSIONS_INCLUDE_LABELS=e.nodeDimensionsIncludeLabels,a.DEFAULT_INCREMENTAL=i.DEFAULT_INCREMENTAL=r.DEFAULT_INCREMENTAL=!e.randomize,a.ANIMATE=i.ANIMATE=r.ANIMATE=e.animate,a.TILE=e.tile,a.TILING_PADDING_VERTICAL="function"==typeof e.tilingPaddingVertical?e.tilingPaddingVertical.call():e.tilingPaddingVertical,a.TILING_PADDING_HORIZONTAL="function"==typeof e.tilingPaddingHorizontal?e.tilingPaddingHorizontal.call():e.tilingPaddingHorizontal};h.prototype.run=function(){var e,t,n=this.options,r=(this.idToLNode={},this.layout=new o),i=this;i.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var a=r.newGraphManager();this.gm=a;var s=this.options.eles.nodes(),l=this.options.eles.edges();this.root=a.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(s),r);for(var u=0;u<l.length;u++){var c=l[u],h=this.idToLNode[c.data("source")],d=this.idToLNode[c.data("target")];h!==d&&0==h.getEdgesBetween(d).length&&(a.add(r.newEdge(),h,d).id=c.id())}var p=function(e,t){"number"==typeof e&&(e=t);var n=e.data("id"),r=i.idToLNode[n];return{x:r.getRect().getCenterX(),y:r.getRect().getCenterY()}},g=function a(){for(var o,s=function(){n.fit&&n.cy.fit(n.eles,n.padding),e||(e=!0,i.cy.one("layoutready",n.ready),i.cy.trigger({type:"layoutready",layout:i}))},l=i.options.refresh,u=0;u<l&&!o;u++)o=i.stopped||i.layout.tick();if(o)return r.checkLayoutSuccess()&&!r.isSubLayout&&r.doPostLayout(),r.tilingPostLayout&&r.tilingPostLayout(),r.isLayoutFinished=!0,i.options.eles.nodes().positions(p),s(),i.cy.one("layoutstop",i.options.stop),i.cy.trigger({type:"layoutstop",layout:i}),t&&cancelAnimationFrame(t),void(e=!1);var c=i.layout.getPositionsData();n.eles.nodes().positions((function(e,t){if("number"==typeof e&&(e=t),!e.isParent()){for(var n=e.id(),r=c[n],i=e;null==r&&(r=c[i.data("parent")]||c["DummyCompound_"+i.data("parent")],c[n]=r,null!=(i=i.parent()[0])););return null!=r?{x:r.x,y:r.y}:{x:e.position("x"),y:e.position("y")}}})),s(),t=requestAnimationFrame(a)};return r.addListener("layoutstarted",(function(){"during"===i.options.animate&&(t=requestAnimationFrame(g))})),r.runLayout(),"during"!==this.options.animate&&(i.options.eles.nodes().not(":parent").layoutPositions(i,i.options,p),e=!1),this},h.prototype.getTopMostNodes=function(e){for(var t={},n=0;n<e.length;n++)t[e[n].id()]=!0;var r=e.filter((function(e,n){"number"==typeof e&&(e=n);for(var r=e.parent()[0];null!=r;){if(t[r.id()])return!1;r=r.parent()[0]}return!0}));return r},h.prototype.processChildrenList=function(e,t,n){for(var r=t.length,i=0;i<r;i++){var a,o,c=t[i],h=c.children(),d=c.layoutDimensions({nodeDimensionsIncludeLabels:this.options.nodeDimensionsIncludeLabels});if((a=null!=c.outerWidth()&&null!=c.outerHeight()?e.add(new s(n.graphManager,new l(c.position("x")-d.w/2,c.position("y")-d.h/2),new u(parseFloat(d.w),parseFloat(d.h)))):e.add(new s(this.graphManager))).id=c.data("id"),a.paddingLeft=parseInt(c.css("padding")),a.paddingTop=parseInt(c.css("padding")),a.paddingRight=parseInt(c.css("padding")),a.paddingBottom=parseInt(c.css("padding")),this.options.nodeDimensionsIncludeLabels&&c.isParent()){var p=c.boundingBox({includeLabels:!0,includeNodes:!1}).w,g=c.boundingBox({includeLabels:!0,includeNodes:!1}).h,f=c.css("text-halign");a.labelWidth=p,a.labelHeight=g,a.labelPos=f}this.idToLNode[c.data("id")]=a,isNaN(a.rect.x)&&(a.rect.x=0),isNaN(a.rect.y)&&(a.rect.y=0),null!=h&&h.length>0&&(o=n.getGraphManager().add(n.newGraph(),a),this.processChildrenList(o,h,n))}},h.prototype.stop=function(){return this.stopped=!0,this};var p=function(e){e("layout","cose-bilkent",h)};"undefined"!=typeof cytoscape&&p(cytoscape),e.exports=p}])},e.exports=r(n(84182))},71377:function(e,t,n){e.exports=function(){"use strict";function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function i(e,t,n){return t&&r(e.prototype,t),n&&r(e,n),Object.defineProperty(e,"prototype",{writable:!1}),e}function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){return s(e)||l(e,t)||u(e,t)||h()}function s(e){if(Array.isArray(e))return e}function l(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,i,a=[],o=!0,s=!1;try{for(n=n.call(e);!(o=(r=n.next()).done)&&(a.push(r.value),!t||a.length!==t);o=!0);}catch(l){s=!0,i=l}finally{try{o||null==n.return||n.return()}finally{if(s)throw i}}return a}}function u(e,t){if(e){if("string"==typeof e)return c(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(e,t):void 0}}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function h(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var d="undefined"==typeof window?null:window,p=d?d.navigator:null;d&&d.document;var g=e(""),f=e({}),v=e((function(){})),y="undefined"==typeof HTMLElement?"undefined":e(HTMLElement),m=function(e){return e&&e.instanceString&&x(e.instanceString)?e.instanceString():null},b=function(t){return null!=t&&e(t)==g},x=function(t){return null!=t&&e(t)===v},w=function(e){return!N(e)&&(Array.isArray?Array.isArray(e):null!=e&&e instanceof Array)},E=function(t){return null!=t&&e(t)===f&&!w(t)&&t.constructor===Object},T=function(t){return null!=t&&e(t)===f},_=function(t){return null!=t&&e(t)===e(1)&&!isNaN(t)},D=function(e){return _(e)&&Math.floor(e)===e},C=function(e){return"undefined"===y?void 0:null!=e&&e instanceof HTMLElement},N=function(e){return A(e)||L(e)},A=function(e){return"collection"===m(e)&&e._private.single},L=function(e){return"collection"===m(e)&&!e._private.single},S=function(e){return"core"===m(e)},O=function(e){return"stylesheet"===m(e)},I=function(e){return"event"===m(e)},k=function(e){return null==e||!(""!==e&&!e.match(/^\s+$/))},M=function(e){return"undefined"!=typeof HTMLElement&&e instanceof HTMLElement},P=function(e){return E(e)&&_(e.x1)&&_(e.x2)&&_(e.y1)&&_(e.y2)},R=function(e){return T(e)&&x(e.then)},B=function(){return p&&p.userAgent.match(/msie|trident|edge/i)},F=function(e,t){t||(t=function(){if(1===arguments.length)return arguments[0];if(0===arguments.length)return"undefined";for(var e=[],t=0;t<arguments.length;t++)e.push(arguments[t]);return e.join("$")});var n=function n(){var r,i=this,a=arguments,o=t.apply(i,a),s=n.cache;return(r=s[o])||(r=s[o]=e.apply(i,a)),r};return n.cache={},n},z=F((function(e){return e.replace(/([A-Z])/g,(function(e){return"-"+e.toLowerCase()}))})),G=F((function(e){return e.replace(/(-\w)/g,(function(e){return e[1].toUpperCase()}))})),Y=F((function(e,t){return e+t[0].toUpperCase()+t.substring(1)}),(function(e,t){return e+"$"+t})),X=function(e){return k(e)?e:e.charAt(0).toUpperCase()+e.substring(1)},V="(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))",U="rgb[a]?\\(("+V+"[%]?)\\s*,\\s*("+V+"[%]?)\\s*,\\s*("+V+"[%]?)(?:\\s*,\\s*("+V+"))?\\)",j="rgb[a]?\\((?:"+V+"[%]?)\\s*,\\s*(?:"+V+"[%]?)\\s*,\\s*(?:"+V+"[%]?)(?:\\s*,\\s*(?:"+V+"))?\\)",H="hsl[a]?\\(("+V+")\\s*,\\s*("+V+"[%])\\s*,\\s*("+V+"[%])(?:\\s*,\\s*("+V+"))?\\)",q="hsl[a]?\\((?:"+V+")\\s*,\\s*(?:"+V+"[%])\\s*,\\s*(?:"+V+"[%])(?:\\s*,\\s*(?:"+V+"))?\\)",W="\\#[0-9a-fA-F]{3}",$="\\#[0-9a-fA-F]{6}",K=function(e,t){return e<t?-1:e>t?1:0},Z=function(e,t){return-1*K(e,t)},Q=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n<t.length;n++){var r=t[n];if(null!=r)for(var i=Object.keys(r),a=0;a<i.length;a++){var o=i[a];e[o]=r[o]}}return e},J=function(e){if((4===e.length||7===e.length)&&"#"===e[0]){var t,n,r,i=16;return 4===e.length?(t=parseInt(e[1]+e[1],i),n=parseInt(e[2]+e[2],i),r=parseInt(e[3]+e[3],i)):(t=parseInt(e[1]+e[2],i),n=parseInt(e[3]+e[4],i),r=parseInt(e[5]+e[6],i)),[t,n,r]}},ee=function(e){var t,n,r,i,a,o,s,l;function u(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+H+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(i=parseFloat(c[3]))<0||i>100)return;if(i/=100,void 0!==(a=c[4])&&((a=parseFloat(a))<0||a>1))return;if(0===r)o=s=l=Math.round(255*i);else{var h=i<.5?i*(1+r):i+r-i*r,d=2*i-h;o=Math.round(255*u(d,h,n+1/3)),s=Math.round(255*u(d,h,n)),l=Math.round(255*u(d,h,n-1/3))}t=[o,s,l,a]}return t},te=function(e){var t,n=new RegExp("^"+U+"$").exec(e);if(n){t=[];for(var r=[],i=1;i<=3;i++){var a=n[i];if("%"===a[a.length-1]&&(r[i]=!0),a=parseFloat(a),r[i]&&(a=a/100*255),a<0||a>255)return;t.push(Math.floor(a))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t},ne=function(e){return ie[e.toLowerCase()]},re=function(e){return(w(e)?e:null)||ne(e)||J(e)||te(e)||ee(e)},ie={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},ae=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i<r;i++){var a=n[i];if(E(a))throw Error("Tried to set map with object key");i<n.length-1?(null==t[a]&&(t[a]={}),t=t[a]):t[a]=e.value}},oe=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i<r;i++){var a=n[i];if(E(a))throw Error("Tried to get map with object key");if(null==(t=t[a]))return t}return t};function se(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}var le=se,ue="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:"undefined"!=typeof self?self:{};function ce(e,t){return e(t={exports:{}},t.exports),t.exports}var he="object"==typeof ue&&ue&&ue.Object===Object&&ue,de="object"==typeof self&&self&&self.Object===Object&&self,pe=he||de||Function("return this")(),ge=function(){return pe.Date.now()},fe=/\s/;function ve(e){for(var t=e.length;t--&&fe.test(e.charAt(t)););return t}var ye=ve,me=/^\s+/;function be(e){return e?e.slice(0,ye(e)+1).replace(me,""):e}var xe=be,we=pe.Symbol,Ee=Object.prototype,Te=Ee.hasOwnProperty,_e=Ee.toString,De=we?we.toStringTag:void 0;function Ce(e){var t=Te.call(e,De),n=e[De];try{e[De]=void 0;var r=!0}catch(a){}var i=_e.call(e);return r&&(t?e[De]=n:delete e[De]),i}var Ne=Ce,Ae=Object.prototype.toString;function Le(e){return Ae.call(e)}var Se=Le,Oe="[object Null]",Ie="[object Undefined]",ke=we?we.toStringTag:void 0;function Me(e){return null==e?void 0===e?Ie:Oe:ke&&ke in Object(e)?Ne(e):Se(e)}var Pe=Me;function Re(e){return null!=e&&"object"==typeof e}var Be=Re,Fe="[object Symbol]";function ze(e){return"symbol"==typeof e||Be(e)&&Pe(e)==Fe}var Ge=ze,Ye=NaN,Xe=/^[-+]0x[0-9a-f]+$/i,Ve=/^0b[01]+$/i,Ue=/^0o[0-7]+$/i,je=parseInt;function He(e){if("number"==typeof e)return e;if(Ge(e))return Ye;if(le(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=le(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=xe(e);var n=Ve.test(e);return n||Ue.test(e)?je(e.slice(2),n?2:8):Xe.test(e)?Ye:+e}var qe=He,We="Expected a function",$e=Math.max,Ke=Math.min;function Ze(e,t,n){var r,i,a,o,s,l,u=0,c=!1,h=!1,d=!0;if("function"!=typeof e)throw new TypeError(We);function p(t){var n=r,a=i;return r=i=void 0,u=t,o=e.apply(a,n)}function g(e){return u=e,s=setTimeout(y,t),c?p(e):o}function f(e){var n=t-(e-l);return h?Ke(n,a-(e-u)):n}function v(e){var n=e-l;return void 0===l||n>=t||n<0||h&&e-u>=a}function y(){var e=ge();if(v(e))return m(e);s=setTimeout(y,f(e))}function m(e){return s=void 0,d&&r?p(e):(r=i=void 0,o)}function b(){void 0!==s&&clearTimeout(s),u=0,r=l=i=s=void 0}function x(){return void 0===s?o:m(ge())}function w(){var e=ge(),n=v(e);if(r=arguments,i=this,l=e,n){if(void 0===s)return g(l);if(h)return clearTimeout(s),s=setTimeout(y,t),p(l)}return void 0===s&&(s=setTimeout(y,t)),o}return t=qe(t)||0,le(n)&&(c=!!n.leading,a=(h="maxWait"in n)?$e(qe(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),w.cancel=b,w.flush=x,w}var Qe=Ze,Je=d?d.performance:null,et=Je&&Je.now?function(){return Je.now()}:function(){return Date.now()},tt=function(){if(d){if(d.requestAnimationFrame)return function(e){d.requestAnimationFrame(e)};if(d.mozRequestAnimationFrame)return function(e){d.mozRequestAnimationFrame(e)};if(d.webkitRequestAnimationFrame)return function(e){d.webkitRequestAnimationFrame(e)};if(d.msRequestAnimationFrame)return function(e){d.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout((function(){e(et())}),1e3/60)}}(),nt=function(e){return tt(e)},rt=et,it=9261,at=65599,ot=5381,st=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:it;!(t=e.next()).done;)n=n*at+t.value|0;return n},lt=function(e){return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:it)*at+e|0},ut=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ot;return(t<<5)+t+e|0},ct=function(e,t){return 2097152*e+t},ht=function(e){return 2097152*e[0]+e[1]},dt=function(e,t){return[lt(e[0],t[0]),ut(e[1],t[1])]},pt=function(e,t){var n={value:0,done:!1},r=0,i=e.length;return st({next:function(){return r<i?n.value=e[r++]:n.done=!0,n}},t)},gt=function(e,t){var n={value:0,done:!1},r=0,i=e.length;return st({next:function(){return r<i?n.value=e.charCodeAt(r++):n.done=!0,n}},t)},ft=function(){return vt(arguments)},vt=function(e){for(var t,n=0;n<e.length;n++){var r=e[n];t=0===n?gt(r):gt(r,t)}return t},yt=!0,mt=null!=console.warn,bt=null!=console.trace,xt=Number.MAX_SAFE_INTEGER||9007199254740991,wt=function(){return!0},Et=function(){return!1},Tt=function(){return 0},_t=function(){},Dt=function(e){throw new Error(e)},Ct=function(e){if(void 0===e)return yt;yt=!!e},Nt=function(e){Ct()&&(mt?console.warn(e):(console.log(e),bt&&console.trace()))},At=function(e){return Q({},e)},Lt=function(e){return null==e?e:w(e)?e.slice():E(e)?At(e):e},St=function(e){return e.slice()},Ot=function(e,t){for(t=e="";e++<36;t+=51*e&52?(15^e?8^Math.random()*(20^e?16:4):4).toString(16):"-");return t},It={},kt=function(){return It},Mt=function(e){var t=Object.keys(e);return function(n){for(var r={},i=0;i<t.length;i++){var a=t[i],o=null==n?void 0:n[a];r[a]=void 0===o?e[a]:o}return r}},Pt=function(e,t,n){for(var r=e.length-1;r>=0&&(e[r]!==t||(e.splice(r,1),!n));r--);},Rt=function(e){e.splice(0,e.length)},Bt=function(e,t){for(var n=0;n<t.length;n++){var r=t[n];e.push(r)}},Ft=function(e,t,n){return n&&(t=Y(n,t)),e[t]},zt=function(e,t,n,r){n&&(t=Y(n,t)),e[t]=r},Gt=function(){function e(){t(this,e),this._obj={}}return i(e,[{key:"set",value:function(e,t){return this._obj[e]=t,this}},{key:"delete",value:function(e){return this._obj[e]=void 0,this}},{key:"clear",value:function(){this._obj={}}},{key:"has",value:function(e){return void 0!==this._obj[e]}},{key:"get",value:function(e){return this._obj[e]}}]),e}(),Yt="undefined"!=typeof Map?Map:Gt,Xt="undefined",Vt=function(){function e(n){if(t(this,e),this._obj=Object.create(null),this.size=0,null!=n){var r;r=null!=n.instanceString&&n.instanceString()===this.instanceString()?n.toArray():n;for(var i=0;i<r.length;i++)this.add(r[i])}}return i(e,[{key:"instanceString",value:function(){return"set"}},{key:"add",value:function(e){var t=this._obj;1!==t[e]&&(t[e]=1,this.size++)}},{key:"delete",value:function(e){var t=this._obj;1===t[e]&&(t[e]=0,this.size--)}},{key:"clear",value:function(){this._obj=Object.create(null)}},{key:"has",value:function(e){return 1===this._obj[e]}},{key:"toArray",value:function(){var e=this;return Object.keys(this._obj).filter((function(t){return e.has(t)}))}},{key:"forEach",value:function(e,t){return this.toArray().forEach(e,t)}}]),e}(),Ut=("undefined"==typeof Set?"undefined":e(Set))!==Xt?Set:Vt,jt=function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&S(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var i=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new Ut,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(null==i.position.x&&(i.position.x=0),null==i.position.y&&(i.position.y=0),t.renderedPosition){var a=t.renderedPosition,o=e.pan(),s=e.zoom();i.position={x:(a.x-o.x)/s,y:(a.y-o.y)/s}}var l=[];w(t.classes)?l=t.classes:b(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;u<c;u++){var h=l[u];h&&""!==h&&i.classes.add(h)}this.createEmitter();var d=t.style||t.css;d&&(Nt("Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead."),this.style(d)),(void 0===n||n)&&this.restore()}else Dt("An element must be of type `nodes` or `edges`; you specified `"+r+"`")}else Dt("An element must have a core reference and parameters set")},Ht=function(e){return e={bfs:e.bfs||!e.dfs,dfs:e.dfs||!e.bfs},function(t,n,r){var i;E(t)&&!N(t)&&(t=(i=t).roots||i.root,n=i.visit,r=i.directed),r=2!==arguments.length||x(n)?r:n,n=x(n)?n:function(){};for(var a,o=this._private.cy,s=t=b(t)?this.filter(t):t,l=[],u=[],c={},h={},d={},p=0,g=this.byGroup(),f=g.nodes,v=g.edges,y=0;y<s.length;y++){var m=s[y],w=m.id();m.isNode()&&(l.unshift(m),e.bfs&&(d[w]=!0,u.push(m)),h[w]=0)}for(var T=function(){var t=e.bfs?l.shift():l.pop(),i=t.id();if(e.dfs){if(d[i])return"continue";d[i]=!0,u.push(t)}var o=h[i],s=c[i],g=null!=s?s.source():null,y=null!=s?s.target():null,m=null==s?void 0:t.same(g)?y[0]:g[0],b=void 0;if(!0===(b=n(t,s,m,p++,o)))return a=t,"break";if(!1===b)return"break";for(var x=t.connectedEdges().filter((function(e){return(!r||e.source().same(t))&&v.has(e)})),w=0;w<x.length;w++){var E=x[w],T=E.connectedNodes().filter((function(e){return!e.same(t)&&f.has(e)})),_=T.id();0===T.length||d[_]||(T=T[0],l.push(T),e.bfs&&(d[_]=!0,u.push(T)),c[_]=E,h[_]=h[i]+1)}};0!==l.length;){var _=T();if("continue"!==_&&"break"===_)break}for(var D=o.collection(),C=0;C<u.length;C++){var A=u[C],L=c[A.id()];null!=L&&D.push(L),D.push(A)}return{path:o.collection(D),found:o.collection(a)}}},qt={breadthFirstSearch:Ht({bfs:!0}),depthFirstSearch:Ht({dfs:!0})};qt.bfs=qt.breadthFirstSearch,qt.dfs=qt.depthFirstSearch;var Wt=ce((function(e,t){(function(){var t,n,r,i,a,o,s,l,u,c,h,d,p,g,f;r=Math.floor,c=Math.min,n=function(e,t){return e<t?-1:e>t?1:0},u=function(e,t,i,a,o){var s;if(null==i&&(i=0),null==o&&(o=n),i<0)throw new Error("lo must be non-negative");for(null==a&&(a=e.length);i<a;)o(t,e[s=r((i+a)/2)])<0?a=s:i=s+1;return[].splice.apply(e,[i,i-i].concat(t)),t},o=function(e,t,r){return null==r&&(r=n),e.push(t),g(e,0,e.length-1,r)},a=function(e,t){var r,i;return null==t&&(t=n),r=e.pop(),e.length?(i=e[0],e[0]=r,f(e,0,t)):i=r,i},l=function(e,t,r){var i;return null==r&&(r=n),i=e[0],e[0]=t,f(e,0,r),i},s=function(e,t,r){var i;return null==r&&(r=n),e.length&&r(e[0],t)<0&&(t=(i=[e[0],t])[0],e[0]=i[1],f(e,0,r)),t},i=function(e,t){var i,a,o,s,l,u;for(null==t&&(t=n),l=[],a=0,o=(s=function(){u=[];for(var t=0,n=r(e.length/2);0<=n?t<n:t>n;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse()).length;a<o;a++)i=s[a],l.push(f(e,i,t));return l},p=function(e,t,r){var i;if(null==r&&(r=n),-1!==(i=e.indexOf(t)))return g(e,0,i,r),f(e,i,r)},h=function(e,t,r){var a,o,l,u,c;if(null==r&&(r=n),!(o=e.slice(0,t)).length)return o;for(i(o,r),l=0,u=(c=e.slice(t)).length;l<u;l++)a=c[l],s(o,a,r);return o.sort(r).reverse()},d=function(e,t,r){var o,s,l,h,d,p,g,f,v;if(null==r&&(r=n),10*t<=e.length){if(!(l=e.slice(0,t).sort(r)).length)return l;for(s=l[l.length-1],h=0,p=(g=e.slice(t)).length;h<p;h++)r(o=g[h],s)<0&&(u(l,o,0,null,r),l.pop(),s=l[l.length-1]);return l}for(i(e,r),v=[],d=0,f=c(t,e.length);0<=f?d<f:d>f;0<=f?++d:--d)v.push(a(e,r));return v},g=function(e,t,r,i){var a,o,s;for(null==i&&(i=n),a=e[r];r>t&&i(a,o=e[s=r-1>>1])<0;)e[r]=o,r=s;return e[r]=a},f=function(e,t,r){var i,a,o,s,l;for(null==r&&(r=n),a=e.length,l=t,o=e[t],i=2*t+1;i<a;)(s=i+1)<a&&!(r(e[i],e[s])<0)&&(i=s),e[t]=e[i],i=2*(t=i)+1;return e[t]=o,g(e,l,t,r)},t=function(){function e(e){this.cmp=null!=e?e:n,this.nodes=[]}return e.push=o,e.pop=a,e.replace=l,e.pushpop=s,e.heapify=i,e.updateItem=p,e.nlargest=h,e.nsmallest=d,e.prototype.push=function(e){return o(this.nodes,e,this.cmp)},e.prototype.pop=function(){return a(this.nodes,this.cmp)},e.prototype.peek=function(){return this.nodes[0]},e.prototype.contains=function(e){return-1!==this.nodes.indexOf(e)},e.prototype.replace=function(e){return l(this.nodes,e,this.cmp)},e.prototype.pushpop=function(e){return s(this.nodes,e,this.cmp)},e.prototype.heapify=function(){return i(this.nodes,this.cmp)},e.prototype.updateItem=function(e){return p(this.nodes,e,this.cmp)},e.prototype.clear=function(){return this.nodes=[]},e.prototype.empty=function(){return 0===this.nodes.length},e.prototype.size=function(){return this.nodes.length},e.prototype.clone=function(){var t;return(t=new e).nodes=this.nodes.slice(0),t},e.prototype.toArray=function(){return this.nodes.slice(0)},e.prototype.insert=e.prototype.push,e.prototype.top=e.prototype.peek,e.prototype.front=e.prototype.peek,e.prototype.has=e.prototype.contains,e.prototype.copy=e.prototype.clone,e}(),function(t,n){e.exports=n()}(0,(function(){return t}))}).call(ue)})),$t=Wt,Kt=Mt({root:null,weight:function(e){return 1},directed:!1}),Zt={dijkstra:function(e){if(!E(e)){var t=arguments;e={root:t[0],weight:t[1],directed:t[2]}}var n=Kt(e),r=n.root,i=n.weight,a=n.directed,o=this,s=i,l=b(r)?this.filter(r)[0]:r[0],u={},c={},h={},d=this.byGroup(),p=d.nodes,g=d.edges;g.unmergeBy((function(e){return e.isLoop()}));for(var f=function(e){return u[e.id()]},v=function(e,t){u[e.id()]=t,y.updateItem(e)},y=new $t((function(e,t){return f(e)-f(t)})),m=0;m<p.length;m++){var x=p[m];u[x.id()]=x.same(l)?0:1/0,y.push(x)}for(var w=function(e,t){for(var n,r=(a?e.edgesTo(t):e.edgesWith(t)).intersect(g),i=1/0,o=0;o<r.length;o++){var l=r[o],u=s(l);(u<i||!n)&&(i=u,n=l)}return{edge:n,dist:i}};y.size()>0;){var T=y.pop(),_=f(T),D=T.id();if(h[D]=_,_!==1/0)for(var C=T.neighborhood().intersect(p),N=0;N<C.length;N++){var A=C[N],L=A.id(),S=w(T,A),O=_+S.dist;O<f(A)&&(v(A,O),c[L]={node:T,edge:S.edge})}}return{distanceTo:function(e){var t=b(e)?p.filter(e)[0]:e[0];return h[t.id()]},pathTo:function(e){var t=b(e)?p.filter(e)[0]:e[0],n=[],r=t,i=r.id();if(t.length>0)for(n.unshift(t);c[i];){var a=c[i];n.unshift(a.edge),n.unshift(a.node),i=(r=a.node).id()}return o.spawn(n)}}}},Qt={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,i=n.length,a=new Array(i),o=n,s=function(e){for(var t=0;t<a.length;t++)if(a[t].has(e))return t},l=0;l<i;l++)a[l]=this.spawn(n[l]);for(var u=r.sort((function(t,n){return e(t)-e(n)})),c=0;c<u.length;c++){var h=u[c],d=h.source()[0],p=h.target()[0],g=s(d),f=s(p),v=a[g],y=a[f];g!==f&&(o.merge(h),v.merge(y),a.splice(f,1))}return o}},Jt=Mt({root:null,goal:null,weight:function(e){return 1},heuristic:function(e){return 0},directed:!1}),en={aStar:function(e){var t=this.cy(),n=Jt(e),r=n.root,i=n.goal,a=n.heuristic,o=n.directed,s=n.weight;r=t.collection(r)[0],i=t.collection(i)[0];var l,u,c=r.id(),h=i.id(),d={},p={},g={},f=new $t((function(e,t){return p[e.id()]-p[t.id()]})),v=new Ut,y={},m={},b=function(e,t){f.push(e),v.add(t)},x=function(){l=f.pop(),u=l.id(),v.delete(u)},w=function(e){return v.has(e)};b(r,c),d[c]=0,p[c]=a(r);for(var E=0;f.size()>0;){if(x(),E++,u===h){for(var T=[],_=i,D=h,C=m[D];T.unshift(_),null!=C&&T.unshift(C),null!=(_=y[D]);)C=m[D=_.id()];return{found:!0,distance:d[u],path:this.spawn(T),steps:E}}g[u]=!0;for(var N=l._private.edges,A=0;A<N.length;A++){var L=N[A];if(this.hasElementWithId(L.id())&&(!o||L.data("source")===u)){var S=L.source(),O=L.target(),I=S.id()!==u?S:O,k=I.id();if(this.hasElementWithId(k)&&!g[k]){var M=d[u]+s(L);w(k)?M<d[k]&&(d[k]=M,p[k]=M+a(I),y[k]=l,m[k]=L):(d[k]=M,p[k]=M+a(I),b(I,k),y[k]=l,m[k]=L)}}}}return{found:!1,distance:void 0,path:void 0,steps:E}}},tn=Mt({weight:function(e){return 1},directed:!1}),nn={floydWarshall:function(e){for(var t=this.cy(),n=tn(e),r=n.weight,i=n.directed,a=r,o=this.byGroup(),s=o.nodes,l=o.edges,u=s.length,c=u*u,h=function(e){return s.indexOf(e)},d=function(e){return s[e]},p=new Array(c),g=0;g<c;g++){var f=g%u,v=(g-f)/u;p[g]=v===f?0:1/0}for(var y=new Array(c),m=new Array(c),x=0;x<l.length;x++){var w=l[x],E=w.source()[0],T=w.target()[0];if(E!==T){var _=h(E),D=h(T),C=_*u+D,N=a(w);if(p[C]>N&&(p[C]=N,y[C]=D,m[C]=w),!i){var A=D*u+_;!i&&p[A]>N&&(p[A]=N,y[A]=_,m[A]=w)}}}for(var L=0;L<u;L++)for(var S=0;S<u;S++)for(var O=S*u+L,I=0;I<u;I++){var k=S*u+I,M=L*u+I;p[O]+p[M]<p[k]&&(p[k]=p[O]+p[M],y[k]=y[O])}var P=function(e){return(b(e)?t.filter(e):e)[0]},R=function(e){return h(P(e))},B={distance:function(e,t){var n=R(e),r=R(t);return p[n*u+r]},path:function(e,n){var r=R(e),i=R(n),a=d(r);if(r===i)return a.collection();if(null==y[r*u+i])return t.collection();var o,s=t.collection(),l=r;for(s.merge(a);r!==i;)l=r,r=y[r*u+i],o=m[l*u+r],s.merge(o),s.merge(d(r));return s}};return B}},rn=Mt({weight:function(e){return 1},directed:!1,root:null}),an={bellmanFord:function(e){var t=this,n=rn(e),r=n.weight,i=n.directed,a=n.root,o=r,s=this,l=this.cy(),u=this.byGroup(),c=u.edges,h=u.nodes,d=h.length,p=new Yt,g=!1,f=[];a=l.collection(a)[0],c.unmergeBy((function(e){return e.isLoop()}));for(var v=c.length,y=function(e){var t=p.get(e.id());return t||(t={},p.set(e.id(),t)),t},m=function(e){return(b(e)?l.$(e):e)[0]},x=function(e){return y(m(e)).dist},w=function(e){for(var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:a,r=[],i=m(e);;){if(null==i)return t.spawn();var o=y(i),l=o.edge,u=o.pred;if(r.unshift(i[0]),i.same(n)&&r.length>0)break;null!=l&&r.unshift(l),i=u}return s.spawn(r)},E=0;E<d;E++){var T=h[E],_=y(T);T.same(a)?_.dist=0:_.dist=1/0,_.pred=null,_.edge=null}for(var D=!1,C=function(e,t,n,r,i,a){var o=r.dist+a;o<i.dist&&!n.same(r.edge)&&(i.dist=o,i.pred=e,i.edge=n,D=!0)},N=1;N<d;N++){D=!1;for(var A=0;A<v;A++){var L=c[A],S=L.source(),O=L.target(),I=o(L),k=y(S),M=y(O);C(S,O,L,k,M,I),i||C(O,S,L,M,k,I)}if(!D)break}if(D)for(var P=[],R=0;R<v;R++){var B=c[R],F=B.source(),z=B.target(),G=o(B),Y=y(F).dist,X=y(z).dist;if(Y+G<X||!i&&X+G<Y){if(g||(Nt("Graph contains a negative weight cycle for Bellman-Ford"),g=!0),!1===e.findNegativeWeightCycles)break;var V=[];Y+G<X&&V.push(F),!i&&X+G<Y&&V.push(z);for(var U=V.length,j=0;j<U;j++){var H=V[j],q=[H];q.push(y(H).edge);for(var W=y(H).pred;-1===q.indexOf(W);)q.push(W),q.push(y(W).edge),W=y(W).pred;for(var $=(q=q.slice(q.indexOf(W)))[0].id(),K=0,Z=2;Z<q.length;Z+=2)q[Z].id()<$&&($=q[Z].id(),K=Z);(q=q.slice(K).concat(q.slice(0,K))).push(q[0]);var Q=q.map((function(e){return e.id()})).join(",");-1===P.indexOf(Q)&&(f.push(s.spawn(q)),P.push(Q))}}}return{distanceTo:x,pathTo:w,hasNegativeWeightCycle:g,negativeWeightCycles:f}}},on=Math.sqrt(2),sn=function(e,t,n){0===n.length&&Dt("Karger-Stein must be run on a connected (sub)graph");for(var r=n[e],i=r[1],a=r[2],o=t[i],s=t[a],l=n,u=l.length-1;u>=0;u--){var c=l[u],h=c[1],d=c[2];(t[h]===o&&t[d]===s||t[h]===s&&t[d]===o)&&l.splice(u,1)}for(var p=0;p<l.length;p++){var g=l[p];g[1]===s?(l[p]=g.slice(),l[p][1]=o):g[2]===s&&(l[p]=g.slice(),l[p][2]=o)}for(var f=0;f<t.length;f++)t[f]===s&&(t[f]=o);return l},ln=function(e,t,n,r){for(;n>r;){var i=Math.floor(Math.random()*t.length);t=sn(i,e,t),n--}return t},un={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy((function(e){return e.isLoop()}));var i=n.length,a=r.length,o=Math.ceil(Math.pow(Math.log(i)/Math.LN2,2)),s=Math.floor(i/on);if(!(i<2)){for(var l=[],u=0;u<a;u++){var c=r[u];l.push([u,n.indexOf(c.source()),n.indexOf(c.target())])}for(var h=1/0,d=[],p=new Array(i),g=new Array(i),f=new Array(i),v=function(e,t){for(var n=0;n<i;n++)t[n]=e[n]},y=0;y<=o;y++){for(var m=0;m<i;m++)g[m]=m;var b=ln(g,l.slice(),i,s),x=b.slice();v(g,f);var w=ln(g,b,s,2),E=ln(f,x,s,2);w.length<=E.length&&w.length<h?(h=w.length,d=w,v(g,p)):E.length<=w.length&&E.length<h&&(h=E.length,d=E,v(f,p))}for(var T=this.spawn(d.map((function(e){return r[e[0]]}))),_=this.spawn(),D=this.spawn(),C=p[0],N=0;N<p.length;N++){var A=p[N],L=n[N];A===C?_.merge(L):D.merge(L)}var S=function(t){var n=e.spawn();return t.forEach((function(t){n.merge(t),t.connectedEdges().forEach((function(t){e.contains(t)&&!T.contains(t)&&n.merge(t)}))})),n},O=[S(_),S(D)];return{cut:T,components:O,partition1:_,partition2:D}}Dt("At least 2 nodes are required for Karger-Stein algorithm")}},cn=function(e){return{x:e.x,y:e.y}},hn=function(e,t,n){return{x:e.x*t+n.x,y:e.y*t+n.y}},dn=function(e,t,n){return{x:(e.x-n.x)/t,y:(e.y-n.y)/t}},pn=function(e){return{x:e[0],y:e[1]}},gn=function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,i=t;i<n;i++){var a=e[i];isFinite(a)&&(r=Math.min(a,r))}return r},fn=function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,i=t;i<n;i++){var a=e[i];isFinite(a)&&(r=Math.max(a,r))}return r},vn=function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,i=0,a=t;a<n;a++){var o=e[a];isFinite(o)&&(r+=o,i++)}return r/i},yn=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n<e.length&&e.splice(n,e.length-n),t>0&&e.splice(0,t)):e=e.slice(t,n);for(var a=0,o=e.length-1;o>=0;o--){var s=e[o];i?isFinite(s)||(e[o]=-1/0,a++):e.splice(o,1)}r&&e.sort((function(e,t){return e-t}));var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+a]:(e[u-1+a]+e[u+a])/2},mn=function(e){return Math.PI*e/180},bn=function(e,t){return Math.atan2(t,e)-Math.PI/2},xn=Math.log2||function(e){return Math.log(e)/Math.log(2)},wn=function(e){return e>0?1:e<0?-1:0},En=function(e,t){return Math.sqrt(Tn(e,t))},Tn=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},_n=function(e){for(var t=e.length,n=0,r=0;r<t;r++)n+=e[r];for(var i=0;i<t;i++)e[i]=e[i]/n;return e},Dn=function(e,t,n,r){return(1-r)*(1-r)*e+2*(1-r)*r*t+r*r*n},Cn=function(e,t,n,r){return{x:Dn(e.x,t.x,n.x,r),y:Dn(e.y,t.y,n.y,r)}},Nn=function(e,t,n,r){var i={x:t.x-e.x,y:t.y-e.y},a=En(e,t),o={x:i.x/a,y:i.y/a};return n=null==n?0:n,r=null!=r?r:n*a,{x:e.x+o.x*r,y:e.y+o.y*r}},An=function(e,t,n){return Math.max(e,Math.min(n,t))},Ln=function(e){if(null==e)return{x1:1/0,y1:1/0,x2:-1/0,y2:-1/0,w:0,h:0};if(null!=e.x1&&null!=e.y1){if(null!=e.x2&&null!=e.y2&&e.x2>=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(null!=e.w&&null!=e.h&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},Sn=function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}},On=function(e){e.x1=1/0,e.y1=1/0,e.x2=-1/0,e.y2=-1/0,e.w=0,e.h=0},In=function(e,t){e.x1=Math.min(e.x1,t.x1),e.x2=Math.max(e.x2,t.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,t.y1),e.y2=Math.max(e.y2,t.y2),e.h=e.y2-e.y1},kn=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},Mn=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Pn=function(e){var t,n,r,i,a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===a.length)t=n=r=i=a[0];else if(2===a.length)t=r=a[0],i=n=a[1];else if(4===a.length){var s=o(a,4);t=s[0],n=s[1],r=s[2],i=s[3]}return e.x1-=i,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Rn=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},Bn=function(e,t){return!(e.x1>t.x2||t.x1>e.x2||e.x2<t.x1||t.x2<e.x1||e.y2<t.y1||t.y2<e.y1||e.y1>t.y2||t.y1>e.y2)},Fn=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},zn=function(e,t){return Fn(e,t.x,t.y)},Gn=function(e,t){return Fn(e,t.x1,t.y1)&&Fn(e,t.x2,t.y2)},Yn=function(e,t,n,r,i,a,o){var s,l=cr(i,a),u=i/2,c=a/2,h=r-c-o;if((s=rr(e,t,n,r,n-u+l-o,h,n+u-l+o,h,!1)).length>0)return s;var d=n+u+o;if((s=rr(e,t,n,r,d,r-c+l-o,d,r+c-l+o,!1)).length>0)return s;var p=r+c+o;if((s=rr(e,t,n,r,n-u+l-o,p,n+u-l+o,p,!1)).length>0)return s;var g,f=n-u-o;if((s=rr(e,t,n,r,f,r-c+l-o,f,r+c-l+o,!1)).length>0)return s;var v=n-u+l,y=r-c+l;if((g=tr(e,t,n,r,v,y,l+o)).length>0&&g[0]<=v&&g[1]<=y)return[g[0],g[1]];var m=n+u-l,b=r-c+l;if((g=tr(e,t,n,r,m,b,l+o)).length>0&&g[0]>=m&&g[1]<=b)return[g[0],g[1]];var x=n+u-l,w=r+c-l;if((g=tr(e,t,n,r,x,w,l+o)).length>0&&g[0]>=x&&g[1]>=w)return[g[0],g[1]];var E=n-u+l,T=r+c-l;return(g=tr(e,t,n,r,E,T,l+o)).length>0&&g[0]<=E&&g[1]>=T?[g[0],g[1]]:[]},Xn=function(e,t,n,r,i,a,o){var s=o,l=Math.min(n,i),u=Math.max(n,i),c=Math.min(r,a),h=Math.max(r,a);return l-s<=e&&e<=u+s&&c-s<=t&&t<=h+s},Vn=function(e,t,n,r,i,a,o,s,l){var u={x1:Math.min(n,o,i)-l,x2:Math.max(n,o,i)+l,y1:Math.min(r,s,a)-l,y2:Math.max(r,s,a)+l};return!(e<u.x1||e>u.x2||t<u.y1||t>u.y2)},Un=function(e,t,n,r){var i=t*t-4*e*(n-=r);if(i<0)return[];var a=Math.sqrt(i),o=2*e;return[(-t+a)/o,(-t-a)/o]},jn=function(e,t,n,r,i){var a,o,s,l,u,c,h,d;return 0===e&&(e=1e-5),s=-27*(r/=e)+(t/=e)*(9*(n/=e)-t*t*2),a=(o=(3*n-t*t)/9)*o*o+(s/=54)*s,i[1]=0,h=t/3,a>0?(u=(u=s+Math.sqrt(a))<0?-Math.pow(-u,1/3):Math.pow(u,1/3),c=(c=s-Math.sqrt(a))<0?-Math.pow(-c,1/3):Math.pow(c,1/3),i[0]=-h+u+c,h+=(u+c)/2,i[4]=i[2]=-h,h=Math.sqrt(3)*(-c+u)/2,i[3]=h,void(i[5]=-h)):(i[5]=i[3]=0,0===a?(d=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3),i[0]=2*d-h,void(i[4]=i[2]=-(d+h))):(l=(o=-o)*o*o,l=Math.acos(s/Math.sqrt(l)),d=2*Math.sqrt(o),i[0]=-h+d*Math.cos(l/3),i[2]=-h+d*Math.cos((l+2*Math.PI)/3),void(i[4]=-h+d*Math.cos((l+4*Math.PI)/3))))},Hn=function(e,t,n,r,i,a,o,s){var l=[];jn(1*n*n-4*n*i+2*n*o+4*i*i-4*i*o+o*o+r*r-4*r*a+2*r*s+4*a*a-4*a*s+s*s,9*n*i-3*n*n-3*n*o-6*i*i+3*i*o+9*r*a-3*r*r-3*r*s-6*a*a+3*a*s,3*n*n-6*n*i+n*o-n*e+2*i*i+2*i*e-o*e+3*r*r-6*r*a+r*s-r*t+2*a*a+2*a*t-s*t,1*n*i-n*n+n*e-i*e+r*a-r*r+r*t-a*t,l);for(var u=1e-7,c=[],h=0;h<6;h+=2)Math.abs(l[h+1])<u&&l[h]>=0&&l[h]<=1&&c.push(l[h]);c.push(1),c.push(0);for(var d,p,g,f=-1,v=0;v<c.length;v++)d=Math.pow(1-c[v],2)*n+2*(1-c[v])*c[v]*i+c[v]*c[v]*o,p=Math.pow(1-c[v],2)*r+2*(1-c[v])*c[v]*a+c[v]*c[v]*s,g=Math.pow(d-e,2)+Math.pow(p-t,2),f>=0?g<f&&(f=g):f=g;return f},qn=function(e,t,n,r,i,a){var o=[e-n,t-r],s=[i-n,a-r],l=s[0]*s[0]+s[1]*s[1],u=o[0]*o[0]+o[1]*o[1],c=o[0]*s[0]+o[1]*s[1],h=c*c/l;return c<0?u:h>l?(e-i)*(e-i)+(t-a)*(t-a):u-h},Wn=function(e,t,n){for(var r,i,a,o,s=0,l=0;l<n.length/2;l++)if(r=n[2*l],i=n[2*l+1],l+1<n.length/2?(a=n[2*(l+1)],o=n[2*(l+1)+1]):(a=n[2*(l+1-n.length/2)],o=n[2*(l+1-n.length/2)+1]),r==e&&a==e);else{if(!(r>=e&&e>=a||r<=e&&e<=a))continue;(e-r)/(a-r)*(o-i)+i>t&&s++}return s%2!=0},$n=function(e,t,n,r,i,a,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var h,d=Math.cos(-u),p=Math.sin(-u),g=0;g<c.length/2;g++)c[2*g]=a/2*(n[2*g]*d-n[2*g+1]*p),c[2*g+1]=o/2*(n[2*g+1]*d+n[2*g]*p),c[2*g]+=r,c[2*g+1]+=i;if(l>0){var f=Qn(c,-l);h=Zn(f)}else h=c;return Wn(e,t,h)},Kn=function(e,t,n,r,i,a,o){for(var s=new Array(n.length),l=a/2,u=o/2,c=hr(a,o),h=c*c,d=0;d<n.length/4;d++){var p=void 0,g=void 0;p=0===d?n.length-2:4*d-2,g=4*d+2;var f=r+l*n[4*d],v=i+u*n[4*d+1],y=-n[p]*n[g]-n[p+1]*n[g+1],m=c/Math.tan(Math.acos(y)/2),b=f-m*n[p],x=v-m*n[p+1],w=f+m*n[g],E=v+m*n[g+1];s[4*d]=b,s[4*d+1]=x,s[4*d+2]=w,s[4*d+3]=E;var T=n[p+1],_=-n[p];T*n[g]+_*n[g+1]<0&&(T*=-1,_*=-1);var D=b+T*c,C=x+_*c;if(Math.pow(D-e,2)+Math.pow(C-t,2)<=h)return!0}return Wn(e,t,s)},Zn=function(e){for(var t,n,r,i,a,o,s,l,u=new Array(e.length/2),c=0;c<e.length/4;c++){t=e[4*c],n=e[4*c+1],r=e[4*c+2],i=e[4*c+3],c<e.length/4-1?(a=e[4*(c+1)],o=e[4*(c+1)+1],s=e[4*(c+1)+2],l=e[4*(c+1)+3]):(a=e[0],o=e[1],s=e[2],l=e[3]);var h=rr(t,n,r,i,a,o,s,l,!0);u[2*c]=h[0],u[2*c+1]=h[1]}return u},Qn=function(e,t){for(var n,r,i,a,o=new Array(2*e.length),s=0;s<e.length/2;s++){n=e[2*s],r=e[2*s+1],s<e.length/2-1?(i=e[2*(s+1)],a=e[2*(s+1)+1]):(i=e[0],a=e[1]);var l=a-r,u=-(i-n),c=Math.sqrt(l*l+u*u),h=l/c,d=u/c;o[4*s]=n+h*t,o[4*s+1]=r+d*t,o[4*s+2]=i+h*t,o[4*s+3]=a+d*t}return o},Jn=function(e,t,n,r,i,a){var o=n-e,s=r-t;o/=i,s/=a;var l=Math.sqrt(o*o+s*s),u=l-1;if(u<0)return[];var c=u/l;return[(n-e)*c+e,(r-t)*c+t]},er=function(e,t,n,r,i,a,o){return e-=i,t-=a,(e/=n/2+o)*e+(t/=r/2+o)*t<=1},tr=function(e,t,n,r,i,a,o){var s=[n-e,r-t],l=[e-i,t-a],u=s[0]*s[0]+s[1]*s[1],c=2*(l[0]*s[0]+l[1]*s[1]),h=c*c-4*u*(l[0]*l[0]+l[1]*l[1]-o*o);if(h<0)return[];var d=(-c+Math.sqrt(h))/(2*u),p=(-c-Math.sqrt(h))/(2*u),g=Math.min(d,p),f=Math.max(d,p),v=[];if(g>=0&&g<=1&&v.push(g),f>=0&&f<=1&&v.push(f),0===v.length)return[];var y=v[0]*s[0]+e,m=v[0]*s[1]+t;return v.length>1?v[0]==v[1]?[y,m]:[y,m,v[1]*s[0]+e,v[1]*s[1]+t]:[y,m]},nr=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},rr=function(e,t,n,r,i,a,o,s,l){var u=e-i,c=n-e,h=o-i,d=t-a,p=r-t,g=s-a,f=h*d-g*u,v=c*d-p*u,y=g*c-h*p;if(0!==y){var m=f/y,b=v/y,x=.001,w=0-x,E=1+x;return w<=m&&m<=E&&w<=b&&b<=E||l?[e+m*c,t+m*p]:[]}return 0===f||0===v?nr(e,n,o)===o?[o,s]:nr(e,n,i)===i?[i,a]:nr(i,o,n)===n?[n,r]:[]:[]},ir=function(e,t,n,r,i,a,o,s){var l,u,c,h,d,p,g=[],f=new Array(n.length),v=!0;if(null==a&&(v=!1),v){for(var y=0;y<f.length/2;y++)f[2*y]=n[2*y]*a+r,f[2*y+1]=n[2*y+1]*o+i;if(s>0){var m=Qn(f,-s);u=Zn(m)}else u=f}else u=n;for(var b=0;b<u.length/2;b++)c=u[2*b],h=u[2*b+1],b<u.length/2-1?(d=u[2*(b+1)],p=u[2*(b+1)+1]):(d=u[0],p=u[1]),0!==(l=rr(e,t,r,i,c,h,d,p)).length&&g.push(l[0],l[1]);return g},ar=function(e,t,n,r,i,a,o,s){for(var l,u=[],c=new Array(n.length),h=a/2,d=o/2,p=hr(a,o),g=0;g<n.length/4;g++){var f=void 0,v=void 0;f=0===g?n.length-2:4*g-2,v=4*g+2;var y=r+h*n[4*g],m=i+d*n[4*g+1],b=-n[f]*n[v]-n[f+1]*n[v+1],x=p/Math.tan(Math.acos(b)/2),w=y-x*n[f],E=m-x*n[f+1],T=y+x*n[v],_=m+x*n[v+1];0===g?(c[n.length-2]=w,c[n.length-1]=E):(c[4*g-2]=w,c[4*g-1]=E),c[4*g]=T,c[4*g+1]=_;var D=n[f+1],C=-n[f];D*n[v]+C*n[v+1]<0&&(D*=-1,C*=-1),0!==(l=tr(e,t,r,i,w+D*p,E+C*p,p)).length&&u.push(l[0],l[1])}for(var N=0;N<c.length/4;N++)0!==(l=rr(e,t,r,i,c[4*N],c[4*N+1],c[4*N+2],c[4*N+3],!1)).length&&u.push(l[0],l[1]);if(u.length>2){for(var A=[u[0],u[1]],L=Math.pow(A[0]-e,2)+Math.pow(A[1]-t,2),S=1;S<u.length/2;S++){var O=Math.pow(u[2*S]-e,2)+Math.pow(u[2*S+1]-t,2);O<=L&&(A[0]=u[2*S],A[1]=u[2*S+1],L=O)}return A}return u},or=function(e,t,n){var r=[e[0]-t[0],e[1]-t[1]],i=Math.sqrt(r[0]*r[0]+r[1]*r[1]),a=(i-n)/i;return a<0&&(a=1e-5),[t[0]+a*r[0],t[1]+a*r[1]]},sr=function(e,t){var n=ur(e,t);return n=lr(n)},lr=function(e){for(var t,n,r=e.length/2,i=1/0,a=1/0,o=-1/0,s=-1/0,l=0;l<r;l++)t=e[2*l],n=e[2*l+1],i=Math.min(i,t),o=Math.max(o,t),a=Math.min(a,n),s=Math.max(s,n);for(var u=2/(o-i),c=2/(s-a),h=0;h<r;h++)t=e[2*h]=e[2*h]*u,n=e[2*h+1]=e[2*h+1]*c,i=Math.min(i,t),o=Math.max(o,t),a=Math.min(a,n),s=Math.max(s,n);if(a<-1)for(var d=0;d<r;d++)n=e[2*d+1]=e[2*d+1]+(-1-a);return e},ur=function(e,t){var n=1/e*2*Math.PI,r=e%2==0?Math.PI/2+n/2:Math.PI/2;r+=t;for(var i,a=new Array(2*e),o=0;o<e;o++)i=o*n+r,a[2*o]=Math.cos(i),a[2*o+1]=Math.sin(-i);return a},cr=function(e,t){return Math.min(e/4,t/4,8)},hr=function(e,t){return Math.min(e/10,t/10,8)},dr=function(){return 8},pr=function(e,t,n){return[e-2*t+n,2*(t-e),e]},gr=function(e,t){return{heightOffset:Math.min(15,.05*t),widthOffset:Math.min(100,.25*e),ctrlPtOffsetPct:.05}},fr=Mt({dampingFactor:.8,precision:1e-6,iterations:200,weight:function(e){return 1}}),vr={pageRank:function(e){for(var t=fr(e),n=t.dampingFactor,r=t.precision,i=t.iterations,a=t.weight,o=this._private.cy,s=this.byGroup(),l=s.nodes,u=s.edges,c=l.length,h=c*c,d=u.length,p=new Array(h),g=new Array(c),f=(1-n)/c,v=0;v<c;v++){for(var y=0;y<c;y++)p[v*c+y]=0;g[v]=0}for(var m=0;m<d;m++){var b=u[m],x=b.data("source"),w=b.data("target");if(x!==w){var E=l.indexOfId(x),T=l.indexOfId(w),_=a(b);p[T*c+E]+=_,g[E]+=_}}for(var D=1/c+f,C=0;C<c;C++)if(0===g[C])for(var N=0;N<c;N++)p[N*c+C]=D;else for(var A=0;A<c;A++){var L=A*c+C;p[L]=p[L]/g[C]+f}for(var S,O=new Array(c),I=new Array(c),k=0;k<c;k++)O[k]=1;for(var M=0;M<i;M++){for(var P=0;P<c;P++)I[P]=0;for(var R=0;R<c;R++)for(var B=0;B<c;B++){var F=R*c+B;I[R]+=p[F]*O[B]}_n(I),S=O,O=I,I=S;for(var z=0,G=0;G<c;G++){var Y=S[G]-O[G];z+=Y*Y}if(z<r)break}return{rank:function(e){return e=o.collection(e)[0],O[l.indexOf(e)]}}}},yr=Mt({root:null,weight:function(e){return 1},directed:!1,alpha:0}),mr={degreeCentralityNormalized:function(e){e=yr(e);var t=this.cy(),n=this.nodes(),r=n.length;if(e.directed){for(var i={},a={},o=0,s=0,l=0;l<r;l++){var u=n[l],c=u.id();e.root=u;var h=this.degreeCentrality(e);o<h.indegree&&(o=h.indegree),s<h.outdegree&&(s=h.outdegree),i[c]=h.indegree,a[c]=h.outdegree}return{indegree:function(e){return 0==o?0:(b(e)&&(e=t.filter(e)),i[e.id()]/o)},outdegree:function(e){return 0===s?0:(b(e)&&(e=t.filter(e)),a[e.id()]/s)}}}for(var d={},p=0,g=0;g<r;g++){var f=n[g];e.root=f;var v=this.degreeCentrality(e);p<v.degree&&(p=v.degree),d[f.id()]=v.degree}return{degree:function(e){return 0===p?0:(b(e)&&(e=t.filter(e)),d[e.id()]/p)}}},degreeCentrality:function(e){e=yr(e);var t=this.cy(),n=this,r=e,i=r.root,a=r.weight,o=r.directed,s=r.alpha;if(i=t.collection(i)[0],o){for(var l=i.connectedEdges(),u=l.filter((function(e){return e.target().same(i)&&n.has(e)})),c=l.filter((function(e){return e.source().same(i)&&n.has(e)})),h=u.length,d=c.length,p=0,g=0,f=0;f<u.length;f++)p+=a(u[f]);for(var v=0;v<c.length;v++)g+=a(c[v]);return{indegree:Math.pow(h,1-s)*Math.pow(p,s),outdegree:Math.pow(d,1-s)*Math.pow(g,s)}}for(var y=i.connectedEdges().intersection(n),m=y.length,b=0,x=0;x<y.length;x++)b+=a(y[x]);return{degree:Math.pow(m,1-s)*Math.pow(b,s)}}};mr.dc=mr.degreeCentrality,mr.dcn=mr.degreeCentralityNormalised=mr.degreeCentralityNormalized;var br=Mt({harmonic:!0,weight:function(){return 1},directed:!1,root:null}),xr={closenessCentralityNormalized:function(e){for(var t=br(e),n=t.harmonic,r=t.weight,i=t.directed,a=this.cy(),o={},s=0,l=this.nodes(),u=this.floydWarshall({weight:r,directed:i}),c=0;c<l.length;c++){for(var h=0,d=l[c],p=0;p<l.length;p++)if(c!==p){var g=u.distance(d,l[p]);h+=n?1/g:g}n||(h=1/h),s<h&&(s=h),o[d.id()]=h}return{closeness:function(e){return 0==s?0:(e=b(e)?a.filter(e)[0].id():e.id(),o[e]/s)}}},closenessCentrality:function(e){var t=br(e),n=t.root,r=t.weight,i=t.directed,a=t.harmonic;n=this.filter(n)[0];for(var o=this.dijkstra({root:n,weight:r,directed:i}),s=0,l=this.nodes(),u=0;u<l.length;u++){var c=l[u];if(!c.same(n)){var h=o.distanceTo(c);s+=a?1/h:h}}return a?s:1/s}};xr.cc=xr.closenessCentrality,xr.ccn=xr.closenessCentralityNormalised=xr.closenessCentralityNormalized;var wr=Mt({weight:null,directed:!1}),Er={betweennessCentrality:function(e){for(var t=wr(e),n=t.directed,r=t.weight,i=null!=r,a=this.cy(),o=this.nodes(),s={},l={},u=0,c={set:function(e,t){l[e]=t,t>u&&(u=t)},get:function(e){return l[e]}},h=0;h<o.length;h++){var d=o[h],p=d.id();s[p]=n?d.outgoers().nodes():d.openNeighborhood().nodes(),c.set(p,0)}for(var g=function(e){for(var t=o[e].id(),n=[],l={},u={},h={},d=new $t((function(e,t){return h[e]-h[t]})),p=0;p<o.length;p++){var g=o[p].id();l[g]=[],u[g]=0,h[g]=1/0}for(u[t]=1,h[t]=0,d.push(t);!d.empty();){var f=d.pop();if(n.push(f),i)for(var v=0;v<s[f].length;v++){var y=s[f][v],m=a.getElementById(f),b=void 0;b=m.edgesTo(y).length>0?m.edgesTo(y)[0]:y.edgesTo(m)[0];var x=r(b);y=y.id(),h[y]>h[f]+x&&(h[y]=h[f]+x,d.nodes.indexOf(y)<0?d.push(y):d.updateItem(y),u[y]=0,l[y]=[]),h[y]==h[f]+x&&(u[y]=u[y]+u[f],l[y].push(f))}else for(var w=0;w<s[f].length;w++){var E=s[f][w].id();h[E]==1/0&&(d.push(E),h[E]=h[f]+1),h[E]==h[f]+1&&(u[E]=u[E]+u[f],l[E].push(f))}}for(var T={},_=0;_<o.length;_++)T[o[_].id()]=0;for(;n.length>0;){for(var D=n.pop(),C=0;C<l[D].length;C++){var N=l[D][C];T[N]=T[N]+u[N]/u[D]*(1+T[D])}D!=o[e].id()&&c.set(D,c.get(D)+T[D])}},f=0;f<o.length;f++)g(f);var v={betweenness:function(e){var t=a.collection(e).id();return c.get(t)},betweennessNormalized:function(e){if(0==u)return 0;var t=a.collection(e).id();return c.get(t)/u}};return v.betweennessNormalised=v.betweennessNormalized,v}};Er.bc=Er.betweennessCentrality;var Tr=Mt({expandFactor:2,inflateFactor:2,multFactor:1,maxIterations:20,attributes:[function(e){return 1}]}),_r=function(e){return Tr(e)},Dr=function(e,t){for(var n=0,r=0;r<t.length;r++)n+=t[r](e);return n},Cr=function(e,t,n){for(var r=0;r<t;r++)e[r*t+r]=n},Nr=function(e,t){for(var n,r=0;r<t;r++){n=0;for(var i=0;i<t;i++)n+=e[i*t+r];for(var a=0;a<t;a++)e[a*t+r]=e[a*t+r]/n}},Ar=function(e,t,n){for(var r=new Array(n*n),i=0;i<n;i++){for(var a=0;a<n;a++)r[i*n+a]=0;for(var o=0;o<n;o++)for(var s=0;s<n;s++)r[i*n+s]+=e[i*n+o]*t[o*n+s]}return r},Lr=function(e,t,n){for(var r=e.slice(0),i=1;i<n;i++)e=Ar(e,r,t);return e},Sr=function(e,t,n){for(var r=new Array(t*t),i=0;i<t*t;i++)r[i]=Math.pow(e[i],n);return Nr(r,t),r},Or=function(e,t,n,r){for(var i=0;i<n;i++)if(Math.round(e[i]*Math.pow(10,r))/Math.pow(10,r)!=Math.round(t[i]*Math.pow(10,r))/Math.pow(10,r))return!1;return!0},Ir=function(e,t,n,r){for(var i=[],a=0;a<t;a++){for(var o=[],s=0;s<t;s++)Math.round(1e3*e[a*t+s])/1e3>0&&o.push(n[s]);0!==o.length&&i.push(r.collection(o))}return i},kr=function(e,t){for(var n=0;n<e.length;n++)if(!t[n]||e[n].id()!==t[n].id())return!1;return!0},Mr=function(e){for(var t=0;t<e.length;t++)for(var n=0;n<e.length;n++)t!=n&&kr(e[t],e[n])&&e.splice(n,1);return e},Pr=function(e){for(var t=this.nodes(),n=this.edges(),r=this.cy(),i=_r(e),a={},o=0;o<t.length;o++)a[t[o].id()]=o;for(var s,l=t.length,u=l*l,c=new Array(u),h=0;h<u;h++)c[h]=0;for(var d=0;d<n.length;d++){var p=n[d],g=a[p.source().id()],f=a[p.target().id()],v=Dr(p,i.attributes);c[g*l+f]+=v,c[f*l+g]+=v}Cr(c,l,i.multFactor),Nr(c,l);for(var y=!0,m=0;y&&m<i.maxIterations;)y=!1,s=Lr(c,l,i.expandFactor),c=Sr(s,l,i.inflateFactor),Or(c,s,u,4)||(y=!0),m++;var b=Ir(c,l,t,r);return b=Mr(b)},Rr={markovClustering:Pr,mcl:Pr},Br=function(e){return e},Fr=function(e,t){return Math.abs(t-e)},zr=function(e,t,n){return e+Fr(t,n)},Gr=function(e,t,n){return e+Math.pow(n-t,2)},Yr=function(e){return Math.sqrt(e)},Xr=function(e,t,n){return Math.max(e,Fr(t,n))},Vr=function(e,t,n,r,i){for(var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:Br,o=r,s=0;s<e;s++)o=i(o,t(s),n(s));return a(o)},Ur={euclidean:function(e,t,n){return e>=2?Vr(e,t,n,0,Gr,Yr):Vr(e,t,n,0,zr)},squaredEuclidean:function(e,t,n){return Vr(e,t,n,0,Gr)},manhattan:function(e,t,n){return Vr(e,t,n,0,zr)},max:function(e,t,n){return Vr(e,t,n,-1/0,Xr)}};function jr(e,t,n,r,i,a){var o;return o=x(e)?e:Ur[e]||Ur.euclidean,0===t&&x(e)?o(i,a):o(t,n,r,i,a)}Ur["squared-euclidean"]=Ur.squaredEuclidean,Ur.squaredeuclidean=Ur.squaredEuclidean;var Hr=Mt({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),qr=function(e){return Hr(e)},Wr=function(e,t,n,r,i){var a="kMedoids"!==i?function(e){return n[e]}:function(e){return r[e](n)},o=function(e){return r[e](t)},s=n,l=t;return jr(e,r.length,a,o,s,l)},$r=function(e,t,n){for(var r=n.length,i=new Array(r),a=new Array(r),o=new Array(t),s=null,l=0;l<r;l++)i[l]=e.min(n[l]).value,a[l]=e.max(n[l]).value;for(var u=0;u<t;u++){s=[];for(var c=0;c<r;c++)s[c]=Math.random()*(a[c]-i[c])+i[c];o[u]=s}return o},Kr=function(e,t,n,r,i){for(var a=1/0,o=0,s=0;s<t.length;s++){var l=Wr(n,e,t[s],r,i);l<a&&(a=l,o=s)}return o},Zr=function(e,t,n){for(var r=[],i=null,a=0;a<t.length;a++)n[(i=t[a]).id()]===e&&r.push(i);return r},Qr=function(e,t,n){return Math.abs(t-e)<=n},Jr=function(e,t,n){for(var r=0;r<e.length;r++)for(var i=0;i<e[r].length;i++)if(Math.abs(e[r][i]-t[r][i])>n)return!1;return!0},ei=function(e,t,n){for(var r=0;r<n;r++)if(e===t[r])return!0;return!1},ti=function(e,t){var n=new Array(t);if(e.length<50)for(var r=0;r<t;r++){for(var i=e[Math.floor(Math.random()*e.length)];ei(i,n,r);)i=e[Math.floor(Math.random()*e.length)];n[r]=i}else for(var a=0;a<t;a++)n[a]=e[Math.floor(Math.random()*e.length)];return n},ni=function(e,t,n){for(var r=0,i=0;i<t.length;i++)r+=Wr("manhattan",t[i],e,n,"kMedoids");return r},ri=function(e,t,n,r,i){for(var a,o,s=0;s<t.length;s++)for(var l=0;l<e.length;l++)r[s][l]=Math.pow(n[s][l],i.m);for(var u=0;u<e.length;u++)for(var c=0;c<i.attributes.length;c++){a=0,o=0;for(var h=0;h<t.length;h++)a+=r[h][u]*i.attributes[c](t[h]),o+=r[h][u];e[u][c]=a/o}},ii=function(e,t,n,r,i){for(var a=0;a<e.length;a++)t[a]=e[a].slice();for(var o,s,l,u=2/(i.m-1),c=0;c<n.length;c++)for(var h=0;h<r.length;h++){o=0;for(var d=0;d<n.length;d++)s=Wr(i.distance,r[h],n[c],i.attributes,"cmeans"),l=Wr(i.distance,r[h],n[d],i.attributes,"cmeans"),o+=Math.pow(s/l,u);e[h][c]=1/o}},ai=function(e,t,n,r){for(var i,a,o=new Array(n.k),s=0;s<o.length;s++)o[s]=[];for(var l=0;l<t.length;l++){i=-1/0,a=-1;for(var u=0;u<t[0].length;u++)t[l][u]>i&&(i=t[l][u],a=u);o[a].push(e[l])}for(var c=0;c<o.length;c++)o[c]=r.collection(o[c]);return o},oi=function(e){var t,n,r,i,a=this.cy(),o=this.nodes(),s=qr(e);r=new Array(o.length);for(var l=0;l<o.length;l++)r[l]=new Array(s.k);n=new Array(o.length);for(var u=0;u<o.length;u++)n[u]=new Array(s.k);for(var c=0;c<o.length;c++){for(var h=0,d=0;d<s.k;d++)n[c][d]=Math.random(),h+=n[c][d];for(var p=0;p<s.k;p++)n[c][p]=n[c][p]/h}t=new Array(s.k);for(var g=0;g<s.k;g++)t[g]=new Array(s.attributes.length);i=new Array(o.length);for(var f=0;f<o.length;f++)i[f]=new Array(s.k);for(var v=!0,y=0;v&&y<s.maxIterations;)v=!1,ri(t,o,n,i,s),ii(n,r,t,o,s),Jr(n,r,s.sensitivityThreshold)||(v=!0),y++;return{clusters:ai(o,n,s,a),degreeOfMembership:n}},si={kMeans:function(t){var n,r=this.cy(),i=this.nodes(),a=null,o=qr(t),s=new Array(o.k),l={};o.testMode?"number"==typeof o.testCentroids?(o.testCentroids,n=$r(i,o.k,o.attributes)):n="object"===e(o.testCentroids)?o.testCentroids:$r(i,o.k,o.attributes):n=$r(i,o.k,o.attributes);for(var u=!0,c=0;u&&c<o.maxIterations;){for(var h=0;h<i.length;h++)l[(a=i[h]).id()]=Kr(a,n,o.distance,o.attributes,"kMeans");u=!1;for(var d=0;d<o.k;d++){var p=Zr(d,i,l);if(0!==p.length){for(var g=o.attributes.length,f=n[d],v=new Array(g),y=new Array(g),m=0;m<g;m++){y[m]=0;for(var b=0;b<p.length;b++)a=p[b],y[m]+=o.attributes[m](a);v[m]=y[m]/p.length,Qr(v[m],f[m],o.sensitivityThreshold)||(u=!0)}n[d]=v,s[d]=r.collection(p)}}c++}return s},kMedoids:function(t){var n,r,i=this.cy(),a=this.nodes(),o=null,s=qr(t),l=new Array(s.k),u={},c=new Array(s.k);s.testMode?"number"==typeof s.testCentroids||(n="object"===e(s.testCentroids)?s.testCentroids:ti(a,s.k)):n=ti(a,s.k);for(var h=!0,d=0;h&&d<s.maxIterations;){for(var p=0;p<a.length;p++)u[(o=a[p]).id()]=Kr(o,n,s.distance,s.attributes,"kMedoids");h=!1;for(var g=0;g<n.length;g++){var f=Zr(g,a,u);if(0!==f.length){c[g]=ni(n[g],f,s.attributes);for(var v=0;v<f.length;v++)(r=ni(f[v],f,s.attributes))<c[g]&&(c[g]=r,n[g]=f[v],h=!0);l[g]=i.collection(f)}}d++}return l},fuzzyCMeans:oi,fcm:oi},li=Mt({distance:"euclidean",linkage:"min",mode:"threshold",threshold:1/0,addDendrogram:!1,dendrogramDepth:0,attributes:[]}),ui={single:"min",complete:"max"},ci=function(e){var t=li(e),n=ui[t.linkage];return null!=n&&(t.linkage=n),t},hi=function(e,t,n,r,i){for(var a,o=0,s=1/0,l=i.attributes,u=function(e,t){return jr(i.distance,l.length,(function(t){return l[t](e)}),(function(e){return l[e](t)}),e,t)},c=0;c<e.length;c++){var h=e[c].key,d=n[h][r[h]];d<s&&(o=h,s=d)}if("threshold"===i.mode&&s>=i.threshold||"dendrogram"===i.mode&&1===e.length)return!1;var p,g=t[o],f=t[r[o]];p="dendrogram"===i.mode?{left:g,right:f,key:g.key}:{value:g.value.concat(f.value),key:g.key},e[g.index]=p,e.splice(f.index,1),t[g.key]=p;for(var v=0;v<e.length;v++){var y=e[v];g.key===y.key?a=1/0:"min"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]>n[f.key][y.key]&&(a=n[f.key][y.key])):"max"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]<n[f.key][y.key]&&(a=n[f.key][y.key])):a="mean"===i.linkage?(n[g.key][y.key]*g.size+n[f.key][y.key]*f.size)/(g.size+f.size):"dendrogram"===i.mode?u(y.value,g.value):u(y.value[0],g.value[0]),n[g.key][y.key]=n[y.key][g.key]=a}for(var m=0;m<e.length;m++){var b=e[m].key;if(r[b]===g.key||r[b]===f.key){for(var x=b,w=0;w<e.length;w++){var E=e[w].key;n[b][E]<n[b][x]&&(x=E)}r[b]=x}e[m].index=m}return g.key=f.key=g.index=f.index=null,!0},di=function e(t,n,r){t&&(t.value?n.push(t.value):(t.left&&e(t.left,n),t.right&&e(t.right,n)))},pi=function e(t,n){if(!t)return"";if(t.left&&t.right){var r=e(t.left,n),i=e(t.right,n),a=n.add({group:"nodes",data:{id:r+","+i}});return n.add({group:"edges",data:{source:r,target:a.id()}}),n.add({group:"edges",data:{source:i,target:a.id()}}),a.id()}return t.value?t.value.id():void 0},gi=function e(t,n,r){if(!t)return[];var i=[],a=[],o=[];return 0===n?(t.left&&di(t.left,i),t.right&&di(t.right,a),o=i.concat(a),[r.collection(o)]):1===n?t.value?[r.collection(t.value)]:(t.left&&di(t.left,i),t.right&&di(t.right,a),[r.collection(i),r.collection(a)]):t.value?[r.collection(t.value)]:(t.left&&(i=e(t.left,n-1,r)),t.right&&(a=e(t.right,n-1,r)),i.concat(a))},fi=function(e){for(var t=this.cy(),n=this.nodes(),r=ci(e),i=r.attributes,a=function(e,t){return jr(r.distance,i.length,(function(t){return i[t](e)}),(function(e){return i[e](t)}),e,t)},o=[],s=[],l=[],u=[],c=0;c<n.length;c++){var h={value:"dendrogram"===r.mode?n[c]:[n[c]],key:c,index:c};o[c]=h,u[c]=h,s[c]=[],l[c]=0}for(var d=0;d<o.length;d++)for(var p=0;p<=d;p++){var g=void 0;g="dendrogram"===r.mode?d===p?1/0:a(o[d].value,o[p].value):d===p?1/0:a(o[d].value[0],o[p].value[0]),s[d][p]=g,s[p][d]=g,g<s[d][l[d]]&&(l[d]=p)}for(var f,v=hi(o,u,s,l,r);v;)v=hi(o,u,s,l,r);return"dendrogram"===r.mode?(f=gi(o[0],r.dendrogramDepth,t),r.addDendrogram&&pi(o[0],t)):(f=new Array(o.length),o.forEach((function(e,n){e.key=e.index=null,f[n]=t.collection(e.value)}))),f},vi={hierarchicalClustering:fi,hca:fi},yi=Mt({distance:"euclidean",preference:"median",damping:.8,maxIterations:1e3,minIterations:100,attributes:[]}),mi=function(e){var t=e.damping,n=e.preference;.5<=t&&t<1||Dt("Damping must range on [0.5, 1). Got: ".concat(t));var r=["median","mean","min","max"];return r.some((function(e){return e===n}))||_(n)||Dt("Preference must be one of [".concat(r.map((function(e){return"'".concat(e,"'")})).join(", "),"] or a number. Got: ").concat(n)),yi(e)},bi=function(e,t,n,r){var i=function(e,t){return r[t](e)};return-jr(e,r.length,(function(e){return i(t,e)}),(function(e){return i(n,e)}),t,n)},xi=function(e,t){return"median"===t?yn(e):"mean"===t?vn(e):"min"===t?gn(e):"max"===t?fn(e):t},wi=function(e,t,n){for(var r=[],i=0;i<e;i++)t[i*e+i]+n[i*e+i]>0&&r.push(i);return r},Ei=function(e,t,n){for(var r=[],i=0;i<e;i++){for(var a=-1,o=-1/0,s=0;s<n.length;s++){var l=n[s];t[i*e+l]>o&&(a=l,o=t[i*e+l])}a>0&&r.push(a)}for(var u=0;u<n.length;u++)r[n[u]]=n[u];return r},Ti=function(e,t,n){for(var r=Ei(e,t,n),i=0;i<n.length;i++){for(var a=[],o=0;o<r.length;o++)r[o]===n[i]&&a.push(o);for(var s=-1,l=-1/0,u=0;u<a.length;u++){for(var c=0,h=0;h<a.length;h++)c+=t[a[h]*e+a[u]];c>l&&(s=u,l=c)}n[i]=a[s]}return r=Ei(e,t,n)},_i=function(e){for(var t,n,r,i,a,o,s=this.cy(),l=this.nodes(),u=mi(e),c={},h=0;h<l.length;h++)c[l[h].id()]=h;n=(t=l.length)*t,r=new Array(n);for(var d=0;d<n;d++)r[d]=-1/0;for(var p=0;p<t;p++)for(var g=0;g<t;g++)p!==g&&(r[p*t+g]=bi(u.distance,l[p],l[g],u.attributes));i=xi(r,u.preference);for(var f=0;f<t;f++)r[f*t+f]=i;a=new Array(n);for(var v=0;v<n;v++)a[v]=0;o=new Array(n);for(var y=0;y<n;y++)o[y]=0;for(var m=new Array(t),b=new Array(t),x=new Array(t),w=0;w<t;w++)m[w]=0,b[w]=0,x[w]=0;for(var E,T=new Array(t*u.minIterations),_=0;_<T.length;_++)T[_]=0;for(E=0;E<u.maxIterations;E++){for(var D=0;D<t;D++){for(var C=-1/0,N=-1/0,A=-1,L=0,S=0;S<t;S++)m[S]=a[D*t+S],(L=o[D*t+S]+r[D*t+S])>=C?(N=C,C=L,A=S):L>N&&(N=L);for(var O=0;O<t;O++)a[D*t+O]=(1-u.damping)*(r[D*t+O]-C)+u.damping*m[O];a[D*t+A]=(1-u.damping)*(r[D*t+A]-N)+u.damping*m[A]}for(var I=0;I<t;I++){for(var k=0,M=0;M<t;M++)m[M]=o[M*t+I],b[M]=Math.max(0,a[M*t+I]),k+=b[M];k-=b[I],b[I]=a[I*t+I],k+=b[I];for(var P=0;P<t;P++)o[P*t+I]=(1-u.damping)*Math.min(0,k-b[P])+u.damping*m[P];o[I*t+I]=(1-u.damping)*(k-b[I])+u.damping*m[I]}for(var R=0,B=0;B<t;B++){var F=o[B*t+B]+a[B*t+B]>0?1:0;T[E%u.minIterations*t+B]=F,R+=F}if(R>0&&(E>=u.minIterations-1||E==u.maxIterations-1)){for(var z=0,G=0;G<t;G++){x[G]=0;for(var Y=0;Y<u.minIterations;Y++)x[G]+=T[Y*t+G];0!==x[G]&&x[G]!==u.minIterations||z++}if(z===t)break}}for(var X=wi(t,a,o),V=Ti(t,r,X),U={},j=0;j<X.length;j++)U[X[j]]=[];for(var H=0;H<l.length;H++){var q=V[c[l[H].id()]];null!=q&&U[q].push(l[H])}for(var W=new Array(X.length),$=0;$<X.length;$++)W[$]=s.collection(U[X[$]]);return W},Di={affinityPropagation:_i,ap:_i},Ci=Mt({root:void 0,directed:!1}),Ni={hierholzer:function(e){if(!E(e)){var t=arguments;e={root:t[0],directed:t[1]}}var n,r,i,a=Ci(e),o=a.root,s=a.directed,l=this,u=!1;o&&(i=b(o)?this.filter(o)[0].id():o[0].id());var c={},h={};s?l.forEach((function(e){var t=e.id();if(e.isNode()){var i=e.indegree(!0),a=e.outdegree(!0),o=i-a,s=a-i;1==o?n?u=!0:n=t:1==s?r?u=!0:r=t:(s>1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach((function(e){e.isEdge()&&c[t].push(e.id())}))}else h[t]=[void 0,e.target().id()]})):l.forEach((function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach((function(e){return c[t].push(e.id())}))):h[t]=[e.source().id(),e.target().id()]}));var d={found:!1,trail:void 0};if(u)return d;if(r&&n)if(s){if(i&&r!=i)return d;i=r}else{if(i&&r!=i&&n!=i)return d;i||(i=r)}else i||(i=l[0].id());var p=function(e){for(var t,n,r,i=e,a=[e];c[i].length;)t=c[i].shift(),n=h[t][0],i!=(r=h[t][1])?(c[r]=c[r].filter((function(e){return e!=t})),i=r):s||i==n||(c[n]=c[n].filter((function(e){return e!=t})),i=n),a.unshift(t),a.unshift(i);return a},g=[],f=[];for(f=p(i);1!=f.length;)0==c[f[0]].length?(g.unshift(l.getElementById(f.shift())),g.unshift(l.getElementById(f.shift()))):f=p(f.shift()).concat(f);for(var v in g.unshift(l.getElementById(f.shift())),c)if(c[v].length)return d;return d.found=!0,d.trail=this.spawn(g,!0),d}},Ai=function(){var e=this,t={},n=0,r=0,i=[],a=[],o={},s=function(n,r){for(var o=a.length-1,s=[],l=e.spawn();a[o].x!=n||a[o].y!=r;)s.push(a.pop().edge),o--;s.push(a.pop().edge),s.forEach((function(n){var r=n.connectedNodes().intersection(e);l.merge(n),r.forEach((function(n){var r=n.id(),i=n.connectedEdges().intersection(e);l.merge(n),t[r].cutVertex?l.merge(i.filter((function(e){return e.isLoop()}))):l.merge(i)}))})),i.push(l)},l=function l(u,c,h){u===h&&(r+=1),t[c]={id:n,low:n++,cutVertex:!1};var d,p,g,f,v=e.getElementById(c).connectedEdges().intersection(e);0===v.size()?i.push(e.spawn(e.getElementById(c))):v.forEach((function(e){d=e.source().id(),p=e.target().id(),(g=d===c?p:d)!==h&&(f=e.id(),o[f]||(o[f]=!0,a.push({x:c,y:g,edge:e})),g in t?t[c].low=Math.min(t[c].low,t[g].id):(l(u,g,c),t[c].low=Math.min(t[c].low,t[g].low),t[c].id<=t[g].low&&(t[c].cutVertex=!0,s(c,g))))}))};e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||(r=0,l(n,n),t[n].cutVertex=r>1)}}));var u=Object.keys(t).filter((function(e){return t[e].cutVertex})).map((function(t){return e.getElementById(t)}));return{cut:e.spawn(u),components:i}},Li=function(){var e=this,t={},n=0,r=[],i=[],a=e.spawn(e),o=function o(s){if(i.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach((function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))})),t[s].index===t[s].low){for(var l=e.spawn();;){var u=i.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),h=l.merge(c);r.push(h),a=a.difference(h)}};return e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||o(n)}})),{cut:a,components:r}},Si={};[qt,Zt,Qt,en,nn,an,un,vr,mr,xr,Er,Rr,si,vi,Di,Ni,{hopcroftTarjanBiconnected:Ai,htbc:Ai,htb:Ai,hopcroftTarjanBiconnectedComponents:Ai},{tarjanStronglyConnected:Li,tsc:Li,tscc:Li,tarjanStronglyConnectedComponents:Li}].forEach((function(e){Q(Si,e)}));var Oi=0,Ii=1,ki=2,Mi=function e(t){if(!(this instanceof e))return new e(t);this.id="Thenable/1.0.7",this.state=Oi,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},"function"==typeof t&&t.call(this,this.fulfill.bind(this),this.reject.bind(this))};Mi.prototype={fulfill:function(e){return Pi(this,Ii,"fulfillValue",e)},reject:function(e){return Pi(this,ki,"rejectReason",e)},then:function(e,t){var n=this,r=new Mi;return n.onFulfilled.push(Fi(e,r,"fulfill")),n.onRejected.push(Fi(t,r,"reject")),Ri(n),r.proxy}};var Pi=function(e,t,n,r){return e.state===Oi&&(e.state=t,e[n]=r,Ri(e)),e},Ri=function(e){e.state===Ii?Bi(e,"onFulfilled",e.fulfillValue):e.state===ki&&Bi(e,"onRejected",e.rejectReason)},Bi=function(e,t,n){if(0!==e[t].length){var r=e[t];e[t]=[];var i=function(){for(var e=0;e<r.length;e++)r[e](n)};"function"==typeof setImmediate?setImmediate(i):setTimeout(i,0)}},Fi=function(e,t,n){return function(r){if("function"!=typeof e)t[n].call(t,r);else{var i;try{i=e(r)}catch(a){return void t.reject(a)}zi(t,i)}}},zi=function t(n,r){if(n!==r&&n.proxy!==r){var i;if("object"===e(r)&&null!==r||"function"==typeof r)try{i=r.then}catch(o){return void n.reject(o)}if("function"!=typeof i)n.fulfill(r);else{var a=!1;try{i.call(r,(function(e){a||(a=!0,e===r?n.reject(new TypeError("circular thenable chain")):t(n,e))}),(function(e){a||(a=!0,n.reject(e))}))}catch(o){a||n.reject(o)}}}else n.reject(new TypeError("cannot resolve promise with itself"))};Mi.all=function(e){return new Mi((function(t,n){for(var r=new Array(e.length),i=0,a=function(n,a){r[n]=a,++i===e.length&&t(r)},o=0;o<e.length;o++)!function(t){var r=e[t];null!=r&&null!=r.then?r.then((function(e){a(t,e)}),(function(e){n(e)})):a(t,r)}(o)}))},Mi.resolve=function(e){return new Mi((function(t,n){t(e)}))},Mi.reject=function(e){return new Mi((function(t,n){n(e)}))};var Gi="undefined"!=typeof Promise?Promise:Mi,Yi=function(e,t,n){var r=S(e),i=!r,a=this._private=Q({duration:1e3},t,n);if(a.target=e,a.style=a.style||a.css,a.started=!1,a.playing=!1,a.hooked=!1,a.applying=!1,a.progress=0,a.completes=[],a.frames=[],a.complete&&x(a.complete)&&a.completes.push(a.complete),i){var o=e.position();a.startPosition=a.startPosition||{x:o.x,y:o.y},a.startStyle=a.startStyle||e.cy().style().getAnimationStartStyle(e,a.style)}if(r){var s=e.pan();a.startPan={x:s.x,y:s.y},a.startZoom=e.zoom()}this.length=1,this[0]=this},Xi=Yi.prototype;Q(Xi,{instanceString:function(){return"animation"},hook:function(){var e=this._private;if(!e.hooked){var t=e.target._private.animation;(e.queue?t.queue:t.current).push(this),N(e.target)&&e.target.cy().addToAnimationPool(e.target),e.hooked=!0}return this},play:function(){var e=this._private;return 1===e.progress&&(e.progress=0),e.playing=!0,e.started=!1,e.stopped=!1,this.hook(),this},playing:function(){return this._private.playing},apply:function(){var e=this._private;return e.applying=!0,e.started=!1,e.stopped=!1,this.hook(),this},applying:function(){return this._private.applying},pause:function(){var e=this._private;return e.playing=!1,e.started=!1,this},stop:function(){var e=this._private;return e.playing=!1,e.started=!1,e.stopped=!0,this},rewind:function(){return this.progress(0)},fastforward:function(){return this.progress(1)},time:function(e){var t=this._private;return void 0===e?t.progress*t.duration:this.progress(e/t.duration)},progress:function(e){var t=this._private,n=t.playing;return void 0===e?t.progress:(n&&this.pause(),t.progress=e,t.started=!1,n&&this.play(),this)},completed:function(){return 1===this._private.progress},reverse:function(){var e=this._private,t=e.playing;t&&this.pause(),e.progress=1-e.progress,e.started=!1;var n=function(t,n){var r=e[t];null!=r&&(e[t]=e[n],e[n]=r)};if(n("zoom","startZoom"),n("pan","startPan"),n("position","startPosition"),e.style)for(var r=0;r<e.style.length;r++){var i=e.style[r],a=i.name,o=e.startStyle[a];e.startStyle[a]=i,e.style[r]=o}return t&&this.play(),this},promise:function(e){var t,n=this._private;return t="frame"===e?n.frames:n.completes,new Gi((function(e,n){t.push((function(){e()}))}))}}),Xi.complete=Xi.completed,Xi.run=Xi.play,Xi.running=Xi.playing;var Vi={animated:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return!1;var n=t[0];return n?n._private.animation.current.length>0:void 0}},clearQueue:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return this;for(var n=0;n<t.length;n++)t[n]._private.animation.queue=[];return this}},delay:function(){return function(e,t){return(this._private.cy||this).styleEnabled()?this.animate({delay:e,duration:e,complete:t}):this}},delayAnimation:function(){return function(e,t){return(this._private.cy||this).styleEnabled()?this.animation({delay:e,duration:e,complete:t}):this}},animation:function(){return function(e,t){var n=this,r=void 0!==n.length,i=r?n:[n],a=this._private.cy||this,o=!r,s=!o;if(!a.styleEnabled())return this;var l=a.style();if(e=Q({},e,t),0===Object.keys(e).length)return new Yi(i[0],e);switch(void 0===e.duration&&(e.duration=400),e.duration){case"slow":e.duration=600;break;case"fast":e.duration=200}if(s&&(e.style=l.getPropsList(e.style||e.css),e.css=void 0),s&&null!=e.renderedPosition){var u=e.renderedPosition,c=a.pan(),h=a.zoom();e.position=dn(u,h,c)}if(o&&null!=e.panBy){var d=e.panBy,p=a.pan();e.pan={x:p.x+d.x,y:p.y+d.y}}var g=e.center||e.centre;if(o&&null!=g){var f=a.getCenterPan(g.eles,e.zoom);null!=f&&(e.pan=f)}if(o&&null!=e.fit){var v=e.fit,y=a.getFitViewport(v.eles||v.boundingBox,v.padding);null!=y&&(e.pan=y.pan,e.zoom=y.zoom)}if(o&&E(e.zoom)){var m=a.getZoomedViewport(e.zoom);null!=m?(m.zoomed&&(e.zoom=m.zoom),m.panned&&(e.pan=m.pan)):e.zoom=null}return new Yi(i[0],e)}},animate:function(){return function(e,t){var n=this,r=void 0!==n.length?n:[n];if(!(this._private.cy||this).styleEnabled())return this;t&&(e=Q({},e,t));for(var i=0;i<r.length;i++){var a=r[i],o=a.animated()&&(void 0===e.queue||e.queue);a.animation(e,o?{queue:!0}:void 0).play()}return this}},stop:function(){return function(e,t){var n=this,r=void 0!==n.length?n:[n],i=this._private.cy||this;if(!i.styleEnabled())return this;for(var a=0;a<r.length;a++){for(var o=r[a]._private,s=o.animation.current,l=0;l<s.length;l++){var u=s[l]._private;t&&(u.duration=0)}e&&(o.animation.queue=[]),t||(o.animation.current=[])}return i.notify("draw"),this}}},Ui=Array.isArray,ji=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Hi=/^\w*$/;function qi(e,t){if(Ui(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!Ge(e))||Hi.test(e)||!ji.test(e)||null!=t&&e in Object(t)}var Wi=qi,$i="[object AsyncFunction]",Ki="[object Function]",Zi="[object GeneratorFunction]",Qi="[object Proxy]";function Ji(e){if(!le(e))return!1;var t=Pe(e);return t==Ki||t==Zi||t==$i||t==Qi}var ea,ta=Ji,na=pe["__core-js_shared__"],ra=(ea=/[^.]+$/.exec(na&&na.keys&&na.keys.IE_PROTO||""))?"Symbol(src)_1."+ea:"";function ia(e){return!!ra&&ra in e}var aa=ia,oa=Function.prototype.toString;function sa(e){if(null!=e){try{return oa.call(e)}catch(t){}try{return e+""}catch(t){}}return""}var la=sa,ua=/[\\^$.*+?()[\]{}|]/g,ca=/^\[object .+?Constructor\]$/,ha=Function.prototype,da=Object.prototype,pa=ha.toString,ga=da.hasOwnProperty,fa=RegExp("^"+pa.call(ga).replace(ua,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function va(e){return!(!le(e)||aa(e))&&(ta(e)?fa:ca).test(la(e))}var ya=va;function ma(e,t){return null==e?void 0:e[t]}var ba=ma;function xa(e,t){var n=ba(e,t);return ya(n)?n:void 0}var wa=xa,Ea=wa(Object,"create");function Ta(){this.__data__=Ea?Ea(null):{},this.size=0}var _a=Ta;function Da(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}var Ca=Da,Na="__lodash_hash_undefined__",Aa=Object.prototype.hasOwnProperty;function La(e){var t=this.__data__;if(Ea){var n=t[e];return n===Na?void 0:n}return Aa.call(t,e)?t[e]:void 0}var Sa=La,Oa=Object.prototype.hasOwnProperty;function Ia(e){var t=this.__data__;return Ea?void 0!==t[e]:Oa.call(t,e)}var ka=Ia,Ma="__lodash_hash_undefined__";function Pa(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=Ea&&void 0===t?Ma:t,this}var Ra=Pa;function Ba(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}Ba.prototype.clear=_a,Ba.prototype.delete=Ca,Ba.prototype.get=Sa,Ba.prototype.has=ka,Ba.prototype.set=Ra;var Fa=Ba;function za(){this.__data__=[],this.size=0}var Ga=za;function Ya(e,t){return e===t||e!=e&&t!=t}var Xa=Ya;function Va(e,t){for(var n=e.length;n--;)if(Xa(e[n][0],t))return n;return-1}var Ua=Va,ja=Array.prototype.splice;function Ha(e){var t=this.__data__,n=Ua(t,e);return!(n<0||(n==t.length-1?t.pop():ja.call(t,n,1),--this.size,0))}var qa=Ha;function Wa(e){var t=this.__data__,n=Ua(t,e);return n<0?void 0:t[n][1]}var $a=Wa;function Ka(e){return Ua(this.__data__,e)>-1}var Za=Ka;function Qa(e,t){var n=this.__data__,r=Ua(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}var Ja=Qa;function eo(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}eo.prototype.clear=Ga,eo.prototype.delete=qa,eo.prototype.get=$a,eo.prototype.has=Za,eo.prototype.set=Ja;var to=eo,no=wa(pe,"Map");function ro(){this.size=0,this.__data__={hash:new Fa,map:new(no||to),string:new Fa}}var io=ro;function ao(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}var oo=ao;function so(e,t){var n=e.__data__;return oo(t)?n["string"==typeof t?"string":"hash"]:n.map}var lo=so;function uo(e){var t=lo(this,e).delete(e);return this.size-=t?1:0,t}var co=uo;function ho(e){return lo(this,e).get(e)}var po=ho;function go(e){return lo(this,e).has(e)}var fo=go;function vo(e,t){var n=lo(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this}var yo=vo;function mo(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}mo.prototype.clear=io,mo.prototype.delete=co,mo.prototype.get=po,mo.prototype.has=fo,mo.prototype.set=yo;var bo=mo,xo="Expected a function";function wo(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError(xo);var n=function(){var r=arguments,i=t?t.apply(this,r):r[0],a=n.cache;if(a.has(i))return a.get(i);var o=e.apply(this,r);return n.cache=a.set(i,o)||a,o};return n.cache=new(wo.Cache||bo),n}wo.Cache=bo;var Eo=wo,To=500;function _o(e){var t=Eo(e,(function(e){return n.size===To&&n.clear(),e})),n=t.cache;return t}var Do=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Co=/\\(\\)?/g,No=_o((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(Do,(function(e,n,r,i){t.push(r?i.replace(Co,"$1"):n||e)})),t}));function Ao(e,t){for(var n=-1,r=null==e?0:e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}var Lo=Ao,So=1/0,Oo=we?we.prototype:void 0,Io=Oo?Oo.toString:void 0;function ko(e){if("string"==typeof e)return e;if(Ui(e))return Lo(e,ko)+"";if(Ge(e))return Io?Io.call(e):"";var t=e+"";return"0"==t&&1/e==-So?"-0":t}var Mo=ko;function Po(e){return null==e?"":Mo(e)}var Ro=Po;function Bo(e,t){return Ui(e)?e:Wi(e,t)?[e]:No(Ro(e))}var Fo=Bo,zo=1/0;function Go(e){if("string"==typeof e||Ge(e))return e;var t=e+"";return"0"==t&&1/e==-zo?"-0":t}var Yo=Go;function Xo(e,t){for(var n=0,r=(t=Fo(t,e)).length;null!=e&&n<r;)e=e[Yo(t[n++])];return n&&n==r?e:void 0}var Vo=Xo;function Uo(e,t,n){var r=null==e?void 0:Vo(e,t);return void 0===r?n:r}var jo=Uo,Ho=function(){try{var e=wa(Object,"defineProperty");return e({},"",{}),e}catch(t){}}();function qo(e,t,n){"__proto__"==t&&Ho?Ho(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}var Wo=qo,$o=Object.prototype.hasOwnProperty;function Ko(e,t,n){var r=e[t];$o.call(e,t)&&Xa(r,n)&&(void 0!==n||t in e)||Wo(e,t,n)}var Zo=Ko,Qo=9007199254740991,Jo=/^(?:0|[1-9]\d*)$/;function es(e,t){var n=typeof e;return!!(t=null==t?Qo:t)&&("number"==n||"symbol"!=n&&Jo.test(e))&&e>-1&&e%1==0&&e<t}var ts=es;function ns(e,t,n,r){if(!le(e))return e;for(var i=-1,a=(t=Fo(t,e)).length,o=a-1,s=e;null!=s&&++i<a;){var l=Yo(t[i]),u=n;if("__proto__"===l||"constructor"===l||"prototype"===l)return e;if(i!=o){var c=s[l];void 0===(u=r?r(c,l,s):void 0)&&(u=le(c)?c:ts(t[i+1])?[]:{})}Zo(s,l,u),s=s[l]}return e}var rs=ns;function is(e,t,n){return null==e?e:rs(e,t,n)}var as=is;function os(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n<r;)t[n]=e[n];return t}var ss=os;function ls(e){return Ui(e)?Lo(e,Yo):Ge(e)?[e]:ss(No(Ro(e)))}var us=ls,cs={eventAliasesOn:function(e){var t=e;t.addListener=t.listen=t.bind=t.on,t.unlisten=t.unbind=t.off=t.removeListener,t.trigger=t.emit,t.pon=t.promiseOn=function(e,t){var n=this,r=Array.prototype.slice.call(arguments,0);return new Gi((function(e,t){var i=function(t){n.off.apply(n,o),e(t)},a=r.concat([i]),o=a.concat([]);n.on.apply(n,a)}))}}},hs={};[Vi,{data:function(e){return e=Q({},{field:"data",bindingEvent:"data",allowBinding:!1,allowSetting:!1,allowGetting:!1,settingEvent:"data",settingTriggersEvent:!1,triggerFnName:"trigger",immutableKeys:{},updateStyle:!1,beforeGet:function(e){},beforeSet:function(e,t){},onSet:function(e){},canSet:function(e){return!0}},e),function(t,n){var r=e,i=this,o=void 0!==i.length,s=o?i:[i],l=o?i[0]:i;if(b(t)){var u,c=-1!==t.indexOf(".")&&us(t);if(r.allowGetting&&void 0===n)return l&&(r.beforeGet(l),u=c&&void 0===l._private[r.field][t]?jo(l._private[r.field],c):l._private[r.field][t]),u;if(r.allowSetting&&void 0!==n&&!r.immutableKeys[t]){var h=a({},t,n);r.beforeSet(i,h);for(var d=0,p=s.length;d<p;d++){var g=s[d];r.canSet(g)&&(c&&void 0===l._private[r.field][t]?as(g._private[r.field],c,n):g._private[r.field][t]=n)}r.updateStyle&&i.updateStyle(),r.onSet(i),r.settingTriggersEvent&&i[r.triggerFnName](r.settingEvent)}}else if(r.allowSetting&&E(t)){var f,v,y=t,m=Object.keys(y);r.beforeSet(i,y);for(var w=0;w<m.length;w++)if(v=y[f=m[w]],!r.immutableKeys[f])for(var T=0;T<s.length;T++){var _=s[T];r.canSet(_)&&(_._private[r.field][f]=v)}r.updateStyle&&i.updateStyle(),r.onSet(i),r.settingTriggersEvent&&i[r.triggerFnName](r.settingEvent)}else if(r.allowBinding&&x(t)){var D=t;i.on(r.bindingEvent,D)}else if(r.allowGetting&&void 0===t){var C;return l&&(r.beforeGet(l),C=l._private[r.field]),C}return i}},removeData:function(e){return e=Q({},{field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!1,immutableKeys:{}},e),function(t){var n=e,r=this,i=void 0!==r.length?r:[r];if(b(t)){for(var a=t.split(/\s+/),o=a.length,s=0;s<o;s++){var l=a[s];if(!k(l)&&!n.immutableKeys[l])for(var u=0,c=i.length;u<c;u++)i[u]._private[n.field][l]=void 0}n.triggerEvent&&r[n.triggerFnName](n.event)}else if(void 0===t){for(var h=0,d=i.length;h<d;h++)for(var p=i[h]._private[n.field],g=Object.keys(p),f=0;f<g.length;f++){var v=g[f];!n.immutableKeys[v]&&(p[v]=void 0)}n.triggerEvent&&r[n.triggerFnName](n.event)}return r}}},cs].forEach((function(e){Q(hs,e)}));var ds={animate:hs.animate(),animation:hs.animation(),animated:hs.animated(),clearQueue:hs.clearQueue(),delay:hs.delay(),delayAnimation:hs.delayAnimation(),stop:hs.stop()},ps={classes:function(e){var t=this;if(void 0===e){var n=[];return t[0]._private.classes.forEach((function(e){return n.push(e)})),n}w(e)||(e=(e||"").match(/\S+/g)||[]);for(var r=[],i=new Ut(e),a=0;a<t.length;a++){for(var o=t[a],s=o._private,l=s.classes,u=!1,c=0;c<e.length;c++){var h=e[c];if(!l.has(h)){u=!0;break}}u||(u=l.size!==e.length),u&&(s.classes=i,r.push(o))}return r.length>0&&this.spawn(r).updateStyle().emit("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes.has(e)},toggleClass:function(e,t){w(e)||(e=e.match(/\S+/g)||[]);for(var n=this,r=void 0===t,i=[],a=0,o=n.length;a<o;a++)for(var s=n[a],l=s._private.classes,u=!1,c=0;c<e.length;c++){var h=e[c],d=l.has(h),p=!1;t||r&&!d?(l.add(h),p=!0):(!t||r&&d)&&(l.delete(h),p=!0),!u&&p&&(i.push(s),u=!0)}return i.length>0&&this.spawn(i).updateStyle().emit("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var n=this;if(null==t)t=250;else if(0===t)return n;return n.addClass(e),setTimeout((function(){n.removeClass(e)}),t),n}};ps.className=ps.classNames=ps.classes;var gs={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:"\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'",number:V,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};gs.variable="(?:[\\w-.]|(?:\\\\"+gs.metaChar+"))+",gs.className="(?:[\\w-]|(?:\\\\"+gs.metaChar+"))+",gs.value=gs.string+"|"+gs.number,gs.id=gs.variable,function(){var e,t,n;for(e=gs.comparatorOp.split("|"),n=0;n<e.length;n++)t=e[n],gs.comparatorOp+="|@"+t;for(e=gs.comparatorOp.split("|"),n=0;n<e.length;n++)(t=e[n]).indexOf("!")>=0||"="!==t&&(gs.comparatorOp+="|\\!"+t)}();var fs=function(){return{checks:[]}},vs={GROUP:0,COLLECTION:1,FILTER:2,DATA_COMPARE:3,DATA_EXIST:4,DATA_BOOL:5,META_COMPARE:6,STATE:7,ID:8,CLASS:9,UNDIRECTED_EDGE:10,DIRECTED_EDGE:11,NODE_SOURCE:12,NODE_TARGET:13,NODE_NEIGHBOR:14,CHILD:15,DESCENDANT:16,PARENT:17,ANCESTOR:18,COMPOUND_SPLIT:19,TRUE:20},ys=[{selector:":selected",matches:function(e){return e.selected()}},{selector:":unselected",matches:function(e){return!e.selected()}},{selector:":selectable",matches:function(e){return e.selectable()}},{selector:":unselectable",matches:function(e){return!e.selectable()}},{selector:":locked",matches:function(e){return e.locked()}},{selector:":unlocked",matches:function(e){return!e.locked()}},{selector:":visible",matches:function(e){return e.visible()}},{selector:":hidden",matches:function(e){return!e.visible()}},{selector:":transparent",matches:function(e){return e.transparent()}},{selector:":grabbed",matches:function(e){return e.grabbed()}},{selector:":free",matches:function(e){return!e.grabbed()}},{selector:":removed",matches:function(e){return e.removed()}},{selector:":inside",matches:function(e){return!e.removed()}},{selector:":grabbable",matches:function(e){return e.grabbable()}},{selector:":ungrabbable",matches:function(e){return!e.grabbable()}},{selector:":animated",matches:function(e){return e.animated()}},{selector:":unanimated",matches:function(e){return!e.animated()}},{selector:":parent",matches:function(e){return e.isParent()}},{selector:":childless",matches:function(e){return e.isChildless()}},{selector:":child",matches:function(e){return e.isChild()}},{selector:":orphan",matches:function(e){return e.isOrphan()}},{selector:":nonorphan",matches:function(e){return e.isChild()}},{selector:":compound",matches:function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()}},{selector:":loop",matches:function(e){return e.isLoop()}},{selector:":simple",matches:function(e){return e.isSimple()}},{selector:":active",matches:function(e){return e.active()}},{selector:":inactive",matches:function(e){return!e.active()}},{selector:":backgrounding",matches:function(e){return e.backgrounding()}},{selector:":nonbackgrounding",matches:function(e){return!e.backgrounding()}}].sort((function(e,t){return Z(e.selector,t.selector)})),ms=function(){for(var e,t={},n=0;n<ys.length;n++)t[(e=ys[n]).selector]=e.matches;return t}(),bs=function(e,t){return ms[e](t)},xs="("+ys.map((function(e){return e.selector})).join("|")+")",ws=function(e){return e.replace(new RegExp("\\\\("+gs.metaChar+")","g"),(function(e,t){return t}))},Es=function(e,t,n){e[e.length-1]=n},Ts=[{name:"group",query:!0,regex:"("+gs.group+")",populate:function(e,t,n){var r=o(n,1)[0];t.checks.push({type:vs.GROUP,value:"*"===r?r:r+"s"})}},{name:"state",query:!0,regex:xs,populate:function(e,t,n){var r=o(n,1)[0];t.checks.push({type:vs.STATE,value:r})}},{name:"id",query:!0,regex:"\\#("+gs.id+")",populate:function(e,t,n){var r=o(n,1)[0];t.checks.push({type:vs.ID,value:ws(r)})}},{name:"className",query:!0,regex:"\\.("+gs.className+")",populate:function(e,t,n){var r=o(n,1)[0];t.checks.push({type:vs.CLASS,value:ws(r)})}},{name:"dataExists",query:!0,regex:"\\[\\s*("+gs.variable+")\\s*\\]",populate:function(e,t,n){var r=o(n,1)[0];t.checks.push({type:vs.DATA_EXIST,field:ws(r)})}},{name:"dataCompare",query:!0,regex:"\\[\\s*("+gs.variable+")\\s*("+gs.comparatorOp+")\\s*("+gs.value+")\\s*\\]",populate:function(e,t,n){var r=o(n,3),i=r[0],a=r[1],s=r[2];s=null!=new RegExp("^"+gs.string+"$").exec(s)?s.substring(1,s.length-1):parseFloat(s),t.checks.push({type:vs.DATA_COMPARE,field:ws(i),operator:a,value:s})}},{name:"dataBool",query:!0,regex:"\\[\\s*("+gs.boolOp+")\\s*("+gs.variable+")\\s*\\]",populate:function(e,t,n){var r=o(n,2),i=r[0],a=r[1];t.checks.push({type:vs.DATA_BOOL,field:ws(a),operator:i})}},{name:"metaCompare",query:!0,regex:"\\[\\[\\s*("+gs.meta+")\\s*("+gs.comparatorOp+")\\s*("+gs.number+")\\s*\\]\\]",populate:function(e,t,n){var r=o(n,3),i=r[0],a=r[1],s=r[2];t.checks.push({type:vs.META_COMPARE,field:ws(i),operator:a,value:parseFloat(s)})}},{name:"nextQuery",separator:!0,regex:gs.separator,populate:function(e,t){var n=e.currentSubject,r=e.edgeCount,i=e.compoundCount,a=e[e.length-1];return null!=n&&(a.subject=n,e.currentSubject=null),a.edgeCount=r,a.compoundCount=i,e.edgeCount=0,e.compoundCount=0,e[e.length++]=fs()}},{name:"directedEdge",separator:!0,regex:gs.directedEdge,populate:function(e,t){if(null==e.currentSubject){var n=fs(),r=t,i=fs();return n.checks.push({type:vs.DIRECTED_EDGE,source:r,target:i}),Es(e,t,n),e.edgeCount++,i}var a=fs(),o=t,s=fs();return a.checks.push({type:vs.NODE_SOURCE,source:o,target:s}),Es(e,t,a),e.edgeCount++,s}},{name:"undirectedEdge",separator:!0,regex:gs.undirectedEdge,populate:function(e,t){if(null==e.currentSubject){var n=fs(),r=t,i=fs();return n.checks.push({type:vs.UNDIRECTED_EDGE,nodes:[r,i]}),Es(e,t,n),e.edgeCount++,i}var a=fs(),o=t,s=fs();return a.checks.push({type:vs.NODE_NEIGHBOR,node:o,neighbor:s}),Es(e,t,a),s}},{name:"child",separator:!0,regex:gs.child,populate:function(e,t){if(null==e.currentSubject){var n=fs(),r=fs(),i=e[e.length-1];return n.checks.push({type:vs.CHILD,parent:i,child:r}),Es(e,t,n),e.compoundCount++,r}if(e.currentSubject===t){var a=fs(),o=e[e.length-1],s=fs(),l=fs(),u=fs(),c=fs();return a.checks.push({type:vs.COMPOUND_SPLIT,left:o,right:s,subject:l}),l.checks=t.checks,t.checks=[{type:vs.TRUE}],c.checks.push({type:vs.TRUE}),s.checks.push({type:vs.PARENT,parent:c,child:u}),Es(e,o,a),e.currentSubject=l,e.compoundCount++,u}var h=fs(),d=fs(),p=[{type:vs.PARENT,parent:h,child:d}];return h.checks=t.checks,t.checks=p,e.compoundCount++,d}},{name:"descendant",separator:!0,regex:gs.descendant,populate:function(e,t){if(null==e.currentSubject){var n=fs(),r=fs(),i=e[e.length-1];return n.checks.push({type:vs.DESCENDANT,ancestor:i,descendant:r}),Es(e,t,n),e.compoundCount++,r}if(e.currentSubject===t){var a=fs(),o=e[e.length-1],s=fs(),l=fs(),u=fs(),c=fs();return a.checks.push({type:vs.COMPOUND_SPLIT,left:o,right:s,subject:l}),l.checks=t.checks,t.checks=[{type:vs.TRUE}],c.checks.push({type:vs.TRUE}),s.checks.push({type:vs.ANCESTOR,ancestor:c,descendant:u}),Es(e,o,a),e.currentSubject=l,e.compoundCount++,u}var h=fs(),d=fs(),p=[{type:vs.ANCESTOR,ancestor:h,descendant:d}];return h.checks=t.checks,t.checks=p,e.compoundCount++,d}},{name:"subject",modifier:!0,regex:gs.subject,populate:function(e,t){if(null!=e.currentSubject&&e.currentSubject!==t)return Nt("Redefinition of subject in selector `"+e.toString()+"`"),!1;e.currentSubject=t;var n=e[e.length-1].checks[0],r=null==n?null:n.type;r===vs.DIRECTED_EDGE?n.type=vs.NODE_TARGET:r===vs.UNDIRECTED_EDGE&&(n.type=vs.NODE_NEIGHBOR,n.node=n.nodes[1],n.neighbor=n.nodes[0],n.nodes=null)}}];Ts.forEach((function(e){return e.regexObj=new RegExp("^"+e.regex)}));var _s=function(e){for(var t,n,r,i=0;i<Ts.length;i++){var a=Ts[i],o=a.name,s=e.match(a.regexObj);if(null!=s){n=s,t=a,r=o;var l=s[0];e=e.substring(l.length);break}}return{expr:t,match:n,name:r,remaining:e}},Ds=function(e){var t=e.match(/^\s+/);if(t){var n=t[0];e=e.substring(n.length)}return e},Cs={parse:function(e){var t=this,n=t.inputText=e,r=t[0]=fs();for(t.length=1,n=Ds(n);;){var i=_s(n);if(null==i.expr)return Nt("The selector `"+e+"`is invalid"),!1;var a=i.match.slice(1),o=i.expr.populate(t,r,a);if(!1===o)return!1;if(null!=o&&(r=o),(n=i.remaining).match(/^\s*$/))break}var s=t[t.length-1];null!=t.currentSubject&&(s.subject=t.currentSubject),s.edgeCount=t.edgeCount,s.compoundCount=t.compoundCount;for(var l=0;l<t.length;l++){var u=t[l];if(u.compoundCount>0&&u.edgeCount>0)return Nt("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(u.edgeCount>1)return Nt("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;1===u.edgeCount&&Nt("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},toString:function(){if(null!=this.toStringCache)return this.toStringCache;for(var e=function(e){return null==e?"":e},t=function(t){return b(t)?'"'+t+'"':e(t)},n=function(e){return" "+e+" "},r=function(r,a){var o=r.type,s=r.value;switch(o){case vs.GROUP:var l=e(s);return l.substring(0,l.length-1);case vs.DATA_COMPARE:var u=r.field,c=r.operator;return"["+u+n(e(c))+t(s)+"]";case vs.DATA_BOOL:var h=r.operator,d=r.field;return"["+e(h)+d+"]";case vs.DATA_EXIST:return"["+r.field+"]";case vs.META_COMPARE:var p=r.operator;return"[["+r.field+n(e(p))+t(s)+"]]";case vs.STATE:return s;case vs.ID:return"#"+s;case vs.CLASS:return"."+s;case vs.PARENT:case vs.CHILD:return i(r.parent,a)+n(">")+i(r.child,a);case vs.ANCESTOR:case vs.DESCENDANT:return i(r.ancestor,a)+" "+i(r.descendant,a);case vs.COMPOUND_SPLIT:var g=i(r.left,a),f=i(r.subject,a),v=i(r.right,a);return g+(g.length>0?" ":"")+f+v;case vs.TRUE:return""}},i=function(e,t){return e.checks.reduce((function(n,i,a){return n+(t===e&&0===a?"$":"")+r(i,t)}),"")},a="",o=0;o<this.length;o++){var s=this[o];a+=i(s,s.subject),this.length>1&&o<this.length-1&&(a+=", ")}return this.toStringCache=a,a}},Ns=function(e,t,n){var r,i,a,o=b(e),s=_(e),l=b(n),u=!1,c=!1,h=!1;switch(t.indexOf("!")>=0&&(t=t.replace("!",""),c=!0),t.indexOf("@")>=0&&(t=t.replace("@",""),u=!0),(o||l||u)&&(i=o||s?""+e:"",a=""+n),u&&(e=i=i.toLowerCase(),n=a=a.toLowerCase()),t){case"*=":r=i.indexOf(a)>=0;break;case"$=":r=i.indexOf(a,i.length-a.length)>=0;break;case"^=":r=0===i.indexOf(a);break;case"=":r=e===n;break;case">":h=!0,r=e>n;break;case">=":h=!0,r=e>=n;break;case"<":h=!0,r=e<n;break;case"<=":h=!0,r=e<=n;break;default:r=!1}return!c||null==e&&h||(r=!r),r},As=function(e,t){switch(t){case"?":return!!e;case"!":return!e;case"^":return void 0===e}},Ls=function(e){return void 0!==e},Ss=function(e,t){return e.data(t)},Os=function(e,t){return e[t]()},Is=[],ks=function(e,t){return e.checks.every((function(e){return Is[e.type](e,t)}))};Is[vs.GROUP]=function(e,t){var n=e.value;return"*"===n||n===t.group()},Is[vs.STATE]=function(e,t){var n=e.value;return bs(n,t)},Is[vs.ID]=function(e,t){var n=e.value;return t.id()===n},Is[vs.CLASS]=function(e,t){var n=e.value;return t.hasClass(n)},Is[vs.META_COMPARE]=function(e,t){var n=e.field,r=e.operator,i=e.value;return Ns(Os(t,n),r,i)},Is[vs.DATA_COMPARE]=function(e,t){var n=e.field,r=e.operator,i=e.value;return Ns(Ss(t,n),r,i)},Is[vs.DATA_BOOL]=function(e,t){var n=e.field,r=e.operator;return As(Ss(t,n),r)},Is[vs.DATA_EXIST]=function(e,t){var n=e.field;return e.operator,Ls(Ss(t,n))},Is[vs.UNDIRECTED_EDGE]=function(e,t){var n=e.nodes[0],r=e.nodes[1],i=t.source(),a=t.target();return ks(n,i)&&ks(r,a)||ks(r,i)&&ks(n,a)},Is[vs.NODE_NEIGHBOR]=function(e,t){return ks(e.node,t)&&t.neighborhood().some((function(t){return t.isNode()&&ks(e.neighbor,t)}))},Is[vs.DIRECTED_EDGE]=function(e,t){return ks(e.source,t.source())&&ks(e.target,t.target())},Is[vs.NODE_SOURCE]=function(e,t){return ks(e.source,t)&&t.outgoers().some((function(t){return t.isNode()&&ks(e.target,t)}))},Is[vs.NODE_TARGET]=function(e,t){return ks(e.target,t)&&t.incomers().some((function(t){return t.isNode()&&ks(e.source,t)}))},Is[vs.CHILD]=function(e,t){return ks(e.child,t)&&ks(e.parent,t.parent())},Is[vs.PARENT]=function(e,t){return ks(e.parent,t)&&t.children().some((function(t){return ks(e.child,t)}))},Is[vs.DESCENDANT]=function(e,t){return ks(e.descendant,t)&&t.ancestors().some((function(t){return ks(e.ancestor,t)}))},Is[vs.ANCESTOR]=function(e,t){return ks(e.ancestor,t)&&t.descendants().some((function(t){return ks(e.descendant,t)}))},Is[vs.COMPOUND_SPLIT]=function(e,t){return ks(e.subject,t)&&ks(e.left,t)&&ks(e.right,t)},Is[vs.TRUE]=function(){return!0},Is[vs.COLLECTION]=function(e,t){return e.value.has(t)},Is[vs.FILTER]=function(e,t){return(0,e.value)(t)};var Ms={matches:function(e){for(var t=this,n=0;n<t.length;n++){var r=t[n];if(ks(r,e))return!0}return!1},filter:function(e){var t=this;if(1===t.length&&1===t[0].checks.length&&t[0].checks[0].type===vs.ID)return e.getElementById(t[0].checks[0].value).collection();var n=function(e){for(var n=0;n<t.length;n++){var r=t[n];if(ks(r,e))return!0}return!1};return null==t.text()&&(n=function(){return!0}),e.filter(n)}},Ps=function(e){this.inputText=e,this.currentSubject=null,this.compoundCount=0,this.edgeCount=0,this.length=0,null==e||b(e)&&e.match(/^\s*$/)||(N(e)?this.addQuery({checks:[{type:vs.COLLECTION,value:e.collection()}]}):x(e)?this.addQuery({checks:[{type:vs.FILTER,value:e}]}):b(e)?this.parse(e)||(this.invalid=!0):Dt("A selector must be created from a string; found "))},Rs=Ps.prototype;[Cs,Ms].forEach((function(e){return Q(Rs,e)})),Rs.text=function(){return this.inputText},Rs.size=function(){return this.length},Rs.eq=function(e){return this[e]},Rs.sameText=function(e){return!this.invalid&&!e.invalid&&this.text()===e.text()},Rs.addQuery=function(e){this[this.length++]=e},Rs.selector=Rs.toString;var Bs={allAre:function(e){var t=new Ps(e);return this.every((function(e){return t.matches(e)}))},is:function(e){var t=new Ps(e);return this.some((function(e){return t.matches(e)}))},some:function(e,t){for(var n=0;n<this.length;n++)if(t?e.apply(t,[this[n],n,this]):e(this[n],n,this))return!0;return!1},every:function(e,t){for(var n=0;n<this.length;n++)if(!(t?e.apply(t,[this[n],n,this]):e(this[n],n,this)))return!1;return!0},same:function(e){if(this===e)return!0;e=this.cy().collection(e);var t=this.length;return t===e.length&&(1===t?this[0]===e[0]:this.every((function(t){return e.hasElementWithId(t.id())})))},anySame:function(e){return e=this.cy().collection(e),this.some((function(t){return e.hasElementWithId(t.id())}))},allAreNeighbors:function(e){e=this.cy().collection(e);var t=this.neighborhood();return e.every((function(e){return t.hasElementWithId(e.id())}))},contains:function(e){e=this.cy().collection(e);var t=this;return e.every((function(e){return t.hasElementWithId(e.id())}))}};Bs.allAreNeighbours=Bs.allAreNeighbors,Bs.has=Bs.contains,Bs.equal=Bs.equals=Bs.same;var Fs,zs,Gs=function(e,t){return function(n,r,i,a){var o,s=n,l=this;if(null==s?o="":N(s)&&1===s.length&&(o=s.id()),1===l.length&&o){var u=l[0]._private,c=u.traversalCache=u.traversalCache||{},h=c[t]=c[t]||[],d=gt(o),p=h[d];return p||(h[d]=e.call(l,n,r,i,a))}return e.call(l,n,r,i,a)}},Ys={parent:function(e){var t=[];if(1===this.length){var n=this[0]._private.parent;if(n)return n}for(var r=0;r<this.length;r++){var i=this[r]._private.parent;i&&t.push(i)}return this.spawn(t,!0).filter(e)},parents:function(e){for(var t=[],n=this.parent();n.nonempty();){for(var r=0;r<n.length;r++){var i=n[r];t.push(i)}n=n.parent()}return this.spawn(t,!0).filter(e)},commonAncestors:function(e){for(var t,n=0;n<this.length;n++){var r=this[n].parents();t=(t=t||r).intersect(r)}return t.filter(e)},orphans:function(e){return this.stdFilter((function(e){return e.isOrphan()})).filter(e)},nonorphans:function(e){return this.stdFilter((function(e){return e.isChild()})).filter(e)},children:Gs((function(e){for(var t=[],n=0;n<this.length;n++)for(var r=this[n]._private.children,i=0;i<r.length;i++)t.push(r[i]);return this.spawn(t,!0).filter(e)}),"children"),siblings:function(e){return this.parent().children().not(this).filter(e)},isParent:function(){var e=this[0];if(e)return e.isNode()&&0!==e._private.children.length},isChildless:function(){var e=this[0];if(e)return e.isNode()&&0===e._private.children.length},isChild:function(){var e=this[0];if(e)return e.isNode()&&null!=e._private.parent},isOrphan:function(){var e=this[0];if(e)return e.isNode()&&null==e._private.parent},descendants:function(e){var t=[];function n(e){for(var r=0;r<e.length;r++){var i=e[r];t.push(i),i.children().nonempty()&&n(i.children())}}return n(this.children()),this.spawn(t,!0).filter(e)}};function Xs(e,t,n,r){for(var i=[],a=new Ut,o=e.cy().hasCompoundNodes(),s=0;s<e.length;s++){var l=e[s];n?i.push(l):o&&r(i,a,l)}for(;i.length>0;){var u=i.shift();t(u),a.add(u.id()),o&&r(i,a,u)}return e}function Vs(e,t,n){if(n.isParent())for(var r=n._private.children,i=0;i<r.length;i++){var a=r[i];t.has(a.id())||e.push(a)}}function Us(e,t,n){if(n.isChild()){var r=n._private.parent;t.has(r.id())||e.push(r)}}function js(e,t,n){Us(e,t,n),Vs(e,t,n)}Ys.forEachDown=function(e){return Xs(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],Vs)},Ys.forEachUp=function(e){return Xs(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],Us)},Ys.forEachUpAndDown=function(e){return Xs(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],js)},Ys.ancestors=Ys.parents,(Fs=zs={data:hs.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:hs.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:hs.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:hs.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:hs.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:hs.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];if(e)return e._private.data.id}}).attr=Fs.data,Fs.removeAttr=Fs.removeData;var Hs,qs,Ws=zs,$s={};function Ks(e){return function(t){var n=this;if(void 0===t&&(t=!0),0!==n.length&&n.isNode()&&!n.removed()){for(var r=0,i=n[0],a=i._private.edges,o=0;o<a.length;o++){var s=a[o];!t&&s.isLoop()||(r+=e(i,s))}return r}}}function Zs(e,t){return function(n){for(var r,i=this.nodes(),a=0;a<i.length;a++){var o=i[a][e](n);void 0===o||void 0!==r&&!t(o,r)||(r=o)}return r}}Q($s,{degree:Ks((function(e,t){return t.source().same(t.target())?2:1})),indegree:Ks((function(e,t){return t.target().same(e)?1:0})),outdegree:Ks((function(e,t){return t.source().same(e)?1:0}))}),Q($s,{minDegree:Zs("degree",(function(e,t){return e<t})),maxDegree:Zs("degree",(function(e,t){return e>t})),minIndegree:Zs("indegree",(function(e,t){return e<t})),maxIndegree:Zs("indegree",(function(e,t){return e>t})),minOutdegree:Zs("outdegree",(function(e,t){return e<t})),maxOutdegree:Zs("outdegree",(function(e,t){return e>t}))}),Q($s,{totalDegree:function(e){for(var t=0,n=this.nodes(),r=0;r<n.length;r++)t+=n[r].degree(e);return t}});var Qs=function(e,t,n){for(var r=0;r<e.length;r++){var i=e[r];if(!i.locked()){var a=i._private.position,o={x:null!=t.x?t.x-a.x:0,y:null!=t.y?t.y-a.y:0};!i.isParent()||0===o.x&&0===o.y||i.children().shift(o,n),i.dirtyBoundingBoxCache()}}},Js={field:"position",bindingEvent:"position",allowBinding:!0,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!0,triggerFnName:"emitAndNotify",allowGetting:!0,validKeys:["x","y"],beforeGet:function(e){e.updateCompoundBounds()},beforeSet:function(e,t){Qs(e,t,!1)},onSet:function(e){e.dirtyCompoundBoundsCache()},canSet:function(e){return!e.locked()}};(Hs=qs={position:hs.data(Js),silentPosition:hs.data(Q({},Js,{allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!1,beforeSet:function(e,t){Qs(e,t,!0)},onSet:function(e){e.dirtyCompoundBoundsCache()}})),positions:function(e,t){if(E(e))t?this.silentPosition(e):this.position(e);else if(x(e)){var n=e,r=this.cy();r.startBatch();for(var i=0;i<this.length;i++){var a=this[i],o=void 0;(o=n(a,i))&&(t?a.silentPosition(o):a.position(o))}r.endBatch()}return this},silentPositions:function(e){return this.positions(e,!0)},shift:function(e,t,n){var r;if(E(e)?(r={x:_(e.x)?e.x:0,y:_(e.y)?e.y:0},n=t):b(e)&&_(t)&&((r={x:0,y:0})[e]=t),null!=r){var i=this.cy();i.startBatch();for(var a=0;a<this.length;a++){var o=this[a];if(!(i.hasCompoundNodes()&&o.isChild()&&o.ancestors().anySame(this))){var s=o.position(),l={x:s.x+r.x,y:s.y+r.y};n?o.silentPosition(l):o.position(l)}}i.endBatch()}return this},silentShift:function(e,t){return E(e)?this.shift(e,!0):b(e)&&_(t)&&this.shift(e,t,!0),this},renderedPosition:function(e,t){var n=this[0],r=this.cy(),i=r.zoom(),a=r.pan(),o=E(e)?e:void 0,s=void 0!==o||void 0!==t&&b(e);if(n&&n.isNode()){if(!s){var l=n.position();return o=hn(l,i,a),void 0===e?o:o[e]}for(var u=0;u<this.length;u++){var c=this[u];void 0!==t?c.position(e,(t-a[e])/i):void 0!==o&&c.position(dn(o,i,a))}}else if(!s)return;return this},relativePosition:function(e,t){var n=this[0],r=this.cy(),i=E(e)?e:void 0,a=void 0!==i||void 0!==t&&b(e),o=r.hasCompoundNodes();if(n&&n.isNode()){if(!a){var s=n.position(),l=o?n.parent():null,u=l&&l.length>0,c=u;u&&(l=l[0]);var h=c?l.position():{x:0,y:0};return i={x:s.x-h.x,y:s.y-h.y},void 0===e?i:i[e]}for(var d=0;d<this.length;d++){var p=this[d],g=o?p.parent():null,f=g&&g.length>0,v=f;f&&(g=g[0]);var y=v?g.position():{x:0,y:0};void 0!==t?p.position(e,t+y[e]):void 0!==i&&p.position({x:i.x+y.x,y:i.y+y.y})}}else if(!a)return;return this}}).modelPosition=Hs.point=Hs.position,Hs.modelPositions=Hs.points=Hs.positions,Hs.renderedPoint=Hs.renderedPosition,Hs.relativePoint=Hs.relativePosition;var el,tl,nl=qs;el=tl={},tl.renderedBoundingBox=function(e){var t=this.boundingBox(e),n=this.cy(),r=n.zoom(),i=n.pan(),a=t.x1*r+i.x,o=t.x2*r+i.x,s=t.y1*r+i.y,l=t.y2*r+i.y;return{x1:a,x2:o,y1:s,y2:l,w:o-a,h:l-s}},tl.dirtyCompoundBoundsCache=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();return t.styleEnabled()&&t.hasCompoundNodes()?(this.forEachUp((function(t){if(t.isParent()){var n=t._private;n.compoundBoundsClean=!1,n.bbCache=null,e||t.emitAndNotify("bounds")}})),this):this},tl.updateCompoundBounds=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return this;if(!e&&t.batching())return this;function n(e){if(e.isParent()){var t=e._private,n=e.children(),r="include"===e.pstyle("compound-sizing-wrt-labels").value,i={width:{val:e.pstyle("min-width").pfValue,left:e.pstyle("min-width-bias-left"),right:e.pstyle("min-width-bias-right")},height:{val:e.pstyle("min-height").pfValue,top:e.pstyle("min-height-bias-top"),bottom:e.pstyle("min-height-bias-bottom")}},a=n.boundingBox({includeLabels:r,includeOverlays:!1,useCache:!1}),o=t.position;0!==a.w&&0!==a.h||((a={w:e.pstyle("width").pfValue,h:e.pstyle("height").pfValue}).x1=o.x-a.w/2,a.x2=o.x+a.w/2,a.y1=o.y-a.h/2,a.y2=o.y+a.h/2);var s=i.width.left.value;"px"===i.width.left.units&&i.width.val>0&&(s=100*s/i.width.val);var l=i.width.right.value;"px"===i.width.right.units&&i.width.val>0&&(l=100*l/i.width.val);var u=i.height.top.value;"px"===i.height.top.units&&i.height.val>0&&(u=100*u/i.height.val);var c=i.height.bottom.value;"px"===i.height.bottom.units&&i.height.val>0&&(c=100*c/i.height.val);var h=y(i.width.val-a.w,s,l),d=h.biasDiff,p=h.biasComplementDiff,g=y(i.height.val-a.h,u,c),f=g.biasDiff,v=g.biasComplementDiff;t.autoPadding=m(a.w,a.h,e.pstyle("padding"),e.pstyle("padding-relative-to").value),t.autoWidth=Math.max(a.w,i.width.val),o.x=(-d+a.x1+a.x2+p)/2,t.autoHeight=Math.max(a.h,i.height.val),o.y=(-f+a.y1+a.y2+v)/2}function y(e,t,n){var r=0,i=0,a=t+n;return e>0&&a>0&&(r=t/a*e,i=n/a*e),{biasDiff:r,biasComplementDiff:i}}function m(e,t,n,r){if("%"!==n.units)return"px"===n.units?n.pfValue:0;switch(r){case"width":return e>0?n.pfValue*e:0;case"height":return t>0?n.pfValue*t:0;case"average":return e>0&&t>0?n.pfValue*(e+t)/2:0;case"min":return e>0&&t>0?e>t?n.pfValue*t:n.pfValue*e:0;case"max":return e>0&&t>0?e>t?n.pfValue*e:n.pfValue*t:0;default:return 0}}}for(var r=0;r<this.length;r++){var i=this[r],a=i._private;a.compoundBoundsClean&&!e||(n(i),t.batching()||(a.compoundBoundsClean=!0))}return this};var rl=function(e){return e===1/0||e===-1/0?0:e},il=function(e,t,n,r,i){r-t!=0&&i-n!=0&&null!=t&&null!=n&&null!=r&&null!=i&&(e.x1=t<e.x1?t:e.x1,e.x2=r>e.x2?r:e.x2,e.y1=n<e.y1?n:e.y1,e.y2=i>e.y2?i:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},al=function(e,t){return null==t?e:il(e,t.x1,t.y1,t.x2,t.y2)},ol=function(e,t,n){return Ft(e,t,n)},sl=function(e,t,n){if(!t.cy().headless()){var r,i,a=t._private,o=a.rstyle,s=o.arrowWidth/2;if("none"!==t.pstyle(n+"-arrow-shape").value){"source"===n?(r=o.srcX,i=o.srcY):"target"===n?(r=o.tgtX,i=o.tgtY):(r=o.midX,i=o.midY);var l=a.arrowBounds=a.arrowBounds||{},u=l[n]=l[n]||{};u.x1=r-s,u.y1=i-s,u.x2=r+s,u.y2=i+s,u.w=u.x2-u.x1,u.h=u.y2-u.y1,Mn(u,1),il(e,u.x1,u.y1,u.x2,u.y2)}}},ll=function(e,t,n){if(!t.cy().headless()){var r;r=n?n+"-":"";var i=t._private,a=i.rstyle;if(t.pstyle(r+"label").strValue){var o,s,l,u,c=t.pstyle("text-halign"),h=t.pstyle("text-valign"),d=ol(a,"labelWidth",n),p=ol(a,"labelHeight",n),g=ol(a,"labelX",n),f=ol(a,"labelY",n),v=t.pstyle(r+"text-margin-x").pfValue,y=t.pstyle(r+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle(r+"text-rotation"),x=t.pstyle("text-outline-width").pfValue,w=t.pstyle("text-border-width").pfValue/2,E=t.pstyle("text-background-padding").pfValue,T=2,_=p,D=d,C=D/2,N=_/2;if(m)o=g-C,s=g+C,l=f-N,u=f+N;else{switch(c.value){case"left":o=g-D,s=g;break;case"center":o=g-C,s=g+C;break;case"right":o=g,s=g+D}switch(h.value){case"top":l=f-_,u=f;break;case"center":l=f-N,u=f+N;break;case"bottom":l=f,u=f+_}}o+=v-Math.max(x,w)-E-T,s+=v+Math.max(x,w)+E+T,l+=y-Math.max(x,w)-E-T,u+=y+Math.max(x,w)+E+T;var A=n||"main",L=i.labelBounds,S=L[A]=L[A]||{};S.x1=o,S.y1=l,S.x2=s,S.y2=u,S.w=s-o,S.h=u-l;var O=m&&"autorotate"===b.strValue,I=null!=b.pfValue&&0!==b.pfValue;if(O||I){var k=O?ol(i.rstyle,"labelAngle",n):b.pfValue,M=Math.cos(k),P=Math.sin(k),R=(o+s)/2,B=(l+u)/2;if(!m){switch(c.value){case"left":R=s;break;case"right":R=o}switch(h.value){case"top":B=u;break;case"bottom":B=l}}var F=function(e,t){return{x:(e-=R)*M-(t-=B)*P+R,y:e*P+t*M+B}},z=F(o,l),G=F(o,u),Y=F(s,l),X=F(s,u);o=Math.min(z.x,G.x,Y.x,X.x),s=Math.max(z.x,G.x,Y.x,X.x),l=Math.min(z.y,G.y,Y.y,X.y),u=Math.max(z.y,G.y,Y.y,X.y)}var V=A+"Rot",U=L[V]=L[V]||{};U.x1=o,U.y1=l,U.x2=s,U.y2=u,U.w=s-o,U.h=u-l,il(e,o,l,s,u),il(i.labelBounds.all,o,l,s,u)}return e}},ul=function(e,t){var n,r,i,a,o,s,l=e._private.cy,u=l.styleEnabled(),c=l.headless(),h=Ln(),d=e._private,p=e.isNode(),g=e.isEdge(),f=d.rstyle,v=p&&u?e.pstyle("bounds-expansion").pfValue:[0],y=function(e){return"none"!==e.pstyle("display").value},m=!u||y(e)&&(!g||y(e.source())&&y(e.target()));if(m){var b=0;u&&t.includeOverlays&&0!==e.pstyle("overlay-opacity").value&&(b=e.pstyle("overlay-padding").value);var x=0;u&&t.includeUnderlays&&0!==e.pstyle("underlay-opacity").value&&(x=e.pstyle("underlay-padding").value);var w=Math.max(b,x),E=0;if(u&&(E=e.pstyle("width").pfValue/2),p&&t.includeNodes){var T=e.position();o=T.x,s=T.y;var _=e.outerWidth()/2,D=e.outerHeight()/2;il(h,n=o-_,i=s-D,r=o+_,a=s+D)}else if(g&&t.includeEdges)if(u&&!c){var C=e.pstyle("curve-style").strValue;if(n=Math.min(f.srcX,f.midX,f.tgtX),r=Math.max(f.srcX,f.midX,f.tgtX),i=Math.min(f.srcY,f.midY,f.tgtY),a=Math.max(f.srcY,f.midY,f.tgtY),il(h,n-=E,i-=E,r+=E,a+=E),"haystack"===C){var N=f.haystackPts;if(N&&2===N.length){if(n=N[0].x,i=N[0].y,n>(r=N[1].x)){var A=n;n=r,r=A}if(i>(a=N[1].y)){var L=i;i=a,a=L}il(h,n-E,i-E,r+E,a+E)}}else if("bezier"===C||"unbundled-bezier"===C||"segments"===C||"taxi"===C){var S;switch(C){case"bezier":case"unbundled-bezier":S=f.bezierPts;break;case"segments":case"taxi":S=f.linePts}if(null!=S)for(var O=0;O<S.length;O++){var I=S[O];n=I.x-E,r=I.x+E,i=I.y-E,a=I.y+E,il(h,n,i,r,a)}}}else{var k=e.source().position(),M=e.target().position();if((n=k.x)>(r=M.x)){var P=n;n=r,r=P}if((i=k.y)>(a=M.y)){var R=i;i=a,a=R}il(h,n-=E,i-=E,r+=E,a+=E)}if(u&&t.includeEdges&&g&&(sl(h,e,"mid-source"),sl(h,e,"mid-target"),sl(h,e,"source"),sl(h,e,"target")),u&&"yes"===e.pstyle("ghost").value){var B=e.pstyle("ghost-offset-x").pfValue,F=e.pstyle("ghost-offset-y").pfValue;il(h,h.x1+B,h.y1+F,h.x2+B,h.y2+F)}var z=d.bodyBounds=d.bodyBounds||{};Rn(z,h),Pn(z,v),Mn(z,1),u&&(n=h.x1,r=h.x2,i=h.y1,a=h.y2,il(h,n-w,i-w,r+w,a+w));var G=d.overlayBounds=d.overlayBounds||{};Rn(G,h),Pn(G,v),Mn(G,1);var Y=d.labelBounds=d.labelBounds||{};null!=Y.all?On(Y.all):Y.all=Ln(),u&&t.includeLabels&&(t.includeMainLabels&&ll(h,e,null),g&&(t.includeSourceLabels&&ll(h,e,"source"),t.includeTargetLabels&&ll(h,e,"target")))}return h.x1=rl(h.x1),h.y1=rl(h.y1),h.x2=rl(h.x2),h.y2=rl(h.y2),h.w=rl(h.x2-h.x1),h.h=rl(h.y2-h.y1),h.w>0&&h.h>0&&m&&(Pn(h,v),Mn(h,1)),h},cl=function(e){var t=0,n=function(e){return(e?1:0)<<t++},r=0;return r+=n(e.incudeNodes),r+=n(e.includeEdges),r+=n(e.includeLabels),r+=n(e.includeMainLabels),r+=n(e.includeSourceLabels),r+=n(e.includeTargetLabels),r+=n(e.includeOverlays)},hl=function(e){if(e.isEdge()){var t=e.source().position(),n=e.target().position(),r=function(e){return Math.round(e)};return pt([r(t.x),r(t.y),r(n.x),r(n.y)])}return 0},dl=function(e,t){var n,r=e._private,i=e.isEdge(),a=(null==t?gl:cl(t))===gl,o=hl(e),s=r.bbCachePosKey===o,l=t.useCache&&s,u=function(e){return null==e._private.bbCache||e._private.styleDirty};if(!l||u(e)||i&&u(e.source())||u(e.target())?(s||e.recalculateRenderedStyle(l),n=ul(e,pl),r.bbCache=n,r.bbCachePosKey=o):n=r.bbCache,!a){var c=e.isNode();n=Ln(),(t.includeNodes&&c||t.includeEdges&&!c)&&(t.includeOverlays?al(n,r.overlayBounds):al(n,r.bodyBounds)),t.includeLabels&&(t.includeMainLabels&&(!i||t.includeSourceLabels&&t.includeTargetLabels)?al(n,r.labelBounds.all):(t.includeMainLabels&&al(n,r.labelBounds.mainRot),t.includeSourceLabels&&al(n,r.labelBounds.sourceRot),t.includeTargetLabels&&al(n,r.labelBounds.targetRot))),n.w=n.x2-n.x1,n.h=n.y2-n.y1}return n},pl={includeNodes:!0,includeEdges:!0,includeLabels:!0,includeMainLabels:!0,includeSourceLabels:!0,includeTargetLabels:!0,includeOverlays:!0,includeUnderlays:!0,useCache:!0},gl=cl(pl),fl=Mt(pl);tl.boundingBox=function(e){var t;if(1!==this.length||null==this[0]._private.bbCache||this[0]._private.styleDirty||void 0!==e&&void 0!==e.useCache&&!0!==e.useCache){t=Ln();var n=fl(e=e||pl),r=this;if(r.cy().styleEnabled())for(var i=0;i<r.length;i++){var a=r[i],o=a._private,s=hl(a),l=o.bbCachePosKey===s,u=n.useCache&&l&&!o.styleDirty;a.recalculateRenderedStyle(u)}this.updateCompoundBounds(!e.useCache);for(var c=0;c<r.length;c++){var h=r[c];al(t,dl(h,n))}}else e=void 0===e?pl:fl(e),t=dl(this[0],e);return t.x1=rl(t.x1),t.y1=rl(t.y1),t.x2=rl(t.x2),t.y2=rl(t.y2),t.w=rl(t.x2-t.x1),t.h=rl(t.y2-t.y1),t},tl.dirtyBoundingBoxCache=function(){for(var e=0;e<this.length;e++){var t=this[e]._private;t.bbCache=null,t.bbCachePosKey=null,t.bodyBounds=null,t.overlayBounds=null,t.labelBounds.all=null,t.labelBounds.source=null,t.labelBounds.target=null,t.labelBounds.main=null,t.labelBounds.sourceRot=null,t.labelBounds.targetRot=null,t.labelBounds.mainRot=null,t.arrowBounds.source=null,t.arrowBounds.target=null,t.arrowBounds["mid-source"]=null,t.arrowBounds["mid-target"]=null}return this.emitAndNotify("bounds"),this},tl.boundingBoxAt=function(e){var t=this.nodes(),n=this.cy(),r=n.hasCompoundNodes(),i=n.collection();if(r&&(i=t.filter((function(e){return e.isParent()})),t=t.not(i)),E(e)){var a=e;e=function(){return a}}var o=function(t,n){return t._private.bbAtOldPos=e(t,n)},s=function(e){return e._private.bbAtOldPos};n.startBatch(),t.forEach(o).silentPositions(e),r&&(i.dirtyCompoundBoundsCache(),i.dirtyBoundingBoxCache(),i.updateCompoundBounds(!0));var l=Sn(this.boundingBox({useCache:!1}));return t.silentPositions(s),r&&(i.dirtyCompoundBoundsCache(),i.dirtyBoundingBoxCache(),i.updateCompoundBounds(!0)),n.endBatch(),l},el.boundingbox=el.bb=el.boundingBox,el.renderedBoundingbox=el.renderedBoundingBox;var vl,yl,ml=tl;vl=yl={};var bl=function(e){e.uppercaseName=X(e.name),e.autoName="auto"+e.uppercaseName,e.labelName="label"+e.uppercaseName,e.outerName="outer"+e.uppercaseName,e.uppercaseOuterName=X(e.outerName),vl[e.name]=function(){var t=this[0],n=t._private,r=n.cy._private.styleEnabled;if(t){if(r){if(t.isParent())return t.updateCompoundBounds(),n[e.autoName]||0;var i=t.pstyle(e.name);return"label"===i.strValue?(t.recalculateRenderedStyle(),n.rstyle[e.labelName]||0):i.pfValue}return 1}},vl["outer"+e.uppercaseName]=function(){var t=this[0],n=t._private.cy._private.styleEnabled;if(t)return n?t[e.name]()+t.pstyle("border-width").pfValue+2*t.padding():1},vl["rendered"+e.uppercaseName]=function(){var t=this[0];if(t)return t[e.name]()*this.cy().zoom()},vl["rendered"+e.uppercaseOuterName]=function(){var t=this[0];if(t)return t[e.outerName]()*this.cy().zoom()}};bl({name:"width"}),bl({name:"height"}),yl.padding=function(){var e=this[0],t=e._private;return e.isParent()?(e.updateCompoundBounds(),void 0!==t.autoPadding?t.autoPadding:e.pstyle("padding").pfValue):e.pstyle("padding").pfValue},yl.paddedHeight=function(){var e=this[0];return e.height()+2*e.padding()},yl.paddedWidth=function(){var e=this[0];return e.width()+2*e.padding()};var xl=yl,wl=function(e,t){if(e.isEdge())return t(e)},El=function(e,t){if(e.isEdge()){var n=e.cy();return hn(t(e),n.zoom(),n.pan())}},Tl=function(e,t){if(e.isEdge()){var n=e.cy(),r=n.pan(),i=n.zoom();return t(e).map((function(e){return hn(e,i,r)}))}},_l={controlPoints:{get:function(e){return e.renderer().getControlPoints(e)},mult:!0},segmentPoints:{get:function(e){return e.renderer().getSegmentPoints(e)},mult:!0},sourceEndpoint:{get:function(e){return e.renderer().getSourceEndpoint(e)}},targetEndpoint:{get:function(e){return e.renderer().getTargetEndpoint(e)}},midpoint:{get:function(e){return e.renderer().getEdgeMidpoint(e)}}},Dl=function(e){return"rendered"+e[0].toUpperCase()+e.substr(1)},Cl=Object.keys(_l).reduce((function(e,t){var n=_l[t],r=Dl(t);return e[t]=function(){return wl(this,n.get)},n.mult?e[r]=function(){return Tl(this,n.get)}:e[r]=function(){return El(this,n.get)},e}),{}),Nl=Q({},nl,ml,xl,Cl),Al=function(e,t){this.recycle(e,t)};function Ll(){return!1}function Sl(){return!0}Al.prototype={instanceString:function(){return"event"},recycle:function(e,t){if(this.isImmediatePropagationStopped=this.isPropagationStopped=this.isDefaultPrevented=Ll,null!=e&&e.preventDefault?(this.type=e.type,this.isDefaultPrevented=e.defaultPrevented?Sl:Ll):null!=e&&e.type?t=e:this.type=e,null!=t&&(this.originalEvent=t.originalEvent,this.type=null!=t.type?t.type:this.type,this.cy=t.cy,this.target=t.target,this.position=t.position,this.renderedPosition=t.renderedPosition,this.namespace=t.namespace,this.layout=t.layout),null!=this.cy&&null!=this.position&&null==this.renderedPosition){var n=this.position,r=this.cy.zoom(),i=this.cy.pan();this.renderedPosition={x:n.x*r+i.x,y:n.y*r+i.y}}this.timeStamp=e&&e.timeStamp||Date.now()},preventDefault:function(){this.isDefaultPrevented=Sl;var e=this.originalEvent;e&&e.preventDefault&&e.preventDefault()},stopPropagation:function(){this.isPropagationStopped=Sl;var e=this.originalEvent;e&&e.stopPropagation&&e.stopPropagation()},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Sl,this.stopPropagation()},isDefaultPrevented:Ll,isPropagationStopped:Ll,isImmediatePropagationStopped:Ll};var Ol=/^([^.]+)(\.(?:[^.]+))?$/,Il=".*",kl={qualifierCompare:function(e,t){return e===t},eventMatches:function(){return!0},addEventFields:function(){},callbackContext:function(e){return e},beforeEmit:function(){},afterEmit:function(){},bubble:function(){return!1},parent:function(){return null},context:null},Ml=Object.keys(kl),Pl={};function Rl(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Pl,t=arguments.length>1?arguments[1]:void 0,n=0;n<Ml.length;n++){var r=Ml[n];this[r]=e[r]||kl[r]}this.context=t||this.context,this.listeners=[],this.emitting=0}var Bl=Rl.prototype,Fl=function(e,t,n,r,i,a,o){x(r)&&(i=r,r=null),o&&(a=null==a?o:Q({},a,o));for(var s=w(n)?n:n.split(/\s+/),l=0;l<s.length;l++){var u=s[l];if(!k(u)){var c=u.match(Ol);if(c&&!1===t(e,u,c[1],c[2]?c[2]:null,r,i,a))break}}},zl=function(e,t){return e.addEventFields(e.context,t),new Al(t.type,t)},Gl=function(e,t,n){if(I(n))t(e,n);else if(E(n))t(e,zl(e,n));else for(var r=w(n)?n:n.split(/\s+/),i=0;i<r.length;i++){var a=r[i];if(!k(a)){var o=a.match(Ol);if(o){var s=o[1],l=o[2]?o[2]:null;t(e,zl(e,{type:s,namespace:l,target:e.context}))}}}};Bl.on=Bl.addListener=function(e,t,n,r,i){return Fl(this,(function(e,t,n,r,i,a,o){x(a)&&e.listeners.push({event:t,callback:a,type:n,namespace:r,qualifier:i,conf:o})}),e,t,n,r,i),this},Bl.one=function(e,t,n,r){return this.on(e,t,n,r,{one:!0})},Bl.removeListener=Bl.off=function(e,t,n,r){var i=this;0!==this.emitting&&(this.listeners=St(this.listeners));for(var a=this.listeners,o=function(o){var s=a[o];Fl(i,(function(t,n,r,i,l,u){if((s.type===r||"*"===e)&&(!i&&".*"!==s.namespace||s.namespace===i)&&(!l||t.qualifierCompare(s.qualifier,l))&&(!u||s.callback===u))return a.splice(o,1),!1}),e,t,n,r)},s=a.length-1;s>=0;s--)o(s);return this},Bl.removeAllListeners=function(){return this.removeListener("*")},Bl.emit=Bl.trigger=function(e,t,n){var r=this.listeners,i=r.length;return this.emitting++,w(t)||(t=[t]),Gl(this,(function(e,a){null!=n&&(r=[{event:a.event,type:a.type,namespace:a.namespace,callback:n}],i=r.length);for(var o=function(n){var i=r[n];if(i.type===a.type&&(!i.namespace||i.namespace===a.namespace||i.namespace===Il)&&e.eventMatches(e.context,i,a)){var o=[a];null!=t&&Bt(o,t),e.beforeEmit(e.context,i,a),i.conf&&i.conf.one&&(e.listeners=e.listeners.filter((function(e){return e!==i})));var s=e.callbackContext(e.context,i,a),l=i.callback.apply(s,o);e.afterEmit(e.context,i,a),!1===l&&(a.stopPropagation(),a.preventDefault())}},s=0;s<i;s++)o(s);e.bubble(e.context)&&!a.isPropagationStopped()&&e.parent(e.context).emit(a,t)}),e),this.emitting--,this};var Yl={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&A(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e.cy(),t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e},beforeEmit:function(e,t){t.conf&&t.conf.once&&t.conf.onceCollection.removeListener(t.event,t.qualifier,t.callback)},bubble:function(){return!0},parent:function(e){return e.isChild()?e.parent():e.cy()}},Xl=function(e){return b(e)?new Ps(e):e},Vl={createEmitter:function(){for(var e=0;e<this.length;e++){var t=this[e],n=t._private;n.emitter||(n.emitter=new Rl(Yl,t))}return this},emitter:function(){return this._private.emitter},on:function(e,t,n){for(var r=Xl(t),i=0;i<this.length;i++)this[i].emitter().on(e,r,n);return this},removeListener:function(e,t,n){for(var r=Xl(t),i=0;i<this.length;i++)this[i].emitter().removeListener(e,r,n);return this},removeAllListeners:function(){for(var e=0;e<this.length;e++)this[e].emitter().removeAllListeners();return this},one:function(e,t,n){for(var r=Xl(t),i=0;i<this.length;i++)this[i].emitter().one(e,r,n);return this},once:function(e,t,n){for(var r=Xl(t),i=0;i<this.length;i++)this[i].emitter().on(e,r,n,{once:!0,onceCollection:this})},emit:function(e,t){for(var n=0;n<this.length;n++)this[n].emitter().emit(e,t);return this},emitAndNotify:function(e,t){if(0!==this.length)return this.cy().notify(e,this),this.emit(e,t),this}};hs.eventAliasesOn(Vl);var Ul={nodes:function(e){return this.filter((function(e){return e.isNode()})).filter(e)},edges:function(e){return this.filter((function(e){return e.isEdge()})).filter(e)},byGroup:function(){for(var e=this.spawn(),t=this.spawn(),n=0;n<this.length;n++){var r=this[n];r.isNode()?e.push(r):t.push(r)}return{nodes:e,edges:t}},filter:function(e,t){if(void 0===e)return this;if(b(e)||N(e))return new Ps(e).filter(this);if(x(e)){for(var n=this.spawn(),r=this,i=0;i<r.length;i++){var a=r[i];(t?e.apply(t,[a,i,r]):e(a,i,r))&&n.push(a)}return n}return this.spawn()},not:function(e){if(e){b(e)&&(e=this.filter(e));for(var t=this.spawn(),n=0;n<this.length;n++){var r=this[n];e.has(r)||t.push(r)}return t}return this},absoluteComplement:function(){return this.cy().mutableElements().not(this)},intersect:function(e){if(b(e)){var t=e;return this.filter(t)}for(var n=this.spawn(),r=this,i=e,a=this.length<e.length,o=a?r:i,s=a?i:r,l=0;l<o.length;l++){var u=o[l];s.has(u)&&n.push(u)}return n},xor:function(e){var t=this._private.cy;b(e)&&(e=t.$(e));var n=this.spawn(),r=this,i=e,a=function(e,t){for(var r=0;r<e.length;r++){var i=e[r],a=i._private.data.id;t.hasElementWithId(a)||n.push(i)}};return a(r,i),a(i,r),n},diff:function(e){var t=this._private.cy;b(e)&&(e=t.$(e));var n=this.spawn(),r=this.spawn(),i=this.spawn(),a=this,o=e,s=function(e,t,n){for(var r=0;r<e.length;r++){var a=e[r],o=a._private.data.id;t.hasElementWithId(o)?i.merge(a):n.push(a)}};return s(a,o,n),s(o,a,r),{left:n,right:r,both:i}},add:function(e){var t=this._private.cy;if(!e)return this;if(b(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=this.spawnSelf(),i=0;i<e.length;i++){var a=e[i],o=!this.has(a);o&&r.push(a)}return r},merge:function(e){var t=this._private,n=t.cy;if(!e)return this;if(e&&b(e)){var r=e;e=n.mutableElements().filter(r)}for(var i=t.map,a=0;a<e.length;a++){var o=e[a],s=o._private.data.id;if(!i.has(s)){var l=this.length++;this[l]=o,i.set(s,{ele:o,index:l})}}return this},unmergeAt:function(e){var t=this[e].id(),n=this._private.map;this[e]=void 0,n.delete(t);var r=e===this.length-1;if(this.length>1&&!r){var i=this.length-1,a=this[i],o=a._private.data.id;this[i]=void 0,this[e]=a,n.set(o,{ele:a,index:e})}return this.length--,this},unmergeOne:function(e){e=e[0];var t=this._private,n=e._private.data.id,r=t.map.get(n);if(!r)return this;var i=r.index;return this.unmergeAt(i),this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(e&&b(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=0;r<e.length;r++)this.unmergeOne(e[r]);return this},unmergeBy:function(e){for(var t=this.length-1;t>=0;t--)e(this[t])&&this.unmergeAt(t);return this},map:function(e,t){for(var n=[],r=this,i=0;i<r.length;i++){var a=r[i],o=t?e.apply(t,[a,i,r]):e(a,i,r);n.push(o)}return n},reduce:function(e,t){for(var n=t,r=this,i=0;i<r.length;i++)n=e(n,r[i],i,r);return n},max:function(e,t){for(var n,r=-1/0,i=this,a=0;a<i.length;a++){var o=i[a],s=t?e.apply(t,[o,a,i]):e(o,a,i);s>r&&(r=s,n=o)}return{value:r,ele:n}},min:function(e,t){for(var n,r=1/0,i=this,a=0;a<i.length;a++){var o=i[a],s=t?e.apply(t,[o,a,i]):e(o,a,i);s<r&&(r=s,n=o)}return{value:r,ele:n}}},jl=Ul;jl.u=jl["|"]=jl["+"]=jl.union=jl.or=jl.add,jl["\\"]=jl["!"]=jl["-"]=jl.difference=jl.relativeComplement=jl.subtract=jl.not,jl.n=jl["&"]=jl["."]=jl.and=jl.intersection=jl.intersect,jl["^"]=jl["(+)"]=jl["(-)"]=jl.symmetricDifference=jl.symdiff=jl.xor,jl.fnFilter=jl.filterFn=jl.stdFilter=jl.filter,jl.complement=jl.abscomp=jl.absoluteComplement;var Hl,ql={isNode:function(){return"nodes"===this.group()},isEdge:function(){return"edges"===this.group()},isLoop:function(){return this.isEdge()&&this.source()[0]===this.target()[0]},isSimple:function(){return this.isEdge()&&this.source()[0]!==this.target()[0]},group:function(){var e=this[0];if(e)return e._private.group}},Wl=function(e,t){var n=e.cy().hasCompoundNodes();function r(e){var t=e.pstyle("z-compound-depth");return"auto"===t.value?n?e.zDepth():0:"bottom"===t.value?-1:"top"===t.value?xt:0}var i=r(e)-r(t);if(0!==i)return i;function a(e){return"auto"===e.pstyle("z-index-compare").value&&e.isNode()?1:0}var o=a(e)-a(t);if(0!==o)return o;var s=e.pstyle("z-index").value-t.pstyle("z-index").value;return 0!==s?s:e.poolIndex()-t.poolIndex()},$l={forEach:function(e,t){if(x(e))for(var n=this.length,r=0;r<n;r++){var i=this[r];if(!1===(t?e.apply(t,[i,r,this]):e(i,r,this)))break}return this},toArray:function(){for(var e=[],t=0;t<this.length;t++)e.push(this[t]);return e},slice:function(e,t){var n=[],r=this.length;null==t&&(t=r),null==e&&(e=0),e<0&&(e=r+e),t<0&&(t=r+t);for(var i=e;i>=0&&i<t&&i<r;i++)n.push(this[i]);return this.spawn(n)},size:function(){return this.length},eq:function(e){return this[e]||this.spawn()},first:function(){return this[0]||this.spawn()},last:function(){return this[this.length-1]||this.spawn()},empty:function(){return 0===this.length},nonempty:function(){return!this.empty()},sort:function(e){if(!x(e))return this;var t=this.toArray().sort(e);return this.spawn(t)},sortByZIndex:function(){return this.sort(Wl)},zDepth:function(){var e=this[0];if(e){var t=e._private;if("nodes"===t.group){var n=t.data.parent?e.parents().size():0;return e.isParent()?n:xt-1}var r=t.source,i=t.target,a=r.zDepth(),o=i.zDepth();return Math.max(a,o,0)}}};$l.each=$l.forEach,Hl="undefined",("undefined"==typeof Symbol?"undefined":e(Symbol))!=Hl&&e(Symbol.iterator)!=Hl&&($l[Symbol.iterator]=function(){var e=this,t={value:void 0,done:!1},n=0,r=this.length;return a({next:function(){return n<r?t.value=e[n++]:(t.value=void 0,t.done=!0),t}},Symbol.iterator,(function(){return this}))});var Kl=Mt({nodeDimensionsIncludeLabels:!1}),Zl={layoutDimensions:function(e){var t;if(e=Kl(e),this.takesUpSpace())if(e.nodeDimensionsIncludeLabels){var n=this.boundingBox();t={w:n.w,h:n.h}}else t={w:this.outerWidth(),h:this.outerHeight()};else t={w:0,h:0};return 0!==t.w&&0!==t.h||(t.w=t.h=1),t},layoutPositions:function(e,t,n){var r=this.nodes().filter((function(e){return!e.isParent()})),i=this.cy(),a=t.eles,o=function(e){return e.id()},s=F(n,o);e.emit({type:"layoutstart",layout:e}),e.animations=[];var l=function(e,t,n){var r={x:t.x1+t.w/2,y:t.y1+t.h/2},i={x:(n.x-r.x)*e,y:(n.y-r.y)*e};return{x:r.x+i.x,y:r.y+i.y}},u=t.spacingFactor&&1!==t.spacingFactor,c=function(){if(!u)return null;for(var e=Ln(),t=0;t<r.length;t++){var n=r[t],i=s(n,t);kn(e,i.x,i.y)}return e},h=c(),d=F((function(e,n){var r=s(e,n);if(u){var i=Math.abs(t.spacingFactor);r=l(i,h,r)}return null!=t.transform&&(r=t.transform(e,r)),r}),o);if(t.animate){for(var p=0;p<r.length;p++){var g=r[p],f=d(g,p);if(null==t.animateFilter||t.animateFilter(g,p)){var v=g.animation({position:f,duration:t.animationDuration,easing:t.animationEasing});e.animations.push(v)}else g.position(f)}if(t.fit){var y=i.animation({fit:{boundingBox:a.boundingBoxAt(d),padding:t.padding},duration:t.animationDuration,easing:t.animationEasing});e.animations.push(y)}else if(void 0!==t.zoom&&void 0!==t.pan){var m=i.animation({zoom:t.zoom,pan:t.pan,duration:t.animationDuration,easing:t.animationEasing});e.animations.push(m)}e.animations.forEach((function(e){return e.play()})),e.one("layoutready",t.ready),e.emit({type:"layoutready",layout:e}),Gi.all(e.animations.map((function(e){return e.promise()}))).then((function(){e.one("layoutstop",t.stop),e.emit({type:"layoutstop",layout:e})}))}else r.positions(d),t.fit&&i.fit(t.eles,t.padding),null!=t.zoom&&i.zoom(t.zoom),t.pan&&i.pan(t.pan),e.one("layoutready",t.ready),e.emit({type:"layoutready",layout:e}),e.one("layoutstop",t.stop),e.emit({type:"layoutstop",layout:e});return this},layout:function(e){return this.cy().makeLayout(Q({},e,{eles:this}))}};function Ql(e,t,n){var r,i=n._private,a=i.styleCache=i.styleCache||[];return null!=(r=a[e])?r:r=a[e]=t(n)}function Jl(e,t){return e=gt(e),function(n){return Ql(e,t,n)}}function eu(e,t){e=gt(e);var n=function(e){return t.call(e)};return function(){var t=this[0];if(t)return Ql(e,n,t)}}Zl.createLayout=Zl.makeLayout=Zl.layout;var tu={recalculateRenderedStyle:function(e){var t=this.cy(),n=t.renderer(),r=t.styleEnabled();return n&&r&&n.recalculateRenderedStyle(this,e),this},dirtyStyleCache:function(){var e,t=this.cy(),n=function(e){return e._private.styleCache=null};return t.hasCompoundNodes()?((e=this.spawnSelf().merge(this.descendants()).merge(this.parents())).merge(e.connectedEdges()),e.forEach(n)):this.forEach((function(e){n(e),e.connectedEdges().forEach(n)})),this},updateStyle:function(e){var t=this._private.cy;if(!t.styleEnabled())return this;if(t.batching())return t._private.batchStyleEles.merge(this),this;var n=this;e=!(!e&&void 0!==e),t.hasCompoundNodes()&&(n=this.spawnSelf().merge(this.descendants()).merge(this.parents()));var r=n;return e?r.emitAndNotify("style"):r.emit("style"),n.forEach((function(e){return e._private.styleDirty=!0})),this},cleanStyle:function(){var e=this.cy();if(e.styleEnabled())for(var t=0;t<this.length;t++){var n=this[t];n._private.styleDirty&&(n._private.styleDirty=!1,e.style().apply(n))}},parsedStyle:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this[0],r=n.cy();if(r.styleEnabled()&&n){this.cleanStyle();var i=n._private.style[e];return null!=i?i:t?r.style().getDefaultProperty(e):null}},numericStyle:function(e){var t=this[0];if(t.cy().styleEnabled()&&t){var n=t.pstyle(e);return void 0!==n.pfValue?n.pfValue:n.value}},numericStyleUnits:function(e){var t=this[0];if(t.cy().styleEnabled())return t?t.pstyle(e).units:void 0},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=this[0];return n?t.style().getRenderedStyle(n,e):void 0},style:function(e,t){var n=this.cy();if(!n.styleEnabled())return this;var r=!1,i=n.style();if(E(e)){var a=e;i.applyBypass(this,a,r),this.emitAndNotify("style")}else if(b(e)){if(void 0===t){var o=this[0];return o?i.getStylePropertyValue(o,e):void 0}i.applyBypass(this,e,t,r),this.emitAndNotify("style")}else if(void 0===e){var s=this[0];return s?i.getRawStyle(s):void 0}return this},removeStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=!1,r=t.style(),i=this;if(void 0===e)for(var a=0;a<i.length;a++){var o=i[a];r.removeAllBypasses(o,n)}else{e=e.split(/\s+/);for(var s=0;s<i.length;s++){var l=i[s];r.removeBypasses(l,e,n)}}return this.emitAndNotify("style"),this},show:function(){return this.css("display","element"),this},hide:function(){return this.css("display","none"),this},effectiveOpacity:function(){var e=this.cy();if(!e.styleEnabled())return 1;var t=e.hasCompoundNodes(),n=this[0];if(n){var r=n._private,i=n.pstyle("opacity").value;if(!t)return i;var a=r.data.parent?n.parents():null;if(a)for(var o=0;o<a.length;o++)i*=a[o].pstyle("opacity").value;return i}},transparent:function(){if(!this.cy().styleEnabled())return!1;var e=this[0],t=e.cy().hasCompoundNodes();return e?t?0===e.effectiveOpacity():0===e.pstyle("opacity").value:void 0},backgrounding:function(){return!!this.cy().styleEnabled()&&!!this[0]._private.backgrounding}};function nu(e,t){var n=e._private.data.parent?e.parents():null;if(n)for(var r=0;r<n.length;r++)if(!t(n[r]))return!1;return!0}function ru(e){var t=e.ok,n=e.edgeOkViaNode||e.ok,r=e.parentOk||e.ok;return function(){var e=this.cy();if(!e.styleEnabled())return!0;var i=this[0],a=e.hasCompoundNodes();if(i){var o=i._private;if(!t(i))return!1;if(i.isNode())return!a||nu(i,r);var s=o.source,l=o.target;return n(s)&&(!a||nu(s,n))&&(s===l||n(l)&&(!a||nu(l,n)))}}}var iu=Jl("eleTakesUpSpace",(function(e){return"element"===e.pstyle("display").value&&0!==e.width()&&(!e.isNode()||0!==e.height())}));tu.takesUpSpace=eu("takesUpSpace",ru({ok:iu}));var au=Jl("eleInteractive",(function(e){return"yes"===e.pstyle("events").value&&"visible"===e.pstyle("visibility").value&&iu(e)})),ou=Jl("parentInteractive",(function(e){return"visible"===e.pstyle("visibility").value&&iu(e)}));tu.interactive=eu("interactive",ru({ok:au,parentOk:ou,edgeOkViaNode:iu})),tu.noninteractive=function(){var e=this[0];if(e)return!e.interactive()};var su=Jl("eleVisible",(function(e){return"visible"===e.pstyle("visibility").value&&0!==e.pstyle("opacity").pfValue&&iu(e)})),lu=iu;tu.visible=eu("visible",ru({ok:su,edgeOkViaNode:lu})),tu.hidden=function(){var e=this[0];if(e)return!e.visible()},tu.isBundledBezier=eu("isBundledBezier",(function(){return!!this.cy().styleEnabled()&&!this.removed()&&"bezier"===this.pstyle("curve-style").value&&this.takesUpSpace()})),tu.bypass=tu.css=tu.style,tu.renderedCss=tu.renderedStyle,tu.removeBypass=tu.removeCss=tu.removeStyle,tu.pstyle=tu.parsedStyle;var uu={};function cu(e){return function(){var t=arguments,n=[];if(2===t.length){var r=t[0],i=t[1];this.on(e.event,r,i)}else if(1===t.length&&x(t[0])){var a=t[0];this.on(e.event,a)}else if(0===t.length||1===t.length&&w(t[0])){for(var o=1===t.length?t[0]:null,s=0;s<this.length;s++){var l=this[s],u=!e.ableField||l._private[e.ableField],c=l._private[e.field]!=e.value;if(e.overrideAble){var h=e.overrideAble(l);if(void 0!==h&&(u=h,!h))return this}u&&(l._private[e.field]=e.value,c&&n.push(l))}var d=this.spawn(n);d.updateStyle(),d.emit(e.event),o&&d.emit(o)}return this}}function hu(e){uu[e.field]=function(){var t=this[0];if(t){if(e.overrideField){var n=e.overrideField(t);if(void 0!==n)return n}return t._private[e.field]}},uu[e.on]=cu({event:e.on,field:e.field,ableField:e.ableField,overrideAble:e.overrideAble,value:!0}),uu[e.off]=cu({event:e.off,field:e.field,ableField:e.ableField,overrideAble:e.overrideAble,value:!1})}hu({field:"locked",overrideField:function(e){return!!e.cy().autolock()||void 0},on:"lock",off:"unlock"}),hu({field:"grabbable",overrideField:function(e){return!e.cy().autoungrabify()&&!e.pannable()&&void 0},on:"grabify",off:"ungrabify"}),hu({field:"selected",ableField:"selectable",overrideAble:function(e){return!e.cy().autounselectify()&&void 0},on:"select",off:"unselect"}),hu({field:"selectable",overrideField:function(e){return!e.cy().autounselectify()&&void 0},on:"selectify",off:"unselectify"}),uu.deselect=uu.unselect,uu.grabbed=function(){var e=this[0];if(e)return e._private.grabbed},hu({field:"active",on:"activate",off:"unactivate"}),hu({field:"pannable",on:"panify",off:"unpanify"}),uu.inactive=function(){var e=this[0];if(e)return!e._private.active};var du={},pu=function(e){return function(t){for(var n=this,r=[],i=0;i<n.length;i++){var a=n[i];if(a.isNode()){for(var o=!1,s=a.connectedEdges(),l=0;l<s.length;l++){var u=s[l],c=u.source(),h=u.target();if(e.noIncomingEdges&&h===a&&c!==a||e.noOutgoingEdges&&c===a&&h!==a){o=!0;break}}o||r.push(a)}}return this.spawn(r,!0).filter(t)}},gu=function(e){return function(t){for(var n=this,r=[],i=0;i<n.length;i++){var a=n[i];if(a.isNode())for(var o=a.connectedEdges(),s=0;s<o.length;s++){var l=o[s],u=l.source(),c=l.target();e.outgoing&&u===a?(r.push(l),r.push(c)):e.incoming&&c===a&&(r.push(l),r.push(u))}}return this.spawn(r,!0).filter(t)}},fu=function(e){return function(t){for(var n=this,r=[],i={};;){var a=e.outgoing?n.outgoers():n.incomers();if(0===a.length)break;for(var o=!1,s=0;s<a.length;s++){var l=a[s],u=l.id();i[u]||(i[u]=!0,r.push(l),o=!0)}if(!o)break;n=a}return this.spawn(r,!0).filter(t)}};function vu(e){return function(t){for(var n=[],r=0;r<this.length;r++){var i=this[r]._private[e.attr];i&&n.push(i)}return this.spawn(n,!0).filter(t)}}function yu(e){return function(t){var n=[],r=this._private.cy,i=e||{};b(t)&&(t=r.$(t));for(var a=0;a<t.length;a++)for(var o=t[a]._private.edges,s=0;s<o.length;s++){var l=o[s],u=l._private.data,c=this.hasElementWithId(u.source)&&t.hasElementWithId(u.target),h=t.hasElementWithId(u.source)&&this.hasElementWithId(u.target);if(c||h){if(i.thisIsSrc||i.thisIsTgt){if(i.thisIsSrc&&!c)continue;if(i.thisIsTgt&&!h)continue}n.push(l)}}return this.spawn(n,!0)}}function mu(e){return e=Q({},{codirected:!1},e),function(t){for(var n=[],r=this.edges(),i=e,a=0;a<r.length;a++)for(var o=r[a]._private,s=o.source,l=s._private.data.id,u=o.data.target,c=s._private.edges,h=0;h<c.length;h++){var d=c[h],p=d._private.data,g=p.target,f=p.source,v=g===u&&f===l,y=l===g&&u===f;(i.codirected&&v||!i.codirected&&(v||y))&&n.push(d)}return this.spawn(n,!0).filter(t)}}du.clearTraversalCache=function(){for(var e=0;e<this.length;e++)this[e]._private.traversalCache=null},Q(du,{roots:pu({noIncomingEdges:!0}),leaves:pu({noOutgoingEdges:!0}),outgoers:Gs(gu({outgoing:!0}),"outgoers"),successors:fu({outgoing:!0}),incomers:Gs(gu({incoming:!0}),"incomers"),predecessors:fu({incoming:!0})}),Q(du,{neighborhood:Gs((function(e){for(var t=[],n=this.nodes(),r=0;r<n.length;r++)for(var i=n[r],a=i.connectedEdges(),o=0;o<a.length;o++){var s=a[o],l=s.source(),u=s.target(),c=i===l?u:l;c.length>0&&t.push(c[0]),t.push(s[0])}return this.spawn(t,!0).filter(e)}),"neighborhood"),closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),du.neighbourhood=du.neighborhood,du.closedNeighbourhood=du.closedNeighborhood,du.openNeighbourhood=du.openNeighborhood,Q(du,{source:Gs((function(e){var t,n=this[0];return n&&(t=n._private.source||n.cy().collection()),t&&e?t.filter(e):t}),"source"),target:Gs((function(e){var t,n=this[0];return n&&(t=n._private.target||n.cy().collection()),t&&e?t.filter(e):t}),"target"),sources:vu({attr:"source"}),targets:vu({attr:"target"})}),Q(du,{edgesWith:Gs(yu(),"edgesWith"),edgesTo:Gs(yu({thisIsSrc:!0}),"edgesTo")}),Q(du,{connectedEdges:Gs((function(e){for(var t=[],n=this,r=0;r<n.length;r++){var i=n[r];if(i.isNode())for(var a=i._private.edges,o=0;o<a.length;o++){var s=a[o];t.push(s)}}return this.spawn(t,!0).filter(e)}),"connectedEdges"),connectedNodes:Gs((function(e){for(var t=[],n=this,r=0;r<n.length;r++){var i=n[r];i.isEdge()&&(t.push(i.source()[0]),t.push(i.target()[0]))}return this.spawn(t,!0).filter(e)}),"connectedNodes"),parallelEdges:Gs(mu(),"parallelEdges"),codirectedEdges:Gs(mu({codirected:!0}),"codirectedEdges")}),Q(du,{components:function(e){var t=this,n=t.cy(),r=n.collection(),i=null==e?t.nodes():e.nodes(),a=[];null!=e&&i.empty()&&(i=e.sources());var o=function(e,t){r.merge(e),i.unmerge(e),t.merge(e)};if(i.empty())return t.spawn();var s=function(){var e=n.collection();a.push(e);var r=i[0];o(r,e),t.bfs({directed:!1,roots:r,visit:function(t){return o(t,e)}}),e.forEach((function(n){n.connectedEdges().forEach((function(n){t.has(n)&&e.has(n.source())&&e.has(n.target())&&e.merge(n)}))}))};do{s()}while(i.length>0);return a},component:function(){var e=this[0];return e.cy().mutableElements().components(e)[0]}}),du.componentsOf=du.components;var bu=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(void 0!==e){var i=new Yt,a=!1;if(t){if(t.length>0&&E(t[0])&&!A(t[0])){a=!0;for(var o=[],s=new Ut,l=0,u=t.length;l<u;l++){var c=t[l];null==c.data&&(c.data={});var h=c.data;if(null==h.id)h.id=Ot();else if(e.hasElementWithId(h.id)||s.has(h.id))continue;var d=new jt(e,c,!1);o.push(d),s.add(h.id)}t=o}}else t=[];this.length=0;for(var p=0,g=t.length;p<g;p++){var f=t[p][0];if(null!=f){var v=f._private.data.id;n&&i.has(v)||(n&&i.set(v,{index:this.length,ele:f}),this[this.length]=f,this.length++)}}this._private={eles:this,cy:e,get map(){return null==this.lazyMap&&this.rebuildMap(),this.lazyMap},set map(e){this.lazyMap=e},rebuildMap:function(){for(var e=this.lazyMap=new Yt,t=this.eles,n=0;n<t.length;n++){var r=t[n];e.set(r.id(),{index:n,ele:r})}}},n&&(this._private.map=i),a&&!r&&this.restore()}else Dt("A collection must have a reference to the core")},xu=jt.prototype=bu.prototype=Object.create(Array.prototype);xu.instanceString=function(){return"collection"},xu.spawn=function(e,t){return new bu(this.cy(),e,t)},xu.spawnSelf=function(){return this.spawn(this)},xu.cy=function(){return this._private.cy},xu.renderer=function(){return this._private.cy.renderer()},xu.element=function(){return this[0]},xu.collection=function(){return L(this)?this:new bu(this._private.cy,[this])},xu.unique=function(){return new bu(this._private.cy,this,!0)},xu.hasElementWithId=function(e){return e=""+e,this._private.map.has(e)},xu.getElementById=function(e){e=""+e;var t=this._private.cy,n=this._private.map.get(e);return n?n.ele:new bu(t)},xu.$id=xu.getElementById,xu.poolIndex=function(){var e=this._private.cy._private.elements,t=this[0]._private.data.id;return e._private.map.get(t).index},xu.indexOf=function(e){var t=e[0]._private.data.id;return this._private.map.get(t).index},xu.indexOfId=function(e){return e=""+e,this._private.map.get(e).index},xu.json=function(e){var t=this.element(),n=this.cy();if(null==t&&e)return this;if(null!=t){var r=t._private;if(E(e)){if(n.startBatch(),e.data){t.data(e.data);var i=r.data;if(t.isEdge()){var a=!1,o={},s=e.data.source,l=e.data.target;null!=s&&s!=i.source&&(o.source=""+s,a=!0),null!=l&&l!=i.target&&(o.target=""+l,a=!0),a&&(t=t.move(o))}else{var u="parent"in e.data,c=e.data.parent;!u||null==c&&null==i.parent||c==i.parent||(void 0===c&&(c=null),null!=c&&(c=""+c),t=t.move({parent:c}))}}e.position&&t.position(e.position);var h=function(n,i,a){var o=e[n];null!=o&&o!==r[n]&&(o?t[i]():t[a]())};return h("removed","remove","restore"),h("selected","select","unselect"),h("selectable","selectify","unselectify"),h("locked","lock","unlock"),h("grabbable","grabify","ungrabify"),h("pannable","panify","unpanify"),null!=e.classes&&t.classes(e.classes),n.endBatch(),this}if(void 0===e){var d={data:Lt(r.data),position:Lt(r.position),group:r.group,removed:r.removed,selected:r.selected,selectable:r.selectable,locked:r.locked,grabbable:r.grabbable,pannable:r.pannable,classes:null};d.classes="";var p=0;return r.classes.forEach((function(e){return d.classes+=0==p++?e:" "+e})),d}}},xu.jsons=function(){for(var e=[],t=0;t<this.length;t++){var n=this[t].json();e.push(n)}return e},xu.clone=function(){for(var e=this.cy(),t=[],n=0;n<this.length;n++){var r=this[n].json(),i=new jt(e,r,!1);t.push(i)}return new bu(e,t)},xu.copy=xu.clone,xu.restore=function(){for(var e,t,n=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=this,a=i.cy(),o=a._private,s=[],l=[],u=0,c=i.length;u<c;u++){var h=i[u];r&&!h.removed()||(h.isNode()?s.push(h):l.push(h))}e=s.concat(l);var d=function(){e.splice(t,1),t--};for(t=0;t<e.length;t++){var p=e[t],g=p._private,f=g.data;if(p.clearTraversalCache(),r||g.removed)if(void 0===f.id)f.id=Ot();else if(_(f.id))f.id=""+f.id;else{if(k(f.id)||!b(f.id)){Dt("Can not create element with invalid string ID `"+f.id+"`"),d();continue}if(a.hasElementWithId(f.id)){Dt("Can not create second element with ID `"+f.id+"`"),d();continue}}var v=f.id;if(p.isNode()){var y=g.position;null==y.x&&(y.x=0),null==y.y&&(y.y=0)}if(p.isEdge()){for(var m=p,x=["source","target"],w=x.length,E=!1,T=0;T<w;T++){var D=x[T],C=f[D];_(C)&&(C=f[D]=""+f[D]),null==C||""===C?(Dt("Can not create edge `"+v+"` with unspecified "+D),E=!0):a.hasElementWithId(C)||(Dt("Can not create edge `"+v+"` with nonexistant "+D+" `"+C+"`"),E=!0)}if(E){d();continue}var N=a.getElementById(f.source),A=a.getElementById(f.target);N.same(A)?N._private.edges.push(m):(N._private.edges.push(m),A._private.edges.push(m)),m._private.source=N,m._private.target=A}g.map=new Yt,g.map.set(v,{ele:p,index:0}),g.removed=!1,r&&a.addToPool(p)}for(var L=0;L<s.length;L++){var S=s[L],O=S._private.data;_(O.parent)&&(O.parent=""+O.parent);var I=O.parent;if(null!=I||S._private.parent){var M=S._private.parent?a.collection().merge(S._private.parent):a.getElementById(I);if(M.empty())O.parent=void 0;else if(M[0].removed())Nt("Node added with missing parent, reference to parent removed"),O.parent=void 0,S._private.parent=null;else{for(var P=!1,R=M;!R.empty();){if(S.same(R)){P=!0,O.parent=void 0;break}R=R.parent()}P||(M[0]._private.children.push(S),S._private.parent=M[0],o.hasCompoundNodes=!0)}}}if(e.length>0){for(var B=e.length===i.length?i:new bu(a,e),F=0;F<B.length;F++){var z=B[F];z.isNode()||(z.parallelEdges().clearTraversalCache(),z.source().clearTraversalCache(),z.target().clearTraversalCache())}(o.hasCompoundNodes?a.collection().merge(B).merge(B.connectedNodes()).merge(B.parent()):B).dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(n),n?B.emitAndNotify("add"):r&&B.emit("add")}return i},xu.removed=function(){var e=this[0];return e&&e._private.removed},xu.inside=function(){var e=this[0];return e&&!e._private.removed},xu.remove=function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this,r=[],i={},a=n._private.cy;function o(e){for(var t=e._private.edges,n=0;n<t.length;n++)l(t[n])}function s(e){for(var t=e._private.children,n=0;n<t.length;n++)l(t[n])}function l(e){var n=i[e.id()];t&&e.removed()||n||(i[e.id()]=!0,e.isNode()?(r.push(e),o(e),s(e)):r.unshift(e))}for(var u=0,c=n.length;u<c;u++)l(n[u]);function h(e,t){var n=e._private.edges;Pt(n,t),e.clearTraversalCache()}function d(e){e.clearTraversalCache()}var p=[];function g(e,t){t=t[0];var n=(e=e[0])._private.children,r=e.id();Pt(n,t),t._private.parent=null,p.ids[r]||(p.ids[r]=!0,p.push(e))}p.ids={},n.dirtyCompoundBoundsCache(),t&&a.removeFromPool(r);for(var f=0;f<r.length;f++){var v=r[f];if(v.isEdge()){var y=v.source()[0],m=v.target()[0];h(y,v),h(m,v);for(var b=v.parallelEdges(),x=0;x<b.length;x++){var w=b[x];d(w),w.isBundledBezier()&&w.dirtyBoundingBoxCache()}}else{var E=v.parent();0!==E.length&&g(E,v)}t&&(v._private.removed=!0)}var T=a._private.elements;a._private.hasCompoundNodes=!1;for(var _=0;_<T.length;_++)if(T[_].isParent()){a._private.hasCompoundNodes=!0;break}var D=new bu(this.cy(),r);D.size()>0&&(e?D.emitAndNotify("remove"):t&&D.emit("remove"));for(var C=0;C<p.length;C++){var N=p[C];t&&N.removed()||N.updateStyle()}return D},xu.move=function(e){var t=this._private.cy,n=this,r=!1,i=!1,a=function(e){return null==e?e:""+e};if(void 0!==e.source||void 0!==e.target){var o=a(e.source),s=a(e.target),l=null!=o&&t.hasElementWithId(o),u=null!=s&&t.hasElementWithId(s);(l||u)&&(t.batch((function(){n.remove(r,i),n.emitAndNotify("moveout");for(var e=0;e<n.length;e++){var t=n[e],a=t._private.data;t.isEdge()&&(l&&(a.source=o),u&&(a.target=s))}n.restore(r,i)})),n.emitAndNotify("move"))}else if(void 0!==e.parent){var c=a(e.parent);if(null===c||t.hasElementWithId(c)){var h=null===c?void 0:c;t.batch((function(){var e=n.remove(r,i);e.emitAndNotify("moveout");for(var t=0;t<n.length;t++){var a=n[t],o=a._private.data;a.isNode()&&(o.parent=h)}e.restore(r,i)})),n.emitAndNotify("move")}}return this},[Si,ds,ps,Bs,Ys,Ws,$s,Nl,Vl,Ul,ql,$l,Zl,tu,uu,du].forEach((function(e){Q(xu,e)}));var wu={add:function(e){var t,n=this;if(N(e)){var r=e;if(r._private.cy===n)t=r.restore();else{for(var i=[],a=0;a<r.length;a++){var o=r[a];i.push(o.json())}t=new bu(n,i)}}else if(w(e))t=new bu(n,e);else if(E(e)&&(w(e.nodes)||w(e.edges))){for(var s=e,l=[],u=["nodes","edges"],c=0,h=u.length;c<h;c++){var d=u[c],p=s[d];if(w(p))for(var g=0,f=p.length;g<f;g++){var v=Q({group:d},p[g]);l.push(v)}}t=new bu(n,l)}else t=new jt(n,e).collection();return t},remove:function(e){if(N(e));else if(b(e)){var t=e;e=this.$(t)}return e.remove()}};function Eu(e,t,n,r){var i=4,a=.001,o=1e-7,s=10,l=11,u=1/(l-1),c="undefined"!=typeof Float32Array;if(4!==arguments.length)return!1;for(var h=0;h<4;++h)if("number"!=typeof arguments[h]||isNaN(arguments[h])||!isFinite(arguments[h]))return!1;e=Math.min(e,1),n=Math.min(n,1),e=Math.max(e,0),n=Math.max(n,0);var d=c?new Float32Array(l):new Array(l);function p(e,t){return 1-3*t+3*e}function g(e,t){return 3*t-6*e}function f(e){return 3*e}function v(e,t,n){return((p(t,n)*e+g(t,n))*e+f(t))*e}function y(e,t,n){return 3*p(t,n)*e*e+2*g(t,n)*e+f(t)}function m(t,r){for(var a=0;a<i;++a){var o=y(r,e,n);if(0===o)return r;r-=(v(r,e,n)-t)/o}return r}function b(){for(var t=0;t<l;++t)d[t]=v(t*u,e,n)}function x(t,r,i){var a,l,u=0;do{(a=v(l=r+(i-r)/2,e,n)-t)>0?i=l:r=l}while(Math.abs(a)>o&&++u<s);return l}function w(t){for(var r=0,i=1,o=l-1;i!==o&&d[i]<=t;++i)r+=u;--i;var s=r+(t-d[i])/(d[i+1]-d[i])*u,c=y(s,e,n);return c>=a?m(t,s):0===c?s:x(t,r,r+u)}var E=!1;function T(){E=!0,e===t&&n===r||b()}var _=function(i){return E||T(),e===t&&n===r?i:0===i?0:1===i?1:v(w(i),t,r)};_.getControlPoints=function(){return[{x:e,y:t},{x:n,y:r}]};var D="generateBezier("+[e,t,n,r]+")";return _.toString=function(){return D},_}var Tu=function(){function e(e){return-e.tension*e.x-e.friction*e.v}function t(t,n,r){var i={x:t.x+r.dx*n,v:t.v+r.dv*n,tension:t.tension,friction:t.friction};return{dx:i.v,dv:e(i)}}function n(n,r){var i={dx:n.v,dv:e(n)},a=t(n,.5*r,i),o=t(n,.5*r,a),s=t(n,r,o),l=1/6*(i.dx+2*(a.dx+o.dx)+s.dx),u=1/6*(i.dv+2*(a.dv+o.dv)+s.dv);return n.x=n.x+l*r,n.v=n.v+u*r,n}return function e(t,r,i){var a,o,s,l={x:-1,v:0,tension:null,friction:null},u=[0],c=0,h=1e-4,d=.016;for(t=parseFloat(t)||500,r=parseFloat(r)||20,i=i||null,l.tension=t,l.friction=r,o=(a=null!==i)?(c=e(t,r))/i*d:d;s=n(s||l,o),u.push(1+s.x),c+=16,Math.abs(s.x)>h&&Math.abs(s.v)>h;);return a?function(e){return u[e*(u.length-1)|0]}:c}}(),_u=function(e,t,n,r){var i=Eu(e,t,n,r);return function(e,t,n){return e+(t-e)*i(n)}},Du={linear:function(e,t,n){return e+(t-e)*n},ease:_u(.25,.1,.25,1),"ease-in":_u(.42,0,1,1),"ease-out":_u(0,0,.58,1),"ease-in-out":_u(.42,0,.58,1),"ease-in-sine":_u(.47,0,.745,.715),"ease-out-sine":_u(.39,.575,.565,1),"ease-in-out-sine":_u(.445,.05,.55,.95),"ease-in-quad":_u(.55,.085,.68,.53),"ease-out-quad":_u(.25,.46,.45,.94),"ease-in-out-quad":_u(.455,.03,.515,.955),"ease-in-cubic":_u(.55,.055,.675,.19),"ease-out-cubic":_u(.215,.61,.355,1),"ease-in-out-cubic":_u(.645,.045,.355,1),"ease-in-quart":_u(.895,.03,.685,.22),"ease-out-quart":_u(.165,.84,.44,1),"ease-in-out-quart":_u(.77,0,.175,1),"ease-in-quint":_u(.755,.05,.855,.06),"ease-out-quint":_u(.23,1,.32,1),"ease-in-out-quint":_u(.86,0,.07,1),"ease-in-expo":_u(.95,.05,.795,.035),"ease-out-expo":_u(.19,1,.22,1),"ease-in-out-expo":_u(1,0,0,1),"ease-in-circ":_u(.6,.04,.98,.335),"ease-out-circ":_u(.075,.82,.165,1),"ease-in-out-circ":_u(.785,.135,.15,.86),spring:function(e,t,n){if(0===n)return Du.linear;var r=Tu(e,t,n);return function(e,t,n){return e+(t-e)*r(n)}},"cubic-bezier":_u};function Cu(e,t,n,r,i){if(1===r)return n;if(t===n)return n;var a=i(t,n,r);return null==e||((e.roundValue||e.color)&&(a=Math.round(a)),void 0!==e.min&&(a=Math.max(a,e.min)),void 0!==e.max&&(a=Math.min(a,e.max))),a}function Nu(e,t){return null!=e.pfValue||null!=e.value?null==e.pfValue||null!=t&&"%"===t.type.units?e.value:e.pfValue:e}function Au(e,t,n,r,i){var a=null!=i?i.type:null;n<0?n=0:n>1&&(n=1);var o=Nu(e,i),s=Nu(t,i);if(_(o)&&_(s))return Cu(a,o,s,n,r);if(w(o)&&w(s)){for(var l=[],u=0;u<s.length;u++){var c=o[u],h=s[u];if(null!=c&&null!=h){var d=Cu(a,c,h,n,r);l.push(d)}else l.push(h)}return l}}function Lu(e,t,n,r){var i=!r,a=e._private,o=t._private,s=o.easing,l=o.startTime,u=(r?e:e.cy()).style();if(!o.easingImpl)if(null==s)o.easingImpl=Du.linear;else{var c,h,d;c=b(s)?u.parse("transition-timing-function",s).value:s,b(c)?(h=c,d=[]):(h=c[1],d=c.slice(2).map((function(e){return+e}))),d.length>0?("spring"===h&&d.push(o.duration),o.easingImpl=Du[h].apply(null,d)):o.easingImpl=Du[h]}var p,g=o.easingImpl;if(p=0===o.duration?1:(n-l)/o.duration,o.applying&&(p=o.progress),p<0?p=0:p>1&&(p=1),null==o.delay){var f=o.startPosition,v=o.position;if(v&&i&&!e.locked()){var y={};Su(f.x,v.x)&&(y.x=Au(f.x,v.x,p,g)),Su(f.y,v.y)&&(y.y=Au(f.y,v.y,p,g)),e.position(y)}var m=o.startPan,x=o.pan,w=a.pan,E=null!=x&&r;E&&(Su(m.x,x.x)&&(w.x=Au(m.x,x.x,p,g)),Su(m.y,x.y)&&(w.y=Au(m.y,x.y,p,g)),e.emit("pan"));var T=o.startZoom,_=o.zoom,D=null!=_&&r;D&&(Su(T,_)&&(a.zoom=An(a.minZoom,Au(T,_,p,g),a.maxZoom)),e.emit("zoom")),(E||D)&&e.emit("viewport");var C=o.style;if(C&&C.length>0&&i){for(var N=0;N<C.length;N++){var A=C[N],L=A.name,S=A,O=o.startStyle[L],I=Au(O,S,p,g,u.properties[O.name]);u.overrideBypass(e,L,I)}e.emit("style")}}return o.progress=p,p}function Su(e,t){return!!(null!=e&&null!=t&&(_(e)&&_(t)||e&&t))}function Ou(e,t,n,r){var i=t._private;i.started=!0,i.startTime=n-i.progress*i.duration}function Iu(e,t){var n=t._private.aniEles,r=[];function i(t,n){var i=t._private,a=i.animation.current,o=i.animation.queue,s=!1;if(0===a.length){var l=o.shift();l&&a.push(l)}for(var u=function(e){for(var t=e.length-1;t>=0;t--)(0,e[t])();e.splice(0,e.length)},c=a.length-1;c>=0;c--){var h=a[c],d=h._private;d.stopped?(a.splice(c,1),d.hooked=!1,d.playing=!1,d.started=!1,u(d.frames)):(d.playing||d.applying)&&(d.playing&&d.applying&&(d.applying=!1),d.started||Ou(t,h,e),Lu(t,h,e,n),d.applying&&(d.applying=!1),u(d.frames),null!=d.step&&d.step(e),h.completed()&&(a.splice(c,1),d.hooked=!1,d.playing=!1,d.started=!1,u(d.completes)),s=!0)}return n||0!==a.length||0!==o.length||r.push(t),s}for(var a=!1,o=0;o<n.length;o++){var s=i(n[o]);a=a||s}var l=i(t,!0);(a||l)&&(n.length>0?t.notify("draw",n):t.notify("draw")),n.unmerge(r),t.emit("step")}var ku={animate:hs.animate(),animation:hs.animation(),animated:hs.animated(),clearQueue:hs.clearQueue(),delay:hs.delay(),delayAnimation:hs.delayAnimation(),stop:hs.stop(),addToAnimationPool:function(e){var t=this;t.styleEnabled()&&t._private.aniEles.merge(e)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){var e=this;if(e._private.animationsRunning=!0,e.styleEnabled()){var t=e.renderer();t&&t.beforeRender?t.beforeRender((function(t,n){Iu(n,e)}),t.beforeRenderPriorities.animations):n()}function n(){e._private.animationsRunning&&nt((function(t){Iu(t,e),n()}))}}},Mu={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&A(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e,t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e}},Pu=function(e){return b(e)?new Ps(e):e},Ru={createEmitter:function(){var e=this._private;return e.emitter||(e.emitter=new Rl(Mu,this)),this},emitter:function(){return this._private.emitter},on:function(e,t,n){return this.emitter().on(e,Pu(t),n),this},removeListener:function(e,t,n){return this.emitter().removeListener(e,Pu(t),n),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},one:function(e,t,n){return this.emitter().one(e,Pu(t),n),this},once:function(e,t,n){return this.emitter().one(e,Pu(t),n),this},emit:function(e,t){return this.emitter().emit(e,t),this},emitAndNotify:function(e,t){return this.emit(e),this.notify(e,t),this}};hs.eventAliasesOn(Ru);var Bu={png:function(e){return e=e||{},this._private.renderer.png(e)},jpg:function(e){var t=this._private.renderer;return(e=e||{}).bg=e.bg||"#fff",t.jpg(e)}};Bu.jpeg=Bu.jpg;var Fu={layout:function(e){var t=this;if(null!=e)if(null!=e.name){var n=e.name,r=t.extension("layout",n);if(null!=r){var i;i=b(e.eles)?t.$(e.eles):null!=e.eles?e.eles:t.$();var a=new r(Q({},e,{cy:t,eles:i}));return a}Dt("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?")}else Dt("A `name` must be specified to make a layout");else Dt("Layout options must be specified to make a layout")}};Fu.createLayout=Fu.makeLayout=Fu.layout;var zu={notify:function(e,t){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var r=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();null!=t&&r.merge(t)}else if(n.notificationsEnabled){var i=this.renderer();!this.destroyed()&&i&&i.notify(e,t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:(t.notificationsEnabled=!!e,this)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)},batching:function(){return this._private.batchCount>0},startBatch:function(){var e=this._private;return null==e.batchCount&&(e.batchCount=0),0===e.batchCount&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},endBatch:function(){var e=this._private;if(0===e.batchCount)return this;if(e.batchCount--,0===e.batchCount){e.batchStyleEles.updateStyle();var t=this.renderer();Object.keys(e.batchNotifications).forEach((function(n){var r=e.batchNotifications[n];r.empty()?t.notify(n):t.notify(n,r)}))}return this},batch:function(e){return this.startBatch(),e(),this.endBatch(),this},batchData:function(e){var t=this;return this.batch((function(){for(var n=Object.keys(e),r=0;r<n.length;r++){var i=n[r],a=e[i];t.getElementById(i).data(a)}}))}},Gu=Mt({hideEdgesOnViewport:!1,textureOnViewport:!1,motionBlur:!1,motionBlurOpacity:.05,pixelRatio:void 0,desktopTapThreshold:4,touchTapThreshold:8,wheelSensitivity:1,debug:!1,showFps:!1}),Yu={renderTo:function(e,t,n,r){return this._private.renderer.renderTo(e,t,n,r),this},renderer:function(){return this._private.renderer},forceRender:function(){return this.notify("draw"),this},resize:function(){return this.invalidateSize(),this.emitAndNotify("resize"),this},initRenderer:function(e){var t=this,n=t.extension("renderer",e.name);if(null!=n){void 0!==e.wheelSensitivity&&Nt("You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.");var r=Gu(e);r.cy=t,t._private.renderer=new n(r),this.notify("init")}else Dt("Can not initialise: No such renderer `".concat(e.name,"` found. Did you forget to import it and `cytoscape.use()` it?"))},destroyRenderer:function(){var e=this;e.notify("destroy");var t=e.container();if(t)for(t._cyreg=null;t.childNodes.length>0;)t.removeChild(t.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach((function(e){var t=e._private;t.rscratch={},t.rstyle={},t.animation.current=[],t.animation.queue=[]}))},onRender:function(e){return this.on("render",e)},offRender:function(e){return this.off("render",e)}};Yu.invalidateDimensions=Yu.resize;var Xu={collection:function(e,t){return b(e)?this.$(e):N(e)?e.collection():w(e)?(t||(t={}),new bu(this,e,t.unique,t.removed)):new bu(this)},nodes:function(e){var t=this.$((function(e){return e.isNode()}));return e?t.filter(e):t},edges:function(e){var t=this.$((function(e){return e.isEdge()}));return e?t.filter(e):t},$:function(e){var t=this._private.elements;return e?t.filter(e):t.spawnSelf()},mutableElements:function(){return this._private.elements}};Xu.elements=Xu.filter=Xu.$;var Vu={},Uu="t",ju="f";Vu.apply=function(e){for(var t=this,n=t._private.cy.collection(),r=0;r<e.length;r++){var i=e[r],a=t.getContextMeta(i);if(!a.empty){var o=t.getContextStyle(a),s=t.applyContextStyle(a,o,i);i._private.appliedInitStyle?t.updateTransitions(i,s.diffProps):i._private.appliedInitStyle=!0,t.updateStyleHints(i)&&n.push(i)}}return n},Vu.getPropertiesDiff=function(e,t){var n=this,r=n._private.propDiffs=n._private.propDiffs||{},i=e+"-"+t,a=r[i];if(a)return a;for(var o=[],s={},l=0;l<n.length;l++){var u=n[l],c=e[l]===Uu,h=t[l]===Uu,d=c!==h,p=u.mappedProperties.length>0;if(d||h&&p){var g=void 0;d&&p||d?g=u.properties:p&&(g=u.mappedProperties);for(var f=0;f<g.length;f++){for(var v=g[f],y=v.name,m=!1,b=l+1;b<n.length;b++){var x=n[b];if(t[b]===Uu&&(m=null!=x.properties[v.name]))break}s[y]||m||(s[y]=!0,o.push(y))}}}return r[i]=o,o},Vu.getContextMeta=function(e){for(var t,n=this,r="",i=e._private.styleCxtKey||"",a=0;a<n.length;a++){var o=n[a];r+=o.selector&&o.selector.matches(e)?Uu:ju}return t=n.getPropertiesDiff(i,r),e._private.styleCxtKey=r,{key:r,diffPropNames:t,empty:0===t.length}},Vu.getContextStyle=function(e){var t=e.key,n=this,r=this._private.contextStyles=this._private.contextStyles||{};if(r[t])return r[t];for(var i={_private:{key:t}},a=0;a<n.length;a++){var o=n[a];if(t[a]===Uu)for(var s=0;s<o.properties.length;s++){var l=o.properties[s];i[l.name]=l}}return r[t]=i,i},Vu.applyContextStyle=function(e,t,n){for(var r=this,i=e.diffPropNames,a={},o=r.types,s=0;s<i.length;s++){var l=i[s],u=t[l],c=n.pstyle(l);if(!u){if(!c)continue;u=c.bypass?{name:l,deleteBypassed:!0}:{name:l,delete:!0}}if(c!==u){if(u.mapped===o.fn&&null!=c&&null!=c.mapping&&c.mapping.value===u.value){var h=c.mapping;if((h.fnValue=u.value(n))===h.prevFnValue)continue}var d=a[l]={prev:c};r.applyParsedProperty(n,u),d.next=n.pstyle(l),d.next&&d.next.bypass&&(d.next=d.next.bypassed)}}return{diffProps:a}},Vu.updateStyleHints=function(e){var t=e._private,n=this,r=n.propertyGroupNames,i=n.propertyGroupKeys,a=function(e,t,r){return n.getPropertiesHash(e,t,r)},o=t.styleKey;if(e.removed())return!1;var s="nodes"===t.group,l=e._private.style;r=Object.keys(l);for(var u=0;u<i.length;u++){var c=i[u];t.styleKeys[c]=[it,ot]}for(var h=function(e,n){return t.styleKeys[n][0]=lt(e,t.styleKeys[n][0])},d=function(e,n){return t.styleKeys[n][1]=ut(e,t.styleKeys[n][1])},p=function(e,t){h(e,t),d(e,t)},g=function(e,t){for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);h(r,t),d(r,t)}},f=2e9,v=function(e){return-128<e&&e<128&&Math.floor(e)!==e?f-(1024*e|0):e},y=0;y<r.length;y++){var m=r[y],b=l[m];if(null!=b){var x=this.properties[m],w=x.type,E=x.groupKey,T=void 0;null!=x.hashOverride?T=x.hashOverride(e,b):null!=b.pfValue&&(T=b.pfValue);var _=null==x.enums?b.value:null,D=null!=T,C=D||null!=_,N=b.units;w.number&&C&&!w.multiple?(p(v(D?T:_),E),D||null==N||g(N,E)):g(b.strValue,E)}}for(var A=[it,ot],L=0;L<i.length;L++){var S=i[L],O=t.styleKeys[S];A[0]=lt(O[0],A[0]),A[1]=ut(O[1],A[1])}t.styleKey=ct(A[0],A[1]);var I=t.styleKeys;t.labelDimsKey=ht(I.labelDimensions);var k=a(e,["label"],I.labelDimensions);if(t.labelKey=ht(k),t.labelStyleKey=ht(dt(I.commonLabel,k)),!s){var M=a(e,["source-label"],I.labelDimensions);t.sourceLabelKey=ht(M),t.sourceLabelStyleKey=ht(dt(I.commonLabel,M));var P=a(e,["target-label"],I.labelDimensions);t.targetLabelKey=ht(P),t.targetLabelStyleKey=ht(dt(I.commonLabel,P))}if(s){var R=t.styleKeys,B=R.nodeBody,F=R.nodeBorder,z=R.backgroundImage,G=R.compound,Y=R.pie,X=[B,F,z,G,Y].filter((function(e){return null!=e})).reduce(dt,[it,ot]);t.nodeKey=ht(X),t.hasPie=null!=Y&&Y[0]!==it&&Y[1]!==ot}return o!==t.styleKey},Vu.clearStyleHints=function(e){var t=e._private;t.styleCxtKey="",t.styleKeys={},t.styleKey=null,t.labelKey=null,t.labelStyleKey=null,t.sourceLabelKey=null,t.sourceLabelStyleKey=null,t.targetLabelKey=null,t.targetLabelStyleKey=null,t.nodeKey=null,t.hasPie=null},Vu.applyParsedProperty=function(e,t){var n,r=this,i=t,a=e._private.style,o=r.types,s=r.properties[i.name].type,l=i.bypass,u=a[i.name],c=u&&u.bypass,h=e._private,d="mapping",p=function(e){return null==e?null:null!=e.pfValue?e.pfValue:e.value},g=function(){var t=p(u),n=p(i);r.checkTriggers(e,i.name,t,n)};if(i&&"pie"===i.name.substr(0,3)&&Nt("The pie style properties are deprecated. Create charts using background images instead."),"curve-style"===t.name&&e.isEdge()&&("bezier"!==t.value&&e.isLoop()||"haystack"===t.value&&(e.source().isParent()||e.target().isParent()))&&(i=t=this.parse(t.name,"bezier",l)),i.delete)return a[i.name]=void 0,g(),!0;if(i.deleteBypassed)return u?!!u.bypass&&(u.bypassed=void 0,g(),!0):(g(),!0);if(i.deleteBypass)return u?!!u.bypass&&(a[i.name]=u.bypassed,g(),!0):(g(),!0);var f=function(){Nt("Do not assign mappings to elements without corresponding data (i.e. ele `"+e.id()+"` has no mapping for property `"+i.name+"` with data field `"+i.field+"`); try a `["+i.field+"]` selector to limit scope to elements with `"+i.field+"` defined")};switch(i.mapped){case o.mapData:for(var v,y=i.field.split("."),m=h.data,b=0;b<y.length&&m;b++)m=m[y[b]];if(null==m)return f(),!1;if(!_(m))return Nt("Do not use continuous mappers without specifying numeric data (i.e. `"+i.field+": "+m+"` for `"+e.id()+"` is non-numeric)"),!1;var x=i.fieldMax-i.fieldMin;if((v=0===x?0:(m-i.fieldMin)/x)<0?v=0:v>1&&(v=1),s.color){var w=i.valueMin[0],E=i.valueMax[0],T=i.valueMin[1],D=i.valueMax[1],C=i.valueMin[2],N=i.valueMax[2],A=null==i.valueMin[3]?1:i.valueMin[3],L=null==i.valueMax[3]?1:i.valueMax[3],S=[Math.round(w+(E-w)*v),Math.round(T+(D-T)*v),Math.round(C+(N-C)*v),Math.round(A+(L-A)*v)];n={bypass:i.bypass,name:i.name,value:S,strValue:"rgb("+S[0]+", "+S[1]+", "+S[2]+")"}}else{if(!s.number)return!1;var O=i.valueMin+(i.valueMax-i.valueMin)*v;n=this.parse(i.name,O,i.bypass,d)}if(!n)return f(),!1;n.mapping=i,i=n;break;case o.data:for(var I=i.field.split("."),k=h.data,M=0;M<I.length&&k;M++)k=k[I[M]];if(null!=k&&(n=this.parse(i.name,k,i.bypass,d)),!n)return f(),!1;n.mapping=i,i=n;break;case o.fn:var P=i.value,R=null!=i.fnValue?i.fnValue:P(e);if(i.prevFnValue=R,null==R)return Nt("Custom function mappers may not return null (i.e. `"+i.name+"` for ele `"+e.id()+"` is null)"),!1;if(!(n=this.parse(i.name,R,i.bypass,d)))return Nt("Custom function mappers may not return invalid values for the property type (i.e. `"+i.name+"` for ele `"+e.id()+"` is invalid)"),!1;n.mapping=Lt(i),i=n;break;case void 0:break;default:return!1}return l?(i.bypassed=c?u.bypassed:u,a[i.name]=i):c?u.bypassed=i:a[i.name]=i,g(),!0},Vu.cleanElements=function(e,t){for(var n=0;n<e.length;n++){var r=e[n];if(this.clearStyleHints(r),r.dirtyCompoundBoundsCache(),r.dirtyBoundingBoxCache(),t)for(var i=r._private.style,a=Object.keys(i),o=0;o<a.length;o++){var s=a[o],l=i[s];null!=l&&(l.bypass?l.bypassed=null:i[s]=null)}else r._private.style={}}},Vu.update=function(){this._private.cy.mutableElements().updateStyle()},Vu.updateTransitions=function(e,t){var n=this,r=e._private,i=e.pstyle("transition-property").value,a=e.pstyle("transition-duration").pfValue,o=e.pstyle("transition-delay").pfValue;if(i.length>0&&a>0){for(var s={},l=!1,u=0;u<i.length;u++){var c=i[u],h=e.pstyle(c),d=t[c];if(d){var p=d.prev,g=null!=d.next?d.next:h,f=!1,v=void 0,y=1e-6;p&&(_(p.pfValue)&&_(g.pfValue)?(f=g.pfValue-p.pfValue,v=p.pfValue+y*f):_(p.value)&&_(g.value)?(f=g.value-p.value,v=p.value+y*f):w(p.value)&&w(g.value)&&(f=p.value[0]!==g.value[0]||p.value[1]!==g.value[1]||p.value[2]!==g.value[2],v=p.strValue),f&&(s[c]=g.strValue,this.applyBypass(e,c,v),l=!0))}}if(!l)return;r.transitioning=!0,new Gi((function(t){o>0?e.delayAnimation(o).play().promise().then(t):t()})).then((function(){return e.animation({style:s,duration:a,easing:e.pstyle("transition-timing-function").value,queue:!1}).play().promise()})).then((function(){n.removeBypasses(e,i),e.emitAndNotify("style"),r.transitioning=!1}))}else r.transitioning&&(this.removeBypasses(e,i),e.emitAndNotify("style"),r.transitioning=!1)},Vu.checkTrigger=function(e,t,n,r,i,a){var o=this.properties[t],s=i(o);null!=s&&s(n,r)&&a(o)},Vu.checkZOrderTrigger=function(e,t,n,r){var i=this;this.checkTrigger(e,t,n,r,(function(e){return e.triggersZOrder}),(function(){i._private.cy.notify("zorder",e)}))},Vu.checkBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,(function(e){return e.triggersBounds}),(function(i){e.dirtyCompoundBoundsCache(),e.dirtyBoundingBoxCache(),!i.triggersBoundsOfParallelBeziers||("curve-style"!==t||"bezier"!==n&&"bezier"!==r)&&("display"!==t||"none"!==n&&"none"!==r)||e.parallelEdges().forEach((function(e){e.isBundledBezier()&&e.dirtyBoundingBoxCache()}))}))},Vu.checkTriggers=function(e,t,n,r){e.dirtyStyleCache(),this.checkZOrderTrigger(e,t,n,r),this.checkBoundsTrigger(e,t,n,r)};var Hu={applyBypass:function(e,t,n,r){var i=this,a=[],o=!0;if("*"===t||"**"===t){if(void 0!==n)for(var s=0;s<i.properties.length;s++){var l=i.properties[s].name,u=this.parse(l,n,!0);u&&a.push(u)}}else if(b(t)){var c=this.parse(t,n,!0);c&&a.push(c)}else{if(!E(t))return!1;var h=t;r=n;for(var d=Object.keys(h),p=0;p<d.length;p++){var g=d[p],f=h[g];if(void 0===f&&(f=h[G(g)]),void 0!==f){var v=this.parse(g,f,!0);v&&a.push(v)}}}if(0===a.length)return!1;for(var y=!1,m=0;m<e.length;m++){for(var x=e[m],w={},T=void 0,_=0;_<a.length;_++){var D=a[_];if(r){var C=x.pstyle(D.name);T=w[D.name]={prev:C}}y=this.applyParsedProperty(x,Lt(D))||y,r&&(T.next=x.pstyle(D.name))}y&&this.updateStyleHints(x),r&&this.updateTransitions(x,w,o)}return y},overrideBypass:function(e,t,n){t=z(t);for(var r=0;r<e.length;r++){var i=e[r],a=i._private.style[t],o=this.properties[t].type,s=o.color,l=o.mutiple,u=a?null!=a.pfValue?a.pfValue:a.value:null;a&&a.bypass?(a.value=n,null!=a.pfValue&&(a.pfValue=n),a.strValue=s?"rgb("+n.join(",")+")":l?n.join(" "):""+n,this.updateStyleHints(i)):this.applyBypass(i,t,n),this.checkTriggers(i,t,u,n)}},removeAllBypasses:function(e,t){return this.removeBypasses(e,this.propertyNames,t)},removeBypasses:function(e,t,n){for(var r=!0,i=0;i<e.length;i++){for(var a=e[i],o={},s=0;s<t.length;s++){var l=t[s],u=this.properties[l],c=a.pstyle(u.name);if(c&&c.bypass){var h="",d=this.parse(l,h,!0),p=o[u.name]={prev:c};this.applyParsedProperty(a,d),p.next=a.pstyle(u.name)}}this.updateStyleHints(a),n&&this.updateTransitions(a,o,r)}}},qu={getEmSizeInPixels:function(){var e=this.containerCss("font-size");return null!=e?parseFloat(e):1},containerCss:function(e){var t=this._private.cy,n=t.container(),r=t.window();if(r&&n&&r.getComputedStyle)return r.getComputedStyle(n).getPropertyValue(e)}},Wu={getRenderedStyle:function(e,t){return t?this.getStylePropertyValue(e,t,!0):this.getRawStyle(e,!0)},getRawStyle:function(e,t){var n=this;if(e=e[0]){for(var r={},i=0;i<n.properties.length;i++){var a=n.properties[i],o=n.getStylePropertyValue(e,a.name,t);null!=o&&(r[a.name]=o,r[G(a.name)]=o)}return r}},getIndexedStyle:function(e,t,n,r){var i=e.pstyle(t)[n][r];return null!=i?i:e.cy().style().getDefaultProperty(t)[n][0]},getStylePropertyValue:function(e,t,n){var r=this;if(e=e[0]){var i=r.properties[t];i.alias&&(i=i.pointsTo);var a=i.type,o=e.pstyle(i.name);if(o){var s=o.value,l=o.units,u=o.strValue;if(n&&a.number&&null!=s&&_(s)){var c=e.cy().zoom(),h=function(e){return e*c},d=function(e,t){return h(e)+t},p=w(s);return(p?l.every((function(e){return null!=e})):null!=l)?p?s.map((function(e,t){return d(e,l[t])})).join(" "):d(s,l):p?s.map((function(e){return b(e)?e:""+h(e)})).join(" "):""+h(s)}if(null!=u)return u}return null}},getAnimationStartStyle:function(e,t){for(var n={},r=0;r<t.length;r++){var i=t[r].name,a=e.pstyle(i);void 0!==a&&(a=E(a)?this.parse(i,a.strValue):this.parse(i,a)),a&&(n[i]=a)}return n},getPropsList:function(e){var t=[],n=e,r=this.properties;if(n)for(var i=Object.keys(n),a=0;a<i.length;a++){var o=i[a],s=n[o],l=r[o]||r[z(o)],u=this.parse(l.name,s);u&&t.push(u)}return t},getNonDefaultPropertiesHash:function(e,t,n){var r,i,a,o,s,l,u=n.slice();for(s=0;s<t.length;s++)if(r=t[s],null!=(i=e.pstyle(r,!1)))if(null!=i.pfValue)u[0]=lt(o,u[0]),u[1]=ut(o,u[1]);else for(a=i.strValue,l=0;l<a.length;l++)o=a.charCodeAt(l),u[0]=lt(o,u[0]),u[1]=ut(o,u[1]);return u}};Wu.getPropertiesHash=Wu.getNonDefaultPropertiesHash;var $u={appendFromJson:function(e){for(var t=this,n=0;n<e.length;n++){var r=e[n],i=r.selector,a=r.style||r.css,o=Object.keys(a);t.selector(i);for(var s=0;s<o.length;s++){var l=o[s],u=a[l];t.css(l,u)}}return t},fromJson:function(e){var t=this;return t.resetToDefault(),t.appendFromJson(e),t},json:function(){for(var e=[],t=this.defaultLength;t<this.length;t++){for(var n=this[t],r=n.selector,i=n.properties,a={},o=0;o<i.length;o++){var s=i[o];a[s.name]=s.strValue}e.push({selector:r?r.toString():"core",style:a})}return e}},Ku={appendFromString:function(e){var t,n,r,i=this,a=this,o=""+e;function s(){o=o.length>t.length?o.substr(t.length):""}function l(){n=n.length>r.length?n.substr(r.length):""}for(o=o.replace(/[/][*](\s|.)+?[*][/]/g,"");!o.match(/^\s*$/);){var u=o.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!u){Nt("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+o);break}t=u[0];var c=u[1];if("core"!==c&&new Ps(c).invalid)Nt("Skipping parsing of block: Invalid selector found in string stylesheet: "+c),s();else{var h=u[2],d=!1;n=h;for(var p=[];!n.match(/^\s*$/);){var g=n.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!g){Nt("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+h),d=!0;break}r=g[0];var f=g[1],v=g[2];i.properties[f]?a.parse(f,v)?(p.push({name:f,val:v}),l()):(Nt("Skipping property: Invalid property definition in: "+r),l()):(Nt("Skipping property: Invalid property name in: "+r),l())}if(d){s();break}a.selector(c);for(var y=0;y<p.length;y++){var m=p[y];a.css(m.name,m.val)}s()}}return a},fromString:function(e){var t=this;return t.resetToDefault(),t.appendFromString(e),t}},Zu={};(function(){var e=V,t=j,n=q,r=W,i=$,a=function(e){return"^"+e+"\\s*\\(\\s*([\\w\\.]+)\\s*\\)$"},o=function(a){var o=e+"|\\w+|"+t+"|"+n+"|"+r+"|"+i;return"^"+a+"\\s*\\(([\\w\\.]+)\\s*\\,\\s*("+e+")\\s*\\,\\s*("+e+")\\s*,\\s*("+o+")\\s*\\,\\s*("+o+")\\)$"},s=["^url\\s*\\(\\s*['\"]?(.+?)['\"]?\\s*\\)$","^(none)$","^(.+)$"];Zu.types={time:{number:!0,min:0,units:"s|ms",implicitUnits:"ms"},percent:{number:!0,min:0,max:100,units:"%",implicitUnits:"%"},percentages:{number:!0,min:0,max:100,units:"%",implicitUnits:"%",multiple:!0},zeroOneNumber:{number:!0,min:0,max:1,unitless:!0},zeroOneNumbers:{number:!0,min:0,max:1,unitless:!0,multiple:!0},nOneOneNumber:{number:!0,min:-1,max:1,unitless:!0},nonNegativeInt:{number:!0,min:0,integer:!0,unitless:!0},nonNegativeNumber:{number:!0,min:0,unitless:!0},position:{enums:["parent","origin"]},nodeSize:{number:!0,min:0,enums:["label"]},number:{number:!0,unitless:!0},numbers:{number:!0,unitless:!0,multiple:!0},positiveNumber:{number:!0,unitless:!0,min:0,strictMin:!0},size:{number:!0,min:0},bidirectionalSize:{number:!0},bidirectionalSizeMaybePercent:{number:!0,allowPercent:!0},bidirectionalSizes:{number:!0,multiple:!0},sizeMaybePercent:{number:!0,min:0,allowPercent:!0},axisDirection:{enums:["horizontal","leftward","rightward","vertical","upward","downward","auto"]},paddingRelativeTo:{enums:["width","height","average","min","max"]},bgWH:{number:!0,min:0,allowPercent:!0,enums:["auto"],multiple:!0},bgPos:{number:!0,allowPercent:!0,multiple:!0},bgRelativeTo:{enums:["inner","include-padding"],multiple:!0},bgRepeat:{enums:["repeat","repeat-x","repeat-y","no-repeat"],multiple:!0},bgFit:{enums:["none","contain","cover"],multiple:!0},bgCrossOrigin:{enums:["anonymous","use-credentials","null"],multiple:!0},bgClip:{enums:["none","node"],multiple:!0},bgContainment:{enums:["inside","over"],multiple:!0},color:{color:!0},colors:{color:!0,multiple:!0},fill:{enums:["solid","linear-gradient","radial-gradient"]},bool:{enums:["yes","no"]},bools:{enums:["yes","no"],multiple:!0},lineStyle:{enums:["solid","dotted","dashed"]},lineCap:{enums:["butt","round","square"]},borderStyle:{enums:["solid","dotted","dashed","double"]},curveStyle:{enums:["bezier","unbundled-bezier","haystack","segments","straight","straight-triangle","taxi"]},fontFamily:{regex:'^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$'},fontStyle:{enums:["italic","normal","oblique"]},fontWeight:{enums:["normal","bold","bolder","lighter","100","200","300","400","500","600","800","900",100,200,300,400,500,600,700,800,900]},textDecoration:{enums:["none","underline","overline","line-through"]},textTransform:{enums:["none","uppercase","lowercase"]},textWrap:{enums:["none","wrap","ellipsis"]},textOverflowWrap:{enums:["whitespace","anywhere"]},textBackgroundShape:{enums:["rectangle","roundrectangle","round-rectangle"]},nodeShape:{enums:["rectangle","roundrectangle","round-rectangle","cutrectangle","cut-rectangle","bottomroundrectangle","bottom-round-rectangle","barrel","ellipse","triangle","round-triangle","square","pentagon","round-pentagon","hexagon","round-hexagon","concavehexagon","concave-hexagon","heptagon","round-heptagon","octagon","round-octagon","tag","round-tag","star","diamond","round-diamond","vee","rhomboid","right-rhomboid","polygon"]},overlayShape:{enums:["roundrectangle","round-rectangle","ellipse"]},compoundIncludeLabels:{enums:["include","exclude"]},arrowShape:{enums:["tee","triangle","triangle-tee","circle-triangle","triangle-cross","triangle-backcurve","vee","square","circle","diamond","chevron","none"]},arrowFill:{enums:["filled","hollow"]},display:{enums:["element","none"]},visibility:{enums:["hidden","visible"]},zCompoundDepth:{enums:["bottom","orphan","auto","top"]},zIndexCompare:{enums:["auto","manual"]},valign:{enums:["top","center","bottom"]},halign:{enums:["left","center","right"]},justification:{enums:["left","center","right","auto"]},text:{string:!0},data:{mapping:!0,regex:a("data")},layoutData:{mapping:!0,regex:a("layoutData")},scratch:{mapping:!0,regex:a("scratch")},mapData:{mapping:!0,regex:o("mapData")},mapLayoutData:{mapping:!0,regex:o("mapLayoutData")},mapScratch:{mapping:!0,regex:o("mapScratch")},fn:{mapping:!0,fn:!0},url:{regexes:s,singleRegexMatchValue:!0},urls:{regexes:s,singleRegexMatchValue:!0,multiple:!0},propList:{propList:!0},angle:{number:!0,units:"deg|rad",implicitUnits:"rad"},textRotation:{number:!0,units:"deg|rad",implicitUnits:"rad",enums:["none","autorotate"]},polygonPointList:{number:!0,multiple:!0,evenMultiple:!0,min:-1,max:1,unitless:!0},edgeDistances:{enums:["intersection","node-position","endpoints"]},edgeEndpoint:{number:!0,multiple:!0,units:"%|px|em|deg|rad",implicitUnits:"px",enums:["inside-to-node","outside-to-node","outside-to-node-or-label","outside-to-line","outside-to-line-or-label"],singleEnum:!0,validate:function(e,t){switch(e.length){case 2:return"deg"!==t[0]&&"rad"!==t[0]&&"deg"!==t[1]&&"rad"!==t[1];case 1:return b(e[0])||"deg"===t[0]||"rad"===t[0];default:return!1}}},easing:{regexes:["^(spring)\\s*\\(\\s*("+e+")\\s*,\\s*("+e+")\\s*\\)$","^(cubic-bezier)\\s*\\(\\s*("+e+")\\s*,\\s*("+e+")\\s*,\\s*("+e+")\\s*,\\s*("+e+")\\s*\\)$"],enums:["linear","ease","ease-in","ease-out","ease-in-out","ease-in-sine","ease-out-sine","ease-in-out-sine","ease-in-quad","ease-out-quad","ease-in-out-quad","ease-in-cubic","ease-out-cubic","ease-in-out-cubic","ease-in-quart","ease-out-quart","ease-in-out-quart","ease-in-quint","ease-out-quint","ease-in-out-quint","ease-in-expo","ease-out-expo","ease-in-out-expo","ease-in-circ","ease-out-circ","ease-in-out-circ"]},gradientDirection:{enums:["to-bottom","to-top","to-left","to-right","to-bottom-right","to-bottom-left","to-top-right","to-top-left","to-right-bottom","to-left-bottom","to-right-top","to-left-top"]},boundsExpansion:{number:!0,multiple:!0,min:0,validate:function(e){var t=e.length;return 1===t||2===t||4===t}}};var l={zeroNonZero:function(e,t){return(null==e||null==t)&&e!==t||0==e&&0!=t||0!=e&&0==t},any:function(e,t){return e!=t},emptyNonEmpty:function(e,t){var n=k(e),r=k(t);return n&&!r||!n&&r}},u=Zu.types,c=[{name:"label",type:u.text,triggersBounds:l.any,triggersZOrder:l.emptyNonEmpty},{name:"text-rotation",type:u.textRotation,triggersBounds:l.any},{name:"text-margin-x",type:u.bidirectionalSize,triggersBounds:l.any},{name:"text-margin-y",type:u.bidirectionalSize,triggersBounds:l.any}],h=[{name:"source-label",type:u.text,triggersBounds:l.any},{name:"source-text-rotation",type:u.textRotation,triggersBounds:l.any},{name:"source-text-margin-x",type:u.bidirectionalSize,triggersBounds:l.any},{name:"source-text-margin-y",type:u.bidirectionalSize,triggersBounds:l.any},{name:"source-text-offset",type:u.size,triggersBounds:l.any}],d=[{name:"target-label",type:u.text,triggersBounds:l.any},{name:"target-text-rotation",type:u.textRotation,triggersBounds:l.any},{name:"target-text-margin-x",type:u.bidirectionalSize,triggersBounds:l.any},{name:"target-text-margin-y",type:u.bidirectionalSize,triggersBounds:l.any},{name:"target-text-offset",type:u.size,triggersBounds:l.any}],p=[{name:"font-family",type:u.fontFamily,triggersBounds:l.any},{name:"font-style",type:u.fontStyle,triggersBounds:l.any},{name:"font-weight",type:u.fontWeight,triggersBounds:l.any},{name:"font-size",type:u.size,triggersBounds:l.any},{name:"text-transform",type:u.textTransform,triggersBounds:l.any},{name:"text-wrap",type:u.textWrap,triggersBounds:l.any},{name:"text-overflow-wrap",type:u.textOverflowWrap,triggersBounds:l.any},{name:"text-max-width",type:u.size,triggersBounds:l.any},{name:"text-outline-width",type:u.size,triggersBounds:l.any},{name:"line-height",type:u.positiveNumber,triggersBounds:l.any}],g=[{name:"text-valign",type:u.valign,triggersBounds:l.any},{name:"text-halign",type:u.halign,triggersBounds:l.any},{name:"color",type:u.color},{name:"text-outline-color",type:u.color},{name:"text-outline-opacity",type:u.zeroOneNumber},{name:"text-background-color",type:u.color},{name:"text-background-opacity",type:u.zeroOneNumber},{name:"text-background-padding",type:u.size,triggersBounds:l.any},{name:"text-border-opacity",type:u.zeroOneNumber},{name:"text-border-color",type:u.color},{name:"text-border-width",type:u.size,triggersBounds:l.any},{name:"text-border-style",type:u.borderStyle,triggersBounds:l.any},{name:"text-background-shape",type:u.textBackgroundShape,triggersBounds:l.any},{name:"text-justification",type:u.justification}],f=[{name:"events",type:u.bool,triggersZOrder:l.any},{name:"text-events",type:u.bool,triggersZOrder:l.any}],v=[{name:"display",type:u.display,triggersZOrder:l.any,triggersBounds:l.any,triggersBoundsOfParallelBeziers:!0},{name:"visibility",type:u.visibility,triggersZOrder:l.any},{name:"opacity",type:u.zeroOneNumber,triggersZOrder:l.zeroNonZero},{name:"text-opacity",type:u.zeroOneNumber},{name:"min-zoomed-font-size",type:u.size},{name:"z-compound-depth",type:u.zCompoundDepth,triggersZOrder:l.any},{name:"z-index-compare",type:u.zIndexCompare,triggersZOrder:l.any},{name:"z-index",type:u.number,triggersZOrder:l.any}],y=[{name:"overlay-padding",type:u.size,triggersBounds:l.any},{name:"overlay-color",type:u.color},{name:"overlay-opacity",type:u.zeroOneNumber,triggersBounds:l.zeroNonZero},{name:"overlay-shape",type:u.overlayShape,triggersBounds:l.any}],m=[{name:"underlay-padding",type:u.size,triggersBounds:l.any},{name:"underlay-color",type:u.color},{name:"underlay-opacity",type:u.zeroOneNumber,triggersBounds:l.zeroNonZero},{name:"underlay-shape",type:u.overlayShape,triggersBounds:l.any}],x=[{name:"transition-property",type:u.propList},{name:"transition-duration",type:u.time},{name:"transition-delay",type:u.time},{name:"transition-timing-function",type:u.easing}],w=function(e,t){return"label"===t.value?-e.poolIndex():t.pfValue},E=[{name:"height",type:u.nodeSize,triggersBounds:l.any,hashOverride:w},{name:"width",type:u.nodeSize,triggersBounds:l.any,hashOverride:w},{name:"shape",type:u.nodeShape,triggersBounds:l.any},{name:"shape-polygon-points",type:u.polygonPointList,triggersBounds:l.any},{name:"background-color",type:u.color},{name:"background-fill",type:u.fill},{name:"background-opacity",type:u.zeroOneNumber},{name:"background-blacken",type:u.nOneOneNumber},{name:"background-gradient-stop-colors",type:u.colors},{name:"background-gradient-stop-positions",type:u.percentages},{name:"background-gradient-direction",type:u.gradientDirection},{name:"padding",type:u.sizeMaybePercent,triggersBounds:l.any},{name:"padding-relative-to",type:u.paddingRelativeTo,triggersBounds:l.any},{name:"bounds-expansion",type:u.boundsExpansion,triggersBounds:l.any}],T=[{name:"border-color",type:u.color},{name:"border-opacity",type:u.zeroOneNumber},{name:"border-width",type:u.size,triggersBounds:l.any},{name:"border-style",type:u.borderStyle}],_=[{name:"background-image",type:u.urls},{name:"background-image-crossorigin",type:u.bgCrossOrigin},{name:"background-image-opacity",type:u.zeroOneNumbers},{name:"background-image-containment",type:u.bgContainment},{name:"background-image-smoothing",type:u.bools},{name:"background-position-x",type:u.bgPos},{name:"background-position-y",type:u.bgPos},{name:"background-width-relative-to",type:u.bgRelativeTo},{name:"background-height-relative-to",type:u.bgRelativeTo},{name:"background-repeat",type:u.bgRepeat},{name:"background-fit",type:u.bgFit},{name:"background-clip",type:u.bgClip},{name:"background-width",type:u.bgWH},{name:"background-height",type:u.bgWH},{name:"background-offset-x",type:u.bgPos},{name:"background-offset-y",type:u.bgPos}],D=[{name:"position",type:u.position,triggersBounds:l.any},{name:"compound-sizing-wrt-labels",type:u.compoundIncludeLabels,triggersBounds:l.any},{name:"min-width",type:u.size,triggersBounds:l.any},{name:"min-width-bias-left",type:u.sizeMaybePercent,triggersBounds:l.any},{name:"min-width-bias-right",type:u.sizeMaybePercent,triggersBounds:l.any},{name:"min-height",type:u.size,triggersBounds:l.any},{name:"min-height-bias-top",type:u.sizeMaybePercent,triggersBounds:l.any},{name:"min-height-bias-bottom",type:u.sizeMaybePercent,triggersBounds:l.any}],C=[{name:"line-style",type:u.lineStyle},{name:"line-color",type:u.color},{name:"line-fill",type:u.fill},{name:"line-cap",type:u.lineCap},{name:"line-opacity",type:u.zeroOneNumber},{name:"line-dash-pattern",type:u.numbers},{name:"line-dash-offset",type:u.number},{name:"line-gradient-stop-colors",type:u.colors},{name:"line-gradient-stop-positions",type:u.percentages},{name:"curve-style",type:u.curveStyle,triggersBounds:l.any,triggersBoundsOfParallelBeziers:!0},{name:"haystack-radius",type:u.zeroOneNumber,triggersBounds:l.any},{name:"source-endpoint",type:u.edgeEndpoint,triggersBounds:l.any},{name:"target-endpoint",type:u.edgeEndpoint,triggersBounds:l.any},{name:"control-point-step-size",type:u.size,triggersBounds:l.any},{name:"control-point-distances",type:u.bidirectionalSizes,triggersBounds:l.any},{name:"control-point-weights",type:u.numbers,triggersBounds:l.any},{name:"segment-distances",type:u.bidirectionalSizes,triggersBounds:l.any},{name:"segment-weights",type:u.numbers,triggersBounds:l.any},{name:"taxi-turn",type:u.bidirectionalSizeMaybePercent,triggersBounds:l.any},{name:"taxi-turn-min-distance",type:u.size,triggersBounds:l.any},{name:"taxi-direction",type:u.axisDirection,triggersBounds:l.any},{name:"edge-distances",type:u.edgeDistances,triggersBounds:l.any},{name:"arrow-scale",type:u.positiveNumber,triggersBounds:l.any},{name:"loop-direction",type:u.angle,triggersBounds:l.any},{name:"loop-sweep",type:u.angle,triggersBounds:l.any},{name:"source-distance-from-node",type:u.size,triggersBounds:l.any},{name:"target-distance-from-node",type:u.size,triggersBounds:l.any}],N=[{name:"ghost",type:u.bool,triggersBounds:l.any},{name:"ghost-offset-x",type:u.bidirectionalSize,triggersBounds:l.any},{name:"ghost-offset-y",type:u.bidirectionalSize,triggersBounds:l.any},{name:"ghost-opacity",type:u.zeroOneNumber}],A=[{name:"selection-box-color",type:u.color},{name:"selection-box-opacity",type:u.zeroOneNumber},{name:"selection-box-border-color",type:u.color},{name:"selection-box-border-width",type:u.size},{name:"active-bg-color",type:u.color},{name:"active-bg-opacity",type:u.zeroOneNumber},{name:"active-bg-size",type:u.size},{name:"outside-texture-bg-color",type:u.color},{name:"outside-texture-bg-opacity",type:u.zeroOneNumber}],L=[];Zu.pieBackgroundN=16,L.push({name:"pie-size",type:u.sizeMaybePercent});for(var S=1;S<=Zu.pieBackgroundN;S++)L.push({name:"pie-"+S+"-background-color",type:u.color}),L.push({name:"pie-"+S+"-background-size",type:u.percent}),L.push({name:"pie-"+S+"-background-opacity",type:u.zeroOneNumber});var O=[],I=Zu.arrowPrefixes=["source","mid-source","target","mid-target"];[{name:"arrow-shape",type:u.arrowShape,triggersBounds:l.any},{name:"arrow-color",type:u.color},{name:"arrow-fill",type:u.arrowFill}].forEach((function(e){I.forEach((function(t){var n=t+"-"+e.name,r=e.type,i=e.triggersBounds;O.push({name:n,type:r,triggersBounds:i})}))}),{});var M=Zu.properties=[].concat(f,x,v,y,m,N,g,p,c,h,d,E,T,_,L,D,C,O,A),P=Zu.propertyGroups={behavior:f,transition:x,visibility:v,overlay:y,underlay:m,ghost:N,commonLabel:g,labelDimensions:p,mainLabel:c,sourceLabel:h,targetLabel:d,nodeBody:E,nodeBorder:T,backgroundImage:_,pie:L,compound:D,edgeLine:C,edgeArrow:O,core:A},R=Zu.propertyGroupNames={};(Zu.propertyGroupKeys=Object.keys(P)).forEach((function(e){R[e]=P[e].map((function(e){return e.name})),P[e].forEach((function(t){return t.groupKey=e}))}));var B=Zu.aliases=[{name:"content",pointsTo:"label"},{name:"control-point-distance",pointsTo:"control-point-distances"},{name:"control-point-weight",pointsTo:"control-point-weights"},{name:"edge-text-rotation",pointsTo:"text-rotation"},{name:"padding-left",pointsTo:"padding"},{name:"padding-right",pointsTo:"padding"},{name:"padding-top",pointsTo:"padding"},{name:"padding-bottom",pointsTo:"padding"}];Zu.propertyNames=M.map((function(e){return e.name}));for(var F=0;F<M.length;F++){var z=M[F];M[z.name]=z}for(var G=0;G<B.length;G++){var Y=B[G],X=M[Y.pointsTo],U={name:Y.name,alias:!0,pointsTo:X};M.push(U),M[Y.name]=U}})(),Zu.getDefaultProperty=function(e){return this.getDefaultProperties()[e]},Zu.getDefaultProperties=function(){var e=this._private;if(null!=e.defaultProperties)return e.defaultProperties;for(var t=Q({"selection-box-color":"#ddd","selection-box-opacity":.65,"selection-box-border-color":"#aaa","selection-box-border-width":1,"active-bg-color":"black","active-bg-opacity":.15,"active-bg-size":30,"outside-texture-bg-color":"#000","outside-texture-bg-opacity":.125,events:"yes","text-events":"no","text-valign":"top","text-halign":"center","text-justification":"auto","line-height":1,color:"#000","text-outline-color":"#000","text-outline-width":0,"text-outline-opacity":1,"text-opacity":1,"text-decoration":"none","text-transform":"none","text-wrap":"none","text-overflow-wrap":"whitespace","text-max-width":9999,"text-background-color":"#000","text-background-opacity":0,"text-background-shape":"rectangle","text-background-padding":0,"text-border-opacity":0,"text-border-width":0,"text-border-style":"solid","text-border-color":"#000","font-family":"Helvetica Neue, Helvetica, sans-serif","font-style":"normal","font-weight":"normal","font-size":16,"min-zoomed-font-size":0,"text-rotation":"none","source-text-rotation":"none","target-text-rotation":"none",visibility:"visible",display:"element",opacity:1,"z-compound-depth":"auto","z-index-compare":"auto","z-index":0,label:"","text-margin-x":0,"text-margin-y":0,"source-label":"","source-text-offset":0,"source-text-margin-x":0,"source-text-margin-y":0,"target-label":"","target-text-offset":0,"target-text-margin-x":0,"target-text-margin-y":0,"overlay-opacity":0,"overlay-color":"#000","overlay-padding":10,"overlay-shape":"round-rectangle","underlay-opacity":0,"underlay-color":"#000","underlay-padding":10,"underlay-shape":"round-rectangle","transition-property":"none","transition-duration":0,"transition-delay":0,"transition-timing-function":"linear","background-blacken":0,"background-color":"#999","background-fill":"solid","background-opacity":1,"background-image":"none","background-image-crossorigin":"anonymous","background-image-opacity":1,"background-image-containment":"inside","background-image-smoothing":"yes","background-position-x":"50%","background-position-y":"50%","background-offset-x":0,"background-offset-y":0,"background-width-relative-to":"include-padding","background-height-relative-to":"include-padding","background-repeat":"no-repeat","background-fit":"none","background-clip":"node","background-width":"auto","background-height":"auto","border-color":"#000","border-opacity":1,"border-width":0,"border-style":"solid",height:30,width:30,shape:"ellipse","shape-polygon-points":"-1, -1, 1, -1, 1, 1, -1, 1","bounds-expansion":0,"background-gradient-direction":"to-bottom","background-gradient-stop-colors":"#999","background-gradient-stop-positions":"0%",ghost:"no","ghost-offset-y":0,"ghost-offset-x":0,"ghost-opacity":0,padding:0,"padding-relative-to":"width",position:"origin","compound-sizing-wrt-labels":"include","min-width":0,"min-width-bias-left":0,"min-width-bias-right":0,"min-height":0,"min-height-bias-top":0,"min-height-bias-bottom":0},{"pie-size":"100%"},[{name:"pie-{{i}}-background-color",value:"black"},{name:"pie-{{i}}-background-size",value:"0%"},{name:"pie-{{i}}-background-opacity",value:1}].reduce((function(e,t){for(var n=1;n<=Zu.pieBackgroundN;n++){var r=t.name.replace("{{i}}",n),i=t.value;e[r]=i}return e}),{}),{"line-style":"solid","line-color":"#999","line-fill":"solid","line-cap":"butt","line-opacity":1,"line-gradient-stop-colors":"#999","line-gradient-stop-positions":"0%","control-point-step-size":40,"control-point-weights":.5,"segment-weights":.5,"segment-distances":20,"taxi-turn":"50%","taxi-turn-min-distance":10,"taxi-direction":"auto","edge-distances":"intersection","curve-style":"haystack","haystack-radius":0,"arrow-scale":1,"loop-direction":"-45deg","loop-sweep":"-90deg","source-distance-from-node":0,"target-distance-from-node":0,"source-endpoint":"outside-to-node","target-endpoint":"outside-to-node","line-dash-pattern":[6,3],"line-dash-offset":0},[{name:"arrow-shape",value:"none"},{name:"arrow-color",value:"#999"},{name:"arrow-fill",value:"filled"}].reduce((function(e,t){return Zu.arrowPrefixes.forEach((function(n){var r=n+"-"+t.name,i=t.value;e[r]=i})),e}),{})),n={},r=0;r<this.properties.length;r++){var i=this.properties[r];if(!i.pointsTo){var a=i.name,o=t[a],s=this.parse(a,o);n[a]=s}}return e.defaultProperties=n,e.defaultProperties},Zu.addDefaultStylesheet=function(){this.selector(":parent").css({shape:"rectangle",padding:10,"background-color":"#eee","border-color":"#ccc","border-width":1}).selector("edge").css({width:3}).selector(":loop").css({"curve-style":"bezier"}).selector("edge:compound").css({"curve-style":"bezier","source-endpoint":"outside-to-line","target-endpoint":"outside-to-line"}).selector(":selected").css({"background-color":"#0169D9","line-color":"#0169D9","source-arrow-color":"#0169D9","target-arrow-color":"#0169D9","mid-source-arrow-color":"#0169D9","mid-target-arrow-color":"#0169D9"}).selector(":parent:selected").css({"background-color":"#CCE1F9","border-color":"#aec8e5"}).selector(":active").css({"overlay-color":"black","overlay-padding":10,"overlay-opacity":.25}),this.defaultLength=this.length};var Qu={parse:function(e,t,n,r){var i=this;if(x(t))return i.parseImplWarn(e,t,n,r);var a,o=ft(e,""+t,n?"t":"f","mapping"===r||!0===r||!1===r||null==r?"dontcare":r),s=i.propCache=i.propCache||[];return(a=s[o])||(a=s[o]=i.parseImplWarn(e,t,n,r)),(n||"mapping"===r)&&(a=Lt(a))&&(a.value=Lt(a.value)),a},parseImplWarn:function(e,t,n,r){var i=this.parseImpl(e,t,n,r);return i||null==t||Nt("The style property `".concat(e,": ").concat(t,"` is invalid")),!i||"width"!==i.name&&"height"!==i.name||"label"!==t||Nt("The style value of `label` is deprecated for `"+i.name+"`"),i},parseImpl:function(e,t,n,r){var i=this;e=z(e);var a=i.properties[e],o=t,s=i.types;if(!a)return null;if(void 0===t)return null;a.alias&&(a=a.pointsTo,e=a.name);var l=b(t);l&&(t=t.trim());var u,c,h=a.type;if(!h)return null;if(n&&(""===t||null===t))return{name:e,value:t,bypass:!0,deleteBypass:!0};if(x(t))return{name:e,value:t,strValue:"fn",mapped:s.fn,bypass:n};if(!l||r||t.length<7||"a"!==t[1]);else{if(t.length>=7&&"d"===t[0]&&(u=new RegExp(s.data.regex).exec(t))){if(n)return!1;var d=s.data;return{name:e,value:u,strValue:""+t,mapped:d,field:u[1],bypass:n}}if(t.length>=10&&"m"===t[0]&&(c=new RegExp(s.mapData.regex).exec(t))){if(n)return!1;if(h.multiple)return!1;var p=s.mapData;if(!h.color&&!h.number)return!1;var g=this.parse(e,c[4]);if(!g||g.mapped)return!1;var f=this.parse(e,c[5]);if(!f||f.mapped)return!1;if(g.pfValue===f.pfValue||g.strValue===f.strValue)return Nt("`"+e+": "+t+"` is not a valid mapper because the output range is zero; converting to `"+e+": "+g.strValue+"`"),this.parse(e,g.strValue);if(h.color){var v=g.value,y=f.value;if(!(v[0]!==y[0]||v[1]!==y[1]||v[2]!==y[2]||v[3]!==y[3]&&(null!=v[3]&&1!==v[3]||null!=y[3]&&1!==y[3])))return!1}return{name:e,value:c,strValue:""+t,mapped:p,field:c[1],fieldMin:parseFloat(c[2]),fieldMax:parseFloat(c[3]),valueMin:g.value,valueMax:f.value,bypass:n}}}if(h.multiple&&"multiple"!==r){var m;if(m=l?t.split(/\s+/):w(t)?t:[t],h.evenMultiple&&m.length%2!=0)return null;for(var E=[],T=[],_=[],C="",N=!1,A=0;A<m.length;A++){var L=i.parse(e,m[A],n,"multiple");N=N||b(L.value),E.push(L.value),_.push(null!=L.pfValue?L.pfValue:L.value),T.push(L.units),C+=(A>0?" ":"")+L.strValue}return h.validate&&!h.validate(E,T)?null:h.singleEnum&&N?1===E.length&&b(E[0])?{name:e,value:E[0],strValue:E[0],bypass:n}:null:{name:e,value:E,pfValue:_,strValue:C,bypass:n,units:T}}var S=function(){for(var r=0;r<h.enums.length;r++)if(h.enums[r]===t)return{name:e,value:t,strValue:""+t,bypass:n};return null};if(h.number){var O,I="px";if(h.units&&(O=h.units),h.implicitUnits&&(I=h.implicitUnits),!h.unitless)if(l){var k="px|em"+(h.allowPercent?"|\\%":"");O&&(k=O);var M=t.match("^("+V+")("+k+")?$");M&&(t=M[1],O=M[2]||I)}else O&&!h.implicitUnits||(O=I);if(t=parseFloat(t),isNaN(t)&&void 0===h.enums)return null;if(isNaN(t)&&void 0!==h.enums)return t=o,S();if(h.integer&&!D(t))return null;if(void 0!==h.min&&(t<h.min||h.strictMin&&t===h.min)||void 0!==h.max&&(t>h.max||h.strictMax&&t===h.max))return null;var P={name:e,value:t,strValue:""+t+(O||""),units:O,bypass:n};return h.unitless||"px"!==O&&"em"!==O?P.pfValue=t:P.pfValue="px"!==O&&O?this.getEmSizeInPixels()*t:t,"ms"!==O&&"s"!==O||(P.pfValue="ms"===O?t:1e3*t),"deg"!==O&&"rad"!==O||(P.pfValue="rad"===O?t:mn(t)),"%"===O&&(P.pfValue=t/100),P}if(h.propList){var R=[],B=""+t;if("none"===B);else{for(var F=B.split(/\s*,\s*|\s+/),G=0;G<F.length;G++){var Y=F[G].trim();i.properties[Y]?R.push(Y):Nt("`"+Y+"` is not a valid property name")}if(0===R.length)return null}return{name:e,value:R,strValue:0===R.length?"none":R.join(" "),bypass:n}}if(h.color){var X=re(t);return X?{name:e,value:X,pfValue:X,strValue:"rgb("+X[0]+","+X[1]+","+X[2]+")",bypass:n}:null}if(h.regex||h.regexes){if(h.enums){var U=S();if(U)return U}for(var j=h.regexes?h.regexes:[h.regex],H=0;H<j.length;H++){var q=new RegExp(j[H]).exec(t);if(q)return{name:e,value:h.singleRegexMatchValue?q[1]:q,strValue:""+t,bypass:n}}return null}return h.string?{name:e,value:""+t,strValue:""+t,bypass:n}:h.enums?S():null}},Ju=function e(t){if(!(this instanceof e))return new e(t);S(t)?(this._private={cy:t,coreStyle:{}},this.length=0,this.resetToDefault()):Dt("A style must have a core reference")},ec=Ju.prototype;ec.instanceString=function(){return"style"},ec.clear=function(){for(var e=this._private,t=e.cy.elements(),n=0;n<this.length;n++)this[n]=void 0;return this.length=0,e.contextStyles={},e.propDiffs={},this.cleanElements(t,!0),t.forEach((function(e){var t=e[0]._private;t.styleDirty=!0,t.appliedInitStyle=!1})),this},ec.resetToDefault=function(){return this.clear(),this.addDefaultStylesheet(),this},ec.core=function(e){return this._private.coreStyle[e]||this.getDefaultProperty(e)},ec.selector=function(e){var t="core"===e?null:new Ps(e),n=this.length++;return this[n]={selector:t,properties:[],mappedProperties:[],index:n},this},ec.css=function(){var e=this,t=arguments;if(1===t.length)for(var n=t[0],r=0;r<e.properties.length;r++){var i=e.properties[r],a=n[i.name];void 0===a&&(a=n[G(i.name)]),void 0!==a&&this.cssRule(i.name,a)}else 2===t.length&&this.cssRule(t[0],t[1]);return this},ec.style=ec.css,ec.cssRule=function(e,t){var n=this.parse(e,t);if(n){var r=this.length-1;this[r].properties.push(n),this[r].properties[n.name]=n,n.name.match(/pie-(\d+)-background-size/)&&n.value&&(this._private.hasPie=!0),n.mapped&&this[r].mappedProperties.push(n),!this[r].selector&&(this._private.coreStyle[n.name]=n)}return this},ec.append=function(e){return O(e)?e.appendToStyle(this):w(e)?this.appendFromJson(e):b(e)&&this.appendFromString(e),this},Ju.fromJson=function(e,t){var n=new Ju(e);return n.fromJson(t),n},Ju.fromString=function(e,t){return new Ju(e).fromString(t)},[Vu,Hu,qu,Wu,$u,Ku,Zu,Qu].forEach((function(e){Q(ec,e)})),Ju.types=ec.types,Ju.properties=ec.properties,Ju.propertyGroups=ec.propertyGroups,Ju.propertyGroupNames=ec.propertyGroupNames,Ju.propertyGroupKeys=ec.propertyGroupKeys;var tc={style:function(e){return e&&this.setStyle(e).update(),this._private.style},setStyle:function(e){var t=this._private;return O(e)?t.style=e.generateStyle(this):w(e)?t.style=Ju.fromJson(this,e):b(e)?t.style=Ju.fromString(this,e):t.style=Ju(this),t.style},updateStyle:function(){this.mutableElements().updateStyle()}},nc="single",rc={autolock:function(e){return void 0===e?this._private.autolock:(this._private.autolock=!!e,this)},autoungrabify:function(e){return void 0===e?this._private.autoungrabify:(this._private.autoungrabify=!!e,this)},autounselectify:function(e){return void 0===e?this._private.autounselectify:(this._private.autounselectify=!!e,this)},selectionType:function(e){var t=this._private;return null==t.selectionType&&(t.selectionType=nc),void 0===e?t.selectionType:("additive"!==e&&"single"!==e||(t.selectionType=e),this)},panningEnabled:function(e){return void 0===e?this._private.panningEnabled:(this._private.panningEnabled=!!e,this)},userPanningEnabled:function(e){return void 0===e?this._private.userPanningEnabled:(this._private.userPanningEnabled=!!e,this)},zoomingEnabled:function(e){return void 0===e?this._private.zoomingEnabled:(this._private.zoomingEnabled=!!e,this)},userZoomingEnabled:function(e){return void 0===e?this._private.userZoomingEnabled:(this._private.userZoomingEnabled=!!e,this)},boxSelectionEnabled:function(e){return void 0===e?this._private.boxSelectionEnabled:(this._private.boxSelectionEnabled=!!e,this)},pan:function(){var e,t,n,r,i,a=arguments,o=this._private.pan;switch(a.length){case 0:return o;case 1:if(b(a[0]))return o[e=a[0]];if(E(a[0])){if(!this._private.panningEnabled)return this;r=(n=a[0]).x,i=n.y,_(r)&&(o.x=r),_(i)&&(o.y=i),this.emit("pan viewport")}break;case 2:if(!this._private.panningEnabled)return this;e=a[0],t=a[1],"x"!==e&&"y"!==e||!_(t)||(o[e]=t),this.emit("pan viewport")}return this.notify("viewport"),this},panBy:function(e,t){var n,r,i,a,o,s=arguments,l=this._private.pan;if(!this._private.panningEnabled)return this;switch(s.length){case 1:E(e)&&(a=(i=s[0]).x,o=i.y,_(a)&&(l.x+=a),_(o)&&(l.y+=o),this.emit("pan viewport"));break;case 2:r=t,"x"!==(n=e)&&"y"!==n||!_(r)||(l[n]+=r),this.emit("pan viewport")}return this.notify("viewport"),this},fit:function(e,t){var n=this.getFitViewport(e,t);if(n){var r=this._private;r.zoom=n.zoom,r.pan=n.pan,this.emit("pan zoom viewport"),this.notify("viewport")}return this},getFitViewport:function(e,t){if(_(e)&&void 0===t&&(t=e,e=void 0),this._private.panningEnabled&&this._private.zoomingEnabled){var n;if(b(e)){var r=e;e=this.$(r)}else if(P(e)){var i=e;(n={x1:i.x1,y1:i.y1,x2:i.x2,y2:i.y2}).w=n.x2-n.x1,n.h=n.y2-n.y1}else N(e)||(e=this.mutableElements());if(!N(e)||!e.empty()){n=n||e.boundingBox();var a,o=this.width(),s=this.height();if(t=_(t)?t:0,!isNaN(o)&&!isNaN(s)&&o>0&&s>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0)return{zoom:a=(a=(a=Math.min((o-2*t)/n.w,(s-2*t)/n.h))>this._private.maxZoom?this._private.maxZoom:a)<this._private.minZoom?this._private.minZoom:a,pan:{x:(o-a*(n.x1+n.x2))/2,y:(s-a*(n.y1+n.y2))/2}}}}},zoomRange:function(e,t){var n=this._private;if(null==t){var r=e;e=r.min,t=r.max}return _(e)&&_(t)&&e<=t?(n.minZoom=e,n.maxZoom=t):_(e)&&void 0===t&&e<=n.maxZoom?n.minZoom=e:_(t)&&void 0===e&&t>=n.minZoom&&(n.maxZoom=t),this},minZoom:function(e){return void 0===e?this._private.minZoom:this.zoomRange({min:e})},maxZoom:function(e){return void 0===e?this._private.maxZoom:this.zoomRange({max:e})},getZoomedViewport:function(e){var t,n,r=this._private,i=r.pan,a=r.zoom,o=!1;if(r.zoomingEnabled||(o=!0),_(e)?n=e:E(e)&&(n=e.level,null!=e.position?t=hn(e.position,a,i):null!=e.renderedPosition&&(t=e.renderedPosition),null==t||r.panningEnabled||(o=!0)),n=(n=n>r.maxZoom?r.maxZoom:n)<r.minZoom?r.minZoom:n,o||!_(n)||n===a||null!=t&&(!_(t.x)||!_(t.y)))return null;if(null!=t){var s=i,l=a,u=n;return{zoomed:!0,panned:!0,zoom:u,pan:{x:-u/l*(t.x-s.x)+t.x,y:-u/l*(t.y-s.y)+t.y}}}return{zoomed:!0,panned:!1,zoom:n,pan:i}},zoom:function(e){if(void 0===e)return this._private.zoom;var t=this.getZoomedViewport(e),n=this._private;return null!=t&&t.zoomed?(n.zoom=t.zoom,t.panned&&(n.pan.x=t.pan.x,n.pan.y=t.pan.y),this.emit("zoom"+(t.panned?" pan":"")+" viewport"),this.notify("viewport"),this):this},viewport:function(e){var t=this._private,n=!0,r=!0,i=[],a=!1,o=!1;if(!e)return this;if(_(e.zoom)||(n=!1),E(e.pan)||(r=!1),!n&&!r)return this;if(n){var s=e.zoom;s<t.minZoom||s>t.maxZoom||!t.zoomingEnabled?a=!0:(t.zoom=s,i.push("zoom"))}if(r&&(!a||!e.cancelOnFailedZoom)&&t.panningEnabled){var l=e.pan;_(l.x)&&(t.pan.x=l.x,o=!1),_(l.y)&&(t.pan.y=l.y,o=!1),o||i.push("pan")}return i.length>0&&(i.push("viewport"),this.emit(i.join(" ")),this.notify("viewport")),this},center:function(e){var t=this.getCenterPan(e);return t&&(this._private.pan=t,this.emit("pan viewport"),this.notify("viewport")),this},getCenterPan:function(e,t){if(this._private.panningEnabled){if(b(e)){var n=e;e=this.mutableElements().filter(n)}else N(e)||(e=this.mutableElements());if(0!==e.length){var r=e.boundingBox(),i=this.width(),a=this.height();return{x:(i-(t=void 0===t?this._private.zoom:t)*(r.x1+r.x2))/2,y:(a-t*(r.y1+r.y2))/2}}}},reset:function(){return this._private.panningEnabled&&this._private.zoomingEnabled?(this.viewport({pan:{x:0,y:0},zoom:1}),this):this},invalidateSize:function(){this._private.sizeCache=null},size:function(){var e,t,n=this._private,r=n.container,i=this;return n.sizeCache=n.sizeCache||(r?(e=i.window().getComputedStyle(r),t=function(t){return parseFloat(e.getPropertyValue(t))},{width:r.clientWidth-t("padding-left")-t("padding-right"),height:r.clientHeight-t("padding-top")-t("padding-bottom")}):{width:1,height:1})},width:function(){return this.size().width},height:function(){return this.size().height},extent:function(){var e=this._private.pan,t=this._private.zoom,n=this.renderedExtent(),r={x1:(n.x1-e.x)/t,x2:(n.x2-e.x)/t,y1:(n.y1-e.y)/t,y2:(n.y2-e.y)/t};return r.w=r.x2-r.x1,r.h=r.y2-r.y1,r},renderedExtent:function(){var e=this.width(),t=this.height();return{x1:0,y1:0,x2:e,y2:t,w:e,h:t}},multiClickDebounceTime:function(e){return e?(this._private.multiClickDebounceTime=e,this):this._private.multiClickDebounceTime}};rc.centre=rc.center,rc.autolockNodes=rc.autolock,rc.autoungrabifyNodes=rc.autoungrabify;var ic={data:hs.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:hs.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:hs.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:hs.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};ic.attr=ic.data,ic.removeAttr=ic.removeData;var ac=function(e){var t=this,n=(e=Q({},e)).container;n&&!C(n)&&C(n[0])&&(n=n[0]);var r=n?n._cyreg:null;(r=r||{})&&r.cy&&(r.cy.destroy(),r={});var i=r.readies=r.readies||[];n&&(n._cyreg=r),r.cy=t;var a=void 0!==d&&void 0!==n&&!e.headless,o=e;o.layout=Q({name:a?"grid":"null"},o.layout),o.renderer=Q({name:a?"canvas":"null"},o.renderer);var s=function(e,t,n){return void 0!==t?t:void 0!==n?n:e},l=this._private={container:n,ready:!1,options:o,elements:new bu(this),listeners:[],aniEles:new bu(this),data:o.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:s(!0,o.zoomingEnabled),userZoomingEnabled:s(!0,o.userZoomingEnabled),panningEnabled:s(!0,o.panningEnabled),userPanningEnabled:s(!0,o.userPanningEnabled),boxSelectionEnabled:s(!0,o.boxSelectionEnabled),autolock:s(!1,o.autolock,o.autolockNodes),autoungrabify:s(!1,o.autoungrabify,o.autoungrabifyNodes),autounselectify:s(!1,o.autounselectify),styleEnabled:void 0===o.styleEnabled?a:o.styleEnabled,zoom:_(o.zoom)?o.zoom:1,pan:{x:E(o.pan)&&_(o.pan.x)?o.pan.x:0,y:E(o.pan)&&_(o.pan.y)?o.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:s(250,o.multiClickDebounceTime)};this.createEmitter(),this.selectionType(o.selectionType),this.zoomRange({min:o.minZoom,max:o.maxZoom});var u=function(e,t){if(e.some(R))return Gi.all(e).then(t);t(e)};l.styleEnabled&&t.setStyle([]);var c=Q({},o,o.renderer);t.initRenderer(c);var h=function(e,n,r){t.notifications(!1);var i=t.mutableElements();i.length>0&&i.remove(),null!=e&&(E(e)||w(e))&&t.add(e),t.one("layoutready",(function(e){t.notifications(!0),t.emit(e),t.one("load",n),t.emitAndNotify("load")})).one("layoutstop",(function(){t.one("done",r),t.emit("done")}));var a=Q({},t._private.options.layout);a.eles=t.elements(),t.layout(a).run()};u([o.style,o.elements],(function(e){var n=e[0],a=e[1];l.styleEnabled&&t.style().append(n),h(a,(function(){t.startAnimationLoop(),l.ready=!0,x(o.ready)&&t.on("ready",o.ready);for(var e=0;e<i.length;e++){var n=i[e];t.on("ready",n)}r&&(r.readies=[]),t.emit("ready")}),o.done)}))},oc=ac.prototype;Q(oc,{instanceString:function(){return"core"},isReady:function(){return this._private.ready},destroyed:function(){return this._private.destroyed},ready:function(e){return this.isReady()?this.emitter().emit("ready",[],e):this.on("ready",e),this},destroy:function(){var e=this;if(!e.destroyed())return e.stopAnimationLoop(),e.destroyRenderer(),this.emit("destroy"),e._private.destroyed=!0,e},hasElementWithId:function(e){return this._private.elements.hasElementWithId(e)},getElementById:function(e){return this._private.elements.getElementById(e)},hasCompoundNodes:function(){return this._private.hasCompoundNodes},headless:function(){return this._private.renderer.isHeadless()},styleEnabled:function(){return this._private.styleEnabled},addToPool:function(e){return this._private.elements.merge(e),this},removeFromPool:function(e){return this._private.elements.unmerge(e),this},container:function(){return this._private.container||null},window:function(){if(null==this._private.container)return d;var e=this._private.container.ownerDocument;return void 0===e||null==e?d:e.defaultView||d},mount:function(e){if(null!=e){var t=this,n=t._private,r=n.options;return!C(e)&&C(e[0])&&(e=e[0]),t.stopAnimationLoop(),t.destroyRenderer(),n.container=e,n.styleEnabled=!0,t.invalidateSize(),t.initRenderer(Q({},r,r.renderer,{name:"null"===r.renderer.name?"canvas":r.renderer.name})),t.startAnimationLoop(),t.style(r.style),t.emit("mount"),t}},unmount:function(){var e=this;return e.stopAnimationLoop(),e.destroyRenderer(),e.initRenderer({name:"null"}),e.emit("unmount"),e},options:function(){return Lt(this._private.options)},json:function(e){var t=this,n=t._private,r=t.mutableElements(),i=function(e){return t.getElementById(e.id())};if(E(e)){if(t.startBatch(),e.elements){var a={},o=function(e,n){for(var r=[],i=[],o=0;o<e.length;o++){var s=e[o];if(s.data.id){var l=""+s.data.id,u=t.getElementById(l);a[l]=!0,0!==u.length?i.push({ele:u,json:s}):n?(s.group=n,r.push(s)):r.push(s)}else Nt("cy.json() cannot handle elements without an ID attribute")}t.add(r);for(var c=0;c<i.length;c++){var h=i[c],d=h.ele,p=h.json;d.json(p)}};if(w(e.elements))o(e.elements);else for(var s=["nodes","edges"],l=0;l<s.length;l++){var u=s[l],c=e.elements[u];w(c)&&o(c,u)}var h=t.collection();r.filter((function(e){return!a[e.id()]})).forEach((function(e){e.isParent()?h.merge(e):e.remove()})),h.forEach((function(e){return e.children().move({parent:null})})),h.forEach((function(e){return i(e).remove()}))}e.style&&t.style(e.style),null!=e.zoom&&e.zoom!==n.zoom&&t.zoom(e.zoom),e.pan&&(e.pan.x===n.pan.x&&e.pan.y===n.pan.y||t.pan(e.pan)),e.data&&t.data(e.data);for(var d=["minZoom","maxZoom","zoomingEnabled","userZoomingEnabled","panningEnabled","userPanningEnabled","boxSelectionEnabled","autolock","autoungrabify","autounselectify","multiClickDebounceTime"],p=0;p<d.length;p++){var g=d[p];null!=e[g]&&t[g](e[g])}return t.endBatch(),this}var f={};e?f.elements=this.elements().map((function(e){return e.json()})):(f.elements={},r.forEach((function(e){var t=e.group();f.elements[t]||(f.elements[t]=[]),f.elements[t].push(e.json())}))),this._private.styleEnabled&&(f.style=t.style().json()),f.data=Lt(t.data());var v=n.options;return f.zoomingEnabled=n.zoomingEnabled,f.userZoomingEnabled=n.userZoomingEnabled,f.zoom=n.zoom,f.minZoom=n.minZoom,f.maxZoom=n.maxZoom,f.panningEnabled=n.panningEnabled,f.userPanningEnabled=n.userPanningEnabled,f.pan=Lt(n.pan),f.boxSelectionEnabled=n.boxSelectionEnabled,f.renderer=Lt(v.renderer),f.hideEdgesOnViewport=v.hideEdgesOnViewport,f.textureOnViewport=v.textureOnViewport,f.wheelSensitivity=v.wheelSensitivity,f.motionBlur=v.motionBlur,f.multiClickDebounceTime=v.multiClickDebounceTime,f}}),oc.$id=oc.getElementById,[wu,ku,Ru,Bu,Fu,zu,Yu,Xu,tc,rc,ic].forEach((function(e){Q(oc,e)}));var sc={fit:!0,directed:!1,padding:30,circle:!1,grid:!1,spacingFactor:1.75,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,roots:void 0,depthSort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}},lc={maximal:!1,acyclic:!1},uc=function(e){return e.scratch("breadthfirst")},cc=function(e,t){return e.scratch("breadthfirst",t)};function hc(e){this.options=Q({},sc,lc,e)}hc.prototype.run=function(){var e,t=this.options,n=t,r=t.cy,i=n.eles,a=i.nodes().filter((function(e){return!e.isParent()})),o=i,s=n.directed,l=n.acyclic||n.maximal||n.maximalAdjustments>0,u=Ln(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()});if(N(n.roots))e=n.roots;else if(w(n.roots)){for(var c=[],h=0;h<n.roots.length;h++){var d=n.roots[h],p=r.getElementById(d);c.push(p)}e=r.collection(c)}else if(b(n.roots))e=r.$(n.roots);else if(s)e=a.roots();else{var g=i.components();e=r.collection();for(var f=function(t){var n=g[t],r=n.maxDegree(!1),i=n.filter((function(e){return e.degree(!1)===r}));e=e.add(i)},v=0;v<g.length;v++)f(v)}var y=[],m={},x=function(e,t){null==y[t]&&(y[t]=[]);var n=y[t].length;y[t].push(e),cc(e,{index:n,depth:t})},E=function(e,t){var n=uc(e),r=n.depth,i=n.index;y[r][i]=null,x(e,t)};o.bfs({roots:e,directed:n.directed,visit:function(e,t,n,r,i){var a=e[0],o=a.id();x(a,i),m[o]=!0}});for(var T=[],_=0;_<a.length;_++){var D=a[_];m[D.id()]||T.push(D)}var C=function(e){for(var t=y[e],n=0;n<t.length;n++){var r=t[n];null!=r?cc(r,{depth:e,index:n}):(t.splice(n,1),n--)}},A=function(){for(var e=0;e<y.length;e++)C(e)},L=function(e,t){for(var r=uc(e),a=e.incomers().filter((function(e){return e.isNode()&&i.has(e)})),o=-1,s=e.id(),l=0;l<a.length;l++){var u=a[l],c=uc(u);o=Math.max(o,c.depth)}if(r.depth<=o){if(!n.acyclic&&t[s])return null;var h=o+1;return E(e,h),t[s]=h,!0}return!1};if(s&&l){var S=[],O={},I=function(e){return S.push(e)},k=function(){return S.shift()};for(a.forEach((function(e){return S.push(e)}));S.length>0;){var M=k(),P=L(M,O);if(P)M.outgoers().filter((function(e){return e.isNode()&&i.has(e)})).forEach(I);else if(null===P){Nt("Detected double maximal shift for node `"+M.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}A();var R=0;if(n.avoidOverlap)for(var B=0;B<a.length;B++){var F=a[B].layoutDimensions(n),z=F.w,G=F.h;R=Math.max(R,z,G)}var Y={},X=function(e){if(Y[e.id()])return Y[e.id()];for(var t=uc(e).depth,n=e.neighborhood(),r=0,i=0,o=0;o<n.length;o++){var s=n[o];if(!s.isEdge()&&!s.isParent()&&a.has(s)){var l=uc(s);if(null!=l){var u=l.index,c=l.depth;if(null!=u&&null!=c){var h=y[c].length;c<t&&(r+=u/h,i++)}}}}return r/=i=Math.max(1,i),0===i&&(r=0),Y[e.id()]=r,r},V=function(e,t){var n=X(e)-X(t);return 0===n?K(e.id(),t.id()):n};void 0!==n.depthSort&&(V=n.depthSort);for(var U=0;U<y.length;U++)y[U].sort(V),C(U);for(var j=[],H=0;H<T.length;H++)j.push(T[H]);y.unshift(j),A();for(var q=0,W=0;W<y.length;W++)q=Math.max(y[W].length,q);var $={x:u.x1+u.w/2,y:u.x1+u.h/2},Z=y.reduce((function(e,t){return Math.max(e,t.length)}),0),Q=function(e){var t=uc(e),r=t.depth,i=t.index,a=y[r].length,o=Math.max(u.w/((n.grid?Z:a)+1),R),s=Math.max(u.h/(y.length+1),R),l=Math.min(u.w/2/y.length,u.h/2/y.length);if(l=Math.max(l,R),n.circle){var c=l*r+l-(y.length>0&&y[0].length<=3?l/2:0),h=2*Math.PI/y[r].length*i;return 0===r&&1===y[0].length&&(c=1),{x:$.x+c*Math.cos(h),y:$.y+c*Math.sin(h)}}return{x:$.x+(i+1-(a+1)/2)*o,y:(r+1)*s}};return i.nodes().layoutPositions(this,n,Q),this};var dc={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function pc(e){this.options=Q({},dc,e)}pc.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,i=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,a=r.nodes().not(":parent");t.sort&&(a=a.sort(t.sort));for(var o,s=Ln(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=(void 0===t.sweep?2*Math.PI-2*Math.PI/a.length:t.sweep)/Math.max(1,a.length-1),c=0,h=0;h<a.length;h++){var d=a[h].layoutDimensions(t),p=d.w,g=d.h;c=Math.max(c,p,g)}if(o=_(t.radius)?t.radius:a.length<=1?0:Math.min(s.h,s.w)/2-c,a.length>1&&t.avoidOverlap){c*=1.75;var f=Math.cos(u)-Math.cos(0),v=Math.sin(u)-Math.sin(0),y=Math.sqrt(c*c/(f*f+v*v));o=Math.max(y,o)}var m=function(e,n){var r=t.startAngle+n*u*(i?1:-1),a=o*Math.cos(r),s=o*Math.sin(r);return{x:l.x+a,y:l.y+s}};return r.nodes().layoutPositions(this,t,m),this};var gc,fc={fit:!0,padding:30,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:function(e){return e.degree()},levelWidth:function(e){return e.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function vc(e){this.options=Q({},fc,e)}vc.prototype.run=function(){for(var e=this.options,t=e,n=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,r=e.cy,i=t.eles,a=i.nodes().not(":parent"),o=Ln(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),s={x:o.x1+o.w/2,y:o.y1+o.h/2},l=[],u=0,c=0;c<a.length;c++){var h=a[c],d=void 0;d=t.concentric(h),l.push({value:d,node:h}),h._private.scratch.concentric=d}a.updateStyle();for(var p=0;p<a.length;p++){var g=a[p].layoutDimensions(t);u=Math.max(u,g.w,g.h)}l.sort((function(e,t){return t.value-e.value}));for(var f=t.levelWidth(a),v=[[]],y=v[0],m=0;m<l.length;m++){var b=l[m];y.length>0&&Math.abs(y[0].value-b.value)>=f&&(y=[],v.push(y)),y.push(b)}var x=u+t.minNodeSpacing;if(!t.avoidOverlap){var w=v.length>0&&v[0].length>1,E=(Math.min(o.w,o.h)/2-x)/(v.length+w?1:0);x=Math.min(x,E)}for(var T=0,_=0;_<v.length;_++){var D=v[_],C=void 0===t.sweep?2*Math.PI-2*Math.PI/D.length:t.sweep,N=D.dTheta=C/Math.max(1,D.length-1);if(D.length>1&&t.avoidOverlap){var A=Math.cos(N)-Math.cos(0),L=Math.sin(N)-Math.sin(0),S=Math.sqrt(x*x/(A*A+L*L));T=Math.max(S,T)}D.r=T,T+=x}if(t.equidistant){for(var O=0,I=0,k=0;k<v.length;k++){var M=v[k].r-I;O=Math.max(O,M)}I=0;for(var P=0;P<v.length;P++){var R=v[P];0===P&&(I=R.r),R.r=I,I+=O}}for(var B={},F=0;F<v.length;F++)for(var z=v[F],G=z.dTheta,Y=z.r,X=0;X<z.length;X++){var V=z[X],U=t.startAngle+(n?1:-1)*G*X,j={x:s.x+Y*Math.cos(U),y:s.y+Y*Math.sin(U)};B[V.node.id()]=j}return i.nodes().layoutPositions(this,t,(function(e){var t=e.id();return B[t]})),this};var yc={ready:function(){},stop:function(){},animate:!0,animationEasing:void 0,animationDuration:void 0,animateFilter:function(e,t){return!0},animationThreshold:250,refresh:20,fit:!0,padding:30,boundingBox:void 0,nodeDimensionsIncludeLabels:!1,randomize:!1,componentSpacing:40,nodeRepulsion:function(e){return 2048},nodeOverlap:4,idealEdgeLength:function(e){return 32},edgeElasticity:function(e){return 32},nestingFactor:1.2,gravity:1,numIter:1e3,initialTemp:1e3,coolingFactor:.99,minTemp:1};function mc(e){this.options=Q({},yc,e),this.options.layout=this;var t=this.options.eles.nodes(),n=this.options.eles.edges().filter((function(e){var n=e.source().data("id"),r=e.target().data("id"),i=t.some((function(e){return e.data("id")===n})),a=t.some((function(e){return e.data("id")===r}));return!i||!a}));this.options.eles=this.options.eles.not(n)}mc.prototype.run=function(){var e=this.options,t=e.cy,n=this;n.stopped=!1,!0!==e.animate&&!1!==e.animate||n.emit({type:"layoutstart",layout:n}),gc=!0===e.debug;var r=xc(t,n,e);gc&&bc(r),e.randomize&&Tc(r);var i=rt(),a=function(){Dc(r,t,e),!0===e.fit&&t.fit(e.padding)},o=function(t){return!(n.stopped||t>=e.numIter||(Cc(r,e),r.temperature=r.temperature*e.coolingFactor,r.temperature<e.minTemp))},s=function(){if(!0===e.animate||!1===e.animate)a(),n.one("layoutstop",e.stop),n.emit({type:"layoutstop",layout:n});else{var t=e.eles.nodes(),i=_c(r,e,t);t.layoutPositions(n,e,i)}},l=0,u=!0;if(!0===e.animate)!function t(){for(var n=0;u&&n<e.refresh;)u=o(l),l++,n++;u?(rt()-i>=e.animationThreshold&&a(),nt(t)):(Fc(r,e),s())}();else{for(;u;)u=o(l),l++;Fc(r,e),s()}return this},mc.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this},mc.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};var bc,xc=function(e,t,n){for(var r=n.eles.edges(),i=n.eles.nodes(),a=Ln(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),o={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:i.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:r.size(),temperature:n.initialTemp,clientWidth:a.w,clientHeight:a.h,boundingBox:a},s=n.eles.components(),l={},u=0;u<s.length;u++)for(var c=s[u],h=0;h<c.length;h++)l[c[h].id()]=u;for(u=0;u<o.nodeSize;u++){var d=(y=i[u]).layoutDimensions(n);(M={}).isLocked=y.locked(),M.id=y.data("id"),M.parentId=y.data("parent"),M.cmptId=l[y.id()],M.children=[],M.positionX=y.position("x"),M.positionY=y.position("y"),M.offsetX=0,M.offsetY=0,M.height=d.w,M.width=d.h,M.maxX=M.positionX+M.width/2,M.minX=M.positionX-M.width/2,M.maxY=M.positionY+M.height/2,M.minY=M.positionY-M.height/2,M.padLeft=parseFloat(y.style("padding")),M.padRight=parseFloat(y.style("padding")),M.padTop=parseFloat(y.style("padding")),M.padBottom=parseFloat(y.style("padding")),M.nodeRepulsion=x(n.nodeRepulsion)?n.nodeRepulsion(y):n.nodeRepulsion,o.layoutNodes.push(M),o.idToIndex[M.id]=u}var p=[],g=0,f=-1,v=[];for(u=0;u<o.nodeSize;u++){var y,m=(y=o.layoutNodes[u]).parentId;null!=m?o.layoutNodes[o.idToIndex[m]].children.push(y.id):(p[++f]=y.id,v.push(y.id))}for(o.graphSet.push(v);g<=f;){var b=p[g++],w=o.idToIndex[b],E=o.layoutNodes[w].children;if(E.length>0)for(o.graphSet.push(E),u=0;u<E.length;u++)p[++f]=E[u]}for(u=0;u<o.graphSet.length;u++){var T=o.graphSet[u];for(h=0;h<T.length;h++){var _=o.idToIndex[T[h]];o.indexToGraph[_]=u}}for(u=0;u<o.edgeSize;u++){var D=r[u],C={};C.id=D.data("id"),C.sourceId=D.data("source"),C.targetId=D.data("target");var N=x(n.idealEdgeLength)?n.idealEdgeLength(D):n.idealEdgeLength,A=x(n.edgeElasticity)?n.edgeElasticity(D):n.edgeElasticity,L=o.idToIndex[C.sourceId],S=o.idToIndex[C.targetId];if(o.indexToGraph[L]!=o.indexToGraph[S]){for(var O=wc(C.sourceId,C.targetId,o),I=o.graphSet[O],k=0,M=o.layoutNodes[L];-1===I.indexOf(M.id);)M=o.layoutNodes[o.idToIndex[M.parentId]],k++;for(M=o.layoutNodes[S];-1===I.indexOf(M.id);)M=o.layoutNodes[o.idToIndex[M.parentId]],k++;N*=k*n.nestingFactor}C.idealLength=N,C.elasticity=A,o.layoutEdges.push(C)}return o},wc=function(e,t,n){var r=Ec(e,t,0,n);return 2>r.count?0:r.graph},Ec=function e(t,n,r,i){var a=i.graphSet[r];if(-1<a.indexOf(t)&&-1<a.indexOf(n))return{count:2,graph:r};for(var o=0,s=0;s<a.length;s++){var l=a[s],u=i.idToIndex[l],c=i.layoutNodes[u].children;if(0!==c.length){var h=e(t,n,i.indexToGraph[i.idToIndex[c[0]]],i);if(0!==h.count){if(1!==h.count)return h;if(2==++o)break}}}return{count:o,graph:r}},Tc=function(e,t){for(var n=e.clientWidth,r=e.clientHeight,i=0;i<e.nodeSize;i++){var a=e.layoutNodes[i];0!==a.children.length||a.isLocked||(a.positionX=Math.random()*n,a.positionY=Math.random()*r)}},_c=function(e,t,n){var r=e.boundingBox,i={x1:1/0,x2:-1/0,y1:1/0,y2:-1/0};return t.boundingBox&&(n.forEach((function(t){var n=e.layoutNodes[e.idToIndex[t.data("id")]];i.x1=Math.min(i.x1,n.positionX),i.x2=Math.max(i.x2,n.positionX),i.y1=Math.min(i.y1,n.positionY),i.y2=Math.max(i.y2,n.positionY)})),i.w=i.x2-i.x1,i.h=i.y2-i.y1),function(n,a){var o=e.layoutNodes[e.idToIndex[n.data("id")]];if(t.boundingBox){var s=(o.positionX-i.x1)/i.w,l=(o.positionY-i.y1)/i.h;return{x:r.x1+s*r.w,y:r.y1+l*r.h}}return{x:o.positionX,y:o.positionY}}},Dc=function(e,t,n){var r=n.layout,i=n.eles.nodes(),a=_c(e,n,i);i.positions(a),!0!==e.ready&&(e.ready=!0,r.one("layoutready",n.ready),r.emit({type:"layoutready",layout:this}))},Cc=function(e,t,n){Nc(e,t),Ic(e),kc(e,t),Mc(e),Pc(e)},Nc=function(e,t){for(var n=0;n<e.graphSet.length;n++)for(var r=e.graphSet[n],i=r.length,a=0;a<i;a++)for(var o=e.layoutNodes[e.idToIndex[r[a]]],s=a+1;s<i;s++){var l=e.layoutNodes[e.idToIndex[r[s]]];Lc(o,l,e,t)}},Ac=function(e){return-e+2*e*Math.random()},Lc=function(e,t,n,r){if(e.cmptId===t.cmptId||n.isCompound){var i=t.positionX-e.positionX,a=t.positionY-e.positionY,o=1;0===i&&0===a&&(i=Ac(o),a=Ac(o));var s=Sc(e,t,i,a);if(s>0)var l=(c=r.nodeOverlap*s)*i/(v=Math.sqrt(i*i+a*a)),u=c*a/v;else{var c,h=Oc(e,i,a),d=Oc(t,-1*i,-1*a),p=d.x-h.x,g=d.y-h.y,f=p*p+g*g,v=Math.sqrt(f);l=(c=(e.nodeRepulsion+t.nodeRepulsion)/f)*p/v,u=c*g/v}e.isLocked||(e.offsetX-=l,e.offsetY-=u),t.isLocked||(t.offsetX+=l,t.offsetY+=u)}},Sc=function(e,t,n,r){if(n>0)var i=e.maxX-t.minX;else i=t.maxX-e.minX;if(r>0)var a=e.maxY-t.minY;else a=t.maxY-e.minY;return i>=0&&a>=0?Math.sqrt(i*i+a*a):0},Oc=function(e,t,n){var r=e.positionX,i=e.positionY,a=e.height||1,o=e.width||1,s=n/t,l=a/o,u={};return 0===t&&0<n||0===t&&0>n?(u.x=r,u.y=i+a/2,u):0<t&&-1*l<=s&&s<=l?(u.x=r+o/2,u.y=i+o*n/2/t,u):0>t&&-1*l<=s&&s<=l?(u.x=r-o/2,u.y=i-o*n/2/t,u):0<n&&(s<=-1*l||s>=l)?(u.x=r+a*t/2/n,u.y=i+a/2,u):0>n&&(s<=-1*l||s>=l)?(u.x=r-a*t/2/n,u.y=i-a/2,u):u},Ic=function(e,t){for(var n=0;n<e.edgeSize;n++){var r=e.layoutEdges[n],i=e.idToIndex[r.sourceId],a=e.layoutNodes[i],o=e.idToIndex[r.targetId],s=e.layoutNodes[o],l=s.positionX-a.positionX,u=s.positionY-a.positionY;if(0!==l||0!==u){var c=Oc(a,l,u),h=Oc(s,-1*l,-1*u),d=h.x-c.x,p=h.y-c.y,g=Math.sqrt(d*d+p*p),f=Math.pow(r.idealLength-g,2)/r.elasticity;if(0!==g)var v=f*d/g,y=f*p/g;else v=0,y=0;a.isLocked||(a.offsetX+=v,a.offsetY+=y),s.isLocked||(s.offsetX-=v,s.offsetY-=y)}}},kc=function(e,t){if(0!==t.gravity)for(var n=1,r=0;r<e.graphSet.length;r++){var i=e.graphSet[r],a=i.length;if(0===r)var o=e.clientHeight/2,s=e.clientWidth/2;else{var l=e.layoutNodes[e.idToIndex[i[0]]],u=e.layoutNodes[e.idToIndex[l.parentId]];o=u.positionX,s=u.positionY}for(var c=0;c<a;c++){var h=e.layoutNodes[e.idToIndex[i[c]]];if(!h.isLocked){var d=o-h.positionX,p=s-h.positionY,g=Math.sqrt(d*d+p*p);if(g>n){var f=t.gravity*d/g,v=t.gravity*p/g;h.offsetX+=f,h.offsetY+=v}}}}},Mc=function(e,t){var n=[],r=0,i=-1;for(n.push.apply(n,e.graphSet[0]),i+=e.graphSet[0].length;r<=i;){var a=n[r++],o=e.idToIndex[a],s=e.layoutNodes[o],l=s.children;if(0<l.length&&!s.isLocked){for(var u=s.offsetX,c=s.offsetY,h=0;h<l.length;h++){var d=e.layoutNodes[e.idToIndex[l[h]]];d.offsetX+=u,d.offsetY+=c,n[++i]=l[h]}s.offsetX=0,s.offsetY=0}}},Pc=function(e,t){for(var n=0;n<e.nodeSize;n++)0<(i=e.layoutNodes[n]).children.length&&(i.maxX=void 0,i.minX=void 0,i.maxY=void 0,i.minY=void 0);for(n=0;n<e.nodeSize;n++)if(!(0<(i=e.layoutNodes[n]).children.length||i.isLocked)){var r=Rc(i.offsetX,i.offsetY,e.temperature);i.positionX+=r.x,i.positionY+=r.y,i.offsetX=0,i.offsetY=0,i.minX=i.positionX-i.width,i.maxX=i.positionX+i.width,i.minY=i.positionY-i.height,i.maxY=i.positionY+i.height,Bc(i,e)}for(n=0;n<e.nodeSize;n++){var i;0<(i=e.layoutNodes[n]).children.length&&!i.isLocked&&(i.positionX=(i.maxX+i.minX)/2,i.positionY=(i.maxY+i.minY)/2,i.width=i.maxX-i.minX,i.height=i.maxY-i.minY)}},Rc=function(e,t,n){var r=Math.sqrt(e*e+t*t);if(r>n)var i={x:n*e/r,y:n*t/r};else i={x:e,y:t};return i},Bc=function e(t,n){var r=t.parentId;if(null!=r){var i=n.layoutNodes[n.idToIndex[r]],a=!1;return(null==i.maxX||t.maxX+i.padRight>i.maxX)&&(i.maxX=t.maxX+i.padRight,a=!0),(null==i.minX||t.minX-i.padLeft<i.minX)&&(i.minX=t.minX-i.padLeft,a=!0),(null==i.maxY||t.maxY+i.padBottom>i.maxY)&&(i.maxY=t.maxY+i.padBottom,a=!0),(null==i.minY||t.minY-i.padTop<i.minY)&&(i.minY=t.minY-i.padTop,a=!0),a?e(i,n):void 0}},Fc=function(e,t){for(var n=e.layoutNodes,r=[],i=0;i<n.length;i++){var a=n[i],o=a.cmptId;(r[o]=r[o]||[]).push(a)}var s=0;for(i=0;i<r.length;i++)if(f=r[i]){f.x1=1/0,f.x2=-1/0,f.y1=1/0,f.y2=-1/0;for(var l=0;l<f.length;l++){var u=f[l];f.x1=Math.min(f.x1,u.positionX-u.width/2),f.x2=Math.max(f.x2,u.positionX+u.width/2),f.y1=Math.min(f.y1,u.positionY-u.height/2),f.y2=Math.max(f.y2,u.positionY+u.height/2)}f.w=f.x2-f.x1,f.h=f.y2-f.y1,s+=f.w*f.h}r.sort((function(e,t){return t.w*t.h-e.w*e.h}));var c=0,h=0,d=0,p=0,g=Math.sqrt(s)*e.clientWidth/e.clientHeight;for(i=0;i<r.length;i++){var f;if(f=r[i]){for(l=0;l<f.length;l++)(u=f[l]).isLocked||(u.positionX+=c-f.x1,u.positionY+=h-f.y1);c+=f.w+t.componentSpacing,d+=f.w+t.componentSpacing,p=Math.max(p,f.h),d>g&&(h+=p+t.componentSpacing,c=0,d=0,p=0)}}},zc={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:function(e){},sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Gc(e){this.options=Q({},zc,e)}Gc.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,i=r.nodes().not(":parent");t.sort&&(i=i.sort(t.sort));var a=Ln(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()});if(0===a.h||0===a.w)r.nodes().layoutPositions(this,t,(function(e){return{x:a.x1,y:a.y1}}));else{var o=i.size(),s=Math.sqrt(o*a.h/a.w),l=Math.round(s),u=Math.round(a.w/a.h*s),c=function(e){if(null==e)return Math.min(l,u);Math.min(l,u)==l?l=e:u=e},h=function(e){if(null==e)return Math.max(l,u);Math.max(l,u)==l?l=e:u=e},d=t.rows,p=null!=t.cols?t.cols:t.columns;if(null!=d&&null!=p)l=d,u=p;else if(null!=d&&null==p)l=d,u=Math.ceil(o/l);else if(null==d&&null!=p)u=p,l=Math.ceil(o/u);else if(u*l>o){var g=c(),f=h();(g-1)*f>=o?c(g-1):(f-1)*g>=o&&h(f-1)}else for(;u*l<o;){var v=c(),y=h();(y+1)*v>=o?h(y+1):c(v+1)}var m=a.w/u,b=a.h/l;if(t.condense&&(m=0,b=0),t.avoidOverlap)for(var x=0;x<i.length;x++){var w=i[x],E=w._private.position;null!=E.x&&null!=E.y||(E.x=0,E.y=0);var T=w.layoutDimensions(t),_=t.avoidOverlapPadding,D=T.w+_,C=T.h+_;m=Math.max(m,D),b=Math.max(b,C)}for(var N={},A=function(e,t){return!!N["c-"+e+"-"+t]},L=function(e,t){N["c-"+e+"-"+t]=!0},S=0,O=0,I=function(){++O>=u&&(O=0,S++)},k={},M=0;M<i.length;M++){var P=i[M],R=t.position(P);if(R&&(void 0!==R.row||void 0!==R.col)){var B={row:R.row,col:R.col};if(void 0===B.col)for(B.col=0;A(B.row,B.col);)B.col++;else if(void 0===B.row)for(B.row=0;A(B.row,B.col);)B.row++;k[P.id()]=B,L(B.row,B.col)}}var F=function(e,t){var n,r;if(e.locked()||e.isParent())return!1;var i=k[e.id()];if(i)n=i.col*m+m/2+a.x1,r=i.row*b+b/2+a.y1;else{for(;A(S,O);)I();n=O*m+m/2+a.x1,r=S*b+b/2+a.y1,L(S,O),I()}return{x:n,y:r}};i.layoutPositions(this,t,F)}return this};var Yc={ready:function(){},stop:function(){}};function Xc(e){this.options=Q({},Yc,e)}Xc.prototype.run=function(){var e=this.options,t=e.eles,n=this;return e.cy,n.emit("layoutstart"),t.nodes().positions((function(){return{x:0,y:0}})),n.one("layoutready",e.ready),n.emit("layoutready"),n.one("layoutstop",e.stop),n.emit("layoutstop"),this},Xc.prototype.stop=function(){return this};var Vc={positions:void 0,zoom:void 0,pan:void 0,fit:!0,padding:30,spacingFactor:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Uc(e){this.options=Q({},Vc,e)}Uc.prototype.run=function(){var e=this.options,t=e.eles.nodes(),n=x(e.positions);function r(t){if(null==e.positions)return cn(t.position());if(n)return e.positions(t);var r=e.positions[t._private.data.id];return null==r?null:r}return t.layoutPositions(this,e,(function(e,t){var n=r(e);return!e.locked()&&null!=n&&n})),this};var jc={fit:!0,padding:30,boundingBox:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Hc(e){this.options=Q({},jc,e)}Hc.prototype.run=function(){var e=this.options,t=e.cy,n=e.eles,r=Ln(e.boundingBox?e.boundingBox:{x1:0,y1:0,w:t.width(),h:t.height()}),i=function(e,t){return{x:r.x1+Math.round(Math.random()*r.w),y:r.y1+Math.round(Math.random()*r.h)}};return n.nodes().layoutPositions(this,e,i),this};var qc=[{name:"breadthfirst",impl:hc},{name:"circle",impl:pc},{name:"concentric",impl:vc},{name:"cose",impl:mc},{name:"grid",impl:Gc},{name:"null",impl:Xc},{name:"preset",impl:Uc},{name:"random",impl:Hc}];function Wc(e){this.options=e,this.notifications=0}var $c=function(){},Kc=function(){throw new Error("A headless instance can not render images")};Wc.prototype={recalculateRenderedStyle:$c,notify:function(){this.notifications++},init:$c,isHeadless:function(){return!0},png:Kc,jpg:Kc};var Zc={arrowShapeWidth:.3,registerArrowShapes:function(){var e=this.arrowShapes={},t=this,n=function(e,t,n,r,i,a,o){var s=i.x-n/2-o,l=i.x+n/2+o,u=i.y-n/2-o,c=i.y+n/2+o;return s<=e&&e<=l&&u<=t&&t<=c},r=function(e,t,n,r,i){var a=e*Math.cos(r)-t*Math.sin(r),o=(e*Math.sin(r)+t*Math.cos(r))*n;return{x:a*n+i.x,y:o+i.y}},i=function(e,t,n,i){for(var a=[],o=0;o<e.length;o+=2){var s=e[o],l=e[o+1];a.push(r(s,l,t,n,i))}return a},a=function(e){for(var t=[],n=0;n<e.length;n++){var r=e[n];t.push(r.x,r.y)}return t},o=function(e){return e.pstyle("width").pfValue*e.pstyle("arrow-scale").pfValue*2},s=function(r,s){b(s)&&(s=e[s]),e[r]=Q({name:r,points:[-.15,-.3,.15,-.3,.15,.3,-.15,.3],collide:function(e,t,n,r,o,s){var l=a(i(this.points,n+2*s,r,o));return Wn(e,t,l)},roughCollide:n,draw:function(e,n,r,a){var o=i(this.points,n,r,a);t.arrowShapeImpl("polygon")(e,o)},spacing:function(e){return 0},gap:o},s)};s("none",{collide:Et,roughCollide:Et,draw:_t,spacing:Tt,gap:Tt}),s("triangle",{points:[-.15,-.3,0,0,.15,-.3]}),s("arrow","triangle"),s("triangle-backcurve",{points:e.triangle.points,controlPoint:[0,-.15],roughCollide:n,draw:function(e,n,a,o,s){var l=i(this.points,n,a,o),u=this.controlPoint,c=r(u[0],u[1],n,a,o);t.arrowShapeImpl(this.name)(e,l,c)},gap:function(e){return.8*o(e)}}),s("triangle-tee",{points:[0,0,.15,-.3,-.15,-.3,0,0],pointsTee:[-.15,-.4,-.15,-.5,.15,-.5,.15,-.4],collide:function(e,t,n,r,o,s,l){var u=a(i(this.points,n+2*l,r,o)),c=a(i(this.pointsTee,n+2*l,r,o));return Wn(e,t,u)||Wn(e,t,c)},draw:function(e,n,r,a,o){var s=i(this.points,n,r,a),l=i(this.pointsTee,n,r,a);t.arrowShapeImpl(this.name)(e,s,l)}}),s("circle-triangle",{radius:.15,pointsTr:[0,-.15,.15,-.45,-.15,-.45,0,-.15],collide:function(e,t,n,r,o,s,l){var u=o,c=Math.pow(u.x-e,2)+Math.pow(u.y-t,2)<=Math.pow((n+2*l)*this.radius,2),h=a(i(this.points,n+2*l,r,o));return Wn(e,t,h)||c},draw:function(e,n,r,a,o){var s=i(this.pointsTr,n,r,a);t.arrowShapeImpl(this.name)(e,s,a.x,a.y,this.radius*n)},spacing:function(e){return t.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.radius}}),s("triangle-cross",{points:[0,0,.15,-.3,-.15,-.3,0,0],baseCrossLinePts:[-.15,-.4,-.15,-.4,.15,-.4,.15,-.4],crossLinePts:function(e,t){var n=this.baseCrossLinePts.slice(),r=t/e,i=3,a=5;return n[i]=n[i]-r,n[a]=n[a]-r,n},collide:function(e,t,n,r,o,s,l){var u=a(i(this.points,n+2*l,r,o)),c=a(i(this.crossLinePts(n,s),n+2*l,r,o));return Wn(e,t,u)||Wn(e,t,c)},draw:function(e,n,r,a,o){var s=i(this.points,n,r,a),l=i(this.crossLinePts(n,o),n,r,a);t.arrowShapeImpl(this.name)(e,s,l)}}),s("vee",{points:[-.15,-.3,0,0,.15,-.3,0,-.15],gap:function(e){return.525*o(e)}}),s("circle",{radius:.15,collide:function(e,t,n,r,i,a,o){var s=i;return Math.pow(s.x-e,2)+Math.pow(s.y-t,2)<=Math.pow((n+2*o)*this.radius,2)},draw:function(e,n,r,i,a){t.arrowShapeImpl(this.name)(e,i.x,i.y,this.radius*n)},spacing:function(e){return t.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.radius}}),s("tee",{points:[-.15,0,-.15,-.1,.15,-.1,.15,0],spacing:function(e){return 1},gap:function(e){return 1}}),s("square",{points:[-.15,0,.15,0,.15,-.3,-.15,-.3]}),s("diamond",{points:[-.15,-.15,0,-.3,.15,-.15,0,0],gap:function(e){return e.pstyle("width").pfValue*e.pstyle("arrow-scale").value}}),s("chevron",{points:[0,0,-.15,-.15,-.1,-.2,0,-.1,.1,-.2,.15,-.15],gap:function(e){return.95*e.pstyle("width").pfValue*e.pstyle("arrow-scale").value}})}},Qc={projectIntoViewport:function(e,t){var n=this.cy,r=this.findContainerClientCoords(),i=r[0],a=r[1],o=r[4],s=n.pan(),l=n.zoom();return[((e-i)/o-s.x)/l,((t-a)/o-s.y)/l]},findContainerClientCoords:function(){if(this.containerBB)return this.containerBB;var e=this.container,t=e.getBoundingClientRect(),n=this.cy.window().getComputedStyle(e),r=function(e){return parseFloat(n.getPropertyValue(e))},i={left:r("padding-left"),right:r("padding-right"),top:r("padding-top"),bottom:r("padding-bottom")},a={left:r("border-left-width"),right:r("border-right-width"),top:r("border-top-width"),bottom:r("border-bottom-width")},o=e.clientWidth,s=e.clientHeight,l=i.left+i.right,u=i.top+i.bottom,c=a.left+a.right,h=t.width/(o+c),d=o-l,p=s-u,g=t.left+i.left+a.left,f=t.top+i.top+a.top;return this.containerBB=[g,f,d,p,h]},invalidateContainerClientCoordsCache:function(){this.containerBB=null},findNearestElement:function(e,t,n,r){return this.findNearestElements(e,t,n,r)[0]},findNearestElements:function(e,t,n,r){var i,a,o=this,s=this,l=s.getCachedZSortedEles(),u=[],c=s.cy.zoom(),h=s.cy.hasCompoundNodes(),d=(r?24:8)/c,p=(r?8:2)/c,g=(r?8:2)/c,f=1/0;function v(e,t){if(e.isNode()){if(a)return;a=e,u.push(e)}if(e.isEdge()&&(null==t||t<f))if(i){if(i.pstyle("z-compound-depth").value===e.pstyle("z-compound-depth").value&&i.pstyle("z-compound-depth").value===e.pstyle("z-compound-depth").value)for(var n=0;n<u.length;n++)if(u[n].isEdge()){u[n]=e,i=e,f=null!=t?t:f;break}}else u.push(e),i=e,f=null!=t?t:f}function y(n){var r=n.outerWidth()+2*p,i=n.outerHeight()+2*p,a=r/2,l=i/2,u=n.position();if(u.x-a<=e&&e<=u.x+a&&u.y-l<=t&&t<=u.y+l&&s.nodeShapes[o.getNodeShape(n)].checkPoint(e,t,0,r,i,u.x,u.y))return v(n,0),!0}function m(n){var r,i=n._private,a=i.rscratch,l=n.pstyle("width").pfValue,c=n.pstyle("arrow-scale").value,p=l/2+d,g=p*p,f=2*p,m=i.source,b=i.target;if("segments"===a.edgeType||"straight"===a.edgeType||"haystack"===a.edgeType){for(var x=a.allpts,w=0;w+3<x.length;w+=2)if(Xn(e,t,x[w],x[w+1],x[w+2],x[w+3],f)&&g>(r=qn(e,t,x[w],x[w+1],x[w+2],x[w+3])))return v(n,r),!0}else if("bezier"===a.edgeType||"multibezier"===a.edgeType||"self"===a.edgeType||"compound"===a.edgeType)for(x=a.allpts,w=0;w+5<a.allpts.length;w+=4)if(Vn(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5],f)&&g>(r=Hn(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5])))return v(n,r),!0;m=m||i.source,b=b||i.target;var E=o.getArrowWidth(l,c),T=[{name:"source",x:a.arrowStartX,y:a.arrowStartY,angle:a.srcArrowAngle},{name:"target",x:a.arrowEndX,y:a.arrowEndY,angle:a.tgtArrowAngle},{name:"mid-source",x:a.midX,y:a.midY,angle:a.midsrcArrowAngle},{name:"mid-target",x:a.midX,y:a.midY,angle:a.midtgtArrowAngle}];for(w=0;w<T.length;w++){var _=T[w],D=s.arrowShapes[n.pstyle(_.name+"-arrow-shape").value],C=n.pstyle("width").pfValue;if(D.roughCollide(e,t,E,_.angle,{x:_.x,y:_.y},C,d)&&D.collide(e,t,E,_.angle,{x:_.x,y:_.y},C,d))return v(n),!0}h&&u.length>0&&(y(m),y(b))}function b(e,t,n){return Ft(e,t,n)}function x(n,r){var i,a=n._private,o=g;i=r?r+"-":"",n.boundingBox();var s=a.labelBounds[r||"main"],l=n.pstyle(i+"label").value;if("yes"===n.pstyle("text-events").strValue&&l){var u=b(a.rscratch,"labelX",r),c=b(a.rscratch,"labelY",r),h=b(a.rscratch,"labelAngle",r),d=n.pstyle(i+"text-margin-x").pfValue,p=n.pstyle(i+"text-margin-y").pfValue,f=s.x1-o-d,y=s.x2+o-d,m=s.y1-o-p,x=s.y2+o-p;if(h){var w=Math.cos(h),E=Math.sin(h),T=function(e,t){return{x:(e-=u)*w-(t-=c)*E+u,y:e*E+t*w+c}},_=T(f,m),D=T(f,x),C=T(y,m),N=T(y,x),A=[_.x+d,_.y+p,C.x+d,C.y+p,N.x+d,N.y+p,D.x+d,D.y+p];if(Wn(e,t,A))return v(n),!0}else if(Fn(s,e,t))return v(n),!0}}n&&(l=l.interactive);for(var w=l.length-1;w>=0;w--){var E=l[w];E.isNode()?y(E)||x(E):m(E)||x(E)||x(E,"source")||x(E,"target")}return u},getAllInBox:function(e,t,n,r){for(var i=this.getCachedZSortedEles().interactive,a=[],o=Math.min(e,n),s=Math.max(e,n),l=Math.min(t,r),u=Math.max(t,r),c=Ln({x1:e=o,y1:t=l,x2:n=s,y2:r=u}),h=0;h<i.length;h++){var d=i[h];if(d.isNode()){var p=d,g=p.boundingBox({includeNodes:!0,includeEdges:!1,includeLabels:!1});Bn(c,g)&&!Gn(g,c)&&a.push(p)}else{var f=d,v=f._private,y=v.rscratch;if(null!=y.startX&&null!=y.startY&&!Fn(c,y.startX,y.startY))continue;if(null!=y.endX&&null!=y.endY&&!Fn(c,y.endX,y.endY))continue;if("bezier"===y.edgeType||"multibezier"===y.edgeType||"self"===y.edgeType||"compound"===y.edgeType||"segments"===y.edgeType||"haystack"===y.edgeType){for(var m=v.rstyle.bezierPts||v.rstyle.linePts||v.rstyle.haystackPts,b=!0,x=0;x<m.length;x++)if(!zn(c,m[x])){b=!1;break}b&&a.push(f)}else"haystack"!==y.edgeType&&"straight"!==y.edgeType||a.push(f)}}return a}},Jc={calculateArrowAngles:function(e){var t,n,r,i,a,o,s=e._private.rscratch,l="haystack"===s.edgeType,u="bezier"===s.edgeType,c="multibezier"===s.edgeType,h="segments"===s.edgeType,d="compound"===s.edgeType,p="self"===s.edgeType;if(l?(r=s.haystackPts[0],i=s.haystackPts[1],a=s.haystackPts[2],o=s.haystackPts[3]):(r=s.arrowStartX,i=s.arrowStartY,a=s.arrowEndX,o=s.arrowEndY),f=s.midX,v=s.midY,h)t=r-s.segpts[0],n=i-s.segpts[1];else if(c||d||p||u){var g=s.allpts;t=r-Dn(g[0],g[2],g[4],.1),n=i-Dn(g[1],g[3],g[5],.1)}else t=r-f,n=i-v;s.srcArrowAngle=bn(t,n);var f=s.midX,v=s.midY;if(l&&(f=(r+a)/2,v=(i+o)/2),t=a-r,n=o-i,h)if((g=s.allpts).length/2%2==0){var y=(m=g.length/2)-2;t=g[m]-g[y],n=g[m+1]-g[y+1]}else{y=(m=g.length/2-1)-2;var m,b=m+2;t=g[m]-g[y],n=g[m+1]-g[y+1]}else if(c||d||p){var x,w,E,T,g=s.allpts;if(s.ctrlpts.length/2%2==0){var _=2+(D=2+(C=g.length/2-1));x=Dn(g[C],g[D],g[_],0),w=Dn(g[C+1],g[D+1],g[_+1],0),E=Dn(g[C],g[D],g[_],1e-4),T=Dn(g[C+1],g[D+1],g[_+1],1e-4)}else{var D,C;_=2+(D=g.length/2-1),x=Dn(g[C=D-2],g[D],g[_],.4999),w=Dn(g[C+1],g[D+1],g[_+1],.4999),E=Dn(g[C],g[D],g[_],.5),T=Dn(g[C+1],g[D+1],g[_+1],.5)}t=E-x,n=T-w}if(s.midtgtArrowAngle=bn(t,n),s.midDispX=t,s.midDispY=n,t*=-1,n*=-1,h&&((g=s.allpts).length/2%2==0||(t=-(g[b=2+(m=g.length/2-1)]-g[m]),n=-(g[b+1]-g[m+1]))),s.midsrcArrowAngle=bn(t,n),h)t=a-s.segpts[s.segpts.length-2],n=o-s.segpts[s.segpts.length-1];else if(c||d||p||u){var N=(g=s.allpts).length;t=a-Dn(g[N-6],g[N-4],g[N-2],.9),n=o-Dn(g[N-5],g[N-3],g[N-1],.9)}else t=a-f,n=o-v;s.tgtArrowAngle=bn(t,n)}};Jc.getArrowWidth=Jc.getArrowHeight=function(e,t){var n=this.arrowWidthCache=this.arrowWidthCache||{},r=n[e+", "+t];return r||(r=Math.max(Math.pow(13.37*e,.9),29)*t,n[e+", "+t]=r,r)};var eh={};function th(e){var t=[];if(null!=e){for(var n=0;n<e.length;n+=2){var r=e[n],i=e[n+1];t.push({x:r,y:i})}return t}}eh.findMidptPtsEtc=function(e,t){var n,r=t.posPts,i=t.intersectionPts,a=t.vectorNormInverse,s=e.pstyle("source-endpoint"),l=e.pstyle("target-endpoint"),u=null!=s.units&&null!=l.units,c=function(e,t,n,r){var i=r-t,a=n-e,o=Math.sqrt(a*a+i*i);return{x:-i/o,y:a/o}};switch(e.pstyle("edge-distances").value){case"node-position":n=r;break;case"intersection":n=i;break;case"endpoints":if(u){var h=o(this.manualEndptToPx(e.source()[0],s),2),d=h[0],p=h[1],g=o(this.manualEndptToPx(e.target()[0],l),2),f=g[0],v=g[1],y={x1:d,y1:p,x2:f,y2:v};a=c(d,p,f,v),n=y}else Nt("Edge ".concat(e.id()," has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")),n=i}return{midptPts:n,vectorNormInverse:a}},eh.findHaystackPoints=function(e){for(var t=0;t<e.length;t++){var n=e[t],r=n._private,i=r.rscratch;if(!i.haystack){var a=2*Math.random()*Math.PI;i.source={x:Math.cos(a),y:Math.sin(a)},a=2*Math.random()*Math.PI,i.target={x:Math.cos(a),y:Math.sin(a)}}var o=r.source,s=r.target,l=o.position(),u=s.position(),c=o.width(),h=s.width(),d=o.height(),p=s.height(),g=n.pstyle("haystack-radius").value/2;i.haystackPts=i.allpts=[i.source.x*c*g+l.x,i.source.y*d*g+l.y,i.target.x*h*g+u.x,i.target.y*p*g+u.y],i.midX=(i.allpts[0]+i.allpts[2])/2,i.midY=(i.allpts[1]+i.allpts[3])/2,i.edgeType="haystack",i.haystack=!0,this.storeEdgeProjections(n),this.calculateArrowAngles(n),this.recalculateEdgeLabelProjections(n),this.calculateLabelAngles(n)}},eh.findSegmentsPoints=function(e,t){var n=e._private.rscratch,r=e.pstyle("segment-weights"),i=e.pstyle("segment-distances"),a=Math.min(r.pfValue.length,i.pfValue.length);n.edgeType="segments",n.segpts=[];for(var o=0;o<a;o++){var s=r.pfValue[o],l=i.pfValue[o],u=1-s,c=s,h=this.findMidptPtsEtc(e,t),d=h.midptPts,p=h.vectorNormInverse,g={x:d.x1*u+d.x2*c,y:d.y1*u+d.y2*c};n.segpts.push(g.x+p.x*l,g.y+p.y*l)}},eh.findLoopPoints=function(e,t,n,r){var i=e._private.rscratch,a=t.dirCounts,o=t.srcPos,s=e.pstyle("control-point-distances"),l=s?s.pfValue[0]:void 0,u=e.pstyle("loop-direction").pfValue,c=e.pstyle("loop-sweep").pfValue,h=e.pstyle("control-point-step-size").pfValue;i.edgeType="self";var d=n,p=h;r&&(d=0,p=l);var g=u-Math.PI/2,f=g-c/2,v=g+c/2,y=String(u+"_"+c);d=void 0===a[y]?a[y]=0:++a[y],i.ctrlpts=[o.x+1.4*Math.cos(f)*p*(d/3+1),o.y+1.4*Math.sin(f)*p*(d/3+1),o.x+1.4*Math.cos(v)*p*(d/3+1),o.y+1.4*Math.sin(v)*p*(d/3+1)]},eh.findCompoundLoopPoints=function(e,t,n,r){var i=e._private.rscratch;i.edgeType="compound";var a=t.srcPos,o=t.tgtPos,s=t.srcW,l=t.srcH,u=t.tgtW,c=t.tgtH,h=e.pstyle("control-point-step-size").pfValue,d=e.pstyle("control-point-distances"),p=d?d.pfValue[0]:void 0,g=n,f=h;r&&(g=0,f=p);var v=50,y={x:a.x-s/2,y:a.y-l/2},m={x:o.x-u/2,y:o.y-c/2},b={x:Math.min(y.x,m.x),y:Math.min(y.y,m.y)},x=.5,w=Math.max(x,Math.log(.01*s)),E=Math.max(x,Math.log(.01*u));i.ctrlpts=[b.x,b.y-(1+Math.pow(v,1.12)/100)*f*(g/3+1)*w,b.x-(1+Math.pow(v,1.12)/100)*f*(g/3+1)*E,b.y]},eh.findStraightEdgePoints=function(e){e._private.rscratch.edgeType="straight"},eh.findBezierPoints=function(e,t,n,r,i){var a=e._private.rscratch,o=e.pstyle("control-point-step-size").pfValue,s=e.pstyle("control-point-distances"),l=e.pstyle("control-point-weights"),u=s&&l?Math.min(s.value.length,l.value.length):1,c=s?s.pfValue[0]:void 0,h=l.value[0],d=r;a.edgeType=d?"multibezier":"bezier",a.ctrlpts=[];for(var p=0;p<u;p++){var g=(.5-t.eles.length/2+n)*o*(i?-1:1),f=void 0,v=wn(g);d&&(c=s?s.pfValue[p]:o,h=l.value[p]);var y=void 0!==(f=r?c:void 0!==c?v*c:void 0)?f:g,m=1-h,b=h,x=this.findMidptPtsEtc(e,t),w=x.midptPts,E=x.vectorNormInverse,T={x:w.x1*m+w.x2*b,y:w.y1*m+w.y2*b};a.ctrlpts.push(T.x+E.x*y,T.y+E.y*y)}},eh.findTaxiPoints=function(e,t){var n=e._private.rscratch;n.edgeType="segments";var r="vertical",i="horizontal",a="leftward",o="rightward",s="downward",l="upward",u="auto",c=t.posPts,h=t.srcW,d=t.srcH,p=t.tgtW,g=t.tgtH,f="node-position"!==e.pstyle("edge-distances").value,v=e.pstyle("taxi-direction").value,y=v,m=e.pstyle("taxi-turn"),b="%"===m.units,x=m.pfValue,w=x<0,E=e.pstyle("taxi-turn-min-distance").pfValue,T=f?(h+p)/2:0,_=f?(d+g)/2:0,D=c.x2-c.x1,C=c.y2-c.y1,N=function(e,t){return e>0?Math.max(e-t,0):Math.min(e+t,0)},A=N(D,T),L=N(C,_),S=!1;y===u?v=Math.abs(A)>Math.abs(L)?i:r:y===l||y===s?(v=r,S=!0):y!==a&&y!==o||(v=i,S=!0);var O,I=v===r,k=I?L:A,M=I?C:D,P=wn(M),R=!1;S&&(b||w)||!(y===s&&M<0||y===l&&M>0||y===a&&M>0||y===o&&M<0)||(k=(P*=-1)*Math.abs(k),R=!0);var B=function(e){return Math.abs(e)<E||Math.abs(e)>=Math.abs(k)},F=B(O=b?(x<0?1+x:x)*k:(x<0?k:0)+x*P),z=B(Math.abs(k)-Math.abs(O));if(!F&&!z||R)if(I){var G=c.y1+O+(f?d/2*P:0),Y=c.x1,X=c.x2;n.segpts=[Y,G,X,G]}else{var V=c.x1+O+(f?h/2*P:0),U=c.y1,j=c.y2;n.segpts=[V,U,V,j]}else if(I){var H=Math.abs(M)<=d/2,q=Math.abs(D)<=p/2;if(H){var W=(c.x1+c.x2)/2,$=c.y1,K=c.y2;n.segpts=[W,$,W,K]}else if(q){var Z=(c.y1+c.y2)/2,Q=c.x1,J=c.x2;n.segpts=[Q,Z,J,Z]}else n.segpts=[c.x1,c.y2]}else{var ee=Math.abs(M)<=h/2,te=Math.abs(C)<=g/2;if(ee){var ne=(c.y1+c.y2)/2,re=c.x1,ie=c.x2;n.segpts=[re,ne,ie,ne]}else if(te){var ae=(c.x1+c.x2)/2,oe=c.y1,se=c.y2;n.segpts=[ae,oe,ae,se]}else n.segpts=[c.x2,c.y1]}},eh.tryToCorrectInvalidPoints=function(e,t){var n=e._private.rscratch;if("bezier"===n.edgeType){var r=t.srcPos,i=t.tgtPos,a=t.srcW,o=t.srcH,s=t.tgtW,l=t.tgtH,u=t.srcShape,c=t.tgtShape,h=!_(n.startX)||!_(n.startY),d=!_(n.arrowStartX)||!_(n.arrowStartY),p=!_(n.endX)||!_(n.endY),g=!_(n.arrowEndX)||!_(n.arrowEndY),f=this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth*3,v=En({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.startX,y:n.startY}),y=v<f,m=En({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.endX,y:n.endY}),b=m<f,x=!1;if(h||d||y){x=!0;var w={x:n.ctrlpts[0]-r.x,y:n.ctrlpts[1]-r.y},E=Math.sqrt(w.x*w.x+w.y*w.y),T={x:w.x/E,y:w.y/E},D=Math.max(a,o),C={x:n.ctrlpts[0]+2*T.x*D,y:n.ctrlpts[1]+2*T.y*D},N=u.intersectLine(r.x,r.y,a,o,C.x,C.y,0);y?(n.ctrlpts[0]=n.ctrlpts[0]+T.x*(f-v),n.ctrlpts[1]=n.ctrlpts[1]+T.y*(f-v)):(n.ctrlpts[0]=N[0]+T.x*f,n.ctrlpts[1]=N[1]+T.y*f)}if(p||g||b){x=!0;var A={x:n.ctrlpts[0]-i.x,y:n.ctrlpts[1]-i.y},L=Math.sqrt(A.x*A.x+A.y*A.y),S={x:A.x/L,y:A.y/L},O=Math.max(a,o),I={x:n.ctrlpts[0]+2*S.x*O,y:n.ctrlpts[1]+2*S.y*O},k=c.intersectLine(i.x,i.y,s,l,I.x,I.y,0);b?(n.ctrlpts[0]=n.ctrlpts[0]+S.x*(f-m),n.ctrlpts[1]=n.ctrlpts[1]+S.y*(f-m)):(n.ctrlpts[0]=k[0]+S.x*f,n.ctrlpts[1]=k[1]+S.y*f)}x&&this.findEndpoints(e)}},eh.storeAllpts=function(e){var t=e._private.rscratch;if("multibezier"===t.edgeType||"bezier"===t.edgeType||"self"===t.edgeType||"compound"===t.edgeType){t.allpts=[],t.allpts.push(t.startX,t.startY);for(var n=0;n+1<t.ctrlpts.length;n+=2)t.allpts.push(t.ctrlpts[n],t.ctrlpts[n+1]),n+3<t.ctrlpts.length&&t.allpts.push((t.ctrlpts[n]+t.ctrlpts[n+2])/2,(t.ctrlpts[n+1]+t.ctrlpts[n+3])/2);var r,i;t.allpts.push(t.endX,t.endY),t.ctrlpts.length/2%2==0?(r=t.allpts.length/2-1,t.midX=t.allpts[r],t.midY=t.allpts[r+1]):(r=t.allpts.length/2-3,i=.5,t.midX=Dn(t.allpts[r],t.allpts[r+2],t.allpts[r+4],i),t.midY=Dn(t.allpts[r+1],t.allpts[r+3],t.allpts[r+5],i))}else if("straight"===t.edgeType)t.allpts=[t.startX,t.startY,t.endX,t.endY],t.midX=(t.startX+t.endX+t.arrowStartX+t.arrowEndX)/4,t.midY=(t.startY+t.endY+t.arrowStartY+t.arrowEndY)/4;else if("segments"===t.edgeType)if(t.allpts=[],t.allpts.push(t.startX,t.startY),t.allpts.push.apply(t.allpts,t.segpts),t.allpts.push(t.endX,t.endY),t.segpts.length%4==0){var a=t.segpts.length/2,o=a-2;t.midX=(t.segpts[o]+t.segpts[a])/2,t.midY=(t.segpts[o+1]+t.segpts[a+1])/2}else{var s=t.segpts.length/2-1;t.midX=t.segpts[s],t.midY=t.segpts[s+1]}},eh.checkForInvalidEdgeWarning=function(e){var t=e[0]._private.rscratch;t.nodesOverlap||_(t.startX)&&_(t.startY)&&_(t.endX)&&_(t.endY)?t.loggedErr=!1:t.loggedErr||(t.loggedErr=!0,Nt("Edge `"+e.id()+"` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap."))},eh.findEdgeControlPoints=function(e){var t=this;if(e&&0!==e.length){for(var n=this,r=n.cy.hasCompoundNodes(),i={map:new Yt,get:function(e){var t=this.map.get(e[0]);return null!=t?t.get(e[1]):null},set:function(e,t){var n=this.map.get(e[0]);null==n&&(n=new Yt,this.map.set(e[0],n)),n.set(e[1],t)}},a=[],o=[],s=0;s<e.length;s++){var l=e[s],u=l._private,c=l.pstyle("curve-style").value;if(!l.removed()&&l.takesUpSpace())if("haystack"!==c){var h="unbundled-bezier"===c||"segments"===c||"straight"===c||"straight-triangle"===c||"taxi"===c,d="unbundled-bezier"===c||"bezier"===c,p=u.source,g=u.target,f=[p.poolIndex(),g.poolIndex()].sort(),v=i.get(f);null==v&&(v={eles:[]},i.set(f,v),a.push(f)),v.eles.push(l),h&&(v.hasUnbundled=!0),d&&(v.hasBezier=!0)}else o.push(l)}for(var y=function(e){var o=a[e],s=i.get(o),l=void 0;if(!s.hasUnbundled){var u=s.eles[0].parallelEdges().filter((function(e){return e.isBundledBezier()}));Rt(s.eles),u.forEach((function(e){return s.eles.push(e)})),s.eles.sort((function(e,t){return e.poolIndex()-t.poolIndex()}))}var c=s.eles[0],h=c.source(),d=c.target();if(h.poolIndex()>d.poolIndex()){var p=h;h=d,d=p}var g=s.srcPos=h.position(),f=s.tgtPos=d.position(),v=s.srcW=h.outerWidth(),y=s.srcH=h.outerHeight(),m=s.tgtW=d.outerWidth(),b=s.tgtH=d.outerHeight(),x=s.srcShape=n.nodeShapes[t.getNodeShape(h)],w=s.tgtShape=n.nodeShapes[t.getNodeShape(d)];s.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var E=0;E<s.eles.length;E++){var T=s.eles[E],D=T[0]._private.rscratch,C=T.pstyle("curve-style").value,N="unbundled-bezier"===C||"segments"===C||"taxi"===C,A=!h.same(T.source());if(!s.calculatedIntersection&&h!==d&&(s.hasBezier||s.hasUnbundled)){s.calculatedIntersection=!0;var L=x.intersectLine(g.x,g.y,v,y,f.x,f.y,0),S=s.srcIntn=L,O=w.intersectLine(f.x,f.y,m,b,g.x,g.y,0),I=s.tgtIntn=O,k=s.intersectionPts={x1:L[0],x2:O[0],y1:L[1],y2:O[1]},M=s.posPts={x1:g.x,x2:f.x,y1:g.y,y2:f.y},P=O[1]-L[1],R=O[0]-L[0],B=Math.sqrt(R*R+P*P),F=s.vector={x:R,y:P},z=s.vectorNorm={x:F.x/B,y:F.y/B},G={x:-z.y,y:z.x};s.nodesOverlap=!_(B)||w.checkPoint(L[0],L[1],0,m,b,f.x,f.y)||x.checkPoint(O[0],O[1],0,v,y,g.x,g.y),s.vectorNormInverse=G,l={nodesOverlap:s.nodesOverlap,dirCounts:s.dirCounts,calculatedIntersection:!0,hasBezier:s.hasBezier,hasUnbundled:s.hasUnbundled,eles:s.eles,srcPos:f,tgtPos:g,srcW:m,srcH:b,tgtW:v,tgtH:y,srcIntn:I,tgtIntn:S,srcShape:w,tgtShape:x,posPts:{x1:M.x2,y1:M.y2,x2:M.x1,y2:M.y1},intersectionPts:{x1:k.x2,y1:k.y2,x2:k.x1,y2:k.y1},vector:{x:-F.x,y:-F.y},vectorNorm:{x:-z.x,y:-z.y},vectorNormInverse:{x:-G.x,y:-G.y}}}var Y=A?l:s;D.nodesOverlap=Y.nodesOverlap,D.srcIntn=Y.srcIntn,D.tgtIntn=Y.tgtIntn,r&&(h.isParent()||h.isChild()||d.isParent()||d.isChild())&&(h.parents().anySame(d)||d.parents().anySame(h)||h.same(d)&&h.isParent())?t.findCompoundLoopPoints(T,Y,E,N):h===d?t.findLoopPoints(T,Y,E,N):"segments"===C?t.findSegmentsPoints(T,Y):"taxi"===C?t.findTaxiPoints(T,Y):"straight"===C||!N&&s.eles.length%2==1&&E===Math.floor(s.eles.length/2)?t.findStraightEdgePoints(T):t.findBezierPoints(T,Y,E,N,A),t.findEndpoints(T),t.tryToCorrectInvalidPoints(T,Y),t.checkForInvalidEdgeWarning(T),t.storeAllpts(T),t.storeEdgeProjections(T),t.calculateArrowAngles(T),t.recalculateEdgeLabelProjections(T),t.calculateLabelAngles(T)}},m=0;m<a.length;m++)y(m);this.findHaystackPoints(o)}},eh.getSegmentPoints=function(e){var t=e[0]._private.rscratch;if("segments"===t.edgeType)return this.recalculateRenderedStyle(e),th(t.segpts)},eh.getControlPoints=function(e){var t=e[0]._private.rscratch,n=t.edgeType;if("bezier"===n||"multibezier"===n||"self"===n||"compound"===n)return this.recalculateRenderedStyle(e),th(t.ctrlpts)},eh.getEdgeMidpoint=function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),{x:t.midX,y:t.midY}};var nh={manualEndptToPx:function(e,t){var n=this,r=e.position(),i=e.outerWidth(),a=e.outerHeight();if(2===t.value.length){var o=[t.pfValue[0],t.pfValue[1]];return"%"===t.units[0]&&(o[0]=o[0]*i),"%"===t.units[1]&&(o[1]=o[1]*a),o[0]+=r.x,o[1]+=r.y,o}var s=t.pfValue[0];s=-Math.PI/2+s;var l=2*Math.max(i,a),u=[r.x+Math.cos(s)*l,r.y+Math.sin(s)*l];return n.nodeShapes[this.getNodeShape(e)].intersectLine(r.x,r.y,i,a,u[0],u[1],0)},findEndpoints:function(e){var t,n,r,i,a,o=this,s=e.source()[0],l=e.target()[0],u=s.position(),c=l.position(),h=e.pstyle("target-arrow-shape").value,d=e.pstyle("source-arrow-shape").value,p=e.pstyle("target-distance-from-node").pfValue,g=e.pstyle("source-distance-from-node").pfValue,f=e.pstyle("curve-style").value,v=e._private.rscratch,y=v.edgeType,m="self"===y||"compound"===y,b="bezier"===y||"multibezier"===y||m,x="bezier"!==y,w="straight"===y||"segments"===y,E="segments"===y,T=b||x||w,D=m||"taxi"===f,C=e.pstyle("source-endpoint"),N=D?"outside-to-node":C.value,A=e.pstyle("target-endpoint"),L=D?"outside-to-node":A.value;if(v.srcManEndpt=C,v.tgtManEndpt=A,b){var S=[v.ctrlpts[0],v.ctrlpts[1]];n=x?[v.ctrlpts[v.ctrlpts.length-2],v.ctrlpts[v.ctrlpts.length-1]]:S,r=S}else if(w){var O=E?v.segpts.slice(0,2):[c.x,c.y];n=E?v.segpts.slice(v.segpts.length-2):[u.x,u.y],r=O}if("inside-to-node"===L)t=[c.x,c.y];else if(A.units)t=this.manualEndptToPx(l,A);else if("outside-to-line"===L)t=v.tgtIntn;else if("outside-to-node"===L||"outside-to-node-or-label"===L?i=n:"outside-to-line"!==L&&"outside-to-line-or-label"!==L||(i=[u.x,u.y]),t=o.nodeShapes[this.getNodeShape(l)].intersectLine(c.x,c.y,l.outerWidth(),l.outerHeight(),i[0],i[1],0),"outside-to-node-or-label"===L||"outside-to-line-or-label"===L){var I=l._private.rscratch,k=I.labelWidth,M=I.labelHeight,P=I.labelX,R=I.labelY,B=k/2,F=M/2,z=l.pstyle("text-valign").value;"top"===z?R-=F:"bottom"===z&&(R+=F);var G=l.pstyle("text-halign").value;"left"===G?P-=B:"right"===G&&(P+=B);var Y=ir(i[0],i[1],[P-B,R-F,P+B,R-F,P+B,R+F,P-B,R+F],c.x,c.y);if(Y.length>0){var X=u,V=Tn(X,pn(t)),U=Tn(X,pn(Y)),j=V;U<V&&(t=Y,j=U),Y.length>2&&Tn(X,{x:Y[2],y:Y[3]})<j&&(t=[Y[2],Y[3]])}}var H=or(t,n,o.arrowShapes[h].spacing(e)+p),q=or(t,n,o.arrowShapes[h].gap(e)+p);if(v.endX=q[0],v.endY=q[1],v.arrowEndX=H[0],v.arrowEndY=H[1],"inside-to-node"===N)t=[u.x,u.y];else if(C.units)t=this.manualEndptToPx(s,C);else if("outside-to-line"===N)t=v.srcIntn;else if("outside-to-node"===N||"outside-to-node-or-label"===N?a=r:"outside-to-line"!==N&&"outside-to-line-or-label"!==N||(a=[c.x,c.y]),t=o.nodeShapes[this.getNodeShape(s)].intersectLine(u.x,u.y,s.outerWidth(),s.outerHeight(),a[0],a[1],0),"outside-to-node-or-label"===N||"outside-to-line-or-label"===N){var W=s._private.rscratch,$=W.labelWidth,K=W.labelHeight,Z=W.labelX,Q=W.labelY,J=$/2,ee=K/2,te=s.pstyle("text-valign").value;"top"===te?Q-=ee:"bottom"===te&&(Q+=ee);var ne=s.pstyle("text-halign").value;"left"===ne?Z-=J:"right"===ne&&(Z+=J);var re=ir(a[0],a[1],[Z-J,Q-ee,Z+J,Q-ee,Z+J,Q+ee,Z-J,Q+ee],u.x,u.y);if(re.length>0){var ie=c,ae=Tn(ie,pn(t)),oe=Tn(ie,pn(re)),se=ae;oe<ae&&(t=[re[0],re[1]],se=oe),re.length>2&&Tn(ie,{x:re[2],y:re[3]})<se&&(t=[re[2],re[3]])}}var le=or(t,r,o.arrowShapes[d].spacing(e)+g),ue=or(t,r,o.arrowShapes[d].gap(e)+g);v.startX=ue[0],v.startY=ue[1],v.arrowStartX=le[0],v.arrowStartY=le[1],T&&(_(v.startX)&&_(v.startY)&&_(v.endX)&&_(v.endY)?v.badLine=!1:v.badLine=!0)},getSourceEndpoint:function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),"haystack"===t.edgeType?{x:t.haystackPts[0],y:t.haystackPts[1]}:{x:t.arrowStartX,y:t.arrowStartY}},getTargetEndpoint:function(e){var t=e[0]._private.rscratch;return this.recalculateRenderedStyle(e),"haystack"===t.edgeType?{x:t.haystackPts[2],y:t.haystackPts[3]}:{x:t.arrowEndX,y:t.arrowEndY}}},rh={};function ih(e,t,n){for(var r=function(e,t,n,r){return Dn(e,t,n,r)},i=t._private.rstyle.bezierPts,a=0;a<e.bezierProjPcts.length;a++){var o=e.bezierProjPcts[a];i.push({x:r(n[0],n[2],n[4],o),y:r(n[1],n[3],n[5],o)})}}rh.storeEdgeProjections=function(e){var t=e._private,n=t.rscratch,r=n.edgeType;if(t.rstyle.bezierPts=null,t.rstyle.linePts=null,t.rstyle.haystackPts=null,"multibezier"===r||"bezier"===r||"self"===r||"compound"===r){t.rstyle.bezierPts=[];for(var i=0;i+5<n.allpts.length;i+=4)ih(this,e,n.allpts.slice(i,i+6))}else if("segments"===r){var a=t.rstyle.linePts=[];for(i=0;i+1<n.allpts.length;i+=2)a.push({x:n.allpts[i],y:n.allpts[i+1]})}else if("haystack"===r){var o=n.haystackPts;t.rstyle.haystackPts=[{x:o[0],y:o[1]},{x:o[2],y:o[3]}]}t.rstyle.arrowWidth=this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth},rh.recalculateEdgeProjections=function(e){this.findEdgeControlPoints(e)};var ah={recalculateNodeLabelProjection:function(e){var t=e.pstyle("label").strValue;if(!k(t)){var n,r,i=e._private,a=e.width(),o=e.height(),s=e.padding(),l=e.position(),u=e.pstyle("text-halign").strValue,c=e.pstyle("text-valign").strValue,h=i.rscratch,d=i.rstyle;switch(u){case"left":n=l.x-a/2-s;break;case"right":n=l.x+a/2+s;break;default:n=l.x}switch(c){case"top":r=l.y-o/2-s;break;case"bottom":r=l.y+o/2+s;break;default:r=l.y}h.labelX=n,h.labelY=r,d.labelX=n,d.labelY=r,this.calculateLabelAngles(e),this.applyLabelDimensions(e)}}},oh=function(e,t){var n=Math.atan(t/e);return 0===e&&n<0&&(n*=-1),n},sh=function(e,t){var n=t.x-e.x,r=t.y-e.y;return oh(n,r)},lh=function(e,t,n,r){var i=An(0,r-.001,1),a=An(0,r+.001,1),o=Cn(e,t,n,i),s=Cn(e,t,n,a);return sh(o,s)};ah.recalculateEdgeLabelProjections=function(e){var t,n=e._private,r=n.rscratch,i=this,a={mid:e.pstyle("label").strValue,source:e.pstyle("source-label").strValue,target:e.pstyle("target-label").strValue};if(a.mid||a.source||a.target){t={x:r.midX,y:r.midY};var o=function(e,t,r){zt(n.rscratch,e,t,r),zt(n.rstyle,e,t,r)};o("labelX",null,t.x),o("labelY",null,t.y);var s=oh(r.midDispX,r.midDispY);o("labelAutoAngle",null,s);var l=function e(){if(e.cache)return e.cache;for(var t=[],a=0;a+5<r.allpts.length;a+=4){var o={x:r.allpts[a],y:r.allpts[a+1]},s={x:r.allpts[a+2],y:r.allpts[a+3]},l={x:r.allpts[a+4],y:r.allpts[a+5]};t.push({p0:o,p1:s,p2:l,startDist:0,length:0,segments:[]})}var u=n.rstyle.bezierPts,c=i.bezierProjPcts.length;function h(e,t,n,r,i){var a=En(t,n),o=e.segments[e.segments.length-1],s={p0:t,p1:n,t0:r,t1:i,startDist:o?o.startDist+o.length:0,length:a};e.segments.push(s),e.length+=a}for(var d=0;d<t.length;d++){var p=t[d],g=t[d-1];g&&(p.startDist=g.startDist+g.length),h(p,p.p0,u[d*c],0,i.bezierProjPcts[0]);for(var f=0;f<c-1;f++)h(p,u[d*c+f],u[d*c+f+1],i.bezierProjPcts[f],i.bezierProjPcts[f+1]);h(p,u[d*c+c-1],p.p2,i.bezierProjPcts[c-1],1)}return e.cache=t},u=function(n){var i,s="source"===n;if(a[n]){var u=e.pstyle(n+"-text-offset").pfValue;switch(r.edgeType){case"self":case"compound":case"bezier":case"multibezier":for(var c,h=l(),d=0,p=0,g=0;g<h.length;g++){for(var f=h[s?g:h.length-1-g],v=0;v<f.segments.length;v++){var y=f.segments[s?v:f.segments.length-1-v],m=g===h.length-1&&v===f.segments.length-1;if(d=p,(p+=y.length)>=u||m){c={cp:f,segment:y};break}}if(c)break}var b=c.cp,x=c.segment,w=(u-d)/x.length,E=x.t1-x.t0,T=s?x.t0+E*w:x.t1-E*w;T=An(0,T,1),t=Cn(b.p0,b.p1,b.p2,T),i=lh(b.p0,b.p1,b.p2,T);break;case"straight":case"segments":case"haystack":for(var _,D,C,N,A=0,L=r.allpts.length,S=0;S+3<L&&(s?(C={x:r.allpts[S],y:r.allpts[S+1]},N={x:r.allpts[S+2],y:r.allpts[S+3]}):(C={x:r.allpts[L-2-S],y:r.allpts[L-1-S]},N={x:r.allpts[L-4-S],y:r.allpts[L-3-S]}),D=A,!((A+=_=En(C,N))>=u));S+=2);var O=(u-D)/_;O=An(0,O,1),t=Nn(C,N,O),i=sh(C,N)}o("labelX",n,t.x),o("labelY",n,t.y),o("labelAutoAngle",n,i)}};u("source"),u("target"),this.applyLabelDimensions(e)}},ah.applyLabelDimensions=function(e){this.applyPrefixedLabelDimensions(e),e.isEdge()&&(this.applyPrefixedLabelDimensions(e,"source"),this.applyPrefixedLabelDimensions(e,"target"))},ah.applyPrefixedLabelDimensions=function(e,t){var n=e._private,r=this.getLabelText(e,t),i=this.calculateLabelDimensions(e,r),a=e.pstyle("line-height").pfValue,o=e.pstyle("text-wrap").strValue,s=Ft(n.rscratch,"labelWrapCachedLines",t)||[],l="wrap"!==o?1:Math.max(s.length,1),u=i.height/l,c=u*a,h=i.width,d=i.height+(l-1)*(a-1)*u;zt(n.rstyle,"labelWidth",t,h),zt(n.rscratch,"labelWidth",t,h),zt(n.rstyle,"labelHeight",t,d),zt(n.rscratch,"labelHeight",t,d),zt(n.rscratch,"labelLineHeight",t,c)},ah.getLabelText=function(e,t){var n=e._private,r=t?t+"-":"",i=e.pstyle(r+"label").strValue,a=e.pstyle("text-transform").value,o=function(e,r){return r?(zt(n.rscratch,e,t,r),r):Ft(n.rscratch,e,t)};if(!i)return"";"none"==a||("uppercase"==a?i=i.toUpperCase():"lowercase"==a&&(i=i.toLowerCase()));var s=e.pstyle("text-wrap").value;if("wrap"===s){var l=o("labelKey");if(null!=l&&o("labelWrapKey")===l)return o("labelWrapCachedText");for(var u="\u200b",c=i.split("\n"),h=e.pstyle("text-max-width").pfValue,d="anywhere"===e.pstyle("text-overflow-wrap").value,p=[],g=/[\s\u200b]+/,f=d?"":" ",v=0;v<c.length;v++){var y=c[v],m=this.calculateLabelDimensions(e,y).width;if(d){var b=y.split("").join(u);y=b}if(m>h){for(var x=y.split(g),w="",E=0;E<x.length;E++){var T=x[E],_=0===w.length?T:w+f+T;this.calculateLabelDimensions(e,_).width<=h?w+=T+f:(w&&p.push(w),w=T+f)}w.match(/^[\s\u200b]+$/)||p.push(w)}else p.push(y)}o("labelWrapCachedLines",p),i=o("labelWrapCachedText",p.join("\n")),o("labelWrapKey",l)}else if("ellipsis"===s){var D=e.pstyle("text-max-width").pfValue,C="",N="\u2026",A=!1;if(this.calculateLabelDimensions(e,i).width<D)return i;for(var L=0;L<i.length&&!(this.calculateLabelDimensions(e,C+i[L]+N).width>D);L++)C+=i[L],L===i.length-1&&(A=!0);return A||(C+=N),C}return i},ah.getLabelJustification=function(e){var t=e.pstyle("text-justification").strValue,n=e.pstyle("text-halign").strValue;if("auto"!==t)return t;if(!e.isNode())return"center";switch(n){case"left":return"right";case"right":return"left";default:return"center"}},ah.calculateLabelDimensions=function(e,t){var n=this,r=gt(t,e._private.labelDimsKey),i=n.labelDimCache||(n.labelDimCache=[]),a=i[r];if(null!=a)return a;var o=0,s=e.pstyle("font-style").strValue,l=e.pstyle("font-size").pfValue,u=e.pstyle("font-family").strValue,c=e.pstyle("font-weight").strValue,h=this.labelCalcCanvas,d=this.labelCalcCanvasContext;if(!h){h=this.labelCalcCanvas=document.createElement("canvas"),d=this.labelCalcCanvasContext=h.getContext("2d");var p=h.style;p.position="absolute",p.left="-9999px",p.top="-9999px",p.zIndex="-1",p.visibility="hidden",p.pointerEvents="none"}d.font="".concat(s," ").concat(c," ").concat(l,"px ").concat(u);for(var g=0,f=0,v=t.split("\n"),y=0;y<v.length;y++){var m=v[y],b=d.measureText(m),x=Math.ceil(b.width),w=l;g=Math.max(x,g),f+=w}return g+=o,f+=o,i[r]={width:g,height:f}},ah.calculateLabelAngle=function(e,t){var n=e._private.rscratch,r=e.isEdge(),i=t?t+"-":"",a=e.pstyle(i+"text-rotation"),o=a.strValue;return"none"===o?0:r&&"autorotate"===o?n.labelAutoAngle:"autorotate"===o?0:a.pfValue},ah.calculateLabelAngles=function(e){var t=this,n=e.isEdge(),r=e._private.rscratch;r.labelAngle=t.calculateLabelAngle(e),n&&(r.sourceLabelAngle=t.calculateLabelAngle(e,"source"),r.targetLabelAngle=t.calculateLabelAngle(e,"target"))};var uh={},ch=28,hh=!1;uh.getNodeShape=function(e){var t=this,n=e.pstyle("shape").value;if("cutrectangle"===n&&(e.width()<ch||e.height()<ch))return hh||(Nt("The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead"),hh=!0),"rectangle";if(e.isParent())return"rectangle"===n||"roundrectangle"===n||"round-rectangle"===n||"cutrectangle"===n||"cut-rectangle"===n||"barrel"===n?n:"rectangle";if("polygon"===n){var r=e.pstyle("shape-polygon-points").value;return t.nodeShapes.makePolygon(r).name}return n};var dh={registerCalculationListeners:function(){var e=this.cy,t=e.collection(),n=this,r=function(e){var n=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(t.merge(e),n)for(var r=0;r<e.length;r++){var i=e[r]._private.rstyle;i.clean=!1,i.cleanConnected=!1}};n.binder(e).on("bounds.* dirty.*",(function(e){var t=e.target;r(t)})).on("style.* background.*",(function(e){var t=e.target;r(t,!1)}));var i=function(i){if(i){var a=n.onUpdateEleCalcsFns;t.cleanStyle();for(var o=0;o<t.length;o++){var s=t[o],l=s._private.rstyle;s.isNode()&&!l.cleanConnected&&(r(s.connectedEdges()),l.cleanConnected=!0)}if(a)for(var u=0;u<a.length;u++)(0,a[u])(i,t);n.recalculateRenderedStyle(t),t=e.collection()}};n.flushRenderedStyleQueue=function(){i(!0)},n.beforeRender(i,n.beforeRenderPriorities.eleCalcs)},onUpdateEleCalcs:function(e){(this.onUpdateEleCalcsFns=this.onUpdateEleCalcsFns||[]).push(e)},recalculateRenderedStyle:function(e,t){var n=function(e){return e._private.rstyle.cleanConnected},r=[],i=[];if(!this.destroyed){void 0===t&&(t=!0);for(var a=0;a<e.length;a++){var o=e[a],s=o._private,l=s.rstyle;!o.isEdge()||n(o.source())&&n(o.target())||(l.clean=!1),t&&l.clean||o.removed()||"none"!==o.pstyle("display").value&&("nodes"===s.group?i.push(o):r.push(o),l.clean=!0)}for(var u=0;u<i.length;u++){var c=i[u],h=c._private.rstyle,d=c.position();this.recalculateNodeLabelProjection(c),h.nodeX=d.x,h.nodeY=d.y,h.nodeW=c.pstyle("width").pfValue,h.nodeH=c.pstyle("height").pfValue}this.recalculateEdgeProjections(r);for(var p=0;p<r.length;p++){var g=r[p]._private,f=g.rstyle,v=g.rscratch;f.srcX=v.arrowStartX,f.srcY=v.arrowStartY,f.tgtX=v.arrowEndX,f.tgtY=v.arrowEndY,f.midX=v.midX,f.midY=v.midY,f.labelAngle=v.labelAngle,f.sourceLabelAngle=v.sourceLabelAngle,f.targetLabelAngle=v.targetLabelAngle}}}},ph={updateCachedGrabbedEles:function(){var e=this.cachedZSortedEles;if(e){e.drag=[],e.nondrag=[];for(var t=[],n=0;n<e.length;n++){var r=(i=e[n])._private.rscratch;i.grabbed()&&!i.isParent()?t.push(i):r.inDragLayer?e.drag.push(i):e.nondrag.push(i)}for(n=0;n<t.length;n++){var i=t[n];e.drag.push(i)}}},invalidateCachedZSortedEles:function(){this.cachedZSortedEles=null},getCachedZSortedEles:function(e){if(e||!this.cachedZSortedEles){var t=this.cy.mutableElements().toArray();t.sort(Wl),t.interactive=t.filter((function(e){return e.interactive()})),this.cachedZSortedEles=t,this.updateCachedGrabbedEles()}else t=this.cachedZSortedEles;return t}},gh={};[Qc,Jc,eh,nh,rh,ah,uh,dh,ph].forEach((function(e){Q(gh,e)}));var fh={getCachedImage:function(e,t,n){var r=this,i=r.imageCache=r.imageCache||{},a=i[e];if(a)return a.image.complete||a.image.addEventListener("load",n),a.image;var o=(a=i[e]=i[e]||{}).image=new Image;o.addEventListener("load",n),o.addEventListener("error",(function(){o.error=!0}));var s="data:";return e.substring(0,s.length).toLowerCase()===s||(t="null"===t?null:t,o.crossOrigin=t),o.src=e,o}},vh={registerBinding:function(e,t,n,r){var i=Array.prototype.slice.apply(arguments,[1]),a=this.binder(e);return a.on.apply(a,i)},binder:function(e){var t=this,n=t.cy.window(),r=e===n||e===n.document||e===n.document.body||M(e);if(null==t.supportsPassiveEvents){var i=!1;try{var a=Object.defineProperty({},"passive",{get:function(){return i=!0,!0}});n.addEventListener("test",null,a)}catch(s){}t.supportsPassiveEvents=i}var o=function(n,i,a){var o=Array.prototype.slice.call(arguments);return r&&t.supportsPassiveEvents&&(o[2]={capture:null!=a&&a,passive:!1,once:!1}),t.bindings.push({target:e,args:o}),(e.addEventListener||e.on).apply(e,o),this};return{on:o,addEventListener:o,addListener:o,bind:o}},nodeIsDraggable:function(e){return e&&e.isNode()&&!e.locked()&&e.grabbable()},nodeIsGrabbable:function(e){return this.nodeIsDraggable(e)&&e.interactive()},load:function(){var e=this,t=e.cy.window(),n=function(e){return e.selected()},r=function(t,n,r,i){null==t&&(t=e.cy);for(var a=0;a<n.length;a++){var o=n[a];t.emit({originalEvent:r,type:o,position:i})}},i=function(e){return e.shiftKey||e.metaKey||e.ctrlKey},a=function(t,n){var r=!0;if(e.cy.hasCompoundNodes()&&t&&t.pannable()){for(var i=0;n&&i<n.length;i++)if((t=n[i]).isNode()&&t.isParent()&&!t.pannable()){r=!1;break}}else r=!0;return r},o=function(e){e[0]._private.grabbed=!0},s=function(e){e[0]._private.grabbed=!1},l=function(e){e[0]._private.rscratch.inDragLayer=!0},u=function(e){e[0]._private.rscratch.inDragLayer=!1},c=function(e){e[0]._private.rscratch.isGrabTarget=!0},h=function(e){e[0]._private.rscratch.isGrabTarget=!1},d=function(e,t){var n=t.addToList;n.has(e)||!e.grabbable()||e.locked()||(n.merge(e),o(e))},p=function(e,t){if(e.cy().hasCompoundNodes()&&(null!=t.inDragLayer||null!=t.addToList)){var n=e.descendants();t.inDragLayer&&(n.forEach(l),n.connectedEdges().forEach(l)),t.addToList&&d(n,t)}},g=function(t,n){n=n||{};var r=t.cy().hasCompoundNodes();n.inDragLayer&&(t.forEach(l),t.neighborhood().stdFilter((function(e){return!r||e.isEdge()})).forEach(l)),n.addToList&&t.forEach((function(e){d(e,n)})),p(t,n),y(t,{inDragLayer:n.inDragLayer}),e.updateCachedGrabbedEles()},f=g,v=function(t){t&&(e.getCachedZSortedEles().forEach((function(e){s(e),u(e),h(e)})),e.updateCachedGrabbedEles())},y=function(e,t){if((null!=t.inDragLayer||null!=t.addToList)&&e.cy().hasCompoundNodes()){var n=e.ancestors().orphans();if(!n.same(e)){var r=n.descendants().spawnSelf().merge(n).unmerge(e).unmerge(e.descendants()),i=r.connectedEdges();t.inDragLayer&&(i.forEach(l),r.forEach(l)),t.addToList&&r.forEach((function(e){d(e,t)}))}}},m=function(){null!=document.activeElement&&null!=document.activeElement.blur&&document.activeElement.blur()},b="undefined"!=typeof MutationObserver,x="undefined"!=typeof ResizeObserver;b?(e.removeObserver=new MutationObserver((function(t){for(var n=0;n<t.length;n++){var r=t[n].removedNodes;if(r)for(var i=0;i<r.length;i++)if(r[i]===e.container){e.destroy();break}}})),e.container.parentNode&&e.removeObserver.observe(e.container.parentNode,{childList:!0})):e.registerBinding(e.container,"DOMNodeRemoved",(function(t){e.destroy()}));var w=Qe((function(){e.cy.resize()}),100);b&&(e.styleObserver=new MutationObserver(w),e.styleObserver.observe(e.container,{attributes:!0})),e.registerBinding(t,"resize",w),x&&(e.resizeObserver=new ResizeObserver(w),e.resizeObserver.observe(e.container));var E=function(e,t){for(;null!=e;)t(e),e=e.parentNode},T=function(){e.invalidateContainerClientCoordsCache()};E(e.container,(function(t){e.registerBinding(t,"transitionend",T),e.registerBinding(t,"animationend",T),e.registerBinding(t,"scroll",T)})),e.registerBinding(e.container,"contextmenu",(function(e){e.preventDefault()}));var D,C,N,A=function(){return 0!==e.selection[4]},L=function(t){for(var n=e.findContainerClientCoords(),r=n[0],i=n[1],a=n[2],o=n[3],s=t.touches?t.touches:[t],l=!1,u=0;u<s.length;u++){var c=s[u];if(r<=c.clientX&&c.clientX<=r+a&&i<=c.clientY&&c.clientY<=i+o){l=!0;break}}if(!l)return!1;for(var h=e.container,d=t.target.parentNode,p=!1;d;){if(d===h){p=!0;break}d=d.parentNode}return!!p};e.registerBinding(e.container,"mousedown",(function(t){if(L(t)){t.preventDefault(),m(),e.hoverData.capture=!0,e.hoverData.which=t.which;var n=e.cy,i=[t.clientX,t.clientY],a=e.projectIntoViewport(i[0],i[1]),o=e.selection,s=e.findNearestElements(a[0],a[1],!0,!1),l=s[0],u=e.dragData.possibleDragElements;e.hoverData.mdownPos=a,e.hoverData.mdownGPos=i;var h=function(){e.hoverData.tapholdCancelled=!1,clearTimeout(e.hoverData.tapholdTimeout),e.hoverData.tapholdTimeout=setTimeout((function(){if(!e.hoverData.tapholdCancelled){var r=e.hoverData.down;r?r.emit({originalEvent:t,type:"taphold",position:{x:a[0],y:a[1]}}):n.emit({originalEvent:t,type:"taphold",position:{x:a[0],y:a[1]}})}}),e.tapholdDuration)};if(3==t.which){e.hoverData.cxtStarted=!0;var d={originalEvent:t,type:"cxttapstart",position:{x:a[0],y:a[1]}};l?(l.activate(),l.emit(d),e.hoverData.down=l):n.emit(d),e.hoverData.downTime=(new Date).getTime(),e.hoverData.cxtDragged=!1}else if(1==t.which){if(l&&l.activate(),null!=l&&e.nodeIsGrabbable(l)){var p=function(e){return{originalEvent:t,type:e,position:{x:a[0],y:a[1]}}},v=function(e){e.emit(p("grab"))};if(c(l),l.selected()){u=e.dragData.possibleDragElements=n.collection();var y=n.$((function(t){return t.isNode()&&t.selected()&&e.nodeIsGrabbable(t)}));g(y,{addToList:u}),l.emit(p("grabon")),y.forEach(v)}else u=e.dragData.possibleDragElements=n.collection(),f(l,{addToList:u}),l.emit(p("grabon")).emit(p("grab"));e.redrawHint("eles",!0),e.redrawHint("drag",!0)}e.hoverData.down=l,e.hoverData.downs=s,e.hoverData.downTime=(new Date).getTime(),r(l,["mousedown","tapstart","vmousedown"],t,{x:a[0],y:a[1]}),null==l?(o[4]=1,e.data.bgActivePosistion={x:a[0],y:a[1]},e.redrawHint("select",!0),e.redraw()):l.pannable()&&(o[4]=1),h()}o[0]=o[2]=a[0],o[1]=o[3]=a[1]}}),!1),e.registerBinding(t,"mousemove",(function(t){if(e.hoverData.capture||L(t)){var n=!1,o=e.cy,s=o.zoom(),l=[t.clientX,t.clientY],u=e.projectIntoViewport(l[0],l[1]),c=e.hoverData.mdownPos,h=e.hoverData.mdownGPos,d=e.selection,p=null;e.hoverData.draggingEles||e.hoverData.dragging||e.hoverData.selecting||(p=e.findNearestElement(u[0],u[1],!0,!1));var f,y=e.hoverData.last,m=e.hoverData.down,b=[u[0]-d[2],u[1]-d[3]],x=e.dragData.possibleDragElements;if(h){var w=l[0]-h[0],E=w*w,T=l[1]-h[1],D=E+T*T;e.hoverData.isOverThresholdDrag=f=D>=e.desktopTapThreshold2}var C=i(t);f&&(e.hoverData.tapholdCancelled=!0);var N=function(){var t=e.hoverData.dragDelta=e.hoverData.dragDelta||[];0===t.length?(t.push(b[0]),t.push(b[1])):(t[0]+=b[0],t[1]+=b[1])};n=!0,r(p,["mousemove","vmousemove","tapdrag"],t,{x:u[0],y:u[1]});var A=function(){e.data.bgActivePosistion=void 0,e.hoverData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:u[0],y:u[1]}}),d[4]=1,e.hoverData.selecting=!0,e.redrawHint("select",!0),e.redraw()};if(3===e.hoverData.which){if(f){var S={originalEvent:t,type:"cxtdrag",position:{x:u[0],y:u[1]}};m?m.emit(S):o.emit(S),e.hoverData.cxtDragged=!0,e.hoverData.cxtOver&&p===e.hoverData.cxtOver||(e.hoverData.cxtOver&&e.hoverData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:u[0],y:u[1]}}),e.hoverData.cxtOver=p,p&&p.emit({originalEvent:t,type:"cxtdragover",position:{x:u[0],y:u[1]}}))}}else if(e.hoverData.dragging){if(n=!0,o.panningEnabled()&&o.userPanningEnabled()){var O;if(e.hoverData.justStartedPan){var I=e.hoverData.mdownPos;O={x:(u[0]-I[0])*s,y:(u[1]-I[1])*s},e.hoverData.justStartedPan=!1}else O={x:b[0]*s,y:b[1]*s};o.panBy(O),o.emit("dragpan"),e.hoverData.dragged=!0}u=e.projectIntoViewport(t.clientX,t.clientY)}else if(1!=d[4]||null!=m&&!m.pannable()){if(m&&m.pannable()&&m.active()&&m.unactivate(),m&&m.grabbed()||p==y||(y&&r(y,["mouseout","tapdragout"],t,{x:u[0],y:u[1]}),p&&r(p,["mouseover","tapdragover"],t,{x:u[0],y:u[1]}),e.hoverData.last=p),m)if(f){if(o.boxSelectionEnabled()&&C)m&&m.grabbed()&&(v(x),m.emit("freeon"),x.emit("free"),e.dragData.didDrag&&(m.emit("dragfreeon"),x.emit("dragfree"))),A();else if(m&&m.grabbed()&&e.nodeIsDraggable(m)){var k=!e.dragData.didDrag;k&&e.redrawHint("eles",!0),e.dragData.didDrag=!0,e.hoverData.draggingEles||g(x,{inDragLayer:!0});var M={x:0,y:0};if(_(b[0])&&_(b[1])&&(M.x+=b[0],M.y+=b[1],k)){var P=e.hoverData.dragDelta;P&&_(P[0])&&_(P[1])&&(M.x+=P[0],M.y+=P[1])}e.hoverData.draggingEles=!0,x.silentShift(M).emit("position drag"),e.redrawHint("drag",!0),e.redraw()}}else N();n=!0}else f&&(e.hoverData.dragging||!o.boxSelectionEnabled()||!C&&o.panningEnabled()&&o.userPanningEnabled()?!e.hoverData.selecting&&o.panningEnabled()&&o.userPanningEnabled()&&a(m,e.hoverData.downs)&&(e.hoverData.dragging=!0,e.hoverData.justStartedPan=!0,d[4]=0,e.data.bgActivePosistion=pn(c),e.redrawHint("select",!0),e.redraw()):A(),m&&m.pannable()&&m.active()&&m.unactivate());return d[2]=u[0],d[3]=u[1],n?(t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),!1):void 0}}),!1),e.registerBinding(t,"mouseup",(function(t){if(e.hoverData.capture){e.hoverData.capture=!1;var a=e.cy,o=e.projectIntoViewport(t.clientX,t.clientY),s=e.selection,l=e.findNearestElement(o[0],o[1],!0,!1),u=e.dragData.possibleDragElements,c=e.hoverData.down,h=i(t);if(e.data.bgActivePosistion&&(e.redrawHint("select",!0),e.redraw()),e.hoverData.tapholdCancelled=!0,e.data.bgActivePosistion=void 0,c&&c.unactivate(),3===e.hoverData.which){var d={originalEvent:t,type:"cxttapend",position:{x:o[0],y:o[1]}};if(c?c.emit(d):a.emit(d),!e.hoverData.cxtDragged){var p={originalEvent:t,type:"cxttap",position:{x:o[0],y:o[1]}};c?c.emit(p):a.emit(p)}e.hoverData.cxtDragged=!1,e.hoverData.which=null}else if(1===e.hoverData.which){if(r(l,["mouseup","tapend","vmouseup"],t,{x:o[0],y:o[1]}),e.dragData.didDrag||e.hoverData.dragged||e.hoverData.selecting||e.hoverData.isOverThresholdDrag||(r(c,["click","tap","vclick"],t,{x:o[0],y:o[1]}),C=!1,t.timeStamp-N<=a.multiClickDebounceTime()?(D&&clearTimeout(D),C=!0,N=null,r(c,["dblclick","dbltap","vdblclick"],t,{x:o[0],y:o[1]})):(D=setTimeout((function(){C||r(c,["oneclick","onetap","voneclick"],t,{x:o[0],y:o[1]})}),a.multiClickDebounceTime()),N=t.timeStamp)),null!=c||e.dragData.didDrag||e.hoverData.selecting||e.hoverData.dragged||i(t)||(a.$(n).unselect(["tapunselect"]),u.length>0&&e.redrawHint("eles",!0),e.dragData.possibleDragElements=u=a.collection()),l!=c||e.dragData.didDrag||e.hoverData.selecting||null!=l&&l._private.selectable&&(e.hoverData.dragging||("additive"===a.selectionType()||h?l.selected()?l.unselect(["tapunselect"]):l.select(["tapselect"]):h||(a.$(n).unmerge(l).unselect(["tapunselect"]),l.select(["tapselect"]))),e.redrawHint("eles",!0)),e.hoverData.selecting){var g=a.collection(e.getAllInBox(s[0],s[1],s[2],s[3]));e.redrawHint("select",!0),g.length>0&&e.redrawHint("eles",!0),a.emit({type:"boxend",originalEvent:t,position:{x:o[0],y:o[1]}});var f=function(e){return e.selectable()&&!e.selected()};"additive"===a.selectionType()||h||a.$(n).unmerge(g).unselect(),g.emit("box").stdFilter(f).select().emit("boxselect"),e.redraw()}if(e.hoverData.dragging&&(e.hoverData.dragging=!1,e.redrawHint("select",!0),e.redrawHint("eles",!0),e.redraw()),!s[4]){e.redrawHint("drag",!0),e.redrawHint("eles",!0);var y=c&&c.grabbed();v(u),y&&(c.emit("freeon"),u.emit("free"),e.dragData.didDrag&&(c.emit("dragfreeon"),u.emit("dragfree")))}}s[4]=0,e.hoverData.down=null,e.hoverData.cxtStarted=!1,e.hoverData.draggingEles=!1,e.hoverData.selecting=!1,e.hoverData.isOverThresholdDrag=!1,e.dragData.didDrag=!1,e.hoverData.dragged=!1,e.hoverData.dragDelta=[],e.hoverData.mdownPos=null,e.hoverData.mdownGPos=null}}),!1);var S,O,I,k,M,P,R,B,F,z,G,Y,X,V=function(t){if(!e.scrollingPage){var n=e.cy,r=n.zoom(),i=n.pan(),a=e.projectIntoViewport(t.clientX,t.clientY),o=[a[0]*r+i.x,a[1]*r+i.y];if(e.hoverData.draggingEles||e.hoverData.dragging||e.hoverData.cxtStarted||A())t.preventDefault();else if(n.panningEnabled()&&n.userPanningEnabled()&&n.zoomingEnabled()&&n.userZoomingEnabled()){var s;t.preventDefault(),e.data.wheelZooming=!0,clearTimeout(e.data.wheelTimeout),e.data.wheelTimeout=setTimeout((function(){e.data.wheelZooming=!1,e.redrawHint("eles",!0),e.redraw()}),150),s=null!=t.deltaY?t.deltaY/-250:null!=t.wheelDeltaY?t.wheelDeltaY/1e3:t.wheelDelta/1e3,s*=e.wheelSensitivity,1===t.deltaMode&&(s*=33);var l=n.zoom()*Math.pow(10,s);"gesturechange"===t.type&&(l=e.gestureStartZoom*t.scale),n.zoom({level:l,renderedPosition:{x:o[0],y:o[1]}}),n.emit("gesturechange"===t.type?"pinchzoom":"scrollzoom")}}};e.registerBinding(e.container,"wheel",V,!0),e.registerBinding(t,"scroll",(function(t){e.scrollingPage=!0,clearTimeout(e.scrollingPageTimeout),e.scrollingPageTimeout=setTimeout((function(){e.scrollingPage=!1}),250)}),!0),e.registerBinding(e.container,"gesturestart",(function(t){e.gestureStartZoom=e.cy.zoom(),e.hasTouchStarted||t.preventDefault()}),!0),e.registerBinding(e.container,"gesturechange",(function(t){e.hasTouchStarted||V(t)}),!0),e.registerBinding(e.container,"mouseout",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseout",position:{x:n[0],y:n[1]}})}),!1),e.registerBinding(e.container,"mouseover",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseover",position:{x:n[0],y:n[1]}})}),!1);var U,j,H,q,W,$,K,Z=function(e,t,n,r){return Math.sqrt((n-e)*(n-e)+(r-t)*(r-t))},Q=function(e,t,n,r){return(n-e)*(n-e)+(r-t)*(r-t)};if(e.registerBinding(e.container,"touchstart",U=function(t){if(e.hasTouchStarted=!0,L(t)){m(),e.touchData.capture=!0,e.data.bgActivePosistion=void 0;var n=e.cy,i=e.touchData.now,a=e.touchData.earlier;if(t.touches[0]){var o=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);i[0]=o[0],i[1]=o[1]}if(t.touches[1]&&(o=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY),i[2]=o[0],i[3]=o[1]),t.touches[2]&&(o=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY),i[4]=o[0],i[5]=o[1]),t.touches[1]){e.touchData.singleTouchMoved=!0,v(e.dragData.touchDragEles);var s=e.findContainerClientCoords();F=s[0],z=s[1],G=s[2],Y=s[3],S=t.touches[0].clientX-F,O=t.touches[0].clientY-z,I=t.touches[1].clientX-F,k=t.touches[1].clientY-z,X=0<=S&&S<=G&&0<=I&&I<=G&&0<=O&&O<=Y&&0<=k&&k<=Y;var l=n.pan(),u=n.zoom();M=Z(S,O,I,k),P=Q(S,O,I,k),B=[((R=[(S+I)/2,(O+k)/2])[0]-l.x)/u,(R[1]-l.y)/u];var h=200;if(P<h*h&&!t.touches[2]){var d=e.findNearestElement(i[0],i[1],!0,!0),p=e.findNearestElement(i[2],i[3],!0,!0);return d&&d.isNode()?(d.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start=d):p&&p.isNode()?(p.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start=p):n.emit({originalEvent:t,type:"cxttapstart",position:{x:i[0],y:i[1]}}),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!0,e.touchData.cxtDragged=!1,e.data.bgActivePosistion=void 0,void e.redraw()}}if(t.touches[2])n.boxSelectionEnabled()&&t.preventDefault();else if(t.touches[1]);else if(t.touches[0]){var y=e.findNearestElements(i[0],i[1],!0,!0),b=y[0];if(null!=b&&(b.activate(),e.touchData.start=b,e.touchData.starts=y,e.nodeIsGrabbable(b))){var x=e.dragData.touchDragEles=n.collection(),w=null;e.redrawHint("eles",!0),e.redrawHint("drag",!0),b.selected()?(w=n.$((function(t){return t.selected()&&e.nodeIsGrabbable(t)})),g(w,{addToList:x})):f(b,{addToList:x}),c(b);var E=function(e){return{originalEvent:t,type:e,position:{x:i[0],y:i[1]}}};b.emit(E("grabon")),w?w.forEach((function(e){e.emit(E("grab"))})):b.emit(E("grab"))}r(b,["touchstart","tapstart","vmousedown"],t,{x:i[0],y:i[1]}),null==b&&(e.data.bgActivePosistion={x:o[0],y:o[1]},e.redrawHint("select",!0),e.redraw()),e.touchData.singleTouchMoved=!1,e.touchData.singleTouchStartTime=+new Date,clearTimeout(e.touchData.tapholdTimeout),e.touchData.tapholdTimeout=setTimeout((function(){!1!==e.touchData.singleTouchMoved||e.pinching||e.touchData.selecting||r(e.touchData.start,["taphold"],t,{x:i[0],y:i[1]})}),e.tapholdDuration)}if(t.touches.length>=1){for(var T=e.touchData.startPosition=[null,null,null,null,null,null],_=0;_<i.length;_++)T[_]=a[_]=i[_];var D=t.touches[0];e.touchData.startGPosition=[D.clientX,D.clientY]}}},!1),e.registerBinding(window,"touchmove",j=function(t){var n=e.touchData.capture;if(n||L(t)){var i=e.selection,o=e.cy,s=e.touchData.now,l=e.touchData.earlier,u=o.zoom();if(t.touches[0]){var c=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);s[0]=c[0],s[1]=c[1]}t.touches[1]&&(c=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY),s[2]=c[0],s[3]=c[1]),t.touches[2]&&(c=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY),s[4]=c[0],s[5]=c[1]);var h,d=e.touchData.startGPosition;if(n&&t.touches[0]&&d){for(var p=[],f=0;f<s.length;f++)p[f]=s[f]-l[f];var y=t.touches[0].clientX-d[0],m=y*y,b=t.touches[0].clientY-d[1];h=m+b*b>=e.touchTapThreshold2}if(n&&e.touchData.cxt){t.preventDefault();var x=t.touches[0].clientX-F,w=t.touches[0].clientY-z,E=t.touches[1].clientX-F,T=t.touches[1].clientY-z,D=Q(x,w,E,T),C=150,N=1.5;if(D/P>=N*N||D>=C*C){e.touchData.cxt=!1,e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var A={originalEvent:t,type:"cxttapend",position:{x:s[0],y:s[1]}};e.touchData.start?(e.touchData.start.unactivate().emit(A),e.touchData.start=null):o.emit(A)}}if(n&&e.touchData.cxt){A={originalEvent:t,type:"cxtdrag",position:{x:s[0],y:s[1]}},e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.touchData.start?e.touchData.start.emit(A):o.emit(A),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxtDragged=!0;var R=e.findNearestElement(s[0],s[1],!0,!0);e.touchData.cxtOver&&R===e.touchData.cxtOver||(e.touchData.cxtOver&&e.touchData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:s[0],y:s[1]}}),e.touchData.cxtOver=R,R&&R.emit({originalEvent:t,type:"cxtdragover",position:{x:s[0],y:s[1]}}))}else if(n&&t.touches[2]&&o.boxSelectionEnabled())t.preventDefault(),e.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,e.touchData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:s[0],y:s[1]}}),e.touchData.selecting=!0,e.touchData.didSelect=!0,i[4]=1,i&&0!==i.length&&void 0!==i[0]?(i[2]=(s[0]+s[2]+s[4])/3,i[3]=(s[1]+s[3]+s[5])/3):(i[0]=(s[0]+s[2]+s[4])/3,i[1]=(s[1]+s[3]+s[5])/3,i[2]=(s[0]+s[2]+s[4])/3+1,i[3]=(s[1]+s[3]+s[5])/3+1),e.redrawHint("select",!0),e.redraw();else if(n&&t.touches[1]&&!e.touchData.didSelect&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){if(t.preventDefault(),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),ne=e.dragData.touchDragEles){e.redrawHint("drag",!0);for(var G=0;G<ne.length;G++){var Y=ne[G]._private;Y.grabbed=!1,Y.rscratch.inDragLayer=!1}}var V=e.touchData.start,U=(x=t.touches[0].clientX-F,w=t.touches[0].clientY-z,E=t.touches[1].clientX-F,T=t.touches[1].clientY-z,Z(x,w,E,T)),j=U/M;if(X){var H=(x-S+(E-I))/2,q=(w-O+(T-k))/2,W=o.zoom(),$=W*j,K=o.pan(),J=B[0]*W+K.x,ee=B[1]*W+K.y,te={x:-$/W*(J-K.x-H)+J,y:-$/W*(ee-K.y-q)+ee};if(V&&V.active()){var ne=e.dragData.touchDragEles;v(ne),e.redrawHint("drag",!0),e.redrawHint("eles",!0),V.unactivate().emit("freeon"),ne.emit("free"),e.dragData.didDrag&&(V.emit("dragfreeon"),ne.emit("dragfree"))}o.viewport({zoom:$,pan:te,cancelOnFailedZoom:!0}),o.emit("pinchzoom"),M=U,S=x,O=w,I=E,k=T,e.pinching=!0}t.touches[0]&&(c=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY),s[0]=c[0],s[1]=c[1]),t.touches[1]&&(c=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY),s[2]=c[0],s[3]=c[1]),t.touches[2]&&(c=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY),s[4]=c[0],s[5]=c[1])}else if(t.touches[0]&&!e.touchData.didSelect){var re=e.touchData.start,ie=e.touchData.last;if(e.hoverData.draggingEles||e.swipePanning||(R=e.findNearestElement(s[0],s[1],!0,!0)),n&&null!=re&&t.preventDefault(),n&&null!=re&&e.nodeIsDraggable(re))if(h){ne=e.dragData.touchDragEles;var ae=!e.dragData.didDrag;ae&&g(ne,{inDragLayer:!0}),e.dragData.didDrag=!0;var oe={x:0,y:0};_(p[0])&&_(p[1])&&(oe.x+=p[0],oe.y+=p[1],ae&&(e.redrawHint("eles",!0),(se=e.touchData.dragDelta)&&_(se[0])&&_(se[1])&&(oe.x+=se[0],oe.y+=se[1]))),e.hoverData.draggingEles=!0,ne.silentShift(oe).emit("position drag"),e.redrawHint("drag",!0),e.touchData.startPosition[0]==l[0]&&e.touchData.startPosition[1]==l[1]&&e.redrawHint("eles",!0),e.redraw()}else{var se;0===(se=e.touchData.dragDelta=e.touchData.dragDelta||[]).length?(se.push(p[0]),se.push(p[1])):(se[0]+=p[0],se[1]+=p[1])}if(r(re||R,["touchmove","tapdrag","vmousemove"],t,{x:s[0],y:s[1]}),re&&re.grabbed()||R==ie||(ie&&ie.emit({originalEvent:t,type:"tapdragout",position:{x:s[0],y:s[1]}}),R&&R.emit({originalEvent:t,type:"tapdragover",position:{x:s[0],y:s[1]}})),e.touchData.last=R,n)for(G=0;G<s.length;G++)s[G]&&e.touchData.startPosition[G]&&h&&(e.touchData.singleTouchMoved=!0);n&&(null==re||re.pannable())&&o.panningEnabled()&&o.userPanningEnabled()&&(a(re,e.touchData.starts)&&(t.preventDefault(),e.data.bgActivePosistion||(e.data.bgActivePosistion=pn(e.touchData.startPosition)),e.swipePanning?(o.panBy({x:p[0]*u,y:p[1]*u}),o.emit("dragpan")):h&&(e.swipePanning=!0,o.panBy({x:y*u,y:b*u}),o.emit("dragpan"),re&&(re.unactivate(),e.redrawHint("select",!0),e.touchData.start=null))),c=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY),s[0]=c[0],s[1]=c[1])}for(f=0;f<s.length;f++)l[f]=s[f];n&&t.touches.length>0&&!e.hoverData.draggingEles&&!e.swipePanning&&null!=e.data.bgActivePosistion&&(e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.redraw())}},!1),e.registerBinding(t,"touchcancel",H=function(t){var n=e.touchData.start;e.touchData.capture=!1,n&&n.unactivate()}),e.registerBinding(t,"touchend",q=function(t){var i=e.touchData.start;if(e.touchData.capture){0===t.touches.length&&(e.touchData.capture=!1),t.preventDefault();var a=e.selection;e.swipePanning=!1,e.hoverData.draggingEles=!1;var o,s=e.cy,l=s.zoom(),u=e.touchData.now,c=e.touchData.earlier;if(t.touches[0]){var h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);u[0]=h[0],u[1]=h[1]}if(t.touches[1]&&(h=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY),u[2]=h[0],u[3]=h[1]),t.touches[2]&&(h=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY),u[4]=h[0],u[5]=h[1]),i&&i.unactivate(),e.touchData.cxt){if(o={originalEvent:t,type:"cxttapend",position:{x:u[0],y:u[1]}},i?i.emit(o):s.emit(o),!e.touchData.cxtDragged){var d={originalEvent:t,type:"cxttap",position:{x:u[0],y:u[1]}};i?i.emit(d):s.emit(d)}return e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!1,e.touchData.start=null,void e.redraw()}if(!t.touches[2]&&s.boxSelectionEnabled()&&e.touchData.selecting){e.touchData.selecting=!1;var p=s.collection(e.getAllInBox(a[0],a[1],a[2],a[3]));a[0]=void 0,a[1]=void 0,a[2]=void 0,a[3]=void 0,a[4]=0,e.redrawHint("select",!0),s.emit({type:"boxend",originalEvent:t,position:{x:u[0],y:u[1]}});var g=function(e){return e.selectable()&&!e.selected()};p.emit("box").stdFilter(g).select().emit("boxselect"),p.nonempty()&&e.redrawHint("eles",!0),e.redraw()}if(null!=i&&i.unactivate(),t.touches[2])e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);else if(t.touches[1]);else if(t.touches[0]);else if(!t.touches[0]){e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var f=e.dragData.touchDragEles;if(null!=i){var y=i._private.grabbed;v(f),e.redrawHint("drag",!0),e.redrawHint("eles",!0),y&&(i.emit("freeon"),f.emit("free"),e.dragData.didDrag&&(i.emit("dragfreeon"),f.emit("dragfree"))),r(i,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]}),i.unactivate(),e.touchData.start=null}else{var m=e.findNearestElement(u[0],u[1],!0,!0);r(m,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]})}var b=e.touchData.startPosition[0]-u[0],x=b*b,w=e.touchData.startPosition[1]-u[1],E=(x+w*w)*l*l;e.touchData.singleTouchMoved||(i||s.$(":selected").unselect(["tapunselect"]),r(i,["tap","vclick"],t,{x:u[0],y:u[1]}),W=!1,t.timeStamp-K<=s.multiClickDebounceTime()?($&&clearTimeout($),W=!0,K=null,r(i,["dbltap","vdblclick"],t,{x:u[0],y:u[1]})):($=setTimeout((function(){W||r(i,["onetap","voneclick"],t,{x:u[0],y:u[1]})}),s.multiClickDebounceTime()),K=t.timeStamp)),null!=i&&!e.dragData.didDrag&&i._private.selectable&&E<e.touchTapThreshold2&&!e.pinching&&("single"===s.selectionType()?(s.$(n).unmerge(i).unselect(["tapunselect"]),i.select(["tapselect"])):i.selected()?i.unselect(["tapunselect"]):i.select(["tapselect"]),e.redrawHint("eles",!0)),e.touchData.singleTouchMoved=!0}for(var T=0;T<u.length;T++)c[T]=u[T];e.dragData.didDrag=!1,0===t.touches.length&&(e.touchData.dragDelta=[],e.touchData.startPosition=[null,null,null,null,null,null],e.touchData.startGPosition=null,e.touchData.didSelect=!1),t.touches.length<2&&(1===t.touches.length&&(e.touchData.startGPosition=[t.touches[0].clientX,t.touches[0].clientY]),e.pinching=!1,e.redrawHint("eles",!0),e.redraw())}},!1),"undefined"==typeof TouchEvent){var J=[],ee=function(e){return{clientX:e.clientX,clientY:e.clientY,force:1,identifier:e.pointerId,pageX:e.pageX,pageY:e.pageY,radiusX:e.width/2,radiusY:e.height/2,screenX:e.screenX,screenY:e.screenY,target:e.target}},te=function(e){return{event:e,touch:ee(e)}},ne=function(e){J.push(te(e))},re=function(e){for(var t=0;t<J.length;t++)if(J[t].event.pointerId===e.pointerId)return void J.splice(t,1)},ie=function(e){var t=J.filter((function(t){return t.event.pointerId===e.pointerId}))[0];t.event=e,t.touch=ee(e)},ae=function(e){e.touches=J.map((function(e){return e.touch}))},oe=function(e){return"mouse"===e.pointerType||4===e.pointerType};e.registerBinding(e.container,"pointerdown",(function(e){oe(e)||(e.preventDefault(),ne(e),ae(e),U(e))})),e.registerBinding(e.container,"pointerup",(function(e){oe(e)||(re(e),ae(e),q(e))})),e.registerBinding(e.container,"pointercancel",(function(e){oe(e)||(re(e),ae(e),H(e))})),e.registerBinding(e.container,"pointermove",(function(e){oe(e)||(e.preventDefault(),ie(e),ae(e),j(e))}))}}},yh={generatePolygon:function(e,t){return this.nodeShapes[e]={renderer:this,name:e,points:t,draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl("polygon",e,t,n,r,i,this.points)},intersectLine:function(e,t,n,r,i,a,o){return ir(i,a,this.points,e,t,n/2,r/2,o)},checkPoint:function(e,t,n,r,i,a,o){return $n(e,t,this.points,a,o,r,i,[0,-1],n)}}},generateEllipse:function(){return this.nodeShapes.ellipse={renderer:this,name:"ellipse",draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){return Jn(i,a,e,t,n/2+o,r/2+o)},checkPoint:function(e,t,n,r,i,a,o){return er(e,t,r,i,a,o,n)}}},generateRoundPolygon:function(e,t){for(var n=new Array(2*t.length),r=0;r<t.length/2;r++){var i=2*r,a=void 0;a=r<t.length/2-1?2*(r+1):0,n[4*r]=t[i],n[4*r+1]=t[i+1];var o=t[a]-t[i],s=t[a+1]-t[i+1],l=Math.sqrt(o*o+s*s);n[4*r+2]=o/l,n[4*r+3]=s/l}return this.nodeShapes[e]={renderer:this,name:e,points:n,draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl("round-polygon",e,t,n,r,i,this.points)},intersectLine:function(e,t,n,r,i,a,o){return ar(i,a,this.points,e,t,n,r)},checkPoint:function(e,t,n,r,i,a,o){return Kn(e,t,this.points,a,o,r,i)}}},generateRoundRectangle:function(){return this.nodeShapes["round-rectangle"]=this.nodeShapes.roundrectangle={renderer:this,name:"round-rectangle",points:sr(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){return Yn(i,a,e,t,n,r,o)},checkPoint:function(e,t,n,r,i,a,o){var s=cr(r,i),l=2*s;return!!($n(e,t,this.points,a,o,r,i-l,[0,-1],n)||$n(e,t,this.points,a,o,r-l,i,[0,-1],n)||er(e,t,l,l,a-r/2+s,o-i/2+s,n)||er(e,t,l,l,a+r/2-s,o-i/2+s,n)||er(e,t,l,l,a+r/2-s,o+i/2-s,n)||er(e,t,l,l,a-r/2+s,o+i/2-s,n))}}},generateCutRectangle:function(){return this.nodeShapes["cut-rectangle"]=this.nodeShapes.cutrectangle={renderer:this,name:"cut-rectangle",cornerLength:dr(),points:sr(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},generateCutTrianglePts:function(e,t,n,r){var i=this.cornerLength,a=t/2,o=e/2,s=n-o,l=n+o,u=r-a,c=r+a;return{topLeft:[s,u+i,s+i,u,s+i,u+i],topRight:[l-i,u,l,u+i,l-i,u+i],bottomRight:[l,c-i,l-i,c,l-i,c-i],bottomLeft:[s+i,c,s,c-i,s+i,c-i]}},intersectLine:function(e,t,n,r,i,a,o){var s=this.generateCutTrianglePts(n+2*o,r+2*o,e,t),l=[].concat.apply([],[s.topLeft.splice(0,4),s.topRight.splice(0,4),s.bottomRight.splice(0,4),s.bottomLeft.splice(0,4)]);return ir(i,a,l,e,t)},checkPoint:function(e,t,n,r,i,a,o){if($n(e,t,this.points,a,o,r,i-2*this.cornerLength,[0,-1],n))return!0;if($n(e,t,this.points,a,o,r-2*this.cornerLength,i,[0,-1],n))return!0;var s=this.generateCutTrianglePts(r,i,a,o);return Wn(e,t,s.topLeft)||Wn(e,t,s.topRight)||Wn(e,t,s.bottomRight)||Wn(e,t,s.bottomLeft)}}},generateBarrel:function(){return this.nodeShapes.barrel={renderer:this,name:"barrel",points:sr(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){var s=.15,l=.5,u=.85,c=this.generateBarrelBezierPts(n+2*o,r+2*o,e,t),h=function(e){var t=Cn({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},s),n=Cn({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},l),r=Cn({x:e[0],y:e[1]},{x:e[2],y:e[3]},{x:e[4],y:e[5]},u);return[e[0],e[1],t.x,t.y,n.x,n.y,r.x,r.y,e[4],e[5]]},d=[].concat(h(c.topLeft),h(c.topRight),h(c.bottomRight),h(c.bottomLeft));return ir(i,a,d,e,t)},generateBarrelBezierPts:function(e,t,n,r){var i=t/2,a=e/2,o=n-a,s=n+a,l=r-i,u=r+i,c=gr(e,t),h=c.heightOffset,d=c.widthOffset,p=c.ctrlPtOffsetPct*e,g={topLeft:[o,l+h,o+p,l,o+d,l],topRight:[s-d,l,s-p,l,s,l+h],bottomRight:[s,u-h,s-p,u,s-d,u],bottomLeft:[o+d,u,o+p,u,o,u-h]};return g.topLeft.isTop=!0,g.topRight.isTop=!0,g.bottomLeft.isBottom=!0,g.bottomRight.isBottom=!0,g},checkPoint:function(e,t,n,r,i,a,o){var s=gr(r,i),l=s.heightOffset,u=s.widthOffset;if($n(e,t,this.points,a,o,r,i-2*l,[0,-1],n))return!0;if($n(e,t,this.points,a,o,r-2*u,i,[0,-1],n))return!0;for(var c=this.generateBarrelBezierPts(r,i,a,o),h=function(e,t,n){var r=n[4],i=n[2],a=n[0],o=n[5],s=n[1],l=Math.min(r,a),u=Math.max(r,a),c=Math.min(o,s),h=Math.max(o,s);if(l<=e&&e<=u&&c<=t&&t<=h){var d=pr(r,i,a),p=Un(d[0],d[1],d[2],e).filter((function(e){return 0<=e&&e<=1}));if(p.length>0)return p[0]}return null},d=Object.keys(c),p=0;p<d.length;p++){var g=c[d[p]],f=h(e,t,g);if(null!=f){var v=g[5],y=g[3],m=g[1],b=Dn(v,y,m,f);if(g.isTop&&b<=t)return!0;if(g.isBottom&&t<=b)return!0}}return!1}}},generateBottomRoundrectangle:function(){return this.nodeShapes["bottom-round-rectangle"]=this.nodeShapes.bottomroundrectangle={renderer:this,name:"bottom-round-rectangle",points:sr(4,0),draw:function(e,t,n,r,i){this.renderer.nodeShapeImpl(this.name,e,t,n,r,i)},intersectLine:function(e,t,n,r,i,a,o){var s=t-(r/2+o),l=rr(i,a,e,t,e-(n/2+o),s,e+(n/2+o),s,!1);return l.length>0?l:Yn(i,a,e,t,n,r,o)},checkPoint:function(e,t,n,r,i,a,o){var s=cr(r,i),l=2*s;if($n(e,t,this.points,a,o,r,i-l,[0,-1],n))return!0;if($n(e,t,this.points,a,o,r-l,i,[0,-1],n))return!0;var u=r/2+2*n,c=i/2+2*n;return!!Wn(e,t,[a-u,o-c,a-u,o,a+u,o,a+u,o-c])||!!er(e,t,l,l,a+r/2-s,o+i/2-s,n)||!!er(e,t,l,l,a-r/2+s,o+i/2-s,n)}}},registerNodeShapes:function(){var e=this.nodeShapes={},t=this;this.generateEllipse(),this.generatePolygon("triangle",sr(3,0)),this.generateRoundPolygon("round-triangle",sr(3,0)),this.generatePolygon("rectangle",sr(4,0)),e.square=e.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();var n=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",n),this.generateRoundPolygon("round-diamond",n),this.generatePolygon("pentagon",sr(5,0)),this.generateRoundPolygon("round-pentagon",sr(5,0)),this.generatePolygon("hexagon",sr(6,0)),this.generateRoundPolygon("round-hexagon",sr(6,0)),this.generatePolygon("heptagon",sr(7,0)),this.generateRoundPolygon("round-heptagon",sr(7,0)),this.generatePolygon("octagon",sr(8,0)),this.generateRoundPolygon("round-octagon",sr(8,0));var r=new Array(20),i=ur(5,0),a=ur(5,Math.PI/5),o=.5*(3-Math.sqrt(5));o*=1.57;for(var s=0;s<a.length/2;s++)a[2*s]*=o,a[2*s+1]*=o;for(s=0;s<5;s++)r[4*s]=i[2*s],r[4*s+1]=i[2*s+1],r[4*s+2]=a[2*s],r[4*s+3]=a[2*s+1];r=lr(r),this.generatePolygon("star",r),this.generatePolygon("vee",[-1,-1,0,-.333,1,-1,0,1]),this.generatePolygon("rhomboid",[-1,-1,.333,-1,1,1,-.333,1]),this.generatePolygon("right-rhomboid",[-.333,-1,1,-1,.333,1,-1,1]),this.nodeShapes.concavehexagon=this.generatePolygon("concave-hexagon",[-1,-.95,-.75,0,-1,.95,1,.95,.75,0,1,-.95]);var l=[-1,-1,.25,-1,1,0,.25,1,-1,1];this.generatePolygon("tag",l),this.generateRoundPolygon("round-tag",l),e.makePolygon=function(e){var n,r="polygon-"+e.join("$");return(n=this[r])?n:t.generatePolygon(r,e)}}},mh={timeToRender:function(){return this.redrawTotalTime/this.redrawCount},redraw:function(e){e=e||kt();var t=this;void 0===t.averageRedrawTime&&(t.averageRedrawTime=0),void 0===t.lastRedrawTime&&(t.lastRedrawTime=0),void 0===t.lastDrawTime&&(t.lastDrawTime=0),t.requestedFrame=!0,t.renderOptions=e},beforeRender:function(e,t){if(!this.destroyed){null==t&&Dt("Priority is not optional for beforeRender");var n=this.beforeRenderCallbacks;n.push({fn:e,priority:t}),n.sort((function(e,t){return t.priority-e.priority}))}}},bh=function(e,t,n){for(var r=e.beforeRenderCallbacks,i=0;i<r.length;i++)r[i].fn(t,n)};mh.startRenderLoop=function(){var e=this,t=e.cy;if(!e.renderLoopStarted){e.renderLoopStarted=!0;var n=function n(r){if(!e.destroyed){if(t.batching());else if(e.requestedFrame&&!e.skipFrame){bh(e,!0,r);var i=rt();e.render(e.renderOptions);var a=e.lastDrawTime=rt();void 0===e.averageRedrawTime&&(e.averageRedrawTime=a-i),void 0===e.redrawCount&&(e.redrawCount=0),e.redrawCount++,void 0===e.redrawTotalTime&&(e.redrawTotalTime=0);var o=a-i;e.redrawTotalTime+=o,e.lastRedrawTime=o,e.averageRedrawTime=e.averageRedrawTime/2+o/2,e.requestedFrame=!1}else bh(e,!1,r);e.skipFrame=!1,nt(n)}};nt(n)}};var xh=function(e){this.init(e)},wh=xh.prototype;wh.clientFunctions=["redrawHint","render","renderTo","matchCanvasSize","nodeShapeImpl","arrowShapeImpl"],wh.init=function(e){var t=this;t.options=e,t.cy=e.cy;var n=t.container=e.cy.container(),r=t.cy.window();if(r){var i=r.document,a=i.head,o="__________cytoscape_stylesheet",s="__________cytoscape_container",l=null!=i.getElementById(o);if(n.className.indexOf(s)<0&&(n.className=(n.className||"")+" "+s),!l){var u=i.createElement("style");u.id=o,u.textContent="."+s+" { position: relative; }",a.insertBefore(u,a.children[0])}"static"===r.getComputedStyle(n).getPropertyValue("position")&&Nt("A Cytoscape container has style position:static and so can not use UI extensions properly")}t.selection=[void 0,void 0,void 0,void 0,0],t.bezierProjPcts=[.05,.225,.4,.5,.6,.775,.95],t.hoverData={down:null,last:null,downTime:null,triggerMode:null,dragging:!1,initialPan:[null,null],capture:!1},t.dragData={possibleDragElements:[]},t.touchData={start:null,capture:!1,startPosition:[null,null,null,null,null,null],singleTouchStartTime:null,singleTouchMoved:!0,now:[null,null,null,null,null,null],earlier:[null,null,null,null,null,null]},t.redraws=0,t.showFps=e.showFps,t.debug=e.debug,t.hideEdgesOnViewport=e.hideEdgesOnViewport,t.textureOnViewport=e.textureOnViewport,t.wheelSensitivity=e.wheelSensitivity,t.motionBlurEnabled=e.motionBlur,t.forcedPixelRatio=_(e.pixelRatio)?e.pixelRatio:null,t.motionBlur=e.motionBlur,t.motionBlurOpacity=e.motionBlurOpacity,t.motionBlurTransparency=1-t.motionBlurOpacity,t.motionBlurPxRatio=1,t.mbPxRBlurry=1,t.minMbLowQualFrames=4,t.fullQualityMb=!1,t.clearedForMotionBlur=[],t.desktopTapThreshold=e.desktopTapThreshold,t.desktopTapThreshold2=e.desktopTapThreshold*e.desktopTapThreshold,t.touchTapThreshold=e.touchTapThreshold,t.touchTapThreshold2=e.touchTapThreshold*e.touchTapThreshold,t.tapholdDuration=500,t.bindings=[],t.beforeRenderCallbacks=[],t.beforeRenderPriorities={animations:400,eleCalcs:300,eleTxrDeq:200,lyrTxrDeq:150,lyrTxrSkip:100},t.registerNodeShapes(),t.registerArrowShapes(),t.registerCalculationListeners()},wh.notify=function(e,t){var n=this,r=n.cy;this.destroyed||("init"!==e?"destroy"!==e?(("add"===e||"remove"===e||"move"===e&&r.hasCompoundNodes()||"load"===e||"zorder"===e||"mount"===e)&&n.invalidateCachedZSortedEles(),"viewport"===e&&n.redrawHint("select",!0),"load"!==e&&"resize"!==e&&"mount"!==e||(n.invalidateContainerClientCoordsCache(),n.matchCanvasSize(n.container)),n.redrawHint("eles",!0),n.redrawHint("drag",!0),this.startRenderLoop(),this.redraw()):n.destroy():n.load())},wh.destroy=function(){var e=this;e.destroyed=!0,e.cy.stopAnimationLoop();for(var t=0;t<e.bindings.length;t++){var n=e.bindings[t],r=n.target;(r.off||r.removeEventListener).apply(r,n.args)}if(e.bindings=[],e.beforeRenderCallbacks=[],e.onUpdateEleCalcsFns=[],e.removeObserver&&e.removeObserver.disconnect(),e.styleObserver&&e.styleObserver.disconnect(),e.resizeObserver&&e.resizeObserver.disconnect(),e.labelCalcDiv)try{document.body.removeChild(e.labelCalcDiv)}catch(i){}},wh.isHeadless=function(){return!1},[Zc,gh,fh,vh,yh,mh].forEach((function(e){Q(wh,e)}));var Eh=1e3/60,Th={setupDequeueing:function(e){return function(){var t=this,n=this.renderer;if(!t.dequeueingSetup){t.dequeueingSetup=!0;var r=Qe((function(){n.redrawHint("eles",!0),n.redrawHint("drag",!0),n.redraw()}),e.deqRedrawThreshold),i=function(i,a){var o=rt(),s=n.averageRedrawTime,l=n.lastRedrawTime,u=[],c=n.cy.extent(),h=n.getPixelRatio();for(i||n.flushRenderedStyleQueue();;){var d=rt(),p=d-o,g=d-a;if(l<Eh){var f=Eh-(i?s:0);if(g>=e.deqFastCost*f)break}else if(i){if(p>=e.deqCost*l||p>=e.deqAvgCost*s)break}else if(g>=e.deqNoDrawCost*Eh)break;var v=e.deq(t,h,c);if(!(v.length>0))break;for(var y=0;y<v.length;y++)u.push(v[y])}u.length>0&&(e.onDeqd(t,u),!i&&e.shouldRedraw(t,u,h,c)&&r())},a=e.priority||_t;n.beforeRender(i,a(t))}}}},_h=function(){function e(n){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Et;t(this,e),this.idsByKey=new Yt,this.keyForId=new Yt,this.cachesByLvl=new Yt,this.lvls=[],this.getKey=n,this.doesEleInvalidateKey=r}return i(e,[{key:"getIdsFor",value:function(e){null==e&&Dt("Can not get id list for null key");var t=this.idsByKey,n=this.idsByKey.get(e);return n||(n=new Ut,t.set(e,n)),n}},{key:"addIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).add(t)}},{key:"deleteIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).delete(t)}},{key:"getNumberOfIdsForKey",value:function(e){return null==e?0:this.getIdsFor(e).size}},{key:"updateKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t),r=this.getKey(e);this.deleteIdForKey(n,t),this.addIdForKey(r,t),this.keyForId.set(t,r)}},{key:"deleteKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteIdForKey(n,t),this.keyForId.delete(t)}},{key:"keyHasChangedFor",value:function(e){var t=e.id();return this.keyForId.get(t)!==this.getKey(e)}},{key:"isInvalid",value:function(e){return this.keyHasChangedFor(e)||this.doesEleInvalidateKey(e)}},{key:"getCachesAt",value:function(e){var t=this.cachesByLvl,n=this.lvls,r=t.get(e);return r||(r=new Yt,t.set(e,r),n.push(e)),r}},{key:"getCache",value:function(e,t){return this.getCachesAt(t).get(e)}},{key:"get",value:function(e,t){var n=this.getKey(e),r=this.getCache(n,t);return null!=r&&this.updateKeyMappingFor(e),r}},{key:"getForCachedKey",value:function(e,t){var n=this.keyForId.get(e.id());return this.getCache(n,t)}},{key:"hasCache",value:function(e,t){return this.getCachesAt(t).has(e)}},{key:"has",value:function(e,t){var n=this.getKey(e);return this.hasCache(n,t)}},{key:"setCache",value:function(e,t,n){n.key=e,this.getCachesAt(t).set(e,n)}},{key:"set",value:function(e,t,n){var r=this.getKey(e);this.setCache(r,t,n),this.updateKeyMappingFor(e)}},{key:"deleteCache",value:function(e,t){this.getCachesAt(t).delete(e)}},{key:"delete",value:function(e,t){var n=this.getKey(e);this.deleteCache(n,t)}},{key:"invalidateKey",value:function(e){var t=this;this.lvls.forEach((function(n){return t.deleteCache(e,n)}))}},{key:"invalidate",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteKeyMappingFor(e);var r=this.doesEleInvalidateKey(e);return r&&this.invalidateKey(n),r||0===this.getNumberOfIdsForKey(n)}}]),e}(),Dh=25,Ch=50,Nh=-4,Ah=3,Lh=7.99,Sh=8,Oh=1024,Ih=1024,kh=1024,Mh=.2,Ph=.8,Rh=10,Bh=.15,Fh=.1,zh=.9,Gh=.9,Yh=100,Xh=1,Vh={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},Uh=Mt({getKey:null,doesEleInvalidateKey:Et,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:wt,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),jh=function(e,t){var n=this;n.renderer=e,n.onDequeues=[];var r=Uh(t);Q(n,r),n.lookup=new _h(r.getKey,r.doesEleInvalidateKey),n.setupDequeueing()},Hh=jh.prototype;Hh.reasons=Vh,Hh.getTextureQueue=function(e){var t=this;return t.eleImgCaches=t.eleImgCaches||{},t.eleImgCaches[e]=t.eleImgCaches[e]||[]},Hh.getRetiredTextureQueue=function(e){var t=this,n=t.eleImgCaches.retired=t.eleImgCaches.retired||{};return n[e]=n[e]||[]},Hh.getElementQueue=function(){var e=this;return e.eleCacheQueue=e.eleCacheQueue||new $t((function(e,t){return t.reqs-e.reqs}))},Hh.getElementKeyToQueue=function(){var e=this;return e.eleKeyToCacheQueue=e.eleKeyToCacheQueue||{}},Hh.getElement=function(e,t,n,r,i){var a=this,o=this.renderer,s=o.cy.zoom(),l=this.lookup;if(!t||0===t.w||0===t.h||isNaN(t.w)||isNaN(t.h)||!e.visible()||e.removed())return null;if(!a.allowEdgeTxrCaching&&e.isEdge()||!a.allowParentTxrCaching&&e.isParent())return null;if(null==r&&(r=Math.ceil(xn(s*n))),r<Nh)r=Nh;else if(s>=Lh||r>Ah)return null;var u=Math.pow(2,r),c=t.h*u,h=t.w*u,d=o.eleTextBiggerThanMin(e,u);if(!this.isVisible(e,d))return null;var p,g=l.get(e,r);if(g&&g.invalidated&&(g.invalidated=!1,g.texture.invalidatedWidth-=g.width),g)return g;if(p=c<=Dh?Dh:c<=Ch?Ch:Math.ceil(c/Ch)*Ch,c>kh||h>Ih)return null;var f=a.getTextureQueue(p),v=f[f.length-2],y=function(){return a.recycleTexture(p,h)||a.addTexture(p,h)};v||(v=f[f.length-1]),v||(v=y()),v.width-v.usedWidth<h&&(v=y());for(var m,b=function(e){return e&&e.scaledLabelShown===d},x=i&&i===Vh.dequeue,w=i&&i===Vh.highQuality,E=i&&i===Vh.downscale,T=r+1;T<=Ah;T++){var _=l.get(e,T);if(_){m=_;break}}var D=m&&m.level===r+1?m:null,C=function(){v.context.drawImage(D.texture.canvas,D.x,0,D.width,D.height,v.usedWidth,0,h,c)};if(v.context.setTransform(1,0,0,1,0,0),v.context.clearRect(v.usedWidth,0,h,p),b(D))C();else if(b(m)){if(!w)return a.queueElement(e,m.level-1),m;for(var N=m.level;N>r;N--)D=a.getElement(e,t,n,N,Vh.downscale);C()}else{var A;if(!x&&!w&&!E)for(var L=r-1;L>=Nh;L--){var S=l.get(e,L);if(S){A=S;break}}if(b(A))return a.queueElement(e,r),A;v.context.translate(v.usedWidth,0),v.context.scale(u,u),this.drawElement(v.context,e,t,d,!1),v.context.scale(1/u,1/u),v.context.translate(-v.usedWidth,0)}return g={x:v.usedWidth,texture:v,level:r,scale:u,width:h,height:c,scaledLabelShown:d},v.usedWidth+=Math.ceil(h+Sh),v.eleCaches.push(g),l.set(e,r,g),a.checkTextureFullness(v),g},Hh.invalidateElements=function(e){for(var t=0;t<e.length;t++)this.invalidateElement(e[t])},Hh.invalidateElement=function(e){var t=this,n=t.lookup,r=[];if(n.isInvalid(e)){for(var i=Nh;i<=Ah;i++){var a=n.getForCachedKey(e,i);a&&r.push(a)}if(n.invalidate(e))for(var o=0;o<r.length;o++){var s=r[o],l=s.texture;l.invalidatedWidth+=s.width,s.invalidated=!0,t.checkTextureUtility(l)}t.removeFromQueue(e)}},Hh.checkTextureUtility=function(e){e.invalidatedWidth>=Mh*e.width&&this.retireTexture(e)},Hh.checkTextureFullness=function(e){var t=this.getTextureQueue(e.height);e.usedWidth/e.width>Ph&&e.fullnessChecks>=Rh?Pt(t,e):e.fullnessChecks++},Hh.retireTexture=function(e){var t=this,n=e.height,r=t.getTextureQueue(n),i=this.lookup;Pt(r,e),e.retired=!0;for(var a=e.eleCaches,o=0;o<a.length;o++){var s=a[o];i.deleteCache(s.key,s.level)}Rt(a),t.getRetiredTextureQueue(n).push(e)},Hh.addTexture=function(e,t){var n=this,r={};return n.getTextureQueue(e).push(r),r.eleCaches=[],r.height=e,r.width=Math.max(Oh,t),r.usedWidth=0,r.invalidatedWidth=0,r.fullnessChecks=0,r.canvas=n.renderer.makeOffscreenCanvas(r.width,r.height),r.context=r.canvas.getContext("2d"),r},Hh.recycleTexture=function(e,t){for(var n=this,r=n.getTextureQueue(e),i=n.getRetiredTextureQueue(e),a=0;a<i.length;a++){var o=i[a];if(o.width>=t)return o.retired=!1,o.usedWidth=0,o.invalidatedWidth=0,o.fullnessChecks=0,Rt(o.eleCaches),o.context.setTransform(1,0,0,1,0,0),o.context.clearRect(0,0,o.width,o.height),Pt(i,o),r.push(o),o}},Hh.queueElement=function(e,t){var n=this,r=n.getElementQueue(),i=n.getElementKeyToQueue(),a=this.getKey(e),o=i[a];if(o)o.level=Math.max(o.level,t),o.eles.merge(e),o.reqs++,r.updateItem(o);else{var s={eles:e.spawn().merge(e),level:t,reqs:1,key:a};r.push(s),i[a]=s}},Hh.dequeue=function(e){for(var t=this,n=t.getElementQueue(),r=t.getElementKeyToQueue(),i=[],a=t.lookup,o=0;o<Xh&&n.size()>0;o++){var s=n.pop(),l=s.key,u=s.eles[0],c=a.hasCache(u,s.level);if(r[l]=null,!c){i.push(s);var h=t.getBoundingBox(u);t.getElement(u,h,e,s.level,Vh.dequeue)}}return i},Hh.removeFromQueue=function(e){var t=this,n=t.getElementQueue(),r=t.getElementKeyToQueue(),i=this.getKey(e),a=r[i];null!=a&&(1===a.eles.length?(a.reqs=xt,n.updateItem(a),n.pop(),r[i]=null):a.eles.unmerge(e))},Hh.onDequeue=function(e){this.onDequeues.push(e)},Hh.offDequeue=function(e){Pt(this.onDequeues,e)},Hh.setupDequeueing=Th.setupDequeueing({deqRedrawThreshold:Yh,deqCost:Bh,deqAvgCost:Fh,deqNoDrawCost:zh,deqFastCost:Gh,deq:function(e,t,n){return e.dequeue(t,n)},onDeqd:function(e,t){for(var n=0;n<e.onDequeues.length;n++)(0,e.onDequeues[n])(t)},shouldRedraw:function(e,t,n,r){for(var i=0;i<t.length;i++)for(var a=t[i].eles,o=0;o<a.length;o++){var s=a[o].boundingBox();if(Bn(s,r))return!0}return!1},priority:function(e){return e.renderer.beforeRenderPriorities.eleTxrDeq}});var qh=1,Wh=-4,$h=2,Kh=3.99,Zh=50,Qh=50,Jh=.15,ed=.1,td=.9,nd=.9,rd=1,id=250,ad=16e6,od=!0,sd=function(e){var t=this,n=t.renderer=e,r=n.cy;t.layersByLevel={},t.firstGet=!0,t.lastInvalidationTime=rt()-2*id,t.skipping=!1,t.eleTxrDeqs=r.collection(),t.scheduleElementRefinement=Qe((function(){t.refineElementTextures(t.eleTxrDeqs),t.eleTxrDeqs.unmerge(t.eleTxrDeqs)}),Qh),n.beforeRender((function(e,n){n-t.lastInvalidationTime<=id?t.skipping=!0:t.skipping=!1}),n.beforeRenderPriorities.lyrTxrSkip);var i=function(e,t){return t.reqs-e.reqs};t.layersQueue=new $t(i),t.setupDequeueing()},ld=sd.prototype,ud=0,cd=Math.pow(2,53)-1;ld.makeLayer=function(e,t){var n=Math.pow(2,t),r=Math.ceil(e.w*n),i=Math.ceil(e.h*n),a=this.renderer.makeOffscreenCanvas(r,i),o={id:ud=++ud%cd,bb:e,level:t,width:r,height:i,canvas:a,context:a.getContext("2d"),eles:[],elesQueue:[],reqs:0},s=o.context,l=-o.bb.x1,u=-o.bb.y1;return s.scale(n,n),s.translate(l,u),o},ld.getLayers=function(e,t,n){var r=this,i=r.renderer.cy.zoom(),a=r.firstGet;if(r.firstGet=!1,null==n)if((n=Math.ceil(xn(i*t)))<Wh)n=Wh;else if(i>=Kh||n>$h)return null;r.validateLayersElesOrdering(n,e);var o,s,l=r.layersByLevel,u=Math.pow(2,n),c=l[n]=l[n]||[],h=function(){var t=function(t){if(r.validateLayersElesOrdering(t,e),r.levelIsComplete(t,e))return s=l[t],!0},i=function(e){if(!s)for(var r=n+e;Wh<=r&&r<=$h&&!t(r);r+=e);};i(1),i(-1);for(var a=c.length-1;a>=0;a--){var o=c[a];o.invalid&&Pt(c,o)}};if(r.levelIsComplete(n,e))return c;h();var d=function(){if(!o){o=Ln();for(var t=0;t<e.length;t++)In(o,e[t].boundingBox())}return o},p=function(e){var t=(e=e||{}).after;if(d(),o.w*u*(o.h*u)>ad)return null;var i=r.makeLayer(o,n);if(null!=t){var a=c.indexOf(t)+1;c.splice(a,0,i)}else(void 0===e.insert||e.insert)&&c.unshift(i);return i};if(r.skipping&&!a)return null;for(var g=null,f=e.length/qh,v=!a,y=0;y<e.length;y++){var m=e[y],b=m._private.rscratch,x=b.imgLayerCaches=b.imgLayerCaches||{},w=x[n];if(w)g=w;else{if((!g||g.eles.length>=f||!Gn(g.bb,m.boundingBox()))&&!(g=p({insert:!0,after:g})))return null;s||v?r.queueLayer(g,m):r.drawEleInLayer(g,m,n,t),g.eles.push(m),x[n]=g}}return s||(v?null:c)},ld.getEleLevelForLayerLevel=function(e,t){return e},ld.drawEleInLayer=function(e,t,n,r){var i=this,a=this.renderer,o=e.context,s=t.boundingBox();0!==s.w&&0!==s.h&&t.visible()&&(n=i.getEleLevelForLayerLevel(n,r),a.setImgSmoothing(o,!1),a.drawCachedElement(o,t,null,null,n,od),a.setImgSmoothing(o,!0))},ld.levelIsComplete=function(e,t){var n=this.layersByLevel[e];if(!n||0===n.length)return!1;for(var r=0,i=0;i<n.length;i++){var a=n[i];if(a.reqs>0)return!1;if(a.invalid)return!1;r+=a.eles.length}return r===t.length},ld.validateLayersElesOrdering=function(e,t){var n=this.layersByLevel[e];if(n)for(var r=0;r<n.length;r++){for(var i=n[r],a=-1,o=0;o<t.length;o++)if(i.eles[0]===t[o]){a=o;break}if(a<0)this.invalidateLayer(i);else{var s=a;for(o=0;o<i.eles.length;o++)if(i.eles[o]!==t[s+o]){this.invalidateLayer(i);break}}}},ld.updateElementsInLayers=function(e,t){for(var n=this,r=A(e[0]),i=0;i<e.length;i++)for(var a=r?null:e[i],o=r?e[i]:e[i].ele,s=o._private.rscratch,l=s.imgLayerCaches=s.imgLayerCaches||{},u=Wh;u<=$h;u++){var c=l[u];c&&(a&&n.getEleLevelForLayerLevel(c.level)!==a.level||t(c,o,a))}},ld.haveLayers=function(){for(var e=this,t=!1,n=Wh;n<=$h;n++){var r=e.layersByLevel[n];if(r&&r.length>0){t=!0;break}}return t},ld.invalidateElements=function(e){var t=this;0!==e.length&&(t.lastInvalidationTime=rt(),0!==e.length&&t.haveLayers()&&t.updateElementsInLayers(e,(function(e,n,r){t.invalidateLayer(e)})))},ld.invalidateLayer=function(e){if(this.lastInvalidationTime=rt(),!e.invalid){var t=e.level,n=e.eles,r=this.layersByLevel[t];Pt(r,e),e.elesQueue=[],e.invalid=!0,e.replacement&&(e.replacement.invalid=!0);for(var i=0;i<n.length;i++){var a=n[i]._private.rscratch.imgLayerCaches;a&&(a[t]=null)}}},ld.refineElementTextures=function(e){var t=this;t.updateElementsInLayers(e,(function(e,n,r){var i=e.replacement;if(i||((i=e.replacement=t.makeLayer(e.bb,e.level)).replaces=e,i.eles=e.eles),!i.reqs)for(var a=0;a<i.eles.length;a++)t.queueLayer(i,i.eles[a])}))},ld.enqueueElementRefinement=function(e){this.eleTxrDeqs.merge(e),this.scheduleElementRefinement()},ld.queueLayer=function(e,t){var n=this.layersQueue,r=e.elesQueue,i=r.hasId=r.hasId||{};if(!e.replacement){if(t){if(i[t.id()])return;r.push(t),i[t.id()]=!0}e.reqs?(e.reqs++,n.updateItem(e)):(e.reqs=1,n.push(e))}},ld.dequeue=function(e){for(var t=this,n=t.layersQueue,r=[],i=0;i<rd&&0!==n.size();){var a=n.peek();if(a.replacement)n.pop();else if(a.replaces&&a!==a.replaces.replacement)n.pop();else if(a.invalid)n.pop();else{var o=a.elesQueue.shift();o&&(t.drawEleInLayer(a,o,a.level,e),i++),0===r.length&&r.push(!0),0===a.elesQueue.length&&(n.pop(),a.reqs=0,a.replaces&&t.applyLayerReplacement(a),t.requestRedraw())}}return r},ld.applyLayerReplacement=function(e){var t=this,n=t.layersByLevel[e.level],r=e.replaces,i=n.indexOf(r);if(!(i<0||r.invalid)){n[i]=e;for(var a=0;a<e.eles.length;a++){var o=e.eles[a]._private,s=o.imgLayerCaches=o.imgLayerCaches||{};s&&(s[e.level]=e)}t.requestRedraw()}},ld.requestRedraw=Qe((function(){var e=this.renderer;e.redrawHint("eles",!0),e.redrawHint("drag",!0),e.redraw()}),100),ld.setupDequeueing=Th.setupDequeueing({deqRedrawThreshold:Zh,deqCost:Jh,deqAvgCost:ed,deqNoDrawCost:td,deqFastCost:nd,deq:function(e,t){return e.dequeue(t)},onDeqd:_t,shouldRedraw:wt,priority:function(e){return e.renderer.beforeRenderPriorities.lyrTxrDeq}});var hd,dd={};function pd(e,t){for(var n=0;n<t.length;n++){var r=t[n];e.lineTo(r.x,r.y)}}function gd(e,t,n){for(var r,i=0;i<t.length;i++){var a=t[i];0===i&&(r=a),e.lineTo(a.x,a.y)}e.quadraticCurveTo(n.x,n.y,r.x,r.y)}function fd(e,t,n){e.beginPath&&e.beginPath();for(var r=t,i=0;i<r.length;i++){var a=r[i];e.lineTo(a.x,a.y)}var o=n,s=n[0];for(e.moveTo(s.x,s.y),i=1;i<o.length;i++)a=o[i],e.lineTo(a.x,a.y);e.closePath&&e.closePath()}function vd(e,t,n,r,i){e.beginPath&&e.beginPath(),e.arc(n,r,i,0,2*Math.PI,!1);var a=t,o=a[0];e.moveTo(o.x,o.y);for(var s=0;s<a.length;s++){var l=a[s];e.lineTo(l.x,l.y)}e.closePath&&e.closePath()}function yd(e,t,n,r){e.arc(t,n,r,0,2*Math.PI,!1)}dd.arrowShapeImpl=function(e){return(hd||(hd={polygon:pd,"triangle-backcurve":gd,"triangle-tee":fd,"circle-triangle":vd,"triangle-cross":fd,circle:yd}))[e]};var md={drawElement:function(e,t,n,r,i,a){var o=this;t.isNode()?o.drawNode(e,t,n,r,i,a):o.drawEdge(e,t,n,r,i,a)},drawElementOverlay:function(e,t){var n=this;t.isNode()?n.drawNodeOverlay(e,t):n.drawEdgeOverlay(e,t)},drawElementUnderlay:function(e,t){var n=this;t.isNode()?n.drawNodeUnderlay(e,t):n.drawEdgeUnderlay(e,t)},drawCachedElementPortion:function(e,t,n,r,i,a,o,s){var l=this,u=n.getBoundingBox(t);if(0!==u.w&&0!==u.h){var c=n.getElement(t,u,r,i,a);if(null!=c){var h=s(l,t);if(0===h)return;var d,p,g,f,v,y,m=o(l,t),b=u.x1,x=u.y1,w=u.w,E=u.h;if(0!==m){var T=n.getRotationPoint(t);g=T.x,f=T.y,e.translate(g,f),e.rotate(m),(v=l.getImgSmoothing(e))||l.setImgSmoothing(e,!0);var _=n.getRotationOffset(t);d=_.x,p=_.y}else d=b,p=x;1!==h&&(y=e.globalAlpha,e.globalAlpha=y*h),e.drawImage(c.texture.canvas,c.x,0,c.width,c.height,d,p,w,E),1!==h&&(e.globalAlpha=y),0!==m&&(e.rotate(-m),e.translate(-g,-f),v||l.setImgSmoothing(e,!1))}else n.drawElement(e,t)}}},bd=function(){return 0},xd=function(e,t){return e.getTextAngle(t,null)},wd=function(e,t){return e.getTextAngle(t,"source")},Ed=function(e,t){return e.getTextAngle(t,"target")},Td=function(e,t){return t.effectiveOpacity()},_d=function(e,t){return t.pstyle("text-opacity").pfValue*t.effectiveOpacity()};md.drawCachedElement=function(e,t,n,r,i,a){var o=this,s=o.data,l=s.eleTxrCache,u=s.lblTxrCache,c=s.slbTxrCache,h=s.tlbTxrCache,d=t.boundingBox(),p=!0===a?l.reasons.highQuality:null;if(0!==d.w&&0!==d.h&&t.visible()&&(!r||Bn(d,r))){var g=t.isEdge(),f=t.element()._private.rscratch.badLine;o.drawElementUnderlay(e,t),o.drawCachedElementPortion(e,t,l,n,i,p,bd,Td),g&&f||o.drawCachedElementPortion(e,t,u,n,i,p,xd,_d),g&&!f&&(o.drawCachedElementPortion(e,t,c,n,i,p,wd,_d),o.drawCachedElementPortion(e,t,h,n,i,p,Ed,_d)),o.drawElementOverlay(e,t)}},md.drawElements=function(e,t){for(var n=this,r=0;r<t.length;r++){var i=t[r];n.drawElement(e,i)}},md.drawCachedElements=function(e,t,n,r){for(var i=this,a=0;a<t.length;a++){var o=t[a];i.drawCachedElement(e,o,n,r)}},md.drawCachedNodes=function(e,t,n,r){for(var i=this,a=0;a<t.length;a++){var o=t[a];o.isNode()&&i.drawCachedElement(e,o,n,r)}},md.drawLayeredElements=function(e,t,n,r){var i=this,a=i.data.lyrTxrCache.getLayers(t,n);if(a)for(var o=0;o<a.length;o++){var s=a[o],l=s.bb;0!==l.w&&0!==l.h&&e.drawImage(s.canvas,l.x1,l.y1,l.w,l.h)}else i.drawCachedElements(e,t,n,r)};var Dd={drawEdge:function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this,s=t._private.rscratch;if((!a||t.visible())&&!s.badLine&&null!=s.allpts&&!isNaN(s.allpts[0])){var l;n&&(l=n,e.translate(-l.x1,-l.y1));var u=a?t.pstyle("opacity").value:1,c=a?t.pstyle("line-opacity").value:1,h=t.pstyle("curve-style").value,d=t.pstyle("line-style").value,p=t.pstyle("width").pfValue,g=t.pstyle("line-cap").value,f=u*c,v=u*c,y=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:f;"straight-triangle"===h?(o.eleStrokeStyle(e,t,n),o.drawEdgeTrianglePath(t,e,s.allpts)):(e.lineWidth=p,e.lineCap=g,o.eleStrokeStyle(e,t,n),o.drawEdgePath(t,e,s.allpts,d),e.lineCap="butt")},m=function(){i&&o.drawEdgeOverlay(e,t)},b=function(){i&&o.drawEdgeUnderlay(e,t)},x=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:v;o.drawArrowheads(e,t,n)},w=function(){o.drawElementText(e,t,null,r)};if(e.lineJoin="round","yes"===t.pstyle("ghost").value){var E=t.pstyle("ghost-offset-x").pfValue,T=t.pstyle("ghost-offset-y").pfValue,_=t.pstyle("ghost-opacity").value,D=f*_;e.translate(E,T),y(D),x(D),e.translate(-E,-T)}b(),y(),x(),m(),w(),n&&e.translate(l.x1,l.y1)}}},Cd=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n){if(n.visible()){var r=n.pstyle("".concat(e,"-opacity")).value;if(0!==r){var i=this,a=i.usePaths(),o=n._private.rscratch,s=2*n.pstyle("".concat(e,"-padding")).pfValue,l=n.pstyle("".concat(e,"-color")).value;t.lineWidth=s,"self"!==o.edgeType||a?t.lineCap="round":t.lineCap="butt",i.colorStrokeStyle(t,l[0],l[1],l[2],r),i.drawEdgePath(n,t,o.allpts,"solid")}}}};Dd.drawEdgeOverlay=Cd("overlay"),Dd.drawEdgeUnderlay=Cd("underlay"),Dd.drawEdgePath=function(e,t,n,r){var i,a=e._private.rscratch,o=t,s=!1,l=this.usePaths(),u=e.pstyle("line-dash-pattern").pfValue,c=e.pstyle("line-dash-offset").pfValue;if(l){var h=n.join("$");a.pathCacheKey&&a.pathCacheKey===h?(i=t=a.pathCache,s=!0):(i=t=new Path2D,a.pathCacheKey=h,a.pathCache=i)}if(o.setLineDash)switch(r){case"dotted":o.setLineDash([1,1]);break;case"dashed":o.setLineDash(u),o.lineDashOffset=c;break;case"solid":o.setLineDash([])}if(!s&&!a.badLine)switch(t.beginPath&&t.beginPath(),t.moveTo(n[0],n[1]),a.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var d=2;d+3<n.length;d+=4)t.quadraticCurveTo(n[d],n[d+1],n[d+2],n[d+3]);break;case"straight":case"segments":case"haystack":for(var p=2;p+1<n.length;p+=2)t.lineTo(n[p],n[p+1])}t=o,l?t.stroke(i):t.stroke(),t.setLineDash&&t.setLineDash([])},Dd.drawEdgeTrianglePath=function(e,t,n){t.fillStyle=t.strokeStyle;for(var r=e.pstyle("width").pfValue,i=0;i+1<n.length;i+=2){var a=[n[i+2]-n[i],n[i+3]-n[i+1]],o=Math.sqrt(a[0]*a[0]+a[1]*a[1]),s=[a[1]/o,-a[0]/o],l=[s[0]*r/2,s[1]*r/2];t.beginPath(),t.moveTo(n[i]-l[0],n[i+1]-l[1]),t.lineTo(n[i]+l[0],n[i+1]+l[1]),t.lineTo(n[i+2],n[i+3]),t.closePath(),t.fill()}},Dd.drawArrowheads=function(e,t,n){var r=t._private.rscratch,i="haystack"===r.edgeType;i||this.drawArrowhead(e,t,"source",r.arrowStartX,r.arrowStartY,r.srcArrowAngle,n),this.drawArrowhead(e,t,"mid-target",r.midX,r.midY,r.midtgtArrowAngle,n),this.drawArrowhead(e,t,"mid-source",r.midX,r.midY,r.midsrcArrowAngle,n),i||this.drawArrowhead(e,t,"target",r.arrowEndX,r.arrowEndY,r.tgtArrowAngle,n)},Dd.drawArrowhead=function(e,t,n,r,i,a,o){if(!(isNaN(r)||null==r||isNaN(i)||null==i||isNaN(a)||null==a)){var s=this,l=t.pstyle(n+"-arrow-shape").value;if("none"!==l){var u="hollow"===t.pstyle(n+"-arrow-fill").value?"both":"filled",c=t.pstyle(n+"-arrow-fill").value,h=t.pstyle("width").pfValue,d=t.pstyle("opacity").value;void 0===o&&(o=d);var p=e.globalCompositeOperation;1===o&&"hollow"!==c||(e.globalCompositeOperation="destination-out",s.colorFillStyle(e,255,255,255,1),s.colorStrokeStyle(e,255,255,255,1),s.drawArrowShape(t,e,u,h,l,r,i,a),e.globalCompositeOperation=p);var g=t.pstyle(n+"-arrow-color").value;s.colorFillStyle(e,g[0],g[1],g[2],o),s.colorStrokeStyle(e,g[0],g[1],g[2],o),s.drawArrowShape(t,e,c,h,l,r,i,a)}}},Dd.drawArrowShape=function(e,t,n,r,i,a,o,s){var l,u=this,c=this.usePaths()&&"triangle-cross"!==i,h=!1,d=t,p={x:a,y:o},g=e.pstyle("arrow-scale").value,f=this.getArrowWidth(r,g),v=u.arrowShapes[i];if(c){var y=u.arrowPathCache=u.arrowPathCache||[],m=gt(i),b=y[m];null!=b?(l=t=b,h=!0):(l=t=new Path2D,y[m]=l)}h||(t.beginPath&&t.beginPath(),c?v.draw(t,1,0,{x:0,y:0},1):v.draw(t,f,s,p,r),t.closePath&&t.closePath()),t=d,c&&(t.translate(a,o),t.rotate(s),t.scale(f,f)),"filled"!==n&&"both"!==n||(c?t.fill(l):t.fill()),"hollow"!==n&&"both"!==n||(t.lineWidth=(v.matchEdgeWidth?r:1)/(c?f:1),t.lineJoin="miter",c?t.stroke(l):t.stroke()),c&&(t.scale(1/f,1/f),t.rotate(-s),t.translate(-a,-o))};var Nd={safeDrawImage:function(e,t,n,r,i,a,o,s,l,u){if(!(i<=0||a<=0||l<=0||u<=0))try{e.drawImage(t,n,r,i,a,o,s,l,u)}catch(c){Nt(c)}},drawInscribedImage:function(e,t,n,r,i){var a=this,o=n.position(),s=o.x,l=o.y,u=n.cy().style(),c=u.getIndexedStyle.bind(u),h=c(n,"background-fit","value",r),d=c(n,"background-repeat","value",r),p=n.width(),g=n.height(),f=2*n.padding(),v=p+("inner"===c(n,"background-width-relative-to","value",r)?0:f),y=g+("inner"===c(n,"background-height-relative-to","value",r)?0:f),m=n._private.rscratch,b="node"===c(n,"background-clip","value",r),x=c(n,"background-image-opacity","value",r)*i,w=c(n,"background-image-smoothing","value",r),E=t.width||t.cachedW,T=t.height||t.cachedH;null!=E&&null!=T||(document.body.appendChild(t),E=t.cachedW=t.width||t.offsetWidth,T=t.cachedH=t.height||t.offsetHeight,document.body.removeChild(t));var _=E,D=T;if("auto"!==c(n,"background-width","value",r)&&(_="%"===c(n,"background-width","units",r)?c(n,"background-width","pfValue",r)*v:c(n,"background-width","pfValue",r)),"auto"!==c(n,"background-height","value",r)&&(D="%"===c(n,"background-height","units",r)?c(n,"background-height","pfValue",r)*y:c(n,"background-height","pfValue",r)),0!==_&&0!==D){if("contain"===h)_*=C=Math.min(v/_,y/D),D*=C;else if("cover"===h){var C;_*=C=Math.max(v/_,y/D),D*=C}var N=s-v/2,A=c(n,"background-position-x","units",r),L=c(n,"background-position-x","pfValue",r);N+="%"===A?(v-_)*L:L;var S=c(n,"background-offset-x","units",r),O=c(n,"background-offset-x","pfValue",r);N+="%"===S?(v-_)*O:O;var I=l-y/2,k=c(n,"background-position-y","units",r),M=c(n,"background-position-y","pfValue",r);I+="%"===k?(y-D)*M:M;var P=c(n,"background-offset-y","units",r),R=c(n,"background-offset-y","pfValue",r);I+="%"===P?(y-D)*R:R,m.pathCache&&(N-=s,I-=l,s=0,l=0);var B=e.globalAlpha;e.globalAlpha=x;var F=a.getImgSmoothing(e),z=!1;if("no"===w&&F?(a.setImgSmoothing(e,!1),z=!0):"yes"!==w||F||(a.setImgSmoothing(e,!0),z=!0),"no-repeat"===d)b&&(e.save(),m.pathCache?e.clip(m.pathCache):(a.nodeShapes[a.getNodeShape(n)].draw(e,s,l,v,y),e.clip())),a.safeDrawImage(e,t,0,0,E,T,N,I,_,D),b&&e.restore();else{var G=e.createPattern(t,d);e.fillStyle=G,a.nodeShapes[a.getNodeShape(n)].draw(e,s,l,v,y),e.translate(N,I),e.fill(),e.translate(-N,-I)}e.globalAlpha=B,z&&a.setImgSmoothing(e,F)}}},Ad={};function Ld(e,t,n,r,i){var a=arguments.length>5&&void 0!==arguments[5]?arguments[5]:5;e.beginPath(),e.moveTo(t+a,n),e.lineTo(t+r-a,n),e.quadraticCurveTo(t+r,n,t+r,n+a),e.lineTo(t+r,n+i-a),e.quadraticCurveTo(t+r,n+i,t+r-a,n+i),e.lineTo(t+a,n+i),e.quadraticCurveTo(t,n+i,t,n+i-a),e.lineTo(t,n+a),e.quadraticCurveTo(t,n,t+a,n),e.closePath(),e.fill()}Ad.eleTextBiggerThanMin=function(e,t){if(!t){var n=e.cy().zoom(),r=this.getPixelRatio(),i=Math.ceil(xn(n*r));t=Math.pow(2,i)}return!(e.pstyle("font-size").pfValue*t<e.pstyle("min-zoomed-font-size").pfValue)},Ad.drawElementText=function(e,t,n,r,i){var a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this;if(null==r){if(a&&!o.eleTextBiggerThanMin(t))return}else if(!1===r)return;if(t.isNode()){var s=t.pstyle("label");if(!s||!s.value)return;var l=o.getLabelJustification(t);e.textAlign=l,e.textBaseline="bottom"}else{var u=t.element()._private.rscratch.badLine,c=t.pstyle("label"),h=t.pstyle("source-label"),d=t.pstyle("target-label");if(u||(!c||!c.value)&&(!h||!h.value)&&(!d||!d.value))return;e.textAlign="center",e.textBaseline="bottom"}var p,g=!n;n&&(p=n,e.translate(-p.x1,-p.y1)),null==i?(o.drawText(e,t,null,g,a),t.isEdge()&&(o.drawText(e,t,"source",g,a),o.drawText(e,t,"target",g,a))):o.drawText(e,t,i,g,a),n&&e.translate(p.x1,p.y1)},Ad.getFontCache=function(e){var t;this.fontCaches=this.fontCaches||[];for(var n=0;n<this.fontCaches.length;n++)if((t=this.fontCaches[n]).context===e)return t;return t={context:e},this.fontCaches.push(t),t},Ad.setupTextStyle=function(e,t){var n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2],r=t.pstyle("font-style").strValue,i=t.pstyle("font-size").pfValue+"px",a=t.pstyle("font-family").strValue,o=t.pstyle("font-weight").strValue,s=n?t.effectiveOpacity()*t.pstyle("text-opacity").value:1,l=t.pstyle("text-outline-opacity").value*s,u=t.pstyle("color").value,c=t.pstyle("text-outline-color").value;e.font=r+" "+o+" "+i+" "+a,e.lineJoin="round",this.colorFillStyle(e,u[0],u[1],u[2],s),this.colorStrokeStyle(e,c[0],c[1],c[2],l)},Ad.getTextAngle=function(e,t){var n=e._private.rscratch,r=t?t+"-":"",i=e.pstyle(r+"text-rotation"),a=Ft(n,"labelAngle",t);return"autorotate"===i.strValue?e.isEdge()?a:0:"none"===i.strValue?0:i.pfValue},Ad.drawText=function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],i=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=t._private.rscratch,o=i?t.effectiveOpacity():1;if(!i||0!==o&&0!==t.pstyle("text-opacity").value){"main"===n&&(n=null);var s,l,u=Ft(a,"labelX",n),c=Ft(a,"labelY",n),h=this.getLabelText(t,n);if(null!=h&&""!==h&&!isNaN(u)&&!isNaN(c)){this.setupTextStyle(e,t,i);var d,p=n?n+"-":"",g=Ft(a,"labelWidth",n),f=Ft(a,"labelHeight",n),v=t.pstyle(p+"text-margin-x").pfValue,y=t.pstyle(p+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle("text-halign").value,x=t.pstyle("text-valign").value;switch(m&&(b="center",x="center"),u+=v,c+=y,0!==(d=r?this.getTextAngle(t,n):0)&&(s=u,l=c,e.translate(s,l),e.rotate(d),u=0,c=0),x){case"top":break;case"center":c+=f/2;break;case"bottom":c+=f}var w=t.pstyle("text-background-opacity").value,E=t.pstyle("text-border-opacity").value,T=t.pstyle("text-border-width").pfValue,_=t.pstyle("text-background-padding").pfValue;if(w>0||T>0&&E>0){var D=u-_;switch(b){case"left":D-=g;break;case"center":D-=g/2}var C=c-f-_,N=g+2*_,A=f+2*_;if(w>0){var L=e.fillStyle,S=t.pstyle("text-background-color").value;e.fillStyle="rgba("+S[0]+","+S[1]+","+S[2]+","+w*o+")",0===t.pstyle("text-background-shape").strValue.indexOf("round")?Ld(e,D,C,N,A,2):e.fillRect(D,C,N,A),e.fillStyle=L}if(T>0&&E>0){var O=e.strokeStyle,I=e.lineWidth,k=t.pstyle("text-border-color").value,M=t.pstyle("text-border-style").value;if(e.strokeStyle="rgba("+k[0]+","+k[1]+","+k[2]+","+E*o+")",e.lineWidth=T,e.setLineDash)switch(M){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"double":e.lineWidth=T/4,e.setLineDash([]);break;case"solid":e.setLineDash([])}if(e.strokeRect(D,C,N,A),"double"===M){var P=T/2;e.strokeRect(D+P,C+P,N-2*P,A-2*P)}e.setLineDash&&e.setLineDash([]),e.lineWidth=I,e.strokeStyle=O}}var R=2*t.pstyle("text-outline-width").pfValue;if(R>0&&(e.lineWidth=R),"wrap"===t.pstyle("text-wrap").value){var B=Ft(a,"labelWrapCachedLines",n),F=Ft(a,"labelLineHeight",n),z=g/2,G=this.getLabelJustification(t);switch("auto"===G||("left"===b?"left"===G?u+=-g:"center"===G&&(u+=-z):"center"===b?"left"===G?u+=-z:"right"===G&&(u+=z):"right"===b&&("center"===G?u+=z:"right"===G&&(u+=g))),x){case"top":case"center":case"bottom":c-=(B.length-1)*F}for(var Y=0;Y<B.length;Y++)R>0&&e.strokeText(B[Y],u,c),e.fillText(B[Y],u,c),c+=F}else R>0&&e.strokeText(h,u,c),e.fillText(h,u,c);0!==d&&(e.rotate(-d),e.translate(-s,-l))}}};var Sd={drawNode:function(e,t,n){var r,i,a=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],s=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],l=this,u=t._private,c=u.rscratch,h=t.position();if(_(h.x)&&_(h.y)&&(!s||t.visible())){var d,p,g=s?t.effectiveOpacity():1,f=l.usePaths(),v=!1,y=t.padding();r=t.width()+2*y,i=t.height()+2*y,n&&(p=n,e.translate(-p.x1,-p.y1));for(var m=t.pstyle("background-image").value,b=new Array(m.length),x=new Array(m.length),w=0,E=0;E<m.length;E++){var T=m[E];if(b[E]=null!=T&&"none"!==T){var D=t.cy().style().getIndexedStyle(t,"background-image-crossorigin","value",E);w++,x[E]=l.getCachedImage(T,D,(function(){u.backgroundTimestamp=Date.now(),t.emitAndNotify("background")}))}}var C=t.pstyle("background-blacken").value,N=t.pstyle("border-width").pfValue,A=t.pstyle("background-opacity").value*g,L=t.pstyle("border-color").value,S=t.pstyle("border-style").value,O=t.pstyle("border-opacity").value*g;e.lineJoin="miter";var I=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:A;l.eleFillStyle(e,t,n)},k=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:O;l.colorStrokeStyle(e,L[0],L[1],L[2],t)},M=t.pstyle("shape").strValue,P=t.pstyle("shape-polygon-points").pfValue;if(f){e.translate(h.x,h.y);var R=l.nodePathCache=l.nodePathCache||[],B=ft("polygon"===M?M+","+P.join(","):M,""+i,""+r),F=R[B];null!=F?(d=F,v=!0,c.pathCache=d):(d=new Path2D,R[B]=c.pathCache=d)}var z=function(){if(!v){var n=h;f&&(n={x:0,y:0}),l.nodeShapes[l.getNodeShape(t)].draw(d||e,n.x,n.y,r,i)}f?e.fill(d):e.fill()},G=function(){for(var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:g,r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=u.backgrounding,a=0,o=0;o<x.length;o++){var s=t.cy().style().getIndexedStyle(t,"background-image-containment","value",o);r&&"over"===s||!r&&"inside"===s?a++:b[o]&&x[o].complete&&!x[o].error&&(a++,l.drawInscribedImage(e,x[o],t,o,n))}u.backgrounding=!(a===w),i!==u.backgrounding&&t.updateStyle(!1)},Y=function(){var n=arguments.length>0&&void 0!==arguments[0]&&arguments[0],a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:g;l.hasPie(t)&&(l.drawPie(e,t,a),n&&(f||l.nodeShapes[l.getNodeShape(t)].draw(e,h.x,h.y,r,i)))},X=function(){var t=(C>0?C:-C)*(arguments.length>0&&void 0!==arguments[0]?arguments[0]:g),n=C>0?0:255;0!==C&&(l.colorFillStyle(e,n,n,n,t),f?e.fill(d):e.fill())},V=function(){if(N>0){if(e.lineWidth=N,e.lineCap="butt",e.setLineDash)switch(S){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}if(f?e.stroke(d):e.stroke(),"double"===S){e.lineWidth=N/3;var t=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",f?e.stroke(d):e.stroke(),e.globalCompositeOperation=t}e.setLineDash&&e.setLineDash([])}},U=function(){o&&l.drawNodeOverlay(e,t,h,r,i)},j=function(){o&&l.drawNodeUnderlay(e,t,h,r,i)},H=function(){l.drawElementText(e,t,null,a)};if("yes"===t.pstyle("ghost").value){var q=t.pstyle("ghost-offset-x").pfValue,W=t.pstyle("ghost-offset-y").pfValue,$=t.pstyle("ghost-opacity").value,K=$*g;e.translate(q,W),I($*A),z(),G(K,!0),k($*O),V(),Y(0!==C||0!==N),G(K,!1),X(K),e.translate(-q,-W)}f&&e.translate(-h.x,-h.y),j(),f&&e.translate(h.x,h.y),I(),z(),G(g,!0),k(),V(),Y(0!==C||0!==N),G(g,!1),X(),f&&e.translate(-h.x,-h.y),H(),U(),n&&e.translate(p.x1,p.y1)}}},Od=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n,r,i,a){var o=this;if(n.visible()){var s=n.pstyle("".concat(e,"-padding")).pfValue,l=n.pstyle("".concat(e,"-opacity")).value,u=n.pstyle("".concat(e,"-color")).value,c=n.pstyle("".concat(e,"-shape")).value;if(l>0){if(r=r||n.position(),null==i||null==a){var h=n.padding();i=n.width()+2*h,a=n.height()+2*h}o.colorFillStyle(t,u[0],u[1],u[2],l),o.nodeShapes[c].draw(t,r.x,r.y,i+2*s,a+2*s),t.fill()}}}};Sd.drawNodeOverlay=Od("overlay"),Sd.drawNodeUnderlay=Od("underlay"),Sd.hasPie=function(e){return(e=e[0])._private.hasPie},Sd.drawPie=function(e,t,n,r){t=t[0],r=r||t.position();var i=t.cy().style(),a=t.pstyle("pie-size"),o=r.x,s=r.y,l=t.width(),u=t.height(),c=Math.min(l,u)/2,h=0;this.usePaths()&&(o=0,s=0),"%"===a.units?c*=a.pfValue:void 0!==a.pfValue&&(c=a.pfValue/2);for(var d=1;d<=i.pieBackgroundN;d++){var p=t.pstyle("pie-"+d+"-background-size").value,g=t.pstyle("pie-"+d+"-background-color").value,f=t.pstyle("pie-"+d+"-background-opacity").value*n,v=p/100;v+h>1&&(v=1-h);var y=1.5*Math.PI+2*Math.PI*h,m=y+2*Math.PI*v;0===p||h>=1||h+v>1||(e.beginPath(),e.moveTo(o,s),e.arc(o,s,c,y,m),e.closePath(),this.colorFillStyle(e,g[0],g[1],g[2],f),e.fill(),h+=v)}};var Id={},kd=100;Id.getPixelRatio=function(){var e=this.data.contexts[0];if(null!=this.forcedPixelRatio)return this.forcedPixelRatio;var t=e.backingStorePixelRatio||e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return(window.devicePixelRatio||1)/t},Id.paintCache=function(e){for(var t,n=this.paintCaches=this.paintCaches||[],r=!0,i=0;i<n.length;i++)if((t=n[i]).context===e){r=!1;break}return r&&(t={context:e},n.push(t)),t},Id.createGradientStyleFor=function(e,t,n,r,i){var a,o=this.usePaths(),s=n.pstyle(t+"-gradient-stop-colors").value,l=n.pstyle(t+"-gradient-stop-positions").pfValue;if("radial-gradient"===r)if(n.isEdge()){var u=n.sourceEndpoint(),c=n.targetEndpoint(),h=n.midpoint(),d=En(u,h),p=En(c,h);a=e.createRadialGradient(h.x,h.y,0,h.x,h.y,Math.max(d,p))}else{var g=o?{x:0,y:0}:n.position(),f=n.paddedWidth(),v=n.paddedHeight();a=e.createRadialGradient(g.x,g.y,0,g.x,g.y,Math.max(f,v))}else if(n.isEdge()){var y=n.sourceEndpoint(),m=n.targetEndpoint();a=e.createLinearGradient(y.x,y.y,m.x,m.y)}else{var b=o?{x:0,y:0}:n.position(),x=n.paddedWidth()/2,w=n.paddedHeight()/2;switch(n.pstyle("background-gradient-direction").value){case"to-bottom":a=e.createLinearGradient(b.x,b.y-w,b.x,b.y+w);break;case"to-top":a=e.createLinearGradient(b.x,b.y+w,b.x,b.y-w);break;case"to-left":a=e.createLinearGradient(b.x+x,b.y,b.x-x,b.y);break;case"to-right":a=e.createLinearGradient(b.x-x,b.y,b.x+x,b.y);break;case"to-bottom-right":case"to-right-bottom":a=e.createLinearGradient(b.x-x,b.y-w,b.x+x,b.y+w);break;case"to-top-right":case"to-right-top":a=e.createLinearGradient(b.x-x,b.y+w,b.x+x,b.y-w);break;case"to-bottom-left":case"to-left-bottom":a=e.createLinearGradient(b.x+x,b.y-w,b.x-x,b.y+w);break;case"to-top-left":case"to-left-top":a=e.createLinearGradient(b.x+x,b.y+w,b.x-x,b.y-w)}}if(!a)return null;for(var E=l.length===s.length,T=s.length,_=0;_<T;_++)a.addColorStop(E?l[_]:_/(T-1),"rgba("+s[_][0]+","+s[_][1]+","+s[_][2]+","+i+")");return a},Id.gradientFillStyle=function(e,t,n,r){var i=this.createGradientStyleFor(e,"background",t,n,r);if(!i)return null;e.fillStyle=i},Id.colorFillStyle=function(e,t,n,r,i){e.fillStyle="rgba("+t+","+n+","+r+","+i+")"},Id.eleFillStyle=function(e,t,n){var r=t.pstyle("background-fill").value;if("linear-gradient"===r||"radial-gradient"===r)this.gradientFillStyle(e,t,r,n);else{var i=t.pstyle("background-color").value;this.colorFillStyle(e,i[0],i[1],i[2],n)}},Id.gradientStrokeStyle=function(e,t,n,r){var i=this.createGradientStyleFor(e,"line",t,n,r);if(!i)return null;e.strokeStyle=i},Id.colorStrokeStyle=function(e,t,n,r,i){e.strokeStyle="rgba("+t+","+n+","+r+","+i+")"},Id.eleStrokeStyle=function(e,t,n){var r=t.pstyle("line-fill").value;if("linear-gradient"===r||"radial-gradient"===r)this.gradientStrokeStyle(e,t,r,n);else{var i=t.pstyle("line-color").value;this.colorStrokeStyle(e,i[0],i[1],i[2],n)}},Id.matchCanvasSize=function(e){var t=this,n=t.data,r=t.findContainerClientCoords(),i=r[2],a=r[3],o=t.getPixelRatio(),s=t.motionBlurPxRatio;e!==t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_NODE]&&e!==t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_DRAG]||(o=s);var l,u=i*o,c=a*o;if(u!==t.canvasWidth||c!==t.canvasHeight){t.fontCaches=null;var h=n.canvasContainer;h.style.width=i+"px",h.style.height=a+"px";for(var d=0;d<t.CANVAS_LAYERS;d++)(l=n.canvases[d]).width=u,l.height=c,l.style.width=i+"px",l.style.height=a+"px";for(d=0;d<t.BUFFER_COUNT;d++)(l=n.bufferCanvases[d]).width=u,l.height=c,l.style.width=i+"px",l.style.height=a+"px";t.textureMult=1,o<=1&&(l=n.bufferCanvases[t.TEXTURE_BUFFER],t.textureMult=2,l.width=u*t.textureMult,l.height=c*t.textureMult),t.canvasWidth=u,t.canvasHeight=c}},Id.renderTo=function(e,t,n,r){this.render({forcedContext:e,forcedZoom:t,forcedPan:n,drawAllLayers:!0,forcedPxRatio:r})},Id.render=function(e){var t=(e=e||kt()).forcedContext,n=e.drawAllLayers,r=e.drawOnlyNodeLayer,i=e.forcedZoom,a=e.forcedPan,o=this,s=void 0===e.forcedPxRatio?this.getPixelRatio():e.forcedPxRatio,l=o.cy,u=o.data,c=u.canvasNeedsRedraw,h=o.textureOnViewport&&!t&&(o.pinching||o.hoverData.dragging||o.swipePanning||o.data.wheelZooming),d=void 0!==e.motionBlur?e.motionBlur:o.motionBlur,p=o.motionBlurPxRatio,g=l.hasCompoundNodes(),f=o.hoverData.draggingEles,v=!(!o.hoverData.selecting&&!o.touchData.selecting),y=d=d&&!t&&o.motionBlurEnabled&&!v;t||(o.prevPxRatio!==s&&(o.invalidateContainerClientCoordsCache(),o.matchCanvasSize(o.container),o.redrawHint("eles",!0),o.redrawHint("drag",!0)),o.prevPxRatio=s),!t&&o.motionBlurTimeout&&clearTimeout(o.motionBlurTimeout),d&&(null==o.mbFrames&&(o.mbFrames=0),o.mbFrames++,o.mbFrames<3&&(y=!1),o.mbFrames>o.minMbLowQualFrames&&(o.motionBlurPxRatio=o.mbPxRBlurry)),o.clearingMotionBlur&&(o.motionBlurPxRatio=1),o.textureDrawLastFrame&&!h&&(c[o.NODE]=!0,c[o.SELECT_BOX]=!0);var m=l.style(),b=l.zoom(),x=void 0!==i?i:b,w=l.pan(),E={x:w.x,y:w.y},T={zoom:b,pan:{x:w.x,y:w.y}},_=o.prevViewport;void 0===_||T.zoom!==_.zoom||T.pan.x!==_.pan.x||T.pan.y!==_.pan.y||f&&!g||(o.motionBlurPxRatio=1),a&&(E=a),x*=s,E.x*=s,E.y*=s;var D=o.getCachedZSortedEles();function C(e,t,n,r,i){var a=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",o.colorFillStyle(e,255,255,255,o.motionBlurTransparency),e.fillRect(t,n,r,i),e.globalCompositeOperation=a}function N(e,r){var s,l,c,h;o.clearingMotionBlur||e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]&&e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]?(s=E,l=x,c=o.canvasWidth,h=o.canvasHeight):(s={x:w.x*p,y:w.y*p},l=b*p,c=o.canvasWidth*p,h=o.canvasHeight*p),e.setTransform(1,0,0,1,0,0),"motionBlur"===r?C(e,0,0,c,h):t||void 0!==r&&!r||e.clearRect(0,0,c,h),n||(e.translate(s.x,s.y),e.scale(l,l)),a&&e.translate(a.x,a.y),i&&e.scale(i,i)}if(h||(o.textureDrawLastFrame=!1),h){if(o.textureDrawLastFrame=!0,!o.textureCache){o.textureCache={},o.textureCache.bb=l.mutableElements().boundingBox(),o.textureCache.texture=o.data.bufferCanvases[o.TEXTURE_BUFFER];var A=o.data.bufferContexts[o.TEXTURE_BUFFER];A.setTransform(1,0,0,1,0,0),A.clearRect(0,0,o.canvasWidth*o.textureMult,o.canvasHeight*o.textureMult),o.render({forcedContext:A,drawOnlyNodeLayer:!0,forcedPxRatio:s*o.textureMult}),(T=o.textureCache.viewport={zoom:l.zoom(),pan:l.pan(),width:o.canvasWidth,height:o.canvasHeight}).mpan={x:(0-T.pan.x)/T.zoom,y:(0-T.pan.y)/T.zoom}}c[o.DRAG]=!1,c[o.NODE]=!1;var L=u.contexts[o.NODE],S=o.textureCache.texture;T=o.textureCache.viewport,L.setTransform(1,0,0,1,0,0),d?C(L,0,0,T.width,T.height):L.clearRect(0,0,T.width,T.height);var O=m.core("outside-texture-bg-color").value,I=m.core("outside-texture-bg-opacity").value;o.colorFillStyle(L,O[0],O[1],O[2],I),L.fillRect(0,0,T.width,T.height),b=l.zoom(),N(L,!1),L.clearRect(T.mpan.x,T.mpan.y,T.width/T.zoom/s,T.height/T.zoom/s),L.drawImage(S,T.mpan.x,T.mpan.y,T.width/T.zoom/s,T.height/T.zoom/s)}else o.textureOnViewport&&!t&&(o.textureCache=null);var k=l.extent(),M=o.pinching||o.hoverData.dragging||o.swipePanning||o.data.wheelZooming||o.hoverData.draggingEles||o.cy.animated(),P=o.hideEdgesOnViewport&&M,R=[];if(R[o.NODE]=!c[o.NODE]&&d&&!o.clearedForMotionBlur[o.NODE]||o.clearingMotionBlur,R[o.NODE]&&(o.clearedForMotionBlur[o.NODE]=!0),R[o.DRAG]=!c[o.DRAG]&&d&&!o.clearedForMotionBlur[o.DRAG]||o.clearingMotionBlur,R[o.DRAG]&&(o.clearedForMotionBlur[o.DRAG]=!0),c[o.NODE]||n||r||R[o.NODE]){var B=d&&!R[o.NODE]&&1!==p;N(L=t||(B?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]:u.contexts[o.NODE]),d&&!B?"motionBlur":void 0),P?o.drawCachedNodes(L,D.nondrag,s,k):o.drawLayeredElements(L,D.nondrag,s,k),o.debug&&o.drawDebugPoints(L,D.nondrag),n||d||(c[o.NODE]=!1)}if(!r&&(c[o.DRAG]||n||R[o.DRAG])&&(B=d&&!R[o.DRAG]&&1!==p,N(L=t||(B?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]:u.contexts[o.DRAG]),d&&!B?"motionBlur":void 0),P?o.drawCachedNodes(L,D.drag,s,k):o.drawCachedElements(L,D.drag,s,k),o.debug&&o.drawDebugPoints(L,D.drag),n||d||(c[o.DRAG]=!1)),o.showFps||!r&&c[o.SELECT_BOX]&&!n){if(N(L=t||u.contexts[o.SELECT_BOX]),1==o.selection[4]&&(o.hoverData.selecting||o.touchData.selecting)){b=o.cy.zoom();var F=m.core("selection-box-border-width").value/b;L.lineWidth=F,L.fillStyle="rgba("+m.core("selection-box-color").value[0]+","+m.core("selection-box-color").value[1]+","+m.core("selection-box-color").value[2]+","+m.core("selection-box-opacity").value+")",L.fillRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]),F>0&&(L.strokeStyle="rgba("+m.core("selection-box-border-color").value[0]+","+m.core("selection-box-border-color").value[1]+","+m.core("selection-box-border-color").value[2]+","+m.core("selection-box-opacity").value+")",L.strokeRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]))}if(u.bgActivePosistion&&!o.hoverData.selecting){b=o.cy.zoom();var z=u.bgActivePosistion;L.fillStyle="rgba("+m.core("active-bg-color").value[0]+","+m.core("active-bg-color").value[1]+","+m.core("active-bg-color").value[2]+","+m.core("active-bg-opacity").value+")",L.beginPath(),L.arc(z.x,z.y,m.core("active-bg-size").pfValue/b,0,2*Math.PI),L.fill()}var G=o.lastRedrawTime;if(o.showFps&&G){G=Math.round(G);var Y=Math.round(1e3/G);L.setTransform(1,0,0,1,0,0),L.fillStyle="rgba(255, 0, 0, 0.75)",L.strokeStyle="rgba(255, 0, 0, 0.75)",L.lineWidth=1,L.fillText("1 frame = "+G+" ms = "+Y+" fps",0,20);var X=60;L.strokeRect(0,30,250,20),L.fillRect(0,30,250*Math.min(Y/X,1),20)}n||(c[o.SELECT_BOX]=!1)}if(d&&1!==p){var V=u.contexts[o.NODE],U=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_NODE],j=u.contexts[o.DRAG],H=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_DRAG],q=function(e,t,n){e.setTransform(1,0,0,1,0,0),n||!y?e.clearRect(0,0,o.canvasWidth,o.canvasHeight):C(e,0,0,o.canvasWidth,o.canvasHeight);var r=p;e.drawImage(t,0,0,o.canvasWidth*r,o.canvasHeight*r,0,0,o.canvasWidth,o.canvasHeight)};(c[o.NODE]||R[o.NODE])&&(q(V,U,R[o.NODE]),c[o.NODE]=!1),(c[o.DRAG]||R[o.DRAG])&&(q(j,H,R[o.DRAG]),c[o.DRAG]=!1)}o.prevViewport=T,o.clearingMotionBlur&&(o.clearingMotionBlur=!1,o.motionBlurCleared=!0,o.motionBlur=!0),d&&(o.motionBlurTimeout=setTimeout((function(){o.motionBlurTimeout=null,o.clearedForMotionBlur[o.NODE]=!1,o.clearedForMotionBlur[o.DRAG]=!1,o.motionBlur=!1,o.clearingMotionBlur=!h,o.mbFrames=0,c[o.NODE]=!0,c[o.DRAG]=!0,o.redraw()}),kd)),t||l.emit("render")};for(var Md={drawPolygonPath:function(e,t,n,r,i,a){var o=r/2,s=i/2;e.beginPath&&e.beginPath(),e.moveTo(t+o*a[0],n+s*a[1]);for(var l=1;l<a.length/2;l++)e.lineTo(t+o*a[2*l],n+s*a[2*l+1]);e.closePath()},drawRoundPolygonPath:function(e,t,n,r,i,a){var o=r/2,s=i/2,l=hr(r,i);e.beginPath&&e.beginPath();for(var u=0;u<a.length/4;u++){var c=void 0,h=void 0;c=0===u?a.length-2:4*u-2,h=4*u+2;var d=t+o*a[4*u],p=n+s*a[4*u+1],g=-a[c]*a[h]-a[c+1]*a[h+1],f=l/Math.tan(Math.acos(g)/2),v=d-f*a[c],y=p-f*a[c+1],m=d+f*a[h],b=p+f*a[h+1];0===u?e.moveTo(v,y):e.lineTo(v,y),e.arcTo(d,p,m,b,l)}e.closePath()},drawRoundRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2,s=cr(r,i);e.beginPath&&e.beginPath(),e.moveTo(t,n-o),e.arcTo(t+a,n-o,t+a,n,s),e.arcTo(t+a,n+o,t,n+o,s),e.arcTo(t-a,n+o,t-a,n,s),e.arcTo(t-a,n-o,t,n-o,s),e.lineTo(t,n-o),e.closePath()},drawBottomRoundRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2,s=cr(r,i);e.beginPath&&e.beginPath(),e.moveTo(t,n-o),e.lineTo(t+a,n-o),e.lineTo(t+a,n),e.arcTo(t+a,n+o,t,n+o,s),e.arcTo(t-a,n+o,t-a,n,s),e.lineTo(t-a,n-o),e.lineTo(t,n-o),e.closePath()},drawCutRectanglePath:function(e,t,n,r,i){var a=r/2,o=i/2,s=dr();e.beginPath&&e.beginPath(),e.moveTo(t-a+s,n-o),e.lineTo(t+a-s,n-o),e.lineTo(t+a,n-o+s),e.lineTo(t+a,n+o-s),e.lineTo(t+a-s,n+o),e.lineTo(t-a+s,n+o),e.lineTo(t-a,n+o-s),e.lineTo(t-a,n-o+s),e.closePath()},drawBarrelPath:function(e,t,n,r,i){var a=r/2,o=i/2,s=t-a,l=t+a,u=n-o,c=n+o,h=gr(r,i),d=h.widthOffset,p=h.heightOffset,g=h.ctrlPtOffsetPct*d;e.beginPath&&e.beginPath(),e.moveTo(s,u+p),e.lineTo(s,c-p),e.quadraticCurveTo(s+g,c,s+d,c),e.lineTo(l-d,c),e.quadraticCurveTo(l-g,c,l,c-p),e.lineTo(l,u+p),e.quadraticCurveTo(l-g,u,l-d,u),e.lineTo(s+d,u),e.quadraticCurveTo(s+g,u,s,u+p),e.closePath()}},Pd=Math.sin(0),Rd=Math.cos(0),Bd={},Fd={},zd=Math.PI/40,Gd=0*Math.PI;Gd<2*Math.PI;Gd+=zd)Bd[Gd]=Math.sin(Gd),Fd[Gd]=Math.cos(Gd);Md.drawEllipsePath=function(e,t,n,r,i){if(e.beginPath&&e.beginPath(),e.ellipse)e.ellipse(t,n,r/2,i/2,0,0,2*Math.PI);else for(var a,o,s=r/2,l=i/2,u=0*Math.PI;u<2*Math.PI;u+=zd)a=t-s*Bd[u]*Pd+s*Fd[u]*Rd,o=n+l*Fd[u]*Pd+l*Bd[u]*Rd,0===u?e.moveTo(a,o):e.lineTo(a,o);e.closePath()};var Yd={};function Xd(e,t){for(var n=atob(e),r=new ArrayBuffer(n.length),i=new Uint8Array(r),a=0;a<n.length;a++)i[a]=n.charCodeAt(a);return new Blob([r],{type:t})}function Vd(e){var t=e.indexOf(",");return e.substr(t+1)}function Ud(e,t,n){var r=function(){return t.toDataURL(n,e.quality)};switch(e.output){case"blob-promise":return new Gi((function(r,i){try{t.toBlob((function(e){null!=e?r(e):i(new Error("`canvas.toBlob()` sent a null value in its callback"))}),n,e.quality)}catch(a){i(a)}}));case"blob":return Xd(Vd(r()),n);case"base64":return Vd(r());default:return r()}}Yd.createBuffer=function(e,t){var n=document.createElement("canvas");return n.width=e,n.height=t,[n,n.getContext("2d")]},Yd.bufferCanvasImage=function(e){var t=this.cy,n=t.mutableElements().boundingBox(),r=this.findContainerClientCoords(),i=e.full?Math.ceil(n.w):r[2],a=e.full?Math.ceil(n.h):r[3],o=_(e.maxWidth)||_(e.maxHeight),s=this.getPixelRatio(),l=1;if(void 0!==e.scale)i*=e.scale,a*=e.scale,l=e.scale;else if(o){var u=1/0,c=1/0;_(e.maxWidth)&&(u=l*e.maxWidth/i),_(e.maxHeight)&&(c=l*e.maxHeight/a),i*=l=Math.min(u,c),a*=l}o||(i*=s,a*=s,l*=s);var h=document.createElement("canvas");h.width=i,h.height=a,h.style.width=i+"px",h.style.height=a+"px";var d=h.getContext("2d");if(i>0&&a>0){d.clearRect(0,0,i,a),d.globalCompositeOperation="source-over";var p=this.getCachedZSortedEles();if(e.full)d.translate(-n.x1*l,-n.y1*l),d.scale(l,l),this.drawElements(d,p),d.scale(1/l,1/l),d.translate(n.x1*l,n.y1*l);else{var g=t.pan(),f={x:g.x*l,y:g.y*l};l*=t.zoom(),d.translate(f.x,f.y),d.scale(l,l),this.drawElements(d,p),d.scale(1/l,1/l),d.translate(-f.x,-f.y)}e.bg&&(d.globalCompositeOperation="destination-over",d.fillStyle=e.bg,d.rect(0,0,i,a),d.fill())}return h},Yd.png=function(e){return Ud(e,this.bufferCanvasImage(e),"image/png")},Yd.jpg=function(e){return Ud(e,this.bufferCanvasImage(e),"image/jpeg")};var jd={nodeShapeImpl:function(e,t,n,r,i,a,o){switch(e){case"ellipse":return this.drawEllipsePath(t,n,r,i,a);case"polygon":return this.drawPolygonPath(t,n,r,i,a,o);case"round-polygon":return this.drawRoundPolygonPath(t,n,r,i,a,o);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(t,n,r,i,a);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(t,n,r,i,a);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(t,n,r,i,a);case"barrel":return this.drawBarrelPath(t,n,r,i,a)}}},Hd=Wd,qd=Wd.prototype;function Wd(e){var t=this;t.data={canvases:new Array(qd.CANVAS_LAYERS),contexts:new Array(qd.CANVAS_LAYERS),canvasNeedsRedraw:new Array(qd.CANVAS_LAYERS),bufferCanvases:new Array(qd.BUFFER_COUNT),bufferContexts:new Array(qd.CANVAS_LAYERS)};var n="-webkit-tap-highlight-color",r="rgba(0,0,0,0)";t.data.canvasContainer=document.createElement("div");var i=t.data.canvasContainer.style;t.data.canvasContainer.style[n]=r,i.position="relative",i.zIndex="0",i.overflow="hidden";var a=e.cy.container();a.appendChild(t.data.canvasContainer),a.style[n]=r;var o={"-webkit-user-select":"none","-moz-user-select":"-moz-none","user-select":"none","-webkit-tap-highlight-color":"rgba(0,0,0,0)","outline-style":"none"};B()&&(o["-ms-touch-action"]="none",o["touch-action"]="none");for(var s=0;s<qd.CANVAS_LAYERS;s++){var l=t.data.canvases[s]=document.createElement("canvas");t.data.contexts[s]=l.getContext("2d"),Object.keys(o).forEach((function(e){l.style[e]=o[e]})),l.style.position="absolute",l.setAttribute("data-id","layer"+s),l.style.zIndex=String(qd.CANVAS_LAYERS-s),t.data.canvasContainer.appendChild(l),t.data.canvasNeedsRedraw[s]=!1}for(t.data.topCanvas=t.data.canvases[0],t.data.canvases[qd.NODE].setAttribute("data-id","layer"+qd.NODE+"-node"),t.data.canvases[qd.SELECT_BOX].setAttribute("data-id","layer"+qd.SELECT_BOX+"-selectbox"),t.data.canvases[qd.DRAG].setAttribute("data-id","layer"+qd.DRAG+"-drag"),s=0;s<qd.BUFFER_COUNT;s++)t.data.bufferCanvases[s]=document.createElement("canvas"),t.data.bufferContexts[s]=t.data.bufferCanvases[s].getContext("2d"),t.data.bufferCanvases[s].style.position="absolute",t.data.bufferCanvases[s].setAttribute("data-id","buffer"+s),t.data.bufferCanvases[s].style.zIndex=String(-s-1),t.data.bufferCanvases[s].style.visibility="hidden";t.pathsEnabled=!0;var u=Ln(),c=function(e){return{x:(e.x1+e.x2)/2,y:(e.y1+e.y2)/2}},h=function(e){return{x:-e.w/2,y:-e.h/2}},d=function(e){var t=e[0]._private;return!(t.oldBackgroundTimestamp===t.backgroundTimestamp)},p=function(e){return e[0]._private.nodeKey},g=function(e){return e[0]._private.labelStyleKey},f=function(e){return e[0]._private.sourceLabelStyleKey},v=function(e){return e[0]._private.targetLabelStyleKey},y=function(e,n,r,i,a){return t.drawElement(e,n,r,!1,!1,a)},m=function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"main",a)},b=function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"source",a)},x=function(e,n,r,i,a){return t.drawElementText(e,n,r,i,"target",a)},w=function(e){return e.boundingBox(),e[0]._private.bodyBounds},E=function(e){return e.boundingBox(),e[0]._private.labelBounds.main||u},T=function(e){return e.boundingBox(),e[0]._private.labelBounds.source||u},_=function(e){return e.boundingBox(),e[0]._private.labelBounds.target||u},D=function(e,t){return t},C=function(e){return c(w(e))},N=function(e,t,n){var r=e?e+"-":"";return{x:t.x+n.pstyle(r+"text-margin-x").pfValue,y:t.y+n.pstyle(r+"text-margin-y").pfValue}},A=function(e,t,n){var r=e[0]._private.rscratch;return{x:r[t],y:r[n]}},L=function(e){return N("",A(e,"labelX","labelY"),e)},S=function(e){return N("source",A(e,"sourceLabelX","sourceLabelY"),e)},O=function(e){return N("target",A(e,"targetLabelX","targetLabelY"),e)},I=function(e){return h(w(e))},k=function(e){return h(T(e))},M=function(e){return h(_(e))},P=function(e){var t=E(e),n=h(E(e));if(e.isNode()){switch(e.pstyle("text-halign").value){case"left":n.x=-t.w;break;case"right":n.x=0}switch(e.pstyle("text-valign").value){case"top":n.y=-t.h;break;case"bottom":n.y=0}}return n},R=t.data.eleTxrCache=new jh(t,{getKey:p,doesEleInvalidateKey:d,drawElement:y,getBoundingBox:w,getRotationPoint:C,getRotationOffset:I,allowEdgeTxrCaching:!1,allowParentTxrCaching:!1}),F=t.data.lblTxrCache=new jh(t,{getKey:g,drawElement:m,getBoundingBox:E,getRotationPoint:L,getRotationOffset:P,isVisible:D}),z=t.data.slbTxrCache=new jh(t,{getKey:f,drawElement:b,getBoundingBox:T,getRotationPoint:S,getRotationOffset:k,isVisible:D}),G=t.data.tlbTxrCache=new jh(t,{getKey:v,drawElement:x,getBoundingBox:_,getRotationPoint:O,getRotationOffset:M,isVisible:D}),Y=t.data.lyrTxrCache=new sd(t);t.onUpdateEleCalcs((function(e,t){R.invalidateElements(t),F.invalidateElements(t),z.invalidateElements(t),G.invalidateElements(t),Y.invalidateElements(t);for(var n=0;n<t.length;n++){var r=t[n]._private;r.oldBackgroundTimestamp=r.backgroundTimestamp}}));var X=function(e){for(var t=0;t<e.length;t++)Y.enqueueElementRefinement(e[t].ele)};R.onDequeue(X),F.onDequeue(X),z.onDequeue(X),G.onDequeue(X)}qd.CANVAS_LAYERS=3,qd.SELECT_BOX=0,qd.DRAG=1,qd.NODE=2,qd.BUFFER_COUNT=3,qd.TEXTURE_BUFFER=0,qd.MOTIONBLUR_BUFFER_NODE=1,qd.MOTIONBLUR_BUFFER_DRAG=2,qd.redrawHint=function(e,t){var n=this;switch(e){case"eles":n.data.canvasNeedsRedraw[qd.NODE]=t;break;case"drag":n.data.canvasNeedsRedraw[qd.DRAG]=t;break;case"select":n.data.canvasNeedsRedraw[qd.SELECT_BOX]=t}};var $d="undefined"!=typeof Path2D;qd.path2dEnabled=function(e){if(void 0===e)return this.pathsEnabled;this.pathsEnabled=!!e},qd.usePaths=function(){return $d&&this.pathsEnabled},qd.setImgSmoothing=function(e,t){null!=e.imageSmoothingEnabled?e.imageSmoothingEnabled=t:(e.webkitImageSmoothingEnabled=t,e.mozImageSmoothingEnabled=t,e.msImageSmoothingEnabled=t)},qd.getImgSmoothing=function(e){return null!=e.imageSmoothingEnabled?e.imageSmoothingEnabled:e.webkitImageSmoothingEnabled||e.mozImageSmoothingEnabled||e.msImageSmoothingEnabled},qd.makeOffscreenCanvas=function(t,n){var r;return"undefined"!==("undefined"==typeof OffscreenCanvas?"undefined":e(OffscreenCanvas))?r=new OffscreenCanvas(t,n):((r=document.createElement("canvas")).width=t,r.height=n),r},[dd,md,Dd,Nd,Ad,Sd,Id,Md,Yd,jd].forEach((function(e){Q(qd,e)}));var Kd=[{type:"layout",extensions:qc},{type:"renderer",extensions:[{name:"null",impl:Wc},{name:"base",impl:xh},{name:"canvas",impl:Hd}]}],Zd={},Qd={};function Jd(e,t,n){var r=n,i=function(n){Nt("Can not register `"+t+"` for `"+e+"` since `"+n+"` already exists in the prototype and can not be overridden")};if("core"===e){if(ac.prototype[t])return i(t);ac.prototype[t]=n}else if("collection"===e){if(bu.prototype[t])return i(t);bu.prototype[t]=n}else if("layout"===e){for(var a=function(e){this.options=e,n.call(this,e),E(this._private)||(this._private={}),this._private.cy=e.cy,this._private.listeners=[],this.createEmitter()},o=a.prototype=Object.create(n.prototype),s=[],l=0;l<s.length;l++){var u=s[l];o[u]=o[u]||function(){return this}}o.start&&!o.run?o.run=function(){return this.start(),this}:!o.start&&o.run&&(o.start=function(){return this.run(),this});var c=n.prototype.stop;o.stop=function(){var e=this.options;if(e&&e.animate){var t=this.animations;if(t)for(var n=0;n<t.length;n++)t[n].stop()}return c?c.call(this):this.emit("layoutstop"),this},o.destroy||(o.destroy=function(){return this}),o.cy=function(){return this._private.cy};var h=function(e){return e._private.cy},d={addEventFields:function(e,t){t.layout=e,t.cy=h(e),t.target=e},bubble:function(){return!0},parent:function(e){return h(e)}};Q(o,{createEmitter:function(){return this._private.emitter=new Rl(d,this),this},emitter:function(){return this._private.emitter},on:function(e,t){return this.emitter().on(e,t),this},one:function(e,t){return this.emitter().one(e,t),this},once:function(e,t){return this.emitter().one(e,t),this},removeListener:function(e,t){return this.emitter().removeListener(e,t),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},emit:function(e,t){return this.emitter().emit(e,t),this}}),hs.eventAliasesOn(o),r=a}else if("renderer"===e&&"null"!==t&&"base"!==t){var p=ep("renderer","base"),g=p.prototype,f=n,v=n.prototype,y=function(){p.apply(this,arguments),f.apply(this,arguments)},m=y.prototype;for(var b in g){var x=g[b];if(null!=v[b])return i(b);m[b]=x}for(var w in v)m[w]=v[w];g.clientFunctions.forEach((function(e){m[e]=m[e]||function(){Dt("Renderer does not implement `renderer."+e+"()` on its prototype")}})),r=y}else if("__proto__"===e||"constructor"===e||"prototype"===e)return Dt(e+" is an illegal type to be registered, possibly lead to prototype pollutions");return ae({map:Zd,keys:[e,t],value:r})}function ep(e,t){return oe({map:Zd,keys:[e,t]})}function tp(e,t,n,r,i){return ae({map:Qd,keys:[e,t,n,r],value:i})}function np(e,t,n,r){return oe({map:Qd,keys:[e,t,n,r]})}var rp=function(){return 2===arguments.length?ep.apply(null,arguments):3===arguments.length?Jd.apply(null,arguments):4===arguments.length?np.apply(null,arguments):5===arguments.length?tp.apply(null,arguments):void Dt("Invalid extension access syntax")};ac.prototype.extension=rp,Kd.forEach((function(e){e.extensions.forEach((function(t){Jd(e.type,t.name,t.impl)}))}));var ip=function e(){if(!(this instanceof e))return new e;this.length=0},ap=ip.prototype;ap.instanceString=function(){return"stylesheet"},ap.selector=function(e){return this[this.length++]={selector:e,properties:[]},this},ap.css=function(e,t){var n=this.length-1;if(b(e))this[n].properties.push({name:e,value:t});else if(E(e))for(var r=e,i=Object.keys(r),a=0;a<i.length;a++){var o=i[a],s=r[o];if(null!=s){var l=Ju.properties[o]||Ju.properties[G(o)];if(null!=l){var u=l.name,c=s;this[n].properties.push({name:u,value:c})}}}return this},ap.style=ap.css,ap.generateStyle=function(e){var t=new Ju(e);return this.appendToStyle(t)},ap.appendToStyle=function(e){for(var t=0;t<this.length;t++){var n=this[t],r=n.selector,i=n.properties;e.selector(r);for(var a=0;a<i.length;a++){var o=i[a];e.css(o.name,o.value)}}return e};var op="3.27.0",sp=function(e){return void 0===e&&(e={}),E(e)?new ac(e):b(e)?rp.apply(rp,arguments):void 0};return sp.use=function(e){var t=Array.prototype.slice.call(arguments,1);return t.unshift(sp),e.apply(null,t),this},sp.warnings=function(e){return Ct(e)},sp.version=op,sp.stylesheet=sp.Stylesheet=ip,sp}()},82241:function(e){var t;t=function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=26)}([function(e,t,n){"use strict";function r(){}r.QUALITY=1,r.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,r.DEFAULT_INCREMENTAL=!1,r.DEFAULT_ANIMATION_ON_LAYOUT=!0,r.DEFAULT_ANIMATION_DURING_LAYOUT=!1,r.DEFAULT_ANIMATION_PERIOD=50,r.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,r.DEFAULT_GRAPH_MARGIN=15,r.NODE_DIMENSIONS_INCLUDE_LABELS=!1,r.SIMPLE_NODE_SIZE=40,r.SIMPLE_NODE_HALF_SIZE=r.SIMPLE_NODE_SIZE/2,r.EMPTY_COMPOUND_NODE_SIZE=40,r.MIN_EDGE_LENGTH=1,r.WORLD_BOUNDARY=1e6,r.INITIAL_WORLD_BOUNDARY=r.WORLD_BOUNDARY/1e3,r.WORLD_CENTER_X=1200,r.WORLD_CENTER_Y=900,e.exports=r},function(e,t,n){"use strict";var r=n(2),i=n(8),a=n(9);function o(e,t,n){r.call(this,n),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=n,this.bendpoints=[],this.source=e,this.target=t}for(var s in o.prototype=Object.create(r.prototype),r)o[s]=r[s];o.prototype.getSource=function(){return this.source},o.prototype.getTarget=function(){return this.target},o.prototype.isInterGraph=function(){return this.isInterGraph},o.prototype.getLength=function(){return this.length},o.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},o.prototype.getBendpoints=function(){return this.bendpoints},o.prototype.getLca=function(){return this.lca},o.prototype.getSourceInLca=function(){return this.sourceInLca},o.prototype.getTargetInLca=function(){return this.targetInLca},o.prototype.getOtherEnd=function(e){if(this.source===e)return this.target;if(this.target===e)return this.source;throw"Node is not incident with this edge"},o.prototype.getOtherEndInGraph=function(e,t){for(var n=this.getOtherEnd(e),r=t.getGraphManager().getRoot();;){if(n.getOwner()==t)return n;if(n.getOwner()==r)break;n=n.getOwner().getParent()}return null},o.prototype.updateLength=function(){var e=new Array(4);this.isOverlapingSourceAndTarget=i.getIntersection(this.target.getRect(),this.source.getRect(),e),this.isOverlapingSourceAndTarget||(this.lengthX=e[0]-e[2],this.lengthY=e[1]-e[3],Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},o.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=a.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=a.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},e.exports=o},function(e,t,n){"use strict";e.exports=function(e){this.vGraphObject=e}},function(e,t,n){"use strict";var r=n(2),i=n(10),a=n(13),o=n(0),s=n(16),l=n(4);function u(e,t,n,o){null==n&&null==o&&(o=t),r.call(this,o),null!=e.graphManager&&(e=e.graphManager),this.estimatedSize=i.MIN_VALUE,this.inclusionTreeDepth=i.MAX_VALUE,this.vGraphObject=o,this.edges=[],this.graphManager=e,this.rect=null!=n&&null!=t?new a(t.x,t.y,n.width,n.height):new a}for(var c in u.prototype=Object.create(r.prototype),r)u[c]=r[c];u.prototype.getEdges=function(){return this.edges},u.prototype.getChild=function(){return this.child},u.prototype.getOwner=function(){return this.owner},u.prototype.getWidth=function(){return this.rect.width},u.prototype.setWidth=function(e){this.rect.width=e},u.prototype.getHeight=function(){return this.rect.height},u.prototype.setHeight=function(e){this.rect.height=e},u.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},u.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},u.prototype.getCenter=function(){return new l(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},u.prototype.getLocation=function(){return new l(this.rect.x,this.rect.y)},u.prototype.getRect=function(){return this.rect},u.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},u.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},u.prototype.setRect=function(e,t){this.rect.x=e.x,this.rect.y=e.y,this.rect.width=t.width,this.rect.height=t.height},u.prototype.setCenter=function(e,t){this.rect.x=e-this.rect.width/2,this.rect.y=t-this.rect.height/2},u.prototype.setLocation=function(e,t){this.rect.x=e,this.rect.y=t},u.prototype.moveBy=function(e,t){this.rect.x+=e,this.rect.y+=t},u.prototype.getEdgeListToNode=function(e){var t=[],n=this;return n.edges.forEach((function(r){if(r.target==e){if(r.source!=n)throw"Incorrect edge source!";t.push(r)}})),t},u.prototype.getEdgesBetween=function(e){var t=[],n=this;return n.edges.forEach((function(r){if(r.source!=n&&r.target!=n)throw"Incorrect edge source and/or target";r.target!=e&&r.source!=e||t.push(r)})),t},u.prototype.getNeighborsList=function(){var e=new Set,t=this;return t.edges.forEach((function(n){if(n.source==t)e.add(n.target);else{if(n.target!=t)throw"Incorrect incidency!";e.add(n.source)}})),e},u.prototype.withChildren=function(){var e=new Set;if(e.add(this),null!=this.child)for(var t=this.child.getNodes(),n=0;n<t.length;n++)t[n].withChildren().forEach((function(t){e.add(t)}));return e},u.prototype.getNoOfChildren=function(){var e=0;if(null==this.child)e=1;else for(var t=this.child.getNodes(),n=0;n<t.length;n++)e+=t[n].getNoOfChildren();return 0==e&&(e=1),e},u.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},u.prototype.calcEstimatedSize=function(){return null==this.child?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},u.prototype.scatter=function(){var e,t,n=-o.INITIAL_WORLD_BOUNDARY,r=o.INITIAL_WORLD_BOUNDARY;e=o.WORLD_CENTER_X+s.nextDouble()*(r-n)+n;var i=-o.INITIAL_WORLD_BOUNDARY,a=o.INITIAL_WORLD_BOUNDARY;t=o.WORLD_CENTER_Y+s.nextDouble()*(a-i)+i,this.rect.x=e,this.rect.y=t},u.prototype.updateBounds=function(){if(null==this.getChild())throw"assert failed";if(0!=this.getChild().getNodes().length){var e=this.getChild();if(e.updateBounds(!0),this.rect.x=e.getLeft(),this.rect.y=e.getTop(),this.setWidth(e.getRight()-e.getLeft()),this.setHeight(e.getBottom()-e.getTop()),o.NODE_DIMENSIONS_INCLUDE_LABELS){var t=e.getRight()-e.getLeft(),n=e.getBottom()-e.getTop();this.labelWidth>t&&(this.rect.x-=(this.labelWidth-t)/2,this.setWidth(this.labelWidth)),this.labelHeight>n&&("center"==this.labelPos?this.rect.y-=(this.labelHeight-n)/2:"top"==this.labelPos&&(this.rect.y-=this.labelHeight-n),this.setHeight(this.labelHeight))}}},u.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==i.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},u.prototype.transform=function(e){var t=this.rect.x;t>o.WORLD_BOUNDARY?t=o.WORLD_BOUNDARY:t<-o.WORLD_BOUNDARY&&(t=-o.WORLD_BOUNDARY);var n=this.rect.y;n>o.WORLD_BOUNDARY?n=o.WORLD_BOUNDARY:n<-o.WORLD_BOUNDARY&&(n=-o.WORLD_BOUNDARY);var r=new l(t,n),i=e.inverseTransformPoint(r);this.setLocation(i.x,i.y)},u.prototype.getLeft=function(){return this.rect.x},u.prototype.getRight=function(){return this.rect.x+this.rect.width},u.prototype.getTop=function(){return this.rect.y},u.prototype.getBottom=function(){return this.rect.y+this.rect.height},u.prototype.getParent=function(){return null==this.owner?null:this.owner.getParent()},e.exports=u},function(e,t,n){"use strict";function r(e,t){null==e&&null==t?(this.x=0,this.y=0):(this.x=e,this.y=t)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.setX=function(e){this.x=e},r.prototype.setY=function(e){this.y=e},r.prototype.getDifference=function(e){return new DimensionD(this.x-e.x,this.y-e.y)},r.prototype.getCopy=function(){return new r(this.x,this.y)},r.prototype.translate=function(e){return this.x+=e.width,this.y+=e.height,this},e.exports=r},function(e,t,n){"use strict";var r=n(2),i=n(10),a=n(0),o=n(6),s=n(3),l=n(1),u=n(13),c=n(12),h=n(11);function d(e,t,n){r.call(this,n),this.estimatedSize=i.MIN_VALUE,this.margin=a.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=e,null!=t&&t instanceof o?this.graphManager=t:null!=t&&t instanceof Layout&&(this.graphManager=t.graphManager)}for(var p in d.prototype=Object.create(r.prototype),r)d[p]=r[p];d.prototype.getNodes=function(){return this.nodes},d.prototype.getEdges=function(){return this.edges},d.prototype.getGraphManager=function(){return this.graphManager},d.prototype.getParent=function(){return this.parent},d.prototype.getLeft=function(){return this.left},d.prototype.getRight=function(){return this.right},d.prototype.getTop=function(){return this.top},d.prototype.getBottom=function(){return this.bottom},d.prototype.isConnected=function(){return this.isConnected},d.prototype.add=function(e,t,n){if(null==t&&null==n){var r=e;if(null==this.graphManager)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(r)>-1)throw"Node already in graph!";return r.owner=this,this.getNodes().push(r),r}var i=e;if(!(this.getNodes().indexOf(t)>-1&&this.getNodes().indexOf(n)>-1))throw"Source or target not in graph!";if(t.owner!=n.owner||t.owner!=this)throw"Both owners must be this graph!";return t.owner!=n.owner?null:(i.source=t,i.target=n,i.isInterGraph=!1,this.getEdges().push(i),t.edges.push(i),n!=t&&n.edges.push(i),i)},d.prototype.remove=function(e){var t=e;if(e instanceof s){if(null==t)throw"Node is null!";if(null==t.owner||t.owner!=this)throw"Owner graph is invalid!";if(null==this.graphManager)throw"Owner graph manager is invalid!";for(var n=t.edges.slice(),r=n.length,i=0;i<r;i++)(a=n[i]).isInterGraph?this.graphManager.remove(a):a.source.owner.remove(a);if(-1==(o=this.nodes.indexOf(t)))throw"Node not in owner node list!";this.nodes.splice(o,1)}else if(e instanceof l){var a;if(null==(a=e))throw"Edge is null!";if(null==a.source||null==a.target)throw"Source and/or target is null!";if(null==a.source.owner||null==a.target.owner||a.source.owner!=this||a.target.owner!=this)throw"Source and/or target owner is invalid!";var o,u=a.source.edges.indexOf(a),c=a.target.edges.indexOf(a);if(!(u>-1&&c>-1))throw"Source and/or target doesn't know this edge!";if(a.source.edges.splice(u,1),a.target!=a.source&&a.target.edges.splice(c,1),-1==(o=a.source.owner.getEdges().indexOf(a)))throw"Not in owner's edge list!";a.source.owner.getEdges().splice(o,1)}},d.prototype.updateLeftTop=function(){for(var e,t,n,r=i.MAX_VALUE,a=i.MAX_VALUE,o=this.getNodes(),s=o.length,l=0;l<s;l++){var u=o[l];r>(e=u.getTop())&&(r=e),a>(t=u.getLeft())&&(a=t)}return r==i.MAX_VALUE?null:(n=null!=o[0].getParent().paddingLeft?o[0].getParent().paddingLeft:this.margin,this.left=a-n,this.top=r-n,new c(this.left,this.top))},d.prototype.updateBounds=function(e){for(var t,n,r,a,o,s=i.MAX_VALUE,l=-i.MAX_VALUE,c=i.MAX_VALUE,h=-i.MAX_VALUE,d=this.nodes,p=d.length,g=0;g<p;g++){var f=d[g];e&&null!=f.child&&f.updateBounds(),s>(t=f.getLeft())&&(s=t),l<(n=f.getRight())&&(l=n),c>(r=f.getTop())&&(c=r),h<(a=f.getBottom())&&(h=a)}var v=new u(s,c,l-s,h-c);s==i.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),o=null!=d[0].getParent().paddingLeft?d[0].getParent().paddingLeft:this.margin,this.left=v.x-o,this.right=v.x+v.width+o,this.top=v.y-o,this.bottom=v.y+v.height+o},d.calculateBounds=function(e){for(var t,n,r,a,o=i.MAX_VALUE,s=-i.MAX_VALUE,l=i.MAX_VALUE,c=-i.MAX_VALUE,h=e.length,d=0;d<h;d++){var p=e[d];o>(t=p.getLeft())&&(o=t),s<(n=p.getRight())&&(s=n),l>(r=p.getTop())&&(l=r),c<(a=p.getBottom())&&(c=a)}return new u(o,l,s-o,c-l)},d.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},d.prototype.getEstimatedSize=function(){if(this.estimatedSize==i.MIN_VALUE)throw"assert failed";return this.estimatedSize},d.prototype.calcEstimatedSize=function(){for(var e=0,t=this.nodes,n=t.length,r=0;r<n;r++)e+=t[r].calcEstimatedSize();return this.estimatedSize=0==e?a.EMPTY_COMPOUND_NODE_SIZE:e/Math.sqrt(this.nodes.length),this.estimatedSize},d.prototype.updateConnected=function(){var e=this;if(0!=this.nodes.length){var t,n,r=new h,i=new Set,a=this.nodes[0];for(a.withChildren().forEach((function(e){r.push(e),i.add(e)}));0!==r.length;)for(var o=(t=(a=r.shift()).getEdges()).length,s=0;s<o;s++)null==(n=t[s].getOtherEndInGraph(a,this))||i.has(n)||n.withChildren().forEach((function(e){r.push(e),i.add(e)}));if(this.isConnected=!1,i.size>=this.nodes.length){var l=0;i.forEach((function(t){t.owner==e&&l++})),l==this.nodes.length&&(this.isConnected=!0)}}else this.isConnected=!0},e.exports=d},function(e,t,n){"use strict";var r,i=n(1);function a(e){r=n(5),this.layout=e,this.graphs=[],this.edges=[]}a.prototype.addRoot=function(){var e=this.layout.newGraph(),t=this.layout.newNode(null),n=this.add(e,t);return this.setRootGraph(n),this.rootGraph},a.prototype.add=function(e,t,n,r,i){if(null==n&&null==r&&null==i){if(null==e)throw"Graph is null!";if(null==t)throw"Parent node is null!";if(this.graphs.indexOf(e)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(e),null!=e.parent)throw"Already has a parent!";if(null!=t.child)throw"Already has a child!";return e.parent=t,t.child=e,e}i=n,n=e;var a=(r=t).getOwner(),o=i.getOwner();if(null==a||a.getGraphManager()!=this)throw"Source not in this graph mgr!";if(null==o||o.getGraphManager()!=this)throw"Target not in this graph mgr!";if(a==o)return n.isInterGraph=!1,a.add(n,r,i);if(n.isInterGraph=!0,n.source=r,n.target=i,this.edges.indexOf(n)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(n),null==n.source||null==n.target)throw"Edge source and/or target is null!";if(-1!=n.source.edges.indexOf(n)||-1!=n.target.edges.indexOf(n))throw"Edge already in source and/or target incidency list!";return n.source.edges.push(n),n.target.edges.push(n),n},a.prototype.remove=function(e){if(e instanceof r){var t=e;if(t.getGraphManager()!=this)throw"Graph not in this graph mgr";if(t!=this.rootGraph&&(null==t.parent||t.parent.graphManager!=this))throw"Invalid parent node!";for(var n,a=[],o=(a=a.concat(t.getEdges())).length,s=0;s<o;s++)n=a[s],t.remove(n);var l,u=[];for(o=(u=u.concat(t.getNodes())).length,s=0;s<o;s++)l=u[s],t.remove(l);t==this.rootGraph&&this.setRootGraph(null);var c=this.graphs.indexOf(t);this.graphs.splice(c,1),t.parent=null}else if(e instanceof i){if(null==(n=e))throw"Edge is null!";if(!n.isInterGraph)throw"Not an inter-graph edge!";if(null==n.source||null==n.target)throw"Source and/or target is null!";if(-1==n.source.edges.indexOf(n)||-1==n.target.edges.indexOf(n))throw"Source and/or target doesn't know this edge!";if(c=n.source.edges.indexOf(n),n.source.edges.splice(c,1),c=n.target.edges.indexOf(n),n.target.edges.splice(c,1),null==n.source.owner||null==n.source.owner.getGraphManager())throw"Edge owner graph or owner graph manager is null!";if(-1==n.source.owner.getGraphManager().edges.indexOf(n))throw"Not in owner graph manager's edge list!";c=n.source.owner.getGraphManager().edges.indexOf(n),n.source.owner.getGraphManager().edges.splice(c,1)}},a.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},a.prototype.getGraphs=function(){return this.graphs},a.prototype.getAllNodes=function(){if(null==this.allNodes){for(var e=[],t=this.getGraphs(),n=t.length,r=0;r<n;r++)e=e.concat(t[r].getNodes());this.allNodes=e}return this.allNodes},a.prototype.resetAllNodes=function(){this.allNodes=null},a.prototype.resetAllEdges=function(){this.allEdges=null},a.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},a.prototype.getAllEdges=function(){if(null==this.allEdges){for(var e=[],t=this.getGraphs(),n=(t.length,0);n<t.length;n++)e=e.concat(t[n].getEdges());e=e.concat(this.edges),this.allEdges=e}return this.allEdges},a.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},a.prototype.setAllNodesToApplyGravitation=function(e){if(null!=this.allNodesToApplyGravitation)throw"assert failed";this.allNodesToApplyGravitation=e},a.prototype.getRoot=function(){return this.rootGraph},a.prototype.setRootGraph=function(e){if(e.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=e,null==e.parent&&(e.parent=this.layout.newNode("Root node"))},a.prototype.getLayout=function(){return this.layout},a.prototype.isOneAncestorOfOther=function(e,t){if(null==e||null==t)throw"assert failed";if(e==t)return!0;for(var n,r=e.getOwner();null!=(n=r.getParent());){if(n==t)return!0;if(null==(r=n.getOwner()))break}for(r=t.getOwner();null!=(n=r.getParent());){if(n==e)return!0;if(null==(r=n.getOwner()))break}return!1},a.prototype.calcLowestCommonAncestors=function(){for(var e,t,n,r,i,a=this.getAllEdges(),o=a.length,s=0;s<o;s++)if(t=(e=a[s]).source,n=e.target,e.lca=null,e.sourceInLca=t,e.targetInLca=n,t!=n){for(r=t.getOwner();null==e.lca;){for(e.targetInLca=n,i=n.getOwner();null==e.lca;){if(i==r){e.lca=i;break}if(i==this.rootGraph)break;if(null!=e.lca)throw"assert failed";e.targetInLca=i.getParent(),i=e.targetInLca.getOwner()}if(r==this.rootGraph)break;null==e.lca&&(e.sourceInLca=r.getParent(),r=e.sourceInLca.getOwner())}if(null==e.lca)throw"assert failed"}else e.lca=t.getOwner()},a.prototype.calcLowestCommonAncestor=function(e,t){if(e==t)return e.getOwner();for(var n=e.getOwner();null!=n;){for(var r=t.getOwner();null!=r;){if(r==n)return r;r=r.getParent().getOwner()}n=n.getParent().getOwner()}return n},a.prototype.calcInclusionTreeDepths=function(e,t){var n;null==e&&null==t&&(e=this.rootGraph,t=1);for(var r=e.getNodes(),i=r.length,a=0;a<i;a++)(n=r[a]).inclusionTreeDepth=t,null!=n.child&&this.calcInclusionTreeDepths(n.child,t+1)},a.prototype.includesInvalidEdge=function(){for(var e,t=this.edges.length,n=0;n<t;n++)if(e=this.edges[n],this.isOneAncestorOfOther(e.source,e.target))return!0;return!1},e.exports=a},function(e,t,n){"use strict";var r=n(0);function i(){}for(var a in r)i[a]=r[a];i.MAX_ITERATIONS=2500,i.DEFAULT_EDGE_LENGTH=50,i.DEFAULT_SPRING_STRENGTH=.45,i.DEFAULT_REPULSION_STRENGTH=4500,i.DEFAULT_GRAVITY_STRENGTH=.4,i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,i.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,i.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,i.COOLING_ADAPTATION_FACTOR=.33,i.ADAPTATION_LOWER_NODE_LIMIT=1e3,i.ADAPTATION_UPPER_NODE_LIMIT=5e3,i.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,i.MAX_NODE_DISPLACEMENT=3*i.MAX_NODE_DISPLACEMENT_INCREMENTAL,i.MIN_REPULSION_DIST=i.DEFAULT_EDGE_LENGTH/10,i.CONVERGENCE_CHECK_PERIOD=100,i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,i.MIN_EDGE_LENGTH=1,i.GRID_CALCULATION_CHECK_PERIOD=10,e.exports=i},function(e,t,n){"use strict";var r=n(12);function i(){}i.calcSeparationAmount=function(e,t,n,r){if(!e.intersects(t))throw"assert failed";var i=new Array(2);this.decideDirectionsForOverlappingNodes(e,t,i),n[0]=Math.min(e.getRight(),t.getRight())-Math.max(e.x,t.x),n[1]=Math.min(e.getBottom(),t.getBottom())-Math.max(e.y,t.y),e.getX()<=t.getX()&&e.getRight()>=t.getRight()?n[0]+=Math.min(t.getX()-e.getX(),e.getRight()-t.getRight()):t.getX()<=e.getX()&&t.getRight()>=e.getRight()&&(n[0]+=Math.min(e.getX()-t.getX(),t.getRight()-e.getRight())),e.getY()<=t.getY()&&e.getBottom()>=t.getBottom()?n[1]+=Math.min(t.getY()-e.getY(),e.getBottom()-t.getBottom()):t.getY()<=e.getY()&&t.getBottom()>=e.getBottom()&&(n[1]+=Math.min(e.getY()-t.getY(),t.getBottom()-e.getBottom()));var a=Math.abs((t.getCenterY()-e.getCenterY())/(t.getCenterX()-e.getCenterX()));t.getCenterY()===e.getCenterY()&&t.getCenterX()===e.getCenterX()&&(a=1);var o=a*n[0],s=n[1]/a;n[0]<s?s=n[0]:o=n[1],n[0]=-1*i[0]*(s/2+r),n[1]=-1*i[1]*(o/2+r)},i.decideDirectionsForOverlappingNodes=function(e,t,n){e.getCenterX()<t.getCenterX()?n[0]=-1:n[0]=1,e.getCenterY()<t.getCenterY()?n[1]=-1:n[1]=1},i.getIntersection2=function(e,t,n){var r=e.getCenterX(),i=e.getCenterY(),a=t.getCenterX(),o=t.getCenterY();if(e.intersects(t))return n[0]=r,n[1]=i,n[2]=a,n[3]=o,!0;var s=e.getX(),l=e.getY(),u=e.getRight(),c=e.getX(),h=e.getBottom(),d=e.getRight(),p=e.getWidthHalf(),g=e.getHeightHalf(),f=t.getX(),v=t.getY(),y=t.getRight(),m=t.getX(),b=t.getBottom(),x=t.getRight(),w=t.getWidthHalf(),E=t.getHeightHalf(),T=!1,_=!1;if(r===a){if(i>o)return n[0]=r,n[1]=l,n[2]=a,n[3]=b,!1;if(i<o)return n[0]=r,n[1]=h,n[2]=a,n[3]=v,!1}else if(i===o){if(r>a)return n[0]=s,n[1]=i,n[2]=y,n[3]=o,!1;if(r<a)return n[0]=u,n[1]=i,n[2]=f,n[3]=o,!1}else{var D=e.height/e.width,C=t.height/t.width,N=(o-i)/(a-r),A=void 0,L=void 0,S=void 0,O=void 0,I=void 0,k=void 0;if(-D===N?r>a?(n[0]=c,n[1]=h,T=!0):(n[0]=u,n[1]=l,T=!0):D===N&&(r>a?(n[0]=s,n[1]=l,T=!0):(n[0]=d,n[1]=h,T=!0)),-C===N?a>r?(n[2]=m,n[3]=b,_=!0):(n[2]=y,n[3]=v,_=!0):C===N&&(a>r?(n[2]=f,n[3]=v,_=!0):(n[2]=x,n[3]=b,_=!0)),T&&_)return!1;if(r>a?i>o?(A=this.getCardinalDirection(D,N,4),L=this.getCardinalDirection(C,N,2)):(A=this.getCardinalDirection(-D,N,3),L=this.getCardinalDirection(-C,N,1)):i>o?(A=this.getCardinalDirection(-D,N,1),L=this.getCardinalDirection(-C,N,3)):(A=this.getCardinalDirection(D,N,2),L=this.getCardinalDirection(C,N,4)),!T)switch(A){case 1:O=l,S=r+-g/N,n[0]=S,n[1]=O;break;case 2:S=d,O=i+p*N,n[0]=S,n[1]=O;break;case 3:O=h,S=r+g/N,n[0]=S,n[1]=O;break;case 4:S=c,O=i+-p*N,n[0]=S,n[1]=O}if(!_)switch(L){case 1:k=v,I=a+-E/N,n[2]=I,n[3]=k;break;case 2:I=x,k=o+w*N,n[2]=I,n[3]=k;break;case 3:k=b,I=a+E/N,n[2]=I,n[3]=k;break;case 4:I=m,k=o+-w*N,n[2]=I,n[3]=k}}return!1},i.getCardinalDirection=function(e,t,n){return e>t?n:1+n%4},i.getIntersection=function(e,t,n,i){if(null==i)return this.getIntersection2(e,t,n);var a,o,s,l,u,c,h,d=e.x,p=e.y,g=t.x,f=t.y,v=n.x,y=n.y,m=i.x,b=i.y;return 0==(h=(a=f-p)*(l=v-m)-(o=b-y)*(s=d-g))?null:new r((s*(c=m*y-v*b)-l*(u=g*p-d*f))/h,(o*u-a*c)/h)},i.angleOfVector=function(e,t,n,r){var i=void 0;return e!==n?(i=Math.atan((r-t)/(n-e)),n<e?i+=Math.PI:r<t&&(i+=this.TWO_PI)):i=r<t?this.ONE_AND_HALF_PI:this.HALF_PI,i},i.doIntersect=function(e,t,n,r){var i=e.x,a=e.y,o=t.x,s=t.y,l=n.x,u=n.y,c=r.x,h=r.y,d=(o-i)*(h-u)-(c-l)*(s-a);if(0===d)return!1;var p=((h-u)*(c-i)+(l-c)*(h-a))/d,g=((a-s)*(c-i)+(o-i)*(h-a))/d;return 0<p&&p<1&&0<g&&g<1},i.HALF_PI=.5*Math.PI,i.ONE_AND_HALF_PI=1.5*Math.PI,i.TWO_PI=2*Math.PI,i.THREE_PI=3*Math.PI,e.exports=i},function(e,t,n){"use strict";function r(){}r.sign=function(e){return e>0?1:e<0?-1:0},r.floor=function(e){return e<0?Math.ceil(e):Math.floor(e)},r.ceil=function(e){return e<0?Math.floor(e):Math.ceil(e)},e.exports=r},function(e,t,n){"use strict";function r(){}r.MAX_VALUE=2147483647,r.MIN_VALUE=-2147483648,e.exports=r},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=function(e){return{value:e,next:null,prev:null}},a=function(e,t,n,r){return null!==e?e.next=t:r.head=t,null!==n?n.prev=t:r.tail=t,t.prev=e,t.next=n,r.length++,t},o=function(e,t){var n=e.prev,r=e.next;return null!==n?n.next=r:t.head=r,null!==r?r.prev=n:t.tail=n,e.prev=e.next=null,t.length--,e},s=function(){function e(t){var n=this;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.length=0,this.head=null,this.tail=null,null!=t&&t.forEach((function(e){return n.push(e)}))}return r(e,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(e,t){return a(t.prev,i(e),t,this)}},{key:"insertAfter",value:function(e,t){return a(t,i(e),t.next,this)}},{key:"insertNodeBefore",value:function(e,t){return a(t.prev,e,t,this)}},{key:"insertNodeAfter",value:function(e,t){return a(t,e,t.next,this)}},{key:"push",value:function(e){return a(this.tail,i(e),null,this)}},{key:"unshift",value:function(e){return a(null,i(e),this.head,this)}},{key:"remove",value:function(e){return o(e,this)}},{key:"pop",value:function(){return o(this.tail,this).value}},{key:"popNode",value:function(){return o(this.tail,this)}},{key:"shift",value:function(){return o(this.head,this).value}},{key:"shiftNode",value:function(){return o(this.head,this)}},{key:"get_object_at",value:function(e){if(e<=this.length()){for(var t=1,n=this.head;t<e;)n=n.next,t++;return n.value}}},{key:"set_object_at",value:function(e,t){if(e<=this.length()){for(var n=1,r=this.head;n<e;)r=r.next,n++;r.value=t}}}]),e}();e.exports=s},function(e,t,n){"use strict";function r(e,t,n){this.x=null,this.y=null,null==e&&null==t&&null==n?(this.x=0,this.y=0):"number"==typeof e&&"number"==typeof t&&null==n?(this.x=e,this.y=t):"Point"==e.constructor.name&&null==t&&null==n&&(n=e,this.x=n.x,this.y=n.y)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.getLocation=function(){return new r(this.x,this.y)},r.prototype.setLocation=function(e,t,n){"Point"==e.constructor.name&&null==t&&null==n?(n=e,this.setLocation(n.x,n.y)):"number"==typeof e&&"number"==typeof t&&null==n&&(parseInt(e)==e&&parseInt(t)==t?this.move(e,t):(this.x=Math.floor(e+.5),this.y=Math.floor(t+.5)))},r.prototype.move=function(e,t){this.x=e,this.y=t},r.prototype.translate=function(e,t){this.x+=e,this.y+=t},r.prototype.equals=function(e){if("Point"==e.constructor.name){var t=e;return this.x==t.x&&this.y==t.y}return this==e},r.prototype.toString=function(){return(new r).constructor.name+"[x="+this.x+",y="+this.y+"]"},e.exports=r},function(e,t,n){"use strict";function r(e,t,n,r){this.x=0,this.y=0,this.width=0,this.height=0,null!=e&&null!=t&&null!=n&&null!=r&&(this.x=e,this.y=t,this.width=n,this.height=r)}r.prototype.getX=function(){return this.x},r.prototype.setX=function(e){this.x=e},r.prototype.getY=function(){return this.y},r.prototype.setY=function(e){this.y=e},r.prototype.getWidth=function(){return this.width},r.prototype.setWidth=function(e){this.width=e},r.prototype.getHeight=function(){return this.height},r.prototype.setHeight=function(e){this.height=e},r.prototype.getRight=function(){return this.x+this.width},r.prototype.getBottom=function(){return this.y+this.height},r.prototype.intersects=function(e){return!(this.getRight()<e.x||this.getBottom()<e.y||e.getRight()<this.x||e.getBottom()<this.y)},r.prototype.getCenterX=function(){return this.x+this.width/2},r.prototype.getMinX=function(){return this.getX()},r.prototype.getMaxX=function(){return this.getX()+this.width},r.prototype.getCenterY=function(){return this.y+this.height/2},r.prototype.getMinY=function(){return this.getY()},r.prototype.getMaxY=function(){return this.getY()+this.height},r.prototype.getWidthHalf=function(){return this.width/2},r.prototype.getHeightHalf=function(){return this.height/2},e.exports=r},function(e,t,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};function i(){}i.lastID=0,i.createID=function(e){return i.isPrimitive(e)?e:(null!=e.uniqueID||(e.uniqueID=i.getString(),i.lastID++),e.uniqueID)},i.getString=function(e){return null==e&&(e=i.lastID),"Object#"+e},i.isPrimitive=function(e){var t=void 0===e?"undefined":r(e);return null==e||"object"!=t&&"function"!=t},e.exports=i},function(e,t,n){"use strict";function r(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}var i=n(0),a=n(6),o=n(3),s=n(1),l=n(5),u=n(4),c=n(17),h=n(27);function d(e){h.call(this),this.layoutQuality=i.QUALITY,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=i.DEFAULT_INCREMENTAL,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new a(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,null!=e&&(this.isRemoteUse=e)}d.RANDOM_SEED=1,d.prototype=Object.create(h.prototype),d.prototype.getGraphManager=function(){return this.graphManager},d.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},d.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},d.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},d.prototype.newGraphManager=function(){var e=new a(this);return this.graphManager=e,e},d.prototype.newGraph=function(e){return new l(null,this.graphManager,e)},d.prototype.newNode=function(e){return new o(this.graphManager,e)},d.prototype.newEdge=function(e){return new s(null,null,e)},d.prototype.checkLayoutSuccess=function(){return null==this.graphManager.getRoot()||0==this.graphManager.getRoot().getNodes().length||this.graphManager.includesInvalidEdge()},d.prototype.runLayout=function(){var e;return this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters(),e=!this.checkLayoutSuccess()&&this.layout(),"during"!==i.ANIMATE&&(e&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,e)},d.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},d.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var e=this.graphManager.getAllEdges(),t=0;t<e.length;t++)e[t];var n=this.graphManager.getRoot().getNodes();for(t=0;t<n.length;t++)n[t];this.update(this.graphManager.getRoot())}},d.prototype.update=function(e){if(null==e)this.update2();else if(e instanceof o){var t=e;if(null!=t.getChild())for(var n=t.getChild().getNodes(),r=0;r<n.length;r++)update(n[r]);null!=t.vGraphObject&&t.vGraphObject.update(t)}else if(e instanceof s){var i=e;null!=i.vGraphObject&&i.vGraphObject.update(i)}else if(e instanceof l){var a=e;null!=a.vGraphObject&&a.vGraphObject.update(a)}},d.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=i.QUALITY,this.animationDuringLayout=i.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=i.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=i.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=i.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=i.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=i.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},d.prototype.transform=function(e){if(null==e)this.transform(new u(0,0));else{var t=new c,n=this.graphManager.getRoot().updateLeftTop();if(null!=n){t.setWorldOrgX(e.x),t.setWorldOrgY(e.y),t.setDeviceOrgX(n.x),t.setDeviceOrgY(n.y);for(var r=this.getAllNodes(),i=0;i<r.length;i++)r[i].transform(t)}}},d.prototype.positionNodesRandomly=function(e){if(null==e)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var t,n,r=e.getNodes(),i=0;i<r.length;i++)null==(n=(t=r[i]).getChild())||0==n.getNodes().length?t.scatter():(this.positionNodesRandomly(n),t.updateBounds())},d.prototype.getFlatForest=function(){for(var e=[],t=!0,n=this.graphManager.getRoot().getNodes(),i=!0,a=0;a<n.length;a++)null!=n[a].getChild()&&(i=!1);if(!i)return e;var o=new Set,s=[],l=new Map,u=[];for(u=u.concat(n);u.length>0&&t;){for(s.push(u[0]);s.length>0&&t;){var c=s[0];s.splice(0,1),o.add(c);var h=c.getEdges();for(a=0;a<h.length;a++){var d=h[a].getOtherEnd(c);if(l.get(c)!=d){if(o.has(d)){t=!1;break}s.push(d),l.set(d,c)}}}if(t){var p=[].concat(r(o));for(e.push(p),a=0;a<p.length;a++){var g=p[a],f=u.indexOf(g);f>-1&&u.splice(f,1)}o=new Set,l=new Map}else e=[]}return e},d.prototype.createDummyNodesForBendpoints=function(e){for(var t=[],n=e.source,r=this.graphManager.calcLowestCommonAncestor(e.source,e.target),i=0;i<e.bendpoints.length;i++){var a=this.newNode(null);a.setRect(new Point(0,0),new Dimension(1,1)),r.add(a);var o=this.newEdge(null);this.graphManager.add(o,n,a),t.add(a),n=a}return o=this.newEdge(null),this.graphManager.add(o,n,e.target),this.edgeToDummyNodes.set(e,t),e.isInterGraph()?this.graphManager.remove(e):r.remove(e),t},d.prototype.createBendpointsFromDummyNodes=function(){var e=[];e=e.concat(this.graphManager.getAllEdges()),e=[].concat(r(this.edgeToDummyNodes.keys())).concat(e);for(var t=0;t<e.length;t++){var n=e[t];if(n.bendpoints.length>0){for(var i=this.edgeToDummyNodes.get(n),a=0;a<i.length;a++){var o=i[a],s=new u(o.getCenterX(),o.getCenterY()),l=n.bendpoints.get(a);l.x=s.x,l.y=s.y,o.getOwner().remove(o)}this.graphManager.add(n,n.source,n.target)}}},d.transform=function(e,t,n,r){if(null!=n&&null!=r){var i=t;return e<=50?i-=(t-t/n)/50*(50-e):i+=(t*r-t)/50*(e-50),i}var a,o;return e<=50?(a=9*t/500,o=t/10):(a=9*t/50,o=-8*t),a*e+o},d.findCenterOfTree=function(e){var t=[];t=t.concat(e);var n=[],r=new Map,i=!1,a=null;1!=t.length&&2!=t.length||(i=!0,a=t[0]);for(var o=0;o<t.length;o++){var s=(c=t[o]).getNeighborsList().size;r.set(c,c.getNeighborsList().size),1==s&&n.push(c)}var l=[];for(l=l.concat(n);!i;){var u=[];for(u=u.concat(l),l=[],o=0;o<t.length;o++){var c=t[o],h=t.indexOf(c);h>=0&&t.splice(h,1),c.getNeighborsList().forEach((function(e){if(n.indexOf(e)<0){var t=r.get(e)-1;1==t&&l.push(e),r.set(e,t)}}))}n=n.concat(l),1!=t.length&&2!=t.length||(i=!0,a=t[0])}return a},d.prototype.setGraphManager=function(e){this.graphManager=e},e.exports=d},function(e,t,n){"use strict";function r(){}r.seed=1,r.x=0,r.nextDouble=function(){return r.x=1e4*Math.sin(r.seed++),r.x-Math.floor(r.x)},e.exports=r},function(e,t,n){"use strict";var r=n(4);function i(e,t){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}i.prototype.getWorldOrgX=function(){return this.lworldOrgX},i.prototype.setWorldOrgX=function(e){this.lworldOrgX=e},i.prototype.getWorldOrgY=function(){return this.lworldOrgY},i.prototype.setWorldOrgY=function(e){this.lworldOrgY=e},i.prototype.getWorldExtX=function(){return this.lworldExtX},i.prototype.setWorldExtX=function(e){this.lworldExtX=e},i.prototype.getWorldExtY=function(){return this.lworldExtY},i.prototype.setWorldExtY=function(e){this.lworldExtY=e},i.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},i.prototype.setDeviceOrgX=function(e){this.ldeviceOrgX=e},i.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},i.prototype.setDeviceOrgY=function(e){this.ldeviceOrgY=e},i.prototype.getDeviceExtX=function(){return this.ldeviceExtX},i.prototype.setDeviceExtX=function(e){this.ldeviceExtX=e},i.prototype.getDeviceExtY=function(){return this.ldeviceExtY},i.prototype.setDeviceExtY=function(e){this.ldeviceExtY=e},i.prototype.transformX=function(e){var t=0,n=this.lworldExtX;return 0!=n&&(t=this.ldeviceOrgX+(e-this.lworldOrgX)*this.ldeviceExtX/n),t},i.prototype.transformY=function(e){var t=0,n=this.lworldExtY;return 0!=n&&(t=this.ldeviceOrgY+(e-this.lworldOrgY)*this.ldeviceExtY/n),t},i.prototype.inverseTransformX=function(e){var t=0,n=this.ldeviceExtX;return 0!=n&&(t=this.lworldOrgX+(e-this.ldeviceOrgX)*this.lworldExtX/n),t},i.prototype.inverseTransformY=function(e){var t=0,n=this.ldeviceExtY;return 0!=n&&(t=this.lworldOrgY+(e-this.ldeviceOrgY)*this.lworldExtY/n),t},i.prototype.inverseTransformPoint=function(e){return new r(this.inverseTransformX(e.x),this.inverseTransformY(e.y))},e.exports=i},function(e,t,n){"use strict";var r=n(15),i=n(7),a=n(0),o=n(8),s=n(9);function l(){r.call(this),this.useSmartIdealEdgeLengthCalculation=i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=i.DEFAULT_EDGE_LENGTH,this.springConstant=i.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=i.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=i.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=i.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*i.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=i.MAX_ITERATIONS}for(var u in l.prototype=Object.create(r.prototype),r)l[u]=r[u];l.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},l.prototype.calcIdealEdgeLengths=function(){for(var e,t,n,r,o,s,l=this.getGraphManager().getAllEdges(),u=0;u<l.length;u++)(e=l[u]).idealLength=this.idealEdgeLength,e.isInterGraph&&(n=e.getSource(),r=e.getTarget(),o=e.getSourceInLca().getEstimatedSize(),s=e.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(e.idealLength+=o+s-2*a.SIMPLE_NODE_SIZE),t=e.getLca().getInclusionTreeDepth(),e.idealLength+=i.DEFAULT_EDGE_LENGTH*i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(n.getInclusionTreeDepth()+r.getInclusionTreeDepth()-2*t))},l.prototype.initSpringEmbedder=function(){var e=this.getAllNodes().length;this.incremental?(e>i.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*i.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(e-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-i.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT_INCREMENTAL):(e>i.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(i.COOLING_ADAPTATION_FACTOR,1-(e-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*(1-i.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(5*this.getAllNodes().length,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},l.prototype.calcSpringForces=function(){for(var e,t=this.getAllEdges(),n=0;n<t.length;n++)e=t[n],this.calcSpringForce(e,e.idealLength)},l.prototype.calcRepulsionForces=function(){var e,t,n,r,a,o=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],s=arguments.length>1&&void 0!==arguments[1]&&arguments[1],l=this.getAllNodes();if(this.useFRGridVariant)for(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&o&&this.updateGrid(),a=new Set,e=0;e<l.length;e++)n=l[e],this.calculateRepulsionForceOfANode(n,a,o,s),a.add(n);else for(e=0;e<l.length;e++)for(n=l[e],t=e+1;t<l.length;t++)r=l[t],n.getOwner()==r.getOwner()&&this.calcRepulsionForce(n,r)},l.prototype.calcGravitationalForces=function(){for(var e,t=this.getAllNodesToApplyGravitation(),n=0;n<t.length;n++)e=t[n],this.calcGravitationalForce(e)},l.prototype.moveNodes=function(){for(var e=this.getAllNodes(),t=0;t<e.length;t++)e[t].move()},l.prototype.calcSpringForce=function(e,t){var n,r,i,a,o=e.getSource(),s=e.getTarget();if(this.uniformLeafNodeSizes&&null==o.getChild()&&null==s.getChild())e.updateLengthSimple();else if(e.updateLength(),e.isOverlapingSourceAndTarget)return;0!=(n=e.getLength())&&(i=(r=this.springConstant*(n-t))*(e.lengthX/n),a=r*(e.lengthY/n),o.springForceX+=i,o.springForceY+=a,s.springForceX-=i,s.springForceY-=a)},l.prototype.calcRepulsionForce=function(e,t){var n,r,a,l,u,c,h,d=e.getRect(),p=t.getRect(),g=new Array(2),f=new Array(4);if(d.intersects(p)){o.calcSeparationAmount(d,p,g,i.DEFAULT_EDGE_LENGTH/2),c=2*g[0],h=2*g[1];var v=e.noOfChildren*t.noOfChildren/(e.noOfChildren+t.noOfChildren);e.repulsionForceX-=v*c,e.repulsionForceY-=v*h,t.repulsionForceX+=v*c,t.repulsionForceY+=v*h}else this.uniformLeafNodeSizes&&null==e.getChild()&&null==t.getChild()?(n=p.getCenterX()-d.getCenterX(),r=p.getCenterY()-d.getCenterY()):(o.getIntersection(d,p,f),n=f[2]-f[0],r=f[3]-f[1]),Math.abs(n)<i.MIN_REPULSION_DIST&&(n=s.sign(n)*i.MIN_REPULSION_DIST),Math.abs(r)<i.MIN_REPULSION_DIST&&(r=s.sign(r)*i.MIN_REPULSION_DIST),a=n*n+r*r,l=Math.sqrt(a),c=(u=this.repulsionConstant*e.noOfChildren*t.noOfChildren/a)*n/l,h=u*r/l,e.repulsionForceX-=c,e.repulsionForceY-=h,t.repulsionForceX+=c,t.repulsionForceY+=h},l.prototype.calcGravitationalForce=function(e){var t,n,r,i,a,o,s,l;n=((t=e.getOwner()).getRight()+t.getLeft())/2,r=(t.getTop()+t.getBottom())/2,i=e.getCenterX()-n,a=e.getCenterY()-r,o=Math.abs(i)+e.getWidth()/2,s=Math.abs(a)+e.getHeight()/2,e.getOwner()==this.graphManager.getRoot()?(o>(l=t.getEstimatedSize()*this.gravityRangeFactor)||s>l)&&(e.gravitationForceX=-this.gravityConstant*i,e.gravitationForceY=-this.gravityConstant*a):(o>(l=t.getEstimatedSize()*this.compoundGravityRangeFactor)||s>l)&&(e.gravitationForceX=-this.gravityConstant*i*this.compoundGravityConstant,e.gravitationForceY=-this.gravityConstant*a*this.compoundGravityConstant)},l.prototype.isConverged=function(){var e,t=!1;return this.totalIterations>this.maxIterations/3&&(t=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),e=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,e||t},l.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},l.prototype.calcNoOfChildrenForAllNodes=function(){for(var e,t=this.graphManager.getAllNodes(),n=0;n<t.length;n++)(e=t[n]).noOfChildren=e.getNoOfChildren()},l.prototype.calcGrid=function(e){var t,n;t=parseInt(Math.ceil((e.getRight()-e.getLeft())/this.repulsionRange)),n=parseInt(Math.ceil((e.getBottom()-e.getTop())/this.repulsionRange));for(var r=new Array(t),i=0;i<t;i++)r[i]=new Array(n);for(i=0;i<t;i++)for(var a=0;a<n;a++)r[i][a]=new Array;return r},l.prototype.addNodeToGrid=function(e,t,n){var r,i,a,o;r=parseInt(Math.floor((e.getRect().x-t)/this.repulsionRange)),i=parseInt(Math.floor((e.getRect().width+e.getRect().x-t)/this.repulsionRange)),a=parseInt(Math.floor((e.getRect().y-n)/this.repulsionRange)),o=parseInt(Math.floor((e.getRect().height+e.getRect().y-n)/this.repulsionRange));for(var s=r;s<=i;s++)for(var l=a;l<=o;l++)this.grid[s][l].push(e),e.setGridCoordinates(r,i,a,o)},l.prototype.updateGrid=function(){var e,t,n=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),e=0;e<n.length;e++)t=n[e],this.addNodeToGrid(t,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},l.prototype.calculateRepulsionForceOfANode=function(e,t,n,r){if(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&n||r){var a,o=new Set;e.surrounding=new Array;for(var s=this.grid,l=e.startX-1;l<e.finishX+2;l++)for(var u=e.startY-1;u<e.finishY+2;u++)if(!(l<0||u<0||l>=s.length||u>=s[0].length))for(var c=0;c<s[l][u].length;c++)if(a=s[l][u][c],e.getOwner()==a.getOwner()&&e!=a&&!t.has(a)&&!o.has(a)){var h=Math.abs(e.getCenterX()-a.getCenterX())-(e.getWidth()/2+a.getWidth()/2),d=Math.abs(e.getCenterY()-a.getCenterY())-(e.getHeight()/2+a.getHeight()/2);h<=this.repulsionRange&&d<=this.repulsionRange&&o.add(a)}e.surrounding=[].concat(function(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t<e.length;t++)n[t]=e[t];return n}return Array.from(e)}(o))}for(l=0;l<e.surrounding.length;l++)this.calcRepulsionForce(e,e.surrounding[l])},l.prototype.calcRepulsionRange=function(){return 0},e.exports=l},function(e,t,n){"use strict";var r=n(1),i=n(7);function a(e,t,n){r.call(this,e,t,n),this.idealLength=i.DEFAULT_EDGE_LENGTH}for(var o in a.prototype=Object.create(r.prototype),r)a[o]=r[o];e.exports=a},function(e,t,n){"use strict";var r=n(3);function i(e,t,n,i){r.call(this,e,t,n,i),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}for(var a in i.prototype=Object.create(r.prototype),r)i[a]=r[a];i.prototype.setGridCoordinates=function(e,t,n,r){this.startX=e,this.finishX=t,this.startY=n,this.finishY=r},e.exports=i},function(e,t,n){"use strict";function r(e,t){this.width=0,this.height=0,null!==e&&null!==t&&(this.height=t,this.width=e)}r.prototype.getWidth=function(){return this.width},r.prototype.setWidth=function(e){this.width=e},r.prototype.getHeight=function(){return this.height},r.prototype.setHeight=function(e){this.height=e},e.exports=r},function(e,t,n){"use strict";var r=n(14);function i(){this.map={},this.keys=[]}i.prototype.put=function(e,t){var n=r.createID(e);this.contains(n)||(this.map[n]=t,this.keys.push(e))},i.prototype.contains=function(e){return r.createID(e),null!=this.map[e]},i.prototype.get=function(e){var t=r.createID(e);return this.map[t]},i.prototype.keySet=function(){return this.keys},e.exports=i},function(e,t,n){"use strict";var r=n(14);function i(){this.set={}}i.prototype.add=function(e){var t=r.createID(e);this.contains(t)||(this.set[t]=e)},i.prototype.remove=function(e){delete this.set[r.createID(e)]},i.prototype.clear=function(){this.set={}},i.prototype.contains=function(e){return this.set[r.createID(e)]==e},i.prototype.isEmpty=function(){return 0===this.size()},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAllTo=function(e){for(var t=Object.keys(this.set),n=t.length,r=0;r<n;r++)e.push(this.set[t[r]])},i.prototype.size=function(){return Object.keys(this.set).length},i.prototype.addAll=function(e){for(var t=e.length,n=0;n<t;n++){var r=e[n];this.add(r)}},e.exports=i},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=n(11),a=function(){function e(t,n){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),null===n&&void 0===n||(this.compareFunction=this._defaultCompareFunction);var r=void 0;r=t instanceof i?t.size():t.length,this._quicksort(t,0,r-1)}return r(e,[{key:"_quicksort",value:function(e,t,n){if(t<n){var r=this._partition(e,t,n);this._quicksort(e,t,r),this._quicksort(e,r+1,n)}}},{key:"_partition",value:function(e,t,n){for(var r=this._get(e,t),i=t,a=n;;){for(;this.compareFunction(r,this._get(e,a));)a--;for(;this.compareFunction(this._get(e,i),r);)i++;if(!(i<a))return a;this._swap(e,i,a),i++,a--}}},{key:"_get",value:function(e,t){return e instanceof i?e.get_object_at(t):e[t]}},{key:"_set",value:function(e,t,n){e instanceof i?e.set_object_at(t,n):e[t]=n}},{key:"_swap",value:function(e,t,n){var r=this._get(e,t);this._set(e,t,this._get(e,n)),this._set(e,n,r)}},{key:"_defaultCompareFunction",value:function(e,t){return t>e}}]),e}();e.exports=a},function(e,t,n){"use strict";var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),i=function(){function e(t,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:1,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.sequence1=t,this.sequence2=n,this.match_score=r,this.mismatch_penalty=i,this.gap_penalty=a,this.iMax=t.length+1,this.jMax=n.length+1,this.grid=new Array(this.iMax);for(var o=0;o<this.iMax;o++){this.grid[o]=new Array(this.jMax);for(var s=0;s<this.jMax;s++)this.grid[o][s]=0}this.tracebackGrid=new Array(this.iMax);for(var l=0;l<this.iMax;l++){this.tracebackGrid[l]=new Array(this.jMax);for(var u=0;u<this.jMax;u++)this.tracebackGrid[l][u]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return r(e,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var e=1;e<this.jMax;e++)this.grid[0][e]=this.grid[0][e-1]+this.gap_penalty,this.tracebackGrid[0][e]=[!1,!1,!0];for(var t=1;t<this.iMax;t++)this.grid[t][0]=this.grid[t-1][0]+this.gap_penalty,this.tracebackGrid[t][0]=[!1,!0,!1];for(var n=1;n<this.iMax;n++)for(var r=1;r<this.jMax;r++){var i=[this.sequence1[n-1]===this.sequence2[r-1]?this.grid[n-1][r-1]+this.match_score:this.grid[n-1][r-1]+this.mismatch_penalty,this.grid[n-1][r]+this.gap_penalty,this.grid[n][r-1]+this.gap_penalty],a=this.arrayAllMaxIndexes(i);this.grid[n][r]=i[a[0]],this.tracebackGrid[n][r]=[a.includes(0),a.includes(1),a.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var e=[];for(e.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});e[0];){var t=e[0],n=this.tracebackGrid[t.pos[0]][t.pos[1]];n[0]&&e.push({pos:[t.pos[0]-1,t.pos[1]-1],seq1:this.sequence1[t.pos[0]-1]+t.seq1,seq2:this.sequence2[t.pos[1]-1]+t.seq2}),n[1]&&e.push({pos:[t.pos[0]-1,t.pos[1]],seq1:this.sequence1[t.pos[0]-1]+t.seq1,seq2:"-"+t.seq2}),n[2]&&e.push({pos:[t.pos[0],t.pos[1]-1],seq1:"-"+t.seq1,seq2:this.sequence2[t.pos[1]-1]+t.seq2}),0===t.pos[0]&&0===t.pos[1]&&this.alignments.push({sequence1:t.seq1,sequence2:t.seq2}),e.shift()}return this.alignments}},{key:"getAllIndexes",value:function(e,t){for(var n=[],r=-1;-1!==(r=e.indexOf(t,r+1));)n.push(r);return n}},{key:"arrayAllMaxIndexes",value:function(e){return this.getAllIndexes(e,Math.max.apply(null,e))}}]),e}();e.exports=i},function(e,t,n){"use strict";var r=function(){};r.FDLayout=n(18),r.FDLayoutConstants=n(7),r.FDLayoutEdge=n(19),r.FDLayoutNode=n(20),r.DimensionD=n(21),r.HashMap=n(22),r.HashSet=n(23),r.IGeometry=n(8),r.IMath=n(9),r.Integer=n(10),r.Point=n(12),r.PointD=n(4),r.RandomSeed=n(16),r.RectangleD=n(13),r.Transform=n(17),r.UniqueIDGeneretor=n(14),r.Quicksort=n(24),r.LinkedList=n(11),r.LGraphObject=n(2),r.LGraph=n(5),r.LEdge=n(1),r.LGraphManager=n(6),r.LNode=n(3),r.Layout=n(15),r.LayoutConstants=n(0),r.NeedlemanWunsch=n(25),e.exports=r},function(e,t,n){"use strict";function r(){this.listeners=[]}var i=r.prototype;i.addListener=function(e,t){this.listeners.push({event:e,callback:t})},i.removeListener=function(e,t){for(var n=this.listeners.length;n>=0;n--){var r=this.listeners[n];r.event===e&&r.callback===t&&this.listeners.splice(n,1)}},i.emit=function(e,t){for(var n=0;n<this.listeners.length;n++){var r=this.listeners[n];e===r.event&&r.callback(t)}},e.exports=r}])},e.exports=t()},87807:(e,t,n)=>{"use strict";n.d(t,{diagram:()=>A});var r=n(56363),i=n(64218),a=n(74697),o=n(71377),s=n(14607),l=n(91619),u=n(12281),c=n(7201),h=(n(27484),n(17967),n(27856),function(){var e=function(e,t,n,r){for(n=n||{},r=e.length;r--;n[e[r]]=t);return n},t=[1,4],n=[1,13],r=[1,12],i=[1,15],a=[1,16],o=[1,20],s=[1,19],l=[6,7,8],u=[1,26],c=[1,24],h=[1,25],d=[6,7,11],p=[1,6,13,15,16,19,22],g=[1,33],f=[1,34],v=[1,6,7,11,13,15,16,19,22],y={trace:function(){},yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:function(e,t,n,r,i,a,o){var s=a.length-1;switch(i){case 6:case 7:return r;case 8:r.getLogger().trace("Stop NL ");break;case 9:r.getLogger().trace("Stop EOF ");break;case 11:r.getLogger().trace("Stop NL2 ");break;case 12:r.getLogger().trace("Stop EOF2 ");break;case 15:r.getLogger().info("Node: ",a[s].id),r.addNode(a[s-1].length,a[s].id,a[s].descr,a[s].type);break;case 16:r.getLogger().trace("Icon: ",a[s]),r.decorateNode({icon:a[s]});break;case 17:case 21:r.decorateNode({class:a[s]});break;case 18:r.getLogger().trace("SPACELIST");break;case 19:r.getLogger().trace("Node: ",a[s].id),r.addNode(0,a[s].id,a[s].descr,a[s].type);break;case 20:r.decorateNode({icon:a[s]});break;case 25:r.getLogger().trace("node found ..",a[s-2]),this.$={id:a[s-1],descr:a[s-1],type:r.getType(a[s-2],a[s])};break;case 26:this.$={id:a[s],descr:a[s],type:r.nodeType.DEFAULT};break;case 27:r.getLogger().trace("node found ..",a[s-3]),this.$={id:a[s-3],descr:a[s-1],type:r.getType(a[s-2],a[s])}}},table:[{3:1,4:2,5:3,6:[1,5],8:t},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:t},{6:n,7:[1,10],9:9,12:11,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},e(l,[2,3]),{1:[2,2]},e(l,[2,4]),e(l,[2,5]),{1:[2,6],6:n,12:21,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},{6:n,9:22,12:11,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},{6:u,7:c,10:23,11:h},e(d,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:o,22:s}),e(d,[2,18]),e(d,[2,19]),e(d,[2,20]),e(d,[2,21]),e(d,[2,23]),e(d,[2,24]),e(d,[2,26],{19:[1,30]}),{20:[1,31]},{6:u,7:c,10:32,11:h},{1:[2,7],6:n,12:21,13:r,14:14,15:i,16:a,17:17,18:18,19:o,22:s},e(p,[2,14],{7:g,11:f}),e(v,[2,8]),e(v,[2,9]),e(v,[2,10]),e(d,[2,15]),e(d,[2,16]),e(d,[2,17]),{20:[1,35]},{21:[1,36]},e(p,[2,13],{7:g,11:f}),e(v,[2,11]),e(v,[2,12]),{21:[1,37]},e(d,[2,25]),e(d,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:function(e,t){if(!t.recoverable){var n=new Error(e);throw n.hash=t,n}this.trace(e)},parse:function(e){var t=this,n=[0],r=[],i=[null],a=[],o=this.table,s="",l=0,u=0,c=a.slice.call(arguments,1),h=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);h.setInput(e,d.yy),d.yy.lexer=h,d.yy.parser=this,void 0===h.yylloc&&(h.yylloc={});var g=h.yylloc;a.push(g);var f=h.options&&h.options.ranges;"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var v,y,m,b,x,w,E,T,_,D={};;){if(y=n[n.length-1],this.defaultActions[y]?m=this.defaultActions[y]:(null==v&&(_=void 0,"number"!=typeof(_=r.pop()||h.lex()||1)&&(_ instanceof Array&&(_=(r=_).pop()),_=t.symbols_[_]||_),v=_),m=o[y]&&o[y][v]),void 0===m||!m.length||!m[0]){var C="";for(x in T=[],o[y])this.terminals_[x]&&x>2&&T.push("'"+this.terminals_[x]+"'");C=h.showPosition?"Parse error on line "+(l+1)+":\n"+h.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==v?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError(C,{text:h.match,token:this.terminals_[v]||v,line:h.yylineno,loc:g,expected:T})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+y+", token: "+v);switch(m[0]){case 1:n.push(v),i.push(h.yytext),a.push(h.yylloc),n.push(m[1]),v=null,u=h.yyleng,s=h.yytext,l=h.yylineno,g=h.yylloc;break;case 2:if(w=this.productions_[m[1]][1],D.$=i[i.length-w],D._$={first_line:a[a.length-(w||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(w||1)].first_column,last_column:a[a.length-1].last_column},f&&(D._$.range=[a[a.length-(w||1)].range[0],a[a.length-1].range[1]]),void 0!==(b=this.performAction.apply(D,[s,u,l,d.yy,m[1],i,a].concat(c))))return b;w&&(n=n.slice(0,-1*w*2),i=i.slice(0,-1*w),a=a.slice(0,-1*w)),n.push(this.productions_[m[1]][0]),i.push(D.$),a.push(D._$),E=o[n[n.length-2]][n[n.length-1]],n.push(E);break;case 3:return!0}}return!0}},m={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],n=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;a<i.length;a++)if((n=this._input.match(this.rules[i[a]]))&&(!t||n[0].length>t[0].length)){if(t=n,r=a,this.options.backtrack_lexer){if(!1!==(e=this.test_match(n,i[a])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,i[r]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(e,t,n,r){switch(n){case 0:return e.getLogger().trace("Found comment",t.yytext),6;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;case 4:case 23:case 26:this.popState();break;case 5:e.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return e.getLogger().trace("SPACELINE"),6;case 7:return 7;case 8:return 15;case 9:e.getLogger().trace("end icon"),this.popState();break;case 10:return e.getLogger().trace("Exploding node"),this.begin("NODE"),19;case 11:return e.getLogger().trace("Cloud"),this.begin("NODE"),19;case 12:return e.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;case 13:return e.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;case 14:case 15:case 16:case 17:return this.begin("NODE"),19;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 24:e.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return e.getLogger().trace("description:",t.yytext),"NODE_DESCR";case 27:return this.popState(),e.getLogger().trace("node end ))"),"NODE_DEND";case 28:return this.popState(),e.getLogger().trace("node end )"),"NODE_DEND";case 29:return this.popState(),e.getLogger().trace("node end ...",t.yytext),"NODE_DEND";case 30:case 33:case 34:return this.popState(),e.getLogger().trace("node end (("),"NODE_DEND";case 31:case 32:return this.popState(),e.getLogger().trace("node end (-"),"NODE_DEND";case 35:case 36:return e.getLogger().trace("Long description:",t.yytext),20}},rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}};function b(){this.yy={}}return y.lexer=m,b.prototype=y,y.Parser=b,new b}());h.parser=h;const d=h,p=e=>(0,r.d)(e,(0,r.c)());let g=[],f=0,v={};const y={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},m=(e,t)=>{v[e]=t},b=e=>{switch(e){case y.DEFAULT:return"no-border";case y.RECT:return"rect";case y.ROUNDED_RECT:return"rounded-rect";case y.CIRCLE:return"circle";case y.CLOUD:return"cloud";case y.BANG:return"bang";case y.HEXAGON:return"hexgon";default:return"no-border"}};let x;const w=e=>v[e],E=Object.freeze(Object.defineProperty({__proto__:null,addNode:(e,t,n,i)=>{r.l.info("addNode",e,t,n,i);const a=(0,r.c)(),o={id:f++,nodeId:p(t),level:e,descr:p(n),type:i,children:[],width:(0,r.c)().mindmap.maxNodeWidth};switch(o.type){case y.ROUNDED_RECT:case y.RECT:case y.HEXAGON:o.padding=2*a.mindmap.padding;break;default:o.padding=a.mindmap.padding}const s=function(e){for(let t=g.length-1;t>=0;t--)if(g[t].level<e)return g[t];return null}(e);if(s)s.children.push(o),g.push(o);else{if(0!==g.length){let e=new Error('There can be only one root. No parent could be found for ("'+o.descr+'")');throw e.hash={text:"branch "+name,token:"branch "+name,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+name+'"']},e}g.push(o)}},clear:()=>{g=[],f=0,v={}},decorateNode:e=>{const t=g[g.length-1];e&&e.icon&&(t.icon=p(e.icon)),e&&e.class&&(t.class=p(e.class))},getElementById:w,getLogger:()=>r.l,getMindmap:()=>g.length>0?g[0]:null,getNodeById:e=>g[e],getType:(e,t)=>{switch(r.l.debug("In get type",e,t),e){case"[":return y.RECT;case"(":return")"===t?y.ROUNDED_RECT:y.CLOUD;case"((":return y.CIRCLE;case")":return y.CLOUD;case"))":return y.BANG;case"{{":return y.HEXAGON;default:return y.DEFAULT}},nodeType:y,get parseError(){return x},sanitizeText:p,setElementForId:m,setErrorHandler:e=>{x=e},type2Str:b},Symbol.toStringTag,{value:"Module"}));const T=function(e,t,n,r){const i=r.htmlLabels,o=n%11,s=e.append("g");t.section=o;let l="section-"+o;o<0&&(l+=" section-root"),s.attr("class",(t.class?t.class+" ":"")+"mindmap-node "+l);const u=s.append("g"),c=s.append("g"),h=t.descr.replace(/(<br\/*>)/g,"\n");(0,a.a)(c,h,{useHtmlLabels:i,width:t.width,classes:"mindmap-node-label"}),i||c.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");const d=c.node().getBBox(),p=r.fontSize.replace?r.fontSize.replace("px",""):r.fontSize;if(t.height=d.height+1.1*p*.5+t.padding,t.width=d.width+2*t.padding,t.icon)if(t.type===y.CIRCLE){t.height+=50,t.width+=50;s.append("foreignObject").attr("height","50px").attr("width",t.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+o+" "+t.icon),c.attr("transform","translate("+t.width/2+", "+(t.height/2-1.5*t.padding)+")")}else{t.width+=50;const e=t.height;t.height=Math.max(e,60);const n=Math.abs(t.height-e);s.append("foreignObject").attr("width","60px").attr("height",t.height).attr("style","text-align: center;margin-top:"+n/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+o+" "+t.icon),c.attr("transform","translate("+(25+t.width/2)+", "+(n/2+t.padding/2)+")")}else if(i){const e=(t.width-d.width)/2,n=(t.height-d.height)/2;c.attr("transform","translate("+e+", "+n+")")}else{const e=t.width/2,n=t.padding/2;c.attr("transform","translate("+e+", "+n+")")}switch(t.type){case y.DEFAULT:!function(e,t,n){e.append("path").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("d",`M0 ${t.height-5} v${10-t.height} q0,-5 5,-5 h${t.width-10} q5,0 5,5 v${t.height-5} H0 Z`),e.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",t.height).attr("x2",t.width).attr("y2",t.height)}(u,t,o);break;case y.ROUNDED_RECT:!function(e,t){e.append("rect").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("height",t.height).attr("rx",t.padding).attr("ry",t.padding).attr("width",t.width)}(u,t);break;case y.RECT:!function(e,t){e.append("rect").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("height",t.height).attr("width",t.width)}(u,t);break;case y.CIRCLE:u.attr("transform","translate("+t.width/2+", "+ +t.height/2+")"),function(e,t){e.append("circle").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("r",t.width/2)}(u,t);break;case y.CLOUD:!function(e,t){const n=t.width,r=t.height,i=.15*n,a=.25*n,o=.35*n,s=.2*n;e.append("path").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("d",`M0 0 a${i},${i} 0 0,1 ${.25*n},${-1*n*.1}\n a${o},${o} 1 0,1 ${.4*n},${-1*n*.1}\n a${a},${a} 1 0,1 ${.35*n},${1*n*.2}\n\n a${i},${i} 1 0,1 ${.15*n},${1*r*.35}\n a${s},${s} 1 0,1 ${-1*n*.15},${1*r*.65}\n\n a${a},${i} 1 0,1 ${-1*n*.25},${.15*n}\n a${o},${o} 1 0,1 ${-1*n*.5},0\n a${i},${i} 1 0,1 ${-1*n*.25},${-1*n*.15}\n\n a${i},${i} 1 0,1 ${-1*n*.1},${-1*r*.35}\n a${s},${s} 1 0,1 ${.1*n},${-1*r*.65}\n\n H0 V0 Z`)}(u,t);break;case y.BANG:!function(e,t){const n=t.width,r=t.height,i=.15*n;e.append("path").attr("id","node-"+t.id).attr("class","node-bkg node-"+b(t.type)).attr("d",`M0 0 a${i},${i} 1 0,0 ${.25*n},${-1*r*.1}\n a${i},${i} 1 0,0 ${.25*n},0\n a${i},${i} 1 0,0 ${.25*n},0\n a${i},${i} 1 0,0 ${.25*n},${1*r*.1}\n\n a${i},${i} 1 0,0 ${.15*n},${1*r*.33}\n a${.8*i},${.8*i} 1 0,0 0,${1*r*.34}\n a${i},${i} 1 0,0 ${-1*n*.15},${1*r*.33}\n\n a${i},${i} 1 0,0 ${-1*n*.25},${.15*r}\n a${i},${i} 1 0,0 ${-1*n*.25},0\n a${i},${i} 1 0,0 ${-1*n*.25},0\n a${i},${i} 1 0,0 ${-1*n*.25},${-1*r*.15}\n\n a${i},${i} 1 0,0 ${-1*n*.1},${-1*r*.33}\n a${.8*i},${.8*i} 1 0,0 0,${-1*r*.34}\n a${i},${i} 1 0,0 ${.1*n},${-1*r*.33}\n\n H0 V0 Z`)}(u,t);break;case y.HEXAGON:!function(e,t){const n=t.height,r=n/4,i=t.width-t.padding+2*r;!function(e,t,n,r,i){e.insert("polygon",":first-child").attr("points",r.map((function(e){return e.x+","+e.y})).join(" ")).attr("transform","translate("+(i.width-t)/2+", "+n+")")}(e,i,n,[{x:r,y:0},{x:i-r,y:0},{x:i,y:-n/2},{x:i-r,y:-n},{x:r,y:-n},{x:0,y:-n/2}],t)}(u,t)}return m(t.id,s),t.height},_=function(e){const t=w(e.id),n=e.x||0,r=e.y||0;t.attr("transform","translate("+n+","+r+")")};function D(e,t,n,r){T(e,t,n,r),t.children&&t.children.forEach(((t,i)=>{D(e,t,n<0?i:n,r)}))}function C(e,t,n,r){t.add({group:"nodes",data:{id:e.id,labelText:e.descr,height:e.height,width:e.width,level:r,nodeId:e.id,padding:e.padding,type:e.type},position:{x:e.x,y:e.y}}),e.children&&e.children.forEach((i=>{C(i,t,n,r+1),t.add({group:"edges",data:{id:`${e.id}_${i.id}`,source:e.id,target:i.id,depth:r,section:i.section}})}))}function N(e,t){return new Promise((n=>{const a=(0,i.Ys)("body").append("div").attr("id","cy").attr("style","display:none"),s=o({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});a.remove(),C(e,s,t,0),s.nodes().forEach((function(e){e.layoutDimensions=()=>{const t=e.data();return{w:t.width,h:t.height}}})),s.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),s.ready((e=>{r.l.info("Ready",e),n(s)}))}))}o.use(s);const A={db:E,renderer:{draw:async(e,t,n,a)=>{const o=(0,r.c)();o.htmlLabels=!1,r.l.debug("Rendering mindmap diagram\n"+e,a.parser);const s=(0,r.c)().securityLevel;let l;"sandbox"===s&&(l=(0,i.Ys)("#i"+t));const u=("sandbox"===s?(0,i.Ys)(l.nodes()[0].contentDocument.body):(0,i.Ys)("body")).select("#"+t);u.append("g");const c=a.db.getMindmap(),h=u.append("g");h.attr("class","mindmap-edges");const d=u.append("g");d.attr("class","mindmap-nodes"),D(d,c,-1,o);const p=await N(c,o);!function(e,t){t.edges().map(((t,n)=>{const i=t.data();if(t[0]._private.bodyBounds){const a=t[0]._private.rscratch;r.l.trace("Edge: ",n,i),e.insert("path").attr("d",`M ${a.startX},${a.startY} L ${a.midX},${a.midY} L${a.endX},${a.endY} `).attr("class","edge section-edge-"+i.section+" edge-depth-"+i.depth)}}))}(h,p),function(e){e.nodes().map(((e,t)=>{const n=e.data();n.x=e.position().x,n.y=e.position().y,_(n);const i=w(n.nodeId);r.l.info("Id:",t,"Position: (",e.position().x,", ",e.position().y,")",n),i.attr("transform",`translate(${e.position().x-n.width/2}, ${e.position().y-n.height/2})`),i.attr("attr",`apa-${t})`)}))}(p),(0,r.o)(void 0,u,o.mindmap.padding,o.mindmap.useMaxWidth)}},parser:d,styles:e=>`\n .edge {\n stroke-width: 3;\n }\n ${(e=>{let t="";for(let n=0;n<e.THEME_COLOR_LIMIT;n++)e["lineColor"+n]=e["lineColor"+n]||e["cScaleInv"+n],(0,l.Z)(e["lineColor"+n])?e["lineColor"+n]=(0,u.Z)(e["lineColor"+n],20):e["lineColor"+n]=(0,c.Z)(e["lineColor"+n],20);for(let n=0;n<e.THEME_COLOR_LIMIT;n++){const r=""+(17-3*n);t+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} polygon, .section-${n-1} path {\n fill: ${e["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${e["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${e["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${e["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${r};\n }\n .section-${n-1} line {\n stroke: ${e["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return t})(e)}\n .section-root rect, .section-root path, .section-root circle, .section-root polygon {\n fill: ${e.git0};\n }\n .section-root text {\n fill: ${e.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .mindmap-node-label {\n dy: 1em;\n alignment-baseline: middle;\n text-anchor: middle;\n dominant-baseline: middle;\n text-align: center;\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/7807.b82574b2.js.LICENSE.txt b/assets/js/7807.b82574b2.js.LICENSE.txt new file mode 100644 index 000000000..a58daed49 --- /dev/null +++ b/assets/js/7807.b82574b2.js.LICENSE.txt @@ -0,0 +1,9 @@ +/*! + Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable + Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) + Licensed under The MIT License (http://opensource.org/licenses/MIT) + */ + +/*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */ + +/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */ diff --git a/assets/js/7856.26f0b80c.js b/assets/js/7856.26f0b80c.js new file mode 100644 index 000000000..2a1f3e853 --- /dev/null +++ b/assets/js/7856.26f0b80c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7856],{5658:(e,t,i)=>{i.d(t,{Z:()=>a});i(67294);var n=i(86010),s=i(95999),o=i(92503),r=i(85893);function a(e){let{className:t}=e;return(0,r.jsx)("main",{className:(0,n.Z)("container margin-vert--xl",t),children:(0,r.jsx)("div",{className:"row",children:(0,r.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,r.jsx)(o.Z,{as:"h1",className:"hero__title",children:(0,r.jsx)(s.Z,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,r.jsx)("p",{children:(0,r.jsx)(s.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,r.jsx)("p",{children:(0,r.jsx)(s.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},51772:(e,t,i)=>{i.r(t),i.d(t,{default:()=>l});i(67294);var n=i(95999),s=i(10833),o=i(58207),r=i(5658),a=i(85893);function l(){const e=(0,n.I)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.d,{title:e}),(0,a.jsx)(o.Z,{children:(0,a.jsx)(r.Z,{})})]})}}}]); \ No newline at end of file diff --git a/assets/js/79a97f4e.418816f9.js b/assets/js/79a97f4e.418816f9.js deleted file mode 100644 index 169db8539..000000000 --- a/assets/js/79a97f4e.418816f9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6412],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),m=c(r),f=a,v=m["".concat(i,".").concat(f)]||m[f]||s[f]||o;return r?n.createElement(v,l(l({ref:t},u),{},{components:r})):n.createElement(v,l({ref:t},u))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:a,l[1]=p;for(var c=2;c<o;c++)l[c]=r[c];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},82792:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>s,frontMatter:()=>o,metadata:()=>p,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",slug:"woowacourse-level2-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,p={permalink:"/woowacourse-level2-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",description:"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.",date:"2023-06-11T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 11\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:2.545,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",slug:"woowacourse-level2-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"Docusaurus",permalink:"/docusaurus"},nextItem:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",permalink:"/level2-interview-retrospective"}},i={authorsImageUrls:[]},c=[{value:"\ud559\uc2b5",id:"\ud559\uc2b5",level:3},{value:"\uc218\uba74",id:"\uc218\uba74",level:3},{value:"\ud611\uc5c5",id:"\ud611\uc5c5",level:3},{value:"\ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70",id:"\ub808\ubca8-2\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube60\ub974\uac8c \uc9c0\ub098\uac00\uc11c \uc870\uae08 \uc544\uc27d\ub2e4. "),(0,a.kt)("h3",{id:"\ud559\uc2b5"},"\ud559\uc2b5"),(0,a.kt)("p",null,"\ud68c\uace0\ub97c \uc791\uc131\ud558\uae30 \uc804\uc5d0 \ub808\ubca8 2 \ub3d9\uc548 \ubcf4\ub0c8\ub358 PR\uacfc \ud68c\uace0\ub97c \ucb49 \uc77d\uc5b4\ubd24\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \uc544\uc26c\uc6b4 \uacf3\uc740 \uc788\uae30 \ub9c8\ub828\uc774\uc9c0\ub9cc, \uc798 \ud559\uc2b5\ud55c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc744 \ud558\uba74\uc11c \uae30\uc220\uc744 \uc5b4\ub5bb\uac8c \uc120\ud0dd\ud558\uace0, \uc801\uc6a9\ud560 \uac83\uc778\uc9c0 \uace0\ubbfc\ud558\ub294 \uacfc\uc815\uc5d0\uc11c \uaf64\ub098 \ub9ce\uc740 \uc131\uc7a5\uc744 \ud55c \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\uace0\ubbfc\uc740 \uae4a\uc5c8\uc9c0\ub9cc \uc774\ub860\uc801\uc778 \ud559\uc2b5\uc774 \ubd80\uc871\ud55c \ub808\ubca8 2\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc29\ud559 \uadf8\ub9ac\uace0 \ub808\ubca8 3 \ub54c\ub294 \uc870\uae08 \ub354 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc744 \ud559\uc2b5\ud558\ub294\ub370 \uc9d1\uc911\ud574\uc57c\uaca0\ub2e4. "),(0,a.kt)("p",null,"\uc810\ucc28 \ud559\uc2b5 \ubc94\uc704\uac00 \ub113\uc5b4\uc9c0\uba74\uc11c \uc790\uc5f0\uc2a4\ub7fd\uac8c \ubaa8\ub974\ub294 \ub0b4\uc6a9\uc774 \uc313\uc5ec\uac04\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud544\uc694\ud55c \ub0b4\uc6a9\uc740 \uc55e\uc73c\ub85c \ucc9c\ucc9c\ud788 \ud559\uc2b5\ud558\uba74 \ub418\ub2c8\uae4c \uc870\uae09\ud574\uc9c0\uc9c0 \ub9d0\uc544\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\uc218\uba74"},"\uc218\uba74"),(0,a.kt)("p",null,"\ub808\ubca8 2\ub97c \uc9c4\ud589\ud558\ub294 \ub3d9\uc548 \uc218\uba74\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\uc5c8\uace0, \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \uadf8\ub0a0\uc758 \ucee8\ub514\uc158\uc744 \ub9ce\uc774 \uc88c\uc6b0\ud588\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc218\uba74 \uc2dc\uac04\uc744 \ub298\ub9ac\uace0, \uc88b\uc740 \uc218\uba74 \uc2b5\uad00\uc744 \uac00\uc9c0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\ud611\uc5c5"},"\ud611\uc5c5"),(0,a.kt)("p",null,"\ub808\ubca8 2 \ub9c8\uc9c0\ub9c9\uc5d0 \ud611\uc5c5 \ubbf8\uc158\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c0\uae08\uae4c\uc9c0\ub294 \ubc31\uc5d4\ub4dc \ud06c\ub8e8\ub4e4\uacfc \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud558\uba74\uc11c \ud611\uc5c5\uc744 \uacbd\ud5d8\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0\ub294 \ud504\ub7f0\ud2b8\uc5d4\ub4dc \ud06c\ub8e8\uc640 \ud611\uc5c5\uc744 \ud588\ub2e4. \uc18c\ud1b5\uc740 \uc798 \ub41c \uac83 \uac19\uc9c0\ub9cc API \uba85\uc138\ub97c \uc815\ud558\ub294 \ubd80\ubd84\uc774 \uc544\uc9c1 \ubbf8\uc219\ud55c \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\ub808\ubca8 3 \ub54c\ubd80\ud130 \ubcf8\uaca9\uc801\uc73c\ub85c \ud504\ub85c\uc81d\ud2b8\uac00 \uc2dc\uc791\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud300\uc744 \uc704\ud574 \uc5b4\ub5a4 \uac83\uc744 \ud560 \uc218 \uc788\uc744\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud574\ubd10\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\ub808\ubca8-2\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70"},"\ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70"),(0,a.kt)("p",null,"\ud68c\uace0 \uc791\uc131\ud558\uba74\uc11c \ub808\ubca8 2\uc5d0\uc11c \ud588\ub358 \uac83\ub4e4\uc744 \ubc18\ucd94\ud574 \ubd24\ub294\ub370 \ubd80\uc871\ud55c \uc810\uc740 \ub9ce\uc558\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \uac00\uace0 \uc788\ub294 \uac83 \uac19\ub2e4.\n\uc77d\uace0 \uc2f6\uc740 \ucc45\ub3c4 \uc77d\uace0, \ubd80\uc871\ud55c \ubd80\ubd84 \ucc44\uc6b0\uba74\uc11c \uc26c\uc5b4\uc57c\uaca0\ub2e4."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/79a97f4e.6cfb3091.js b/assets/js/79a97f4e.6cfb3091.js new file mode 100644 index 000000000..0c63cac48 --- /dev/null +++ b/assets/js/79a97f4e.6cfb3091.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6412],{13408:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var n=t(85893),o=t(3905);const s={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",slug:"woowacourse-level2-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,i={permalink:"/woowacourse-level2-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",description:"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.",date:"2023-06-11T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 11\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:2.545,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",slug:"woowacourse-level2-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"Docusaurus",permalink:"/docusaurus"},nextItem:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",permalink:"/level2-interview-retrospective"}},a={authorsImageUrls:[]},l=[{value:"\ud559\uc2b5",id:"\ud559\uc2b5",level:3},{value:"\uc218\uba74",id:"\uc218\uba74",level:3},{value:"\ud611\uc5c5",id:"\ud611\uc5c5",level:3},{value:"\ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70",id:"\ub808\ubca8-2\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70",level:3}];function p(e){const r={br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(r.p,{children:["23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ube60\ub974\uac8c \uc9c0\ub098\uac00\uc11c \uc870\uae08 \uc544\uc27d\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ud559\uc2b5",children:"\ud559\uc2b5"}),"\n",(0,n.jsxs)(r.p,{children:["\ud68c\uace0\ub97c \uc791\uc131\ud558\uae30 \uc804\uc5d0 \ub808\ubca8 2 \ub3d9\uc548 \ubcf4\ub0c8\ub358 PR\uacfc \ud68c\uace0\ub97c \ucb49 \uc77d\uc5b4\ubd24\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud56d\uc0c1 \uc544\uc26c\uc6b4 \uacf3\uc740 \uc788\uae30 \ub9c8\ub828\uc774\uc9c0\ub9cc, \uc798 \ud559\uc2b5\ud55c \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc744 \ud558\uba74\uc11c \uae30\uc220\uc744 \uc5b4\ub5bb\uac8c \uc120\ud0dd\ud558\uace0, \uc801\uc6a9\ud560 \uac83\uc778\uc9c0 \uace0\ubbfc\ud558\ub294 \uacfc\uc815\uc5d0\uc11c \uaf64\ub098 \ub9ce\uc740 \uc131\uc7a5\uc744 \ud55c \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\uace0\ubbfc\uc740 \uae4a\uc5c8\uc9c0\ub9cc \uc774\ub860\uc801\uc778 \ud559\uc2b5\uc774 \ubd80\uc871\ud55c \ub808\ubca8 2\uc600\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubc29\ud559 \uadf8\ub9ac\uace0 \ub808\ubca8 3 \ub54c\ub294 \uc870\uae08 \ub354 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc744 \ud559\uc2b5\ud558\ub294\ub370 \uc9d1\uc911\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\uc810\ucc28 \ud559\uc2b5 \ubc94\uc704\uac00 \ub113\uc5b4\uc9c0\uba74\uc11c \uc790\uc5f0\uc2a4\ub7fd\uac8c \ubaa8\ub974\ub294 \ub0b4\uc6a9\uc774 \uc313\uc5ec\uac04\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud544\uc694\ud55c \ub0b4\uc6a9\uc740 \uc55e\uc73c\ub85c \ucc9c\ucc9c\ud788 \ud559\uc2b5\ud558\uba74 \ub418\ub2c8\uae4c \uc870\uae09\ud574\uc9c0\uc9c0 \ub9d0\uc544\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc218\uba74",children:"\uc218\uba74"}),"\n",(0,n.jsxs)(r.p,{children:["\ub808\ubca8 2\ub97c \uc9c4\ud589\ud558\ub294 \ub3d9\uc548 \uc218\uba74\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\uc5c8\uace0, \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \uadf8\ub0a0\uc758 \ucee8\ub514\uc158\uc744 \ub9ce\uc774 \uc88c\uc6b0\ud588\ub358 \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c \uc218\uba74 \uc2dc\uac04\uc744 \ub298\ub9ac\uace0, \uc88b\uc740 \uc218\uba74 \uc2b5\uad00\uc744 \uac00\uc9c0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ud611\uc5c5",children:"\ud611\uc5c5"}),"\n",(0,n.jsxs)(r.p,{children:["\ub808\ubca8 2 \ub9c8\uc9c0\ub9c9\uc5d0 \ud611\uc5c5 \ubbf8\uc158\uc774 \uc788\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc9c0\uae08\uae4c\uc9c0\ub294 \ubc31\uc5d4\ub4dc \ud06c\ub8e8\ub4e4\uacfc \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud558\uba74\uc11c \ud611\uc5c5\uc744 \uacbd\ud5d8\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc774\ubc88\uc5d0\ub294 \ud504\ub7f0\ud2b8\uc5d4\ub4dc \ud06c\ub8e8\uc640 \ud611\uc5c5\uc744 \ud588\ub2e4. \uc18c\ud1b5\uc740 \uc798 \ub41c \uac83 \uac19\uc9c0\ub9cc API \uba85\uc138\ub97c \uc815\ud558\ub294 \ubd80\ubd84\uc774 \uc544\uc9c1 \ubbf8\uc219\ud55c \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ub808\ubca8 3 \ub54c\ubd80\ud130 \ubcf8\uaca9\uc801\uc73c\ub85c \ud504\ub85c\uc81d\ud2b8\uac00 \uc2dc\uc791\ub41c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud300\uc744 \uc704\ud574 \uc5b4\ub5a4 \uac83\uc744 \ud560 \uc218 \uc788\uc744\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud574\ubd10\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ub808\ubca8-2\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70",children:"\ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70"}),"\n",(0,n.jsx)(r.p,{children:"\ud68c\uace0 \uc791\uc131\ud558\uba74\uc11c \ub808\ubca8 2\uc5d0\uc11c \ud588\ub358 \uac83\ub4e4\uc744 \ubc18\ucd94\ud574 \ubd24\ub294\ub370 \ubd80\uc871\ud55c \uc810\uc740 \ub9ce\uc558\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \uac00\uace0 \uc788\ub294 \uac83 \uac19\ub2e4.\n\uc77d\uace0 \uc2f6\uc740 \ucc45\ub3c4 \uc77d\uace0, \ubd80\uc871\ud55c \ubd80\ubd84 \ucc44\uc6b0\uba74\uc11c \uc26c\uc5b4\uc57c\uaca0\ub2e4."})]})}function u(e={}){const{wrapper:r}={...(0,o.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>l});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function c(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?s(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function i(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},s=Object.keys(e);for(n=0;n<s.length;n++)t=s[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)t=s[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var a=n.createContext({}),l=function(e){var r=n.useContext(a),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},p={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},u=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,s=e.originalType,a=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=l(t),h=o,b=d["".concat(a,".").concat(h)]||d[h]||p[h]||s;return t?n.createElement(b,c(c({ref:r},u),{},{components:t})):n.createElement(b,c({ref:r},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/7bbc420e.82f9788b.js b/assets/js/7bbc420e.de2e8ae6.js similarity index 81% rename from assets/js/7bbc420e.82f9788b.js rename to assets/js/7bbc420e.de2e8ae6.js index 9aeed25f0..256d4e85a 100644 --- a/assets/js/7bbc420e.82f9788b.js +++ b/assets/js/7bbc420e.de2e8ae6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4311],{41691:e=>{e.exports=JSON.parse('{"label":"Documentation","permalink":"/tags/documentation","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4311],{41691:e=>{e.exports=JSON.parse('{"label":"Documentation","permalink":"/tags/documentation","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/7e4c1ed7.19c4489f.js b/assets/js/7e4c1ed7.3a8a4e55.js similarity index 86% rename from assets/js/7e4c1ed7.19c4489f.js rename to assets/js/7e4c1ed7.3a8a4e55.js index 600e70f5d..76182fc2e 100644 --- a/assets/js/7e4c1ed7.19c4489f.js +++ b/assets/js/7e4c1ed7.3a8a4e55.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1653],{83297:e=>{e.exports=JSON.parse('{"label":"postmortem","permalink":"/docs/tags/postmortem","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","title":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","description":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)","permalink":"/docs/culture/postmortem"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1653],{83297:e=>{e.exports=JSON.parse('{"label":"postmortem","permalink":"/docs/tags/postmortem","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","title":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","description":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)","permalink":"/docs/culture/postmortem"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/7fd9a574.986af784.js b/assets/js/7fd9a574.7929f04e.js similarity index 81% rename from assets/js/7fd9a574.986af784.js rename to assets/js/7fd9a574.7929f04e.js index 03104f1e6..639e024c9 100644 --- a/assets/js/7fd9a574.986af784.js +++ b/assets/js/7fd9a574.7929f04e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2889],{5863:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2889],{5863:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/807.d82fc398.js b/assets/js/807.d82fc398.js new file mode 100644 index 000000000..e81b5f6e7 --- /dev/null +++ b/assets/js/807.d82fc398.js @@ -0,0 +1,51069 @@ +exports.id = 807; +exports.ids = [807]; +exports.modules = { + +/***/ 84182: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +(function webpackUniversalModuleDefinition(root, factory) { + if(true) + module.exports = factory(__webpack_require__(82241)); + else {} +})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __nested_webpack_require_643__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_643__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __nested_webpack_require_643__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __nested_webpack_require_643__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __nested_webpack_require_643__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __nested_webpack_require_643__.d = function(exports, name, getter) { +/******/ if(!__nested_webpack_require_643__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __nested_webpack_require_643__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __nested_webpack_require_643__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __nested_webpack_require_643__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __nested_webpack_require_643__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __nested_webpack_require_643__(__nested_webpack_require_643__.s = 7); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_0__; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __nested_webpack_require_3185__) { + +"use strict"; + + +var FDLayoutConstants = __nested_webpack_require_3185__(0).FDLayoutConstants; + +function CoSEConstants() {} + +//CoSEConstants inherits static props in FDLayoutConstants +for (var prop in FDLayoutConstants) { + CoSEConstants[prop] = FDLayoutConstants[prop]; +} + +CoSEConstants.DEFAULT_USE_MULTI_LEVEL_SCALING = false; +CoSEConstants.DEFAULT_RADIAL_SEPARATION = FDLayoutConstants.DEFAULT_EDGE_LENGTH; +CoSEConstants.DEFAULT_COMPONENT_SEPERATION = 60; +CoSEConstants.TILE = true; +CoSEConstants.TILING_PADDING_VERTICAL = 10; +CoSEConstants.TILING_PADDING_HORIZONTAL = 10; +CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = false; // make this true when cose is used incrementally as a part of other non-incremental layout + +module.exports = CoSEConstants; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __nested_webpack_require_4002__) { + +"use strict"; + + +var FDLayoutEdge = __nested_webpack_require_4002__(0).FDLayoutEdge; + +function CoSEEdge(source, target, vEdge) { + FDLayoutEdge.call(this, source, target, vEdge); +} + +CoSEEdge.prototype = Object.create(FDLayoutEdge.prototype); +for (var prop in FDLayoutEdge) { + CoSEEdge[prop] = FDLayoutEdge[prop]; +} + +module.exports = CoSEEdge; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __nested_webpack_require_4409__) { + +"use strict"; + + +var LGraph = __nested_webpack_require_4409__(0).LGraph; + +function CoSEGraph(parent, graphMgr, vGraph) { + LGraph.call(this, parent, graphMgr, vGraph); +} + +CoSEGraph.prototype = Object.create(LGraph.prototype); +for (var prop in LGraph) { + CoSEGraph[prop] = LGraph[prop]; +} + +module.exports = CoSEGraph; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __nested_webpack_require_4790__) { + +"use strict"; + + +var LGraphManager = __nested_webpack_require_4790__(0).LGraphManager; + +function CoSEGraphManager(layout) { + LGraphManager.call(this, layout); +} + +CoSEGraphManager.prototype = Object.create(LGraphManager.prototype); +for (var prop in LGraphManager) { + CoSEGraphManager[prop] = LGraphManager[prop]; +} + +module.exports = CoSEGraphManager; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __nested_webpack_require_5205__) { + +"use strict"; + + +var FDLayoutNode = __nested_webpack_require_5205__(0).FDLayoutNode; +var IMath = __nested_webpack_require_5205__(0).IMath; + +function CoSENode(gm, loc, size, vNode) { + FDLayoutNode.call(this, gm, loc, size, vNode); +} + +CoSENode.prototype = Object.create(FDLayoutNode.prototype); +for (var prop in FDLayoutNode) { + CoSENode[prop] = FDLayoutNode[prop]; +} + +CoSENode.prototype.move = function () { + var layout = this.graphManager.getLayout(); + this.displacementX = layout.coolingFactor * (this.springForceX + this.repulsionForceX + this.gravitationForceX) / this.noOfChildren; + this.displacementY = layout.coolingFactor * (this.springForceY + this.repulsionForceY + this.gravitationForceY) / this.noOfChildren; + + if (Math.abs(this.displacementX) > layout.coolingFactor * layout.maxNodeDisplacement) { + this.displacementX = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementX); + } + + if (Math.abs(this.displacementY) > layout.coolingFactor * layout.maxNodeDisplacement) { + this.displacementY = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementY); + } + + // a simple node, just move it + if (this.child == null) { + this.moveBy(this.displacementX, this.displacementY); + } + // an empty compound node, again just move it + else if (this.child.getNodes().length == 0) { + this.moveBy(this.displacementX, this.displacementY); + } + // non-empty compound node, propogate movement to children as well + else { + this.propogateDisplacementToChildren(this.displacementX, this.displacementY); + } + + layout.totalDisplacement += Math.abs(this.displacementX) + Math.abs(this.displacementY); + + this.springForceX = 0; + this.springForceY = 0; + this.repulsionForceX = 0; + this.repulsionForceY = 0; + this.gravitationForceX = 0; + this.gravitationForceY = 0; + this.displacementX = 0; + this.displacementY = 0; +}; + +CoSENode.prototype.propogateDisplacementToChildren = function (dX, dY) { + var nodes = this.getChild().getNodes(); + var node; + for (var i = 0; i < nodes.length; i++) { + node = nodes[i]; + if (node.getChild() == null) { + node.moveBy(dX, dY); + node.displacementX += dX; + node.displacementY += dY; + } else { + node.propogateDisplacementToChildren(dX, dY); + } + } +}; + +CoSENode.prototype.setPred1 = function (pred1) { + this.pred1 = pred1; +}; + +CoSENode.prototype.getPred1 = function () { + return pred1; +}; + +CoSENode.prototype.getPred2 = function () { + return pred2; +}; + +CoSENode.prototype.setNext = function (next) { + this.next = next; +}; + +CoSENode.prototype.getNext = function () { + return next; +}; + +CoSENode.prototype.setProcessed = function (processed) { + this.processed = processed; +}; + +CoSENode.prototype.isProcessed = function () { + return processed; +}; + +module.exports = CoSENode; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __nested_webpack_require_8085__) { + +"use strict"; + + +var FDLayout = __nested_webpack_require_8085__(0).FDLayout; +var CoSEGraphManager = __nested_webpack_require_8085__(4); +var CoSEGraph = __nested_webpack_require_8085__(3); +var CoSENode = __nested_webpack_require_8085__(5); +var CoSEEdge = __nested_webpack_require_8085__(2); +var CoSEConstants = __nested_webpack_require_8085__(1); +var FDLayoutConstants = __nested_webpack_require_8085__(0).FDLayoutConstants; +var LayoutConstants = __nested_webpack_require_8085__(0).LayoutConstants; +var Point = __nested_webpack_require_8085__(0).Point; +var PointD = __nested_webpack_require_8085__(0).PointD; +var Layout = __nested_webpack_require_8085__(0).Layout; +var Integer = __nested_webpack_require_8085__(0).Integer; +var IGeometry = __nested_webpack_require_8085__(0).IGeometry; +var LGraph = __nested_webpack_require_8085__(0).LGraph; +var Transform = __nested_webpack_require_8085__(0).Transform; + +function CoSELayout() { + FDLayout.call(this); + + this.toBeTiled = {}; // Memorize if a node is to be tiled or is tiled +} + +CoSELayout.prototype = Object.create(FDLayout.prototype); + +for (var prop in FDLayout) { + CoSELayout[prop] = FDLayout[prop]; +} + +CoSELayout.prototype.newGraphManager = function () { + var gm = new CoSEGraphManager(this); + this.graphManager = gm; + return gm; +}; + +CoSELayout.prototype.newGraph = function (vGraph) { + return new CoSEGraph(null, this.graphManager, vGraph); +}; + +CoSELayout.prototype.newNode = function (vNode) { + return new CoSENode(this.graphManager, vNode); +}; + +CoSELayout.prototype.newEdge = function (vEdge) { + return new CoSEEdge(null, null, vEdge); +}; + +CoSELayout.prototype.initParameters = function () { + FDLayout.prototype.initParameters.call(this, arguments); + if (!this.isSubLayout) { + if (CoSEConstants.DEFAULT_EDGE_LENGTH < 10) { + this.idealEdgeLength = 10; + } else { + this.idealEdgeLength = CoSEConstants.DEFAULT_EDGE_LENGTH; + } + + this.useSmartIdealEdgeLengthCalculation = CoSEConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION; + this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH; + this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH; + this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH; + this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH; + this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR; + this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR; + + // variables for tree reduction support + this.prunedNodesAll = []; + this.growTreeIterations = 0; + this.afterGrowthIterations = 0; + this.isTreeGrowing = false; + this.isGrowthFinished = false; + + // variables for cooling + this.coolingCycle = 0; + this.maxCoolingCycle = this.maxIterations / FDLayoutConstants.CONVERGENCE_CHECK_PERIOD; + this.finalTemperature = FDLayoutConstants.CONVERGENCE_CHECK_PERIOD / this.maxIterations; + this.coolingAdjuster = 1; + } +}; + +CoSELayout.prototype.layout = function () { + var createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED; + if (createBendsAsNeeded) { + this.createBendpoints(); + this.graphManager.resetAllEdges(); + } + + this.level = 0; + return this.classicLayout(); +}; + +CoSELayout.prototype.classicLayout = function () { + this.nodesWithGravity = this.calculateNodesToApplyGravitationTo(); + this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity); + this.calcNoOfChildrenForAllNodes(); + this.graphManager.calcLowestCommonAncestors(); + this.graphManager.calcInclusionTreeDepths(); + this.graphManager.getRoot().calcEstimatedSize(); + this.calcIdealEdgeLengths(); + + if (!this.incremental) { + var forest = this.getFlatForest(); + + // The graph associated with this layout is flat and a forest + if (forest.length > 0) { + this.positionNodesRadially(forest); + } + // The graph associated with this layout is not flat or a forest + else { + // Reduce the trees when incremental mode is not enabled and graph is not a forest + this.reduceTrees(); + // Update nodes that gravity will be applied + this.graphManager.resetAllNodesToApplyGravitation(); + var allNodes = new Set(this.getAllNodes()); + var intersection = this.nodesWithGravity.filter(function (x) { + return allNodes.has(x); + }); + this.graphManager.setAllNodesToApplyGravitation(intersection); + + this.positionNodesRandomly(); + } + } else { + if (CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL) { + // Reduce the trees in incremental mode if only this constant is set to true + this.reduceTrees(); + // Update nodes that gravity will be applied + this.graphManager.resetAllNodesToApplyGravitation(); + var allNodes = new Set(this.getAllNodes()); + var intersection = this.nodesWithGravity.filter(function (x) { + return allNodes.has(x); + }); + this.graphManager.setAllNodesToApplyGravitation(intersection); + } + } + + this.initSpringEmbedder(); + this.runSpringEmbedder(); + + return true; +}; + +CoSELayout.prototype.tick = function () { + this.totalIterations++; + + if (this.totalIterations === this.maxIterations && !this.isTreeGrowing && !this.isGrowthFinished) { + if (this.prunedNodesAll.length > 0) { + this.isTreeGrowing = true; + } else { + return true; + } + } + + if (this.totalIterations % FDLayoutConstants.CONVERGENCE_CHECK_PERIOD == 0 && !this.isTreeGrowing && !this.isGrowthFinished) { + if (this.isConverged()) { + if (this.prunedNodesAll.length > 0) { + this.isTreeGrowing = true; + } else { + return true; + } + } + + this.coolingCycle++; + + if (this.layoutQuality == 0) { + // quality - "draft" + this.coolingAdjuster = this.coolingCycle; + } else if (this.layoutQuality == 1) { + // quality - "default" + this.coolingAdjuster = this.coolingCycle / 3; + } + + // cooling schedule is based on http://www.btluke.com/simanf1.html -> cooling schedule 3 + this.coolingFactor = Math.max(this.initialCoolingFactor - Math.pow(this.coolingCycle, Math.log(100 * (this.initialCoolingFactor - this.finalTemperature)) / Math.log(this.maxCoolingCycle)) / 100 * this.coolingAdjuster, this.finalTemperature); + this.animationPeriod = Math.ceil(this.initialAnimationPeriod * Math.sqrt(this.coolingFactor)); + } + // Operations while tree is growing again + if (this.isTreeGrowing) { + if (this.growTreeIterations % 10 == 0) { + if (this.prunedNodesAll.length > 0) { + this.graphManager.updateBounds(); + this.updateGrid(); + this.growTree(this.prunedNodesAll); + // Update nodes that gravity will be applied + this.graphManager.resetAllNodesToApplyGravitation(); + var allNodes = new Set(this.getAllNodes()); + var intersection = this.nodesWithGravity.filter(function (x) { + return allNodes.has(x); + }); + this.graphManager.setAllNodesToApplyGravitation(intersection); + + this.graphManager.updateBounds(); + this.updateGrid(); + this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL; + } else { + this.isTreeGrowing = false; + this.isGrowthFinished = true; + } + } + this.growTreeIterations++; + } + // Operations after growth is finished + if (this.isGrowthFinished) { + if (this.isConverged()) { + return true; + } + if (this.afterGrowthIterations % 10 == 0) { + this.graphManager.updateBounds(); + this.updateGrid(); + } + this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL * ((100 - this.afterGrowthIterations) / 100); + this.afterGrowthIterations++; + } + + var gridUpdateAllowed = !this.isTreeGrowing && !this.isGrowthFinished; + var forceToNodeSurroundingUpdate = this.growTreeIterations % 10 == 1 && this.isTreeGrowing || this.afterGrowthIterations % 10 == 1 && this.isGrowthFinished; + + this.totalDisplacement = 0; + this.graphManager.updateBounds(); + this.calcSpringForces(); + this.calcRepulsionForces(gridUpdateAllowed, forceToNodeSurroundingUpdate); + this.calcGravitationalForces(); + this.moveNodes(); + this.animate(); + + return false; // Layout is not ended yet return false +}; + +CoSELayout.prototype.getPositionsData = function () { + var allNodes = this.graphManager.getAllNodes(); + var pData = {}; + for (var i = 0; i < allNodes.length; i++) { + var rect = allNodes[i].rect; + var id = allNodes[i].id; + pData[id] = { + id: id, + x: rect.getCenterX(), + y: rect.getCenterY(), + w: rect.width, + h: rect.height + }; + } + + return pData; +}; + +CoSELayout.prototype.runSpringEmbedder = function () { + this.initialAnimationPeriod = 25; + this.animationPeriod = this.initialAnimationPeriod; + var layoutEnded = false; + + // If aminate option is 'during' signal that layout is supposed to start iterating + if (FDLayoutConstants.ANIMATE === 'during') { + this.emit('layoutstarted'); + } else { + // If aminate option is 'during' tick() function will be called on index.js + while (!layoutEnded) { + layoutEnded = this.tick(); + } + + this.graphManager.updateBounds(); + } +}; + +CoSELayout.prototype.calculateNodesToApplyGravitationTo = function () { + var nodeList = []; + var graph; + + var graphs = this.graphManager.getGraphs(); + var size = graphs.length; + var i; + for (i = 0; i < size; i++) { + graph = graphs[i]; + + graph.updateConnected(); + + if (!graph.isConnected) { + nodeList = nodeList.concat(graph.getNodes()); + } + } + + return nodeList; +}; + +CoSELayout.prototype.createBendpoints = function () { + var edges = []; + edges = edges.concat(this.graphManager.getAllEdges()); + var visited = new Set(); + var i; + for (i = 0; i < edges.length; i++) { + var edge = edges[i]; + + if (!visited.has(edge)) { + var source = edge.getSource(); + var target = edge.getTarget(); + + if (source == target) { + edge.getBendpoints().push(new PointD()); + edge.getBendpoints().push(new PointD()); + this.createDummyNodesForBendpoints(edge); + visited.add(edge); + } else { + var edgeList = []; + + edgeList = edgeList.concat(source.getEdgeListToNode(target)); + edgeList = edgeList.concat(target.getEdgeListToNode(source)); + + if (!visited.has(edgeList[0])) { + if (edgeList.length > 1) { + var k; + for (k = 0; k < edgeList.length; k++) { + var multiEdge = edgeList[k]; + multiEdge.getBendpoints().push(new PointD()); + this.createDummyNodesForBendpoints(multiEdge); + } + } + edgeList.forEach(function (edge) { + visited.add(edge); + }); + } + } + } + + if (visited.size == edges.length) { + break; + } + } +}; + +CoSELayout.prototype.positionNodesRadially = function (forest) { + // We tile the trees to a grid row by row; first tree starts at (0,0) + var currentStartingPoint = new Point(0, 0); + var numberOfColumns = Math.ceil(Math.sqrt(forest.length)); + var height = 0; + var currentY = 0; + var currentX = 0; + var point = new PointD(0, 0); + + for (var i = 0; i < forest.length; i++) { + if (i % numberOfColumns == 0) { + // Start of a new row, make the x coordinate 0, increment the + // y coordinate with the max height of the previous row + currentX = 0; + currentY = height; + + if (i != 0) { + currentY += CoSEConstants.DEFAULT_COMPONENT_SEPERATION; + } + + height = 0; + } + + var tree = forest[i]; + + // Find the center of the tree + var centerNode = Layout.findCenterOfTree(tree); + + // Set the staring point of the next tree + currentStartingPoint.x = currentX; + currentStartingPoint.y = currentY; + + // Do a radial layout starting with the center + point = CoSELayout.radialLayout(tree, centerNode, currentStartingPoint); + + if (point.y > height) { + height = Math.floor(point.y); + } + + currentX = Math.floor(point.x + CoSEConstants.DEFAULT_COMPONENT_SEPERATION); + } + + this.transform(new PointD(LayoutConstants.WORLD_CENTER_X - point.x / 2, LayoutConstants.WORLD_CENTER_Y - point.y / 2)); +}; + +CoSELayout.radialLayout = function (tree, centerNode, startingPoint) { + var radialSep = Math.max(this.maxDiagonalInTree(tree), CoSEConstants.DEFAULT_RADIAL_SEPARATION); + CoSELayout.branchRadialLayout(centerNode, null, 0, 359, 0, radialSep); + var bounds = LGraph.calculateBounds(tree); + + var transform = new Transform(); + transform.setDeviceOrgX(bounds.getMinX()); + transform.setDeviceOrgY(bounds.getMinY()); + transform.setWorldOrgX(startingPoint.x); + transform.setWorldOrgY(startingPoint.y); + + for (var i = 0; i < tree.length; i++) { + var node = tree[i]; + node.transform(transform); + } + + var bottomRight = new PointD(bounds.getMaxX(), bounds.getMaxY()); + + return transform.inverseTransformPoint(bottomRight); +}; + +CoSELayout.branchRadialLayout = function (node, parentOfNode, startAngle, endAngle, distance, radialSeparation) { + // First, position this node by finding its angle. + var halfInterval = (endAngle - startAngle + 1) / 2; + + if (halfInterval < 0) { + halfInterval += 180; + } + + var nodeAngle = (halfInterval + startAngle) % 360; + var teta = nodeAngle * IGeometry.TWO_PI / 360; + + // Make polar to java cordinate conversion. + var cos_teta = Math.cos(teta); + var x_ = distance * Math.cos(teta); + var y_ = distance * Math.sin(teta); + + node.setCenter(x_, y_); + + // Traverse all neighbors of this node and recursively call this + // function. + var neighborEdges = []; + neighborEdges = neighborEdges.concat(node.getEdges()); + var childCount = neighborEdges.length; + + if (parentOfNode != null) { + childCount--; + } + + var branchCount = 0; + + var incEdgesCount = neighborEdges.length; + var startIndex; + + var edges = node.getEdgesBetween(parentOfNode); + + // If there are multiple edges, prune them until there remains only one + // edge. + while (edges.length > 1) { + //neighborEdges.remove(edges.remove(0)); + var temp = edges[0]; + edges.splice(0, 1); + var index = neighborEdges.indexOf(temp); + if (index >= 0) { + neighborEdges.splice(index, 1); + } + incEdgesCount--; + childCount--; + } + + if (parentOfNode != null) { + //assert edges.length == 1; + startIndex = (neighborEdges.indexOf(edges[0]) + 1) % incEdgesCount; + } else { + startIndex = 0; + } + + var stepAngle = Math.abs(endAngle - startAngle) / childCount; + + for (var i = startIndex; branchCount != childCount; i = ++i % incEdgesCount) { + var currentNeighbor = neighborEdges[i].getOtherEnd(node); + + // Don't back traverse to root node in current tree. + if (currentNeighbor == parentOfNode) { + continue; + } + + var childStartAngle = (startAngle + branchCount * stepAngle) % 360; + var childEndAngle = (childStartAngle + stepAngle) % 360; + + CoSELayout.branchRadialLayout(currentNeighbor, node, childStartAngle, childEndAngle, distance + radialSeparation, radialSeparation); + + branchCount++; + } +}; + +CoSELayout.maxDiagonalInTree = function (tree) { + var maxDiagonal = Integer.MIN_VALUE; + + for (var i = 0; i < tree.length; i++) { + var node = tree[i]; + var diagonal = node.getDiagonal(); + + if (diagonal > maxDiagonal) { + maxDiagonal = diagonal; + } + } + + return maxDiagonal; +}; + +CoSELayout.prototype.calcRepulsionRange = function () { + // formula is 2 x (level + 1) x idealEdgeLength + return 2 * (this.level + 1) * this.idealEdgeLength; +}; + +// Tiling methods + +// Group zero degree members whose parents are not to be tiled, create dummy parents where needed and fill memberGroups by their dummp parent id's +CoSELayout.prototype.groupZeroDegreeMembers = function () { + var self = this; + // array of [parent_id x oneDegreeNode_id] + var tempMemberGroups = {}; // A temporary map of parent node and its zero degree members + this.memberGroups = {}; // A map of dummy parent node and its zero degree members whose parents are not to be tiled + this.idToDummyNode = {}; // A map of id to dummy node + + var zeroDegree = []; // List of zero degree nodes whose parents are not to be tiled + var allNodes = this.graphManager.getAllNodes(); + + // Fill zero degree list + for (var i = 0; i < allNodes.length; i++) { + var node = allNodes[i]; + var parent = node.getParent(); + // If a node has zero degree and its parent is not to be tiled if exists add that node to zeroDegres list + if (this.getNodeDegreeWithChildren(node) === 0 && (parent.id == undefined || !this.getToBeTiled(parent))) { + zeroDegree.push(node); + } + } + + // Create a map of parent node and its zero degree members + for (var i = 0; i < zeroDegree.length; i++) { + var node = zeroDegree[i]; // Zero degree node itself + var p_id = node.getParent().id; // Parent id + + if (typeof tempMemberGroups[p_id] === "undefined") tempMemberGroups[p_id] = []; + + tempMemberGroups[p_id] = tempMemberGroups[p_id].concat(node); // Push node to the list belongs to its parent in tempMemberGroups + } + + // If there are at least two nodes at a level, create a dummy compound for them + Object.keys(tempMemberGroups).forEach(function (p_id) { + if (tempMemberGroups[p_id].length > 1) { + var dummyCompoundId = "DummyCompound_" + p_id; // The id of dummy compound which will be created soon + self.memberGroups[dummyCompoundId] = tempMemberGroups[p_id]; // Add dummy compound to memberGroups + + var parent = tempMemberGroups[p_id][0].getParent(); // The parent of zero degree nodes will be the parent of new dummy compound + + // Create a dummy compound with calculated id + var dummyCompound = new CoSENode(self.graphManager); + dummyCompound.id = dummyCompoundId; + dummyCompound.paddingLeft = parent.paddingLeft || 0; + dummyCompound.paddingRight = parent.paddingRight || 0; + dummyCompound.paddingBottom = parent.paddingBottom || 0; + dummyCompound.paddingTop = parent.paddingTop || 0; + + self.idToDummyNode[dummyCompoundId] = dummyCompound; + + var dummyParentGraph = self.getGraphManager().add(self.newGraph(), dummyCompound); + var parentGraph = parent.getChild(); + + // Add dummy compound to parent the graph + parentGraph.add(dummyCompound); + + // For each zero degree node in this level remove it from its parent graph and add it to the graph of dummy parent + for (var i = 0; i < tempMemberGroups[p_id].length; i++) { + var node = tempMemberGroups[p_id][i]; + + parentGraph.remove(node); + dummyParentGraph.add(node); + } + } + }); +}; + +CoSELayout.prototype.clearCompounds = function () { + var childGraphMap = {}; + var idToNode = {}; + + // Get compound ordering by finding the inner one first + this.performDFSOnCompounds(); + + for (var i = 0; i < this.compoundOrder.length; i++) { + + idToNode[this.compoundOrder[i].id] = this.compoundOrder[i]; + childGraphMap[this.compoundOrder[i].id] = [].concat(this.compoundOrder[i].getChild().getNodes()); + + // Remove children of compounds + this.graphManager.remove(this.compoundOrder[i].getChild()); + this.compoundOrder[i].child = null; + } + + this.graphManager.resetAllNodes(); + + // Tile the removed children + this.tileCompoundMembers(childGraphMap, idToNode); +}; + +CoSELayout.prototype.clearZeroDegreeMembers = function () { + var self = this; + var tiledZeroDegreePack = this.tiledZeroDegreePack = []; + + Object.keys(this.memberGroups).forEach(function (id) { + var compoundNode = self.idToDummyNode[id]; // Get the dummy compound + + tiledZeroDegreePack[id] = self.tileNodes(self.memberGroups[id], compoundNode.paddingLeft + compoundNode.paddingRight); + + // Set the width and height of the dummy compound as calculated + compoundNode.rect.width = tiledZeroDegreePack[id].width; + compoundNode.rect.height = tiledZeroDegreePack[id].height; + }); +}; + +CoSELayout.prototype.repopulateCompounds = function () { + for (var i = this.compoundOrder.length - 1; i >= 0; i--) { + var lCompoundNode = this.compoundOrder[i]; + var id = lCompoundNode.id; + var horizontalMargin = lCompoundNode.paddingLeft; + var verticalMargin = lCompoundNode.paddingTop; + + this.adjustLocations(this.tiledMemberPack[id], lCompoundNode.rect.x, lCompoundNode.rect.y, horizontalMargin, verticalMargin); + } +}; + +CoSELayout.prototype.repopulateZeroDegreeMembers = function () { + var self = this; + var tiledPack = this.tiledZeroDegreePack; + + Object.keys(tiledPack).forEach(function (id) { + var compoundNode = self.idToDummyNode[id]; // Get the dummy compound by its id + var horizontalMargin = compoundNode.paddingLeft; + var verticalMargin = compoundNode.paddingTop; + + // Adjust the positions of nodes wrt its compound + self.adjustLocations(tiledPack[id], compoundNode.rect.x, compoundNode.rect.y, horizontalMargin, verticalMargin); + }); +}; + +CoSELayout.prototype.getToBeTiled = function (node) { + var id = node.id; + //firstly check the previous results + if (this.toBeTiled[id] != null) { + return this.toBeTiled[id]; + } + + //only compound nodes are to be tiled + var childGraph = node.getChild(); + if (childGraph == null) { + this.toBeTiled[id] = false; + return false; + } + + var children = childGraph.getNodes(); // Get the children nodes + + //a compound node is not to be tiled if all of its compound children are not to be tiled + for (var i = 0; i < children.length; i++) { + var theChild = children[i]; + + if (this.getNodeDegree(theChild) > 0) { + this.toBeTiled[id] = false; + return false; + } + + //pass the children not having the compound structure + if (theChild.getChild() == null) { + this.toBeTiled[theChild.id] = false; + continue; + } + + if (!this.getToBeTiled(theChild)) { + this.toBeTiled[id] = false; + return false; + } + } + this.toBeTiled[id] = true; + return true; +}; + +// Get degree of a node depending of its edges and independent of its children +CoSELayout.prototype.getNodeDegree = function (node) { + var id = node.id; + var edges = node.getEdges(); + var degree = 0; + + // For the edges connected + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + if (edge.getSource().id !== edge.getTarget().id) { + degree = degree + 1; + } + } + return degree; +}; + +// Get degree of a node with its children +CoSELayout.prototype.getNodeDegreeWithChildren = function (node) { + var degree = this.getNodeDegree(node); + if (node.getChild() == null) { + return degree; + } + var children = node.getChild().getNodes(); + for (var i = 0; i < children.length; i++) { + var child = children[i]; + degree += this.getNodeDegreeWithChildren(child); + } + return degree; +}; + +CoSELayout.prototype.performDFSOnCompounds = function () { + this.compoundOrder = []; + this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes()); +}; + +CoSELayout.prototype.fillCompexOrderByDFS = function (children) { + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child.getChild() != null) { + this.fillCompexOrderByDFS(child.getChild().getNodes()); + } + if (this.getToBeTiled(child)) { + this.compoundOrder.push(child); + } + } +}; + +/** +* This method places each zero degree member wrt given (x,y) coordinates (top left). +*/ +CoSELayout.prototype.adjustLocations = function (organization, x, y, compoundHorizontalMargin, compoundVerticalMargin) { + x += compoundHorizontalMargin; + y += compoundVerticalMargin; + + var left = x; + + for (var i = 0; i < organization.rows.length; i++) { + var row = organization.rows[i]; + x = left; + var maxHeight = 0; + + for (var j = 0; j < row.length; j++) { + var lnode = row[j]; + + lnode.rect.x = x; // + lnode.rect.width / 2; + lnode.rect.y = y; // + lnode.rect.height / 2; + + x += lnode.rect.width + organization.horizontalPadding; + + if (lnode.rect.height > maxHeight) maxHeight = lnode.rect.height; + } + + y += maxHeight + organization.verticalPadding; + } +}; + +CoSELayout.prototype.tileCompoundMembers = function (childGraphMap, idToNode) { + var self = this; + this.tiledMemberPack = []; + + Object.keys(childGraphMap).forEach(function (id) { + // Get the compound node + var compoundNode = idToNode[id]; + + self.tiledMemberPack[id] = self.tileNodes(childGraphMap[id], compoundNode.paddingLeft + compoundNode.paddingRight); + + compoundNode.rect.width = self.tiledMemberPack[id].width; + compoundNode.rect.height = self.tiledMemberPack[id].height; + }); +}; + +CoSELayout.prototype.tileNodes = function (nodes, minWidth) { + var verticalPadding = CoSEConstants.TILING_PADDING_VERTICAL; + var horizontalPadding = CoSEConstants.TILING_PADDING_HORIZONTAL; + var organization = { + rows: [], + rowWidth: [], + rowHeight: [], + width: 0, + height: minWidth, // assume minHeight equals to minWidth + verticalPadding: verticalPadding, + horizontalPadding: horizontalPadding + }; + + // Sort the nodes in ascending order of their areas + nodes.sort(function (n1, n2) { + if (n1.rect.width * n1.rect.height > n2.rect.width * n2.rect.height) return -1; + if (n1.rect.width * n1.rect.height < n2.rect.width * n2.rect.height) return 1; + return 0; + }); + + // Create the organization -> tile members + for (var i = 0; i < nodes.length; i++) { + var lNode = nodes[i]; + + if (organization.rows.length == 0) { + this.insertNodeToRow(organization, lNode, 0, minWidth); + } else if (this.canAddHorizontal(organization, lNode.rect.width, lNode.rect.height)) { + this.insertNodeToRow(organization, lNode, this.getShortestRowIndex(organization), minWidth); + } else { + this.insertNodeToRow(organization, lNode, organization.rows.length, minWidth); + } + + this.shiftToLastRow(organization); + } + + return organization; +}; + +CoSELayout.prototype.insertNodeToRow = function (organization, node, rowIndex, minWidth) { + var minCompoundSize = minWidth; + + // Add new row if needed + if (rowIndex == organization.rows.length) { + var secondDimension = []; + + organization.rows.push(secondDimension); + organization.rowWidth.push(minCompoundSize); + organization.rowHeight.push(0); + } + + // Update row width + var w = organization.rowWidth[rowIndex] + node.rect.width; + + if (organization.rows[rowIndex].length > 0) { + w += organization.horizontalPadding; + } + + organization.rowWidth[rowIndex] = w; + // Update compound width + if (organization.width < w) { + organization.width = w; + } + + // Update height + var h = node.rect.height; + if (rowIndex > 0) h += organization.verticalPadding; + + var extraHeight = 0; + if (h > organization.rowHeight[rowIndex]) { + extraHeight = organization.rowHeight[rowIndex]; + organization.rowHeight[rowIndex] = h; + extraHeight = organization.rowHeight[rowIndex] - extraHeight; + } + + organization.height += extraHeight; + + // Insert node + organization.rows[rowIndex].push(node); +}; + +//Scans the rows of an organization and returns the one with the min width +CoSELayout.prototype.getShortestRowIndex = function (organization) { + var r = -1; + var min = Number.MAX_VALUE; + + for (var i = 0; i < organization.rows.length; i++) { + if (organization.rowWidth[i] < min) { + r = i; + min = organization.rowWidth[i]; + } + } + return r; +}; + +//Scans the rows of an organization and returns the one with the max width +CoSELayout.prototype.getLongestRowIndex = function (organization) { + var r = -1; + var max = Number.MIN_VALUE; + + for (var i = 0; i < organization.rows.length; i++) { + + if (organization.rowWidth[i] > max) { + r = i; + max = organization.rowWidth[i]; + } + } + + return r; +}; + +/** +* This method checks whether adding extra width to the organization violates +* the aspect ratio(1) or not. +*/ +CoSELayout.prototype.canAddHorizontal = function (organization, extraWidth, extraHeight) { + + var sri = this.getShortestRowIndex(organization); + + if (sri < 0) { + return true; + } + + var min = organization.rowWidth[sri]; + + if (min + organization.horizontalPadding + extraWidth <= organization.width) return true; + + var hDiff = 0; + + // Adding to an existing row + if (organization.rowHeight[sri] < extraHeight) { + if (sri > 0) hDiff = extraHeight + organization.verticalPadding - organization.rowHeight[sri]; + } + + var add_to_row_ratio; + if (organization.width - min >= extraWidth + organization.horizontalPadding) { + add_to_row_ratio = (organization.height + hDiff) / (min + extraWidth + organization.horizontalPadding); + } else { + add_to_row_ratio = (organization.height + hDiff) / organization.width; + } + + // Adding a new row for this node + hDiff = extraHeight + organization.verticalPadding; + var add_new_row_ratio; + if (organization.width < extraWidth) { + add_new_row_ratio = (organization.height + hDiff) / extraWidth; + } else { + add_new_row_ratio = (organization.height + hDiff) / organization.width; + } + + if (add_new_row_ratio < 1) add_new_row_ratio = 1 / add_new_row_ratio; + + if (add_to_row_ratio < 1) add_to_row_ratio = 1 / add_to_row_ratio; + + return add_to_row_ratio < add_new_row_ratio; +}; + +//If moving the last node from the longest row and adding it to the last +//row makes the bounding box smaller, do it. +CoSELayout.prototype.shiftToLastRow = function (organization) { + var longest = this.getLongestRowIndex(organization); + var last = organization.rowWidth.length - 1; + var row = organization.rows[longest]; + var node = row[row.length - 1]; + + var diff = node.width + organization.horizontalPadding; + + // Check if there is enough space on the last row + if (organization.width - organization.rowWidth[last] > diff && longest != last) { + // Remove the last element of the longest row + row.splice(-1, 1); + + // Push it to the last row + organization.rows[last].push(node); + + organization.rowWidth[longest] = organization.rowWidth[longest] - diff; + organization.rowWidth[last] = organization.rowWidth[last] + diff; + organization.width = organization.rowWidth[instance.getLongestRowIndex(organization)]; + + // Update heights of the organization + var maxHeight = Number.MIN_VALUE; + for (var i = 0; i < row.length; i++) { + if (row[i].height > maxHeight) maxHeight = row[i].height; + } + if (longest > 0) maxHeight += organization.verticalPadding; + + var prevTotal = organization.rowHeight[longest] + organization.rowHeight[last]; + + organization.rowHeight[longest] = maxHeight; + if (organization.rowHeight[last] < node.height + organization.verticalPadding) organization.rowHeight[last] = node.height + organization.verticalPadding; + + var finalTotal = organization.rowHeight[longest] + organization.rowHeight[last]; + organization.height += finalTotal - prevTotal; + + this.shiftToLastRow(organization); + } +}; + +CoSELayout.prototype.tilingPreLayout = function () { + if (CoSEConstants.TILE) { + // Find zero degree nodes and create a compound for each level + this.groupZeroDegreeMembers(); + // Tile and clear children of each compound + this.clearCompounds(); + // Separately tile and clear zero degree nodes for each level + this.clearZeroDegreeMembers(); + } +}; + +CoSELayout.prototype.tilingPostLayout = function () { + if (CoSEConstants.TILE) { + this.repopulateZeroDegreeMembers(); + this.repopulateCompounds(); + } +}; + +// ----------------------------------------------------------------------------- +// Section: Tree Reduction methods +// ----------------------------------------------------------------------------- +// Reduce trees +CoSELayout.prototype.reduceTrees = function () { + var prunedNodesAll = []; + var containsLeaf = true; + var node; + + while (containsLeaf) { + var allNodes = this.graphManager.getAllNodes(); + var prunedNodesInStepTemp = []; + containsLeaf = false; + + for (var i = 0; i < allNodes.length; i++) { + node = allNodes[i]; + if (node.getEdges().length == 1 && !node.getEdges()[0].isInterGraph && node.getChild() == null) { + prunedNodesInStepTemp.push([node, node.getEdges()[0], node.getOwner()]); + containsLeaf = true; + } + } + if (containsLeaf == true) { + var prunedNodesInStep = []; + for (var j = 0; j < prunedNodesInStepTemp.length; j++) { + if (prunedNodesInStepTemp[j][0].getEdges().length == 1) { + prunedNodesInStep.push(prunedNodesInStepTemp[j]); + prunedNodesInStepTemp[j][0].getOwner().remove(prunedNodesInStepTemp[j][0]); + } + } + prunedNodesAll.push(prunedNodesInStep); + this.graphManager.resetAllNodes(); + this.graphManager.resetAllEdges(); + } + } + this.prunedNodesAll = prunedNodesAll; +}; + +// Grow tree one step +CoSELayout.prototype.growTree = function (prunedNodesAll) { + var lengthOfPrunedNodesInStep = prunedNodesAll.length; + var prunedNodesInStep = prunedNodesAll[lengthOfPrunedNodesInStep - 1]; + + var nodeData; + for (var i = 0; i < prunedNodesInStep.length; i++) { + nodeData = prunedNodesInStep[i]; + + this.findPlaceforPrunedNode(nodeData); + + nodeData[2].add(nodeData[0]); + nodeData[2].add(nodeData[1], nodeData[1].source, nodeData[1].target); + } + + prunedNodesAll.splice(prunedNodesAll.length - 1, 1); + this.graphManager.resetAllNodes(); + this.graphManager.resetAllEdges(); +}; + +// Find an appropriate position to replace pruned node, this method can be improved +CoSELayout.prototype.findPlaceforPrunedNode = function (nodeData) { + + var gridForPrunedNode; + var nodeToConnect; + var prunedNode = nodeData[0]; + if (prunedNode == nodeData[1].source) { + nodeToConnect = nodeData[1].target; + } else { + nodeToConnect = nodeData[1].source; + } + var startGridX = nodeToConnect.startX; + var finishGridX = nodeToConnect.finishX; + var startGridY = nodeToConnect.startY; + var finishGridY = nodeToConnect.finishY; + + var upNodeCount = 0; + var downNodeCount = 0; + var rightNodeCount = 0; + var leftNodeCount = 0; + var controlRegions = [upNodeCount, rightNodeCount, downNodeCount, leftNodeCount]; + + if (startGridY > 0) { + for (var i = startGridX; i <= finishGridX; i++) { + controlRegions[0] += this.grid[i][startGridY - 1].length + this.grid[i][startGridY].length - 1; + } + } + if (finishGridX < this.grid.length - 1) { + for (var i = startGridY; i <= finishGridY; i++) { + controlRegions[1] += this.grid[finishGridX + 1][i].length + this.grid[finishGridX][i].length - 1; + } + } + if (finishGridY < this.grid[0].length - 1) { + for (var i = startGridX; i <= finishGridX; i++) { + controlRegions[2] += this.grid[i][finishGridY + 1].length + this.grid[i][finishGridY].length - 1; + } + } + if (startGridX > 0) { + for (var i = startGridY; i <= finishGridY; i++) { + controlRegions[3] += this.grid[startGridX - 1][i].length + this.grid[startGridX][i].length - 1; + } + } + var min = Integer.MAX_VALUE; + var minCount; + var minIndex; + for (var j = 0; j < controlRegions.length; j++) { + if (controlRegions[j] < min) { + min = controlRegions[j]; + minCount = 1; + minIndex = j; + } else if (controlRegions[j] == min) { + minCount++; + } + } + + if (minCount == 3 && min == 0) { + if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[2] == 0) { + gridForPrunedNode = 1; + } else if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[3] == 0) { + gridForPrunedNode = 0; + } else if (controlRegions[0] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) { + gridForPrunedNode = 3; + } else if (controlRegions[1] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) { + gridForPrunedNode = 2; + } + } else if (minCount == 2 && min == 0) { + var random = Math.floor(Math.random() * 2); + if (controlRegions[0] == 0 && controlRegions[1] == 0) { + ; + if (random == 0) { + gridForPrunedNode = 0; + } else { + gridForPrunedNode = 1; + } + } else if (controlRegions[0] == 0 && controlRegions[2] == 0) { + if (random == 0) { + gridForPrunedNode = 0; + } else { + gridForPrunedNode = 2; + } + } else if (controlRegions[0] == 0 && controlRegions[3] == 0) { + if (random == 0) { + gridForPrunedNode = 0; + } else { + gridForPrunedNode = 3; + } + } else if (controlRegions[1] == 0 && controlRegions[2] == 0) { + if (random == 0) { + gridForPrunedNode = 1; + } else { + gridForPrunedNode = 2; + } + } else if (controlRegions[1] == 0 && controlRegions[3] == 0) { + if (random == 0) { + gridForPrunedNode = 1; + } else { + gridForPrunedNode = 3; + } + } else { + if (random == 0) { + gridForPrunedNode = 2; + } else { + gridForPrunedNode = 3; + } + } + } else if (minCount == 4 && min == 0) { + var random = Math.floor(Math.random() * 4); + gridForPrunedNode = random; + } else { + gridForPrunedNode = minIndex; + } + + if (gridForPrunedNode == 0) { + prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() - nodeToConnect.getHeight() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getHeight() / 2); + } else if (gridForPrunedNode == 1) { + prunedNode.setCenter(nodeToConnect.getCenterX() + nodeToConnect.getWidth() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getWidth() / 2, nodeToConnect.getCenterY()); + } else if (gridForPrunedNode == 2) { + prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() + nodeToConnect.getHeight() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getHeight() / 2); + } else { + prunedNode.setCenter(nodeToConnect.getCenterX() - nodeToConnect.getWidth() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getWidth() / 2, nodeToConnect.getCenterY()); + } +}; + +module.exports = CoSELayout; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __nested_webpack_require_45620__) { + +"use strict"; + + +var coseBase = {}; + +coseBase.layoutBase = __nested_webpack_require_45620__(0); +coseBase.CoSEConstants = __nested_webpack_require_45620__(1); +coseBase.CoSEEdge = __nested_webpack_require_45620__(2); +coseBase.CoSEGraph = __nested_webpack_require_45620__(3); +coseBase.CoSEGraphManager = __nested_webpack_require_45620__(4); +coseBase.CoSELayout = __nested_webpack_require_45620__(6); +coseBase.CoSENode = __nested_webpack_require_45620__(5); + +module.exports = coseBase; + +/***/ }) +/******/ ]); +}); + +/***/ }), + +/***/ 14607: +/***/ (function(module, __unused_webpack_exports, __webpack_require__) { + +(function webpackUniversalModuleDefinition(root, factory) { + if(true) + module.exports = factory(__webpack_require__(84182)); + else {} +})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __nested_webpack_require_659__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_659__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __nested_webpack_require_659__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __nested_webpack_require_659__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __nested_webpack_require_659__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __nested_webpack_require_659__.d = function(exports, name, getter) { +/******/ if(!__nested_webpack_require_659__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __nested_webpack_require_659__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __nested_webpack_require_659__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __nested_webpack_require_659__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __nested_webpack_require_659__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __nested_webpack_require_659__(__nested_webpack_require_659__.s = 1); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = __WEBPACK_EXTERNAL_MODULE_0__; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __nested_webpack_require_3201__) { + +"use strict"; + + +var LayoutConstants = __nested_webpack_require_3201__(0).layoutBase.LayoutConstants; +var FDLayoutConstants = __nested_webpack_require_3201__(0).layoutBase.FDLayoutConstants; +var CoSEConstants = __nested_webpack_require_3201__(0).CoSEConstants; +var CoSELayout = __nested_webpack_require_3201__(0).CoSELayout; +var CoSENode = __nested_webpack_require_3201__(0).CoSENode; +var PointD = __nested_webpack_require_3201__(0).layoutBase.PointD; +var DimensionD = __nested_webpack_require_3201__(0).layoutBase.DimensionD; + +var defaults = { + // Called on `layoutready` + ready: function ready() {}, + // Called on `layoutstop` + stop: function stop() {}, + // 'draft', 'default' or 'proof" + // - 'draft' fast cooling rate + // - 'default' moderate cooling rate + // - "proof" slow cooling rate + quality: 'default', + // include labels in node dimensions + nodeDimensionsIncludeLabels: false, + // number of ticks per frame; higher is faster but more jerky + refresh: 30, + // Whether to fit the network view after when done + fit: true, + // Padding on fit + padding: 10, + // Whether to enable incremental mode + randomize: true, + // Node repulsion (non overlapping) multiplier + nodeRepulsion: 4500, + // Ideal edge (non nested) length + idealEdgeLength: 50, + // Divisor to compute edge forces + edgeElasticity: 0.45, + // Nesting factor (multiplier) to compute ideal edge length for nested edges + nestingFactor: 0.1, + // Gravity force (constant) + gravity: 0.25, + // Maximum number of iterations to perform + numIter: 2500, + // For enabling tiling + tile: true, + // Type of layout animation. The option set is {'during', 'end', false} + animate: 'end', + // Duration for animate:end + animationDuration: 500, + // Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function) + tilingPaddingVertical: 10, + // Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function) + tilingPaddingHorizontal: 10, + // Gravity range (constant) for compounds + gravityRangeCompound: 1.5, + // Gravity force (constant) for compounds + gravityCompound: 1.0, + // Gravity range (constant) + gravityRange: 3.8, + // Initial cooling factor for incremental layout + initialEnergyOnIncremental: 0.5 +}; + +function extend(defaults, options) { + var obj = {}; + + for (var i in defaults) { + obj[i] = defaults[i]; + } + + for (var i in options) { + obj[i] = options[i]; + } + + return obj; +}; + +function _CoSELayout(_options) { + this.options = extend(defaults, _options); + getUserOptions(this.options); +} + +var getUserOptions = function getUserOptions(options) { + if (options.nodeRepulsion != null) CoSEConstants.DEFAULT_REPULSION_STRENGTH = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = options.nodeRepulsion; + if (options.idealEdgeLength != null) CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength; + if (options.edgeElasticity != null) CoSEConstants.DEFAULT_SPRING_STRENGTH = FDLayoutConstants.DEFAULT_SPRING_STRENGTH = options.edgeElasticity; + if (options.nestingFactor != null) CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor; + if (options.gravity != null) CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity; + if (options.numIter != null) CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter; + if (options.gravityRange != null) CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange; + if (options.gravityCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound; + if (options.gravityRangeCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound; + if (options.initialEnergyOnIncremental != null) CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental; + + if (options.quality == 'draft') LayoutConstants.QUALITY = 0;else if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 1; + + CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels; + CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = !options.randomize; + CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate; + CoSEConstants.TILE = options.tile; + CoSEConstants.TILING_PADDING_VERTICAL = typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical; + CoSEConstants.TILING_PADDING_HORIZONTAL = typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal; +}; + +_CoSELayout.prototype.run = function () { + var ready; + var frameId; + var options = this.options; + var idToLNode = this.idToLNode = {}; + var layout = this.layout = new CoSELayout(); + var self = this; + + self.stopped = false; + + this.cy = this.options.cy; + + this.cy.trigger({ type: 'layoutstart', layout: this }); + + var gm = layout.newGraphManager(); + this.gm = gm; + + var nodes = this.options.eles.nodes(); + var edges = this.options.eles.edges(); + + this.root = gm.addRoot(); + this.processChildrenList(this.root, this.getTopMostNodes(nodes), layout); + + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + var sourceNode = this.idToLNode[edge.data("source")]; + var targetNode = this.idToLNode[edge.data("target")]; + if (sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) { + var e1 = gm.add(layout.newEdge(), sourceNode, targetNode); + e1.id = edge.id(); + } + } + + var getPositions = function getPositions(ele, i) { + if (typeof ele === "number") { + ele = i; + } + var theId = ele.data('id'); + var lNode = self.idToLNode[theId]; + + return { + x: lNode.getRect().getCenterX(), + y: lNode.getRect().getCenterY() + }; + }; + + /* + * Reposition nodes in iterations animatedly + */ + var iterateAnimated = function iterateAnimated() { + // Thigs to perform after nodes are repositioned on screen + var afterReposition = function afterReposition() { + if (options.fit) { + options.cy.fit(options.eles, options.padding); + } + + if (!ready) { + ready = true; + self.cy.one('layoutready', options.ready); + self.cy.trigger({ type: 'layoutready', layout: self }); + } + }; + + var ticksPerFrame = self.options.refresh; + var isDone; + + for (var i = 0; i < ticksPerFrame && !isDone; i++) { + isDone = self.stopped || self.layout.tick(); + } + + // If layout is done + if (isDone) { + // If the layout is not a sublayout and it is successful perform post layout. + if (layout.checkLayoutSuccess() && !layout.isSubLayout) { + layout.doPostLayout(); + } + + // If layout has a tilingPostLayout function property call it. + if (layout.tilingPostLayout) { + layout.tilingPostLayout(); + } + + layout.isLayoutFinished = true; + + self.options.eles.nodes().positions(getPositions); + + afterReposition(); + + // trigger layoutstop when the layout stops (e.g. finishes) + self.cy.one('layoutstop', self.options.stop); + self.cy.trigger({ type: 'layoutstop', layout: self }); + + if (frameId) { + cancelAnimationFrame(frameId); + } + + ready = false; + return; + } + + var animationData = self.layout.getPositionsData(); // Get positions of layout nodes note that all nodes may not be layout nodes because of tiling + + // Position nodes, for the nodes whose id does not included in data (because they are removed from their parents and included in dummy compounds) + // use position of their ancestors or dummy ancestors + options.eles.nodes().positions(function (ele, i) { + if (typeof ele === "number") { + ele = i; + } + // If ele is a compound node, then its position will be defined by its children + if (!ele.isParent()) { + var theId = ele.id(); + var pNode = animationData[theId]; + var temp = ele; + // If pNode is undefined search until finding position data of its first ancestor (It may be dummy as well) + while (pNode == null) { + pNode = animationData[temp.data('parent')] || animationData['DummyCompound_' + temp.data('parent')]; + animationData[theId] = pNode; + temp = temp.parent()[0]; + if (temp == undefined) { + break; + } + } + if (pNode != null) { + return { + x: pNode.x, + y: pNode.y + }; + } else { + return { + x: ele.position('x'), + y: ele.position('y') + }; + } + } + }); + + afterReposition(); + + frameId = requestAnimationFrame(iterateAnimated); + }; + + /* + * Listen 'layoutstarted' event and start animated iteration if animate option is 'during' + */ + layout.addListener('layoutstarted', function () { + if (self.options.animate === 'during') { + frameId = requestAnimationFrame(iterateAnimated); + } + }); + + layout.runLayout(); // Run cose layout + + /* + * If animate option is not 'during' ('end' or false) perform these here (If it is 'during' similar things are already performed) + */ + if (this.options.animate !== "during") { + self.options.eles.nodes().not(":parent").layoutPositions(self, self.options, getPositions); // Use layout positions to reposition the nodes it considers the options parameter + ready = false; + } + + return this; // chaining +}; + +//Get the top most ones of a list of nodes +_CoSELayout.prototype.getTopMostNodes = function (nodes) { + var nodesMap = {}; + for (var i = 0; i < nodes.length; i++) { + nodesMap[nodes[i].id()] = true; + } + var roots = nodes.filter(function (ele, i) { + if (typeof ele === "number") { + ele = i; + } + var parent = ele.parent()[0]; + while (parent != null) { + if (nodesMap[parent.id()]) { + return false; + } + parent = parent.parent()[0]; + } + return true; + }); + + return roots; +}; + +_CoSELayout.prototype.processChildrenList = function (parent, children, layout) { + var size = children.length; + for (var i = 0; i < size; i++) { + var theChild = children[i]; + var children_of_children = theChild.children(); + var theNode; + + var dimensions = theChild.layoutDimensions({ + nodeDimensionsIncludeLabels: this.options.nodeDimensionsIncludeLabels + }); + + if (theChild.outerWidth() != null && theChild.outerHeight() != null) { + theNode = parent.add(new CoSENode(layout.graphManager, new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h)))); + } else { + theNode = parent.add(new CoSENode(this.graphManager)); + } + // Attach id to the layout node + theNode.id = theChild.data("id"); + // Attach the paddings of cy node to layout node + theNode.paddingLeft = parseInt(theChild.css('padding')); + theNode.paddingTop = parseInt(theChild.css('padding')); + theNode.paddingRight = parseInt(theChild.css('padding')); + theNode.paddingBottom = parseInt(theChild.css('padding')); + + //Attach the label properties to compound if labels will be included in node dimensions + if (this.options.nodeDimensionsIncludeLabels) { + if (theChild.isParent()) { + var labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false }).w; + var labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false }).h; + var labelPos = theChild.css("text-halign"); + theNode.labelWidth = labelWidth; + theNode.labelHeight = labelHeight; + theNode.labelPos = labelPos; + } + } + + // Map the layout node + this.idToLNode[theChild.data("id")] = theNode; + + if (isNaN(theNode.rect.x)) { + theNode.rect.x = 0; + } + + if (isNaN(theNode.rect.y)) { + theNode.rect.y = 0; + } + + if (children_of_children != null && children_of_children.length > 0) { + var theNewGraph; + theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode); + this.processChildrenList(theNewGraph, children_of_children, layout); + } + } +}; + +/** + * @brief : called on continuous layouts to stop them before they finish + */ +_CoSELayout.prototype.stop = function () { + this.stopped = true; + + return this; // chaining +}; + +var register = function register(cytoscape) { + // var Layout = getLayout( cytoscape ); + + cytoscape('layout', 'cose-bilkent', _CoSELayout); +}; + +// auto reg for globals +if (typeof cytoscape !== 'undefined') { + register(cytoscape); +} + +module.exports = register; + +/***/ }) +/******/ ]); +}); + +/***/ }), + +/***/ 71377: +/***/ (function(module) { + +/** + * Copyright (c) 2016-2023, The Cytoscape Consortium. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the “Software”), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +(function (global, factory) { + true ? module.exports = factory() : + 0; +})(this, (function () { 'use strict'; + + function _typeof(obj) { + "@babel/helpers - typeof"; + + return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { + return typeof obj; + } : function (obj) { + return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; + }, _typeof(obj); + } + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + function _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); + } + } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { + writable: false + }); + return Constructor; + } + function _defineProperty$1(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; + } + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); + } + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + function _iterableToArrayLimit(arr, i) { + var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; + if (_i == null) return; + var _arr = []; + var _n = true; + var _d = false; + var _s, _e; + try { + for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { + _arr.push(_s.value); + if (i && _arr.length === i) break; + } + } catch (err) { + _d = true; + _e = err; + } finally { + try { + if (!_n && _i["return"] != null) _i["return"](); + } finally { + if (_d) throw _e; + } + } + return _arr; + } + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + return arr2; + } + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + + var _window = typeof window === 'undefined' ? null : window; // eslint-disable-line no-undef + + var navigator = _window ? _window.navigator : null; + _window ? _window.document : null; + var typeofstr = _typeof(''); + var typeofobj = _typeof({}); + var typeoffn = _typeof(function () {}); + var typeofhtmlele = typeof HTMLElement === "undefined" ? "undefined" : _typeof(HTMLElement); + var instanceStr = function instanceStr(obj) { + return obj && obj.instanceString && fn$6(obj.instanceString) ? obj.instanceString() : null; + }; + + var string = function string(obj) { + return obj != null && _typeof(obj) == typeofstr; + }; + var fn$6 = function fn(obj) { + return obj != null && _typeof(obj) === typeoffn; + }; + var array = function array(obj) { + return !elementOrCollection(obj) && (Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array); + }; + var plainObject = function plainObject(obj) { + return obj != null && _typeof(obj) === typeofobj && !array(obj) && obj.constructor === Object; + }; + var object = function object(obj) { + return obj != null && _typeof(obj) === typeofobj; + }; + var number$1 = function number(obj) { + return obj != null && _typeof(obj) === _typeof(1) && !isNaN(obj); + }; + var integer = function integer(obj) { + return number$1(obj) && Math.floor(obj) === obj; + }; + var htmlElement = function htmlElement(obj) { + if ('undefined' === typeofhtmlele) { + return undefined; + } else { + return null != obj && obj instanceof HTMLElement; + } + }; + var elementOrCollection = function elementOrCollection(obj) { + return element(obj) || collection(obj); + }; + var element = function element(obj) { + return instanceStr(obj) === 'collection' && obj._private.single; + }; + var collection = function collection(obj) { + return instanceStr(obj) === 'collection' && !obj._private.single; + }; + var core = function core(obj) { + return instanceStr(obj) === 'core'; + }; + var stylesheet = function stylesheet(obj) { + return instanceStr(obj) === 'stylesheet'; + }; + var event = function event(obj) { + return instanceStr(obj) === 'event'; + }; + var emptyString = function emptyString(obj) { + if (obj === undefined || obj === null) { + // null is empty + return true; + } else if (obj === '' || obj.match(/^\s+$/)) { + return true; // empty string is empty + } + + return false; // otherwise, we don't know what we've got + }; + var domElement = function domElement(obj) { + if (typeof HTMLElement === 'undefined') { + return false; // we're not in a browser so it doesn't matter + } else { + return obj instanceof HTMLElement; + } + }; + var boundingBox = function boundingBox(obj) { + return plainObject(obj) && number$1(obj.x1) && number$1(obj.x2) && number$1(obj.y1) && number$1(obj.y2); + }; + var promise = function promise(obj) { + return object(obj) && fn$6(obj.then); + }; + var ms = function ms() { + return navigator && navigator.userAgent.match(/msie|trident|edge/i); + }; // probably a better way to detect this... + + var memoize$1 = function memoize(fn, keyFn) { + if (!keyFn) { + keyFn = function keyFn() { + if (arguments.length === 1) { + return arguments[0]; + } else if (arguments.length === 0) { + return 'undefined'; + } + var args = []; + for (var i = 0; i < arguments.length; i++) { + args.push(arguments[i]); + } + return args.join('$'); + }; + } + var memoizedFn = function memoizedFn() { + var self = this; + var args = arguments; + var ret; + var k = keyFn.apply(self, args); + var cache = memoizedFn.cache; + if (!(ret = cache[k])) { + ret = cache[k] = fn.apply(self, args); + } + return ret; + }; + memoizedFn.cache = {}; + return memoizedFn; + }; + + var camel2dash = memoize$1(function (str) { + return str.replace(/([A-Z])/g, function (v) { + return '-' + v.toLowerCase(); + }); + }); + var dash2camel = memoize$1(function (str) { + return str.replace(/(-\w)/g, function (v) { + return v[1].toUpperCase(); + }); + }); + var prependCamel = memoize$1(function (prefix, str) { + return prefix + str[0].toUpperCase() + str.substring(1); + }, function (prefix, str) { + return prefix + '$' + str; + }); + var capitalize = function capitalize(str) { + if (emptyString(str)) { + return str; + } + return str.charAt(0).toUpperCase() + str.substring(1); + }; + + var number = '(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))'; + var rgba = 'rgb[a]?\\((' + number + '[%]?)\\s*,\\s*(' + number + '[%]?)\\s*,\\s*(' + number + '[%]?)(?:\\s*,\\s*(' + number + '))?\\)'; + var rgbaNoBackRefs = 'rgb[a]?\\((?:' + number + '[%]?)\\s*,\\s*(?:' + number + '[%]?)\\s*,\\s*(?:' + number + '[%]?)(?:\\s*,\\s*(?:' + number + '))?\\)'; + var hsla = 'hsl[a]?\\((' + number + ')\\s*,\\s*(' + number + '[%])\\s*,\\s*(' + number + '[%])(?:\\s*,\\s*(' + number + '))?\\)'; + var hslaNoBackRefs = 'hsl[a]?\\((?:' + number + ')\\s*,\\s*(?:' + number + '[%])\\s*,\\s*(?:' + number + '[%])(?:\\s*,\\s*(?:' + number + '))?\\)'; + var hex3 = '\\#[0-9a-fA-F]{3}'; + var hex6 = '\\#[0-9a-fA-F]{6}'; + + var ascending = function ascending(a, b) { + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else { + return 0; + } + }; + var descending = function descending(a, b) { + return -1 * ascending(a, b); + }; + + var extend = Object.assign != null ? Object.assign.bind(Object) : function (tgt) { + var args = arguments; + for (var i = 1; i < args.length; i++) { + var obj = args[i]; + if (obj == null) { + continue; + } + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; j++) { + var k = keys[j]; + tgt[k] = obj[k]; + } + } + return tgt; + }; + + // get [r, g, b] from #abc or #aabbcc + var hex2tuple = function hex2tuple(hex) { + if (!(hex.length === 4 || hex.length === 7) || hex[0] !== '#') { + return; + } + var shortHex = hex.length === 4; + var r, g, b; + var base = 16; + if (shortHex) { + r = parseInt(hex[1] + hex[1], base); + g = parseInt(hex[2] + hex[2], base); + b = parseInt(hex[3] + hex[3], base); + } else { + r = parseInt(hex[1] + hex[2], base); + g = parseInt(hex[3] + hex[4], base); + b = parseInt(hex[5] + hex[6], base); + } + return [r, g, b]; + }; + + // get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0) + var hsl2tuple = function hsl2tuple(hsl) { + var ret; + var h, s, l, a, r, g, b; + function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + var m = new RegExp('^' + hsla + '$').exec(hsl); + if (m) { + // get hue + h = parseInt(m[1]); + if (h < 0) { + h = (360 - -1 * h % 360) % 360; + } else if (h > 360) { + h = h % 360; + } + h /= 360; // normalise on [0, 1] + + s = parseFloat(m[2]); + if (s < 0 || s > 100) { + return; + } // saturation is [0, 100] + s = s / 100; // normalise on [0, 1] + + l = parseFloat(m[3]); + if (l < 0 || l > 100) { + return; + } // lightness is [0, 100] + l = l / 100; // normalise on [0, 1] + + a = m[4]; + if (a !== undefined) { + a = parseFloat(a); + if (a < 0 || a > 1) { + return; + } // alpha is [0, 1] + } + + // now, convert to rgb + // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + if (s === 0) { + r = g = b = Math.round(l * 255); // achromatic + } else { + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = Math.round(255 * hue2rgb(p, q, h + 1 / 3)); + g = Math.round(255 * hue2rgb(p, q, h)); + b = Math.round(255 * hue2rgb(p, q, h - 1 / 3)); + } + ret = [r, g, b, a]; + } + return ret; + }; + + // get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0) + var rgb2tuple = function rgb2tuple(rgb) { + var ret; + var m = new RegExp('^' + rgba + '$').exec(rgb); + if (m) { + ret = []; + var isPct = []; + for (var i = 1; i <= 3; i++) { + var channel = m[i]; + if (channel[channel.length - 1] === '%') { + isPct[i] = true; + } + channel = parseFloat(channel); + if (isPct[i]) { + channel = channel / 100 * 255; // normalise to [0, 255] + } + + if (channel < 0 || channel > 255) { + return; + } // invalid channel value + + ret.push(Math.floor(channel)); + } + var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3]; + var allArePct = isPct[1] && isPct[2] && isPct[3]; + if (atLeastOneIsPct && !allArePct) { + return; + } // must all be percent values if one is + + var alpha = m[4]; + if (alpha !== undefined) { + alpha = parseFloat(alpha); + if (alpha < 0 || alpha > 1) { + return; + } // invalid alpha value + + ret.push(alpha); + } + } + return ret; + }; + var colorname2tuple = function colorname2tuple(color) { + return colors[color.toLowerCase()]; + }; + var color2tuple = function color2tuple(color) { + return (array(color) ? color : null) || colorname2tuple(color) || hex2tuple(color) || rgb2tuple(color) || hsl2tuple(color); + }; + var colors = { + // special colour names + transparent: [0, 0, 0, 0], + // NB alpha === 0 + + // regular colours + aliceblue: [240, 248, 255], + antiquewhite: [250, 235, 215], + aqua: [0, 255, 255], + aquamarine: [127, 255, 212], + azure: [240, 255, 255], + beige: [245, 245, 220], + bisque: [255, 228, 196], + black: [0, 0, 0], + blanchedalmond: [255, 235, 205], + blue: [0, 0, 255], + blueviolet: [138, 43, 226], + brown: [165, 42, 42], + burlywood: [222, 184, 135], + cadetblue: [95, 158, 160], + chartreuse: [127, 255, 0], + chocolate: [210, 105, 30], + coral: [255, 127, 80], + cornflowerblue: [100, 149, 237], + cornsilk: [255, 248, 220], + crimson: [220, 20, 60], + cyan: [0, 255, 255], + darkblue: [0, 0, 139], + darkcyan: [0, 139, 139], + darkgoldenrod: [184, 134, 11], + darkgray: [169, 169, 169], + darkgreen: [0, 100, 0], + darkgrey: [169, 169, 169], + darkkhaki: [189, 183, 107], + darkmagenta: [139, 0, 139], + darkolivegreen: [85, 107, 47], + darkorange: [255, 140, 0], + darkorchid: [153, 50, 204], + darkred: [139, 0, 0], + darksalmon: [233, 150, 122], + darkseagreen: [143, 188, 143], + darkslateblue: [72, 61, 139], + darkslategray: [47, 79, 79], + darkslategrey: [47, 79, 79], + darkturquoise: [0, 206, 209], + darkviolet: [148, 0, 211], + deeppink: [255, 20, 147], + deepskyblue: [0, 191, 255], + dimgray: [105, 105, 105], + dimgrey: [105, 105, 105], + dodgerblue: [30, 144, 255], + firebrick: [178, 34, 34], + floralwhite: [255, 250, 240], + forestgreen: [34, 139, 34], + fuchsia: [255, 0, 255], + gainsboro: [220, 220, 220], + ghostwhite: [248, 248, 255], + gold: [255, 215, 0], + goldenrod: [218, 165, 32], + gray: [128, 128, 128], + grey: [128, 128, 128], + green: [0, 128, 0], + greenyellow: [173, 255, 47], + honeydew: [240, 255, 240], + hotpink: [255, 105, 180], + indianred: [205, 92, 92], + indigo: [75, 0, 130], + ivory: [255, 255, 240], + khaki: [240, 230, 140], + lavender: [230, 230, 250], + lavenderblush: [255, 240, 245], + lawngreen: [124, 252, 0], + lemonchiffon: [255, 250, 205], + lightblue: [173, 216, 230], + lightcoral: [240, 128, 128], + lightcyan: [224, 255, 255], + lightgoldenrodyellow: [250, 250, 210], + lightgray: [211, 211, 211], + lightgreen: [144, 238, 144], + lightgrey: [211, 211, 211], + lightpink: [255, 182, 193], + lightsalmon: [255, 160, 122], + lightseagreen: [32, 178, 170], + lightskyblue: [135, 206, 250], + lightslategray: [119, 136, 153], + lightslategrey: [119, 136, 153], + lightsteelblue: [176, 196, 222], + lightyellow: [255, 255, 224], + lime: [0, 255, 0], + limegreen: [50, 205, 50], + linen: [250, 240, 230], + magenta: [255, 0, 255], + maroon: [128, 0, 0], + mediumaquamarine: [102, 205, 170], + mediumblue: [0, 0, 205], + mediumorchid: [186, 85, 211], + mediumpurple: [147, 112, 219], + mediumseagreen: [60, 179, 113], + mediumslateblue: [123, 104, 238], + mediumspringgreen: [0, 250, 154], + mediumturquoise: [72, 209, 204], + mediumvioletred: [199, 21, 133], + midnightblue: [25, 25, 112], + mintcream: [245, 255, 250], + mistyrose: [255, 228, 225], + moccasin: [255, 228, 181], + navajowhite: [255, 222, 173], + navy: [0, 0, 128], + oldlace: [253, 245, 230], + olive: [128, 128, 0], + olivedrab: [107, 142, 35], + orange: [255, 165, 0], + orangered: [255, 69, 0], + orchid: [218, 112, 214], + palegoldenrod: [238, 232, 170], + palegreen: [152, 251, 152], + paleturquoise: [175, 238, 238], + palevioletred: [219, 112, 147], + papayawhip: [255, 239, 213], + peachpuff: [255, 218, 185], + peru: [205, 133, 63], + pink: [255, 192, 203], + plum: [221, 160, 221], + powderblue: [176, 224, 230], + purple: [128, 0, 128], + red: [255, 0, 0], + rosybrown: [188, 143, 143], + royalblue: [65, 105, 225], + saddlebrown: [139, 69, 19], + salmon: [250, 128, 114], + sandybrown: [244, 164, 96], + seagreen: [46, 139, 87], + seashell: [255, 245, 238], + sienna: [160, 82, 45], + silver: [192, 192, 192], + skyblue: [135, 206, 235], + slateblue: [106, 90, 205], + slategray: [112, 128, 144], + slategrey: [112, 128, 144], + snow: [255, 250, 250], + springgreen: [0, 255, 127], + steelblue: [70, 130, 180], + tan: [210, 180, 140], + teal: [0, 128, 128], + thistle: [216, 191, 216], + tomato: [255, 99, 71], + turquoise: [64, 224, 208], + violet: [238, 130, 238], + wheat: [245, 222, 179], + white: [255, 255, 255], + whitesmoke: [245, 245, 245], + yellow: [255, 255, 0], + yellowgreen: [154, 205, 50] + }; + + // sets the value in a map (map may not be built) + var setMap = function setMap(options) { + var obj = options.map; + var keys = options.keys; + var l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (plainObject(key)) { + throw Error('Tried to set map with object key'); + } + if (i < keys.length - 1) { + // extend the map if necessary + if (obj[key] == null) { + obj[key] = {}; + } + obj = obj[key]; + } else { + // set the value + obj[key] = options.value; + } + } + }; + + // gets the value in a map even if it's not built in places + var getMap = function getMap(options) { + var obj = options.map; + var keys = options.keys; + var l = keys.length; + for (var i = 0; i < l; i++) { + var key = keys[i]; + if (plainObject(key)) { + throw Error('Tried to get map with object key'); + } + obj = obj[key]; + if (obj == null) { + return obj; + } + } + return obj; + }; + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } + + var isObject_1 = isObject; + + var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + + var _freeGlobal = freeGlobal; + + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + + /** Used as a reference to the global object. */ + var root = _freeGlobal || freeSelf || Function('return this')(); + + var _root = root; + + /** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ + var now = function() { + return _root.Date.now(); + }; + + var now_1 = now; + + /** Used to match a single whitespace character. */ + var reWhitespace = /\s/; + + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; + } + + var _trimmedEndIndex = trimmedEndIndex; + + /** Used to match leading whitespace. */ + var reTrimStart = /^\s+/; + + /** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ + function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; + } + + var _baseTrim = baseTrim; + + /** Built-in value references. */ + var Symbol$1 = _root.Symbol; + + var _Symbol = Symbol$1; + + /** Used for built-in method references. */ + var objectProto$5 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$4 = objectProto$5.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1 = objectProto$5.toString; + + /** Built-in value references. */ + var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined; + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty$4.call(value, symToStringTag$1), + tag = value[symToStringTag$1]; + + try { + value[symToStringTag$1] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString$1.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag$1] = tag; + } else { + delete value[symToStringTag$1]; + } + } + return result; + } + + var _getRawTag = getRawTag; + + /** Used for built-in method references. */ + var objectProto$4 = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto$4.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString.call(value); + } + + var _objectToString = objectToString; + + /** `Object#toString` result references. */ + var nullTag = '[object Null]', + undefinedTag = '[object Undefined]'; + + /** Built-in value references. */ + var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? _getRawTag(value) + : _objectToString(value); + } + + var _baseGetTag = baseGetTag; + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; + } + + var isObjectLike_1 = isObjectLike; + + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike_1(value) && _baseGetTag(value) == symbolTag); + } + + var isSymbol_1 = isSymbol; + + /** Used as references for various `Number` constants. */ + var NAN = 0 / 0; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Built-in method references without a dependency on `root`. */ + var freeParseInt = parseInt; + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol_1(value)) { + return NAN; + } + if (isObject_1(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = isObject_1(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + var toNumber_1 = toNumber; + + /** Error message constants. */ + var FUNC_ERROR_TEXT$1 = 'Expected a function'; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max, + nativeMin = Math.min; + + /** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. The debounced function comes with a `cancel` method to cancel + * delayed `func` invocations and a `flush` method to immediately invoke them. + * Provide `options` to indicate whether `func` should be invoked on the + * leading and/or trailing edge of the `wait` timeout. The `func` is invoked + * with the last arguments provided to the debounced function. Subsequent + * calls to the debounced function return the result of the last `func` + * invocation. + * + * **Note:** If `leading` and `trailing` options are `true`, `func` is + * invoked on the trailing edge of the timeout only if the debounced function + * is invoked more than once during the `wait` timeout. + * + * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred + * until to the next tick, similar to `setTimeout` with a timeout of `0`. + * + * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) + * for details over the differences between `_.debounce` and `_.throttle`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to debounce. + * @param {number} [wait=0] The number of milliseconds to delay. + * @param {Object} [options={}] The options object. + * @param {boolean} [options.leading=false] + * Specify invoking on the leading edge of the timeout. + * @param {number} [options.maxWait] + * The maximum time `func` is allowed to be delayed before it's invoked. + * @param {boolean} [options.trailing=true] + * Specify invoking on the trailing edge of the timeout. + * @returns {Function} Returns the new debounced function. + * @example + * + * // Avoid costly calculations while the window size is in flux. + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); + * + * // Invoke `sendMail` when clicked, debouncing subsequent calls. + * jQuery(element).on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); + * + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. + * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); + * var source = new EventSource('/stream'); + * jQuery(source).on('message', debounced); + * + * // Cancel the trailing debounced invocation. + * jQuery(window).on('popstate', debounced.cancel); + */ + function debounce(func, wait, options) { + var lastArgs, + lastThis, + maxWait, + result, + timerId, + lastCallTime, + lastInvokeTime = 0, + leading = false, + maxing = false, + trailing = true; + + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT$1); + } + wait = toNumber_1(wait) || 0; + if (isObject_1(options)) { + leading = !!options.leading; + maxing = 'maxWait' in options; + maxWait = maxing ? nativeMax(toNumber_1(options.maxWait) || 0, wait) : maxWait; + trailing = 'trailing' in options ? !!options.trailing : trailing; + } + + function invokeFunc(time) { + var args = lastArgs, + thisArg = lastThis; + + lastArgs = lastThis = undefined; + lastInvokeTime = time; + result = func.apply(thisArg, args); + return result; + } + + function leadingEdge(time) { + // Reset any `maxWait` timer. + lastInvokeTime = time; + // Start the timer for the trailing edge. + timerId = setTimeout(timerExpired, wait); + // Invoke the leading edge. + return leading ? invokeFunc(time) : result; + } + + function remainingWait(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime, + timeWaiting = wait - timeSinceLastCall; + + return maxing + ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + function shouldInvoke(time) { + var timeSinceLastCall = time - lastCallTime, + timeSinceLastInvoke = time - lastInvokeTime; + + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge, or we've hit the `maxWait` limit. + return (lastCallTime === undefined || (timeSinceLastCall >= wait) || + (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); + } + + function timerExpired() { + var time = now_1(); + if (shouldInvoke(time)) { + return trailingEdge(time); + } + // Restart the timer. + timerId = setTimeout(timerExpired, remainingWait(time)); + } + + function trailingEdge(time) { + timerId = undefined; + + // Only invoke if we have `lastArgs` which means `func` has been + // debounced at least once. + if (trailing && lastArgs) { + return invokeFunc(time); + } + lastArgs = lastThis = undefined; + return result; + } + + function cancel() { + if (timerId !== undefined) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = undefined; + } + + function flush() { + return timerId === undefined ? result : trailingEdge(now_1()); + } + + function debounced() { + var time = now_1(), + isInvoking = shouldInvoke(time); + + lastArgs = arguments; + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timerId === undefined) { + return leadingEdge(lastCallTime); + } + if (maxing) { + // Handle invocations in a tight loop. + clearTimeout(timerId); + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === undefined) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush; + return debounced; + } + + var debounce_1 = debounce; + + var performance = _window ? _window.performance : null; + var pnow = performance && performance.now ? function () { + return performance.now(); + } : function () { + return Date.now(); + }; + var raf = function () { + if (_window) { + if (_window.requestAnimationFrame) { + return function (fn) { + _window.requestAnimationFrame(fn); + }; + } else if (_window.mozRequestAnimationFrame) { + return function (fn) { + _window.mozRequestAnimationFrame(fn); + }; + } else if (_window.webkitRequestAnimationFrame) { + return function (fn) { + _window.webkitRequestAnimationFrame(fn); + }; + } else if (_window.msRequestAnimationFrame) { + return function (fn) { + _window.msRequestAnimationFrame(fn); + }; + } + } + return function (fn) { + if (fn) { + setTimeout(function () { + fn(pnow()); + }, 1000 / 60); + } + }; + }(); + var requestAnimationFrame = function requestAnimationFrame(fn) { + return raf(fn); + }; + var performanceNow = pnow; + + var DEFAULT_HASH_SEED = 9261; + var K = 65599; // 37 also works pretty well + var DEFAULT_HASH_SEED_ALT = 5381; + var hashIterableInts = function hashIterableInts(iterator) { + var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED; + // sdbm/string-hash + var hash = seed; + var entry; + for (;;) { + entry = iterator.next(); + if (entry.done) { + break; + } + hash = hash * K + entry.value | 0; + } + return hash; + }; + var hashInt = function hashInt(num) { + var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED; + // sdbm/string-hash + return seed * K + num | 0; + }; + var hashIntAlt = function hashIntAlt(num) { + var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED_ALT; + // djb2/string-hash + return (seed << 5) + seed + num | 0; + }; + var combineHashes = function combineHashes(hash1, hash2) { + return hash1 * 0x200000 + hash2; + }; + var combineHashesArray = function combineHashesArray(hashes) { + return hashes[0] * 0x200000 + hashes[1]; + }; + var hashArrays = function hashArrays(hashes1, hashes2) { + return [hashInt(hashes1[0], hashes2[0]), hashIntAlt(hashes1[1], hashes2[1])]; + }; + var hashIntsArray = function hashIntsArray(ints, seed) { + var entry = { + value: 0, + done: false + }; + var i = 0; + var length = ints.length; + var iterator = { + next: function next() { + if (i < length) { + entry.value = ints[i++]; + } else { + entry.done = true; + } + return entry; + } + }; + return hashIterableInts(iterator, seed); + }; + var hashString = function hashString(str, seed) { + var entry = { + value: 0, + done: false + }; + var i = 0; + var length = str.length; + var iterator = { + next: function next() { + if (i < length) { + entry.value = str.charCodeAt(i++); + } else { + entry.done = true; + } + return entry; + } + }; + return hashIterableInts(iterator, seed); + }; + var hashStrings = function hashStrings() { + return hashStringsArray(arguments); + }; + var hashStringsArray = function hashStringsArray(strs) { + var hash; + for (var i = 0; i < strs.length; i++) { + var str = strs[i]; + if (i === 0) { + hash = hashString(str); + } else { + hash = hashString(str, hash); + } + } + return hash; + }; + + /*global console */ + var warningsEnabled = true; + var warnSupported = console.warn != null; // eslint-disable-line no-console + var traceSupported = console.trace != null; // eslint-disable-line no-console + + var MAX_INT$1 = Number.MAX_SAFE_INTEGER || 9007199254740991; + var trueify = function trueify() { + return true; + }; + var falsify = function falsify() { + return false; + }; + var zeroify = function zeroify() { + return 0; + }; + var noop$1 = function noop() {}; + var error = function error(msg) { + throw new Error(msg); + }; + var warnings = function warnings(enabled) { + if (enabled !== undefined) { + warningsEnabled = !!enabled; + } else { + return warningsEnabled; + } + }; + var warn = function warn(msg) { + /* eslint-disable no-console */ + if (!warnings()) { + return; + } + if (warnSupported) { + console.warn(msg); + } else { + console.log(msg); + if (traceSupported) { + console.trace(); + } + } + }; /* eslint-enable */ + + var clone = function clone(obj) { + return extend({}, obj); + }; + + // gets a shallow copy of the argument + var copy = function copy(obj) { + if (obj == null) { + return obj; + } + if (array(obj)) { + return obj.slice(); + } else if (plainObject(obj)) { + return clone(obj); + } else { + return obj; + } + }; + var copyArray$1 = function copyArray(arr) { + return arr.slice(); + }; + var uuid = function uuid(a, b /* placeholders */) { + for ( + // loop :) + b = a = ''; + // b - result , a - numeric letiable + a++ < 36; + // + b += a * 51 & 52 // if "a" is not 9 or 14 or 19 or 24 + ? + // return a random number or 4 + (a ^ 15 // if "a" is not 15 + ? + // generate a random number from 0 to 15 + 8 ^ Math.random() * (a ^ 20 ? 16 : 4) // unless "a" is 20, in which case a random number from 8 to 11 + : 4 // otherwise 4 + ).toString(16) : '-' // in other cases (if "a" is 9,14,19,24) insert "-" + ) { + } + return b; + }; + var _staticEmptyObject = {}; + var staticEmptyObject = function staticEmptyObject() { + return _staticEmptyObject; + }; + var defaults$g = function defaults(_defaults) { + var keys = Object.keys(_defaults); + return function (opts) { + var filledOpts = {}; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var optVal = opts == null ? undefined : opts[key]; + filledOpts[key] = optVal === undefined ? _defaults[key] : optVal; + } + return filledOpts; + }; + }; + var removeFromArray = function removeFromArray(arr, ele, oneCopy) { + for (var i = arr.length - 1; i >= 0; i--) { + if (arr[i] === ele) { + arr.splice(i, 1); + if (oneCopy) { + break; + } + } + } + }; + var clearArray = function clearArray(arr) { + arr.splice(0, arr.length); + }; + var push = function push(arr, otherArr) { + for (var i = 0; i < otherArr.length; i++) { + var el = otherArr[i]; + arr.push(el); + } + }; + var getPrefixedProperty = function getPrefixedProperty(obj, propName, prefix) { + if (prefix) { + propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth + } + + return obj[propName]; + }; + var setPrefixedProperty = function setPrefixedProperty(obj, propName, prefix, value) { + if (prefix) { + propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth + } + + obj[propName] = value; + }; + + /* global Map */ + var ObjectMap = /*#__PURE__*/function () { + function ObjectMap() { + _classCallCheck(this, ObjectMap); + this._obj = {}; + } + _createClass(ObjectMap, [{ + key: "set", + value: function set(key, val) { + this._obj[key] = val; + return this; + } + }, { + key: "delete", + value: function _delete(key) { + this._obj[key] = undefined; + return this; + } + }, { + key: "clear", + value: function clear() { + this._obj = {}; + } + }, { + key: "has", + value: function has(key) { + return this._obj[key] !== undefined; + } + }, { + key: "get", + value: function get(key) { + return this._obj[key]; + } + }]); + return ObjectMap; + }(); + var Map$2 = typeof Map !== 'undefined' ? Map : ObjectMap; + + /* global Set */ + + var undef = "undefined" ; + var ObjectSet = /*#__PURE__*/function () { + function ObjectSet(arrayOrObjectSet) { + _classCallCheck(this, ObjectSet); + this._obj = Object.create(null); + this.size = 0; + if (arrayOrObjectSet != null) { + var arr; + if (arrayOrObjectSet.instanceString != null && arrayOrObjectSet.instanceString() === this.instanceString()) { + arr = arrayOrObjectSet.toArray(); + } else { + arr = arrayOrObjectSet; + } + for (var i = 0; i < arr.length; i++) { + this.add(arr[i]); + } + } + } + _createClass(ObjectSet, [{ + key: "instanceString", + value: function instanceString() { + return 'set'; + } + }, { + key: "add", + value: function add(val) { + var o = this._obj; + if (o[val] !== 1) { + o[val] = 1; + this.size++; + } + } + }, { + key: "delete", + value: function _delete(val) { + var o = this._obj; + if (o[val] === 1) { + o[val] = 0; + this.size--; + } + } + }, { + key: "clear", + value: function clear() { + this._obj = Object.create(null); + } + }, { + key: "has", + value: function has(val) { + return this._obj[val] === 1; + } + }, { + key: "toArray", + value: function toArray() { + var _this = this; + return Object.keys(this._obj).filter(function (key) { + return _this.has(key); + }); + } + }, { + key: "forEach", + value: function forEach(callback, thisArg) { + return this.toArray().forEach(callback, thisArg); + } + }]); + return ObjectSet; + }(); + var Set$1 = (typeof Set === "undefined" ? "undefined" : _typeof(Set)) !== undef ? Set : ObjectSet; + + // represents a node or an edge + var Element = function Element(cy, params) { + var restore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + if (cy === undefined || params === undefined || !core(cy)) { + error('An element must have a core reference and parameters set'); + return; + } + var group = params.group; + + // try to automatically infer the group if unspecified + if (group == null) { + if (params.data && params.data.source != null && params.data.target != null) { + group = 'edges'; + } else { + group = 'nodes'; + } + } + + // validate group + if (group !== 'nodes' && group !== 'edges') { + error('An element must be of type `nodes` or `edges`; you specified `' + group + '`'); + return; + } + + // make the element array-like, just like a collection + this.length = 1; + this[0] = this; + + // NOTE: when something is added here, add also to ele.json() + var _p = this._private = { + cy: cy, + single: true, + // indicates this is an element + data: params.data || {}, + // data object + position: params.position || { + x: 0, + y: 0 + }, + // (x, y) position pair + autoWidth: undefined, + // width and height of nodes calculated by the renderer when set to special 'auto' value + autoHeight: undefined, + autoPadding: undefined, + compoundBoundsClean: false, + // whether the compound dimensions need to be recalculated the next time dimensions are read + listeners: [], + // array of bound listeners + group: group, + // string; 'nodes' or 'edges' + style: {}, + // properties as set by the style + rstyle: {}, + // properties for style sent from the renderer to the core + styleCxts: [], + // applied style contexts from the styler + styleKeys: {}, + // per-group keys of style property values + removed: true, + // whether it's inside the vis; true if removed (set true here since we call restore) + selected: params.selected ? true : false, + // whether it's selected + selectable: params.selectable === undefined ? true : params.selectable ? true : false, + // whether it's selectable + locked: params.locked ? true : false, + // whether the element is locked (cannot be moved) + grabbed: false, + // whether the element is grabbed by the mouse; renderer sets this privately + grabbable: params.grabbable === undefined ? true : params.grabbable ? true : false, + // whether the element can be grabbed + pannable: params.pannable === undefined ? group === 'edges' ? true : false : params.pannable ? true : false, + // whether the element has passthrough panning enabled + active: false, + // whether the element is active from user interaction + classes: new Set$1(), + // map ( className => true ) + animation: { + // object for currently-running animations + current: [], + queue: [] + }, + rscratch: {}, + // object in which the renderer can store information + scratch: params.scratch || {}, + // scratch objects + edges: [], + // array of connected edges + children: [], + // array of children + parent: params.parent && params.parent.isNode() ? params.parent : null, + // parent ref + traversalCache: {}, + // cache of output of traversal functions + backgrounding: false, + // whether background images are loading + bbCache: null, + // cache of the current bounding box + bbCacheShift: { + x: 0, + y: 0 + }, + // shift applied to cached bb to be applied on next get + bodyBounds: null, + // bounds cache of element body, w/o overlay + overlayBounds: null, + // bounds cache of element body, including overlay + labelBounds: { + // bounds cache of labels + all: null, + source: null, + target: null, + main: null + }, + arrowBounds: { + // bounds cache of edge arrows + source: null, + target: null, + 'mid-source': null, + 'mid-target': null + } + }; + if (_p.position.x == null) { + _p.position.x = 0; + } + if (_p.position.y == null) { + _p.position.y = 0; + } + + // renderedPosition overrides if specified + if (params.renderedPosition) { + var rpos = params.renderedPosition; + var pan = cy.pan(); + var zoom = cy.zoom(); + _p.position = { + x: (rpos.x - pan.x) / zoom, + y: (rpos.y - pan.y) / zoom + }; + } + var classes = []; + if (array(params.classes)) { + classes = params.classes; + } else if (string(params.classes)) { + classes = params.classes.split(/\s+/); + } + for (var i = 0, l = classes.length; i < l; i++) { + var cls = classes[i]; + if (!cls || cls === '') { + continue; + } + _p.classes.add(cls); + } + this.createEmitter(); + var bypass = params.style || params.css; + if (bypass) { + warn('Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead.'); + this.style(bypass); + } + if (restore === undefined || restore) { + this.restore(); + } + }; + + var defineSearch = function defineSearch(params) { + params = { + bfs: params.bfs || !params.dfs, + dfs: params.dfs || !params.bfs + }; + + // from pseudocode on wikipedia + return function searchFn(roots, fn, directed) { + var options; + if (plainObject(roots) && !elementOrCollection(roots)) { + options = roots; + roots = options.roots || options.root; + fn = options.visit; + directed = options.directed; + } + directed = arguments.length === 2 && !fn$6(fn) ? fn : directed; + fn = fn$6(fn) ? fn : function () {}; + var cy = this._private.cy; + var v = roots = string(roots) ? this.filter(roots) : roots; + var Q = []; + var connectedNodes = []; + var connectedBy = {}; + var id2depth = {}; + var V = {}; + var j = 0; + var found; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + + // enqueue v + for (var i = 0; i < v.length; i++) { + var vi = v[i]; + var viId = vi.id(); + if (vi.isNode()) { + Q.unshift(vi); + if (params.bfs) { + V[viId] = true; + connectedNodes.push(vi); + } + id2depth[viId] = 0; + } + } + var _loop = function _loop() { + var v = params.bfs ? Q.shift() : Q.pop(); + var vId = v.id(); + if (params.dfs) { + if (V[vId]) { + return "continue"; + } + V[vId] = true; + connectedNodes.push(v); + } + var depth = id2depth[vId]; + var prevEdge = connectedBy[vId]; + var src = prevEdge != null ? prevEdge.source() : null; + var tgt = prevEdge != null ? prevEdge.target() : null; + var prevNode = prevEdge == null ? undefined : v.same(src) ? tgt[0] : src[0]; + var ret = void 0; + ret = fn(v, prevEdge, prevNode, j++, depth); + if (ret === true) { + found = v; + return "break"; + } + if (ret === false) { + return "break"; + } + var vwEdges = v.connectedEdges().filter(function (e) { + return (!directed || e.source().same(v)) && edges.has(e); + }); + for (var _i2 = 0; _i2 < vwEdges.length; _i2++) { + var e = vwEdges[_i2]; + var w = e.connectedNodes().filter(function (n) { + return !n.same(v) && nodes.has(n); + }); + var wId = w.id(); + if (w.length !== 0 && !V[wId]) { + w = w[0]; + Q.push(w); + if (params.bfs) { + V[wId] = true; + connectedNodes.push(w); + } + connectedBy[wId] = e; + id2depth[wId] = id2depth[vId] + 1; + } + } + }; + while (Q.length !== 0) { + var _ret = _loop(); + if (_ret === "continue") continue; + if (_ret === "break") break; + } + var connectedEles = cy.collection(); + for (var _i = 0; _i < connectedNodes.length; _i++) { + var node = connectedNodes[_i]; + var edge = connectedBy[node.id()]; + if (edge != null) { + connectedEles.push(edge); + } + connectedEles.push(node); + } + return { + path: cy.collection(connectedEles), + found: cy.collection(found) + }; + }; + }; + + // search, spanning trees, etc + var elesfn$v = { + breadthFirstSearch: defineSearch({ + bfs: true + }), + depthFirstSearch: defineSearch({ + dfs: true + }) + }; + + // nice, short mathematical alias + elesfn$v.bfs = elesfn$v.breadthFirstSearch; + elesfn$v.dfs = elesfn$v.depthFirstSearch; + + var heap$1 = createCommonjsModule(function (module, exports) { + // Generated by CoffeeScript 1.8.0 + (function() { + var Heap, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup; + + floor = Math.floor, min = Math.min; + + + /* + Default comparison function to be used + */ + + defaultCmp = function(x, y) { + if (x < y) { + return -1; + } + if (x > y) { + return 1; + } + return 0; + }; + + + /* + Insert item x in list a, and keep it sorted assuming a is sorted. + + If x is already in a, insert it to the right of the rightmost x. + + Optional args lo (default 0) and hi (default a.length) bound the slice + of a to be searched. + */ + + insort = function(a, x, lo, hi, cmp) { + var mid; + if (lo == null) { + lo = 0; + } + if (cmp == null) { + cmp = defaultCmp; + } + if (lo < 0) { + throw new Error('lo must be non-negative'); + } + if (hi == null) { + hi = a.length; + } + while (lo < hi) { + mid = floor((lo + hi) / 2); + if (cmp(x, a[mid]) < 0) { + hi = mid; + } else { + lo = mid + 1; + } + } + return ([].splice.apply(a, [lo, lo - lo].concat(x)), x); + }; + + + /* + Push item onto heap, maintaining the heap invariant. + */ + + heappush = function(array, item, cmp) { + if (cmp == null) { + cmp = defaultCmp; + } + array.push(item); + return _siftdown(array, 0, array.length - 1, cmp); + }; + + + /* + Pop the smallest item off the heap, maintaining the heap invariant. + */ + + heappop = function(array, cmp) { + var lastelt, returnitem; + if (cmp == null) { + cmp = defaultCmp; + } + lastelt = array.pop(); + if (array.length) { + returnitem = array[0]; + array[0] = lastelt; + _siftup(array, 0, cmp); + } else { + returnitem = lastelt; + } + return returnitem; + }; + + + /* + Pop and return the current smallest value, and add the new item. + + This is more efficient than heappop() followed by heappush(), and can be + more appropriate when using a fixed size heap. Note that the value + returned may be larger than item! That constrains reasonable use of + this routine unless written as part of a conditional replacement: + if item > array[0] + item = heapreplace(array, item) + */ + + heapreplace = function(array, item, cmp) { + var returnitem; + if (cmp == null) { + cmp = defaultCmp; + } + returnitem = array[0]; + array[0] = item; + _siftup(array, 0, cmp); + return returnitem; + }; + + + /* + Fast version of a heappush followed by a heappop. + */ + + heappushpop = function(array, item, cmp) { + var _ref; + if (cmp == null) { + cmp = defaultCmp; + } + if (array.length && cmp(array[0], item) < 0) { + _ref = [array[0], item], item = _ref[0], array[0] = _ref[1]; + _siftup(array, 0, cmp); + } + return item; + }; + + + /* + Transform list into a heap, in-place, in O(array.length) time. + */ + + heapify = function(array, cmp) { + var i, _i, _len, _ref1, _results, _results1; + if (cmp == null) { + cmp = defaultCmp; + } + _ref1 = (function() { + _results1 = []; + for (var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--){ _results1.push(_j); } + return _results1; + }).apply(this).reverse(); + _results = []; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + i = _ref1[_i]; + _results.push(_siftup(array, i, cmp)); + } + return _results; + }; + + + /* + Update the position of the given item in the heap. + This function should be called every time the item is being modified. + */ + + updateItem = function(array, item, cmp) { + var pos; + if (cmp == null) { + cmp = defaultCmp; + } + pos = array.indexOf(item); + if (pos === -1) { + return; + } + _siftdown(array, 0, pos, cmp); + return _siftup(array, pos, cmp); + }; + + + /* + Find the n largest elements in a dataset. + */ + + nlargest = function(array, n, cmp) { + var elem, result, _i, _len, _ref; + if (cmp == null) { + cmp = defaultCmp; + } + result = array.slice(0, n); + if (!result.length) { + return result; + } + heapify(result, cmp); + _ref = array.slice(n); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elem = _ref[_i]; + heappushpop(result, elem, cmp); + } + return result.sort(cmp).reverse(); + }; + + + /* + Find the n smallest elements in a dataset. + */ + + nsmallest = function(array, n, cmp) { + var elem, los, result, _i, _j, _len, _ref, _ref1, _results; + if (cmp == null) { + cmp = defaultCmp; + } + if (n * 10 <= array.length) { + result = array.slice(0, n).sort(cmp); + if (!result.length) { + return result; + } + los = result[result.length - 1]; + _ref = array.slice(n); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elem = _ref[_i]; + if (cmp(elem, los) < 0) { + insort(result, elem, 0, null, cmp); + result.pop(); + los = result[result.length - 1]; + } + } + return result; + } + heapify(array, cmp); + _results = []; + for (_j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; 0 <= _ref1 ? ++_j : --_j) { + _results.push(heappop(array, cmp)); + } + return _results; + }; + + _siftdown = function(array, startpos, pos, cmp) { + var newitem, parent, parentpos; + if (cmp == null) { + cmp = defaultCmp; + } + newitem = array[pos]; + while (pos > startpos) { + parentpos = (pos - 1) >> 1; + parent = array[parentpos]; + if (cmp(newitem, parent) < 0) { + array[pos] = parent; + pos = parentpos; + continue; + } + break; + } + return array[pos] = newitem; + }; + + _siftup = function(array, pos, cmp) { + var childpos, endpos, newitem, rightpos, startpos; + if (cmp == null) { + cmp = defaultCmp; + } + endpos = array.length; + startpos = pos; + newitem = array[pos]; + childpos = 2 * pos + 1; + while (childpos < endpos) { + rightpos = childpos + 1; + if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) { + childpos = rightpos; + } + array[pos] = array[childpos]; + pos = childpos; + childpos = 2 * pos + 1; + } + array[pos] = newitem; + return _siftdown(array, startpos, pos, cmp); + }; + + Heap = (function() { + Heap.push = heappush; + + Heap.pop = heappop; + + Heap.replace = heapreplace; + + Heap.pushpop = heappushpop; + + Heap.heapify = heapify; + + Heap.updateItem = updateItem; + + Heap.nlargest = nlargest; + + Heap.nsmallest = nsmallest; + + function Heap(cmp) { + this.cmp = cmp != null ? cmp : defaultCmp; + this.nodes = []; + } + + Heap.prototype.push = function(x) { + return heappush(this.nodes, x, this.cmp); + }; + + Heap.prototype.pop = function() { + return heappop(this.nodes, this.cmp); + }; + + Heap.prototype.peek = function() { + return this.nodes[0]; + }; + + Heap.prototype.contains = function(x) { + return this.nodes.indexOf(x) !== -1; + }; + + Heap.prototype.replace = function(x) { + return heapreplace(this.nodes, x, this.cmp); + }; + + Heap.prototype.pushpop = function(x) { + return heappushpop(this.nodes, x, this.cmp); + }; + + Heap.prototype.heapify = function() { + return heapify(this.nodes, this.cmp); + }; + + Heap.prototype.updateItem = function(x) { + return updateItem(this.nodes, x, this.cmp); + }; + + Heap.prototype.clear = function() { + return this.nodes = []; + }; + + Heap.prototype.empty = function() { + return this.nodes.length === 0; + }; + + Heap.prototype.size = function() { + return this.nodes.length; + }; + + Heap.prototype.clone = function() { + var heap; + heap = new Heap(); + heap.nodes = this.nodes.slice(0); + return heap; + }; + + Heap.prototype.toArray = function() { + return this.nodes.slice(0); + }; + + Heap.prototype.insert = Heap.prototype.push; + + Heap.prototype.top = Heap.prototype.peek; + + Heap.prototype.front = Heap.prototype.peek; + + Heap.prototype.has = Heap.prototype.contains; + + Heap.prototype.copy = Heap.prototype.clone; + + return Heap; + + })(); + + (function(root, factory) { + { + return module.exports = factory(); + } + })(this, function() { + return Heap; + }); + + }).call(commonjsGlobal); + }); + + var heap = heap$1; + + var dijkstraDefaults = defaults$g({ + root: null, + weight: function weight(edge) { + return 1; + }, + directed: false + }); + var elesfn$u = { + dijkstra: function dijkstra(options) { + if (!plainObject(options)) { + var args = arguments; + options = { + root: args[0], + weight: args[1], + directed: args[2] + }; + } + var _dijkstraDefaults = dijkstraDefaults(options), + root = _dijkstraDefaults.root, + weight = _dijkstraDefaults.weight, + directed = _dijkstraDefaults.directed; + var eles = this; + var weightFn = weight; + var source = string(root) ? this.filter(root)[0] : root[0]; + var dist = {}; + var prev = {}; + var knownDist = {}; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + edges.unmergeBy(function (ele) { + return ele.isLoop(); + }); + var getDist = function getDist(node) { + return dist[node.id()]; + }; + var setDist = function setDist(node, d) { + dist[node.id()] = d; + Q.updateItem(node); + }; + var Q = new heap(function (a, b) { + return getDist(a) - getDist(b); + }); + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + dist[node.id()] = node.same(source) ? 0 : Infinity; + Q.push(node); + } + var distBetween = function distBetween(u, v) { + var uvs = (directed ? u.edgesTo(v) : u.edgesWith(v)).intersect(edges); + var smallestDistance = Infinity; + var smallestEdge; + for (var _i = 0; _i < uvs.length; _i++) { + var edge = uvs[_i]; + var _weight = weightFn(edge); + if (_weight < smallestDistance || !smallestEdge) { + smallestDistance = _weight; + smallestEdge = edge; + } + } + return { + edge: smallestEdge, + dist: smallestDistance + }; + }; + while (Q.size() > 0) { + var u = Q.pop(); + var smalletsDist = getDist(u); + var uid = u.id(); + knownDist[uid] = smalletsDist; + if (smalletsDist === Infinity) { + continue; + } + var neighbors = u.neighborhood().intersect(nodes); + for (var _i2 = 0; _i2 < neighbors.length; _i2++) { + var v = neighbors[_i2]; + var vid = v.id(); + var vDist = distBetween(u, v); + var alt = smalletsDist + vDist.dist; + if (alt < getDist(v)) { + setDist(v, alt); + prev[vid] = { + node: u, + edge: vDist.edge + }; + } + } // for + } // while + + return { + distanceTo: function distanceTo(node) { + var target = string(node) ? nodes.filter(node)[0] : node[0]; + return knownDist[target.id()]; + }, + pathTo: function pathTo(node) { + var target = string(node) ? nodes.filter(node)[0] : node[0]; + var S = []; + var u = target; + var uid = u.id(); + if (target.length > 0) { + S.unshift(target); + while (prev[uid]) { + var p = prev[uid]; + S.unshift(p.edge); + S.unshift(p.node); + u = p.node; + uid = u.id(); + } + } + return eles.spawn(S); + } + }; + } + }; + + var elesfn$t = { + // kruskal's algorithm (finds min spanning tree, assuming undirected graph) + // implemented from pseudocode from wikipedia + kruskal: function kruskal(weightFn) { + weightFn = weightFn || function (edge) { + return 1; + }; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + var numNodes = nodes.length; + var forest = new Array(numNodes); + var A = nodes; // assumes byGroup() creates new collections that can be safely mutated + + var findSetIndex = function findSetIndex(ele) { + for (var i = 0; i < forest.length; i++) { + var eles = forest[i]; + if (eles.has(ele)) { + return i; + } + } + }; + + // start with one forest per node + for (var i = 0; i < numNodes; i++) { + forest[i] = this.spawn(nodes[i]); + } + var S = edges.sort(function (a, b) { + return weightFn(a) - weightFn(b); + }); + for (var _i = 0; _i < S.length; _i++) { + var edge = S[_i]; + var u = edge.source()[0]; + var v = edge.target()[0]; + var setUIndex = findSetIndex(u); + var setVIndex = findSetIndex(v); + var setU = forest[setUIndex]; + var setV = forest[setVIndex]; + if (setUIndex !== setVIndex) { + A.merge(edge); + + // combine forests for u and v + setU.merge(setV); + forest.splice(setVIndex, 1); + } + } + return A; + } + }; + + var aStarDefaults = defaults$g({ + root: null, + goal: null, + weight: function weight(edge) { + return 1; + }, + heuristic: function heuristic(edge) { + return 0; + }, + directed: false + }); + var elesfn$s = { + // Implemented from pseudocode from wikipedia + aStar: function aStar(options) { + var cy = this.cy(); + var _aStarDefaults = aStarDefaults(options), + root = _aStarDefaults.root, + goal = _aStarDefaults.goal, + heuristic = _aStarDefaults.heuristic, + directed = _aStarDefaults.directed, + weight = _aStarDefaults.weight; + root = cy.collection(root)[0]; + goal = cy.collection(goal)[0]; + var sid = root.id(); + var tid = goal.id(); + var gScore = {}; + var fScore = {}; + var closedSetIds = {}; + var openSet = new heap(function (a, b) { + return fScore[a.id()] - fScore[b.id()]; + }); + var openSetIds = new Set$1(); + var cameFrom = {}; + var cameFromEdge = {}; + var addToOpenSet = function addToOpenSet(ele, id) { + openSet.push(ele); + openSetIds.add(id); + }; + var cMin, cMinId; + var popFromOpenSet = function popFromOpenSet() { + cMin = openSet.pop(); + cMinId = cMin.id(); + openSetIds["delete"](cMinId); + }; + var isInOpenSet = function isInOpenSet(id) { + return openSetIds.has(id); + }; + addToOpenSet(root, sid); + gScore[sid] = 0; + fScore[sid] = heuristic(root); + + // Counter + var steps = 0; + + // Main loop + while (openSet.size() > 0) { + popFromOpenSet(); + steps++; + + // If we've found our goal, then we are done + if (cMinId === tid) { + var path = []; + var pathNode = goal; + var pathNodeId = tid; + var pathEdge = cameFromEdge[pathNodeId]; + for (;;) { + path.unshift(pathNode); + if (pathEdge != null) { + path.unshift(pathEdge); + } + pathNode = cameFrom[pathNodeId]; + if (pathNode == null) { + break; + } + pathNodeId = pathNode.id(); + pathEdge = cameFromEdge[pathNodeId]; + } + return { + found: true, + distance: gScore[cMinId], + path: this.spawn(path), + steps: steps + }; + } + + // Add cMin to processed nodes + closedSetIds[cMinId] = true; + + // Update scores for neighbors of cMin + // Take into account if graph is directed or not + var vwEdges = cMin._private.edges; + for (var i = 0; i < vwEdges.length; i++) { + var e = vwEdges[i]; + + // edge must be in set of calling eles + if (!this.hasElementWithId(e.id())) { + continue; + } + + // cMin must be the source of edge if directed + if (directed && e.data('source') !== cMinId) { + continue; + } + var wSrc = e.source(); + var wTgt = e.target(); + var w = wSrc.id() !== cMinId ? wSrc : wTgt; + var wid = w.id(); + + // node must be in set of calling eles + if (!this.hasElementWithId(wid)) { + continue; + } + + // if node is in closedSet, ignore it + if (closedSetIds[wid]) { + continue; + } + + // New tentative score for node w + var tempScore = gScore[cMinId] + weight(e); + + // Update gScore for node w if: + // w not present in openSet + // OR + // tentative gScore is less than previous value + + // w not in openSet + if (!isInOpenSet(wid)) { + gScore[wid] = tempScore; + fScore[wid] = tempScore + heuristic(w); + addToOpenSet(w, wid); + cameFrom[wid] = cMin; + cameFromEdge[wid] = e; + continue; + } + + // w already in openSet, but with greater gScore + if (tempScore < gScore[wid]) { + gScore[wid] = tempScore; + fScore[wid] = tempScore + heuristic(w); + cameFrom[wid] = cMin; + cameFromEdge[wid] = e; + } + } // End of neighbors update + } // End of main loop + + // If we've reached here, then we've not reached our goal + return { + found: false, + distance: undefined, + path: undefined, + steps: steps + }; + } + }; // elesfn + + var floydWarshallDefaults = defaults$g({ + weight: function weight(edge) { + return 1; + }, + directed: false + }); + var elesfn$r = { + // Implemented from pseudocode from wikipedia + floydWarshall: function floydWarshall(options) { + var cy = this.cy(); + var _floydWarshallDefault = floydWarshallDefaults(options), + weight = _floydWarshallDefault.weight, + directed = _floydWarshallDefault.directed; + var weightFn = weight; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + var N = nodes.length; + var Nsq = N * N; + var indexOf = function indexOf(node) { + return nodes.indexOf(node); + }; + var atIndex = function atIndex(i) { + return nodes[i]; + }; + + // Initialize distance matrix + var dist = new Array(Nsq); + for (var n = 0; n < Nsq; n++) { + var j = n % N; + var i = (n - j) / N; + if (i === j) { + dist[n] = 0; + } else { + dist[n] = Infinity; + } + } + + // Initialize matrix used for path reconstruction + // Initialize distance matrix + var next = new Array(Nsq); + var edgeNext = new Array(Nsq); + + // Process edges + for (var _i = 0; _i < edges.length; _i++) { + var edge = edges[_i]; + var src = edge.source()[0]; + var tgt = edge.target()[0]; + if (src === tgt) { + continue; + } // exclude loops + + var s = indexOf(src); + var t = indexOf(tgt); + var st = s * N + t; // source to target index + var _weight = weightFn(edge); + + // Check if already process another edge between same 2 nodes + if (dist[st] > _weight) { + dist[st] = _weight; + next[st] = t; + edgeNext[st] = edge; + } + + // If undirected graph, process 'reversed' edge + if (!directed) { + var ts = t * N + s; // target to source index + + if (!directed && dist[ts] > _weight) { + dist[ts] = _weight; + next[ts] = s; + edgeNext[ts] = edge; + } + } + } + + // Main loop + for (var k = 0; k < N; k++) { + for (var _i2 = 0; _i2 < N; _i2++) { + var ik = _i2 * N + k; + for (var _j = 0; _j < N; _j++) { + var ij = _i2 * N + _j; + var kj = k * N + _j; + if (dist[ik] + dist[kj] < dist[ij]) { + dist[ij] = dist[ik] + dist[kj]; + next[ij] = next[ik]; + } + } + } + } + var getArgEle = function getArgEle(ele) { + return (string(ele) ? cy.filter(ele) : ele)[0]; + }; + var indexOfArgEle = function indexOfArgEle(ele) { + return indexOf(getArgEle(ele)); + }; + var res = { + distance: function distance(from, to) { + var i = indexOfArgEle(from); + var j = indexOfArgEle(to); + return dist[i * N + j]; + }, + path: function path(from, to) { + var i = indexOfArgEle(from); + var j = indexOfArgEle(to); + var fromNode = atIndex(i); + if (i === j) { + return fromNode.collection(); + } + if (next[i * N + j] == null) { + return cy.collection(); + } + var path = cy.collection(); + var prev = i; + var edge; + path.merge(fromNode); + while (i !== j) { + prev = i; + i = next[i * N + j]; + edge = edgeNext[prev * N + i]; + path.merge(edge); + path.merge(atIndex(i)); + } + return path; + } + }; + return res; + } // floydWarshall + }; // elesfn + + var bellmanFordDefaults = defaults$g({ + weight: function weight(edge) { + return 1; + }, + directed: false, + root: null + }); + var elesfn$q = { + // Implemented from pseudocode from wikipedia + bellmanFord: function bellmanFord(options) { + var _this = this; + var _bellmanFordDefaults = bellmanFordDefaults(options), + weight = _bellmanFordDefaults.weight, + directed = _bellmanFordDefaults.directed, + root = _bellmanFordDefaults.root; + var weightFn = weight; + var eles = this; + var cy = this.cy(); + var _this$byGroup = this.byGroup(), + edges = _this$byGroup.edges, + nodes = _this$byGroup.nodes; + var numNodes = nodes.length; + var infoMap = new Map$2(); + var hasNegativeWeightCycle = false; + var negativeWeightCycles = []; + root = cy.collection(root)[0]; // in case selector passed + + edges.unmergeBy(function (edge) { + return edge.isLoop(); + }); + var numEdges = edges.length; + var getInfo = function getInfo(node) { + var obj = infoMap.get(node.id()); + if (!obj) { + obj = {}; + infoMap.set(node.id(), obj); + } + return obj; + }; + var getNodeFromTo = function getNodeFromTo(to) { + return (string(to) ? cy.$(to) : to)[0]; + }; + var distanceTo = function distanceTo(to) { + return getInfo(getNodeFromTo(to)).dist; + }; + var pathTo = function pathTo(to) { + var thisStart = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : root; + var end = getNodeFromTo(to); + var path = []; + var node = end; + for (;;) { + if (node == null) { + return _this.spawn(); + } + var _getInfo = getInfo(node), + edge = _getInfo.edge, + pred = _getInfo.pred; + path.unshift(node[0]); + if (node.same(thisStart) && path.length > 0) { + break; + } + if (edge != null) { + path.unshift(edge); + } + node = pred; + } + return eles.spawn(path); + }; + + // Initializations { dist, pred, edge } + for (var i = 0; i < numNodes; i++) { + var node = nodes[i]; + var info = getInfo(node); + if (node.same(root)) { + info.dist = 0; + } else { + info.dist = Infinity; + } + info.pred = null; + info.edge = null; + } + + // Edges relaxation + var replacedEdge = false; + var checkForEdgeReplacement = function checkForEdgeReplacement(node1, node2, edge, info1, info2, weight) { + var dist = info1.dist + weight; + if (dist < info2.dist && !edge.same(info1.edge)) { + info2.dist = dist; + info2.pred = node1; + info2.edge = edge; + replacedEdge = true; + } + }; + for (var _i = 1; _i < numNodes; _i++) { + replacedEdge = false; + for (var e = 0; e < numEdges; e++) { + var edge = edges[e]; + var src = edge.source(); + var tgt = edge.target(); + var _weight = weightFn(edge); + var srcInfo = getInfo(src); + var tgtInfo = getInfo(tgt); + checkForEdgeReplacement(src, tgt, edge, srcInfo, tgtInfo, _weight); + + // If undirected graph, we need to take into account the 'reverse' edge + if (!directed) { + checkForEdgeReplacement(tgt, src, edge, tgtInfo, srcInfo, _weight); + } + } + if (!replacedEdge) { + break; + } + } + if (replacedEdge) { + // Check for negative weight cycles + var negativeWeightCycleIds = []; + for (var _e = 0; _e < numEdges; _e++) { + var _edge = edges[_e]; + var _src = _edge.source(); + var _tgt = _edge.target(); + var _weight2 = weightFn(_edge); + var srcDist = getInfo(_src).dist; + var tgtDist = getInfo(_tgt).dist; + if (srcDist + _weight2 < tgtDist || !directed && tgtDist + _weight2 < srcDist) { + if (!hasNegativeWeightCycle) { + warn('Graph contains a negative weight cycle for Bellman-Ford'); + hasNegativeWeightCycle = true; + } + if (options.findNegativeWeightCycles !== false) { + var negativeNodes = []; + if (srcDist + _weight2 < tgtDist) { + negativeNodes.push(_src); + } + if (!directed && tgtDist + _weight2 < srcDist) { + negativeNodes.push(_tgt); + } + var numNegativeNodes = negativeNodes.length; + for (var n = 0; n < numNegativeNodes; n++) { + var start = negativeNodes[n]; + var cycle = [start]; + cycle.push(getInfo(start).edge); + var _node = getInfo(start).pred; + while (cycle.indexOf(_node) === -1) { + cycle.push(_node); + cycle.push(getInfo(_node).edge); + _node = getInfo(_node).pred; + } + cycle = cycle.slice(cycle.indexOf(_node)); + var smallestId = cycle[0].id(); + var smallestIndex = 0; + for (var c = 2; c < cycle.length; c += 2) { + if (cycle[c].id() < smallestId) { + smallestId = cycle[c].id(); + smallestIndex = c; + } + } + cycle = cycle.slice(smallestIndex).concat(cycle.slice(0, smallestIndex)); + cycle.push(cycle[0]); + var cycleId = cycle.map(function (el) { + return el.id(); + }).join(","); + if (negativeWeightCycleIds.indexOf(cycleId) === -1) { + negativeWeightCycles.push(eles.spawn(cycle)); + negativeWeightCycleIds.push(cycleId); + } + } + } else { + break; + } + } + } + } + return { + distanceTo: distanceTo, + pathTo: pathTo, + hasNegativeWeightCycle: hasNegativeWeightCycle, + negativeWeightCycles: negativeWeightCycles + }; + } // bellmanFord + }; // elesfn + + var sqrt2 = Math.sqrt(2); + + // Function which colapses 2 (meta) nodes into one + // Updates the remaining edge lists + // Receives as a paramater the edge which causes the collapse + var collapse = function collapse(edgeIndex, nodeMap, remainingEdges) { + if (remainingEdges.length === 0) { + error("Karger-Stein must be run on a connected (sub)graph"); + } + var edgeInfo = remainingEdges[edgeIndex]; + var sourceIn = edgeInfo[1]; + var targetIn = edgeInfo[2]; + var partition1 = nodeMap[sourceIn]; + var partition2 = nodeMap[targetIn]; + var newEdges = remainingEdges; // re-use array + + // Delete all edges between partition1 and partition2 + for (var i = newEdges.length - 1; i >= 0; i--) { + var edge = newEdges[i]; + var src = edge[1]; + var tgt = edge[2]; + if (nodeMap[src] === partition1 && nodeMap[tgt] === partition2 || nodeMap[src] === partition2 && nodeMap[tgt] === partition1) { + newEdges.splice(i, 1); + } + } + + // All edges pointing to partition2 should now point to partition1 + for (var _i = 0; _i < newEdges.length; _i++) { + var _edge = newEdges[_i]; + if (_edge[1] === partition2) { + // Check source + newEdges[_i] = _edge.slice(); // copy + newEdges[_i][1] = partition1; + } else if (_edge[2] === partition2) { + // Check target + newEdges[_i] = _edge.slice(); // copy + newEdges[_i][2] = partition1; + } + } + + // Move all nodes from partition2 to partition1 + for (var _i2 = 0; _i2 < nodeMap.length; _i2++) { + if (nodeMap[_i2] === partition2) { + nodeMap[_i2] = partition1; + } + } + return newEdges; + }; + + // Contracts a graph until we reach a certain number of meta nodes + var contractUntil = function contractUntil(metaNodeMap, remainingEdges, size, sizeLimit) { + while (size > sizeLimit) { + // Choose an edge randomly + var edgeIndex = Math.floor(Math.random() * remainingEdges.length); + + // Collapse graph based on edge + remainingEdges = collapse(edgeIndex, metaNodeMap, remainingEdges); + size--; + } + return remainingEdges; + }; + var elesfn$p = { + // Computes the minimum cut of an undirected graph + // Returns the correct answer with high probability + kargerStein: function kargerStein() { + var _this = this; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + edges.unmergeBy(function (edge) { + return edge.isLoop(); + }); + var numNodes = nodes.length; + var numEdges = edges.length; + var numIter = Math.ceil(Math.pow(Math.log(numNodes) / Math.LN2, 2)); + var stopSize = Math.floor(numNodes / sqrt2); + if (numNodes < 2) { + error('At least 2 nodes are required for Karger-Stein algorithm'); + return undefined; + } + + // Now store edge destination as indexes + // Format for each edge (edge index, source node index, target node index) + var edgeIndexes = []; + for (var i = 0; i < numEdges; i++) { + var e = edges[i]; + edgeIndexes.push([i, nodes.indexOf(e.source()), nodes.indexOf(e.target())]); + } + + // We will store the best cut found here + var minCutSize = Infinity; + var minCutEdgeIndexes = []; + var minCutNodeMap = new Array(numNodes); + + // Initial meta node partition + var metaNodeMap = new Array(numNodes); + var metaNodeMap2 = new Array(numNodes); + var copyNodesMap = function copyNodesMap(from, to) { + for (var _i3 = 0; _i3 < numNodes; _i3++) { + to[_i3] = from[_i3]; + } + }; + + // Main loop + for (var iter = 0; iter <= numIter; iter++) { + // Reset meta node partition + for (var _i4 = 0; _i4 < numNodes; _i4++) { + metaNodeMap[_i4] = _i4; + } + + // Contract until stop point (stopSize nodes) + var edgesState = contractUntil(metaNodeMap, edgeIndexes.slice(), numNodes, stopSize); + var edgesState2 = edgesState.slice(); // copy + + // Create a copy of the colapsed nodes state + copyNodesMap(metaNodeMap, metaNodeMap2); + + // Run 2 iterations starting in the stop state + var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2); + var res2 = contractUntil(metaNodeMap2, edgesState2, stopSize, 2); + + // Is any of the 2 results the best cut so far? + if (res1.length <= res2.length && res1.length < minCutSize) { + minCutSize = res1.length; + minCutEdgeIndexes = res1; + copyNodesMap(metaNodeMap, minCutNodeMap); + } else if (res2.length <= res1.length && res2.length < minCutSize) { + minCutSize = res2.length; + minCutEdgeIndexes = res2; + copyNodesMap(metaNodeMap2, minCutNodeMap); + } + } // end of main loop + + // Construct result + var cut = this.spawn(minCutEdgeIndexes.map(function (e) { + return edges[e[0]]; + })); + var partition1 = this.spawn(); + var partition2 = this.spawn(); + + // traverse metaNodeMap for best cut + var witnessNodePartition = minCutNodeMap[0]; + for (var _i5 = 0; _i5 < minCutNodeMap.length; _i5++) { + var partitionId = minCutNodeMap[_i5]; + var node = nodes[_i5]; + if (partitionId === witnessNodePartition) { + partition1.merge(node); + } else { + partition2.merge(node); + } + } + + // construct components corresponding to each disjoint subset of nodes + var constructComponent = function constructComponent(subset) { + var component = _this.spawn(); + subset.forEach(function (node) { + component.merge(node); + node.connectedEdges().forEach(function (edge) { + // ensure edge is within calling collection and edge is not in cut + if (_this.contains(edge) && !cut.contains(edge)) { + component.merge(edge); + } + }); + }); + return component; + }; + var components = [constructComponent(partition1), constructComponent(partition2)]; + var ret = { + cut: cut, + components: components, + // n.b. partitions are included to be compatible with the old api spec + // (could be removed in a future major version) + partition1: partition1, + partition2: partition2 + }; + return ret; + } + }; // elesfn + + var copyPosition = function copyPosition(p) { + return { + x: p.x, + y: p.y + }; + }; + var modelToRenderedPosition = function modelToRenderedPosition(p, zoom, pan) { + return { + x: p.x * zoom + pan.x, + y: p.y * zoom + pan.y + }; + }; + var renderedToModelPosition = function renderedToModelPosition(p, zoom, pan) { + return { + x: (p.x - pan.x) / zoom, + y: (p.y - pan.y) / zoom + }; + }; + var array2point = function array2point(arr) { + return { + x: arr[0], + y: arr[1] + }; + }; + var min = function min(arr) { + var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length; + var min = Infinity; + for (var i = begin; i < end; i++) { + var val = arr[i]; + if (isFinite(val)) { + min = Math.min(val, min); + } + } + return min; + }; + var max = function max(arr) { + var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length; + var max = -Infinity; + for (var i = begin; i < end; i++) { + var val = arr[i]; + if (isFinite(val)) { + max = Math.max(val, max); + } + } + return max; + }; + var mean = function mean(arr) { + var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length; + var total = 0; + var n = 0; + for (var i = begin; i < end; i++) { + var val = arr[i]; + if (isFinite(val)) { + total += val; + n++; + } + } + return total / n; + }; + var median = function median(arr) { + var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length; + var copy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var sort = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var includeHoles = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + if (copy) { + arr = arr.slice(begin, end); + } else { + if (end < arr.length) { + arr.splice(end, arr.length - end); + } + if (begin > 0) { + arr.splice(0, begin); + } + } + + // all non finite (e.g. Infinity, NaN) elements must be -Infinity so they go to the start + var off = 0; // offset from non-finite values + for (var i = arr.length - 1; i >= 0; i--) { + var v = arr[i]; + if (includeHoles) { + if (!isFinite(v)) { + arr[i] = -Infinity; + off++; + } + } else { + // just remove it if we don't want to consider holes + arr.splice(i, 1); + } + } + if (sort) { + arr.sort(function (a, b) { + return a - b; + }); // requires copy = true if you don't want to change the orig + } + + var len = arr.length; + var mid = Math.floor(len / 2); + if (len % 2 !== 0) { + return arr[mid + 1 + off]; + } else { + return (arr[mid - 1 + off] + arr[mid + off]) / 2; + } + }; + var deg2rad = function deg2rad(deg) { + return Math.PI * deg / 180; + }; + var getAngleFromDisp = function getAngleFromDisp(dispX, dispY) { + return Math.atan2(dispY, dispX) - Math.PI / 2; + }; + var log2 = Math.log2 || function (n) { + return Math.log(n) / Math.log(2); + }; + var signum = function signum(x) { + if (x > 0) { + return 1; + } else if (x < 0) { + return -1; + } else { + return 0; + } + }; + var dist = function dist(p1, p2) { + return Math.sqrt(sqdist(p1, p2)); + }; + var sqdist = function sqdist(p1, p2) { + var dx = p2.x - p1.x; + var dy = p2.y - p1.y; + return dx * dx + dy * dy; + }; + var inPlaceSumNormalize = function inPlaceSumNormalize(v) { + var length = v.length; + + // First, get sum of all elements + var total = 0; + for (var i = 0; i < length; i++) { + total += v[i]; + } + + // Now, divide each by the sum of all elements + for (var _i = 0; _i < length; _i++) { + v[_i] = v[_i] / total; + } + return v; + }; + + // from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves + var qbezierAt = function qbezierAt(p0, p1, p2, t) { + return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2; + }; + var qbezierPtAt = function qbezierPtAt(p0, p1, p2, t) { + return { + x: qbezierAt(p0.x, p1.x, p2.x, t), + y: qbezierAt(p0.y, p1.y, p2.y, t) + }; + }; + var lineAt = function lineAt(p0, p1, t, d) { + var vec = { + x: p1.x - p0.x, + y: p1.y - p0.y + }; + var vecDist = dist(p0, p1); + var normVec = { + x: vec.x / vecDist, + y: vec.y / vecDist + }; + t = t == null ? 0 : t; + d = d != null ? d : t * vecDist; + return { + x: p0.x + normVec.x * d, + y: p0.y + normVec.y * d + }; + }; + var bound = function bound(min, val, max) { + return Math.max(min, Math.min(max, val)); + }; + + // makes a full bb (x1, y1, x2, y2, w, h) from implicit params + var makeBoundingBox = function makeBoundingBox(bb) { + if (bb == null) { + return { + x1: Infinity, + y1: Infinity, + x2: -Infinity, + y2: -Infinity, + w: 0, + h: 0 + }; + } else if (bb.x1 != null && bb.y1 != null) { + if (bb.x2 != null && bb.y2 != null && bb.x2 >= bb.x1 && bb.y2 >= bb.y1) { + return { + x1: bb.x1, + y1: bb.y1, + x2: bb.x2, + y2: bb.y2, + w: bb.x2 - bb.x1, + h: bb.y2 - bb.y1 + }; + } else if (bb.w != null && bb.h != null && bb.w >= 0 && bb.h >= 0) { + return { + x1: bb.x1, + y1: bb.y1, + x2: bb.x1 + bb.w, + y2: bb.y1 + bb.h, + w: bb.w, + h: bb.h + }; + } + } + }; + var copyBoundingBox = function copyBoundingBox(bb) { + return { + x1: bb.x1, + x2: bb.x2, + w: bb.w, + y1: bb.y1, + y2: bb.y2, + h: bb.h + }; + }; + var clearBoundingBox = function clearBoundingBox(bb) { + bb.x1 = Infinity; + bb.y1 = Infinity; + bb.x2 = -Infinity; + bb.y2 = -Infinity; + bb.w = 0; + bb.h = 0; + }; + var updateBoundingBox = function updateBoundingBox(bb1, bb2) { + // update bb1 with bb2 bounds + + bb1.x1 = Math.min(bb1.x1, bb2.x1); + bb1.x2 = Math.max(bb1.x2, bb2.x2); + bb1.w = bb1.x2 - bb1.x1; + bb1.y1 = Math.min(bb1.y1, bb2.y1); + bb1.y2 = Math.max(bb1.y2, bb2.y2); + bb1.h = bb1.y2 - bb1.y1; + }; + var expandBoundingBoxByPoint = function expandBoundingBoxByPoint(bb, x, y) { + bb.x1 = Math.min(bb.x1, x); + bb.x2 = Math.max(bb.x2, x); + bb.w = bb.x2 - bb.x1; + bb.y1 = Math.min(bb.y1, y); + bb.y2 = Math.max(bb.y2, y); + bb.h = bb.y2 - bb.y1; + }; + var expandBoundingBox = function expandBoundingBox(bb) { + var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + bb.x1 -= padding; + bb.x2 += padding; + bb.y1 -= padding; + bb.y2 += padding; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + return bb; + }; + var expandBoundingBoxSides = function expandBoundingBoxSides(bb) { + var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0]; + var top, right, bottom, left; + if (padding.length === 1) { + top = right = bottom = left = padding[0]; + } else if (padding.length === 2) { + top = bottom = padding[0]; + left = right = padding[1]; + } else if (padding.length === 4) { + var _padding = _slicedToArray(padding, 4); + top = _padding[0]; + right = _padding[1]; + bottom = _padding[2]; + left = _padding[3]; + } + bb.x1 -= left; + bb.x2 += right; + bb.y1 -= top; + bb.y2 += bottom; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + return bb; + }; + + // assign the values of bb2 into bb1 + var assignBoundingBox = function assignBoundingBox(bb1, bb2) { + bb1.x1 = bb2.x1; + bb1.y1 = bb2.y1; + bb1.x2 = bb2.x2; + bb1.y2 = bb2.y2; + bb1.w = bb1.x2 - bb1.x1; + bb1.h = bb1.y2 - bb1.y1; + }; + var boundingBoxesIntersect = function boundingBoxesIntersect(bb1, bb2) { + // case: one bb to right of other + if (bb1.x1 > bb2.x2) { + return false; + } + if (bb2.x1 > bb1.x2) { + return false; + } + + // case: one bb to left of other + if (bb1.x2 < bb2.x1) { + return false; + } + if (bb2.x2 < bb1.x1) { + return false; + } + + // case: one bb above other + if (bb1.y2 < bb2.y1) { + return false; + } + if (bb2.y2 < bb1.y1) { + return false; + } + + // case: one bb below other + if (bb1.y1 > bb2.y2) { + return false; + } + if (bb2.y1 > bb1.y2) { + return false; + } + + // otherwise, must have some overlap + return true; + }; + var inBoundingBox = function inBoundingBox(bb, x, y) { + return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2; + }; + var pointInBoundingBox = function pointInBoundingBox(bb, pt) { + return inBoundingBox(bb, pt.x, pt.y); + }; + var boundingBoxInBoundingBox = function boundingBoxInBoundingBox(bb1, bb2) { + return inBoundingBox(bb1, bb2.x1, bb2.y1) && inBoundingBox(bb1, bb2.x2, bb2.y2); + }; + var roundRectangleIntersectLine = function roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding) { + var cornerRadius = getRoundRectangleRadius(width, height); + var halfWidth = width / 2; + var halfHeight = height / 2; + + // Check intersections with straight line segments + var straightLineIntersections; + + // Top segment, left to right + { + var topStartX = nodeX - halfWidth + cornerRadius - padding; + var topStartY = nodeY - halfHeight - padding; + var topEndX = nodeX + halfWidth - cornerRadius + padding; + var topEndY = topStartY; + straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false); + if (straightLineIntersections.length > 0) { + return straightLineIntersections; + } + } + + // Right segment, top to bottom + { + var rightStartX = nodeX + halfWidth + padding; + var rightStartY = nodeY - halfHeight + cornerRadius - padding; + var rightEndX = rightStartX; + var rightEndY = nodeY + halfHeight - cornerRadius + padding; + straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false); + if (straightLineIntersections.length > 0) { + return straightLineIntersections; + } + } + + // Bottom segment, left to right + { + var bottomStartX = nodeX - halfWidth + cornerRadius - padding; + var bottomStartY = nodeY + halfHeight + padding; + var bottomEndX = nodeX + halfWidth - cornerRadius + padding; + var bottomEndY = bottomStartY; + straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false); + if (straightLineIntersections.length > 0) { + return straightLineIntersections; + } + } + + // Left segment, top to bottom + { + var leftStartX = nodeX - halfWidth - padding; + var leftStartY = nodeY - halfHeight + cornerRadius - padding; + var leftEndX = leftStartX; + var leftEndY = nodeY + halfHeight - cornerRadius + padding; + straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false); + if (straightLineIntersections.length > 0) { + return straightLineIntersections; + } + } + + // Check intersections with arc segments + var arcIntersections; + + // Top Left + { + var topLeftCenterX = nodeX - halfWidth + cornerRadius; + var topLeftCenterY = nodeY - halfHeight + cornerRadius; + arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topLeftCenterX, topLeftCenterY, cornerRadius + padding); + + // Ensure the intersection is on the desired quarter of the circle + if (arcIntersections.length > 0 && arcIntersections[0] <= topLeftCenterX && arcIntersections[1] <= topLeftCenterY) { + return [arcIntersections[0], arcIntersections[1]]; + } + } + + // Top Right + { + var topRightCenterX = nodeX + halfWidth - cornerRadius; + var topRightCenterY = nodeY - halfHeight + cornerRadius; + arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topRightCenterX, topRightCenterY, cornerRadius + padding); + + // Ensure the intersection is on the desired quarter of the circle + if (arcIntersections.length > 0 && arcIntersections[0] >= topRightCenterX && arcIntersections[1] <= topRightCenterY) { + return [arcIntersections[0], arcIntersections[1]]; + } + } + + // Bottom Right + { + var bottomRightCenterX = nodeX + halfWidth - cornerRadius; + var bottomRightCenterY = nodeY + halfHeight - cornerRadius; + arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomRightCenterX, bottomRightCenterY, cornerRadius + padding); + + // Ensure the intersection is on the desired quarter of the circle + if (arcIntersections.length > 0 && arcIntersections[0] >= bottomRightCenterX && arcIntersections[1] >= bottomRightCenterY) { + return [arcIntersections[0], arcIntersections[1]]; + } + } + + // Bottom Left + { + var bottomLeftCenterX = nodeX - halfWidth + cornerRadius; + var bottomLeftCenterY = nodeY + halfHeight - cornerRadius; + arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding); + + // Ensure the intersection is on the desired quarter of the circle + if (arcIntersections.length > 0 && arcIntersections[0] <= bottomLeftCenterX && arcIntersections[1] >= bottomLeftCenterY) { + return [arcIntersections[0], arcIntersections[1]]; + } + } + return []; // if nothing + }; + + var inLineVicinity = function inLineVicinity(x, y, lx1, ly1, lx2, ly2, tolerance) { + var t = tolerance; + var x1 = Math.min(lx1, lx2); + var x2 = Math.max(lx1, lx2); + var y1 = Math.min(ly1, ly2); + var y2 = Math.max(ly1, ly2); + return x1 - t <= x && x <= x2 + t && y1 - t <= y && y <= y2 + t; + }; + var inBezierVicinity = function inBezierVicinity(x, y, x1, y1, x2, y2, x3, y3, tolerance) { + var bb = { + x1: Math.min(x1, x3, x2) - tolerance, + x2: Math.max(x1, x3, x2) + tolerance, + y1: Math.min(y1, y3, y2) - tolerance, + y2: Math.max(y1, y3, y2) + tolerance + }; + + // if outside the rough bounding box for the bezier, then it can't be a hit + if (x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2) { + // console.log('bezier out of rough bb') + return false; + } else { + // console.log('do more expensive check'); + return true; + } + }; + var solveQuadratic = function solveQuadratic(a, b, c, val) { + c -= val; + var r = b * b - 4 * a * c; + if (r < 0) { + return []; + } + var sqrtR = Math.sqrt(r); + var denom = 2 * a; + var root1 = (-b + sqrtR) / denom; + var root2 = (-b - sqrtR) / denom; + return [root1, root2]; + }; + var solveCubic = function solveCubic(a, b, c, d, result) { + // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where + // r is the real component, i is the imaginary component + + // An implementation of the Cardano method from the year 1545 + // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots + + var epsilon = 0.00001; + + // avoid division by zero while keeping the overall expression close in value + if (a === 0) { + a = epsilon; + } + b /= a; + c /= a; + d /= a; + var discriminant, q, r, dum1, s, t, term1, r13; + q = (3.0 * c - b * b) / 9.0; + r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b)); + r /= 54.0; + discriminant = q * q * q + r * r; + result[1] = 0; + term1 = b / 3.0; + if (discriminant > 0) { + s = r + Math.sqrt(discriminant); + s = s < 0 ? -Math.pow(-s, 1.0 / 3.0) : Math.pow(s, 1.0 / 3.0); + t = r - Math.sqrt(discriminant); + t = t < 0 ? -Math.pow(-t, 1.0 / 3.0) : Math.pow(t, 1.0 / 3.0); + result[0] = -term1 + s + t; + term1 += (s + t) / 2.0; + result[4] = result[2] = -term1; + term1 = Math.sqrt(3.0) * (-t + s) / 2; + result[3] = term1; + result[5] = -term1; + return; + } + result[5] = result[3] = 0; + if (discriminant === 0) { + r13 = r < 0 ? -Math.pow(-r, 1.0 / 3.0) : Math.pow(r, 1.0 / 3.0); + result[0] = -term1 + 2.0 * r13; + result[4] = result[2] = -(r13 + term1); + return; + } + q = -q; + dum1 = q * q * q; + dum1 = Math.acos(r / Math.sqrt(dum1)); + r13 = 2.0 * Math.sqrt(q); + result[0] = -term1 + r13 * Math.cos(dum1 / 3.0); + result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0); + result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0); + return; + }; + var sqdistToQuadraticBezier = function sqdistToQuadraticBezier(x, y, x1, y1, x2, y2, x3, y3) { + // Find minimum distance by using the minimum of the distance + // function between the given point and the curve + + // This gives the coefficients of the resulting cubic equation + // whose roots tell us where a possible minimum is + // (Coefficients are divided by 4) + + var a = 1.0 * x1 * x1 - 4 * x1 * x2 + 2 * x1 * x3 + 4 * x2 * x2 - 4 * x2 * x3 + x3 * x3 + y1 * y1 - 4 * y1 * y2 + 2 * y1 * y3 + 4 * y2 * y2 - 4 * y2 * y3 + y3 * y3; + var b = 1.0 * 9 * x1 * x2 - 3 * x1 * x1 - 3 * x1 * x3 - 6 * x2 * x2 + 3 * x2 * x3 + 9 * y1 * y2 - 3 * y1 * y1 - 3 * y1 * y3 - 6 * y2 * y2 + 3 * y2 * y3; + var c = 1.0 * 3 * x1 * x1 - 6 * x1 * x2 + x1 * x3 - x1 * x + 2 * x2 * x2 + 2 * x2 * x - x3 * x + 3 * y1 * y1 - 6 * y1 * y2 + y1 * y3 - y1 * y + 2 * y2 * y2 + 2 * y2 * y - y3 * y; + var d = 1.0 * x1 * x2 - x1 * x1 + x1 * x - x2 * x + y1 * y2 - y1 * y1 + y1 * y - y2 * y; + + // debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a); + + var roots = []; + + // Use the cubic solving algorithm + solveCubic(a, b, c, d, roots); + var zeroThreshold = 0.0000001; + var params = []; + for (var index = 0; index < 6; index += 2) { + if (Math.abs(roots[index + 1]) < zeroThreshold && roots[index] >= 0 && roots[index] <= 1.0) { + params.push(roots[index]); + } + } + params.push(1.0); + params.push(0.0); + var minDistanceSquared = -1; + var curX, curY, distSquared; + for (var i = 0; i < params.length; i++) { + curX = Math.pow(1.0 - params[i], 2.0) * x1 + 2.0 * (1 - params[i]) * params[i] * x2 + params[i] * params[i] * x3; + curY = Math.pow(1 - params[i], 2.0) * y1 + 2 * (1.0 - params[i]) * params[i] * y2 + params[i] * params[i] * y3; + distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2); + // debug('distance for param ' + params[i] + ": " + Math.sqrt(distSquared)); + if (minDistanceSquared >= 0) { + if (distSquared < minDistanceSquared) { + minDistanceSquared = distSquared; + } + } else { + minDistanceSquared = distSquared; + } + } + return minDistanceSquared; + }; + var sqdistToFiniteLine = function sqdistToFiniteLine(x, y, x1, y1, x2, y2) { + var offset = [x - x1, y - y1]; + var line = [x2 - x1, y2 - y1]; + var lineSq = line[0] * line[0] + line[1] * line[1]; + var hypSq = offset[0] * offset[0] + offset[1] * offset[1]; + var dotProduct = offset[0] * line[0] + offset[1] * line[1]; + var adjSq = dotProduct * dotProduct / lineSq; + if (dotProduct < 0) { + return hypSq; + } + if (adjSq > lineSq) { + return (x - x2) * (x - x2) + (y - y2) * (y - y2); + } + return hypSq - adjSq; + }; + var pointInsidePolygonPoints = function pointInsidePolygonPoints(x, y, points) { + var x1, y1, x2, y2; + var y3; + + // Intersect with vertical line through (x, y) + var up = 0; + // let down = 0; + for (var i = 0; i < points.length / 2; i++) { + x1 = points[i * 2]; + y1 = points[i * 2 + 1]; + if (i + 1 < points.length / 2) { + x2 = points[(i + 1) * 2]; + y2 = points[(i + 1) * 2 + 1]; + } else { + x2 = points[(i + 1 - points.length / 2) * 2]; + y2 = points[(i + 1 - points.length / 2) * 2 + 1]; + } + if (x1 == x && x2 == x) ; else if (x1 >= x && x >= x2 || x1 <= x && x <= x2) { + y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1; + if (y3 > y) { + up++; + } + + // if( y3 < y ){ + // down++; + // } + } else { + continue; + } + } + if (up % 2 === 0) { + return false; + } else { + return true; + } + }; + var pointInsidePolygon = function pointInsidePolygon(x, y, basePoints, centerX, centerY, width, height, direction, padding) { + var transformedPoints = new Array(basePoints.length); + + // Gives negative angle + var angle; + if (direction[0] != null) { + angle = Math.atan(direction[1] / direction[0]); + if (direction[0] < 0) { + angle = angle + Math.PI / 2; + } else { + angle = -angle - Math.PI / 2; + } + } else { + angle = direction; + } + var cos = Math.cos(-angle); + var sin = Math.sin(-angle); + + // console.log("base: " + basePoints); + for (var i = 0; i < transformedPoints.length / 2; i++) { + transformedPoints[i * 2] = width / 2 * (basePoints[i * 2] * cos - basePoints[i * 2 + 1] * sin); + transformedPoints[i * 2 + 1] = height / 2 * (basePoints[i * 2 + 1] * cos + basePoints[i * 2] * sin); + transformedPoints[i * 2] += centerX; + transformedPoints[i * 2 + 1] += centerY; + } + var points; + if (padding > 0) { + var expandedLineSet = expandPolygon(transformedPoints, -padding); + points = joinLines(expandedLineSet); + } else { + points = transformedPoints; + } + return pointInsidePolygonPoints(x, y, points); + }; + var pointInsideRoundPolygon = function pointInsideRoundPolygon(x, y, basePoints, centerX, centerY, width, height) { + var cutPolygonPoints = new Array(basePoints.length); + var halfW = width / 2; + var halfH = height / 2; + var cornerRadius = getRoundPolygonRadius(width, height); + var squaredCornerRadius = cornerRadius * cornerRadius; + for (var i = 0; i < basePoints.length / 4; i++) { + var sourceUv = void 0, + destUv = void 0; + if (i === 0) { + sourceUv = basePoints.length - 2; + } else { + sourceUv = i * 4 - 2; + } + destUv = i * 4 + 2; + var px = centerX + halfW * basePoints[i * 4]; + var py = centerY + halfH * basePoints[i * 4 + 1]; + var cosTheta = -basePoints[sourceUv] * basePoints[destUv] - basePoints[sourceUv + 1] * basePoints[destUv + 1]; + var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2); + var cp0x = px - offset * basePoints[sourceUv]; + var cp0y = py - offset * basePoints[sourceUv + 1]; + var cp1x = px + offset * basePoints[destUv]; + var cp1y = py + offset * basePoints[destUv + 1]; + cutPolygonPoints[i * 4] = cp0x; + cutPolygonPoints[i * 4 + 1] = cp0y; + cutPolygonPoints[i * 4 + 2] = cp1x; + cutPolygonPoints[i * 4 + 3] = cp1y; + var orthx = basePoints[sourceUv + 1]; + var orthy = -basePoints[sourceUv]; + var cosAlpha = orthx * basePoints[destUv] + orthy * basePoints[destUv + 1]; + if (cosAlpha < 0) { + orthx *= -1; + orthy *= -1; + } + var cx = cp0x + orthx * cornerRadius; + var cy = cp0y + orthy * cornerRadius; + var squaredDistance = Math.pow(cx - x, 2) + Math.pow(cy - y, 2); + if (squaredDistance <= squaredCornerRadius) { + return true; + } + } + return pointInsidePolygonPoints(x, y, cutPolygonPoints); + }; + var joinLines = function joinLines(lineSet) { + var vertices = new Array(lineSet.length / 2); + var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY; + var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY; + for (var i = 0; i < lineSet.length / 4; i++) { + currentLineStartX = lineSet[i * 4]; + currentLineStartY = lineSet[i * 4 + 1]; + currentLineEndX = lineSet[i * 4 + 2]; + currentLineEndY = lineSet[i * 4 + 3]; + if (i < lineSet.length / 4 - 1) { + nextLineStartX = lineSet[(i + 1) * 4]; + nextLineStartY = lineSet[(i + 1) * 4 + 1]; + nextLineEndX = lineSet[(i + 1) * 4 + 2]; + nextLineEndY = lineSet[(i + 1) * 4 + 3]; + } else { + nextLineStartX = lineSet[0]; + nextLineStartY = lineSet[1]; + nextLineEndX = lineSet[2]; + nextLineEndY = lineSet[3]; + } + var intersection = finiteLinesIntersect(currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY, nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY, true); + vertices[i * 2] = intersection[0]; + vertices[i * 2 + 1] = intersection[1]; + } + return vertices; + }; + var expandPolygon = function expandPolygon(points, pad) { + var expandedLineSet = new Array(points.length * 2); + var currentPointX, currentPointY, nextPointX, nextPointY; + for (var i = 0; i < points.length / 2; i++) { + currentPointX = points[i * 2]; + currentPointY = points[i * 2 + 1]; + if (i < points.length / 2 - 1) { + nextPointX = points[(i + 1) * 2]; + nextPointY = points[(i + 1) * 2 + 1]; + } else { + nextPointX = points[0]; + nextPointY = points[1]; + } + + // Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY] + + // Assume CCW polygon winding + + var offsetX = nextPointY - currentPointY; + var offsetY = -(nextPointX - currentPointX); + + // Normalize + var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY); + var normalizedOffsetX = offsetX / offsetLength; + var normalizedOffsetY = offsetY / offsetLength; + expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad; + expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad; + expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad; + expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad; + } + return expandedLineSet; + }; + var intersectLineEllipse = function intersectLineEllipse(x, y, centerX, centerY, ellipseWradius, ellipseHradius) { + var dispX = centerX - x; + var dispY = centerY - y; + dispX /= ellipseWradius; + dispY /= ellipseHradius; + var len = Math.sqrt(dispX * dispX + dispY * dispY); + var newLength = len - 1; + if (newLength < 0) { + return []; + } + var lenProportion = newLength / len; + return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y]; + }; + var checkInEllipse = function checkInEllipse(x, y, width, height, centerX, centerY, padding) { + x -= centerX; + y -= centerY; + x /= width / 2 + padding; + y /= height / 2 + padding; + return x * x + y * y <= 1; + }; + + // Returns intersections of increasing distance from line's start point + var intersectLineCircle = function intersectLineCircle(x1, y1, x2, y2, centerX, centerY, radius) { + // Calculate d, direction vector of line + var d = [x2 - x1, y2 - y1]; // Direction vector of line + var f = [x1 - centerX, y1 - centerY]; + var a = d[0] * d[0] + d[1] * d[1]; + var b = 2 * (f[0] * d[0] + f[1] * d[1]); + var c = f[0] * f[0] + f[1] * f[1] - radius * radius; + var discriminant = b * b - 4 * a * c; + if (discriminant < 0) { + return []; + } + var t1 = (-b + Math.sqrt(discriminant)) / (2 * a); + var t2 = (-b - Math.sqrt(discriminant)) / (2 * a); + var tMin = Math.min(t1, t2); + var tMax = Math.max(t1, t2); + var inRangeParams = []; + if (tMin >= 0 && tMin <= 1) { + inRangeParams.push(tMin); + } + if (tMax >= 0 && tMax <= 1) { + inRangeParams.push(tMax); + } + if (inRangeParams.length === 0) { + return []; + } + var nearIntersectionX = inRangeParams[0] * d[0] + x1; + var nearIntersectionY = inRangeParams[0] * d[1] + y1; + if (inRangeParams.length > 1) { + if (inRangeParams[0] == inRangeParams[1]) { + return [nearIntersectionX, nearIntersectionY]; + } else { + var farIntersectionX = inRangeParams[1] * d[0] + x1; + var farIntersectionY = inRangeParams[1] * d[1] + y1; + return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY]; + } + } else { + return [nearIntersectionX, nearIntersectionY]; + } + }; + var midOfThree = function midOfThree(a, b, c) { + if (b <= a && a <= c || c <= a && a <= b) { + return a; + } else if (a <= b && b <= c || c <= b && b <= a) { + return b; + } else { + return c; + } + }; + + // (x1,y1)=>(x2,y2) intersect with (x3,y3)=>(x4,y4) + var finiteLinesIntersect = function finiteLinesIntersect(x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) { + var dx13 = x1 - x3; + var dx21 = x2 - x1; + var dx43 = x4 - x3; + var dy13 = y1 - y3; + var dy21 = y2 - y1; + var dy43 = y4 - y3; + var ua_t = dx43 * dy13 - dy43 * dx13; + var ub_t = dx21 * dy13 - dy21 * dx13; + var u_b = dy43 * dx21 - dx43 * dy21; + if (u_b !== 0) { + var ua = ua_t / u_b; + var ub = ub_t / u_b; + var flptThreshold = 0.001; + var _min = 0 - flptThreshold; + var _max = 1 + flptThreshold; + if (_min <= ua && ua <= _max && _min <= ub && ub <= _max) { + return [x1 + ua * dx21, y1 + ua * dy21]; + } else { + if (!infiniteLines) { + return []; + } else { + return [x1 + ua * dx21, y1 + ua * dy21]; + } + } + } else { + if (ua_t === 0 || ub_t === 0) { + // Parallel, coincident lines. Check if overlap + + // Check endpoint of second line + if (midOfThree(x1, x2, x4) === x4) { + return [x4, y4]; + } + + // Check start point of second line + if (midOfThree(x1, x2, x3) === x3) { + return [x3, y3]; + } + + // Endpoint of first line + if (midOfThree(x3, x4, x2) === x2) { + return [x2, y2]; + } + return []; + } else { + // Parallel, non-coincident + return []; + } + } + }; + + // math.polygonIntersectLine( x, y, basePoints, centerX, centerY, width, height, padding ) + // intersect a node polygon (pts transformed) + // + // math.polygonIntersectLine( x, y, basePoints, centerX, centerY ) + // intersect the points (no transform) + var polygonIntersectLine = function polygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) { + var intersections = []; + var intersection; + var transformedPoints = new Array(basePoints.length); + var doTransform = true; + if (width == null) { + doTransform = false; + } + var points; + if (doTransform) { + for (var i = 0; i < transformedPoints.length / 2; i++) { + transformedPoints[i * 2] = basePoints[i * 2] * width + centerX; + transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY; + } + if (padding > 0) { + var expandedLineSet = expandPolygon(transformedPoints, -padding); + points = joinLines(expandedLineSet); + } else { + points = transformedPoints; + } + } else { + points = basePoints; + } + var currentX, currentY, nextX, nextY; + for (var _i2 = 0; _i2 < points.length / 2; _i2++) { + currentX = points[_i2 * 2]; + currentY = points[_i2 * 2 + 1]; + if (_i2 < points.length / 2 - 1) { + nextX = points[(_i2 + 1) * 2]; + nextY = points[(_i2 + 1) * 2 + 1]; + } else { + nextX = points[0]; + nextY = points[1]; + } + intersection = finiteLinesIntersect(x, y, centerX, centerY, currentX, currentY, nextX, nextY); + if (intersection.length !== 0) { + intersections.push(intersection[0], intersection[1]); + } + } + return intersections; + }; + var roundPolygonIntersectLine = function roundPolygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) { + var intersections = []; + var intersection; + var lines = new Array(basePoints.length); + var halfW = width / 2; + var halfH = height / 2; + var cornerRadius = getRoundPolygonRadius(width, height); + for (var i = 0; i < basePoints.length / 4; i++) { + var sourceUv = void 0, + destUv = void 0; + if (i === 0) { + sourceUv = basePoints.length - 2; + } else { + sourceUv = i * 4 - 2; + } + destUv = i * 4 + 2; + var px = centerX + halfW * basePoints[i * 4]; + var py = centerY + halfH * basePoints[i * 4 + 1]; + var cosTheta = -basePoints[sourceUv] * basePoints[destUv] - basePoints[sourceUv + 1] * basePoints[destUv + 1]; + var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2); + var cp0x = px - offset * basePoints[sourceUv]; + var cp0y = py - offset * basePoints[sourceUv + 1]; + var cp1x = px + offset * basePoints[destUv]; + var cp1y = py + offset * basePoints[destUv + 1]; + if (i === 0) { + lines[basePoints.length - 2] = cp0x; + lines[basePoints.length - 1] = cp0y; + } else { + lines[i * 4 - 2] = cp0x; + lines[i * 4 - 1] = cp0y; + } + lines[i * 4] = cp1x; + lines[i * 4 + 1] = cp1y; + var orthx = basePoints[sourceUv + 1]; + var orthy = -basePoints[sourceUv]; + var cosAlpha = orthx * basePoints[destUv] + orthy * basePoints[destUv + 1]; + if (cosAlpha < 0) { + orthx *= -1; + orthy *= -1; + } + var cx = cp0x + orthx * cornerRadius; + var cy = cp0y + orthy * cornerRadius; + intersection = intersectLineCircle(x, y, centerX, centerY, cx, cy, cornerRadius); + if (intersection.length !== 0) { + intersections.push(intersection[0], intersection[1]); + } + } + for (var _i3 = 0; _i3 < lines.length / 4; _i3++) { + intersection = finiteLinesIntersect(x, y, centerX, centerY, lines[_i3 * 4], lines[_i3 * 4 + 1], lines[_i3 * 4 + 2], lines[_i3 * 4 + 3], false); + if (intersection.length !== 0) { + intersections.push(intersection[0], intersection[1]); + } + } + if (intersections.length > 2) { + var lowestIntersection = [intersections[0], intersections[1]]; + var lowestSquaredDistance = Math.pow(lowestIntersection[0] - x, 2) + Math.pow(lowestIntersection[1] - y, 2); + for (var _i4 = 1; _i4 < intersections.length / 2; _i4++) { + var squaredDistance = Math.pow(intersections[_i4 * 2] - x, 2) + Math.pow(intersections[_i4 * 2 + 1] - y, 2); + if (squaredDistance <= lowestSquaredDistance) { + lowestIntersection[0] = intersections[_i4 * 2]; + lowestIntersection[1] = intersections[_i4 * 2 + 1]; + lowestSquaredDistance = squaredDistance; + } + } + return lowestIntersection; + } + return intersections; + }; + var shortenIntersection = function shortenIntersection(intersection, offset, amount) { + var disp = [intersection[0] - offset[0], intersection[1] - offset[1]]; + var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]); + var lenRatio = (length - amount) / length; + if (lenRatio < 0) { + lenRatio = 0.00001; + } + return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]]; + }; + var generateUnitNgonPointsFitToSquare = function generateUnitNgonPointsFitToSquare(sides, rotationRadians) { + var points = generateUnitNgonPoints(sides, rotationRadians); + points = fitPolygonToSquare(points); + return points; + }; + var fitPolygonToSquare = function fitPolygonToSquare(points) { + var x, y; + var sides = points.length / 2; + var minX = Infinity, + minY = Infinity, + maxX = -Infinity, + maxY = -Infinity; + for (var i = 0; i < sides; i++) { + x = points[2 * i]; + y = points[2 * i + 1]; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + + // stretch factors + var sx = 2 / (maxX - minX); + var sy = 2 / (maxY - minY); + for (var _i5 = 0; _i5 < sides; _i5++) { + x = points[2 * _i5] = points[2 * _i5] * sx; + y = points[2 * _i5 + 1] = points[2 * _i5 + 1] * sy; + minX = Math.min(minX, x); + maxX = Math.max(maxX, x); + minY = Math.min(minY, y); + maxY = Math.max(maxY, y); + } + if (minY < -1) { + for (var _i6 = 0; _i6 < sides; _i6++) { + y = points[2 * _i6 + 1] = points[2 * _i6 + 1] + (-1 - minY); + } + } + return points; + }; + var generateUnitNgonPoints = function generateUnitNgonPoints(sides, rotationRadians) { + var increment = 1.0 / sides * 2 * Math.PI; + var startAngle = sides % 2 === 0 ? Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0; + startAngle += rotationRadians; + var points = new Array(sides * 2); + var currentAngle; + for (var i = 0; i < sides; i++) { + currentAngle = i * increment + startAngle; + points[2 * i] = Math.cos(currentAngle); // x + points[2 * i + 1] = Math.sin(-currentAngle); // y + } + + return points; + }; + + // Set the default radius, unless half of width or height is smaller than default + var getRoundRectangleRadius = function getRoundRectangleRadius(width, height) { + return Math.min(width / 4, height / 4, 8); + }; + + // Set the default radius + var getRoundPolygonRadius = function getRoundPolygonRadius(width, height) { + return Math.min(width / 10, height / 10, 8); + }; + var getCutRectangleCornerLength = function getCutRectangleCornerLength() { + return 8; + }; + var bezierPtsToQuadCoeff = function bezierPtsToQuadCoeff(p0, p1, p2) { + return [p0 - 2 * p1 + p2, 2 * (p1 - p0), p0]; + }; + + // get curve width, height, and control point position offsets as a percentage of node height / width + var getBarrelCurveConstants = function getBarrelCurveConstants(width, height) { + return { + heightOffset: Math.min(15, 0.05 * height), + widthOffset: Math.min(100, 0.25 * width), + ctrlPtOffsetPct: 0.05 + }; + }; + + var pageRankDefaults = defaults$g({ + dampingFactor: 0.8, + precision: 0.000001, + iterations: 200, + weight: function weight(edge) { + return 1; + } + }); + var elesfn$o = { + pageRank: function pageRank(options) { + var _pageRankDefaults = pageRankDefaults(options), + dampingFactor = _pageRankDefaults.dampingFactor, + precision = _pageRankDefaults.precision, + iterations = _pageRankDefaults.iterations, + weight = _pageRankDefaults.weight; + var cy = this._private.cy; + var _this$byGroup = this.byGroup(), + nodes = _this$byGroup.nodes, + edges = _this$byGroup.edges; + var numNodes = nodes.length; + var numNodesSqd = numNodes * numNodes; + var numEdges = edges.length; + + // Construct transposed adjacency matrix + // First lets have a zeroed matrix of the right size + // We'll also keep track of the sum of each column + var matrix = new Array(numNodesSqd); + var columnSum = new Array(numNodes); + var additionalProb = (1 - dampingFactor) / numNodes; + + // Create null matrix + for (var i = 0; i < numNodes; i++) { + for (var j = 0; j < numNodes; j++) { + var n = i * numNodes + j; + matrix[n] = 0; + } + columnSum[i] = 0; + } + + // Now, process edges + for (var _i = 0; _i < numEdges; _i++) { + var edge = edges[_i]; + var srcId = edge.data('source'); + var tgtId = edge.data('target'); + + // Don't include loops in the matrix + if (srcId === tgtId) { + continue; + } + var s = nodes.indexOfId(srcId); + var t = nodes.indexOfId(tgtId); + var w = weight(edge); + var _n = t * numNodes + s; + + // Update matrix + matrix[_n] += w; + + // Update column sum + columnSum[s] += w; + } + + // Add additional probability based on damping factor + // Also, take into account columns that have sum = 0 + var p = 1.0 / numNodes + additionalProb; // Shorthand + + // Traverse matrix, column by column + for (var _j = 0; _j < numNodes; _j++) { + if (columnSum[_j] === 0) { + // No 'links' out from node jth, assume equal probability for each possible node + for (var _i2 = 0; _i2 < numNodes; _i2++) { + var _n2 = _i2 * numNodes + _j; + matrix[_n2] = p; + } + } else { + // Node jth has outgoing link, compute normalized probabilities + for (var _i3 = 0; _i3 < numNodes; _i3++) { + var _n3 = _i3 * numNodes + _j; + matrix[_n3] = matrix[_n3] / columnSum[_j] + additionalProb; + } + } + } + + // Compute dominant eigenvector using power method + var eigenvector = new Array(numNodes); + var temp = new Array(numNodes); + var previous; + + // Start with a vector of all 1's + // Also, initialize a null vector which will be used as shorthand + for (var _i4 = 0; _i4 < numNodes; _i4++) { + eigenvector[_i4] = 1; + } + for (var iter = 0; iter < iterations; iter++) { + // Temp array with all 0's + for (var _i5 = 0; _i5 < numNodes; _i5++) { + temp[_i5] = 0; + } + + // Multiply matrix with previous result + for (var _i6 = 0; _i6 < numNodes; _i6++) { + for (var _j2 = 0; _j2 < numNodes; _j2++) { + var _n4 = _i6 * numNodes + _j2; + temp[_i6] += matrix[_n4] * eigenvector[_j2]; + } + } + inPlaceSumNormalize(temp); + previous = eigenvector; + eigenvector = temp; + temp = previous; + var diff = 0; + // Compute difference (squared module) of both vectors + for (var _i7 = 0; _i7 < numNodes; _i7++) { + var delta = previous[_i7] - eigenvector[_i7]; + diff += delta * delta; + } + + // If difference is less than the desired threshold, stop iterating + if (diff < precision) { + break; + } + } + + // Construct result + var res = { + rank: function rank(node) { + node = cy.collection(node)[0]; + return eigenvector[nodes.indexOf(node)]; + } + }; + return res; + } // pageRank + }; // elesfn + + var defaults$f = defaults$g({ + root: null, + weight: function weight(edge) { + return 1; + }, + directed: false, + alpha: 0 + }); + var elesfn$n = { + degreeCentralityNormalized: function degreeCentralityNormalized(options) { + options = defaults$f(options); + var cy = this.cy(); + var nodes = this.nodes(); + var numNodes = nodes.length; + if (!options.directed) { + var degrees = {}; + var maxDegree = 0; + for (var i = 0; i < numNodes; i++) { + var node = nodes[i]; + + // add current node to the current options object and call degreeCentrality + options.root = node; + var currDegree = this.degreeCentrality(options); + if (maxDegree < currDegree.degree) { + maxDegree = currDegree.degree; + } + degrees[node.id()] = currDegree.degree; + } + return { + degree: function degree(node) { + if (maxDegree === 0) { + return 0; + } + if (string(node)) { + // from is a selector string + node = cy.filter(node); + } + return degrees[node.id()] / maxDegree; + } + }; + } else { + var indegrees = {}; + var outdegrees = {}; + var maxIndegree = 0; + var maxOutdegree = 0; + for (var _i = 0; _i < numNodes; _i++) { + var _node = nodes[_i]; + var id = _node.id(); + + // add current node to the current options object and call degreeCentrality + options.root = _node; + var _currDegree = this.degreeCentrality(options); + if (maxIndegree < _currDegree.indegree) maxIndegree = _currDegree.indegree; + if (maxOutdegree < _currDegree.outdegree) maxOutdegree = _currDegree.outdegree; + indegrees[id] = _currDegree.indegree; + outdegrees[id] = _currDegree.outdegree; + } + return { + indegree: function indegree(node) { + if (maxIndegree == 0) { + return 0; + } + if (string(node)) { + // from is a selector string + node = cy.filter(node); + } + return indegrees[node.id()] / maxIndegree; + }, + outdegree: function outdegree(node) { + if (maxOutdegree === 0) { + return 0; + } + if (string(node)) { + // from is a selector string + node = cy.filter(node); + } + return outdegrees[node.id()] / maxOutdegree; + } + }; + } + }, + // degreeCentralityNormalized + + // Implemented from the algorithm in Opsahl's paper + // "Node centrality in weighted networks: Generalizing degree and shortest paths" + // check the heading 2 "Degree" + degreeCentrality: function degreeCentrality(options) { + options = defaults$f(options); + var cy = this.cy(); + var callingEles = this; + var _options = options, + root = _options.root, + weight = _options.weight, + directed = _options.directed, + alpha = _options.alpha; + root = cy.collection(root)[0]; + if (!directed) { + var connEdges = root.connectedEdges().intersection(callingEles); + var k = connEdges.length; + var s = 0; + + // Now, sum edge weights + for (var i = 0; i < connEdges.length; i++) { + s += weight(connEdges[i]); + } + return { + degree: Math.pow(k, 1 - alpha) * Math.pow(s, alpha) + }; + } else { + var edges = root.connectedEdges(); + var incoming = edges.filter(function (edge) { + return edge.target().same(root) && callingEles.has(edge); + }); + var outgoing = edges.filter(function (edge) { + return edge.source().same(root) && callingEles.has(edge); + }); + var k_in = incoming.length; + var k_out = outgoing.length; + var s_in = 0; + var s_out = 0; + + // Now, sum incoming edge weights + for (var _i2 = 0; _i2 < incoming.length; _i2++) { + s_in += weight(incoming[_i2]); + } + + // Now, sum outgoing edge weights + for (var _i3 = 0; _i3 < outgoing.length; _i3++) { + s_out += weight(outgoing[_i3]); + } + return { + indegree: Math.pow(k_in, 1 - alpha) * Math.pow(s_in, alpha), + outdegree: Math.pow(k_out, 1 - alpha) * Math.pow(s_out, alpha) + }; + } + } // degreeCentrality + }; // elesfn + + // nice, short mathematical alias + elesfn$n.dc = elesfn$n.degreeCentrality; + elesfn$n.dcn = elesfn$n.degreeCentralityNormalised = elesfn$n.degreeCentralityNormalized; + + var defaults$e = defaults$g({ + harmonic: true, + weight: function weight() { + return 1; + }, + directed: false, + root: null + }); + var elesfn$m = { + closenessCentralityNormalized: function closenessCentralityNormalized(options) { + var _defaults = defaults$e(options), + harmonic = _defaults.harmonic, + weight = _defaults.weight, + directed = _defaults.directed; + var cy = this.cy(); + var closenesses = {}; + var maxCloseness = 0; + var nodes = this.nodes(); + var fw = this.floydWarshall({ + weight: weight, + directed: directed + }); + + // Compute closeness for every node and find the maximum closeness + for (var i = 0; i < nodes.length; i++) { + var currCloseness = 0; + var node_i = nodes[i]; + for (var j = 0; j < nodes.length; j++) { + if (i !== j) { + var d = fw.distance(node_i, nodes[j]); + if (harmonic) { + currCloseness += 1 / d; + } else { + currCloseness += d; + } + } + } + if (!harmonic) { + currCloseness = 1 / currCloseness; + } + if (maxCloseness < currCloseness) { + maxCloseness = currCloseness; + } + closenesses[node_i.id()] = currCloseness; + } + return { + closeness: function closeness(node) { + if (maxCloseness == 0) { + return 0; + } + if (string(node)) { + // from is a selector string + node = cy.filter(node)[0].id(); + } else { + // from is a node + node = node.id(); + } + return closenesses[node] / maxCloseness; + } + }; + }, + // Implemented from pseudocode from wikipedia + closenessCentrality: function closenessCentrality(options) { + var _defaults2 = defaults$e(options), + root = _defaults2.root, + weight = _defaults2.weight, + directed = _defaults2.directed, + harmonic = _defaults2.harmonic; + root = this.filter(root)[0]; + + // we need distance from this node to every other node + var dijkstra = this.dijkstra({ + root: root, + weight: weight, + directed: directed + }); + var totalDistance = 0; + var nodes = this.nodes(); + for (var i = 0; i < nodes.length; i++) { + var n = nodes[i]; + if (!n.same(root)) { + var d = dijkstra.distanceTo(n); + if (harmonic) { + totalDistance += 1 / d; + } else { + totalDistance += d; + } + } + } + return harmonic ? totalDistance : 1 / totalDistance; + } // closenessCentrality + }; // elesfn + + // nice, short mathematical alias + elesfn$m.cc = elesfn$m.closenessCentrality; + elesfn$m.ccn = elesfn$m.closenessCentralityNormalised = elesfn$m.closenessCentralityNormalized; + + var defaults$d = defaults$g({ + weight: null, + directed: false + }); + var elesfn$l = { + // Implemented from the algorithm in the paper "On Variants of Shortest-Path Betweenness Centrality and their Generic Computation" by Ulrik Brandes + betweennessCentrality: function betweennessCentrality(options) { + var _defaults = defaults$d(options), + directed = _defaults.directed, + weight = _defaults.weight; + var weighted = weight != null; + var cy = this.cy(); + + // starting + var V = this.nodes(); + var A = {}; + var _C = {}; + var max = 0; + var C = { + set: function set(key, val) { + _C[key] = val; + if (val > max) { + max = val; + } + }, + get: function get(key) { + return _C[key]; + } + }; + + // A contains the neighborhoods of every node + for (var i = 0; i < V.length; i++) { + var v = V[i]; + var vid = v.id(); + if (directed) { + A[vid] = v.outgoers().nodes(); // get outgoers of every node + } else { + A[vid] = v.openNeighborhood().nodes(); // get neighbors of every node + } + + C.set(vid, 0); + } + var _loop = function _loop(s) { + var sid = V[s].id(); + var S = []; // stack + var P = {}; + var g = {}; + var d = {}; + var Q = new heap(function (a, b) { + return d[a] - d[b]; + }); // queue + + // init dictionaries + for (var _i = 0; _i < V.length; _i++) { + var _vid = V[_i].id(); + P[_vid] = []; + g[_vid] = 0; + d[_vid] = Infinity; + } + g[sid] = 1; // sigma + d[sid] = 0; // distance to s + + Q.push(sid); + while (!Q.empty()) { + var _v = Q.pop(); + S.push(_v); + if (weighted) { + for (var j = 0; j < A[_v].length; j++) { + var w = A[_v][j]; + var vEle = cy.getElementById(_v); + var edge = void 0; + if (vEle.edgesTo(w).length > 0) { + edge = vEle.edgesTo(w)[0]; + } else { + edge = w.edgesTo(vEle)[0]; + } + var edgeWeight = weight(edge); + w = w.id(); + if (d[w] > d[_v] + edgeWeight) { + d[w] = d[_v] + edgeWeight; + if (Q.nodes.indexOf(w) < 0) { + //if w is not in Q + Q.push(w); + } else { + // update position if w is in Q + Q.updateItem(w); + } + g[w] = 0; + P[w] = []; + } + if (d[w] == d[_v] + edgeWeight) { + g[w] = g[w] + g[_v]; + P[w].push(_v); + } + } + } else { + for (var _j = 0; _j < A[_v].length; _j++) { + var _w = A[_v][_j].id(); + if (d[_w] == Infinity) { + Q.push(_w); + d[_w] = d[_v] + 1; + } + if (d[_w] == d[_v] + 1) { + g[_w] = g[_w] + g[_v]; + P[_w].push(_v); + } + } + } + } + var e = {}; + for (var _i2 = 0; _i2 < V.length; _i2++) { + e[V[_i2].id()] = 0; + } + while (S.length > 0) { + var _w2 = S.pop(); + for (var _j2 = 0; _j2 < P[_w2].length; _j2++) { + var _v2 = P[_w2][_j2]; + e[_v2] = e[_v2] + g[_v2] / g[_w2] * (1 + e[_w2]); + } + if (_w2 != V[s].id()) { + C.set(_w2, C.get(_w2) + e[_w2]); + } + } + }; + for (var s = 0; s < V.length; s++) { + _loop(s); + } + var ret = { + betweenness: function betweenness(node) { + var id = cy.collection(node).id(); + return C.get(id); + }, + betweennessNormalized: function betweennessNormalized(node) { + if (max == 0) { + return 0; + } + var id = cy.collection(node).id(); + return C.get(id) / max; + } + }; + + // alias + ret.betweennessNormalised = ret.betweennessNormalized; + return ret; + } // betweennessCentrality + }; // elesfn + + // nice, short mathematical alias + elesfn$l.bc = elesfn$l.betweennessCentrality; + + // Implemented by Zoe Xi @zoexi for GSOC 2016 + + /* eslint-disable no-unused-vars */ + var defaults$c = defaults$g({ + expandFactor: 2, + // affects time of computation and cluster granularity to some extent: M * M + inflateFactor: 2, + // affects cluster granularity (the greater the value, the more clusters): M(i,j) / E(j) + multFactor: 1, + // optional self loops for each node. Use a neutral value to improve cluster computations. + maxIterations: 20, + // maximum number of iterations of the MCL algorithm in a single run + attributes: [ + // attributes/features used to group nodes, ie. similarity values between nodes + function (edge) { + return 1; + }] + }); + /* eslint-enable */ + + var setOptions$3 = function setOptions(options) { + return defaults$c(options); + }; + /* eslint-enable */ + + var getSimilarity$1 = function getSimilarity(edge, attributes) { + var total = 0; + for (var i = 0; i < attributes.length; i++) { + total += attributes[i](edge); + } + return total; + }; + var addLoops = function addLoops(M, n, val) { + for (var i = 0; i < n; i++) { + M[i * n + i] = val; + } + }; + var normalize = function normalize(M, n) { + var sum; + for (var col = 0; col < n; col++) { + sum = 0; + for (var row = 0; row < n; row++) { + sum += M[row * n + col]; + } + for (var _row = 0; _row < n; _row++) { + M[_row * n + col] = M[_row * n + col] / sum; + } + } + }; + + // TODO: blocked matrix multiplication? + var mmult = function mmult(A, B, n) { + var C = new Array(n * n); + for (var i = 0; i < n; i++) { + for (var j = 0; j < n; j++) { + C[i * n + j] = 0; + } + for (var k = 0; k < n; k++) { + for (var _j = 0; _j < n; _j++) { + C[i * n + _j] += A[i * n + k] * B[k * n + _j]; + } + } + } + return C; + }; + var expand = function expand(M, n, expandFactor /** power **/) { + var _M = M.slice(0); + for (var p = 1; p < expandFactor; p++) { + M = mmult(M, _M, n); + } + return M; + }; + var inflate = function inflate(M, n, inflateFactor /** r **/) { + var _M = new Array(n * n); + + // M(i,j) ^ inflatePower + for (var i = 0; i < n * n; i++) { + _M[i] = Math.pow(M[i], inflateFactor); + } + normalize(_M, n); + return _M; + }; + var hasConverged = function hasConverged(M, _M, n2, roundFactor) { + // Check that both matrices have the same elements (i,j) + for (var i = 0; i < n2; i++) { + var v1 = Math.round(M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor); // truncate to 'roundFactor' decimal places + var v2 = Math.round(_M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor); + if (v1 !== v2) { + return false; + } + } + return true; + }; + var assign$2 = function assign(M, n, nodes, cy) { + var clusters = []; + for (var i = 0; i < n; i++) { + var cluster = []; + for (var j = 0; j < n; j++) { + // Row-wise attractors and elements that they attract belong in same cluster + if (Math.round(M[i * n + j] * 1000) / 1000 > 0) { + cluster.push(nodes[j]); + } + } + if (cluster.length !== 0) { + clusters.push(cy.collection(cluster)); + } + } + return clusters; + }; + var isDuplicate = function isDuplicate(c1, c2) { + for (var i = 0; i < c1.length; i++) { + if (!c2[i] || c1[i].id() !== c2[i].id()) { + return false; + } + } + return true; + }; + var removeDuplicates = function removeDuplicates(clusters) { + for (var i = 0; i < clusters.length; i++) { + for (var j = 0; j < clusters.length; j++) { + if (i != j && isDuplicate(clusters[i], clusters[j])) { + clusters.splice(j, 1); + } + } + } + return clusters; + }; + var markovClustering = function markovClustering(options) { + var nodes = this.nodes(); + var edges = this.edges(); + var cy = this.cy(); + + // Set parameters of algorithm: + var opts = setOptions$3(options); + + // Map each node to its position in node array + var id2position = {}; + for (var i = 0; i < nodes.length; i++) { + id2position[nodes[i].id()] = i; + } + + // Generate stochastic matrix M from input graph G (should be symmetric/undirected) + var n = nodes.length, + n2 = n * n; + var M = new Array(n2), + _M; + for (var _i = 0; _i < n2; _i++) { + M[_i] = 0; + } + for (var e = 0; e < edges.length; e++) { + var edge = edges[e]; + var _i2 = id2position[edge.source().id()]; + var j = id2position[edge.target().id()]; + var sim = getSimilarity$1(edge, opts.attributes); + M[_i2 * n + j] += sim; // G should be symmetric and undirected + M[j * n + _i2] += sim; + } + + // Begin Markov cluster algorithm + + // Step 1: Add self loops to each node, ie. add multFactor to matrix diagonal + addLoops(M, n, opts.multFactor); + + // Step 2: M = normalize( M ); + normalize(M, n); + var isStillMoving = true; + var iterations = 0; + while (isStillMoving && iterations < opts.maxIterations) { + isStillMoving = false; + + // Step 3: + _M = expand(M, n, opts.expandFactor); + + // Step 4: + M = inflate(_M, n, opts.inflateFactor); + + // Step 5: check to see if ~steady state has been reached + if (!hasConverged(M, _M, n2, 4)) { + isStillMoving = true; + } + iterations++; + } + + // Build clusters from matrix + var clusters = assign$2(M, n, nodes, cy); + + // Remove duplicate clusters due to symmetry of graph and M matrix + clusters = removeDuplicates(clusters); + return clusters; + }; + var markovClustering$1 = { + markovClustering: markovClustering, + mcl: markovClustering + }; + + // Common distance metrics for clustering algorithms + var identity = function identity(x) { + return x; + }; + var absDiff = function absDiff(p, q) { + return Math.abs(q - p); + }; + var addAbsDiff = function addAbsDiff(total, p, q) { + return total + absDiff(p, q); + }; + var addSquaredDiff = function addSquaredDiff(total, p, q) { + return total + Math.pow(q - p, 2); + }; + var sqrt = function sqrt(x) { + return Math.sqrt(x); + }; + var maxAbsDiff = function maxAbsDiff(currentMax, p, q) { + return Math.max(currentMax, absDiff(p, q)); + }; + var getDistance = function getDistance(length, getP, getQ, init, visit) { + var post = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : identity; + var ret = init; + var p, q; + for (var dim = 0; dim < length; dim++) { + p = getP(dim); + q = getQ(dim); + ret = visit(ret, p, q); + } + return post(ret); + }; + var distances = { + euclidean: function euclidean(length, getP, getQ) { + if (length >= 2) { + return getDistance(length, getP, getQ, 0, addSquaredDiff, sqrt); + } else { + // for single attr case, more efficient to avoid sqrt + return getDistance(length, getP, getQ, 0, addAbsDiff); + } + }, + squaredEuclidean: function squaredEuclidean(length, getP, getQ) { + return getDistance(length, getP, getQ, 0, addSquaredDiff); + }, + manhattan: function manhattan(length, getP, getQ) { + return getDistance(length, getP, getQ, 0, addAbsDiff); + }, + max: function max(length, getP, getQ) { + return getDistance(length, getP, getQ, -Infinity, maxAbsDiff); + } + }; + + // in case the user accidentally doesn't use camel case + distances['squared-euclidean'] = distances['squaredEuclidean']; + distances['squaredeuclidean'] = distances['squaredEuclidean']; + function clusteringDistance (method, length, getP, getQ, nodeP, nodeQ) { + var impl; + if (fn$6(method)) { + impl = method; + } else { + impl = distances[method] || distances.euclidean; + } + if (length === 0 && fn$6(method)) { + return impl(nodeP, nodeQ); + } else { + return impl(length, getP, getQ, nodeP, nodeQ); + } + } + + var defaults$b = defaults$g({ + k: 2, + m: 2, + sensitivityThreshold: 0.0001, + distance: 'euclidean', + maxIterations: 10, + attributes: [], + testMode: false, + testCentroids: null + }); + var setOptions$2 = function setOptions(options) { + return defaults$b(options); + }; + + var getDist = function getDist(type, node, centroid, attributes, mode) { + var noNodeP = mode !== 'kMedoids'; + var getP = noNodeP ? function (i) { + return centroid[i]; + } : function (i) { + return attributes[i](centroid); + }; + var getQ = function getQ(i) { + return attributes[i](node); + }; + var nodeP = centroid; + var nodeQ = node; + return clusteringDistance(type, attributes.length, getP, getQ, nodeP, nodeQ); + }; + var randomCentroids = function randomCentroids(nodes, k, attributes) { + var ndim = attributes.length; + var min = new Array(ndim); + var max = new Array(ndim); + var centroids = new Array(k); + var centroid = null; + + // Find min, max values for each attribute dimension + for (var i = 0; i < ndim; i++) { + min[i] = nodes.min(attributes[i]).value; + max[i] = nodes.max(attributes[i]).value; + } + + // Build k centroids, each represented as an n-dim feature vector + for (var c = 0; c < k; c++) { + centroid = []; + for (var _i = 0; _i < ndim; _i++) { + centroid[_i] = Math.random() * (max[_i] - min[_i]) + min[_i]; // random initial value + } + + centroids[c] = centroid; + } + return centroids; + }; + var classify = function classify(node, centroids, distance, attributes, type) { + var min = Infinity; + var index = 0; + for (var i = 0; i < centroids.length; i++) { + var dist = getDist(distance, node, centroids[i], attributes, type); + if (dist < min) { + min = dist; + index = i; + } + } + return index; + }; + var buildCluster = function buildCluster(centroid, nodes, assignment) { + var cluster = []; + var node = null; + for (var n = 0; n < nodes.length; n++) { + node = nodes[n]; + if (assignment[node.id()] === centroid) { + //console.log("Node " + node.id() + " is associated with medoid #: " + m); + cluster.push(node); + } + } + return cluster; + }; + var haveValuesConverged = function haveValuesConverged(v1, v2, sensitivityThreshold) { + return Math.abs(v2 - v1) <= sensitivityThreshold; + }; + var haveMatricesConverged = function haveMatricesConverged(v1, v2, sensitivityThreshold) { + for (var i = 0; i < v1.length; i++) { + for (var j = 0; j < v1[i].length; j++) { + var diff = Math.abs(v1[i][j] - v2[i][j]); + if (diff > sensitivityThreshold) { + return false; + } + } + } + return true; + }; + var seenBefore = function seenBefore(node, medoids, n) { + for (var i = 0; i < n; i++) { + if (node === medoids[i]) return true; + } + return false; + }; + var randomMedoids = function randomMedoids(nodes, k) { + var medoids = new Array(k); + + // For small data sets, the probability of medoid conflict is greater, + // so we need to check to see if we've already seen or chose this node before. + if (nodes.length < 50) { + // Randomly select k medoids from the n nodes + for (var i = 0; i < k; i++) { + var node = nodes[Math.floor(Math.random() * nodes.length)]; + + // If we've already chosen this node to be a medoid, don't choose it again (for small data sets). + // Instead choose a different random node. + while (seenBefore(node, medoids, i)) { + node = nodes[Math.floor(Math.random() * nodes.length)]; + } + medoids[i] = node; + } + } else { + // Relatively large data set, so pretty safe to not check and just select random nodes + for (var _i2 = 0; _i2 < k; _i2++) { + medoids[_i2] = nodes[Math.floor(Math.random() * nodes.length)]; + } + } + return medoids; + }; + var findCost = function findCost(potentialNewMedoid, cluster, attributes) { + var cost = 0; + for (var n = 0; n < cluster.length; n++) { + cost += getDist('manhattan', cluster[n], potentialNewMedoid, attributes, 'kMedoids'); + } + return cost; + }; + var kMeans = function kMeans(options) { + var cy = this.cy(); + var nodes = this.nodes(); + var node = null; + + // Set parameters of algorithm: # of clusters, distance metric, etc. + var opts = setOptions$2(options); + + // Begin k-means algorithm + var clusters = new Array(opts.k); + var assignment = {}; + var centroids; + + // Step 1: Initialize centroid positions + if (opts.testMode) { + if (typeof opts.testCentroids === 'number') { + // TODO: implement a seeded random number generator. + opts.testCentroids; + centroids = randomCentroids(nodes, opts.k, opts.attributes); + } else if (_typeof(opts.testCentroids) === 'object') { + centroids = opts.testCentroids; + } else { + centroids = randomCentroids(nodes, opts.k, opts.attributes); + } + } else { + centroids = randomCentroids(nodes, opts.k, opts.attributes); + } + var isStillMoving = true; + var iterations = 0; + while (isStillMoving && iterations < opts.maxIterations) { + // Step 2: Assign nodes to the nearest centroid + for (var n = 0; n < nodes.length; n++) { + node = nodes[n]; + // Determine which cluster this node belongs to: node id => cluster # + assignment[node.id()] = classify(node, centroids, opts.distance, opts.attributes, 'kMeans'); + } + + // Step 3: For each of the k clusters, update its centroid + isStillMoving = false; + for (var c = 0; c < opts.k; c++) { + // Get all nodes that belong to this cluster + var cluster = buildCluster(c, nodes, assignment); + if (cluster.length === 0) { + // If cluster is empty, break out early & move to next cluster + continue; + } + + // Update centroids by calculating avg of all nodes within the cluster. + var ndim = opts.attributes.length; + var centroid = centroids[c]; // [ dim_1, dim_2, dim_3, ... , dim_n ] + var newCentroid = new Array(ndim); + var sum = new Array(ndim); + for (var d = 0; d < ndim; d++) { + sum[d] = 0.0; + for (var i = 0; i < cluster.length; i++) { + node = cluster[i]; + sum[d] += opts.attributes[d](node); + } + newCentroid[d] = sum[d] / cluster.length; + + // Check to see if algorithm has converged, i.e. when centroids no longer change + if (!haveValuesConverged(newCentroid[d], centroid[d], opts.sensitivityThreshold)) { + isStillMoving = true; + } + } + centroids[c] = newCentroid; + clusters[c] = cy.collection(cluster); + } + iterations++; + } + return clusters; + }; + var kMedoids = function kMedoids(options) { + var cy = this.cy(); + var nodes = this.nodes(); + var node = null; + var opts = setOptions$2(options); + + // Begin k-medoids algorithm + var clusters = new Array(opts.k); + var medoids; + var assignment = {}; + var curCost; + var minCosts = new Array(opts.k); // minimum cost configuration for each cluster + + // Step 1: Initialize k medoids + if (opts.testMode) { + if (typeof opts.testCentroids === 'number') ; else if (_typeof(opts.testCentroids) === 'object') { + medoids = opts.testCentroids; + } else { + medoids = randomMedoids(nodes, opts.k); + } + } else { + medoids = randomMedoids(nodes, opts.k); + } + var isStillMoving = true; + var iterations = 0; + while (isStillMoving && iterations < opts.maxIterations) { + // Step 2: Assign nodes to the nearest medoid + for (var n = 0; n < nodes.length; n++) { + node = nodes[n]; + // Determine which cluster this node belongs to: node id => cluster # + assignment[node.id()] = classify(node, medoids, opts.distance, opts.attributes, 'kMedoids'); + } + isStillMoving = false; + // Step 3: For each medoid m, and for each node associated with mediod m, + // select the node with the lowest configuration cost as new medoid. + for (var m = 0; m < medoids.length; m++) { + // Get all nodes that belong to this medoid + var cluster = buildCluster(m, nodes, assignment); + if (cluster.length === 0) { + // If cluster is empty, break out early & move to next cluster + continue; + } + minCosts[m] = findCost(medoids[m], cluster, opts.attributes); // original cost + + // Select different medoid if its configuration has the lowest cost + for (var _n = 0; _n < cluster.length; _n++) { + curCost = findCost(cluster[_n], cluster, opts.attributes); + if (curCost < minCosts[m]) { + minCosts[m] = curCost; + medoids[m] = cluster[_n]; + isStillMoving = true; + } + } + clusters[m] = cy.collection(cluster); + } + iterations++; + } + return clusters; + }; + var updateCentroids = function updateCentroids(centroids, nodes, U, weight, opts) { + var numerator, denominator; + for (var n = 0; n < nodes.length; n++) { + for (var c = 0; c < centroids.length; c++) { + weight[n][c] = Math.pow(U[n][c], opts.m); + } + } + for (var _c = 0; _c < centroids.length; _c++) { + for (var dim = 0; dim < opts.attributes.length; dim++) { + numerator = 0; + denominator = 0; + for (var _n2 = 0; _n2 < nodes.length; _n2++) { + numerator += weight[_n2][_c] * opts.attributes[dim](nodes[_n2]); + denominator += weight[_n2][_c]; + } + centroids[_c][dim] = numerator / denominator; + } + } + }; + var updateMembership = function updateMembership(U, _U, centroids, nodes, opts) { + // Save previous step + for (var i = 0; i < U.length; i++) { + _U[i] = U[i].slice(); + } + var sum, numerator, denominator; + var pow = 2 / (opts.m - 1); + for (var c = 0; c < centroids.length; c++) { + for (var n = 0; n < nodes.length; n++) { + sum = 0; + for (var k = 0; k < centroids.length; k++) { + // against all other centroids + numerator = getDist(opts.distance, nodes[n], centroids[c], opts.attributes, 'cmeans'); + denominator = getDist(opts.distance, nodes[n], centroids[k], opts.attributes, 'cmeans'); + sum += Math.pow(numerator / denominator, pow); + } + U[n][c] = 1 / sum; + } + } + }; + var assign$1 = function assign(nodes, U, opts, cy) { + var clusters = new Array(opts.k); + for (var c = 0; c < clusters.length; c++) { + clusters[c] = []; + } + var max; + var index; + for (var n = 0; n < U.length; n++) { + // for each node (U is N x C matrix) + max = -Infinity; + index = -1; + // Determine which cluster the node is most likely to belong in + for (var _c2 = 0; _c2 < U[0].length; _c2++) { + if (U[n][_c2] > max) { + max = U[n][_c2]; + index = _c2; + } + } + clusters[index].push(nodes[n]); + } + + // Turn every array into a collection of nodes + for (var _c3 = 0; _c3 < clusters.length; _c3++) { + clusters[_c3] = cy.collection(clusters[_c3]); + } + return clusters; + }; + var fuzzyCMeans = function fuzzyCMeans(options) { + var cy = this.cy(); + var nodes = this.nodes(); + var opts = setOptions$2(options); + + // Begin fuzzy c-means algorithm + var clusters; + var centroids; + var U; + var _U; + var weight; + + // Step 1: Initialize letiables. + _U = new Array(nodes.length); + for (var i = 0; i < nodes.length; i++) { + // N x C matrix + _U[i] = new Array(opts.k); + } + U = new Array(nodes.length); + for (var _i3 = 0; _i3 < nodes.length; _i3++) { + // N x C matrix + U[_i3] = new Array(opts.k); + } + for (var _i4 = 0; _i4 < nodes.length; _i4++) { + var total = 0; + for (var j = 0; j < opts.k; j++) { + U[_i4][j] = Math.random(); + total += U[_i4][j]; + } + for (var _j = 0; _j < opts.k; _j++) { + U[_i4][_j] = U[_i4][_j] / total; + } + } + centroids = new Array(opts.k); + for (var _i5 = 0; _i5 < opts.k; _i5++) { + centroids[_i5] = new Array(opts.attributes.length); + } + weight = new Array(nodes.length); + for (var _i6 = 0; _i6 < nodes.length; _i6++) { + // N x C matrix + weight[_i6] = new Array(opts.k); + } + // end init FCM + + var isStillMoving = true; + var iterations = 0; + while (isStillMoving && iterations < opts.maxIterations) { + isStillMoving = false; + + // Step 2: Calculate the centroids for each step. + updateCentroids(centroids, nodes, U, weight, opts); + + // Step 3: Update the partition matrix U. + updateMembership(U, _U, centroids, nodes, opts); + + // Step 4: Check for convergence. + if (!haveMatricesConverged(U, _U, opts.sensitivityThreshold)) { + isStillMoving = true; + } + iterations++; + } + + // Assign nodes to clusters with highest probability. + clusters = assign$1(nodes, U, opts, cy); + return { + clusters: clusters, + degreeOfMembership: U + }; + }; + var kClustering = { + kMeans: kMeans, + kMedoids: kMedoids, + fuzzyCMeans: fuzzyCMeans, + fcm: fuzzyCMeans + }; + + // Implemented by Zoe Xi @zoexi for GSOC 2016 + var defaults$a = defaults$g({ + distance: 'euclidean', + // distance metric to compare nodes + linkage: 'min', + // linkage criterion : how to determine the distance between clusters of nodes + mode: 'threshold', + // mode:'threshold' => clusters must be threshold distance apart + threshold: Infinity, + // the distance threshold + // mode:'dendrogram' => the nodes are organised as leaves in a tree (siblings are close), merging makes clusters + addDendrogram: false, + // whether to add the dendrogram to the graph for viz + dendrogramDepth: 0, + // depth at which dendrogram branches are merged into the returned clusters + attributes: [] // array of attr functions + }); + + var linkageAliases = { + 'single': 'min', + 'complete': 'max' + }; + var setOptions$1 = function setOptions(options) { + var opts = defaults$a(options); + var preferredAlias = linkageAliases[opts.linkage]; + if (preferredAlias != null) { + opts.linkage = preferredAlias; + } + return opts; + }; + var mergeClosest = function mergeClosest(clusters, index, dists, mins, opts) { + // Find two closest clusters from cached mins + var minKey = 0; + var min = Infinity; + var dist; + var attrs = opts.attributes; + var getDist = function getDist(n1, n2) { + return clusteringDistance(opts.distance, attrs.length, function (i) { + return attrs[i](n1); + }, function (i) { + return attrs[i](n2); + }, n1, n2); + }; + for (var i = 0; i < clusters.length; i++) { + var key = clusters[i].key; + var _dist = dists[key][mins[key]]; + if (_dist < min) { + minKey = key; + min = _dist; + } + } + if (opts.mode === 'threshold' && min >= opts.threshold || opts.mode === 'dendrogram' && clusters.length === 1) { + return false; + } + var c1 = index[minKey]; + var c2 = index[mins[minKey]]; + var merged; + + // Merge two closest clusters + if (opts.mode === 'dendrogram') { + merged = { + left: c1, + right: c2, + key: c1.key + }; + } else { + merged = { + value: c1.value.concat(c2.value), + key: c1.key + }; + } + clusters[c1.index] = merged; + clusters.splice(c2.index, 1); + index[c1.key] = merged; + + // Update distances with new merged cluster + for (var _i = 0; _i < clusters.length; _i++) { + var cur = clusters[_i]; + if (c1.key === cur.key) { + dist = Infinity; + } else if (opts.linkage === 'min') { + dist = dists[c1.key][cur.key]; + if (dists[c1.key][cur.key] > dists[c2.key][cur.key]) { + dist = dists[c2.key][cur.key]; + } + } else if (opts.linkage === 'max') { + dist = dists[c1.key][cur.key]; + if (dists[c1.key][cur.key] < dists[c2.key][cur.key]) { + dist = dists[c2.key][cur.key]; + } + } else if (opts.linkage === 'mean') { + dist = (dists[c1.key][cur.key] * c1.size + dists[c2.key][cur.key] * c2.size) / (c1.size + c2.size); + } else { + if (opts.mode === 'dendrogram') dist = getDist(cur.value, c1.value);else dist = getDist(cur.value[0], c1.value[0]); + } + dists[c1.key][cur.key] = dists[cur.key][c1.key] = dist; // distance matrix is symmetric + } + + // Update cached mins + for (var _i2 = 0; _i2 < clusters.length; _i2++) { + var key1 = clusters[_i2].key; + if (mins[key1] === c1.key || mins[key1] === c2.key) { + var _min = key1; + for (var j = 0; j < clusters.length; j++) { + var key2 = clusters[j].key; + if (dists[key1][key2] < dists[key1][_min]) { + _min = key2; + } + } + mins[key1] = _min; + } + clusters[_i2].index = _i2; + } + + // Clean up meta data used for clustering + c1.key = c2.key = c1.index = c2.index = null; + return true; + }; + var getAllChildren = function getAllChildren(root, arr, cy) { + if (!root) return; + if (root.value) { + arr.push(root.value); + } else { + if (root.left) getAllChildren(root.left, arr); + if (root.right) getAllChildren(root.right, arr); + } + }; + var buildDendrogram = function buildDendrogram(root, cy) { + if (!root) return ''; + if (root.left && root.right) { + var leftStr = buildDendrogram(root.left, cy); + var rightStr = buildDendrogram(root.right, cy); + var node = cy.add({ + group: 'nodes', + data: { + id: leftStr + ',' + rightStr + } + }); + cy.add({ + group: 'edges', + data: { + source: leftStr, + target: node.id() + } + }); + cy.add({ + group: 'edges', + data: { + source: rightStr, + target: node.id() + } + }); + return node.id(); + } else if (root.value) { + return root.value.id(); + } + }; + var buildClustersFromTree = function buildClustersFromTree(root, k, cy) { + if (!root) return []; + var left = [], + right = [], + leaves = []; + if (k === 0) { + // don't cut tree, simply return all nodes as 1 single cluster + if (root.left) getAllChildren(root.left, left); + if (root.right) getAllChildren(root.right, right); + leaves = left.concat(right); + return [cy.collection(leaves)]; + } else if (k === 1) { + // cut at root + + if (root.value) { + // leaf node + return [cy.collection(root.value)]; + } else { + if (root.left) getAllChildren(root.left, left); + if (root.right) getAllChildren(root.right, right); + return [cy.collection(left), cy.collection(right)]; + } + } else { + if (root.value) { + return [cy.collection(root.value)]; + } else { + if (root.left) left = buildClustersFromTree(root.left, k - 1, cy); + if (root.right) right = buildClustersFromTree(root.right, k - 1, cy); + return left.concat(right); + } + } + }; + + var hierarchicalClustering = function hierarchicalClustering(options) { + var cy = this.cy(); + var nodes = this.nodes(); + + // Set parameters of algorithm: linkage type, distance metric, etc. + var opts = setOptions$1(options); + var attrs = opts.attributes; + var getDist = function getDist(n1, n2) { + return clusteringDistance(opts.distance, attrs.length, function (i) { + return attrs[i](n1); + }, function (i) { + return attrs[i](n2); + }, n1, n2); + }; + + // Begin hierarchical algorithm + var clusters = []; + var dists = []; // distances between each pair of clusters + var mins = []; // closest cluster for each cluster + var index = []; // hash of all clusters by key + + // In agglomerative (bottom-up) clustering, each node starts as its own cluster + for (var n = 0; n < nodes.length; n++) { + var cluster = { + value: opts.mode === 'dendrogram' ? nodes[n] : [nodes[n]], + key: n, + index: n + }; + clusters[n] = cluster; + index[n] = cluster; + dists[n] = []; + mins[n] = 0; + } + + // Calculate the distance between each pair of clusters + for (var i = 0; i < clusters.length; i++) { + for (var j = 0; j <= i; j++) { + var dist = void 0; + if (opts.mode === 'dendrogram') { + // modes store cluster values differently + dist = i === j ? Infinity : getDist(clusters[i].value, clusters[j].value); + } else { + dist = i === j ? Infinity : getDist(clusters[i].value[0], clusters[j].value[0]); + } + dists[i][j] = dist; + dists[j][i] = dist; + if (dist < dists[i][mins[i]]) { + mins[i] = j; // Cache mins: closest cluster to cluster i is cluster j + } + } + } + + // Find the closest pair of clusters and merge them into a single cluster. + // Update distances between new cluster and each of the old clusters, and loop until threshold reached. + var merged = mergeClosest(clusters, index, dists, mins, opts); + while (merged) { + merged = mergeClosest(clusters, index, dists, mins, opts); + } + var retClusters; + + // Dendrogram mode builds the hierarchy and adds intermediary nodes + edges + // in addition to returning the clusters. + if (opts.mode === 'dendrogram') { + retClusters = buildClustersFromTree(clusters[0], opts.dendrogramDepth, cy); + if (opts.addDendrogram) buildDendrogram(clusters[0], cy); + } else { + // Regular mode simply returns the clusters + + retClusters = new Array(clusters.length); + clusters.forEach(function (cluster, i) { + // Clean up meta data used for clustering + cluster.key = cluster.index = null; + retClusters[i] = cy.collection(cluster.value); + }); + } + return retClusters; + }; + var hierarchicalClustering$1 = { + hierarchicalClustering: hierarchicalClustering, + hca: hierarchicalClustering + }; + + // Implemented by Zoe Xi @zoexi for GSOC 2016 + var defaults$9 = defaults$g({ + distance: 'euclidean', + // distance metric to compare attributes between two nodes + preference: 'median', + // suitability of a data point to serve as an exemplar + damping: 0.8, + // damping factor between [0.5, 1) + maxIterations: 1000, + // max number of iterations to run + minIterations: 100, + // min number of iterations to run in order for clustering to stop + attributes: [// functions to quantify the similarity between any two points + // e.g. node => node.data('weight') + ] + }); + var setOptions = function setOptions(options) { + var dmp = options.damping; + var pref = options.preference; + if (!(0.5 <= dmp && dmp < 1)) { + error("Damping must range on [0.5, 1). Got: ".concat(dmp)); + } + var validPrefs = ['median', 'mean', 'min', 'max']; + if (!(validPrefs.some(function (v) { + return v === pref; + }) || number$1(pref))) { + error("Preference must be one of [".concat(validPrefs.map(function (p) { + return "'".concat(p, "'"); + }).join(', '), "] or a number. Got: ").concat(pref)); + } + return defaults$9(options); + }; + + var getSimilarity = function getSimilarity(type, n1, n2, attributes) { + var attr = function attr(n, i) { + return attributes[i](n); + }; + + // nb negative because similarity should have an inverse relationship to distance + return -clusteringDistance(type, attributes.length, function (i) { + return attr(n1, i); + }, function (i) { + return attr(n2, i); + }, n1, n2); + }; + var getPreference = function getPreference(S, preference) { + // larger preference = greater # of clusters + var p = null; + if (preference === 'median') { + p = median(S); + } else if (preference === 'mean') { + p = mean(S); + } else if (preference === 'min') { + p = min(S); + } else if (preference === 'max') { + p = max(S); + } else { + // Custom preference number, as set by user + p = preference; + } + return p; + }; + var findExemplars = function findExemplars(n, R, A) { + var indices = []; + for (var i = 0; i < n; i++) { + if (R[i * n + i] + A[i * n + i] > 0) { + indices.push(i); + } + } + return indices; + }; + var assignClusters = function assignClusters(n, S, exemplars) { + var clusters = []; + for (var i = 0; i < n; i++) { + var index = -1; + var max = -Infinity; + for (var ei = 0; ei < exemplars.length; ei++) { + var e = exemplars[ei]; + if (S[i * n + e] > max) { + index = e; + max = S[i * n + e]; + } + } + if (index > 0) { + clusters.push(index); + } + } + for (var _ei = 0; _ei < exemplars.length; _ei++) { + clusters[exemplars[_ei]] = exemplars[_ei]; + } + return clusters; + }; + var assign = function assign(n, S, exemplars) { + var clusters = assignClusters(n, S, exemplars); + for (var ei = 0; ei < exemplars.length; ei++) { + var ii = []; + for (var c = 0; c < clusters.length; c++) { + if (clusters[c] === exemplars[ei]) { + ii.push(c); + } + } + var maxI = -1; + var maxSum = -Infinity; + for (var i = 0; i < ii.length; i++) { + var sum = 0; + for (var j = 0; j < ii.length; j++) { + sum += S[ii[j] * n + ii[i]]; + } + if (sum > maxSum) { + maxI = i; + maxSum = sum; + } + } + exemplars[ei] = ii[maxI]; + } + clusters = assignClusters(n, S, exemplars); + return clusters; + }; + var affinityPropagation = function affinityPropagation(options) { + var cy = this.cy(); + var nodes = this.nodes(); + var opts = setOptions(options); + + // Map each node to its position in node array + var id2position = {}; + for (var i = 0; i < nodes.length; i++) { + id2position[nodes[i].id()] = i; + } + + // Begin affinity propagation algorithm + + var n; // number of data points + var n2; // size of matrices + var S; // similarity matrix (1D array) + var p; // preference/suitability of a data point to serve as an exemplar + var R; // responsibility matrix (1D array) + var A; // availability matrix (1D array) + + n = nodes.length; + n2 = n * n; + + // Initialize and build S similarity matrix + S = new Array(n2); + for (var _i = 0; _i < n2; _i++) { + S[_i] = -Infinity; // for cases where two data points shouldn't be linked together + } + + for (var _i2 = 0; _i2 < n; _i2++) { + for (var j = 0; j < n; j++) { + if (_i2 !== j) { + S[_i2 * n + j] = getSimilarity(opts.distance, nodes[_i2], nodes[j], opts.attributes); + } + } + } + + // Place preferences on the diagonal of S + p = getPreference(S, opts.preference); + for (var _i3 = 0; _i3 < n; _i3++) { + S[_i3 * n + _i3] = p; + } + + // Initialize R responsibility matrix + R = new Array(n2); + for (var _i4 = 0; _i4 < n2; _i4++) { + R[_i4] = 0.0; + } + + // Initialize A availability matrix + A = new Array(n2); + for (var _i5 = 0; _i5 < n2; _i5++) { + A[_i5] = 0.0; + } + var old = new Array(n); + var Rp = new Array(n); + var se = new Array(n); + for (var _i6 = 0; _i6 < n; _i6++) { + old[_i6] = 0.0; + Rp[_i6] = 0.0; + se[_i6] = 0; + } + var e = new Array(n * opts.minIterations); + for (var _i7 = 0; _i7 < e.length; _i7++) { + e[_i7] = 0; + } + var iter; + for (iter = 0; iter < opts.maxIterations; iter++) { + // main algorithmic loop + + // Update R responsibility matrix + for (var _i8 = 0; _i8 < n; _i8++) { + var max = -Infinity, + max2 = -Infinity, + maxI = -1, + AS = 0.0; + for (var _j = 0; _j < n; _j++) { + old[_j] = R[_i8 * n + _j]; + AS = A[_i8 * n + _j] + S[_i8 * n + _j]; + if (AS >= max) { + max2 = max; + max = AS; + maxI = _j; + } else if (AS > max2) { + max2 = AS; + } + } + for (var _j2 = 0; _j2 < n; _j2++) { + R[_i8 * n + _j2] = (1 - opts.damping) * (S[_i8 * n + _j2] - max) + opts.damping * old[_j2]; + } + R[_i8 * n + maxI] = (1 - opts.damping) * (S[_i8 * n + maxI] - max2) + opts.damping * old[maxI]; + } + + // Update A availability matrix + for (var _i9 = 0; _i9 < n; _i9++) { + var sum = 0; + for (var _j3 = 0; _j3 < n; _j3++) { + old[_j3] = A[_j3 * n + _i9]; + Rp[_j3] = Math.max(0, R[_j3 * n + _i9]); + sum += Rp[_j3]; + } + sum -= Rp[_i9]; + Rp[_i9] = R[_i9 * n + _i9]; + sum += Rp[_i9]; + for (var _j4 = 0; _j4 < n; _j4++) { + A[_j4 * n + _i9] = (1 - opts.damping) * Math.min(0, sum - Rp[_j4]) + opts.damping * old[_j4]; + } + A[_i9 * n + _i9] = (1 - opts.damping) * (sum - Rp[_i9]) + opts.damping * old[_i9]; + } + + // Check for convergence + var K = 0; + for (var _i10 = 0; _i10 < n; _i10++) { + var E = A[_i10 * n + _i10] + R[_i10 * n + _i10] > 0 ? 1 : 0; + e[iter % opts.minIterations * n + _i10] = E; + K += E; + } + if (K > 0 && (iter >= opts.minIterations - 1 || iter == opts.maxIterations - 1)) { + var _sum = 0; + for (var _i11 = 0; _i11 < n; _i11++) { + se[_i11] = 0; + for (var _j5 = 0; _j5 < opts.minIterations; _j5++) { + se[_i11] += e[_j5 * n + _i11]; + } + if (se[_i11] === 0 || se[_i11] === opts.minIterations) { + _sum++; + } + } + if (_sum === n) { + // then we have convergence + break; + } + } + } + + // Identify exemplars (cluster centers) + var exemplarsIndices = findExemplars(n, R, A); + + // Assign nodes to clusters + var clusterIndices = assign(n, S, exemplarsIndices); + var clusters = {}; + for (var c = 0; c < exemplarsIndices.length; c++) { + clusters[exemplarsIndices[c]] = []; + } + for (var _i12 = 0; _i12 < nodes.length; _i12++) { + var pos = id2position[nodes[_i12].id()]; + var clusterIndex = clusterIndices[pos]; + if (clusterIndex != null) { + // the node may have not been assigned a cluster if no valid attributes were specified + clusters[clusterIndex].push(nodes[_i12]); + } + } + var retClusters = new Array(exemplarsIndices.length); + for (var _c = 0; _c < exemplarsIndices.length; _c++) { + retClusters[_c] = cy.collection(clusters[exemplarsIndices[_c]]); + } + return retClusters; + }; + var affinityPropagation$1 = { + affinityPropagation: affinityPropagation, + ap: affinityPropagation + }; + + var hierholzerDefaults = defaults$g({ + root: undefined, + directed: false + }); + var elesfn$k = { + hierholzer: function hierholzer(options) { + if (!plainObject(options)) { + var args = arguments; + options = { + root: args[0], + directed: args[1] + }; + } + var _hierholzerDefaults = hierholzerDefaults(options), + root = _hierholzerDefaults.root, + directed = _hierholzerDefaults.directed; + var eles = this; + var dflag = false; + var oddIn; + var oddOut; + var startVertex; + if (root) startVertex = string(root) ? this.filter(root)[0].id() : root[0].id(); + var nodes = {}; + var edges = {}; + if (directed) { + eles.forEach(function (ele) { + var id = ele.id(); + if (ele.isNode()) { + var ind = ele.indegree(true); + var outd = ele.outdegree(true); + var d1 = ind - outd; + var d2 = outd - ind; + if (d1 == 1) { + if (oddIn) dflag = true;else oddIn = id; + } else if (d2 == 1) { + if (oddOut) dflag = true;else oddOut = id; + } else if (d2 > 1 || d1 > 1) { + dflag = true; + } + nodes[id] = []; + ele.outgoers().forEach(function (e) { + if (e.isEdge()) nodes[id].push(e.id()); + }); + } else { + edges[id] = [undefined, ele.target().id()]; + } + }); + } else { + eles.forEach(function (ele) { + var id = ele.id(); + if (ele.isNode()) { + var d = ele.degree(true); + if (d % 2) { + if (!oddIn) oddIn = id;else if (!oddOut) oddOut = id;else dflag = true; + } + nodes[id] = []; + ele.connectedEdges().forEach(function (e) { + return nodes[id].push(e.id()); + }); + } else { + edges[id] = [ele.source().id(), ele.target().id()]; + } + }); + } + var result = { + found: false, + trail: undefined + }; + if (dflag) return result;else if (oddOut && oddIn) { + if (directed) { + if (startVertex && oddOut != startVertex) { + return result; + } + startVertex = oddOut; + } else { + if (startVertex && oddOut != startVertex && oddIn != startVertex) { + return result; + } else if (!startVertex) { + startVertex = oddOut; + } + } + } else { + if (!startVertex) startVertex = eles[0].id(); + } + var walk = function walk(v) { + var currentNode = v; + var subtour = [v]; + var adj, adjTail, adjHead; + while (nodes[currentNode].length) { + adj = nodes[currentNode].shift(); + adjTail = edges[adj][0]; + adjHead = edges[adj][1]; + if (currentNode != adjHead) { + nodes[adjHead] = nodes[adjHead].filter(function (e) { + return e != adj; + }); + currentNode = adjHead; + } else if (!directed && currentNode != adjTail) { + nodes[adjTail] = nodes[adjTail].filter(function (e) { + return e != adj; + }); + currentNode = adjTail; + } + subtour.unshift(adj); + subtour.unshift(currentNode); + } + return subtour; + }; + var trail = []; + var subtour = []; + subtour = walk(startVertex); + while (subtour.length != 1) { + if (nodes[subtour[0]].length == 0) { + trail.unshift(eles.getElementById(subtour.shift())); + trail.unshift(eles.getElementById(subtour.shift())); + } else { + subtour = walk(subtour.shift()).concat(subtour); + } + } + trail.unshift(eles.getElementById(subtour.shift())); // final node + + for (var d in nodes) { + if (nodes[d].length) { + return result; + } + } + result.found = true; + result.trail = this.spawn(trail, true); + return result; + } + }; + + var hopcroftTarjanBiconnected = function hopcroftTarjanBiconnected() { + var eles = this; + var nodes = {}; + var id = 0; + var edgeCount = 0; + var components = []; + var stack = []; + var visitedEdges = {}; + var buildComponent = function buildComponent(x, y) { + var i = stack.length - 1; + var cutset = []; + var component = eles.spawn(); + while (stack[i].x != x || stack[i].y != y) { + cutset.push(stack.pop().edge); + i--; + } + cutset.push(stack.pop().edge); + cutset.forEach(function (edge) { + var connectedNodes = edge.connectedNodes().intersection(eles); + component.merge(edge); + connectedNodes.forEach(function (node) { + var nodeId = node.id(); + var connectedEdges = node.connectedEdges().intersection(eles); + component.merge(node); + if (!nodes[nodeId].cutVertex) { + component.merge(connectedEdges); + } else { + component.merge(connectedEdges.filter(function (edge) { + return edge.isLoop(); + })); + } + }); + }); + components.push(component); + }; + var biconnectedSearch = function biconnectedSearch(root, currentNode, parent) { + if (root === parent) edgeCount += 1; + nodes[currentNode] = { + id: id, + low: id++, + cutVertex: false + }; + var edges = eles.getElementById(currentNode).connectedEdges().intersection(eles); + if (edges.size() === 0) { + components.push(eles.spawn(eles.getElementById(currentNode))); + } else { + var sourceId, targetId, otherNodeId, edgeId; + edges.forEach(function (edge) { + sourceId = edge.source().id(); + targetId = edge.target().id(); + otherNodeId = sourceId === currentNode ? targetId : sourceId; + if (otherNodeId !== parent) { + edgeId = edge.id(); + if (!visitedEdges[edgeId]) { + visitedEdges[edgeId] = true; + stack.push({ + x: currentNode, + y: otherNodeId, + edge: edge + }); + } + if (!(otherNodeId in nodes)) { + biconnectedSearch(root, otherNodeId, currentNode); + nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].low); + if (nodes[currentNode].id <= nodes[otherNodeId].low) { + nodes[currentNode].cutVertex = true; + buildComponent(currentNode, otherNodeId); + } + } else { + nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].id); + } + } + }); + } + }; + eles.forEach(function (ele) { + if (ele.isNode()) { + var nodeId = ele.id(); + if (!(nodeId in nodes)) { + edgeCount = 0; + biconnectedSearch(nodeId, nodeId); + nodes[nodeId].cutVertex = edgeCount > 1; + } + } + }); + var cutVertices = Object.keys(nodes).filter(function (id) { + return nodes[id].cutVertex; + }).map(function (id) { + return eles.getElementById(id); + }); + return { + cut: eles.spawn(cutVertices), + components: components + }; + }; + var hopcroftTarjanBiconnected$1 = { + hopcroftTarjanBiconnected: hopcroftTarjanBiconnected, + htbc: hopcroftTarjanBiconnected, + htb: hopcroftTarjanBiconnected, + hopcroftTarjanBiconnectedComponents: hopcroftTarjanBiconnected + }; + + var tarjanStronglyConnected = function tarjanStronglyConnected() { + var eles = this; + var nodes = {}; + var index = 0; + var components = []; + var stack = []; + var cut = eles.spawn(eles); + var stronglyConnectedSearch = function stronglyConnectedSearch(sourceNodeId) { + stack.push(sourceNodeId); + nodes[sourceNodeId] = { + index: index, + low: index++, + explored: false + }; + var connectedEdges = eles.getElementById(sourceNodeId).connectedEdges().intersection(eles); + connectedEdges.forEach(function (edge) { + var targetNodeId = edge.target().id(); + if (targetNodeId !== sourceNodeId) { + if (!(targetNodeId in nodes)) { + stronglyConnectedSearch(targetNodeId); + } + if (!nodes[targetNodeId].explored) { + nodes[sourceNodeId].low = Math.min(nodes[sourceNodeId].low, nodes[targetNodeId].low); + } + } + }); + if (nodes[sourceNodeId].index === nodes[sourceNodeId].low) { + var componentNodes = eles.spawn(); + for (;;) { + var nodeId = stack.pop(); + componentNodes.merge(eles.getElementById(nodeId)); + nodes[nodeId].low = nodes[sourceNodeId].index; + nodes[nodeId].explored = true; + if (nodeId === sourceNodeId) { + break; + } + } + var componentEdges = componentNodes.edgesWith(componentNodes); + var component = componentNodes.merge(componentEdges); + components.push(component); + cut = cut.difference(component); + } + }; + eles.forEach(function (ele) { + if (ele.isNode()) { + var nodeId = ele.id(); + if (!(nodeId in nodes)) { + stronglyConnectedSearch(nodeId); + } + } + }); + return { + cut: cut, + components: components + }; + }; + var tarjanStronglyConnected$1 = { + tarjanStronglyConnected: tarjanStronglyConnected, + tsc: tarjanStronglyConnected, + tscc: tarjanStronglyConnected, + tarjanStronglyConnectedComponents: tarjanStronglyConnected + }; + + var elesfn$j = {}; + [elesfn$v, elesfn$u, elesfn$t, elesfn$s, elesfn$r, elesfn$q, elesfn$p, elesfn$o, elesfn$n, elesfn$m, elesfn$l, markovClustering$1, kClustering, hierarchicalClustering$1, affinityPropagation$1, elesfn$k, hopcroftTarjanBiconnected$1, tarjanStronglyConnected$1].forEach(function (props) { + extend(elesfn$j, props); + }); + + /*! + Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable + Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com) + Licensed under The MIT License (http://opensource.org/licenses/MIT) + */ + + /* promise states [Promises/A+ 2.1] */ + var STATE_PENDING = 0; /* [Promises/A+ 2.1.1] */ + var STATE_FULFILLED = 1; /* [Promises/A+ 2.1.2] */ + var STATE_REJECTED = 2; /* [Promises/A+ 2.1.3] */ + + /* promise object constructor */ + var api = function api(executor) { + /* optionally support non-constructor/plain-function call */ + if (!(this instanceof api)) return new api(executor); + + /* initialize object */ + this.id = 'Thenable/1.0.7'; + this.state = STATE_PENDING; /* initial state */ + this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */ + this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */ + this.onFulfilled = []; /* initial handlers */ + this.onRejected = []; /* initial handlers */ + + /* provide optional information-hiding proxy */ + this.proxy = { + then: this.then.bind(this) + }; + + /* support optional executor function */ + if (typeof executor === 'function') executor.call(this, this.fulfill.bind(this), this.reject.bind(this)); + }; + + /* promise API methods */ + api.prototype = { + /* promise resolving methods */ + fulfill: function fulfill(value) { + return deliver(this, STATE_FULFILLED, 'fulfillValue', value); + }, + reject: function reject(value) { + return deliver(this, STATE_REJECTED, 'rejectReason', value); + }, + /* "The then Method" [Promises/A+ 1.1, 1.2, 2.2] */ + then: function then(onFulfilled, onRejected) { + var curr = this; + var next = new api(); /* [Promises/A+ 2.2.7] */ + curr.onFulfilled.push(resolver(onFulfilled, next, 'fulfill')); /* [Promises/A+ 2.2.2/2.2.6] */ + curr.onRejected.push(resolver(onRejected, next, 'reject')); /* [Promises/A+ 2.2.3/2.2.6] */ + execute(curr); + return next.proxy; /* [Promises/A+ 2.2.7, 3.3] */ + } + }; + + /* deliver an action */ + var deliver = function deliver(curr, state, name, value) { + if (curr.state === STATE_PENDING) { + curr.state = state; /* [Promises/A+ 2.1.2.1, 2.1.3.1] */ + curr[name] = value; /* [Promises/A+ 2.1.2.2, 2.1.3.2] */ + execute(curr); + } + return curr; + }; + + /* execute all handlers */ + var execute = function execute(curr) { + if (curr.state === STATE_FULFILLED) execute_handlers(curr, 'onFulfilled', curr.fulfillValue);else if (curr.state === STATE_REJECTED) execute_handlers(curr, 'onRejected', curr.rejectReason); + }; + + /* execute particular set of handlers */ + var execute_handlers = function execute_handlers(curr, name, value) { + /* global setImmediate: true */ + /* global setTimeout: true */ + + /* short-circuit processing */ + if (curr[name].length === 0) return; + + /* iterate over all handlers, exactly once */ + var handlers = curr[name]; + curr[name] = []; /* [Promises/A+ 2.2.2.3, 2.2.3.3] */ + var func = function func() { + for (var i = 0; i < handlers.length; i++) { + handlers[i](value); + } /* [Promises/A+ 2.2.5] */ + }; + + /* execute procedure asynchronously */ /* [Promises/A+ 2.2.4, 3.1] */ + if (typeof setImmediate === 'function') setImmediate(func);else setTimeout(func, 0); + }; + + /* generate a resolver function */ + var resolver = function resolver(cb, next, method) { + return function (value) { + if (typeof cb !== 'function') /* [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4] */ + next[method].call(next, value); /* [Promises/A+ 2.2.7.3, 2.2.7.4] */else { + var result; + try { + result = cb(value); + } /* [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2] */ catch (e) { + next.reject(e); /* [Promises/A+ 2.2.7.2] */ + return; + } + resolve(next, result); /* [Promises/A+ 2.2.7.1] */ + } + }; + }; + + /* "Promise Resolution Procedure" */ /* [Promises/A+ 2.3] */ + var resolve = function resolve(promise, x) { + /* sanity check arguments */ /* [Promises/A+ 2.3.1] */ + if (promise === x || promise.proxy === x) { + promise.reject(new TypeError('cannot resolve promise with itself')); + return; + } + + /* surgically check for a "then" method + (mainly to just call the "getter" of "then" only once) */ + var then; + if (_typeof(x) === 'object' && x !== null || typeof x === 'function') { + try { + then = x.then; + } /* [Promises/A+ 2.3.3.1, 3.5] */ catch (e) { + promise.reject(e); /* [Promises/A+ 2.3.3.2] */ + return; + } + } + + /* handle own Thenables [Promises/A+ 2.3.2] + and similar "thenables" [Promises/A+ 2.3.3] */ + if (typeof then === 'function') { + var resolved = false; + try { + /* call retrieved "then" method */ /* [Promises/A+ 2.3.3.3] */ + then.call(x, /* resolvePromise */ /* [Promises/A+ 2.3.3.3.1] */ + function (y) { + if (resolved) return; + resolved = true; /* [Promises/A+ 2.3.3.3.3] */ + if (y === x) /* [Promises/A+ 3.6] */ + promise.reject(new TypeError('circular thenable chain'));else resolve(promise, y); + }, /* rejectPromise */ /* [Promises/A+ 2.3.3.3.2] */ + function (r) { + if (resolved) return; + resolved = true; /* [Promises/A+ 2.3.3.3.3] */ + promise.reject(r); + }); + } catch (e) { + if (!resolved) /* [Promises/A+ 2.3.3.3.3] */ + promise.reject(e); /* [Promises/A+ 2.3.3.3.4] */ + } + + return; + } + + /* handle other values */ + promise.fulfill(x); /* [Promises/A+ 2.3.4, 2.3.3.4] */ + }; + + // so we always have Promise.all() + api.all = function (ps) { + return new api(function (resolveAll, rejectAll) { + var vals = new Array(ps.length); + var doneCount = 0; + var fulfill = function fulfill(i, val) { + vals[i] = val; + doneCount++; + if (doneCount === ps.length) { + resolveAll(vals); + } + }; + for (var i = 0; i < ps.length; i++) { + (function (i) { + var p = ps[i]; + var isPromise = p != null && p.then != null; + if (isPromise) { + p.then(function (val) { + fulfill(i, val); + }, function (err) { + rejectAll(err); + }); + } else { + var val = p; + fulfill(i, val); + } + })(i); + } + }); + }; + api.resolve = function (val) { + return new api(function (resolve, reject) { + resolve(val); + }); + }; + api.reject = function (val) { + return new api(function (resolve, reject) { + reject(val); + }); + }; + var Promise$1 = typeof Promise !== 'undefined' ? Promise : api; // eslint-disable-line no-undef + + var Animation = function Animation(target, opts, opts2) { + var isCore = core(target); + var isEle = !isCore; + var _p = this._private = extend({ + duration: 1000 + }, opts, opts2); + _p.target = target; + _p.style = _p.style || _p.css; + _p.started = false; + _p.playing = false; + _p.hooked = false; + _p.applying = false; + _p.progress = 0; + _p.completes = []; + _p.frames = []; + if (_p.complete && fn$6(_p.complete)) { + _p.completes.push(_p.complete); + } + if (isEle) { + var pos = target.position(); + _p.startPosition = _p.startPosition || { + x: pos.x, + y: pos.y + }; + _p.startStyle = _p.startStyle || target.cy().style().getAnimationStartStyle(target, _p.style); + } + if (isCore) { + var pan = target.pan(); + _p.startPan = { + x: pan.x, + y: pan.y + }; + _p.startZoom = target.zoom(); + } + + // for future timeline/animations impl + this.length = 1; + this[0] = this; + }; + var anifn = Animation.prototype; + extend(anifn, { + instanceString: function instanceString() { + return 'animation'; + }, + hook: function hook() { + var _p = this._private; + if (!_p.hooked) { + // add to target's animation queue + var q; + var tAni = _p.target._private.animation; + if (_p.queue) { + q = tAni.queue; + } else { + q = tAni.current; + } + q.push(this); + + // add to the animation loop pool + if (elementOrCollection(_p.target)) { + _p.target.cy().addToAnimationPool(_p.target); + } + _p.hooked = true; + } + return this; + }, + play: function play() { + var _p = this._private; + + // autorewind + if (_p.progress === 1) { + _p.progress = 0; + } + _p.playing = true; + _p.started = false; // needs to be started by animation loop + _p.stopped = false; + this.hook(); + + // the animation loop will start the animation... + + return this; + }, + playing: function playing() { + return this._private.playing; + }, + apply: function apply() { + var _p = this._private; + _p.applying = true; + _p.started = false; // needs to be started by animation loop + _p.stopped = false; + this.hook(); + + // the animation loop will apply the animation at this progress + + return this; + }, + applying: function applying() { + return this._private.applying; + }, + pause: function pause() { + var _p = this._private; + _p.playing = false; + _p.started = false; + return this; + }, + stop: function stop() { + var _p = this._private; + _p.playing = false; + _p.started = false; + _p.stopped = true; // to be removed from animation queues + + return this; + }, + rewind: function rewind() { + return this.progress(0); + }, + fastforward: function fastforward() { + return this.progress(1); + }, + time: function time(t) { + var _p = this._private; + if (t === undefined) { + return _p.progress * _p.duration; + } else { + return this.progress(t / _p.duration); + } + }, + progress: function progress(p) { + var _p = this._private; + var wasPlaying = _p.playing; + if (p === undefined) { + return _p.progress; + } else { + if (wasPlaying) { + this.pause(); + } + _p.progress = p; + _p.started = false; + if (wasPlaying) { + this.play(); + } + } + return this; + }, + completed: function completed() { + return this._private.progress === 1; + }, + reverse: function reverse() { + var _p = this._private; + var wasPlaying = _p.playing; + if (wasPlaying) { + this.pause(); + } + _p.progress = 1 - _p.progress; + _p.started = false; + var swap = function swap(a, b) { + var _pa = _p[a]; + if (_pa == null) { + return; + } + _p[a] = _p[b]; + _p[b] = _pa; + }; + swap('zoom', 'startZoom'); + swap('pan', 'startPan'); + swap('position', 'startPosition'); + + // swap styles + if (_p.style) { + for (var i = 0; i < _p.style.length; i++) { + var prop = _p.style[i]; + var name = prop.name; + var startStyleProp = _p.startStyle[name]; + _p.startStyle[name] = prop; + _p.style[i] = startStyleProp; + } + } + if (wasPlaying) { + this.play(); + } + return this; + }, + promise: function promise(type) { + var _p = this._private; + var arr; + switch (type) { + case 'frame': + arr = _p.frames; + break; + default: + case 'complete': + case 'completed': + arr = _p.completes; + } + return new Promise$1(function (resolve, reject) { + arr.push(function () { + resolve(); + }); + }); + } + }); + anifn.complete = anifn.completed; + anifn.run = anifn.play; + anifn.running = anifn.playing; + + var define$3 = { + animated: function animated() { + return function animatedImpl() { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return false; + } + var ele = all[0]; + if (ele) { + return ele._private.animation.current.length > 0; + } + }; + }, + // animated + + clearQueue: function clearQueue() { + return function clearQueueImpl() { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + for (var i = 0; i < all.length; i++) { + var ele = all[i]; + ele._private.animation.queue = []; + } + return this; + }; + }, + // clearQueue + + delay: function delay() { + return function delayImpl(time, complete) { + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + return this.animate({ + delay: time, + duration: time, + complete: complete + }); + }; + }, + // delay + + delayAnimation: function delayAnimation() { + return function delayAnimationImpl(time, complete) { + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + return this.animation({ + delay: time, + duration: time, + complete: complete + }); + }; + }, + // delay + + animation: function animation() { + return function animationImpl(properties, params) { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + var isCore = !selfIsArrayLike; + var isEles = !isCore; + if (!cy.styleEnabled()) { + return this; + } + var style = cy.style(); + properties = extend({}, properties, params); + var propertiesEmpty = Object.keys(properties).length === 0; + if (propertiesEmpty) { + return new Animation(all[0], properties); // nothing to animate + } + + if (properties.duration === undefined) { + properties.duration = 400; + } + switch (properties.duration) { + case 'slow': + properties.duration = 600; + break; + case 'fast': + properties.duration = 200; + break; + } + if (isEles) { + properties.style = style.getPropsList(properties.style || properties.css); + properties.css = undefined; + } + if (isEles && properties.renderedPosition != null) { + var rpos = properties.renderedPosition; + var pan = cy.pan(); + var zoom = cy.zoom(); + properties.position = renderedToModelPosition(rpos, zoom, pan); + } + + // override pan w/ panBy if set + if (isCore && properties.panBy != null) { + var panBy = properties.panBy; + var cyPan = cy.pan(); + properties.pan = { + x: cyPan.x + panBy.x, + y: cyPan.y + panBy.y + }; + } + + // override pan w/ center if set + var center = properties.center || properties.centre; + if (isCore && center != null) { + var centerPan = cy.getCenterPan(center.eles, properties.zoom); + if (centerPan != null) { + properties.pan = centerPan; + } + } + + // override pan & zoom w/ fit if set + if (isCore && properties.fit != null) { + var fit = properties.fit; + var fitVp = cy.getFitViewport(fit.eles || fit.boundingBox, fit.padding); + if (fitVp != null) { + properties.pan = fitVp.pan; + properties.zoom = fitVp.zoom; + } + } + + // override zoom (& potentially pan) w/ zoom obj if set + if (isCore && plainObject(properties.zoom)) { + var vp = cy.getZoomedViewport(properties.zoom); + if (vp != null) { + if (vp.zoomed) { + properties.zoom = vp.zoom; + } + if (vp.panned) { + properties.pan = vp.pan; + } + } else { + properties.zoom = null; // an inavalid zoom (e.g. no delta) gets automatically destroyed + } + } + + return new Animation(all[0], properties); + }; + }, + // animate + + animate: function animate() { + return function animateImpl(properties, params) { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + if (params) { + properties = extend({}, properties, params); + } + + // manually hook and run the animation + for (var i = 0; i < all.length; i++) { + var ele = all[i]; + var queue = ele.animated() && (properties.queue === undefined || properties.queue); + var ani = ele.animation(properties, queue ? { + queue: true + } : undefined); + ani.play(); + } + return this; // chaining + }; + }, + + // animate + + stop: function stop() { + return function stopImpl(clearQueue, jumpToEnd) { + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var cy = this._private.cy || this; + if (!cy.styleEnabled()) { + return this; + } + for (var i = 0; i < all.length; i++) { + var ele = all[i]; + var _p = ele._private; + var anis = _p.animation.current; + for (var j = 0; j < anis.length; j++) { + var ani = anis[j]; + var ani_p = ani._private; + if (jumpToEnd) { + // next iteration of the animation loop, the animation + // will go straight to the end and be removed + ani_p.duration = 0; + } + } + + // clear the queue of future animations + if (clearQueue) { + _p.animation.queue = []; + } + if (!jumpToEnd) { + _p.animation.current = []; + } + } + + // we have to notify (the animation loop doesn't do it for us on `stop`) + cy.notify('draw'); + return this; + }; + } // stop + }; // define + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + var isArray_1 = isArray; + + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + + /** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ + function isKey(value, object) { + if (isArray_1(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol_1(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); + } + + var _isKey = isKey; + + /** `Object#toString` result references. */ + var asyncTag = '[object AsyncFunction]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + proxyTag = '[object Proxy]'; + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject_1(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = _baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + var isFunction_1 = isFunction; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = _root['__core-js_shared__']; + + var _coreJsData = coreJsData; + + /** Used to detect methods masquerading as native. */ + var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; + }()); + + /** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ + function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); + } + + var _isMasked = isMasked; + + /** Used for built-in method references. */ + var funcProto$1 = Function.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString$1 = funcProto$1.toString; + + /** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to convert. + * @returns {string} Returns the source code. + */ + function toSource(func) { + if (func != null) { + try { + return funcToString$1.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; + } + + var _toSource = toSource; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ + var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + + /** Used to detect host constructors (Safari). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; + + /** Used for built-in method references. */ + var funcProto = Function.prototype, + objectProto$3 = Object.prototype; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty$3 = objectProto$3.hasOwnProperty; + + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty$3).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' + ); + + /** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ + function baseIsNative(value) { + if (!isObject_1(value) || _isMasked(value)) { + return false; + } + var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor; + return pattern.test(_toSource(value)); + } + + var _baseIsNative = baseIsNative; + + /** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function getValue$1(object, key) { + return object == null ? undefined : object[key]; + } + + var _getValue = getValue$1; + + /** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ + function getNative(object, key) { + var value = _getValue(object, key); + return _baseIsNative(value) ? value : undefined; + } + + var _getNative = getNative; + + /* Built-in method references that are verified to be native. */ + var nativeCreate = _getNative(Object, 'create'); + + var _nativeCreate = nativeCreate; + + /** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ + function hashClear() { + this.__data__ = _nativeCreate ? _nativeCreate(null) : {}; + this.size = 0; + } + + var _hashClear = hashClear; + + /** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function hashDelete(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + var _hashDelete = hashDelete; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED$1 = '__lodash_hash_undefined__'; + + /** Used for built-in method references. */ + var objectProto$2 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$2 = objectProto$2.hasOwnProperty; + + /** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function hashGet(key) { + var data = this.__data__; + if (_nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED$1 ? undefined : result; + } + return hasOwnProperty$2.call(data, key) ? data[key] : undefined; + } + + var _hashGet = hashGet; + + /** Used for built-in method references. */ + var objectProto$1 = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto$1.hasOwnProperty; + + /** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function hashHas(key) { + var data = this.__data__; + return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$1.call(data, key); + } + + var _hashHas = hashHas; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ + function hashSet(key, value) { + var data = this.__data__; + this.size += this.has(key) ? 0 : 1; + data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; + } + + var _hashSet = hashSet; + + /** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function Hash(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `Hash`. + Hash.prototype.clear = _hashClear; + Hash.prototype['delete'] = _hashDelete; + Hash.prototype.get = _hashGet; + Hash.prototype.has = _hashHas; + Hash.prototype.set = _hashSet; + + var _Hash = Hash; + + /** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ + function listCacheClear() { + this.__data__ = []; + this.size = 0; + } + + var _listCacheClear = listCacheClear; + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + var eq_1 = eq; + + /** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq_1(array[length][0], key)) { + return length; + } + } + return -1; + } + + var _assocIndexOf = assocIndexOf; + + /** Used for built-in method references. */ + var arrayProto = Array.prototype; + + /** Built-in value references. */ + var splice = arrayProto.splice; + + /** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function listCacheDelete(key) { + var data = this.__data__, + index = _assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + --this.size; + return true; + } + + var _listCacheDelete = listCacheDelete; + + /** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function listCacheGet(key) { + var data = this.__data__, + index = _assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; + } + + var _listCacheGet = listCacheGet; + + /** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function listCacheHas(key) { + return _assocIndexOf(this.__data__, key) > -1; + } + + var _listCacheHas = listCacheHas; + + /** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ + function listCacheSet(key, value) { + var data = this.__data__, + index = _assocIndexOf(data, key); + + if (index < 0) { + ++this.size; + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; + } + + var _listCacheSet = listCacheSet; + + /** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function ListCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `ListCache`. + ListCache.prototype.clear = _listCacheClear; + ListCache.prototype['delete'] = _listCacheDelete; + ListCache.prototype.get = _listCacheGet; + ListCache.prototype.has = _listCacheHas; + ListCache.prototype.set = _listCacheSet; + + var _ListCache = ListCache; + + /* Built-in method references that are verified to be native. */ + var Map$1 = _getNative(_root, 'Map'); + + var _Map = Map$1; + + /** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ + function mapCacheClear() { + this.size = 0; + this.__data__ = { + 'hash': new _Hash, + 'map': new (_Map || _ListCache), + 'string': new _Hash + }; + } + + var _mapCacheClear = mapCacheClear; + + /** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ + function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); + } + + var _isKeyable = isKeyable; + + /** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ + function getMapData(map, key) { + var data = map.__data__; + return _isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; + } + + var _getMapData = getMapData; + + /** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ + function mapCacheDelete(key) { + var result = _getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + var _mapCacheDelete = mapCacheDelete; + + /** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ + function mapCacheGet(key) { + return _getMapData(this, key).get(key); + } + + var _mapCacheGet = mapCacheGet; + + /** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapCacheHas(key) { + return _getMapData(this, key).has(key); + } + + var _mapCacheHas = mapCacheHas; + + /** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ + function mapCacheSet(key, value) { + var data = _getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + return this; + } + + var _mapCacheSet = mapCacheSet; + + /** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ + function MapCache(entries) { + var index = -1, + length = entries == null ? 0 : entries.length; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } + } + + // Add methods to `MapCache`. + MapCache.prototype.clear = _mapCacheClear; + MapCache.prototype['delete'] = _mapCacheDelete; + MapCache.prototype.get = _mapCacheGet; + MapCache.prototype.has = _mapCacheHas; + MapCache.prototype.set = _mapCacheSet; + + var _MapCache = MapCache; + + /** Error message constants. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || _MapCache); + return memoized; + } + + // Expose `MapCache`. + memoize.Cache = _MapCache; + + var memoize_1 = memoize; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize_1(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + var _memoizeCapped = memoizeCapped; + + /** Used to match property names within property paths. */ + var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; + }); + + var _stringToPath = stringToPath; + + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } + + var _arrayMap = arrayMap; + + /** Used as references for various `Number` constants. */ + var INFINITY$1 = 1 / 0; + + /** Used to convert symbols to primitives and strings. */ + var symbolProto = _Symbol ? _Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray_1(value)) { + // Recursively convert values (susceptible to call stack limits). + return _arrayMap(value, baseToString) + ''; + } + if (isSymbol_1(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result; + } + + var _baseToString = baseToString; + + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString$1(value) { + return value == null ? '' : _baseToString(value); + } + + var toString_1 = toString$1; + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray_1(value)) { + return value; + } + return _isKey(value, object) ? [value] : _stringToPath(toString_1(value)); + } + + var _castPath = castPath; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; + + /** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ + function toKey(value) { + if (typeof value == 'string' || isSymbol_1(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } + + var _toKey = toKey; + + /** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ + function baseGet(object, path) { + path = _castPath(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[_toKey(path[index++])]; + } + return (index && index == length) ? object : undefined; + } + + var _baseGet = baseGet; + + /** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ + function get(object, path, defaultValue) { + var result = object == null ? undefined : _baseGet(object, path); + return result === undefined ? defaultValue : result; + } + + var get_1 = get; + + var defineProperty = (function() { + try { + var func = _getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + var _defineProperty = defineProperty; + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function baseAssignValue(object, key, value) { + if (key == '__proto__' && _defineProperty) { + _defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + var _baseAssignValue = baseAssignValue; + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq_1(objValue, value)) || + (value === undefined && !(key in object))) { + _baseAssignValue(object, key, value); + } + } + + var _assignValue = assignValue; + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + var _isIndex = isIndex; + + /** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject_1(object)) { + return object; + } + path = _castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = _toKey(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject_1(objValue) + ? objValue + : (_isIndex(path[index + 1]) ? [] : {}); + } + } + _assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + var _baseSet = baseSet; + + /** + * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, + * it's created. Arrays are created for missing index properties while objects + * are created for all other missing properties. Use `_.setWith` to customize + * `path` creation. + * + * **Note:** This method mutates `object`. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @returns {Object} Returns `object`. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 + * + * _.set(object, ['x', '0', 'y', 'z'], 5); + * console.log(object.x[0].y.z); + * // => 5 + */ + function set(object, path, value) { + return object == null ? object : _baseSet(object, path, value); + } + + var set_1 = set; + + /** + * Copies the values of `source` to `array`. + * + * @private + * @param {Array} source The array to copy values from. + * @param {Array} [array=[]] The array to copy values to. + * @returns {Array} Returns `array`. + */ + function copyArray(source, array) { + var index = -1, + length = source.length; + + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } + + var _copyArray = copyArray; + + /** + * Converts `value` to a property path array. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Util + * @param {*} value The value to convert. + * @returns {Array} Returns the new property path array. + * @example + * + * _.toPath('a.b.c'); + * // => ['a', 'b', 'c'] + * + * _.toPath('a[0].b.c'); + * // => ['a', '0', 'b', 'c'] + */ + function toPath(value) { + if (isArray_1(value)) { + return _arrayMap(value, _toKey); + } + return isSymbol_1(value) ? [value] : _copyArray(_stringToPath(toString_1(value))); + } + + var toPath_1 = toPath; + + var define$2 = { + // access data field + data: function data(params) { + var defaults = { + field: 'data', + bindingEvent: 'data', + allowBinding: false, + allowSetting: false, + allowGetting: false, + settingEvent: 'data', + settingTriggersEvent: false, + triggerFnName: 'trigger', + immutableKeys: {}, + // key => true if immutable + updateStyle: false, + beforeGet: function beforeGet(self) {}, + beforeSet: function beforeSet(self, obj) {}, + onSet: function onSet(self) {}, + canSet: function canSet(self) { + return true; + } + }; + params = extend({}, defaults, params); + return function dataImpl(name, value) { + var p = params; + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var single = selfIsArrayLike ? self[0] : self; + + // .data('foo', ...) + if (string(name)) { + // set or get property + var isPathLike = name.indexOf('.') !== -1; // there might be a normal field with a dot + var path = isPathLike && toPath_1(name); + + // .data('foo') + if (p.allowGetting && value === undefined) { + // get + + var ret; + if (single) { + p.beforeGet(single); + + // check if it's path and a field with the same name doesn't exist + if (path && single._private[p.field][name] === undefined) { + ret = get_1(single._private[p.field], path); + } else { + ret = single._private[p.field][name]; + } + } + return ret; + + // .data('foo', 'bar') + } else if (p.allowSetting && value !== undefined) { + // set + var valid = !p.immutableKeys[name]; + if (valid) { + var change = _defineProperty$1({}, name, value); + p.beforeSet(self, change); + for (var i = 0, l = all.length; i < l; i++) { + var ele = all[i]; + if (p.canSet(ele)) { + if (path && single._private[p.field][name] === undefined) { + set_1(ele._private[p.field], path, value); + } else { + ele._private[p.field][name] = value; + } + } + } + + // update mappers if asked + if (p.updateStyle) { + self.updateStyle(); + } + + // call onSet callback + p.onSet(self); + if (p.settingTriggersEvent) { + self[p.triggerFnName](p.settingEvent); + } + } + } + + // .data({ 'foo': 'bar' }) + } else if (p.allowSetting && plainObject(name)) { + // extend + var obj = name; + var k, v; + var keys = Object.keys(obj); + p.beforeSet(self, obj); + for (var _i = 0; _i < keys.length; _i++) { + k = keys[_i]; + v = obj[k]; + var _valid = !p.immutableKeys[k]; + if (_valid) { + for (var j = 0; j < all.length; j++) { + var _ele = all[j]; + if (p.canSet(_ele)) { + _ele._private[p.field][k] = v; + } + } + } + } + + // update mappers if asked + if (p.updateStyle) { + self.updateStyle(); + } + + // call onSet callback + p.onSet(self); + if (p.settingTriggersEvent) { + self[p.triggerFnName](p.settingEvent); + } + + // .data(function(){ ... }) + } else if (p.allowBinding && fn$6(name)) { + // bind to event + var fn = name; + self.on(p.bindingEvent, fn); + + // .data() + } else if (p.allowGetting && name === undefined) { + // get whole object + var _ret; + if (single) { + p.beforeGet(single); + _ret = single._private[p.field]; + } + return _ret; + } + return self; // maintain chainability + }; // function + }, + + // data + + // remove data field + removeData: function removeData(params) { + var defaults = { + field: 'data', + event: 'data', + triggerFnName: 'trigger', + triggerEvent: false, + immutableKeys: {} // key => true if immutable + }; + + params = extend({}, defaults, params); + return function removeDataImpl(names) { + var p = params; + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + + // .removeData('foo bar') + if (string(names)) { + // then get the list of keys, and delete them + var keys = names.split(/\s+/); + var l = keys.length; + for (var i = 0; i < l; i++) { + // delete each non-empty key + var key = keys[i]; + if (emptyString(key)) { + continue; + } + var valid = !p.immutableKeys[key]; // not valid if immutable + if (valid) { + for (var i_a = 0, l_a = all.length; i_a < l_a; i_a++) { + all[i_a]._private[p.field][key] = undefined; + } + } + } + if (p.triggerEvent) { + self[p.triggerFnName](p.event); + } + + // .removeData() + } else if (names === undefined) { + // then delete all keys + + for (var _i_a = 0, _l_a = all.length; _i_a < _l_a; _i_a++) { + var _privateFields = all[_i_a]._private[p.field]; + var _keys = Object.keys(_privateFields); + for (var _i2 = 0; _i2 < _keys.length; _i2++) { + var _key = _keys[_i2]; + var validKeyToDelete = !p.immutableKeys[_key]; + if (validKeyToDelete) { + _privateFields[_key] = undefined; + } + } + } + if (p.triggerEvent) { + self[p.triggerFnName](p.event); + } + } + return self; // maintain chaining + }; // function + } // removeData + }; // define + + var define$1 = { + eventAliasesOn: function eventAliasesOn(proto) { + var p = proto; + p.addListener = p.listen = p.bind = p.on; + p.unlisten = p.unbind = p.off = p.removeListener; + p.trigger = p.emit; + + // this is just a wrapper alias of .on() + p.pon = p.promiseOn = function (events, selector) { + var self = this; + var args = Array.prototype.slice.call(arguments, 0); + return new Promise$1(function (resolve, reject) { + var callback = function callback(e) { + self.off.apply(self, offArgs); + resolve(e); + }; + var onArgs = args.concat([callback]); + var offArgs = onArgs.concat([]); + self.on.apply(self, onArgs); + }); + }; + } + }; // define + + // use this module to cherry pick functions into your prototype + var define = {}; + [define$3, define$2, define$1].forEach(function (m) { + extend(define, m); + }); + + var elesfn$i = { + animate: define.animate(), + animation: define.animation(), + animated: define.animated(), + clearQueue: define.clearQueue(), + delay: define.delay(), + delayAnimation: define.delayAnimation(), + stop: define.stop() + }; + + var elesfn$h = { + classes: function classes(_classes) { + var self = this; + if (_classes === undefined) { + var ret = []; + self[0]._private.classes.forEach(function (cls) { + return ret.push(cls); + }); + return ret; + } else if (!array(_classes)) { + // extract classes from string + _classes = (_classes || '').match(/\S+/g) || []; + } + var changed = []; + var classesSet = new Set$1(_classes); + + // check and update each ele + for (var j = 0; j < self.length; j++) { + var ele = self[j]; + var _p = ele._private; + var eleClasses = _p.classes; + var changedEle = false; + + // check if ele has all of the passed classes + for (var i = 0; i < _classes.length; i++) { + var cls = _classes[i]; + var eleHasClass = eleClasses.has(cls); + if (!eleHasClass) { + changedEle = true; + break; + } + } + + // check if ele has classes outside of those passed + if (!changedEle) { + changedEle = eleClasses.size !== _classes.length; + } + if (changedEle) { + _p.classes = classesSet; + changed.push(ele); + } + } + + // trigger update style on those eles that had class changes + if (changed.length > 0) { + this.spawn(changed).updateStyle().emit('class'); + } + return self; + }, + addClass: function addClass(classes) { + return this.toggleClass(classes, true); + }, + hasClass: function hasClass(className) { + var ele = this[0]; + return ele != null && ele._private.classes.has(className); + }, + toggleClass: function toggleClass(classes, toggle) { + if (!array(classes)) { + // extract classes from string + classes = classes.match(/\S+/g) || []; + } + var self = this; + var toggleUndefd = toggle === undefined; + var changed = []; // eles who had classes changed + + for (var i = 0, il = self.length; i < il; i++) { + var ele = self[i]; + var eleClasses = ele._private.classes; + var changedEle = false; + for (var j = 0; j < classes.length; j++) { + var cls = classes[j]; + var hasClass = eleClasses.has(cls); + var changedNow = false; + if (toggle || toggleUndefd && !hasClass) { + eleClasses.add(cls); + changedNow = true; + } else if (!toggle || toggleUndefd && hasClass) { + eleClasses["delete"](cls); + changedNow = true; + } + if (!changedEle && changedNow) { + changed.push(ele); + changedEle = true; + } + } // for j classes + } // for i eles + + // trigger update style on those eles that had class changes + if (changed.length > 0) { + this.spawn(changed).updateStyle().emit('class'); + } + return self; + }, + removeClass: function removeClass(classes) { + return this.toggleClass(classes, false); + }, + flashClass: function flashClass(classes, duration) { + var self = this; + if (duration == null) { + duration = 250; + } else if (duration === 0) { + return self; // nothing to do really + } + + self.addClass(classes); + setTimeout(function () { + self.removeClass(classes); + }, duration); + return self; + } + }; + elesfn$h.className = elesfn$h.classNames = elesfn$h.classes; + + // tokens in the query language + var tokens = { + metaChar: '[\\!\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]', + // chars we need to escape in let names, etc + comparatorOp: '=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=', + // binary comparison op (used in data selectors) + boolOp: '\\?|\\!|\\^', + // boolean (unary) operators (used in data selectors) + string: '"(?:\\\\"|[^"])*"' + '|' + "'(?:\\\\'|[^'])*'", + // string literals (used in data selectors) -- doublequotes | singlequotes + number: number, + // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123 + meta: 'degree|indegree|outdegree', + // allowed metadata fields (i.e. allowed functions to use from Collection) + separator: '\\s*,\\s*', + // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass + descendant: '\\s+', + child: '\\s+>\\s+', + subject: '\\$', + group: 'node|edge|\\*', + directedEdge: '\\s+->\\s+', + undirectedEdge: '\\s+<->\\s+' + }; + tokens.variable = '(?:[\\w-.]|(?:\\\\' + tokens.metaChar + '))+'; // a variable name can have letters, numbers, dashes, and periods + tokens.className = '(?:[\\w-]|(?:\\\\' + tokens.metaChar + '))+'; // a class name has the same rules as a variable except it can't have a '.' in the name + tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number + tokens.id = tokens.variable; // an element id (follows variable conventions) + + (function () { + var ops, op, i; + + // add @ variants to comparatorOp + ops = tokens.comparatorOp.split('|'); + for (i = 0; i < ops.length; i++) { + op = ops[i]; + tokens.comparatorOp += '|@' + op; + } + + // add ! variants to comparatorOp + ops = tokens.comparatorOp.split('|'); + for (i = 0; i < ops.length; i++) { + op = ops[i]; + if (op.indexOf('!') >= 0) { + continue; + } // skip ops that explicitly contain ! + if (op === '=') { + continue; + } // skip = b/c != is explicitly defined + + tokens.comparatorOp += '|\\!' + op; + } + })(); + + /** + * Make a new query object + * + * @prop type {Type} The type enum (int) of the query + * @prop checks List of checks to make against an ele to test for a match + */ + var newQuery = function newQuery() { + return { + checks: [] + }; + }; + + /** + * A check type enum-like object. Uses integer values for fast match() lookup. + * The ordering does not matter as long as the ints are unique. + */ + var Type = { + /** E.g. node */ + GROUP: 0, + /** A collection of elements */ + COLLECTION: 1, + /** A filter(ele) function */ + FILTER: 2, + /** E.g. [foo > 1] */ + DATA_COMPARE: 3, + /** E.g. [foo] */ + DATA_EXIST: 4, + /** E.g. [?foo] */ + DATA_BOOL: 5, + /** E.g. [[degree > 2]] */ + META_COMPARE: 6, + /** E.g. :selected */ + STATE: 7, + /** E.g. #foo */ + ID: 8, + /** E.g. .foo */ + CLASS: 9, + /** E.g. #foo <-> #bar */ + UNDIRECTED_EDGE: 10, + /** E.g. #foo -> #bar */ + DIRECTED_EDGE: 11, + /** E.g. $#foo -> #bar */ + NODE_SOURCE: 12, + /** E.g. #foo -> $#bar */ + NODE_TARGET: 13, + /** E.g. $#foo <-> #bar */ + NODE_NEIGHBOR: 14, + /** E.g. #foo > #bar */ + CHILD: 15, + /** E.g. #foo #bar */ + DESCENDANT: 16, + /** E.g. $#foo > #bar */ + PARENT: 17, + /** E.g. $#foo #bar */ + ANCESTOR: 18, + /** E.g. #foo > $bar > #baz */ + COMPOUND_SPLIT: 19, + /** Always matches, useful placeholder for subject in `COMPOUND_SPLIT` */ + TRUE: 20 + }; + + var stateSelectors = [{ + selector: ':selected', + matches: function matches(ele) { + return ele.selected(); + } + }, { + selector: ':unselected', + matches: function matches(ele) { + return !ele.selected(); + } + }, { + selector: ':selectable', + matches: function matches(ele) { + return ele.selectable(); + } + }, { + selector: ':unselectable', + matches: function matches(ele) { + return !ele.selectable(); + } + }, { + selector: ':locked', + matches: function matches(ele) { + return ele.locked(); + } + }, { + selector: ':unlocked', + matches: function matches(ele) { + return !ele.locked(); + } + }, { + selector: ':visible', + matches: function matches(ele) { + return ele.visible(); + } + }, { + selector: ':hidden', + matches: function matches(ele) { + return !ele.visible(); + } + }, { + selector: ':transparent', + matches: function matches(ele) { + return ele.transparent(); + } + }, { + selector: ':grabbed', + matches: function matches(ele) { + return ele.grabbed(); + } + }, { + selector: ':free', + matches: function matches(ele) { + return !ele.grabbed(); + } + }, { + selector: ':removed', + matches: function matches(ele) { + return ele.removed(); + } + }, { + selector: ':inside', + matches: function matches(ele) { + return !ele.removed(); + } + }, { + selector: ':grabbable', + matches: function matches(ele) { + return ele.grabbable(); + } + }, { + selector: ':ungrabbable', + matches: function matches(ele) { + return !ele.grabbable(); + } + }, { + selector: ':animated', + matches: function matches(ele) { + return ele.animated(); + } + }, { + selector: ':unanimated', + matches: function matches(ele) { + return !ele.animated(); + } + }, { + selector: ':parent', + matches: function matches(ele) { + return ele.isParent(); + } + }, { + selector: ':childless', + matches: function matches(ele) { + return ele.isChildless(); + } + }, { + selector: ':child', + matches: function matches(ele) { + return ele.isChild(); + } + }, { + selector: ':orphan', + matches: function matches(ele) { + return ele.isOrphan(); + } + }, { + selector: ':nonorphan', + matches: function matches(ele) { + return ele.isChild(); + } + }, { + selector: ':compound', + matches: function matches(ele) { + if (ele.isNode()) { + return ele.isParent(); + } else { + return ele.source().isParent() || ele.target().isParent(); + } + } + }, { + selector: ':loop', + matches: function matches(ele) { + return ele.isLoop(); + } + }, { + selector: ':simple', + matches: function matches(ele) { + return ele.isSimple(); + } + }, { + selector: ':active', + matches: function matches(ele) { + return ele.active(); + } + }, { + selector: ':inactive', + matches: function matches(ele) { + return !ele.active(); + } + }, { + selector: ':backgrounding', + matches: function matches(ele) { + return ele.backgrounding(); + } + }, { + selector: ':nonbackgrounding', + matches: function matches(ele) { + return !ele.backgrounding(); + } + }].sort(function (a, b) { + // n.b. selectors that are starting substrings of others must have the longer ones first + return descending(a.selector, b.selector); + }); + var lookup = function () { + var selToFn = {}; + var s; + for (var i = 0; i < stateSelectors.length; i++) { + s = stateSelectors[i]; + selToFn[s.selector] = s.matches; + } + return selToFn; + }(); + var stateSelectorMatches = function stateSelectorMatches(sel, ele) { + return lookup[sel](ele); + }; + var stateSelectorRegex = '(' + stateSelectors.map(function (s) { + return s.selector; + }).join('|') + ')'; + + // when a token like a variable has escaped meta characters, we need to clean the backslashes out + // so that values get compared properly in Selector.filter() + var cleanMetaChars = function cleanMetaChars(str) { + return str.replace(new RegExp('\\\\(' + tokens.metaChar + ')', 'g'), function (match, $1) { + return $1; + }); + }; + var replaceLastQuery = function replaceLastQuery(selector, examiningQuery, replacementQuery) { + selector[selector.length - 1] = replacementQuery; + }; + + // NOTE: add new expression syntax here to have it recognised by the parser; + // - a query contains all adjacent (i.e. no separator in between) expressions; + // - the current query is stored in selector[i] + // - you need to check the query objects in match() for it actually filter properly, but that's pretty straight forward + var exprs = [{ + name: 'group', + // just used for identifying when debugging + query: true, + regex: '(' + tokens.group + ')', + populate: function populate(selector, query, _ref) { + var _ref2 = _slicedToArray(_ref, 1), + group = _ref2[0]; + query.checks.push({ + type: Type.GROUP, + value: group === '*' ? group : group + 's' + }); + } + }, { + name: 'state', + query: true, + regex: stateSelectorRegex, + populate: function populate(selector, query, _ref3) { + var _ref4 = _slicedToArray(_ref3, 1), + state = _ref4[0]; + query.checks.push({ + type: Type.STATE, + value: state + }); + } + }, { + name: 'id', + query: true, + regex: '\\#(' + tokens.id + ')', + populate: function populate(selector, query, _ref5) { + var _ref6 = _slicedToArray(_ref5, 1), + id = _ref6[0]; + query.checks.push({ + type: Type.ID, + value: cleanMetaChars(id) + }); + } + }, { + name: 'className', + query: true, + regex: '\\.(' + tokens.className + ')', + populate: function populate(selector, query, _ref7) { + var _ref8 = _slicedToArray(_ref7, 1), + className = _ref8[0]; + query.checks.push({ + type: Type.CLASS, + value: cleanMetaChars(className) + }); + } + }, { + name: 'dataExists', + query: true, + regex: '\\[\\s*(' + tokens.variable + ')\\s*\\]', + populate: function populate(selector, query, _ref9) { + var _ref10 = _slicedToArray(_ref9, 1), + variable = _ref10[0]; + query.checks.push({ + type: Type.DATA_EXIST, + field: cleanMetaChars(variable) + }); + } + }, { + name: 'dataCompare', + query: true, + regex: '\\[\\s*(' + tokens.variable + ')\\s*(' + tokens.comparatorOp + ')\\s*(' + tokens.value + ')\\s*\\]', + populate: function populate(selector, query, _ref11) { + var _ref12 = _slicedToArray(_ref11, 3), + variable = _ref12[0], + comparatorOp = _ref12[1], + value = _ref12[2]; + var valueIsString = new RegExp('^' + tokens.string + '$').exec(value) != null; + if (valueIsString) { + value = value.substring(1, value.length - 1); + } else { + value = parseFloat(value); + } + query.checks.push({ + type: Type.DATA_COMPARE, + field: cleanMetaChars(variable), + operator: comparatorOp, + value: value + }); + } + }, { + name: 'dataBool', + query: true, + regex: '\\[\\s*(' + tokens.boolOp + ')\\s*(' + tokens.variable + ')\\s*\\]', + populate: function populate(selector, query, _ref13) { + var _ref14 = _slicedToArray(_ref13, 2), + boolOp = _ref14[0], + variable = _ref14[1]; + query.checks.push({ + type: Type.DATA_BOOL, + field: cleanMetaChars(variable), + operator: boolOp + }); + } + }, { + name: 'metaCompare', + query: true, + regex: '\\[\\[\\s*(' + tokens.meta + ')\\s*(' + tokens.comparatorOp + ')\\s*(' + tokens.number + ')\\s*\\]\\]', + populate: function populate(selector, query, _ref15) { + var _ref16 = _slicedToArray(_ref15, 3), + meta = _ref16[0], + comparatorOp = _ref16[1], + number = _ref16[2]; + query.checks.push({ + type: Type.META_COMPARE, + field: cleanMetaChars(meta), + operator: comparatorOp, + value: parseFloat(number) + }); + } + }, { + name: 'nextQuery', + separator: true, + regex: tokens.separator, + populate: function populate(selector, query) { + var currentSubject = selector.currentSubject; + var edgeCount = selector.edgeCount; + var compoundCount = selector.compoundCount; + var lastQ = selector[selector.length - 1]; + if (currentSubject != null) { + lastQ.subject = currentSubject; + selector.currentSubject = null; + } + lastQ.edgeCount = edgeCount; + lastQ.compoundCount = compoundCount; + selector.edgeCount = 0; + selector.compoundCount = 0; + + // go on to next query + var nextQuery = selector[selector.length++] = newQuery(); + return nextQuery; // this is the new query to be filled by the following exprs + } + }, { + name: 'directedEdge', + separator: true, + regex: tokens.directedEdge, + populate: function populate(selector, query) { + if (selector.currentSubject == null) { + // undirected edge + var edgeQuery = newQuery(); + var source = query; + var target = newQuery(); + edgeQuery.checks.push({ + type: Type.DIRECTED_EDGE, + source: source, + target: target + }); + + // the query in the selector should be the edge rather than the source + replaceLastQuery(selector, query, edgeQuery); + selector.edgeCount++; + + // we're now populating the target query with expressions that follow + return target; + } else { + // source/target + var srcTgtQ = newQuery(); + var _source = query; + var _target = newQuery(); + srcTgtQ.checks.push({ + type: Type.NODE_SOURCE, + source: _source, + target: _target + }); + + // the query in the selector should be the neighbourhood rather than the node + replaceLastQuery(selector, query, srcTgtQ); + selector.edgeCount++; + return _target; // now populating the target with the following expressions + } + } + }, { + name: 'undirectedEdge', + separator: true, + regex: tokens.undirectedEdge, + populate: function populate(selector, query) { + if (selector.currentSubject == null) { + // undirected edge + var edgeQuery = newQuery(); + var source = query; + var target = newQuery(); + edgeQuery.checks.push({ + type: Type.UNDIRECTED_EDGE, + nodes: [source, target] + }); + + // the query in the selector should be the edge rather than the source + replaceLastQuery(selector, query, edgeQuery); + selector.edgeCount++; + + // we're now populating the target query with expressions that follow + return target; + } else { + // neighbourhood + var nhoodQ = newQuery(); + var node = query; + var neighbor = newQuery(); + nhoodQ.checks.push({ + type: Type.NODE_NEIGHBOR, + node: node, + neighbor: neighbor + }); + + // the query in the selector should be the neighbourhood rather than the node + replaceLastQuery(selector, query, nhoodQ); + return neighbor; // now populating the neighbor with following expressions + } + } + }, { + name: 'child', + separator: true, + regex: tokens.child, + populate: function populate(selector, query) { + if (selector.currentSubject == null) { + // default: child query + var parentChildQuery = newQuery(); + var child = newQuery(); + var parent = selector[selector.length - 1]; + parentChildQuery.checks.push({ + type: Type.CHILD, + parent: parent, + child: child + }); + + // the query in the selector should be the '>' itself + replaceLastQuery(selector, query, parentChildQuery); + selector.compoundCount++; + + // we're now populating the child query with expressions that follow + return child; + } else if (selector.currentSubject === query) { + // compound split query + var compound = newQuery(); + var left = selector[selector.length - 1]; + var right = newQuery(); + var subject = newQuery(); + var _child = newQuery(); + var _parent = newQuery(); + + // set up the root compound q + compound.checks.push({ + type: Type.COMPOUND_SPLIT, + left: left, + right: right, + subject: subject + }); + + // populate the subject and replace the q at the old spot (within left) with TRUE + subject.checks = query.checks; // take the checks from the left + query.checks = [{ + type: Type.TRUE + }]; // checks under left refs the subject implicitly + + // set up the right q + _parent.checks.push({ + type: Type.TRUE + }); // parent implicitly refs the subject + right.checks.push({ + type: Type.PARENT, + // type is swapped on right side queries + parent: _parent, + child: _child // empty for now + }); + + replaceLastQuery(selector, left, compound); + + // update the ref since we moved things around for `query` + selector.currentSubject = subject; + selector.compoundCount++; + return _child; // now populating the right side's child + } else { + // parent query + // info for parent query + var _parent2 = newQuery(); + var _child2 = newQuery(); + var pcQChecks = [{ + type: Type.PARENT, + parent: _parent2, + child: _child2 + }]; + + // the parent-child query takes the place of the query previously being populated + _parent2.checks = query.checks; // the previous query contains the checks for the parent + query.checks = pcQChecks; // pc query takes over + + selector.compoundCount++; + return _child2; // we're now populating the child + } + } + }, { + name: 'descendant', + separator: true, + regex: tokens.descendant, + populate: function populate(selector, query) { + if (selector.currentSubject == null) { + // default: descendant query + var ancChQuery = newQuery(); + var descendant = newQuery(); + var ancestor = selector[selector.length - 1]; + ancChQuery.checks.push({ + type: Type.DESCENDANT, + ancestor: ancestor, + descendant: descendant + }); + + // the query in the selector should be the '>' itself + replaceLastQuery(selector, query, ancChQuery); + selector.compoundCount++; + + // we're now populating the descendant query with expressions that follow + return descendant; + } else if (selector.currentSubject === query) { + // compound split query + var compound = newQuery(); + var left = selector[selector.length - 1]; + var right = newQuery(); + var subject = newQuery(); + var _descendant = newQuery(); + var _ancestor = newQuery(); + + // set up the root compound q + compound.checks.push({ + type: Type.COMPOUND_SPLIT, + left: left, + right: right, + subject: subject + }); + + // populate the subject and replace the q at the old spot (within left) with TRUE + subject.checks = query.checks; // take the checks from the left + query.checks = [{ + type: Type.TRUE + }]; // checks under left refs the subject implicitly + + // set up the right q + _ancestor.checks.push({ + type: Type.TRUE + }); // ancestor implicitly refs the subject + right.checks.push({ + type: Type.ANCESTOR, + // type is swapped on right side queries + ancestor: _ancestor, + descendant: _descendant // empty for now + }); + + replaceLastQuery(selector, left, compound); + + // update the ref since we moved things around for `query` + selector.currentSubject = subject; + selector.compoundCount++; + return _descendant; // now populating the right side's descendant + } else { + // ancestor query + // info for parent query + var _ancestor2 = newQuery(); + var _descendant2 = newQuery(); + var adQChecks = [{ + type: Type.ANCESTOR, + ancestor: _ancestor2, + descendant: _descendant2 + }]; + + // the parent-child query takes the place of the query previously being populated + _ancestor2.checks = query.checks; // the previous query contains the checks for the parent + query.checks = adQChecks; // pc query takes over + + selector.compoundCount++; + return _descendant2; // we're now populating the child + } + } + }, { + name: 'subject', + modifier: true, + regex: tokens.subject, + populate: function populate(selector, query) { + if (selector.currentSubject != null && selector.currentSubject !== query) { + warn('Redefinition of subject in selector `' + selector.toString() + '`'); + return false; + } + selector.currentSubject = query; + var topQ = selector[selector.length - 1]; + var topChk = topQ.checks[0]; + var topType = topChk == null ? null : topChk.type; + if (topType === Type.DIRECTED_EDGE) { + // directed edge with subject on the target + + // change to target node check + topChk.type = Type.NODE_TARGET; + } else if (topType === Type.UNDIRECTED_EDGE) { + // undirected edge with subject on the second node + + // change to neighbor check + topChk.type = Type.NODE_NEIGHBOR; + topChk.node = topChk.nodes[1]; // second node is subject + topChk.neighbor = topChk.nodes[0]; + + // clean up unused fields for new type + topChk.nodes = null; + } + } + }]; + exprs.forEach(function (e) { + return e.regexObj = new RegExp('^' + e.regex); + }); + + /** + * Of all the expressions, find the first match in the remaining text. + * @param {string} remaining The remaining text to parse + * @returns The matched expression and the newly remaining text `{ expr, match, name, remaining }` + */ + var consumeExpr = function consumeExpr(remaining) { + var expr; + var match; + var name; + for (var j = 0; j < exprs.length; j++) { + var e = exprs[j]; + var n = e.name; + var m = remaining.match(e.regexObj); + if (m != null) { + match = m; + expr = e; + name = n; + var consumed = m[0]; + remaining = remaining.substring(consumed.length); + break; // we've consumed one expr, so we can return now + } + } + + return { + expr: expr, + match: match, + name: name, + remaining: remaining + }; + }; + + /** + * Consume all the leading whitespace + * @param {string} remaining The text to consume + * @returns The text with the leading whitespace removed + */ + var consumeWhitespace = function consumeWhitespace(remaining) { + var match = remaining.match(/^\s+/); + if (match) { + var consumed = match[0]; + remaining = remaining.substring(consumed.length); + } + return remaining; + }; + + /** + * Parse the string and store the parsed representation in the Selector. + * @param {string} selector The selector string + * @returns `true` if the selector was successfully parsed, `false` otherwise + */ + var parse = function parse(selector) { + var self = this; + var remaining = self.inputText = selector; + var currentQuery = self[0] = newQuery(); + self.length = 1; + remaining = consumeWhitespace(remaining); // get rid of leading whitespace + + for (;;) { + var exprInfo = consumeExpr(remaining); + if (exprInfo.expr == null) { + warn('The selector `' + selector + '`is invalid'); + return false; + } else { + var args = exprInfo.match.slice(1); + + // let the token populate the selector object in currentQuery + var ret = exprInfo.expr.populate(self, currentQuery, args); + if (ret === false) { + return false; // exit if population failed + } else if (ret != null) { + currentQuery = ret; // change the current query to be filled if the expr specifies + } + } + + remaining = exprInfo.remaining; + + // we're done when there's nothing left to parse + if (remaining.match(/^\s*$/)) { + break; + } + } + var lastQ = self[self.length - 1]; + if (self.currentSubject != null) { + lastQ.subject = self.currentSubject; + } + lastQ.edgeCount = self.edgeCount; + lastQ.compoundCount = self.compoundCount; + for (var i = 0; i < self.length; i++) { + var q = self[i]; + + // in future, this could potentially be allowed if there were operator precedence and detection of invalid combinations + if (q.compoundCount > 0 && q.edgeCount > 0) { + warn('The selector `' + selector + '` is invalid because it uses both a compound selector and an edge selector'); + return false; + } + if (q.edgeCount > 1) { + warn('The selector `' + selector + '` is invalid because it uses multiple edge selectors'); + return false; + } else if (q.edgeCount === 1) { + warn('The selector `' + selector + '` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.'); + } + } + return true; // success + }; + + /** + * Get the selector represented as a string. This value uses default formatting, + * so things like spacing may differ from the input text passed to the constructor. + * @returns {string} The selector string + */ + var toString = function toString() { + if (this.toStringCache != null) { + return this.toStringCache; + } + var clean = function clean(obj) { + if (obj == null) { + return ''; + } else { + return obj; + } + }; + var cleanVal = function cleanVal(val) { + if (string(val)) { + return '"' + val + '"'; + } else { + return clean(val); + } + }; + var space = function space(val) { + return ' ' + val + ' '; + }; + var checkToString = function checkToString(check, subject) { + var type = check.type, + value = check.value; + switch (type) { + case Type.GROUP: + { + var group = clean(value); + return group.substring(0, group.length - 1); + } + case Type.DATA_COMPARE: + { + var field = check.field, + operator = check.operator; + return '[' + field + space(clean(operator)) + cleanVal(value) + ']'; + } + case Type.DATA_BOOL: + { + var _operator = check.operator, + _field = check.field; + return '[' + clean(_operator) + _field + ']'; + } + case Type.DATA_EXIST: + { + var _field2 = check.field; + return '[' + _field2 + ']'; + } + case Type.META_COMPARE: + { + var _operator2 = check.operator, + _field3 = check.field; + return '[[' + _field3 + space(clean(_operator2)) + cleanVal(value) + ']]'; + } + case Type.STATE: + { + return value; + } + case Type.ID: + { + return '#' + value; + } + case Type.CLASS: + { + return '.' + value; + } + case Type.PARENT: + case Type.CHILD: + { + return queryToString(check.parent, subject) + space('>') + queryToString(check.child, subject); + } + case Type.ANCESTOR: + case Type.DESCENDANT: + { + return queryToString(check.ancestor, subject) + ' ' + queryToString(check.descendant, subject); + } + case Type.COMPOUND_SPLIT: + { + var lhs = queryToString(check.left, subject); + var sub = queryToString(check.subject, subject); + var rhs = queryToString(check.right, subject); + return lhs + (lhs.length > 0 ? ' ' : '') + sub + rhs; + } + case Type.TRUE: + { + return ''; + } + } + }; + var queryToString = function queryToString(query, subject) { + return query.checks.reduce(function (str, chk, i) { + return str + (subject === query && i === 0 ? '$' : '') + checkToString(chk, subject); + }, ''); + }; + var str = ''; + for (var i = 0; i < this.length; i++) { + var query = this[i]; + str += queryToString(query, query.subject); + if (this.length > 1 && i < this.length - 1) { + str += ', '; + } + } + this.toStringCache = str; + return str; + }; + var parse$1 = { + parse: parse, + toString: toString + }; + + var valCmp = function valCmp(fieldVal, operator, value) { + var matches; + var isFieldStr = string(fieldVal); + var isFieldNum = number$1(fieldVal); + var isValStr = string(value); + var fieldStr, valStr; + var caseInsensitive = false; + var notExpr = false; + var isIneqCmp = false; + if (operator.indexOf('!') >= 0) { + operator = operator.replace('!', ''); + notExpr = true; + } + if (operator.indexOf('@') >= 0) { + operator = operator.replace('@', ''); + caseInsensitive = true; + } + if (isFieldStr || isValStr || caseInsensitive) { + fieldStr = !isFieldStr && !isFieldNum ? '' : '' + fieldVal; + valStr = '' + value; + } + + // if we're doing a case insensitive comparison, then we're using a STRING comparison + // even if we're comparing numbers + if (caseInsensitive) { + fieldVal = fieldStr = fieldStr.toLowerCase(); + value = valStr = valStr.toLowerCase(); + } + switch (operator) { + case '*=': + matches = fieldStr.indexOf(valStr) >= 0; + break; + case '$=': + matches = fieldStr.indexOf(valStr, fieldStr.length - valStr.length) >= 0; + break; + case '^=': + matches = fieldStr.indexOf(valStr) === 0; + break; + case '=': + matches = fieldVal === value; + break; + case '>': + isIneqCmp = true; + matches = fieldVal > value; + break; + case '>=': + isIneqCmp = true; + matches = fieldVal >= value; + break; + case '<': + isIneqCmp = true; + matches = fieldVal < value; + break; + case '<=': + isIneqCmp = true; + matches = fieldVal <= value; + break; + default: + matches = false; + break; + } + + // apply the not op, but null vals for inequalities should always stay non-matching + if (notExpr && (fieldVal != null || !isIneqCmp)) { + matches = !matches; + } + return matches; + }; + var boolCmp = function boolCmp(fieldVal, operator) { + switch (operator) { + case '?': + return fieldVal ? true : false; + case '!': + return fieldVal ? false : true; + case '^': + return fieldVal === undefined; + } + }; + var existCmp = function existCmp(fieldVal) { + return fieldVal !== undefined; + }; + var data$1 = function data(ele, field) { + return ele.data(field); + }; + var meta = function meta(ele, field) { + return ele[field](); + }; + + /** A lookup of `match(check, ele)` functions by `Type` int */ + var match = []; + + /** + * Returns whether the query matches for the element + * @param query The `{ type, value, ... }` query object + * @param ele The element to compare against + */ + var matches$1 = function matches(query, ele) { + return query.checks.every(function (chk) { + return match[chk.type](chk, ele); + }); + }; + match[Type.GROUP] = function (check, ele) { + var group = check.value; + return group === '*' || group === ele.group(); + }; + match[Type.STATE] = function (check, ele) { + var stateSelector = check.value; + return stateSelectorMatches(stateSelector, ele); + }; + match[Type.ID] = function (check, ele) { + var id = check.value; + return ele.id() === id; + }; + match[Type.CLASS] = function (check, ele) { + var cls = check.value; + return ele.hasClass(cls); + }; + match[Type.META_COMPARE] = function (check, ele) { + var field = check.field, + operator = check.operator, + value = check.value; + return valCmp(meta(ele, field), operator, value); + }; + match[Type.DATA_COMPARE] = function (check, ele) { + var field = check.field, + operator = check.operator, + value = check.value; + return valCmp(data$1(ele, field), operator, value); + }; + match[Type.DATA_BOOL] = function (check, ele) { + var field = check.field, + operator = check.operator; + return boolCmp(data$1(ele, field), operator); + }; + match[Type.DATA_EXIST] = function (check, ele) { + var field = check.field; + check.operator; + return existCmp(data$1(ele, field)); + }; + match[Type.UNDIRECTED_EDGE] = function (check, ele) { + var qA = check.nodes[0]; + var qB = check.nodes[1]; + var src = ele.source(); + var tgt = ele.target(); + return matches$1(qA, src) && matches$1(qB, tgt) || matches$1(qB, src) && matches$1(qA, tgt); + }; + match[Type.NODE_NEIGHBOR] = function (check, ele) { + return matches$1(check.node, ele) && ele.neighborhood().some(function (n) { + return n.isNode() && matches$1(check.neighbor, n); + }); + }; + match[Type.DIRECTED_EDGE] = function (check, ele) { + return matches$1(check.source, ele.source()) && matches$1(check.target, ele.target()); + }; + match[Type.NODE_SOURCE] = function (check, ele) { + return matches$1(check.source, ele) && ele.outgoers().some(function (n) { + return n.isNode() && matches$1(check.target, n); + }); + }; + match[Type.NODE_TARGET] = function (check, ele) { + return matches$1(check.target, ele) && ele.incomers().some(function (n) { + return n.isNode() && matches$1(check.source, n); + }); + }; + match[Type.CHILD] = function (check, ele) { + return matches$1(check.child, ele) && matches$1(check.parent, ele.parent()); + }; + match[Type.PARENT] = function (check, ele) { + return matches$1(check.parent, ele) && ele.children().some(function (c) { + return matches$1(check.child, c); + }); + }; + match[Type.DESCENDANT] = function (check, ele) { + return matches$1(check.descendant, ele) && ele.ancestors().some(function (a) { + return matches$1(check.ancestor, a); + }); + }; + match[Type.ANCESTOR] = function (check, ele) { + return matches$1(check.ancestor, ele) && ele.descendants().some(function (d) { + return matches$1(check.descendant, d); + }); + }; + match[Type.COMPOUND_SPLIT] = function (check, ele) { + return matches$1(check.subject, ele) && matches$1(check.left, ele) && matches$1(check.right, ele); + }; + match[Type.TRUE] = function () { + return true; + }; + match[Type.COLLECTION] = function (check, ele) { + var collection = check.value; + return collection.has(ele); + }; + match[Type.FILTER] = function (check, ele) { + var filter = check.value; + return filter(ele); + }; + + // filter an existing collection + var filter = function filter(collection) { + var self = this; + + // for 1 id #foo queries, just get the element + if (self.length === 1 && self[0].checks.length === 1 && self[0].checks[0].type === Type.ID) { + return collection.getElementById(self[0].checks[0].value).collection(); + } + var selectorFunction = function selectorFunction(element) { + for (var j = 0; j < self.length; j++) { + var query = self[j]; + if (matches$1(query, element)) { + return true; + } + } + return false; + }; + if (self.text() == null) { + selectorFunction = function selectorFunction() { + return true; + }; + } + return collection.filter(selectorFunction); + }; // filter + + // does selector match a single element? + var matches = function matches(ele) { + var self = this; + for (var j = 0; j < self.length; j++) { + var query = self[j]; + if (matches$1(query, ele)) { + return true; + } + } + return false; + }; // matches + + var matching = { + matches: matches, + filter: filter + }; + + var Selector = function Selector(selector) { + this.inputText = selector; + this.currentSubject = null; + this.compoundCount = 0; + this.edgeCount = 0; + this.length = 0; + if (selector == null || string(selector) && selector.match(/^\s*$/)) ; else if (elementOrCollection(selector)) { + this.addQuery({ + checks: [{ + type: Type.COLLECTION, + value: selector.collection() + }] + }); + } else if (fn$6(selector)) { + this.addQuery({ + checks: [{ + type: Type.FILTER, + value: selector + }] + }); + } else if (string(selector)) { + if (!this.parse(selector)) { + this.invalid = true; + } + } else { + error('A selector must be created from a string; found '); + } + }; + var selfn = Selector.prototype; + [parse$1, matching].forEach(function (p) { + return extend(selfn, p); + }); + selfn.text = function () { + return this.inputText; + }; + selfn.size = function () { + return this.length; + }; + selfn.eq = function (i) { + return this[i]; + }; + selfn.sameText = function (otherSel) { + return !this.invalid && !otherSel.invalid && this.text() === otherSel.text(); + }; + selfn.addQuery = function (q) { + this[this.length++] = q; + }; + selfn.selector = selfn.toString; + + var elesfn$g = { + allAre: function allAre(selector) { + var selObj = new Selector(selector); + return this.every(function (ele) { + return selObj.matches(ele); + }); + }, + is: function is(selector) { + var selObj = new Selector(selector); + return this.some(function (ele) { + return selObj.matches(ele); + }); + }, + some: function some(fn, thisArg) { + for (var i = 0; i < this.length; i++) { + var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]); + if (ret) { + return true; + } + } + return false; + }, + every: function every(fn, thisArg) { + for (var i = 0; i < this.length; i++) { + var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]); + if (!ret) { + return false; + } + } + return true; + }, + same: function same(collection) { + // cheap collection ref check + if (this === collection) { + return true; + } + collection = this.cy().collection(collection); + var thisLength = this.length; + var collectionLength = collection.length; + + // cheap length check + if (thisLength !== collectionLength) { + return false; + } + + // cheap element ref check + if (thisLength === 1) { + return this[0] === collection[0]; + } + return this.every(function (ele) { + return collection.hasElementWithId(ele.id()); + }); + }, + anySame: function anySame(collection) { + collection = this.cy().collection(collection); + return this.some(function (ele) { + return collection.hasElementWithId(ele.id()); + }); + }, + allAreNeighbors: function allAreNeighbors(collection) { + collection = this.cy().collection(collection); + var nhood = this.neighborhood(); + return collection.every(function (ele) { + return nhood.hasElementWithId(ele.id()); + }); + }, + contains: function contains(collection) { + collection = this.cy().collection(collection); + var self = this; + return collection.every(function (ele) { + return self.hasElementWithId(ele.id()); + }); + } + }; + elesfn$g.allAreNeighbours = elesfn$g.allAreNeighbors; + elesfn$g.has = elesfn$g.contains; + elesfn$g.equal = elesfn$g.equals = elesfn$g.same; + + var cache = function cache(fn, name) { + return function traversalCache(arg1, arg2, arg3, arg4) { + var selectorOrEles = arg1; + var eles = this; + var key; + if (selectorOrEles == null) { + key = ''; + } else if (elementOrCollection(selectorOrEles) && selectorOrEles.length === 1) { + key = selectorOrEles.id(); + } + if (eles.length === 1 && key) { + var _p = eles[0]._private; + var tch = _p.traversalCache = _p.traversalCache || {}; + var ch = tch[name] = tch[name] || []; + var hash = hashString(key); + var cacheHit = ch[hash]; + if (cacheHit) { + return cacheHit; + } else { + return ch[hash] = fn.call(eles, arg1, arg2, arg3, arg4); + } + } else { + return fn.call(eles, arg1, arg2, arg3, arg4); + } + }; + }; + + var elesfn$f = { + parent: function parent(selector) { + var parents = []; + + // optimisation for single ele call + if (this.length === 1) { + var parent = this[0]._private.parent; + if (parent) { + return parent; + } + } + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var _parent = ele._private.parent; + if (_parent) { + parents.push(_parent); + } + } + return this.spawn(parents, true).filter(selector); + }, + parents: function parents(selector) { + var parents = []; + var eles = this.parent(); + while (eles.nonempty()) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + parents.push(ele); + } + eles = eles.parent(); + } + return this.spawn(parents, true).filter(selector); + }, + commonAncestors: function commonAncestors(selector) { + var ancestors; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var parents = ele.parents(); + ancestors = ancestors || parents; + ancestors = ancestors.intersect(parents); // current list must be common with current ele parents set + } + + return ancestors.filter(selector); + }, + orphans: function orphans(selector) { + return this.stdFilter(function (ele) { + return ele.isOrphan(); + }).filter(selector); + }, + nonorphans: function nonorphans(selector) { + return this.stdFilter(function (ele) { + return ele.isChild(); + }).filter(selector); + }, + children: cache(function (selector) { + var children = []; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var eleChildren = ele._private.children; + for (var j = 0; j < eleChildren.length; j++) { + children.push(eleChildren[j]); + } + } + return this.spawn(children, true).filter(selector); + }, 'children'), + siblings: function siblings(selector) { + return this.parent().children().not(this).filter(selector); + }, + isParent: function isParent() { + var ele = this[0]; + if (ele) { + return ele.isNode() && ele._private.children.length !== 0; + } + }, + isChildless: function isChildless() { + var ele = this[0]; + if (ele) { + return ele.isNode() && ele._private.children.length === 0; + } + }, + isChild: function isChild() { + var ele = this[0]; + if (ele) { + return ele.isNode() && ele._private.parent != null; + } + }, + isOrphan: function isOrphan() { + var ele = this[0]; + if (ele) { + return ele.isNode() && ele._private.parent == null; + } + }, + descendants: function descendants(selector) { + var elements = []; + function add(eles) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + elements.push(ele); + if (ele.children().nonempty()) { + add(ele.children()); + } + } + } + add(this.children()); + return this.spawn(elements, true).filter(selector); + } + }; + function forEachCompound(eles, fn, includeSelf, recursiveStep) { + var q = []; + var did = new Set$1(); + var cy = eles.cy(); + var hasCompounds = cy.hasCompoundNodes(); + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (includeSelf) { + q.push(ele); + } else if (hasCompounds) { + recursiveStep(q, did, ele); + } + } + while (q.length > 0) { + var _ele = q.shift(); + fn(_ele); + did.add(_ele.id()); + if (hasCompounds) { + recursiveStep(q, did, _ele); + } + } + return eles; + } + function addChildren(q, did, ele) { + if (ele.isParent()) { + var children = ele._private.children; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (!did.has(child.id())) { + q.push(child); + } + } + } + } + + // very efficient version of eles.add( eles.descendants() ).forEach() + // for internal use + elesfn$f.forEachDown = function (fn) { + var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return forEachCompound(this, fn, includeSelf, addChildren); + }; + function addParent(q, did, ele) { + if (ele.isChild()) { + var parent = ele._private.parent; + if (!did.has(parent.id())) { + q.push(parent); + } + } + } + elesfn$f.forEachUp = function (fn) { + var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return forEachCompound(this, fn, includeSelf, addParent); + }; + function addParentAndChildren(q, did, ele) { + addParent(q, did, ele); + addChildren(q, did, ele); + } + elesfn$f.forEachUpAndDown = function (fn) { + var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + return forEachCompound(this, fn, includeSelf, addParentAndChildren); + }; + + // aliases + elesfn$f.ancestors = elesfn$f.parents; + + var fn$5, elesfn$e; + fn$5 = elesfn$e = { + data: define.data({ + field: 'data', + bindingEvent: 'data', + allowBinding: true, + allowSetting: true, + settingEvent: 'data', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true, + immutableKeys: { + 'id': true, + 'source': true, + 'target': true, + 'parent': true + }, + updateStyle: true + }), + removeData: define.removeData({ + field: 'data', + event: 'data', + triggerFnName: 'trigger', + triggerEvent: true, + immutableKeys: { + 'id': true, + 'source': true, + 'target': true, + 'parent': true + }, + updateStyle: true + }), + scratch: define.data({ + field: 'scratch', + bindingEvent: 'scratch', + allowBinding: true, + allowSetting: true, + settingEvent: 'scratch', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true, + updateStyle: true + }), + removeScratch: define.removeData({ + field: 'scratch', + event: 'scratch', + triggerFnName: 'trigger', + triggerEvent: true, + updateStyle: true + }), + rscratch: define.data({ + field: 'rscratch', + allowBinding: false, + allowSetting: true, + settingTriggersEvent: false, + allowGetting: true + }), + removeRscratch: define.removeData({ + field: 'rscratch', + triggerEvent: false + }), + id: function id() { + var ele = this[0]; + if (ele) { + return ele._private.data.id; + } + } + }; + + // aliases + fn$5.attr = fn$5.data; + fn$5.removeAttr = fn$5.removeData; + var data = elesfn$e; + + var elesfn$d = {}; + function defineDegreeFunction(callback) { + return function (includeLoops) { + var self = this; + if (includeLoops === undefined) { + includeLoops = true; + } + if (self.length === 0) { + return; + } + if (self.isNode() && !self.removed()) { + var degree = 0; + var node = self[0]; + var connectedEdges = node._private.edges; + for (var i = 0; i < connectedEdges.length; i++) { + var edge = connectedEdges[i]; + if (!includeLoops && edge.isLoop()) { + continue; + } + degree += callback(node, edge); + } + return degree; + } else { + return; + } + }; + } + extend(elesfn$d, { + degree: defineDegreeFunction(function (node, edge) { + if (edge.source().same(edge.target())) { + return 2; + } else { + return 1; + } + }), + indegree: defineDegreeFunction(function (node, edge) { + if (edge.target().same(node)) { + return 1; + } else { + return 0; + } + }), + outdegree: defineDegreeFunction(function (node, edge) { + if (edge.source().same(node)) { + return 1; + } else { + return 0; + } + }) + }); + function defineDegreeBoundsFunction(degreeFn, callback) { + return function (includeLoops) { + var ret; + var nodes = this.nodes(); + for (var i = 0; i < nodes.length; i++) { + var ele = nodes[i]; + var degree = ele[degreeFn](includeLoops); + if (degree !== undefined && (ret === undefined || callback(degree, ret))) { + ret = degree; + } + } + return ret; + }; + } + extend(elesfn$d, { + minDegree: defineDegreeBoundsFunction('degree', function (degree, min) { + return degree < min; + }), + maxDegree: defineDegreeBoundsFunction('degree', function (degree, max) { + return degree > max; + }), + minIndegree: defineDegreeBoundsFunction('indegree', function (degree, min) { + return degree < min; + }), + maxIndegree: defineDegreeBoundsFunction('indegree', function (degree, max) { + return degree > max; + }), + minOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, min) { + return degree < min; + }), + maxOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, max) { + return degree > max; + }) + }); + extend(elesfn$d, { + totalDegree: function totalDegree(includeLoops) { + var total = 0; + var nodes = this.nodes(); + for (var i = 0; i < nodes.length; i++) { + total += nodes[i].degree(includeLoops); + } + return total; + } + }); + + var fn$4, elesfn$c; + var beforePositionSet = function beforePositionSet(eles, newPos, silent) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (!ele.locked()) { + var oldPos = ele._private.position; + var delta = { + x: newPos.x != null ? newPos.x - oldPos.x : 0, + y: newPos.y != null ? newPos.y - oldPos.y : 0 + }; + if (ele.isParent() && !(delta.x === 0 && delta.y === 0)) { + ele.children().shift(delta, silent); + } + ele.dirtyBoundingBoxCache(); + } + } + }; + var positionDef = { + field: 'position', + bindingEvent: 'position', + allowBinding: true, + allowSetting: true, + settingEvent: 'position', + settingTriggersEvent: true, + triggerFnName: 'emitAndNotify', + allowGetting: true, + validKeys: ['x', 'y'], + beforeGet: function beforeGet(ele) { + ele.updateCompoundBounds(); + }, + beforeSet: function beforeSet(eles, newPos) { + beforePositionSet(eles, newPos, false); + }, + onSet: function onSet(eles) { + eles.dirtyCompoundBoundsCache(); + }, + canSet: function canSet(ele) { + return !ele.locked(); + } + }; + fn$4 = elesfn$c = { + position: define.data(positionDef), + // position but no notification to renderer + silentPosition: define.data(extend({}, positionDef, { + allowBinding: false, + allowSetting: true, + settingTriggersEvent: false, + allowGetting: false, + beforeSet: function beforeSet(eles, newPos) { + beforePositionSet(eles, newPos, true); + }, + onSet: function onSet(eles) { + eles.dirtyCompoundBoundsCache(); + } + })), + positions: function positions(pos, silent) { + if (plainObject(pos)) { + if (silent) { + this.silentPosition(pos); + } else { + this.position(pos); + } + } else if (fn$6(pos)) { + var _fn = pos; + var cy = this.cy(); + cy.startBatch(); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var _pos = void 0; + if (_pos = _fn(ele, i)) { + if (silent) { + ele.silentPosition(_pos); + } else { + ele.position(_pos); + } + } + } + cy.endBatch(); + } + return this; // chaining + }, + + silentPositions: function silentPositions(pos) { + return this.positions(pos, true); + }, + shift: function shift(dim, val, silent) { + var delta; + if (plainObject(dim)) { + delta = { + x: number$1(dim.x) ? dim.x : 0, + y: number$1(dim.y) ? dim.y : 0 + }; + silent = val; + } else if (string(dim) && number$1(val)) { + delta = { + x: 0, + y: 0 + }; + delta[dim] = val; + } + if (delta != null) { + var cy = this.cy(); + cy.startBatch(); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + + // exclude any node that is a descendant of the calling collection + if (cy.hasCompoundNodes() && ele.isChild() && ele.ancestors().anySame(this)) { + continue; + } + var pos = ele.position(); + var newPos = { + x: pos.x + delta.x, + y: pos.y + delta.y + }; + if (silent) { + ele.silentPosition(newPos); + } else { + ele.position(newPos); + } + } + cy.endBatch(); + } + return this; + }, + silentShift: function silentShift(dim, val) { + if (plainObject(dim)) { + this.shift(dim, true); + } else if (string(dim) && number$1(val)) { + this.shift(dim, val, true); + } + return this; + }, + // get/set the rendered (i.e. on screen) positon of the element + renderedPosition: function renderedPosition(dim, val) { + var ele = this[0]; + var cy = this.cy(); + var zoom = cy.zoom(); + var pan = cy.pan(); + var rpos = plainObject(dim) ? dim : undefined; + var setting = rpos !== undefined || val !== undefined && string(dim); + if (ele && ele.isNode()) { + // must have an element and must be a node to return position + if (setting) { + for (var i = 0; i < this.length; i++) { + var _ele = this[i]; + if (val !== undefined) { + // set one dimension + _ele.position(dim, (val - pan[dim]) / zoom); + } else if (rpos !== undefined) { + // set whole position + _ele.position(renderedToModelPosition(rpos, zoom, pan)); + } + } + } else { + // getting + var pos = ele.position(); + rpos = modelToRenderedPosition(pos, zoom, pan); + if (dim === undefined) { + // then return the whole rendered position + return rpos; + } else { + // then return the specified dimension + return rpos[dim]; + } + } + } else if (!setting) { + return undefined; // for empty collection case + } + + return this; // chaining + }, + + // get/set the position relative to the parent + relativePosition: function relativePosition(dim, val) { + var ele = this[0]; + var cy = this.cy(); + var ppos = plainObject(dim) ? dim : undefined; + var setting = ppos !== undefined || val !== undefined && string(dim); + var hasCompoundNodes = cy.hasCompoundNodes(); + if (ele && ele.isNode()) { + // must have an element and must be a node to return position + if (setting) { + for (var i = 0; i < this.length; i++) { + var _ele2 = this[i]; + var parent = hasCompoundNodes ? _ele2.parent() : null; + var hasParent = parent && parent.length > 0; + var relativeToParent = hasParent; + if (hasParent) { + parent = parent[0]; + } + var origin = relativeToParent ? parent.position() : { + x: 0, + y: 0 + }; + if (val !== undefined) { + // set one dimension + _ele2.position(dim, val + origin[dim]); + } else if (ppos !== undefined) { + // set whole position + _ele2.position({ + x: ppos.x + origin.x, + y: ppos.y + origin.y + }); + } + } + } else { + // getting + var pos = ele.position(); + var _parent = hasCompoundNodes ? ele.parent() : null; + var _hasParent = _parent && _parent.length > 0; + var _relativeToParent = _hasParent; + if (_hasParent) { + _parent = _parent[0]; + } + var _origin = _relativeToParent ? _parent.position() : { + x: 0, + y: 0 + }; + ppos = { + x: pos.x - _origin.x, + y: pos.y - _origin.y + }; + if (dim === undefined) { + // then return the whole rendered position + return ppos; + } else { + // then return the specified dimension + return ppos[dim]; + } + } + } else if (!setting) { + return undefined; // for empty collection case + } + + return this; // chaining + } + }; + + // aliases + fn$4.modelPosition = fn$4.point = fn$4.position; + fn$4.modelPositions = fn$4.points = fn$4.positions; + fn$4.renderedPoint = fn$4.renderedPosition; + fn$4.relativePoint = fn$4.relativePosition; + var position = elesfn$c; + + var fn$3, elesfn$b; + fn$3 = elesfn$b = {}; + elesfn$b.renderedBoundingBox = function (options) { + var bb = this.boundingBox(options); + var cy = this.cy(); + var zoom = cy.zoom(); + var pan = cy.pan(); + var x1 = bb.x1 * zoom + pan.x; + var x2 = bb.x2 * zoom + pan.x; + var y1 = bb.y1 * zoom + pan.y; + var y2 = bb.y2 * zoom + pan.y; + return { + x1: x1, + x2: x2, + y1: y1, + y2: y2, + w: x2 - x1, + h: y2 - y1 + }; + }; + elesfn$b.dirtyCompoundBoundsCache = function () { + var silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var cy = this.cy(); + if (!cy.styleEnabled() || !cy.hasCompoundNodes()) { + return this; + } + this.forEachUp(function (ele) { + if (ele.isParent()) { + var _p = ele._private; + _p.compoundBoundsClean = false; + _p.bbCache = null; + if (!silent) { + ele.emitAndNotify('bounds'); + } + } + }); + return this; + }; + elesfn$b.updateCompoundBounds = function () { + var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var cy = this.cy(); + + // not possible to do on non-compound graphs or with the style disabled + if (!cy.styleEnabled() || !cy.hasCompoundNodes()) { + return this; + } + + // save cycles when batching -- but bounds will be stale (or not exist yet) + if (!force && cy.batching()) { + return this; + } + function update(parent) { + if (!parent.isParent()) { + return; + } + var _p = parent._private; + var children = parent.children(); + var includeLabels = parent.pstyle('compound-sizing-wrt-labels').value === 'include'; + var min = { + width: { + val: parent.pstyle('min-width').pfValue, + left: parent.pstyle('min-width-bias-left'), + right: parent.pstyle('min-width-bias-right') + }, + height: { + val: parent.pstyle('min-height').pfValue, + top: parent.pstyle('min-height-bias-top'), + bottom: parent.pstyle('min-height-bias-bottom') + } + }; + var bb = children.boundingBox({ + includeLabels: includeLabels, + includeOverlays: false, + // updating the compound bounds happens outside of the regular + // cache cycle (i.e. before fired events) + useCache: false + }); + var pos = _p.position; + + // if children take up zero area then keep position and fall back on stylesheet w/h + if (bb.w === 0 || bb.h === 0) { + bb = { + w: parent.pstyle('width').pfValue, + h: parent.pstyle('height').pfValue + }; + bb.x1 = pos.x - bb.w / 2; + bb.x2 = pos.x + bb.w / 2; + bb.y1 = pos.y - bb.h / 2; + bb.y2 = pos.y + bb.h / 2; + } + function computeBiasValues(propDiff, propBias, propBiasComplement) { + var biasDiff = 0; + var biasComplementDiff = 0; + var biasTotal = propBias + propBiasComplement; + if (propDiff > 0 && biasTotal > 0) { + biasDiff = propBias / biasTotal * propDiff; + biasComplementDiff = propBiasComplement / biasTotal * propDiff; + } + return { + biasDiff: biasDiff, + biasComplementDiff: biasComplementDiff + }; + } + function computePaddingValues(width, height, paddingObject, relativeTo) { + // Assuming percentage is number from 0 to 1 + if (paddingObject.units === '%') { + switch (relativeTo) { + case 'width': + return width > 0 ? paddingObject.pfValue * width : 0; + case 'height': + return height > 0 ? paddingObject.pfValue * height : 0; + case 'average': + return width > 0 && height > 0 ? paddingObject.pfValue * (width + height) / 2 : 0; + case 'min': + return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * height : paddingObject.pfValue * width : 0; + case 'max': + return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * width : paddingObject.pfValue * height : 0; + default: + return 0; + } + } else if (paddingObject.units === 'px') { + return paddingObject.pfValue; + } else { + return 0; + } + } + var leftVal = min.width.left.value; + if (min.width.left.units === 'px' && min.width.val > 0) { + leftVal = leftVal * 100 / min.width.val; + } + var rightVal = min.width.right.value; + if (min.width.right.units === 'px' && min.width.val > 0) { + rightVal = rightVal * 100 / min.width.val; + } + var topVal = min.height.top.value; + if (min.height.top.units === 'px' && min.height.val > 0) { + topVal = topVal * 100 / min.height.val; + } + var bottomVal = min.height.bottom.value; + if (min.height.bottom.units === 'px' && min.height.val > 0) { + bottomVal = bottomVal * 100 / min.height.val; + } + var widthBiasDiffs = computeBiasValues(min.width.val - bb.w, leftVal, rightVal); + var diffLeft = widthBiasDiffs.biasDiff; + var diffRight = widthBiasDiffs.biasComplementDiff; + var heightBiasDiffs = computeBiasValues(min.height.val - bb.h, topVal, bottomVal); + var diffTop = heightBiasDiffs.biasDiff; + var diffBottom = heightBiasDiffs.biasComplementDiff; + _p.autoPadding = computePaddingValues(bb.w, bb.h, parent.pstyle('padding'), parent.pstyle('padding-relative-to').value); + _p.autoWidth = Math.max(bb.w, min.width.val); + pos.x = (-diffLeft + bb.x1 + bb.x2 + diffRight) / 2; + _p.autoHeight = Math.max(bb.h, min.height.val); + pos.y = (-diffTop + bb.y1 + bb.y2 + diffBottom) / 2; + } + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var _p = ele._private; + if (!_p.compoundBoundsClean || force) { + update(ele); + if (!cy.batching()) { + _p.compoundBoundsClean = true; + } + } + } + return this; + }; + var noninf = function noninf(x) { + if (x === Infinity || x === -Infinity) { + return 0; + } + return x; + }; + var updateBounds = function updateBounds(b, x1, y1, x2, y2) { + // don't update with zero area boxes + if (x2 - x1 === 0 || y2 - y1 === 0) { + return; + } + + // don't update with null dim + if (x1 == null || y1 == null || x2 == null || y2 == null) { + return; + } + b.x1 = x1 < b.x1 ? x1 : b.x1; + b.x2 = x2 > b.x2 ? x2 : b.x2; + b.y1 = y1 < b.y1 ? y1 : b.y1; + b.y2 = y2 > b.y2 ? y2 : b.y2; + b.w = b.x2 - b.x1; + b.h = b.y2 - b.y1; + }; + var updateBoundsFromBox = function updateBoundsFromBox(b, b2) { + if (b2 == null) { + return b; + } + return updateBounds(b, b2.x1, b2.y1, b2.x2, b2.y2); + }; + var prefixedProperty = function prefixedProperty(obj, field, prefix) { + return getPrefixedProperty(obj, field, prefix); + }; + var updateBoundsFromArrow = function updateBoundsFromArrow(bounds, ele, prefix) { + if (ele.cy().headless()) { + return; + } + var _p = ele._private; + var rstyle = _p.rstyle; + var halfArW = rstyle.arrowWidth / 2; + var arrowType = ele.pstyle(prefix + '-arrow-shape').value; + var x; + var y; + if (arrowType !== 'none') { + if (prefix === 'source') { + x = rstyle.srcX; + y = rstyle.srcY; + } else if (prefix === 'target') { + x = rstyle.tgtX; + y = rstyle.tgtY; + } else { + x = rstyle.midX; + y = rstyle.midY; + } + + // always store the individual arrow bounds + var bbs = _p.arrowBounds = _p.arrowBounds || {}; + var bb = bbs[prefix] = bbs[prefix] || {}; + bb.x1 = x - halfArW; + bb.y1 = y - halfArW; + bb.x2 = x + halfArW; + bb.y2 = y + halfArW; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + expandBoundingBox(bb, 1); + updateBounds(bounds, bb.x1, bb.y1, bb.x2, bb.y2); + } + }; + var updateBoundsFromLabel = function updateBoundsFromLabel(bounds, ele, prefix) { + if (ele.cy().headless()) { + return; + } + var prefixDash; + if (prefix) { + prefixDash = prefix + '-'; + } else { + prefixDash = ''; + } + var _p = ele._private; + var rstyle = _p.rstyle; + var label = ele.pstyle(prefixDash + 'label').strValue; + if (label) { + var halign = ele.pstyle('text-halign'); + var valign = ele.pstyle('text-valign'); + var labelWidth = prefixedProperty(rstyle, 'labelWidth', prefix); + var labelHeight = prefixedProperty(rstyle, 'labelHeight', prefix); + var labelX = prefixedProperty(rstyle, 'labelX', prefix); + var labelY = prefixedProperty(rstyle, 'labelY', prefix); + var marginX = ele.pstyle(prefixDash + 'text-margin-x').pfValue; + var marginY = ele.pstyle(prefixDash + 'text-margin-y').pfValue; + var isEdge = ele.isEdge(); + var rotation = ele.pstyle(prefixDash + 'text-rotation'); + var outlineWidth = ele.pstyle('text-outline-width').pfValue; + var borderWidth = ele.pstyle('text-border-width').pfValue; + var halfBorderWidth = borderWidth / 2; + var padding = ele.pstyle('text-background-padding').pfValue; + var marginOfError = 2; // expand to work around browser dimension inaccuracies + + var lh = labelHeight; + var lw = labelWidth; + var lw_2 = lw / 2; + var lh_2 = lh / 2; + var lx1, lx2, ly1, ly2; + if (isEdge) { + lx1 = labelX - lw_2; + lx2 = labelX + lw_2; + ly1 = labelY - lh_2; + ly2 = labelY + lh_2; + } else { + switch (halign.value) { + case 'left': + lx1 = labelX - lw; + lx2 = labelX; + break; + case 'center': + lx1 = labelX - lw_2; + lx2 = labelX + lw_2; + break; + case 'right': + lx1 = labelX; + lx2 = labelX + lw; + break; + } + switch (valign.value) { + case 'top': + ly1 = labelY - lh; + ly2 = labelY; + break; + case 'center': + ly1 = labelY - lh_2; + ly2 = labelY + lh_2; + break; + case 'bottom': + ly1 = labelY; + ly2 = labelY + lh; + break; + } + } + + // shift by margin and expand by outline and border + lx1 += marginX - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError; + lx2 += marginX + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError; + ly1 += marginY - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError; + ly2 += marginY + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError; + + // always store the unrotated label bounds separately + var bbPrefix = prefix || 'main'; + var bbs = _p.labelBounds; + var bb = bbs[bbPrefix] = bbs[bbPrefix] || {}; + bb.x1 = lx1; + bb.y1 = ly1; + bb.x2 = lx2; + bb.y2 = ly2; + bb.w = lx2 - lx1; + bb.h = ly2 - ly1; + var isAutorotate = isEdge && rotation.strValue === 'autorotate'; + var isPfValue = rotation.pfValue != null && rotation.pfValue !== 0; + if (isAutorotate || isPfValue) { + var theta = isAutorotate ? prefixedProperty(_p.rstyle, 'labelAngle', prefix) : rotation.pfValue; + var cos = Math.cos(theta); + var sin = Math.sin(theta); + + // rotation point (default value for center-center) + var xo = (lx1 + lx2) / 2; + var yo = (ly1 + ly2) / 2; + if (!isEdge) { + switch (halign.value) { + case 'left': + xo = lx2; + break; + case 'right': + xo = lx1; + break; + } + switch (valign.value) { + case 'top': + yo = ly2; + break; + case 'bottom': + yo = ly1; + break; + } + } + var rotate = function rotate(x, y) { + x = x - xo; + y = y - yo; + return { + x: x * cos - y * sin + xo, + y: x * sin + y * cos + yo + }; + }; + var px1y1 = rotate(lx1, ly1); + var px1y2 = rotate(lx1, ly2); + var px2y1 = rotate(lx2, ly1); + var px2y2 = rotate(lx2, ly2); + lx1 = Math.min(px1y1.x, px1y2.x, px2y1.x, px2y2.x); + lx2 = Math.max(px1y1.x, px1y2.x, px2y1.x, px2y2.x); + ly1 = Math.min(px1y1.y, px1y2.y, px2y1.y, px2y2.y); + ly2 = Math.max(px1y1.y, px1y2.y, px2y1.y, px2y2.y); + } + var bbPrefixRot = bbPrefix + 'Rot'; + var bbRot = bbs[bbPrefixRot] = bbs[bbPrefixRot] || {}; + bbRot.x1 = lx1; + bbRot.y1 = ly1; + bbRot.x2 = lx2; + bbRot.y2 = ly2; + bbRot.w = lx2 - lx1; + bbRot.h = ly2 - ly1; + updateBounds(bounds, lx1, ly1, lx2, ly2); + updateBounds(_p.labelBounds.all, lx1, ly1, lx2, ly2); + } + return bounds; + }; + + // get the bounding box of the elements (in raw model position) + var boundingBoxImpl = function boundingBoxImpl(ele, options) { + var cy = ele._private.cy; + var styleEnabled = cy.styleEnabled(); + var headless = cy.headless(); + var bounds = makeBoundingBox(); + var _p = ele._private; + var isNode = ele.isNode(); + var isEdge = ele.isEdge(); + var ex1, ex2, ey1, ey2; // extrema of body / lines + var x, y; // node pos + var rstyle = _p.rstyle; + var manualExpansion = isNode && styleEnabled ? ele.pstyle('bounds-expansion').pfValue : [0]; + + // must use `display` prop only, as reading `compound.width()` causes recursion + // (other factors like width values will be considered later in this function anyway) + var isDisplayed = function isDisplayed(ele) { + return ele.pstyle('display').value !== 'none'; + }; + var displayed = !styleEnabled || isDisplayed(ele) + + // must take into account connected nodes b/c of implicit edge hiding on display:none node + && (!isEdge || isDisplayed(ele.source()) && isDisplayed(ele.target())); + if (displayed) { + // displayed suffices, since we will find zero area eles anyway + var overlayOpacity = 0; + var overlayPadding = 0; + if (styleEnabled && options.includeOverlays) { + overlayOpacity = ele.pstyle('overlay-opacity').value; + if (overlayOpacity !== 0) { + overlayPadding = ele.pstyle('overlay-padding').value; + } + } + var underlayOpacity = 0; + var underlayPadding = 0; + if (styleEnabled && options.includeUnderlays) { + underlayOpacity = ele.pstyle('underlay-opacity').value; + if (underlayOpacity !== 0) { + underlayPadding = ele.pstyle('underlay-padding').value; + } + } + var padding = Math.max(overlayPadding, underlayPadding); + var w = 0; + var wHalf = 0; + if (styleEnabled) { + w = ele.pstyle('width').pfValue; + wHalf = w / 2; + } + if (isNode && options.includeNodes) { + var pos = ele.position(); + x = pos.x; + y = pos.y; + var _w = ele.outerWidth(); + var halfW = _w / 2; + var h = ele.outerHeight(); + var halfH = h / 2; + + // handle node dimensions + ///////////////////////// + + ex1 = x - halfW; + ex2 = x + halfW; + ey1 = y - halfH; + ey2 = y + halfH; + updateBounds(bounds, ex1, ey1, ex2, ey2); + } else if (isEdge && options.includeEdges) { + if (styleEnabled && !headless) { + var curveStyle = ele.pstyle('curve-style').strValue; + + // handle edge dimensions (rough box estimate) + ////////////////////////////////////////////// + + ex1 = Math.min(rstyle.srcX, rstyle.midX, rstyle.tgtX); + ex2 = Math.max(rstyle.srcX, rstyle.midX, rstyle.tgtX); + ey1 = Math.min(rstyle.srcY, rstyle.midY, rstyle.tgtY); + ey2 = Math.max(rstyle.srcY, rstyle.midY, rstyle.tgtY); + + // take into account edge width + ex1 -= wHalf; + ex2 += wHalf; + ey1 -= wHalf; + ey2 += wHalf; + updateBounds(bounds, ex1, ey1, ex2, ey2); + + // precise edges + //////////////// + + if (curveStyle === 'haystack') { + var hpts = rstyle.haystackPts; + if (hpts && hpts.length === 2) { + ex1 = hpts[0].x; + ey1 = hpts[0].y; + ex2 = hpts[1].x; + ey2 = hpts[1].y; + if (ex1 > ex2) { + var temp = ex1; + ex1 = ex2; + ex2 = temp; + } + if (ey1 > ey2) { + var _temp = ey1; + ey1 = ey2; + ey2 = _temp; + } + updateBounds(bounds, ex1 - wHalf, ey1 - wHalf, ex2 + wHalf, ey2 + wHalf); + } + } else if (curveStyle === 'bezier' || curveStyle === 'unbundled-bezier' || curveStyle === 'segments' || curveStyle === 'taxi') { + var pts; + switch (curveStyle) { + case 'bezier': + case 'unbundled-bezier': + pts = rstyle.bezierPts; + break; + case 'segments': + case 'taxi': + pts = rstyle.linePts; + break; + } + if (pts != null) { + for (var j = 0; j < pts.length; j++) { + var pt = pts[j]; + ex1 = pt.x - wHalf; + ex2 = pt.x + wHalf; + ey1 = pt.y - wHalf; + ey2 = pt.y + wHalf; + updateBounds(bounds, ex1, ey1, ex2, ey2); + } + } + } // bezier-like or segment-like edge + } else { + // headless or style disabled + + // fallback on source and target positions + ////////////////////////////////////////// + + var n1 = ele.source(); + var n1pos = n1.position(); + var n2 = ele.target(); + var n2pos = n2.position(); + ex1 = n1pos.x; + ex2 = n2pos.x; + ey1 = n1pos.y; + ey2 = n2pos.y; + if (ex1 > ex2) { + var _temp2 = ex1; + ex1 = ex2; + ex2 = _temp2; + } + if (ey1 > ey2) { + var _temp3 = ey1; + ey1 = ey2; + ey2 = _temp3; + } + + // take into account edge width + ex1 -= wHalf; + ex2 += wHalf; + ey1 -= wHalf; + ey2 += wHalf; + updateBounds(bounds, ex1, ey1, ex2, ey2); + } // headless or style disabled + } // edges + + // handle edge arrow size + ///////////////////////// + + if (styleEnabled && options.includeEdges && isEdge) { + updateBoundsFromArrow(bounds, ele, 'mid-source'); + updateBoundsFromArrow(bounds, ele, 'mid-target'); + updateBoundsFromArrow(bounds, ele, 'source'); + updateBoundsFromArrow(bounds, ele, 'target'); + } + + // ghost + //////// + + if (styleEnabled) { + var ghost = ele.pstyle('ghost').value === 'yes'; + if (ghost) { + var gx = ele.pstyle('ghost-offset-x').pfValue; + var gy = ele.pstyle('ghost-offset-y').pfValue; + updateBounds(bounds, bounds.x1 + gx, bounds.y1 + gy, bounds.x2 + gx, bounds.y2 + gy); + } + } + + // always store the body bounds separately from the labels + var bbBody = _p.bodyBounds = _p.bodyBounds || {}; + assignBoundingBox(bbBody, bounds); + expandBoundingBoxSides(bbBody, manualExpansion); + expandBoundingBox(bbBody, 1); // expand to work around browser dimension inaccuracies + + // overlay + ////////// + + if (styleEnabled) { + ex1 = bounds.x1; + ex2 = bounds.x2; + ey1 = bounds.y1; + ey2 = bounds.y2; + updateBounds(bounds, ex1 - padding, ey1 - padding, ex2 + padding, ey2 + padding); + } + + // always store the body bounds separately from the labels + var bbOverlay = _p.overlayBounds = _p.overlayBounds || {}; + assignBoundingBox(bbOverlay, bounds); + expandBoundingBoxSides(bbOverlay, manualExpansion); + expandBoundingBox(bbOverlay, 1); // expand to work around browser dimension inaccuracies + + // handle label dimensions + ////////////////////////// + + var bbLabels = _p.labelBounds = _p.labelBounds || {}; + if (bbLabels.all != null) { + clearBoundingBox(bbLabels.all); + } else { + bbLabels.all = makeBoundingBox(); + } + if (styleEnabled && options.includeLabels) { + if (options.includeMainLabels) { + updateBoundsFromLabel(bounds, ele, null); + } + if (isEdge) { + if (options.includeSourceLabels) { + updateBoundsFromLabel(bounds, ele, 'source'); + } + if (options.includeTargetLabels) { + updateBoundsFromLabel(bounds, ele, 'target'); + } + } + } // style enabled for labels + } // if displayed + + bounds.x1 = noninf(bounds.x1); + bounds.y1 = noninf(bounds.y1); + bounds.x2 = noninf(bounds.x2); + bounds.y2 = noninf(bounds.y2); + bounds.w = noninf(bounds.x2 - bounds.x1); + bounds.h = noninf(bounds.y2 - bounds.y1); + if (bounds.w > 0 && bounds.h > 0 && displayed) { + expandBoundingBoxSides(bounds, manualExpansion); + + // expand bounds by 1 because antialiasing can increase the visual/effective size by 1 on all sides + expandBoundingBox(bounds, 1); + } + return bounds; + }; + var getKey = function getKey(opts) { + var i = 0; + var tf = function tf(val) { + return (val ? 1 : 0) << i++; + }; + var key = 0; + key += tf(opts.incudeNodes); + key += tf(opts.includeEdges); + key += tf(opts.includeLabels); + key += tf(opts.includeMainLabels); + key += tf(opts.includeSourceLabels); + key += tf(opts.includeTargetLabels); + key += tf(opts.includeOverlays); + return key; + }; + var getBoundingBoxPosKey = function getBoundingBoxPosKey(ele) { + if (ele.isEdge()) { + var p1 = ele.source().position(); + var p2 = ele.target().position(); + var r = function r(x) { + return Math.round(x); + }; + return hashIntsArray([r(p1.x), r(p1.y), r(p2.x), r(p2.y)]); + } else { + return 0; + } + }; + var cachedBoundingBoxImpl = function cachedBoundingBoxImpl(ele, opts) { + var _p = ele._private; + var bb; + var isEdge = ele.isEdge(); + var key = opts == null ? defBbOptsKey : getKey(opts); + var usingDefOpts = key === defBbOptsKey; + var currPosKey = getBoundingBoxPosKey(ele); + var isPosKeySame = _p.bbCachePosKey === currPosKey; + var useCache = opts.useCache && isPosKeySame; + var isDirty = function isDirty(ele) { + return ele._private.bbCache == null || ele._private.styleDirty; + }; + var needRecalc = !useCache || isDirty(ele) || isEdge && isDirty(ele.source()) || isDirty(ele.target()); + if (needRecalc) { + if (!isPosKeySame) { + ele.recalculateRenderedStyle(useCache); + } + bb = boundingBoxImpl(ele, defBbOpts); + _p.bbCache = bb; + _p.bbCachePosKey = currPosKey; + } else { + bb = _p.bbCache; + } + + // not using def opts => need to build up bb from combination of sub bbs + if (!usingDefOpts) { + var isNode = ele.isNode(); + bb = makeBoundingBox(); + if (opts.includeNodes && isNode || opts.includeEdges && !isNode) { + if (opts.includeOverlays) { + updateBoundsFromBox(bb, _p.overlayBounds); + } else { + updateBoundsFromBox(bb, _p.bodyBounds); + } + } + if (opts.includeLabels) { + if (opts.includeMainLabels && (!isEdge || opts.includeSourceLabels && opts.includeTargetLabels)) { + updateBoundsFromBox(bb, _p.labelBounds.all); + } else { + if (opts.includeMainLabels) { + updateBoundsFromBox(bb, _p.labelBounds.mainRot); + } + if (opts.includeSourceLabels) { + updateBoundsFromBox(bb, _p.labelBounds.sourceRot); + } + if (opts.includeTargetLabels) { + updateBoundsFromBox(bb, _p.labelBounds.targetRot); + } + } + } + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + } + return bb; + }; + var defBbOpts = { + includeNodes: true, + includeEdges: true, + includeLabels: true, + includeMainLabels: true, + includeSourceLabels: true, + includeTargetLabels: true, + includeOverlays: true, + includeUnderlays: true, + useCache: true + }; + var defBbOptsKey = getKey(defBbOpts); + var filledBbOpts = defaults$g(defBbOpts); + elesfn$b.boundingBox = function (options) { + var bounds; + + // the main usecase is ele.boundingBox() for a single element with no/def options + // specified s.t. the cache is used, so check for this case to make it faster by + // avoiding the overhead of the rest of the function + if (this.length === 1 && this[0]._private.bbCache != null && !this[0]._private.styleDirty && (options === undefined || options.useCache === undefined || options.useCache === true)) { + if (options === undefined) { + options = defBbOpts; + } else { + options = filledBbOpts(options); + } + bounds = cachedBoundingBoxImpl(this[0], options); + } else { + bounds = makeBoundingBox(); + options = options || defBbOpts; + var opts = filledBbOpts(options); + var eles = this; + var cy = eles.cy(); + var styleEnabled = cy.styleEnabled(); + if (styleEnabled) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _p = ele._private; + var currPosKey = getBoundingBoxPosKey(ele); + var isPosKeySame = _p.bbCachePosKey === currPosKey; + var useCache = opts.useCache && isPosKeySame && !_p.styleDirty; + ele.recalculateRenderedStyle(useCache); + } + } + this.updateCompoundBounds(!options.useCache); + for (var _i = 0; _i < eles.length; _i++) { + var _ele = eles[_i]; + updateBoundsFromBox(bounds, cachedBoundingBoxImpl(_ele, opts)); + } + } + bounds.x1 = noninf(bounds.x1); + bounds.y1 = noninf(bounds.y1); + bounds.x2 = noninf(bounds.x2); + bounds.y2 = noninf(bounds.y2); + bounds.w = noninf(bounds.x2 - bounds.x1); + bounds.h = noninf(bounds.y2 - bounds.y1); + return bounds; + }; + elesfn$b.dirtyBoundingBoxCache = function () { + for (var i = 0; i < this.length; i++) { + var _p = this[i]._private; + _p.bbCache = null; + _p.bbCachePosKey = null; + _p.bodyBounds = null; + _p.overlayBounds = null; + _p.labelBounds.all = null; + _p.labelBounds.source = null; + _p.labelBounds.target = null; + _p.labelBounds.main = null; + _p.labelBounds.sourceRot = null; + _p.labelBounds.targetRot = null; + _p.labelBounds.mainRot = null; + _p.arrowBounds.source = null; + _p.arrowBounds.target = null; + _p.arrowBounds['mid-source'] = null; + _p.arrowBounds['mid-target'] = null; + } + this.emitAndNotify('bounds'); + return this; + }; + + // private helper to get bounding box for custom node positions + // - good for perf in certain cases but currently requires dirtying the rendered style + // - would be better to not modify the nodes but the nodes are read directly everywhere in the renderer... + // - try to use for only things like discrete layouts where the node position would change anyway + elesfn$b.boundingBoxAt = function (fn) { + var nodes = this.nodes(); + var cy = this.cy(); + var hasCompoundNodes = cy.hasCompoundNodes(); + var parents = cy.collection(); + if (hasCompoundNodes) { + parents = nodes.filter(function (node) { + return node.isParent(); + }); + nodes = nodes.not(parents); + } + if (plainObject(fn)) { + var obj = fn; + fn = function fn() { + return obj; + }; + } + var storeOldPos = function storeOldPos(node, i) { + return node._private.bbAtOldPos = fn(node, i); + }; + var getOldPos = function getOldPos(node) { + return node._private.bbAtOldPos; + }; + cy.startBatch(); + nodes.forEach(storeOldPos).silentPositions(fn); + if (hasCompoundNodes) { + parents.dirtyCompoundBoundsCache(); + parents.dirtyBoundingBoxCache(); + parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle + } + + var bb = copyBoundingBox(this.boundingBox({ + useCache: false + })); + nodes.silentPositions(getOldPos); + if (hasCompoundNodes) { + parents.dirtyCompoundBoundsCache(); + parents.dirtyBoundingBoxCache(); + parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle + } + + cy.endBatch(); + return bb; + }; + fn$3.boundingbox = fn$3.bb = fn$3.boundingBox; + fn$3.renderedBoundingbox = fn$3.renderedBoundingBox; + var bounds = elesfn$b; + + var fn$2, elesfn$a; + fn$2 = elesfn$a = {}; + var defineDimFns = function defineDimFns(opts) { + opts.uppercaseName = capitalize(opts.name); + opts.autoName = 'auto' + opts.uppercaseName; + opts.labelName = 'label' + opts.uppercaseName; + opts.outerName = 'outer' + opts.uppercaseName; + opts.uppercaseOuterName = capitalize(opts.outerName); + fn$2[opts.name] = function dimImpl() { + var ele = this[0]; + var _p = ele._private; + var cy = _p.cy; + var styleEnabled = cy._private.styleEnabled; + if (ele) { + if (styleEnabled) { + if (ele.isParent()) { + ele.updateCompoundBounds(); + return _p[opts.autoName] || 0; + } + var d = ele.pstyle(opts.name); + switch (d.strValue) { + case 'label': + ele.recalculateRenderedStyle(); + return _p.rstyle[opts.labelName] || 0; + default: + return d.pfValue; + } + } else { + return 1; + } + } + }; + fn$2['outer' + opts.uppercaseName] = function outerDimImpl() { + var ele = this[0]; + var _p = ele._private; + var cy = _p.cy; + var styleEnabled = cy._private.styleEnabled; + if (ele) { + if (styleEnabled) { + var dim = ele[opts.name](); + var border = ele.pstyle('border-width').pfValue; // n.b. 1/2 each side + var padding = 2 * ele.padding(); + return dim + border + padding; + } else { + return 1; + } + } + }; + fn$2['rendered' + opts.uppercaseName] = function renderedDimImpl() { + var ele = this[0]; + if (ele) { + var d = ele[opts.name](); + return d * this.cy().zoom(); + } + }; + fn$2['rendered' + opts.uppercaseOuterName] = function renderedOuterDimImpl() { + var ele = this[0]; + if (ele) { + var od = ele[opts.outerName](); + return od * this.cy().zoom(); + } + }; + }; + defineDimFns({ + name: 'width' + }); + defineDimFns({ + name: 'height' + }); + elesfn$a.padding = function () { + var ele = this[0]; + var _p = ele._private; + if (ele.isParent()) { + ele.updateCompoundBounds(); + if (_p.autoPadding !== undefined) { + return _p.autoPadding; + } else { + return ele.pstyle('padding').pfValue; + } + } else { + return ele.pstyle('padding').pfValue; + } + }; + elesfn$a.paddedHeight = function () { + var ele = this[0]; + return ele.height() + 2 * ele.padding(); + }; + elesfn$a.paddedWidth = function () { + var ele = this[0]; + return ele.width() + 2 * ele.padding(); + }; + var widthHeight = elesfn$a; + + var ifEdge = function ifEdge(ele, getValue) { + if (ele.isEdge()) { + return getValue(ele); + } + }; + var ifEdgeRenderedPosition = function ifEdgeRenderedPosition(ele, getPoint) { + if (ele.isEdge()) { + var cy = ele.cy(); + return modelToRenderedPosition(getPoint(ele), cy.zoom(), cy.pan()); + } + }; + var ifEdgeRenderedPositions = function ifEdgeRenderedPositions(ele, getPoints) { + if (ele.isEdge()) { + var cy = ele.cy(); + var pan = cy.pan(); + var zoom = cy.zoom(); + return getPoints(ele).map(function (p) { + return modelToRenderedPosition(p, zoom, pan); + }); + } + }; + var controlPoints = function controlPoints(ele) { + return ele.renderer().getControlPoints(ele); + }; + var segmentPoints = function segmentPoints(ele) { + return ele.renderer().getSegmentPoints(ele); + }; + var sourceEndpoint = function sourceEndpoint(ele) { + return ele.renderer().getSourceEndpoint(ele); + }; + var targetEndpoint = function targetEndpoint(ele) { + return ele.renderer().getTargetEndpoint(ele); + }; + var midpoint = function midpoint(ele) { + return ele.renderer().getEdgeMidpoint(ele); + }; + var pts = { + controlPoints: { + get: controlPoints, + mult: true + }, + segmentPoints: { + get: segmentPoints, + mult: true + }, + sourceEndpoint: { + get: sourceEndpoint + }, + targetEndpoint: { + get: targetEndpoint + }, + midpoint: { + get: midpoint + } + }; + var renderedName = function renderedName(name) { + return 'rendered' + name[0].toUpperCase() + name.substr(1); + }; + var edgePoints = Object.keys(pts).reduce(function (obj, name) { + var spec = pts[name]; + var rName = renderedName(name); + obj[name] = function () { + return ifEdge(this, spec.get); + }; + if (spec.mult) { + obj[rName] = function () { + return ifEdgeRenderedPositions(this, spec.get); + }; + } else { + obj[rName] = function () { + return ifEdgeRenderedPosition(this, spec.get); + }; + } + return obj; + }, {}); + + var dimensions = extend({}, position, bounds, widthHeight, edgePoints); + + /*! + Event object based on jQuery events, MIT license + + https://jquery.org/license/ + https://tldrlegal.com/license/mit-license + https://github.com/jquery/jquery/blob/master/src/event.js + */ + + var Event = function Event(src, props) { + this.recycle(src, props); + }; + function returnFalse() { + return false; + } + function returnTrue() { + return true; + } + + // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html + Event.prototype = { + instanceString: function instanceString() { + return 'event'; + }, + recycle: function recycle(src, props) { + this.isImmediatePropagationStopped = this.isPropagationStopped = this.isDefaultPrevented = returnFalse; + if (src != null && src.preventDefault) { + // Browser Event object + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented ? returnTrue : returnFalse; + } else if (src != null && src.type) { + // Plain object containing all event details + props = src; + } else { + // Event string + this.type = src; + } + + // Put explicitly provided properties onto the event object + if (props != null) { + // more efficient to manually copy fields we use + this.originalEvent = props.originalEvent; + this.type = props.type != null ? props.type : this.type; + this.cy = props.cy; + this.target = props.target; + this.position = props.position; + this.renderedPosition = props.renderedPosition; + this.namespace = props.namespace; + this.layout = props.layout; + } + if (this.cy != null && this.position != null && this.renderedPosition == null) { + // create a rendered position based on the passed position + var pos = this.position; + var zoom = this.cy.zoom(); + var pan = this.cy.pan(); + this.renderedPosition = { + x: pos.x * zoom + pan.x, + y: pos.y * zoom + pan.y + }; + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + }, + preventDefault: function preventDefault() { + this.isDefaultPrevented = returnTrue; + var e = this.originalEvent; + if (!e) { + return; + } + + // if preventDefault exists run it on the original event + if (e.preventDefault) { + e.preventDefault(); + } + }, + stopPropagation: function stopPropagation() { + this.isPropagationStopped = returnTrue; + var e = this.originalEvent; + if (!e) { + return; + } + + // if stopPropagation exists run it on the original event + if (e.stopPropagation) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function stopImmediatePropagation() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse + }; + + var eventRegex = /^([^.]+)(\.(?:[^.]+))?$/; // regex for matching event strings (e.g. "click.namespace") + var universalNamespace = '.*'; // matches as if no namespace specified and prevents users from unbinding accidentally + + var defaults$8 = { + qualifierCompare: function qualifierCompare(q1, q2) { + return q1 === q2; + }, + eventMatches: function eventMatches( /*context, listener, eventObj*/ + ) { + return true; + }, + addEventFields: function addEventFields( /*context, evt*/ + ) {}, + callbackContext: function callbackContext(context /*, listener, eventObj*/) { + return context; + }, + beforeEmit: function beforeEmit( /* context, listener, eventObj */ + ) {}, + afterEmit: function afterEmit( /* context, listener, eventObj */ + ) {}, + bubble: function bubble( /*context*/ + ) { + return false; + }, + parent: function parent( /*context*/ + ) { + return null; + }, + context: null + }; + var defaultsKeys = Object.keys(defaults$8); + var emptyOpts = {}; + function Emitter() { + var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : emptyOpts; + var context = arguments.length > 1 ? arguments[1] : undefined; + // micro-optimisation vs Object.assign() -- reduces Element instantiation time + for (var i = 0; i < defaultsKeys.length; i++) { + var key = defaultsKeys[i]; + this[key] = opts[key] || defaults$8[key]; + } + this.context = context || this.context; + this.listeners = []; + this.emitting = 0; + } + var p = Emitter.prototype; + var forEachEvent = function forEachEvent(self, handler, events, qualifier, callback, conf, confOverrides) { + if (fn$6(qualifier)) { + callback = qualifier; + qualifier = null; + } + if (confOverrides) { + if (conf == null) { + conf = confOverrides; + } else { + conf = extend({}, conf, confOverrides); + } + } + var eventList = array(events) ? events : events.split(/\s+/); + for (var i = 0; i < eventList.length; i++) { + var evt = eventList[i]; + if (emptyString(evt)) { + continue; + } + var match = evt.match(eventRegex); // type[.namespace] + + if (match) { + var type = match[1]; + var namespace = match[2] ? match[2] : null; + var ret = handler(self, evt, type, namespace, qualifier, callback, conf); + if (ret === false) { + break; + } // allow exiting early + } + } + }; + + var makeEventObj = function makeEventObj(self, obj) { + self.addEventFields(self.context, obj); + return new Event(obj.type, obj); + }; + var forEachEventObj = function forEachEventObj(self, handler, events) { + if (event(events)) { + handler(self, events); + return; + } else if (plainObject(events)) { + handler(self, makeEventObj(self, events)); + return; + } + var eventList = array(events) ? events : events.split(/\s+/); + for (var i = 0; i < eventList.length; i++) { + var evt = eventList[i]; + if (emptyString(evt)) { + continue; + } + var match = evt.match(eventRegex); // type[.namespace] + + if (match) { + var type = match[1]; + var namespace = match[2] ? match[2] : null; + var eventObj = makeEventObj(self, { + type: type, + namespace: namespace, + target: self.context + }); + handler(self, eventObj); + } + } + }; + p.on = p.addListener = function (events, qualifier, callback, conf, confOverrides) { + forEachEvent(this, function (self, event, type, namespace, qualifier, callback, conf) { + if (fn$6(callback)) { + self.listeners.push({ + event: event, + // full event string + callback: callback, + // callback to run + type: type, + // the event type (e.g. 'click') + namespace: namespace, + // the event namespace (e.g. ".foo") + qualifier: qualifier, + // a restriction on whether to match this emitter + conf: conf // additional configuration + }); + } + }, events, qualifier, callback, conf, confOverrides); + return this; + }; + p.one = function (events, qualifier, callback, conf) { + return this.on(events, qualifier, callback, conf, { + one: true + }); + }; + p.removeListener = p.off = function (events, qualifier, callback, conf) { + var _this = this; + if (this.emitting !== 0) { + this.listeners = copyArray$1(this.listeners); + } + var listeners = this.listeners; + var _loop = function _loop(i) { + var listener = listeners[i]; + forEachEvent(_this, function (self, event, type, namespace, qualifier, callback /*, conf*/) { + if ((listener.type === type || events === '*') && (!namespace && listener.namespace !== '.*' || listener.namespace === namespace) && (!qualifier || self.qualifierCompare(listener.qualifier, qualifier)) && (!callback || listener.callback === callback)) { + listeners.splice(i, 1); + return false; + } + }, events, qualifier, callback, conf); + }; + for (var i = listeners.length - 1; i >= 0; i--) { + _loop(i); + } + return this; + }; + p.removeAllListeners = function () { + return this.removeListener('*'); + }; + p.emit = p.trigger = function (events, extraParams, manualCallback) { + var listeners = this.listeners; + var numListenersBeforeEmit = listeners.length; + this.emitting++; + if (!array(extraParams)) { + extraParams = [extraParams]; + } + forEachEventObj(this, function (self, eventObj) { + if (manualCallback != null) { + listeners = [{ + event: eventObj.event, + type: eventObj.type, + namespace: eventObj.namespace, + callback: manualCallback + }]; + numListenersBeforeEmit = listeners.length; + } + var _loop2 = function _loop2(i) { + var listener = listeners[i]; + if (listener.type === eventObj.type && (!listener.namespace || listener.namespace === eventObj.namespace || listener.namespace === universalNamespace) && self.eventMatches(self.context, listener, eventObj)) { + var args = [eventObj]; + if (extraParams != null) { + push(args, extraParams); + } + self.beforeEmit(self.context, listener, eventObj); + if (listener.conf && listener.conf.one) { + self.listeners = self.listeners.filter(function (l) { + return l !== listener; + }); + } + var context = self.callbackContext(self.context, listener, eventObj); + var ret = listener.callback.apply(context, args); + self.afterEmit(self.context, listener, eventObj); + if (ret === false) { + eventObj.stopPropagation(); + eventObj.preventDefault(); + } + } // if listener matches + }; + for (var i = 0; i < numListenersBeforeEmit; i++) { + _loop2(i); + } // for listener + + if (self.bubble(self.context) && !eventObj.isPropagationStopped()) { + self.parent(self.context).emit(eventObj, extraParams); + } + }, events); + this.emitting--; + return this; + }; + + var emitterOptions$1 = { + qualifierCompare: function qualifierCompare(selector1, selector2) { + if (selector1 == null || selector2 == null) { + return selector1 == null && selector2 == null; + } else { + return selector1.sameText(selector2); + } + }, + eventMatches: function eventMatches(ele, listener, eventObj) { + var selector = listener.qualifier; + if (selector != null) { + return ele !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target); + } + return true; + }, + addEventFields: function addEventFields(ele, evt) { + evt.cy = ele.cy(); + evt.target = ele; + }, + callbackContext: function callbackContext(ele, listener, eventObj) { + return listener.qualifier != null ? eventObj.target : ele; + }, + beforeEmit: function beforeEmit(context, listener /*, eventObj*/) { + if (listener.conf && listener.conf.once) { + listener.conf.onceCollection.removeListener(listener.event, listener.qualifier, listener.callback); + } + }, + bubble: function bubble() { + return true; + }, + parent: function parent(ele) { + return ele.isChild() ? ele.parent() : ele.cy(); + } + }; + var argSelector$1 = function argSelector(arg) { + if (string(arg)) { + return new Selector(arg); + } else { + return arg; + } + }; + var elesfn$9 = { + createEmitter: function createEmitter() { + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var _p = ele._private; + if (!_p.emitter) { + _p.emitter = new Emitter(emitterOptions$1, ele); + } + } + return this; + }, + emitter: function emitter() { + return this._private.emitter; + }, + on: function on(events, selector, callback) { + var argSel = argSelector$1(selector); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().on(events, argSel, callback); + } + return this; + }, + removeListener: function removeListener(events, selector, callback) { + var argSel = argSelector$1(selector); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().removeListener(events, argSel, callback); + } + return this; + }, + removeAllListeners: function removeAllListeners() { + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().removeAllListeners(); + } + return this; + }, + one: function one(events, selector, callback) { + var argSel = argSelector$1(selector); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().one(events, argSel, callback); + } + return this; + }, + once: function once(events, selector, callback) { + var argSel = argSelector$1(selector); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().on(events, argSel, callback, { + once: true, + onceCollection: this + }); + } + }, + emit: function emit(events, extraParams) { + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + ele.emitter().emit(events, extraParams); + } + return this; + }, + emitAndNotify: function emitAndNotify(event, extraParams) { + // for internal use only + if (this.length === 0) { + return; + } // empty collections don't need to notify anything + + // notify renderer + this.cy().notify(event, this); + this.emit(event, extraParams); + return this; + } + }; + define.eventAliasesOn(elesfn$9); + + var elesfn$8 = { + nodes: function nodes(selector) { + return this.filter(function (ele) { + return ele.isNode(); + }).filter(selector); + }, + edges: function edges(selector) { + return this.filter(function (ele) { + return ele.isEdge(); + }).filter(selector); + }, + // internal helper to get nodes and edges as separate collections with single iteration over elements + byGroup: function byGroup() { + var nodes = this.spawn(); + var edges = this.spawn(); + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + if (ele.isNode()) { + nodes.push(ele); + } else { + edges.push(ele); + } + } + return { + nodes: nodes, + edges: edges + }; + }, + filter: function filter(_filter, thisArg) { + if (_filter === undefined) { + // check this first b/c it's the most common/performant case + return this; + } else if (string(_filter) || elementOrCollection(_filter)) { + return new Selector(_filter).filter(this); + } else if (fn$6(_filter)) { + var filterEles = this.spawn(); + var eles = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var include = thisArg ? _filter.apply(thisArg, [ele, i, eles]) : _filter(ele, i, eles); + if (include) { + filterEles.push(ele); + } + } + return filterEles; + } + return this.spawn(); // if not handled by above, give 'em an empty collection + }, + + not: function not(toRemove) { + if (!toRemove) { + return this; + } else { + if (string(toRemove)) { + toRemove = this.filter(toRemove); + } + var elements = this.spawn(); + for (var i = 0; i < this.length; i++) { + var element = this[i]; + var remove = toRemove.has(element); + if (!remove) { + elements.push(element); + } + } + return elements; + } + }, + absoluteComplement: function absoluteComplement() { + var cy = this.cy(); + return cy.mutableElements().not(this); + }, + intersect: function intersect(other) { + // if a selector is specified, then filter by it instead + if (string(other)) { + var selector = other; + return this.filter(selector); + } + var elements = this.spawn(); + var col1 = this; + var col2 = other; + var col1Smaller = this.length < other.length; + var colS = col1Smaller ? col1 : col2; + var colL = col1Smaller ? col2 : col1; + for (var i = 0; i < colS.length; i++) { + var ele = colS[i]; + if (colL.has(ele)) { + elements.push(ele); + } + } + return elements; + }, + xor: function xor(other) { + var cy = this._private.cy; + if (string(other)) { + other = cy.$(other); + } + var elements = this.spawn(); + var col1 = this; + var col2 = other; + var add = function add(col, other) { + for (var i = 0; i < col.length; i++) { + var ele = col[i]; + var id = ele._private.data.id; + var inOther = other.hasElementWithId(id); + if (!inOther) { + elements.push(ele); + } + } + }; + add(col1, col2); + add(col2, col1); + return elements; + }, + diff: function diff(other) { + var cy = this._private.cy; + if (string(other)) { + other = cy.$(other); + } + var left = this.spawn(); + var right = this.spawn(); + var both = this.spawn(); + var col1 = this; + var col2 = other; + var add = function add(col, other, retEles) { + for (var i = 0; i < col.length; i++) { + var ele = col[i]; + var id = ele._private.data.id; + var inOther = other.hasElementWithId(id); + if (inOther) { + both.merge(ele); + } else { + retEles.push(ele); + } + } + }; + add(col1, col2, left); + add(col2, col1, right); + return { + left: left, + right: right, + both: both + }; + }, + add: function add(toAdd) { + var cy = this._private.cy; + if (!toAdd) { + return this; + } + if (string(toAdd)) { + var selector = toAdd; + toAdd = cy.mutableElements().filter(selector); + } + var elements = this.spawnSelf(); + for (var i = 0; i < toAdd.length; i++) { + var ele = toAdd[i]; + var add = !this.has(ele); + if (add) { + elements.push(ele); + } + } + return elements; + }, + // in place merge on calling collection + merge: function merge(toAdd) { + var _p = this._private; + var cy = _p.cy; + if (!toAdd) { + return this; + } + if (toAdd && string(toAdd)) { + var selector = toAdd; + toAdd = cy.mutableElements().filter(selector); + } + var map = _p.map; + for (var i = 0; i < toAdd.length; i++) { + var toAddEle = toAdd[i]; + var id = toAddEle._private.data.id; + var add = !map.has(id); + if (add) { + var index = this.length++; + this[index] = toAddEle; + map.set(id, { + ele: toAddEle, + index: index + }); + } + } + return this; // chaining + }, + + unmergeAt: function unmergeAt(i) { + var ele = this[i]; + var id = ele.id(); + var _p = this._private; + var map = _p.map; + + // remove ele + this[i] = undefined; + map["delete"](id); + var unmergedLastEle = i === this.length - 1; + + // replace empty spot with last ele in collection + if (this.length > 1 && !unmergedLastEle) { + var lastEleI = this.length - 1; + var lastEle = this[lastEleI]; + var lastEleId = lastEle._private.data.id; + this[lastEleI] = undefined; + this[i] = lastEle; + map.set(lastEleId, { + ele: lastEle, + index: i + }); + } + + // the collection is now 1 ele smaller + this.length--; + return this; + }, + // remove single ele in place in calling collection + unmergeOne: function unmergeOne(ele) { + ele = ele[0]; + var _p = this._private; + var id = ele._private.data.id; + var map = _p.map; + var entry = map.get(id); + if (!entry) { + return this; // no need to remove + } + + var i = entry.index; + this.unmergeAt(i); + return this; + }, + // remove eles in place on calling collection + unmerge: function unmerge(toRemove) { + var cy = this._private.cy; + if (!toRemove) { + return this; + } + if (toRemove && string(toRemove)) { + var selector = toRemove; + toRemove = cy.mutableElements().filter(selector); + } + for (var i = 0; i < toRemove.length; i++) { + this.unmergeOne(toRemove[i]); + } + return this; // chaining + }, + + unmergeBy: function unmergeBy(toRmFn) { + for (var i = this.length - 1; i >= 0; i--) { + var ele = this[i]; + if (toRmFn(ele)) { + this.unmergeAt(i); + } + } + return this; + }, + map: function map(mapFn, thisArg) { + var arr = []; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var ret = thisArg ? mapFn.apply(thisArg, [ele, i, eles]) : mapFn(ele, i, eles); + arr.push(ret); + } + return arr; + }, + reduce: function reduce(fn, initialValue) { + var val = initialValue; + var eles = this; + for (var i = 0; i < eles.length; i++) { + val = fn(val, eles[i], i, eles); + } + return val; + }, + max: function max(valFn, thisArg) { + var max = -Infinity; + var maxEle; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles); + if (val > max) { + max = val; + maxEle = ele; + } + } + return { + value: max, + ele: maxEle + }; + }, + min: function min(valFn, thisArg) { + var min = Infinity; + var minEle; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles); + if (val < min) { + min = val; + minEle = ele; + } + } + return { + value: min, + ele: minEle + }; + } + }; + + // aliases + var fn$1 = elesfn$8; + fn$1['u'] = fn$1['|'] = fn$1['+'] = fn$1.union = fn$1.or = fn$1.add; + fn$1['\\'] = fn$1['!'] = fn$1['-'] = fn$1.difference = fn$1.relativeComplement = fn$1.subtract = fn$1.not; + fn$1['n'] = fn$1['&'] = fn$1['.'] = fn$1.and = fn$1.intersection = fn$1.intersect; + fn$1['^'] = fn$1['(+)'] = fn$1['(-)'] = fn$1.symmetricDifference = fn$1.symdiff = fn$1.xor; + fn$1.fnFilter = fn$1.filterFn = fn$1.stdFilter = fn$1.filter; + fn$1.complement = fn$1.abscomp = fn$1.absoluteComplement; + + var elesfn$7 = { + isNode: function isNode() { + return this.group() === 'nodes'; + }, + isEdge: function isEdge() { + return this.group() === 'edges'; + }, + isLoop: function isLoop() { + return this.isEdge() && this.source()[0] === this.target()[0]; + }, + isSimple: function isSimple() { + return this.isEdge() && this.source()[0] !== this.target()[0]; + }, + group: function group() { + var ele = this[0]; + if (ele) { + return ele._private.group; + } + } + }; + + /** + * Elements are drawn in a specific order based on compound depth (low to high), the element type (nodes above edges), + * and z-index (low to high). These styles affect how this applies: + * + * z-compound-depth: May be `bottom | orphan | auto | top`. The first drawn is `bottom`, then `orphan` which is the + * same depth as the root of the compound graph, followed by the default value `auto` which draws in order from + * root to leaves of the compound graph. The last drawn is `top`. + * z-index-compare: May be `auto | manual`. The default value is `auto` which always draws edges under nodes. + * `manual` ignores this convention and draws based on the `z-index` value setting. + * z-index: An integer value that affects the relative draw order of elements. In general, an element with a higher + * `z-index` will be drawn on top of an element with a lower `z-index`. + */ + var zIndexSort = function zIndexSort(a, b) { + var cy = a.cy(); + var hasCompoundNodes = cy.hasCompoundNodes(); + function getDepth(ele) { + var style = ele.pstyle('z-compound-depth'); + if (style.value === 'auto') { + return hasCompoundNodes ? ele.zDepth() : 0; + } else if (style.value === 'bottom') { + return -1; + } else if (style.value === 'top') { + return MAX_INT$1; + } + // 'orphan' + return 0; + } + var depthDiff = getDepth(a) - getDepth(b); + if (depthDiff !== 0) { + return depthDiff; + } + function getEleDepth(ele) { + var style = ele.pstyle('z-index-compare'); + if (style.value === 'auto') { + return ele.isNode() ? 1 : 0; + } + // 'manual' + return 0; + } + var eleDiff = getEleDepth(a) - getEleDepth(b); + if (eleDiff !== 0) { + return eleDiff; + } + var zDiff = a.pstyle('z-index').value - b.pstyle('z-index').value; + if (zDiff !== 0) { + return zDiff; + } + // compare indices in the core (order added to graph w/ last on top) + return a.poolIndex() - b.poolIndex(); + }; + + var elesfn$6 = { + forEach: function forEach(fn, thisArg) { + if (fn$6(fn)) { + var N = this.length; + for (var i = 0; i < N; i++) { + var ele = this[i]; + var ret = thisArg ? fn.apply(thisArg, [ele, i, this]) : fn(ele, i, this); + if (ret === false) { + break; + } // exit each early on return false + } + } + + return this; + }, + toArray: function toArray() { + var array = []; + for (var i = 0; i < this.length; i++) { + array.push(this[i]); + } + return array; + }, + slice: function slice(start, end) { + var array = []; + var thisSize = this.length; + if (end == null) { + end = thisSize; + } + if (start == null) { + start = 0; + } + if (start < 0) { + start = thisSize + start; + } + if (end < 0) { + end = thisSize + end; + } + for (var i = start; i >= 0 && i < end && i < thisSize; i++) { + array.push(this[i]); + } + return this.spawn(array); + }, + size: function size() { + return this.length; + }, + eq: function eq(i) { + return this[i] || this.spawn(); + }, + first: function first() { + return this[0] || this.spawn(); + }, + last: function last() { + return this[this.length - 1] || this.spawn(); + }, + empty: function empty() { + return this.length === 0; + }, + nonempty: function nonempty() { + return !this.empty(); + }, + sort: function sort(sortFn) { + if (!fn$6(sortFn)) { + return this; + } + var sorted = this.toArray().sort(sortFn); + return this.spawn(sorted); + }, + sortByZIndex: function sortByZIndex() { + return this.sort(zIndexSort); + }, + zDepth: function zDepth() { + var ele = this[0]; + if (!ele) { + return undefined; + } + + // let cy = ele.cy(); + var _p = ele._private; + var group = _p.group; + if (group === 'nodes') { + var depth = _p.data.parent ? ele.parents().size() : 0; + if (!ele.isParent()) { + return MAX_INT$1 - 1; // childless nodes always on top + } + + return depth; + } else { + var src = _p.source; + var tgt = _p.target; + var srcDepth = src.zDepth(); + var tgtDepth = tgt.zDepth(); + return Math.max(srcDepth, tgtDepth, 0); // depth of deepest parent + } + } + }; + + elesfn$6.each = elesfn$6.forEach; + var defineSymbolIterator = function defineSymbolIterator() { + var typeofUndef = "undefined" ; + var isIteratorSupported = (typeof Symbol === "undefined" ? "undefined" : _typeof(Symbol)) != typeofUndef && _typeof(Symbol.iterator) != typeofUndef; // eslint-disable-line no-undef + + if (isIteratorSupported) { + elesfn$6[Symbol.iterator] = function () { + var _this = this; + // eslint-disable-line no-undef + var entry = { + value: undefined, + done: false + }; + var i = 0; + var length = this.length; + return _defineProperty$1({ + next: function next() { + if (i < length) { + entry.value = _this[i++]; + } else { + entry.value = undefined; + entry.done = true; + } + return entry; + } + }, Symbol.iterator, function () { + // eslint-disable-line no-undef + return this; + }); + }; + } + }; + defineSymbolIterator(); + + var getLayoutDimensionOptions = defaults$g({ + nodeDimensionsIncludeLabels: false + }); + var elesfn$5 = { + // Calculates and returns node dimensions { x, y } based on options given + layoutDimensions: function layoutDimensions(options) { + options = getLayoutDimensionOptions(options); + var dims; + if (!this.takesUpSpace()) { + dims = { + w: 0, + h: 0 + }; + } else if (options.nodeDimensionsIncludeLabels) { + var bbDim = this.boundingBox(); + dims = { + w: bbDim.w, + h: bbDim.h + }; + } else { + dims = { + w: this.outerWidth(), + h: this.outerHeight() + }; + } + + // sanitise the dimensions for external layouts (avoid division by zero) + if (dims.w === 0 || dims.h === 0) { + dims.w = dims.h = 1; + } + return dims; + }, + // using standard layout options, apply position function (w/ or w/o animation) + layoutPositions: function layoutPositions(layout, options, fn) { + var nodes = this.nodes().filter(function (n) { + return !n.isParent(); + }); + var cy = this.cy(); + var layoutEles = options.eles; // nodes & edges + var getMemoizeKey = function getMemoizeKey(node) { + return node.id(); + }; + var fnMem = memoize$1(fn, getMemoizeKey); // memoized version of position function + + layout.emit({ + type: 'layoutstart', + layout: layout + }); + layout.animations = []; + var calculateSpacing = function calculateSpacing(spacing, nodesBb, pos) { + var center = { + x: nodesBb.x1 + nodesBb.w / 2, + y: nodesBb.y1 + nodesBb.h / 2 + }; + var spacingVector = { + // scale from center of bounding box (not necessarily 0,0) + x: (pos.x - center.x) * spacing, + y: (pos.y - center.y) * spacing + }; + return { + x: center.x + spacingVector.x, + y: center.y + spacingVector.y + }; + }; + var useSpacingFactor = options.spacingFactor && options.spacingFactor !== 1; + var spacingBb = function spacingBb() { + if (!useSpacingFactor) { + return null; + } + var bb = makeBoundingBox(); + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var pos = fnMem(node, i); + expandBoundingBoxByPoint(bb, pos.x, pos.y); + } + return bb; + }; + var bb = spacingBb(); + var getFinalPos = memoize$1(function (node, i) { + var newPos = fnMem(node, i); + if (useSpacingFactor) { + var spacing = Math.abs(options.spacingFactor); + newPos = calculateSpacing(spacing, bb, newPos); + } + if (options.transform != null) { + newPos = options.transform(node, newPos); + } + return newPos; + }, getMemoizeKey); + if (options.animate) { + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var newPos = getFinalPos(node, i); + var animateNode = options.animateFilter == null || options.animateFilter(node, i); + if (animateNode) { + var ani = node.animation({ + position: newPos, + duration: options.animationDuration, + easing: options.animationEasing + }); + layout.animations.push(ani); + } else { + node.position(newPos); + } + } + if (options.fit) { + var fitAni = cy.animation({ + fit: { + boundingBox: layoutEles.boundingBoxAt(getFinalPos), + padding: options.padding + }, + duration: options.animationDuration, + easing: options.animationEasing + }); + layout.animations.push(fitAni); + } else if (options.zoom !== undefined && options.pan !== undefined) { + var zoomPanAni = cy.animation({ + zoom: options.zoom, + pan: options.pan, + duration: options.animationDuration, + easing: options.animationEasing + }); + layout.animations.push(zoomPanAni); + } + layout.animations.forEach(function (ani) { + return ani.play(); + }); + layout.one('layoutready', options.ready); + layout.emit({ + type: 'layoutready', + layout: layout + }); + Promise$1.all(layout.animations.map(function (ani) { + return ani.promise(); + })).then(function () { + layout.one('layoutstop', options.stop); + layout.emit({ + type: 'layoutstop', + layout: layout + }); + }); + } else { + nodes.positions(getFinalPos); + if (options.fit) { + cy.fit(options.eles, options.padding); + } + if (options.zoom != null) { + cy.zoom(options.zoom); + } + if (options.pan) { + cy.pan(options.pan); + } + layout.one('layoutready', options.ready); + layout.emit({ + type: 'layoutready', + layout: layout + }); + layout.one('layoutstop', options.stop); + layout.emit({ + type: 'layoutstop', + layout: layout + }); + } + return this; // chaining + }, + + layout: function layout(options) { + var cy = this.cy(); + return cy.makeLayout(extend({}, options, { + eles: this + })); + } + }; + + // aliases: + elesfn$5.createLayout = elesfn$5.makeLayout = elesfn$5.layout; + + function styleCache(key, fn, ele) { + var _p = ele._private; + var cache = _p.styleCache = _p.styleCache || []; + var val; + if ((val = cache[key]) != null) { + return val; + } else { + val = cache[key] = fn(ele); + return val; + } + } + function cacheStyleFunction(key, fn) { + key = hashString(key); + return function cachedStyleFunction(ele) { + return styleCache(key, fn, ele); + }; + } + function cachePrototypeStyleFunction(key, fn) { + key = hashString(key); + var selfFn = function selfFn(ele) { + return fn.call(ele); + }; + return function cachedPrototypeStyleFunction() { + var ele = this[0]; + if (ele) { + return styleCache(key, selfFn, ele); + } + }; + } + var elesfn$4 = { + recalculateRenderedStyle: function recalculateRenderedStyle(useCache) { + var cy = this.cy(); + var renderer = cy.renderer(); + var styleEnabled = cy.styleEnabled(); + if (renderer && styleEnabled) { + renderer.recalculateRenderedStyle(this, useCache); + } + return this; + }, + dirtyStyleCache: function dirtyStyleCache() { + var cy = this.cy(); + var dirty = function dirty(ele) { + return ele._private.styleCache = null; + }; + if (cy.hasCompoundNodes()) { + var eles; + eles = this.spawnSelf().merge(this.descendants()).merge(this.parents()); + eles.merge(eles.connectedEdges()); + eles.forEach(dirty); + } else { + this.forEach(function (ele) { + dirty(ele); + ele.connectedEdges().forEach(dirty); + }); + } + return this; + }, + // fully updates (recalculates) the style for the elements + updateStyle: function updateStyle(notifyRenderer) { + var cy = this._private.cy; + if (!cy.styleEnabled()) { + return this; + } + if (cy.batching()) { + var bEles = cy._private.batchStyleEles; + bEles.merge(this); + return this; // chaining and exit early when batching + } + + var hasCompounds = cy.hasCompoundNodes(); + var updatedEles = this; + notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; + if (hasCompounds) { + // then add everything up and down for compound selector checks + updatedEles = this.spawnSelf().merge(this.descendants()).merge(this.parents()); + } + + // let changedEles = style.apply( updatedEles ); + var changedEles = updatedEles; + if (notifyRenderer) { + changedEles.emitAndNotify('style'); // let renderer know we changed style + } else { + changedEles.emit('style'); // just fire the event + } + + updatedEles.forEach(function (ele) { + return ele._private.styleDirty = true; + }); + return this; // chaining + }, + + // private: clears dirty flag and recalculates style + cleanStyle: function cleanStyle() { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return; + } + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + if (ele._private.styleDirty) { + // n.b. this flag should be set before apply() to avoid potential infinite recursion + ele._private.styleDirty = false; + cy.style().apply(ele); + } + } + }, + // get the internal parsed style object for the specified property + parsedStyle: function parsedStyle(property) { + var includeNonDefault = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var ele = this[0]; + var cy = ele.cy(); + if (!cy.styleEnabled()) { + return; + } + if (ele) { + this.cleanStyle(); + var overriddenStyle = ele._private.style[property]; + if (overriddenStyle != null) { + return overriddenStyle; + } else if (includeNonDefault) { + return cy.style().getDefaultProperty(property); + } else { + return null; + } + } + }, + numericStyle: function numericStyle(property) { + var ele = this[0]; + if (!ele.cy().styleEnabled()) { + return; + } + if (ele) { + var pstyle = ele.pstyle(property); + return pstyle.pfValue !== undefined ? pstyle.pfValue : pstyle.value; + } + }, + numericStyleUnits: function numericStyleUnits(property) { + var ele = this[0]; + if (!ele.cy().styleEnabled()) { + return; + } + if (ele) { + return ele.pstyle(property).units; + } + }, + // get the specified css property as a rendered value (i.e. on-screen value) + // or get the whole rendered style if no property specified (NB doesn't allow setting) + renderedStyle: function renderedStyle(property) { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return this; + } + var ele = this[0]; + if (ele) { + return cy.style().getRenderedStyle(ele, property); + } + }, + // read the calculated css style of the element or override the style (via a bypass) + style: function style(name, value) { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return this; + } + var updateTransitions = false; + var style = cy.style(); + if (plainObject(name)) { + // then extend the bypass + var props = name; + style.applyBypass(this, props, updateTransitions); + this.emitAndNotify('style'); // let the renderer know we've updated style + } else if (string(name)) { + if (value === undefined) { + // then get the property from the style + var ele = this[0]; + if (ele) { + return style.getStylePropertyValue(ele, name); + } else { + // empty collection => can't get any value + return; + } + } else { + // then set the bypass with the property value + style.applyBypass(this, name, value, updateTransitions); + this.emitAndNotify('style'); // let the renderer know we've updated style + } + } else if (name === undefined) { + var _ele = this[0]; + if (_ele) { + return style.getRawStyle(_ele); + } else { + // empty collection => can't get any value + return; + } + } + return this; // chaining + }, + + removeStyle: function removeStyle(names) { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return this; + } + var updateTransitions = false; + var style = cy.style(); + var eles = this; + if (names === undefined) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + style.removeAllBypasses(ele, updateTransitions); + } + } else { + names = names.split(/\s+/); + for (var _i = 0; _i < eles.length; _i++) { + var _ele2 = eles[_i]; + style.removeBypasses(_ele2, names, updateTransitions); + } + } + this.emitAndNotify('style'); // let the renderer know we've updated style + + return this; // chaining + }, + + show: function show() { + this.css('display', 'element'); + return this; // chaining + }, + + hide: function hide() { + this.css('display', 'none'); + return this; // chaining + }, + + effectiveOpacity: function effectiveOpacity() { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return 1; + } + var hasCompoundNodes = cy.hasCompoundNodes(); + var ele = this[0]; + if (ele) { + var _p = ele._private; + var parentOpacity = ele.pstyle('opacity').value; + if (!hasCompoundNodes) { + return parentOpacity; + } + var parents = !_p.data.parent ? null : ele.parents(); + if (parents) { + for (var i = 0; i < parents.length; i++) { + var parent = parents[i]; + var opacity = parent.pstyle('opacity').value; + parentOpacity = opacity * parentOpacity; + } + } + return parentOpacity; + } + }, + transparent: function transparent() { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return false; + } + var ele = this[0]; + var hasCompoundNodes = ele.cy().hasCompoundNodes(); + if (ele) { + if (!hasCompoundNodes) { + return ele.pstyle('opacity').value === 0; + } else { + return ele.effectiveOpacity() === 0; + } + } + }, + backgrounding: function backgrounding() { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return false; + } + var ele = this[0]; + return ele._private.backgrounding ? true : false; + } + }; + function checkCompound(ele, parentOk) { + var _p = ele._private; + var parents = _p.data.parent ? ele.parents() : null; + if (parents) { + for (var i = 0; i < parents.length; i++) { + var parent = parents[i]; + if (!parentOk(parent)) { + return false; + } + } + } + return true; + } + function defineDerivedStateFunction(specs) { + var ok = specs.ok; + var edgeOkViaNode = specs.edgeOkViaNode || specs.ok; + var parentOk = specs.parentOk || specs.ok; + return function () { + var cy = this.cy(); + if (!cy.styleEnabled()) { + return true; + } + var ele = this[0]; + var hasCompoundNodes = cy.hasCompoundNodes(); + if (ele) { + var _p = ele._private; + if (!ok(ele)) { + return false; + } + if (ele.isNode()) { + return !hasCompoundNodes || checkCompound(ele, parentOk); + } else { + var src = _p.source; + var tgt = _p.target; + return edgeOkViaNode(src) && (!hasCompoundNodes || checkCompound(src, edgeOkViaNode)) && (src === tgt || edgeOkViaNode(tgt) && (!hasCompoundNodes || checkCompound(tgt, edgeOkViaNode))); + } + } + }; + } + var eleTakesUpSpace = cacheStyleFunction('eleTakesUpSpace', function (ele) { + return ele.pstyle('display').value === 'element' && ele.width() !== 0 && (ele.isNode() ? ele.height() !== 0 : true); + }); + elesfn$4.takesUpSpace = cachePrototypeStyleFunction('takesUpSpace', defineDerivedStateFunction({ + ok: eleTakesUpSpace + })); + var eleInteractive = cacheStyleFunction('eleInteractive', function (ele) { + return ele.pstyle('events').value === 'yes' && ele.pstyle('visibility').value === 'visible' && eleTakesUpSpace(ele); + }); + var parentInteractive = cacheStyleFunction('parentInteractive', function (parent) { + return parent.pstyle('visibility').value === 'visible' && eleTakesUpSpace(parent); + }); + elesfn$4.interactive = cachePrototypeStyleFunction('interactive', defineDerivedStateFunction({ + ok: eleInteractive, + parentOk: parentInteractive, + edgeOkViaNode: eleTakesUpSpace + })); + elesfn$4.noninteractive = function () { + var ele = this[0]; + if (ele) { + return !ele.interactive(); + } + }; + var eleVisible = cacheStyleFunction('eleVisible', function (ele) { + return ele.pstyle('visibility').value === 'visible' && ele.pstyle('opacity').pfValue !== 0 && eleTakesUpSpace(ele); + }); + var edgeVisibleViaNode = eleTakesUpSpace; + elesfn$4.visible = cachePrototypeStyleFunction('visible', defineDerivedStateFunction({ + ok: eleVisible, + edgeOkViaNode: edgeVisibleViaNode + })); + elesfn$4.hidden = function () { + var ele = this[0]; + if (ele) { + return !ele.visible(); + } + }; + elesfn$4.isBundledBezier = cachePrototypeStyleFunction('isBundledBezier', function () { + if (!this.cy().styleEnabled()) { + return false; + } + return !this.removed() && this.pstyle('curve-style').value === 'bezier' && this.takesUpSpace(); + }); + elesfn$4.bypass = elesfn$4.css = elesfn$4.style; + elesfn$4.renderedCss = elesfn$4.renderedStyle; + elesfn$4.removeBypass = elesfn$4.removeCss = elesfn$4.removeStyle; + elesfn$4.pstyle = elesfn$4.parsedStyle; + + var elesfn$3 = {}; + function defineSwitchFunction(params) { + return function () { + var args = arguments; + var changedEles = []; + + // e.g. cy.nodes().select( data, handler ) + if (args.length === 2) { + var data = args[0]; + var handler = args[1]; + this.on(params.event, data, handler); + } + + // e.g. cy.nodes().select( handler ) + else if (args.length === 1 && fn$6(args[0])) { + var _handler = args[0]; + this.on(params.event, _handler); + } + + // e.g. cy.nodes().select() + // e.g. (private) cy.nodes().select(['tapselect']) + else if (args.length === 0 || args.length === 1 && array(args[0])) { + var addlEvents = args.length === 1 ? args[0] : null; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var able = !params.ableField || ele._private[params.ableField]; + var changed = ele._private[params.field] != params.value; + if (params.overrideAble) { + var overrideAble = params.overrideAble(ele); + if (overrideAble !== undefined) { + able = overrideAble; + if (!overrideAble) { + return this; + } // to save cycles assume not able for all on override + } + } + + if (able) { + ele._private[params.field] = params.value; + if (changed) { + changedEles.push(ele); + } + } + } + var changedColl = this.spawn(changedEles); + changedColl.updateStyle(); // change of state => possible change of style + changedColl.emit(params.event); + if (addlEvents) { + changedColl.emit(addlEvents); + } + } + return this; + }; + } + function defineSwitchSet(params) { + elesfn$3[params.field] = function () { + var ele = this[0]; + if (ele) { + if (params.overrideField) { + var val = params.overrideField(ele); + if (val !== undefined) { + return val; + } + } + return ele._private[params.field]; + } + }; + elesfn$3[params.on] = defineSwitchFunction({ + event: params.on, + field: params.field, + ableField: params.ableField, + overrideAble: params.overrideAble, + value: true + }); + elesfn$3[params.off] = defineSwitchFunction({ + event: params.off, + field: params.field, + ableField: params.ableField, + overrideAble: params.overrideAble, + value: false + }); + } + defineSwitchSet({ + field: 'locked', + overrideField: function overrideField(ele) { + return ele.cy().autolock() ? true : undefined; + }, + on: 'lock', + off: 'unlock' + }); + defineSwitchSet({ + field: 'grabbable', + overrideField: function overrideField(ele) { + return ele.cy().autoungrabify() || ele.pannable() ? false : undefined; + }, + on: 'grabify', + off: 'ungrabify' + }); + defineSwitchSet({ + field: 'selected', + ableField: 'selectable', + overrideAble: function overrideAble(ele) { + return ele.cy().autounselectify() ? false : undefined; + }, + on: 'select', + off: 'unselect' + }); + defineSwitchSet({ + field: 'selectable', + overrideField: function overrideField(ele) { + return ele.cy().autounselectify() ? false : undefined; + }, + on: 'selectify', + off: 'unselectify' + }); + elesfn$3.deselect = elesfn$3.unselect; + elesfn$3.grabbed = function () { + var ele = this[0]; + if (ele) { + return ele._private.grabbed; + } + }; + defineSwitchSet({ + field: 'active', + on: 'activate', + off: 'unactivate' + }); + defineSwitchSet({ + field: 'pannable', + on: 'panify', + off: 'unpanify' + }); + elesfn$3.inactive = function () { + var ele = this[0]; + if (ele) { + return !ele._private.active; + } + }; + + var elesfn$2 = {}; + + // DAG functions + //////////////// + + var defineDagExtremity = function defineDagExtremity(params) { + return function dagExtremityImpl(selector) { + var eles = this; + var ret = []; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (!ele.isNode()) { + continue; + } + var disqualified = false; + var edges = ele.connectedEdges(); + for (var j = 0; j < edges.length; j++) { + var edge = edges[j]; + var src = edge.source(); + var tgt = edge.target(); + if (params.noIncomingEdges && tgt === ele && src !== ele || params.noOutgoingEdges && src === ele && tgt !== ele) { + disqualified = true; + break; + } + } + if (!disqualified) { + ret.push(ele); + } + } + return this.spawn(ret, true).filter(selector); + }; + }; + var defineDagOneHop = function defineDagOneHop(params) { + return function (selector) { + var eles = this; + var oEles = []; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (!ele.isNode()) { + continue; + } + var edges = ele.connectedEdges(); + for (var j = 0; j < edges.length; j++) { + var edge = edges[j]; + var src = edge.source(); + var tgt = edge.target(); + if (params.outgoing && src === ele) { + oEles.push(edge); + oEles.push(tgt); + } else if (params.incoming && tgt === ele) { + oEles.push(edge); + oEles.push(src); + } + } + } + return this.spawn(oEles, true).filter(selector); + }; + }; + var defineDagAllHops = function defineDagAllHops(params) { + return function (selector) { + var eles = this; + var sEles = []; + var sElesIds = {}; + for (;;) { + var next = params.outgoing ? eles.outgoers() : eles.incomers(); + if (next.length === 0) { + break; + } // done if none left + + var newNext = false; + for (var i = 0; i < next.length; i++) { + var n = next[i]; + var nid = n.id(); + if (!sElesIds[nid]) { + sElesIds[nid] = true; + sEles.push(n); + newNext = true; + } + } + if (!newNext) { + break; + } // done if touched all outgoers already + + eles = next; + } + return this.spawn(sEles, true).filter(selector); + }; + }; + elesfn$2.clearTraversalCache = function () { + for (var i = 0; i < this.length; i++) { + this[i]._private.traversalCache = null; + } + }; + extend(elesfn$2, { + // get the root nodes in the DAG + roots: defineDagExtremity({ + noIncomingEdges: true + }), + // get the leaf nodes in the DAG + leaves: defineDagExtremity({ + noOutgoingEdges: true + }), + // normally called children in graph theory + // these nodes =edges=> outgoing nodes + outgoers: cache(defineDagOneHop({ + outgoing: true + }), 'outgoers'), + // aka DAG descendants + successors: defineDagAllHops({ + outgoing: true + }), + // normally called parents in graph theory + // these nodes <=edges= incoming nodes + incomers: cache(defineDagOneHop({ + incoming: true + }), 'incomers'), + // aka DAG ancestors + predecessors: defineDagAllHops({ + incoming: true + }) + }); + + // Neighbourhood functions + ////////////////////////// + + extend(elesfn$2, { + neighborhood: cache(function (selector) { + var elements = []; + var nodes = this.nodes(); + for (var i = 0; i < nodes.length; i++) { + // for all nodes + var node = nodes[i]; + var connectedEdges = node.connectedEdges(); + + // for each connected edge, add the edge and the other node + for (var j = 0; j < connectedEdges.length; j++) { + var edge = connectedEdges[j]; + var src = edge.source(); + var tgt = edge.target(); + var otherNode = node === src ? tgt : src; + + // need check in case of loop + if (otherNode.length > 0) { + elements.push(otherNode[0]); // add node 1 hop away + } + + // add connected edge + elements.push(edge[0]); + } + } + return this.spawn(elements, true).filter(selector); + }, 'neighborhood'), + closedNeighborhood: function closedNeighborhood(selector) { + return this.neighborhood().add(this).filter(selector); + }, + openNeighborhood: function openNeighborhood(selector) { + return this.neighborhood(selector); + } + }); + + // aliases + elesfn$2.neighbourhood = elesfn$2.neighborhood; + elesfn$2.closedNeighbourhood = elesfn$2.closedNeighborhood; + elesfn$2.openNeighbourhood = elesfn$2.openNeighborhood; + + // Edge functions + ///////////////// + + extend(elesfn$2, { + source: cache(function sourceImpl(selector) { + var ele = this[0]; + var src; + if (ele) { + src = ele._private.source || ele.cy().collection(); + } + return src && selector ? src.filter(selector) : src; + }, 'source'), + target: cache(function targetImpl(selector) { + var ele = this[0]; + var tgt; + if (ele) { + tgt = ele._private.target || ele.cy().collection(); + } + return tgt && selector ? tgt.filter(selector) : tgt; + }, 'target'), + sources: defineSourceFunction({ + attr: 'source' + }), + targets: defineSourceFunction({ + attr: 'target' + }) + }); + function defineSourceFunction(params) { + return function sourceImpl(selector) { + var sources = []; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var src = ele._private[params.attr]; + if (src) { + sources.push(src); + } + } + return this.spawn(sources, true).filter(selector); + }; + } + extend(elesfn$2, { + edgesWith: cache(defineEdgesWithFunction(), 'edgesWith'), + edgesTo: cache(defineEdgesWithFunction({ + thisIsSrc: true + }), 'edgesTo') + }); + function defineEdgesWithFunction(params) { + return function edgesWithImpl(otherNodes) { + var elements = []; + var cy = this._private.cy; + var p = params || {}; + + // get elements if a selector is specified + if (string(otherNodes)) { + otherNodes = cy.$(otherNodes); + } + for (var h = 0; h < otherNodes.length; h++) { + var edges = otherNodes[h]._private.edges; + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + var edgeData = edge._private.data; + var thisToOther = this.hasElementWithId(edgeData.source) && otherNodes.hasElementWithId(edgeData.target); + var otherToThis = otherNodes.hasElementWithId(edgeData.source) && this.hasElementWithId(edgeData.target); + var edgeConnectsThisAndOther = thisToOther || otherToThis; + if (!edgeConnectsThisAndOther) { + continue; + } + if (p.thisIsSrc || p.thisIsTgt) { + if (p.thisIsSrc && !thisToOther) { + continue; + } + if (p.thisIsTgt && !otherToThis) { + continue; + } + } + elements.push(edge); + } + } + return this.spawn(elements, true); + }; + } + extend(elesfn$2, { + connectedEdges: cache(function (selector) { + var retEles = []; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var node = eles[i]; + if (!node.isNode()) { + continue; + } + var edges = node._private.edges; + for (var j = 0; j < edges.length; j++) { + var edge = edges[j]; + retEles.push(edge); + } + } + return this.spawn(retEles, true).filter(selector); + }, 'connectedEdges'), + connectedNodes: cache(function (selector) { + var retEles = []; + var eles = this; + for (var i = 0; i < eles.length; i++) { + var edge = eles[i]; + if (!edge.isEdge()) { + continue; + } + retEles.push(edge.source()[0]); + retEles.push(edge.target()[0]); + } + return this.spawn(retEles, true).filter(selector); + }, 'connectedNodes'), + parallelEdges: cache(defineParallelEdgesFunction(), 'parallelEdges'), + codirectedEdges: cache(defineParallelEdgesFunction({ + codirected: true + }), 'codirectedEdges') + }); + function defineParallelEdgesFunction(params) { + var defaults = { + codirected: false + }; + params = extend({}, defaults, params); + return function parallelEdgesImpl(selector) { + // micro-optimised for renderer + var elements = []; + var edges = this.edges(); + var p = params; + + // look at all the edges in the collection + for (var i = 0; i < edges.length; i++) { + var edge1 = edges[i]; + var edge1_p = edge1._private; + var src1 = edge1_p.source; + var srcid1 = src1._private.data.id; + var tgtid1 = edge1_p.data.target; + var srcEdges1 = src1._private.edges; + + // look at edges connected to the src node of this edge + for (var j = 0; j < srcEdges1.length; j++) { + var edge2 = srcEdges1[j]; + var edge2data = edge2._private.data; + var tgtid2 = edge2data.target; + var srcid2 = edge2data.source; + var codirected = tgtid2 === tgtid1 && srcid2 === srcid1; + var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2; + if (p.codirected && codirected || !p.codirected && (codirected || oppdirected)) { + elements.push(edge2); + } + } + } + return this.spawn(elements, true).filter(selector); + }; + } + + // Misc functions + ///////////////// + + extend(elesfn$2, { + components: function components(root) { + var self = this; + var cy = self.cy(); + var visited = cy.collection(); + var unvisited = root == null ? self.nodes() : root.nodes(); + var components = []; + if (root != null && unvisited.empty()) { + // root may contain only edges + unvisited = root.sources(); // doesn't matter which node to use (undirected), so just use the source sides + } + + var visitInComponent = function visitInComponent(node, component) { + visited.merge(node); + unvisited.unmerge(node); + component.merge(node); + }; + if (unvisited.empty()) { + return self.spawn(); + } + var _loop = function _loop() { + // each iteration yields a component + var cmpt = cy.collection(); + components.push(cmpt); + var root = unvisited[0]; + visitInComponent(root, cmpt); + self.bfs({ + directed: false, + roots: root, + visit: function visit(v) { + return visitInComponent(v, cmpt); + } + }); + cmpt.forEach(function (node) { + node.connectedEdges().forEach(function (e) { + // connectedEdges() usually cached + if (self.has(e) && cmpt.has(e.source()) && cmpt.has(e.target())) { + // has() is cheap + cmpt.merge(e); // forEach() only considers nodes -- sets N at call time + } + }); + }); + }; + do { + _loop(); + } while (unvisited.length > 0); + return components; + }, + component: function component() { + var ele = this[0]; + return ele.cy().mutableElements().components(ele)[0]; + } + }); + elesfn$2.componentsOf = elesfn$2.components; + + // represents a set of nodes, edges, or both together + var Collection = function Collection(cy, elements) { + var unique = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + var removed = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; + if (cy === undefined) { + error('A collection must have a reference to the core'); + return; + } + var map = new Map$2(); + var createdElements = false; + if (!elements) { + elements = []; + } else if (elements.length > 0 && plainObject(elements[0]) && !element(elements[0])) { + createdElements = true; + + // make elements from json and restore all at once later + var eles = []; + var elesIds = new Set$1(); + for (var i = 0, l = elements.length; i < l; i++) { + var json = elements[i]; + if (json.data == null) { + json.data = {}; + } + var _data = json.data; + + // make sure newly created elements have valid ids + if (_data.id == null) { + _data.id = uuid(); + } else if (cy.hasElementWithId(_data.id) || elesIds.has(_data.id)) { + continue; // can't create element if prior id already exists + } + + var ele = new Element(cy, json, false); + eles.push(ele); + elesIds.add(_data.id); + } + elements = eles; + } + this.length = 0; + for (var _i = 0, _l = elements.length; _i < _l; _i++) { + var element$1 = elements[_i][0]; // [0] in case elements is an array of collections, rather than array of elements + if (element$1 == null) { + continue; + } + var id = element$1._private.data.id; + if (!unique || !map.has(id)) { + if (unique) { + map.set(id, { + index: this.length, + ele: element$1 + }); + } + this[this.length] = element$1; + this.length++; + } + } + this._private = { + eles: this, + cy: cy, + get map() { + if (this.lazyMap == null) { + this.rebuildMap(); + } + return this.lazyMap; + }, + set map(m) { + this.lazyMap = m; + }, + rebuildMap: function rebuildMap() { + var m = this.lazyMap = new Map$2(); + var eles = this.eles; + for (var _i2 = 0; _i2 < eles.length; _i2++) { + var _ele = eles[_i2]; + m.set(_ele.id(), { + index: _i2, + ele: _ele + }); + } + } + }; + if (unique) { + this._private.map = map; + } + + // restore the elements if we created them from json + if (createdElements && !removed) { + this.restore(); + } + }; + + // Functions + //////////////////////////////////////////////////////////////////////////////////////////////////// + + // keep the prototypes in sync (an element has the same functions as a collection) + // and use elefn and elesfn as shorthands to the prototypes + var elesfn$1 = Element.prototype = Collection.prototype = Object.create(Array.prototype); + elesfn$1.instanceString = function () { + return 'collection'; + }; + elesfn$1.spawn = function (eles, unique) { + return new Collection(this.cy(), eles, unique); + }; + elesfn$1.spawnSelf = function () { + return this.spawn(this); + }; + elesfn$1.cy = function () { + return this._private.cy; + }; + elesfn$1.renderer = function () { + return this._private.cy.renderer(); + }; + elesfn$1.element = function () { + return this[0]; + }; + elesfn$1.collection = function () { + if (collection(this)) { + return this; + } else { + // an element + return new Collection(this._private.cy, [this]); + } + }; + elesfn$1.unique = function () { + return new Collection(this._private.cy, this, true); + }; + elesfn$1.hasElementWithId = function (id) { + id = '' + id; // id must be string + + return this._private.map.has(id); + }; + elesfn$1.getElementById = function (id) { + id = '' + id; // id must be string + + var cy = this._private.cy; + var entry = this._private.map.get(id); + return entry ? entry.ele : new Collection(cy); // get ele or empty collection + }; + + elesfn$1.$id = elesfn$1.getElementById; + elesfn$1.poolIndex = function () { + var cy = this._private.cy; + var eles = cy._private.elements; + var id = this[0]._private.data.id; + return eles._private.map.get(id).index; + }; + elesfn$1.indexOf = function (ele) { + var id = ele[0]._private.data.id; + return this._private.map.get(id).index; + }; + elesfn$1.indexOfId = function (id) { + id = '' + id; // id must be string + + return this._private.map.get(id).index; + }; + elesfn$1.json = function (obj) { + var ele = this.element(); + var cy = this.cy(); + if (ele == null && obj) { + return this; + } // can't set to no eles + + if (ele == null) { + return undefined; + } // can't get from no eles + + var p = ele._private; + if (plainObject(obj)) { + // set + + cy.startBatch(); + if (obj.data) { + ele.data(obj.data); + var _data2 = p.data; + if (ele.isEdge()) { + // source and target are immutable via data() + var move = false; + var spec = {}; + var src = obj.data.source; + var tgt = obj.data.target; + if (src != null && src != _data2.source) { + spec.source = '' + src; // id must be string + move = true; + } + if (tgt != null && tgt != _data2.target) { + spec.target = '' + tgt; // id must be string + move = true; + } + if (move) { + ele = ele.move(spec); + } + } else { + // parent is immutable via data() + var newParentValSpecd = ('parent' in obj.data); + var parent = obj.data.parent; + if (newParentValSpecd && (parent != null || _data2.parent != null) && parent != _data2.parent) { + if (parent === undefined) { + // can't set undefined imperatively, so use null + parent = null; + } + if (parent != null) { + parent = '' + parent; // id must be string + } + + ele = ele.move({ + parent: parent + }); + } + } + } + if (obj.position) { + ele.position(obj.position); + } + + // ignore group -- immutable + + var checkSwitch = function checkSwitch(k, trueFnName, falseFnName) { + var obj_k = obj[k]; + if (obj_k != null && obj_k !== p[k]) { + if (obj_k) { + ele[trueFnName](); + } else { + ele[falseFnName](); + } + } + }; + checkSwitch('removed', 'remove', 'restore'); + checkSwitch('selected', 'select', 'unselect'); + checkSwitch('selectable', 'selectify', 'unselectify'); + checkSwitch('locked', 'lock', 'unlock'); + checkSwitch('grabbable', 'grabify', 'ungrabify'); + checkSwitch('pannable', 'panify', 'unpanify'); + if (obj.classes != null) { + ele.classes(obj.classes); + } + cy.endBatch(); + return this; + } else if (obj === undefined) { + // get + + var json = { + data: copy(p.data), + position: copy(p.position), + group: p.group, + removed: p.removed, + selected: p.selected, + selectable: p.selectable, + locked: p.locked, + grabbable: p.grabbable, + pannable: p.pannable, + classes: null + }; + json.classes = ''; + var i = 0; + p.classes.forEach(function (cls) { + return json.classes += i++ === 0 ? cls : ' ' + cls; + }); + return json; + } + }; + elesfn$1.jsons = function () { + var jsons = []; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var json = ele.json(); + jsons.push(json); + } + return jsons; + }; + elesfn$1.clone = function () { + var cy = this.cy(); + var elesArr = []; + for (var i = 0; i < this.length; i++) { + var ele = this[i]; + var json = ele.json(); + var clone = new Element(cy, json, false); // NB no restore + + elesArr.push(clone); + } + return new Collection(cy, elesArr); + }; + elesfn$1.copy = elesfn$1.clone; + elesfn$1.restore = function () { + var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var addToPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var self = this; + var cy = self.cy(); + var cy_p = cy._private; + + // create arrays of nodes and edges, since we need to + // restore the nodes first + var nodes = []; + var edges = []; + var elements; + for (var _i3 = 0, l = self.length; _i3 < l; _i3++) { + var ele = self[_i3]; + if (addToPool && !ele.removed()) { + // don't need to handle this ele + continue; + } + + // keep nodes first in the array and edges after + if (ele.isNode()) { + // put to front of array if node + nodes.push(ele); + } else { + // put to end of array if edge + edges.push(ele); + } + } + elements = nodes.concat(edges); + var i; + var removeFromElements = function removeFromElements() { + elements.splice(i, 1); + i--; + }; + + // now, restore each element + for (i = 0; i < elements.length; i++) { + var _ele2 = elements[i]; + var _private = _ele2._private; + var _data3 = _private.data; + + // the traversal cache should start fresh when ele is added + _ele2.clearTraversalCache(); + + // set id and validate + if (!addToPool && !_private.removed) ; else if (_data3.id === undefined) { + _data3.id = uuid(); + } else if (number$1(_data3.id)) { + _data3.id = '' + _data3.id; // now it's a string + } else if (emptyString(_data3.id) || !string(_data3.id)) { + error('Can not create element with invalid string ID `' + _data3.id + '`'); + + // can't create element if it has empty string as id or non-string id + removeFromElements(); + continue; + } else if (cy.hasElementWithId(_data3.id)) { + error('Can not create second element with ID `' + _data3.id + '`'); + + // can't create element if one already has that id + removeFromElements(); + continue; + } + var id = _data3.id; // id is finalised, now let's keep a ref + + if (_ele2.isNode()) { + // extra checks for nodes + var pos = _private.position; + + // make sure the nodes have a defined position + + if (pos.x == null) { + pos.x = 0; + } + if (pos.y == null) { + pos.y = 0; + } + } + if (_ele2.isEdge()) { + // extra checks for edges + + var edge = _ele2; + var fields = ['source', 'target']; + var fieldsLength = fields.length; + var badSourceOrTarget = false; + for (var j = 0; j < fieldsLength; j++) { + var field = fields[j]; + var val = _data3[field]; + if (number$1(val)) { + val = _data3[field] = '' + _data3[field]; // now string + } + + if (val == null || val === '') { + // can't create if source or target is not defined properly + error('Can not create edge `' + id + '` with unspecified ' + field); + badSourceOrTarget = true; + } else if (!cy.hasElementWithId(val)) { + // can't create edge if one of its nodes doesn't exist + error('Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`'); + badSourceOrTarget = true; + } + } + if (badSourceOrTarget) { + removeFromElements(); + continue; + } // can't create this + + var src = cy.getElementById(_data3.source); + var tgt = cy.getElementById(_data3.target); + + // only one edge in node if loop + if (src.same(tgt)) { + src._private.edges.push(edge); + } else { + src._private.edges.push(edge); + tgt._private.edges.push(edge); + } + edge._private.source = src; + edge._private.target = tgt; + } // if is edge + + // create mock ids / indexes maps for element so it can be used like collections + _private.map = new Map$2(); + _private.map.set(id, { + ele: _ele2, + index: 0 + }); + _private.removed = false; + if (addToPool) { + cy.addToPool(_ele2); + } + } // for each element + + // do compound node sanity checks + for (var _i4 = 0; _i4 < nodes.length; _i4++) { + // each node + var node = nodes[_i4]; + var _data4 = node._private.data; + if (number$1(_data4.parent)) { + // then automake string + _data4.parent = '' + _data4.parent; + } + var parentId = _data4.parent; + var specifiedParent = parentId != null; + if (specifiedParent || node._private.parent) { + var parent = node._private.parent ? cy.collection().merge(node._private.parent) : cy.getElementById(parentId); + if (parent.empty()) { + // non-existant parent; just remove it + _data4.parent = undefined; + } else if (parent[0].removed()) { + warn('Node added with missing parent, reference to parent removed'); + _data4.parent = undefined; + node._private.parent = null; + } else { + var selfAsParent = false; + var ancestor = parent; + while (!ancestor.empty()) { + if (node.same(ancestor)) { + // mark self as parent and remove from data + selfAsParent = true; + _data4.parent = undefined; // remove parent reference + + // exit or we loop forever + break; + } + ancestor = ancestor.parent(); + } + if (!selfAsParent) { + // connect with children + parent[0]._private.children.push(node); + node._private.parent = parent[0]; + + // let the core know we have a compound graph + cy_p.hasCompoundNodes = true; + } + } // else + } // if specified parent + } // for each node + + if (elements.length > 0) { + var restored = elements.length === self.length ? self : new Collection(cy, elements); + for (var _i5 = 0; _i5 < restored.length; _i5++) { + var _ele3 = restored[_i5]; + if (_ele3.isNode()) { + continue; + } + + // adding an edge invalidates the traversal caches for the parallel edges + _ele3.parallelEdges().clearTraversalCache(); + + // adding an edge invalidates the traversal cache for the connected nodes + _ele3.source().clearTraversalCache(); + _ele3.target().clearTraversalCache(); + } + var toUpdateStyle; + if (cy_p.hasCompoundNodes) { + toUpdateStyle = cy.collection().merge(restored).merge(restored.connectedNodes()).merge(restored.parent()); + } else { + toUpdateStyle = restored; + } + toUpdateStyle.dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(notifyRenderer); + if (notifyRenderer) { + restored.emitAndNotify('add'); + } else if (addToPool) { + restored.emit('add'); + } + } + return self; // chainability + }; + + elesfn$1.removed = function () { + var ele = this[0]; + return ele && ele._private.removed; + }; + elesfn$1.inside = function () { + var ele = this[0]; + return ele && !ele._private.removed; + }; + elesfn$1.remove = function () { + var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var removeFromPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var self = this; + var elesToRemove = []; + var elesToRemoveIds = {}; + var cy = self._private.cy; + + // add connected edges + function addConnectedEdges(node) { + var edges = node._private.edges; + for (var i = 0; i < edges.length; i++) { + add(edges[i]); + } + } + + // add descendant nodes + function addChildren(node) { + var children = node._private.children; + for (var i = 0; i < children.length; i++) { + add(children[i]); + } + } + function add(ele) { + var alreadyAdded = elesToRemoveIds[ele.id()]; + if (removeFromPool && ele.removed() || alreadyAdded) { + return; + } else { + elesToRemoveIds[ele.id()] = true; + } + if (ele.isNode()) { + elesToRemove.push(ele); // nodes are removed last + + addConnectedEdges(ele); + addChildren(ele); + } else { + elesToRemove.unshift(ele); // edges are removed first + } + } + + // make the list of elements to remove + // (may be removing more than specified due to connected edges etc) + + for (var i = 0, l = self.length; i < l; i++) { + var ele = self[i]; + add(ele); + } + function removeEdgeRef(node, edge) { + var connectedEdges = node._private.edges; + removeFromArray(connectedEdges, edge); + + // removing an edges invalidates the traversal cache for its nodes + node.clearTraversalCache(); + } + function removeParallelRef(pllEdge) { + // removing an edge invalidates the traversal caches for the parallel edges + pllEdge.clearTraversalCache(); + } + var alteredParents = []; + alteredParents.ids = {}; + function removeChildRef(parent, ele) { + ele = ele[0]; + parent = parent[0]; + var children = parent._private.children; + var pid = parent.id(); + removeFromArray(children, ele); // remove parent => child ref + + ele._private.parent = null; // remove child => parent ref + + if (!alteredParents.ids[pid]) { + alteredParents.ids[pid] = true; + alteredParents.push(parent); + } + } + self.dirtyCompoundBoundsCache(); + if (removeFromPool) { + cy.removeFromPool(elesToRemove); // remove from core pool + } + + for (var _i6 = 0; _i6 < elesToRemove.length; _i6++) { + var _ele4 = elesToRemove[_i6]; + if (_ele4.isEdge()) { + // remove references to this edge in its connected nodes + var src = _ele4.source()[0]; + var tgt = _ele4.target()[0]; + removeEdgeRef(src, _ele4); + removeEdgeRef(tgt, _ele4); + var pllEdges = _ele4.parallelEdges(); + for (var j = 0; j < pllEdges.length; j++) { + var pllEdge = pllEdges[j]; + removeParallelRef(pllEdge); + if (pllEdge.isBundledBezier()) { + pllEdge.dirtyBoundingBoxCache(); + } + } + } else { + // remove reference to parent + var parent = _ele4.parent(); + if (parent.length !== 0) { + removeChildRef(parent, _ele4); + } + } + if (removeFromPool) { + // mark as removed + _ele4._private.removed = true; + } + } + + // check to see if we have a compound graph or not + var elesStillInside = cy._private.elements; + cy._private.hasCompoundNodes = false; + for (var _i7 = 0; _i7 < elesStillInside.length; _i7++) { + var _ele5 = elesStillInside[_i7]; + if (_ele5.isParent()) { + cy._private.hasCompoundNodes = true; + break; + } + } + var removedElements = new Collection(this.cy(), elesToRemove); + if (removedElements.size() > 0) { + // must manually notify since trigger won't do this automatically once removed + + if (notifyRenderer) { + removedElements.emitAndNotify('remove'); + } else if (removeFromPool) { + removedElements.emit('remove'); + } + } + + // the parents who were modified by the removal need their style updated + for (var _i8 = 0; _i8 < alteredParents.length; _i8++) { + var _ele6 = alteredParents[_i8]; + if (!removeFromPool || !_ele6.removed()) { + _ele6.updateStyle(); + } + } + return removedElements; + }; + elesfn$1.move = function (struct) { + var cy = this._private.cy; + var eles = this; + + // just clean up refs, caches, etc. in the same way as when removing and then restoring + // (our calls to remove/restore do not remove from the graph or make events) + var notifyRenderer = false; + var modifyPool = false; + var toString = function toString(id) { + return id == null ? id : '' + id; + }; // id must be string + + if (struct.source !== undefined || struct.target !== undefined) { + var srcId = toString(struct.source); + var tgtId = toString(struct.target); + var srcExists = srcId != null && cy.hasElementWithId(srcId); + var tgtExists = tgtId != null && cy.hasElementWithId(tgtId); + if (srcExists || tgtExists) { + cy.batch(function () { + // avoid duplicate style updates + eles.remove(notifyRenderer, modifyPool); // clean up refs etc. + eles.emitAndNotify('moveout'); + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _data5 = ele._private.data; + if (ele.isEdge()) { + if (srcExists) { + _data5.source = srcId; + } + if (tgtExists) { + _data5.target = tgtId; + } + } + } + eles.restore(notifyRenderer, modifyPool); // make new refs, style, etc. + }); + + eles.emitAndNotify('move'); + } + } else if (struct.parent !== undefined) { + // move node to new parent + var parentId = toString(struct.parent); + var parentExists = parentId === null || cy.hasElementWithId(parentId); + if (parentExists) { + var pidToAssign = parentId === null ? undefined : parentId; + cy.batch(function () { + // avoid duplicate style updates + var updated = eles.remove(notifyRenderer, modifyPool); // clean up refs etc. + updated.emitAndNotify('moveout'); + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _data6 = ele._private.data; + if (ele.isNode()) { + _data6.parent = pidToAssign; + } + } + updated.restore(notifyRenderer, modifyPool); // make new refs, style, etc. + }); + + eles.emitAndNotify('move'); + } + } + return this; + }; + [elesfn$j, elesfn$i, elesfn$h, elesfn$g, elesfn$f, data, elesfn$d, dimensions, elesfn$9, elesfn$8, elesfn$7, elesfn$6, elesfn$5, elesfn$4, elesfn$3, elesfn$2].forEach(function (props) { + extend(elesfn$1, props); + }); + + var corefn$9 = { + add: function add(opts) { + var elements; + var cy = this; + + // add the elements + if (elementOrCollection(opts)) { + var eles = opts; + if (eles._private.cy === cy) { + // same instance => just restore + elements = eles.restore(); + } else { + // otherwise, copy from json + var jsons = []; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + jsons.push(ele.json()); + } + elements = new Collection(cy, jsons); + } + } + + // specify an array of options + else if (array(opts)) { + var _jsons = opts; + elements = new Collection(cy, _jsons); + } + + // specify via opts.nodes and opts.edges + else if (plainObject(opts) && (array(opts.nodes) || array(opts.edges))) { + var elesByGroup = opts; + var _jsons2 = []; + var grs = ['nodes', 'edges']; + for (var _i = 0, il = grs.length; _i < il; _i++) { + var group = grs[_i]; + var elesArray = elesByGroup[group]; + if (array(elesArray)) { + for (var j = 0, jl = elesArray.length; j < jl; j++) { + var json = extend({ + group: group + }, elesArray[j]); + _jsons2.push(json); + } + } + } + elements = new Collection(cy, _jsons2); + } + + // specify options for one element + else { + var _json = opts; + elements = new Element(cy, _json).collection(); + } + return elements; + }, + remove: function remove(collection) { + if (elementOrCollection(collection)) ; else if (string(collection)) { + var selector = collection; + collection = this.$(selector); + } + return collection.remove(); + } + }; + + /* global Float32Array */ + + /*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */ + function generateCubicBezier(mX1, mY1, mX2, mY2) { + var NEWTON_ITERATIONS = 4, + NEWTON_MIN_SLOPE = 0.001, + SUBDIVISION_PRECISION = 0.0000001, + SUBDIVISION_MAX_ITERATIONS = 10, + kSplineTableSize = 11, + kSampleStepSize = 1.0 / (kSplineTableSize - 1.0), + float32ArraySupported = typeof Float32Array !== 'undefined'; + + /* Must contain four arguments. */ + if (arguments.length !== 4) { + return false; + } + + /* Arguments must be numbers. */ + for (var i = 0; i < 4; ++i) { + if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) { + return false; + } + } + + /* X values must be in the [0, 1] range. */ + mX1 = Math.min(mX1, 1); + mX2 = Math.min(mX2, 1); + mX1 = Math.max(mX1, 0); + mX2 = Math.max(mX2, 0); + var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); + function A(aA1, aA2) { + return 1.0 - 3.0 * aA2 + 3.0 * aA1; + } + function B(aA1, aA2) { + return 3.0 * aA2 - 6.0 * aA1; + } + function C(aA1) { + return 3.0 * aA1; + } + function calcBezier(aT, aA1, aA2) { + return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; + } + function getSlope(aT, aA1, aA2) { + return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); + } + function newtonRaphsonIterate(aX, aGuessT) { + for (var _i = 0; _i < NEWTON_ITERATIONS; ++_i) { + var currentSlope = getSlope(aGuessT, mX1, mX2); + if (currentSlope === 0.0) { + return aGuessT; + } + var currentX = calcBezier(aGuessT, mX1, mX2) - aX; + aGuessT -= currentX / currentSlope; + } + return aGuessT; + } + function calcSampleValues() { + for (var _i2 = 0; _i2 < kSplineTableSize; ++_i2) { + mSampleValues[_i2] = calcBezier(_i2 * kSampleStepSize, mX1, mX2); + } + } + function binarySubdivide(aX, aA, aB) { + var currentX, + currentT, + i = 0; + do { + currentT = aA + (aB - aA) / 2.0; + currentX = calcBezier(currentT, mX1, mX2) - aX; + if (currentX > 0.0) { + aB = currentT; + } else { + aA = currentT; + } + } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); + return currentT; + } + function getTForX(aX) { + var intervalStart = 0.0, + currentSample = 1, + lastSample = kSplineTableSize - 1; + for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) { + intervalStart += kSampleStepSize; + } + --currentSample; + var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]), + guessForT = intervalStart + dist * kSampleStepSize, + initialSlope = getSlope(guessForT, mX1, mX2); + if (initialSlope >= NEWTON_MIN_SLOPE) { + return newtonRaphsonIterate(aX, guessForT); + } else if (initialSlope === 0.0) { + return guessForT; + } else { + return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize); + } + } + var _precomputed = false; + function precompute() { + _precomputed = true; + if (mX1 !== mY1 || mX2 !== mY2) { + calcSampleValues(); + } + } + var f = function f(aX) { + if (!_precomputed) { + precompute(); + } + if (mX1 === mY1 && mX2 === mY2) { + return aX; + } + if (aX === 0) { + return 0; + } + if (aX === 1) { + return 1; + } + return calcBezier(getTForX(aX), mY1, mY2); + }; + f.getControlPoints = function () { + return [{ + x: mX1, + y: mY1 + }, { + x: mX2, + y: mY2 + }]; + }; + var str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")"; + f.toString = function () { + return str; + }; + return f; + } + + /*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */ + /* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass + then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */ + var generateSpringRK4 = function () { + function springAccelerationForState(state) { + return -state.tension * state.x - state.friction * state.v; + } + function springEvaluateStateWithDerivative(initialState, dt, derivative) { + var state = { + x: initialState.x + derivative.dx * dt, + v: initialState.v + derivative.dv * dt, + tension: initialState.tension, + friction: initialState.friction + }; + return { + dx: state.v, + dv: springAccelerationForState(state) + }; + } + function springIntegrateState(state, dt) { + var a = { + dx: state.v, + dv: springAccelerationForState(state) + }, + b = springEvaluateStateWithDerivative(state, dt * 0.5, a), + c = springEvaluateStateWithDerivative(state, dt * 0.5, b), + d = springEvaluateStateWithDerivative(state, dt, c), + dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx), + dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv); + state.x = state.x + dxdt * dt; + state.v = state.v + dvdt * dt; + return state; + } + return function springRK4Factory(tension, friction, duration) { + var initState = { + x: -1, + v: 0, + tension: null, + friction: null + }, + path = [0], + time_lapsed = 0, + tolerance = 1 / 10000, + DT = 16 / 1000, + have_duration, + dt, + last_state; + tension = parseFloat(tension) || 500; + friction = parseFloat(friction) || 20; + duration = duration || null; + initState.tension = tension; + initState.friction = friction; + have_duration = duration !== null; + + /* Calculate the actual time it takes for this animation to complete with the provided conditions. */ + if (have_duration) { + /* Run the simulation without a duration. */ + time_lapsed = springRK4Factory(tension, friction); + /* Compute the adjusted time delta. */ + dt = time_lapsed / duration * DT; + } else { + dt = DT; + } + for (;;) { + /* Next/step function .*/ + last_state = springIntegrateState(last_state || initState, dt); + /* Store the position. */ + path.push(1 + last_state.x); + time_lapsed += 16; + /* If the change threshold is reached, break. */ + if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) { + break; + } + } + + /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the + computed path and returns a snapshot of the position according to a given percentComplete. */ + return !have_duration ? time_lapsed : function (percentComplete) { + return path[percentComplete * (path.length - 1) | 0]; + }; + }; + }(); + + var cubicBezier = function cubicBezier(t1, p1, t2, p2) { + var bezier = generateCubicBezier(t1, p1, t2, p2); + return function (start, end, percent) { + return start + (end - start) * bezier(percent); + }; + }; + var easings = { + 'linear': function linear(start, end, percent) { + return start + (end - start) * percent; + }, + // default easings + 'ease': cubicBezier(0.25, 0.1, 0.25, 1), + 'ease-in': cubicBezier(0.42, 0, 1, 1), + 'ease-out': cubicBezier(0, 0, 0.58, 1), + 'ease-in-out': cubicBezier(0.42, 0, 0.58, 1), + // sine + 'ease-in-sine': cubicBezier(0.47, 0, 0.745, 0.715), + 'ease-out-sine': cubicBezier(0.39, 0.575, 0.565, 1), + 'ease-in-out-sine': cubicBezier(0.445, 0.05, 0.55, 0.95), + // quad + 'ease-in-quad': cubicBezier(0.55, 0.085, 0.68, 0.53), + 'ease-out-quad': cubicBezier(0.25, 0.46, 0.45, 0.94), + 'ease-in-out-quad': cubicBezier(0.455, 0.03, 0.515, 0.955), + // cubic + 'ease-in-cubic': cubicBezier(0.55, 0.055, 0.675, 0.19), + 'ease-out-cubic': cubicBezier(0.215, 0.61, 0.355, 1), + 'ease-in-out-cubic': cubicBezier(0.645, 0.045, 0.355, 1), + // quart + 'ease-in-quart': cubicBezier(0.895, 0.03, 0.685, 0.22), + 'ease-out-quart': cubicBezier(0.165, 0.84, 0.44, 1), + 'ease-in-out-quart': cubicBezier(0.77, 0, 0.175, 1), + // quint + 'ease-in-quint': cubicBezier(0.755, 0.05, 0.855, 0.06), + 'ease-out-quint': cubicBezier(0.23, 1, 0.32, 1), + 'ease-in-out-quint': cubicBezier(0.86, 0, 0.07, 1), + // expo + 'ease-in-expo': cubicBezier(0.95, 0.05, 0.795, 0.035), + 'ease-out-expo': cubicBezier(0.19, 1, 0.22, 1), + 'ease-in-out-expo': cubicBezier(1, 0, 0, 1), + // circ + 'ease-in-circ': cubicBezier(0.6, 0.04, 0.98, 0.335), + 'ease-out-circ': cubicBezier(0.075, 0.82, 0.165, 1), + 'ease-in-out-circ': cubicBezier(0.785, 0.135, 0.15, 0.86), + // user param easings... + + 'spring': function spring(tension, friction, duration) { + if (duration === 0) { + // can't get a spring w/ duration 0 + return easings.linear; // duration 0 => jump to end so impl doesn't matter + } + + var spring = generateSpringRK4(tension, friction, duration); + return function (start, end, percent) { + return start + (end - start) * spring(percent); + }; + }, + 'cubic-bezier': cubicBezier + }; + + function getEasedValue(type, start, end, percent, easingFn) { + if (percent === 1) { + return end; + } + if (start === end) { + return end; + } + var val = easingFn(start, end, percent); + if (type == null) { + return val; + } + if (type.roundValue || type.color) { + val = Math.round(val); + } + if (type.min !== undefined) { + val = Math.max(val, type.min); + } + if (type.max !== undefined) { + val = Math.min(val, type.max); + } + return val; + } + function getValue(prop, spec) { + if (prop.pfValue != null || prop.value != null) { + if (prop.pfValue != null && (spec == null || spec.type.units !== '%')) { + return prop.pfValue; + } else { + return prop.value; + } + } else { + return prop; + } + } + function ease(startProp, endProp, percent, easingFn, propSpec) { + var type = propSpec != null ? propSpec.type : null; + if (percent < 0) { + percent = 0; + } else if (percent > 1) { + percent = 1; + } + var start = getValue(startProp, propSpec); + var end = getValue(endProp, propSpec); + if (number$1(start) && number$1(end)) { + return getEasedValue(type, start, end, percent, easingFn); + } else if (array(start) && array(end)) { + var easedArr = []; + for (var i = 0; i < end.length; i++) { + var si = start[i]; + var ei = end[i]; + if (si != null && ei != null) { + var val = getEasedValue(type, si, ei, percent, easingFn); + easedArr.push(val); + } else { + easedArr.push(ei); + } + } + return easedArr; + } + return undefined; + } + + function step$1(self, ani, now, isCore) { + var isEles = !isCore; + var _p = self._private; + var ani_p = ani._private; + var pEasing = ani_p.easing; + var startTime = ani_p.startTime; + var cy = isCore ? self : self.cy(); + var style = cy.style(); + if (!ani_p.easingImpl) { + if (pEasing == null) { + // use default + ani_p.easingImpl = easings['linear']; + } else { + // then define w/ name + var easingVals; + if (string(pEasing)) { + var easingProp = style.parse('transition-timing-function', pEasing); + easingVals = easingProp.value; + } else { + // then assume preparsed array + easingVals = pEasing; + } + var name, args; + if (string(easingVals)) { + name = easingVals; + args = []; + } else { + name = easingVals[1]; + args = easingVals.slice(2).map(function (n) { + return +n; + }); + } + if (args.length > 0) { + // create with args + if (name === 'spring') { + args.push(ani_p.duration); // need duration to generate spring + } + + ani_p.easingImpl = easings[name].apply(null, args); + } else { + // static impl by name + ani_p.easingImpl = easings[name]; + } + } + } + var easing = ani_p.easingImpl; + var percent; + if (ani_p.duration === 0) { + percent = 1; + } else { + percent = (now - startTime) / ani_p.duration; + } + if (ani_p.applying) { + percent = ani_p.progress; + } + if (percent < 0) { + percent = 0; + } else if (percent > 1) { + percent = 1; + } + if (ani_p.delay == null) { + // then update + + var startPos = ani_p.startPosition; + var endPos = ani_p.position; + if (endPos && isEles && !self.locked()) { + var newPos = {}; + if (valid(startPos.x, endPos.x)) { + newPos.x = ease(startPos.x, endPos.x, percent, easing); + } + if (valid(startPos.y, endPos.y)) { + newPos.y = ease(startPos.y, endPos.y, percent, easing); + } + self.position(newPos); + } + var startPan = ani_p.startPan; + var endPan = ani_p.pan; + var pan = _p.pan; + var animatingPan = endPan != null && isCore; + if (animatingPan) { + if (valid(startPan.x, endPan.x)) { + pan.x = ease(startPan.x, endPan.x, percent, easing); + } + if (valid(startPan.y, endPan.y)) { + pan.y = ease(startPan.y, endPan.y, percent, easing); + } + self.emit('pan'); + } + var startZoom = ani_p.startZoom; + var endZoom = ani_p.zoom; + var animatingZoom = endZoom != null && isCore; + if (animatingZoom) { + if (valid(startZoom, endZoom)) { + _p.zoom = bound(_p.minZoom, ease(startZoom, endZoom, percent, easing), _p.maxZoom); + } + self.emit('zoom'); + } + if (animatingPan || animatingZoom) { + self.emit('viewport'); + } + var props = ani_p.style; + if (props && props.length > 0 && isEles) { + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + var _name = prop.name; + var end = prop; + var start = ani_p.startStyle[_name]; + var propSpec = style.properties[start.name]; + var easedVal = ease(start, end, percent, easing, propSpec); + style.overrideBypass(self, _name, easedVal); + } // for props + + self.emit('style'); + } // if + } + + ani_p.progress = percent; + return percent; + } + function valid(start, end) { + if (start == null || end == null) { + return false; + } + if (number$1(start) && number$1(end)) { + return true; + } else if (start && end) { + return true; + } + return false; + } + + function startAnimation(self, ani, now, isCore) { + var ani_p = ani._private; + ani_p.started = true; + ani_p.startTime = now - ani_p.progress * ani_p.duration; + } + + function stepAll(now, cy) { + var eles = cy._private.aniEles; + var doneEles = []; + function stepOne(ele, isCore) { + var _p = ele._private; + var current = _p.animation.current; + var queue = _p.animation.queue; + var ranAnis = false; + + // if nothing currently animating, get something from the queue + if (current.length === 0) { + var next = queue.shift(); + if (next) { + current.push(next); + } + } + var callbacks = function callbacks(_callbacks) { + for (var j = _callbacks.length - 1; j >= 0; j--) { + var cb = _callbacks[j]; + cb(); + } + _callbacks.splice(0, _callbacks.length); + }; + + // step and remove if done + for (var i = current.length - 1; i >= 0; i--) { + var ani = current[i]; + var ani_p = ani._private; + if (ani_p.stopped) { + current.splice(i, 1); + ani_p.hooked = false; + ani_p.playing = false; + ani_p.started = false; + callbacks(ani_p.frames); + continue; + } + if (!ani_p.playing && !ani_p.applying) { + continue; + } + + // an apply() while playing shouldn't do anything + if (ani_p.playing && ani_p.applying) { + ani_p.applying = false; + } + if (!ani_p.started) { + startAnimation(ele, ani, now); + } + step$1(ele, ani, now, isCore); + if (ani_p.applying) { + ani_p.applying = false; + } + callbacks(ani_p.frames); + if (ani_p.step != null) { + ani_p.step(now); + } + if (ani.completed()) { + current.splice(i, 1); + ani_p.hooked = false; + ani_p.playing = false; + ani_p.started = false; + callbacks(ani_p.completes); + } + ranAnis = true; + } + if (!isCore && current.length === 0 && queue.length === 0) { + doneEles.push(ele); + } + return ranAnis; + } // stepElement + + // handle all eles + var ranEleAni = false; + for (var e = 0; e < eles.length; e++) { + var ele = eles[e]; + var handledThisEle = stepOne(ele); + ranEleAni = ranEleAni || handledThisEle; + } // each element + + var ranCoreAni = stepOne(cy, true); + + // notify renderer + if (ranEleAni || ranCoreAni) { + if (eles.length > 0) { + cy.notify('draw', eles); + } else { + cy.notify('draw'); + } + } + + // remove elements from list of currently animating if its queues are empty + eles.unmerge(doneEles); + cy.emit('step'); + } // stepAll + + var corefn$8 = { + // pull in animation functions + animate: define.animate(), + animation: define.animation(), + animated: define.animated(), + clearQueue: define.clearQueue(), + delay: define.delay(), + delayAnimation: define.delayAnimation(), + stop: define.stop(), + addToAnimationPool: function addToAnimationPool(eles) { + var cy = this; + if (!cy.styleEnabled()) { + return; + } // save cycles when no style used + + cy._private.aniEles.merge(eles); + }, + stopAnimationLoop: function stopAnimationLoop() { + this._private.animationsRunning = false; + }, + startAnimationLoop: function startAnimationLoop() { + var cy = this; + cy._private.animationsRunning = true; + if (!cy.styleEnabled()) { + return; + } // save cycles when no style used + + // NB the animation loop will exec in headless environments if style enabled + // and explicit cy.destroy() is necessary to stop the loop + + function headlessStep() { + if (!cy._private.animationsRunning) { + return; + } + requestAnimationFrame(function animationStep(now) { + stepAll(now, cy); + headlessStep(); + }); + } + var renderer = cy.renderer(); + if (renderer && renderer.beforeRender) { + // let the renderer schedule animations + renderer.beforeRender(function rendererAnimationStep(willDraw, now) { + stepAll(now, cy); + }, renderer.beforeRenderPriorities.animations); + } else { + // manage the animation loop ourselves + headlessStep(); // first call + } + } + }; + + var emitterOptions = { + qualifierCompare: function qualifierCompare(selector1, selector2) { + if (selector1 == null || selector2 == null) { + return selector1 == null && selector2 == null; + } else { + return selector1.sameText(selector2); + } + }, + eventMatches: function eventMatches(cy, listener, eventObj) { + var selector = listener.qualifier; + if (selector != null) { + return cy !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target); + } + return true; + }, + addEventFields: function addEventFields(cy, evt) { + evt.cy = cy; + evt.target = cy; + }, + callbackContext: function callbackContext(cy, listener, eventObj) { + return listener.qualifier != null ? eventObj.target : cy; + } + }; + var argSelector = function argSelector(arg) { + if (string(arg)) { + return new Selector(arg); + } else { + return arg; + } + }; + var elesfn = { + createEmitter: function createEmitter() { + var _p = this._private; + if (!_p.emitter) { + _p.emitter = new Emitter(emitterOptions, this); + } + return this; + }, + emitter: function emitter() { + return this._private.emitter; + }, + on: function on(events, selector, callback) { + this.emitter().on(events, argSelector(selector), callback); + return this; + }, + removeListener: function removeListener(events, selector, callback) { + this.emitter().removeListener(events, argSelector(selector), callback); + return this; + }, + removeAllListeners: function removeAllListeners() { + this.emitter().removeAllListeners(); + return this; + }, + one: function one(events, selector, callback) { + this.emitter().one(events, argSelector(selector), callback); + return this; + }, + once: function once(events, selector, callback) { + this.emitter().one(events, argSelector(selector), callback); + return this; + }, + emit: function emit(events, extraParams) { + this.emitter().emit(events, extraParams); + return this; + }, + emitAndNotify: function emitAndNotify(event, eles) { + this.emit(event); + this.notify(event, eles); + return this; + } + }; + define.eventAliasesOn(elesfn); + + var corefn$7 = { + png: function png(options) { + var renderer = this._private.renderer; + options = options || {}; + return renderer.png(options); + }, + jpg: function jpg(options) { + var renderer = this._private.renderer; + options = options || {}; + options.bg = options.bg || '#fff'; + return renderer.jpg(options); + } + }; + corefn$7.jpeg = corefn$7.jpg; + + var corefn$6 = { + layout: function layout(options) { + var cy = this; + if (options == null) { + error('Layout options must be specified to make a layout'); + return; + } + if (options.name == null) { + error('A `name` must be specified to make a layout'); + return; + } + var name = options.name; + var Layout = cy.extension('layout', name); + if (Layout == null) { + error('No such layout `' + name + '` found. Did you forget to import it and `cytoscape.use()` it?'); + return; + } + var eles; + if (string(options.eles)) { + eles = cy.$(options.eles); + } else { + eles = options.eles != null ? options.eles : cy.$(); + } + var layout = new Layout(extend({}, options, { + cy: cy, + eles: eles + })); + return layout; + } + }; + corefn$6.createLayout = corefn$6.makeLayout = corefn$6.layout; + + var corefn$5 = { + notify: function notify(eventName, eventEles) { + var _p = this._private; + if (this.batching()) { + _p.batchNotifications = _p.batchNotifications || {}; + var eles = _p.batchNotifications[eventName] = _p.batchNotifications[eventName] || this.collection(); + if (eventEles != null) { + eles.merge(eventEles); + } + return; // notifications are disabled during batching + } + + if (!_p.notificationsEnabled) { + return; + } // exit on disabled + + var renderer = this.renderer(); + + // exit if destroy() called on core or renderer in between frames #1499 #1528 + if (this.destroyed() || !renderer) { + return; + } + renderer.notify(eventName, eventEles); + }, + notifications: function notifications(bool) { + var p = this._private; + if (bool === undefined) { + return p.notificationsEnabled; + } else { + p.notificationsEnabled = bool ? true : false; + } + return this; + }, + noNotifications: function noNotifications(callback) { + this.notifications(false); + callback(); + this.notifications(true); + }, + batching: function batching() { + return this._private.batchCount > 0; + }, + startBatch: function startBatch() { + var _p = this._private; + if (_p.batchCount == null) { + _p.batchCount = 0; + } + if (_p.batchCount === 0) { + _p.batchStyleEles = this.collection(); + _p.batchNotifications = {}; + } + _p.batchCount++; + return this; + }, + endBatch: function endBatch() { + var _p = this._private; + if (_p.batchCount === 0) { + return this; + } + _p.batchCount--; + if (_p.batchCount === 0) { + // update style for dirty eles + _p.batchStyleEles.updateStyle(); + var renderer = this.renderer(); + + // notify the renderer of queued eles and event types + Object.keys(_p.batchNotifications).forEach(function (eventName) { + var eles = _p.batchNotifications[eventName]; + if (eles.empty()) { + renderer.notify(eventName); + } else { + renderer.notify(eventName, eles); + } + }); + } + return this; + }, + batch: function batch(callback) { + this.startBatch(); + callback(); + this.endBatch(); + return this; + }, + // for backwards compatibility + batchData: function batchData(map) { + var cy = this; + return this.batch(function () { + var ids = Object.keys(map); + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + var data = map[id]; + var ele = cy.getElementById(id); + ele.data(data); + } + }); + } + }; + + var rendererDefaults = defaults$g({ + hideEdgesOnViewport: false, + textureOnViewport: false, + motionBlur: false, + motionBlurOpacity: 0.05, + pixelRatio: undefined, + desktopTapThreshold: 4, + touchTapThreshold: 8, + wheelSensitivity: 1, + debug: false, + showFps: false + }); + var corefn$4 = { + renderTo: function renderTo(context, zoom, pan, pxRatio) { + var r = this._private.renderer; + r.renderTo(context, zoom, pan, pxRatio); + return this; + }, + renderer: function renderer() { + return this._private.renderer; + }, + forceRender: function forceRender() { + this.notify('draw'); + return this; + }, + resize: function resize() { + this.invalidateSize(); + this.emitAndNotify('resize'); + return this; + }, + initRenderer: function initRenderer(options) { + var cy = this; + var RendererProto = cy.extension('renderer', options.name); + if (RendererProto == null) { + error("Can not initialise: No such renderer `".concat(options.name, "` found. Did you forget to import it and `cytoscape.use()` it?")); + return; + } + if (options.wheelSensitivity !== undefined) { + warn("You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine."); + } + var rOpts = rendererDefaults(options); + rOpts.cy = cy; + cy._private.renderer = new RendererProto(rOpts); + this.notify('init'); + }, + destroyRenderer: function destroyRenderer() { + var cy = this; + cy.notify('destroy'); // destroy the renderer + + var domEle = cy.container(); + if (domEle) { + domEle._cyreg = null; + while (domEle.childNodes.length > 0) { + domEle.removeChild(domEle.childNodes[0]); + } + } + cy._private.renderer = null; // to be extra safe, remove the ref + cy.mutableElements().forEach(function (ele) { + var _p = ele._private; + _p.rscratch = {}; + _p.rstyle = {}; + _p.animation.current = []; + _p.animation.queue = []; + }); + }, + onRender: function onRender(fn) { + return this.on('render', fn); + }, + offRender: function offRender(fn) { + return this.off('render', fn); + } + }; + corefn$4.invalidateDimensions = corefn$4.resize; + + var corefn$3 = { + // get a collection + // - empty collection on no args + // - collection of elements in the graph on selector arg + // - guarantee a returned collection when elements or collection specified + collection: function collection(eles, opts) { + if (string(eles)) { + return this.$(eles); + } else if (elementOrCollection(eles)) { + return eles.collection(); + } else if (array(eles)) { + if (!opts) { + opts = {}; + } + return new Collection(this, eles, opts.unique, opts.removed); + } + return new Collection(this); + }, + nodes: function nodes(selector) { + var nodes = this.$(function (ele) { + return ele.isNode(); + }); + if (selector) { + return nodes.filter(selector); + } + return nodes; + }, + edges: function edges(selector) { + var edges = this.$(function (ele) { + return ele.isEdge(); + }); + if (selector) { + return edges.filter(selector); + } + return edges; + }, + // search the graph like jQuery + $: function $(selector) { + var eles = this._private.elements; + if (selector) { + return eles.filter(selector); + } else { + return eles.spawnSelf(); + } + }, + mutableElements: function mutableElements() { + return this._private.elements; + } + }; + + // aliases + corefn$3.elements = corefn$3.filter = corefn$3.$; + + var styfn$8 = {}; + + // keys for style blocks, e.g. ttfftt + var TRUE = 't'; + var FALSE = 'f'; + + // (potentially expensive calculation) + // apply the style to the element based on + // - its bypass + // - what selectors match it + styfn$8.apply = function (eles) { + var self = this; + var _p = self._private; + var cy = _p.cy; + var updatedEles = cy.collection(); + for (var ie = 0; ie < eles.length; ie++) { + var ele = eles[ie]; + var cxtMeta = self.getContextMeta(ele); + if (cxtMeta.empty) { + continue; + } + var cxtStyle = self.getContextStyle(cxtMeta); + var app = self.applyContextStyle(cxtMeta, cxtStyle, ele); + if (ele._private.appliedInitStyle) { + self.updateTransitions(ele, app.diffProps); + } else { + ele._private.appliedInitStyle = true; + } + var hintsDiff = self.updateStyleHints(ele); + if (hintsDiff) { + updatedEles.push(ele); + } + } // for elements + + return updatedEles; + }; + styfn$8.getPropertiesDiff = function (oldCxtKey, newCxtKey) { + var self = this; + var cache = self._private.propDiffs = self._private.propDiffs || {}; + var dualCxtKey = oldCxtKey + '-' + newCxtKey; + var cachedVal = cache[dualCxtKey]; + if (cachedVal) { + return cachedVal; + } + var diffProps = []; + var addedProp = {}; + for (var i = 0; i < self.length; i++) { + var cxt = self[i]; + var oldHasCxt = oldCxtKey[i] === TRUE; + var newHasCxt = newCxtKey[i] === TRUE; + var cxtHasDiffed = oldHasCxt !== newHasCxt; + var cxtHasMappedProps = cxt.mappedProperties.length > 0; + if (cxtHasDiffed || newHasCxt && cxtHasMappedProps) { + var props = void 0; + if (cxtHasDiffed && cxtHasMappedProps) { + props = cxt.properties; // suffices b/c mappedProperties is a subset of properties + } else if (cxtHasDiffed) { + props = cxt.properties; // need to check them all + } else if (cxtHasMappedProps) { + props = cxt.mappedProperties; // only need to check mapped + } + + for (var j = 0; j < props.length; j++) { + var prop = props[j]; + var name = prop.name; + + // if a later context overrides this property, then the fact that this context has switched/diffed doesn't matter + // (semi expensive check since it makes this function O(n^2) on context length, but worth it since overall result + // is cached) + var laterCxtOverrides = false; + for (var k = i + 1; k < self.length; k++) { + var laterCxt = self[k]; + var hasLaterCxt = newCxtKey[k] === TRUE; + if (!hasLaterCxt) { + continue; + } // can't override unless the context is active + + laterCxtOverrides = laterCxt.properties[prop.name] != null; + if (laterCxtOverrides) { + break; + } // exit early as long as one later context overrides + } + + if (!addedProp[name] && !laterCxtOverrides) { + addedProp[name] = true; + diffProps.push(name); + } + } // for props + } // if + } // for contexts + + cache[dualCxtKey] = diffProps; + return diffProps; + }; + styfn$8.getContextMeta = function (ele) { + var self = this; + var cxtKey = ''; + var diffProps; + var prevKey = ele._private.styleCxtKey || ''; + + // get the cxt key + for (var i = 0; i < self.length; i++) { + var context = self[i]; + var contextSelectorMatches = context.selector && context.selector.matches(ele); // NB: context.selector may be null for 'core' + + if (contextSelectorMatches) { + cxtKey += TRUE; + } else { + cxtKey += FALSE; + } + } // for context + + diffProps = self.getPropertiesDiff(prevKey, cxtKey); + ele._private.styleCxtKey = cxtKey; + return { + key: cxtKey, + diffPropNames: diffProps, + empty: diffProps.length === 0 + }; + }; + + // gets a computed ele style object based on matched contexts + styfn$8.getContextStyle = function (cxtMeta) { + var cxtKey = cxtMeta.key; + var self = this; + var cxtStyles = this._private.contextStyles = this._private.contextStyles || {}; + + // if already computed style, returned cached copy + if (cxtStyles[cxtKey]) { + return cxtStyles[cxtKey]; + } + var style = { + _private: { + key: cxtKey + } + }; + for (var i = 0; i < self.length; i++) { + var cxt = self[i]; + var hasCxt = cxtKey[i] === TRUE; + if (!hasCxt) { + continue; + } + for (var j = 0; j < cxt.properties.length; j++) { + var prop = cxt.properties[j]; + style[prop.name] = prop; + } + } + cxtStyles[cxtKey] = style; + return style; + }; + styfn$8.applyContextStyle = function (cxtMeta, cxtStyle, ele) { + var self = this; + var diffProps = cxtMeta.diffPropNames; + var retDiffProps = {}; + var types = self.types; + for (var i = 0; i < diffProps.length; i++) { + var diffPropName = diffProps[i]; + var cxtProp = cxtStyle[diffPropName]; + var eleProp = ele.pstyle(diffPropName); + if (!cxtProp) { + // no context prop means delete + if (!eleProp) { + continue; // no existing prop means nothing needs to be removed + // nb affects initial application on mapped values like control-point-distances + } else if (eleProp.bypass) { + cxtProp = { + name: diffPropName, + deleteBypassed: true + }; + } else { + cxtProp = { + name: diffPropName, + "delete": true + }; + } + } + + // save cycles when the context prop doesn't need to be applied + if (eleProp === cxtProp) { + continue; + } + + // save cycles when a mapped context prop doesn't need to be applied + if (cxtProp.mapped === types.fn // context prop is function mapper + && eleProp != null // some props can be null even by default (e.g. a prop that overrides another one) + && eleProp.mapping != null // ele prop is a concrete value from from a mapper + && eleProp.mapping.value === cxtProp.value // the current prop on the ele is a flat prop value for the function mapper + ) { + // NB don't write to cxtProp, as it's shared among eles (stored in stylesheet) + var mapping = eleProp.mapping; // can write to mapping, as it's a per-ele copy + var fnValue = mapping.fnValue = cxtProp.value(ele); // temporarily cache the value in case of a miss + + if (fnValue === mapping.prevFnValue) { + continue; + } + } + var retDiffProp = retDiffProps[diffPropName] = { + prev: eleProp + }; + self.applyParsedProperty(ele, cxtProp); + retDiffProp.next = ele.pstyle(diffPropName); + if (retDiffProp.next && retDiffProp.next.bypass) { + retDiffProp.next = retDiffProp.next.bypassed; + } + } + return { + diffProps: retDiffProps + }; + }; + styfn$8.updateStyleHints = function (ele) { + var _p = ele._private; + var self = this; + var propNames = self.propertyGroupNames; + var propGrKeys = self.propertyGroupKeys; + var propHash = function propHash(ele, propNames, seedKey) { + return self.getPropertiesHash(ele, propNames, seedKey); + }; + var oldStyleKey = _p.styleKey; + if (ele.removed()) { + return false; + } + var isNode = _p.group === 'nodes'; + + // get the style key hashes per prop group + // but lazily -- only use non-default prop values to reduce the number of hashes + // + + var overriddenStyles = ele._private.style; + propNames = Object.keys(overriddenStyles); + for (var i = 0; i < propGrKeys.length; i++) { + var grKey = propGrKeys[i]; + _p.styleKeys[grKey] = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]; + } + var updateGrKey1 = function updateGrKey1(val, grKey) { + return _p.styleKeys[grKey][0] = hashInt(val, _p.styleKeys[grKey][0]); + }; + var updateGrKey2 = function updateGrKey2(val, grKey) { + return _p.styleKeys[grKey][1] = hashIntAlt(val, _p.styleKeys[grKey][1]); + }; + var updateGrKey = function updateGrKey(val, grKey) { + updateGrKey1(val, grKey); + updateGrKey2(val, grKey); + }; + var updateGrKeyWStr = function updateGrKeyWStr(strVal, grKey) { + for (var j = 0; j < strVal.length; j++) { + var ch = strVal.charCodeAt(j); + updateGrKey1(ch, grKey); + updateGrKey2(ch, grKey); + } + }; + + // - hashing works on 32 bit ints b/c we use bitwise ops + // - small numbers get cut off (e.g. 0.123 is seen as 0 by the hashing function) + // - raise up small numbers so more significant digits are seen by hashing + // - make small numbers larger than a normal value to avoid collisions + // - works in practice and it's relatively cheap + var N = 2000000000; + var cleanNum = function cleanNum(val) { + return -128 < val && val < 128 && Math.floor(val) !== val ? N - (val * 1024 | 0) : val; + }; + for (var _i = 0; _i < propNames.length; _i++) { + var name = propNames[_i]; + var parsedProp = overriddenStyles[name]; + if (parsedProp == null) { + continue; + } + var propInfo = this.properties[name]; + var type = propInfo.type; + var _grKey = propInfo.groupKey; + var normalizedNumberVal = void 0; + if (propInfo.hashOverride != null) { + normalizedNumberVal = propInfo.hashOverride(ele, parsedProp); + } else if (parsedProp.pfValue != null) { + normalizedNumberVal = parsedProp.pfValue; + } + + // might not be a number if it allows enums + var numberVal = propInfo.enums == null ? parsedProp.value : null; + var haveNormNum = normalizedNumberVal != null; + var haveUnitedNum = numberVal != null; + var haveNum = haveNormNum || haveUnitedNum; + var units = parsedProp.units; + + // numbers are cheaper to hash than strings + // 1 hash op vs n hash ops (for length n string) + if (type.number && haveNum && !type.multiple) { + var v = haveNormNum ? normalizedNumberVal : numberVal; + updateGrKey(cleanNum(v), _grKey); + if (!haveNormNum && units != null) { + updateGrKeyWStr(units, _grKey); + } + } else { + updateGrKeyWStr(parsedProp.strValue, _grKey); + } + } + + // overall style key + // + + var hash = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]; + for (var _i2 = 0; _i2 < propGrKeys.length; _i2++) { + var _grKey2 = propGrKeys[_i2]; + var grHash = _p.styleKeys[_grKey2]; + hash[0] = hashInt(grHash[0], hash[0]); + hash[1] = hashIntAlt(grHash[1], hash[1]); + } + _p.styleKey = combineHashes(hash[0], hash[1]); + + // label dims + // + + var sk = _p.styleKeys; + _p.labelDimsKey = combineHashesArray(sk.labelDimensions); + var labelKeys = propHash(ele, ['label'], sk.labelDimensions); + _p.labelKey = combineHashesArray(labelKeys); + _p.labelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, labelKeys)); + if (!isNode) { + var sourceLabelKeys = propHash(ele, ['source-label'], sk.labelDimensions); + _p.sourceLabelKey = combineHashesArray(sourceLabelKeys); + _p.sourceLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, sourceLabelKeys)); + var targetLabelKeys = propHash(ele, ['target-label'], sk.labelDimensions); + _p.targetLabelKey = combineHashesArray(targetLabelKeys); + _p.targetLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, targetLabelKeys)); + } + + // node + // + + if (isNode) { + var _p$styleKeys = _p.styleKeys, + nodeBody = _p$styleKeys.nodeBody, + nodeBorder = _p$styleKeys.nodeBorder, + backgroundImage = _p$styleKeys.backgroundImage, + compound = _p$styleKeys.compound, + pie = _p$styleKeys.pie; + var nodeKeys = [nodeBody, nodeBorder, backgroundImage, compound, pie].filter(function (k) { + return k != null; + }).reduce(hashArrays, [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]); + _p.nodeKey = combineHashesArray(nodeKeys); + _p.hasPie = pie != null && pie[0] !== DEFAULT_HASH_SEED && pie[1] !== DEFAULT_HASH_SEED_ALT; + } + return oldStyleKey !== _p.styleKey; + }; + styfn$8.clearStyleHints = function (ele) { + var _p = ele._private; + _p.styleCxtKey = ''; + _p.styleKeys = {}; + _p.styleKey = null; + _p.labelKey = null; + _p.labelStyleKey = null; + _p.sourceLabelKey = null; + _p.sourceLabelStyleKey = null; + _p.targetLabelKey = null; + _p.targetLabelStyleKey = null; + _p.nodeKey = null; + _p.hasPie = null; + }; + + // apply a property to the style (for internal use) + // returns whether application was successful + // + // now, this function flattens the property, and here's how: + // + // for parsedProp:{ bypass: true, deleteBypass: true } + // no property is generated, instead the bypass property in the + // element's style is replaced by what's pointed to by the `bypassed` + // field in the bypass property (i.e. restoring the property the + // bypass was overriding) + // + // for parsedProp:{ mapped: truthy } + // the generated flattenedProp:{ mapping: prop } + // + // for parsedProp:{ bypass: true } + // the generated flattenedProp:{ bypassed: parsedProp } + styfn$8.applyParsedProperty = function (ele, parsedProp) { + var self = this; + var prop = parsedProp; + var style = ele._private.style; + var flatProp; + var types = self.types; + var type = self.properties[prop.name].type; + var propIsBypass = prop.bypass; + var origProp = style[prop.name]; + var origPropIsBypass = origProp && origProp.bypass; + var _p = ele._private; + var flatPropMapping = 'mapping'; + var getVal = function getVal(p) { + if (p == null) { + return null; + } else if (p.pfValue != null) { + return p.pfValue; + } else { + return p.value; + } + }; + var checkTriggers = function checkTriggers() { + var fromVal = getVal(origProp); + var toVal = getVal(prop); + self.checkTriggers(ele, prop.name, fromVal, toVal); + }; + if (prop && prop.name.substr(0, 3) === 'pie') { + warn('The pie style properties are deprecated. Create charts using background images instead.'); + } + + // edge sanity checks to prevent the client from making serious mistakes + if (parsedProp.name === 'curve-style' && ele.isEdge() && ( + // loops must be bundled beziers + parsedProp.value !== 'bezier' && ele.isLoop() || + // edges connected to compound nodes can not be haystacks + parsedProp.value === 'haystack' && (ele.source().isParent() || ele.target().isParent()))) { + prop = parsedProp = this.parse(parsedProp.name, 'bezier', propIsBypass); + } + if (prop["delete"]) { + // delete the property and use the default value on falsey value + style[prop.name] = undefined; + checkTriggers(); + return true; + } + if (prop.deleteBypassed) { + // delete the property that the + if (!origProp) { + checkTriggers(); + return true; // can't delete if no prop + } else if (origProp.bypass) { + // delete bypassed + origProp.bypassed = undefined; + checkTriggers(); + return true; + } else { + return false; // we're unsuccessful deleting the bypassed + } + } + + // check if we need to delete the current bypass + if (prop.deleteBypass) { + // then this property is just here to indicate we need to delete + if (!origProp) { + checkTriggers(); + return true; // property is already not defined + } else if (origProp.bypass) { + // then replace the bypass property with the original + // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary) + style[prop.name] = origProp.bypassed; + checkTriggers(); + return true; + } else { + return false; // we're unsuccessful deleting the bypass + } + } + + var printMappingErr = function printMappingErr() { + warn('Do not assign mappings to elements without corresponding data (i.e. ele `' + ele.id() + '` has no mapping for property `' + prop.name + '` with data field `' + prop.field + '`); try a `[' + prop.field + ']` selector to limit scope to elements with `' + prop.field + '` defined'); + }; + + // put the property in the style objects + switch (prop.mapped) { + // flatten the property if mapped + case types.mapData: + { + // flatten the field (e.g. data.foo.bar) + var fields = prop.field.split('.'); + var fieldVal = _p.data; + for (var i = 0; i < fields.length && fieldVal; i++) { + var field = fields[i]; + fieldVal = fieldVal[field]; + } + if (fieldVal == null) { + printMappingErr(); + return false; + } + var percent; + if (!number$1(fieldVal)) { + // then don't apply and fall back on the existing style + warn('Do not use continuous mappers without specifying numeric data (i.e. `' + prop.field + ': ' + fieldVal + '` for `' + ele.id() + '` is non-numeric)'); + return false; + } else { + var fieldWidth = prop.fieldMax - prop.fieldMin; + if (fieldWidth === 0) { + // safety check -- not strictly necessary as no props of zero range should be passed here + percent = 0; + } else { + percent = (fieldVal - prop.fieldMin) / fieldWidth; + } + } + + // make sure to bound percent value + if (percent < 0) { + percent = 0; + } else if (percent > 1) { + percent = 1; + } + if (type.color) { + var r1 = prop.valueMin[0]; + var r2 = prop.valueMax[0]; + var g1 = prop.valueMin[1]; + var g2 = prop.valueMax[1]; + var b1 = prop.valueMin[2]; + var b2 = prop.valueMax[2]; + var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3]; + var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3]; + var clr = [Math.round(r1 + (r2 - r1) * percent), Math.round(g1 + (g2 - g1) * percent), Math.round(b1 + (b2 - b1) * percent), Math.round(a1 + (a2 - a1) * percent)]; + flatProp = { + // colours are simple, so just create the flat property instead of expensive string parsing + bypass: prop.bypass, + // we're a bypass if the mapping property is a bypass + name: prop.name, + value: clr, + strValue: 'rgb(' + clr[0] + ', ' + clr[1] + ', ' + clr[2] + ')' + }; + } else if (type.number) { + var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent; + flatProp = this.parse(prop.name, calcValue, prop.bypass, flatPropMapping); + } else { + return false; // can only map to colours and numbers + } + + if (!flatProp) { + // if we can't flatten the property, then don't apply the property and fall back on the existing style + printMappingErr(); + return false; + } + flatProp.mapping = prop; // keep a reference to the mapping + prop = flatProp; // the flattened (mapped) property is the one we want + + break; + } + + // direct mapping + case types.data: + { + // flatten the field (e.g. data.foo.bar) + var _fields = prop.field.split('.'); + var _fieldVal = _p.data; + for (var _i3 = 0; _i3 < _fields.length && _fieldVal; _i3++) { + var _field = _fields[_i3]; + _fieldVal = _fieldVal[_field]; + } + if (_fieldVal != null) { + flatProp = this.parse(prop.name, _fieldVal, prop.bypass, flatPropMapping); + } + if (!flatProp) { + // if we can't flatten the property, then don't apply and fall back on the existing style + printMappingErr(); + return false; + } + flatProp.mapping = prop; // keep a reference to the mapping + prop = flatProp; // the flattened (mapped) property is the one we want + + break; + } + case types.fn: + { + var fn = prop.value; + var fnRetVal = prop.fnValue != null ? prop.fnValue : fn(ele); // check for cached value before calling function + + prop.prevFnValue = fnRetVal; + if (fnRetVal == null) { + warn('Custom function mappers may not return null (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is null)'); + return false; + } + flatProp = this.parse(prop.name, fnRetVal, prop.bypass, flatPropMapping); + if (!flatProp) { + warn('Custom function mappers may not return invalid values for the property type (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is invalid)'); + return false; + } + flatProp.mapping = copy(prop); // keep a reference to the mapping + prop = flatProp; // the flattened (mapped) property is the one we want + + break; + } + case undefined: + break; + // just set the property + + default: + return false; + // not a valid mapping + } + + // if the property is a bypass property, then link the resultant property to the original one + if (propIsBypass) { + if (origPropIsBypass) { + // then this bypass overrides the existing one + prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass + } else { + // then link the orig prop to the new bypass + prop.bypassed = origProp; + } + style[prop.name] = prop; // and set + } else { + // prop is not bypass + if (origPropIsBypass) { + // then keep the orig prop (since it's a bypass) and link to the new prop + origProp.bypassed = prop; + } else { + // then just replace the old prop with the new one + style[prop.name] = prop; + } + } + checkTriggers(); + return true; + }; + styfn$8.cleanElements = function (eles, keepBypasses) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + this.clearStyleHints(ele); + ele.dirtyCompoundBoundsCache(); + ele.dirtyBoundingBoxCache(); + if (!keepBypasses) { + ele._private.style = {}; + } else { + var style = ele._private.style; + var propNames = Object.keys(style); + for (var j = 0; j < propNames.length; j++) { + var propName = propNames[j]; + var eleProp = style[propName]; + if (eleProp != null) { + if (eleProp.bypass) { + eleProp.bypassed = null; + } else { + style[propName] = null; + } + } + } + } + } + }; + + // updates the visual style for all elements (useful for manual style modification after init) + styfn$8.update = function () { + var cy = this._private.cy; + var eles = cy.mutableElements(); + eles.updateStyle(); + }; + + // diffProps : { name => { prev, next } } + styfn$8.updateTransitions = function (ele, diffProps) { + var self = this; + var _p = ele._private; + var props = ele.pstyle('transition-property').value; + var duration = ele.pstyle('transition-duration').pfValue; + var delay = ele.pstyle('transition-delay').pfValue; + if (props.length > 0 && duration > 0) { + var style = {}; + + // build up the style to animate towards + var anyPrev = false; + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + var styProp = ele.pstyle(prop); + var diffProp = diffProps[prop]; + if (!diffProp) { + continue; + } + var prevProp = diffProp.prev; + var fromProp = prevProp; + var toProp = diffProp.next != null ? diffProp.next : styProp; + var diff = false; + var initVal = void 0; + var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity) + + if (!fromProp) { + continue; + } + + // consider px values + if (number$1(fromProp.pfValue) && number$1(toProp.pfValue)) { + diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy + initVal = fromProp.pfValue + initDt * diff; + + // consider numerical values + } else if (number$1(fromProp.value) && number$1(toProp.value)) { + diff = toProp.value - fromProp.value; // nonzero is truthy + initVal = fromProp.value + initDt * diff; + + // consider colour values + } else if (array(fromProp.value) && array(toProp.value)) { + diff = fromProp.value[0] !== toProp.value[0] || fromProp.value[1] !== toProp.value[1] || fromProp.value[2] !== toProp.value[2]; + initVal = fromProp.strValue; + } + + // the previous value is good for an animation only if it's different + if (diff) { + style[prop] = toProp.strValue; // to val + this.applyBypass(ele, prop, initVal); // from val + anyPrev = true; + } + } // end if props allow ani + + // can't transition if there's nothing previous to transition from + if (!anyPrev) { + return; + } + _p.transitioning = true; + new Promise$1(function (resolve) { + if (delay > 0) { + ele.delayAnimation(delay).play().promise().then(resolve); + } else { + resolve(); + } + }).then(function () { + return ele.animation({ + style: style, + duration: duration, + easing: ele.pstyle('transition-timing-function').value, + queue: false + }).play().promise(); + }).then(function () { + // if( !isBypass ){ + self.removeBypasses(ele, props); + ele.emitAndNotify('style'); + // } + + _p.transitioning = false; + }); + } else if (_p.transitioning) { + this.removeBypasses(ele, props); + ele.emitAndNotify('style'); + _p.transitioning = false; + } + }; + styfn$8.checkTrigger = function (ele, name, fromValue, toValue, getTrigger, onTrigger) { + var prop = this.properties[name]; + var triggerCheck = getTrigger(prop); + if (triggerCheck != null && triggerCheck(fromValue, toValue)) { + onTrigger(prop); + } + }; + styfn$8.checkZOrderTrigger = function (ele, name, fromValue, toValue) { + var _this = this; + this.checkTrigger(ele, name, fromValue, toValue, function (prop) { + return prop.triggersZOrder; + }, function () { + _this._private.cy.notify('zorder', ele); + }); + }; + styfn$8.checkBoundsTrigger = function (ele, name, fromValue, toValue) { + this.checkTrigger(ele, name, fromValue, toValue, function (prop) { + return prop.triggersBounds; + }, function (prop) { + ele.dirtyCompoundBoundsCache(); + ele.dirtyBoundingBoxCache(); + + // if the prop change makes the bb of pll bezier edges invalid, + // then dirty the pll edge bb cache as well + if ( + // only for beziers -- so performance of other edges isn't affected + prop.triggersBoundsOfParallelBeziers && (name === 'curve-style' && (fromValue === 'bezier' || toValue === 'bezier') || name === 'display' && (fromValue === 'none' || toValue === 'none'))) { + ele.parallelEdges().forEach(function (pllEdge) { + if (pllEdge.isBundledBezier()) { + pllEdge.dirtyBoundingBoxCache(); + } + }); + } + }); + }; + styfn$8.checkTriggers = function (ele, name, fromValue, toValue) { + ele.dirtyStyleCache(); + this.checkZOrderTrigger(ele, name, fromValue, toValue); + this.checkBoundsTrigger(ele, name, fromValue, toValue); + }; + + var styfn$7 = {}; + + // bypasses are applied to an existing style on an element, and just tacked on temporarily + // returns true iff application was successful for at least 1 specified property + styfn$7.applyBypass = function (eles, name, value, updateTransitions) { + var self = this; + var props = []; + var isBypass = true; + + // put all the properties (can specify one or many) in an array after parsing them + if (name === '*' || name === '**') { + // apply to all property names + + if (value !== undefined) { + for (var i = 0; i < self.properties.length; i++) { + var prop = self.properties[i]; + var _name = prop.name; + var parsedProp = this.parse(_name, value, true); + if (parsedProp) { + props.push(parsedProp); + } + } + } + } else if (string(name)) { + // then parse the single property + var _parsedProp = this.parse(name, value, true); + if (_parsedProp) { + props.push(_parsedProp); + } + } else if (plainObject(name)) { + // then parse each property + var specifiedProps = name; + updateTransitions = value; + var names = Object.keys(specifiedProps); + for (var _i = 0; _i < names.length; _i++) { + var _name2 = names[_i]; + var _value = specifiedProps[_name2]; + if (_value === undefined) { + // try camel case name too + _value = specifiedProps[dash2camel(_name2)]; + } + if (_value !== undefined) { + var _parsedProp2 = this.parse(_name2, _value, true); + if (_parsedProp2) { + props.push(_parsedProp2); + } + } + } + } else { + // can't do anything without well defined properties + return false; + } + + // we've failed if there are no valid properties + if (props.length === 0) { + return false; + } + + // now, apply the bypass properties on the elements + var ret = false; // return true if at least one succesful bypass applied + for (var _i2 = 0; _i2 < eles.length; _i2++) { + // for each ele + var ele = eles[_i2]; + var diffProps = {}; + var diffProp = void 0; + for (var j = 0; j < props.length; j++) { + // for each prop + var _prop = props[j]; + if (updateTransitions) { + var prevProp = ele.pstyle(_prop.name); + diffProp = diffProps[_prop.name] = { + prev: prevProp + }; + } + ret = this.applyParsedProperty(ele, copy(_prop)) || ret; + if (updateTransitions) { + diffProp.next = ele.pstyle(_prop.name); + } + } // for props + + if (ret) { + this.updateStyleHints(ele); + } + if (updateTransitions) { + this.updateTransitions(ele, diffProps, isBypass); + } + } // for eles + + return ret; + }; + + // only useful in specific cases like animation + styfn$7.overrideBypass = function (eles, name, value) { + name = camel2dash(name); + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var prop = ele._private.style[name]; + var type = this.properties[name].type; + var isColor = type.color; + var isMulti = type.mutiple; + var oldValue = !prop ? null : prop.pfValue != null ? prop.pfValue : prop.value; + if (!prop || !prop.bypass) { + // need a bypass if one doesn't exist + this.applyBypass(ele, name, value); + } else { + prop.value = value; + if (prop.pfValue != null) { + prop.pfValue = value; + } + if (isColor) { + prop.strValue = 'rgb(' + value.join(',') + ')'; + } else if (isMulti) { + prop.strValue = value.join(' '); + } else { + prop.strValue = '' + value; + } + this.updateStyleHints(ele); + } + this.checkTriggers(ele, name, oldValue, value); + } + }; + styfn$7.removeAllBypasses = function (eles, updateTransitions) { + return this.removeBypasses(eles, this.propertyNames, updateTransitions); + }; + styfn$7.removeBypasses = function (eles, props, updateTransitions) { + var isBypass = true; + for (var j = 0; j < eles.length; j++) { + var ele = eles[j]; + var diffProps = {}; + for (var i = 0; i < props.length; i++) { + var name = props[i]; + var prop = this.properties[name]; + var prevProp = ele.pstyle(prop.name); + if (!prevProp || !prevProp.bypass) { + // if a bypass doesn't exist for the prop, nothing needs to be removed + continue; + } + var value = ''; // empty => remove bypass + var parsedProp = this.parse(name, value, true); + var diffProp = diffProps[prop.name] = { + prev: prevProp + }; + this.applyParsedProperty(ele, parsedProp); + diffProp.next = ele.pstyle(prop.name); + } // for props + + this.updateStyleHints(ele); + if (updateTransitions) { + this.updateTransitions(ele, diffProps, isBypass); + } + } // for eles + }; + + var styfn$6 = {}; + + // gets what an em size corresponds to in pixels relative to a dom element + styfn$6.getEmSizeInPixels = function () { + var px = this.containerCss('font-size'); + if (px != null) { + return parseFloat(px); + } else { + return 1; // for headless + } + }; + + // gets css property from the core container + styfn$6.containerCss = function (propName) { + var cy = this._private.cy; + var domElement = cy.container(); + var containerWindow = cy.window(); + if (containerWindow && domElement && containerWindow.getComputedStyle) { + return containerWindow.getComputedStyle(domElement).getPropertyValue(propName); + } + }; + + var styfn$5 = {}; + + // gets the rendered style for an element + styfn$5.getRenderedStyle = function (ele, prop) { + if (prop) { + return this.getStylePropertyValue(ele, prop, true); + } else { + return this.getRawStyle(ele, true); + } + }; + + // gets the raw style for an element + styfn$5.getRawStyle = function (ele, isRenderedVal) { + var self = this; + ele = ele[0]; // insure it's an element + + if (ele) { + var rstyle = {}; + for (var i = 0; i < self.properties.length; i++) { + var prop = self.properties[i]; + var val = self.getStylePropertyValue(ele, prop.name, isRenderedVal); + if (val != null) { + rstyle[prop.name] = val; + rstyle[dash2camel(prop.name)] = val; + } + } + return rstyle; + } + }; + styfn$5.getIndexedStyle = function (ele, property, subproperty, index) { + var pstyle = ele.pstyle(property)[subproperty][index]; + return pstyle != null ? pstyle : ele.cy().style().getDefaultProperty(property)[subproperty][0]; + }; + styfn$5.getStylePropertyValue = function (ele, propName, isRenderedVal) { + var self = this; + ele = ele[0]; // insure it's an element + + if (ele) { + var prop = self.properties[propName]; + if (prop.alias) { + prop = prop.pointsTo; + } + var type = prop.type; + var styleProp = ele.pstyle(prop.name); + if (styleProp) { + var value = styleProp.value, + units = styleProp.units, + strValue = styleProp.strValue; + if (isRenderedVal && type.number && value != null && number$1(value)) { + var zoom = ele.cy().zoom(); + var getRenderedValue = function getRenderedValue(val) { + return val * zoom; + }; + var getValueStringWithUnits = function getValueStringWithUnits(val, units) { + return getRenderedValue(val) + units; + }; + var isArrayValue = array(value); + var haveUnits = isArrayValue ? units.every(function (u) { + return u != null; + }) : units != null; + if (haveUnits) { + if (isArrayValue) { + return value.map(function (v, i) { + return getValueStringWithUnits(v, units[i]); + }).join(' '); + } else { + return getValueStringWithUnits(value, units); + } + } else { + if (isArrayValue) { + return value.map(function (v) { + return string(v) ? v : '' + getRenderedValue(v); + }).join(' '); + } else { + return '' + getRenderedValue(value); + } + } + } else if (strValue != null) { + return strValue; + } + } + return null; + } + }; + styfn$5.getAnimationStartStyle = function (ele, aniProps) { + var rstyle = {}; + for (var i = 0; i < aniProps.length; i++) { + var aniProp = aniProps[i]; + var name = aniProp.name; + var styleProp = ele.pstyle(name); + if (styleProp !== undefined) { + // then make a prop of it + if (plainObject(styleProp)) { + styleProp = this.parse(name, styleProp.strValue); + } else { + styleProp = this.parse(name, styleProp); + } + } + if (styleProp) { + rstyle[name] = styleProp; + } + } + return rstyle; + }; + styfn$5.getPropsList = function (propsObj) { + var self = this; + var rstyle = []; + var style = propsObj; + var props = self.properties; + if (style) { + var names = Object.keys(style); + for (var i = 0; i < names.length; i++) { + var name = names[i]; + var val = style[name]; + var prop = props[name] || props[camel2dash(name)]; + var styleProp = this.parse(prop.name, val); + if (styleProp) { + rstyle.push(styleProp); + } + } + } + return rstyle; + }; + styfn$5.getNonDefaultPropertiesHash = function (ele, propNames, seed) { + var hash = seed.slice(); + var name, val, strVal, chVal; + var i, j; + for (i = 0; i < propNames.length; i++) { + name = propNames[i]; + val = ele.pstyle(name, false); + if (val == null) { + continue; + } else if (val.pfValue != null) { + hash[0] = hashInt(chVal, hash[0]); + hash[1] = hashIntAlt(chVal, hash[1]); + } else { + strVal = val.strValue; + for (j = 0; j < strVal.length; j++) { + chVal = strVal.charCodeAt(j); + hash[0] = hashInt(chVal, hash[0]); + hash[1] = hashIntAlt(chVal, hash[1]); + } + } + } + return hash; + }; + styfn$5.getPropertiesHash = styfn$5.getNonDefaultPropertiesHash; + + var styfn$4 = {}; + styfn$4.appendFromJson = function (json) { + var style = this; + for (var i = 0; i < json.length; i++) { + var context = json[i]; + var selector = context.selector; + var props = context.style || context.css; + var names = Object.keys(props); + style.selector(selector); // apply selector + + for (var j = 0; j < names.length; j++) { + var name = names[j]; + var value = props[name]; + style.css(name, value); // apply property + } + } + + return style; + }; + + // accessible cy.style() function + styfn$4.fromJson = function (json) { + var style = this; + style.resetToDefault(); + style.appendFromJson(json); + return style; + }; + + // get json from cy.style() api + styfn$4.json = function () { + var json = []; + for (var i = this.defaultLength; i < this.length; i++) { + var cxt = this[i]; + var selector = cxt.selector; + var props = cxt.properties; + var css = {}; + for (var j = 0; j < props.length; j++) { + var prop = props[j]; + css[prop.name] = prop.strValue; + } + json.push({ + selector: !selector ? 'core' : selector.toString(), + style: css + }); + } + return json; + }; + + var styfn$3 = {}; + styfn$3.appendFromString = function (string) { + var self = this; + var style = this; + var remaining = '' + string; + var selAndBlockStr; + var blockRem; + var propAndValStr; + + // remove comments from the style string + remaining = remaining.replace(/[/][*](\s|.)+?[*][/]/g, ''); + function removeSelAndBlockFromRemaining() { + // remove the parsed selector and block from the remaining text to parse + if (remaining.length > selAndBlockStr.length) { + remaining = remaining.substr(selAndBlockStr.length); + } else { + remaining = ''; + } + } + function removePropAndValFromRem() { + // remove the parsed property and value from the remaining block text to parse + if (blockRem.length > propAndValStr.length) { + blockRem = blockRem.substr(propAndValStr.length); + } else { + blockRem = ''; + } + } + for (;;) { + var nothingLeftToParse = remaining.match(/^\s*$/); + if (nothingLeftToParse) { + break; + } + var selAndBlock = remaining.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/); + if (!selAndBlock) { + warn('Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' + remaining); + break; + } + selAndBlockStr = selAndBlock[0]; + + // parse the selector + var selectorStr = selAndBlock[1]; + if (selectorStr !== 'core') { + var selector = new Selector(selectorStr); + if (selector.invalid) { + warn('Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr); + + // skip this selector and block + removeSelAndBlockFromRemaining(); + continue; + } + } + + // parse the block of properties and values + var blockStr = selAndBlock[2]; + var invalidBlock = false; + blockRem = blockStr; + var props = []; + for (;;) { + var _nothingLeftToParse = blockRem.match(/^\s*$/); + if (_nothingLeftToParse) { + break; + } + var propAndVal = blockRem.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/); + if (!propAndVal) { + warn('Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr); + invalidBlock = true; + break; + } + propAndValStr = propAndVal[0]; + var propStr = propAndVal[1]; + var valStr = propAndVal[2]; + var prop = self.properties[propStr]; + if (!prop) { + warn('Skipping property: Invalid property name in: ' + propAndValStr); + + // skip this property in the block + removePropAndValFromRem(); + continue; + } + var parsedProp = style.parse(propStr, valStr); + if (!parsedProp) { + warn('Skipping property: Invalid property definition in: ' + propAndValStr); + + // skip this property in the block + removePropAndValFromRem(); + continue; + } + props.push({ + name: propStr, + val: valStr + }); + removePropAndValFromRem(); + } + if (invalidBlock) { + removeSelAndBlockFromRemaining(); + break; + } + + // put the parsed block in the style + style.selector(selectorStr); + for (var i = 0; i < props.length; i++) { + var _prop = props[i]; + style.css(_prop.name, _prop.val); + } + removeSelAndBlockFromRemaining(); + } + return style; + }; + styfn$3.fromString = function (string) { + var style = this; + style.resetToDefault(); + style.appendFromString(string); + return style; + }; + + var styfn$2 = {}; + (function () { + var number$1 = number; + var rgba = rgbaNoBackRefs; + var hsla = hslaNoBackRefs; + var hex3$1 = hex3; + var hex6$1 = hex6; + var data = function data(prefix) { + return '^' + prefix + '\\s*\\(\\s*([\\w\\.]+)\\s*\\)$'; + }; + var mapData = function mapData(prefix) { + var mapArg = number$1 + '|\\w+|' + rgba + '|' + hsla + '|' + hex3$1 + '|' + hex6$1; + return '^' + prefix + '\\s*\\(([\\w\\.]+)\\s*\\,\\s*(' + number$1 + ')\\s*\\,\\s*(' + number$1 + ')\\s*,\\s*(' + mapArg + ')\\s*\\,\\s*(' + mapArg + ')\\)$'; + }; + var urlRegexes = ['^url\\s*\\(\\s*[\'"]?(.+?)[\'"]?\\s*\\)$', '^(none)$', '^(.+)$']; + + // each visual style property has a type and needs to be validated according to it + styfn$2.types = { + time: { + number: true, + min: 0, + units: 's|ms', + implicitUnits: 'ms' + }, + percent: { + number: true, + min: 0, + max: 100, + units: '%', + implicitUnits: '%' + }, + percentages: { + number: true, + min: 0, + max: 100, + units: '%', + implicitUnits: '%', + multiple: true + }, + zeroOneNumber: { + number: true, + min: 0, + max: 1, + unitless: true + }, + zeroOneNumbers: { + number: true, + min: 0, + max: 1, + unitless: true, + multiple: true + }, + nOneOneNumber: { + number: true, + min: -1, + max: 1, + unitless: true + }, + nonNegativeInt: { + number: true, + min: 0, + integer: true, + unitless: true + }, + nonNegativeNumber: { + number: true, + min: 0, + unitless: true + }, + position: { + enums: ['parent', 'origin'] + }, + nodeSize: { + number: true, + min: 0, + enums: ['label'] + }, + number: { + number: true, + unitless: true + }, + numbers: { + number: true, + unitless: true, + multiple: true + }, + positiveNumber: { + number: true, + unitless: true, + min: 0, + strictMin: true + }, + size: { + number: true, + min: 0 + }, + bidirectionalSize: { + number: true + }, + // allows negative + bidirectionalSizeMaybePercent: { + number: true, + allowPercent: true + }, + // allows negative + bidirectionalSizes: { + number: true, + multiple: true + }, + // allows negative + sizeMaybePercent: { + number: true, + min: 0, + allowPercent: true + }, + axisDirection: { + enums: ['horizontal', 'leftward', 'rightward', 'vertical', 'upward', 'downward', 'auto'] + }, + paddingRelativeTo: { + enums: ['width', 'height', 'average', 'min', 'max'] + }, + bgWH: { + number: true, + min: 0, + allowPercent: true, + enums: ['auto'], + multiple: true + }, + bgPos: { + number: true, + allowPercent: true, + multiple: true + }, + bgRelativeTo: { + enums: ['inner', 'include-padding'], + multiple: true + }, + bgRepeat: { + enums: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'], + multiple: true + }, + bgFit: { + enums: ['none', 'contain', 'cover'], + multiple: true + }, + bgCrossOrigin: { + enums: ['anonymous', 'use-credentials', 'null'], + multiple: true + }, + bgClip: { + enums: ['none', 'node'], + multiple: true + }, + bgContainment: { + enums: ['inside', 'over'], + multiple: true + }, + color: { + color: true + }, + colors: { + color: true, + multiple: true + }, + fill: { + enums: ['solid', 'linear-gradient', 'radial-gradient'] + }, + bool: { + enums: ['yes', 'no'] + }, + bools: { + enums: ['yes', 'no'], + multiple: true + }, + lineStyle: { + enums: ['solid', 'dotted', 'dashed'] + }, + lineCap: { + enums: ['butt', 'round', 'square'] + }, + borderStyle: { + enums: ['solid', 'dotted', 'dashed', 'double'] + }, + curveStyle: { + enums: ['bezier', 'unbundled-bezier', 'haystack', 'segments', 'straight', 'straight-triangle', 'taxi'] + }, + fontFamily: { + regex: '^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$' + }, + fontStyle: { + enums: ['italic', 'normal', 'oblique'] + }, + fontWeight: { + enums: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '800', '900', 100, 200, 300, 400, 500, 600, 700, 800, 900] + }, + textDecoration: { + enums: ['none', 'underline', 'overline', 'line-through'] + }, + textTransform: { + enums: ['none', 'uppercase', 'lowercase'] + }, + textWrap: { + enums: ['none', 'wrap', 'ellipsis'] + }, + textOverflowWrap: { + enums: ['whitespace', 'anywhere'] + }, + textBackgroundShape: { + enums: ['rectangle', 'roundrectangle', 'round-rectangle'] + }, + nodeShape: { + enums: ['rectangle', 'roundrectangle', 'round-rectangle', 'cutrectangle', 'cut-rectangle', 'bottomroundrectangle', 'bottom-round-rectangle', 'barrel', 'ellipse', 'triangle', 'round-triangle', 'square', 'pentagon', 'round-pentagon', 'hexagon', 'round-hexagon', 'concavehexagon', 'concave-hexagon', 'heptagon', 'round-heptagon', 'octagon', 'round-octagon', 'tag', 'round-tag', 'star', 'diamond', 'round-diamond', 'vee', 'rhomboid', 'right-rhomboid', 'polygon'] + }, + overlayShape: { + enums: ['roundrectangle', 'round-rectangle', 'ellipse'] + }, + compoundIncludeLabels: { + enums: ['include', 'exclude'] + }, + arrowShape: { + enums: ['tee', 'triangle', 'triangle-tee', 'circle-triangle', 'triangle-cross', 'triangle-backcurve', 'vee', 'square', 'circle', 'diamond', 'chevron', 'none'] + }, + arrowFill: { + enums: ['filled', 'hollow'] + }, + display: { + enums: ['element', 'none'] + }, + visibility: { + enums: ['hidden', 'visible'] + }, + zCompoundDepth: { + enums: ['bottom', 'orphan', 'auto', 'top'] + }, + zIndexCompare: { + enums: ['auto', 'manual'] + }, + valign: { + enums: ['top', 'center', 'bottom'] + }, + halign: { + enums: ['left', 'center', 'right'] + }, + justification: { + enums: ['left', 'center', 'right', 'auto'] + }, + text: { + string: true + }, + data: { + mapping: true, + regex: data('data') + }, + layoutData: { + mapping: true, + regex: data('layoutData') + }, + scratch: { + mapping: true, + regex: data('scratch') + }, + mapData: { + mapping: true, + regex: mapData('mapData') + }, + mapLayoutData: { + mapping: true, + regex: mapData('mapLayoutData') + }, + mapScratch: { + mapping: true, + regex: mapData('mapScratch') + }, + fn: { + mapping: true, + fn: true + }, + url: { + regexes: urlRegexes, + singleRegexMatchValue: true + }, + urls: { + regexes: urlRegexes, + singleRegexMatchValue: true, + multiple: true + }, + propList: { + propList: true + }, + angle: { + number: true, + units: 'deg|rad', + implicitUnits: 'rad' + }, + textRotation: { + number: true, + units: 'deg|rad', + implicitUnits: 'rad', + enums: ['none', 'autorotate'] + }, + polygonPointList: { + number: true, + multiple: true, + evenMultiple: true, + min: -1, + max: 1, + unitless: true + }, + edgeDistances: { + enums: ['intersection', 'node-position', 'endpoints'] + }, + edgeEndpoint: { + number: true, + multiple: true, + units: '%|px|em|deg|rad', + implicitUnits: 'px', + enums: ['inside-to-node', 'outside-to-node', 'outside-to-node-or-label', 'outside-to-line', 'outside-to-line-or-label'], + singleEnum: true, + validate: function validate(valArr, unitsArr) { + switch (valArr.length) { + case 2: + // can be % or px only + return unitsArr[0] !== 'deg' && unitsArr[0] !== 'rad' && unitsArr[1] !== 'deg' && unitsArr[1] !== 'rad'; + case 1: + // can be enum, deg, or rad only + return string(valArr[0]) || unitsArr[0] === 'deg' || unitsArr[0] === 'rad'; + default: + return false; + } + } + }, + easing: { + regexes: ['^(spring)\\s*\\(\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*\\)$', '^(cubic-bezier)\\s*\\(\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*\\)$'], + enums: ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'ease-in-sine', 'ease-out-sine', 'ease-in-out-sine', 'ease-in-quad', 'ease-out-quad', 'ease-in-out-quad', 'ease-in-cubic', 'ease-out-cubic', 'ease-in-out-cubic', 'ease-in-quart', 'ease-out-quart', 'ease-in-out-quart', 'ease-in-quint', 'ease-out-quint', 'ease-in-out-quint', 'ease-in-expo', 'ease-out-expo', 'ease-in-out-expo', 'ease-in-circ', 'ease-out-circ', 'ease-in-out-circ'] + }, + gradientDirection: { + enums: ['to-bottom', 'to-top', 'to-left', 'to-right', 'to-bottom-right', 'to-bottom-left', 'to-top-right', 'to-top-left', 'to-right-bottom', 'to-left-bottom', 'to-right-top', 'to-left-top' // different order + ] + }, + + boundsExpansion: { + number: true, + multiple: true, + min: 0, + validate: function validate(valArr) { + var length = valArr.length; + return length === 1 || length === 2 || length === 4; + } + } + }; + var diff = { + zeroNonZero: function zeroNonZero(val1, val2) { + if ((val1 == null || val2 == null) && val1 !== val2) { + return true; // null cases could represent any value + } + if (val1 == 0 && val2 != 0) { + return true; + } else if (val1 != 0 && val2 == 0) { + return true; + } else { + return false; + } + }, + any: function any(val1, val2) { + return val1 != val2; + }, + emptyNonEmpty: function emptyNonEmpty(str1, str2) { + var empty1 = emptyString(str1); + var empty2 = emptyString(str2); + return empty1 && !empty2 || !empty1 && empty2; + } + }; + + // define visual style properties + // + // - n.b. adding a new group of props may require updates to updateStyleHints() + // - adding new props to an existing group gets handled automatically + + var t = styfn$2.types; + var mainLabel = [{ + name: 'label', + type: t.text, + triggersBounds: diff.any, + triggersZOrder: diff.emptyNonEmpty + }, { + name: 'text-rotation', + type: t.textRotation, + triggersBounds: diff.any + }, { + name: 'text-margin-x', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'text-margin-y', + type: t.bidirectionalSize, + triggersBounds: diff.any + }]; + var sourceLabel = [{ + name: 'source-label', + type: t.text, + triggersBounds: diff.any + }, { + name: 'source-text-rotation', + type: t.textRotation, + triggersBounds: diff.any + }, { + name: 'source-text-margin-x', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'source-text-margin-y', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'source-text-offset', + type: t.size, + triggersBounds: diff.any + }]; + var targetLabel = [{ + name: 'target-label', + type: t.text, + triggersBounds: diff.any + }, { + name: 'target-text-rotation', + type: t.textRotation, + triggersBounds: diff.any + }, { + name: 'target-text-margin-x', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'target-text-margin-y', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'target-text-offset', + type: t.size, + triggersBounds: diff.any + }]; + var labelDimensions = [{ + name: 'font-family', + type: t.fontFamily, + triggersBounds: diff.any + }, { + name: 'font-style', + type: t.fontStyle, + triggersBounds: diff.any + }, { + name: 'font-weight', + type: t.fontWeight, + triggersBounds: diff.any + }, { + name: 'font-size', + type: t.size, + triggersBounds: diff.any + }, { + name: 'text-transform', + type: t.textTransform, + triggersBounds: diff.any + }, { + name: 'text-wrap', + type: t.textWrap, + triggersBounds: diff.any + }, { + name: 'text-overflow-wrap', + type: t.textOverflowWrap, + triggersBounds: diff.any + }, { + name: 'text-max-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'text-outline-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'line-height', + type: t.positiveNumber, + triggersBounds: diff.any + }]; + var commonLabel = [{ + name: 'text-valign', + type: t.valign, + triggersBounds: diff.any + }, { + name: 'text-halign', + type: t.halign, + triggersBounds: diff.any + }, { + name: 'color', + type: t.color + }, { + name: 'text-outline-color', + type: t.color + }, { + name: 'text-outline-opacity', + type: t.zeroOneNumber + }, { + name: 'text-background-color', + type: t.color + }, { + name: 'text-background-opacity', + type: t.zeroOneNumber + }, { + name: 'text-background-padding', + type: t.size, + triggersBounds: diff.any + }, { + name: 'text-border-opacity', + type: t.zeroOneNumber + }, { + name: 'text-border-color', + type: t.color + }, { + name: 'text-border-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'text-border-style', + type: t.borderStyle, + triggersBounds: diff.any + }, { + name: 'text-background-shape', + type: t.textBackgroundShape, + triggersBounds: diff.any + }, { + name: 'text-justification', + type: t.justification + }]; + var behavior = [{ + name: 'events', + type: t.bool, + triggersZOrder: diff.any + }, { + name: 'text-events', + type: t.bool, + triggersZOrder: diff.any + }]; + var visibility = [{ + name: 'display', + type: t.display, + triggersZOrder: diff.any, + triggersBounds: diff.any, + triggersBoundsOfParallelBeziers: true + }, { + name: 'visibility', + type: t.visibility, + triggersZOrder: diff.any + }, { + name: 'opacity', + type: t.zeroOneNumber, + triggersZOrder: diff.zeroNonZero + }, { + name: 'text-opacity', + type: t.zeroOneNumber + }, { + name: 'min-zoomed-font-size', + type: t.size + }, { + name: 'z-compound-depth', + type: t.zCompoundDepth, + triggersZOrder: diff.any + }, { + name: 'z-index-compare', + type: t.zIndexCompare, + triggersZOrder: diff.any + }, { + name: 'z-index', + type: t.number, + triggersZOrder: diff.any + }]; + var overlay = [{ + name: 'overlay-padding', + type: t.size, + triggersBounds: diff.any + }, { + name: 'overlay-color', + type: t.color + }, { + name: 'overlay-opacity', + type: t.zeroOneNumber, + triggersBounds: diff.zeroNonZero + }, { + name: 'overlay-shape', + type: t.overlayShape, + triggersBounds: diff.any + }]; + var underlay = [{ + name: 'underlay-padding', + type: t.size, + triggersBounds: diff.any + }, { + name: 'underlay-color', + type: t.color + }, { + name: 'underlay-opacity', + type: t.zeroOneNumber, + triggersBounds: diff.zeroNonZero + }, { + name: 'underlay-shape', + type: t.overlayShape, + triggersBounds: diff.any + }]; + var transition = [{ + name: 'transition-property', + type: t.propList + }, { + name: 'transition-duration', + type: t.time + }, { + name: 'transition-delay', + type: t.time + }, { + name: 'transition-timing-function', + type: t.easing + }]; + var nodeSizeHashOverride = function nodeSizeHashOverride(ele, parsedProp) { + if (parsedProp.value === 'label') { + return -ele.poolIndex(); // no hash key hits is using label size (hitrate for perf probably low anyway) + } else { + return parsedProp.pfValue; + } + }; + var nodeBody = [{ + name: 'height', + type: t.nodeSize, + triggersBounds: diff.any, + hashOverride: nodeSizeHashOverride + }, { + name: 'width', + type: t.nodeSize, + triggersBounds: diff.any, + hashOverride: nodeSizeHashOverride + }, { + name: 'shape', + type: t.nodeShape, + triggersBounds: diff.any + }, { + name: 'shape-polygon-points', + type: t.polygonPointList, + triggersBounds: diff.any + }, { + name: 'background-color', + type: t.color + }, { + name: 'background-fill', + type: t.fill + }, { + name: 'background-opacity', + type: t.zeroOneNumber + }, { + name: 'background-blacken', + type: t.nOneOneNumber + }, { + name: 'background-gradient-stop-colors', + type: t.colors + }, { + name: 'background-gradient-stop-positions', + type: t.percentages + }, { + name: 'background-gradient-direction', + type: t.gradientDirection + }, { + name: 'padding', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'padding-relative-to', + type: t.paddingRelativeTo, + triggersBounds: diff.any + }, { + name: 'bounds-expansion', + type: t.boundsExpansion, + triggersBounds: diff.any + }]; + var nodeBorder = [{ + name: 'border-color', + type: t.color + }, { + name: 'border-opacity', + type: t.zeroOneNumber + }, { + name: 'border-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'border-style', + type: t.borderStyle + }]; + var backgroundImage = [{ + name: 'background-image', + type: t.urls + }, { + name: 'background-image-crossorigin', + type: t.bgCrossOrigin + }, { + name: 'background-image-opacity', + type: t.zeroOneNumbers + }, { + name: 'background-image-containment', + type: t.bgContainment + }, { + name: 'background-image-smoothing', + type: t.bools + }, { + name: 'background-position-x', + type: t.bgPos + }, { + name: 'background-position-y', + type: t.bgPos + }, { + name: 'background-width-relative-to', + type: t.bgRelativeTo + }, { + name: 'background-height-relative-to', + type: t.bgRelativeTo + }, { + name: 'background-repeat', + type: t.bgRepeat + }, { + name: 'background-fit', + type: t.bgFit + }, { + name: 'background-clip', + type: t.bgClip + }, { + name: 'background-width', + type: t.bgWH + }, { + name: 'background-height', + type: t.bgWH + }, { + name: 'background-offset-x', + type: t.bgPos + }, { + name: 'background-offset-y', + type: t.bgPos + }]; + var compound = [{ + name: 'position', + type: t.position, + triggersBounds: diff.any + }, { + name: 'compound-sizing-wrt-labels', + type: t.compoundIncludeLabels, + triggersBounds: diff.any + }, { + name: 'min-width', + type: t.size, + triggersBounds: diff.any + }, { + name: 'min-width-bias-left', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'min-width-bias-right', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'min-height', + type: t.size, + triggersBounds: diff.any + }, { + name: 'min-height-bias-top', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'min-height-bias-bottom', + type: t.sizeMaybePercent, + triggersBounds: diff.any + }]; + var edgeLine = [{ + name: 'line-style', + type: t.lineStyle + }, { + name: 'line-color', + type: t.color + }, { + name: 'line-fill', + type: t.fill + }, { + name: 'line-cap', + type: t.lineCap + }, { + name: 'line-opacity', + type: t.zeroOneNumber + }, { + name: 'line-dash-pattern', + type: t.numbers + }, { + name: 'line-dash-offset', + type: t.number + }, { + name: 'line-gradient-stop-colors', + type: t.colors + }, { + name: 'line-gradient-stop-positions', + type: t.percentages + }, { + name: 'curve-style', + type: t.curveStyle, + triggersBounds: diff.any, + triggersBoundsOfParallelBeziers: true + }, { + name: 'haystack-radius', + type: t.zeroOneNumber, + triggersBounds: diff.any + }, { + name: 'source-endpoint', + type: t.edgeEndpoint, + triggersBounds: diff.any + }, { + name: 'target-endpoint', + type: t.edgeEndpoint, + triggersBounds: diff.any + }, { + name: 'control-point-step-size', + type: t.size, + triggersBounds: diff.any + }, { + name: 'control-point-distances', + type: t.bidirectionalSizes, + triggersBounds: diff.any + }, { + name: 'control-point-weights', + type: t.numbers, + triggersBounds: diff.any + }, { + name: 'segment-distances', + type: t.bidirectionalSizes, + triggersBounds: diff.any + }, { + name: 'segment-weights', + type: t.numbers, + triggersBounds: diff.any + }, { + name: 'taxi-turn', + type: t.bidirectionalSizeMaybePercent, + triggersBounds: diff.any + }, { + name: 'taxi-turn-min-distance', + type: t.size, + triggersBounds: diff.any + }, { + name: 'taxi-direction', + type: t.axisDirection, + triggersBounds: diff.any + }, { + name: 'edge-distances', + type: t.edgeDistances, + triggersBounds: diff.any + }, { + name: 'arrow-scale', + type: t.positiveNumber, + triggersBounds: diff.any + }, { + name: 'loop-direction', + type: t.angle, + triggersBounds: diff.any + }, { + name: 'loop-sweep', + type: t.angle, + triggersBounds: diff.any + }, { + name: 'source-distance-from-node', + type: t.size, + triggersBounds: diff.any + }, { + name: 'target-distance-from-node', + type: t.size, + triggersBounds: diff.any + }]; + var ghost = [{ + name: 'ghost', + type: t.bool, + triggersBounds: diff.any + }, { + name: 'ghost-offset-x', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'ghost-offset-y', + type: t.bidirectionalSize, + triggersBounds: diff.any + }, { + name: 'ghost-opacity', + type: t.zeroOneNumber + }]; + var core = [{ + name: 'selection-box-color', + type: t.color + }, { + name: 'selection-box-opacity', + type: t.zeroOneNumber + }, { + name: 'selection-box-border-color', + type: t.color + }, { + name: 'selection-box-border-width', + type: t.size + }, { + name: 'active-bg-color', + type: t.color + }, { + name: 'active-bg-opacity', + type: t.zeroOneNumber + }, { + name: 'active-bg-size', + type: t.size + }, { + name: 'outside-texture-bg-color', + type: t.color + }, { + name: 'outside-texture-bg-opacity', + type: t.zeroOneNumber + }]; + + // pie backgrounds for nodes + var pie = []; + styfn$2.pieBackgroundN = 16; // because the pie properties are numbered, give access to a constant N (for renderer use) + pie.push({ + name: 'pie-size', + type: t.sizeMaybePercent + }); + for (var i = 1; i <= styfn$2.pieBackgroundN; i++) { + pie.push({ + name: 'pie-' + i + '-background-color', + type: t.color + }); + pie.push({ + name: 'pie-' + i + '-background-size', + type: t.percent + }); + pie.push({ + name: 'pie-' + i + '-background-opacity', + type: t.zeroOneNumber + }); + } + + // edge arrows + var edgeArrow = []; + var arrowPrefixes = styfn$2.arrowPrefixes = ['source', 'mid-source', 'target', 'mid-target']; + [{ + name: 'arrow-shape', + type: t.arrowShape, + triggersBounds: diff.any + }, { + name: 'arrow-color', + type: t.color + }, { + name: 'arrow-fill', + type: t.arrowFill + }].forEach(function (prop) { + arrowPrefixes.forEach(function (prefix) { + var name = prefix + '-' + prop.name; + var type = prop.type, + triggersBounds = prop.triggersBounds; + edgeArrow.push({ + name: name, + type: type, + triggersBounds: triggersBounds + }); + }); + }, {}); + var props = styfn$2.properties = [].concat(behavior, transition, visibility, overlay, underlay, ghost, commonLabel, labelDimensions, mainLabel, sourceLabel, targetLabel, nodeBody, nodeBorder, backgroundImage, pie, compound, edgeLine, edgeArrow, core); + var propGroups = styfn$2.propertyGroups = { + // common to all eles + behavior: behavior, + transition: transition, + visibility: visibility, + overlay: overlay, + underlay: underlay, + ghost: ghost, + // labels + commonLabel: commonLabel, + labelDimensions: labelDimensions, + mainLabel: mainLabel, + sourceLabel: sourceLabel, + targetLabel: targetLabel, + // node props + nodeBody: nodeBody, + nodeBorder: nodeBorder, + backgroundImage: backgroundImage, + pie: pie, + compound: compound, + // edge props + edgeLine: edgeLine, + edgeArrow: edgeArrow, + core: core + }; + var propGroupNames = styfn$2.propertyGroupNames = {}; + var propGroupKeys = styfn$2.propertyGroupKeys = Object.keys(propGroups); + propGroupKeys.forEach(function (key) { + propGroupNames[key] = propGroups[key].map(function (prop) { + return prop.name; + }); + propGroups[key].forEach(function (prop) { + return prop.groupKey = key; + }); + }); + + // define aliases + var aliases = styfn$2.aliases = [{ + name: 'content', + pointsTo: 'label' + }, { + name: 'control-point-distance', + pointsTo: 'control-point-distances' + }, { + name: 'control-point-weight', + pointsTo: 'control-point-weights' + }, { + name: 'edge-text-rotation', + pointsTo: 'text-rotation' + }, { + name: 'padding-left', + pointsTo: 'padding' + }, { + name: 'padding-right', + pointsTo: 'padding' + }, { + name: 'padding-top', + pointsTo: 'padding' + }, { + name: 'padding-bottom', + pointsTo: 'padding' + }]; + + // list of property names + styfn$2.propertyNames = props.map(function (p) { + return p.name; + }); + + // allow access of properties by name ( e.g. style.properties.height ) + for (var _i = 0; _i < props.length; _i++) { + var prop = props[_i]; + props[prop.name] = prop; // allow lookup by name + } + + // map aliases + for (var _i2 = 0; _i2 < aliases.length; _i2++) { + var alias = aliases[_i2]; + var pointsToProp = props[alias.pointsTo]; + var aliasProp = { + name: alias.name, + alias: true, + pointsTo: pointsToProp + }; + + // add alias prop for parsing + props.push(aliasProp); + props[alias.name] = aliasProp; // allow lookup by name + } + })(); + + styfn$2.getDefaultProperty = function (name) { + return this.getDefaultProperties()[name]; + }; + styfn$2.getDefaultProperties = function () { + var _p = this._private; + if (_p.defaultProperties != null) { + return _p.defaultProperties; + } + var rawProps = extend({ + // core props + 'selection-box-color': '#ddd', + 'selection-box-opacity': 0.65, + 'selection-box-border-color': '#aaa', + 'selection-box-border-width': 1, + 'active-bg-color': 'black', + 'active-bg-opacity': 0.15, + 'active-bg-size': 30, + 'outside-texture-bg-color': '#000', + 'outside-texture-bg-opacity': 0.125, + // common node/edge props + 'events': 'yes', + 'text-events': 'no', + 'text-valign': 'top', + 'text-halign': 'center', + 'text-justification': 'auto', + 'line-height': 1, + 'color': '#000', + 'text-outline-color': '#000', + 'text-outline-width': 0, + 'text-outline-opacity': 1, + 'text-opacity': 1, + 'text-decoration': 'none', + 'text-transform': 'none', + 'text-wrap': 'none', + 'text-overflow-wrap': 'whitespace', + 'text-max-width': 9999, + 'text-background-color': '#000', + 'text-background-opacity': 0, + 'text-background-shape': 'rectangle', + 'text-background-padding': 0, + 'text-border-opacity': 0, + 'text-border-width': 0, + 'text-border-style': 'solid', + 'text-border-color': '#000', + 'font-family': 'Helvetica Neue, Helvetica, sans-serif', + 'font-style': 'normal', + 'font-weight': 'normal', + 'font-size': 16, + 'min-zoomed-font-size': 0, + 'text-rotation': 'none', + 'source-text-rotation': 'none', + 'target-text-rotation': 'none', + 'visibility': 'visible', + 'display': 'element', + 'opacity': 1, + 'z-compound-depth': 'auto', + 'z-index-compare': 'auto', + 'z-index': 0, + 'label': '', + 'text-margin-x': 0, + 'text-margin-y': 0, + 'source-label': '', + 'source-text-offset': 0, + 'source-text-margin-x': 0, + 'source-text-margin-y': 0, + 'target-label': '', + 'target-text-offset': 0, + 'target-text-margin-x': 0, + 'target-text-margin-y': 0, + 'overlay-opacity': 0, + 'overlay-color': '#000', + 'overlay-padding': 10, + 'overlay-shape': 'round-rectangle', + 'underlay-opacity': 0, + 'underlay-color': '#000', + 'underlay-padding': 10, + 'underlay-shape': 'round-rectangle', + 'transition-property': 'none', + 'transition-duration': 0, + 'transition-delay': 0, + 'transition-timing-function': 'linear', + // node props + 'background-blacken': 0, + 'background-color': '#999', + 'background-fill': 'solid', + 'background-opacity': 1, + 'background-image': 'none', + 'background-image-crossorigin': 'anonymous', + 'background-image-opacity': 1, + 'background-image-containment': 'inside', + 'background-image-smoothing': 'yes', + 'background-position-x': '50%', + 'background-position-y': '50%', + 'background-offset-x': 0, + 'background-offset-y': 0, + 'background-width-relative-to': 'include-padding', + 'background-height-relative-to': 'include-padding', + 'background-repeat': 'no-repeat', + 'background-fit': 'none', + 'background-clip': 'node', + 'background-width': 'auto', + 'background-height': 'auto', + 'border-color': '#000', + 'border-opacity': 1, + 'border-width': 0, + 'border-style': 'solid', + 'height': 30, + 'width': 30, + 'shape': 'ellipse', + 'shape-polygon-points': '-1, -1, 1, -1, 1, 1, -1, 1', + 'bounds-expansion': 0, + // node gradient + 'background-gradient-direction': 'to-bottom', + 'background-gradient-stop-colors': '#999', + 'background-gradient-stop-positions': '0%', + // ghost props + 'ghost': 'no', + 'ghost-offset-y': 0, + 'ghost-offset-x': 0, + 'ghost-opacity': 0, + // compound props + 'padding': 0, + 'padding-relative-to': 'width', + 'position': 'origin', + 'compound-sizing-wrt-labels': 'include', + 'min-width': 0, + 'min-width-bias-left': 0, + 'min-width-bias-right': 0, + 'min-height': 0, + 'min-height-bias-top': 0, + 'min-height-bias-bottom': 0 + }, { + // node pie bg + 'pie-size': '100%' + }, [{ + name: 'pie-{{i}}-background-color', + value: 'black' + }, { + name: 'pie-{{i}}-background-size', + value: '0%' + }, { + name: 'pie-{{i}}-background-opacity', + value: 1 + }].reduce(function (css, prop) { + for (var i = 1; i <= styfn$2.pieBackgroundN; i++) { + var name = prop.name.replace('{{i}}', i); + var val = prop.value; + css[name] = val; + } + return css; + }, {}), { + // edge props + 'line-style': 'solid', + 'line-color': '#999', + 'line-fill': 'solid', + 'line-cap': 'butt', + 'line-opacity': 1, + 'line-gradient-stop-colors': '#999', + 'line-gradient-stop-positions': '0%', + 'control-point-step-size': 40, + 'control-point-weights': 0.5, + 'segment-weights': 0.5, + 'segment-distances': 20, + 'taxi-turn': '50%', + 'taxi-turn-min-distance': 10, + 'taxi-direction': 'auto', + 'edge-distances': 'intersection', + 'curve-style': 'haystack', + 'haystack-radius': 0, + 'arrow-scale': 1, + 'loop-direction': '-45deg', + 'loop-sweep': '-90deg', + 'source-distance-from-node': 0, + 'target-distance-from-node': 0, + 'source-endpoint': 'outside-to-node', + 'target-endpoint': 'outside-to-node', + 'line-dash-pattern': [6, 3], + 'line-dash-offset': 0 + }, [{ + name: 'arrow-shape', + value: 'none' + }, { + name: 'arrow-color', + value: '#999' + }, { + name: 'arrow-fill', + value: 'filled' + }].reduce(function (css, prop) { + styfn$2.arrowPrefixes.forEach(function (prefix) { + var name = prefix + '-' + prop.name; + var val = prop.value; + css[name] = val; + }); + return css; + }, {})); + var parsedProps = {}; + for (var i = 0; i < this.properties.length; i++) { + var prop = this.properties[i]; + if (prop.pointsTo) { + continue; + } + var name = prop.name; + var val = rawProps[name]; + var parsedProp = this.parse(name, val); + parsedProps[name] = parsedProp; + } + _p.defaultProperties = parsedProps; + return _p.defaultProperties; + }; + styfn$2.addDefaultStylesheet = function () { + this.selector(':parent').css({ + 'shape': 'rectangle', + 'padding': 10, + 'background-color': '#eee', + 'border-color': '#ccc', + 'border-width': 1 + }).selector('edge').css({ + 'width': 3 + }).selector(':loop').css({ + 'curve-style': 'bezier' + }).selector('edge:compound').css({ + 'curve-style': 'bezier', + 'source-endpoint': 'outside-to-line', + 'target-endpoint': 'outside-to-line' + }).selector(':selected').css({ + 'background-color': '#0169D9', + 'line-color': '#0169D9', + 'source-arrow-color': '#0169D9', + 'target-arrow-color': '#0169D9', + 'mid-source-arrow-color': '#0169D9', + 'mid-target-arrow-color': '#0169D9' + }).selector(':parent:selected').css({ + 'background-color': '#CCE1F9', + 'border-color': '#aec8e5' + }).selector(':active').css({ + 'overlay-color': 'black', + 'overlay-padding': 10, + 'overlay-opacity': 0.25 + }); + this.defaultLength = this.length; + }; + + var styfn$1 = {}; + + // a caching layer for property parsing + styfn$1.parse = function (name, value, propIsBypass, propIsFlat) { + var self = this; + + // function values can't be cached in all cases, and there isn't much benefit of caching them anyway + if (fn$6(value)) { + return self.parseImplWarn(name, value, propIsBypass, propIsFlat); + } + var flatKey = propIsFlat === 'mapping' || propIsFlat === true || propIsFlat === false || propIsFlat == null ? 'dontcare' : propIsFlat; + var bypassKey = propIsBypass ? 't' : 'f'; + var valueKey = '' + value; + var argHash = hashStrings(name, valueKey, bypassKey, flatKey); + var propCache = self.propCache = self.propCache || []; + var ret; + if (!(ret = propCache[argHash])) { + ret = propCache[argHash] = self.parseImplWarn(name, value, propIsBypass, propIsFlat); + } + + // - bypasses can't be shared b/c the value can be changed by animations or otherwise overridden + // - mappings can't be shared b/c mappings are per-element + if (propIsBypass || propIsFlat === 'mapping') { + // need a copy since props are mutated later in their lifecycles + ret = copy(ret); + if (ret) { + ret.value = copy(ret.value); // because it could be an array, e.g. colour + } + } + + return ret; + }; + styfn$1.parseImplWarn = function (name, value, propIsBypass, propIsFlat) { + var prop = this.parseImpl(name, value, propIsBypass, propIsFlat); + if (!prop && value != null) { + warn("The style property `".concat(name, ": ").concat(value, "` is invalid")); + } + if (prop && (prop.name === 'width' || prop.name === 'height') && value === 'label') { + warn('The style value of `label` is deprecated for `' + prop.name + '`'); + } + return prop; + }; + + // parse a property; return null on invalid; return parsed property otherwise + // fields : + // - name : the name of the property + // - value : the parsed, native-typed value of the property + // - strValue : a string value that represents the property value in valid css + // - bypass : true iff the property is a bypass property + styfn$1.parseImpl = function (name, value, propIsBypass, propIsFlat) { + var self = this; + name = camel2dash(name); // make sure the property name is in dash form (e.g. 'property-name' not 'propertyName') + + var property = self.properties[name]; + var passedValue = value; + var types = self.types; + if (!property) { + return null; + } // return null on property of unknown name + if (value === undefined) { + return null; + } // can't assign undefined + + // the property may be an alias + if (property.alias) { + property = property.pointsTo; + name = property.name; + } + var valueIsString = string(value); + if (valueIsString) { + // trim the value to make parsing easier + value = value.trim(); + } + var type = property.type; + if (!type) { + return null; + } // no type, no luck + + // check if bypass is null or empty string (i.e. indication to delete bypass property) + if (propIsBypass && (value === '' || value === null)) { + return { + name: name, + value: value, + bypass: true, + deleteBypass: true + }; + } + + // check if value is a function used as a mapper + if (fn$6(value)) { + return { + name: name, + value: value, + strValue: 'fn', + mapped: types.fn, + bypass: propIsBypass + }; + } + + // check if value is mapped + var data, mapData; + if (!valueIsString || propIsFlat || value.length < 7 || value[1] !== 'a') ; else if (value.length >= 7 && value[0] === 'd' && (data = new RegExp(types.data.regex).exec(value))) { + if (propIsBypass) { + return false; + } // mappers not allowed in bypass + + var mapped = types.data; + return { + name: name, + value: data, + strValue: '' + value, + mapped: mapped, + field: data[1], + bypass: propIsBypass + }; + } else if (value.length >= 10 && value[0] === 'm' && (mapData = new RegExp(types.mapData.regex).exec(value))) { + if (propIsBypass) { + return false; + } // mappers not allowed in bypass + if (type.multiple) { + return false; + } // impossible to map to num + + var _mapped = types.mapData; + + // we can map only if the type is a colour or a number + if (!(type.color || type.number)) { + return false; + } + var valueMin = this.parse(name, mapData[4]); // parse to validate + if (!valueMin || valueMin.mapped) { + return false; + } // can't be invalid or mapped + + var valueMax = this.parse(name, mapData[5]); // parse to validate + if (!valueMax || valueMax.mapped) { + return false; + } // can't be invalid or mapped + + // check if valueMin and valueMax are the same + if (valueMin.pfValue === valueMax.pfValue || valueMin.strValue === valueMax.strValue) { + warn('`' + name + ': ' + value + '` is not a valid mapper because the output range is zero; converting to `' + name + ': ' + valueMin.strValue + '`'); + return this.parse(name, valueMin.strValue); // can't make much of a mapper without a range + } else if (type.color) { + var c1 = valueMin.value; + var c2 = valueMax.value; + var same = c1[0] === c2[0] // red + && c1[1] === c2[1] // green + && c1[2] === c2[2] // blue + && ( + // optional alpha + c1[3] === c2[3] // same alpha outright + || (c1[3] == null || c1[3] === 1 // full opacity for colour 1? + ) && (c2[3] == null || c2[3] === 1) // full opacity for colour 2? + ); + + if (same) { + return false; + } // can't make a mapper without a range + } + + return { + name: name, + value: mapData, + strValue: '' + value, + mapped: _mapped, + field: mapData[1], + fieldMin: parseFloat(mapData[2]), + // min & max are numeric + fieldMax: parseFloat(mapData[3]), + valueMin: valueMin.value, + valueMax: valueMax.value, + bypass: propIsBypass + }; + } + if (type.multiple && propIsFlat !== 'multiple') { + var vals; + if (valueIsString) { + vals = value.split(/\s+/); + } else if (array(value)) { + vals = value; + } else { + vals = [value]; + } + if (type.evenMultiple && vals.length % 2 !== 0) { + return null; + } + var valArr = []; + var unitsArr = []; + var pfValArr = []; + var strVal = ''; + var hasEnum = false; + for (var i = 0; i < vals.length; i++) { + var p = self.parse(name, vals[i], propIsBypass, 'multiple'); + hasEnum = hasEnum || string(p.value); + valArr.push(p.value); + pfValArr.push(p.pfValue != null ? p.pfValue : p.value); + unitsArr.push(p.units); + strVal += (i > 0 ? ' ' : '') + p.strValue; + } + if (type.validate && !type.validate(valArr, unitsArr)) { + return null; + } + if (type.singleEnum && hasEnum) { + if (valArr.length === 1 && string(valArr[0])) { + return { + name: name, + value: valArr[0], + strValue: valArr[0], + bypass: propIsBypass + }; + } else { + return null; + } + } + return { + name: name, + value: valArr, + pfValue: pfValArr, + strValue: strVal, + bypass: propIsBypass, + units: unitsArr + }; + } + + // several types also allow enums + var checkEnums = function checkEnums() { + for (var _i = 0; _i < type.enums.length; _i++) { + var en = type.enums[_i]; + if (en === value) { + return { + name: name, + value: value, + strValue: '' + value, + bypass: propIsBypass + }; + } + } + return null; + }; + + // check the type and return the appropriate object + if (type.number) { + var units; + var implicitUnits = 'px'; // not set => px + + if (type.units) { + // use specified units if set + units = type.units; + } + if (type.implicitUnits) { + implicitUnits = type.implicitUnits; + } + if (!type.unitless) { + if (valueIsString) { + var unitsRegex = 'px|em' + (type.allowPercent ? '|\\%' : ''); + if (units) { + unitsRegex = units; + } // only allow explicit units if so set + var match = value.match('^(' + number + ')(' + unitsRegex + ')?' + '$'); + if (match) { + value = match[1]; + units = match[2] || implicitUnits; + } + } else if (!units || type.implicitUnits) { + units = implicitUnits; // implicitly px if unspecified + } + } + + value = parseFloat(value); + + // if not a number and enums not allowed, then the value is invalid + if (isNaN(value) && type.enums === undefined) { + return null; + } + + // check if this number type also accepts special keywords in place of numbers + // (i.e. `left`, `auto`, etc) + if (isNaN(value) && type.enums !== undefined) { + value = passedValue; + return checkEnums(); + } + + // check if value must be an integer + if (type.integer && !integer(value)) { + return null; + } + + // check value is within range + if (type.min !== undefined && (value < type.min || type.strictMin && value === type.min) || type.max !== undefined && (value > type.max || type.strictMax && value === type.max)) { + return null; + } + var ret = { + name: name, + value: value, + strValue: '' + value + (units ? units : ''), + units: units, + bypass: propIsBypass + }; + + // normalise value in pixels + if (type.unitless || units !== 'px' && units !== 'em') { + ret.pfValue = value; + } else { + ret.pfValue = units === 'px' || !units ? value : this.getEmSizeInPixels() * value; + } + + // normalise value in ms + if (units === 'ms' || units === 's') { + ret.pfValue = units === 'ms' ? value : 1000 * value; + } + + // normalise value in rad + if (units === 'deg' || units === 'rad') { + ret.pfValue = units === 'rad' ? value : deg2rad(value); + } + + // normalize value in % + if (units === '%') { + ret.pfValue = value / 100; + } + return ret; + } else if (type.propList) { + var props = []; + var propsStr = '' + value; + if (propsStr === 'none') ; else { + // go over each prop + + var propsSplit = propsStr.split(/\s*,\s*|\s+/); + for (var _i2 = 0; _i2 < propsSplit.length; _i2++) { + var propName = propsSplit[_i2].trim(); + if (self.properties[propName]) { + props.push(propName); + } else { + warn('`' + propName + '` is not a valid property name'); + } + } + if (props.length === 0) { + return null; + } + } + return { + name: name, + value: props, + strValue: props.length === 0 ? 'none' : props.join(' '), + bypass: propIsBypass + }; + } else if (type.color) { + var tuple = color2tuple(value); + if (!tuple) { + return null; + } + return { + name: name, + value: tuple, + pfValue: tuple, + strValue: 'rgb(' + tuple[0] + ',' + tuple[1] + ',' + tuple[2] + ')', + // n.b. no spaces b/c of multiple support + bypass: propIsBypass + }; + } else if (type.regex || type.regexes) { + // first check enums + if (type.enums) { + var enumProp = checkEnums(); + if (enumProp) { + return enumProp; + } + } + var regexes = type.regexes ? type.regexes : [type.regex]; + for (var _i3 = 0; _i3 < regexes.length; _i3++) { + var regex = new RegExp(regexes[_i3]); // make a regex from the type string + var m = regex.exec(value); + if (m) { + // regex matches + return { + name: name, + value: type.singleRegexMatchValue ? m[1] : m, + strValue: '' + value, + bypass: propIsBypass + }; + } + } + return null; // didn't match any + } else if (type.string) { + // just return + return { + name: name, + value: '' + value, + strValue: '' + value, + bypass: propIsBypass + }; + } else if (type.enums) { + // check enums last because it's a combo type in others + return checkEnums(); + } else { + return null; // not a type we can handle + } + }; + + var Style = function Style(cy) { + if (!(this instanceof Style)) { + return new Style(cy); + } + if (!core(cy)) { + error('A style must have a core reference'); + return; + } + this._private = { + cy: cy, + coreStyle: {} + }; + this.length = 0; + this.resetToDefault(); + }; + var styfn = Style.prototype; + styfn.instanceString = function () { + return 'style'; + }; + + // remove all contexts + styfn.clear = function () { + var _p = this._private; + var cy = _p.cy; + var eles = cy.elements(); + for (var i = 0; i < this.length; i++) { + this[i] = undefined; + } + this.length = 0; + _p.contextStyles = {}; + _p.propDiffs = {}; + this.cleanElements(eles, true); + eles.forEach(function (ele) { + var ele_p = ele[0]._private; + ele_p.styleDirty = true; + ele_p.appliedInitStyle = false; + }); + return this; // chaining + }; + + styfn.resetToDefault = function () { + this.clear(); + this.addDefaultStylesheet(); + return this; + }; + + // builds a style object for the 'core' selector + styfn.core = function (propName) { + return this._private.coreStyle[propName] || this.getDefaultProperty(propName); + }; + + // create a new context from the specified selector string and switch to that context + styfn.selector = function (selectorStr) { + // 'core' is a special case and does not need a selector + var selector = selectorStr === 'core' ? null : new Selector(selectorStr); + var i = this.length++; // new context means new index + this[i] = { + selector: selector, + properties: [], + mappedProperties: [], + index: i + }; + return this; // chaining + }; + + // add one or many css rules to the current context + styfn.css = function () { + var self = this; + var args = arguments; + if (args.length === 1) { + var map = args[0]; + for (var i = 0; i < self.properties.length; i++) { + var prop = self.properties[i]; + var mapVal = map[prop.name]; + if (mapVal === undefined) { + mapVal = map[dash2camel(prop.name)]; + } + if (mapVal !== undefined) { + this.cssRule(prop.name, mapVal); + } + } + } else if (args.length === 2) { + this.cssRule(args[0], args[1]); + } + + // do nothing if args are invalid + + return this; // chaining + }; + + styfn.style = styfn.css; + + // add a single css rule to the current context + styfn.cssRule = function (name, value) { + // name-value pair + var property = this.parse(name, value); + + // add property to current context if valid + if (property) { + var i = this.length - 1; + this[i].properties.push(property); + this[i].properties[property.name] = property; // allow access by name as well + + if (property.name.match(/pie-(\d+)-background-size/) && property.value) { + this._private.hasPie = true; + } + if (property.mapped) { + this[i].mappedProperties.push(property); + } + + // add to core style if necessary + var currentSelectorIsCore = !this[i].selector; + if (currentSelectorIsCore) { + this._private.coreStyle[property.name] = property; + } + } + return this; // chaining + }; + + styfn.append = function (style) { + if (stylesheet(style)) { + style.appendToStyle(this); + } else if (array(style)) { + this.appendFromJson(style); + } else if (string(style)) { + this.appendFromString(style); + } // you probably wouldn't want to append a Style, since you'd duplicate the default parts + + return this; + }; + + // static function + Style.fromJson = function (cy, json) { + var style = new Style(cy); + style.fromJson(json); + return style; + }; + Style.fromString = function (cy, string) { + return new Style(cy).fromString(string); + }; + [styfn$8, styfn$7, styfn$6, styfn$5, styfn$4, styfn$3, styfn$2, styfn$1].forEach(function (props) { + extend(styfn, props); + }); + Style.types = styfn.types; + Style.properties = styfn.properties; + Style.propertyGroups = styfn.propertyGroups; + Style.propertyGroupNames = styfn.propertyGroupNames; + Style.propertyGroupKeys = styfn.propertyGroupKeys; + + var corefn$2 = { + style: function style(newStyle) { + if (newStyle) { + var s = this.setStyle(newStyle); + s.update(); + } + return this._private.style; + }, + setStyle: function setStyle(style) { + var _p = this._private; + if (stylesheet(style)) { + _p.style = style.generateStyle(this); + } else if (array(style)) { + _p.style = Style.fromJson(this, style); + } else if (string(style)) { + _p.style = Style.fromString(this, style); + } else { + _p.style = Style(this); + } + return _p.style; + }, + // e.g. cy.data() changed => recalc ele mappers + updateStyle: function updateStyle() { + this.mutableElements().updateStyle(); // just send to all eles + } + }; + + var defaultSelectionType = 'single'; + var corefn$1 = { + autolock: function autolock(bool) { + if (bool !== undefined) { + this._private.autolock = bool ? true : false; + } else { + return this._private.autolock; + } + return this; // chaining + }, + + autoungrabify: function autoungrabify(bool) { + if (bool !== undefined) { + this._private.autoungrabify = bool ? true : false; + } else { + return this._private.autoungrabify; + } + return this; // chaining + }, + + autounselectify: function autounselectify(bool) { + if (bool !== undefined) { + this._private.autounselectify = bool ? true : false; + } else { + return this._private.autounselectify; + } + return this; // chaining + }, + + selectionType: function selectionType(selType) { + var _p = this._private; + if (_p.selectionType == null) { + _p.selectionType = defaultSelectionType; + } + if (selType !== undefined) { + if (selType === 'additive' || selType === 'single') { + _p.selectionType = selType; + } + } else { + return _p.selectionType; + } + return this; + }, + panningEnabled: function panningEnabled(bool) { + if (bool !== undefined) { + this._private.panningEnabled = bool ? true : false; + } else { + return this._private.panningEnabled; + } + return this; // chaining + }, + + userPanningEnabled: function userPanningEnabled(bool) { + if (bool !== undefined) { + this._private.userPanningEnabled = bool ? true : false; + } else { + return this._private.userPanningEnabled; + } + return this; // chaining + }, + + zoomingEnabled: function zoomingEnabled(bool) { + if (bool !== undefined) { + this._private.zoomingEnabled = bool ? true : false; + } else { + return this._private.zoomingEnabled; + } + return this; // chaining + }, + + userZoomingEnabled: function userZoomingEnabled(bool) { + if (bool !== undefined) { + this._private.userZoomingEnabled = bool ? true : false; + } else { + return this._private.userZoomingEnabled; + } + return this; // chaining + }, + + boxSelectionEnabled: function boxSelectionEnabled(bool) { + if (bool !== undefined) { + this._private.boxSelectionEnabled = bool ? true : false; + } else { + return this._private.boxSelectionEnabled; + } + return this; // chaining + }, + + pan: function pan() { + var args = arguments; + var pan = this._private.pan; + var dim, val, dims, x, y; + switch (args.length) { + case 0: + // .pan() + return pan; + case 1: + if (string(args[0])) { + // .pan('x') + dim = args[0]; + return pan[dim]; + } else if (plainObject(args[0])) { + // .pan({ x: 0, y: 100 }) + if (!this._private.panningEnabled) { + return this; + } + dims = args[0]; + x = dims.x; + y = dims.y; + if (number$1(x)) { + pan.x = x; + } + if (number$1(y)) { + pan.y = y; + } + this.emit('pan viewport'); + } + break; + case 2: + // .pan('x', 100) + if (!this._private.panningEnabled) { + return this; + } + dim = args[0]; + val = args[1]; + if ((dim === 'x' || dim === 'y') && number$1(val)) { + pan[dim] = val; + } + this.emit('pan viewport'); + break; + // invalid + } + + this.notify('viewport'); + return this; // chaining + }, + + panBy: function panBy(arg0, arg1) { + var args = arguments; + var pan = this._private.pan; + var dim, val, dims, x, y; + if (!this._private.panningEnabled) { + return this; + } + switch (args.length) { + case 1: + if (plainObject(arg0)) { + // .panBy({ x: 0, y: 100 }) + dims = args[0]; + x = dims.x; + y = dims.y; + if (number$1(x)) { + pan.x += x; + } + if (number$1(y)) { + pan.y += y; + } + this.emit('pan viewport'); + } + break; + case 2: + // .panBy('x', 100) + dim = arg0; + val = arg1; + if ((dim === 'x' || dim === 'y') && number$1(val)) { + pan[dim] += val; + } + this.emit('pan viewport'); + break; + // invalid + } + + this.notify('viewport'); + return this; // chaining + }, + + fit: function fit(elements, padding) { + var viewportState = this.getFitViewport(elements, padding); + if (viewportState) { + var _p = this._private; + _p.zoom = viewportState.zoom; + _p.pan = viewportState.pan; + this.emit('pan zoom viewport'); + this.notify('viewport'); + } + return this; // chaining + }, + + getFitViewport: function getFitViewport(elements, padding) { + if (number$1(elements) && padding === undefined) { + // elements is optional + padding = elements; + elements = undefined; + } + if (!this._private.panningEnabled || !this._private.zoomingEnabled) { + return; + } + var bb; + if (string(elements)) { + var sel = elements; + elements = this.$(sel); + } else if (boundingBox(elements)) { + // assume bb + var bbe = elements; + bb = { + x1: bbe.x1, + y1: bbe.y1, + x2: bbe.x2, + y2: bbe.y2 + }; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + } else if (!elementOrCollection(elements)) { + elements = this.mutableElements(); + } + if (elementOrCollection(elements) && elements.empty()) { + return; + } // can't fit to nothing + + bb = bb || elements.boundingBox(); + var w = this.width(); + var h = this.height(); + var zoom; + padding = number$1(padding) ? padding : 0; + if (!isNaN(w) && !isNaN(h) && w > 0 && h > 0 && !isNaN(bb.w) && !isNaN(bb.h) && bb.w > 0 && bb.h > 0) { + zoom = Math.min((w - 2 * padding) / bb.w, (h - 2 * padding) / bb.h); + + // crop zoom + zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; + zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; + var pan = { + // now pan to middle + x: (w - zoom * (bb.x1 + bb.x2)) / 2, + y: (h - zoom * (bb.y1 + bb.y2)) / 2 + }; + return { + zoom: zoom, + pan: pan + }; + } + return; + }, + zoomRange: function zoomRange(min, max) { + var _p = this._private; + if (max == null) { + var opts = min; + min = opts.min; + max = opts.max; + } + if (number$1(min) && number$1(max) && min <= max) { + _p.minZoom = min; + _p.maxZoom = max; + } else if (number$1(min) && max === undefined && min <= _p.maxZoom) { + _p.minZoom = min; + } else if (number$1(max) && min === undefined && max >= _p.minZoom) { + _p.maxZoom = max; + } + return this; + }, + minZoom: function minZoom(zoom) { + if (zoom === undefined) { + return this._private.minZoom; + } else { + return this.zoomRange({ + min: zoom + }); + } + }, + maxZoom: function maxZoom(zoom) { + if (zoom === undefined) { + return this._private.maxZoom; + } else { + return this.zoomRange({ + max: zoom + }); + } + }, + getZoomedViewport: function getZoomedViewport(params) { + var _p = this._private; + var currentPan = _p.pan; + var currentZoom = _p.zoom; + var pos; // in rendered px + var zoom; + var bail = false; + if (!_p.zoomingEnabled) { + // zooming disabled + bail = true; + } + if (number$1(params)) { + // then set the zoom + zoom = params; + } else if (plainObject(params)) { + // then zoom about a point + zoom = params.level; + if (params.position != null) { + pos = modelToRenderedPosition(params.position, currentZoom, currentPan); + } else if (params.renderedPosition != null) { + pos = params.renderedPosition; + } + if (pos != null && !_p.panningEnabled) { + // panning disabled + bail = true; + } + } + + // crop zoom + zoom = zoom > _p.maxZoom ? _p.maxZoom : zoom; + zoom = zoom < _p.minZoom ? _p.minZoom : zoom; + + // can't zoom with invalid params + if (bail || !number$1(zoom) || zoom === currentZoom || pos != null && (!number$1(pos.x) || !number$1(pos.y))) { + return null; + } + if (pos != null) { + // set zoom about position + var pan1 = currentPan; + var zoom1 = currentZoom; + var zoom2 = zoom; + var pan2 = { + x: -zoom2 / zoom1 * (pos.x - pan1.x) + pos.x, + y: -zoom2 / zoom1 * (pos.y - pan1.y) + pos.y + }; + return { + zoomed: true, + panned: true, + zoom: zoom2, + pan: pan2 + }; + } else { + // just set the zoom + return { + zoomed: true, + panned: false, + zoom: zoom, + pan: currentPan + }; + } + }, + zoom: function zoom(params) { + if (params === undefined) { + // get + return this._private.zoom; + } else { + // set + var vp = this.getZoomedViewport(params); + var _p = this._private; + if (vp == null || !vp.zoomed) { + return this; + } + _p.zoom = vp.zoom; + if (vp.panned) { + _p.pan.x = vp.pan.x; + _p.pan.y = vp.pan.y; + } + this.emit('zoom' + (vp.panned ? ' pan' : '') + ' viewport'); + this.notify('viewport'); + return this; // chaining + } + }, + + viewport: function viewport(opts) { + var _p = this._private; + var zoomDefd = true; + var panDefd = true; + var events = []; // to trigger + var zoomFailed = false; + var panFailed = false; + if (!opts) { + return this; + } + if (!number$1(opts.zoom)) { + zoomDefd = false; + } + if (!plainObject(opts.pan)) { + panDefd = false; + } + if (!zoomDefd && !panDefd) { + return this; + } + if (zoomDefd) { + var z = opts.zoom; + if (z < _p.minZoom || z > _p.maxZoom || !_p.zoomingEnabled) { + zoomFailed = true; + } else { + _p.zoom = z; + events.push('zoom'); + } + } + if (panDefd && (!zoomFailed || !opts.cancelOnFailedZoom) && _p.panningEnabled) { + var p = opts.pan; + if (number$1(p.x)) { + _p.pan.x = p.x; + panFailed = false; + } + if (number$1(p.y)) { + _p.pan.y = p.y; + panFailed = false; + } + if (!panFailed) { + events.push('pan'); + } + } + if (events.length > 0) { + events.push('viewport'); + this.emit(events.join(' ')); + this.notify('viewport'); + } + return this; // chaining + }, + + center: function center(elements) { + var pan = this.getCenterPan(elements); + if (pan) { + this._private.pan = pan; + this.emit('pan viewport'); + this.notify('viewport'); + } + return this; // chaining + }, + + getCenterPan: function getCenterPan(elements, zoom) { + if (!this._private.panningEnabled) { + return; + } + if (string(elements)) { + var selector = elements; + elements = this.mutableElements().filter(selector); + } else if (!elementOrCollection(elements)) { + elements = this.mutableElements(); + } + if (elements.length === 0) { + return; + } // can't centre pan to nothing + + var bb = elements.boundingBox(); + var w = this.width(); + var h = this.height(); + zoom = zoom === undefined ? this._private.zoom : zoom; + var pan = { + // middle + x: (w - zoom * (bb.x1 + bb.x2)) / 2, + y: (h - zoom * (bb.y1 + bb.y2)) / 2 + }; + return pan; + }, + reset: function reset() { + if (!this._private.panningEnabled || !this._private.zoomingEnabled) { + return this; + } + this.viewport({ + pan: { + x: 0, + y: 0 + }, + zoom: 1 + }); + return this; // chaining + }, + + invalidateSize: function invalidateSize() { + this._private.sizeCache = null; + }, + size: function size() { + var _p = this._private; + var container = _p.container; + var cy = this; + return _p.sizeCache = _p.sizeCache || (container ? function () { + var style = cy.window().getComputedStyle(container); + var val = function val(name) { + return parseFloat(style.getPropertyValue(name)); + }; + return { + width: container.clientWidth - val('padding-left') - val('padding-right'), + height: container.clientHeight - val('padding-top') - val('padding-bottom') + }; + }() : { + // fallback if no container (not 0 b/c can be used for dividing etc) + width: 1, + height: 1 + }); + }, + width: function width() { + return this.size().width; + }, + height: function height() { + return this.size().height; + }, + extent: function extent() { + var pan = this._private.pan; + var zoom = this._private.zoom; + var rb = this.renderedExtent(); + var b = { + x1: (rb.x1 - pan.x) / zoom, + x2: (rb.x2 - pan.x) / zoom, + y1: (rb.y1 - pan.y) / zoom, + y2: (rb.y2 - pan.y) / zoom + }; + b.w = b.x2 - b.x1; + b.h = b.y2 - b.y1; + return b; + }, + renderedExtent: function renderedExtent() { + var width = this.width(); + var height = this.height(); + return { + x1: 0, + y1: 0, + x2: width, + y2: height, + w: width, + h: height + }; + }, + multiClickDebounceTime: function multiClickDebounceTime(_int) { + if (_int) this._private.multiClickDebounceTime = _int;else return this._private.multiClickDebounceTime; + return this; // chaining + } + }; + + // aliases + corefn$1.centre = corefn$1.center; + + // backwards compatibility + corefn$1.autolockNodes = corefn$1.autolock; + corefn$1.autoungrabifyNodes = corefn$1.autoungrabify; + + var fn = { + data: define.data({ + field: 'data', + bindingEvent: 'data', + allowBinding: true, + allowSetting: true, + settingEvent: 'data', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true, + updateStyle: true + }), + removeData: define.removeData({ + field: 'data', + event: 'data', + triggerFnName: 'trigger', + triggerEvent: true, + updateStyle: true + }), + scratch: define.data({ + field: 'scratch', + bindingEvent: 'scratch', + allowBinding: true, + allowSetting: true, + settingEvent: 'scratch', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true, + updateStyle: true + }), + removeScratch: define.removeData({ + field: 'scratch', + event: 'scratch', + triggerFnName: 'trigger', + triggerEvent: true, + updateStyle: true + }) + }; + + // aliases + fn.attr = fn.data; + fn.removeAttr = fn.removeData; + + var Core = function Core(opts) { + var cy = this; + opts = extend({}, opts); + var container = opts.container; + + // allow for passing a wrapped jquery object + // e.g. cytoscape({ container: $('#cy') }) + if (container && !htmlElement(container) && htmlElement(container[0])) { + container = container[0]; + } + var reg = container ? container._cyreg : null; // e.g. already registered some info (e.g. readies) via jquery + reg = reg || {}; + if (reg && reg.cy) { + reg.cy.destroy(); + reg = {}; // old instance => replace reg completely + } + + var readies = reg.readies = reg.readies || []; + if (container) { + container._cyreg = reg; + } // make sure container assoc'd reg points to this cy + reg.cy = cy; + var head = _window !== undefined && container !== undefined && !opts.headless; + var options = opts; + options.layout = extend({ + name: head ? 'grid' : 'null' + }, options.layout); + options.renderer = extend({ + name: head ? 'canvas' : 'null' + }, options.renderer); + var defVal = function defVal(def, val, altVal) { + if (val !== undefined) { + return val; + } else if (altVal !== undefined) { + return altVal; + } else { + return def; + } + }; + var _p = this._private = { + container: container, + // html dom ele container + ready: false, + // whether ready has been triggered + options: options, + // cached options + elements: new Collection(this), + // elements in the graph + listeners: [], + // list of listeners + aniEles: new Collection(this), + // elements being animated + data: options.data || {}, + // data for the core + scratch: {}, + // scratch object for core + layout: null, + renderer: null, + destroyed: false, + // whether destroy was called + notificationsEnabled: true, + // whether notifications are sent to the renderer + minZoom: 1e-50, + maxZoom: 1e50, + zoomingEnabled: defVal(true, options.zoomingEnabled), + userZoomingEnabled: defVal(true, options.userZoomingEnabled), + panningEnabled: defVal(true, options.panningEnabled), + userPanningEnabled: defVal(true, options.userPanningEnabled), + boxSelectionEnabled: defVal(true, options.boxSelectionEnabled), + autolock: defVal(false, options.autolock, options.autolockNodes), + autoungrabify: defVal(false, options.autoungrabify, options.autoungrabifyNodes), + autounselectify: defVal(false, options.autounselectify), + styleEnabled: options.styleEnabled === undefined ? head : options.styleEnabled, + zoom: number$1(options.zoom) ? options.zoom : 1, + pan: { + x: plainObject(options.pan) && number$1(options.pan.x) ? options.pan.x : 0, + y: plainObject(options.pan) && number$1(options.pan.y) ? options.pan.y : 0 + }, + animation: { + // object for currently-running animations + current: [], + queue: [] + }, + hasCompoundNodes: false, + multiClickDebounceTime: defVal(250, options.multiClickDebounceTime) + }; + this.createEmitter(); + + // set selection type + this.selectionType(options.selectionType); + + // init zoom bounds + this.zoomRange({ + min: options.minZoom, + max: options.maxZoom + }); + var loadExtData = function loadExtData(extData, next) { + var anyIsPromise = extData.some(promise); + if (anyIsPromise) { + return Promise$1.all(extData).then(next); // load all data asynchronously, then exec rest of init + } else { + next(extData); // exec synchronously for convenience + } + }; + + // start with the default stylesheet so we have something before loading an external stylesheet + if (_p.styleEnabled) { + cy.setStyle([]); + } + + // create the renderer + var rendererOptions = extend({}, options, options.renderer); // allow rendering hints in top level options + cy.initRenderer(rendererOptions); + var setElesAndLayout = function setElesAndLayout(elements, onload, ondone) { + cy.notifications(false); + + // remove old elements + var oldEles = cy.mutableElements(); + if (oldEles.length > 0) { + oldEles.remove(); + } + if (elements != null) { + if (plainObject(elements) || array(elements)) { + cy.add(elements); + } + } + cy.one('layoutready', function (e) { + cy.notifications(true); + cy.emit(e); // we missed this event by turning notifications off, so pass it on + + cy.one('load', onload); + cy.emitAndNotify('load'); + }).one('layoutstop', function () { + cy.one('done', ondone); + cy.emit('done'); + }); + var layoutOpts = extend({}, cy._private.options.layout); + layoutOpts.eles = cy.elements(); + cy.layout(layoutOpts).run(); + }; + loadExtData([options.style, options.elements], function (thens) { + var initStyle = thens[0]; + var initEles = thens[1]; + + // init style + if (_p.styleEnabled) { + cy.style().append(initStyle); + } + + // initial load + setElesAndLayout(initEles, function () { + // onready + cy.startAnimationLoop(); + _p.ready = true; + + // if a ready callback is specified as an option, the bind it + if (fn$6(options.ready)) { + cy.on('ready', options.ready); + } + + // bind all the ready handlers registered before creating this instance + for (var i = 0; i < readies.length; i++) { + var fn = readies[i]; + cy.on('ready', fn); + } + if (reg) { + reg.readies = []; + } // clear b/c we've bound them all and don't want to keep it around in case a new core uses the same div etc + + cy.emit('ready'); + }, options.done); + }); + }; + var corefn = Core.prototype; // short alias + + extend(corefn, { + instanceString: function instanceString() { + return 'core'; + }, + isReady: function isReady() { + return this._private.ready; + }, + destroyed: function destroyed() { + return this._private.destroyed; + }, + ready: function ready(fn) { + if (this.isReady()) { + this.emitter().emit('ready', [], fn); // just calls fn as though triggered via ready event + } else { + this.on('ready', fn); + } + return this; + }, + destroy: function destroy() { + var cy = this; + if (cy.destroyed()) return; + cy.stopAnimationLoop(); + cy.destroyRenderer(); + this.emit('destroy'); + cy._private.destroyed = true; + return cy; + }, + hasElementWithId: function hasElementWithId(id) { + return this._private.elements.hasElementWithId(id); + }, + getElementById: function getElementById(id) { + return this._private.elements.getElementById(id); + }, + hasCompoundNodes: function hasCompoundNodes() { + return this._private.hasCompoundNodes; + }, + headless: function headless() { + return this._private.renderer.isHeadless(); + }, + styleEnabled: function styleEnabled() { + return this._private.styleEnabled; + }, + addToPool: function addToPool(eles) { + this._private.elements.merge(eles); + return this; // chaining + }, + + removeFromPool: function removeFromPool(eles) { + this._private.elements.unmerge(eles); + return this; + }, + container: function container() { + return this._private.container || null; + }, + window: function window() { + var container = this._private.container; + if (container == null) return _window; + var ownerDocument = this._private.container.ownerDocument; + if (ownerDocument === undefined || ownerDocument == null) { + return _window; + } + return ownerDocument.defaultView || _window; + }, + mount: function mount(container) { + if (container == null) { + return; + } + var cy = this; + var _p = cy._private; + var options = _p.options; + if (!htmlElement(container) && htmlElement(container[0])) { + container = container[0]; + } + cy.stopAnimationLoop(); + cy.destroyRenderer(); + _p.container = container; + _p.styleEnabled = true; + cy.invalidateSize(); + cy.initRenderer(extend({}, options, options.renderer, { + // allow custom renderer name to be re-used, otherwise use canvas + name: options.renderer.name === 'null' ? 'canvas' : options.renderer.name + })); + cy.startAnimationLoop(); + cy.style(options.style); + cy.emit('mount'); + return cy; + }, + unmount: function unmount() { + var cy = this; + cy.stopAnimationLoop(); + cy.destroyRenderer(); + cy.initRenderer({ + name: 'null' + }); + cy.emit('unmount'); + return cy; + }, + options: function options() { + return copy(this._private.options); + }, + json: function json(obj) { + var cy = this; + var _p = cy._private; + var eles = cy.mutableElements(); + var getFreshRef = function getFreshRef(ele) { + return cy.getElementById(ele.id()); + }; + if (plainObject(obj)) { + // set + + cy.startBatch(); + if (obj.elements) { + var idInJson = {}; + var updateEles = function updateEles(jsons, gr) { + var toAdd = []; + var toMod = []; + for (var i = 0; i < jsons.length; i++) { + var json = jsons[i]; + if (!json.data.id) { + warn('cy.json() cannot handle elements without an ID attribute'); + continue; + } + var id = '' + json.data.id; // id must be string + var ele = cy.getElementById(id); + idInJson[id] = true; + if (ele.length !== 0) { + // existing element should be updated + toMod.push({ + ele: ele, + json: json + }); + } else { + // otherwise should be added + if (gr) { + json.group = gr; + toAdd.push(json); + } else { + toAdd.push(json); + } + } + } + cy.add(toAdd); + for (var _i = 0; _i < toMod.length; _i++) { + var _toMod$_i = toMod[_i], + _ele = _toMod$_i.ele, + _json = _toMod$_i.json; + _ele.json(_json); + } + }; + if (array(obj.elements)) { + // elements: [] + updateEles(obj.elements); + } else { + // elements: { nodes: [], edges: [] } + var grs = ['nodes', 'edges']; + for (var i = 0; i < grs.length; i++) { + var gr = grs[i]; + var elements = obj.elements[gr]; + if (array(elements)) { + updateEles(elements, gr); + } + } + } + var parentsToRemove = cy.collection(); + eles.filter(function (ele) { + return !idInJson[ele.id()]; + }).forEach(function (ele) { + if (ele.isParent()) { + parentsToRemove.merge(ele); + } else { + ele.remove(); + } + }); + + // so that children are not removed w/parent + parentsToRemove.forEach(function (ele) { + return ele.children().move({ + parent: null + }); + }); + + // intermediate parents may be moved by prior line, so make sure we remove by fresh refs + parentsToRemove.forEach(function (ele) { + return getFreshRef(ele).remove(); + }); + } + if (obj.style) { + cy.style(obj.style); + } + if (obj.zoom != null && obj.zoom !== _p.zoom) { + cy.zoom(obj.zoom); + } + if (obj.pan) { + if (obj.pan.x !== _p.pan.x || obj.pan.y !== _p.pan.y) { + cy.pan(obj.pan); + } + } + if (obj.data) { + cy.data(obj.data); + } + var fields = ['minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'panningEnabled', 'userPanningEnabled', 'boxSelectionEnabled', 'autolock', 'autoungrabify', 'autounselectify', 'multiClickDebounceTime']; + for (var _i2 = 0; _i2 < fields.length; _i2++) { + var f = fields[_i2]; + if (obj[f] != null) { + cy[f](obj[f]); + } + } + cy.endBatch(); + return this; // chaining + } else { + // get + var flat = !!obj; + var json = {}; + if (flat) { + json.elements = this.elements().map(function (ele) { + return ele.json(); + }); + } else { + json.elements = {}; + eles.forEach(function (ele) { + var group = ele.group(); + if (!json.elements[group]) { + json.elements[group] = []; + } + json.elements[group].push(ele.json()); + }); + } + if (this._private.styleEnabled) { + json.style = cy.style().json(); + } + json.data = copy(cy.data()); + var options = _p.options; + json.zoomingEnabled = _p.zoomingEnabled; + json.userZoomingEnabled = _p.userZoomingEnabled; + json.zoom = _p.zoom; + json.minZoom = _p.minZoom; + json.maxZoom = _p.maxZoom; + json.panningEnabled = _p.panningEnabled; + json.userPanningEnabled = _p.userPanningEnabled; + json.pan = copy(_p.pan); + json.boxSelectionEnabled = _p.boxSelectionEnabled; + json.renderer = copy(options.renderer); + json.hideEdgesOnViewport = options.hideEdgesOnViewport; + json.textureOnViewport = options.textureOnViewport; + json.wheelSensitivity = options.wheelSensitivity; + json.motionBlur = options.motionBlur; + json.multiClickDebounceTime = options.multiClickDebounceTime; + return json; + } + } + }); + corefn.$id = corefn.getElementById; + [corefn$9, corefn$8, elesfn, corefn$7, corefn$6, corefn$5, corefn$4, corefn$3, corefn$2, corefn$1, fn].forEach(function (props) { + extend(corefn, props); + }); + + /* eslint-disable no-unused-vars */ + var defaults$7 = { + fit: true, + // whether to fit the viewport to the graph + directed: false, + // whether the tree is directed downwards (or edges can point in any direction if false) + padding: 30, + // padding on fit + circle: false, + // put depths in concentric circles if true, put depths top down if false + grid: false, + // whether to create an even grid into which the DAG is placed (circle:false only) + spacingFactor: 1.75, + // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap) + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + avoidOverlap: true, + // prevents node overlap, may overflow boundingBox if not enough space + nodeDimensionsIncludeLabels: false, + // Excludes the label when calculating node bounding boxes for the layout algorithm + roots: undefined, + // the roots of the trees + depthSort: undefined, + // a sorting function to order nodes at equal depth. e.g. function(a, b){ return a.data('weight') - b.data('weight') } + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled, + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts + }; + + var deprecatedOptionDefaults = { + maximal: false, + // whether to shift nodes down their natural BFS depths in order to avoid upwards edges (DAGS only); setting acyclic to true sets maximal to true also + acyclic: false // whether the tree is acyclic and thus a node could be shifted (due to the maximal option) multiple times without causing an infinite loop; setting to true sets maximal to true also; if you are uncertain whether a tree is acyclic, set to false to avoid potential infinite loops + }; + + /* eslint-enable */ + + var getInfo = function getInfo(ele) { + return ele.scratch('breadthfirst'); + }; + var setInfo = function setInfo(ele, obj) { + return ele.scratch('breadthfirst', obj); + }; + function BreadthFirstLayout(options) { + this.options = extend({}, defaults$7, deprecatedOptionDefaults, options); + } + BreadthFirstLayout.prototype.run = function () { + var params = this.options; + var options = params; + var cy = params.cy; + var eles = options.eles; + var nodes = eles.nodes().filter(function (n) { + return !n.isParent(); + }); + var graph = eles; + var directed = options.directed; + var maximal = options.acyclic || options.maximal || options.maximalAdjustments > 0; // maximalAdjustments for compat. w/ old code; also, setting acyclic to true sets maximal to true + + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var roots; + if (elementOrCollection(options.roots)) { + roots = options.roots; + } else if (array(options.roots)) { + var rootsArray = []; + for (var i = 0; i < options.roots.length; i++) { + var id = options.roots[i]; + var ele = cy.getElementById(id); + rootsArray.push(ele); + } + roots = cy.collection(rootsArray); + } else if (string(options.roots)) { + roots = cy.$(options.roots); + } else { + if (directed) { + roots = nodes.roots(); + } else { + var components = eles.components(); + roots = cy.collection(); + var _loop = function _loop(_i) { + var comp = components[_i]; + var maxDegree = comp.maxDegree(false); + var compRoots = comp.filter(function (ele) { + return ele.degree(false) === maxDegree; + }); + roots = roots.add(compRoots); + }; + for (var _i = 0; _i < components.length; _i++) { + _loop(_i); + } + } + } + var depths = []; + var foundByBfs = {}; + var addToDepth = function addToDepth(ele, d) { + if (depths[d] == null) { + depths[d] = []; + } + var i = depths[d].length; + depths[d].push(ele); + setInfo(ele, { + index: i, + depth: d + }); + }; + var changeDepth = function changeDepth(ele, newDepth) { + var _getInfo = getInfo(ele), + depth = _getInfo.depth, + index = _getInfo.index; + depths[depth][index] = null; + addToDepth(ele, newDepth); + }; + + // find the depths of the nodes + graph.bfs({ + roots: roots, + directed: options.directed, + visit: function visit(node, edge, pNode, i, depth) { + var ele = node[0]; + var id = ele.id(); + addToDepth(ele, depth); + foundByBfs[id] = true; + } + }); + + // check for nodes not found by bfs + var orphanNodes = []; + for (var _i2 = 0; _i2 < nodes.length; _i2++) { + var _ele = nodes[_i2]; + if (foundByBfs[_ele.id()]) { + continue; + } else { + orphanNodes.push(_ele); + } + } + + // assign the nodes a depth and index + + var assignDepthsAt = function assignDepthsAt(i) { + var eles = depths[i]; + for (var j = 0; j < eles.length; j++) { + var _ele2 = eles[j]; + if (_ele2 == null) { + eles.splice(j, 1); + j--; + continue; + } + setInfo(_ele2, { + depth: i, + index: j + }); + } + }; + var assignDepths = function assignDepths() { + for (var _i3 = 0; _i3 < depths.length; _i3++) { + assignDepthsAt(_i3); + } + }; + var adjustMaximally = function adjustMaximally(ele, shifted) { + var eInfo = getInfo(ele); + var incomers = ele.incomers().filter(function (el) { + return el.isNode() && eles.has(el); + }); + var maxDepth = -1; + var id = ele.id(); + for (var k = 0; k < incomers.length; k++) { + var incmr = incomers[k]; + var iInfo = getInfo(incmr); + maxDepth = Math.max(maxDepth, iInfo.depth); + } + if (eInfo.depth <= maxDepth) { + if (!options.acyclic && shifted[id]) { + return null; + } + var newDepth = maxDepth + 1; + changeDepth(ele, newDepth); + shifted[id] = newDepth; + return true; + } + return false; + }; + + // for the directed case, try to make the edges all go down (i.e. depth i => depth i + 1) + if (directed && maximal) { + var Q = []; + var shifted = {}; + var enqueue = function enqueue(n) { + return Q.push(n); + }; + var dequeue = function dequeue() { + return Q.shift(); + }; + nodes.forEach(function (n) { + return Q.push(n); + }); + while (Q.length > 0) { + var _ele3 = dequeue(); + var didShift = adjustMaximally(_ele3, shifted); + if (didShift) { + _ele3.outgoers().filter(function (el) { + return el.isNode() && eles.has(el); + }).forEach(enqueue); + } else if (didShift === null) { + warn('Detected double maximal shift for node `' + _ele3.id() + '`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.'); + break; // exit on failure + } + } + } + + assignDepths(); // clear holes + + // find min distance we need to leave between nodes + var minDistance = 0; + if (options.avoidOverlap) { + for (var _i4 = 0; _i4 < nodes.length; _i4++) { + var n = nodes[_i4]; + var nbb = n.layoutDimensions(options); + var w = nbb.w; + var h = nbb.h; + minDistance = Math.max(minDistance, w, h); + } + } + + // get the weighted percent for an element based on its connectivity to other levels + var cachedWeightedPercent = {}; + var getWeightedPercent = function getWeightedPercent(ele) { + if (cachedWeightedPercent[ele.id()]) { + return cachedWeightedPercent[ele.id()]; + } + var eleDepth = getInfo(ele).depth; + var neighbors = ele.neighborhood(); + var percent = 0; + var samples = 0; + for (var _i5 = 0; _i5 < neighbors.length; _i5++) { + var neighbor = neighbors[_i5]; + if (neighbor.isEdge() || neighbor.isParent() || !nodes.has(neighbor)) { + continue; + } + var bf = getInfo(neighbor); + if (bf == null) { + continue; + } + var index = bf.index; + var depth = bf.depth; + + // unassigned neighbours shouldn't affect the ordering + if (index == null || depth == null) { + continue; + } + var nDepth = depths[depth].length; + if (depth < eleDepth) { + // only get influenced by elements above + percent += index / nDepth; + samples++; + } + } + samples = Math.max(1, samples); + percent = percent / samples; + if (samples === 0) { + // put lone nodes at the start + percent = 0; + } + cachedWeightedPercent[ele.id()] = percent; + return percent; + }; + + // rearrange the indices in each depth level based on connectivity + + var sortFn = function sortFn(a, b) { + var apct = getWeightedPercent(a); + var bpct = getWeightedPercent(b); + var diff = apct - bpct; + if (diff === 0) { + return ascending(a.id(), b.id()); // make sure sort doesn't have don't-care comparisons + } else { + return diff; + } + }; + if (options.depthSort !== undefined) { + sortFn = options.depthSort; + } + + // sort each level to make connected nodes closer + for (var _i6 = 0; _i6 < depths.length; _i6++) { + depths[_i6].sort(sortFn); + assignDepthsAt(_i6); + } + + // assign orphan nodes to a new top-level depth + var orphanDepth = []; + for (var _i7 = 0; _i7 < orphanNodes.length; _i7++) { + orphanDepth.push(orphanNodes[_i7]); + } + depths.unshift(orphanDepth); + assignDepths(); + var biggestDepthSize = 0; + for (var _i8 = 0; _i8 < depths.length; _i8++) { + biggestDepthSize = Math.max(depths[_i8].length, biggestDepthSize); + } + var center = { + x: bb.x1 + bb.w / 2, + y: bb.x1 + bb.h / 2 + }; + var maxDepthSize = depths.reduce(function (max, eles) { + return Math.max(max, eles.length); + }, 0); + var getPosition = function getPosition(ele) { + var _getInfo2 = getInfo(ele), + depth = _getInfo2.depth, + index = _getInfo2.index; + var depthSize = depths[depth].length; + var distanceX = Math.max(bb.w / ((options.grid ? maxDepthSize : depthSize) + 1), minDistance); + var distanceY = Math.max(bb.h / (depths.length + 1), minDistance); + var radiusStepSize = Math.min(bb.w / 2 / depths.length, bb.h / 2 / depths.length); + radiusStepSize = Math.max(radiusStepSize, minDistance); + if (!options.circle) { + var epos = { + x: center.x + (index + 1 - (depthSize + 1) / 2) * distanceX, + y: (depth + 1) * distanceY + }; + return epos; + } else { + var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize / 2 : 0); + var theta = 2 * Math.PI / depths[depth].length * index; + if (depth === 0 && depths[0].length === 1) { + radius = 1; + } + return { + x: center.x + radius * Math.cos(theta), + y: center.y + radius * Math.sin(theta) + }; + } + }; + eles.nodes().layoutPositions(this, options, getPosition); + return this; // chaining + }; + + var defaults$6 = { + fit: true, + // whether to fit the viewport to the graph + padding: 30, + // the padding on fit + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + avoidOverlap: true, + // prevents node overlap, may overflow boundingBox and radius if not enough space + nodeDimensionsIncludeLabels: false, + // Excludes the label when calculating node bounding boxes for the layout algorithm + spacingFactor: undefined, + // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up + radius: undefined, + // the radius of the circle + startAngle: 3 / 2 * Math.PI, + // where nodes start in radians + sweep: undefined, + // how many radians should be between the first and last node (defaults to full circle) + clockwise: true, + // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false) + sort: undefined, + // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') } + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts + }; + + function CircleLayout(options) { + this.options = extend({}, defaults$6, options); + } + CircleLayout.prototype.run = function () { + var params = this.options; + var options = params; + var cy = params.cy; + var eles = options.eles; + var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise; + var nodes = eles.nodes().not(':parent'); + if (options.sort) { + nodes = nodes.sort(options.sort); + } + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var center = { + x: bb.x1 + bb.w / 2, + y: bb.y1 + bb.h / 2 + }; + var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / nodes.length : options.sweep; + var dTheta = sweep / Math.max(1, nodes.length - 1); + var r; + var minDistance = 0; + for (var i = 0; i < nodes.length; i++) { + var n = nodes[i]; + var nbb = n.layoutDimensions(options); + var w = nbb.w; + var h = nbb.h; + minDistance = Math.max(minDistance, w, h); + } + if (number$1(options.radius)) { + r = options.radius; + } else if (nodes.length <= 1) { + r = 0; + } else { + r = Math.min(bb.h, bb.w) / 2 - minDistance; + } + + // calculate the radius + if (nodes.length > 1 && options.avoidOverlap) { + // but only if more than one node (can't overlap) + minDistance *= 1.75; // just to have some nice spacing + + var dcos = Math.cos(dTheta) - Math.cos(0); + var dsin = Math.sin(dTheta) - Math.sin(0); + var rMin = Math.sqrt(minDistance * minDistance / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping + r = Math.max(rMin, r); + } + var getPos = function getPos(ele, i) { + var theta = options.startAngle + i * dTheta * (clockwise ? 1 : -1); + var rx = r * Math.cos(theta); + var ry = r * Math.sin(theta); + var pos = { + x: center.x + rx, + y: center.y + ry + }; + return pos; + }; + eles.nodes().layoutPositions(this, options, getPos); + return this; // chaining + }; + + var defaults$5 = { + fit: true, + // whether to fit the viewport to the graph + padding: 30, + // the padding on fit + startAngle: 3 / 2 * Math.PI, + // where nodes start in radians + sweep: undefined, + // how many radians should be between the first and last node (defaults to full circle) + clockwise: true, + // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false) + equidistant: false, + // whether levels have an equal radial distance betwen them, may cause bounding box overflow + minNodeSpacing: 10, + // min spacing between outside of nodes (used for radius adjustment) + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + avoidOverlap: true, + // prevents node overlap, may overflow boundingBox if not enough space + nodeDimensionsIncludeLabels: false, + // Excludes the label when calculating node bounding boxes for the layout algorithm + height: undefined, + // height of layout area (overrides container height) + width: undefined, + // width of layout area (overrides container width) + spacingFactor: undefined, + // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up + concentric: function concentric(node) { + // returns numeric value for each node, placing higher nodes in levels towards the centre + return node.degree(); + }, + levelWidth: function levelWidth(nodes) { + // the variation of concentric values in each level + return nodes.maxDegree() / 4; + }, + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts + }; + + function ConcentricLayout(options) { + this.options = extend({}, defaults$5, options); + } + ConcentricLayout.prototype.run = function () { + var params = this.options; + var options = params; + var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise; + var cy = params.cy; + var eles = options.eles; + var nodes = eles.nodes().not(':parent'); + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var center = { + x: bb.x1 + bb.w / 2, + y: bb.y1 + bb.h / 2 + }; + var nodeValues = []; // { node, value } + var maxNodeSize = 0; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var value = void 0; + + // calculate the node value + value = options.concentric(node); + nodeValues.push({ + value: value, + node: node + }); + + // for style mapping + node._private.scratch.concentric = value; + } + + // in case we used the `concentric` in style + nodes.updateStyle(); + + // calculate max size now based on potentially updated mappers + for (var _i = 0; _i < nodes.length; _i++) { + var _node = nodes[_i]; + var nbb = _node.layoutDimensions(options); + maxNodeSize = Math.max(maxNodeSize, nbb.w, nbb.h); + } + + // sort node values in descreasing order + nodeValues.sort(function (a, b) { + return b.value - a.value; + }); + var levelWidth = options.levelWidth(nodes); + + // put the values into levels + var levels = [[]]; + var currentLevel = levels[0]; + for (var _i2 = 0; _i2 < nodeValues.length; _i2++) { + var val = nodeValues[_i2]; + if (currentLevel.length > 0) { + var diff = Math.abs(currentLevel[0].value - val.value); + if (diff >= levelWidth) { + currentLevel = []; + levels.push(currentLevel); + } + } + currentLevel.push(val); + } + + // create positions from levels + + var minDist = maxNodeSize + options.minNodeSpacing; // min dist between nodes + + if (!options.avoidOverlap) { + // then strictly constrain to bb + var firstLvlHasMulti = levels.length > 0 && levels[0].length > 1; + var maxR = Math.min(bb.w, bb.h) / 2 - minDist; + var rStep = maxR / (levels.length + firstLvlHasMulti ? 1 : 0); + minDist = Math.min(minDist, rStep); + } + + // find the metrics for each level + var r = 0; + for (var _i3 = 0; _i3 < levels.length; _i3++) { + var level = levels[_i3]; + var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / level.length : options.sweep; + var dTheta = level.dTheta = sweep / Math.max(1, level.length - 1); + + // calculate the radius + if (level.length > 1 && options.avoidOverlap) { + // but only if more than one node (can't overlap) + var dcos = Math.cos(dTheta) - Math.cos(0); + var dsin = Math.sin(dTheta) - Math.sin(0); + var rMin = Math.sqrt(minDist * minDist / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping + + r = Math.max(rMin, r); + } + level.r = r; + r += minDist; + } + if (options.equidistant) { + var rDeltaMax = 0; + var _r = 0; + for (var _i4 = 0; _i4 < levels.length; _i4++) { + var _level = levels[_i4]; + var rDelta = _level.r - _r; + rDeltaMax = Math.max(rDeltaMax, rDelta); + } + _r = 0; + for (var _i5 = 0; _i5 < levels.length; _i5++) { + var _level2 = levels[_i5]; + if (_i5 === 0) { + _r = _level2.r; + } + _level2.r = _r; + _r += rDeltaMax; + } + } + + // calculate the node positions + var pos = {}; // id => position + for (var _i6 = 0; _i6 < levels.length; _i6++) { + var _level3 = levels[_i6]; + var _dTheta = _level3.dTheta; + var _r2 = _level3.r; + for (var j = 0; j < _level3.length; j++) { + var _val = _level3[j]; + var theta = options.startAngle + (clockwise ? 1 : -1) * _dTheta * j; + var p = { + x: center.x + _r2 * Math.cos(theta), + y: center.y + _r2 * Math.sin(theta) + }; + pos[_val.node.id()] = p; + } + } + + // position the nodes + eles.nodes().layoutPositions(this, options, function (ele) { + var id = ele.id(); + return pos[id]; + }); + return this; // chaining + }; + + /* + The CoSE layout was written by Gerardo Huck. + https://www.linkedin.com/in/gerardohuck/ + + Based on the following article: + http://dl.acm.org/citation.cfm?id=1498047 + + Modifications tracked on Github. + */ + var DEBUG; + + /** + * @brief : default layout options + */ + var defaults$4 = { + // Called on `layoutready` + ready: function ready() {}, + // Called on `layoutstop` + stop: function stop() {}, + // Whether to animate while running the layout + // true : Animate continuously as the layout is running + // false : Just show the end result + // 'end' : Animate with the end result, from the initial positions to the end positions + animate: true, + // Easing of the animation for animate:'end' + animationEasing: undefined, + // The duration of the animation for animate:'end' + animationDuration: undefined, + // A function that determines whether the node should be animated + // All nodes animated by default on animate enabled + // Non-animated nodes are positioned immediately when the layout starts + animateFilter: function animateFilter(node, i) { + return true; + }, + // The layout animates only after this many milliseconds for animate:true + // (prevents flashing on fast runs) + animationThreshold: 250, + // Number of iterations between consecutive screen positions update + refresh: 20, + // Whether to fit the network view after when done + fit: true, + // Padding on fit + padding: 30, + // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + boundingBox: undefined, + // Excludes the label when calculating node bounding boxes for the layout algorithm + nodeDimensionsIncludeLabels: false, + // Randomize the initial positions of the nodes (true) or use existing positions (false) + randomize: false, + // Extra spacing between components in non-compound graphs + componentSpacing: 40, + // Node repulsion (non overlapping) multiplier + nodeRepulsion: function nodeRepulsion(node) { + return 2048; + }, + // Node repulsion (overlapping) multiplier + nodeOverlap: 4, + // Ideal edge (non nested) length + idealEdgeLength: function idealEdgeLength(edge) { + return 32; + }, + // Divisor to compute edge forces + edgeElasticity: function edgeElasticity(edge) { + return 32; + }, + // Nesting factor (multiplier) to compute ideal edge length for nested edges + nestingFactor: 1.2, + // Gravity force (constant) + gravity: 1, + // Maximum number of iterations to perform + numIter: 1000, + // Initial temperature (maximum node displacement) + initialTemp: 1000, + // Cooling factor (how the temperature is reduced between consecutive iterations + coolingFactor: 0.99, + // Lower temperature threshold (below this point the layout will end) + minTemp: 1.0 + }; + + /** + * @brief : constructor + * @arg options : object containing layout options + */ + function CoseLayout(options) { + this.options = extend({}, defaults$4, options); + this.options.layout = this; + + // Exclude any edge that has a source or target node that is not in the set of passed-in nodes + var nodes = this.options.eles.nodes(); + var edges = this.options.eles.edges(); + var notEdges = edges.filter(function (e) { + var sourceId = e.source().data('id'); + var targetId = e.target().data('id'); + var hasSource = nodes.some(function (n) { + return n.data('id') === sourceId; + }); + var hasTarget = nodes.some(function (n) { + return n.data('id') === targetId; + }); + return !hasSource || !hasTarget; + }); + this.options.eles = this.options.eles.not(notEdges); + } + + /** + * @brief : runs the layout + */ + CoseLayout.prototype.run = function () { + var options = this.options; + var cy = options.cy; + var layout = this; + layout.stopped = false; + if (options.animate === true || options.animate === false) { + layout.emit({ + type: 'layoutstart', + layout: layout + }); + } + + // Set DEBUG - Global variable + if (true === options.debug) { + DEBUG = true; + } else { + DEBUG = false; + } + + // Initialize layout info + var layoutInfo = createLayoutInfo(cy, layout, options); + + // Show LayoutInfo contents if debugging + if (DEBUG) { + printLayoutInfo(layoutInfo); + } + + // If required, randomize node positions + if (options.randomize) { + randomizePositions(layoutInfo); + } + var startTime = performanceNow(); + var refresh = function refresh() { + refreshPositions(layoutInfo, cy, options); + + // Fit the graph if necessary + if (true === options.fit) { + cy.fit(options.padding); + } + }; + var mainLoop = function mainLoop(i) { + if (layout.stopped || i >= options.numIter) { + // logDebug("Layout manually stopped. Stopping computation in step " + i); + return false; + } + + // Do one step in the phisical simulation + step(layoutInfo, options); + + // Update temperature + layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor; + // logDebug("New temperature: " + layoutInfo.temperature); + + if (layoutInfo.temperature < options.minTemp) { + // logDebug("Temperature drop below minimum threshold. Stopping computation in step " + i); + return false; + } + return true; + }; + var done = function done() { + if (options.animate === true || options.animate === false) { + refresh(); + + // Layout has finished + layout.one('layoutstop', options.stop); + layout.emit({ + type: 'layoutstop', + layout: layout + }); + } else { + var nodes = options.eles.nodes(); + var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes); + nodes.layoutPositions(layout, options, getScaledPos); + } + }; + var i = 0; + var loopRet = true; + if (options.animate === true) { + var frame = function frame() { + var f = 0; + while (loopRet && f < options.refresh) { + loopRet = mainLoop(i); + i++; + f++; + } + if (!loopRet) { + // it's done + separateComponents(layoutInfo, options); + done(); + } else { + var now = performanceNow(); + if (now - startTime >= options.animationThreshold) { + refresh(); + } + requestAnimationFrame(frame); + } + }; + frame(); + } else { + while (loopRet) { + loopRet = mainLoop(i); + i++; + } + separateComponents(layoutInfo, options); + done(); + } + return this; // chaining + }; + + /** + * @brief : called on continuous layouts to stop them before they finish + */ + CoseLayout.prototype.stop = function () { + this.stopped = true; + if (this.thread) { + this.thread.stop(); + } + this.emit('layoutstop'); + return this; // chaining + }; + + CoseLayout.prototype.destroy = function () { + if (this.thread) { + this.thread.stop(); + } + return this; // chaining + }; + + /** + * @brief : Creates an object which is contains all the data + * used in the layout process + * @arg cy : cytoscape.js object + * @return : layoutInfo object initialized + */ + var createLayoutInfo = function createLayoutInfo(cy, layout, options) { + // Shortcut + var edges = options.eles.edges(); + var nodes = options.eles.nodes(); + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var layoutInfo = { + isCompound: cy.hasCompoundNodes(), + layoutNodes: [], + idToIndex: {}, + nodeSize: nodes.size(), + graphSet: [], + indexToGraph: [], + layoutEdges: [], + edgeSize: edges.size(), + temperature: options.initialTemp, + clientWidth: bb.w, + clientHeight: bb.h, + boundingBox: bb + }; + var components = options.eles.components(); + var id2cmptId = {}; + for (var i = 0; i < components.length; i++) { + var component = components[i]; + for (var j = 0; j < component.length; j++) { + var node = component[j]; + id2cmptId[node.id()] = i; + } + } + + // Iterate over all nodes, creating layout nodes + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = nodes[i]; + var nbb = n.layoutDimensions(options); + var tempNode = {}; + tempNode.isLocked = n.locked(); + tempNode.id = n.data('id'); + tempNode.parentId = n.data('parent'); + tempNode.cmptId = id2cmptId[n.id()]; + tempNode.children = []; + tempNode.positionX = n.position('x'); + tempNode.positionY = n.position('y'); + tempNode.offsetX = 0; + tempNode.offsetY = 0; + tempNode.height = nbb.w; + tempNode.width = nbb.h; + tempNode.maxX = tempNode.positionX + tempNode.width / 2; + tempNode.minX = tempNode.positionX - tempNode.width / 2; + tempNode.maxY = tempNode.positionY + tempNode.height / 2; + tempNode.minY = tempNode.positionY - tempNode.height / 2; + tempNode.padLeft = parseFloat(n.style('padding')); + tempNode.padRight = parseFloat(n.style('padding')); + tempNode.padTop = parseFloat(n.style('padding')); + tempNode.padBottom = parseFloat(n.style('padding')); + + // forces + tempNode.nodeRepulsion = fn$6(options.nodeRepulsion) ? options.nodeRepulsion(n) : options.nodeRepulsion; + + // Add new node + layoutInfo.layoutNodes.push(tempNode); + // Add entry to id-index map + layoutInfo.idToIndex[tempNode.id] = i; + } + + // Inline implementation of a queue, used for traversing the graph in BFS order + var queue = []; + var start = 0; // Points to the start the queue + var end = -1; // Points to the end of the queue + + var tempGraph = []; + + // Second pass to add child information and + // initialize queue for hierarchical traversal + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + var p_id = n.parentId; + // Check if node n has a parent node + if (null != p_id) { + // Add node Id to parent's list of children + layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id); + } else { + // If a node doesn't have a parent, then it's in the root graph + queue[++end] = n.id; + tempGraph.push(n.id); + } + } + + // Add root graph to graphSet + layoutInfo.graphSet.push(tempGraph); + + // Traverse the graph, level by level, + while (start <= end) { + // Get the node to visit and remove it from queue + var node_id = queue[start++]; + var node_ix = layoutInfo.idToIndex[node_id]; + var node = layoutInfo.layoutNodes[node_ix]; + var children = node.children; + if (children.length > 0) { + // Add children nodes as a new graph to graph set + layoutInfo.graphSet.push(children); + // Add children to que queue to be visited + for (var i = 0; i < children.length; i++) { + queue[++end] = children[i]; + } + } + } + + // Create indexToGraph map + for (var i = 0; i < layoutInfo.graphSet.length; i++) { + var graph = layoutInfo.graphSet[i]; + for (var j = 0; j < graph.length; j++) { + var index = layoutInfo.idToIndex[graph[j]]; + layoutInfo.indexToGraph[index] = i; + } + } + + // Iterate over all edges, creating Layout Edges + for (var i = 0; i < layoutInfo.edgeSize; i++) { + var e = edges[i]; + var tempEdge = {}; + tempEdge.id = e.data('id'); + tempEdge.sourceId = e.data('source'); + tempEdge.targetId = e.data('target'); + + // Compute ideal length + var idealLength = fn$6(options.idealEdgeLength) ? options.idealEdgeLength(e) : options.idealEdgeLength; + var elasticity = fn$6(options.edgeElasticity) ? options.edgeElasticity(e) : options.edgeElasticity; + + // Check if it's an inter graph edge + var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId]; + var targetIx = layoutInfo.idToIndex[tempEdge.targetId]; + var sourceGraph = layoutInfo.indexToGraph[sourceIx]; + var targetGraph = layoutInfo.indexToGraph[targetIx]; + if (sourceGraph != targetGraph) { + // Find lowest common graph ancestor + var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo); + + // Compute sum of node depths, relative to lca graph + var lcaGraph = layoutInfo.graphSet[lca]; + var depth = 0; + + // Source depth + var tempNode = layoutInfo.layoutNodes[sourceIx]; + while (-1 === lcaGraph.indexOf(tempNode.id)) { + tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]]; + depth++; + } + + // Target depth + tempNode = layoutInfo.layoutNodes[targetIx]; + while (-1 === lcaGraph.indexOf(tempNode.id)) { + tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]]; + depth++; + } + + // logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId + + // ". Index: " + lca + " Contents: " + lcaGraph.toString() + + // ". Depth: " + depth); + + // Update idealLength + idealLength *= depth * options.nestingFactor; + } + tempEdge.idealLength = idealLength; + tempEdge.elasticity = elasticity; + layoutInfo.layoutEdges.push(tempEdge); + } + + // Finally, return layoutInfo object + return layoutInfo; + }; + + /** + * @brief : This function finds the index of the lowest common + * graph ancestor between 2 nodes in the subtree + * (from the graph hierarchy induced tree) whose + * root is graphIx + * + * @arg node1: node1's ID + * @arg node2: node2's ID + * @arg layoutInfo: layoutInfo object + * + */ + var findLCA = function findLCA(node1, node2, layoutInfo) { + // Find their common ancester, starting from the root graph + var res = findLCA_aux(node1, node2, 0, layoutInfo); + if (2 > res.count) { + // If aux function couldn't find the common ancester, + // then it is the root graph + return 0; + } else { + return res.graph; + } + }; + + /** + * @brief : Auxiliary function used for LCA computation + * + * @arg node1 : node1's ID + * @arg node2 : node2's ID + * @arg graphIx : subgraph index + * @arg layoutInfo : layoutInfo object + * + * @return : object of the form {count: X, graph: Y}, where: + * X is the number of ancestors (max: 2) found in + * graphIx (and it's subgraphs), + * Y is the graph index of the lowest graph containing + * all X nodes + */ + var findLCA_aux = function findLCA_aux(node1, node2, graphIx, layoutInfo) { + var graph = layoutInfo.graphSet[graphIx]; + // If both nodes belongs to graphIx + if (-1 < graph.indexOf(node1) && -1 < graph.indexOf(node2)) { + return { + count: 2, + graph: graphIx + }; + } + + // Make recursive calls for all subgraphs + var c = 0; + for (var i = 0; i < graph.length; i++) { + var nodeId = graph[i]; + var nodeIx = layoutInfo.idToIndex[nodeId]; + var children = layoutInfo.layoutNodes[nodeIx].children; + + // If the node has no child, skip it + if (0 === children.length) { + continue; + } + var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]]; + var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo); + if (0 === result.count) { + // Neither node1 nor node2 are present in this subgraph + continue; + } else if (1 === result.count) { + // One of (node1, node2) is present in this subgraph + c++; + if (2 === c) { + // We've already found both nodes, no need to keep searching + break; + } + } else { + // Both nodes are present in this subgraph + return result; + } + } + return { + count: c, + graph: graphIx + }; + }; + + /** + * @brief: printsLayoutInfo into js console + * Only used for debbuging + */ +var printLayoutInfo; + + /** + * @brief : Randomizes the position of all nodes + */ + var randomizePositions = function randomizePositions(layoutInfo, cy) { + var width = layoutInfo.clientWidth; + var height = layoutInfo.clientHeight; + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + + // No need to randomize compound nodes or locked nodes + if (0 === n.children.length && !n.isLocked) { + n.positionX = Math.random() * width; + n.positionY = Math.random() * height; + } + } + }; + var getScaleInBoundsFn = function getScaleInBoundsFn(layoutInfo, options, nodes) { + var bb = layoutInfo.boundingBox; + var coseBB = { + x1: Infinity, + x2: -Infinity, + y1: Infinity, + y2: -Infinity + }; + if (options.boundingBox) { + nodes.forEach(function (node) { + var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[node.data('id')]]; + coseBB.x1 = Math.min(coseBB.x1, lnode.positionX); + coseBB.x2 = Math.max(coseBB.x2, lnode.positionX); + coseBB.y1 = Math.min(coseBB.y1, lnode.positionY); + coseBB.y2 = Math.max(coseBB.y2, lnode.positionY); + }); + coseBB.w = coseBB.x2 - coseBB.x1; + coseBB.h = coseBB.y2 - coseBB.y1; + } + return function (ele, i) { + var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]]; + if (options.boundingBox) { + // then add extra bounding box constraint + var pctX = (lnode.positionX - coseBB.x1) / coseBB.w; + var pctY = (lnode.positionY - coseBB.y1) / coseBB.h; + return { + x: bb.x1 + pctX * bb.w, + y: bb.y1 + pctY * bb.h + }; + } else { + return { + x: lnode.positionX, + y: lnode.positionY + }; + } + }; + }; + + /** + * @brief : Updates the positions of nodes in the network + * @arg layoutInfo : LayoutInfo object + * @arg cy : Cytoscape object + * @arg options : Layout options + */ + var refreshPositions = function refreshPositions(layoutInfo, cy, options) { + // var s = 'Refreshing positions'; + // logDebug(s); + + var layout = options.layout; + var nodes = options.eles.nodes(); + var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes); + nodes.positions(getScaledPos); + + // Trigger layoutReady only on first call + if (true !== layoutInfo.ready) { + // s = 'Triggering layoutready'; + // logDebug(s); + layoutInfo.ready = true; + layout.one('layoutready', options.ready); + layout.emit({ + type: 'layoutready', + layout: this + }); + } + }; + + /** + * @brief : Logs a debug message in JS console, if DEBUG is ON + */ + // var logDebug = function(text) { + // if (DEBUG) { + // console.debug(text); + // } + // }; + + /** + * @brief : Performs one iteration of the physical simulation + * @arg layoutInfo : LayoutInfo object already initialized + * @arg cy : Cytoscape object + * @arg options : Layout options + */ + var step = function step(layoutInfo, options, _step) { + // var s = "\n\n###############################"; + // s += "\nSTEP: " + step; + // s += "\n###############################\n"; + // logDebug(s); + + // Calculate node repulsions + calculateNodeForces(layoutInfo, options); + // Calculate edge forces + calculateEdgeForces(layoutInfo); + // Calculate gravity forces + calculateGravityForces(layoutInfo, options); + // Propagate forces from parent to child + propagateForces(layoutInfo); + // Update positions based on calculated forces + updatePositions(layoutInfo); + }; + + /** + * @brief : Computes the node repulsion forces + */ + var calculateNodeForces = function calculateNodeForces(layoutInfo, options) { + // Go through each of the graphs in graphSet + // Nodes only repel each other if they belong to the same graph + // var s = 'calculateNodeForces'; + // logDebug(s); + for (var i = 0; i < layoutInfo.graphSet.length; i++) { + var graph = layoutInfo.graphSet[i]; + var numNodes = graph.length; + + // s = "Set: " + graph.toString(); + // logDebug(s); + + // Now get all the pairs of nodes + // Only get each pair once, (A, B) = (B, A) + for (var j = 0; j < numNodes; j++) { + var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]]; + for (var k = j + 1; k < numNodes; k++) { + var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]]; + nodeRepulsion(node1, node2, layoutInfo, options); + } + } + } + }; + var randomDistance = function randomDistance(max) { + return -max + 2 * max * Math.random(); + }; + + /** + * @brief : Compute the node repulsion forces between a pair of nodes + */ + var nodeRepulsion = function nodeRepulsion(node1, node2, layoutInfo, options) { + // var s = "Node repulsion. Node1: " + node1.id + " Node2: " + node2.id; + + var cmptId1 = node1.cmptId; + var cmptId2 = node2.cmptId; + if (cmptId1 !== cmptId2 && !layoutInfo.isCompound) { + return; + } + + // Get direction of line connecting both node centers + var directionX = node2.positionX - node1.positionX; + var directionY = node2.positionY - node1.positionY; + var maxRandDist = 1; + // s += "\ndirectionX: " + directionX + ", directionY: " + directionY; + + // If both centers are the same, apply a random force + if (0 === directionX && 0 === directionY) { + directionX = randomDistance(maxRandDist); + directionY = randomDistance(maxRandDist); + } + var overlap = nodesOverlap(node1, node2, directionX, directionY); + if (overlap > 0) { + // s += "\nNodes DO overlap."; + // s += "\nOverlap: " + overlap; + // If nodes overlap, repulsion force is proportional + // to the overlap + var force = options.nodeOverlap * overlap; + + // Compute the module and components of the force vector + var distance = Math.sqrt(directionX * directionX + directionY * directionY); + // s += "\nDistance: " + distance; + var forceX = force * directionX / distance; + var forceY = force * directionY / distance; + } else { + // s += "\nNodes do NOT overlap."; + // If there's no overlap, force is inversely proportional + // to squared distance + + // Get clipping points for both nodes + var point1 = findClippingPoint(node1, directionX, directionY); + var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY); + + // Use clipping points to compute distance + var distanceX = point2.x - point1.x; + var distanceY = point2.y - point1.y; + var distanceSqr = distanceX * distanceX + distanceY * distanceY; + var distance = Math.sqrt(distanceSqr); + // s += "\nDistance: " + distance; + + // Compute the module and components of the force vector + var force = (node1.nodeRepulsion + node2.nodeRepulsion) / distanceSqr; + var forceX = force * distanceX / distance; + var forceY = force * distanceY / distance; + } + + // Apply force + if (!node1.isLocked) { + node1.offsetX -= forceX; + node1.offsetY -= forceY; + } + if (!node2.isLocked) { + node2.offsetX += forceX; + node2.offsetY += forceY; + } + + // s += "\nForceX: " + forceX + " ForceY: " + forceY; + // logDebug(s); + + return; + }; + + /** + * @brief : Determines whether two nodes overlap or not + * @return : Amount of overlapping (0 => no overlap) + */ + var nodesOverlap = function nodesOverlap(node1, node2, dX, dY) { + if (dX > 0) { + var overlapX = node1.maxX - node2.minX; + } else { + var overlapX = node2.maxX - node1.minX; + } + if (dY > 0) { + var overlapY = node1.maxY - node2.minY; + } else { + var overlapY = node2.maxY - node1.minY; + } + if (overlapX >= 0 && overlapY >= 0) { + return Math.sqrt(overlapX * overlapX + overlapY * overlapY); + } else { + return 0; + } + }; + + /** + * @brief : Finds the point in which an edge (direction dX, dY) intersects + * the rectangular bounding box of it's source/target node + */ + var findClippingPoint = function findClippingPoint(node, dX, dY) { + // Shorcuts + var X = node.positionX; + var Y = node.positionY; + var H = node.height || 1; + var W = node.width || 1; + var dirSlope = dY / dX; + var nodeSlope = H / W; + + // var s = 'Computing clipping point of node ' + node.id + + // " . Height: " + H + ", Width: " + W + + // "\nDirection " + dX + ", " + dY; + // + // Compute intersection + var res = {}; + + // Case: Vertical direction (up) + if (0 === dX && 0 < dY) { + res.x = X; + // s += "\nUp direction"; + res.y = Y + H / 2; + return res; + } + + // Case: Vertical direction (down) + if (0 === dX && 0 > dY) { + res.x = X; + res.y = Y + H / 2; + // s += "\nDown direction"; + + return res; + } + + // Case: Intersects the right border + if (0 < dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) { + res.x = X + W / 2; + res.y = Y + W * dY / 2 / dX; + // s += "\nRightborder"; + + return res; + } + + // Case: Intersects the left border + if (0 > dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) { + res.x = X - W / 2; + res.y = Y - W * dY / 2 / dX; + // s += "\nLeftborder"; + + return res; + } + + // Case: Intersects the top border + if (0 < dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) { + res.x = X + H * dX / 2 / dY; + res.y = Y + H / 2; + // s += "\nTop border"; + + return res; + } + + // Case: Intersects the bottom border + if (0 > dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) { + res.x = X - H * dX / 2 / dY; + res.y = Y - H / 2; + // s += "\nBottom border"; + + return res; + } + + // s += "\nClipping point found at " + res.x + ", " + res.y; + // logDebug(s); + return res; + }; + + /** + * @brief : Calculates all edge forces + */ + var calculateEdgeForces = function calculateEdgeForces(layoutInfo, options) { + // Iterate over all edges + for (var i = 0; i < layoutInfo.edgeSize; i++) { + // Get edge, source & target nodes + var edge = layoutInfo.layoutEdges[i]; + var sourceIx = layoutInfo.idToIndex[edge.sourceId]; + var source = layoutInfo.layoutNodes[sourceIx]; + var targetIx = layoutInfo.idToIndex[edge.targetId]; + var target = layoutInfo.layoutNodes[targetIx]; + + // Get direction of line connecting both node centers + var directionX = target.positionX - source.positionX; + var directionY = target.positionY - source.positionY; + + // If both centers are the same, do nothing. + // A random force has already been applied as node repulsion + if (0 === directionX && 0 === directionY) { + continue; + } + + // Get clipping points for both nodes + var point1 = findClippingPoint(source, directionX, directionY); + var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY); + var lx = point2.x - point1.x; + var ly = point2.y - point1.y; + var l = Math.sqrt(lx * lx + ly * ly); + var force = Math.pow(edge.idealLength - l, 2) / edge.elasticity; + if (0 !== l) { + var forceX = force * lx / l; + var forceY = force * ly / l; + } else { + var forceX = 0; + var forceY = 0; + } + + // Add this force to target and source nodes + if (!source.isLocked) { + source.offsetX += forceX; + source.offsetY += forceY; + } + if (!target.isLocked) { + target.offsetX -= forceX; + target.offsetY -= forceY; + } + + // var s = 'Edge force between nodes ' + source.id + ' and ' + target.id; + // s += "\nDistance: " + l + " Force: (" + forceX + ", " + forceY + ")"; + // logDebug(s); + } + }; + + /** + * @brief : Computes gravity forces for all nodes + */ + var calculateGravityForces = function calculateGravityForces(layoutInfo, options) { + if (options.gravity === 0) { + return; + } + var distThreshold = 1; + + // var s = 'calculateGravityForces'; + // logDebug(s); + for (var i = 0; i < layoutInfo.graphSet.length; i++) { + var graph = layoutInfo.graphSet[i]; + var numNodes = graph.length; + + // s = "Set: " + graph.toString(); + // logDebug(s); + + // Compute graph center + if (0 === i) { + var centerX = layoutInfo.clientHeight / 2; + var centerY = layoutInfo.clientWidth / 2; + } else { + // Get Parent node for this graph, and use its position as center + var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]]; + var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]]; + var centerX = parent.positionX; + var centerY = parent.positionY; + } + // s = "Center found at: " + centerX + ", " + centerY; + // logDebug(s); + + // Apply force to all nodes in graph + for (var j = 0; j < numNodes; j++) { + var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]]; + // s = "Node: " + node.id; + + if (node.isLocked) { + continue; + } + var dx = centerX - node.positionX; + var dy = centerY - node.positionY; + var d = Math.sqrt(dx * dx + dy * dy); + if (d > distThreshold) { + var fx = options.gravity * dx / d; + var fy = options.gravity * dy / d; + node.offsetX += fx; + node.offsetY += fy; + // s += ": Applied force: " + fx + ", " + fy; + } + // logDebug(s); + } + } + }; + + /** + * @brief : This function propagates the existing offsets from + * parent nodes to its descendents. + * @arg layoutInfo : layoutInfo Object + * @arg cy : cytoscape Object + * @arg options : Layout options + */ + var propagateForces = function propagateForces(layoutInfo, options) { + // Inline implementation of a queue, used for traversing the graph in BFS order + var queue = []; + var start = 0; // Points to the start the queue + var end = -1; // Points to the end of the queue + + // logDebug('propagateForces'); + + // Start by visiting the nodes in the root graph + queue.push.apply(queue, layoutInfo.graphSet[0]); + end += layoutInfo.graphSet[0].length; + + // Traverse the graph, level by level, + while (start <= end) { + // Get the node to visit and remove it from queue + var nodeId = queue[start++]; + var nodeIndex = layoutInfo.idToIndex[nodeId]; + var node = layoutInfo.layoutNodes[nodeIndex]; + var children = node.children; + + // We only need to process the node if it's compound + if (0 < children.length && !node.isLocked) { + var offX = node.offsetX; + var offY = node.offsetY; + + // var s = "Propagating offset from parent node : " + node.id + + // ". OffsetX: " + offX + ". OffsetY: " + offY; + // s += "\n Children: " + children.toString(); + // logDebug(s); + + for (var i = 0; i < children.length; i++) { + var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]]; + // Propagate offset + childNode.offsetX += offX; + childNode.offsetY += offY; + // Add children to queue to be visited + queue[++end] = children[i]; + } + + // Reset parent offsets + node.offsetX = 0; + node.offsetY = 0; + } + } + }; + + /** + * @brief : Updates the layout model positions, based on + * the accumulated forces + */ + var updatePositions = function updatePositions(layoutInfo, options) { + // var s = 'Updating positions'; + // logDebug(s); + + // Reset boundaries for compound nodes + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + if (0 < n.children.length) { + // logDebug("Resetting boundaries of compound node: " + n.id); + n.maxX = undefined; + n.minX = undefined; + n.maxY = undefined; + n.minY = undefined; + } + } + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + if (0 < n.children.length || n.isLocked) { + // No need to set compound or locked node position + // logDebug("Skipping position update of node: " + n.id); + continue; + } + // s = "Node: " + n.id + " Previous position: (" + + // n.positionX + ", " + n.positionY + ")."; + + // Limit displacement in order to improve stability + var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature); + n.positionX += tempForce.x; + n.positionY += tempForce.y; + n.offsetX = 0; + n.offsetY = 0; + n.minX = n.positionX - n.width; + n.maxX = n.positionX + n.width; + n.minY = n.positionY - n.height; + n.maxY = n.positionY + n.height; + // s += " New Position: (" + n.positionX + ", " + n.positionY + ")."; + // logDebug(s); + + // Update ancestry boudaries + updateAncestryBoundaries(n, layoutInfo); + } + + // Update size, position of compund nodes + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + if (0 < n.children.length && !n.isLocked) { + n.positionX = (n.maxX + n.minX) / 2; + n.positionY = (n.maxY + n.minY) / 2; + n.width = n.maxX - n.minX; + n.height = n.maxY - n.minY; + // s = "Updating position, size of compound node " + n.id; + // s += "\nPositionX: " + n.positionX + ", PositionY: " + n.positionY; + // s += "\nWidth: " + n.width + ", Height: " + n.height; + // logDebug(s); + } + } + }; + + /** + * @brief : Limits a force (forceX, forceY) to be not + * greater (in modulo) than max. + 8 Preserves force direction. + */ + var limitForce = function limitForce(forceX, forceY, max) { + // var s = "Limiting force: (" + forceX + ", " + forceY + "). Max: " + max; + var force = Math.sqrt(forceX * forceX + forceY * forceY); + if (force > max) { + var res = { + x: max * forceX / force, + y: max * forceY / force + }; + } else { + var res = { + x: forceX, + y: forceY + }; + } + + // s += ".\nResult: (" + res.x + ", " + res.y + ")"; + // logDebug(s); + + return res; + }; + + /** + * @brief : Function used for keeping track of compound node + * sizes, since they should bound all their subnodes. + */ + var updateAncestryBoundaries = function updateAncestryBoundaries(node, layoutInfo) { + // var s = "Propagating new position/size of node " + node.id; + var parentId = node.parentId; + if (null == parentId) { + // If there's no parent, we are done + // s += ". No parent node."; + // logDebug(s); + return; + } + + // Get Parent Node + var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]]; + var flag = false; + + // MaxX + if (null == p.maxX || node.maxX + p.padRight > p.maxX) { + p.maxX = node.maxX + p.padRight; + flag = true; + // s += "\nNew maxX for parent node " + p.id + ": " + p.maxX; + } + + // MinX + if (null == p.minX || node.minX - p.padLeft < p.minX) { + p.minX = node.minX - p.padLeft; + flag = true; + // s += "\nNew minX for parent node " + p.id + ": " + p.minX; + } + + // MaxY + if (null == p.maxY || node.maxY + p.padBottom > p.maxY) { + p.maxY = node.maxY + p.padBottom; + flag = true; + // s += "\nNew maxY for parent node " + p.id + ": " + p.maxY; + } + + // MinY + if (null == p.minY || node.minY - p.padTop < p.minY) { + p.minY = node.minY - p.padTop; + flag = true; + // s += "\nNew minY for parent node " + p.id + ": " + p.minY; + } + + // If updated boundaries, propagate changes upward + if (flag) { + // logDebug(s); + return updateAncestryBoundaries(p, layoutInfo); + } + + // s += ". No changes in boundaries/position of parent node " + p.id; + // logDebug(s); + return; + }; + var separateComponents = function separateComponents(layoutInfo, options) { + var nodes = layoutInfo.layoutNodes; + var components = []; + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var cid = node.cmptId; + var component = components[cid] = components[cid] || []; + component.push(node); + } + var totalA = 0; + for (var i = 0; i < components.length; i++) { + var c = components[i]; + if (!c) { + continue; + } + c.x1 = Infinity; + c.x2 = -Infinity; + c.y1 = Infinity; + c.y2 = -Infinity; + for (var j = 0; j < c.length; j++) { + var n = c[j]; + c.x1 = Math.min(c.x1, n.positionX - n.width / 2); + c.x2 = Math.max(c.x2, n.positionX + n.width / 2); + c.y1 = Math.min(c.y1, n.positionY - n.height / 2); + c.y2 = Math.max(c.y2, n.positionY + n.height / 2); + } + c.w = c.x2 - c.x1; + c.h = c.y2 - c.y1; + totalA += c.w * c.h; + } + components.sort(function (c1, c2) { + return c2.w * c2.h - c1.w * c1.h; + }); + var x = 0; + var y = 0; + var usedW = 0; + var rowH = 0; + var maxRowW = Math.sqrt(totalA) * layoutInfo.clientWidth / layoutInfo.clientHeight; + for (var i = 0; i < components.length; i++) { + var c = components[i]; + if (!c) { + continue; + } + for (var j = 0; j < c.length; j++) { + var n = c[j]; + if (!n.isLocked) { + n.positionX += x - c.x1; + n.positionY += y - c.y1; + } + } + x += c.w + options.componentSpacing; + usedW += c.w + options.componentSpacing; + rowH = Math.max(rowH, c.h); + if (usedW > maxRowW) { + y += rowH + options.componentSpacing; + x = 0; + usedW = 0; + rowH = 0; + } + } + }; + + var defaults$3 = { + fit: true, + // whether to fit the viewport to the graph + padding: 30, + // padding used on fit + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + avoidOverlap: true, + // prevents node overlap, may overflow boundingBox if not enough space + avoidOverlapPadding: 10, + // extra spacing around nodes when avoidOverlap: true + nodeDimensionsIncludeLabels: false, + // Excludes the label when calculating node bounding boxes for the layout algorithm + spacingFactor: undefined, + // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up + condense: false, + // uses all available space on false, uses minimal space on true + rows: undefined, + // force num of rows in the grid + cols: undefined, + // force num of columns in the grid + position: function position(node) {}, + // returns { row, col } for element + sort: undefined, + // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') } + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts + }; + + function GridLayout(options) { + this.options = extend({}, defaults$3, options); + } + GridLayout.prototype.run = function () { + var params = this.options; + var options = params; + var cy = params.cy; + var eles = options.eles; + var nodes = eles.nodes().not(':parent'); + if (options.sort) { + nodes = nodes.sort(options.sort); + } + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + if (bb.h === 0 || bb.w === 0) { + eles.nodes().layoutPositions(this, options, function (ele) { + return { + x: bb.x1, + y: bb.y1 + }; + }); + } else { + // width/height * splits^2 = cells where splits is number of times to split width + var cells = nodes.size(); + var splits = Math.sqrt(cells * bb.h / bb.w); + var rows = Math.round(splits); + var cols = Math.round(bb.w / bb.h * splits); + var small = function small(val) { + if (val == null) { + return Math.min(rows, cols); + } else { + var min = Math.min(rows, cols); + if (min == rows) { + rows = val; + } else { + cols = val; + } + } + }; + var large = function large(val) { + if (val == null) { + return Math.max(rows, cols); + } else { + var max = Math.max(rows, cols); + if (max == rows) { + rows = val; + } else { + cols = val; + } + } + }; + var oRows = options.rows; + var oCols = options.cols != null ? options.cols : options.columns; + + // if rows or columns were set in options, use those values + if (oRows != null && oCols != null) { + rows = oRows; + cols = oCols; + } else if (oRows != null && oCols == null) { + rows = oRows; + cols = Math.ceil(cells / rows); + } else if (oRows == null && oCols != null) { + cols = oCols; + rows = Math.ceil(cells / cols); + } + + // otherwise use the automatic values and adjust accordingly + + // if rounding was up, see if we can reduce rows or columns + else if (cols * rows > cells) { + var sm = small(); + var lg = large(); + + // reducing the small side takes away the most cells, so try it first + if ((sm - 1) * lg >= cells) { + small(sm - 1); + } else if ((lg - 1) * sm >= cells) { + large(lg - 1); + } + } else { + // if rounding was too low, add rows or columns + while (cols * rows < cells) { + var _sm = small(); + var _lg = large(); + + // try to add to larger side first (adds less in multiplication) + if ((_lg + 1) * _sm >= cells) { + large(_lg + 1); + } else { + small(_sm + 1); + } + } + } + var cellWidth = bb.w / cols; + var cellHeight = bb.h / rows; + if (options.condense) { + cellWidth = 0; + cellHeight = 0; + } + if (options.avoidOverlap) { + for (var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var pos = node._private.position; + if (pos.x == null || pos.y == null) { + // for bb + pos.x = 0; + pos.y = 0; + } + var nbb = node.layoutDimensions(options); + var p = options.avoidOverlapPadding; + var w = nbb.w + p; + var h = nbb.h + p; + cellWidth = Math.max(cellWidth, w); + cellHeight = Math.max(cellHeight, h); + } + } + var cellUsed = {}; // e.g. 'c-0-2' => true + + var used = function used(row, col) { + return cellUsed['c-' + row + '-' + col] ? true : false; + }; + var use = function use(row, col) { + cellUsed['c-' + row + '-' + col] = true; + }; + + // to keep track of current cell position + var row = 0; + var col = 0; + var moveToNextCell = function moveToNextCell() { + col++; + if (col >= cols) { + col = 0; + row++; + } + }; + + // get a cache of all the manual positions + var id2manPos = {}; + for (var _i = 0; _i < nodes.length; _i++) { + var _node = nodes[_i]; + var rcPos = options.position(_node); + if (rcPos && (rcPos.row !== undefined || rcPos.col !== undefined)) { + // must have at least row or col def'd + var _pos = { + row: rcPos.row, + col: rcPos.col + }; + if (_pos.col === undefined) { + // find unused col + _pos.col = 0; + while (used(_pos.row, _pos.col)) { + _pos.col++; + } + } else if (_pos.row === undefined) { + // find unused row + _pos.row = 0; + while (used(_pos.row, _pos.col)) { + _pos.row++; + } + } + id2manPos[_node.id()] = _pos; + use(_pos.row, _pos.col); + } + } + var getPos = function getPos(element, i) { + var x, y; + if (element.locked() || element.isParent()) { + return false; + } + + // see if we have a manual position set + var rcPos = id2manPos[element.id()]; + if (rcPos) { + x = rcPos.col * cellWidth + cellWidth / 2 + bb.x1; + y = rcPos.row * cellHeight + cellHeight / 2 + bb.y1; + } else { + // otherwise set automatically + + while (used(row, col)) { + moveToNextCell(); + } + x = col * cellWidth + cellWidth / 2 + bb.x1; + y = row * cellHeight + cellHeight / 2 + bb.y1; + use(row, col); + moveToNextCell(); + } + return { + x: x, + y: y + }; + }; + nodes.layoutPositions(this, options, getPos); + } + return this; // chaining + }; + + // default layout options + var defaults$2 = { + ready: function ready() {}, + // on layoutready + stop: function stop() {} // on layoutstop + }; + + // constructor + // options : object containing layout options + function NullLayout(options) { + this.options = extend({}, defaults$2, options); + } + + // runs the layout + NullLayout.prototype.run = function () { + var options = this.options; + var eles = options.eles; // elements to consider in the layout + var layout = this; + + // cy is automatically populated for us in the constructor + // (disable eslint for next line as this serves as example layout code to external developers) + // eslint-disable-next-line no-unused-vars + options.cy; + layout.emit('layoutstart'); + + // puts all nodes at (0, 0) + // n.b. most layouts would use layoutPositions(), instead of positions() and manual events + eles.nodes().positions(function () { + return { + x: 0, + y: 0 + }; + }); + + // trigger layoutready when each node has had its position set at least once + layout.one('layoutready', options.ready); + layout.emit('layoutready'); + + // trigger layoutstop when the layout stops (e.g. finishes) + layout.one('layoutstop', options.stop); + layout.emit('layoutstop'); + return this; // chaining + }; + + // called on continuous layouts to stop them before they finish + NullLayout.prototype.stop = function () { + return this; // chaining + }; + + var defaults$1 = { + positions: undefined, + // map of (node id) => (position obj); or function(node){ return somPos; } + zoom: undefined, + // the zoom level to set (prob want fit = false if set) + pan: undefined, + // the pan level to set (prob want fit = false if set) + fit: true, + // whether to fit to viewport + padding: 30, + // padding on fit + spacingFactor: undefined, + // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts + }; + + function PresetLayout(options) { + this.options = extend({}, defaults$1, options); + } + PresetLayout.prototype.run = function () { + var options = this.options; + var eles = options.eles; + var nodes = eles.nodes(); + var posIsFn = fn$6(options.positions); + function getPosition(node) { + if (options.positions == null) { + return copyPosition(node.position()); + } + if (posIsFn) { + return options.positions(node); + } + var pos = options.positions[node._private.data.id]; + if (pos == null) { + return null; + } + return pos; + } + nodes.layoutPositions(this, options, function (node, i) { + var position = getPosition(node); + if (node.locked() || position == null) { + return false; + } + return position; + }); + return this; // chaining + }; + + var defaults = { + fit: true, + // whether to fit to viewport + padding: 30, + // fit padding + boundingBox: undefined, + // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } + animate: false, + // whether to transition the node positions + animationDuration: 500, + // duration of animation in ms if enabled + animationEasing: undefined, + // easing of animation if enabled + animateFilter: function animateFilter(node, i) { + return true; + }, + // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts + ready: undefined, + // callback on layoutready + stop: undefined, + // callback on layoutstop + transform: function transform(node, position) { + return position; + } // transform a given node position. Useful for changing flow direction in discrete layouts + }; + + function RandomLayout(options) { + this.options = extend({}, defaults, options); + } + RandomLayout.prototype.run = function () { + var options = this.options; + var cy = options.cy; + var eles = options.eles; + var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : { + x1: 0, + y1: 0, + w: cy.width(), + h: cy.height() + }); + var getPos = function getPos(node, i) { + return { + x: bb.x1 + Math.round(Math.random() * bb.w), + y: bb.y1 + Math.round(Math.random() * bb.h) + }; + }; + eles.nodes().layoutPositions(this, options, getPos); + return this; // chaining + }; + + var layout = [{ + name: 'breadthfirst', + impl: BreadthFirstLayout + }, { + name: 'circle', + impl: CircleLayout + }, { + name: 'concentric', + impl: ConcentricLayout + }, { + name: 'cose', + impl: CoseLayout + }, { + name: 'grid', + impl: GridLayout + }, { + name: 'null', + impl: NullLayout + }, { + name: 'preset', + impl: PresetLayout + }, { + name: 'random', + impl: RandomLayout + }]; + + function NullRenderer(options) { + this.options = options; + this.notifications = 0; // for testing + } + + var noop = function noop() {}; + var throwImgErr = function throwImgErr() { + throw new Error('A headless instance can not render images'); + }; + NullRenderer.prototype = { + recalculateRenderedStyle: noop, + notify: function notify() { + this.notifications++; + }, + init: noop, + isHeadless: function isHeadless() { + return true; + }, + png: throwImgErr, + jpg: throwImgErr + }; + + var BRp$f = {}; + BRp$f.arrowShapeWidth = 0.3; + BRp$f.registerArrowShapes = function () { + var arrowShapes = this.arrowShapes = {}; + var renderer = this; + + // Contract for arrow shapes: + // 0, 0 is arrow tip + // (0, 1) is direction towards node + // (1, 0) is right + // + // functional api: + // collide: check x, y in shape + // roughCollide: called before collide, no false negatives + // draw: draw + // spacing: dist(arrowTip, nodeBoundary) + // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip + + var bbCollide = function bbCollide(x, y, size, angle, translation, edgeWidth, padding) { + var x1 = translation.x - size / 2 - padding; + var x2 = translation.x + size / 2 + padding; + var y1 = translation.y - size / 2 - padding; + var y2 = translation.y + size / 2 + padding; + var inside = x1 <= x && x <= x2 && y1 <= y && y <= y2; + return inside; + }; + var transform = function transform(x, y, size, angle, translation) { + var xRotated = x * Math.cos(angle) - y * Math.sin(angle); + var yRotated = x * Math.sin(angle) + y * Math.cos(angle); + var xScaled = xRotated * size; + var yScaled = yRotated * size; + var xTranslated = xScaled + translation.x; + var yTranslated = yScaled + translation.y; + return { + x: xTranslated, + y: yTranslated + }; + }; + var transformPoints = function transformPoints(pts, size, angle, translation) { + var retPts = []; + for (var i = 0; i < pts.length; i += 2) { + var x = pts[i]; + var y = pts[i + 1]; + retPts.push(transform(x, y, size, angle, translation)); + } + return retPts; + }; + var pointsToArr = function pointsToArr(pts) { + var ret = []; + for (var i = 0; i < pts.length; i++) { + var p = pts[i]; + ret.push(p.x, p.y); + } + return ret; + }; + var standardGap = function standardGap(edge) { + return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').pfValue * 2; + }; + var defineArrowShape = function defineArrowShape(name, defn) { + if (string(defn)) { + defn = arrowShapes[defn]; + } + arrowShapes[name] = extend({ + name: name, + points: [-0.15, -0.3, 0.15, -0.3, 0.15, 0.3, -0.15, 0.3], + collide: function collide(x, y, size, angle, translation, padding) { + var points = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation)); + var inside = pointInsidePolygonPoints(x, y, points); + return inside; + }, + roughCollide: bbCollide, + draw: function draw(context, size, angle, translation) { + var points = transformPoints(this.points, size, angle, translation); + renderer.arrowShapeImpl('polygon')(context, points); + }, + spacing: function spacing(edge) { + return 0; + }, + gap: standardGap + }, defn); + }; + defineArrowShape('none', { + collide: falsify, + roughCollide: falsify, + draw: noop$1, + spacing: zeroify, + gap: zeroify + }); + defineArrowShape('triangle', { + points: [-0.15, -0.3, 0, 0, 0.15, -0.3] + }); + defineArrowShape('arrow', 'triangle'); + defineArrowShape('triangle-backcurve', { + points: arrowShapes['triangle'].points, + controlPoint: [0, -0.15], + roughCollide: bbCollide, + draw: function draw(context, size, angle, translation, edgeWidth) { + var ptsTrans = transformPoints(this.points, size, angle, translation); + var ctrlPt = this.controlPoint; + var ctrlPtTrans = transform(ctrlPt[0], ctrlPt[1], size, angle, translation); + renderer.arrowShapeImpl(this.name)(context, ptsTrans, ctrlPtTrans); + }, + gap: function gap(edge) { + return standardGap(edge) * 0.8; + } + }); + defineArrowShape('triangle-tee', { + points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0], + pointsTee: [-0.15, -0.4, -0.15, -0.5, 0.15, -0.5, 0.15, -0.4], + collide: function collide(x, y, size, angle, translation, edgeWidth, padding) { + var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation)); + var teePts = pointsToArr(transformPoints(this.pointsTee, size + 2 * padding, angle, translation)); + var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts); + return inside; + }, + draw: function draw(context, size, angle, translation, edgeWidth) { + var triPts = transformPoints(this.points, size, angle, translation); + var teePts = transformPoints(this.pointsTee, size, angle, translation); + renderer.arrowShapeImpl(this.name)(context, triPts, teePts); + } + }); + defineArrowShape('circle-triangle', { + radius: 0.15, + pointsTr: [0, -0.15, 0.15, -0.45, -0.15, -0.45, 0, -0.15], + collide: function collide(x, y, size, angle, translation, edgeWidth, padding) { + var t = translation; + var circleInside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2); + var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation)); + return pointInsidePolygonPoints(x, y, triPts) || circleInside; + }, + draw: function draw(context, size, angle, translation, edgeWidth) { + var triPts = transformPoints(this.pointsTr, size, angle, translation); + renderer.arrowShapeImpl(this.name)(context, triPts, translation.x, translation.y, this.radius * size); + }, + spacing: function spacing(edge) { + return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius; + } + }); + defineArrowShape('triangle-cross', { + points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0], + baseCrossLinePts: [-0.15, -0.4, + // first half of the rectangle + -0.15, -0.4, 0.15, -0.4, + // second half of the rectangle + 0.15, -0.4], + crossLinePts: function crossLinePts(size, edgeWidth) { + // shift points so that the distance between the cross points matches edge width + var p = this.baseCrossLinePts.slice(); + var shiftFactor = edgeWidth / size; + var y0 = 3; + var y1 = 5; + p[y0] = p[y0] - shiftFactor; + p[y1] = p[y1] - shiftFactor; + return p; + }, + collide: function collide(x, y, size, angle, translation, edgeWidth, padding) { + var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation)); + var teePts = pointsToArr(transformPoints(this.crossLinePts(size, edgeWidth), size + 2 * padding, angle, translation)); + var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts); + return inside; + }, + draw: function draw(context, size, angle, translation, edgeWidth) { + var triPts = transformPoints(this.points, size, angle, translation); + var crossLinePts = transformPoints(this.crossLinePts(size, edgeWidth), size, angle, translation); + renderer.arrowShapeImpl(this.name)(context, triPts, crossLinePts); + } + }); + defineArrowShape('vee', { + points: [-0.15, -0.3, 0, 0, 0.15, -0.3, 0, -0.15], + gap: function gap(edge) { + return standardGap(edge) * 0.525; + } + }); + defineArrowShape('circle', { + radius: 0.15, + collide: function collide(x, y, size, angle, translation, edgeWidth, padding) { + var t = translation; + var inside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2); + return inside; + }, + draw: function draw(context, size, angle, translation, edgeWidth) { + renderer.arrowShapeImpl(this.name)(context, translation.x, translation.y, this.radius * size); + }, + spacing: function spacing(edge) { + return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius; + } + }); + defineArrowShape('tee', { + points: [-0.15, 0, -0.15, -0.1, 0.15, -0.1, 0.15, 0], + spacing: function spacing(edge) { + return 1; + }, + gap: function gap(edge) { + return 1; + } + }); + defineArrowShape('square', { + points: [-0.15, 0.00, 0.15, 0.00, 0.15, -0.3, -0.15, -0.3] + }); + defineArrowShape('diamond', { + points: [-0.15, -0.15, 0, -0.3, 0.15, -0.15, 0, 0], + gap: function gap(edge) { + return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value; + } + }); + defineArrowShape('chevron', { + points: [0, 0, -0.15, -0.15, -0.1, -0.2, 0, -0.1, 0.1, -0.2, 0.15, -0.15], + gap: function gap(edge) { + return 0.95 * edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value; + } + }); + }; + + var BRp$e = {}; + + // Project mouse + BRp$e.projectIntoViewport = function (clientX, clientY) { + var cy = this.cy; + var offsets = this.findContainerClientCoords(); + var offsetLeft = offsets[0]; + var offsetTop = offsets[1]; + var scale = offsets[4]; + var pan = cy.pan(); + var zoom = cy.zoom(); + var x = ((clientX - offsetLeft) / scale - pan.x) / zoom; + var y = ((clientY - offsetTop) / scale - pan.y) / zoom; + return [x, y]; + }; + BRp$e.findContainerClientCoords = function () { + if (this.containerBB) { + return this.containerBB; + } + var container = this.container; + var rect = container.getBoundingClientRect(); + var style = this.cy.window().getComputedStyle(container); + var styleValue = function styleValue(name) { + return parseFloat(style.getPropertyValue(name)); + }; + var padding = { + left: styleValue('padding-left'), + right: styleValue('padding-right'), + top: styleValue('padding-top'), + bottom: styleValue('padding-bottom') + }; + var border = { + left: styleValue('border-left-width'), + right: styleValue('border-right-width'), + top: styleValue('border-top-width'), + bottom: styleValue('border-bottom-width') + }; + var clientWidth = container.clientWidth; + var clientHeight = container.clientHeight; + var paddingHor = padding.left + padding.right; + var paddingVer = padding.top + padding.bottom; + var borderHor = border.left + border.right; + var scale = rect.width / (clientWidth + borderHor); + var unscaledW = clientWidth - paddingHor; + var unscaledH = clientHeight - paddingVer; + var left = rect.left + padding.left + border.left; + var top = rect.top + padding.top + border.top; + return this.containerBB = [left, top, unscaledW, unscaledH, scale]; + }; + BRp$e.invalidateContainerClientCoordsCache = function () { + this.containerBB = null; + }; + BRp$e.findNearestElement = function (x, y, interactiveElementsOnly, isTouch) { + return this.findNearestElements(x, y, interactiveElementsOnly, isTouch)[0]; + }; + BRp$e.findNearestElements = function (x, y, interactiveElementsOnly, isTouch) { + var self = this; + var r = this; + var eles = r.getCachedZSortedEles(); + var near = []; // 1 node max, 1 edge max + var zoom = r.cy.zoom(); + var hasCompounds = r.cy.hasCompoundNodes(); + var edgeThreshold = (isTouch ? 24 : 8) / zoom; + var nodeThreshold = (isTouch ? 8 : 2) / zoom; + var labelThreshold = (isTouch ? 8 : 2) / zoom; + var minSqDist = Infinity; + var nearEdge; + var nearNode; + if (interactiveElementsOnly) { + eles = eles.interactive; + } + function addEle(ele, sqDist) { + if (ele.isNode()) { + if (nearNode) { + return; // can't replace node + } else { + nearNode = ele; + near.push(ele); + } + } + if (ele.isEdge() && (sqDist == null || sqDist < minSqDist)) { + if (nearEdge) { + // then replace existing edge + // can replace only if same z-index + if (nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value && nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value) { + for (var i = 0; i < near.length; i++) { + if (near[i].isEdge()) { + near[i] = ele; + nearEdge = ele; + minSqDist = sqDist != null ? sqDist : minSqDist; + break; + } + } + } + } else { + near.push(ele); + nearEdge = ele; + minSqDist = sqDist != null ? sqDist : minSqDist; + } + } + } + function checkNode(node) { + var width = node.outerWidth() + 2 * nodeThreshold; + var height = node.outerHeight() + 2 * nodeThreshold; + var hw = width / 2; + var hh = height / 2; + var pos = node.position(); + if (pos.x - hw <= x && x <= pos.x + hw // bb check x + && pos.y - hh <= y && y <= pos.y + hh // bb check y + ) { + var shape = r.nodeShapes[self.getNodeShape(node)]; + if (shape.checkPoint(x, y, 0, width, height, pos.x, pos.y)) { + addEle(node, 0); + return true; + } + } + } + function checkEdge(edge) { + var _p = edge._private; + var rs = _p.rscratch; + var styleWidth = edge.pstyle('width').pfValue; + var scale = edge.pstyle('arrow-scale').value; + var width = styleWidth / 2 + edgeThreshold; // more like a distance radius from centre + var widthSq = width * width; + var width2 = width * 2; + var src = _p.source; + var tgt = _p.target; + var sqDist; + if (rs.edgeType === 'segments' || rs.edgeType === 'straight' || rs.edgeType === 'haystack') { + var pts = rs.allpts; + for (var i = 0; i + 3 < pts.length; i += 2) { + if (inLineVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], width2) && widthSq > (sqDist = sqdistToFiniteLine(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3]))) { + addEle(edge, sqDist); + return true; + } + } + } else if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') { + var pts = rs.allpts; + for (var i = 0; i + 5 < rs.allpts.length; i += 4) { + if (inBezierVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], width2) && widthSq > (sqDist = sqdistToQuadraticBezier(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5]))) { + addEle(edge, sqDist); + return true; + } + } + } + + // if we're close to the edge but didn't hit it, maybe we hit its arrows + + var src = src || _p.source; + var tgt = tgt || _p.target; + var arSize = self.getArrowWidth(styleWidth, scale); + var arrows = [{ + name: 'source', + x: rs.arrowStartX, + y: rs.arrowStartY, + angle: rs.srcArrowAngle + }, { + name: 'target', + x: rs.arrowEndX, + y: rs.arrowEndY, + angle: rs.tgtArrowAngle + }, { + name: 'mid-source', + x: rs.midX, + y: rs.midY, + angle: rs.midsrcArrowAngle + }, { + name: 'mid-target', + x: rs.midX, + y: rs.midY, + angle: rs.midtgtArrowAngle + }]; + for (var i = 0; i < arrows.length; i++) { + var ar = arrows[i]; + var shape = r.arrowShapes[edge.pstyle(ar.name + '-arrow-shape').value]; + var edgeWidth = edge.pstyle('width').pfValue; + if (shape.roughCollide(x, y, arSize, ar.angle, { + x: ar.x, + y: ar.y + }, edgeWidth, edgeThreshold) && shape.collide(x, y, arSize, ar.angle, { + x: ar.x, + y: ar.y + }, edgeWidth, edgeThreshold)) { + addEle(edge); + return true; + } + } + + // for compound graphs, hitting edge may actually want a connected node instead (b/c edge may have greater z-index precedence) + if (hasCompounds && near.length > 0) { + checkNode(src); + checkNode(tgt); + } + } + function preprop(obj, name, pre) { + return getPrefixedProperty(obj, name, pre); + } + function checkLabel(ele, prefix) { + var _p = ele._private; + var th = labelThreshold; + var prefixDash; + if (prefix) { + prefixDash = prefix + '-'; + } else { + prefixDash = ''; + } + ele.boundingBox(); + var bb = _p.labelBounds[prefix || 'main']; + var text = ele.pstyle(prefixDash + 'label').value; + var eventsEnabled = ele.pstyle('text-events').strValue === 'yes'; + if (!eventsEnabled || !text) { + return; + } + var lx = preprop(_p.rscratch, 'labelX', prefix); + var ly = preprop(_p.rscratch, 'labelY', prefix); + var theta = preprop(_p.rscratch, 'labelAngle', prefix); + var ox = ele.pstyle(prefixDash + 'text-margin-x').pfValue; + var oy = ele.pstyle(prefixDash + 'text-margin-y').pfValue; + var lx1 = bb.x1 - th - ox; // (-ox, -oy) as bb already includes margin + var lx2 = bb.x2 + th - ox; // and rotation is about (lx, ly) + var ly1 = bb.y1 - th - oy; + var ly2 = bb.y2 + th - oy; + if (theta) { + var cos = Math.cos(theta); + var sin = Math.sin(theta); + var rotate = function rotate(x, y) { + x = x - lx; + y = y - ly; + return { + x: x * cos - y * sin + lx, + y: x * sin + y * cos + ly + }; + }; + var px1y1 = rotate(lx1, ly1); + var px1y2 = rotate(lx1, ly2); + var px2y1 = rotate(lx2, ly1); + var px2y2 = rotate(lx2, ly2); + var points = [ + // with the margin added after the rotation is applied + px1y1.x + ox, px1y1.y + oy, px2y1.x + ox, px2y1.y + oy, px2y2.x + ox, px2y2.y + oy, px1y2.x + ox, px1y2.y + oy]; + if (pointInsidePolygonPoints(x, y, points)) { + addEle(ele); + return true; + } + } else { + // do a cheaper bb check + if (inBoundingBox(bb, x, y)) { + addEle(ele); + return true; + } + } + } + for (var i = eles.length - 1; i >= 0; i--) { + // reverse order for precedence + var ele = eles[i]; + if (ele.isNode()) { + checkNode(ele) || checkLabel(ele); + } else { + // then edge + checkEdge(ele) || checkLabel(ele) || checkLabel(ele, 'source') || checkLabel(ele, 'target'); + } + } + return near; + }; + + // 'Give me everything from this box' + BRp$e.getAllInBox = function (x1, y1, x2, y2) { + var eles = this.getCachedZSortedEles().interactive; + var box = []; + var x1c = Math.min(x1, x2); + var x2c = Math.max(x1, x2); + var y1c = Math.min(y1, y2); + var y2c = Math.max(y1, y2); + x1 = x1c; + x2 = x2c; + y1 = y1c; + y2 = y2c; + var boxBb = makeBoundingBox({ + x1: x1, + y1: y1, + x2: x2, + y2: y2 + }); + for (var e = 0; e < eles.length; e++) { + var ele = eles[e]; + if (ele.isNode()) { + var node = ele; + var nodeBb = node.boundingBox({ + includeNodes: true, + includeEdges: false, + includeLabels: false + }); + if (boundingBoxesIntersect(boxBb, nodeBb) && !boundingBoxInBoundingBox(nodeBb, boxBb)) { + box.push(node); + } + } else { + var edge = ele; + var _p = edge._private; + var rs = _p.rscratch; + if (rs.startX != null && rs.startY != null && !inBoundingBox(boxBb, rs.startX, rs.startY)) { + continue; + } + if (rs.endX != null && rs.endY != null && !inBoundingBox(boxBb, rs.endX, rs.endY)) { + continue; + } + if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' || rs.edgeType === 'segments' || rs.edgeType === 'haystack') { + var pts = _p.rstyle.bezierPts || _p.rstyle.linePts || _p.rstyle.haystackPts; + var allInside = true; + for (var i = 0; i < pts.length; i++) { + if (!pointInBoundingBox(boxBb, pts[i])) { + allInside = false; + break; + } + } + if (allInside) { + box.push(edge); + } + } else if (rs.edgeType === 'haystack' || rs.edgeType === 'straight') { + box.push(edge); + } + } + } + return box; + }; + + var BRp$d = {}; + BRp$d.calculateArrowAngles = function (edge) { + var rs = edge._private.rscratch; + var isHaystack = rs.edgeType === 'haystack'; + var isBezier = rs.edgeType === 'bezier'; + var isMultibezier = rs.edgeType === 'multibezier'; + var isSegments = rs.edgeType === 'segments'; + var isCompound = rs.edgeType === 'compound'; + var isSelf = rs.edgeType === 'self'; + + // Displacement gives direction for arrowhead orientation + var dispX, dispY; + var startX, startY, endX, endY, midX, midY; + if (isHaystack) { + startX = rs.haystackPts[0]; + startY = rs.haystackPts[1]; + endX = rs.haystackPts[2]; + endY = rs.haystackPts[3]; + } else { + startX = rs.arrowStartX; + startY = rs.arrowStartY; + endX = rs.arrowEndX; + endY = rs.arrowEndY; + } + midX = rs.midX; + midY = rs.midY; + + // source + // + + if (isSegments) { + dispX = startX - rs.segpts[0]; + dispY = startY - rs.segpts[1]; + } else if (isMultibezier || isCompound || isSelf || isBezier) { + var pts = rs.allpts; + var bX = qbezierAt(pts[0], pts[2], pts[4], 0.1); + var bY = qbezierAt(pts[1], pts[3], pts[5], 0.1); + dispX = startX - bX; + dispY = startY - bY; + } else { + dispX = startX - midX; + dispY = startY - midY; + } + rs.srcArrowAngle = getAngleFromDisp(dispX, dispY); + + // mid target + // + + var midX = rs.midX; + var midY = rs.midY; + if (isHaystack) { + midX = (startX + endX) / 2; + midY = (startY + endY) / 2; + } + dispX = endX - startX; + dispY = endY - startY; + if (isSegments) { + var pts = rs.allpts; + if (pts.length / 2 % 2 === 0) { + var i2 = pts.length / 2; + var i1 = i2 - 2; + dispX = pts[i2] - pts[i1]; + dispY = pts[i2 + 1] - pts[i1 + 1]; + } else { + var i2 = pts.length / 2 - 1; + var i1 = i2 - 2; + var i3 = i2 + 2; + dispX = pts[i2] - pts[i1]; + dispY = pts[i2 + 1] - pts[i1 + 1]; + } + } else if (isMultibezier || isCompound || isSelf) { + var pts = rs.allpts; + var cpts = rs.ctrlpts; + var bp0x, bp0y; + var bp1x, bp1y; + if (cpts.length / 2 % 2 === 0) { + var p0 = pts.length / 2 - 1; // startpt + var ic = p0 + 2; + var p1 = ic + 2; + bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0); + bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0); + bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0001); + bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0001); + } else { + var ic = pts.length / 2 - 1; // ctrpt + var p0 = ic - 2; // startpt + var p1 = ic + 2; // endpt + + bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.4999); + bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.4999); + bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.5); + bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.5); + } + dispX = bp1x - bp0x; + dispY = bp1y - bp0y; + } + rs.midtgtArrowAngle = getAngleFromDisp(dispX, dispY); + rs.midDispX = dispX; + rs.midDispY = dispY; + + // mid source + // + + dispX *= -1; + dispY *= -1; + if (isSegments) { + var pts = rs.allpts; + if (pts.length / 2 % 2 === 0) ; else { + var i2 = pts.length / 2 - 1; + var i3 = i2 + 2; + dispX = -(pts[i3] - pts[i2]); + dispY = -(pts[i3 + 1] - pts[i2 + 1]); + } + } + rs.midsrcArrowAngle = getAngleFromDisp(dispX, dispY); + + // target + // + + if (isSegments) { + dispX = endX - rs.segpts[rs.segpts.length - 2]; + dispY = endY - rs.segpts[rs.segpts.length - 1]; + } else if (isMultibezier || isCompound || isSelf || isBezier) { + var pts = rs.allpts; + var l = pts.length; + var bX = qbezierAt(pts[l - 6], pts[l - 4], pts[l - 2], 0.9); + var bY = qbezierAt(pts[l - 5], pts[l - 3], pts[l - 1], 0.9); + dispX = endX - bX; + dispY = endY - bY; + } else { + dispX = endX - midX; + dispY = endY - midY; + } + rs.tgtArrowAngle = getAngleFromDisp(dispX, dispY); + }; + BRp$d.getArrowWidth = BRp$d.getArrowHeight = function (edgeWidth, scale) { + var cache = this.arrowWidthCache = this.arrowWidthCache || {}; + var cachedVal = cache[edgeWidth + ', ' + scale]; + if (cachedVal) { + return cachedVal; + } + cachedVal = Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29) * scale; + cache[edgeWidth + ', ' + scale] = cachedVal; + return cachedVal; + }; + + var BRp$c = {}; + BRp$c.findMidptPtsEtc = function (edge, pairInfo) { + var posPts = pairInfo.posPts, + intersectionPts = pairInfo.intersectionPts, + vectorNormInverse = pairInfo.vectorNormInverse; + var midptPts; + + // n.b. assumes all edges in bezier bundle have same endpoints specified + var srcManEndpt = edge.pstyle('source-endpoint'); + var tgtManEndpt = edge.pstyle('target-endpoint'); + var haveManualEndPts = srcManEndpt.units != null && tgtManEndpt.units != null; + var recalcVectorNormInverse = function recalcVectorNormInverse(x1, y1, x2, y2) { + var dy = y2 - y1; + var dx = x2 - x1; + var l = Math.sqrt(dx * dx + dy * dy); + return { + x: -dy / l, + y: dx / l + }; + }; + var edgeDistances = edge.pstyle('edge-distances').value; + switch (edgeDistances) { + case 'node-position': + midptPts = posPts; + break; + case 'intersection': + midptPts = intersectionPts; + break; + case 'endpoints': + { + if (haveManualEndPts) { + var _this$manualEndptToPx = this.manualEndptToPx(edge.source()[0], srcManEndpt), + _this$manualEndptToPx2 = _slicedToArray(_this$manualEndptToPx, 2), + x1 = _this$manualEndptToPx2[0], + y1 = _this$manualEndptToPx2[1]; + var _this$manualEndptToPx3 = this.manualEndptToPx(edge.target()[0], tgtManEndpt), + _this$manualEndptToPx4 = _slicedToArray(_this$manualEndptToPx3, 2), + x2 = _this$manualEndptToPx4[0], + y2 = _this$manualEndptToPx4[1]; + var endPts = { + x1: x1, + y1: y1, + x2: x2, + y2: y2 + }; + vectorNormInverse = recalcVectorNormInverse(x1, y1, x2, y2); + midptPts = endPts; + } else { + warn("Edge ".concat(edge.id(), " has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).")); + midptPts = intersectionPts; // back to default + } + + break; + } + } + return { + midptPts: midptPts, + vectorNormInverse: vectorNormInverse + }; + }; + BRp$c.findHaystackPoints = function (edges) { + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + var _p = edge._private; + var rs = _p.rscratch; + if (!rs.haystack) { + var angle = Math.random() * 2 * Math.PI; + rs.source = { + x: Math.cos(angle), + y: Math.sin(angle) + }; + angle = Math.random() * 2 * Math.PI; + rs.target = { + x: Math.cos(angle), + y: Math.sin(angle) + }; + } + var src = _p.source; + var tgt = _p.target; + var srcPos = src.position(); + var tgtPos = tgt.position(); + var srcW = src.width(); + var tgtW = tgt.width(); + var srcH = src.height(); + var tgtH = tgt.height(); + var radius = edge.pstyle('haystack-radius').value; + var halfRadius = radius / 2; // b/c have to half width/height + + rs.haystackPts = rs.allpts = [rs.source.x * srcW * halfRadius + srcPos.x, rs.source.y * srcH * halfRadius + srcPos.y, rs.target.x * tgtW * halfRadius + tgtPos.x, rs.target.y * tgtH * halfRadius + tgtPos.y]; + rs.midX = (rs.allpts[0] + rs.allpts[2]) / 2; + rs.midY = (rs.allpts[1] + rs.allpts[3]) / 2; + + // always override as haystack in case set to different type previously + rs.edgeType = 'haystack'; + rs.haystack = true; + this.storeEdgeProjections(edge); + this.calculateArrowAngles(edge); + this.recalculateEdgeLabelProjections(edge); + this.calculateLabelAngles(edge); + } + }; + BRp$c.findSegmentsPoints = function (edge, pairInfo) { + // Segments (multiple straight lines) + + var rs = edge._private.rscratch; + var segmentWs = edge.pstyle('segment-weights'); + var segmentDs = edge.pstyle('segment-distances'); + var segmentsN = Math.min(segmentWs.pfValue.length, segmentDs.pfValue.length); + rs.edgeType = 'segments'; + rs.segpts = []; + for (var s = 0; s < segmentsN; s++) { + var w = segmentWs.pfValue[s]; + var d = segmentDs.pfValue[s]; + var w1 = 1 - w; + var w2 = w; + var _this$findMidptPtsEtc = this.findMidptPtsEtc(edge, pairInfo), + midptPts = _this$findMidptPtsEtc.midptPts, + vectorNormInverse = _this$findMidptPtsEtc.vectorNormInverse; + var adjustedMidpt = { + x: midptPts.x1 * w1 + midptPts.x2 * w2, + y: midptPts.y1 * w1 + midptPts.y2 * w2 + }; + rs.segpts.push(adjustedMidpt.x + vectorNormInverse.x * d, adjustedMidpt.y + vectorNormInverse.y * d); + } + }; + BRp$c.findLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) { + // Self-edge + + var rs = edge._private.rscratch; + var dirCounts = pairInfo.dirCounts, + srcPos = pairInfo.srcPos; + var ctrlptDists = edge.pstyle('control-point-distances'); + var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined; + var loopDir = edge.pstyle('loop-direction').pfValue; + var loopSwp = edge.pstyle('loop-sweep').pfValue; + var stepSize = edge.pstyle('control-point-step-size').pfValue; + rs.edgeType = 'self'; + var j = i; + var loopDist = stepSize; + if (edgeIsUnbundled) { + j = 0; + loopDist = ctrlptDist; + } + var loopAngle = loopDir - Math.PI / 2; + var outAngle = loopAngle - loopSwp / 2; + var inAngle = loopAngle + loopSwp / 2; + + // increase by step size for overlapping loops, keyed on direction and sweep values + var dc = String(loopDir + '_' + loopSwp); + j = dirCounts[dc] === undefined ? dirCounts[dc] = 0 : ++dirCounts[dc]; + rs.ctrlpts = [srcPos.x + Math.cos(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.x + Math.cos(inAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(inAngle) * 1.4 * loopDist * (j / 3 + 1)]; + }; + BRp$c.findCompoundLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) { + // Compound edge + + var rs = edge._private.rscratch; + rs.edgeType = 'compound'; + var srcPos = pairInfo.srcPos, + tgtPos = pairInfo.tgtPos, + srcW = pairInfo.srcW, + srcH = pairInfo.srcH, + tgtW = pairInfo.tgtW, + tgtH = pairInfo.tgtH; + var stepSize = edge.pstyle('control-point-step-size').pfValue; + var ctrlptDists = edge.pstyle('control-point-distances'); + var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined; + var j = i; + var loopDist = stepSize; + if (edgeIsUnbundled) { + j = 0; + loopDist = ctrlptDist; + } + var loopW = 50; + var loopaPos = { + x: srcPos.x - srcW / 2, + y: srcPos.y - srcH / 2 + }; + var loopbPos = { + x: tgtPos.x - tgtW / 2, + y: tgtPos.y - tgtH / 2 + }; + var loopPos = { + x: Math.min(loopaPos.x, loopbPos.x), + y: Math.min(loopaPos.y, loopbPos.y) + }; + + // avoids cases with impossible beziers + var minCompoundStretch = 0.5; + var compoundStretchA = Math.max(minCompoundStretch, Math.log(srcW * 0.01)); + var compoundStretchB = Math.max(minCompoundStretch, Math.log(tgtW * 0.01)); + rs.ctrlpts = [loopPos.x, loopPos.y - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchA, loopPos.x - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchB, loopPos.y]; + }; + BRp$c.findStraightEdgePoints = function (edge) { + // Straight edge within bundle + + edge._private.rscratch.edgeType = 'straight'; + }; + BRp$c.findBezierPoints = function (edge, pairInfo, i, edgeIsUnbundled, edgeIsSwapped) { + var rs = edge._private.rscratch; + var stepSize = edge.pstyle('control-point-step-size').pfValue; + var ctrlptDists = edge.pstyle('control-point-distances'); + var ctrlptWs = edge.pstyle('control-point-weights'); + var bezierN = ctrlptDists && ctrlptWs ? Math.min(ctrlptDists.value.length, ctrlptWs.value.length) : 1; + var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined; + var ctrlptWeight = ctrlptWs.value[0]; + + // (Multi)bezier + + var multi = edgeIsUnbundled; + rs.edgeType = multi ? 'multibezier' : 'bezier'; + rs.ctrlpts = []; + for (var b = 0; b < bezierN; b++) { + var normctrlptDist = (0.5 - pairInfo.eles.length / 2 + i) * stepSize * (edgeIsSwapped ? -1 : 1); + var manctrlptDist = void 0; + var sign = signum(normctrlptDist); + if (multi) { + ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[b] : stepSize; // fall back on step size + ctrlptWeight = ctrlptWs.value[b]; + } + if (edgeIsUnbundled) { + // multi or single unbundled + manctrlptDist = ctrlptDist; + } else { + manctrlptDist = ctrlptDist !== undefined ? sign * ctrlptDist : undefined; + } + var distanceFromMidpoint = manctrlptDist !== undefined ? manctrlptDist : normctrlptDist; + var w1 = 1 - ctrlptWeight; + var w2 = ctrlptWeight; + var _this$findMidptPtsEtc2 = this.findMidptPtsEtc(edge, pairInfo), + midptPts = _this$findMidptPtsEtc2.midptPts, + vectorNormInverse = _this$findMidptPtsEtc2.vectorNormInverse; + var adjustedMidpt = { + x: midptPts.x1 * w1 + midptPts.x2 * w2, + y: midptPts.y1 * w1 + midptPts.y2 * w2 + }; + rs.ctrlpts.push(adjustedMidpt.x + vectorNormInverse.x * distanceFromMidpoint, adjustedMidpt.y + vectorNormInverse.y * distanceFromMidpoint); + } + }; + BRp$c.findTaxiPoints = function (edge, pairInfo) { + // Taxicab geometry with two turns maximum + + var rs = edge._private.rscratch; + rs.edgeType = 'segments'; + var VERTICAL = 'vertical'; + var HORIZONTAL = 'horizontal'; + var LEFTWARD = 'leftward'; + var RIGHTWARD = 'rightward'; + var DOWNWARD = 'downward'; + var UPWARD = 'upward'; + var AUTO = 'auto'; + var posPts = pairInfo.posPts, + srcW = pairInfo.srcW, + srcH = pairInfo.srcH, + tgtW = pairInfo.tgtW, + tgtH = pairInfo.tgtH; + var edgeDistances = edge.pstyle('edge-distances').value; + var dIncludesNodeBody = edgeDistances !== 'node-position'; + var taxiDir = edge.pstyle('taxi-direction').value; + var rawTaxiDir = taxiDir; // unprocessed value + var taxiTurn = edge.pstyle('taxi-turn'); + var turnIsPercent = taxiTurn.units === '%'; + var taxiTurnPfVal = taxiTurn.pfValue; + var turnIsNegative = taxiTurnPfVal < 0; // i.e. from target side + var minD = edge.pstyle('taxi-turn-min-distance').pfValue; + var dw = dIncludesNodeBody ? (srcW + tgtW) / 2 : 0; + var dh = dIncludesNodeBody ? (srcH + tgtH) / 2 : 0; + var pdx = posPts.x2 - posPts.x1; + var pdy = posPts.y2 - posPts.y1; + + // take away the effective w/h from the magnitude of the delta value + var subDWH = function subDWH(dxy, dwh) { + if (dxy > 0) { + return Math.max(dxy - dwh, 0); + } else { + return Math.min(dxy + dwh, 0); + } + }; + var dx = subDWH(pdx, dw); + var dy = subDWH(pdy, dh); + var isExplicitDir = false; + if (rawTaxiDir === AUTO) { + taxiDir = Math.abs(dx) > Math.abs(dy) ? HORIZONTAL : VERTICAL; + } else if (rawTaxiDir === UPWARD || rawTaxiDir === DOWNWARD) { + taxiDir = VERTICAL; + isExplicitDir = true; + } else if (rawTaxiDir === LEFTWARD || rawTaxiDir === RIGHTWARD) { + taxiDir = HORIZONTAL; + isExplicitDir = true; + } + var isVert = taxiDir === VERTICAL; + var l = isVert ? dy : dx; + var pl = isVert ? pdy : pdx; + var sgnL = signum(pl); + var forcedDir = false; + if (!(isExplicitDir && (turnIsPercent || turnIsNegative)) // forcing in this case would cause weird growing in the opposite direction + && (rawTaxiDir === DOWNWARD && pl < 0 || rawTaxiDir === UPWARD && pl > 0 || rawTaxiDir === LEFTWARD && pl > 0 || rawTaxiDir === RIGHTWARD && pl < 0)) { + sgnL *= -1; + l = sgnL * Math.abs(l); + forcedDir = true; + } + var d; + if (turnIsPercent) { + var p = taxiTurnPfVal < 0 ? 1 + taxiTurnPfVal : taxiTurnPfVal; + d = p * l; + } else { + var k = taxiTurnPfVal < 0 ? l : 0; + d = k + taxiTurnPfVal * sgnL; + } + var getIsTooClose = function getIsTooClose(d) { + return Math.abs(d) < minD || Math.abs(d) >= Math.abs(l); + }; + var isTooCloseSrc = getIsTooClose(d); + var isTooCloseTgt = getIsTooClose(Math.abs(l) - Math.abs(d)); + var isTooClose = isTooCloseSrc || isTooCloseTgt; + if (isTooClose && !forcedDir) { + // non-ideal routing + if (isVert) { + // vertical fallbacks + var lShapeInsideSrc = Math.abs(pl) <= srcH / 2; + var lShapeInsideTgt = Math.abs(pdx) <= tgtW / 2; + if (lShapeInsideSrc) { + // horizontal Z-shape (direction not respected) + var x = (posPts.x1 + posPts.x2) / 2; + var y1 = posPts.y1, + y2 = posPts.y2; + rs.segpts = [x, y1, x, y2]; + } else if (lShapeInsideTgt) { + // vertical Z-shape (distance not respected) + var y = (posPts.y1 + posPts.y2) / 2; + var x1 = posPts.x1, + x2 = posPts.x2; + rs.segpts = [x1, y, x2, y]; + } else { + // L-shape fallback (turn distance not respected, but works well with tree siblings) + rs.segpts = [posPts.x1, posPts.y2]; + } + } else { + // horizontal fallbacks + var _lShapeInsideSrc = Math.abs(pl) <= srcW / 2; + var _lShapeInsideTgt = Math.abs(pdy) <= tgtH / 2; + if (_lShapeInsideSrc) { + // vertical Z-shape (direction not respected) + var _y = (posPts.y1 + posPts.y2) / 2; + var _x = posPts.x1, + _x2 = posPts.x2; + rs.segpts = [_x, _y, _x2, _y]; + } else if (_lShapeInsideTgt) { + // horizontal Z-shape (turn distance not respected) + var _x3 = (posPts.x1 + posPts.x2) / 2; + var _y2 = posPts.y1, + _y3 = posPts.y2; + rs.segpts = [_x3, _y2, _x3, _y3]; + } else { + // L-shape (turn distance not respected, but works well for tree siblings) + rs.segpts = [posPts.x2, posPts.y1]; + } + } + } else { + // ideal routing + if (isVert) { + var _y4 = posPts.y1 + d + (dIncludesNodeBody ? srcH / 2 * sgnL : 0); + var _x4 = posPts.x1, + _x5 = posPts.x2; + rs.segpts = [_x4, _y4, _x5, _y4]; + } else { + // horizontal + var _x6 = posPts.x1 + d + (dIncludesNodeBody ? srcW / 2 * sgnL : 0); + var _y5 = posPts.y1, + _y6 = posPts.y2; + rs.segpts = [_x6, _y5, _x6, _y6]; + } + } + }; + BRp$c.tryToCorrectInvalidPoints = function (edge, pairInfo) { + var rs = edge._private.rscratch; + + // can only correct beziers for now... + if (rs.edgeType === 'bezier') { + var srcPos = pairInfo.srcPos, + tgtPos = pairInfo.tgtPos, + srcW = pairInfo.srcW, + srcH = pairInfo.srcH, + tgtW = pairInfo.tgtW, + tgtH = pairInfo.tgtH, + srcShape = pairInfo.srcShape, + tgtShape = pairInfo.tgtShape; + var badStart = !number$1(rs.startX) || !number$1(rs.startY); + var badAStart = !number$1(rs.arrowStartX) || !number$1(rs.arrowStartY); + var badEnd = !number$1(rs.endX) || !number$1(rs.endY); + var badAEnd = !number$1(rs.arrowEndX) || !number$1(rs.arrowEndY); + var minCpADistFactor = 3; + var arrowW = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth; + var minCpADist = minCpADistFactor * arrowW; + var startACpDist = dist({ + x: rs.ctrlpts[0], + y: rs.ctrlpts[1] + }, { + x: rs.startX, + y: rs.startY + }); + var closeStartACp = startACpDist < minCpADist; + var endACpDist = dist({ + x: rs.ctrlpts[0], + y: rs.ctrlpts[1] + }, { + x: rs.endX, + y: rs.endY + }); + var closeEndACp = endACpDist < minCpADist; + var overlapping = false; + if (badStart || badAStart || closeStartACp) { + overlapping = true; + + // project control point along line from src centre to outside the src shape + // (otherwise intersection will yield nothing) + var cpD = { + // delta + x: rs.ctrlpts[0] - srcPos.x, + y: rs.ctrlpts[1] - srcPos.y + }; + var cpL = Math.sqrt(cpD.x * cpD.x + cpD.y * cpD.y); // length of line + var cpM = { + // normalised delta + x: cpD.x / cpL, + y: cpD.y / cpL + }; + var radius = Math.max(srcW, srcH); + var cpProj = { + // *2 radius guarantees outside shape + x: rs.ctrlpts[0] + cpM.x * 2 * radius, + y: rs.ctrlpts[1] + cpM.y * 2 * radius + }; + var srcCtrlPtIntn = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, cpProj.x, cpProj.y, 0); + if (closeStartACp) { + rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - startACpDist); + rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - startACpDist); + } else { + rs.ctrlpts[0] = srcCtrlPtIntn[0] + cpM.x * minCpADist; + rs.ctrlpts[1] = srcCtrlPtIntn[1] + cpM.y * minCpADist; + } + } + if (badEnd || badAEnd || closeEndACp) { + overlapping = true; + + // project control point along line from tgt centre to outside the tgt shape + // (otherwise intersection will yield nothing) + var _cpD = { + // delta + x: rs.ctrlpts[0] - tgtPos.x, + y: rs.ctrlpts[1] - tgtPos.y + }; + var _cpL = Math.sqrt(_cpD.x * _cpD.x + _cpD.y * _cpD.y); // length of line + var _cpM = { + // normalised delta + x: _cpD.x / _cpL, + y: _cpD.y / _cpL + }; + var _radius = Math.max(srcW, srcH); + var _cpProj = { + // *2 radius guarantees outside shape + x: rs.ctrlpts[0] + _cpM.x * 2 * _radius, + y: rs.ctrlpts[1] + _cpM.y * 2 * _radius + }; + var tgtCtrlPtIntn = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, _cpProj.x, _cpProj.y, 0); + if (closeEndACp) { + rs.ctrlpts[0] = rs.ctrlpts[0] + _cpM.x * (minCpADist - endACpDist); + rs.ctrlpts[1] = rs.ctrlpts[1] + _cpM.y * (minCpADist - endACpDist); + } else { + rs.ctrlpts[0] = tgtCtrlPtIntn[0] + _cpM.x * minCpADist; + rs.ctrlpts[1] = tgtCtrlPtIntn[1] + _cpM.y * minCpADist; + } + } + if (overlapping) { + // recalc endpts + this.findEndpoints(edge); + } + } + }; + BRp$c.storeAllpts = function (edge) { + var rs = edge._private.rscratch; + if (rs.edgeType === 'multibezier' || rs.edgeType === 'bezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') { + rs.allpts = []; + rs.allpts.push(rs.startX, rs.startY); + for (var b = 0; b + 1 < rs.ctrlpts.length; b += 2) { + // ctrl pt itself + rs.allpts.push(rs.ctrlpts[b], rs.ctrlpts[b + 1]); + + // the midpt between ctrlpts as intermediate destination pts + if (b + 3 < rs.ctrlpts.length) { + rs.allpts.push((rs.ctrlpts[b] + rs.ctrlpts[b + 2]) / 2, (rs.ctrlpts[b + 1] + rs.ctrlpts[b + 3]) / 2); + } + } + rs.allpts.push(rs.endX, rs.endY); + var m, mt; + if (rs.ctrlpts.length / 2 % 2 === 0) { + m = rs.allpts.length / 2 - 1; + rs.midX = rs.allpts[m]; + rs.midY = rs.allpts[m + 1]; + } else { + m = rs.allpts.length / 2 - 3; + mt = 0.5; + rs.midX = qbezierAt(rs.allpts[m], rs.allpts[m + 2], rs.allpts[m + 4], mt); + rs.midY = qbezierAt(rs.allpts[m + 1], rs.allpts[m + 3], rs.allpts[m + 5], mt); + } + } else if (rs.edgeType === 'straight') { + // need to calc these after endpts + rs.allpts = [rs.startX, rs.startY, rs.endX, rs.endY]; + + // default midpt for labels etc + rs.midX = (rs.startX + rs.endX + rs.arrowStartX + rs.arrowEndX) / 4; + rs.midY = (rs.startY + rs.endY + rs.arrowStartY + rs.arrowEndY) / 4; + } else if (rs.edgeType === 'segments') { + rs.allpts = []; + rs.allpts.push(rs.startX, rs.startY); + rs.allpts.push.apply(rs.allpts, rs.segpts); + rs.allpts.push(rs.endX, rs.endY); + if (rs.segpts.length % 4 === 0) { + var i2 = rs.segpts.length / 2; + var i1 = i2 - 2; + rs.midX = (rs.segpts[i1] + rs.segpts[i2]) / 2; + rs.midY = (rs.segpts[i1 + 1] + rs.segpts[i2 + 1]) / 2; + } else { + var _i = rs.segpts.length / 2 - 1; + rs.midX = rs.segpts[_i]; + rs.midY = rs.segpts[_i + 1]; + } + } + }; + BRp$c.checkForInvalidEdgeWarning = function (edge) { + var rs = edge[0]._private.rscratch; + if (rs.nodesOverlap || number$1(rs.startX) && number$1(rs.startY) && number$1(rs.endX) && number$1(rs.endY)) { + rs.loggedErr = false; + } else { + if (!rs.loggedErr) { + rs.loggedErr = true; + warn('Edge `' + edge.id() + '` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap.'); + } + } + }; + BRp$c.findEdgeControlPoints = function (edges) { + var _this = this; + if (!edges || edges.length === 0) { + return; + } + var r = this; + var cy = r.cy; + var hasCompounds = cy.hasCompoundNodes(); + var hashTable = { + map: new Map$2(), + get: function get(pairId) { + var map2 = this.map.get(pairId[0]); + if (map2 != null) { + return map2.get(pairId[1]); + } else { + return null; + } + }, + set: function set(pairId, val) { + var map2 = this.map.get(pairId[0]); + if (map2 == null) { + map2 = new Map$2(); + this.map.set(pairId[0], map2); + } + map2.set(pairId[1], val); + } + }; + var pairIds = []; + var haystackEdges = []; + + // create a table of edge (src, tgt) => list of edges between them + for (var i = 0; i < edges.length; i++) { + var edge = edges[i]; + var _p = edge._private; + var curveStyle = edge.pstyle('curve-style').value; + + // ignore edges who are not to be displayed + // they shouldn't take up space + if (edge.removed() || !edge.takesUpSpace()) { + continue; + } + if (curveStyle === 'haystack') { + haystackEdges.push(edge); + continue; + } + var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments' || curveStyle === 'straight' || curveStyle === 'straight-triangle' || curveStyle === 'taxi'; + var edgeIsBezier = curveStyle === 'unbundled-bezier' || curveStyle === 'bezier'; + var src = _p.source; + var tgt = _p.target; + var srcIndex = src.poolIndex(); + var tgtIndex = tgt.poolIndex(); + var pairId = [srcIndex, tgtIndex].sort(); + var tableEntry = hashTable.get(pairId); + if (tableEntry == null) { + tableEntry = { + eles: [] + }; + hashTable.set(pairId, tableEntry); + pairIds.push(pairId); + } + tableEntry.eles.push(edge); + if (edgeIsUnbundled) { + tableEntry.hasUnbundled = true; + } + if (edgeIsBezier) { + tableEntry.hasBezier = true; + } + } + + // for each pair (src, tgt), create the ctrl pts + // Nested for loop is OK; total number of iterations for both loops = edgeCount + var _loop = function _loop(p) { + var pairId = pairIds[p]; + var pairInfo = hashTable.get(pairId); + var swappedpairInfo = void 0; + if (!pairInfo.hasUnbundled) { + var pllEdges = pairInfo.eles[0].parallelEdges().filter(function (e) { + return e.isBundledBezier(); + }); + clearArray(pairInfo.eles); + pllEdges.forEach(function (edge) { + return pairInfo.eles.push(edge); + }); + + // for each pair id, the edges should be sorted by index + pairInfo.eles.sort(function (edge1, edge2) { + return edge1.poolIndex() - edge2.poolIndex(); + }); + } + var firstEdge = pairInfo.eles[0]; + var src = firstEdge.source(); + var tgt = firstEdge.target(); + + // make sure src/tgt distinction is consistent w.r.t. pairId + if (src.poolIndex() > tgt.poolIndex()) { + var temp = src; + src = tgt; + tgt = temp; + } + var srcPos = pairInfo.srcPos = src.position(); + var tgtPos = pairInfo.tgtPos = tgt.position(); + var srcW = pairInfo.srcW = src.outerWidth(); + var srcH = pairInfo.srcH = src.outerHeight(); + var tgtW = pairInfo.tgtW = tgt.outerWidth(); + var tgtH = pairInfo.tgtH = tgt.outerHeight(); + var srcShape = pairInfo.srcShape = r.nodeShapes[_this.getNodeShape(src)]; + var tgtShape = pairInfo.tgtShape = r.nodeShapes[_this.getNodeShape(tgt)]; + pairInfo.dirCounts = { + 'north': 0, + 'west': 0, + 'south': 0, + 'east': 0, + 'northwest': 0, + 'southwest': 0, + 'northeast': 0, + 'southeast': 0 + }; + for (var _i2 = 0; _i2 < pairInfo.eles.length; _i2++) { + var _edge = pairInfo.eles[_i2]; + var rs = _edge[0]._private.rscratch; + var _curveStyle = _edge.pstyle('curve-style').value; + var _edgeIsUnbundled = _curveStyle === 'unbundled-bezier' || _curveStyle === 'segments' || _curveStyle === 'taxi'; + + // whether the normalised pair order is the reverse of the edge's src-tgt order + var edgeIsSwapped = !src.same(_edge.source()); + if (!pairInfo.calculatedIntersection && src !== tgt && (pairInfo.hasBezier || pairInfo.hasUnbundled)) { + pairInfo.calculatedIntersection = true; + + // pt outside src shape to calc distance/displacement from src to tgt + var srcOutside = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, tgtPos.x, tgtPos.y, 0); + var srcIntn = pairInfo.srcIntn = srcOutside; + + // pt outside tgt shape to calc distance/displacement from src to tgt + var tgtOutside = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, srcPos.x, srcPos.y, 0); + var tgtIntn = pairInfo.tgtIntn = tgtOutside; + var intersectionPts = pairInfo.intersectionPts = { + x1: srcOutside[0], + x2: tgtOutside[0], + y1: srcOutside[1], + y2: tgtOutside[1] + }; + var posPts = pairInfo.posPts = { + x1: srcPos.x, + x2: tgtPos.x, + y1: srcPos.y, + y2: tgtPos.y + }; + var dy = tgtOutside[1] - srcOutside[1]; + var dx = tgtOutside[0] - srcOutside[0]; + var l = Math.sqrt(dx * dx + dy * dy); + var vector = pairInfo.vector = { + x: dx, + y: dy + }; + var vectorNorm = pairInfo.vectorNorm = { + x: vector.x / l, + y: vector.y / l + }; + var vectorNormInverse = { + x: -vectorNorm.y, + y: vectorNorm.x + }; + + // if node shapes overlap, then no ctrl pts to draw + pairInfo.nodesOverlap = !number$1(l) || tgtShape.checkPoint(srcOutside[0], srcOutside[1], 0, tgtW, tgtH, tgtPos.x, tgtPos.y) || srcShape.checkPoint(tgtOutside[0], tgtOutside[1], 0, srcW, srcH, srcPos.x, srcPos.y); + pairInfo.vectorNormInverse = vectorNormInverse; + swappedpairInfo = { + nodesOverlap: pairInfo.nodesOverlap, + dirCounts: pairInfo.dirCounts, + calculatedIntersection: true, + hasBezier: pairInfo.hasBezier, + hasUnbundled: pairInfo.hasUnbundled, + eles: pairInfo.eles, + srcPos: tgtPos, + tgtPos: srcPos, + srcW: tgtW, + srcH: tgtH, + tgtW: srcW, + tgtH: srcH, + srcIntn: tgtIntn, + tgtIntn: srcIntn, + srcShape: tgtShape, + tgtShape: srcShape, + posPts: { + x1: posPts.x2, + y1: posPts.y2, + x2: posPts.x1, + y2: posPts.y1 + }, + intersectionPts: { + x1: intersectionPts.x2, + y1: intersectionPts.y2, + x2: intersectionPts.x1, + y2: intersectionPts.y1 + }, + vector: { + x: -vector.x, + y: -vector.y + }, + vectorNorm: { + x: -vectorNorm.x, + y: -vectorNorm.y + }, + vectorNormInverse: { + x: -vectorNormInverse.x, + y: -vectorNormInverse.y + } + }; + } + var passedPairInfo = edgeIsSwapped ? swappedpairInfo : pairInfo; + rs.nodesOverlap = passedPairInfo.nodesOverlap; + rs.srcIntn = passedPairInfo.srcIntn; + rs.tgtIntn = passedPairInfo.tgtIntn; + if (hasCompounds && (src.isParent() || src.isChild() || tgt.isParent() || tgt.isChild()) && (src.parents().anySame(tgt) || tgt.parents().anySame(src) || src.same(tgt) && src.isParent())) { + _this.findCompoundLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled); + } else if (src === tgt) { + _this.findLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled); + } else if (_curveStyle === 'segments') { + _this.findSegmentsPoints(_edge, passedPairInfo); + } else if (_curveStyle === 'taxi') { + _this.findTaxiPoints(_edge, passedPairInfo); + } else if (_curveStyle === 'straight' || !_edgeIsUnbundled && pairInfo.eles.length % 2 === 1 && _i2 === Math.floor(pairInfo.eles.length / 2)) { + _this.findStraightEdgePoints(_edge); + } else { + _this.findBezierPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled, edgeIsSwapped); + } + _this.findEndpoints(_edge); + _this.tryToCorrectInvalidPoints(_edge, passedPairInfo); + _this.checkForInvalidEdgeWarning(_edge); + _this.storeAllpts(_edge); + _this.storeEdgeProjections(_edge); + _this.calculateArrowAngles(_edge); + _this.recalculateEdgeLabelProjections(_edge); + _this.calculateLabelAngles(_edge); + } // for pair edges + }; + for (var p = 0; p < pairIds.length; p++) { + _loop(p); + } // for pair ids + + // haystacks avoid the expense of pairInfo stuff (intersections etc.) + this.findHaystackPoints(haystackEdges); + }; + function getPts(pts) { + var retPts = []; + if (pts == null) { + return; + } + for (var i = 0; i < pts.length; i += 2) { + var x = pts[i]; + var y = pts[i + 1]; + retPts.push({ + x: x, + y: y + }); + } + return retPts; + } + BRp$c.getSegmentPoints = function (edge) { + var rs = edge[0]._private.rscratch; + var type = rs.edgeType; + if (type === 'segments') { + this.recalculateRenderedStyle(edge); + return getPts(rs.segpts); + } + }; + BRp$c.getControlPoints = function (edge) { + var rs = edge[0]._private.rscratch; + var type = rs.edgeType; + if (type === 'bezier' || type === 'multibezier' || type === 'self' || type === 'compound') { + this.recalculateRenderedStyle(edge); + return getPts(rs.ctrlpts); + } + }; + BRp$c.getEdgeMidpoint = function (edge) { + var rs = edge[0]._private.rscratch; + this.recalculateRenderedStyle(edge); + return { + x: rs.midX, + y: rs.midY + }; + }; + + var BRp$b = {}; + BRp$b.manualEndptToPx = function (node, prop) { + var r = this; + var npos = node.position(); + var w = node.outerWidth(); + var h = node.outerHeight(); + if (prop.value.length === 2) { + var p = [prop.pfValue[0], prop.pfValue[1]]; + if (prop.units[0] === '%') { + p[0] = p[0] * w; + } + if (prop.units[1] === '%') { + p[1] = p[1] * h; + } + p[0] += npos.x; + p[1] += npos.y; + return p; + } else { + var angle = prop.pfValue[0]; + angle = -Math.PI / 2 + angle; // start at 12 o'clock + + var l = 2 * Math.max(w, h); + var _p = [npos.x + Math.cos(angle) * l, npos.y + Math.sin(angle) * l]; + return r.nodeShapes[this.getNodeShape(node)].intersectLine(npos.x, npos.y, w, h, _p[0], _p[1], 0); + } + }; + BRp$b.findEndpoints = function (edge) { + var r = this; + var intersect; + var source = edge.source()[0]; + var target = edge.target()[0]; + var srcPos = source.position(); + var tgtPos = target.position(); + var tgtArShape = edge.pstyle('target-arrow-shape').value; + var srcArShape = edge.pstyle('source-arrow-shape').value; + var tgtDist = edge.pstyle('target-distance-from-node').pfValue; + var srcDist = edge.pstyle('source-distance-from-node').pfValue; + var curveStyle = edge.pstyle('curve-style').value; + var rs = edge._private.rscratch; + var et = rs.edgeType; + var taxi = curveStyle === 'taxi'; + var self = et === 'self' || et === 'compound'; + var bezier = et === 'bezier' || et === 'multibezier' || self; + var multi = et !== 'bezier'; + var lines = et === 'straight' || et === 'segments'; + var segments = et === 'segments'; + var hasEndpts = bezier || multi || lines; + var overrideEndpts = self || taxi; + var srcManEndpt = edge.pstyle('source-endpoint'); + var srcManEndptVal = overrideEndpts ? 'outside-to-node' : srcManEndpt.value; + var tgtManEndpt = edge.pstyle('target-endpoint'); + var tgtManEndptVal = overrideEndpts ? 'outside-to-node' : tgtManEndpt.value; + rs.srcManEndpt = srcManEndpt; + rs.tgtManEndpt = tgtManEndpt; + var p1; // last known point of edge on target side + var p2; // last known point of edge on source side + + var p1_i; // point to intersect with target shape + var p2_i; // point to intersect with source shape + + if (bezier) { + var cpStart = [rs.ctrlpts[0], rs.ctrlpts[1]]; + var cpEnd = multi ? [rs.ctrlpts[rs.ctrlpts.length - 2], rs.ctrlpts[rs.ctrlpts.length - 1]] : cpStart; + p1 = cpEnd; + p2 = cpStart; + } else if (lines) { + var srcArrowFromPt = !segments ? [tgtPos.x, tgtPos.y] : rs.segpts.slice(0, 2); + var tgtArrowFromPt = !segments ? [srcPos.x, srcPos.y] : rs.segpts.slice(rs.segpts.length - 2); + p1 = tgtArrowFromPt; + p2 = srcArrowFromPt; + } + if (tgtManEndptVal === 'inside-to-node') { + intersect = [tgtPos.x, tgtPos.y]; + } else if (tgtManEndpt.units) { + intersect = this.manualEndptToPx(target, tgtManEndpt); + } else if (tgtManEndptVal === 'outside-to-line') { + intersect = rs.tgtIntn; // use cached value from ctrlpt calc + } else { + if (tgtManEndptVal === 'outside-to-node' || tgtManEndptVal === 'outside-to-node-or-label') { + p1_i = p1; + } else if (tgtManEndptVal === 'outside-to-line' || tgtManEndptVal === 'outside-to-line-or-label') { + p1_i = [srcPos.x, srcPos.y]; + } + intersect = r.nodeShapes[this.getNodeShape(target)].intersectLine(tgtPos.x, tgtPos.y, target.outerWidth(), target.outerHeight(), p1_i[0], p1_i[1], 0); + if (tgtManEndptVal === 'outside-to-node-or-label' || tgtManEndptVal === 'outside-to-line-or-label') { + var trs = target._private.rscratch; + var lw = trs.labelWidth; + var lh = trs.labelHeight; + var lx = trs.labelX; + var ly = trs.labelY; + var lw2 = lw / 2; + var lh2 = lh / 2; + var va = target.pstyle('text-valign').value; + if (va === 'top') { + ly -= lh2; + } else if (va === 'bottom') { + ly += lh2; + } + var ha = target.pstyle('text-halign').value; + if (ha === 'left') { + lx -= lw2; + } else if (ha === 'right') { + lx += lw2; + } + var labelIntersect = polygonIntersectLine(p1_i[0], p1_i[1], [lx - lw2, ly - lh2, lx + lw2, ly - lh2, lx + lw2, ly + lh2, lx - lw2, ly + lh2], tgtPos.x, tgtPos.y); + if (labelIntersect.length > 0) { + var refPt = srcPos; + var intSqdist = sqdist(refPt, array2point(intersect)); + var labIntSqdist = sqdist(refPt, array2point(labelIntersect)); + var minSqDist = intSqdist; + if (labIntSqdist < intSqdist) { + intersect = labelIntersect; + minSqDist = labIntSqdist; + } + if (labelIntersect.length > 2) { + var labInt2SqDist = sqdist(refPt, { + x: labelIntersect[2], + y: labelIntersect[3] + }); + if (labInt2SqDist < minSqDist) { + intersect = [labelIntersect[2], labelIntersect[3]]; + } + } + } + } + } + var arrowEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].spacing(edge) + tgtDist); + var edgeEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].gap(edge) + tgtDist); + rs.endX = edgeEnd[0]; + rs.endY = edgeEnd[1]; + rs.arrowEndX = arrowEnd[0]; + rs.arrowEndY = arrowEnd[1]; + if (srcManEndptVal === 'inside-to-node') { + intersect = [srcPos.x, srcPos.y]; + } else if (srcManEndpt.units) { + intersect = this.manualEndptToPx(source, srcManEndpt); + } else if (srcManEndptVal === 'outside-to-line') { + intersect = rs.srcIntn; // use cached value from ctrlpt calc + } else { + if (srcManEndptVal === 'outside-to-node' || srcManEndptVal === 'outside-to-node-or-label') { + p2_i = p2; + } else if (srcManEndptVal === 'outside-to-line' || srcManEndptVal === 'outside-to-line-or-label') { + p2_i = [tgtPos.x, tgtPos.y]; + } + intersect = r.nodeShapes[this.getNodeShape(source)].intersectLine(srcPos.x, srcPos.y, source.outerWidth(), source.outerHeight(), p2_i[0], p2_i[1], 0); + if (srcManEndptVal === 'outside-to-node-or-label' || srcManEndptVal === 'outside-to-line-or-label') { + var srs = source._private.rscratch; + var _lw = srs.labelWidth; + var _lh = srs.labelHeight; + var _lx = srs.labelX; + var _ly = srs.labelY; + var _lw2 = _lw / 2; + var _lh2 = _lh / 2; + var _va = source.pstyle('text-valign').value; + if (_va === 'top') { + _ly -= _lh2; + } else if (_va === 'bottom') { + _ly += _lh2; + } + var _ha = source.pstyle('text-halign').value; + if (_ha === 'left') { + _lx -= _lw2; + } else if (_ha === 'right') { + _lx += _lw2; + } + var _labelIntersect = polygonIntersectLine(p2_i[0], p2_i[1], [_lx - _lw2, _ly - _lh2, _lx + _lw2, _ly - _lh2, _lx + _lw2, _ly + _lh2, _lx - _lw2, _ly + _lh2], srcPos.x, srcPos.y); + if (_labelIntersect.length > 0) { + var _refPt = tgtPos; + var _intSqdist = sqdist(_refPt, array2point(intersect)); + var _labIntSqdist = sqdist(_refPt, array2point(_labelIntersect)); + var _minSqDist = _intSqdist; + if (_labIntSqdist < _intSqdist) { + intersect = [_labelIntersect[0], _labelIntersect[1]]; + _minSqDist = _labIntSqdist; + } + if (_labelIntersect.length > 2) { + var _labInt2SqDist = sqdist(_refPt, { + x: _labelIntersect[2], + y: _labelIntersect[3] + }); + if (_labInt2SqDist < _minSqDist) { + intersect = [_labelIntersect[2], _labelIntersect[3]]; + } + } + } + } + } + var arrowStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].spacing(edge) + srcDist); + var edgeStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].gap(edge) + srcDist); + rs.startX = edgeStart[0]; + rs.startY = edgeStart[1]; + rs.arrowStartX = arrowStart[0]; + rs.arrowStartY = arrowStart[1]; + if (hasEndpts) { + if (!number$1(rs.startX) || !number$1(rs.startY) || !number$1(rs.endX) || !number$1(rs.endY)) { + rs.badLine = true; + } else { + rs.badLine = false; + } + } + }; + BRp$b.getSourceEndpoint = function (edge) { + var rs = edge[0]._private.rscratch; + this.recalculateRenderedStyle(edge); + switch (rs.edgeType) { + case 'haystack': + return { + x: rs.haystackPts[0], + y: rs.haystackPts[1] + }; + default: + return { + x: rs.arrowStartX, + y: rs.arrowStartY + }; + } + }; + BRp$b.getTargetEndpoint = function (edge) { + var rs = edge[0]._private.rscratch; + this.recalculateRenderedStyle(edge); + switch (rs.edgeType) { + case 'haystack': + return { + x: rs.haystackPts[2], + y: rs.haystackPts[3] + }; + default: + return { + x: rs.arrowEndX, + y: rs.arrowEndY + }; + } + }; + + var BRp$a = {}; + function pushBezierPts(r, edge, pts) { + var qbezierAt$1 = function qbezierAt$1(p1, p2, p3, t) { + return qbezierAt(p1, p2, p3, t); + }; + var _p = edge._private; + var bpts = _p.rstyle.bezierPts; + for (var i = 0; i < r.bezierProjPcts.length; i++) { + var p = r.bezierProjPcts[i]; + bpts.push({ + x: qbezierAt$1(pts[0], pts[2], pts[4], p), + y: qbezierAt$1(pts[1], pts[3], pts[5], p) + }); + } + } + BRp$a.storeEdgeProjections = function (edge) { + var _p = edge._private; + var rs = _p.rscratch; + var et = rs.edgeType; + + // clear the cached points state + _p.rstyle.bezierPts = null; + _p.rstyle.linePts = null; + _p.rstyle.haystackPts = null; + if (et === 'multibezier' || et === 'bezier' || et === 'self' || et === 'compound') { + _p.rstyle.bezierPts = []; + for (var i = 0; i + 5 < rs.allpts.length; i += 4) { + pushBezierPts(this, edge, rs.allpts.slice(i, i + 6)); + } + } else if (et === 'segments') { + var lpts = _p.rstyle.linePts = []; + for (var i = 0; i + 1 < rs.allpts.length; i += 2) { + lpts.push({ + x: rs.allpts[i], + y: rs.allpts[i + 1] + }); + } + } else if (et === 'haystack') { + var hpts = rs.haystackPts; + _p.rstyle.haystackPts = [{ + x: hpts[0], + y: hpts[1] + }, { + x: hpts[2], + y: hpts[3] + }]; + } + _p.rstyle.arrowWidth = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth; + }; + BRp$a.recalculateEdgeProjections = function (edges) { + this.findEdgeControlPoints(edges); + }; + + /* global document */ + + var BRp$9 = {}; + BRp$9.recalculateNodeLabelProjection = function (node) { + var content = node.pstyle('label').strValue; + if (emptyString(content)) { + return; + } + var textX, textY; + var _p = node._private; + var nodeWidth = node.width(); + var nodeHeight = node.height(); + var padding = node.padding(); + var nodePos = node.position(); + var textHalign = node.pstyle('text-halign').strValue; + var textValign = node.pstyle('text-valign').strValue; + var rs = _p.rscratch; + var rstyle = _p.rstyle; + switch (textHalign) { + case 'left': + textX = nodePos.x - nodeWidth / 2 - padding; + break; + case 'right': + textX = nodePos.x + nodeWidth / 2 + padding; + break; + default: + // e.g. center + textX = nodePos.x; + } + switch (textValign) { + case 'top': + textY = nodePos.y - nodeHeight / 2 - padding; + break; + case 'bottom': + textY = nodePos.y + nodeHeight / 2 + padding; + break; + default: + // e.g. middle + textY = nodePos.y; + } + rs.labelX = textX; + rs.labelY = textY; + rstyle.labelX = textX; + rstyle.labelY = textY; + this.calculateLabelAngles(node); + this.applyLabelDimensions(node); + }; + var lineAngleFromDelta = function lineAngleFromDelta(dx, dy) { + var angle = Math.atan(dy / dx); + if (dx === 0 && angle < 0) { + angle = angle * -1; + } + return angle; + }; + var lineAngle = function lineAngle(p0, p1) { + var dx = p1.x - p0.x; + var dy = p1.y - p0.y; + return lineAngleFromDelta(dx, dy); + }; + var bezierAngle = function bezierAngle(p0, p1, p2, t) { + var t0 = bound(0, t - 0.001, 1); + var t1 = bound(0, t + 0.001, 1); + var lp0 = qbezierPtAt(p0, p1, p2, t0); + var lp1 = qbezierPtAt(p0, p1, p2, t1); + return lineAngle(lp0, lp1); + }; + BRp$9.recalculateEdgeLabelProjections = function (edge) { + var p; + var _p = edge._private; + var rs = _p.rscratch; + var r = this; + var content = { + mid: edge.pstyle('label').strValue, + source: edge.pstyle('source-label').strValue, + target: edge.pstyle('target-label').strValue + }; + if (content.mid || content.source || content.target) ; else { + return; // no labels => no calcs + } + + // add center point to style so bounding box calculations can use it + // + p = { + x: rs.midX, + y: rs.midY + }; + var setRs = function setRs(propName, prefix, value) { + setPrefixedProperty(_p.rscratch, propName, prefix, value); + setPrefixedProperty(_p.rstyle, propName, prefix, value); + }; + setRs('labelX', null, p.x); + setRs('labelY', null, p.y); + var midAngle = lineAngleFromDelta(rs.midDispX, rs.midDispY); + setRs('labelAutoAngle', null, midAngle); + var createControlPointInfo = function createControlPointInfo() { + if (createControlPointInfo.cache) { + return createControlPointInfo.cache; + } // use cache so only 1x per edge + + var ctrlpts = []; + + // store each ctrlpt info init + for (var i = 0; i + 5 < rs.allpts.length; i += 4) { + var p0 = { + x: rs.allpts[i], + y: rs.allpts[i + 1] + }; + var p1 = { + x: rs.allpts[i + 2], + y: rs.allpts[i + 3] + }; // ctrlpt + var p2 = { + x: rs.allpts[i + 4], + y: rs.allpts[i + 5] + }; + ctrlpts.push({ + p0: p0, + p1: p1, + p2: p2, + startDist: 0, + length: 0, + segments: [] + }); + } + var bpts = _p.rstyle.bezierPts; + var nProjs = r.bezierProjPcts.length; + function addSegment(cp, p0, p1, t0, t1) { + var length = dist(p0, p1); + var prevSegment = cp.segments[cp.segments.length - 1]; + var segment = { + p0: p0, + p1: p1, + t0: t0, + t1: t1, + startDist: prevSegment ? prevSegment.startDist + prevSegment.length : 0, + length: length + }; + cp.segments.push(segment); + cp.length += length; + } + + // update each ctrlpt with segment info + for (var _i = 0; _i < ctrlpts.length; _i++) { + var cp = ctrlpts[_i]; + var prevCp = ctrlpts[_i - 1]; + if (prevCp) { + cp.startDist = prevCp.startDist + prevCp.length; + } + addSegment(cp, cp.p0, bpts[_i * nProjs], 0, r.bezierProjPcts[0]); // first + + for (var j = 0; j < nProjs - 1; j++) { + addSegment(cp, bpts[_i * nProjs + j], bpts[_i * nProjs + j + 1], r.bezierProjPcts[j], r.bezierProjPcts[j + 1]); + } + addSegment(cp, bpts[_i * nProjs + nProjs - 1], cp.p2, r.bezierProjPcts[nProjs - 1], 1); // last + } + + return createControlPointInfo.cache = ctrlpts; + }; + var calculateEndProjection = function calculateEndProjection(prefix) { + var angle; + var isSrc = prefix === 'source'; + if (!content[prefix]) { + return; + } + var offset = edge.pstyle(prefix + '-text-offset').pfValue; + switch (rs.edgeType) { + case 'self': + case 'compound': + case 'bezier': + case 'multibezier': + { + var cps = createControlPointInfo(); + var selected; + var startDist = 0; + var totalDist = 0; + + // find the segment we're on + for (var i = 0; i < cps.length; i++) { + var _cp = cps[isSrc ? i : cps.length - 1 - i]; + for (var j = 0; j < _cp.segments.length; j++) { + var _seg = _cp.segments[isSrc ? j : _cp.segments.length - 1 - j]; + var lastSeg = i === cps.length - 1 && j === _cp.segments.length - 1; + startDist = totalDist; + totalDist += _seg.length; + if (totalDist >= offset || lastSeg) { + selected = { + cp: _cp, + segment: _seg + }; + break; + } + } + if (selected) { + break; + } + } + var cp = selected.cp; + var seg = selected.segment; + var tSegment = (offset - startDist) / seg.length; + var segDt = seg.t1 - seg.t0; + var t = isSrc ? seg.t0 + segDt * tSegment : seg.t1 - segDt * tSegment; + t = bound(0, t, 1); + p = qbezierPtAt(cp.p0, cp.p1, cp.p2, t); + angle = bezierAngle(cp.p0, cp.p1, cp.p2, t); + break; + } + case 'straight': + case 'segments': + case 'haystack': + { + var d = 0, + di, + d0; + var p0, p1; + var l = rs.allpts.length; + for (var _i2 = 0; _i2 + 3 < l; _i2 += 2) { + if (isSrc) { + p0 = { + x: rs.allpts[_i2], + y: rs.allpts[_i2 + 1] + }; + p1 = { + x: rs.allpts[_i2 + 2], + y: rs.allpts[_i2 + 3] + }; + } else { + p0 = { + x: rs.allpts[l - 2 - _i2], + y: rs.allpts[l - 1 - _i2] + }; + p1 = { + x: rs.allpts[l - 4 - _i2], + y: rs.allpts[l - 3 - _i2] + }; + } + di = dist(p0, p1); + d0 = d; + d += di; + if (d >= offset) { + break; + } + } + var pD = offset - d0; + var _t = pD / di; + _t = bound(0, _t, 1); + p = lineAt(p0, p1, _t); + angle = lineAngle(p0, p1); + break; + } + } + setRs('labelX', prefix, p.x); + setRs('labelY', prefix, p.y); + setRs('labelAutoAngle', prefix, angle); + }; + calculateEndProjection('source'); + calculateEndProjection('target'); + this.applyLabelDimensions(edge); + }; + BRp$9.applyLabelDimensions = function (ele) { + this.applyPrefixedLabelDimensions(ele); + if (ele.isEdge()) { + this.applyPrefixedLabelDimensions(ele, 'source'); + this.applyPrefixedLabelDimensions(ele, 'target'); + } + }; + BRp$9.applyPrefixedLabelDimensions = function (ele, prefix) { + var _p = ele._private; + var text = this.getLabelText(ele, prefix); + var labelDims = this.calculateLabelDimensions(ele, text); + var lineHeight = ele.pstyle('line-height').pfValue; + var textWrap = ele.pstyle('text-wrap').strValue; + var lines = getPrefixedProperty(_p.rscratch, 'labelWrapCachedLines', prefix) || []; + var numLines = textWrap !== 'wrap' ? 1 : Math.max(lines.length, 1); + var normPerLineHeight = labelDims.height / numLines; + var labelLineHeight = normPerLineHeight * lineHeight; + var width = labelDims.width; + var height = labelDims.height + (numLines - 1) * (lineHeight - 1) * normPerLineHeight; + setPrefixedProperty(_p.rstyle, 'labelWidth', prefix, width); + setPrefixedProperty(_p.rscratch, 'labelWidth', prefix, width); + setPrefixedProperty(_p.rstyle, 'labelHeight', prefix, height); + setPrefixedProperty(_p.rscratch, 'labelHeight', prefix, height); + setPrefixedProperty(_p.rscratch, 'labelLineHeight', prefix, labelLineHeight); + }; + BRp$9.getLabelText = function (ele, prefix) { + var _p = ele._private; + var pfd = prefix ? prefix + '-' : ''; + var text = ele.pstyle(pfd + 'label').strValue; + var textTransform = ele.pstyle('text-transform').value; + var rscratch = function rscratch(propName, value) { + if (value) { + setPrefixedProperty(_p.rscratch, propName, prefix, value); + return value; + } else { + return getPrefixedProperty(_p.rscratch, propName, prefix); + } + }; + + // for empty text, skip all processing + if (!text) { + return ''; + } + if (textTransform == 'none') ; else if (textTransform == 'uppercase') { + text = text.toUpperCase(); + } else if (textTransform == 'lowercase') { + text = text.toLowerCase(); + } + var wrapStyle = ele.pstyle('text-wrap').value; + if (wrapStyle === 'wrap') { + var labelKey = rscratch('labelKey'); + + // save recalc if the label is the same as before + if (labelKey != null && rscratch('labelWrapKey') === labelKey) { + return rscratch('labelWrapCachedText'); + } + var zwsp = "\u200B"; + var lines = text.split('\n'); + var maxW = ele.pstyle('text-max-width').pfValue; + var overflow = ele.pstyle('text-overflow-wrap').value; + var overflowAny = overflow === 'anywhere'; + var wrappedLines = []; + var wordsRegex = /[\s\u200b]+/; + var wordSeparator = overflowAny ? '' : ' '; + for (var l = 0; l < lines.length; l++) { + var line = lines[l]; + var lineDims = this.calculateLabelDimensions(ele, line); + var lineW = lineDims.width; + if (overflowAny) { + var processedLine = line.split('').join(zwsp); + line = processedLine; + } + if (lineW > maxW) { + // line is too long + var words = line.split(wordsRegex); + var subline = ''; + for (var w = 0; w < words.length; w++) { + var word = words[w]; + var testLine = subline.length === 0 ? word : subline + wordSeparator + word; + var testDims = this.calculateLabelDimensions(ele, testLine); + var testW = testDims.width; + if (testW <= maxW) { + // word fits on current line + subline += word + wordSeparator; + } else { + // word starts new line + if (subline) { + wrappedLines.push(subline); + } + subline = word + wordSeparator; + } + } + + // if there's remaining text, put it in a wrapped line + if (!subline.match(/^[\s\u200b]+$/)) { + wrappedLines.push(subline); + } + } else { + // line is already short enough + wrappedLines.push(line); + } + } // for + + rscratch('labelWrapCachedLines', wrappedLines); + text = rscratch('labelWrapCachedText', wrappedLines.join('\n')); + rscratch('labelWrapKey', labelKey); + } else if (wrapStyle === 'ellipsis') { + var _maxW = ele.pstyle('text-max-width').pfValue; + var ellipsized = ''; + var ellipsis = "\u2026"; + var incLastCh = false; + if (this.calculateLabelDimensions(ele, text).width < _maxW) { + // the label already fits + return text; + } + for (var i = 0; i < text.length; i++) { + var widthWithNextCh = this.calculateLabelDimensions(ele, ellipsized + text[i] + ellipsis).width; + if (widthWithNextCh > _maxW) { + break; + } + ellipsized += text[i]; + if (i === text.length - 1) { + incLastCh = true; + } + } + if (!incLastCh) { + ellipsized += ellipsis; + } + return ellipsized; + } // if ellipsize + + return text; + }; + BRp$9.getLabelJustification = function (ele) { + var justification = ele.pstyle('text-justification').strValue; + var textHalign = ele.pstyle('text-halign').strValue; + if (justification === 'auto') { + if (ele.isNode()) { + switch (textHalign) { + case 'left': + return 'right'; + case 'right': + return 'left'; + default: + return 'center'; + } + } else { + return 'center'; + } + } else { + return justification; + } + }; + BRp$9.calculateLabelDimensions = function (ele, text) { + var r = this; + var cacheKey = hashString(text, ele._private.labelDimsKey); + var cache = r.labelDimCache || (r.labelDimCache = []); + var existingVal = cache[cacheKey]; + if (existingVal != null) { + return existingVal; + } + var padding = 0; // add padding around text dims, as the measurement isn't that accurate + var fStyle = ele.pstyle('font-style').strValue; + var size = ele.pstyle('font-size').pfValue; + var family = ele.pstyle('font-family').strValue; + var weight = ele.pstyle('font-weight').strValue; + var canvas = this.labelCalcCanvas; + var c2d = this.labelCalcCanvasContext; + if (!canvas) { + canvas = this.labelCalcCanvas = document.createElement('canvas'); + c2d = this.labelCalcCanvasContext = canvas.getContext('2d'); + var ds = canvas.style; + ds.position = 'absolute'; + ds.left = '-9999px'; + ds.top = '-9999px'; + ds.zIndex = '-1'; + ds.visibility = 'hidden'; + ds.pointerEvents = 'none'; + } + c2d.font = "".concat(fStyle, " ").concat(weight, " ").concat(size, "px ").concat(family); + var width = 0; + var height = 0; + var lines = text.split('\n'); + for (var i = 0; i < lines.length; i++) { + var line = lines[i]; + var metrics = c2d.measureText(line); + var w = Math.ceil(metrics.width); + var h = size; + width = Math.max(w, width); + height += h; + } + width += padding; + height += padding; + return cache[cacheKey] = { + width: width, + height: height + }; + }; + BRp$9.calculateLabelAngle = function (ele, prefix) { + var _p = ele._private; + var rs = _p.rscratch; + var isEdge = ele.isEdge(); + var prefixDash = prefix ? prefix + '-' : ''; + var rot = ele.pstyle(prefixDash + 'text-rotation'); + var rotStr = rot.strValue; + if (rotStr === 'none') { + return 0; + } else if (isEdge && rotStr === 'autorotate') { + return rs.labelAutoAngle; + } else if (rotStr === 'autorotate') { + return 0; + } else { + return rot.pfValue; + } + }; + BRp$9.calculateLabelAngles = function (ele) { + var r = this; + var isEdge = ele.isEdge(); + var _p = ele._private; + var rs = _p.rscratch; + rs.labelAngle = r.calculateLabelAngle(ele); + if (isEdge) { + rs.sourceLabelAngle = r.calculateLabelAngle(ele, 'source'); + rs.targetLabelAngle = r.calculateLabelAngle(ele, 'target'); + } + }; + + var BRp$8 = {}; + var TOO_SMALL_CUT_RECT = 28; + var warnedCutRect = false; + BRp$8.getNodeShape = function (node) { + var r = this; + var shape = node.pstyle('shape').value; + if (shape === 'cutrectangle' && (node.width() < TOO_SMALL_CUT_RECT || node.height() < TOO_SMALL_CUT_RECT)) { + if (!warnedCutRect) { + warn('The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead'); + warnedCutRect = true; + } + return 'rectangle'; + } + if (node.isParent()) { + if (shape === 'rectangle' || shape === 'roundrectangle' || shape === 'round-rectangle' || shape === 'cutrectangle' || shape === 'cut-rectangle' || shape === 'barrel') { + return shape; + } else { + return 'rectangle'; + } + } + if (shape === 'polygon') { + var points = node.pstyle('shape-polygon-points').value; + return r.nodeShapes.makePolygon(points).name; + } + return shape; + }; + + var BRp$7 = {}; + BRp$7.registerCalculationListeners = function () { + var cy = this.cy; + var elesToUpdate = cy.collection(); + var r = this; + var enqueue = function enqueue(eles) { + var dirtyStyleCaches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + elesToUpdate.merge(eles); + if (dirtyStyleCaches) { + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _p = ele._private; + var rstyle = _p.rstyle; + rstyle.clean = false; + rstyle.cleanConnected = false; + } + } + }; + r.binder(cy).on('bounds.* dirty.*', function onDirtyBounds(e) { + var ele = e.target; + enqueue(ele); + }).on('style.* background.*', function onDirtyStyle(e) { + var ele = e.target; + enqueue(ele, false); + }); + var updateEleCalcs = function updateEleCalcs(willDraw) { + if (willDraw) { + var fns = r.onUpdateEleCalcsFns; + + // because we need to have up-to-date style (e.g. stylesheet mappers) + // before calculating rendered style (and pstyle might not be called yet) + elesToUpdate.cleanStyle(); + for (var i = 0; i < elesToUpdate.length; i++) { + var ele = elesToUpdate[i]; + var rstyle = ele._private.rstyle; + if (ele.isNode() && !rstyle.cleanConnected) { + enqueue(ele.connectedEdges()); + rstyle.cleanConnected = true; + } + } + if (fns) { + for (var _i = 0; _i < fns.length; _i++) { + var fn = fns[_i]; + fn(willDraw, elesToUpdate); + } + } + r.recalculateRenderedStyle(elesToUpdate); + elesToUpdate = cy.collection(); + } + }; + r.flushRenderedStyleQueue = function () { + updateEleCalcs(true); + }; + r.beforeRender(updateEleCalcs, r.beforeRenderPriorities.eleCalcs); + }; + BRp$7.onUpdateEleCalcs = function (fn) { + var fns = this.onUpdateEleCalcsFns = this.onUpdateEleCalcsFns || []; + fns.push(fn); + }; + BRp$7.recalculateRenderedStyle = function (eles, useCache) { + var isCleanConnected = function isCleanConnected(ele) { + return ele._private.rstyle.cleanConnected; + }; + var edges = []; + var nodes = []; + + // the renderer can't be used for calcs when destroyed, e.g. ele.boundingBox() + if (this.destroyed) { + return; + } + + // use cache by default for perf + if (useCache === undefined) { + useCache = true; + } + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var _p = ele._private; + var rstyle = _p.rstyle; + + // an edge may be implicitly dirty b/c of one of its connected nodes + // (and a request for recalc may come in between frames) + if (ele.isEdge() && (!isCleanConnected(ele.source()) || !isCleanConnected(ele.target()))) { + rstyle.clean = false; + } + + // only update if dirty and in graph + if (useCache && rstyle.clean || ele.removed()) { + continue; + } + + // only update if not display: none + if (ele.pstyle('display').value === 'none') { + continue; + } + if (_p.group === 'nodes') { + nodes.push(ele); + } else { + // edges + edges.push(ele); + } + rstyle.clean = true; + } + + // update node data from projections + for (var _i2 = 0; _i2 < nodes.length; _i2++) { + var _ele = nodes[_i2]; + var _p2 = _ele._private; + var _rstyle = _p2.rstyle; + var pos = _ele.position(); + this.recalculateNodeLabelProjection(_ele); + _rstyle.nodeX = pos.x; + _rstyle.nodeY = pos.y; + _rstyle.nodeW = _ele.pstyle('width').pfValue; + _rstyle.nodeH = _ele.pstyle('height').pfValue; + } + this.recalculateEdgeProjections(edges); + + // update edge data from projections + for (var _i3 = 0; _i3 < edges.length; _i3++) { + var _ele2 = edges[_i3]; + var _p3 = _ele2._private; + var _rstyle2 = _p3.rstyle; + var rs = _p3.rscratch; + + // update rstyle positions + _rstyle2.srcX = rs.arrowStartX; + _rstyle2.srcY = rs.arrowStartY; + _rstyle2.tgtX = rs.arrowEndX; + _rstyle2.tgtY = rs.arrowEndY; + _rstyle2.midX = rs.midX; + _rstyle2.midY = rs.midY; + _rstyle2.labelAngle = rs.labelAngle; + _rstyle2.sourceLabelAngle = rs.sourceLabelAngle; + _rstyle2.targetLabelAngle = rs.targetLabelAngle; + } + }; + + var BRp$6 = {}; + BRp$6.updateCachedGrabbedEles = function () { + var eles = this.cachedZSortedEles; + if (!eles) { + // just let this be recalculated on the next z sort tick + return; + } + eles.drag = []; + eles.nondrag = []; + var grabTargets = []; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var rs = ele._private.rscratch; + if (ele.grabbed() && !ele.isParent()) { + grabTargets.push(ele); + } else if (rs.inDragLayer) { + eles.drag.push(ele); + } else { + eles.nondrag.push(ele); + } + } + + // put the grab target nodes last so it's on top of its neighbourhood + for (var i = 0; i < grabTargets.length; i++) { + var ele = grabTargets[i]; + eles.drag.push(ele); + } + }; + BRp$6.invalidateCachedZSortedEles = function () { + this.cachedZSortedEles = null; + }; + BRp$6.getCachedZSortedEles = function (forceRecalc) { + if (forceRecalc || !this.cachedZSortedEles) { + var eles = this.cy.mutableElements().toArray(); + eles.sort(zIndexSort); + eles.interactive = eles.filter(function (ele) { + return ele.interactive(); + }); + this.cachedZSortedEles = eles; + this.updateCachedGrabbedEles(); + } else { + eles = this.cachedZSortedEles; + } + return eles; + }; + + var BRp$5 = {}; + [BRp$e, BRp$d, BRp$c, BRp$b, BRp$a, BRp$9, BRp$8, BRp$7, BRp$6].forEach(function (props) { + extend(BRp$5, props); + }); + + var BRp$4 = {}; + BRp$4.getCachedImage = function (url, crossOrigin, onLoad) { + var r = this; + var imageCache = r.imageCache = r.imageCache || {}; + var cache = imageCache[url]; + if (cache) { + if (!cache.image.complete) { + cache.image.addEventListener('load', onLoad); + } + return cache.image; + } else { + cache = imageCache[url] = imageCache[url] || {}; + var image = cache.image = new Image(); // eslint-disable-line no-undef + + image.addEventListener('load', onLoad); + image.addEventListener('error', function () { + image.error = true; + }); + + // #1582 safari doesn't load data uris with crossOrigin properly + // https://bugs.webkit.org/show_bug.cgi?id=123978 + var dataUriPrefix = 'data:'; + var isDataUri = url.substring(0, dataUriPrefix.length).toLowerCase() === dataUriPrefix; + if (!isDataUri) { + // if crossorigin is 'null'(stringified), then manually set it to null + crossOrigin = crossOrigin === 'null' ? null : crossOrigin; + image.crossOrigin = crossOrigin; // prevent tainted canvas + } + + image.src = url; + return image; + } + }; + + var BRp$3 = {}; + + /* global document, window, ResizeObserver, MutationObserver */ + + BRp$3.registerBinding = function (target, event, handler, useCapture) { + // eslint-disable-line no-unused-vars + var args = Array.prototype.slice.apply(arguments, [1]); // copy + var b = this.binder(target); + return b.on.apply(b, args); + }; + BRp$3.binder = function (tgt) { + var r = this; + var containerWindow = r.cy.window(); + var tgtIsDom = tgt === containerWindow || tgt === containerWindow.document || tgt === containerWindow.document.body || domElement(tgt); + if (r.supportsPassiveEvents == null) { + // from https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection + var supportsPassive = false; + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get() { + supportsPassive = true; + return true; + } + }); + containerWindow.addEventListener('test', null, opts); + } catch (err) { + // not supported + } + r.supportsPassiveEvents = supportsPassive; + } + var on = function on(event, handler, useCapture) { + var args = Array.prototype.slice.call(arguments); + if (tgtIsDom && r.supportsPassiveEvents) { + // replace useCapture w/ opts obj + args[2] = { + capture: useCapture != null ? useCapture : false, + passive: false, + once: false + }; + } + r.bindings.push({ + target: tgt, + args: args + }); + (tgt.addEventListener || tgt.on).apply(tgt, args); + return this; + }; + return { + on: on, + addEventListener: on, + addListener: on, + bind: on + }; + }; + BRp$3.nodeIsDraggable = function (node) { + return node && node.isNode() && !node.locked() && node.grabbable(); + }; + BRp$3.nodeIsGrabbable = function (node) { + return this.nodeIsDraggable(node) && node.interactive(); + }; + BRp$3.load = function () { + var r = this; + var containerWindow = r.cy.window(); + var isSelected = function isSelected(ele) { + return ele.selected(); + }; + var triggerEvents = function triggerEvents(target, names, e, position) { + if (target == null) { + target = r.cy; + } + for (var i = 0; i < names.length; i++) { + var name = names[i]; + target.emit({ + originalEvent: e, + type: name, + position: position + }); + } + }; + var isMultSelKeyDown = function isMultSelKeyDown(e) { + return e.shiftKey || e.metaKey || e.ctrlKey; // maybe e.altKey + }; + + var allowPanningPassthrough = function allowPanningPassthrough(down, downs) { + var allowPassthrough = true; + if (r.cy.hasCompoundNodes() && down && down.pannable()) { + // a grabbable compound node below the ele => no passthrough panning + for (var i = 0; downs && i < downs.length; i++) { + var down = downs[i]; + + //if any parent node in event hierarchy isn't pannable, reject passthrough + if (down.isNode() && down.isParent() && !down.pannable()) { + allowPassthrough = false; + break; + } + } + } else { + allowPassthrough = true; + } + return allowPassthrough; + }; + var setGrabbed = function setGrabbed(ele) { + ele[0]._private.grabbed = true; + }; + var setFreed = function setFreed(ele) { + ele[0]._private.grabbed = false; + }; + var setInDragLayer = function setInDragLayer(ele) { + ele[0]._private.rscratch.inDragLayer = true; + }; + var setOutDragLayer = function setOutDragLayer(ele) { + ele[0]._private.rscratch.inDragLayer = false; + }; + var setGrabTarget = function setGrabTarget(ele) { + ele[0]._private.rscratch.isGrabTarget = true; + }; + var removeGrabTarget = function removeGrabTarget(ele) { + ele[0]._private.rscratch.isGrabTarget = false; + }; + var addToDragList = function addToDragList(ele, opts) { + var list = opts.addToList; + var listHasEle = list.has(ele); + if (!listHasEle && ele.grabbable() && !ele.locked()) { + list.merge(ele); + setGrabbed(ele); + } + }; + + // helper function to determine which child nodes and inner edges + // of a compound node to be dragged as well as the grabbed and selected nodes + var addDescendantsToDrag = function addDescendantsToDrag(node, opts) { + if (!node.cy().hasCompoundNodes()) { + return; + } + if (opts.inDragLayer == null && opts.addToList == null) { + return; + } // nothing to do + + var innerNodes = node.descendants(); + if (opts.inDragLayer) { + innerNodes.forEach(setInDragLayer); + innerNodes.connectedEdges().forEach(setInDragLayer); + } + if (opts.addToList) { + addToDragList(innerNodes, opts); + } + }; + + // adds the given nodes and its neighbourhood to the drag layer + var addNodesToDrag = function addNodesToDrag(nodes, opts) { + opts = opts || {}; + var hasCompoundNodes = nodes.cy().hasCompoundNodes(); + if (opts.inDragLayer) { + nodes.forEach(setInDragLayer); + nodes.neighborhood().stdFilter(function (ele) { + return !hasCompoundNodes || ele.isEdge(); + }).forEach(setInDragLayer); + } + if (opts.addToList) { + nodes.forEach(function (ele) { + addToDragList(ele, opts); + }); + } + addDescendantsToDrag(nodes, opts); // always add to drag + + // also add nodes and edges related to the topmost ancestor + updateAncestorsInDragLayer(nodes, { + inDragLayer: opts.inDragLayer + }); + r.updateCachedGrabbedEles(); + }; + var addNodeToDrag = addNodesToDrag; + var freeDraggedElements = function freeDraggedElements(grabbedEles) { + if (!grabbedEles) { + return; + } + + // just go over all elements rather than doing a bunch of (possibly expensive) traversals + r.getCachedZSortedEles().forEach(function (ele) { + setFreed(ele); + setOutDragLayer(ele); + removeGrabTarget(ele); + }); + r.updateCachedGrabbedEles(); + }; + + // helper function to determine which ancestor nodes and edges should go + // to the drag layer (or should be removed from drag layer). + var updateAncestorsInDragLayer = function updateAncestorsInDragLayer(node, opts) { + if (opts.inDragLayer == null && opts.addToList == null) { + return; + } // nothing to do + + if (!node.cy().hasCompoundNodes()) { + return; + } + + // find top-level parent + var parent = node.ancestors().orphans(); + + // no parent node: no nodes to add to the drag layer + if (parent.same(node)) { + return; + } + var nodes = parent.descendants().spawnSelf().merge(parent).unmerge(node).unmerge(node.descendants()); + var edges = nodes.connectedEdges(); + if (opts.inDragLayer) { + edges.forEach(setInDragLayer); + nodes.forEach(setInDragLayer); + } + if (opts.addToList) { + nodes.forEach(function (ele) { + addToDragList(ele, opts); + }); + } + }; + var blurActiveDomElement = function blurActiveDomElement() { + if (document.activeElement != null && document.activeElement.blur != null) { + document.activeElement.blur(); + } + }; + var haveMutationsApi = typeof MutationObserver !== 'undefined'; + var haveResizeObserverApi = typeof ResizeObserver !== 'undefined'; + + // watch for when the cy container is removed from the dom + if (haveMutationsApi) { + r.removeObserver = new MutationObserver(function (mutns) { + // eslint-disable-line no-undef + for (var i = 0; i < mutns.length; i++) { + var mutn = mutns[i]; + var rNodes = mutn.removedNodes; + if (rNodes) { + for (var j = 0; j < rNodes.length; j++) { + var rNode = rNodes[j]; + if (rNode === r.container) { + r.destroy(); + break; + } + } + } + } + }); + if (r.container.parentNode) { + r.removeObserver.observe(r.container.parentNode, { + childList: true + }); + } + } else { + r.registerBinding(r.container, 'DOMNodeRemoved', function (e) { + // eslint-disable-line no-unused-vars + r.destroy(); + }); + } + var onResize = debounce_1(function () { + r.cy.resize(); + }, 100); + if (haveMutationsApi) { + r.styleObserver = new MutationObserver(onResize); // eslint-disable-line no-undef + + r.styleObserver.observe(r.container, { + attributes: true + }); + } + + // auto resize + r.registerBinding(containerWindow, 'resize', onResize); // eslint-disable-line no-undef + + if (haveResizeObserverApi) { + r.resizeObserver = new ResizeObserver(onResize); // eslint-disable-line no-undef + + r.resizeObserver.observe(r.container); + } + var forEachUp = function forEachUp(domEle, fn) { + while (domEle != null) { + fn(domEle); + domEle = domEle.parentNode; + } + }; + var invalidateCoords = function invalidateCoords() { + r.invalidateContainerClientCoordsCache(); + }; + forEachUp(r.container, function (domEle) { + r.registerBinding(domEle, 'transitionend', invalidateCoords); + r.registerBinding(domEle, 'animationend', invalidateCoords); + r.registerBinding(domEle, 'scroll', invalidateCoords); + }); + + // stop right click menu from appearing on cy + r.registerBinding(r.container, 'contextmenu', function (e) { + e.preventDefault(); + }); + var inBoxSelection = function inBoxSelection() { + return r.selection[4] !== 0; + }; + var eventInContainer = function eventInContainer(e) { + // save cycles if mouse events aren't to be captured + var containerPageCoords = r.findContainerClientCoords(); + var x = containerPageCoords[0]; + var y = containerPageCoords[1]; + var width = containerPageCoords[2]; + var height = containerPageCoords[3]; + var positions = e.touches ? e.touches : [e]; + var atLeastOnePosInside = false; + for (var i = 0; i < positions.length; i++) { + var p = positions[i]; + if (x <= p.clientX && p.clientX <= x + width && y <= p.clientY && p.clientY <= y + height) { + atLeastOnePosInside = true; + break; + } + } + if (!atLeastOnePosInside) { + return false; + } + var container = r.container; + var target = e.target; + var tParent = target.parentNode; + var containerIsTarget = false; + while (tParent) { + if (tParent === container) { + containerIsTarget = true; + break; + } + tParent = tParent.parentNode; + } + if (!containerIsTarget) { + return false; + } // if target is outisde cy container, then this event is not for us + + return true; + }; + + // Primary key + r.registerBinding(r.container, 'mousedown', function mousedownHandler(e) { + if (!eventInContainer(e)) { + return; + } + e.preventDefault(); + blurActiveDomElement(); + r.hoverData.capture = true; + r.hoverData.which = e.which; + var cy = r.cy; + var gpos = [e.clientX, e.clientY]; + var pos = r.projectIntoViewport(gpos[0], gpos[1]); + var select = r.selection; + var nears = r.findNearestElements(pos[0], pos[1], true, false); + var near = nears[0]; + var draggedElements = r.dragData.possibleDragElements; + r.hoverData.mdownPos = pos; + r.hoverData.mdownGPos = gpos; + var checkForTaphold = function checkForTaphold() { + r.hoverData.tapholdCancelled = false; + clearTimeout(r.hoverData.tapholdTimeout); + r.hoverData.tapholdTimeout = setTimeout(function () { + if (r.hoverData.tapholdCancelled) { + return; + } else { + var ele = r.hoverData.down; + if (ele) { + ele.emit({ + originalEvent: e, + type: 'taphold', + position: { + x: pos[0], + y: pos[1] + } + }); + } else { + cy.emit({ + originalEvent: e, + type: 'taphold', + position: { + x: pos[0], + y: pos[1] + } + }); + } + } + }, r.tapholdDuration); + }; + + // Right click button + if (e.which == 3) { + r.hoverData.cxtStarted = true; + var cxtEvt = { + originalEvent: e, + type: 'cxttapstart', + position: { + x: pos[0], + y: pos[1] + } + }; + if (near) { + near.activate(); + near.emit(cxtEvt); + r.hoverData.down = near; + } else { + cy.emit(cxtEvt); + } + r.hoverData.downTime = new Date().getTime(); + r.hoverData.cxtDragged = false; + + // Primary button + } else if (e.which == 1) { + if (near) { + near.activate(); + } + + // Element dragging + { + // If something is under the cursor and it is draggable, prepare to grab it + if (near != null) { + if (r.nodeIsGrabbable(near)) { + var makeEvent = function makeEvent(type) { + return { + originalEvent: e, + type: type, + position: { + x: pos[0], + y: pos[1] + } + }; + }; + var triggerGrab = function triggerGrab(ele) { + ele.emit(makeEvent('grab')); + }; + setGrabTarget(near); + if (!near.selected()) { + draggedElements = r.dragData.possibleDragElements = cy.collection(); + addNodeToDrag(near, { + addToList: draggedElements + }); + near.emit(makeEvent('grabon')).emit(makeEvent('grab')); + } else { + draggedElements = r.dragData.possibleDragElements = cy.collection(); + var selectedNodes = cy.$(function (ele) { + return ele.isNode() && ele.selected() && r.nodeIsGrabbable(ele); + }); + addNodesToDrag(selectedNodes, { + addToList: draggedElements + }); + near.emit(makeEvent('grabon')); + selectedNodes.forEach(triggerGrab); + } + r.redrawHint('eles', true); + r.redrawHint('drag', true); + } + } + r.hoverData.down = near; + r.hoverData.downs = nears; + r.hoverData.downTime = new Date().getTime(); + } + triggerEvents(near, ['mousedown', 'tapstart', 'vmousedown'], e, { + x: pos[0], + y: pos[1] + }); + if (near == null) { + select[4] = 1; + r.data.bgActivePosistion = { + x: pos[0], + y: pos[1] + }; + r.redrawHint('select', true); + r.redraw(); + } else if (near.pannable()) { + select[4] = 1; // for future pan + } + + checkForTaphold(); + } + + // Initialize selection box coordinates + select[0] = select[2] = pos[0]; + select[1] = select[3] = pos[1]; + }, false); + r.registerBinding(containerWindow, 'mousemove', function mousemoveHandler(e) { + // eslint-disable-line no-undef + var capture = r.hoverData.capture; + if (!capture && !eventInContainer(e)) { + return; + } + var preventDefault = false; + var cy = r.cy; + var zoom = cy.zoom(); + var gpos = [e.clientX, e.clientY]; + var pos = r.projectIntoViewport(gpos[0], gpos[1]); + var mdownPos = r.hoverData.mdownPos; + var mdownGPos = r.hoverData.mdownGPos; + var select = r.selection; + var near = null; + if (!r.hoverData.draggingEles && !r.hoverData.dragging && !r.hoverData.selecting) { + near = r.findNearestElement(pos[0], pos[1], true, false); + } + var last = r.hoverData.last; + var down = r.hoverData.down; + var disp = [pos[0] - select[2], pos[1] - select[3]]; + var draggedElements = r.dragData.possibleDragElements; + var isOverThresholdDrag; + if (mdownGPos) { + var dx = gpos[0] - mdownGPos[0]; + var dx2 = dx * dx; + var dy = gpos[1] - mdownGPos[1]; + var dy2 = dy * dy; + var dist2 = dx2 + dy2; + r.hoverData.isOverThresholdDrag = isOverThresholdDrag = dist2 >= r.desktopTapThreshold2; + } + var multSelKeyDown = isMultSelKeyDown(e); + if (isOverThresholdDrag) { + r.hoverData.tapholdCancelled = true; + } + var updateDragDelta = function updateDragDelta() { + var dragDelta = r.hoverData.dragDelta = r.hoverData.dragDelta || []; + if (dragDelta.length === 0) { + dragDelta.push(disp[0]); + dragDelta.push(disp[1]); + } else { + dragDelta[0] += disp[0]; + dragDelta[1] += disp[1]; + } + }; + preventDefault = true; + triggerEvents(near, ['mousemove', 'vmousemove', 'tapdrag'], e, { + x: pos[0], + y: pos[1] + }); + var goIntoBoxMode = function goIntoBoxMode() { + r.data.bgActivePosistion = undefined; + if (!r.hoverData.selecting) { + cy.emit({ + originalEvent: e, + type: 'boxstart', + position: { + x: pos[0], + y: pos[1] + } + }); + } + select[4] = 1; + r.hoverData.selecting = true; + r.redrawHint('select', true); + r.redraw(); + }; + + // trigger context drag if rmouse down + if (r.hoverData.which === 3) { + // but only if over threshold + if (isOverThresholdDrag) { + var cxtEvt = { + originalEvent: e, + type: 'cxtdrag', + position: { + x: pos[0], + y: pos[1] + } + }; + if (down) { + down.emit(cxtEvt); + } else { + cy.emit(cxtEvt); + } + r.hoverData.cxtDragged = true; + if (!r.hoverData.cxtOver || near !== r.hoverData.cxtOver) { + if (r.hoverData.cxtOver) { + r.hoverData.cxtOver.emit({ + originalEvent: e, + type: 'cxtdragout', + position: { + x: pos[0], + y: pos[1] + } + }); + } + r.hoverData.cxtOver = near; + if (near) { + near.emit({ + originalEvent: e, + type: 'cxtdragover', + position: { + x: pos[0], + y: pos[1] + } + }); + } + } + } + + // Check if we are drag panning the entire graph + } else if (r.hoverData.dragging) { + preventDefault = true; + if (cy.panningEnabled() && cy.userPanningEnabled()) { + var deltaP; + if (r.hoverData.justStartedPan) { + var mdPos = r.hoverData.mdownPos; + deltaP = { + x: (pos[0] - mdPos[0]) * zoom, + y: (pos[1] - mdPos[1]) * zoom + }; + r.hoverData.justStartedPan = false; + } else { + deltaP = { + x: disp[0] * zoom, + y: disp[1] * zoom + }; + } + cy.panBy(deltaP); + cy.emit('dragpan'); + r.hoverData.dragged = true; + } + + // Needs reproject due to pan changing viewport + pos = r.projectIntoViewport(e.clientX, e.clientY); + + // Checks primary button down & out of time & mouse not moved much + } else if (select[4] == 1 && (down == null || down.pannable())) { + if (isOverThresholdDrag) { + if (!r.hoverData.dragging && cy.boxSelectionEnabled() && (multSelKeyDown || !cy.panningEnabled() || !cy.userPanningEnabled())) { + goIntoBoxMode(); + } else if (!r.hoverData.selecting && cy.panningEnabled() && cy.userPanningEnabled()) { + var allowPassthrough = allowPanningPassthrough(down, r.hoverData.downs); + if (allowPassthrough) { + r.hoverData.dragging = true; + r.hoverData.justStartedPan = true; + select[4] = 0; + r.data.bgActivePosistion = array2point(mdownPos); + r.redrawHint('select', true); + r.redraw(); + } + } + if (down && down.pannable() && down.active()) { + down.unactivate(); + } + } + } else { + if (down && down.pannable() && down.active()) { + down.unactivate(); + } + if ((!down || !down.grabbed()) && near != last) { + if (last) { + triggerEvents(last, ['mouseout', 'tapdragout'], e, { + x: pos[0], + y: pos[1] + }); + } + if (near) { + triggerEvents(near, ['mouseover', 'tapdragover'], e, { + x: pos[0], + y: pos[1] + }); + } + r.hoverData.last = near; + } + if (down) { + if (isOverThresholdDrag) { + // then we can take action + + if (cy.boxSelectionEnabled() && multSelKeyDown) { + // then selection overrides + if (down && down.grabbed()) { + freeDraggedElements(draggedElements); + down.emit('freeon'); + draggedElements.emit('free'); + if (r.dragData.didDrag) { + down.emit('dragfreeon'); + draggedElements.emit('dragfree'); + } + } + goIntoBoxMode(); + } else if (down && down.grabbed() && r.nodeIsDraggable(down)) { + // drag node + var justStartedDrag = !r.dragData.didDrag; + if (justStartedDrag) { + r.redrawHint('eles', true); + } + r.dragData.didDrag = true; // indicate that we actually did drag the node + + // now, add the elements to the drag layer if not done already + if (!r.hoverData.draggingEles) { + addNodesToDrag(draggedElements, { + inDragLayer: true + }); + } + var totalShift = { + x: 0, + y: 0 + }; + if (number$1(disp[0]) && number$1(disp[1])) { + totalShift.x += disp[0]; + totalShift.y += disp[1]; + if (justStartedDrag) { + var dragDelta = r.hoverData.dragDelta; + if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) { + totalShift.x += dragDelta[0]; + totalShift.y += dragDelta[1]; + } + } + } + r.hoverData.draggingEles = true; + draggedElements.silentShift(totalShift).emit('position drag'); + r.redrawHint('drag', true); + r.redraw(); + } + } else { + // otherwise save drag delta for when we actually start dragging so the relative grab pos is constant + updateDragDelta(); + } + } + + // prevent the dragging from triggering text selection on the page + preventDefault = true; + } + select[2] = pos[0]; + select[3] = pos[1]; + if (preventDefault) { + if (e.stopPropagation) e.stopPropagation(); + if (e.preventDefault) e.preventDefault(); + return false; + } + }, false); + var clickTimeout, didDoubleClick, prevClickTimeStamp; + r.registerBinding(containerWindow, 'mouseup', function mouseupHandler(e) { + // eslint-disable-line no-undef + var capture = r.hoverData.capture; + if (!capture) { + return; + } + r.hoverData.capture = false; + var cy = r.cy; + var pos = r.projectIntoViewport(e.clientX, e.clientY); + var select = r.selection; + var near = r.findNearestElement(pos[0], pos[1], true, false); + var draggedElements = r.dragData.possibleDragElements; + var down = r.hoverData.down; + var multSelKeyDown = isMultSelKeyDown(e); + if (r.data.bgActivePosistion) { + r.redrawHint('select', true); + r.redraw(); + } + r.hoverData.tapholdCancelled = true; + r.data.bgActivePosistion = undefined; // not active bg now + + if (down) { + down.unactivate(); + } + if (r.hoverData.which === 3) { + var cxtEvt = { + originalEvent: e, + type: 'cxttapend', + position: { + x: pos[0], + y: pos[1] + } + }; + if (down) { + down.emit(cxtEvt); + } else { + cy.emit(cxtEvt); + } + if (!r.hoverData.cxtDragged) { + var cxtTap = { + originalEvent: e, + type: 'cxttap', + position: { + x: pos[0], + y: pos[1] + } + }; + if (down) { + down.emit(cxtTap); + } else { + cy.emit(cxtTap); + } + } + r.hoverData.cxtDragged = false; + r.hoverData.which = null; + } else if (r.hoverData.which === 1) { + triggerEvents(near, ['mouseup', 'tapend', 'vmouseup'], e, { + x: pos[0], + y: pos[1] + }); + if (!r.dragData.didDrag && + // didn't move a node around + !r.hoverData.dragged && + // didn't pan + !r.hoverData.selecting && + // not box selection + !r.hoverData.isOverThresholdDrag // didn't move too much + ) { + triggerEvents(down, ["click", "tap", "vclick"], e, { + x: pos[0], + y: pos[1] + }); + didDoubleClick = false; + if (e.timeStamp - prevClickTimeStamp <= cy.multiClickDebounceTime()) { + clickTimeout && clearTimeout(clickTimeout); + didDoubleClick = true; + prevClickTimeStamp = null; + triggerEvents(down, ["dblclick", "dbltap", "vdblclick"], e, { + x: pos[0], + y: pos[1] + }); + } else { + clickTimeout = setTimeout(function () { + if (didDoubleClick) return; + triggerEvents(down, ["oneclick", "onetap", "voneclick"], e, { + x: pos[0], + y: pos[1] + }); + }, cy.multiClickDebounceTime()); + prevClickTimeStamp = e.timeStamp; + } + } + + // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something + if (down == null // not mousedown on node + && !r.dragData.didDrag // didn't move the node around + && !r.hoverData.selecting // not box selection + && !r.hoverData.dragged // didn't pan + && !isMultSelKeyDown(e)) { + cy.$(isSelected).unselect(['tapunselect']); + if (draggedElements.length > 0) { + r.redrawHint('eles', true); + } + r.dragData.possibleDragElements = draggedElements = cy.collection(); + } + + // Single selection + if (near == down && !r.dragData.didDrag && !r.hoverData.selecting) { + if (near != null && near._private.selectable) { + if (r.hoverData.dragging) ; else if (cy.selectionType() === 'additive' || multSelKeyDown) { + if (near.selected()) { + near.unselect(['tapunselect']); + } else { + near.select(['tapselect']); + } + } else { + if (!multSelKeyDown) { + cy.$(isSelected).unmerge(near).unselect(['tapunselect']); + near.select(['tapselect']); + } + } + r.redrawHint('eles', true); + } + } + if (r.hoverData.selecting) { + var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3])); + r.redrawHint('select', true); + if (box.length > 0) { + r.redrawHint('eles', true); + } + cy.emit({ + type: 'boxend', + originalEvent: e, + position: { + x: pos[0], + y: pos[1] + } + }); + var eleWouldBeSelected = function eleWouldBeSelected(ele) { + return ele.selectable() && !ele.selected(); + }; + if (cy.selectionType() === 'additive') { + box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect'); + } else { + if (!multSelKeyDown) { + cy.$(isSelected).unmerge(box).unselect(); + } + box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect'); + } + + // always need redraw in case eles unselectable + r.redraw(); + } + + // Cancel drag pan + if (r.hoverData.dragging) { + r.hoverData.dragging = false; + r.redrawHint('select', true); + r.redrawHint('eles', true); + r.redraw(); + } + if (!select[4]) { + r.redrawHint('drag', true); + r.redrawHint('eles', true); + var downWasGrabbed = down && down.grabbed(); + freeDraggedElements(draggedElements); + if (downWasGrabbed) { + down.emit('freeon'); + draggedElements.emit('free'); + if (r.dragData.didDrag) { + down.emit('dragfreeon'); + draggedElements.emit('dragfree'); + } + } + } + } // else not right mouse + + select[4] = 0; + r.hoverData.down = null; + r.hoverData.cxtStarted = false; + r.hoverData.draggingEles = false; + r.hoverData.selecting = false; + r.hoverData.isOverThresholdDrag = false; + r.dragData.didDrag = false; + r.hoverData.dragged = false; + r.hoverData.dragDelta = []; + r.hoverData.mdownPos = null; + r.hoverData.mdownGPos = null; + }, false); + var wheelHandler = function wheelHandler(e) { + if (r.scrollingPage) { + return; + } // while scrolling, ignore wheel-to-zoom + + var cy = r.cy; + var zoom = cy.zoom(); + var pan = cy.pan(); + var pos = r.projectIntoViewport(e.clientX, e.clientY); + var rpos = [pos[0] * zoom + pan.x, pos[1] * zoom + pan.y]; + if (r.hoverData.draggingEles || r.hoverData.dragging || r.hoverData.cxtStarted || inBoxSelection()) { + // if pan dragging or cxt dragging, wheel movements make no zoom + e.preventDefault(); + return; + } + if (cy.panningEnabled() && cy.userPanningEnabled() && cy.zoomingEnabled() && cy.userZoomingEnabled()) { + e.preventDefault(); + r.data.wheelZooming = true; + clearTimeout(r.data.wheelTimeout); + r.data.wheelTimeout = setTimeout(function () { + r.data.wheelZooming = false; + r.redrawHint('eles', true); + r.redraw(); + }, 150); + var diff; + if (e.deltaY != null) { + diff = e.deltaY / -250; + } else if (e.wheelDeltaY != null) { + diff = e.wheelDeltaY / 1000; + } else { + diff = e.wheelDelta / 1000; + } + diff = diff * r.wheelSensitivity; + var needsWheelFix = e.deltaMode === 1; + if (needsWheelFix) { + // fixes slow wheel events on ff/linux and ff/windows + diff *= 33; + } + var newZoom = cy.zoom() * Math.pow(10, diff); + if (e.type === 'gesturechange') { + newZoom = r.gestureStartZoom * e.scale; + } + cy.zoom({ + level: newZoom, + renderedPosition: { + x: rpos[0], + y: rpos[1] + } + }); + cy.emit(e.type === 'gesturechange' ? 'pinchzoom' : 'scrollzoom'); + } + }; + + // Functions to help with whether mouse wheel should trigger zooming + // -- + r.registerBinding(r.container, 'wheel', wheelHandler, true); + + // disable nonstandard wheel events + // r.registerBinding(r.container, 'mousewheel', wheelHandler, true); + // r.registerBinding(r.container, 'DOMMouseScroll', wheelHandler, true); + // r.registerBinding(r.container, 'MozMousePixelScroll', wheelHandler, true); // older firefox + + r.registerBinding(containerWindow, 'scroll', function scrollHandler(e) { + // eslint-disable-line no-unused-vars + r.scrollingPage = true; + clearTimeout(r.scrollingPageTimeout); + r.scrollingPageTimeout = setTimeout(function () { + r.scrollingPage = false; + }, 250); + }, true); + + // desktop safari pinch to zoom start + r.registerBinding(r.container, 'gesturestart', function gestureStartHandler(e) { + r.gestureStartZoom = r.cy.zoom(); + if (!r.hasTouchStarted) { + // don't affect touch devices like iphone + e.preventDefault(); + } + }, true); + r.registerBinding(r.container, 'gesturechange', function (e) { + if (!r.hasTouchStarted) { + // don't affect touch devices like iphone + wheelHandler(e); + } + }, true); + + // Functions to help with handling mouseout/mouseover on the Cytoscape container + // Handle mouseout on Cytoscape container + r.registerBinding(r.container, 'mouseout', function mouseOutHandler(e) { + var pos = r.projectIntoViewport(e.clientX, e.clientY); + r.cy.emit({ + originalEvent: e, + type: 'mouseout', + position: { + x: pos[0], + y: pos[1] + } + }); + }, false); + r.registerBinding(r.container, 'mouseover', function mouseOverHandler(e) { + var pos = r.projectIntoViewport(e.clientX, e.clientY); + r.cy.emit({ + originalEvent: e, + type: 'mouseover', + position: { + x: pos[0], + y: pos[1] + } + }); + }, false); + var f1x1, f1y1, f2x1, f2y1; // starting points for pinch-to-zoom + var distance1, distance1Sq; // initial distance between finger 1 and finger 2 for pinch-to-zoom + var center1, modelCenter1; // center point on start pinch to zoom + var offsetLeft, offsetTop; + var containerWidth, containerHeight; + var twoFingersStartInside; + var distance = function distance(x1, y1, x2, y2) { + return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + }; + var distanceSq = function distanceSq(x1, y1, x2, y2) { + return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1); + }; + var touchstartHandler; + r.registerBinding(r.container, 'touchstart', touchstartHandler = function touchstartHandler(e) { + r.hasTouchStarted = true; + if (!eventInContainer(e)) { + return; + } + blurActiveDomElement(); + r.touchData.capture = true; + r.data.bgActivePosistion = undefined; + var cy = r.cy; + var now = r.touchData.now; + var earlier = r.touchData.earlier; + if (e.touches[0]) { + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + if (e.touches[1]) { + var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); + now[2] = pos[0]; + now[3] = pos[1]; + } + if (e.touches[2]) { + var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); + now[4] = pos[0]; + now[5] = pos[1]; + } + + // record starting points for pinch-to-zoom + if (e.touches[1]) { + r.touchData.singleTouchMoved = true; + freeDraggedElements(r.dragData.touchDragEles); + var offsets = r.findContainerClientCoords(); + offsetLeft = offsets[0]; + offsetTop = offsets[1]; + containerWidth = offsets[2]; + containerHeight = offsets[3]; + f1x1 = e.touches[0].clientX - offsetLeft; + f1y1 = e.touches[0].clientY - offsetTop; + f2x1 = e.touches[1].clientX - offsetLeft; + f2y1 = e.touches[1].clientY - offsetTop; + twoFingersStartInside = 0 <= f1x1 && f1x1 <= containerWidth && 0 <= f2x1 && f2x1 <= containerWidth && 0 <= f1y1 && f1y1 <= containerHeight && 0 <= f2y1 && f2y1 <= containerHeight; + var pan = cy.pan(); + var zoom = cy.zoom(); + distance1 = distance(f1x1, f1y1, f2x1, f2y1); + distance1Sq = distanceSq(f1x1, f1y1, f2x1, f2y1); + center1 = [(f1x1 + f2x1) / 2, (f1y1 + f2y1) / 2]; + modelCenter1 = [(center1[0] - pan.x) / zoom, (center1[1] - pan.y) / zoom]; + + // consider context tap + var cxtDistThreshold = 200; + var cxtDistThresholdSq = cxtDistThreshold * cxtDistThreshold; + if (distance1Sq < cxtDistThresholdSq && !e.touches[2]) { + var near1 = r.findNearestElement(now[0], now[1], true, true); + var near2 = r.findNearestElement(now[2], now[3], true, true); + if (near1 && near1.isNode()) { + near1.activate().emit({ + originalEvent: e, + type: 'cxttapstart', + position: { + x: now[0], + y: now[1] + } + }); + r.touchData.start = near1; + } else if (near2 && near2.isNode()) { + near2.activate().emit({ + originalEvent: e, + type: 'cxttapstart', + position: { + x: now[0], + y: now[1] + } + }); + r.touchData.start = near2; + } else { + cy.emit({ + originalEvent: e, + type: 'cxttapstart', + position: { + x: now[0], + y: now[1] + } + }); + } + if (r.touchData.start) { + r.touchData.start._private.grabbed = false; + } + r.touchData.cxt = true; + r.touchData.cxtDragged = false; + r.data.bgActivePosistion = undefined; + r.redraw(); + return; + } + } + if (e.touches[2]) { + // ignore + + // safari on ios pans the page otherwise (normally you should be able to preventdefault on touchmove...) + if (cy.boxSelectionEnabled()) { + e.preventDefault(); + } + } else if (e.touches[1]) ; else if (e.touches[0]) { + var nears = r.findNearestElements(now[0], now[1], true, true); + var near = nears[0]; + if (near != null) { + near.activate(); + r.touchData.start = near; + r.touchData.starts = nears; + if (r.nodeIsGrabbable(near)) { + var draggedEles = r.dragData.touchDragEles = cy.collection(); + var selectedNodes = null; + r.redrawHint('eles', true); + r.redrawHint('drag', true); + if (near.selected()) { + // reset drag elements, since near will be added again + + selectedNodes = cy.$(function (ele) { + return ele.selected() && r.nodeIsGrabbable(ele); + }); + addNodesToDrag(selectedNodes, { + addToList: draggedEles + }); + } else { + addNodeToDrag(near, { + addToList: draggedEles + }); + } + setGrabTarget(near); + var makeEvent = function makeEvent(type) { + return { + originalEvent: e, + type: type, + position: { + x: now[0], + y: now[1] + } + }; + }; + near.emit(makeEvent('grabon')); + if (selectedNodes) { + selectedNodes.forEach(function (n) { + n.emit(makeEvent('grab')); + }); + } else { + near.emit(makeEvent('grab')); + } + } + } + triggerEvents(near, ['touchstart', 'tapstart', 'vmousedown'], e, { + x: now[0], + y: now[1] + }); + if (near == null) { + r.data.bgActivePosistion = { + x: pos[0], + y: pos[1] + }; + r.redrawHint('select', true); + r.redraw(); + } + + // Tap, taphold + // ----- + + r.touchData.singleTouchMoved = false; + r.touchData.singleTouchStartTime = +new Date(); + clearTimeout(r.touchData.tapholdTimeout); + r.touchData.tapholdTimeout = setTimeout(function () { + if (r.touchData.singleTouchMoved === false && !r.pinching // if pinching, then taphold unselect shouldn't take effect + && !r.touchData.selecting // box selection shouldn't allow taphold through + ) { + triggerEvents(r.touchData.start, ['taphold'], e, { + x: now[0], + y: now[1] + }); + } + }, r.tapholdDuration); + } + if (e.touches.length >= 1) { + var sPos = r.touchData.startPosition = [null, null, null, null, null, null]; + for (var i = 0; i < now.length; i++) { + sPos[i] = earlier[i] = now[i]; + } + var touch0 = e.touches[0]; + r.touchData.startGPosition = [touch0.clientX, touch0.clientY]; + } + }, false); + var touchmoveHandler; + r.registerBinding(window, 'touchmove', touchmoveHandler = function touchmoveHandler(e) { + // eslint-disable-line no-undef + var capture = r.touchData.capture; + if (!capture && !eventInContainer(e)) { + return; + } + var select = r.selection; + var cy = r.cy; + var now = r.touchData.now; + var earlier = r.touchData.earlier; + var zoom = cy.zoom(); + if (e.touches[0]) { + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + if (e.touches[1]) { + var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); + now[2] = pos[0]; + now[3] = pos[1]; + } + if (e.touches[2]) { + var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); + now[4] = pos[0]; + now[5] = pos[1]; + } + var startGPos = r.touchData.startGPosition; + var isOverThresholdDrag; + if (capture && e.touches[0] && startGPos) { + var disp = []; + for (var j = 0; j < now.length; j++) { + disp[j] = now[j] - earlier[j]; + } + var dx = e.touches[0].clientX - startGPos[0]; + var dx2 = dx * dx; + var dy = e.touches[0].clientY - startGPos[1]; + var dy2 = dy * dy; + var dist2 = dx2 + dy2; + isOverThresholdDrag = dist2 >= r.touchTapThreshold2; + } + + // context swipe cancelling + if (capture && r.touchData.cxt) { + e.preventDefault(); + var f1x2 = e.touches[0].clientX - offsetLeft, + f1y2 = e.touches[0].clientY - offsetTop; + var f2x2 = e.touches[1].clientX - offsetLeft, + f2y2 = e.touches[1].clientY - offsetTop; + // var distance2 = distance( f1x2, f1y2, f2x2, f2y2 ); + var distance2Sq = distanceSq(f1x2, f1y2, f2x2, f2y2); + var factorSq = distance2Sq / distance1Sq; + var distThreshold = 150; + var distThresholdSq = distThreshold * distThreshold; + var factorThreshold = 1.5; + var factorThresholdSq = factorThreshold * factorThreshold; + + // cancel ctx gestures if the distance b/t the fingers increases + if (factorSq >= factorThresholdSq || distance2Sq >= distThresholdSq) { + r.touchData.cxt = false; + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + var cxtEvt = { + originalEvent: e, + type: 'cxttapend', + position: { + x: now[0], + y: now[1] + } + }; + if (r.touchData.start) { + r.touchData.start.unactivate().emit(cxtEvt); + r.touchData.start = null; + } else { + cy.emit(cxtEvt); + } + } + } + + // context swipe + if (capture && r.touchData.cxt) { + var cxtEvt = { + originalEvent: e, + type: 'cxtdrag', + position: { + x: now[0], + y: now[1] + } + }; + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + if (r.touchData.start) { + r.touchData.start.emit(cxtEvt); + } else { + cy.emit(cxtEvt); + } + if (r.touchData.start) { + r.touchData.start._private.grabbed = false; + } + r.touchData.cxtDragged = true; + var near = r.findNearestElement(now[0], now[1], true, true); + if (!r.touchData.cxtOver || near !== r.touchData.cxtOver) { + if (r.touchData.cxtOver) { + r.touchData.cxtOver.emit({ + originalEvent: e, + type: 'cxtdragout', + position: { + x: now[0], + y: now[1] + } + }); + } + r.touchData.cxtOver = near; + if (near) { + near.emit({ + originalEvent: e, + type: 'cxtdragover', + position: { + x: now[0], + y: now[1] + } + }); + } + } + + // box selection + } else if (capture && e.touches[2] && cy.boxSelectionEnabled()) { + e.preventDefault(); + r.data.bgActivePosistion = undefined; + this.lastThreeTouch = +new Date(); + if (!r.touchData.selecting) { + cy.emit({ + originalEvent: e, + type: 'boxstart', + position: { + x: now[0], + y: now[1] + } + }); + } + r.touchData.selecting = true; + r.touchData.didSelect = true; + select[4] = 1; + if (!select || select.length === 0 || select[0] === undefined) { + select[0] = (now[0] + now[2] + now[4]) / 3; + select[1] = (now[1] + now[3] + now[5]) / 3; + select[2] = (now[0] + now[2] + now[4]) / 3 + 1; + select[3] = (now[1] + now[3] + now[5]) / 3 + 1; + } else { + select[2] = (now[0] + now[2] + now[4]) / 3; + select[3] = (now[1] + now[3] + now[5]) / 3; + } + r.redrawHint('select', true); + r.redraw(); + + // pinch to zoom + } else if (capture && e.touches[1] && !r.touchData.didSelect // don't allow box selection to degrade to pinch-to-zoom + && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled()) { + // two fingers => pinch to zoom + e.preventDefault(); + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + var draggedEles = r.dragData.touchDragEles; + if (draggedEles) { + r.redrawHint('drag', true); + for (var i = 0; i < draggedEles.length; i++) { + var de_p = draggedEles[i]._private; + de_p.grabbed = false; + de_p.rscratch.inDragLayer = false; + } + } + var _start = r.touchData.start; + + // (x2, y2) for fingers 1 and 2 + var f1x2 = e.touches[0].clientX - offsetLeft, + f1y2 = e.touches[0].clientY - offsetTop; + var f2x2 = e.touches[1].clientX - offsetLeft, + f2y2 = e.touches[1].clientY - offsetTop; + var distance2 = distance(f1x2, f1y2, f2x2, f2y2); + // var distance2Sq = distanceSq( f1x2, f1y2, f2x2, f2y2 ); + // var factor = Math.sqrt( distance2Sq ) / Math.sqrt( distance1Sq ); + var factor = distance2 / distance1; + if (twoFingersStartInside) { + // delta finger1 + var df1x = f1x2 - f1x1; + var df1y = f1y2 - f1y1; + + // delta finger 2 + var df2x = f2x2 - f2x1; + var df2y = f2y2 - f2y1; + + // translation is the normalised vector of the two fingers movement + // i.e. so pinching cancels out and moving together pans + var tx = (df1x + df2x) / 2; + var ty = (df1y + df2y) / 2; + + // now calculate the zoom + var zoom1 = cy.zoom(); + var zoom2 = zoom1 * factor; + var pan1 = cy.pan(); + + // the model center point converted to the current rendered pos + var ctrx = modelCenter1[0] * zoom1 + pan1.x; + var ctry = modelCenter1[1] * zoom1 + pan1.y; + var pan2 = { + x: -zoom2 / zoom1 * (ctrx - pan1.x - tx) + ctrx, + y: -zoom2 / zoom1 * (ctry - pan1.y - ty) + ctry + }; + + // remove dragged eles + if (_start && _start.active()) { + var draggedEles = r.dragData.touchDragEles; + freeDraggedElements(draggedEles); + r.redrawHint('drag', true); + r.redrawHint('eles', true); + _start.unactivate().emit('freeon'); + draggedEles.emit('free'); + if (r.dragData.didDrag) { + _start.emit('dragfreeon'); + draggedEles.emit('dragfree'); + } + } + cy.viewport({ + zoom: zoom2, + pan: pan2, + cancelOnFailedZoom: true + }); + cy.emit('pinchzoom'); + distance1 = distance2; + f1x1 = f1x2; + f1y1 = f1y2; + f2x1 = f2x2; + f2y1 = f2y2; + r.pinching = true; + } + + // Re-project + if (e.touches[0]) { + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + if (e.touches[1]) { + var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); + now[2] = pos[0]; + now[3] = pos[1]; + } + if (e.touches[2]) { + var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); + now[4] = pos[0]; + now[5] = pos[1]; + } + } else if (e.touches[0] && !r.touchData.didSelect // don't allow box selection to degrade to single finger events like panning + ) { + var start = r.touchData.start; + var last = r.touchData.last; + var near; + if (!r.hoverData.draggingEles && !r.swipePanning) { + near = r.findNearestElement(now[0], now[1], true, true); + } + if (capture && start != null) { + e.preventDefault(); + } + + // dragging nodes + if (capture && start != null && r.nodeIsDraggable(start)) { + if (isOverThresholdDrag) { + // then dragging can happen + var draggedEles = r.dragData.touchDragEles; + var justStartedDrag = !r.dragData.didDrag; + if (justStartedDrag) { + addNodesToDrag(draggedEles, { + inDragLayer: true + }); + } + r.dragData.didDrag = true; + var totalShift = { + x: 0, + y: 0 + }; + if (number$1(disp[0]) && number$1(disp[1])) { + totalShift.x += disp[0]; + totalShift.y += disp[1]; + if (justStartedDrag) { + r.redrawHint('eles', true); + var dragDelta = r.touchData.dragDelta; + if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) { + totalShift.x += dragDelta[0]; + totalShift.y += dragDelta[1]; + } + } + } + r.hoverData.draggingEles = true; + draggedEles.silentShift(totalShift).emit('position drag'); + r.redrawHint('drag', true); + if (r.touchData.startPosition[0] == earlier[0] && r.touchData.startPosition[1] == earlier[1]) { + r.redrawHint('eles', true); + } + r.redraw(); + } else { + // otherwise keep track of drag delta for later + var dragDelta = r.touchData.dragDelta = r.touchData.dragDelta || []; + if (dragDelta.length === 0) { + dragDelta.push(disp[0]); + dragDelta.push(disp[1]); + } else { + dragDelta[0] += disp[0]; + dragDelta[1] += disp[1]; + } + } + } + + // touchmove + { + triggerEvents(start || near, ['touchmove', 'tapdrag', 'vmousemove'], e, { + x: now[0], + y: now[1] + }); + if ((!start || !start.grabbed()) && near != last) { + if (last) { + last.emit({ + originalEvent: e, + type: 'tapdragout', + position: { + x: now[0], + y: now[1] + } + }); + } + if (near) { + near.emit({ + originalEvent: e, + type: 'tapdragover', + position: { + x: now[0], + y: now[1] + } + }); + } + } + r.touchData.last = near; + } + + // check to cancel taphold + if (capture) { + for (var i = 0; i < now.length; i++) { + if (now[i] && r.touchData.startPosition[i] && isOverThresholdDrag) { + r.touchData.singleTouchMoved = true; + } + } + } + + // panning + if (capture && (start == null || start.pannable()) && cy.panningEnabled() && cy.userPanningEnabled()) { + var allowPassthrough = allowPanningPassthrough(start, r.touchData.starts); + if (allowPassthrough) { + e.preventDefault(); + if (!r.data.bgActivePosistion) { + r.data.bgActivePosistion = array2point(r.touchData.startPosition); + } + if (r.swipePanning) { + cy.panBy({ + x: disp[0] * zoom, + y: disp[1] * zoom + }); + cy.emit('dragpan'); + } else if (isOverThresholdDrag) { + r.swipePanning = true; + cy.panBy({ + x: dx * zoom, + y: dy * zoom + }); + cy.emit('dragpan'); + if (start) { + start.unactivate(); + r.redrawHint('select', true); + r.touchData.start = null; + } + } + } + + // Re-project + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + } + for (var j = 0; j < now.length; j++) { + earlier[j] = now[j]; + } + + // the active bg indicator should be removed when making a swipe that is neither for dragging nodes or panning + if (capture && e.touches.length > 0 && !r.hoverData.draggingEles && !r.swipePanning && r.data.bgActivePosistion != null) { + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + r.redraw(); + } + }, false); + var touchcancelHandler; + r.registerBinding(containerWindow, 'touchcancel', touchcancelHandler = function touchcancelHandler(e) { + // eslint-disable-line no-unused-vars + var start = r.touchData.start; + r.touchData.capture = false; + if (start) { + start.unactivate(); + } + }); + var touchendHandler, didDoubleTouch, touchTimeout, prevTouchTimeStamp; + r.registerBinding(containerWindow, 'touchend', touchendHandler = function touchendHandler(e) { + // eslint-disable-line no-unused-vars + var start = r.touchData.start; + var capture = r.touchData.capture; + if (capture) { + if (e.touches.length === 0) { + r.touchData.capture = false; + } + e.preventDefault(); + } else { + return; + } + var select = r.selection; + r.swipePanning = false; + r.hoverData.draggingEles = false; + var cy = r.cy; + var zoom = cy.zoom(); + var now = r.touchData.now; + var earlier = r.touchData.earlier; + if (e.touches[0]) { + var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); + now[0] = pos[0]; + now[1] = pos[1]; + } + if (e.touches[1]) { + var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); + now[2] = pos[0]; + now[3] = pos[1]; + } + if (e.touches[2]) { + var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); + now[4] = pos[0]; + now[5] = pos[1]; + } + if (start) { + start.unactivate(); + } + var ctxTapend; + if (r.touchData.cxt) { + ctxTapend = { + originalEvent: e, + type: 'cxttapend', + position: { + x: now[0], + y: now[1] + } + }; + if (start) { + start.emit(ctxTapend); + } else { + cy.emit(ctxTapend); + } + if (!r.touchData.cxtDragged) { + var ctxTap = { + originalEvent: e, + type: 'cxttap', + position: { + x: now[0], + y: now[1] + } + }; + if (start) { + start.emit(ctxTap); + } else { + cy.emit(ctxTap); + } + } + if (r.touchData.start) { + r.touchData.start._private.grabbed = false; + } + r.touchData.cxt = false; + r.touchData.start = null; + r.redraw(); + return; + } + + // no more box selection if we don't have three fingers + if (!e.touches[2] && cy.boxSelectionEnabled() && r.touchData.selecting) { + r.touchData.selecting = false; + var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3])); + select[0] = undefined; + select[1] = undefined; + select[2] = undefined; + select[3] = undefined; + select[4] = 0; + r.redrawHint('select', true); + cy.emit({ + type: 'boxend', + originalEvent: e, + position: { + x: now[0], + y: now[1] + } + }); + var eleWouldBeSelected = function eleWouldBeSelected(ele) { + return ele.selectable() && !ele.selected(); + }; + box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect'); + if (box.nonempty()) { + r.redrawHint('eles', true); + } + r.redraw(); + } + if (start != null) { + start.unactivate(); + } + if (e.touches[2]) { + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + } else if (e.touches[1]) ; else if (e.touches[0]) ; else if (!e.touches[0]) { + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + var draggedEles = r.dragData.touchDragEles; + if (start != null) { + var startWasGrabbed = start._private.grabbed; + freeDraggedElements(draggedEles); + r.redrawHint('drag', true); + r.redrawHint('eles', true); + if (startWasGrabbed) { + start.emit('freeon'); + draggedEles.emit('free'); + if (r.dragData.didDrag) { + start.emit('dragfreeon'); + draggedEles.emit('dragfree'); + } + } + triggerEvents(start, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, { + x: now[0], + y: now[1] + }); + start.unactivate(); + r.touchData.start = null; + } else { + var near = r.findNearestElement(now[0], now[1], true, true); + triggerEvents(near, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, { + x: now[0], + y: now[1] + }); + } + var dx = r.touchData.startPosition[0] - now[0]; + var dx2 = dx * dx; + var dy = r.touchData.startPosition[1] - now[1]; + var dy2 = dy * dy; + var dist2 = dx2 + dy2; + var rdist2 = dist2 * zoom * zoom; + + // Tap event, roughly same as mouse click event for touch + if (!r.touchData.singleTouchMoved) { + if (!start) { + cy.$(':selected').unselect(['tapunselect']); + } + triggerEvents(start, ['tap', 'vclick'], e, { + x: now[0], + y: now[1] + }); + didDoubleTouch = false; + if (e.timeStamp - prevTouchTimeStamp <= cy.multiClickDebounceTime()) { + touchTimeout && clearTimeout(touchTimeout); + didDoubleTouch = true; + prevTouchTimeStamp = null; + triggerEvents(start, ['dbltap', 'vdblclick'], e, { + x: now[0], + y: now[1] + }); + } else { + touchTimeout = setTimeout(function () { + if (didDoubleTouch) return; + triggerEvents(start, ['onetap', 'voneclick'], e, { + x: now[0], + y: now[1] + }); + }, cy.multiClickDebounceTime()); + prevTouchTimeStamp = e.timeStamp; + } + } + + // Prepare to select the currently touched node, only if it hasn't been dragged past a certain distance + if (start != null && !r.dragData.didDrag // didn't drag nodes around + && start._private.selectable && rdist2 < r.touchTapThreshold2 && !r.pinching // pinch to zoom should not affect selection + ) { + if (cy.selectionType() === 'single') { + cy.$(isSelected).unmerge(start).unselect(['tapunselect']); + start.select(['tapselect']); + } else { + if (start.selected()) { + start.unselect(['tapunselect']); + } else { + start.select(['tapselect']); + } + } + r.redrawHint('eles', true); + } + r.touchData.singleTouchMoved = true; + } + for (var j = 0; j < now.length; j++) { + earlier[j] = now[j]; + } + r.dragData.didDrag = false; // reset for next touchstart + + if (e.touches.length === 0) { + r.touchData.dragDelta = []; + r.touchData.startPosition = [null, null, null, null, null, null]; + r.touchData.startGPosition = null; + r.touchData.didSelect = false; + } + if (e.touches.length < 2) { + if (e.touches.length === 1) { + // the old start global pos'n may not be the same finger that remains + r.touchData.startGPosition = [e.touches[0].clientX, e.touches[0].clientY]; + } + r.pinching = false; + r.redrawHint('eles', true); + r.redraw(); + } + + //r.redraw(); + }, false); + + // fallback compatibility layer for ms pointer events + if (typeof TouchEvent === 'undefined') { + var pointers = []; + var makeTouch = function makeTouch(e) { + return { + clientX: e.clientX, + clientY: e.clientY, + force: 1, + identifier: e.pointerId, + pageX: e.pageX, + pageY: e.pageY, + radiusX: e.width / 2, + radiusY: e.height / 2, + screenX: e.screenX, + screenY: e.screenY, + target: e.target + }; + }; + var makePointer = function makePointer(e) { + return { + event: e, + touch: makeTouch(e) + }; + }; + var addPointer = function addPointer(e) { + pointers.push(makePointer(e)); + }; + var removePointer = function removePointer(e) { + for (var i = 0; i < pointers.length; i++) { + var p = pointers[i]; + if (p.event.pointerId === e.pointerId) { + pointers.splice(i, 1); + return; + } + } + }; + var updatePointer = function updatePointer(e) { + var p = pointers.filter(function (p) { + return p.event.pointerId === e.pointerId; + })[0]; + p.event = e; + p.touch = makeTouch(e); + }; + var addTouchesToEvent = function addTouchesToEvent(e) { + e.touches = pointers.map(function (p) { + return p.touch; + }); + }; + var pointerIsMouse = function pointerIsMouse(e) { + return e.pointerType === 'mouse' || e.pointerType === 4; + }; + r.registerBinding(r.container, 'pointerdown', function (e) { + if (pointerIsMouse(e)) { + return; + } // mouse already handled + + e.preventDefault(); + addPointer(e); + addTouchesToEvent(e); + touchstartHandler(e); + }); + r.registerBinding(r.container, 'pointerup', function (e) { + if (pointerIsMouse(e)) { + return; + } // mouse already handled + + removePointer(e); + addTouchesToEvent(e); + touchendHandler(e); + }); + r.registerBinding(r.container, 'pointercancel', function (e) { + if (pointerIsMouse(e)) { + return; + } // mouse already handled + + removePointer(e); + addTouchesToEvent(e); + touchcancelHandler(e); + }); + r.registerBinding(r.container, 'pointermove', function (e) { + if (pointerIsMouse(e)) { + return; + } // mouse already handled + + e.preventDefault(); + updatePointer(e); + addTouchesToEvent(e); + touchmoveHandler(e); + }); + } + }; + + var BRp$2 = {}; + BRp$2.generatePolygon = function (name, points) { + return this.nodeShapes[name] = { + renderer: this, + name: name, + points: points, + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl('polygon', context, centerX, centerY, width, height, this.points); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + return polygonIntersectLine(x, y, this.points, nodeX, nodeY, width / 2, height / 2, padding); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + return pointInsidePolygon(x, y, this.points, centerX, centerY, width, height, [0, -1], padding); + } + }; + }; + BRp$2.generateEllipse = function () { + return this.nodeShapes['ellipse'] = { + renderer: this, + name: 'ellipse', + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + return intersectLineEllipse(x, y, nodeX, nodeY, width / 2 + padding, height / 2 + padding); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + return checkInEllipse(x, y, width, height, centerX, centerY, padding); + } + }; + }; + BRp$2.generateRoundPolygon = function (name, points) { + // Pre-compute control points + // Since these points depend on the radius length (which in turns depend on the width/height of the node) we will only pre-compute + // the unit vectors. + // For simplicity the layout will be: + // [ p0, UnitVectorP0P1, p1, UniVectorP1P2, ..., pn, UnitVectorPnP0 ] + var allPoints = new Array(points.length * 2); + for (var i = 0; i < points.length / 2; i++) { + var sourceIndex = i * 2; + var destIndex = void 0; + if (i < points.length / 2 - 1) { + destIndex = (i + 1) * 2; + } else { + destIndex = 0; + } + allPoints[i * 4] = points[sourceIndex]; + allPoints[i * 4 + 1] = points[sourceIndex + 1]; + var xDest = points[destIndex] - points[sourceIndex]; + var yDest = points[destIndex + 1] - points[sourceIndex + 1]; + var norm = Math.sqrt(xDest * xDest + yDest * yDest); + allPoints[i * 4 + 2] = xDest / norm; + allPoints[i * 4 + 3] = yDest / norm; + } + return this.nodeShapes[name] = { + renderer: this, + name: name, + points: allPoints, + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl('round-polygon', context, centerX, centerY, width, height, this.points); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + return roundPolygonIntersectLine(x, y, this.points, nodeX, nodeY, width, height); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + return pointInsideRoundPolygon(x, y, this.points, centerX, centerY, width, height); + } + }; + }; + BRp$2.generateRoundRectangle = function () { + return this.nodeShapes['round-rectangle'] = this.nodeShapes['roundrectangle'] = { + renderer: this, + name: 'round-rectangle', + points: generateUnitNgonPointsFitToSquare(4, 0), + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + var cornerRadius = getRoundRectangleRadius(width, height); + var diam = cornerRadius * 2; + + // Check hBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) { + return true; + } + + // Check vBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) { + return true; + } + + // Check top left quarter circle + if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY - height / 2 + cornerRadius, padding)) { + return true; + } + + // Check top right quarter circle + if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY - height / 2 + cornerRadius, padding)) { + return true; + } + + // Check bottom right quarter circle + if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) { + return true; + } + + // Check bottom left quarter circle + if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) { + return true; + } + return false; + } + }; + }; + BRp$2.generateCutRectangle = function () { + return this.nodeShapes['cut-rectangle'] = this.nodeShapes['cutrectangle'] = { + renderer: this, + name: 'cut-rectangle', + cornerLength: getCutRectangleCornerLength(), + points: generateUnitNgonPointsFitToSquare(4, 0), + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + generateCutTrianglePts: function generateCutTrianglePts(width, height, centerX, centerY) { + var cl = this.cornerLength; + var hh = height / 2; + var hw = width / 2; + var xBegin = centerX - hw; + var xEnd = centerX + hw; + var yBegin = centerY - hh; + var yEnd = centerY + hh; + + // points are in clockwise order, inner (imaginary) triangle pt on [4, 5] + return { + topLeft: [xBegin, yBegin + cl, xBegin + cl, yBegin, xBegin + cl, yBegin + cl], + topRight: [xEnd - cl, yBegin, xEnd, yBegin + cl, xEnd - cl, yBegin + cl], + bottomRight: [xEnd, yEnd - cl, xEnd - cl, yEnd, xEnd - cl, yEnd - cl], + bottomLeft: [xBegin + cl, yEnd, xBegin, yEnd - cl, xBegin + cl, yEnd - cl] + }; + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + var cPts = this.generateCutTrianglePts(width + 2 * padding, height + 2 * padding, nodeX, nodeY); + var pts = [].concat.apply([], [cPts.topLeft.splice(0, 4), cPts.topRight.splice(0, 4), cPts.bottomRight.splice(0, 4), cPts.bottomLeft.splice(0, 4)]); + return polygonIntersectLine(x, y, pts, nodeX, nodeY); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + // Check hBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * this.cornerLength, [0, -1], padding)) { + return true; + } + + // Check vBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * this.cornerLength, height, [0, -1], padding)) { + return true; + } + var cutTrianglePts = this.generateCutTrianglePts(width, height, centerX, centerY); + return pointInsidePolygonPoints(x, y, cutTrianglePts.topLeft) || pointInsidePolygonPoints(x, y, cutTrianglePts.topRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomLeft); + } + }; + }; + BRp$2.generateBarrel = function () { + return this.nodeShapes['barrel'] = { + renderer: this, + name: 'barrel', + points: generateUnitNgonPointsFitToSquare(4, 0), + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + // use two fixed t values for the bezier curve approximation + + var t0 = 0.15; + var t1 = 0.5; + var t2 = 0.85; + var bPts = this.generateBarrelBezierPts(width + 2 * padding, height + 2 * padding, nodeX, nodeY); + var approximateBarrelCurvePts = function approximateBarrelCurvePts(pts) { + // approximate curve pts based on the two t values + var m0 = qbezierPtAt({ + x: pts[0], + y: pts[1] + }, { + x: pts[2], + y: pts[3] + }, { + x: pts[4], + y: pts[5] + }, t0); + var m1 = qbezierPtAt({ + x: pts[0], + y: pts[1] + }, { + x: pts[2], + y: pts[3] + }, { + x: pts[4], + y: pts[5] + }, t1); + var m2 = qbezierPtAt({ + x: pts[0], + y: pts[1] + }, { + x: pts[2], + y: pts[3] + }, { + x: pts[4], + y: pts[5] + }, t2); + return [pts[0], pts[1], m0.x, m0.y, m1.x, m1.y, m2.x, m2.y, pts[4], pts[5]]; + }; + var pts = [].concat(approximateBarrelCurvePts(bPts.topLeft), approximateBarrelCurvePts(bPts.topRight), approximateBarrelCurvePts(bPts.bottomRight), approximateBarrelCurvePts(bPts.bottomLeft)); + return polygonIntersectLine(x, y, pts, nodeX, nodeY); + }, + generateBarrelBezierPts: function generateBarrelBezierPts(width, height, centerX, centerY) { + var hh = height / 2; + var hw = width / 2; + var xBegin = centerX - hw; + var xEnd = centerX + hw; + var yBegin = centerY - hh; + var yEnd = centerY + hh; + var curveConstants = getBarrelCurveConstants(width, height); + var hOffset = curveConstants.heightOffset; + var wOffset = curveConstants.widthOffset; + var ctrlPtXOffset = curveConstants.ctrlPtOffsetPct * width; + + // points are in clockwise order, inner (imaginary) control pt on [4, 5] + var pts = { + topLeft: [xBegin, yBegin + hOffset, xBegin + ctrlPtXOffset, yBegin, xBegin + wOffset, yBegin], + topRight: [xEnd - wOffset, yBegin, xEnd - ctrlPtXOffset, yBegin, xEnd, yBegin + hOffset], + bottomRight: [xEnd, yEnd - hOffset, xEnd - ctrlPtXOffset, yEnd, xEnd - wOffset, yEnd], + bottomLeft: [xBegin + wOffset, yEnd, xBegin + ctrlPtXOffset, yEnd, xBegin, yEnd - hOffset] + }; + pts.topLeft.isTop = true; + pts.topRight.isTop = true; + pts.bottomLeft.isBottom = true; + pts.bottomRight.isBottom = true; + return pts; + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + var curveConstants = getBarrelCurveConstants(width, height); + var hOffset = curveConstants.heightOffset; + var wOffset = curveConstants.widthOffset; + + // Check hBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * hOffset, [0, -1], padding)) { + return true; + } + + // Check vBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * wOffset, height, [0, -1], padding)) { + return true; + } + var barrelCurvePts = this.generateBarrelBezierPts(width, height, centerX, centerY); + var getCurveT = function getCurveT(x, y, curvePts) { + var x0 = curvePts[4]; + var x1 = curvePts[2]; + var x2 = curvePts[0]; + var y0 = curvePts[5]; + // var y1 = curvePts[ 3 ]; + var y2 = curvePts[1]; + var xMin = Math.min(x0, x2); + var xMax = Math.max(x0, x2); + var yMin = Math.min(y0, y2); + var yMax = Math.max(y0, y2); + if (xMin <= x && x <= xMax && yMin <= y && y <= yMax) { + var coeff = bezierPtsToQuadCoeff(x0, x1, x2); + var roots = solveQuadratic(coeff[0], coeff[1], coeff[2], x); + var validRoots = roots.filter(function (r) { + return 0 <= r && r <= 1; + }); + if (validRoots.length > 0) { + return validRoots[0]; + } + } + return null; + }; + var curveRegions = Object.keys(barrelCurvePts); + for (var i = 0; i < curveRegions.length; i++) { + var corner = curveRegions[i]; + var cornerPts = barrelCurvePts[corner]; + var t = getCurveT(x, y, cornerPts); + if (t == null) { + continue; + } + var y0 = cornerPts[5]; + var y1 = cornerPts[3]; + var y2 = cornerPts[1]; + var bezY = qbezierAt(y0, y1, y2, t); + if (cornerPts.isTop && bezY <= y) { + return true; + } + if (cornerPts.isBottom && y <= bezY) { + return true; + } + } + return false; + } + }; + }; + BRp$2.generateBottomRoundrectangle = function () { + return this.nodeShapes['bottom-round-rectangle'] = this.nodeShapes['bottomroundrectangle'] = { + renderer: this, + name: 'bottom-round-rectangle', + points: generateUnitNgonPointsFitToSquare(4, 0), + draw: function draw(context, centerX, centerY, width, height) { + this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height); + }, + intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) { + var topStartX = nodeX - (width / 2 + padding); + var topStartY = nodeY - (height / 2 + padding); + var topEndY = topStartY; + var topEndX = nodeX + (width / 2 + padding); + var topIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false); + if (topIntersections.length > 0) { + return topIntersections; + } + return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding); + }, + checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) { + var cornerRadius = getRoundRectangleRadius(width, height); + var diam = 2 * cornerRadius; + + // Check hBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) { + return true; + } + + // Check vBox + if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) { + return true; + } + + // check non-rounded top side + var outerWidth = width / 2 + 2 * padding; + var outerHeight = height / 2 + 2 * padding; + var points = [centerX - outerWidth, centerY - outerHeight, centerX - outerWidth, centerY, centerX + outerWidth, centerY, centerX + outerWidth, centerY - outerHeight]; + if (pointInsidePolygonPoints(x, y, points)) { + return true; + } + + // Check bottom right quarter circle + if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) { + return true; + } + + // Check bottom left quarter circle + if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) { + return true; + } + return false; + } + }; + }; + BRp$2.registerNodeShapes = function () { + var nodeShapes = this.nodeShapes = {}; + var renderer = this; + this.generateEllipse(); + this.generatePolygon('triangle', generateUnitNgonPointsFitToSquare(3, 0)); + this.generateRoundPolygon('round-triangle', generateUnitNgonPointsFitToSquare(3, 0)); + this.generatePolygon('rectangle', generateUnitNgonPointsFitToSquare(4, 0)); + nodeShapes['square'] = nodeShapes['rectangle']; + this.generateRoundRectangle(); + this.generateCutRectangle(); + this.generateBarrel(); + this.generateBottomRoundrectangle(); + { + var diamondPoints = [0, 1, 1, 0, 0, -1, -1, 0]; + this.generatePolygon('diamond', diamondPoints); + this.generateRoundPolygon('round-diamond', diamondPoints); + } + this.generatePolygon('pentagon', generateUnitNgonPointsFitToSquare(5, 0)); + this.generateRoundPolygon('round-pentagon', generateUnitNgonPointsFitToSquare(5, 0)); + this.generatePolygon('hexagon', generateUnitNgonPointsFitToSquare(6, 0)); + this.generateRoundPolygon('round-hexagon', generateUnitNgonPointsFitToSquare(6, 0)); + this.generatePolygon('heptagon', generateUnitNgonPointsFitToSquare(7, 0)); + this.generateRoundPolygon('round-heptagon', generateUnitNgonPointsFitToSquare(7, 0)); + this.generatePolygon('octagon', generateUnitNgonPointsFitToSquare(8, 0)); + this.generateRoundPolygon('round-octagon', generateUnitNgonPointsFitToSquare(8, 0)); + var star5Points = new Array(20); + { + var outerPoints = generateUnitNgonPoints(5, 0); + var innerPoints = generateUnitNgonPoints(5, Math.PI / 5); + + // Outer radius is 1; inner radius of star is smaller + var innerRadius = 0.5 * (3 - Math.sqrt(5)); + innerRadius *= 1.57; + for (var i = 0; i < innerPoints.length / 2; i++) { + innerPoints[i * 2] *= innerRadius; + innerPoints[i * 2 + 1] *= innerRadius; + } + for (var i = 0; i < 20 / 4; i++) { + star5Points[i * 4] = outerPoints[i * 2]; + star5Points[i * 4 + 1] = outerPoints[i * 2 + 1]; + star5Points[i * 4 + 2] = innerPoints[i * 2]; + star5Points[i * 4 + 3] = innerPoints[i * 2 + 1]; + } + } + star5Points = fitPolygonToSquare(star5Points); + this.generatePolygon('star', star5Points); + this.generatePolygon('vee', [-1, -1, 0, -0.333, 1, -1, 0, 1]); + this.generatePolygon('rhomboid', [-1, -1, 0.333, -1, 1, 1, -0.333, 1]); + this.generatePolygon('right-rhomboid', [-0.333, -1, 1, -1, 0.333, 1, -1, 1]); + this.nodeShapes['concavehexagon'] = this.generatePolygon('concave-hexagon', [-1, -0.95, -0.75, 0, -1, 0.95, 1, 0.95, 0.75, 0, 1, -0.95]); + { + var tagPoints = [-1, -1, 0.25, -1, 1, 0, 0.25, 1, -1, 1]; + this.generatePolygon('tag', tagPoints); + this.generateRoundPolygon('round-tag', tagPoints); + } + nodeShapes.makePolygon = function (points) { + // use caching on user-specified polygons so they are as fast as native shapes + + var key = points.join('$'); + var name = 'polygon-' + key; + var shape; + if (shape = this[name]) { + // got cached shape + return shape; + } + + // create and cache new shape + return renderer.generatePolygon(name, points); + }; + }; + + var BRp$1 = {}; + BRp$1.timeToRender = function () { + return this.redrawTotalTime / this.redrawCount; + }; + BRp$1.redraw = function (options) { + options = options || staticEmptyObject(); + var r = this; + if (r.averageRedrawTime === undefined) { + r.averageRedrawTime = 0; + } + if (r.lastRedrawTime === undefined) { + r.lastRedrawTime = 0; + } + if (r.lastDrawTime === undefined) { + r.lastDrawTime = 0; + } + r.requestedFrame = true; + r.renderOptions = options; + }; + BRp$1.beforeRender = function (fn, priority) { + // the renderer can't add tick callbacks when destroyed + if (this.destroyed) { + return; + } + if (priority == null) { + error('Priority is not optional for beforeRender'); + } + var cbs = this.beforeRenderCallbacks; + cbs.push({ + fn: fn, + priority: priority + }); + + // higher priority callbacks executed first + cbs.sort(function (a, b) { + return b.priority - a.priority; + }); + }; + var beforeRenderCallbacks = function beforeRenderCallbacks(r, willDraw, startTime) { + var cbs = r.beforeRenderCallbacks; + for (var i = 0; i < cbs.length; i++) { + cbs[i].fn(willDraw, startTime); + } + }; + BRp$1.startRenderLoop = function () { + var r = this; + var cy = r.cy; + if (r.renderLoopStarted) { + return; + } else { + r.renderLoopStarted = true; + } + var renderFn = function renderFn(requestTime) { + if (r.destroyed) { + return; + } + if (cy.batching()) ; else if (r.requestedFrame && !r.skipFrame) { + beforeRenderCallbacks(r, true, requestTime); + var startTime = performanceNow(); + r.render(r.renderOptions); + var endTime = r.lastDrawTime = performanceNow(); + if (r.averageRedrawTime === undefined) { + r.averageRedrawTime = endTime - startTime; + } + if (r.redrawCount === undefined) { + r.redrawCount = 0; + } + r.redrawCount++; + if (r.redrawTotalTime === undefined) { + r.redrawTotalTime = 0; + } + var duration = endTime - startTime; + r.redrawTotalTime += duration; + r.lastRedrawTime = duration; + + // use a weighted average with a bias from the previous average so we don't spike so easily + r.averageRedrawTime = r.averageRedrawTime / 2 + duration / 2; + r.requestedFrame = false; + } else { + beforeRenderCallbacks(r, false, requestTime); + } + r.skipFrame = false; + requestAnimationFrame(renderFn); + }; + requestAnimationFrame(renderFn); + }; + + var BaseRenderer = function BaseRenderer(options) { + this.init(options); + }; + var BR = BaseRenderer; + var BRp = BR.prototype; + BRp.clientFunctions = ['redrawHint', 'render', 'renderTo', 'matchCanvasSize', 'nodeShapeImpl', 'arrowShapeImpl']; + BRp.init = function (options) { + var r = this; + r.options = options; + r.cy = options.cy; + var ctr = r.container = options.cy.container(); + var containerWindow = r.cy.window(); + + // prepend a stylesheet in the head such that + if (containerWindow) { + var document = containerWindow.document; + var head = document.head; + var stylesheetId = '__________cytoscape_stylesheet'; + var className = '__________cytoscape_container'; + var stylesheetAlreadyExists = document.getElementById(stylesheetId) != null; + if (ctr.className.indexOf(className) < 0) { + ctr.className = (ctr.className || '') + ' ' + className; + } + if (!stylesheetAlreadyExists) { + var stylesheet = document.createElement('style'); + stylesheet.id = stylesheetId; + stylesheet.textContent = '.' + className + ' { position: relative; }'; + head.insertBefore(stylesheet, head.children[0]); // first so lowest priority + } + + var computedStyle = containerWindow.getComputedStyle(ctr); + var position = computedStyle.getPropertyValue('position'); + if (position === 'static') { + warn('A Cytoscape container has style position:static and so can not use UI extensions properly'); + } + } + r.selection = [undefined, undefined, undefined, undefined, 0]; // Coordinates for selection box, plus enabled flag + + r.bezierProjPcts = [0.05, 0.225, 0.4, 0.5, 0.6, 0.775, 0.95]; + + //--Pointer-related data + r.hoverData = { + down: null, + last: null, + downTime: null, + triggerMode: null, + dragging: false, + initialPan: [null, null], + capture: false + }; + r.dragData = { + possibleDragElements: [] + }; + r.touchData = { + start: null, + capture: false, + // These 3 fields related to tap, taphold events + startPosition: [null, null, null, null, null, null], + singleTouchStartTime: null, + singleTouchMoved: true, + now: [null, null, null, null, null, null], + earlier: [null, null, null, null, null, null] + }; + r.redraws = 0; + r.showFps = options.showFps; + r.debug = options.debug; + r.hideEdgesOnViewport = options.hideEdgesOnViewport; + r.textureOnViewport = options.textureOnViewport; + r.wheelSensitivity = options.wheelSensitivity; + r.motionBlurEnabled = options.motionBlur; // on by default + r.forcedPixelRatio = number$1(options.pixelRatio) ? options.pixelRatio : null; + r.motionBlur = options.motionBlur; // for initial kick off + r.motionBlurOpacity = options.motionBlurOpacity; + r.motionBlurTransparency = 1 - r.motionBlurOpacity; + r.motionBlurPxRatio = 1; + r.mbPxRBlurry = 1; //0.8; + r.minMbLowQualFrames = 4; + r.fullQualityMb = false; + r.clearedForMotionBlur = []; + r.desktopTapThreshold = options.desktopTapThreshold; + r.desktopTapThreshold2 = options.desktopTapThreshold * options.desktopTapThreshold; + r.touchTapThreshold = options.touchTapThreshold; + r.touchTapThreshold2 = options.touchTapThreshold * options.touchTapThreshold; + r.tapholdDuration = 500; + r.bindings = []; + r.beforeRenderCallbacks = []; + r.beforeRenderPriorities = { + // higher priority execs before lower one + animations: 400, + eleCalcs: 300, + eleTxrDeq: 200, + lyrTxrDeq: 150, + lyrTxrSkip: 100 + }; + r.registerNodeShapes(); + r.registerArrowShapes(); + r.registerCalculationListeners(); + }; + BRp.notify = function (eventName, eles) { + var r = this; + var cy = r.cy; + + // the renderer can't be notified after it's destroyed + if (this.destroyed) { + return; + } + if (eventName === 'init') { + r.load(); + return; + } + if (eventName === 'destroy') { + r.destroy(); + return; + } + if (eventName === 'add' || eventName === 'remove' || eventName === 'move' && cy.hasCompoundNodes() || eventName === 'load' || eventName === 'zorder' || eventName === 'mount') { + r.invalidateCachedZSortedEles(); + } + if (eventName === 'viewport') { + r.redrawHint('select', true); + } + if (eventName === 'load' || eventName === 'resize' || eventName === 'mount') { + r.invalidateContainerClientCoordsCache(); + r.matchCanvasSize(r.container); + } + r.redrawHint('eles', true); + r.redrawHint('drag', true); + this.startRenderLoop(); + this.redraw(); + }; + BRp.destroy = function () { + var r = this; + r.destroyed = true; + r.cy.stopAnimationLoop(); + for (var i = 0; i < r.bindings.length; i++) { + var binding = r.bindings[i]; + var b = binding; + var tgt = b.target; + (tgt.off || tgt.removeEventListener).apply(tgt, b.args); + } + r.bindings = []; + r.beforeRenderCallbacks = []; + r.onUpdateEleCalcsFns = []; + if (r.removeObserver) { + r.removeObserver.disconnect(); + } + if (r.styleObserver) { + r.styleObserver.disconnect(); + } + if (r.resizeObserver) { + r.resizeObserver.disconnect(); + } + if (r.labelCalcDiv) { + try { + document.body.removeChild(r.labelCalcDiv); // eslint-disable-line no-undef + } catch (e) { + // ie10 issue #1014 + } + } + }; + BRp.isHeadless = function () { + return false; + }; + [BRp$f, BRp$5, BRp$4, BRp$3, BRp$2, BRp$1].forEach(function (props) { + extend(BRp, props); + }); + + var fullFpsTime = 1000 / 60; // assume 60 frames per second + + var defs = { + setupDequeueing: function setupDequeueing(opts) { + return function setupDequeueingImpl() { + var self = this; + var r = this.renderer; + if (self.dequeueingSetup) { + return; + } else { + self.dequeueingSetup = true; + } + var queueRedraw = debounce_1(function () { + r.redrawHint('eles', true); + r.redrawHint('drag', true); + r.redraw(); + }, opts.deqRedrawThreshold); + var dequeue = function dequeue(willDraw, frameStartTime) { + var startTime = performanceNow(); + var avgRenderTime = r.averageRedrawTime; + var renderTime = r.lastRedrawTime; + var deqd = []; + var extent = r.cy.extent(); + var pixelRatio = r.getPixelRatio(); + + // if we aren't in a tick that causes a draw, then the rendered style + // queue won't automatically be flushed before dequeueing starts + if (!willDraw) { + r.flushRenderedStyleQueue(); + } + while (true) { + // eslint-disable-line no-constant-condition + var now = performanceNow(); + var duration = now - startTime; + var frameDuration = now - frameStartTime; + if (renderTime < fullFpsTime) { + // if we're rendering faster than the ideal fps, then do dequeueing + // during all of the remaining frame time + + var timeAvailable = fullFpsTime - (willDraw ? avgRenderTime : 0); + if (frameDuration >= opts.deqFastCost * timeAvailable) { + break; + } + } else { + if (willDraw) { + if (duration >= opts.deqCost * renderTime || duration >= opts.deqAvgCost * avgRenderTime) { + break; + } + } else if (frameDuration >= opts.deqNoDrawCost * fullFpsTime) { + break; + } + } + var thisDeqd = opts.deq(self, pixelRatio, extent); + if (thisDeqd.length > 0) { + for (var i = 0; i < thisDeqd.length; i++) { + deqd.push(thisDeqd[i]); + } + } else { + break; + } + } + + // callbacks on dequeue + if (deqd.length > 0) { + opts.onDeqd(self, deqd); + if (!willDraw && opts.shouldRedraw(self, deqd, pixelRatio, extent)) { + queueRedraw(); + } + } + }; + var priority = opts.priority || noop$1; + r.beforeRender(dequeue, priority(self)); + }; + } + }; + + // Allows lookups for (ele, lvl) => cache. + // Uses keys so elements may share the same cache. + var ElementTextureCacheLookup = /*#__PURE__*/function () { + function ElementTextureCacheLookup(getKey) { + var doesEleInvalidateKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : falsify; + _classCallCheck(this, ElementTextureCacheLookup); + this.idsByKey = new Map$2(); + this.keyForId = new Map$2(); + this.cachesByLvl = new Map$2(); + this.lvls = []; + this.getKey = getKey; + this.doesEleInvalidateKey = doesEleInvalidateKey; + } + _createClass(ElementTextureCacheLookup, [{ + key: "getIdsFor", + value: function getIdsFor(key) { + if (key == null) { + error("Can not get id list for null key"); + } + var idsByKey = this.idsByKey; + var ids = this.idsByKey.get(key); + if (!ids) { + ids = new Set$1(); + idsByKey.set(key, ids); + } + return ids; + } + }, { + key: "addIdForKey", + value: function addIdForKey(key, id) { + if (key != null) { + this.getIdsFor(key).add(id); + } + } + }, { + key: "deleteIdForKey", + value: function deleteIdForKey(key, id) { + if (key != null) { + this.getIdsFor(key)["delete"](id); + } + } + }, { + key: "getNumberOfIdsForKey", + value: function getNumberOfIdsForKey(key) { + if (key == null) { + return 0; + } else { + return this.getIdsFor(key).size; + } + } + }, { + key: "updateKeyMappingFor", + value: function updateKeyMappingFor(ele) { + var id = ele.id(); + var prevKey = this.keyForId.get(id); + var currKey = this.getKey(ele); + this.deleteIdForKey(prevKey, id); + this.addIdForKey(currKey, id); + this.keyForId.set(id, currKey); + } + }, { + key: "deleteKeyMappingFor", + value: function deleteKeyMappingFor(ele) { + var id = ele.id(); + var prevKey = this.keyForId.get(id); + this.deleteIdForKey(prevKey, id); + this.keyForId["delete"](id); + } + }, { + key: "keyHasChangedFor", + value: function keyHasChangedFor(ele) { + var id = ele.id(); + var prevKey = this.keyForId.get(id); + var newKey = this.getKey(ele); + return prevKey !== newKey; + } + }, { + key: "isInvalid", + value: function isInvalid(ele) { + return this.keyHasChangedFor(ele) || this.doesEleInvalidateKey(ele); + } + }, { + key: "getCachesAt", + value: function getCachesAt(lvl) { + var cachesByLvl = this.cachesByLvl, + lvls = this.lvls; + var caches = cachesByLvl.get(lvl); + if (!caches) { + caches = new Map$2(); + cachesByLvl.set(lvl, caches); + lvls.push(lvl); + } + return caches; + } + }, { + key: "getCache", + value: function getCache(key, lvl) { + return this.getCachesAt(lvl).get(key); + } + }, { + key: "get", + value: function get(ele, lvl) { + var key = this.getKey(ele); + var cache = this.getCache(key, lvl); + + // getting for an element may need to add to the id list b/c eles can share keys + if (cache != null) { + this.updateKeyMappingFor(ele); + } + return cache; + } + }, { + key: "getForCachedKey", + value: function getForCachedKey(ele, lvl) { + var key = this.keyForId.get(ele.id()); // n.b. use cached key, not newly computed key + var cache = this.getCache(key, lvl); + return cache; + } + }, { + key: "hasCache", + value: function hasCache(key, lvl) { + return this.getCachesAt(lvl).has(key); + } + }, { + key: "has", + value: function has(ele, lvl) { + var key = this.getKey(ele); + return this.hasCache(key, lvl); + } + }, { + key: "setCache", + value: function setCache(key, lvl, cache) { + cache.key = key; + this.getCachesAt(lvl).set(key, cache); + } + }, { + key: "set", + value: function set(ele, lvl, cache) { + var key = this.getKey(ele); + this.setCache(key, lvl, cache); + this.updateKeyMappingFor(ele); + } + }, { + key: "deleteCache", + value: function deleteCache(key, lvl) { + this.getCachesAt(lvl)["delete"](key); + } + }, { + key: "delete", + value: function _delete(ele, lvl) { + var key = this.getKey(ele); + this.deleteCache(key, lvl); + } + }, { + key: "invalidateKey", + value: function invalidateKey(key) { + var _this = this; + this.lvls.forEach(function (lvl) { + return _this.deleteCache(key, lvl); + }); + } + + // returns true if no other eles reference the invalidated cache (n.b. other eles may need the cache with the same key) + }, { + key: "invalidate", + value: function invalidate(ele) { + var id = ele.id(); + var key = this.keyForId.get(id); // n.b. use stored key rather than current (potential key) + + this.deleteKeyMappingFor(ele); + var entireKeyInvalidated = this.doesEleInvalidateKey(ele); + if (entireKeyInvalidated) { + // clear mapping for current key + this.invalidateKey(key); + } + return entireKeyInvalidated || this.getNumberOfIdsForKey(key) === 0; + } + }]); + return ElementTextureCacheLookup; + }(); + + var minTxrH = 25; // the size of the texture cache for small height eles (special case) + var txrStepH = 50; // the min size of the regular cache, and the size it increases with each step up + var minLvl$1 = -4; // when scaling smaller than that we don't need to re-render + var maxLvl$1 = 3; // when larger than this scale just render directly (caching is not helpful) + var maxZoom$1 = 7.99; // beyond this zoom level, layered textures are not used + var eleTxrSpacing = 8; // spacing between elements on textures to avoid blitting overlaps + var defTxrWidth = 1024; // default/minimum texture width + var maxTxrW = 1024; // the maximum width of a texture + var maxTxrH = 1024; // the maximum height of a texture + var minUtility = 0.2; // if usage of texture is less than this, it is retired + var maxFullness = 0.8; // fullness of texture after which queue removal is checked + var maxFullnessChecks = 10; // dequeued after this many checks + var deqCost$1 = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame + var deqAvgCost$1 = 0.1; // % of add'l rendering cost compared to average overall redraw time + var deqNoDrawCost$1 = 0.9; // % of avg frame time that can be used for dequeueing when not drawing + var deqFastCost$1 = 0.9; // % of frame time to be used when >60fps + var deqRedrawThreshold$1 = 100; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile + var maxDeqSize$1 = 1; // number of eles to dequeue and render at higher texture in each batch + + var getTxrReasons = { + dequeue: 'dequeue', + downscale: 'downscale', + highQuality: 'highQuality' + }; + var initDefaults = defaults$g({ + getKey: null, + doesEleInvalidateKey: falsify, + drawElement: null, + getBoundingBox: null, + getRotationPoint: null, + getRotationOffset: null, + isVisible: trueify, + allowEdgeTxrCaching: true, + allowParentTxrCaching: true + }); + var ElementTextureCache = function ElementTextureCache(renderer, initOptions) { + var self = this; + self.renderer = renderer; + self.onDequeues = []; + var opts = initDefaults(initOptions); + extend(self, opts); + self.lookup = new ElementTextureCacheLookup(opts.getKey, opts.doesEleInvalidateKey); + self.setupDequeueing(); + }; + var ETCp = ElementTextureCache.prototype; + ETCp.reasons = getTxrReasons; + + // the list of textures in which new subtextures for elements can be placed + ETCp.getTextureQueue = function (txrH) { + var self = this; + self.eleImgCaches = self.eleImgCaches || {}; + return self.eleImgCaches[txrH] = self.eleImgCaches[txrH] || []; + }; + + // the list of usused textures which can be recycled (in use in texture queue) + ETCp.getRetiredTextureQueue = function (txrH) { + var self = this; + var rtxtrQs = self.eleImgCaches.retired = self.eleImgCaches.retired || {}; + var rtxtrQ = rtxtrQs[txrH] = rtxtrQs[txrH] || []; + return rtxtrQ; + }; + + // queue of element draw requests at different scale levels + ETCp.getElementQueue = function () { + var self = this; + var q = self.eleCacheQueue = self.eleCacheQueue || new heap(function (a, b) { + return b.reqs - a.reqs; + }); + return q; + }; + + // queue of element draw requests at different scale levels (element id lookup) + ETCp.getElementKeyToQueue = function () { + var self = this; + var k2q = self.eleKeyToCacheQueue = self.eleKeyToCacheQueue || {}; + return k2q; + }; + ETCp.getElement = function (ele, bb, pxRatio, lvl, reason) { + var self = this; + var r = this.renderer; + var zoom = r.cy.zoom(); + var lookup = this.lookup; + if (!bb || bb.w === 0 || bb.h === 0 || isNaN(bb.w) || isNaN(bb.h) || !ele.visible() || ele.removed()) { + return null; + } + if (!self.allowEdgeTxrCaching && ele.isEdge() || !self.allowParentTxrCaching && ele.isParent()) { + return null; + } + if (lvl == null) { + lvl = Math.ceil(log2(zoom * pxRatio)); + } + if (lvl < minLvl$1) { + lvl = minLvl$1; + } else if (zoom >= maxZoom$1 || lvl > maxLvl$1) { + return null; + } + var scale = Math.pow(2, lvl); + var eleScaledH = bb.h * scale; + var eleScaledW = bb.w * scale; + var scaledLabelShown = r.eleTextBiggerThanMin(ele, scale); + if (!this.isVisible(ele, scaledLabelShown)) { + return null; + } + var eleCache = lookup.get(ele, lvl); + + // if this get was on an unused/invalidated cache, then restore the texture usage metric + if (eleCache && eleCache.invalidated) { + eleCache.invalidated = false; + eleCache.texture.invalidatedWidth -= eleCache.width; + } + if (eleCache) { + return eleCache; + } + var txrH; // which texture height this ele belongs to + + if (eleScaledH <= minTxrH) { + txrH = minTxrH; + } else if (eleScaledH <= txrStepH) { + txrH = txrStepH; + } else { + txrH = Math.ceil(eleScaledH / txrStepH) * txrStepH; + } + if (eleScaledH > maxTxrH || eleScaledW > maxTxrW) { + return null; // caching large elements is not efficient + } + + var txrQ = self.getTextureQueue(txrH); + + // first try the second last one in case it has space at the end + var txr = txrQ[txrQ.length - 2]; + var addNewTxr = function addNewTxr() { + return self.recycleTexture(txrH, eleScaledW) || self.addTexture(txrH, eleScaledW); + }; + + // try the last one if there is no second last one + if (!txr) { + txr = txrQ[txrQ.length - 1]; + } + + // if the last one doesn't exist, we need a first one + if (!txr) { + txr = addNewTxr(); + } + + // if there's no room in the current texture, we need a new one + if (txr.width - txr.usedWidth < eleScaledW) { + txr = addNewTxr(); + } + var scalableFrom = function scalableFrom(otherCache) { + return otherCache && otherCache.scaledLabelShown === scaledLabelShown; + }; + var deqing = reason && reason === getTxrReasons.dequeue; + var highQualityReq = reason && reason === getTxrReasons.highQuality; + var downscaleReq = reason && reason === getTxrReasons.downscale; + var higherCache; // the nearest cache with a higher level + for (var l = lvl + 1; l <= maxLvl$1; l++) { + var c = lookup.get(ele, l); + if (c) { + higherCache = c; + break; + } + } + var oneUpCache = higherCache && higherCache.level === lvl + 1 ? higherCache : null; + var downscale = function downscale() { + txr.context.drawImage(oneUpCache.texture.canvas, oneUpCache.x, 0, oneUpCache.width, oneUpCache.height, txr.usedWidth, 0, eleScaledW, eleScaledH); + }; + + // reset ele area in texture + txr.context.setTransform(1, 0, 0, 1, 0, 0); + txr.context.clearRect(txr.usedWidth, 0, eleScaledW, txrH); + if (scalableFrom(oneUpCache)) { + // then we can relatively cheaply rescale the existing image w/o rerendering + downscale(); + } else if (scalableFrom(higherCache)) { + // then use the higher cache for now and queue the next level down + // to cheaply scale towards the smaller level + + if (highQualityReq) { + for (var _l = higherCache.level; _l > lvl; _l--) { + oneUpCache = self.getElement(ele, bb, pxRatio, _l, getTxrReasons.downscale); + } + downscale(); + } else { + self.queueElement(ele, higherCache.level - 1); + return higherCache; + } + } else { + var lowerCache; // the nearest cache with a lower level + if (!deqing && !highQualityReq && !downscaleReq) { + for (var _l2 = lvl - 1; _l2 >= minLvl$1; _l2--) { + var _c = lookup.get(ele, _l2); + if (_c) { + lowerCache = _c; + break; + } + } + } + if (scalableFrom(lowerCache)) { + // then use the lower quality cache for now and queue the better one for later + + self.queueElement(ele, lvl); + return lowerCache; + } + txr.context.translate(txr.usedWidth, 0); + txr.context.scale(scale, scale); + this.drawElement(txr.context, ele, bb, scaledLabelShown, false); + txr.context.scale(1 / scale, 1 / scale); + txr.context.translate(-txr.usedWidth, 0); + } + eleCache = { + x: txr.usedWidth, + texture: txr, + level: lvl, + scale: scale, + width: eleScaledW, + height: eleScaledH, + scaledLabelShown: scaledLabelShown + }; + txr.usedWidth += Math.ceil(eleScaledW + eleTxrSpacing); + txr.eleCaches.push(eleCache); + lookup.set(ele, lvl, eleCache); + self.checkTextureFullness(txr); + return eleCache; + }; + ETCp.invalidateElements = function (eles) { + for (var i = 0; i < eles.length; i++) { + this.invalidateElement(eles[i]); + } + }; + ETCp.invalidateElement = function (ele) { + var self = this; + var lookup = self.lookup; + var caches = []; + var invalid = lookup.isInvalid(ele); + if (!invalid) { + return; // override the invalidation request if the element key has not changed + } + + for (var lvl = minLvl$1; lvl <= maxLvl$1; lvl++) { + var cache = lookup.getForCachedKey(ele, lvl); + if (cache) { + caches.push(cache); + } + } + var noOtherElesUseCache = lookup.invalidate(ele); + if (noOtherElesUseCache) { + for (var i = 0; i < caches.length; i++) { + var _cache = caches[i]; + var txr = _cache.texture; + + // remove space from the texture it belongs to + txr.invalidatedWidth += _cache.width; + + // mark the cache as invalidated + _cache.invalidated = true; + + // retire the texture if its utility is low + self.checkTextureUtility(txr); + } + } + + // remove from queue since the old req was for the old state + self.removeFromQueue(ele); + }; + ETCp.checkTextureUtility = function (txr) { + // invalidate all entries in the cache if the cache size is small + if (txr.invalidatedWidth >= minUtility * txr.width) { + this.retireTexture(txr); + } + }; + ETCp.checkTextureFullness = function (txr) { + // if texture has been mostly filled and passed over several times, remove + // it from the queue so we don't need to waste time looking at it to put new things + + var self = this; + var txrQ = self.getTextureQueue(txr.height); + if (txr.usedWidth / txr.width > maxFullness && txr.fullnessChecks >= maxFullnessChecks) { + removeFromArray(txrQ, txr); + } else { + txr.fullnessChecks++; + } + }; + ETCp.retireTexture = function (txr) { + var self = this; + var txrH = txr.height; + var txrQ = self.getTextureQueue(txrH); + var lookup = this.lookup; + + // retire the texture from the active / searchable queue: + + removeFromArray(txrQ, txr); + txr.retired = true; + + // remove the refs from the eles to the caches: + + var eleCaches = txr.eleCaches; + for (var i = 0; i < eleCaches.length; i++) { + var eleCache = eleCaches[i]; + lookup.deleteCache(eleCache.key, eleCache.level); + } + clearArray(eleCaches); + + // add the texture to a retired queue so it can be recycled in future: + + var rtxtrQ = self.getRetiredTextureQueue(txrH); + rtxtrQ.push(txr); + }; + ETCp.addTexture = function (txrH, minW) { + var self = this; + var txrQ = self.getTextureQueue(txrH); + var txr = {}; + txrQ.push(txr); + txr.eleCaches = []; + txr.height = txrH; + txr.width = Math.max(defTxrWidth, minW); + txr.usedWidth = 0; + txr.invalidatedWidth = 0; + txr.fullnessChecks = 0; + txr.canvas = self.renderer.makeOffscreenCanvas(txr.width, txr.height); + txr.context = txr.canvas.getContext('2d'); + return txr; + }; + ETCp.recycleTexture = function (txrH, minW) { + var self = this; + var txrQ = self.getTextureQueue(txrH); + var rtxtrQ = self.getRetiredTextureQueue(txrH); + for (var i = 0; i < rtxtrQ.length; i++) { + var txr = rtxtrQ[i]; + if (txr.width >= minW) { + txr.retired = false; + txr.usedWidth = 0; + txr.invalidatedWidth = 0; + txr.fullnessChecks = 0; + clearArray(txr.eleCaches); + txr.context.setTransform(1, 0, 0, 1, 0, 0); + txr.context.clearRect(0, 0, txr.width, txr.height); + removeFromArray(rtxtrQ, txr); + txrQ.push(txr); + return txr; + } + } + }; + ETCp.queueElement = function (ele, lvl) { + var self = this; + var q = self.getElementQueue(); + var k2q = self.getElementKeyToQueue(); + var key = this.getKey(ele); + var existingReq = k2q[key]; + if (existingReq) { + // use the max lvl b/c in between lvls are cheap to make + existingReq.level = Math.max(existingReq.level, lvl); + existingReq.eles.merge(ele); + existingReq.reqs++; + q.updateItem(existingReq); + } else { + var req = { + eles: ele.spawn().merge(ele), + level: lvl, + reqs: 1, + key: key + }; + q.push(req); + k2q[key] = req; + } + }; + ETCp.dequeue = function (pxRatio /*, extent*/) { + var self = this; + var q = self.getElementQueue(); + var k2q = self.getElementKeyToQueue(); + var dequeued = []; + var lookup = self.lookup; + for (var i = 0; i < maxDeqSize$1; i++) { + if (q.size() > 0) { + var req = q.pop(); + var key = req.key; + var ele = req.eles[0]; // all eles have the same key + var cacheExists = lookup.hasCache(ele, req.level); + + // clear out the key to req lookup + k2q[key] = null; + + // dequeueing isn't necessary with an existing cache + if (cacheExists) { + continue; + } + dequeued.push(req); + var bb = self.getBoundingBox(ele); + self.getElement(ele, bb, pxRatio, req.level, getTxrReasons.dequeue); + } else { + break; + } + } + return dequeued; + }; + ETCp.removeFromQueue = function (ele) { + var self = this; + var q = self.getElementQueue(); + var k2q = self.getElementKeyToQueue(); + var key = this.getKey(ele); + var req = k2q[key]; + if (req != null) { + if (req.eles.length === 1) { + // remove if last ele in the req + // bring to front of queue + req.reqs = MAX_INT$1; + q.updateItem(req); + q.pop(); // remove from queue + + k2q[key] = null; // remove from lookup map + } else { + // otherwise just remove ele from req + req.eles.unmerge(ele); + } + } + }; + ETCp.onDequeue = function (fn) { + this.onDequeues.push(fn); + }; + ETCp.offDequeue = function (fn) { + removeFromArray(this.onDequeues, fn); + }; + ETCp.setupDequeueing = defs.setupDequeueing({ + deqRedrawThreshold: deqRedrawThreshold$1, + deqCost: deqCost$1, + deqAvgCost: deqAvgCost$1, + deqNoDrawCost: deqNoDrawCost$1, + deqFastCost: deqFastCost$1, + deq: function deq(self, pxRatio, extent) { + return self.dequeue(pxRatio, extent); + }, + onDeqd: function onDeqd(self, deqd) { + for (var i = 0; i < self.onDequeues.length; i++) { + var fn = self.onDequeues[i]; + fn(deqd); + } + }, + shouldRedraw: function shouldRedraw(self, deqd, pxRatio, extent) { + for (var i = 0; i < deqd.length; i++) { + var eles = deqd[i].eles; + for (var j = 0; j < eles.length; j++) { + var bb = eles[j].boundingBox(); + if (boundingBoxesIntersect(bb, extent)) { + return true; + } + } + } + return false; + }, + priority: function priority(self) { + return self.renderer.beforeRenderPriorities.eleTxrDeq; + } + }); + + var defNumLayers = 1; // default number of layers to use + var minLvl = -4; // when scaling smaller than that we don't need to re-render + var maxLvl = 2; // when larger than this scale just render directly (caching is not helpful) + var maxZoom = 3.99; // beyond this zoom level, layered textures are not used + var deqRedrawThreshold = 50; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile + var refineEleDebounceTime = 50; // time to debounce sharper ele texture updates + var deqCost = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame + var deqAvgCost = 0.1; // % of add'l rendering cost compared to average overall redraw time + var deqNoDrawCost = 0.9; // % of avg frame time that can be used for dequeueing when not drawing + var deqFastCost = 0.9; // % of frame time to be used when >60fps + var maxDeqSize = 1; // number of eles to dequeue and render at higher texture in each batch + var invalidThreshold = 250; // time threshold for disabling b/c of invalidations + var maxLayerArea = 4000 * 4000; // layers can't be bigger than this + var useHighQualityEleTxrReqs = true; // whether to use high quality ele txr requests (generally faster and cheaper in the longterm) + + // var log = function(){ console.log.apply( console, arguments ); }; + + var LayeredTextureCache = function LayeredTextureCache(renderer) { + var self = this; + var r = self.renderer = renderer; + var cy = r.cy; + self.layersByLevel = {}; // e.g. 2 => [ layer1, layer2, ..., layerN ] + + self.firstGet = true; + self.lastInvalidationTime = performanceNow() - 2 * invalidThreshold; + self.skipping = false; + self.eleTxrDeqs = cy.collection(); + self.scheduleElementRefinement = debounce_1(function () { + self.refineElementTextures(self.eleTxrDeqs); + self.eleTxrDeqs.unmerge(self.eleTxrDeqs); + }, refineEleDebounceTime); + r.beforeRender(function (willDraw, now) { + if (now - self.lastInvalidationTime <= invalidThreshold) { + self.skipping = true; + } else { + self.skipping = false; + } + }, r.beforeRenderPriorities.lyrTxrSkip); + var qSort = function qSort(a, b) { + return b.reqs - a.reqs; + }; + self.layersQueue = new heap(qSort); + self.setupDequeueing(); + }; + var LTCp = LayeredTextureCache.prototype; + var layerIdPool = 0; + var MAX_INT = Math.pow(2, 53) - 1; + LTCp.makeLayer = function (bb, lvl) { + var scale = Math.pow(2, lvl); + var w = Math.ceil(bb.w * scale); + var h = Math.ceil(bb.h * scale); + var canvas = this.renderer.makeOffscreenCanvas(w, h); + var layer = { + id: layerIdPool = ++layerIdPool % MAX_INT, + bb: bb, + level: lvl, + width: w, + height: h, + canvas: canvas, + context: canvas.getContext('2d'), + eles: [], + elesQueue: [], + reqs: 0 + }; + + // log('make layer %s with w %s and h %s and lvl %s', layer.id, layer.width, layer.height, layer.level); + + var cxt = layer.context; + var dx = -layer.bb.x1; + var dy = -layer.bb.y1; + + // do the transform on creation to save cycles (it's the same for all eles) + cxt.scale(scale, scale); + cxt.translate(dx, dy); + return layer; + }; + LTCp.getLayers = function (eles, pxRatio, lvl) { + var self = this; + var r = self.renderer; + var cy = r.cy; + var zoom = cy.zoom(); + var firstGet = self.firstGet; + self.firstGet = false; + + // log('--\nget layers with %s eles', eles.length); + //log eles.map(function(ele){ return ele.id() }) ); + + if (lvl == null) { + lvl = Math.ceil(log2(zoom * pxRatio)); + if (lvl < minLvl) { + lvl = minLvl; + } else if (zoom >= maxZoom || lvl > maxLvl) { + return null; + } + } + self.validateLayersElesOrdering(lvl, eles); + var layersByLvl = self.layersByLevel; + var scale = Math.pow(2, lvl); + var layers = layersByLvl[lvl] = layersByLvl[lvl] || []; + var bb; + var lvlComplete = self.levelIsComplete(lvl, eles); + var tmpLayers; + var checkTempLevels = function checkTempLevels() { + var canUseAsTmpLvl = function canUseAsTmpLvl(l) { + self.validateLayersElesOrdering(l, eles); + if (self.levelIsComplete(l, eles)) { + tmpLayers = layersByLvl[l]; + return true; + } + }; + var checkLvls = function checkLvls(dir) { + if (tmpLayers) { + return; + } + for (var l = lvl + dir; minLvl <= l && l <= maxLvl; l += dir) { + if (canUseAsTmpLvl(l)) { + break; + } + } + }; + checkLvls(+1); + checkLvls(-1); + + // remove the invalid layers; they will be replaced as needed later in this function + for (var i = layers.length - 1; i >= 0; i--) { + var layer = layers[i]; + if (layer.invalid) { + removeFromArray(layers, layer); + } + } + }; + if (!lvlComplete) { + // if the current level is incomplete, then use the closest, best quality layerset temporarily + // and later queue the current layerset so we can get the proper quality level soon + + checkTempLevels(); + } else { + // log('level complete, using existing layers\n--'); + return layers; + } + var getBb = function getBb() { + if (!bb) { + bb = makeBoundingBox(); + for (var i = 0; i < eles.length; i++) { + updateBoundingBox(bb, eles[i].boundingBox()); + } + } + return bb; + }; + var makeLayer = function makeLayer(opts) { + opts = opts || {}; + var after = opts.after; + getBb(); + var area = bb.w * scale * (bb.h * scale); + if (area > maxLayerArea) { + return null; + } + var layer = self.makeLayer(bb, lvl); + if (after != null) { + var index = layers.indexOf(after) + 1; + layers.splice(index, 0, layer); + } else if (opts.insert === undefined || opts.insert) { + // no after specified => first layer made so put at start + layers.unshift(layer); + } + + // if( tmpLayers ){ + //self.queueLayer( layer ); + // } + + return layer; + }; + if (self.skipping && !firstGet) { + // log('skip layers'); + return null; + } + + // log('do layers'); + + var layer = null; + var maxElesPerLayer = eles.length / defNumLayers; + var allowLazyQueueing = !firstGet; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + var rs = ele._private.rscratch; + var caches = rs.imgLayerCaches = rs.imgLayerCaches || {}; + + // log('look at ele', ele.id()); + + var existingLayer = caches[lvl]; + if (existingLayer) { + // reuse layer for later eles + // log('reuse layer for', ele.id()); + layer = existingLayer; + continue; + } + if (!layer || layer.eles.length >= maxElesPerLayer || !boundingBoxInBoundingBox(layer.bb, ele.boundingBox())) { + // log('make new layer for ele %s', ele.id()); + + layer = makeLayer({ + insert: true, + after: layer + }); + + // if now layer can be built then we can't use layers at this level + if (!layer) { + return null; + } + + // log('new layer with id %s', layer.id); + } + + if (tmpLayers || allowLazyQueueing) { + // log('queue ele %s in layer %s', ele.id(), layer.id); + self.queueLayer(layer, ele); + } else { + // log('draw ele %s in layer %s', ele.id(), layer.id); + self.drawEleInLayer(layer, ele, lvl, pxRatio); + } + layer.eles.push(ele); + caches[lvl] = layer; + } + + // log('--'); + + if (tmpLayers) { + // then we only queued the current layerset and can't draw it yet + return tmpLayers; + } + if (allowLazyQueueing) { + // log('lazy queue level', lvl); + return null; + } + return layers; + }; + + // a layer may want to use an ele cache of a higher level to avoid blurriness + // so the layer level might not equal the ele level + LTCp.getEleLevelForLayerLevel = function (lvl, pxRatio) { + return lvl; + }; + LTCp.drawEleInLayer = function (layer, ele, lvl, pxRatio) { + var self = this; + var r = this.renderer; + var context = layer.context; + var bb = ele.boundingBox(); + if (bb.w === 0 || bb.h === 0 || !ele.visible()) { + return; + } + lvl = self.getEleLevelForLayerLevel(lvl, pxRatio); + { + r.setImgSmoothing(context, false); + } + { + r.drawCachedElement(context, ele, null, null, lvl, useHighQualityEleTxrReqs); + } + { + r.setImgSmoothing(context, true); + } + }; + LTCp.levelIsComplete = function (lvl, eles) { + var self = this; + var layers = self.layersByLevel[lvl]; + if (!layers || layers.length === 0) { + return false; + } + var numElesInLayers = 0; + for (var i = 0; i < layers.length; i++) { + var layer = layers[i]; + + // if there are any eles needed to be drawn yet, the level is not complete + if (layer.reqs > 0) { + return false; + } + + // if the layer is invalid, the level is not complete + if (layer.invalid) { + return false; + } + numElesInLayers += layer.eles.length; + } + + // we should have exactly the number of eles passed in to be complete + if (numElesInLayers !== eles.length) { + return false; + } + return true; + }; + LTCp.validateLayersElesOrdering = function (lvl, eles) { + var layers = this.layersByLevel[lvl]; + if (!layers) { + return; + } + + // if in a layer the eles are not in the same order, then the layer is invalid + // (i.e. there is an ele in between the eles in the layer) + + for (var i = 0; i < layers.length; i++) { + var layer = layers[i]; + var offset = -1; + + // find the offset + for (var j = 0; j < eles.length; j++) { + if (layer.eles[0] === eles[j]) { + offset = j; + break; + } + } + if (offset < 0) { + // then the layer has nonexistent elements and is invalid + this.invalidateLayer(layer); + continue; + } + + // the eles in the layer must be in the same continuous order, else the layer is invalid + + var o = offset; + for (var j = 0; j < layer.eles.length; j++) { + if (layer.eles[j] !== eles[o + j]) { + // log('invalidate based on ordering', layer.id); + + this.invalidateLayer(layer); + break; + } + } + } + }; + LTCp.updateElementsInLayers = function (eles, update) { + var self = this; + var isEles = element(eles[0]); + + // collect udpated elements (cascaded from the layers) and update each + // layer itself along the way + for (var i = 0; i < eles.length; i++) { + var req = isEles ? null : eles[i]; + var ele = isEles ? eles[i] : eles[i].ele; + var rs = ele._private.rscratch; + var caches = rs.imgLayerCaches = rs.imgLayerCaches || {}; + for (var l = minLvl; l <= maxLvl; l++) { + var layer = caches[l]; + if (!layer) { + continue; + } + + // if update is a request from the ele cache, then it affects only + // the matching level + if (req && self.getEleLevelForLayerLevel(layer.level) !== req.level) { + continue; + } + update(layer, ele, req); + } + } + }; + LTCp.haveLayers = function () { + var self = this; + var haveLayers = false; + for (var l = minLvl; l <= maxLvl; l++) { + var layers = self.layersByLevel[l]; + if (layers && layers.length > 0) { + haveLayers = true; + break; + } + } + return haveLayers; + }; + LTCp.invalidateElements = function (eles) { + var self = this; + if (eles.length === 0) { + return; + } + self.lastInvalidationTime = performanceNow(); + + // log('update invalidate layer time from eles'); + + if (eles.length === 0 || !self.haveLayers()) { + return; + } + self.updateElementsInLayers(eles, function invalAssocLayers(layer, ele, req) { + self.invalidateLayer(layer); + }); + }; + LTCp.invalidateLayer = function (layer) { + // log('update invalidate layer time'); + + this.lastInvalidationTime = performanceNow(); + if (layer.invalid) { + return; + } // save cycles + + var lvl = layer.level; + var eles = layer.eles; + var layers = this.layersByLevel[lvl]; + + // log('invalidate layer', layer.id ); + + removeFromArray(layers, layer); + // layer.eles = []; + + layer.elesQueue = []; + layer.invalid = true; + if (layer.replacement) { + layer.replacement.invalid = true; + } + for (var i = 0; i < eles.length; i++) { + var caches = eles[i]._private.rscratch.imgLayerCaches; + if (caches) { + caches[lvl] = null; + } + } + }; + LTCp.refineElementTextures = function (eles) { + var self = this; + + // log('refine', eles.length); + + self.updateElementsInLayers(eles, function refineEachEle(layer, ele, req) { + var rLyr = layer.replacement; + if (!rLyr) { + rLyr = layer.replacement = self.makeLayer(layer.bb, layer.level); + rLyr.replaces = layer; + rLyr.eles = layer.eles; + + // log('make replacement layer %s for %s with level %s', rLyr.id, layer.id, rLyr.level); + } + + if (!rLyr.reqs) { + for (var i = 0; i < rLyr.eles.length; i++) { + self.queueLayer(rLyr, rLyr.eles[i]); + } + + // log('queue replacement layer refinement', rLyr.id); + } + }); + }; + + LTCp.enqueueElementRefinement = function (ele) { + this.eleTxrDeqs.merge(ele); + this.scheduleElementRefinement(); + }; + LTCp.queueLayer = function (layer, ele) { + var self = this; + var q = self.layersQueue; + var elesQ = layer.elesQueue; + var hasId = elesQ.hasId = elesQ.hasId || {}; + + // if a layer is going to be replaced, queuing is a waste of time + if (layer.replacement) { + return; + } + if (ele) { + if (hasId[ele.id()]) { + return; + } + elesQ.push(ele); + hasId[ele.id()] = true; + } + if (layer.reqs) { + layer.reqs++; + q.updateItem(layer); + } else { + layer.reqs = 1; + q.push(layer); + } + }; + LTCp.dequeue = function (pxRatio) { + var self = this; + var q = self.layersQueue; + var deqd = []; + var eleDeqs = 0; + while (eleDeqs < maxDeqSize) { + if (q.size() === 0) { + break; + } + var layer = q.peek(); + + // if a layer has been or will be replaced, then don't waste time with it + if (layer.replacement) { + // log('layer %s in queue skipped b/c it already has a replacement', layer.id); + q.pop(); + continue; + } + + // if this is a replacement layer that has been superceded, then forget it + if (layer.replaces && layer !== layer.replaces.replacement) { + // log('layer is no longer the most uptodate replacement; dequeued', layer.id) + q.pop(); + continue; + } + if (layer.invalid) { + // log('replacement layer %s is invalid; dequeued', layer.id); + q.pop(); + continue; + } + var ele = layer.elesQueue.shift(); + if (ele) { + // log('dequeue layer %s', layer.id); + + self.drawEleInLayer(layer, ele, layer.level, pxRatio); + eleDeqs++; + } + if (deqd.length === 0) { + // we need only one entry in deqd to queue redrawing etc + deqd.push(true); + } + + // if the layer has all its eles done, then remove from the queue + if (layer.elesQueue.length === 0) { + q.pop(); + layer.reqs = 0; + + // log('dequeue of layer %s complete', layer.id); + + // when a replacement layer is dequeued, it replaces the old layer in the level + if (layer.replaces) { + self.applyLayerReplacement(layer); + } + self.requestRedraw(); + } + } + return deqd; + }; + LTCp.applyLayerReplacement = function (layer) { + var self = this; + var layersInLevel = self.layersByLevel[layer.level]; + var replaced = layer.replaces; + var index = layersInLevel.indexOf(replaced); + + // if the replaced layer is not in the active list for the level, then replacing + // refs would be a mistake (i.e. overwriting the true active layer) + if (index < 0 || replaced.invalid) { + // log('replacement layer would have no effect', layer.id); + return; + } + layersInLevel[index] = layer; // replace level ref + + // replace refs in eles + for (var i = 0; i < layer.eles.length; i++) { + var _p = layer.eles[i]._private; + var cache = _p.imgLayerCaches = _p.imgLayerCaches || {}; + if (cache) { + cache[layer.level] = layer; + } + } + + // log('apply replacement layer %s over %s', layer.id, replaced.id); + + self.requestRedraw(); + }; + LTCp.requestRedraw = debounce_1(function () { + var r = this.renderer; + r.redrawHint('eles', true); + r.redrawHint('drag', true); + r.redraw(); + }, 100); + LTCp.setupDequeueing = defs.setupDequeueing({ + deqRedrawThreshold: deqRedrawThreshold, + deqCost: deqCost, + deqAvgCost: deqAvgCost, + deqNoDrawCost: deqNoDrawCost, + deqFastCost: deqFastCost, + deq: function deq(self, pxRatio) { + return self.dequeue(pxRatio); + }, + onDeqd: noop$1, + shouldRedraw: trueify, + priority: function priority(self) { + return self.renderer.beforeRenderPriorities.lyrTxrDeq; + } + }); + + var CRp$a = {}; + var impl; + function polygon(context, points) { + for (var i = 0; i < points.length; i++) { + var pt = points[i]; + context.lineTo(pt.x, pt.y); + } + } + function triangleBackcurve(context, points, controlPoint) { + var firstPt; + for (var i = 0; i < points.length; i++) { + var pt = points[i]; + if (i === 0) { + firstPt = pt; + } + context.lineTo(pt.x, pt.y); + } + context.quadraticCurveTo(controlPoint.x, controlPoint.y, firstPt.x, firstPt.y); + } + function triangleTee(context, trianglePoints, teePoints) { + if (context.beginPath) { + context.beginPath(); + } + var triPts = trianglePoints; + for (var i = 0; i < triPts.length; i++) { + var pt = triPts[i]; + context.lineTo(pt.x, pt.y); + } + var teePts = teePoints; + var firstTeePt = teePoints[0]; + context.moveTo(firstTeePt.x, firstTeePt.y); + for (var i = 1; i < teePts.length; i++) { + var pt = teePts[i]; + context.lineTo(pt.x, pt.y); + } + if (context.closePath) { + context.closePath(); + } + } + function circleTriangle(context, trianglePoints, rx, ry, r) { + if (context.beginPath) { + context.beginPath(); + } + context.arc(rx, ry, r, 0, Math.PI * 2, false); + var triPts = trianglePoints; + var firstTrPt = triPts[0]; + context.moveTo(firstTrPt.x, firstTrPt.y); + for (var i = 0; i < triPts.length; i++) { + var pt = triPts[i]; + context.lineTo(pt.x, pt.y); + } + if (context.closePath) { + context.closePath(); + } + } + function circle(context, rx, ry, r) { + context.arc(rx, ry, r, 0, Math.PI * 2, false); + } + CRp$a.arrowShapeImpl = function (name) { + return (impl || (impl = { + 'polygon': polygon, + 'triangle-backcurve': triangleBackcurve, + 'triangle-tee': triangleTee, + 'circle-triangle': circleTriangle, + 'triangle-cross': triangleTee, + 'circle': circle + }))[name]; + }; + + var CRp$9 = {}; + CRp$9.drawElement = function (context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity) { + var r = this; + if (ele.isNode()) { + r.drawNode(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity); + } else { + r.drawEdge(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity); + } + }; + CRp$9.drawElementOverlay = function (context, ele) { + var r = this; + if (ele.isNode()) { + r.drawNodeOverlay(context, ele); + } else { + r.drawEdgeOverlay(context, ele); + } + }; + CRp$9.drawElementUnderlay = function (context, ele) { + var r = this; + if (ele.isNode()) { + r.drawNodeUnderlay(context, ele); + } else { + r.drawEdgeUnderlay(context, ele); + } + }; + CRp$9.drawCachedElementPortion = function (context, ele, eleTxrCache, pxRatio, lvl, reason, getRotation, getOpacity) { + var r = this; + var bb = eleTxrCache.getBoundingBox(ele); + if (bb.w === 0 || bb.h === 0) { + return; + } // ignore zero size case + + var eleCache = eleTxrCache.getElement(ele, bb, pxRatio, lvl, reason); + if (eleCache != null) { + var opacity = getOpacity(r, ele); + if (opacity === 0) { + return; + } + var theta = getRotation(r, ele); + var x1 = bb.x1, + y1 = bb.y1, + w = bb.w, + h = bb.h; + var x, y, sx, sy, smooth; + if (theta !== 0) { + var rotPt = eleTxrCache.getRotationPoint(ele); + sx = rotPt.x; + sy = rotPt.y; + context.translate(sx, sy); + context.rotate(theta); + smooth = r.getImgSmoothing(context); + if (!smooth) { + r.setImgSmoothing(context, true); + } + var off = eleTxrCache.getRotationOffset(ele); + x = off.x; + y = off.y; + } else { + x = x1; + y = y1; + } + var oldGlobalAlpha; + if (opacity !== 1) { + oldGlobalAlpha = context.globalAlpha; + context.globalAlpha = oldGlobalAlpha * opacity; + } + context.drawImage(eleCache.texture.canvas, eleCache.x, 0, eleCache.width, eleCache.height, x, y, w, h); + if (opacity !== 1) { + context.globalAlpha = oldGlobalAlpha; + } + if (theta !== 0) { + context.rotate(-theta); + context.translate(-sx, -sy); + if (!smooth) { + r.setImgSmoothing(context, false); + } + } + } else { + eleTxrCache.drawElement(context, ele); // direct draw fallback + } + }; + + var getZeroRotation = function getZeroRotation() { + return 0; + }; + var getLabelRotation = function getLabelRotation(r, ele) { + return r.getTextAngle(ele, null); + }; + var getSourceLabelRotation = function getSourceLabelRotation(r, ele) { + return r.getTextAngle(ele, 'source'); + }; + var getTargetLabelRotation = function getTargetLabelRotation(r, ele) { + return r.getTextAngle(ele, 'target'); + }; + var getOpacity = function getOpacity(r, ele) { + return ele.effectiveOpacity(); + }; + var getTextOpacity = function getTextOpacity(e, ele) { + return ele.pstyle('text-opacity').pfValue * ele.effectiveOpacity(); + }; + CRp$9.drawCachedElement = function (context, ele, pxRatio, extent, lvl, requestHighQuality) { + var r = this; + var _r$data = r.data, + eleTxrCache = _r$data.eleTxrCache, + lblTxrCache = _r$data.lblTxrCache, + slbTxrCache = _r$data.slbTxrCache, + tlbTxrCache = _r$data.tlbTxrCache; + var bb = ele.boundingBox(); + var reason = requestHighQuality === true ? eleTxrCache.reasons.highQuality : null; + if (bb.w === 0 || bb.h === 0 || !ele.visible()) { + return; + } + if (!extent || boundingBoxesIntersect(bb, extent)) { + var isEdge = ele.isEdge(); + var badLine = ele.element()._private.rscratch.badLine; + r.drawElementUnderlay(context, ele); + r.drawCachedElementPortion(context, ele, eleTxrCache, pxRatio, lvl, reason, getZeroRotation, getOpacity); + if (!isEdge || !badLine) { + r.drawCachedElementPortion(context, ele, lblTxrCache, pxRatio, lvl, reason, getLabelRotation, getTextOpacity); + } + if (isEdge && !badLine) { + r.drawCachedElementPortion(context, ele, slbTxrCache, pxRatio, lvl, reason, getSourceLabelRotation, getTextOpacity); + r.drawCachedElementPortion(context, ele, tlbTxrCache, pxRatio, lvl, reason, getTargetLabelRotation, getTextOpacity); + } + r.drawElementOverlay(context, ele); + } + }; + CRp$9.drawElements = function (context, eles) { + var r = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + r.drawElement(context, ele); + } + }; + CRp$9.drawCachedElements = function (context, eles, pxRatio, extent) { + var r = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + r.drawCachedElement(context, ele, pxRatio, extent); + } + }; + CRp$9.drawCachedNodes = function (context, eles, pxRatio, extent) { + var r = this; + for (var i = 0; i < eles.length; i++) { + var ele = eles[i]; + if (!ele.isNode()) { + continue; + } + r.drawCachedElement(context, ele, pxRatio, extent); + } + }; + CRp$9.drawLayeredElements = function (context, eles, pxRatio, extent) { + var r = this; + var layers = r.data.lyrTxrCache.getLayers(eles, pxRatio); + if (layers) { + for (var i = 0; i < layers.length; i++) { + var layer = layers[i]; + var bb = layer.bb; + if (bb.w === 0 || bb.h === 0) { + continue; + } + context.drawImage(layer.canvas, bb.x1, bb.y1, bb.w, bb.h); + } + } else { + // fall back on plain caching if no layers + r.drawCachedElements(context, eles, pxRatio, extent); + } + }; + + /* global Path2D */ + var CRp$8 = {}; + CRp$8.drawEdge = function (context, edge, shiftToOriginWithBb) { + var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + var r = this; + var rs = edge._private.rscratch; + if (shouldDrawOpacity && !edge.visible()) { + return; + } + + // if bezier ctrl pts can not be calculated, then die + if (rs.badLine || rs.allpts == null || isNaN(rs.allpts[0])) { + // isNaN in case edge is impossible and browser bugs (e.g. safari) + return; + } + var bb; + if (shiftToOriginWithBb) { + bb = shiftToOriginWithBb; + context.translate(-bb.x1, -bb.y1); + } + var opacity = shouldDrawOpacity ? edge.pstyle('opacity').value : 1; + var lineOpacity = shouldDrawOpacity ? edge.pstyle('line-opacity').value : 1; + var curveStyle = edge.pstyle('curve-style').value; + var lineStyle = edge.pstyle('line-style').value; + var edgeWidth = edge.pstyle('width').pfValue; + var lineCap = edge.pstyle('line-cap').value; + var effectiveLineOpacity = opacity * lineOpacity; + // separate arrow opacity would require arrow-opacity property + var effectiveArrowOpacity = opacity * lineOpacity; + var drawLine = function drawLine() { + var strokeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveLineOpacity; + if (curveStyle === 'straight-triangle') { + r.eleStrokeStyle(context, edge, strokeOpacity); + r.drawEdgeTrianglePath(edge, context, rs.allpts); + } else { + context.lineWidth = edgeWidth; + context.lineCap = lineCap; + r.eleStrokeStyle(context, edge, strokeOpacity); + r.drawEdgePath(edge, context, rs.allpts, lineStyle); + context.lineCap = 'butt'; // reset for other drawing functions + } + }; + + var drawOverlay = function drawOverlay() { + if (!shouldDrawOverlay) { + return; + } + r.drawEdgeOverlay(context, edge); + }; + var drawUnderlay = function drawUnderlay() { + if (!shouldDrawOverlay) { + return; + } + r.drawEdgeUnderlay(context, edge); + }; + var drawArrows = function drawArrows() { + var arrowOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveArrowOpacity; + r.drawArrowheads(context, edge, arrowOpacity); + }; + var drawText = function drawText() { + r.drawElementText(context, edge, null, drawLabel); + }; + context.lineJoin = 'round'; + var ghost = edge.pstyle('ghost').value === 'yes'; + if (ghost) { + var gx = edge.pstyle('ghost-offset-x').pfValue; + var gy = edge.pstyle('ghost-offset-y').pfValue; + var ghostOpacity = edge.pstyle('ghost-opacity').value; + var effectiveGhostOpacity = effectiveLineOpacity * ghostOpacity; + context.translate(gx, gy); + drawLine(effectiveGhostOpacity); + drawArrows(effectiveGhostOpacity); + context.translate(-gx, -gy); + } + drawUnderlay(); + drawLine(); + drawArrows(); + drawOverlay(); + drawText(); + if (shiftToOriginWithBb) { + context.translate(bb.x1, bb.y1); + } + }; + var drawEdgeOverlayUnderlay = function drawEdgeOverlayUnderlay(overlayOrUnderlay) { + if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) { + throw new Error('Invalid state'); + } + return function (context, edge) { + if (!edge.visible()) { + return; + } + var opacity = edge.pstyle("".concat(overlayOrUnderlay, "-opacity")).value; + if (opacity === 0) { + return; + } + var r = this; + var usePaths = r.usePaths(); + var rs = edge._private.rscratch; + var padding = edge.pstyle("".concat(overlayOrUnderlay, "-padding")).pfValue; + var width = 2 * padding; + var color = edge.pstyle("".concat(overlayOrUnderlay, "-color")).value; + context.lineWidth = width; + if (rs.edgeType === 'self' && !usePaths) { + context.lineCap = 'butt'; + } else { + context.lineCap = 'round'; + } + r.colorStrokeStyle(context, color[0], color[1], color[2], opacity); + r.drawEdgePath(edge, context, rs.allpts, 'solid'); + }; + }; + CRp$8.drawEdgeOverlay = drawEdgeOverlayUnderlay('overlay'); + CRp$8.drawEdgeUnderlay = drawEdgeOverlayUnderlay('underlay'); + CRp$8.drawEdgePath = function (edge, context, pts, type) { + var rs = edge._private.rscratch; + var canvasCxt = context; + var path; + var pathCacheHit = false; + var usePaths = this.usePaths(); + var lineDashPattern = edge.pstyle('line-dash-pattern').pfValue; + var lineDashOffset = edge.pstyle('line-dash-offset').pfValue; + if (usePaths) { + var pathCacheKey = pts.join('$'); + var keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey; + if (keyMatches) { + path = context = rs.pathCache; + pathCacheHit = true; + } else { + path = context = new Path2D(); + rs.pathCacheKey = pathCacheKey; + rs.pathCache = path; + } + } + if (canvasCxt.setLineDash) { + // for very outofdate browsers + switch (type) { + case 'dotted': + canvasCxt.setLineDash([1, 1]); + break; + case 'dashed': + canvasCxt.setLineDash(lineDashPattern); + canvasCxt.lineDashOffset = lineDashOffset; + break; + case 'solid': + canvasCxt.setLineDash([]); + break; + } + } + if (!pathCacheHit && !rs.badLine) { + if (context.beginPath) { + context.beginPath(); + } + context.moveTo(pts[0], pts[1]); + switch (rs.edgeType) { + case 'bezier': + case 'self': + case 'compound': + case 'multibezier': + for (var i = 2; i + 3 < pts.length; i += 4) { + context.quadraticCurveTo(pts[i], pts[i + 1], pts[i + 2], pts[i + 3]); + } + break; + case 'straight': + case 'segments': + case 'haystack': + for (var _i = 2; _i + 1 < pts.length; _i += 2) { + context.lineTo(pts[_i], pts[_i + 1]); + } + break; + } + } + context = canvasCxt; + if (usePaths) { + context.stroke(path); + } else { + context.stroke(); + } + + // reset any line dashes + if (context.setLineDash) { + // for very outofdate browsers + context.setLineDash([]); + } + }; + CRp$8.drawEdgeTrianglePath = function (edge, context, pts) { + // use line stroke style for triangle fill style + context.fillStyle = context.strokeStyle; + var edgeWidth = edge.pstyle('width').pfValue; + for (var i = 0; i + 1 < pts.length; i += 2) { + var vector = [pts[i + 2] - pts[i], pts[i + 3] - pts[i + 1]]; + var length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]); + var normal = [vector[1] / length, -vector[0] / length]; + var triangleHead = [normal[0] * edgeWidth / 2, normal[1] * edgeWidth / 2]; + context.beginPath(); + context.moveTo(pts[i] - triangleHead[0], pts[i + 1] - triangleHead[1]); + context.lineTo(pts[i] + triangleHead[0], pts[i + 1] + triangleHead[1]); + context.lineTo(pts[i + 2], pts[i + 3]); + context.closePath(); + context.fill(); + } + }; + CRp$8.drawArrowheads = function (context, edge, opacity) { + var rs = edge._private.rscratch; + var isHaystack = rs.edgeType === 'haystack'; + if (!isHaystack) { + this.drawArrowhead(context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle, opacity); + } + this.drawArrowhead(context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle, opacity); + this.drawArrowhead(context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle, opacity); + if (!isHaystack) { + this.drawArrowhead(context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle, opacity); + } + }; + CRp$8.drawArrowhead = function (context, edge, prefix, x, y, angle, opacity) { + if (isNaN(x) || x == null || isNaN(y) || y == null || isNaN(angle) || angle == null) { + return; + } + var self = this; + var arrowShape = edge.pstyle(prefix + '-arrow-shape').value; + if (arrowShape === 'none') { + return; + } + var arrowClearFill = edge.pstyle(prefix + '-arrow-fill').value === 'hollow' ? 'both' : 'filled'; + var arrowFill = edge.pstyle(prefix + '-arrow-fill').value; + var edgeWidth = edge.pstyle('width').pfValue; + var edgeOpacity = edge.pstyle('opacity').value; + if (opacity === undefined) { + opacity = edgeOpacity; + } + var gco = context.globalCompositeOperation; + if (opacity !== 1 || arrowFill === 'hollow') { + // then extra clear is needed + context.globalCompositeOperation = 'destination-out'; + self.colorFillStyle(context, 255, 255, 255, 1); + self.colorStrokeStyle(context, 255, 255, 255, 1); + self.drawArrowShape(edge, context, arrowClearFill, edgeWidth, arrowShape, x, y, angle); + context.globalCompositeOperation = gco; + } // otherwise, the opaque arrow clears it for free :) + + var color = edge.pstyle(prefix + '-arrow-color').value; + self.colorFillStyle(context, color[0], color[1], color[2], opacity); + self.colorStrokeStyle(context, color[0], color[1], color[2], opacity); + self.drawArrowShape(edge, context, arrowFill, edgeWidth, arrowShape, x, y, angle); + }; + CRp$8.drawArrowShape = function (edge, context, fill, edgeWidth, shape, x, y, angle) { + var r = this; + var usePaths = this.usePaths() && shape !== 'triangle-cross'; + var pathCacheHit = false; + var path; + var canvasContext = context; + var translation = { + x: x, + y: y + }; + var scale = edge.pstyle('arrow-scale').value; + var size = this.getArrowWidth(edgeWidth, scale); + var shapeImpl = r.arrowShapes[shape]; + if (usePaths) { + var cache = r.arrowPathCache = r.arrowPathCache || []; + var key = hashString(shape); + var cachedPath = cache[key]; + if (cachedPath != null) { + path = context = cachedPath; + pathCacheHit = true; + } else { + path = context = new Path2D(); + cache[key] = path; + } + } + if (!pathCacheHit) { + if (context.beginPath) { + context.beginPath(); + } + if (usePaths) { + // store in the path cache with values easily manipulated later + shapeImpl.draw(context, 1, 0, { + x: 0, + y: 0 + }, 1); + } else { + shapeImpl.draw(context, size, angle, translation, edgeWidth); + } + if (context.closePath) { + context.closePath(); + } + } + context = canvasContext; + if (usePaths) { + // set transform to arrow position/orientation + context.translate(x, y); + context.rotate(angle); + context.scale(size, size); + } + if (fill === 'filled' || fill === 'both') { + if (usePaths) { + context.fill(path); + } else { + context.fill(); + } + } + if (fill === 'hollow' || fill === 'both') { + context.lineWidth = (shapeImpl.matchEdgeWidth ? edgeWidth : 1) / (usePaths ? size : 1); + context.lineJoin = 'miter'; + if (usePaths) { + context.stroke(path); + } else { + context.stroke(); + } + } + if (usePaths) { + // reset transform by applying inverse + context.scale(1 / size, 1 / size); + context.rotate(-angle); + context.translate(-x, -y); + } + }; + + var CRp$7 = {}; + CRp$7.safeDrawImage = function (context, img, ix, iy, iw, ih, x, y, w, h) { + // detect problematic cases for old browsers with bad images (cheaper than try-catch) + if (iw <= 0 || ih <= 0 || w <= 0 || h <= 0) { + return; + } + try { + context.drawImage(img, ix, iy, iw, ih, x, y, w, h); + } catch (e) { + warn(e); + } + }; + CRp$7.drawInscribedImage = function (context, img, node, index, nodeOpacity) { + var r = this; + var pos = node.position(); + var nodeX = pos.x; + var nodeY = pos.y; + var styleObj = node.cy().style(); + var getIndexedStyle = styleObj.getIndexedStyle.bind(styleObj); + var fit = getIndexedStyle(node, 'background-fit', 'value', index); + var repeat = getIndexedStyle(node, 'background-repeat', 'value', index); + var nodeW = node.width(); + var nodeH = node.height(); + var paddingX2 = node.padding() * 2; + var nodeTW = nodeW + (getIndexedStyle(node, 'background-width-relative-to', 'value', index) === 'inner' ? 0 : paddingX2); + var nodeTH = nodeH + (getIndexedStyle(node, 'background-height-relative-to', 'value', index) === 'inner' ? 0 : paddingX2); + var rs = node._private.rscratch; + var clip = getIndexedStyle(node, 'background-clip', 'value', index); + var shouldClip = clip === 'node'; + var imgOpacity = getIndexedStyle(node, 'background-image-opacity', 'value', index) * nodeOpacity; + var smooth = getIndexedStyle(node, 'background-image-smoothing', 'value', index); + var imgW = img.width || img.cachedW; + var imgH = img.height || img.cachedH; + + // workaround for broken browsers like ie + if (null == imgW || null == imgH) { + document.body.appendChild(img); // eslint-disable-line no-undef + + imgW = img.cachedW = img.width || img.offsetWidth; + imgH = img.cachedH = img.height || img.offsetHeight; + document.body.removeChild(img); // eslint-disable-line no-undef + } + + var w = imgW; + var h = imgH; + if (getIndexedStyle(node, 'background-width', 'value', index) !== 'auto') { + if (getIndexedStyle(node, 'background-width', 'units', index) === '%') { + w = getIndexedStyle(node, 'background-width', 'pfValue', index) * nodeTW; + } else { + w = getIndexedStyle(node, 'background-width', 'pfValue', index); + } + } + if (getIndexedStyle(node, 'background-height', 'value', index) !== 'auto') { + if (getIndexedStyle(node, 'background-height', 'units', index) === '%') { + h = getIndexedStyle(node, 'background-height', 'pfValue', index) * nodeTH; + } else { + h = getIndexedStyle(node, 'background-height', 'pfValue', index); + } + } + if (w === 0 || h === 0) { + return; // no point in drawing empty image (and chrome is broken in this case) + } + + if (fit === 'contain') { + var scale = Math.min(nodeTW / w, nodeTH / h); + w *= scale; + h *= scale; + } else if (fit === 'cover') { + var scale = Math.max(nodeTW / w, nodeTH / h); + w *= scale; + h *= scale; + } + var x = nodeX - nodeTW / 2; // left + var posXUnits = getIndexedStyle(node, 'background-position-x', 'units', index); + var posXPfVal = getIndexedStyle(node, 'background-position-x', 'pfValue', index); + if (posXUnits === '%') { + x += (nodeTW - w) * posXPfVal; + } else { + x += posXPfVal; + } + var offXUnits = getIndexedStyle(node, 'background-offset-x', 'units', index); + var offXPfVal = getIndexedStyle(node, 'background-offset-x', 'pfValue', index); + if (offXUnits === '%') { + x += (nodeTW - w) * offXPfVal; + } else { + x += offXPfVal; + } + var y = nodeY - nodeTH / 2; // top + var posYUnits = getIndexedStyle(node, 'background-position-y', 'units', index); + var posYPfVal = getIndexedStyle(node, 'background-position-y', 'pfValue', index); + if (posYUnits === '%') { + y += (nodeTH - h) * posYPfVal; + } else { + y += posYPfVal; + } + var offYUnits = getIndexedStyle(node, 'background-offset-y', 'units', index); + var offYPfVal = getIndexedStyle(node, 'background-offset-y', 'pfValue', index); + if (offYUnits === '%') { + y += (nodeTH - h) * offYPfVal; + } else { + y += offYPfVal; + } + if (rs.pathCache) { + x -= nodeX; + y -= nodeY; + nodeX = 0; + nodeY = 0; + } + var gAlpha = context.globalAlpha; + context.globalAlpha = imgOpacity; + var smoothingEnabled = r.getImgSmoothing(context); + var isSmoothingSwitched = false; + if (smooth === 'no' && smoothingEnabled) { + r.setImgSmoothing(context, false); + isSmoothingSwitched = true; + } else if (smooth === 'yes' && !smoothingEnabled) { + r.setImgSmoothing(context, true); + isSmoothingSwitched = true; + } + if (repeat === 'no-repeat') { + if (shouldClip) { + context.save(); + if (rs.pathCache) { + context.clip(rs.pathCache); + } else { + r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH); + context.clip(); + } + } + r.safeDrawImage(context, img, 0, 0, imgW, imgH, x, y, w, h); + if (shouldClip) { + context.restore(); + } + } else { + var pattern = context.createPattern(img, repeat); + context.fillStyle = pattern; + r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH); + context.translate(x, y); + context.fill(); + context.translate(-x, -y); + } + context.globalAlpha = gAlpha; + if (isSmoothingSwitched) { + r.setImgSmoothing(context, smoothingEnabled); + } + }; + + var CRp$6 = {}; + CRp$6.eleTextBiggerThanMin = function (ele, scale) { + if (!scale) { + var zoom = ele.cy().zoom(); + var pxRatio = this.getPixelRatio(); + var lvl = Math.ceil(log2(zoom * pxRatio)); // the effective texture level + + scale = Math.pow(2, lvl); + } + var computedSize = ele.pstyle('font-size').pfValue * scale; + var minSize = ele.pstyle('min-zoomed-font-size').pfValue; + if (computedSize < minSize) { + return false; + } + return true; + }; + CRp$6.drawElementText = function (context, ele, shiftToOriginWithBb, force, prefix) { + var useEleOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + var r = this; + if (force == null) { + if (useEleOpacity && !r.eleTextBiggerThanMin(ele)) { + return; + } + } else if (force === false) { + return; + } + if (ele.isNode()) { + var label = ele.pstyle('label'); + if (!label || !label.value) { + return; + } + var justification = r.getLabelJustification(ele); + context.textAlign = justification; + context.textBaseline = 'bottom'; + } else { + var badLine = ele.element()._private.rscratch.badLine; + var _label = ele.pstyle('label'); + var srcLabel = ele.pstyle('source-label'); + var tgtLabel = ele.pstyle('target-label'); + if (badLine || (!_label || !_label.value) && (!srcLabel || !srcLabel.value) && (!tgtLabel || !tgtLabel.value)) { + return; + } + context.textAlign = 'center'; + context.textBaseline = 'bottom'; + } + var applyRotation = !shiftToOriginWithBb; + var bb; + if (shiftToOriginWithBb) { + bb = shiftToOriginWithBb; + context.translate(-bb.x1, -bb.y1); + } + if (prefix == null) { + r.drawText(context, ele, null, applyRotation, useEleOpacity); + if (ele.isEdge()) { + r.drawText(context, ele, 'source', applyRotation, useEleOpacity); + r.drawText(context, ele, 'target', applyRotation, useEleOpacity); + } + } else { + r.drawText(context, ele, prefix, applyRotation, useEleOpacity); + } + if (shiftToOriginWithBb) { + context.translate(bb.x1, bb.y1); + } + }; + CRp$6.getFontCache = function (context) { + var cache; + this.fontCaches = this.fontCaches || []; + for (var i = 0; i < this.fontCaches.length; i++) { + cache = this.fontCaches[i]; + if (cache.context === context) { + return cache; + } + } + cache = { + context: context + }; + this.fontCaches.push(cache); + return cache; + }; + + // set up canvas context with font + // returns transformed text string + CRp$6.setupTextStyle = function (context, ele) { + var useEleOpacity = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + // Font style + var labelStyle = ele.pstyle('font-style').strValue; + var labelSize = ele.pstyle('font-size').pfValue + 'px'; + var labelFamily = ele.pstyle('font-family').strValue; + var labelWeight = ele.pstyle('font-weight').strValue; + var opacity = useEleOpacity ? ele.effectiveOpacity() * ele.pstyle('text-opacity').value : 1; + var outlineOpacity = ele.pstyle('text-outline-opacity').value * opacity; + var color = ele.pstyle('color').value; + var outlineColor = ele.pstyle('text-outline-color').value; + context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily; + context.lineJoin = 'round'; // so text outlines aren't jagged + + this.colorFillStyle(context, color[0], color[1], color[2], opacity); + this.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], outlineOpacity); + }; + + // TODO ensure re-used + function roundRect(ctx, x, y, width, height) { + var radius = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 5; + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.lineTo(x + width - radius, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + ctx.lineTo(x + width, y + height - radius); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + ctx.lineTo(x + radius, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); + ctx.fill(); + } + CRp$6.getTextAngle = function (ele, prefix) { + var theta; + var _p = ele._private; + var rscratch = _p.rscratch; + var pdash = prefix ? prefix + '-' : ''; + var rotation = ele.pstyle(pdash + 'text-rotation'); + var textAngle = getPrefixedProperty(rscratch, 'labelAngle', prefix); + if (rotation.strValue === 'autorotate') { + theta = ele.isEdge() ? textAngle : 0; + } else if (rotation.strValue === 'none') { + theta = 0; + } else { + theta = rotation.pfValue; + } + return theta; + }; + CRp$6.drawText = function (context, ele, prefix) { + var applyRotation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var useEleOpacity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var _p = ele._private; + var rscratch = _p.rscratch; + var parentOpacity = useEleOpacity ? ele.effectiveOpacity() : 1; + if (useEleOpacity && (parentOpacity === 0 || ele.pstyle('text-opacity').value === 0)) { + return; + } + + // use 'main' as an alias for the main label (i.e. null prefix) + if (prefix === 'main') { + prefix = null; + } + var textX = getPrefixedProperty(rscratch, 'labelX', prefix); + var textY = getPrefixedProperty(rscratch, 'labelY', prefix); + var orgTextX, orgTextY; // used for rotation + var text = this.getLabelText(ele, prefix); + if (text != null && text !== '' && !isNaN(textX) && !isNaN(textY)) { + this.setupTextStyle(context, ele, useEleOpacity); + var pdash = prefix ? prefix + '-' : ''; + var textW = getPrefixedProperty(rscratch, 'labelWidth', prefix); + var textH = getPrefixedProperty(rscratch, 'labelHeight', prefix); + var marginX = ele.pstyle(pdash + 'text-margin-x').pfValue; + var marginY = ele.pstyle(pdash + 'text-margin-y').pfValue; + var isEdge = ele.isEdge(); + var halign = ele.pstyle('text-halign').value; + var valign = ele.pstyle('text-valign').value; + if (isEdge) { + halign = 'center'; + valign = 'center'; + } + textX += marginX; + textY += marginY; + var theta; + if (!applyRotation) { + theta = 0; + } else { + theta = this.getTextAngle(ele, prefix); + } + if (theta !== 0) { + orgTextX = textX; + orgTextY = textY; + context.translate(orgTextX, orgTextY); + context.rotate(theta); + textX = 0; + textY = 0; + } + switch (valign) { + case 'top': + break; + case 'center': + textY += textH / 2; + break; + case 'bottom': + textY += textH; + break; + } + var backgroundOpacity = ele.pstyle('text-background-opacity').value; + var borderOpacity = ele.pstyle('text-border-opacity').value; + var textBorderWidth = ele.pstyle('text-border-width').pfValue; + var backgroundPadding = ele.pstyle('text-background-padding').pfValue; + if (backgroundOpacity > 0 || textBorderWidth > 0 && borderOpacity > 0) { + var bgX = textX - backgroundPadding; + switch (halign) { + case 'left': + bgX -= textW; + break; + case 'center': + bgX -= textW / 2; + break; + } + var bgY = textY - textH - backgroundPadding; + var bgW = textW + 2 * backgroundPadding; + var bgH = textH + 2 * backgroundPadding; + if (backgroundOpacity > 0) { + var textFill = context.fillStyle; + var textBackgroundColor = ele.pstyle('text-background-color').value; + context.fillStyle = 'rgba(' + textBackgroundColor[0] + ',' + textBackgroundColor[1] + ',' + textBackgroundColor[2] + ',' + backgroundOpacity * parentOpacity + ')'; + var styleShape = ele.pstyle('text-background-shape').strValue; + if (styleShape.indexOf('round') === 0) { + roundRect(context, bgX, bgY, bgW, bgH, 2); + } else { + context.fillRect(bgX, bgY, bgW, bgH); + } + context.fillStyle = textFill; + } + if (textBorderWidth > 0 && borderOpacity > 0) { + var textStroke = context.strokeStyle; + var textLineWidth = context.lineWidth; + var textBorderColor = ele.pstyle('text-border-color').value; + var textBorderStyle = ele.pstyle('text-border-style').value; + context.strokeStyle = 'rgba(' + textBorderColor[0] + ',' + textBorderColor[1] + ',' + textBorderColor[2] + ',' + borderOpacity * parentOpacity + ')'; + context.lineWidth = textBorderWidth; + if (context.setLineDash) { + // for very outofdate browsers + switch (textBorderStyle) { + case 'dotted': + context.setLineDash([1, 1]); + break; + case 'dashed': + context.setLineDash([4, 2]); + break; + case 'double': + context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders + context.setLineDash([]); + break; + case 'solid': + context.setLineDash([]); + break; + } + } + context.strokeRect(bgX, bgY, bgW, bgH); + if (textBorderStyle === 'double') { + var whiteWidth = textBorderWidth / 2; + context.strokeRect(bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2); + } + if (context.setLineDash) { + // for very outofdate browsers + context.setLineDash([]); + } + context.lineWidth = textLineWidth; + context.strokeStyle = textStroke; + } + } + var lineWidth = 2 * ele.pstyle('text-outline-width').pfValue; // *2 b/c the stroke is drawn centred on the middle + + if (lineWidth > 0) { + context.lineWidth = lineWidth; + } + if (ele.pstyle('text-wrap').value === 'wrap') { + var lines = getPrefixedProperty(rscratch, 'labelWrapCachedLines', prefix); + var lineHeight = getPrefixedProperty(rscratch, 'labelLineHeight', prefix); + var halfTextW = textW / 2; + var justification = this.getLabelJustification(ele); + if (justification === 'auto') ; else if (halign === 'left') { + // auto justification : right + if (justification === 'left') { + textX += -textW; + } else if (justification === 'center') { + textX += -halfTextW; + } // else same as auto + } else if (halign === 'center') { + // auto justfication : center + if (justification === 'left') { + textX += -halfTextW; + } else if (justification === 'right') { + textX += halfTextW; + } // else same as auto + } else if (halign === 'right') { + // auto justification : left + if (justification === 'center') { + textX += halfTextW; + } else if (justification === 'right') { + textX += textW; + } // else same as auto + } + + switch (valign) { + case 'top': + textY -= (lines.length - 1) * lineHeight; + break; + case 'center': + case 'bottom': + textY -= (lines.length - 1) * lineHeight; + break; + } + for (var l = 0; l < lines.length; l++) { + if (lineWidth > 0) { + context.strokeText(lines[l], textX, textY); + } + context.fillText(lines[l], textX, textY); + textY += lineHeight; + } + } else { + if (lineWidth > 0) { + context.strokeText(text, textX, textY); + } + context.fillText(text, textX, textY); + } + if (theta !== 0) { + context.rotate(-theta); + context.translate(-orgTextX, -orgTextY); + } + } + }; + + /* global Path2D */ + var CRp$5 = {}; + CRp$5.drawNode = function (context, node, shiftToOriginWithBb) { + var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; + var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true; + var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true; + var r = this; + var nodeWidth, nodeHeight; + var _p = node._private; + var rs = _p.rscratch; + var pos = node.position(); + if (!number$1(pos.x) || !number$1(pos.y)) { + return; // can't draw node with undefined position + } + + if (shouldDrawOpacity && !node.visible()) { + return; + } + var eleOpacity = shouldDrawOpacity ? node.effectiveOpacity() : 1; + var usePaths = r.usePaths(); + var path; + var pathCacheHit = false; + var padding = node.padding(); + nodeWidth = node.width() + 2 * padding; + nodeHeight = node.height() + 2 * padding; + + // + // setup shift + + var bb; + if (shiftToOriginWithBb) { + bb = shiftToOriginWithBb; + context.translate(-bb.x1, -bb.y1); + } + + // + // load bg image + + var bgImgProp = node.pstyle('background-image'); + var urls = bgImgProp.value; + var urlDefined = new Array(urls.length); + var image = new Array(urls.length); + var numImages = 0; + for (var i = 0; i < urls.length; i++) { + var url = urls[i]; + var defd = urlDefined[i] = url != null && url !== 'none'; + if (defd) { + var bgImgCrossOrigin = node.cy().style().getIndexedStyle(node, 'background-image-crossorigin', 'value', i); + numImages++; + + // get image, and if not loaded then ask to redraw when later loaded + image[i] = r.getCachedImage(url, bgImgCrossOrigin, function () { + _p.backgroundTimestamp = Date.now(); + node.emitAndNotify('background'); + }); + } + } + + // + // setup styles + + var darkness = node.pstyle('background-blacken').value; + var borderWidth = node.pstyle('border-width').pfValue; + var bgOpacity = node.pstyle('background-opacity').value * eleOpacity; + var borderColor = node.pstyle('border-color').value; + var borderStyle = node.pstyle('border-style').value; + var borderOpacity = node.pstyle('border-opacity').value * eleOpacity; + context.lineJoin = 'miter'; // so borders are square with the node shape + + var setupShapeColor = function setupShapeColor() { + var bgOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : bgOpacity; + r.eleFillStyle(context, node, bgOpy); + }; + var setupBorderColor = function setupBorderColor() { + var bdrOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : borderOpacity; + r.colorStrokeStyle(context, borderColor[0], borderColor[1], borderColor[2], bdrOpy); + }; + + // + // setup shape + + var styleShape = node.pstyle('shape').strValue; + var shapePts = node.pstyle('shape-polygon-points').pfValue; + if (usePaths) { + context.translate(pos.x, pos.y); + var pathCache = r.nodePathCache = r.nodePathCache || []; + var key = hashStrings(styleShape === 'polygon' ? styleShape + ',' + shapePts.join(',') : styleShape, '' + nodeHeight, '' + nodeWidth); + var cachedPath = pathCache[key]; + if (cachedPath != null) { + path = cachedPath; + pathCacheHit = true; + rs.pathCache = path; + } else { + path = new Path2D(); + pathCache[key] = rs.pathCache = path; + } + } + var drawShape = function drawShape() { + if (!pathCacheHit) { + var npos = pos; + if (usePaths) { + npos = { + x: 0, + y: 0 + }; + } + r.nodeShapes[r.getNodeShape(node)].draw(path || context, npos.x, npos.y, nodeWidth, nodeHeight); + } + if (usePaths) { + context.fill(path); + } else { + context.fill(); + } + }; + var drawImages = function drawImages() { + var nodeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity; + var inside = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var prevBging = _p.backgrounding; + var totalCompleted = 0; + for (var _i = 0; _i < image.length; _i++) { + var bgContainment = node.cy().style().getIndexedStyle(node, 'background-image-containment', 'value', _i); + if (inside && bgContainment === 'over' || !inside && bgContainment === 'inside') { + totalCompleted++; + continue; + } + if (urlDefined[_i] && image[_i].complete && !image[_i].error) { + totalCompleted++; + r.drawInscribedImage(context, image[_i], node, _i, nodeOpacity); + } + } + _p.backgrounding = !(totalCompleted === numImages); + if (prevBging !== _p.backgrounding) { + // update style b/c :backgrounding state changed + node.updateStyle(false); + } + }; + var drawPie = function drawPie() { + var redrawShape = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var pieOpacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : eleOpacity; + if (r.hasPie(node)) { + r.drawPie(context, node, pieOpacity); + + // redraw/restore path if steps after pie need it + if (redrawShape) { + if (!usePaths) { + r.nodeShapes[r.getNodeShape(node)].draw(context, pos.x, pos.y, nodeWidth, nodeHeight); + } + } + } + }; + var darken = function darken() { + var darkenOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity; + var opacity = (darkness > 0 ? darkness : -darkness) * darkenOpacity; + var c = darkness > 0 ? 0 : 255; + if (darkness !== 0) { + r.colorFillStyle(context, c, c, c, opacity); + if (usePaths) { + context.fill(path); + } else { + context.fill(); + } + } + }; + var drawBorder = function drawBorder() { + if (borderWidth > 0) { + context.lineWidth = borderWidth; + context.lineCap = 'butt'; + if (context.setLineDash) { + // for very outofdate browsers + switch (borderStyle) { + case 'dotted': + context.setLineDash([1, 1]); + break; + case 'dashed': + context.setLineDash([4, 2]); + break; + case 'solid': + case 'double': + context.setLineDash([]); + break; + } + } + if (usePaths) { + context.stroke(path); + } else { + context.stroke(); + } + if (borderStyle === 'double') { + context.lineWidth = borderWidth / 3; + var gco = context.globalCompositeOperation; + context.globalCompositeOperation = 'destination-out'; + if (usePaths) { + context.stroke(path); + } else { + context.stroke(); + } + context.globalCompositeOperation = gco; + } + + // reset in case we changed the border style + if (context.setLineDash) { + // for very outofdate browsers + context.setLineDash([]); + } + } + }; + var drawOverlay = function drawOverlay() { + if (shouldDrawOverlay) { + r.drawNodeOverlay(context, node, pos, nodeWidth, nodeHeight); + } + }; + var drawUnderlay = function drawUnderlay() { + if (shouldDrawOverlay) { + r.drawNodeUnderlay(context, node, pos, nodeWidth, nodeHeight); + } + }; + var drawText = function drawText() { + r.drawElementText(context, node, null, drawLabel); + }; + var ghost = node.pstyle('ghost').value === 'yes'; + if (ghost) { + var gx = node.pstyle('ghost-offset-x').pfValue; + var gy = node.pstyle('ghost-offset-y').pfValue; + var ghostOpacity = node.pstyle('ghost-opacity').value; + var effGhostOpacity = ghostOpacity * eleOpacity; + context.translate(gx, gy); + setupShapeColor(ghostOpacity * bgOpacity); + drawShape(); + drawImages(effGhostOpacity, true); + setupBorderColor(ghostOpacity * borderOpacity); + drawBorder(); + drawPie(darkness !== 0 || borderWidth !== 0); + drawImages(effGhostOpacity, false); + darken(effGhostOpacity); + context.translate(-gx, -gy); + } + if (usePaths) { + context.translate(-pos.x, -pos.y); + } + drawUnderlay(); + if (usePaths) { + context.translate(pos.x, pos.y); + } + setupShapeColor(); + drawShape(); + drawImages(eleOpacity, true); + setupBorderColor(); + drawBorder(); + drawPie(darkness !== 0 || borderWidth !== 0); + drawImages(eleOpacity, false); + darken(); + if (usePaths) { + context.translate(-pos.x, -pos.y); + } + drawText(); + drawOverlay(); + + // + // clean up shift + + if (shiftToOriginWithBb) { + context.translate(bb.x1, bb.y1); + } + }; + var drawNodeOverlayUnderlay = function drawNodeOverlayUnderlay(overlayOrUnderlay) { + if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) { + throw new Error('Invalid state'); + } + return function (context, node, pos, nodeWidth, nodeHeight) { + var r = this; + if (!node.visible()) { + return; + } + var padding = node.pstyle("".concat(overlayOrUnderlay, "-padding")).pfValue; + var opacity = node.pstyle("".concat(overlayOrUnderlay, "-opacity")).value; + var color = node.pstyle("".concat(overlayOrUnderlay, "-color")).value; + var shape = node.pstyle("".concat(overlayOrUnderlay, "-shape")).value; + if (opacity > 0) { + pos = pos || node.position(); + if (nodeWidth == null || nodeHeight == null) { + var _padding = node.padding(); + nodeWidth = node.width() + 2 * _padding; + nodeHeight = node.height() + 2 * _padding; + } + r.colorFillStyle(context, color[0], color[1], color[2], opacity); + r.nodeShapes[shape].draw(context, pos.x, pos.y, nodeWidth + padding * 2, nodeHeight + padding * 2); + context.fill(); + } + }; + }; + CRp$5.drawNodeOverlay = drawNodeOverlayUnderlay('overlay'); + CRp$5.drawNodeUnderlay = drawNodeOverlayUnderlay('underlay'); + + // does the node have at least one pie piece? + CRp$5.hasPie = function (node) { + node = node[0]; // ensure ele ref + + return node._private.hasPie; + }; + CRp$5.drawPie = function (context, node, nodeOpacity, pos) { + node = node[0]; // ensure ele ref + pos = pos || node.position(); + var cyStyle = node.cy().style(); + var pieSize = node.pstyle('pie-size'); + var x = pos.x; + var y = pos.y; + var nodeW = node.width(); + var nodeH = node.height(); + var radius = Math.min(nodeW, nodeH) / 2; // must fit in node + var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1] + var usePaths = this.usePaths(); + if (usePaths) { + x = 0; + y = 0; + } + if (pieSize.units === '%') { + radius = radius * pieSize.pfValue; + } else if (pieSize.pfValue !== undefined) { + radius = pieSize.pfValue / 2; + } + for (var i = 1; i <= cyStyle.pieBackgroundN; i++) { + // 1..N + var size = node.pstyle('pie-' + i + '-background-size').value; + var color = node.pstyle('pie-' + i + '-background-color').value; + var opacity = node.pstyle('pie-' + i + '-background-opacity').value * nodeOpacity; + var percent = size / 100; // map integer range [0, 100] to [0, 1] + + // percent can't push beyond 1 + if (percent + lastPercent > 1) { + percent = 1 - lastPercent; + } + var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise + var angleDelta = 2 * Math.PI * percent; + var angleEnd = angleStart + angleDelta; + + // ignore if + // - zero size + // - we're already beyond the full circle + // - adding the current slice would go beyond the full circle + if (size === 0 || lastPercent >= 1 || lastPercent + percent > 1) { + continue; + } + context.beginPath(); + context.moveTo(x, y); + context.arc(x, y, radius, angleStart, angleEnd); + context.closePath(); + this.colorFillStyle(context, color[0], color[1], color[2], opacity); + context.fill(); + lastPercent += percent; + } + }; + + var CRp$4 = {}; + var motionBlurDelay = 100; + + // var isFirefox = typeof InstallTrigger !== 'undefined'; + + CRp$4.getPixelRatio = function () { + var context = this.data.contexts[0]; + if (this.forcedPixelRatio != null) { + return this.forcedPixelRatio; + } + var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; + return (window.devicePixelRatio || 1) / backingStore; // eslint-disable-line no-undef + }; + + CRp$4.paintCache = function (context) { + var caches = this.paintCaches = this.paintCaches || []; + var needToCreateCache = true; + var cache; + for (var i = 0; i < caches.length; i++) { + cache = caches[i]; + if (cache.context === context) { + needToCreateCache = false; + break; + } + } + if (needToCreateCache) { + cache = { + context: context + }; + caches.push(cache); + } + return cache; + }; + CRp$4.createGradientStyleFor = function (context, shapeStyleName, ele, fill, opacity) { + var gradientStyle; + var usePaths = this.usePaths(); + var colors = ele.pstyle(shapeStyleName + '-gradient-stop-colors').value, + positions = ele.pstyle(shapeStyleName + '-gradient-stop-positions').pfValue; + if (fill === 'radial-gradient') { + if (ele.isEdge()) { + var start = ele.sourceEndpoint(), + end = ele.targetEndpoint(), + mid = ele.midpoint(); + var d1 = dist(start, mid); + var d2 = dist(end, mid); + gradientStyle = context.createRadialGradient(mid.x, mid.y, 0, mid.x, mid.y, Math.max(d1, d2)); + } else { + var pos = usePaths ? { + x: 0, + y: 0 + } : ele.position(), + width = ele.paddedWidth(), + height = ele.paddedHeight(); + gradientStyle = context.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, Math.max(width, height)); + } + } else { + if (ele.isEdge()) { + var _start = ele.sourceEndpoint(), + _end = ele.targetEndpoint(); + gradientStyle = context.createLinearGradient(_start.x, _start.y, _end.x, _end.y); + } else { + var _pos = usePaths ? { + x: 0, + y: 0 + } : ele.position(), + _width = ele.paddedWidth(), + _height = ele.paddedHeight(), + halfWidth = _width / 2, + halfHeight = _height / 2; + var direction = ele.pstyle('background-gradient-direction').value; + switch (direction) { + case 'to-bottom': + gradientStyle = context.createLinearGradient(_pos.x, _pos.y - halfHeight, _pos.x, _pos.y + halfHeight); + break; + case 'to-top': + gradientStyle = context.createLinearGradient(_pos.x, _pos.y + halfHeight, _pos.x, _pos.y - halfHeight); + break; + case 'to-left': + gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y, _pos.x - halfWidth, _pos.y); + break; + case 'to-right': + gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y, _pos.x + halfWidth, _pos.y); + break; + case 'to-bottom-right': + case 'to-right-bottom': + gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y - halfHeight, _pos.x + halfWidth, _pos.y + halfHeight); + break; + case 'to-top-right': + case 'to-right-top': + gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y + halfHeight, _pos.x + halfWidth, _pos.y - halfHeight); + break; + case 'to-bottom-left': + case 'to-left-bottom': + gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y - halfHeight, _pos.x - halfWidth, _pos.y + halfHeight); + break; + case 'to-top-left': + case 'to-left-top': + gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y + halfHeight, _pos.x - halfWidth, _pos.y - halfHeight); + break; + } + } + } + if (!gradientStyle) return null; // invalid gradient style + + var hasPositions = positions.length === colors.length; + var length = colors.length; + for (var i = 0; i < length; i++) { + gradientStyle.addColorStop(hasPositions ? positions[i] : i / (length - 1), 'rgba(' + colors[i][0] + ',' + colors[i][1] + ',' + colors[i][2] + ',' + opacity + ')'); + } + return gradientStyle; + }; + CRp$4.gradientFillStyle = function (context, ele, fill, opacity) { + var gradientStyle = this.createGradientStyleFor(context, 'background', ele, fill, opacity); + if (!gradientStyle) return null; // error + context.fillStyle = gradientStyle; + }; + CRp$4.colorFillStyle = function (context, r, g, b, a) { + context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + // turn off for now, seems context does its own caching + + // var cache = this.paintCache(context); + + // var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + + // if( cache.fillStyle !== fillStyle ){ + // context.fillStyle = cache.fillStyle = fillStyle; + // } + }; + + CRp$4.eleFillStyle = function (context, ele, opacity) { + var backgroundFill = ele.pstyle('background-fill').value; + if (backgroundFill === 'linear-gradient' || backgroundFill === 'radial-gradient') { + this.gradientFillStyle(context, ele, backgroundFill, opacity); + } else { + var backgroundColor = ele.pstyle('background-color').value; + this.colorFillStyle(context, backgroundColor[0], backgroundColor[1], backgroundColor[2], opacity); + } + }; + CRp$4.gradientStrokeStyle = function (context, ele, fill, opacity) { + var gradientStyle = this.createGradientStyleFor(context, 'line', ele, fill, opacity); + if (!gradientStyle) return null; // error + context.strokeStyle = gradientStyle; + }; + CRp$4.colorStrokeStyle = function (context, r, g, b, a) { + context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + // turn off for now, seems context does its own caching + + // var cache = this.paintCache(context); + + // var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + + // if( cache.strokeStyle !== strokeStyle ){ + // context.strokeStyle = cache.strokeStyle = strokeStyle; + // } + }; + + CRp$4.eleStrokeStyle = function (context, ele, opacity) { + var lineFill = ele.pstyle('line-fill').value; + if (lineFill === 'linear-gradient' || lineFill === 'radial-gradient') { + this.gradientStrokeStyle(context, ele, lineFill, opacity); + } else { + var lineColor = ele.pstyle('line-color').value; + this.colorStrokeStyle(context, lineColor[0], lineColor[1], lineColor[2], opacity); + } + }; + + // Resize canvas + CRp$4.matchCanvasSize = function (container) { + var r = this; + var data = r.data; + var bb = r.findContainerClientCoords(); + var width = bb[2]; + var height = bb[3]; + var pixelRatio = r.getPixelRatio(); + var mbPxRatio = r.motionBlurPxRatio; + if (container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE] || container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]) { + pixelRatio = mbPxRatio; + } + var canvasWidth = width * pixelRatio; + var canvasHeight = height * pixelRatio; + var canvas; + if (canvasWidth === r.canvasWidth && canvasHeight === r.canvasHeight) { + return; // save cycles if same + } + + r.fontCaches = null; // resizing resets the style + + var canvasContainer = data.canvasContainer; + canvasContainer.style.width = width + 'px'; + canvasContainer.style.height = height + 'px'; + for (var i = 0; i < r.CANVAS_LAYERS; i++) { + canvas = data.canvases[i]; + canvas.width = canvasWidth; + canvas.height = canvasHeight; + canvas.style.width = width + 'px'; + canvas.style.height = height + 'px'; + } + for (var i = 0; i < r.BUFFER_COUNT; i++) { + canvas = data.bufferCanvases[i]; + canvas.width = canvasWidth; + canvas.height = canvasHeight; + canvas.style.width = width + 'px'; + canvas.style.height = height + 'px'; + } + r.textureMult = 1; + if (pixelRatio <= 1) { + canvas = data.bufferCanvases[r.TEXTURE_BUFFER]; + r.textureMult = 2; + canvas.width = canvasWidth * r.textureMult; + canvas.height = canvasHeight * r.textureMult; + } + r.canvasWidth = canvasWidth; + r.canvasHeight = canvasHeight; + }; + CRp$4.renderTo = function (cxt, zoom, pan, pxRatio) { + this.render({ + forcedContext: cxt, + forcedZoom: zoom, + forcedPan: pan, + drawAllLayers: true, + forcedPxRatio: pxRatio + }); + }; + CRp$4.render = function (options) { + options = options || staticEmptyObject(); + var forcedContext = options.forcedContext; + var drawAllLayers = options.drawAllLayers; + var drawOnlyNodeLayer = options.drawOnlyNodeLayer; + var forcedZoom = options.forcedZoom; + var forcedPan = options.forcedPan; + var r = this; + var pixelRatio = options.forcedPxRatio === undefined ? this.getPixelRatio() : options.forcedPxRatio; + var cy = r.cy; + var data = r.data; + var needDraw = data.canvasNeedsRedraw; + var textureDraw = r.textureOnViewport && !forcedContext && (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming); + var motionBlur = options.motionBlur !== undefined ? options.motionBlur : r.motionBlur; + var mbPxRatio = r.motionBlurPxRatio; + var hasCompoundNodes = cy.hasCompoundNodes(); + var inNodeDragGesture = r.hoverData.draggingEles; + var inBoxSelection = r.hoverData.selecting || r.touchData.selecting ? true : false; + motionBlur = motionBlur && !forcedContext && r.motionBlurEnabled && !inBoxSelection; + var motionBlurFadeEffect = motionBlur; + if (!forcedContext) { + if (r.prevPxRatio !== pixelRatio) { + r.invalidateContainerClientCoordsCache(); + r.matchCanvasSize(r.container); + r.redrawHint('eles', true); + r.redrawHint('drag', true); + } + r.prevPxRatio = pixelRatio; + } + if (!forcedContext && r.motionBlurTimeout) { + clearTimeout(r.motionBlurTimeout); + } + if (motionBlur) { + if (r.mbFrames == null) { + r.mbFrames = 0; + } + r.mbFrames++; + if (r.mbFrames < 3) { + // need several frames before even high quality motionblur + motionBlurFadeEffect = false; + } + + // go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing) + if (r.mbFrames > r.minMbLowQualFrames) { + //r.fullQualityMb = false; + r.motionBlurPxRatio = r.mbPxRBlurry; + } + } + if (r.clearingMotionBlur) { + r.motionBlurPxRatio = 1; + } + + // b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame + // because a rogue async texture frame would clear needDraw + if (r.textureDrawLastFrame && !textureDraw) { + needDraw[r.NODE] = true; + needDraw[r.SELECT_BOX] = true; + } + var style = cy.style(); + var zoom = cy.zoom(); + var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom; + var pan = cy.pan(); + var effectivePan = { + x: pan.x, + y: pan.y + }; + var vp = { + zoom: zoom, + pan: { + x: pan.x, + y: pan.y + } + }; + var prevVp = r.prevViewport; + var viewportIsDiff = prevVp === undefined || vp.zoom !== prevVp.zoom || vp.pan.x !== prevVp.pan.x || vp.pan.y !== prevVp.pan.y; + + // we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed) + if (!viewportIsDiff && !(inNodeDragGesture && !hasCompoundNodes)) { + r.motionBlurPxRatio = 1; + } + if (forcedPan) { + effectivePan = forcedPan; + } + + // apply pixel ratio + + effectiveZoom *= pixelRatio; + effectivePan.x *= pixelRatio; + effectivePan.y *= pixelRatio; + var eles = r.getCachedZSortedEles(); + function mbclear(context, x, y, w, h) { + var gco = context.globalCompositeOperation; + context.globalCompositeOperation = 'destination-out'; + r.colorFillStyle(context, 255, 255, 255, r.motionBlurTransparency); + context.fillRect(x, y, w, h); + context.globalCompositeOperation = gco; + } + function setContextTransform(context, clear) { + var ePan, eZoom, w, h; + if (!r.clearingMotionBlur && (context === data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] || context === data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG])) { + ePan = { + x: pan.x * mbPxRatio, + y: pan.y * mbPxRatio + }; + eZoom = zoom * mbPxRatio; + w = r.canvasWidth * mbPxRatio; + h = r.canvasHeight * mbPxRatio; + } else { + ePan = effectivePan; + eZoom = effectiveZoom; + w = r.canvasWidth; + h = r.canvasHeight; + } + context.setTransform(1, 0, 0, 1, 0, 0); + if (clear === 'motionBlur') { + mbclear(context, 0, 0, w, h); + } else if (!forcedContext && (clear === undefined || clear)) { + context.clearRect(0, 0, w, h); + } + if (!drawAllLayers) { + context.translate(ePan.x, ePan.y); + context.scale(eZoom, eZoom); + } + if (forcedPan) { + context.translate(forcedPan.x, forcedPan.y); + } + if (forcedZoom) { + context.scale(forcedZoom, forcedZoom); + } + } + if (!textureDraw) { + r.textureDrawLastFrame = false; + } + if (textureDraw) { + r.textureDrawLastFrame = true; + if (!r.textureCache) { + r.textureCache = {}; + r.textureCache.bb = cy.mutableElements().boundingBox(); + r.textureCache.texture = r.data.bufferCanvases[r.TEXTURE_BUFFER]; + var cxt = r.data.bufferContexts[r.TEXTURE_BUFFER]; + cxt.setTransform(1, 0, 0, 1, 0, 0); + cxt.clearRect(0, 0, r.canvasWidth * r.textureMult, r.canvasHeight * r.textureMult); + r.render({ + forcedContext: cxt, + drawOnlyNodeLayer: true, + forcedPxRatio: pixelRatio * r.textureMult + }); + var vp = r.textureCache.viewport = { + zoom: cy.zoom(), + pan: cy.pan(), + width: r.canvasWidth, + height: r.canvasHeight + }; + vp.mpan = { + x: (0 - vp.pan.x) / vp.zoom, + y: (0 - vp.pan.y) / vp.zoom + }; + } + needDraw[r.DRAG] = false; + needDraw[r.NODE] = false; + var context = data.contexts[r.NODE]; + var texture = r.textureCache.texture; + var vp = r.textureCache.viewport; + context.setTransform(1, 0, 0, 1, 0, 0); + if (motionBlur) { + mbclear(context, 0, 0, vp.width, vp.height); + } else { + context.clearRect(0, 0, vp.width, vp.height); + } + var outsideBgColor = style.core('outside-texture-bg-color').value; + var outsideBgOpacity = style.core('outside-texture-bg-opacity').value; + r.colorFillStyle(context, outsideBgColor[0], outsideBgColor[1], outsideBgColor[2], outsideBgOpacity); + context.fillRect(0, 0, vp.width, vp.height); + var zoom = cy.zoom(); + setContextTransform(context, false); + context.clearRect(vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio); + context.drawImage(texture, vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio); + } else if (r.textureOnViewport && !forcedContext) { + // clear the cache since we don't need it + r.textureCache = null; + } + var extent = cy.extent(); + var vpManip = r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles || r.cy.animated(); + var hideEdges = r.hideEdgesOnViewport && vpManip; + var needMbClear = []; + needMbClear[r.NODE] = !needDraw[r.NODE] && motionBlur && !r.clearedForMotionBlur[r.NODE] || r.clearingMotionBlur; + if (needMbClear[r.NODE]) { + r.clearedForMotionBlur[r.NODE] = true; + } + needMbClear[r.DRAG] = !needDraw[r.DRAG] && motionBlur && !r.clearedForMotionBlur[r.DRAG] || r.clearingMotionBlur; + if (needMbClear[r.DRAG]) { + r.clearedForMotionBlur[r.DRAG] = true; + } + if (needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer || needMbClear[r.NODE]) { + var useBuffer = motionBlur && !needMbClear[r.NODE] && mbPxRatio !== 1; + var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] : data.contexts[r.NODE]); + var clear = motionBlur && !useBuffer ? 'motionBlur' : undefined; + setContextTransform(context, clear); + if (hideEdges) { + r.drawCachedNodes(context, eles.nondrag, pixelRatio, extent); + } else { + r.drawLayeredElements(context, eles.nondrag, pixelRatio, extent); + } + if (r.debug) { + r.drawDebugPoints(context, eles.nondrag); + } + if (!drawAllLayers && !motionBlur) { + needDraw[r.NODE] = false; + } + } + if (!drawOnlyNodeLayer && (needDraw[r.DRAG] || drawAllLayers || needMbClear[r.DRAG])) { + var useBuffer = motionBlur && !needMbClear[r.DRAG] && mbPxRatio !== 1; + var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG] : data.contexts[r.DRAG]); + setContextTransform(context, motionBlur && !useBuffer ? 'motionBlur' : undefined); + if (hideEdges) { + r.drawCachedNodes(context, eles.drag, pixelRatio, extent); + } else { + r.drawCachedElements(context, eles.drag, pixelRatio, extent); + } + if (r.debug) { + r.drawDebugPoints(context, eles.drag); + } + if (!drawAllLayers && !motionBlur) { + needDraw[r.DRAG] = false; + } + } + if (r.showFps || !drawOnlyNodeLayer && needDraw[r.SELECT_BOX] && !drawAllLayers) { + var context = forcedContext || data.contexts[r.SELECT_BOX]; + setContextTransform(context); + if (r.selection[4] == 1 && (r.hoverData.selecting || r.touchData.selecting)) { + var zoom = r.cy.zoom(); + var borderWidth = style.core('selection-box-border-width').value / zoom; + context.lineWidth = borderWidth; + context.fillStyle = 'rgba(' + style.core('selection-box-color').value[0] + ',' + style.core('selection-box-color').value[1] + ',' + style.core('selection-box-color').value[2] + ',' + style.core('selection-box-opacity').value + ')'; + context.fillRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]); + if (borderWidth > 0) { + context.strokeStyle = 'rgba(' + style.core('selection-box-border-color').value[0] + ',' + style.core('selection-box-border-color').value[1] + ',' + style.core('selection-box-border-color').value[2] + ',' + style.core('selection-box-opacity').value + ')'; + context.strokeRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]); + } + } + if (data.bgActivePosistion && !r.hoverData.selecting) { + var zoom = r.cy.zoom(); + var pos = data.bgActivePosistion; + context.fillStyle = 'rgba(' + style.core('active-bg-color').value[0] + ',' + style.core('active-bg-color').value[1] + ',' + style.core('active-bg-color').value[2] + ',' + style.core('active-bg-opacity').value + ')'; + context.beginPath(); + context.arc(pos.x, pos.y, style.core('active-bg-size').pfValue / zoom, 0, 2 * Math.PI); + context.fill(); + } + var timeToRender = r.lastRedrawTime; + if (r.showFps && timeToRender) { + timeToRender = Math.round(timeToRender); + var fps = Math.round(1000 / timeToRender); + context.setTransform(1, 0, 0, 1, 0, 0); + context.fillStyle = 'rgba(255, 0, 0, 0.75)'; + context.strokeStyle = 'rgba(255, 0, 0, 0.75)'; + context.lineWidth = 1; + context.fillText('1 frame = ' + timeToRender + ' ms = ' + fps + ' fps', 0, 20); + var maxFps = 60; + context.strokeRect(0, 30, 250, 20); + context.fillRect(0, 30, 250 * Math.min(fps / maxFps, 1), 20); + } + if (!drawAllLayers) { + needDraw[r.SELECT_BOX] = false; + } + } + + // motionblur: blit rendered blurry frames + if (motionBlur && mbPxRatio !== 1) { + var cxtNode = data.contexts[r.NODE]; + var txtNode = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE]; + var cxtDrag = data.contexts[r.DRAG]; + var txtDrag = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]; + var drawMotionBlur = function drawMotionBlur(cxt, txt, needClear) { + cxt.setTransform(1, 0, 0, 1, 0, 0); + if (needClear || !motionBlurFadeEffect) { + cxt.clearRect(0, 0, r.canvasWidth, r.canvasHeight); + } else { + mbclear(cxt, 0, 0, r.canvasWidth, r.canvasHeight); + } + var pxr = mbPxRatio; + cxt.drawImage(txt, + // img + 0, 0, + // sx, sy + r.canvasWidth * pxr, r.canvasHeight * pxr, + // sw, sh + 0, 0, + // x, y + r.canvasWidth, r.canvasHeight // w, h + ); + }; + + if (needDraw[r.NODE] || needMbClear[r.NODE]) { + drawMotionBlur(cxtNode, txtNode, needMbClear[r.NODE]); + needDraw[r.NODE] = false; + } + if (needDraw[r.DRAG] || needMbClear[r.DRAG]) { + drawMotionBlur(cxtDrag, txtDrag, needMbClear[r.DRAG]); + needDraw[r.DRAG] = false; + } + } + r.prevViewport = vp; + if (r.clearingMotionBlur) { + r.clearingMotionBlur = false; + r.motionBlurCleared = true; + r.motionBlur = true; + } + if (motionBlur) { + r.motionBlurTimeout = setTimeout(function () { + r.motionBlurTimeout = null; + r.clearedForMotionBlur[r.NODE] = false; + r.clearedForMotionBlur[r.DRAG] = false; + r.motionBlur = false; + r.clearingMotionBlur = !textureDraw; + r.mbFrames = 0; + needDraw[r.NODE] = true; + needDraw[r.DRAG] = true; + r.redraw(); + }, motionBlurDelay); + } + if (!forcedContext) { + cy.emit('render'); + } + }; + + var CRp$3 = {}; + + // @O Polygon drawing + CRp$3.drawPolygonPath = function (context, x, y, width, height, points) { + var halfW = width / 2; + var halfH = height / 2; + if (context.beginPath) { + context.beginPath(); + } + context.moveTo(x + halfW * points[0], y + halfH * points[1]); + for (var i = 1; i < points.length / 2; i++) { + context.lineTo(x + halfW * points[i * 2], y + halfH * points[i * 2 + 1]); + } + context.closePath(); + }; + CRp$3.drawRoundPolygonPath = function (context, x, y, width, height, points) { + var halfW = width / 2; + var halfH = height / 2; + var cornerRadius = getRoundPolygonRadius(width, height); + if (context.beginPath) { + context.beginPath(); + } + for (var _i = 0; _i < points.length / 4; _i++) { + var sourceUv = void 0, + destUv = void 0; + if (_i === 0) { + sourceUv = points.length - 2; + } else { + sourceUv = _i * 4 - 2; + } + destUv = _i * 4 + 2; + var px = x + halfW * points[_i * 4]; + var py = y + halfH * points[_i * 4 + 1]; + var cosTheta = -points[sourceUv] * points[destUv] - points[sourceUv + 1] * points[destUv + 1]; + var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2); + var cp0x = px - offset * points[sourceUv]; + var cp0y = py - offset * points[sourceUv + 1]; + var cp1x = px + offset * points[destUv]; + var cp1y = py + offset * points[destUv + 1]; + if (_i === 0) { + context.moveTo(cp0x, cp0y); + } else { + context.lineTo(cp0x, cp0y); + } + context.arcTo(px, py, cp1x, cp1y, cornerRadius); + } + context.closePath(); + }; + + // Round rectangle drawing + CRp$3.drawRoundRectanglePath = function (context, x, y, width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var cornerRadius = getRoundRectangleRadius(width, height); + if (context.beginPath) { + context.beginPath(); + } + + // Start at top middle + context.moveTo(x, y - halfHeight); + // Arc from middle top to right side + context.arcTo(x + halfWidth, y - halfHeight, x + halfWidth, y, cornerRadius); + // Arc from right side to bottom + context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius); + // Arc from bottom to left side + context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius); + // Arc from left side to topBorder + context.arcTo(x - halfWidth, y - halfHeight, x, y - halfHeight, cornerRadius); + // Join line + context.lineTo(x, y - halfHeight); + context.closePath(); + }; + CRp$3.drawBottomRoundRectanglePath = function (context, x, y, width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var cornerRadius = getRoundRectangleRadius(width, height); + if (context.beginPath) { + context.beginPath(); + } + + // Start at top middle + context.moveTo(x, y - halfHeight); + context.lineTo(x + halfWidth, y - halfHeight); + context.lineTo(x + halfWidth, y); + context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius); + context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius); + context.lineTo(x - halfWidth, y - halfHeight); + context.lineTo(x, y - halfHeight); + context.closePath(); + }; + CRp$3.drawCutRectanglePath = function (context, x, y, width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var cornerLength = getCutRectangleCornerLength(); + if (context.beginPath) { + context.beginPath(); + } + context.moveTo(x - halfWidth + cornerLength, y - halfHeight); + context.lineTo(x + halfWidth - cornerLength, y - halfHeight); + context.lineTo(x + halfWidth, y - halfHeight + cornerLength); + context.lineTo(x + halfWidth, y + halfHeight - cornerLength); + context.lineTo(x + halfWidth - cornerLength, y + halfHeight); + context.lineTo(x - halfWidth + cornerLength, y + halfHeight); + context.lineTo(x - halfWidth, y + halfHeight - cornerLength); + context.lineTo(x - halfWidth, y - halfHeight + cornerLength); + context.closePath(); + }; + CRp$3.drawBarrelPath = function (context, x, y, width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var xBegin = x - halfWidth; + var xEnd = x + halfWidth; + var yBegin = y - halfHeight; + var yEnd = y + halfHeight; + var barrelCurveConstants = getBarrelCurveConstants(width, height); + var wOffset = barrelCurveConstants.widthOffset; + var hOffset = barrelCurveConstants.heightOffset; + var ctrlPtXOffset = barrelCurveConstants.ctrlPtOffsetPct * wOffset; + if (context.beginPath) { + context.beginPath(); + } + context.moveTo(xBegin, yBegin + hOffset); + context.lineTo(xBegin, yEnd - hOffset); + context.quadraticCurveTo(xBegin + ctrlPtXOffset, yEnd, xBegin + wOffset, yEnd); + context.lineTo(xEnd - wOffset, yEnd); + context.quadraticCurveTo(xEnd - ctrlPtXOffset, yEnd, xEnd, yEnd - hOffset); + context.lineTo(xEnd, yBegin + hOffset); + context.quadraticCurveTo(xEnd - ctrlPtXOffset, yBegin, xEnd - wOffset, yBegin); + context.lineTo(xBegin + wOffset, yBegin); + context.quadraticCurveTo(xBegin + ctrlPtXOffset, yBegin, xBegin, yBegin + hOffset); + context.closePath(); + }; + var sin0 = Math.sin(0); + var cos0 = Math.cos(0); + var sin = {}; + var cos = {}; + var ellipseStepSize = Math.PI / 40; + for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) { + sin[i] = Math.sin(i); + cos[i] = Math.cos(i); + } + CRp$3.drawEllipsePath = function (context, centerX, centerY, width, height) { + if (context.beginPath) { + context.beginPath(); + } + if (context.ellipse) { + context.ellipse(centerX, centerY, width / 2, height / 2, 0, 0, 2 * Math.PI); + } else { + var xPos, yPos; + var rw = width / 2; + var rh = height / 2; + for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) { + xPos = centerX - rw * sin[i] * sin0 + rw * cos[i] * cos0; + yPos = centerY + rh * cos[i] * sin0 + rh * sin[i] * cos0; + if (i === 0) { + context.moveTo(xPos, yPos); + } else { + context.lineTo(xPos, yPos); + } + } + } + context.closePath(); + }; + + /* global atob, ArrayBuffer, Uint8Array, Blob */ + var CRp$2 = {}; + CRp$2.createBuffer = function (w, h) { + var buffer = document.createElement('canvas'); // eslint-disable-line no-undef + buffer.width = w; + buffer.height = h; + return [buffer, buffer.getContext('2d')]; + }; + CRp$2.bufferCanvasImage = function (options) { + var cy = this.cy; + var eles = cy.mutableElements(); + var bb = eles.boundingBox(); + var ctrRect = this.findContainerClientCoords(); + var width = options.full ? Math.ceil(bb.w) : ctrRect[2]; + var height = options.full ? Math.ceil(bb.h) : ctrRect[3]; + var specdMaxDims = number$1(options.maxWidth) || number$1(options.maxHeight); + var pxRatio = this.getPixelRatio(); + var scale = 1; + if (options.scale !== undefined) { + width *= options.scale; + height *= options.scale; + scale = options.scale; + } else if (specdMaxDims) { + var maxScaleW = Infinity; + var maxScaleH = Infinity; + if (number$1(options.maxWidth)) { + maxScaleW = scale * options.maxWidth / width; + } + if (number$1(options.maxHeight)) { + maxScaleH = scale * options.maxHeight / height; + } + scale = Math.min(maxScaleW, maxScaleH); + width *= scale; + height *= scale; + } + if (!specdMaxDims) { + width *= pxRatio; + height *= pxRatio; + scale *= pxRatio; + } + var buffCanvas = document.createElement('canvas'); // eslint-disable-line no-undef + + buffCanvas.width = width; + buffCanvas.height = height; + buffCanvas.style.width = width + 'px'; + buffCanvas.style.height = height + 'px'; + var buffCxt = buffCanvas.getContext('2d'); + + // Rasterize the layers, but only if container has nonzero size + if (width > 0 && height > 0) { + buffCxt.clearRect(0, 0, width, height); + buffCxt.globalCompositeOperation = 'source-over'; + var zsortedEles = this.getCachedZSortedEles(); + if (options.full) { + // draw the full bounds of the graph + buffCxt.translate(-bb.x1 * scale, -bb.y1 * scale); + buffCxt.scale(scale, scale); + this.drawElements(buffCxt, zsortedEles); + buffCxt.scale(1 / scale, 1 / scale); + buffCxt.translate(bb.x1 * scale, bb.y1 * scale); + } else { + // draw the current view + var pan = cy.pan(); + var translation = { + x: pan.x * scale, + y: pan.y * scale + }; + scale *= cy.zoom(); + buffCxt.translate(translation.x, translation.y); + buffCxt.scale(scale, scale); + this.drawElements(buffCxt, zsortedEles); + buffCxt.scale(1 / scale, 1 / scale); + buffCxt.translate(-translation.x, -translation.y); + } + + // need to fill bg at end like this in order to fill cleared transparent pixels in jpgs + if (options.bg) { + buffCxt.globalCompositeOperation = 'destination-over'; + buffCxt.fillStyle = options.bg; + buffCxt.rect(0, 0, width, height); + buffCxt.fill(); + } + } + return buffCanvas; + }; + function b64ToBlob(b64, mimeType) { + var bytes = atob(b64); + var buff = new ArrayBuffer(bytes.length); + var buffUint8 = new Uint8Array(buff); + for (var i = 0; i < bytes.length; i++) { + buffUint8[i] = bytes.charCodeAt(i); + } + return new Blob([buff], { + type: mimeType + }); + } + function b64UriToB64(b64uri) { + var i = b64uri.indexOf(','); + return b64uri.substr(i + 1); + } + function output(options, canvas, mimeType) { + var getB64Uri = function getB64Uri() { + return canvas.toDataURL(mimeType, options.quality); + }; + switch (options.output) { + case 'blob-promise': + return new Promise$1(function (resolve, reject) { + try { + canvas.toBlob(function (blob) { + if (blob != null) { + resolve(blob); + } else { + reject(new Error('`canvas.toBlob()` sent a null value in its callback')); + } + }, mimeType, options.quality); + } catch (err) { + reject(err); + } + }); + case 'blob': + return b64ToBlob(b64UriToB64(getB64Uri()), mimeType); + case 'base64': + return b64UriToB64(getB64Uri()); + case 'base64uri': + default: + return getB64Uri(); + } + } + CRp$2.png = function (options) { + return output(options, this.bufferCanvasImage(options), 'image/png'); + }; + CRp$2.jpg = function (options) { + return output(options, this.bufferCanvasImage(options), 'image/jpeg'); + }; + + var CRp$1 = {}; + CRp$1.nodeShapeImpl = function (name, context, centerX, centerY, width, height, points) { + switch (name) { + case 'ellipse': + return this.drawEllipsePath(context, centerX, centerY, width, height); + case 'polygon': + return this.drawPolygonPath(context, centerX, centerY, width, height, points); + case 'round-polygon': + return this.drawRoundPolygonPath(context, centerX, centerY, width, height, points); + case 'roundrectangle': + case 'round-rectangle': + return this.drawRoundRectanglePath(context, centerX, centerY, width, height); + case 'cutrectangle': + case 'cut-rectangle': + return this.drawCutRectanglePath(context, centerX, centerY, width, height); + case 'bottomroundrectangle': + case 'bottom-round-rectangle': + return this.drawBottomRoundRectanglePath(context, centerX, centerY, width, height); + case 'barrel': + return this.drawBarrelPath(context, centerX, centerY, width, height); + } + }; + + var CR = CanvasRenderer; + var CRp = CanvasRenderer.prototype; + CRp.CANVAS_LAYERS = 3; + // + CRp.SELECT_BOX = 0; + CRp.DRAG = 1; + CRp.NODE = 2; + CRp.BUFFER_COUNT = 3; + // + CRp.TEXTURE_BUFFER = 0; + CRp.MOTIONBLUR_BUFFER_NODE = 1; + CRp.MOTIONBLUR_BUFFER_DRAG = 2; + function CanvasRenderer(options) { + var r = this; + r.data = { + canvases: new Array(CRp.CANVAS_LAYERS), + contexts: new Array(CRp.CANVAS_LAYERS), + canvasNeedsRedraw: new Array(CRp.CANVAS_LAYERS), + bufferCanvases: new Array(CRp.BUFFER_COUNT), + bufferContexts: new Array(CRp.CANVAS_LAYERS) + }; + var tapHlOffAttr = '-webkit-tap-highlight-color'; + var tapHlOffStyle = 'rgba(0,0,0,0)'; + r.data.canvasContainer = document.createElement('div'); // eslint-disable-line no-undef + var containerStyle = r.data.canvasContainer.style; + r.data.canvasContainer.style[tapHlOffAttr] = tapHlOffStyle; + containerStyle.position = 'relative'; + containerStyle.zIndex = '0'; + containerStyle.overflow = 'hidden'; + var container = options.cy.container(); + container.appendChild(r.data.canvasContainer); + container.style[tapHlOffAttr] = tapHlOffStyle; + var styleMap = { + '-webkit-user-select': 'none', + '-moz-user-select': '-moz-none', + 'user-select': 'none', + '-webkit-tap-highlight-color': 'rgba(0,0,0,0)', + 'outline-style': 'none' + }; + if (ms()) { + styleMap['-ms-touch-action'] = 'none'; + styleMap['touch-action'] = 'none'; + } + for (var i = 0; i < CRp.CANVAS_LAYERS; i++) { + var canvas = r.data.canvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef + r.data.contexts[i] = canvas.getContext('2d'); + Object.keys(styleMap).forEach(function (k) { + canvas.style[k] = styleMap[k]; + }); + canvas.style.position = 'absolute'; + canvas.setAttribute('data-id', 'layer' + i); + canvas.style.zIndex = String(CRp.CANVAS_LAYERS - i); + r.data.canvasContainer.appendChild(canvas); + r.data.canvasNeedsRedraw[i] = false; + } + r.data.topCanvas = r.data.canvases[0]; + r.data.canvases[CRp.NODE].setAttribute('data-id', 'layer' + CRp.NODE + '-node'); + r.data.canvases[CRp.SELECT_BOX].setAttribute('data-id', 'layer' + CRp.SELECT_BOX + '-selectbox'); + r.data.canvases[CRp.DRAG].setAttribute('data-id', 'layer' + CRp.DRAG + '-drag'); + for (var i = 0; i < CRp.BUFFER_COUNT; i++) { + r.data.bufferCanvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef + r.data.bufferContexts[i] = r.data.bufferCanvases[i].getContext('2d'); + r.data.bufferCanvases[i].style.position = 'absolute'; + r.data.bufferCanvases[i].setAttribute('data-id', 'buffer' + i); + r.data.bufferCanvases[i].style.zIndex = String(-i - 1); + r.data.bufferCanvases[i].style.visibility = 'hidden'; + //r.data.canvasContainer.appendChild(r.data.bufferCanvases[i]); + } + + r.pathsEnabled = true; + var emptyBb = makeBoundingBox(); + var getBoxCenter = function getBoxCenter(bb) { + return { + x: (bb.x1 + bb.x2) / 2, + y: (bb.y1 + bb.y2) / 2 + }; + }; + var getCenterOffset = function getCenterOffset(bb) { + return { + x: -bb.w / 2, + y: -bb.h / 2 + }; + }; + var backgroundTimestampHasChanged = function backgroundTimestampHasChanged(ele) { + var _p = ele[0]._private; + var same = _p.oldBackgroundTimestamp === _p.backgroundTimestamp; + return !same; + }; + var getStyleKey = function getStyleKey(ele) { + return ele[0]._private.nodeKey; + }; + var getLabelKey = function getLabelKey(ele) { + return ele[0]._private.labelStyleKey; + }; + var getSourceLabelKey = function getSourceLabelKey(ele) { + return ele[0]._private.sourceLabelStyleKey; + }; + var getTargetLabelKey = function getTargetLabelKey(ele) { + return ele[0]._private.targetLabelStyleKey; + }; + var drawElement = function drawElement(context, ele, bb, scaledLabelShown, useEleOpacity) { + return r.drawElement(context, ele, bb, false, false, useEleOpacity); + }; + var drawLabel = function drawLabel(context, ele, bb, scaledLabelShown, useEleOpacity) { + return r.drawElementText(context, ele, bb, scaledLabelShown, 'main', useEleOpacity); + }; + var drawSourceLabel = function drawSourceLabel(context, ele, bb, scaledLabelShown, useEleOpacity) { + return r.drawElementText(context, ele, bb, scaledLabelShown, 'source', useEleOpacity); + }; + var drawTargetLabel = function drawTargetLabel(context, ele, bb, scaledLabelShown, useEleOpacity) { + return r.drawElementText(context, ele, bb, scaledLabelShown, 'target', useEleOpacity); + }; + var getElementBox = function getElementBox(ele) { + ele.boundingBox(); + return ele[0]._private.bodyBounds; + }; + var getLabelBox = function getLabelBox(ele) { + ele.boundingBox(); + return ele[0]._private.labelBounds.main || emptyBb; + }; + var getSourceLabelBox = function getSourceLabelBox(ele) { + ele.boundingBox(); + return ele[0]._private.labelBounds.source || emptyBb; + }; + var getTargetLabelBox = function getTargetLabelBox(ele) { + ele.boundingBox(); + return ele[0]._private.labelBounds.target || emptyBb; + }; + var isLabelVisibleAtScale = function isLabelVisibleAtScale(ele, scaledLabelShown) { + return scaledLabelShown; + }; + var getElementRotationPoint = function getElementRotationPoint(ele) { + return getBoxCenter(getElementBox(ele)); + }; + var addTextMargin = function addTextMargin(prefix, pt, ele) { + var pre = prefix ? prefix + '-' : ''; + return { + x: pt.x + ele.pstyle(pre + 'text-margin-x').pfValue, + y: pt.y + ele.pstyle(pre + 'text-margin-y').pfValue + }; + }; + var getRsPt = function getRsPt(ele, x, y) { + var rs = ele[0]._private.rscratch; + return { + x: rs[x], + y: rs[y] + }; + }; + var getLabelRotationPoint = function getLabelRotationPoint(ele) { + return addTextMargin('', getRsPt(ele, 'labelX', 'labelY'), ele); + }; + var getSourceLabelRotationPoint = function getSourceLabelRotationPoint(ele) { + return addTextMargin('source', getRsPt(ele, 'sourceLabelX', 'sourceLabelY'), ele); + }; + var getTargetLabelRotationPoint = function getTargetLabelRotationPoint(ele) { + return addTextMargin('target', getRsPt(ele, 'targetLabelX', 'targetLabelY'), ele); + }; + var getElementRotationOffset = function getElementRotationOffset(ele) { + return getCenterOffset(getElementBox(ele)); + }; + var getSourceLabelRotationOffset = function getSourceLabelRotationOffset(ele) { + return getCenterOffset(getSourceLabelBox(ele)); + }; + var getTargetLabelRotationOffset = function getTargetLabelRotationOffset(ele) { + return getCenterOffset(getTargetLabelBox(ele)); + }; + var getLabelRotationOffset = function getLabelRotationOffset(ele) { + var bb = getLabelBox(ele); + var p = getCenterOffset(getLabelBox(ele)); + if (ele.isNode()) { + switch (ele.pstyle('text-halign').value) { + case 'left': + p.x = -bb.w; + break; + case 'right': + p.x = 0; + break; + } + switch (ele.pstyle('text-valign').value) { + case 'top': + p.y = -bb.h; + break; + case 'bottom': + p.y = 0; + break; + } + } + return p; + }; + var eleTxrCache = r.data.eleTxrCache = new ElementTextureCache(r, { + getKey: getStyleKey, + doesEleInvalidateKey: backgroundTimestampHasChanged, + drawElement: drawElement, + getBoundingBox: getElementBox, + getRotationPoint: getElementRotationPoint, + getRotationOffset: getElementRotationOffset, + allowEdgeTxrCaching: false, + allowParentTxrCaching: false + }); + var lblTxrCache = r.data.lblTxrCache = new ElementTextureCache(r, { + getKey: getLabelKey, + drawElement: drawLabel, + getBoundingBox: getLabelBox, + getRotationPoint: getLabelRotationPoint, + getRotationOffset: getLabelRotationOffset, + isVisible: isLabelVisibleAtScale + }); + var slbTxrCache = r.data.slbTxrCache = new ElementTextureCache(r, { + getKey: getSourceLabelKey, + drawElement: drawSourceLabel, + getBoundingBox: getSourceLabelBox, + getRotationPoint: getSourceLabelRotationPoint, + getRotationOffset: getSourceLabelRotationOffset, + isVisible: isLabelVisibleAtScale + }); + var tlbTxrCache = r.data.tlbTxrCache = new ElementTextureCache(r, { + getKey: getTargetLabelKey, + drawElement: drawTargetLabel, + getBoundingBox: getTargetLabelBox, + getRotationPoint: getTargetLabelRotationPoint, + getRotationOffset: getTargetLabelRotationOffset, + isVisible: isLabelVisibleAtScale + }); + var lyrTxrCache = r.data.lyrTxrCache = new LayeredTextureCache(r); + r.onUpdateEleCalcs(function invalidateTextureCaches(willDraw, eles) { + // each cache should check for sub-key diff to see that the update affects that cache particularly + eleTxrCache.invalidateElements(eles); + lblTxrCache.invalidateElements(eles); + slbTxrCache.invalidateElements(eles); + tlbTxrCache.invalidateElements(eles); + + // any change invalidates the layers + lyrTxrCache.invalidateElements(eles); + + // update the old bg timestamp so diffs can be done in the ele txr caches + for (var _i = 0; _i < eles.length; _i++) { + var _p = eles[_i]._private; + _p.oldBackgroundTimestamp = _p.backgroundTimestamp; + } + }); + var refineInLayers = function refineInLayers(reqs) { + for (var i = 0; i < reqs.length; i++) { + lyrTxrCache.enqueueElementRefinement(reqs[i].ele); + } + }; + eleTxrCache.onDequeue(refineInLayers); + lblTxrCache.onDequeue(refineInLayers); + slbTxrCache.onDequeue(refineInLayers); + tlbTxrCache.onDequeue(refineInLayers); + } + CRp.redrawHint = function (group, bool) { + var r = this; + switch (group) { + case 'eles': + r.data.canvasNeedsRedraw[CRp.NODE] = bool; + break; + case 'drag': + r.data.canvasNeedsRedraw[CRp.DRAG] = bool; + break; + case 'select': + r.data.canvasNeedsRedraw[CRp.SELECT_BOX] = bool; + break; + } + }; + + // whether to use Path2D caching for drawing + var pathsImpld = typeof Path2D !== 'undefined'; + CRp.path2dEnabled = function (on) { + if (on === undefined) { + return this.pathsEnabled; + } + this.pathsEnabled = on ? true : false; + }; + CRp.usePaths = function () { + return pathsImpld && this.pathsEnabled; + }; + CRp.setImgSmoothing = function (context, bool) { + if (context.imageSmoothingEnabled != null) { + context.imageSmoothingEnabled = bool; + } else { + context.webkitImageSmoothingEnabled = bool; + context.mozImageSmoothingEnabled = bool; + context.msImageSmoothingEnabled = bool; + } + }; + CRp.getImgSmoothing = function (context) { + if (context.imageSmoothingEnabled != null) { + return context.imageSmoothingEnabled; + } else { + return context.webkitImageSmoothingEnabled || context.mozImageSmoothingEnabled || context.msImageSmoothingEnabled; + } + }; + CRp.makeOffscreenCanvas = function (width, height) { + var canvas; + if ((typeof OffscreenCanvas === "undefined" ? "undefined" : _typeof(OffscreenCanvas)) !== ("undefined" )) { + canvas = new OffscreenCanvas(width, height); + } else { + canvas = document.createElement('canvas'); // eslint-disable-line no-undef + canvas.width = width; + canvas.height = height; + } + return canvas; + }; + [CRp$a, CRp$9, CRp$8, CRp$7, CRp$6, CRp$5, CRp$4, CRp$3, CRp$2, CRp$1].forEach(function (props) { + extend(CRp, props); + }); + + var renderer = [{ + name: 'null', + impl: NullRenderer + }, { + name: 'base', + impl: BR + }, { + name: 'canvas', + impl: CR + }]; + + var incExts = [{ + type: 'layout', + extensions: layout + }, { + type: 'renderer', + extensions: renderer + }]; + + // registered extensions to cytoscape, indexed by name + var extensions = {}; + + // registered modules for extensions, indexed by name + var modules = {}; + function setExtension(type, name, registrant) { + var ext = registrant; + var overrideErr = function overrideErr(field) { + warn('Can not register `' + name + '` for `' + type + '` since `' + field + '` already exists in the prototype and can not be overridden'); + }; + if (type === 'core') { + if (Core.prototype[name]) { + return overrideErr(name); + } else { + Core.prototype[name] = registrant; + } + } else if (type === 'collection') { + if (Collection.prototype[name]) { + return overrideErr(name); + } else { + Collection.prototype[name] = registrant; + } + } else if (type === 'layout') { + // fill in missing layout functions in the prototype + + var Layout = function Layout(options) { + this.options = options; + registrant.call(this, options); + + // make sure layout has _private for use w/ std apis like .on() + if (!plainObject(this._private)) { + this._private = {}; + } + this._private.cy = options.cy; + this._private.listeners = []; + this.createEmitter(); + }; + var layoutProto = Layout.prototype = Object.create(registrant.prototype); + var optLayoutFns = []; + for (var i = 0; i < optLayoutFns.length; i++) { + var fnName = optLayoutFns[i]; + layoutProto[fnName] = layoutProto[fnName] || function () { + return this; + }; + } + + // either .start() or .run() is defined, so autogen the other + if (layoutProto.start && !layoutProto.run) { + layoutProto.run = function () { + this.start(); + return this; + }; + } else if (!layoutProto.start && layoutProto.run) { + layoutProto.start = function () { + this.run(); + return this; + }; + } + var regStop = registrant.prototype.stop; + layoutProto.stop = function () { + var opts = this.options; + if (opts && opts.animate) { + var anis = this.animations; + if (anis) { + for (var _i = 0; _i < anis.length; _i++) { + anis[_i].stop(); + } + } + } + if (regStop) { + regStop.call(this); + } else { + this.emit('layoutstop'); + } + return this; + }; + if (!layoutProto.destroy) { + layoutProto.destroy = function () { + return this; + }; + } + layoutProto.cy = function () { + return this._private.cy; + }; + var getCy = function getCy(layout) { + return layout._private.cy; + }; + var emitterOpts = { + addEventFields: function addEventFields(layout, evt) { + evt.layout = layout; + evt.cy = getCy(layout); + evt.target = layout; + }, + bubble: function bubble() { + return true; + }, + parent: function parent(layout) { + return getCy(layout); + } + }; + extend(layoutProto, { + createEmitter: function createEmitter() { + this._private.emitter = new Emitter(emitterOpts, this); + return this; + }, + emitter: function emitter() { + return this._private.emitter; + }, + on: function on(evt, cb) { + this.emitter().on(evt, cb); + return this; + }, + one: function one(evt, cb) { + this.emitter().one(evt, cb); + return this; + }, + once: function once(evt, cb) { + this.emitter().one(evt, cb); + return this; + }, + removeListener: function removeListener(evt, cb) { + this.emitter().removeListener(evt, cb); + return this; + }, + removeAllListeners: function removeAllListeners() { + this.emitter().removeAllListeners(); + return this; + }, + emit: function emit(evt, params) { + this.emitter().emit(evt, params); + return this; + } + }); + define.eventAliasesOn(layoutProto); + ext = Layout; // replace with our wrapped layout + } else if (type === 'renderer' && name !== 'null' && name !== 'base') { + // user registered renderers inherit from base + + var BaseRenderer = getExtension('renderer', 'base'); + var bProto = BaseRenderer.prototype; + var RegistrantRenderer = registrant; + var rProto = registrant.prototype; + var Renderer = function Renderer() { + BaseRenderer.apply(this, arguments); + RegistrantRenderer.apply(this, arguments); + }; + var proto = Renderer.prototype; + for (var pName in bProto) { + var pVal = bProto[pName]; + var existsInR = rProto[pName] != null; + if (existsInR) { + return overrideErr(pName); + } + proto[pName] = pVal; // take impl from base + } + + for (var _pName in rProto) { + proto[_pName] = rProto[_pName]; // take impl from registrant + } + + bProto.clientFunctions.forEach(function (name) { + proto[name] = proto[name] || function () { + error('Renderer does not implement `renderer.' + name + '()` on its prototype'); + }; + }); + ext = Renderer; + } else if (type === '__proto__' || type === 'constructor' || type === 'prototype') { + // to avoid potential prototype pollution + return error(type + ' is an illegal type to be registered, possibly lead to prototype pollutions'); + } + return setMap({ + map: extensions, + keys: [type, name], + value: ext + }); + } + function getExtension(type, name) { + return getMap({ + map: extensions, + keys: [type, name] + }); + } + function setModule(type, name, moduleType, moduleName, registrant) { + return setMap({ + map: modules, + keys: [type, name, moduleType, moduleName], + value: registrant + }); + } + function getModule(type, name, moduleType, moduleName) { + return getMap({ + map: modules, + keys: [type, name, moduleType, moduleName] + }); + } + var extension = function extension() { + // e.g. extension('renderer', 'svg') + if (arguments.length === 2) { + return getExtension.apply(null, arguments); + } + + // e.g. extension('renderer', 'svg', { ... }) + else if (arguments.length === 3) { + return setExtension.apply(null, arguments); + } + + // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse') + else if (arguments.length === 4) { + return getModule.apply(null, arguments); + } + + // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse', { ... }) + else if (arguments.length === 5) { + return setModule.apply(null, arguments); + } else { + error('Invalid extension access syntax'); + } + }; + + // allows a core instance to access extensions internally + Core.prototype.extension = extension; + + // included extensions + incExts.forEach(function (group) { + group.extensions.forEach(function (ext) { + setExtension(group.type, ext.name, ext.impl); + }); + }); + + // a dummy stylesheet object that doesn't need a reference to the core + // (useful for init) + var Stylesheet = function Stylesheet() { + if (!(this instanceof Stylesheet)) { + return new Stylesheet(); + } + this.length = 0; + }; + var sheetfn = Stylesheet.prototype; + sheetfn.instanceString = function () { + return 'stylesheet'; + }; + + // just store the selector to be parsed later + sheetfn.selector = function (selector) { + var i = this.length++; + this[i] = { + selector: selector, + properties: [] + }; + return this; // chaining + }; + + // just store the property to be parsed later + sheetfn.css = function (name, value) { + var i = this.length - 1; + if (string(name)) { + this[i].properties.push({ + name: name, + value: value + }); + } else if (plainObject(name)) { + var map = name; + var propNames = Object.keys(map); + for (var j = 0; j < propNames.length; j++) { + var key = propNames[j]; + var mapVal = map[key]; + if (mapVal == null) { + continue; + } + var prop = Style.properties[key] || Style.properties[dash2camel(key)]; + if (prop == null) { + continue; + } + var _name = prop.name; + var _value = mapVal; + this[i].properties.push({ + name: _name, + value: _value + }); + } + } + return this; // chaining + }; + + sheetfn.style = sheetfn.css; + + // generate a real style object from the dummy stylesheet + sheetfn.generateStyle = function (cy) { + var style = new Style(cy); + return this.appendToStyle(style); + }; + + // append a dummy stylesheet object on a real style object + sheetfn.appendToStyle = function (style) { + for (var i = 0; i < this.length; i++) { + var context = this[i]; + var selector = context.selector; + var props = context.properties; + style.selector(selector); // apply selector + + for (var j = 0; j < props.length; j++) { + var prop = props[j]; + style.css(prop.name, prop.value); // apply property + } + } + + return style; + }; + + var version = "3.27.0"; + + var cytoscape = function cytoscape(options) { + // if no options specified, use default + if (options === undefined) { + options = {}; + } + + // create instance + if (plainObject(options)) { + return new Core(options); + } + + // allow for registration of extensions + else if (string(options)) { + return extension.apply(extension, arguments); + } + }; + + // e.g. cytoscape.use( require('cytoscape-foo'), bar ) + cytoscape.use = function (ext) { + var args = Array.prototype.slice.call(arguments, 1); // args to pass to ext + + args.unshift(cytoscape); // cytoscape is first arg to ext + + ext.apply(null, args); + return this; + }; + cytoscape.warnings = function (bool) { + return warnings(bool); + }; + + // replaced by build system + cytoscape.version = version; + + // expose public apis (mostly for extensions) + cytoscape.stylesheet = cytoscape.Stylesheet = Stylesheet; + + return cytoscape; + +})); + + +/***/ }), + +/***/ 82241: +/***/ (function(module) { + +(function webpackUniversalModuleDefinition(root, factory) { + if(true) + module.exports = factory(); + else {} +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __nested_webpack_require_543__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_543__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __nested_webpack_require_543__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __nested_webpack_require_543__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __nested_webpack_require_543__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __nested_webpack_require_543__.d = function(exports, name, getter) { +/******/ if(!__nested_webpack_require_543__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __nested_webpack_require_543__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __nested_webpack_require_543__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __nested_webpack_require_543__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __nested_webpack_require_543__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __nested_webpack_require_543__(__nested_webpack_require_543__.s = 26); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function LayoutConstants() {} + +/** + * Layout Quality: 0:draft, 1:default, 2:proof + */ +LayoutConstants.QUALITY = 1; + +/** + * Default parameters + */ +LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED = false; +LayoutConstants.DEFAULT_INCREMENTAL = false; +LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT = true; +LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT = false; +LayoutConstants.DEFAULT_ANIMATION_PERIOD = 50; +LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES = false; + +// ----------------------------------------------------------------------------- +// Section: General other constants +// ----------------------------------------------------------------------------- +/* + * Margins of a graph to be applied on bouding rectangle of its contents. We + * assume margins on all four sides to be uniform. + */ +LayoutConstants.DEFAULT_GRAPH_MARGIN = 15; + +/* + * Whether to consider labels in node dimensions or not + */ +LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = false; + +/* + * Default dimension of a non-compound node. + */ +LayoutConstants.SIMPLE_NODE_SIZE = 40; + +/* + * Default dimension of a non-compound node. + */ +LayoutConstants.SIMPLE_NODE_HALF_SIZE = LayoutConstants.SIMPLE_NODE_SIZE / 2; + +/* + * Empty compound node size. When a compound node is empty, its both + * dimensions should be of this value. + */ +LayoutConstants.EMPTY_COMPOUND_NODE_SIZE = 40; + +/* + * Minimum length that an edge should take during layout + */ +LayoutConstants.MIN_EDGE_LENGTH = 1; + +/* + * World boundaries that layout operates on + */ +LayoutConstants.WORLD_BOUNDARY = 1000000; + +/* + * World boundaries that random positioning can be performed with + */ +LayoutConstants.INITIAL_WORLD_BOUNDARY = LayoutConstants.WORLD_BOUNDARY / 1000; + +/* + * Coordinates of the world center + */ +LayoutConstants.WORLD_CENTER_X = 1200; +LayoutConstants.WORLD_CENTER_Y = 900; + +module.exports = LayoutConstants; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __nested_webpack_require_4947__) { + +"use strict"; + + +var LGraphObject = __nested_webpack_require_4947__(2); +var IGeometry = __nested_webpack_require_4947__(8); +var IMath = __nested_webpack_require_4947__(9); + +function LEdge(source, target, vEdge) { + LGraphObject.call(this, vEdge); + + this.isOverlapingSourceAndTarget = false; + this.vGraphObject = vEdge; + this.bendpoints = []; + this.source = source; + this.target = target; +} + +LEdge.prototype = Object.create(LGraphObject.prototype); + +for (var prop in LGraphObject) { + LEdge[prop] = LGraphObject[prop]; +} + +LEdge.prototype.getSource = function () { + return this.source; +}; + +LEdge.prototype.getTarget = function () { + return this.target; +}; + +LEdge.prototype.isInterGraph = function () { + return this.isInterGraph; +}; + +LEdge.prototype.getLength = function () { + return this.length; +}; + +LEdge.prototype.isOverlapingSourceAndTarget = function () { + return this.isOverlapingSourceAndTarget; +}; + +LEdge.prototype.getBendpoints = function () { + return this.bendpoints; +}; + +LEdge.prototype.getLca = function () { + return this.lca; +}; + +LEdge.prototype.getSourceInLca = function () { + return this.sourceInLca; +}; + +LEdge.prototype.getTargetInLca = function () { + return this.targetInLca; +}; + +LEdge.prototype.getOtherEnd = function (node) { + if (this.source === node) { + return this.target; + } else if (this.target === node) { + return this.source; + } else { + throw "Node is not incident with this edge"; + } +}; + +LEdge.prototype.getOtherEndInGraph = function (node, graph) { + var otherEnd = this.getOtherEnd(node); + var root = graph.getGraphManager().getRoot(); + + while (true) { + if (otherEnd.getOwner() == graph) { + return otherEnd; + } + + if (otherEnd.getOwner() == root) { + break; + } + + otherEnd = otherEnd.getOwner().getParent(); + } + + return null; +}; + +LEdge.prototype.updateLength = function () { + var clipPointCoordinates = new Array(4); + + this.isOverlapingSourceAndTarget = IGeometry.getIntersection(this.target.getRect(), this.source.getRect(), clipPointCoordinates); + + if (!this.isOverlapingSourceAndTarget) { + this.lengthX = clipPointCoordinates[0] - clipPointCoordinates[2]; + this.lengthY = clipPointCoordinates[1] - clipPointCoordinates[3]; + + if (Math.abs(this.lengthX) < 1.0) { + this.lengthX = IMath.sign(this.lengthX); + } + + if (Math.abs(this.lengthY) < 1.0) { + this.lengthY = IMath.sign(this.lengthY); + } + + this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY); + } +}; + +LEdge.prototype.updateLengthSimple = function () { + this.lengthX = this.target.getCenterX() - this.source.getCenterX(); + this.lengthY = this.target.getCenterY() - this.source.getCenterY(); + + if (Math.abs(this.lengthX) < 1.0) { + this.lengthX = IMath.sign(this.lengthX); + } + + if (Math.abs(this.lengthY) < 1.0) { + this.lengthY = IMath.sign(this.lengthY); + } + + this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY); +}; + +module.exports = LEdge; + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function LGraphObject(vGraphObject) { + this.vGraphObject = vGraphObject; +} + +module.exports = LGraphObject; + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __nested_webpack_require_8167__) { + +"use strict"; + + +var LGraphObject = __nested_webpack_require_8167__(2); +var Integer = __nested_webpack_require_8167__(10); +var RectangleD = __nested_webpack_require_8167__(13); +var LayoutConstants = __nested_webpack_require_8167__(0); +var RandomSeed = __nested_webpack_require_8167__(16); +var PointD = __nested_webpack_require_8167__(4); + +function LNode(gm, loc, size, vNode) { + //Alternative constructor 1 : LNode(LGraphManager gm, Point loc, Dimension size, Object vNode) + if (size == null && vNode == null) { + vNode = loc; + } + + LGraphObject.call(this, vNode); + + //Alternative constructor 2 : LNode(Layout layout, Object vNode) + if (gm.graphManager != null) gm = gm.graphManager; + + this.estimatedSize = Integer.MIN_VALUE; + this.inclusionTreeDepth = Integer.MAX_VALUE; + this.vGraphObject = vNode; + this.edges = []; + this.graphManager = gm; + + if (size != null && loc != null) this.rect = new RectangleD(loc.x, loc.y, size.width, size.height);else this.rect = new RectangleD(); +} + +LNode.prototype = Object.create(LGraphObject.prototype); +for (var prop in LGraphObject) { + LNode[prop] = LGraphObject[prop]; +} + +LNode.prototype.getEdges = function () { + return this.edges; +}; + +LNode.prototype.getChild = function () { + return this.child; +}; + +LNode.prototype.getOwner = function () { + // if (this.owner != null) { + // if (!(this.owner == null || this.owner.getNodes().indexOf(this) > -1)) { + // throw "assert failed"; + // } + // } + + return this.owner; +}; + +LNode.prototype.getWidth = function () { + return this.rect.width; +}; + +LNode.prototype.setWidth = function (width) { + this.rect.width = width; +}; + +LNode.prototype.getHeight = function () { + return this.rect.height; +}; + +LNode.prototype.setHeight = function (height) { + this.rect.height = height; +}; + +LNode.prototype.getCenterX = function () { + return this.rect.x + this.rect.width / 2; +}; + +LNode.prototype.getCenterY = function () { + return this.rect.y + this.rect.height / 2; +}; + +LNode.prototype.getCenter = function () { + return new PointD(this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2); +}; + +LNode.prototype.getLocation = function () { + return new PointD(this.rect.x, this.rect.y); +}; + +LNode.prototype.getRect = function () { + return this.rect; +}; + +LNode.prototype.getDiagonal = function () { + return Math.sqrt(this.rect.width * this.rect.width + this.rect.height * this.rect.height); +}; + +/** + * This method returns half the diagonal length of this node. + */ +LNode.prototype.getHalfTheDiagonal = function () { + return Math.sqrt(this.rect.height * this.rect.height + this.rect.width * this.rect.width) / 2; +}; + +LNode.prototype.setRect = function (upperLeft, dimension) { + this.rect.x = upperLeft.x; + this.rect.y = upperLeft.y; + this.rect.width = dimension.width; + this.rect.height = dimension.height; +}; + +LNode.prototype.setCenter = function (cx, cy) { + this.rect.x = cx - this.rect.width / 2; + this.rect.y = cy - this.rect.height / 2; +}; + +LNode.prototype.setLocation = function (x, y) { + this.rect.x = x; + this.rect.y = y; +}; + +LNode.prototype.moveBy = function (dx, dy) { + this.rect.x += dx; + this.rect.y += dy; +}; + +LNode.prototype.getEdgeListToNode = function (to) { + var edgeList = []; + var edge; + var self = this; + + self.edges.forEach(function (edge) { + + if (edge.target == to) { + if (edge.source != self) throw "Incorrect edge source!"; + + edgeList.push(edge); + } + }); + + return edgeList; +}; + +LNode.prototype.getEdgesBetween = function (other) { + var edgeList = []; + var edge; + + var self = this; + self.edges.forEach(function (edge) { + + if (!(edge.source == self || edge.target == self)) throw "Incorrect edge source and/or target"; + + if (edge.target == other || edge.source == other) { + edgeList.push(edge); + } + }); + + return edgeList; +}; + +LNode.prototype.getNeighborsList = function () { + var neighbors = new Set(); + + var self = this; + self.edges.forEach(function (edge) { + + if (edge.source == self) { + neighbors.add(edge.target); + } else { + if (edge.target != self) { + throw "Incorrect incidency!"; + } + + neighbors.add(edge.source); + } + }); + + return neighbors; +}; + +LNode.prototype.withChildren = function () { + var withNeighborsList = new Set(); + var childNode; + var children; + + withNeighborsList.add(this); + + if (this.child != null) { + var nodes = this.child.getNodes(); + for (var i = 0; i < nodes.length; i++) { + childNode = nodes[i]; + children = childNode.withChildren(); + children.forEach(function (node) { + withNeighborsList.add(node); + }); + } + } + + return withNeighborsList; +}; + +LNode.prototype.getNoOfChildren = function () { + var noOfChildren = 0; + var childNode; + + if (this.child == null) { + noOfChildren = 1; + } else { + var nodes = this.child.getNodes(); + for (var i = 0; i < nodes.length; i++) { + childNode = nodes[i]; + + noOfChildren += childNode.getNoOfChildren(); + } + } + + if (noOfChildren == 0) { + noOfChildren = 1; + } + return noOfChildren; +}; + +LNode.prototype.getEstimatedSize = function () { + if (this.estimatedSize == Integer.MIN_VALUE) { + throw "assert failed"; + } + return this.estimatedSize; +}; + +LNode.prototype.calcEstimatedSize = function () { + if (this.child == null) { + return this.estimatedSize = (this.rect.width + this.rect.height) / 2; + } else { + this.estimatedSize = this.child.calcEstimatedSize(); + this.rect.width = this.estimatedSize; + this.rect.height = this.estimatedSize; + + return this.estimatedSize; + } +}; + +LNode.prototype.scatter = function () { + var randomCenterX; + var randomCenterY; + + var minX = -LayoutConstants.INITIAL_WORLD_BOUNDARY; + var maxX = LayoutConstants.INITIAL_WORLD_BOUNDARY; + randomCenterX = LayoutConstants.WORLD_CENTER_X + RandomSeed.nextDouble() * (maxX - minX) + minX; + + var minY = -LayoutConstants.INITIAL_WORLD_BOUNDARY; + var maxY = LayoutConstants.INITIAL_WORLD_BOUNDARY; + randomCenterY = LayoutConstants.WORLD_CENTER_Y + RandomSeed.nextDouble() * (maxY - minY) + minY; + + this.rect.x = randomCenterX; + this.rect.y = randomCenterY; +}; + +LNode.prototype.updateBounds = function () { + if (this.getChild() == null) { + throw "assert failed"; + } + if (this.getChild().getNodes().length != 0) { + // wrap the children nodes by re-arranging the boundaries + var childGraph = this.getChild(); + childGraph.updateBounds(true); + + this.rect.x = childGraph.getLeft(); + this.rect.y = childGraph.getTop(); + + this.setWidth(childGraph.getRight() - childGraph.getLeft()); + this.setHeight(childGraph.getBottom() - childGraph.getTop()); + + // Update compound bounds considering its label properties + if (LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS) { + + var width = childGraph.getRight() - childGraph.getLeft(); + var height = childGraph.getBottom() - childGraph.getTop(); + + if (this.labelWidth > width) { + this.rect.x -= (this.labelWidth - width) / 2; + this.setWidth(this.labelWidth); + } + + if (this.labelHeight > height) { + if (this.labelPos == "center") { + this.rect.y -= (this.labelHeight - height) / 2; + } else if (this.labelPos == "top") { + this.rect.y -= this.labelHeight - height; + } + this.setHeight(this.labelHeight); + } + } + } +}; + +LNode.prototype.getInclusionTreeDepth = function () { + if (this.inclusionTreeDepth == Integer.MAX_VALUE) { + throw "assert failed"; + } + return this.inclusionTreeDepth; +}; + +LNode.prototype.transform = function (trans) { + var left = this.rect.x; + + if (left > LayoutConstants.WORLD_BOUNDARY) { + left = LayoutConstants.WORLD_BOUNDARY; + } else if (left < -LayoutConstants.WORLD_BOUNDARY) { + left = -LayoutConstants.WORLD_BOUNDARY; + } + + var top = this.rect.y; + + if (top > LayoutConstants.WORLD_BOUNDARY) { + top = LayoutConstants.WORLD_BOUNDARY; + } else if (top < -LayoutConstants.WORLD_BOUNDARY) { + top = -LayoutConstants.WORLD_BOUNDARY; + } + + var leftTop = new PointD(left, top); + var vLeftTop = trans.inverseTransformPoint(leftTop); + + this.setLocation(vLeftTop.x, vLeftTop.y); +}; + +LNode.prototype.getLeft = function () { + return this.rect.x; +}; + +LNode.prototype.getRight = function () { + return this.rect.x + this.rect.width; +}; + +LNode.prototype.getTop = function () { + return this.rect.y; +}; + +LNode.prototype.getBottom = function () { + return this.rect.y + this.rect.height; +}; + +LNode.prototype.getParent = function () { + if (this.owner == null) { + return null; + } + + return this.owner.getParent(); +}; + +module.exports = LNode; + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function PointD(x, y) { + if (x == null && y == null) { + this.x = 0; + this.y = 0; + } else { + this.x = x; + this.y = y; + } +} + +PointD.prototype.getX = function () { + return this.x; +}; + +PointD.prototype.getY = function () { + return this.y; +}; + +PointD.prototype.setX = function (x) { + this.x = x; +}; + +PointD.prototype.setY = function (y) { + this.y = y; +}; + +PointD.prototype.getDifference = function (pt) { + return new DimensionD(this.x - pt.x, this.y - pt.y); +}; + +PointD.prototype.getCopy = function () { + return new PointD(this.x, this.y); +}; + +PointD.prototype.translate = function (dim) { + this.x += dim.width; + this.y += dim.height; + return this; +}; + +module.exports = PointD; + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __nested_webpack_require_17549__) { + +"use strict"; + + +var LGraphObject = __nested_webpack_require_17549__(2); +var Integer = __nested_webpack_require_17549__(10); +var LayoutConstants = __nested_webpack_require_17549__(0); +var LGraphManager = __nested_webpack_require_17549__(6); +var LNode = __nested_webpack_require_17549__(3); +var LEdge = __nested_webpack_require_17549__(1); +var RectangleD = __nested_webpack_require_17549__(13); +var Point = __nested_webpack_require_17549__(12); +var LinkedList = __nested_webpack_require_17549__(11); + +function LGraph(parent, obj2, vGraph) { + LGraphObject.call(this, vGraph); + this.estimatedSize = Integer.MIN_VALUE; + this.margin = LayoutConstants.DEFAULT_GRAPH_MARGIN; + this.edges = []; + this.nodes = []; + this.isConnected = false; + this.parent = parent; + + if (obj2 != null && obj2 instanceof LGraphManager) { + this.graphManager = obj2; + } else if (obj2 != null && obj2 instanceof Layout) { + this.graphManager = obj2.graphManager; + } +} + +LGraph.prototype = Object.create(LGraphObject.prototype); +for (var prop in LGraphObject) { + LGraph[prop] = LGraphObject[prop]; +} + +LGraph.prototype.getNodes = function () { + return this.nodes; +}; + +LGraph.prototype.getEdges = function () { + return this.edges; +}; + +LGraph.prototype.getGraphManager = function () { + return this.graphManager; +}; + +LGraph.prototype.getParent = function () { + return this.parent; +}; + +LGraph.prototype.getLeft = function () { + return this.left; +}; + +LGraph.prototype.getRight = function () { + return this.right; +}; + +LGraph.prototype.getTop = function () { + return this.top; +}; + +LGraph.prototype.getBottom = function () { + return this.bottom; +}; + +LGraph.prototype.isConnected = function () { + return this.isConnected; +}; + +LGraph.prototype.add = function (obj1, sourceNode, targetNode) { + if (sourceNode == null && targetNode == null) { + var newNode = obj1; + if (this.graphManager == null) { + throw "Graph has no graph mgr!"; + } + if (this.getNodes().indexOf(newNode) > -1) { + throw "Node already in graph!"; + } + newNode.owner = this; + this.getNodes().push(newNode); + + return newNode; + } else { + var newEdge = obj1; + if (!(this.getNodes().indexOf(sourceNode) > -1 && this.getNodes().indexOf(targetNode) > -1)) { + throw "Source or target not in graph!"; + } + + if (!(sourceNode.owner == targetNode.owner && sourceNode.owner == this)) { + throw "Both owners must be this graph!"; + } + + if (sourceNode.owner != targetNode.owner) { + return null; + } + + // set source and target + newEdge.source = sourceNode; + newEdge.target = targetNode; + + // set as intra-graph edge + newEdge.isInterGraph = false; + + // add to graph edge list + this.getEdges().push(newEdge); + + // add to incidency lists + sourceNode.edges.push(newEdge); + + if (targetNode != sourceNode) { + targetNode.edges.push(newEdge); + } + + return newEdge; + } +}; + +LGraph.prototype.remove = function (obj) { + var node = obj; + if (obj instanceof LNode) { + if (node == null) { + throw "Node is null!"; + } + if (!(node.owner != null && node.owner == this)) { + throw "Owner graph is invalid!"; + } + if (this.graphManager == null) { + throw "Owner graph manager is invalid!"; + } + // remove incident edges first (make a copy to do it safely) + var edgesToBeRemoved = node.edges.slice(); + var edge; + var s = edgesToBeRemoved.length; + for (var i = 0; i < s; i++) { + edge = edgesToBeRemoved[i]; + + if (edge.isInterGraph) { + this.graphManager.remove(edge); + } else { + edge.source.owner.remove(edge); + } + } + + // now the node itself + var index = this.nodes.indexOf(node); + if (index == -1) { + throw "Node not in owner node list!"; + } + + this.nodes.splice(index, 1); + } else if (obj instanceof LEdge) { + var edge = obj; + if (edge == null) { + throw "Edge is null!"; + } + if (!(edge.source != null && edge.target != null)) { + throw "Source and/or target is null!"; + } + if (!(edge.source.owner != null && edge.target.owner != null && edge.source.owner == this && edge.target.owner == this)) { + throw "Source and/or target owner is invalid!"; + } + + var sourceIndex = edge.source.edges.indexOf(edge); + var targetIndex = edge.target.edges.indexOf(edge); + if (!(sourceIndex > -1 && targetIndex > -1)) { + throw "Source and/or target doesn't know this edge!"; + } + + edge.source.edges.splice(sourceIndex, 1); + + if (edge.target != edge.source) { + edge.target.edges.splice(targetIndex, 1); + } + + var index = edge.source.owner.getEdges().indexOf(edge); + if (index == -1) { + throw "Not in owner's edge list!"; + } + + edge.source.owner.getEdges().splice(index, 1); + } +}; + +LGraph.prototype.updateLeftTop = function () { + var top = Integer.MAX_VALUE; + var left = Integer.MAX_VALUE; + var nodeTop; + var nodeLeft; + var margin; + + var nodes = this.getNodes(); + var s = nodes.length; + + for (var i = 0; i < s; i++) { + var lNode = nodes[i]; + nodeTop = lNode.getTop(); + nodeLeft = lNode.getLeft(); + + if (top > nodeTop) { + top = nodeTop; + } + + if (left > nodeLeft) { + left = nodeLeft; + } + } + + // Do we have any nodes in this graph? + if (top == Integer.MAX_VALUE) { + return null; + } + + if (nodes[0].getParent().paddingLeft != undefined) { + margin = nodes[0].getParent().paddingLeft; + } else { + margin = this.margin; + } + + this.left = left - margin; + this.top = top - margin; + + // Apply the margins and return the result + return new Point(this.left, this.top); +}; + +LGraph.prototype.updateBounds = function (recursive) { + // calculate bounds + var left = Integer.MAX_VALUE; + var right = -Integer.MAX_VALUE; + var top = Integer.MAX_VALUE; + var bottom = -Integer.MAX_VALUE; + var nodeLeft; + var nodeRight; + var nodeTop; + var nodeBottom; + var margin; + + var nodes = this.nodes; + var s = nodes.length; + for (var i = 0; i < s; i++) { + var lNode = nodes[i]; + + if (recursive && lNode.child != null) { + lNode.updateBounds(); + } + nodeLeft = lNode.getLeft(); + nodeRight = lNode.getRight(); + nodeTop = lNode.getTop(); + nodeBottom = lNode.getBottom(); + + if (left > nodeLeft) { + left = nodeLeft; + } + + if (right < nodeRight) { + right = nodeRight; + } + + if (top > nodeTop) { + top = nodeTop; + } + + if (bottom < nodeBottom) { + bottom = nodeBottom; + } + } + + var boundingRect = new RectangleD(left, top, right - left, bottom - top); + if (left == Integer.MAX_VALUE) { + this.left = this.parent.getLeft(); + this.right = this.parent.getRight(); + this.top = this.parent.getTop(); + this.bottom = this.parent.getBottom(); + } + + if (nodes[0].getParent().paddingLeft != undefined) { + margin = nodes[0].getParent().paddingLeft; + } else { + margin = this.margin; + } + + this.left = boundingRect.x - margin; + this.right = boundingRect.x + boundingRect.width + margin; + this.top = boundingRect.y - margin; + this.bottom = boundingRect.y + boundingRect.height + margin; +}; + +LGraph.calculateBounds = function (nodes) { + var left = Integer.MAX_VALUE; + var right = -Integer.MAX_VALUE; + var top = Integer.MAX_VALUE; + var bottom = -Integer.MAX_VALUE; + var nodeLeft; + var nodeRight; + var nodeTop; + var nodeBottom; + + var s = nodes.length; + + for (var i = 0; i < s; i++) { + var lNode = nodes[i]; + nodeLeft = lNode.getLeft(); + nodeRight = lNode.getRight(); + nodeTop = lNode.getTop(); + nodeBottom = lNode.getBottom(); + + if (left > nodeLeft) { + left = nodeLeft; + } + + if (right < nodeRight) { + right = nodeRight; + } + + if (top > nodeTop) { + top = nodeTop; + } + + if (bottom < nodeBottom) { + bottom = nodeBottom; + } + } + + var boundingRect = new RectangleD(left, top, right - left, bottom - top); + + return boundingRect; +}; + +LGraph.prototype.getInclusionTreeDepth = function () { + if (this == this.graphManager.getRoot()) { + return 1; + } else { + return this.parent.getInclusionTreeDepth(); + } +}; + +LGraph.prototype.getEstimatedSize = function () { + if (this.estimatedSize == Integer.MIN_VALUE) { + throw "assert failed"; + } + return this.estimatedSize; +}; + +LGraph.prototype.calcEstimatedSize = function () { + var size = 0; + var nodes = this.nodes; + var s = nodes.length; + + for (var i = 0; i < s; i++) { + var lNode = nodes[i]; + size += lNode.calcEstimatedSize(); + } + + if (size == 0) { + this.estimatedSize = LayoutConstants.EMPTY_COMPOUND_NODE_SIZE; + } else { + this.estimatedSize = size / Math.sqrt(this.nodes.length); + } + + return this.estimatedSize; +}; + +LGraph.prototype.updateConnected = function () { + var self = this; + if (this.nodes.length == 0) { + this.isConnected = true; + return; + } + + var queue = new LinkedList(); + var visited = new Set(); + var currentNode = this.nodes[0]; + var neighborEdges; + var currentNeighbor; + var childrenOfNode = currentNode.withChildren(); + childrenOfNode.forEach(function (node) { + queue.push(node); + visited.add(node); + }); + + while (queue.length !== 0) { + currentNode = queue.shift(); + + // Traverse all neighbors of this node + neighborEdges = currentNode.getEdges(); + var size = neighborEdges.length; + for (var i = 0; i < size; i++) { + var neighborEdge = neighborEdges[i]; + currentNeighbor = neighborEdge.getOtherEndInGraph(currentNode, this); + + // Add unvisited neighbors to the list to visit + if (currentNeighbor != null && !visited.has(currentNeighbor)) { + var childrenOfNeighbor = currentNeighbor.withChildren(); + + childrenOfNeighbor.forEach(function (node) { + queue.push(node); + visited.add(node); + }); + } + } + } + + this.isConnected = false; + + if (visited.size >= this.nodes.length) { + var noOfVisitedInThisGraph = 0; + + visited.forEach(function (visitedNode) { + if (visitedNode.owner == self) { + noOfVisitedInThisGraph++; + } + }); + + if (noOfVisitedInThisGraph == this.nodes.length) { + this.isConnected = true; + } + } +}; + +module.exports = LGraph; + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __nested_webpack_require_27617__) { + +"use strict"; + + +var LGraph; +var LEdge = __nested_webpack_require_27617__(1); + +function LGraphManager(layout) { + LGraph = __nested_webpack_require_27617__(5); // It may be better to initilize this out of this function but it gives an error (Right-hand side of 'instanceof' is not callable) now. + this.layout = layout; + + this.graphs = []; + this.edges = []; +} + +LGraphManager.prototype.addRoot = function () { + var ngraph = this.layout.newGraph(); + var nnode = this.layout.newNode(null); + var root = this.add(ngraph, nnode); + this.setRootGraph(root); + return this.rootGraph; +}; + +LGraphManager.prototype.add = function (newGraph, parentNode, newEdge, sourceNode, targetNode) { + //there are just 2 parameters are passed then it adds an LGraph else it adds an LEdge + if (newEdge == null && sourceNode == null && targetNode == null) { + if (newGraph == null) { + throw "Graph is null!"; + } + if (parentNode == null) { + throw "Parent node is null!"; + } + if (this.graphs.indexOf(newGraph) > -1) { + throw "Graph already in this graph mgr!"; + } + + this.graphs.push(newGraph); + + if (newGraph.parent != null) { + throw "Already has a parent!"; + } + if (parentNode.child != null) { + throw "Already has a child!"; + } + + newGraph.parent = parentNode; + parentNode.child = newGraph; + + return newGraph; + } else { + //change the order of the parameters + targetNode = newEdge; + sourceNode = parentNode; + newEdge = newGraph; + var sourceGraph = sourceNode.getOwner(); + var targetGraph = targetNode.getOwner(); + + if (!(sourceGraph != null && sourceGraph.getGraphManager() == this)) { + throw "Source not in this graph mgr!"; + } + if (!(targetGraph != null && targetGraph.getGraphManager() == this)) { + throw "Target not in this graph mgr!"; + } + + if (sourceGraph == targetGraph) { + newEdge.isInterGraph = false; + return sourceGraph.add(newEdge, sourceNode, targetNode); + } else { + newEdge.isInterGraph = true; + + // set source and target + newEdge.source = sourceNode; + newEdge.target = targetNode; + + // add edge to inter-graph edge list + if (this.edges.indexOf(newEdge) > -1) { + throw "Edge already in inter-graph edge list!"; + } + + this.edges.push(newEdge); + + // add edge to source and target incidency lists + if (!(newEdge.source != null && newEdge.target != null)) { + throw "Edge source and/or target is null!"; + } + + if (!(newEdge.source.edges.indexOf(newEdge) == -1 && newEdge.target.edges.indexOf(newEdge) == -1)) { + throw "Edge already in source and/or target incidency list!"; + } + + newEdge.source.edges.push(newEdge); + newEdge.target.edges.push(newEdge); + + return newEdge; + } + } +}; + +LGraphManager.prototype.remove = function (lObj) { + if (lObj instanceof LGraph) { + var graph = lObj; + if (graph.getGraphManager() != this) { + throw "Graph not in this graph mgr"; + } + if (!(graph == this.rootGraph || graph.parent != null && graph.parent.graphManager == this)) { + throw "Invalid parent node!"; + } + + // first the edges (make a copy to do it safely) + var edgesToBeRemoved = []; + + edgesToBeRemoved = edgesToBeRemoved.concat(graph.getEdges()); + + var edge; + var s = edgesToBeRemoved.length; + for (var i = 0; i < s; i++) { + edge = edgesToBeRemoved[i]; + graph.remove(edge); + } + + // then the nodes (make a copy to do it safely) + var nodesToBeRemoved = []; + + nodesToBeRemoved = nodesToBeRemoved.concat(graph.getNodes()); + + var node; + s = nodesToBeRemoved.length; + for (var i = 0; i < s; i++) { + node = nodesToBeRemoved[i]; + graph.remove(node); + } + + // check if graph is the root + if (graph == this.rootGraph) { + this.setRootGraph(null); + } + + // now remove the graph itself + var index = this.graphs.indexOf(graph); + this.graphs.splice(index, 1); + + // also reset the parent of the graph + graph.parent = null; + } else if (lObj instanceof LEdge) { + edge = lObj; + if (edge == null) { + throw "Edge is null!"; + } + if (!edge.isInterGraph) { + throw "Not an inter-graph edge!"; + } + if (!(edge.source != null && edge.target != null)) { + throw "Source and/or target is null!"; + } + + // remove edge from source and target nodes' incidency lists + + if (!(edge.source.edges.indexOf(edge) != -1 && edge.target.edges.indexOf(edge) != -1)) { + throw "Source and/or target doesn't know this edge!"; + } + + var index = edge.source.edges.indexOf(edge); + edge.source.edges.splice(index, 1); + index = edge.target.edges.indexOf(edge); + edge.target.edges.splice(index, 1); + + // remove edge from owner graph manager's inter-graph edge list + + if (!(edge.source.owner != null && edge.source.owner.getGraphManager() != null)) { + throw "Edge owner graph or owner graph manager is null!"; + } + if (edge.source.owner.getGraphManager().edges.indexOf(edge) == -1) { + throw "Not in owner graph manager's edge list!"; + } + + var index = edge.source.owner.getGraphManager().edges.indexOf(edge); + edge.source.owner.getGraphManager().edges.splice(index, 1); + } +}; + +LGraphManager.prototype.updateBounds = function () { + this.rootGraph.updateBounds(true); +}; + +LGraphManager.prototype.getGraphs = function () { + return this.graphs; +}; + +LGraphManager.prototype.getAllNodes = function () { + if (this.allNodes == null) { + var nodeList = []; + var graphs = this.getGraphs(); + var s = graphs.length; + for (var i = 0; i < s; i++) { + nodeList = nodeList.concat(graphs[i].getNodes()); + } + this.allNodes = nodeList; + } + return this.allNodes; +}; + +LGraphManager.prototype.resetAllNodes = function () { + this.allNodes = null; +}; + +LGraphManager.prototype.resetAllEdges = function () { + this.allEdges = null; +}; + +LGraphManager.prototype.resetAllNodesToApplyGravitation = function () { + this.allNodesToApplyGravitation = null; +}; + +LGraphManager.prototype.getAllEdges = function () { + if (this.allEdges == null) { + var edgeList = []; + var graphs = this.getGraphs(); + var s = graphs.length; + for (var i = 0; i < graphs.length; i++) { + edgeList = edgeList.concat(graphs[i].getEdges()); + } + + edgeList = edgeList.concat(this.edges); + + this.allEdges = edgeList; + } + return this.allEdges; +}; + +LGraphManager.prototype.getAllNodesToApplyGravitation = function () { + return this.allNodesToApplyGravitation; +}; + +LGraphManager.prototype.setAllNodesToApplyGravitation = function (nodeList) { + if (this.allNodesToApplyGravitation != null) { + throw "assert failed"; + } + + this.allNodesToApplyGravitation = nodeList; +}; + +LGraphManager.prototype.getRoot = function () { + return this.rootGraph; +}; + +LGraphManager.prototype.setRootGraph = function (graph) { + if (graph.getGraphManager() != this) { + throw "Root not in this graph mgr!"; + } + + this.rootGraph = graph; + // root graph must have a root node associated with it for convenience + if (graph.parent == null) { + graph.parent = this.layout.newNode("Root node"); + } +}; + +LGraphManager.prototype.getLayout = function () { + return this.layout; +}; + +LGraphManager.prototype.isOneAncestorOfOther = function (firstNode, secondNode) { + if (!(firstNode != null && secondNode != null)) { + throw "assert failed"; + } + + if (firstNode == secondNode) { + return true; + } + // Is second node an ancestor of the first one? + var ownerGraph = firstNode.getOwner(); + var parentNode; + + do { + parentNode = ownerGraph.getParent(); + + if (parentNode == null) { + break; + } + + if (parentNode == secondNode) { + return true; + } + + ownerGraph = parentNode.getOwner(); + if (ownerGraph == null) { + break; + } + } while (true); + // Is first node an ancestor of the second one? + ownerGraph = secondNode.getOwner(); + + do { + parentNode = ownerGraph.getParent(); + + if (parentNode == null) { + break; + } + + if (parentNode == firstNode) { + return true; + } + + ownerGraph = parentNode.getOwner(); + if (ownerGraph == null) { + break; + } + } while (true); + + return false; +}; + +LGraphManager.prototype.calcLowestCommonAncestors = function () { + var edge; + var sourceNode; + var targetNode; + var sourceAncestorGraph; + var targetAncestorGraph; + + var edges = this.getAllEdges(); + var s = edges.length; + for (var i = 0; i < s; i++) { + edge = edges[i]; + + sourceNode = edge.source; + targetNode = edge.target; + edge.lca = null; + edge.sourceInLca = sourceNode; + edge.targetInLca = targetNode; + + if (sourceNode == targetNode) { + edge.lca = sourceNode.getOwner(); + continue; + } + + sourceAncestorGraph = sourceNode.getOwner(); + + while (edge.lca == null) { + edge.targetInLca = targetNode; + targetAncestorGraph = targetNode.getOwner(); + + while (edge.lca == null) { + if (targetAncestorGraph == sourceAncestorGraph) { + edge.lca = targetAncestorGraph; + break; + } + + if (targetAncestorGraph == this.rootGraph) { + break; + } + + if (edge.lca != null) { + throw "assert failed"; + } + edge.targetInLca = targetAncestorGraph.getParent(); + targetAncestorGraph = edge.targetInLca.getOwner(); + } + + if (sourceAncestorGraph == this.rootGraph) { + break; + } + + if (edge.lca == null) { + edge.sourceInLca = sourceAncestorGraph.getParent(); + sourceAncestorGraph = edge.sourceInLca.getOwner(); + } + } + + if (edge.lca == null) { + throw "assert failed"; + } + } +}; + +LGraphManager.prototype.calcLowestCommonAncestor = function (firstNode, secondNode) { + if (firstNode == secondNode) { + return firstNode.getOwner(); + } + var firstOwnerGraph = firstNode.getOwner(); + + do { + if (firstOwnerGraph == null) { + break; + } + var secondOwnerGraph = secondNode.getOwner(); + + do { + if (secondOwnerGraph == null) { + break; + } + + if (secondOwnerGraph == firstOwnerGraph) { + return secondOwnerGraph; + } + secondOwnerGraph = secondOwnerGraph.getParent().getOwner(); + } while (true); + + firstOwnerGraph = firstOwnerGraph.getParent().getOwner(); + } while (true); + + return firstOwnerGraph; +}; + +LGraphManager.prototype.calcInclusionTreeDepths = function (graph, depth) { + if (graph == null && depth == null) { + graph = this.rootGraph; + depth = 1; + } + var node; + + var nodes = graph.getNodes(); + var s = nodes.length; + for (var i = 0; i < s; i++) { + node = nodes[i]; + node.inclusionTreeDepth = depth; + + if (node.child != null) { + this.calcInclusionTreeDepths(node.child, depth + 1); + } + } +}; + +LGraphManager.prototype.includesInvalidEdge = function () { + var edge; + + var s = this.edges.length; + for (var i = 0; i < s; i++) { + edge = this.edges[i]; + + if (this.isOneAncestorOfOther(edge.source, edge.target)) { + return true; + } + } + return false; +}; + +module.exports = LGraphManager; + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __nested_webpack_require_38707__) { + +"use strict"; + + +var LayoutConstants = __nested_webpack_require_38707__(0); + +function FDLayoutConstants() {} + +//FDLayoutConstants inherits static props in LayoutConstants +for (var prop in LayoutConstants) { + FDLayoutConstants[prop] = LayoutConstants[prop]; +} + +FDLayoutConstants.MAX_ITERATIONS = 2500; + +FDLayoutConstants.DEFAULT_EDGE_LENGTH = 50; +FDLayoutConstants.DEFAULT_SPRING_STRENGTH = 0.45; +FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = 4500.0; +FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = 0.4; +FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = 1.0; +FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = 3.8; +FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = 1.5; +FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION = true; +FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION = true; +FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = 0.3; +FDLayoutConstants.COOLING_ADAPTATION_FACTOR = 0.33; +FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT = 1000; +FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT = 5000; +FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL = 100.0; +FDLayoutConstants.MAX_NODE_DISPLACEMENT = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL * 3; +FDLayoutConstants.MIN_REPULSION_DIST = FDLayoutConstants.DEFAULT_EDGE_LENGTH / 10.0; +FDLayoutConstants.CONVERGENCE_CHECK_PERIOD = 100; +FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = 0.1; +FDLayoutConstants.MIN_EDGE_LENGTH = 1; +FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD = 10; + +module.exports = FDLayoutConstants; + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __nested_webpack_require_40298__) { + +"use strict"; + + +/** + * This class maintains a list of static geometry related utility methods. + * + * + * Copyright: i-Vis Research Group, Bilkent University, 2007 - present + */ + +var Point = __nested_webpack_require_40298__(12); + +function IGeometry() {} + +/** + * This method calculates *half* the amount in x and y directions of the two + * input rectangles needed to separate them keeping their respective + * positioning, and returns the result in the input array. An input + * separation buffer added to the amount in both directions. We assume that + * the two rectangles do intersect. + */ +IGeometry.calcSeparationAmount = function (rectA, rectB, overlapAmount, separationBuffer) { + if (!rectA.intersects(rectB)) { + throw "assert failed"; + } + + var directions = new Array(2); + + this.decideDirectionsForOverlappingNodes(rectA, rectB, directions); + + overlapAmount[0] = Math.min(rectA.getRight(), rectB.getRight()) - Math.max(rectA.x, rectB.x); + overlapAmount[1] = Math.min(rectA.getBottom(), rectB.getBottom()) - Math.max(rectA.y, rectB.y); + + // update the overlapping amounts for the following cases: + if (rectA.getX() <= rectB.getX() && rectA.getRight() >= rectB.getRight()) { + /* Case x.1: + * + * rectA + * | | + * | _________ | + * | | | | + * |________|_______|______| + * | | + * | | + * rectB + */ + overlapAmount[0] += Math.min(rectB.getX() - rectA.getX(), rectA.getRight() - rectB.getRight()); + } else if (rectB.getX() <= rectA.getX() && rectB.getRight() >= rectA.getRight()) { + /* Case x.2: + * + * rectB + * | | + * | _________ | + * | | | | + * |________|_______|______| + * | | + * | | + * rectA + */ + overlapAmount[0] += Math.min(rectA.getX() - rectB.getX(), rectB.getRight() - rectA.getRight()); + } + if (rectA.getY() <= rectB.getY() && rectA.getBottom() >= rectB.getBottom()) { + /* Case y.1: + * ________ rectA + * | + * | + * ______|____ rectB + * | | + * | | + * ______|____| + * | + * | + * |________ + * + */ + overlapAmount[1] += Math.min(rectB.getY() - rectA.getY(), rectA.getBottom() - rectB.getBottom()); + } else if (rectB.getY() <= rectA.getY() && rectB.getBottom() >= rectA.getBottom()) { + /* Case y.2: + * ________ rectB + * | + * | + * ______|____ rectA + * | | + * | | + * ______|____| + * | + * | + * |________ + * + */ + overlapAmount[1] += Math.min(rectA.getY() - rectB.getY(), rectB.getBottom() - rectA.getBottom()); + } + + // find slope of the line passes two centers + var slope = Math.abs((rectB.getCenterY() - rectA.getCenterY()) / (rectB.getCenterX() - rectA.getCenterX())); + // if centers are overlapped + if (rectB.getCenterY() === rectA.getCenterY() && rectB.getCenterX() === rectA.getCenterX()) { + // assume the slope is 1 (45 degree) + slope = 1.0; + } + + var moveByY = slope * overlapAmount[0]; + var moveByX = overlapAmount[1] / slope; + if (overlapAmount[0] < moveByX) { + moveByX = overlapAmount[0]; + } else { + moveByY = overlapAmount[1]; + } + // return half the amount so that if each rectangle is moved by these + // amounts in opposite directions, overlap will be resolved + overlapAmount[0] = -1 * directions[0] * (moveByX / 2 + separationBuffer); + overlapAmount[1] = -1 * directions[1] * (moveByY / 2 + separationBuffer); +}; + +/** + * This method decides the separation direction of overlapping nodes + * + * if directions[0] = -1, then rectA goes left + * if directions[0] = 1, then rectA goes right + * if directions[1] = -1, then rectA goes up + * if directions[1] = 1, then rectA goes down + */ +IGeometry.decideDirectionsForOverlappingNodes = function (rectA, rectB, directions) { + if (rectA.getCenterX() < rectB.getCenterX()) { + directions[0] = -1; + } else { + directions[0] = 1; + } + + if (rectA.getCenterY() < rectB.getCenterY()) { + directions[1] = -1; + } else { + directions[1] = 1; + } +}; + +/** + * This method calculates the intersection (clipping) points of the two + * input rectangles with line segment defined by the centers of these two + * rectangles. The clipping points are saved in the input double array and + * whether or not the two rectangles overlap is returned. + */ +IGeometry.getIntersection2 = function (rectA, rectB, result) { + //result[0-1] will contain clipPoint of rectA, result[2-3] will contain clipPoint of rectB + var p1x = rectA.getCenterX(); + var p1y = rectA.getCenterY(); + var p2x = rectB.getCenterX(); + var p2y = rectB.getCenterY(); + + //if two rectangles intersect, then clipping points are centers + if (rectA.intersects(rectB)) { + result[0] = p1x; + result[1] = p1y; + result[2] = p2x; + result[3] = p2y; + return true; + } + //variables for rectA + var topLeftAx = rectA.getX(); + var topLeftAy = rectA.getY(); + var topRightAx = rectA.getRight(); + var bottomLeftAx = rectA.getX(); + var bottomLeftAy = rectA.getBottom(); + var bottomRightAx = rectA.getRight(); + var halfWidthA = rectA.getWidthHalf(); + var halfHeightA = rectA.getHeightHalf(); + //variables for rectB + var topLeftBx = rectB.getX(); + var topLeftBy = rectB.getY(); + var topRightBx = rectB.getRight(); + var bottomLeftBx = rectB.getX(); + var bottomLeftBy = rectB.getBottom(); + var bottomRightBx = rectB.getRight(); + var halfWidthB = rectB.getWidthHalf(); + var halfHeightB = rectB.getHeightHalf(); + + //flag whether clipping points are found + var clipPointAFound = false; + var clipPointBFound = false; + + // line is vertical + if (p1x === p2x) { + if (p1y > p2y) { + result[0] = p1x; + result[1] = topLeftAy; + result[2] = p2x; + result[3] = bottomLeftBy; + return false; + } else if (p1y < p2y) { + result[0] = p1x; + result[1] = bottomLeftAy; + result[2] = p2x; + result[3] = topLeftBy; + return false; + } else { + //not line, return null; + } + } + // line is horizontal + else if (p1y === p2y) { + if (p1x > p2x) { + result[0] = topLeftAx; + result[1] = p1y; + result[2] = topRightBx; + result[3] = p2y; + return false; + } else if (p1x < p2x) { + result[0] = topRightAx; + result[1] = p1y; + result[2] = topLeftBx; + result[3] = p2y; + return false; + } else { + //not valid line, return null; + } + } else { + //slopes of rectA's and rectB's diagonals + var slopeA = rectA.height / rectA.width; + var slopeB = rectB.height / rectB.width; + + //slope of line between center of rectA and center of rectB + var slopePrime = (p2y - p1y) / (p2x - p1x); + var cardinalDirectionA = void 0; + var cardinalDirectionB = void 0; + var tempPointAx = void 0; + var tempPointAy = void 0; + var tempPointBx = void 0; + var tempPointBy = void 0; + + //determine whether clipping point is the corner of nodeA + if (-slopeA === slopePrime) { + if (p1x > p2x) { + result[0] = bottomLeftAx; + result[1] = bottomLeftAy; + clipPointAFound = true; + } else { + result[0] = topRightAx; + result[1] = topLeftAy; + clipPointAFound = true; + } + } else if (slopeA === slopePrime) { + if (p1x > p2x) { + result[0] = topLeftAx; + result[1] = topLeftAy; + clipPointAFound = true; + } else { + result[0] = bottomRightAx; + result[1] = bottomLeftAy; + clipPointAFound = true; + } + } + + //determine whether clipping point is the corner of nodeB + if (-slopeB === slopePrime) { + if (p2x > p1x) { + result[2] = bottomLeftBx; + result[3] = bottomLeftBy; + clipPointBFound = true; + } else { + result[2] = topRightBx; + result[3] = topLeftBy; + clipPointBFound = true; + } + } else if (slopeB === slopePrime) { + if (p2x > p1x) { + result[2] = topLeftBx; + result[3] = topLeftBy; + clipPointBFound = true; + } else { + result[2] = bottomRightBx; + result[3] = bottomLeftBy; + clipPointBFound = true; + } + } + + //if both clipping points are corners + if (clipPointAFound && clipPointBFound) { + return false; + } + + //determine Cardinal Direction of rectangles + if (p1x > p2x) { + if (p1y > p2y) { + cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 4); + cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 2); + } else { + cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 3); + cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 1); + } + } else { + if (p1y > p2y) { + cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 1); + cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 3); + } else { + cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 2); + cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 4); + } + } + //calculate clipping Point if it is not found before + if (!clipPointAFound) { + switch (cardinalDirectionA) { + case 1: + tempPointAy = topLeftAy; + tempPointAx = p1x + -halfHeightA / slopePrime; + result[0] = tempPointAx; + result[1] = tempPointAy; + break; + case 2: + tempPointAx = bottomRightAx; + tempPointAy = p1y + halfWidthA * slopePrime; + result[0] = tempPointAx; + result[1] = tempPointAy; + break; + case 3: + tempPointAy = bottomLeftAy; + tempPointAx = p1x + halfHeightA / slopePrime; + result[0] = tempPointAx; + result[1] = tempPointAy; + break; + case 4: + tempPointAx = bottomLeftAx; + tempPointAy = p1y + -halfWidthA * slopePrime; + result[0] = tempPointAx; + result[1] = tempPointAy; + break; + } + } + if (!clipPointBFound) { + switch (cardinalDirectionB) { + case 1: + tempPointBy = topLeftBy; + tempPointBx = p2x + -halfHeightB / slopePrime; + result[2] = tempPointBx; + result[3] = tempPointBy; + break; + case 2: + tempPointBx = bottomRightBx; + tempPointBy = p2y + halfWidthB * slopePrime; + result[2] = tempPointBx; + result[3] = tempPointBy; + break; + case 3: + tempPointBy = bottomLeftBy; + tempPointBx = p2x + halfHeightB / slopePrime; + result[2] = tempPointBx; + result[3] = tempPointBy; + break; + case 4: + tempPointBx = bottomLeftBx; + tempPointBy = p2y + -halfWidthB * slopePrime; + result[2] = tempPointBx; + result[3] = tempPointBy; + break; + } + } + } + return false; +}; + +/** + * This method returns in which cardinal direction does input point stays + * 1: North + * 2: East + * 3: South + * 4: West + */ +IGeometry.getCardinalDirection = function (slope, slopePrime, line) { + if (slope > slopePrime) { + return line; + } else { + return 1 + line % 4; + } +}; + +/** + * This method calculates the intersection of the two lines defined by + * point pairs (s1,s2) and (f1,f2). + */ +IGeometry.getIntersection = function (s1, s2, f1, f2) { + if (f2 == null) { + return this.getIntersection2(s1, s2, f1); + } + + var x1 = s1.x; + var y1 = s1.y; + var x2 = s2.x; + var y2 = s2.y; + var x3 = f1.x; + var y3 = f1.y; + var x4 = f2.x; + var y4 = f2.y; + var x = void 0, + y = void 0; // intersection point + var a1 = void 0, + a2 = void 0, + b1 = void 0, + b2 = void 0, + c1 = void 0, + c2 = void 0; // coefficients of line eqns. + var denom = void 0; + + a1 = y2 - y1; + b1 = x1 - x2; + c1 = x2 * y1 - x1 * y2; // { a1*x + b1*y + c1 = 0 is line 1 } + + a2 = y4 - y3; + b2 = x3 - x4; + c2 = x4 * y3 - x3 * y4; // { a2*x + b2*y + c2 = 0 is line 2 } + + denom = a1 * b2 - a2 * b1; + + if (denom === 0) { + return null; + } + + x = (b1 * c2 - b2 * c1) / denom; + y = (a2 * c1 - a1 * c2) / denom; + + return new Point(x, y); +}; + +/** + * This method finds and returns the angle of the vector from the + x-axis + * in clockwise direction (compatible w/ Java coordinate system!). + */ +IGeometry.angleOfVector = function (Cx, Cy, Nx, Ny) { + var C_angle = void 0; + + if (Cx !== Nx) { + C_angle = Math.atan((Ny - Cy) / (Nx - Cx)); + + if (Nx < Cx) { + C_angle += Math.PI; + } else if (Ny < Cy) { + C_angle += this.TWO_PI; + } + } else if (Ny < Cy) { + C_angle = this.ONE_AND_HALF_PI; // 270 degrees + } else { + C_angle = this.HALF_PI; // 90 degrees + } + + return C_angle; +}; + +/** + * This method checks whether the given two line segments (one with point + * p1 and p2, the other with point p3 and p4) intersect at a point other + * than these points. + */ +IGeometry.doIntersect = function (p1, p2, p3, p4) { + var a = p1.x; + var b = p1.y; + var c = p2.x; + var d = p2.y; + var p = p3.x; + var q = p3.y; + var r = p4.x; + var s = p4.y; + var det = (c - a) * (s - q) - (r - p) * (d - b); + + if (det === 0) { + return false; + } else { + var lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; + var gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; + return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1; + } +}; + +// ----------------------------------------------------------------------------- +// Section: Class Constants +// ----------------------------------------------------------------------------- +/** + * Some useful pre-calculated constants + */ +IGeometry.HALF_PI = 0.5 * Math.PI; +IGeometry.ONE_AND_HALF_PI = 1.5 * Math.PI; +IGeometry.TWO_PI = 2.0 * Math.PI; +IGeometry.THREE_PI = 3.0 * Math.PI; + +module.exports = IGeometry; + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function IMath() {} + +/** + * This method returns the sign of the input value. + */ +IMath.sign = function (value) { + if (value > 0) { + return 1; + } else if (value < 0) { + return -1; + } else { + return 0; + } +}; + +IMath.floor = function (value) { + return value < 0 ? Math.ceil(value) : Math.floor(value); +}; + +IMath.ceil = function (value) { + return value < 0 ? Math.floor(value) : Math.ceil(value); +}; + +module.exports = IMath; + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function Integer() {} + +Integer.MAX_VALUE = 2147483647; +Integer.MIN_VALUE = -2147483648; + +module.exports = Integer; + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +var nodeFrom = function nodeFrom(value) { + return { value: value, next: null, prev: null }; +}; + +var add = function add(prev, node, next, list) { + if (prev !== null) { + prev.next = node; + } else { + list.head = node; + } + + if (next !== null) { + next.prev = node; + } else { + list.tail = node; + } + + node.prev = prev; + node.next = next; + + list.length++; + + return node; +}; + +var _remove = function _remove(node, list) { + var prev = node.prev, + next = node.next; + + + if (prev !== null) { + prev.next = next; + } else { + list.head = next; + } + + if (next !== null) { + next.prev = prev; + } else { + list.tail = prev; + } + + node.prev = node.next = null; + + list.length--; + + return node; +}; + +var LinkedList = function () { + function LinkedList(vals) { + var _this = this; + + _classCallCheck(this, LinkedList); + + this.length = 0; + this.head = null; + this.tail = null; + + if (vals != null) { + vals.forEach(function (v) { + return _this.push(v); + }); + } + } + + _createClass(LinkedList, [{ + key: "size", + value: function size() { + return this.length; + } + }, { + key: "insertBefore", + value: function insertBefore(val, otherNode) { + return add(otherNode.prev, nodeFrom(val), otherNode, this); + } + }, { + key: "insertAfter", + value: function insertAfter(val, otherNode) { + return add(otherNode, nodeFrom(val), otherNode.next, this); + } + }, { + key: "insertNodeBefore", + value: function insertNodeBefore(newNode, otherNode) { + return add(otherNode.prev, newNode, otherNode, this); + } + }, { + key: "insertNodeAfter", + value: function insertNodeAfter(newNode, otherNode) { + return add(otherNode, newNode, otherNode.next, this); + } + }, { + key: "push", + value: function push(val) { + return add(this.tail, nodeFrom(val), null, this); + } + }, { + key: "unshift", + value: function unshift(val) { + return add(null, nodeFrom(val), this.head, this); + } + }, { + key: "remove", + value: function remove(node) { + return _remove(node, this); + } + }, { + key: "pop", + value: function pop() { + return _remove(this.tail, this).value; + } + }, { + key: "popNode", + value: function popNode() { + return _remove(this.tail, this); + } + }, { + key: "shift", + value: function shift() { + return _remove(this.head, this).value; + } + }, { + key: "shiftNode", + value: function shiftNode() { + return _remove(this.head, this); + } + }, { + key: "get_object_at", + value: function get_object_at(index) { + if (index <= this.length()) { + var i = 1; + var current = this.head; + while (i < index) { + current = current.next; + i++; + } + return current.value; + } + } + }, { + key: "set_object_at", + value: function set_object_at(index, value) { + if (index <= this.length()) { + var i = 1; + var current = this.head; + while (i < index) { + current = current.next; + i++; + } + current.value = value; + } + } + }]); + + return LinkedList; +}(); + +module.exports = LinkedList; + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +/* + *This class is the javascript implementation of the Point.java class in jdk + */ +function Point(x, y, p) { + this.x = null; + this.y = null; + if (x == null && y == null && p == null) { + this.x = 0; + this.y = 0; + } else if (typeof x == 'number' && typeof y == 'number' && p == null) { + this.x = x; + this.y = y; + } else if (x.constructor.name == 'Point' && y == null && p == null) { + p = x; + this.x = p.x; + this.y = p.y; + } +} + +Point.prototype.getX = function () { + return this.x; +}; + +Point.prototype.getY = function () { + return this.y; +}; + +Point.prototype.getLocation = function () { + return new Point(this.x, this.y); +}; + +Point.prototype.setLocation = function (x, y, p) { + if (x.constructor.name == 'Point' && y == null && p == null) { + p = x; + this.setLocation(p.x, p.y); + } else if (typeof x == 'number' && typeof y == 'number' && p == null) { + //if both parameters are integer just move (x,y) location + if (parseInt(x) == x && parseInt(y) == y) { + this.move(x, y); + } else { + this.x = Math.floor(x + 0.5); + this.y = Math.floor(y + 0.5); + } + } +}; + +Point.prototype.move = function (x, y) { + this.x = x; + this.y = y; +}; + +Point.prototype.translate = function (dx, dy) { + this.x += dx; + this.y += dy; +}; + +Point.prototype.equals = function (obj) { + if (obj.constructor.name == "Point") { + var pt = obj; + return this.x == pt.x && this.y == pt.y; + } + return this == obj; +}; + +Point.prototype.toString = function () { + return new Point().constructor.name + "[x=" + this.x + ",y=" + this.y + "]"; +}; + +module.exports = Point; + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function RectangleD(x, y, width, height) { + this.x = 0; + this.y = 0; + this.width = 0; + this.height = 0; + + if (x != null && y != null && width != null && height != null) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } +} + +RectangleD.prototype.getX = function () { + return this.x; +}; + +RectangleD.prototype.setX = function (x) { + this.x = x; +}; + +RectangleD.prototype.getY = function () { + return this.y; +}; + +RectangleD.prototype.setY = function (y) { + this.y = y; +}; + +RectangleD.prototype.getWidth = function () { + return this.width; +}; + +RectangleD.prototype.setWidth = function (width) { + this.width = width; +}; + +RectangleD.prototype.getHeight = function () { + return this.height; +}; + +RectangleD.prototype.setHeight = function (height) { + this.height = height; +}; + +RectangleD.prototype.getRight = function () { + return this.x + this.width; +}; + +RectangleD.prototype.getBottom = function () { + return this.y + this.height; +}; + +RectangleD.prototype.intersects = function (a) { + if (this.getRight() < a.x) { + return false; + } + + if (this.getBottom() < a.y) { + return false; + } + + if (a.getRight() < this.x) { + return false; + } + + if (a.getBottom() < this.y) { + return false; + } + + return true; +}; + +RectangleD.prototype.getCenterX = function () { + return this.x + this.width / 2; +}; + +RectangleD.prototype.getMinX = function () { + return this.getX(); +}; + +RectangleD.prototype.getMaxX = function () { + return this.getX() + this.width; +}; + +RectangleD.prototype.getCenterY = function () { + return this.y + this.height / 2; +}; + +RectangleD.prototype.getMinY = function () { + return this.getY(); +}; + +RectangleD.prototype.getMaxY = function () { + return this.getY() + this.height; +}; + +RectangleD.prototype.getWidthHalf = function () { + return this.width / 2; +}; + +RectangleD.prototype.getHeightHalf = function () { + return this.height / 2; +}; + +module.exports = RectangleD; + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + +function UniqueIDGeneretor() {} + +UniqueIDGeneretor.lastID = 0; + +UniqueIDGeneretor.createID = function (obj) { + if (UniqueIDGeneretor.isPrimitive(obj)) { + return obj; + } + if (obj.uniqueID != null) { + return obj.uniqueID; + } + obj.uniqueID = UniqueIDGeneretor.getString(); + UniqueIDGeneretor.lastID++; + return obj.uniqueID; +}; + +UniqueIDGeneretor.getString = function (id) { + if (id == null) id = UniqueIDGeneretor.lastID; + return "Object#" + id + ""; +}; + +UniqueIDGeneretor.isPrimitive = function (arg) { + var type = typeof arg === "undefined" ? "undefined" : _typeof(arg); + return arg == null || type != "object" && type != "function"; +}; + +module.exports = UniqueIDGeneretor; + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __nested_webpack_require_64072__) { + +"use strict"; + + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var LayoutConstants = __nested_webpack_require_64072__(0); +var LGraphManager = __nested_webpack_require_64072__(6); +var LNode = __nested_webpack_require_64072__(3); +var LEdge = __nested_webpack_require_64072__(1); +var LGraph = __nested_webpack_require_64072__(5); +var PointD = __nested_webpack_require_64072__(4); +var Transform = __nested_webpack_require_64072__(17); +var Emitter = __nested_webpack_require_64072__(27); + +function Layout(isRemoteUse) { + Emitter.call(this); + + //Layout Quality: 0:draft, 1:default, 2:proof + this.layoutQuality = LayoutConstants.QUALITY; + //Whether layout should create bendpoints as needed or not + this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED; + //Whether layout should be incremental or not + this.incremental = LayoutConstants.DEFAULT_INCREMENTAL; + //Whether we animate from before to after layout node positions + this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT; + //Whether we animate the layout process or not + this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT; + //Number iterations that should be done between two successive animations + this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD; + /** + * Whether or not leaf nodes (non-compound nodes) are of uniform sizes. When + * they are, both spring and repulsion forces between two leaf nodes can be + * calculated without the expensive clipping point calculations, resulting + * in major speed-up. + */ + this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES; + /** + * This is used for creation of bendpoints by using dummy nodes and edges. + * Maps an LEdge to its dummy bendpoint path. + */ + this.edgeToDummyNodes = new Map(); + this.graphManager = new LGraphManager(this); + this.isLayoutFinished = false; + this.isSubLayout = false; + this.isRemoteUse = false; + + if (isRemoteUse != null) { + this.isRemoteUse = isRemoteUse; + } +} + +Layout.RANDOM_SEED = 1; + +Layout.prototype = Object.create(Emitter.prototype); + +Layout.prototype.getGraphManager = function () { + return this.graphManager; +}; + +Layout.prototype.getAllNodes = function () { + return this.graphManager.getAllNodes(); +}; + +Layout.prototype.getAllEdges = function () { + return this.graphManager.getAllEdges(); +}; + +Layout.prototype.getAllNodesToApplyGravitation = function () { + return this.graphManager.getAllNodesToApplyGravitation(); +}; + +Layout.prototype.newGraphManager = function () { + var gm = new LGraphManager(this); + this.graphManager = gm; + return gm; +}; + +Layout.prototype.newGraph = function (vGraph) { + return new LGraph(null, this.graphManager, vGraph); +}; + +Layout.prototype.newNode = function (vNode) { + return new LNode(this.graphManager, vNode); +}; + +Layout.prototype.newEdge = function (vEdge) { + return new LEdge(null, null, vEdge); +}; + +Layout.prototype.checkLayoutSuccess = function () { + return this.graphManager.getRoot() == null || this.graphManager.getRoot().getNodes().length == 0 || this.graphManager.includesInvalidEdge(); +}; + +Layout.prototype.runLayout = function () { + this.isLayoutFinished = false; + + if (this.tilingPreLayout) { + this.tilingPreLayout(); + } + + this.initParameters(); + var isLayoutSuccessfull; + + if (this.checkLayoutSuccess()) { + isLayoutSuccessfull = false; + } else { + isLayoutSuccessfull = this.layout(); + } + + if (LayoutConstants.ANIMATE === 'during') { + // If this is a 'during' layout animation. Layout is not finished yet. + // We need to perform these in index.js when layout is really finished. + return false; + } + + if (isLayoutSuccessfull) { + if (!this.isSubLayout) { + this.doPostLayout(); + } + } + + if (this.tilingPostLayout) { + this.tilingPostLayout(); + } + + this.isLayoutFinished = true; + + return isLayoutSuccessfull; +}; + +/** + * This method performs the operations required after layout. + */ +Layout.prototype.doPostLayout = function () { + //assert !isSubLayout : "Should not be called on sub-layout!"; + // Propagate geometric changes to v-level objects + if (!this.incremental) { + this.transform(); + } + this.update(); +}; + +/** + * This method updates the geometry of the target graph according to + * calculated layout. + */ +Layout.prototype.update2 = function () { + // update bend points + if (this.createBendsAsNeeded) { + this.createBendpointsFromDummyNodes(); + + // reset all edges, since the topology has changed + this.graphManager.resetAllEdges(); + } + + // perform edge, node and root updates if layout is not called + // remotely + if (!this.isRemoteUse) { + // update all edges + var edge; + var allEdges = this.graphManager.getAllEdges(); + for (var i = 0; i < allEdges.length; i++) { + edge = allEdges[i]; + // this.update(edge); + } + + // recursively update nodes + var node; + var nodes = this.graphManager.getRoot().getNodes(); + for (var i = 0; i < nodes.length; i++) { + node = nodes[i]; + // this.update(node); + } + + // update root graph + this.update(this.graphManager.getRoot()); + } +}; + +Layout.prototype.update = function (obj) { + if (obj == null) { + this.update2(); + } else if (obj instanceof LNode) { + var node = obj; + if (node.getChild() != null) { + // since node is compound, recursively update child nodes + var nodes = node.getChild().getNodes(); + for (var i = 0; i < nodes.length; i++) { + update(nodes[i]); + } + } + + // if the l-level node is associated with a v-level graph object, + // then it is assumed that the v-level node implements the + // interface Updatable. + if (node.vGraphObject != null) { + // cast to Updatable without any type check + var vNode = node.vGraphObject; + + // call the update method of the interface + vNode.update(node); + } + } else if (obj instanceof LEdge) { + var edge = obj; + // if the l-level edge is associated with a v-level graph object, + // then it is assumed that the v-level edge implements the + // interface Updatable. + + if (edge.vGraphObject != null) { + // cast to Updatable without any type check + var vEdge = edge.vGraphObject; + + // call the update method of the interface + vEdge.update(edge); + } + } else if (obj instanceof LGraph) { + var graph = obj; + // if the l-level graph is associated with a v-level graph object, + // then it is assumed that the v-level object implements the + // interface Updatable. + + if (graph.vGraphObject != null) { + // cast to Updatable without any type check + var vGraph = graph.vGraphObject; + + // call the update method of the interface + vGraph.update(graph); + } + } +}; + +/** + * This method is used to set all layout parameters to default values + * determined at compile time. + */ +Layout.prototype.initParameters = function () { + if (!this.isSubLayout) { + this.layoutQuality = LayoutConstants.QUALITY; + this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT; + this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD; + this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT; + this.incremental = LayoutConstants.DEFAULT_INCREMENTAL; + this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED; + this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES; + } + + if (this.animationDuringLayout) { + this.animationOnLayout = false; + } +}; + +Layout.prototype.transform = function (newLeftTop) { + if (newLeftTop == undefined) { + this.transform(new PointD(0, 0)); + } else { + // create a transformation object (from Eclipse to layout). When an + // inverse transform is applied, we get upper-left coordinate of the + // drawing or the root graph at given input coordinate (some margins + // already included in calculation of left-top). + + var trans = new Transform(); + var leftTop = this.graphManager.getRoot().updateLeftTop(); + + if (leftTop != null) { + trans.setWorldOrgX(newLeftTop.x); + trans.setWorldOrgY(newLeftTop.y); + + trans.setDeviceOrgX(leftTop.x); + trans.setDeviceOrgY(leftTop.y); + + var nodes = this.getAllNodes(); + var node; + + for (var i = 0; i < nodes.length; i++) { + node = nodes[i]; + node.transform(trans); + } + } + } +}; + +Layout.prototype.positionNodesRandomly = function (graph) { + + if (graph == undefined) { + //assert !this.incremental; + this.positionNodesRandomly(this.getGraphManager().getRoot()); + this.getGraphManager().getRoot().updateBounds(true); + } else { + var lNode; + var childGraph; + + var nodes = graph.getNodes(); + for (var i = 0; i < nodes.length; i++) { + lNode = nodes[i]; + childGraph = lNode.getChild(); + + if (childGraph == null) { + lNode.scatter(); + } else if (childGraph.getNodes().length == 0) { + lNode.scatter(); + } else { + this.positionNodesRandomly(childGraph); + lNode.updateBounds(); + } + } + } +}; + +/** + * This method returns a list of trees where each tree is represented as a + * list of l-nodes. The method returns a list of size 0 when: + * - The graph is not flat or + * - One of the component(s) of the graph is not a tree. + */ +Layout.prototype.getFlatForest = function () { + var flatForest = []; + var isForest = true; + + // Quick reference for all nodes in the graph manager associated with + // this layout. The list should not be changed. + var allNodes = this.graphManager.getRoot().getNodes(); + + // First be sure that the graph is flat + var isFlat = true; + + for (var i = 0; i < allNodes.length; i++) { + if (allNodes[i].getChild() != null) { + isFlat = false; + } + } + + // Return empty forest if the graph is not flat. + if (!isFlat) { + return flatForest; + } + + // Run BFS for each component of the graph. + + var visited = new Set(); + var toBeVisited = []; + var parents = new Map(); + var unProcessedNodes = []; + + unProcessedNodes = unProcessedNodes.concat(allNodes); + + // Each iteration of this loop finds a component of the graph and + // decides whether it is a tree or not. If it is a tree, adds it to the + // forest and continued with the next component. + + while (unProcessedNodes.length > 0 && isForest) { + toBeVisited.push(unProcessedNodes[0]); + + // Start the BFS. Each iteration of this loop visits a node in a + // BFS manner. + while (toBeVisited.length > 0 && isForest) { + //pool operation + var currentNode = toBeVisited[0]; + toBeVisited.splice(0, 1); + visited.add(currentNode); + + // Traverse all neighbors of this node + var neighborEdges = currentNode.getEdges(); + + for (var i = 0; i < neighborEdges.length; i++) { + var currentNeighbor = neighborEdges[i].getOtherEnd(currentNode); + + // If BFS is not growing from this neighbor. + if (parents.get(currentNode) != currentNeighbor) { + // We haven't previously visited this neighbor. + if (!visited.has(currentNeighbor)) { + toBeVisited.push(currentNeighbor); + parents.set(currentNeighbor, currentNode); + } + // Since we have previously visited this neighbor and + // this neighbor is not parent of currentNode, given + // graph contains a component that is not tree, hence + // it is not a forest. + else { + isForest = false; + break; + } + } + } + } + + // The graph contains a component that is not a tree. Empty + // previously found trees. The method will end. + if (!isForest) { + flatForest = []; + } + // Save currently visited nodes as a tree in our forest. Reset + // visited and parents lists. Continue with the next component of + // the graph, if any. + else { + var temp = [].concat(_toConsumableArray(visited)); + flatForest.push(temp); + //flatForest = flatForest.concat(temp); + //unProcessedNodes.removeAll(visited); + for (var i = 0; i < temp.length; i++) { + var value = temp[i]; + var index = unProcessedNodes.indexOf(value); + if (index > -1) { + unProcessedNodes.splice(index, 1); + } + } + visited = new Set(); + parents = new Map(); + } + } + + return flatForest; +}; + +/** + * This method creates dummy nodes (an l-level node with minimal dimensions) + * for the given edge (one per bendpoint). The existing l-level structure + * is updated accordingly. + */ +Layout.prototype.createDummyNodesForBendpoints = function (edge) { + var dummyNodes = []; + var prev = edge.source; + + var graph = this.graphManager.calcLowestCommonAncestor(edge.source, edge.target); + + for (var i = 0; i < edge.bendpoints.length; i++) { + // create new dummy node + var dummyNode = this.newNode(null); + dummyNode.setRect(new Point(0, 0), new Dimension(1, 1)); + + graph.add(dummyNode); + + // create new dummy edge between prev and dummy node + var dummyEdge = this.newEdge(null); + this.graphManager.add(dummyEdge, prev, dummyNode); + + dummyNodes.add(dummyNode); + prev = dummyNode; + } + + var dummyEdge = this.newEdge(null); + this.graphManager.add(dummyEdge, prev, edge.target); + + this.edgeToDummyNodes.set(edge, dummyNodes); + + // remove real edge from graph manager if it is inter-graph + if (edge.isInterGraph()) { + this.graphManager.remove(edge); + } + // else, remove the edge from the current graph + else { + graph.remove(edge); + } + + return dummyNodes; +}; + +/** + * This method creates bendpoints for edges from the dummy nodes + * at l-level. + */ +Layout.prototype.createBendpointsFromDummyNodes = function () { + var edges = []; + edges = edges.concat(this.graphManager.getAllEdges()); + edges = [].concat(_toConsumableArray(this.edgeToDummyNodes.keys())).concat(edges); + + for (var k = 0; k < edges.length; k++) { + var lEdge = edges[k]; + + if (lEdge.bendpoints.length > 0) { + var path = this.edgeToDummyNodes.get(lEdge); + + for (var i = 0; i < path.length; i++) { + var dummyNode = path[i]; + var p = new PointD(dummyNode.getCenterX(), dummyNode.getCenterY()); + + // update bendpoint's location according to dummy node + var ebp = lEdge.bendpoints.get(i); + ebp.x = p.x; + ebp.y = p.y; + + // remove the dummy node, dummy edges incident with this + // dummy node is also removed (within the remove method) + dummyNode.getOwner().remove(dummyNode); + } + + // add the real edge to graph + this.graphManager.add(lEdge, lEdge.source, lEdge.target); + } + } +}; + +Layout.transform = function (sliderValue, defaultValue, minDiv, maxMul) { + if (minDiv != undefined && maxMul != undefined) { + var value = defaultValue; + + if (sliderValue <= 50) { + var minValue = defaultValue / minDiv; + value -= (defaultValue - minValue) / 50 * (50 - sliderValue); + } else { + var maxValue = defaultValue * maxMul; + value += (maxValue - defaultValue) / 50 * (sliderValue - 50); + } + + return value; + } else { + var a, b; + + if (sliderValue <= 50) { + a = 9.0 * defaultValue / 500.0; + b = defaultValue / 10.0; + } else { + a = 9.0 * defaultValue / 50.0; + b = -8 * defaultValue; + } + + return a * sliderValue + b; + } +}; + +/** + * This method finds and returns the center of the given nodes, assuming + * that the given nodes form a tree in themselves. + */ +Layout.findCenterOfTree = function (nodes) { + var list = []; + list = list.concat(nodes); + + var removedNodes = []; + var remainingDegrees = new Map(); + var foundCenter = false; + var centerNode = null; + + if (list.length == 1 || list.length == 2) { + foundCenter = true; + centerNode = list[0]; + } + + for (var i = 0; i < list.length; i++) { + var node = list[i]; + var degree = node.getNeighborsList().size; + remainingDegrees.set(node, node.getNeighborsList().size); + + if (degree == 1) { + removedNodes.push(node); + } + } + + var tempList = []; + tempList = tempList.concat(removedNodes); + + while (!foundCenter) { + var tempList2 = []; + tempList2 = tempList2.concat(tempList); + tempList = []; + + for (var i = 0; i < list.length; i++) { + var node = list[i]; + + var index = list.indexOf(node); + if (index >= 0) { + list.splice(index, 1); + } + + var neighbours = node.getNeighborsList(); + + neighbours.forEach(function (neighbour) { + if (removedNodes.indexOf(neighbour) < 0) { + var otherDegree = remainingDegrees.get(neighbour); + var newDegree = otherDegree - 1; + + if (newDegree == 1) { + tempList.push(neighbour); + } + + remainingDegrees.set(neighbour, newDegree); + } + }); + } + + removedNodes = removedNodes.concat(tempList); + + if (list.length == 1 || list.length == 2) { + foundCenter = true; + centerNode = list[0]; + } + } + + return centerNode; +}; + +/** + * During the coarsening process, this layout may be referenced by two graph managers + * this setter function grants access to change the currently being used graph manager + */ +Layout.prototype.setGraphManager = function (gm) { + this.graphManager = gm; +}; + +module.exports = Layout; + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function RandomSeed() {} +// adapted from: https://stackoverflow.com/a/19303725 +RandomSeed.seed = 1; +RandomSeed.x = 0; + +RandomSeed.nextDouble = function () { + RandomSeed.x = Math.sin(RandomSeed.seed++) * 10000; + return RandomSeed.x - Math.floor(RandomSeed.x); +}; + +module.exports = RandomSeed; + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __nested_webpack_require_81860__) { + +"use strict"; + + +var PointD = __nested_webpack_require_81860__(4); + +function Transform(x, y) { + this.lworldOrgX = 0.0; + this.lworldOrgY = 0.0; + this.ldeviceOrgX = 0.0; + this.ldeviceOrgY = 0.0; + this.lworldExtX = 1.0; + this.lworldExtY = 1.0; + this.ldeviceExtX = 1.0; + this.ldeviceExtY = 1.0; +} + +Transform.prototype.getWorldOrgX = function () { + return this.lworldOrgX; +}; + +Transform.prototype.setWorldOrgX = function (wox) { + this.lworldOrgX = wox; +}; + +Transform.prototype.getWorldOrgY = function () { + return this.lworldOrgY; +}; + +Transform.prototype.setWorldOrgY = function (woy) { + this.lworldOrgY = woy; +}; + +Transform.prototype.getWorldExtX = function () { + return this.lworldExtX; +}; + +Transform.prototype.setWorldExtX = function (wex) { + this.lworldExtX = wex; +}; + +Transform.prototype.getWorldExtY = function () { + return this.lworldExtY; +}; + +Transform.prototype.setWorldExtY = function (wey) { + this.lworldExtY = wey; +}; + +/* Device related */ + +Transform.prototype.getDeviceOrgX = function () { + return this.ldeviceOrgX; +}; + +Transform.prototype.setDeviceOrgX = function (dox) { + this.ldeviceOrgX = dox; +}; + +Transform.prototype.getDeviceOrgY = function () { + return this.ldeviceOrgY; +}; + +Transform.prototype.setDeviceOrgY = function (doy) { + this.ldeviceOrgY = doy; +}; + +Transform.prototype.getDeviceExtX = function () { + return this.ldeviceExtX; +}; + +Transform.prototype.setDeviceExtX = function (dex) { + this.ldeviceExtX = dex; +}; + +Transform.prototype.getDeviceExtY = function () { + return this.ldeviceExtY; +}; + +Transform.prototype.setDeviceExtY = function (dey) { + this.ldeviceExtY = dey; +}; + +Transform.prototype.transformX = function (x) { + var xDevice = 0.0; + var worldExtX = this.lworldExtX; + if (worldExtX != 0.0) { + xDevice = this.ldeviceOrgX + (x - this.lworldOrgX) * this.ldeviceExtX / worldExtX; + } + + return xDevice; +}; + +Transform.prototype.transformY = function (y) { + var yDevice = 0.0; + var worldExtY = this.lworldExtY; + if (worldExtY != 0.0) { + yDevice = this.ldeviceOrgY + (y - this.lworldOrgY) * this.ldeviceExtY / worldExtY; + } + + return yDevice; +}; + +Transform.prototype.inverseTransformX = function (x) { + var xWorld = 0.0; + var deviceExtX = this.ldeviceExtX; + if (deviceExtX != 0.0) { + xWorld = this.lworldOrgX + (x - this.ldeviceOrgX) * this.lworldExtX / deviceExtX; + } + + return xWorld; +}; + +Transform.prototype.inverseTransformY = function (y) { + var yWorld = 0.0; + var deviceExtY = this.ldeviceExtY; + if (deviceExtY != 0.0) { + yWorld = this.lworldOrgY + (y - this.ldeviceOrgY) * this.lworldExtY / deviceExtY; + } + return yWorld; +}; + +Transform.prototype.inverseTransformPoint = function (inPoint) { + var outPoint = new PointD(this.inverseTransformX(inPoint.x), this.inverseTransformY(inPoint.y)); + return outPoint; +}; + +module.exports = Transform; + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __nested_webpack_require_84747__) { + +"use strict"; + + +function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + +var Layout = __nested_webpack_require_84747__(15); +var FDLayoutConstants = __nested_webpack_require_84747__(7); +var LayoutConstants = __nested_webpack_require_84747__(0); +var IGeometry = __nested_webpack_require_84747__(8); +var IMath = __nested_webpack_require_84747__(9); + +function FDLayout() { + Layout.call(this); + + this.useSmartIdealEdgeLengthCalculation = FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION; + this.idealEdgeLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH; + this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH; + this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH; + this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH; + this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH; + this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR; + this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR; + this.displacementThresholdPerNode = 3.0 * FDLayoutConstants.DEFAULT_EDGE_LENGTH / 100; + this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL; + this.initialCoolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL; + this.totalDisplacement = 0.0; + this.oldTotalDisplacement = 0.0; + this.maxIterations = FDLayoutConstants.MAX_ITERATIONS; +} + +FDLayout.prototype = Object.create(Layout.prototype); + +for (var prop in Layout) { + FDLayout[prop] = Layout[prop]; +} + +FDLayout.prototype.initParameters = function () { + Layout.prototype.initParameters.call(this, arguments); + + this.totalIterations = 0; + this.notAnimatedIterations = 0; + + this.useFRGridVariant = FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION; + + this.grid = []; +}; + +FDLayout.prototype.calcIdealEdgeLengths = function () { + var edge; + var lcaDepth; + var source; + var target; + var sizeOfSourceInLca; + var sizeOfTargetInLca; + + var allEdges = this.getGraphManager().getAllEdges(); + for (var i = 0; i < allEdges.length; i++) { + edge = allEdges[i]; + + edge.idealLength = this.idealEdgeLength; + + if (edge.isInterGraph) { + source = edge.getSource(); + target = edge.getTarget(); + + sizeOfSourceInLca = edge.getSourceInLca().getEstimatedSize(); + sizeOfTargetInLca = edge.getTargetInLca().getEstimatedSize(); + + if (this.useSmartIdealEdgeLengthCalculation) { + edge.idealLength += sizeOfSourceInLca + sizeOfTargetInLca - 2 * LayoutConstants.SIMPLE_NODE_SIZE; + } + + lcaDepth = edge.getLca().getInclusionTreeDepth(); + + edge.idealLength += FDLayoutConstants.DEFAULT_EDGE_LENGTH * FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR * (source.getInclusionTreeDepth() + target.getInclusionTreeDepth() - 2 * lcaDepth); + } + } +}; + +FDLayout.prototype.initSpringEmbedder = function () { + + var s = this.getAllNodes().length; + if (this.incremental) { + if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) { + this.coolingFactor = Math.max(this.coolingFactor * FDLayoutConstants.COOLING_ADAPTATION_FACTOR, this.coolingFactor - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * this.coolingFactor * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR)); + } + this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL; + } else { + if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) { + this.coolingFactor = Math.max(FDLayoutConstants.COOLING_ADAPTATION_FACTOR, 1.0 - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR)); + } else { + this.coolingFactor = 1.0; + } + this.initialCoolingFactor = this.coolingFactor; + this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT; + } + + this.maxIterations = Math.max(this.getAllNodes().length * 5, this.maxIterations); + + this.totalDisplacementThreshold = this.displacementThresholdPerNode * this.getAllNodes().length; + + this.repulsionRange = this.calcRepulsionRange(); +}; + +FDLayout.prototype.calcSpringForces = function () { + var lEdges = this.getAllEdges(); + var edge; + + for (var i = 0; i < lEdges.length; i++) { + edge = lEdges[i]; + + this.calcSpringForce(edge, edge.idealLength); + } +}; + +FDLayout.prototype.calcRepulsionForces = function () { + var gridUpdateAllowed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var forceToNodeSurroundingUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var i, j; + var nodeA, nodeB; + var lNodes = this.getAllNodes(); + var processedNodeSet; + + if (this.useFRGridVariant) { + if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed) { + this.updateGrid(); + } + + processedNodeSet = new Set(); + + // calculate repulsion forces between each nodes and its surrounding + for (i = 0; i < lNodes.length; i++) { + nodeA = lNodes[i]; + this.calculateRepulsionForceOfANode(nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate); + processedNodeSet.add(nodeA); + } + } else { + for (i = 0; i < lNodes.length; i++) { + nodeA = lNodes[i]; + + for (j = i + 1; j < lNodes.length; j++) { + nodeB = lNodes[j]; + + // If both nodes are not members of the same graph, skip. + if (nodeA.getOwner() != nodeB.getOwner()) { + continue; + } + + this.calcRepulsionForce(nodeA, nodeB); + } + } + } +}; + +FDLayout.prototype.calcGravitationalForces = function () { + var node; + var lNodes = this.getAllNodesToApplyGravitation(); + + for (var i = 0; i < lNodes.length; i++) { + node = lNodes[i]; + this.calcGravitationalForce(node); + } +}; + +FDLayout.prototype.moveNodes = function () { + var lNodes = this.getAllNodes(); + var node; + + for (var i = 0; i < lNodes.length; i++) { + node = lNodes[i]; + node.move(); + } +}; + +FDLayout.prototype.calcSpringForce = function (edge, idealLength) { + var sourceNode = edge.getSource(); + var targetNode = edge.getTarget(); + + var length; + var springForce; + var springForceX; + var springForceY; + + // Update edge length + if (this.uniformLeafNodeSizes && sourceNode.getChild() == null && targetNode.getChild() == null) { + edge.updateLengthSimple(); + } else { + edge.updateLength(); + + if (edge.isOverlapingSourceAndTarget) { + return; + } + } + + length = edge.getLength(); + + if (length == 0) return; + + // Calculate spring forces + springForce = this.springConstant * (length - idealLength); + + // Project force onto x and y axes + springForceX = springForce * (edge.lengthX / length); + springForceY = springForce * (edge.lengthY / length); + + // Apply forces on the end nodes + sourceNode.springForceX += springForceX; + sourceNode.springForceY += springForceY; + targetNode.springForceX -= springForceX; + targetNode.springForceY -= springForceY; +}; + +FDLayout.prototype.calcRepulsionForce = function (nodeA, nodeB) { + var rectA = nodeA.getRect(); + var rectB = nodeB.getRect(); + var overlapAmount = new Array(2); + var clipPoints = new Array(4); + var distanceX; + var distanceY; + var distanceSquared; + var distance; + var repulsionForce; + var repulsionForceX; + var repulsionForceY; + + if (rectA.intersects(rectB)) // two nodes overlap + { + // calculate separation amount in x and y directions + IGeometry.calcSeparationAmount(rectA, rectB, overlapAmount, FDLayoutConstants.DEFAULT_EDGE_LENGTH / 2.0); + + repulsionForceX = 2 * overlapAmount[0]; + repulsionForceY = 2 * overlapAmount[1]; + + var childrenConstant = nodeA.noOfChildren * nodeB.noOfChildren / (nodeA.noOfChildren + nodeB.noOfChildren); + + // Apply forces on the two nodes + nodeA.repulsionForceX -= childrenConstant * repulsionForceX; + nodeA.repulsionForceY -= childrenConstant * repulsionForceY; + nodeB.repulsionForceX += childrenConstant * repulsionForceX; + nodeB.repulsionForceY += childrenConstant * repulsionForceY; + } else // no overlap + { + // calculate distance + + if (this.uniformLeafNodeSizes && nodeA.getChild() == null && nodeB.getChild() == null) // simply base repulsion on distance of node centers + { + distanceX = rectB.getCenterX() - rectA.getCenterX(); + distanceY = rectB.getCenterY() - rectA.getCenterY(); + } else // use clipping points + { + IGeometry.getIntersection(rectA, rectB, clipPoints); + + distanceX = clipPoints[2] - clipPoints[0]; + distanceY = clipPoints[3] - clipPoints[1]; + } + + // No repulsion range. FR grid variant should take care of this. + if (Math.abs(distanceX) < FDLayoutConstants.MIN_REPULSION_DIST) { + distanceX = IMath.sign(distanceX) * FDLayoutConstants.MIN_REPULSION_DIST; + } + + if (Math.abs(distanceY) < FDLayoutConstants.MIN_REPULSION_DIST) { + distanceY = IMath.sign(distanceY) * FDLayoutConstants.MIN_REPULSION_DIST; + } + + distanceSquared = distanceX * distanceX + distanceY * distanceY; + distance = Math.sqrt(distanceSquared); + + repulsionForce = this.repulsionConstant * nodeA.noOfChildren * nodeB.noOfChildren / distanceSquared; + + // Project force onto x and y axes + repulsionForceX = repulsionForce * distanceX / distance; + repulsionForceY = repulsionForce * distanceY / distance; + + // Apply forces on the two nodes + nodeA.repulsionForceX -= repulsionForceX; + nodeA.repulsionForceY -= repulsionForceY; + nodeB.repulsionForceX += repulsionForceX; + nodeB.repulsionForceY += repulsionForceY; + } +}; + +FDLayout.prototype.calcGravitationalForce = function (node) { + var ownerGraph; + var ownerCenterX; + var ownerCenterY; + var distanceX; + var distanceY; + var absDistanceX; + var absDistanceY; + var estimatedSize; + ownerGraph = node.getOwner(); + + ownerCenterX = (ownerGraph.getRight() + ownerGraph.getLeft()) / 2; + ownerCenterY = (ownerGraph.getTop() + ownerGraph.getBottom()) / 2; + distanceX = node.getCenterX() - ownerCenterX; + distanceY = node.getCenterY() - ownerCenterY; + absDistanceX = Math.abs(distanceX) + node.getWidth() / 2; + absDistanceY = Math.abs(distanceY) + node.getHeight() / 2; + + if (node.getOwner() == this.graphManager.getRoot()) // in the root graph + { + estimatedSize = ownerGraph.getEstimatedSize() * this.gravityRangeFactor; + + if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) { + node.gravitationForceX = -this.gravityConstant * distanceX; + node.gravitationForceY = -this.gravityConstant * distanceY; + } + } else // inside a compound + { + estimatedSize = ownerGraph.getEstimatedSize() * this.compoundGravityRangeFactor; + + if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) { + node.gravitationForceX = -this.gravityConstant * distanceX * this.compoundGravityConstant; + node.gravitationForceY = -this.gravityConstant * distanceY * this.compoundGravityConstant; + } + } +}; + +FDLayout.prototype.isConverged = function () { + var converged; + var oscilating = false; + + if (this.totalIterations > this.maxIterations / 3) { + oscilating = Math.abs(this.totalDisplacement - this.oldTotalDisplacement) < 2; + } + + converged = this.totalDisplacement < this.totalDisplacementThreshold; + + this.oldTotalDisplacement = this.totalDisplacement; + + return converged || oscilating; +}; + +FDLayout.prototype.animate = function () { + if (this.animationDuringLayout && !this.isSubLayout) { + if (this.notAnimatedIterations == this.animationPeriod) { + this.update(); + this.notAnimatedIterations = 0; + } else { + this.notAnimatedIterations++; + } + } +}; + +//This method calculates the number of children (weight) for all nodes +FDLayout.prototype.calcNoOfChildrenForAllNodes = function () { + var node; + var allNodes = this.graphManager.getAllNodes(); + + for (var i = 0; i < allNodes.length; i++) { + node = allNodes[i]; + node.noOfChildren = node.getNoOfChildren(); + } +}; + +// ----------------------------------------------------------------------------- +// Section: FR-Grid Variant Repulsion Force Calculation +// ----------------------------------------------------------------------------- + +FDLayout.prototype.calcGrid = function (graph) { + + var sizeX = 0; + var sizeY = 0; + + sizeX = parseInt(Math.ceil((graph.getRight() - graph.getLeft()) / this.repulsionRange)); + sizeY = parseInt(Math.ceil((graph.getBottom() - graph.getTop()) / this.repulsionRange)); + + var grid = new Array(sizeX); + + for (var i = 0; i < sizeX; i++) { + grid[i] = new Array(sizeY); + } + + for (var i = 0; i < sizeX; i++) { + for (var j = 0; j < sizeY; j++) { + grid[i][j] = new Array(); + } + } + + return grid; +}; + +FDLayout.prototype.addNodeToGrid = function (v, left, top) { + + var startX = 0; + var finishX = 0; + var startY = 0; + var finishY = 0; + + startX = parseInt(Math.floor((v.getRect().x - left) / this.repulsionRange)); + finishX = parseInt(Math.floor((v.getRect().width + v.getRect().x - left) / this.repulsionRange)); + startY = parseInt(Math.floor((v.getRect().y - top) / this.repulsionRange)); + finishY = parseInt(Math.floor((v.getRect().height + v.getRect().y - top) / this.repulsionRange)); + + for (var i = startX; i <= finishX; i++) { + for (var j = startY; j <= finishY; j++) { + this.grid[i][j].push(v); + v.setGridCoordinates(startX, finishX, startY, finishY); + } + } +}; + +FDLayout.prototype.updateGrid = function () { + var i; + var nodeA; + var lNodes = this.getAllNodes(); + + this.grid = this.calcGrid(this.graphManager.getRoot()); + + // put all nodes to proper grid cells + for (i = 0; i < lNodes.length; i++) { + nodeA = lNodes[i]; + this.addNodeToGrid(nodeA, this.graphManager.getRoot().getLeft(), this.graphManager.getRoot().getTop()); + } +}; + +FDLayout.prototype.calculateRepulsionForceOfANode = function (nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate) { + + if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed || forceToNodeSurroundingUpdate) { + var surrounding = new Set(); + nodeA.surrounding = new Array(); + var nodeB; + var grid = this.grid; + + for (var i = nodeA.startX - 1; i < nodeA.finishX + 2; i++) { + for (var j = nodeA.startY - 1; j < nodeA.finishY + 2; j++) { + if (!(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)) { + for (var k = 0; k < grid[i][j].length; k++) { + nodeB = grid[i][j][k]; + + // If both nodes are not members of the same graph, + // or both nodes are the same, skip. + if (nodeA.getOwner() != nodeB.getOwner() || nodeA == nodeB) { + continue; + } + + // check if the repulsion force between + // nodeA and nodeB has already been calculated + if (!processedNodeSet.has(nodeB) && !surrounding.has(nodeB)) { + var distanceX = Math.abs(nodeA.getCenterX() - nodeB.getCenterX()) - (nodeA.getWidth() / 2 + nodeB.getWidth() / 2); + var distanceY = Math.abs(nodeA.getCenterY() - nodeB.getCenterY()) - (nodeA.getHeight() / 2 + nodeB.getHeight() / 2); + + // if the distance between nodeA and nodeB + // is less then calculation range + if (distanceX <= this.repulsionRange && distanceY <= this.repulsionRange) { + //then add nodeB to surrounding of nodeA + surrounding.add(nodeB); + } + } + } + } + } + } + + nodeA.surrounding = [].concat(_toConsumableArray(surrounding)); + } + for (i = 0; i < nodeA.surrounding.length; i++) { + this.calcRepulsionForce(nodeA, nodeA.surrounding[i]); + } +}; + +FDLayout.prototype.calcRepulsionRange = function () { + return 0.0; +}; + +module.exports = FDLayout; + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __nested_webpack_require_100902__) { + +"use strict"; + + +var LEdge = __nested_webpack_require_100902__(1); +var FDLayoutConstants = __nested_webpack_require_100902__(7); + +function FDLayoutEdge(source, target, vEdge) { + LEdge.call(this, source, target, vEdge); + this.idealLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH; +} + +FDLayoutEdge.prototype = Object.create(LEdge.prototype); + +for (var prop in LEdge) { + FDLayoutEdge[prop] = LEdge[prop]; +} + +module.exports = FDLayoutEdge; + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __nested_webpack_require_101387__) { + +"use strict"; + + +var LNode = __nested_webpack_require_101387__(3); + +function FDLayoutNode(gm, loc, size, vNode) { + // alternative constructor is handled inside LNode + LNode.call(this, gm, loc, size, vNode); + //Spring, repulsion and gravitational forces acting on this node + this.springForceX = 0; + this.springForceY = 0; + this.repulsionForceX = 0; + this.repulsionForceY = 0; + this.gravitationForceX = 0; + this.gravitationForceY = 0; + //Amount by which this node is to be moved in this iteration + this.displacementX = 0; + this.displacementY = 0; + + //Start and finish grid coordinates that this node is fallen into + this.startX = 0; + this.finishX = 0; + this.startY = 0; + this.finishY = 0; + + //Geometric neighbors of this node + this.surrounding = []; +} + +FDLayoutNode.prototype = Object.create(LNode.prototype); + +for (var prop in LNode) { + FDLayoutNode[prop] = LNode[prop]; +} + +FDLayoutNode.prototype.setGridCoordinates = function (_startX, _finishX, _startY, _finishY) { + this.startX = _startX; + this.finishX = _finishX; + this.startY = _startY; + this.finishY = _finishY; +}; + +module.exports = FDLayoutNode; + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function DimensionD(width, height) { + this.width = 0; + this.height = 0; + if (width !== null && height !== null) { + this.height = height; + this.width = width; + } +} + +DimensionD.prototype.getWidth = function () { + return this.width; +}; + +DimensionD.prototype.setWidth = function (width) { + this.width = width; +}; + +DimensionD.prototype.getHeight = function () { + return this.height; +}; + +DimensionD.prototype.setHeight = function (height) { + this.height = height; +}; + +module.exports = DimensionD; + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __nested_webpack_require_103173__) { + +"use strict"; + + +var UniqueIDGeneretor = __nested_webpack_require_103173__(14); + +function HashMap() { + this.map = {}; + this.keys = []; +} + +HashMap.prototype.put = function (key, value) { + var theId = UniqueIDGeneretor.createID(key); + if (!this.contains(theId)) { + this.map[theId] = value; + this.keys.push(key); + } +}; + +HashMap.prototype.contains = function (key) { + var theId = UniqueIDGeneretor.createID(key); + return this.map[key] != null; +}; + +HashMap.prototype.get = function (key) { + var theId = UniqueIDGeneretor.createID(key); + return this.map[theId]; +}; + +HashMap.prototype.keySet = function () { + return this.keys; +}; + +module.exports = HashMap; + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __nested_webpack_require_103901__) { + +"use strict"; + + +var UniqueIDGeneretor = __nested_webpack_require_103901__(14); + +function HashSet() { + this.set = {}; +} +; + +HashSet.prototype.add = function (obj) { + var theId = UniqueIDGeneretor.createID(obj); + if (!this.contains(theId)) this.set[theId] = obj; +}; + +HashSet.prototype.remove = function (obj) { + delete this.set[UniqueIDGeneretor.createID(obj)]; +}; + +HashSet.prototype.clear = function () { + this.set = {}; +}; + +HashSet.prototype.contains = function (obj) { + return this.set[UniqueIDGeneretor.createID(obj)] == obj; +}; + +HashSet.prototype.isEmpty = function () { + return this.size() === 0; +}; + +HashSet.prototype.size = function () { + return Object.keys(this.set).length; +}; + +//concats this.set to the given list +HashSet.prototype.addAllTo = function (list) { + var keys = Object.keys(this.set); + var length = keys.length; + for (var i = 0; i < length; i++) { + list.push(this.set[keys[i]]); + } +}; + +HashSet.prototype.size = function () { + return Object.keys(this.set).length; +}; + +HashSet.prototype.addAll = function (list) { + var s = list.length; + for (var i = 0; i < s; i++) { + var v = list[i]; + this.add(v); + } +}; + +module.exports = HashSet; + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __nested_webpack_require_105138__) { + +"use strict"; + + +var _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * A classic Quicksort algorithm with Hoare's partition + * - Works also on LinkedList objects + * + * Copyright: i-Vis Research Group, Bilkent University, 2007 - present + */ + +var LinkedList = __nested_webpack_require_105138__(11); + +var Quicksort = function () { + function Quicksort(A, compareFunction) { + _classCallCheck(this, Quicksort); + + if (compareFunction !== null || compareFunction !== undefined) this.compareFunction = this._defaultCompareFunction; + + var length = void 0; + if (A instanceof LinkedList) length = A.size();else length = A.length; + + this._quicksort(A, 0, length - 1); + } + + _createClass(Quicksort, [{ + key: '_quicksort', + value: function _quicksort(A, p, r) { + if (p < r) { + var q = this._partition(A, p, r); + this._quicksort(A, p, q); + this._quicksort(A, q + 1, r); + } + } + }, { + key: '_partition', + value: function _partition(A, p, r) { + var x = this._get(A, p); + var i = p; + var j = r; + while (true) { + while (this.compareFunction(x, this._get(A, j))) { + j--; + }while (this.compareFunction(this._get(A, i), x)) { + i++; + }if (i < j) { + this._swap(A, i, j); + i++; + j--; + } else return j; + } + } + }, { + key: '_get', + value: function _get(object, index) { + if (object instanceof LinkedList) return object.get_object_at(index);else return object[index]; + } + }, { + key: '_set', + value: function _set(object, index, value) { + if (object instanceof LinkedList) object.set_object_at(index, value);else object[index] = value; + } + }, { + key: '_swap', + value: function _swap(A, i, j) { + var temp = this._get(A, i); + this._set(A, i, this._get(A, j)); + this._set(A, j, temp); + } + }, { + key: '_defaultCompareFunction', + value: function _defaultCompareFunction(a, b) { + return b > a; + } + }]); + + return Quicksort; +}(); + +module.exports = Quicksort; + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +var _createClass = function () { function 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +/** + * Needleman-Wunsch algorithm is an procedure to compute the optimal global alignment of two string + * sequences by S.B.Needleman and C.D.Wunsch (1970). + * + * Aside from the inputs, you can assign the scores for, + * - Match: The two characters at the current index are same. + * - Mismatch: The two characters at the current index are different. + * - Insertion/Deletion(gaps): The best alignment involves one letter aligning to a gap in the other string. + */ + +var NeedlemanWunsch = function () { + function NeedlemanWunsch(sequence1, sequence2) { + var match_score = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1; + var mismatch_penalty = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1; + var gap_penalty = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1; + + _classCallCheck(this, NeedlemanWunsch); + + this.sequence1 = sequence1; + this.sequence2 = sequence2; + this.match_score = match_score; + this.mismatch_penalty = mismatch_penalty; + this.gap_penalty = gap_penalty; + + // Just the remove redundancy + this.iMax = sequence1.length + 1; + this.jMax = sequence2.length + 1; + + // Grid matrix of scores + this.grid = new Array(this.iMax); + for (var i = 0; i < this.iMax; i++) { + this.grid[i] = new Array(this.jMax); + + for (var j = 0; j < this.jMax; j++) { + this.grid[i][j] = 0; + } + } + + // Traceback matrix (2D array, each cell is an array of boolean values for [`Diag`, `Up`, `Left`] positions) + this.tracebackGrid = new Array(this.iMax); + for (var _i = 0; _i < this.iMax; _i++) { + this.tracebackGrid[_i] = new Array(this.jMax); + + for (var _j = 0; _j < this.jMax; _j++) { + this.tracebackGrid[_i][_j] = [null, null, null]; + } + } + + // The aligned sequences (return multiple possibilities) + this.alignments = []; + + // Final alignment score + this.score = -1; + + // Calculate scores and tracebacks + this.computeGrids(); + } + + _createClass(NeedlemanWunsch, [{ + key: "getScore", + value: function getScore() { + return this.score; + } + }, { + key: "getAlignments", + value: function getAlignments() { + return this.alignments; + } + + // Main dynamic programming procedure + + }, { + key: "computeGrids", + value: function computeGrids() { + // Fill in the first row + for (var j = 1; j < this.jMax; j++) { + this.grid[0][j] = this.grid[0][j - 1] + this.gap_penalty; + this.tracebackGrid[0][j] = [false, false, true]; + } + + // Fill in the first column + for (var i = 1; i < this.iMax; i++) { + this.grid[i][0] = this.grid[i - 1][0] + this.gap_penalty; + this.tracebackGrid[i][0] = [false, true, false]; + } + + // Fill the rest of the grid + for (var _i2 = 1; _i2 < this.iMax; _i2++) { + for (var _j2 = 1; _j2 < this.jMax; _j2++) { + // Find the max score(s) among [`Diag`, `Up`, `Left`] + var diag = void 0; + if (this.sequence1[_i2 - 1] === this.sequence2[_j2 - 1]) diag = this.grid[_i2 - 1][_j2 - 1] + this.match_score;else diag = this.grid[_i2 - 1][_j2 - 1] + this.mismatch_penalty; + + var up = this.grid[_i2 - 1][_j2] + this.gap_penalty; + var left = this.grid[_i2][_j2 - 1] + this.gap_penalty; + + // If there exists multiple max values, capture them for multiple paths + var maxOf = [diag, up, left]; + var indices = this.arrayAllMaxIndexes(maxOf); + + // Update Grids + this.grid[_i2][_j2] = maxOf[indices[0]]; + this.tracebackGrid[_i2][_j2] = [indices.includes(0), indices.includes(1), indices.includes(2)]; + } + } + + // Update alignment score + this.score = this.grid[this.iMax - 1][this.jMax - 1]; + } + + // Gets all possible valid sequence combinations + + }, { + key: "alignmentTraceback", + value: function alignmentTraceback() { + var inProcessAlignments = []; + + inProcessAlignments.push({ pos: [this.sequence1.length, this.sequence2.length], + seq1: "", + seq2: "" + }); + + while (inProcessAlignments[0]) { + var current = inProcessAlignments[0]; + var directions = this.tracebackGrid[current.pos[0]][current.pos[1]]; + + if (directions[0]) { + inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1] - 1], + seq1: this.sequence1[current.pos[0] - 1] + current.seq1, + seq2: this.sequence2[current.pos[1] - 1] + current.seq2 + }); + } + if (directions[1]) { + inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1]], + seq1: this.sequence1[current.pos[0] - 1] + current.seq1, + seq2: '-' + current.seq2 + }); + } + if (directions[2]) { + inProcessAlignments.push({ pos: [current.pos[0], current.pos[1] - 1], + seq1: '-' + current.seq1, + seq2: this.sequence2[current.pos[1] - 1] + current.seq2 + }); + } + + if (current.pos[0] === 0 && current.pos[1] === 0) this.alignments.push({ sequence1: current.seq1, + sequence2: current.seq2 + }); + + inProcessAlignments.shift(); + } + + return this.alignments; + } + + // Helper Functions + + }, { + key: "getAllIndexes", + value: function getAllIndexes(arr, val) { + var indexes = [], + i = -1; + while ((i = arr.indexOf(val, i + 1)) !== -1) { + indexes.push(i); + } + return indexes; + } + }, { + key: "arrayAllMaxIndexes", + value: function arrayAllMaxIndexes(array) { + return this.getAllIndexes(array, Math.max.apply(null, array)); + } + }]); + + return NeedlemanWunsch; +}(); + +module.exports = NeedlemanWunsch; + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __nested_webpack_require_115611__) { + +"use strict"; + + +var layoutBase = function layoutBase() { + return; +}; + +layoutBase.FDLayout = __nested_webpack_require_115611__(18); +layoutBase.FDLayoutConstants = __nested_webpack_require_115611__(7); +layoutBase.FDLayoutEdge = __nested_webpack_require_115611__(19); +layoutBase.FDLayoutNode = __nested_webpack_require_115611__(20); +layoutBase.DimensionD = __nested_webpack_require_115611__(21); +layoutBase.HashMap = __nested_webpack_require_115611__(22); +layoutBase.HashSet = __nested_webpack_require_115611__(23); +layoutBase.IGeometry = __nested_webpack_require_115611__(8); +layoutBase.IMath = __nested_webpack_require_115611__(9); +layoutBase.Integer = __nested_webpack_require_115611__(10); +layoutBase.Point = __nested_webpack_require_115611__(12); +layoutBase.PointD = __nested_webpack_require_115611__(4); +layoutBase.RandomSeed = __nested_webpack_require_115611__(16); +layoutBase.RectangleD = __nested_webpack_require_115611__(13); +layoutBase.Transform = __nested_webpack_require_115611__(17); +layoutBase.UniqueIDGeneretor = __nested_webpack_require_115611__(14); +layoutBase.Quicksort = __nested_webpack_require_115611__(24); +layoutBase.LinkedList = __nested_webpack_require_115611__(11); +layoutBase.LGraphObject = __nested_webpack_require_115611__(2); +layoutBase.LGraph = __nested_webpack_require_115611__(5); +layoutBase.LEdge = __nested_webpack_require_115611__(1); +layoutBase.LGraphManager = __nested_webpack_require_115611__(6); +layoutBase.LNode = __nested_webpack_require_115611__(3); +layoutBase.Layout = __nested_webpack_require_115611__(15); +layoutBase.LayoutConstants = __nested_webpack_require_115611__(0); +layoutBase.NeedlemanWunsch = __nested_webpack_require_115611__(25); + +module.exports = layoutBase; + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function Emitter() { + this.listeners = []; +} + +var p = Emitter.prototype; + +p.addListener = function (event, callback) { + this.listeners.push({ + event: event, + callback: callback + }); +}; + +p.removeListener = function (event, callback) { + for (var i = this.listeners.length; i >= 0; i--) { + var l = this.listeners[i]; + + if (l.event === event && l.callback === callback) { + this.listeners.splice(i, 1); + } + } +}; + +p.emit = function (event, data) { + for (var i = 0; i < this.listeners.length; i++) { + var l = this.listeners[i]; + + if (event === l.event) { + l.callback(data); + } + } +}; + +module.exports = Emitter; + +/***/ }) +/******/ ]); +}); + +/***/ }), + +/***/ 64589: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + a: () => (/* binding */ createText), + c: () => (/* binding */ computeDimensionOfText) +}); + +// NAMESPACE OBJECT: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +var constructs_namespaceObject = {}; +__webpack_require__.r(constructs_namespaceObject); +__webpack_require__.d(constructs_namespaceObject, { + attentionMarkers: () => (attentionMarkers), + contentInitial: () => (contentInitial), + disable: () => (disable), + document: () => (constructs_document), + flow: () => (constructs_flow), + flowInitial: () => (flowInitial), + insideSpan: () => (insideSpan), + string: () => (constructs_string), + text: () => (constructs_text) +}); + +// EXTERNAL MODULE: ./node_modules/mermaid/dist/mermaid-8af3addd.js + 8 modules +var mermaid_8af3addd = __webpack_require__(56363); +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-to-string/lib/index.js +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * + * @typedef Options + * Configuration (optional). + * @property {boolean | null | undefined} [includeImageAlt=true] + * Whether to use `alt` for `image`s. + * @property {boolean | null | undefined} [includeHtml=true] + * Whether to use `value` of HTML. + */ + +/** @type {Options} */ +const emptyOptions = {} + +/** + * Get the text content of a node or list of nodes. + * + * Prefers the node’s plain-text fields, otherwise serializes its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} value + * Thing to serialize, typically `Node`. + * @param {Options | null | undefined} [options] + * Configuration (optional). + * @returns {string} + * Serialized `value`. + */ +function lib_toString(value, options) { + const settings = options || emptyOptions + const includeImageAlt = + typeof settings.includeImageAlt === 'boolean' + ? settings.includeImageAlt + : true + const includeHtml = + typeof settings.includeHtml === 'boolean' ? settings.includeHtml : true + + return one(value, includeImageAlt, includeHtml) +} + +/** + * One node or several nodes. + * + * @param {unknown} value + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized node. + */ +function one(value, includeImageAlt, includeHtml) { + if (node(value)) { + if ('value' in value) { + return value.type === 'html' && !includeHtml ? '' : value.value + } + + if (includeImageAlt && 'alt' in value && value.alt) { + return value.alt + } + + if ('children' in value) { + return lib_all(value.children, includeImageAlt, includeHtml) + } + } + + if (Array.isArray(value)) { + return lib_all(value, includeImageAlt, includeHtml) + } + + return '' +} + +/** + * Serialize a list of nodes. + * + * @param {Array<unknown>} values + * Thing to serialize. + * @param {boolean} includeImageAlt + * Include image `alt`s. + * @param {boolean} includeHtml + * Include HTML. + * @returns {string} + * Serialized nodes. + */ +function lib_all(values, includeImageAlt, includeHtml) { + /** @type {Array<string>} */ + const result = [] + let index = -1 + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt, includeHtml) + } + + return result.join('') +} + +/** + * Check if `value` looks like a node. + * + * @param {unknown} value + * Thing. + * @returns {value is Node} + * Whether `value` is a node. + */ +function node(value) { + return Boolean(value && typeof value === 'object') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-combine-extensions/index.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Handles} Handles + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + */ + + + +const micromark_util_combine_extensions_hasOwnProperty = {}.hasOwnProperty + +/** + * Combine multiple syntax extensions into one. + * + * @param {Array<Extension>} extensions + * List of syntax extensions. + * @returns {NormalizedExtension} + * A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {} + let index = -1 + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]) + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all + * Extension to merge into. + * @param {Extension} extension + * Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {keyof Extension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + /** @type {Record<string, unknown>} */ + const left = maybe || (all[hook] = {}) + /** @type {Record<string, unknown> | undefined} */ + const right = extension[hook] + /** @type {string} */ + let code + + if (right) { + for (code in right) { + if (!micromark_util_combine_extensions_hasOwnProperty.call(left, code)) left[code] = [] + const value = right[code] + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ) + } + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {Array<unknown>} existing + * @param {Array<unknown>} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1 + /** @type {Array<unknown>} */ + const before = [] + + while (++index < list.length) { + // @ts-expect-error Looks like an object. + ;(list[index].add === 'after' ? existing : before).push(list[index]) + } + + splice(existing, 0, 0, before) +} + +/** + * Combine multiple HTML extensions into one. + * + * @param {Array<HtmlExtension>} htmlExtensions + * List of HTML extensions. + * @returns {HtmlExtension} + * A single combined HTML extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {} + let index = -1 + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]) + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all + * Extension to merge into. + * @param {HtmlExtension} extension + * Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {keyof HtmlExtension} */ + let hook + + for (hook in extension) { + const maybe = micromark_util_combine_extensions_hasOwnProperty.call(all, hook) ? all[hook] : undefined + const left = maybe || (all[hook] = {}) + const right = extension[hook] + /** @type {keyof Handles} */ + let type + + if (right) { + for (type in right) { + // @ts-expect-error assume document vs regular handler are managed correctly. + left[type] = right[type] + } + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/lib/unicode-punctuation-regex.js +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. + +/** + * Regular expression that matches a unicode punctuation character. + */ +const unicodePunctuationRegex = + /[!-\/:-@\[-`\{-~\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/ + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + + +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlpha = regexCheck(/[A-Za-z]/) + +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/) + +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/) + +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} + +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiDigit = regexCheck(/\d/) + +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/) + +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/) + +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEnding(code) { + return code !== null && code < -2 +} + +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} + +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * Code. + * @returns {boolean} + * Whether it matches. + */ +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} + +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodePunctuation = regexCheck(unicodePunctuationRegex) + +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + * + * @param code + * Code. + * @returns + * Whether it matches. + */ +const unicodeWhitespace = regexCheck(/\s/) + +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => boolean} + */ +function regexCheck(regex) { + return check + + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code + * Character code. + * @returns {boolean} + * Whether the character code matches the bound regex. + */ + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-space/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +// To do: implement `spaceOrTab`, `spaceOrTabMinMax`, `spaceOrTabWithOptions`. + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * spaces in markdown are often optional, in which case this factory can be + * used and `ok` will be switched to whether spaces were found or not + * * one line ending or space can be detected with `markdownSpace(code)` right + * before using `factorySpace` + * + * ###### Examples + * + * Where `␉` represents a tab (plus how much it expands) and `␠` represents a + * single space. + * + * ```markdown + * ␉ + * ␠␠␠␠ + * ␉␠ + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {TokenType} type + * Type (`' \t'`). + * @param {number | undefined} [max=Infinity] + * Max (exclusive). + * @returns + * Start state. + */ +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY + let size = 0 + return start + + /** @type {State} */ + function start(code) { + if (markdownSpace(code)) { + effects.enter(type) + return prefix(code) + } + return ok(code) + } + + /** @type {State} */ + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code) + return prefix + } + effects.exit(type) + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/content.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + +/** @type {InitialConstruct} */ +const content = { + tokenize: initializeContent +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ) + /** @type {Token} */ + let previous + return contentStart + + /** @type {State} */ + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, contentStart, 'linePrefix') + } + + /** @type {State} */ + function paragraphInitial(code) { + effects.enter('paragraph') + return lineStart(code) + } + + /** @type {State} */ + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }) + if (previous) { + previous.next = token + } + previous = token + return data(code) + } + + /** @type {State} */ + function data(code) { + if (code === null) { + effects.exit('chunkText') + effects.exit('paragraph') + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + effects.exit('chunkText') + return lineStart + } + + // Data. + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/document.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + +/** + * @typedef {[Construct, ContainerState]} StackItem + */ + + + + +/** @type {InitialConstruct} */ +const document_document = { + tokenize: initializeDocument +} + +/** @type {Construct} */ +const containerConstruct = { + tokenize: tokenizeContainer +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeDocument(effects) { + const self = this + /** @type {Array<StackItem>} */ + const stack = [] + let continued = 0 + /** @type {TokenizeContext | undefined} */ + let childFlow + /** @type {Token | undefined} */ + let childToken + /** @type {number} */ + let lineStartOffset + return start + + /** @type {State} */ + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued] + self.containerState = item[1] + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } + + // Done. + return checkNewContainers(code) + } + + /** @type {State} */ + function documentContinue(code) { + continued++ + + // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined + if (childFlow) { + closeFlow() + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {Point | undefined} */ + let point + + // Find the flow chunk. + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end + break + } + } + exitContainers(continued) + + // Fix positions. + let index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + return checkNewContainers(code) + } + return start(code) + } + + /** @type {State} */ + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } + + // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } + + // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + // To do: next major: remove `_gfmTableDynamicInterruptHack` (no longer + // needed in micromark-extension-gfm-table@1.0.6). + self.interrupt = Boolean( + childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack + ) + } + + // Check if there is a new container. + self.containerState = {} + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + + /** @type {State} */ + function thereIsANewContainer(code) { + if (childFlow) closeFlow() + exitContainers(continued) + return documentContinued(code) + } + + /** @type {State} */ + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length + lineStartOffset = self.now().offset + return flowStart(code) + } + + /** @type {State} */ + function documentContinued(code) { + // Try new containers. + self.containerState = {} + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + + /** @type {State} */ + function containerContinue(code) { + continued++ + stack.push([self.currentConstruct, self.containerState]) + // Try another. + return documentContinued(code) + } + + /** @type {State} */ + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow() + exitContainers(0) + effects.consume(code) + return + } + childFlow = childFlow || self.parser.flow(self.now()) + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }) + return flowContinue(code) + } + + /** @type {State} */ + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true) + exitContainers(0) + effects.consume(code) + return + } + if (markdownLineEnding(code)) { + effects.consume(code) + writeToChild(effects.exit('chunkFlow')) + // Get ready for the next line. + continued = 0 + self.interrupt = undefined + return start + } + effects.consume(code) + return flowContinue + } + + /** + * @param {Token} token + * @param {boolean | undefined} [eof] + * @returns {void} + */ + function writeToChild(token, eof) { + const stream = self.sliceStream(token) + if (eof) stream.push(null) + token.previous = childToken + if (childToken) childToken.next = token + childToken = token + childFlow.defineSkip(token.start) + childFlow.write(stream) + + // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + // …and either is not ended yet… + (!childFlow.events[index][1].end || + // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } + + // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + const indexBeforeExits = self.events.length + let indexBeforeFlow = indexBeforeExits + /** @type {boolean | undefined} */ + let seen + /** @type {Point | undefined} */ + let point + + // Find the previous chunk (the one before the lazy line). + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end + break + } + seen = true + } + } + exitContainers(continued) + + // Fix positions. + index = indexBeforeExits + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point) + index++ + } + + // Inject the exits earlier (they’re still also at the end). + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ) + + // Discard the duplicate exits. + self.events.length = index + } + } + + /** + * @param {number} size + * @returns {void} + */ + function exitContainers(size) { + let index = stack.length + + // Exit open containers. + while (index-- > size) { + const entry = stack[index] + self.containerState = entry[1] + entry[0].exit.call(self, effects) + } + stack.length = size + } + function closeFlow() { + childFlow.write([null]) + childToken = undefined + childFlow = undefined + self.containerState._closeFlow = undefined + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContainer(effects, ok, nok) { + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/blank-line.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLine(effects, ok, nok) { + return start + + /** + * Start of blank line. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + return markdownSpace(code) + ? factorySpace(effects, after, 'linePrefix')(code) + : after(code) + } + + /** + * At eof/eol, after optional whitespace. + * + * > 👉 **Note**: `␠` represents a space character. + * + * ```markdown + * > | ␠␠␊ + * ^ + * > | ␊ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/node_modules/micromark-util-chunked/index.js +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {number} start + * Index to remove/insert at (can be negative). + * @param {number} remove + * Number of items to remove. + * @param {Array<T>} items + * Items to inject into `list`. + * @returns {void} + * Nothing. + */ +function micromark_util_chunked_splice(list, start, remove, items) { + const end = list.length + let chunkStart = 0 + /** @type {Array<unknown>} */ + let parameters + + // Make start between zero and `end` (included). + if (start < 0) { + start = -start > end ? 0 : end + start + } else { + start = start > end ? end : start + } + remove = remove > 0 ? remove : 0 + + // No need to chunk the items if there’s only a couple (10k) items. + if (items.length < 10000) { + parameters = Array.from(items) + parameters.unshift(start, remove) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + } else { + // Delete `remove` items starting from `start` + if (remove) list.splice(start, remove) + + // Insert the items in chunks to not cause stack overflows. + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000) + parameters.unshift(start, 0) + // @ts-expect-error Hush, it’s fine. + list.splice(...parameters) + chunkStart += 10000 + start += 10000 + } + } +} + +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * Item type. + * @param {Array<T>} list + * List to operate on. + * @param {Array<T>} items + * Items to add to `list`. + * @returns {Array<T>} + * Either `list` or `items`. + */ +function micromark_util_chunked_push(list, items) { + if (list.length > 0) { + micromark_util_chunked_splice(list, list.length, 0, items) + return list + } + return items +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-subtokenize/index.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + */ + + +/** + * Tokenize subcontent. + * + * @param {Array<Event>} events + * List of events. + * @returns {boolean} + * Whether subtokens were found. + */ +function subtokenize(events) { + /** @type {Record<string, number>} */ + const jumps = {} + let index = -1 + /** @type {Event} */ + let event + /** @type {number | undefined} */ + let lineIndex + /** @type {number} */ + let otherIndex + /** @type {Event} */ + let otherEvent + /** @type {Array<Event>} */ + let parameters + /** @type {Array<Event>} */ + let subevents + /** @type {boolean | undefined} */ + let more + while (++index < events.length) { + while (index in jumps) { + index = jumps[index] + } + event = events[index] + + // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events + otherIndex = 0 + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2 + } + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true + otherIndex++ + } + } + } + } + + // Enter. + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)) + index = jumps[index] + more = true + } + } + // Exit. + else if (event[1]._container) { + otherIndex = index + lineIndex = undefined + while (otherIndex--) { + otherEvent = events[otherIndex] + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + } + otherEvent[1].type = 'lineEnding' + lineIndex = otherIndex + } + } else { + break + } + } + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start) + + // Switch container exit w/ line endings. + parameters = events.slice(lineIndex, index) + parameters.unshift(event) + micromark_util_chunked_splice(events, lineIndex, index - lineIndex + 1, parameters) + } + } + } + return !more +} + +/** + * Tokenize embedded tokens. + * + * @param {Array<Event>} events + * @param {number} eventIndex + * @returns {Record<string, number>} + */ +function subcontent(events, eventIndex) { + const token = events[eventIndex][1] + const context = events[eventIndex][2] + let startPosition = eventIndex - 1 + /** @type {Array<number>} */ + const startPositions = [] + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start) + const childEvents = tokenizer.events + /** @type {Array<[number, number]>} */ + const jumps = [] + /** @type {Record<string, number>} */ + const gaps = {} + /** @type {Array<Chunk>} */ + let stream + /** @type {Token | undefined} */ + let previous + let index = -1 + /** @type {Token | undefined} */ + let current = token + let adjust = 0 + let start = 0 + const breaks = [start] + + // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + startPositions.push(startPosition) + if (!current._tokenizer) { + stream = context.sliceStream(current) + if (!current.next) { + stream.push(null) + } + if (previous) { + tokenizer.defineSkip(current.start) + } + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true + } + tokenizer.write(stream) + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined + } + } + + // Unravel the next token. + previous = current + current = current.next + } + + // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + current = token + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1 + breaks.push(start) + // Help GC. + current._tokenizer = undefined + current.previous = undefined + current = current.next + } + } + + // Help GC. + tokenizer.events = [] + + // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + if (current) { + // Help GC. + current._tokenizer = undefined + current.previous = undefined + } else { + breaks.pop() + } + + // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + index = breaks.length + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]) + const start = startPositions.pop() + jumps.unshift([start, start + slice.length - 1]) + micromark_util_chunked_splice(events, start, 2, slice) + } + index = -1 + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1] + adjust += jumps[index][1] - jumps[index][0] - 1 + } + return gaps +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/content.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content_content = { + tokenize: tokenizeContent, + resolve: resolveContent +} + +/** @type {Construct} */ +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +} + +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ +function resolveContent(events) { + subtokenize(events) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContent(effects, ok) { + /** @type {Token | undefined} */ + let previous + return chunkStart + + /** + * Before a content chunk. + * + * ```markdown + * > | abc + * ^ + * ``` + * + * @type {State} + */ + function chunkStart(code) { + effects.enter('content') + previous = effects.enter('chunkContent', { + contentType: 'content' + }) + return chunkInside(code) + } + + /** + * In a content chunk. + * + * ```markdown + * > | abc + * ^^^ + * ``` + * + * @type {State} + */ + function chunkInside(code) { + if (code === null) { + return contentEnd(code) + } + + // To do: in `markdown-rs`, each line is parsed on its own, and everything + // is stitched together resolving. + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } + + // Data. + effects.consume(code) + return chunkInside + } + + /** + * + * + * @type {State} + */ + function contentEnd(code) { + effects.exit('chunkContent') + effects.exit('content') + return ok(code) + } + + /** + * + * + * @type {State} + */ + function contentContinue(code) { + effects.consume(code) + effects.exit('chunkContent') + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }) + previous = previous.next + return chunkInside + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeContinuation(effects, ok, nok) { + const self = this + return startLookahead + + /** + * + * + * @type {State} + */ + function startLookahead(code) { + effects.exit('chunkContent') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, prefixed, 'linePrefix') + } + + /** + * + * + * @type {State} + */ + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + // Always populated by defaults. + + const tail = self.events[self.events.length - 1] + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/flow.js +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + + + + +/** @type {InitialConstruct} */ +const flow = { + tokenize: initializeFlow +} + +/** + * @this {TokenizeContext} + * @type {Initializer} + */ +function initializeFlow(effects) { + const self = this + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, + // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content_content, afterConstruct) + ), + 'linePrefix' + ) + ) + ) + return initial + + /** @type {State} */ + function atBlankEnding(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEndingBlank') + effects.consume(code) + effects.exit('lineEndingBlank') + self.currentConstruct = undefined + return initial + } + + /** @type {State} */ + function afterConstruct(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + self.currentConstruct = undefined + return initial + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/initialize/text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +const resolver = { + resolveAll: createResolver() +} +const string = initializeFactory('string') +const text_text = initializeFactory('text') + +/** + * @param {'string' | 'text'} field + * @returns {InitialConstruct} + */ +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + + /** + * @this {TokenizeContext} + * @type {Initializer} + */ + function initializeText(effects) { + const self = this + const constructs = this.parser.constructs[field] + const text = effects.attempt(constructs, start, notText) + return start + + /** @type {State} */ + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + + /** @type {State} */ + function notText(code) { + if (code === null) { + effects.consume(code) + return + } + effects.enter('data') + effects.consume(code) + return data + } + + /** @type {State} */ + function data(code) { + if (atBreak(code)) { + effects.exit('data') + return text(code) + } + + // Data. + effects.consume(code) + return data + } + + /** + * @param {Code} code + * @returns {boolean} + */ + function atBreak(code) { + if (code === null) { + return true + } + const list = constructs[code] + let index = -1 + if (list) { + // Always populated by defaults. + + while (++index < list.length) { + const item = list[index] + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + return false + } + } +} + +/** + * @param {Resolver | undefined} [extraResolver] + * @returns {Resolver} + */ +function createResolver(extraResolver) { + return resolveAllText + + /** @type {Resolver} */ + function resolveAllText(events, context) { + let index = -1 + /** @type {number | undefined} */ + let enter + + // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index + index++ + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + index = enter + 2 + } + enter = undefined + } + } + return extraResolver ? extraResolver(events, context) : events + } +} + +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ +function resolveAllLineSuffixes(events, context) { + let eventIndex = 0 // Skip first. + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1] + const chunks = context.sliceStream(data) + let index = chunks.length + let bufferIndex = -1 + let size = 0 + /** @type {boolean | undefined} */ + let tabs + while (index--) { + const chunk = chunks[index] + if (typeof chunk === 'string') { + bufferIndex = chunk.length + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++ + bufferIndex-- + } + if (bufferIndex) break + bufferIndex = -1 + } + // Number + else if (chunk === -2) { + tabs = true + size++ + } else if (chunk === -1) { + // Empty + } else { + // Replacement character, exit. + index++ + break + } + } + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + } + data.end = Object.assign({}, token.start) + if (data.start.offset === data.end.offset) { + Object.assign(data, token) + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ) + eventIndex += 2 + } + } + eventIndex++ + } + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-resolve-all/index.js +/** + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * Call all `resolveAll`s. + * + * @param {Array<{resolveAll?: Resolver | undefined}>} constructs + * List of constructs, optionally with `resolveAll`s. + * @param {Array<Event>} events + * List of events. + * @param {TokenizeContext} context + * Context used by `tokenize`. + * @returns {Array<Event>} + * Changed events. + */ +function resolveAll(constructs, events, context) { + /** @type {Array<Resolver>} */ + const called = [] + let index = -1 + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context) + called.push(resolve) + } + } + + return events +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/create-tokenizer.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenType} TokenType + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + */ + +/** + * @callback Restore + * @returns {void} + * + * @typedef Info + * @property {Restore} restore + * @property {number} from + * + * @callback ReturnHandle + * Handle a successful run. + * @param {Construct} construct + * @param {Info} info + * @returns {void} + */ + + + + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit<Point, '_bufferIndex' | '_index'> | undefined} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ) + /** @type {Record<string, number>} */ + const columnStart = {} + /** @type {Array<Construct>} */ + const resolveAllConstructs = [] + /** @type {Array<Chunk>} */ + let chunks = [] + /** @type {Array<Token>} */ + let stack = [] + /** @type {boolean | undefined} */ + let consumed = true + + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + } + + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + } + + /** + * The state function. + * + * @type {State | void} + */ + let state = initialize.tokenize.call(context, effects) + + /** + * Track which character we expect to be consumed, to catch bugs. + * + * @type {Code} + */ + let expectedCode + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize) + } + return context + + /** @type {TokenizeContext['write']} */ + function write(slice) { + chunks = push(chunks, slice) + main() + + // Exit if we’re not done, resolve might change stuff. + if (chunks[chunks.length - 1] !== null) { + return [] + } + addResult(initialize, 0) + + // Otherwise, resolve, and exit. + context.events = resolveAll(resolveAllConstructs, context.events, context) + return context.events + } + + // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + + /** @type {TokenizeContext['sliceStream']} */ + function sliceStream(token) { + return sliceChunks(chunks, token) + } + + /** @type {TokenizeContext['now']} */ + function now() { + // This is a hot path, so we clone manually instead of `Object.assign({}, point)` + const {line, column, offset, _index, _bufferIndex} = point + return { + line, + column, + offset, + _index, + _bufferIndex + } + } + + /** @type {TokenizeContext['defineSkip']} */ + function defineSkip(value) { + columnStart[value.line] = value.column + accountForPotentialSkip() + } + + // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + function main() { + /** @type {number} */ + let chunkIndex + while (point._index < chunks.length) { + const chunk = chunks[point._index] + + // If we’re in a buffer chunk, loop through it. + if (typeof chunk === 'string') { + chunkIndex = point._index + if (point._bufferIndex < 0) { + point._bufferIndex = 0 + } + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)) + } + } else { + go(chunk) + } + } + } + + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + function go(code) { + consumed = undefined + expectedCode = code + state = state(code) + } + + /** @type {Effects['consume']} */ + function consume(code) { + if (markdownLineEnding(code)) { + point.line++ + point.column = 1 + point.offset += code === -3 ? 2 : 1 + accountForPotentialSkip() + } else if (code !== -1) { + point.column++ + point.offset++ + } + + // Not in a string chunk. + if (point._bufferIndex < 0) { + point._index++ + } else { + point._bufferIndex++ + + // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1 + point._index++ + } + } + + // Expose the previous character. + context.previous = code + + // Mark as consumed. + consumed = true + } + + /** @type {Effects['enter']} */ + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {} + token.type = type + token.start = now() + context.events.push(['enter', token, context]) + stack.push(token) + return token + } + + /** @type {Effects['exit']} */ + function exit(type) { + const token = stack.pop() + token.end = now() + context.events.push(['exit', token, context]) + return token + } + + /** + * Use results. + * + * @type {ReturnHandle} + */ + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from) + } + + /** + * Discard results. + * + * @type {ReturnHandle} + */ + function onsuccessfulcheck(_, info) { + info.restore() + } + + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {{interrupt?: boolean | undefined} | undefined} [fields] + */ + function constructFactory(onreturn, fields) { + return hook + + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Array<Construct> | Construct | ConstructRecord} constructs + * @param {State} returnState + * @param {State | undefined} [bogusState] + * @returns {State} + */ + function hook(constructs, returnState, bogusState) { + /** @type {Array<Construct>} */ + let listOfConstructs + /** @type {number} */ + let constructIndex + /** @type {Construct} */ + let currentConstruct + /** @type {Info} */ + let info + return Array.isArray(constructs) /* c8 ignore next 1 */ + ? handleListOfConstructs(constructs) + : 'tokenize' in constructs + ? // @ts-expect-error Looks like a construct. + handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + function handleMapOfConstructs(map) { + return start + + /** @type {State} */ + function start(code) { + const def = code !== null && map[code] + const all = code !== null && map.null + const list = [ + // To do: add more extension tests. + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ] + return handleListOfConstructs(list)(code) + } + } + + /** + * Handle a list of construct. + * + * @param {Array<Construct>} list + * @returns {State} + */ + function handleListOfConstructs(list) { + listOfConstructs = list + constructIndex = 0 + if (list.length === 0) { + return bogusState + } + return handleConstruct(list[constructIndex]) + } + + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + function handleConstruct(construct) { + return start + + /** @type {State} */ + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store() + currentConstruct = construct + if (!construct.partial) { + context.currentConstruct = construct + } + + // Always populated by defaults. + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok(code) + } + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + + /** @type {State} */ + function ok(code) { + consumed = true + onreturn(currentConstruct, info) + return returnState + } + + /** @type {State} */ + function nok(code) { + consumed = true + info.restore() + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + return bogusState + } + } + } + + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct) + } + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ) + } + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context) + } + } + + /** + * Store state. + * + * @returns {Info} + */ + function store() { + const startPoint = now() + const startPrevious = context.previous + const startCurrentConstruct = context.currentConstruct + const startEventsIndex = context.events.length + const startStack = Array.from(stack) + return { + restore, + from: startEventsIndex + } + + /** + * Restore state. + * + * @returns {void} + */ + function restore() { + point = startPoint + context.previous = startPrevious + context.currentConstruct = startCurrentConstruct + context.events.length = startEventsIndex + stack = startStack + accountForPotentialSkip() + } + } + + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line] + point.offset += columnStart[point.line] - 1 + } + } +} + +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Array<Chunk>} chunks + * @param {Pick<Token, 'end' | 'start'>} token + * @returns {Array<Chunk>} + */ +function sliceChunks(chunks, token) { + const startIndex = token.start._index + const startBufferIndex = token.start._bufferIndex + const endIndex = token.end._index + const endBufferIndex = token.end._bufferIndex + /** @type {Array<Chunk>} */ + let view + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)] + } else { + view = chunks.slice(startIndex, endIndex) + if (startBufferIndex > -1) { + const head = view[0] + if (typeof head === 'string') { + view[0] = head.slice(startBufferIndex) + } else { + view.shift() + } + } + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)) + } + } + return view +} + +/** + * Get the string value of a slice of chunks. + * + * @param {Array<Chunk>} chunks + * @param {boolean | undefined} [expandTabs=false] + * @returns {string} + */ +function serializeChunks(chunks, expandTabs) { + let index = -1 + /** @type {Array<string>} */ + const result = [] + /** @type {boolean | undefined} */ + let atTab + while (++index < chunks.length) { + const chunk = chunks[index] + /** @type {string} */ + let value + if (typeof chunk === 'string') { + value = chunk + } else + switch (chunk) { + case -5: { + value = '\r' + break + } + case -4: { + value = '\n' + break + } + case -3: { + value = '\r' + '\n' + break + } + case -2: { + value = expandTabs ? ' ' : '\t' + break + } + case -1: { + if (!expandTabs && atTab) continue + value = ' ' + break + } + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk) + } + } + atTab = chunk === -2 + result.push(value) + } + return result.join('') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/thematic-break.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const thematicBreak = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of thematic break. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('thematicBreak') + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * After optional whitespace, at marker. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + marker = code + return atBreak(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence') + return sequence(code) + } + if (size >= 3 && (code === null || markdownLineEnding(code))) { + effects.exit('thematicBreak') + return ok(code) + } + return nok(code) + } + + /** + * In sequence. + * + * ```markdown + * > | *** + * ^ + * ``` + * + * @type {State} + */ + function sequence(code) { + if (code === marker) { + effects.consume(code) + size++ + return sequence + } + effects.exit('thematicBreakSequence') + return markdownSpace(code) + ? factorySpace(effects, atBreak, 'whitespace')(code) + : atBreak(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/list.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').ContainerState} ContainerState + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + +/** @type {Construct} */ +const list = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +} + +/** @type {Construct} */ +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +} + +/** @type {Construct} */ +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +} + +// To do: `markdown-rs` parses list items on their own and later stitches them +// together. + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListStart(effects, ok, nok) { + const self = this + const tail = self.events[self.events.length - 1] + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + let size = 0 + return start + + /** @type {State} */ + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered') + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind + effects.enter(kind, { + _container: true + }) + } + if (kind === 'listUnordered') { + effects.enter('listItemPrefix') + return code === 42 || code === 45 + ? effects.check(thematicBreak, nok, atMarker)(code) + : atMarker(code) + } + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix') + effects.enter('listItemValue') + return inside(code) + } + } + return nok(code) + } + + /** @type {State} */ + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code) + return inside + } + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue') + return atMarker(code) + } + return nok(code) + } + + /** + * @type {State} + **/ + function atMarker(code) { + effects.enter('listItemMarker') + effects.consume(code) + effects.exit('listItemMarker') + self.containerState.marker = self.containerState.marker || code + return effects.check( + blankLine, + // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + + /** @type {State} */ + function onBlank(code) { + self.containerState.initialBlankLine = true + initialSize++ + return endOfPrefix(code) + } + + /** @type {State} */ + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace') + effects.consume(code) + effects.exit('listItemPrefixWhitespace') + return endOfPrefix + } + return nok(code) + } + + /** @type {State} */ + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length + return ok(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListContinuation(effects, ok, nok) { + const self = this + self.containerState._closeFlow = undefined + return effects.check(blankLine, onBlank, notBlank) + + /** @type {State} */ + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine + + // We have a blank line. + // Still, try to consume at most the items size. + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + + /** @type {State} */ + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return notInCurrentItem(code) + } + self.containerState.furtherBlankLines = undefined + self.containerState.initialBlankLine = undefined + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + + /** @type {State} */ + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true + // As we’re closing flow, we’re no longer interrupting. + self.interrupt = undefined + // Always populated by defaults. + + return factorySpace( + effects, + effects.attempt(list, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeIndent(effects, ok, nok) { + const self = this + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} + +/** + * @type {Exiter} + * @this {TokenizeContext} + */ +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type) +} + +/** + * @type {Tokenizer} + * @this {TokenizeContext} + */ +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this + + // Always populated by defaults. + + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + + /** @type {State} */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/block-quote.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this + return start + + /** + * Start of block quote. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 62) { + const state = self.containerState + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }) + state.open = true + } + effects.enter('blockQuotePrefix') + effects.enter('blockQuoteMarker') + effects.consume(code) + effects.exit('blockQuoteMarker') + return after + } + return nok(code) + } + + /** + * After `>`, before optional whitespace. + * + * ```markdown + * > | > a + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace') + effects.consume(code) + effects.exit('blockQuotePrefixWhitespace') + effects.exit('blockQuotePrefix') + return ok + } + effects.exit('blockQuotePrefix') + return ok(code) + } +} + +/** + * Start of block quote continuation. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + const self = this + return contStart + + /** + * Start of block quote continuation. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contStart(code) { + if (markdownSpace(code)) { + // Always populated by defaults. + + return factorySpace( + effects, + contBefore, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } + return contBefore(code) + } + + /** + * At `>`, after optional whitespace. + * + * Also used to parse the first block quote opening. + * + * ```markdown + * | > a + * > | > b + * ^ + * ``` + * + * @type {State} + */ + function contBefore(code) { + return effects.attempt(blockQuote, ok, nok)(code) + } +} + +/** @type {Exiter} */ +function exit(effects) { + effects.exit('blockQuote') +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-destination/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse destinations. + * + * ###### Examples + * + * ```markdown + * <a> + * <a\>b> + * <a b> + * <a)> + * a + * a\)b + * a(b)c + * a(b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type for whole (`<a>` or `b`). + * @param {TokenType} literalType + * Type when enclosed (`<a>`). + * @param {TokenType} literalMarkerType + * Type for enclosing (`<` and `>`). + * @param {TokenType} rawType + * Type when not enclosed (`b`). + * @param {TokenType} stringType + * Type for the value (`a` or `b`). + * @param {number | undefined} [max=Infinity] + * Depth of nested parens (inclusive). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY + let balance = 0 + return start + + /** + * Start of destination. + * + * ```markdown + * > | <aa> + * ^ + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 60) { + effects.enter(type) + effects.enter(literalType) + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + return enclosedBefore + } + + // ASCII control, space, closing paren. + if (code === null || code === 32 || code === 41 || asciiControl(code)) { + return nok(code) + } + effects.enter(type) + effects.enter(rawType) + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return raw(code) + } + + /** + * After `<`, at an enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType) + effects.consume(code) + effects.exit(literalMarkerType) + effects.exit(literalType) + effects.exit(type) + return ok + } + effects.enter(stringType) + effects.enter('chunkString', { + contentType: 'string' + }) + return enclosed(code) + } + + /** + * In enclosed destination. + * + * ```markdown + * > | <aa> + * ^ + * ``` + * + * @type {State} + */ + function enclosed(code) { + if (code === 62) { + effects.exit('chunkString') + effects.exit(stringType) + return enclosedBefore(code) + } + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? enclosedEscape : enclosed + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | <a\*a> + * ^ + * ``` + * + * @type {State} + */ + function enclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code) + return enclosed + } + return enclosed(code) + } + + /** + * In raw destination. + * + * ```markdown + * > | aa + * ^ + * ``` + * + * @type {State} + */ + function raw(code) { + if ( + !balance && + (code === null || code === 41 || markdownLineEndingOrSpace(code)) + ) { + effects.exit('chunkString') + effects.exit(stringType) + effects.exit(rawType) + effects.exit(type) + return ok(code) + } + if (balance < limit && code === 40) { + effects.consume(code) + balance++ + return raw + } + if (code === 41) { + effects.consume(code) + balance-- + return raw + } + + // ASCII control (but *not* `\0`) and space and `(`. + // Note: in `markdown-rs`, `\0` exists in codes, in `micromark-js` it + // doesn’t. + if (code === null || code === 32 || code === 40 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return code === 92 ? rawEscape : raw + } + + /** + * After `\`, at special character. + * + * ```markdown + * > | a\*a + * ^ + * ``` + * + * @type {State} + */ + function rawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code) + return raw + } + return raw(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-label/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + +/** + * Parse labels. + * + * > 👉 **Note**: labels in markdown are capped at 999 characters in the string. + * + * ###### Examples + * + * ```markdown + * [a] + * [a + * b] + * [a\]b] + * ``` + * + * @this {TokenizeContext} + * Tokenize context. + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole label (`[a]`). + * @param {TokenType} markerType + * Type for the markers (`[` and `]`). + * @param {TokenType} stringType + * Type for the identifier (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this + let size = 0 + /** @type {boolean} */ + let seen + return start + + /** + * Start of label. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.enter(stringType) + return atBreak + } + + /** + * In label, at something, before something else. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if ( + size > 999 || + code === null || + code === 91 || + (code === 93 && !seen) || + // To do: remove in the future once we’ve switched from + // `micromark-extension-footnote` to `micromark-extension-gfm-footnote`, + // which doesn’t need this. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) + ) { + return nok(code) + } + if (code === 93) { + effects.exit(stringType) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + + // To do: indent? Link chunks and EOLs together? + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return atBreak + } + effects.enter('chunkString', { + contentType: 'string' + }) + return labelInside(code) + } + + /** + * In label, in text. + * + * ```markdown + * > | [a] + * ^ + * ``` + * + * @type {State} + */ + function labelInside(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + if (!seen) seen = !markdownSpace(code) + return code === 92 ? labelEscape : labelInside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | [a\*a] + * ^ + * ``` + * + * @type {State} + */ + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code) + size++ + return labelInside + } + return labelInside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-title/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenType} TokenType + */ + + + +/** + * Parse titles. + * + * ###### Examples + * + * ```markdown + * "a" + * 'b' + * (c) + * "a + * b" + * 'a + * b' + * (a\)b) + * ``` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @param {State} nok + * State switched to when unsuccessful. + * @param {TokenType} type + * Type of the whole title (`"a"`, `'b'`, `(c)`). + * @param {TokenType} markerType + * Type for the markers (`"`, `'`, `(`, and `)`). + * @param {TokenType} stringType + * Type for the value (`a`). + * @returns {State} + * Start state. + */ // eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of title. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + if (code === 34 || code === 39 || code === 40) { + effects.enter(type) + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + marker = code === 40 ? 41 : code + return begin + } + return nok(code) + } + + /** + * After opening marker. + * + * This is also used at the closing marker. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function begin(code) { + if (code === marker) { + effects.enter(markerType) + effects.consume(code) + effects.exit(markerType) + effects.exit(type) + return ok + } + effects.enter(stringType) + return atBreak(code) + } + + /** + * At something, before something else. + * + * ```markdown + * > | "a" + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === marker) { + effects.exit(stringType) + return begin(marker) + } + if (code === null) { + return nok(code) + } + + // Note: blank lines can’t exist in content. + if (markdownLineEnding(code)) { + // To do: use `space_or_tab_eol_with_options`, connect. + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, atBreak, 'linePrefix') + } + effects.enter('chunkString', { + contentType: 'string' + }) + return inside(code) + } + + /** + * + * + * @type {State} + */ + function inside(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + return atBreak(code) + } + effects.consume(code) + return code === 92 ? escape : inside + } + + /** + * After `\`, at a special character. + * + * ```markdown + * > | "a\*b" + * ^ + * ``` + * + * @type {State} + */ + function escape(code) { + if (code === marker || code === 92) { + effects.consume(code) + return inside + } + return inside(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-factory-whitespace/index.js +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + + + +/** + * Parse spaces and tabs. + * + * There is no `nok` parameter: + * + * * line endings or spaces in markdown are often optional, in which case this + * factory can be used and `ok` will be switched to whether spaces were found + * or not + * * one line ending or space can be detected with + * `markdownLineEndingOrSpace(code)` right before using `factoryWhitespace` + * + * @param {Effects} effects + * Context. + * @param {State} ok + * State switched to when successful. + * @returns + * Start state. + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen + return start + + /** @type {State} */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + seen = true + return start + } + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + return ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-normalize-identifier/index.js +/** + * Normalize an identifier (as found in references, definitions). + * + * Collapses markdown whitespace, trim, and then lower- and uppercase. + * + * Some characters are considered “uppercase”, such as U+03F4 (`ϴ`), but if their + * lowercase counterpart (U+03B8 (`θ`)) is uppercased will result in a different + * uppercase character (U+0398 (`Θ`)). + * So, to get a canonical form, we perform both lower- and uppercase. + * + * Using uppercase last makes sure keys will never interact with default + * prototypal values (such as `constructor`): nothing in the prototype of + * `Object` is uppercase. + * + * @param {string} value + * Identifier to normalize. + * @returns {string} + * Normalized identifier. + */ +function normalizeIdentifier(value) { + return ( + value + // Collapse markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') + // Trim. + .replace(/^ | $/g, '') + // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/definition.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + +/** @type {Construct} */ +const definition = { + name: 'definition', + tokenize: tokenizeDefinition +} + +/** @type {Construct} */ +const titleBefore = { + tokenize: tokenizeTitleBefore, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeDefinition(effects, ok, nok) { + const self = this + /** @type {string} */ + let identifier + return start + + /** + * At start of a definition. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Do not interrupt paragraphs (but do follow definitions). + // To do: do `interrupt` the way `markdown-rs` does. + // To do: parse whitespace the way `markdown-rs` does. + effects.enter('definition') + return before(code) + } + + /** + * After optional whitespace, at `[`. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + // To do: parse whitespace the way `markdown-rs` does. + + return factoryLabel.call( + self, + effects, + labelAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + + /** + * After label. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + if (code === 58) { + effects.enter('definitionMarker') + effects.consume(code) + effects.exit('definitionMarker') + return markerAfter + } + return nok(code) + } + + /** + * After marker. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function markerAfter(code) { + // Note: whitespace is optional. + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, destinationBefore)(code) + : destinationBefore(code) + } + + /** + * Before destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationBefore(code) { + return factoryDestination( + effects, + destinationAfter, + // Note: we don’t need to reset the way `markdown-rs` does. + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + )(code) + } + + /** + * After destination. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function destinationAfter(code) { + return effects.attempt(titleBefore, after, after)(code) + } + + /** + * After definition. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return markdownSpace(code) + ? factorySpace(effects, afterWhitespace, 'whitespace')(code) + : afterWhitespace(code) + } + + /** + * After definition, after optional whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function afterWhitespace(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition') + + // Note: we don’t care about uniqueness. + // It’s likely that that doesn’t happen very frequently. + // It is more likely that it wastes precious time. + self.parser.defined.push(identifier) + + // To do: `markdown-rs` interrupt. + // // You’d be interrupting. + // tokenizer.interrupt = true + return ok(code) + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeTitleBefore(effects, ok, nok) { + return titleBefore + + /** + * After destination, at whitespace. + * + * ```markdown + * > | [a]: b + * ^ + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, beforeMarker)(code) + : nok(code) + } + + /** + * At title. + * + * ```markdown + * | [a]: b + * > | "c" + * ^ + * ``` + * + * @type {State} + */ + function beforeMarker(code) { + return factoryTitle( + effects, + titleAfter, + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + /** + * After title. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfter(code) { + return markdownSpace(code) + ? factorySpace(effects, titleAfterOptionalWhitespace, 'whitespace')(code) + : titleAfterOptionalWhitespace(code) + } + + /** + * After title, after optional whitespace. + * + * ```markdown + * > | [a]: b "c" + * ^ + * ``` + * + * @type {State} + */ + function titleAfterOptionalWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-indented.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +} + +/** @type {Construct} */ +const furtherStart = { + tokenize: tokenizeFurtherStart, + partial: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeIndented(effects, ok, nok) { + const self = this + return start + + /** + * Start of code (indented). + * + * > **Parsing note**: it is not needed to check if this first line is a + * > filled line (that it has a non-whitespace character), because blank lines + * > are parsed already, so we never run into that. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: manually check if interrupting like `markdown-rs`. + + effects.enter('codeIndented') + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? atBreak(code) + : nok(code) + } + + /** + * At a break. + * + * ```markdown + * > | aaa + * ^ ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === null) { + return after(code) + } + if (markdownLineEnding(code)) { + return effects.attempt(furtherStart, atBreak, after)(code) + } + effects.enter('codeFlowValue') + return inside(code) + } + + /** + * In code content. + * + * ```markdown + * > | aaa + * ^^^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return atBreak(code) + } + effects.consume(code) + return inside + } + + /** @type {State} */ + function after(code) { + effects.exit('codeIndented') + // To do: allow interrupting like `markdown-rs`. + // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeFurtherStart(effects, ok, nok) { + const self = this + return furtherStart + + /** + * At eol, trying to parse another indent. + * + * ```markdown + * > | aaa + * ^ + * | bbb + * ``` + * + * @type {State} + */ + function furtherStart(code) { + // To do: improve `lazy` / `pierce` handling. + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return furtherStart + } + + // To do: the code here in `micromark-js` is a bit different from + // `markdown-rs` because there it can attempt spaces. + // We can’t yet. + // + // To do: use an improved `space_or_tab` function like `markdown-rs`, + // so that we can drop the next state. + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + + /** + * At start, after 1 or 4 spaces. + * + * ```markdown + * > | aaa + * ^ + * ``` + * + * @type {State} + */ + function afterPrefix(code) { + const tail = self.events[self.events.length - 1] + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? furtherStart(code) + : nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/heading-atx.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +} + +/** @type {Resolver} */ +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2 + let contentStart = 3 + /** @type {Token} */ + let content + /** @type {Token} */ + let text + + // Prefix whitespace, part of the opening. + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2 + } + + // Suffix whitespace, part of the closing. + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2 + } + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4 + } + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + } + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + contentType: 'text' + } + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHeadingAtx(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of a heading (atx). + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + effects.enter('atxHeading') + return before(code) + } + + /** + * After optional whitespace, at `#`. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('atxHeadingSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 35 && size++ < 6) { + effects.consume(code) + return sequenceOpen + } + + // Always at least one `#`. + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence') + return atBreak(code) + } + return nok(code) + } + + /** + * After something, before something else. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function atBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence') + return sequenceFurther(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading') + // To do: interrupt like `markdown-rs`. + // // Feel free to interrupt. + // tokenizer.interrupt = false + return ok(code) + } + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + // To do: generate `data` tokens, add the `text` token later. + // Needs edit map, see: `markdown.rs`. + effects.enter('atxHeadingText') + return data(code) + } + + /** + * In further sequence (after whitespace). + * + * Could be normal “visible” hashes in the heading or a final sequence. + * + * ```markdown + * > | ## aa ## + * ^ + * ``` + * + * @type {State} + */ + function sequenceFurther(code) { + if (code === 35) { + effects.consume(code) + return sequenceFurther + } + effects.exit('atxHeadingSequence') + return atBreak(code) + } + + /** + * In text. + * + * ```markdown + * > | ## aa + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText') + return atBreak(code) + } + effects.consume(code) + return data + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/setext-underline.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +} + +/** @type {Resolver} */ +function resolveToSetextUnderline(events, context) { + // To do: resolve like `markdown-rs`. + let index = events.length + /** @type {number | undefined} */ + let content + /** @type {number | undefined} */ + let text + /** @type {number | undefined} */ + let definition + + // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index + break + } + if (events[index][1].type === 'paragraph') { + text = index + } + } + // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1) + } + if (!definition && events[index][1].type === 'definition') { + definition = index + } + } + } + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + + // Change the paragraph to setext heading text. + events[text][1].type = 'setextHeadingText' + + // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + if (definition) { + events.splice(text, 0, ['enter', heading, context]) + events.splice(definition + 1, 0, ['exit', events[content][1], context]) + events[content][1].end = Object.assign({}, events[definition][1].end) + } else { + events[content][1] = heading + } + + // Add the heading exit at the end. + events.push(['exit', heading, context]) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * At start of heading (setext) underline. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + let index = self.events.length + /** @type {boolean | undefined} */ + let paragraph + // Find an opening. + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph' + break + } + } + + // To do: handle lazy/pierce like `markdown-rs`. + // To do: parse indent like `markdown-rs`. + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine') + marker = code + return before(code) + } + return nok(code) + } + + /** + * After optional whitespace, at `-` or `=`. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('setextHeadingLineSequence') + return inside(code) + } + + /** + * In sequence. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + effects.exit('setextHeadingLineSequence') + return markdownSpace(code) + ? factorySpace(effects, after, 'lineSuffix')(code) + : after(code) + } + + /** + * After sequence, after optional whitespace. + * + * ```markdown + * | aa + * > | == + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-html-tag-name/index.js +/** + * List of lowercase HTML “block” tag names. + * + * The list, when parsing HTML (flow), results in more relaxed rules (condition + * 6). + * Because they are known blocks, the HTML-like syntax doesn’t have to be + * strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `search` was added in `CommonMark@0.31`. + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'search', + 'section', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +] + +/** + * List of lowercase HTML “raw” tag names. + * + * The list, when parsing HTML (flow), results in HTML that can include lines + * without exiting, until a closing tag also in this list is found (condition + * 1). + * + * This module is copied from: + * <https://spec.commonmark.org/0.30/#html-blocks>. + * + * > 👉 **Note**: `textarea` was added in `CommonMark@0.30`. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea'] + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-flow.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + +/** @type {Construct} */ +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +} + +/** @type {Construct} */ +const blankLineBefore = { + tokenize: tokenizeBlankLineBefore, + partial: true +} +const nonLazyContinuationStart = { + tokenize: tokenizeNonLazyContinuationStart, + partial: true +} + +/** @type {Resolver} */ +function resolveToHtmlFlow(events) { + let index = events.length + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start + // Add the prefix start to the HTML line token. + events[index + 1][1].start = events[index - 2][1].start + // Remove the line prefix. + events.splice(index - 2, 2) + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this + /** @type {number} */ + let marker + /** @type {boolean} */ + let closingTag + /** @type {string} */ + let buffer + /** @type {number} */ + let index + /** @type {Code} */ + let markerB + return start + + /** + * Start of HTML (flow). + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse indent like `markdown-rs`. + return before(code) + } + + /** + * At `<`, after optional whitespace. + * + * ```markdown + * > | <x /> + * ^ + * ``` + * + * @type {State} + */ + function before(code) { + effects.enter('htmlFlow') + effects.enter('htmlFlowData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | <x /> + * ^ + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + closingTag = true + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + marker = 3 + // To do: + // tokenizer.concrete = true + // To do: use `markdown-rs` style interrupt. + // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + return self.interrupt ? ok : continuationDeclarationInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | <!doctype> + * ^ + * > | <!--xxx--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + marker = 2 + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + marker = 5 + index = 0 + return cdataOpenInside + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + marker = 4 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<!-`, inside a comment, at another `-`. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuationDeclarationInside + } + return nok(code) + } + + /** + * After `<![`, inside CDATA, expecting `CDATA[`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + if (index === value.length) { + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return cdataOpenInside + } + return nok(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | </x> + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code) + // @ts-expect-error: not null. + buffer = String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * In tag name. + * + * ```markdown + * > | <ab> + * ^^ + * > | </ab> + * ^^ + * ``` + * + * @type {State} + */ + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + const slash = code === 47 + const name = buffer.toLowerCase() + if (!slash && !closingTag && htmlRawNames.includes(name)) { + marker = 1 + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + if (htmlBlockNames.includes(buffer.toLowerCase())) { + marker = 6 + if (slash) { + effects.consume(code) + return basicSelfClosing + } + + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok(code) : continuation(code) + } + marker = 7 + // Do not support complete HTML when interrupting. + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : closingTag + ? completeClosingTagAfter(code) + : completeAttributeNameBefore(code) + } + + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + buffer += String.fromCharCode(code) + return tagName + } + return nok(code) + } + + /** + * After closing slash of a basic tag name. + * + * ```markdown + * > | <div/> + * ^ + * ``` + * + * @type {State} + */ + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code) + // // Do not form containers. + // tokenizer.concrete = true + return self.interrupt ? ok : continuation + } + return nok(code) + } + + /** + * After closing slash of a complete tag name. + * + * ```markdown + * > | <x/> + * ^ + * ``` + * + * @type {State} + */ + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code) + return completeClosingTagAfter + } + return completeEnd(code) + } + + /** + * At an attribute name. + * + * At first, this state is used after a complete tag name, after whitespace, + * where it expects optional attributes or the end of the tag. + * It is also reused after attributes, when expecting more optional + * attributes. + * + * ```markdown + * > | <a /> + * ^ + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * > | <a > + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code) + return completeEnd + } + + // ASCII alphanumerical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return completeAttributeName + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameBefore + } + return completeEnd(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | <a :b> + * ^ + * > | <a _b> + * ^ + * > | <a b> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeName(code) { + // ASCII alphanumerical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return completeAttributeName + } + return completeAttributeNameAfter(code) + } + + /** + * After attribute name, at an optional initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | <a b> + * ^ + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return completeAttributeValueBefore + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeNameAfter + } + return completeAttributeNameBefore(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | <a b=c> + * ^ + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + markerB = code + return completeAttributeValueQuoted + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAttributeValueBefore + } + return completeAttributeValueUnquoted(code) + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | <a b="c"> + * ^ + * > | <a b='c'> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuoted(code) { + if (code === markerB) { + effects.consume(code) + markerB = null + return completeAttributeValueQuotedAfter + } + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + effects.consume(code) + return completeAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | <a b=c> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 47 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + effects.consume(code) + return completeAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the + * end of the tag. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + return nok(code) + } + + /** + * In certain circumstances of a complete tag where only an `>` is allowed. + * + * ```markdown + * > | <a b="c"> + * ^ + * ``` + * + * @type {State} + */ + function completeEnd(code) { + if (code === 62) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * After `>` in a complete tag. + * + * ```markdown + * > | <x> + * ^ + * ``` + * + * @type {State} + */ + function completeAfter(code) { + if (code === null || markdownLineEnding(code)) { + // // Do not form containers. + // tokenizer.concrete = true + return continuation(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return completeAfter + } + return nok(code) + } + + /** + * In continuation of any HTML kind. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuation(code) { + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationCommentInside + } + if (code === 60 && marker === 1) { + effects.consume(code) + return continuationRawTagOpen + } + if (code === 62 && marker === 4) { + effects.consume(code) + return continuationClose + } + if (code === 63 && marker === 3) { + effects.consume(code) + return continuationDeclarationInside + } + if (code === 93 && marker === 5) { + effects.consume(code) + return continuationCdataInside + } + if (markdownLineEnding(code) && (marker === 6 || marker === 7)) { + effects.exit('htmlFlowData') + return effects.check( + blankLineBefore, + continuationAfter, + continuationStart + )(code) + } + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationStart(code) + } + effects.consume(code) + return continuation + } + + /** + * In continuation, at eol. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStart(code) { + return effects.check( + nonLazyContinuationStart, + continuationStartNonLazy, + continuationAfter + )(code) + } + + /** + * In continuation, at eol, before non-lazy content. + * + * ```markdown + * > | <x> + * ^ + * | asd + * ``` + * + * @type {State} + */ + function continuationStartNonLazy(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return continuationBefore + } + + /** + * In continuation, before non-lazy content. + * + * ```markdown + * | <x> + * > | asd + * ^ + * ``` + * + * @type {State} + */ + function continuationBefore(code) { + if (code === null || markdownLineEnding(code)) { + return continuationStart(code) + } + effects.enter('htmlFlowData') + return continuation(code) + } + + /** + * In comment continuation, after one `-`, expecting another. + * + * ```markdown + * > | <!--xxx--> + * ^ + * ``` + * + * @type {State} + */ + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In raw continuation, after `<`, at `/`. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^ + * ``` + * + * @type {State} + */ + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code) + buffer = '' + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In raw continuation, after `</`, in a raw tag name. + * + * ```markdown + * > | <script>console.log(1)</script> + * ^^^^^^ + * ``` + * + * @type {State} + */ + function continuationRawEndTag(code) { + if (code === 62) { + const name = buffer.toLowerCase() + if (htmlRawNames.includes(name)) { + effects.consume(code) + return continuationClose + } + return continuation(code) + } + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code) + // @ts-expect-error: not null. + buffer += String.fromCharCode(code) + return continuationRawEndTag + } + return continuation(code) + } + + /** + * In cdata continuation, after `]`, expecting `]>`. + * + * ```markdown + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationCdataInside(code) { + if (code === 93) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In declaration or instruction continuation, at `>`. + * + * ```markdown + * > | <!--> + * ^ + * > | <?> + * ^ + * > | <!q> + * ^ + * > | <!--ab--> + * ^ + * > | <![CDATA[>&<]]> + * ^ + * ``` + * + * @type {State} + */ + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code) + return continuationClose + } + + // More dashes. + if (code === 45 && marker === 2) { + effects.consume(code) + return continuationDeclarationInside + } + return continuation(code) + } + + /** + * In closed continuation: everything we get until the eol/eof is part of it. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData') + return continuationAfter(code) + } + effects.consume(code) + return continuationClose + } + + /** + * Done. + * + * ```markdown + * > | <!doctype> + * ^ + * ``` + * + * @type {State} + */ + function continuationAfter(code) { + effects.exit('htmlFlow') + // // Feel free to interrupt. + // tokenizer.interrupt = false + // // No longer concrete. + // tokenizer.concrete = false + return ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuationStart(effects, ok, nok) { + const self = this + return start + + /** + * At eol, before continuation. + * + * ```markdown + * > | * ```js + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return after + } + return nok(code) + } + + /** + * A continuation. + * + * ```markdown + * | * ```js + * > | b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeBlankLineBefore(effects, ok, nok) { + return start + + /** + * Before eol, expecting blank line. + * + * ```markdown + * > | <div> + * ^ + * | + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return effects.attempt(blankLine, ok, nok) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-fenced.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const nonLazyContinuation = { + tokenize: tokenizeNonLazyContinuation, + partial: true +} + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeFenced(effects, ok, nok) { + const self = this + /** @type {Construct} */ + const closeStart = { + tokenize: tokenizeCloseStart, + partial: true + } + let initialPrefix = 0 + let sizeOpen = 0 + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Start of code. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function start(code) { + // To do: parse whitespace like `markdown-rs`. + return beforeSequenceOpen(code) + } + + /** + * In opening fence, after prefix, at sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeSequenceOpen(code) { + const tail = self.events[self.events.length - 1] + initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0 + marker = code + effects.enter('codeFenced') + effects.enter('codeFencedFence') + effects.enter('codeFencedFenceSequence') + return sequenceOpen(code) + } + + /** + * In opening fence sequence. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === marker) { + sizeOpen++ + effects.consume(code) + return sequenceOpen + } + if (sizeOpen < 3) { + return nok(code) + } + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, infoBefore, 'whitespace')(code) + : infoBefore(code) + } + + /** + * In opening fence, after the sequence (and optional whitespace), before info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function infoBefore(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return self.interrupt + ? ok(code) + : effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFencedFenceInfo') + effects.enter('chunkString', { + contentType: 'string' + }) + return info(code) + } + + /** + * In info. + * + * ```markdown + * > | ~~~js + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function info(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return infoBefore(code) + } + if (markdownSpace(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceInfo') + return factorySpace(effects, metaBefore, 'whitespace')(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return info + } + + /** + * In opening fence, after info and whitespace, before meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function metaBefore(code) { + if (code === null || markdownLineEnding(code)) { + return infoBefore(code) + } + effects.enter('codeFencedFenceMeta') + effects.enter('chunkString', { + contentType: 'string' + }) + return meta(code) + } + + /** + * In meta. + * + * ```markdown + * > | ~~~js eval + * ^ + * | alert(1) + * | ~~~ + * ``` + * + * @type {State} + */ + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString') + effects.exit('codeFencedFenceMeta') + return infoBefore(code) + } + if (code === 96 && code === marker) { + return nok(code) + } + effects.consume(code) + return meta + } + + /** + * At eol/eof in code, before a non-lazy closing fence or content. + * + * ```markdown + * > | ~~~js + * ^ + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function atNonLazyBreak(code) { + return effects.attempt(closeStart, after, contentBefore)(code) + } + + /** + * Before code content, not a closing fence, at eol. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return contentStart + } + + /** + * Before code content, not a closing fence. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentStart(code) { + return initialPrefix > 0 && markdownSpace(code) + ? factorySpace( + effects, + beforeContentChunk, + 'linePrefix', + initialPrefix + 1 + )(code) + : beforeContentChunk(code) + } + + /** + * Before code content, after optional prefix. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^ + * | ~~~ + * ``` + * + * @type {State} + */ + function beforeContentChunk(code) { + if (code === null || markdownLineEnding(code)) { + return effects.check(nonLazyContinuation, atNonLazyBreak, after)(code) + } + effects.enter('codeFlowValue') + return contentChunk(code) + } + + /** + * In code content. + * + * ```markdown + * | ~~~js + * > | alert(1) + * ^^^^^^^^ + * | ~~~ + * ``` + * + * @type {State} + */ + function contentChunk(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue') + return beforeContentChunk(code) + } + effects.consume(code) + return contentChunk + } + + /** + * After code. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + effects.exit('codeFenced') + return ok(code) + } + + /** + * @this {TokenizeContext} + * @type {Tokenizer} + */ + function tokenizeCloseStart(effects, ok, nok) { + let size = 0 + return startBefore + + /** + * + * + * @type {State} + */ + function startBefore(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return start + } + + /** + * Before closing fence, at optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + // Always populated by defaults. + + // To do: `enter` here or in next state? + effects.enter('codeFencedFence') + return markdownSpace(code) + ? factorySpace( + effects, + beforeSequenceClose, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : beforeSequenceClose(code) + } + + /** + * In closing fence, after optional whitespace, at sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function beforeSequenceClose(code) { + if (code === marker) { + effects.enter('codeFencedFenceSequence') + return sequenceClose(code) + } + return nok(code) + } + + /** + * In closing fence sequence. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + if (code === marker) { + size++ + effects.consume(code) + return sequenceClose + } + if (size >= sizeOpen) { + effects.exit('codeFencedFenceSequence') + return markdownSpace(code) + ? factorySpace(effects, sequenceCloseAfter, 'whitespace')(code) + : sequenceCloseAfter(code) + } + return nok(code) + } + + /** + * After closing fence sequence, after optional whitespace. + * + * ```markdown + * | ~~~js + * | alert(1) + * > | ~~~ + * ^ + * ``` + * + * @type {State} + */ + function sequenceCloseAfter(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence') + return ok(code) + } + return nok(code) + } + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeNonLazyContinuation(effects, ok, nok) { + const self = this + return start + + /** + * + * + * @type {State} + */ + function start(code) { + if (code === null) { + return nok(code) + } + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineStart + } + + /** + * + * + * @type {State} + */ + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/character-entities/index.js +/** + * Map of named character references. + * + * @type {Record<string, string>} + */ +const characterEntities = { + AElig: 'Æ', + AMP: '&', + Aacute: 'Á', + Abreve: 'Ă', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atilde: 'Ã', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ETH: 'Ð', + Eacute: 'É', + Ecaron: 'Ě', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacute: 'Í', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacute: 'Ó', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslash: 'Ø', + Otilde: 'Õ', + Otimes: '⨷', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acirc: 'â', + acute: '´', + acy: 'а', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atilde: 'ã', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedil: '¸', + cemptyv: '⦲', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: '≖', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + eth: 'ð', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacute: 'í', + ic: '⁣', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacute: 'ó', + oast: '⊛', + ocir: '⊚', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: '⩝', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslash: 'ø', + osol: '⊘', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + ouml: 'ö', + ovbar: '⌽', + par: '∥', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup1: '¹', + sup2: '²', + sup3: '³', + sup: '⊃', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thorn: 'þ', + tilde: '˜', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +} + +;// CONCATENATED MODULE: ./node_modules/decode-named-character-reference/index.js + + +const own = {}.hasOwnProperty + +/** + * Decode a single character reference (without the `&` or `;`). + * You probably only need this when you’re building parsers yourself that follow + * different rules compared to HTML. + * This is optimized to be tiny in browsers. + * + * @param {string} value + * `notin` (named), `#123` (deci), `#x123` (hexa). + * @returns {string|false} + * Decoded reference. + */ +function decodeNamedCharacterReference(value) { + return own.call(characterEntities, value) ? characterEntities[value] : false +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-reference.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterReference(effects, ok, nok) { + const self = this + let size = 0 + /** @type {number} */ + let max + /** @type {(code: Code) => boolean} */ + let test + return start + + /** + * Start of character reference. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterReference') + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + return open + } + + /** + * After `&`, at `#` for numeric references or alphanumeric for named + * references. + * + * ```markdown + * > | a&b + * ^ + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric') + effects.consume(code) + effects.exit('characterReferenceMarkerNumeric') + return numeric + } + effects.enter('characterReferenceValue') + max = 31 + test = asciiAlphanumeric + return value(code) + } + + /** + * After `#`, at `x` for hexadecimals or digit for decimals. + * + * ```markdown + * > | a{b + * ^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal') + effects.consume(code) + effects.exit('characterReferenceMarkerHexadecimal') + effects.enter('characterReferenceValue') + max = 6 + test = asciiHexDigit + return value + } + effects.enter('characterReferenceValue') + max = 7 + test = asciiDigit + return value(code) + } + + /** + * After markers (`&#x`, `&#`, or `&`), in value, before `;`. + * + * The character reference kind defines what and how many characters are + * allowed. + * + * ```markdown + * > | a&b + * ^^^ + * > | a{b + * ^^^ + * > | a b + * ^ + * ``` + * + * @type {State} + */ + function value(code) { + if (code === 59 && size) { + const token = effects.exit('characterReferenceValue') + if ( + test === asciiAlphanumeric && + !decodeNamedCharacterReference(self.sliceSerialize(token)) + ) { + return nok(code) + } + + // To do: `markdown-rs` uses a different name: + // `CharacterReferenceMarkerSemi`. + effects.enter('characterReferenceMarker') + effects.consume(code) + effects.exit('characterReferenceMarker') + effects.exit('characterReference') + return ok + } + if (test(code) && size++ < max) { + effects.consume(code) + return value + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/character-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCharacterEscape(effects, ok, nok) { + return start + + /** + * Start of character escape. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('characterEscape') + effects.enter('escapeMarker') + effects.consume(code) + effects.exit('escapeMarker') + return inside + } + + /** + * After `\`, at punctuation. + * + * ```markdown + * > | a\*b + * ^ + * ``` + * + * @type {State} + */ + function inside(code) { + // ASCII punctuation. + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue') + effects.consume(code) + effects.exit('characterEscapeValue') + effects.exit('characterEscape') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/line-ending.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLineEnding(effects, ok) { + return start + + /** @type {State} */ + function start(code) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return factorySpace(effects, ok, 'linePrefix') + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-end.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + + + + + + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +} + +/** @type {Construct} */ +const resourceConstruct = { + tokenize: tokenizeResource +} +/** @type {Construct} */ +const referenceFullConstruct = { + tokenize: tokenizeReferenceFull +} +/** @type {Construct} */ +const referenceCollapsedConstruct = { + tokenize: tokenizeReferenceCollapsed +} + +/** @type {Resolver} */ +function resolveAllLabelEnd(events) { + let index = -1 + while (++index < events.length) { + const token = events[index][1] + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2) + token.type = 'data' + index++ + } + } + return events +} + +/** @type {Resolver} */ +function resolveToLabelEnd(events, context) { + let index = events.length + let offset = 0 + /** @type {Token} */ + let token + /** @type {number | undefined} */ + let open + /** @type {number | undefined} */ + let close + /** @type {Array<Event>} */ + let media + + // Find an opening. + while (index--) { + token = events[index][1] + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } + + // Mark other link openings as inactive, as we can’t have links in + // links. + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index + if (token.type !== 'labelLink') { + offset = 2 + break + } + } + } else if (token.type === 'labelEnd') { + close = index + } + } + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + } + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + } + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + } + media = [ + ['enter', group, context], + ['enter', label, context] + ] + + // Opening marker. + media = push(media, events.slice(open + 1, open + offset + 3)) + + // Text open. + media = push(media, [['enter', text, context]]) + + // Always populated by defaults. + + // Between. + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ) + + // Text close, marker close, label close. + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]) + + // Reference, resource, or so. + media = push(media, events.slice(close + 1)) + + // Media close. + media = push(media, [['exit', group, context]]) + splice(events, open, events.length, media) + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelEnd(effects, ok, nok) { + const self = this + let index = self.events.length + /** @type {Token} */ + let labelStart + /** @type {boolean} */ + let defined + + // Find an opening. + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1] + break + } + } + return start + + /** + * Start of label end. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ``` + * + * @type {State} + */ + function start(code) { + // If there is not an okay opening. + if (!labelStart) { + return nok(code) + } + + // If the corresponding label (link) start is marked as inactive, + // it means we’d be wrapping a link, like this: + // + // ```markdown + // > | a [b [c](d) e](f) g. + // ^ + // ``` + // + // We can’t have that, so it’s just balanced brackets. + if (labelStart._inactive) { + return labelEndNok(code) + } + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ) + effects.enter('labelEnd') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelEnd') + return after + } + + /** + * After `]`. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function after(code) { + // Note: `markdown-rs` also parses GFM footnotes here, which for us is in + // an extension. + + // Resource (`[asd](fgh)`)? + if (code === 40) { + return effects.attempt( + resourceConstruct, + labelEndOk, + defined ? labelEndOk : labelEndNok + )(code) + } + + // Full (`[asd][fgh]`) or collapsed (`[asd][]`) reference? + if (code === 91) { + return effects.attempt( + referenceFullConstruct, + labelEndOk, + defined ? referenceNotFull : labelEndNok + )(code) + } + + // Shortcut (`[asd]`) reference? + return defined ? labelEndOk(code) : labelEndNok(code) + } + + /** + * After `]`, at `[`, but not at a full reference. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function referenceNotFull(code) { + return effects.attempt( + referenceCollapsedConstruct, + labelEndOk, + labelEndNok + )(code) + } + + /** + * Done, we found something. + * + * ```markdown + * > | [a](b) c + * ^ + * > | [a][b] c + * ^ + * > | [a][] b + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndOk(code) { + // Note: `markdown-rs` does a bunch of stuff here. + return ok(code) + } + + /** + * Done, it’s nothing. + * + * There was an okay opening, but we didn’t match anything. + * + * ```markdown + * > | [a](b c + * ^ + * > | [a][b c + * ^ + * > | [a] b + * ^ + * ``` + * + * @type {State} + */ + function labelEndNok(code) { + labelStart._balanced = true + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeResource(effects, ok, nok) { + return resourceStart + + /** + * At a resource. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceStart(code) { + effects.enter('resource') + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + return resourceBefore + } + + /** + * In resource, after `(`, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBefore(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceOpen)(code) + : resourceOpen(code) + } + + /** + * In resource, after optional whitespace, at `)` or a destination. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceOpen(code) { + if (code === 41) { + return resourceEnd(code) + } + return factoryDestination( + effects, + resourceDestinationAfter, + resourceDestinationMissing, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 32 + )(code) + } + + /** + * In resource, after destination, at optional whitespace. + * + * ```markdown + * > | [a](b) c + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceBetween)(code) + : resourceEnd(code) + } + + /** + * At invalid destination. + * + * ```markdown + * > | [a](<<) b + * ^ + * ``` + * + * @type {State} + */ + function resourceDestinationMissing(code) { + return nok(code) + } + + /** + * In resource, after destination and whitespace, at `(` or title. + * + * ```markdown + * > | [a](b ) c + * ^ + * ``` + * + * @type {State} + */ + function resourceBetween(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + resourceTitleAfter, + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + return resourceEnd(code) + } + + /** + * In resource, after title, at optional whitespace. + * + * ```markdown + * > | [a](b "c") d + * ^ + * ``` + * + * @type {State} + */ + function resourceTitleAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, resourceEnd)(code) + : resourceEnd(code) + } + + /** + * In resource, at `)`. + * + * ```markdown + * > | [a](b) d + * ^ + * ``` + * + * @type {State} + */ + function resourceEnd(code) { + if (code === 41) { + effects.enter('resourceMarker') + effects.consume(code) + effects.exit('resourceMarker') + effects.exit('resource') + return ok + } + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceFull(effects, ok, nok) { + const self = this + return referenceFull + + /** + * In a reference (full), at the `[`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFull(code) { + return factoryLabel.call( + self, + effects, + referenceFullAfter, + referenceFullMissing, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + + /** + * In a reference (full), after `]`. + * + * ```markdown + * > | [a][b] d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullAfter(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } + + /** + * In reference (full) that was missing. + * + * ```markdown + * > | [a][b d + * ^ + * ``` + * + * @type {State} + */ + function referenceFullMissing(code) { + return nok(code) + } +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeReferenceCollapsed(effects, ok, nok) { + return referenceCollapsedStart + + /** + * In reference (collapsed), at `[`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedStart(code) { + // We only attempt a collapsed label if there’s a `[`. + + effects.enter('reference') + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + return referenceCollapsedOpen + } + + /** + * In reference (collapsed), at `]`. + * + * > 👉 **Note**: we only get here if the label is defined. + * + * ```markdown + * > | [a][] d + * ^ + * ``` + * + * @type {State} + */ + function referenceCollapsedOpen(code) { + if (code === 93) { + effects.enter('referenceMarker') + effects.consume(code) + effects.exit('referenceMarker') + effects.exit('reference') + return ok + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-image.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (image) start. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelImage') + effects.enter('labelImageMarker') + effects.consume(code) + effects.exit('labelImageMarker') + return open + } + + /** + * After `!`, at `[`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 91) { + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelImage') + return after + } + return nok(code) + } + + /** + * After `![`. + * + * ```markdown + * > | a ![b] c + * ^ + * ``` + * + * This is needed in because, when GFM footnotes are enabled, images never + * form when started with a `^`. + * Instead, links form: + * + * ```markdown + * ![^a](b) + * + * ![^a][b] + * + * [b]: c + * ``` + * + * ```html + * <p>!<a href=\"b\">^a</a></p> + * <p>!<a href=\"c\">^a</a></p> + * ``` + * + * @type {State} + */ + function after(code) { + // To do: use a new field to do this, this is still needed for + // `micromark-extension-gfm-footnote`, but the `label-start-link` + // behavior isn’t. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-classify-character/index.js +/** + * @typedef {import('micromark-util-types').Code} Code + */ + + +/** + * Classify whether a code represents whitespace, punctuation, or something + * else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * > 👉 **Note**: eof (`null`) is seen as whitespace. + * + * @param {Code} code + * Code. + * @returns {typeof constants.characterGroupWhitespace | typeof constants.characterGroupPunctuation | undefined} + * Group. + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + if (unicodePunctuation(code)) { + return 2 + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/attention.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +} + +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ +function resolveAllAttention(events, context) { + let index = -1 + /** @type {number} */ + let open + /** @type {Token} */ + let group + /** @type {Token} */ + let text + /** @type {Token} */ + let openingSequence + /** @type {Token} */ + let closingSequence + /** @type {number} */ + let use + /** @type {Array<Event>} */ + let nextEvents + /** @type {number} */ + let offset + + // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index + + // Now walk back to find an opener. + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && + // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } + + // Number of markers to use from the sequence. + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1 + const start = Object.assign({}, events[open][1].end) + const end = Object.assign({}, events[index][1].start) + movePoint(start, -use) + movePoint(end, use) + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + } + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + } + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + } + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + } + events[open][1].end = Object.assign({}, openingSequence.start) + events[index][1].start = Object.assign({}, closingSequence.end) + nextEvents = [] + + // If there are more markers in the opening, add them before. + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]) + } + + // Opening. + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]) + + // Always populated by defaults. + + // Between. + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ) + + // Closing. + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]) + + // If there are more markers in the closing, add them after. + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2 + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]) + } else { + offset = 0 + } + splice(events, open - 1, index - open + 3, nextEvents) + index = open + nextEvents.length - offset - 2 + break + } + } + } + } + + // Remove remaining sequences. + index = -1 + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data' + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null + const previous = this.previous + const before = classifyCharacter(previous) + + /** @type {NonNullable<Code>} */ + let marker + return start + + /** + * Before a sequence. + * + * ```markdown + * > | ** + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + marker = code + effects.enter('attentionSequence') + return inside(code) + } + + /** + * In a sequence. + * + * ```markdown + * > | ** + * ^^ + * ``` + * + * @type {State} + */ + function inside(code) { + if (code === marker) { + effects.consume(code) + return inside + } + const token = effects.exit('attentionSequence') + + // To do: next major: move this to resolver, just like `markdown-rs`. + const after = classifyCharacter(code) + + // Always populated by defaults. + + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code) + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous) + token._open = Boolean(marker === 42 ? open : open && (before || !close)) + token._close = Boolean(marker === 42 ? close : close && (after || !open)) + return ok(code) + } +} + +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ +function movePoint(point, offset) { + point.column += offset + point.offset += offset + point._bufferIndex += offset +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/autolink.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeAutolink(effects, ok, nok) { + let size = 0 + return start + + /** + * Start of an autolink. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('autolink') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.enter('autolinkProtocol') + return open + } + + /** + * After `<`, at protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code) + return schemeOrEmailAtext + } + return emailAtext(code) + } + + /** + * At second byte of protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeOrEmailAtext(code) { + // ASCII alphanumeric and `+`, `-`, and `.`. + if (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) { + // Count the previous alphabetical from `open` too. + size = 1 + return schemeInsideOrEmailAtext(code) + } + return emailAtext(code) + } + + /** + * In ambiguous protocol or atext. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * > | a<user@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code) + size = 0 + return urlInside + } + + // ASCII alphanumeric and `+`, `-`, and `.`. + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code) + return schemeInsideOrEmailAtext + } + size = 0 + return emailAtext(code) + } + + /** + * After protocol, in URL. + * + * ```markdown + * > | a<https://example.com>b + * ^ + * ``` + * + * @type {State} + */ + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol') + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + + // ASCII control, space, or `<`. + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + effects.consume(code) + return urlInside + } + + /** + * In email atext. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailAtext(code) { + if (code === 64) { + effects.consume(code) + return emailAtSignOrDot + } + if (asciiAtext(code)) { + effects.consume(code) + return emailAtext + } + return nok(code) + } + + /** + * In label, after at-sign or dot. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ ^ + * ``` + * + * @type {State} + */ + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + + /** + * In label, where `.` and `>` are allowed. + * + * ```markdown + * > | a<user.name@example.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailLabel(code) { + if (code === 46) { + effects.consume(code) + size = 0 + return emailAtSignOrDot + } + if (code === 62) { + // Exit, then change the token type. + effects.exit('autolinkProtocol').type = 'autolinkEmail' + effects.enter('autolinkMarker') + effects.consume(code) + effects.exit('autolinkMarker') + effects.exit('autolink') + return ok + } + return emailValue(code) + } + + /** + * In label, where `.` and `>` are *not* allowed. + * + * Though, this is also used in `emailLabel` to parse other values. + * + * ```markdown + * > | a<user.name@ex-ample.com>b + * ^ + * ``` + * + * @type {State} + */ + function emailValue(code) { + // ASCII alphanumeric or `-`. + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + const next = code === 45 ? emailValue : emailLabel + effects.consume(code) + return next + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/html-text.js +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHtmlText(effects, ok, nok) { + const self = this + /** @type {NonNullable<Code> | undefined} */ + let marker + /** @type {number} */ + let index + /** @type {State} */ + let returnState + return start + + /** + * Start of HTML (text). + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('htmlText') + effects.enter('htmlTextData') + effects.consume(code) + return open + } + + /** + * After `<`, at tag name or other stuff. + * + * ```markdown + * > | a <b> c + * ^ + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function open(code) { + if (code === 33) { + effects.consume(code) + return declarationOpen + } + if (code === 47) { + effects.consume(code) + return tagCloseStart + } + if (code === 63) { + effects.consume(code) + return instruction + } + + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagOpen + } + return nok(code) + } + + /** + * After `<!`, at declaration, comment, or CDATA. + * + * ```markdown + * > | a <!doctype> c + * ^ + * > | a <!--b--> c + * ^ + * > | a <![CDATA[>&<]]> c + * ^ + * ``` + * + * @type {State} + */ + function declarationOpen(code) { + if (code === 45) { + effects.consume(code) + return commentOpenInside + } + if (code === 91) { + effects.consume(code) + index = 0 + return cdataOpenInside + } + if (asciiAlpha(code)) { + effects.consume(code) + return declaration + } + return nok(code) + } + + /** + * In a comment, after `<!-`, at another `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return nok(code) + } + + /** + * In comment. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function comment(code) { + if (code === null) { + return nok(code) + } + if (code === 45) { + effects.consume(code) + return commentClose + } + if (markdownLineEnding(code)) { + returnState = comment + return lineEndingBefore(code) + } + effects.consume(code) + return comment + } + + /** + * In comment, after `-`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentClose(code) { + if (code === 45) { + effects.consume(code) + return commentEnd + } + return comment(code) + } + + /** + * In comment, after `--`. + * + * ```markdown + * > | a <!--b--> c + * ^ + * ``` + * + * @type {State} + */ + function commentEnd(code) { + return code === 62 + ? end(code) + : code === 45 + ? commentClose(code) + : comment(code) + } + + /** + * After `<![`, in CDATA, expecting `CDATA[`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^^^^ + * ``` + * + * @type {State} + */ + function cdataOpenInside(code) { + const value = 'CDATA[' + if (code === value.charCodeAt(index++)) { + effects.consume(code) + return index === value.length ? cdata : cdataOpenInside + } + return nok(code) + } + + /** + * In CDATA. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^^^ + * ``` + * + * @type {State} + */ + function cdata(code) { + if (code === null) { + return nok(code) + } + if (code === 93) { + effects.consume(code) + return cdataClose + } + if (markdownLineEnding(code)) { + returnState = cdata + return lineEndingBefore(code) + } + effects.consume(code) + return cdata + } + + /** + * In CDATA, after `]`, at another `]`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataClose(code) { + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In CDATA, after `]]`, at `>`. + * + * ```markdown + * > | a <![CDATA[>&<]]> b + * ^ + * ``` + * + * @type {State} + */ + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + if (code === 93) { + effects.consume(code) + return cdataEnd + } + return cdata(code) + } + + /** + * In declaration. + * + * ```markdown + * > | a <!b> c + * ^ + * ``` + * + * @type {State} + */ + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + if (markdownLineEnding(code)) { + returnState = declaration + return lineEndingBefore(code) + } + effects.consume(code) + return declaration + } + + /** + * In instruction. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instruction(code) { + if (code === null) { + return nok(code) + } + if (code === 63) { + effects.consume(code) + return instructionClose + } + if (markdownLineEnding(code)) { + returnState = instruction + return lineEndingBefore(code) + } + effects.consume(code) + return instruction + } + + /** + * In instruction, after `?`, at `>`. + * + * ```markdown + * > | a <?b?> c + * ^ + * ``` + * + * @type {State} + */ + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + + /** + * After `</`, in closing tag, at tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseStart(code) { + // ASCII alphabetical. + if (asciiAlpha(code)) { + effects.consume(code) + return tagClose + } + return nok(code) + } + + /** + * After `</x`, in a tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagClose(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagClose + } + return tagCloseBetween(code) + } + + /** + * In closing tag, after tag name. + * + * ```markdown + * > | a </b> c + * ^ + * ``` + * + * @type {State} + */ + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagCloseBetween + } + return end(code) + } + + /** + * After `<x`, in opening tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpen(code) { + // ASCII alphanumerical and `-`. + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code) + return tagOpen + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In opening tag, after tag name. + * + * ```markdown + * > | a <b> c + * ^ + * ``` + * + * @type {State} + */ + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code) + return end + } + + // ASCII alphabetical and `:` and `_`. + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code) + return tagOpenAttributeName + } + if (markdownLineEnding(code)) { + returnState = tagOpenBetween + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenBetween + } + return end(code) + } + + /** + * In attribute name. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeName(code) { + // ASCII alphabetical and `-`, `.`, `:`, and `_`. + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code) + return tagOpenAttributeName + } + return tagOpenAttributeNameAfter(code) + } + + /** + * After attribute name, before initializer, the end of the tag, or + * whitespace. + * + * ```markdown + * > | a <b c> d + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeNameAfter + } + return tagOpenBetween(code) + } + + /** + * Before unquoted, double quoted, or single quoted attribute value, allowing + * whitespace. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + if (code === 34 || code === 39) { + effects.consume(code) + marker = code + return tagOpenAttributeValueQuoted + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore + return lineEndingBefore(code) + } + if (markdownSpace(code)) { + effects.consume(code) + return tagOpenAttributeValueBefore + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * In double or single quoted attribute value. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code) + marker = undefined + return tagOpenAttributeValueQuotedAfter + } + if (code === null) { + return nok(code) + } + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted + return lineEndingBefore(code) + } + effects.consume(code) + return tagOpenAttributeValueQuoted + } + + /** + * In unquoted attribute value. + * + * ```markdown + * > | a <b c=d> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + effects.consume(code) + return tagOpenAttributeValueUnquoted + } + + /** + * After double or single quoted attribute value, before whitespace or the end + * of the tag. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + return nok(code) + } + + /** + * In certain circumstances of a tag where only an `>` is allowed. + * + * ```markdown + * > | a <b c="d"> e + * ^ + * ``` + * + * @type {State} + */ + function end(code) { + if (code === 62) { + effects.consume(code) + effects.exit('htmlTextData') + effects.exit('htmlText') + return ok + } + return nok(code) + } + + /** + * At eol. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * > | a <!--a + * ^ + * | b--> + * ``` + * + * @type {State} + */ + function lineEndingBefore(code) { + effects.exit('htmlTextData') + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return lineEndingAfter + } + + /** + * After eol, at optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfter(code) { + // Always populated by defaults. + + return markdownSpace(code) + ? factorySpace( + effects, + lineEndingAfterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + : lineEndingAfterPrefix(code) + } + + /** + * After eol, after optional whitespace. + * + * > 👉 **Note**: we can’t have blank lines in text, so no need to worry about + * > empty tokens. + * + * ```markdown + * | a <!--a + * > | b--> + * ^ + * ``` + * + * @type {State} + */ + function lineEndingAfterPrefix(code) { + effects.enter('htmlTextData') + return returnState(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/label-start-link.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + + +/** @type {Construct} */ +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this + return start + + /** + * Start of label (link) start. + * + * ```markdown + * > | a [b] c + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('labelLink') + effects.enter('labelMarker') + effects.consume(code) + effects.exit('labelMarker') + effects.exit('labelLink') + return after + } + + /** @type {State} */ + function after(code) { + // To do: this isn’t needed in `micromark-extension-gfm-footnote`, + // remove. + // Hidden footnotes hook. + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/hard-break-escape.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + + /** + * Start of a hard break (escape). + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('hardBreakEscape') + effects.consume(code) + return after + } + + /** + * After `\`, at eol. + * + * ```markdown + * > | a\ + * ^ + * | b + * ``` + * + * @type {State} + */ + function after(code) { + if (markdownLineEnding(code)) { + effects.exit('hardBreakEscape') + return ok(code) + } + return nok(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-core-commonmark/lib/code-text.js +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + */ + + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous +} + +// To do: next major: don’t resolve, like `markdown-rs`. +/** @type {Resolver} */ +function resolveCodeText(events) { + let tailExitIndex = events.length - 4 + let headEnterIndex = 3 + /** @type {number} */ + let index + /** @type {number | undefined} */ + let enter + + // If we start and end with an EOL or a space. + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex + + // And we have data. + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding' + events[tailExitIndex][1].type = 'codeTextPadding' + headEnterIndex += 2 + tailExitIndex -= 2 + break + } + } + } + + // Merge adjacent spaces and data. + index = headEnterIndex - 1 + tailExitIndex++ + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData' + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end + events.splice(enter + 2, index - enter - 2) + tailExitIndex -= index - enter - 2 + index = enter + 2 + } + enter = undefined + } + } + return events +} + +/** + * @this {TokenizeContext} + * @type {Previous} + */ +function previous(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} + +/** + * @this {TokenizeContext} + * @type {Tokenizer} + */ +function tokenizeCodeText(effects, ok, nok) { + const self = this + let sizeOpen = 0 + /** @type {number} */ + let size + /** @type {Token} */ + let token + return start + + /** + * Start of code (text). + * + * ```markdown + * > | `a` + * ^ + * > | \`a` + * ^ + * ``` + * + * @type {State} + */ + function start(code) { + effects.enter('codeText') + effects.enter('codeTextSequence') + return sequenceOpen(code) + } + + /** + * In opening sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceOpen(code) { + if (code === 96) { + effects.consume(code) + sizeOpen++ + return sequenceOpen + } + effects.exit('codeTextSequence') + return between(code) + } + + /** + * Between something and something else. + * + * ```markdown + * > | `a` + * ^^ + * ``` + * + * @type {State} + */ + function between(code) { + // EOF. + if (code === null) { + return nok(code) + } + + // To do: next major: don’t do spaces in resolve, but when compiling, + // like `markdown-rs`. + // Tabs don’t work, and virtual spaces don’t make sense. + if (code === 32) { + effects.enter('space') + effects.consume(code) + effects.exit('space') + return between + } + + // Closing fence? Could also be data. + if (code === 96) { + token = effects.enter('codeTextSequence') + size = 0 + return sequenceClose(code) + } + if (markdownLineEnding(code)) { + effects.enter('lineEnding') + effects.consume(code) + effects.exit('lineEnding') + return between + } + + // Data. + effects.enter('codeTextData') + return data(code) + } + + /** + * In data. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData') + return between(code) + } + effects.consume(code) + return data + } + + /** + * In closing sequence. + * + * ```markdown + * > | `a` + * ^ + * ``` + * + * @type {State} + */ + function sequenceClose(code) { + // More. + if (code === 96) { + effects.consume(code) + size++ + return sequenceClose + } + + // Done! + if (size === sizeOpen) { + effects.exit('codeTextSequence') + effects.exit('codeText') + return ok(code) + } + + // More or less accents: mark as data. + token.type = 'codeTextData' + return data(code) + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/constructs.js +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ + + + + +/** @satisfies {Extension['document']} */ +const constructs_document = { + [42]: list, + [43]: list, + [45]: list, + [48]: list, + [49]: list, + [50]: list, + [51]: list, + [52]: list, + [53]: list, + [54]: list, + [55]: list, + [56]: list, + [57]: list, + [62]: blockQuote +} + +/** @satisfies {Extension['contentInitial']} */ +const contentInitial = { + [91]: definition +} + +/** @satisfies {Extension['flowInitial']} */ +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +} + +/** @satisfies {Extension['flow']} */ +const constructs_flow = { + [35]: headingAtx, + [42]: thematicBreak, + [45]: [setextUnderline, thematicBreak], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak, + [96]: codeFenced, + [126]: codeFenced +} + +/** @satisfies {Extension['string']} */ +const constructs_string = { + [38]: characterReference, + [92]: characterEscape +} + +/** @satisfies {Extension['text']} */ +const constructs_text = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +} + +/** @satisfies {Extension['insideSpan']} */ +const insideSpan = { + null: [attention, resolver] +} + +/** @satisfies {Extension['attentionMarkers']} */ +const attentionMarkers = { + null: [42, 95] +} + +/** @satisfies {Extension['disable']} */ +const disable = { + null: [] +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/parse.js +/** + * @typedef {import('micromark-util-types').Create} Create + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + */ + + + + + + + + + +/** + * @param {ParseOptions | null | undefined} [options] + * @returns {ParseContext} + */ +function parse(options) { + const settings = options || {} + const constructs = + /** @type {FullNormalizedExtension} */ + combineExtensions([constructs_namespaceObject, ...(settings.extensions || [])]) + + /** @type {ParseContext} */ + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content), + document: create(document_document), + flow: create(flow), + string: create(string), + text: create(text_text) + } + return parser + + /** + * @param {InitialConstruct} initial + */ + function create(initial) { + return creator + /** @type {Create} */ + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/preprocess.js +/** + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding | null | undefined} [encoding] + * @param {boolean | null | undefined} [end=false] + * @returns {Array<Chunk>} + */ + +const search = /[\0\t\n\r]/g + +/** + * @returns {Preprocessor} + */ +function preprocess() { + let column = 1 + let buffer = '' + /** @type {boolean | undefined} */ + let start = true + /** @type {boolean | undefined} */ + let atCarriageReturn + return preprocessor + + /** @type {Preprocessor} */ + function preprocessor(value, encoding, end) { + /** @type {Array<Chunk>} */ + const chunks = [] + /** @type {RegExpMatchArray | null} */ + let match + /** @type {number} */ + let next + /** @type {number} */ + let startPosition + /** @type {number} */ + let endPosition + /** @type {Code} */ + let code + + // @ts-expect-error `Buffer` does allow an encoding. + value = buffer + value.toString(encoding) + startPosition = 0 + buffer = '' + if (start) { + // To do: `markdown-rs` actually parses BOMs (byte order mark). + if (value.charCodeAt(0) === 65279) { + startPosition++ + } + start = undefined + } + while (startPosition < value.length) { + search.lastIndex = startPosition + match = search.exec(value) + endPosition = + match && match.index !== undefined ? match.index : value.length + code = value.charCodeAt(endPosition) + if (!match) { + buffer = value.slice(startPosition) + break + } + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3) + atCarriageReturn = undefined + } else { + if (atCarriageReturn) { + chunks.push(-5) + atCarriageReturn = undefined + } + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)) + column += endPosition - startPosition + } + switch (code) { + case 0: { + chunks.push(65533) + column++ + break + } + case 9: { + next = Math.ceil(column / 4) * 4 + chunks.push(-2) + while (column++ < next) chunks.push(-1) + break + } + case 10: { + chunks.push(-4) + column = 1 + break + } + default: { + atCarriageReturn = true + column = 1 + } + } + } + startPosition = endPosition + 1 + } + if (end) { + if (atCarriageReturn) chunks.push(-5) + if (buffer) chunks.push(buffer) + chunks.push(null) + } + return chunks + } +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark/lib/postprocess.js +/** + * @typedef {import('micromark-util-types').Event} Event + */ + + + +/** + * @param {Array<Event>} events + * @returns {Array<Event>} + */ +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + return events +} + +;// CONCATENATED MODULE: ./node_modules/micromark-util-decode-numeric-character-reference/index.js +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * Sort of like `String.fromCharCode(Number.parseInt(value, base))`, but makes + * non-characters and control characters safe. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + * Character. + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base) + if ( + // C0 except for HT, LF, FF, CR, space. + code < 9 || + code === 11 || + (code > 13 && code < 32) || + // Control character (DEL) of C0, and C1 controls. + (code > 126 && code < 160) || + // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || + // Noncharacters. + (code > 64975 && code < 65008) /* eslint-disable no-bitwise */ || + (code & 65535) === 65535 || + (code & 65535) === 65534 /* eslint-enable no-bitwise */ || + // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + return String.fromCharCode(code) +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/micromark-util-decode-string/index.js + + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi + +/** + * Decode markdown strings (which occur in places such as fenced code info + * strings, destinations, labels, and titles). + * + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * Value to decode. + * @returns {string} + * Decoded value. + */ +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} + +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } + + // Reference. + const head = $2.charCodeAt(0) + if (head === 35) { + const head = $2.charCodeAt(1) + const hex = head === 120 || head === 88 + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + return decodeNamedCharacterReference($2) || $0 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/unist-util-stringify-position/lib/index.js +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +;// CONCATENATED MODULE: ./node_modules/mermaid/node_modules/mdast-util-from-markdown/lib/index.js +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').StaticPhrasingContent} StaticPhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * @typedef {import('mdast').ReferenceType} ReferenceType + * @typedef {import('../index.js').CompileData} CompileData + */ + +/** + * @typedef {Root | Content} Node + * @typedef {Extract<Node, UnistParent>} Parent + * + * @typedef {Omit<UnistParent, 'type' | 'children'> & {type: 'fragment', children: Array<PhrasingContent>}} Fragment + */ + +/** + * @callback Transform + * Extra transform, to change the AST afterwards. + * @param {Root} tree + * Tree to transform. + * @returns {Root | undefined | null | void} + * New tree or nothing (in which case the current tree is used). + * + * @callback Handle + * Handle a token. + * @param {CompileContext} this + * Context. + * @param {Token} token + * Current token. + * @returns {void} + * Nothing. + * + * @typedef {Record<string, Handle>} Handles + * Token types mapping to handles + * + * @callback OnEnterError + * Handle the case where the `right` token is open, but it is closed (by the + * `left` token) or because we reached the end of the document. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token | undefined} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @callback OnExitError + * Handle the case where the `right` token is open but it is closed by + * exiting the `left` token. + * @param {Omit<CompileContext, 'sliceSerialize'>} this + * Context. + * @param {Token} left + * Left token. + * @param {Token} right + * Right token. + * @returns {void} + * Nothing. + * + * @typedef {[Token, OnEnterError | undefined]} TokenTuple + * Open token on the stack, with an optional error handler for when + * that token isn’t closed properly. + */ + +/** + * @typedef Config + * Configuration. + * + * We have our defaults, but extensions will add more. + * @property {Array<string>} canContainEols + * Token types where line endings are used. + * @property {Handles} enter + * Opening handles. + * @property {Handles} exit + * Closing handles. + * @property {Array<Transform>} transforms + * Tree transforms. + * + * @typedef {Partial<Config>} Extension + * Change how markdown tokens from micromark are turned into mdast. + * + * @typedef CompileContext + * mdast compiler context. + * @property {Array<Node | Fragment>} stack + * Stack of nodes. + * @property {Array<TokenTuple>} tokenStack + * Stack of tokens. + * @property {<Key extends keyof CompileData>(key: Key) => CompileData[Key]} getData + * Get data from the key/value store. + * @property {<Key extends keyof CompileData>(key: Key, value?: CompileData[Key]) => void} setData + * Set data into the key/value store. + * @property {(this: CompileContext) => void} buffer + * Capture some of the output data. + * @property {(this: CompileContext) => string} resume + * Stop capturing and access the output data. + * @property {<Kind extends Node>(this: CompileContext, node: Kind, token: Token, onError?: OnEnterError) => Kind} enter + * Enter a token. + * @property {(this: CompileContext, token: Token, onError?: OnExitError) => Node} exit + * Exit a token. + * @property {TokenizeContext['sliceSerialize']} sliceSerialize + * Get the string value of a token. + * @property {Config} config + * Configuration. + * + * @typedef FromMarkdownOptions + * Configuration for how to build mdast. + * @property {Array<Extension | Array<Extension>> | null | undefined} [mdastExtensions] + * Extensions for this utility to change how tokens are turned into a tree. + * + * @typedef {ParseOptions & FromMarkdownOptions} Options + * Configuration. + */ + +// To do: micromark: create a registry of tokens? +// To do: next major: don’t return given `Node` from `enter`. +// To do: next major: remove setter/getter. + + + + + + + + + + +const lib_own = {}.hasOwnProperty + +/** + * @param value + * Markdown to parse. + * @param encoding + * Character encoding for when `value` is `Buffer`. + * @param options + * Configuration. + * @returns + * mdast tree. + */ +const fromMarkdown = + /** + * @type {( + * ((value: Value, encoding: Encoding, options?: Options | null | undefined) => Root) & + * ((value: Value, options?: Options | null | undefined) => Root) + * )} + */ + + /** + * @param {Value} value + * @param {Encoding | Options | null | undefined} [encoding] + * @param {Options | null | undefined} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding + encoding = undefined + } + return compiler(options)( + postprocess( + parse(options).document().write(preprocess()(value, encoding, true)) + ) + ) + } + +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options | null | undefined} [options] + */ +function compiler(options) { + /** @type {Config} */ + const config = { + transforms: [], + canContainEols: ['emphasis', 'fragment', 'heading', 'paragraph', 'strong'], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + } + configure(config, (options || {}).mdastExtensions || []) + + /** @type {CompileData} */ + const data = {} + return compile + + /** + * Turn micromark events into an mdast tree. + * + * @param {Array<Event>} events + * Events. + * @returns {Root} + * mdast tree. + */ + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + } + /** @type {Omit<CompileContext, 'sliceSerialize'>} */ + const context = { + stack: [tree], + tokenStack: [], + config, + enter, + exit, + buffer, + resume, + setData, + getData + } + /** @type {Array<number>} */ + const listStack = [] + let index = -1 + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index) + } else { + const tail = listStack.pop() + index = prepareList(events, tail, index) + } + } + } + index = -1 + while (++index < events.length) { + const handler = config[events[index][0]] + if (lib_own.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ) + } + } + + // Handle tokens still being open. + if (context.tokenStack.length > 0) { + const tail = context.tokenStack[context.tokenStack.length - 1] + const handler = tail[1] || defaultOnError + handler.call(context, undefined, tail[0]) + } + + // Figure out `root` position. + tree.position = { + start: lib_point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: lib_point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + } + + // Call transforms. + index = -1 + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree + } + return tree + } + + /** + * @param {Array<Event>} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + function prepareList(events, start, length) { + let index = start - 1 + let containerBalance = -1 + let listSpread = false + /** @type {Token | undefined} */ + let listItem + /** @type {number | undefined} */ + let lineIndex + /** @type {number | undefined} */ + let firstBlankLineIndex + /** @type {boolean | undefined} */ + let atMarker + while (++index <= length) { + const event = events[index] + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++ + } else { + containerBalance-- + } + atMarker = undefined + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index + } + atMarker = undefined + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) { + // Empty. + } else { + atMarker = undefined + } + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index + lineIndex = undefined + while (tailIndex--) { + const tailEvent = events[tailIndex] + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank' + listSpread = true + } + tailEvent[1].type = 'lineEnding' + lineIndex = tailIndex + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) { + // Empty + } else { + break + } + } + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + listItem._spread = true + } + + // Fix position. + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ) + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]) + index++ + length++ + } + + // Create a new list item. + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + _spread: false, + start: Object.assign({}, event[1].start), + // @ts-expect-error: we’ll add `end` in a second. + end: undefined + } + // @ts-expect-error: `listItem` is most definitely defined, TS... + events.splice(index, 0, ['enter', listItem, event[2]]) + index++ + length++ + firstBlankLineIndex = undefined + atMarker = true + } + } + } + events[start][1]._spread = listSpread + return length + } + + /** + * Set data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @param {CompileData[Key]} [value] + * New value. + * @returns {void} + * Nothing. + */ + function setData(key, value) { + data[key] = value + } + + /** + * Get data. + * + * @template {keyof CompileData} Key + * Field type. + * @param {Key} key + * Key of field. + * @returns {CompileData[Key]} + * Value. + */ + function getData(key) { + return data[key] + } + + /** + * Create an opener handle. + * + * @param {(token: Token) => Node} create + * Create a node. + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function opener(create, and) { + return open + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function open(token) { + enter.call(this, create(token), token) + if (and) and.call(this, token) + } + } + + /** + * @this {CompileContext} + * @returns {void} + */ + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }) + } + + /** + * @template {Node} Kind + * Node type. + * @this {CompileContext} + * Context. + * @param {Kind} node + * Node to enter. + * @param {Token} token + * Corresponding token. + * @param {OnEnterError | undefined} [errorHandler] + * Handle the case where this token is open, but it is closed by something else. + * @returns {Kind} + * The given node. + */ + function enter(node, token, errorHandler) { + const parent = this.stack[this.stack.length - 1] + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node) + this.stack.push(node) + this.tokenStack.push([token, errorHandler]) + // @ts-expect-error: `end` will be patched later. + node.position = { + start: lib_point(token.start) + } + return node + } + + /** + * Create a closer handle. + * + * @param {Handle} [and] + * Optional function to also run. + * @returns {Handle} + * Handle. + */ + function closer(and) { + return close + + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + function close(token) { + if (and) and.call(this, token) + exit.call(this, token) + } + } + + /** + * @this {CompileContext} + * Context. + * @param {Token} token + * Corresponding token. + * @param {OnExitError | undefined} [onExitError] + * Handle the case where another token is open. + * @returns {Node} + * The closed node. + */ + function exit(token, onExitError) { + const node = this.stack.pop() + const open = this.tokenStack.pop() + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open[0].type !== token.type) { + if (onExitError) { + onExitError.call(this, token, open[0]) + } else { + const handler = open[1] || defaultOnError + handler.call(this, token, open[0]) + } + } + node.position.end = lib_point(token.end) + return node + } + + /** + * @this {CompileContext} + * @returns {string} + */ + function resume() { + return lib_toString(this.stack.pop()) + } + + // + // Handlers. + // + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistordered() { + setData('expectingFirstListItemValue', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2] + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10) + setData('expectingFirstListItemValue') + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfenceinfo() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.lang = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfencemeta() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.meta = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer() + setData('flowCodeInside', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodefenced() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, '') + setData('flowCodeInside') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcodeindented() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data.replace(/(\r?\n|\r)$/g, '') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitionlabelstring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + node.label = label + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiontitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitdefinitiondestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1] + if (!node.depth) { + const depth = this.sliceSerialize(token).length + node.depth = depth + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1] + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2 + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterdata(token) { + const node = this.stack[this.stack.length - 1] + let tail = node.children[node.children.length - 1] + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text() + // @ts-expect-error: we’ll add `end` later. + tail.position = { + start: lib_point(token.start) + } + // @ts-expect-error: Assume `parent` accepts `text`. + node.children.push(tail) + } + this.stack.push(tail) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitdata(token) { + const tail = this.stack.pop() + tail.value += this.sliceSerialize(token) + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1] + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1] + tail.position.end = lib_point(token.end) + setData('atHardBreak') + return + } + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token) + onexitdata.call(this, token) + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithardbreak() { + setData('atHardBreak', true) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmlflow() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexithtmltext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcodetext() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.value = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlink() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitimage() { + const node = this.stack[this.stack.length - 1] + // Note: there are also `identifier` and `label` fields on this link node! + // These are used / cleaned here. + // To do: clean. + if (getData('inReference')) { + /** @type {ReferenceType} */ + const referenceType = getData('referenceType') || 'shortcut' + node.type += 'Reference' + // @ts-expect-error: mutate. + node.referenceType = referenceType + // @ts-expect-error: mutate. + delete node.url + delete node.title + } else { + // @ts-expect-error: mutate. + delete node.identifier + // @ts-expect-error: mutate. + delete node.label + } + setData('referenceType') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabeltext(token) { + const string = this.sliceSerialize(token) + const ancestor = this.stack[this.stack.length - 2] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + ancestor.label = decodeString(string) + // @ts-expect-error: same as above. + ancestor.identifier = normalizeIdentifier(string).toLowerCase() + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1] + const value = this.resume() + const node = this.stack[this.stack.length - 1] + // Assume a reference. + setData('inReference', true) + if (node.type === 'link') { + /** @type {Array<StaticPhrasingContent>} */ + // @ts-expect-error: Assume static phrasing content. + const children = fragment.children + node.children = children + } else { + node.alt = value + } + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcedestinationstring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.url = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresourcetitlestring() { + const data = this.resume() + const node = this.stack[this.stack.length - 1] + node.title = data + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitresource() { + setData('inReference') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onenterreference() { + setData('referenceType', 'collapsed') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitreferencestring(token) { + const label = this.resume() + const node = this.stack[this.stack.length - 1] + // @ts-expect-error: stash this on the node, as it might become a reference + // later. + node.label = label + // @ts-expect-error: same as above. + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase() + setData('referenceType', 'full') + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token) + const type = getData('characterReferenceType') + /** @type {string} */ + let value + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ) + setData('characterReferenceType') + } else { + const result = decodeNamedCharacterReference(data) + value = result + } + const tail = this.stack.pop() + tail.value += value + tail.position.end = lib_point(token.end) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkprotocol(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = this.sliceSerialize(token) + } + + /** + * @this {CompileContext} + * @type {Handle} + */ + function onexitautolinkemail(token) { + onexitdata.call(this, token) + const node = this.stack[this.stack.length - 1] + node.url = 'mailto:' + this.sliceSerialize(token) + } + + // + // Creaters. + // + + /** @returns {Blockquote} */ + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + + /** @returns {Code} */ + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + + /** @returns {InlineCode} */ + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + + /** @returns {Definition} */ + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + + /** @returns {Emphasis} */ + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + + /** @returns {Heading} */ + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + + /** @returns {Break} */ + function hardBreak() { + return { + type: 'break' + } + } + + /** @returns {HTML} */ + function html() { + return { + type: 'html', + value: '' + } + } + + /** @returns {Image} */ + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + + /** @returns {Link} */ + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + + /** + * @param {Token} token + * @returns {List} + */ + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + spread: token._spread, + children: [] + } + } + + /** + * @param {Token} token + * @returns {ListItem} + */ + function listItem(token) { + return { + type: 'listItem', + spread: token._spread, + checked: null, + children: [] + } + } + + /** @returns {Paragraph} */ + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + + /** @returns {Strong} */ + function strong() { + return { + type: 'strong', + children: [] + } + } + + /** @returns {Text} */ + function text() { + return { + type: 'text', + value: '' + } + } + + /** @returns {ThematicBreak} */ + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} + +/** + * Copy a point-like value. + * + * @param {Point} d + * Point-like value. + * @returns {Point} + * unist point. + */ +function lib_point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } +} + +/** + * @param {Config} combined + * @param {Array<Extension | Array<Extension>>} extensions + * @returns {void} + */ +function configure(combined, extensions) { + let index = -1 + while (++index < extensions.length) { + const value = extensions[index] + if (Array.isArray(value)) { + configure(combined, value) + } else { + extension(combined, value) + } + } +} + +/** + * @param {Config} combined + * @param {Extension} extension + * @returns {void} + */ +function extension(combined, extension) { + /** @type {keyof Extension} */ + let key + for (key in extension) { + if (lib_own.call(extension, key)) { + if (key === 'canContainEols') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'transforms') { + const right = extension[key] + if (right) { + combined[key].push(...right) + } + } else if (key === 'enter' || key === 'exit') { + const right = extension[key] + if (right) { + Object.assign(combined[key], right) + } + } + } + } +} + +/** @type {OnEnterError} */ +function defaultOnError(left, right) { + if (left) { + throw new Error( + 'Cannot close `' + + left.type + + '` (' + + stringifyPosition({ + start: left.start, + end: left.end + }) + + '): a different token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is open' + ) + } else { + throw new Error( + 'Cannot close document, a token (`' + + right.type + + '`, ' + + stringifyPosition({ + start: right.start, + end: right.end + }) + + ') is still open' + ) + } +} + +// EXTERNAL MODULE: ./node_modules/ts-dedent/esm/index.js +var esm = __webpack_require__(18464); +;// CONCATENATED MODULE: ./node_modules/mermaid/dist/createText-62fc7601.js + + + +function preprocessMarkdown(markdown) { + const withoutMultipleNewlines = markdown.replace(/\n{2,}/g, "\n"); + const withoutExtraSpaces = (0,esm/* dedent */.Z)(withoutMultipleNewlines); + return withoutExtraSpaces; +} +function markdownToLines(markdown) { + const preprocessedMarkdown = preprocessMarkdown(markdown); + const { children } = fromMarkdown(preprocessedMarkdown); + const lines = [[]]; + let currentLine = 0; + function processNode(node, parentType = "normal") { + if (node.type === "text") { + const textLines = node.value.split("\n"); + textLines.forEach((textLine, index) => { + if (index !== 0) { + currentLine++; + lines.push([]); + } + textLine.split(" ").forEach((word) => { + if (word) { + lines[currentLine].push({ content: word, type: parentType }); + } + }); + }); + } else if (node.type === "strong" || node.type === "emphasis") { + node.children.forEach((contentNode) => { + processNode(contentNode, node.type); + }); + } + } + children.forEach((treeNode) => { + if (treeNode.type === "paragraph") { + treeNode.children.forEach((contentNode) => { + processNode(contentNode); + }); + } + }); + return lines; +} +function markdownToHTML(markdown) { + const { children } = fromMarkdown(markdown); + function output(node) { + if (node.type === "text") { + return node.value.replace(/\n/g, "<br/>"); + } else if (node.type === "strong") { + return `<strong>${node.children.map(output).join("")}</strong>`; + } else if (node.type === "emphasis") { + return `<em>${node.children.map(output).join("")}</em>`; + } else if (node.type === "paragraph") { + return `<p>${node.children.map(output).join("")}</p>`; + } + return `Unsupported markdown: ${node.type}`; + } + return children.map(output).join(""); +} +function splitTextToChars(text) { + if (Intl.Segmenter) { + return [...new Intl.Segmenter().segment(text)].map((s) => s.segment); + } + return [...text]; +} +function splitWordToFitWidth(checkFit, word) { + const characters = splitTextToChars(word.content); + return splitWordToFitWidthRecursion(checkFit, [], characters, word.type); +} +function splitWordToFitWidthRecursion(checkFit, usedChars, remainingChars, type) { + if (remainingChars.length === 0) { + return [ + { content: usedChars.join(""), type }, + { content: "", type } + ]; + } + const [nextChar, ...rest] = remainingChars; + const newWord = [...usedChars, nextChar]; + if (checkFit([{ content: newWord.join(""), type }])) { + return splitWordToFitWidthRecursion(checkFit, newWord, rest, type); + } + if (usedChars.length === 0 && nextChar) { + usedChars.push(nextChar); + remainingChars.shift(); + } + return [ + { content: usedChars.join(""), type }, + { content: remainingChars.join(""), type } + ]; +} +function splitLineToFitWidth(line, checkFit) { + if (line.some(({ content }) => content.includes("\n"))) { + throw new Error("splitLineToFitWidth does not support newlines in the line"); + } + return splitLineToFitWidthRecursion(line, checkFit); +} +function splitLineToFitWidthRecursion(words, checkFit, lines = [], newLine = []) { + if (words.length === 0) { + if (newLine.length > 0) { + lines.push(newLine); + } + return lines.length > 0 ? lines : []; + } + let joiner = ""; + if (words[0].content === " ") { + joiner = " "; + words.shift(); + } + const nextWord = words.shift() ?? { content: " ", type: "normal" }; + const lineWithNextWord = [...newLine]; + if (joiner !== "") { + lineWithNextWord.push({ content: joiner, type: "normal" }); + } + lineWithNextWord.push(nextWord); + if (checkFit(lineWithNextWord)) { + return splitLineToFitWidthRecursion(words, checkFit, lines, lineWithNextWord); + } + if (newLine.length > 0) { + lines.push(newLine); + words.unshift(nextWord); + } else if (nextWord.content) { + const [line, rest] = splitWordToFitWidth(checkFit, nextWord); + lines.push([line]); + if (rest.content) { + words.unshift(rest); + } + } + return splitLineToFitWidthRecursion(words, checkFit, lines); +} +function applyStyle(dom, styleFn) { + if (styleFn) { + dom.attr("style", styleFn); + } +} +function addHtmlSpan(element, node, width, classes, addBackground = false) { + const fo = element.append("foreignObject"); + const div = fo.append("xhtml:div"); + const label = node.label; + const labelClass = node.isNode ? "nodeLabel" : "edgeLabel"; + div.html( + ` + <span class="${labelClass} ${classes}" ` + (node.labelStyle ? 'style="' + node.labelStyle + '"' : "") + ">" + label + "</span>" + ); + applyStyle(div, node.labelStyle); + div.style("display", "table-cell"); + div.style("white-space", "nowrap"); + div.style("max-width", width + "px"); + div.attr("xmlns", "http://www.w3.org/1999/xhtml"); + if (addBackground) { + div.attr("class", "labelBkg"); + } + let bbox = div.node().getBoundingClientRect(); + if (bbox.width === width) { + div.style("display", "table"); + div.style("white-space", "break-spaces"); + div.style("width", width + "px"); + bbox = div.node().getBoundingClientRect(); + } + fo.style("width", bbox.width); + fo.style("height", bbox.height); + return fo.node(); +} +function createTspan(textElement, lineIndex, lineHeight) { + return textElement.append("tspan").attr("class", "text-outer-tspan").attr("x", 0).attr("y", lineIndex * lineHeight - 0.1 + "em").attr("dy", lineHeight + "em"); +} +function computeWidthOfText(parentNode, lineHeight, line) { + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, line); + const textLength = testSpan.node().getComputedTextLength(); + testElement.remove(); + return textLength; +} +function computeDimensionOfText(parentNode, lineHeight, text) { + var _a; + const testElement = parentNode.append("text"); + const testSpan = createTspan(testElement, 1, lineHeight); + updateTextContentAndStyles(testSpan, [{ content: text, type: "normal" }]); + const textDimension = (_a = testSpan.node()) == null ? void 0 : _a.getBoundingClientRect(); + if (textDimension) { + testElement.remove(); + } + return textDimension; +} +function createFormattedText(width, g, structuredText, addBackground = false) { + const lineHeight = 1.1; + const labelGroup = g.append("g"); + const bkg = labelGroup.insert("rect").attr("class", "background"); + const textElement = labelGroup.append("text").attr("y", "-10.1"); + let lineIndex = 0; + for (const line of structuredText) { + const checkWidth = (line2) => computeWidthOfText(labelGroup, lineHeight, line2) <= width; + const linesUnderWidth = checkWidth(line) ? [line] : splitLineToFitWidth(line, checkWidth); + for (const preparedLine of linesUnderWidth) { + const tspan = createTspan(textElement, lineIndex, lineHeight); + updateTextContentAndStyles(tspan, preparedLine); + lineIndex++; + } + } + if (addBackground) { + const bbox = textElement.node().getBBox(); + const padding = 2; + bkg.attr("x", -padding).attr("y", -padding).attr("width", bbox.width + 2 * padding).attr("height", bbox.height + 2 * padding); + return labelGroup.node(); + } else { + return textElement.node(); + } +} +function updateTextContentAndStyles(tspan, wrappedLine) { + tspan.text(""); + wrappedLine.forEach((word, index) => { + const innerTspan = tspan.append("tspan").attr("font-style", word.type === "emphasis" ? "italic" : "normal").attr("class", "text-inner-tspan").attr("font-weight", word.type === "strong" ? "bold" : "normal"); + if (index === 0) { + innerTspan.text(word.content); + } else { + innerTspan.text(" " + word.content); + } + }); +} +const createText = (el, text = "", { + style = "", + isTitle = false, + classes = "", + useHtmlLabels = true, + isNode = true, + width = 200, + addSvgBackground = false +} = {}) => { + mermaid_8af3addd.l.info("createText", text, style, isTitle, classes, useHtmlLabels, isNode, addSvgBackground); + if (useHtmlLabels) { + const htmlText = markdownToHTML(text); + const node = { + isNode, + label: (0,mermaid_8af3addd.J)(htmlText).replace( + /fa[blrs]?:fa-[\w-]+/g, + (s) => `<i class='${s.replace(":", " ")}'></i>` + ), + labelStyle: style.replace("fill:", "color:") + }; + const vertexNode = addHtmlSpan(el, node, width, classes, addSvgBackground); + return vertexNode; + } else { + const structuredText = markdownToLines(text); + const svgLabel = createFormattedText(width, el, structuredText, addSvgBackground); + return svgLabel; + } +}; + + + +/***/ }), + +/***/ 87807: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +"use strict"; +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(56363); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var _createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(64589); +/* harmony import */ var cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(71377); +/* harmony import */ var cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14607); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(91619); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(12281); +/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(7201); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(20683); + + + + + + + + + + + + + + + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 4], $V1 = [1, 13], $V2 = [1, 12], $V3 = [1, 15], $V4 = [1, 16], $V5 = [1, 20], $V6 = [1, 19], $V7 = [6, 7, 8], $V8 = [1, 26], $V9 = [1, 24], $Va = [1, 25], $Vb = [6, 7, 11], $Vc = [1, 6, 13, 15, 16, 19, 22], $Vd = [1, 33], $Ve = [1, 34], $Vf = [1, 6, 7, 11, 13, 15, 16, 19, 22]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "mindMap": 4, "spaceLines": 5, "SPACELINE": 6, "NL": 7, "MINDMAP": 8, "document": 9, "stop": 10, "EOF": 11, "statement": 12, "SPACELIST": 13, "node": 14, "ICON": 15, "CLASS": 16, "nodeWithId": 17, "nodeWithoutId": 18, "NODE_DSTART": 19, "NODE_DESCR": 20, "NODE_DEND": 21, "NODE_ID": 22, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 6: "SPACELINE", 7: "NL", 8: "MINDMAP", 11: "EOF", 13: "SPACELIST", 15: "ICON", 16: "CLASS", 19: "NODE_DSTART", 20: "NODE_DESCR", 21: "NODE_DEND", 22: "NODE_ID" }, + productions_: [0, [3, 1], [3, 2], [5, 1], [5, 2], [5, 2], [4, 2], [4, 3], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [9, 3], [9, 2], [12, 2], [12, 2], [12, 2], [12, 1], [12, 1], [12, 1], [12, 1], [12, 1], [14, 1], [14, 1], [18, 3], [17, 1], [17, 4]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 6: + case 7: + return yy; + case 8: + yy.getLogger().trace("Stop NL "); + break; + case 9: + yy.getLogger().trace("Stop EOF "); + break; + case 11: + yy.getLogger().trace("Stop NL2 "); + break; + case 12: + yy.getLogger().trace("Stop EOF2 "); + break; + case 15: + yy.getLogger().info("Node: ", $$[$0].id); + yy.addNode($$[$0 - 1].length, $$[$0].id, $$[$0].descr, $$[$0].type); + break; + case 16: + yy.getLogger().trace("Icon: ", $$[$0]); + yy.decorateNode({ icon: $$[$0] }); + break; + case 17: + case 21: + yy.decorateNode({ class: $$[$0] }); + break; + case 18: + yy.getLogger().trace("SPACELIST"); + break; + case 19: + yy.getLogger().trace("Node: ", $$[$0].id); + yy.addNode(0, $$[$0].id, $$[$0].descr, $$[$0].type); + break; + case 20: + yy.decorateNode({ icon: $$[$0] }); + break; + case 25: + yy.getLogger().trace("node found ..", $$[$0 - 2]); + this.$ = { id: $$[$0 - 1], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) }; + break; + case 26: + this.$ = { id: $$[$0], descr: $$[$0], type: yy.nodeType.DEFAULT }; + break; + case 27: + yy.getLogger().trace("node found ..", $$[$0 - 3]); + this.$ = { id: $$[$0 - 3], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) }; + break; + } + }, + table: [{ 3: 1, 4: 2, 5: 3, 6: [1, 5], 8: $V0 }, { 1: [3] }, { 1: [2, 1] }, { 4: 6, 6: [1, 7], 7: [1, 8], 8: $V0 }, { 6: $V1, 7: [1, 10], 9: 9, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($V7, [2, 3]), { 1: [2, 2] }, o($V7, [2, 4]), o($V7, [2, 5]), { 1: [2, 6], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V1, 9: 22, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V8, 7: $V9, 10: 23, 11: $Va }, o($Vb, [2, 22], { 17: 17, 18: 18, 14: 27, 15: [1, 28], 16: [1, 29], 19: $V5, 22: $V6 }), o($Vb, [2, 18]), o($Vb, [2, 19]), o($Vb, [2, 20]), o($Vb, [2, 21]), o($Vb, [2, 23]), o($Vb, [2, 24]), o($Vb, [2, 26], { 19: [1, 30] }), { 20: [1, 31] }, { 6: $V8, 7: $V9, 10: 32, 11: $Va }, { 1: [2, 7], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($Vc, [2, 14], { 7: $Vd, 11: $Ve }), o($Vf, [2, 8]), o($Vf, [2, 9]), o($Vf, [2, 10]), o($Vb, [2, 15]), o($Vb, [2, 16]), o($Vb, [2, 17]), { 20: [1, 35] }, { 21: [1, 36] }, o($Vc, [2, 13], { 7: $Vd, 11: $Ve }), o($Vf, [2, 11]), o($Vf, [2, 12]), { 21: [1, 37] }, o($Vb, [2, 25]), o($Vb, [2, 27])], + defaultActions: { 2: [2, 1], 6: [2, 2] }, + parseError: function parseError2(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError2(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + yy.getLogger().trace("Found comment", yy_.yytext); + return 6; + case 1: + return 8; + case 2: + this.begin("CLASS"); + break; + case 3: + this.popState(); + return 16; + case 4: + this.popState(); + break; + case 5: + yy.getLogger().trace("Begin icon"); + this.begin("ICON"); + break; + case 6: + yy.getLogger().trace("SPACELINE"); + return 6; + case 7: + return 7; + case 8: + return 15; + case 9: + yy.getLogger().trace("end icon"); + this.popState(); + break; + case 10: + yy.getLogger().trace("Exploding node"); + this.begin("NODE"); + return 19; + case 11: + yy.getLogger().trace("Cloud"); + this.begin("NODE"); + return 19; + case 12: + yy.getLogger().trace("Explosion Bang"); + this.begin("NODE"); + return 19; + case 13: + yy.getLogger().trace("Cloud Bang"); + this.begin("NODE"); + return 19; + case 14: + this.begin("NODE"); + return 19; + case 15: + this.begin("NODE"); + return 19; + case 16: + this.begin("NODE"); + return 19; + case 17: + this.begin("NODE"); + return 19; + case 18: + return 13; + case 19: + return 22; + case 20: + return 11; + case 21: + this.begin("NSTR2"); + break; + case 22: + return "NODE_DESCR"; + case 23: + this.popState(); + break; + case 24: + yy.getLogger().trace("Starting NSTR"); + this.begin("NSTR"); + break; + case 25: + yy.getLogger().trace("description:", yy_.yytext); + return "NODE_DESCR"; + case 26: + this.popState(); + break; + case 27: + this.popState(); + yy.getLogger().trace("node end ))"); + return "NODE_DEND"; + case 28: + this.popState(); + yy.getLogger().trace("node end )"); + return "NODE_DEND"; + case 29: + this.popState(); + yy.getLogger().trace("node end ...", yy_.yytext); + return "NODE_DEND"; + case 30: + this.popState(); + yy.getLogger().trace("node end (("); + return "NODE_DEND"; + case 31: + this.popState(); + yy.getLogger().trace("node end (-"); + return "NODE_DEND"; + case 32: + this.popState(); + yy.getLogger().trace("node end (-"); + return "NODE_DEND"; + case 33: + this.popState(); + yy.getLogger().trace("node end (("); + return "NODE_DEND"; + case 34: + this.popState(); + yy.getLogger().trace("node end (("); + return "NODE_DEND"; + case 35: + yy.getLogger().trace("Long description:", yy_.yytext); + return 20; + case 36: + yy.getLogger().trace("Long description:", yy_.yytext); + return 20; + } + }, + rules: [/^(?:\s*%%.*)/i, /^(?:mindmap\b)/i, /^(?::::)/i, /^(?:.+)/i, /^(?:\n)/i, /^(?:::icon\()/i, /^(?:[\s]+[\n])/i, /^(?:[\n]+)/i, /^(?:[^\)]+)/i, /^(?:\))/i, /^(?:-\))/i, /^(?:\(-)/i, /^(?:\)\))/i, /^(?:\))/i, /^(?:\(\()/i, /^(?:\{\{)/i, /^(?:\()/i, /^(?:\[)/i, /^(?:[\s]+)/i, /^(?:[^\(\[\n\)\{\}]+)/i, /^(?:$)/i, /^(?:["][`])/i, /^(?:[^`"]+)/i, /^(?:[`]["])/i, /^(?:["])/i, /^(?:[^"]+)/i, /^(?:["])/i, /^(?:[\)]\))/i, /^(?:[\)])/i, /^(?:[\]])/i, /^(?:\}\})/i, /^(?:\(-)/i, /^(?:-\))/i, /^(?:\(\()/i, /^(?:\()/i, /^(?:[^\)\]\(\}]+)/i, /^(?:.+(?!\(\())/i], + conditions: { "CLASS": { "rules": [3, 4], "inclusive": false }, "ICON": { "rules": [8, 9], "inclusive": false }, "NSTR2": { "rules": [22, 23], "inclusive": false }, "NSTR": { "rules": [25, 26], "inclusive": false }, "NODE": { "rules": [21, 24, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const mindmapParser = parser; +const sanitizeText = (text) => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.d)(text, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)()); +let nodes = []; +let cnt = 0; +let elements = {}; +const clear = () => { + nodes = []; + cnt = 0; + elements = {}; +}; +const getParent = function(level) { + for (let i = nodes.length - 1; i >= 0; i--) { + if (nodes[i].level < level) { + return nodes[i]; + } + } + return null; +}; +const getMindmap = () => { + return nodes.length > 0 ? nodes[0] : null; +}; +const addNode = (level, id, descr, type) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("addNode", level, id, descr, type); + const conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)(); + const node = { + id: cnt++, + nodeId: sanitizeText(id), + level, + descr: sanitizeText(descr), + type, + children: [], + width: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().mindmap.maxNodeWidth + }; + switch (node.type) { + case nodeType.ROUNDED_RECT: + node.padding = 2 * conf.mindmap.padding; + break; + case nodeType.RECT: + node.padding = 2 * conf.mindmap.padding; + break; + case nodeType.HEXAGON: + node.padding = 2 * conf.mindmap.padding; + break; + default: + node.padding = conf.mindmap.padding; + } + const parent = getParent(level); + if (parent) { + parent.children.push(node); + nodes.push(node); + } else { + if (nodes.length === 0) { + nodes.push(node); + } else { + let error = new Error( + 'There can be only one root. No parent could be found for ("' + node.descr + '")' + ); + error.hash = { + text: "branch " + name, + token: "branch " + name, + line: "1", + loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 }, + expected: ['"checkout ' + name + '"'] + }; + throw error; + } + } +}; +const nodeType = { + DEFAULT: 0, + NO_BORDER: 0, + ROUNDED_RECT: 1, + RECT: 2, + CIRCLE: 3, + CLOUD: 4, + BANG: 5, + HEXAGON: 6 +}; +const getType = (startStr, endStr) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("In get type", startStr, endStr); + switch (startStr) { + case "[": + return nodeType.RECT; + case "(": + return endStr === ")" ? nodeType.ROUNDED_RECT : nodeType.CLOUD; + case "((": + return nodeType.CIRCLE; + case ")": + return nodeType.CLOUD; + case "))": + return nodeType.BANG; + case "{{": + return nodeType.HEXAGON; + default: + return nodeType.DEFAULT; + } +}; +const setElementForId = (id, element) => { + elements[id] = element; +}; +const decorateNode = (decoration) => { + const node = nodes[nodes.length - 1]; + if (decoration && decoration.icon) { + node.icon = sanitizeText(decoration.icon); + } + if (decoration && decoration.class) { + node.class = sanitizeText(decoration.class); + } +}; +const type2Str = (type) => { + switch (type) { + case nodeType.DEFAULT: + return "no-border"; + case nodeType.RECT: + return "rect"; + case nodeType.ROUNDED_RECT: + return "rounded-rect"; + case nodeType.CIRCLE: + return "circle"; + case nodeType.CLOUD: + return "cloud"; + case nodeType.BANG: + return "bang"; + case nodeType.HEXAGON: + return "hexgon"; + default: + return "no-border"; + } +}; +let parseError; +const setErrorHandler = (handler) => { + parseError = handler; +}; +const getLogger = () => _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l; +const getNodeById = (id) => nodes[id]; +const getElementById = (id) => elements[id]; +const mindmapDb = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ + __proto__: null, + addNode, + clear, + decorateNode, + getElementById, + getLogger, + getMindmap, + getNodeById, + getType, + nodeType, + get parseError() { + return parseError; + }, + sanitizeText, + setElementForId, + setErrorHandler, + type2Str +}, Symbol.toStringTag, { value: "Module" })); +const MAX_SECTIONS = 12; +const defaultBkg = function(elem, node, section) { + const rd = 5; + elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr( + "d", + `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd} q5,0 5,5 v${node.height - rd} H0 Z` + ); + elem.append("line").attr("class", "node-line-" + section).attr("x1", 0).attr("y1", node.height).attr("x2", node.width).attr("y2", node.height); +}; +const rectBkg = function(elem, node) { + elem.append("rect").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("height", node.height).attr("width", node.width); +}; +const cloudBkg = function(elem, node) { + const w = node.width; + const h = node.height; + const r1 = 0.15 * w; + const r2 = 0.25 * w; + const r3 = 0.35 * w; + const r4 = 0.2 * w; + elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr( + "d", + `M0 0 a${r1},${r1} 0 0,1 ${w * 0.25},${-1 * w * 0.1} + a${r3},${r3} 1 0,1 ${w * 0.4},${-1 * w * 0.1} + a${r2},${r2} 1 0,1 ${w * 0.35},${1 * w * 0.2} + + a${r1},${r1} 1 0,1 ${w * 0.15},${1 * h * 0.35} + a${r4},${r4} 1 0,1 ${-1 * w * 0.15},${1 * h * 0.65} + + a${r2},${r1} 1 0,1 ${-1 * w * 0.25},${w * 0.15} + a${r3},${r3} 1 0,1 ${-1 * w * 0.5},${0} + a${r1},${r1} 1 0,1 ${-1 * w * 0.25},${-1 * w * 0.15} + + a${r1},${r1} 1 0,1 ${-1 * w * 0.1},${-1 * h * 0.35} + a${r4},${r4} 1 0,1 ${w * 0.1},${-1 * h * 0.65} + + H0 V0 Z` + ); +}; +const bangBkg = function(elem, node) { + const w = node.width; + const h = node.height; + const r = 0.15 * w; + elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr( + "d", + `M0 0 a${r},${r} 1 0,0 ${w * 0.25},${-1 * h * 0.1} + a${r},${r} 1 0,0 ${w * 0.25},${0} + a${r},${r} 1 0,0 ${w * 0.25},${0} + a${r},${r} 1 0,0 ${w * 0.25},${1 * h * 0.1} + + a${r},${r} 1 0,0 ${w * 0.15},${1 * h * 0.33} + a${r * 0.8},${r * 0.8} 1 0,0 ${0},${1 * h * 0.34} + a${r},${r} 1 0,0 ${-1 * w * 0.15},${1 * h * 0.33} + + a${r},${r} 1 0,0 ${-1 * w * 0.25},${h * 0.15} + a${r},${r} 1 0,0 ${-1 * w * 0.25},${0} + a${r},${r} 1 0,0 ${-1 * w * 0.25},${0} + a${r},${r} 1 0,0 ${-1 * w * 0.25},${-1 * h * 0.15} + + a${r},${r} 1 0,0 ${-1 * w * 0.1},${-1 * h * 0.33} + a${r * 0.8},${r * 0.8} 1 0,0 ${0},${-1 * h * 0.34} + a${r},${r} 1 0,0 ${w * 0.1},${-1 * h * 0.33} + + H0 V0 Z` + ); +}; +const circleBkg = function(elem, node) { + elem.append("circle").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("r", node.width / 2); +}; +function insertPolygonShape(parent, w, h, points, node) { + return parent.insert("polygon", ":first-child").attr( + "points", + points.map(function(d) { + return d.x + "," + d.y; + }).join(" ") + ).attr("transform", "translate(" + (node.width - w) / 2 + ", " + h + ")"); +} +const hexagonBkg = function(elem, node) { + const h = node.height; + const f = 4; + const m = h / f; + const w = node.width - node.padding + 2 * m; + const points = [ + { x: m, y: 0 }, + { x: w - m, y: 0 }, + { x: w, y: -h / 2 }, + { x: w - m, y: -h }, + { x: m, y: -h }, + { x: 0, y: -h / 2 } + ]; + insertPolygonShape(elem, w, h, points, node); +}; +const roundedRectBkg = function(elem, node) { + elem.append("rect").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("height", node.height).attr("rx", node.padding).attr("ry", node.padding).attr("width", node.width); +}; +const drawNode = function(elem, node, fullSection, conf) { + const htmlLabels = conf.htmlLabels; + const section = fullSection % (MAX_SECTIONS - 1); + const nodeElem = elem.append("g"); + node.section = section; + let sectionClass = "section-" + section; + if (section < 0) { + sectionClass += " section-root"; + } + nodeElem.attr("class", (node.class ? node.class + " " : "") + "mindmap-node " + sectionClass); + const bkgElem = nodeElem.append("g"); + const textElem = nodeElem.append("g"); + const description = node.descr.replace(/(<br\/*>)/g, "\n"); + (0,_createText_62fc7601_js__WEBPACK_IMPORTED_MODULE_7__.a)(textElem, description, { + useHtmlLabels: htmlLabels, + width: node.width, + classes: "mindmap-node-label" + }); + if (!htmlLabels) { + textElem.attr("dy", "1em").attr("alignment-baseline", "middle").attr("dominant-baseline", "middle").attr("text-anchor", "middle"); + } + const bbox = textElem.node().getBBox(); + const fontSize = conf.fontSize.replace ? conf.fontSize.replace("px", "") : conf.fontSize; + node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding; + node.width = bbox.width + 2 * node.padding; + if (node.icon) { + if (node.type === nodeType.CIRCLE) { + node.height += 50; + node.width += 50; + const icon = nodeElem.append("foreignObject").attr("height", "50px").attr("width", node.width).attr("style", "text-align: center;"); + icon.append("div").attr("class", "icon-container").append("i").attr("class", "node-icon-" + section + " " + node.icon); + textElem.attr( + "transform", + "translate(" + node.width / 2 + ", " + (node.height / 2 - 1.5 * node.padding) + ")" + ); + } else { + node.width += 50; + const orgHeight = node.height; + node.height = Math.max(orgHeight, 60); + const heightDiff = Math.abs(node.height - orgHeight); + const icon = nodeElem.append("foreignObject").attr("width", "60px").attr("height", node.height).attr("style", "text-align: center;margin-top:" + heightDiff / 2 + "px;"); + icon.append("div").attr("class", "icon-container").append("i").attr("class", "node-icon-" + section + " " + node.icon); + textElem.attr( + "transform", + "translate(" + (25 + node.width / 2) + ", " + (heightDiff / 2 + node.padding / 2) + ")" + ); + } + } else { + if (!htmlLabels) { + const dx = node.width / 2; + const dy = node.padding / 2; + textElem.attr("transform", "translate(" + dx + ", " + dy + ")"); + } else { + const dx = (node.width - bbox.width) / 2; + const dy = (node.height - bbox.height) / 2; + textElem.attr("transform", "translate(" + dx + ", " + dy + ")"); + } + } + switch (node.type) { + case nodeType.DEFAULT: + defaultBkg(bkgElem, node, section); + break; + case nodeType.ROUNDED_RECT: + roundedRectBkg(bkgElem, node); + break; + case nodeType.RECT: + rectBkg(bkgElem, node); + break; + case nodeType.CIRCLE: + bkgElem.attr("transform", "translate(" + node.width / 2 + ", " + +node.height / 2 + ")"); + circleBkg(bkgElem, node); + break; + case nodeType.CLOUD: + cloudBkg(bkgElem, node); + break; + case nodeType.BANG: + bangBkg(bkgElem, node); + break; + case nodeType.HEXAGON: + hexagonBkg(bkgElem, node); + break; + } + setElementForId(node.id, nodeElem); + return node.height; +}; +const drawEdge = function drawEdge2(edgesElem, mindmap, parent, depth, fullSection) { + const section = fullSection % (MAX_SECTIONS - 1); + const sx = parent.x + parent.width / 2; + const sy = parent.y + parent.height / 2; + const ex = mindmap.x + mindmap.width / 2; + const ey = mindmap.y + mindmap.height / 2; + const mx = ex > sx ? sx + Math.abs(sx - ex) / 2 : sx - Math.abs(sx - ex) / 2; + const my = ey > sy ? sy + Math.abs(sy - ey) / 2 : sy - Math.abs(sy - ey) / 2; + const qx = ex > sx ? Math.abs(sx - mx) / 2 + sx : -Math.abs(sx - mx) / 2 + sx; + const qy = ey > sy ? Math.abs(sy - my) / 2 + sy : -Math.abs(sy - my) / 2 + sy; + edgesElem.append("path").attr( + "d", + parent.direction === "TB" || parent.direction === "BT" ? `M${sx},${sy} Q${sx},${qy} ${mx},${my} T${ex},${ey}` : `M${sx},${sy} Q${qx},${sy} ${mx},${my} T${ex},${ey}` + ).attr("class", "edge section-edge-" + section + " edge-depth-" + depth); +}; +const positionNode = function(node) { + const nodeElem = getElementById(node.id); + const x = node.x || 0; + const y = node.y || 0; + nodeElem.attr("transform", "translate(" + x + "," + y + ")"); +}; +const svgDraw = { drawNode, positionNode, drawEdge }; +cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1__.use(cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2__); +function drawNodes(svg, mindmap, section, conf) { + svgDraw.drawNode(svg, mindmap, section, conf); + if (mindmap.children) { + mindmap.children.forEach((child, index) => { + drawNodes(svg, child, section < 0 ? index : section, conf); + }); + } +} +function drawEdges(edgesEl, cy) { + cy.edges().map((edge, id) => { + const data = edge.data(); + if (edge[0]._private.bodyBounds) { + const bounds = edge[0]._private.rscratch; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.trace("Edge: ", id, data); + edgesEl.insert("path").attr( + "d", + `M ${bounds.startX},${bounds.startY} L ${bounds.midX},${bounds.midY} L${bounds.endX},${bounds.endY} ` + ).attr("class", "edge section-edge-" + data.section + " edge-depth-" + data.depth); + } + }); +} +function addNodes(mindmap, cy, conf, level) { + cy.add({ + group: "nodes", + data: { + id: mindmap.id, + labelText: mindmap.descr, + height: mindmap.height, + width: mindmap.width, + level, + nodeId: mindmap.id, + padding: mindmap.padding, + type: mindmap.type + }, + position: { + x: mindmap.x, + y: mindmap.y + } + }); + if (mindmap.children) { + mindmap.children.forEach((child) => { + addNodes(child, cy, conf, level + 1); + cy.add({ + group: "edges", + data: { + id: `${mindmap.id}_${child.id}`, + source: mindmap.id, + target: child.id, + depth: level, + section: child.section + } + }); + }); + } +} +function layoutMindmap(node, conf) { + return new Promise((resolve) => { + const renderEl = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body").append("div").attr("id", "cy").attr("style", "display:none"); + const cy = cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1__({ + container: document.getElementById("cy"), + // container to render in + style: [ + { + selector: "edge", + style: { + "curve-style": "bezier" + } + } + ] + }); + renderEl.remove(); + addNodes(node, cy, conf, 0); + cy.nodes().forEach(function(n) { + n.layoutDimensions = () => { + const data = n.data(); + return { w: data.width, h: data.height }; + }; + }); + cy.layout({ + name: "cose-bilkent", + quality: "proof", + // headless: true, + styleEnabled: false, + animate: false + }).run(); + cy.ready((e) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Ready", e); + resolve(cy); + }); + }); +} +function positionNodes(cy) { + cy.nodes().map((node, id) => { + const data = node.data(); + data.x = node.position().x; + data.y = node.position().y; + svgDraw.positionNode(data); + const el = getElementById(data.nodeId); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Id:", id, "Position: (", node.position().x, ", ", node.position().y, ")", data); + el.attr( + "transform", + `translate(${node.position().x - data.width / 2}, ${node.position().y - data.height / 2})` + ); + el.attr("attr", `apa-${id})`); + }); +} +const draw = async (text, id, version, diagObj) => { + const conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)(); + conf.htmlLabels = false; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Rendering mindmap diagram\n" + text, diagObj.parser); + const securityLevel = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const svg = root.select("#" + id); + svg.append("g"); + const mm = diagObj.db.getMindmap(); + const edgesElem = svg.append("g"); + edgesElem.attr("class", "mindmap-edges"); + const nodesElem = svg.append("g"); + nodesElem.attr("class", "mindmap-nodes"); + drawNodes(nodesElem, mm, -1, conf); + const cy = await layoutMindmap(mm, conf); + drawEdges(edgesElem, cy); + positionNodes(cy); + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.o)(void 0, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth); +}; +const mindmapRenderer = { + draw +}; +const genSections = (options) => { + let sections = ""; + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + options["lineColor" + i] = options["lineColor" + i] || options["cScaleInv" + i]; + if ((0,khroma__WEBPACK_IMPORTED_MODULE_8__/* ["default"] */ .Z)(options["lineColor" + i])) { + options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .Z)(options["lineColor" + i], 20); + } else { + options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_10__/* ["default"] */ .Z)(options["lineColor" + i], 20); + } + } + for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) { + const sw = "" + (17 - 3 * i); + sections += ` + .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} polygon, .section-${i - 1} path { + fill: ${options["cScale" + i]}; + } + .section-${i - 1} text { + fill: ${options["cScaleLabel" + i]}; + } + .node-icon-${i - 1} { + font-size: 40px; + color: ${options["cScaleLabel" + i]}; + } + .section-edge-${i - 1}{ + stroke: ${options["cScale" + i]}; + } + .edge-depth-${i - 1}{ + stroke-width: ${sw}; + } + .section-${i - 1} line { + stroke: ${options["cScaleInv" + i]} ; + stroke-width: 3; + } + + .disabled, .disabled circle, .disabled text { + fill: lightgray; + } + .disabled text { + fill: #efefef; + } + `; + } + return sections; +}; +const getStyles = (options) => ` + .edge { + stroke-width: 3; + } + ${genSections(options)} + .section-root rect, .section-root path, .section-root circle, .section-root polygon { + fill: ${options.git0}; + } + .section-root text { + fill: ${options.gitBranchLabel0}; + } + .icon-container { + height:100%; + display: flex; + justify-content: center; + align-items: center; + } + .edge { + fill: none; + } + .mindmap-node-label { + dy: 1em; + alignment-baseline: middle; + text-anchor: middle; + dominant-baseline: middle; + text-align: center; + } +`; +const mindmapStyles = getStyles; +const diagram = { + db: mindmapDb, + renderer: mindmapRenderer, + parser: mindmapParser, + styles: mindmapStyles +}; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/814f3328.0103710c.js b/assets/js/814f3328.0103710c.js deleted file mode 100644 index f5ba41a25..000000000 --- a/assets/js/814f3328.0103710c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2535],{45641:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0","permalink":"/refactoring-retrospective"},{"title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/jdbc-retrospective"},{"title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/mvc-retrospective"},{"title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","permalink":"/spring-test-isolation"},{"title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","permalink":"/web-application-evolution"}]}')}}]); \ No newline at end of file diff --git a/assets/js/814f3328.2e60c17f.js b/assets/js/814f3328.2e60c17f.js new file mode 100644 index 000000000..0dd126537 --- /dev/null +++ b/assets/js/814f3328.2e60c17f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2535],{45641:e=>{e.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0","permalink":"/refactoring-retrospective","unlisted":false},{"title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/jdbc-retrospective","unlisted":false},{"title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/mvc-retrospective","unlisted":false},{"title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","permalink":"/spring-test-isolation","unlisted":false},{"title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","permalink":"/web-application-evolution","unlisted":false}]}')}}]); \ No newline at end of file diff --git a/assets/js/816.dcd00e38.js b/assets/js/816.dcd00e38.js new file mode 100644 index 000000000..e1793e61c --- /dev/null +++ b/assets/js/816.dcd00e38.js @@ -0,0 +1,10814 @@ +"use strict"; +exports.id = 816; +exports.ids = [816]; +exports.modules = { + +/***/ 41644: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + bK: () => (/* reexport */ layout) +}); + +// UNUSED EXPORTS: acyclic, normalize, rank + +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/uniqueId.js +var uniqueId = __webpack_require__(66749); +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/map.js +var map = __webpack_require__(43836); +// EXTERNAL MODULE: ./node_modules/lodash-es/range.js + 2 modules +var range = __webpack_require__(74379); +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/index.js +var graphlib = __webpack_require__(45625); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/data/list.js +/* + * Simple doubly linked list implementation derived from Cormen, et al., + * "Introduction to Algorithms". + */ + + + +class List { + constructor() { + var sentinel = {}; + sentinel._next = sentinel._prev = sentinel; + this._sentinel = sentinel; + } + dequeue() { + var sentinel = this._sentinel; + var entry = sentinel._prev; + if (entry !== sentinel) { + unlink(entry); + return entry; + } + } + enqueue(entry) { + var sentinel = this._sentinel; + if (entry._prev && entry._next) { + unlink(entry); + } + entry._next = sentinel._next; + sentinel._next._prev = entry; + sentinel._next = entry; + entry._prev = sentinel; + } + toString() { + var strs = []; + var sentinel = this._sentinel; + var curr = sentinel._prev; + while (curr !== sentinel) { + strs.push(JSON.stringify(curr, filterOutLinks)); + curr = curr._prev; + } + return '[' + strs.join(', ') + ']'; + } +} + +function unlink(entry) { + entry._prev._next = entry._next; + entry._next._prev = entry._prev; + delete entry._next; + delete entry._prev; +} + +function filterOutLinks(k, v) { + if (k !== '_next' && k !== '_prev') { + return v; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/greedy-fas.js + + + + +/* + * A greedy heuristic for finding a feedback arc set for a graph. A feedback + * arc set is a set of edges that can be removed to make a graph acyclic. + * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and + * effective heuristic for the feedback arc set problem." This implementation + * adjusts that from the paper to allow for weighted edges. + */ + + +var DEFAULT_WEIGHT_FN = constant/* default */.Z(1); + +function greedyFAS(g, weightFn) { + if (g.nodeCount() <= 1) { + return []; + } + var state = buildState(g, weightFn || DEFAULT_WEIGHT_FN); + var results = doGreedyFAS(state.graph, state.buckets, state.zeroIdx); + + // Expand multi-edges + return flatten/* default */.Z( + map/* default */.Z(results, function (e) { + return g.outEdges(e.v, e.w); + }) + ); +} + +function doGreedyFAS(g, buckets, zeroIdx) { + var results = []; + var sources = buckets[buckets.length - 1]; + var sinks = buckets[0]; + + var entry; + while (g.nodeCount()) { + while ((entry = sinks.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + while ((entry = sources.dequeue())) { + removeNode(g, buckets, zeroIdx, entry); + } + if (g.nodeCount()) { + for (var i = buckets.length - 2; i > 0; --i) { + entry = buckets[i].dequeue(); + if (entry) { + results = results.concat(removeNode(g, buckets, zeroIdx, entry, true)); + break; + } + } + } + } + + return results; +} + +function removeNode(g, buckets, zeroIdx, entry, collectPredecessors) { + var results = collectPredecessors ? [] : undefined; + + forEach/* default */.Z(g.inEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var uEntry = g.node(edge.v); + + if (collectPredecessors) { + results.push({ v: edge.v, w: edge.w }); + } + + uEntry.out -= weight; + assignBucket(buckets, zeroIdx, uEntry); + }); + + forEach/* default */.Z(g.outEdges(entry.v), function (edge) { + var weight = g.edge(edge); + var w = edge.w; + var wEntry = g.node(w); + wEntry['in'] -= weight; + assignBucket(buckets, zeroIdx, wEntry); + }); + + g.removeNode(entry.v); + + return results; +} + +function buildState(g, weightFn) { + var fasGraph = new graphlib/* Graph */.k(); + var maxIn = 0; + var maxOut = 0; + + forEach/* default */.Z(g.nodes(), function (v) { + fasGraph.setNode(v, { v: v, in: 0, out: 0 }); + }); + + // Aggregate weights on nodes, but also sum the weights across multi-edges + // into a single edge for the fasGraph. + forEach/* default */.Z(g.edges(), function (e) { + var prevWeight = fasGraph.edge(e.v, e.w) || 0; + var weight = weightFn(e); + var edgeWeight = prevWeight + weight; + fasGraph.setEdge(e.v, e.w, edgeWeight); + maxOut = Math.max(maxOut, (fasGraph.node(e.v).out += weight)); + maxIn = Math.max(maxIn, (fasGraph.node(e.w)['in'] += weight)); + }); + + var buckets = range/* default */.Z(maxOut + maxIn + 3).map(function () { + return new List(); + }); + var zeroIdx = maxIn + 1; + + forEach/* default */.Z(fasGraph.nodes(), function (v) { + assignBucket(buckets, zeroIdx, fasGraph.node(v)); + }); + + return { graph: fasGraph, buckets: buckets, zeroIdx: zeroIdx }; +} + +function assignBucket(buckets, zeroIdx, entry) { + if (!entry.out) { + buckets[0].enqueue(entry); + } else if (!entry['in']) { + buckets[buckets.length - 1].enqueue(entry); + } else { + buckets[entry.out - entry['in'] + zeroIdx].enqueue(entry); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/acyclic.js + + + + + +function run(g) { + var fas = g.graph().acyclicer === 'greedy' ? greedyFAS(g, weightFn(g)) : dfsFAS(g); + forEach/* default */.Z(fas, function (e) { + var label = g.edge(e); + g.removeEdge(e); + label.forwardName = e.name; + label.reversed = true; + g.setEdge(e.w, e.v, label, uniqueId/* default */.Z('rev')); + }); + + function weightFn(g) { + return function (e) { + return g.edge(e).weight; + }; + } +} + +function dfsFAS(g) { + var fas = []; + var stack = {}; + var visited = {}; + + function dfs(v) { + if (has/* default */.Z(visited, v)) { + return; + } + visited[v] = true; + stack[v] = true; + forEach/* default */.Z(g.outEdges(v), function (e) { + if (has/* default */.Z(stack, e.w)) { + fas.push(e); + } else { + dfs(e.w); + } + }); + delete stack[v]; + } + + forEach/* default */.Z(g.nodes(), dfs); + return fas; +} + +function undo(g) { + forEach/* default */.Z(g.edges(), function (e) { + var label = g.edge(e); + if (label.reversed) { + g.removeEdge(e); + + var forwardName = label.forwardName; + delete label.reversed; + delete label.forwardName; + g.setEdge(e.w, e.v, label, forwardName); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/merge.js + 6 modules +var merge = __webpack_require__(59236); +// EXTERNAL MODULE: ./node_modules/lodash-es/pick.js + 4 modules +var pick = __webpack_require__(61666); +// EXTERNAL MODULE: ./node_modules/lodash-es/defaults.js +var defaults = __webpack_require__(3688); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseExtremum.js + + +/** + * The base implementation of methods like `_.max` and `_.min` which accepts a + * `comparator` to determine the extremum value. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The iteratee invoked per iteration. + * @param {Function} comparator The comparator used to compare values. + * @returns {*} Returns the extremum value. + */ +function baseExtremum(array, iteratee, comparator) { + var index = -1, + length = array.length; + + while (++index < length) { + var value = array[index], + current = iteratee(value); + + if (current != null && (computed === undefined + ? (current === current && !(0,isSymbol/* default */.Z)(current)) + : comparator(current, computed) + )) { + var computed = current, + result = value; + } + } + return result; +} + +/* harmony default export */ const _baseExtremum = (baseExtremum); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseGt.js +/** + * The base implementation of `_.gt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is greater than `other`, + * else `false`. + */ +function baseGt(value, other) { + return value > other; +} + +/* harmony default export */ const _baseGt = (baseGt); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/max.js + + + + +/** + * Computes the maximum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + * @example + * + * _.max([4, 2, 8, 6]); + * // => 8 + * + * _.max([]); + * // => undefined + */ +function max(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseGt) + : undefined; +} + +/* harmony default export */ const lodash_es_max = (max); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/last.js +/** + * Gets the last element of `array`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example + * + * _.last([1, 2, 3]); + * // => 3 + */ +function last(array) { + var length = array == null ? 0 : array.length; + return length ? array[length - 1] : undefined; +} + +/* harmony default export */ const lodash_es_last = (last); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseAssignValue.js +var _baseAssignValue = __webpack_require__(74752); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/mapValues.js + + + + +/** + * Creates an object with the same keys as `object` and values generated + * by running each own enumerable string keyed property of `object` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, key, object). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns the new mapped object. + * @see _.mapKeys + * @example + * + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; + * + * _.mapValues(users, function(o) { return o.age; }); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + * + * // The `_.property` iteratee shorthand. + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) + */ +function mapValues(object, iteratee) { + var result = {}; + iteratee = (0,_baseIteratee/* default */.Z)(iteratee, 3); + + (0,_baseForOwn/* default */.Z)(object, function(value, key, object) { + (0,_baseAssignValue/* default */.Z)(result, key, iteratee(value, key, object)); + }); + return result; +} + +/* harmony default export */ const lodash_es_mapValues = (mapValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseLt.js +/** + * The base implementation of `_.lt` which doesn't coerce arguments. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if `value` is less than `other`, + * else `false`. + */ +function baseLt(value, other) { + return value < other; +} + +/* harmony default export */ const _baseLt = (baseLt); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/min.js + + + + +/** + * Computes the minimum value of `array`. If `array` is empty or falsey, + * `undefined` is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Math + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + * @example + * + * _.min([4, 2, 8, 6]); + * // => 2 + * + * _.min([]); + * // => undefined + */ +function min(array) { + return (array && array.length) + ? _baseExtremum(array, identity/* default */.Z, _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_min = (min); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_root.js +var _root = __webpack_require__(66092); +;// CONCATENATED MODULE: ./node_modules/lodash-es/now.js + + +/** + * Gets the timestamp of the number of milliseconds that have elapsed since + * the Unix epoch (1 January 1970 00:00:00 UTC). + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Date + * @returns {number} Returns the timestamp. + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => Logs the number of milliseconds it took for the deferred invocation. + */ +var now = function() { + return _root/* default */.Z.Date.now(); +}; + +/* harmony default export */ const lodash_es_now = (now); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/util.js + + + + + +/* + * Adds a dummy node to the graph and return v. + */ +function addDummyNode(g, type, attrs, name) { + var v; + do { + v = uniqueId/* default */.Z(name); + } while (g.hasNode(v)); + + attrs.dummy = type; + g.setNode(v, attrs); + return v; +} + +/* + * Returns a new graph with only simple edges. Handles aggregation of data + * associated with multi-edges. + */ +function simplify(g) { + var simplified = new graphlib/* Graph */.k().setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + simplified.setNode(v, g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var simpleLabel = simplified.edge(e.v, e.w) || { weight: 0, minlen: 1 }; + var label = g.edge(e); + simplified.setEdge(e.v, e.w, { + weight: simpleLabel.weight + label.weight, + minlen: Math.max(simpleLabel.minlen, label.minlen), + }); + }); + return simplified; +} + +function asNonCompoundGraph(g) { + var simplified = new graphlib/* Graph */.k({ multigraph: g.isMultigraph() }).setGraph(g.graph()); + forEach/* default */.Z(g.nodes(), function (v) { + if (!g.children(v).length) { + simplified.setNode(v, g.node(v)); + } + }); + forEach/* default */.Z(g.edges(), function (e) { + simplified.setEdge(e, g.edge(e)); + }); + return simplified; +} + +function successorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var sucs = {}; + _.forEach(g.outEdges(v), function (e) { + sucs[e.w] = (sucs[e.w] || 0) + g.edge(e).weight; + }); + return sucs; + }); + return _.zipObject(g.nodes(), weightMap); +} + +function predecessorWeights(g) { + var weightMap = _.map(g.nodes(), function (v) { + var preds = {}; + _.forEach(g.inEdges(v), function (e) { + preds[e.v] = (preds[e.v] || 0) + g.edge(e).weight; + }); + return preds; + }); + return _.zipObject(g.nodes(), weightMap); +} + +/* + * Finds where a line starting at point ({x, y}) would intersect a rectangle + * ({x, y, width, height}) if it were pointing at the rectangle's center. + */ +function intersectRect(rect, point) { + var x = rect.x; + var y = rect.y; + + // Rectangle intersection algorithm from: + // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes + var dx = point.x - x; + var dy = point.y - y; + var w = rect.width / 2; + var h = rect.height / 2; + + if (!dx && !dy) { + throw new Error('Not possible to find intersection inside of the rectangle'); + } + + var sx, sy; + if (Math.abs(dy) * w > Math.abs(dx) * h) { + // Intersection is top or bottom of rect. + if (dy < 0) { + h = -h; + } + sx = (h * dx) / dy; + sy = h; + } else { + // Intersection is left or right of rect. + if (dx < 0) { + w = -w; + } + sx = w; + sy = (w * dy) / dx; + } + + return { x: x + sx, y: y + sy }; +} + +/* + * Given a DAG with each node assigned "rank" and "order" properties, this + * function will produce a matrix with the ids of each node. + */ +function buildLayerMatrix(g) { + var layering = map/* default */.Z(range/* default */.Z(util_maxRank(g) + 1), function () { + return []; + }); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + var rank = node.rank; + if (!isUndefined/* default */.Z(rank)) { + layering[rank][node.order] = v; + } + }); + return layering; +} + +/* + * Adjusts the ranks for all nodes in the graph such that all nodes v have + * rank(v) >= 0 and at least one node w has rank(w) = 0. + */ +function normalizeRanks(g) { + var min = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (has/* default */.Z(node, 'rank')) { + node.rank -= min; + } + }); +} + +function removeEmptyRanks(g) { + // Ranks may not start at 0, so we need to offset them + var offset = lodash_es_min( + map/* default */.Z(g.nodes(), function (v) { + return g.node(v).rank; + }) + ); + + var layers = []; + forEach/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank - offset; + if (!layers[rank]) { + layers[rank] = []; + } + layers[rank].push(v); + }); + + var delta = 0; + var nodeRankFactor = g.graph().nodeRankFactor; + forEach/* default */.Z(layers, function (vs, i) { + if (isUndefined/* default */.Z(vs) && i % nodeRankFactor !== 0) { + --delta; + } else if (delta) { + forEach/* default */.Z(vs, function (v) { + g.node(v).rank += delta; + }); + } + }); +} + +function addBorderNode(g, prefix, rank, order) { + var node = { + width: 0, + height: 0, + }; + if (arguments.length >= 4) { + node.rank = rank; + node.order = order; + } + return addDummyNode(g, 'border', node, prefix); +} + +function util_maxRank(g) { + return lodash_es_max( + map/* default */.Z(g.nodes(), function (v) { + var rank = g.node(v).rank; + if (!isUndefined/* default */.Z(rank)) { + return rank; + } + }) + ); +} + +/* + * Partition a collection into two groups: `lhs` and `rhs`. If the supplied + * function returns true for an entry it goes into `lhs`. Otherwise it goes + * into `rhs. + */ +function partition(collection, fn) { + var result = { lhs: [], rhs: [] }; + forEach/* default */.Z(collection, function (value) { + if (fn(value)) { + result.lhs.push(value); + } else { + result.rhs.push(value); + } + }); + return result; +} + +/* + * Returns a new function that wraps `fn` with a timer. The wrapper logs the + * time it takes to execute the function. + */ +function util_time(name, fn) { + var start = lodash_es_now(); + try { + return fn(); + } finally { + console.log(name + ' time: ' + (lodash_es_now() - start) + 'ms'); + } +} + +function notime(name, fn) { + return fn(); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/add-border-segments.js + + + + + +function addBorderSegments(g) { + function dfs(v) { + var children = g.children(v); + var node = g.node(v); + if (children.length) { + forEach/* default */.Z(children, dfs); + } + + if (has/* default */.Z(node, 'minRank')) { + node.borderLeft = []; + node.borderRight = []; + for (var rank = node.minRank, maxRank = node.maxRank + 1; rank < maxRank; ++rank) { + add_border_segments_addBorderNode(g, 'borderLeft', '_bl', v, node, rank); + add_border_segments_addBorderNode(g, 'borderRight', '_br', v, node, rank); + } + } + } + + forEach/* default */.Z(g.children(), dfs); +} + +function add_border_segments_addBorderNode(g, prop, prefix, sg, sgNode, rank) { + var label = { width: 0, height: 0, rank: rank, borderType: prop }; + var prev = sgNode[prop][rank - 1]; + var curr = addDummyNode(g, 'border', label, prefix); + sgNode[prop][rank] = curr; + g.setParent(curr, sg); + if (prev) { + g.setEdge(prev, curr, { weight: 1 }); + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/coordinate-system.js + + + + +function adjust(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'lr' || rankDir === 'rl') { + swapWidthHeight(g); + } +} + +function coordinate_system_undo(g) { + var rankDir = g.graph().rankdir.toLowerCase(); + if (rankDir === 'bt' || rankDir === 'rl') { + reverseY(g); + } + + if (rankDir === 'lr' || rankDir === 'rl') { + swapXY(g); + swapWidthHeight(g); + } +} + +function swapWidthHeight(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapWidthHeightOne(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + swapWidthHeightOne(g.edge(e)); + }); +} + +function swapWidthHeightOne(attrs) { + var w = attrs.width; + attrs.width = attrs.height; + attrs.height = w; +} + +function reverseY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + reverseYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, reverseYOne); + if (has/* default */.Z(edge, 'y')) { + reverseYOne(edge); + } + }); +} + +function reverseYOne(attrs) { + attrs.y = -attrs.y; +} + +function swapXY(g) { + forEach/* default */.Z(g.nodes(), function (v) { + swapXYOne(g.node(v)); + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, swapXYOne); + if (has/* default */.Z(edge, 'x')) { + swapXYOne(edge); + } + }); +} + +function swapXYOne(attrs) { + var x = attrs.x; + attrs.x = attrs.y; + attrs.y = x; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/normalize.js + + + + + +/* + * Breaks any long edges in the graph into short segments that span 1 layer + * each. This operation is undoable with the denormalize function. + * + * Pre-conditions: + * + * 1. The input graph is a DAG. + * 2. Each node in the graph has a "rank" property. + * + * Post-condition: + * + * 1. All edges in the graph have a length of 1. + * 2. Dummy nodes are added where edges have been split into segments. + * 3. The graph is augmented with a "dummyChains" attribute which contains + * the first dummy in each chain of dummy nodes produced. + */ +function normalize_run(g) { + g.graph().dummyChains = []; + forEach/* default */.Z(g.edges(), function (edge) { + normalizeEdge(g, edge); + }); +} + +function normalizeEdge(g, e) { + var v = e.v; + var vRank = g.node(v).rank; + var w = e.w; + var wRank = g.node(w).rank; + var name = e.name; + var edgeLabel = g.edge(e); + var labelRank = edgeLabel.labelRank; + + if (wRank === vRank + 1) return; + + g.removeEdge(e); + + var dummy, attrs, i; + for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) { + edgeLabel.points = []; + attrs = { + width: 0, + height: 0, + edgeLabel: edgeLabel, + edgeObj: e, + rank: vRank, + }; + dummy = addDummyNode(g, 'edge', attrs, '_d'); + if (vRank === labelRank) { + attrs.width = edgeLabel.width; + attrs.height = edgeLabel.height; + // @ts-expect-error + attrs.dummy = 'edge-label'; + // @ts-expect-error + attrs.labelpos = edgeLabel.labelpos; + } + g.setEdge(v, dummy, { weight: edgeLabel.weight }, name); + if (i === 0) { + g.graph().dummyChains.push(dummy); + } + v = dummy; + } + + g.setEdge(v, w, { weight: edgeLabel.weight }, name); +} + +function normalize_undo(g) { + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var origLabel = node.edgeLabel; + var w; + g.setEdge(node.edgeObj, origLabel); + while (node.dummy) { + w = g.successors(v)[0]; + g.removeNode(v); + origLabel.points.push({ x: node.x, y: node.y }); + if (node.dummy === 'edge-label') { + origLabel.x = node.x; + origLabel.y = node.y; + origLabel.width = node.width; + origLabel.height = node.height; + } + v = w; + node = g.node(v); + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/lodash-es/minBy.js + + + + +/** + * This method is like `_.min` except that it accepts `iteratee` which is + * invoked for each element in `array` to generate the criterion by which + * the value is ranked. The iteratee is invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Math + * @param {Array} array The array to iterate over. + * @param {Function} [iteratee=_.identity] The iteratee invoked per element. + * @returns {*} Returns the minimum value. + * @example + * + * var objects = [{ 'n': 1 }, { 'n': 2 }]; + * + * _.minBy(objects, function(o) { return o.n; }); + * // => { 'n': 1 } + * + * // The `_.property` iteratee shorthand. + * _.minBy(objects, 'n'); + * // => { 'n': 1 } + */ +function minBy(array, iteratee) { + return (array && array.length) + ? _baseExtremum(array, (0,_baseIteratee/* default */.Z)(iteratee, 2), _baseLt) + : undefined; +} + +/* harmony default export */ const lodash_es_minBy = (minBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/util.js + + + + +/* + * Initializes ranks for the input graph using the longest path algorithm. This + * algorithm scales well and is fast in practice, it yields rather poor + * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom + * ranks wide and leaving edges longer than necessary. However, due to its + * speed, this algorithm is good for getting an initial ranking that can be fed + * into other algorithms. + * + * This algorithm does not normalize layers because it will be used by other + * algorithms in most cases. If using this algorithm directly, be sure to + * run normalize at the end. + * + * Pre-conditions: + * + * 1. Input graph is a DAG. + * 2. Input graph node labels can be assigned properties. + * + * Post-conditions: + * + * 1. Each node will be assign an (unnormalized) "rank" property. + */ +function longestPath(g) { + var visited = {}; + + function dfs(v) { + var label = g.node(v); + if (has/* default */.Z(visited, v)) { + return label.rank; + } + visited[v] = true; + + var rank = lodash_es_min( + map/* default */.Z(g.outEdges(v), function (e) { + return dfs(e.w) - g.edge(e).minlen; + }) + ); + + if ( + rank === Number.POSITIVE_INFINITY || // return value of _.map([]) for Lodash 3 + rank === undefined || // return value of _.map([]) for Lodash 4 + rank === null + ) { + // return value of _.map([null]) + rank = 0; + } + + return (label.rank = rank); + } + + forEach/* default */.Z(g.sources(), dfs); +} + +/* + * Returns the amount of slack for the given edge. The slack is defined as the + * difference between the length of the edge and its minimum length. + */ +function slack(g, e) { + return g.node(e.w).rank - g.node(e.v).rank - g.edge(e).minlen; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js + + + + + + +/* + * Constructs a spanning tree with tight edges and adjusted the input node's + * ranks to achieve this. A tight edge is one that is has a length that matches + * its "minlen" attribute. + * + * The basic structure for this function is derived from Gansner, et al., "A + * Technique for Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a DAG. + * 2. Graph must be connected. + * 3. Graph must have at least one node. + * 5. Graph nodes must have been previously assigned a "rank" property that + * respects the "minlen" property of incident edges. + * 6. Graph edges must have a "minlen" property. + * + * Post-conditions: + * + * - Graph nodes will have their rank adjusted to ensure that all edges are + * tight. + * + * Returns a tree (undirected graph) that is constructed using only "tight" + * edges. + */ +function feasibleTree(g) { + var t = new graphlib/* Graph */.k({ directed: false }); + + // Choose arbitrary node from which to start our tree + var start = g.nodes()[0]; + var size = g.nodeCount(); + t.setNode(start, {}); + + var edge, delta; + while (tightTree(t, g) < size) { + edge = findMinSlackEdge(t, g); + delta = t.hasNode(edge.v) ? slack(g, edge) : -slack(g, edge); + shiftRanks(t, g, delta); + } + + return t; +} + +/* + * Finds a maximal tree of tight edges and returns the number of nodes in the + * tree. + */ +function tightTree(t, g) { + function dfs(v) { + forEach/* default */.Z(g.nodeEdges(v), function (e) { + var edgeV = e.v, + w = v === edgeV ? e.w : edgeV; + if (!t.hasNode(w) && !slack(g, e)) { + t.setNode(w, {}); + t.setEdge(v, w, {}); + dfs(w); + } + }); + } + + forEach/* default */.Z(t.nodes(), dfs); + return t.nodeCount(); +} + +/* + * Finds the edge with the smallest slack that is incident on tree and returns + * it. + */ +function findMinSlackEdge(t, g) { + return lodash_es_minBy(g.edges(), function (e) { + if (t.hasNode(e.v) !== t.hasNode(e.w)) { + return slack(g, e); + } + }); +} + +function shiftRanks(t, g, delta) { + forEach/* default */.Z(t.nodes(), function (v) { + g.node(v).rank += delta; + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createFind.js + + + + +/** + * Creates a `_.find` or `_.findLast` function. + * + * @private + * @param {Function} findIndexFunc The function to find the collection index. + * @returns {Function} Returns the new find function. + */ +function createFind(findIndexFunc) { + return function(collection, predicate, fromIndex) { + var iterable = Object(collection); + if (!(0,isArrayLike/* default */.Z)(collection)) { + var iteratee = (0,_baseIteratee/* default */.Z)(predicate, 3); + collection = (0,keys/* default */.Z)(collection); + predicate = function(key) { return iteratee(iterable[key], key, iterable); }; + } + var index = findIndexFunc(collection, predicate, fromIndex); + return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; + }; +} + +/* harmony default export */ const _createFind = (createFind); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toInteger.js + + +/** + * Converts `value` to an integer. + * + * **Note:** This method is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ +function toInteger(value) { + var result = (0,toFinite/* default */.Z)(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; +} + +/* harmony default export */ const lodash_es_toInteger = (toInteger); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/findIndex.js + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeMax = Math.max; + +/** + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. + * + * @static + * @memberOf _ + * @since 1.1.0 + * @category Array + * @param {Array} array The array to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {number} Returns the index of the found element, else `-1`. + * @example + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * _.findIndex(users, function(o) { return o.user == 'barney'; }); + * // => 0 + * + * // The `_.matches` iteratee shorthand. + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // The `_.matchesProperty` iteratee shorthand. + * _.findIndex(users, ['active', false]); + * // => 0 + * + * // The `_.property` iteratee shorthand. + * _.findIndex(users, 'active'); + * // => 2 + */ +function findIndex(array, predicate, fromIndex) { + var length = array == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = fromIndex == null ? 0 : lodash_es_toInteger(fromIndex); + if (index < 0) { + index = nativeMax(length + index, 0); + } + return (0,_baseFindIndex/* default */.Z)(array, (0,_baseIteratee/* default */.Z)(predicate, 3), index); +} + +/* harmony default export */ const lodash_es_findIndex = (findIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/find.js + + + +/** + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to inspect. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @param {number} [fromIndex=0] The index to search from. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false }, + * { 'user': 'pebbles', 'age': 1, 'active': true } + * ]; + * + * _.find(users, function(o) { return o.age < 40; }); + * // => object for 'barney' + * + * // The `_.matches` iteratee shorthand. + * _.find(users, { 'age': 1, 'active': true }); + * // => object for 'pebbles' + * + * // The `_.matchesProperty` iteratee shorthand. + * _.find(users, ['active', false]); + * // => object for 'fred' + * + * // The `_.property` iteratee shorthand. + * _.find(users, 'active'); + * // => object for 'barney' + */ +var find = _createFind(lodash_es_findIndex); + +/* harmony default export */ const lodash_es_find = (find); + +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js + + + + + +var DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function dijkstra_dijkstra(g, source, weightFn, edgeFn) { + return runDijkstra( + g, + String(source), + weightFn || DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runDijkstra(g, source, weightFn, edgeFn) { + var results = {}; + var pq = new PriorityQueue(); + var v, vEntry; + + var updateNeighbors = function (edge) { + var w = edge.v !== v ? edge.v : edge.w; + var wEntry = results[w]; + var weight = weightFn(edge); + var distance = vEntry.distance + weight; + + if (weight < 0) { + throw new Error( + 'dijkstra does not allow negative edge weights. ' + + 'Bad edge: ' + + edge + + ' Weight: ' + + weight + ); + } + + if (distance < wEntry.distance) { + wEntry.distance = distance; + wEntry.predecessor = v; + pq.decrease(w, distance); + } + }; + + g.nodes().forEach(function (v) { + var distance = v === source ? 0 : Number.POSITIVE_INFINITY; + results[v] = { distance: distance }; + pq.add(v, distance); + }); + + while (pq.size() > 0) { + v = pq.removeMin(); + vEntry = results[v]; + if (vEntry.distance === Number.POSITIVE_INFINITY) { + break; + } + + edgeFn(v).forEach(updateNeighbors); + } + + return results; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js + + + + + +function dijkstraAll(g, weightFunc, edgeFunc) { + return _.transform( + g.nodes(), + function (acc, v) { + acc[v] = dijkstra(g, v, weightFunc, edgeFunc); + }, + {} + ); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js + + + + +var floyd_warshall_DEFAULT_WEIGHT_FUNC = constant/* default */.Z(1); + +function floydWarshall(g, weightFn, edgeFn) { + return runFloydWarshall( + g, + weightFn || floyd_warshall_DEFAULT_WEIGHT_FUNC, + edgeFn || + function (v) { + return g.outEdges(v); + } + ); +} + +function runFloydWarshall(g, weightFn, edgeFn) { + var results = {}; + var nodes = g.nodes(); + + nodes.forEach(function (v) { + results[v] = {}; + results[v][v] = { distance: 0 }; + nodes.forEach(function (w) { + if (v !== w) { + results[v][w] = { distance: Number.POSITIVE_INFINITY }; + } + }); + edgeFn(v).forEach(function (edge) { + var w = edge.v === v ? edge.w : edge.v; + var d = weightFn(edge); + results[v][w] = { distance: d, predecessor: v }; + }); + }); + + nodes.forEach(function (k) { + var rowK = results[k]; + nodes.forEach(function (i) { + var rowI = results[i]; + nodes.forEach(function (j) { + var ik = rowI[k]; + var kj = rowK[j]; + var ij = rowI[j]; + var altDistance = ik.distance + kj.distance; + if (altDistance < ij.distance) { + ij.distance = altDistance; + ij.predecessor = kj.predecessor; + } + }); + }); + }); + + return results; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseKeys.js + 1 modules +var _baseKeys = __webpack_require__(39473); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetTag.js + 2 modules +var _baseGetTag = __webpack_require__(93589); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isString.js + + + + +/** `Object#toString` result references. */ +var stringTag = '[object String]'; + +/** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a string, else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ +function isString(value) { + return typeof value == 'string' || + (!(0,isArray/* default */.Z)(value) && (0,isObjectLike/* default */.Z)(value) && (0,_baseGetTag/* default */.Z)(value) == stringTag); +} + +/* harmony default export */ const lodash_es_isString = (isString); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_asciiSize.js + + +/** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +var asciiSize = (0,_baseProperty/* default */.Z)('length'); + +/* harmony default export */ const _asciiSize = (asciiSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_hasUnicode.js +/** Used to compose unicode character classes. */ +var rsAstralRange = '\\ud800-\\udfff', + rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsZWJ = '\\u200d'; + +/** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ +var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + +/** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ +function hasUnicode(string) { + return reHasUnicode.test(string); +} + +/* harmony default export */ const _hasUnicode = (hasUnicode); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_unicodeSize.js +/** Used to compose unicode character classes. */ +var _unicodeSize_rsAstralRange = '\\ud800-\\udfff', + _unicodeSize_rsComboMarksRange = '\\u0300-\\u036f', + _unicodeSize_reComboHalfMarksRange = '\\ufe20-\\ufe2f', + _unicodeSize_rsComboSymbolsRange = '\\u20d0-\\u20ff', + _unicodeSize_rsComboRange = _unicodeSize_rsComboMarksRange + _unicodeSize_reComboHalfMarksRange + _unicodeSize_rsComboSymbolsRange, + _unicodeSize_rsVarRange = '\\ufe0e\\ufe0f'; + +/** Used to compose unicode capture groups. */ +var rsAstral = '[' + _unicodeSize_rsAstralRange + ']', + rsCombo = '[' + _unicodeSize_rsComboRange + ']', + rsFitz = '\\ud83c[\\udffb-\\udfff]', + rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', + rsNonAstral = '[^' + _unicodeSize_rsAstralRange + ']', + rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', + rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', + _unicodeSize_rsZWJ = '\\u200d'; + +/** Used to compose unicode regexes. */ +var reOptMod = rsModifier + '?', + rsOptVar = '[' + _unicodeSize_rsVarRange + ']?', + rsOptJoin = '(?:' + _unicodeSize_rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsSeq = rsOptVar + reOptMod + rsOptJoin, + rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + +/** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ +var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + +/** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ +function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; +} + +/* harmony default export */ const _unicodeSize = (unicodeSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringSize.js + + + + +/** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ +function stringSize(string) { + return _hasUnicode(string) + ? _unicodeSize(string) + : _asciiSize(string); +} + +/* harmony default export */ const _stringSize = (stringSize); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/size.js + + + + + + +/** `Object#toString` result references. */ +var mapTag = '[object Map]', + setTag = '[object Set]'; + +/** + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable string keyed properties for objects. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the collection size. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 + */ +function size(collection) { + if (collection == null) { + return 0; + } + if ((0,isArrayLike/* default */.Z)(collection)) { + return lodash_es_isString(collection) ? _stringSize(collection) : collection.length; + } + var tag = (0,_getTag/* default */.Z)(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return (0,_baseKeys/* default */.Z)(collection).length; +} + +/* harmony default export */ const lodash_es_size = (size); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/topsort.js + + + + +topsort_topsort.CycleException = topsort_CycleException; + +function topsort_topsort(g) { + var visited = {}; + var stack = {}; + var results = []; + + function visit(node) { + if (has/* default */.Z(stack, node)) { + throw new topsort_CycleException(); + } + + if (!has/* default */.Z(visited, node)) { + stack[node] = true; + visited[node] = true; + forEach/* default */.Z(g.predecessors(node), visit); + delete stack[node]; + results.push(node); + } + } + + forEach/* default */.Z(g.sinks(), visit); + + if (lodash_es_size(visited) !== g.nodeCount()) { + throw new topsort_CycleException(); + } + + return results; +} + +function topsort_CycleException() {} +topsort_CycleException.prototype = new Error(); // must be an instance of Error to pass testing + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js + + + + +function isAcyclic(g) { + try { + topsort(g); + } catch (e) { + if (e instanceof CycleException) { + return false; + } + throw e; + } + return true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/dfs.js + + + + +/* + * A helper that preforms a pre- or post-order traversal on the input graph + * and returns the nodes in the order they were visited. If the graph is + * undirected then this algorithm will navigate using neighbors. If the graph + * is directed then this algorithm will navigate using successors. + * + * Order must be one of "pre" or "post". + */ +function dfs(g, vs, order) { + if (!isArray/* default */.Z(vs)) { + vs = [vs]; + } + + var navigation = (g.isDirected() ? g.successors : g.neighbors).bind(g); + + var acc = []; + var visited = {}; + forEach/* default */.Z(vs, function (v) { + if (!g.hasNode(v)) { + throw new Error('Graph does not have node: ' + v); + } + + doDfs(g, v, order === 'post', visited, navigation, acc); + }); + return acc; +} + +function doDfs(g, v, postorder, visited, navigation, acc) { + if (!has/* default */.Z(visited, v)) { + visited[v] = true; + + if (!postorder) { + acc.push(v); + } + forEach/* default */.Z(navigation(v), function (w) { + doDfs(g, w, postorder, visited, navigation, acc); + }); + if (postorder) { + acc.push(v); + } + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/postorder.js + + + + +function postorder(g, vs) { + return dfs(g, vs, 'post'); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/preorder.js + + + + +function preorder(g, vs) { + return dfs(g, vs, 'pre'); +} + +// EXTERNAL MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + 9 modules +var graph = __webpack_require__(52544); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/prim.js + + + + + + +function prim(g, weightFunc) { + var result = new Graph(); + var parents = {}; + var pq = new PriorityQueue(); + var v; + + function updateNeighbors(edge) { + var w = edge.v === v ? edge.w : edge.v; + var pri = pq.priority(w); + if (pri !== undefined) { + var edgeWeight = weightFunc(edge); + if (edgeWeight < pri) { + parents[w] = v; + pq.decrease(w, edgeWeight); + } + } + } + + if (g.nodeCount() === 0) { + return result; + } + + _.each(g.nodes(), function (v) { + pq.add(v, Number.POSITIVE_INFINITY); + result.setNode(v); + }); + + // Start from an arbitrary node + pq.decrease(g.nodes()[0], 0); + + var init = false; + while (pq.size() > 0) { + v = pq.removeMin(); + if (_.has(parents, v)) { + result.setEdge(v, parents[v]); + } else if (init) { + throw new Error('Input graph is not connected: ' + g); + } else { + init = true; + } + + g.nodeEdges(v).forEach(updateNeighbors); + } + + return result; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/alg/index.js + + + + + + + + + + + + + + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js + + + + + + + + +// Expose some internals for testing purposes +networkSimplex.initLowLimValues = initLowLimValues; +networkSimplex.initCutValues = initCutValues; +networkSimplex.calcCutValue = calcCutValue; +networkSimplex.leaveEdge = leaveEdge; +networkSimplex.enterEdge = enterEdge; +networkSimplex.exchangeEdges = exchangeEdges; + +/* + * The network simplex algorithm assigns ranks to each node in the input graph + * and iteratively improves the ranking to reduce the length of edges. + * + * Preconditions: + * + * 1. The input graph must be a DAG. + * 2. All nodes in the graph must have an object value. + * 3. All edges in the graph must have "minlen" and "weight" attributes. + * + * Postconditions: + * + * 1. All nodes in the graph will have an assigned "rank" attribute that has + * been optimized by the network simplex algorithm. Ranks start at 0. + * + * + * A rough sketch of the algorithm is as follows: + * + * 1. Assign initial ranks to each node. We use the longest path algorithm, + * which assigns ranks to the lowest position possible. In general this + * leads to very wide bottom ranks and unnecessarily long edges. + * 2. Construct a feasible tight tree. A tight tree is one such that all + * edges in the tree have no slack (difference between length of edge + * and minlen for the edge). This by itself greatly improves the assigned + * rankings by shorting edges. + * 3. Iteratively find edges that have negative cut values. Generally a + * negative cut value indicates that the edge could be removed and a new + * tree edge could be added to produce a more compact graph. + * + * Much of the algorithms here are derived from Gansner, et al., "A Technique + * for Drawing Directed Graphs." The structure of the file roughly follows the + * structure of the overall algorithm. + */ +function networkSimplex(g) { + g = simplify(g); + longestPath(g); + var t = feasibleTree(g); + initLowLimValues(t); + initCutValues(t, g); + + var e, f; + while ((e = leaveEdge(t))) { + f = enterEdge(t, g, e); + exchangeEdges(t, g, e, f); + } +} + +/* + * Initializes cut values for all edges in the tree. + */ +function initCutValues(t, g) { + var vs = postorder(t, t.nodes()); + vs = vs.slice(0, vs.length - 1); + forEach/* default */.Z(vs, function (v) { + assignCutValue(t, g, v); + }); +} + +function assignCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + t.edge(child, parent).cutvalue = calcCutValue(t, g, child); +} + +/* + * Given the tight tree, its graph, and a child in the graph calculate and + * return the cut value for the edge between the child and its parent. + */ +function calcCutValue(t, g, child) { + var childLab = t.node(child); + var parent = childLab.parent; + // True if the child is on the tail end of the edge in the directed graph + var childIsTail = true; + // The graph's view of the tree edge we're inspecting + var graphEdge = g.edge(child, parent); + // The accumulated cut value for the edge between this node and its parent + var cutValue = 0; + + if (!graphEdge) { + childIsTail = false; + graphEdge = g.edge(parent, child); + } + + cutValue = graphEdge.weight; + + forEach/* default */.Z(g.nodeEdges(child), function (e) { + var isOutEdge = e.v === child, + other = isOutEdge ? e.w : e.v; + + if (other !== parent) { + var pointsToHead = isOutEdge === childIsTail, + otherWeight = g.edge(e).weight; + + cutValue += pointsToHead ? otherWeight : -otherWeight; + if (isTreeEdge(t, child, other)) { + var otherCutValue = t.edge(child, other).cutvalue; + cutValue += pointsToHead ? -otherCutValue : otherCutValue; + } + } + }); + + return cutValue; +} + +function initLowLimValues(tree, root) { + if (arguments.length < 2) { + root = tree.nodes()[0]; + } + dfsAssignLowLim(tree, {}, 1, root); +} + +function dfsAssignLowLim(tree, visited, nextLim, v, parent) { + var low = nextLim; + var label = tree.node(v); + + visited[v] = true; + forEach/* default */.Z(tree.neighbors(v), function (w) { + if (!has/* default */.Z(visited, w)) { + nextLim = dfsAssignLowLim(tree, visited, nextLim, w, v); + } + }); + + label.low = low; + label.lim = nextLim++; + if (parent) { + label.parent = parent; + } else { + // TODO should be able to remove this when we incrementally update low lim + delete label.parent; + } + + return nextLim; +} + +function leaveEdge(tree) { + return lodash_es_find(tree.edges(), function (e) { + return tree.edge(e).cutvalue < 0; + }); +} + +function enterEdge(t, g, edge) { + var v = edge.v; + var w = edge.w; + + // For the rest of this function we assume that v is the tail and w is the + // head, so if we don't have this edge in the graph we should flip it to + // match the correct orientation. + if (!g.hasEdge(v, w)) { + v = edge.w; + w = edge.v; + } + + var vLabel = t.node(v); + var wLabel = t.node(w); + var tailLabel = vLabel; + var flip = false; + + // If the root is in the tail of the edge then we need to flip the logic that + // checks for the head and tail nodes in the candidates function below. + if (vLabel.lim > wLabel.lim) { + tailLabel = wLabel; + flip = true; + } + + var candidates = filter/* default */.Z(g.edges(), function (edge) { + return ( + flip === isDescendant(t, t.node(edge.v), tailLabel) && + flip !== isDescendant(t, t.node(edge.w), tailLabel) + ); + }); + + return lodash_es_minBy(candidates, function (edge) { + return slack(g, edge); + }); +} + +function exchangeEdges(t, g, e, f) { + var v = e.v; + var w = e.w; + t.removeEdge(v, w); + t.setEdge(f.v, f.w, {}); + initLowLimValues(t); + initCutValues(t, g); + updateRanks(t, g); +} + +function updateRanks(t, g) { + var root = lodash_es_find(t.nodes(), function (v) { + return !g.node(v).parent; + }); + var vs = preorder(t, root); + vs = vs.slice(1); + forEach/* default */.Z(vs, function (v) { + var parent = t.node(v).parent, + edge = g.edge(v, parent), + flipped = false; + + if (!edge) { + edge = g.edge(parent, v); + flipped = true; + } + + g.node(v).rank = g.node(parent).rank + (flipped ? edge.minlen : -edge.minlen); + }); +} + +/* + * Returns true if the edge is in the tree. + */ +function isTreeEdge(tree, u, v) { + return tree.hasEdge(u, v); +} + +/* + * Returns true if the specified node is descendant of the root node per the + * assigned low and lim attributes in the tree. + */ +function isDescendant(tree, vLabel, rootLabel) { + return rootLabel.low <= vLabel.lim && vLabel.lim <= rootLabel.lim; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/rank/index.js + + + + + + +/* + * Assigns a rank to each node in the input graph that respects the "minlen" + * constraint specified on edges between nodes. + * + * This basic structure is derived from Gansner, et al., "A Technique for + * Drawing Directed Graphs." + * + * Pre-conditions: + * + * 1. Graph must be a connected DAG + * 2. Graph nodes must be objects + * 3. Graph edges must have "weight" and "minlen" attributes + * + * Post-conditions: + * + * 1. Graph nodes will have a "rank" attribute based on the results of the + * algorithm. Ranks can start at any index (including negative), we'll + * fix them up later. + */ +function rank(g) { + switch (g.graph().ranker) { + case 'network-simplex': + networkSimplexRanker(g); + break; + case 'tight-tree': + tightTreeRanker(g); + break; + case 'longest-path': + longestPathRanker(g); + break; + default: + networkSimplexRanker(g); + } +} + +// A fast and simple ranker, but results are far from optimal. +var longestPathRanker = longestPath; + +function tightTreeRanker(g) { + longestPath(g); + feasibleTree(g); +} + +function networkSimplexRanker(g) { + networkSimplex(g); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/nesting-graph.js + + + + + +/* + * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs, + * adds appropriate edges to ensure that all cluster nodes are placed between + * these boundries, and ensures that the graph is connected. + * + * In addition we ensure, through the use of the minlen property, that nodes + * and subgraph border nodes to not end up on the same rank. + * + * Preconditions: + * + * 1. Input graph is a DAG + * 2. Nodes in the input graph has a minlen attribute + * + * Postconditions: + * + * 1. Input graph is connected. + * 2. Dummy nodes are added for the tops and bottoms of subgraphs. + * 3. The minlen attribute for nodes is adjusted to ensure nodes do not + * get placed on the same rank as subgraph border nodes. + * + * The nesting graph idea comes from Sander, "Layout of Compound Directed + * Graphs." + */ +function nesting_graph_run(g) { + var root = addDummyNode(g, 'root', {}, '_root'); + var depths = treeDepths(g); + var height = lodash_es_max(values/* default */.Z(depths)) - 1; // Note: depths is an Object not an array + var nodeSep = 2 * height + 1; + + g.graph().nestingRoot = root; + + // Multiply minlen by nodeSep to align nodes on non-border ranks. + forEach/* default */.Z(g.edges(), function (e) { + g.edge(e).minlen *= nodeSep; + }); + + // Calculate a weight that is sufficient to keep subgraphs vertically compact + var weight = sumWeights(g) + 1; + + // Create border nodes and link them up + forEach/* default */.Z(g.children(), function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + }); + + // Save the multiplier for node layers for later removal of empty border + // layers. + g.graph().nodeRankFactor = nodeSep; +} + +function nesting_graph_dfs(g, root, nodeSep, weight, height, depths, v) { + var children = g.children(v); + if (!children.length) { + if (v !== root) { + g.setEdge(root, v, { weight: 0, minlen: nodeSep }); + } + return; + } + + var top = addBorderNode(g, '_bt'); + var bottom = addBorderNode(g, '_bb'); + var label = g.node(v); + + g.setParent(top, v); + label.borderTop = top; + g.setParent(bottom, v); + label.borderBottom = bottom; + + forEach/* default */.Z(children, function (child) { + nesting_graph_dfs(g, root, nodeSep, weight, height, depths, child); + + var childNode = g.node(child); + var childTop = childNode.borderTop ? childNode.borderTop : child; + var childBottom = childNode.borderBottom ? childNode.borderBottom : child; + var thisWeight = childNode.borderTop ? weight : 2 * weight; + var minlen = childTop !== childBottom ? 1 : height - depths[v] + 1; + + g.setEdge(top, childTop, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + + g.setEdge(childBottom, bottom, { + weight: thisWeight, + minlen: minlen, + nestingEdge: true, + }); + }); + + if (!g.parent(v)) { + g.setEdge(root, top, { weight: 0, minlen: height + depths[v] }); + } +} + +function treeDepths(g) { + var depths = {}; + function dfs(v, depth) { + var children = g.children(v); + if (children && children.length) { + forEach/* default */.Z(children, function (child) { + dfs(child, depth + 1); + }); + } + depths[v] = depth; + } + forEach/* default */.Z(g.children(), function (v) { + dfs(v, 1); + }); + return depths; +} + +function sumWeights(g) { + return reduce/* default */.Z( + g.edges(), + function (acc, e) { + return acc + g.edge(e).weight; + }, + 0 + ); +} + +function cleanup(g) { + var graphLabel = g.graph(); + g.removeNode(graphLabel.nestingRoot); + delete graphLabel.nestingRoot; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.nestingEdge) { + g.removeEdge(e); + } + }); +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseClone.js + 15 modules +var _baseClone = __webpack_require__(48451); +;// CONCATENATED MODULE: ./node_modules/lodash-es/cloneDeep.js + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_SYMBOLS_FLAG = 4; + +/** + * This method is like `_.clone` except that it recursively clones `value`. + * + * @static + * @memberOf _ + * @since 1.0.0 + * @category Lang + * @param {*} value The value to recursively clone. + * @returns {*} Returns the deep cloned value. + * @see _.clone + * @example + * + * var objects = [{ 'a': 1 }, { 'b': 2 }]; + * + * var deep = _.cloneDeep(objects); + * console.log(deep[0] === objects[0]); + * // => false + */ +function cloneDeep(value) { + return (0,_baseClone/* default */.Z)(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); +} + +/* harmony default export */ const lodash_es_cloneDeep = (cloneDeep); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js + + + + +function addSubgraphConstraints(g, cg, vs) { + var prev = {}, + rootPrev; + + forEach/* default */.Z(vs, function (v) { + var child = g.parent(v), + parent, + prevChild; + while (child) { + parent = g.parent(child); + if (parent) { + prevChild = prev[parent]; + prev[parent] = child; + } else { + prevChild = rootPrev; + rootPrev = child; + } + if (prevChild && prevChild !== child) { + cg.setEdge(prevChild, child); + return; + } + child = parent; + } + }); + + /* + function dfs(v) { + var children = v ? g.children(v) : g.children(); + if (children.length) { + var min = Number.POSITIVE_INFINITY, + subgraphs = []; + _.each(children, function(child) { + var childMin = dfs(child); + if (g.children(child).length) { + subgraphs.push({ v: child, order: childMin }); + } + min = Math.min(min, childMin); + }); + _.reduce(_.sortBy(subgraphs, "order"), function(prev, curr) { + cg.setEdge(prev.v, curr.v); + return curr; + }); + return min; + } + return g.node(v).order; + } + dfs(undefined); + */ +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js + + + + + +/* + * Constructs a graph that can be used to sort a layer of nodes. The graph will + * contain all base and subgraph nodes from the request layer in their original + * hierarchy and any edges that are incident on these nodes and are of the type + * requested by the "relationship" parameter. + * + * Nodes from the requested rank that do not have parents are assigned a root + * node in the output graph, which is set in the root graph attribute. This + * makes it easy to walk the hierarchy of movable nodes during ordering. + * + * Pre-conditions: + * + * 1. Input graph is a DAG + * 2. Base nodes in the input graph have a rank attribute + * 3. Subgraph nodes in the input graph has minRank and maxRank attributes + * 4. Edges have an assigned weight + * + * Post-conditions: + * + * 1. Output graph has all nodes in the movable rank with preserved + * hierarchy. + * 2. Root nodes in the movable layer are made children of the node + * indicated by the root attribute of the graph. + * 3. Non-movable nodes incident on movable nodes, selected by the + * relationship parameter, are included in the graph (without hierarchy). + * 4. Edges incident on movable nodes, selected by the relationship + * parameter, are added to the output graph. + * 5. The weights for copied edges are aggregated as need, since the output + * graph is not a multi-graph. + */ +function buildLayerGraph(g, rank, relationship) { + var root = createRootNode(g), + result = new graphlib/* Graph */.k({ compound: true }) + .setGraph({ root: root }) + .setDefaultNodeLabel(function (v) { + return g.node(v); + }); + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v), + parent = g.parent(v); + + if (node.rank === rank || (node.minRank <= rank && rank <= node.maxRank)) { + result.setNode(v); + result.setParent(v, parent || root); + + // This assumes we have only short edges! + forEach/* default */.Z(g[relationship](v), function (e) { + var u = e.v === v ? e.w : e.v, + edge = result.edge(u, v), + weight = !isUndefined/* default */.Z(edge) ? edge.weight : 0; + result.setEdge(u, v, { weight: g.edge(e).weight + weight }); + }); + + if (has/* default */.Z(node, 'minRank')) { + result.setNode(v, { + borderLeft: node.borderLeft[rank], + borderRight: node.borderRight[rank], + }); + } + } + }); + + return result; +} + +function createRootNode(g) { + var v; + while (g.hasNode((v = uniqueId/* default */.Z('_root')))); + return v; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseZipObject.js +/** + * This base implementation of `_.zipObject` which assigns values using `assignFunc`. + * + * @private + * @param {Array} props The property identifiers. + * @param {Array} values The property values. + * @param {Function} assignFunc The function to assign values. + * @returns {Object} Returns the new object. + */ +function baseZipObject(props, values, assignFunc) { + var index = -1, + length = props.length, + valsLength = values.length, + result = {}; + + while (++index < length) { + var value = index < valsLength ? values[index] : undefined; + assignFunc(result, props[index], value); + } + return result; +} + +/* harmony default export */ const _baseZipObject = (baseZipObject); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/zipObject.js + + + +/** + * This method is like `_.fromPairs` except that it accepts two arrays, + * one of property identifiers and one of corresponding values. + * + * @static + * @memberOf _ + * @since 0.4.0 + * @category Array + * @param {Array} [props=[]] The property identifiers. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example + * + * _.zipObject(['a', 'b'], [1, 2]); + * // => { 'a': 1, 'b': 2 } + */ +function zipObject(props, values) { + return _baseZipObject(props || [], values || [], _assignValue/* default */.Z); +} + +/* harmony default export */ const lodash_es_zipObject = (zipObject); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseMap.js +var _baseMap = __webpack_require__(21018); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSortBy.js +/** + * The base implementation of `_.sortBy` which uses `comparer` to define the + * sort order of `array` and replaces criteria objects with their corresponding + * values. + * + * @private + * @param {Array} array The array to sort. + * @param {Function} comparer The function to define sort order. + * @returns {Array} Returns `array`. + */ +function baseSortBy(array, comparer) { + var length = array.length; + + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; +} + +/* harmony default export */ const _baseSortBy = (baseSortBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareAscending.js + + +/** + * Compares values to sort them in ascending order. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {number} Returns the sort order indicator for `value`. + */ +function compareAscending(value, other) { + if (value !== other) { + var valIsDefined = value !== undefined, + valIsNull = value === null, + valIsReflexive = value === value, + valIsSymbol = (0,isSymbol/* default */.Z)(value); + + var othIsDefined = other !== undefined, + othIsNull = other === null, + othIsReflexive = other === other, + othIsSymbol = (0,isSymbol/* default */.Z)(other); + + if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || + (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || + (valIsNull && othIsDefined && othIsReflexive) || + (!valIsDefined && othIsReflexive) || + !valIsReflexive) { + return 1; + } + if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || + (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || + (othIsNull && valIsDefined && valIsReflexive) || + (!othIsDefined && valIsReflexive) || + !othIsReflexive) { + return -1; + } + } + return 0; +} + +/* harmony default export */ const _compareAscending = (compareAscending); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_compareMultiple.js + + +/** + * Used by `_.orderBy` to compare multiple properties of a value to another + * and stable sort them. + * + * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, + * specify an order of "desc" for descending or "asc" for ascending sort order + * of corresponding values. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {boolean[]|string[]} orders The order to sort by for each property. + * @returns {number} Returns the sort order indicator for `object`. + */ +function compareMultiple(object, other, orders) { + var index = -1, + objCriteria = object.criteria, + othCriteria = other.criteria, + length = objCriteria.length, + ordersLength = orders.length; + + while (++index < length) { + var result = _compareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + var order = orders[index]; + return result * (order == 'desc' ? -1 : 1); + } + } + // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications + // that causes it, under certain circumstances, to provide the same value for + // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 + // for more details. + // + // This also ensures a stable sort in V8 and other engines. + // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; +} + +/* harmony default export */ const _compareMultiple = (compareMultiple); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseOrderBy.js + + + + + + + + + + +/** + * The base implementation of `_.orderBy` without param guards. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {string[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ +function baseOrderBy(collection, iteratees, orders) { + if (iteratees.length) { + iteratees = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + if ((0,isArray/* default */.Z)(iteratee)) { + return function(value) { + return (0,_baseGet/* default */.Z)(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity/* default */.Z]; + } + + var index = -1; + iteratees = (0,_arrayMap/* default */.Z)(iteratees, (0,_baseUnary/* default */.Z)(_baseIteratee/* default */.Z)); + + var result = (0,_baseMap/* default */.Z)(collection, function(value, key, collection) { + var criteria = (0,_arrayMap/* default */.Z)(iteratees, function(iteratee) { + return iteratee(value); + }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); + + return _baseSortBy(result, function(object, other) { + return _compareMultiple(object, other, orders); + }); +} + +/* harmony default export */ const _baseOrderBy = (baseOrderBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +;// CONCATENATED MODULE: ./node_modules/lodash-es/sortBy.js + + + + + +/** + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection thru each iteratee. This method + * performs a stable sort, that is, it preserves the original sort order of + * equal elements. The iteratees are invoked with one argument: (value). + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {...(Function|Function[])} [iteratees=[_.identity]] + * The iteratees to sort by. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ +var sortBy = (0,_baseRest/* default */.Z)(function(collection, iteratees) { + if (collection == null) { + return []; + } + var length = iteratees.length; + if (length > 1 && (0,_isIterateeCall/* default */.Z)(collection, iteratees[0], iteratees[1])) { + iteratees = []; + } else if (length > 2 && (0,_isIterateeCall/* default */.Z)(iteratees[0], iteratees[1], iteratees[2])) { + iteratees = [iteratees[0]]; + } + return _baseOrderBy(collection, (0,_baseFlatten/* default */.Z)(iteratees, 1), []); +}); + +/* harmony default export */ const lodash_es_sortBy = (sortBy); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/cross-count.js + + + + +/* + * A function that takes a layering (an array of layers, each with an array of + * ordererd nodes) and a graph and returns a weighted crossing count. + * + * Pre-conditions: + * + * 1. Input graph must be simple (not a multigraph), directed, and include + * only simple edges. + * 2. Edges in the input graph must have assigned weights. + * + * Post-conditions: + * + * 1. The graph and layering matrix are left unchanged. + * + * This algorithm is derived from Barth, et al., "Bilayer Cross Counting." + */ +function crossCount(g, layering) { + var cc = 0; + for (var i = 1; i < layering.length; ++i) { + cc += twoLayerCrossCount(g, layering[i - 1], layering[i]); + } + return cc; +} + +function twoLayerCrossCount(g, northLayer, southLayer) { + // Sort all of the edges between the north and south layers by their position + // in the north layer and then the south. Map these edges to the position of + // their head in the south layer. + var southPos = lodash_es_zipObject( + southLayer, + map/* default */.Z(southLayer, function (v, i) { + return i; + }) + ); + var southEntries = flatten/* default */.Z( + map/* default */.Z(northLayer, function (v) { + return lodash_es_sortBy( + map/* default */.Z(g.outEdges(v), function (e) { + return { pos: southPos[e.w], weight: g.edge(e).weight }; + }), + 'pos' + ); + }) + ); + + // Build the accumulator tree + var firstIndex = 1; + while (firstIndex < southLayer.length) firstIndex <<= 1; + var treeSize = 2 * firstIndex - 1; + firstIndex -= 1; + var tree = map/* default */.Z(new Array(treeSize), function () { + return 0; + }); + + // Calculate the weighted crossings + var cc = 0; + forEach/* default */.Z( + // @ts-expect-error + southEntries.forEach(function (entry) { + var index = entry.pos + firstIndex; + tree[index] += entry.weight; + var weightSum = 0; + // @ts-expect-error + while (index > 0) { + // @ts-expect-error + if (index % 2) { + weightSum += tree[index + 1]; + } + // @ts-expect-error + index = (index - 1) >> 1; + tree[index] += entry.weight; + } + cc += entry.weight * weightSum; + }) + ); + + return cc; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/init-order.js + + + + +/* + * Assigns an initial order value for each node by performing a DFS search + * starting from nodes in the first rank. Nodes are assigned an order in their + * rank as they are first visited. + * + * This approach comes from Gansner, et al., "A Technique for Drawing Directed + * Graphs." + * + * Returns a layering matrix with an array per layer and each layer sorted by + * the order of its nodes. + */ +function initOrder(g) { + var visited = {}; + var simpleNodes = filter/* default */.Z(g.nodes(), function (v) { + return !g.children(v).length; + }); + var maxRank = lodash_es_max( + map/* default */.Z(simpleNodes, function (v) { + return g.node(v).rank; + }) + ); + var layers = map/* default */.Z(range/* default */.Z(maxRank + 1), function () { + return []; + }); + + function dfs(v) { + if (has/* default */.Z(visited, v)) return; + visited[v] = true; + var node = g.node(v); + layers[node.rank].push(v); + forEach/* default */.Z(g.successors(v), dfs); + } + + var orderedVs = lodash_es_sortBy(simpleNodes, function (v) { + return g.node(v).rank; + }); + forEach/* default */.Z(orderedVs, dfs); + + return layers; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/barycenter.js + + + + +function barycenter(g, movable) { + return map/* default */.Z(movable, function (v) { + var inV = g.inEdges(v); + if (!inV.length) { + return { v: v }; + } else { + var result = reduce/* default */.Z( + inV, + function (acc, e) { + var edge = g.edge(e), + nodeU = g.node(e.v); + return { + sum: acc.sum + edge.weight * nodeU.order, + weight: acc.weight + edge.weight, + }; + }, + { sum: 0, weight: 0 } + ); + + return { + v: v, + barycenter: result.sum / result.weight, + weight: result.weight, + }; + } + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js + + + + +/* + * Given a list of entries of the form {v, barycenter, weight} and a + * constraint graph this function will resolve any conflicts between the + * constraint graph and the barycenters for the entries. If the barycenters for + * an entry would violate a constraint in the constraint graph then we coalesce + * the nodes in the conflict into a new node that respects the contraint and + * aggregates barycenter and weight information. + * + * This implementation is based on the description in Forster, "A Fast and + * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it + * differs in some specific details. + * + * Pre-conditions: + * + * 1. Each entry has the form {v, barycenter, weight}, or if the node has + * no barycenter, then {v}. + * + * Returns: + * + * A new list of entries of the form {vs, i, barycenter, weight}. The list + * `vs` may either be a singleton or it may be an aggregation of nodes + * ordered such that they do not violate constraints from the constraint + * graph. The property `i` is the lowest original index of any of the + * elements in `vs`. + */ +function resolveConflicts(entries, cg) { + var mappedEntries = {}; + forEach/* default */.Z(entries, function (entry, i) { + var tmp = (mappedEntries[entry.v] = { + indegree: 0, + in: [], + out: [], + vs: [entry.v], + i: i, + }); + if (!isUndefined/* default */.Z(entry.barycenter)) { + // @ts-expect-error + tmp.barycenter = entry.barycenter; + // @ts-expect-error + tmp.weight = entry.weight; + } + }); + + forEach/* default */.Z(cg.edges(), function (e) { + var entryV = mappedEntries[e.v]; + var entryW = mappedEntries[e.w]; + if (!isUndefined/* default */.Z(entryV) && !isUndefined/* default */.Z(entryW)) { + entryW.indegree++; + entryV.out.push(mappedEntries[e.w]); + } + }); + + var sourceSet = filter/* default */.Z(mappedEntries, function (entry) { + // @ts-expect-error + return !entry.indegree; + }); + + return doResolveConflicts(sourceSet); +} + +function doResolveConflicts(sourceSet) { + var entries = []; + + function handleIn(vEntry) { + return function (uEntry) { + if (uEntry.merged) { + return; + } + if ( + isUndefined/* default */.Z(uEntry.barycenter) || + isUndefined/* default */.Z(vEntry.barycenter) || + uEntry.barycenter >= vEntry.barycenter + ) { + mergeEntries(vEntry, uEntry); + } + }; + } + + function handleOut(vEntry) { + return function (wEntry) { + wEntry['in'].push(vEntry); + if (--wEntry.indegree === 0) { + sourceSet.push(wEntry); + } + }; + } + + while (sourceSet.length) { + var entry = sourceSet.pop(); + entries.push(entry); + forEach/* default */.Z(entry['in'].reverse(), handleIn(entry)); + forEach/* default */.Z(entry.out, handleOut(entry)); + } + + return map/* default */.Z( + filter/* default */.Z(entries, function (entry) { + return !entry.merged; + }), + function (entry) { + return pick/* default */.Z(entry, ['vs', 'i', 'barycenter', 'weight']); + } + ); +} + +function mergeEntries(target, source) { + var sum = 0; + var weight = 0; + + if (target.weight) { + sum += target.barycenter * target.weight; + weight += target.weight; + } + + if (source.weight) { + sum += source.barycenter * source.weight; + weight += source.weight; + } + + target.vs = source.vs.concat(target.vs); + target.barycenter = sum / weight; + target.weight = weight; + target.i = Math.min(source.i, target.i); + source.merged = true; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort.js + + + + + +function sort(entries, biasRight) { + var parts = partition(entries, function (entry) { + return has/* default */.Z(entry, 'barycenter'); + }); + var sortable = parts.lhs, + unsortable = lodash_es_sortBy(parts.rhs, function (entry) { + return -entry.i; + }), + vs = [], + sum = 0, + weight = 0, + vsIndex = 0; + + sortable.sort(compareWithBias(!!biasRight)); + + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + + forEach/* default */.Z(sortable, function (entry) { + vsIndex += entry.vs.length; + vs.push(entry.vs); + sum += entry.barycenter * entry.weight; + weight += entry.weight; + vsIndex = consumeUnsortable(vs, unsortable, vsIndex); + }); + + var result = { vs: flatten/* default */.Z(vs) }; + if (weight) { + result.barycenter = sum / weight; + result.weight = weight; + } + return result; +} + +function consumeUnsortable(vs, unsortable, index) { + var last; + while (unsortable.length && (last = lodash_es_last(unsortable)).i <= index) { + unsortable.pop(); + vs.push(last.vs); + index++; + } + return index; +} + +function compareWithBias(bias) { + return function (entryV, entryW) { + if (entryV.barycenter < entryW.barycenter) { + return -1; + } else if (entryV.barycenter > entryW.barycenter) { + return 1; + } + + return !bias ? entryV.i - entryW.i : entryW.i - entryV.i; + }; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js + + + + + + + +function sortSubgraph(g, v, cg, biasRight) { + var movable = g.children(v); + var node = g.node(v); + var bl = node ? node.borderLeft : undefined; + var br = node ? node.borderRight : undefined; + var subgraphs = {}; + + if (bl) { + movable = filter/* default */.Z(movable, function (w) { + return w !== bl && w !== br; + }); + } + + var barycenters = barycenter(g, movable); + forEach/* default */.Z(barycenters, function (entry) { + if (g.children(entry.v).length) { + var subgraphResult = sortSubgraph(g, entry.v, cg, biasRight); + subgraphs[entry.v] = subgraphResult; + if (has/* default */.Z(subgraphResult, 'barycenter')) { + mergeBarycenters(entry, subgraphResult); + } + } + }); + + var entries = resolveConflicts(barycenters, cg); + expandSubgraphs(entries, subgraphs); + + var result = sort(entries, biasRight); + + if (bl) { + result.vs = flatten/* default */.Z([bl, result.vs, br]); + if (g.predecessors(bl).length) { + var blPred = g.node(g.predecessors(bl)[0]), + brPred = g.node(g.predecessors(br)[0]); + if (!has/* default */.Z(result, 'barycenter')) { + result.barycenter = 0; + result.weight = 0; + } + result.barycenter = + (result.barycenter * result.weight + blPred.order + brPred.order) / (result.weight + 2); + result.weight += 2; + } + } + + return result; +} + +function expandSubgraphs(entries, subgraphs) { + forEach/* default */.Z(entries, function (entry) { + entry.vs = flatten/* default */.Z( + entry.vs.map(function (v) { + if (subgraphs[v]) { + return subgraphs[v].vs; + } + return v; + }) + ); + }); +} + +function mergeBarycenters(target, other) { + if (!isUndefined/* default */.Z(target.barycenter)) { + target.barycenter = + (target.barycenter * target.weight + other.barycenter * other.weight) / + (target.weight + other.weight); + target.weight += other.weight; + } else { + target.barycenter = other.barycenter; + target.weight = other.weight; + } +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/order/index.js + + + + + + + + + + + +/* + * Applies heuristics to minimize edge crossings in the graph and sets the best + * order solution as an order attribute on each node. + * + * Pre-conditions: + * + * 1. Graph must be DAG + * 2. Graph nodes must be objects with a "rank" attribute + * 3. Graph edges must have the "weight" attribute + * + * Post-conditions: + * + * 1. Graph nodes will have an "order" attribute based on the results of the + * algorithm. + */ +function order(g) { + var maxRank = util_maxRank(g), + downLayerGraphs = buildLayerGraphs(g, range/* default */.Z(1, maxRank + 1), 'inEdges'), + upLayerGraphs = buildLayerGraphs(g, range/* default */.Z(maxRank - 1, -1, -1), 'outEdges'); + + var layering = initOrder(g); + assignOrder(g, layering); + + var bestCC = Number.POSITIVE_INFINITY, + best; + + for (var i = 0, lastBest = 0; lastBest < 4; ++i, ++lastBest) { + sweepLayerGraphs(i % 2 ? downLayerGraphs : upLayerGraphs, i % 4 >= 2); + + layering = buildLayerMatrix(g); + var cc = crossCount(g, layering); + if (cc < bestCC) { + lastBest = 0; + best = lodash_es_cloneDeep(layering); + bestCC = cc; + } + } + + assignOrder(g, best); +} + +function buildLayerGraphs(g, ranks, relationship) { + return map/* default */.Z(ranks, function (rank) { + return buildLayerGraph(g, rank, relationship); + }); +} + +function sweepLayerGraphs(layerGraphs, biasRight) { + var cg = new graphlib/* Graph */.k(); + forEach/* default */.Z(layerGraphs, function (lg) { + var root = lg.graph().root; + var sorted = sortSubgraph(lg, root, cg, biasRight); + forEach/* default */.Z(sorted.vs, function (v, i) { + lg.node(v).order = i; + }); + addSubgraphConstraints(lg, cg, sorted.vs); + }); +} + +function assignOrder(g, layering) { + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, i) { + g.node(v).order = i; + }); + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js + + + + +function parentDummyChains(g) { + var postorderNums = parent_dummy_chains_postorder(g); + + forEach/* default */.Z(g.graph().dummyChains, function (v) { + var node = g.node(v); + var edgeObj = node.edgeObj; + var pathData = findPath(g, postorderNums, edgeObj.v, edgeObj.w); + var path = pathData.path; + var lca = pathData.lca; + var pathIdx = 0; + var pathV = path[pathIdx]; + var ascending = true; + + while (v !== edgeObj.w) { + node = g.node(v); + + if (ascending) { + while ((pathV = path[pathIdx]) !== lca && g.node(pathV).maxRank < node.rank) { + pathIdx++; + } + + if (pathV === lca) { + ascending = false; + } + } + + if (!ascending) { + while ( + pathIdx < path.length - 1 && + g.node((pathV = path[pathIdx + 1])).minRank <= node.rank + ) { + pathIdx++; + } + pathV = path[pathIdx]; + } + + g.setParent(v, pathV); + v = g.successors(v)[0]; + } + }); +} + +// Find a path from v to w through the lowest common ancestor (LCA). Return the +// full path and the LCA. +function findPath(g, postorderNums, v, w) { + var vPath = []; + var wPath = []; + var low = Math.min(postorderNums[v].low, postorderNums[w].low); + var lim = Math.max(postorderNums[v].lim, postorderNums[w].lim); + var parent; + var lca; + + // Traverse up from v to find the LCA + parent = v; + do { + parent = g.parent(parent); + vPath.push(parent); + } while (parent && (postorderNums[parent].low > low || lim > postorderNums[parent].lim)); + lca = parent; + + // Traverse from w to LCA + parent = w; + while ((parent = g.parent(parent)) !== lca) { + wPath.push(parent); + } + + return { path: vPath.concat(wPath.reverse()), lca: lca }; +} + +function parent_dummy_chains_postorder(g) { + var result = {}; + var lim = 0; + + function dfs(v) { + var low = lim; + forEach/* default */.Z(g.children(v), dfs); + result[v] = { low: low, lim: lim++ }; + } + forEach/* default */.Z(g.children(), dfs); + + return result; +} + +// EXTERNAL MODULE: ./node_modules/lodash-es/_castFunction.js +var _castFunction = __webpack_require__(68882); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forOwn.js + + + +/** + * Iterates over own enumerable string keyed properties of an object and + * invokes `iteratee` for each property. The iteratee is invoked with three + * arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forOwnRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forOwn(object, iteratee) { + return object && (0,_baseForOwn/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee)); +} + +/* harmony default export */ const lodash_es_forOwn = (forOwn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFor.js + 1 modules +var _baseFor = __webpack_require__(61395); +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/forIn.js + + + + +/** + * Iterates over own and inherited enumerable string keyed properties of an + * object and invokes `iteratee` for each property. The iteratee is invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. + * + * @static + * @memberOf _ + * @since 0.3.0 + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Object} Returns `object`. + * @see _.forInRight + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). + */ +function forIn(object, iteratee) { + return object == null + ? object + : (0,_baseFor/* default */.Z)(object, (0,_castFunction/* default */.Z)(iteratee), keysIn/* default */.Z); +} + +/* harmony default export */ const lodash_es_forIn = (forIn); + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/bk.js + + + + +/* + * This module provides coordinate assignment based on Brandes and Köpf, "Fast + * and Simple Horizontal Coordinate Assignment." + */ + + + +/* + * Marks all edges in the graph with a type-1 conflict with the "type1Conflict" + * property. A type-1 conflict is one where a non-inner segment crosses an + * inner segment. An inner segment is an edge with both incident nodes marked + * with the "dummy" property. + * + * This algorithm scans layer by layer, starting with the second, for type-1 + * conflicts between the current layer and the previous layer. For each layer + * it scans the nodes from left to right until it reaches one that is incident + * on an inner segment. It then scans predecessors to determine if they have + * edges that cross that inner segment. At the end a final scan is done for all + * nodes on the current rank to see if they cross the last visited inner + * segment. + * + * This algorithm (safely) assumes that a dummy node will only be incident on a + * single node in the layers being scanned. + */ +function findType1Conflicts(g, layering) { + var conflicts = {}; + + function visitLayer(prevLayer, layer) { + var // last visited node in the previous layer that is incident on an inner + // segment. + k0 = 0, + // Tracks the last node in this layer scanned for crossings with a type-1 + // segment. + scanPos = 0, + prevLayerLength = prevLayer.length, + lastNode = lodash_es_last(layer); + + forEach/* default */.Z(layer, function (v, i) { + var w = findOtherInnerSegmentNode(g, v), + k1 = w ? g.node(w).order : prevLayerLength; + + if (w || v === lastNode) { + forEach/* default */.Z(layer.slice(scanPos, i + 1), function (scanNode) { + forEach/* default */.Z(g.predecessors(scanNode), function (u) { + var uLabel = g.node(u), + uPos = uLabel.order; + if ((uPos < k0 || k1 < uPos) && !(uLabel.dummy && g.node(scanNode).dummy)) { + addConflict(conflicts, u, scanNode); + } + }); + }); + // @ts-expect-error + scanPos = i + 1; + k0 = k1; + } + }); + + return layer; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findType2Conflicts(g, layering) { + var conflicts = {}; + + function scan(south, southPos, southEnd, prevNorthBorder, nextNorthBorder) { + var v; + forEach/* default */.Z(range/* default */.Z(southPos, southEnd), function (i) { + v = south[i]; + if (g.node(v).dummy) { + forEach/* default */.Z(g.predecessors(v), function (u) { + var uNode = g.node(u); + if (uNode.dummy && (uNode.order < prevNorthBorder || uNode.order > nextNorthBorder)) { + addConflict(conflicts, u, v); + } + }); + } + }); + } + + function visitLayer(north, south) { + var prevNorthPos = -1, + nextNorthPos, + southPos = 0; + + forEach/* default */.Z(south, function (v, southLookahead) { + if (g.node(v).dummy === 'border') { + var predecessors = g.predecessors(v); + if (predecessors.length) { + nextNorthPos = g.node(predecessors[0]).order; + scan(south, southPos, southLookahead, prevNorthPos, nextNorthPos); + // @ts-expect-error + southPos = southLookahead; + prevNorthPos = nextNorthPos; + } + } + scan(south, southPos, south.length, nextNorthPos, north.length); + }); + + return south; + } + + reduce/* default */.Z(layering, visitLayer); + return conflicts; +} + +function findOtherInnerSegmentNode(g, v) { + if (g.node(v).dummy) { + return lodash_es_find(g.predecessors(v), function (u) { + return g.node(u).dummy; + }); + } +} + +function addConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + + var conflictsV = conflicts[v]; + if (!conflictsV) { + conflicts[v] = conflictsV = {}; + } + conflictsV[w] = true; +} + +function hasConflict(conflicts, v, w) { + if (v > w) { + var tmp = v; + v = w; + w = tmp; + } + return has/* default */.Z(conflicts[v], w); +} + +/* + * Try to align nodes into vertical "blocks" where possible. This algorithm + * attempts to align a node with one of its median neighbors. If the edge + * connecting a neighbor is a type-1 conflict then we ignore that possibility. + * If a previous node has already formed a block with a node after the node + * we're trying to form a block with, we also ignore that possibility - our + * blocks would be split in that scenario. + */ +function verticalAlignment(g, layering, conflicts, neighborFn) { + var root = {}, + align = {}, + pos = {}; + + // We cache the position here based on the layering because the graph and + // layering may be out of sync. The layering matrix is manipulated to + // generate different extreme alignments. + forEach/* default */.Z(layering, function (layer) { + forEach/* default */.Z(layer, function (v, order) { + root[v] = v; + align[v] = v; + pos[v] = order; + }); + }); + + forEach/* default */.Z(layering, function (layer) { + var prevIdx = -1; + forEach/* default */.Z(layer, function (v) { + var ws = neighborFn(v); + if (ws.length) { + ws = lodash_es_sortBy(ws, function (w) { + return pos[w]; + }); + var mp = (ws.length - 1) / 2; + for (var i = Math.floor(mp), il = Math.ceil(mp); i <= il; ++i) { + var w = ws[i]; + if (align[v] === v && prevIdx < pos[w] && !hasConflict(conflicts, v, w)) { + align[w] = v; + align[v] = root[v] = root[w]; + prevIdx = pos[w]; + } + } + } + }); + }); + + return { root: root, align: align }; +} + +function horizontalCompaction(g, layering, root, align, reverseSep) { + // This portion of the algorithm differs from BK due to a number of problems. + // Instead of their algorithm we construct a new block graph and do two + // sweeps. The first sweep places blocks with the smallest possible + // coordinates. The second sweep removes unused space by moving blocks to the + // greatest coordinates without violating separation. + var xs = {}, + blockG = buildBlockGraph(g, layering, root, reverseSep), + borderType = reverseSep ? 'borderLeft' : 'borderRight'; + + function iterate(setXsFunc, nextNodesFunc) { + var stack = blockG.nodes(); + var elem = stack.pop(); + var visited = {}; + while (elem) { + if (visited[elem]) { + setXsFunc(elem); + } else { + visited[elem] = true; + stack.push(elem); + stack = stack.concat(nextNodesFunc(elem)); + } + + elem = stack.pop(); + } + } + + // First pass, assign smallest coordinates + function pass1(elem) { + xs[elem] = blockG.inEdges(elem).reduce(function (acc, e) { + return Math.max(acc, xs[e.v] + blockG.edge(e)); + }, 0); + } + + // Second pass, assign greatest coordinates + function pass2(elem) { + var min = blockG.outEdges(elem).reduce(function (acc, e) { + return Math.min(acc, xs[e.w] - blockG.edge(e)); + }, Number.POSITIVE_INFINITY); + + var node = g.node(elem); + if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) { + xs[elem] = Math.max(xs[elem], min); + } + } + + iterate(pass1, blockG.predecessors.bind(blockG)); + iterate(pass2, blockG.successors.bind(blockG)); + + // Assign x coordinates to all nodes + forEach/* default */.Z(align, function (v) { + xs[v] = xs[root[v]]; + }); + + return xs; +} + +function buildBlockGraph(g, layering, root, reverseSep) { + var blockGraph = new graphlib/* Graph */.k(), + graphLabel = g.graph(), + sepFn = sep(graphLabel.nodesep, graphLabel.edgesep, reverseSep); + + forEach/* default */.Z(layering, function (layer) { + var u; + forEach/* default */.Z(layer, function (v) { + var vRoot = root[v]; + blockGraph.setNode(vRoot); + if (u) { + var uRoot = root[u], + prevMax = blockGraph.edge(uRoot, vRoot); + blockGraph.setEdge(uRoot, vRoot, Math.max(sepFn(g, v, u), prevMax || 0)); + } + u = v; + }); + }); + + return blockGraph; +} + +/* + * Returns the alignment that has the smallest width of the given alignments. + */ +function findSmallestWidthAlignment(g, xss) { + return lodash_es_minBy(values/* default */.Z(xss), function (xs) { + var max = Number.NEGATIVE_INFINITY; + var min = Number.POSITIVE_INFINITY; + + lodash_es_forIn(xs, function (x, v) { + var halfWidth = width(g, v) / 2; + + max = Math.max(x + halfWidth, max); + min = Math.min(x - halfWidth, min); + }); + + return max - min; + }); +} + +/* + * Align the coordinates of each of the layout alignments such that + * left-biased alignments have their minimum coordinate at the same point as + * the minimum coordinate of the smallest width alignment and right-biased + * alignments have their maximum coordinate at the same point as the maximum + * coordinate of the smallest width alignment. + */ +function alignCoordinates(xss, alignTo) { + var alignToVals = values/* default */.Z(alignTo), + alignToMin = lodash_es_min(alignToVals), + alignToMax = lodash_es_max(alignToVals); + + forEach/* default */.Z(['u', 'd'], function (vert) { + forEach/* default */.Z(['l', 'r'], function (horiz) { + var alignment = vert + horiz, + xs = xss[alignment], + delta; + if (xs === alignTo) return; + + var xsVals = values/* default */.Z(xs); + delta = horiz === 'l' ? alignToMin - lodash_es_min(xsVals) : alignToMax - lodash_es_max(xsVals); + + if (delta) { + xss[alignment] = lodash_es_mapValues(xs, function (x) { + return x + delta; + }); + } + }); + }); +} + +function balance(xss, align) { + return lodash_es_mapValues(xss.ul, function (ignore, v) { + if (align) { + return xss[align.toLowerCase()][v]; + } else { + var xs = lodash_es_sortBy(map/* default */.Z(xss, v)); + return (xs[1] + xs[2]) / 2; + } + }); +} + +function positionX(g) { + var layering = buildLayerMatrix(g); + var conflicts = merge/* default */.Z(findType1Conflicts(g, layering), findType2Conflicts(g, layering)); + + var xss = {}; + var adjustedLayering; + forEach/* default */.Z(['u', 'd'], function (vert) { + adjustedLayering = vert === 'u' ? layering : values/* default */.Z(layering).reverse(); + forEach/* default */.Z(['l', 'r'], function (horiz) { + if (horiz === 'r') { + adjustedLayering = map/* default */.Z(adjustedLayering, function (inner) { + return values/* default */.Z(inner).reverse(); + }); + } + + var neighborFn = (vert === 'u' ? g.predecessors : g.successors).bind(g); + var align = verticalAlignment(g, adjustedLayering, conflicts, neighborFn); + var xs = horizontalCompaction(g, adjustedLayering, align.root, align.align, horiz === 'r'); + if (horiz === 'r') { + xs = lodash_es_mapValues(xs, function (x) { + return -x; + }); + } + xss[vert + horiz] = xs; + }); + }); + + var smallestWidth = findSmallestWidthAlignment(g, xss); + alignCoordinates(xss, smallestWidth); + return balance(xss, g.graph().align); +} + +function sep(nodeSep, edgeSep, reverseSep) { + return function (g, v, w) { + var vLabel = g.node(v); + var wLabel = g.node(w); + var sum = 0; + var delta; + + sum += vLabel.width / 2; + if (has/* default */.Z(vLabel, 'labelpos')) { + switch (vLabel.labelpos.toLowerCase()) { + case 'l': + delta = -vLabel.width / 2; + break; + case 'r': + delta = vLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + sum += (vLabel.dummy ? edgeSep : nodeSep) / 2; + sum += (wLabel.dummy ? edgeSep : nodeSep) / 2; + + sum += wLabel.width / 2; + if (has/* default */.Z(wLabel, 'labelpos')) { + switch (wLabel.labelpos.toLowerCase()) { + case 'l': + delta = wLabel.width / 2; + break; + case 'r': + delta = -wLabel.width / 2; + break; + } + } + if (delta) { + sum += reverseSep ? delta : -delta; + } + delta = 0; + + return sum; + }; +} + +function width(g, v) { + return g.node(v).width; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/position/index.js + + + + + + +function position(g) { + g = asNonCompoundGraph(g); + + positionY(g); + lodash_es_forOwn(positionX(g), function (x, v) { + g.node(v).x = x; + }); +} + +function positionY(g) { + var layering = buildLayerMatrix(g); + var rankSep = g.graph().ranksep; + var prevY = 0; + forEach/* default */.Z(layering, function (layer) { + var maxHeight = lodash_es_max( + map/* default */.Z(layer, function (v) { + return g.node(v).height; + }) + ); + forEach/* default */.Z(layer, function (v) { + g.node(v).y = prevY + maxHeight / 2; + }); + prevY += maxHeight + rankSep; + }); +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/layout.js + + + + + + + + + + + + + + + +function layout(g, opts) { + var time = opts && opts.debugTiming ? util_time : notime; + time('layout', function () { + var layoutGraph = time(' buildLayoutGraph', function () { + return buildLayoutGraph(g); + }); + time(' runLayout', function () { + runLayout(layoutGraph, time); + }); + time(' updateInputGraph', function () { + updateInputGraph(g, layoutGraph); + }); + }); +} + +function runLayout(g, time) { + time(' makeSpaceForEdgeLabels', function () { + makeSpaceForEdgeLabels(g); + }); + time(' removeSelfEdges', function () { + removeSelfEdges(g); + }); + time(' acyclic', function () { + run(g); + }); + time(' nestingGraph.run', function () { + nesting_graph_run(g); + }); + time(' rank', function () { + rank(asNonCompoundGraph(g)); + }); + time(' injectEdgeLabelProxies', function () { + injectEdgeLabelProxies(g); + }); + time(' removeEmptyRanks', function () { + removeEmptyRanks(g); + }); + time(' nestingGraph.cleanup', function () { + cleanup(g); + }); + time(' normalizeRanks', function () { + normalizeRanks(g); + }); + time(' assignRankMinMax', function () { + assignRankMinMax(g); + }); + time(' removeEdgeLabelProxies', function () { + removeEdgeLabelProxies(g); + }); + time(' normalize.run', function () { + normalize_run(g); + }); + time(' parentDummyChains', function () { + parentDummyChains(g); + }); + time(' addBorderSegments', function () { + addBorderSegments(g); + }); + time(' order', function () { + order(g); + }); + time(' insertSelfEdges', function () { + insertSelfEdges(g); + }); + time(' adjustCoordinateSystem', function () { + adjust(g); + }); + time(' position', function () { + position(g); + }); + time(' positionSelfEdges', function () { + positionSelfEdges(g); + }); + time(' removeBorderNodes', function () { + removeBorderNodes(g); + }); + time(' normalize.undo', function () { + normalize_undo(g); + }); + time(' fixupEdgeLabelCoords', function () { + fixupEdgeLabelCoords(g); + }); + time(' undoCoordinateSystem', function () { + coordinate_system_undo(g); + }); + time(' translateGraph', function () { + translateGraph(g); + }); + time(' assignNodeIntersects', function () { + assignNodeIntersects(g); + }); + time(' reversePoints', function () { + reversePointsForReversedEdges(g); + }); + time(' acyclic.undo', function () { + undo(g); + }); +} + +/* + * Copies final layout information from the layout graph back to the input + * graph. This process only copies whitelisted attributes from the layout graph + * to the input graph, so it serves as a good place to determine what + * attributes can influence layout. + */ +function updateInputGraph(inputGraph, layoutGraph) { + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var inputLabel = inputGraph.node(v); + var layoutLabel = layoutGraph.node(v); + + if (inputLabel) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + + if (layoutGraph.children(v).length) { + inputLabel.width = layoutLabel.width; + inputLabel.height = layoutLabel.height; + } + } + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var inputLabel = inputGraph.edge(e); + var layoutLabel = layoutGraph.edge(e); + + inputLabel.points = layoutLabel.points; + if (has/* default */.Z(layoutLabel, 'x')) { + inputLabel.x = layoutLabel.x; + inputLabel.y = layoutLabel.y; + } + }); + + inputGraph.graph().width = layoutGraph.graph().width; + inputGraph.graph().height = layoutGraph.graph().height; +} + +var graphNumAttrs = ['nodesep', 'edgesep', 'ranksep', 'marginx', 'marginy']; +var graphDefaults = { ranksep: 50, edgesep: 20, nodesep: 50, rankdir: 'tb' }; +var graphAttrs = ['acyclicer', 'ranker', 'rankdir', 'align']; +var nodeNumAttrs = ['width', 'height']; +var nodeDefaults = { width: 0, height: 0 }; +var edgeNumAttrs = ['minlen', 'weight', 'width', 'height', 'labeloffset']; +var edgeDefaults = { + minlen: 1, + weight: 1, + width: 0, + height: 0, + labeloffset: 10, + labelpos: 'r', +}; +var edgeAttrs = ['labelpos']; + +/* + * Constructs a new graph from the input graph, which can be used for layout. + * This process copies only whitelisted attributes from the input graph to the + * layout graph. Thus this function serves as a good place to determine what + * attributes can influence layout. + */ +function buildLayoutGraph(inputGraph) { + var g = new graphlib/* Graph */.k({ multigraph: true, compound: true }); + var graph = canonicalize(inputGraph.graph()); + + g.setGraph( + merge/* default */.Z({}, graphDefaults, selectNumberAttrs(graph, graphNumAttrs), pick/* default */.Z(graph, graphAttrs)) + ); + + forEach/* default */.Z(inputGraph.nodes(), function (v) { + var node = canonicalize(inputGraph.node(v)); + g.setNode(v, defaults/* default */.Z(selectNumberAttrs(node, nodeNumAttrs), nodeDefaults)); + g.setParent(v, inputGraph.parent(v)); + }); + + forEach/* default */.Z(inputGraph.edges(), function (e) { + var edge = canonicalize(inputGraph.edge(e)); + g.setEdge( + e, + merge/* default */.Z({}, edgeDefaults, selectNumberAttrs(edge, edgeNumAttrs), pick/* default */.Z(edge, edgeAttrs)) + ); + }); + + return g; +} + +/* + * This idea comes from the Gansner paper: to account for edge labels in our + * layout we split each rank in half by doubling minlen and halving ranksep. + * Then we can place labels at these mid-points between nodes. + * + * We also add some minimal padding to the width to push the label for the edge + * away from the edge itself a bit. + */ +function makeSpaceForEdgeLabels(g) { + var graph = g.graph(); + graph.ranksep /= 2; + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + edge.minlen *= 2; + if (edge.labelpos.toLowerCase() !== 'c') { + if (graph.rankdir === 'TB' || graph.rankdir === 'BT') { + edge.width += edge.labeloffset; + } else { + edge.height += edge.labeloffset; + } + } + }); +} + +/* + * Creates temporary dummy nodes that capture the rank in which each edge's + * label is going to, if it has one of non-zero width and height. We do this + * so that we can safely remove empty ranks while preserving balance for the + * label's position. + */ +function injectEdgeLabelProxies(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.width && edge.height) { + var v = g.node(e.v); + var w = g.node(e.w); + var label = { rank: (w.rank - v.rank) / 2 + v.rank, e: e }; + addDummyNode(g, 'edge-proxy', label, '_ep'); + } + }); +} + +function assignRankMinMax(g) { + var maxRank = 0; + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.borderTop) { + node.minRank = g.node(node.borderTop).rank; + node.maxRank = g.node(node.borderBottom).rank; + // @ts-expect-error + maxRank = lodash_es_max(maxRank, node.maxRank); + } + }); + g.graph().maxRank = maxRank; +} + +function removeEdgeLabelProxies(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'edge-proxy') { + g.edge(node.e).labelRank = node.rank; + g.removeNode(v); + } + }); +} + +function translateGraph(g) { + var minX = Number.POSITIVE_INFINITY; + var maxX = 0; + var minY = Number.POSITIVE_INFINITY; + var maxY = 0; + var graphLabel = g.graph(); + var marginX = graphLabel.marginx || 0; + var marginY = graphLabel.marginy || 0; + + function getExtremes(attrs) { + var x = attrs.x; + var y = attrs.y; + var w = attrs.width; + var h = attrs.height; + minX = Math.min(minX, x - w / 2); + maxX = Math.max(maxX, x + w / 2); + minY = Math.min(minY, y - h / 2); + maxY = Math.max(maxY, y + h / 2); + } + + forEach/* default */.Z(g.nodes(), function (v) { + getExtremes(g.node(v)); + }); + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + getExtremes(edge); + } + }); + + minX -= marginX; + minY -= marginY; + + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + node.x -= minX; + node.y -= minY; + }); + + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + forEach/* default */.Z(edge.points, function (p) { + p.x -= minX; + p.y -= minY; + }); + if (has/* default */.Z(edge, 'x')) { + edge.x -= minX; + } + if (has/* default */.Z(edge, 'y')) { + edge.y -= minY; + } + }); + + graphLabel.width = maxX - minX + marginX; + graphLabel.height = maxY - minY + marginY; +} + +function assignNodeIntersects(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + var nodeV = g.node(e.v); + var nodeW = g.node(e.w); + var p1, p2; + if (!edge.points) { + edge.points = []; + p1 = nodeW; + p2 = nodeV; + } else { + p1 = edge.points[0]; + p2 = edge.points[edge.points.length - 1]; + } + edge.points.unshift(intersectRect(nodeV, p1)); + edge.points.push(intersectRect(nodeW, p2)); + }); +} + +function fixupEdgeLabelCoords(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (has/* default */.Z(edge, 'x')) { + if (edge.labelpos === 'l' || edge.labelpos === 'r') { + edge.width -= edge.labeloffset; + } + switch (edge.labelpos) { + case 'l': + edge.x -= edge.width / 2 + edge.labeloffset; + break; + case 'r': + edge.x += edge.width / 2 + edge.labeloffset; + break; + } + } + }); +} + +function reversePointsForReversedEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + var edge = g.edge(e); + if (edge.reversed) { + edge.points.reverse(); + } + }); +} + +function removeBorderNodes(g) { + forEach/* default */.Z(g.nodes(), function (v) { + if (g.children(v).length) { + var node = g.node(v); + var t = g.node(node.borderTop); + var b = g.node(node.borderBottom); + var l = g.node(lodash_es_last(node.borderLeft)); + var r = g.node(lodash_es_last(node.borderRight)); + + node.width = Math.abs(r.x - l.x); + node.height = Math.abs(b.y - t.y); + node.x = l.x + node.width / 2; + node.y = t.y + node.height / 2; + } + }); + + forEach/* default */.Z(g.nodes(), function (v) { + if (g.node(v).dummy === 'border') { + g.removeNode(v); + } + }); +} + +function removeSelfEdges(g) { + forEach/* default */.Z(g.edges(), function (e) { + if (e.v === e.w) { + var node = g.node(e.v); + if (!node.selfEdges) { + node.selfEdges = []; + } + node.selfEdges.push({ e: e, label: g.edge(e) }); + g.removeEdge(e); + } + }); +} + +function insertSelfEdges(g) { + var layers = buildLayerMatrix(g); + forEach/* default */.Z(layers, function (layer) { + var orderShift = 0; + forEach/* default */.Z(layer, function (v, i) { + var node = g.node(v); + node.order = i + orderShift; + forEach/* default */.Z(node.selfEdges, function (selfEdge) { + addDummyNode( + g, + 'selfedge', + { + width: selfEdge.label.width, + height: selfEdge.label.height, + rank: node.rank, + order: i + ++orderShift, + e: selfEdge.e, + label: selfEdge.label, + }, + '_se' + ); + }); + delete node.selfEdges; + }); + }); +} + +function positionSelfEdges(g) { + forEach/* default */.Z(g.nodes(), function (v) { + var node = g.node(v); + if (node.dummy === 'selfedge') { + var selfNode = g.node(node.e.v); + var x = selfNode.x + selfNode.width / 2; + var y = selfNode.y; + var dx = node.x - x; + var dy = selfNode.height / 2; + g.setEdge(node.e, node.label); + g.removeNode(v); + node.label.points = [ + { x: x + (2 * dx) / 3, y: y - dy }, + { x: x + (5 * dx) / 6, y: y - dy }, + { x: x + dx, y: y }, + { x: x + (5 * dx) / 6, y: y + dy }, + { x: x + (2 * dx) / 3, y: y + dy }, + ]; + node.label.x = node.x; + node.label.y = node.y; + } + }); +} + +function selectNumberAttrs(obj, attrs) { + return lodash_es_mapValues(pick/* default */.Z(obj, attrs), Number); +} + +function canonicalize(attrs) { + var newAttrs = {}; + forEach/* default */.Z(attrs, function (v, k) { + newAttrs[k.toLowerCase()] = v; + }); + return newAttrs; +} + +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/dagre/index.js + + + + + + + + +/***/ }), + +/***/ 52544: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + k: () => (/* binding */ Graph) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/has.js + 1 modules +var has = __webpack_require__(17452); +// EXTERNAL MODULE: ./node_modules/lodash-es/constant.js +var constant = __webpack_require__(62002); +// EXTERNAL MODULE: ./node_modules/lodash-es/isFunction.js +var isFunction = __webpack_require__(73234); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +// EXTERNAL MODULE: ./node_modules/lodash-es/filter.js + 1 modules +var filter = __webpack_require__(13445); +// EXTERNAL MODULE: ./node_modules/lodash-es/isEmpty.js +var isEmpty = __webpack_require__(79697); +// EXTERNAL MODULE: ./node_modules/lodash-es/forEach.js +var forEach = __webpack_require__(70870); +// EXTERNAL MODULE: ./node_modules/lodash-es/isUndefined.js +var isUndefined = __webpack_require__(49360); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFlatten.js + 1 modules +var _baseFlatten = __webpack_require__(10626); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseRest.js +var _baseRest = __webpack_require__(69581); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseFindIndex.js +var _baseFindIndex = __webpack_require__(21692); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsNaN.js +/** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ +function baseIsNaN(value) { + return value !== value; +} + +/* harmony default export */ const _baseIsNaN = (baseIsNaN); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_strictIndexOf.js +/** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; +} + +/* harmony default export */ const _strictIndexOf = (strictIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIndexOf.js + + + + +/** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseIndexOf(array, value, fromIndex) { + return value === value + ? _strictIndexOf(array, value, fromIndex) + : (0,_baseFindIndex/* default */.Z)(array, _baseIsNaN, fromIndex); +} + +/* harmony default export */ const _baseIndexOf = (baseIndexOf); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludes.js + + +/** + * A specialized version of `_.includes` for arrays without support for + * specifying an index to search from. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + return !!length && _baseIndexOf(array, value, 0) > -1; +} + +/* harmony default export */ const _arrayIncludes = (arrayIncludes); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayIncludesWith.js +/** + * This function is like `arrayIncludes` except that it accepts a comparator. + * + * @private + * @param {Array} [array] The array to inspect. + * @param {*} target The value to search for. + * @param {Function} comparator The comparator invoked per element. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ +function arrayIncludesWith(array, value, comparator) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (comparator(value, array[index])) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arrayIncludesWith = (arrayIncludesWith); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Set.js +var _Set = __webpack_require__(93203); +;// CONCATENATED MODULE: ./node_modules/lodash-es/noop.js +/** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ +function noop() { + // No operation performed. +} + +/* harmony default export */ const lodash_es_noop = (noop); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createSet.js + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Creates a set object of `values`. + * + * @private + * @param {Array} values The values to add to the set. + * @returns {Object} Returns the new set. + */ +var createSet = !(_Set/* default */.Z && (1 / (0,_setToArray/* default */.Z)(new _Set/* default */.Z([,-0]))[1]) == INFINITY) ? lodash_es_noop : function(values) { + return new _Set/* default */.Z(values); +}; + +/* harmony default export */ const _createSet = (createSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseUniq.js + + + + + + + +/** Used as the size to enable large array optimizations. */ +var LARGE_ARRAY_SIZE = 200; + +/** + * The base implementation of `_.uniqBy` without support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The iteratee invoked per element. + * @param {Function} [comparator] The comparator invoked per element. + * @returns {Array} Returns the new duplicate free array. + */ +function baseUniq(array, iteratee, comparator) { + var index = -1, + includes = _arrayIncludes, + length = array.length, + isCommon = true, + result = [], + seen = result; + + if (comparator) { + isCommon = false; + includes = _arrayIncludesWith; + } + else if (length >= LARGE_ARRAY_SIZE) { + var set = iteratee ? null : _createSet(array); + if (set) { + return (0,_setToArray/* default */.Z)(set); + } + isCommon = false; + includes = _cacheHas/* default */.Z; + seen = new _SetCache/* default */.Z; + } + else { + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value) : value; + + value = (comparator || value !== 0) ? value : 0; + if (isCommon && computed === computed) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (!includes(seen, computed, comparator)) { + if (seen !== result) { + seen.push(computed); + } + result.push(value); + } + } + return result; +} + +/* harmony default export */ const _baseUniq = (baseUniq); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLikeObject.js +var isArrayLikeObject = __webpack_require__(836); +;// CONCATENATED MODULE: ./node_modules/lodash-es/union.js + + + + + +/** + * Creates an array of unique values, in order, from all given arrays using + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([2], [1, 2]); + * // => [2, 1] + */ +var union = (0,_baseRest/* default */.Z)(function(arrays) { + return _baseUniq((0,_baseFlatten/* default */.Z)(arrays, 1, isArrayLikeObject/* default */.Z, true)); +}); + +/* harmony default export */ const lodash_es_union = (union); + +// EXTERNAL MODULE: ./node_modules/lodash-es/values.js + 1 modules +var values = __webpack_require__(34148); +// EXTERNAL MODULE: ./node_modules/lodash-es/reduce.js + 2 modules +var reduce = __webpack_require__(92344); +;// CONCATENATED MODULE: ./node_modules/dagre-d3-es/src/graphlib/graph.js + + +var DEFAULT_EDGE_NAME = '\x00'; +var GRAPH_NODE = '\x00'; +var EDGE_KEY_DELIM = '\x01'; + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. + +// Implementation notes: +// +// * Node id query functions should return string ids for the nodes +// * Edge id query functions should return an "edgeObj", edge object, that is +// composed of enough information to uniquely identify an edge: {v, w, name}. +// * Internally we use an "edgeId", a stringified form of the edgeObj, to +// reference edges. This is because we need a performant way to look these +// edges up and, object properties, which have string keys, are the closest +// we're going to get to a performant hashtable in JavaScript. +class Graph { + constructor(opts = {}) { + this._isDirected = has/* default */.Z(opts, 'directed') ? opts.directed : true; + this._isMultigraph = has/* default */.Z(opts, 'multigraph') ? opts.multigraph : false; + this._isCompound = has/* default */.Z(opts, 'compound') ? opts.compound : false; + + // Label for the graph itself + this._label = undefined; + + // Defaults to be set when creating a new node + this._defaultNodeLabelFn = constant/* default */.Z(undefined); + + // Defaults to be set when creating a new edge + this._defaultEdgeLabelFn = constant/* default */.Z(undefined); + + // v -> label + this._nodes = {}; + + if (this._isCompound) { + // v -> parent + this._parent = {}; + + // v -> children + this._children = {}; + this._children[GRAPH_NODE] = {}; + } + + // v -> edgeObj + this._in = {}; + + // u -> v -> Number + this._preds = {}; + + // v -> edgeObj + this._out = {}; + + // v -> w -> Number + this._sucs = {}; + + // e -> edgeObj + this._edgeObjs = {}; + + // e -> label + this._edgeLabels = {}; + } + /* === Graph functions ========= */ + isDirected() { + return this._isDirected; + } + isMultigraph() { + return this._isMultigraph; + } + isCompound() { + return this._isCompound; + } + setGraph(label) { + this._label = label; + return this; + } + graph() { + return this._label; + } + /* === Node functions ========== */ + setDefaultNodeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultNodeLabelFn = newDefault; + return this; + } + nodeCount() { + return this._nodeCount; + } + nodes() { + return keys/* default */.Z(this._nodes); + } + sources() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._in[v]); + }); + } + sinks() { + var self = this; + return filter/* default */.Z(this.nodes(), function (v) { + return isEmpty/* default */.Z(self._out[v]); + }); + } + setNodes(vs, value) { + var args = arguments; + var self = this; + forEach/* default */.Z(vs, function (v) { + if (args.length > 1) { + self.setNode(v, value); + } else { + self.setNode(v); + } + }); + return this; + } + setNode(v, value) { + if (has/* default */.Z(this._nodes, v)) { + if (arguments.length > 1) { + this._nodes[v] = value; + } + return this; + } + + // @ts-expect-error + this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); + if (this._isCompound) { + this._parent[v] = GRAPH_NODE; + this._children[v] = {}; + this._children[GRAPH_NODE][v] = true; + } + this._in[v] = {}; + this._preds[v] = {}; + this._out[v] = {}; + this._sucs[v] = {}; + ++this._nodeCount; + return this; + } + node(v) { + return this._nodes[v]; + } + hasNode(v) { + return has/* default */.Z(this._nodes, v); + } + removeNode(v) { + var self = this; + if (has/* default */.Z(this._nodes, v)) { + var removeEdge = function (e) { + self.removeEdge(self._edgeObjs[e]); + }; + delete this._nodes[v]; + if (this._isCompound) { + this._removeFromParentsChildList(v); + delete this._parent[v]; + forEach/* default */.Z(this.children(v), function (child) { + self.setParent(child); + }); + delete this._children[v]; + } + forEach/* default */.Z(keys/* default */.Z(this._in[v]), removeEdge); + delete this._in[v]; + delete this._preds[v]; + forEach/* default */.Z(keys/* default */.Z(this._out[v]), removeEdge); + delete this._out[v]; + delete this._sucs[v]; + --this._nodeCount; + } + return this; + } + setParent(v, parent) { + if (!this._isCompound) { + throw new Error('Cannot set parent in a non-compound graph'); + } + + if (isUndefined/* default */.Z(parent)) { + parent = GRAPH_NODE; + } else { + // Coerce parent to string + parent += ''; + for (var ancestor = parent; !isUndefined/* default */.Z(ancestor); ancestor = this.parent(ancestor)) { + if (ancestor === v) { + throw new Error('Setting ' + parent + ' as parent of ' + v + ' would create a cycle'); + } + } + + this.setNode(parent); + } + + this.setNode(v); + this._removeFromParentsChildList(v); + this._parent[v] = parent; + this._children[parent][v] = true; + return this; + } + _removeFromParentsChildList(v) { + delete this._children[this._parent[v]][v]; + } + parent(v) { + if (this._isCompound) { + var parent = this._parent[v]; + if (parent !== GRAPH_NODE) { + return parent; + } + } + } + children(v) { + if (isUndefined/* default */.Z(v)) { + v = GRAPH_NODE; + } + + if (this._isCompound) { + var children = this._children[v]; + if (children) { + return keys/* default */.Z(children); + } + } else if (v === GRAPH_NODE) { + return this.nodes(); + } else if (this.hasNode(v)) { + return []; + } + } + predecessors(v) { + var predsV = this._preds[v]; + if (predsV) { + return keys/* default */.Z(predsV); + } + } + successors(v) { + var sucsV = this._sucs[v]; + if (sucsV) { + return keys/* default */.Z(sucsV); + } + } + neighbors(v) { + var preds = this.predecessors(v); + if (preds) { + return lodash_es_union(preds, this.successors(v)); + } + } + isLeaf(v) { + var neighbors; + if (this.isDirected()) { + neighbors = this.successors(v); + } else { + neighbors = this.neighbors(v); + } + return neighbors.length === 0; + } + filterNodes(filter) { + // @ts-expect-error + var copy = new this.constructor({ + directed: this._isDirected, + multigraph: this._isMultigraph, + compound: this._isCompound, + }); + + copy.setGraph(this.graph()); + + var self = this; + forEach/* default */.Z(this._nodes, function (value, v) { + if (filter(v)) { + copy.setNode(v, value); + } + }); + + forEach/* default */.Z(this._edgeObjs, function (e) { + // @ts-expect-error + if (copy.hasNode(e.v) && copy.hasNode(e.w)) { + copy.setEdge(e, self.edge(e)); + } + }); + + var parents = {}; + function findParent(v) { + var parent = self.parent(v); + if (parent === undefined || copy.hasNode(parent)) { + parents[v] = parent; + return parent; + } else if (parent in parents) { + return parents[parent]; + } else { + return findParent(parent); + } + } + + if (this._isCompound) { + forEach/* default */.Z(copy.nodes(), function (v) { + copy.setParent(v, findParent(v)); + }); + } + + return copy; + } + /* === Edge functions ========== */ + setDefaultEdgeLabel(newDefault) { + if (!isFunction/* default */.Z(newDefault)) { + newDefault = constant/* default */.Z(newDefault); + } + this._defaultEdgeLabelFn = newDefault; + return this; + } + edgeCount() { + return this._edgeCount; + } + edges() { + return values/* default */.Z(this._edgeObjs); + } + setPath(vs, value) { + var self = this; + var args = arguments; + reduce/* default */.Z(vs, function (v, w) { + if (args.length > 1) { + self.setEdge(v, w, value); + } else { + self.setEdge(v, w); + } + return w; + }); + return this; + } + /* + * setEdge(v, w, [value, [name]]) + * setEdge({ v, w, [name] }, [value]) + */ + setEdge() { + var v, w, name, value; + var valueSpecified = false; + var arg0 = arguments[0]; + + if (typeof arg0 === 'object' && arg0 !== null && 'v' in arg0) { + v = arg0.v; + w = arg0.w; + name = arg0.name; + if (arguments.length === 2) { + value = arguments[1]; + valueSpecified = true; + } + } else { + v = arg0; + w = arguments[1]; + name = arguments[3]; + if (arguments.length > 2) { + value = arguments[2]; + valueSpecified = true; + } + } + + v = '' + v; + w = '' + w; + if (!isUndefined/* default */.Z(name)) { + name = '' + name; + } + + var e = edgeArgsToId(this._isDirected, v, w, name); + if (has/* default */.Z(this._edgeLabels, e)) { + if (valueSpecified) { + this._edgeLabels[e] = value; + } + return this; + } + + if (!isUndefined/* default */.Z(name) && !this._isMultigraph) { + throw new Error('Cannot set a named edge when isMultigraph = false'); + } + + // It didn't exist, so we need to create it. + // First ensure the nodes exist. + this.setNode(v); + this.setNode(w); + + // @ts-expect-error + this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); + + var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); + // Ensure we add undirected edges in a consistent way. + v = edgeObj.v; + w = edgeObj.w; + + Object.freeze(edgeObj); + this._edgeObjs[e] = edgeObj; + incrementOrInitEntry(this._preds[w], v); + incrementOrInitEntry(this._sucs[v], w); + this._in[w][e] = edgeObj; + this._out[v][e] = edgeObj; + this._edgeCount++; + return this; + } + edge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return this._edgeLabels[e]; + } + hasEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + return has/* default */.Z(this._edgeLabels, e); + } + removeEdge(v, w, name) { + var e = + arguments.length === 1 + ? edgeObjToId(this._isDirected, arguments[0]) + : edgeArgsToId(this._isDirected, v, w, name); + var edge = this._edgeObjs[e]; + if (edge) { + v = edge.v; + w = edge.w; + delete this._edgeLabels[e]; + delete this._edgeObjs[e]; + decrementOrRemoveEntry(this._preds[w], v); + decrementOrRemoveEntry(this._sucs[v], w); + delete this._in[w][e]; + delete this._out[v][e]; + this._edgeCount--; + } + return this; + } + inEdges(v, u) { + var inV = this._in[v]; + if (inV) { + var edges = values/* default */.Z(inV); + if (!u) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.v === u; + }); + } + } + outEdges(v, w) { + var outV = this._out[v]; + if (outV) { + var edges = values/* default */.Z(outV); + if (!w) { + return edges; + } + return filter/* default */.Z(edges, function (edge) { + return edge.w === w; + }); + } + } + nodeEdges(v, w) { + var inEdges = this.inEdges(v, w); + if (inEdges) { + return inEdges.concat(this.outEdges(v, w)); + } + } +} + +/* Number of nodes in the graph. Should only be changed by the implementation. */ +Graph.prototype._nodeCount = 0; + +/* Number of edges in the graph. Should only be changed by the implementation. */ +Graph.prototype._edgeCount = 0; + +function incrementOrInitEntry(map, k) { + if (map[k]) { + map[k]++; + } else { + map[k] = 1; + } +} + +function decrementOrRemoveEntry(map, k) { + if (!--map[k]) { + delete map[k]; + } +} + +function edgeArgsToId(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + (isUndefined/* default */.Z(name) ? DEFAULT_EDGE_NAME : name); +} + +function edgeArgsToObj(isDirected, v_, w_, name) { + var v = '' + v_; + var w = '' + w_; + if (!isDirected && v > w) { + var tmp = v; + v = w; + w = tmp; + } + var edgeObj = { v: v, w: w }; + if (name) { + edgeObj.name = name; + } + return edgeObj; +} + +function edgeObjToId(isDirected, edgeObj) { + return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); +} + + +/***/ }), + +/***/ 45625: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ k: () => (/* reexport safe */ _graph_js__WEBPACK_IMPORTED_MODULE_0__.k) +/* harmony export */ }); +/* unused harmony export version */ +/* harmony import */ var _graph_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52544); +// Includes only the "core" of graphlib + + + +const version = '2.1.9-pre'; + + + + +/***/ }), + +/***/ 63001: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _SetCache) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_MapCache.js + 14 modules +var _MapCache = __webpack_require__(37834); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheAdd.js +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** + * Adds `value` to the array cache. + * + * @private + * @name add + * @memberOf SetCache + * @alias push + * @param {*} value The value to cache. + * @returns {Object} Returns the cache instance. + */ +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} + +/* harmony default export */ const _setCacheAdd = (setCacheAdd); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_setCacheHas.js +/** + * Checks if `value` is in the array cache. + * + * @private + * @name has + * @memberOf SetCache + * @param {*} value The value to search for. + * @returns {number} Returns `true` if `value` is found, else `false`. + */ +function setCacheHas(value) { + return this.__data__.has(value); +} + +/* harmony default export */ const _setCacheHas = (setCacheHas); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_SetCache.js + + + + +/** + * + * Creates an array cache object to store unique values. + * + * @private + * @constructor + * @param {Array} [values] The values to cache. + */ +function SetCache(values) { + var index = -1, + length = values == null ? 0 : values.length; + + this.__data__ = new _MapCache/* default */.Z; + while (++index < length) { + this.add(values[index]); + } +} + +// Add methods to `SetCache`. +SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd; +SetCache.prototype.has = _setCacheHas; + +/* harmony default export */ const _SetCache = (SetCache); + + +/***/ }), + +/***/ 76579: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. + */ +function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach); + + +/***/ }), + +/***/ 68774: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.filter` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function arrayFilter(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length, + resIndex = 0, + result = []; + + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[resIndex++] = value; + } + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter); + + +/***/ }), + +/***/ 74073: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); + + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayMap); + + +/***/ }), + +/***/ 58694: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Appends the elements of `values` to `array`. + * + * @private + * @param {Array} array The array to modify. + * @param {Array} values The values to append. + * @returns {Array} Returns `array`. + */ +function arrayPush(array, values) { + var index = -1, + length = values.length, + offset = array.length; + + while (++index < length) { + array[offset + index] = values[index]; + } + return array; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush); + + +/***/ }), + +/***/ 48451: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseClone) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayEach.js +var _arrayEach = __webpack_require__(76579); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyObject.js +var _copyObject = __webpack_require__(31899); +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssign.js + + + +/** + * The base implementation of `_.assign` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssign(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keys/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssign = (baseAssign); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keysIn.js + 2 modules +var keysIn = __webpack_require__(32957); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseAssignIn.js + + + +/** + * The base implementation of `_.assignIn` without support for multiple sources + * or `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ +function baseAssignIn(object, source) { + return object && (0,_copyObject/* default */.Z)(source, (0,keysIn/* default */.Z)(source), object); +} + +/* harmony default export */ const _baseAssignIn = (baseAssignIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneBuffer.js +var _cloneBuffer = __webpack_require__(91050); +// EXTERNAL MODULE: ./node_modules/lodash-es/_copyArray.js +var _copyArray = __webpack_require__(87215); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getSymbols.js +var _getSymbols = __webpack_require__(95695); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbols.js + + + +/** + * Copies own symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbols(source, object) { + return (0,_copyObject/* default */.Z)(source, (0,_getSymbols/* default */.Z)(source), object); +} + +/* harmony default export */ const _copySymbols = (copySymbols); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_getPrototype.js +var _getPrototype = __webpack_require__(12513); +// EXTERNAL MODULE: ./node_modules/lodash-es/stubArray.js +var stubArray = __webpack_require__(60532); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getSymbolsIn.js + + + + + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own and inherited enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbolsIn = !nativeGetSymbols ? stubArray/* default */.Z : function(object) { + var result = []; + while (object) { + (0,_arrayPush/* default */.Z)(result, (0,_getSymbols/* default */.Z)(object)); + object = (0,_getPrototype/* default */.Z)(object); + } + return result; +}; + +/* harmony default export */ const _getSymbolsIn = (getSymbolsIn); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_copySymbolsIn.js + + + +/** + * Copies own and inherited symbols of `source` to `object`. + * + * @private + * @param {Object} source The object to copy symbols from. + * @param {Object} [object={}] The object to copy symbols to. + * @returns {Object} Returns `object`. + */ +function copySymbolsIn(source, object) { + return (0,_copyObject/* default */.Z)(source, _getSymbolsIn(source), object); +} + +/* harmony default export */ const _copySymbolsIn = (copySymbolsIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGetAllKeys.js +var _baseGetAllKeys = __webpack_require__(63327); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getAllKeysIn.js + + + + +/** + * Creates an array of own and inherited enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeysIn(object) { + return (0,_baseGetAllKeys/* default */.Z)(object, keysIn/* default */.Z, _getSymbolsIn); +} + +/* harmony default export */ const _getAllKeysIn = (getAllKeysIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneArray.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _initCloneArray_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Initializes an array clone. + * + * @private + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. + */ +function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add properties assigned by `RegExp#exec`. + if (length && typeof array[0] == 'string' && _initCloneArray_hasOwnProperty.call(array, 'index')) { + result.index = array.index; + result.input = array.input; + } + return result; +} + +/* harmony default export */ const _initCloneArray = (initCloneArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneArrayBuffer.js +var _cloneArrayBuffer = __webpack_require__(41884); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneDataView.js + + +/** + * Creates a clone of `dataView`. + * + * @private + * @param {Object} dataView The data view to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the cloned data view. + */ +function cloneDataView(dataView, isDeep) { + var buffer = isDeep ? (0,_cloneArrayBuffer/* default */.Z)(dataView.buffer) : dataView.buffer; + return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); +} + +/* harmony default export */ const _cloneDataView = (cloneDataView); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneRegExp.js +/** Used to match `RegExp` flags from their coerced string values. */ +var reFlags = /\w*$/; + +/** + * Creates a clone of `regexp`. + * + * @private + * @param {Object} regexp The regexp to clone. + * @returns {Object} Returns the cloned regexp. + */ +function cloneRegExp(regexp) { + var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); + result.lastIndex = regexp.lastIndex; + return result; +} + +/* harmony default export */ const _cloneRegExp = (cloneRegExp); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_cloneSymbol.js + + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * Creates a clone of the `symbol` object. + * + * @private + * @param {Object} symbol The symbol object to clone. + * @returns {Object} Returns the cloned symbol object. + */ +function cloneSymbol(symbol) { + return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; +} + +/* harmony default export */ const _cloneSymbol = (cloneSymbol); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cloneTypedArray.js +var _cloneTypedArray = __webpack_require__(12701); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_initCloneByTag.js + + + + + + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ +function initCloneByTag(object, tag, isDeep) { + var Ctor = object.constructor; + switch (tag) { + case arrayBufferTag: + return (0,_cloneArrayBuffer/* default */.Z)(object); + + case boolTag: + case dateTag: + return new Ctor(+object); + + case dataViewTag: + return _cloneDataView(object, isDeep); + + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + return (0,_cloneTypedArray/* default */.Z)(object, isDeep); + + case mapTag: + return new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return _cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return _cloneSymbol(object); + } +} + +/* harmony default export */ const _initCloneByTag = (initCloneByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_initCloneObject.js + 1 modules +var _initCloneObject = __webpack_require__(73658); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMap.js + + + +/** `Object#toString` result references. */ +var _baseIsMap_mapTag = '[object Map]'; + +/** + * The base implementation of `_.isMap` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + */ +function baseIsMap(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsMap_mapTag; +} + +/* harmony default export */ const _baseIsMap = (baseIsMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseUnary.js +var _baseUnary = __webpack_require__(21162); +// EXTERNAL MODULE: ./node_modules/lodash-es/_nodeUtil.js +var _nodeUtil = __webpack_require__(98351); +;// CONCATENATED MODULE: ./node_modules/lodash-es/isMap.js + + + + +/* Node.js helper references. */ +var nodeIsMap = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isMap; + +/** + * Checks if `value` is classified as a `Map` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a map, else `false`. + * @example + * + * _.isMap(new Map); + * // => true + * + * _.isMap(new WeakMap); + * // => false + */ +var isMap = nodeIsMap ? (0,_baseUnary/* default */.Z)(nodeIsMap) : _baseIsMap; + +/* harmony default export */ const lodash_es_isMap = (isMap); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsSet.js + + + +/** `Object#toString` result references. */ +var _baseIsSet_setTag = '[object Set]'; + +/** + * The base implementation of `_.isSet` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + */ +function baseIsSet(value) { + return (0,isObjectLike/* default */.Z)(value) && (0,_getTag/* default */.Z)(value) == _baseIsSet_setTag; +} + +/* harmony default export */ const _baseIsSet = (baseIsSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/isSet.js + + + + +/* Node.js helper references. */ +var nodeIsSet = _nodeUtil/* default */.Z && _nodeUtil/* default */.Z.isSet; + +/** + * Checks if `value` is classified as a `Set` object. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a set, else `false`. + * @example + * + * _.isSet(new Set); + * // => true + * + * _.isSet(new WeakSet); + * // => false + */ +var isSet = nodeIsSet ? (0,_baseUnary/* default */.Z)(nodeIsSet) : _baseIsSet; + +/* harmony default export */ const lodash_es_isSet = (isSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseClone.js + + + + + + + + + + + + + + + + + + + + + + + +/** Used to compose bitmasks for cloning. */ +var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + _baseClone_boolTag = '[object Boolean]', + _baseClone_dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + _baseClone_mapTag = '[object Map]', + _baseClone_numberTag = '[object Number]', + objectTag = '[object Object]', + _baseClone_regexpTag = '[object RegExp]', + _baseClone_setTag = '[object Set]', + _baseClone_stringTag = '[object String]', + _baseClone_symbolTag = '[object Symbol]', + weakMapTag = '[object WeakMap]'; + +var _baseClone_arrayBufferTag = '[object ArrayBuffer]', + _baseClone_dataViewTag = '[object DataView]', + _baseClone_float32Tag = '[object Float32Array]', + _baseClone_float64Tag = '[object Float64Array]', + _baseClone_int8Tag = '[object Int8Array]', + _baseClone_int16Tag = '[object Int16Array]', + _baseClone_int32Tag = '[object Int32Array]', + _baseClone_uint8Tag = '[object Uint8Array]', + _baseClone_uint8ClampedTag = '[object Uint8ClampedArray]', + _baseClone_uint16Tag = '[object Uint16Array]', + _baseClone_uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values supported by `_.clone`. */ +var cloneableTags = {}; +cloneableTags[argsTag] = cloneableTags[arrayTag] = +cloneableTags[_baseClone_arrayBufferTag] = cloneableTags[_baseClone_dataViewTag] = +cloneableTags[_baseClone_boolTag] = cloneableTags[_baseClone_dateTag] = +cloneableTags[_baseClone_float32Tag] = cloneableTags[_baseClone_float64Tag] = +cloneableTags[_baseClone_int8Tag] = cloneableTags[_baseClone_int16Tag] = +cloneableTags[_baseClone_int32Tag] = cloneableTags[_baseClone_mapTag] = +cloneableTags[_baseClone_numberTag] = cloneableTags[objectTag] = +cloneableTags[_baseClone_regexpTag] = cloneableTags[_baseClone_setTag] = +cloneableTags[_baseClone_stringTag] = cloneableTags[_baseClone_symbolTag] = +cloneableTags[_baseClone_uint8Tag] = cloneableTags[_baseClone_uint8ClampedTag] = +cloneableTags[_baseClone_uint16Tag] = cloneableTags[_baseClone_uint32Tag] = true; +cloneableTags[errorTag] = cloneableTags[funcTag] = +cloneableTags[weakMapTag] = false; + +/** + * The base implementation of `_.clone` and `_.cloneDeep` which tracks + * traversed objects. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone symbols + * @param {Function} [customizer] The function to customize cloning. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The parent object of `value`. + * @param {Object} [stack] Tracks traversed objects and their clone counterparts. + * @returns {*} Returns the cloned value. + */ +function baseClone(value, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + if (customizer) { + result = object ? customizer(value, key, object, stack) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!(0,isObject/* default */.Z)(value)) { + return value; + } + var isArr = (0,isArray/* default */.Z)(value); + if (isArr) { + result = _initCloneArray(value); + if (!isDeep) { + return (0,_copyArray/* default */.Z)(value, result); + } + } else { + var tag = (0,_getTag/* default */.Z)(value), + isFunc = tag == funcTag || tag == genTag; + + if ((0,isBuffer/* default */.Z)(value)) { + return (0,_cloneBuffer/* default */.Z)(value, isDeep); + } + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = (isFlat || isFunc) ? {} : (0,_initCloneObject/* default */.Z)(value); + if (!isDeep) { + return isFlat + ? _copySymbolsIn(value, _baseAssignIn(result, value)) + : _copySymbols(value, _baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = _initCloneByTag(value, tag, isDeep); + } + } + // Check for circular references and return its corresponding clone. + stack || (stack = new _Stack/* default */.Z); + var stacked = stack.get(value); + if (stacked) { + return stacked; + } + stack.set(value, result); + + if (lodash_es_isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (lodash_es_isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? _getAllKeysIn : _getAllKeys/* default */.Z) + : (isFlat ? keysIn/* default */.Z : keys/* default */.Z); + + var props = isArr ? undefined : keysFunc(value); + (0,_arrayEach/* default */.Z)(props || value, function(subValue, key) { + if (props) { + key = subValue; + subValue = value[key]; + } + // Recursively populate clone (susceptible to call stack limits). + (0,_assignValue/* default */.Z)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + return result; +} + +/* harmony default export */ const _baseClone = (baseClone); + + +/***/ }), + +/***/ 49811: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseEach) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseForOwn.js +var _baseForOwn = __webpack_require__(2693); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArrayLike.js +var isArrayLike = __webpack_require__(50585); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createBaseEach.js + + +/** + * Creates a `baseEach` or `baseEachRight` function. + * + * @private + * @param {Function} eachFunc The function to iterate over a collection. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ +function createBaseEach(eachFunc, fromRight) { + return function(collection, iteratee) { + if (collection == null) { + return collection; + } + if (!(0,isArrayLike/* default */.Z)(collection)) { + return eachFunc(collection, iteratee); + } + var length = collection.length, + index = fromRight ? length : -1, + iterable = Object(collection); + + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; +} + +/* harmony default export */ const _createBaseEach = (createBaseEach); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseEach.js + + + +/** + * The base implementation of `_.forEach` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + */ +var baseEach = _createBaseEach(_baseForOwn/* default */.Z); + +/* harmony default export */ const _baseEach = (baseEach); + + +/***/ }), + +/***/ 21692: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); + + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseFindIndex); + + +/***/ }), + +/***/ 10626: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseFlatten) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayPush.js +var _arrayPush = __webpack_require__(58694); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArguments.js + 1 modules +var isArguments = __webpack_require__(29169); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isFlattenable.js + + + + +/** Built-in value references. */ +var spreadableSymbol = _Symbol/* default */.Z ? _Symbol/* default */.Z.isConcatSpreadable : undefined; + +/** + * Checks if `value` is a flattenable `arguments` object or array. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. + */ +function isFlattenable(value) { + return (0,isArray/* default */.Z)(value) || (0,isArguments/* default */.Z)(value) || + !!(spreadableSymbol && value && value[spreadableSymbol]); +} + +/* harmony default export */ const _isFlattenable = (isFlattenable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFlatten.js + + + +/** + * The base implementation of `_.flatten` with support for restricting flattening. + * + * @private + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. + * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. + * @param {Array} [result=[]] The initial result value. + * @returns {Array} Returns the new flattened array. + */ +function baseFlatten(array, depth, predicate, isStrict, result) { + var index = -1, + length = array.length; + + predicate || (predicate = _isFlattenable); + result || (result = []); + + while (++index < length) { + var value = array[index]; + if (depth > 0 && predicate(value)) { + if (depth > 1) { + // Recursively flatten arrays (susceptible to call stack limits). + baseFlatten(value, depth - 1, predicate, isStrict, result); + } else { + (0,_arrayPush/* default */.Z)(result, value); + } + } else if (!isStrict) { + result[result.length] = value; + } + } + return result; +} + +/* harmony default export */ const _baseFlatten = (baseFlatten); + + +/***/ }), + +/***/ 2693: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(61395); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + +/** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ +function baseForOwn(object, iteratee) { + return object && (0,_baseFor_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, iteratee, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseForOwn); + + +/***/ }), + +/***/ 13317: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + +/** + * The base implementation of `_.get` without support for default values. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @returns {*} Returns the resolved value. + */ +function baseGet(object, path) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = 0, + length = path.length; + + while (object != null && index < length) { + object = object[(0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index++])]; + } + return (index && index == length) ? object : undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGet); + + +/***/ }), + +/***/ 63327: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58694); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + +/** + * The base implementation of `getAllKeys` and `getAllKeysIn` which uses + * `keysFunc` and `symbolsFunc` to get the enumerable property names and + * symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Function} keysFunc The function to get the keys of `object`. + * @param {Function} symbolsFunc The function to get the symbols of `object`. + * @returns {Array} Returns the array of property names and symbols. + */ +function baseGetAllKeys(object, keysFunc, symbolsFunc) { + var result = keysFunc(object); + return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(result, symbolsFunc(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys); + + +/***/ }), + +/***/ 74765: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _baseIteratee) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Stack.js + 5 modules +var _Stack = __webpack_require__(31667); +// EXTERNAL MODULE: ./node_modules/lodash-es/_SetCache.js + 2 modules +var _SetCache = __webpack_require__(63001); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arraySome.js +/** + * A specialized version of `_.some` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + */ +function arraySome(array, predicate) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; +} + +/* harmony default export */ const _arraySome = (arraySome); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_cacheHas.js +var _cacheHas = __webpack_require__(59548); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalArrays.js + + + + +/** Used to compose bitmasks for value comparisons. */ +var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache/* default */.Z : undefined; + + stack.set(array, other); + stack.set(other, array); + + // Ignore non-index properties. + while (++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, arrValue, index, other, array, stack) + : customizer(arrValue, othValue, index, array, other, stack); + } + if (compared !== undefined) { + if (compared) { + continue; + } + result = false; + break; + } + // Recursively compare arrays (susceptible to call stack limits). + if (seen) { + if (!_arraySome(other, function(othValue, othIndex) { + if (!(0,_cacheHas/* default */.Z)(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, stack) + )) { + result = false; + break; + } + } + stack['delete'](array); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalArrays = (equalArrays); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_Uint8Array.js +var _Uint8Array = __webpack_require__(84073); +// EXTERNAL MODULE: ./node_modules/lodash-es/eq.js +var eq = __webpack_require__(79651); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_mapToArray.js +/** + * Converts `map` to its key-value pairs. + * + * @private + * @param {Object} map The map to convert. + * @returns {Array} Returns the key-value pairs. + */ +function mapToArray(map) { + var index = -1, + result = Array(map.size); + + map.forEach(function(value, key) { + result[++index] = [key, value]; + }); + return result; +} + +/* harmony default export */ const _mapToArray = (mapToArray); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToArray.js +var _setToArray = __webpack_require__(6545); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalByTag.js + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _equalByTag_COMPARE_PARTIAL_FLAG = 1, + _equalByTag_COMPARE_UNORDERED_FLAG = 2; + +/** `Object#toString` result references. */ +var boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + mapTag = '[object Map]', + numberTag = '[object Number]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]'; + +var arrayBufferTag = '[object ArrayBuffer]', + dataViewTag = '[object DataView]'; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { + switch (tag) { + case dataViewTag: + if ((object.byteLength != other.byteLength) || + (object.byteOffset != other.byteOffset)) { + return false; + } + object = object.buffer; + other = other.buffer; + + case arrayBufferTag: + if ((object.byteLength != other.byteLength) || + !equalFunc(new _Uint8Array/* default */.Z(object), new _Uint8Array/* default */.Z(other))) { + return false; + } + return true; + + case boolTag: + case dateTag: + case numberTag: + // Coerce booleans to `1` or `0` and dates to milliseconds. + // Invalid dates are coerced to `NaN`. + return (0,eq/* default */.Z)(+object, +other); + + case errorTag: + return object.name == other.name && object.message == other.message; + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings, primitives and objects, + // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = _mapToArray; + + case setTag: + var isPartial = bitmask & _equalByTag_COMPARE_PARTIAL_FLAG; + convert || (convert = _setToArray/* default */.Z); + + if (object.size != other.size && !isPartial) { + return false; + } + // Assume cyclic values are equal. + var stacked = stack.get(object); + if (stacked) { + return stacked == other; + } + bitmask |= _equalByTag_COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); + stack['delete'](object); + return result; + + case symbolTag: + if (symbolValueOf) { + return symbolValueOf.call(object) == symbolValueOf.call(other); + } + } + return false; +} + +/* harmony default export */ const _equalByTag = (equalByTag); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getAllKeys.js +var _getAllKeys = __webpack_require__(1808); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_equalObjects.js + + +/** Used to compose bitmasks for value comparisons. */ +var _equalObjects_COMPARE_PARTIAL_FLAG = 1; + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _equalObjects_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & _equalObjects_COMPARE_PARTIAL_FLAG, + objProps = (0,_getAllKeys/* default */.Z)(object), + objLength = objProps.length, + othProps = (0,_getAllKeys/* default */.Z)(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : _equalObjects_hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + var result = true; + stack.set(object, other); + stack.set(other, object); + + var skipCtor = isPartial; + while (++index < objLength) { + key = objProps[index]; + var objValue = object[key], + othValue = other[key]; + + if (customizer) { + var compared = isPartial + ? customizer(othValue, objValue, key, other, object, stack) + : customizer(objValue, othValue, key, object, other, stack); + } + // Recursively compare objects (susceptible to call stack limits). + if (!(compared === undefined + ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) + : compared + )) { + result = false; + break; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (result && !skipCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && + ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && + typeof othCtor == 'function' && othCtor instanceof othCtor)) { + result = false; + } + } + stack['delete'](object); + stack['delete'](other); + return result; +} + +/* harmony default export */ const _equalObjects = (equalObjects); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_getTag.js + 3 modules +var _getTag = __webpack_require__(83970); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isBuffer.js + 1 modules +var isBuffer = __webpack_require__(77008); +// EXTERNAL MODULE: ./node_modules/lodash-es/isTypedArray.js + 1 modules +var isTypedArray = __webpack_require__(18843); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqualDeep.js + + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsEqualDeep_COMPARE_PARTIAL_FLAG = 1; + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + objectTag = '[object Object]'; + +/** Used for built-in method references. */ +var _baseIsEqualDeep_objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseIsEqualDeep_hasOwnProperty = _baseIsEqualDeep_objectProto.hasOwnProperty; + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = (0,isArray/* default */.Z)(object), + othIsArr = (0,isArray/* default */.Z)(other), + objTag = objIsArr ? arrayTag : (0,_getTag/* default */.Z)(object), + othTag = othIsArr ? arrayTag : (0,_getTag/* default */.Z)(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && (0,isBuffer/* default */.Z)(object)) { + if (!(0,isBuffer/* default */.Z)(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new _Stack/* default */.Z); + return (objIsArr || (0,isTypedArray/* default */.Z)(object)) + ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & _baseIsEqualDeep_COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && _baseIsEqualDeep_hasOwnProperty.call(object, '__wrapped__'), + othIsWrapped = othIsObj && _baseIsEqualDeep_hasOwnProperty.call(other, '__wrapped__'); + + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object.value() : object, + othUnwrapped = othIsWrapped ? other.value() : other; + + stack || (stack = new _Stack/* default */.Z); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new _Stack/* default */.Z); + return _equalObjects(object, other, bitmask, customizer, equalFunc, stack); +} + +/* harmony default export */ const _baseIsEqualDeep = (baseIsEqualDeep); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObjectLike.js +var isObjectLike = __webpack_require__(18533); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsEqual.js + + + +/** + * The base implementation of `_.isEqual` which supports partial comparisons + * and tracks traversed objects. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!(0,isObjectLike/* default */.Z)(value) && !(0,isObjectLike/* default */.Z)(other))) { + return value !== value && other !== other; + } + return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); +} + +/* harmony default export */ const _baseIsEqual = (baseIsEqual); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIsMatch.js + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseIsMatch_COMPARE_PARTIAL_FLAG = 1, + _baseIsMatch_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.isMatch` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to inspect. + * @param {Object} source The object of property values to match. + * @param {Array} matchData The property names, values, and compare flags to match. + * @param {Function} [customizer] The function to customize comparisons. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ +function baseIsMatch(object, source, matchData, customizer) { + var index = matchData.length, + length = index, + noCustomizer = !customizer; + + if (object == null) { + return !length; + } + object = Object(object); + while (index--) { + var data = matchData[index]; + if ((noCustomizer && data[2]) + ? data[1] !== object[data[0]] + : !(data[0] in object) + ) { + return false; + } + } + while (++index < length) { + data = matchData[index]; + var key = data[0], + objValue = object[key], + srcValue = data[1]; + + if (noCustomizer && data[2]) { + if (objValue === undefined && !(key in object)) { + return false; + } + } else { + var stack = new _Stack/* default */.Z; + if (customizer) { + var result = customizer(objValue, srcValue, key, object, source, stack); + } + if (!(result === undefined + ? _baseIsEqual(srcValue, objValue, _baseIsMatch_COMPARE_PARTIAL_FLAG | _baseIsMatch_COMPARE_UNORDERED_FLAG, customizer, stack) + : result + )) { + return false; + } + } + } + return true; +} + +/* harmony default export */ const _baseIsMatch = (baseIsMatch); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_isStrictComparable.js + + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && !(0,isObject/* default */.Z)(value); +} + +/* harmony default export */ const _isStrictComparable = (isStrictComparable); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_getMatchData.js + + + +/** + * Gets the property names, values, and compare flags of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the match data of `object`. + */ +function getMatchData(object) { + var result = (0,keys/* default */.Z)(object), + length = result.length; + + while (length--) { + var key = result[length], + value = object[key]; + + result[length] = [key, value, _isStrictComparable(value)]; + } + return result; +} + +/* harmony default export */ const _getMatchData = (getMatchData); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_matchesStrictComparable.js +/** + * A specialized version of `matchesProperty` for source values suitable + * for strict equality comparisons, i.e. `===`. + * + * @private + * @param {string} key The key of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function matchesStrictComparable(key, srcValue) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === srcValue && + (srcValue !== undefined || (key in Object(object))); + }; +} + +/* harmony default export */ const _matchesStrictComparable = (matchesStrictComparable); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatches.js + + + + +/** + * The base implementation of `_.matches` which doesn't clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatches(source) { + var matchData = _getMatchData(source); + if (matchData.length == 1 && matchData[0][2]) { + return _matchesStrictComparable(matchData[0][0], matchData[0][1]); + } + return function(object) { + return object === source || _baseIsMatch(object, source, matchData); + }; +} + +/* harmony default export */ const _baseMatches = (baseMatches); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +;// CONCATENATED MODULE: ./node_modules/lodash-es/get.js + + +/** + * Gets the value at `path` of `object`. If the resolved value is + * `undefined`, the `defaultValue` is returned in its place. + * + * @static + * @memberOf _ + * @since 3.7.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to get. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; + * + * _.get(object, 'a[0].b.c'); + * // => 3 + * + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 + * + * _.get(object, 'a.b.c', 'default'); + * // => 'default' + */ +function get(object, path, defaultValue) { + var result = object == null ? undefined : (0,_baseGet/* default */.Z)(object, path); + return result === undefined ? defaultValue : result; +} + +/* harmony default export */ const lodash_es_get = (get); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseMatchesProperty.js + + + + + + + + +/** Used to compose bitmasks for value comparisons. */ +var _baseMatchesProperty_COMPARE_PARTIAL_FLAG = 1, + _baseMatchesProperty_COMPARE_UNORDERED_FLAG = 2; + +/** + * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} srcValue The value to match. + * @returns {Function} Returns the new spec function. + */ +function baseMatchesProperty(path, srcValue) { + if ((0,_isKey/* default */.Z)(path) && _isStrictComparable(srcValue)) { + return _matchesStrictComparable((0,_toKey/* default */.Z)(path), srcValue); + } + return function(object) { + var objValue = lodash_es_get(object, path); + return (objValue === undefined && objValue === srcValue) + ? (0,hasIn/* default */.Z)(object, path) + : _baseIsEqual(srcValue, objValue, _baseMatchesProperty_COMPARE_PARTIAL_FLAG | _baseMatchesProperty_COMPARE_UNORDERED_FLAG); + }; +} + +/* harmony default export */ const _baseMatchesProperty = (baseMatchesProperty); + +// EXTERNAL MODULE: ./node_modules/lodash-es/identity.js +var identity = __webpack_require__(69203); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseProperty.js +var _baseProperty = __webpack_require__(54193); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePropertyDeep.js + + +/** + * A specialized version of `baseProperty` which supports deep paths. + * + * @private + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function basePropertyDeep(path) { + return function(object) { + return (0,_baseGet/* default */.Z)(object, path); + }; +} + +/* harmony default export */ const _basePropertyDeep = (basePropertyDeep); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/property.js + + + + + +/** + * Creates a function that returns the value at `path` of a given object. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {Array|string} path The path of the property to get. + * @returns {Function} Returns the new accessor function. + * @example + * + * var objects = [ + * { 'a': { 'b': 2 } }, + * { 'a': { 'b': 1 } } + * ]; + * + * _.map(objects, _.property('a.b')); + * // => [2, 1] + * + * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); + * // => [1, 2] + */ +function property(path) { + return (0,_isKey/* default */.Z)(path) ? (0,_baseProperty/* default */.Z)((0,_toKey/* default */.Z)(path)) : _basePropertyDeep(path); +} + +/* harmony default export */ const lodash_es_property = (property); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseIteratee.js + + + + + + +/** + * The base implementation of `_.iteratee`. + * + * @private + * @param {*} [value=_.identity] The value to convert to an iteratee. + * @returns {Function} Returns the iteratee. + */ +function baseIteratee(value) { + // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. + // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. + if (typeof value == 'function') { + return value; + } + if (value == null) { + return identity/* default */.Z; + } + if (typeof value == 'object') { + return (0,isArray/* default */.Z)(value) + ? _baseMatchesProperty(value[0], value[1]) + : _baseMatches(value); + } + return lodash_es_property(value); +} + +/* harmony default export */ const _baseIteratee = (baseIteratee); + + +/***/ }), + +/***/ 21018: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49811); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + +/** + * The base implementation of `_.map` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ +function baseMap(collection, iteratee) { + var index = -1, + result = (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? Array(collection.length) : []; + + (0,_baseEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseMap); + + +/***/ }), + +/***/ 54193: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseProperty); + + +/***/ }), + +/***/ 59548: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if a `cache` value for `key` exists. + * + * @private + * @param {Object} cache The cache to query. + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function cacheHas(cache, key) { + return cache.has(key); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cacheHas); + + +/***/ }), + +/***/ 68882: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _identity_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69203); + + +/** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Function} Returns cast function. + */ +function castFunction(value) { + return typeof value == 'function' ? value : _identity_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (castFunction); + + +/***/ }), + +/***/ 22823: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ _castPath) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isKey.js +var _isKey = __webpack_require__(99365); +// EXTERNAL MODULE: ./node_modules/lodash-es/memoize.js +var memoize = __webpack_require__(42454); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_memoizeCapped.js + + +/** Used as the maximum memoize cache size. */ +var MAX_MEMOIZE_SIZE = 500; + +/** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ +function memoizeCapped(func) { + var result = (0,memoize/* default */.Z)(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; +} + +/* harmony default export */ const _memoizeCapped = (memoizeCapped); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_stringToPath.js + + +/** Used to match property names within property paths. */ +var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = _memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/* harmony default export */ const _stringToPath = (stringToPath); + +// EXTERNAL MODULE: ./node_modules/lodash-es/toString.js + 1 modules +var lodash_es_toString = __webpack_require__(50751); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_castPath.js + + + + + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value, object) { + if ((0,isArray/* default */.Z)(value)) { + return value; + } + return (0,_isKey/* default */.Z)(value, object) ? [value] : _stringToPath((0,lodash_es_toString/* default */.Z)(value)); +} + +/* harmony default export */ const _castPath = (castPath); + + +/***/ }), + +/***/ 1808: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63327); +/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(95695); +/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17179); + + + + +/** + * Creates an array of own enumerable property names and symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names and symbols. + */ +function getAllKeys(object) { + return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z, _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys); + + +/***/ }), + +/***/ 95695: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(68774); +/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(60532); + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Built-in value references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeGetSymbols = Object.getOwnPropertySymbols; + +/** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ +var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); +}; + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols); + + +/***/ }), + +/***/ 16174: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _castPath_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22823); +/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(29169); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(27771); +/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(56009); +/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1656); +/* harmony import */ var _toKey_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62281); + + + + + + + +/** + * Checks if `path` exists on `object`. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @param {Function} hasFunc The function to check properties. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + */ +function hasPath(object, path, hasFunc) { + path = (0,_castPath_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = (0,_toKey_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(length) && (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(key, length) && + ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Z)(object) || (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hasPath); + + +/***/ }), + +/***/ 99365: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(72714); + + + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/; + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if ((0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKey); + + +/***/ }), + +/***/ 6545: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Converts `set` to an array of its values. + * + * @private + * @param {Object} set The set to convert. + * @returns {Array} Returns the values. + */ +function setToArray(set) { + var index = -1, + result = Array(set.size); + + set.forEach(function(value) { + result[++index] = value; + }); + return result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (setToArray); + + +/***/ }), + +/***/ 62281: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(72714); + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || (0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toKey); + + +/***/ }), + +/***/ 3688: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseRest_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(69581); +/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(79651); +/* harmony import */ var _isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50439); +/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32957); + + + + + +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Assigns own and inherited enumerable string keyed properties of source + * objects to the destination object for all destination properties that + * resolve to `undefined`. Source objects are applied from left to right. + * Once a property is set, additional values of the same property are ignored. + * + * **Note:** This method mutates `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.defaultsDeep + * @example + * + * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); + * // => { 'a': 1, 'b': 2 } + */ +var defaults = (0,_baseRest_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(function(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && (0,_isIterateeCall_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + ((0,_eq_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; +}); + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defaults); + + +/***/ }), + +/***/ 13445: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_filter) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayFilter.js +var _arrayFilter = __webpack_require__(68774); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseFilter.js + + +/** + * The base implementation of `_.filter` without support for iteratee shorthands. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} predicate The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + */ +function baseFilter(collection, predicate) { + var result = []; + (0,_baseEach/* default */.Z)(collection, function(value, index, collection) { + if (predicate(value, index, collection)) { + result.push(value); + } + }); + return result; +} + +/* harmony default export */ const _baseFilter = (baseFilter); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/filter.js + + + + + +/** + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is invoked with three + * arguments: (value, index|key, collection). + * + * **Note:** Unlike `_.remove`, this method returns a new array. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [predicate=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new filtered array. + * @see _.reject + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.filter(users, function(o) { return !o.active; }); + * // => objects for ['fred'] + * + * // The `_.matches` iteratee shorthand. + * _.filter(users, { 'age': 36, 'active': true }); + * // => objects for ['barney'] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, ['active', false]); + * // => objects for ['fred'] + * + * // The `_.property` iteratee shorthand. + * _.filter(users, 'active'); + * // => objects for ['barney'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', 'barney'] + */ +function filter(collection, predicate) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayFilter/* default */.Z : _baseFilter; + return func(collection, (0,_baseIteratee/* default */.Z)(predicate, 3)); +} + +/* harmony default export */ const lodash_es_filter = (filter); + + +/***/ }), + +/***/ 27961: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10626); + + +/** + * Flattens `array` a single level deep. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Array + * @param {Array} array The array to flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] + */ +function flatten(array) { + var length = array == null ? 0 : array.length; + return length ? (0,_baseFlatten_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(array, 1) : []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatten); + + +/***/ }), + +/***/ 70870: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(76579); +/* harmony import */ var _baseEach_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49811); +/* harmony import */ var _castFunction_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(68882); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Iterates over elements of `collection` and invokes `iteratee` for each element. + * The iteratee is invoked with three arguments: (value, index|key, collection). + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * **Note:** As with other "Collections" methods, objects with a "length" + * property are iterated like arrays. To avoid this behavior use `_.forIn` + * or `_.forOwn` for object iteration. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @alias each + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array|Object} Returns `collection`. + * @see _.forEachRight + * @example + * + * _.forEach([1, 2], function(value) { + * console.log(value); + * }); + * // => Logs `1` then `2`. + * + * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { + * console.log(key); + * }); + * // => Logs 'a' then 'b' (iteration order is not guaranteed). + */ +function forEach(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayEach_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseEach_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_castFunction_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (forEach); + + +/***/ }), + +/***/ 17452: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_has) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHas.js +/** Used for built-in method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var _baseHas_hasOwnProperty = objectProto.hasOwnProperty; + +/** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHas(object, key) { + return object != null && _baseHas_hasOwnProperty.call(object, key); +} + +/* harmony default export */ const _baseHas = (baseHas); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/has.js + + + +/** + * Checks if `path` is a direct property of `object`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = { 'a': { 'b': 2 } }; + * var other = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.has(object, 'a'); + * // => true + * + * _.has(object, 'a.b'); + * // => true + * + * _.has(object, ['a', 'b']); + * // => true + * + * _.has(other, 'a'); + * // => false + */ +function has(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHas); +} + +/* harmony default export */ const lodash_es_has = (has); + + +/***/ }), + +/***/ 75487: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_hasIn) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseHasIn.js +/** + * The base implementation of `_.hasIn` without support for deep paths. + * + * @private + * @param {Object} [object] The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ +function baseHasIn(object, key) { + return object != null && key in Object(object); +} + +/* harmony default export */ const _baseHasIn = (baseHasIn); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_hasPath.js +var _hasPath = __webpack_require__(16174); +;// CONCATENATED MODULE: ./node_modules/lodash-es/hasIn.js + + + +/** + * Checks if `path` is a direct or inherited property of `object`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` exists, else `false`. + * @example + * + * var object = _.create({ 'a': _.create({ 'b': 2 }) }); + * + * _.hasIn(object, 'a'); + * // => true + * + * _.hasIn(object, 'a.b'); + * // => true + * + * _.hasIn(object, ['a', 'b']); + * // => true + * + * _.hasIn(object, 'b'); + * // => false + */ +function hasIn(object, path) { + return object != null && (0,_hasPath/* default */.Z)(object, path, _baseHasIn); +} + +/* harmony default export */ const lodash_es_hasIn = (hasIn); + + +/***/ }), + +/***/ 72714: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93589); +/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18533); + + + +/** `Object#toString` result references. */ +var symbolTag = '[object Symbol]'; + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + ((0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(value) == symbolTag); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol); + + +/***/ }), + +/***/ 49360: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * Checks if `value` is `undefined`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. + * @example + * + * _.isUndefined(void 0); + * // => true + * + * _.isUndefined(null); + * // => false + */ +function isUndefined(value) { + return value === undefined; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isUndefined); + + +/***/ }), + +/***/ 17179: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(87668); +/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39473); +/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50585); + + + + +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +function keys(object) { + return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(object); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys); + + +/***/ }), + +/***/ 43836: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74073); +/* harmony import */ var _baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74765); +/* harmony import */ var _baseMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(21018); +/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27771); + + + + + +/** + * Creates an array of values by running each element in `collection` thru + * `iteratee`. The iteratee is invoked with three arguments: + * (value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, + * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, + * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, + * `template`, `trim`, `trimEnd`, `trimStart`, and `words` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + * @example + * + * function square(n) { + * return n * n; + * } + * + * _.map([4, 8], square); + * // => [16, 64] + * + * _.map({ 'a': 4, 'b': 8 }, square); + * // => [16, 64] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // The `_.property` iteratee shorthand. + * _.map(users, 'user'); + * // => ['barney', 'fred'] + */ +function map(collection, iteratee) { + var func = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(collection) ? _arrayMap_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z : _baseMap_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z; + return func(collection, (0,_baseIteratee_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Z)(iteratee, 3)); +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (map); + + +/***/ }), + +/***/ 61666: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_pick) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseGet.js +var _baseGet = __webpack_require__(13317); +// EXTERNAL MODULE: ./node_modules/lodash-es/_assignValue.js +var _assignValue = __webpack_require__(72954); +// EXTERNAL MODULE: ./node_modules/lodash-es/_castPath.js + 2 modules +var _castPath = __webpack_require__(22823); +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIndex.js +var _isIndex = __webpack_require__(56009); +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/_toKey.js +var _toKey = __webpack_require__(62281); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseSet.js + + + + + + +/** + * The base implementation of `_.set`. + * + * @private + * @param {Object} object The object to modify. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. + * @param {Function} [customizer] The function to customize path creation. + * @returns {Object} Returns `object`. + */ +function baseSet(object, path, value, customizer) { + if (!(0,isObject/* default */.Z)(object)) { + return object; + } + path = (0,_castPath/* default */.Z)(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = (0,_toKey/* default */.Z)(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = (0,isObject/* default */.Z)(objValue) + ? objValue + : ((0,_isIndex/* default */.Z)(path[index + 1]) ? [] : {}); + } + } + (0,_assignValue/* default */.Z)(nested, key, newValue); + nested = nested[key]; + } + return object; +} + +/* harmony default export */ const _baseSet = (baseSet); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePickBy.js + + + + +/** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ +function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = (0,_baseGet/* default */.Z)(object, path); + + if (predicate(value, path)) { + _baseSet(result, (0,_castPath/* default */.Z)(path, object), value); + } + } + return result; +} + +/* harmony default export */ const _basePickBy = (basePickBy); + +// EXTERNAL MODULE: ./node_modules/lodash-es/hasIn.js + 1 modules +var hasIn = __webpack_require__(75487); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_basePick.js + + + +/** + * The base implementation of `_.pick` without support for individual + * property identifiers. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ +function basePick(object, paths) { + return _basePickBy(object, paths, function(value, path) { + return (0,hasIn/* default */.Z)(object, path); + }); +} + +/* harmony default export */ const _basePick = (basePick); + +// EXTERNAL MODULE: ./node_modules/lodash-es/flatten.js +var flatten = __webpack_require__(27961); +// EXTERNAL MODULE: ./node_modules/lodash-es/_overRest.js + 1 modules +var _overRest = __webpack_require__(81211); +// EXTERNAL MODULE: ./node_modules/lodash-es/_setToString.js + 2 modules +var _setToString = __webpack_require__(27227); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_flatRest.js + + + + +/** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ +function flatRest(func) { + return (0,_setToString/* default */.Z)((0,_overRest/* default */.Z)(func, undefined, flatten/* default */.Z), func + ''); +} + +/* harmony default export */ const _flatRest = (flatRest); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/pick.js + + + +/** + * Creates an object composed of the picked `object` properties. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths to pick. + * @returns {Object} Returns the new object. + * @example + * + * var object = { 'a': 1, 'b': '2', 'c': 3 }; + * + * _.pick(object, ['a', 'c']); + * // => { 'a': 1, 'c': 3 } + */ +var pick = _flatRest(function(object, paths) { + return object == null ? {} : _basePick(object, paths); +}); + +/* harmony default export */ const lodash_es_pick = (pick); + + +/***/ }), + +/***/ 74379: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_range) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseRange.js +/* Built-in method references for those with the same name as other `lodash` methods. */ +var nativeCeil = Math.ceil, + nativeMax = Math.max; + +/** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ +function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); + + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; + } + return result; +} + +/* harmony default export */ const _baseRange = (baseRange); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_isIterateeCall.js +var _isIterateeCall = __webpack_require__(50439); +// EXTERNAL MODULE: ./node_modules/lodash-es/toFinite.js + 3 modules +var toFinite = __webpack_require__(94099); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_createRange.js + + + + +/** + * Creates a `_.range` or `_.rangeRight` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new range function. + */ +function createRange(fromRight) { + return function(start, end, step) { + if (step && typeof step != 'number' && (0,_isIterateeCall/* default */.Z)(start, end, step)) { + end = step = undefined; + } + // Ensure the sign of `-0` is preserved. + start = (0,toFinite/* default */.Z)(start); + if (end === undefined) { + end = start; + start = 0; + } else { + end = (0,toFinite/* default */.Z)(end); + } + step = step === undefined ? (start < end ? 1 : -1) : (0,toFinite/* default */.Z)(step); + return _baseRange(start, end, step, fromRight); + }; +} + +/* harmony default export */ const _createRange = (createRange); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/range.js + + +/** + * Creates an array of numbers (positive and/or negative) progressing from + * `start` up to, but not including, `end`. A step of `-1` is used if a negative + * `start` is specified without an `end` or `step`. If `end` is not specified, + * it's set to `start` with `start` then set to `0`. + * + * **Note:** JavaScript follows the IEEE-754 standard for resolving + * floating-point values which can produce unexpected results. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {number} [start=0] The start of the range. + * @param {number} end The end of the range. + * @param {number} [step=1] The value to increment or decrement by. + * @returns {Array} Returns the range of numbers. + * @see _.inRange, _.rangeRight + * @example + * + * _.range(4); + * // => [0, 1, 2, 3] + * + * _.range(-4); + * // => [0, -1, -2, -3] + * + * _.range(1, 5); + * // => [1, 2, 3, 4] + * + * _.range(0, 20, 5); + * // => [0, 5, 10, 15] + * + * _.range(0, -4, -1); + * // => [0, -1, -2, -3] + * + * _.range(1, 4, 0); + * // => [1, 1, 1] + * + * _.range(0); + * // => [] + */ +var range = _createRange(); + +/* harmony default export */ const lodash_es_range = (range); + + +/***/ }), + +/***/ 92344: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_reduce) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_arrayReduce.js +/** + * A specialized version of `_.reduce` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initAccum] Specify using the first element of `array` as + * the initial value. + * @returns {*} Returns the accumulated value. + */ +function arrayReduce(array, iteratee, accumulator, initAccum) { + var index = -1, + length = array == null ? 0 : array.length; + + if (initAccum && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; +} + +/* harmony default export */ const _arrayReduce = (arrayReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseEach.js + 1 modules +var _baseEach = __webpack_require__(49811); +// EXTERNAL MODULE: ./node_modules/lodash-es/_baseIteratee.js + 16 modules +var _baseIteratee = __webpack_require__(74765); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseReduce.js +/** + * The base implementation of `_.reduce` and `_.reduceRight`, without support + * for iteratee shorthands, which iterates over `collection` using `eachFunc`. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} accumulator The initial value. + * @param {boolean} initAccum Specify using the first or last element of + * `collection` as the initial value. + * @param {Function} eachFunc The function to iterate over `collection`. + * @returns {*} Returns the accumulated value. + */ +function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { + eachFunc(collection, function(value, index, collection) { + accumulator = initAccum + ? (initAccum = false, value) + : iteratee(accumulator, value, index, collection); + }); + return accumulator; +} + +/* harmony default export */ const _baseReduce = (baseReduce); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +;// CONCATENATED MODULE: ./node_modules/lodash-es/reduce.js + + + + + + +/** + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` thru `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not given, the first element of `collection` is used as the initial + * value. The iteratee is invoked with four arguments: + * (accumulator, value, index|key, collection). + * + * Many lodash methods are guarded to work as iteratees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, + * and `sortBy` + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Collection + * @param {Array|Object} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @returns {*} Returns the accumulated value. + * @see _.reduceRight + * @example + * + * _.reduce([1, 2], function(sum, n) { + * return sum + n; + * }, 0); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { + * (result[value] || (result[value] = [])).push(key); + * return result; + * }, {}); + * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) + */ +function reduce(collection, iteratee, accumulator) { + var func = (0,isArray/* default */.Z)(collection) ? _arrayReduce : _baseReduce, + initAccum = arguments.length < 3; + + return func(collection, (0,_baseIteratee/* default */.Z)(iteratee, 4), accumulator, initAccum, _baseEach/* default */.Z); +} + +/* harmony default export */ const lodash_es_reduce = (reduce); + + +/***/ }), + +/***/ 60532: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/** + * This method returns a new empty array. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {Array} Returns the new empty array. + * @example + * + * var arrays = _.times(2, _.stubArray); + * + * console.log(arrays); + * // => [[], []] + * + * console.log(arrays[0] === arrays[1]); + * // => false + */ +function stubArray() { + return []; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray); + + +/***/ }), + +/***/ 94099: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toFinite) +}); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_trimmedEndIndex.js +/** Used to match a single whitespace character. */ +var reWhitespace = /\s/; + +/** + * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ +function trimmedEndIndex(string) { + var index = string.length; + + while (index-- && reWhitespace.test(string.charAt(index))) {} + return index; +} + +/* harmony default export */ const _trimmedEndIndex = (trimmedEndIndex); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseTrim.js + + +/** Used to match leading whitespace. */ +var reTrimStart = /^\s+/; + +/** + * The base implementation of `_.trim`. + * + * @private + * @param {string} string The string to trim. + * @returns {string} Returns the trimmed string. + */ +function baseTrim(string) { + return string + ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '') + : string; +} + +/* harmony default export */ const _baseTrim = (baseTrim); + +// EXTERNAL MODULE: ./node_modules/lodash-es/isObject.js +var isObject = __webpack_require__(77226); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/toNumber.js + + + + +/** Used as references for various `Number` constants. */ +var NAN = 0 / 0; + +/** Used to detect bad signed hexadecimal string values. */ +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + +/** Used to detect binary string values. */ +var reIsBinary = /^0b[01]+$/i; + +/** Used to detect octal string values. */ +var reIsOctal = /^0o[0-7]+$/i; + +/** Built-in method references without a dependency on `root`. */ +var freeParseInt = parseInt; + +/** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ +function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if ((0,isSymbol/* default */.Z)(value)) { + return NAN; + } + if ((0,isObject/* default */.Z)(value)) { + var other = typeof value.valueOf == 'function' ? value.valueOf() : value; + value = (0,isObject/* default */.Z)(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = _baseTrim(value); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); +} + +/* harmony default export */ const lodash_es_toNumber = (toNumber); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toFinite.js + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308; + +/** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ +function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = lodash_es_toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; +} + +/* harmony default export */ const lodash_es_toFinite = (toFinite); + + +/***/ }), + +/***/ 50751: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_toString) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_Symbol.js +var _Symbol = __webpack_require__(17685); +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +// EXTERNAL MODULE: ./node_modules/lodash-es/isArray.js +var isArray = __webpack_require__(27771); +// EXTERNAL MODULE: ./node_modules/lodash-es/isSymbol.js +var isSymbol = __webpack_require__(72714); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseToString.js + + + + + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = _Symbol/* default */.Z ? _Symbol/* default */.Z.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if ((0,isArray/* default */.Z)(value)) { + // Recursively convert values (susceptible to call stack limits). + return (0,_arrayMap/* default */.Z)(value, baseToString) + ''; + } + if ((0,isSymbol/* default */.Z)(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/* harmony default export */ const _baseToString = (baseToString); + +;// CONCATENATED MODULE: ./node_modules/lodash-es/toString.js + + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString_toString(value) { + return value == null ? '' : _baseToString(value); +} + +/* harmony default export */ const lodash_es_toString = (toString_toString); + + +/***/ }), + +/***/ 66749: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ Z: () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* harmony import */ var _toString_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50751); + + +/** Used to generate unique IDs. */ +var idCounter = 0; + +/** + * Generates a unique ID. If `prefix` is given, the ID is appended to it. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Util + * @param {string} [prefix=''] The value to prefix the ID with. + * @returns {string} Returns the unique ID. + * @example + * + * _.uniqueId('contact_'); + * // => 'contact_104' + * + * _.uniqueId(); + * // => '105' + */ +function uniqueId(prefix) { + var id = ++idCounter; + return (0,_toString_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(prefix) + id; +} + +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (uniqueId); + + +/***/ }), + +/***/ 34148: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + Z: () => (/* binding */ lodash_es_values) +}); + +// EXTERNAL MODULE: ./node_modules/lodash-es/_arrayMap.js +var _arrayMap = __webpack_require__(74073); +;// CONCATENATED MODULE: ./node_modules/lodash-es/_baseValues.js + + +/** + * The base implementation of `_.values` and `_.valuesIn` which creates an + * array of `object` property values corresponding to the property names + * of `props`. + * + * @private + * @param {Object} object The object to query. + * @param {Array} props The property names to get values for. + * @returns {Object} Returns the array of property values. + */ +function baseValues(object, props) { + return (0,_arrayMap/* default */.Z)(props, function(key) { + return object[key]; + }); +} + +/* harmony default export */ const _baseValues = (baseValues); + +// EXTERNAL MODULE: ./node_modules/lodash-es/keys.js +var keys = __webpack_require__(17179); +;// CONCATENATED MODULE: ./node_modules/lodash-es/values.js + + + +/** + * Creates an array of the own enumerable string keyed property values of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property values. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.values(new Foo); + * // => [1, 2] (iteration order is not guaranteed) + * + * _.values('hi'); + * // => ['h', 'i'] + */ +function values(object) { + return object == null ? [] : _baseValues(object, (0,keys/* default */.Z)(object)); +} + +/* harmony default export */ const lodash_es_values = (values); + + +/***/ }), + +/***/ 9816: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ diagram: () => (/* binding */ diagram) +/* harmony export */ }); +/* harmony import */ var _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(52244); +/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(64218); +/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(41644); +/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(45625); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(56363); +/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(27484); +/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17967); +/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(20683); + + + + + + + + + + + + + + +const idCache = {}; +const set = (key, val) => { + idCache[key] = val; +}; +const get = (k) => idCache[k]; +const keys = () => Object.keys(idCache); +const size = () => keys().length; +const idCache$1 = { + get, + set, + keys, + size +}; +const drawStartState = (g) => g.append("circle").attr("class", "start-state").attr("r", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit).attr("cx", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit).attr("cy", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit); +const drawDivider = (g) => g.append("line").style("stroke", "grey").style("stroke-dasharray", "3").attr("x1", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight).attr("class", "divider").attr("x2", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight * 2).attr("y1", 0).attr("y2", 0); +const drawSimpleState = (g, stateDef) => { + const state = g.append("text").attr("x", 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("font-size", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.fontSize).attr("class", "state-title").text(stateDef.id); + const classBox = state.node().getBBox(); + g.insert("rect", ":first-child").attr("x", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("width", classBox.width + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("height", classBox.height + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("rx", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.radius); + return state; +}; +const drawDescrState = (g, stateDef) => { + const addTspan = function(textEl, txt, isFirst2) { + const tSpan = textEl.append("tspan").attr("x", 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).text(txt); + if (!isFirst2) { + tSpan.attr("dy", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight); + } + }; + const title = g.append("text").attr("x", 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight + 1.3 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("font-size", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.fontSize).attr("class", "state-title").text(stateDef.descriptions[0]); + const titleBox = title.node().getBBox(); + const titleHeight = titleBox.height; + const description = g.append("text").attr("x", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr( + "y", + titleHeight + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding * 0.4 + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.dividerMargin + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight + ).attr("class", "state-description"); + let isFirst = true; + let isSecond = true; + stateDef.descriptions.forEach(function(descr) { + if (!isFirst) { + addTspan(description, descr, isSecond); + isSecond = false; + } + isFirst = false; + }); + const descrLine = g.append("line").attr("x1", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y1", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + titleHeight + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.dividerMargin / 2).attr("y2", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + titleHeight + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.dividerMargin / 2).attr("class", "descr-divider"); + const descrBox = description.node().getBBox(); + const width = Math.max(descrBox.width, titleBox.width); + descrLine.attr("x2", width + 3 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding); + g.insert("rect", ":first-child").attr("x", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("width", width + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("height", descrBox.height + titleHeight + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("rx", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.radius); + return g; +}; +const addTitleAndBox = (g, stateDef, altBkg) => { + const pad = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding; + const dblPad = 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding; + const orgBox = g.node().getBBox(); + const orgWidth = orgBox.width; + const orgX = orgBox.x; + const title = g.append("text").attr("x", 0).attr("y", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.titleShift).attr("font-size", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.fontSize).attr("class", "state-title").text(stateDef.id); + const titleBox = title.node().getBBox(); + const titleWidth = titleBox.width + dblPad; + let width = Math.max(titleWidth, orgWidth); + if (width === orgWidth) { + width = width + dblPad; + } + let startX; + const graphBox = g.node().getBBox(); + if (stateDef.doc) + ; + startX = orgX - pad; + if (titleWidth > orgWidth) { + startX = (orgWidth - width) / 2 + pad; + } + if (Math.abs(orgX - graphBox.x) < pad && titleWidth > orgWidth) { + startX = orgX - (titleWidth - orgWidth) / 2; + } + const lineY = 1 - (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight; + g.insert("rect", ":first-child").attr("x", startX).attr("y", lineY).attr("class", altBkg ? "alt-composit" : "composit").attr("width", width).attr( + "height", + graphBox.height + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.titleShift + 1 + ).attr("rx", "0"); + title.attr("x", startX + pad); + if (titleWidth <= orgWidth) { + title.attr("x", orgX + (width - dblPad) / 2 - titleWidth / 2 + pad); + } + g.insert("rect", ":first-child").attr("x", startX).attr( + "y", + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.titleShift - (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight - (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + ).attr("width", width).attr("height", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight * 3).attr("rx", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.radius); + g.insert("rect", ":first-child").attr("x", startX).attr( + "y", + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.titleShift - (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight - (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + ).attr("width", width).attr("height", graphBox.height + 3 + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.textHeight).attr("rx", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.radius); + return g; +}; +const drawEndState = (g) => { + g.append("circle").attr("class", "end-state-outer").attr("r", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.miniPadding).attr( + "cx", + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.miniPadding + ).attr( + "cy", + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.miniPadding + ); + return g.append("circle").attr("class", "end-state-inner").attr("r", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit).attr("cx", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + 2).attr("cy", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.sizeUnit + 2); +}; +const drawForkJoinState = (g, stateDef) => { + let width = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.forkWidth; + let height = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.forkHeight; + if (stateDef.parentId) { + let tmp = width; + width = height; + height = tmp; + } + return g.append("rect").style("stroke", "black").style("fill", "black").attr("width", width).attr("height", height).attr("x", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("y", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding); +}; +const _drawLongText = (_text, x, y, g) => { + let textHeight = 0; + const textElem = g.append("text"); + textElem.style("text-anchor", "start"); + textElem.attr("class", "noteText"); + let text = _text.replace(/\r\n/g, "<br/>"); + text = text.replace(/\n/g, "<br/>"); + const lines = text.split(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.e.lineBreakRegex); + let tHeight = 1.25 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin; + for (const line2 of lines) { + const txt = line2.trim(); + if (txt.length > 0) { + const span = textElem.append("tspan"); + span.text(txt); + if (tHeight === 0) { + const textBounds = span.node().getBBox(); + tHeight += textBounds.height; + } + textHeight += tHeight; + span.attr("x", x + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin); + span.attr("y", y + textHeight + 1.25 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin); + } + } + return { textWidth: textElem.node().getBBox().width, textHeight }; +}; +const drawNote = (text, g) => { + g.attr("class", "state-note"); + const note = g.append("rect").attr("x", 0).attr("y", (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding); + const rectElem = g.append("g"); + const { textWidth, textHeight } = _drawLongText(text, 0, 0, rectElem); + note.attr("height", textHeight + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin); + note.attr("width", textWidth + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.noteMargin * 2); + return note; +}; +const drawState = function(elem, stateDef) { + const id = stateDef.id; + const stateInfo = { + id, + label: stateDef.id, + width: 0, + height: 0 + }; + const g = elem.append("g").attr("id", id).attr("class", "stateGroup"); + if (stateDef.type === "start") { + drawStartState(g); + } + if (stateDef.type === "end") { + drawEndState(g); + } + if (stateDef.type === "fork" || stateDef.type === "join") { + drawForkJoinState(g, stateDef); + } + if (stateDef.type === "note") { + drawNote(stateDef.note.text, g); + } + if (stateDef.type === "divider") { + drawDivider(g); + } + if (stateDef.type === "default" && stateDef.descriptions.length === 0) { + drawSimpleState(g, stateDef); + } + if (stateDef.type === "default" && stateDef.descriptions.length > 0) { + drawDescrState(g, stateDef); + } + const stateBox = g.node().getBBox(); + stateInfo.width = stateBox.width + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding; + stateInfo.height = stateBox.height + 2 * (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding; + idCache$1.set(id, stateInfo); + return stateInfo; +}; +let edgeCount = 0; +const drawEdge = function(elem, path, relation) { + const getRelationType = function(type) { + switch (type) { + case _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.AGGREGATION: + return "aggregation"; + case _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.EXTENSION: + return "extension"; + case _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.COMPOSITION: + return "composition"; + case _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.DEPENDENCY: + return "dependency"; + } + }; + path.points = path.points.filter((p) => !Number.isNaN(p.y)); + const lineData = path.points; + const lineFunction = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .line */ .jvg)().x(function(d) { + return d.x; + }).y(function(d) { + return d.y; + }).curve(d3__WEBPACK_IMPORTED_MODULE_0__/* .curveBasis */ .$0Z); + const svgPath = elem.append("path").attr("d", lineFunction(lineData)).attr("id", "edge" + edgeCount).attr("class", "transition"); + let url = ""; + if ((0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.arrowMarkerAbsolute) { + url = window.location.protocol + "//" + window.location.host + window.location.pathname + window.location.search; + url = url.replace(/\(/g, "\\("); + url = url.replace(/\)/g, "\\)"); + } + svgPath.attr( + "marker-end", + "url(" + url + "#" + getRelationType(_styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d.relationType.DEPENDENCY) + "End)" + ); + if (relation.title !== void 0) { + const label = elem.append("g").attr("class", "stateLabel"); + const { x, y } = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.u.calcLabelPosition(path.points); + const rows = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.e.getRows(relation.title); + let titleHeight = 0; + const titleRows = []; + let maxWidth = 0; + let minX = 0; + for (let i = 0; i <= rows.length; i++) { + const title = label.append("text").attr("text-anchor", "middle").text(rows[i]).attr("x", x).attr("y", y + titleHeight); + const boundstmp = title.node().getBBox(); + maxWidth = Math.max(maxWidth, boundstmp.width); + minX = Math.min(minX, boundstmp.x); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info(boundstmp.x, x, y + titleHeight); + if (titleHeight === 0) { + const titleBox = title.node().getBBox(); + titleHeight = titleBox.height; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info("Title height", titleHeight, y); + } + titleRows.push(title); + } + let boxHeight = titleHeight * rows.length; + if (rows.length > 1) { + const heightAdj = (rows.length - 1) * titleHeight * 0.5; + titleRows.forEach((title, i) => title.attr("y", y + i * titleHeight - heightAdj)); + boxHeight = titleHeight * rows.length; + } + const bounds = label.node().getBBox(); + label.insert("rect", ":first-child").attr("class", "box").attr("x", x - maxWidth / 2 - (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding / 2).attr("y", y - boxHeight / 2 - (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding / 2 - 3.5).attr("width", maxWidth + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding).attr("height", boxHeight + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state.padding); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.info(bounds); + } + edgeCount++; +}; +let conf; +const transformationLog = {}; +const setConf = function() { +}; +const insertMarkers = function(elem) { + elem.append("defs").append("marker").attr("id", "dependencyEnd").attr("refX", 19).attr("refY", 7).attr("markerWidth", 20).attr("markerHeight", 28).attr("orient", "auto").append("path").attr("d", "M 19,7 L9,13 L14,7 L9,1 Z"); +}; +const draw = function(text, id, _version, diagObj) { + conf = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().state; + const securityLevel = (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.c)().securityLevel; + let sandboxElement; + if (securityLevel === "sandbox") { + sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id); + } + const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body"); + const doc = securityLevel === "sandbox" ? sandboxElement.nodes()[0].contentDocument : document; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Rendering diagram " + text); + const diagram2 = root.select(`[id='${id}']`); + insertMarkers(diagram2); + const rootDoc = diagObj.db.getRootDoc(); + renderDoc(rootDoc, diagram2, void 0, false, root, doc, diagObj); + const padding = conf.padding; + const bounds = diagram2.node().getBBox(); + const width = bounds.width + padding * 2; + const height = bounds.height + padding * 2; + const svgWidth = width * 1.75; + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.i)(diagram2, height, svgWidth, conf.useMaxWidth); + diagram2.attr( + "viewBox", + `${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + " " + height + ); +}; +const getLabelWidth = (text) => { + return text ? text.length * conf.fontSizeFactor : 1; +}; +const renderDoc = (doc, diagram2, parentId, altBkg, root, domDocument, diagObj) => { + const graph = new dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_2__/* .Graph */ .k({ + compound: true, + multigraph: true + }); + let i; + let edgeFreeDoc = true; + for (i = 0; i < doc.length; i++) { + if (doc[i].stmt === "relation") { + edgeFreeDoc = false; + break; + } + } + if (parentId) { + graph.setGraph({ + rankdir: "LR", + multigraph: true, + compound: true, + // acyclicer: 'greedy', + ranker: "tight-tree", + ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor, + nodeSep: edgeFreeDoc ? 1 : 50, + isMultiGraph: true + // ranksep: 5, + // nodesep: 1 + }); + } else { + graph.setGraph({ + rankdir: "TB", + multigraph: true, + compound: true, + // isCompound: true, + // acyclicer: 'greedy', + // ranker: 'longest-path' + ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor, + nodeSep: edgeFreeDoc ? 1 : 50, + ranker: "tight-tree", + // ranker: 'network-simplex' + isMultiGraph: true + }); + } + graph.setDefaultEdgeLabel(function() { + return {}; + }); + diagObj.db.extract(doc); + const states = diagObj.db.getStates(); + const relations = diagObj.db.getRelations(); + const keys2 = Object.keys(states); + for (const key of keys2) { + const stateDef = states[key]; + if (parentId) { + stateDef.parentId = parentId; + } + let node; + if (stateDef.doc) { + let sub = diagram2.append("g").attr("id", stateDef.id).attr("class", "stateGroup"); + node = renderDoc(stateDef.doc, sub, stateDef.id, !altBkg, root, domDocument, diagObj); + { + sub = addTitleAndBox(sub, stateDef, altBkg); + let boxBounds = sub.node().getBBox(); + node.width = boxBounds.width; + node.height = boxBounds.height + conf.padding / 2; + transformationLog[stateDef.id] = { y: conf.compositTitleSize }; + } + } else { + node = drawState(diagram2, stateDef); + } + if (stateDef.note) { + const noteDef = { + descriptions: [], + id: stateDef.id + "-note", + note: stateDef.note, + type: "note" + }; + const note = drawState(diagram2, noteDef); + if (stateDef.note.position === "left of") { + graph.setNode(node.id + "-note", note); + graph.setNode(node.id, node); + } else { + graph.setNode(node.id, node); + graph.setNode(node.id + "-note", note); + } + graph.setParent(node.id, node.id + "-group"); + graph.setParent(node.id + "-note", node.id + "-group"); + } else { + graph.setNode(node.id, node); + } + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Count=", graph.nodeCount(), graph); + let cnt = 0; + relations.forEach(function(relation) { + cnt++; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Setting edge", relation); + graph.setEdge( + relation.id1, + relation.id2, + { + relation, + width: getLabelWidth(relation.title), + height: conf.labelHeight * _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.e.getRows(relation.title).length, + labelpos: "c" + }, + "id" + cnt + ); + }); + (0,dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_1__/* .layout */ .bK)(graph); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Graph after layout", graph.nodes()); + const svgElem = diagram2.node(); + graph.nodes().forEach(function(v) { + if (v !== void 0 && graph.node(v) !== void 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.warn("Node " + v + ": " + JSON.stringify(graph.node(v))); + root.select("#" + svgElem.id + " #" + v).attr( + "transform", + "translate(" + (graph.node(v).x - graph.node(v).width / 2) + "," + (graph.node(v).y + (transformationLog[v] ? transformationLog[v].y : 0) - graph.node(v).height / 2) + " )" + ); + root.select("#" + svgElem.id + " #" + v).attr("data-x-shift", graph.node(v).x - graph.node(v).width / 2); + const dividers = domDocument.querySelectorAll("#" + svgElem.id + " #" + v + " .divider"); + dividers.forEach((divider) => { + const parent = divider.parentElement; + let pWidth = 0; + let pShift = 0; + if (parent) { + if (parent.parentElement) { + pWidth = parent.parentElement.getBBox().width; + } + pShift = parseInt(parent.getAttribute("data-x-shift"), 10); + if (Number.isNaN(pShift)) { + pShift = 0; + } + } + divider.setAttribute("x1", 0 - pShift + 8); + divider.setAttribute("x2", pWidth - pShift - 8); + }); + } else { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("No Node " + v + ": " + JSON.stringify(graph.node(v))); + } + }); + let stateBox = svgElem.getBBox(); + graph.edges().forEach(function(e) { + if (e !== void 0 && graph.edge(e) !== void 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(graph.edge(e))); + drawEdge(diagram2, graph.edge(e), graph.edge(e).relation); + } + }); + stateBox = svgElem.getBBox(); + const stateInfo = { + id: parentId ? parentId : "root", + label: parentId ? parentId : "root", + width: 0, + height: 0 + }; + stateInfo.width = stateBox.width + 2 * conf.padding; + stateInfo.height = stateBox.height + 2 * conf.padding; + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_6__.l.debug("Doc rendered", stateInfo, graph); + return stateInfo; +}; +const renderer = { + setConf, + draw +}; +const diagram = { + parser: _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.p, + db: _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d, + renderer, + styles: _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.s, + init: (cnf) => { + if (!cnf.state) { + cnf.state = {}; + } + cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute; + _styles_9c745c82_js__WEBPACK_IMPORTED_MODULE_7__.d.clear(); + } +}; + + + +/***/ }), + +/***/ 52244: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ D: () => (/* binding */ DEFAULT_STATE_TYPE), +/* harmony export */ S: () => (/* binding */ STMT_RELATION), +/* harmony export */ a: () => (/* binding */ DIVIDER_TYPE), +/* harmony export */ b: () => (/* binding */ STMT_STATE), +/* harmony export */ c: () => (/* binding */ DEFAULT_NESTED_DOC_DIR), +/* harmony export */ d: () => (/* binding */ db), +/* harmony export */ p: () => (/* binding */ parser$1), +/* harmony export */ s: () => (/* binding */ styles) +/* harmony export */ }); +/* harmony import */ var _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(56363); + +var parser = function() { + var o = function(k, v, o2, l) { + for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) + ; + return o2; + }, $V0 = [1, 2], $V1 = [1, 3], $V2 = [1, 4], $V3 = [2, 4], $V4 = [1, 9], $V5 = [1, 11], $V6 = [1, 15], $V7 = [1, 16], $V8 = [1, 17], $V9 = [1, 18], $Va = [1, 30], $Vb = [1, 19], $Vc = [1, 20], $Vd = [1, 21], $Ve = [1, 22], $Vf = [1, 23], $Vg = [1, 25], $Vh = [1, 26], $Vi = [1, 27], $Vj = [1, 28], $Vk = [1, 29], $Vl = [1, 32], $Vm = [1, 33], $Vn = [1, 34], $Vo = [1, 35], $Vp = [1, 31], $Vq = [1, 4, 5, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $Vr = [1, 4, 5, 13, 14, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $Vs = [4, 5, 15, 16, 18, 20, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50]; + var parser2 = { + trace: function trace() { + }, + yy: {}, + symbols_: { "error": 2, "start": 3, "SPACE": 4, "NL": 5, "SD": 6, "document": 7, "line": 8, "statement": 9, "classDefStatement": 10, "cssClassStatement": 11, "idStatement": 12, "DESCR": 13, "-->": 14, "HIDE_EMPTY": 15, "scale": 16, "WIDTH": 17, "COMPOSIT_STATE": 18, "STRUCT_START": 19, "STRUCT_STOP": 20, "STATE_DESCR": 21, "AS": 22, "ID": 23, "FORK": 24, "JOIN": 25, "CHOICE": 26, "CONCURRENT": 27, "note": 28, "notePosition": 29, "NOTE_TEXT": 30, "direction": 31, "acc_title": 32, "acc_title_value": 33, "acc_descr": 34, "acc_descr_value": 35, "acc_descr_multiline_value": 36, "classDef": 37, "CLASSDEF_ID": 38, "CLASSDEF_STYLEOPTS": 39, "DEFAULT": 40, "class": 41, "CLASSENTITY_IDS": 42, "STYLECLASS": 43, "direction_tb": 44, "direction_bt": 45, "direction_rl": 46, "direction_lr": 47, "eol": 48, ";": 49, "EDGE_STATE": 50, "STYLE_SEPARATOR": 51, "left_of": 52, "right_of": 53, "$accept": 0, "$end": 1 }, + terminals_: { 2: "error", 4: "SPACE", 5: "NL", 6: "SD", 13: "DESCR", 14: "-->", 15: "HIDE_EMPTY", 16: "scale", 17: "WIDTH", 18: "COMPOSIT_STATE", 19: "STRUCT_START", 20: "STRUCT_STOP", 21: "STATE_DESCR", 22: "AS", 23: "ID", 24: "FORK", 25: "JOIN", 26: "CHOICE", 27: "CONCURRENT", 28: "note", 30: "NOTE_TEXT", 32: "acc_title", 33: "acc_title_value", 34: "acc_descr", 35: "acc_descr_value", 36: "acc_descr_multiline_value", 37: "classDef", 38: "CLASSDEF_ID", 39: "CLASSDEF_STYLEOPTS", 40: "DEFAULT", 41: "class", 42: "CLASSENTITY_IDS", 43: "STYLECLASS", 44: "direction_tb", 45: "direction_bt", 46: "direction_rl", 47: "direction_lr", 49: ";", 50: "EDGE_STATE", 51: "STYLE_SEPARATOR", 52: "left_of", 53: "right_of" }, + productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [8, 1], [8, 1], [9, 1], [9, 1], [9, 1], [9, 2], [9, 3], [9, 4], [9, 1], [9, 2], [9, 1], [9, 4], [9, 3], [9, 6], [9, 1], [9, 1], [9, 1], [9, 1], [9, 4], [9, 4], [9, 1], [9, 2], [9, 2], [9, 1], [10, 3], [10, 3], [11, 3], [31, 1], [31, 1], [31, 1], [31, 1], [48, 1], [48, 1], [12, 1], [12, 1], [12, 3], [12, 3], [29, 1], [29, 1]], + performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { + var $0 = $$.length - 1; + switch (yystate) { + case 3: + yy.setRootDoc($$[$0]); + return $$[$0]; + case 4: + this.$ = []; + break; + case 5: + if ($$[$0] != "nl") { + $$[$0 - 1].push($$[$0]); + this.$ = $$[$0 - 1]; + } + break; + case 6: + case 7: + this.$ = $$[$0]; + break; + case 8: + this.$ = "nl"; + break; + case 11: + this.$ = $$[$0]; + break; + case 12: + const stateStmt = $$[$0 - 1]; + stateStmt.description = yy.trimColon($$[$0]); + this.$ = stateStmt; + break; + case 13: + this.$ = { stmt: "relation", state1: $$[$0 - 2], state2: $$[$0] }; + break; + case 14: + const relDescription = yy.trimColon($$[$0]); + this.$ = { stmt: "relation", state1: $$[$0 - 3], state2: $$[$0 - 1], description: relDescription }; + break; + case 18: + this.$ = { stmt: "state", id: $$[$0 - 3], type: "default", description: "", doc: $$[$0 - 1] }; + break; + case 19: + var id = $$[$0]; + var description = $$[$0 - 2].trim(); + if ($$[$0].match(":")) { + var parts = $$[$0].split(":"); + id = parts[0]; + description = [description, parts[1]]; + } + this.$ = { stmt: "state", id, type: "default", description }; + break; + case 20: + this.$ = { stmt: "state", id: $$[$0 - 3], type: "default", description: $$[$0 - 5], doc: $$[$0 - 1] }; + break; + case 21: + this.$ = { stmt: "state", id: $$[$0], type: "fork" }; + break; + case 22: + this.$ = { stmt: "state", id: $$[$0], type: "join" }; + break; + case 23: + this.$ = { stmt: "state", id: $$[$0], type: "choice" }; + break; + case 24: + this.$ = { stmt: "state", id: yy.getDividerId(), type: "divider" }; + break; + case 25: + this.$ = { stmt: "state", id: $$[$0 - 1].trim(), note: { position: $$[$0 - 2].trim(), text: $$[$0].trim() } }; + break; + case 28: + this.$ = $$[$0].trim(); + yy.setAccTitle(this.$); + break; + case 29: + case 30: + this.$ = $$[$0].trim(); + yy.setAccDescription(this.$); + break; + case 31: + case 32: + this.$ = { stmt: "classDef", id: $$[$0 - 1].trim(), classes: $$[$0].trim() }; + break; + case 33: + this.$ = { stmt: "applyClass", id: $$[$0 - 1].trim(), styleClass: $$[$0].trim() }; + break; + case 34: + yy.setDirection("TB"); + this.$ = { stmt: "dir", value: "TB" }; + break; + case 35: + yy.setDirection("BT"); + this.$ = { stmt: "dir", value: "BT" }; + break; + case 36: + yy.setDirection("RL"); + this.$ = { stmt: "dir", value: "RL" }; + break; + case 37: + yy.setDirection("LR"); + this.$ = { stmt: "dir", value: "LR" }; + break; + case 40: + case 41: + this.$ = { stmt: "state", id: $$[$0].trim(), type: "default", description: "" }; + break; + case 42: + this.$ = { stmt: "state", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: "default", description: "" }; + break; + case 43: + this.$ = { stmt: "state", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: "default", description: "" }; + break; + } + }, + table: [{ 3: 1, 4: $V0, 5: $V1, 6: $V2 }, { 1: [3] }, { 3: 5, 4: $V0, 5: $V1, 6: $V2 }, { 3: 6, 4: $V0, 5: $V1, 6: $V2 }, o([1, 4, 5, 15, 16, 18, 21, 23, 24, 25, 26, 27, 28, 32, 34, 36, 37, 41, 44, 45, 46, 47, 50], $V3, { 7: 7 }), { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3], 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 5]), { 9: 36, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 7]), o($Vq, [2, 8]), o($Vq, [2, 9]), o($Vq, [2, 10]), o($Vq, [2, 11], { 13: [1, 37], 14: [1, 38] }), o($Vq, [2, 15]), { 17: [1, 39] }, o($Vq, [2, 17], { 19: [1, 40] }), { 22: [1, 41] }, o($Vq, [2, 21]), o($Vq, [2, 22]), o($Vq, [2, 23]), o($Vq, [2, 24]), { 29: 42, 30: [1, 43], 52: [1, 44], 53: [1, 45] }, o($Vq, [2, 27]), { 33: [1, 46] }, { 35: [1, 47] }, o($Vq, [2, 30]), { 38: [1, 48], 40: [1, 49] }, { 42: [1, 50] }, o($Vr, [2, 40], { 51: [1, 51] }), o($Vr, [2, 41], { 51: [1, 52] }), o($Vq, [2, 34]), o($Vq, [2, 35]), o($Vq, [2, 36]), o($Vq, [2, 37]), o($Vq, [2, 6]), o($Vq, [2, 12]), { 12: 53, 23: $Va, 50: $Vp }, o($Vq, [2, 16]), o($Vs, $V3, { 7: 54 }), { 23: [1, 55] }, { 23: [1, 56] }, { 22: [1, 57] }, { 23: [2, 44] }, { 23: [2, 45] }, o($Vq, [2, 28]), o($Vq, [2, 29]), { 39: [1, 58] }, { 39: [1, 59] }, { 43: [1, 60] }, { 23: [1, 61] }, { 23: [1, 62] }, o($Vq, [2, 13], { 13: [1, 63] }), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 20: [1, 64], 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 19], { 19: [1, 65] }), { 30: [1, 66] }, { 23: [1, 67] }, o($Vq, [2, 31]), o($Vq, [2, 32]), o($Vq, [2, 33]), o($Vr, [2, 42]), o($Vr, [2, 43]), o($Vq, [2, 14]), o($Vq, [2, 18]), o($Vs, $V3, { 7: 68 }), o($Vq, [2, 25]), o($Vq, [2, 26]), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 15: $V6, 16: $V7, 18: $V8, 20: [1, 69], 21: $V9, 23: $Va, 24: $Vb, 25: $Vc, 26: $Vd, 27: $Ve, 28: $Vf, 31: 24, 32: $Vg, 34: $Vh, 36: $Vi, 37: $Vj, 41: $Vk, 44: $Vl, 45: $Vm, 46: $Vn, 47: $Vo, 50: $Vp }, o($Vq, [2, 20])], + defaultActions: { 5: [2, 1], 6: [2, 2], 44: [2, 44], 45: [2, 45] }, + parseError: function parseError(str, hash) { + if (hash.recoverable) { + this.trace(str); + } else { + var error = new Error(str); + error.hash = hash; + throw error; + } + }, + parse: function parse(input) { + var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1; + var args = lstack.slice.call(arguments, 1); + var lexer2 = Object.create(this.lexer); + var sharedState = { yy: {} }; + for (var k in this.yy) { + if (Object.prototype.hasOwnProperty.call(this.yy, k)) { + sharedState.yy[k] = this.yy[k]; + } + } + lexer2.setInput(input, sharedState.yy); + sharedState.yy.lexer = lexer2; + sharedState.yy.parser = this; + if (typeof lexer2.yylloc == "undefined") { + lexer2.yylloc = {}; + } + var yyloc = lexer2.yylloc; + lstack.push(yyloc); + var ranges = lexer2.options && lexer2.options.ranges; + if (typeof sharedState.yy.parseError === "function") { + this.parseError = sharedState.yy.parseError; + } else { + this.parseError = Object.getPrototypeOf(this).parseError; + } + function lex() { + var token; + token = tstack.pop() || lexer2.lex() || EOF; + if (typeof token !== "number") { + if (token instanceof Array) { + tstack = token; + token = tstack.pop(); + } + token = self.symbols_[token] || token; + } + return token; + } + var symbol, state, action, r, yyval = {}, p, len, newState, expected; + while (true) { + state = stack[stack.length - 1]; + if (this.defaultActions[state]) { + action = this.defaultActions[state]; + } else { + if (symbol === null || typeof symbol == "undefined") { + symbol = lex(); + } + action = table[state] && table[state][symbol]; + } + if (typeof action === "undefined" || !action.length || !action[0]) { + var errStr = ""; + expected = []; + for (p in table[state]) { + if (this.terminals_[p] && p > TERROR) { + expected.push("'" + this.terminals_[p] + "'"); + } + } + if (lexer2.showPosition) { + errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; + } else { + errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); + } + this.parseError(errStr, { + text: lexer2.match, + token: this.terminals_[symbol] || symbol, + line: lexer2.yylineno, + loc: yyloc, + expected + }); + } + if (action[0] instanceof Array && action.length > 1) { + throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); + } + switch (action[0]) { + case 1: + stack.push(symbol); + vstack.push(lexer2.yytext); + lstack.push(lexer2.yylloc); + stack.push(action[1]); + symbol = null; + { + yyleng = lexer2.yyleng; + yytext = lexer2.yytext; + yylineno = lexer2.yylineno; + yyloc = lexer2.yylloc; + } + break; + case 2: + len = this.productions_[action[1]][1]; + yyval.$ = vstack[vstack.length - len]; + yyval._$ = { + first_line: lstack[lstack.length - (len || 1)].first_line, + last_line: lstack[lstack.length - 1].last_line, + first_column: lstack[lstack.length - (len || 1)].first_column, + last_column: lstack[lstack.length - 1].last_column + }; + if (ranges) { + yyval._$.range = [ + lstack[lstack.length - (len || 1)].range[0], + lstack[lstack.length - 1].range[1] + ]; + } + r = this.performAction.apply(yyval, [ + yytext, + yyleng, + yylineno, + sharedState.yy, + action[1], + vstack, + lstack + ].concat(args)); + if (typeof r !== "undefined") { + return r; + } + if (len) { + stack = stack.slice(0, -1 * len * 2); + vstack = vstack.slice(0, -1 * len); + lstack = lstack.slice(0, -1 * len); + } + stack.push(this.productions_[action[1]][0]); + vstack.push(yyval.$); + lstack.push(yyval._$); + newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; + stack.push(newState); + break; + case 3: + return true; + } + } + return true; + } + }; + var lexer = function() { + var lexer2 = { + EOF: 1, + parseError: function parseError(str, hash) { + if (this.yy.parser) { + this.yy.parser.parseError(str, hash); + } else { + throw new Error(str); + } + }, + // resets the lexer, sets new input + setInput: function(input, yy) { + this.yy = yy || this.yy || {}; + this._input = input; + this._more = this._backtrack = this.done = false; + this.yylineno = this.yyleng = 0; + this.yytext = this.matched = this.match = ""; + this.conditionStack = ["INITIAL"]; + this.yylloc = { + first_line: 1, + first_column: 0, + last_line: 1, + last_column: 0 + }; + if (this.options.ranges) { + this.yylloc.range = [0, 0]; + } + this.offset = 0; + return this; + }, + // consumes and returns one char from the input + input: function() { + var ch = this._input[0]; + this.yytext += ch; + this.yyleng++; + this.offset++; + this.match += ch; + this.matched += ch; + var lines = ch.match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno++; + this.yylloc.last_line++; + } else { + this.yylloc.last_column++; + } + if (this.options.ranges) { + this.yylloc.range[1]++; + } + this._input = this._input.slice(1); + return ch; + }, + // unshifts one char (or a string) into the input + unput: function(ch) { + var len = ch.length; + var lines = ch.split(/(?:\r\n?|\n)/g); + this._input = ch + this._input; + this.yytext = this.yytext.substr(0, this.yytext.length - len); + this.offset -= len; + var oldLines = this.match.split(/(?:\r\n?|\n)/g); + this.match = this.match.substr(0, this.match.length - 1); + this.matched = this.matched.substr(0, this.matched.length - 1); + if (lines.length - 1) { + this.yylineno -= lines.length - 1; + } + var r = this.yylloc.range; + this.yylloc = { + first_line: this.yylloc.first_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.first_column, + last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len + }; + if (this.options.ranges) { + this.yylloc.range = [r[0], r[0] + this.yyleng - len]; + } + this.yyleng = this.yytext.length; + return this; + }, + // When called from action, caches matched text and appends it on next action + more: function() { + this._more = true; + return this; + }, + // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead. + reject: function() { + if (this.options.backtrack_lexer) { + this._backtrack = true; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + return this; + }, + // retain first n characters of the match + less: function(n) { + this.unput(this.match.slice(n)); + }, + // displays already matched input, i.e. for error messages + pastInput: function() { + var past = this.matched.substr(0, this.matched.length - this.match.length); + return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, ""); + }, + // displays upcoming input, i.e. for error messages + upcomingInput: function() { + var next = this.match; + if (next.length < 20) { + next += this._input.substr(0, 20 - next.length); + } + return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, ""); + }, + // displays the character position where the lexing error occurred, i.e. for error messages + showPosition: function() { + var pre = this.pastInput(); + var c = new Array(pre.length + 1).join("-"); + return pre + this.upcomingInput() + "\n" + c + "^"; + }, + // test the lexed token: return FALSE when not a match, otherwise return token + test_match: function(match, indexed_rule) { + var token, lines, backup; + if (this.options.backtrack_lexer) { + backup = { + yylineno: this.yylineno, + yylloc: { + first_line: this.yylloc.first_line, + last_line: this.last_line, + first_column: this.yylloc.first_column, + last_column: this.yylloc.last_column + }, + yytext: this.yytext, + match: this.match, + matches: this.matches, + matched: this.matched, + yyleng: this.yyleng, + offset: this.offset, + _more: this._more, + _input: this._input, + yy: this.yy, + conditionStack: this.conditionStack.slice(0), + done: this.done + }; + if (this.options.ranges) { + backup.yylloc.range = this.yylloc.range.slice(0); + } + } + lines = match[0].match(/(?:\r\n?|\n).*/g); + if (lines) { + this.yylineno += lines.length; + } + this.yylloc = { + first_line: this.yylloc.last_line, + last_line: this.yylineno + 1, + first_column: this.yylloc.last_column, + last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length + }; + this.yytext += match[0]; + this.match += match[0]; + this.matches = match; + this.yyleng = this.yytext.length; + if (this.options.ranges) { + this.yylloc.range = [this.offset, this.offset += this.yyleng]; + } + this._more = false; + this._backtrack = false; + this._input = this._input.slice(match[0].length); + this.matched += match[0]; + token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]); + if (this.done && this._input) { + this.done = false; + } + if (token) { + return token; + } else if (this._backtrack) { + for (var k in backup) { + this[k] = backup[k]; + } + return false; + } + return false; + }, + // return next match in input + next: function() { + if (this.done) { + return this.EOF; + } + if (!this._input) { + this.done = true; + } + var token, match, tempMatch, index; + if (!this._more) { + this.yytext = ""; + this.match = ""; + } + var rules = this._currentRules(); + for (var i = 0; i < rules.length; i++) { + tempMatch = this._input.match(this.rules[rules[i]]); + if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { + match = tempMatch; + index = i; + if (this.options.backtrack_lexer) { + token = this.test_match(tempMatch, rules[i]); + if (token !== false) { + return token; + } else if (this._backtrack) { + match = false; + continue; + } else { + return false; + } + } else if (!this.options.flex) { + break; + } + } + } + if (match) { + token = this.test_match(match, rules[index]); + if (token !== false) { + return token; + } + return false; + } + if (this._input === "") { + return this.EOF; + } else { + return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), { + text: "", + token: null, + line: this.yylineno + }); + } + }, + // return next match that has a token + lex: function lex() { + var r = this.next(); + if (r) { + return r; + } else { + return this.lex(); + } + }, + // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack) + begin: function begin(condition) { + this.conditionStack.push(condition); + }, + // pop the previously active lexer condition state off the condition stack + popState: function popState() { + var n = this.conditionStack.length - 1; + if (n > 0) { + return this.conditionStack.pop(); + } else { + return this.conditionStack[0]; + } + }, + // produce the lexer rule set which is active for the currently active lexer condition state + _currentRules: function _currentRules() { + if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) { + return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; + } else { + return this.conditions["INITIAL"].rules; + } + }, + // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available + topState: function topState(n) { + n = this.conditionStack.length - 1 - Math.abs(n || 0); + if (n >= 0) { + return this.conditionStack[n]; + } else { + return "INITIAL"; + } + }, + // alias for begin(condition) + pushState: function pushState(condition) { + this.begin(condition); + }, + // return the number of states currently on the stack + stateStackSize: function stateStackSize() { + return this.conditionStack.length; + }, + options: { "case-insensitive": true }, + performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { + switch ($avoiding_name_collisions) { + case 0: + return 40; + case 1: + return 44; + case 2: + return 45; + case 3: + return 46; + case 4: + return 47; + case 5: + break; + case 6: + break; + case 7: + return 5; + case 8: + break; + case 9: + break; + case 10: + break; + case 11: + break; + case 12: + this.pushState("SCALE"); + return 16; + case 13: + return 17; + case 14: + this.popState(); + break; + case 15: + this.begin("acc_title"); + return 32; + case 16: + this.popState(); + return "acc_title_value"; + case 17: + this.begin("acc_descr"); + return 34; + case 18: + this.popState(); + return "acc_descr_value"; + case 19: + this.begin("acc_descr_multiline"); + break; + case 20: + this.popState(); + break; + case 21: + return "acc_descr_multiline_value"; + case 22: + this.pushState("CLASSDEF"); + return 37; + case 23: + this.popState(); + this.pushState("CLASSDEFID"); + return "DEFAULT_CLASSDEF_ID"; + case 24: + this.popState(); + this.pushState("CLASSDEFID"); + return 38; + case 25: + this.popState(); + return 39; + case 26: + this.pushState("CLASS"); + return 41; + case 27: + this.popState(); + this.pushState("CLASS_STYLE"); + return 42; + case 28: + this.popState(); + return 43; + case 29: + this.pushState("SCALE"); + return 16; + case 30: + return 17; + case 31: + this.popState(); + break; + case 32: + this.pushState("STATE"); + break; + case 33: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 24; + case 34: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 25; + case 35: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -10).trim(); + return 26; + case 36: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 24; + case 37: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 25; + case 38: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -10).trim(); + return 26; + case 39: + return 44; + case 40: + return 45; + case 41: + return 46; + case 42: + return 47; + case 43: + this.pushState("STATE_STRING"); + break; + case 44: + this.pushState("STATE_ID"); + return "AS"; + case 45: + this.popState(); + return "ID"; + case 46: + this.popState(); + break; + case 47: + return "STATE_DESCR"; + case 48: + return 18; + case 49: + this.popState(); + break; + case 50: + this.popState(); + this.pushState("struct"); + return 19; + case 51: + break; + case 52: + this.popState(); + return 20; + case 53: + break; + case 54: + this.begin("NOTE"); + return 28; + case 55: + this.popState(); + this.pushState("NOTE_ID"); + return 52; + case 56: + this.popState(); + this.pushState("NOTE_ID"); + return 53; + case 57: + this.popState(); + this.pushState("FLOATING_NOTE"); + break; + case 58: + this.popState(); + this.pushState("FLOATING_NOTE_ID"); + return "AS"; + case 59: + break; + case 60: + return "NOTE_TEXT"; + case 61: + this.popState(); + return "ID"; + case 62: + this.popState(); + this.pushState("NOTE_TEXT"); + return 23; + case 63: + this.popState(); + yy_.yytext = yy_.yytext.substr(2).trim(); + return 30; + case 64: + this.popState(); + yy_.yytext = yy_.yytext.slice(0, -8).trim(); + return 30; + case 65: + return 6; + case 66: + return 6; + case 67: + return 15; + case 68: + return 50; + case 69: + return 23; + case 70: + yy_.yytext = yy_.yytext.trim(); + return 13; + case 71: + return 14; + case 72: + return 27; + case 73: + return 51; + case 74: + return 5; + case 75: + return "INVALID"; + } + }, + rules: [/^(?:default\b)/i, /^(?:.*direction\s+TB[^\n]*)/i, /^(?:.*direction\s+BT[^\n]*)/i, /^(?:.*direction\s+RL[^\n]*)/i, /^(?:.*direction\s+LR[^\n]*)/i, /^(?:%%(?!\{)[^\n]*)/i, /^(?:[^\}]%%[^\n]*)/i, /^(?:[\n]+)/i, /^(?:[\s]+)/i, /^(?:((?!\n)\s)+)/i, /^(?:#[^\n]*)/i, /^(?:%[^\n]*)/i, /^(?:scale\s+)/i, /^(?:\d+)/i, /^(?:\s+width\b)/i, /^(?:accTitle\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*:\s*)/i, /^(?:(?!\n||)*[^\n]*)/i, /^(?:accDescr\s*\{\s*)/i, /^(?:[\}])/i, /^(?:[^\}]*)/i, /^(?:classDef\s+)/i, /^(?:DEFAULT\s+)/i, /^(?:\w+\s+)/i, /^(?:[^\n]*)/i, /^(?:class\s+)/i, /^(?:(\w+)+((,\s*\w+)*))/i, /^(?:[^\n]*)/i, /^(?:scale\s+)/i, /^(?:\d+)/i, /^(?:\s+width\b)/i, /^(?:state\s+)/i, /^(?:.*<<fork>>)/i, /^(?:.*<<join>>)/i, /^(?:.*<<choice>>)/i, /^(?:.*\[\[fork\]\])/i, /^(?:.*\[\[join\]\])/i, /^(?:.*\[\[choice\]\])/i, /^(?:.*direction\s+TB[^\n]*)/i, /^(?:.*direction\s+BT[^\n]*)/i, /^(?:.*direction\s+RL[^\n]*)/i, /^(?:.*direction\s+LR[^\n]*)/i, /^(?:["])/i, /^(?:\s*as\s+)/i, /^(?:[^\n\{]*)/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[^\n\s\{]+)/i, /^(?:\n)/i, /^(?:\{)/i, /^(?:%%(?!\{)[^\n]*)/i, /^(?:\})/i, /^(?:[\n])/i, /^(?:note\s+)/i, /^(?:left of\b)/i, /^(?:right of\b)/i, /^(?:")/i, /^(?:\s*as\s*)/i, /^(?:["])/i, /^(?:[^"]*)/i, /^(?:[^\n]*)/i, /^(?:\s*[^:\n\s\-]+)/i, /^(?:\s*:[^:\n;]+)/i, /^(?:[\s\S]*?end note\b)/i, /^(?:stateDiagram\s+)/i, /^(?:stateDiagram-v2\s+)/i, /^(?:hide empty description\b)/i, /^(?:\[\*\])/i, /^(?:[^:\n\s\-\{]+)/i, /^(?:\s*:[^:\n;]+)/i, /^(?:-->)/i, /^(?:--)/i, /^(?::::)/i, /^(?:$)/i, /^(?:.)/i], + conditions: { "LINE": { "rules": [9, 10], "inclusive": false }, "struct": { "rules": [9, 10, 22, 26, 32, 39, 40, 41, 42, 51, 52, 53, 54, 68, 69, 70, 71, 72], "inclusive": false }, "FLOATING_NOTE_ID": { "rules": [61], "inclusive": false }, "FLOATING_NOTE": { "rules": [58, 59, 60], "inclusive": false }, "NOTE_TEXT": { "rules": [63, 64], "inclusive": false }, "NOTE_ID": { "rules": [62], "inclusive": false }, "NOTE": { "rules": [55, 56, 57], "inclusive": false }, "CLASS_STYLE": { "rules": [28], "inclusive": false }, "CLASS": { "rules": [27], "inclusive": false }, "CLASSDEFID": { "rules": [25], "inclusive": false }, "CLASSDEF": { "rules": [23, 24], "inclusive": false }, "acc_descr_multiline": { "rules": [20, 21], "inclusive": false }, "acc_descr": { "rules": [18], "inclusive": false }, "acc_title": { "rules": [16], "inclusive": false }, "SCALE": { "rules": [13, 14, 30, 31], "inclusive": false }, "ALIAS": { "rules": [], "inclusive": false }, "STATE_ID": { "rules": [45], "inclusive": false }, "STATE_STRING": { "rules": [46, 47], "inclusive": false }, "FORK_STATE": { "rules": [], "inclusive": false }, "STATE": { "rules": [9, 10, 33, 34, 35, 36, 37, 38, 43, 44, 48, 49, 50], "inclusive": false }, "ID": { "rules": [9, 10], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 17, 19, 22, 26, 29, 32, 50, 54, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75], "inclusive": true } } + }; + return lexer2; + }(); + parser2.lexer = lexer; + function Parser() { + this.yy = {}; + } + Parser.prototype = parser2; + parser2.Parser = Parser; + return new Parser(); +}(); +parser.parser = parser; +const parser$1 = parser; +const DEFAULT_DIAGRAM_DIRECTION = "LR"; +const DEFAULT_NESTED_DOC_DIR = "TB"; +const STMT_STATE = "state"; +const STMT_RELATION = "relation"; +const STMT_CLASSDEF = "classDef"; +const STMT_APPLYCLASS = "applyClass"; +const DEFAULT_STATE_TYPE = "default"; +const DIVIDER_TYPE = "divider"; +const START_NODE = "[*]"; +const START_TYPE = "start"; +const END_NODE = START_NODE; +const END_TYPE = "end"; +const COLOR_KEYWORD = "color"; +const FILL_KEYWORD = "fill"; +const BG_FILL = "bgFill"; +const STYLECLASS_SEP = ","; +function newClassesList() { + return {}; +} +let direction = DEFAULT_DIAGRAM_DIRECTION; +let rootDoc = []; +let classes = newClassesList(); +const newDoc = () => { + return { + relations: [], + states: {}, + documents: {} + }; +}; +let documents = { + root: newDoc() +}; +let currentDocument = documents.root; +let startEndCount = 0; +let dividerCnt = 0; +const lineType = { + LINE: 0, + DOTTED_LINE: 1 +}; +const relationType = { + AGGREGATION: 0, + EXTENSION: 1, + COMPOSITION: 2, + DEPENDENCY: 3 +}; +const clone = (o) => JSON.parse(JSON.stringify(o)); +const setRootDoc = (o) => { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting root doc", o); + rootDoc = o; +}; +const getRootDoc = () => rootDoc; +const docTranslator = (parent, node, first) => { + if (node.stmt === STMT_RELATION) { + docTranslator(parent, node.state1, true); + docTranslator(parent, node.state2, false); + } else { + if (node.stmt === STMT_STATE) { + if (node.id === "[*]") { + node.id = first ? parent.id + "_start" : parent.id + "_end"; + node.start = first; + } else { + node.id = node.id.trim(); + } + } + if (node.doc) { + const doc = []; + let currentDoc = []; + let i; + for (i = 0; i < node.doc.length; i++) { + if (node.doc[i].type === DIVIDER_TYPE) { + const newNode = clone(node.doc[i]); + newNode.doc = clone(currentDoc); + doc.push(newNode); + currentDoc = []; + } else { + currentDoc.push(node.doc[i]); + } + } + if (doc.length > 0 && currentDoc.length > 0) { + const newNode = { + stmt: STMT_STATE, + id: (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.G)(), + type: "divider", + doc: clone(currentDoc) + }; + doc.push(clone(newNode)); + node.doc = doc; + } + node.doc.forEach((docNode) => docTranslator(node, docNode, true)); + } + } +}; +const getRootDocV2 = () => { + docTranslator({ id: "root" }, { id: "root", doc: rootDoc }, true); + return { id: "root", doc: rootDoc }; +}; +const extract = (_doc) => { + let doc; + if (_doc.doc) { + doc = _doc.doc; + } else { + doc = _doc; + } + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info(doc); + clear(true); + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Extract", doc); + doc.forEach((item) => { + switch (item.stmt) { + case STMT_STATE: + addState( + item.id.trim(), + item.type, + item.doc, + item.description, + item.note, + item.classes, + item.styles, + item.textStyles + ); + break; + case STMT_RELATION: + addRelation(item.state1, item.state2, item.description); + break; + case STMT_CLASSDEF: + addStyleClass(item.id.trim(), item.classes); + break; + case STMT_APPLYCLASS: + setCssClass(item.id.trim(), item.styleClass); + break; + } + }); +}; +const addState = function(id, type = DEFAULT_STATE_TYPE, doc = null, descr = null, note = null, classes2 = null, styles2 = null, textStyles = null) { + const trimmedId = id == null ? void 0 : id.trim(); + if (currentDocument.states[trimmedId] === void 0) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Adding state ", trimmedId, descr); + currentDocument.states[trimmedId] = { + id: trimmedId, + descriptions: [], + type, + doc, + note, + classes: [], + styles: [], + textStyles: [] + }; + } else { + if (!currentDocument.states[trimmedId].doc) { + currentDocument.states[trimmedId].doc = doc; + } + if (!currentDocument.states[trimmedId].type) { + currentDocument.states[trimmedId].type = type; + } + } + if (descr) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state description", trimmedId, descr); + if (typeof descr === "string") { + addDescription(trimmedId, descr.trim()); + } + if (typeof descr === "object") { + descr.forEach((des) => addDescription(trimmedId, des.trim())); + } + } + if (note) { + currentDocument.states[trimmedId].note = note; + currentDocument.states[trimmedId].note.text = _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText( + currentDocument.states[trimmedId].note.text, + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)() + ); + } + if (classes2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state classes", trimmedId, classes2); + const classesList = typeof classes2 === "string" ? [classes2] : classes2; + classesList.forEach((klass) => setCssClass(trimmedId, klass.trim())); + } + if (styles2) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state styles", trimmedId, styles2); + const stylesList = typeof styles2 === "string" ? [styles2] : styles2; + stylesList.forEach((style) => setStyle(trimmedId, style.trim())); + } + if (textStyles) { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Setting state styles", trimmedId, styles2); + const textStylesList = typeof textStyles === "string" ? [textStyles] : textStyles; + textStylesList.forEach((textStyle) => setTextStyle(trimmedId, textStyle.trim())); + } +}; +const clear = function(saveCommon) { + documents = { + root: newDoc() + }; + currentDocument = documents.root; + startEndCount = 0; + classes = newClassesList(); + if (!saveCommon) { + (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.t)(); + } +}; +const getState = function(id) { + return currentDocument.states[id]; +}; +const getStates = function() { + return currentDocument.states; +}; +const logDocuments = function() { + _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.l.info("Documents = ", documents); +}; +const getRelations = function() { + return currentDocument.relations; +}; +function startIdIfNeeded(id = "") { + let fixedId = id; + if (id === START_NODE) { + startEndCount++; + fixedId = `${START_TYPE}${startEndCount}`; + } + return fixedId; +} +function startTypeIfNeeded(id = "", type = DEFAULT_STATE_TYPE) { + return id === START_NODE ? START_TYPE : type; +} +function endIdIfNeeded(id = "") { + let fixedId = id; + if (id === END_NODE) { + startEndCount++; + fixedId = `${END_TYPE}${startEndCount}`; + } + return fixedId; +} +function endTypeIfNeeded(id = "", type = DEFAULT_STATE_TYPE) { + return id === END_NODE ? END_TYPE : type; +} +function addRelationObjs(item1, item2, relationTitle) { + let id1 = startIdIfNeeded(item1.id.trim()); + let type1 = startTypeIfNeeded(item1.id.trim(), item1.type); + let id2 = startIdIfNeeded(item2.id.trim()); + let type2 = startTypeIfNeeded(item2.id.trim(), item2.type); + addState( + id1, + type1, + item1.doc, + item1.description, + item1.note, + item1.classes, + item1.styles, + item1.textStyles + ); + addState( + id2, + type2, + item2.doc, + item2.description, + item2.note, + item2.classes, + item2.styles, + item2.textStyles + ); + currentDocument.relations.push({ + id1, + id2, + relationTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(relationTitle, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)()) + }); +} +const addRelation = function(item1, item2, title) { + if (typeof item1 === "object") { + addRelationObjs(item1, item2, title); + } else { + const id1 = startIdIfNeeded(item1.trim()); + const type1 = startTypeIfNeeded(item1); + const id2 = endIdIfNeeded(item2.trim()); + const type2 = endTypeIfNeeded(item2); + addState(id1, type1); + addState(id2, type2); + currentDocument.relations.push({ + id1, + id2, + title: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(title, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)()) + }); + } +}; +const addDescription = function(id, descr) { + const theState = currentDocument.states[id]; + const _descr = descr.startsWith(":") ? descr.replace(":", "").trim() : descr; + theState.descriptions.push(_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.e.sanitizeText(_descr, (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)())); +}; +const cleanupLabel = function(label) { + if (label.substring(0, 1) === ":") { + return label.substr(2).trim(); + } else { + return label.trim(); + } +}; +const getDividerId = () => { + dividerCnt++; + return "divider-id-" + dividerCnt; +}; +const addStyleClass = function(id, styleAttributes = "") { + if (classes[id] === void 0) { + classes[id] = { id, styles: [], textStyles: [] }; + } + const foundClass = classes[id]; + if (styleAttributes !== void 0 && styleAttributes !== null) { + styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => { + const fixedAttrib = attrib.replace(/([^;]*);/, "$1").trim(); + if (attrib.match(COLOR_KEYWORD)) { + const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL); + const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD); + foundClass.textStyles.push(newStyle2); + } + foundClass.styles.push(fixedAttrib); + }); + } +}; +const getClasses = function() { + return classes; +}; +const setCssClass = function(itemIds, cssClassName) { + itemIds.split(",").forEach(function(id) { + let foundState = getState(id); + if (foundState === void 0) { + const trimmedId = id.trim(); + addState(trimmedId); + foundState = getState(trimmedId); + } + foundState.classes.push(cssClassName); + }); +}; +const setStyle = function(itemId, styleText) { + const item = getState(itemId); + if (item !== void 0) { + item.textStyles.push(styleText); + } +}; +const setTextStyle = function(itemId, cssClassName) { + const item = getState(itemId); + if (item !== void 0) { + item.textStyles.push(cssClassName); + } +}; +const getDirection = () => direction; +const setDirection = (dir) => { + direction = dir; +}; +const trimColon = (str) => str && str[0] === ":" ? str.substr(1).trim() : str.trim(); +const db = { + getConfig: () => (0,_mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.c)().state, + addState, + clear, + getState, + getStates, + getRelations, + getClasses, + getDirection, + addRelation, + getDividerId, + setDirection, + cleanupLabel, + lineType, + relationType, + logDocuments, + getRootDoc, + setRootDoc, + getRootDocV2, + extract, + trimColon, + getAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.g, + setAccTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.s, + getAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.a, + setAccDescription: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.b, + addStyleClass, + setCssClass, + addDescription, + setDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.q, + getDiagramTitle: _mermaid_8af3addd_js__WEBPACK_IMPORTED_MODULE_0__.r +}; +const getStyles = (options) => ` +defs #statediagram-barbEnd { + fill: ${options.transitionColor}; + stroke: ${options.transitionColor}; + } +g.stateGroup text { + fill: ${options.nodeBorder}; + stroke: none; + font-size: 10px; +} +g.stateGroup text { + fill: ${options.textColor}; + stroke: none; + font-size: 10px; + +} +g.stateGroup .state-title { + font-weight: bolder; + fill: ${options.stateLabelColor}; +} + +g.stateGroup rect { + fill: ${options.mainBkg}; + stroke: ${options.nodeBorder}; +} + +g.stateGroup line { + stroke: ${options.lineColor}; + stroke-width: 1; +} + +.transition { + stroke: ${options.transitionColor}; + stroke-width: 1; + fill: none; +} + +.stateGroup .composit { + fill: ${options.background}; + border-bottom: 1px +} + +.stateGroup .alt-composit { + fill: #e0e0e0; + border-bottom: 1px +} + +.state-note { + stroke: ${options.noteBorderColor}; + fill: ${options.noteBkgColor}; + + text { + fill: ${options.noteTextColor}; + stroke: none; + font-size: 10px; + } +} + +.stateLabel .box { + stroke: none; + stroke-width: 0; + fill: ${options.mainBkg}; + opacity: 0.5; +} + +.edgeLabel .label rect { + fill: ${options.labelBackgroundColor}; + opacity: 0.5; +} +.edgeLabel .label text { + fill: ${options.transitionLabelColor || options.tertiaryTextColor}; +} +.label div .edgeLabel { + color: ${options.transitionLabelColor || options.tertiaryTextColor}; +} + +.stateLabel text { + fill: ${options.stateLabelColor}; + font-size: 10px; + font-weight: bold; +} + +.node circle.state-start { + fill: ${options.specialStateColor}; + stroke: ${options.specialStateColor}; +} + +.node .fork-join { + fill: ${options.specialStateColor}; + stroke: ${options.specialStateColor}; +} + +.node circle.state-end { + fill: ${options.innerEndBackground}; + stroke: ${options.background}; + stroke-width: 1.5 +} +.end-state-inner { + fill: ${options.compositeBackground || options.background}; + // stroke: ${options.background}; + stroke-width: 1.5 +} + +.node rect { + fill: ${options.stateBkg || options.mainBkg}; + stroke: ${options.stateBorder || options.nodeBorder}; + stroke-width: 1px; +} +.node polygon { + fill: ${options.mainBkg}; + stroke: ${options.stateBorder || options.nodeBorder};; + stroke-width: 1px; +} +#statediagram-barbEnd { + fill: ${options.lineColor}; +} + +.statediagram-cluster rect { + fill: ${options.compositeTitleBackground}; + stroke: ${options.stateBorder || options.nodeBorder}; + stroke-width: 1px; +} + +.cluster-label, .nodeLabel { + color: ${options.stateLabelColor}; +} + +.statediagram-cluster rect.outer { + rx: 5px; + ry: 5px; +} +.statediagram-state .divider { + stroke: ${options.stateBorder || options.nodeBorder}; +} + +.statediagram-state .title-state { + rx: 5px; + ry: 5px; +} +.statediagram-cluster.statediagram-cluster .inner { + fill: ${options.compositeBackground || options.background}; +} +.statediagram-cluster.statediagram-cluster-alt .inner { + fill: ${options.altBackground ? options.altBackground : "#efefef"}; +} + +.statediagram-cluster .inner { + rx:0; + ry:0; +} + +.statediagram-state rect.basic { + rx: 5px; + ry: 5px; +} +.statediagram-state rect.divider { + stroke-dasharray: 10,10; + fill: ${options.altBackground ? options.altBackground : "#efefef"}; +} + +.note-edge { + stroke-dasharray: 5; +} + +.statediagram-note rect { + fill: ${options.noteBkgColor}; + stroke: ${options.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} +.statediagram-note rect { + fill: ${options.noteBkgColor}; + stroke: ${options.noteBorderColor}; + stroke-width: 1px; + rx: 0; + ry: 0; +} + +.statediagram-note text { + fill: ${options.noteTextColor}; +} + +.statediagram-note .nodeLabel { + color: ${options.noteTextColor}; +} +.statediagram .edgeLabel { + color: red; // ${options.noteTextColor}; +} + +#dependencyStart, #dependencyEnd { + fill: ${options.lineColor}; + stroke: ${options.lineColor}; + stroke-width: 1; +} + +.statediagramTitleText { + text-anchor: middle; + font-size: 18px; + fill: ${options.textColor}; +} +`; +const styles = getStyles; + + + +/***/ }) + +}; +; \ No newline at end of file diff --git a/assets/js/8189.25b38ba5.js b/assets/js/8189.25b38ba5.js new file mode 100644 index 000000000..dc4621776 --- /dev/null +++ b/assets/js/8189.25b38ba5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8189],{18189:(t,e,i)=>{i.d(e,{diagram:()=>T});var n=i(56363),r=i(64218),s=i(41644),a=i(45625),l=(i(27484),i(17967),i(27856),function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,3],i=[1,4],n=[1,5],r=[1,6],s=[5,6,8,9,11,13,31,32,33,34,35,36,44,62,63],a=[1,18],l=[2,7],c=[1,22],o=[1,23],h=[1,24],u=[1,25],y=[1,26],d=[1,27],p=[1,20],_=[1,28],E=[1,29],g=[62,63],R=[5,8,9,11,13,31,32,33,34,35,36,44,51,53,62,63],m=[1,47],f=[1,48],I=[1,49],b=[1,50],k=[1,51],S=[1,52],T=[1,53],N=[53,54],x=[1,64],A=[1,60],v=[1,61],q=[1,62],w=[1,63],$=[1,65],O=[1,69],C=[1,70],L=[1,67],F=[1,68],M=[5,8,9,11,13,31,32,33,34,35,36,44,62,63],D={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,requirementType:17,requirementName:18,STRUCT_START:19,requirementBody:20,ID:21,COLONSEP:22,id:23,TEXT:24,text:25,RISK:26,riskLevel:27,VERIFYMTHD:28,verifyType:29,STRUCT_STOP:30,REQUIREMENT:31,FUNCTIONAL_REQUIREMENT:32,INTERFACE_REQUIREMENT:33,PERFORMANCE_REQUIREMENT:34,PHYSICAL_REQUIREMENT:35,DESIGN_CONSTRAINT:36,LOW_RISK:37,MED_RISK:38,HIGH_RISK:39,VERIFY_ANALYSIS:40,VERIFY_DEMONSTRATION:41,VERIFY_INSPECTION:42,VERIFY_TEST:43,ELEMENT:44,elementName:45,elementBody:46,TYPE:47,type:48,DOCREF:49,ref:50,END_ARROW_L:51,relationship:52,LINE:53,END_ARROW_R:54,CONTAINS:55,COPIES:56,DERIVES:57,SATISFIES:58,VERIFIES:59,REFINES:60,TRACES:61,unqString:62,qString:63,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",19:"STRUCT_START",21:"ID",22:"COLONSEP",24:"TEXT",26:"RISK",28:"VERIFYMTHD",30:"STRUCT_STOP",31:"REQUIREMENT",32:"FUNCTIONAL_REQUIREMENT",33:"INTERFACE_REQUIREMENT",34:"PERFORMANCE_REQUIREMENT",35:"PHYSICAL_REQUIREMENT",36:"DESIGN_CONSTRAINT",37:"LOW_RISK",38:"MED_RISK",39:"HIGH_RISK",40:"VERIFY_ANALYSIS",41:"VERIFY_DEMONSTRATION",42:"VERIFY_INSPECTION",43:"VERIFY_TEST",44:"ELEMENT",47:"TYPE",49:"DOCREF",51:"END_ARROW_L",53:"LINE",54:"END_ARROW_R",55:"CONTAINS",56:"COPIES",57:"DERIVES",58:"SATISFIES",59:"VERIFIES",60:"REFINES",61:"TRACES",62:"unqString",63:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[14,5],[20,5],[20,5],[20,5],[20,5],[20,2],[20,1],[17,1],[17,1],[17,1],[17,1],[17,1],[17,1],[27,1],[27,1],[27,1],[29,1],[29,1],[29,1],[29,1],[15,5],[46,5],[46,5],[46,2],[46,1],[16,5],[16,5],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[18,1],[18,1],[23,1],[23,1],[25,1],[25,1],[45,1],[45,1],[48,1],[48,1],[50,1],[50,1]],performAction:function(t,e,i,n,r,s,a){var l=s.length-1;switch(r){case 4:this.$=s[l].trim(),n.setAccTitle(this.$);break;case 5:case 6:this.$=s[l].trim(),n.setAccDescription(this.$);break;case 7:this.$=[];break;case 13:n.addRequirement(s[l-3],s[l-4]);break;case 14:n.setNewReqId(s[l-2]);break;case 15:n.setNewReqText(s[l-2]);break;case 16:n.setNewReqRisk(s[l-2]);break;case 17:n.setNewReqVerifyMethod(s[l-2]);break;case 20:this.$=n.RequirementType.REQUIREMENT;break;case 21:this.$=n.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 22:this.$=n.RequirementType.INTERFACE_REQUIREMENT;break;case 23:this.$=n.RequirementType.PERFORMANCE_REQUIREMENT;break;case 24:this.$=n.RequirementType.PHYSICAL_REQUIREMENT;break;case 25:this.$=n.RequirementType.DESIGN_CONSTRAINT;break;case 26:this.$=n.RiskLevel.LOW_RISK;break;case 27:this.$=n.RiskLevel.MED_RISK;break;case 28:this.$=n.RiskLevel.HIGH_RISK;break;case 29:this.$=n.VerifyType.VERIFY_ANALYSIS;break;case 30:this.$=n.VerifyType.VERIFY_DEMONSTRATION;break;case 31:this.$=n.VerifyType.VERIFY_INSPECTION;break;case 32:this.$=n.VerifyType.VERIFY_TEST;break;case 33:n.addElement(s[l-3]);break;case 34:n.setNewElementType(s[l-2]);break;case 35:n.setNewElementDocRef(s[l-2]);break;case 38:n.addRelationship(s[l-2],s[l],s[l-4]);break;case 39:n.addRelationship(s[l-2],s[l-4],s[l]);break;case 40:this.$=n.Relationships.CONTAINS;break;case 41:this.$=n.Relationships.COPIES;break;case 42:this.$=n.Relationships.DERIVES;break;case 43:this.$=n.Relationships.SATISFIES;break;case 44:this.$=n.Relationships.VERIFIES;break;case 45:this.$=n.Relationships.REFINES;break;case 46:this.$=n.Relationships.TRACES}},table:[{3:1,4:2,6:e,9:i,11:n,13:r},{1:[3]},{3:8,4:2,5:[1,7],6:e,9:i,11:n,13:r},{5:[1,9]},{10:[1,10]},{12:[1,11]},t(s,[2,6]),{3:12,4:2,6:e,9:i,11:n,13:r},{1:[2,2]},{4:17,5:a,7:13,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},t(s,[2,4]),t(s,[2,5]),{1:[2,1]},{8:[1,30]},{4:17,5:a,7:31,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:32,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:33,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:34,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{4:17,5:a,7:35,8:l,9:i,11:n,13:r,14:14,15:15,16:16,17:19,23:21,31:c,32:o,33:h,34:u,35:y,36:d,44:p,62:_,63:E},{18:36,62:[1,37],63:[1,38]},{45:39,62:[1,40],63:[1,41]},{51:[1,42],53:[1,43]},t(g,[2,20]),t(g,[2,21]),t(g,[2,22]),t(g,[2,23]),t(g,[2,24]),t(g,[2,25]),t(R,[2,49]),t(R,[2,50]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{19:[1,44]},{19:[2,47]},{19:[2,48]},{19:[1,45]},{19:[2,53]},{19:[2,54]},{52:46,55:m,56:f,57:I,58:b,59:k,60:S,61:T},{52:54,55:m,56:f,57:I,58:b,59:k,60:S,61:T},{5:[1,55]},{5:[1,56]},{53:[1,57]},t(N,[2,40]),t(N,[2,41]),t(N,[2,42]),t(N,[2,43]),t(N,[2,44]),t(N,[2,45]),t(N,[2,46]),{54:[1,58]},{5:x,20:59,21:A,24:v,26:q,28:w,30:$},{5:O,30:C,46:66,47:L,49:F},{23:71,62:_,63:E},{23:72,62:_,63:E},t(M,[2,13]),{22:[1,73]},{22:[1,74]},{22:[1,75]},{22:[1,76]},{5:x,20:77,21:A,24:v,26:q,28:w,30:$},t(M,[2,19]),t(M,[2,33]),{22:[1,78]},{22:[1,79]},{5:O,30:C,46:80,47:L,49:F},t(M,[2,37]),t(M,[2,38]),t(M,[2,39]),{23:81,62:_,63:E},{25:82,62:[1,83],63:[1,84]},{27:85,37:[1,86],38:[1,87],39:[1,88]},{29:89,40:[1,90],41:[1,91],42:[1,92],43:[1,93]},t(M,[2,18]),{48:94,62:[1,95],63:[1,96]},{50:97,62:[1,98],63:[1,99]},t(M,[2,36]),{5:[1,100]},{5:[1,101]},{5:[2,51]},{5:[2,52]},{5:[1,102]},{5:[2,26]},{5:[2,27]},{5:[2,28]},{5:[1,103]},{5:[2,29]},{5:[2,30]},{5:[2,31]},{5:[2,32]},{5:[1,104]},{5:[2,55]},{5:[2,56]},{5:[1,105]},{5:[2,57]},{5:[2,58]},{5:x,20:106,21:A,24:v,26:q,28:w,30:$},{5:x,20:107,21:A,24:v,26:q,28:w,30:$},{5:x,20:108,21:A,24:v,26:q,28:w,30:$},{5:x,20:109,21:A,24:v,26:q,28:w,30:$},{5:O,30:C,46:110,47:L,49:F},{5:O,30:C,46:111,47:L,49:F},t(M,[2,14]),t(M,[2,15]),t(M,[2,16]),t(M,[2,17]),t(M,[2,34]),t(M,[2,35])],defaultActions:{8:[2,2],12:[2,1],30:[2,3],31:[2,8],32:[2,9],33:[2,10],34:[2,11],35:[2,12],37:[2,47],38:[2,48],40:[2,53],41:[2,54],83:[2,51],84:[2,52],86:[2,26],87:[2,27],88:[2,28],90:[2,29],91:[2,30],92:[2,31],93:[2,32],95:[2,55],96:[2,56],98:[2,57],99:[2,58]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],r=[null],s=[],a=this.table,l="",c=0,o=0,h=s.slice.call(arguments,1),u=Object.create(this.lexer),y={yy:{}};for(var d in this.yy)Object.prototype.hasOwnProperty.call(this.yy,d)&&(y.yy[d]=this.yy[d]);u.setInput(t,y.yy),y.yy.lexer=u,y.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var p=u.yylloc;s.push(p);var _=u.options&&u.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,g,R,m,f,I,b,k,S,T={};;){if(g=i[i.length-1],this.defaultActions[g]?R=this.defaultActions[g]:(null==E&&(S=void 0,"number"!=typeof(S=n.pop()||u.lex()||1)&&(S instanceof Array&&(S=(n=S).pop()),S=e.symbols_[S]||S),E=S),R=a[g]&&a[g][E]),void 0===R||!R.length||!R[0]){var N="";for(f in k=[],a[g])this.terminals_[f]&&f>2&&k.push("'"+this.terminals_[f]+"'");N=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==E?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(N,{text:u.match,token:this.terminals_[E]||E,line:u.yylineno,loc:p,expected:k})}if(R[0]instanceof Array&&R.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+E);switch(R[0]){case 1:i.push(E),r.push(u.yytext),s.push(u.yylloc),i.push(R[1]),E=null,o=u.yyleng,l=u.yytext,c=u.yylineno,p=u.yylloc;break;case 2:if(I=this.productions_[R[1]][1],T.$=r[r.length-I],T._$={first_line:s[s.length-(I||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(I||1)].first_column,last_column:s[s.length-1].last_column},_&&(T._$.range=[s[s.length-(I||1)].range[0],s[s.length-1].range[1]]),void 0!==(m=this.performAction.apply(T,[l,o,c,y.yy,R[1],r,s].concat(h))))return m;I&&(i=i.slice(0,-1*I*2),r=r.slice(0,-1*I),s=s.slice(0,-1*I)),i.push(this.productions_[R[1]][0]),r.push(T.$),s.push(T._$),b=a[i[i.length-2]][i[i.length-1]],i.push(b);break;case 3:return!0}}return!0}},P={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var i,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;s<r.length;s++)if((i=this._input.match(this.rules[r[s]]))&&(!e||i[0].length>e[0].length)){if(e=i,n=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,r[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:return"title";case 1:return this.begin("acc_title"),9;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),11;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 48:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 5;case 9:case 10:case 11:break;case 12:return 8;case 13:return 6;case 14:return 19;case 15:return 30;case 16:return 22;case 17:return 21;case 18:return 24;case 19:return 26;case 20:return 28;case 21:return 31;case 22:return 32;case 23:return 33;case 24:return 34;case 25:return 35;case 26:return 36;case 27:return 37;case 28:return 38;case 29:return 39;case 30:return 40;case 31:return 41;case 32:return 42;case 33:return 43;case 34:return 44;case 35:return 55;case 36:return 56;case 37:return 57;case 38:return 58;case 39:return 59;case 40:return 60;case 41:return 61;case 42:return 47;case 43:return 49;case 44:return 51;case 45:return 54;case 46:return 53;case 47:this.begin("string");break;case 49:return"qString";case 50:return e.yytext=e.yytext.trim(),62}},rules:[/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[48,49],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,50],inclusive:!0}}};function V(){this.yy={}}return D.lexer=P,V.prototype=D,D.Parser=V,new V}());l.parser=l;const c=l;let o=[],h={},u={},y={},d={};const p={RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},getConfig:()=>(0,n.c)().req,addRequirement:(t,e)=>(void 0===u[t]&&(u[t]={name:t,type:e,id:h.id,text:h.text,risk:h.risk,verifyMethod:h.verifyMethod}),h={},u[t]),getRequirements:()=>u,setNewReqId:t=>{void 0!==h&&(h.id=t)},setNewReqText:t=>{void 0!==h&&(h.text=t)},setNewReqRisk:t=>{void 0!==h&&(h.risk=t)},setNewReqVerifyMethod:t=>{void 0!==h&&(h.verifyMethod=t)},setAccTitle:n.s,getAccTitle:n.g,setAccDescription:n.b,getAccDescription:n.a,addElement:t=>(void 0===d[t]&&(d[t]={name:t,type:y.type,docRef:y.docRef},n.l.info("Added new requirement: ",t)),y={},d[t]),getElements:()=>d,setNewElementType:t=>{void 0!==y&&(y.type=t)},setNewElementDocRef:t=>{void 0!==y&&(y.docRef=t)},addRelationship:(t,e,i)=>{o.push({type:t,src:e,dst:i})},getRelationships:()=>o,clear:()=>{o=[],h={},u={},y={},d={},(0,n.t)()}},_={CONTAINS:"contains",ARROW:"arrow"},E=_,g=(t,e)=>{let i=t.append("defs").append("marker").attr("id",_.CONTAINS+"_line_ending").attr("refX",0).attr("refY",e.line_height/2).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("g");i.append("circle").attr("cx",e.line_height/2).attr("cy",e.line_height/2).attr("r",e.line_height/2).attr("fill","none"),i.append("line").attr("x1",0).attr("x2",e.line_height).attr("y1",e.line_height/2).attr("y2",e.line_height/2).attr("stroke-width",1),i.append("line").attr("y1",0).attr("y2",e.line_height).attr("x1",e.line_height/2).attr("x2",e.line_height/2).attr("stroke-width",1),t.append("defs").append("marker").attr("id",_.ARROW+"_line_ending").attr("refX",e.line_height).attr("refY",.5*e.line_height).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("path").attr("d",`M0,0\n L${e.line_height},${e.line_height/2}\n M${e.line_height},${e.line_height/2}\n L0,${e.line_height}`).attr("stroke-width",1)};let R={},m=0;const f=(t,e)=>t.insert("rect","#"+e).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",R.rect_min_width+"px").attr("height",R.rect_min_height+"px"),I=(t,e,i)=>{let n=R.rect_min_width/2,r=t.append("text").attr("class","req reqLabel reqTitle").attr("id",e).attr("x",n).attr("y",R.rect_padding).attr("dominant-baseline","hanging"),s=0;i.forEach((t=>{0==s?r.append("tspan").attr("text-anchor","middle").attr("x",R.rect_min_width/2).attr("dy",0).text(t):r.append("tspan").attr("text-anchor","middle").attr("x",R.rect_min_width/2).attr("dy",.75*R.line_height).text(t),s++}));let a=1.5*R.rect_padding+s*R.line_height*.75;return t.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",R.rect_min_width).attr("y1",a).attr("y2",a),{titleNode:r,y:a}},b=(t,e,i,n)=>{let r=t.append("text").attr("class","req reqLabel").attr("id",e).attr("x",R.rect_padding).attr("y",n).attr("dominant-baseline","hanging"),s=0;let a=[];return i.forEach((t=>{let e=t.length;for(;e>30&&s<3;){let i=t.substring(0,30);e=(t=t.substring(30,t.length)).length,a[a.length]=i,s++}if(3==s){let t=a[a.length-1];a[a.length-1]=t.substring(0,t.length-4)+"..."}else a[a.length]=t;s=0})),a.forEach((t=>{r.append("tspan").attr("x",R.rect_padding).attr("dy",R.line_height).text(t)})),r},k=function(t,e,i,s,a){const l=i.edge(S(e.src),S(e.dst)),c=(0,r.jvg)().x((function(t){return t.x})).y((function(t){return t.y})),o=t.insert("path","#"+s).attr("class","er relationshipLine").attr("d",c(l.points)).attr("fill","none");e.type==a.db.Relationships.CONTAINS?o.attr("marker-start","url("+n.e.getUrl(R.arrowMarkerAbsolute)+"#"+e.type+"_line_ending)"):(o.attr("stroke-dasharray","10,7"),o.attr("marker-end","url("+n.e.getUrl(R.arrowMarkerAbsolute)+"#"+E.ARROW+"_line_ending)")),((t,e,i,n)=>{const r=e.node().getTotalLength(),s=e.node().getPointAtLength(.5*r),a="rel"+m;m++;const l=t.append("text").attr("class","req relationshipLabel").attr("id",a).attr("x",s.x).attr("y",s.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(n).node().getBBox();t.insert("rect","#"+a).attr("class","req reqLabelBox").attr("x",s.x-l.width/2).attr("y",s.y-l.height/2).attr("width",l.width).attr("height",l.height).attr("fill","white").attr("fill-opacity","85%")})(t,o,0,`<<${e.type}>>`)},S=t=>t.replace(/\s/g,"").replace(/\./g,"_"),T={parser:c,db:p,renderer:{draw:(t,e,i,l)=>{R=(0,n.c)().requirement;const c=R.securityLevel;let o;"sandbox"===c&&(o=(0,r.Ys)("#i"+e));const h=("sandbox"===c?(0,r.Ys)(o.nodes()[0].contentDocument.body):(0,r.Ys)("body")).select(`[id='${e}']`);g(h,R);const u=new a.k({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:R.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));let y=l.db.getRequirements(),d=l.db.getElements(),p=l.db.getRelationships();var _,E,m;_=y,E=u,m=h,Object.keys(_).forEach((t=>{let e=_[t];t=S(t),n.l.info("Added new requirement: ",t);const i=m.append("g").attr("id",t),r=f(i,"req-"+t);let s=I(i,t+"_title",[`<<${e.type}>>`,`${e.name}`]);b(i,t+"_body",[`Id: ${e.id}`,`Text: ${e.text}`,`Risk: ${e.risk}`,`Verification: ${e.verifyMethod}`],s.y);const a=r.node().getBBox();E.setNode(t,{width:a.width,height:a.height,shape:"rect",id:t})})),((t,e,i)=>{Object.keys(t).forEach((n=>{let r=t[n];const s=S(n),a=i.append("g").attr("id",s),l="element-"+s,c=f(a,l);let o=I(a,l+"_title",["<<Element>>",`${n}`]);b(a,l+"_body",[`Type: ${r.type||"Not Specified"}`,`Doc Ref: ${r.docRef||"None"}`],o.y);const h=c.node().getBBox();e.setNode(s,{width:h.width,height:h.height,shape:"rect",id:s})}))})(d,u,h),((t,e)=>{t.forEach((function(t){let i=S(t.src),n=S(t.dst);e.setEdge(i,n,{relationship:t})}))})(p,u),(0,s.bK)(u),function(t,e){e.nodes().forEach((function(i){void 0!==i&&void 0!==e.node(i)&&(t.select("#"+i),t.select("#"+i).attr("transform","translate("+(e.node(i).x-e.node(i).width/2)+","+(e.node(i).y-e.node(i).height/2)+" )"))}))}(h,u),p.forEach((function(t){k(h,t,u,e,l)}));const T=R.rect_padding,N=h.node().getBBox(),x=N.width+2*T,A=N.height+2*T;(0,n.i)(h,A,x,R.useMaxWidth),h.attr("viewBox",`${N.x-T} ${N.y-T} ${x} ${A}`)}},styles:t=>`\n\n marker {\n fill: ${t.relationColor};\n stroke: ${t.relationColor};\n }\n\n marker.cross {\n stroke: ${t.lineColor};\n }\n\n svg {\n font-family: ${t.fontFamily};\n font-size: ${t.fontSize};\n }\n\n .reqBox {\n fill: ${t.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${t.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${t.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${t.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${t.relationLabelColor};\n }\n\n`}}}]); \ No newline at end of file diff --git a/assets/js/829fa7b9.582cc610.js b/assets/js/829fa7b9.582cc610.js deleted file mode 100644 index 53a8cebbe..000000000 --- a/assets/js/829fa7b9.582cc610.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9391],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var k=n.createContext({}),u=function(e){var t=n.useContext(k),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(k.Provider,{value:t},e.children)},i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,k=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),b=u(r),m=a,s=b["".concat(k,".").concat(m)]||b[m]||i[m]||p;return r?n.createElement(s,o(o({ref:t},c),{},{components:r})):n.createElement(s,o({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=b;var l={};for(var k in t)hasOwnProperty.call(t,k)&&(l[k]=t[k]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var u=2;u<p;u++)o[u]=r[u];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}b.displayName="MDXCreateElement"},22895:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>k,contentTitle:()=>o,default:()=>i,frontMatter:()=>p,metadata:()=>l,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const p={title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",slug:"book-leadership-and-self-deception",tags:["Book"]},o=void 0,l={permalink:"/book-leadership-and-self-deception",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",source:"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",description:"\ucc45 \uc815\ubcf4",date:"2023-04-08T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 8\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:5.16,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",slug:"book-leadership-and-self-deception",tags:["Book"]},prevItem:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",permalink:"/tecochat-retrospective-1"},nextItem:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/innodb-lock"}},k={authorsImageUrls:[]},u=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18",id:"\uc790\uae30\uae30\ub9cc\uacfc-\uc790\uae30\ubc30\ubc18",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}],c={toc:u};function i(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ucc45-\uc815\ubcf4"},"\ucc45 \uc815\ubcf4"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ube48\uc800\uc5f0\uad6c\uc18c")),(0,a.kt)("h3",{id:"\uc790\uae30\uae30\ub9cc\uacfc-\uc790\uae30\ubc30\ubc18"},"\uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18"),(0,a.kt)("p",null,"\ucc45\uc5d0\uc11c\ub294 \uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc744 \ub2e4\ub8ec\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uc790\uae30\uae30\ub9cc: \uc790\uc2e0\uc758 \ubb38\uc81c\ub97c \uc778\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 "),(0,a.kt)("li",{parentName:"ul"},"\uc790\uae30\ubc30\ubc18: \ub2e4\ub978 \uc0ac\ub78c\uc744 \uc704\ud574 \ubb34\uc5b8\uac00 \ud574\uc57c\ub9cc \ud55c\ub2e4\ub294 \uc0dd\uac01\uc744 \ubc18\ud558\ub294 \ud589\uc704")),(0,a.kt)("p",null,"\uc790\uae30\ubc30\ubc18\uc744 \ud55c\ub2e4\uba74 \uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uac00 \ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uc5d0 \ube60\uc9c0\ub294 \uac83\uc744 \ucc45\uc5d0\uc11c\ub294 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac04\ub2e4\uace0 \ud45c\ud604\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc77d\uace0-\ub098\uc11c"},"\uc77d\uace0 \ub098\uc11c"),(0,a.kt)("p",null,"\ucd5c\uadfc\uc5d0 \uc77d\uc740 \ucc45 \uc911 \uac00\uc7a5 \ub9c8\uc74c\uc774 \ubd88\ud3b8\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub807\uae30\uc5d0 \ub354\ub354\uc6b1 \ub098\uc5d0\uac8c \ud544\uc694\ud55c \ub0b4\uc6a9\uc774 \ub2f4\uaca8\uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc0b4\uba74\uc11c \ub9ce\uc740 \uc120\ud0dd\uc758 \uc21c\uac04\uc774 \uc874\uc7ac\ud588\uace0, \uadf8 \uc21c\uac04\ub9c8\ub2e4 \uc790\uae30\ubc30\ubc18\uc744 \ud0dd\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc791\uac8c\ub294 \uc9d1\uc548\uc77c\uc744 \ud574\uc57c \ud558\ub294\ub370 \ubab8\uc774 \uc870\uae08 \ud798\ub4e4\ub2e4\uace0 \ud558\uc9c0 \uc54a\uac70\ub098",(0,a.kt)("br",{parentName:"p"}),"\n","\ud06c\uac8c\ub294 \uc798\ubabb\uc744 \uc778\uc815\ud574\uc57c \ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uadf8\ub7ec\uc9c0 \uc54a\uc740 \uacbd\uc6b0\uac00 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub7f0 \uc0c1\ud669\uc774 \ubc18\ubcf5\ub418\uc5b4 \uacb0\uad6d \uc0c1\uc790 \uc548\uc5d0 \ub098 \uc790\uc2e0\uc744 \uac00\ub450\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4. "),(0,a.kt)("p",null,"\ub354 \ub098\uc740 \uc0b6\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \uc9c0\uc18d\uc801\uc73c\ub85c \ud655\uc778\ud558\uace0, \uc0c1\uc790 \ubc16\uc73c\ub85c \ub098\uac00\ub824\ub294 \uc5f0\uc2b5\uc744 \ud574\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub113\uc740 \uc2dc\uc120\uc744 \uac00\uc9c0\uace0, \ud56d\uc0c1 \ub0b4\uac00 \ud2c0\ub9b4 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc0dd\uac01\ud558\uace0 \uc0b4\uc544\uac00\uc790. "),(0,a.kt)("h3",{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4"},"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc6b0\ub9ac\uc758 \uc0dd\uac01\uc740 \uc9c0\uc2dd\ubcf4\ub2e4 \uc791\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uc758 \uc9c0\uc2dd\uc740 \uc0ac\ub791\ubcf4\ub2e4 \uc791\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uc758 \uc0ac\ub791\uc740 \uc874\uc7ac\ubcf4\ub2e4 \uc791\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub9ac\uace0 \uc6b0\ub9ac\uac00 \uc0dd\uac01\ud558\ub294 \ub098\ub294 \uc2e4\uc81c\uc758 \ub098\ubcf4\ub2e4 \uadf8\ub9cc\ud07c \uc791\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","R. D. \ub7ad",(0,a.kt)("br",{parentName:"p"}),"\n","p.19")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc6b0\ub9ac\uac00 \uc678\uc801\uc73c\ub85c \uc5b4\ub5a4 \ud589\ub3d9\uc744 \ud558\ub4e0\uc9c0 \uac04\uc5d0, \uc0ac\ub78c\ub4e4\uc740 \uc6b0\ub9ac \ub9c8\uc74c\uc5d0\uc11c \uadf8\ub4e4\uc744 \uc5b4\ub5bb\uac8c \ub300\ud558\uace0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \uc8fc\ub85c \ubc18\uc751\ud569\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uac00 \uc0ac\ub78c\ub4e4\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \ub290\ub07c\uac8c \ub418\ub294\uc9c0\ub294 \uc6b0\ub9ac\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \ud639\uc740 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \ub2ec\ub77c\uc9c0\uac8c \ub429\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.66")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\ube44\ub09c\uc740 \uac10\uc815\uc5d0 \uc18d\ud558\uace0 \ub099\uad00\uc740 \uc758\uc9c0\uc5d0 \uc18d\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc778\uac04\uc740 \uac10\uc815\ubcf4\ub2e4 \ub354 \ud070 \uc874\uc7ac\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc54c\ub7ad, \ud0c1\ub2db\ud55c",(0,a.kt)("br",{parentName:"p"}),"\n","p.103")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc6b0\ub9ac\uac00 \uc790\uc2e0\uc5d0\uac8c\ub9cc \uc9d1\uc911\ud558\uace0 \uc788\ub294 \ud55c, \ud63c\uc790\uc11c \uc77c\ud558\ub294 \uac83 \uc774\uc0c1\uc758 \ucc3d\uc870\uc801\uc778 \uacb0\uacfc\ub098 \ud611\ub825\uc744 \uc774\ub04c\uc5b4 \ub0b8\ub2e4\ub294 \uac83\uc740 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc624\ub298\ub0a0 \uacbd\uc81c \ud658\uacbd\uc5d0\uc11c\ub294 \ud63c\uc790\uc11c\ub294 \uc77c\uc758 \uacb0\uacfc\ub97c \ud0c1\uc6d4\ud558\uac8c \ub9cc\ub4e4\uc5b4 \ub0b4\uae30\uac00 \uc5b4\ub835\uc2b5\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \uc911\uc2ec\uc774\uc5b4\uc57c \ub41c\ub2e4\ub294 \ud3d0\uc1c4\uc801\uc778 \uc0ac\uace0\ub294 \ud568\uaed8 \uc77c\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uc5f4\uc815\uc744 \ubd88\ub7ec\uc624\uc9c0 \ubabb\ud569\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.175")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc194\uc9c1\ud568\uc740 \uc6b0\ub9ac\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\ub294 \uc5f4\uc1e0\uc785\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\uac83\uc740 \uc790\uc2e0\uc758 \ud589\ub3d9\uacfc \uad00\ub828\ub41c \uc0ac\ub78c\uc5d0 \ub300\ud574 \uae30\uaebc\uc774 \uc0ac\uacfc\ub97c \ud558\ub294 \uac83\uc785\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\uac83\ub9cc\uc774 \uc2e4\ud0c0\ub798\ucc98\ub7fc \uc5c9\ud0a8 \uad00\uacc4\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc774\uc8e0.",(0,a.kt)("br",{parentName:"p"}),"\n","p.188")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\ub204\uad70\uac00\ub97c \ub098\uc640 \uac19\uc774 \ub3d9\uc77c\ud55c \uac00\uce58\ub97c \uc9c0\ub2cc \ud55c \uc778\uac04\uc73c\ub85c \uc0dd\uac01\ud574\uc11c \uadf8 \uc0ac\ub78c\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \ubc16\uc5d0 \uacc4\uc18d \uba38\ubb34\ub974\uace0 \uc2f6\uc740 \uc5f4\ub9dd\uc774 \uc0dd\uae38 \ub54c, \ub098\ub294 \uc774\ubbf8 \uadf8 \uc0ac\ub78c\uc5d0 \ub300\ud574 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.214")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\ub300\ubd80\ubd84\uc758 \uc0ac\ub78c\ub4e4\uc774 \uad00\uacc4 \uae30\uc220\uc744 \uac00\uc9c0\uace0 \uadf8\ub4e4\uc774 \uacaa\uace0 \uc788\ub294 \ubb38\uc81c\ub97c \ubc14\ub85c\uc7a1\uc73c\ub824\uace0 \ud558\ub294 \ub178\ub825\uc774 \uacb0\uc2e4\uc744 \uc5bb\uc9c0 \ubabb\ud558\ub294 \uac83\uc740 \uacb0\ucf54 \uadf8\ub7ec\ud55c \uae30\uc220 \ubd80\uc871 \ub54c\ubb38\uc5d0 \uc0dd\uae30\ub294 \uac83\uc774 \uc544\ub2d9\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\uac83\ub4e4\uc740 \uc790\uae30\ubc30\ubc18 \ub54c\ubb38\uc5d0 \uc0dd\uaca8\ub0a9\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.224")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc6b0\ub9ac\ub294 \ud568\uaed8 \uc77c\ud558\uace0 \uc6b0\ub9ac\uc640 \ud568\uaed8 \uc0b4\uc544\uac00\ub294 \uc0ac\ub78c\uc774 \uc9c4\uc815\uc73c\ub85c \ub204\uad6c\uc778\uc9c0 \uc54c\uc9c0 \ubabb\ud569\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uac00 \uadf8\ub4e4\uacfc \uc9c4\uc815\uc73c\ub85c \ud568\uaed8 \uc18c\ud1b5\ud558\uae30 \uc804\uae4c\uc9c0\ub294 \uc6b0\ub9ac\ub294 \uadf8\ub4e4\uc758 \uac00\uce58\ub97c \uc798 \ubaa8\ub985\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uc758 \uc704\ub300\ud568\uc774\ub780 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc758 \uc704\ub300\ud55c \uc810\uc744 \ubc1c\uacac\ud574 \uc8fc\ub294 \uac83\uc5d0 \uc788\uc2b5\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.280")))}i.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/829fa7b9.c29a2b79.js b/assets/js/829fa7b9.c29a2b79.js new file mode 100644 index 000000000..556f05e63 --- /dev/null +++ b/assets/js/829fa7b9.c29a2b79.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9391],{4565:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>l,metadata:()=>i,toc:()=>a});var t=r(85893),s=r(3905);const l={title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",slug:"book-leadership-and-self-deception",tags:["Book"]},o=void 0,i={permalink:"/book-leadership-and-self-deception",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",source:"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",description:"\ucc45 \uc815\ubcf4",date:"2023-04-08T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 8\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:5.16,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",slug:"book-leadership-and-self-deception",tags:["Book"]},unlisted:!1,prevItem:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",permalink:"/tecochat-retrospective-1"},nextItem:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/innodb-lock"}},c={authorsImageUrls:[]},a=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18",id:"\uc790\uae30\uae30\ub9cc\uacfc-\uc790\uae30\ubc30\ubc18",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}];function b(e){const n={blockquote:"blockquote",br:"br",h3:"h3",li:"li",p:"p",ul:"ul",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\ucc45-\uc815\ubcf4",children:"\ucc45 \uc815\ubcf4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",(0,t.jsx)(n.br,{}),"\n","\uc544\ube48\uc800\uc5f0\uad6c\uc18c"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc790\uae30\uae30\ub9cc\uacfc-\uc790\uae30\ubc30\ubc18",children:"\uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18"}),"\n",(0,t.jsx)(n.p,{children:"\ucc45\uc5d0\uc11c\ub294 \uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc744 \ub2e4\ub8ec\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc790\uae30\uae30\ub9cc: \uc790\uc2e0\uc758 \ubb38\uc81c\ub97c \uc778\uc815\ud558\uc9c0 \uc54a\ub294 \uac83"}),"\n",(0,t.jsx)(n.li,{children:"\uc790\uae30\ubc30\ubc18: \ub2e4\ub978 \uc0ac\ub78c\uc744 \uc704\ud574 \ubb34\uc5b8\uac00 \ud574\uc57c\ub9cc \ud55c\ub2e4\ub294 \uc0dd\uac01\uc744 \ubc18\ud558\ub294 \ud589\uc704"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\uc790\uae30\ubc30\ubc18\uc744 \ud55c\ub2e4\uba74 \uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uac00 \ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uc5d0 \ube60\uc9c0\ub294 \uac83\uc744 \ucc45\uc5d0\uc11c\ub294 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac04\ub2e4\uace0 \ud45c\ud604\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc77d\uace0-\ub098\uc11c",children:"\uc77d\uace0 \ub098\uc11c"}),"\n",(0,t.jsxs)(n.p,{children:["\ucd5c\uadfc\uc5d0 \uc77d\uc740 \ucc45 \uc911 \uac00\uc7a5 \ub9c8\uc74c\uc774 \ubd88\ud3b8\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\ub807\uae30\uc5d0 \ub354\ub354\uc6b1 \ub098\uc5d0\uac8c \ud544\uc694\ud55c \ub0b4\uc6a9\uc774 \ub2f4\uaca8\uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\uc0b4\uba74\uc11c \ub9ce\uc740 \uc120\ud0dd\uc758 \uc21c\uac04\uc774 \uc874\uc7ac\ud588\uace0, \uadf8 \uc21c\uac04\ub9c8\ub2e4 \uc790\uae30\ubc30\ubc18\uc744 \ud0dd\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc791\uac8c\ub294 \uc9d1\uc548\uc77c\uc744 \ud574\uc57c \ud558\ub294\ub370 \ubab8\uc774 \uc870\uae08 \ud798\ub4e4\ub2e4\uace0 \ud558\uc9c0 \uc54a\uac70\ub098",(0,t.jsx)(n.br,{}),"\n","\ud06c\uac8c\ub294 \uc798\ubabb\uc744 \uc778\uc815\ud574\uc57c \ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uadf8\ub7ec\uc9c0 \uc54a\uc740 \uacbd\uc6b0\uac00 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub7f0 \uc0c1\ud669\uc774 \ubc18\ubcf5\ub418\uc5b4 \uacb0\uad6d \uc0c1\uc790 \uc548\uc5d0 \ub098 \uc790\uc2e0\uc744 \uac00\ub450\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\ub354 \ub098\uc740 \uc0b6\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \uc9c0\uc18d\uc801\uc73c\ub85c \ud655\uc778\ud558\uace0, \uc0c1\uc790 \ubc16\uc73c\ub85c \ub098\uac00\ub824\ub294 \uc5f0\uc2b5\uc744 \ud574\uc57c\uaca0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub113\uc740 \uc2dc\uc120\uc744 \uac00\uc9c0\uace0, \ud56d\uc0c1 \ub0b4\uac00 \ud2c0\ub9b4 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc0dd\uac01\ud558\uace0 \uc0b4\uc544\uac00\uc790."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",children:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc6b0\ub9ac\uc758 \uc0dd\uac01\uc740 \uc9c0\uc2dd\ubcf4\ub2e4 \uc791\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uc758 \uc9c0\uc2dd\uc740 \uc0ac\ub791\ubcf4\ub2e4 \uc791\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uc758 \uc0ac\ub791\uc740 \uc874\uc7ac\ubcf4\ub2e4 \uc791\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\ub9ac\uace0 \uc6b0\ub9ac\uac00 \uc0dd\uac01\ud558\ub294 \ub098\ub294 \uc2e4\uc81c\uc758 \ub098\ubcf4\ub2e4 \uadf8\ub9cc\ud07c \uc791\ub2e4.",(0,t.jsx)(n.br,{}),"\n","R. D. \ub7ad",(0,t.jsx)(n.br,{}),"\n","p.19"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc6b0\ub9ac\uac00 \uc678\uc801\uc73c\ub85c \uc5b4\ub5a4 \ud589\ub3d9\uc744 \ud558\ub4e0\uc9c0 \uac04\uc5d0, \uc0ac\ub78c\ub4e4\uc740 \uc6b0\ub9ac \ub9c8\uc74c\uc5d0\uc11c \uadf8\ub4e4\uc744 \uc5b4\ub5bb\uac8c \ub300\ud558\uace0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \uc8fc\ub85c \ubc18\uc751\ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uac00 \uc0ac\ub78c\ub4e4\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \ub290\ub07c\uac8c \ub418\ub294\uc9c0\ub294 \uc6b0\ub9ac\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \ud639\uc740 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \ub2ec\ub77c\uc9c0\uac8c \ub429\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.66"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\ube44\ub09c\uc740 \uac10\uc815\uc5d0 \uc18d\ud558\uace0 \ub099\uad00\uc740 \uc758\uc9c0\uc5d0 \uc18d\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc778\uac04\uc740 \uac10\uc815\ubcf4\ub2e4 \ub354 \ud070 \uc874\uc7ac\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc54c\ub7ad, \ud0c1\ub2db\ud55c",(0,t.jsx)(n.br,{}),"\n","p.103"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc6b0\ub9ac\uac00 \uc790\uc2e0\uc5d0\uac8c\ub9cc \uc9d1\uc911\ud558\uace0 \uc788\ub294 \ud55c, \ud63c\uc790\uc11c \uc77c\ud558\ub294 \uac83 \uc774\uc0c1\uc758 \ucc3d\uc870\uc801\uc778 \uacb0\uacfc\ub098 \ud611\ub825\uc744 \uc774\ub04c\uc5b4 \ub0b8\ub2e4\ub294 \uac83\uc740 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc624\ub298\ub0a0 \uacbd\uc81c \ud658\uacbd\uc5d0\uc11c\ub294 \ud63c\uc790\uc11c\ub294 \uc77c\uc758 \uacb0\uacfc\ub97c \ud0c1\uc6d4\ud558\uac8c \ub9cc\ub4e4\uc5b4 \ub0b4\uae30\uac00 \uc5b4\ub835\uc2b5\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub0b4\uac00 \uc911\uc2ec\uc774\uc5b4\uc57c \ub41c\ub2e4\ub294 \ud3d0\uc1c4\uc801\uc778 \uc0ac\uace0\ub294 \ud568\uaed8 \uc77c\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uc5f4\uc815\uc744 \ubd88\ub7ec\uc624\uc9c0 \ubabb\ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.175"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc194\uc9c1\ud568\uc740 \uc6b0\ub9ac\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\ub294 \uc5f4\uc1e0\uc785\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\uac83\uc740 \uc790\uc2e0\uc758 \ud589\ub3d9\uacfc \uad00\ub828\ub41c \uc0ac\ub78c\uc5d0 \ub300\ud574 \uae30\uaebc\uc774 \uc0ac\uacfc\ub97c \ud558\ub294 \uac83\uc785\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\uac83\ub9cc\uc774 \uc2e4\ud0c0\ub798\ucc98\ub7fc \uc5c9\ud0a8 \uad00\uacc4\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc774\uc8e0.",(0,t.jsx)(n.br,{}),"\n","p.188"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\ub204\uad70\uac00\ub97c \ub098\uc640 \uac19\uc774 \ub3d9\uc77c\ud55c \uac00\uce58\ub97c \uc9c0\ub2cc \ud55c \uc778\uac04\uc73c\ub85c \uc0dd\uac01\ud574\uc11c \uadf8 \uc0ac\ub78c\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \ubc16\uc5d0 \uacc4\uc18d \uba38\ubb34\ub974\uace0 \uc2f6\uc740 \uc5f4\ub9dd\uc774 \uc0dd\uae38 \ub54c, \ub098\ub294 \uc774\ubbf8 \uadf8 \uc0ac\ub78c\uc5d0 \ub300\ud574 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.214"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\ub300\ubd80\ubd84\uc758 \uc0ac\ub78c\ub4e4\uc774 \uad00\uacc4 \uae30\uc220\uc744 \uac00\uc9c0\uace0 \uadf8\ub4e4\uc774 \uacaa\uace0 \uc788\ub294 \ubb38\uc81c\ub97c \ubc14\ub85c\uc7a1\uc73c\ub824\uace0 \ud558\ub294 \ub178\ub825\uc774 \uacb0\uc2e4\uc744 \uc5bb\uc9c0 \ubabb\ud558\ub294 \uac83\uc740 \uacb0\ucf54 \uadf8\ub7ec\ud55c \uae30\uc220 \ubd80\uc871 \ub54c\ubb38\uc5d0 \uc0dd\uae30\ub294 \uac83\uc774 \uc544\ub2d9\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\uac83\ub4e4\uc740 \uc790\uae30\ubc30\ubc18 \ub54c\ubb38\uc5d0 \uc0dd\uaca8\ub0a9\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.224"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc6b0\ub9ac\ub294 \ud568\uaed8 \uc77c\ud558\uace0 \uc6b0\ub9ac\uc640 \ud568\uaed8 \uc0b4\uc544\uac00\ub294 \uc0ac\ub78c\uc774 \uc9c4\uc815\uc73c\ub85c \ub204\uad6c\uc778\uc9c0 \uc54c\uc9c0 \ubabb\ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uac00 \uadf8\ub4e4\uacfc \uc9c4\uc815\uc73c\ub85c \ud568\uaed8 \uc18c\ud1b5\ud558\uae30 \uc804\uae4c\uc9c0\ub294 \uc6b0\ub9ac\ub294 \uadf8\ub4e4\uc758 \uac00\uce58\ub97c \uc798 \ubaa8\ub985\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uc758 \uc704\ub300\ud568\uc774\ub780 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc758 \uc704\ub300\ud55c \uc810\uc744 \ubc1c\uacac\ud574 \uc8fc\ub294 \uac83\uc5d0 \uc788\uc2b5\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.280"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,s.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(b,{...e})}):b(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function s(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function l(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?l(Object(r),!0).forEach((function(n){s(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function i(e,n){if(null==e)return{};var r,t,s=function(e,n){if(null==e)return{};var r,t,s={},l=Object.keys(e);for(t=0;t<l.length;t++)r=l[t],n.indexOf(r)>=0||(s[r]=e[r]);return s}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(t=0;t<l.length;t++)r=l[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var c=t.createContext({}),a=function(e){var n=t.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},b={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,s=e.mdxType,l=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),j=a(r),d=s,x=j["".concat(c,".").concat(d)]||j[d]||b[d]||l;return r?t.createElement(x,o(o({ref:n},p),{},{components:r})):t.createElement(x,o({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/8365.83cd436c.js b/assets/js/8365.83cd436c.js new file mode 100644 index 000000000..b59a0fb26 --- /dev/null +++ b/assets/js/8365.83cd436c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8365],{88365:(t,e,i)=>{i.d(e,{diagram:()=>d});var n=i(56363),s=i(64218),r=(i(27484),i(17967),i(27856),function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,3],i=[1,4],n=[1,5],s=[1,6],r=[1,10,12,14,16,18,19,20,21,22],l=[2,4],a=[1,5,10,12,14,16,18,19,20,21,22],c=[20,21,22],o=[2,7],h=[1,12],u=[1,13],y=[1,14],p=[1,15],d=[1,16],g=[1,17],_={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,PIE:5,document:6,showData:7,line:8,statement:9,txt:10,value:11,title:12,title_value:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,section:19,NEWLINE:20,";":21,EOF:22,$accept:0,$end:1},terminals_:{2:"error",5:"PIE",7:"showData",10:"txt",11:"value",12:"title",13:"title_value",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"section",20:"NEWLINE",21:";",22:"EOF"},productions_:[0,[3,2],[3,2],[3,3],[6,0],[6,2],[8,2],[9,0],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[4,1],[4,1],[4,1]],performAction:function(t,e,i,n,s,r,l){var a=r.length-1;switch(s){case 3:n.setShowData(!0);break;case 6:this.$=r[a-1];break;case 8:n.addSection(r[a-1],n.cleanupValue(r[a]));break;case 9:this.$=r[a].trim(),n.setDiagramTitle(this.$);break;case 10:this.$=r[a].trim(),n.setAccTitle(this.$);break;case 11:case 12:this.$=r[a].trim(),n.setAccDescription(this.$);break;case 13:n.addSection(r[a].substr(8)),this.$=r[a].substr(8)}},table:[{3:1,4:2,5:e,20:i,21:n,22:s},{1:[3]},{3:7,4:2,5:e,20:i,21:n,22:s},t(r,l,{6:8,7:[1,9]}),t(a,[2,14]),t(a,[2,15]),t(a,[2,16]),{1:[2,1]},t(c,o,{8:10,9:11,1:[2,2],10:h,12:u,14:y,16:p,18:d,19:g}),t(r,l,{6:18}),t(r,[2,5]),{4:19,20:i,21:n,22:s},{11:[1,20]},{13:[1,21]},{15:[1,22]},{17:[1,23]},t(c,[2,12]),t(c,[2,13]),t(c,o,{8:10,9:11,1:[2,3],10:h,12:u,14:y,16:p,18:d,19:g}),t(r,[2,6]),t(c,[2,8]),t(c,[2,9]),t(c,[2,10]),t(c,[2,11])],defaultActions:{7:[2,1]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],s=[null],r=[],l=this.table,a="",c=0,o=0,h=r.slice.call(arguments,1),u=Object.create(this.lexer),y={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(y.yy[p]=this.yy[p]);u.setInput(t,y.yy),y.yy.lexer=u,y.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var d=u.yylloc;r.push(d);var g=u.options&&u.options.ranges;"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,f,m,b,k,v,x,S,w,$={};;){if(f=i[i.length-1],this.defaultActions[f]?m=this.defaultActions[f]:(null==_&&(w=void 0,"number"!=typeof(w=n.pop()||u.lex()||1)&&(w instanceof Array&&(w=(n=w).pop()),w=e.symbols_[w]||w),_=w),m=l[f]&&l[f][_]),void 0===m||!m.length||!m[0]){var E="";for(k in S=[],l[f])this.terminals_[k]&&k>2&&S.push("'"+this.terminals_[k]+"'");E=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+S.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(E,{text:u.match,token:this.terminals_[_]||_,line:u.yylineno,loc:d,expected:S})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+f+", token: "+_);switch(m[0]){case 1:i.push(_),s.push(u.yytext),r.push(u.yylloc),i.push(m[1]),_=null,o=u.yyleng,a=u.yytext,c=u.yylineno,d=u.yylloc;break;case 2:if(v=this.productions_[m[1]][1],$.$=s[s.length-v],$._$={first_line:r[r.length-(v||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(v||1)].first_column,last_column:r[r.length-1].last_column},g&&($._$.range=[r[r.length-(v||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply($,[a,o,c,y.yy,m[1],s,r].concat(h))))return b;v&&(i=i.slice(0,-1*v*2),s=s.slice(0,-1*v),r=r.slice(0,-1*v)),i.push(this.productions_[m[1]][0]),s.push($.$),r.push($._$),x=l[i[i.length-2]][i[i.length-1]],i.push(x);break;case 3:return!0}}return!0}},f={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var i,n,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((i=this._input.match(this.rules[s[r]]))&&(!e||i[0].length>e[0].length)){if(e=i,n=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:case 1:case 3:case 4:break;case 2:return 20;case 5:return this.begin("title"),12;case 6:return this.popState(),"title_value";case 7:return this.begin("acc_title"),14;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),16;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:case 15:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:this.begin("string");break;case 16:return"txt";case 17:return 5;case 18:return 7;case 19:return"value";case 20:return 22}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[6],inclusive:!1},string:{rules:[15,16],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,7,9,11,14,17,18,19,20],inclusive:!0}}};function m(){this.yy={}}return _.lexer=f,m.prototype=_,_.Parser=m,new m}());r.parser=r;const l=r,a=n.A.pie,c={},o=!1;let h=c,u=o;const y=structuredClone(a),p={getConfig:()=>structuredClone(y),clear:()=>{h=structuredClone(c),u=o,(0,n.t)()},setDiagramTitle:n.q,getDiagramTitle:n.r,setAccTitle:n.s,getAccTitle:n.g,setAccDescription:n.b,getAccDescription:n.a,addSection:(t,e)=>{t=(0,n.d)(t,(0,n.c)()),void 0===h[t]&&(h[t]=e,n.l.debug(`added new section: ${t}, with value: ${e}`))},getSections:()=>h,cleanupValue:t=>(":"===t.substring(0,1)&&(t=t.substring(1).trim()),Number(t.trim())),setShowData:t=>{u=t},getShowData:()=>u},d={parser:l,db:p,renderer:{draw:(t,e,i,r)=>{var l,a;n.l.debug("rendering pie chart\n"+t);const c=r.db,o=(0,n.c)(),h=(0,n.B)(c.getConfig(),o.pie),u=450,y=(null==(a=null==(l=document.getElementById(e))?void 0:l.parentElement)?void 0:a.offsetWidth)??h.useWidth,p=(0,n.z)(e);p.attr("viewBox",`0 0 ${y} 450`),(0,n.i)(p,u,y,h.useMaxWidth);const d=18,g=p.append("g");g.attr("transform","translate("+y/2+",225)");const{themeVariables:_}=o;let[f]=(0,n.C)(_.pieOuterStrokeWidth);f??(f=2);const m=h.textPosition,b=Math.min(y,u)/2-40,k=(0,s.Nb1)().innerRadius(0).outerRadius(b),v=(0,s.Nb1)().innerRadius(b*m).outerRadius(b*m);g.append("circle").attr("cx",0).attr("cy",0).attr("r",b+f/2).attr("class","pieOuterCircle");const x=c.getSections(),S=(t=>{const e=Object.entries(t).map((t=>({label:t[0],value:t[1]}))).sort(((t,e)=>e.value-t.value));return(0,s.ve8)().value((t=>t.value))(e)})(x),w=[_.pie1,_.pie2,_.pie3,_.pie4,_.pie5,_.pie6,_.pie7,_.pie8,_.pie9,_.pie10,_.pie11,_.pie12],$=(0,s.PKp)(w);g.selectAll("mySlices").data(S).enter().append("path").attr("d",k).attr("fill",(t=>$(t.data.label))).attr("class","pieCircle");let E=0;Object.keys(x).forEach((t=>{E+=x[t]})),g.selectAll("mySlices").data(S).enter().append("text").text((t=>(t.data.value/E*100).toFixed(0)+"%")).attr("transform",(t=>"translate("+v.centroid(t)+")")).style("text-anchor","middle").attr("class","slice"),g.append("text").text(c.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");const A=g.selectAll(".legend").data($.domain()).enter().append("g").attr("class","legend").attr("transform",((t,e)=>"translate(216,"+(22*e-22*$.domain().length/2)+")"));A.append("rect").attr("width",d).attr("height",d).style("fill",$).style("stroke",$),A.data(S).append("text").attr("x",22).attr("y",14).text((t=>{const{label:e,value:i}=t.data;return c.getShowData()?`${e} [${i}]`:e}))}},styles:t=>`\n .pieCircle{\n stroke: ${t.pieStrokeColor};\n stroke-width : ${t.pieStrokeWidth};\n opacity : ${t.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${t.pieOuterStrokeColor};\n stroke-width: ${t.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${t.pieTitleTextSize};\n fill: ${t.pieTitleTextColor};\n font-family: ${t.fontFamily};\n }\n .slice {\n font-family: ${t.fontFamily};\n fill: ${t.pieSectionTextColor};\n font-size:${t.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${t.pieLegendTextColor};\n font-family: ${t.fontFamily};\n font-size: ${t.pieLegendTextSize};\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/8371.9ec33232.js b/assets/js/8371.9ec33232.js new file mode 100644 index 000000000..a38c3476f --- /dev/null +++ b/assets/js/8371.9ec33232.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8371],{43349:(e,t,n)=>{n.d(t,{a:()=>l});var r=n(96225);function l(e,t){var n=e.append("foreignObject").attr("width","100000"),l=n.append("xhtml:div");l.attr("xmlns","http://www.w3.org/1999/xhtml");var o=t.label;switch(typeof o){case"function":l.insert(o);break;case"object":l.insert((function(){return o}));break;default:l.html(o)}r.bg(l,t.labelStyle),l.style("display","inline-block"),l.style("white-space","nowrap");var a=l.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}},96225:(e,t,n)=>{n.d(t,{$p:()=>d,O1:()=>a,WR:()=>p,bF:()=>o,bg:()=>c});var r=n(37514),l=n(73234);function o(e,t){return!!e.children(t).length}function a(e){return i(e.v)+":"+i(e.w)+":"+i(e.name)}var s=/:/g;function i(e){return e?String(e).replace(s,"\\:"):""}function c(e,t){t&&e.attr("style",t)}function d(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function p(e,t){var n=t.graph();if(r.Z(n)){var o=n.transition;if(l.Z(o))return o(e)}return e}},18371:(e,t,n)=>{n.d(t,{diagram:()=>a});var r=n(75254),l=n(38621),o=n(56363);n(64218),n(45625),n(41644),n(39354),n(27484),n(17967),n(27856);const a={parser:r.p,db:r.f,renderer:l.f,styles:l.a,init:e=>{e.flowchart||(e.flowchart={}),e.flowchart.arrowMarkerAbsolute=e.arrowMarkerAbsolute,(0,o.p)({flowchart:{arrowMarkerAbsolute:e.arrowMarkerAbsolute}}),l.f.setConf(e.flowchart),r.f.clear(),r.f.setGen("gen-2")}}},38621:(e,t,n)=>{n.d(t,{a:()=>h,f:()=>u});var r=n(45625),l=n(64218),o=n(56363),a=n(90360),s=n(43349),i=n(61691),c=n(71610);const d=(e,t)=>i.Z.lang.round(c.Z.parse(e)[t]);var p=n(51117);const b={},w=function(e,t,n,r,l,a){const i=r.select(`[id="${n}"]`);Object.keys(e).forEach((function(n){const r=e[n];let c="default";r.classes.length>0&&(c=r.classes.join(" ")),c+=" flowchart-label";const d=(0,o.k)(r.styles);let p,b=void 0!==r.text?r.text:r.id;if(o.l.info("vertex",r,r.labelType),"markdown"===r.labelType)o.l.info("vertex",r,r.labelType);else if((0,o.m)((0,o.c)().flowchart.htmlLabels)){const e={label:b.replace(/fa[blrs]?:fa-[\w-]+/g,(e=>`<i class='${e.replace(":"," ")}'></i>`))};p=(0,s.a)(i,e).node(),p.parentNode.removeChild(p)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",d.labelStyle.replace("color:","fill:"));const t=b.split(o.e.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}p=e}let w=0,f="";switch(r.type){case"round":w=5,f="rect";break;case"square":case"group":default:f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":case"odd_right":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"doublecircle":f="doublecircle"}t.setNode(r.id,{labelStyle:d.labelStyle,shape:f,labelText:b,labelType:r.labelType,rx:w,ry:w,class:c,style:d.style,id:r.id,link:r.link,linkTarget:r.linkTarget,tooltip:a.db.getTooltip(r.id)||"",domId:a.db.lookUpDomId(r.id),haveCallback:r.haveCallback,width:"group"===r.type?500:void 0,dir:r.dir,type:r.type,props:r.props,padding:(0,o.c)().flowchart.padding}),o.l.info("setNode",{labelStyle:d.labelStyle,labelType:r.labelType,shape:f,labelText:b,rx:w,ry:w,class:c,style:d.style,id:r.id,domId:a.db.lookUpDomId(r.id),width:"group"===r.type?500:void 0,type:r.type,dir:r.dir,props:r.props,padding:(0,o.c)().flowchart.padding})}))},f=function(e,t,n){o.l.info("abc78 edges = ",e);let r,a,s=0,i={};if(void 0!==e.defaultStyle){const t=(0,o.k)(e.defaultStyle);r=t.style,a=t.labelStyle}e.forEach((function(n){s++;const c="L-"+n.start+"-"+n.end;void 0===i[c]?(i[c]=0,o.l.info("abc78 new entry",c,i[c])):(i[c]++,o.l.info("abc78 new entry",c,i[c]));let d=c+"-"+i[c];o.l.info("abc78 new link id to be used is",c,d,i[c]);const p="LS-"+n.start,w="LE-"+n.end,f={style:"",labelStyle:""};switch(f.minlen=n.length||1,"arrow_open"===n.type?f.arrowhead="none":f.arrowhead="normal",f.arrowTypeStart="arrow_open",f.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":f.arrowTypeStart="arrow_cross";case"arrow_cross":f.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":f.arrowTypeStart="arrow_point";case"arrow_point":f.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":f.arrowTypeStart="arrow_circle";case"arrow_circle":f.arrowTypeEnd="arrow_circle"}let u="",h="";switch(n.stroke){case"normal":u="fill:none;",void 0!==r&&(u=r),void 0!==a&&(h=a),f.thickness="normal",f.pattern="solid";break;case"dotted":f.thickness="normal",f.pattern="dotted",f.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":f.thickness="thick",f.pattern="solid",f.style="stroke-width: 3.5px;fill:none;";break;case"invisible":f.thickness="invisible",f.pattern="solid",f.style="stroke-width: 0;fill:none;"}if(void 0!==n.style){const e=(0,o.k)(n.style);u=e.style,h=e.labelStyle}f.style=f.style+=u,f.labelStyle=f.labelStyle+=h,void 0!==n.interpolate?f.curve=(0,o.n)(n.interpolate,l.c_6):void 0!==e.defaultInterpolate?f.curve=(0,o.n)(e.defaultInterpolate,l.c_6):f.curve=(0,o.n)(b.curve,l.c_6),void 0===n.text?void 0!==n.style&&(f.arrowheadStyle="fill: #333"):(f.arrowheadStyle="fill: #333",f.labelpos="c"),f.labelType=n.labelType,f.label=n.text.replace(o.e.lineBreakRegex,"\n"),void 0===n.style&&(f.style=f.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),f.labelStyle=f.labelStyle.replace("color:","fill:"),f.id=d,f.classes="flowchart-link "+p+" "+w,t.setEdge(n.start,n.end,f,s)}))},u={setConf:function(e){const t=Object.keys(e);for(const n of t)b[n]=e[n]},addVertices:w,addEdges:f,getClasses:function(e,t){return t.db.getClasses()},draw:async function(e,t,n,s){o.l.info("Drawing flowchart");let i=s.db.getDirection();void 0===i&&(i="TD");const{securityLevel:c,flowchart:d}=(0,o.c)(),p=d.nodeSpacing||50,b=d.rankSpacing||50;let u;"sandbox"===c&&(u=(0,l.Ys)("#i"+t));const h="sandbox"===c?(0,l.Ys)(u.nodes()[0].contentDocument.body):(0,l.Ys)("body"),g="sandbox"===c?u.nodes()[0].contentDocument:document,y=new r.k({multigraph:!0,compound:!0}).setGraph({rankdir:i,nodesep:p,ranksep:b,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let k;const x=s.db.getSubGraphs();o.l.info("Subgraphs - ",x);for(let r=x.length-1;r>=0;r--)k=x[r],o.l.info("Subgraph - ",k),s.db.addVertex(k.id,{text:k.title,type:k.labelType},"group",void 0,k.classes,k.dir);const v=s.db.getVertices(),m=s.db.getEdges();o.l.info("Edges",m);let S=0;for(S=x.length-1;S>=0;S--){k=x[S],(0,l.td_)("cluster").append("text");for(let e=0;e<k.nodes.length;e++)o.l.info("Setting up subgraphs",k.nodes[e],k.id),y.setParent(k.nodes[e],k.id)}w(v,y,t,h,g,s),f(m,y);const T=h.select(`[id="${t}"]`),_=h.select("#"+t+" g");if(await(0,a.r)(_,y,["point","circle","cross"],"flowchart",t),o.u.insertTitle(T,"flowchartTitleText",d.titleTopMargin,s.db.getDiagramTitle()),(0,o.o)(y,T,d.diagramPadding,d.useMaxWidth),s.db.indexNodes("subGraph"+S),!d.htmlLabels){const e=g.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of e){const e=t.getBBox(),n=g.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("rx",0),n.setAttribute("ry",0),n.setAttribute("width",e.width),n.setAttribute("height",e.height),t.insertBefore(n,t.firstChild)}}Object.keys(v).forEach((function(e){const n=v[e];if(n.link){const r=(0,l.Ys)("#"+t+' [id="'+e+'"]');if(r){const e=g.createElementNS("http://www.w3.org/2000/svg","a");e.setAttributeNS("http://www.w3.org/2000/svg","class",n.classes.join(" ")),e.setAttributeNS("http://www.w3.org/2000/svg","href",n.link),e.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),"sandbox"===c?e.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):n.linkTarget&&e.setAttributeNS("http://www.w3.org/2000/svg","target",n.linkTarget);const t=r.insert((function(){return e}),":first-child"),l=r.select(".label-container");l&&t.append((function(){return l.node()}));const o=r.select(".label");o&&t.append((function(){return o.node()}))}}}))}},h=e=>`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=d,r=n(e,"r"),l=n(e,"g"),o=n(e,"b");return p.Z(r,l,o,t)})(e.edgeLabelBackground,.5)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`}}]); \ No newline at end of file diff --git a/assets/js/8687.c0c746b9.js b/assets/js/8687.c0c746b9.js new file mode 100644 index 000000000..c61c68c40 --- /dev/null +++ b/assets/js/8687.c0c746b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8687],{78687:(t,i,e)=>{e.d(i,{diagram:()=>O});var s=e(56363),n=e(74697),a=e(64218),h=(e(27484),e(17967),e(27856),function(){var t=function(t,i,e,s){for(e=e||{},s=t.length;s--;e[t[s]]=i);return e},i=[1,10,12,14,16,18,19,21,23],e=[2,6],s=[1,3],n=[1,5],a=[1,6],h=[1,7],o=[1,5,10,12,14,16,18,19,21,23,34,35,36],r=[1,25],l=[1,26],c=[1,28],g=[1,29],u=[1,30],x=[1,31],d=[1,32],p=[1,33],f=[1,34],y=[1,35],m=[1,36],b=[1,37],A=[1,43],w=[1,42],S=[1,47],C=[1,50],k=[1,10,12,14,16,18,19,21,23,34,35,36],_=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],T=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],R=[1,64],D={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:function(t,i,e,s,n,a,h){var o=a.length-1;switch(n){case 5:s.setOrientation(a[o]);break;case 9:s.setDiagramTitle(a[o].text.trim());break;case 12:s.setLineData({text:"",type:"text"},a[o]);break;case 13:s.setLineData(a[o-1],a[o]);break;case 14:s.setBarData({text:"",type:"text"},a[o]);break;case 15:s.setBarData(a[o-1],a[o]);break;case 16:this.$=a[o].trim(),s.setAccTitle(this.$);break;case 17:case 18:this.$=a[o].trim(),s.setAccDescription(this.$);break;case 19:case 27:this.$=a[o-1];break;case 20:this.$=[Number(a[o-2]),...a[o]];break;case 21:this.$=[Number(a[o])];break;case 22:s.setXAxisTitle(a[o]);break;case 23:s.setXAxisTitle(a[o-1]);break;case 24:s.setXAxisTitle({type:"text",text:""});break;case 25:s.setXAxisBand(a[o]);break;case 26:s.setXAxisRangeData(Number(a[o-2]),Number(a[o]));break;case 28:this.$=[a[o-2],...a[o]];break;case 29:this.$=[a[o]];break;case 30:s.setYAxisTitle(a[o]);break;case 31:s.setYAxisTitle(a[o-1]);break;case 32:s.setYAxisTitle({type:"text",text:""});break;case 33:s.setYAxisRangeData(Number(a[o-2]),Number(a[o]));break;case 37:case 38:this.$={text:a[o],type:"text"};break;case 39:this.$={text:a[o],type:"markdown"};break;case 40:this.$=a[o];break;case 41:this.$=a[o-1]+""+a[o]}},table:[t(i,e,{3:1,4:2,7:4,5:s,34:n,35:a,36:h}),{1:[3]},t(i,e,{4:2,7:4,3:8,5:s,34:n,35:a,36:h}),t(i,e,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:a,36:h}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(o,[2,34]),t(o,[2,35]),t(o,[2,36]),{1:[2,1]},t(i,e,{4:2,7:4,3:21,5:s,34:n,35:a,36:h}),{1:[2,3]},t(o,[2,5]),t(i,[2,7],{4:22,34:n,35:a,36:h}),{11:23,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:39,13:38,24:A,27:w,29:40,30:41,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:45,15:44,27:S,33:46,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:49,17:48,24:C,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{11:52,17:51,24:C,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},{20:[1,53]},{22:[1,54]},t(k,[2,18]),{1:[2,2]},t(k,[2,8]),t(k,[2,9]),t(_,[2,37],{40:55,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b}),t(_,[2,38]),t(_,[2,39]),t(T,[2,40]),t(T,[2,42]),t(T,[2,43]),t(T,[2,44]),t(T,[2,45]),t(T,[2,46]),t(T,[2,47]),t(T,[2,48]),t(T,[2,49]),t(T,[2,50]),t(T,[2,51]),t(k,[2,10]),t(k,[2,22],{30:41,29:56,24:A,27:w}),t(k,[2,24]),t(k,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},t(k,[2,11]),t(k,[2,30],{33:60,27:S}),t(k,[2,32]),{31:[1,61]},t(k,[2,12]),{17:62,24:C},{25:63,27:R},t(k,[2,14]),{17:65,24:C},t(k,[2,16]),t(k,[2,17]),t(T,[2,41]),t(k,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},t(k,[2,31]),{27:[1,69]},t(k,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},t(k,[2,15]),t(k,[2,26]),t(k,[2,27]),{11:59,32:72,37:24,38:r,39:l,40:27,41:c,42:g,43:u,44:x,45:d,46:p,47:f,48:y,49:m,50:b},t(k,[2,33]),t(k,[2,19]),{25:73,27:R},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},parse:function(t){var i=this,e=[0],s=[],n=[null],a=[],h=this.table,o="",r=0,l=0,c=a.slice.call(arguments,1),g=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);g.setInput(t,u.yy),u.yy.lexer=g,u.yy.parser=this,void 0===g.yylloc&&(g.yylloc={});var d=g.yylloc;a.push(d);var p=g.options&&g.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,y,m,b,A,w,S,C,k,_={};;){if(y=e[e.length-1],this.defaultActions[y]?m=this.defaultActions[y]:(null==f&&(k=void 0,"number"!=typeof(k=s.pop()||g.lex()||1)&&(k instanceof Array&&(k=(s=k).pop()),k=i.symbols_[k]||k),f=k),m=h[y]&&h[y][f]),void 0===m||!m.length||!m[0]){var T="";for(A in C=[],h[y])this.terminals_[A]&&A>2&&C.push("'"+this.terminals_[A]+"'");T=g.showPosition?"Parse error on line "+(r+1)+":\n"+g.showPosition()+"\nExpecting "+C.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(r+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(T,{text:g.match,token:this.terminals_[f]||f,line:g.yylineno,loc:d,expected:C})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+y+", token: "+f);switch(m[0]){case 1:e.push(f),n.push(g.yytext),a.push(g.yylloc),e.push(m[1]),f=null,l=g.yyleng,o=g.yytext,r=g.yylineno,d=g.yylloc;break;case 2:if(w=this.productions_[m[1]][1],_.$=n[n.length-w],_._$={first_line:a[a.length-(w||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(w||1)].first_column,last_column:a[a.length-1].last_column},p&&(_._$.range=[a[a.length-(w||1)].range[0],a[a.length-1].range[1]]),void 0!==(b=this.performAction.apply(_,[o,l,r,u.yy,m[1],n,a].concat(c))))return b;w&&(e=e.slice(0,-1*w*2),n=n.slice(0,-1*w),a=a.slice(0,-1*w)),e.push(this.productions_[m[1]][0]),n.push(_.$),a.push(_._$),S=h[e[e.length-2]][e[e.length-1]],e.push(S);break;case 3:return!0}}return!0}},L={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===s.length?this.yylloc.first_column:0)+s[s.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"},test_match:function(t,i){var e,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in n)this[a]=n[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),a=0;a<n.length;a++)if((e=this._input.match(this.rules[n[a]]))&&(!i||e[0].length>i[0].length)){if(i=e,s=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[a])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,s){switch(e){case 0:case 1:case 5:case 43:break;case 2:case 3:return this.popState(),34;case 4:return 34;case 6:return 10;case 7:return this.pushState("acc_title"),19;case 8:return this.popState(),"acc_title_value";case 9:return this.pushState("acc_descr"),21;case 10:return this.popState(),"acc_descr_value";case 11:this.pushState("acc_descr_multiline");break;case 12:case 25:case 27:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 5;case 15:return 8;case 16:return this.pushState("axis_data"),"X_AXIS";case 17:return this.pushState("axis_data"),"Y_AXIS";case 18:return this.pushState("axis_band_data"),24;case 19:return 31;case 20:return this.pushState("data"),16;case 21:return this.pushState("data"),18;case 22:return this.pushState("data_inner"),24;case 23:return 27;case 24:return this.popState(),26;case 26:this.pushState("string");break;case 28:return"STR";case 29:return 24;case 30:return 26;case 31:return 43;case 32:return"COLON";case 33:return 44;case 34:return 28;case 35:return 45;case 36:return 46;case 37:return 48;case 38:return 50;case 39:return 47;case 40:return 41;case 41:return 49;case 42:return 42;case 44:return 35;case 45:return 36}},rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\{)/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n<md_string>\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n<md_string>\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,23,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,20,21,22,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,23,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[27,28],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0}}};function P(){this.yy={}}return D.lexer=L,P.prototype=D,D.Parser=P,new P}());h.parser=h;const o=h;function r(t){return"bar"===t.type}function l(t){return"band"===t.type}function c(t){return"linear"===t.type}class g{constructor(t){this.parentGroup=t}getMaxDimension(t,i){if(!this.parentGroup)return{width:t.reduce(((t,i)=>Math.max(i.length,t)),0)*i,height:i};const e={width:0,height:0},s=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",i);for(const a of t){const t=(0,n.c)(s,1,a),h=t?t.width:a.length*i,o=t?t.height:i;e.width=Math.max(e.width,h),e.height=Math.max(e.height,o)}return s.remove(),e}}class u{constructor(t,i,e,s){this.axisConfig=t,this.title=i,this.textDimensionCalculator=e,this.axisThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left",this.showTitle=!1,this.showLabel=!1,this.showTick=!1,this.showAxisLine=!1,this.outerPadding=0,this.titleTextHeight=0,this.labelTextHeight=0,this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left"}setRange(t){this.range=t,"left"===this.axisPosition||"right"===this.axisPosition?this.boundingRect.height=t[1]-t[0]:this.boundingRect.width=t[1]-t[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(t){this.axisPosition=t,this.setRange(this.range)}getTickDistance(){const t=this.getRange();return Math.abs(t[0]-t[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map((t=>t.toString())),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){.7*this.getTickDistance()>2*this.outerPadding&&(this.outerPadding=Math.floor(.7*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(t){let i=t.height;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.width;this.outerPadding=Math.min(e.width/2,s);const n=e.height+2*this.axisConfig.labelPadding;this.labelTextHeight=e.height,n<=i&&(i-=n,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width,this.boundingRect.height=t.height-i}calculateSpaceIfDrawnVertical(t){let i=t.width;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.height;this.outerPadding=Math.min(e.height/2,s);const n=e.width+2*this.axisConfig.labelPadding;n<=i&&(i-=n,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width-i,this.boundingRect.height=t.height}calculateSpace(t){return"left"===this.axisPosition||"right"===this.axisPosition?this.calculateSpaceIfDrawnVertical(t):this.calculateSpaceIfDrawnHorizontally(t),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}getDrawableElementsForLeftAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${i},${this.boundingRect.y} L ${i},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(t),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"})))}),this.showTick){const i=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${i},${this.getScaleValue(t)} L ${i-this.axisConfig.tickLength},${this.getScaleValue(t)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForBottomAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"})))}),this.showTick){const i=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${this.getScaleValue(t)},${i} L ${this.getScaleValue(t)},${i+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForTopAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+2*this.axisConfig.titlePadding:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"})))}),this.showTick){const i=this.boundingRect.y;t.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${this.getScaleValue(t)},${i+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(t)},${i+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElements(){if("left"===this.axisPosition)return this.getDrawableElementsForLeftAxis();if("right"===this.axisPosition)throw Error("Drawing of right axis is not implemented");return"bottom"===this.axisPosition?this.getDrawableElementsForBottomAxis():"top"===this.axisPosition?this.getDrawableElementsForTopAxis():[]}}class x extends u{constructor(t,i,e,s,n){super(t,s,n,i),this.categories=e,this.scale=(0,a.tiA)().domain(this.categories).range(this.getRange())}setRange(t){super.setRange(t)}recalculateScale(){this.scale=(0,a.tiA)().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),s.l.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(t){return this.scale(t)||this.getRange()[0]}}class d extends u{constructor(t,i,e,s,n){super(t,s,n,i),this.domain=e,this.scale=(0,a.BYU)().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){const t=[...this.domain];"left"===this.axisPosition&&t.reverse(),this.scale=(0,a.BYU)().domain(t).range(this.getRange())}getScaleValue(t){return this.scale(t)}}function p(t,i,e,s){const n=new g(s);return l(t)?new x(i,e,t.categories,t.title,n):new d(i,e,[t.min,t.max],t.title,n)}class f{constructor(t,i,e,s){this.textDimensionCalculator=t,this.chartConfig=i,this.chartData=e,this.chartThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){const i=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),e=Math.max(i.width,t.width),s=i.height+2*this.chartConfig.titlePadding;return i.width<=e&&i.height<=s&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=e,this.boundingRect.height=s,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){const t=[];return this.showChartTitle&&t.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),t}}function y(t,i,e,s){const n=new g(s);return new f(n,t,i,e)}class m{constructor(t,i,e,s,n){this.plotData=t,this.xAxis=i,this.yAxis=e,this.orientation=s,this.plotIndex=n}getDrawableElement(){const t=this.plotData.data.map((t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])]));let i;return i="horizontal"===this.orientation?(0,a.jvg)().y((t=>t[0])).x((t=>t[1]))(t):(0,a.jvg)().x((t=>t[0])).y((t=>t[1]))(t),i?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:i,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}}class b{constructor(t,i,e,s,n,a){this.barData=t,this.boundingRect=i,this.xAxis=e,this.yAxis=s,this.orientation=n,this.plotIndex=a}getDrawableElement(){const t=this.barData.data.map((t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])])),i=.95*Math.min(2*this.xAxis.getAxisOuterPadding(),this.xAxis.getTickDistance()),e=i/2;return"horizontal"===this.orientation?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map((t=>({x:this.boundingRect.x,y:t[0]-e,height:i,width:t[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill})))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map((t=>({x:t[0]-e,y:t[1],width:i,height:this.boundingRect.y+this.boundingRect.height-t[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill})))}]}}class A{constructor(t,i,e){this.chartConfig=t,this.chartData=i,this.chartThemeConfig=e,this.boundingRect={x:0,y:0,width:0,height:0}}setAxes(t,i){this.xAxis=t,this.yAxis=i}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){return this.boundingRect.width=t.width,this.boundingRect.height=t.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!this.xAxis||!this.yAxis)throw Error("Axes must be passed to render Plots");const t=[];for(const[i,e]of this.chartData.plots.entries())switch(e.type){case"line":{const s=new m(e,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}break;case"bar":{const s=new b(e,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}}return t}}function w(t,i,e){return new A(t,i,e)}class S{constructor(t,i,e,s){this.chartConfig=t,this.chartData=i,this.componentStore={title:y(t,i,e,s),plot:w(t,i,e),xAxis:p(i.xAxis,t.xAxis,{titleColor:e.xAxisTitleColor,labelColor:e.xAxisLabelColor,tickColor:e.xAxisTickColor,axisLineColor:e.xAxisLineColor},s),yAxis:p(i.yAxis,t.yAxis,{titleColor:e.yAxisTitleColor,labelColor:e.yAxisLabelColor,tickColor:e.yAxisTickColor,axisLineColor:e.yAxisLineColor},s)}}calculateVerticalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,n=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),a=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),h=this.componentStore.plot.calculateSpace({width:n,height:a});t-=h.width,i-=h.height,h=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),s=h.height,i-=h.height,this.componentStore.xAxis.setAxisPosition("bottom"),h=this.componentStore.xAxis.calculateSpace({width:t,height:i}),i-=h.height,this.componentStore.yAxis.setAxisPosition("left"),h=this.componentStore.yAxis.calculateSpace({width:t,height:i}),e=h.width,t-=h.width,t>0&&(n+=t,t=0),i>0&&(a+=i,i=0),this.componentStore.plot.calculateSpace({width:n,height:a}),this.componentStore.plot.setBoundingBoxXY({x:e,y:s}),this.componentStore.xAxis.setRange([e,e+n]),this.componentStore.xAxis.setBoundingBoxXY({x:e,y:s+a}),this.componentStore.yAxis.setRange([s,s+a]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:s}),this.chartData.plots.some((t=>r(t)))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizonatalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,n=0,a=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),h=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),o=this.componentStore.plot.calculateSpace({width:a,height:h});t-=o.width,i-=o.height,o=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),e=o.height,i-=o.height,this.componentStore.xAxis.setAxisPosition("left"),o=this.componentStore.xAxis.calculateSpace({width:t,height:i}),t-=o.width,s=o.width,this.componentStore.yAxis.setAxisPosition("top"),o=this.componentStore.yAxis.calculateSpace({width:t,height:i}),i-=o.height,n=e+o.height,t>0&&(a+=t,t=0),i>0&&(h+=i,i=0),this.componentStore.plot.calculateSpace({width:a,height:h}),this.componentStore.plot.setBoundingBoxXY({x:s,y:n}),this.componentStore.yAxis.setRange([s,s+a]),this.componentStore.yAxis.setBoundingBoxXY({x:s,y:e}),this.componentStore.xAxis.setRange([n,n+h]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:n}),this.chartData.plots.some((t=>r(t)))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){"horizontal"===this.chartConfig.chartOrientation?this.calculateHorizonatalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();const t=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(const i of Object.values(this.componentStore))t.push(...i.getDrawableElements());return t}}class C{static build(t,i,e,s){return new S(t,i,e,s).getDrawableElement()}}let k,_=0,T=I(),R=v(),D=M(),L=R.plotColorPalette.split(",").map((t=>t.trim())),P=!1,E=!1;function v(){const t=(0,s.D)(),i=(0,s.E)();return(0,s.B)(t.xyChart,i.themeVariables.xyChart)}function I(){const t=(0,s.E)();return(0,s.B)(s.A.xyChart,t.xyChart)}function M(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function $(t){const i=(0,s.E)();return(0,s.d)(t.trim(),i)}function B(t,i){D.xAxis={type:"linear",title:D.xAxis.title,min:t,max:i},P=!0}function z(t){let i=[];if(0===t.length)return i;if(!P){const i=c(D.xAxis)?D.xAxis.min:1/0,e=c(D.xAxis)?D.xAxis.max:-1/0;B(Math.min(i,1),Math.max(e,t.length))}if(E||function(t){const i=Math.min(...t),e=Math.max(...t),s=c(D.yAxis)?D.yAxis.min:1/0,n=c(D.yAxis)?D.yAxis.max:-1/0;D.yAxis={type:"linear",title:D.yAxis.title,min:Math.min(s,i),max:Math.max(n,e)}}(t),l(D.xAxis)&&(i=D.xAxis.categories.map(((i,e)=>[i,t[e]]))),c(D.xAxis)){const e=D.xAxis.min,s=D.xAxis.max,n=(s-e+1)/t.length,a=[];for(let t=e;t<=s;t+=n)a.push(`${t}`);i=a.map(((i,e)=>[i,t[e]]))}return i}function W(t){return L[0===t?0:t%L.length]}const O={parser:o,db:{getDrawableElem:function(){if(0===D.plots.length)throw Error("No Plot to render, please provide a plot with some data");return D.title=(0,s.r)(),C.build(T,D,R,k)},clear:function(){(0,s.t)(),_=0,T=I(),D={yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]},R=v(),L=R.plotColorPalette.split(",").map((t=>t.trim())),P=!1,E=!1},setAccTitle:s.s,getAccTitle:s.g,setDiagramTitle:s.q,getDiagramTitle:s.r,getAccDescription:s.a,setAccDescription:s.b,setOrientation:function(t){T.chartOrientation="horizontal"===t?"horizontal":"vertical"},setXAxisTitle:function(t){D.xAxis.title=$(t.text)},setXAxisRangeData:B,setXAxisBand:function(t){D.xAxis={type:"band",title:D.xAxis.title,categories:t.map((t=>$(t.text)))},P=!0},setYAxisTitle:function(t){D.yAxis.title=$(t.text)},setYAxisRangeData:function(t,i){D.yAxis={type:"linear",title:D.yAxis.title,min:t,max:i},E=!0},setLineData:function(t,i){const e=z(i);D.plots.push({type:"line",strokeFill:W(_),strokeWidth:2,data:e}),_++},setBarData:function(t,i){const e=z(i);D.plots.push({type:"bar",fill:W(_),data:e}),_++},setTmpSVGG:function(t){k=t},getChartThemeConfig:function(){return R},getChartConfig:function(){return T}},renderer:{draw:(t,i,e,n)=>{const a=n.db,h=a.getChartThemeConfig(),o=a.getChartConfig();function r(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}s.l.debug("Rendering xychart chart\n"+t);const l=(0,s.z)(i),c=l.append("g").attr("class","main"),g=c.append("rect").attr("width",o.width).attr("height",o.height).attr("class","background");(0,s.i)(l,o.height,o.width,!0),l.attr("viewBox",`0 0 ${o.width} ${o.height}`),g.attr("fill",h.backgroundColor),a.setTmpSVGG(l.append("g").attr("class","mermaid-tmp-group"));const u=a.getDrawableElem(),x={};function d(t){let i=c,e="";for(const[s]of t.entries()){let n=c;s>0&&x[e]&&(n=x[e]),e+=t[s],i=x[e],i||(i=x[e]=n.append("g").attr("class",t[s]))}return i}for(const s of u){if(0===s.data.length)continue;const t=d(s.groupTexts);switch(s.type){case"rect":t.selectAll("rect").data(s.data).enter().append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)).attr("stroke",(t=>t.strokeFill)).attr("stroke-width",(t=>t.strokeWidth));break;case"text":t.selectAll("text").data(s.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>"top"===t.verticalPos?"text-before-edge":"middle")).attr("text-anchor",(t=>{return"left"===(i=t.horizontalPos)?"start":"right"===i?"end":"middle";var i})).attr("transform",(t=>r(t))).text((t=>t.text));break;case"path":t.selectAll("path").data(s.data).enter().append("path").attr("d",(t=>t.path)).attr("fill",(t=>t.fill?t.fill:"none")).attr("stroke",(t=>t.strokeFill)).attr("stroke-width",(t=>t.strokeWidth))}}}}}}}]); \ No newline at end of file diff --git a/assets/js/86b4da3d.3bc777bd.js b/assets/js/86b4da3d.ecad1fac.js similarity index 77% rename from assets/js/86b4da3d.3bc777bd.js rename to assets/js/86b4da3d.ecad1fac.js index 0c9fd5985..28b6d6d83 100644 --- a/assets/js/86b4da3d.3bc777bd.js +++ b/assets/js/86b4da3d.ecad1fac.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[952],{44149:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[952],{44149:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/87070fc3.407d5246.js b/assets/js/87070fc3.407d5246.js new file mode 100644 index 000000000..c2713fcaa --- /dev/null +++ b/assets/js/87070fc3.407d5246.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6124],{4679:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>p,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var n=r(85893),s=r(3905);const c={title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",slug:"/performance/types",last_update:{date:"2023/08/30"},tags:["performance","test"]},a=void 0,i={id:"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8",title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",description:"| \ud14c\uc2a4\ud2b8 | \uc124\uba85 |",source:"@site/docs/\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",sourceDirName:"\uc131\ub2a5",slug:"/performance/types",permalink:"/docs/performance/types",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",tags:[{label:"performance",permalink:"/docs/tags/performance"},{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1693353600,formattedLastUpdatedAt:"2023\ub144 8\uc6d4 30\uc77c",frontMatter:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",slug:"/performance/types",last_update:{date:"2023/08/30"},tags:["performance","test"]},sidebar:"tutorialSidebar",previous:{title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",permalink:"/docs/performance/throughput-latency"},next:{title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",permalink:"/docs/spring/essence"}},o={},d=[{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function l(e){const t={h3:"h3",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"\ud14c\uc2a4\ud2b8"}),(0,n.jsx)(t.th,{children:"\uc124\uba85"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"\uc9c0\uc5f0 \ud14c\uc2a4\ud2b8(latency test)"}),(0,n.jsx)(t.td,{children:"\uc694\uccad\uc5d0 \ub300\ud55c \uc751\ub2f5 \uc2dc\uac04\uc744 \uce21\uc815"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"\ucc98\ub9ac\uc728 \ud14c\uc2a4\ud2b8(throughput test)"}),(0,n.jsx)(t.td,{children:"\uc2dc\uc2a4\ud15c \uc131\ub2a5\uc774 \uae09\ub77d\ud558\uae30 \uc9c1\uc804, \ucd5c\ub300 \ucc98\ub9ac\uc728 \uc218\uce58\ub97c \uce21\uc815"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"\ubd80\ud558 \ud14c\uc2a4\ud2b8(load test)"}),(0,n.jsx)(t.td,{children:"\ube44\uc988\ub2c8\uc2a4 \uc774\ubca4\ud2b8\ub97c \ub300\ube44\ud574 \ud2b8\ub798\ud53d\uc744 \uacac\ub51c \uc218 \uc788\ub294\uc9c0 \ud655\uc778"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(stress test)"}),(0,n.jsx)(t.td,{children:"\uc2dc\uc2a4\ud15c\uc758 \ud55c\uacc4\uc810\uc744 \ud655\uc778"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(endurance test)"}),(0,n.jsx)(t.td,{children:"\uc7a5\uc2dc\uac04 \uc2e4\ud589\ud560 \uacbd\uc6b0 \uc131\ub2a5 \uc774\uc0c1\uc774 \ubc1c\uc0dd\ud558\ub294\uc9c0 \ud655\uc778"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"\uc6a9\ub7c9 \uacc4\ud68d \ud14c\uc2a4\ud2b8(capacity planning test)"}),(0,n.jsx)(t.td,{children:"\ub9ac\uc18c\uc2a4\ub97c \ucd94\uac00\ud55c \ub9cc\ud07c \uc2dc\uc2a4\ud15c\uc774 \ud655\uc7a5\ub418\ub294\uc9c0 \ud655\uc778"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"\uc800\ud558 \ud14c\uc2a4\ud2b8(degradation test)"}),(0,n.jsx)(t.td,{children:"\uc2dc\uc2a4\ud15c\uc774 \ubd80\ubd84\uc801\uc73c\ub85c \uc2e4\ud328\ud560 \uacbd\uc6b0 \uc5b4\ub5a4 \uc77c\uc774 \ubc1c\uc0dd\ud558\ub294\uc9c0 \ud655\uc778(\uc7a5\uc560 \ubcf5\uad6c \ubc0f \ud68c\ubcf5 \ub4f1)"})]})]})]}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsx)(t.p,{children:"\uc790\ubc14 \ucd5c\uc801\ud654 - \ubca4\uc800\ubbfc J. \uc5d0\ubc88\uc2a4, \uc81c\uc784\uc2a4 \uace0\ud504, \ud06c\ub9ac\uc2a4 \ub274\ub79c\ub4dc"})]})}function p(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>d});var n=r(67294);function s(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?c(Object(r),!0).forEach((function(t){s(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):c(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,n,s=function(e,t){if(null==e)return{};var r,n,s={},c=Object.keys(e);for(n=0;n<c.length;n++)r=c[n],t.indexOf(r)>=0||(s[r]=e[r]);return s}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(n=0;n<c.length;n++)r=c[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var o=n.createContext({}),d=function(e){var t=n.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},l={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,s=e.mdxType,c=e.originalType,o=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),h=d(r),u=s,f=h["".concat(o,".").concat(u)]||h[u]||l[u]||c;return r?n.createElement(f,a(a({ref:t},p),{},{components:r})):n.createElement(f,a({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/87070fc3.d725d20f.js b/assets/js/87070fc3.d725d20f.js deleted file mode 100644 index 0b96787f5..000000000 --- a/assets/js/87070fc3.d725d20f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6124],{3905:(t,e,r)=>{r.d(e,{Zo:()=>s,kt:()=>d});var n=r(67294);function a(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function l(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function o(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?l(Object(r),!0).forEach((function(e){a(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}function p(t,e){if(null==t)return{};var r,n,a=function(t,e){if(null==t)return{};var r,n,a={},l=Object.keys(t);for(n=0;n<l.length;n++)r=l[n],e.indexOf(r)>=0||(a[r]=t[r]);return a}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)r=l[n],e.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(a[r]=t[r])}return a}var i=n.createContext({}),c=function(t){var e=n.useContext(i),r=e;return t&&(r="function"==typeof t?t(e):o(o({},e),t)),r},s=function(t){var e=c(t.components);return n.createElement(i.Provider,{value:e},t.children)},u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},m=n.forwardRef((function(t,e){var r=t.components,a=t.mdxType,l=t.originalType,i=t.parentName,s=p(t,["components","mdxType","originalType","parentName"]),m=c(r),d=a,f=m["".concat(i,".").concat(d)]||m[d]||u[d]||l;return r?n.createElement(f,o(o({ref:e},s),{},{components:r})):n.createElement(f,o({ref:e},s))}));function d(t,e){var r=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var l=r.length,o=new Array(l);o[0]=m;var p={};for(var i in e)hasOwnProperty.call(e,i)&&(p[i]=e[i]);p.originalType=t,p.mdxType="string"==typeof t?t:a,o[1]=p;for(var c=2;c<l;c++)o[c]=r[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},74161:(t,e,r)=>{r.r(e),r.d(e,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",slug:"/performance/types",last_update:{date:"2023/08/30"},tags:["performance","test"]},o=void 0,p={unversionedId:"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8",id:"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8",title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",description:"| \ud14c\uc2a4\ud2b8 | \uc124\uba85 |",source:"@site/docs/\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",sourceDirName:"\uc131\ub2a5",slug:"/performance/types",permalink:"/docs/performance/types",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",tags:[{label:"performance",permalink:"/docs/tags/performance"},{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1693353600,formattedLastUpdatedAt:"2023\ub144 8\uc6d4 30\uc77c",frontMatter:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",slug:"/performance/types",last_update:{date:"2023/08/30"},tags:["performance","test"]},sidebar:"tutorialSidebar",previous:{title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",permalink:"/docs/performance/throughput-latency"},next:{title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",permalink:"/docs/spring/essence"}},i={},c=[{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:c};function u(t){let{components:e,...r}=t;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"\ud14c\uc2a4\ud2b8"),(0,a.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc9c0\uc5f0 \ud14c\uc2a4\ud2b8(latency test)"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc694\uccad\uc5d0 \ub300\ud55c \uc751\ub2f5 \uc2dc\uac04\uc744 \uce21\uc815")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ucc98\ub9ac\uc728 \ud14c\uc2a4\ud2b8(throughput test)"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc2dc\uc2a4\ud15c \uc131\ub2a5\uc774 \uae09\ub77d\ud558\uae30 \uc9c1\uc804, \ucd5c\ub300 \ucc98\ub9ac\uc728 \uc218\uce58\ub97c \uce21\uc815")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ubd80\ud558 \ud14c\uc2a4\ud2b8(load test)"),(0,a.kt)("td",{parentName:"tr",align:null},"\ube44\uc988\ub2c8\uc2a4 \uc774\ubca4\ud2b8\ub97c \ub300\ube44\ud574 \ud2b8\ub798\ud53d\uc744 \uacac\ub51c \uc218 \uc788\ub294\uc9c0 \ud655\uc778")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(stress test)"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc2dc\uc2a4\ud15c\uc758 \ud55c\uacc4\uc810\uc744 \ud655\uc778")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ub0b4\uad6c \ud14c\uc2a4\ud2b8(endurance test)"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc7a5\uc2dc\uac04 \uc2e4\ud589\ud560 \uacbd\uc6b0 \uc131\ub2a5 \uc774\uc0c1\uc774 \ubc1c\uc0dd\ud558\ub294\uc9c0 \ud655\uc778")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc6a9\ub7c9 \uacc4\ud68d \ud14c\uc2a4\ud2b8(capacity planning test)"),(0,a.kt)("td",{parentName:"tr",align:null},"\ub9ac\uc18c\uc2a4\ub97c \ucd94\uac00\ud55c \ub9cc\ud07c \uc2dc\uc2a4\ud15c\uc774 \ud655\uc7a5\ub418\ub294\uc9c0 \ud655\uc778")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc800\ud558 \ud14c\uc2a4\ud2b8(degradation test)"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc2dc\uc2a4\ud15c\uc774 \ubd80\ubd84\uc801\uc73c\ub85c \uc2e4\ud328\ud560 \uacbd\uc6b0 \uc5b4\ub5a4 \uc77c\uc774 \ubc1c\uc0dd\ud558\ub294\uc9c0 \ud655\uc778(\uc7a5\uc560 \ubcf5\uad6c \ubc0f \ud68c\ubcf5 \ub4f1)")))),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc790\ubc14 \ucd5c\uc801\ud654 - \ubca4\uc800\ubbfc J. \uc5d0\ubc88\uc2a4, \uc81c\uc784\uc2a4 \uace0\ud504, \ud06c\ub9ac\uc2a4 \ub274\ub79c\ub4dc"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8720c147.05a8b5ca.js b/assets/js/8720c147.05a8b5ca.js deleted file mode 100644 index 63592556d..000000000 --- a/assets/js/8720c147.05a8b5ca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[470],{3905:(t,e,a)=>{a.d(e,{Zo:()=>s,kt:()=>k});var n=a(67294);function l(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function r(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?r(Object(a),!0).forEach((function(e){l(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function p(t,e){if(null==t)return{};var a,n,l=function(t,e){if(null==t)return{};var a,n,l={},r=Object.keys(t);for(n=0;n<r.length;n++)a=r[n],e.indexOf(a)>=0||(l[a]=t[a]);return l}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(n=0;n<r.length;n++)a=r[n],e.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(l[a]=t[a])}return l}var u=n.createContext({}),m=function(t){var e=n.useContext(u),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},s=function(t){var e=m(t.components);return n.createElement(u.Provider,{value:e},t.children)},o={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},d=n.forwardRef((function(t,e){var a=t.components,l=t.mdxType,r=t.originalType,u=t.parentName,s=p(t,["components","mdxType","originalType","parentName"]),d=m(a),k=l,c=d["".concat(u,".").concat(k)]||d[k]||o[k]||r;return a?n.createElement(c,i(i({ref:e},s),{},{components:a})):n.createElement(c,i({ref:e},s))}));function k(t,e){var a=arguments,l=e&&e.mdxType;if("string"==typeof t||l){var r=a.length,i=new Array(r);i[0]=d;var p={};for(var u in e)hasOwnProperty.call(e,u)&&(p[u]=e[u]);p.originalType=t,p.mdxType="string"==typeof t?t:l,i[1]=p;for(var m=2;m<r;m++)i[m]=a[m];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}d.displayName="MDXCreateElement"},55810:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>u,contentTitle:()=>i,default:()=>o,frontMatter:()=>r,metadata:()=>p,toc:()=>m});var n=a(87462),l=(a(67294),a(3905));const r={title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",slug:"java-class-file",tags:["Java","Class"]},i=void 0,p={permalink:"/java-class-file",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",source:"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",description:"\ud074\ub798\uc2a4 \ud30c\uc77c",date:"2023-04-03T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 3\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Class",permalink:"/tags/class"}],readingTime:5.63,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",slug:"java-class-file",tags:["Java","Class"]},prevItem:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",permalink:"/test-double"},nextItem:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",permalink:"/custom-jdbc-template"}},u={authorsImageUrls:[]},m=[{value:"\ud074\ub798\uc2a4 \ud30c\uc77c",id:"\ud074\ub798\uc2a4-\ud30c\uc77c",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd",id:"\ud074\ub798\uc2a4-\ud30c\uc77c\uc758-\ub370\uc774\ud130-\ud615\uc2dd",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\uad6c\uc870",level:3},{value:"\ub9e4\uc9c1\ub118\ubc84",id:"\ub9e4\uc9c1\ub118\ubc84",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud3ec\ub9f7-\ubc84\uc804",level:3},{value:"\uc0c1\uc218 \ud480",id:"\uc0c1\uc218-\ud480",level:3},{value:"\uc561\uc138\uc2a4 \ud50c\ub798\uadf8",id:"\uc561\uc138\uc2a4-\ud50c\ub798\uadf8",level:3},{value:"this_class",id:"this_class",level:3},{value:"super_class",id:"super_class",level:3},{value:"interface, field, method",id:"interface-field-method",level:3},{value:"attributes",id:"attributes",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud655\uc778\ud558\uba74\uc11c-\uc0ac\uc6a9\ud55c-\ud234",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:m};function o(t){let{components:e,...a}=t;return(0,l.kt)("wrapper",(0,n.Z)({},s,a,{components:e,mdxType:"MDXLayout"}),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c"},"\ud074\ub798\uc2a4 \ud30c\uc77c"),(0,l.kt)("p",null,"\uc790\ubc14 \uc18c\uc2a4\ucf54\ub4dc\uac00 \uc2e4\ud589\uc774 \ub418\ub824\uba74 \uc790\ubc14 \ucef4\ud30c\uc77c\ub7ec(javac)\ub97c \ud1b5\ud574 \uc18c\uc2a4\ucf54\ub4dc\ub97c \ud074\ub798\uc2a4\ud30c\uc77c\ub85c \ubcc0\ud658\ud574\uc57c \ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ucef4\ud30c\uc77c\ub41c \ud074\ub798\uc2a4\ud30c\uc77c\uc740 \uc5b4\ub5a4 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\uc744\uae4c?"),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c\uc758-\ub370\uc774\ud130-\ud615\uc2dd"},"\ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd"),(0,l.kt)("p",null,"8\ube44\ud2b8 \ubc14\uc774\ud2b8\uc758 \uc2a4\ud2b8\ub9bc\uc73c\ub85c \uad6c\uc131\ub41c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","16\ube44\ud2b8 \ubc0f 32\ube44\ud2b8\uc758 \ub370\uc774\ud130\ub294 \uac01\uac01 2\uac1c, 4\uac1c\uc758 \uc5f0\uc18d\ub41c 8\ube44\ud2b8\ub97c \uc77d\uc5b4\uc11c \uad6c\uc131\ub41c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\uba40\ud2f0\ubc14\uc774\ud2b8\uc758 \uacbd\uc6b0 \ud56d\uc0c1 big endian \uc21c\uc11c\ub85c \uc800\uc7a5\ub41c\ub2e4. "),(0,l.kt)("p",null,"u1 \u2192 unsigned 1byte",(0,l.kt)("br",{parentName:"p"}),"\n","u2 \u2192 unsigned 2byte",(0,l.kt)("br",{parentName:"p"}),"\n","u4 \u2192 unsigned 4byte "),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\uad6c\uc870"},"\ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"ClassFile {\n u4 magic;\n u2 minor_version;\n u2 major_version;\n u2 constant_pool_count;\n cp_info constant_pool[constant_pool_count-1];\n u2 access_flags;\n u2 this_class;\n u2 super_class;\n u2 interfaces_count;\n u2 interfaces[interfaces_count];\n u2 fields_count;\n field_info fields[fields_count];\n u2 methods_count;\n method_info methods[methods_count];\n u2 attributes_count;\n attribute_info attributes[attributes_count];\n}\n")),(0,l.kt)("h3",{id:"\ub9e4\uc9c1\ub118\ubc84"},"\ub9e4\uc9c1\ub118\ubc84"),(0,l.kt)("p",null,"\ubaa8\ub4e0 \ud074\ub798\uc2a4 \ud30c\uc77c\uc740 0xCAFEBABE\ub77c\ub294 \ub9e4\uc9c1\ub118\ubc84\ub85c \uc2dc\uc791\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ubcf4\ud1b5 \ub9e4\uc9c1\ub118\ubc84\ub294 \ud30c\uc77c \uc885\ub958\ub97c \uc2dd\ubcc4\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9\ub41c\ub2e4. "),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud3ec\ub9f7-\ubc84\uc804"},"\ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804"),(0,l.kt)("p",null,"\ud074\ub798\uc2a4 \ud30c\uc77c \ubc84\uc804 \uac12\uc740 \ud074\ub798\uc2a4\ub85c\ub354\uc758 \ud638\ud658\uc131 \ubcf4\uc7a5\uc744 \uc704\ud574 \uaf2d \ud544\uc694\ud55c \uac12\uc774\ub2e4. "),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Java 17 \ubc84\uc804\uc73c\ub85c \ube4c\ub4dc\ud55c\ub2e4\uba74 class version 61 ex) 00 00 00 3D")),(0,l.kt)("p",null,"\ud638\ud658\ub418\uc9c0 \uc54a\ub294 \ubc84\uc804\uc758 \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \ub85c\ub529\ud558\ub824\uace0 \ud558\ub294 \uacbd\uc6b0 \ub7f0\ud0c0\uc784\uc5d0 ",(0,l.kt)("inlineCode",{parentName:"p"},"UnsupportedClassVersionError")," \uc608\uc678\uac00 \ubc1c\uc0dd\ud55c\ub2e4. "),(0,l.kt)("p",null,(0,l.kt)("strong",{parentName:"p"},"class\xa0file format major versions")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Java SE"),(0,l.kt)("th",{parentName:"tr",align:null},"Released"),(0,l.kt)("th",{parentName:"tr",align:null},"Major"),(0,l.kt)("th",{parentName:"tr",align:null},"Supported majors"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"8"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2014"),(0,l.kt)("td",{parentName:"tr",align:null},"52"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 52")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"9"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2017"),(0,l.kt)("td",{parentName:"tr",align:null},"53"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 53")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"10"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2018"),(0,l.kt)("td",{parentName:"tr",align:null},"54"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 54")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"11"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2018"),(0,l.kt)("td",{parentName:"tr",align:null},"55"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 55")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"12"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2019"),(0,l.kt)("td",{parentName:"tr",align:null},"56"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 56")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"13"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2019"),(0,l.kt)("td",{parentName:"tr",align:null},"57"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 57")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"14"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2020"),(0,l.kt)("td",{parentName:"tr",align:null},"58"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 58")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"15"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2020"),(0,l.kt)("td",{parentName:"tr",align:null},"59"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 59")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"16"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2021"),(0,l.kt)("td",{parentName:"tr",align:null},"60"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 60")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"17"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2021"),(0,l.kt)("td",{parentName:"tr",align:null},"61"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 61")))),(0,l.kt)("h3",{id:"\uc0c1\uc218-\ud480"},"\uc0c1\uc218 \ud480"),(0,l.kt)("p",null,"2\ubc14\uc774\ud2b8\uc758 \uc0c1\uc218\uc758 \uac1c\uc218\uac12\uc774 \uba3c\uc800\uc624\uace0 \uadf8 \ub4a4\ub85c \ucf54\ub4dc\uc5d0 \ub4f1\uc7a5\ud558\ub294 \uc0c1\uc218\uac12\uc774 \ubaa8\uc5ec\uc788\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ud074\ub798\uc2a4\uba85, \uc0c1\uc218\uba85, \uc0c1\uc218 \uac12, \ud544\ub4dc\uba85, \uba54\uc11c\ub4dc\uba85\uacfc \uac19\uc740 \uac12\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","JVM\uc740 \ucf54\ub4dc \uc2e4\ud589 \uc2dc \ub7f0\ud0c0\uc784\uc5d0 \ubc30\uce58\ub41c \uba54\ubaa8\ub9ac\uac00 \uc544\ub2c8\ub77c, \ud574\ub2f9 \uc0c1\uc218 \ud480 \ud14c\uc774\ube14\uc744 \ucc3e\uc544\ubcf4\uace0 \ud544\uc694\ud55c \uac12\uc744 \ucc38\uc870\ud55c\ub2e4."),(0,l.kt)("h3",{id:"\uc561\uc138\uc2a4-\ud50c\ub798\uadf8"},"\uc561\uc138\uc2a4 \ud50c\ub798\uadf8"),(0,l.kt)("p",null,"\ud074\ub798\uc2a4, \uc778\ud130\ud398\uc774\uc2a4\uc640 \uac19\uc740 \ud30c\uc77c\uc758 \uc18d\uc131\uc744 \ud45c\uc2dc\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\uc608\ub97c \ub4e4\uc5b4 public interface\ub85c \uc815\uc758\ub41c \uc778\ud130\ud398\uc774\uc2a4\uc758 \ud50c\ub798\uadf8\ub294 0x0601\uc774\ub2e4. "),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uacc4\uc0b0\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. ",(0,l.kt)("inlineCode",{parentName:"li"},"ACC_PUBLIC")," xor ",(0,l.kt)("inlineCode",{parentName:"li"},"ACC_INTERFACE")," xor ",(0,l.kt)("inlineCode",{parentName:"li"},"ACC_ABSTRACT"))),(0,l.kt)("p",null,"\uacf5\uc2dd\ubb38\uc11c\uc5d0 \ub4e4\uc5b4\uac00\uba74 \uac01 \ud50c\ub798\uadf8\uc5d0 \ub300\ud55c \uc124\uba85 + \ud50c\ub798\uadf8 \uc124\uc815\uc2dc \ub3d9\uc2dc\uc5d0 \uc124\uc815\ub418\uba74 \uc548\ub418\ub294 \ud50c\ub798\uadf8\uc640 \uac19\uc740 \uc124\uba85\uc774 \uc790\uc138\ud558\uac8c \ub098\uc640\uc788\ub2e4."),(0,l.kt)("p",null,(0,l.kt)("strong",{parentName:"p"},"Class access and property modifiers")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Flag Name"),(0,l.kt)("th",{parentName:"tr",align:null},"Value"),(0,l.kt)("th",{parentName:"tr",align:null},"Interpretation"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_PUBLIC"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0001"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared\xa0public; may be accessed from outside its package.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_FINAL"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0010"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared\xa0final; no subclasses allowed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_SUPER"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0020"),(0,l.kt)("td",{parentName:"tr",align:null},"Treat superclass methods specially when invoked by the\xa0invokespecial\xa0instruction.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_INTERFACE"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0200"),(0,l.kt)("td",{parentName:"tr",align:null},"Is an interface, not a class.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_ABSTRACT"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0400"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared\xa0abstract; must not be instantiated.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_SYNTHETIC"),(0,l.kt)("td",{parentName:"tr",align:null},"0x1000"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared synthetic; not present in the source code.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_ANNOTATION"),(0,l.kt)("td",{parentName:"tr",align:null},"0x2000"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared as an annotation type.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_ENUM"),(0,l.kt)("td",{parentName:"tr",align:null},"0x4000"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared as an\xa0enum\xa0type.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_MODULE"),(0,l.kt)("td",{parentName:"tr",align:null},"0x8000"),(0,l.kt)("td",{parentName:"tr",align:null},"Is a module, not a class or interface.")))),(0,l.kt)("h3",{id:"this_class"},"this_class"),(0,l.kt)("p",null,"\ud074\ub798\uc2a4\uba85\uacfc \uac19\uc740 \uc774\ub984\uc744 \ud45c\ud604\ud558\ub294 \uac12\uc73c\ub85c, \uc0c1\uc218 \ud480\uc5d0\uc11c \ud074\ub798\uc2a4\uba85\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uc778\ub371\uc2a4\uc758 \ud56d\ubaa9\uc740 ",(0,l.kt)("inlineCode",{parentName:"p"},"CONSTANT_Class_infoclass")," \ud615\uc2dd\uc758 \uac12\uc774\uc5b4\uc57c \ud55c\ub2e4. "),(0,l.kt)("h3",{id:"super_class"},"super_class"),(0,l.kt)("p",null,"\uc0c1\uc218 \ud480\uc5d0\uc11c \uc288\ud37c \ud074\ub798\uc2a4\uc758 \uc774\ub984\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\uc544\ubb34\uac83\ub3c4 \uc0c1\uc18d\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\uc758 \uacbd\uc6b0 ",(0,l.kt)("inlineCode",{parentName:"p"},"java.lang.Object"),"\uc758 \uc778\ub371\uc2a4 \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4."),(0,l.kt)("h3",{id:"interface-field-method"},"interface, field, method"),(0,l.kt)("p",null,"\uac01\uac01\uc758 \uac1c\uc218\uc640, \uc815\ubcf4\uc5d0 \ub300\ud55c \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","interface, field, method\ub97c \ud45c\uc2dc\ud558\ub294 \ubc29\ubc95\uc774 \uac01\uac01 \ub2e4\ub974\uace0, \uc811\uadfc\uc790\uc5d0 \ub300\ud55c \ud50c\ub798\uadf8\ub3c4 \uac01\uac01 \ub2e4\ub974\ub2e4."),(0,l.kt)("h3",{id:"attributes"},"attributes"),(0,l.kt)("p",null,"\ud574\ub2f9 \ud074\ub798\uc2a4 \ud30c\uc77c\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucd94\uac00 \uc815\ubcf4\uc758 \ubaa8\uc74c\uc774\ub2e4. \uc608) \uc18c\uc2a4\ud30c\uc77c\uba85",(0,l.kt)("br",{parentName:"p"}),"\n","\uc815\ud574\uc9c4 \ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \uad6c\uc870\ub97c \ud655\uc7a5\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. "),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud655\uc778\ud558\uba74\uc11c-\uc0ac\uc6a9\ud55c-\ud234"},"\ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234"),(0,l.kt)("p",null,"IntelliJ plugin - BinEd",(0,l.kt)("br",{parentName:"p"}),"\n","IntelliJ plugin - jclasslib Bytecode Viewer"),(0,l.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,l.kt)("p",null,"2\uc7a5 JVM \uc774\uc57c\uae30, \uc790\ubc14 \ucd5c\uc801\ud654",(0,l.kt)("br",{parentName:"p"}),"\n",(0,l.kt)("a",{parentName:"p",href:"https://docs.fileformat.com/ko/programming/class/"},"Class file in Java, File Format"),(0,l.kt)("br",{parentName:"p"}),"\n",(0,l.kt)("a",{parentName:"p",href:"https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html"},"java se11 Class \ud30c\uc77c \ud615\uc2dd, Oracle"),(0,l.kt)("br",{parentName:"p"}),"\n",(0,l.kt)("a",{parentName:"p",href:"https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html"},"java se17 Class \ud30c\uc77c \ud615\uc2dd, Oracle")))}o.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8720c147.b6a4b7a3.js b/assets/js/8720c147.b6a4b7a3.js new file mode 100644 index 000000000..2c226fe5a --- /dev/null +++ b/assets/js/8720c147.b6a4b7a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[470],{75712:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>d,default:()=>j,frontMatter:()=>l,metadata:()=>i,toc:()=>a});var r=n(85893),t=n(3905);const l={title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",slug:"java-class-file",tags:["Java","Class"]},d=void 0,i={permalink:"/java-class-file",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",source:"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",description:"\ud074\ub798\uc2a4 \ud30c\uc77c",date:"2023-04-03T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 3\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Class",permalink:"/tags/class"}],readingTime:5.63,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",slug:"java-class-file",tags:["Java","Class"]},unlisted:!1,prevItem:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",permalink:"/test-double"},nextItem:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",permalink:"/custom-jdbc-template"}},c={authorsImageUrls:[]},a=[{value:"\ud074\ub798\uc2a4 \ud30c\uc77c",id:"\ud074\ub798\uc2a4-\ud30c\uc77c",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd",id:"\ud074\ub798\uc2a4-\ud30c\uc77c\uc758-\ub370\uc774\ud130-\ud615\uc2dd",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\uad6c\uc870",level:3},{value:"\ub9e4\uc9c1\ub118\ubc84",id:"\ub9e4\uc9c1\ub118\ubc84",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud3ec\ub9f7-\ubc84\uc804",level:3},{value:"\uc0c1\uc218 \ud480",id:"\uc0c1\uc218-\ud480",level:3},{value:"\uc561\uc138\uc2a4 \ud50c\ub798\uadf8",id:"\uc561\uc138\uc2a4-\ud50c\ub798\uadf8",level:3},{value:"this_class",id:"this_class",level:3},{value:"super_class",id:"super_class",level:3},{value:"interface, field, method",id:"interface-field-method",level:3},{value:"attributes",id:"attributes",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud655\uc778\ud558\uba74\uc11c-\uc0ac\uc6a9\ud55c-\ud234",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function h(e){const s={a:"a",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c",children:"\ud074\ub798\uc2a4 \ud30c\uc77c"}),"\n",(0,r.jsxs)(s.p,{children:["\uc790\ubc14 \uc18c\uc2a4\ucf54\ub4dc\uac00 \uc2e4\ud589\uc774 \ub418\ub824\uba74 \uc790\ubc14 \ucef4\ud30c\uc77c\ub7ec(javac)\ub97c \ud1b5\ud574 \uc18c\uc2a4\ucf54\ub4dc\ub97c \ud074\ub798\uc2a4\ud30c\uc77c\ub85c \ubcc0\ud658\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\ucef4\ud30c\uc77c\ub41c \ud074\ub798\uc2a4\ud30c\uc77c\uc740 \uc5b4\ub5a4 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\uc744\uae4c?"]}),"\n",(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c\uc758-\ub370\uc774\ud130-\ud615\uc2dd",children:"\ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd"}),"\n",(0,r.jsxs)(s.p,{children:["8\ube44\ud2b8 \ubc14\uc774\ud2b8\uc758 \uc2a4\ud2b8\ub9bc\uc73c\ub85c \uad6c\uc131\ub41c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","16\ube44\ud2b8 \ubc0f 32\ube44\ud2b8\uc758 \ub370\uc774\ud130\ub294 \uac01\uac01 2\uac1c, 4\uac1c\uc758 \uc5f0\uc18d\ub41c 8\ube44\ud2b8\ub97c \uc77d\uc5b4\uc11c \uad6c\uc131\ub41c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\uba40\ud2f0\ubc14\uc774\ud2b8\uc758 \uacbd\uc6b0 \ud56d\uc0c1 big endian \uc21c\uc11c\ub85c \uc800\uc7a5\ub41c\ub2e4."]}),"\n",(0,r.jsxs)(s.p,{children:["u1 \u2192 unsigned 1byte",(0,r.jsx)(s.br,{}),"\n","u2 \u2192 unsigned 2byte",(0,r.jsx)(s.br,{}),"\n","u4 \u2192 unsigned 4byte"]}),"\n",(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\uad6c\uc870",children:"\ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"ClassFile {\n u4 magic;\n u2 minor_version;\n u2 major_version;\n u2 constant_pool_count;\n cp_info constant_pool[constant_pool_count-1];\n u2 access_flags;\n u2 this_class;\n u2 super_class;\n u2 interfaces_count;\n u2 interfaces[interfaces_count];\n u2 fields_count;\n field_info fields[fields_count];\n u2 methods_count;\n method_info methods[methods_count];\n u2 attributes_count;\n attribute_info attributes[attributes_count];\n}\n"})}),"\n",(0,r.jsx)(s.h3,{id:"\ub9e4\uc9c1\ub118\ubc84",children:"\ub9e4\uc9c1\ub118\ubc84"}),"\n",(0,r.jsxs)(s.p,{children:["\ubaa8\ub4e0 \ud074\ub798\uc2a4 \ud30c\uc77c\uc740 0xCAFEBABE\ub77c\ub294 \ub9e4\uc9c1\ub118\ubc84\ub85c \uc2dc\uc791\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\ubcf4\ud1b5 \ub9e4\uc9c1\ub118\ubc84\ub294 \ud30c\uc77c \uc885\ub958\ub97c \uc2dd\ubcc4\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud3ec\ub9f7-\ubc84\uc804",children:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804"}),"\n",(0,r.jsx)(s.p,{children:"\ud074\ub798\uc2a4 \ud30c\uc77c \ubc84\uc804 \uac12\uc740 \ud074\ub798\uc2a4\ub85c\ub354\uc758 \ud638\ud658\uc131 \ubcf4\uc7a5\uc744 \uc704\ud574 \uaf2d \ud544\uc694\ud55c \uac12\uc774\ub2e4."}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Java 17 \ubc84\uc804\uc73c\ub85c \ube4c\ub4dc\ud55c\ub2e4\uba74 class version 61 ex) 00 00 00 3D"}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["\ud638\ud658\ub418\uc9c0 \uc54a\ub294 \ubc84\uc804\uc758 \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \ub85c\ub529\ud558\ub824\uace0 \ud558\ub294 \uacbd\uc6b0 \ub7f0\ud0c0\uc784\uc5d0 ",(0,r.jsx)(s.code,{children:"UnsupportedClassVersionError"})," \uc608\uc678\uac00 \ubc1c\uc0dd\ud55c\ub2e4."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"class\xa0file format major versions"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Java SE"}),(0,r.jsx)(s.th,{children:"Released"}),(0,r.jsx)(s.th,{children:"Major"}),(0,r.jsx)(s.th,{children:"Supported majors"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"March 2014"}),(0,r.jsx)(s.td,{children:"52"}),(0,r.jsx)(s.td,{children:"45 .. 52"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"9"}),(0,r.jsx)(s.td,{children:"September 2017"}),(0,r.jsx)(s.td,{children:"53"}),(0,r.jsx)(s.td,{children:"45 .. 53"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"10"}),(0,r.jsx)(s.td,{children:"March 2018"}),(0,r.jsx)(s.td,{children:"54"}),(0,r.jsx)(s.td,{children:"45 .. 54"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"11"}),(0,r.jsx)(s.td,{children:"September 2018"}),(0,r.jsx)(s.td,{children:"55"}),(0,r.jsx)(s.td,{children:"45 .. 55"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"12"}),(0,r.jsx)(s.td,{children:"March 2019"}),(0,r.jsx)(s.td,{children:"56"}),(0,r.jsx)(s.td,{children:"45 .. 56"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"13"}),(0,r.jsx)(s.td,{children:"September 2019"}),(0,r.jsx)(s.td,{children:"57"}),(0,r.jsx)(s.td,{children:"45 .. 57"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"14"}),(0,r.jsx)(s.td,{children:"March 2020"}),(0,r.jsx)(s.td,{children:"58"}),(0,r.jsx)(s.td,{children:"45 .. 58"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"15"}),(0,r.jsx)(s.td,{children:"September 2020"}),(0,r.jsx)(s.td,{children:"59"}),(0,r.jsx)(s.td,{children:"45 .. 59"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{children:"March 2021"}),(0,r.jsx)(s.td,{children:"60"}),(0,r.jsx)(s.td,{children:"45 .. 60"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"17"}),(0,r.jsx)(s.td,{children:"September 2021"}),(0,r.jsx)(s.td,{children:"61"}),(0,r.jsx)(s.td,{children:"45 .. 61"})]})]})]}),"\n",(0,r.jsx)(s.h3,{id:"\uc0c1\uc218-\ud480",children:"\uc0c1\uc218 \ud480"}),"\n",(0,r.jsxs)(s.p,{children:["2\ubc14\uc774\ud2b8\uc758 \uc0c1\uc218\uc758 \uac1c\uc218\uac12\uc774 \uba3c\uc800\uc624\uace0 \uadf8 \ub4a4\ub85c \ucf54\ub4dc\uc5d0 \ub4f1\uc7a5\ud558\ub294 \uc0c1\uc218\uac12\uc774 \ubaa8\uc5ec\uc788\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\ud074\ub798\uc2a4\uba85, \uc0c1\uc218\uba85, \uc0c1\uc218 \uac12, \ud544\ub4dc\uba85, \uba54\uc11c\ub4dc\uba85\uacfc \uac19\uc740 \uac12\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","JVM\uc740 \ucf54\ub4dc \uc2e4\ud589 \uc2dc \ub7f0\ud0c0\uc784\uc5d0 \ubc30\uce58\ub41c \uba54\ubaa8\ub9ac\uac00 \uc544\ub2c8\ub77c, \ud574\ub2f9 \uc0c1\uc218 \ud480 \ud14c\uc774\ube14\uc744 \ucc3e\uc544\ubcf4\uace0 \ud544\uc694\ud55c \uac12\uc744 \ucc38\uc870\ud55c\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"\uc561\uc138\uc2a4-\ud50c\ub798\uadf8",children:"\uc561\uc138\uc2a4 \ud50c\ub798\uadf8"}),"\n",(0,r.jsxs)(s.p,{children:["\ud074\ub798\uc2a4, \uc778\ud130\ud398\uc774\uc2a4\uc640 \uac19\uc740 \ud30c\uc77c\uc758 \uc18d\uc131\uc744 \ud45c\uc2dc\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\uc608\ub97c \ub4e4\uc5b4 public interface\ub85c \uc815\uc758\ub41c \uc778\ud130\ud398\uc774\uc2a4\uc758 \ud50c\ub798\uadf8\ub294 0x0601\uc774\ub2e4."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["\uacc4\uc0b0\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. ",(0,r.jsx)(s.code,{children:"ACC_PUBLIC"})," xor ",(0,r.jsx)(s.code,{children:"ACC_INTERFACE"})," xor ",(0,r.jsx)(s.code,{children:"ACC_ABSTRACT"})]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"\uacf5\uc2dd\ubb38\uc11c\uc5d0 \ub4e4\uc5b4\uac00\uba74 \uac01 \ud50c\ub798\uadf8\uc5d0 \ub300\ud55c \uc124\uba85 + \ud50c\ub798\uadf8 \uc124\uc815\uc2dc \ub3d9\uc2dc\uc5d0 \uc124\uc815\ub418\uba74 \uc548\ub418\ub294 \ud50c\ub798\uadf8\uc640 \uac19\uc740 \uc124\uba85\uc774 \uc790\uc138\ud558\uac8c \ub098\uc640\uc788\ub2e4."}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Class access and property modifiers"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Flag Name"}),(0,r.jsx)(s.th,{children:"Value"}),(0,r.jsx)(s.th,{children:"Interpretation"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_PUBLIC"}),(0,r.jsx)(s.td,{children:"0x0001"}),(0,r.jsx)(s.td,{children:"Declared\xa0public; may be accessed from outside its package."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_FINAL"}),(0,r.jsx)(s.td,{children:"0x0010"}),(0,r.jsx)(s.td,{children:"Declared\xa0final; no subclasses allowed."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_SUPER"}),(0,r.jsx)(s.td,{children:"0x0020"}),(0,r.jsx)(s.td,{children:"Treat superclass methods specially when invoked by the\xa0invokespecial\xa0instruction."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_INTERFACE"}),(0,r.jsx)(s.td,{children:"0x0200"}),(0,r.jsx)(s.td,{children:"Is an interface, not a class."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_ABSTRACT"}),(0,r.jsx)(s.td,{children:"0x0400"}),(0,r.jsx)(s.td,{children:"Declared\xa0abstract; must not be instantiated."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_SYNTHETIC"}),(0,r.jsx)(s.td,{children:"0x1000"}),(0,r.jsx)(s.td,{children:"Declared synthetic; not present in the source code."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_ANNOTATION"}),(0,r.jsx)(s.td,{children:"0x2000"}),(0,r.jsx)(s.td,{children:"Declared as an annotation type."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_ENUM"}),(0,r.jsx)(s.td,{children:"0x4000"}),(0,r.jsx)(s.td,{children:"Declared as an\xa0enum\xa0type."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_MODULE"}),(0,r.jsx)(s.td,{children:"0x8000"}),(0,r.jsx)(s.td,{children:"Is a module, not a class or interface."})]})]})]}),"\n",(0,r.jsx)(s.h3,{id:"this_class",children:"this_class"}),"\n",(0,r.jsxs)(s.p,{children:["\ud074\ub798\uc2a4\uba85\uacfc \uac19\uc740 \uc774\ub984\uc744 \ud45c\ud604\ud558\ub294 \uac12\uc73c\ub85c, \uc0c1\uc218 \ud480\uc5d0\uc11c \ud074\ub798\uc2a4\uba85\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\ud574\ub2f9 \uc778\ub371\uc2a4\uc758 \ud56d\ubaa9\uc740 ",(0,r.jsx)(s.code,{children:"CONSTANT_Class_infoclass"})," \ud615\uc2dd\uc758 \uac12\uc774\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"super_class",children:"super_class"}),"\n",(0,r.jsxs)(s.p,{children:["\uc0c1\uc218 \ud480\uc5d0\uc11c \uc288\ud37c \ud074\ub798\uc2a4\uc758 \uc774\ub984\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\uc544\ubb34\uac83\ub3c4 \uc0c1\uc18d\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\uc758 \uacbd\uc6b0 ",(0,r.jsx)(s.code,{children:"java.lang.Object"}),"\uc758 \uc778\ub371\uc2a4 \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"interface-field-method",children:"interface, field, method"}),"\n",(0,r.jsxs)(s.p,{children:["\uac01\uac01\uc758 \uac1c\uc218\uc640, \uc815\ubcf4\uc5d0 \ub300\ud55c \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4.",(0,r.jsx)(s.br,{}),"\n","interface, field, method\ub97c \ud45c\uc2dc\ud558\ub294 \ubc29\ubc95\uc774 \uac01\uac01 \ub2e4\ub974\uace0, \uc811\uadfc\uc790\uc5d0 \ub300\ud55c \ud50c\ub798\uadf8\ub3c4 \uac01\uac01 \ub2e4\ub974\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"attributes",children:"attributes"}),"\n",(0,r.jsxs)(s.p,{children:["\ud574\ub2f9 \ud074\ub798\uc2a4 \ud30c\uc77c\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucd94\uac00 \uc815\ubcf4\uc758 \ubaa8\uc74c\uc774\ub2e4. \uc608) \uc18c\uc2a4\ud30c\uc77c\uba85",(0,r.jsx)(s.br,{}),"\n","\uc815\ud574\uc9c4 \ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \uad6c\uc870\ub97c \ud655\uc7a5\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud655\uc778\ud558\uba74\uc11c-\uc0ac\uc6a9\ud55c-\ud234",children:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234"}),"\n",(0,r.jsxs)(s.p,{children:["IntelliJ plugin - BinEd",(0,r.jsx)(s.br,{}),"\n","IntelliJ plugin - jclasslib Bytecode Viewer"]}),"\n",(0,r.jsx)(s.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(s.p,{children:["2\uc7a5 JVM \uc774\uc57c\uae30, \uc790\ubc14 \ucd5c\uc801\ud654",(0,r.jsx)(s.br,{}),"\n",(0,r.jsx)(s.a,{href:"https://docs.fileformat.com/ko/programming/class/",children:"Class file in Java, File Format"}),(0,r.jsx)(s.br,{}),"\n",(0,r.jsx)(s.a,{href:"https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html",children:"java se11 Class \ud30c\uc77c \ud615\uc2dd, Oracle"}),(0,r.jsx)(s.br,{}),"\n",(0,r.jsx)(s.a,{href:"https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html",children:"java se17 Class \ud30c\uc77c \ud615\uc2dd, Oracle"})]})]})}function j(e={}){const{wrapper:s}={...(0,t.ah)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},3905:(e,s,n)=>{n.d(s,{ah:()=>a});var r=n(67294);function t(e,s,n){return s in e?Object.defineProperty(e,s,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[s]=n,e}function l(e,s){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);s&&(r=r.filter((function(s){return Object.getOwnPropertyDescriptor(e,s).enumerable}))),n.push.apply(n,r)}return n}function d(e){for(var s=1;s<arguments.length;s++){var n=null!=arguments[s]?arguments[s]:{};s%2?l(Object(n),!0).forEach((function(s){t(e,s,n[s])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(s){Object.defineProperty(e,s,Object.getOwnPropertyDescriptor(n,s))}))}return e}function i(e,s){if(null==e)return{};var n,r,t=function(e,s){if(null==e)return{};var n,r,t={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],s.indexOf(n)>=0||(t[n]=e[n]);return t}(e,s);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],s.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(t[n]=e[n])}return t}var c=r.createContext({}),a=function(e){var s=r.useContext(c),n=s;return e&&(n="function"==typeof e?e(s):d(d({},s),e)),n},h={inlineCode:"code",wrapper:function(e){var s=e.children;return r.createElement(r.Fragment,{},s)}},j=r.forwardRef((function(e,s){var n=e.components,t=e.mdxType,l=e.originalType,c=e.parentName,j=i(e,["components","mdxType","originalType","parentName"]),x=a(n),o=t,u=x["".concat(c,".").concat(o)]||x[o]||h[o]||l;return n?r.createElement(u,d(d({ref:s},j),{},{components:n})):r.createElement(u,d({ref:s},j))}));j.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/8a24850b.556fbbc3.js b/assets/js/8a24850b.556fbbc3.js deleted file mode 100644 index b1caeacf5..000000000 --- a/assets/js/8a24850b.556fbbc3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[741],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>k});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,u=e.parentName,s=o(e,["components","mdxType","originalType","parentName"]),m=c(r),k=a,b=m["".concat(u,".").concat(k)]||m[k]||i[k]||p;return r?n.createElement(b,l(l({ref:t},s),{},{components:r})):n.createElement(b,l({ref:t},s))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=m;var o={};for(var u in t)hasOwnProperty.call(t,u)&&(o[u]=t[u]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var c=2;c<p;c++)l[c]=r[c];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},12401:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>l,default:()=>i,frontMatter:()=>p,metadata:()=>o,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",slug:"chess-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,o={permalink:"/chess-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",description:"1, 2\ub2e8\uacc4//github.com/woowacourse/java-chess/pull/441",date:"2023-03-31T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 31\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.705,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",slug:"chess-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",permalink:"/woowacourse-level1-retrospective"},nextItem:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",permalink:"/grasp"}},u={authorsImageUrls:[]},c=[{value:"\uccb4\uc2a4",id:"\uccb4\uc2a4",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],s={toc:c};function i(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1, 2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-chess/pull/441"},"https://github.com/woowacourse/java-chess/pull/441"),(0,a.kt)("br",{parentName:"p"}),"\n","3, 4\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-chess/pull/529"},"https://github.com/woowacourse/java-chess/pull/529")," ")),(0,a.kt)("h3",{id:"\uccb4\uc2a4"},"\uccb4\uc2a4"),(0,a.kt)("p",null,"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\ub294 \uac00\ube44\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4!",(0,a.kt)("br",{parentName:"p"}),"\n","\uccb4\uc2a4\ub294 \uc774\uc804 \ubbf8\uc158\ub4e4\ubcf4\ub2e4 \ud6e8\uc52c \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uac00\ube44\uc640 \ub098\ub294 \uccb4\uc2a4 \ub3c4\uba54\uc778\uc774 \uc775\uc219\ud574\uc11c \ub354 \ud3b8\ud55c \ub9c8\uc74c\uc73c\ub85c \uc2dc\uc791\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc5b4\ub824\uc6e0\ub358 \ubd80\ubd84\uc740 \uae30\ubb3c\uc758 \uc774\ub3d9, \uc774\ub3d9\uc2dc \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uac00\ube44\uac00 \uc9d1\uc5d0\uac00\uc11c\ub3c4 \uae30\ubb3c\uc758 \uc774\ub3d9 \uad00\ub828\ud574 \uc0dd\uac01 \uc815\ub9ac\ud55c \uae00\uc744 \ubcf4\ub0b4\uc918\uc11c \ub354\uc6b1 \ube68\ub9ac \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\uc885\uc801\uc73c\ub85c \uacb0\uc815\ud55c \ubd80\ubd84\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5\uc5ec\ubd80"),(0,a.kt)("br",{parentName:"p"}),"\n","Rank\uc640 File\uc740 \uac01\uac01 \uc704\uce58\uac12\uc744 \uac00\uc9c0\uace0 \uc788\uace0, \uac12\uc758 \ucc28\uc774\ub97c \uc774\uc6a9\ud574\uc11c \uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uacc4\uc0b0\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c1\uc120 \u2192 Rank\uc640 File \ucc28\uc774 \uc911 \ud558\ub098\uac00 0\uc774\uc5b4\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub300\uac01\uc120 \u2192 Rank\uc640 File \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \uac19\uc544\uc57c \ud55c\ub2e4. ex) abs(-2) == abs(2)",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\uc774\ud2b8 \u2192 \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \ud558\ub098\ub294 2 \ub098\uba38\uc9c0 \ud558\ub098\ub294 1\uc774\uc5b4\uc57c \ud55c\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub3c4\ucc29 \uce78\uc758 \uae30\ubb3c \uc5ec\ubd80"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\uad70 \u2192 \uc774\ub3d9\uc774 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc801\uad70 \u2192 \uc774\ub3d9\uc774 \uac00\ub2a5\ud558\ub2e4. \uc801\uad70\uc744 \uc7a1\ub294\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc911\uac04\uc5d0 \uae30\ubb3c \uc874\uc7ac \uc5ec\ubd80"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub3d9 \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\uba74 \uc548\ub41c\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0ac\uc6a9"),(0,a.kt)("br",{parentName:"p"}),"\n","\uccb4\uc2a4 \ubbf8\uc158\uc740 \ud2b9\ubcc4\ud558\uac8c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc5f0\uacb0\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uccb4\uc2a4 \uac8c\uc784\uc758 \uc0c1\ud0dc\ub97c \ub2e4\uc74c\uc758 \ub450\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uc815\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95 "),(0,a.kt)("li",{parentName:"ul"},"\uae30\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uac8c\uc784\uc744 \ubd88\ub7ec\uc640 \uae30\ubcf4\ub300\ub85c \uc774\ub3d9\uc2dc\ud0a4\ub294 \ubc29\ubc95 ")),(0,a.kt)("p",null,"\uae30\ubb3c\uc774 \uc774\ub3d9\ud560 \ub54c\ub9c8\ub2e4 \uac12\uc744 \uc800\uc7a5\ud558\uace0 \uc2f6\uc5c8\uace0, \uae30\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\uc9c0 \uc54a\uc740 \uc774\uc720\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\ud134\uacfc \uac19\uc740 \ubd80\uac00\uc801\uc778 \uc694\uc18c\ub97c \uc800\uc7a5\ud574\uc57c \ud55c\ub2e4. "),(0,a.kt)("li",{parentName:"ul"},"\uc774\ub3d9\uc744 \ud560 \ub54c \uae30\ubb3c\uc774 \uc7a1\ud788\ub294 \uacbd\uc6b0 update \ucffc\ub9ac(\uc774\ub3d9 \uae30\ubb3c)\uc640 delete(\uc7a1\ud78c \uae30\ubb3c) 2\uac1c\uc758 \ucffc\ub9ac\ub97c \ub0a0\ub824\uc57c \ud55c\ub2e4. "),(0,a.kt)("li",{parentName:"ul"},"\ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ub3c4\uba54\uc778\uc758 \ubcc0\uacbd\uc774 \ud06c\uac8c(\ucd08\uae30 \uc0c1\ud0dc\ub97c \uad6c\uc131\ud558\ub294 \ubd80\ubd84) \uc77c\uc5b4\ub098\uc57c \ud55c\ub2e4. ")),(0,a.kt)("p",null,"\uc815\ub9ac\ud558\uc790\uba74 \uae30\ubb3c \uc804\uccb4 \uc800\uc7a5\uacfc \uae30\ubcf4 \uc800\uc7a5\uc740 \ub2e4\uc74c\uacfc \ucc28\uc774\uac00 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcf4\ub4dc\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc\uc5d0\uc11c 32\uac1c\uc758 Insert \ucffc\ub9ac(\uae30\ubb3c\uc758 \uc704\uce58) + \uae30\ubb3c \uc774\ub3d9 \uc2dc \uc6c0\uc9c1\uc784 \ubcc0\uacbd(\uc7a1\ud788\ub294 \uacbd\uc6b0 2\uac1c\uc758 \ucffc\ub9ac)",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ubcf4\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uad6c\uc131 + \uc800\uc7a5\ub41c \uae30\ubcf4\ub97c select \ucffc\ub9ac\ub85c \uc870\ud68c\ud574\uc11c \uc0ac\uc6a9(1\ud68c) + insert \ucffc\ub9ac(\uc774\ub3d9 \ub2f9 1\ud68c)"),(0,a.kt)("p",null,"\ucd94\uac00\ub85c \uae30\ubcf4\uc800\uc7a5\uc774 \uad6c\ud604\ub3c4 \ub354\uc6b1 \uac04\ub2e8\ud558\ub2e4. \ud83d\udc4d "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ubd80\uac00\uc801\uc778 \ubd80\ubd84")),(0,a.kt)("p",null,"\ub9ac\ubdf0\uc5b4\uc778 \ucc30\ub9ac\ud83c\udf6b\uac00 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \uac8c\uc784\uc774 \uc9c4\ud589\ub41c\ub2e4\uba74 \uc5b4\ub5a8\uc9c0? \uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ub2e4\uc591\ud55c \uc2dc\ub3c4\ub97c \ud574\ubd24\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\ub204\ub204\uc758 \ub3c4\uc6c0\uc73c\ub85c ConnectionPool \uad6c\ud604 "),(0,a.kt)("li",{parentName:"ul"},"ThreadLocal \uc0ac\uc6a9\ud574\uc11c \uc4f0\ub808\ub4dc \ubcc4 \uc138\uc158 \uad00\ub9ac "),(0,a.kt)("li",{parentName:"ul"},"\uc2e4\uc81c\ub85c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4\uc5d0\uc11c \uccb4\uc2a4 \uac8c\uc784\uc774 \uc9c4\ud589\ub418\ub294 Board\ub97c ConcurrentHashMap\uc73c\ub85c \uc800\uc7a5(\uc0ac\uc2e4 \uc774 \ubd80\ubd84\uc740 \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ud544\uc694\uc5c6\uc9c0\ub9cc 2\uba85\uc774 \uc11c\ub85c \uac8c\uc784\ud558\ub294 \uacbd\uc6b0\ub97c \uc0dd\uac01\ud574\uc11c \ub123\uc5b4\ubcf4\uc558\ub2e4.) ")),(0,a.kt)("p",null,"\ub450 \uba85\uc774 \uc11c\ub85c \uac19\uc740 \ubc29\uc5d0 \uc785\uc7a5\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4\uba74 \ucd9c\ub825\ud558\ub294 \ubd80\ubd84\uc774 \uae4c\ub2e4\ub85c\uc6cc\uc9c8 \uac83 \uac19\ub2e4\uace0 \uc608\uc0c1\ub418\uc5b4(Board\uc5d0 \uc635\uc800\ubc84 \ud328\ud134\uc744 \uc0ac\uc6a9\ud574\uc57c\ub418\ub098?) \ud574\ubcfc \uc5c4\ub450\uac00 \ub098\uc9c0 \uc54a\uc558\ub2e4. "),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc9c0 \ubabb\ud55c \ubd80\ubd84"),(0,a.kt)("br",{parentName:"p"}),"\n","DB \uad00\ub828 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub3c4\uba54\uc778 \ub85c\uc9c1\uc5d0\ub9cc \uc9d1\uc911\ud558\ub2e4\ubcf4\ub2c8 \uc815\uc801 \uc911\uc694\ud55c DB\uc758 \ucf54\ub4dc\uc758 \uc608\uc678\ucc98\ub9ac, \ube48 \uac12\uc744 \ubc18\ud658 \ud558\ub294 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucc98\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ucc30\ub9ac\uc758 \uaf3c\uaf3c\ud55c \ub9ac\ubdf0\ub85c DB\ubd80\ubd84\uacfc \ub098\ub9cc\uc758 JdbcTemplate\uc744 \uae54\ub054\ud558\uac8c \uad6c\ud604\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ub2f4\uac10"),(0,a.kt)("br",{parentName:"p"}),"\n","\ucd08\ubc18\uc5d0\ub294 \uc5ec\uc720\ub86d\uc9c0\ub9cc \uc81c\ucd9c \ub9c8\uac10\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \uc218\ub85d \uc0ac\ub78c\uc774 \uae09\ud574\uc9c0\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\ud560 \ub550 \uc18d\ub3c4\ub97c \uc870\uc808\ud558\uace0, \ub9c8\uc74c\uc5d0 \uc5ec\uc720\ub97c \uac00\uc838\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"DAO \uc911\ubcf5 \uc81c\uac70")),(0,a.kt)("p",null,"\ud504\ub864\ub85c\uadf8\uc5d0 ",(0,a.kt)("a",{parentName:"p",href:"https://prolog.techcourse.co.kr/studylogs/2947"},"\uae00"),"\uc744 \uc791\uc131\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","DAO\ub97c \uc791\uc131\ud558\ub294\ub370 try-catch-resources\uc640 \uc5ec\ub7ec \ucf54\ub4dc\uac00 \uc911\ubcf5\ub418\uc11c \uc81c\uac70\ud558\uace0\uc2f6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc73c\ub85c \uae54\ub054\ud558\uac8c \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\udc4d"),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud398\uc5b4 \uc0dd\uac01\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uac00\ube44\ub294 \ub204\uad6c\ubcf4\ub2e4 \ud398\uc5b4\ub97c \uc0dd\uac01\ud558\uace0, \ubc30\ub824\ud574\uc8fc\ub294 \ud398\uc5b4\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc911\uac04 \uc911\uac04 \ub2f9 \ub5a8\uc5b4\uc9c8\uae4c\ubd10 \uac71\uc815\ub3c4 \ud574\uc8fc\uace0, \ub098\uc758 \ucee8\ub514\uc158\ub3c4 \ud655\uc778\ud574\uc92c\ub2e4! "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ubbf8\uc158 \ubab0\uc785\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\uadfc\uc5d0 \ubbf8\uc158\uc5d0 \uc798 \ubab0\uc785\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac00\ube44\ub294 \ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \ubbf8\uc158\uc5d0 \ub300\ud55c \ubab0\uc785\ub3c4\uac00 \ub9e4\uc6b0 \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9d1\uc5d0\uac00\uc11c\ub3c4 \uccb4\uc2a4 \uc774\ub3d9\uc5d0 \ub300\ud55c \ub85c\uc9c1\uc744 \uc5b4\ub5bb\uac8c \uad6c\ud604\ud560 \uc9c0 \uc0dd\uac01\ud55c \ub4a4 \uaf3c\uaf3c\ud574\uc11c \uc815\ub9ac\ud574\uc11c \ub098\uc5d0\uac8c \ubcf4\ub0b4\uc8fc\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub355\ubd84\uc5d0 \ub098\ub3c4 \uac00\ube44\uc758 \uc0dd\uac01\uc744 \uc54c \uc218 \uc788\uc5b4\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294\ub370 \uac00\uc18d\ub3c4\uac00 \ubd99\uc740 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ubbf8\uc158\uc744 \uc798 \ub9c8\ubb34\ub9ac\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c\uc774 \uc804\ub2ec\ub418\uc11c \uadf8\ub7f0\uc9c0 \ub098\ub3c4 \ub369\ub2ec\uc544 \uc5f4\uc2ec\ud788 \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\ude04 "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc194\uc9c1\ud568"),(0,a.kt)("br",{parentName:"p"}),"\n","\uba3c\uc800 \ud68c\uace0\ud558\uc790\uace0 \ub9d0 \uac78\uc5b4\uc918\uc11c \uc815\ub9d0 \uace0\ub9c8\uc6e0\ub2e4\uace0 \ud45c\ud604\ud574\uc8fc\ub294 \ubd80\ubd84",(0,a.kt)("br",{parentName:"p"}),"\n","\ubaa8\ub974\ub294\uac8c \uc788\uc73c\uba74 \uc194\uc9c1\ud558\uac8c \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\uc758 \uc758\uacac\uc744 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud55c \uc0c1\ud0dc\ub85c \uc804\ub2ec\ud560 \ub54c \uc774\ud574\uac00 \uc548\ub418\uc5c8\ub2e4\uace0 \uc815\ud655\ud788 \uc804\ub2ec\ud574\uc8fc\ub294 \ubd80\ubd84",(0,a.kt)("br",{parentName:"p"}),"\n","\uc194\uc9c1\ud568\uc740 \ud398\uc5b4\ud560 \ub54c \uc911\uc694\ud55c \ubd80\ubd84\uc778 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ucc30\ub9ac\ud83c\udf6b \uccb4\uc2a4 \ubbf8\uc158\ub54c \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0 \ub0a8\uaca8\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4!"))}i.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8a24850b.b479905c.js b/assets/js/8a24850b.b479905c.js new file mode 100644 index 000000000..3748d5a8f --- /dev/null +++ b/assets/js/8a24850b.b479905c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[741],{86331:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>j,frontMatter:()=>c,metadata:()=>l,toc:()=>a});var s=r(85893),t=r(3905);const c={title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",slug:"chess-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,l={permalink:"/chess-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",description:"1, 2\ub2e8\uacc4//github.com/woowacourse/java-chess/pull/441",date:"2023-03-31T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 31\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.705,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",slug:"chess-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",permalink:"/woowacourse-level1-retrospective"},nextItem:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",permalink:"/grasp"}},o={authorsImageUrls:[]},a=[{value:"\uccb4\uc2a4",id:"\uccb4\uc2a4",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function h(e){const n={a:"a",admonition:"admonition",br:"br",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.ah)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,s.jsxs)(n.p,{children:["1, 2\ub2e8\uacc4: ",(0,s.jsx)(n.a,{href:"https://github.com/woowacourse/java-chess/pull/441",children:"https://github.com/woowacourse/java-chess/pull/441"}),(0,s.jsx)(n.br,{}),"\n","3, 4\ub2e8\uacc4: ",(0,s.jsx)(n.a,{href:"https://github.com/woowacourse/java-chess/pull/529",children:"https://github.com/woowacourse/java-chess/pull/529"})]})}),"\n",(0,s.jsx)(n.h3,{id:"\uccb4\uc2a4",children:"\uccb4\uc2a4"}),"\n",(0,s.jsxs)(n.p,{children:["\uccb4\uc2a4 \ubbf8\uc158\uc5d0\ub294 \uac00\ube44\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4!",(0,s.jsx)(n.br,{}),"\n","\uccb4\uc2a4\ub294 \uc774\uc804 \ubbf8\uc158\ub4e4\ubcf4\ub2e4 \ud6e8\uc52c \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778\uc774\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \uac00\ube44\uc640 \ub098\ub294 \uccb4\uc2a4 \ub3c4\uba54\uc778\uc774 \uc775\uc219\ud574\uc11c \ub354 \ud3b8\ud55c \ub9c8\uc74c\uc73c\ub85c \uc2dc\uc791\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc5b4\ub824\uc6e0\ub358 \ubd80\ubd84\uc740 \uae30\ubb3c\uc758 \uc774\ub3d9, \uc774\ub3d9\uc2dc \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:["\uac00\ube44\uac00 \uc9d1\uc5d0\uac00\uc11c\ub3c4 \uae30\ubb3c\uc758 \uc774\ub3d9 \uad00\ub828\ud574 \uc0dd\uac01 \uc815\ub9ac\ud55c \uae00\uc744 \ubcf4\ub0b4\uc918\uc11c \ub354\uc6b1 \ube68\ub9ac \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ucd5c\uc885\uc801\uc73c\ub85c \uacb0\uc815\ud55c \ubd80\ubd84\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5\uc5ec\ubd80"}),(0,s.jsx)(n.br,{}),"\n","Rank\uc640 File\uc740 \uac01\uac01 \uc704\uce58\uac12\uc744 \uac00\uc9c0\uace0 \uc788\uace0, \uac12\uc758 \ucc28\uc774\ub97c \uc774\uc6a9\ud574\uc11c \uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uacc4\uc0b0\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uc9c1\uc120 \u2192 Rank\uc640 File \ucc28\uc774 \uc911 \ud558\ub098\uac00 0\uc774\uc5b4\uc57c \ud55c\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub300\uac01\uc120 \u2192 Rank\uc640 File \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \uac19\uc544\uc57c \ud55c\ub2e4. ex) abs(-2) == abs(2)",(0,s.jsx)(n.br,{}),"\n","\ub098\uc774\ud2b8 \u2192 \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \ud558\ub098\ub294 2 \ub098\uba38\uc9c0 \ud558\ub098\ub294 1\uc774\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\ub3c4\ucc29 \uce78\uc758 \uae30\ubb3c \uc5ec\ubd80"}),(0,s.jsx)(n.br,{}),"\n","\uc544\uad70 \u2192 \uc774\ub3d9\uc774 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uc801\uad70 \u2192 \uc774\ub3d9\uc774 \uac00\ub2a5\ud558\ub2e4. \uc801\uad70\uc744 \uc7a1\ub294\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uc911\uac04\uc5d0 \uae30\ubb3c \uc874\uc7ac \uc5ec\ubd80"}),(0,s.jsx)(n.br,{}),"\n","\uc774\ub3d9 \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\uba74 \uc548\ub41c\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0ac\uc6a9"}),(0,s.jsx)(n.br,{}),"\n","\uccb4\uc2a4 \ubbf8\uc158\uc740 \ud2b9\ubcc4\ud558\uac8c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc5f0\uacb0\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uccb4\uc2a4 \uac8c\uc784\uc758 \uc0c1\ud0dc\ub97c \ub2e4\uc74c\uc758 \ub450\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uc815\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95"}),"\n",(0,s.jsx)(n.li,{children:"\uae30\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uac8c\uc784\uc744 \ubd88\ub7ec\uc640 \uae30\ubcf4\ub300\ub85c \uc774\ub3d9\uc2dc\ud0a4\ub294 \ubc29\ubc95"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["\uae30\ubb3c\uc774 \uc774\ub3d9\ud560 \ub54c\ub9c8\ub2e4 \uac12\uc744 \uc800\uc7a5\ud558\uace0 \uc2f6\uc5c8\uace0, \uae30\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\uc9c0 \uc54a\uc740 \uc774\uc720\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\ud134\uacfc \uac19\uc740 \ubd80\uac00\uc801\uc778 \uc694\uc18c\ub97c \uc800\uc7a5\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,s.jsx)(n.li,{children:"\uc774\ub3d9\uc744 \ud560 \ub54c \uae30\ubb3c\uc774 \uc7a1\ud788\ub294 \uacbd\uc6b0 update \ucffc\ub9ac(\uc774\ub3d9 \uae30\ubb3c)\uc640 delete(\uc7a1\ud78c \uae30\ubb3c) 2\uac1c\uc758 \ucffc\ub9ac\ub97c \ub0a0\ub824\uc57c \ud55c\ub2e4."}),"\n",(0,s.jsx)(n.li,{children:"\ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ub3c4\uba54\uc778\uc758 \ubcc0\uacbd\uc774 \ud06c\uac8c(\ucd08\uae30 \uc0c1\ud0dc\ub97c \uad6c\uc131\ud558\ub294 \ubd80\ubd84) \uc77c\uc5b4\ub098\uc57c \ud55c\ub2e4."}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["\uc815\ub9ac\ud558\uc790\uba74 \uae30\ubb3c \uc804\uccb4 \uc800\uc7a5\uacfc \uae30\ubcf4 \uc800\uc7a5\uc740 \ub2e4\uc74c\uacfc \ucc28\uc774\uac00 \uc788\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ubcf4\ub4dc\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc\uc5d0\uc11c 32\uac1c\uc758 Insert \ucffc\ub9ac(\uae30\ubb3c\uc758 \uc704\uce58) + \uae30\ubb3c \uc774\ub3d9 \uc2dc \uc6c0\uc9c1\uc784 \ubcc0\uacbd(\uc7a1\ud788\ub294 \uacbd\uc6b0 2\uac1c\uc758 \ucffc\ub9ac)",(0,s.jsx)(n.br,{}),"\n","\uae30\ubcf4\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uad6c\uc131 + \uc800\uc7a5\ub41c \uae30\ubcf4\ub97c select \ucffc\ub9ac\ub85c \uc870\ud68c\ud574\uc11c \uc0ac\uc6a9(1\ud68c) + insert \ucffc\ub9ac(\uc774\ub3d9 \ub2f9 1\ud68c)"]}),"\n",(0,s.jsx)(n.p,{children:"\ucd94\uac00\ub85c \uae30\ubcf4\uc800\uc7a5\uc774 \uad6c\ud604\ub3c4 \ub354\uc6b1 \uac04\ub2e8\ud558\ub2e4. \ud83d\udc4d"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"\ubd80\uac00\uc801\uc778 \ubd80\ubd84"})}),"\n",(0,s.jsx)(n.p,{children:"\ub9ac\ubdf0\uc5b4\uc778 \ucc30\ub9ac\ud83c\udf6b\uac00 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \uac8c\uc784\uc774 \uc9c4\ud589\ub41c\ub2e4\uba74 \uc5b4\ub5a8\uc9c0? \uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ub2e4\uc591\ud55c \uc2dc\ub3c4\ub97c \ud574\ubd24\ub2e4."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"\ub204\ub204\uc758 \ub3c4\uc6c0\uc73c\ub85c ConnectionPool \uad6c\ud604"}),"\n",(0,s.jsx)(n.li,{children:"ThreadLocal \uc0ac\uc6a9\ud574\uc11c \uc4f0\ub808\ub4dc \ubcc4 \uc138\uc158 \uad00\ub9ac"}),"\n",(0,s.jsx)(n.li,{children:"\uc2e4\uc81c\ub85c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4\uc5d0\uc11c \uccb4\uc2a4 \uac8c\uc784\uc774 \uc9c4\ud589\ub418\ub294 Board\ub97c ConcurrentHashMap\uc73c\ub85c \uc800\uc7a5(\uc0ac\uc2e4 \uc774 \ubd80\ubd84\uc740 \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ud544\uc694\uc5c6\uc9c0\ub9cc 2\uba85\uc774 \uc11c\ub85c \uac8c\uc784\ud558\ub294 \uacbd\uc6b0\ub97c \uc0dd\uac01\ud574\uc11c \ub123\uc5b4\ubcf4\uc558\ub2e4.)"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"\ub450 \uba85\uc774 \uc11c\ub85c \uac19\uc740 \ubc29\uc5d0 \uc785\uc7a5\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4\uba74 \ucd9c\ub825\ud558\ub294 \ubd80\ubd84\uc774 \uae4c\ub2e4\ub85c\uc6cc\uc9c8 \uac83 \uac19\ub2e4\uace0 \uc608\uc0c1\ub418\uc5b4(Board\uc5d0 \uc635\uc800\ubc84 \ud328\ud134\uc744 \uc0ac\uc6a9\ud574\uc57c\ub418\ub098?) \ud574\ubcfc \uc5c4\ub450\uac00 \ub098\uc9c0 \uc54a\uc558\ub2e4."}),"\n",(0,s.jsx)(n.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc9c0 \ubabb\ud55c \ubd80\ubd84"}),(0,s.jsx)(n.br,{}),"\n","DB \uad00\ub828 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub3c4\uba54\uc778 \ub85c\uc9c1\uc5d0\ub9cc \uc9d1\uc911\ud558\ub2e4\ubcf4\ub2c8 \uc815\uc801 \uc911\uc694\ud55c DB\uc758 \ucf54\ub4dc\uc758 \uc608\uc678\ucc98\ub9ac, \ube48 \uac12\uc744 \ubc18\ud658 \ud558\ub294 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucc98\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \ucc30\ub9ac\uc758 \uaf3c\uaf3c\ud55c \ub9ac\ubdf0\ub85c DB\ubd80\ubd84\uacfc \ub098\ub9cc\uc758 JdbcTemplate\uc744 \uae54\ub054\ud558\uac8c \uad6c\ud604\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ub2f4\uac10"}),(0,s.jsx)(n.br,{}),"\n","\ucd08\ubc18\uc5d0\ub294 \uc5ec\uc720\ub86d\uc9c0\ub9cc \uc81c\ucd9c \ub9c8\uac10\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \uc218\ub85d \uc0ac\ub78c\uc774 \uae09\ud574\uc9c0\ub294 \uac83 \uac19\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub2e4\uc74c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\ud560 \ub550 \uc18d\ub3c4\ub97c \uc870\uc808\ud558\uace0, \ub9c8\uc74c\uc5d0 \uc5ec\uc720\ub97c \uac00\uc838\uc57c\uaca0\ub2e4."]}),"\n",(0,s.jsx)(n.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"DAO \uc911\ubcf5 \uc81c\uac70"})}),"\n",(0,s.jsxs)(n.p,{children:["\ud504\ub864\ub85c\uadf8\uc5d0 ",(0,s.jsx)(n.a,{href:"https://prolog.techcourse.co.kr/studylogs/2947",children:"\uae00"}),"\uc744 \uc791\uc131\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","DAO\ub97c \uc791\uc131\ud558\ub294\ub370 try-catch-resources\uc640 \uc5ec\ub7ec \ucf54\ub4dc\uac00 \uc911\ubcf5\ub418\uc11c \uc81c\uac70\ud558\uace0\uc2f6\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc73c\ub85c \uae54\ub054\ud558\uac8c \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\udc4d"]}),"\n",(0,s.jsx)(n.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\ud398\uc5b4 \uc0dd\uac01\ud558\uae30"}),(0,s.jsx)(n.br,{}),"\n","\uac00\ube44\ub294 \ub204\uad6c\ubcf4\ub2e4 \ud398\uc5b4\ub97c \uc0dd\uac01\ud558\uace0, \ubc30\ub824\ud574\uc8fc\ub294 \ud398\uc5b4\uc600\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uc911\uac04 \uc911\uac04 \ub2f9 \ub5a8\uc5b4\uc9c8\uae4c\ubd10 \uac71\uc815\ub3c4 \ud574\uc8fc\uace0, \ub098\uc758 \ucee8\ub514\uc158\ub3c4 \ud655\uc778\ud574\uc92c\ub2e4!"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\ubbf8\uc158 \ubab0\uc785\ud558\uae30"}),(0,s.jsx)(n.br,{}),"\n","\ucd5c\uadfc\uc5d0 \ubbf8\uc158\uc5d0 \uc798 \ubab0\uc785\ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uac00\ube44\ub294 \ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \ubbf8\uc158\uc5d0 \ub300\ud55c \ubab0\uc785\ub3c4\uac00 \ub9e4\uc6b0 \uc88b\uc558\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\uc9d1\uc5d0\uac00\uc11c\ub3c4 \uccb4\uc2a4 \uc774\ub3d9\uc5d0 \ub300\ud55c \ub85c\uc9c1\uc744 \uc5b4\ub5bb\uac8c \uad6c\ud604\ud560 \uc9c0 \uc0dd\uac01\ud55c \ub4a4 \uaf3c\uaf3c\ud574\uc11c \uc815\ub9ac\ud574\uc11c \ub098\uc5d0\uac8c \ubcf4\ub0b4\uc8fc\uc5c8\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub355\ubd84\uc5d0 \ub098\ub3c4 \uac00\ube44\uc758 \uc0dd\uac01\uc744 \uc54c \uc218 \uc788\uc5b4\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294\ub370 \uac00\uc18d\ub3c4\uac00 \ubd99\uc740 \uac83 \uac19\ub2e4.",(0,s.jsx)(n.br,{}),"\n","\ub610\ud55c \ubbf8\uc158\uc744 \uc798 \ub9c8\ubb34\ub9ac\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c\uc774 \uc804\ub2ec\ub418\uc11c \uadf8\ub7f0\uc9c0 \ub098\ub3c4 \ub369\ub2ec\uc544 \uc5f4\uc2ec\ud788 \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\ude04"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"\uc194\uc9c1\ud568"}),(0,s.jsx)(n.br,{}),"\n","\uba3c\uc800 \ud68c\uace0\ud558\uc790\uace0 \ub9d0 \uac78\uc5b4\uc918\uc11c \uc815\ub9d0 \uace0\ub9c8\uc6e0\ub2e4\uace0 \ud45c\ud604\ud574\uc8fc\ub294 \ubd80\ubd84",(0,s.jsx)(n.br,{}),"\n","\ubaa8\ub974\ub294\uac8c \uc788\uc73c\uba74 \uc194\uc9c1\ud558\uac8c \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84",(0,s.jsx)(n.br,{}),"\n","\ub098\uc758 \uc758\uacac\uc744 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud55c \uc0c1\ud0dc\ub85c \uc804\ub2ec\ud560 \ub54c \uc774\ud574\uac00 \uc548\ub418\uc5c8\ub2e4\uace0 \uc815\ud655\ud788 \uc804\ub2ec\ud574\uc8fc\ub294 \ubd80\ubd84",(0,s.jsx)(n.br,{}),"\n","\uc194\uc9c1\ud568\uc740 \ud398\uc5b4\ud560 \ub54c \uc911\uc694\ud55c \ubd80\ubd84\uc778 \uac83 \uac19\ub2e4."]}),"\n",(0,s.jsx)(n.p,{children:"\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ucc30\ub9ac\ud83c\udf6b \uccb4\uc2a4 \ubbf8\uc158\ub54c \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0 \ub0a8\uaca8\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4!"})]})}function j(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var s=r(67294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function c(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);n&&(s=s.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,s)}return r}function i(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?c(Object(r),!0).forEach((function(n){t(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):c(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function l(e,n){if(null==e)return{};var r,s,t=function(e,n){if(null==e)return{};var r,s,t={},c=Object.keys(e);for(s=0;s<c.length;s++)r=c[s],n.indexOf(r)>=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(s=0;s<c.length;s++)r=c[s],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var o=s.createContext({}),a=function(e){var n=s.useContext(o),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},h={inlineCode:"code",wrapper:function(e){var n=e.children;return s.createElement(s.Fragment,{},n)}},j=s.forwardRef((function(e,n){var r=e.components,t=e.mdxType,c=e.originalType,o=e.parentName,j=l(e,["components","mdxType","originalType","parentName"]),x=a(r),p=t,d=x["".concat(o,".").concat(p)]||x[p]||h[p]||c;return r?s.createElement(d,i(i({ref:n},j),{},{components:r})):s.createElement(d,i({ref:n},j))}));j.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/8a27aeff.2359b403.js b/assets/js/8a27aeff.2359b403.js new file mode 100644 index 000000000..818a419a5 --- /dev/null +++ b/assets/js/8a27aeff.2359b403.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[71],{57041:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var n=t(85893),s=t(3905);const i={title:"2022\ub144 \ud68c\uace0",slug:"2022-retrospective",tags:["Retrospective"]},o=void 0,c={permalink:"/2022-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",title:"2022\ub144 \ud68c\uace0",description:"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70",date:"2023-01-02T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 2\uc77c",tags:[{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.705,hasTruncateMarker:!1,authors:[],frontMatter:{title:"2022\ub144 \ud68c\uace0",slug:"2022-retrospective",tags:["Retrospective"]},unlisted:!1,prevItem:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",permalink:"/the-essence-of-object-orientation"},nextItem:{title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",permalink:"/book-writer"}},l={authorsImageUrls:[]},a=[{value:"\uc804\uc5ed",id:"\uc804\uc5ed",level:3},{value:"\uc790\ubc14",id:"\uc790\ubc14",level:3},{value:"\uc2a4\ud130\ub514",id:"\uc2a4\ud130\ub514",level:3},{value:"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4",id:"\uc6b0\uc544\ud55c-\ud14c\ud06c\ucf54\uc2a4",level:3},{value:"2023\ub144\uc5d0\ub294",id:"2023\ub144\uc5d0\ub294",level:3}];function p(e){const r={a:"a",br:"br",h3:"h3",p:"p",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.p,{children:"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70"}),"\n",(0,n.jsx)(r.h3,{id:"\uc804\uc5ed",children:"\uc804\uc5ed"}),"\n",(0,n.jsxs)(r.p,{children:["\uc57d 1\ub144 6\uac1c\uc6d4\uac04\uc758 \uacf5\uad70 \uc815\ubcf4\ubcf4\ud638\ubcd1 \uc0dd\ud65c\uc744 \ub9c8\uce58\uace0 \uc804\uc5ed\uc744 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc870\uae30 \uc804\uc5ed \ub54c\ubb38\uc5d0 2021\ub144 12\uc6d4\uc5d0 \ub098\uc654\uc9c0\ub9cc, \uc2e4\uc81c \uc804\uc5ed \ub0a0\uc9dc\ub294 2022\ub144\uc774\ub2c8 \ud68c\uace0\uc5d0 \uc801\uc5b4\ub3c4 \uc0c1\uad00\uc5c6\uaca0\uc9c0."]}),"\n",(0,n.jsxs)(r.p,{children:["\uc870\uae08 \ub354 \ubbf8\ub798\uc5d0 \ub300\ud55c \uc0dd\uac01\uc744 \ud574\ubcfc\uac78 \uadf8\ub7ac\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc804\uc5ed\uc744 \ud588\uc9c0\ub9cc \ubb50 \ud558\ub098 \uc81c\ub300\ub85c \ud560 \uc904 \uc544\ub294 \uac83\ub3c4 \uc5c6\uc73c\ub2c8 \ub113\uc740 \ubc14\ub2f7\uc18d\uc5d0 \ub369\uadf8\ub7ec\ub2c8 \ub193\uc544\uc9c4 \uae30\ubd84\uc774 \uad1c\ud788 \ub4e4\uc5c8\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc77c\ucc0d \uc0dd\uac01\uc744 \uc815\ub9ac\ud558\uc5ec \ubc29\ud5a5\uc744 \uc7a1\uc9c0 \ubabb\ud588\uae30\uc5d0 \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub0a8\uc558\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc790\ubc14",children:"\uc790\ubc14"}),"\n",(0,n.jsxs)(r.p,{children:["\uc804\uc5ed\uc744 \ud558\uace0 \uc9c4\ub85c\ub97c \uace0\ubbfc\ud558\ub2e4 \ud5a5\ub85c\ub2d8\uc758 ",(0,n.jsx)(r.a,{href:"https://jojoldu.tistory.com/609",children:"\uc790\ubc14 \uacf5\ud654\uad6d"})," \ud3ec\uc2a4\ud305\uc744 \uc77d\uace0 \ub098\uc11c \uc790\ubc14 \uacf5\ubd80\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc720\uba85\ud55c \uc778\ud504\ub7f0\uc758 \uae40\uc601\ud55c\ub2d8\uc758 \uc2a4\ud504\ub9c1 \uac15\uc758\ub3c4 \uc788\uace0, \uc88b\uc740 \uc790\ubc14 \uac1c\ubc1c \uc11c\uc801\uc774 \ub9ce\uc544\uc11c \ub3c5\ud559\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud558\ub2e4 \ubcf4\ub2c8 \uc790\ubc14\uc640 \uc2a4\ud504\ub9c1\uc744 \uacf5\ubd80\ud558\uba74\uc11c \u201c\uc65c \uc9c4\uc791\ud558\uc9c0 \uc54a\uc558\uc9c0\u201d\ub77c\ub294 \uc0dd\uac01\ub3c4 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc591\uc9c8\uc758 \uc790\ub8cc\ub3c4 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0, \uc608\uc804\uc5d0 \ub178\ub4dc\ub85c \uac1c\ubc1c\ud588\uc744 \ub54c \ud480\uc9c0 \ubabb\ud588\ub358 \ub2f5\ub2f5\ud568\uc744 \ub9ce\uc774 \ud574\uc18c\ud588\ub358 \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["23\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae4a\uac8c \uc790\ubc14\ub97c \uacf5\ubd80\ud574\ubcfc \uc0dd\uac01\uc774\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc5b8\uc5b4\ub97c \ud558\ub098 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ub9ce\uc740 \ub3c4\uc6c0\uc774 \ub418\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc2a4\ud130\ub514",children:"\uc2a4\ud130\ub514"}),"\n",(0,n.jsxs)(r.p,{children:["\uae40\uc601\ud55c\ub2d8\uc758 \uac15\uc758\ub97c \uac70\uc758 \ub2e4 \ub4e4\uc5c8\uc744 \ub54c\ucbe4, \ud56d\uc0c1 \uac15\uc758\uc5d0\uc11c \uc5b8\uae09\ub418\ub294 \ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1\uc744 \uc77d\uc5b4\ubcf4\uace0 \uc2f6\uc5b4\uc84c\uace0",(0,n.jsx)(r.br,{}),"\n","\ud63c\uc790 \uacf5\ubd80\ud558\uae30\uc5d0\ub294 \ub3d9\uae30\ubd80\uc5ec\ub3c4 \ubd80\uc871\ud588\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud130\ub514\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub2e4\ub978 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\uc744 \ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uacf5\ubd80\ub97c \ud560 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\uc9c0\ub9cc \ub098\uc5d0\uac8c\ub294 \ub0b4\uc6a9\uc774 \uaf64\ub098 \uc5b4\ub824\uc6cc\uc11c \uc2dc\uac04\uc744 \ub9ce\uc774 \uc18c\ube44\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uac19\uc774 \uc2a4\ud130\ub514\ud558\uc2dc\ub294 \ubd84\uacfc 7\uac1c\uc6d4 \ub3d9\uc548 \uc2a4\ud130\ub514\ub97c \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00 \ucd1d 3\uad8c\uc758 \ucc45\uc744 \uc77d\uc744 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc6b0\uc544\ud55c-\ud14c\ud06c\ucf54\uc2a4",children:"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4"}),"\n",(0,n.jsxs)(r.p,{children:["\uad70 \ubcf5\ubb34 \uc911\uc77c \ub54c \uc9c0\uc6d0\ud588\ub2e4 \ub5a8\uc5b4\uc9c4 \uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ub2e4\uc2dc \uc9c0\uc6d0\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc774\ubc88 \uc5f0\ub3c4\uc5d0 \ucde8\uc5c5\uc744 \ud558\ub294 \uac8c \ubaa9\ud45c\uc600\uc9c0\ub9cc \ub0b4\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \ud2b9\ubcc4\ud55c \ubb34\uae30\uac00 \uc5c6\ub2e4\ub294 \uac78 \uae68\ub2ec\uc558\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc801\uc9c0 \uc54a\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574 \uc900\ube44\ub97c \ud588\uace0, \uac10\uc0ac\ud558\uac8c\ub3c4 \uc774\ubc88\uc5d0\ub294 \ucd5c\uc885 \ud569\uaca9\uc744 \ud588\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ub09c \uc0ac\ub78c\ub4e4\uacfc \uc18c\ud1b5\ud558\uace0, \ud611\uc5c5\ud558\ub294 \ub2a5\ub825\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ud1b5\ud574 \uadf8 \ube48 \ubd80\ubd84\uc744 \ucc44\uc6b0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"2023\ub144\uc5d0\ub294",children:"2023\ub144\uc5d0\ub294"}),"\n",(0,n.jsxs)(r.p,{children:["\ub9c8\uc74c\uc758 \uc5ec\uc720\uac00 \uc5c6\uc5c8\ub358 2022\ub144\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud558\uace0 \uc2f6\uc740 \uac74 \ub9ce\uc9c0\ub9cc, \uc774\ubc88\uc5d0\ub294 \uc5ec\uc720\ub97c \uac00\uc9c0\uace0 \ud560 \uc218 \uc788\ub294 \uac83\uc5d0 \ucd5c\uc120\uc744 \ub2e4\ud574\uc57c\uaca0\ub2e4."]})]})}function u(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>a});var n=t(67294);function s(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function o(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){s(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function c(e,r){if(null==e)return{};var t,n,s=function(e,r){if(null==e)return{};var t,n,s={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(s[t]=e[t]);return s}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var l=n.createContext({}),a=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):o(o({},r),e)),t},p={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},u=n.forwardRef((function(e,r){var t=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),d=a(t),b=s,j=d["".concat(l,".").concat(b)]||d[b]||p[b]||i;return t?n.createElement(j,o(o({ref:r},u),{},{components:t})):n.createElement(j,o({ref:r},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/8a27aeff.630953b4.js b/assets/js/8a27aeff.630953b4.js deleted file mode 100644 index a29801757..000000000 --- a/assets/js/8a27aeff.630953b4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[71],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=c(r),b=a,f=m["".concat(i,".").concat(b)]||m[b]||s[b]||o;return r?n.createElement(f,p(p({ref:t},u),{},{components:r})):n.createElement(f,p({ref:t},u))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,p=new Array(o);p[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,p[1]=l;for(var c=2;c<o;c++)p[c]=r[c];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},17442:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>s,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"2022\ub144 \ud68c\uace0",slug:"2022-retrospective",tags:["Retrospective"]},p=void 0,l={permalink:"/2022-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",title:"2022\ub144 \ud68c\uace0",description:"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70",date:"2023-01-02T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 2\uc77c",tags:[{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.705,hasTruncateMarker:!1,authors:[],frontMatter:{title:"2022\ub144 \ud68c\uace0",slug:"2022-retrospective",tags:["Retrospective"]},prevItem:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",permalink:"/the-essence-of-object-orientation"},nextItem:{title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",permalink:"/book-writer"}},i={authorsImageUrls:[]},c=[{value:"\uc804\uc5ed",id:"\uc804\uc5ed",level:3},{value:"\uc790\ubc14",id:"\uc790\ubc14",level:3},{value:"\uc2a4\ud130\ub514",id:"\uc2a4\ud130\ub514",level:3},{value:"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4",id:"\uc6b0\uc544\ud55c-\ud14c\ud06c\ucf54\uc2a4",level:3},{value:"2023\ub144\uc5d0\ub294",id:"2023\ub144\uc5d0\ub294",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70 "),(0,a.kt)("h3",{id:"\uc804\uc5ed"},"\uc804\uc5ed"),(0,a.kt)("p",null,"\uc57d 1\ub144 6\uac1c\uc6d4\uac04\uc758 \uacf5\uad70 \uc815\ubcf4\ubcf4\ud638\ubcd1 \uc0dd\ud65c\uc744 \ub9c8\uce58\uace0 \uc804\uc5ed\uc744 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc870\uae30 \uc804\uc5ed \ub54c\ubb38\uc5d0 2021\ub144 12\uc6d4\uc5d0 \ub098\uc654\uc9c0\ub9cc, \uc2e4\uc81c \uc804\uc5ed \ub0a0\uc9dc\ub294 2022\ub144\uc774\ub2c8 \ud68c\uace0\uc5d0 \uc801\uc5b4\ub3c4 \uc0c1\uad00\uc5c6\uaca0\uc9c0. "),(0,a.kt)("p",null,"\uc870\uae08 \ub354 \ubbf8\ub798\uc5d0 \ub300\ud55c \uc0dd\uac01\uc744 \ud574\ubcfc\uac78 \uadf8\ub7ac\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc804\uc5ed\uc744 \ud588\uc9c0\ub9cc \ubb50 \ud558\ub098 \uc81c\ub300\ub85c \ud560 \uc904 \uc544\ub294 \uac83\ub3c4 \uc5c6\uc73c\ub2c8 \ub113\uc740 \ubc14\ub2f7\uc18d\uc5d0 \ub369\uadf8\ub7ec\ub2c8 \ub193\uc544\uc9c4 \uae30\ubd84\uc774 \uad1c\ud788 \ub4e4\uc5c8\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ucc0d \uc0dd\uac01\uc744 \uc815\ub9ac\ud558\uc5ec \ubc29\ud5a5\uc744 \uc7a1\uc9c0 \ubabb\ud588\uae30\uc5d0 \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub0a8\uc558\ub2e4. "),(0,a.kt)("h3",{id:"\uc790\ubc14"},"\uc790\ubc14"),(0,a.kt)("p",null,"\uc804\uc5ed\uc744 \ud558\uace0 \uc9c4\ub85c\ub97c \uace0\ubbfc\ud558\ub2e4 \ud5a5\ub85c\ub2d8\uc758 ",(0,a.kt)("a",{parentName:"p",href:"https://jojoldu.tistory.com/609"},"\uc790\ubc14 \uacf5\ud654\uad6d")," \ud3ec\uc2a4\ud305\uc744 \uc77d\uace0 \ub098\uc11c \uc790\ubc14 \uacf5\ubd80\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc720\uba85\ud55c \uc778\ud504\ub7f0\uc758 \uae40\uc601\ud55c\ub2d8\uc758 \uc2a4\ud504\ub9c1 \uac15\uc758\ub3c4 \uc788\uace0, \uc88b\uc740 \uc790\ubc14 \uac1c\ubc1c \uc11c\uc801\uc774 \ub9ce\uc544\uc11c \ub3c5\ud559\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\ub2e4 \ubcf4\ub2c8 \uc790\ubc14\uc640 \uc2a4\ud504\ub9c1\uc744 \uacf5\ubd80\ud558\uba74\uc11c \u201c\uc65c \uc9c4\uc791\ud558\uc9c0 \uc54a\uc558\uc9c0\u201d\ub77c\ub294 \uc0dd\uac01\ub3c4 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc591\uc9c8\uc758 \uc790\ub8cc\ub3c4 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0, \uc608\uc804\uc5d0 \ub178\ub4dc\ub85c \uac1c\ubc1c\ud588\uc744 \ub54c \ud480\uc9c0 \ubabb\ud588\ub358 \ub2f5\ub2f5\ud568\uc744 \ub9ce\uc774 \ud574\uc18c\ud588\ub358 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,"23\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae4a\uac8c \uc790\ubc14\ub97c \uacf5\ubd80\ud574\ubcfc \uc0dd\uac01\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc5b8\uc5b4\ub97c \ud558\ub098 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ub9ce\uc740 \ub3c4\uc6c0\uc774 \ub418\ub294 \uac83 \uac19\ub2e4."),(0,a.kt)("h3",{id:"\uc2a4\ud130\ub514"},"\uc2a4\ud130\ub514"),(0,a.kt)("p",null,"\uae40\uc601\ud55c\ub2d8\uc758 \uac15\uc758\ub97c \uac70\uc758 \ub2e4 \ub4e4\uc5c8\uc744 \ub54c\ucbe4, \ud56d\uc0c1 \uac15\uc758\uc5d0\uc11c \uc5b8\uae09\ub418\ub294 \ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1\uc744 \uc77d\uc5b4\ubcf4\uace0 \uc2f6\uc5b4\uc84c\uace0",(0,a.kt)("br",{parentName:"p"}),"\n","\ud63c\uc790 \uacf5\ubd80\ud558\uae30\uc5d0\ub294 \ub3d9\uae30\ubd80\uc5ec\ub3c4 \ubd80\uc871\ud588\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud130\ub514\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\uc744 \ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uacf5\ubd80\ub97c \ud560 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\uc9c0\ub9cc \ub098\uc5d0\uac8c\ub294 \ub0b4\uc6a9\uc774 \uaf64\ub098 \uc5b4\ub824\uc6cc\uc11c \uc2dc\uac04\uc744 \ub9ce\uc774 \uc18c\ube44\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac19\uc774 \uc2a4\ud130\ub514\ud558\uc2dc\ub294 \ubd84\uacfc 7\uac1c\uc6d4 \ub3d9\uc548 \uc2a4\ud130\ub514\ub97c \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00 \ucd1d 3\uad8c\uc758 \ucc45\uc744 \uc77d\uc744 \uc218 \uc788\uc5c8\ub2e4."),(0,a.kt)("h3",{id:"\uc6b0\uc544\ud55c-\ud14c\ud06c\ucf54\uc2a4"},"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4"),(0,a.kt)("p",null,"\uad70 \ubcf5\ubb34 \uc911\uc77c \ub54c \uc9c0\uc6d0\ud588\ub2e4 \ub5a8\uc5b4\uc9c4 \uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ub2e4\uc2dc \uc9c0\uc6d0\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \uc5f0\ub3c4\uc5d0 \ucde8\uc5c5\uc744 \ud558\ub294 \uac8c \ubaa9\ud45c\uc600\uc9c0\ub9cc \ub0b4\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \ud2b9\ubcc4\ud55c \ubb34\uae30\uac00 \uc5c6\ub2e4\ub294 \uac78 \uae68\ub2ec\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc801\uc9c0 \uc54a\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574 \uc900\ube44\ub97c \ud588\uace0, \uac10\uc0ac\ud558\uac8c\ub3c4 \uc774\ubc88\uc5d0\ub294 \ucd5c\uc885 \ud569\uaca9\uc744 \ud588\ub2e4. "),(0,a.kt)("p",null,"\ub09c \uc0ac\ub78c\ub4e4\uacfc \uc18c\ud1b5\ud558\uace0, \ud611\uc5c5\ud558\ub294 \ub2a5\ub825\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ud1b5\ud574 \uadf8 \ube48 \ubd80\ubd84\uc744 \ucc44\uc6b0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"2023\ub144\uc5d0\ub294"},"2023\ub144\uc5d0\ub294"),(0,a.kt)("p",null,"\ub9c8\uc74c\uc758 \uc5ec\uc720\uac00 \uc5c6\uc5c8\ub358 2022\ub144\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uace0 \uc2f6\uc740 \uac74 \ub9ce\uc9c0\ub9cc, \uc774\ubc88\uc5d0\ub294 \uc5ec\uc720\ub97c \uac00\uc9c0\uace0 \ud560 \uc218 \uc788\ub294 \uac83\uc5d0 \ucd5c\uc120\uc744 \ub2e4\ud574\uc57c\uaca0\ub2e4."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8ad2f007.9b356e06.js b/assets/js/8ad2f007.9b356e06.js new file mode 100644 index 000000000..6bae46b4b --- /dev/null +++ b/assets/js/8ad2f007.9b356e06.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8360],{6073:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var n=r(85893),o=r(3905);const c={title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",slug:"mock-static-method",tags:["Mockito","static"]},i=void 0,a={permalink:"/mock-static-method",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",source:"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",description:"\uac1c\uc694",date:"2023-07-30T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 30\uc77c",tags:[{label:"Mockito",permalink:"/tags/mockito"},{label:"static",permalink:"/tags/static"}],readingTime:2.635,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",slug:"mock-static-method",tags:["Mockito","static"]},unlisted:!1,prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",permalink:"/route-image-python"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",permalink:"/route-image-intro"}},s={authorsImageUrls:[]},l=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"Mocking static methods",id:"mocking-static-methods",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function m(e){const t={a:"a",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",...(0,o.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,n.jsxs)(t.p,{children:["\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud55c\ub2e4\ub294 \uac83\uc740 \uac1d\uccb4\uc9c0\ud5a5\uc801\uc778 \uad00\uc810\uc5d0\uc11c \ubcfc \ub54c \uc548\ud2f0\ud328\ud134\uc774\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud558\uc9c0\ub9cc \ud2b9\uc218\ud55c \uacbd\uc6b0\uc5d0\ub294 \uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc774 \ud544\uc694\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.p,{children:"\uc608\ub97c \ub4e4\uc5b4 \ub808\uac70\uc2dc \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud55c\ub2e4\ub358\uc9c0, IO \uad00\ub828\ud55c \ubd80\ubd84\uc744 \ud14c\uc2a4\ud2b8 \ud560 \ub54c \uc815\ub9d0 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\ub9cc \uc801\uc6a9\ud560 \uc218 \uc788\uc744 \uac83\uc774\ub2e4."}),"\n",(0,n.jsxs)(t.p,{children:["\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba70 ImageIo.write \uba54\uc11c\ub4dc\uac00 \ud638\ucd9c\ub418\ub294 \uc9c0 \uac80\uc99d\uc774 \ud544\uc694\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud574\ub2f9 static \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294 \ubd80\ubd84\uc744 \ub530\ub85c RouteImageUploader \ud074\ub798\uc2a4\ub85c \ucd5c\ub300\ud55c \ubd84\ub9ac\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc800\uc7a5 \uae30\ub2a5 \uc790\uccb4\uac00 \uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc774\uace0, \ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc0ac\ud558\ub294\ub370\ub294 mock\uc744 \uc0ac\uc6a9\ud558\ub294\uac8c \uc801\uc808\ud558\ub2e4\uace0 \ud310\ub2e8\ud588\ub2e4."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-java",children:"public void upload(BufferedImage bufferedImage) {\n File file = new File(\ud30c\uc77c\uacbd\ub85c);\n try {\n ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);\n } catch (IOException e) {\n throw new DrawException(IMAGE_SAVE_FAIL);\n }\n}\n"})}),"\n",(0,n.jsx)(t.h3,{id:"mocking-static-methods",children:"Mocking static methods"}),"\n",(0,n.jsxs)(t.p,{children:["Mockito 3.4.0 \uc774\ud6c4\uc5d0\ub294 static method\ub97c \ubaa8\ud0b9\ud560 \uc218 \uc788\ub294 Mockito.mockStatic \uba54\uc11c\ub4dc\ub97c \uc9c0\uc6d0\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","mockStatic\uc744 \uc0ac\uc6a9\ud558\uba74 ",(0,n.jsx)(t.code,{children:"MockedStatic<T>"}),"\uc774 \ubc18\ud658\ub418\ub294\ub370 \uc0ac\uc6a9 \ud6c4 \uaf2d close\ub97c \ud574\uc918\uc57c \ud55c\ub2e4."]}),"\n",(0,n.jsxs)(t.p,{children:["JUnit\uc758 @BeforeAll\ub85c \uc124\uc815\ud558\uace0 @AfterAll \uba54\uc11c\ub4dc\ub85c \uc885\ub8cc\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\uc9c0\ub9cc ",(0,n.jsx)(t.code,{children:"MockedStatic<T>"}),"\uc758 \uc0c1\uc704 \uc778\ud130\ud398\uc774\uc2a4\uc778 ScopedMock\uc774 AutoCloseable\uc744 \uad6c\ud604\ud558\uace0 \uc788\uae30\uc5d0 try-with-resources\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \ub354\uc6b1 \uc88b\uc740 \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-java",children:"// given\nBufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);\nRouteImageUploader routeImageUploader = new RouteImageUploader();\n\n// expect\ntry (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {\n routeImageUploader.upload(bufferedImage);\n imageIO.verify(\n () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),\n times(1)\n );\n}\n"})}),"\n",(0,n.jsx)(t.h3,{id:"\ub9c8\uce58\uba70",children:"\ub9c8\uce58\uba70"}),"\n",(0,n.jsxs)(t.p,{children:["\uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc740 \uc548\ud2f0\ud328\ud134\uc774\uc73c\ub85c \uc801\uc808\ud55c \ucd94\uc0c1\ud654\ub97c \uc774\uc6a9\ud574 \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc88b\uc740 \ucf54\ub4dc\ub97c \ub9cc\ub4dc\ub294 \uc5f0\uc2b5\uc744 \ud558\uc790.",(0,n.jsx)(t.br,{}),"\n","\ud558\uc9c0\ub9cc \ucd94\uc0c1\ud654\ub97c \ud558\uba74 \ud560 \uc218\ub85d \ucf54\ub4dc\uc758 \ubcf5\uc7a1\ub3c4\ub294 \uc99d\uac00\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud56d\uc0c1 \uc0c1\ud669\uc744 \uace0\ub824\ud558\uace0 \uac04\uacb0\ud568\uc744 \ud3ec\uae30\ud560 \ub9cc\ud07c \uc911\uc694\ud55c \ubd80\ubd84\uc778\uc9c0 \uc801\uc808\ud55c \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uace0\ub824\ud558\uc790."]}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks",children:"Mocking static methods"}),(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.a,{href:"https://www.baeldung.com/mockito-mock-static-methods",children:"Mockito mock static methods"}),(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.a,{href:"https://github.com/mockito/mockito/issues/1013",children:"Enable mocking static methods in Mockito"})]})]})}function d(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(m,{...e})}):m(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function c(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?c(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):c(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},c=Object.keys(e);for(n=0;n<c.length;n++)r=c[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(n=0;n<c.length;n++)r=c[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,c=e.originalType,s=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),u=l(r),p=o,g=u["".concat(s,".").concat(p)]||u[p]||m[p]||c;return r?n.createElement(g,i(i({ref:t},d),{},{components:r})):n.createElement(g,i({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/8ad2f007.b27b51dd.js b/assets/js/8ad2f007.b27b51dd.js deleted file mode 100644 index d59548234..000000000 --- a/assets/js/8ad2f007.b27b51dd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8360],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>k});var a=r(67294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,a)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){n(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,a,n=function(e,t){if(null==e)return{};var r,a,n={},o=Object.keys(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)r=o[a],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var l=a.createContext({}),m=function(e){var t=a.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=m(e.components);return a.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var r=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=m(r),k=n,d=u["".concat(l,".").concat(k)]||u[k]||s[k]||o;return r?a.createElement(d,i(i({ref:t},p),{},{components:r})):a.createElement(d,i({ref:t},p))}));function k(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=r.length,i=new Array(o);i[0]=u;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:n,i[1]=c;for(var m=2;m<o;m++)i[m]=r[m];return a.createElement.apply(null,i)}return a.createElement.apply(null,r)}u.displayName="MDXCreateElement"},96431:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>s,frontMatter:()=>o,metadata:()=>c,toc:()=>m});var a=r(87462),n=(r(67294),r(3905));const o={title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",slug:"mock-static-method",tags:["Mockito","static"]},i=void 0,c={permalink:"/mock-static-method",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",source:"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",description:"\uac1c\uc694",date:"2023-07-30T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 30\uc77c",tags:[{label:"Mockito",permalink:"/tags/mockito"},{label:"static",permalink:"/tags/static"}],readingTime:2.635,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",slug:"mock-static-method",tags:["Mockito","static"]},prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",permalink:"/route-image-python"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",permalink:"/route-image-intro"}},l={authorsImageUrls:[]},m=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"Mocking static methods",id:"mocking-static-methods",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],p={toc:m};function s(e){let{components:t,...r}=e;return(0,n.kt)("wrapper",(0,a.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("h3",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,n.kt)("p",null,"\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud55c\ub2e4\ub294 \uac83\uc740 \uac1d\uccb4\uc9c0\ud5a5\uc801\uc778 \uad00\uc810\uc5d0\uc11c \ubcfc \ub54c \uc548\ud2f0\ud328\ud134\uc774\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ud2b9\uc218\ud55c \uacbd\uc6b0\uc5d0\ub294 \uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc774 \ud544\uc694\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,n.kt)("p",null,"\uc608\ub97c \ub4e4\uc5b4 \ub808\uac70\uc2dc \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud55c\ub2e4\ub358\uc9c0, IO \uad00\ub828\ud55c \ubd80\ubd84\uc744 \ud14c\uc2a4\ud2b8 \ud560 \ub54c \uc815\ub9d0 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\ub9cc \uc801\uc6a9\ud560 \uc218 \uc788\uc744 \uac83\uc774\ub2e4. "),(0,n.kt)("p",null,"\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba70 ImageIo.write \uba54\uc11c\ub4dc\uac00 \ud638\ucd9c\ub418\ub294 \uc9c0 \uac80\uc99d\uc774 \ud544\uc694\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 static \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294 \ubd80\ubd84\uc744 \ub530\ub85c RouteImageUploader \ud074\ub798\uc2a4\ub85c \ucd5c\ub300\ud55c \ubd84\ub9ac\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc800\uc7a5 \uae30\ub2a5 \uc790\uccb4\uac00 \uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc774\uace0, \ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc0ac\ud558\ub294\ub370\ub294 mock\uc744 \uc0ac\uc6a9\ud558\ub294\uac8c \uc801\uc808\ud558\ub2e4\uace0 \ud310\ub2e8\ud588\ub2e4. "),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},"public void upload(BufferedImage bufferedImage) {\n File file = new File(\ud30c\uc77c\uacbd\ub85c);\n try {\n ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);\n } catch (IOException e) {\n throw new DrawException(IMAGE_SAVE_FAIL);\n }\n}\n")),(0,n.kt)("h3",{id:"mocking-static-methods"},"Mocking static methods"),(0,n.kt)("p",null,"Mockito 3.4.0 \uc774\ud6c4\uc5d0\ub294 static method\ub97c \ubaa8\ud0b9\ud560 \uc218 \uc788\ub294 Mockito.mockStatic \uba54\uc11c\ub4dc\ub97c \uc9c0\uc6d0\ud55c\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","mockStatic\uc744 \uc0ac\uc6a9\ud558\uba74 ",(0,n.kt)("inlineCode",{parentName:"p"},"MockedStatic<T>"),"\uc774 \ubc18\ud658\ub418\ub294\ub370 \uc0ac\uc6a9 \ud6c4 \uaf2d close\ub97c \ud574\uc918\uc57c \ud55c\ub2e4. "),(0,n.kt)("p",null,"JUnit\uc758 @BeforeAll\ub85c \uc124\uc815\ud558\uace0 @AfterAll \uba54\uc11c\ub4dc\ub85c \uc885\ub8cc\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\uc9c0\ub9cc ",(0,n.kt)("inlineCode",{parentName:"p"},"MockedStatic<T>"),"\uc758 \uc0c1\uc704 \uc778\ud130\ud398\uc774\uc2a4\uc778 ScopedMock\uc774 AutoCloseable\uc744 \uad6c\ud604\ud558\uace0 \uc788\uae30\uc5d0 try-with-resources\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \ub354\uc6b1 \uc88b\uc740 \uac83 \uac19\ub2e4. "),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},"// given\nBufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);\nRouteImageUploader routeImageUploader = new RouteImageUploader();\n\n// expect\ntry (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {\n routeImageUploader.upload(bufferedImage);\n imageIO.verify(\n () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),\n times(1)\n );\n}\n")),(0,n.kt)("h3",{id:"\ub9c8\uce58\uba70"},"\ub9c8\uce58\uba70"),(0,n.kt)("p",null,"\uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc740 \uc548\ud2f0\ud328\ud134\uc774\uc73c\ub85c \uc801\uc808\ud55c \ucd94\uc0c1\ud654\ub97c \uc774\uc6a9\ud574 \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc88b\uc740 \ucf54\ub4dc\ub97c \ub9cc\ub4dc\ub294 \uc5f0\uc2b5\uc744 \ud558\uc790.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ucd94\uc0c1\ud654\ub97c \ud558\uba74 \ud560 \uc218\ub85d \ucf54\ub4dc\uc758 \ubcf5\uc7a1\ub3c4\ub294 \uc99d\uac00\ud55c\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \uc0c1\ud669\uc744 \uace0\ub824\ud558\uace0 \uac04\uacb0\ud568\uc744 \ud3ec\uae30\ud560 \ub9cc\ud07c \uc911\uc694\ud55c \ubd80\ubd84\uc778\uc9c0 \uc801\uc808\ud55c \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uace0\ub824\ud558\uc790. "),(0,n.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,n.kt)("p",null,(0,n.kt)("a",{parentName:"p",href:"https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks"},"Mocking static methods"),(0,n.kt)("br",{parentName:"p"}),"\n",(0,n.kt)("a",{parentName:"p",href:"https://www.baeldung.com/mockito-mock-static-methods"},"Mockito mock static methods"),(0,n.kt)("br",{parentName:"p"}),"\n",(0,n.kt)("a",{parentName:"p",href:"https://github.com/mockito/mockito/issues/1013"},"Enable mocking static methods in Mockito")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8b79a48d.782b4bba.js b/assets/js/8b79a48d.84d2f0c6.js similarity index 81% rename from assets/js/8b79a48d.782b4bba.js rename to assets/js/8b79a48d.84d2f0c6.js index 47f873485..6ab1fd10e 100644 --- a/assets/js/8b79a48d.782b4bba.js +++ b/assets/js/8b79a48d.84d2f0c6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9287],{59070:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9287],{59070:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/8c6c0796.8c72a84a.js b/assets/js/8c6c0796.7c634fd6.js similarity index 81% rename from assets/js/8c6c0796.8c72a84a.js rename to assets/js/8c6c0796.7c634fd6.js index 8d4af5e84..126b4b7f5 100644 --- a/assets/js/8c6c0796.8c72a84a.js +++ b/assets/js/8c6c0796.7c634fd6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2816],{59123:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2816],{59123:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/8da65e83.884cacff.js b/assets/js/8da65e83.b9934882.js similarity index 77% rename from assets/js/8da65e83.884cacff.js rename to assets/js/8da65e83.b9934882.js index 8ac492998..60d14249a 100644 --- a/assets/js/8da65e83.884cacff.js +++ b/assets/js/8da65e83.b9934882.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9427],{1341:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9427],{1341:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/8e498bb6.a1dd0c3d.js b/assets/js/8e498bb6.ad307809.js similarity index 88% rename from assets/js/8e498bb6.a1dd0c3d.js rename to assets/js/8e498bb6.ad307809.js index 83cd35b0e..b8890ee82 100644 --- a/assets/js/8e498bb6.a1dd0c3d.js +++ b/assets/js/8e498bb6.ad307809.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1436],{50257:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1436],{50257:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/8fbd512b.23ff3cd4.js b/assets/js/8fbd512b.4d36cc4b.js similarity index 88% rename from assets/js/8fbd512b.23ff3cd4.js rename to assets/js/8fbd512b.4d36cc4b.js index 7c2ad6f83..7635fa944 100644 --- a/assets/js/8fbd512b.23ff3cd4.js +++ b/assets/js/8fbd512b.4d36cc4b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5873],{15:s=>{s.exports=JSON.parse('{"label":"async","permalink":"/tags/async","allTagsPath":"/tags","count":2}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5873],{15:s=>{s.exports=JSON.parse('{"label":"async","permalink":"/tags/async","allTagsPath":"/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/905ecccc.0adeb2b8.js b/assets/js/905ecccc.0adeb2b8.js deleted file mode 100644 index 8b7d83f5e..000000000 --- a/assets/js/905ecccc.0adeb2b8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2939],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>d});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=a.createContext({}),c=function(e){var t=a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=c(e.components);return a.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,u=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=c(n),d=r,g=m["".concat(u,".").concat(d)]||m[d]||p[d]||o;return n?a.createElement(g,i(i({ref:t},s),{},{components:n})):a.createElement(g,i({ref:t},s))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var c=2;c<o;c++)i[c]=n[c];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"},85162:(e,t,n)=>{n.d(t,{Z:()=>i});var a=n(67294),r=n(86010);const o="tabItem_Ymn6";function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,i),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>S});var a=n(87462),r=n(67294),o=n(86010),i=n(12466),l=n(16550),u=n(91980),c=n(67392),s=n(50012);function p(e){return function(e){return r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function m(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,n])}function d(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function g(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),o=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function k(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=m(e),[i,l]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!d({value:t,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=n.find((e=>e.default))??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:o}))),[u,c]=g({queryString:n,groupId:a}),[p,k]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,s.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),f=(()=>{const e=u??p;return d({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{f&&l(f)}),[f]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!d({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);l(e),c(e),k(e)}),[c,k,o]),tabValues:o}}var f=n(72389);const b="tabList__CuJ",h="tabItem_LNqP";function N(e){let{className:t,block:n,selectedValue:l,selectValue:u,tabValues:c}=e;const s=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),m=e=>{const t=e.currentTarget,n=s.indexOf(t),a=c[n].value;a!==l&&(p(t),u(a))},d=e=>{let t=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const n=s.indexOf(e.currentTarget)+1;t=s[n]??s[0];break}case"ArrowLeft":{const n=s.indexOf(e.currentTarget)-1;t=s[n]??s[s.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>s.push(e),onKeyDown:d,onClick:m},i,{className:(0,o.Z)("tabs__item",h,i?.className,{"tabs__item--active":l===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;const o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function C(e){const t=k(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",b)},r.createElement(N,(0,a.Z)({},e,t)),r.createElement(v,(0,a.Z)({},e,t)))}function S(e){const t=(0,f.Z)();return r.createElement(C,(0,a.Z)({key:String(t)},e))}},1057:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>u,default:()=>d,frontMatter:()=>l,metadata:()=>c,toc:()=>p});var a=n(87462),r=(n(67294),n(3905)),o=n(74866),i=n(85162);const l={title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"tomcat-retrospective",tags:["Woowahan Techcourse","Retrospective"]},u=void 0,c={permalink:"/tomcat-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1, 2\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-http/pull/302",date:"2023-09-11T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 11\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:12.345,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"tomcat-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",permalink:"/log-async-exception"},nextItem:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",permalink:"/performance-test-type"}},s={authorsImageUrls:[]},p=[{value:"\ud1b0\ucea3 \uad6c\ud604",id:"\ud1b0\ucea3-\uad6c\ud604",level:3},{value:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",id:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",level:3},{value:"\ucf54\ub4dc \ub9ac\ubdf0",id:"\ucf54\ub4dc-\ub9ac\ubdf0",level:3},{value:"SessionConfig",id:"sessionconfig",level:3},{value:"HTTP \uc218\uc5c5",id:"http-\uc218\uc5c5",level:3},{value:"Thread \uc218\uc5c5",id:"thread-\uc218\uc5c5",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],m={toc:p};function d(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"1, 2\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-http/pull/302"},"https://github.com/woowacourse/jwp-dashboard-http/pull/302"),(0,r.kt)("br",{parentName:"p"}),"\n","3, 4\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-http/pull/431"},"https://github.com/woowacourse/jwp-dashboard-http/pull/431"))),(0,r.kt)("h3",{id:"\ud1b0\ucea3-\uad6c\ud604"},"\ud1b0\ucea3 \uad6c\ud604"),(0,r.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c0\uc6d0\ud560 \ub54c \uac1d\uccb4\uc9c0\ud5a5\uacfc \uad00\ub828\ub41c \ubbf8\uc158\ub3c4 \uae30\ub300\ub97c \ub9ce\uc774 \ud588\uc9c0\ub9cc \ub808\ubca8 4\uc5d0 \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc774 \uc815\ub9d0 \ud558\uace0 \uc2f6\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uadf8\ub798\uc11c \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc744\uae4c\ub77c\ub294 \uac71\uc815 \ubc18, \ubbf8\uc158\uc5d0 \ub300\ud55c \uae30\ub300 \ubc18\uc73c\ub85c \ubd80\ud47c \ub9c8\uc74c\uc744 \uac00\uc9c0\uace0 \ubbf8\uc158\uc744 \uc2dc\uc791\ud588\ub358 \uac83 \uac19\ub2e4. "),(0,r.kt)("p",null,"\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc801\uc808\ud558\uac8c \ucd94\uc0c1\ud654\ud558\uace0, \ubbf8\uc158\uc758 \ubcf8\uc9c8\uc744 \uc774\ud574\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158\uc740 ",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc2616/"},"RFC 2616"),"\uc5d0 \uba85\uc2dc\ub41c \uc2a4\ud399(\uc644\ubcbd\ud558\uc9c0 \uc54a\uc9c0\ub9cc \ubbf8\uc158\uc5d0\uc11c \uc8fc\uc5b4\uc9c4 \uc694\uad6c\uc0ac\ud56d\ub9cc \ub9cc\uc871\ud558\ub3c4\ub85d)\uc73c\ub85c \uc694\uccad\uc744 \ubc1b\uc544 \ucc98\ub9ac \ud6c4 \ubc18\ud658\ud558\ub294\ub370 \uc9d1\uc911\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\ub2e4\uc774\uc5b4\uadf8\ub7a8"},"\ub2e4\uc774\uc5b4\uadf8\ub7a8"),(0,r.kt)("p",null,"Catalina\ub294 Tomcat\uc758 \uc11c\ube14\ub9bf \ucee8\ud14c\uc774\ub108, Coyote\ub294 HTTP 1.1 \uc6f9 \uc11c\ubc84\ub97c \uc9c0\uc6d0\ud558\ub294 \uad6c\uc131 \uc694\uc18c\ub77c\uace0 \uc0dd\uac01\ud558\uace0 \uc544\ub798\uc640 \uac19\uc774 \uad6c\uc131\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc2e4 \ub0b4\ubd80 \uad6c\uc870\ub97c \uae4a\uac8c \uacf5\ubd80\ud560 \uc2dc\uac04\uc744 \uac00\uc9c0\uc9c0 \ubabb\ud574\uc11c \uac01 \uad6c\uc131 \uc694\uc18c\uac00 \uc65c \ud574\ub2f9 \uc704\uce58\uc5d0 \uc788\ub294\uc9c0 \uc644\ubcbd\ud558\uac8c \uc124\uba85\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc774\uac74 \uc5ec\uae30\uc5d0 \uc788\uc73c\uba74 \uc88b\uc744 \uac83 \uac19\uc740\ub370? \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e4\uba74 \uc801\uc808\ud55c \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\uc2dc\ud0a4\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \uc801\uc808\ud558\uac8c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc73c\ub85c \ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n\tsubgraph coyote\n\t\tHP[Http11Processor] --\x3e A\n\t\tHP --\x3e HttpRequestParser\n\t\tHP --\x3e HttpResponseGenerator\n\t\tA[Adapter]\n end\n\n subgraph catalina\n\t\tRA[RequestAdapter] -.-> A\n\t\tAC[AbstractController] -.-> C[Controller]\n\t\tStaticController -.-> AC\n\t\tSM[SessionManger] -.-> Manager\n\t\tTC[Tomcat] --\x3e RA\n\t\tRA --\x3e C\n\t\tRA --\x3e Manager\n\t\tRA --\x3e RM\n\t\tRM[RequestMapper] --\x3e C\n end\n\n subgraph jwp\n\t\tLC[LoginController] -.-> AC\n\t\tApplication --\x3e TC\n end\n"}),(0,r.kt)("h3",{id:"\ucf54\ub4dc-\ub9ac\ubdf0"},"\ucf54\ub4dc \ub9ac\ubdf0"),(0,r.kt)("p",null,"\ud06c\ub8e8 \uc911 \ud55c \uba85\uc774 \ub098\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\uace0, \ub0b4\uac00 \ub2e4\ub978 \ud06c\ub8e8\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\ub294 \ud615\ud0dc\ub85c \uc9c4\ud589\uc774 \ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub514\ub178, \ub9ac\ubdf0\uc774\ub294 \ud544\ub9bd\uc774\uc5c8\ub2e4. "),(0,r.kt)("p",null,"\ub514\ub178(\ub9e4\uc758 \ub208\uc774 \uc544\ub2cc \uacf5\ub8e1\uc758 \ub208?)\uac00 \ub9e4\uc6b0 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud574\uc8fc\uc5b4\uc11c \uc870\uae08 \ub354 \ub098\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \uc218 \uc788\uc5c8\uace0, \ud544\ub9bd\uc758 \ucf54\ub4dc\uc5d0\uc11c\ub294 \uaf3c\uaf3c\ud558\uac8c \uc608\uc678\ucc98\ub9ac \ud558\ub294 \ubd80\ubd84\uc744 \ubc30\uc6b8 \uc218 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud55c \uac00\uc9c0 \uc544\uc26c\uc6b4 \uc810\uc740 \ud544\ub9bd\uc5d0\uac8c \uc791\uc131\ud55c \ub098\uc758 \ucf54\uba58\ud2b8\ub4e4\uc774 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uacbd\ud5d8 \uae30\ubc18\uc73c\ub85c \uc791\uc131\ud55c \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uadfc\uac70\uac00 \uc870\uae08 \ubd80\uc871\ud588\uace0, \uc815\ub9ac\ub418\uc9c0 \uc54a\uc740 \ubd80\ubd84\uc774 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130 \ub9ac\ubdf0\ud560 \ub54c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ub354 \uc88b\uc740 \ub0b4\uc6a9\uc744 \ud06c\ub8e8\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. "),(0,r.kt)("h3",{id:"sessionconfig"},"SessionConfig"),(0,r.kt)("p",null,"\ubbf8\uc158\uc744 \uc9c4\ud589 \uc911 catalina \ud328\ud0a4\uc9c0\uc758 Session \uad00\ub828 \ubd80\ubd84\uc744 \ubcf4\uba74\uc11c \uc911\ubcf5 \ub85c\uc9c1\uc744 \uac1c\uc120\ud574 \ubcfc \uc218 \uc788\uc744 \uac83 \uac19\uc544 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/apache/tomcat/pull/660"},"\ucee8\ud2b8\ub9ac\ubdf0\ud2b8"),"\ub97c \uc2dc\ub3c4\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc138\uc158 \ucfe0\ud0a4\uc758 \uc774\ub984\uc744 \uac00\uc838\uc624\ub294 Util \ud074\ub798\uc2a4\uc758 \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub294\ub370 \uae30\ubcf8 \uac12\uc740 JSESSIONID \uc9c0\ub9cc \uc124\uc815\uc5d0 \ub530\ub77c\uc11c \uc138\uc158 \ucfe0\ud0a4\uba85\uc744 \ub2e4\ub974\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ub85c\uc9c1\uc774 \uc788\ub294 \uac83\uc73c\ub85c \uc0dd\uac01\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc758 \ucf54\ub4dc\ub294 \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \ucf54\ub4dc\uc758 \ud750\ub984\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc544\uc11c \uc57d\uac04 \uc774\ud574\ud558\uae30 \uc5b4\ub824\uc6e0\ub2e4. "),(0,r.kt)("p",null,"\ucd08\uae30\uc5d0 \uc694\uccad\ud588\ub358 PR\uc740 \uae30\uc874\uc758 \ucf54\ub4dc\ubcf4\ub2e4 \uc804\uccb4\uc801\uc73c\ub85c \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, context\uac00 null\uc778 \uacbd\uc6b0 \ubc14\ub85c \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud568\uc73c\ub85c\uc368 \uc131\ub2a5 \uac1c\uc120\uc758 \ud6a8\uacfc\uac00 \uc788\uc744 \uac70\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uba54\uc778\ud14c\uc774\ub108\uc778 Mark Thomas \ud615\uc774 \ud574\ub2f9 \ub85c\uc9c1\uc758 \uacbd\uc6b0 \ucef4\ud30c\uc77c\ub7ec\uac00 \ud574\ub2f9 \ubd80\ubd84\uc744 \ucd5c\uc801\ud654 \ud560 \uc218 \uc788\uc744 \uac70\ub77c\uace0 \uae30\ub300\ud55c\ub2e4\uace0 \ud588\uace0, \uac00\ub3c5\uc131\uc744 \uac1c\uc120\uc2dc\ucf1c\ubcf4\ub77c\uace0 \uc870\uc5b8\ud574\uc8fc\uc168\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucef4\ud30c\uc77c\ub7ec \ucd5c\uc801\ud654\ub294 \uace0\ub824\ud574\ubcf4\uc9c0 \ubabb\ud55c \ubd80\ubd84\uc778\ub370, \uc55e\uc73c\ub85c \ud559\uc2b5\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc0b0\ub354\ubbf8\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,r.kt)("p",null,"\ub0a8\uaca8\uc900 \ucf54\uba58\ud2b8\uc5d0 \ub530\ub77c \ucd5c\uc885\uc801\uc73c\ub85c\ub294 \uc911\ubcf5\ub41c \ucf54\ub4dc\ub97c \uc904\uc774\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uacb0\uacfc\uc801\uc73c\ub85c \uae30\uc874 \ub85c\uc9c1 \ub300\ube44 \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \uc720\uc0ac\ud55c \ud750\ub984\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \ud588\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"\uae30\uc874",label:"\uae30\uc874",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public static String getSessionCookieName(Context context) {\n\n String result = getConfiguredSessionCookieName(context);\n\n if (result == null) {\n result = DEFAULT_SESSION_COOKIE_NAME;\n }\n\n return result;\n}\n\npublic static String getSessionUriParamName(Context context) {\n\n String result = getConfiguredSessionCookieName(context);\n\n if (result == null) {\n result = DEFAULT_SESSION_PARAMETER_NAME;\n }\n\n return result;\n}\n\nprivate static String getConfiguredSessionCookieName(Context context) {\n\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n if (context != null) {\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc =\n context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n }\n\n return null;\n}\n"))),(0,r.kt)(i.Z,{value:"PR \uc694\uccad",label:"PR \uc694\uccad",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public static String getSessionCookieName(Context context) {\n if (context == null) {\n return DEFAULT_SESSION_COOKIE_NAME;\n }\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\n}\n\npublic static String getSessionUriParamName(Context context) {\n if (context == null) {\n return DEFAULT_SESSION_PARAMETER_NAME;\n }\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\n}\n\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n return defaultName;\n}\n"))),(0,r.kt)(i.Z,{value:"\ucd5c\uc885",label:"\ucd5c\uc885",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public static String getSessionCookieName(Context context) {\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\n}\n\npublic static String getSessionUriParamName(Context context) {\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\n}\n\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n if (context != null) {\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n }\n return defaultName;\n}\n")))),(0,r.kt)("h3",{id:"http-\uc218\uc5c5"},"HTTP \uc218\uc5c5"),(0,r.kt)("p",null,"\ubbf8\uc158 \uc911\uac04\uc5d0 \uc9c4\ud589\ub418\uc5c8\ub358 HTTP \uc218\uc5c5\uc5d0\ub294 HTTP\ub97c \uc801\uc808\ud558\uac8c \ud65c\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \uc131\ub2a5 \uac1c\uc120\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub2e8\uc5d0\uc11c \ucd5c\uc801\ud654\ud574\ubcf4\ub824\uace0 \ub178\ub825\uc744 \ud588\uc9c0\ub9cc, \ub354 \uc801\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ud6a8\uc728\uc801\uc73c\ub85c \uc131\ub2a5\uc744 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc54c \uc218 \uc788\uc5c8\ub358 \uc218\uc5c5\uc774\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","HTTP \uc555\ucd95, HTTP \uce90\uc2f1, \ub9ac\uc18c\uc2a4 \ucd5c\uc801\ud654 \uae30\ubc95\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4. "),(0,r.kt)("p",null,"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \ub2e4\uc74c \uc635\uc158\uc744 \uc124\uc815\ud558\uc5ec http\uc758 \uc1a1\uc218\uc2e0\uc758 \uc555\ucd95\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml"},"server:\n compression:\n enabled: true\n")),(0,r.kt)("p",null,"\uc218\uc5c5 \uc911 \ud574\ub2f9 \uc555\ucd95 \uc131\ub2a5\uc774 \uc88b\ub2e4\uba74 \uc65c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \uae30\ubcf8 \uac12\uc73c\ub85c \uc124\uc815\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\uc9c0 \uad81\uae08\ud574\uc84c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uad81\uae08\uc99d\uc744 \ud574\uc18c\ud558\uc9c0 \ubabb\ud588\ub294\ub370 \ub9d0\ub791\uc774 \uc7a1\ub2f4 \ucc44\ub110\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc740 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-boot/issues/21369"},"issue"),"\ub97c \ucc3e\uc544\uc8fc\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub0b4\uc6a9\uc744 \uc694\uc57d\ud574 \ubcf4\uc790\uba74 WAS \ubcc4\ub85c \uc555\ucd95\uc744 \ud558\uae30 \uc704\ud574 \uc124\uc815\ud574\uc57c \ud558\ub294 \uac83\uc774 \ub2e4\ub974\uace0, \ubb34\uc870\uac74 \uc555\ucd95\uc744 \ud558\ub294 \uac83\uc774 \ucd5c\uc801\uc758 \uacbd\uc6b0\uac00 \uc544\ub2d0 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 \uac19\ub2e4. "),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.")),(0,r.kt)("p",null,"Phil Webb \ud615\ub2d8\uc758 \ub9d0\uc5d0 \ub530\ub974\uba74 \uc77c\ubc18\uc801\uc778 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \uacbd\uc6b0 gzip \uc555\ucd95\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc9c0\ub9cc, MSA \ud658\uacbd + \ub370\uc774\ud130 \uc13c\ud130\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \uc624\uc9c1 \ub2e4\ub978 MSA \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uacfc \ud1b5\uc2e0\ud558\uace0, \uace0\uc131\ub2a5 \ub124\ud2b8\uc6cc\ud06c\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0 CPU \ubd80\ud558\ub97c \uc904\uc774\ub294 \uac83\uc774 \uc6b0\uc120\uc2dc \ub420 \uc218\ub3c4 \uc788\ub2e4\ub294 \uac83\uc774\uc5c8\ub2e4. "),(0,r.kt)("p",null,"\uc774\uc678\uc5d0\ub3c4 \uc758\ub3c4\ud558\uc9c0 \uc54a\uc740 \uce90\uc2f1\uc744 \ub9c9\uae30 \uc704\ud574 \ud734\ub9ac\uc2a4\ud2f1 \uce90\uc2f1\uc744 \uc81c\uac70\ud558\uac70\ub098, \uac1c\uc778 \uc815\ubcf4 \uc720\ucd9c\uc744 \ub9c9\uae30 \uc704\ud574 \uc751\ub2f5 \ud5e4\ub354\uc5d0 private\uc744 \uc124\uc815, ETag\ub3c4 \ud559\uc2b5\ud588\ub2e4. "),(0,r.kt)("admonition",{title:"ETag",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"ETag HTTP \uc751\ub2f5 \ud5e4\ub354\ub294 \ud2b9\uc815 \ubc84\uc804\uc758 \ub9ac\uc18c\uc2a4\ub97c \uc2dd\ubcc4\ud558\ub294 \uc2dd\ubcc4\uc790\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc6f9 \uc11c\ubc84\uac00 \ub0b4\uc6a9\uc744 \ud655\uc778\ud558\uace0 \ubcc0\ud558\uc9c0 \uc54a\uc558\uc73c\uba74, \uc6f9 \uc11c\ubc84\ub85c full \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0, \uce90\uc2dc\uac00 \ub354 \ud6a8\uc728\uc801\uc774\uac8c \ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MDN")),(0,r.kt)("h3",{id:"thread-\uc218\uc5c5"},"Thread \uc218\uc5c5"),(0,r.kt)("p",null,"\uc2a4\ub808\ub4dc\uc5d0 \ub300\ud55c \uc218\uc5c5\uc744 \ub4e4\uc5c8\uc9c0\ub9cc, \ubcf5\uc7a1\ud55c \ub0b4\uc6a9\ub3c4 \uc6cc\ub099 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0 \uc124\uba85\ud558\ub77c\uace0 \ud558\uba74 \uc798 \ubabb\ud560 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud604\uc7ac \ud504\ub85c\uc81d\ud2b8, \ubbf8\uc158, \ud14c\ucf54\ud1a1 \uc900\ube44\ub97c \ubcd1\ud589\ud574\uc57c \ud574\uc11c \uc138\ubd80\uc801\uc778 \ub0b4\uc6a9\uc740 \uc2dc\uac04 \ub0a0 \ub54c \ubcf5\uc2b5\ud558\ub824\uace0 \ud55c\ub2e4. "),(0,r.kt)("p",null,"\uc2a4\ub808\ub4dc\ub97c \uc774\ud574\ud558\uace0, WAS\uc5d0 \uc2a4\ub808\ub4dc \uc124\uc815 \uad00\ub828\ud55c \uc2e4\uc2b5\uc774 \uc788\uc5c8\ub294\ub370 \ud14c\uc624\uc640 \uac19\uc774 1\uc2dc\uac04 \uc815\ub3c4 \ud398\uc5b4\ub85c Thread \uc2e4\uc2b5\uc744 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud559\uc2b5\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"threads.max"),": Tomcat\uc758 \ucd5c\ub300 \uc2a4\ub808\ub4dc \uac1c\uc218",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"max-connections"),": Tomcat\uc774 \uc720\uc9c0\ud560 \uc218 \uc788\ub294 \ucd5c\ub300 \ucee4\ub125\uc158 \uac1c\uc218",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"accept-count"),": \ucd5c\ub300 \uc5f0\uacb0 \uc218\uc5d0 \ub3c4\ub2ec\ud588\uc744 \ub54c \uc5f0\uacb0 \uc694\uccad\uc5d0 \ub300\ud574 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub300\uae30\uc5f4\uc758 \ucd5c\ub300 \uae38\uc774. \ud574\ub2f9 Queue\uc5d0 \uc694\uccad\uc774 \uc313\uc774\ub294 \uac83\uc740 Tomcat\uc774 \ub354 \uc774\uc0c1 \uc694\uccad\uc744 \ubc1b\uc744 \uc218 \uc5c6\ub2e4\ub294 \ub73b\uc774\ub2e4. accpet-count queue\uc5d0\ub3c4 \uc694\uccad\uc774 \uac00\ub4dd\ucc28\uba74 \uadf8 \uc774\ud6c4\uc5d0 \uc624\ub294 \uc694\uccad\uc740 \uac70\ubd80\ub41c\ub2e4. "),(0,r.kt)("mermaid",{value:'graph LR\n C("Client") -- request --\x3e ACQ("\uc6b4\uc601\uccb4\uc81c\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue \n size = accept-count") --\x3e TCQ("Tomcat Connector\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue\n size = max-connections") --\x3e TP("Thread Pool\n size = threads.max")'}),(0,r.kt)("h3",{id:"\ub9c8\uce58\uba70"},"\ub9c8\uce58\uba70"),(0,r.kt)("p",null,"\uc2dc\uac04\uc740 \ub108\ubb34 \ube60\ub974\uac8c \uac00\uace0 \ud560 \uc77c\uc740 \ub9ce\uc740 \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc6b0\uc120\uc21c\uc704\ub97c \uc798 \uc815\ud558\uace0 \ud559\uc2b5\uc744 \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud604\uc7ac \ub370\uc774\ud130 \ub2e4\ub8e8\ub294 \ubd80\ubd84(DB)\uc5d0 \ub300\ud55c \ud559\uc2b5\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\ub2e4. \ud574\ub2f9 \ubd80\ubd84\uc740 \ud14c\ucf54\ud1a1\uc774 \ub05d\ub098\ub294\ub300\ub85c \ucc44\uc6cc\uc57c\uaca0\ub2e4. "),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc2616/"},"RFC 2616"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/ETag"},"ETag, mdn"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://tomcat.apache.org/tomcat-8.5-doc/config/http.html"},"Apache Tomcat 8 Configuration Reference"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://bcho.tistory.com/788"},"Apache Tomcat Tuning, Terry Cho"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev-ws.tistory.com/96"},"maxThreads, maxConnections, acceptCount\ub85c Tomcat \ud29c\ub2dd\ud558\uae30")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/905ecccc.aeeb3c76.js b/assets/js/905ecccc.aeeb3c76.js new file mode 100644 index 000000000..a2494ff90 --- /dev/null +++ b/assets/js/905ecccc.aeeb3c76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2939],{76306:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var r=t(85893),o=t(3905),a=t(74866),i=t(85162);const s={title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"tomcat-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,c={permalink:"/tomcat-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1, 2\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-http/pull/302",date:"2023-09-11T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 11\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:12.345,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"tomcat-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",permalink:"/log-async-exception"},nextItem:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",permalink:"/performance-test-type"}},u={authorsImageUrls:[]},d=[{value:"\ud1b0\ucea3 \uad6c\ud604",id:"\ud1b0\ucea3-\uad6c\ud604",level:3},{value:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",id:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",level:3},{value:"\ucf54\ub4dc \ub9ac\ubdf0",id:"\ucf54\ub4dc-\ub9ac\ubdf0",level:3},{value:"SessionConfig",id:"sessionconfig",level:3},{value:"HTTP \uc218\uc5c5",id:"http-\uc218\uc5c5",level:3},{value:"Thread \uc218\uc5c5",id:"thread-\uc218\uc5c5",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",br:"br",code:"code",h3:"h3",mermaid:"mermaid",p:"p",pre:"pre",...(0,o.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,r.jsxs)(n.p,{children:["1, 2\ub2e8\uacc4: ",(0,r.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-http/pull/302",children:"https://github.com/woowacourse/jwp-dashboard-http/pull/302"}),(0,r.jsx)(n.br,{}),"\n","3, 4\ub2e8\uacc4: ",(0,r.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-http/pull/431",children:"https://github.com/woowacourse/jwp-dashboard-http/pull/431"})]})}),"\n",(0,r.jsx)(n.h3,{id:"\ud1b0\ucea3-\uad6c\ud604",children:"\ud1b0\ucea3 \uad6c\ud604"}),"\n",(0,r.jsxs)(n.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c0\uc6d0\ud560 \ub54c \uac1d\uccb4\uc9c0\ud5a5\uacfc \uad00\ub828\ub41c \ubbf8\uc158\ub3c4 \uae30\ub300\ub97c \ub9ce\uc774 \ud588\uc9c0\ub9cc \ub808\ubca8 4\uc5d0 \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc774 \uc815\ub9d0 \ud558\uace0 \uc2f6\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uadf8\ub798\uc11c \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc744\uae4c\ub77c\ub294 \uac71\uc815 \ubc18, \ubbf8\uc158\uc5d0 \ub300\ud55c \uae30\ub300 \ubc18\uc73c\ub85c \ubd80\ud47c \ub9c8\uc74c\uc744 \uac00\uc9c0\uace0 \ubbf8\uc158\uc744 \uc2dc\uc791\ud588\ub358 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc801\uc808\ud558\uac8c \ucd94\uc0c1\ud654\ud558\uace0, \ubbf8\uc158\uc758 \ubcf8\uc9c8\uc744 \uc774\ud574\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158\uc740 ",(0,r.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2616/",children:"RFC 2616"}),"\uc5d0 \uba85\uc2dc\ub41c \uc2a4\ud399(\uc644\ubcbd\ud558\uc9c0 \uc54a\uc9c0\ub9cc \ubbf8\uc158\uc5d0\uc11c \uc8fc\uc5b4\uc9c4 \uc694\uad6c\uc0ac\ud56d\ub9cc \ub9cc\uc871\ud558\ub3c4\ub85d)\uc73c\ub85c \uc694\uccad\uc744 \ubc1b\uc544 \ucc98\ub9ac \ud6c4 \ubc18\ud658\ud558\ub294\ub370 \uc9d1\uc911\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",children:"\ub2e4\uc774\uc5b4\uadf8\ub7a8"}),"\n",(0,r.jsxs)(n.p,{children:["Catalina\ub294 Tomcat\uc758 \uc11c\ube14\ub9bf \ucee8\ud14c\uc774\ub108, Coyote\ub294 HTTP 1.1 \uc6f9 \uc11c\ubc84\ub97c \uc9c0\uc6d0\ud558\ub294 \uad6c\uc131 \uc694\uc18c\ub77c\uace0 \uc0dd\uac01\ud558\uace0 \uc544\ub798\uc640 \uac19\uc774 \uad6c\uc131\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc0ac\uc2e4 \ub0b4\ubd80 \uad6c\uc870\ub97c \uae4a\uac8c \uacf5\ubd80\ud560 \uc2dc\uac04\uc744 \uac00\uc9c0\uc9c0 \ubabb\ud574\uc11c \uac01 \uad6c\uc131 \uc694\uc18c\uac00 \uc65c \ud574\ub2f9 \uc704\uce58\uc5d0 \uc788\ub294\uc9c0 \uc644\ubcbd\ud558\uac8c \uc124\uba85\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc774\uac74 \uc5ec\uae30\uc5d0 \uc788\uc73c\uba74 \uc88b\uc744 \uac83 \uac19\uc740\ub370? \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e4\uba74 \uc801\uc808\ud55c \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\uc2dc\ud0a4\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub610\ud55c \uc801\uc808\ud558\uac8c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc73c\ub85c \ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n\tsubgraph coyote\n\t\tHP[Http11Processor] --\x3e A\n\t\tHP --\x3e HttpRequestParser\n\t\tHP --\x3e HttpResponseGenerator\n\t\tA[Adapter]\n end\n\n subgraph catalina\n\t\tRA[RequestAdapter] -.-> A\n\t\tAC[AbstractController] -.-> C[Controller]\n\t\tStaticController -.-> AC\n\t\tSM[SessionManger] -.-> Manager\n\t\tTC[Tomcat] --\x3e RA\n\t\tRA --\x3e C\n\t\tRA --\x3e Manager\n\t\tRA --\x3e RM\n\t\tRM[RequestMapper] --\x3e C\n end\n\n subgraph jwp\n\t\tLC[LoginController] -.-> AC\n\t\tApplication --\x3e TC\n end\n"}),"\n",(0,r.jsx)(n.h3,{id:"\ucf54\ub4dc-\ub9ac\ubdf0",children:"\ucf54\ub4dc \ub9ac\ubdf0"}),"\n",(0,r.jsxs)(n.p,{children:["\ud06c\ub8e8 \uc911 \ud55c \uba85\uc774 \ub098\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\uace0, \ub0b4\uac00 \ub2e4\ub978 \ud06c\ub8e8\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\ub294 \ud615\ud0dc\ub85c \uc9c4\ud589\uc774 \ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub514\ub178, \ub9ac\ubdf0\uc774\ub294 \ud544\ub9bd\uc774\uc5c8\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ub514\ub178(\ub9e4\uc758 \ub208\uc774 \uc544\ub2cc \uacf5\ub8e1\uc758 \ub208?)\uac00 \ub9e4\uc6b0 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud574\uc8fc\uc5b4\uc11c \uc870\uae08 \ub354 \ub098\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \uc218 \uc788\uc5c8\uace0, \ud544\ub9bd\uc758 \ucf54\ub4dc\uc5d0\uc11c\ub294 \uaf3c\uaf3c\ud558\uac8c \uc608\uc678\ucc98\ub9ac \ud558\ub294 \ubd80\ubd84\uc744 \ubc30\uc6b8 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud55c \uac00\uc9c0 \uc544\uc26c\uc6b4 \uc810\uc740 \ud544\ub9bd\uc5d0\uac8c \uc791\uc131\ud55c \ub098\uc758 \ucf54\uba58\ud2b8\ub4e4\uc774 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uacbd\ud5d8 \uae30\ubc18\uc73c\ub85c \uc791\uc131\ud55c \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uadfc\uac70\uac00 \uc870\uae08 \ubd80\uc871\ud588\uace0, \uc815\ub9ac\ub418\uc9c0 \uc54a\uc740 \ubd80\ubd84\uc774 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130 \ub9ac\ubdf0\ud560 \ub54c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ub354 \uc88b\uc740 \ub0b4\uc6a9\uc744 \ud06c\ub8e8\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"sessionconfig",children:"SessionConfig"}),"\n",(0,r.jsxs)(n.p,{children:["\ubbf8\uc158\uc744 \uc9c4\ud589 \uc911 catalina \ud328\ud0a4\uc9c0\uc758 Session \uad00\ub828 \ubd80\ubd84\uc744 \ubcf4\uba74\uc11c \uc911\ubcf5 \ub85c\uc9c1\uc744 \uac1c\uc120\ud574 \ubcfc \uc218 \uc788\uc744 \uac83 \uac19\uc544 ",(0,r.jsx)(n.a,{href:"https://github.com/apache/tomcat/pull/660",children:"\ucee8\ud2b8\ub9ac\ubdf0\ud2b8"}),"\ub97c \uc2dc\ub3c4\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc138\uc158 \ucfe0\ud0a4\uc758 \uc774\ub984\uc744 \uac00\uc838\uc624\ub294 Util \ud074\ub798\uc2a4\uc758 \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub294\ub370 \uae30\ubcf8 \uac12\uc740 JSESSIONID \uc9c0\ub9cc \uc124\uc815\uc5d0 \ub530\ub77c\uc11c \uc138\uc158 \ucfe0\ud0a4\uba85\uc744 \ub2e4\ub974\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ub85c\uc9c1\uc774 \uc788\ub294 \uac83\uc73c\ub85c \uc0dd\uac01\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uae30\uc874\uc758 \ucf54\ub4dc\ub294 \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \ucf54\ub4dc\uc758 \ud750\ub984\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc544\uc11c \uc57d\uac04 \uc774\ud574\ud558\uae30 \uc5b4\ub824\uc6e0\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ucd08\uae30\uc5d0 \uc694\uccad\ud588\ub358 PR\uc740 \uae30\uc874\uc758 \ucf54\ub4dc\ubcf4\ub2e4 \uc804\uccb4\uc801\uc73c\ub85c \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, context\uac00 null\uc778 \uacbd\uc6b0 \ubc14\ub85c \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud568\uc73c\ub85c\uc368 \uc131\ub2a5 \uac1c\uc120\uc758 \ud6a8\uacfc\uac00 \uc788\uc744 \uac70\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uba54\uc778\ud14c\uc774\ub108\uc778 Mark Thomas \ud615\uc774 \ud574\ub2f9 \ub85c\uc9c1\uc758 \uacbd\uc6b0 \ucef4\ud30c\uc77c\ub7ec\uac00 \ud574\ub2f9 \ubd80\ubd84\uc744 \ucd5c\uc801\ud654 \ud560 \uc218 \uc788\uc744 \uac70\ub77c\uace0 \uae30\ub300\ud55c\ub2e4\uace0 \ud588\uace0, \uac00\ub3c5\uc131\uc744 \uac1c\uc120\uc2dc\ucf1c\ubcf4\ub77c\uace0 \uc870\uc5b8\ud574\uc8fc\uc168\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucef4\ud30c\uc77c\ub7ec \ucd5c\uc801\ud654\ub294 \uace0\ub824\ud574\ubcf4\uc9c0 \ubabb\ud55c \ubd80\ubd84\uc778\ub370, \uc55e\uc73c\ub85c \ud559\uc2b5\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc0b0\ub354\ubbf8\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ub0a8\uaca8\uc900 \ucf54\uba58\ud2b8\uc5d0 \ub530\ub77c \ucd5c\uc885\uc801\uc73c\ub85c\ub294 \uc911\ubcf5\ub41c \ucf54\ub4dc\ub97c \uc904\uc774\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uacb0\uacfc\uc801\uc73c\ub85c \uae30\uc874 \ub85c\uc9c1 \ub300\ube44 \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \uc720\uc0ac\ud55c \ud750\ub984\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \ud588\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n","\n","\n",(0,r.jsxs)(a.Z,{children:[(0,r.jsx)(i.Z,{value:"\uae30\uc874",label:"\uae30\uc874",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public static String getSessionCookieName(Context context) {\n\n String result = getConfiguredSessionCookieName(context);\n\n if (result == null) {\n result = DEFAULT_SESSION_COOKIE_NAME;\n }\n\n return result;\n}\n\npublic static String getSessionUriParamName(Context context) {\n\n String result = getConfiguredSessionCookieName(context);\n\n if (result == null) {\n result = DEFAULT_SESSION_PARAMETER_NAME;\n }\n\n return result;\n}\n\nprivate static String getConfiguredSessionCookieName(Context context) {\n\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n if (context != null) {\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc =\n context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n }\n\n return null;\n}\n"})})}),(0,r.jsx)(i.Z,{value:"PR \uc694\uccad",label:"PR \uc694\uccad",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public static String getSessionCookieName(Context context) {\n if (context == null) {\n return DEFAULT_SESSION_COOKIE_NAME;\n }\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\n}\n\npublic static String getSessionUriParamName(Context context) {\n if (context == null) {\n return DEFAULT_SESSION_PARAMETER_NAME;\n }\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\n}\n\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n return defaultName;\n}\n"})})}),(0,r.jsx)(i.Z,{value:"\ucd5c\uc885",label:"\ucd5c\uc885",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public static String getSessionCookieName(Context context) {\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\n}\n\npublic static String getSessionUriParamName(Context context) {\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\n}\n\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n if (context != null) {\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n }\n return defaultName;\n}\n"})})})]}),"\n",(0,r.jsx)(n.h3,{id:"http-\uc218\uc5c5",children:"HTTP \uc218\uc5c5"}),"\n",(0,r.jsxs)(n.p,{children:["\ubbf8\uc158 \uc911\uac04\uc5d0 \uc9c4\ud589\ub418\uc5c8\ub358 HTTP \uc218\uc5c5\uc5d0\ub294 HTTP\ub97c \uc801\uc808\ud558\uac8c \ud65c\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud56d\uc0c1 \uc131\ub2a5 \uac1c\uc120\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub2e8\uc5d0\uc11c \ucd5c\uc801\ud654\ud574\ubcf4\ub824\uace0 \ub178\ub825\uc744 \ud588\uc9c0\ub9cc, \ub354 \uc801\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ud6a8\uc728\uc801\uc73c\ub85c \uc131\ub2a5\uc744 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc54c \uc218 \uc788\uc5c8\ub358 \uc218\uc5c5\uc774\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","HTTP \uc555\ucd95, HTTP \uce90\uc2f1, \ub9ac\uc18c\uc2a4 \ucd5c\uc801\ud654 \uae30\ubc95\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \ub2e4\uc74c \uc635\uc158\uc744 \uc124\uc815\ud558\uc5ec http\uc758 \uc1a1\uc218\uc2e0\uc758 \uc555\ucd95\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yml",children:"server:\n compression:\n enabled: true\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc218\uc5c5 \uc911 \ud574\ub2f9 \uc555\ucd95 \uc131\ub2a5\uc774 \uc88b\ub2e4\uba74 \uc65c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \uae30\ubcf8 \uac12\uc73c\ub85c \uc124\uc815\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\uc9c0 \uad81\uae08\ud574\uc84c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uad81\uae08\uc99d\uc744 \ud574\uc18c\ud558\uc9c0 \ubabb\ud588\ub294\ub370 \ub9d0\ub791\uc774 \uc7a1\ub2f4 \ucc44\ub110\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc740 ",(0,r.jsx)(n.a,{href:"https://github.com/spring-projects/spring-boot/issues/21369",children:"issue"}),"\ub97c \ucc3e\uc544\uc8fc\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub0b4\uc6a9\uc744 \uc694\uc57d\ud574 \ubcf4\uc790\uba74 WAS \ubcc4\ub85c \uc555\ucd95\uc744 \ud558\uae30 \uc704\ud574 \uc124\uc815\ud574\uc57c \ud558\ub294 \uac83\uc774 \ub2e4\ub974\uace0, \ubb34\uc870\uac74 \uc555\ucd95\uc744 \ud558\ub294 \uac83\uc774 \ucd5c\uc801\uc758 \uacbd\uc6b0\uac00 \uc544\ub2d0 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Phil Webb \ud615\ub2d8\uc758 \ub9d0\uc5d0 \ub530\ub974\uba74 \uc77c\ubc18\uc801\uc778 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \uacbd\uc6b0 gzip \uc555\ucd95\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc9c0\ub9cc, MSA \ud658\uacbd + \ub370\uc774\ud130 \uc13c\ud130\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \uc624\uc9c1 \ub2e4\ub978 MSA \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uacfc \ud1b5\uc2e0\ud558\uace0, \uace0\uc131\ub2a5 \ub124\ud2b8\uc6cc\ud06c\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0 CPU \ubd80\ud558\ub97c \uc904\uc774\ub294 \uac83\uc774 \uc6b0\uc120\uc2dc \ub420 \uc218\ub3c4 \uc788\ub2e4\ub294 \uac83\uc774\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:"\uc774\uc678\uc5d0\ub3c4 \uc758\ub3c4\ud558\uc9c0 \uc54a\uc740 \uce90\uc2f1\uc744 \ub9c9\uae30 \uc704\ud574 \ud734\ub9ac\uc2a4\ud2f1 \uce90\uc2f1\uc744 \uc81c\uac70\ud558\uac70\ub098, \uac1c\uc778 \uc815\ubcf4 \uc720\ucd9c\uc744 \ub9c9\uae30 \uc704\ud574 \uc751\ub2f5 \ud5e4\ub354\uc5d0 private\uc744 \uc124\uc815, ETag\ub3c4 \ud559\uc2b5\ud588\ub2e4."}),"\n",(0,r.jsx)(n.admonition,{title:"ETag",type:"note",children:(0,r.jsxs)(n.p,{children:["ETag HTTP \uc751\ub2f5 \ud5e4\ub354\ub294 \ud2b9\uc815 \ubc84\uc804\uc758 \ub9ac\uc18c\uc2a4\ub97c \uc2dd\ubcc4\ud558\ub294 \uc2dd\ubcc4\uc790\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc6f9 \uc11c\ubc84\uac00 \ub0b4\uc6a9\uc744 \ud655\uc778\ud558\uace0 \ubcc0\ud558\uc9c0 \uc54a\uc558\uc73c\uba74, \uc6f9 \uc11c\ubc84\ub85c full \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0, \uce90\uc2dc\uac00 \ub354 \ud6a8\uc728\uc801\uc774\uac8c \ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","MDN"]})}),"\n",(0,r.jsx)(n.h3,{id:"thread-\uc218\uc5c5",children:"Thread \uc218\uc5c5"}),"\n",(0,r.jsxs)(n.p,{children:["\uc2a4\ub808\ub4dc\uc5d0 \ub300\ud55c \uc218\uc5c5\uc744 \ub4e4\uc5c8\uc9c0\ub9cc, \ubcf5\uc7a1\ud55c \ub0b4\uc6a9\ub3c4 \uc6cc\ub099 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0 \uc124\uba85\ud558\ub77c\uace0 \ud558\uba74 \uc798 \ubabb\ud560 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e0\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud604\uc7ac \ud504\ub85c\uc81d\ud2b8, \ubbf8\uc158, \ud14c\ucf54\ud1a1 \uc900\ube44\ub97c \ubcd1\ud589\ud574\uc57c \ud574\uc11c \uc138\ubd80\uc801\uc778 \ub0b4\uc6a9\uc740 \uc2dc\uac04 \ub0a0 \ub54c \ubcf5\uc2b5\ud558\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\uc2a4\ub808\ub4dc\ub97c \uc774\ud574\ud558\uace0, WAS\uc5d0 \uc2a4\ub808\ub4dc \uc124\uc815 \uad00\ub828\ud55c \uc2e4\uc2b5\uc774 \uc788\uc5c8\ub294\ub370 \ud14c\uc624\uc640 \uac19\uc774 1\uc2dc\uac04 \uc815\ub3c4 \ud398\uc5b4\ub85c Thread \uc2e4\uc2b5\uc744 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud559\uc2b5\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"threads.max"}),": Tomcat\uc758 \ucd5c\ub300 \uc2a4\ub808\ub4dc \uac1c\uc218",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.code,{children:"max-connections"}),": Tomcat\uc774 \uc720\uc9c0\ud560 \uc218 \uc788\ub294 \ucd5c\ub300 \ucee4\ub125\uc158 \uac1c\uc218",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.code,{children:"accept-count"}),": \ucd5c\ub300 \uc5f0\uacb0 \uc218\uc5d0 \ub3c4\ub2ec\ud588\uc744 \ub54c \uc5f0\uacb0 \uc694\uccad\uc5d0 \ub300\ud574 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub300\uae30\uc5f4\uc758 \ucd5c\ub300 \uae38\uc774. \ud574\ub2f9 Queue\uc5d0 \uc694\uccad\uc774 \uc313\uc774\ub294 \uac83\uc740 Tomcat\uc774 \ub354 \uc774\uc0c1 \uc694\uccad\uc744 \ubc1b\uc744 \uc218 \uc5c6\ub2e4\ub294 \ub73b\uc774\ub2e4. accpet-count queue\uc5d0\ub3c4 \uc694\uccad\uc774 \uac00\ub4dd\ucc28\uba74 \uadf8 \uc774\ud6c4\uc5d0 \uc624\ub294 \uc694\uccad\uc740 \uac70\ubd80\ub41c\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:'graph LR\n C("Client") -- request --\x3e ACQ("\uc6b4\uc601\uccb4\uc81c\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue \n size = accept-count") --\x3e TCQ("Tomcat Connector\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue\n size = max-connections") --\x3e TP("Thread Pool\n size = threads.max")'}),"\n",(0,r.jsx)(n.h3,{id:"\ub9c8\uce58\uba70",children:"\ub9c8\uce58\uba70"}),"\n",(0,r.jsxs)(n.p,{children:["\uc2dc\uac04\uc740 \ub108\ubb34 \ube60\ub974\uac8c \uac00\uace0 \ud560 \uc77c\uc740 \ub9ce\uc740 \uac83 \uac19\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc6b0\uc120\uc21c\uc704\ub97c \uc798 \uc815\ud558\uace0 \ud559\uc2b5\uc744 \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud604\uc7ac \ub370\uc774\ud130 \ub2e4\ub8e8\ub294 \ubd80\ubd84(DB)\uc5d0 \ub300\ud55c \ud559\uc2b5\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\ub2e4. \ud574\ub2f9 \ubd80\ubd84\uc740 \ud14c\ucf54\ud1a1\uc774 \ub05d\ub098\ub294\ub300\ub85c \ucc44\uc6cc\uc57c\uaca0\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2616/",children:"RFC 2616"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/ETag",children:"ETag, mdn"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://tomcat.apache.org/tomcat-8.5-doc/config/http.html",children:"Apache Tomcat 8 Configuration Reference"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://bcho.tistory.com/788",children:"Apache Tomcat Tuning, Terry Cho"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://dev-ws.tistory.com/96",children:"maxThreads, maxConnections, acceptCount\ub85c Tomcat \ud29c\ub2dd\ud558\uae30"})]})]})}function h(e={}){const{wrapper:n}={...(0,o.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>c});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?a(Object(t),!0).forEach((function(n){o(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(t),h=o,m=p["".concat(l,".").concat(h)]||p[h]||u[h]||a;return t?r.createElement(m,i(i({ref:n},d),{},{components:t})):r.createElement(m,i({ref:n},d))}));d.displayName="MDXCreateElement"},85162:(e,n,t)=>{t.d(n,{Z:()=>i});t(67294);var r=t(86010);const o={tabItem:"tabItem_Ymn6"};var a=t(85893);function i(e){let{children:n,hidden:t,className:i}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:t,children:n})}},74866:(e,n,t)=>{t.d(n,{Z:()=>S});var r=t(67294),o=t(86010),a=t(12466),i=t(16550),s=t(20469),l=t(91980),c=t(67392),u=t(50012);function d(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:o}}=e;return{value:n,label:t,attributes:r,default:o}}))}(t);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function h(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:t}=e;const o=(0,i.k6)(),a=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,l._X)(a),(0,r.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(o.location.search);n.set(a,e),o.replace({...o.location,search:n.toString()})}),[a,o])]}function g(e){const{defaultValue:n,queryString:t=!1,groupId:o}=e,a=p(e),[i,l]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!h({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:a}))),[c,d]=m({queryString:t,groupId:o}),[g,x]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[o,a]=(0,u.Nk)(t);return[o,(0,r.useCallback)((e=>{t&&a.set(e)}),[t,a])]}({groupId:o}),b=(()=>{const e=c??g;return h({value:e,tabValues:a})?e:null})();(0,s.Z)((()=>{b&&l(b)}),[b]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!h({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),x(e)}),[d,x,a]),tabValues:a}}var x=t(72389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var f=t(85893);function j(e){let{className:n,block:t,selectedValue:r,selectValue:i,tabValues:s}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,a.o5)(),u=e=>{const n=e.currentTarget,t=l.indexOf(n),o=s[t].value;o!==r&&(c(n),i(o))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1];break}}n?.focus()};return(0,f.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":t},n),children:s.map((e=>{let{value:n,label:t,attributes:a}=e;return(0,f.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>l.push(e),onKeyDown:d,onClick:u,...a,className:(0,o.Z)("tabs__item",b.tabItem,a?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function v(e){let{lazy:n,children:t,selectedValue:o}=e;const a=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===o));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,f.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==o})))})}function C(e){const n=g(e);return(0,f.jsxs)("div",{className:(0,o.Z)("tabs-container",b.tabList),children:[(0,f.jsx)(j,{...e,...n}),(0,f.jsx)(v,{...e,...n})]})}function S(e){const n=(0,x.Z)();return(0,f.jsx)(C,{...e,children:d(e.children)},String(n))}}}]); \ No newline at end of file diff --git a/assets/js/9205.d00839b7.js b/assets/js/9205.d00839b7.js new file mode 100644 index 000000000..904320924 --- /dev/null +++ b/assets/js/9205.d00839b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9205],{43349:(e,t,n)=>{n.d(t,{a:()=>l});var r=n(96225);function l(e,t){var n=e.append("foreignObject").attr("width","100000"),l=n.append("xhtml:div");l.attr("xmlns","http://www.w3.org/1999/xhtml");var o=t.label;switch(typeof o){case"function":l.insert(o);break;case"object":l.insert((function(){return o}));break;default:l.html(o)}r.bg(l,t.labelStyle),l.style("display","inline-block"),l.style("white-space","nowrap");var a=l.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}},96225:(e,t,n)=>{n.d(t,{$p:()=>d,O1:()=>a,WR:()=>p,bF:()=>o,bg:()=>c});var r=n(37514),l=n(73234);function o(e,t){return!!e.children(t).length}function a(e){return i(e.v)+":"+i(e.w)+":"+i(e.name)}var s=/:/g;function i(e){return e?String(e).replace(s,"\\:"):""}function c(e,t){t&&e.attr("style",t)}function d(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function p(e,t){var n=t.graph();if(r.Z(n)){var o=n.transition;if(l.Z(o))return o(e)}return e}},69205:(e,t,n)=>{n.d(t,{diagram:()=>i});var r=n(75254),l=(n(45625),n(64218));n(56363),n(17452),n(3688),n(70870),n(41644),n(96225);n(43349);n(66749),n(74379);n(61666);l.c_6;var o=n(38621);n(27484),n(17967),n(27856),n(39354);const a={},s=function(e){const t=Object.keys(e);for(const n of t)a[n]=e[n]},i={parser:r.p,db:r.f,renderer:o.f,styles:o.a,init:e=>{e.flowchart||(e.flowchart={}),e.flowchart.arrowMarkerAbsolute=e.arrowMarkerAbsolute,s(e.flowchart),r.f.clear(),r.f.setGen("gen-1")}}},38621:(e,t,n)=>{n.d(t,{a:()=>h,f:()=>u});var r=n(45625),l=n(64218),o=n(56363),a=n(90360),s=n(43349),i=n(61691),c=n(71610);const d=(e,t)=>i.Z.lang.round(c.Z.parse(e)[t]);var p=n(51117);const b={},w=function(e,t,n,r,l,a){const i=r.select(`[id="${n}"]`);Object.keys(e).forEach((function(n){const r=e[n];let c="default";r.classes.length>0&&(c=r.classes.join(" ")),c+=" flowchart-label";const d=(0,o.k)(r.styles);let p,b=void 0!==r.text?r.text:r.id;if(o.l.info("vertex",r,r.labelType),"markdown"===r.labelType)o.l.info("vertex",r,r.labelType);else if((0,o.m)((0,o.c)().flowchart.htmlLabels)){const e={label:b.replace(/fa[blrs]?:fa-[\w-]+/g,(e=>`<i class='${e.replace(":"," ")}'></i>`))};p=(0,s.a)(i,e).node(),p.parentNode.removeChild(p)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",d.labelStyle.replace("color:","fill:"));const t=b.split(o.e.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}p=e}let w=0,f="";switch(r.type){case"round":w=5,f="rect";break;case"square":case"group":default:f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":case"odd_right":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"doublecircle":f="doublecircle"}t.setNode(r.id,{labelStyle:d.labelStyle,shape:f,labelText:b,labelType:r.labelType,rx:w,ry:w,class:c,style:d.style,id:r.id,link:r.link,linkTarget:r.linkTarget,tooltip:a.db.getTooltip(r.id)||"",domId:a.db.lookUpDomId(r.id),haveCallback:r.haveCallback,width:"group"===r.type?500:void 0,dir:r.dir,type:r.type,props:r.props,padding:(0,o.c)().flowchart.padding}),o.l.info("setNode",{labelStyle:d.labelStyle,labelType:r.labelType,shape:f,labelText:b,rx:w,ry:w,class:c,style:d.style,id:r.id,domId:a.db.lookUpDomId(r.id),width:"group"===r.type?500:void 0,type:r.type,dir:r.dir,props:r.props,padding:(0,o.c)().flowchart.padding})}))},f=function(e,t,n){o.l.info("abc78 edges = ",e);let r,a,s=0,i={};if(void 0!==e.defaultStyle){const t=(0,o.k)(e.defaultStyle);r=t.style,a=t.labelStyle}e.forEach((function(n){s++;const c="L-"+n.start+"-"+n.end;void 0===i[c]?(i[c]=0,o.l.info("abc78 new entry",c,i[c])):(i[c]++,o.l.info("abc78 new entry",c,i[c]));let d=c+"-"+i[c];o.l.info("abc78 new link id to be used is",c,d,i[c]);const p="LS-"+n.start,w="LE-"+n.end,f={style:"",labelStyle:""};switch(f.minlen=n.length||1,"arrow_open"===n.type?f.arrowhead="none":f.arrowhead="normal",f.arrowTypeStart="arrow_open",f.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":f.arrowTypeStart="arrow_cross";case"arrow_cross":f.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":f.arrowTypeStart="arrow_point";case"arrow_point":f.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":f.arrowTypeStart="arrow_circle";case"arrow_circle":f.arrowTypeEnd="arrow_circle"}let u="",h="";switch(n.stroke){case"normal":u="fill:none;",void 0!==r&&(u=r),void 0!==a&&(h=a),f.thickness="normal",f.pattern="solid";break;case"dotted":f.thickness="normal",f.pattern="dotted",f.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":f.thickness="thick",f.pattern="solid",f.style="stroke-width: 3.5px;fill:none;";break;case"invisible":f.thickness="invisible",f.pattern="solid",f.style="stroke-width: 0;fill:none;"}if(void 0!==n.style){const e=(0,o.k)(n.style);u=e.style,h=e.labelStyle}f.style=f.style+=u,f.labelStyle=f.labelStyle+=h,void 0!==n.interpolate?f.curve=(0,o.n)(n.interpolate,l.c_6):void 0!==e.defaultInterpolate?f.curve=(0,o.n)(e.defaultInterpolate,l.c_6):f.curve=(0,o.n)(b.curve,l.c_6),void 0===n.text?void 0!==n.style&&(f.arrowheadStyle="fill: #333"):(f.arrowheadStyle="fill: #333",f.labelpos="c"),f.labelType=n.labelType,f.label=n.text.replace(o.e.lineBreakRegex,"\n"),void 0===n.style&&(f.style=f.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),f.labelStyle=f.labelStyle.replace("color:","fill:"),f.id=d,f.classes="flowchart-link "+p+" "+w,t.setEdge(n.start,n.end,f,s)}))},u={setConf:function(e){const t=Object.keys(e);for(const n of t)b[n]=e[n]},addVertices:w,addEdges:f,getClasses:function(e,t){return t.db.getClasses()},draw:async function(e,t,n,s){o.l.info("Drawing flowchart");let i=s.db.getDirection();void 0===i&&(i="TD");const{securityLevel:c,flowchart:d}=(0,o.c)(),p=d.nodeSpacing||50,b=d.rankSpacing||50;let u;"sandbox"===c&&(u=(0,l.Ys)("#i"+t));const h="sandbox"===c?(0,l.Ys)(u.nodes()[0].contentDocument.body):(0,l.Ys)("body"),g="sandbox"===c?u.nodes()[0].contentDocument:document,y=new r.k({multigraph:!0,compound:!0}).setGraph({rankdir:i,nodesep:p,ranksep:b,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let k;const x=s.db.getSubGraphs();o.l.info("Subgraphs - ",x);for(let r=x.length-1;r>=0;r--)k=x[r],o.l.info("Subgraph - ",k),s.db.addVertex(k.id,{text:k.title,type:k.labelType},"group",void 0,k.classes,k.dir);const v=s.db.getVertices(),m=s.db.getEdges();o.l.info("Edges",m);let S=0;for(S=x.length-1;S>=0;S--){k=x[S],(0,l.td_)("cluster").append("text");for(let e=0;e<k.nodes.length;e++)o.l.info("Setting up subgraphs",k.nodes[e],k.id),y.setParent(k.nodes[e],k.id)}w(v,y,t,h,g,s),f(m,y);const T=h.select(`[id="${t}"]`),_=h.select("#"+t+" g");if(await(0,a.r)(_,y,["point","circle","cross"],"flowchart",t),o.u.insertTitle(T,"flowchartTitleText",d.titleTopMargin,s.db.getDiagramTitle()),(0,o.o)(y,T,d.diagramPadding,d.useMaxWidth),s.db.indexNodes("subGraph"+S),!d.htmlLabels){const e=g.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of e){const e=t.getBBox(),n=g.createElementNS("http://www.w3.org/2000/svg","rect");n.setAttribute("rx",0),n.setAttribute("ry",0),n.setAttribute("width",e.width),n.setAttribute("height",e.height),t.insertBefore(n,t.firstChild)}}Object.keys(v).forEach((function(e){const n=v[e];if(n.link){const r=(0,l.Ys)("#"+t+' [id="'+e+'"]');if(r){const e=g.createElementNS("http://www.w3.org/2000/svg","a");e.setAttributeNS("http://www.w3.org/2000/svg","class",n.classes.join(" ")),e.setAttributeNS("http://www.w3.org/2000/svg","href",n.link),e.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),"sandbox"===c?e.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):n.linkTarget&&e.setAttributeNS("http://www.w3.org/2000/svg","target",n.linkTarget);const t=r.insert((function(){return e}),":first-child"),l=r.select(".label-container");l&&t.append((function(){return l.node()}));const o=r.select(".label");o&&t.append((function(){return o.node()}))}}}))}},h=e=>`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=d,r=n(e,"r"),l=n(e,"g"),o=n(e,"b");return p.Z(r,l,o,t)})(e.edgeLabelBackground,.5)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`}}]); \ No newline at end of file diff --git a/assets/js/92ade856.3ed7370b.js b/assets/js/92ade856.3ed7370b.js deleted file mode 100644 index 607429b0d..000000000 --- a/assets/js/92ade856.3ed7370b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1772],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?l(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function i(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},l=Object.keys(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var u=n.createContext({}),c=function(e){var t=n.useContext(u),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,u=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(a),d=r,k=m["".concat(u,".").concat(d)]||m[d]||s[d]||l;return a?n.createElement(k,o(o({ref:t},p),{},{components:a})):n.createElement(k,o({ref:t},p))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,o=new Array(l);o[0]=m;var i={};for(var u in t)hasOwnProperty.call(t,u)&&(i[u]=t[u]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var c=2;c<l;c++)o[c]=a[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"},85162:(e,t,a)=>{a.d(t,{Z:()=>o});var n=a(67294),r=a(86010);const l="tabItem_Ymn6";function o(e){let{children:t,hidden:a,className:o}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(l,o),hidden:a},t)}},74866:(e,t,a)=>{a.d(t,{Z:()=>v});var n=a(87462),r=a(67294),l=a(86010),o=a(12466),i=a(16550),u=a(91980),c=a(67392),p=a(50012);function s(e){return function(e){return r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function m(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??s(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,a])}function d(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function k(e){let{queryString:t=!1,groupId:a}=e;const n=(0,i.k6)(),l=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,u._X)(l),(0,r.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(n.location.search);t.set(l,e),n.replace({...n.location,search:t.toString()})}),[l,n])]}function S(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,l=m(e),[o,i]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!d({value:t,tabValues:a}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:l}))),[u,c]=k({queryString:a,groupId:n}),[s,S]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,l]=(0,p.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&l.set(e)}),[a,l])]}({groupId:n}),g=(()=>{const e=u??s;return d({value:e,tabValues:l})?e:null})();(0,r.useLayoutEffect)((()=>{g&&i(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!d({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),S(e)}),[c,S,l]),tabValues:l}}var g=a(72389);const b="tabList__CuJ",y="tabItem_LNqP";function _(e){let{className:t,block:a,selectedValue:i,selectValue:u,tabValues:c}=e;const p=[],{blockElementScrollPositionUntilNextRender:s}=(0,o.o5)(),m=e=>{const t=e.currentTarget,a=p.indexOf(t),n=c[a].value;n!==i&&(s(t),u(n))},d=e=>{let t=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const a=p.indexOf(e.currentTarget)+1;t=p[a]??p[0];break}case"ArrowLeft":{const a=p.indexOf(e.currentTarget)-1;t=p[a]??p[p.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:o}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>p.push(e),onKeyDown:d,onClick:m},o,{className:(0,l.Z)("tabs__item",y,o?.className,{"tabs__item--active":i===t})}),a??t)})))}function N(e){let{lazy:t,children:a,selectedValue:n}=e;const l=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=l.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},l.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function R(e){const t=S(e);return r.createElement("div",{className:(0,l.Z)("tabs-container",b)},r.createElement(_,(0,n.Z)({},e,t)),r.createElement(N,(0,n.Z)({},e,t)))}function v(e){const t=(0,g.Z)();return r.createElement(R,(0,n.Z)({key:String(t)},e))}},68499:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>u,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var n=a(87462),r=(a(67294),a(3905)),l=a(74866),o=a(85162);const i={title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",slug:"db-replication",tags:["mysql","replication"]},u=void 0,c={permalink:"/db-replication",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",source:"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",description:"\ubcf5\uc81c(Replication)",date:"2023-08-22T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 22\uc77c",tags:[{label:"mysql",permalink:"/tags/mysql"},{label:"replication",permalink:"/tags/replication"}],readingTime:21,hasTruncateMarker:!1,authors:[],frontMatter:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",slug:"db-replication",tags:["mysql","replication"]},prevItem:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",permalink:"/performance-test-type"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",permalink:"/woowacourse-level3-retrospective"}},p={authorsImageUrls:[]},s=[{value:"\ubcf5\uc81c(Replication)",id:"\ubcf5\uc81creplication",level:2},{value:"\ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720",id:"\ubcf5\uc81c\ub97c-\ud558\ub294-\uc774\uc720",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ud30c\uc77c-\uc704\uce58-\uae30\ubc18-\ubcf5\uc81c",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd\uc758-\ubb38\uc81c\uc810",level:3},{value:"\uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c",id:"\uae00\ub85c\ubc8c-\ud2b8\ub79c\uc7ad\uc158-\uc544\uc774\ub514gtid-\uae30\ubc18-\ubcf5\uc81c",level:3},{value:"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0",id:"\ubcf5\uc81c-\ud1a0\ud3f4\ub85c\uc9c0",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd-replication-\uad6c\uc131\ud558\uae30",level:2},{value:"MySQL \ud658\uacbd \uad6c\uc131",id:"mysql-\ud658\uacbd-\uad6c\uc131",level:3},{value:"\ub3c4\ucee4 \uc2e4\ud589",id:"\ub3c4\ucee4-\uc2e4\ud589",level:3},{value:"replication slave \uad8c\ud55c \uc124\uc815",id:"replication-slave-\uad8c\ud55c-\uc124\uc815",level:3},{value:"SOURCE DB \uc815\ubcf4 \ud655\uc778",id:"source-db-\uc815\ubcf4-\ud655\uc778",level:3},{value:"SOURCE ip \uc8fc\uc18c \ud655\uc778",id:"source-ip-\uc8fc\uc18c-\ud655\uc778",level:3},{value:"replica mysql \uc811\uc18d",id:"replica-mysql-\uc811\uc18d",level:3},{value:"replica \uc124\uc815",id:"replica-\uc124\uc815",level:3},{value:"\uc124\uc815 \ud655\uc778",id:"\uc124\uc815-\ud655\uc778",level:3},{value:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30",id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8\ub85c-db-\uc811\uadfc\ud558\uae30",level:2},{value:"Environment \uc124\uc815",id:"environment-\uc124\uc815",level:3},{value:"DataSourceType \uc124\uc815",id:"datasourcetype-\uc124\uc815",level:3},{value:"AbstractRoutingDataSource \uc124\uc815",id:"abstractroutingdatasource-\uc124\uc815",level:3},{value:"DataSource \uc124\uc815",id:"datasource-\uc124\uc815",level:3},{value:"\ub3d9\uc791 \ud655\uc778",id:"\ub3d9\uc791-\ud655\uc778",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],m={toc:s};function d(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"\ubcf5\uc81creplication"},"\ubcf5\uc81c(Replication)"),(0,r.kt)("p",null,"\ud55c \uc11c\ubc84\uc5d0\uc11c \ub2e4\ub978 \uc11c\ubc84\ub85c \ub370\uc774\ud130\ub97c \ub3d9\uae30\ud654\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc6d0\ubcf8 \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Primary \ub610\ub294 Source \ub77c\uace0 \ubd80\ub974\uace0, \ubcf5\uc81c\ub41c \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Secondary \ub610\ub294 Replica \ub77c\uace0 \ubd80\ub978\ub2e4. "),(0,r.kt)("h3",{id:"\ubcf5\uc81c\ub97c-\ud558\ub294-\uc774\uc720"},"\ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"1. \uc2a4\ucf00\uc77c \uc544\uc6c3")),(0,r.kt)("p",null,"\uc0ac\uc6a9\uc790\uc758 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0, \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uac00\ud574\uc9c0\ub294 \ubd80\ud558\ub3c4 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc99d\uac00\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud574 \ubcf5\uc81c\ub97c \ud1b5\ud55c \uc2a4\ucf00\uc77c \uc544\uc6c3\uc744 \uc801\uc6a9\ud558\uc5ec \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucffc\ub9ac\ub4e4\uc744 \uac01\uac01\uc758 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub85c \ubd84\uc0b0 \uc2dc\ud0ac \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"2. \ub370\uc774\ud130 \ubc31\uc5c5")),(0,r.kt)("p",null,"\uc2e4\uc81c \uc6b4\uc601\ub418\ub294 \uc11c\ube44\uc2a4\uac00 \uc0ac\uc6a9\ud558\uace0 \uc788\ub294 DB\uc5d0\uc11c \ubc31\uc5c5\uc744 \uc9c4\ud589\ud558\ub294 \uacbd\uc6b0, \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc2e4\uc81c \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc774 \uac00\uc9c0 \uc54a\ub3c4\ub85d \ubcf5\uc81c\ub97c \ud1b5\ud574 Replica \uc11c\ubc84\ub97c \uad6c\ucd95\ud558\uc5ec, Replica \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ub97c \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\uc73c\ub85c \uc601\ud5a5\uc744 \ucd5c\uc18c\ud654 \ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"3. \ub370\uc774\ud130 \ubd84\uc11d")),(0,r.kt)("p",null,"\ubc31\uc5c5\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc7a1\ud558\uace0 \ubb34\uac70\uc6b4 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\uc758 \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc81c\ub97c \uc0ac\uc6a9\ud574 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ud658\uacbd\uc744 \ub9cc\ub4e4 \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"4. \ub370\uc774\ud130\uc758 \uc9c0\ub9ac\uc801 \ubd84\uc0b0")),(0,r.kt)("p",null,"\ube60\ub978 \uc751\ub2f5\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc11c\ubc84\uc5d0 \uac00\uae5d\uac8c \uc11c\ubc84\ub97c \uad6c\uc131\ud558\uac70\ub098, \uace0\uac00\uc6a9\uc131(High Availability)\uc744 \uc704\ud574\uc11c\ub3c4 \uc0ac\uc6a9\ub41c\ub2e4. "),(0,r.kt)("h3",{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ud30c\uc77c-\uc704\uce58-\uae30\ubc18-\ubcf5\uc81c"},"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c"),(0,r.kt)("p",null,"MySQL \uc11c\ubc84\uc5d0\uc11c \ubc1c\uc0dd\ud558\ub294 \ubcc0\uacbd\uc0ac\ud56d\uc5d0 \ub300\ud55c \ub85c\uadf8 \ud30c\uc77c\uc744 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub77c\uace0 \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ud1b5\ud574 \ub370\uc774\ud130 \ubcc0\uacbd, \ud14c\uc774\ube14 \uad6c\uc870 \ubcc0\uacbd, \uacc4\uc815\uc774\ub098 \uad8c\ud55c \ubcc0\uacbd\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc800\uc7a5\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MySQL\uc758 \ubcf5\uc81c\ub294 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 \uc788\ub2e4. \uc774\ub97c Replica \uc11c\ubc84\ub85c \uc804\ub2ec\ud558\uace0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \ub370\uc774\ud130\ub97c \ubcc0\uacbd \uc0ac\ud56d\uc744 \ubc18\uc601\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n\tsubgraph Replica\n\t\tdirection TB\n\t\tIO[Replication I/O thread] -- save --\x3e RL[Relay Log]\n\t\tSQL[Replication SQL Thread] -- read --\x3e RL\n\tend\n\n\tsubgraph Source\n\t\tdirection TB\n\t\tBLD[Binary Log Dump Thread] -- Send Binary Log Dump--\x3e IO\n\tend\n"}),(0,r.kt)("admonition",{title:"\uc2a4\ub808\ub4dc\ubcc4 \uc5ed\ud560",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Binary Log Dump Thread: \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc758 \ub0b4\uc6a9\uc744 Replica \uc11c\ubc84\ub85c \uc804\ub2ec",(0,r.kt)("br",{parentName:"p"}),"\n","Replication I/O Thread: Binary \ub85c\uadf8 \uc774\ubca4\ud2b8\ub97c \uac00\uc838\uc640 \ub85c\uceec \uc11c\ubc84\uc758 \ud30c\uc77c(Relay Log)\ub85c \uc800\uc7a5",(0,r.kt)("br",{parentName:"p"}),"\n","Replication SQL Thread: \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc774\ubca4\ud2b8\ub97c \uc77d\uace0 \uc2e4\ud589")),(0,r.kt)("h3",{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd\uc758-\ubb38\uc81c\uc810"},"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810"),(0,r.kt)("p",null,"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc740 \uc11c\ubc84\uc5d0 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud588\uc744 \ub54c \ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0 \ubcc0\uacbd\uc774 \uae4c\ub2e4\ub86d\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud1a0\ud3f4\ub85c\uc9c0\ub780 \ub124\ud2b8\uc6cc\ud06c\uc758 \uc694\uc18c\ub4e4\uc744 \ubb3c\ub9ac\uc801\uc73c\ub85c \uc5f0\uacb0\ud574 \ub193\uc740 \uac83, \ub610\ub294 \uadf8 \uc5f0\uacb0 \ubc29\uc2dd\uc744 \ub9d0\ud55c\ub2e4."),(0,r.kt)("mermaid",{value:"graph TD\n\tA[A binary-log:300] --\x3e B[B Binary-log:300]\n\tA[A binary-log:300] --\x3e C[C Binary-log:200]"}),(0,r.kt)("p",null,"\uc704\uc640 \uac19\uc774 Source \uc11c\ubc84, Replica 2\ub300\uac00 \uc874\uc7ac\ud558\uace0, C \uc11c\ubc84\uc5d0 \ubcf5\uc81c \uc9c0\uc5f0\uc774 \ub418\uc5c8\uc744 \ub54c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph TD\n\tA[A binary-log:300]\n\tB[B Binary-log:300] --\x3e C[C Binary-log:200 \ubb38\uc81c \ubc1c\uc0dd]"}),(0,r.kt)("p",null,"A \uc11c\ubc84\uc5d0\uc11c \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 B \uc11c\ubc84\ub97c Source \uc11c\ubc84\ub85c \uc2b9\uaca9\ud558\uace0, C\uc5d0\uac8c \uc870\ud68c \ucffc\ub9ac\ub97c \ubd84\uc0b0\uc2dc\ud0a8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uc5ec\uae30\uc11c C \uc11c\ubc84\uc5d0\ub294 A \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\uac00 \uc548\ub418\uc5c8\uc73c\ub2c8 \uc870\ud68c \uc2dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub4a4\ub2a6\uac8c B \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\ub97c \ud558\ub824\uace0 \ud574\ub3c4, \uc5b4\ub5a4 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8, \uc5b4\ub5a4 \uc704\uce58\uc640 \ub3d9\uae30\ud654\ud574\uc57c\ud558\ub294\uc9c0 \uc54c\uae30 \uc5b4\ub835\ub2e4. "),(0,r.kt)("h3",{id:"\uae00\ub85c\ubc8c-\ud2b8\ub79c\uc7ad\uc158-\uc544\uc774\ub514gtid-\uae30\ubc18-\ubcf5\uc81c"},"\uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c"),(0,r.kt)("p",null,"GTID \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ubc1c\uc0dd\ud55c \uc774\ubca4\ud2b8\uc5d0 \uace0\uc720\ud55c \uc2dd\ubcc4\uac12\uc744 \ubd80\uc5ec\ud55c\ub2e4\uba74, \ub3d9\uae30\ud654\uc5d0 \ub300\ud55c \ubb38\uc81c\ub97c \uac04\ub2e8\ud558\uac8c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc704\uc758 \uc608\uc2dc\uc640 \uac19\uc774 \ubcf5\uc81c \uc9c0\uc5f0\uacfc \ud568\uaed8 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\ud574\ub3c4 \ud2b9\uc815 GTID \ubd80\ud130 \ubcf5\uc81c\ub97c \uc7ac\uac1c\ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("admonition",{title:"GTID",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0\uc5d0 \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \uc11c\ubc84\uc5d0\uc11c \uace0\uc720\ud558\ub3c4\ub85d \uac01 \uc774\ubca4\ud2b8\uc5d0 \ubd80\uc5ec\ub41c \uc2dd\ubcc4\uac12",(0,r.kt)("br",{parentName:"p"}),"\n","[source_id]",":","[transaction_id]","\ub85c \uad6c\uc131\ub418\uba70, source_id\ub294 \uc11c\ubc84\ub97c \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc774\uace0 transaction_id\ub294 \ucee4\ubc0b\ub41c \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc73c\ub85c 1\uc529 \uc99d\uac00\ud558\ub294 \ud615\ud0dc\ub85c \ubc1c\uae09\ub41c\ub2e4. ")),(0,r.kt)("h3",{id:"\ubcf5\uc81c-\ud1a0\ud3f4\ub85c\uc9c0"},"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"\uac00\uc7a5 \uac04\ub2e8\ud55c \uad6c\uc131\uc73c\ub85c \uc81c\uc77c \ub9ce\uc774 \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","replica \uc11c\ubc84\ub97c \uc77d\uae30 \uc804\uc6a9, \uc608\ube44 \uc11c\ubc84, \ubc31\uc5c5 \uc6a9\ub3c4\ub85c \ub9ce\uc774 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R\n S[Source] --\x3e R[Replica]"}),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uba40\ud2f0 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"2\uac1c\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\ub098\uc758 replica\ub294 \uc608\ube44 \uc6a9\ub3c4\ub85c \ub0a8\uaca8\ub450\ub294 \ud615\ud0dc\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\ud6c4\uc5d0 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0 \uc608\ube44 \uc6a9\ub3c4\uc758 replica\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c \uc77d\uae30 \uc694\uccad\uc758 \ubd80\ud558 \ubd84\uc0b0\uc744 \ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R1\n S[Source] --\x3e R1[Replica1]\n S --\x3e R2[Replica2]"}),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uccb4\uc778 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"replica \uc11c\ubc84\uac00 \ub9ce\uc740 \uacbd\uc6b0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \uc804\ub2ec\ud558\ub294 \uc791\uc5c5 \uc790\uccb4\uac00 \ubd80\ud558\uac00 \ub420 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c 1:M:M \uad6c\uc870\ub85c \uccb4\uc778 \ubcf5\uc81c \uad6c\uc131\uc744 \uace0\ub824\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R1\n S[Source] --\x3e R1[Replica1]\n S --\x3e R2[Replica2]\n S --\x3e R3[Replica3]\n\n R3 --\x3e R3-1[Replica 3-1]\n R3 --\x3e R3-2[Replica 3-2]\n\n B[Batch Server] --\x3e R3-2"}),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\ub4c0\uc5bc \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"2\uac1c\uc758 MySQL \uc11c\ubc84 \ubaa8\ub450 \uc77d\uae30\uc640 \uc4f0\uae30\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d \ud558\ub294 \uad6c\uc131\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uac01 \uc11c\ubc84\uc5d0\uc11c \ubcc0\uacbd\ub41c \ub370\uc774\ud130\ub294 \ub2e4\ub978 \uc11c\ubc84\uc5d0 \ubc18\uc601\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubaa9\uc801\uc5d0 \ub530\ub77c ACTIVE-ACTIVE \ud615\ud0dc \ub610\ub294 ACTIVE-PASSIVE \ud615\ud0dc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","ACTIVE-PASSIVE \ud615\ud0dc\uc778 \uacbd\uc6b0 \uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131\uacfc \ub3d9\uc77c\ud574\ubcf4\uc774\uc9c0\ub9cc, ACTIVE \uc11c\ubc84\uc5d0\uc11c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uba74 \uc124\uc815\uc758 \ubcc0\uacbd\uc5c6\uc774 PASSIVE \uc11c\ubc84\ub85c \uc4f0\uae30 \uc791\uc5c5\uc744 \uc804\ud658\ud560 \uc218 \uc788\ub2e4\ub294 \uac83\uc774 \uc7a5\uc810\uc774\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR1\n W -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR2\n SR1[Source/Replica 1] --\x3e SR2[Source/Replica 2]"}),(0,r.kt)("admonition",{title:"ACTIVE-ACTIVE, ACTIVE-PASSIVE",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"ACTIVE-ACTIVE: 2\uac1c\uc758 \uc11c\ubc84 \ubaa8\ub450 \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc",(0,r.kt)("br",{parentName:"p"}),"\n","ACTIVE-PASSIVE: \ud558\ub098\uc758 \uc11c\ubc84\uc5d0\uc11c\ub9cc \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uba40\ud2f0 \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"\uc5ec\ub7ec\uac1c\uc758 source \uc11c\ubc84\uc640 \ud558\ub098\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \uad6c\uc131\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 source \uc11c\ubc84\uc758 \ub370\uc774\ud130\ub97c \ud55c \uacf3\uc5d0 \ubc31\uc5c5\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9, \uc5ec\ub7ec \uc11c\ubc84\uc5d0 \uc874\uc7ac\ud558\ub294 \ub370\uc774\ud130\ub97c \ud1b5\ud569, \uc0e4\ub529\ub418\uc5b4\uc788\ub294 \ud14c\uc774\ube14 \ub370\uc774\ud130\ub97c \ud1b5\ud569\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n S1[Source 1] --\x3e R[Replica]\n S2[Source 2] --\x3e R"}),(0,r.kt)("h2",{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd-replication-\uad6c\uc131\ud558\uae30"},"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30"),(0,r.kt)("p",null,"mysql 2\ub300\ub97c \uc774\uc6a9\ud558\uc5ec replication\uc744 \uad6c\uc131\ud558\uace0, spring boot application\uc73c\ub85c source, replica \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc811\uadfc\ud574\ubcf4\ub294 \uc608\uc81c\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/bbiac/db-replication"},"https://github.com/bbiac/db-replication")," "),(0,r.kt)("h3",{id:"mysql-\ud658\uacbd-\uad6c\uc131"},"MySQL \ud658\uacbd \uad6c\uc131"),(0,r.kt)("p",null,"MySQL \ubc84\uc804\uc740 8.1\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","13306, 13307 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud574\uc11c MySQL \uc11c\ubc84 2\ub300\ub97c \ub744\uc6e0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \uc0ac\uc2e4 IP \ub300\uc5ed\uc73c\ub85c \ud1b5\uc2e0\ud560 \uc218 \uc788\ub3c4\ub85d \ucee4\uc2a4\ud140 \ub124\ud2b8\uc6cc\ud06c\ub97c \ucd94\uac00\ud588\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml"},"version: '3.8'\n\nservices:\n source:\n platform: linux/x86_64\n image: mysql:latest\n restart: always\n container_name: mysql-source\n environment:\n TZ: 'Asia/Seoul'\n MYSQL_DATABASE: 'db'\n MYSQL_USER: 'user'\n MYSQL_PASSWORD: 'password'\n MYSQL_ROOT_PASSWORD: 'password'\n ports:\n - \"13306:3306\"\n volumes:\n - db-source:/var/lib/mysql\n - db-source:/var/lib/mysql-files\n - ./docker/source.cnf:/etc/mysql/my.cnf\n networks:\n - mysql_network\n\n replica:\n platform: linux/x86_64\n image: mysql:latest\n restart: always\n container_name: mysql-replica\n environment:\n TZ: 'Asia/Seoul'\n MYSQL_DATABASE: 'db'\n MYSQL_USER: 'user'\n MYSQL_PASSWORD: 'password'\n MYSQL_ROOT_PASSWORD: 'password'\n ports:\n - \"13307:3306\"\n volumes:\n - db-replica:/var/lib/mysql\n - db-replica:/var/lib/mysql-files\n - ./docker/replica.cnf:/etc/mysql/my.cnf\n networks:\n - mysql_network\n\nvolumes:\n db-source:\n db-replica:\n\nnetworks:\n mysql_network:\n driver: bridge\n")),(0,r.kt)("p",null,"\ub610\ud55c source, replica \uac01\uac01 \ub2e4\uc74c\uacfc \uac19\uc774 db \uc124\uc815\uc744 \ud588\ub2e4. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uc815"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"server_id"),(0,r.kt)("td",{parentName:"tr",align:null},"\uac01\uac01\uc758 mysql \ub9c8\ub2e4 \uace0\uc720\ud55c \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"log_bin"),(0,r.kt)("td",{parentName:"tr",align:null},"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815\uc73c\ub85c \uc808\ub300\uacbd\ub85c\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 /var/lib/mysql \uc544\ub798 \ud574\ub2f9 log_bin\uc5d0 \uc124\uc815\ub41c \uac12\uc73c\ub85c \ub85c\uadf8\uac00 \uc0dd\uc131\ub41c\ub2e4.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"sync_binlog"),(0,r.kt)("td",{parentName:"tr",align:null},"N\uac1c\uc758 \ud2b8\ub79c\uc7ad\uc158 \ub2f9 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ub514\uc2a4\ud06c\uc640 \ub3d9\uae30\ud654 \uc791\uc5c5\uc744 \ud558\ub3c4\ub85d \ud55c\ub2e4.\xa01\uc740 \uae30\ubcf8\uac12\uc73c\ub85c \uc548\uc815\uc801\uc774\uc9c0\ub9cc, \uac00\uc7a5 \ub290\ub9ac\ub2e4.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"relay_log"),(0,r.kt)("td",{parentName:"tr",align:null},"\ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"relay_log_purge"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud544\uc694 \uc5c6\ub294 \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc744 \uc790\ub3d9\uc73c\ub85c \uc0ad\uc81c\ud558\ub294 \uc635\uc158")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"read_only"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc77d\uae30 \uc804\uc6a9 \uc124\uc815")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"log_replica_updates"),(0,r.kt)("td",{parentName:"tr",align:null},"Replication SQL Thread\ub85c \uc778\ud574 \uc2e4\ud589\ub418\ub294 \uc815\ubcf4\ub97c \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc5d0 \uae30\ub85d \ucd94\ud6c4\uc5d0 \uc18c\uc2a4 \uc11c\ubc84\ub85c \uc2b9\uaca9\ub418\ub294 \uacbd\uc6b0\ub97c \uace0\ub824\ud558\uba74 \uc124\uc815\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.")))),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{value:"Source",label:"Source",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-cnf",metastring:'title="/docker/source.cnf"',title:'"/docker/source.cnf"'},"[mysqld]\nserver_id=1\nlog_bin=mysql-bin\nsync_binlog=1\n"))),(0,r.kt)(o.Z,{value:"Replica",label:"Replica",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-cnf",metastring:'title="/docker/replica.cnf"',title:'"/docker/replica.cnf"'},"[mysqld]\nserver_id=2\nrelay_log=mysql-relay-bin\nrelay_log_purge=ON\nread_only\nlog_replica_updates\n")))),(0,r.kt)("h3",{id:"\ub3c4\ucee4-\uc2e4\ud589"},"\ub3c4\ucee4 \uc2e4\ud589"),(0,r.kt)("p",null,"docker-compose up \uba85\ub839\uc5b4\ub85c docker-compose \uc124\uc815\uc73c\ub85c docker\ub97c \ub744\uc6b4\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","-d \uc635\uc158\uc744 \ubd99\uc774\uba74 \ubc31\uadf8\ub77c\uc6b4\ub4dc \ubaa8\ub4dc\ub85c \uc2e4\ud589\ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"docker-compose up -d\n")),(0,r.kt)("h3",{id:"replication-slave-\uad8c\ud55c-\uc124\uc815"},"replication slave \uad8c\ud55c \uc124\uc815"),(0,r.kt)("p",null,"REPLICATION SLAVE \uad8c\ud55c\uc774 \uc124\uc815\ub418\uc5b4 \uc788\uc5b4\uc57c replica \uc11c\ubc84\uc5d0\uc11c source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec \ub85c\uadf8\ub97c \uc77d\uc5b4\uc62c \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec user \uacc4\uc815\uc5d0 \ud574\ub2f9 \uad8c\ud55c\uc744 \uc124\uc815\ud574\uc900\ub2e4. "),(0,r.kt)("p",null,"SOURCE \uc811\uc18d"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"docker exec -it mysql-source mysql -u root -p\n")),(0,r.kt)("p",null,"user \uacc4\uc815\uc5d0 REPLICATION SLAVE \uad8c\ud55c \ucd94\uac00"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mysql"},"GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';\nFLUSH PRIVILEGES;\n")),(0,r.kt)("h3",{id:"source-db-\uc815\ubcf4-\ud655\uc778"},"SOURCE DB \uc815\ubcf4 \ud655\uc778"),(0,r.kt)("p",null,"replica \uc124\uc815\uc5d0 \ud544\uc694\ud55c source db\uc758 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c\uba85\uacfc Position\uc744 \ud655\uc778\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Position \uac12\uc740 \uc2e4\uc81c \ud30c\uc77c\uc758 \ubc14\uc774\ud2b8 \uc218\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud655\uc778\ud55c File(SOURCE_LOG_FILE)\uacfc Position(SOURCE_LOG_POS) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mysql"},"SHOW MASTER STATUS;\n\n+------------------+----------+--------------+------------------+-------------------+\n| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\n+------------------+----------+--------------+------------------+-------------------+\n| mysql-bin.000003 | 1082 | | | |\n+------------------+----------+--------------+------------------+-------------------+\n")),(0,r.kt)("h3",{id:"source-ip-\uc8fc\uc18c-\ud655\uc778"},"SOURCE ip \uc8fc\uc18c \ud655\uc778"),(0,r.kt)("p",null,"docker inspect -f \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uba74 \ud574\ub2f9 \ucee8\ud14c\uc774\ub108\uc758 \uc138\ubd80 \uc815\ubcf4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud574 docker-compose \ud30c\uc77c\uc5d0 \uc124\uc815\ud574\ub454 mysql_network\uc5d0\uc11c \uc0ac\uc6a9\ub418\ub294 \uc0ac\uc124 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \ud655\uc778\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'docker inspect -f "{{with index .NetworkSettings.Networks \\"db-replication_mysql_network\\"}}{{.IPAddress}}{{end}}" mysql-source\n')),(0,r.kt)("p",null,"ip \uc8fc\uc18c\uac00 \ub098\uc624\uc9c0 \uc54a\ub294 \uacbd\uc6b0 docker inspect mysql-source\ub85c \ud655\uc778\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud655\uc778\ud55c IP\uc8fc\uc18c(SOURCE_HOST) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4."),(0,r.kt)("h3",{id:"replica-mysql-\uc811\uc18d"},"replica mysql \uc811\uc18d"),(0,r.kt)("p",null,"source db\uc5d0 \uc811\uc18d\ud588\ub358 \ubc29\ubc95\uacfc \ub3d9\uc77c\ud558\uac8c replica db\uc5d0 \uc811\uc18d\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"docker exec -it mysql-replica mysql -u root -p\n")),(0,r.kt)("h3",{id:"replica-\uc124\uc815"},"replica \uc124\uc815"),(0,r.kt)("p",null,"\uc774\uc804\uc5d0 source db\uc5d0\uc11c \uc5bb\uc5c8\ub358 \uc815\ubcf4\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc5ec replica \uc124\uc815\uc744 \uc9c4\ud589\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc2e4\uc81c DB \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc73c\ub85c source DB\uc758 \ud30c\uc77c\uc744 \ubcf5\uc81c\ud574\uc57c\ud558\uc9c0\ub9cc \ud604\uc7ac \ubcf5\uc81c\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ubd80\ubd84\uc740 \uc0dd\ub7b5\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS \ub97c \uc801\uc808\ud788 \ubcc0\uacbd\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mysql"},"STOP REPLICA;\n\nCHANGE REPLICATION SOURCE TO \nSOURCE_HOST='172.29.0.2', \nSOURCE_USER='user', \nSOURCE_PASSWORD='password', \nSOURCE_LOG_FILE='mysql-bin.000001', \nSOURCE_LOG_POS=0, \nGET_SOURCE_PUBLIC_KEY=1;\n\nSTART REPLICA;\n")),(0,r.kt)("h3",{id:"\uc124\uc815-\ud655\uc778"},"\uc124\uc815 \ud655\uc778"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mysql"},"SHOW REPLICA STATUS;\n\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n")),(0,r.kt)("p",null,"Replica_IO_Running, Replica_SQL_Running \uac12\uc774 YES\ub77c\uba74 \uc815\uc0c1\uc801\uc73c\ub85c replication \uad6c\uc131\uc774 \uc644\ub8cc\ub41c \uac83\uc774\ub2e4. "),(0,r.kt)("p",null,"\uc124\uc815\uc744 \ub9c8\uce5c \ud6c4 source db\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 create table \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","replica db\uc5d0 \ub3d9\uc77c\ud55c member table\uc774 \uc0dd\uc131\ub41c \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"CREATE TABLE member\n(\n id BIGINT PRIMARY KEY AUTO_INCREMENT,\n name VARCHAR(255)\n);\n")),(0,r.kt)("h2",{id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8\ub85c-db-\uc811\uadfc\ud558\uae30"},"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30"),(0,r.kt)("p",null,"\uc77c\ubc18\uc801\uc778 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 source, \uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158\uc778 \uacbd\uc6b0 replica\ub85c \uc694\uccad\uc774 \uac00\ub3c4\ub85d \uad6c\uc131\ud574\ubcf4\uc790. "),(0,r.kt)("h3",{id:"environment-\uc124\uc815"},"Environment \uc124\uc815"),(0,r.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 source, replica\ub85c \uad6c\ubd84\ud558\uc5ec \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml",metastring:'title="application.yml"',title:'"application.yml"'},"spring:\n datasource:\n source:\n username: user\n password: password\n driver-class-name: com.mysql.cj.jdbc.Driver\n jdbc-url: jdbc:mysql://localhost:13306/db\n replica:\n username: user\n password: password\n driver-class-name: com.mysql.cj.jdbc.Driver\n jdbc-url: jdbc:mysql://localhost:13307/db\n")),(0,r.kt)("h3",{id:"datasourcetype-\uc124\uc815"},"DataSourceType \uc124\uc815"),(0,r.kt)("p",null,"\ub2e8\uc21c \ubb38\uc790\uc5f4\ub85c\ub3c4 \uad6c\ubd84\ud560 \uc218 \uc788\uc9c0\ub9cc, enum\uc744 \uc774\uc6a9\ud574\uc11c \ud2b8\ub79c\uc7ad\uc158\uc744 \uad6c\ubd84\ud558\ub3c4\ub85d \uc0dd\uc131\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Key\ub294 \ucd94\ud6c4\uc5d0 \ube48 \uc124\uc815\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="DataSourceType"',title:'"DataSourceType"'},'public enum DataSourceType {\n SOURCE(SOURCE_NAME),\n REPLICA(REPLICA_NAME),\n ;\n\n private final String key;\n\n DataSourceType(String key) {\n this.key = key;\n }\n\n public static class Key {\n public static final String ROUTING_NAME = "ROUTING";\n public static final String SOURCE_NAME = "SOURCE";\n public static final String REPLICA_NAME = "REPLICA";\n }\n}\n')),(0,r.kt)("h3",{id:"abstractroutingdatasource-\uc124\uc815"},"AbstractRoutingDataSource \uc124\uc815"),(0,r.kt)("p",null,"\uc2a4\ud504\ub9c1\uc774 \uc9c0\uc6d0\ud574\uc8fc\ub294 AbstractRoutingDataSource\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSource\ub97c \ud5a5\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("p",null,"\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub294 Map<DataSourceKey, DataSource>\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\uc744 \ubc1b\uc544 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"setDefaultTargetDataSource: \uae30\ubcf8 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("li",{parentName:"ul"},"setTargetDataSources: \ub9f5 \ud615\ud0dc\ub85c \ubc1b\uc740 \ub370\uc774\ud130 \uc18c\uc2a4 \uac12\ub4e4\uc744 \uc124\uc815\ud55c\ub2e4. ")),(0,r.kt)("p",null,"determineCurrentLookupKey\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \ud2b8\ub79c\uc7ad\uc158\uc774 \uc77d\uae30 \uc804\uc6a9\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("li",{parentName:"ul"},"DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uace0, \ubc18\ud658\ud55c \uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ub370\uc774\ud130 \uc18c\uc2a4\uac00 \uc0ac\uc6a9\ub41c\ub2e4. ")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="RoutingDataSource"',title:'"RoutingDataSource"'},'public class RoutingDataSource extends AbstractRoutingDataSource {\n\n private final Logger log = LoggerFactory.getLogger(getClass());\n\n public static RoutingDataSource from(Map<Object, Object> dataSources) {\n RoutingDataSource routingDataSource = new RoutingDataSource();\n routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));\n routingDataSource.setTargetDataSources(dataSources);\n return routingDataSource;\n }\n\n @Override\n protected Object determineCurrentLookupKey() {\n boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();\n\n if (readOnly) {\n log.info("readOnly = true, request to replica");\n return DataSourceType.REPLICA;\n }\n log.info("readOnly = false, request to source");\n return DataSourceType.SOURCE;\n }\n}\n')),(0,r.kt)("h3",{id:"datasource-\uc124\uc815"},"DataSource \uc124\uc815"),(0,r.kt)("p",null,"\uc704\uc5d0\uc11c\ubd80\ud130 \uc21c\uc11c\ub300\ub85c Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy \uc124\uc815\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud504\ub9c1\uc740 \ud2b8\ub79c\uc7ad\uc158 \uc2dc\uc791\uc2dc\uc5d0 \ucee4\ub125\uc158\uc758 \uc0ac\uc6a9\uc5ec\ubd80\uc640 \uc0c1\uad00\uc5c6\uc774 \ucee4\ub125\uc158\uc744 \ud655\ubcf4\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c readOnly \ud2b8\ub79c\uc7ad\uc158\uc774 \uc124\uc815\ub41c \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ubbf8\ub9ac \ud655\ubcf4\ub41c \ucee4\ub125\uc158\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 replica db\ub85c \uc694\uccad\uc744 \ud558\uc9c0 \uc54a\uace0 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4. "),(0,r.kt)("p",null,"TransactionSynchronizationManager.isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc \ud638\ucd9c \uc2dc currentTransactionReadOnly\ub77c\ub294 ",(0,r.kt)("inlineCode",{parentName:"p"},"ThreadLocal<Boolean>"),"\uc5d0 \uc124\uc815\ub41c \uac12\uc744 \ubc18\ud658\ud558\ub294\ub370 readOnly \uc124\uc815\uc774 \ub418\uba74 \uc774 \uac12\uc744 true\ub85c \uc124\uc815\ud55c\ub2e4. \ud558\uc9c0\ub9cc determineCurrentLookupKey\ub97c \ud638\ucd9c\ud558\uc5ec key \uac12\uc744 \uac00\uc838\uc624\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc774\ud6c4\uc5d0 \uc124\uc815\ub418\uae30 \ub54c\ubb38\uc5d0 determineCurrentLookupKey \uba54\uc11c\ub4dc\uc5d0\uc11c \ud56d\uc0c1 DataSourceType.SOURCE\uac00 \ubc18\ud658\ub418\uc5b4 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4. "),(0,r.kt)("p",null,"LazyConnectionDataSourceProxy\ub97c \uc124\uc815\ud558\ub294 \uacbd\uc6b0 \uc2e4\uc81c DataSource\ub97c \uc0ac\uc6a9\ud558\ub294 \uc2dc\uc810\uc5d0 \ucee4\ub125\uc158\uc744 \ud68d\ub4dd\ud574\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc124\uc815\ud55c\ub300\ub85c replica db\ub85c \uc870\ud68c \uc694\uccad\uc744 \ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="DataSourceConfiguration"',title:'"DataSourceConfiguration"'},'@Configuration\npublic class DataSourceConfiguration {\n\n @Bean\n @Qualifier(SOURCE_NAME)\n @ConfigurationProperties(prefix = "spring.datasource.source")\n public DataSource sourceDataSource() {\n return DataSourceBuilder.create().build();\n }\n\n @Bean\n @Qualifier(REPLICA_NAME)\n @ConfigurationProperties(prefix = "spring.datasource.replica")\n public DataSource replicaDataSource() {\n return DataSourceBuilder.create().build();\n }\n\n @Bean\n @Qualifier(ROUTING_NAME)\n public DataSource routingDataSource(\n @Qualifier(SOURCE_NAME) DataSource sourceDataSource,\n @Qualifier(REPLICA_NAME) DataSource replicaDataSource\n ) {\n return RoutingDataSource.from(Map.of(\n DataSourceType.SOURCE, sourceDataSource,\n DataSourceType.REPLICA, replicaDataSource\n ));\n }\n\n @Bean\n @Primary\n public DataSource dataSource(\n @Qualifier(ROUTING_NAME) DataSource routingDataSource\n ) {\n return new LazyConnectionDataSourceProxy(routingDataSource);\n }\n}\n')),(0,r.kt)("p",null,"\ucd5c\uc885\uc801\uc73c\ub85c DataSource \ube48\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\uac00 \ub41c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n DSP[LazyConnectionDataSourceProxy] --\x3e RDS[RoutingDataSource]\n\tRDS --\x3e S[SourceDataSource]\n\tRDS --\x3e R[ReplicaDataSource]"}),(0,r.kt)("h3",{id:"\ub3d9\uc791-\ud655\uc778"},"\ub3d9\uc791 \ud655\uc778"),(0,r.kt)("p",null,"\uac04\ub2e8\ud558\uac8c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud574\uc11c \uc124\uc815\ud55c\ub300\ub85c \ub3d9\uc791\uc774 \ub418\ub294\uc9c0 \ud655\uc778\ud574\ubcf4\uc558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","save \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 ",(0,r.kt)("inlineCode",{parentName:"p"},"@Transactional"),", findById \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 ",(0,r.kt)("inlineCode",{parentName:"p"},"@Transactional(readOnly = true)"),"\uac00 \uc124\uc815\ub418\uc5b4\uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub85c\uadf8\ub97c \ud1b5\ud574 save\uc758 \uacbd\uc6b0 source db\ub85c findById\uc758 \uacbd\uc6b0 replica db\ub85c \uc694\uccad\uc744 \ud558\ub294 \uac83\uc744 \uc54c \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="MemberServiceTest"',title:'"MemberServiceTest"'},'@SpringBootTest\nclass MemberServiceTest {\n\n @Autowired\n private MemberService memberService;\n\n @Test\n void \uc0ac\uc6a9\uc790\ub97c_\uc800\uc7a5\ud55c\ub2e4() {\n // RoutingDataSource log: readOnly = false\n memberService.save("bbiac");\n }\n\n @Test\n void \uc0ac\uc6a9\uc790\ub97c_\uc870\ud68c\ud55c\ub2e4() {\n // RoutingDataSource log: readOnly = true\n assertThatThrownBy(() -> memberService.findById(MAX_VALUE))\n .isInstanceOf(NoSuchElementException.class);\n }\n}\n')),(0,r.kt)("p",null,"DB\uc5d0\uc11c\ub294 \ud655\uc778\ud558\ub824\uba74 root \uacc4\uc815\uc73c\ub85c \uc811\uc18d\ud55c \ud6c4 general log\ub97c \ud65c\uc131\ud654 \uc2dc\ud0a8\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"SET GLOBAL log_output = 'table';\nSET GLOBAL general_log = 1;\n")),(0,r.kt)("p",null,"general log\ub97c \ud65c\uc131\ud654 \ud55c \ud6c4 \uc77d\uae30 \uc804\uc6a9 \uba54\uc11c\ub4dc\ub97c \uc2e4\ud589\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","server_id, \uc2e4\ud589\ud55c \ucffc\ub9ac\ubb38\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';\n\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n| user_host | thread_id | server_id | convert(argument using utf8) |\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n")),(0,r.kt)("p",null,"\ud655\uc778 \ud6c4 general log\ub97c \ube44\ud65c\uc131\ud654 \ud55c \ud6c4 \ube44\ud65c\uc131\ud654 \ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"SET GLOBAL general_log = 0;\nSHOW VARIABLES LIKE '%general%';\n\n+------------------+---------------------------------+\n| Variable_name | Value |\n+------------------+---------------------------------+\n| general_log | OFF |\n| general_log_file | /var/lib/mysql/4b6b9db98290.log |\n+------------------+---------------------------------+\n")),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"16\uc7a5 \ubcf5\uc81c, Real MySQL 8.0 - \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.1/en/replication.html"},"Replication, MySQL Docs"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://huisam.tistory.com/entry/mysql-replication"},"MySql - Master Slave Replication \uad6c\uc870 \ub9cc\ub4e4\uc5b4\ubcf4\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://cheese10yun.github.io/spring-transaction/"},"Spring \ub808\ud50c\ub9ac\ucf00\uc774\uc158 \ud2b8\ub79c\uc7ad\uc158 \ucc98\ub9ac \ubc29\uc2dd"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/kwon37xi/replication-datasource"},"replication-datasource"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.linkedin.com/pulse/simplified-guide-mysql-replication-docker-compose-rakesh-shekhawat/"},"Simplified Guide to MySQL Replication with Docker Compose"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.daleseo.com/dockerfile/"},"Dockerfile\uc5d0\uc11c \uc790\uc8fc \uc4f0\uc774\ub294 \uba85\ub839\uc5b4"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.1/en/change-replication-source-to.html"},"CHANGE REPLICATION SOURCE TO Statement"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://kwonnam.pe.kr/wiki/springframework/lazyconnectiondatasourceproxy"},"LazyConnectionDataSourceProxy"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://hudi.blog/database-replication-with-springboot-and-mysql/"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub808\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ud1b5\ud55c \ucffc\ub9ac \uc131\ub2a5 \uac1c\uc120 (feat. Mysql, SpringBoot)"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://chagokx2.tistory.com/100"},"\ubd80\ud558 \ubd84\uc0b0\uc744 \uc704\ud55c MySQL Replication \uad6c\uc131 \ubc0f \ucffc\ub9ac \uc694\uccad \ubd84\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.docker.com/get-started/08_using_compose/"},"Use Docker Compose, Docker")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/92ade856.9c969003.js b/assets/js/92ade856.9c969003.js new file mode 100644 index 000000000..bf1f523e9 --- /dev/null +++ b/assets/js/92ade856.9c969003.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1772],{31824:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var a=r(85893),t=r(3905),i=r(74866),l=r(85162);const s={title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",slug:"db-replication",tags:["mysql","replication"]},c=void 0,o={permalink:"/db-replication",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",source:"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",description:"\ubcf5\uc81c(Replication)",date:"2023-08-22T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 22\uc77c",tags:[{label:"mysql",permalink:"/tags/mysql"},{label:"replication",permalink:"/tags/replication"}],readingTime:21,hasTruncateMarker:!1,authors:[],frontMatter:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",slug:"db-replication",tags:["mysql","replication"]},unlisted:!1,prevItem:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",permalink:"/performance-test-type"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",permalink:"/woowacourse-level3-retrospective"}},u={authorsImageUrls:[]},d=[{value:"\ubcf5\uc81c(Replication)",id:"\ubcf5\uc81creplication",level:2},{value:"\ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720",id:"\ubcf5\uc81c\ub97c-\ud558\ub294-\uc774\uc720",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ud30c\uc77c-\uc704\uce58-\uae30\ubc18-\ubcf5\uc81c",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd\uc758-\ubb38\uc81c\uc810",level:3},{value:"\uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c",id:"\uae00\ub85c\ubc8c-\ud2b8\ub79c\uc7ad\uc158-\uc544\uc774\ub514gtid-\uae30\ubc18-\ubcf5\uc81c",level:3},{value:"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0",id:"\ubcf5\uc81c-\ud1a0\ud3f4\ub85c\uc9c0",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd-replication-\uad6c\uc131\ud558\uae30",level:2},{value:"MySQL \ud658\uacbd \uad6c\uc131",id:"mysql-\ud658\uacbd-\uad6c\uc131",level:3},{value:"\ub3c4\ucee4 \uc2e4\ud589",id:"\ub3c4\ucee4-\uc2e4\ud589",level:3},{value:"replication slave \uad8c\ud55c \uc124\uc815",id:"replication-slave-\uad8c\ud55c-\uc124\uc815",level:3},{value:"SOURCE DB \uc815\ubcf4 \ud655\uc778",id:"source-db-\uc815\ubcf4-\ud655\uc778",level:3},{value:"SOURCE ip \uc8fc\uc18c \ud655\uc778",id:"source-ip-\uc8fc\uc18c-\ud655\uc778",level:3},{value:"replica mysql \uc811\uc18d",id:"replica-mysql-\uc811\uc18d",level:3},{value:"replica \uc124\uc815",id:"replica-\uc124\uc815",level:3},{value:"\uc124\uc815 \ud655\uc778",id:"\uc124\uc815-\ud655\uc778",level:3},{value:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30",id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8\ub85c-db-\uc811\uadfc\ud558\uae30",level:2},{value:"Environment \uc124\uc815",id:"environment-\uc124\uc815",level:3},{value:"DataSourceType \uc124\uc815",id:"datasourcetype-\uc124\uc815",level:3},{value:"AbstractRoutingDataSource \uc124\uc815",id:"abstractroutingdatasource-\uc124\uc815",level:3},{value:"DataSource \uc124\uc815",id:"datasource-\uc124\uc815",level:3},{value:"\ub3d9\uc791 \ud655\uc778",id:"\ub3d9\uc791-\ud655\uc778",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function p(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.ah)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"\ubcf5\uc81creplication",children:"\ubcf5\uc81c(Replication)"}),"\n",(0,a.jsxs)(n.p,{children:["\ud55c \uc11c\ubc84\uc5d0\uc11c \ub2e4\ub978 \uc11c\ubc84\ub85c \ub370\uc774\ud130\ub97c \ub3d9\uae30\ud654\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc6d0\ubcf8 \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Primary \ub610\ub294 Source \ub77c\uace0 \ubd80\ub974\uace0, \ubcf5\uc81c\ub41c \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Secondary \ub610\ub294 Replica \ub77c\uace0 \ubd80\ub978\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\ubcf5\uc81c\ub97c-\ud558\ub294-\uc774\uc720",children:"\ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"1. \uc2a4\ucf00\uc77c \uc544\uc6c3"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc0ac\uc6a9\uc790\uc758 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0, \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uac00\ud574\uc9c0\ub294 \ubd80\ud558\ub3c4 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc99d\uac00\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc774\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud574 \ubcf5\uc81c\ub97c \ud1b5\ud55c \uc2a4\ucf00\uc77c \uc544\uc6c3\uc744 \uc801\uc6a9\ud558\uc5ec \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucffc\ub9ac\ub4e4\uc744 \uac01\uac01\uc758 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub85c \ubd84\uc0b0 \uc2dc\ud0ac \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"2. \ub370\uc774\ud130 \ubc31\uc5c5"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc2e4\uc81c \uc6b4\uc601\ub418\ub294 \uc11c\ube44\uc2a4\uac00 \uc0ac\uc6a9\ud558\uace0 \uc788\ub294 DB\uc5d0\uc11c \ubc31\uc5c5\uc744 \uc9c4\ud589\ud558\ub294 \uacbd\uc6b0, \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc2e4\uc81c \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc774 \uac00\uc9c0 \uc54a\ub3c4\ub85d \ubcf5\uc81c\ub97c \ud1b5\ud574 Replica \uc11c\ubc84\ub97c \uad6c\ucd95\ud558\uc5ec, Replica \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ub97c \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\uc73c\ub85c \uc601\ud5a5\uc744 \ucd5c\uc18c\ud654 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3. \ub370\uc774\ud130 \ubd84\uc11d"})}),"\n",(0,a.jsxs)(n.p,{children:["\ubc31\uc5c5\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc7a1\ud558\uace0 \ubb34\uac70\uc6b4 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\uc758 \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc81c\ub97c \uc0ac\uc6a9\ud574 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ud658\uacbd\uc744 \ub9cc\ub4e4 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"4. \ub370\uc774\ud130\uc758 \uc9c0\ub9ac\uc801 \ubd84\uc0b0"})}),"\n",(0,a.jsx)(n.p,{children:"\ube60\ub978 \uc751\ub2f5\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc11c\ubc84\uc5d0 \uac00\uae5d\uac8c \uc11c\ubc84\ub97c \uad6c\uc131\ud558\uac70\ub098, \uace0\uac00\uc6a9\uc131(High Availability)\uc744 \uc704\ud574\uc11c\ub3c4 \uc0ac\uc6a9\ub41c\ub2e4."}),"\n",(0,a.jsx)(n.h3,{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ud30c\uc77c-\uc704\uce58-\uae30\ubc18-\ubcf5\uc81c",children:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c"}),"\n",(0,a.jsxs)(n.p,{children:["MySQL \uc11c\ubc84\uc5d0\uc11c \ubc1c\uc0dd\ud558\ub294 \ubcc0\uacbd\uc0ac\ud56d\uc5d0 \ub300\ud55c \ub85c\uadf8 \ud30c\uc77c\uc744 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub77c\uace0 \ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ud1b5\ud574 \ub370\uc774\ud130 \ubcc0\uacbd, \ud14c\uc774\ube14 \uad6c\uc870 \ubcc0\uacbd, \uacc4\uc815\uc774\ub098 \uad8c\ud55c \ubcc0\uacbd\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc800\uc7a5\ub41c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","MySQL\uc758 \ubcf5\uc81c\ub294 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 \uc788\ub2e4. \uc774\ub97c Replica \uc11c\ubc84\ub85c \uc804\ub2ec\ud558\uace0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \ub370\uc774\ud130\ub97c \ubcc0\uacbd \uc0ac\ud56d\uc744 \ubc18\uc601\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n\tsubgraph Replica\n\t\tdirection TB\n\t\tIO[Replication I/O thread] -- save --\x3e RL[Relay Log]\n\t\tSQL[Replication SQL Thread] -- read --\x3e RL\n\tend\n\n\tsubgraph Source\n\t\tdirection TB\n\t\tBLD[Binary Log Dump Thread] -- Send Binary Log Dump--\x3e IO\n\tend\n"}),"\n",(0,a.jsx)(n.admonition,{title:"\uc2a4\ub808\ub4dc\ubcc4 \uc5ed\ud560",type:"note",children:(0,a.jsxs)(n.p,{children:["Binary Log Dump Thread: \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc758 \ub0b4\uc6a9\uc744 Replica \uc11c\ubc84\ub85c \uc804\ub2ec",(0,a.jsx)(n.br,{}),"\n","Replication I/O Thread: Binary \ub85c\uadf8 \uc774\ubca4\ud2b8\ub97c \uac00\uc838\uc640 \ub85c\uceec \uc11c\ubc84\uc758 \ud30c\uc77c(Relay Log)\ub85c \uc800\uc7a5",(0,a.jsx)(n.br,{}),"\n","Replication SQL Thread: \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc774\ubca4\ud2b8\ub97c \uc77d\uace0 \uc2e4\ud589"]})}),"\n",(0,a.jsx)(n.h3,{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd\uc758-\ubb38\uc81c\uc810",children:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810"}),"\n",(0,a.jsxs)(n.p,{children:["\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc740 \uc11c\ubc84\uc5d0 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud588\uc744 \ub54c \ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0 \ubcc0\uacbd\uc774 \uae4c\ub2e4\ub86d\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud1a0\ud3f4\ub85c\uc9c0\ub780 \ub124\ud2b8\uc6cc\ud06c\uc758 \uc694\uc18c\ub4e4\uc744 \ubb3c\ub9ac\uc801\uc73c\ub85c \uc5f0\uacb0\ud574 \ub193\uc740 \uac83, \ub610\ub294 \uadf8 \uc5f0\uacb0 \ubc29\uc2dd\uc744 \ub9d0\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph TD\n\tA[A binary-log:300] --\x3e B[B Binary-log:300]\n\tA[A binary-log:300] --\x3e C[C Binary-log:200]"}),"\n",(0,a.jsx)(n.p,{children:"\uc704\uc640 \uac19\uc774 Source \uc11c\ubc84, Replica 2\ub300\uac00 \uc874\uc7ac\ud558\uace0, C \uc11c\ubc84\uc5d0 \ubcf5\uc81c \uc9c0\uc5f0\uc774 \ub418\uc5c8\uc744 \ub54c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.mermaid,{value:"graph TD\n\tA[A binary-log:300]\n\tB[B Binary-log:300] --\x3e C[C Binary-log:200 \ubb38\uc81c \ubc1c\uc0dd]"}),"\n",(0,a.jsxs)(n.p,{children:["A \uc11c\ubc84\uc5d0\uc11c \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 B \uc11c\ubc84\ub97c Source \uc11c\ubc84\ub85c \uc2b9\uaca9\ud558\uace0, C\uc5d0\uac8c \uc870\ud68c \ucffc\ub9ac\ub97c \ubd84\uc0b0\uc2dc\ud0a8\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \uc5ec\uae30\uc11c C \uc11c\ubc84\uc5d0\ub294 A \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\uac00 \uc548\ub418\uc5c8\uc73c\ub2c8 \uc870\ud68c \uc2dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub4a4\ub2a6\uac8c B \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\ub97c \ud558\ub824\uace0 \ud574\ub3c4, \uc5b4\ub5a4 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8, \uc5b4\ub5a4 \uc704\uce58\uc640 \ub3d9\uae30\ud654\ud574\uc57c\ud558\ub294\uc9c0 \uc54c\uae30 \uc5b4\ub835\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\uae00\ub85c\ubc8c-\ud2b8\ub79c\uc7ad\uc158-\uc544\uc774\ub514gtid-\uae30\ubc18-\ubcf5\uc81c",children:"\uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c"}),"\n",(0,a.jsxs)(n.p,{children:["GTID \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ubc1c\uc0dd\ud55c \uc774\ubca4\ud2b8\uc5d0 \uace0\uc720\ud55c \uc2dd\ubcc4\uac12\uc744 \ubd80\uc5ec\ud55c\ub2e4\uba74, \ub3d9\uae30\ud654\uc5d0 \ub300\ud55c \ubb38\uc81c\ub97c \uac04\ub2e8\ud558\uac8c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc704\uc758 \uc608\uc2dc\uc640 \uac19\uc774 \ubcf5\uc81c \uc9c0\uc5f0\uacfc \ud568\uaed8 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\ud574\ub3c4 \ud2b9\uc815 GTID \ubd80\ud130 \ubcf5\uc81c\ub97c \uc7ac\uac1c\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,a.jsx)(n.admonition,{title:"GTID",type:"note",children:(0,a.jsxs)(n.p,{children:["\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0\uc5d0 \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \uc11c\ubc84\uc5d0\uc11c \uace0\uc720\ud558\ub3c4\ub85d \uac01 \uc774\ubca4\ud2b8\uc5d0 \ubd80\uc5ec\ub41c \uc2dd\ubcc4\uac12",(0,a.jsx)(n.br,{}),"\n","[source_id]:[transaction_id]\ub85c \uad6c\uc131\ub418\uba70, source_id\ub294 \uc11c\ubc84\ub97c \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc774\uace0 transaction_id\ub294 \ucee4\ubc0b\ub41c \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc73c\ub85c 1\uc529 \uc99d\uac00\ud558\ub294 \ud615\ud0dc\ub85c \ubc1c\uae09\ub41c\ub2e4."]})}),"\n",(0,a.jsx)(n.h3,{id:"\ubcf5\uc81c-\ud1a0\ud3f4\ub85c\uc9c0",children:"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["\uac00\uc7a5 \uac04\ub2e8\ud55c \uad6c\uc131\uc73c\ub85c \uc81c\uc77c \ub9ce\uc774 \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4.",(0,a.jsx)(n.br,{}),"\n","replica \uc11c\ubc84\ub97c \uc77d\uae30 \uc804\uc6a9, \uc608\ube44 \uc11c\ubc84, \ubc31\uc5c5 \uc6a9\ub3c4\ub85c \ub9ce\uc774 \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R\n S[Source] --\x3e R[Replica]"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\uba40\ud2f0 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["2\uac1c\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud558\ub098\uc758 replica\ub294 \uc608\ube44 \uc6a9\ub3c4\ub85c \ub0a8\uaca8\ub450\ub294 \ud615\ud0dc\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ucd94\ud6c4\uc5d0 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0 \uc608\ube44 \uc6a9\ub3c4\uc758 replica\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c \uc77d\uae30 \uc694\uccad\uc758 \ubd80\ud558 \ubd84\uc0b0\uc744 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R1\n S[Source] --\x3e R1[Replica1]\n S --\x3e R2[Replica2]"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\uccb4\uc778 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["replica \uc11c\ubc84\uac00 \ub9ce\uc740 \uacbd\uc6b0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \uc804\ub2ec\ud558\ub294 \uc791\uc5c5 \uc790\uccb4\uac00 \ubd80\ud558\uac00 \ub420 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c 1:M",":M"," \uad6c\uc870\ub85c \uccb4\uc778 \ubcf5\uc81c \uad6c\uc131\uc744 \uace0\ub824\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R1\n S[Source] --\x3e R1[Replica1]\n S --\x3e R2[Replica2]\n S --\x3e R3[Replica3]\n\n R3 --\x3e R3-1[Replica 3-1]\n R3 --\x3e R3-2[Replica 3-2]\n\n B[Batch Server] --\x3e R3-2"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\ub4c0\uc5bc \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["2\uac1c\uc758 MySQL \uc11c\ubc84 \ubaa8\ub450 \uc77d\uae30\uc640 \uc4f0\uae30\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d \ud558\ub294 \uad6c\uc131\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uac01 \uc11c\ubc84\uc5d0\uc11c \ubcc0\uacbd\ub41c \ub370\uc774\ud130\ub294 \ub2e4\ub978 \uc11c\ubc84\uc5d0 \ubc18\uc601\ub41c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ubaa9\uc801\uc5d0 \ub530\ub77c ACTIVE-ACTIVE \ud615\ud0dc \ub610\ub294 ACTIVE-PASSIVE \ud615\ud0dc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","ACTIVE-PASSIVE \ud615\ud0dc\uc778 \uacbd\uc6b0 \uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131\uacfc \ub3d9\uc77c\ud574\ubcf4\uc774\uc9c0\ub9cc, ACTIVE \uc11c\ubc84\uc5d0\uc11c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uba74 \uc124\uc815\uc758 \ubcc0\uacbd\uc5c6\uc774 PASSIVE \uc11c\ubc84\ub85c \uc4f0\uae30 \uc791\uc5c5\uc744 \uc804\ud658\ud560 \uc218 \uc788\ub2e4\ub294 \uac83\uc774 \uc7a5\uc810\uc774\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR1\n W -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR2\n SR1[Source/Replica 1] --\x3e SR2[Source/Replica 2]"}),"\n",(0,a.jsx)(n.admonition,{title:"ACTIVE-ACTIVE, ACTIVE-PASSIVE",type:"note",children:(0,a.jsxs)(n.p,{children:["ACTIVE-ACTIVE: 2\uac1c\uc758 \uc11c\ubc84 \ubaa8\ub450 \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc",(0,a.jsx)(n.br,{}),"\n","ACTIVE-PASSIVE: \ud558\ub098\uc758 \uc11c\ubc84\uc5d0\uc11c\ub9cc \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc"]})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\uba40\ud2f0 \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc5ec\ub7ec\uac1c\uc758 source \uc11c\ubc84\uc640 \ud558\ub098\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \uad6c\uc131\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc774\ub294 source \uc11c\ubc84\uc758 \ub370\uc774\ud130\ub97c \ud55c \uacf3\uc5d0 \ubc31\uc5c5\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9, \uc5ec\ub7ec \uc11c\ubc84\uc5d0 \uc874\uc7ac\ud558\ub294 \ub370\uc774\ud130\ub97c \ud1b5\ud569, \uc0e4\ub529\ub418\uc5b4\uc788\ub294 \ud14c\uc774\ube14 \ub370\uc774\ud130\ub97c \ud1b5\ud569\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n S1[Source 1] --\x3e R[Replica]\n S2[Source 2] --\x3e R"}),"\n",(0,a.jsx)(n.h2,{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd-replication-\uad6c\uc131\ud558\uae30",children:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30"}),"\n",(0,a.jsxs)(n.p,{children:["mysql 2\ub300\ub97c \uc774\uc6a9\ud558\uc5ec replication\uc744 \uad6c\uc131\ud558\uace0, spring boot application\uc73c\ub85c source, replica \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc811\uadfc\ud574\ubcf4\ub294 \uc608\uc81c\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://github.com/bbiac/db-replication",children:"https://github.com/bbiac/db-replication"})]}),"\n",(0,a.jsx)(n.h3,{id:"mysql-\ud658\uacbd-\uad6c\uc131",children:"MySQL \ud658\uacbd \uad6c\uc131"}),"\n",(0,a.jsxs)(n.p,{children:["MySQL \ubc84\uc804\uc740 8.1\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","13306, 13307 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud574\uc11c MySQL \uc11c\ubc84 2\ub300\ub97c \ub744\uc6e0\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub610\ud55c \uc0ac\uc2e4 IP \ub300\uc5ed\uc73c\ub85c \ud1b5\uc2e0\ud560 \uc218 \uc788\ub3c4\ub85d \ucee4\uc2a4\ud140 \ub124\ud2b8\uc6cc\ud06c\ub97c \ucd94\uac00\ud588\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yml",children:"version: '3.8'\n\nservices:\n source:\n platform: linux/x86_64\n image: mysql:latest\n restart: always\n container_name: mysql-source\n environment:\n TZ: 'Asia/Seoul'\n MYSQL_DATABASE: 'db'\n MYSQL_USER: 'user'\n MYSQL_PASSWORD: 'password'\n MYSQL_ROOT_PASSWORD: 'password'\n ports:\n - \"13306:3306\"\n volumes:\n - db-source:/var/lib/mysql\n - db-source:/var/lib/mysql-files\n - ./docker/source.cnf:/etc/mysql/my.cnf\n networks:\n - mysql_network\n\n replica:\n platform: linux/x86_64\n image: mysql:latest\n restart: always\n container_name: mysql-replica\n environment:\n TZ: 'Asia/Seoul'\n MYSQL_DATABASE: 'db'\n MYSQL_USER: 'user'\n MYSQL_PASSWORD: 'password'\n MYSQL_ROOT_PASSWORD: 'password'\n ports:\n - \"13307:3306\"\n volumes:\n - db-replica:/var/lib/mysql\n - db-replica:/var/lib/mysql-files\n - ./docker/replica.cnf:/etc/mysql/my.cnf\n networks:\n - mysql_network\n\nvolumes:\n db-source:\n db-replica:\n\nnetworks:\n mysql_network:\n driver: bridge\n"})}),"\n",(0,a.jsx)(n.p,{children:"\ub610\ud55c source, replica \uac01\uac01 \ub2e4\uc74c\uacfc \uac19\uc774 db \uc124\uc815\uc744 \ud588\ub2e4."}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"\uc124\uc815"}),(0,a.jsx)(n.th,{children:"\uc124\uba85"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"server_id"}),(0,a.jsx)(n.td,{children:"\uac01\uac01\uc758 mysql \ub9c8\ub2e4 \uace0\uc720\ud55c \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"log_bin"}),(0,a.jsx)(n.td,{children:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815\uc73c\ub85c \uc808\ub300\uacbd\ub85c\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 /var/lib/mysql \uc544\ub798 \ud574\ub2f9 log_bin\uc5d0 \uc124\uc815\ub41c \uac12\uc73c\ub85c \ub85c\uadf8\uac00 \uc0dd\uc131\ub41c\ub2e4."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"sync_binlog"}),(0,a.jsx)(n.td,{children:"N\uac1c\uc758 \ud2b8\ub79c\uc7ad\uc158 \ub2f9 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ub514\uc2a4\ud06c\uc640 \ub3d9\uae30\ud654 \uc791\uc5c5\uc744 \ud558\ub3c4\ub85d \ud55c\ub2e4.\xa01\uc740 \uae30\ubcf8\uac12\uc73c\ub85c \uc548\uc815\uc801\uc774\uc9c0\ub9cc, \uac00\uc7a5 \ub290\ub9ac\ub2e4."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"relay_log"}),(0,a.jsx)(n.td,{children:"\ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"relay_log_purge"}),(0,a.jsx)(n.td,{children:"\ud544\uc694 \uc5c6\ub294 \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc744 \uc790\ub3d9\uc73c\ub85c \uc0ad\uc81c\ud558\ub294 \uc635\uc158"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"read_only"}),(0,a.jsx)(n.td,{children:"\uc77d\uae30 \uc804\uc6a9 \uc124\uc815"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"log_replica_updates"}),(0,a.jsx)(n.td,{children:"Replication SQL Thread\ub85c \uc778\ud574 \uc2e4\ud589\ub418\ub294 \uc815\ubcf4\ub97c \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc5d0 \uae30\ub85d \ucd94\ud6c4\uc5d0 \uc18c\uc2a4 \uc11c\ubc84\ub85c \uc2b9\uaca9\ub418\ub294 \uacbd\uc6b0\ub97c \uace0\ub824\ud558\uba74 \uc124\uc815\ud558\ub294 \uac83\uc774 \uc88b\ub2e4."})]})]})]}),"\n","\n","\n",(0,a.jsxs)(i.Z,{children:[(0,a.jsx)(l.Z,{value:"Source",label:"Source",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-cnf",metastring:'title="/docker/source.cnf"',children:"[mysqld]\nserver_id=1\nlog_bin=mysql-bin\nsync_binlog=1\n"})})}),(0,a.jsx)(l.Z,{value:"Replica",label:"Replica",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-cnf",metastring:'title="/docker/replica.cnf"',children:"[mysqld]\nserver_id=2\nrelay_log=mysql-relay-bin\nrelay_log_purge=ON\nread_only\nlog_replica_updates\n"})})})]}),"\n",(0,a.jsx)(n.h3,{id:"\ub3c4\ucee4-\uc2e4\ud589",children:"\ub3c4\ucee4 \uc2e4\ud589"}),"\n",(0,a.jsxs)(n.p,{children:["docker-compose up \uba85\ub839\uc5b4\ub85c docker-compose \uc124\uc815\uc73c\ub85c docker\ub97c \ub744\uc6b4\ub2e4.",(0,a.jsx)(n.br,{}),"\n","-d \uc635\uc158\uc744 \ubd99\uc774\uba74 \ubc31\uadf8\ub77c\uc6b4\ub4dc \ubaa8\ub4dc\ub85c \uc2e4\ud589\ub41c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"docker-compose up -d\n"})}),"\n",(0,a.jsx)(n.h3,{id:"replication-slave-\uad8c\ud55c-\uc124\uc815",children:"replication slave \uad8c\ud55c \uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["REPLICATION SLAVE \uad8c\ud55c\uc774 \uc124\uc815\ub418\uc5b4 \uc788\uc5b4\uc57c replica \uc11c\ubc84\uc5d0\uc11c source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec \ub85c\uadf8\ub97c \uc77d\uc5b4\uc62c \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec user \uacc4\uc815\uc5d0 \ud574\ub2f9 \uad8c\ud55c\uc744 \uc124\uc815\ud574\uc900\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:"SOURCE \uc811\uc18d"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"docker exec -it mysql-source mysql -u root -p\n"})}),"\n",(0,a.jsx)(n.p,{children:"user \uacc4\uc815\uc5d0 REPLICATION SLAVE \uad8c\ud55c \ucd94\uac00"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-mysql",children:"GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';\nFLUSH PRIVILEGES;\n"})}),"\n",(0,a.jsx)(n.h3,{id:"source-db-\uc815\ubcf4-\ud655\uc778",children:"SOURCE DB \uc815\ubcf4 \ud655\uc778"}),"\n",(0,a.jsxs)(n.p,{children:["replica \uc124\uc815\uc5d0 \ud544\uc694\ud55c source db\uc758 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c\uba85\uacfc Position\uc744 \ud655\uc778\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","Position \uac12\uc740 \uc2e4\uc81c \ud30c\uc77c\uc758 \ubc14\uc774\ud2b8 \uc218\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud655\uc778\ud55c File(SOURCE_LOG_FILE)\uacfc Position(SOURCE_LOG_POS) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-mysql",children:"SHOW MASTER STATUS;\n\n+------------------+----------+--------------+------------------+-------------------+\n| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\n+------------------+----------+--------------+------------------+-------------------+\n| mysql-bin.000003 | 1082 | | | |\n+------------------+----------+--------------+------------------+-------------------+\n"})}),"\n",(0,a.jsx)(n.h3,{id:"source-ip-\uc8fc\uc18c-\ud655\uc778",children:"SOURCE ip \uc8fc\uc18c \ud655\uc778"}),"\n",(0,a.jsxs)(n.p,{children:["docker inspect -f \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uba74 \ud574\ub2f9 \ucee8\ud14c\uc774\ub108\uc758 \uc138\ubd80 \uc815\ubcf4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud574 docker-compose \ud30c\uc77c\uc5d0 \uc124\uc815\ud574\ub454 mysql_network\uc5d0\uc11c \uc0ac\uc6a9\ub418\ub294 \uc0ac\uc124 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \ud655\uc778\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'docker inspect -f "{{with index .NetworkSettings.Networks \\"db-replication_mysql_network\\"}}{{.IPAddress}}{{end}}" mysql-source\n'})}),"\n",(0,a.jsxs)(n.p,{children:["ip \uc8fc\uc18c\uac00 \ub098\uc624\uc9c0 \uc54a\ub294 \uacbd\uc6b0 docker inspect mysql-source\ub85c \ud655\uc778\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud655\uc778\ud55c IP\uc8fc\uc18c(SOURCE_HOST) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"replica-mysql-\uc811\uc18d",children:"replica mysql \uc811\uc18d"}),"\n",(0,a.jsx)(n.p,{children:"source db\uc5d0 \uc811\uc18d\ud588\ub358 \ubc29\ubc95\uacfc \ub3d9\uc77c\ud558\uac8c replica db\uc5d0 \uc811\uc18d\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"docker exec -it mysql-replica mysql -u root -p\n"})}),"\n",(0,a.jsx)(n.h3,{id:"replica-\uc124\uc815",children:"replica \uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["\uc774\uc804\uc5d0 source db\uc5d0\uc11c \uc5bb\uc5c8\ub358 \uc815\ubcf4\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc5ec replica \uc124\uc815\uc744 \uc9c4\ud589\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc2e4\uc81c DB \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc73c\ub85c source DB\uc758 \ud30c\uc77c\uc744 \ubcf5\uc81c\ud574\uc57c\ud558\uc9c0\ub9cc \ud604\uc7ac \ubcf5\uc81c\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ubd80\ubd84\uc740 \uc0dd\ub7b5\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS \ub97c \uc801\uc808\ud788 \ubcc0\uacbd\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-mysql",children:"STOP REPLICA;\n\nCHANGE REPLICATION SOURCE TO \nSOURCE_HOST='172.29.0.2', \nSOURCE_USER='user', \nSOURCE_PASSWORD='password', \nSOURCE_LOG_FILE='mysql-bin.000001', \nSOURCE_LOG_POS=0, \nGET_SOURCE_PUBLIC_KEY=1;\n\nSTART REPLICA;\n"})}),"\n",(0,a.jsx)(n.h3,{id:"\uc124\uc815-\ud655\uc778",children:"\uc124\uc815 \ud655\uc778"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-mysql",children:"SHOW REPLICA STATUS;\n\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n"})}),"\n",(0,a.jsx)(n.p,{children:"Replica_IO_Running, Replica_SQL_Running \uac12\uc774 YES\ub77c\uba74 \uc815\uc0c1\uc801\uc73c\ub85c replication \uad6c\uc131\uc774 \uc644\ub8cc\ub41c \uac83\uc774\ub2e4."}),"\n",(0,a.jsxs)(n.p,{children:["\uc124\uc815\uc744 \ub9c8\uce5c \ud6c4 source db\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 create table \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","replica db\uc5d0 \ub3d9\uc77c\ud55c member table\uc774 \uc0dd\uc131\ub41c \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:"CREATE TABLE member\n(\n id BIGINT PRIMARY KEY AUTO_INCREMENT,\n name VARCHAR(255)\n);\n"})}),"\n",(0,a.jsx)(n.h2,{id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8\ub85c-db-\uc811\uadfc\ud558\uae30",children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30"}),"\n",(0,a.jsx)(n.p,{children:"\uc77c\ubc18\uc801\uc778 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 source, \uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158\uc778 \uacbd\uc6b0 replica\ub85c \uc694\uccad\uc774 \uac00\ub3c4\ub85d \uad6c\uc131\ud574\ubcf4\uc790."}),"\n",(0,a.jsx)(n.h3,{id:"environment-\uc124\uc815",children:"Environment \uc124\uc815"}),"\n",(0,a.jsx)(n.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 source, replica\ub85c \uad6c\ubd84\ud558\uc5ec \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yml",metastring:'title="application.yml"',children:"spring:\n datasource:\n source:\n username: user\n password: password\n driver-class-name: com.mysql.cj.jdbc.Driver\n jdbc-url: jdbc:mysql://localhost:13306/db\n replica:\n username: user\n password: password\n driver-class-name: com.mysql.cj.jdbc.Driver\n jdbc-url: jdbc:mysql://localhost:13307/db\n"})}),"\n",(0,a.jsx)(n.h3,{id:"datasourcetype-\uc124\uc815",children:"DataSourceType \uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["\ub2e8\uc21c \ubb38\uc790\uc5f4\ub85c\ub3c4 \uad6c\ubd84\ud560 \uc218 \uc788\uc9c0\ub9cc, enum\uc744 \uc774\uc6a9\ud574\uc11c \ud2b8\ub79c\uc7ad\uc158\uc744 \uad6c\ubd84\ud558\ub3c4\ub85d \uc0dd\uc131\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","Key\ub294 \ucd94\ud6c4\uc5d0 \ube48 \uc124\uc815\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-java",metastring:'title="DataSourceType"',children:'public enum DataSourceType {\n SOURCE(SOURCE_NAME),\n REPLICA(REPLICA_NAME),\n ;\n\n private final String key;\n\n DataSourceType(String key) {\n this.key = key;\n }\n\n public static class Key {\n public static final String ROUTING_NAME = "ROUTING";\n public static final String SOURCE_NAME = "SOURCE";\n public static final String REPLICA_NAME = "REPLICA";\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"abstractroutingdatasource-\uc124\uc815",children:"AbstractRoutingDataSource \uc124\uc815"}),"\n",(0,a.jsx)(n.p,{children:"\uc2a4\ud504\ub9c1\uc774 \uc9c0\uc6d0\ud574\uc8fc\ub294 AbstractRoutingDataSource\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSource\ub97c \ud5a5\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsxs)(n.p,{children:["\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub294 ",(0,a.jsx)(n.code,{children:"Map<DataSourceKey, DataSource>"}),"\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\uc744 \ubc1b\uc544 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"setDefaultTargetDataSource: \uae30\ubcf8 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.li,{children:"setTargetDataSources: \ub9f5 \ud615\ud0dc\ub85c \ubc1b\uc740 \ub370\uc774\ud130 \uc18c\uc2a4 \uac12\ub4e4\uc744 \uc124\uc815\ud55c\ub2e4."}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"determineCurrentLookupKey\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \ud2b8\ub79c\uc7ad\uc158\uc774 \uc77d\uae30 \uc804\uc6a9\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(n.li,{children:"DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uace0, \ubc18\ud658\ud55c \uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ub370\uc774\ud130 \uc18c\uc2a4\uac00 \uc0ac\uc6a9\ub41c\ub2e4."}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-java",metastring:'title="RoutingDataSource"',children:'public class RoutingDataSource extends AbstractRoutingDataSource {\n\n private final Logger log = LoggerFactory.getLogger(getClass());\n\n public static RoutingDataSource from(Map<Object, Object> dataSources) {\n RoutingDataSource routingDataSource = new RoutingDataSource();\n routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));\n routingDataSource.setTargetDataSources(dataSources);\n return routingDataSource;\n }\n\n @Override\n protected Object determineCurrentLookupKey() {\n boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();\n\n if (readOnly) {\n log.info("readOnly = true, request to replica");\n return DataSourceType.REPLICA;\n }\n log.info("readOnly = false, request to source");\n return DataSourceType.SOURCE;\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"datasource-\uc124\uc815",children:"DataSource \uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["\uc704\uc5d0\uc11c\ubd80\ud130 \uc21c\uc11c\ub300\ub85c Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy \uc124\uc815\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc2a4\ud504\ub9c1\uc740 \ud2b8\ub79c\uc7ad\uc158 \uc2dc\uc791\uc2dc\uc5d0 \ucee4\ub125\uc158\uc758 \uc0ac\uc6a9\uc5ec\ubd80\uc640 \uc0c1\uad00\uc5c6\uc774 \ucee4\ub125\uc158\uc744 \ud655\ubcf4\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c readOnly \ud2b8\ub79c\uc7ad\uc158\uc774 \uc124\uc815\ub41c \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ubbf8\ub9ac \ud655\ubcf4\ub41c \ucee4\ub125\uc158\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 replica db\ub85c \uc694\uccad\uc744 \ud558\uc9c0 \uc54a\uace0 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4."]}),"\n",(0,a.jsxs)(n.p,{children:["TransactionSynchronizationManager.isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc \ud638\ucd9c \uc2dc currentTransactionReadOnly\ub77c\ub294 ",(0,a.jsx)(n.code,{children:"ThreadLocal<Boolean>"}),"\uc5d0 \uc124\uc815\ub41c \uac12\uc744 \ubc18\ud658\ud558\ub294\ub370 readOnly \uc124\uc815\uc774 \ub418\uba74 \uc774 \uac12\uc744 true\ub85c \uc124\uc815\ud55c\ub2e4. \ud558\uc9c0\ub9cc determineCurrentLookupKey\ub97c \ud638\ucd9c\ud558\uc5ec key \uac12\uc744 \uac00\uc838\uc624\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc774\ud6c4\uc5d0 \uc124\uc815\ub418\uae30 \ub54c\ubb38\uc5d0 determineCurrentLookupKey \uba54\uc11c\ub4dc\uc5d0\uc11c \ud56d\uc0c1 DataSourceType.SOURCE\uac00 \ubc18\ud658\ub418\uc5b4 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:"LazyConnectionDataSourceProxy\ub97c \uc124\uc815\ud558\ub294 \uacbd\uc6b0 \uc2e4\uc81c DataSource\ub97c \uc0ac\uc6a9\ud558\ub294 \uc2dc\uc810\uc5d0 \ucee4\ub125\uc158\uc744 \ud68d\ub4dd\ud574\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc124\uc815\ud55c\ub300\ub85c replica db\ub85c \uc870\ud68c \uc694\uccad\uc744 \ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-java",metastring:'title="DataSourceConfiguration"',children:'@Configuration\npublic class DataSourceConfiguration {\n\n @Bean\n @Qualifier(SOURCE_NAME)\n @ConfigurationProperties(prefix = "spring.datasource.source")\n public DataSource sourceDataSource() {\n return DataSourceBuilder.create().build();\n }\n\n @Bean\n @Qualifier(REPLICA_NAME)\n @ConfigurationProperties(prefix = "spring.datasource.replica")\n public DataSource replicaDataSource() {\n return DataSourceBuilder.create().build();\n }\n\n @Bean\n @Qualifier(ROUTING_NAME)\n public DataSource routingDataSource(\n @Qualifier(SOURCE_NAME) DataSource sourceDataSource,\n @Qualifier(REPLICA_NAME) DataSource replicaDataSource\n ) {\n return RoutingDataSource.from(Map.of(\n DataSourceType.SOURCE, sourceDataSource,\n DataSourceType.REPLICA, replicaDataSource\n ));\n }\n\n @Bean\n @Primary\n public DataSource dataSource(\n @Qualifier(ROUTING_NAME) DataSource routingDataSource\n ) {\n return new LazyConnectionDataSourceProxy(routingDataSource);\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"\ucd5c\uc885\uc801\uc73c\ub85c DataSource \ube48\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\uac00 \ub41c\ub2e4."}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n DSP[LazyConnectionDataSourceProxy] --\x3e RDS[RoutingDataSource]\n\tRDS --\x3e S[SourceDataSource]\n\tRDS --\x3e R[ReplicaDataSource]"}),"\n",(0,a.jsx)(n.h3,{id:"\ub3d9\uc791-\ud655\uc778",children:"\ub3d9\uc791 \ud655\uc778"}),"\n",(0,a.jsxs)(n.p,{children:["\uac04\ub2e8\ud558\uac8c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud574\uc11c \uc124\uc815\ud55c\ub300\ub85c \ub3d9\uc791\uc774 \ub418\ub294\uc9c0 \ud655\uc778\ud574\ubcf4\uc558\ub2e4.",(0,a.jsx)(n.br,{}),"\n","save \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 ",(0,a.jsx)(n.code,{children:"@Transactional"}),", findById \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 ",(0,a.jsx)(n.code,{children:"@Transactional(readOnly = true)"}),"\uac00 \uc124\uc815\ub418\uc5b4\uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub85c\uadf8\ub97c \ud1b5\ud574 save\uc758 \uacbd\uc6b0 source db\ub85c findById\uc758 \uacbd\uc6b0 replica db\ub85c \uc694\uccad\uc744 \ud558\ub294 \uac83\uc744 \uc54c \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-java",metastring:'title="MemberServiceTest"',children:'@SpringBootTest\nclass MemberServiceTest {\n\n @Autowired\n private MemberService memberService;\n\n @Test\n void \uc0ac\uc6a9\uc790\ub97c_\uc800\uc7a5\ud55c\ub2e4() {\n // RoutingDataSource log: readOnly = false\n memberService.save("bbiac");\n }\n\n @Test\n void \uc0ac\uc6a9\uc790\ub97c_\uc870\ud68c\ud55c\ub2e4() {\n // RoutingDataSource log: readOnly = true\n assertThatThrownBy(() -> memberService.findById(MAX_VALUE))\n .isInstanceOf(NoSuchElementException.class);\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"DB\uc5d0\uc11c\ub294 \ud655\uc778\ud558\ub824\uba74 root \uacc4\uc815\uc73c\ub85c \uc811\uc18d\ud55c \ud6c4 general log\ub97c \ud65c\uc131\ud654 \uc2dc\ud0a8\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:"SET GLOBAL log_output = 'table';\nSET GLOBAL general_log = 1;\n"})}),"\n",(0,a.jsxs)(n.p,{children:["general log\ub97c \ud65c\uc131\ud654 \ud55c \ud6c4 \uc77d\uae30 \uc804\uc6a9 \uba54\uc11c\ub4dc\ub97c \uc2e4\ud589\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","server_id, \uc2e4\ud589\ud55c \ucffc\ub9ac\ubb38\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:"SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';\n\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n| user_host | thread_id | server_id | convert(argument using utf8) |\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n"})}),"\n",(0,a.jsx)(n.p,{children:"\ud655\uc778 \ud6c4 general log\ub97c \ube44\ud65c\uc131\ud654 \ud55c \ud6c4 \ube44\ud65c\uc131\ud654 \ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:"SET GLOBAL general_log = 0;\nSHOW VARIABLES LIKE '%general%';\n\n+------------------+---------------------------------+\n| Variable_name | Value |\n+------------------+---------------------------------+\n| general_log | OFF |\n| general_log_file | /var/lib/mysql/4b6b9db98290.log |\n+------------------+---------------------------------+\n"})}),"\n",(0,a.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,a.jsxs)(n.p,{children:["16\uc7a5 \ubcf5\uc81c, Real MySQL 8.0 - \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.1/en/replication.html",children:"Replication, MySQL Docs"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://huisam.tistory.com/entry/mysql-replication",children:"MySql - Master Slave Replication \uad6c\uc870 \ub9cc\ub4e4\uc5b4\ubcf4\uae30"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://cheese10yun.github.io/spring-transaction/",children:"Spring \ub808\ud50c\ub9ac\ucf00\uc774\uc158 \ud2b8\ub79c\uc7ad\uc158 \ucc98\ub9ac \ubc29\uc2dd"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://github.com/kwon37xi/replication-datasource",children:"replication-datasource"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://www.linkedin.com/pulse/simplified-guide-mysql-replication-docker-compose-rakesh-shekhawat/",children:"Simplified Guide to MySQL Replication with Docker Compose"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://www.daleseo.com/dockerfile/",children:"Dockerfile\uc5d0\uc11c \uc790\uc8fc \uc4f0\uc774\ub294 \uba85\ub839\uc5b4"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.1/en/change-replication-source-to.html",children:"CHANGE REPLICATION SOURCE TO Statement"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://kwonnam.pe.kr/wiki/springframework/lazyconnectiondatasourceproxy",children:"LazyConnectionDataSourceProxy"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://hudi.blog/database-replication-with-springboot-and-mysql/",children:"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub808\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ud1b5\ud55c \ucffc\ub9ac \uc131\ub2a5 \uac1c\uc120 (feat. Mysql, SpringBoot)"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://chagokx2.tistory.com/100",children:"\ubd80\ud558 \ubd84\uc0b0\uc744 \uc704\ud55c MySQL Replication \uad6c\uc131 \ubc0f \ucffc\ub9ac \uc694\uccad \ubd84\uae30"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://docs.docker.com/get-started/08_using_compose/",children:"Use Docker Compose, Docker"})]})]})}function h(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>o});var a=r(67294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,a)}return r}function l(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){t(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function s(e,n){if(null==e)return{};var r,a,t=function(e,n){if(null==e)return{};var r,a,t={},i=Object.keys(e);for(a=0;a<i.length;a++)r=i[a],n.indexOf(r)>=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)r=i[a],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var c=a.createContext({}),o=function(e){var n=a.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):l(l({},n),e)),r},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var r=e.components,t=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=o(r),h=t,S=p["".concat(c,".").concat(h)]||p[h]||u[h]||i;return r?a.createElement(S,l(l({ref:n},d),{},{components:r})):a.createElement(S,l({ref:n},d))}));d.displayName="MDXCreateElement"},85162:(e,n,r)=>{r.d(n,{Z:()=>l});r(67294);var a=r(86010);const t={tabItem:"tabItem_Ymn6"};var i=r(85893);function l(e){let{children:n,hidden:r,className:l}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,a.Z)(t.tabItem,l),hidden:r,children:n})}},74866:(e,n,r)=>{r.d(n,{Z:()=>R});var a=r(67294),t=r(86010),i=r(12466),l=r(16550),s=r(20469),c=r(91980),o=r(67392),u=r(50012);function d(e){return a.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:r}=e;return(0,a.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:r,attributes:a,default:t}}=e;return{value:n,label:r,attributes:a,default:t}}))}(r);return function(e){const n=(0,o.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function h(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function S(e){let{queryString:n=!1,groupId:r}=e;const t=(0,l.k6)(),i=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,c._X)(i),(0,a.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})}),[i,t])]}function x(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,i=p(e),[l,c]=(0,a.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!h({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const a=r.find((e=>e.default))??r[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:i}))),[o,d]=S({queryString:r,groupId:t}),[x,m]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,i]=(0,u.Nk)(r);return[t,(0,a.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:t}),b=(()=>{const e=o??x;return h({value:e,tabValues:i})?e:null})();(0,s.Z)((()=>{b&&c(b)}),[b]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!h({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);c(e),d(e),m(e)}),[d,m,i]),tabValues:i}}var m=r(72389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var j=r(85893);function g(e){let{className:n,block:r,selectedValue:a,selectValue:l,tabValues:s}=e;const c=[],{blockElementScrollPositionUntilNextRender:o}=(0,i.o5)(),u=e=>{const n=e.currentTarget,r=c.indexOf(n),t=s[r].value;t!==a&&(o(n),l(t))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;n=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;n=c[r]??c[c.length-1];break}}n?.focus()};return(0,j.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.Z)("tabs",{"tabs--block":r},n),children:s.map((e=>{let{value:n,label:r,attributes:i}=e;return(0,j.jsx)("li",{role:"tab",tabIndex:a===n?0:-1,"aria-selected":a===n,ref:e=>c.push(e),onKeyDown:d,onClick:u,...i,className:(0,t.Z)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":a===n}),children:r??n},n)}))})}function _(e){let{lazy:n,children:r,selectedValue:t}=e;const i=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===t));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return(0,j.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,a.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function y(e){const n=x(e);return(0,j.jsxs)("div",{className:(0,t.Z)("tabs-container",b.tabList),children:[(0,j.jsx)(g,{...e,...n}),(0,j.jsx)(_,{...e,...n})]})}function R(e){const n=(0,m.Z)();return(0,j.jsx)(y,{...e,children:d(e.children)},String(n))}}}]); \ No newline at end of file diff --git a/assets/js/92fef07b.c8b2c292.js b/assets/js/92fef07b.c8b2c292.js deleted file mode 100644 index 266933d13..000000000 --- a/assets/js/92fef07b.c8b2c292.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[300],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>k});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},s=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),s=c(r),k=a,g=s["".concat(i,".").concat(k)]||s[k]||m[k]||p;return r?n.createElement(g,l(l({ref:t},u),{},{components:r})):n.createElement(g,l({ref:t},u))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=s;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var c=2;c<p;c++)l[c]=r[c];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}s.displayName="MDXCreateElement"},21474:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>m,frontMatter:()=>p,metadata:()=>o,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",slug:"racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,o={permalink:"/racing-car-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-racingcar/pull/510",date:"2023-02-14T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 14\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.625,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",slug:"racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",permalink:"/ladder-retrospective"},nextItem:{title:"Parameterized Tests",permalink:"/parameterized-tests"}},i={authorsImageUrls:[]},c=[{value:"\uc790\ub3d9\ucc28 \uacbd\uc8fc",id:"\uc790\ub3d9\ucc28-\uacbd\uc8fc",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],u={toc:c};function m(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-racingcar/pull/510"},"https://github.com/woowacourse/java-racingcar/pull/510"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-racingcar/pull/538"},"https://github.com/woowacourse/java-racingcar/pull/538")," ")),(0,a.kt)("h3",{id:"\uc790\ub3d9\ucc28-\uacbd\uc8fc"},"\uc790\ub3d9\ucc28 \uacbd\uc8fc"),(0,a.kt)("p",null,"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158\uc5d0\uc11c\ub294 \ub2e4\uc990\uacfc \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ud14c\ucf54 \ub4e4\uc5b4\uc640\uc11c \uccab \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\uc774\ub77c \ub9ce\uc774 \ub5a8\ub838\uc9c0\ub9cc, \ub2e4\uc990\uc774 \ub300\ud654\ub97c \uc798 \uc774\ub04c\uc5b4\uc918 \ub108\ubb34 \uc990\uac70\uc6e0\ub2e4. "),(0,a.kt)("p",null,"\uccab\ub0a0\uc740 \uac04\ub2e8\ud788 \ucee8\ubca4\uc158\uacfc \ud658\uacbd\uc744 \uc124\uc815\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc84c\uace0 \ub2e4\uc74c \ub0a0\ubd80\ud130 \uc790\ub3d9\ucc28 \uacbd\uc8fc\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2dc\uc791\uc740 \uac04\ub2e8\ud558\uac8c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud558\uace0, \uc5b4\ub5bb\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud560\uc9c0 \uac19\uc774 \uace0\ubbfc\ud588\ub2e4. "),(0,a.kt)("p",null,"\uc2dc\uc791\ud558\uae30 \uc804 \uc544\ub798\uc640 \uac19\uc774 mermaid\ub97c \uc774\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc5d0 \ub300\ud574\uc11c \uac04\ub2e8\ud55c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uace0 \uc2dc\uc791\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","mermaid\ub294 \ucf54\ub4dc\ub85c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \uc0dd\uc131 \ud574\uc8fc\ub294 \ub3c4\uad6c\ub85c \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc774 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\ucf54\ub4dc \uae30\ubc18\uc774\ub77c \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \uc0dd\uac01\ud55c \uac83\uc744 \uc2dc\uac01\ud654\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("li",{parentName:"ul"},"github\uc5d0\uc11c mermaid\ub97c \uc9c0\uc6d0\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \ucf54\ub4dc\ub97c \uc774\ud574\ud560 \uc218 \uc788\ub294 \ubd80\uac00\uc801\uc778 \uc815\ubcf4\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.")),(0,a.kt)("mermaid",{value:"---\ntitle: \uc790\ub3d9\ucc28 \uacbd\uc8fc \uccab \ub9ac\ubdf0 \uc694\uccad\uc2dc \uad6c\uc870\n---\ngraph TD\n Cars --\x3e Car\n Car --\x3e Name\n Car --\x3e Position\n RacingGame --\x3e Count\n RacingGame --\x3e NumberGenerator\n RacingGame --\x3e Cars\n RacingCarController --\x3e RacingGame\n RandomNumberGenerator -.-> NumberGenerator\n RacingCarController --\x3e InputView\n InputView --\x3e InputValidator\n RacingCarController --\x3e OutputView"}),(0,a.kt)("p",null,"\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \ub370 \ud070 \uc5b4\ub824\uc6c0\uc774 \uc788\uc9c0\ub294 \uc54a\uc558\uace0, \ud398\uc5b4\ub97c \ub9c8\uce58\uae30 \uc804 \uc11c\ub85c \uace0\ubbfc\ub418\ub294 \ubd80\ubd84\uc744 \uc815\ub9ac\ud588\uc744 \ub54c \uc88b\uc558\ub2e4."),(0,a.kt)("p",null,"\ud398\uc5b4\ud558\uba74\uc11c \uc798\ud588\ub2e4\uace0 \uc0dd\uac01\ud588\ub358 \uc810\uc740 \uc11c\ub85c\uc758 \uc0dd\uac01\uacfc \ub9ac\ubdf0 \ubc1b\uc740 \uac83\uc744 \uacf5\uc720\ud55c \uac83\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ud329\ud130\ub9c1\uc744 \uc5b4\ub5bb\uac8c \ud588\ub294\uc9c0? \uc774\ub7f0 \ub9ac\ubdf0\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \uc0dd\uac01\ud558\ub294\uc9c0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c8 \uc218 \uc788\uc5c8\ub2e4."),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,"\ub9ac\ud329\ud130\ub9c1\uc774 \ub05d\ub09c \ud6c4 \uba54\uc11c\ub4dc\uba85, \ud14c\uc2a4\ud2b8\uc2dc \ucd9c\ub825\ud558\ub294 \uba54\uc2dc\uc9c0\uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\uac00 \ub9ce\uc774 \ub2ec\ub838\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac1d\uccb4\uac00 \uc5b4\ub5a4 \ucc45\uc784\uacfc \uc5ed\ud560\uc744 \uac00\uc9c0\ub294\uc9c0 \uc0dd\uac01\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uba85\ud655\ud55c \uba54\uc11c\ub4dc\uba85\uc744 \uc791\uc131\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("p",null,"\ud3c9\uc18c\uc5d0 \ud504\ub85c\uadf8\ub798\ubc0d \uc774\uc57c\uae30\uac00 \uc544\ub2cc \ub2e4\ub978 \uc8fc\uc81c\ub85c \uc774\uc57c\uae30\ud558\uba74 \uc798 \ub4e4\uc73c\ub824\uace0 \ud558\ub294 \ud3b8\uc774\uc9c0\ub9cc",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \uc88b\uc544\ud558\ub294 \uc8fc\uc81c, \uad00\uc2ec\uac00\ub294 \uc8fc\uc81c\uc778 \ud504\ub85c\uadf8\ub798\ubc0d\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub97c \ud560 \ub550 \ub9d0\uc774 \ub9ce\uc544\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130\ub294 \ub354 \ub9ce\uc740 \uc2dc\uac04\uc744 \ud398\uc5b4\uc758 \uc758\uacac\uacfc \uc774\uc57c\uae30\ub97c \ub4e3\ub294 \uacf3\uc5d0 \uc0ac\uc6a9\ud574\uc57c\uaca0\ub2e4."),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Assertions extracting")),(0,a.kt)("p",null,"\uacb0\uacfc \ub0b4\ubd80\uc5d0 \uc788\ub294 \uac12\uc744 \ud655\uc778\ud558\uace0 \uc2f6\uc744 \ub54c extracting \ud0a4\uc6cc\ub4dc\ub97c \uc774\uc6a9\ud574\uc11c \ub0b4\ubd80\uc758 \uac12\uc744 \uac80\uc99d\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804\uc5d0\ub294 \ud544\uc694\uc5d0 \ub530\ub77c stream\uc744 \uc774\uc6a9\ud558\uc5ec \uac80\uc99d\ud560 \uac12\uc744 \uc0dd\uc131\ud588\uc9c0\ub9cc, \ud574\ub2f9 \ubc29\ubc95\uc744 \uc774\uc6a9\ud574\uc11c \uc808\ucc28\ub97c \uc904\uc77c \uc218 \uc788\uc5c8\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@Test\nvoid extracting() {\n final Cars cars = new Cars(List.of("car1", "car2"));\n\n assertThat(cars.getCars())\n .extracting(Car::getName)\n .containsExactly("car1", "car2");\n}\n')),(0,a.kt)("hr",null),(0,a.kt)("p",null,"\uc544\ub798\ub294 \ub9ac\ubdf0\uc5b4\ub2d8\uacfc \ub300\ud654\ub97c \ub098\ub204\uba74\uc11c \uc5bb\uc740 \ub2f5\ubcc0 + \ub098\uc758 \uc758\uacac\uc774\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8")),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8 \ub300\uc0c1\uc774 \uac80\uc99d\ub41c \uac83\uc774\ub77c\uba74 \uc791\uc131\ud558\uc9c0 \uc54a\uac70\ub098, \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uc791\uc131\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uac74 \uac1c\uc778\uc801\uc778 \uc0dd\uac01\uc774\uc9c0\ub9cc \ub0b4\uac00 \uc548\uc815\uac10\uc774 \ub4e4 \uc218 \uc788\uc744 \uc815\ub3c4\ub85c \ucd9c\ub825 \ubc94\uc704 \ub0b4\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud558\ub294\uc9c0 \uc815\ub3c4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub2e8\uc21c \uc704\uc784\uc744 \ud558\ub294 \uba54\uc11c\ub4dc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8")),(0,a.kt)("p",null,"\uc704\uc784\uc774\ub77c\ub294 \uac83\uc740 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \ub118\uaca8\uc900\ub2e4\ub294 \uac83\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc99d\ud558\ub294 \uac83\ubcf4\ub2e4 \uacb0\uacfc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc21c\ud788 \uc704\uc784\ub9cc \ud558\ub294 \ud14c\uc2a4\ud2b8\uc758 \uacbd\uc6b0 \uacb0\uacfc\ub97c \uac80\uc99d\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8\uac00 \uc911\ubcf5\ub418\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc911\ubcf5\ub41c \ud14c\uc2a4\ud2b8\ub97c \uc904\uc774\uae30 \uc704\ud574 \ub0b4\ubd80\uc758 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0 \uac80\uc99d\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\ub294 \uac83\uc744 \uc54c\uac8c \ub418\uc5c8\uc9c0\ub9cc",(0,a.kt)("br",{parentName:"p"}),"\n","\uc548\uc815\uc801\uc73c\ub85c \uacb0\uacfc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc778 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c getter \uc0ac\uc6a9")),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\ub85c \ub3c4\uba54\uc778\uc5d0 \uc0c8\ub85c\uc6b4 \uba54\uc11c\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc740 \uc88b\uc9c0 \ubabb\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud544\uc694\uc758 \uacbd\uc6b0 \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc9c0\ub9cc, \uae30\uc874\uc5d0 \uc788\ub294 \uba54\uc11c\ub4dc\ub4e4\uc744 \ud65c\uc6a9\ud574\ubcf4\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub9e4\uc6b0 \ub3d9\uc758\ud558\uace0, \uc55e\uc73c\ub85c\ub3c4 \ucd5c\ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \ucf54\ub4dc\ub97c \ub3c4\uba54\uc778\uc5d0 \uc791\uc131\ud558\uc9c0 \uc54a\uc744 \uac83 \uac19\ub2e4."),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,"\uc9c8\ubb38\uc774\ub098 \uc0dd\uac01\ud560 \uc810\uc774 \uc788\uc744 \ub54c \ub9e4\uc6b0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uac83 \uac19\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0dd\uac01\uc744 \uc815\ub9ac\ud55c \ud6c4 \uc790\uc2e0\uc758 \uc758\uacac\uc744 \uba85\ub8cc\ud558\uac8c \uc804\ub2ec\ud574\uc8fc\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc2dd\uc744 \ud6a8\uc728\uc801\uc73c\ub85c \uc2b5\ub4dd\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub09c \uc0dd\uac01\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc740 \ucc44\ub85c \ub0b4\ubc84\ub824 \ub454 \uc595\uc740 \uc9c0\uc2dd\uc774 \ub9ce\uc740 \uac83 \uac19\ub2e4. (\uc774\ub7f0 \uac83\ub3c4 \uc544\ub294 \uac83\uc774\ub77c\uace0 \ud560 \uc218 \uc788\uc744\uae4c?)",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc870\uae08 \ub354 \uba38\ub9bf\uc18d\uc5d0\uc11c \uc815\ub9ac\ud558\uace0, \ubb38\uc81c\uc5d0 \ub300\ud574 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \ub298\ub824\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,"\uac1c\ubc1c\uc5d0 \uc5f4\uc815\uc744 \uac00\uc9c4 \uac8c \ub290\uaef4\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 \uac1c\ubc1c\uc744 \uc88b\uc544\ud558\uc9c0\ub9cc, \ucd5c\uadfc\uc5d0\ub294 \uc758\uc9c0\uac00 \uc57d\ud574\uc84c\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc5f4\uc815\uc774 \uac00\ub4dd\ud55c \uc0ac\ub78c\uc744 \ub9cc\ub098\ub2c8 \ub098\ub3c4 \uc5f4\uc815\uc801\uc778 \uc0ac\ub78c\uc774 \ub418\ub294 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,"\uce6d\ucc2c\uc744 \ub9ce\uc774 \ud574\uc900\ub2e4. \ub2e8\uc21c\ud788 \ub9ce\uc774 \ud574\uc8fc\ub294 \uac83\uc774 \uc544\ub2c8\ub77c, \uc9c4\uc2ec\uc744 \ub2f4\uae34 \uce6d\ucc2c\uc744 \ud574\uc92c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uce6d\ucc2c\uc740 \uace0\ub798\ub3c4 \ucda4\ucd94\uac8c \ud558\ub358\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub798\uc11c \uc990\uac70\uc6b4 \ub9c8\uc74c\uc73c\ub85c \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud588\uc5c8\ub358 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,"\uc5b4\ub5a4 \uc774\uc720 \ub54c\ubb38\uc778\uc9c0 \ubaa8\ub974\uaca0\uc9c0\ub9cc \uac19\uc774 \ud398\uc5b4\ud558\ub294\ub370 \ud3b8\ud55c \ub9c8\uc74c\uc774 \ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uac74 \ubc14\ub85c \ubc30\uc6b8 \uc218 \uc5c6\uc9c0\ub9cc.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 \uac19\uc774 \uc77c\ud560 \ub54c \ud3b8\ud55c \uc0ac\ub78c, \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub418\uae30 \uc704\ud574 \uae4a\uc774 \uace0\ubbfc\ud574\ubd10\uc57c\uaca0\ub2e4."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/92fef07b.fcbe78e8.js b/assets/js/92fef07b.fcbe78e8.js new file mode 100644 index 000000000..9ac0ec002 --- /dev/null +++ b/assets/js/92fef07b.fcbe78e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[300],{41632:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>o,contentTitle:()=>i,default:()=>x,frontMatter:()=>s,metadata:()=>c,toc:()=>l});var t=n(85893),a=n(3905);const s={title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",slug:"racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,c={permalink:"/racing-car-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-racingcar/pull/510",date:"2023-02-14T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 14\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.625,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",slug:"racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",permalink:"/ladder-retrospective"},nextItem:{title:"Parameterized Tests",permalink:"/parameterized-tests"}},o={authorsImageUrls:[]},l=[{value:"\uc790\ub3d9\ucc28 \uacbd\uc8fc",id:"\uc790\ub3d9\ucc28-\uacbd\uc8fc",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function p(e){const r={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",hr:"hr",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/java-racingcar/pull/510",children:"https://github.com/woowacourse/java-racingcar/pull/510"}),(0,t.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/java-racingcar/pull/538",children:"https://github.com/woowacourse/java-racingcar/pull/538"})]})}),"\n",(0,t.jsx)(r.h3,{id:"\uc790\ub3d9\ucc28-\uacbd\uc8fc",children:"\uc790\ub3d9\ucc28 \uacbd\uc8fc"}),"\n",(0,t.jsxs)(r.p,{children:["\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158\uc5d0\uc11c\ub294 \ub2e4\uc990\uacfc \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6b0\ud14c\ucf54 \ub4e4\uc5b4\uc640\uc11c \uccab \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\uc774\ub77c \ub9ce\uc774 \ub5a8\ub838\uc9c0\ub9cc, \ub2e4\uc990\uc774 \ub300\ud654\ub97c \uc798 \uc774\ub04c\uc5b4\uc918 \ub108\ubb34 \uc990\uac70\uc6e0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uccab\ub0a0\uc740 \uac04\ub2e8\ud788 \ucee8\ubca4\uc158\uacfc \ud658\uacbd\uc744 \uc124\uc815\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc84c\uace0 \ub2e4\uc74c \ub0a0\ubd80\ud130 \uc790\ub3d9\ucc28 \uacbd\uc8fc\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc2dc\uc791\uc740 \uac04\ub2e8\ud558\uac8c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud558\uace0, \uc5b4\ub5bb\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud560\uc9c0 \uac19\uc774 \uace0\ubbfc\ud588\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc2dc\uc791\ud558\uae30 \uc804 \uc544\ub798\uc640 \uac19\uc774 mermaid\ub97c \uc774\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc5d0 \ub300\ud574\uc11c \uac04\ub2e8\ud55c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uace0 \uc2dc\uc791\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","mermaid\ub294 \ucf54\ub4dc\ub85c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \uc0dd\uc131 \ud574\uc8fc\ub294 \ub3c4\uad6c\ub85c \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc774 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:"\ucf54\ub4dc \uae30\ubc18\uc774\ub77c \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \uc0dd\uac01\ud55c \uac83\uc744 \uc2dc\uac01\ud654\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(r.li,{children:"github\uc5d0\uc11c mermaid\ub97c \uc9c0\uc6d0\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \ucf54\ub4dc\ub97c \uc774\ud574\ud560 \uc218 \uc788\ub294 \ubd80\uac00\uc801\uc778 \uc815\ubcf4\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."}),"\n"]}),"\n",(0,t.jsx)(r.mermaid,{value:"---\ntitle: \uc790\ub3d9\ucc28 \uacbd\uc8fc \uccab \ub9ac\ubdf0 \uc694\uccad\uc2dc \uad6c\uc870\n---\ngraph TD\n Cars --\x3e Car\n Car --\x3e Name\n Car --\x3e Position\n RacingGame --\x3e Count\n RacingGame --\x3e NumberGenerator\n RacingGame --\x3e Cars\n RacingCarController --\x3e RacingGame\n RandomNumberGenerator -.-> NumberGenerator\n RacingCarController --\x3e InputView\n InputView --\x3e InputValidator\n RacingCarController --\x3e OutputView"}),"\n",(0,t.jsx)(r.p,{children:"\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \ub370 \ud070 \uc5b4\ub824\uc6c0\uc774 \uc788\uc9c0\ub294 \uc54a\uc558\uace0, \ud398\uc5b4\ub97c \ub9c8\uce58\uae30 \uc804 \uc11c\ub85c \uace0\ubbfc\ub418\ub294 \ubd80\ubd84\uc744 \uc815\ub9ac\ud588\uc744 \ub54c \uc88b\uc558\ub2e4."}),"\n",(0,t.jsxs)(r.p,{children:["\ud398\uc5b4\ud558\uba74\uc11c \uc798\ud588\ub2e4\uace0 \uc0dd\uac01\ud588\ub358 \uc810\uc740 \uc11c\ub85c\uc758 \uc0dd\uac01\uacfc \ub9ac\ubdf0 \ubc1b\uc740 \uac83\uc744 \uacf5\uc720\ud55c \uac83\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub9ac\ud329\ud130\ub9c1\uc744 \uc5b4\ub5bb\uac8c \ud588\ub294\uc9c0? \uc774\ub7f0 \ub9ac\ubdf0\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \uc0dd\uac01\ud558\ub294\uc9c0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c8 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:["\ub9ac\ud329\ud130\ub9c1\uc774 \ub05d\ub09c \ud6c4 \uba54\uc11c\ub4dc\uba85, \ud14c\uc2a4\ud2b8\uc2dc \ucd9c\ub825\ud558\ub294 \uba54\uc2dc\uc9c0\uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\uac00 \ub9ce\uc774 \ub2ec\ub838\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uac1d\uccb4\uac00 \uc5b4\ub5a4 \ucc45\uc784\uacfc \uc5ed\ud560\uc744 \uac00\uc9c0\ub294\uc9c0 \uc0dd\uac01\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uba85\ud655\ud55c \uba54\uc11c\ub4dc\uba85\uc744 \uc791\uc131\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ud3c9\uc18c\uc5d0 \ud504\ub85c\uadf8\ub798\ubc0d \uc774\uc57c\uae30\uac00 \uc544\ub2cc \ub2e4\ub978 \uc8fc\uc81c\ub85c \uc774\uc57c\uae30\ud558\uba74 \uc798 \ub4e4\uc73c\ub824\uace0 \ud558\ub294 \ud3b8\uc774\uc9c0\ub9cc",(0,t.jsx)(r.br,{}),"\n","\ub0b4\uac00 \uc88b\uc544\ud558\ub294 \uc8fc\uc81c, \uad00\uc2ec\uac00\ub294 \uc8fc\uc81c\uc778 \ud504\ub85c\uadf8\ub798\ubc0d\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub97c \ud560 \ub550 \ub9d0\uc774 \ub9ce\uc544\uc9c4\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130\ub294 \ub354 \ub9ce\uc740 \uc2dc\uac04\uc744 \ud398\uc5b4\uc758 \uc758\uacac\uacfc \uc774\uc57c\uae30\ub97c \ub4e3\ub294 \uacf3\uc5d0 \uc0ac\uc6a9\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"Assertions extracting"})}),"\n",(0,t.jsxs)(r.p,{children:["\uacb0\uacfc \ub0b4\ubd80\uc5d0 \uc788\ub294 \uac12\uc744 \ud655\uc778\ud558\uace0 \uc2f6\uc744 \ub54c extracting \ud0a4\uc6cc\ub4dc\ub97c \uc774\uc6a9\ud574\uc11c \ub0b4\ubd80\uc758 \uac12\uc744 \uac80\uc99d\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\uc804\uc5d0\ub294 \ud544\uc694\uc5d0 \ub530\ub77c stream\uc744 \uc774\uc6a9\ud558\uc5ec \uac80\uc99d\ud560 \uac12\uc744 \uc0dd\uc131\ud588\uc9c0\ub9cc, \ud574\ub2f9 \ubc29\ubc95\uc744 \uc774\uc6a9\ud574\uc11c \uc808\ucc28\ub97c \uc904\uc77c \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-java",children:'@Test\nvoid extracting() {\n final Cars cars = new Cars(List.of("car1", "car2"));\n\n assertThat(cars.getCars())\n .extracting(Car::getName)\n .containsExactly("car1", "car2");\n}\n'})}),"\n",(0,t.jsx)(r.hr,{}),"\n",(0,t.jsx)(r.p,{children:"\uc544\ub798\ub294 \ub9ac\ubdf0\uc5b4\ub2d8\uacfc \ub300\ud654\ub97c \ub098\ub204\uba74\uc11c \uc5bb\uc740 \ub2f5\ubcc0 + \ub098\uc758 \uc758\uacac\uc774\ub2e4."}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8"})}),"\n",(0,t.jsxs)(r.p,{children:["\ud14c\uc2a4\ud2b8 \ub300\uc0c1\uc774 \uac80\uc99d\ub41c \uac83\uc774\ub77c\uba74 \uc791\uc131\ud558\uc9c0 \uc54a\uac70\ub098, \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uc791\uc131\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\uac74 \uac1c\uc778\uc801\uc778 \uc0dd\uac01\uc774\uc9c0\ub9cc \ub0b4\uac00 \uc548\uc815\uac10\uc774 \ub4e4 \uc218 \uc788\uc744 \uc815\ub3c4\ub85c \ucd9c\ub825 \ubc94\uc704 \ub0b4\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud558\ub294\uc9c0 \uc815\ub3c4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ub2e8\uc21c \uc704\uc784\uc744 \ud558\ub294 \uba54\uc11c\ub4dc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc704\uc784\uc774\ub77c\ub294 \uac83\uc740 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \ub118\uaca8\uc900\ub2e4\ub294 \uac83\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc99d\ud558\ub294 \uac83\ubcf4\ub2e4 \uacb0\uacfc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub2e8\uc21c\ud788 \uc704\uc784\ub9cc \ud558\ub294 \ud14c\uc2a4\ud2b8\uc758 \uacbd\uc6b0 \uacb0\uacfc\ub97c \uac80\uc99d\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8\uac00 \uc911\ubcf5\ub418\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub530\ub77c\uc11c \uc911\ubcf5\ub41c \ud14c\uc2a4\ud2b8\ub97c \uc904\uc774\uae30 \uc704\ud574 \ub0b4\ubd80\uc758 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0 \uac80\uc99d\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\ub294 \uac83\uc744 \uc54c\uac8c \ub418\uc5c8\uc9c0\ub9cc",(0,t.jsx)(r.br,{}),"\n","\uc548\uc815\uc801\uc73c\ub85c \uacb0\uacfc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc778 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c getter \uc0ac\uc6a9"})}),"\n",(0,t.jsxs)(r.p,{children:["\ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\ub85c \ub3c4\uba54\uc778\uc5d0 \uc0c8\ub85c\uc6b4 \uba54\uc11c\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc740 \uc88b\uc9c0 \ubabb\ud558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud544\uc694\uc758 \uacbd\uc6b0 \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc9c0\ub9cc, \uae30\uc874\uc5d0 \uc788\ub294 \uba54\uc11c\ub4dc\ub4e4\uc744 \ud65c\uc6a9\ud574\ubcf4\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub9e4\uc6b0 \ub3d9\uc758\ud558\uace0, \uc55e\uc73c\ub85c\ub3c4 \ucd5c\ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \ucf54\ub4dc\ub97c \ub3c4\uba54\uc778\uc5d0 \uc791\uc131\ud558\uc9c0 \uc54a\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:["\uc9c8\ubb38\uc774\ub098 \uc0dd\uac01\ud560 \uc810\uc774 \uc788\uc744 \ub54c \ub9e4\uc6b0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uac83 \uac19\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc0dd\uac01\uc744 \uc815\ub9ac\ud55c \ud6c4 \uc790\uc2e0\uc758 \uc758\uacac\uc744 \uba85\ub8cc\ud558\uac8c \uc804\ub2ec\ud574\uc8fc\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc2dd\uc744 \ud6a8\uc728\uc801\uc73c\ub85c \uc2b5\ub4dd\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub09c \uc0dd\uac01\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc740 \ucc44\ub85c \ub0b4\ubc84\ub824 \ub454 \uc595\uc740 \uc9c0\uc2dd\uc774 \ub9ce\uc740 \uac83 \uac19\ub2e4. (\uc774\ub7f0 \uac83\ub3c4 \uc544\ub294 \uac83\uc774\ub77c\uace0 \ud560 \uc218 \uc788\uc744\uae4c?)",(0,t.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c \uc870\uae08 \ub354 \uba38\ub9bf\uc18d\uc5d0\uc11c \uc815\ub9ac\ud558\uace0, \ubb38\uc81c\uc5d0 \ub300\ud574 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \ub298\ub824\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uac1c\ubc1c\uc5d0 \uc5f4\uc815\uc744 \uac00\uc9c4 \uac8c \ub290\uaef4\uc9c4\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub098\ub3c4 \uac1c\ubc1c\uc744 \uc88b\uc544\ud558\uc9c0\ub9cc, \ucd5c\uadfc\uc5d0\ub294 \uc758\uc9c0\uac00 \uc57d\ud574\uc84c\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc5f4\uc815\uc774 \uac00\ub4dd\ud55c \uc0ac\ub78c\uc744 \ub9cc\ub098\ub2c8 \ub098\ub3c4 \uc5f4\uc815\uc801\uc778 \uc0ac\ub78c\uc774 \ub418\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uce6d\ucc2c\uc744 \ub9ce\uc774 \ud574\uc900\ub2e4. \ub2e8\uc21c\ud788 \ub9ce\uc774 \ud574\uc8fc\ub294 \uac83\uc774 \uc544\ub2c8\ub77c, \uc9c4\uc2ec\uc744 \ub2f4\uae34 \uce6d\ucc2c\uc744 \ud574\uc92c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uce6d\ucc2c\uc740 \uace0\ub798\ub3c4 \ucda4\ucd94\uac8c \ud558\ub358\uac00?",(0,t.jsx)(r.br,{}),"\n","\uadf8\ub798\uc11c \uc990\uac70\uc6b4 \ub9c8\uc74c\uc73c\ub85c \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud588\uc5c8\ub358 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc5b4\ub5a4 \uc774\uc720 \ub54c\ubb38\uc778\uc9c0 \ubaa8\ub974\uaca0\uc9c0\ub9cc \uac19\uc774 \ud398\uc5b4\ud558\ub294\ub370 \ud3b8\ud55c \ub9c8\uc74c\uc774 \ub4e4\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\uac74 \ubc14\ub85c \ubc30\uc6b8 \uc218 \uc5c6\uc9c0\ub9cc.",(0,t.jsx)(r.br,{}),"\n","\ub098\ub3c4 \uac19\uc774 \uc77c\ud560 \ub54c \ud3b8\ud55c \uc0ac\ub78c, \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub418\uae30 \uc704\ud574 \uae4a\uc774 \uace0\ubbfc\ud574\ubd10\uc57c\uaca0\ub2e4."]})]})}function x(e={}){const{wrapper:r}={...(0,a.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>l});var t=n(67294);function a(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function s(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function i(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?s(Object(n),!0).forEach((function(r){a(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function c(e,r){if(null==e)return{};var n,t,a=function(e,r){if(null==e)return{};var n,t,a={},s=Object.keys(e);for(t=0;t<s.length;t++)n=s[t],r.indexOf(n)>=0||(a[n]=e[n]);return a}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t<s.length;t++)n=s[t],r.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var o=t.createContext({}),l=function(e){var r=t.useContext(o),n=r;return e&&(n="function"==typeof e?e(r):i(i({},r),e)),n},p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},x=t.forwardRef((function(e,r){var n=e.components,a=e.mdxType,s=e.originalType,o=e.parentName,x=c(e,["components","mdxType","originalType","parentName"]),d=l(n),j=a,h=d["".concat(o,".").concat(j)]||d[j]||p[j]||s;return n?t.createElement(h,i(i({ref:r},x),{},{components:n})):t.createElement(h,i({ref:r},x))}));x.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.5b9655c6.js b/assets/js/935f2afb.5b9655c6.js new file mode 100644 index 000000000..a173635b3 --- /dev/null +++ b/assets/js/935f2afb.5b9655c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"category","label":"JPA","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","href":"/docs/jpa/key","docId":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551","unlisted":false}]},{"type":"category","label":"Java","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SequencedCollection","href":"/docs/java/sequenced-collection","docId":"Java/SequencedCollection","unlisted":false}]},{"type":"category","label":"MAC","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","href":"/docs/mac/java","docId":"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","unlisted":false}]},{"type":"category","label":"Nginx","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4","href":"/docs/nginx/command","docId":"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4","unlisted":false},{"type":"link","label":"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5","href":"/docs/nginx/static-file","docId":"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5","unlisted":false}]},{"type":"link","label":"\ubb38\uc11c","href":"/docs/","docId":"intro","unlisted":false},{"type":"category","label":"\uae30\ud0c0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","href":"/docs/etc/healthful-growth","docId":"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","unlisted":false},{"type":"link","label":"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","href":"/docs/etc/develop-with-spring","docId":"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","unlisted":false},{"type":"link","label":"\uacbd\ud5d8\uacfc \uc9c8\ubb38","href":"/docs/etc/experience-and-self-question","docId":"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8","unlisted":false},{"type":"link","label":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","href":"/docs/etc/communication","docId":"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","unlisted":false}]},{"type":"category","label":"\ub124\ud2b8\uc6cc\ud06c","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","href":"/docs/network/load-balancing-algorithm","docId":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","unlisted":false},{"type":"link","label":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1","href":"/docs/network/load-balancing","docId":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","unlisted":false}]},{"type":"category","label":"\ub370\uc774\ud130\ubca0\uc774\uc2a4","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"maximumPoolSize","href":"/docs/database/maximumPoolSize","docId":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool","unlisted":false},{"type":"link","label":"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","href":"/docs/database/query-execution","docId":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","unlisted":false}]},{"type":"category","label":"\ub3c4\uc11c","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","href":"/docs/book/getting-out-of-the-box","docId":"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","unlisted":false}]},{"type":"category","label":"\ub9ac\ub205\uc2a4","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Swap \uba54\ubaa8\ub9ac \uc124\uc815","href":"/docs/linux/swap","docId":"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815","unlisted":false},{"type":"link","label":"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","href":"/docs/linux/shell","docId":"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","unlisted":false}]},{"type":"category","label":"\ubaa8\ub2c8\ud130\ub9c1","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","href":"/docs/monitoring/intro","docId":"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","unlisted":false}]},{"type":"category","label":"\ubb38\ud654","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","href":"/docs/culture/postmortem","docId":"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","unlisted":false}]},{"type":"category","label":"\ubc30\ud3ec","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","href":"/docs/deploy/zero-downtime","docId":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","unlisted":false}]},{"type":"category","label":"\uc124\uacc4","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ud328\ud0a4\uc9c0","href":"/docs/design/package","docId":"\uc124\uacc4/\ud328\ud0a4\uc9c0","unlisted":false}]},{"type":"category","label":"\uc131\ub2a5","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Throughput \ubaa9\ud46f\uac12","href":"/docs/performance/throughput","docId":"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12","unlisted":false},{"type":"link","label":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","href":"/docs/performance/throughput-latency","docId":"\uc131\ub2a5/Throughput\uacfc Latency","unlisted":false},{"type":"link","label":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615","href":"/docs/performance/types","docId":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","unlisted":false}]},{"type":"category","label":"\uc2a4\ud504\ub9c1","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","href":"/docs/spring/essence","docId":"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","unlisted":false}]},{"type":"category","label":"\uc544\ud0a4\ud14d\ucc98","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","href":"/docs/architecture/virtical-slice-architecture","docId":"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","unlisted":false}]},{"type":"category","label":"\ud14c\uc2a4\ud2b8","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"FIRST","href":"/docs/test/first","docId":"\ud14c\uc2a4\ud2b8/FIRST","unlisted":false},{"type":"link","label":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","href":"/docs/test/stairstep","docId":"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","unlisted":false},{"type":"link","label":"TDD heuristics","href":"/docs/test/heuristics","docId":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59","unlisted":false},{"type":"link","label":"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","href":"/docs/test/benefit","docId":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","unlisted":false}]}]},"docs":{"intro":{"id":"intro","title":"\ubb38\uc11c","description":"\ub9c8\uc74c\uc5d0 \ub4e0 \ud0a4\uc6cc\ub4dc \uc815\ub9ac","sidebar":"tutorialSidebar"},"Java/SequencedCollection":{"id":"Java/SequencedCollection","title":"SequencedCollection","description":"JEP 431: Sequenced Collections","sidebar":"tutorialSidebar"},"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551":{"id":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551","title":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","description":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","sidebar":"tutorialSidebar"},"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd":{"id":"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","title":"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","description":"\uc124\uce58\ub41c \uc790\ubc14 \ubc84\uc804 \ud655\uc778","sidebar":"tutorialSidebar"},"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4":{"id":"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4","title":"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4","description":"\ud3f4\ub354 \ubc0f \ud30c\uc77c","sidebar":"tutorialSidebar"},"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5":{"id":"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5","title":"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5","description":"root","sidebar":"tutorialSidebar"},"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30":{"id":"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","title":"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","description":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 4\uc6d4 19\uc77c","sidebar":"tutorialSidebar"},"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30":{"id":"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","title":"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","description":"\uc5b4\ub5a4 \uae30\uc220\uc744 \ud1b5\ud574\uc11c\ub3c4 \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4.","sidebar":"tutorialSidebar"},"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8":{"id":"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8","title":"\uacbd\ud5d8\uacfc \uc9c8\ubb38","description":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 10\uc6d4 6\uc77c","sidebar":"tutorialSidebar"},"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00":{"id":"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","title":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","description":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?","sidebar":"tutorialSidebar"},"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1":{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1","description":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?","sidebar":"tutorialSidebar"},"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998":{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","description":"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)","sidebar":"tutorialSidebar"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool":{"id":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool","title":"maximumPoolSize","description":"maximumPoolSize","sidebar":"tutorialSidebar"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870":{"id":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","title":"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","description":"\uc2e4\ud589 \uad6c\uc870","sidebar":"tutorialSidebar"},"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30":{"id":"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","title":"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","description":"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac","sidebar":"tutorialSidebar"},"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815":{"id":"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815","title":"Swap \uba54\ubaa8\ub9ac \uc124\uc815","description":"Swap \uba54\ubaa8\ub9ac","sidebar":"tutorialSidebar"},"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815":{"id":"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","title":"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","description":"\uacc4\uc815 \ubcc4 \ud130\ubbf8\ub110 \uc124\uc815","sidebar":"tutorialSidebar"},"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131":{"id":"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","title":"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","description":"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4","sidebar":"tutorialSidebar"},"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c":{"id":"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","title":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","description":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)","sidebar":"tutorialSidebar"},"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec":{"id":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","title":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","description":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","sidebar":"tutorialSidebar"},"\uc124\uacc4/\ud328\ud0a4\uc9c0":{"id":"\uc124\uacc4/\ud328\ud0a4\uc9c0","title":"\ud328\ud0a4\uc9c0","description":"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0","sidebar":"tutorialSidebar"},"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12":{"id":"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12","title":"Throughput \ubaa9\ud46f\uac12","description":"Throughput","sidebar":"tutorialSidebar"},"\uc131\ub2a5/Throughput\uacfc Latency":{"id":"\uc131\ub2a5/Throughput\uacfc Latency","title":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","description":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","sidebar":"tutorialSidebar"},"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8":{"id":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615","description":"| \ud14c\uc2a4\ud2b8 | \uc124\uba85 |","sidebar":"tutorialSidebar"},"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5":{"id":"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","title":"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","description":"\uc2a4\ud504\ub9c1\uc758 \ud575\uc2ec \uac1c\ubc1c\uc790\ub4e4\uc774 \uc4f4 Professional Spring Framework \ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc758 \uc815\uc218(essence)\ub294 \\"\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\ub294 \uac83\\" \uc774\ub77c\uace0 \ud588\ub2e4.","sidebar":"tutorialSidebar"},"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98":{"id":"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","title":"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","description":"\uac1c\uc694","sidebar":"tutorialSidebar"},"\ud14c\uc2a4\ud2b8/FIRST":{"id":"\ud14c\uc2a4\ud2b8/FIRST","title":"FIRST","description":"FIRST\ub780?","sidebar":"tutorialSidebar"},"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8":{"id":"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","title":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","description":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)","sidebar":"tutorialSidebar"},"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59":{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59","title":"TDD heuristics","description":"TDD heuristics","sidebar":"tutorialSidebar"},"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd":{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","title":"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","description":"\ub514\ubc84\uae45 \uac10\uc18c","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.b34f8ac9.js b/assets/js/935f2afb.b34f8ac9.js deleted file mode 100644 index 0d86e082c..000000000 --- a/assets/js/935f2afb.b34f8ac9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[53],{1109:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"category","label":"JPA","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","href":"/docs/jpa/key","docId":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551"}]},{"type":"category","label":"Java","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SequencedCollection","href":"/docs/java/sequenced-collection","docId":"Java/SequencedCollection"}]},{"type":"category","label":"MAC","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","href":"/docs/mac/java","docId":"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd"}]},{"type":"category","label":"Nginx","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4","href":"/docs/nginx/command","docId":"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4"},{"type":"link","label":"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5","href":"/docs/nginx/static-file","docId":"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5"}]},{"type":"link","label":"\ubb38\uc11c","href":"/docs/","docId":"intro"},{"type":"category","label":"\uae30\ud0c0","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","href":"/docs/etc/healthful-growth","docId":"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30"},{"type":"link","label":"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","href":"/docs/etc/develop-with-spring","docId":"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30"},{"type":"link","label":"\uacbd\ud5d8\uacfc \uc9c8\ubb38","href":"/docs/etc/experience-and-self-question","docId":"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8"},{"type":"link","label":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","href":"/docs/etc/communication","docId":"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00"}]},{"type":"category","label":"\ub124\ud2b8\uc6cc\ud06c","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","href":"/docs/network/load-balancing-algorithm","docId":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998"},{"type":"link","label":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1","href":"/docs/network/load-balancing","docId":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1"}]},{"type":"category","label":"\ub370\uc774\ud130\ubca0\uc774\uc2a4","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"maximumPoolSize","href":"/docs/database/maximumPoolSize","docId":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool"},{"type":"link","label":"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","href":"/docs/database/query-execution","docId":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870"}]},{"type":"category","label":"\ub3c4\uc11c","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","href":"/docs/book/getting-out-of-the-box","docId":"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30"}]},{"type":"category","label":"\ub9ac\ub205\uc2a4","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Swap \uba54\ubaa8\ub9ac \uc124\uc815","href":"/docs/linux/swap","docId":"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815"},{"type":"link","label":"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","href":"/docs/linux/shell","docId":"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815"}]},{"type":"category","label":"\ubaa8\ub2c8\ud130\ub9c1","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","href":"/docs/monitoring/intro","docId":"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131"}]},{"type":"category","label":"\ubb38\ud654","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","href":"/docs/culture/postmortem","docId":"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c"}]},{"type":"category","label":"\ubc30\ud3ec","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","href":"/docs/deploy/zero-downtime","docId":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec"}]},{"type":"category","label":"\uc124\uacc4","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ud328\ud0a4\uc9c0","href":"/docs/design/package","docId":"\uc124\uacc4/\ud328\ud0a4\uc9c0"}]},{"type":"category","label":"\uc131\ub2a5","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Throughput \ubaa9\ud46f\uac12","href":"/docs/performance/throughput","docId":"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12"},{"type":"link","label":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","href":"/docs/performance/throughput-latency","docId":"\uc131\ub2a5/Throughput\uacfc Latency"},{"type":"link","label":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615","href":"/docs/performance/types","docId":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8"}]},{"type":"category","label":"\uc2a4\ud504\ub9c1","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","href":"/docs/spring/essence","docId":"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5"}]},{"type":"category","label":"\uc544\ud0a4\ud14d\ucc98","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","href":"/docs/architecture/virtical-slice-architecture","docId":"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98"}]},{"type":"category","label":"\ud14c\uc2a4\ud2b8","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"FIRST","href":"/docs/test/first","docId":"\ud14c\uc2a4\ud2b8/FIRST"},{"type":"link","label":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","href":"/docs/test/stairstep","docId":"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8"},{"type":"link","label":"TDD heuristics","href":"/docs/test/heuristics","docId":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59"},{"type":"link","label":"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","href":"/docs/test/benefit","docId":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd"}]}]},"docs":{"intro":{"id":"intro","title":"\ubb38\uc11c","description":"\ub9c8\uc74c\uc5d0 \ub4e0 \ud0a4\uc6cc\ub4dc \uc815\ub9ac","sidebar":"tutorialSidebar"},"Java/SequencedCollection":{"id":"Java/SequencedCollection","title":"SequencedCollection","description":"JEP 431: Sequenced Collections","sidebar":"tutorialSidebar"},"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551":{"id":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551","title":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","description":"\uae30\ubcf8 \ud0a4 \ub9e4\ud551","sidebar":"tutorialSidebar"},"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd":{"id":"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","title":"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","description":"\uc124\uce58\ub41c \uc790\ubc14 \ubc84\uc804 \ud655\uc778","sidebar":"tutorialSidebar"},"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4":{"id":"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4","title":"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4","description":"\ud3f4\ub354 \ubc0f \ud30c\uc77c","sidebar":"tutorialSidebar"},"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5":{"id":"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5","title":"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5","description":"root","sidebar":"tutorialSidebar"},"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30":{"id":"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","title":"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","description":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 4\uc6d4 19\uc77c","sidebar":"tutorialSidebar"},"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30":{"id":"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","title":"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","description":"\uc5b4\ub5a4 \uae30\uc220\uc744 \ud1b5\ud574\uc11c\ub3c4 \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4.","sidebar":"tutorialSidebar"},"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8":{"id":"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8","title":"\uacbd\ud5d8\uacfc \uc9c8\ubb38","description":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 10\uc6d4 6\uc77c","sidebar":"tutorialSidebar"},"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00":{"id":"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","title":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","description":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?","sidebar":"tutorialSidebar"},"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1":{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1","description":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?","sidebar":"tutorialSidebar"},"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998":{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","title":"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","description":"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)","sidebar":"tutorialSidebar"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool":{"id":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool","title":"maximumPoolSize","description":"maximumPoolSize","sidebar":"tutorialSidebar"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870":{"id":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","title":"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","description":"\uc2e4\ud589 \uad6c\uc870","sidebar":"tutorialSidebar"},"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30":{"id":"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","title":"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","description":"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac","sidebar":"tutorialSidebar"},"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815":{"id":"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815","title":"Swap \uba54\ubaa8\ub9ac \uc124\uc815","description":"Swap \uba54\ubaa8\ub9ac","sidebar":"tutorialSidebar"},"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815":{"id":"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","title":"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","description":"\uacc4\uc815 \ubcc4 \ud130\ubbf8\ub110 \uc124\uc815","sidebar":"tutorialSidebar"},"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131":{"id":"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","title":"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","description":"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4","sidebar":"tutorialSidebar"},"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c":{"id":"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","title":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","description":"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)","sidebar":"tutorialSidebar"},"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec":{"id":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","title":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","description":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","sidebar":"tutorialSidebar"},"\uc124\uacc4/\ud328\ud0a4\uc9c0":{"id":"\uc124\uacc4/\ud328\ud0a4\uc9c0","title":"\ud328\ud0a4\uc9c0","description":"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0","sidebar":"tutorialSidebar"},"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12":{"id":"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12","title":"Throughput \ubaa9\ud46f\uac12","description":"Throughput","sidebar":"tutorialSidebar"},"\uc131\ub2a5/Throughput\uacfc Latency":{"id":"\uc131\ub2a5/Throughput\uacfc Latency","title":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","description":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","sidebar":"tutorialSidebar"},"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8":{"id":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615","description":"| \ud14c\uc2a4\ud2b8 | \uc124\uba85 |","sidebar":"tutorialSidebar"},"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5":{"id":"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","title":"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","description":"\uc2a4\ud504\ub9c1\uc758 \ud575\uc2ec \uac1c\ubc1c\uc790\ub4e4\uc774 \uc4f4 Professional Spring Framework \ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc758 \uc815\uc218(essence)\ub294 \\"\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\ub294 \uac83\\" \uc774\ub77c\uace0 \ud588\ub2e4.","sidebar":"tutorialSidebar"},"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98":{"id":"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","title":"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","description":"\uac1c\uc694","sidebar":"tutorialSidebar"},"\ud14c\uc2a4\ud2b8/FIRST":{"id":"\ud14c\uc2a4\ud2b8/FIRST","title":"FIRST","description":"FIRST\ub780?","sidebar":"tutorialSidebar"},"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8":{"id":"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","title":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","description":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)","sidebar":"tutorialSidebar"},"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59":{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59","title":"TDD heuristics","description":"TDD heuristics","sidebar":"tutorialSidebar"},"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd":{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","title":"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","description":"\ub514\ubc84\uae45 \uac10\uc18c","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/9469.e32b0c9d.js b/assets/js/9469.e32b0c9d.js new file mode 100644 index 000000000..c5add7c0d --- /dev/null +++ b/assets/js/9469.e32b0c9d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9469],{9469:(t,e,n)=>{n.d(e,{diagram:()=>O});var i=n(56363),s=n(64218),r=n(91619),a=n(12281),o=n(7201),l=(n(27484),n(17967),n(27856),function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[6,8,10,11,12,14,16,17,20,21],n=[1,9],i=[1,10],s=[1,11],r=[1,12],a=[1,13],o=[1,16],l=[1,17],c={trace:function(){},yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.getCommonDb().setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.getCommonDb().setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 15:i.addTask(r[o],0,""),this.$=r[o];break;case 16:i.addEvent(r[o].substr(2)),this.$=r[o]}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:s,16:r,17:a,18:14,19:15,20:o,21:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:18,11:n,12:i,14:s,16:r,17:a,18:14,19:15,20:o,21:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,19]},{15:[1,20]},t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),t(e,[2,4]),t(e,[2,9]),t(e,[2,10])],defaultActions:{},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",l=0,c=0,h=r.slice.call(arguments,1),d=Object.create(this.lexer),u={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(u.yy[p]=this.yy[p]);d.setInput(t,u.yy),u.yy.lexer=d,u.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var y=d.yylloc;r.push(y);var g=d.options&&d.options.ranges;"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,m,_,b,x,k,v,w,S,$={};;){if(m=n[n.length-1],this.defaultActions[m]?_=this.defaultActions[m]:(null==f&&(S=void 0,"number"!=typeof(S=i.pop()||d.lex()||1)&&(S instanceof Array&&(S=(i=S).pop()),S=e.symbols_[S]||S),f=S),_=a[m]&&a[m][f]),void 0===_||!_.length||!_[0]){var E="";for(x in w=[],a[m])this.terminals_[x]&&x>2&&w.push("'"+this.terminals_[x]+"'");E=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+w.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(E,{text:d.match,token:this.terminals_[f]||f,line:d.yylineno,loc:y,expected:w})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+f);switch(_[0]){case 1:n.push(f),s.push(d.yytext),r.push(d.yylloc),n.push(_[1]),f=null,c=d.yyleng,o=d.yytext,l=d.yylineno,y=d.yylloc;break;case 2:if(k=this.productions_[_[1]][1],$.$=s[s.length-k],$._$={first_line:r[r.length-(k||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(k||1)].first_column,last_column:r[r.length-1].last_column},g&&($._$.range=[r[r.length-(k||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply($,[o,c,l,u.yy,_[1],s,r].concat(h))))return b;k&&(n=n.slice(0,-1*k*2),s=s.slice(0,-1*k),r=r.slice(0,-1*k)),n.push(this.productions_[_[1]][0]),s.push($.$),r.push($._$),v=a[n[n.length-2]][n[n.length-1]],n.push(v);break;case 3:return!0}}return!0}},h={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 21;case 16:return 20;case 17:return 6;case 18:return"INVALID"}},rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?::\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18],inclusive:!0}}};function d(){this.yy={}}return c.lexer=h,d.prototype=c,c.Parser=d,new d}());l.parser=l;const c=l;let h="",d=0;const u=[],p=[],y=[],g=()=>i.K,f=function(){u.length=0,p.length=0,h="",y.length=0,(0,i.t)()},m=function(t){h=t,u.push(t)},_=function(){return u},b=function(){let t=w();let e=0;for(;!t&&e<100;)t=w(),e++;return p.push(...y),p},x=function(t,e,n){const i={id:d++,section:h,type:h,task:t,score:e||0,events:n?[n]:[]};y.push(i)},k=function(t){y.find((t=>t.id===d-1)).events.push(t)},v=function(t){const e={section:h,type:h,description:t,task:t,classes:[]};p.push(e)},w=function(){let t=!0;for(const[e,n]of y.entries())y[e].processed,t=t&&n.processed;return t},S={clear:f,getCommonDb:g,addSection:m,getSections:_,getTasks:b,addTask:x,addTaskOrg:v,addEvent:k},$=Object.freeze(Object.defineProperty({__proto__:null,addEvent:k,addSection:m,addTask:x,addTaskOrg:v,clear:f,default:S,getCommonDb:g,getSections:_,getTasks:b},Symbol.toStringTag,{value:"Module"}));!function(){function t(t,e,n,s,r,a,o,l){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",l).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,l,c){const{taskFontSize:h,taskFontFamily:d}=l,u=t.split(/<br\s*\/?>/gi);for(let p=0;p<u.length;p++){const t=p*h-h*(u.length-1)/2,l=e.append("text").attr("x",n+r/2).attr("y",s).attr("fill",c).style("text-anchor","middle").style("font-size",h).style("font-family",d);l.append("tspan").attr("x",n+r/2).attr("dy",t).text(u[p]),l.attr("y",s+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(l,o)}}function n(t,n,s,r,a,o,l,c){const h=n.append("switch"),d=h.append("foreignObject").attr("x",s).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,r,a,o,l,c),i(d,l)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}}();function E(t,e){t.each((function(){var t,n=(0,s.Ys)(this),i=n.text().split(/(\s+|<br>)/).reverse(),r=[],a=n.attr("y"),o=parseFloat(n.attr("dy")),l=n.text(null).append("tspan").attr("x",0).attr("y",a).attr("dy",o+"em");for(let s=0;s<i.length;s++)t=i[i.length-1-s],r.push(t),l.text(r.join(" ").trim()),(l.node().getComputedTextLength()>e||"<br>"===t)&&(r.pop(),l.text(r.join(" ").trim()),r="<br>"===t?[""]:[t],l=n.append("tspan").attr("x",0).attr("y",a).attr("dy","1.1em").text(t))}))}const I=function(t,e,n){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${10-e.height} q0,-5 5,-5 h${e.width-10} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)},T=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},C=function(t,e,n,i){const s=n%12-1,r=t.append("g");e.section=s,r.attr("class",(e.class?e.class+" ":"")+"timeline-node section-"+s);const a=r.append("g"),o=r.append("g"),l=o.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(E,e.width).node().getBBox(),c=i.fontSize&&i.fontSize.replace?i.fontSize.replace("px",""):i.fontSize;return e.height=l.height+1.1*c*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,o.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),I(a,e,s),e},L=function(t,e,n){const i=t.append("g"),s=i.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(E,e.width).node().getBBox(),r=n.fontSize&&n.fontSize.replace?n.fontSize.replace("px",""):n.fontSize;return i.remove(),s.height+1.1*r*.5+e.padding},A=function(t,e,n,s,r,a,o,l,c,h,d){var u;for(const p of e){const e={descr:p.task,section:n,number:n,width:150,padding:20,maxHeight:a};i.l.debug("taskNode",e);const l=t.append("g").attr("class","taskWrapper"),y=C(l,e,n,o).height;if(i.l.debug("taskHeight after draw",y),l.attr("transform",`translate(${s}, ${r})`),a=Math.max(a,y),p.events){const e=t.append("g").attr("class","lineWrapper");let i=a;r+=100,i+=M(t,p.events,n,s,r,o),r-=100,e.append("line").attr("x1",s+95).attr("y1",r+a).attr("x2",s+95).attr("y2",r+a+(d?a:h)+c+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}s+=200,d&&!(null==(u=o.timeline)?void 0:u.disableMulticolor)&&n++}r-=10},M=function(t,e,n,s,r,a){let o=0;const l=r;r+=100;for(const c of e){const e={descr:c,section:n,number:n,width:150,padding:20,maxHeight:50};i.l.debug("eventNode",e);const l=t.append("g").attr("class","eventWrapper"),h=C(l,e,n,a).height;o+=h,l.attr("transform",`translate(${s}, ${r})`),r=r+10+h}return r=l,o},O={db:$,renderer:{setConf:()=>{},draw:function(t,e,n,r){var a,o;const l=(0,i.c)(),c=l.leftMargin??50;i.l.debug("timeline",r.db);const h=l.securityLevel;let d;"sandbox"===h&&(d=(0,s.Ys)("#i"+e));const u=("sandbox"===h?(0,s.Ys)(d.nodes()[0].contentDocument.body):(0,s.Ys)("body")).select("#"+e);u.append("g");const p=r.db.getTasks(),y=r.db.getCommonDb().getDiagramTitle();i.l.debug("task",p),T(u);const g=r.db.getSections();i.l.debug("sections",g);let f=0,m=0,_=0,b=0,x=50+c,k=50;b=50;let v=0,w=!0;g.forEach((function(t){const e=L(u,{number:v,descr:t,section:v,width:150,padding:20,maxHeight:f},l);i.l.debug("sectionHeight before draw",e),f=Math.max(f,e+20)}));let S=0,$=0;i.l.debug("tasks.length",p.length);for(const[s,I]of p.entries()){const t={number:s,descr:I,section:I.section,width:150,padding:20,maxHeight:m},e=L(u,t,l);i.l.debug("taskHeight before draw",e),m=Math.max(m,e+20),S=Math.max(S,I.events.length);let n=0;for(let i=0;i<I.events.length;i++){const t={descr:I.events[i],section:I.section,number:I.section,width:150,padding:20,maxHeight:50};n+=L(u,t,l)}$=Math.max($,n)}i.l.debug("maxSectionHeight before draw",f),i.l.debug("maxTaskHeight before draw",m),g&&g.length>0?g.forEach((t=>{const e=p.filter((e=>e.section===t)),n={number:v,descr:t,section:v,width:200*Math.max(e.length,1)-50,padding:20,maxHeight:f};i.l.debug("sectionNode",n);const s=u.append("g"),r=C(s,n,v,l);i.l.debug("sectionNode output",r),s.attr("transform",`translate(${x}, 50)`),k+=f+50,e.length>0&&A(u,e,v,x,k,m,l,S,$,f,!1),x+=200*Math.max(e.length,1),k=50,v++})):(w=!1,A(u,p,v,x,k,m,l,S,$,f,!0));const E=u.node().getBBox();i.l.debug("bounds",E),y&&u.append("text").text(y).attr("x",E.width/2-c).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),_=w?f+m+150:m+100;u.append("g").attr("class","lineWrapper").append("line").attr("x1",c).attr("y1",_).attr("x2",E.width+3*c).attr("y2",_).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),(0,i.o)(void 0,u,(null==(a=l.timeline)?void 0:a.padding)??50,(null==(o=l.timeline)?void 0:o.useMaxWidth)??!1)}},parser:c,styles:t=>`\n .edge {\n stroke-width: 3;\n }\n ${(t=>{let e="";for(let n=0;n<t.THEME_COLOR_LIMIT;n++)t["lineColor"+n]=t["lineColor"+n]||t["cScaleInv"+n],(0,r.Z)(t["lineColor"+n])?t["lineColor"+n]=(0,a.Z)(t["lineColor"+n],20):t["lineColor"+n]=(0,o.Z)(t["lineColor"+n],20);for(let n=0;n<t.THEME_COLOR_LIMIT;n++){const i=""+(17-3*n);e+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} path {\n fill: ${t["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${t["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${t["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${t["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${i};\n }\n .section-${n-1} line {\n stroke: ${t["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .lineWrapper line{\n stroke: ${t["cScaleLabel"+n]} ;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return e})(t)}\n .section-root rect, .section-root path, .section-root circle {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .eventWrapper {\n filter: brightness(120%);\n }\n`}}}]); \ No newline at end of file diff --git a/assets/js/9816.71ee2fb3.js b/assets/js/9816.71ee2fb3.js new file mode 100644 index 000000000..c491eab55 --- /dev/null +++ b/assets/js/9816.71ee2fb3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9816],{9816:(t,e,a)=>{a.d(e,{diagram:()=>b});var i=a(52244),n=a(64218),d=a(41644),r=a(45625),s=a(56363);a(27484),a(17967),a(27856);const o={},c=(t,e)=>{o[t]=e},g=(t,e)=>{const a=t.append("text").attr("x",2*(0,s.c)().state.padding).attr("y",(0,s.c)().state.textHeight+1.3*(0,s.c)().state.padding).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),i=a.height,n=t.append("text").attr("x",(0,s.c)().state.padding).attr("y",i+.4*(0,s.c)().state.padding+(0,s.c)().state.dividerMargin+(0,s.c)().state.textHeight).attr("class","state-description");let d=!0,r=!0;e.descriptions.forEach((function(t){d||(!function(t,e,a){const i=t.append("tspan").attr("x",2*(0,s.c)().state.padding).text(e);a||i.attr("dy",(0,s.c)().state.textHeight)}(n,t,r),r=!1),d=!1}));const o=t.append("line").attr("x1",(0,s.c)().state.padding).attr("y1",(0,s.c)().state.padding+i+(0,s.c)().state.dividerMargin/2).attr("y2",(0,s.c)().state.padding+i+(0,s.c)().state.dividerMargin/2).attr("class","descr-divider"),c=n.node().getBBox(),g=Math.max(c.width,a.width);return o.attr("x2",g+3*(0,s.c)().state.padding),t.insert("rect",":first-child").attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding).attr("width",g+2*(0,s.c)().state.padding).attr("height",c.height+i+2*(0,s.c)().state.padding).attr("rx",(0,s.c)().state.radius),t},p=(t,e,a)=>{const i=(0,s.c)().state.padding,n=2*(0,s.c)().state.padding,d=t.node().getBBox(),r=d.width,o=d.x,c=t.append("text").attr("x",0).attr("y",(0,s.c)().state.titleShift).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.id),g=c.node().getBBox().width+n;let p,h=Math.max(g,r);h===r&&(h+=n);const l=t.node().getBBox();e.doc,p=o-i,g>r&&(p=(r-h)/2+i),Math.abs(o-l.x)<i&&g>r&&(p=o-(g-r)/2);const x=1-(0,s.c)().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",x).attr("class",a?"alt-composit":"composit").attr("width",h).attr("height",l.height+(0,s.c)().state.textHeight+(0,s.c)().state.titleShift+1).attr("rx","0"),c.attr("x",p+i),g<=r&&c.attr("x",o+(h-n)/2-g/2+i),t.insert("rect",":first-child").attr("x",p).attr("y",(0,s.c)().state.titleShift-(0,s.c)().state.textHeight-(0,s.c)().state.padding).attr("width",h).attr("height",3*(0,s.c)().state.textHeight).attr("rx",(0,s.c)().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",(0,s.c)().state.titleShift-(0,s.c)().state.textHeight-(0,s.c)().state.padding).attr("width",h).attr("height",l.height+3+2*(0,s.c)().state.textHeight).attr("rx",(0,s.c)().state.radius),t},h=(t,e)=>{e.attr("class","state-note");const a=e.append("rect").attr("x",0).attr("y",(0,s.c)().state.padding),i=e.append("g"),{textWidth:n,textHeight:d}=((t,e,a,i)=>{let n=0;const d=i.append("text");d.style("text-anchor","start"),d.attr("class","noteText");let r=t.replace(/\r\n/g,"<br/>");r=r.replace(/\n/g,"<br/>");const o=r.split(s.e.lineBreakRegex);let c=1.25*(0,s.c)().state.noteMargin;for(const g of o){const t=g.trim();if(t.length>0){const i=d.append("tspan");i.text(t),0===c&&(c+=i.node().getBBox().height),n+=c,i.attr("x",e+(0,s.c)().state.noteMargin),i.attr("y",a+n+1.25*(0,s.c)().state.noteMargin)}}return{textWidth:d.node().getBBox().width,textHeight:n}})(t,0,0,i);return a.attr("height",d+2*(0,s.c)().state.noteMargin),a.attr("width",n+2*(0,s.c)().state.noteMargin),a},l=function(t,e){const a=e.id,i={id:a,label:e.id,width:0,height:0},n=t.append("g").attr("id",a).attr("class","stateGroup");"start"===e.type&&(t=>{t.append("circle").attr("class","start-state").attr("r",(0,s.c)().state.sizeUnit).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit)})(n),"end"===e.type&&(t=>{t.append("circle").attr("class","end-state-outer").attr("r",(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+(0,s.c)().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",(0,s.c)().state.sizeUnit).attr("cx",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+2).attr("cy",(0,s.c)().state.padding+(0,s.c)().state.sizeUnit+2)})(n),"fork"!==e.type&&"join"!==e.type||((t,e)=>{let a=(0,s.c)().state.forkWidth,i=(0,s.c)().state.forkHeight;if(e.parentId){let t=a;a=i,i=t}t.append("rect").style("stroke","black").style("fill","black").attr("width",a).attr("height",i).attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding)})(n,e),"note"===e.type&&h(e.note.text,n),"divider"===e.type&&(t=>{t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",(0,s.c)().state.textHeight).attr("class","divider").attr("x2",2*(0,s.c)().state.textHeight).attr("y1",0).attr("y2",0)})(n),"default"===e.type&&0===e.descriptions.length&&((t,e)=>{const a=t.append("text").attr("x",2*(0,s.c)().state.padding).attr("y",(0,s.c)().state.textHeight+2*(0,s.c)().state.padding).attr("font-size",(0,s.c)().state.fontSize).attr("class","state-title").text(e.id),i=a.node().getBBox();t.insert("rect",":first-child").attr("x",(0,s.c)().state.padding).attr("y",(0,s.c)().state.padding).attr("width",i.width+2*(0,s.c)().state.padding).attr("height",i.height+2*(0,s.c)().state.padding).attr("rx",(0,s.c)().state.radius)})(n,e),"default"===e.type&&e.descriptions.length>0&&g(n,e);const d=n.node().getBBox();return i.width=d.width+2*(0,s.c)().state.padding,i.height=d.height+2*(0,s.c)().state.padding,c(a,i),i};let x=0;let u;const f={},y=(t,e,a,o,c,g,h)=>{const w=new r.k({compound:!0,multigraph:!0});let b,m=!0;for(b=0;b<t.length;b++)if("relation"===t[b].stmt){m=!1;break}a?w.setGraph({rankdir:"LR",multigraph:!0,compound:!0,ranker:"tight-tree",ranksep:m?1:u.edgeLengthFactor,nodeSep:m?1:50,isMultiGraph:!0}):w.setGraph({rankdir:"TB",multigraph:!0,compound:!0,ranksep:m?1:u.edgeLengthFactor,nodeSep:m?1:50,ranker:"tight-tree",isMultiGraph:!0}),w.setDefaultEdgeLabel((function(){return{}})),h.db.extract(t);const B=h.db.getStates(),k=h.db.getRelations(),N=Object.keys(B);for(const i of N){const t=B[i];let n;if(a&&(t.parentId=a),t.doc){let a=e.append("g").attr("id",t.id).attr("class","stateGroup");n=y(t.doc,a,t.id,!o,c,g,h);{a=p(a,t,o);let e=a.node().getBBox();n.width=e.width,n.height=e.height+u.padding/2,f[t.id]={y:u.compositTitleSize}}}else n=l(e,t);if(t.note){const a={descriptions:[],id:t.id+"-note",note:t.note,type:"note"},i=l(e,a);"left of"===t.note.position?(w.setNode(n.id+"-note",i),w.setNode(n.id,n)):(w.setNode(n.id,n),w.setNode(n.id+"-note",i)),w.setParent(n.id,n.id+"-group"),w.setParent(n.id+"-note",n.id+"-group")}else w.setNode(n.id,n)}s.l.debug("Count=",w.nodeCount(),w);let E=0;k.forEach((function(t){var e;E++,s.l.debug("Setting edge",t),w.setEdge(t.id1,t.id2,{relation:t,width:(e=t.title,e?e.length*u.fontSizeFactor:1),height:u.labelHeight*s.e.getRows(t.title).length,labelpos:"c"},"id"+E)})),(0,d.bK)(w),s.l.debug("Graph after layout",w.nodes());const M=e.node();w.nodes().forEach((function(t){if(void 0!==t&&void 0!==w.node(t)){s.l.warn("Node "+t+": "+JSON.stringify(w.node(t))),c.select("#"+M.id+" #"+t).attr("transform","translate("+(w.node(t).x-w.node(t).width/2)+","+(w.node(t).y+(f[t]?f[t].y:0)-w.node(t).height/2)+" )"),c.select("#"+M.id+" #"+t).attr("data-x-shift",w.node(t).x-w.node(t).width/2);g.querySelectorAll("#"+M.id+" #"+t+" .divider").forEach((t=>{const e=t.parentElement;let a=0,i=0;e&&(e.parentElement&&(a=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",a-i-8)}))}else s.l.debug("No Node "+t+": "+JSON.stringify(w.node(t)))}));let v=M.getBBox();w.edges().forEach((function(t){void 0!==t&&void 0!==w.edge(t)&&(s.l.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(w.edge(t))),function(t,e,a){e.points=e.points.filter((t=>!Number.isNaN(t.y)));const d=e.points,r=(0,n.jvg)().x((function(t){return t.x})).y((function(t){return t.y})).curve(n.$0Z),o=t.append("path").attr("d",r(d)).attr("id","edge"+x).attr("class","transition");let c="";if((0,s.c)().state.arrowMarkerAbsolute&&(c=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,c=c.replace(/\(/g,"\\("),c=c.replace(/\)/g,"\\)")),o.attr("marker-end","url("+c+"#"+function(t){switch(t){case i.d.relationType.AGGREGATION:return"aggregation";case i.d.relationType.EXTENSION:return"extension";case i.d.relationType.COMPOSITION:return"composition";case i.d.relationType.DEPENDENCY:return"dependency"}}(i.d.relationType.DEPENDENCY)+"End)"),void 0!==a.title){const i=t.append("g").attr("class","stateLabel"),{x:n,y:d}=s.u.calcLabelPosition(e.points),r=s.e.getRows(a.title);let o=0;const c=[];let g=0,p=0;for(let t=0;t<=r.length;t++){const e=i.append("text").attr("text-anchor","middle").text(r[t]).attr("x",n).attr("y",d+o),a=e.node().getBBox();if(g=Math.max(g,a.width),p=Math.min(p,a.x),s.l.info(a.x,n,d+o),0===o){const t=e.node().getBBox();o=t.height,s.l.info("Title height",o,d)}c.push(e)}let h=o*r.length;if(r.length>1){const t=(r.length-1)*o*.5;c.forEach(((e,a)=>e.attr("y",d+a*o-t))),h=o*r.length}const l=i.node().getBBox();i.insert("rect",":first-child").attr("class","box").attr("x",n-g/2-(0,s.c)().state.padding/2).attr("y",d-h/2-(0,s.c)().state.padding/2-3.5).attr("width",g+(0,s.c)().state.padding).attr("height",h+(0,s.c)().state.padding),s.l.info(l)}x++}(e,w.edge(t),w.edge(t).relation))})),v=M.getBBox();const S={id:a||"root",label:a||"root",width:0,height:0};return S.width=v.width+2*u.padding,S.height=v.height+2*u.padding,s.l.debug("Doc rendered",S,w),S},w={setConf:function(){},draw:function(t,e,a,i){u=(0,s.c)().state;const d=(0,s.c)().securityLevel;let r;"sandbox"===d&&(r=(0,n.Ys)("#i"+e));const o="sandbox"===d?(0,n.Ys)(r.nodes()[0].contentDocument.body):(0,n.Ys)("body"),c="sandbox"===d?r.nodes()[0].contentDocument:document;s.l.debug("Rendering diagram "+t);const g=o.select(`[id='${e}']`);g.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z");const p=i.db.getRootDoc();y(p,g,void 0,!1,o,c,i);const h=u.padding,l=g.node().getBBox(),x=l.width+2*h,f=l.height+2*h,w=1.75*x;(0,s.i)(g,f,w,u.useMaxWidth),g.attr("viewBox",`${l.x-u.padding} ${l.y-u.padding} `+x+" "+f)}},b={parser:i.p,db:i.d,renderer:w,styles:i.s,init:t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,i.d.clear()}}}}]); \ No newline at end of file diff --git a/assets/js/981f7647.86256e1a.js b/assets/js/981f7647.86256e1a.js new file mode 100644 index 000000000..d068e6c90 --- /dev/null +++ b/assets/js/981f7647.86256e1a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2947],{52070:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var n=r(85893),a=r(3905);const i={title:"\ud328\ud0a4\uc9c0",slug:"/design/package",last_update:{date:"2023/05/31"},tags:["package"]},c=void 0,o={id:"\uc124\uacc4/\ud328\ud0a4\uc9c0",title:"\ud328\ud0a4\uc9c0",description:"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0",source:"@site/docs/\uc124\uacc4/\ud328\ud0a4\uc9c0.mdx",sourceDirName:"\uc124\uacc4",slug:"/design/package",permalink:"/docs/design/package",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc124\uacc4/\ud328\ud0a4\uc9c0.mdx",tags:[{label:"package",permalink:"/docs/tags/package"}],version:"current",lastUpdatedAt:1685491200,formattedLastUpdatedAt:"2023\ub144 5\uc6d4 31\uc77c",frontMatter:{title:"\ud328\ud0a4\uc9c0",slug:"/design/package",last_update:{date:"2023/05/31"},tags:["package"]},sidebar:"tutorialSidebar",previous:{title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",permalink:"/docs/deploy/zero-downtime"},next:{title:"Throughput \ubaa9\ud46f\uac12",permalink:"/docs/performance/throughput"}},s={},l=[{value:"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0",id:"\uacc4\uce35-\uae30\ubc18-\ud328\ud0a4\uc9c0",level:3},{value:"\uae30\ub2a5 \uae30\ubc18 \ud328\ud0a4\uc9c0",id:"\uae30\ub2a5-\uae30\ubc18-\ud328\ud0a4\uc9c0",level:3},{value:"\ud3ec\ud2b8\uc640 \uc5b4\ub311\ud130",id:"\ud3ec\ud2b8\uc640-\uc5b4\ub311\ud130",level:3},{value:"\ucef4\ud3ec\ub10c\ud2b8 \uae30\ubc18 \ud328\ud0a4\uc9c0",id:"\ucef4\ud3ec\ub10c\ud2b8-\uae30\ubc18-\ud328\ud0a4\uc9c0",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const t={br:"br",h3:"h3",p:"p",...(0,a.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uacc4\uce35-\uae30\ubc18-\ud328\ud0a4\uc9c0",children:"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0"}),"\n",(0,n.jsxs)(t.p,{children:["\uc804\ud1b5\uc801\uc778 \uc218\ud3c9 \uacc4\uce35\ud615 \uc544\ud0a4\ud14d\ucc98",(0,n.jsx)(t.br,{}),"\n","\uae30\uc220\uc801\uc778 \uad00\uc810\uc5d0\uc11c \ud574\ub2f9 \ucf54\ub4dc\uac00 \ud558\ub294 \uc77c\uc5d0 \uae30\ubc18\ud574 \ucf54\ub4dc\ub97c \ubd84\ud560"]}),"\n",(0,n.jsx)(t.h3,{id:"\uae30\ub2a5-\uae30\ubc18-\ud328\ud0a4\uc9c0",children:"\uae30\ub2a5 \uae30\ubc18 \ud328\ud0a4\uc9c0"}),"\n",(0,n.jsx)(t.p,{children:"\uc11c\ub85c \uc5f0\uad00\ub41c \uae30\ub2a5, \ub3c4\uba54\uc778 \uac1c\ub150, \ub610\ub294 Aggregate Root\uc5d0 \uae30\ubc18\ud558\uc5ec \uc218\uc9c1\uc758 \uc587\uc740 \uc870\uac01\uc73c\ub85c \ucf54\ub4dc\ub97c \ub098\ub204\ub294 \ubc29\uc2dd"}),"\n",(0,n.jsx)(t.h3,{id:"\ud3ec\ud2b8\uc640-\uc5b4\ub311\ud130",children:"\ud3ec\ud2b8\uc640 \uc5b4\ub311\ud130"}),"\n",(0,n.jsx)(t.p,{children:"\uc5c5\ubb34/\ub3c4\uba54\uc778\uc5d0 \ucd08\uc810\uc744 \ub454 \ucf54\ub4dc\uac00 \ud504\ub808\uc784\uc6cc\ud06c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac19\uc740 \uae30\uc220\uc801\uc778 \uc138\ubd80 \uad6c\ud604\uacfc \ub3c5\ub9bd\uc801\uc774\uba70 \ubd84\ub9ac\ub41c \uc544\ud0a4\ud14d\ucc98\ub97c \ub9cc\ub4e4\uae30 \uc704\ud574 \uc0ac\uc6a9"}),"\n",(0,n.jsx)(t.h3,{id:"\ucef4\ud3ec\ub10c\ud2b8-\uae30\ubc18-\ud328\ud0a4\uc9c0",children:"\ucef4\ud3ec\ub10c\ud2b8 \uae30\ubc18 \ud328\ud0a4\uc9c0"}),"\n",(0,n.jsxs)(t.p,{children:["\ud070 \ub2e8\uc704\uc758 \ub2e8\uc77c \ucef4\ud3ec\ub10c\ud2b8\uc640 \uad00\ub828\ub41c \ubaa8\ub4e0 \ucc45\uc784\uc744 \ud558\ub098\uc758 \uc790\ubc14 \ud328\ud0a4\uc9c0\ub85c \ubb36\ub294 \ub370 \uc8fc\uc548\uc810\uc744 \ub460",(0,n.jsx)(t.br,{}),"\n","\ubaa8\ub178\ub9ac\ud2f1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \ucef4\ud3ec\ub10c\ud2b8\ub97c \uc798 \uc815\uc758\ud558\uba74 MSA\ub85c \uac00\uae30 \uc704\ud55c \ubc1c\ud310\uc73c\ub85c \uc0bc\uc744 \uc218 \uc788\uc74c"]}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsx)(t.p,{children:"\ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 p.316"})]})}function d(e={}){const{wrapper:t}={...(0,a.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),u=l(r),g=a,f=u["".concat(s,".").concat(g)]||u[g]||p[g]||i;return r?n.createElement(f,c(c({ref:t},d),{},{components:r})):n.createElement(f,c({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/981f7647.b7830cd7.js b/assets/js/981f7647.b7830cd7.js deleted file mode 100644 index 8c8184dbf..000000000 --- a/assets/js/981f7647.b7830cd7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2947],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=c(r),f=a,g=d["".concat(p,".").concat(f)]||d[f]||s[f]||o;return r?n.createElement(g,l(l({ref:t},u),{},{components:r})):n.createElement(g,l({ref:t},u))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c<o;c++)l[c]=r[c];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},51077:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>s,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"\ud328\ud0a4\uc9c0",slug:"/design/package",last_update:{date:"2023/05/31"},tags:["package"]},l=void 0,i={unversionedId:"\uc124\uacc4/\ud328\ud0a4\uc9c0",id:"\uc124\uacc4/\ud328\ud0a4\uc9c0",title:"\ud328\ud0a4\uc9c0",description:"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0",source:"@site/docs/\uc124\uacc4/\ud328\ud0a4\uc9c0.mdx",sourceDirName:"\uc124\uacc4",slug:"/design/package",permalink:"/docs/design/package",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc124\uacc4/\ud328\ud0a4\uc9c0.mdx",tags:[{label:"package",permalink:"/docs/tags/package"}],version:"current",lastUpdatedAt:1685491200,formattedLastUpdatedAt:"2023\ub144 5\uc6d4 31\uc77c",frontMatter:{title:"\ud328\ud0a4\uc9c0",slug:"/design/package",last_update:{date:"2023/05/31"},tags:["package"]},sidebar:"tutorialSidebar",previous:{title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",permalink:"/docs/deploy/zero-downtime"},next:{title:"Throughput \ubaa9\ud46f\uac12",permalink:"/docs/performance/throughput"}},p={},c=[{value:"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0",id:"\uacc4\uce35-\uae30\ubc18-\ud328\ud0a4\uc9c0",level:3},{value:"\uae30\ub2a5 \uae30\ubc18 \ud328\ud0a4\uc9c0",id:"\uae30\ub2a5-\uae30\ubc18-\ud328\ud0a4\uc9c0",level:3},{value:"\ud3ec\ud2b8\uc640 \uc5b4\ub311\ud130",id:"\ud3ec\ud2b8\uc640-\uc5b4\ub311\ud130",level:3},{value:"\ucef4\ud3ec\ub10c\ud2b8 \uae30\ubc18 \ud328\ud0a4\uc9c0",id:"\ucef4\ud3ec\ub10c\ud2b8-\uae30\ubc18-\ud328\ud0a4\uc9c0",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uacc4\uce35-\uae30\ubc18-\ud328\ud0a4\uc9c0"},"\uacc4\uce35 \uae30\ubc18 \ud328\ud0a4\uc9c0"),(0,a.kt)("p",null,"\uc804\ud1b5\uc801\uc778 \uc218\ud3c9 \uacc4\uce35\ud615 \uc544\ud0a4\ud14d\ucc98",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc220\uc801\uc778 \uad00\uc810\uc5d0\uc11c \ud574\ub2f9 \ucf54\ub4dc\uac00 \ud558\ub294 \uc77c\uc5d0 \uae30\ubc18\ud574 \ucf54\ub4dc\ub97c \ubd84\ud560"),(0,a.kt)("h3",{id:"\uae30\ub2a5-\uae30\ubc18-\ud328\ud0a4\uc9c0"},"\uae30\ub2a5 \uae30\ubc18 \ud328\ud0a4\uc9c0"),(0,a.kt)("p",null,"\uc11c\ub85c \uc5f0\uad00\ub41c \uae30\ub2a5, \ub3c4\uba54\uc778 \uac1c\ub150, \ub610\ub294 Aggregate Root\uc5d0 \uae30\ubc18\ud558\uc5ec \uc218\uc9c1\uc758 \uc587\uc740 \uc870\uac01\uc73c\ub85c \ucf54\ub4dc\ub97c \ub098\ub204\ub294 \ubc29\uc2dd"),(0,a.kt)("h3",{id:"\ud3ec\ud2b8\uc640-\uc5b4\ub311\ud130"},"\ud3ec\ud2b8\uc640 \uc5b4\ub311\ud130"),(0,a.kt)("p",null,"\uc5c5\ubb34/\ub3c4\uba54\uc778\uc5d0 \ucd08\uc810\uc744 \ub454 \ucf54\ub4dc\uac00 \ud504\ub808\uc784\uc6cc\ud06c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac19\uc740 \uae30\uc220\uc801\uc778 \uc138\ubd80 \uad6c\ud604\uacfc \ub3c5\ub9bd\uc801\uc774\uba70 \ubd84\ub9ac\ub41c \uc544\ud0a4\ud14d\ucc98\ub97c \ub9cc\ub4e4\uae30 \uc704\ud574 \uc0ac\uc6a9"),(0,a.kt)("h3",{id:"\ucef4\ud3ec\ub10c\ud2b8-\uae30\ubc18-\ud328\ud0a4\uc9c0"},"\ucef4\ud3ec\ub10c\ud2b8 \uae30\ubc18 \ud328\ud0a4\uc9c0"),(0,a.kt)("p",null,"\ud070 \ub2e8\uc704\uc758 \ub2e8\uc77c \ucef4\ud3ec\ub10c\ud2b8\uc640 \uad00\ub828\ub41c \ubaa8\ub4e0 \ucc45\uc784\uc744 \ud558\ub098\uc758 \uc790\ubc14 \ud328\ud0a4\uc9c0\ub85c \ubb36\ub294 \ub370 \uc8fc\uc548\uc810\uc744 \ub460",(0,a.kt)("br",{parentName:"p"}),"\n","\ubaa8\ub178\ub9ac\ud2f1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \ucef4\ud3ec\ub10c\ud2b8\ub97c \uc798 \uc815\uc758\ud558\uba74 MSA\ub85c \uac00\uae30 \uc704\ud55c \ubc1c\ud310\uc73c\ub85c \uc0bc\uc744 \uc218 \uc788\uc74c"),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 p.316"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9b43eac8.4b06c7e4.js b/assets/js/9b43eac8.4b06c7e4.js deleted file mode 100644 index 6ebe3c655..000000000 --- a/assets/js/9b43eac8.4b06c7e4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9286],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=c(r),b=a,f=m["".concat(i,".").concat(b)]||m[b]||s[b]||o;return r?n.createElement(f,p(p({ref:t},u),{},{components:r})):n.createElement(f,p({ref:t},u))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,p=new Array(o);p[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,p[1]=l;for(var c=2;c<o;c++)p[c]=r[c];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},44284:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>s,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"2022\ub144 \ud68c\uace0",slug:"2022-retrospective",tags:["Retrospective"]},p=void 0,l={permalink:"/2022-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",title:"2022\ub144 \ud68c\uace0",description:"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70",date:"2023-01-02T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 2\uc77c",tags:[{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.705,hasTruncateMarker:!1,authors:[],frontMatter:{title:"2022\ub144 \ud68c\uace0",slug:"2022-retrospective",tags:["Retrospective"]},prevItem:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",permalink:"/the-essence-of-object-orientation"},nextItem:{title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",permalink:"/book-writer"}},i={authorsImageUrls:[]},c=[{value:"\uc804\uc5ed",id:"\uc804\uc5ed",level:3},{value:"\uc790\ubc14",id:"\uc790\ubc14",level:3},{value:"\uc2a4\ud130\ub514",id:"\uc2a4\ud130\ub514",level:3},{value:"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4",id:"\uc6b0\uc544\ud55c-\ud14c\ud06c\ucf54\uc2a4",level:3},{value:"2023\ub144\uc5d0\ub294",id:"2023\ub144\uc5d0\ub294",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70 "),(0,a.kt)("h3",{id:"\uc804\uc5ed"},"\uc804\uc5ed"),(0,a.kt)("p",null,"\uc57d 1\ub144 6\uac1c\uc6d4\uac04\uc758 \uacf5\uad70 \uc815\ubcf4\ubcf4\ud638\ubcd1 \uc0dd\ud65c\uc744 \ub9c8\uce58\uace0 \uc804\uc5ed\uc744 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc870\uae30 \uc804\uc5ed \ub54c\ubb38\uc5d0 2021\ub144 12\uc6d4\uc5d0 \ub098\uc654\uc9c0\ub9cc, \uc2e4\uc81c \uc804\uc5ed \ub0a0\uc9dc\ub294 2022\ub144\uc774\ub2c8 \ud68c\uace0\uc5d0 \uc801\uc5b4\ub3c4 \uc0c1\uad00\uc5c6\uaca0\uc9c0. "),(0,a.kt)("p",null,"\uc870\uae08 \ub354 \ubbf8\ub798\uc5d0 \ub300\ud55c \uc0dd\uac01\uc744 \ud574\ubcfc\uac78 \uadf8\ub7ac\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc804\uc5ed\uc744 \ud588\uc9c0\ub9cc \ubb50 \ud558\ub098 \uc81c\ub300\ub85c \ud560 \uc904 \uc544\ub294 \uac83\ub3c4 \uc5c6\uc73c\ub2c8 \ub113\uc740 \ubc14\ub2f7\uc18d\uc5d0 \ub369\uadf8\ub7ec\ub2c8 \ub193\uc544\uc9c4 \uae30\ubd84\uc774 \uad1c\ud788 \ub4e4\uc5c8\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ucc0d \uc0dd\uac01\uc744 \uc815\ub9ac\ud558\uc5ec \ubc29\ud5a5\uc744 \uc7a1\uc9c0 \ubabb\ud588\uae30\uc5d0 \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub0a8\uc558\ub2e4. "),(0,a.kt)("h3",{id:"\uc790\ubc14"},"\uc790\ubc14"),(0,a.kt)("p",null,"\uc804\uc5ed\uc744 \ud558\uace0 \uc9c4\ub85c\ub97c \uace0\ubbfc\ud558\ub2e4 \ud5a5\ub85c\ub2d8\uc758 ",(0,a.kt)("a",{parentName:"p",href:"https://jojoldu.tistory.com/609"},"\uc790\ubc14 \uacf5\ud654\uad6d")," \ud3ec\uc2a4\ud305\uc744 \uc77d\uace0 \ub098\uc11c \uc790\ubc14 \uacf5\ubd80\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc720\uba85\ud55c \uc778\ud504\ub7f0\uc758 \uae40\uc601\ud55c\ub2d8\uc758 \uc2a4\ud504\ub9c1 \uac15\uc758\ub3c4 \uc788\uace0, \uc88b\uc740 \uc790\ubc14 \uac1c\ubc1c \uc11c\uc801\uc774 \ub9ce\uc544\uc11c \ub3c5\ud559\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\ub2e4 \ubcf4\ub2c8 \uc790\ubc14\uc640 \uc2a4\ud504\ub9c1\uc744 \uacf5\ubd80\ud558\uba74\uc11c \u201c\uc65c \uc9c4\uc791\ud558\uc9c0 \uc54a\uc558\uc9c0\u201d\ub77c\ub294 \uc0dd\uac01\ub3c4 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc591\uc9c8\uc758 \uc790\ub8cc\ub3c4 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0, \uc608\uc804\uc5d0 \ub178\ub4dc\ub85c \uac1c\ubc1c\ud588\uc744 \ub54c \ud480\uc9c0 \ubabb\ud588\ub358 \ub2f5\ub2f5\ud568\uc744 \ub9ce\uc774 \ud574\uc18c\ud588\ub358 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,"23\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae4a\uac8c \uc790\ubc14\ub97c \uacf5\ubd80\ud574\ubcfc \uc0dd\uac01\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc5b8\uc5b4\ub97c \ud558\ub098 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ub9ce\uc740 \ub3c4\uc6c0\uc774 \ub418\ub294 \uac83 \uac19\ub2e4."),(0,a.kt)("h3",{id:"\uc2a4\ud130\ub514"},"\uc2a4\ud130\ub514"),(0,a.kt)("p",null,"\uae40\uc601\ud55c\ub2d8\uc758 \uac15\uc758\ub97c \uac70\uc758 \ub2e4 \ub4e4\uc5c8\uc744 \ub54c\ucbe4, \ud56d\uc0c1 \uac15\uc758\uc5d0\uc11c \uc5b8\uae09\ub418\ub294 \ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1\uc744 \uc77d\uc5b4\ubcf4\uace0 \uc2f6\uc5b4\uc84c\uace0",(0,a.kt)("br",{parentName:"p"}),"\n","\ud63c\uc790 \uacf5\ubd80\ud558\uae30\uc5d0\ub294 \ub3d9\uae30\ubd80\uc5ec\ub3c4 \ubd80\uc871\ud588\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud130\ub514\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\uc744 \ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uacf5\ubd80\ub97c \ud560 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\uc9c0\ub9cc \ub098\uc5d0\uac8c\ub294 \ub0b4\uc6a9\uc774 \uaf64\ub098 \uc5b4\ub824\uc6cc\uc11c \uc2dc\uac04\uc744 \ub9ce\uc774 \uc18c\ube44\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac19\uc774 \uc2a4\ud130\ub514\ud558\uc2dc\ub294 \ubd84\uacfc 7\uac1c\uc6d4 \ub3d9\uc548 \uc2a4\ud130\ub514\ub97c \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00 \ucd1d 3\uad8c\uc758 \ucc45\uc744 \uc77d\uc744 \uc218 \uc788\uc5c8\ub2e4."),(0,a.kt)("h3",{id:"\uc6b0\uc544\ud55c-\ud14c\ud06c\ucf54\uc2a4"},"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4"),(0,a.kt)("p",null,"\uad70 \ubcf5\ubb34 \uc911\uc77c \ub54c \uc9c0\uc6d0\ud588\ub2e4 \ub5a8\uc5b4\uc9c4 \uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ub2e4\uc2dc \uc9c0\uc6d0\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88 \uc5f0\ub3c4\uc5d0 \ucde8\uc5c5\uc744 \ud558\ub294 \uac8c \ubaa9\ud45c\uc600\uc9c0\ub9cc \ub0b4\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \ud2b9\ubcc4\ud55c \ubb34\uae30\uac00 \uc5c6\ub2e4\ub294 \uac78 \uae68\ub2ec\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc801\uc9c0 \uc54a\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574 \uc900\ube44\ub97c \ud588\uace0, \uac10\uc0ac\ud558\uac8c\ub3c4 \uc774\ubc88\uc5d0\ub294 \ucd5c\uc885 \ud569\uaca9\uc744 \ud588\ub2e4. "),(0,a.kt)("p",null,"\ub09c \uc0ac\ub78c\ub4e4\uacfc \uc18c\ud1b5\ud558\uace0, \ud611\uc5c5\ud558\ub294 \ub2a5\ub825\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ud1b5\ud574 \uadf8 \ube48 \ubd80\ubd84\uc744 \ucc44\uc6b0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"2023\ub144\uc5d0\ub294"},"2023\ub144\uc5d0\ub294"),(0,a.kt)("p",null,"\ub9c8\uc74c\uc758 \uc5ec\uc720\uac00 \uc5c6\uc5c8\ub358 2022\ub144\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uace0 \uc2f6\uc740 \uac74 \ub9ce\uc9c0\ub9cc, \uc774\ubc88\uc5d0\ub294 \uc5ec\uc720\ub97c \uac00\uc9c0\uace0 \ud560 \uc218 \uc788\ub294 \uac83\uc5d0 \ucd5c\uc120\uc744 \ub2e4\ud574\uc57c\uaca0\ub2e4."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9b43eac8.90a09cb8.js b/assets/js/9b43eac8.90a09cb8.js new file mode 100644 index 000000000..dc419d12e --- /dev/null +++ b/assets/js/9b43eac8.90a09cb8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9286],{8617:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var n=t(85893),s=t(3905);const i={title:"2022\ub144 \ud68c\uace0",slug:"2022-retrospective",tags:["Retrospective"]},o=void 0,c={permalink:"/2022-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",title:"2022\ub144 \ud68c\uace0",description:"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70",date:"2023-01-02T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 2\uc77c",tags:[{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.705,hasTruncateMarker:!1,authors:[],frontMatter:{title:"2022\ub144 \ud68c\uace0",slug:"2022-retrospective",tags:["Retrospective"]},unlisted:!1,prevItem:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",permalink:"/the-essence-of-object-orientation"},nextItem:{title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",permalink:"/book-writer"}},l={authorsImageUrls:[]},a=[{value:"\uc804\uc5ed",id:"\uc804\uc5ed",level:3},{value:"\uc790\ubc14",id:"\uc790\ubc14",level:3},{value:"\uc2a4\ud130\ub514",id:"\uc2a4\ud130\ub514",level:3},{value:"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4",id:"\uc6b0\uc544\ud55c-\ud14c\ud06c\ucf54\uc2a4",level:3},{value:"2023\ub144\uc5d0\ub294",id:"2023\ub144\uc5d0\ub294",level:3}];function p(e){const r={a:"a",br:"br",h3:"h3",p:"p",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.p,{children:"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70"}),"\n",(0,n.jsx)(r.h3,{id:"\uc804\uc5ed",children:"\uc804\uc5ed"}),"\n",(0,n.jsxs)(r.p,{children:["\uc57d 1\ub144 6\uac1c\uc6d4\uac04\uc758 \uacf5\uad70 \uc815\ubcf4\ubcf4\ud638\ubcd1 \uc0dd\ud65c\uc744 \ub9c8\uce58\uace0 \uc804\uc5ed\uc744 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc870\uae30 \uc804\uc5ed \ub54c\ubb38\uc5d0 2021\ub144 12\uc6d4\uc5d0 \ub098\uc654\uc9c0\ub9cc, \uc2e4\uc81c \uc804\uc5ed \ub0a0\uc9dc\ub294 2022\ub144\uc774\ub2c8 \ud68c\uace0\uc5d0 \uc801\uc5b4\ub3c4 \uc0c1\uad00\uc5c6\uaca0\uc9c0."]}),"\n",(0,n.jsxs)(r.p,{children:["\uc870\uae08 \ub354 \ubbf8\ub798\uc5d0 \ub300\ud55c \uc0dd\uac01\uc744 \ud574\ubcfc\uac78 \uadf8\ub7ac\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc804\uc5ed\uc744 \ud588\uc9c0\ub9cc \ubb50 \ud558\ub098 \uc81c\ub300\ub85c \ud560 \uc904 \uc544\ub294 \uac83\ub3c4 \uc5c6\uc73c\ub2c8 \ub113\uc740 \ubc14\ub2f7\uc18d\uc5d0 \ub369\uadf8\ub7ec\ub2c8 \ub193\uc544\uc9c4 \uae30\ubd84\uc774 \uad1c\ud788 \ub4e4\uc5c8\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc77c\ucc0d \uc0dd\uac01\uc744 \uc815\ub9ac\ud558\uc5ec \ubc29\ud5a5\uc744 \uc7a1\uc9c0 \ubabb\ud588\uae30\uc5d0 \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub0a8\uc558\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc790\ubc14",children:"\uc790\ubc14"}),"\n",(0,n.jsxs)(r.p,{children:["\uc804\uc5ed\uc744 \ud558\uace0 \uc9c4\ub85c\ub97c \uace0\ubbfc\ud558\ub2e4 \ud5a5\ub85c\ub2d8\uc758 ",(0,n.jsx)(r.a,{href:"https://jojoldu.tistory.com/609",children:"\uc790\ubc14 \uacf5\ud654\uad6d"})," \ud3ec\uc2a4\ud305\uc744 \uc77d\uace0 \ub098\uc11c \uc790\ubc14 \uacf5\ubd80\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc720\uba85\ud55c \uc778\ud504\ub7f0\uc758 \uae40\uc601\ud55c\ub2d8\uc758 \uc2a4\ud504\ub9c1 \uac15\uc758\ub3c4 \uc788\uace0, \uc88b\uc740 \uc790\ubc14 \uac1c\ubc1c \uc11c\uc801\uc774 \ub9ce\uc544\uc11c \ub3c5\ud559\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud558\ub2e4 \ubcf4\ub2c8 \uc790\ubc14\uc640 \uc2a4\ud504\ub9c1\uc744 \uacf5\ubd80\ud558\uba74\uc11c \u201c\uc65c \uc9c4\uc791\ud558\uc9c0 \uc54a\uc558\uc9c0\u201d\ub77c\ub294 \uc0dd\uac01\ub3c4 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc591\uc9c8\uc758 \uc790\ub8cc\ub3c4 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0, \uc608\uc804\uc5d0 \ub178\ub4dc\ub85c \uac1c\ubc1c\ud588\uc744 \ub54c \ud480\uc9c0 \ubabb\ud588\ub358 \ub2f5\ub2f5\ud568\uc744 \ub9ce\uc774 \ud574\uc18c\ud588\ub358 \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["23\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae4a\uac8c \uc790\ubc14\ub97c \uacf5\ubd80\ud574\ubcfc \uc0dd\uac01\uc774\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc5b8\uc5b4\ub97c \ud558\ub098 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ub9ce\uc740 \ub3c4\uc6c0\uc774 \ub418\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc2a4\ud130\ub514",children:"\uc2a4\ud130\ub514"}),"\n",(0,n.jsxs)(r.p,{children:["\uae40\uc601\ud55c\ub2d8\uc758 \uac15\uc758\ub97c \uac70\uc758 \ub2e4 \ub4e4\uc5c8\uc744 \ub54c\ucbe4, \ud56d\uc0c1 \uac15\uc758\uc5d0\uc11c \uc5b8\uae09\ub418\ub294 \ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1\uc744 \uc77d\uc5b4\ubcf4\uace0 \uc2f6\uc5b4\uc84c\uace0",(0,n.jsx)(r.br,{}),"\n","\ud63c\uc790 \uacf5\ubd80\ud558\uae30\uc5d0\ub294 \ub3d9\uae30\ubd80\uc5ec\ub3c4 \ubd80\uc871\ud588\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud130\ub514\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub2e4\ub978 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\uc744 \ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uacf5\ubd80\ub97c \ud560 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\uc9c0\ub9cc \ub098\uc5d0\uac8c\ub294 \ub0b4\uc6a9\uc774 \uaf64\ub098 \uc5b4\ub824\uc6cc\uc11c \uc2dc\uac04\uc744 \ub9ce\uc774 \uc18c\ube44\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uac19\uc774 \uc2a4\ud130\ub514\ud558\uc2dc\ub294 \ubd84\uacfc 7\uac1c\uc6d4 \ub3d9\uc548 \uc2a4\ud130\ub514\ub97c \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00 \ucd1d 3\uad8c\uc758 \ucc45\uc744 \uc77d\uc744 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc6b0\uc544\ud55c-\ud14c\ud06c\ucf54\uc2a4",children:"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4"}),"\n",(0,n.jsxs)(r.p,{children:["\uad70 \ubcf5\ubb34 \uc911\uc77c \ub54c \uc9c0\uc6d0\ud588\ub2e4 \ub5a8\uc5b4\uc9c4 \uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ub2e4\uc2dc \uc9c0\uc6d0\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc774\ubc88 \uc5f0\ub3c4\uc5d0 \ucde8\uc5c5\uc744 \ud558\ub294 \uac8c \ubaa9\ud45c\uc600\uc9c0\ub9cc \ub0b4\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \ud2b9\ubcc4\ud55c \ubb34\uae30\uac00 \uc5c6\ub2e4\ub294 \uac78 \uae68\ub2ec\uc558\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc801\uc9c0 \uc54a\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574 \uc900\ube44\ub97c \ud588\uace0, \uac10\uc0ac\ud558\uac8c\ub3c4 \uc774\ubc88\uc5d0\ub294 \ucd5c\uc885 \ud569\uaca9\uc744 \ud588\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ub09c \uc0ac\ub78c\ub4e4\uacfc \uc18c\ud1b5\ud558\uace0, \ud611\uc5c5\ud558\ub294 \ub2a5\ub825\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ud1b5\ud574 \uadf8 \ube48 \ubd80\ubd84\uc744 \ucc44\uc6b0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"2023\ub144\uc5d0\ub294",children:"2023\ub144\uc5d0\ub294"}),"\n",(0,n.jsxs)(r.p,{children:["\ub9c8\uc74c\uc758 \uc5ec\uc720\uac00 \uc5c6\uc5c8\ub358 2022\ub144\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud558\uace0 \uc2f6\uc740 \uac74 \ub9ce\uc9c0\ub9cc, \uc774\ubc88\uc5d0\ub294 \uc5ec\uc720\ub97c \uac00\uc9c0\uace0 \ud560 \uc218 \uc788\ub294 \uac83\uc5d0 \ucd5c\uc120\uc744 \ub2e4\ud574\uc57c\uaca0\ub2e4."]})]})}function u(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>a});var n=t(67294);function s(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function o(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){s(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function c(e,r){if(null==e)return{};var t,n,s=function(e,r){if(null==e)return{};var t,n,s={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(s[t]=e[t]);return s}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var l=n.createContext({}),a=function(e){var r=n.useContext(l),t=r;return e&&(t="function"==typeof e?e(r):o(o({},r),e)),t},p={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},u=n.forwardRef((function(e,r){var t=e.components,s=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),d=a(t),b=s,j=d["".concat(l,".").concat(b)]||d[b]||p[b]||i;return t?n.createElement(j,o(o({ref:r},u),{},{components:t})):n.createElement(j,o({ref:r},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/9bad5ae7.ab21a5c2.js b/assets/js/9bad5ae7.ab21a5c2.js deleted file mode 100644 index ee7d9fbf3..000000000 --- a/assets/js/9bad5ae7.ab21a5c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2153],{3905:(e,t,n)=>{n.d(t,{Zo:()=>k,kt:()=>d});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),c=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},k=function(e){var t=c(e.components);return a.createElement(p.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},s=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,k=i(e,["components","mdxType","originalType","parentName"]),s=c(n),d=r,u=s["".concat(p,".").concat(d)]||s[d]||m[d]||l;return n?a.createElement(u,o(o({ref:t},k),{},{components:n})):a.createElement(u,o({ref:t},k))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=s;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var c=2;c<l;c++)o[c]=n[c];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}s.displayName="MDXCreateElement"},2163:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>i,toc:()=>c});var a=n(87462),r=(n(67294),n(3905));const l={title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"innodb-lock",tags:["DataBase","Lock","InnoDB"]},o=void 0,i={permalink:"/innodb-lock",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",source:"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",description:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",date:"2023-04-07T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 7\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Lock",permalink:"/tags/lock"},{label:"InnoDB",permalink:"/tags/inno-db"}],readingTime:5.805,hasTruncateMarker:!1,authors:[],frontMatter:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"innodb-lock",tags:["DataBase","Lock","InnoDB"]},prevItem:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",permalink:"/book-leadership-and-self-deception"},nextItem:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/mysql-lock"}},p={authorsImageUrls:[]},c=[{value:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",id:"innodb-\uc2a4\ud1a0\ub9ac\uc9c0-\uc5d4\uc9c4\uc758-\uc7a0\uae08",level:2},{value:"Shared & Exclusive Locks",id:"shared--exclusive-locks",level:3},{value:"Intention Locks",id:"intention-locks",level:3},{value:"Record Locks",id:"record-locks",level:3},{value:"Gap Locks",id:"gap-locks",level:3},{value:"Next-Key Locks",id:"next-key-locks",level:3},{value:"AUTO-INC Locks",id:"auto-inc-locks",level:3},{value:"\uc7a0\uae08 \uc608\uc2dc",id:"\uc7a0\uae08-\uc608\uc2dc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],k={toc:c};function m(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},k,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"innodb-\uc2a4\ud1a0\ub9ac\uc9c0-\uc5d4\uc9c4\uc758-\uc7a0\uae08"},"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08"),(0,r.kt)("p",null,"MySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08\uacfc \ubcc4\uac1c\ub85c \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub0b4\ubd80\uc5d0\uc11c \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubcf4\ud1b5 \uba85\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\ub294 \ub4dc\ubb3c\uace0, \uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ubb35\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc774 \uc0ac\uc6a9\ub41c\ub2e4. "),(0,r.kt)("p",null,"\ub3d9\uc2dc\uc131 \uc81c\uc5b4 \ubc29\uc2dd\uc5d0\ub294 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uacfc \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc774 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB\ub294 \uae30\ubcf8\uc801\uc73c\ub85c MVCC(\ub2e4\uc911 \ubc84\uc804 \ub3d9\uc2dc\uc131 \uc81c\uc5b4)\ub97c \ud1b5\ud574 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uace0 \ub77d\uc744 \ud1b5\ud574 \ud2b9\uc815 \uc0c1\ud669\uc5d0\uc11c \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("admonition",{title:"\ub099\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(OCC, Optimistic concurrency control)",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc11c\ub85c \ucda9\ub3cc\ud558\uc9c0 \uc54a\ub294\ub2e4\uace0 \uac00\uc815\ud558\ub294 \ubc29\uc2dd ")),(0,r.kt)("admonition",{title:"\ube44\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(PCC, Pessimistic Concurrency Control)",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\ud2b8\ub79c\uc7ad\uc158\uc774 \ucda9\ub3cc\ud558\ub294 \uac00\uc815\ud558\uc5d0 \uc7a0\uae08\uc744 \uac70\ub294 \ubc29\uc2dd",(0,r.kt)("br",{parentName:"p"}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c\xa0Shared Lock, Exclusive Lock\uc744 \ud1b5\ud574 \uc774\ub97c \uad6c\ud604\ud55c\ub2e4.")),(0,r.kt)("h3",{id:"shared--exclusive-locks"},"Shared & Exclusive Locks"),(0,r.kt)("p",null,"InnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc218\ud589\ud560 \ub54c \uacf5\uc720 \uc7a0\uae08\uacfc \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uacf5\uc720 \uc7a0\uae08(S, shared lock)")),(0,r.kt)("p",null,"\ub370\uc774\ud130 \uc870\ud68c\ub97c \uc704\ud55c \ub77d, \uc77d\uae30 \uc7a0\uae08(read lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uae30\uac00 \uac00\ub2a5\ud558\uc9c0\ub9cc, \uc4f0\uae30\ub294 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) ",(0,r.kt)("inlineCode",{parentName:"p"},"SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\ubc30\ud0c0\uc801 \uc7a0\uae08(X, exclusive lock)")," "),(0,r.kt)("p",null,"\ub370\uc774\ud130 \ubcc0\uacbd\uc744 \uc704\ud55c \ub77d, \uc4f0\uae30 \uc7a0\uae08(write lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub77d\uc744 \uac74 \ud2b8\ub79c\uc7ad\uc158\ub9cc\uc774 \ud574\ub2f9 \ub370\uc774\ud130\uc5d0 \uc811\uadfc \uac00\ub2a5\ud558\ub2e4. \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \uc77d\uae30, \uc4f0\uae30\uac00 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) ",(0,r.kt)("inlineCode",{parentName:"p"},"SELECT * FROM table_name WHERE id = 1 FOR UPDATE;")),(0,r.kt)("h3",{id:"intention-locks"},"Intention Locks"),(0,r.kt)("p",null,"InnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uacfc \ud14c\uc774\ube14 \uc7a0\uae08\uc758 \uacf5\uc874\uc744 \uc704\ud574 \uc778\ud14d\uc158 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud14c\uc774\ube14\uc5d0 \uc788\ub294 \ub85c\uc6b0\uc5d0 \ub300\ud574\uc11c \ub098\uc911\uc5d0 \uc694\uccad\ub418\ub294 \uac83\uc774 \uc5b4\ub5a4 \ud615\ud0dc\uc758 \uc7a0\uae08\uc778\uc9c0 \uac00\ub9ac\ud0a4\uae30 \uc704\ud574 \uc0ac\uc6a9\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uc744 \uc218\ud589\ud558\uae30 \uc804\uc5d0 \uc778\ud150\uc158 \uc7a0\uae08\uc744 \uba3c\uc800 \ud68d\ub4dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc778\ud150\uc158 \ub77d\uc740 \uae30\ubcf8\uc801\uc73c\ub85c \ucda9\ub3cc\uc744 \ubc29\uc9c0\ud558\uace0 \ub370\ub4dc\ub77d\uc744 \ubc29\uc9c0\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uc778\ud150\uc158 \uacf5\uc720 \uc7a0\uae08(IS, intention shared lock)")),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \uacf5\uc720 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uc778\ud150\uc158 \ubc30\ud0c0\uc801 \uc7a0\uae08(IX, intention exclusive lock)")," "),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"}," \uc7a0\uae08\uac04\uc758 \ud638\ud658\uc131 ")),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null}),(0,r.kt)("th",{parentName:"tr",align:null},"X"),(0,r.kt)("th",{parentName:"tr",align:null},"IX"),(0,r.kt)("th",{parentName:"tr",align:null},"S"),(0,r.kt)("th",{parentName:"tr",align:null},"IS"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"IX"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"S"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"IS"),(0,r.kt)("td",{parentName:"tr",align:null},"Conflict"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible"),(0,r.kt)("td",{parentName:"tr",align:null},"Compatible")))),(0,r.kt)("h3",{id:"record-locks"},"Record Locks"),(0,r.kt)("p",null,"\ub808\ucf54\ub4dc \uc790\uccb4\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc740 \ub808\ucf54\ub4dc \uc790\uccb4\uac00 \uc544\ub2c8\ub77c \uc778\ub371\uc2a4\uc758 \ub808\ucf54\ub4dc\ub97c \uc7a0\uadfc\ub2e4. "),(0,r.kt)("h3",{id:"gap-locks"},"Gap Locks"),(0,r.kt)("p",null,"\ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub808\ucf54\ub4dc\uc640 \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\uc5d0 \uc0c8\ub85c\uc6b4 \ub808\ucf54\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc744 \uc81c\uc5b4\ud558\uace0, \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc758 \uc77c\ubd80\ub85c \uc0ac\uc6a9\ub41c\ub2e4. "),(0,r.kt)("h3",{id:"next-key-locks"},"Next-Key Locks"),(0,r.kt)("p",null,"\ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"REPEATABLE READ")," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ud32c\ud140 \ub9ac\ub4dc\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud55c \uc7a0\uae08\uc774\ub2e4. "),(0,r.kt)("h3",{id:"auto-inc-locks"},"AUTO-INC Locks"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"AUTO_INCREMENT")," \uce7c\ub9bc\uc774 \uc0ac\uc6a9\ub41c \ud14c\uc774\ube14\uc5d0 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \ub808\ucf54\ub4dc\uac00 ",(0,r.kt)("inlineCode",{parentName:"p"},"INSERT"),"\ub418\ub294 \uacbd\uc6b0, \uac01 \ub808\ucf54\ub4dc\ub294 \uc911\ubcf5\ub418\uc9c0 \uc54a\uace0 \uc800\uc7a5\ub41c \uc21c\uc11c\ub300\ub85c \uc99d\uac00\ud558\ub294 \uc77c\ub828\ubc88\ud638 \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB \ub294 \ub0b4\ubd80\uc801\uc73c\ub85c AUTO-INC \ub77d\uc774\ub77c\uace0 \ud558\ub294 \ud14c\uc774\ube14 \uc218\uc900\uc758 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158\uacfc \uad00\uacc4 \uc5c6\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"INSERT"),"\ub098 ",(0,r.kt)("inlineCode",{parentName:"p"},"REPLACE")," \ubb38\uc7a5\uc5d0\uc11c ",(0,r.kt)("inlineCode",{parentName:"p"},"AUTO_INCREMENT")," \uac12\uc744 \uac00\uc838\uc624\ub294 \uc21c\uac04\ub9cc \ub77d\uc774 \uac78\ub838\ub2e4\uac00 \ud574\uc81c\ub41c\ub2e4."),(0,r.kt)("h3",{id:"\uc7a0\uae08-\uc608\uc2dc"},"\uc7a0\uae08 \uc608\uc2dc"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- \ub808\ucf54\ub4dc\ub294 id \uae30\uc900 10, 20, 30, 40, 50\uc774 \uc788\ub2e4\uace0 \uac00\uc815\n-- Record Locks: 10\uc5d0 \ub300\ud574 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id = 10 for update;\n\n-- Gap Locks: 51\ubd80\ud130 PositiveInfinity\uae4c\uc9c0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id > 100 for update;\n\n-- Next-Key Locks: 21\ubd80\ud130 30, 31\ubd80\ud130 40\uc5d0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id BETWEEN 25 AND 35 for update;\n")),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.ibm.com/docs/en/rational-clearquest/9.0.0?topic=clearquest-optimistic-pessimistic-record-locking"},"Optimistic and Pessimistic record locking, IBM"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://cecil1018.wordpress.com/2016/06/18/mysql-innodb-locks/"},"MySQL Innodb Locks, cecil1018"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html"},"MySQL 8.0 InnoDB Locks, MySQL"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html"},"Locks Set by Different SQL Statements in InnoDB, MySQL")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9bad5ae7.fa0f41bc.js b/assets/js/9bad5ae7.fa0f41bc.js new file mode 100644 index 000000000..f2cb67078 --- /dev/null +++ b/assets/js/9bad5ae7.fa0f41bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2153],{27555:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>d});var r=t(85893),c=t(3905);const i={title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"innodb-lock",tags:["DataBase","Lock","InnoDB"]},s=void 0,l={permalink:"/innodb-lock",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",source:"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",description:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",date:"2023-04-07T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 7\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Lock",permalink:"/tags/lock"},{label:"InnoDB",permalink:"/tags/inno-db"}],readingTime:5.805,hasTruncateMarker:!1,authors:[],frontMatter:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"innodb-lock",tags:["DataBase","Lock","InnoDB"]},unlisted:!1,prevItem:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",permalink:"/book-leadership-and-self-deception"},nextItem:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/mysql-lock"}},o={authorsImageUrls:[]},d=[{value:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",id:"innodb-\uc2a4\ud1a0\ub9ac\uc9c0-\uc5d4\uc9c4\uc758-\uc7a0\uae08",level:2},{value:"Shared & Exclusive Locks",id:"shared--exclusive-locks",level:3},{value:"Intention Locks",id:"intention-locks",level:3},{value:"Record Locks",id:"record-locks",level:3},{value:"Gap Locks",id:"gap-locks",level:3},{value:"Next-Key Locks",id:"next-key-locks",level:3},{value:"AUTO-INC Locks",id:"auto-inc-locks",level:3},{value:"\uc7a0\uae08 \uc608\uc2dc",id:"\uc7a0\uae08-\uc608\uc2dc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function a(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,c.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"innodb-\uc2a4\ud1a0\ub9ac\uc9c0-\uc5d4\uc9c4\uc758-\uc7a0\uae08",children:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08"}),"\n",(0,r.jsxs)(n.p,{children:["MySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08\uacfc \ubcc4\uac1c\ub85c \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub0b4\ubd80\uc5d0\uc11c \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubcf4\ud1b5 \uba85\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\ub294 \ub4dc\ubb3c\uace0, \uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ubb35\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc774 \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ub3d9\uc2dc\uc131 \uc81c\uc5b4 \ubc29\uc2dd\uc5d0\ub294 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uacfc \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc774 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","InnoDB\ub294 \uae30\ubcf8\uc801\uc73c\ub85c MVCC(\ub2e4\uc911 \ubc84\uc804 \ub3d9\uc2dc\uc131 \uc81c\uc5b4)\ub97c \ud1b5\ud574 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uace0 \ub77d\uc744 \ud1b5\ud574 \ud2b9\uc815 \uc0c1\ud669\uc5d0\uc11c \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.admonition,{title:"\ub099\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(OCC, Optimistic concurrency control)",type:"note",children:(0,r.jsx)(n.p,{children:"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc11c\ub85c \ucda9\ub3cc\ud558\uc9c0 \uc54a\ub294\ub2e4\uace0 \uac00\uc815\ud558\ub294 \ubc29\uc2dd"})}),"\n",(0,r.jsx)(n.admonition,{title:"\ube44\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(PCC, Pessimistic Concurrency Control)",type:"note",children:(0,r.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc774 \ucda9\ub3cc\ud558\ub294 \uac00\uc815\ud558\uc5d0 \uc7a0\uae08\uc744 \uac70\ub294 \ubc29\uc2dd",(0,r.jsx)(n.br,{}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c\xa0Shared Lock, Exclusive Lock\uc744 \ud1b5\ud574 \uc774\ub97c \uad6c\ud604\ud55c\ub2e4."]})}),"\n",(0,r.jsx)(n.h3,{id:"shared--exclusive-locks",children:"Shared & Exclusive Locks"}),"\n",(0,r.jsx)(n.p,{children:"InnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc218\ud589\ud560 \ub54c \uacf5\uc720 \uc7a0\uae08\uacfc \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\uacf5\uc720 \uc7a0\uae08(S, shared lock)"})}),"\n",(0,r.jsxs)(n.p,{children:["\ub370\uc774\ud130 \uc870\ud68c\ub97c \uc704\ud55c \ub77d, \uc77d\uae30 \uc7a0\uae08(read lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uae30\uac00 \uac00\ub2a5\ud558\uc9c0\ub9cc, \uc4f0\uae30\ub294 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc608) ",(0,r.jsx)(n.code,{children:"SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;"})]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\ubc30\ud0c0\uc801 \uc7a0\uae08(X, exclusive lock)"})}),"\n",(0,r.jsxs)(n.p,{children:["\ub370\uc774\ud130 \ubcc0\uacbd\uc744 \uc704\ud55c \ub77d, \uc4f0\uae30 \uc7a0\uae08(write lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub77d\uc744 \uac74 \ud2b8\ub79c\uc7ad\uc158\ub9cc\uc774 \ud574\ub2f9 \ub370\uc774\ud130\uc5d0 \uc811\uadfc \uac00\ub2a5\ud558\ub2e4. \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \uc77d\uae30, \uc4f0\uae30\uac00 \ubd88\uac00\ub2a5\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc608) ",(0,r.jsx)(n.code,{children:"SELECT * FROM table_name WHERE id = 1 FOR UPDATE;"})]}),"\n",(0,r.jsx)(n.h3,{id:"intention-locks",children:"Intention Locks"}),"\n",(0,r.jsxs)(n.p,{children:["InnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uacfc \ud14c\uc774\ube14 \uc7a0\uae08\uc758 \uacf5\uc874\uc744 \uc704\ud574 \uc778\ud14d\uc158 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud14c\uc774\ube14\uc5d0 \uc788\ub294 \ub85c\uc6b0\uc5d0 \ub300\ud574\uc11c \ub098\uc911\uc5d0 \uc694\uccad\ub418\ub294 \uac83\uc774 \uc5b4\ub5a4 \ud615\ud0dc\uc758 \uc7a0\uae08\uc778\uc9c0 \uac00\ub9ac\ud0a4\uae30 \uc704\ud574 \uc0ac\uc6a9\ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uc744 \uc218\ud589\ud558\uae30 \uc804\uc5d0 \uc778\ud150\uc158 \uc7a0\uae08\uc744 \uba3c\uc800 \ud68d\ub4dd\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc778\ud150\uc158 \ub77d\uc740 \uae30\ubcf8\uc801\uc73c\ub85c \ucda9\ub3cc\uc744 \ubc29\uc9c0\ud558\uace0 \ub370\ub4dc\ub77d\uc744 \ubc29\uc9c0\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\uc778\ud150\uc158 \uacf5\uc720 \uc7a0\uae08(IS, intention shared lock)"})}),"\n",(0,r.jsx)(n.p,{children:"\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \uacf5\uc720 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\uc778\ud150\uc158 \ubc30\ud0c0\uc801 \uc7a0\uae08(IX, intention exclusive lock)"})}),"\n",(0,r.jsx)(n.p,{children:"\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:"** \uc7a0\uae08\uac04\uc758 \ud638\ud658\uc131 **"}),"\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{}),(0,r.jsx)(n.th,{children:"X"}),(0,r.jsx)(n.th,{children:"IX"}),(0,r.jsx)(n.th,{children:"S"}),(0,r.jsx)(n.th,{children:"IS"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"X"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Conflict"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"IX"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Compatible"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Compatible"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"S"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Compatible"}),(0,r.jsx)(n.td,{children:"Compatible"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"IS"}),(0,r.jsx)(n.td,{children:"Conflict"}),(0,r.jsx)(n.td,{children:"Compatible"}),(0,r.jsx)(n.td,{children:"Compatible"}),(0,r.jsx)(n.td,{children:"Compatible"})]})]})]}),"\n",(0,r.jsx)(n.h3,{id:"record-locks",children:"Record Locks"}),"\n",(0,r.jsxs)(n.p,{children:["\ub808\ucf54\ub4dc \uc790\uccb4\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.jsx)(n.br,{}),"\n","InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc740 \ub808\ucf54\ub4dc \uc790\uccb4\uac00 \uc544\ub2c8\ub77c \uc778\ub371\uc2a4\uc758 \ub808\ucf54\ub4dc\ub97c \uc7a0\uadfc\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"gap-locks",children:"Gap Locks"}),"\n",(0,r.jsxs)(n.p,{children:["\ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub808\ucf54\ub4dc\uc640 \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\uc5d0 \uc0c8\ub85c\uc6b4 \ub808\ucf54\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc744 \uc81c\uc5b4\ud558\uace0, \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc758 \uc77c\ubd80\ub85c \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"next-key-locks",children:"Next-Key Locks"}),"\n",(0,r.jsxs)(n.p,{children:["\ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.code,{children:"REPEATABLE READ"})," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ud32c\ud140 \ub9ac\ub4dc\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud55c \uc7a0\uae08\uc774\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"auto-inc-locks",children:"AUTO-INC Locks"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"AUTO_INCREMENT"})," \uce7c\ub9bc\uc774 \uc0ac\uc6a9\ub41c \ud14c\uc774\ube14\uc5d0 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \ub808\ucf54\ub4dc\uac00 ",(0,r.jsx)(n.code,{children:"INSERT"}),"\ub418\ub294 \uacbd\uc6b0, \uac01 \ub808\ucf54\ub4dc\ub294 \uc911\ubcf5\ub418\uc9c0 \uc54a\uace0 \uc800\uc7a5\ub41c \uc21c\uc11c\ub300\ub85c \uc99d\uac00\ud558\ub294 \uc77c\ub828\ubc88\ud638 \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","InnoDB \ub294 \ub0b4\ubd80\uc801\uc73c\ub85c AUTO-INC \ub77d\uc774\ub77c\uace0 \ud558\ub294 \ud14c\uc774\ube14 \uc218\uc900\uc758 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158\uacfc \uad00\uacc4 \uc5c6\uc774 ",(0,r.jsx)(n.code,{children:"INSERT"}),"\ub098 ",(0,r.jsx)(n.code,{children:"REPLACE"})," \ubb38\uc7a5\uc5d0\uc11c ",(0,r.jsx)(n.code,{children:"AUTO_INCREMENT"})," \uac12\uc744 \uac00\uc838\uc624\ub294 \uc21c\uac04\ub9cc \ub77d\uc774 \uac78\ub838\ub2e4\uac00 \ud574\uc81c\ub41c\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc7a0\uae08-\uc608\uc2dc",children:"\uc7a0\uae08 \uc608\uc2dc"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sql",children:"-- \ub808\ucf54\ub4dc\ub294 id \uae30\uc900 10, 20, 30, 40, 50\uc774 \uc788\ub2e4\uace0 \uac00\uc815\n-- Record Locks: 10\uc5d0 \ub300\ud574 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id = 10 for update;\n\n-- Gap Locks: 51\ubd80\ud130 PositiveInfinity\uae4c\uc9c0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id > 100 for update;\n\n-- Next-Key Locks: 21\ubd80\ud130 30, 31\ubd80\ud130 40\uc5d0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\nSELECT * FROM table_name where id BETWEEN 25 AND 35 for update;\n"})}),"\n",(0,r.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:["Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.ibm.com/docs/en/rational-clearquest/9.0.0?topic=clearquest-optimistic-pessimistic-record-locking",children:"Optimistic and Pessimistic record locking, IBM"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://cecil1018.wordpress.com/2016/06/18/mysql-innodb-locks/",children:"MySQL Innodb Locks, cecil1018"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html",children:"MySQL 8.0 InnoDB Locks, MySQL"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html",children:"Locks Set by Different SQL Statements in InnoDB, MySQL"})]})]})}function h(e={}){const{wrapper:n}={...(0,c.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>d});var r=t(67294);function c(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?i(Object(t),!0).forEach((function(n){c(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function l(e,n){if(null==e)return{};var t,r,c=function(e,n){if(null==e)return{};var t,r,c={},i=Object.keys(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||(c[t]=e[t]);return c}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(c[t]=e[t])}return c}var o=r.createContext({}),d=function(e){var n=r.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},a={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},h=r.forwardRef((function(e,n){var t=e.components,c=e.mdxType,i=e.originalType,o=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),x=d(t),j=c,p=x["".concat(o,".").concat(j)]||x[j]||a[j]||i;return t?r.createElement(p,s(s({ref:n},h),{},{components:t})):r.createElement(p,s({ref:n},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/9bbc65ac.6e49b159.js b/assets/js/9bbc65ac.c162c71c.js similarity index 92% rename from assets/js/9bbc65ac.6e49b159.js rename to assets/js/9bbc65ac.c162c71c.js index 85a17ccfa..689cf2cf3 100644 --- a/assets/js/9bbc65ac.6e49b159.js +++ b/assets/js/9bbc65ac.c162c71c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7210],{51020:t=>{t.exports=JSON.parse('{"label":"test","permalink":"/docs/tags/test","allTagsPath":"/docs/tags","count":5,"items":[{"id":"\ud14c\uc2a4\ud2b8/FIRST","title":"FIRST","description":"FIRST\ub780?","permalink":"/docs/test/first"},{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59","title":"TDD heuristics","description":"TDD heuristics","permalink":"/docs/test/heuristics"},{"id":"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","title":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","description":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)","permalink":"/docs/test/stairstep"},{"id":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615","description":"| \ud14c\uc2a4\ud2b8 | \uc124\uba85 |","permalink":"/docs/performance/types"},{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","title":"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","description":"\ub514\ubc84\uae45 \uac10\uc18c","permalink":"/docs/test/benefit"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7210],{51020:t=>{t.exports=JSON.parse('{"label":"test","permalink":"/docs/tags/test","allTagsPath":"/docs/tags","count":5,"items":[{"id":"\ud14c\uc2a4\ud2b8/FIRST","title":"FIRST","description":"FIRST\ub780?","permalink":"/docs/test/first"},{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59","title":"TDD heuristics","description":"TDD heuristics","permalink":"/docs/test/heuristics"},{"id":"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","title":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","description":"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)","permalink":"/docs/test/stairstep"},{"id":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615","description":"| \ud14c\uc2a4\ud2b8 | \uc124\uba85 |","permalink":"/docs/performance/types"},{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","title":"\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","description":"\ub514\ubc84\uae45 \uac10\uc18c","permalink":"/docs/test/benefit"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/9c6e5a12.70f826f0.js b/assets/js/9c6e5a12.70f826f0.js deleted file mode 100644 index db6ce4ed2..000000000 --- a/assets/js/9c6e5a12.70f826f0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2145],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,f=d["".concat(p,".").concat(m)]||d[m]||s[m]||a;return r?n.createElement(f,i(i({ref:t},u),{},{components:r})):n.createElement(f,i({ref:t},u))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c<a;c++)i[c]=r[c];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},22059:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>s,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"/monitoring/intro",last_update:{date:"2023/07/01"},tags:["monitoring"]},i=void 0,l={unversionedId:"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",id:"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",description:"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4",source:"@site/docs/\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.mdx",sourceDirName:"\ubaa8\ub2c8\ud130\ub9c1",slug:"/monitoring/intro",permalink:"/docs/monitoring/intro",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.mdx",tags:[{label:"monitoring",permalink:"/docs/tags/monitoring"}],version:"current",lastUpdatedAt:1688169600,formattedLastUpdatedAt:"2023\ub144 7\uc6d4 1\uc77c",frontMatter:{title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"/monitoring/intro",last_update:{date:"2023/07/01"},tags:["monitoring"]},sidebar:"tutorialSidebar",previous:{title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",permalink:"/docs/linux/shell"},next:{title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",permalink:"/docs/culture/postmortem"}},p={},c=[{value:"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4",id:"\ubaa8\ub2c8\ud130\ub9c1-3\ub2e8\uacc4",level:3},{value:"\ubaa8\ub2c8\ud130\ub9c1 \ub300\uc0c1",id:"\ubaa8\ub2c8\ud130\ub9c1-\ub300\uc0c1",level:3},{value:"\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ucd94\uc801",id:"\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ucd94\uc801",level:3},{value:"\ub85c\uadf8",id:"\ub85c\uadf8",level:3},{value:"\ubaa8\ub2c8\ud130\ub9c1",id:"\ubaa8\ub2c8\ud130\ub9c1",level:3},{value:"\uc54c\ub78c",id:"\uc54c\ub78c",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"\ubaa8\ub2c8\ud130\ub9c1-3\ub2e8\uacc4"},"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4"),(0,o.kt)("p",null,"\ub300\uc2dc\ubcf4\ub4dc",(0,o.kt)("br",{parentName:"p"}),"\n","\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ucd94\uc801 - \ud540\ud3ec\uc778\ud2b8",(0,o.kt)("br",{parentName:"p"}),"\n","\ub85c\uadf8 "),(0,o.kt)("h3",{id:"\ubaa8\ub2c8\ud130\ub9c1-\ub300\uc0c1"},"\ubaa8\ub2c8\ud130\ub9c1 \ub300\uc0c1"),(0,o.kt)("p",null,"\uc2dc\uc2a4\ud15c \uba54\ud2b8\ub9ad(CPU, \uba54\ubaa8\ub9ac)",(0,o.kt)("br",{parentName:"p"}),"\n","\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uba54\ud2b8\ub9ad(Thread Pool, Connection Pool, \ud638\ucd9c \uc218)",(0,o.kt)("br",{parentName:"p"}),"\n","\ube44\uc988\ub2c8\uc2a4 \uba54\ud2b8\ub9ad"),(0,o.kt)("h3",{id:"\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ucd94\uc801"},"\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ucd94\uc801"),(0,o.kt)("p",null,"\uac01\uac01\uc758 HTTP \uc694\uccad \ucd94\uc801",(0,o.kt)("br",{parentName:"p"}),"\n","\ud540\ud3ec\uc778\ud2b8, \uc2a4\uce74\uc6b0\ud2b8, \uc640\ud0ed, \uc81c\ub2c8\ud37c "),(0,o.kt)("h3",{id:"\ub85c\uadf8"},"\ub85c\uadf8"),(0,o.kt)("p",null,"\uac00\uc7a5 \uc138\uc138\ud55c \ucd94\uc801",(0,o.kt)("br",{parentName:"p"}),"\n","\uac19\uc740 HTTP \uc694\uccad\uc744 \ubb36\uc5b4\uc11c \ud655\uc778\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \uc911\uc694\ud558\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","MDC(Mapped Diagnostic Context) \uc801\uc6a9"),(0,o.kt)("p",null,"\ud30c\uc77c\ub85c \uc9c1\uc811 \ub85c\uadf8\ub97c \ub0a8\uae30\ub294 \uacbd\uc6b0 \u2192 \uc77c\ubc18 \ub85c\uadf8\uc640 \uc5d0\ub7ec \ub85c\uadf8 \ud30c\uc77c\uc744 \uad6c\ubd84\ud574\uc11c \ub0a8\uaca8\uc57c \ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ud074\ub77c\uc6b0\ub4dc\uc5d0 \uc800\uc7a5\ud558\ub294 \uacbd\uc6b0 \u2192 \uac80\uc0c9\uc774 \uc798 \ub418\ub3c4\ub85d \uad6c\ubd84\ud55c\ub2e4. "),(0,o.kt)("h3",{id:"\ubaa8\ub2c8\ud130\ub9c1"},"\ubaa8\ub2c8\ud130\ub9c1"),(0,o.kt)("p",null,"\uad00\ucc30\uc758 \uacbd\uc6b0 \uc804\uccb4 \u2192 \uc881\uac8c"),(0,o.kt)("h3",{id:"\uc54c\ub78c"},"\uc54c\ub78c"),(0,o.kt)("p",null,"\uc54c\ub78c\uc758 \uacbd\uc6b0 2\uac00\uc9c0 \uc885\ub958(\uacbd\uace0, \uc2ec\uac01)\ub85c \uad6c\ubd84\ud574\uc11c \uad00\ub9ac\ud55c\ub2e4."),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ud575\uc2ec \uc6d0\ub9ac\uc640 \ud65c\uc6a9, \uae40\uc601\ud55c"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9c6e5a12.76e4be75.js b/assets/js/9c6e5a12.76e4be75.js new file mode 100644 index 000000000..6c546747a --- /dev/null +++ b/assets/js/9c6e5a12.76e4be75.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2145],{81145:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>a});var r=n(85893),i=n(3905);const o={title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"/monitoring/intro",last_update:{date:"2023/07/01"},tags:["monitoring"]},l=void 0,s={id:"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",description:"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4",source:"@site/docs/\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.mdx",sourceDirName:"\ubaa8\ub2c8\ud130\ub9c1",slug:"/monitoring/intro",permalink:"/docs/monitoring/intro",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.mdx",tags:[{label:"monitoring",permalink:"/docs/tags/monitoring"}],version:"current",lastUpdatedAt:1688169600,formattedLastUpdatedAt:"2023\ub144 7\uc6d4 1\uc77c",frontMatter:{title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"/monitoring/intro",last_update:{date:"2023/07/01"},tags:["monitoring"]},sidebar:"tutorialSidebar",previous:{title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",permalink:"/docs/linux/shell"},next:{title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",permalink:"/docs/culture/postmortem"}},c={},a=[{value:"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4",id:"\ubaa8\ub2c8\ud130\ub9c1-3\ub2e8\uacc4",level:3},{value:"\ubaa8\ub2c8\ud130\ub9c1 \ub300\uc0c1",id:"\ubaa8\ub2c8\ud130\ub9c1-\ub300\uc0c1",level:3},{value:"\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ucd94\uc801",id:"\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ucd94\uc801",level:3},{value:"\ub85c\uadf8",id:"\ub85c\uadf8",level:3},{value:"\ubaa8\ub2c8\ud130\ub9c1",id:"\ubaa8\ub2c8\ud130\ub9c1",level:3},{value:"\uc54c\ub78c",id:"\uc54c\ub78c",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={br:"br",h3:"h3",p:"p",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"\ubaa8\ub2c8\ud130\ub9c1-3\ub2e8\uacc4",children:"\ubaa8\ub2c8\ud130\ub9c1 3\ub2e8\uacc4"}),"\n",(0,r.jsxs)(t.p,{children:["\ub300\uc2dc\ubcf4\ub4dc",(0,r.jsx)(t.br,{}),"\n","\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ucd94\uc801 - \ud540\ud3ec\uc778\ud2b8",(0,r.jsx)(t.br,{}),"\n","\ub85c\uadf8"]}),"\n",(0,r.jsx)(t.h3,{id:"\ubaa8\ub2c8\ud130\ub9c1-\ub300\uc0c1",children:"\ubaa8\ub2c8\ud130\ub9c1 \ub300\uc0c1"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2dc\uc2a4\ud15c \uba54\ud2b8\ub9ad(CPU, \uba54\ubaa8\ub9ac)",(0,r.jsx)(t.br,{}),"\n","\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uba54\ud2b8\ub9ad(Thread Pool, Connection Pool, \ud638\ucd9c \uc218)",(0,r.jsx)(t.br,{}),"\n","\ube44\uc988\ub2c8\uc2a4 \uba54\ud2b8\ub9ad"]}),"\n",(0,r.jsx)(t.h3,{id:"\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ucd94\uc801",children:"\uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ucd94\uc801"}),"\n",(0,r.jsxs)(t.p,{children:["\uac01\uac01\uc758 HTTP \uc694\uccad \ucd94\uc801",(0,r.jsx)(t.br,{}),"\n","\ud540\ud3ec\uc778\ud2b8, \uc2a4\uce74\uc6b0\ud2b8, \uc640\ud0ed, \uc81c\ub2c8\ud37c"]}),"\n",(0,r.jsx)(t.h3,{id:"\ub85c\uadf8",children:"\ub85c\uadf8"}),"\n",(0,r.jsxs)(t.p,{children:["\uac00\uc7a5 \uc138\uc138\ud55c \ucd94\uc801",(0,r.jsx)(t.br,{}),"\n","\uac19\uc740 HTTP \uc694\uccad\uc744 \ubb36\uc5b4\uc11c \ud655\uc778\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \uc911\uc694\ud558\ub2e4.",(0,r.jsx)(t.br,{}),"\n","MDC(Mapped Diagnostic Context) \uc801\uc6a9"]}),"\n",(0,r.jsxs)(t.p,{children:["\ud30c\uc77c\ub85c \uc9c1\uc811 \ub85c\uadf8\ub97c \ub0a8\uae30\ub294 \uacbd\uc6b0 \u2192 \uc77c\ubc18 \ub85c\uadf8\uc640 \uc5d0\ub7ec \ub85c\uadf8 \ud30c\uc77c\uc744 \uad6c\ubd84\ud574\uc11c \ub0a8\uaca8\uc57c \ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud074\ub77c\uc6b0\ub4dc\uc5d0 \uc800\uc7a5\ud558\ub294 \uacbd\uc6b0 \u2192 \uac80\uc0c9\uc774 \uc798 \ub418\ub3c4\ub85d \uad6c\ubd84\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ubaa8\ub2c8\ud130\ub9c1",children:"\ubaa8\ub2c8\ud130\ub9c1"}),"\n",(0,r.jsx)(t.p,{children:"\uad00\ucc30\uc758 \uacbd\uc6b0 \uc804\uccb4 \u2192 \uc881\uac8c"}),"\n",(0,r.jsx)(t.h3,{id:"\uc54c\ub78c",children:"\uc54c\ub78c"}),"\n",(0,r.jsx)(t.p,{children:"\uc54c\ub78c\uc758 \uacbd\uc6b0 2\uac00\uc9c0 \uc885\ub958(\uacbd\uace0, \uc2ec\uac01)\ub85c \uad6c\ubd84\ud574\uc11c \uad00\ub9ac\ud55c\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsx)(t.p,{children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ud575\uc2ec \uc6d0\ub9ac\uc640 \ud65c\uc6a9, \uae40\uc601\ud55c"})]})}function p(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>a});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),a=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=a(n),m=i,b=u["".concat(c,".").concat(m)]||u[m]||d[m]||o;return n?r.createElement(b,l(l({ref:t},p),{},{components:n})):r.createElement(b,l({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/9ca52986.08ff34b4.js b/assets/js/9ca52986.3fac83b3.js similarity index 88% rename from assets/js/9ca52986.08ff34b4.js rename to assets/js/9ca52986.3fac83b3.js index f6e6525c0..1d118ba46 100644 --- a/assets/js/9ca52986.08ff34b4.js +++ b/assets/js/9ca52986.3fac83b3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3490],{92016:e=>{e.exports=JSON.parse('{"label":"Lock","permalink":"/tags/lock","allTagsPath":"/tags","count":2}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3490],{92016:e=>{e.exports=JSON.parse('{"label":"Lock","permalink":"/tags/lock","allTagsPath":"/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/9d1fd2b0.80d4a2ec.js b/assets/js/9d1fd2b0.80d4a2ec.js new file mode 100644 index 000000000..d432ef7b7 --- /dev/null +++ b/assets/js/9d1fd2b0.80d4a2ec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7972],{30138:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var n=t(85893),o=t(3905);const s={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",slug:"woowacourse-level2-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,i={permalink:"/woowacourse-level2-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",description:"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.",date:"2023-06-11T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 11\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:2.545,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",slug:"woowacourse-level2-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"Docusaurus",permalink:"/docusaurus"},nextItem:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",permalink:"/level2-interview-retrospective"}},a={authorsImageUrls:[]},l=[{value:"\ud559\uc2b5",id:"\ud559\uc2b5",level:3},{value:"\uc218\uba74",id:"\uc218\uba74",level:3},{value:"\ud611\uc5c5",id:"\ud611\uc5c5",level:3},{value:"\ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70",id:"\ub808\ubca8-2\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70",level:3}];function p(e){const r={br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(r.p,{children:["23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ube60\ub974\uac8c \uc9c0\ub098\uac00\uc11c \uc870\uae08 \uc544\uc27d\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ud559\uc2b5",children:"\ud559\uc2b5"}),"\n",(0,n.jsxs)(r.p,{children:["\ud68c\uace0\ub97c \uc791\uc131\ud558\uae30 \uc804\uc5d0 \ub808\ubca8 2 \ub3d9\uc548 \ubcf4\ub0c8\ub358 PR\uacfc \ud68c\uace0\ub97c \ucb49 \uc77d\uc5b4\ubd24\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud56d\uc0c1 \uc544\uc26c\uc6b4 \uacf3\uc740 \uc788\uae30 \ub9c8\ub828\uc774\uc9c0\ub9cc, \uc798 \ud559\uc2b5\ud55c \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubbf8\uc158\uc744 \ud558\uba74\uc11c \uae30\uc220\uc744 \uc5b4\ub5bb\uac8c \uc120\ud0dd\ud558\uace0, \uc801\uc6a9\ud560 \uac83\uc778\uc9c0 \uace0\ubbfc\ud558\ub294 \uacfc\uc815\uc5d0\uc11c \uaf64\ub098 \ub9ce\uc740 \uc131\uc7a5\uc744 \ud55c \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\uace0\ubbfc\uc740 \uae4a\uc5c8\uc9c0\ub9cc \uc774\ub860\uc801\uc778 \ud559\uc2b5\uc774 \ubd80\uc871\ud55c \ub808\ubca8 2\uc600\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubc29\ud559 \uadf8\ub9ac\uace0 \ub808\ubca8 3 \ub54c\ub294 \uc870\uae08 \ub354 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc744 \ud559\uc2b5\ud558\ub294\ub370 \uc9d1\uc911\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\uc810\ucc28 \ud559\uc2b5 \ubc94\uc704\uac00 \ub113\uc5b4\uc9c0\uba74\uc11c \uc790\uc5f0\uc2a4\ub7fd\uac8c \ubaa8\ub974\ub294 \ub0b4\uc6a9\uc774 \uc313\uc5ec\uac04\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud544\uc694\ud55c \ub0b4\uc6a9\uc740 \uc55e\uc73c\ub85c \ucc9c\ucc9c\ud788 \ud559\uc2b5\ud558\uba74 \ub418\ub2c8\uae4c \uc870\uae09\ud574\uc9c0\uc9c0 \ub9d0\uc544\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc218\uba74",children:"\uc218\uba74"}),"\n",(0,n.jsxs)(r.p,{children:["\ub808\ubca8 2\ub97c \uc9c4\ud589\ud558\ub294 \ub3d9\uc548 \uc218\uba74\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\uc5c8\uace0, \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \uadf8\ub0a0\uc758 \ucee8\ub514\uc158\uc744 \ub9ce\uc774 \uc88c\uc6b0\ud588\ub358 \uac83 \uac19\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c \uc218\uba74 \uc2dc\uac04\uc744 \ub298\ub9ac\uace0, \uc88b\uc740 \uc218\uba74 \uc2b5\uad00\uc744 \uac00\uc9c0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ud611\uc5c5",children:"\ud611\uc5c5"}),"\n",(0,n.jsxs)(r.p,{children:["\ub808\ubca8 2 \ub9c8\uc9c0\ub9c9\uc5d0 \ud611\uc5c5 \ubbf8\uc158\uc774 \uc788\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc9c0\uae08\uae4c\uc9c0\ub294 \ubc31\uc5d4\ub4dc \ud06c\ub8e8\ub4e4\uacfc \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud558\uba74\uc11c \ud611\uc5c5\uc744 \uacbd\ud5d8\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc774\ubc88\uc5d0\ub294 \ud504\ub7f0\ud2b8\uc5d4\ub4dc \ud06c\ub8e8\uc640 \ud611\uc5c5\uc744 \ud588\ub2e4. \uc18c\ud1b5\uc740 \uc798 \ub41c \uac83 \uac19\uc9c0\ub9cc API \uba85\uc138\ub97c \uc815\ud558\ub294 \ubd80\ubd84\uc774 \uc544\uc9c1 \ubbf8\uc219\ud55c \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ub808\ubca8 3 \ub54c\ubd80\ud130 \ubcf8\uaca9\uc801\uc73c\ub85c \ud504\ub85c\uc81d\ud2b8\uac00 \uc2dc\uc791\ub41c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud300\uc744 \uc704\ud574 \uc5b4\ub5a4 \uac83\uc744 \ud560 \uc218 \uc788\uc744\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud574\ubd10\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ub808\ubca8-2\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70",children:"\ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70"}),"\n",(0,n.jsx)(r.p,{children:"\ud68c\uace0 \uc791\uc131\ud558\uba74\uc11c \ub808\ubca8 2\uc5d0\uc11c \ud588\ub358 \uac83\ub4e4\uc744 \ubc18\ucd94\ud574 \ubd24\ub294\ub370 \ubd80\uc871\ud55c \uc810\uc740 \ub9ce\uc558\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \uac00\uace0 \uc788\ub294 \uac83 \uac19\ub2e4.\n\uc77d\uace0 \uc2f6\uc740 \ucc45\ub3c4 \uc77d\uace0, \ubd80\uc871\ud55c \ubd80\ubd84 \ucc44\uc6b0\uba74\uc11c \uc26c\uc5b4\uc57c\uaca0\ub2e4."})]})}function u(e={}){const{wrapper:r}={...(0,o.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>l});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function s(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function c(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?s(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function i(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},s=Object.keys(e);for(n=0;n<s.length;n++)t=s[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)t=s[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var a=n.createContext({}),l=function(e){var r=n.useContext(a),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},p={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},u=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,s=e.originalType,a=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=l(t),h=o,b=d["".concat(a,".").concat(h)]||d[h]||p[h]||s;return t?n.createElement(b,c(c({ref:r},u),{},{components:t})):n.createElement(b,c({ref:r},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/9d1fd2b0.fa60d8c7.js b/assets/js/9d1fd2b0.fa60d8c7.js deleted file mode 100644 index 26908bef4..000000000 --- a/assets/js/9d1fd2b0.fa60d8c7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7972],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>f});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=p(e,["components","mdxType","originalType","parentName"]),m=c(r),f=a,v=m["".concat(i,".").concat(f)]||m[f]||s[f]||o;return r?n.createElement(v,l(l({ref:t},u),{},{components:r})):n.createElement(v,l({ref:t},u))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=m;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:a,l[1]=p;for(var c=2;c<o;c++)l[c]=r[c];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},15361:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>s,frontMatter:()=>o,metadata:()=>p,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",slug:"woowacourse-level2-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,p={permalink:"/woowacourse-level2-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",description:"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.",date:"2023-06-11T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 11\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:2.545,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",slug:"woowacourse-level2-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"Docusaurus",permalink:"/docusaurus"},nextItem:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",permalink:"/level2-interview-retrospective"}},i={authorsImageUrls:[]},c=[{value:"\ud559\uc2b5",id:"\ud559\uc2b5",level:3},{value:"\uc218\uba74",id:"\uc218\uba74",level:3},{value:"\ud611\uc5c5",id:"\ud611\uc5c5",level:3},{value:"\ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70",id:"\ub808\ubca8-2\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube60\ub974\uac8c \uc9c0\ub098\uac00\uc11c \uc870\uae08 \uc544\uc27d\ub2e4. "),(0,a.kt)("h3",{id:"\ud559\uc2b5"},"\ud559\uc2b5"),(0,a.kt)("p",null,"\ud68c\uace0\ub97c \uc791\uc131\ud558\uae30 \uc804\uc5d0 \ub808\ubca8 2 \ub3d9\uc548 \ubcf4\ub0c8\ub358 PR\uacfc \ud68c\uace0\ub97c \ucb49 \uc77d\uc5b4\ubd24\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \uc544\uc26c\uc6b4 \uacf3\uc740 \uc788\uae30 \ub9c8\ub828\uc774\uc9c0\ub9cc, \uc798 \ud559\uc2b5\ud55c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158\uc744 \ud558\uba74\uc11c \uae30\uc220\uc744 \uc5b4\ub5bb\uac8c \uc120\ud0dd\ud558\uace0, \uc801\uc6a9\ud560 \uac83\uc778\uc9c0 \uace0\ubbfc\ud558\ub294 \uacfc\uc815\uc5d0\uc11c \uaf64\ub098 \ub9ce\uc740 \uc131\uc7a5\uc744 \ud55c \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\uace0\ubbfc\uc740 \uae4a\uc5c8\uc9c0\ub9cc \uc774\ub860\uc801\uc778 \ud559\uc2b5\uc774 \ubd80\uc871\ud55c \ub808\ubca8 2\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc29\ud559 \uadf8\ub9ac\uace0 \ub808\ubca8 3 \ub54c\ub294 \uc870\uae08 \ub354 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc744 \ud559\uc2b5\ud558\ub294\ub370 \uc9d1\uc911\ud574\uc57c\uaca0\ub2e4. "),(0,a.kt)("p",null,"\uc810\ucc28 \ud559\uc2b5 \ubc94\uc704\uac00 \ub113\uc5b4\uc9c0\uba74\uc11c \uc790\uc5f0\uc2a4\ub7fd\uac8c \ubaa8\ub974\ub294 \ub0b4\uc6a9\uc774 \uc313\uc5ec\uac04\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud544\uc694\ud55c \ub0b4\uc6a9\uc740 \uc55e\uc73c\ub85c \ucc9c\ucc9c\ud788 \ud559\uc2b5\ud558\uba74 \ub418\ub2c8\uae4c \uc870\uae09\ud574\uc9c0\uc9c0 \ub9d0\uc544\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\uc218\uba74"},"\uc218\uba74"),(0,a.kt)("p",null,"\ub808\ubca8 2\ub97c \uc9c4\ud589\ud558\ub294 \ub3d9\uc548 \uc218\uba74\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\uc5c8\uace0, \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \uadf8\ub0a0\uc758 \ucee8\ub514\uc158\uc744 \ub9ce\uc774 \uc88c\uc6b0\ud588\ub358 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc218\uba74 \uc2dc\uac04\uc744 \ub298\ub9ac\uace0, \uc88b\uc740 \uc218\uba74 \uc2b5\uad00\uc744 \uac00\uc9c0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\ud611\uc5c5"},"\ud611\uc5c5"),(0,a.kt)("p",null,"\ub808\ubca8 2 \ub9c8\uc9c0\ub9c9\uc5d0 \ud611\uc5c5 \ubbf8\uc158\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc9c0\uae08\uae4c\uc9c0\ub294 \ubc31\uc5d4\ub4dc \ud06c\ub8e8\ub4e4\uacfc \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud558\uba74\uc11c \ud611\uc5c5\uc744 \uacbd\ud5d8\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0\ub294 \ud504\ub7f0\ud2b8\uc5d4\ub4dc \ud06c\ub8e8\uc640 \ud611\uc5c5\uc744 \ud588\ub2e4. \uc18c\ud1b5\uc740 \uc798 \ub41c \uac83 \uac19\uc9c0\ub9cc API \uba85\uc138\ub97c \uc815\ud558\ub294 \ubd80\ubd84\uc774 \uc544\uc9c1 \ubbf8\uc219\ud55c \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,"\ub808\ubca8 3 \ub54c\ubd80\ud130 \ubcf8\uaca9\uc801\uc73c\ub85c \ud504\ub85c\uc81d\ud2b8\uac00 \uc2dc\uc791\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud300\uc744 \uc704\ud574 \uc5b4\ub5a4 \uac83\uc744 \ud560 \uc218 \uc788\uc744\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud574\ubd10\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\ub808\ubca8-2\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70"},"\ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70"),(0,a.kt)("p",null,"\ud68c\uace0 \uc791\uc131\ud558\uba74\uc11c \ub808\ubca8 2\uc5d0\uc11c \ud588\ub358 \uac83\ub4e4\uc744 \ubc18\ucd94\ud574 \ubd24\ub294\ub370 \ubd80\uc871\ud55c \uc810\uc740 \ub9ce\uc558\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \uac00\uace0 \uc788\ub294 \uac83 \uac19\ub2e4.\n\uc77d\uace0 \uc2f6\uc740 \ucc45\ub3c4 \uc77d\uace0, \ubd80\uc871\ud55c \ubd80\ubd84 \ucc44\uc6b0\uba74\uc11c \uc26c\uc5b4\uc57c\uaca0\ub2e4."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9d8ee3a8.3e89b3f5.js b/assets/js/9d8ee3a8.22bab478.js similarity index 59% rename from assets/js/9d8ee3a8.3e89b3f5.js rename to assets/js/9d8ee3a8.22bab478.js index 5d2c77bbe..52809d866 100644 --- a/assets/js/9d8ee3a8.3e89b3f5.js +++ b/assets/js/9d8ee3a8.22bab478.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5962],{71297:e=>{e.exports=JSON.parse('{"label":"OOP","permalink":"/tags/oop","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5962],{71297:e=>{e.exports=JSON.parse('{"label":"OOP","permalink":"/tags/oop","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/9dec6b67.a1bd30cc.js b/assets/js/9dec6b67.ce191000.js similarity index 84% rename from assets/js/9dec6b67.a1bd30cc.js rename to assets/js/9dec6b67.ce191000.js index 27d61ac7b..1798c799d 100644 --- a/assets/js/9dec6b67.a1bd30cc.js +++ b/assets/js/9dec6b67.ce191000.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8524],{88221:a=>{a.exports=JSON.parse('{"label":"DataBase","permalink":"/tags/data-base","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8524],{88221:a=>{a.exports=JSON.parse('{"label":"DataBase","permalink":"/tags/data-base","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/9e2e3982.6ece4d4c.js b/assets/js/9e2e3982.6ece4d4c.js new file mode 100644 index 000000000..6b7efde37 --- /dev/null +++ b/assets/js/9e2e3982.6ece4d4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7617],{15448:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>l,metadata:()=>s,toc:()=>o});var r=n(85893),i=n(3905);const l={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",slug:"route-image-intro",tags:["image","awt"]},a=void 0,s={permalink:"/route-image-intro",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",source:"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",description:"./route.png",date:"2023-07-27T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 27\uc77c",tags:[{label:"image",permalink:"/tags/image"},{label:"awt",permalink:"/tags/awt"}],readingTime:5.865,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",slug:"route-image-intro",tags:["image","awt"]},unlisted:!1,prevItem:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",permalink:"/mock-static-method"},nextItem:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",permalink:"/java-spring-springboot"}},c={authorsImageUrls:[]},o=[{value:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784",id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc758-\ucc45\uc784",level:3},{value:"\uace0\ub824\ud55c \uae30\uc220",id:"\uace0\ub824\ud55c-\uae30\uc220",level:3},{value:"Python & Matplotlib",id:"python--matplotlib",level:2},{value:"Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac",id:"java-awt-\uc774\uc678\uc758-\ub77c\uc774\ube0c\ub7ec\ub9ac",level:3},{value:"Java & AWT(Abstract Window Toolkit)",id:"java--awtabstract-window-toolkit",level:3},{value:"\uae30\uc220 \uc120\ud0dd",id:"\uae30\uc220-\uc120\ud0dd",level:3},{value:"\uc720\uc9c0 \ubcf4\uc218",id:"\uc720\uc9c0-\ubcf4\uc218",level:3},{value:"\ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00",id:"\ub808\ubca8-3\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70-\ub0b4\uc6a9-\ucd94\uac00",level:3}];function d(e){const t={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"./route.png",src:n(29632).Z+"",width:"1014",height:"902"})}),"\n",(0,r.jsx)(t.h3,{id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc758-\ucc45\uc784",children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784"}),"\n",(0,r.jsxs)(t.p,{children:["\uc704 \uc640\uc774\uc5b4 \ud504\ub808\uc784\uc5d0\uc11c ",(0,r.jsx)(t.code,{children:"\uc5ec\ud589 \ud788\uc2a4\ud1a0\ub9ac"}),"\uc640 ",(0,r.jsx)(t.code,{children:"\uc5ec\ud589\uc5d0 \ub300\ud55c \uac10\uc0c1\uc744 \uc704\ud55c \uacbd\ub85c \uc774\ubbf8\uc9c0"}),"\uc758 \uacbd\uc6b0 \ub124\uc774\ubc84 \uc9c0\ub3c4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\ub2f9 \uae30\ub2a5\uc744 \uad6c\ud604\ud560 \uc218 \uc5c6\uc73c\ub2c8 \ub2f9\uc5f0\ud788 \ub9f5 API\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub3c4\ud615 \uadf8\ub9ac\uae30 API(\ub124\uc774\ubc84 \ub9f5 API \uae30\uc900 Polyline)\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub530\ub77c\uc11c \uc774\ubbf8\uc9c0\ub97c \uc9c1\uc811 \uc0dd\uc131\ud558\uac70\ub098, \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uc11c \uc9c1\uc811 \uc704\uacbd\ub3c4\ub97c \uc774\uc6a9\ud558\uc5ec \uadf8\ub824\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:"\ud574\ub2f9 \uc694\uad6c\uc0ac\ud56d\uc744 \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uae30\ub2a5\uc744 \uac00\uc9c4 \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 \ud544\uc694\ud558\ub2e4."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131"}),"\n",(0,r.jsx)(t.li,{children:"\uc120\uacfc \uc810 \ud45c\ud604"}),"\n",(0,r.jsx)(t.li,{children:"\ud22c\uba85\ud55c \ubc30\uacbd\uc0c9"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"\ud604\uc7ac \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \ubc14\uc05c \uc77c\uc815\uacfc \uae30\ub2a5 \uad6c\ud604\uc5d0 \uc788\uc5b4 \uc57d\uac04\uc758 \uc5f0\uc0b0\uc774 \ub4e4\uc5b4\uac04\ub2e4\ub294 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uc5ec \ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30\ub85c \uacb0\uc815\uc744 \ub0b4\ub838\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"\uace0\ub824\ud55c-\uae30\uc220",children:"\uace0\ub824\ud55c \uae30\uc220"}),"\n",(0,r.jsx)(t.p,{children:"\ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uae30 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub610\ub294 \uae30\uc220\ub4e4\uc744 \ud655\uc778\ud574 \ubcf4\uc558\ub2e4."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Python\uc758 Matplotlib"}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.strong,{children:"AWT(Abstract Window Toolkit) [\ucd5c\uc885 \uc120\ud0dd]"})}),"\n",(0,r.jsx)(t.li,{children:"\uc774\ubbf8\uc9c0 \ucc98\ub9ac \ub77c\uc774\ube0c\ub7ec\ub9ac \ubc0f Java\uc5d0\uc11c \ub0b4\ubd80\uc801\uc73c\ub85c Matplotlib \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac (\uc6d0\ud558\ub294 \uae30\ub2a5 \uc5c6\uc74c)"}),"\n",(0,r.jsx)(t.li,{children:"Java Swing, Java FX (\ub2e8\uc21c\ud55c \uc120 \uadf8\ub9ac\uae30 + \uc810 \ucc0d\uae30\ub77c \ubd88\ud544\uc694)"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"python--matplotlib",children:"Python & Matplotlib"}),"\n",(0,r.jsxs)(t.p,{children:["\ub370\uc774\ud130 \uc2dc\uac01\ud654 \ub77c\uc774\ube0c\ub7ec\ub9ac",(0,r.jsx)(t.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 0.2\ucd08"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\ucf54\ub4dc\uac00 \uac04\ub2e8\ud574\uc11c \uc720\uc9c0 \ubcf4\uc218\uc131\uc774 \uc88b\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"AWS Lambda \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ucef4\ud4e8\ud305 \uc11c\ube44\uc2a4\ub098 FastAPI\uc640 \uac19\uc740 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\ub85c \ucd94\uac00\uc801\uc778 API\ub97c \uad6c\ud604\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"Spring Boot\uc5d0\uc11c \ucd94\uac00\uc801\uc778 API \ud638\ucd9c\uc744 \ud574\uc57c\ud558\uace0, \ud655\uc7a5\uc131\uacfc \ube44\ub3d9\uae30 \ucc98\ub9ac \ub4f1 \uace0\ub824 \ud574\uc57c \ud560 \ubd80\ubd84\uc774 \ub9ce\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"java-awt-\uc774\uc678\uc758-\ub77c\uc774\ube0c\ub7ec\ub9ac",children:"Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac"}),"\n",(0,r.jsx)(t.p,{children:"Python\uc774 \uc544\ub2cc Java\uc5d0\uc11c\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub3c4 \uace0\ub824\ub97c \ud574\ubd24\uc9c0\ub9cc \uc694\uad6c\uc0ac\ud56d\uc5d0 \uc801\ud569\ud558\uc9c0 \uc54a\uac70\ub098, \uc801\uc740 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac70\uc6b4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc774 \ub9ce\uc544\uc11c \uc81c\uc678\ud588\ub2e4."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"\ub77c\uc774\ube0c\ub7ec\ub9ac"}),(0,r.jsx)(t.th,{children:"\uc124\uba85"}),(0,r.jsx)(t.th,{children:"\uc81c\uc678 \uc774\uc720"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Swing"}),(0,r.jsx)(t.td,{children:"AWT \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, \ub124\uc774\ud2f0\ube0c UI\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 \ubaa8\ub4e0 \uc6b4\uc601\uccb4\uc81c \uc0c1\uc5d0\uc11c \ub3d9\uc77c\ud55c UI\ub97c \uac00\uc9c0\ub3c4\ub85d \ud568"}),(0,r.jsx)(t.td,{children:"\uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"JavaFX"}),(0,r.jsx)(t.td,{children:"Swing \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, 3\ucc28\uc6d0 \uadf8\ub798\ud53d\uc744 \uc9c0\uc6d0\ud568"}),(0,r.jsx)(t.td,{children:"\uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://github.com/yuriy-g/simple-java-plot",children:"simple-java-plot"})}),(0,r.jsx)(t.td,{children:"AWT\ub85c \uad6c\ud604\ub41c \ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac"}),(0,r.jsx)(t.td,{children:"AWT \uae30\ubc18\uc774\uae34 \ud558\uc9c0\ub9cc \uc9c1\uc811 AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc5d0 \ube44\ud574 \uba54\ub9ac\ud2b8\uac00 \uc5c6\uc74c, \ucee4\uc2a4\ud140 \uc124\uc815 \uae30\ub2a5\uc774 \uc5c6\uc74c"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"https://github.com/sh0nk/matplotlib4j",children:"matplotlib4j"})}),(0,r.jsx)(t.td,{children:"Matplotlib\ub97c Java\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uac8c \ud558\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac"}),(0,r.jsx)(t.td,{children:"\ub0b4\ubd80\uc801\uc73c\ub85c \ud30c\uc774\uc36c \uc0ac\uc6a9\ud558\uae30\uc5d0 \ubb34\uac70\uc6c0, \ubc30\uacbd \ud22c\uba85\ud654 \uae30\ub2a5 \uc5c6\uc74c"})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"java--awtabstract-window-toolkit",children:"Java & AWT(Abstract Window Toolkit)"}),"\n",(0,r.jsxs)(t.p,{children:["\uadf8\ub798\ud53d\uacfc \uc774\ubbf8\uc9c0\ub97c \uadf8\ub9ac\uae30 \uc704\ud55c \ub3c4\uad6c",(0,r.jsx)(t.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 1.75\ucd08"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ubcf4\ub2e4 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc874\uc7ac\ud55c\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub2e4\uc18c \uc18c\uc694\ub418\uae30 \ub54c\ubb38\uc5d0 \ube60\ub978 \uc751\ub2f5 \ubc18\ud658\uc744 \uc704\ud574 \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \uace0\ub824\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"\ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"\uae30\uc220-\uc120\ud0dd",children:"\uae30\uc220 \uc120\ud0dd"}),"\n",(0,r.jsxs)(t.p,{children:["AWT\uc758 \uacbd\uc6b0 Matplotlib\uc5d0 \ube44\ud574 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc788\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub354 \ub9ce\uc774 \uac78\ub9ac\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud558\uc9c0\ub9cc \ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub418\ub294 \ubd80\ubd84, Python\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc778 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uace0\ub824\ud558\uc5ec AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uc720\uc9c0-\ubcf4\uc218",children:"\uc720\uc9c0 \ubcf4\uc218"}),"\n",(0,r.jsxs)(t.p,{children:["AWT\ub77c\ub294 \uc0dd\uc18c\ud55c \uae30\uc220\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc720\uc9c0 \ubcf4\uc218\uc131\uc744 \uc704\ud574 \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub530\ub77c\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ubc29\ubc95\uc73c\ub85c \uacf5\uc720\ud558\uae30\ub85c \ud588\ub2e4."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"\ucf54\ub4dc \ub9ac\ubdf0\uc640 PR\uc744 \ud1b5\ud574 \uc791\uc131\ud55c AWT \ucf54\ub4dc\uc5d0 \ub300\ud55c \uc124\uba85 \ubc0f \ub9ac\ubdf0 \ubc1b\ub294\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"AWT\ub97c \uc0ac\uc6a9\ud55c \ubd80\ubd84\uc744 \ubb38\uc11c\ud654\ud558\uc5ec \uacf5\uc720\ud55c\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"\ub808\ubca8-3\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70-\ub0b4\uc6a9-\ucd94\uac00",children:"\ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00"}),"\n",(0,r.jsxs)(t.p,{children:["\uae30\uc220 \uc120\ud0dd\uc744 \ud558\uae30 \uc704\ud55c \uc2e4\ud589 \uc2dc\uac04 \uce21\uc815\uc5d0 \uc624\ub958\uac00 \uc788\uc5c8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc2e4\ud589 \uc2dc\uac04\uc744 \uc81c\uc678\ud558\uba74 \ud30c\uc774\uc36c\uacfc \ube44\uc2b7\ud55c \uc2dc\uac04\uc548\uc5d0 \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud560 \uc218 \uc788\uc5c8\ub2e4."]})]})}function h(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>o});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=r.createContext({}),o=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,l=e.originalType,c=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),j=o(n),p=i,x=j["".concat(c,".").concat(p)]||j[p]||d[p]||l;return n?r.createElement(x,a(a({ref:t},h),{},{components:n})):r.createElement(x,a({ref:t},h))}));h.displayName="MDXCreateElement"},29632:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png"}}]); \ No newline at end of file diff --git a/assets/js/9e2e3982.e9ee5729.js b/assets/js/9e2e3982.e9ee5729.js deleted file mode 100644 index 41e697ffc..000000000 --- a/assets/js/9e2e3982.e9ee5729.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7617],{3905:(t,e,a)=>{a.d(e,{Zo:()=>m,kt:()=>d});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?l(Object(a),!0).forEach((function(e){r(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function p(t,e){if(null==t)return{};var a,n,r=function(t,e){if(null==t)return{};var a,n,r={},l=Object.keys(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var o=n.createContext({}),u=function(t){var e=n.useContext(o),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},m=function(t){var e=u(t.components);return n.createElement(o.Provider,{value:e},t.children)},k={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},c=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,o=t.parentName,m=p(t,["components","mdxType","originalType","parentName"]),c=u(a),d=r,s=c["".concat(o,".").concat(d)]||c[d]||k[d]||l;return a?n.createElement(s,i(i({ref:e},m),{},{components:a})):n.createElement(s,i({ref:e},m))}));function d(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,i=new Array(l);i[0]=c;var p={};for(var o in e)hasOwnProperty.call(e,o)&&(p[o]=e[o]);p.originalType=t,p.mdxType="string"==typeof t?t:r,i[1]=p;for(var u=2;u<l;u++)i[u]=a[u];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}c.displayName="MDXCreateElement"},57214:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>o,contentTitle:()=>i,default:()=>k,frontMatter:()=>l,metadata:()=>p,toc:()=>u});var n=a(87462),r=(a(67294),a(3905));const l={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",slug:"route-image-intro",tags:["image","awt"]},i=void 0,p={permalink:"/route-image-intro",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",source:"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",description:"./route.png",date:"2023-07-27T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 27\uc77c",tags:[{label:"image",permalink:"/tags/image"},{label:"awt",permalink:"/tags/awt"}],readingTime:5.865,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",slug:"route-image-intro",tags:["image","awt"]},prevItem:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",permalink:"/mock-static-method"},nextItem:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",permalink:"/java-spring-springboot"}},o={authorsImageUrls:[]},u=[{value:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784",id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc758-\ucc45\uc784",level:3},{value:"\uace0\ub824\ud55c \uae30\uc220",id:"\uace0\ub824\ud55c-\uae30\uc220",level:3},{value:"Python & Matplotlib",id:"python--matplotlib",level:2},{value:"Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac",id:"java-awt-\uc774\uc678\uc758-\ub77c\uc774\ube0c\ub7ec\ub9ac",level:3},{value:"Java & AWT(Abstract Window Toolkit)",id:"java--awtabstract-window-toolkit",level:3},{value:"\uae30\uc220 \uc120\ud0dd",id:"\uae30\uc220-\uc120\ud0dd",level:3},{value:"\uc720\uc9c0 \ubcf4\uc218",id:"\uc720\uc9c0-\ubcf4\uc218",level:3},{value:"\ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00",id:"\ub808\ubca8-3\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70-\ub0b4\uc6a9-\ucd94\uac00",level:3}],m={toc:u};function k(t){let{components:e,...l}=t;return(0,r.kt)("wrapper",(0,n.Z)({},m,l,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./route.png",src:a(29632).Z,width:"1014",height:"902"})),(0,r.kt)("h3",{id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc758-\ucc45\uc784"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784"),(0,r.kt)("p",null,"\uc704 \uc640\uc774\uc5b4 \ud504\ub808\uc784\uc5d0\uc11c ",(0,r.kt)("inlineCode",{parentName:"p"},"\uc5ec\ud589 \ud788\uc2a4\ud1a0\ub9ac"),"\uc640 ",(0,r.kt)("inlineCode",{parentName:"p"},"\uc5ec\ud589\uc5d0 \ub300\ud55c \uac10\uc0c1\uc744 \uc704\ud55c \uacbd\ub85c \uc774\ubbf8\uc9c0"),"\uc758 \uacbd\uc6b0 \ub124\uc774\ubc84 \uc9c0\ub3c4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\ub2f9 \uae30\ub2a5\uc744 \uad6c\ud604\ud560 \uc218 \uc5c6\uc73c\ub2c8 \ub2f9\uc5f0\ud788 \ub9f5 API\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub3c4\ud615 \uadf8\ub9ac\uae30 API(\ub124\uc774\ubc84 \ub9f5 API \uae30\uc900 Polyline)\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc774\ubbf8\uc9c0\ub97c \uc9c1\uc811 \uc0dd\uc131\ud558\uac70\ub098, \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uc11c \uc9c1\uc811 \uc704\uacbd\ub3c4\ub97c \uc774\uc6a9\ud558\uc5ec \uadf8\ub824\uc57c \ud55c\ub2e4."),(0,r.kt)("p",null,"\ud574\ub2f9 \uc694\uad6c\uc0ac\ud56d\uc744 \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uae30\ub2a5\uc744 \uac00\uc9c4 \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 \ud544\uc694\ud558\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131"),(0,r.kt)("li",{parentName:"ul"},"\uc120\uacfc \uc810 \ud45c\ud604"),(0,r.kt)("li",{parentName:"ul"},"\ud22c\uba85\ud55c \ubc30\uacbd\uc0c9")),(0,r.kt)("p",null,"\ud604\uc7ac \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \ubc14\uc05c \uc77c\uc815\uacfc \uae30\ub2a5 \uad6c\ud604\uc5d0 \uc788\uc5b4 \uc57d\uac04\uc758 \uc5f0\uc0b0\uc774 \ub4e4\uc5b4\uac04\ub2e4\ub294 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uc5ec \ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30\ub85c \uacb0\uc815\uc744 \ub0b4\ub838\ub2e4."),(0,r.kt)("h3",{id:"\uace0\ub824\ud55c-\uae30\uc220"},"\uace0\ub824\ud55c \uae30\uc220"),(0,r.kt)("p",null,"\ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uae30 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub610\ub294 \uae30\uc220\ub4e4\uc744 \ud655\uc778\ud574 \ubcf4\uc558\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Python\uc758 Matplotlib"),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("strong",{parentName:"li"},"AWT(Abstract Window Toolkit) ","[\ucd5c\uc885 \uc120\ud0dd]")),(0,r.kt)("li",{parentName:"ul"},"\uc774\ubbf8\uc9c0 \ucc98\ub9ac \ub77c\uc774\ube0c\ub7ec\ub9ac \ubc0f Java\uc5d0\uc11c \ub0b4\ubd80\uc801\uc73c\ub85c Matplotlib \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac (\uc6d0\ud558\ub294 \uae30\ub2a5 \uc5c6\uc74c)"),(0,r.kt)("li",{parentName:"ul"},"Java Swing, Java FX (\ub2e8\uc21c\ud55c \uc120 \uadf8\ub9ac\uae30 + \uc810 \ucc0d\uae30\ub77c \ubd88\ud544\uc694)")),(0,r.kt)("h2",{id:"python--matplotlib"},"Python & Matplotlib"),(0,r.kt)("p",null,"\ub370\uc774\ud130 \uc2dc\uac01\ud654 \ub77c\uc774\ube0c\ub7ec\ub9ac",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 0.2\ucd08 "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ucf54\ub4dc\uac00 \uac04\ub2e8\ud574\uc11c \uc720\uc9c0 \ubcf4\uc218\uc131\uc774 \uc88b\ub2e4. "),(0,r.kt)("li",{parentName:"ul"},"AWS Lambda \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ucef4\ud4e8\ud305 \uc11c\ube44\uc2a4\ub098 FastAPI\uc640 \uac19\uc740 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\ub85c \ucd94\uac00\uc801\uc778 API\ub97c \uad6c\ud604\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"Spring Boot\uc5d0\uc11c \ucd94\uac00\uc801\uc778 API \ud638\ucd9c\uc744 \ud574\uc57c\ud558\uace0, \ud655\uc7a5\uc131\uacfc \ube44\ub3d9\uae30 \ucc98\ub9ac \ub4f1 \uace0\ub824 \ud574\uc57c \ud560 \ubd80\ubd84\uc774 \ub9ce\ub2e4.")),(0,r.kt)("h3",{id:"java-awt-\uc774\uc678\uc758-\ub77c\uc774\ube0c\ub7ec\ub9ac"},"Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac"),(0,r.kt)("p",null,"Python\uc774 \uc544\ub2cc Java\uc5d0\uc11c\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub3c4 \uace0\ub824\ub97c \ud574\ubd24\uc9c0\ub9cc \uc694\uad6c\uc0ac\ud56d\uc5d0 \uc801\ud569\ud558\uc9c0 \uc54a\uac70\ub098, \uc801\uc740 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac70\uc6b4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc774 \ub9ce\uc544\uc11c \uc81c\uc678\ud588\ub2e4."),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\ub77c\uc774\ube0c\ub7ec\ub9ac"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc81c\uc678 \uc774\uc720"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Swing"),(0,r.kt)("td",{parentName:"tr",align:null},"AWT \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, \ub124\uc774\ud2f0\ube0c UI\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 \ubaa8\ub4e0 \uc6b4\uc601\uccb4\uc81c \uc0c1\uc5d0\uc11c \ub3d9\uc77c\ud55c UI\ub97c \uac00\uc9c0\ub3c4\ub85d \ud568"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"JavaFX"),(0,r.kt)("td",{parentName:"tr",align:null},"Swing \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, 3\ucc28\uc6d0 \uadf8\ub798\ud53d\uc744 \uc9c0\uc6d0\ud568"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://github.com/yuriy-g/simple-java-plot"},"simple-java-plot")),(0,r.kt)("td",{parentName:"tr",align:null},"AWT\ub85c \uad6c\ud604\ub41c \ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac"),(0,r.kt)("td",{parentName:"tr",align:null},"AWT \uae30\ubc18\uc774\uae34 \ud558\uc9c0\ub9cc \uc9c1\uc811 AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc5d0 \ube44\ud574 \uba54\ub9ac\ud2b8\uac00 \uc5c6\uc74c, \ucee4\uc2a4\ud140 \uc124\uc815 \uae30\ub2a5\uc774 \uc5c6\uc74c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},(0,r.kt)("a",{parentName:"td",href:"https://github.com/sh0nk/matplotlib4j"},"matplotlib4j")),(0,r.kt)("td",{parentName:"tr",align:null},"Matplotlib\ub97c Java\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uac8c \ud558\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac"),(0,r.kt)("td",{parentName:"tr",align:null},"\ub0b4\ubd80\uc801\uc73c\ub85c \ud30c\uc774\uc36c \uc0ac\uc6a9\ud558\uae30\uc5d0 \ubb34\uac70\uc6c0, \ubc30\uacbd \ud22c\uba85\ud654 \uae30\ub2a5 \uc5c6\uc74c")))),(0,r.kt)("h3",{id:"java--awtabstract-window-toolkit"},"Java & AWT(Abstract Window Toolkit)"),(0,r.kt)("p",null,"\uadf8\ub798\ud53d\uacfc \uc774\ubbf8\uc9c0\ub97c \uadf8\ub9ac\uae30 \uc704\ud55c \ub3c4\uad6c",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 1.75\ucd08 "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ubcf4\ub2e4 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub2e4\uc18c \uc18c\uc694\ub418\uae30 \ub54c\ubb38\uc5d0 \ube60\ub978 \uc751\ub2f5 \ubc18\ud658\uc744 \uc704\ud574 \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \uace0\ub824\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4.")),(0,r.kt)("h3",{id:"\uae30\uc220-\uc120\ud0dd"},"\uae30\uc220 \uc120\ud0dd"),(0,r.kt)("p",null,"AWT\uc758 \uacbd\uc6b0 Matplotlib\uc5d0 \ube44\ud574 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc788\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub354 \ub9ce\uc774 \uac78\ub9ac\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub418\ub294 \ubd80\ubd84, Python\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc778 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uace0\ub824\ud558\uc5ec AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4."),(0,r.kt)("h3",{id:"\uc720\uc9c0-\ubcf4\uc218"},"\uc720\uc9c0 \ubcf4\uc218"),(0,r.kt)("p",null,"AWT\ub77c\ub294 \uc0dd\uc18c\ud55c \uae30\uc220\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc720\uc9c0 \ubcf4\uc218\uc131\uc744 \uc704\ud574 \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ubc29\ubc95\uc73c\ub85c \uacf5\uc720\ud558\uae30\ub85c \ud588\ub2e4. "),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"\ucf54\ub4dc \ub9ac\ubdf0\uc640 PR\uc744 \ud1b5\ud574 \uc791\uc131\ud55c AWT \ucf54\ub4dc\uc5d0 \ub300\ud55c \uc124\uba85 \ubc0f \ub9ac\ubdf0 \ubc1b\ub294\ub2e4. "),(0,r.kt)("li",{parentName:"ol"},"AWT\ub97c \uc0ac\uc6a9\ud55c \ubd80\ubd84\uc744 \ubb38\uc11c\ud654\ud558\uc5ec \uacf5\uc720\ud55c\ub2e4.")),(0,r.kt)("h3",{id:"\ub808\ubca8-3\ub97c-\ub9c8\ubb34\ub9ac\ud558\uba70-\ub0b4\uc6a9-\ucd94\uac00"},"\ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00"),(0,r.kt)("p",null,"\uae30\uc220 \uc120\ud0dd\uc744 \ud558\uae30 \uc704\ud55c \uc2e4\ud589 \uc2dc\uac04 \uce21\uc815\uc5d0 \uc624\ub958\uac00 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc2e4\ud589 \uc2dc\uac04\uc744 \uc81c\uc678\ud558\uba74 \ud30c\uc774\uc36c\uacfc \ube44\uc2b7\ud55c \uc2dc\uac04\uc548\uc5d0 \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud560 \uc218 \uc788\uc5c8\ub2e4."))}k.isMDXComponent=!0},29632:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png"}}]); \ No newline at end of file diff --git a/assets/js/9e4087bc.9cf973ca.js b/assets/js/9e4087bc.9cf973ca.js deleted file mode 100644 index 583504b11..000000000 --- a/assets/js/9e4087bc.9cf973ca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3608],{63169:(e,t,a)=>{a.r(t),a.d(t,{default:()=>o});var r=a(67294),l=a(39960),n=a(95999),c=a(10833),m=a(7452);function i(e){let{year:t,posts:a}=e;return r.createElement(r.Fragment,null,r.createElement("h3",null,t),r.createElement("ul",null,a.map((e=>r.createElement("li",{key:e.metadata.date},r.createElement(l.Z,{to:e.metadata.permalink},e.metadata.formattedDate," - ",e.metadata.title))))))}function s(e){let{years:t}=e;return r.createElement("section",{className:"margin-vert--lg"},r.createElement("div",{className:"container"},r.createElement("div",{className:"row"},t.map(((e,t)=>r.createElement("div",{key:t,className:"col col--4 margin-vert--lg"},r.createElement(i,e)))))))}function o(e){let{archive:t}=e;const a=(0,n.I)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),l=(0,n.I)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),i=function(e){const t=e.reduceRight(((e,t)=>{const a=t.metadata.date.split("-")[0],r=e.get(a)??[];return e.set(a,[t,...r])}),new Map);return Array.from(t,(e=>{let[t,a]=e;return{year:t,posts:a}}))}(t.blogPosts);return r.createElement(r.Fragment,null,r.createElement(c.d,{title:a,description:l}),r.createElement(m.Z,null,r.createElement("header",{className:"hero hero--primary"},r.createElement("div",{className:"container"},r.createElement("h1",{className:"hero__title"},a),r.createElement("p",{className:"hero__subtitle"},l))),r.createElement("main",null,i.length>0&&r.createElement(s,{years:i}))))}}}]); \ No newline at end of file diff --git a/assets/js/9e4087bc.d7673a23.js b/assets/js/9e4087bc.d7673a23.js new file mode 100644 index 000000000..cf22cbeff --- /dev/null +++ b/assets/js/9e4087bc.d7673a23.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3608],{63169:(e,s,t)=>{t.r(s),t.d(s,{default:()=>o});t(67294);var r=t(39960),a=t(95999),i=t(10833),n=t(58207),c=t(92503),l=t(85893);function h(e){let{year:s,posts:t}=e;return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c.Z,{as:"h3",id:s,children:s}),(0,l.jsx)("ul",{children:t.map((e=>(0,l.jsx)("li",{children:(0,l.jsxs)(r.Z,{to:e.metadata.permalink,children:[e.metadata.formattedDate," - ",e.metadata.title]})},e.metadata.date)))})]})}function d(e){let{years:s}=e;return(0,l.jsx)("section",{className:"margin-vert--lg",children:(0,l.jsx)("div",{className:"container",children:(0,l.jsx)("div",{className:"row",children:s.map(((e,s)=>(0,l.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,l.jsx)(h,{...e})},s)))})})})}function o(e){let{archive:s}=e;const t=(0,a.I)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),r=(0,a.I)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),h=function(e){const s=e.reduce(((e,s)=>{const t=s.metadata.date.split("-")[0],r=e.get(t)??[];return e.set(t,[s,...r])}),new Map);return Array.from(s,(e=>{let[s,t]=e;return{year:s,posts:t}}))}(s.blogPosts);return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.d,{title:t,description:r}),(0,l.jsxs)(n.Z,{children:[(0,l.jsx)("header",{className:"hero hero--primary",children:(0,l.jsxs)("div",{className:"container",children:[(0,l.jsx)(c.Z,{as:"h1",className:"hero__title",children:t}),(0,l.jsx)("p",{className:"hero__subtitle",children:r})]})}),(0,l.jsx)("main",{children:h.length>0&&(0,l.jsx)(d,{years:h})})]})]})}}}]); \ No newline at end of file diff --git a/assets/js/9e4ad429.26efcf8e.js b/assets/js/9e4ad429.a307a08a.js similarity index 84% rename from assets/js/9e4ad429.26efcf8e.js rename to assets/js/9e4ad429.a307a08a.js index 81baad66b..a4bb38c2a 100644 --- a/assets/js/9e4ad429.26efcf8e.js +++ b/assets/js/9e4ad429.a307a08a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5406],{16060:e=>{e.exports=JSON.parse('{"label":"performance","permalink":"/docs/tags/performance","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615","description":"| \ud14c\uc2a4\ud2b8 | \uc124\uba85 |","permalink":"/docs/performance/types"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5406],{16060:e=>{e.exports=JSON.parse('{"label":"performance","permalink":"/docs/tags/performance","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615","description":"| \ud14c\uc2a4\ud2b8 | \uc124\uba85 |","permalink":"/docs/performance/types"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a0410ab5.192fd50a.js b/assets/js/a0410ab5.c3ca4fe1.js similarity index 81% rename from assets/js/a0410ab5.192fd50a.js rename to assets/js/a0410ab5.c3ca4fe1.js index 24f5be9b3..1a350a7ef 100644 --- a/assets/js/a0410ab5.192fd50a.js +++ b/assets/js/a0410ab5.c3ca4fe1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7843],{76970:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7843],{76970:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a14ec7b5.0ab78cf6.js b/assets/js/a14ec7b5.0ab78cf6.js new file mode 100644 index 000000000..2ef8405fe --- /dev/null +++ b/assets/js/a14ec7b5.0ab78cf6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3833],{44720:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var n=r(85893),s=r(3905);const i={title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",slug:"/test/stairstep",last_update:{date:"2023/04/04"},tags:["test"]},a=void 0,o={id:"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",description:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)",source:"@site/docs/\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8.mdx",sourceDirName:"\ud14c\uc2a4\ud2b8",slug:"/test/stairstep",permalink:"/docs/test/stairstep",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8.mdx",tags:[{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1680566400,formattedLastUpdatedAt:"2023\ub144 4\uc6d4 4\uc77c",frontMatter:{title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",slug:"/test/stairstep",last_update:{date:"2023/04/04"},tags:["test"]},sidebar:"tutorialSidebar",previous:{title:"FIRST",permalink:"/docs/test/first"},next:{title:"TDD heuristics",permalink:"/docs/test/heuristics"}},c={},l=[{value:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)",id:"\uacc4\ub2e8-\ud14c\uc2a4\ud2b8stairstep-test",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const t={br:"br",h3:"h3",p:"p",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uacc4\ub2e8-\ud14c\uc2a4\ud2b8stairstep-test",children:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)"}),"\n",(0,n.jsxs)(t.p,{children:["\ucd94\ud6c4\uc5d0 \ud544\uc694\ub85c \ud560 \ud074\ub798\uc2a4, \ud568\uc218, \ub2e4\ub978 \uad6c\uc870\ub97c \ub9cc\ub4e4\ub3c4\ub85d \uac15\uc81c\ud558\uae30 \uc704\ud574 \uc791\uc131\ud558\ub294 \ud14c\uc2a4\ud2b8",(0,n.jsx)(t.br,{}),"\n","\uc544\ubb34\ub7f0 \ub2e8\uc815\ubb38\uc774 \uc5c6\uc744 \uc218\ub3c4 \uc788\uace0, \uae30\ub2a5\uc774 \uc870\uae08 \ub354 \uad6c\ud604\ub41c\ub2e4\uba74 \uc81c\uac70\ud558\uace0 \ud3ec\uad04\uc801\uc778 \ud14c\uc2a4\ud2b8\ub85c \ub300\uc2e0\ud560 \uc218 \uc788\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ubcf5\uc7a1\ub3c4\ub97c \ud544\uc694\ud55c \uc218\uc900\uae4c\uc9c0 \uc810\uc9c4\uc801\uc73c\ub85c \uc99d\uac00\uc2dc\ud0ac \uc218 \uc788\uac8c \ub3c4\uc640\uc8fc\ub294 \uacc4\ub2e8 \uc5ed\ud560\uc744 \ud558\uae30 \ub54c\ubb38\uc5d0 \uacc4\ub2e8 \ud14c\uc2a4\ud2b8\ub77c\uace0 \ubd80\ub978\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsx)(t.p,{children:"\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 p.74"})]})}function u(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function s(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){s(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,s=function(e,t){if(null==e)return{};var r,n,s={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(s[r]=e[r]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,s=e.mdxType,i=e.originalType,c=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=l(r),f=s,b=d["".concat(c,".").concat(f)]||d[f]||p[f]||i;return r?n.createElement(b,a(a({ref:t},u),{},{components:r})):n.createElement(b,a({ref:t},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/a14ec7b5.53e9b93f.js b/assets/js/a14ec7b5.53e9b93f.js deleted file mode 100644 index a813b8bb8..000000000 --- a/assets/js/a14ec7b5.53e9b93f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3833],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>f});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?s(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,s=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),d=l(r),f=a,m=d["".concat(p,".").concat(f)]||d[f]||u[f]||s;return r?n.createElement(m,o(o({ref:t},c),{},{components:r})):n.createElement(m,o({ref:t},c))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var s=r.length,o=new Array(s);o[0]=d;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var l=2;l<s;l++)o[l]=r[l];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},9756:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var n=r(87462),a=(r(67294),r(3905));const s={title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",slug:"/test/stairstep",last_update:{date:"2023/04/04"},tags:["test"]},o=void 0,i={unversionedId:"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",id:"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",description:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)",source:"@site/docs/\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8.mdx",sourceDirName:"\ud14c\uc2a4\ud2b8",slug:"/test/stairstep",permalink:"/docs/test/stairstep",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8.mdx",tags:[{label:"test",permalink:"/docs/tags/test"}],version:"current",lastUpdatedAt:1680566400,formattedLastUpdatedAt:"2023\ub144 4\uc6d4 4\uc77c",frontMatter:{title:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8",slug:"/test/stairstep",last_update:{date:"2023/04/04"},tags:["test"]},sidebar:"tutorialSidebar",previous:{title:"FIRST",permalink:"/docs/test/first"},next:{title:"TDD heuristics",permalink:"/docs/test/heuristics"}},p={},l=[{value:"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)",id:"\uacc4\ub2e8-\ud14c\uc2a4\ud2b8stairstep-test",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:l};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uacc4\ub2e8-\ud14c\uc2a4\ud2b8stairstep-test"},"\uacc4\ub2e8 \ud14c\uc2a4\ud2b8(Stairstep Test)"),(0,a.kt)("p",null,"\ucd94\ud6c4\uc5d0 \ud544\uc694\ub85c \ud560 \ud074\ub798\uc2a4, \ud568\uc218, \ub2e4\ub978 \uad6c\uc870\ub97c \ub9cc\ub4e4\ub3c4\ub85d \uac15\uc81c\ud558\uae30 \uc704\ud574 \uc791\uc131\ud558\ub294 \ud14c\uc2a4\ud2b8",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ubb34\ub7f0 \ub2e8\uc815\ubb38\uc774 \uc5c6\uc744 \uc218\ub3c4 \uc788\uace0, \uae30\ub2a5\uc774 \uc870\uae08 \ub354 \uad6c\ud604\ub41c\ub2e4\uba74 \uc81c\uac70\ud558\uace0 \ud3ec\uad04\uc801\uc778 \ud14c\uc2a4\ud2b8\ub85c \ub300\uc2e0\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcf5\uc7a1\ub3c4\ub97c \ud544\uc694\ud55c \uc218\uc900\uae4c\uc9c0 \uc810\uc9c4\uc801\uc73c\ub85c \uc99d\uac00\uc2dc\ud0ac \uc218 \uc788\uac8c \ub3c4\uc640\uc8fc\ub294 \uacc4\ub2e8 \uc5ed\ud560\uc744 \ud558\uae30 \ub54c\ubb38\uc5d0 \uacc4\ub2e8 \ud14c\uc2a4\ud2b8\ub77c\uace0 \ubd80\ub978\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 p.74"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a3614f73.63484f4e.js b/assets/js/a3614f73.63484f4e.js new file mode 100644 index 000000000..ef302b988 --- /dev/null +++ b/assets/js/a3614f73.63484f4e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8474],{15899:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>o,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>c,toc:()=>j});var t=n(85893),s=n(3905);const l={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",slug:"woowacourse-level1-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,c={permalink:"/woowacourse-level1-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",description:"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.",date:"2023-04-01T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 1\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.48,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",slug:"woowacourse-level1-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",permalink:"/custom-jdbc-template"},nextItem:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",permalink:"/chess-retrospective"}},o={authorsImageUrls:[]},j=[{value:"Keep",id:"keep",level:3},{value:"Problem",id:"problem",level:3},{value:"Try",id:"try",level:3},{value:"\ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70",id:"\ub808\ubca8-1\uc744-\ub9c8\ubb34\ub9ac\ud558\uba70",level:3}];function a(e){const r={br:"br",code:"code",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(r.p,{children:["\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6b0\ud14c\ucf54\ub97c \uc2dc\uc791\ud558\uae30 \uc804 \ub0b4\uac00 \uc815\ud574\ub450\uc5c8\ub358 \ubaa9\ud45c \uc774\uc0c1\uc73c\ub85c \ub2ec\uc131\ud588\uae30 \ub54c\ubb38\uc5d0 \ub9e4\uc6b0 \ub9cc\uc871\uc2a4\ub7fd\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud63c\uc790 \ub3c5\ud559\uc744 \ud560 \ub550 \uc774 \ubc29\ud5a5\uc73c\ub85c \uacf5\ubd80\ud558\ub294 \uac8c \ub9de\ub294\uc9c0 \uacc4\uc18d \ubc18\ucd94\ud558\ub2e4 \uacb0\uad6d \ubb34\uae30\ub825\ud568\uc5d0 \ube60\uc838\ub4e4\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\uc9c0\ub9cc \uc774\uc81c\ub294 \uac19\uc774 \uacf5\ubd80\ud560 \uc0ac\ub78c\ub3c4 \uc788\uace0, \uc774\uc57c\uae30\ud560 \uc0ac\ub78c\ub3c4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc990\uae30\ub294 \uc77c\ub9cc \ub0a8\uc740 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"keep",children:"Keep"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ub098\ub9cc\uc758 \ub8e8\ud2f4 \ub9cc\ub4e4\uae30"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc2a4\uc2a4\ub85c\uac00 \uc678\ubd80\uc758 \uc601\ud5a5\uc744 \ub9ce\uc774 \ubc1b\ub294\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucd5c\ub300\ud55c \uafb8\uc900\ud788 \ud560 \uc218 \uc788\ub294 \uc2dc\uac04\uc744 \ub9cc\ub4dc\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ub9e4\uc77c 8\uc2dc\uc5d0 \ub3c4\ucc29\ud558\uc5ec \uc544\uce68\uc5d0 \ud574\uc57c \ud560 \uc77c\uc744 \uc815\ub9ac\ud558\uac70\ub098, \uc6b0\uc120\uc21c\uc704\uc5d0 \ub530\ub77c \ucc98\ub9ac\ud558\uace0",(0,t.jsx)(r.br,{}),"\n","\uc18c\ud654\ub2a5\ub825\uc774 \ubd80\uc871\ud558\uae30 \ub54c\ubb38\uc5d0 \uc810\uc2ec\uc740 \ub3c4\uc2dc\ub77d(\uadf8\ub798\ubd24\uc790 \uacc4\ub7802\uac1c)\uc744 \uc900\ube44\ud558\uace0",(0,t.jsx)(r.br,{}),"\n","\ud56d\uc0c1 \ub611\uac19\uc740 \ucee8\ub514\uc158\uc744 \uc720\uc9c0\ud558\uae30 \uc704\ud574 \ud56d\uc0c1 6\uc2dc\uc5d0 \uc9d1\uc5d0 \uac04\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\uc81c \ubc14\ube60\uc9c8 \ud14c\ub2c8 \uc77c\ucc0d \uc9d1\uc5d0 \uac00\ub294 \uc77c\uc740 \uc5b4\uca54 \uc218 \uc5c6\uc774 \uc904\uc5b4\ub4e4\uaca0\uc9c0\ub9cc\ud83d\ude22"]}),"\n",(0,t.jsx)(r.p,{children:"\uc120\ud0dd\ub3c4 \ube44\uc6a9\uc774\ub2e4. \uc55e\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\uc774 \ud544\uc694 \uc5c6\ub294 \ubd80\ubd84\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\ub4e4\uc5b4\uc57c\uaca0\ub2e4."}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uae30"})}),"\n",(0,t.jsxs)(r.p,{children:["10\uba85 \uc815\ub3c4\uc758 \ud06c\ub8e8\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b0\uace0 \uce5c\ud558\uac8c \uc9c0\ub0b8\ub2e4\uba74 \uc131\uacf5\uc801\uc774\ub77c\uace0 \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\ub2e4 \ubcf4\ub2c8 \ub354 \ub9ce\uc740 \ud06c\ub8e8\ub4e4\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b4 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c\ub3c4 \ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uace0 \uc544\ubb34 \ub54c\ub098 \ub9d0\uc744 \uac78 \uc218 \uc788\ub294 \ud06c\ub8e8\uac00 \ub298\uc5b4\ub098\uae38 :)"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uae00\uc4f0\uae30"})}),"\n",(0,t.jsxs)(r.p,{children:["\uae00\uc744 \uc798 \uc4f0\ub294 \ud3b8\uc740 \uc544\ub2c8\uc9c0\ub9cc \uafb8\uc900\ud788 \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub9e4 \ubbf8\uc158\ub9c8\ub2e4 \ud68c\uace0\ub97c \uc791\uc131\ud558\ub2c8 \uc0dd\uac01\ub3c4 \uc815\ub9ac\ub418\uace0 \uac1c\uc120\uc810\ub3c4 \ucc3e\uc744 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc5d0\ub294 \ub808\ubca8\ub9c8\ub2e4 \uae00\uc4f0\uae30\ub97c \uc9c4\ud589\ud558\ub294\ub370, \uc6b4\uc774 \uc88b\uac8c \uae00\uc4f0\uae30 \uc0c1\uc744 \ubc1b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc0ac\uc2e4 \uac89\uc73c\ub85c \ub4dc\ub7ec\ub0b4\uc9c0 \uc54a\uc558\uc9c0\ub9cc \uaf2d \ubc1b\uc544\ubcf4\uace0 \uc2f6\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uae00\uc4f0\uae30 \uc870\uc6d0, \ud22c\ud45c\ud574 \uc900 \ud06c\ub8e8\ub4e4\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514"})}),"\n",(0,t.jsxs)(r.p,{children:["\ub204\ub204, \uc8fc\ub178, \ub2e4\uc990, \ub9d0\ub791, \ubc15\uc2a4\ud130, \uc624\uc789, \uae43\uc9f1\uc640 \ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514\ub97c \uc9c4\ud589\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uacfc\uc5f0 \ub3c4\uc6c0\uc774 \ub420\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud558\uba74\uc11c \uc131\uc7a5\uc744 \ub9ce\uc774 \ud55c \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud22c\uc790\ud55c \uc2dc\uac04 \ub300\ube44 \uac00\uc131\ube44\uac00 \uc88b\uc740 \ud65c\ub3d9\uc774\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub204\ub204\uac00 \uc2a4\ud130\ub514\uc7a5\uc778\ub370 \uacfc\uc5f0 \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00\ub824\ub098?"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ub808\ubca8 \uc778\ud130\ubdf0"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc778\ud130\ubdf0\ud560 \ub54c \ub9ce\uc774 \ub5a8\uc9c0 \uc54a\uc544\uc11c \uc88b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub0a8\ub4e4 \uc55e\uc5d0\uc11c \uc774\uc57c\uae30\ub97c \ud558\uac70\ub098, \uba74\uc811\uc744 \ubcf4\uba74 \ud56d\uc0c1 \uc5c4\uccad \ub5a8\uc5b4\uc11c \uac71\uc815\ud588\ub294\ub370",(0,t.jsx)(r.br,{}),"\n","\uae30\uc220\uc801\uc778 \uc9c8\ubb38\uc744 \ubc1b\uc558\uc744 \ub54c \ub5a8\uc9c0 \uc54a\uace0 \uc798 \ub300\ub2f5\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \ub2e4\ub978 \ud06c\ub8e8\uac00 \uc9c8\ubb38\ud588\uc744 \ub54c, \ucd5c\ub300\ud55c \uc774\ud574\ud558\uae30 \uc27d\uac8c \uc124\uba85\ud558\ub824\uace0 \ud588\ub358 \uacbd\ud5d8\uc774 \ub3c4\uc6c0\uc774 \ub41c \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\ud6c4 \ub808\ubca8 \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc740 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:"\ub300\ub2f5\ud558\uba74\uc11c \uc9c8\ubb38\uc744 \uacc4\uc18d \uc0dd\uac01\ud558\uba70 \uc78a\uc5b4\ubc84\ub9ac\uc9c0 \ub9d0\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\ub450\uad04\uc2dd \ud45c\ud604"}),"\n",(0,t.jsx)(r.li,{children:"\uc124\uba85\ud558\ub2e4\uac00 \uc798\ubabb \uc124\uba85\ud55c \uac83 \uac19\uc73c\uba74 \ub2e4 \ub04a\uace0 \ub2e4\uc2dc \uc774\uc57c\uae30\ud574\ub3c4 \ub420\uc9c0 \ubb3c\uc5b4\ubcf4\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\uc124\uba85\ud560 \uc218 \uc788\uc744\ub9cc\ud07c \uc2dc\uac04 \ucda9\ubd84\ud788 \uac00\uc9c0\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\uc778\ud130\ubdf0\uc5b4\uc758 \uc9c8\ubb38 \uc758\ub3c4\ub97c \uba85\ud655\ud788 \uc774\ud574\ud558\uc9c0 \ubabb\ud588\ub2e4\uba74 \uc758\ub3c4 \ub2e4\uc2dc \ubb3c\uc5b4\ubcf4\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\ub05d\ub9fa\ub294 \ubd80\ubd84 \uc5f0\uc2b5\ud558\uae30(\uc790\uc2e0\uac10 \uc788\uac8c)"}),"\n",(0,t.jsx)(r.li,{children:"\uae30\uc220\uc801\uc778 \uc9d1\ucc29\uac00\uc9c0\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud788 \uc900\ube44\ud588\uc73c\uba74 \ud611\uc5c5 \uad00\ub828 \uc9c8\ubb38\ub3c4 \uc900\ube44\ud558\uae30"}),"\n"]}),"\n",(0,t.jsx)(r.h3,{id:"problem",children:"Problem"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uac00\uc7a5 \uc5b4\ub824\uc6b4 \ud65c\ub3d9 \uc911 \ud558\ub098\ub77c\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud398\uc5b4\ub294 \ub9e4\ubc88 \ubc14\ub00c\uace0, \ubbf8\uc158\uc758 \ubcf5\uc7a1\ub3c4\ub3c4 \uc99d\uac00\ud558\uae30 \ub54c\ubb38\uc778 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc18c\ud1b5 \ub2a5\ub825, \uc2dc\uac04\uad00\ub9ac\uac00 \ubd80\uc871\ud588\uace0, \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\uc9c0\ub9cc \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uace0, \ud68c\uace0\ub97c \ud558\ub2e4 \ubcf4\ub2c8 \ub098\ub9cc\uc758 \ub178\ud558\uc6b0\uac00 \uc313\uc774\ub294 \ub290\ub08c\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub808\ubca8 2\uc5d0\uc11c\ub294 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc120\ud558\uc5ec \ud568\uaed8\ud558\uace0 \uc2f6\uc740 \ud398\uc5b4\uac00 \ub418\uace0 \uc2f6\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uc9d1\uc911\ud558\ub294 \uc2dc\uac04\u23f1\ufe0f \ubd80\uc871"})}),"\n",(0,t.jsxs)(r.p,{children:["\ub808\ubca8 1\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc9d1\uc911\ud558\ub294 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\ub978 \uc544\uce68\uacfc \uc624\ud6c4\uc5d0 \uac1c\uc778\uc801\uc73c\ub85c \uc9d1\uc911\ud560 \uc218 \uc788\ub294 \uacf5\uac04\uc744 \uc608\uc57d\ud574\uc11c \uc628\uc804\ud788 \ub098\ub9cc\uc758 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"try",children:"Try"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ud5c8\ube0c\ud83c\udf3f\uc640\uc758 \ud2f0\ud0c0\uc784?"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc744 \ub298\ub9b4 \ubc29\ubc95\uc744 \uc0dd\uac01\ud558\ub2e4\uac00 \ub300\ud654\ub97c \ub098\ub204\uc9c0 \ubabb\ud55c \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \uae5c\uc9dd \ucee4\ud53c\ucc57\uc744 \ud558\uba74 \uc5b4\ub5a8\uae4c \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc608\ub97c \ub4e4\uc5b4 \uc7a1\ub2f4\ubc29\uc5d0 ",(0,t.jsx)(r.code,{children:"\uc800\uc640 \ucee4\ud53c\ucc57 \ud558\uc2e4 \ubd84 :)"})," \ud558\uba74\uc11c \uc62c\ub9b4 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucc38\uc5ec\ud558\ub294 \uc0ac\ub78c\uc774 \uc788\uc744\uc9c0, \uc548 \uc88b\uac8c \ubcf4\ub294 \uac8c \uc544\ub2d0\uc9c0 \uac71\uc815\ub418\uc9c0\ub9cc \uadf8\ub798\ub3c4 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc800\ub791 \ud5c8\ube0c\ud2f0 \ud55c\uc794 \ud558\uc2e4\ub798\uc694?"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uae30\uc220\uc801\uc778 \ubd80\ubd84"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc5d0 \uc870\uae08 \ub354 \ubb34\uac8c\ub97c \ub450\ub2e4 \ubcf4\ub2c8 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc774 \ubd80\uc871\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc2dc\uac04\uc758 \uc5ec\uc720\uac00 \ub420 \ub54c \ucc45\uc744 \uc870\uae08\uc529 \uc77d\uc5b4\uc57c\uaca0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ube14\ub85c\uadf8\uc5d0 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \ub9ce\uc774 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\ub294 \uc2dc\uac04\ub3c4 \uac00\uc838\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ub808\ubca8-1\uc744-\ub9c8\ubb34\ub9ac\ud558\uba70",children:"\ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70"}),"\n",(0,t.jsxs)(r.p,{children:["\uc2dc\uac04\uc774 \ube60\ub974\uac8c \ud758\ub7ec\uac14\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud0c0\uc778\uc5d0\uac8c \uc88b\uc740 \uc601\ud5a5\uc744 \uc8fc\uae30\uc704\ud574, \ubc29\ud559\ub3d9\uc548 \ub098\ub97c \ucc59\uae30\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub610\ud55c \ud568\uaed8 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc744 \ubaa9\ud45c\ub85c \uc55e\uc73c\ub85c\ub3c4 \uafb8\uc900\ud788 \uc758\uc2dd\uc801 \ub178\ub825\uc744 \ud574\uc57c\uaca0\ub2e4."]})]})}function p(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>j});var t=n(67294);function s(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function l(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function i(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?l(Object(n),!0).forEach((function(r){s(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function c(e,r){if(null==e)return{};var n,t,s=function(e,r){if(null==e)return{};var n,t,s={},l=Object.keys(e);for(t=0;t<l.length;t++)n=l[t],r.indexOf(n)>=0||(s[n]=e[n]);return s}(e,r);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(t=0;t<l.length;t++)n=l[t],r.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var o=t.createContext({}),j=function(e){var r=t.useContext(o),n=r;return e&&(n="function"==typeof e?e(r):i(i({},r),e)),n},a={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},p=t.forwardRef((function(e,r){var n=e.components,s=e.mdxType,l=e.originalType,o=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),x=j(n),d=s,h=x["".concat(o,".").concat(d)]||x[d]||a[d]||l;return n?t.createElement(h,i(i({ref:r},p),{},{components:n})):t.createElement(h,i({ref:r},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/a3614f73.e670cd3b.js b/assets/js/a3614f73.e670cd3b.js deleted file mode 100644 index 8be77e0d3..000000000 --- a/assets/js/a3614f73.e670cd3b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8474],{3905:(e,t,r)=>{r.d(t,{Zo:()=>i,kt:()=>s});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var m=n.createContext({}),u=function(e){var t=n.useContext(m),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},i=function(e){var t=u(e.components);return n.createElement(m.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,m=e.parentName,i=o(e,["components","mdxType","originalType","parentName"]),k=u(r),s=a,b=k["".concat(m,".").concat(s)]||k[s]||c[s]||p;return r?n.createElement(b,l(l({ref:t},i),{},{components:r})):n.createElement(b,l({ref:t},i))}));function s(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=k;var o={};for(var m in t)hasOwnProperty.call(t,m)&&(o[m]=t[m]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var u=2;u<p;u++)l[u]=r[u];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}k.displayName="MDXCreateElement"},8797:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>m,contentTitle:()=>l,default:()=>c,frontMatter:()=>p,metadata:()=>o,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",slug:"woowacourse-level1-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,o={permalink:"/woowacourse-level1-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",description:"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.",date:"2023-04-01T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 1\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.48,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",slug:"woowacourse-level1-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",permalink:"/custom-jdbc-template"},nextItem:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",permalink:"/chess-retrospective"}},m={authorsImageUrls:[]},u=[{value:"Keep",id:"keep",level:3},{value:"Problem",id:"problem",level:3},{value:"Try",id:"try",level:3},{value:"\ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70",id:"\ub808\ubca8-1\uc744-\ub9c8\ubb34\ub9ac\ud558\uba70",level:3}],i={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},i,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ud14c\ucf54\ub97c \uc2dc\uc791\ud558\uae30 \uc804 \ub0b4\uac00 \uc815\ud574\ub450\uc5c8\ub358 \ubaa9\ud45c \uc774\uc0c1\uc73c\ub85c \ub2ec\uc131\ud588\uae30 \ub54c\ubb38\uc5d0 \ub9e4\uc6b0 \ub9cc\uc871\uc2a4\ub7fd\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud63c\uc790 \ub3c5\ud559\uc744 \ud560 \ub550 \uc774 \ubc29\ud5a5\uc73c\ub85c \uacf5\ubd80\ud558\ub294 \uac8c \ub9de\ub294\uc9c0 \uacc4\uc18d \ubc18\ucd94\ud558\ub2e4 \uacb0\uad6d \ubb34\uae30\ub825\ud568\uc5d0 \ube60\uc838\ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uc774\uc81c\ub294 \uac19\uc774 \uacf5\ubd80\ud560 \uc0ac\ub78c\ub3c4 \uc788\uace0, \uc774\uc57c\uae30\ud560 \uc0ac\ub78c\ub3c4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc990\uae30\ub294 \uc77c\ub9cc \ub0a8\uc740 \uac83 \uac19\ub2e4. "),(0,a.kt)("h3",{id:"keep"},"Keep"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub098\ub9cc\uc758 \ub8e8\ud2f4 \ub9cc\ub4e4\uae30")," "),(0,a.kt)("p",null,"\uc2a4\uc2a4\ub85c\uac00 \uc678\ubd80\uc758 \uc601\ud5a5\uc744 \ub9ce\uc774 \ubc1b\ub294\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\ub300\ud55c \uafb8\uc900\ud788 \ud560 \uc218 \uc788\ub294 \uc2dc\uac04\uc744 \ub9cc\ub4dc\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,a.kt)("p",null,"\ub9e4\uc77c 8\uc2dc\uc5d0 \ub3c4\ucc29\ud558\uc5ec \uc544\uce68\uc5d0 \ud574\uc57c \ud560 \uc77c\uc744 \uc815\ub9ac\ud558\uac70\ub098, \uc6b0\uc120\uc21c\uc704\uc5d0 \ub530\ub77c \ucc98\ub9ac\ud558\uace0",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\ud654\ub2a5\ub825\uc774 \ubd80\uc871\ud558\uae30 \ub54c\ubb38\uc5d0 \uc810\uc2ec\uc740 \ub3c4\uc2dc\ub77d(\uadf8\ub798\ubd24\uc790 \uacc4\ub7802\uac1c)\uc744 \uc900\ube44\ud558\uace0",(0,a.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \ub611\uac19\uc740 \ucee8\ub514\uc158\uc744 \uc720\uc9c0\ud558\uae30 \uc704\ud574 \ud56d\uc0c1 6\uc2dc\uc5d0 \uc9d1\uc5d0 \uac04\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc81c \ubc14\ube60\uc9c8 \ud14c\ub2c8 \uc77c\ucc0d \uc9d1\uc5d0 \uac00\ub294 \uc77c\uc740 \uc5b4\uca54 \uc218 \uc5c6\uc774 \uc904\uc5b4\ub4e4\uaca0\uc9c0\ub9cc\ud83d\ude22 "),(0,a.kt)("p",null,"\uc120\ud0dd\ub3c4 \ube44\uc6a9\uc774\ub2e4. \uc55e\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\uc774 \ud544\uc694 \uc5c6\ub294 \ubd80\ubd84\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\ub4e4\uc5b4\uc57c\uaca0\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uae30")," "),(0,a.kt)("p",null,"10\uba85 \uc815\ub3c4\uc758 \ud06c\ub8e8\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b0\uace0 \uce5c\ud558\uac8c \uc9c0\ub0b8\ub2e4\uba74 \uc131\uacf5\uc801\uc774\ub77c\uace0 \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\ub2e4 \ubcf4\ub2c8 \ub354 \ub9ce\uc740 \ud06c\ub8e8\ub4e4\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b4 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c\ub3c4 \ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uace0 \uc544\ubb34 \ub54c\ub098 \ub9d0\uc744 \uac78 \uc218 \uc788\ub294 \ud06c\ub8e8\uac00 \ub298\uc5b4\ub098\uae38 :) "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uae00\uc4f0\uae30")," "),(0,a.kt)("p",null,"\uae00\uc744 \uc798 \uc4f0\ub294 \ud3b8\uc740 \uc544\ub2c8\uc9c0\ub9cc \uafb8\uc900\ud788 \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9e4 \ubbf8\uc158\ub9c8\ub2e4 \ud68c\uace0\ub97c \uc791\uc131\ud558\ub2c8 \uc0dd\uac01\ub3c4 \uc815\ub9ac\ub418\uace0 \uac1c\uc120\uc810\ub3c4 \ucc3e\uc744 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\ub2e4. "),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc5d0\ub294 \ub808\ubca8\ub9c8\ub2e4 \uae00\uc4f0\uae30\ub97c \uc9c4\ud589\ud558\ub294\ub370, \uc6b4\uc774 \uc88b\uac8c \uae00\uc4f0\uae30 \uc0c1\uc744 \ubc1b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc2e4 \uac89\uc73c\ub85c \ub4dc\ub7ec\ub0b4\uc9c0 \uc54a\uc558\uc9c0\ub9cc \uaf2d \ubc1b\uc544\ubcf4\uace0 \uc2f6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae00\uc4f0\uae30 \uc870\uc6d0, \ud22c\ud45c\ud574 \uc900 \ud06c\ub8e8\ub4e4\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514")," "),(0,a.kt)("p",null,"\ub204\ub204, \uc8fc\ub178, \ub2e4\uc990, \ub9d0\ub791, \ubc15\uc2a4\ud130, \uc624\uc789, \uae43\uc9f1\uc640 \ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514\ub97c \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uacfc\uc5f0 \ub3c4\uc6c0\uc774 \ub420\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud558\uba74\uc11c \uc131\uc7a5\uc744 \ub9ce\uc774 \ud55c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud22c\uc790\ud55c \uc2dc\uac04 \ub300\ube44 \uac00\uc131\ube44\uac00 \uc88b\uc740 \ud65c\ub3d9\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub204\ub204\uac00 \uc2a4\ud130\ub514\uc7a5\uc778\ub370 \uacfc\uc5f0 \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00\ub824\ub098? "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub808\ubca8 \uc778\ud130\ubdf0")),(0,a.kt)("p",null,"\uc778\ud130\ubdf0\ud560 \ub54c \ub9ce\uc774 \ub5a8\uc9c0 \uc54a\uc544\uc11c \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0a8\ub4e4 \uc55e\uc5d0\uc11c \uc774\uc57c\uae30\ub97c \ud558\uac70\ub098, \uba74\uc811\uc744 \ubcf4\uba74 \ud56d\uc0c1 \uc5c4\uccad \ub5a8\uc5b4\uc11c \uac71\uc815\ud588\ub294\ub370",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc220\uc801\uc778 \uc9c8\ubb38\uc744 \ubc1b\uc558\uc744 \ub54c \ub5a8\uc9c0 \uc54a\uace0 \uc798 \ub300\ub2f5\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \ub2e4\ub978 \ud06c\ub8e8\uac00 \uc9c8\ubb38\ud588\uc744 \ub54c, \ucd5c\ub300\ud55c \uc774\ud574\ud558\uae30 \uc27d\uac8c \uc124\uba85\ud558\ub824\uace0 \ud588\ub358 \uacbd\ud5d8\uc774 \ub3c4\uc6c0\uc774 \ub41c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ud6c4 \ub808\ubca8 \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc740 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\ub300\ub2f5\ud558\uba74\uc11c \uc9c8\ubb38\uc744 \uacc4\uc18d \uc0dd\uac01\ud558\uba70 \uc78a\uc5b4\ubc84\ub9ac\uc9c0 \ub9d0\uae30 "),(0,a.kt)("li",{parentName:"ul"},"\ub450\uad04\uc2dd \ud45c\ud604"),(0,a.kt)("li",{parentName:"ul"},"\uc124\uba85\ud558\ub2e4\uac00 \uc798\ubabb \uc124\uba85\ud55c \uac83 \uac19\uc73c\uba74 \ub2e4 \ub04a\uace0 \ub2e4\uc2dc \uc774\uc57c\uae30\ud574\ub3c4 \ub420\uc9c0 \ubb3c\uc5b4\ubcf4\uae30 "),(0,a.kt)("li",{parentName:"ul"},"\uc124\uba85\ud560 \uc218 \uc788\uc744\ub9cc\ud07c \uc2dc\uac04 \ucda9\ubd84\ud788 \uac00\uc9c0\uae30"),(0,a.kt)("li",{parentName:"ul"},"\uc778\ud130\ubdf0\uc5b4\uc758 \uc9c8\ubb38 \uc758\ub3c4\ub97c \uba85\ud655\ud788 \uc774\ud574\ud558\uc9c0 \ubabb\ud588\ub2e4\uba74 \uc758\ub3c4 \ub2e4\uc2dc \ubb3c\uc5b4\ubcf4\uae30"),(0,a.kt)("li",{parentName:"ul"},"\ub05d\ub9fa\ub294 \ubd80\ubd84 \uc5f0\uc2b5\ud558\uae30(\uc790\uc2e0\uac10 \uc788\uac8c)"),(0,a.kt)("li",{parentName:"ul"},"\uae30\uc220\uc801\uc778 \uc9d1\ucc29\uac00\uc9c0\uae30"),(0,a.kt)("li",{parentName:"ul"},"\uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud788 \uc900\ube44\ud588\uc73c\uba74 \ud611\uc5c5 \uad00\ub828 \uc9c8\ubb38\ub3c4 \uc900\ube44\ud558\uae30")),(0,a.kt)("h3",{id:"problem"},"Problem"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d")," "),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uac00\uc7a5 \uc5b4\ub824\uc6b4 \ud65c\ub3d9 \uc911 \ud558\ub098\ub77c\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud398\uc5b4\ub294 \ub9e4\ubc88 \ubc14\ub00c\uace0, \ubbf8\uc158\uc758 \ubcf5\uc7a1\ub3c4\ub3c4 \uc99d\uac00\ud558\uae30 \ub54c\ubb38\uc778 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\ud1b5 \ub2a5\ub825, \uc2dc\uac04\uad00\ub9ac\uac00 \ubd80\uc871\ud588\uace0, \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uace0, \ud68c\uace0\ub97c \ud558\ub2e4 \ubcf4\ub2c8 \ub098\ub9cc\uc758 \ub178\ud558\uc6b0\uac00 \uc313\uc774\ub294 \ub290\ub08c\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 2\uc5d0\uc11c\ub294 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc120\ud558\uc5ec \ud568\uaed8\ud558\uace0 \uc2f6\uc740 \ud398\uc5b4\uac00 \ub418\uace0 \uc2f6\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc9d1\uc911\ud558\ub294 \uc2dc\uac04\u23f1\ufe0f \ubd80\uc871")," "),(0,a.kt)("p",null,"\ub808\ubca8 1\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc9d1\uc911\ud558\ub294 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub978 \uc544\uce68\uacfc \uc624\ud6c4\uc5d0 \uac1c\uc778\uc801\uc73c\ub85c \uc9d1\uc911\ud560 \uc218 \uc788\ub294 \uacf5\uac04\uc744 \uc608\uc57d\ud574\uc11c \uc628\uc804\ud788 \ub098\ub9cc\uc758 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"try"},"Try"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud5c8\ube0c\ud83c\udf3f\uc640\uc758 \ud2f0\ud0c0\uc784?")," "),(0,a.kt)("p",null,"\uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc744 \ub298\ub9b4 \ubc29\ubc95\uc744 \uc0dd\uac01\ud558\ub2e4\uac00 \ub300\ud654\ub97c \ub098\ub204\uc9c0 \ubabb\ud55c \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \uae5c\uc9dd \ucee4\ud53c\ucc57\uc744 \ud558\uba74 \uc5b4\ub5a8\uae4c \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\ub97c \ub4e4\uc5b4 \uc7a1\ub2f4\ubc29\uc5d0 ",(0,a.kt)("inlineCode",{parentName:"p"},"\uc800\uc640 \ucee4\ud53c\ucc57 \ud558\uc2e4 \ubd84 :)")," \ud558\uba74\uc11c \uc62c\ub9b4 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc38\uc5ec\ud558\ub294 \uc0ac\ub78c\uc774 \uc788\uc744\uc9c0, \uc548 \uc88b\uac8c \ubcf4\ub294 \uac8c \uc544\ub2d0\uc9c0 \uac71\uc815\ub418\uc9c0\ub9cc \uadf8\ub798\ub3c4 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc800\ub791 \ud5c8\ube0c\ud2f0 \ud55c\uc794 \ud558\uc2e4\ub798\uc694? "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uae30\uc220\uc801\uc778 \ubd80\ubd84")," "),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc5d0 \uc870\uae08 \ub354 \ubb34\uac8c\ub97c \ub450\ub2e4 \ubcf4\ub2c8 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc774 \ubd80\uc871\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2dc\uac04\uc758 \uc5ec\uc720\uac00 \ub420 \ub54c \ucc45\uc744 \uc870\uae08\uc529 \uc77d\uc5b4\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube14\ub85c\uadf8\uc5d0 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \ub9ce\uc774 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\ub294 \uc2dc\uac04\ub3c4 \uac00\uc838\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\ub808\ubca8-1\uc744-\ub9c8\ubb34\ub9ac\ud558\uba70"},"\ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70"),(0,a.kt)("p",null,"\uc2dc\uac04\uc774 \ube60\ub974\uac8c \ud758\ub7ec\uac14\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud0c0\uc778\uc5d0\uac8c \uc88b\uc740 \uc601\ud5a5\uc744 \uc8fc\uae30\uc704\ud574, \ubc29\ud559\ub3d9\uc548 \ub098\ub97c \ucc59\uae30\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ud568\uaed8 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc744 \ubaa9\ud45c\ub85c \uc55e\uc73c\ub85c\ub3c4 \uafb8\uc900\ud788 \uc758\uc2dd\uc801 \ub178\ub825\uc744 \ud574\uc57c\uaca0\ub2e4."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a3dddb77.2dd61ce3.js b/assets/js/a3dddb77.0be524dd.js similarity index 59% rename from assets/js/a3dddb77.2dd61ce3.js rename to assets/js/a3dddb77.0be524dd.js index e6d678d93..a05be5ecf 100644 --- a/assets/js/a3dddb77.2dd61ce3.js +++ b/assets/js/a3dddb77.0be524dd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[475],{5479:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[475],{5479:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a4349a81.a1bfa638.js b/assets/js/a4349a81.dc01ce87.js similarity index 77% rename from assets/js/a4349a81.a1bfa638.js rename to assets/js/a4349a81.dc01ce87.js index 3c15cf01a..6de94ee6b 100644 --- a/assets/js/a4349a81.a1bfa638.js +++ b/assets/js/a4349a81.dc01ce87.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9623],{32318:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9623],{32318:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a539c018.8e8d9e35.js b/assets/js/a539c018.11f0a959.js similarity index 77% rename from assets/js/a539c018.8e8d9e35.js rename to assets/js/a539c018.11f0a959.js index 16171f4e7..ab1ff4fb1 100644 --- a/assets/js/a539c018.8e8d9e35.js +++ b/assets/js/a539c018.11f0a959.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5758],{99844:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5758],{99844:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a59d28a9.8f8cdb54.js b/assets/js/a59d28a9.8f8cdb54.js deleted file mode 100644 index 15be0e209..000000000 --- a/assets/js/a59d28a9.8f8cdb54.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2012],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>c});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function p(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=a.createContext({}),m=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):p(p({},t),e)),n},u=function(e){var t=m(e.components);return a.createElement(o.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,o=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=m(n),c=r,y=d["".concat(o,".").concat(c)]||d[c]||s[c]||l;return n?a.createElement(y,p(p({ref:t},u),{},{components:n})):a.createElement(y,p({ref:t},u))}));function c(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,p=new Array(l);p[0]=d;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i.mdxType="string"==typeof e?e:r,p[1]=i;for(var m=2;m<l;m++)p[m]=n[m];return a.createElement.apply(null,p)}return a.createElement.apply(null,n)}d.displayName="MDXCreateElement"},44122:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>p,default:()=>s,frontMatter:()=>l,metadata:()=>i,toc:()=>m});var a=n(87462),r=(n(67294),n(3905));const l={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",slug:"route-image-python",tags:["Image","Python"]},p=void 0,i={permalink:"/route-image-python",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",source:"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",description:"\uac1c\uc694",date:"2023-07-31T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 31\uc77c",tags:[{label:"Image",permalink:"/tags/image"},{label:"Python",permalink:"/tags/python"}],readingTime:6.185,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",slug:"route-image-python",tags:["Image","Python"]},prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",permalink:"/route-image-implementation"},nextItem:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",permalink:"/mock-static-method"}},o={authorsImageUrls:[]},m=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\uc0ac\uc6a9 \uae30\uc220",id:"\uc0ac\uc6a9-\uae30\uc220",level:3},{value:"\uc694\uad6c\uc0ac\ud56d",id:"\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd",id:"\uc774\ubbf8\uc9c0-\ucd9c\ub825-\ubc29\uc2dd",level:3},{value:"\ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604",id:"\ub85c\uceec\uc5d0\uc11c-\uae30\ub2a5-\uad6c\ud604",level:3},{value:"AWS Lambda",id:"aws-lambda",level:3},{value:"\ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131",id:"\ub78c\ub2e4-s3-\uc811\uadfc\uc744-\uc704\ud55c-iam-\uc0dd\uc131",level:3},{value:"\ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc",id:"\ub78c\ub2e4-\ubc30\ud3ec\uc6a9-\ucf54\ub4dc",level:3},{value:"Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131",id:"layer-\ucd94\uac00\ub97c-\uc704\ud55c-zip-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"<code>No module named 'numpy.core._multiarray_umath'</code> \uc5d0\ub7ec",id:"no-module-named-numpycore_multiarray_umath-\uc5d0\ub7ec",level:3},{value:"\uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01",id:"\uc801\uc815\uae30\uc220\uc5d0-\ub300\ud55c-\uc0dd\uac01",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],u={toc:m};function s(e){let{components:t,...l}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,l,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,r.kt)("p",null,"\uc774\uc804\uc5d0 \uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uc870\uc0ac\ud558\uba74\uc11c \ud30c\uc774\uc36c\uc744 \uc0ac\uc6a9\ud55c \ub0b4\uc6a9\uc744 \uc815\ub9ac\ud55c \ub0b4\uc6a9\uc774\ub2e4. "),(0,r.kt)("h3",{id:"\uc0ac\uc6a9-\uae30\uc220"},"\uc0ac\uc6a9 \uae30\uc220"),(0,r.kt)("p",null,"\uc5b8\uc5b4: Python 3.10",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131: matplotlib",(0,r.kt)("br",{parentName:"p"}),"\n","\uc11c\ube44\uc2a4: AWS Lambda, AWS API Gateway",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc800\uc7a5 \ubc0f URL: AWS S3, AWS CloudFront "),(0,r.kt)("p",null,"\ud50c\ub85c\uc6b0\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n Server -- \uc0dd\uc131 \uc694\uccad --\x3e AG[API Gateway] --\x3e Lambda --\x3e S3\n Client --\x3e CloudFront --\x3e S3"}),(0,r.kt)("h3",{id:"\uc694\uad6c\uc0ac\ud56d"},"\uc694\uad6c\uc0ac\ud56d"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./route.png",src:n(13533).Z,width:"1014",height:"902"})),(0,r.kt)("p",null,"\uc6b0\uce21 \uc0c1\ub2e8\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub824\uace0 \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \ubc30\uc5f4\uc744 \uc785\ub825\ubc1b\ub294\ub2e4. "),(0,r.kt)("li",{parentName:"ul"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131"),(0,r.kt)("li",{parentName:"ul"},"\uc120\uacfc \uc810 \ud45c\ud604"),(0,r.kt)("li",{parentName:"ul"},"\ud22c\uba85\ud55c \ubc30\uacbd\uc0c9"),(0,r.kt)("li",{parentName:"ul"},"\uc704\uacbd\ub3c4 \ucc28\uc774\uac00 \ud06c\ub4e0 \uc791\ub4e0 \uc81c\uacf5\ud558\ub294 \uc774\ubbf8\uc9c0 \ub0b4\uc5d0 \uacbd\ub85c\uac00 \ub2e4 \ud3ec\ud568\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4. ")),(0,r.kt)("h3",{id:"\uc774\ubbf8\uc9c0-\ucd9c\ub825-\ubc29\uc2dd"},"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"\uc704\uacbd\ub3c4\ub97c \ucc98\ub9ac\ud55c \uac12\uc73c\ub85c \uc9c1\uc811 \uacbd\ub85c\ub97c \uadf8\ub9b0 \ub2e4\uc74c \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5"),(0,r.kt)("li",{parentName:"ol"},"\ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac \uc0ac\uc6a9\ud558\uc5ec \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5")),(0,r.kt)("p",null,"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd\uc758 \uacbd\uc6b0 1\ubc88\uacfc 2\ubc88\uc744 \uace0\ubbfc\ud588\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud30c\uc774\uc36c\uc73c\ub85c\ub294 \ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc778 matplotlib\uc744 \uc0ac\uc6a9\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\ub85c\uceec\uc5d0\uc11c-\uae30\ub2a5-\uad6c\ud604"},"\ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"import time\n\nimport matplotlib.pyplot as plt\n\n\ndef draw(point):\n start = time.time()\n x, y = zip(*point)\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\n draw_lines(pixel_x, pixel_y)\n end = time.time()\n print(end - start)\n \ndef convert_to_pixel_values(x, y):\n max_diff = max(max(x) - min(x), max(y) - min(y))\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\n\n\ndef scale_to_pixel_values(points, max_diff):\n min_value = min(points)\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\n return scaled_coordinates\n\n\ndef draw_lines(x, y):\n figure = plt.gcf()\n figure.set_size_inches(5, 5)\n plt.plot(x, y, c = 'w',linewidth=5)\n plt.scatter(x[3],y[3], c = 'w', s = 125)\n plt.axis('off')\n plt.savefig('name.png', transparent=True, format='png')\n\npoint = [\n [126.96352960597338, 37.590841000217125],\n [126.96987292787792, 37.58435564234159],\n [126.98128481452298, 37.58594375113966],\n [126.99360339342958, 37.58248524741927],\n [126.99867565340067, 37.56778118088622],\n [127.001935378366117, 37.55985240444085],\n [126.9831048919687, 37.548030119488665],\n [126.97189273528845, 37.5119879225856],\n [127.02689859997221, 37.48488593333883]\n]\n\ndraw(point)\n")),(0,r.kt)("p",null,"\uc0dd\uc131 \uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4. (\uc608\uc2dc\ub97c \uc704\ud574 \uac80\uc740\uc0c9\uc73c\ub85c \ucd9c\ub825)"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./routeImage.png",src:n(46365).Z,width:"500",height:"500"})),(0,r.kt)("h3",{id:"aws-lambda"},"AWS Lambda"),(0,r.kt)("p",null,"\uc378\ub124\uc77c \uc0dd\uc131 \uc11c\ubc84\ub97c \ub530\ub85c \ub450\uae30\ub294 \uae30\ub2a5 \ub300\ube44 \ube44\uc6a9\uc774 \ub108\ubb34 \ud074 \uac83\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc11c\ubc84\ub9ac\uc2a4\ub85c \ud30c\uc77c\uc744 \ucc98\ub9ac\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c s3 \uc811\uadfc\uc740 boto3\ub97c \uc0ac\uc6a9\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\ub78c\ub2e4-s3-\uc811\uadfc\uc744-\uc704\ud55c-iam-\uc0dd\uc131"},"\ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131"),(0,r.kt)("p",null,"AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy \ub450\uac00\uc9c0\ub97c \ucd94\uac00\ud574\uc11c Lambda \uc804\uc6a9 \uc5ed\ud560\uc744 \ub9cc\ub4e4\uc5b4 \uc0ac\uc6a9\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\ub78c\ub2e4-\ubc30\ud3ec\uc6a9-\ucf54\ub4dc"},"\ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc"),(0,r.kt)("p",null,"\uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \ud655\uc778\ud560 \ub550 \uc704\uce58 \uc810\uc744 \ucc0d\ub294 \uae30\ub2a5\uc744 \ub78c\ub2e4\uc5d0 \ubc30\ud3ec\ud558\uc9c0 \uc54a\uc558\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"\nimport io\nimport uuid\n\nimport boto3\nimport matplotlib.pyplot as plt\n\nPIXEL = 255\nBUCKET_NAME = 'image-plot'\nS3 = 's3'\n\ndef lambda_handler(event, context):\n x = event['x']\n y = event['y']\n image_name = str(uuid.uuid4())\n\n img_data = draw(x, y)\n s3 = boto3.client(S3)\n s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)\n url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'\n\n return {\n 'statusCode': 200,\n 'body': url\n }\n\ndef draw(x, y):\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\n img_data = draw_lines(pixel_x, pixel_y)\n plt.close()\n return img_data\n\ndef convert_to_pixel_values(x, y):\n max_diff = max(max(x) - min(x), max(y) - min(y))\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\n\ndef scale_to_pixel_values(points, max_diff):\n min_value = min(points)\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\n pixel_values = [int(p * PIXEL) for p in scaled_coordinates]\n return pixel_values\n\ndef draw_lines(x, y):\n plt.plot(x, y, 'k-', linewidth=10)\n plt.axis('off')\n img_data = io.BytesIO()\n plt.savefig(img_data, transparent=True, format='png')\n img_data.seek(0)\n return img_data\n\n")),(0,r.kt)("h3",{id:"layer-\ucd94\uac00\ub97c-\uc704\ud55c-zip-\ud30c\uc77c-\uc0dd\uc131"},"Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131"),(0,r.kt)("p",null,"matplotlib\uc758 \uacbd\uc6b0 \uc678\ubd80 \ub77c\uc774\ube0c\ub7ec\ub9ac\uae30 \ub54c\ubb38\uc5d0 \ub530\ub85c Layer\ub97c \ucd94\uac00\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc5b4\uc11c \uc5c5\ub85c\ub4dc\ud574\uc57c\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub54c python\uc758 Lambda \ub7f0\ud0c0\uc784\uc5d0 \ub300\ud55c \uacc4\uce35 \uacbd\ub85c\ub294 python\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc555\ucd95\ud55c zip \ud30c\uc77c\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\ub97c \ub744\uc5b4\uc57c \ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"pillow.zip\n\u2502 python/PIL\n\u2514 python/Pillow-5.3.0.dist-info\n")),(0,r.kt)("p",null,"Ubuntu \uae30\uc900 \ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc0dd\uc131\uc744 \uc9c4\ud589\ud588\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"sudo apt update\nsudo apt install zip\nsudo apt install python3-pip\n\nmkdir python\npip3 install matplotlib -t python # pip3 install \uc124\uce58\ud560_\ud328\ud0a4\uc9c0 -t \uc124\uce58_\uacbd\ub85c\nzip -r my_layer.zip python # zip -r \uc555\ucd95_\ud30c\uc77c\uba85 \uc555\ucd95_\ud30c\uc77c\uc774_\uc874\uc7ac\ud558\ub294_\uacbd\ub85c\n")),(0,r.kt)("h3",{id:"no-module-named-numpycore_multiarray_umath-\uc5d0\ub7ec"},(0,r.kt)("inlineCode",{parentName:"h3"},"No module named 'numpy.core._multiarray_umath'")," \uc5d0\ub7ec"),(0,r.kt)("p",null,"Layer \ucd94\uac00 \ud6c4 \ub78c\ub2e4 \uc2e4\ud589 \uc2dc \ubc1c\uc0dd\ud55c \uc5d0\ub7ec\uc600\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucc98\uc74c\uc5d0 mac\uc5d0\uc11c zip \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \uc5c5\ub85c\ub4dc\ud588\ub294\ub370 \ud574\ub2f9 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 lambda\uac00 \ub3cc\uc544\uac00\ub294 \ub3d9\uc77c\ud55c \ud658\uacbd\uc5d0\uc11c layer\ub97c \uc704\ud55c zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc9c0 \uc54a\uc544\uc11c \ubc1c\uc0dd\ud558\ub294 \ubb38\uc81c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud558\uac8c ec2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c \ub530\ub85c Layer\ub97c \uc0dd\uc131\ud558\uba74 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4. "),(0,r.kt)("h3",{id:"\uc801\uc815\uae30\uc220\uc5d0-\ub300\ud55c-\uc0dd\uac01"},"\uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01"),(0,r.kt)("p",null,"\ud504\ub85c\uc81d\ud2b8\uc5d0 Lambda\uc640 Python\uc744 \uc0ac\uc6a9\ud558\ub824\uace0 \ud588\uc9c0\ub9cc \uc544\uc27d\uac8c\ub3c4 \ubc18\ub824\ub2f9\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","AWS Lambda\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc778\uc2a4\ud134\uc2a4\uc5d0 \ud574\ub2f9 \ucf54\ub4dc\ub97c \ubc30\ud3ec\ud558\ub294 \uac83\ubcf4\ub2e4 \ub354 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc77c \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ud604\uc7ac \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uac00\uc6a9 \uac00\ub2a5\ud55c \uc790\uc6d0, \uae30\uc220\uc758 \ub09c\uc774\ub3c4, \uc0ac\uc6a9\ud558\ub294 \ud300\uc6d0\uc744 \uace0\ub824\ud55c\ub2e4\uba74 Lambda\ub294 \uc801\uc815\uae30\uc220\uc774 \uc544\ub2d0 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ud574\ub2f9 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\ub97c \uc5b4\ub5bb\uac8c \uc801\uc6a9\ud560\uc9c0 \uc870\uae08 \ub354 \uace0\ub824\ub97c \ud574\uc57c \ub420 \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\ucd5c\uc885\uc801\uc73c\ub85c Java AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.")),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/lambda/"},"AWS Lambda"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-layers.html"},"Lambda Layer"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-package.html"},"Python Lambda \ud568\uc218\uc5d0 \ub300\ud55c .zip \ud30c\uc77c \uc544\uce74\uc774\ube0c \uc791\uc5c5"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://gist.github.com/ksmin23/0f3f243408a8497f766b43cf589fea7b"},"No module named 'numpy.core._multiarray_umath'"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/6217/"},"\uc0ac\ub840\ubcc4\ub85c \uc54c\uc544\ubcf8 \uc548\uc804\ud55c S3 \uc0ac\uc6a9 \uac00\uc774\ub4dc")))}s.isMDXComponent=!0},13533:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png"},46365:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/routeImage-0eac25ba9b356cd034ade6e062c1ce19.png"}}]); \ No newline at end of file diff --git a/assets/js/a59d28a9.aacad7b2.js b/assets/js/a59d28a9.aacad7b2.js new file mode 100644 index 000000000..1649ab254 --- /dev/null +++ b/assets/js/a59d28a9.aacad7b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2012],{63600:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=t(85893),i=t(3905);const r={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",slug:"route-image-python",tags:["Image","Python"]},l=void 0,s={permalink:"/route-image-python",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",source:"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",description:"\uac1c\uc694",date:"2023-07-31T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 31\uc77c",tags:[{label:"Image",permalink:"/tags/image"},{label:"Python",permalink:"/tags/python"}],readingTime:6.185,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",slug:"route-image-python",tags:["Image","Python"]},unlisted:!1,prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",permalink:"/route-image-implementation"},nextItem:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",permalink:"/mock-static-method"}},o={authorsImageUrls:[]},d=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\uc0ac\uc6a9 \uae30\uc220",id:"\uc0ac\uc6a9-\uae30\uc220",level:3},{value:"\uc694\uad6c\uc0ac\ud56d",id:"\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd",id:"\uc774\ubbf8\uc9c0-\ucd9c\ub825-\ubc29\uc2dd",level:3},{value:"\ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604",id:"\ub85c\uceec\uc5d0\uc11c-\uae30\ub2a5-\uad6c\ud604",level:3},{value:"AWS Lambda",id:"aws-lambda",level:3},{value:"\ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131",id:"\ub78c\ub2e4-s3-\uc811\uadfc\uc744-\uc704\ud55c-iam-\uc0dd\uc131",level:3},{value:"\ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc",id:"\ub78c\ub2e4-\ubc30\ud3ec\uc6a9-\ucf54\ub4dc",level:3},{value:"Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131",id:"layer-\ucd94\uac00\ub97c-\uc704\ud55c-zip-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"<code>No module named 'numpy.core._multiarray_umath'</code> \uc5d0\ub7ec",id:"no-module-named-numpycore_multiarray_umath-\uc5d0\ub7ec",level:3},{value:"\uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01",id:"\uc801\uc815\uae30\uc220\uc5d0-\ub300\ud55c-\uc0dd\uac01",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function p(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.ah)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h3,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,a.jsx)(n.p,{children:"\uc774\uc804\uc5d0 \uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uc870\uc0ac\ud558\uba74\uc11c \ud30c\uc774\uc36c\uc744 \uc0ac\uc6a9\ud55c \ub0b4\uc6a9\uc744 \uc815\ub9ac\ud55c \ub0b4\uc6a9\uc774\ub2e4."}),"\n",(0,a.jsx)(n.h3,{id:"\uc0ac\uc6a9-\uae30\uc220",children:"\uc0ac\uc6a9 \uae30\uc220"}),"\n",(0,a.jsxs)(n.p,{children:["\uc5b8\uc5b4: Python 3.10",(0,a.jsx)(n.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131: matplotlib",(0,a.jsx)(n.br,{}),"\n","\uc11c\ube44\uc2a4: AWS Lambda, AWS API Gateway",(0,a.jsx)(n.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc800\uc7a5 \ubc0f URL: AWS S3, AWS CloudFront"]}),"\n",(0,a.jsx)(n.p,{children:"\ud50c\ub85c\uc6b0\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n Server -- \uc0dd\uc131 \uc694\uccad --\x3e AG[API Gateway] --\x3e Lambda --\x3e S3\n Client --\x3e CloudFront --\x3e S3"}),"\n",(0,a.jsx)(n.h3,{id:"\uc694\uad6c\uc0ac\ud56d",children:"\uc694\uad6c\uc0ac\ud56d"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"./route.png",src:t(13533).Z+"",width:"1014",height:"902"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc6b0\uce21 \uc0c1\ub2e8\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub824\uace0 \ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \ubc30\uc5f4\uc744 \uc785\ub825\ubc1b\ub294\ub2e4."}),"\n",(0,a.jsx)(n.li,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131"}),"\n",(0,a.jsx)(n.li,{children:"\uc120\uacfc \uc810 \ud45c\ud604"}),"\n",(0,a.jsx)(n.li,{children:"\ud22c\uba85\ud55c \ubc30\uacbd\uc0c9"}),"\n",(0,a.jsx)(n.li,{children:"\uc704\uacbd\ub3c4 \ucc28\uc774\uac00 \ud06c\ub4e0 \uc791\ub4e0 \uc81c\uacf5\ud558\ub294 \uc774\ubbf8\uc9c0 \ub0b4\uc5d0 \uacbd\ub85c\uac00 \ub2e4 \ud3ec\ud568\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4."}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"\uc774\ubbf8\uc9c0-\ucd9c\ub825-\ubc29\uc2dd",children:"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"\uc704\uacbd\ub3c4\ub97c \ucc98\ub9ac\ud55c \uac12\uc73c\ub85c \uc9c1\uc811 \uacbd\ub85c\ub97c \uadf8\ub9b0 \ub2e4\uc74c \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5"}),"\n",(0,a.jsx)(n.li,{children:"\ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac \uc0ac\uc6a9\ud558\uc5ec \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5"}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd\uc758 \uacbd\uc6b0 1\ubc88\uacfc 2\ubc88\uc744 \uace0\ubbfc\ud588\uc5c8\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud30c\uc774\uc36c\uc73c\ub85c\ub294 \ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc778 matplotlib\uc744 \uc0ac\uc6a9\ud588\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\ub85c\uceec\uc5d0\uc11c-\uae30\ub2a5-\uad6c\ud604",children:"\ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:"import time\n\nimport matplotlib.pyplot as plt\n\n\ndef draw(point):\n start = time.time()\n x, y = zip(*point)\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\n draw_lines(pixel_x, pixel_y)\n end = time.time()\n print(end - start)\n \ndef convert_to_pixel_values(x, y):\n max_diff = max(max(x) - min(x), max(y) - min(y))\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\n\n\ndef scale_to_pixel_values(points, max_diff):\n min_value = min(points)\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\n return scaled_coordinates\n\n\ndef draw_lines(x, y):\n figure = plt.gcf()\n figure.set_size_inches(5, 5)\n plt.plot(x, y, c = 'w',linewidth=5)\n plt.scatter(x[3],y[3], c = 'w', s = 125)\n plt.axis('off')\n plt.savefig('name.png', transparent=True, format='png')\n\npoint = [\n [126.96352960597338, 37.590841000217125],\n [126.96987292787792, 37.58435564234159],\n [126.98128481452298, 37.58594375113966],\n [126.99360339342958, 37.58248524741927],\n [126.99867565340067, 37.56778118088622],\n [127.001935378366117, 37.55985240444085],\n [126.9831048919687, 37.548030119488665],\n [126.97189273528845, 37.5119879225856],\n [127.02689859997221, 37.48488593333883]\n]\n\ndraw(point)\n"})}),"\n",(0,a.jsx)(n.p,{children:"\uc0dd\uc131 \uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4. (\uc608\uc2dc\ub97c \uc704\ud574 \uac80\uc740\uc0c9\uc73c\ub85c \ucd9c\ub825)"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"./routeImage.png",src:t(46365).Z+"",width:"500",height:"500"})}),"\n",(0,a.jsx)(n.h3,{id:"aws-lambda",children:"AWS Lambda"}),"\n",(0,a.jsxs)(n.p,{children:["\uc378\ub124\uc77c \uc0dd\uc131 \uc11c\ubc84\ub97c \ub530\ub85c \ub450\uae30\ub294 \uae30\ub2a5 \ub300\ube44 \ube44\uc6a9\uc774 \ub108\ubb34 \ud074 \uac83\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc11c\ubc84\ub9ac\uc2a4\ub85c \ud30c\uc77c\uc744 \ucc98\ub9ac\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c s3 \uc811\uadfc\uc740 boto3\ub97c \uc0ac\uc6a9\ud588\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\ub78c\ub2e4-s3-\uc811\uadfc\uc744-\uc704\ud55c-iam-\uc0dd\uc131",children:"\ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131"}),"\n",(0,a.jsx)(n.p,{children:"AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy \ub450\uac00\uc9c0\ub97c \ucd94\uac00\ud574\uc11c Lambda \uc804\uc6a9 \uc5ed\ud560\uc744 \ub9cc\ub4e4\uc5b4 \uc0ac\uc6a9\ud588\ub2e4."}),"\n",(0,a.jsx)(n.h3,{id:"\ub78c\ub2e4-\ubc30\ud3ec\uc6a9-\ucf54\ub4dc",children:"\ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc"}),"\n",(0,a.jsx)(n.p,{children:"\uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \ud655\uc778\ud560 \ub550 \uc704\uce58 \uc810\uc744 \ucc0d\ub294 \uae30\ub2a5\uc744 \ub78c\ub2e4\uc5d0 \ubc30\ud3ec\ud558\uc9c0 \uc54a\uc558\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:"\nimport io\nimport uuid\n\nimport boto3\nimport matplotlib.pyplot as plt\n\nPIXEL = 255\nBUCKET_NAME = 'image-plot'\nS3 = 's3'\n\ndef lambda_handler(event, context):\n x = event['x']\n y = event['y']\n image_name = str(uuid.uuid4())\n\n img_data = draw(x, y)\n s3 = boto3.client(S3)\n s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)\n url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'\n\n return {\n 'statusCode': 200,\n 'body': url\n }\n\ndef draw(x, y):\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\n img_data = draw_lines(pixel_x, pixel_y)\n plt.close()\n return img_data\n\ndef convert_to_pixel_values(x, y):\n max_diff = max(max(x) - min(x), max(y) - min(y))\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\n\ndef scale_to_pixel_values(points, max_diff):\n min_value = min(points)\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\n pixel_values = [int(p * PIXEL) for p in scaled_coordinates]\n return pixel_values\n\ndef draw_lines(x, y):\n plt.plot(x, y, 'k-', linewidth=10)\n plt.axis('off')\n img_data = io.BytesIO()\n plt.savefig(img_data, transparent=True, format='png')\n img_data.seek(0)\n return img_data\n\n"})}),"\n",(0,a.jsx)(n.h3,{id:"layer-\ucd94\uac00\ub97c-\uc704\ud55c-zip-\ud30c\uc77c-\uc0dd\uc131",children:"Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131"}),"\n",(0,a.jsxs)(n.p,{children:["matplotlib\uc758 \uacbd\uc6b0 \uc678\ubd80 \ub77c\uc774\ube0c\ub7ec\ub9ac\uae30 \ub54c\ubb38\uc5d0 \ub530\ub85c Layer\ub97c \ucd94\uac00\ud574\uc57c \ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc5b4\uc11c \uc5c5\ub85c\ub4dc\ud574\uc57c\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc774\ub54c python\uc758 Lambda \ub7f0\ud0c0\uc784\uc5d0 \ub300\ud55c \uacc4\uce35 \uacbd\ub85c\ub294 python\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc555\ucd95\ud55c zip \ud30c\uc77c\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\ub97c \ub744\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"pillow.zip\n\u2502 python/PIL\n\u2514 python/Pillow-5.3.0.dist-info\n"})}),"\n",(0,a.jsx)(n.p,{children:"Ubuntu \uae30\uc900 \ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc0dd\uc131\uc744 \uc9c4\ud589\ud588\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"sudo apt update\nsudo apt install zip\nsudo apt install python3-pip\n\nmkdir python\npip3 install matplotlib -t python # pip3 install \uc124\uce58\ud560_\ud328\ud0a4\uc9c0 -t \uc124\uce58_\uacbd\ub85c\nzip -r my_layer.zip python # zip -r \uc555\ucd95_\ud30c\uc77c\uba85 \uc555\ucd95_\ud30c\uc77c\uc774_\uc874\uc7ac\ud558\ub294_\uacbd\ub85c\n"})}),"\n",(0,a.jsxs)(n.h3,{id:"no-module-named-numpycore_multiarray_umath-\uc5d0\ub7ec",children:[(0,a.jsx)(n.code,{children:"No module named 'numpy.core._multiarray_umath'"})," \uc5d0\ub7ec"]}),"\n",(0,a.jsxs)(n.p,{children:["Layer \ucd94\uac00 \ud6c4 \ub78c\ub2e4 \uc2e4\ud589 \uc2dc \ubc1c\uc0dd\ud55c \uc5d0\ub7ec\uc600\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ucc98\uc74c\uc5d0 mac\uc5d0\uc11c zip \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \uc5c5\ub85c\ub4dc\ud588\ub294\ub370 \ud574\ub2f9 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc774\ub294 lambda\uac00 \ub3cc\uc544\uac00\ub294 \ub3d9\uc77c\ud55c \ud658\uacbd\uc5d0\uc11c layer\ub97c \uc704\ud55c zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc9c0 \uc54a\uc544\uc11c \ubc1c\uc0dd\ud558\ub294 \ubb38\uc81c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uac04\ub2e8\ud558\uac8c ec2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c \ub530\ub85c Layer\ub97c \uc0dd\uc131\ud558\uba74 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\uc801\uc815\uae30\uc220\uc5d0-\ub300\ud55c-\uc0dd\uac01",children:"\uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01"}),"\n",(0,a.jsxs)(n.p,{children:["\ud504\ub85c\uc81d\ud2b8\uc5d0 Lambda\uc640 Python\uc744 \uc0ac\uc6a9\ud558\ub824\uace0 \ud588\uc9c0\ub9cc \uc544\uc27d\uac8c\ub3c4 \ubc18\ub824\ub2f9\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","AWS Lambda\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc778\uc2a4\ud134\uc2a4\uc5d0 \ud574\ub2f9 \ucf54\ub4dc\ub97c \ubc30\ud3ec\ud558\ub294 \uac83\ubcf4\ub2e4 \ub354 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc77c \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \ud604\uc7ac \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uac00\uc6a9 \uac00\ub2a5\ud55c \uc790\uc6d0, \uae30\uc220\uc758 \ub09c\uc774\ub3c4, \uc0ac\uc6a9\ud558\ub294 \ud300\uc6d0\uc744 \uace0\ub824\ud55c\ub2e4\uba74 Lambda\ub294 \uc801\uc815\uae30\uc220\uc774 \uc544\ub2d0 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ud574\ub2f9 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\ub97c \uc5b4\ub5bb\uac8c \uc801\uc6a9\ud560\uc9c0 \uc870\uae08 \ub354 \uace0\ub824\ub97c \ud574\uc57c \ub420 \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\ucd5c\uc885\uc801\uc73c\ub85c Java AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4."})}),"\n",(0,a.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://aws.amazon.com/ko/lambda/",children:"AWS Lambda"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-layers.html",children:"Lambda Layer"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-package.html",children:"Python Lambda \ud568\uc218\uc5d0 \ub300\ud55c .zip \ud30c\uc77c \uc544\uce74\uc774\ube0c \uc791\uc5c5"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://gist.github.com/ksmin23/0f3f243408a8497f766b43cf589fea7b",children:"No module named 'numpy.core._multiarray_umath'"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://techblog.woowahan.com/6217/",children:"\uc0ac\ub840\ubcc4\ub85c \uc54c\uc544\ubcf8 \uc548\uc804\ud55c S3 \uc0ac\uc6a9 \uac00\uc774\ub4dc"})]})]})}function c(e={}){const{wrapper:n}={...(0,i.ah)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>d});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function l(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?r(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):r(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,a,i=function(e,n){if(null==e)return{};var t,a,i={},r=Object.keys(e);for(a=0;a<r.length;a++)t=r[a],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)t=r[a],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var o=a.createContext({}),d=function(e){var n=a.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},p={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},c=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,o=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=d(t),x=i,u=m["".concat(o,".").concat(x)]||m[x]||p[x]||r;return t?a.createElement(u,l(l({ref:n},c),{},{components:t})):a.createElement(u,l({ref:n},c))}));c.displayName="MDXCreateElement"},13533:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png"},46365:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/routeImage-0eac25ba9b356cd034ade6e062c1ce19.png"}}]); \ No newline at end of file diff --git a/assets/js/a6aa9e1f.4dfe399a.js b/assets/js/a6aa9e1f.4dfe399a.js new file mode 100644 index 000000000..a042657f2 --- /dev/null +++ b/assets/js/a6aa9e1f.4dfe399a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3089],{80046:(t,e,a)=>{a.r(e),a.d(e,{default:()=>m});a(67294);var s=a(86010),n=a(52263),i=a(10833),r=a(35281),o=a(61460),l=a(99703),c=a(90197),d=a(79985),g=a(85893);function p(t){const{metadata:e}=t,{siteConfig:{title:a}}=(0,n.Z)(),{blogDescription:s,blogTitle:r,permalink:o}=e,l="/"===o?a:r;return(0,g.jsxs)(g.Fragment,{children:[(0,g.jsx)(i.d,{title:l,description:s}),(0,g.jsx)(c.Z,{tag:"blog_posts_list"})]})}function u(t){const{metadata:e,items:a,sidebar:s}=t;return(0,g.jsxs)(o.Z,{sidebar:s,children:[(0,g.jsx)(d.Z,{items:a}),(0,g.jsx)(l.Z,{metadata:e})]})}function m(t){return(0,g.jsxs)(i.FG,{className:(0,s.Z)(r.k.wrapper.blogPages,r.k.page.blogListPage),children:[(0,g.jsx)(p,{...t}),(0,g.jsx)(u,{...t})]})}},99703:(t,e,a)=>{a.d(e,{Z:()=>r});a(67294);var s=a(95999),n=a(32244),i=a(85893);function r(t){const{metadata:e}=t,{previousPage:a,nextPage:r}=e;return(0,i.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,i.jsx)(n.Z,{permalink:a,title:(0,i.jsx)(s.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer Entries"})}),r&&(0,i.jsx)(n.Z,{permalink:r,title:(0,i.jsx)(s.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older Entries"}),isNext:!0})]})}},79985:(t,e,a)=>{a.d(e,{Z:()=>r});a(67294);var s=a(9460),n=a(857),i=a(85893);function r(t){let{items:e,component:a=n.Z}=t;return(0,i.jsx)(i.Fragment,{children:e.map((t=>{let{content:e}=t;return(0,i.jsx)(s.n,{content:e,children:(0,i.jsx)(a,{children:(0,i.jsx)(e,{})})},e.metadata.permalink)}))})}},857:(t,e,a)=>{a.d(e,{Z:()=>l});var s=a(30390),n=a(67294),i=a(92949),r=a(9460),o=a(85893);const l=function(t){const{colorMode:e}=(0,i.I)(),{isBlogPostPage:a}=(0,r.C)(),l="dark"===e?"dark":"light",c=(0,n.useRef)(null);return(0,n.useEffect)((()=>{if(!a)return;const t=c.current.querySelector("iframe.giscus-frame");t?(()=>{const e={setConfig:{theme:l}};t.contentWindow.postMessage({giscus:e},"https://giscus.app")})():(()=>{const t=document.createElement("script");t.src="https://giscus.app/client.js",t.setAttribute("data-repo","greeng00se/greeng00se.github.io"),t.setAttribute("data-repo-id","R_kgDOIRAC3w"),t.setAttribute("data-category","Announcements"),t.setAttribute("data-category-id","DIC_kwDOIRAC384CTcGg"),t.setAttribute("data-mapping","pathname"),t.setAttribute("data-strict","0"),t.setAttribute("data-reactions-enabled","1"),t.setAttribute("data-emit-metadata","0"),t.setAttribute("data-input-position","bottom"),t.setAttribute("data-theme",l),t.setAttribute("data-lang","ko"),t.crossOrigin="anonymous",t.async=!0,c.current.appendChild(t)})()}),[l]),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.Z,{...t}),a&&(0,o.jsx)("div",{ref:c})]})}}}]); \ No newline at end of file diff --git a/assets/js/a6aa9e1f.7b54bae2.js b/assets/js/a6aa9e1f.7b54bae2.js deleted file mode 100644 index c9e01f764..000000000 --- a/assets/js/a6aa9e1f.7b54bae2.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3089],{80046:(e,t,a)=>{"use strict";a.r(t),a.d(t,{default:()=>p});var n=a(67294),r=a(86010),i=a(52263),s=a(10833),o=a(35281),l=a(39058),c=a(99703),u=a(90197),m=a(79985);function g(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,i.Z)(),{blogDescription:r,blogTitle:o,permalink:l}=t,c="/"===l?a:o;return n.createElement(n.Fragment,null,n.createElement(s.d,{title:c,description:r}),n.createElement(u.Z,{tag:"blog_posts_list"}))}function d(e){const{metadata:t,items:a,sidebar:r}=e;return n.createElement(l.Z,{sidebar:r},n.createElement(m.Z,{items:a}),n.createElement(c.Z,{metadata:t}))}function p(e){return n.createElement(s.FG,{className:(0,r.Z)(o.k.wrapper.blogPages,o.k.page.blogListPage)},n.createElement(g,e),n.createElement(d,e))}},99703:(e,t,a)=>{"use strict";a.d(t,{Z:()=>s});var n=a(67294),r=a(95999),i=a(32244);function s(e){const{metadata:t}=e,{previousPage:a,nextPage:s}=t;return n.createElement("nav",{className:"pagination-nav","aria-label":(0,r.I)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"})},a&&n.createElement(i.Z,{permalink:a,title:n.createElement(r.Z,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)"},"Newer Entries")}),s&&n.createElement(i.Z,{permalink:s,title:n.createElement(r.Z,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)"},"Older Entries"),isNext:!0}))}},79985:(e,t,a)=>{"use strict";a.d(t,{Z:()=>s});var n=a(67294),r=a(9460),i=a(857);function s(e){let{items:t,component:a=i.Z}=e;return n.createElement(n.Fragment,null,t.map((e=>{let{content:t}=e;return n.createElement(r.n,{key:t.metadata.permalink,content:t},n.createElement(a,null,n.createElement(t,null)))})))}},857:(e,t,a)=>{"use strict";a.d(t,{Z:()=>o});var n=a(30390),r=a(67294),i=a(92949),s=a(9460);const o=function(e){const{colorMode:t}=(0,i.I)(),{isBlogPostPage:a}=(0,s.C)(),o="dark"===t?"dark":"light",l=(0,r.useRef)(null);return(0,r.useEffect)((()=>{if(!a)return;const e=l.current.querySelector("iframe.giscus-frame");e?(()=>{const t={setConfig:{theme:o}};e.contentWindow.postMessage({giscus:t},"https://giscus.app")})():(()=>{const e=document.createElement("script");e.src="https://giscus.app/client.js",e.setAttribute("data-repo","greeng00se/greeng00se.github.io"),e.setAttribute("data-repo-id","R_kgDOIRAC3w"),e.setAttribute("data-category","Announcements"),e.setAttribute("data-category-id","DIC_kwDOIRAC384CTcGg"),e.setAttribute("data-mapping","pathname"),e.setAttribute("data-strict","0"),e.setAttribute("data-reactions-enabled","1"),e.setAttribute("data-emit-metadata","0"),e.setAttribute("data-input-position","bottom"),e.setAttribute("data-theme",o),e.setAttribute("data-lang","ko"),e.crossOrigin="anonymous",e.async=!0,l.current.appendChild(e)})()}),[o]),r.createElement(r.Fragment,null,r.createElement(n.Z,e),a&&r.createElement("div",{ref:l}))}},11748:(e,t,a)=>{var n={"./locale":89234,"./locale.js":89234};function r(e){var t=i(e);return a(t)}function i(e){if(!a.o(n,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return n[e]}r.keys=function(){return Object.keys(n)},r.resolve=i,e.exports=r,r.id=11748}}]); \ No newline at end of file diff --git a/assets/js/a710d533.89036d73.js b/assets/js/a710d533.89036d73.js new file mode 100644 index 000000000..5451f5358 --- /dev/null +++ b/assets/js/a710d533.89036d73.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1711],{42089:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var r=t(85893),o=t(3905),a=t(74866),i=t(85162);const s={title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"tomcat-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,c={permalink:"/tomcat-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1, 2\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-http/pull/302",date:"2023-09-11T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 11\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:12.345,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"tomcat-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",permalink:"/log-async-exception"},nextItem:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",permalink:"/performance-test-type"}},u={authorsImageUrls:[]},d=[{value:"\ud1b0\ucea3 \uad6c\ud604",id:"\ud1b0\ucea3-\uad6c\ud604",level:3},{value:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",id:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",level:3},{value:"\ucf54\ub4dc \ub9ac\ubdf0",id:"\ucf54\ub4dc-\ub9ac\ubdf0",level:3},{value:"SessionConfig",id:"sessionconfig",level:3},{value:"HTTP \uc218\uc5c5",id:"http-\uc218\uc5c5",level:3},{value:"Thread \uc218\uc5c5",id:"thread-\uc218\uc5c5",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",br:"br",code:"code",h3:"h3",mermaid:"mermaid",p:"p",pre:"pre",...(0,o.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,r.jsxs)(n.p,{children:["1, 2\ub2e8\uacc4: ",(0,r.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-http/pull/302",children:"https://github.com/woowacourse/jwp-dashboard-http/pull/302"}),(0,r.jsx)(n.br,{}),"\n","3, 4\ub2e8\uacc4: ",(0,r.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-dashboard-http/pull/431",children:"https://github.com/woowacourse/jwp-dashboard-http/pull/431"})]})}),"\n",(0,r.jsx)(n.h3,{id:"\ud1b0\ucea3-\uad6c\ud604",children:"\ud1b0\ucea3 \uad6c\ud604"}),"\n",(0,r.jsxs)(n.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c0\uc6d0\ud560 \ub54c \uac1d\uccb4\uc9c0\ud5a5\uacfc \uad00\ub828\ub41c \ubbf8\uc158\ub3c4 \uae30\ub300\ub97c \ub9ce\uc774 \ud588\uc9c0\ub9cc \ub808\ubca8 4\uc5d0 \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc774 \uc815\ub9d0 \ud558\uace0 \uc2f6\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uadf8\ub798\uc11c \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc744\uae4c\ub77c\ub294 \uac71\uc815 \ubc18, \ubbf8\uc158\uc5d0 \ub300\ud55c \uae30\ub300 \ubc18\uc73c\ub85c \ubd80\ud47c \ub9c8\uc74c\uc744 \uac00\uc9c0\uace0 \ubbf8\uc158\uc744 \uc2dc\uc791\ud588\ub358 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc801\uc808\ud558\uac8c \ucd94\uc0c1\ud654\ud558\uace0, \ubbf8\uc158\uc758 \ubcf8\uc9c8\uc744 \uc774\ud574\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158\uc740 ",(0,r.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2616/",children:"RFC 2616"}),"\uc5d0 \uba85\uc2dc\ub41c \uc2a4\ud399(\uc644\ubcbd\ud558\uc9c0 \uc54a\uc9c0\ub9cc \ubbf8\uc158\uc5d0\uc11c \uc8fc\uc5b4\uc9c4 \uc694\uad6c\uc0ac\ud56d\ub9cc \ub9cc\uc871\ud558\ub3c4\ub85d)\uc73c\ub85c \uc694\uccad\uc744 \ubc1b\uc544 \ucc98\ub9ac \ud6c4 \ubc18\ud658\ud558\ub294\ub370 \uc9d1\uc911\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",children:"\ub2e4\uc774\uc5b4\uadf8\ub7a8"}),"\n",(0,r.jsxs)(n.p,{children:["Catalina\ub294 Tomcat\uc758 \uc11c\ube14\ub9bf \ucee8\ud14c\uc774\ub108, Coyote\ub294 HTTP 1.1 \uc6f9 \uc11c\ubc84\ub97c \uc9c0\uc6d0\ud558\ub294 \uad6c\uc131 \uc694\uc18c\ub77c\uace0 \uc0dd\uac01\ud558\uace0 \uc544\ub798\uc640 \uac19\uc774 \uad6c\uc131\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc0ac\uc2e4 \ub0b4\ubd80 \uad6c\uc870\ub97c \uae4a\uac8c \uacf5\ubd80\ud560 \uc2dc\uac04\uc744 \uac00\uc9c0\uc9c0 \ubabb\ud574\uc11c \uac01 \uad6c\uc131 \uc694\uc18c\uac00 \uc65c \ud574\ub2f9 \uc704\uce58\uc5d0 \uc788\ub294\uc9c0 \uc644\ubcbd\ud558\uac8c \uc124\uba85\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc774\uac74 \uc5ec\uae30\uc5d0 \uc788\uc73c\uba74 \uc88b\uc744 \uac83 \uac19\uc740\ub370? \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e4\uba74 \uc801\uc808\ud55c \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\uc2dc\ud0a4\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub610\ud55c \uc801\uc808\ud558\uac8c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc73c\ub85c \ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n\tsubgraph coyote\n\t\tHP[Http11Processor] --\x3e A\n\t\tHP --\x3e HttpRequestParser\n\t\tHP --\x3e HttpResponseGenerator\n\t\tA[Adapter]\n end\n\n subgraph catalina\n\t\tRA[RequestAdapter] -.-> A\n\t\tAC[AbstractController] -.-> C[Controller]\n\t\tStaticController -.-> AC\n\t\tSM[SessionManger] -.-> Manager\n\t\tTC[Tomcat] --\x3e RA\n\t\tRA --\x3e C\n\t\tRA --\x3e Manager\n\t\tRA --\x3e RM\n\t\tRM[RequestMapper] --\x3e C\n end\n\n subgraph jwp\n\t\tLC[LoginController] -.-> AC\n\t\tApplication --\x3e TC\n end\n"}),"\n",(0,r.jsx)(n.h3,{id:"\ucf54\ub4dc-\ub9ac\ubdf0",children:"\ucf54\ub4dc \ub9ac\ubdf0"}),"\n",(0,r.jsxs)(n.p,{children:["\ud06c\ub8e8 \uc911 \ud55c \uba85\uc774 \ub098\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\uace0, \ub0b4\uac00 \ub2e4\ub978 \ud06c\ub8e8\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\ub294 \ud615\ud0dc\ub85c \uc9c4\ud589\uc774 \ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub514\ub178, \ub9ac\ubdf0\uc774\ub294 \ud544\ub9bd\uc774\uc5c8\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ub514\ub178(\ub9e4\uc758 \ub208\uc774 \uc544\ub2cc \uacf5\ub8e1\uc758 \ub208?)\uac00 \ub9e4\uc6b0 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud574\uc8fc\uc5b4\uc11c \uc870\uae08 \ub354 \ub098\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \uc218 \uc788\uc5c8\uace0, \ud544\ub9bd\uc758 \ucf54\ub4dc\uc5d0\uc11c\ub294 \uaf3c\uaf3c\ud558\uac8c \uc608\uc678\ucc98\ub9ac \ud558\ub294 \ubd80\ubd84\uc744 \ubc30\uc6b8 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud55c \uac00\uc9c0 \uc544\uc26c\uc6b4 \uc810\uc740 \ud544\ub9bd\uc5d0\uac8c \uc791\uc131\ud55c \ub098\uc758 \ucf54\uba58\ud2b8\ub4e4\uc774 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uacbd\ud5d8 \uae30\ubc18\uc73c\ub85c \uc791\uc131\ud55c \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uadfc\uac70\uac00 \uc870\uae08 \ubd80\uc871\ud588\uace0, \uc815\ub9ac\ub418\uc9c0 \uc54a\uc740 \ubd80\ubd84\uc774 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130 \ub9ac\ubdf0\ud560 \ub54c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ub354 \uc88b\uc740 \ub0b4\uc6a9\uc744 \ud06c\ub8e8\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"sessionconfig",children:"SessionConfig"}),"\n",(0,r.jsxs)(n.p,{children:["\ubbf8\uc158\uc744 \uc9c4\ud589 \uc911 catalina \ud328\ud0a4\uc9c0\uc758 Session \uad00\ub828 \ubd80\ubd84\uc744 \ubcf4\uba74\uc11c \uc911\ubcf5 \ub85c\uc9c1\uc744 \uac1c\uc120\ud574 \ubcfc \uc218 \uc788\uc744 \uac83 \uac19\uc544 ",(0,r.jsx)(n.a,{href:"https://github.com/apache/tomcat/pull/660",children:"\ucee8\ud2b8\ub9ac\ubdf0\ud2b8"}),"\ub97c \uc2dc\ub3c4\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc138\uc158 \ucfe0\ud0a4\uc758 \uc774\ub984\uc744 \uac00\uc838\uc624\ub294 Util \ud074\ub798\uc2a4\uc758 \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub294\ub370 \uae30\ubcf8 \uac12\uc740 JSESSIONID \uc9c0\ub9cc \uc124\uc815\uc5d0 \ub530\ub77c\uc11c \uc138\uc158 \ucfe0\ud0a4\uba85\uc744 \ub2e4\ub974\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ub85c\uc9c1\uc774 \uc788\ub294 \uac83\uc73c\ub85c \uc0dd\uac01\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uae30\uc874\uc758 \ucf54\ub4dc\ub294 \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \ucf54\ub4dc\uc758 \ud750\ub984\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc544\uc11c \uc57d\uac04 \uc774\ud574\ud558\uae30 \uc5b4\ub824\uc6e0\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ucd08\uae30\uc5d0 \uc694\uccad\ud588\ub358 PR\uc740 \uae30\uc874\uc758 \ucf54\ub4dc\ubcf4\ub2e4 \uc804\uccb4\uc801\uc73c\ub85c \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, context\uac00 null\uc778 \uacbd\uc6b0 \ubc14\ub85c \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud568\uc73c\ub85c\uc368 \uc131\ub2a5 \uac1c\uc120\uc758 \ud6a8\uacfc\uac00 \uc788\uc744 \uac70\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uba54\uc778\ud14c\uc774\ub108\uc778 Mark Thomas \ud615\uc774 \ud574\ub2f9 \ub85c\uc9c1\uc758 \uacbd\uc6b0 \ucef4\ud30c\uc77c\ub7ec\uac00 \ud574\ub2f9 \ubd80\ubd84\uc744 \ucd5c\uc801\ud654 \ud560 \uc218 \uc788\uc744 \uac70\ub77c\uace0 \uae30\ub300\ud55c\ub2e4\uace0 \ud588\uace0, \uac00\ub3c5\uc131\uc744 \uac1c\uc120\uc2dc\ucf1c\ubcf4\ub77c\uace0 \uc870\uc5b8\ud574\uc8fc\uc168\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucef4\ud30c\uc77c\ub7ec \ucd5c\uc801\ud654\ub294 \uace0\ub824\ud574\ubcf4\uc9c0 \ubabb\ud55c \ubd80\ubd84\uc778\ub370, \uc55e\uc73c\ub85c \ud559\uc2b5\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc0b0\ub354\ubbf8\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ub0a8\uaca8\uc900 \ucf54\uba58\ud2b8\uc5d0 \ub530\ub77c \ucd5c\uc885\uc801\uc73c\ub85c\ub294 \uc911\ubcf5\ub41c \ucf54\ub4dc\ub97c \uc904\uc774\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uacb0\uacfc\uc801\uc73c\ub85c \uae30\uc874 \ub85c\uc9c1 \ub300\ube44 \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \uc720\uc0ac\ud55c \ud750\ub984\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \ud588\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n","\n","\n",(0,r.jsxs)(a.Z,{children:[(0,r.jsx)(i.Z,{value:"\uae30\uc874",label:"\uae30\uc874",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public static String getSessionCookieName(Context context) {\n\n String result = getConfiguredSessionCookieName(context);\n\n if (result == null) {\n result = DEFAULT_SESSION_COOKIE_NAME;\n }\n\n return result;\n}\n\npublic static String getSessionUriParamName(Context context) {\n\n String result = getConfiguredSessionCookieName(context);\n\n if (result == null) {\n result = DEFAULT_SESSION_PARAMETER_NAME;\n }\n\n return result;\n}\n\nprivate static String getConfiguredSessionCookieName(Context context) {\n\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n if (context != null) {\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc =\n context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n }\n\n return null;\n}\n"})})}),(0,r.jsx)(i.Z,{value:"PR \uc694\uccad",label:"PR \uc694\uccad",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public static String getSessionCookieName(Context context) {\n if (context == null) {\n return DEFAULT_SESSION_COOKIE_NAME;\n }\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\n}\n\npublic static String getSessionUriParamName(Context context) {\n if (context == null) {\n return DEFAULT_SESSION_PARAMETER_NAME;\n }\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\n}\n\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n return defaultName;\n}\n"})})}),(0,r.jsx)(i.Z,{value:"\ucd5c\uc885",label:"\ucd5c\uc885",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public static String getSessionCookieName(Context context) {\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\n}\n\npublic static String getSessionUriParamName(Context context) {\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\n}\n\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n if (context != null) {\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n }\n return defaultName;\n}\n"})})})]}),"\n",(0,r.jsx)(n.h3,{id:"http-\uc218\uc5c5",children:"HTTP \uc218\uc5c5"}),"\n",(0,r.jsxs)(n.p,{children:["\ubbf8\uc158 \uc911\uac04\uc5d0 \uc9c4\ud589\ub418\uc5c8\ub358 HTTP \uc218\uc5c5\uc5d0\ub294 HTTP\ub97c \uc801\uc808\ud558\uac8c \ud65c\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud56d\uc0c1 \uc131\ub2a5 \uac1c\uc120\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub2e8\uc5d0\uc11c \ucd5c\uc801\ud654\ud574\ubcf4\ub824\uace0 \ub178\ub825\uc744 \ud588\uc9c0\ub9cc, \ub354 \uc801\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ud6a8\uc728\uc801\uc73c\ub85c \uc131\ub2a5\uc744 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc54c \uc218 \uc788\uc5c8\ub358 \uc218\uc5c5\uc774\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","HTTP \uc555\ucd95, HTTP \uce90\uc2f1, \ub9ac\uc18c\uc2a4 \ucd5c\uc801\ud654 \uae30\ubc95\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \ub2e4\uc74c \uc635\uc158\uc744 \uc124\uc815\ud558\uc5ec http\uc758 \uc1a1\uc218\uc2e0\uc758 \uc555\ucd95\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yml",children:"server:\n compression:\n enabled: true\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc218\uc5c5 \uc911 \ud574\ub2f9 \uc555\ucd95 \uc131\ub2a5\uc774 \uc88b\ub2e4\uba74 \uc65c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \uae30\ubcf8 \uac12\uc73c\ub85c \uc124\uc815\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\uc9c0 \uad81\uae08\ud574\uc84c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uad81\uae08\uc99d\uc744 \ud574\uc18c\ud558\uc9c0 \ubabb\ud588\ub294\ub370 \ub9d0\ub791\uc774 \uc7a1\ub2f4 \ucc44\ub110\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc740 ",(0,r.jsx)(n.a,{href:"https://github.com/spring-projects/spring-boot/issues/21369",children:"issue"}),"\ub97c \ucc3e\uc544\uc8fc\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub0b4\uc6a9\uc744 \uc694\uc57d\ud574 \ubcf4\uc790\uba74 WAS \ubcc4\ub85c \uc555\ucd95\uc744 \ud558\uae30 \uc704\ud574 \uc124\uc815\ud574\uc57c \ud558\ub294 \uac83\uc774 \ub2e4\ub974\uace0, \ubb34\uc870\uac74 \uc555\ucd95\uc744 \ud558\ub294 \uac83\uc774 \ucd5c\uc801\uc758 \uacbd\uc6b0\uac00 \uc544\ub2d0 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"Phil Webb \ud615\ub2d8\uc758 \ub9d0\uc5d0 \ub530\ub974\uba74 \uc77c\ubc18\uc801\uc778 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \uacbd\uc6b0 gzip \uc555\ucd95\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc9c0\ub9cc, MSA \ud658\uacbd + \ub370\uc774\ud130 \uc13c\ud130\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \uc624\uc9c1 \ub2e4\ub978 MSA \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uacfc \ud1b5\uc2e0\ud558\uace0, \uace0\uc131\ub2a5 \ub124\ud2b8\uc6cc\ud06c\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0 CPU \ubd80\ud558\ub97c \uc904\uc774\ub294 \uac83\uc774 \uc6b0\uc120\uc2dc \ub420 \uc218\ub3c4 \uc788\ub2e4\ub294 \uac83\uc774\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:"\uc774\uc678\uc5d0\ub3c4 \uc758\ub3c4\ud558\uc9c0 \uc54a\uc740 \uce90\uc2f1\uc744 \ub9c9\uae30 \uc704\ud574 \ud734\ub9ac\uc2a4\ud2f1 \uce90\uc2f1\uc744 \uc81c\uac70\ud558\uac70\ub098, \uac1c\uc778 \uc815\ubcf4 \uc720\ucd9c\uc744 \ub9c9\uae30 \uc704\ud574 \uc751\ub2f5 \ud5e4\ub354\uc5d0 private\uc744 \uc124\uc815, ETag\ub3c4 \ud559\uc2b5\ud588\ub2e4."}),"\n",(0,r.jsx)(n.admonition,{title:"ETag",type:"note",children:(0,r.jsxs)(n.p,{children:["ETag HTTP \uc751\ub2f5 \ud5e4\ub354\ub294 \ud2b9\uc815 \ubc84\uc804\uc758 \ub9ac\uc18c\uc2a4\ub97c \uc2dd\ubcc4\ud558\ub294 \uc2dd\ubcc4\uc790\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc6f9 \uc11c\ubc84\uac00 \ub0b4\uc6a9\uc744 \ud655\uc778\ud558\uace0 \ubcc0\ud558\uc9c0 \uc54a\uc558\uc73c\uba74, \uc6f9 \uc11c\ubc84\ub85c full \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0, \uce90\uc2dc\uac00 \ub354 \ud6a8\uc728\uc801\uc774\uac8c \ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","MDN"]})}),"\n",(0,r.jsx)(n.h3,{id:"thread-\uc218\uc5c5",children:"Thread \uc218\uc5c5"}),"\n",(0,r.jsxs)(n.p,{children:["\uc2a4\ub808\ub4dc\uc5d0 \ub300\ud55c \uc218\uc5c5\uc744 \ub4e4\uc5c8\uc9c0\ub9cc, \ubcf5\uc7a1\ud55c \ub0b4\uc6a9\ub3c4 \uc6cc\ub099 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0 \uc124\uba85\ud558\ub77c\uace0 \ud558\uba74 \uc798 \ubabb\ud560 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e0\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud604\uc7ac \ud504\ub85c\uc81d\ud2b8, \ubbf8\uc158, \ud14c\ucf54\ud1a1 \uc900\ube44\ub97c \ubcd1\ud589\ud574\uc57c \ud574\uc11c \uc138\ubd80\uc801\uc778 \ub0b4\uc6a9\uc740 \uc2dc\uac04 \ub0a0 \ub54c \ubcf5\uc2b5\ud558\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\uc2a4\ub808\ub4dc\ub97c \uc774\ud574\ud558\uace0, WAS\uc5d0 \uc2a4\ub808\ub4dc \uc124\uc815 \uad00\ub828\ud55c \uc2e4\uc2b5\uc774 \uc788\uc5c8\ub294\ub370 \ud14c\uc624\uc640 \uac19\uc774 1\uc2dc\uac04 \uc815\ub3c4 \ud398\uc5b4\ub85c Thread \uc2e4\uc2b5\uc744 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud559\uc2b5\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"threads.max"}),": Tomcat\uc758 \ucd5c\ub300 \uc2a4\ub808\ub4dc \uac1c\uc218",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.code,{children:"max-connections"}),": Tomcat\uc774 \uc720\uc9c0\ud560 \uc218 \uc788\ub294 \ucd5c\ub300 \ucee4\ub125\uc158 \uac1c\uc218",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.code,{children:"accept-count"}),": \ucd5c\ub300 \uc5f0\uacb0 \uc218\uc5d0 \ub3c4\ub2ec\ud588\uc744 \ub54c \uc5f0\uacb0 \uc694\uccad\uc5d0 \ub300\ud574 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub300\uae30\uc5f4\uc758 \ucd5c\ub300 \uae38\uc774. \ud574\ub2f9 Queue\uc5d0 \uc694\uccad\uc774 \uc313\uc774\ub294 \uac83\uc740 Tomcat\uc774 \ub354 \uc774\uc0c1 \uc694\uccad\uc744 \ubc1b\uc744 \uc218 \uc5c6\ub2e4\ub294 \ub73b\uc774\ub2e4. accpet-count queue\uc5d0\ub3c4 \uc694\uccad\uc774 \uac00\ub4dd\ucc28\uba74 \uadf8 \uc774\ud6c4\uc5d0 \uc624\ub294 \uc694\uccad\uc740 \uac70\ubd80\ub41c\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:'graph LR\n C("Client") -- request --\x3e ACQ("\uc6b4\uc601\uccb4\uc81c\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue \n size = accept-count") --\x3e TCQ("Tomcat Connector\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue\n size = max-connections") --\x3e TP("Thread Pool\n size = threads.max")'}),"\n",(0,r.jsx)(n.h3,{id:"\ub9c8\uce58\uba70",children:"\ub9c8\uce58\uba70"}),"\n",(0,r.jsxs)(n.p,{children:["\uc2dc\uac04\uc740 \ub108\ubb34 \ube60\ub974\uac8c \uac00\uace0 \ud560 \uc77c\uc740 \ub9ce\uc740 \uac83 \uac19\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc6b0\uc120\uc21c\uc704\ub97c \uc798 \uc815\ud558\uace0 \ud559\uc2b5\uc744 \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud604\uc7ac \ub370\uc774\ud130 \ub2e4\ub8e8\ub294 \ubd80\ubd84(DB)\uc5d0 \ub300\ud55c \ud559\uc2b5\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\ub2e4. \ud574\ub2f9 \ubd80\ubd84\uc740 \ud14c\ucf54\ud1a1\uc774 \ub05d\ub098\ub294\ub300\ub85c \ucc44\uc6cc\uc57c\uaca0\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2616/",children:"RFC 2616"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/ETag",children:"ETag, mdn"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://tomcat.apache.org/tomcat-8.5-doc/config/http.html",children:"Apache Tomcat 8 Configuration Reference"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://bcho.tistory.com/788",children:"Apache Tomcat Tuning, Terry Cho"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://dev-ws.tistory.com/96",children:"maxThreads, maxConnections, acceptCount\ub85c Tomcat \ud29c\ub2dd\ud558\uae30"})]})]})}function h(e={}){const{wrapper:n}={...(0,o.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>c});var r=t(67294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?a(Object(t),!0).forEach((function(n){o(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=c(t),h=o,m=p["".concat(l,".").concat(h)]||p[h]||u[h]||a;return t?r.createElement(m,i(i({ref:n},d),{},{components:t})):r.createElement(m,i({ref:n},d))}));d.displayName="MDXCreateElement"},85162:(e,n,t)=>{t.d(n,{Z:()=>i});t(67294);var r=t(86010);const o={tabItem:"tabItem_Ymn6"};var a=t(85893);function i(e){let{children:n,hidden:t,className:i}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,r.Z)(o.tabItem,i),hidden:t,children:n})}},74866:(e,n,t)=>{t.d(n,{Z:()=>S});var r=t(67294),o=t(86010),a=t(12466),i=t(16550),s=t(20469),l=t(91980),c=t(67392),u=t(50012);function d(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:o}}=e;return{value:n,label:t,attributes:r,default:o}}))}(t);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function h(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:t}=e;const o=(0,i.k6)(),a=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,l._X)(a),(0,r.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(o.location.search);n.set(a,e),o.replace({...o.location,search:n.toString()})}),[a,o])]}function g(e){const{defaultValue:n,queryString:t=!1,groupId:o}=e,a=p(e),[i,l]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!h({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:a}))),[c,d]=m({queryString:t,groupId:o}),[g,x]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[o,a]=(0,u.Nk)(t);return[o,(0,r.useCallback)((e=>{t&&a.set(e)}),[t,a])]}({groupId:o}),b=(()=>{const e=c??g;return h({value:e,tabValues:a})?e:null})();(0,s.Z)((()=>{b&&l(b)}),[b]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!h({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),x(e)}),[d,x,a]),tabValues:a}}var x=t(72389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var f=t(85893);function j(e){let{className:n,block:t,selectedValue:r,selectValue:i,tabValues:s}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,a.o5)(),u=e=>{const n=e.currentTarget,t=l.indexOf(n),o=s[t].value;o!==r&&(c(n),i(o))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1];break}}n?.focus()};return(0,f.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":t},n),children:s.map((e=>{let{value:n,label:t,attributes:a}=e;return(0,f.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>l.push(e),onKeyDown:d,onClick:u,...a,className:(0,o.Z)("tabs__item",b.tabItem,a?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function v(e){let{lazy:n,children:t,selectedValue:o}=e;const a=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===o));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,f.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==o})))})}function C(e){const n=g(e);return(0,f.jsxs)("div",{className:(0,o.Z)("tabs-container",b.tabList),children:[(0,f.jsx)(j,{...e,...n}),(0,f.jsx)(v,{...e,...n})]})}function S(e){const n=(0,x.Z)();return(0,f.jsx)(C,{...e,children:d(e.children)},String(n))}}}]); \ No newline at end of file diff --git a/assets/js/a710d533.dc0f0af8.js b/assets/js/a710d533.dc0f0af8.js deleted file mode 100644 index 42b851fb6..000000000 --- a/assets/js/a710d533.dc0f0af8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1711],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>d});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var u=a.createContext({}),c=function(e){var t=a.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},s=function(e){var t=c(e.components);return a.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,u=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=c(n),d=r,g=m["".concat(u,".").concat(d)]||m[d]||p[d]||o;return n?a.createElement(g,i(i({ref:t},s),{},{components:n})):a.createElement(g,i({ref:t},s))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,i=new Array(o);i[0]=m;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:r,i[1]=l;for(var c=2;c<o;c++)i[c]=n[c];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"},85162:(e,t,n)=>{n.d(t,{Z:()=>i});var a=n(67294),r=n(86010);const o="tabItem_Ymn6";function i(e){let{children:t,hidden:n,className:i}=e;return a.createElement("div",{role:"tabpanel",className:(0,r.Z)(o,i),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>S});var a=n(87462),r=n(67294),o=n(86010),i=n(12466),l=n(16550),u=n(91980),c=n(67392),s=n(50012);function p(e){return function(e){return r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:a,default:r}}=e;return{value:t,label:n,attributes:a,default:r}}))}function m(e){const{values:t,children:n}=e;return(0,r.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,n])}function d(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function g(e){let{queryString:t=!1,groupId:n}=e;const a=(0,l.k6)(),o=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,u._X)(o),(0,r.useCallback)((e=>{if(!o)return;const t=new URLSearchParams(a.location.search);t.set(o,e),a.replace({...a.location,search:t.toString()})}),[o,a])]}function k(e){const{defaultValue:t,queryString:n=!1,groupId:a}=e,o=m(e),[i,l]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!d({value:t,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const a=n.find((e=>e.default))??n[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:t,tabValues:o}))),[u,c]=g({queryString:n,groupId:a}),[p,k]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[a,o]=(0,s.Nk)(n);return[a,(0,r.useCallback)((e=>{n&&o.set(e)}),[n,o])]}({groupId:a}),f=(()=>{const e=u??p;return d({value:e,tabValues:o})?e:null})();(0,r.useLayoutEffect)((()=>{f&&l(f)}),[f]);return{selectedValue:i,selectValue:(0,r.useCallback)((e=>{if(!d({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);l(e),c(e),k(e)}),[c,k,o]),tabValues:o}}var f=n(72389);const b="tabList__CuJ",h="tabItem_LNqP";function N(e){let{className:t,block:n,selectedValue:l,selectValue:u,tabValues:c}=e;const s=[],{blockElementScrollPositionUntilNextRender:p}=(0,i.o5)(),m=e=>{const t=e.currentTarget,n=s.indexOf(t),a=c[n].value;a!==l&&(p(t),u(a))},d=e=>{let t=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const n=s.indexOf(e.currentTarget)+1;t=s[n]??s[0];break}case"ArrowLeft":{const n=s.indexOf(e.currentTarget)-1;t=s[n]??s[s.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.Z)("tabs",{"tabs--block":n},t)},c.map((e=>{let{value:t,label:n,attributes:i}=e;return r.createElement("li",(0,a.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>s.push(e),onKeyDown:d,onClick:m},i,{className:(0,o.Z)("tabs__item",h,i?.className,{"tabs__item--active":l===t})}),n??t)})))}function v(e){let{lazy:t,children:n,selectedValue:a}=e;const o=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=o.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},o.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==a}))))}function C(e){const t=k(e);return r.createElement("div",{className:(0,o.Z)("tabs-container",b)},r.createElement(N,(0,a.Z)({},e,t)),r.createElement(v,(0,a.Z)({},e,t)))}function S(e){const t=(0,f.Z)();return r.createElement(C,(0,a.Z)({key:String(t)},e))}},95220:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>u,default:()=>d,frontMatter:()=>l,metadata:()=>c,toc:()=>p});var a=n(87462),r=(n(67294),n(3905)),o=n(74866),i=n(85162);const l={title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"tomcat-retrospective",tags:["Woowahan Techcourse","Retrospective"]},u=void 0,c={permalink:"/tomcat-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1, 2\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-http/pull/302",date:"2023-09-11T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 11\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:12.345,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"tomcat-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",permalink:"/log-async-exception"},nextItem:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",permalink:"/performance-test-type"}},s={authorsImageUrls:[]},p=[{value:"\ud1b0\ucea3 \uad6c\ud604",id:"\ud1b0\ucea3-\uad6c\ud604",level:3},{value:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",id:"\ub2e4\uc774\uc5b4\uadf8\ub7a8",level:3},{value:"\ucf54\ub4dc \ub9ac\ubdf0",id:"\ucf54\ub4dc-\ub9ac\ubdf0",level:3},{value:"SessionConfig",id:"sessionconfig",level:3},{value:"HTTP \uc218\uc5c5",id:"http-\uc218\uc5c5",level:3},{value:"Thread \uc218\uc5c5",id:"thread-\uc218\uc5c5",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],m={toc:p};function d(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"1, 2\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-http/pull/302"},"https://github.com/woowacourse/jwp-dashboard-http/pull/302"),(0,r.kt)("br",{parentName:"p"}),"\n","3, 4\ub2e8\uacc4: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-http/pull/431"},"https://github.com/woowacourse/jwp-dashboard-http/pull/431"))),(0,r.kt)("h3",{id:"\ud1b0\ucea3-\uad6c\ud604"},"\ud1b0\ucea3 \uad6c\ud604"),(0,r.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c0\uc6d0\ud560 \ub54c \uac1d\uccb4\uc9c0\ud5a5\uacfc \uad00\ub828\ub41c \ubbf8\uc158\ub3c4 \uae30\ub300\ub97c \ub9ce\uc774 \ud588\uc9c0\ub9cc \ub808\ubca8 4\uc5d0 \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc774 \uc815\ub9d0 \ud558\uace0 \uc2f6\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uadf8\ub798\uc11c \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc744\uae4c\ub77c\ub294 \uac71\uc815 \ubc18, \ubbf8\uc158\uc5d0 \ub300\ud55c \uae30\ub300 \ubc18\uc73c\ub85c \ubd80\ud47c \ub9c8\uc74c\uc744 \uac00\uc9c0\uace0 \ubbf8\uc158\uc744 \uc2dc\uc791\ud588\ub358 \uac83 \uac19\ub2e4. "),(0,r.kt)("p",null,"\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc801\uc808\ud558\uac8c \ucd94\uc0c1\ud654\ud558\uace0, \ubbf8\uc158\uc758 \ubcf8\uc9c8\uc744 \uc774\ud574\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158\uc740 ",(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc2616/"},"RFC 2616"),"\uc5d0 \uba85\uc2dc\ub41c \uc2a4\ud399(\uc644\ubcbd\ud558\uc9c0 \uc54a\uc9c0\ub9cc \ubbf8\uc158\uc5d0\uc11c \uc8fc\uc5b4\uc9c4 \uc694\uad6c\uc0ac\ud56d\ub9cc \ub9cc\uc871\ud558\ub3c4\ub85d)\uc73c\ub85c \uc694\uccad\uc744 \ubc1b\uc544 \ucc98\ub9ac \ud6c4 \ubc18\ud658\ud558\ub294\ub370 \uc9d1\uc911\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\ub2e4\uc774\uc5b4\uadf8\ub7a8"},"\ub2e4\uc774\uc5b4\uadf8\ub7a8"),(0,r.kt)("p",null,"Catalina\ub294 Tomcat\uc758 \uc11c\ube14\ub9bf \ucee8\ud14c\uc774\ub108, Coyote\ub294 HTTP 1.1 \uc6f9 \uc11c\ubc84\ub97c \uc9c0\uc6d0\ud558\ub294 \uad6c\uc131 \uc694\uc18c\ub77c\uace0 \uc0dd\uac01\ud558\uace0 \uc544\ub798\uc640 \uac19\uc774 \uad6c\uc131\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc2e4 \ub0b4\ubd80 \uad6c\uc870\ub97c \uae4a\uac8c \uacf5\ubd80\ud560 \uc2dc\uac04\uc744 \uac00\uc9c0\uc9c0 \ubabb\ud574\uc11c \uac01 \uad6c\uc131 \uc694\uc18c\uac00 \uc65c \ud574\ub2f9 \uc704\uce58\uc5d0 \uc788\ub294\uc9c0 \uc644\ubcbd\ud558\uac8c \uc124\uba85\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc774\uac74 \uc5ec\uae30\uc5d0 \uc788\uc73c\uba74 \uc88b\uc744 \uac83 \uac19\uc740\ub370? \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e4\uba74 \uc801\uc808\ud55c \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\uc2dc\ud0a4\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \uc801\uc808\ud558\uac8c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc73c\ub85c \ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n\tsubgraph coyote\n\t\tHP[Http11Processor] --\x3e A\n\t\tHP --\x3e HttpRequestParser\n\t\tHP --\x3e HttpResponseGenerator\n\t\tA[Adapter]\n end\n\n subgraph catalina\n\t\tRA[RequestAdapter] -.-> A\n\t\tAC[AbstractController] -.-> C[Controller]\n\t\tStaticController -.-> AC\n\t\tSM[SessionManger] -.-> Manager\n\t\tTC[Tomcat] --\x3e RA\n\t\tRA --\x3e C\n\t\tRA --\x3e Manager\n\t\tRA --\x3e RM\n\t\tRM[RequestMapper] --\x3e C\n end\n\n subgraph jwp\n\t\tLC[LoginController] -.-> AC\n\t\tApplication --\x3e TC\n end\n"}),(0,r.kt)("h3",{id:"\ucf54\ub4dc-\ub9ac\ubdf0"},"\ucf54\ub4dc \ub9ac\ubdf0"),(0,r.kt)("p",null,"\ud06c\ub8e8 \uc911 \ud55c \uba85\uc774 \ub098\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\uace0, \ub0b4\uac00 \ub2e4\ub978 \ud06c\ub8e8\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\ub294 \ud615\ud0dc\ub85c \uc9c4\ud589\uc774 \ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub514\ub178, \ub9ac\ubdf0\uc774\ub294 \ud544\ub9bd\uc774\uc5c8\ub2e4. "),(0,r.kt)("p",null,"\ub514\ub178(\ub9e4\uc758 \ub208\uc774 \uc544\ub2cc \uacf5\ub8e1\uc758 \ub208?)\uac00 \ub9e4\uc6b0 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud574\uc8fc\uc5b4\uc11c \uc870\uae08 \ub354 \ub098\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \uc218 \uc788\uc5c8\uace0, \ud544\ub9bd\uc758 \ucf54\ub4dc\uc5d0\uc11c\ub294 \uaf3c\uaf3c\ud558\uac8c \uc608\uc678\ucc98\ub9ac \ud558\ub294 \ubd80\ubd84\uc744 \ubc30\uc6b8 \uc218 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud55c \uac00\uc9c0 \uc544\uc26c\uc6b4 \uc810\uc740 \ud544\ub9bd\uc5d0\uac8c \uc791\uc131\ud55c \ub098\uc758 \ucf54\uba58\ud2b8\ub4e4\uc774 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uacbd\ud5d8 \uae30\ubc18\uc73c\ub85c \uc791\uc131\ud55c \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uadfc\uac70\uac00 \uc870\uae08 \ubd80\uc871\ud588\uace0, \uc815\ub9ac\ub418\uc9c0 \uc54a\uc740 \ubd80\ubd84\uc774 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130 \ub9ac\ubdf0\ud560 \ub54c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ub354 \uc88b\uc740 \ub0b4\uc6a9\uc744 \ud06c\ub8e8\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. "),(0,r.kt)("h3",{id:"sessionconfig"},"SessionConfig"),(0,r.kt)("p",null,"\ubbf8\uc158\uc744 \uc9c4\ud589 \uc911 catalina \ud328\ud0a4\uc9c0\uc758 Session \uad00\ub828 \ubd80\ubd84\uc744 \ubcf4\uba74\uc11c \uc911\ubcf5 \ub85c\uc9c1\uc744 \uac1c\uc120\ud574 \ubcfc \uc218 \uc788\uc744 \uac83 \uac19\uc544 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/apache/tomcat/pull/660"},"\ucee8\ud2b8\ub9ac\ubdf0\ud2b8"),"\ub97c \uc2dc\ub3c4\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc138\uc158 \ucfe0\ud0a4\uc758 \uc774\ub984\uc744 \uac00\uc838\uc624\ub294 Util \ud074\ub798\uc2a4\uc758 \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub294\ub370 \uae30\ubcf8 \uac12\uc740 JSESSIONID \uc9c0\ub9cc \uc124\uc815\uc5d0 \ub530\ub77c\uc11c \uc138\uc158 \ucfe0\ud0a4\uba85\uc744 \ub2e4\ub974\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ub85c\uc9c1\uc774 \uc788\ub294 \uac83\uc73c\ub85c \uc0dd\uac01\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc758 \ucf54\ub4dc\ub294 \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \ucf54\ub4dc\uc758 \ud750\ub984\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc544\uc11c \uc57d\uac04 \uc774\ud574\ud558\uae30 \uc5b4\ub824\uc6e0\ub2e4. "),(0,r.kt)("p",null,"\ucd08\uae30\uc5d0 \uc694\uccad\ud588\ub358 PR\uc740 \uae30\uc874\uc758 \ucf54\ub4dc\ubcf4\ub2e4 \uc804\uccb4\uc801\uc73c\ub85c \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, context\uac00 null\uc778 \uacbd\uc6b0 \ubc14\ub85c \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud568\uc73c\ub85c\uc368 \uc131\ub2a5 \uac1c\uc120\uc758 \ud6a8\uacfc\uac00 \uc788\uc744 \uac70\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uba54\uc778\ud14c\uc774\ub108\uc778 Mark Thomas \ud615\uc774 \ud574\ub2f9 \ub85c\uc9c1\uc758 \uacbd\uc6b0 \ucef4\ud30c\uc77c\ub7ec\uac00 \ud574\ub2f9 \ubd80\ubd84\uc744 \ucd5c\uc801\ud654 \ud560 \uc218 \uc788\uc744 \uac70\ub77c\uace0 \uae30\ub300\ud55c\ub2e4\uace0 \ud588\uace0, \uac00\ub3c5\uc131\uc744 \uac1c\uc120\uc2dc\ucf1c\ubcf4\ub77c\uace0 \uc870\uc5b8\ud574\uc8fc\uc168\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucef4\ud30c\uc77c\ub7ec \ucd5c\uc801\ud654\ub294 \uace0\ub824\ud574\ubcf4\uc9c0 \ubabb\ud55c \ubd80\ubd84\uc778\ub370, \uc55e\uc73c\ub85c \ud559\uc2b5\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc0b0\ub354\ubbf8\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,r.kt)("p",null,"\ub0a8\uaca8\uc900 \ucf54\uba58\ud2b8\uc5d0 \ub530\ub77c \ucd5c\uc885\uc801\uc73c\ub85c\ub294 \uc911\ubcf5\ub41c \ucf54\ub4dc\ub97c \uc904\uc774\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uacb0\uacfc\uc801\uc73c\ub85c \uae30\uc874 \ub85c\uc9c1 \ub300\ube44 \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \uc720\uc0ac\ud55c \ud750\ub984\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \ud588\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,r.kt)(o.Z,{mdxType:"Tabs"},(0,r.kt)(i.Z,{value:"\uae30\uc874",label:"\uae30\uc874",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public static String getSessionCookieName(Context context) {\n\n String result = getConfiguredSessionCookieName(context);\n\n if (result == null) {\n result = DEFAULT_SESSION_COOKIE_NAME;\n }\n\n return result;\n}\n\npublic static String getSessionUriParamName(Context context) {\n\n String result = getConfiguredSessionCookieName(context);\n\n if (result == null) {\n result = DEFAULT_SESSION_PARAMETER_NAME;\n }\n\n return result;\n}\n\nprivate static String getConfiguredSessionCookieName(Context context) {\n\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n if (context != null) {\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc =\n context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n }\n\n return null;\n}\n"))),(0,r.kt)(i.Z,{value:"PR \uc694\uccad",label:"PR \uc694\uccad",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public static String getSessionCookieName(Context context) {\n if (context == null) {\n return DEFAULT_SESSION_COOKIE_NAME;\n }\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\n}\n\npublic static String getSessionUriParamName(Context context) {\n if (context == null) {\n return DEFAULT_SESSION_PARAMETER_NAME;\n }\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\n}\n\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n return defaultName;\n}\n"))),(0,r.kt)(i.Z,{value:"\ucd5c\uc885",label:"\ucd5c\uc885",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public static String getSessionCookieName(Context context) {\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\n}\n\npublic static String getSessionUriParamName(Context context) {\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\n}\n\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\n // Priority is:\n // 1. Cookie name defined in context\n // 2. Cookie name configured for app\n // 3. Default defined by spec\n if (context != null) {\n String cookieName = context.getSessionCookieName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\n cookieName = scc.getName();\n if (cookieName != null && cookieName.length() > 0) {\n return cookieName;\n }\n }\n return defaultName;\n}\n")))),(0,r.kt)("h3",{id:"http-\uc218\uc5c5"},"HTTP \uc218\uc5c5"),(0,r.kt)("p",null,"\ubbf8\uc158 \uc911\uac04\uc5d0 \uc9c4\ud589\ub418\uc5c8\ub358 HTTP \uc218\uc5c5\uc5d0\ub294 HTTP\ub97c \uc801\uc808\ud558\uac8c \ud65c\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \uc131\ub2a5 \uac1c\uc120\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub2e8\uc5d0\uc11c \ucd5c\uc801\ud654\ud574\ubcf4\ub824\uace0 \ub178\ub825\uc744 \ud588\uc9c0\ub9cc, \ub354 \uc801\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ud6a8\uc728\uc801\uc73c\ub85c \uc131\ub2a5\uc744 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc54c \uc218 \uc788\uc5c8\ub358 \uc218\uc5c5\uc774\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","HTTP \uc555\ucd95, HTTP \uce90\uc2f1, \ub9ac\uc18c\uc2a4 \ucd5c\uc801\ud654 \uae30\ubc95\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4. "),(0,r.kt)("p",null,"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \ub2e4\uc74c \uc635\uc158\uc744 \uc124\uc815\ud558\uc5ec http\uc758 \uc1a1\uc218\uc2e0\uc758 \uc555\ucd95\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml"},"server:\n compression:\n enabled: true\n")),(0,r.kt)("p",null,"\uc218\uc5c5 \uc911 \ud574\ub2f9 \uc555\ucd95 \uc131\ub2a5\uc774 \uc88b\ub2e4\uba74 \uc65c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \uae30\ubcf8 \uac12\uc73c\ub85c \uc124\uc815\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\uc9c0 \uad81\uae08\ud574\uc84c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uad81\uae08\uc99d\uc744 \ud574\uc18c\ud558\uc9c0 \ubabb\ud588\ub294\ub370 \ub9d0\ub791\uc774 \uc7a1\ub2f4 \ucc44\ub110\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc740 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-boot/issues/21369"},"issue"),"\ub97c \ucc3e\uc544\uc8fc\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub0b4\uc6a9\uc744 \uc694\uc57d\ud574 \ubcf4\uc790\uba74 WAS \ubcc4\ub85c \uc555\ucd95\uc744 \ud558\uae30 \uc704\ud574 \uc124\uc815\ud574\uc57c \ud558\ub294 \uac83\uc774 \ub2e4\ub974\uace0, \ubb34\uc870\uac74 \uc555\ucd95\uc744 \ud558\ub294 \uac83\uc774 \ucd5c\uc801\uc758 \uacbd\uc6b0\uac00 \uc544\ub2d0 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 \uac19\ub2e4. "),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.")),(0,r.kt)("p",null,"Phil Webb \ud615\ub2d8\uc758 \ub9d0\uc5d0 \ub530\ub974\uba74 \uc77c\ubc18\uc801\uc778 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \uacbd\uc6b0 gzip \uc555\ucd95\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc9c0\ub9cc, MSA \ud658\uacbd + \ub370\uc774\ud130 \uc13c\ud130\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \uc624\uc9c1 \ub2e4\ub978 MSA \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uacfc \ud1b5\uc2e0\ud558\uace0, \uace0\uc131\ub2a5 \ub124\ud2b8\uc6cc\ud06c\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0 CPU \ubd80\ud558\ub97c \uc904\uc774\ub294 \uac83\uc774 \uc6b0\uc120\uc2dc \ub420 \uc218\ub3c4 \uc788\ub2e4\ub294 \uac83\uc774\uc5c8\ub2e4. "),(0,r.kt)("p",null,"\uc774\uc678\uc5d0\ub3c4 \uc758\ub3c4\ud558\uc9c0 \uc54a\uc740 \uce90\uc2f1\uc744 \ub9c9\uae30 \uc704\ud574 \ud734\ub9ac\uc2a4\ud2f1 \uce90\uc2f1\uc744 \uc81c\uac70\ud558\uac70\ub098, \uac1c\uc778 \uc815\ubcf4 \uc720\ucd9c\uc744 \ub9c9\uae30 \uc704\ud574 \uc751\ub2f5 \ud5e4\ub354\uc5d0 private\uc744 \uc124\uc815, ETag\ub3c4 \ud559\uc2b5\ud588\ub2e4. "),(0,r.kt)("admonition",{title:"ETag",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"ETag HTTP \uc751\ub2f5 \ud5e4\ub354\ub294 \ud2b9\uc815 \ubc84\uc804\uc758 \ub9ac\uc18c\uc2a4\ub97c \uc2dd\ubcc4\ud558\ub294 \uc2dd\ubcc4\uc790\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc6f9 \uc11c\ubc84\uac00 \ub0b4\uc6a9\uc744 \ud655\uc778\ud558\uace0 \ubcc0\ud558\uc9c0 \uc54a\uc558\uc73c\uba74, \uc6f9 \uc11c\ubc84\ub85c full \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0, \uce90\uc2dc\uac00 \ub354 \ud6a8\uc728\uc801\uc774\uac8c \ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MDN")),(0,r.kt)("h3",{id:"thread-\uc218\uc5c5"},"Thread \uc218\uc5c5"),(0,r.kt)("p",null,"\uc2a4\ub808\ub4dc\uc5d0 \ub300\ud55c \uc218\uc5c5\uc744 \ub4e4\uc5c8\uc9c0\ub9cc, \ubcf5\uc7a1\ud55c \ub0b4\uc6a9\ub3c4 \uc6cc\ub099 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0 \uc124\uba85\ud558\ub77c\uace0 \ud558\uba74 \uc798 \ubabb\ud560 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud604\uc7ac \ud504\ub85c\uc81d\ud2b8, \ubbf8\uc158, \ud14c\ucf54\ud1a1 \uc900\ube44\ub97c \ubcd1\ud589\ud574\uc57c \ud574\uc11c \uc138\ubd80\uc801\uc778 \ub0b4\uc6a9\uc740 \uc2dc\uac04 \ub0a0 \ub54c \ubcf5\uc2b5\ud558\ub824\uace0 \ud55c\ub2e4. "),(0,r.kt)("p",null,"\uc2a4\ub808\ub4dc\ub97c \uc774\ud574\ud558\uace0, WAS\uc5d0 \uc2a4\ub808\ub4dc \uc124\uc815 \uad00\ub828\ud55c \uc2e4\uc2b5\uc774 \uc788\uc5c8\ub294\ub370 \ud14c\uc624\uc640 \uac19\uc774 1\uc2dc\uac04 \uc815\ub3c4 \ud398\uc5b4\ub85c Thread \uc2e4\uc2b5\uc744 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud559\uc2b5\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"threads.max"),": Tomcat\uc758 \ucd5c\ub300 \uc2a4\ub808\ub4dc \uac1c\uc218",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"max-connections"),": Tomcat\uc774 \uc720\uc9c0\ud560 \uc218 \uc788\ub294 \ucd5c\ub300 \ucee4\ub125\uc158 \uac1c\uc218",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"accept-count"),": \ucd5c\ub300 \uc5f0\uacb0 \uc218\uc5d0 \ub3c4\ub2ec\ud588\uc744 \ub54c \uc5f0\uacb0 \uc694\uccad\uc5d0 \ub300\ud574 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub300\uae30\uc5f4\uc758 \ucd5c\ub300 \uae38\uc774. \ud574\ub2f9 Queue\uc5d0 \uc694\uccad\uc774 \uc313\uc774\ub294 \uac83\uc740 Tomcat\uc774 \ub354 \uc774\uc0c1 \uc694\uccad\uc744 \ubc1b\uc744 \uc218 \uc5c6\ub2e4\ub294 \ub73b\uc774\ub2e4. accpet-count queue\uc5d0\ub3c4 \uc694\uccad\uc774 \uac00\ub4dd\ucc28\uba74 \uadf8 \uc774\ud6c4\uc5d0 \uc624\ub294 \uc694\uccad\uc740 \uac70\ubd80\ub41c\ub2e4. "),(0,r.kt)("mermaid",{value:'graph LR\n C("Client") -- request --\x3e ACQ("\uc6b4\uc601\uccb4\uc81c\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue \n size = accept-count") --\x3e TCQ("Tomcat Connector\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue\n size = max-connections") --\x3e TP("Thread Pool\n size = threads.max")'}),(0,r.kt)("h3",{id:"\ub9c8\uce58\uba70"},"\ub9c8\uce58\uba70"),(0,r.kt)("p",null,"\uc2dc\uac04\uc740 \ub108\ubb34 \ube60\ub974\uac8c \uac00\uace0 \ud560 \uc77c\uc740 \ub9ce\uc740 \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc6b0\uc120\uc21c\uc704\ub97c \uc798 \uc815\ud558\uace0 \ud559\uc2b5\uc744 \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud604\uc7ac \ub370\uc774\ud130 \ub2e4\ub8e8\ub294 \ubd80\ubd84(DB)\uc5d0 \ub300\ud55c \ud559\uc2b5\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\ub2e4. \ud574\ub2f9 \ubd80\ubd84\uc740 \ud14c\ucf54\ud1a1\uc774 \ub05d\ub098\ub294\ub300\ub85c \ucc44\uc6cc\uc57c\uaca0\ub2e4. "),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc2616/"},"RFC 2616"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/ETag"},"ETag, mdn"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://tomcat.apache.org/tomcat-8.5-doc/config/http.html"},"Apache Tomcat 8 Configuration Reference"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://bcho.tistory.com/788"},"Apache Tomcat Tuning, Terry Cho"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev-ws.tistory.com/96"},"maxThreads, maxConnections, acceptCount\ub85c Tomcat \ud29c\ub2dd\ud558\uae30")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a7bd4aaa.d10943b8.js b/assets/js/a7bd4aaa.d10943b8.js new file mode 100644 index 000000000..2fb3cfe98 --- /dev/null +++ b/assets/js/a7bd4aaa.d10943b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8518],{8564:(e,n,s)=>{s.r(n),s.d(n,{default:()=>d});s(67294);var r=s(10833),o=s(43320),t=s(74477),i=s(18790),c=s(90197),u=s(85893);function a(e){const{version:n}=e;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(c.Z,{version:n.version,tag:(0,o.os)(n.pluginId,n.version)}),(0,u.jsx)(r.d,{children:n.noIndex&&(0,u.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function l(e){const{version:n,route:s}=e;return(0,u.jsx)(r.FG,{className:n.className,children:(0,u.jsx)(t.q,{version:n,children:(0,i.H)(s.routes)})})}function d(e){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{...e}),(0,u.jsx)(l,{...e})]})}}}]); \ No newline at end of file diff --git a/assets/js/a7e0d18f.d72749dc.js b/assets/js/a7e0d18f.ae8780eb.js similarity index 92% rename from assets/js/a7e0d18f.d72749dc.js rename to assets/js/a7e0d18f.ae8780eb.js index 259dcc3cb..f6367650f 100644 --- a/assets/js/a7e0d18f.d72749dc.js +++ b/assets/js/a7e0d18f.ae8780eb.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3519],{59462:s=>{s.exports=JSON.parse('{"label":"spring","permalink":"/docs/tags/spring","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","title":"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","description":"\uc2a4\ud504\ub9c1\uc758 \ud575\uc2ec \uac1c\ubc1c\uc790\ub4e4\uc774 \uc4f4 Professional Spring Framework \ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc758 \uc815\uc218(essence)\ub294 \\"\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\ub294 \uac83\\" \uc774\ub77c\uace0 \ud588\ub2e4.","permalink":"/docs/spring/essence"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3519],{59462:s=>{s.exports=JSON.parse('{"label":"spring","permalink":"/docs/tags/spring","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","title":"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","description":"\uc2a4\ud504\ub9c1\uc758 \ud575\uc2ec \uac1c\ubc1c\uc790\ub4e4\uc774 \uc4f4 Professional Spring Framework \ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc758 \uc815\uc218(essence)\ub294 \\"\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\ub294 \uac83\\" \uc774\ub77c\uace0 \ud588\ub2e4.","permalink":"/docs/spring/essence"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a85e626a.14258449.js b/assets/js/a85e626a.4cd274c5.js similarity index 88% rename from assets/js/a85e626a.14258449.js rename to assets/js/a85e626a.4cd274c5.js index 856a75322..b05e43c2b 100644 --- a/assets/js/a85e626a.14258449.js +++ b/assets/js/a85e626a.4cd274c5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9092],{48458:e=>{e.exports=JSON.parse('{"label":"JDBC","permalink":"/tags/jdbc","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9092],{48458:e=>{e.exports=JSON.parse('{"label":"JDBC","permalink":"/tags/jdbc","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a896be03.193fe0aa.js b/assets/js/a896be03.8424c86d.js similarity index 77% rename from assets/js/a896be03.193fe0aa.js rename to assets/js/a896be03.8424c86d.js index b6884e4d4..9bc5ce917 100644 --- a/assets/js/a896be03.193fe0aa.js +++ b/assets/js/a896be03.8424c86d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2526],{64030:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2526],{64030:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a8cba70f.18be7e46.js b/assets/js/a8cba70f.18be7e46.js new file mode 100644 index 000000000..8eabafdf5 --- /dev/null +++ b/assets/js/a8cba70f.18be7e46.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2261],{58367:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>o,contentTitle:()=>i,default:()=>p,frontMatter:()=>l,metadata:()=>c,toc:()=>j});var t=n(85893),s=n(3905);const l={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",slug:"woowacourse-level1-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,c={permalink:"/woowacourse-level1-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",description:"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.",date:"2023-04-01T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 1\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.48,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",slug:"woowacourse-level1-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",permalink:"/custom-jdbc-template"},nextItem:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",permalink:"/chess-retrospective"}},o={authorsImageUrls:[]},j=[{value:"Keep",id:"keep",level:3},{value:"Problem",id:"problem",level:3},{value:"Try",id:"try",level:3},{value:"\ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70",id:"\ub808\ubca8-1\uc744-\ub9c8\ubb34\ub9ac\ud558\uba70",level:3}];function a(e){const r={br:"br",code:"code",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(r.p,{children:["\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6b0\ud14c\ucf54\ub97c \uc2dc\uc791\ud558\uae30 \uc804 \ub0b4\uac00 \uc815\ud574\ub450\uc5c8\ub358 \ubaa9\ud45c \uc774\uc0c1\uc73c\ub85c \ub2ec\uc131\ud588\uae30 \ub54c\ubb38\uc5d0 \ub9e4\uc6b0 \ub9cc\uc871\uc2a4\ub7fd\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud63c\uc790 \ub3c5\ud559\uc744 \ud560 \ub550 \uc774 \ubc29\ud5a5\uc73c\ub85c \uacf5\ubd80\ud558\ub294 \uac8c \ub9de\ub294\uc9c0 \uacc4\uc18d \ubc18\ucd94\ud558\ub2e4 \uacb0\uad6d \ubb34\uae30\ub825\ud568\uc5d0 \ube60\uc838\ub4e4\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\uc9c0\ub9cc \uc774\uc81c\ub294 \uac19\uc774 \uacf5\ubd80\ud560 \uc0ac\ub78c\ub3c4 \uc788\uace0, \uc774\uc57c\uae30\ud560 \uc0ac\ub78c\ub3c4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc990\uae30\ub294 \uc77c\ub9cc \ub0a8\uc740 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"keep",children:"Keep"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ub098\ub9cc\uc758 \ub8e8\ud2f4 \ub9cc\ub4e4\uae30"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc2a4\uc2a4\ub85c\uac00 \uc678\ubd80\uc758 \uc601\ud5a5\uc744 \ub9ce\uc774 \ubc1b\ub294\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucd5c\ub300\ud55c \uafb8\uc900\ud788 \ud560 \uc218 \uc788\ub294 \uc2dc\uac04\uc744 \ub9cc\ub4dc\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ub9e4\uc77c 8\uc2dc\uc5d0 \ub3c4\ucc29\ud558\uc5ec \uc544\uce68\uc5d0 \ud574\uc57c \ud560 \uc77c\uc744 \uc815\ub9ac\ud558\uac70\ub098, \uc6b0\uc120\uc21c\uc704\uc5d0 \ub530\ub77c \ucc98\ub9ac\ud558\uace0",(0,t.jsx)(r.br,{}),"\n","\uc18c\ud654\ub2a5\ub825\uc774 \ubd80\uc871\ud558\uae30 \ub54c\ubb38\uc5d0 \uc810\uc2ec\uc740 \ub3c4\uc2dc\ub77d(\uadf8\ub798\ubd24\uc790 \uacc4\ub7802\uac1c)\uc744 \uc900\ube44\ud558\uace0",(0,t.jsx)(r.br,{}),"\n","\ud56d\uc0c1 \ub611\uac19\uc740 \ucee8\ub514\uc158\uc744 \uc720\uc9c0\ud558\uae30 \uc704\ud574 \ud56d\uc0c1 6\uc2dc\uc5d0 \uc9d1\uc5d0 \uac04\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\uc81c \ubc14\ube60\uc9c8 \ud14c\ub2c8 \uc77c\ucc0d \uc9d1\uc5d0 \uac00\ub294 \uc77c\uc740 \uc5b4\uca54 \uc218 \uc5c6\uc774 \uc904\uc5b4\ub4e4\uaca0\uc9c0\ub9cc\ud83d\ude22"]}),"\n",(0,t.jsx)(r.p,{children:"\uc120\ud0dd\ub3c4 \ube44\uc6a9\uc774\ub2e4. \uc55e\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\uc774 \ud544\uc694 \uc5c6\ub294 \ubd80\ubd84\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\ub4e4\uc5b4\uc57c\uaca0\ub2e4."}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uae30"})}),"\n",(0,t.jsxs)(r.p,{children:["10\uba85 \uc815\ub3c4\uc758 \ud06c\ub8e8\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b0\uace0 \uce5c\ud558\uac8c \uc9c0\ub0b8\ub2e4\uba74 \uc131\uacf5\uc801\uc774\ub77c\uace0 \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\ub2e4 \ubcf4\ub2c8 \ub354 \ub9ce\uc740 \ud06c\ub8e8\ub4e4\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b4 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c\ub3c4 \ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uace0 \uc544\ubb34 \ub54c\ub098 \ub9d0\uc744 \uac78 \uc218 \uc788\ub294 \ud06c\ub8e8\uac00 \ub298\uc5b4\ub098\uae38 :)"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uae00\uc4f0\uae30"})}),"\n",(0,t.jsxs)(r.p,{children:["\uae00\uc744 \uc798 \uc4f0\ub294 \ud3b8\uc740 \uc544\ub2c8\uc9c0\ub9cc \uafb8\uc900\ud788 \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub9e4 \ubbf8\uc158\ub9c8\ub2e4 \ud68c\uace0\ub97c \uc791\uc131\ud558\ub2c8 \uc0dd\uac01\ub3c4 \uc815\ub9ac\ub418\uace0 \uac1c\uc120\uc810\ub3c4 \ucc3e\uc744 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc5d0\ub294 \ub808\ubca8\ub9c8\ub2e4 \uae00\uc4f0\uae30\ub97c \uc9c4\ud589\ud558\ub294\ub370, \uc6b4\uc774 \uc88b\uac8c \uae00\uc4f0\uae30 \uc0c1\uc744 \ubc1b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc0ac\uc2e4 \uac89\uc73c\ub85c \ub4dc\ub7ec\ub0b4\uc9c0 \uc54a\uc558\uc9c0\ub9cc \uaf2d \ubc1b\uc544\ubcf4\uace0 \uc2f6\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uae00\uc4f0\uae30 \uc870\uc6d0, \ud22c\ud45c\ud574 \uc900 \ud06c\ub8e8\ub4e4\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514"})}),"\n",(0,t.jsxs)(r.p,{children:["\ub204\ub204, \uc8fc\ub178, \ub2e4\uc990, \ub9d0\ub791, \ubc15\uc2a4\ud130, \uc624\uc789, \uae43\uc9f1\uc640 \ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514\ub97c \uc9c4\ud589\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uacfc\uc5f0 \ub3c4\uc6c0\uc774 \ub420\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud558\uba74\uc11c \uc131\uc7a5\uc744 \ub9ce\uc774 \ud55c \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud22c\uc790\ud55c \uc2dc\uac04 \ub300\ube44 \uac00\uc131\ube44\uac00 \uc88b\uc740 \ud65c\ub3d9\uc774\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub204\ub204\uac00 \uc2a4\ud130\ub514\uc7a5\uc778\ub370 \uacfc\uc5f0 \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00\ub824\ub098?"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ub808\ubca8 \uc778\ud130\ubdf0"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc778\ud130\ubdf0\ud560 \ub54c \ub9ce\uc774 \ub5a8\uc9c0 \uc54a\uc544\uc11c \uc88b\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub0a8\ub4e4 \uc55e\uc5d0\uc11c \uc774\uc57c\uae30\ub97c \ud558\uac70\ub098, \uba74\uc811\uc744 \ubcf4\uba74 \ud56d\uc0c1 \uc5c4\uccad \ub5a8\uc5b4\uc11c \uac71\uc815\ud588\ub294\ub370",(0,t.jsx)(r.br,{}),"\n","\uae30\uc220\uc801\uc778 \uc9c8\ubb38\uc744 \ubc1b\uc558\uc744 \ub54c \ub5a8\uc9c0 \uc54a\uace0 \uc798 \ub300\ub2f5\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \ub2e4\ub978 \ud06c\ub8e8\uac00 \uc9c8\ubb38\ud588\uc744 \ub54c, \ucd5c\ub300\ud55c \uc774\ud574\ud558\uae30 \uc27d\uac8c \uc124\uba85\ud558\ub824\uace0 \ud588\ub358 \uacbd\ud5d8\uc774 \ub3c4\uc6c0\uc774 \ub41c \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\ud6c4 \ub808\ubca8 \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc740 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:"\ub300\ub2f5\ud558\uba74\uc11c \uc9c8\ubb38\uc744 \uacc4\uc18d \uc0dd\uac01\ud558\uba70 \uc78a\uc5b4\ubc84\ub9ac\uc9c0 \ub9d0\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\ub450\uad04\uc2dd \ud45c\ud604"}),"\n",(0,t.jsx)(r.li,{children:"\uc124\uba85\ud558\ub2e4\uac00 \uc798\ubabb \uc124\uba85\ud55c \uac83 \uac19\uc73c\uba74 \ub2e4 \ub04a\uace0 \ub2e4\uc2dc \uc774\uc57c\uae30\ud574\ub3c4 \ub420\uc9c0 \ubb3c\uc5b4\ubcf4\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\uc124\uba85\ud560 \uc218 \uc788\uc744\ub9cc\ud07c \uc2dc\uac04 \ucda9\ubd84\ud788 \uac00\uc9c0\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\uc778\ud130\ubdf0\uc5b4\uc758 \uc9c8\ubb38 \uc758\ub3c4\ub97c \uba85\ud655\ud788 \uc774\ud574\ud558\uc9c0 \ubabb\ud588\ub2e4\uba74 \uc758\ub3c4 \ub2e4\uc2dc \ubb3c\uc5b4\ubcf4\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\ub05d\ub9fa\ub294 \ubd80\ubd84 \uc5f0\uc2b5\ud558\uae30(\uc790\uc2e0\uac10 \uc788\uac8c)"}),"\n",(0,t.jsx)(r.li,{children:"\uae30\uc220\uc801\uc778 \uc9d1\ucc29\uac00\uc9c0\uae30"}),"\n",(0,t.jsx)(r.li,{children:"\uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud788 \uc900\ube44\ud588\uc73c\uba74 \ud611\uc5c5 \uad00\ub828 \uc9c8\ubb38\ub3c4 \uc900\ube44\ud558\uae30"}),"\n"]}),"\n",(0,t.jsx)(r.h3,{id:"problem",children:"Problem"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uac00\uc7a5 \uc5b4\ub824\uc6b4 \ud65c\ub3d9 \uc911 \ud558\ub098\ub77c\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud398\uc5b4\ub294 \ub9e4\ubc88 \ubc14\ub00c\uace0, \ubbf8\uc158\uc758 \ubcf5\uc7a1\ub3c4\ub3c4 \uc99d\uac00\ud558\uae30 \ub54c\ubb38\uc778 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc18c\ud1b5 \ub2a5\ub825, \uc2dc\uac04\uad00\ub9ac\uac00 \ubd80\uc871\ud588\uace0, \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\uc9c0\ub9cc \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uace0, \ud68c\uace0\ub97c \ud558\ub2e4 \ubcf4\ub2c8 \ub098\ub9cc\uc758 \ub178\ud558\uc6b0\uac00 \uc313\uc774\ub294 \ub290\ub08c\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub808\ubca8 2\uc5d0\uc11c\ub294 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc120\ud558\uc5ec \ud568\uaed8\ud558\uace0 \uc2f6\uc740 \ud398\uc5b4\uac00 \ub418\uace0 \uc2f6\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uc9d1\uc911\ud558\ub294 \uc2dc\uac04\u23f1\ufe0f \ubd80\uc871"})}),"\n",(0,t.jsxs)(r.p,{children:["\ub808\ubca8 1\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc9d1\uc911\ud558\ub294 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\ub978 \uc544\uce68\uacfc \uc624\ud6c4\uc5d0 \uac1c\uc778\uc801\uc73c\ub85c \uc9d1\uc911\ud560 \uc218 \uc788\ub294 \uacf5\uac04\uc744 \uc608\uc57d\ud574\uc11c \uc628\uc804\ud788 \ub098\ub9cc\uc758 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"try",children:"Try"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ud5c8\ube0c\ud83c\udf3f\uc640\uc758 \ud2f0\ud0c0\uc784?"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc744 \ub298\ub9b4 \ubc29\ubc95\uc744 \uc0dd\uac01\ud558\ub2e4\uac00 \ub300\ud654\ub97c \ub098\ub204\uc9c0 \ubabb\ud55c \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \uae5c\uc9dd \ucee4\ud53c\ucc57\uc744 \ud558\uba74 \uc5b4\ub5a8\uae4c \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc608\ub97c \ub4e4\uc5b4 \uc7a1\ub2f4\ubc29\uc5d0 ",(0,t.jsx)(r.code,{children:"\uc800\uc640 \ucee4\ud53c\ucc57 \ud558\uc2e4 \ubd84 :)"})," \ud558\uba74\uc11c \uc62c\ub9b4 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucc38\uc5ec\ud558\ub294 \uc0ac\ub78c\uc774 \uc788\uc744\uc9c0, \uc548 \uc88b\uac8c \ubcf4\ub294 \uac8c \uc544\ub2d0\uc9c0 \uac71\uc815\ub418\uc9c0\ub9cc \uadf8\ub798\ub3c4 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc800\ub791 \ud5c8\ube0c\ud2f0 \ud55c\uc794 \ud558\uc2e4\ub798\uc694?"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uae30\uc220\uc801\uc778 \ubd80\ubd84"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc5d0 \uc870\uae08 \ub354 \ubb34\uac8c\ub97c \ub450\ub2e4 \ubcf4\ub2c8 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc774 \ubd80\uc871\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc2dc\uac04\uc758 \uc5ec\uc720\uac00 \ub420 \ub54c \ucc45\uc744 \uc870\uae08\uc529 \uc77d\uc5b4\uc57c\uaca0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ube14\ub85c\uadf8\uc5d0 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \ub9ce\uc774 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\ub294 \uc2dc\uac04\ub3c4 \uac00\uc838\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ub808\ubca8-1\uc744-\ub9c8\ubb34\ub9ac\ud558\uba70",children:"\ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70"}),"\n",(0,t.jsxs)(r.p,{children:["\uc2dc\uac04\uc774 \ube60\ub974\uac8c \ud758\ub7ec\uac14\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud0c0\uc778\uc5d0\uac8c \uc88b\uc740 \uc601\ud5a5\uc744 \uc8fc\uae30\uc704\ud574, \ubc29\ud559\ub3d9\uc548 \ub098\ub97c \ucc59\uae30\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub610\ud55c \ud568\uaed8 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc744 \ubaa9\ud45c\ub85c \uc55e\uc73c\ub85c\ub3c4 \uafb8\uc900\ud788 \uc758\uc2dd\uc801 \ub178\ub825\uc744 \ud574\uc57c\uaca0\ub2e4."]})]})}function p(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>j});var t=n(67294);function s(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function l(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function i(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?l(Object(n),!0).forEach((function(r){s(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function c(e,r){if(null==e)return{};var n,t,s=function(e,r){if(null==e)return{};var n,t,s={},l=Object.keys(e);for(t=0;t<l.length;t++)n=l[t],r.indexOf(n)>=0||(s[n]=e[n]);return s}(e,r);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(t=0;t<l.length;t++)n=l[t],r.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var o=t.createContext({}),j=function(e){var r=t.useContext(o),n=r;return e&&(n="function"==typeof e?e(r):i(i({},r),e)),n},a={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},p=t.forwardRef((function(e,r){var n=e.components,s=e.mdxType,l=e.originalType,o=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),x=j(n),d=s,h=x["".concat(o,".").concat(d)]||x[d]||a[d]||l;return n?t.createElement(h,i(i({ref:r},p),{},{components:n})):t.createElement(h,i({ref:r},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/a8cba70f.a8d56601.js b/assets/js/a8cba70f.a8d56601.js deleted file mode 100644 index 804013a72..000000000 --- a/assets/js/a8cba70f.a8d56601.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2261],{3905:(e,t,r)=>{r.d(t,{Zo:()=>i,kt:()=>s});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var m=n.createContext({}),u=function(e){var t=n.useContext(m),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},i=function(e){var t=u(e.components);return n.createElement(m.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,m=e.parentName,i=o(e,["components","mdxType","originalType","parentName"]),k=u(r),s=a,b=k["".concat(m,".").concat(s)]||k[s]||c[s]||p;return r?n.createElement(b,l(l({ref:t},i),{},{components:r})):n.createElement(b,l({ref:t},i))}));function s(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=k;var o={};for(var m in t)hasOwnProperty.call(t,m)&&(o[m]=t[m]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var u=2;u<p;u++)l[u]=r[u];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}k.displayName="MDXCreateElement"},61629:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>m,contentTitle:()=>l,default:()=>c,frontMatter:()=>p,metadata:()=>o,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",slug:"woowacourse-level1-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,o={permalink:"/woowacourse-level1-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",description:"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.",date:"2023-04-01T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 1\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.48,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",slug:"woowacourse-level1-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",permalink:"/custom-jdbc-template"},nextItem:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",permalink:"/chess-retrospective"}},m={authorsImageUrls:[]},u=[{value:"Keep",id:"keep",level:3},{value:"Problem",id:"problem",level:3},{value:"Try",id:"try",level:3},{value:"\ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70",id:"\ub808\ubca8-1\uc744-\ub9c8\ubb34\ub9ac\ud558\uba70",level:3}],i={toc:u};function c(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},i,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ud14c\ucf54\ub97c \uc2dc\uc791\ud558\uae30 \uc804 \ub0b4\uac00 \uc815\ud574\ub450\uc5c8\ub358 \ubaa9\ud45c \uc774\uc0c1\uc73c\ub85c \ub2ec\uc131\ud588\uae30 \ub54c\ubb38\uc5d0 \ub9e4\uc6b0 \ub9cc\uc871\uc2a4\ub7fd\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud63c\uc790 \ub3c5\ud559\uc744 \ud560 \ub550 \uc774 \ubc29\ud5a5\uc73c\ub85c \uacf5\ubd80\ud558\ub294 \uac8c \ub9de\ub294\uc9c0 \uacc4\uc18d \ubc18\ucd94\ud558\ub2e4 \uacb0\uad6d \ubb34\uae30\ub825\ud568\uc5d0 \ube60\uc838\ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uc774\uc81c\ub294 \uac19\uc774 \uacf5\ubd80\ud560 \uc0ac\ub78c\ub3c4 \uc788\uace0, \uc774\uc57c\uae30\ud560 \uc0ac\ub78c\ub3c4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc990\uae30\ub294 \uc77c\ub9cc \ub0a8\uc740 \uac83 \uac19\ub2e4. "),(0,a.kt)("h3",{id:"keep"},"Keep"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub098\ub9cc\uc758 \ub8e8\ud2f4 \ub9cc\ub4e4\uae30")," "),(0,a.kt)("p",null,"\uc2a4\uc2a4\ub85c\uac00 \uc678\ubd80\uc758 \uc601\ud5a5\uc744 \ub9ce\uc774 \ubc1b\ub294\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\ub300\ud55c \uafb8\uc900\ud788 \ud560 \uc218 \uc788\ub294 \uc2dc\uac04\uc744 \ub9cc\ub4dc\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,a.kt)("p",null,"\ub9e4\uc77c 8\uc2dc\uc5d0 \ub3c4\ucc29\ud558\uc5ec \uc544\uce68\uc5d0 \ud574\uc57c \ud560 \uc77c\uc744 \uc815\ub9ac\ud558\uac70\ub098, \uc6b0\uc120\uc21c\uc704\uc5d0 \ub530\ub77c \ucc98\ub9ac\ud558\uace0",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\ud654\ub2a5\ub825\uc774 \ubd80\uc871\ud558\uae30 \ub54c\ubb38\uc5d0 \uc810\uc2ec\uc740 \ub3c4\uc2dc\ub77d(\uadf8\ub798\ubd24\uc790 \uacc4\ub7802\uac1c)\uc744 \uc900\ube44\ud558\uace0",(0,a.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \ub611\uac19\uc740 \ucee8\ub514\uc158\uc744 \uc720\uc9c0\ud558\uae30 \uc704\ud574 \ud56d\uc0c1 6\uc2dc\uc5d0 \uc9d1\uc5d0 \uac04\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc81c \ubc14\ube60\uc9c8 \ud14c\ub2c8 \uc77c\ucc0d \uc9d1\uc5d0 \uac00\ub294 \uc77c\uc740 \uc5b4\uca54 \uc218 \uc5c6\uc774 \uc904\uc5b4\ub4e4\uaca0\uc9c0\ub9cc\ud83d\ude22 "),(0,a.kt)("p",null,"\uc120\ud0dd\ub3c4 \ube44\uc6a9\uc774\ub2e4. \uc55e\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\uc774 \ud544\uc694 \uc5c6\ub294 \ubd80\ubd84\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\ub4e4\uc5b4\uc57c\uaca0\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uae30")," "),(0,a.kt)("p",null,"10\uba85 \uc815\ub3c4\uc758 \ud06c\ub8e8\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b0\uace0 \uce5c\ud558\uac8c \uc9c0\ub0b8\ub2e4\uba74 \uc131\uacf5\uc801\uc774\ub77c\uace0 \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\ub2e4 \ubcf4\ub2c8 \ub354 \ub9ce\uc740 \ud06c\ub8e8\ub4e4\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b4 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c\ub3c4 \ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uace0 \uc544\ubb34 \ub54c\ub098 \ub9d0\uc744 \uac78 \uc218 \uc788\ub294 \ud06c\ub8e8\uac00 \ub298\uc5b4\ub098\uae38 :) "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uae00\uc4f0\uae30")," "),(0,a.kt)("p",null,"\uae00\uc744 \uc798 \uc4f0\ub294 \ud3b8\uc740 \uc544\ub2c8\uc9c0\ub9cc \uafb8\uc900\ud788 \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9e4 \ubbf8\uc158\ub9c8\ub2e4 \ud68c\uace0\ub97c \uc791\uc131\ud558\ub2c8 \uc0dd\uac01\ub3c4 \uc815\ub9ac\ub418\uace0 \uac1c\uc120\uc810\ub3c4 \ucc3e\uc744 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\ub2e4. "),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc5d0\ub294 \ub808\ubca8\ub9c8\ub2e4 \uae00\uc4f0\uae30\ub97c \uc9c4\ud589\ud558\ub294\ub370, \uc6b4\uc774 \uc88b\uac8c \uae00\uc4f0\uae30 \uc0c1\uc744 \ubc1b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc2e4 \uac89\uc73c\ub85c \ub4dc\ub7ec\ub0b4\uc9c0 \uc54a\uc558\uc9c0\ub9cc \uaf2d \ubc1b\uc544\ubcf4\uace0 \uc2f6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae00\uc4f0\uae30 \uc870\uc6d0, \ud22c\ud45c\ud574 \uc900 \ud06c\ub8e8\ub4e4\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514")," "),(0,a.kt)("p",null,"\ub204\ub204, \uc8fc\ub178, \ub2e4\uc990, \ub9d0\ub791, \ubc15\uc2a4\ud130, \uc624\uc789, \uae43\uc9f1\uc640 \ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514\ub97c \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uacfc\uc5f0 \ub3c4\uc6c0\uc774 \ub420\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud558\uba74\uc11c \uc131\uc7a5\uc744 \ub9ce\uc774 \ud55c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud22c\uc790\ud55c \uc2dc\uac04 \ub300\ube44 \uac00\uc131\ube44\uac00 \uc88b\uc740 \ud65c\ub3d9\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub204\ub204\uac00 \uc2a4\ud130\ub514\uc7a5\uc778\ub370 \uacfc\uc5f0 \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00\ub824\ub098? "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub808\ubca8 \uc778\ud130\ubdf0")),(0,a.kt)("p",null,"\uc778\ud130\ubdf0\ud560 \ub54c \ub9ce\uc774 \ub5a8\uc9c0 \uc54a\uc544\uc11c \uc88b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0a8\ub4e4 \uc55e\uc5d0\uc11c \uc774\uc57c\uae30\ub97c \ud558\uac70\ub098, \uba74\uc811\uc744 \ubcf4\uba74 \ud56d\uc0c1 \uc5c4\uccad \ub5a8\uc5b4\uc11c \uac71\uc815\ud588\ub294\ub370",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc220\uc801\uc778 \uc9c8\ubb38\uc744 \ubc1b\uc558\uc744 \ub54c \ub5a8\uc9c0 \uc54a\uace0 \uc798 \ub300\ub2f5\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \ub2e4\ub978 \ud06c\ub8e8\uac00 \uc9c8\ubb38\ud588\uc744 \ub54c, \ucd5c\ub300\ud55c \uc774\ud574\ud558\uae30 \uc27d\uac8c \uc124\uba85\ud558\ub824\uace0 \ud588\ub358 \uacbd\ud5d8\uc774 \ub3c4\uc6c0\uc774 \ub41c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ud6c4 \ub808\ubca8 \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc740 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\ub300\ub2f5\ud558\uba74\uc11c \uc9c8\ubb38\uc744 \uacc4\uc18d \uc0dd\uac01\ud558\uba70 \uc78a\uc5b4\ubc84\ub9ac\uc9c0 \ub9d0\uae30 "),(0,a.kt)("li",{parentName:"ul"},"\ub450\uad04\uc2dd \ud45c\ud604"),(0,a.kt)("li",{parentName:"ul"},"\uc124\uba85\ud558\ub2e4\uac00 \uc798\ubabb \uc124\uba85\ud55c \uac83 \uac19\uc73c\uba74 \ub2e4 \ub04a\uace0 \ub2e4\uc2dc \uc774\uc57c\uae30\ud574\ub3c4 \ub420\uc9c0 \ubb3c\uc5b4\ubcf4\uae30 "),(0,a.kt)("li",{parentName:"ul"},"\uc124\uba85\ud560 \uc218 \uc788\uc744\ub9cc\ud07c \uc2dc\uac04 \ucda9\ubd84\ud788 \uac00\uc9c0\uae30"),(0,a.kt)("li",{parentName:"ul"},"\uc778\ud130\ubdf0\uc5b4\uc758 \uc9c8\ubb38 \uc758\ub3c4\ub97c \uba85\ud655\ud788 \uc774\ud574\ud558\uc9c0 \ubabb\ud588\ub2e4\uba74 \uc758\ub3c4 \ub2e4\uc2dc \ubb3c\uc5b4\ubcf4\uae30"),(0,a.kt)("li",{parentName:"ul"},"\ub05d\ub9fa\ub294 \ubd80\ubd84 \uc5f0\uc2b5\ud558\uae30(\uc790\uc2e0\uac10 \uc788\uac8c)"),(0,a.kt)("li",{parentName:"ul"},"\uae30\uc220\uc801\uc778 \uc9d1\ucc29\uac00\uc9c0\uae30"),(0,a.kt)("li",{parentName:"ul"},"\uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud788 \uc900\ube44\ud588\uc73c\uba74 \ud611\uc5c5 \uad00\ub828 \uc9c8\ubb38\ub3c4 \uc900\ube44\ud558\uae30")),(0,a.kt)("h3",{id:"problem"},"Problem"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d")," "),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uac00\uc7a5 \uc5b4\ub824\uc6b4 \ud65c\ub3d9 \uc911 \ud558\ub098\ub77c\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud398\uc5b4\ub294 \ub9e4\ubc88 \ubc14\ub00c\uace0, \ubbf8\uc158\uc758 \ubcf5\uc7a1\ub3c4\ub3c4 \uc99d\uac00\ud558\uae30 \ub54c\ubb38\uc778 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\ud1b5 \ub2a5\ub825, \uc2dc\uac04\uad00\ub9ac\uac00 \ubd80\uc871\ud588\uace0, \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uace0, \ud68c\uace0\ub97c \ud558\ub2e4 \ubcf4\ub2c8 \ub098\ub9cc\uc758 \ub178\ud558\uc6b0\uac00 \uc313\uc774\ub294 \ub290\ub08c\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 2\uc5d0\uc11c\ub294 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc120\ud558\uc5ec \ud568\uaed8\ud558\uace0 \uc2f6\uc740 \ud398\uc5b4\uac00 \ub418\uace0 \uc2f6\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc9d1\uc911\ud558\ub294 \uc2dc\uac04\u23f1\ufe0f \ubd80\uc871")," "),(0,a.kt)("p",null,"\ub808\ubca8 1\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc9d1\uc911\ud558\ub294 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub978 \uc544\uce68\uacfc \uc624\ud6c4\uc5d0 \uac1c\uc778\uc801\uc73c\ub85c \uc9d1\uc911\ud560 \uc218 \uc788\ub294 \uacf5\uac04\uc744 \uc608\uc57d\ud574\uc11c \uc628\uc804\ud788 \ub098\ub9cc\uc758 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"try"},"Try"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud5c8\ube0c\ud83c\udf3f\uc640\uc758 \ud2f0\ud0c0\uc784?")," "),(0,a.kt)("p",null,"\uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc744 \ub298\ub9b4 \ubc29\ubc95\uc744 \uc0dd\uac01\ud558\ub2e4\uac00 \ub300\ud654\ub97c \ub098\ub204\uc9c0 \ubabb\ud55c \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \uae5c\uc9dd \ucee4\ud53c\ucc57\uc744 \ud558\uba74 \uc5b4\ub5a8\uae4c \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\ub97c \ub4e4\uc5b4 \uc7a1\ub2f4\ubc29\uc5d0 ",(0,a.kt)("inlineCode",{parentName:"p"},"\uc800\uc640 \ucee4\ud53c\ucc57 \ud558\uc2e4 \ubd84 :)")," \ud558\uba74\uc11c \uc62c\ub9b4 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc38\uc5ec\ud558\ub294 \uc0ac\ub78c\uc774 \uc788\uc744\uc9c0, \uc548 \uc88b\uac8c \ubcf4\ub294 \uac8c \uc544\ub2d0\uc9c0 \uac71\uc815\ub418\uc9c0\ub9cc \uadf8\ub798\ub3c4 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc800\ub791 \ud5c8\ube0c\ud2f0 \ud55c\uc794 \ud558\uc2e4\ub798\uc694? "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uae30\uc220\uc801\uc778 \ubd80\ubd84")," "),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc5d0 \uc870\uae08 \ub354 \ubb34\uac8c\ub97c \ub450\ub2e4 \ubcf4\ub2c8 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc774 \ubd80\uc871\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2dc\uac04\uc758 \uc5ec\uc720\uac00 \ub420 \ub54c \ucc45\uc744 \uc870\uae08\uc529 \uc77d\uc5b4\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube14\ub85c\uadf8\uc5d0 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \ub9ce\uc774 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\ub294 \uc2dc\uac04\ub3c4 \uac00\uc838\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\ub808\ubca8-1\uc744-\ub9c8\ubb34\ub9ac\ud558\uba70"},"\ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70"),(0,a.kt)("p",null,"\uc2dc\uac04\uc774 \ube60\ub974\uac8c \ud758\ub7ec\uac14\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud0c0\uc778\uc5d0\uac8c \uc88b\uc740 \uc601\ud5a5\uc744 \uc8fc\uae30\uc704\ud574, \ubc29\ud559\ub3d9\uc548 \ub098\ub97c \ucc59\uae30\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ud568\uaed8 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc744 \ubaa9\ud45c\ub85c \uc55e\uc73c\ub85c\ub3c4 \uafb8\uc900\ud788 \uc758\uc2dd\uc801 \ub178\ub825\uc744 \ud574\uc57c\uaca0\ub2e4."))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/a94703ab.783432bf.js b/assets/js/a94703ab.783432bf.js new file mode 100644 index 000000000..640af7fb2 --- /dev/null +++ b/assets/js/a94703ab.783432bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4368],{12674:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(67294),o=n(86010),i=n(10833),s=n(35281),l=n(53438),r=n(1116),c=n(95999),d=n(12466),u=n(85936);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(85893);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.Ct)();return(0,d.RF)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.S)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.I)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.Z)("clean-btn",s.k.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(91442),x=n(16550),f=n(87524),j=n(86668),k=n(21327);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const v={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.I)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.I)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.Z)("button button--secondary button--outline",v.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:v.collapseSidebarButtonIcon})})}var C=n(59689),S=n(902);const I=Symbol("EmptyContext"),N=a.createContext(I);function T(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(N.Provider,{value:i,children:t})}var B=n(86043),Z=n(48596),y=n(39960),A=n(72389);function L(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.I)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.I)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),type:"button",className:"clean-btn menu__caret",onClick:a})}function w(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.L)(),k=function(e){const t=(0,A.Z)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.LM)(e):void 0),[e,t])}(t),_=(0,l._F)(t,i),v=(0,Z.Mg)(x,i),{collapsed:g,setCollapsed:C}=(0,B.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:T,setExpandedItem:w}=function(){const e=(0,a.useContext)(N);if(e===I)throw new S.i6("DocSidebarItemsExpandedStateProvider");return e}(),E=function(e){void 0===e&&(e=!g),w(e?null:c),C(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,S.D9)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:E}),(0,a.useEffect)((()=>{h&&null!=T&&T!==c&&f&&C(!0)}),[h,T,c,C,f]),(0,b.jsxs)("li",{className:(0,o.Z)(s.k.docs.docSidebarItemCategory,s.k.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.Z)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":v}),children:[(0,b.jsx)(y.Z,{className:(0,o.Z)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?E(!1):(e.preventDefault(),E())}:()=>{n?.(t)},"aria-current":v?"page":void 0,"aria-expanded":h?!g:void 0,href:h?k??"#":k,...d,children:m}),x&&h&&(0,b.jsx)(L,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),E()}})]}),(0,b.jsx)(B.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(V,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var E=n(13919),H=n(39471);const M={menuExternalLink:"menuExternalLink_NmtK"};function R(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l._F)(t,a),x=(0,E.Z)(d);return(0,b.jsx)("li",{className:(0,o.Z)(s.k.docs.docSidebarItemLink,s.k.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.Z,{className:(0,o.Z)("menu__link",!x&&M.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.Z,{})]})},u)}const W={menuHtmlItem:"menuHtmlItem_M9Kj"};function F(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.Z)(s.k.docs.docSidebarItemLink,s.k.docs.docSidebarItemLinkLevel(n),l&&[W.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function P(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(w,{item:t,...n});case"html":return(0,b.jsx)(F,{item:t,...n});default:return(0,b.jsx)(R,{item:t,...n})}}function D(e){let{items:t,...n}=e;const a=(0,l.f)(t,n.activePath);return(0,b.jsx)(T,{children:a.map(((e,t)=>(0,b.jsx)(P,{item:e,index:t,...n},t)))})}const V=(0,a.memo)(D),U={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function K(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,C.nT)(),[t,n]=(0,a.useState)(e);return(0,d.RF)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.I)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.Z)("menu thin-scrollbar",U.menu,l&&U.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.Z)(s.k.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(V,{items:n,activePath:t,level:1})})})}const Y="sidebar_njMd",z="sidebarWithHideableNavbar_wUlq",G="sidebarHidden_VK0M",O="sidebarLogo_isFc";function q(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.L)();return(0,b.jsxs)("div",{className:(0,o.Z)(Y,s&&z,i&&G),children:[s&&(0,b.jsx)(k.Z,{tabIndex:-1,className:O}),(0,b.jsx)(K,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const J=a.memo(q);var Q=n(13102),X=n(93163);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,X.e)();return(0,b.jsx)("ul",{className:(0,o.Z)(s.k.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(V,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(Q.Zo,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.i)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(J,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.I)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.I)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.V)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.TH)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.n)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.Z)(s.k.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.Z)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.V)();return(0,b.jsx)("main",{className:(0,o.Z)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.Z)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.V)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(5658);function be(e){const t=(0,l.SN)(e);if(!t)return(0,b.jsx)(me.Z,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.FG,{className:(0,o.Z)(s.k.page.docsDocPage),children:(0,b.jsx)(r.b,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},5658:(e,t,n)=>{n.d(t,{Z:()=>l});n(67294);var a=n(86010),o=n(95999),i=n(92503),s=n(85893);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.Z)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.Z,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.Z,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.Z,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.Z,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/aa73a035.5245d1dd.js b/assets/js/aa73a035.5245d1dd.js deleted file mode 100644 index 6c7abf913..000000000 --- a/assets/js/aa73a035.5245d1dd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5371],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>d});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},s=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,u=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),s=c(n),d=o,f=s["".concat(u,".").concat(d)]||s[d]||p[d]||a;return n?r.createElement(f,i(i({ref:t},m),{},{components:n})):r.createElement(f,i({ref:t},m))}));function d(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=s;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c<a;c++)i[c]=n[c];return r.createElement.apply(null,i)}return r.createElement.apply(null,n)}s.displayName="MDXCreateElement"},17231:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var r=n(87462),o=(n(67294),n(3905));const a={title:"maximumPoolSize",slug:"/database/maximumPoolSize",last_update:{date:"2023/10/17"},tag:["mysql","maximumPoolSize"]},i=void 0,l={unversionedId:"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool",id:"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool",title:"maximumPoolSize",description:"maximumPoolSize",source:"@site/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool.mdx",sourceDirName:"\ub370\uc774\ud130\ubca0\uc774\uc2a4",slug:"/database/maximumPoolSize",permalink:"/docs/database/maximumPoolSize",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool.mdx",tags:[],version:"current",lastUpdatedAt:1697500800,formattedLastUpdatedAt:"2023\ub144 10\uc6d4 17\uc77c",frontMatter:{title:"maximumPoolSize",slug:"/database/maximumPoolSize",last_update:{date:"2023/10/17"},tag:["mysql","maximumPoolSize"]},sidebar:"tutorialSidebar",previous:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",permalink:"/docs/network/load-balancing"},next:{title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",permalink:"/docs/database/query-execution"}},u={},c=[{value:"maximumPoolSize",id:"maximumpoolsize",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],m={toc:c};function p(e){let{components:t,...n}=e;return(0,o.kt)("wrapper",(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"maximumpoolsize"},"maximumPoolSize"),(0,o.kt)("p",null,"\ucee4\ub125\uc158 \ud480\uc774 \ub3c4\ub2ec\ud560 \uc218 \uc788\ub294 \ucd5c\ub300 \ud06c\uae30 "),(0,o.kt)("p",null,"HikariCP \uacf5\uc2dd \ubb38\uc11c\uc5d0\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uacf5\uc2dd\uc73c\ub85c \uc18c\uac1c\ud558\uace0 \uc788\ub2e4. "),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"connections = ((core_count * 2) + effective_spindle_count)")),(0,o.kt)("p",null,"core count\uc758 \uacbd\uc6b0 \ud558\uc774\ud37c\uc2a4\ub808\ub529\uc744 \uc81c\uc678\ud55c CPU \ucf54\uc5b4 \uc218\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","effective spindle count\uc758 \uacbd\uc6b0 \ud558\ub4dc\ub514\uc2a4\ud06c\uc640 \uad00\ub828\uc774 \uc788\ub2e4. \ud55c \uac1c\uc758 \ud558\ub4dc\ub514\uc2a4\ud06c\ub294 \ud558\ub098\uc758 spindle\uc744 \uac00\uc9c4\ub2e4. "),(0,o.kt)("p",null,"2\uac1c\uc758 \ucf54\uc5b4\ub97c \uac00\uc9c0\uace0 \uc788\ub294 t4g.small\uc758 \uacbd\uc6b0 \ud574\ub2f9 \uacf5\uc2dd\uc744 \uc801\uc6a9\ud558\uba74 (2 * 2) + 1\uc774 \ub41c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uacf5\uc2dd\uc774 SSD\ub97c \uc0ac\uc6a9\ud574\ub3c4 \uc798 \uc801\uc6a9\ud558\ub294\uc9c0\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \uc5c6\uc5c8\uc9c0\ub9cc, \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd\uc5d0\uc11c\ub294 \ud574\ub2f9 \uacf5\uc2dd\uc774 \uc798 \uc801\uc6a9\ub41c \uac83 \uac19\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\ub294\ub370 \uc2dc\uac04\uc774 \ub9ce\uc774 \uac78\ub9ac\ub294 \uacbd\uc6b0 \uc0c1\ud669\uc5d0 \ub530\ub77c\uc11c \ud480 \uc0ac\uc774\uc988\ub97c \ub298\ub9b4 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."),(0,o.kt)("p",null,"\ub9cc\uc57d \ud558\ub098\uc758 \uc2a4\ub808\ub4dc\uac00 \uc5ec\ub7ec \uac1c\uc758 \ucee4\ub125\uc158\uc744 \ub4e4\uace0 \uc788\ub294 \uacbd\uc6b0 \ub370\ub4dc\ub77d\uc774 \ubb38\uc81c\uac00 \ub420 \uc218 \uc788\ub294\ub370 \uc774\ub97c \ubc29\uc9c0\ud558\ub824\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uacf5\uc2dd\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. "),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"pool size = Tn x (Cm - 1) + 1")),(0,o.kt)("p",null,"Tn\uc740 \ucf54\uc5b4 \uc218, Cm\uc758 \uacbd\uc6b0 \ub2e8\uc77c \uc694\uccad\uc774 \uc0ac\uc6a9\ud558\ub294 \ucd5c\ub300 \ub3d9\uc2dc \uc5f0\uacb0 \uc218\ub2e4. "),(0,o.kt)("p",null,"\uacf5\uc2dd\uc774 \uc874\uc7ac\ud558\uc9c0\ub9cc \uacb0\uad6d \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \uc791\ub3d9\ud558\ub294 \ubc29\uc2dd\uc5d0 \ub530\ub77c \uc801\ud569\ud55c pool size\uac00 \uc874\uc7ac\ud558\ub2c8 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc131\uaca9\uc774\ub098, \uc131\ub2a5 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud574 \uc801\ud569\ud55c \uc0ac\uc774\uc988\ub97c \uc124\uc815\ud558\ub294 \uac83\uc774 \uc801\ud569\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/brettwooldridge/HikariCP"},"https://github.com/brettwooldridge/HikariCP")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/aa73a035.e69b92cb.js b/assets/js/aa73a035.e69b92cb.js new file mode 100644 index 000000000..0b2906637 --- /dev/null +++ b/assets/js/aa73a035.e69b92cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5371],{54717:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var r=n(85893),o=n(3905);const i={title:"maximumPoolSize",slug:"/database/maximumPoolSize",last_update:{date:"2023/10/17"},tag:["mysql","maximumPoolSize"]},a=void 0,l={id:"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool",title:"maximumPoolSize",description:"maximumPoolSize",source:"@site/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool.mdx",sourceDirName:"\ub370\uc774\ud130\ubca0\uc774\uc2a4",slug:"/database/maximumPoolSize",permalink:"/docs/database/maximumPoolSize",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool.mdx",tags:[],version:"current",lastUpdatedAt:1697500800,formattedLastUpdatedAt:"2023\ub144 10\uc6d4 17\uc77c",frontMatter:{title:"maximumPoolSize",slug:"/database/maximumPoolSize",last_update:{date:"2023/10/17"},tag:["mysql","maximumPoolSize"]},sidebar:"tutorialSidebar",previous:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",permalink:"/docs/network/load-balancing"},next:{title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",permalink:"/docs/database/query-execution"}},c={},s=[{value:"maximumPoolSize",id:"maximumpoolsize",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function m(e){const t={a:"a",blockquote:"blockquote",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"maximumpoolsize",children:"maximumPoolSize"}),"\n",(0,r.jsx)(t.p,{children:"\ucee4\ub125\uc158 \ud480\uc774 \ub3c4\ub2ec\ud560 \uc218 \uc788\ub294 \ucd5c\ub300 \ud06c\uae30"}),"\n",(0,r.jsx)(t.p,{children:"HikariCP \uacf5\uc2dd \ubb38\uc11c\uc5d0\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uacf5\uc2dd\uc73c\ub85c \uc18c\uac1c\ud558\uace0 \uc788\ub2e4."}),"\n",(0,r.jsxs)(t.blockquote,{children:["\n",(0,r.jsx)(t.p,{children:"connections = ((core_count * 2) + effective_spindle_count)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["core count\uc758 \uacbd\uc6b0 \ud558\uc774\ud37c\uc2a4\ub808\ub529\uc744 \uc81c\uc678\ud55c CPU \ucf54\uc5b4 \uc218\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","effective spindle count\uc758 \uacbd\uc6b0 \ud558\ub4dc\ub514\uc2a4\ud06c\uc640 \uad00\ub828\uc774 \uc788\ub2e4. \ud55c \uac1c\uc758 \ud558\ub4dc\ub514\uc2a4\ud06c\ub294 \ud558\ub098\uc758 spindle\uc744 \uac00\uc9c4\ub2e4."]}),"\n",(0,r.jsxs)(t.p,{children:["2\uac1c\uc758 \ucf54\uc5b4\ub97c \uac00\uc9c0\uace0 \uc788\ub294 t4g.small\uc758 \uacbd\uc6b0 \ud574\ub2f9 \uacf5\uc2dd\uc744 \uc801\uc6a9\ud558\uba74 (2 * 2) + 1\uc774 \ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud574\ub2f9 \uacf5\uc2dd\uc774 SSD\ub97c \uc0ac\uc6a9\ud574\ub3c4 \uc798 \uc801\uc6a9\ud558\ub294\uc9c0\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \uc5c6\uc5c8\uc9c0\ub9cc, \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd\uc5d0\uc11c\ub294 \ud574\ub2f9 \uacf5\uc2dd\uc774 \uc798 \uc801\uc6a9\ub41c \uac83 \uac19\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\ub294\ub370 \uc2dc\uac04\uc774 \ub9ce\uc774 \uac78\ub9ac\ub294 \uacbd\uc6b0 \uc0c1\ud669\uc5d0 \ub530\ub77c\uc11c \ud480 \uc0ac\uc774\uc988\ub97c \ub298\ub9b4 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:"\ub9cc\uc57d \ud558\ub098\uc758 \uc2a4\ub808\ub4dc\uac00 \uc5ec\ub7ec \uac1c\uc758 \ucee4\ub125\uc158\uc744 \ub4e4\uace0 \uc788\ub294 \uacbd\uc6b0 \ub370\ub4dc\ub77d\uc774 \ubb38\uc81c\uac00 \ub420 \uc218 \uc788\ub294\ub370 \uc774\ub97c \ubc29\uc9c0\ud558\ub824\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uacf5\uc2dd\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsxs)(t.blockquote,{children:["\n",(0,r.jsx)(t.p,{children:"pool size = Tn x (Cm - 1) + 1"}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Tn\uc740 \ucf54\uc5b4 \uc218, Cm\uc758 \uacbd\uc6b0 \ub2e8\uc77c \uc694\uccad\uc774 \uc0ac\uc6a9\ud558\ub294 \ucd5c\ub300 \ub3d9\uc2dc \uc5f0\uacb0 \uc218\ub2e4."}),"\n",(0,r.jsx)(t.p,{children:"\uacf5\uc2dd\uc774 \uc874\uc7ac\ud558\uc9c0\ub9cc \uacb0\uad6d \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \uc791\ub3d9\ud558\ub294 \ubc29\uc2dd\uc5d0 \ub530\ub77c \uc801\ud569\ud55c pool size\uac00 \uc874\uc7ac\ud558\ub2c8 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc131\uaca9\uc774\ub098, \uc131\ub2a5 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud574 \uc801\ud569\ud55c \uc0ac\uc774\uc988\ub97c \uc124\uc815\ud558\ub294 \uac83\uc774 \uc801\ud569\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.a,{href:"https://github.com/brettwooldridge/HikariCP",children:"https://github.com/brettwooldridge/HikariCP"})})]})}function u(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(m,{...e})}):m(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>s});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),s=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},m={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},u=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,i=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=s(n),p=o,b=d["".concat(c,".").concat(p)]||d[p]||m[p]||i;return n?r.createElement(b,a(a({ref:t},u),{},{components:n})):r.createElement(b,a({ref:t},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/aacfeabc.8863a050.js b/assets/js/aacfeabc.8863a050.js new file mode 100644 index 000000000..17ab0e722 --- /dev/null +++ b/assets/js/aacfeabc.8863a050.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8909],{60965:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var i=s(85893),t=s(3905);const a={title:"Jenkins\ub85c CI/CD \uc124\uc815",slug:"jenkins",tags:["Jenkins","Elastic Beanstalk"]},r=void 0,l={permalink:"/jenkins",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",source:"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",title:"Jenkins\ub85c CI/CD \uc124\uc815",description:"\uc124\uc815 \ud658\uacbd",date:"2023-04-30T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 30\uc77c",tags:[{label:"Jenkins",permalink:"/tags/jenkins"},{label:"Elastic Beanstalk",permalink:"/tags/elastic-beanstalk"}],readingTime:7.495,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Jenkins\ub85c CI/CD \uc124\uc815",slug:"jenkins",tags:["Jenkins","Elastic Beanstalk"]},unlisted:!1,prevItem:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",permalink:"/tecochat-retrospective-2"},nextItem:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",permalink:"/tecochat-retrospective-1"}},o={authorsImageUrls:[]},c=[{value:"\uc124\uc815 \ud658\uacbd",id:"\uc124\uc815-\ud658\uacbd",level:3},{value:"[EC2 CLI] Swap \uba54\ubaa8\ub9ac \uc124\uc815",id:"ec2-cli-swap-\uba54\ubaa8\ub9ac-\uc124\uc815",level:3},{value:"[EC2 CLI] jenkins \uc124\uce58",id:"ec2-cli-jenkins-\uc124\uce58",level:3},{value:"[EC2 CLI] Jenkins \uc2dc\uc791",id:"ec2-cli-jenkins-\uc2dc\uc791",level:3},{value:"[EC2 CLI] nginx & git \uc124\uce58",id:"ec2-cli-nginx--git-\uc124\uce58",level:3},{value:"[EC2 CLI] nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815",id:"ec2-cli-nginx-\ub9ac\ubc84\uc2a4-\ud504\ub85d\uc2dc-\uc124\uc815",level:3},{value:"[Jenkins] Jenkins \uc811\uc18d",id:"jenkins-jenkins-\uc811\uc18d",level:3},{value:"[Jenkins] Jenkins Blue Ocean \uc124\uce58",id:"jenkins-jenkins-blue-ocean-\uc124\uce58",level:3},{value:"[AWS IAM & EC2] IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30",id:"aws-iam--ec2-iam\uc73c\ub85c-ec2-\uc778\uc2a4\ud134\uc2a4-\uad8c\ud55c-\uc124\uc815\ud558\uae30",level:3},{value:"[AWS S3] Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131",id:"aws-s3-jar-\ud30c\uc77c\uc744-\uc5c5\ub85c\ub4dc-\ud560-s3-\ubc84\ud0b7-\uc0dd\uc131",level:3},{value:"[Github] Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131",id:"github-blue-ocean\uc5d0\uc11c-\ud30c\uc774\ud504\ub77c\uc778-\uc0dd\uc131\uc5d0-\ud544\uc694\ud55c-github-token-\uc0dd\uc131",level:3},{value:"[Jenkins] \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791",id:"jenkins-\ube14\ub8e8-\uc624\uc158-\uc2dc\uc791",level:3},{value:"[Github Repsoitory] Jenkinsfile \uc124\uc815",id:"github-repsoitory-jenkinsfile-\uc124\uc815",level:3},{value:"[Github] Webhooks \uc124\uc815",id:"github-webhooks-\uc124\uc815",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",br:"br",code:"code",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.ah)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"\uc124\uc815-\ud658\uacbd",children:"\uc124\uc815 \ud658\uacbd"}),"\n",(0,i.jsxs)(n.p,{children:["\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc774\ubbf8\uc9c0: Amazon Linux 2023 AMI",(0,i.jsx)(n.br,{}),"\n","\uc544\ud0a4\ud14d\uccd0: ARM",(0,i.jsx)(n.br,{}),"\n","\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small",(0,i.jsx)(n.br,{}),"\n","\ud658\uacbd \uad6c\uc131\uc774 \uc644\ub8cc\ub41c Elastic Beanstalk",(0,i.jsx)(n.br,{}),"\n","\ub2e8\uc77c Spring Boot \ud504\ub85c\uc81d\ud2b8\uac00 \uc874\uc7ac\ud558\ub294 Github Repository"]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-swap-\uba54\ubaa8\ub9ac-\uc124\uc815",children:"[EC2 CLI] Swap \uba54\ubaa8\ub9ac \uc124\uc815"}),"\n",(0,i.jsxs)(n.p,{children:["t4g.small\uc774 \ub7a8\uc774 2G\uc778\ub370 \ub7a8\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \ub290\uaef4\uc838\uc11c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc544\ub798 \uba85\ub839\uc5b4\ub97c \ub530\ub77c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud558\uace0 free -h \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uc798 \uc124\uc815\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# fallocate \uc774\uc6a9\ud558\uc5ec \uc2a4\uc651 \ud30c\uc77c \uc0dd\uc131\nsudo fallocate -l 2G /swapfile\n\n# \uad8c\ud55c \uc124\uc815\nsudo chmod 600 /swapfile\n\n# \ud30c\uc77c\uc744 Swap \ud3ec\ub9f7\uc73c\ub85c \ubcc0\uacbd \ud6c4 \uc2dc\uc2a4\ud15c\uc5d0 \ub4f1\ub85d\nsudo mkswap /swapfile\nsudo swapon /swapfile\n\n# Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9\n# \ucd5c\ud558\ub2e8\uc5d0 \ub2e4\uc74c \uad6c\ubb38 \uc124\uc815 -> /swapfile swap swap defaults 0 0\nsudo vim /etc/fstab\n"})}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-jenkins-\uc124\uce58",children:"[EC2 CLI] jenkins \uc124\uce58"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo wget -O /etc/yum.repos.d/jenkins.repo \\\n https://pkg.jenkins.io/redhat-stable/jenkins.repo\nsudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key\nsudo yum upgrade\nsudo yum install java-17-amazon-corretto-devel\nsudo yum install jenkins\nsudo systemctl daemon-reload\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos",children:"Jenkins \uacf5\uc2dd \ud648\ud398\uc774\uc9c0"})," \ub97c \ucc38\uace0\ud558\uc5ec \uc124\uce58\ud558\ub294 \uac8c \uc88b\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-jenkins-\uc2dc\uc791",children:"[EC2 CLI] Jenkins \uc2dc\uc791"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl enable jenkins\nsudo systemctl start jenkins\n"})}),"\n",(0,i.jsx)(n.p,{children:"enable\ub85c \uc124\uc815\ud558\uc5ec \ubd80\ud305\uc2dc \uc790\ub3d9\uc2dc\uc791 \ub418\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-nginx--git-\uc124\uce58",children:"[EC2 CLI] nginx & git \uc124\uce58"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo yum install nginx\nsudo systemctl enable nginx\nsudo systemctl start nginx\n\nsudo yum install git\n"})}),"\n",(0,i.jsx)(n.p,{children:"nginx\uc640 \ucf54\ub4dc\ub97c \ubd88\ub7ec\uc62c \ub54c \uc0ac\uc6a9\ud560 git\uc744 \uc124\uce58\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-nginx-\ub9ac\ubc84\uc2a4-\ud504\ub85d\uc2dc-\uc124\uc815",children:"[EC2 CLI] nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815"}),"\n",(0,i.jsx)(n.p,{children:"\uc544\ub798 \uc124\uc815 \ud30c\uc77c\uc740 \uacf5\uc2dd \ud648\ud398\uc774\uc9c0\uc5d0\uc11c \uc548\ub0b4\ud55c \uae30\ubcf8\uc801\uc778 \uc124\uc815 \ud30c\uc77c\uc774\ub2e4."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'upstream jenkins {\n keepalive 32; # keepalive connections\n server 127.0.0.1:8080; # jenkins ip and port\n}\n\n# Required for Jenkins websocket agents\nmap $http_upgrade $connection_upgrade {\n default upgrade;\n \'\' close;\n}\n\nserver {\n listen 80; # Listen on port 80 for IPv4 requests\n\n server_name jenkins.example.com; # replace \'jenkins.example.com\' with your server domain name\n\n # this is the jenkins web root directory\n # (mentioned in the output of "systemctl cat jenkins")\n root /var/run/jenkins/war/;\n\n access_log /var/log/nginx/jenkins.access.log;\n error_log /var/log/nginx/jenkins.error.log;\n\n # pass through headers from Jenkins that Nginx considers invalid\n ignore_invalid_headers off;\n\n location ~ "^/static/[0-9a-fA-F]{8}\\/(.*)$" {\n # rewrite all static files into requests to the root\n # E.g /static/12345678/css/something.css will become /css/something.css\n rewrite "^/static/[0-9a-fA-F]{8}\\/(.*)" /$1 last;\n }\n\n location /userContent {\n # have nginx handle all the static requests to userContent folder\n # note : This is the $JENKINS_HOME dir\n root /var/lib/jenkins/;\n if (!-f $request_filename){\n # this file does not exist, might be a directory or a /**view** url\n rewrite (.*) /$1 last;\n break;\n }\n sendfile on;\n }\n\n location / {\n sendfile off;\n proxy_pass http://jenkins;\n proxy_redirect default;\n proxy_http_version 1.1;\n\n # Required for Jenkins websocket agents\n proxy_set_header Connection $connection_upgrade;\n proxy_set_header Upgrade $http_upgrade;\n\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_max_temp_file_size 0;\n\n #this is the maximum upload size\n client_max_body_size 10m;\n client_body_buffer_size 128k;\n\n proxy_connect_timeout 90;\n proxy_send_timeout 90;\n proxy_read_timeout 90;\n proxy_buffering off;\n proxy_request_buffering off; # Required for HTTP CLI commands\n proxy_set_header Connection ""; # Clear for keepalive\n }\n\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Jenkins\ub294 8080 \ud3ec\ud2b8\ub85c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc\ub97c \uc124\uc815\ud574\uc900\ub2e4.",(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.code,{children:"/etc/nginx/conf.d"}),"\xa0\uc544\ub798\xa0",(0,i.jsx)(n.code,{children:"default.conf"}),"\xa0\ud30c\uc77c\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uace0 \uc704\uc640 \uac19\uc774 \uc785\ub825\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","nginx\uc758 \uae30\ubcf8 \uc124\uc815 \ud30c\uc77c\uc5d0 \uc874\uc7ac\ud558\ub294\xa0",(0,i.jsx)(n.code,{children:"include /etc/nginx/conf.d/*.conf;"}),"\xa0\uc124\uc815 \ub54c\ubb38\uc5d0\xa0",(0,i.jsx)(n.code,{children:".conf"}),"\xa0\ub85c \ub05d\ub09c\ub2e4\uba74 \uc124\uc815\uc774 \uc801\uc6a9\ub41c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc124\uc815 \ud6c4\xa0",(0,i.jsx)(n.code,{children:"sudo nginx -t"}),"\ub85c \uc124\uc815\ud30c\uc77c\uc774 \uc815\uc0c1\uc778\uc9c0 \ud655\uc778\ud558\uace0,\xa0",(0,i.jsx)(n.code,{children:"sudo systemctl restart nginx"}),"\xa0\uba85\ub839\uc5b4\ub85c nginx\ub97c \uc7ac\uc2dc\uc791\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"jenkins-jenkins-\uc811\uc18d",children:"[Jenkins] Jenkins \uc811\uc18d"}),"\n",(0,i.jsxs)(n.p,{children:["Jenkins\ub97c \uc124\uce58\ud55c EC2 \uc778\uc2a4\ud134\uc2a4 \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc5d0 80\ubc88 \ud3ec\ud2b8\uac00 \uc5f4\ub824\uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","EC2\uc758 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \uc785\ub825\ud558\uace0 \ub4e4\uc5b4\uac00\uba74 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\ub77c\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"jenkins-start",src:s(71399).Z+"",width:"2008",height:"1836"})}),"\n",(0,i.jsxs)(n.p,{children:["\ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud574\uc57c \ud558\ub294\ub370 ",(0,i.jsx)(n.code,{children:"sudo cat /var/lib/jenkins/secrets/initialAdminPasswor"})," \ub97c \uc785\ub825\ud574 \ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc5bb\uc744 \uc218 \uc788\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\uba74 \ud50c\ub7ec\uadf8\uc778 \uc124\uc815 \ucc3d\uc774 \ub098\uc62c\ud150\ub370 ",(0,i.jsx)(n.code,{children:"install suggested plugins"}),"\uc744 \ud074\ub9ad\ud558\uc5ec Jenkins\uac00 \ucd94\ucc9c\ud558\ub294 \uae30\ubcf8 \ud50c\ub7ec\uadf8\uc778\ub4e4\uc744 \uc124\uce58\ud558\uba74 \ub41c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ud50c\ub7ec\uadf8\uc778\uc744 \uc124\uce58\ud558\uba74 \uacc4\uc815 \ubc0f \uc8fc\uc18c \uc124\uc815\uc744 \ud574\uc57c\ud558\ub294\ub370 \uc774\uac74 \ud3b8\ud558\uac8c \uc124\uc815\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"jenkins-jenkins-blue-ocean-\uc124\uce58",children:"[Jenkins] Jenkins Blue Ocean \uc124\uce58"}),"\n",(0,i.jsx)(n.p,{children:"Jenkins \uad00\ub9ac \u2192 Plugin Manager\uc5d0\uc11c Blue Ocean\uc744 \uac80\uc0c9\ud574 \uc124\uce58\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"aws-iam--ec2-iam\uc73c\ub85c-ec2-\uc778\uc2a4\ud134\uc2a4-\uad8c\ud55c-\uc124\uc815\ud558\uae30",children:"[AWS IAM & EC2] IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30"}),"\n",(0,i.jsxs)(n.p,{children:["S3\uc640 Elastic Beanstalk\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc744 \ubd80\uc5ec\ud558\ub824\uba74 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk \ub450 \uac1c\uc758 \uc815\ucc45\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uc5ed\ud560\uc744 \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","IAM\uc5d0\uc11c \ub2e4\uc74c\uacfc \uac19\uc774 \uc5ed\ud560\uc744 \ud558\ub098 \uc0c8\ub85c \uc0dd\uc131\ud55c\ub2e4."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"\uc5d4\ud130\ud2f0 \uc120\ud0dd"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-iam1",src:s(30618).Z+"",width:"2282",height:"1028"})}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsx)(n.li,{children:"\uad8c\ud55c \ucd94\uac00"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-iam2",src:s(56786).Z+"",width:"2300",height:"880"})}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsx)(n.li,{children:"\uc774\ub984 \uc9c0\uc815, \uac80\ud1a0 \ubc0f \uc0dd\uc131"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-iam3",src:s(63303).Z+"",width:"1872",height:"1724"})}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsx)(n.li,{children:"\uc0dd\uc131\ud55c IAM EC2 Jenkins \uc778\uc2a4\ud134\uc2a4\ub97c \uc120\ud0dd\ud558\uace0, \uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc744 \ub20c\ub7ec Role \uc124\uc815"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-iam4",src:s(82150).Z+"",width:"2264",height:"602"})}),"\n",(0,i.jsx)(n.h3,{id:"aws-s3-jar-\ud30c\uc77c\uc744-\uc5c5\ub85c\ub4dc-\ud560-s3-\ubc84\ud0b7-\uc0dd\uc131",children:"[AWS S3] Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131"}),"\n",(0,i.jsx)(n.p,{children:"\ubc84\ud0b7\uc744 \uc0dd\uc131\ud560 \ub54c \ub2e4\uc74c \uc124\uc815\uc744 \uc81c\uc678\ud558\uace0 \ubaa8\ub450 \ucc28\ub2e8 \ud65c\uc131\ud654\ub97c \ud574\uc900\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"\uc0c8 ACL(\uc561\uc138\uc2a4 \uc81c\uc5b4 \ubaa9\ub85d)\uc744 \ud1b5\ud574 \ubd80\uc5ec\ub41c \ubc84\ud0b7 \ubc0f \uac1d\uccb4\uc5d0 \ub300\ud55c \ud37c\ube14\ub9ad \uc561\uc138\uc2a4 \ucc28\ub2e8"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-s3",src:s(36238).Z+"",width:"1636",height:"1258"})}),"\n",(0,i.jsx)(n.h3,{id:"github-blue-ocean\uc5d0\uc11c-\ud30c\uc774\ud504\ub77c\uc778-\uc0dd\uc131\uc5d0-\ud544\uc694\ud55c-github-token-\uc0dd\uc131",children:"[Github] Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131"}),"\n",(0,i.jsxs)(n.p,{children:["repo, user",":email"," \uad8c\ud55c\uc774 \uc788\ub294 \ud1a0\ud070\uc774 \ud544\uc694\ud558\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"jenkins-\ube14\ub8e8-\uc624\uc158-\uc2dc\uc791",children:"[Jenkins] \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"jenkins-blue-ocean1",src:s(29666).Z+"",width:"2390",height:"1372"})}),"\n",(0,i.jsxs)(n.p,{children:["\ube14\ub8e8 \uc624\uc158 \uc5f4\uae30\ub85c \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc0dd\uc131\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ud1a0\ud070 \uc785\ub825 \u2192 \uc870\uc9c1 \uc120\ud0dd \u2192 CI/CD \uc124\uc815\ud560 Repository \uc120\ud0dd\uc744 \ud558\uba74 \ud30c\uc774\ud504\ub77c\uc778 \ucc3d\uc73c\ub85c \ub118\uc5b4\uac04\ub2e4.",(0,i.jsx)(n.br,{}),"\n","Jenkinsfile\uc744 \uc9c1\uc811 \uc791\uc131\ud558\uc5ec \uc124\uc815\ud558\uae30 \uc704\ud574 \uac04\ub2e8\ud558\uac8c print \ud558\ub098 \ucd9c\ub825\ud558\ub294 \uac83\uc73c\ub85c \uc124\uc815\ud588\ub2e4."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"jenkins-blue-ocean2",src:s(49614).Z+"",width:"2076",height:"638"})}),"\n",(0,i.jsx)(n.p,{children:"\ud30c\uc774\ud504\ub77c\uc778\uc774 \uc2e4\ud589\ub420 \ud150\ub370 pipeline status\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \ucd08\ub85d\ubd88\uc774 \ub728\uba74 \ub41c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"jenkins-blue-ocean3",src:s(71079).Z+"",width:"1084",height:"626"})}),"\n",(0,i.jsx)(n.h3,{id:"github-repsoitory-jenkinsfile-\uc124\uc815",children:"[Github Repsoitory] Jenkinsfile \uc124\uc815"}),"\n",(0,i.jsx)(n.p,{children:"\ube14\ub8e8 \uc624\uc158 \uc2dc\uc791\uc744 \ud1b5\ud574 \uc124\uc815\ud558\uba74 Jenkinsfile\uc774 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc9c0\uace0, \uc544\ub798\uc640 \uac19\uc774 \uc6d0\ud558\ub294 \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc124\uc815\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"pipeline {\n agent any\n stages {\n stage('build and test') {\n steps {\n sh '/gradlew clean build'\n }\n }\n stage('zip') {\n steps {\n sh 'mv ./build/libs/woowachat.jar .'\n sh 'zip -r woowachat.zip .platform delivery.jar Procfile'\n }\n }\n stage('upload') {\n steps {\n sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'\n }\n }\n stage('deploy') {\n steps {\n sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket=\"woowa-chat\",S3Key=\"woowachat.zip\"'\n sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'\n }\n }\n }\n}\n"})}),"\n",(0,i.jsx)(n.h3,{id:"github-webhooks-\uc124\uc815",children:"[Github] Webhooks \uc124\uc815"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"github-hook",src:s(36642).Z+"",width:"1428",height:"1148"})}),"\n",(0,i.jsxs)(n.p,{children:["push \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud560 \ub54c ",(0,i.jsx)(n.code,{children:"http://Jenkins\uc8fc\uc18c/github-webhook/"})," \ub85c post request\ub97c \ud558\ub3c4\ub85d \uc6f9\ud6c5\uc744 \uc124\uc815\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos",children:"Install Jenkins - CentOS, Jenkins"}),(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.a,{href:"https://www.jenkins.io/doc/book/system-administration/reverse-proxy-configuration-nginx/",children:"Nginx Reverse Proxy Configuration, Jenkins"}),(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html",children:"Amazon Corretto 17 JDK Install, AWS"}),(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/linux/al2023/release-notes/all-packages-al2023-20230419.html",children:"Amazon Linux 2023 packages, AWS"})]})]})}function h(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},3905:(e,n,s)=>{s.d(n,{ah:()=>c});var i=s(67294);function t(e,n,s){return n in e?Object.defineProperty(e,n,{value:s,enumerable:!0,configurable:!0,writable:!0}):e[n]=s,e}function a(e,n){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),s.push.apply(s,i)}return s}function r(e){for(var n=1;n<arguments.length;n++){var s=null!=arguments[n]?arguments[n]:{};n%2?a(Object(s),!0).forEach((function(n){t(e,n,s[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(s)):a(Object(s)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(s,n))}))}return e}function l(e,n){if(null==e)return{};var s,i,t=function(e,n){if(null==e)return{};var s,i,t={},a=Object.keys(e);for(i=0;i<a.length;i++)s=a[i],n.indexOf(s)>=0||(t[s]=e[s]);return t}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i<a.length;i++)s=a[i],n.indexOf(s)>=0||Object.prototype.propertyIsEnumerable.call(e,s)&&(t[s]=e[s])}return t}var o=i.createContext({}),c=function(e){var n=i.useContext(o),s=n;return e&&(s="function"==typeof e?e(n):r(r({},n),e)),s},d={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},h=i.forwardRef((function(e,n){var s=e.components,t=e.mdxType,a=e.originalType,o=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=c(s),u=t,j=p["".concat(o,".").concat(u)]||p[u]||d[u]||a;return s?i.createElement(j,r(r({ref:n},h),{},{components:s})):i.createElement(j,r({ref:n},h))}));h.displayName="MDXCreateElement"},30618:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-iam1-e6d63be6b9f41d63e91d604138e6b07c.png"},56786:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-iam2-557683fc91b1c22330d081d6050dfe82.png"},63303:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-iam3-94248e9194dd58bb16d0289af47a4260.png"},82150:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-iam4-54ccc5a4e64d31f7eeab89d39ebf772f.png"},36238:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-s3-757380d36e5492c962f75dae024994e5.png"},36642:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/github-hook-e9ebe0acb3ff0086ecebbd8c857ffe39.png"},29666:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/jenkins-blue-ocean1-bd108d887d700ea081e4b0a3d83ad459.png"},49614:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/jenkins-blue-ocean2-408c6c90e4a5371becc4d1013fba1212.png"},71079:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/jenkins-blue-ocean3-4050a206b3efe95a3c9f39c3f7a47ad7.png"},71399:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/jenkins-start-dce0d7051054c398d2a707c75c685234.png"}}]); \ No newline at end of file diff --git a/assets/js/aacfeabc.ff4dccf0.js b/assets/js/aacfeabc.ff4dccf0.js deleted file mode 100644 index fa42f1cab..000000000 --- a/assets/js/aacfeabc.ff4dccf0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8909],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>d});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?s(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function l(e,n){if(null==e)return{};var t,a,i=function(e,n){if(null==e)return{};var t,a,i={},s=Object.keys(e);for(a=0;a<s.length;a++)t=s[a],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a<s.length;a++)t=s[a],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var o=a.createContext({}),p=function(e){var n=a.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(o.Provider,{value:n},e.children)},k={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,s=e.originalType,o=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(t),d=i,m=u["".concat(o,".").concat(d)]||u[d]||k[d]||s;return t?a.createElement(m,r(r({ref:n},c),{},{components:t})):a.createElement(m,r({ref:n},c))}));function d(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var s=t.length,r=new Array(s);r[0]=u;var l={};for(var o in n)hasOwnProperty.call(n,o)&&(l[o]=n[o]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p<s;p++)r[p]=t[p];return a.createElement.apply(null,r)}return a.createElement.apply(null,t)}u.displayName="MDXCreateElement"},79407:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>k,frontMatter:()=>s,metadata:()=>l,toc:()=>p});var a=t(87462),i=(t(67294),t(3905));const s={title:"Jenkins\ub85c CI/CD \uc124\uc815",slug:"jenkins",tags:["Jenkins","Elastic Beanstalk"]},r=void 0,l={permalink:"/jenkins",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",source:"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",title:"Jenkins\ub85c CI/CD \uc124\uc815",description:"\uc124\uc815 \ud658\uacbd",date:"2023-04-30T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 30\uc77c",tags:[{label:"Jenkins",permalink:"/tags/jenkins"},{label:"Elastic Beanstalk",permalink:"/tags/elastic-beanstalk"}],readingTime:7.495,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Jenkins\ub85c CI/CD \uc124\uc815",slug:"jenkins",tags:["Jenkins","Elastic Beanstalk"]},prevItem:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",permalink:"/tecochat-retrospective-2"},nextItem:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",permalink:"/tecochat-retrospective-1"}},o={authorsImageUrls:[]},p=[{value:"\uc124\uc815 \ud658\uacbd",id:"\uc124\uc815-\ud658\uacbd",level:3},{value:"[EC2 CLI] Swap \uba54\ubaa8\ub9ac \uc124\uc815",id:"ec2-cli-swap-\uba54\ubaa8\ub9ac-\uc124\uc815",level:3},{value:"[EC2 CLI] jenkins \uc124\uce58",id:"ec2-cli-jenkins-\uc124\uce58",level:3},{value:"[EC2 CLI] Jenkins \uc2dc\uc791",id:"ec2-cli-jenkins-\uc2dc\uc791",level:3},{value:"[EC2 CLI] nginx & git \uc124\uce58",id:"ec2-cli-nginx--git-\uc124\uce58",level:3},{value:"[EC2 CLI] nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815",id:"ec2-cli-nginx-\ub9ac\ubc84\uc2a4-\ud504\ub85d\uc2dc-\uc124\uc815",level:3},{value:"[Jenkins] Jenkins \uc811\uc18d",id:"jenkins-jenkins-\uc811\uc18d",level:3},{value:"[Jenkins] Jenkins Blue Ocean \uc124\uce58",id:"jenkins-jenkins-blue-ocean-\uc124\uce58",level:3},{value:"[AWS IAM & EC2] IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30",id:"aws-iam--ec2-iam\uc73c\ub85c-ec2-\uc778\uc2a4\ud134\uc2a4-\uad8c\ud55c-\uc124\uc815\ud558\uae30",level:3},{value:"[AWS S3] Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131",id:"aws-s3-jar-\ud30c\uc77c\uc744-\uc5c5\ub85c\ub4dc-\ud560-s3-\ubc84\ud0b7-\uc0dd\uc131",level:3},{value:"[Github] Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131",id:"github-blue-ocean\uc5d0\uc11c-\ud30c\uc774\ud504\ub77c\uc778-\uc0dd\uc131\uc5d0-\ud544\uc694\ud55c-github-token-\uc0dd\uc131",level:3},{value:"[Jenkins] \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791",id:"jenkins-\ube14\ub8e8-\uc624\uc158-\uc2dc\uc791",level:3},{value:"[Github Repsoitory] Jenkinsfile \uc124\uc815",id:"github-repsoitory-jenkinsfile-\uc124\uc815",level:3},{value:"[Github] Webhooks \uc124\uc815",id:"github-webhooks-\uc124\uc815",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:p};function k(e){let{components:n,...s}=e;return(0,i.kt)("wrapper",(0,a.Z)({},c,s,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h3",{id:"\uc124\uc815-\ud658\uacbd"},"\uc124\uc815 \ud658\uacbd"),(0,i.kt)("p",null,"\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc774\ubbf8\uc9c0: Amazon Linux 2023 AMI",(0,i.kt)("br",{parentName:"p"}),"\n","\uc544\ud0a4\ud14d\uccd0: ARM",(0,i.kt)("br",{parentName:"p"}),"\n","\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small",(0,i.kt)("br",{parentName:"p"}),"\n","\ud658\uacbd \uad6c\uc131\uc774 \uc644\ub8cc\ub41c Elastic Beanstalk",(0,i.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc77c Spring Boot \ud504\ub85c\uc81d\ud2b8\uac00 \uc874\uc7ac\ud558\ub294 Github Repository"),(0,i.kt)("h3",{id:"ec2-cli-swap-\uba54\ubaa8\ub9ac-\uc124\uc815"},"[","EC2 CLI","]"," Swap \uba54\ubaa8\ub9ac \uc124\uc815"),(0,i.kt)("p",null,"t4g.small\uc774 \ub7a8\uc774 2G\uc778\ub370 \ub7a8\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \ub290\uaef4\uc838\uc11c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud588\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\uc544\ub798 \uba85\ub839\uc5b4\ub97c \ub530\ub77c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud558\uace0 free -h \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uc798 \uc124\uc815\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"# fallocate \uc774\uc6a9\ud558\uc5ec \uc2a4\uc651 \ud30c\uc77c \uc0dd\uc131\nsudo fallocate -l 2G /swapfile\n\n# \uad8c\ud55c \uc124\uc815\nsudo chmod 600 /swapfile\n\n# \ud30c\uc77c\uc744 Swap \ud3ec\ub9f7\uc73c\ub85c \ubcc0\uacbd \ud6c4 \uc2dc\uc2a4\ud15c\uc5d0 \ub4f1\ub85d\nsudo mkswap /swapfile\nsudo swapon /swapfile\n\n# Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9\n# \ucd5c\ud558\ub2e8\uc5d0 \ub2e4\uc74c \uad6c\ubb38 \uc124\uc815 -> /swapfile swap swap defaults 0 0\nsudo vim /etc/fstab\n")),(0,i.kt)("h3",{id:"ec2-cli-jenkins-\uc124\uce58"},"[","EC2 CLI","]"," jenkins \uc124\uce58"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo wget -O /etc/yum.repos.d/jenkins.repo \\\n https://pkg.jenkins.io/redhat-stable/jenkins.repo\nsudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key\nsudo yum upgrade\nsudo yum install java-17-amazon-corretto-devel\nsudo yum install jenkins\nsudo systemctl daemon-reload\n")),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos"},"Jenkins \uacf5\uc2dd \ud648\ud398\uc774\uc9c0")," \ub97c \ucc38\uace0\ud558\uc5ec \uc124\uce58\ud558\ub294 \uac8c \uc88b\ub2e4."),(0,i.kt)("h3",{id:"ec2-cli-jenkins-\uc2dc\uc791"},"[","EC2 CLI","]"," Jenkins \uc2dc\uc791"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo systemctl enable jenkins\nsudo systemctl start jenkins\n")),(0,i.kt)("p",null,"enable\ub85c \uc124\uc815\ud558\uc5ec \ubd80\ud305\uc2dc \uc790\ub3d9\uc2dc\uc791 \ub418\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."),(0,i.kt)("h3",{id:"ec2-cli-nginx--git-\uc124\uce58"},"[","EC2 CLI","]"," nginx & git \uc124\uce58"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo yum install nginx\nsudo systemctl enable nginx\nsudo systemctl start nginx\n\nsudo yum install git\n")),(0,i.kt)("p",null,"nginx\uc640 \ucf54\ub4dc\ub97c \ubd88\ub7ec\uc62c \ub54c \uc0ac\uc6a9\ud560 git\uc744 \uc124\uce58\ud55c\ub2e4."),(0,i.kt)("h3",{id:"ec2-cli-nginx-\ub9ac\ubc84\uc2a4-\ud504\ub85d\uc2dc-\uc124\uc815"},"[","EC2 CLI","]"," nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815"),(0,i.kt)("p",null,"\uc544\ub798 \uc124\uc815 \ud30c\uc77c\uc740 \uacf5\uc2dd \ud648\ud398\uc774\uc9c0\uc5d0\uc11c \uc548\ub0b4\ud55c \uae30\ubcf8\uc801\uc778 \uc124\uc815 \ud30c\uc77c\uc774\ub2e4."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'upstream jenkins {\n keepalive 32; # keepalive connections\n server 127.0.0.1:8080; # jenkins ip and port\n}\n\n# Required for Jenkins websocket agents\nmap $http_upgrade $connection_upgrade {\n default upgrade;\n \'\' close;\n}\n\nserver {\n listen 80; # Listen on port 80 for IPv4 requests\n\n server_name jenkins.example.com; # replace \'jenkins.example.com\' with your server domain name\n\n # this is the jenkins web root directory\n # (mentioned in the output of "systemctl cat jenkins")\n root /var/run/jenkins/war/;\n\n access_log /var/log/nginx/jenkins.access.log;\n error_log /var/log/nginx/jenkins.error.log;\n\n # pass through headers from Jenkins that Nginx considers invalid\n ignore_invalid_headers off;\n\n location ~ "^/static/[0-9a-fA-F]{8}\\/(.*)$" {\n # rewrite all static files into requests to the root\n # E.g /static/12345678/css/something.css will become /css/something.css\n rewrite "^/static/[0-9a-fA-F]{8}\\/(.*)" /$1 last;\n }\n\n location /userContent {\n # have nginx handle all the static requests to userContent folder\n # note : This is the $JENKINS_HOME dir\n root /var/lib/jenkins/;\n if (!-f $request_filename){\n # this file does not exist, might be a directory or a /**view** url\n rewrite (.*) /$1 last;\n break;\n }\n sendfile on;\n }\n\n location / {\n sendfile off;\n proxy_pass http://jenkins;\n proxy_redirect default;\n proxy_http_version 1.1;\n\n # Required for Jenkins websocket agents\n proxy_set_header Connection $connection_upgrade;\n proxy_set_header Upgrade $http_upgrade;\n\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_max_temp_file_size 0;\n\n #this is the maximum upload size\n client_max_body_size 10m;\n client_body_buffer_size 128k;\n\n proxy_connect_timeout 90;\n proxy_send_timeout 90;\n proxy_read_timeout 90;\n proxy_buffering off;\n proxy_request_buffering off; # Required for HTTP CLI commands\n proxy_set_header Connection ""; # Clear for keepalive\n }\n\n}\n')),(0,i.kt)("p",null,"Jenkins\ub294 8080 \ud3ec\ud2b8\ub85c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc\ub97c \uc124\uc815\ud574\uc900\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/nginx/conf.d"),"\xa0\uc544\ub798\xa0",(0,i.kt)("inlineCode",{parentName:"p"},"default.conf"),"\xa0\ud30c\uc77c\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uace0 \uc704\uc640 \uac19\uc774 \uc785\ub825\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","nginx\uc758 \uae30\ubcf8 \uc124\uc815 \ud30c\uc77c\uc5d0 \uc874\uc7ac\ud558\ub294\xa0",(0,i.kt)("inlineCode",{parentName:"p"},"include /etc/nginx/conf.d/*.conf;"),"\xa0\uc124\uc815 \ub54c\ubb38\uc5d0\xa0",(0,i.kt)("inlineCode",{parentName:"p"},".conf"),"\xa0\ub85c \ub05d\ub09c\ub2e4\uba74 \uc124\uc815\uc774 \uc801\uc6a9\ub41c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\uc124\uc815 \ud6c4\xa0",(0,i.kt)("inlineCode",{parentName:"p"},"sudo nginx -t"),"\ub85c \uc124\uc815\ud30c\uc77c\uc774 \uc815\uc0c1\uc778\uc9c0 \ud655\uc778\ud558\uace0,\xa0",(0,i.kt)("inlineCode",{parentName:"p"},"sudo systemctl restart nginx"),"\xa0\uba85\ub839\uc5b4\ub85c nginx\ub97c \uc7ac\uc2dc\uc791\ud55c\ub2e4. "),(0,i.kt)("h3",{id:"jenkins-jenkins-\uc811\uc18d"},"[","Jenkins","]"," Jenkins \uc811\uc18d"),(0,i.kt)("p",null,"Jenkins\ub97c \uc124\uce58\ud55c EC2 \uc778\uc2a4\ud134\uc2a4 \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc5d0 80\ubc88 \ud3ec\ud2b8\uac00 \uc5f4\ub824\uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","EC2\uc758 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \uc785\ub825\ud558\uace0 \ub4e4\uc5b4\uac00\uba74 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\ub77c\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"jenkins-start",src:t(71399).Z,width:"2008",height:"1836"})),(0,i.kt)("p",null,"\ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud574\uc57c \ud558\ub294\ub370 ",(0,i.kt)("inlineCode",{parentName:"p"},"sudo cat /var/lib/jenkins/secrets/initialAdminPasswor")," \ub97c \uc785\ub825\ud574 \ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc5bb\uc744 \uc218 \uc788\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\uba74 \ud50c\ub7ec\uadf8\uc778 \uc124\uc815 \ucc3d\uc774 \ub098\uc62c\ud150\ub370 ",(0,i.kt)("inlineCode",{parentName:"p"},"install suggested plugins"),"\uc744 \ud074\ub9ad\ud558\uc5ec Jenkins\uac00 \ucd94\ucc9c\ud558\ub294 \uae30\ubcf8 \ud50c\ub7ec\uadf8\uc778\ub4e4\uc744 \uc124\uce58\ud558\uba74 \ub41c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\ud50c\ub7ec\uadf8\uc778\uc744 \uc124\uce58\ud558\uba74 \uacc4\uc815 \ubc0f \uc8fc\uc18c \uc124\uc815\uc744 \ud574\uc57c\ud558\ub294\ub370 \uc774\uac74 \ud3b8\ud558\uac8c \uc124\uc815\ud558\uba74 \ub41c\ub2e4. "),(0,i.kt)("h3",{id:"jenkins-jenkins-blue-ocean-\uc124\uce58"},"[","Jenkins","]"," Jenkins Blue Ocean \uc124\uce58"),(0,i.kt)("p",null,"Jenkins \uad00\ub9ac \u2192 Plugin Manager\uc5d0\uc11c Blue Ocean\uc744 \uac80\uc0c9\ud574 \uc124\uce58\ud55c\ub2e4."),(0,i.kt)("h3",{id:"aws-iam--ec2-iam\uc73c\ub85c-ec2-\uc778\uc2a4\ud134\uc2a4-\uad8c\ud55c-\uc124\uc815\ud558\uae30"},"[","AWS IAM & EC2","]"," IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30"),(0,i.kt)("p",null,"S3\uc640 Elastic Beanstalk\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc744 \ubd80\uc5ec\ud558\ub824\uba74 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk \ub450 \uac1c\uc758 \uc815\ucc45\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uc5ed\ud560\uc744 \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","IAM\uc5d0\uc11c \ub2e4\uc74c\uacfc \uac19\uc774 \uc5ed\ud560\uc744 \ud558\ub098 \uc0c8\ub85c \uc0dd\uc131\ud55c\ub2e4."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"\uc5d4\ud130\ud2f0 \uc120\ud0dd")),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-iam1",src:t(30618).Z,width:"2282",height:"1028"})),(0,i.kt)("ol",{start:2},(0,i.kt)("li",{parentName:"ol"},"\uad8c\ud55c \ucd94\uac00")),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-iam2",src:t(56786).Z,width:"2300",height:"880"})),(0,i.kt)("ol",{start:3},(0,i.kt)("li",{parentName:"ol"},"\uc774\ub984 \uc9c0\uc815, \uac80\ud1a0 \ubc0f \uc0dd\uc131")),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-iam3",src:t(63303).Z,width:"1872",height:"1724"})),(0,i.kt)("ol",{start:4},(0,i.kt)("li",{parentName:"ol"},"\uc0dd\uc131\ud55c IAM EC2 Jenkins \uc778\uc2a4\ud134\uc2a4\ub97c \uc120\ud0dd\ud558\uace0, \uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc744 \ub20c\ub7ec Role \uc124\uc815")),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-iam4",src:t(82150).Z,width:"2264",height:"602"})),(0,i.kt)("h3",{id:"aws-s3-jar-\ud30c\uc77c\uc744-\uc5c5\ub85c\ub4dc-\ud560-s3-\ubc84\ud0b7-\uc0dd\uc131"},"[","AWS S3","]"," Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131"),(0,i.kt)("p",null,"\ubc84\ud0b7\uc744 \uc0dd\uc131\ud560 \ub54c \ub2e4\uc74c \uc124\uc815\uc744 \uc81c\uc678\ud558\uace0 \ubaa8\ub450 \ucc28\ub2e8 \ud65c\uc131\ud654\ub97c \ud574\uc900\ub2e4."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"\uc0c8 ACL(\uc561\uc138\uc2a4 \uc81c\uc5b4 \ubaa9\ub85d)\uc744 \ud1b5\ud574 \ubd80\uc5ec\ub41c \ubc84\ud0b7 \ubc0f \uac1d\uccb4\uc5d0 \ub300\ud55c \ud37c\ube14\ub9ad \uc561\uc138\uc2a4 \ucc28\ub2e8"))),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-s3",src:t(36238).Z,width:"1636",height:"1258"})),(0,i.kt)("h3",{id:"github-blue-ocean\uc5d0\uc11c-\ud30c\uc774\ud504\ub77c\uc778-\uc0dd\uc131\uc5d0-\ud544\uc694\ud55c-github-token-\uc0dd\uc131"},"[","Github","]"," Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131"),(0,i.kt)("p",null,"repo, user:email \uad8c\ud55c\uc774 \uc788\ub294 \ud1a0\ud070\uc774 \ud544\uc694\ud558\ub2e4. "),(0,i.kt)("h3",{id:"jenkins-\ube14\ub8e8-\uc624\uc158-\uc2dc\uc791"},"[","Jenkins","]"," \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"jenkins-blue-ocean1",src:t(29666).Z,width:"2390",height:"1372"})),(0,i.kt)("p",null,"\ube14\ub8e8 \uc624\uc158 \uc5f4\uae30\ub85c \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc0dd\uc131\ud55c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\ud1a0\ud070 \uc785\ub825 \u2192 \uc870\uc9c1 \uc120\ud0dd \u2192 CI/CD \uc124\uc815\ud560 Repository \uc120\ud0dd\uc744 \ud558\uba74 \ud30c\uc774\ud504\ub77c\uc778 \ucc3d\uc73c\ub85c \ub118\uc5b4\uac04\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","Jenkinsfile\uc744 \uc9c1\uc811 \uc791\uc131\ud558\uc5ec \uc124\uc815\ud558\uae30 \uc704\ud574 \uac04\ub2e8\ud558\uac8c print \ud558\ub098 \ucd9c\ub825\ud558\ub294 \uac83\uc73c\ub85c \uc124\uc815\ud588\ub2e4. "),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"jenkins-blue-ocean2",src:t(49614).Z,width:"2076",height:"638"})),(0,i.kt)("p",null,"\ud30c\uc774\ud504\ub77c\uc778\uc774 \uc2e4\ud589\ub420 \ud150\ub370 pipeline status\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \ucd08\ub85d\ubd88\uc774 \ub728\uba74 \ub41c\ub2e4."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"jenkins-blue-ocean3",src:t(71079).Z,width:"1084",height:"626"})),(0,i.kt)("h3",{id:"github-repsoitory-jenkinsfile-\uc124\uc815"},"[","Github Repsoitory","]"," Jenkinsfile \uc124\uc815"),(0,i.kt)("p",null,"\ube14\ub8e8 \uc624\uc158 \uc2dc\uc791\uc744 \ud1b5\ud574 \uc124\uc815\ud558\uba74 Jenkinsfile\uc774 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc9c0\uace0, \uc544\ub798\uc640 \uac19\uc774 \uc6d0\ud558\ub294 \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc124\uc815\ud55c\ub2e4."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"pipeline {\n agent any\n stages {\n stage('build and test') {\n steps {\n sh '/gradlew clean build'\n }\n }\n stage('zip') {\n steps {\n sh 'mv ./build/libs/woowachat.jar .'\n sh 'zip -r woowachat.zip .platform delivery.jar Procfile'\n }\n }\n stage('upload') {\n steps {\n sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'\n }\n }\n stage('deploy') {\n steps {\n sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket=\"woowa-chat\",S3Key=\"woowachat.zip\"'\n sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'\n }\n }\n }\n}\n")),(0,i.kt)("h3",{id:"github-webhooks-\uc124\uc815"},"[","Github","]"," Webhooks \uc124\uc815"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"github-hook",src:t(36642).Z,width:"1428",height:"1148"})),(0,i.kt)("p",null,"push \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud560 \ub54c ",(0,i.kt)("inlineCode",{parentName:"p"},"http://Jenkins\uc8fc\uc18c/github-webhook/")," \ub85c post request\ub97c \ud558\ub3c4\ub85d \uc6f9\ud6c5\uc744 \uc124\uc815\ud55c\ub2e4."),(0,i.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos"},"Install Jenkins - CentOS, Jenkins"),(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("a",{parentName:"p",href:"https://www.jenkins.io/doc/book/system-administration/reverse-proxy-configuration-nginx/"},"Nginx Reverse Proxy Configuration, Jenkins"),(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html"},"Amazon Corretto 17 JDK Install, AWS"),(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/linux/al2023/release-notes/all-packages-al2023-20230419.html"},"Amazon Linux 2023 packages, AWS")))}k.isMDXComponent=!0},30618:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-iam1-e6d63be6b9f41d63e91d604138e6b07c.png"},56786:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-iam2-557683fc91b1c22330d081d6050dfe82.png"},63303:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-iam3-94248e9194dd58bb16d0289af47a4260.png"},82150:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-iam4-54ccc5a4e64d31f7eeab89d39ebf772f.png"},36238:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-s3-757380d36e5492c962f75dae024994e5.png"},36642:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/github-hook-e9ebe0acb3ff0086ecebbd8c857ffe39.png"},29666:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/jenkins-blue-ocean1-bd108d887d700ea081e4b0a3d83ad459.png"},49614:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/jenkins-blue-ocean2-408c6c90e4a5371becc4d1013fba1212.png"},71079:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/jenkins-blue-ocean3-4050a206b3efe95a3c9f39c3f7a47ad7.png"},71399:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/jenkins-start-dce0d7051054c398d2a707c75c685234.png"}}]); \ No newline at end of file diff --git a/assets/js/abc83b7f.9e2be049.js b/assets/js/abc83b7f.a6c12174.js similarity index 81% rename from assets/js/abc83b7f.9e2be049.js rename to assets/js/abc83b7f.a6c12174.js index 35d2b1b91..eef54bc13 100644 --- a/assets/js/abc83b7f.9e2be049.js +++ b/assets/js/abc83b7f.a6c12174.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2215],{8412:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2215],{8412:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/ac3fdf5d.91db26ff.js b/assets/js/ac3fdf5d.91db26ff.js deleted file mode 100644 index 73d95f314..000000000 --- a/assets/js/ac3fdf5d.91db26ff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8548],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>v});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},l=Object.keys(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),u=c(r),v=a,d=u["".concat(i,".").concat(v)]||u[v]||m[v]||l;return r?n.createElement(d,o(o({ref:t},s),{},{components:r})):n.createElement(d,o({ref:t},s))}));function v(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=u;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:a,o[1]=p;for(var c=2;c<l;c++)o[c]=r[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}u.displayName="MDXCreateElement"},26094:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",slug:"web-application-evolution",tags:["web application"]},o=void 0,p={permalink:"/web-application-evolution",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",source:"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",description:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",date:"2023-09-30T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 30\uc77c",tags:[{label:"web application",permalink:"/tags/web-application"}],readingTime:7.5,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",slug:"web-application-evolution",tags:["web application"]},prevItem:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",permalink:"/spring-test-isolation"},nextItem:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",permalink:"/log-async-exception"}},i={authorsImageUrls:[]},c=[{value:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",level:3},{value:"WWW(1989)",id:"www1989",level:3},{value:"CGI(1993)",id:"cgi1993",level:3},{value:"Servlet(1996)",id:"servlet1996",level:3},{value:"JSP(1999)",id:"jsp1999",level:3},{value:"MVC(2000)",id:"mvc2000",level:3},{value:"Spring Framework(2003)",id:"spring-framework2003",level:3},{value:"WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)",id:"webflux-\uc774\uc804-servlet-302009-312013",level:3},{value:"Spring WebFlux(2017)",id:"spring-webflux2017",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:c};function m(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815"},"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815"),(0,a.kt)("p",null,"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6d0\ub798 \ud68c\uace0\uc5d0 \uc791\uc131\ud558\ub824\uace0 \ud588\uc9c0\ub9cc, \uc815\ub9ac\ud558\ub2e4 \ubcf4\ub2c8 \uc870\uae08 \uae38\uc5b4\uc838\uc11c \ub530\ub85c \ubd84\ub9ac\ud588\ub2e4. "),(0,a.kt)("mermaid",{value:"graph LR\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking"}),(0,a.kt)("h3",{id:"www1989"},"WWW(1989)"),(0,a.kt)("p",null,"\uc815\uc801 \ud398\uc774\uc9c0\ub97c \uc81c\uacf5\ud558\ub294 \uc6f9 \uc11c\ubc84\ub97c \uc2dc\uc791\uc73c\ub85c \ub3d9\uc801 \ud398\uc774\uc9c0\uac00 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 CGI\uac00 \ub4f1\uc7a5\ud588\ub2e4. "),(0,a.kt)("h3",{id:"cgi1993"},"CGI(1993)"),(0,a.kt)("p",null,"CGI\ub294 \ub3d9\uc801 \ucf58\ud150\uce20\ub97c \uc81c\uacf5\ud558\uae30 \uc704\ud55c \uaddc\uc57d\uc73c\ub85c, \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc774\uc6a9\ud574\uc11c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ucf1c \uc815\ubcf4\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ub9ce\uc740 \ubd80\ud558\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc774\ub7ec\ud55c \ub2e8\uc810\uc744 \uadf9\ubcf5\ud558\uae30 \uc704\ud574 \ub098\uc628 \uac83\uc774 Servlet\uc774\ub2e4. "),(0,a.kt)("h3",{id:"servlet1996"},"Servlet(1996)"),(0,a.kt)("p",null,"Servlet\uc740 \uc6f9 \uc11c\ubc84\uc5d0\uc11c \uc2e4\ud589\ub418\ub294 \uc790\ubc14 \ud504\ub85c\uadf8\ub7a8\uc73c\ub85c HTTP\ub97c \uc774\uc6a9\ud558\uc5ec \uc6f9 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc744 \uc218\uc2e0\ud558\uace0 \uc751\ub2f5\ud55c\ub2e4. CGI\uc640 \ub2e4\ub974\uac8c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\uac00 \uc544\ub2cc \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uc5ec \uc751\ub2f5\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc View \uc601\uc5ed\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uae30 \uc704\ud574 Servlet\uc758 \uc18c\uc2a4 \ucf54\ub4dc\ub97c \uc54c\uc544\uc57c \ud558\ub294 \ub4f1 \ubcf5\uc7a1\ub3c4\uac00 \ub108\ubb34 \ub192\uc558\ub2e4. \ub530\ub77c\uc11c \ud574\ub2f9 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 JSP\uac00 \ub4f1\uc7a5\ud588\ub2e4. "),(0,a.kt)("h3",{id:"jsp1999"},"JSP(1999)"),(0,a.kt)("p",null,"JSP\ub294 HTML\uc5d0 \uc790\ubc14 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ub3d9\uc801 \uc6f9 \ud398\uc774\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\uc220\ub85c, \uc720\uc0ac\ud55c \uae30\uc220\ub85c\ub294 ASP, PHP\uac00 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","JSP\ub9cc \uc0ac\uc6a9\ud558\uc5ec \ud504\ub85c\uadf8\ub798\ubc0d\ud55c\ub2e4\uba74 Model 1, \uc544\ub798 \uad6c\uc131\ub3c4\uc640 \uac19\uc774 JSP\uac00 View \uc601\uc5ed\ub9cc \ub2f4\ub2f9\ud55c\ub2e4\uba74 Model 2\ub77c\uace0 \ud55c\ub2e4. "),(0,a.kt)("mermaid",{value:"---\ntitle: JSP Model 2\n---\ngraph LR\n Client -- Request --\x3e Servlet <-- JDBC --\x3e Database\n\tServlet --\x3e Bean\n\tServlet --\x3e JSP\n\tBean <--\x3e JSP\n\tJSP -- Response --\x3e Client"}),(0,a.kt)("h3",{id:"mvc2000"},"MVC(2000)"),(0,a.kt)("p",null,"\uc704 JSP\uc758 \uad6c\uc131\ub3c4\ub97c \ubcf4\uba74 \ud604\uc7ac MVC\uc640 \ub9e4\uc6b0 \uc720\uc0ac\ud55c\ub370, Govind Seshadri\ub77c\ub294 \uc0ac\ub78c\uc774 JSP Model 2\ub97c MVC \ud328\ud134\uc73c\ub85c \uacf5\uc2dd\ud654\ub97c \uc81c\uc548\ud588\ub2e4. "),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.",(0,a.kt)("br",{parentName:"p"}),"\n","Govind Seshadri")),(0,a.kt)("p",null,"\uc774\ub54c MVC \ud328\ud134\uc774 \ucc98\uc74c \ud0c4\uc0dd\ud55c \uac83\uc740 \uc544\ub2c8\uace0, \uc11c\ubc84 \uce21 \uad6c\ud604\uc774\ub77c\uace0 \ud558\ub294 \uac83\uc744 \ubcf4\ub2c8 MVC\uac00 \ucc98\uc74c \ub4f1\uc7a5\ud55c \uac74 \uc544\ub2cc \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html"},"\ud574\ub2f9 \ubb38\uc11c"),"\ub97c \ubcf4\uba74 MVC\ub77c\ub294 \uc6a9\uc5b4\uc758 \ub4f1\uc7a5\uc740 1978\ub144\uc5d0 \ub4f1\uc7a5\ud55c \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4. "),(0,a.kt)("h3",{id:"spring-framework2003"},"Spring Framework(2003)"),(0,a.kt)("p",null,"Spring\uc740 \ubcf5\uc7a1\ud588\ub358 J2EE\uc744 \ub300\uccb4\ud558\uae30 \uc704\ud574 2003\ub144\uc5d0 \ub4f1\uc7a5\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","J2EE\ub294 \uc6f9 \uae30\ubc18\uc758 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\uae30 \uc704\ud55c \ud50c\ub7ab\ud3fc\uc73c\ub85c \uc704\uc5d0\uc11c \uc124\uba85\ud55c Servlet, JSP, EJB \ub4f1\uc758 \uae30\uc220\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uc774\uc911 EJB\ub77c\ub294 \uae30\uc220\uc774 J2EE\uc758 \ud575\uc2ec \uae30\uc220\uc774\uc5c8\ub294\ub370, \ud574\ub2f9 \uae30\uc220\uc774 \ub9e4\uc6b0 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub9ce\uc558\ub2e4\uace0 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","2002\ub144\uc5d0 Rod Johnson\uc774 EJB\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 J2EE \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc800\uc220\ud55c ",(0,a.kt)("inlineCode",{parentName:"p"},"Expert One-to-One J2EE Development"),"\ub77c\ub294 \ucc45\uc744 \ubc1c\ud589\ud588\uace0, \ucd9c\uac04 \ud6c4 Juergen Hoeller, Yann Caroff\uac00 Rod Johnson\uc5d0\uac8c \uc624\ud508\uc18c\uc2a4 \uc81c\uc548\uc744 \ud558\uc5ec \uc2a4\ud504\ub9c1\uc774 \ud0c4\uc0dd\ud588\ub2e4\uace0 \ud55c\ub2e4. "),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uc740 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\uba70, \uc774 \ub355\ubd84\uc5d0 \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"webflux-\uc774\uc804-servlet-302009-312013"},"WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)"),(0,a.kt)("p",null,"Tomcat\uc758 NIO \ub3d9\uc791 \ubc29\uc2dd\uc744 \ubcf4\uba74 Poller\uac00 \uc18c\ucf13 \ucee4\ub125\uc158\uc744 \ub4e4\uace0 \uc788\ub2e4\uac00 \ucc98\ub9ac\uac00 \uac00\ub2a5\ud560 \ub54c \uc2a4\ub808\ub4dc\ub97c \ud560\ub2f9\ud558\ub294 \uc2dd\uc73c\ub85c \ucc98\ub9ac\ub97c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ud560\ub2f9 \ud6c4 Servlet\uacfc \ud1b5\uc2e0\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \uc694\uccad\uc774 \ub05d\ub0a0 \ub54c\uae4c\uc9c0 \uc2a4\ub808\ub4dc\ub97c \uc810\uc720\ud558\uace0 \uc788\uc5c8\uace0, \uc2a4\ub808\ub4dc \uc810\uc720\ub85c \uc778\ud574 \uc694\uccad\uc774 max thread\uc5d0 \ub3c4\ub2ec\ud558\uba74 \uc694\uccad\uc744 \ucc98\ub9ac\ud560 \uc218 \uc5c6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub798\uc11c \ube44\ub3d9\uae30 \ubc29\uc2dd\uc758 Servlet\uc774 Servlet 3.0\uc5d0 \ub4f1\uc7a5\ud588\ub2e4. \ud558\uc9c0\ub9cc \uc804\ud1b5\uc801\uc778 I/O \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \ub3d9\uc791\ud588\ub2e4. Servlet 3.1\uc5d0\uc11c \ub17c\ube14\ub85c\ud0b9 I/O\uac00 \ucd94\uac00\ub418\uc5c8\uc9c0\ub9cc, \ub9ce\uc774 \uc0ac\uc6a9\ub418\uc9c0 \uc54a\uc558\ub2e4\uace0 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"spring-webflux2017"},"Spring WebFlux(2017)"),(0,a.kt)("p",null,"\uc801\uc740 \uc218\uc758 \uc2a4\ub808\ub4dc\ub85c \ub3d9\uc2dc\uc131\uc744 \ucc98\ub9ac\ud558\uace0, \uc801\uc740 \ub9ac\uc18c\uc2a4\ub85c \ud655\uc7a5\uc774 \uac00\ub2a5\ud55c \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd\uc758 \uc6f9 \uae30\uc220\uc774 \ud544\uc694\ud588\uace0, \uae30\uc874\uc758 Servlet\uc758 \uacbd\uc6b0 \ube44\ub3d9\uae30\ub97c \uc9c0\uc6d0\ud55c\ub2e4 \ud574\ub3c4 \ub3d9\uae30\uc2dd API\ub4e4\uc774 \ub9ce\uc774 \ub0a8\uc544\uc788\uc5c8\uae30 \ub54c\ubb38\uc5d0 \uc774\ub7ec\ud55c Servlet\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294 \uae30\uc220\uc774 \ud544\uc694\ud588\ub2e4. \ub610\ud55c \uae30\uc874\uc5d0 Netty\uc640 \uac19\uc774 \ube44\ub3d9\uae30, \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd \uc11c\ubc84\ub85c \uc790\ub9ac\ub97c \uc798 \uc7a1\uc740 \uc11c\ubc84\ub97c \uc704\ud574 Spring WebFlux\uac00 \ub4f1\uc7a5\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ub370\uc774\ud130 \uc811\uadfc\uc744 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 JDBC\uc758 \uacbd\uc6b0 Blocking API\ub77c, Spring Webflux\uc5d0\uc11c\ub294 R2DBC\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uace0 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ub9c8\uce58\uba70"},"\ub9c8\uce58\uba70"),(0,a.kt)("p",null,"\ud574\ub2f9 \uc815\ub9ac \ub0b4\uc6a9\uc758 \uacbd\uc6b0 Async, Non Blocking \uad00\ub828\ub41c \ub0b4\uc6a9\uc744 \uae4a\uac8c \uacf5\ubd80\ud55c \uc801\uc774 \uc5c6\uc5b4\uc11c \uc815\ud655\ud558\uc9c0 \uc54a\uc744 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub798\ub3c4 \uae30\uc220\uc758 \ub4f1\uc7a5 \ubc30\uacbd\uc774\ub098 \uacfc\uc815\uc744 \uc54c\uace0 \uc788\ub2e4\uba74 \uc870\uae08 \ub354 \uae4a\uc774 \uc788\ub294 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815, \uad6c\uad6c \uac15\uc758",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://httpd.apache.org/docs/trunk/en/howto/cgi.html"},"Dynamic Content with CGI, Apache Tutorial"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/reference/overview.html#overview-history"},"History of Spring and the Spring Framework, Spring"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.infoworld.com/article/2076557/understanding-javaserver-pages-model-2-architecture.html"},"Understanding JavaServer Pages Model 2 architecture, Govind Seshadri"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html"},"MVC, XEROX PARC"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.amazon.com/Expert-One-One-Development-without/dp/0764558315"},"Expert One-to-One J2EE Development, Rod Johnson"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/2667/"},"\ubc30\ub2ec\uc758\ubbfc\uc871 \ucd5c\uc804\ubc29 \uc2dc\uc2a4\ud15c! \u2018\uac00\uac8c\ub178\ucd9c \uc2dc\uc2a4\ud15c\u2019\uc744 \uc18c\uac1c\ud569\ub2c8\ub2e4, \ubc30\ub2ec\uc758\ubbfc\uc871"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.infoworld.com/article/2077995/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html"},"Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu"),"\n",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/reference/web/webflux/new-framework.html"},"WebFlux Overview, Spring"),"\n",(0,a.kt)("a",{parentName:"p",href:"https://d2.naver.com/helloworld/6080222"},"Spring WebFlux\uc640 Armeria\ub97c \uc774\uc6a9\ud558\uc5ec Microservice\uc5d0 \ud544\uc694\ud55c Reactive + RPC \ub3d9\uc2dc\uc5d0 \uc7a1\uae30, Naver D2"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://tweety1121.tistory.com/entry/Spring-WebFlux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C"},"Spring WebFlux\ub780 \ubb34\uc5c7\uc77c\uae4c")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ac3fdf5d.9c827f3a.js b/assets/js/ac3fdf5d.9c827f3a.js new file mode 100644 index 000000000..012aecad9 --- /dev/null +++ b/assets/js/ac3fdf5d.9c827f3a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8548],{40911:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>d,frontMatter:()=>l,metadata:()=>s,toc:()=>c});var t=n(85893),i=n(3905);const l={title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",slug:"web-application-evolution",tags:["web application"]},o=void 0,s={permalink:"/web-application-evolution",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",source:"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",description:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",date:"2023-09-30T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 30\uc77c",tags:[{label:"web application",permalink:"/tags/web-application"}],readingTime:7.5,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",slug:"web-application-evolution",tags:["web application"]},unlisted:!1,prevItem:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",permalink:"/spring-test-isolation"},nextItem:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",permalink:"/log-async-exception"}},a={authorsImageUrls:[]},c=[{value:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",level:3},{value:"WWW(1989)",id:"www1989",level:3},{value:"CGI(1993)",id:"cgi1993",level:3},{value:"Servlet(1996)",id:"servlet1996",level:3},{value:"JSP(1999)",id:"jsp1999",level:3},{value:"MVC(2000)",id:"mvc2000",level:3},{value:"Spring Framework(2003)",id:"spring-framework2003",level:3},{value:"WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)",id:"webflux-\uc774\uc804-servlet-302009-312013",level:3},{value:"Spring WebFlux(2017)",id:"spring-webflux2017",level:3},{value:"\ub9c8\uce58\uba70",id:"\ub9c8\uce58\uba70",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const r={a:"a",blockquote:"blockquote",br:"br",code:"code",h3:"h3",mermaid:"mermaid",p:"p",...(0,i.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.h3,{id:"\uc6f9-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\ubc1c\uc804-\uacfc\uc815",children:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815"}),"\n",(0,t.jsxs)(r.p,{children:["\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6d0\ub798 \ud68c\uace0\uc5d0 \uc791\uc131\ud558\ub824\uace0 \ud588\uc9c0\ub9cc, \uc815\ub9ac\ud558\ub2e4 \ubcf4\ub2c8 \uc870\uae08 \uae38\uc5b4\uc838\uc11c \ub530\ub85c \ubd84\ub9ac\ud588\ub2e4."]}),"\n",(0,t.jsx)(r.mermaid,{value:"graph LR\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking"}),"\n",(0,t.jsx)(r.h3,{id:"www1989",children:"WWW(1989)"}),"\n",(0,t.jsx)(r.p,{children:"\uc815\uc801 \ud398\uc774\uc9c0\ub97c \uc81c\uacf5\ud558\ub294 \uc6f9 \uc11c\ubc84\ub97c \uc2dc\uc791\uc73c\ub85c \ub3d9\uc801 \ud398\uc774\uc9c0\uac00 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 CGI\uac00 \ub4f1\uc7a5\ud588\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"cgi1993",children:"CGI(1993)"}),"\n",(0,t.jsx)(r.p,{children:"CGI\ub294 \ub3d9\uc801 \ucf58\ud150\uce20\ub97c \uc81c\uacf5\ud558\uae30 \uc704\ud55c \uaddc\uc57d\uc73c\ub85c, \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc774\uc6a9\ud574\uc11c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ucf1c \uc815\ubcf4\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ub9ce\uc740 \ubd80\ud558\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc774\ub7ec\ud55c \ub2e8\uc810\uc744 \uadf9\ubcf5\ud558\uae30 \uc704\ud574 \ub098\uc628 \uac83\uc774 Servlet\uc774\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"servlet1996",children:"Servlet(1996)"}),"\n",(0,t.jsxs)(r.p,{children:["Servlet\uc740 \uc6f9 \uc11c\ubc84\uc5d0\uc11c \uc2e4\ud589\ub418\ub294 \uc790\ubc14 \ud504\ub85c\uadf8\ub7a8\uc73c\ub85c HTTP\ub97c \uc774\uc6a9\ud558\uc5ec \uc6f9 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc744 \uc218\uc2e0\ud558\uace0 \uc751\ub2f5\ud55c\ub2e4. CGI\uc640 \ub2e4\ub974\uac8c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\uac00 \uc544\ub2cc \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uc5ec \uc751\ub2f5\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\uc9c0\ub9cc View \uc601\uc5ed\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uae30 \uc704\ud574 Servlet\uc758 \uc18c\uc2a4 \ucf54\ub4dc\ub97c \uc54c\uc544\uc57c \ud558\ub294 \ub4f1 \ubcf5\uc7a1\ub3c4\uac00 \ub108\ubb34 \ub192\uc558\ub2e4. \ub530\ub77c\uc11c \ud574\ub2f9 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 JSP\uac00 \ub4f1\uc7a5\ud588\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"jsp1999",children:"JSP(1999)"}),"\n",(0,t.jsxs)(r.p,{children:["JSP\ub294 HTML\uc5d0 \uc790\ubc14 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ub3d9\uc801 \uc6f9 \ud398\uc774\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\uc220\ub85c, \uc720\uc0ac\ud55c \uae30\uc220\ub85c\ub294 ASP, PHP\uac00 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","JSP\ub9cc \uc0ac\uc6a9\ud558\uc5ec \ud504\ub85c\uadf8\ub798\ubc0d\ud55c\ub2e4\uba74 Model 1, \uc544\ub798 \uad6c\uc131\ub3c4\uc640 \uac19\uc774 JSP\uac00 View \uc601\uc5ed\ub9cc \ub2f4\ub2f9\ud55c\ub2e4\uba74 Model 2\ub77c\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.mermaid,{value:"---\ntitle: JSP Model 2\n---\ngraph LR\n Client -- Request --\x3e Servlet <-- JDBC --\x3e Database\n\tServlet --\x3e Bean\n\tServlet --\x3e JSP\n\tBean <--\x3e JSP\n\tJSP -- Response --\x3e Client"}),"\n",(0,t.jsx)(r.h3,{id:"mvc2000",children:"MVC(2000)"}),"\n",(0,t.jsx)(r.p,{children:"\uc704 JSP\uc758 \uad6c\uc131\ub3c4\ub97c \ubcf4\uba74 \ud604\uc7ac MVC\uc640 \ub9e4\uc6b0 \uc720\uc0ac\ud55c\ub370, Govind Seshadri\ub77c\ub294 \uc0ac\ub78c\uc774 JSP Model 2\ub97c MVC \ud328\ud134\uc73c\ub85c \uacf5\uc2dd\ud654\ub97c \uc81c\uc548\ud588\ub2e4."}),"\n",(0,t.jsxs)(r.blockquote,{children:["\n",(0,t.jsxs)(r.p,{children:["I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.",(0,t.jsx)(r.br,{}),"\n","Govind Seshadri"]}),"\n"]}),"\n",(0,t.jsxs)(r.p,{children:["\uc774\ub54c MVC \ud328\ud134\uc774 \ucc98\uc74c \ud0c4\uc0dd\ud55c \uac83\uc740 \uc544\ub2c8\uace0, \uc11c\ubc84 \uce21 \uad6c\ud604\uc774\ub77c\uace0 \ud558\ub294 \uac83\uc744 \ubcf4\ub2c8 MVC\uac00 \ucc98\uc74c \ub4f1\uc7a5\ud55c \uac74 \uc544\ub2cc \uac83 \uac19\ub2e4.",(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html",children:"\ud574\ub2f9 \ubb38\uc11c"}),"\ub97c \ubcf4\uba74 MVC\ub77c\ub294 \uc6a9\uc5b4\uc758 \ub4f1\uc7a5\uc740 1978\ub144\uc5d0 \ub4f1\uc7a5\ud55c \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"spring-framework2003",children:"Spring Framework(2003)"}),"\n",(0,t.jsxs)(r.p,{children:["Spring\uc740 \ubcf5\uc7a1\ud588\ub358 J2EE\uc744 \ub300\uccb4\ud558\uae30 \uc704\ud574 2003\ub144\uc5d0 \ub4f1\uc7a5\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","J2EE\ub294 \uc6f9 \uae30\ubc18\uc758 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\uae30 \uc704\ud55c \ud50c\ub7ab\ud3fc\uc73c\ub85c \uc704\uc5d0\uc11c \uc124\uba85\ud55c Servlet, JSP, EJB \ub4f1\uc758 \uae30\uc220\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud558\uc9c0\ub9cc \uc774\uc911 EJB\ub77c\ub294 \uae30\uc220\uc774 J2EE\uc758 \ud575\uc2ec \uae30\uc220\uc774\uc5c8\ub294\ub370, \ud574\ub2f9 \uae30\uc220\uc774 \ub9e4\uc6b0 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub9ce\uc558\ub2e4\uace0 \ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","2002\ub144\uc5d0 Rod Johnson\uc774 EJB\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 J2EE \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc800\uc220\ud55c ",(0,t.jsx)(r.code,{children:"Expert One-to-One J2EE Development"}),"\ub77c\ub294 \ucc45\uc744 \ubc1c\ud589\ud588\uace0, \ucd9c\uac04 \ud6c4 Juergen Hoeller, Yann Caroff\uac00 Rod Johnson\uc5d0\uac8c \uc624\ud508\uc18c\uc2a4 \uc81c\uc548\uc744 \ud558\uc5ec \uc2a4\ud504\ub9c1\uc774 \ud0c4\uc0dd\ud588\ub2e4\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:"\uc2a4\ud504\ub9c1\uc740 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\uba70, \uc774 \ub355\ubd84\uc5d0 \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"webflux-\uc774\uc804-servlet-302009-312013",children:"WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)"}),"\n",(0,t.jsxs)(r.p,{children:["Tomcat\uc758 NIO \ub3d9\uc791 \ubc29\uc2dd\uc744 \ubcf4\uba74 Poller\uac00 \uc18c\ucf13 \ucee4\ub125\uc158\uc744 \ub4e4\uace0 \uc788\ub2e4\uac00 \ucc98\ub9ac\uac00 \uac00\ub2a5\ud560 \ub54c \uc2a4\ub808\ub4dc\ub97c \ud560\ub2f9\ud558\ub294 \uc2dd\uc73c\ub85c \ucc98\ub9ac\ub97c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ud560\ub2f9 \ud6c4 Servlet\uacfc \ud1b5\uc2e0\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \uc694\uccad\uc774 \ub05d\ub0a0 \ub54c\uae4c\uc9c0 \uc2a4\ub808\ub4dc\ub97c \uc810\uc720\ud558\uace0 \uc788\uc5c8\uace0, \uc2a4\ub808\ub4dc \uc810\uc720\ub85c \uc778\ud574 \uc694\uccad\uc774 max thread\uc5d0 \ub3c4\ub2ec\ud558\uba74 \uc694\uccad\uc744 \ucc98\ub9ac\ud560 \uc218 \uc5c6\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uadf8\ub798\uc11c \ube44\ub3d9\uae30 \ubc29\uc2dd\uc758 Servlet\uc774 Servlet 3.0\uc5d0 \ub4f1\uc7a5\ud588\ub2e4. \ud558\uc9c0\ub9cc \uc804\ud1b5\uc801\uc778 I/O \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \ub3d9\uc791\ud588\ub2e4. Servlet 3.1\uc5d0\uc11c \ub17c\ube14\ub85c\ud0b9 I/O\uac00 \ucd94\uac00\ub418\uc5c8\uc9c0\ub9cc, \ub9ce\uc774 \uc0ac\uc6a9\ub418\uc9c0 \uc54a\uc558\ub2e4\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"spring-webflux2017",children:"Spring WebFlux(2017)"}),"\n",(0,t.jsxs)(r.p,{children:["\uc801\uc740 \uc218\uc758 \uc2a4\ub808\ub4dc\ub85c \ub3d9\uc2dc\uc131\uc744 \ucc98\ub9ac\ud558\uace0, \uc801\uc740 \ub9ac\uc18c\uc2a4\ub85c \ud655\uc7a5\uc774 \uac00\ub2a5\ud55c \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd\uc758 \uc6f9 \uae30\uc220\uc774 \ud544\uc694\ud588\uace0, \uae30\uc874\uc758 Servlet\uc758 \uacbd\uc6b0 \ube44\ub3d9\uae30\ub97c \uc9c0\uc6d0\ud55c\ub2e4 \ud574\ub3c4 \ub3d9\uae30\uc2dd API\ub4e4\uc774 \ub9ce\uc774 \ub0a8\uc544\uc788\uc5c8\uae30 \ub54c\ubb38\uc5d0 \uc774\ub7ec\ud55c Servlet\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294 \uae30\uc220\uc774 \ud544\uc694\ud588\ub2e4. \ub610\ud55c \uae30\uc874\uc5d0 Netty\uc640 \uac19\uc774 \ube44\ub3d9\uae30, \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd \uc11c\ubc84\ub85c \uc790\ub9ac\ub97c \uc798 \uc7a1\uc740 \uc11c\ubc84\ub97c \uc704\ud574 Spring WebFlux\uac00 \ub4f1\uc7a5\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ucd94\uac00\ub85c \ub370\uc774\ud130 \uc811\uadfc\uc744 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 JDBC\uc758 \uacbd\uc6b0 Blocking API\ub77c, Spring Webflux\uc5d0\uc11c\ub294 R2DBC\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ub9c8\uce58\uba70",children:"\ub9c8\uce58\uba70"}),"\n",(0,t.jsxs)(r.p,{children:["\ud574\ub2f9 \uc815\ub9ac \ub0b4\uc6a9\uc758 \uacbd\uc6b0 Async, Non Blocking \uad00\ub828\ub41c \ub0b4\uc6a9\uc744 \uae4a\uac8c \uacf5\ubd80\ud55c \uc801\uc774 \uc5c6\uc5b4\uc11c \uc815\ud655\ud558\uc9c0 \uc54a\uc744 \uc218 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uadf8\ub798\ub3c4 \uae30\uc220\uc758 \ub4f1\uc7a5 \ubc30\uacbd\uc774\ub098 \uacfc\uc815\uc744 \uc54c\uace0 \uc788\ub2e4\uba74 \uc870\uae08 \ub354 \uae4a\uc774 \uc788\ub294 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(r.p,{children:["\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815, \uad6c\uad6c \uac15\uc758",(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://httpd.apache.org/docs/trunk/en/howto/cgi.html",children:"Dynamic Content with CGI, Apache Tutorial"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://docs.spring.io/spring-framework/reference/overview.html#overview-history",children:"History of Spring and the Spring Framework, Spring"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://www.infoworld.com/article/2076557/understanding-javaserver-pages-model-2-architecture.html",children:"Understanding JavaServer Pages Model 2 architecture, Govind Seshadri"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html",children:"MVC, XEROX PARC"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://www.amazon.com/Expert-One-One-Development-without/dp/0764558315",children:"Expert One-to-One J2EE Development, Rod Johnson"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://techblog.woowahan.com/2667/",children:"\ubc30\ub2ec\uc758\ubbfc\uc871 \ucd5c\uc804\ubc29 \uc2dc\uc2a4\ud15c! \u2018\uac00\uac8c\ub178\ucd9c \uc2dc\uc2a4\ud15c\u2019\uc744 \uc18c\uac1c\ud569\ub2c8\ub2e4, \ubc30\ub2ec\uc758\ubbfc\uc871"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://www.infoworld.com/article/2077995/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html",children:"Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu"}),"\n",(0,t.jsx)(r.a,{href:"https://docs.spring.io/spring-framework/reference/web/webflux/new-framework.html",children:"WebFlux Overview, Spring"}),"\n",(0,t.jsx)(r.a,{href:"https://d2.naver.com/helloworld/6080222",children:"Spring WebFlux\uc640 Armeria\ub97c \uc774\uc6a9\ud558\uc5ec Microservice\uc5d0 \ud544\uc694\ud55c Reactive + RPC \ub3d9\uc2dc\uc5d0 \uc7a1\uae30, Naver D2"}),(0,t.jsx)(r.br,{}),"\n",(0,t.jsx)(r.a,{href:"https://tweety1121.tistory.com/entry/Spring-WebFlux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C",children:"Spring WebFlux\ub780 \ubb34\uc5c7\uc77c\uae4c"})]})]})}function d(e={}){const{wrapper:r}={...(0,i.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>c});var t=n(67294);function i(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function l(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function o(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?l(Object(n),!0).forEach((function(r){i(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function s(e,r){if(null==e)return{};var n,t,i=function(e,r){if(null==e)return{};var n,t,i={},l=Object.keys(e);for(t=0;t<l.length;t++)n=l[t],r.indexOf(n)>=0||(i[n]=e[n]);return i}(e,r);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(t=0;t<l.length;t++)n=l[t],r.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var a=t.createContext({}),c=function(e){var r=t.useContext(a),n=r;return e&&(n="function"==typeof e?e(r):o(o({},r),e)),n},p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},d=t.forwardRef((function(e,r){var n=e.components,i=e.mdxType,l=e.originalType,a=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),h=c(n),u=i,x=h["".concat(a,".").concat(u)]||h[u]||p[u]||l;return n?t.createElement(x,o(o({ref:r},d),{},{components:n})):t.createElement(x,o({ref:r},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/ad3b7b62.a08f7c0f.js b/assets/js/ad3b7b62.a08f7c0f.js deleted file mode 100644 index 8b18be79f..000000000 --- a/assets/js/ad3b7b62.a08f7c0f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[26],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>g});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),i=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=i(e.components);return n.createElement(c.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,c=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=i(r),g=a,b=m["".concat(c,".").concat(g)]||m[g]||u[g]||p;return r?n.createElement(b,o(o({ref:t},s),{},{components:r})):n.createElement(b,o({ref:t},s))}));function g(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=m;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var i=2;i<p;i++)o[i]=r[i];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},55097:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>p,metadata:()=>l,toc:()=>i});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",slug:"shopping-cart-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,l={permalink:"/shopping-cart-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-shopping-cart/pull/244",date:"2023-05-12T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 12\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.845,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",slug:"shopping-cart-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",permalink:"/accidental-duplication"},nextItem:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",permalink:"/web-racing-car-retrospective"}},c={authorsImageUrls:[]},i=[{value:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158",id:"\uc6f9-\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],s={toc:i};function u(e){let{components:t,...p}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,p,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-shopping-cart/pull/244"},"https://github.com/woowacourse/jwp-shopping-cart/pull/244"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-shopping-cart/pull/300"},"https://github.com/woowacourse/jwp-shopping-cart/pull/300")," ")),(0,a.kt)("h3",{id:"\uc6f9-\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158"},"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158"),(0,a.kt)("p",null,"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc740 \ube14\ub799\ucea3\uc774\ub791 \uc9c4\ud589\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uad6c\uc0ac\ud56d\uc774 \uc5c4\uccad \ubcf5\uc7a1\ud55c \ubbf8\uc158\uc740 \uc544\ub2c8\uc5c8\uace0, \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \uae30\ubcf8\uc801\uc778 CRUD\ub97c \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4\uc5d0\uc11c\ub294 Basic \uc778\uc99d\uc744 \ud1b5\ud574 \uc790\uc2e0\uc758 \uc7a5\ubc14\uad6c\ub2c8\uc5d0\ub9cc \uc0c1\ud488\uc744 \ub2f4\uace0, \uc81c\uac70\ud560 \uc218 \uc788\ub3c4\ub85d \uad6c\ud604\ud558\ub294 \uc694\uad6c\uc0ac\ud56d\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Interceptor\ub098 Argument Resolver\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\uac00 \ub192\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc870\uae08 \ub354 \uc54c\uc544\uac04 \ub290\ub08c\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804\uc5d0 \uc2a4\ud504\ub9c1 \uc0ac\uc6a9\ud560 \ub54c\ub294 \uc544\ubb34 \uc0dd\uac01 \uc5c6\uc774 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub294\ub370, \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \ub54c \uadfc\uac70\uac00 \uc0dd\uae30\uace0 \uc788\ub294 \uac83 \uac19\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"DTO \uc6b0\ubc1c\uc801 \uc911\ubcf5")),(0,a.kt)("p",null,"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"dto1",src:r(33946).Z,width:"2028",height:"704"})),(0,a.kt)("p",null,"\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d \ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0 \uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\uc744 \ud588\uace0, \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec \uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"\uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4.")),(0,a.kt)("p",null,"\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131 \uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ub9ac\ubdf0\uc5b4 \uc6e8\uc9c0\uac00 \uc544\ub798\uc640 \uac19\uc774 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\uace0 \uc54c\ub824\uc8fc\uc168\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"dto2",src:r(15907).Z,width:"1508",height:"896"})),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Interceptor\uc5d0\uc11c \uc778\uc99d\ud55c \uac12 \uc7ac\uc0ac\uc6a9")),(0,a.kt)("p",null,"\uc0ac\uc2e4 \uc870\ud68c\ub97c \ub450 \ubc88 \ud558\uae30 \uc2eb\uc5b4\uc11c \ub2e4\uc591\ud55c \ubc29\ubc95\uc744 \uc0dd\uac01\ud588\uc5c8\ub294\ub370 \uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 ThreadLocal\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ub2e8 Tomcat\uc740 \uc694\uccad\ub9c8\ub2e4 \ub2e4\ub978 \uc2a4\ub808\ub4dc\ub97c \uc0ac\uc6a9\ud558\uace0, Interceptor\uc5d0\uc11c \uc870\ud68c\ud574\uc11c \ub9cc\ub4e0 Credential\uc744 ThreadLocal\uc5d0 \ub123\uc5b4\ub450\uc5c8\ub2e4\uac00 ArgumentResolver\uc5d0\uc11c \uaebc\ub0b8 \ub2e4\uc74c ThreadLocal\uc744 clear \ud558\uba74 \ubb38\uc81c\uac00 \uc5c6\uc744 \uac70\ub77c \ud310\ub2e8\ud588\ub2e4. "),(0,a.kt)("p",null,"\ub9ac\ubdf0\uc5b4\uc778 \uc6e8\uc9c0\uc5d0\uac8c\ub3c4 \uc5b4\ub5a4 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560\uc9c0 \uad81\uae08\uc99d\uc744 \uc791\uc131\ud588\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6e8\uc9c0\ub294 email\uc5d0 index\ub97c \uac78\uc5b4\ub450\uace0 dao \uc7ac\uc870\ud68c\ub97c \uc0ac\uc6a9\ud560 \uac83\uc774\ub77c\uace0 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc7ac\uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 db\uc5d0 \uc778\ub371\uc2a4\ub97c \uac78 \uc0dd\uac01\uc740 \ud558\uc9c0 \ubabb\ud588\ub294\ub370, \uc81c\uc77c \uc9c1\uad00\uc801\uc774\uace0 \uc88b\uc740 \ubc29\ubc95\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uae30\ub85d")),(0,a.kt)("p",null,"\ube14\ub799\ucea3\uc740 \uae30\ub85d\uc744 \uad49\uc7a5\ud788 \uc798 \ud558\ub294 \ud06c\ub8e8\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub178\uc158\uc5d0 \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ud588\ub358 \ub0b4\uc6a9 + \uace0\ubbfc\ud588\ub358 \ubd80\ubd84 + \ud68c\uace0\ub97c \uaf3c\uaf3c\ud558\uac8c \uae30\ub85d\ud574\uc11c \uacf5\uc720\ud574 \uc8fc\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\uc801\uc73c\ub85c \uc774\ubaa8\uc9c0\ub97c \uc801\uadf9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\uc5ec \ub354\uc6b1 \uc88b\uc558\ub2e4!"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc758\uacac \uc77c\uce58\uc2dc\ud0a4\uae30")),(0,a.kt)("p",null,"\ud398\uc5b4 \uc2dc\uac04\uc740 \ud55c\uc815\ub418\uc5b4 \uc788\uace0, \uae30\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc801\ub2f9\ud788 \ud0c0\ud611\uc744 \ubd10\uc11c \uc758\uacac\uc744 \ube60\ub974\uac8c \uc218\uc6a9\ud574 \ub370\ub4dc\ub77c\uc778\uc744 \ub9de\ucd94\ub294 \uac83\ub3c4 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube14\ub799\ucea3\uc740 \ub0b4 \uc758\uacac\uc744 \uc798 \ub4e4\uc5b4\uc92c\uace0, \ub355\ubd84\uc5d0 \ub9c9\ud788\ub294 \ubd80\ubd84 \uc5c6\uc774 \ube60\ub974\uac8c \ubbf8\uc158\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ube68\ub9ac \uce5c\ud574\uc84c\uace0, \uc758\uc0ac\uc18c\ud1b5\uc774 \uc798 \ub3fc\uc11c \uc7ac\ubc0c\uac8c \ucf54\ub529\ud560 \uc218 \uc788\uc5c8\ub2e4!"))}u.isMDXComponent=!0},33946:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/dto1-ccd4f91674b224578f2b295b3fccaf2c.png"},15907:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/dto2-15b381e0a024487f54608d438e5385f9.png"}}]); \ No newline at end of file diff --git a/assets/js/ad3b7b62.f8707eac.js b/assets/js/ad3b7b62.f8707eac.js new file mode 100644 index 000000000..f6c42c2ef --- /dev/null +++ b/assets/js/ad3b7b62.f8707eac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[26],{76556:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var n=t(85893),s=t(3905);const o={title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",slug:"shopping-cart-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,i={permalink:"/shopping-cart-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-shopping-cart/pull/244",date:"2023-05-12T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 12\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.845,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",slug:"shopping-cart-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",permalink:"/accidental-duplication"},nextItem:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",permalink:"/web-racing-car-retrospective"}},a={authorsImageUrls:[]},l=[{value:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158",id:"\uc6f9-\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function p(e){const r={a:"a",admonition:"admonition",br:"br",h3:"h3",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,n.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-shopping-cart/pull/244",children:"https://github.com/woowacourse/jwp-shopping-cart/pull/244"}),(0,n.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,n.jsx)(r.a,{href:"https://github.com/woowacourse/jwp-shopping-cart/pull/300",children:"https://github.com/woowacourse/jwp-shopping-cart/pull/300"})]})}),"\n",(0,n.jsx)(r.h3,{id:"\uc6f9-\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158",children:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158"}),"\n",(0,n.jsxs)(r.p,{children:["\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc740 \ube14\ub799\ucea3\uc774\ub791 \uc9c4\ud589\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc694\uad6c\uc0ac\ud56d\uc774 \uc5c4\uccad \ubcf5\uc7a1\ud55c \ubbf8\uc158\uc740 \uc544\ub2c8\uc5c8\uace0, \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \uae30\ubcf8\uc801\uc778 CRUD\ub97c \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","2\ub2e8\uacc4\uc5d0\uc11c\ub294 Basic \uc778\uc99d\uc744 \ud1b5\ud574 \uc790\uc2e0\uc758 \uc7a5\ubc14\uad6c\ub2c8\uc5d0\ub9cc \uc0c1\ud488\uc744 \ub2f4\uace0, \uc81c\uac70\ud560 \uc218 \uc788\ub3c4\ub85d \uad6c\ud604\ud558\ub294 \uc694\uad6c\uc0ac\ud56d\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","Interceptor\ub098 Argument Resolver\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\uac00 \ub192\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc870\uae08 \ub354 \uc54c\uc544\uac04 \ub290\ub08c\uc774\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc774\uc804\uc5d0 \uc2a4\ud504\ub9c1 \uc0ac\uc6a9\ud560 \ub54c\ub294 \uc544\ubb34 \uc0dd\uac01 \uc5c6\uc774 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub294\ub370, \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \ub54c \uadfc\uac70\uac00 \uc0dd\uae30\uace0 \uc788\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.strong,{children:"DTO \uc6b0\ubc1c\uc801 \uc911\ubcf5"})}),"\n",(0,n.jsx)(r.p,{children:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4."}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.img,{alt:"dto1",src:t(33946).Z+"",width:"2028",height:"704"})}),"\n",(0,n.jsxs)(r.p,{children:["\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d \ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0 \uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\uc744 \ud588\uace0, \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec \uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4."]}),"\n",(0,n.jsxs)(r.ul,{children:["\n",(0,n.jsx)(r.li,{children:"\uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,n.jsx)(r.li,{children:"\uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4."}),"\n"]}),"\n",(0,n.jsxs)(r.p,{children:["\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131 \uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub530\ub77c\uc11c \ub9ac\ubdf0\uc5b4 \uc6e8\uc9c0\uac00 \uc544\ub798\uc640 \uac19\uc774 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\uace0 \uc54c\ub824\uc8fc\uc168\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.img,{alt:"dto2",src:t(15907).Z+"",width:"1508",height:"896"})}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.strong,{children:"Interceptor\uc5d0\uc11c \uc778\uc99d\ud55c \uac12 \uc7ac\uc0ac\uc6a9"})}),"\n",(0,n.jsxs)(r.p,{children:["\uc0ac\uc2e4 \uc870\ud68c\ub97c \ub450 \ubc88 \ud558\uae30 \uc2eb\uc5b4\uc11c \ub2e4\uc591\ud55c \ubc29\ubc95\uc744 \uc0dd\uac01\ud588\uc5c8\ub294\ub370 \uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 ThreadLocal\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc77c\ub2e8 Tomcat\uc740 \uc694\uccad\ub9c8\ub2e4 \ub2e4\ub978 \uc2a4\ub808\ub4dc\ub97c \uc0ac\uc6a9\ud558\uace0, Interceptor\uc5d0\uc11c \uc870\ud68c\ud574\uc11c \ub9cc\ub4e0 Credential\uc744 ThreadLocal\uc5d0 \ub123\uc5b4\ub450\uc5c8\ub2e4\uac00 ArgumentResolver\uc5d0\uc11c \uaebc\ub0b8 \ub2e4\uc74c ThreadLocal\uc744 clear \ud558\uba74 \ubb38\uc81c\uac00 \uc5c6\uc744 \uac70\ub77c \ud310\ub2e8\ud588\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ub9ac\ubdf0\uc5b4\uc778 \uc6e8\uc9c0\uc5d0\uac8c\ub3c4 \uc5b4\ub5a4 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560\uc9c0 \uad81\uae08\uc99d\uc744 \uc791\uc131\ud588\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc6e8\uc9c0\ub294 email\uc5d0 index\ub97c \uac78\uc5b4\ub450\uace0 dao \uc7ac\uc870\ud68c\ub97c \uc0ac\uc6a9\ud560 \uac83\uc774\ub77c\uace0 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc7ac\uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 db\uc5d0 \uc778\ub371\uc2a4\ub97c \uac78 \uc0dd\uac01\uc740 \ud558\uc9c0 \ubabb\ud588\ub294\ub370, \uc81c\uc77c \uc9c1\uad00\uc801\uc774\uace0 \uc88b\uc740 \ubc29\ubc95\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.strong,{children:"\uae30\ub85d"})}),"\n",(0,n.jsxs)(r.p,{children:["\ube14\ub799\ucea3\uc740 \uae30\ub85d\uc744 \uad49\uc7a5\ud788 \uc798 \ud558\ub294 \ud06c\ub8e8\uc600\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub178\uc158\uc5d0 \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ud588\ub358 \ub0b4\uc6a9 + \uace0\ubbfc\ud588\ub358 \ubd80\ubd84 + \ud68c\uace0\ub97c \uaf3c\uaf3c\ud558\uac8c \uae30\ub85d\ud574\uc11c \uacf5\uc720\ud574 \uc8fc\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ucd94\uac00\uc801\uc73c\ub85c \uc774\ubaa8\uc9c0\ub97c \uc801\uadf9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\uc5ec \ub354\uc6b1 \uc88b\uc558\ub2e4!"]}),"\n",(0,n.jsx)(r.p,{children:(0,n.jsx)(r.strong,{children:"\uc758\uacac \uc77c\uce58\uc2dc\ud0a4\uae30"})}),"\n",(0,n.jsxs)(r.p,{children:["\ud398\uc5b4 \uc2dc\uac04\uc740 \ud55c\uc815\ub418\uc5b4 \uc788\uace0, \uae30\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574\uc57c \ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub530\ub77c\uc11c \uc801\ub2f9\ud788 \ud0c0\ud611\uc744 \ubd10\uc11c \uc758\uacac\uc744 \ube60\ub974\uac8c \uc218\uc6a9\ud574 \ub370\ub4dc\ub77c\uc778\uc744 \ub9de\ucd94\ub294 \uac83\ub3c4 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ube14\ub799\ucea3\uc740 \ub0b4 \uc758\uacac\uc744 \uc798 \ub4e4\uc5b4\uc92c\uace0, \ub355\ubd84\uc5d0 \ub9c9\ud788\ub294 \ubd80\ubd84 \uc5c6\uc774 \ube60\ub974\uac8c \ubbf8\uc158\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:"\ube68\ub9ac \uce5c\ud574\uc84c\uace0, \uc758\uc0ac\uc18c\ud1b5\uc774 \uc798 \ub3fc\uc11c \uc7ac\ubc0c\uac8c \ucf54\ub529\ud560 \uc218 \uc788\uc5c8\ub2e4!"})]})}function h(e={}){const{wrapper:r}={...(0,s.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>l});var n=t(67294);function s(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function c(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){s(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function i(e,r){if(null==e)return{};var t,n,s=function(e,r){if(null==e)return{};var t,n,s={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(s[t]=e[t]);return s}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(s[t]=e[t])}return s}var a=n.createContext({}),l=function(e){var r=n.useContext(a),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},p={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},h=n.forwardRef((function(e,r){var t=e.components,s=e.mdxType,o=e.originalType,a=e.parentName,h=i(e,["components","mdxType","originalType","parentName"]),d=l(t),u=s,j=d["".concat(a,".").concat(u)]||d[u]||p[u]||o;return t?n.createElement(j,c(c({ref:r},h),{},{components:t})):n.createElement(j,c({ref:r},h))}));h.displayName="MDXCreateElement"},33946:(e,r,t)=>{t.d(r,{Z:()=>n});const n=t.p+"assets/images/dto1-ccd4f91674b224578f2b295b3fccaf2c.png"},15907:(e,r,t)=>{t.d(r,{Z:()=>n});const n=t.p+"assets/images/dto2-15b381e0a024487f54608d438e5385f9.png"}}]); \ No newline at end of file diff --git a/assets/js/ae82353f.265ad54c.js b/assets/js/ae82353f.265ad54c.js deleted file mode 100644 index a2ecc3254..000000000 --- a/assets/js/ae82353f.265ad54c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6420],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},T=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),T=c(n),m=a,d=T["".concat(l,".").concat(m)]||T[m]||u[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=T;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:a,o[1]=s;for(var c=2;c<i;c++)o[c]=n[c];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}T.displayName="MDXCreateElement"},49968:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const i={title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",slug:"spring-test-isolation",tags:["test"]},o=void 0,s={permalink:"/spring-test-isolation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",source:"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",description:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac",date:"2023-10-03T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 3\uc77c",tags:[{label:"test",permalink:"/tags/test"}],readingTime:4.315,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",slug:"spring-test-isolation",tags:["test"]},prevItem:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/mvc-retrospective"},nextItem:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",permalink:"/web-application-evolution"}},l={authorsImageUrls:[]},c=[{value:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac",id:"\ud14c\uc2a4\ud2b8-\uaca9\ub9ac",level:3},{value:"TestExecutionListener",id:"testexecutionlistener",level:3},{value:"AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604",id:"abstracttestexecutionlistener-\uc0c1\uc18d\ud558\uc5ec-\uad6c\ud604",level:3},{value:"Listener \ub4f1\ub85d",id:"listener-\ub4f1\ub85d",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ud14c\uc2a4\ud2b8-\uaca9\ub9ac"},"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac"),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8\uc758 \uc21c\uc11c\uc5d0 \ub530\ub77c \uc131\uacf5 \uc2e4\ud328 \uc5ec\ubd80\uac00 \uacb0\uc815\ub418\ub294 \ube44\uacb0\uc815\uc801\uc778(non-determinism) \ud14c\uc2a4\ud2b8\uac00 \ub418\uc5b4\uc11c\ub294 \uc548\ub418\uace0, \ud14c\uc2a4\ud2b8\ub294 \ud56d\uc0c1 \uc21c\uc11c\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc218\ud589\ub418\ub3c4\ub85d \ubcf4\uc7a5\ub418\uc5b4\uc57c \ud55c\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \uc790\uc6d0\uc758 \uacf5\uc720, \uc678\ubd80 API, \uc2dc\uac04 \ub4f1\uc73c\ub85c \ube44\uacb0\uc815\uc801\uc778 \ud14c\uc2a4\ud2b8\uac00 \ub41c\ub2e4. \uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \uc0ac\uc6a9\ud558\uac70\ub098, \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc7ac\uc2e4\ud589\ud558\ub294 ",(0,a.kt)("inlineCode",{parentName:"p"},"@DirtiesContext"),", \uc790\uc6d0\uc744 \ucd08\uae30\ud654\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uc774\ud6c4\uc5d0 \ud14c\uc774\ube14\uc744 \ub864\ubc31 \ud558\ub294 ",(0,a.kt)("inlineCode",{parentName:"p"},"@Transactional"),"\ub4f1 \ub2e4\uc591\ud55c \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uae00\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc5d0\uc11c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc790\uc6d0\uc758 \uacf5\uc720\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc218\ud589\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc124\uba85\ud55c\ub2e4. "),(0,a.kt)("admonition",{title:"Independent - FIRST",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ud14c\uc2a4\ud2b8\ub07c\ub9ac \uc11c\ub85c \uc758\uc874\ud558\uba74 \uc548 \ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc11c\ub85c \uc758\uc874\ud558\uac8c \ub41c\ub2e4\uba74 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \ub54c, \ub610 \ub2e4\ub978 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589 \uac00\ub2a5\ud55c \ud14c\uc2a4\ud2b8\uac00 \uc88b\uc740 \ud14c\uc2a4\ud2b8\ub2e4. ")),(0,a.kt)("h3",{id:"testexecutionlistener"},"TestExecutionListener"),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 TextExecutionListner\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 \ud14c\uc2a4\ud2b8 \uc2e4\ud589 \ub2e8\uacc4\uc5d0\uc11c \uc774\ubca4\ud2b8\ub97c \uc218\uc2e0\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c \uc774\uc6a9\ud558\uba74 JUnit\uc758 @BeforeEach\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uacfc \uc720\uc0ac\ud558\uac8c, \ud14c\uc2a4\ud2b8\uc758 \uc0dd\uba85\uc8fc\uae30 \uc774\uc804 \ub610\ub294 \uc774\ud6c4\uc5d0 \ud544\uc694\ud55c \uc791\uc5c5\uc744 \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=TextExecutionListner",title:"TextExecutionListner"},"public interface TestExecutionListener {\n default void beforeTestClass(TestContext testContext) throws Exception {}\n default void prepareTestInstance(TestContext testContext) throws Exception {}\n default void beforeTestMethod(TestContext testContext) throws Exception {}\n default void beforeTestExecution(TestContext testContext) throws Exception {}\n default void afterTestExecution(TestContext testContext) throws Exception {}\n default void afterTestMethod(TestContext testContext) throws Exception {}\n default void afterTestClass(TestContext testContext) throws Exception {}\n}\n")),(0,a.kt)("h3",{id:"abstracttestexecutionlistener-\uc0c1\uc18d\ud558\uc5ec-\uad6c\ud604"},"AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604"),(0,a.kt)("p",null,"AbstractTestExecutionListener\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac \ud658\uacbd\uc744 \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \ud074\ub798\uc2a4\ub85c, \uc778\ud130\ud398\uc774\uc2a4\uc778 TextExecutionListner\uc640 \ub2ec\ub9ac Ordered\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc5b4 \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ubc1b\uc544 \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub294 \ud504\ub808\uc784\uc6cc\ud06c\uac00 \uc81c\uacf5\ud558\ub294 \ub9ac\uc2a4\ub108 \ub2e4\uc74c\uc5d0 \uc2e4\ud589\uc2dc\ud0a4\ub3c4\ub85d \ud574\uc900\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c\uacfc \uac19\uc774 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac01\uac01\uc758 \ud14c\uc774\ube14\uc5d0 \ud574\ub2f9\ud558\ub294 Truncate \ucffc\ub9ac\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc870\ud68c\ud558\uace0, Test \uba54\uc11c\ub4dc\uac00 \ub05d\ub0a0\ub54c \ub9c8\ub2e4 \ud574\ub2f9 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uc5ec \ud14c\uc774\ube14\uc744 \ucd08\uae30\ud654\uc2dc\ud0a4\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=DatabaseCleaner",title:"DatabaseCleaner"},'\npublic class DatabaseCleaner extends AbstractTestExecutionListener {\n\n private static final String TRUNCATE_TABLE_QUERY = """\n SELECT Concat(\'TRUNCATE TABLE \', TABLE_NAME, \';\') \n FROM INFORMATION_SCHEMA.TABLES\n WHERE TABLE_SCHEMA = \'PUBLIC\'\n """;\n\n @Override\n public void afterTestMethod(TestContext testContext) {\n JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);\n List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);\n truncateTables(jdbcTemplate, truncateTableQueries);\n }\n\n private JdbcTemplate getJdbcTemplate(TestContext testContext) {\n return testContext.getApplicationContext().getBean(JdbcTemplate.class);\n }\n\n private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {\n return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);\n }\n\n private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {\n jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");\n truncateTableQueries.forEach(jdbcTemplate::execute);\n jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");\n }\n}\n\n')),(0,a.kt)("h3",{id:"listener-\ub4f1\ub85d"},"Listener \ub4f1\ub85d"),(0,a.kt)("p",null,"@TestExecutionListeners\ub97c \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790 \uc815\uc758 \ub9ac\uc2a4\ub108\ub97c \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","mergeMode\uc758 \uae30\ubcf8\uac12\uc740 REPLACE_DEFAULTS\ub85c \ub9ac\uc2a4\ub108\uac00 \uc774\ubbf8 \uc874\uc7ac\ud558\ub294 \uacbd\uc6b0 \ub4f1\ub85d\ub41c \ub9ac\uc2a4\ub108\ub85c \ubcc0\uacbd\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","MERGE_WITH_DEFAULTS\ub85c \uc124\uc815\ud55c\ub2e4\uba74 Ordered \uae30\uc900\uc73c\ub85c \uc21c\uc11c\uac00 \uacb0\uc815\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ud6c4 \uaca9\ub9ac\uac00 \ud544\uc694\ud55c \ud14c\uc2a4\ud2b8\ub4e4\uc740 \ub2e4\uc74c\uc758 \ucd94\uc0c1 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ud558\uc5ec \uc0ac\uc6a9\ud558\uba74 \ub41c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AcceptanceTest",title:"AcceptanceTest"},"\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\n@TestExecutionListeners(\n value = DatabaseCleaner.class,\n mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS\n)\npublic abstract class AcceptanceTest {\n\n @LocalServerPort\n private int port;\n\n @BeforeEach\n public void setUp() {\n RestAssured.port = port;\n }\n}\n\n")),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.baeldung.com/spring-testexecutionlistener"},"The Spring TestExecutionListener, Baeldung"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://tecoble.techcourse.co.kr/post/2020-09-15-test-isolation/"},"\uc778\uc218\ud14c\uc2a4\ud2b8\uc5d0\uc11c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ud558\uae30, \ud14c\ucf54\ube14"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://martinfowler.com/articles/nonDeterminism.html"},"Eradicating Non-Determinism in Tests, martin fowler"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://mangkyu.tistory.com/264"},"@SpringBootTest\uc758 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\uc2dc\ud0a4\uae30, MangKyu")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ae82353f.77430c26.js b/assets/js/ae82353f.77430c26.js new file mode 100644 index 000000000..0048430d8 --- /dev/null +++ b/assets/js/ae82353f.77430c26.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6420],{96046:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var r=n(85893),s=n(3905);const i={title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",slug:"spring-test-isolation",tags:["test"]},a=void 0,o={permalink:"/spring-test-isolation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",source:"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",description:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac",date:"2023-10-03T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 3\uc77c",tags:[{label:"test",permalink:"/tags/test"}],readingTime:4.315,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac",slug:"spring-test-isolation",tags:["test"]},unlisted:!1,prevItem:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/mvc-retrospective"},nextItem:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",permalink:"/web-application-evolution"}},c={authorsImageUrls:[]},l=[{value:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac",id:"\ud14c\uc2a4\ud2b8-\uaca9\ub9ac",level:3},{value:"TestExecutionListener",id:"testexecutionlistener",level:3},{value:"AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604",id:"abstracttestexecutionlistener-\uc0c1\uc18d\ud558\uc5ec-\uad6c\ud604",level:3},{value:"Listener \ub4f1\ub85d",id:"listener-\ub4f1\ub85d",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",...(0,s.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"\ud14c\uc2a4\ud2b8-\uaca9\ub9ac",children:"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac"}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\uc758 \uc21c\uc11c\uc5d0 \ub530\ub77c \uc131\uacf5 \uc2e4\ud328 \uc5ec\ubd80\uac00 \uacb0\uc815\ub418\ub294 \ube44\uacb0\uc815\uc801\uc778(non-determinism) \ud14c\uc2a4\ud2b8\uac00 \ub418\uc5b4\uc11c\ub294 \uc548\ub418\uace0, \ud14c\uc2a4\ud2b8\ub294 \ud56d\uc0c1 \uc21c\uc11c\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc218\ud589\ub418\ub3c4\ub85d \ubcf4\uc7a5\ub418\uc5b4\uc57c \ud55c\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \uc790\uc6d0\uc758 \uacf5\uc720, \uc678\ubd80 API, \uc2dc\uac04 \ub4f1\uc73c\ub85c \ube44\uacb0\uc815\uc801\uc778 \ud14c\uc2a4\ud2b8\uac00 \ub41c\ub2e4. \uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \uc0ac\uc6a9\ud558\uac70\ub098, \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc7ac\uc2e4\ud589\ud558\ub294 ",(0,r.jsx)(t.code,{children:"@DirtiesContext"}),", \uc790\uc6d0\uc744 \ucd08\uae30\ud654\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uc774\ud6c4\uc5d0 \ud14c\uc774\ube14\uc744 \ub864\ubc31 \ud558\ub294 ",(0,r.jsx)(t.code,{children:"@Transactional"}),"\ub4f1 \ub2e4\uc591\ud55c \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud574\ub2f9 \uae00\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc5d0\uc11c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc790\uc6d0\uc758 \uacf5\uc720\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc218\ud589\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc124\uba85\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.admonition,{title:"Independent - FIRST",type:"note",children:(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8\ub07c\ub9ac \uc11c\ub85c \uc758\uc874\ud558\uba74 \uc548 \ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc11c\ub85c \uc758\uc874\ud558\uac8c \ub41c\ub2e4\uba74 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \ub54c, \ub610 \ub2e4\ub978 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589 \uac00\ub2a5\ud55c \ud14c\uc2a4\ud2b8\uac00 \uc88b\uc740 \ud14c\uc2a4\ud2b8\ub2e4."]})}),"\n",(0,r.jsx)(t.h3,{id:"testexecutionlistener",children:"TestExecutionListener"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 TextExecutionListner\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 \ud14c\uc2a4\ud2b8 \uc2e4\ud589 \ub2e8\uacc4\uc5d0\uc11c \uc774\ubca4\ud2b8\ub97c \uc218\uc2e0\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub97c \uc774\uc6a9\ud558\uba74 JUnit\uc758 @BeforeEach\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uacfc \uc720\uc0ac\ud558\uac8c, \ud14c\uc2a4\ud2b8\uc758 \uc0dd\uba85\uc8fc\uae30 \uc774\uc804 \ub610\ub294 \uc774\ud6c4\uc5d0 \ud544\uc694\ud55c \uc791\uc5c5\uc744 \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",metastring:"title=TextExecutionListner",children:"public interface TestExecutionListener {\n default void beforeTestClass(TestContext testContext) throws Exception {}\n default void prepareTestInstance(TestContext testContext) throws Exception {}\n default void beforeTestMethod(TestContext testContext) throws Exception {}\n default void beforeTestExecution(TestContext testContext) throws Exception {}\n default void afterTestExecution(TestContext testContext) throws Exception {}\n default void afterTestMethod(TestContext testContext) throws Exception {}\n default void afterTestClass(TestContext testContext) throws Exception {}\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"abstracttestexecutionlistener-\uc0c1\uc18d\ud558\uc5ec-\uad6c\ud604",children:"AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604"}),"\n",(0,r.jsxs)(t.p,{children:["AbstractTestExecutionListener\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac \ud658\uacbd\uc744 \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \ud074\ub798\uc2a4\ub85c, \uc778\ud130\ud398\uc774\uc2a4\uc778 TextExecutionListner\uc640 \ub2ec\ub9ac Ordered\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc5b4 \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ubc1b\uc544 \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub294 \ud504\ub808\uc784\uc6cc\ud06c\uac00 \uc81c\uacf5\ud558\ub294 \ub9ac\uc2a4\ub108 \ub2e4\uc74c\uc5d0 \uc2e4\ud589\uc2dc\ud0a4\ub3c4\ub85d \ud574\uc900\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub2e4\uc74c\uacfc \uac19\uc774 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac01\uac01\uc758 \ud14c\uc774\ube14\uc5d0 \ud574\ub2f9\ud558\ub294 Truncate \ucffc\ub9ac\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc870\ud68c\ud558\uace0, Test \uba54\uc11c\ub4dc\uac00 \ub05d\ub0a0\ub54c \ub9c8\ub2e4 \ud574\ub2f9 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uc5ec \ud14c\uc774\ube14\uc744 \ucd08\uae30\ud654\uc2dc\ud0a4\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",metastring:"title=DatabaseCleaner",children:'\npublic class DatabaseCleaner extends AbstractTestExecutionListener {\n\n private static final String TRUNCATE_TABLE_QUERY = """\n SELECT Concat(\'TRUNCATE TABLE \', TABLE_NAME, \';\') \n FROM INFORMATION_SCHEMA.TABLES\n WHERE TABLE_SCHEMA = \'PUBLIC\'\n """;\n\n @Override\n public void afterTestMethod(TestContext testContext) {\n JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);\n List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);\n truncateTables(jdbcTemplate, truncateTableQueries);\n }\n\n private JdbcTemplate getJdbcTemplate(TestContext testContext) {\n return testContext.getApplicationContext().getBean(JdbcTemplate.class);\n }\n\n private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {\n return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);\n }\n\n private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {\n jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");\n truncateTableQueries.forEach(jdbcTemplate::execute);\n jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");\n }\n}\n\n'})}),"\n",(0,r.jsx)(t.h3,{id:"listener-\ub4f1\ub85d",children:"Listener \ub4f1\ub85d"}),"\n",(0,r.jsxs)(t.p,{children:["@TestExecutionListeners\ub97c \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790 \uc815\uc758 \ub9ac\uc2a4\ub108\ub97c \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","mergeMode\uc758 \uae30\ubcf8\uac12\uc740 REPLACE_DEFAULTS\ub85c \ub9ac\uc2a4\ub108\uac00 \uc774\ubbf8 \uc874\uc7ac\ud558\ub294 \uacbd\uc6b0 \ub4f1\ub85d\ub41c \ub9ac\uc2a4\ub108\ub85c \ubcc0\uacbd\ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","MERGE_WITH_DEFAULTS\ub85c \uc124\uc815\ud55c\ub2e4\uba74 Ordered \uae30\uc900\uc73c\ub85c \uc21c\uc11c\uac00 \uacb0\uc815\ub41c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ud6c4 \uaca9\ub9ac\uac00 \ud544\uc694\ud55c \ud14c\uc2a4\ud2b8\ub4e4\uc740 \ub2e4\uc74c\uc758 \ucd94\uc0c1 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ud558\uc5ec \uc0ac\uc6a9\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",metastring:"title=AcceptanceTest",children:"\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\n@TestExecutionListeners(\n value = DatabaseCleaner.class,\n mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS\n)\npublic abstract class AcceptanceTest {\n\n @LocalServerPort\n private int port;\n\n @BeforeEach\n public void setUp() {\n RestAssured.port = port;\n }\n}\n\n"})}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://www.baeldung.com/spring-testexecutionlistener",children:"The Spring TestExecutionListener, Baeldung"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://tecoble.techcourse.co.kr/post/2020-09-15-test-isolation/",children:"\uc778\uc218\ud14c\uc2a4\ud2b8\uc5d0\uc11c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ud558\uae30, \ud14c\ucf54\ube14"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://martinfowler.com/articles/nonDeterminism.html",children:"Eradicating Non-Determinism in Tests, martin fowler"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://mangkyu.tistory.com/264",children:"@SpringBootTest\uc758 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\uc2dc\ud0a4\uae30, MangKyu"})]})]})}function p(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>l});var r=n(67294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,s=function(e,t){if(null==e)return{};var n,r,s={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=l(n),T=s,x=u["".concat(c,".").concat(T)]||u[T]||d[T]||i;return n?r.createElement(x,a(a({ref:t},p),{},{components:n})):r.createElement(x,a({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/af81a133.7821cdd8.js b/assets/js/af81a133.cb0b4019.js similarity index 84% rename from assets/js/af81a133.7821cdd8.js rename to assets/js/af81a133.cb0b4019.js index d896531ac..65c65701c 100644 --- a/assets/js/af81a133.7821cdd8.js +++ b/assets/js/af81a133.cb0b4019.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7787],{13800:e=>{e.exports=JSON.parse('{"label":"TecoChat","permalink":"/tags/teco-chat","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7787],{13800:e=>{e.exports=JSON.parse('{"label":"TecoChat","permalink":"/tags/teco-chat","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/b2b675dd.4e7704bd.js b/assets/js/b2b675dd.4e7704bd.js deleted file mode 100644 index 909d48db1..000000000 --- a/assets/js/b2b675dd.4e7704bd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[533],{28017:n=>{n.exports=JSON.parse('{"blogPosts":[{"id":"refactoring-retrospective","metadata":{"permalink":"/refactoring-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-refactoring/pull/465","date":"2023-10-31T00:00:00.000Z","formattedDate":"2023\ub144 10\uc6d4 31\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":8.055,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0","slug":"refactoring-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"nextItem":{"title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/jdbc-retrospective"}},"content":":::note PR \ub9c1\ud06c\\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-refactoring/pull/465 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-refactoring/pull/547 \\n3\ub2e8\uacc4: https://github.com/woowacourse/jwp-refactoring/pull/610 \\n4\ub2e8\uacc4: https://github.com/woowacourse/jwp-refactoring/pull/721 \\n:::\\n\\n### \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158\\n\\n\uc694\uad6c\uc0ac\ud56d \uc791\uc131 \u2192 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud55c \ucf54\ub4dc \ubcf4\ud638 \u2192 \ub9ac\ud329\ud130\ub9c1 \u2192 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1 \u2192 \uba40\ud2f0\ubaa8\ub4c8 \uc21c\uc11c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4. \\n\ubbf8\uc158\uc5d0 \uc628\uc804\ud788 \uc9d1\uc911\ud558\uace0 \uc2f6\uc5c8\uc9c0\ub9cc, \ud504\ub85c\uc81d\ud2b8\uc640 \ubcd1\ud589\ud558\uba74\uc11c \uc9c4\ud589\ud588\uae30\uc5d0 \uc5b4\ub290\uc815\ub3c4 \ud0c0\ud611\ubcf4\uace0 \uc9c4\ud589\ud55c \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c \uc544\uc26c\uc6e0\ub2e4. \\n\\n### 1, 2\ub2e8\uacc4\\n\\n1\ub2e8\uacc4\ub294 \uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud558\uace0, \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ucd94\ud6c4\uc5d0 \ub9ac\ud329\ud130\ub9c1 \ud560 \ub54c \uc548\uc815\uac10 \uc788\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\ub3c4\ub85d \uc900\ube44\ud558\ub294 \uacfc\uc815\uc774\uc5c8\ub2e4. \\n\uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud560 \ub54c \uc81c\uacf5\ub41c \uc6a9\uc5b4 \uc0ac\uc804\uc744 \ucd5c\ub300\ud55c \ud65c\uc6a9\ud558\uba74\uc11c \uae30\uc874\uc758 \ucf54\ub4dc\ub97c \ubcf4\uba74\uc11c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud588\ub2e4. \\n\ud14c\uc2a4\ud2b8\ub294 \uc2dc\uac04 \uad00\uacc4\uc0c1 API, \uc11c\ube44\uc2a4 \ub458 \uc911 \ud558\ub098\ub9cc \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4. \\n\\n\ucd5c\uc885\uc801\uc73c\ub85c \uc11c\ube44\uc2a4 \uae30\uc900\uc73c\ub85c \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud588\ub294\ub370 \uc57d\uac04 \ud6c4\ud68c\ub418\ub294 \uacb0\uc815\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\ub9ac\ud329\ud130\ub9c1 \uacfc\uc815\uc5d0\uc11c API \uba85\uc138\uac00 \ubc14\ub00c\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4\ub294 \uac83\uc744 \uae30\uc900\uc744 \uc7a1\uace0 \uc774\ubc88 \ubbf8\uc158\uc744 \ud55c\ub2e4\uace0 \uac00\uc815\ud588\uc744 \ub54c API \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\uace0, \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ub354 \uc548\uc815\uac10 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\n2\ub2e8\uacc4\ub294 \uc791\uc131\ub41c \ud14c\uc2a4\ud2b8 \uae30\ubc18\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\uc11c\ube44\uc2a4\uc5d0\uc11c \ub3c4\uba54\uc778\uc744 \uc9c1\uc811 \ubc18\ud658\ud558\ub294 \uad6c\uc870\uc600\ub294\ub370, \ub3c4\uba54\uc778\uc5d0 JPA\ub97c \uc801\uc6a9\ud558\uba74 \uae30\uc874 \uba85\uc138\uc640 \ub2ec\ub77c\uc9c8 \uac83\uc744 \uc6b0\ub824\ud574\uc11c DTO\ub85c \uc218\uc815\ud558\ub294 \uc791\uc5c5\uc744 \uba3c\uc800 \uc9c4\ud589\ud588\ub2e4. \\nDTO \uc774\ud6c4\uc5d0 \uc11c\ube44\uc2a4\uc5d0 \uc788\ub294 \ub85c\uc9c1\uc744 \ub3c4\uba54\uc778\uc73c\ub85c \uc774\ub3d9\uc2dc\ud0a4\uace0, \ucd5c\uc885\uc801\uc73c\ub85c JPA\ub97c \uc801\uc6a9\ud558\ub294 \uc21c\uc11c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud588\ub2e4. \\n\uc774 \uacfc\uc815\uc5d0\uc11c \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \uc591\ubc29\ud5a5\uc778 \ubd80\ubd84\ub3c4 \uc0dd\uaca8\ub0ac\ub2e4. \\n\\n### \uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\\n\\n\uc911\uac04\uc5d0 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\uc5d0 \uad00\ud55c \uc81c\uc774\uc2a8\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4. \\n\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\ub294 \uc5d0\ub9ad \uc5d0\ubc18\uc2a4\uc758 \uc800\uc11c `\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4`\uc758 \ubd80\uc81c\uc774\ub2e4. \\n\\n\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\ub294 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4, \uc804\uc220\uc801 \uc124\uacc4\uac00 \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4. \\n\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4\uac00 \uc804\uccb4\uc758 90%\uc5d0 \ud574\ub2f9\ud560 \uc815\ub3c4\ub85c \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4. \ub610\ud55c \uc804\uc220\uc801 \uc124\uacc4\ub9cc \ud558\ub294 \uacbd\uc6b0\ub97c DDD Lite \ub77c\uace0 \ud55c\ub2e4. \\n\\n\uac04\ub2e8\ud788 \ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\uc5d0\uc11c \ub098\uc624\ub294 \ub2e8\uc5b4\ub97c \uc815\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n| \ub2e8\uc5b4 | \uc124\uba85 |\\n| --- | --- |\\n| \ub3c4\uba54\uc778 | \uc18c\ud504\ud2b8\uc6e8\uc5b4\ub85c \ud574\uacb0\ud558\uace0\uc790 \ud558\ub294 \ubb38\uc81c \uc601\uc5ed |\\n| \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8 | \ud574\uacb0 \uc601\uc5ed, \uad00\uc2ec\uc0ac\ub97c \ubd84\ub9ac\ud558\uace0 \uaca9\ub9ac\ud558\uc5ec \ubb38\uc81c \ud574\uacb0\uc5d0 \uc9d1\uc911\ud560 \ubc94\uc704 |\\n| \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4 | \ud504\ub85c\uc81d\ud2b8\uc5d0 \uc774\ud574\uad00\uacc4\uc790\ub4e4\uc758 \uacf5\ud1b5\ub41c \uc5b8\uc5b4\ub85c, \uc11c\ub85c\uc758 \uc758\uc0ac\uc18c\ud1b5 \ube44\uc6a9\uc744 \uc904\uc774\uae30 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 \uc5b8\uc5b4 |\\n| \uc804\ub7b5\uc801 \uc124\uacc4 | \ub3c4\uba54\uc778 \uc804\ubb38\uac00\uc640 \uac1c\ubc1c\uc790\uac00 \ud568\uaed8 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec \ub3c4\uba54\uc778\uacfc \uad00\ub828\ub41c \uc9c0\uc2dd\uc744 \uc774\ud574\ud558\uace0 \uc774\ub97c \ubc14\ud0d5\uc73c\ub85c \uacbd\uacc4\ub97c \ub098\ub220 \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc815\uc758\ud558\uace0, \ucee8\ud14d\uc2a4\ud2b8 \ub9f5\uc744 \uc0dd\uc131\ud558\ub294 \uac83\uc744 \ud3ec\ud568\ud558\ub294 \uacfc\uc815 |\\n| \uc804\uc220\uc801 \uc124\uacc4 | \uc804\ub7b5\uc801 \uc124\uacc4\uc5d0\uc11c \uc815\uc758\ud55c \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\uc640 \ub3c4\uba54\uc778\uc744 \uc774\uc6a9\ud558\uc5ec \uc560\uadf8\ub9ac\uac70\ud2b8, Entity\uc640 VO, Repository \ub4f1\uc744 \uad6c\ud604\ud558\ub294 \uacfc\uc815 |\\n\\n\uc774 \uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ub0b4\uc6a9\ub4e4\uc774 \ub098\uc654\uc9c0\ub9cc, \uc9c0\uc2dd\uc744 \uc81c\ub300\ub85c \ud761\uc218\ud558\uc9c0\ub294 \ubabb\ud588\ub2e4. \\n\\n### 3, 4\ub2e8\uacc4\\n\\n\uc81c\uc774\uc2a8\uc758 \uac15\uc758\ub97c \ub4e3\uace0, \uc870\uc601\ud638\ub2d8\uc758 \uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5 \uc720\ud29c\ube0c \uc601\uc0c1\uc744 \ubcf8 \ub2e4\uc74c 3, 4\ub2e8\uacc4\ub97c \uc9c4\ud589\ud588\ub2e4. \\n\\n3\ub2e8\uacc4\ub294 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1\uc5d0 \uad00\ud55c \ub0b4\uc6a9\uc774\uc5c8\ub2e4. \ud074\ub798\uc2a4 \uac04 \ubc29\ud5a5, \ud328\ud0a4\uc9c0 \uac04 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc774 \ub418\ub3c4\ub85d \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud574\uc57c \ud588\uc5c8\ub2e4. \\n\ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4\ub4e4\uc744 \ubb36\uace0, \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uae30 \uc704\ud574 \uc0dd\uba85\uc8fc\uae30\uac00 \ub2e4\ub974\ub2e4\uba74 id\ub97c \uc774\uc6a9\ud558\uc5ec \ucc38\uc870\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4. \\n\\n\uc758\uc874\uc131\uc744 \ubd84\ub9ac\ud558\uae30 \uc704\ud574 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. \uc774\ubca4\ud2b8\ub294 \ud604\uc7ac \uae30\uc900\uc73c\ub85c \uacfc\uac70\uc5d0 \ubc8c\uc5b4\uc9c4 \uac83\uc744 \ud45c\ud604\ud558\uae30 \ub54c\ubb38\uc5d0 \uc774\ubca4\ud2b8\uba85\uc740 \uacfc\uac70 \uc2dc\uc81c\uac00 \ub418\uc5b4\uc57c\ud558\ub294 \uac83\uc744 \uc54c\uc558\ub2e4. \\n\ucc98\uc74c\uc5d0\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud588\uc9c0\ub9cc, \uc11c\ube44\uc2a4 \ub85c\uc9c1\uc744 \ucd5c\ub300\ud55c \uac04\ub2e8\ud558\uac8c \ud558\uae30 \uc704\ud574 \ub3c4\uba54\uc778 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. \\n\\n4\ub2e8\uacc4\ub294 \uba40\ud2f0\ubaa8\ub4c8\ub85c \ubd84\ub9ac\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub294\ub370 3\ub2e8\uacc4\uc5d0\uc11c \ubd84\ub9ac\ud574\ub454 \ud328\ud0a4\uc9c0 \uadf8\ub300\ub85c \ubd84\ub9ac\ud558\uc9c0\ub294 \uc54a\uc558\ub2e4. \\n3\ub2e8\uacc4\uc5d0\uc11c\ub294 \ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4 \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ud588\ub2e4. 4\ub2e8\uacc4\uc5d0\uc11c\ub294 \ub0b4\uac00 \uc778\uc2dd\ud558\uae30 \ud3b8\ud55c \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ub97c \ud588\ub2e4. \\n\uc544\uc9c1 \ubd84\ub9ac\ud55c \uae30\uc900\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \ubaa8\ud638\ud588\uace0, \uc774\uc5d0 \ub300\ud55c \uacf5\ubd80\ub97c \uc870\uae08 \ub354 \ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tsubgraph Table\\n\\t\\tOrderTable --\x3e TableGroup\\n\\tend\\n\\tsubgraph Order\\n\\t\\tO\\n\\tend\\n O[Order] --\x3e OrderTable\\n\\tsubgraph Menu\\n\\t\\tM[Menu] --\x3e MenuGroup\\n\\t\\tM --\x3e Product\\n\\tend\\n\\tO --\x3e M\\n```\\n\\n\ucd94\uac00\ub85c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc704\ud55c `@ServiceTest` \uc560\ub108\ud14c\uc774\uc158\uc774 \uc788\uc5c8\ub294\ub370, \uc0c1\uc704 \ubaa8\ub4c8\uc758 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \ub9cc\ub4e0 \ud074\ub798\uc2a4\ub97c \ud558\uc704 \ubaa8\ub4c8\uc5d0\uc11c\ub294 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c TestFixtures\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\uacb0\ud588\ub2e4. \\n\\n### \ub9c8\ubb34\ub9ac\\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc758 \ub9c8\uc9c0\ub9c9 \ubbf8\uc158\uc774\ub2c8 \ub9cc\ud07c, \uac00\uc7a5 \ud765\ubbf8\ub85c\uc6b4 \ubbf8\uc158\uc774\uc5c8\uace0 \ubc30\uc6b8\uc810\ub3c4 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4. \\n\ubc14\uc05c \uae30\uac04\uc774\ub77c \ub9ce\uc740 \ub9ac\ubdf0\ub97c \ub0a8\uae30\uc9c0 \ubabb\ud588\ub358 \ub9ac\ubdf0\uc774 \ud638\uc774\uc5d0\uac8c \ubbf8\uc548\ud558\uace0, \ucf54\uba58\ud2b8 \uaf3c\uaf3c\ud558\uac8c \ub2ec\uc544\uc8fc\uace0 \ubbf8\uc158\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub3c4 \uc624\ud504\ub77c\uc778\uc73c\ub85c \ub9ce\uc774 \ub098\ub208 \ub9ac\ubdf0\uc5b4 \ud14c\uc624\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4. \\n\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[\ub3c4\uba54\uc778 \uc6d0\uc815\ub300, \uc6b0\uc544\ucf58 2021](https://www.youtube.com/watch?v=kmUneexSxk0) \\n[\uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5, \uc6b0\uc544\ud55c\ud14c\ud06c\uc138\ubbf8\ub098](https://www.youtube.com/watch?v=dJ5C4qRqAgA) \\n[TestFixtures, \uad8c\ub0a8\ub2d8](https://kwonnam.pe.kr/wiki/gradle/testfixtures)"},{"id":"jdbc-retrospective","metadata":{"permalink":"/jdbc-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-jdbc/pull/267","date":"2023-10-10T00:00:00.000Z","formattedDate":"2023\ub144 10\uc6d4 10\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.83,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","slug":"jdbc-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0","permalink":"/refactoring-retrospective"},"nextItem":{"title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/mvc-retrospective"}},"content":":::note PR \ub9c1\ud06c\\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358 \\n3\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448 \\n4\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515 \\n:::\\n\\n### Jdbc \uad6c\ud604\\n\\n\uc774\ubc88 \ubbf8\uc158\uc740 Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uace0, Transaction \uacbd\uacc4 \uc124\uc815\uacfc \ub3d9\uae30\ud654\ud558\ub294 \ubd80\ubd84\uc744 \uad6c\ud604\ud574 \ubcf4\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\ubbf8\uc158 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n- JDBC \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uba74\uc11c \uc911\ubcf5\uc744 \uc81c\uac70\ud558\ub294 \uc5f0\uc2b5\uc744 \ud55c\ub2e4.\\n- \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\ub97c \ub192\uc778\ub2e4.\\n\\n\ucd5c\ub300\ud55c Java\uac00 \uc81c\uacf5\ud558\ub294 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud588\ub2e4. \\n\\n### JdbcTemplate\\n\\nJdbcTemplate\uc740 Connection\uc744 \uc774\uc6a9\ud558\uc5ec PreparedStatement\ub97c \uc0dd\uc131\ud558\ub294 \ubd80\ubd84, \uadf8\ub9ac\uace0 PreparedStatement\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ubd84\ub9ac\ud588\ub2e4. \\n\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc801\uc808\ud558\uac8c \uc801\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \ube44\uad50\uc801 \uac04\ub2e8\ud558\uac8c \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\uc608\uc804\uc5d0\ub3c4 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c [JdbcTemplate\uc744 \uad6c\ud604](./custom-jdbc-template)\ud55c \uc801\uc774 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \uc790\uc6d0 \ud560\ub2f9\uacfc \ud574\uc81c \ubd80\ubd84\uc5d0 \ub300\ud55c \uc911\ubcf5\ub3c4 \uc81c\uac70\ud588\ub2e4. \\n\\n```java\\npublic class JdbcTemplate {\\n\\n private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);\\n\\n private final DataSource dataSource;\\n private final StatementCreator statementCreator;\\n private final StatementExecutor statementExecutor;\\n\\n public JdbcTemplate(final DataSource dataSource) {\\n this(dataSource, new StatementCreator(), new StatementExecutor());\\n }\\n\\n JdbcTemplate(\\n final DataSource dataSource,\\n final StatementCreator statementCreator,\\n final StatementExecutor statementExecutor\\n ) {\\n this.dataSource = dataSource;\\n this.statementCreator = statementCreator;\\n this.statementExecutor = statementExecutor;\\n }\\n\\n private <T> T query(\\n final String sql,\\n final PreparedStatementCallback<T> preparedStatementCallback,\\n final Object... parameters\\n ) {\\n final Connection connection = DataSourceUtils.getConnection(dataSource);\\n try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {\\n return preparedStatementCallback.execute(preparedStatement);\\n } catch (final SQLException e) {\\n log.error(e.getMessage(), e);\\n throw new DataAccessException(e);\\n } finally {\\n DataSourceUtils.releaseConnection(connection, dataSource);\\n }\\n }\\n\\n public void update(final String sql, final Object... parameters) {\\n query(sql, PreparedStatement::executeUpdate, parameters);\\n }\\n\\n public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\\n final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\\n if (results.size() > 1) {\\n throw new DataAccessException(\\"2\uac1c \uc774\uc0c1\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\\");\\n }\\n return results.stream().findAny();\\n }\\n\\n public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\\n return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\\n }\\n}\\n```\\n\\n### \ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9\\n\\n3, 4\ub2e8\uacc4\ub294 \uae30\uc874\uc758 \ucf54\ub4dc\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uace0 \ub05d\ub098\ub294 \ubd80\ubd84\uc778 \ud2b8\ub79c\uc7ad\uc158 \uacbd\uacc4\ub97c \uc124\uc815\ud558\uace0 ThreadLocal\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654(Transaction synchronization)\ub97c \uc801\uc6a9\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654\ub780 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uae30 \uc704\ud55c Connection \uac1d\uccb4\ub97c ThreadLocal\uacfc \uac19\uc740 \uacf5\uac04\uc5d0 \ub530\ub85c \uc800\uc7a5 \ud6c4, \ud544\uc694\ud560 \ub54c \uc800\uc7a5\ub41c Connection\uc744 \uac00\uc838\ub2e4 \uc0ac\uc6a9\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4. \\n\uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub294\ub370, ThreadLocal\uc5d0 Connection \uac1d\uccb4\uac00 \uc544\ub2cc, Connection \uac1d\uccb4\uc640 Transaction\uc774 \uc9c4\ud589 \uc911\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 flag\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \uc800\uc7a5\ud574\uc11c \uc0ac\uc6a9\ud558\ub3c4\ub85d \ud588\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tTransactionTemplate --\x3e TransactionManager\\n\\tTransactionManager --\x3e TransactionSynchronizationManager\\n\\tDataSourceUtils --\x3e TransactionSynchronizationManager\\n\\tJdbcTemplate --\x3e DataSourceUtils\\n```\\n\\n### \ub9c8\ubb34\ub9ac\\n\\nJdbc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c AOP\ub098 Transactional\uc5d0 \ub300\ud55c \ud559\uc2b5 \ud14c\uc2a4\ud2b8\ub3c4 \uc9c4\ud589\ud558\uace0, \uc57d\uac04 \uc54c\ucc2c \ubbf8\uc158\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\uaf3c\uaf3c\ud788 \ucf54\ub4dc\ub97c \ubd10\uc900 \ub9ac\ubdf0\uc5b4 \ud638\uc774 \uadf8\ub9ac\uace0 \uc5f0\ud734 \ub3d9\uc548 \uacc4\uc18d \ud2f0\ud0a4\ud0c0\uce74 \ud558\uba74\uc11c \uc7ac\ubc0c\uac8c \ub9ac\ubdf0\ud55c \ubbfc\ud2b8\uc5d0\uac8c \uac10\uc0ac\ud558\ub2e4. \\n\ud68c\uace0 \uc774\ub9cc \ub05d\ub0b4\uace0 \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud558\ub7ec\uac00\uc57c\uaca0\ub2e4. \ud83d\ude0a"},{"id":"mvc-retrospective","metadata":{"permalink":"/mvc-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-mvc/pull/404","date":"2023-10-07T00:00:00.000Z","formattedDate":"2023\ub144 10\uc6d4 7\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":5.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","slug":"mvc-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/jdbc-retrospective"},"nextItem":{"title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","permalink":"/spring-test-isolation"}},"content":":::note PR \ub9c1\ud06c\\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-mvc/pull/404 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-mvc/pull/465 \\n3\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-mvc/pull/580 \\n:::\\n\\n### MVC \uad6c\ud604\\n\\nReflection\uc744 \uc774\uc6a9\ud558\uc5ec Spring MVC\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\ubbf8\uc158\uc758 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\uc558\ub2e4.\\n\\n- MVC \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uad6c\ud604\ud558\uba74\uc11c \ub0b4\ubd80 \ub3d9\uc791 \uc6d0\ub9ac\ub97c \ud559\uc2b5\ud55c\ub2e4.\\n- \uc810\uc9c4\uc801\uc778 \ub9ac\ud329\ud1a0\ub9c1\uc744 \uacbd\ud5d8\ud55c\ub2e4.\\n\\n\ubbf8\uc158\uc758 \ubaa9\ud45c\uc640 \ub354\ubd88\uc5b4 \uac01 \ud074\ub798\uc2a4\ub4e4\uc774 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \uc801\uc808\ud788 \uac00\uc9c0\ub3c4\ub85d \ud558\uace0, \ud328\ud0a4\uc9c0\uc758 \uc758\uc874 \ubc29\ud5a5\uc744 \uace0\ubbfc\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc5d0 \uc911\uc810\uc744 \ub450\uc5c8\ub2e4. \\n\\n### \uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30\\n\\n\uae30\uc874 \ucf54\ub4dc\uc5d0 ManualHandlerMapping\uc774\ub77c\ub294 \uc11c\ube14\ub9bf\uc744 \uc9c1\uc811 \ub4f1\ub85d\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 HandlerMapping \ud074\ub798\uc2a4\uac00 \uc788\uc5c8\uace0, 1\ub2e8\uacc4\uc5d0\uc11c\ub294 \uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18\uc758 AnnotationHandlerMapping\uc744 \uad6c\ud604\ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 @Controller, @RequestMapping\uc744 Reflection\uc744 \uc774\uc6a9\ud558\uc5ec \uc2a4\uce94\ud558\uace0, \ud578\ub4e4\ub7ec \ub9e4\ud551\uc744 \ub4f1\ub85d\ud558\ub294 \ubd80\ubd84\uae4c\uc9c0 \uc9c4\ud589\ud574\uc57c \ud588\ub2e4. \\n\ud14c\uc624\uac00 @GetMapping\uc774\ub098 @PostMapping \ubd80\ubd84\ub3c4 \uc9c4\ud589\ud558\uba74 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4\uace0 \ud574\uc11c \uac19\uc774 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4. \\n\ucd94\uac00\ub85c \ubbf8\uc158 \uc694\uad6c\uc0ac\ud56d\uc740 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ud074\ub798\uc2a4 \ub808\ubca8\uc5d0 \uc801\uc6a9\ub41c @RequestMapping\ub3c4 \ub3d9\uc791\ud558\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\uc558\ub2e4. \\n\\n```mermaid\\ngraph LR\\n AHM[AnnotationHandlerMapping] --\x3e AS[AnnotationScanner]\\n\\tAHM --\x3e HKG[HandlerKeyGenerator] --\x3e HMAP[HttpMappingAnnotationParser]\\n```\\n\\n\ub2e4\uc74c\uacfc \uac19\uc740 Flow\ub85c Handler(\uc2e4\uc81c \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uba54\uc11c\ub4dc) \ub4f1\ub85d\uc744 \uc9c4\ud589\ud55c\ub2e4. \\n\\n1. @Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 \uc815\ubcf4\ub97c \uc2a4\uce94\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4. \\n2. @Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 @RequestMapping\uc774 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\ub4e4\uc758 \uc815\ubcf4\ub97c \ubc18\ud658\ud55c\ub2e4. \\n3. \uac01 \uba54\uc11c\ub4dc\ub4e4\uc744 \uc21c\ud68c\ud558\uba70 HandlerKey(uri + httpMethod \uc815\ubcf4)\uc640 HandlerExecution(\uc778\uc2a4\ud134\uc2a4 + \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc)\uc744 \uc0dd\uc131\ud558\uc5ec Map<HandlerKey, HandlerExecution>\uc5d0 \ucd94\uac00\ud55c\ub2e4. \\n\\nAnnotationHandlerMapping\uc758 initialize \uba54\uc11c\ub4dc\uc5d0\uc11c Handler\ub97c \ub4f1\ub85d\ud55c\ub2e4. \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n```java title=AnnotationHandlerMapping\\npublic void initialize() {\\n if (!initialized.compareAndSet(false, true)) {\\n return;\\n }\\n\\n final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();\\n final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());\\n for (final Method method : methods) {\\n final ControllerInstance controller = controllers.get(method.getDeclaringClass());\\n final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);\\n final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);\\n handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));\\n }\\n\\n log.info(\\"Initialized AnnotationHandlerMapping!\\");\\n handlerExecutions.keySet().forEach(key -> log.info(\\"key: {}, Handler: {}\\", key, handlerExecutions.get(key)));\\n}\\n```\\n\\n### Legacy MVC\uc640 @MVC \ud1b5\ud569\\n\\n2\ub2e8\uacc4\ub294 Legacy MVC\uc640 AnnotationHandlerMapping\uc744 \ud1b5\ud569\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4. \\n\uae30\uc874\uc758 MVC\uc640 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc801\uc6a9\ub41c MVC \ub450 \uac1c\ub97c \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5b4\uc57c \ud5c0\ub2e4. \\n\ub300\ub7b5\uc801\uc778 \ud750\ub984\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n1. DispatcherServlet.service(request, response) \ud638\ucd9c\\n2. HandlerMappings\ub97c \ud1b5\ud574 \uc785\ub825\ubc1b\uc740 request\uc5d0 \ud574\ub2f9\ud558\ub294 Handler \uc870\ud68c\\n3. HandlerAdapters\ub97c \ud1b5\ud574 Handler\ub97c \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub294 HandlerAdapter \uc870\ud68c\\n4. HandlerAdapter\uc758.handle \uba54\uc11c\ub4dc \uc2e4\ud589\\n5. View\uc758 render \ud638\ucd9c\\n\\n```mermaid\\ngraph LR\\n D[DispatcherServlet]\\n D --\x3e HMS[HandlerMappings]\\n D --\x3e HAS[HandlerAdapters]\\n\\n\\tHMS --\x3e HandlerMapping\\n\\tsubgraph HandlerMapping\\n\\t\\tdirection BT\\n\\t\\tAHM[AnnotationHandlerMapping] --\x3e HM[HandlerMapping]\\n\\t\\tMHM[ManualHandlerMapping] --\x3e HM\\n\\tend\\n\\n\\tHAS --\x3e HandlerAdapter\\n\\tsubgraph HandlerAdapter\\n\\t\\tdirection BT\\n\\t\\tHEHA[HandlerExecutionHandlerAdapter] --\x3e HA[HandlerAdapter]\\n\\t\\tCHA[ControllerHandlerAdapter] --\x3e HA\\n\\tend\\n```\\n\\n### \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815\\n\\n\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4. \\n\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4.\\n\\n```mermaid\\ngraph LR\\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking\\n```\\n\\n\ub0b4\uc6a9\uc774 \uae38\uc5b4\uc838\uc11c [\ub2e4\uc74c \ubb38\uc11c](./web-application-evolution)\uc5d0 \uc815\ub9ac\ud588\ub2e4.\\n\\n### \ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95\\n\\n\uc9c1\uad00\uc801\uc774\uc9c0 \uc54a\uc740 \ucd94\uc0c1\uc801\uc778 \uac1c\ub150\uc744 \ud559\uc2b5\ud560 \ub54c\ub294 \uac1c\ub150\uc758 \uad6c\ud604\uc744 \ucc38\uace0\ud558\uba74 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \ud55c\ub2e4.\\n\\n| \uac1c\ub150 | \uad6c\ud604 |\\n| ---- | ------------------------------------------------ |\\n| OOP | Java |\\n| WAS | Tomcat, Jetty |\\n| IoC | Spring BeanFactory, Servlet Container, Framework |\\n| DI | Spring BeanFactory |\\n\\n### \uc815\ub9ac\\n\\n\uc9c0\uae08\uae4c\uc9c0 \uc2a4\ud504\ub9c1\uc758 DispatcherServlet\uc758 \ub3d9\uc791\uc744 \uc774\ub860\uc801\uc73c\ub85c\ub9cc \uc54c\uace0 \uc788\uc5c8\ub294\ub370, \uc2e4\uc81c\ub85c \uad6c\ud604\ud574 \ubcf4\ub2c8 \uc870\uae08 \ub354 \uc774\ud574\uac00 \uc798 \uac00\ub294 \uac83 \uac19\ub2e4. \\n\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c \ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub8e8\uce74, \ub9ac\ubdf0\uc774\ub294 \ud5e4\ub098\uc600\ub2e4. \\n\ub9e4 \ub2e8\uacc4\ub9c8\ub2e4 \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0\ud574 \uc900 \ub8e8\uce74\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\uace0, \ud5e4\ub098\uc5d0\uac8c \uc774\uc0c1\ud55c \ub9ac\ubdf0\ub97c \ub9ce\uc774 \ub0a8\uae34 \uac83 \uac19\uc740\ub370 \uaf3c\uaf3c\ud788 \ubc18\uc601\ud574\uc918\uc11c \uac10\uc0ac\ud558\ub2e4. \\n\uc624\ub7ab\ub3d9\uc548 \uae30\ub2e4\ub824\uc654\ub358 \ub808\ubca8 4 \ubbf8\uc158\uc774 \ud558\ub098\uc529 \ub9c8\ubb34\ub9ac \ub420 \ub54c \ub9c8\ub2e4 \uc544\uc26c\uc6c0\uc774 \ub0a8\ub294\ub2e4."},{"id":"spring-test-isolation","metadata":{"permalink":"/spring-test-isolation","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md","source":"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md","title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","description":"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac","date":"2023-10-03T00:00:00.000Z","formattedDate":"2023\ub144 10\uc6d4 3\uc77c","tags":[{"label":"test","permalink":"/tags/test"}],"readingTime":4.315,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","slug":"spring-test-isolation","tags":["test"]},"prevItem":{"title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/mvc-retrospective"},"nextItem":{"title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","permalink":"/web-application-evolution"}},"content":"### \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\\n\\n\ud14c\uc2a4\ud2b8\uc758 \uc21c\uc11c\uc5d0 \ub530\ub77c \uc131\uacf5 \uc2e4\ud328 \uc5ec\ubd80\uac00 \uacb0\uc815\ub418\ub294 \ube44\uacb0\uc815\uc801\uc778(non-determinism) \ud14c\uc2a4\ud2b8\uac00 \ub418\uc5b4\uc11c\ub294 \uc548\ub418\uace0, \ud14c\uc2a4\ud2b8\ub294 \ud56d\uc0c1 \uc21c\uc11c\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc218\ud589\ub418\ub3c4\ub85d \ubcf4\uc7a5\ub418\uc5b4\uc57c \ud55c\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \uc790\uc6d0\uc758 \uacf5\uc720, \uc678\ubd80 API, \uc2dc\uac04 \ub4f1\uc73c\ub85c \ube44\uacb0\uc815\uc801\uc778 \ud14c\uc2a4\ud2b8\uac00 \ub41c\ub2e4. \uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \uc0ac\uc6a9\ud558\uac70\ub098, \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc7ac\uc2e4\ud589\ud558\ub294 `@DirtiesContext`, \uc790\uc6d0\uc744 \ucd08\uae30\ud654\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uc774\ud6c4\uc5d0 \ud14c\uc774\ube14\uc744 \ub864\ubc31 \ud558\ub294 `@Transactional`\ub4f1 \ub2e4\uc591\ud55c \ubc29\ubc95\uc774 \uc788\ub2e4. \\n\ud574\ub2f9 \uae00\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc5d0\uc11c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc790\uc6d0\uc758 \uacf5\uc720\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc218\ud589\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc124\uba85\ud55c\ub2e4. \\n\\n:::note Independent - FIRST\\n\\n\ud14c\uc2a4\ud2b8\ub07c\ub9ac \uc11c\ub85c \uc758\uc874\ud558\uba74 \uc548 \ub41c\ub2e4. \\n\uc11c\ub85c \uc758\uc874\ud558\uac8c \ub41c\ub2e4\uba74 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \ub54c, \ub610 \ub2e4\ub978 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \uc218 \uc788\ub2e4. \\n\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589 \uac00\ub2a5\ud55c \ud14c\uc2a4\ud2b8\uac00 \uc88b\uc740 \ud14c\uc2a4\ud2b8\ub2e4. \\n\\n:::\\n\\n### TestExecutionListener\\n\\n\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 TextExecutionListner\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 \ud14c\uc2a4\ud2b8 \uc2e4\ud589 \ub2e8\uacc4\uc5d0\uc11c \uc774\ubca4\ud2b8\ub97c \uc218\uc2e0\ud560 \uc218 \uc788\ub2e4. \\n\uc774\ub97c \uc774\uc6a9\ud558\uba74 JUnit\uc758 @BeforeEach\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uacfc \uc720\uc0ac\ud558\uac8c, \ud14c\uc2a4\ud2b8\uc758 \uc0dd\uba85\uc8fc\uae30 \uc774\uc804 \ub610\ub294 \uc774\ud6c4\uc5d0 \ud544\uc694\ud55c \uc791\uc5c5\uc744 \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub2e4. \\n\\n```java title=TextExecutionListner\\npublic interface TestExecutionListener {\\n default void beforeTestClass(TestContext testContext) throws Exception {}\\n default void prepareTestInstance(TestContext testContext) throws Exception {}\\n default void beforeTestMethod(TestContext testContext) throws Exception {}\\n default void beforeTestExecution(TestContext testContext) throws Exception {}\\n default void afterTestExecution(TestContext testContext) throws Exception {}\\n default void afterTestMethod(TestContext testContext) throws Exception {}\\n default void afterTestClass(TestContext testContext) throws Exception {}\\n}\\n```\\n\\n### AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604\\n\\nAbstractTestExecutionListener\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac \ud658\uacbd\uc744 \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \ud074\ub798\uc2a4\ub85c, \uc778\ud130\ud398\uc774\uc2a4\uc778 TextExecutionListner\uc640 \ub2ec\ub9ac Ordered\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc5b4 \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ubc1b\uc544 \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub294 \ud504\ub808\uc784\uc6cc\ud06c\uac00 \uc81c\uacf5\ud558\ub294 \ub9ac\uc2a4\ub108 \ub2e4\uc74c\uc5d0 \uc2e4\ud589\uc2dc\ud0a4\ub3c4\ub85d \ud574\uc900\ub2e4. \\n\ub2e4\uc74c\uacfc \uac19\uc774 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac01\uac01\uc758 \ud14c\uc774\ube14\uc5d0 \ud574\ub2f9\ud558\ub294 Truncate \ucffc\ub9ac\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc870\ud68c\ud558\uace0, Test \uba54\uc11c\ub4dc\uac00 \ub05d\ub0a0\ub54c \ub9c8\ub2e4 \ud574\ub2f9 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uc5ec \ud14c\uc774\ube14\uc744 \ucd08\uae30\ud654\uc2dc\ud0a4\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. \\n\\n```java title=DatabaseCleaner\\n\\npublic class DatabaseCleaner extends AbstractTestExecutionListener {\\n\\n private static final String TRUNCATE_TABLE_QUERY = \\"\\"\\"\\n SELECT Concat(\'TRUNCATE TABLE \', TABLE_NAME, \';\') \\n FROM INFORMATION_SCHEMA.TABLES\\n WHERE TABLE_SCHEMA = \'PUBLIC\'\\n \\"\\"\\";\\n\\n @Override\\n public void afterTestMethod(TestContext testContext) {\\n JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);\\n List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);\\n truncateTables(jdbcTemplate, truncateTableQueries);\\n }\\n\\n private JdbcTemplate getJdbcTemplate(TestContext testContext) {\\n return testContext.getApplicationContext().getBean(JdbcTemplate.class);\\n }\\n\\n private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {\\n return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);\\n }\\n\\n private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {\\n jdbcTemplate.execute(\\"SET REFERENTIAL_INTEGRITY FALSE\\");\\n truncateTableQueries.forEach(jdbcTemplate::execute);\\n jdbcTemplate.execute(\\"SET REFERENTIAL_INTEGRITY TRUE\\");\\n }\\n}\\n\\n```\\n\\n### Listener \ub4f1\ub85d\\n\\n@TestExecutionListeners\ub97c \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790 \uc815\uc758 \ub9ac\uc2a4\ub108\ub97c \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4. \\nmergeMode\uc758 \uae30\ubcf8\uac12\uc740 REPLACE_DEFAULTS\ub85c \ub9ac\uc2a4\ub108\uac00 \uc774\ubbf8 \uc874\uc7ac\ud558\ub294 \uacbd\uc6b0 \ub4f1\ub85d\ub41c \ub9ac\uc2a4\ub108\ub85c \ubcc0\uacbd\ub41c\ub2e4. \\nMERGE_WITH_DEFAULTS\ub85c \uc124\uc815\ud55c\ub2e4\uba74 Ordered \uae30\uc900\uc73c\ub85c \uc21c\uc11c\uac00 \uacb0\uc815\ub41c\ub2e4. \\n\uc774\ud6c4 \uaca9\ub9ac\uac00 \ud544\uc694\ud55c \ud14c\uc2a4\ud2b8\ub4e4\uc740 \ub2e4\uc74c\uc758 \ucd94\uc0c1 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ud558\uc5ec \uc0ac\uc6a9\ud558\uba74 \ub41c\ub2e4. \\n\\n```java title=AcceptanceTest\\n\\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\\n@TestExecutionListeners(\\n value = DatabaseCleaner.class,\\n mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS\\n)\\npublic abstract class AcceptanceTest {\\n\\n @LocalServerPort\\n private int port;\\n\\n @BeforeEach\\n public void setUp() {\\n RestAssured.port = port;\\n }\\n}\\n\\n```\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[The Spring TestExecutionListener, Baeldung](https://www.baeldung.com/spring-testexecutionlistener) \\n[\uc778\uc218\ud14c\uc2a4\ud2b8\uc5d0\uc11c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ud558\uae30, \ud14c\ucf54\ube14](https://tecoble.techcourse.co.kr/post/2020-09-15-test-isolation/) \\n[Eradicating Non-Determinism in Tests, martin fowler](https://martinfowler.com/articles/nonDeterminism.html) \\n[@SpringBootTest\uc758 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\uc2dc\ud0a4\uae30, MangKyu](https://mangkyu.tistory.com/264)"},{"id":"web-application-evolution","metadata":{"permalink":"/web-application-evolution","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx","source":"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx","title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","description":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","date":"2023-09-30T00:00:00.000Z","formattedDate":"2023\ub144 9\uc6d4 30\uc77c","tags":[{"label":"web application","permalink":"/tags/web-application"}],"readingTime":7.5,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","slug":"web-application-evolution","tags":["web application"]},"prevItem":{"title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","permalink":"/spring-test-isolation"},"nextItem":{"title":"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45","permalink":"/log-async-exception"}},"content":"### \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815\\n\\n\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4. \\n\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4. \\n\uc6d0\ub798 \ud68c\uace0\uc5d0 \uc791\uc131\ud558\ub824\uace0 \ud588\uc9c0\ub9cc, \uc815\ub9ac\ud558\ub2e4 \ubcf4\ub2c8 \uc870\uae08 \uae38\uc5b4\uc838\uc11c \ub530\ub85c \ubd84\ub9ac\ud588\ub2e4. \\n\\n```mermaid\\ngraph LR\\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking\\n```\\n\\n### WWW(1989)\\n\\n\uc815\uc801 \ud398\uc774\uc9c0\ub97c \uc81c\uacf5\ud558\ub294 \uc6f9 \uc11c\ubc84\ub97c \uc2dc\uc791\uc73c\ub85c \ub3d9\uc801 \ud398\uc774\uc9c0\uac00 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 CGI\uac00 \ub4f1\uc7a5\ud588\ub2e4. \\n\\n### CGI(1993) \\n\\nCGI\ub294 \ub3d9\uc801 \ucf58\ud150\uce20\ub97c \uc81c\uacf5\ud558\uae30 \uc704\ud55c \uaddc\uc57d\uc73c\ub85c, \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc774\uc6a9\ud574\uc11c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ucf1c \uc815\ubcf4\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ub9ce\uc740 \ubd80\ud558\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc774\ub7ec\ud55c \ub2e8\uc810\uc744 \uadf9\ubcf5\ud558\uae30 \uc704\ud574 \ub098\uc628 \uac83\uc774 Servlet\uc774\ub2e4. \\n\\n### Servlet(1996)\\n\\nServlet\uc740 \uc6f9 \uc11c\ubc84\uc5d0\uc11c \uc2e4\ud589\ub418\ub294 \uc790\ubc14 \ud504\ub85c\uadf8\ub7a8\uc73c\ub85c HTTP\ub97c \uc774\uc6a9\ud558\uc5ec \uc6f9 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc744 \uc218\uc2e0\ud558\uace0 \uc751\ub2f5\ud55c\ub2e4. CGI\uc640 \ub2e4\ub974\uac8c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\uac00 \uc544\ub2cc \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uc5ec \uc751\ub2f5\ud55c\ub2e4. \\n\ud558\uc9c0\ub9cc View \uc601\uc5ed\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uae30 \uc704\ud574 Servlet\uc758 \uc18c\uc2a4 \ucf54\ub4dc\ub97c \uc54c\uc544\uc57c \ud558\ub294 \ub4f1 \ubcf5\uc7a1\ub3c4\uac00 \ub108\ubb34 \ub192\uc558\ub2e4. \ub530\ub77c\uc11c \ud574\ub2f9 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 JSP\uac00 \ub4f1\uc7a5\ud588\ub2e4. \\n\\n### JSP(1999)\\n\\nJSP\ub294 HTML\uc5d0 \uc790\ubc14 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ub3d9\uc801 \uc6f9 \ud398\uc774\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\uc220\ub85c, \uc720\uc0ac\ud55c \uae30\uc220\ub85c\ub294 ASP, PHP\uac00 \uc788\ub2e4. \\nJSP\ub9cc \uc0ac\uc6a9\ud558\uc5ec \ud504\ub85c\uadf8\ub798\ubc0d\ud55c\ub2e4\uba74 Model 1, \uc544\ub798 \uad6c\uc131\ub3c4\uc640 \uac19\uc774 JSP\uac00 View \uc601\uc5ed\ub9cc \ub2f4\ub2f9\ud55c\ub2e4\uba74 Model 2\ub77c\uace0 \ud55c\ub2e4. \\n\\n```mermaid\\n---\\ntitle: JSP Model 2\\n---\\ngraph LR\\n Client -- Request --\x3e Servlet <-- JDBC --\x3e Database\\n\\tServlet --\x3e Bean\\n\\tServlet --\x3e JSP\\n\\tBean <--\x3e JSP\\n\\tJSP -- Response --\x3e Client\\n```\\n\\n### MVC(2000)\\n\\n\uc704 JSP\uc758 \uad6c\uc131\ub3c4\ub97c \ubcf4\uba74 \ud604\uc7ac MVC\uc640 \ub9e4\uc6b0 \uc720\uc0ac\ud55c\ub370, Govind Seshadri\ub77c\ub294 \uc0ac\ub78c\uc774 JSP Model 2\ub97c MVC \ud328\ud134\uc73c\ub85c \uacf5\uc2dd\ud654\ub97c \uc81c\uc548\ud588\ub2e4. \\n\\n> I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern. \\n> Govind Seshadri\\n\\n\uc774\ub54c MVC \ud328\ud134\uc774 \ucc98\uc74c \ud0c4\uc0dd\ud55c \uac83\uc740 \uc544\ub2c8\uace0, \uc11c\ubc84 \uce21 \uad6c\ud604\uc774\ub77c\uace0 \ud558\ub294 \uac83\uc744 \ubcf4\ub2c8 MVC\uac00 \ucc98\uc74c \ub4f1\uc7a5\ud55c \uac74 \uc544\ub2cc \uac83 \uac19\ub2e4. \\n[\ud574\ub2f9 \ubb38\uc11c](https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html)\ub97c \ubcf4\uba74 MVC\ub77c\ub294 \uc6a9\uc5b4\uc758 \ub4f1\uc7a5\uc740 1978\ub144\uc5d0 \ub4f1\uc7a5\ud55c \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4. \\n\\n### Spring Framework(2003)\\n\\nSpring\uc740 \ubcf5\uc7a1\ud588\ub358 J2EE\uc744 \ub300\uccb4\ud558\uae30 \uc704\ud574 2003\ub144\uc5d0 \ub4f1\uc7a5\ud588\ub2e4. \\nJ2EE\ub294 \uc6f9 \uae30\ubc18\uc758 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\uae30 \uc704\ud55c \ud50c\ub7ab\ud3fc\uc73c\ub85c \uc704\uc5d0\uc11c \uc124\uba85\ud55c Servlet, JSP, EJB \ub4f1\uc758 \uae30\uc220\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub2e4. \\n\ud558\uc9c0\ub9cc \uc774\uc911 EJB\ub77c\ub294 \uae30\uc220\uc774 J2EE\uc758 \ud575\uc2ec \uae30\uc220\uc774\uc5c8\ub294\ub370, \ud574\ub2f9 \uae30\uc220\uc774 \ub9e4\uc6b0 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub9ce\uc558\ub2e4\uace0 \ud55c\ub2e4. \\n2002\ub144\uc5d0 Rod Johnson\uc774 EJB\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 J2EE \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc800\uc220\ud55c `Expert One-to-One J2EE Development`\ub77c\ub294 \ucc45\uc744 \ubc1c\ud589\ud588\uace0, \ucd9c\uac04 \ud6c4 Juergen Hoeller, Yann Caroff\uac00 Rod Johnson\uc5d0\uac8c \uc624\ud508\uc18c\uc2a4 \uc81c\uc548\uc744 \ud558\uc5ec \uc2a4\ud504\ub9c1\uc774 \ud0c4\uc0dd\ud588\ub2e4\uace0 \ud55c\ub2e4. \\n\\n\uc2a4\ud504\ub9c1\uc740 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\uba70, \uc774 \ub355\ubd84\uc5d0 \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub2e4. \\n\\n### WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)\\n\\nTomcat\uc758 NIO \ub3d9\uc791 \ubc29\uc2dd\uc744 \ubcf4\uba74 Poller\uac00 \uc18c\ucf13 \ucee4\ub125\uc158\uc744 \ub4e4\uace0 \uc788\ub2e4\uac00 \ucc98\ub9ac\uac00 \uac00\ub2a5\ud560 \ub54c \uc2a4\ub808\ub4dc\ub97c \ud560\ub2f9\ud558\ub294 \uc2dd\uc73c\ub85c \ucc98\ub9ac\ub97c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ud560\ub2f9 \ud6c4 Servlet\uacfc \ud1b5\uc2e0\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \uc694\uccad\uc774 \ub05d\ub0a0 \ub54c\uae4c\uc9c0 \uc2a4\ub808\ub4dc\ub97c \uc810\uc720\ud558\uace0 \uc788\uc5c8\uace0, \uc2a4\ub808\ub4dc \uc810\uc720\ub85c \uc778\ud574 \uc694\uccad\uc774 max thread\uc5d0 \ub3c4\ub2ec\ud558\uba74 \uc694\uccad\uc744 \ucc98\ub9ac\ud560 \uc218 \uc5c6\uc5c8\ub2e4. \\n\uadf8\ub798\uc11c \ube44\ub3d9\uae30 \ubc29\uc2dd\uc758 Servlet\uc774 Servlet 3.0\uc5d0 \ub4f1\uc7a5\ud588\ub2e4. \ud558\uc9c0\ub9cc \uc804\ud1b5\uc801\uc778 I/O \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \ub3d9\uc791\ud588\ub2e4. Servlet 3.1\uc5d0\uc11c \ub17c\ube14\ub85c\ud0b9 I/O\uac00 \ucd94\uac00\ub418\uc5c8\uc9c0\ub9cc, \ub9ce\uc774 \uc0ac\uc6a9\ub418\uc9c0 \uc54a\uc558\ub2e4\uace0 \ud55c\ub2e4. \\n\\n### Spring WebFlux(2017)\\n\\n\uc801\uc740 \uc218\uc758 \uc2a4\ub808\ub4dc\ub85c \ub3d9\uc2dc\uc131\uc744 \ucc98\ub9ac\ud558\uace0, \uc801\uc740 \ub9ac\uc18c\uc2a4\ub85c \ud655\uc7a5\uc774 \uac00\ub2a5\ud55c \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd\uc758 \uc6f9 \uae30\uc220\uc774 \ud544\uc694\ud588\uace0, \uae30\uc874\uc758 Servlet\uc758 \uacbd\uc6b0 \ube44\ub3d9\uae30\ub97c \uc9c0\uc6d0\ud55c\ub2e4 \ud574\ub3c4 \ub3d9\uae30\uc2dd API\ub4e4\uc774 \ub9ce\uc774 \ub0a8\uc544\uc788\uc5c8\uae30 \ub54c\ubb38\uc5d0 \uc774\ub7ec\ud55c Servlet\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294 \uae30\uc220\uc774 \ud544\uc694\ud588\ub2e4. \ub610\ud55c \uae30\uc874\uc5d0 Netty\uc640 \uac19\uc774 \ube44\ub3d9\uae30, \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd \uc11c\ubc84\ub85c \uc790\ub9ac\ub97c \uc798 \uc7a1\uc740 \uc11c\ubc84\ub97c \uc704\ud574 Spring WebFlux\uac00 \ub4f1\uc7a5\ud588\ub2e4. \\n\ucd94\uac00\ub85c \ub370\uc774\ud130 \uc811\uadfc\uc744 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 JDBC\uc758 \uacbd\uc6b0 Blocking API\ub77c, Spring Webflux\uc5d0\uc11c\ub294 R2DBC\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uace0 \ud55c\ub2e4. \\n\\n### \ub9c8\uce58\uba70\\n\\n\ud574\ub2f9 \uc815\ub9ac \ub0b4\uc6a9\uc758 \uacbd\uc6b0 Async, Non Blocking \uad00\ub828\ub41c \ub0b4\uc6a9\uc744 \uae4a\uac8c \uacf5\ubd80\ud55c \uc801\uc774 \uc5c6\uc5b4\uc11c \uc815\ud655\ud558\uc9c0 \uc54a\uc744 \uc218 \uc788\ub2e4. \\n\uadf8\ub798\ub3c4 \uae30\uc220\uc758 \ub4f1\uc7a5 \ubc30\uacbd\uc774\ub098 \uacfc\uc815\uc744 \uc54c\uace0 \uc788\ub2e4\uba74 \uc870\uae08 \ub354 \uae4a\uc774 \uc788\ub294 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815, \uad6c\uad6c \uac15\uc758 \\n[Dynamic Content with CGI, Apache Tutorial](https://httpd.apache.org/docs/trunk/en/howto/cgi.html) \\n[History of Spring and the Spring Framework, Spring](https://docs.spring.io/spring-framework/reference/overview.html#overview-history) \\n[Understanding JavaServer Pages Model 2 architecture, Govind Seshadri](https://www.infoworld.com/article/2076557/understanding-javaserver-pages-model-2-architecture.html) \\n[MVC, XEROX PARC](https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html) \\n[Expert One-to-One J2EE Development, Rod Johnson](https://www.amazon.com/Expert-One-One-Development-without/dp/0764558315) \\n[\ubc30\ub2ec\uc758\ubbfc\uc871 \ucd5c\uc804\ubc29 \uc2dc\uc2a4\ud15c! \u2018\uac00\uac8c\ub178\ucd9c \uc2dc\uc2a4\ud15c\u2019\uc744 \uc18c\uac1c\ud569\ub2c8\ub2e4, \ubc30\ub2ec\uc758\ubbfc\uc871](https://techblog.woowahan.com/2667/) \\n[Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu](https://www.infoworld.com/article/2077995/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html)\\n[WebFlux Overview, Spring](https://docs.spring.io/spring-framework/reference/web/webflux/new-framework.html)\\n[Spring WebFlux\uc640 Armeria\ub97c \uc774\uc6a9\ud558\uc5ec Microservice\uc5d0 \ud544\uc694\ud55c Reactive + RPC \ub3d9\uc2dc\uc5d0 \uc7a1\uae30, Naver D2](https://d2.naver.com/helloworld/6080222) \\n[Spring WebFlux\ub780 \ubb34\uc5c7\uc77c\uae4c](https://tweety1121.tistory.com/entry/Spring-WebFlux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C)"},{"id":"log-async-exception","metadata":{"permalink":"/log-async-exception","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx","source":"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx","title":"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45","description":"\ubb38\uc81c \uc0c1\ud669","date":"2023-09-18T00:00:00.000Z","formattedDate":"2023\ub144 9\uc6d4 18\uc77c","tags":[{"label":"async","permalink":"/tags/async"},{"label":"exception","permalink":"/tags/exception"}],"readingTime":3.615,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45","slug":"log-async-exception","tags":["async","exception"]},"prevItem":{"title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","permalink":"/web-application-evolution"},"nextItem":{"title":"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/tomcat-retrospective"}},"content":"### \ubb38\uc81c \uc0c1\ud669\\n\\n\ud604\uc7ac \ud2b8\ub9bd\ub4dc\ub85c\uc6b0\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ub418\uace0 \uc788\ub2e4. \ub85c\uadf8\ub97c \ud655\uc778\ud558\ub294 \ub3c4\uc911 `@Async`\uac00 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ub85c\uadf8\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \ucd9c\ub825\ub418\uc9c0 \uc54a\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4. \\n\ud655\uc778\ud574 \ubcf4\ub2c8 Spring\uc758 `@ControllerAdvice` + `@ExceptionHandler`\uc758 \uacbd\uc6b0 \ub3d9\uae30 \uc608\uc678\ub9cc \ucc98\ub9ac\ud558\uace0, \ube44\ub3d9\uae30 \uc608\uc678\ub97c \ucc98\ub9ac\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \ubc1c\uc0dd\ud55c \ubb38\uc81c\uc600\ub2e4. \\n\\n### \ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815\\n\\n\uc2a4\ud504\ub9c1 4.1 \ubd80\ud130 \uc81c\uacf5\ub418\ub294 [AsyncUncaughtExceptionHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html)\uc758 \uacbd\uc6b0 \ubc18\ud658 \ud0c0\uc785\uc774 void\uc778 \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\ub97c \uc608\uc678 \ucc98\ub9ac\ud558\uae30 \uc27d\ub3c4\ub85d \ub3c4\uc640\uc900\ub2e4. \\n\\n\ub530\ub77c\uc11c AsyncUncaughtExceptionHandler \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud574\uc11c \uc608\uc678\ub97c \ud578\ub4e4\ub9c1\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud588\ub2e4. \\n\uae30\uc874\uc758 \ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \uc608\uc678\uac00 \ubc1c\uc0dd\ud560 \ub54c \uc2e4\ud589 \ud750\ub984\uc744 \ucd94\uc801\ud558\uae30 \uc704\ud574 MDC(Mapped Diagnostic Context)\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4. \\n\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\ub3c4 \ub9c8\ucc2c\uac00\uc9c0\ub85c MDC\uc758 \uc815\ubcf4\ub97c \uac00\uc838\uc640\uc11c \ub85c\uadf8\ub97c \ucd9c\ub825\ud558\ub3c4\ub85d \uc124\uc815\ud588\ub2e4. \\n\\n```java title=AsyncExceptionHandler\\n@Slf4j\\npublic class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {\\n\\n private static final String LOG_FORMAT = \\"[%s] %s\\";\\n\\n @Override\\n public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {\\n log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);\\n }\\n}\\n```\\n\\nAsyncExceptionHandler\uc758 \uacbd\uc6b0 AsyncConfigurer\ub97c \uad6c\ud604\ud55c Configuration \ud074\ub798\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4. \\ngetAsyncUncaughtExceptionHandler() \uba54\uc11c\ub4dc\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec AsyncExceptionHandler\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uba74 \ub41c\ub2e4. \\n\\n```java title=AsyncConfig\\n@EnableAsync\\n@Configuration\\npublic class AsyncConfig implements AsyncConfigurer {\\n\\n @Override\\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\\n return new AsyncExceptionHandler();\\n }\\n}\\n```\\n\\n\uc774\uc81c \ube44\ub3d9\uae30 \uc0c1\ud669\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 AsyncUncaughtExceptionHandler\uc758 \uad6c\ud604\uccb4\uc778 AsyncExceptionHandler\uac00 \uc608\uc678\ub97c \uc7a1\uc544 \ucc98\ub9ac\ud55c\ub2e4. \\n\\n### MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c\\n\\n\ube44\ub3d9\uae30 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \ubcc4\ub3c4\uc758 \uc2a4\ub808\ub4dc\uc5d0\uc11c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 ThreadLocal \uae30\ubc18\uc73c\ub85c \ub3d9\uc791\ud558\ub294 MDC\uc758 \uc815\ubcf4\ub97c \uc5bb\uc5b4\uc62c \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4. \\n\\n![./mdc-null.png](./mdc-null.png)\\n\\n\uc2a4\ud504\ub9c1 4.3 \uc774\uc0c1\ubd80\ud130 \uc81c\uacf5\ub418\ub294 [TaskDecorator](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html)\ub97c \uc774\uc6a9\ud558\uba74 TaskExecutor\ub97c \ucee4\uc2a4\ud130\ub9c8\uc774\uc9d5 \ud560 \uc218 \uc788\ub2e4. TaskDecorator\ub97c \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \ud558\ub098 \uc0dd\uc131\ud558\uace0, Task\uac00 \uc2e4\ud589\ub418\uae30 \uc804 MDC\uc758 \uc815\ubcf4\ub97c \ubcf5\uc0ac\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. \\n\\n```java title=MdcTaskDecorator\\npublic class MdcTaskDecorator implements TaskDecorator {\\n\\n @Override\\n public Runnable decorate(final Runnable runnable) {\\n Map<String, String> threadContext = MDC.getCopyOfContextMap();\\n return () -> {\\n MDC.setContextMap(threadContext);\\n runnable.run();\\n };\\n }\\n}\\n```\\n\\n\uc0dd\uc131\ud55c Decorator \ud074\ub798\uc2a4\ub97c \uc124\uc815 \ud30c\uc77c\uc5d0 \ub4f1\ub85d\ud574 \uc900\ub2e4.\\n\\n```java title=AsyncConfig\\n@RequiredArgsConstructor\\n@EnableAsync\\n@Configuration\\npublic class AsyncConfig implements AsyncConfigurer {\\n\\n private final AsyncConfigurationProperties properties;\\n\\n @Bean\\n public ThreadPoolTaskExecutor taskExecutor() {\\n ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();\\n executor.setCorePoolSize(properties.coreSize());\\n executor.setMaxPoolSize(properties.maxSize());\\n executor.setQueueCapacity(properties.queueCapacity());\\n \\n // highlight-next-line\\n executor.setTaskDecorator(new MdcTaskDecorator());\\n executor.setWaitForTasksToCompleteOnShutdown(true);\\n executor.initialize();\\n return executor;\\n }\\n\\n @Override\\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\\n return new AsyncExceptionHandler();\\n }\\n}\\n```\\n\\n\uc124\uc815 \ud6c4\uc5d0\ub294 \uc815\uc0c1\uc801\uc73c\ub85c MDC\uc5d0 \ub4e4\uc5b4\uac00 \uc788\ub294 UUID\uac00 \ucd9c\ub825\ub418\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4.\\n\\n![./mdc-not-null.png](./mdc-not-null.png)\\n\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[spring async, baeldung](https://www.baeldung.com/spring-async) \\n[@Async will not call by @ControllerAdvice for global exception](https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception) \\n[Spring \uc758 \ub3d9\uae30, \ube44\ub3d9\uae30, \ubc30\uce58 \ucc98\ub9ac\uc2dc \ud56d\uc0c1 context \ub97c \uc720\uc9c0\ud558\uace0 \ub85c\uae45\ud558\uae30, \uac15\ub0a8\uc5b8\ub2c8](https://blog.gangnamunni.com/post/mdc-context-task-decorator/) \\n[TaskDecorator, Spring docs](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html) \\n[AsyncUncaughtExceptionHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html)"},{"id":"tomcat-retrospective","metadata":{"permalink":"/tomcat-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","description":"1, 2\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-http/pull/302","date":"2023-09-11T00:00:00.000Z","formattedDate":"2023\ub144 9\uc6d4 11\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":12.345,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","slug":"tomcat-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45","permalink":"/log-async-exception"},"nextItem":{"title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958","permalink":"/performance-test-type"}},"content":":::note PR \ub9c1\ud06c \\n1, 2\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-http/pull/302 \\n3, 4\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-http/pull/431\\n:::\\n\\n### \ud1b0\ucea3 \uad6c\ud604\\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c0\uc6d0\ud560 \ub54c \uac1d\uccb4\uc9c0\ud5a5\uacfc \uad00\ub828\ub41c \ubbf8\uc158\ub3c4 \uae30\ub300\ub97c \ub9ce\uc774 \ud588\uc9c0\ub9cc \ub808\ubca8 4\uc5d0 \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc774 \uc815\ub9d0 \ud558\uace0 \uc2f6\uc5c8\ub2e4. \\n\uadf8\ub798\uc11c \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc744\uae4c\ub77c\ub294 \uac71\uc815 \ubc18, \ubbf8\uc158\uc5d0 \ub300\ud55c \uae30\ub300 \ubc18\uc73c\ub85c \ubd80\ud47c \ub9c8\uc74c\uc744 \uac00\uc9c0\uace0 \ubbf8\uc158\uc744 \uc2dc\uc791\ud588\ub358 \uac83 \uac19\ub2e4. \\n\\n\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc801\uc808\ud558\uac8c \ucd94\uc0c1\ud654\ud558\uace0, \ubbf8\uc158\uc758 \ubcf8\uc9c8\uc744 \uc774\ud574\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158\uc740 [RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616/)\uc5d0 \uba85\uc2dc\ub41c \uc2a4\ud399(\uc644\ubcbd\ud558\uc9c0 \uc54a\uc9c0\ub9cc \ubbf8\uc158\uc5d0\uc11c \uc8fc\uc5b4\uc9c4 \uc694\uad6c\uc0ac\ud56d\ub9cc \ub9cc\uc871\ud558\ub3c4\ub85d)\uc73c\ub85c \uc694\uccad\uc744 \ubc1b\uc544 \ucc98\ub9ac \ud6c4 \ubc18\ud658\ud558\ub294\ub370 \uc9d1\uc911\ud588\ub2e4. \\n\\n### \ub2e4\uc774\uc5b4\uadf8\ub7a8\\n\\nCatalina\ub294 Tomcat\uc758 \uc11c\ube14\ub9bf \ucee8\ud14c\uc774\ub108, Coyote\ub294 HTTP 1.1 \uc6f9 \uc11c\ubc84\ub97c \uc9c0\uc6d0\ud558\ub294 \uad6c\uc131 \uc694\uc18c\ub77c\uace0 \uc0dd\uac01\ud558\uace0 \uc544\ub798\uc640 \uac19\uc774 \uad6c\uc131\ud588\ub2e4. \\n\uc0ac\uc2e4 \ub0b4\ubd80 \uad6c\uc870\ub97c \uae4a\uac8c \uacf5\ubd80\ud560 \uc2dc\uac04\uc744 \uac00\uc9c0\uc9c0 \ubabb\ud574\uc11c \uac01 \uad6c\uc131 \uc694\uc18c\uac00 \uc65c \ud574\ub2f9 \uc704\uce58\uc5d0 \uc788\ub294\uc9c0 \uc644\ubcbd\ud558\uac8c \uc124\uba85\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc774\uac74 \uc5ec\uae30\uc5d0 \uc788\uc73c\uba74 \uc88b\uc744 \uac83 \uac19\uc740\ub370? \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e4\uba74 \uc801\uc808\ud55c \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\uc2dc\ud0a4\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\ub2e4. \\n\ub610\ud55c \uc801\uc808\ud558\uac8c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc73c\ub85c \ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tsubgraph coyote\\n\\t\\tHP[Http11Processor] --\x3e A\\n\\t\\tHP --\x3e HttpRequestParser\\n\\t\\tHP --\x3e HttpResponseGenerator\\n\\t\\tA[Adapter]\\n end\\n\\n subgraph catalina\\n\\t\\tRA[RequestAdapter] -.-> A\\n\\t\\tAC[AbstractController] -.-> C[Controller]\\n\\t\\tStaticController -.-> AC\\n\\t\\tSM[SessionManger] -.-> Manager\\n\\t\\tTC[Tomcat] --\x3e RA\\n\\t\\tRA --\x3e C\\n\\t\\tRA --\x3e Manager\\n\\t\\tRA --\x3e RM\\n\\t\\tRM[RequestMapper] --\x3e C\\n end\\n\\n subgraph jwp\\n\\t\\tLC[LoginController] -.-> AC\\n\\t\\tApplication --\x3e TC\\n end\\n\\n```\\n\\n### \ucf54\ub4dc \ub9ac\ubdf0 \\n\\n\ud06c\ub8e8 \uc911 \ud55c \uba85\uc774 \ub098\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\uace0, \ub0b4\uac00 \ub2e4\ub978 \ud06c\ub8e8\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\ub294 \ud615\ud0dc\ub85c \uc9c4\ud589\uc774 \ub418\uc5c8\ub2e4. \\n\ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub514\ub178, \ub9ac\ubdf0\uc774\ub294 \ud544\ub9bd\uc774\uc5c8\ub2e4. \\n\\n\ub514\ub178(\ub9e4\uc758 \ub208\uc774 \uc544\ub2cc \uacf5\ub8e1\uc758 \ub208?)\uac00 \ub9e4\uc6b0 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud574\uc8fc\uc5b4\uc11c \uc870\uae08 \ub354 \ub098\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \uc218 \uc788\uc5c8\uace0, \ud544\ub9bd\uc758 \ucf54\ub4dc\uc5d0\uc11c\ub294 \uaf3c\uaf3c\ud558\uac8c \uc608\uc678\ucc98\ub9ac \ud558\ub294 \ubd80\ubd84\uc744 \ubc30\uc6b8 \uc218 \uc788\uc5c8\ub2e4. \\n\ud55c \uac00\uc9c0 \uc544\uc26c\uc6b4 \uc810\uc740 \ud544\ub9bd\uc5d0\uac8c \uc791\uc131\ud55c \ub098\uc758 \ucf54\uba58\ud2b8\ub4e4\uc774 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uacbd\ud5d8 \uae30\ubc18\uc73c\ub85c \uc791\uc131\ud55c \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uadfc\uac70\uac00 \uc870\uae08 \ubd80\uc871\ud588\uace0, \uc815\ub9ac\ub418\uc9c0 \uc54a\uc740 \ubd80\ubd84\uc774 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4. \\n\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130 \ub9ac\ubdf0\ud560 \ub54c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ub354 \uc88b\uc740 \ub0b4\uc6a9\uc744 \ud06c\ub8e8\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. \\n\\n### SessionConfig\\n\\n\ubbf8\uc158\uc744 \uc9c4\ud589 \uc911 catalina \ud328\ud0a4\uc9c0\uc758 Session \uad00\ub828 \ubd80\ubd84\uc744 \ubcf4\uba74\uc11c \uc911\ubcf5 \ub85c\uc9c1\uc744 \uac1c\uc120\ud574 \ubcfc \uc218 \uc788\uc744 \uac83 \uac19\uc544 [\ucee8\ud2b8\ub9ac\ubdf0\ud2b8](https://github.com/apache/tomcat/pull/660)\ub97c \uc2dc\ub3c4\ud588\ub2e4. \\n\uc138\uc158 \ucfe0\ud0a4\uc758 \uc774\ub984\uc744 \uac00\uc838\uc624\ub294 Util \ud074\ub798\uc2a4\uc758 \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub294\ub370 \uae30\ubcf8 \uac12\uc740 JSESSIONID \uc9c0\ub9cc \uc124\uc815\uc5d0 \ub530\ub77c\uc11c \uc138\uc158 \ucfe0\ud0a4\uba85\uc744 \ub2e4\ub974\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ub85c\uc9c1\uc774 \uc788\ub294 \uac83\uc73c\ub85c \uc0dd\uac01\ud588\ub2e4. \\n\uae30\uc874\uc758 \ucf54\ub4dc\ub294 \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \ucf54\ub4dc\uc758 \ud750\ub984\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc544\uc11c \uc57d\uac04 \uc774\ud574\ud558\uae30 \uc5b4\ub824\uc6e0\ub2e4. \\n\\n\ucd08\uae30\uc5d0 \uc694\uccad\ud588\ub358 PR\uc740 \uae30\uc874\uc758 \ucf54\ub4dc\ubcf4\ub2e4 \uc804\uccb4\uc801\uc73c\ub85c \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, context\uac00 null\uc778 \uacbd\uc6b0 \ubc14\ub85c \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud568\uc73c\ub85c\uc368 \uc131\ub2a5 \uac1c\uc120\uc758 \ud6a8\uacfc\uac00 \uc788\uc744 \uac70\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uba54\uc778\ud14c\uc774\ub108\uc778 Mark Thomas \ud615\uc774 \ud574\ub2f9 \ub85c\uc9c1\uc758 \uacbd\uc6b0 \ucef4\ud30c\uc77c\ub7ec\uac00 \ud574\ub2f9 \ubd80\ubd84\uc744 \ucd5c\uc801\ud654 \ud560 \uc218 \uc788\uc744 \uac70\ub77c\uace0 \uae30\ub300\ud55c\ub2e4\uace0 \ud588\uace0, \uac00\ub3c5\uc131\uc744 \uac1c\uc120\uc2dc\ucf1c\ubcf4\ub77c\uace0 \uc870\uc5b8\ud574\uc8fc\uc168\ub2e4. \\n\ucef4\ud30c\uc77c\ub7ec \ucd5c\uc801\ud654\ub294 \uace0\ub824\ud574\ubcf4\uc9c0 \ubabb\ud55c \ubd80\ubd84\uc778\ub370, \uc55e\uc73c\ub85c \ud559\uc2b5\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc0b0\ub354\ubbf8\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n\ub0a8\uaca8\uc900 \ucf54\uba58\ud2b8\uc5d0 \ub530\ub77c \ucd5c\uc885\uc801\uc73c\ub85c\ub294 \uc911\ubcf5\ub41c \ucf54\ub4dc\ub97c \uc904\uc774\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub2e4. \\n\uacb0\uacfc\uc801\uc73c\ub85c \uae30\uc874 \ub85c\uc9c1 \ub300\ube44 \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \uc720\uc0ac\ud55c \ud750\ub984\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \ud588\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\nimport Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n<Tabs>\\n<TabItem value=\\"\uae30\uc874\\" label=\\"\uae30\uc874\\">\\n\\n```java\\npublic static String getSessionCookieName(Context context) {\\n\\n String result = getConfiguredSessionCookieName(context);\\n\\n if (result == null) {\\n result = DEFAULT_SESSION_COOKIE_NAME;\\n }\\n\\n return result;\\n}\\n\\npublic static String getSessionUriParamName(Context context) {\\n\\n String result = getConfiguredSessionCookieName(context);\\n\\n if (result == null) {\\n result = DEFAULT_SESSION_PARAMETER_NAME;\\n }\\n\\n return result;\\n}\\n\\nprivate static String getConfiguredSessionCookieName(Context context) {\\n\\n // Priority is:\\n // 1. Cookie name defined in context\\n // 2. Cookie name configured for app\\n // 3. Default defined by spec\\n if (context != null) {\\n String cookieName = context.getSessionCookieName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n\\n SessionCookieConfig scc =\\n context.getServletContext().getSessionCookieConfig();\\n cookieName = scc.getName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n }\\n\\n return null;\\n}\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"PR \uc694\uccad\\" label=\\"PR \uc694\uccad\\">\\n\\n```java\\npublic static String getSessionCookieName(Context context) {\\n if (context == null) {\\n return DEFAULT_SESSION_COOKIE_NAME;\\n }\\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\\n}\\n\\npublic static String getSessionUriParamName(Context context) {\\n if (context == null) {\\n return DEFAULT_SESSION_PARAMETER_NAME;\\n }\\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\\n}\\n\\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\\n // Priority is:\\n // 1. Cookie name defined in context\\n // 2. Cookie name configured for app\\n // 3. Default defined by spec\\n String cookieName = context.getSessionCookieName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n\\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\\n cookieName = scc.getName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n\\n return defaultName;\\n}\\n```\\n</TabItem>\\n\\n<TabItem value=\\"\ucd5c\uc885\\" label=\\"\ucd5c\uc885\\">\\n\\n```java\\npublic static String getSessionCookieName(Context context) {\\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\\n}\\n\\npublic static String getSessionUriParamName(Context context) {\\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\\n}\\n\\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\\n // Priority is:\\n // 1. Cookie name defined in context\\n // 2. Cookie name configured for app\\n // 3. Default defined by spec\\n if (context != null) {\\n String cookieName = context.getSessionCookieName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n\\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\\n cookieName = scc.getName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n }\\n return defaultName;\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n### HTTP \uc218\uc5c5\\n\\n\ubbf8\uc158 \uc911\uac04\uc5d0 \uc9c4\ud589\ub418\uc5c8\ub358 HTTP \uc218\uc5c5\uc5d0\ub294 HTTP\ub97c \uc801\uc808\ud558\uac8c \ud65c\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4. \\n\ud56d\uc0c1 \uc131\ub2a5 \uac1c\uc120\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub2e8\uc5d0\uc11c \ucd5c\uc801\ud654\ud574\ubcf4\ub824\uace0 \ub178\ub825\uc744 \ud588\uc9c0\ub9cc, \ub354 \uc801\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ud6a8\uc728\uc801\uc73c\ub85c \uc131\ub2a5\uc744 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc54c \uc218 \uc788\uc5c8\ub358 \uc218\uc5c5\uc774\uc5c8\ub2e4. \\nHTTP \uc555\ucd95, HTTP \uce90\uc2f1, \ub9ac\uc18c\uc2a4 \ucd5c\uc801\ud654 \uae30\ubc95\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4. \\n\\n\uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \ub2e4\uc74c \uc635\uc158\uc744 \uc124\uc815\ud558\uc5ec http\uc758 \uc1a1\uc218\uc2e0\uc758 \uc555\ucd95\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\ub2e4. \\n\\n```yml\\nserver:\\n compression:\\n enabled: true\\n```\\n\\n\uc218\uc5c5 \uc911 \ud574\ub2f9 \uc555\ucd95 \uc131\ub2a5\uc774 \uc88b\ub2e4\uba74 \uc65c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \uae30\ubcf8 \uac12\uc73c\ub85c \uc124\uc815\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\uc9c0 \uad81\uae08\ud574\uc84c\ub2e4. \\n\uad81\uae08\uc99d\uc744 \ud574\uc18c\ud558\uc9c0 \ubabb\ud588\ub294\ub370 \ub9d0\ub791\uc774 \uc7a1\ub2f4 \ucc44\ub110\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc740 [issue](https://github.com/spring-projects/spring-boot/issues/21369)\ub97c \ucc3e\uc544\uc8fc\uc5c8\ub2e4. \\n\ub0b4\uc6a9\uc744 \uc694\uc57d\ud574 \ubcf4\uc790\uba74 WAS \ubcc4\ub85c \uc555\ucd95\uc744 \ud558\uae30 \uc704\ud574 \uc124\uc815\ud574\uc57c \ud558\ub294 \uac83\uc774 \ub2e4\ub974\uace0, \ubb34\uc870\uac74 \uc555\ucd95\uc744 \ud558\ub294 \uac83\uc774 \ucd5c\uc801\uc758 \uacbd\uc6b0\uac00 \uc544\ub2d0 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 \uac19\ub2e4. \\n\\n> If you\'re developing a public-facing application then it\'s probably likely gzip compression would be worthwhile. If, however, you\'re a microservice application and you\'re in a dataceter, you may well prefer to reduce CPU load because you know you\'ll only be talking to other microservices and you have a reliable gigabit network.\\n\\nPhil Webb \ud615\ub2d8\uc758 \ub9d0\uc5d0 \ub530\ub974\uba74 \uc77c\ubc18\uc801\uc778 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \uacbd\uc6b0 gzip \uc555\ucd95\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc9c0\ub9cc, MSA \ud658\uacbd + \ub370\uc774\ud130 \uc13c\ud130\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \uc624\uc9c1 \ub2e4\ub978 MSA \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uacfc \ud1b5\uc2e0\ud558\uace0, \uace0\uc131\ub2a5 \ub124\ud2b8\uc6cc\ud06c\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0 CPU \ubd80\ud558\ub97c \uc904\uc774\ub294 \uac83\uc774 \uc6b0\uc120\uc2dc \ub420 \uc218\ub3c4 \uc788\ub2e4\ub294 \uac83\uc774\uc5c8\ub2e4. \\n\\n\uc774\uc678\uc5d0\ub3c4 \uc758\ub3c4\ud558\uc9c0 \uc54a\uc740 \uce90\uc2f1\uc744 \ub9c9\uae30 \uc704\ud574 \ud734\ub9ac\uc2a4\ud2f1 \uce90\uc2f1\uc744 \uc81c\uac70\ud558\uac70\ub098, \uac1c\uc778 \uc815\ubcf4 \uc720\ucd9c\uc744 \ub9c9\uae30 \uc704\ud574 \uc751\ub2f5 \ud5e4\ub354\uc5d0 private\uc744 \uc124\uc815, ETag\ub3c4 \ud559\uc2b5\ud588\ub2e4. \\n\\n:::note ETag\\nETag HTTP \uc751\ub2f5 \ud5e4\ub354\ub294 \ud2b9\uc815 \ubc84\uc804\uc758 \ub9ac\uc18c\uc2a4\ub97c \uc2dd\ubcc4\ud558\ub294 \uc2dd\ubcc4\uc790\ub2e4. \\n\uc6f9 \uc11c\ubc84\uac00 \ub0b4\uc6a9\uc744 \ud655\uc778\ud558\uace0 \ubcc0\ud558\uc9c0 \uc54a\uc558\uc73c\uba74, \uc6f9 \uc11c\ubc84\ub85c full \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0, \uce90\uc2dc\uac00 \ub354 \ud6a8\uc728\uc801\uc774\uac8c \ub41c\ub2e4. \\nMDN\\n:::\\n\\n### Thread \uc218\uc5c5\\n\\n\uc2a4\ub808\ub4dc\uc5d0 \ub300\ud55c \uc218\uc5c5\uc744 \ub4e4\uc5c8\uc9c0\ub9cc, \ubcf5\uc7a1\ud55c \ub0b4\uc6a9\ub3c4 \uc6cc\ub099 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0 \uc124\uba85\ud558\ub77c\uace0 \ud558\uba74 \uc798 \ubabb\ud560 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e0\ub2e4. \\n\ud604\uc7ac \ud504\ub85c\uc81d\ud2b8, \ubbf8\uc158, \ud14c\ucf54\ud1a1 \uc900\ube44\ub97c \ubcd1\ud589\ud574\uc57c \ud574\uc11c \uc138\ubd80\uc801\uc778 \ub0b4\uc6a9\uc740 \uc2dc\uac04 \ub0a0 \ub54c \ubcf5\uc2b5\ud558\ub824\uace0 \ud55c\ub2e4. \\n\\n\uc2a4\ub808\ub4dc\ub97c \uc774\ud574\ud558\uace0, WAS\uc5d0 \uc2a4\ub808\ub4dc \uc124\uc815 \uad00\ub828\ud55c \uc2e4\uc2b5\uc774 \uc788\uc5c8\ub294\ub370 \ud14c\uc624\uc640 \uac19\uc774 1\uc2dc\uac04 \uc815\ub3c4 \ud398\uc5b4\ub85c Thread \uc2e4\uc2b5\uc744 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4. \\n\ud559\uc2b5\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n`threads.max`: Tomcat\uc758 \ucd5c\ub300 \uc2a4\ub808\ub4dc \uac1c\uc218 \\n`max-connections`: Tomcat\uc774 \uc720\uc9c0\ud560 \uc218 \uc788\ub294 \ucd5c\ub300 \ucee4\ub125\uc158 \uac1c\uc218 \\n`accept-count`: \ucd5c\ub300 \uc5f0\uacb0 \uc218\uc5d0 \ub3c4\ub2ec\ud588\uc744 \ub54c \uc5f0\uacb0 \uc694\uccad\uc5d0 \ub300\ud574 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub300\uae30\uc5f4\uc758 \ucd5c\ub300 \uae38\uc774. \ud574\ub2f9 Queue\uc5d0 \uc694\uccad\uc774 \uc313\uc774\ub294 \uac83\uc740 Tomcat\uc774 \ub354 \uc774\uc0c1 \uc694\uccad\uc744 \ubc1b\uc744 \uc218 \uc5c6\ub2e4\ub294 \ub73b\uc774\ub2e4. accpet-count queue\uc5d0\ub3c4 \uc694\uccad\uc774 \uac00\ub4dd\ucc28\uba74 \uadf8 \uc774\ud6c4\uc5d0 \uc624\ub294 \uc694\uccad\uc740 \uac70\ubd80\ub41c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n C(\\"Client\\") -- request --\x3e ACQ(\\"\uc6b4\uc601\uccb4\uc81c\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue \\n size = accept-count\\") --\x3e TCQ(\\"Tomcat Connector\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue\\n size = max-connections\\") --\x3e TP(\\"Thread Pool\\n size = threads.max\\")\\n```\\n\\n### \ub9c8\uce58\uba70\\n\\n\uc2dc\uac04\uc740 \ub108\ubb34 \ube60\ub974\uac8c \uac00\uace0 \ud560 \uc77c\uc740 \ub9ce\uc740 \uac83 \uac19\ub2e4. \\n\uc6b0\uc120\uc21c\uc704\ub97c \uc798 \uc815\ud558\uace0 \ud559\uc2b5\uc744 \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4. \\n\ud604\uc7ac \ub370\uc774\ud130 \ub2e4\ub8e8\ub294 \ubd80\ubd84(DB)\uc5d0 \ub300\ud55c \ud559\uc2b5\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\ub2e4. \ud574\ub2f9 \ubd80\ubd84\uc740 \ud14c\ucf54\ud1a1\uc774 \ub05d\ub098\ub294\ub300\ub85c \ucc44\uc6cc\uc57c\uaca0\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616/) \\n[ETag, mdn](https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/ETag) \\n[Apache Tomcat 8 Configuration Reference](https://tomcat.apache.org/tomcat-8.5-doc/config/http.html) \\n[Apache Tomcat Tuning, Terry Cho](https://bcho.tistory.com/788) \\n[maxThreads, maxConnections, acceptCount\ub85c Tomcat \ud29c\ub2dd\ud558\uae30](https://dev-ws.tistory.com/96)"},{"id":"performance-test-type","metadata":{"permalink":"/performance-test-type","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx","source":"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx","title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958","description":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8","date":"2023-09-10T00:00:00.000Z","formattedDate":"2023\ub144 9\uc6d4 10\uc77c","tags":[{"label":"performance test","permalink":"/tags/performance-test"}],"readingTime":5.8,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958","slug":"performance-test-type","tags":["performance test"]},"prevItem":{"title":"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/tomcat-retrospective"},"nextItem":{"title":"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30","permalink":"/db-replication"}},"content":"## \uc131\ub2a5 \ud14c\uc2a4\ud2b8\\n\\nAPI\uc758 \uc694\uccad\uc774 \ub9ce\uc740 \uc0c1\ud669\uc5d0\uc11c \uc11c\ubc84\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8\\n\\n\uc2dc\uc2a4\ud15c\uc5d0 \ubd80\ud558\uac00 \uac78\ub9ac\uba74 \ubb38\uc81c \uc0c1\ud669\uc774 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \\n\ub2e4\uc591\ud55c \uc0c1\ud669\uc5d0 \ub300\ube44\ud574\uc11c \uc131\ub2a5 \ud14c\uc2a4\ud2b8\ub97c \ud574\uc57c\ud55c\ub2e4. \\n\\n![./test.png](./test.png)\\n\\n### \uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)\\n\\n\ucd5c\uc18c\ud55c\uc758 \ubd80\ud558\ub97c \uc8fc\uc5b4 \uc2dc\uc2a4\ud15c\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\nVU\ub97c \ucd5c\uc18c\ud55c\uc73c\ub85c \ub450\uace0, \uc9e7\uc740 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \ud14c\uc2a4\ud2b8\ud55c\ub2e4. \\n\ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \uc2dc\uc791\ud558\uae30 \uc804\uc5d0 \uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud568\uc73c\ub85c\uc368 \ud14c\uc2a4\ud2b8 \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc624\ub958\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\uace0, \uc131\ub2a5 \uc9c0\ud45c\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \uc218\uc9d1, \ubaa8\ub2c8\ud130\ub9c1 \ub418\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n:::note \uac00\uc0c1 \uc0ac\uc6a9\uc790(VU)\\n\uac00\uc0c1 \uc0ac\uc6a9\uc790\ub294 \uc11c\ubc84 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0 \ub300\ud574 \ud2b9\uc815 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c\ub2e4. \\n\uc774\ub294 \ub2e4\ub978 \uac00\uc0c1 \uc0ac\uc6a9\uc790\uc640 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589\ub418\uba70, \uc5ec\ub7ec \uac00\uc0c1 \uc0ac\uc6a9\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub3d9\uc2dc \uc5f0\uacb0\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\uc2a4\ub808\ub4dc\ub77c\uace0 \uc0dd\uac01\ud558\uba74 \ub41c\ub2e4. \\n:::\\n\\n### \uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)\\n\\n\uc0ac\uc6a9\ub7c9\uc774 \uae09\uc99d\ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uacac\ub514\uace0 \uc131\ub2a5\uc5d0 \ubb38\uc81c\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\n\ud2f0\ucf13 \ubc1c\uae09, \ud560\uc778 \ucfe0\ud3f0 \ubc1c\uae09\uacfc \uac19\uc740 \uc774\ubca4\ud2b8\ub97c \ud558\ub294 \uacbd\uc6b0 \ub300\uaddc\ubaa8 \ud2b8\ub798\ud53d\uc774 \ub4e4\uc5b4\uc628\ub2e4. \\n\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud574 \uae09\uc99d\ud558\ub294 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\uace0, \ubd80\ud558\ub97c \uc798 \ubc84\ud2f0\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n### \ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)\\n\\n\ubaa9\ud46f\uac12\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \uacac\ub51c \uc218 \uc788\uc744\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\n\uc77c\ubc18\uc801\uc778 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8\ub2e4. \\n\ub7a8\ud504\uc5c5 \ub610\ub294 \ubb19\ud46f\uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ubd80\ud558 \uae30\uac04\ub3d9\uc548 \uc131\ub2a5\uc774 \ubb38\uc81c\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\uace0, \uc2dc\uc2a4\ud15c \ubcc0\uacbd \ud6c4\uc5d0\ub3c4 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \ub3cc\ub824 \ub3d9\uc77c\ud558\uac8c \ubaa9\ud46f\uac12\uc744 \ucc98\ub9ac\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n:::note \ub7a8\ud504 \uc5c5(Ramp-up)\\n\ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud574 \uc124\uc815\ud55c \uac00\uc0c1 \uc0ac\uc6a9\uc790 \uc218\uc5d0 \ub3c4\ub2ec\ud558\ub294 \ub370 \uac78\ub9ac\ub294 \uc2dc\uac04\\n:::\\n\\n### \uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test) \\n\\n\uc2dc\uc2a4\ud15c\uc758 \ucd5c\ub300\uce58\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \ubc1b\uc558\uc744 \ub54c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\n\uadf8\ub798\ud504\ub97c \ubd24\uc744 \ub54c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc640 \uc720\uc0ac\ud55c \ud615\ud0dc\ub85c \ubcf4\uc774\uc9c0\ub9cc, \ubd80\ud558\ub7c9\uc774 \ub2e4\ub974\ub2e4. \\n\uc77c\ubc18\uc801\uc73c\ub85c \ud3c9\uade0\uc801\uc778 \ubaa9\ud46f\uac12 \ub300\ube44 \uc791\uac8c\ub294 50% \uc774\uc0c1, \ud544\uc694\uc758 \uacbd\uc6b0 \uadf8 \uc774\uc0c1\uc73c\ub85c \ubd80\ud558\ub97c \uc900\ub2e4. \\n\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub294 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c \ud6c4\uc5d0\ub9cc \uc2e4\ud589\ud574\uc57c \ud55c\ub2e4. \ubd80\ud558 \ud14c\uc2a4\ud2b8\uac00 \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\uc740 \uc0c1\ud669\uc5d0\uc11c \uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ubcd1\ubaa9 \uc9c0\uc810\uc774\ub098 \ubb38\uc81c \uc0c1\ud669\uc744 \ucc3e\uae30 \uc5b4\ub824\uc6cc\uc9c4\ub2e4. \\n\ub610\ud55c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \uc0ac\uc6a9\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c VU\uac12(\uc2a4\ub808\ub4dc \uc218)\ub9cc \uc218\uc815\ud558\uc5ec \uc7ac\uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\\n### \ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test) \\n\\n\ud3c9\uade0 \uc0ac\uc6a9\ub960\ub85c \uc77c\uc815 \ubd80\ud558\ub97c \uc9c0\uc18d\uc801\uc73c\ub85c \uc8fc\uba70 \uc2dc\uc2a4\ud15c\uc774 \ubb38\uc81c\ub418\ub294 \uc9c0\uc810\uc744 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\n\ud761\uc218 \ud14c\uc2a4\ud2b8(Soak Test)\ub77c\uace0\ub3c4 \ud558\uba70, \uae30\ubcf8\uc801\uc778 \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc758 \ubcc0\ud615\uc774\ub77c\uace0 \ubcfc \uc218 \uc788\ub2e4. \\n\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc640 \ub2ec\ub9ac \uae34 \uc2dc\uac04\ub3d9\uc548 \ud14c\uc2a4\ud2b8\ub97c \ud558\ub294 \uac83\uc774 \ud2b9\uc9d5\uc774\uba70, \uba54\ubaa8\ub9ac \ub204\uc218 \ubb38\uc81c\uc640 \uac19\uc774 \uc7a5\uc2dc\uac04 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc2e4\ud589\ud560 \ub54c \uc2dc\uc2a4\ud15c\uc758 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \ubd80\ubd84\uc744 \ud655\uc778\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4. \\n\\n### \uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)\\n\\n\uc784\uacc4 \uc9c0\uc810\uc744 \ucc3e\uae30 \uc704\ud574 \ubd80\ud558\ub97c \uc810\uc9c4\uc801\uc73c\ub85c \uc99d\uac00\uc2dc\ud0a4\uba70 \uc9c4\ud589\ud558\ub294 \ud14c\uc2a4\ud2b8\\n\\n\ubb38\uc81c\ub418\ub294 \ubd80\ubd84\uc744 \ub354 \ube68\ub9ac \ucc3e\uae30 \uc704\ud574 \ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\uacfc\ud55c \ub2e4\uc74c\uc5d0 \uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud558\uace0, \uc774 \ub54c \uc810\uc9c4\uc801\uc73c\ub85c \ubd80\ud558\ub97c \ub298\ub824\ub098\uac00\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc131\ub2a5 \ud29c\ub2dd\uacfc \ubc18\ubcf5\ud574\uc11c \uc9c4\ud589\ud55c\ub2e4\uba74, \uc2dc\uc2a4\ud15c\uc744 \ub354\uc6b1 \ubc1c\uc804\uc2dc\ud0ac \uc218 \uc788\ub2e4. \\n\ub2e4\ub9cc Auto Scaling\uc774 \uc801\uc6a9\ub41c \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd\uc5d0\uc11c\ub294 \uc9c4\ud589\ud558\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[Load test types, k6](https://k6.io/docs/test-types/load-test-types/) \\n\uc790\ubc14 \ucd5c\uc801\ud654 - \ubca4\uc800\ubbfc J. \uc5d0\ubc88\uc2a4, \uc81c\uc784\uc2a4 \uace0\ud504, \ud06c\ub9ac\uc2a4 \ub274\ub79c\ub4dc \\n\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04"},{"id":"db-replication","metadata":{"permalink":"/db-replication","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx","source":"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx","title":"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30","description":"\ubcf5\uc81c(Replication)","date":"2023-08-22T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 22\uc77c","tags":[{"label":"mysql","permalink":"/tags/mysql"},{"label":"replication","permalink":"/tags/replication"}],"readingTime":21,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30","slug":"db-replication","tags":["mysql","replication"]},"prevItem":{"title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958","permalink":"/performance-test-type"},"nextItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0","permalink":"/woowacourse-level3-retrospective"}},"content":"## \ubcf5\uc81c(Replication)\\n\\n\ud55c \uc11c\ubc84\uc5d0\uc11c \ub2e4\ub978 \uc11c\ubc84\ub85c \ub370\uc774\ud130\ub97c \ub3d9\uae30\ud654\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4. \\n\uc6d0\ubcf8 \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Primary \ub610\ub294 Source \ub77c\uace0 \ubd80\ub974\uace0, \ubcf5\uc81c\ub41c \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Secondary \ub610\ub294 Replica \ub77c\uace0 \ubd80\ub978\ub2e4. \\n\\n### \ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720\\n\\n**1. \uc2a4\ucf00\uc77c \uc544\uc6c3**\\n\\n\uc0ac\uc6a9\uc790\uc758 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0, \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uac00\ud574\uc9c0\ub294 \ubd80\ud558\ub3c4 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc99d\uac00\ud55c\ub2e4. \\n\uc774\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud574 \ubcf5\uc81c\ub97c \ud1b5\ud55c \uc2a4\ucf00\uc77c \uc544\uc6c3\uc744 \uc801\uc6a9\ud558\uc5ec \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucffc\ub9ac\ub4e4\uc744 \uac01\uac01\uc758 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub85c \ubd84\uc0b0 \uc2dc\ud0ac \uc218 \uc788\ub2e4. \\n\\n**2. \ub370\uc774\ud130 \ubc31\uc5c5**\\n\\n\uc2e4\uc81c \uc6b4\uc601\ub418\ub294 \uc11c\ube44\uc2a4\uac00 \uc0ac\uc6a9\ud558\uace0 \uc788\ub294 DB\uc5d0\uc11c \ubc31\uc5c5\uc744 \uc9c4\ud589\ud558\ub294 \uacbd\uc6b0, \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c \uc2e4\uc81c \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc774 \uac00\uc9c0 \uc54a\ub3c4\ub85d \ubcf5\uc81c\ub97c \ud1b5\ud574 Replica \uc11c\ubc84\ub97c \uad6c\ucd95\ud558\uc5ec, Replica \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ub97c \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\uc73c\ub85c \uc601\ud5a5\uc744 \ucd5c\uc18c\ud654 \ud560 \uc218 \uc788\ub2e4. \\n\\n**3. \ub370\uc774\ud130 \ubd84\uc11d**\\n\\n\ubc31\uc5c5\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc7a1\ud558\uace0 \ubb34\uac70\uc6b4 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\uc758 \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4. \\n\ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc81c\ub97c \uc0ac\uc6a9\ud574 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ud658\uacbd\uc744 \ub9cc\ub4e4 \uc218 \uc788\ub2e4. \\n\\n**4. \ub370\uc774\ud130\uc758 \uc9c0\ub9ac\uc801 \ubd84\uc0b0**\\n\\n\ube60\ub978 \uc751\ub2f5\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc11c\ubc84\uc5d0 \uac00\uae5d\uac8c \uc11c\ubc84\ub97c \uad6c\uc131\ud558\uac70\ub098, \uace0\uac00\uc6a9\uc131(High Availability)\uc744 \uc704\ud574\uc11c\ub3c4 \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n### \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c\\n\\nMySQL \uc11c\ubc84\uc5d0\uc11c \ubc1c\uc0dd\ud558\ub294 \ubcc0\uacbd\uc0ac\ud56d\uc5d0 \ub300\ud55c \ub85c\uadf8 \ud30c\uc77c\uc744 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub77c\uace0 \ud55c\ub2e4. \\n\ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ud1b5\ud574 \ub370\uc774\ud130 \ubcc0\uacbd, \ud14c\uc774\ube14 \uad6c\uc870 \ubcc0\uacbd, \uacc4\uc815\uc774\ub098 \uad8c\ud55c \ubcc0\uacbd\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc800\uc7a5\ub41c\ub2e4. \\nMySQL\uc758 \ubcf5\uc81c\ub294 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 \uc788\ub2e4. \uc774\ub97c Replica \uc11c\ubc84\ub85c \uc804\ub2ec\ud558\uace0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \ub370\uc774\ud130\ub97c \ubcc0\uacbd \uc0ac\ud56d\uc744 \ubc18\uc601\ud55c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tsubgraph Replica\\n\\t\\tdirection TB\\n\\t\\tIO[Replication I/O thread] -- save --\x3e RL[Relay Log]\\n\\t\\tSQL[Replication SQL Thread] -- read --\x3e RL\\n\\tend\\n\\n\\tsubgraph Source\\n\\t\\tdirection TB\\n\\t\\tBLD[Binary Log Dump Thread] -- Send Binary Log Dump--\x3e IO\\n\\tend\\n\\n```\\n\\n:::note \uc2a4\ub808\ub4dc\ubcc4 \uc5ed\ud560\\n\\nBinary Log Dump Thread: \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc758 \ub0b4\uc6a9\uc744 Replica \uc11c\ubc84\ub85c \uc804\ub2ec \\nReplication I/O Thread: Binary \ub85c\uadf8 \uc774\ubca4\ud2b8\ub97c \uac00\uc838\uc640 \ub85c\uceec \uc11c\ubc84\uc758 \ud30c\uc77c(Relay Log)\ub85c \uc800\uc7a5 \\nReplication SQL Thread: \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc774\ubca4\ud2b8\ub97c \uc77d\uace0 \uc2e4\ud589\\n\\n:::\\n\\n### \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810\\n\\n\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc740 \uc11c\ubc84\uc5d0 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud588\uc744 \ub54c \ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0 \ubcc0\uacbd\uc774 \uae4c\ub2e4\ub86d\ub2e4. \\n\ud1a0\ud3f4\ub85c\uc9c0\ub780 \ub124\ud2b8\uc6cc\ud06c\uc758 \uc694\uc18c\ub4e4\uc744 \ubb3c\ub9ac\uc801\uc73c\ub85c \uc5f0\uacb0\ud574 \ub193\uc740 \uac83, \ub610\ub294 \uadf8 \uc5f0\uacb0 \ubc29\uc2dd\uc744 \ub9d0\ud55c\ub2e4.\\n\\n```mermaid\\ngraph TD\\n\\tA[A binary-log:300] --\x3e B[B Binary-log:300]\\n\\tA[A binary-log:300] --\x3e C[C Binary-log:200]\\n```\\n\\n\uc704\uc640 \uac19\uc774 Source \uc11c\ubc84, Replica 2\ub300\uac00 \uc874\uc7ac\ud558\uace0, C \uc11c\ubc84\uc5d0 \ubcf5\uc81c \uc9c0\uc5f0\uc774 \ub418\uc5c8\uc744 \ub54c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\\n```mermaid\\ngraph TD\\n\\tA[A binary-log:300]\\n\\tB[B Binary-log:300] --\x3e C[C Binary-log:200 \ubb38\uc81c \ubc1c\uc0dd]\\n```\\n\\nA \uc11c\ubc84\uc5d0\uc11c \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 B \uc11c\ubc84\ub97c Source \uc11c\ubc84\ub85c \uc2b9\uaca9\ud558\uace0, C\uc5d0\uac8c \uc870\ud68c \ucffc\ub9ac\ub97c \ubd84\uc0b0\uc2dc\ud0a8\ub2e4. \\n\ud558\uc9c0\ub9cc \uc5ec\uae30\uc11c C \uc11c\ubc84\uc5d0\ub294 A \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\uac00 \uc548\ub418\uc5c8\uc73c\ub2c8 \uc870\ud68c \uc2dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\ub4a4\ub2a6\uac8c B \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\ub97c \ud558\ub824\uace0 \ud574\ub3c4, \uc5b4\ub5a4 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8, \uc5b4\ub5a4 \uc704\uce58\uc640 \ub3d9\uae30\ud654\ud574\uc57c\ud558\ub294\uc9c0 \uc54c\uae30 \uc5b4\ub835\ub2e4. \\n\\n### \uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c\\n\\nGTID \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ubc1c\uc0dd\ud55c \uc774\ubca4\ud2b8\uc5d0 \uace0\uc720\ud55c \uc2dd\ubcc4\uac12\uc744 \ubd80\uc5ec\ud55c\ub2e4\uba74, \ub3d9\uae30\ud654\uc5d0 \ub300\ud55c \ubb38\uc81c\ub97c \uac04\ub2e8\ud558\uac8c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4. \\n\uc704\uc758 \uc608\uc2dc\uc640 \uac19\uc774 \ubcf5\uc81c \uc9c0\uc5f0\uacfc \ud568\uaed8 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\ud574\ub3c4 \ud2b9\uc815 GTID \ubd80\ud130 \ubcf5\uc81c\ub97c \uc7ac\uac1c\ud558\uba74 \ub41c\ub2e4. \\n\\n:::note GTID\\n\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0\uc5d0 \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \uc11c\ubc84\uc5d0\uc11c \uace0\uc720\ud558\ub3c4\ub85d \uac01 \uc774\ubca4\ud2b8\uc5d0 \ubd80\uc5ec\ub41c \uc2dd\ubcc4\uac12 \\n[source_id]:[transaction_id]\ub85c \uad6c\uc131\ub418\uba70, source_id\ub294 \uc11c\ubc84\ub97c \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc774\uace0 transaction_id\ub294 \ucee4\ubc0b\ub41c \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc73c\ub85c 1\uc529 \uc99d\uac00\ud558\ub294 \ud615\ud0dc\ub85c \ubc1c\uae09\ub41c\ub2e4. \\n:::\\n\\n### \ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0\\n\\n**\uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131**\\n\\n\uac00\uc7a5 \uac04\ub2e8\ud55c \uad6c\uc131\uc73c\ub85c \uc81c\uc77c \ub9ce\uc774 \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4. \\nreplica \uc11c\ubc84\ub97c \uc77d\uae30 \uc804\uc6a9, \uc608\ube44 \uc11c\ubc84, \ubc31\uc5c5 \uc6a9\ub3c4\ub85c \ub9ce\uc774 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\\n W -- \uc77d\uae30 --\x3e R\\n S[Source] --\x3e R[Replica]\\n```\\n\\n**\uba40\ud2f0 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131**\\n\\n2\uac1c\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4. \\n\ud558\ub098\uc758 replica\ub294 \uc608\ube44 \uc6a9\ub3c4\ub85c \ub0a8\uaca8\ub450\ub294 \ud615\ud0dc\ub2e4. \\n\ucd94\ud6c4\uc5d0 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0 \uc608\ube44 \uc6a9\ub3c4\uc758 replica\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c \uc77d\uae30 \uc694\uccad\uc758 \ubd80\ud558 \ubd84\uc0b0\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\\n```mermaid\\ngraph LR\\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\\n W -- \uc77d\uae30 --\x3e R1\\n S[Source] --\x3e R1[Replica1]\\n S --\x3e R2[Replica2]\\n```\\n\\n**\uccb4\uc778 \ubcf5\uc81c \uad6c\uc131**\\n\\nreplica \uc11c\ubc84\uac00 \ub9ce\uc740 \uacbd\uc6b0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \uc804\ub2ec\ud558\ub294 \uc791\uc5c5 \uc790\uccb4\uac00 \ubd80\ud558\uac00 \ub420 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c 1:M:M \uad6c\uc870\ub85c \uccb4\uc778 \ubcf5\uc81c \uad6c\uc131\uc744 \uace0\ub824\ud560 \uc218 \uc788\ub2e4. \\n\\n```mermaid\\ngraph LR\\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\\n W -- \uc77d\uae30 --\x3e R1\\n S[Source] --\x3e R1[Replica1]\\n S --\x3e R2[Replica2]\\n S --\x3e R3[Replica3]\\n\\n R3 --\x3e R3-1[Replica 3-1]\\n R3 --\x3e R3-2[Replica 3-2]\\n\\n B[Batch Server] --\x3e R3-2\\n```\\n\\n**\ub4c0\uc5bc \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131**\\n\\n2\uac1c\uc758 MySQL \uc11c\ubc84 \ubaa8\ub450 \uc77d\uae30\uc640 \uc4f0\uae30\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d \ud558\ub294 \uad6c\uc131\uc774\ub2e4. \\n\uac01 \uc11c\ubc84\uc5d0\uc11c \ubcc0\uacbd\ub41c \ub370\uc774\ud130\ub294 \ub2e4\ub978 \uc11c\ubc84\uc5d0 \ubc18\uc601\ub41c\ub2e4. \\n\ubaa9\uc801\uc5d0 \ub530\ub77c ACTIVE-ACTIVE \ud615\ud0dc \ub610\ub294 ACTIVE-PASSIVE \ud615\ud0dc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. \\nACTIVE-PASSIVE \ud615\ud0dc\uc778 \uacbd\uc6b0 \uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131\uacfc \ub3d9\uc77c\ud574\ubcf4\uc774\uc9c0\ub9cc, ACTIVE \uc11c\ubc84\uc5d0\uc11c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uba74 \uc124\uc815\uc758 \ubcc0\uacbd\uc5c6\uc774 PASSIVE \uc11c\ubc84\ub85c \uc4f0\uae30 \uc791\uc5c5\uc744 \uc804\ud658\ud560 \uc218 \uc788\ub2e4\ub294 \uac83\uc774 \uc7a5\uc810\uc774\ub2e4. \\n\\n```mermaid\\ngraph LR\\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR1\\n W -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR2\\n SR1[Source/Replica 1] --\x3e SR2[Source/Replica 2]\\n```\\n\\n:::note ACTIVE-ACTIVE, ACTIVE-PASSIVE\\nACTIVE-ACTIVE: 2\uac1c\uc758 \uc11c\ubc84 \ubaa8\ub450 \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc \\nACTIVE-PASSIVE: \ud558\ub098\uc758 \uc11c\ubc84\uc5d0\uc11c\ub9cc \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc\\n:::\\n\\n**\uba40\ud2f0 \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131**\\n\\n\uc5ec\ub7ec\uac1c\uc758 source \uc11c\ubc84\uc640 \ud558\ub098\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \uad6c\uc131\uc774\ub2e4. \\n\uc774\ub294 source \uc11c\ubc84\uc758 \ub370\uc774\ud130\ub97c \ud55c \uacf3\uc5d0 \ubc31\uc5c5\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9, \uc5ec\ub7ec \uc11c\ubc84\uc5d0 \uc874\uc7ac\ud558\ub294 \ub370\uc774\ud130\ub97c \ud1b5\ud569, \uc0e4\ub529\ub418\uc5b4\uc788\ub294 \ud14c\uc774\ube14 \ub370\uc774\ud130\ub97c \ud1b5\ud569\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n S1[Source 1] --\x3e R[Replica]\\n S2[Source 2] --\x3e R\\n```\\n\\n## \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30\\n\\nmysql 2\ub300\ub97c \uc774\uc6a9\ud558\uc5ec replication\uc744 \uad6c\uc131\ud558\uace0, spring boot application\uc73c\ub85c source, replica \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc811\uadfc\ud574\ubcf4\ub294 \uc608\uc81c\uc774\ub2e4. \\n[https://github.com/bbiac/db-replication](https://github.com/bbiac/db-replication) \\n\\n### MySQL \ud658\uacbd \uad6c\uc131\\n\\nMySQL \ubc84\uc804\uc740 8.1\uc744 \uc0ac\uc6a9\ud588\ub2e4. \\n13306, 13307 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud574\uc11c MySQL \uc11c\ubc84 2\ub300\ub97c \ub744\uc6e0\ub2e4. \\n\ub610\ud55c \uc0ac\uc2e4 IP \ub300\uc5ed\uc73c\ub85c \ud1b5\uc2e0\ud560 \uc218 \uc788\ub3c4\ub85d \ucee4\uc2a4\ud140 \ub124\ud2b8\uc6cc\ud06c\ub97c \ucd94\uac00\ud588\ub2e4. \\n\\n```yml\\nversion: \'3.8\'\\n\\nservices:\\n source:\\n platform: linux/x86_64\\n image: mysql:latest\\n restart: always\\n container_name: mysql-source\\n environment:\\n TZ: \'Asia/Seoul\'\\n MYSQL_DATABASE: \'db\'\\n MYSQL_USER: \'user\'\\n MYSQL_PASSWORD: \'password\'\\n MYSQL_ROOT_PASSWORD: \'password\'\\n ports:\\n - \\"13306:3306\\"\\n volumes:\\n - db-source:/var/lib/mysql\\n - db-source:/var/lib/mysql-files\\n - ./docker/source.cnf:/etc/mysql/my.cnf\\n networks:\\n - mysql_network\\n\\n replica:\\n platform: linux/x86_64\\n image: mysql:latest\\n restart: always\\n container_name: mysql-replica\\n environment:\\n TZ: \'Asia/Seoul\'\\n MYSQL_DATABASE: \'db\'\\n MYSQL_USER: \'user\'\\n MYSQL_PASSWORD: \'password\'\\n MYSQL_ROOT_PASSWORD: \'password\'\\n ports:\\n - \\"13307:3306\\"\\n volumes:\\n - db-replica:/var/lib/mysql\\n - db-replica:/var/lib/mysql-files\\n - ./docker/replica.cnf:/etc/mysql/my.cnf\\n networks:\\n - mysql_network\\n\\nvolumes:\\n db-source:\\n db-replica:\\n\\nnetworks:\\n mysql_network:\\n driver: bridge\\n```\\n\\n\ub610\ud55c source, replica \uac01\uac01 \ub2e4\uc74c\uacfc \uac19\uc774 db \uc124\uc815\uc744 \ud588\ub2e4. \\n\\n| \uc124\uc815 | \uc124\uba85 |\\n| --- | --- |\\n| server_id | \uac01\uac01\uc758 mysql \ub9c8\ub2e4 \uace0\uc720\ud55c \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4. |\\n| log_bin | \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815\uc73c\ub85c \uc808\ub300\uacbd\ub85c\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 /var/lib/mysql \uc544\ub798 \ud574\ub2f9 log_bin\uc5d0 \uc124\uc815\ub41c \uac12\uc73c\ub85c \ub85c\uadf8\uac00 \uc0dd\uc131\ub41c\ub2e4. |\\n| sync_binlog | N\uac1c\uc758 \ud2b8\ub79c\uc7ad\uc158 \ub2f9 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ub514\uc2a4\ud06c\uc640 \ub3d9\uae30\ud654 \uc791\uc5c5\uc744 \ud558\ub3c4\ub85d \ud55c\ub2e4.\xa01\uc740 \uae30\ubcf8\uac12\uc73c\ub85c \uc548\uc815\uc801\uc774\uc9c0\ub9cc, \uac00\uc7a5 \ub290\ub9ac\ub2e4. |\\n| relay_log | \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815 |\\n| relay_log_purge | \ud544\uc694 \uc5c6\ub294 \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc744 \uc790\ub3d9\uc73c\ub85c \uc0ad\uc81c\ud558\ub294 \uc635\uc158 |\\n| read_only | \uc77d\uae30 \uc804\uc6a9 \uc124\uc815 |\\n| log_replica_updates | Replication SQL Thread\ub85c \uc778\ud574 \uc2e4\ud589\ub418\ub294 \uc815\ubcf4\ub97c \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc5d0 \uae30\ub85d \ucd94\ud6c4\uc5d0 \uc18c\uc2a4 \uc11c\ubc84\ub85c \uc2b9\uaca9\ub418\ub294 \uacbd\uc6b0\ub97c \uace0\ub824\ud558\uba74 \uc124\uc815\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. |\\n\\nimport Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n<Tabs>\\n<TabItem value=\\"Source\\" label=\\"Source\\">\\n\\n```cnf title=\\"/docker/source.cnf\\"\\n[mysqld]\\nserver_id=1\\nlog_bin=mysql-bin\\nsync_binlog=1\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"Replica\\" label=\\"Replica\\">\\n\\n```cnf title=\\"/docker/replica.cnf\\"\\n[mysqld]\\nserver_id=2\\nrelay_log=mysql-relay-bin\\nrelay_log_purge=ON\\nread_only\\nlog_replica_updates\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n### \ub3c4\ucee4 \uc2e4\ud589\\n\\ndocker-compose up \uba85\ub839\uc5b4\ub85c docker-compose \uc124\uc815\uc73c\ub85c docker\ub97c \ub744\uc6b4\ub2e4. \\n-d \uc635\uc158\uc744 \ubd99\uc774\uba74 \ubc31\uadf8\ub77c\uc6b4\ub4dc \ubaa8\ub4dc\ub85c \uc2e4\ud589\ub41c\ub2e4. \\n\\n```\\ndocker-compose up -d\\n```\\n\\n### replication slave \uad8c\ud55c \uc124\uc815\\n\\nREPLICATION SLAVE \uad8c\ud55c\uc774 \uc124\uc815\ub418\uc5b4 \uc788\uc5b4\uc57c replica \uc11c\ubc84\uc5d0\uc11c source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec \ub85c\uadf8\ub97c \uc77d\uc5b4\uc62c \uc218 \uc788\ub2e4. \\nsource \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec user \uacc4\uc815\uc5d0 \ud574\ub2f9 \uad8c\ud55c\uc744 \uc124\uc815\ud574\uc900\ub2e4. \\n\\nSOURCE \uc811\uc18d\\n\\n```bash\\ndocker exec -it mysql-source mysql -u root -p\\n```\\n\\nuser \uacc4\uc815\uc5d0 REPLICATION SLAVE \uad8c\ud55c \ucd94\uac00\\n\\n```mysql\\nGRANT REPLICATION SLAVE ON *.* TO \'user\'@\'%\';\\nFLUSH PRIVILEGES;\\n```\\n\\n### SOURCE DB \uc815\ubcf4 \ud655\uc778\\n\\nreplica \uc124\uc815\uc5d0 \ud544\uc694\ud55c source db\uc758 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c\uba85\uacfc Position\uc744 \ud655\uc778\ud55c\ub2e4. \\nPosition \uac12\uc740 \uc2e4\uc81c \ud30c\uc77c\uc758 \ubc14\uc774\ud2b8 \uc218\ub97c \uc758\ubbf8\ud55c\ub2e4. \\n\ud655\uc778\ud55c File(SOURCE_LOG_FILE)\uacfc Position(SOURCE_LOG_POS) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4.\\n\\n```mysql\\nSHOW MASTER STATUS;\\n\\n+------------------+----------+--------------+------------------+-------------------+\\n| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\\n+------------------+----------+--------------+------------------+-------------------+\\n| mysql-bin.000003 | 1082 | | | |\\n+------------------+----------+--------------+------------------+-------------------+\\n```\\n\\n### SOURCE ip \uc8fc\uc18c \ud655\uc778\\n\\ndocker inspect -f \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uba74 \ud574\ub2f9 \ucee8\ud14c\uc774\ub108\uc758 \uc138\ubd80 \uc815\ubcf4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud574 docker-compose \ud30c\uc77c\uc5d0 \uc124\uc815\ud574\ub454 mysql_network\uc5d0\uc11c \uc0ac\uc6a9\ub418\ub294 \uc0ac\uc124 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \ud655\uc778\ud55c\ub2e4. \\n\\n```bash\\ndocker inspect -f \\"{{with index .NetworkSettings.Networks \\\\\\"db-replication_mysql_network\\\\\\"}}{{.IPAddress}}{{end}}\\" mysql-source\\n```\\n\\nip \uc8fc\uc18c\uac00 \ub098\uc624\uc9c0 \uc54a\ub294 \uacbd\uc6b0 docker inspect mysql-source\ub85c \ud655\uc778\ud55c\ub2e4. \\n\ud655\uc778\ud55c IP\uc8fc\uc18c(SOURCE_HOST) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4.\\n\\n### replica mysql \uc811\uc18d\\n\\nsource db\uc5d0 \uc811\uc18d\ud588\ub358 \ubc29\ubc95\uacfc \ub3d9\uc77c\ud558\uac8c replica db\uc5d0 \uc811\uc18d\ud55c\ub2e4. \\n\\n```bash\\ndocker exec -it mysql-replica mysql -u root -p\\n```\\n\\n### replica \uc124\uc815\\n\\n\uc774\uc804\uc5d0 source db\uc5d0\uc11c \uc5bb\uc5c8\ub358 \uc815\ubcf4\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc5ec replica \uc124\uc815\uc744 \uc9c4\ud589\ud55c\ub2e4. \\n\uc2e4\uc81c DB \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc73c\ub85c source DB\uc758 \ud30c\uc77c\uc744 \ubcf5\uc81c\ud574\uc57c\ud558\uc9c0\ub9cc \ud604\uc7ac \ubcf5\uc81c\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ubd80\ubd84\uc740 \uc0dd\ub7b5\ud588\ub2e4. \\nSOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS \ub97c \uc801\uc808\ud788 \ubcc0\uacbd\ud55c\ub2e4.\\n\\n```mysql\\nSTOP REPLICA;\\n\\nCHANGE REPLICATION SOURCE TO \\nSOURCE_HOST=\'172.29.0.2\', \\nSOURCE_USER=\'user\', \\nSOURCE_PASSWORD=\'password\', \\nSOURCE_LOG_FILE=\'mysql-bin.000001\', \\nSOURCE_LOG_POS=0, \\nGET_SOURCE_PUBLIC_KEY=1;\\n\\nSTART REPLICA;\\n```\\n\\n### \uc124\uc815 \ud655\uc778\\n\\n```mysql\\nSHOW REPLICA STATUS;\\n\\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\\n| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |\\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\\n| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |\\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\\n```\\n\\nReplica_IO_Running, Replica_SQL_Running \uac12\uc774 YES\ub77c\uba74 \uc815\uc0c1\uc801\uc73c\ub85c replication \uad6c\uc131\uc774 \uc644\ub8cc\ub41c \uac83\uc774\ub2e4. \\n\\n\uc124\uc815\uc744 \ub9c8\uce5c \ud6c4 source db\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 create table \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud55c\ub2e4. \\nreplica db\uc5d0 \ub3d9\uc77c\ud55c member table\uc774 \uc0dd\uc131\ub41c \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n```sql\\nCREATE TABLE member\\n(\\n id BIGINT PRIMARY KEY AUTO_INCREMENT,\\n name VARCHAR(255)\\n);\\n```\\n\\n## \uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30\\n\\n\uc77c\ubc18\uc801\uc778 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 source, \uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158\uc778 \uacbd\uc6b0 replica\ub85c \uc694\uccad\uc774 \uac00\ub3c4\ub85d \uad6c\uc131\ud574\ubcf4\uc790. \\n\\n### Environment \uc124\uc815\\n\\n\ub2e4\uc74c\uacfc \uac19\uc774 source, replica\ub85c \uad6c\ubd84\ud558\uc5ec \uc124\uc815\ud55c\ub2e4. \\n\\n```yml title=\\"application.yml\\"\\nspring:\\n datasource:\\n source:\\n username: user\\n password: password\\n driver-class-name: com.mysql.cj.jdbc.Driver\\n jdbc-url: jdbc:mysql://localhost:13306/db\\n replica:\\n username: user\\n password: password\\n driver-class-name: com.mysql.cj.jdbc.Driver\\n jdbc-url: jdbc:mysql://localhost:13307/db\\n```\\n\\n### DataSourceType \uc124\uc815\\n\\n\ub2e8\uc21c \ubb38\uc790\uc5f4\ub85c\ub3c4 \uad6c\ubd84\ud560 \uc218 \uc788\uc9c0\ub9cc, enum\uc744 \uc774\uc6a9\ud574\uc11c \ud2b8\ub79c\uc7ad\uc158\uc744 \uad6c\ubd84\ud558\ub3c4\ub85d \uc0dd\uc131\ud55c\ub2e4. \\nKey\ub294 \ucd94\ud6c4\uc5d0 \ube48 \uc124\uc815\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n```java title=\\"DataSourceType\\"\\npublic enum DataSourceType {\\n SOURCE(SOURCE_NAME),\\n REPLICA(REPLICA_NAME),\\n ;\\n\\n private final String key;\\n\\n DataSourceType(String key) {\\n this.key = key;\\n }\\n\\n public static class Key {\\n public static final String ROUTING_NAME = \\"ROUTING\\";\\n public static final String SOURCE_NAME = \\"SOURCE\\";\\n public static final String REPLICA_NAME = \\"REPLICA\\";\\n }\\n}\\n```\\n\\n### AbstractRoutingDataSource \uc124\uc815\\n\\n\uc2a4\ud504\ub9c1\uc774 \uc9c0\uc6d0\ud574\uc8fc\ub294 AbstractRoutingDataSource\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSource\ub97c \ud5a5\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. \\n\\n\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub294 Map<DataSourceKey, DataSource>\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\uc744 \ubc1b\uc544 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4. \\n- setDefaultTargetDataSource: \uae30\ubcf8 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4. \\n- setTargetDataSources: \ub9f5 \ud615\ud0dc\ub85c \ubc1b\uc740 \ub370\uc774\ud130 \uc18c\uc2a4 \uac12\ub4e4\uc744 \uc124\uc815\ud55c\ub2e4. \\n\\ndetermineCurrentLookupKey\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. \\n- isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \ud2b8\ub79c\uc7ad\uc158\uc774 \uc77d\uae30 \uc804\uc6a9\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n- DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uace0, \ubc18\ud658\ud55c \uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ub370\uc774\ud130 \uc18c\uc2a4\uac00 \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n```java title=\\"RoutingDataSource\\"\\npublic class RoutingDataSource extends AbstractRoutingDataSource {\\n\\n private final Logger log = LoggerFactory.getLogger(getClass());\\n\\n public static RoutingDataSource from(Map<Object, Object> dataSources) {\\n RoutingDataSource routingDataSource = new RoutingDataSource();\\n routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));\\n routingDataSource.setTargetDataSources(dataSources);\\n return routingDataSource;\\n }\\n\\n @Override\\n protected Object determineCurrentLookupKey() {\\n boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();\\n\\n if (readOnly) {\\n log.info(\\"readOnly = true, request to replica\\");\\n return DataSourceType.REPLICA;\\n }\\n log.info(\\"readOnly = false, request to source\\");\\n return DataSourceType.SOURCE;\\n }\\n}\\n```\\n\\n### DataSource \uc124\uc815\\n\\n\uc704\uc5d0\uc11c\ubd80\ud130 \uc21c\uc11c\ub300\ub85c Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy \uc124\uc815\uc774\ub2e4. \\n\uc2a4\ud504\ub9c1\uc740 \ud2b8\ub79c\uc7ad\uc158 \uc2dc\uc791\uc2dc\uc5d0 \ucee4\ub125\uc158\uc758 \uc0ac\uc6a9\uc5ec\ubd80\uc640 \uc0c1\uad00\uc5c6\uc774 \ucee4\ub125\uc158\uc744 \ud655\ubcf4\ud55c\ub2e4. \\n\ub530\ub77c\uc11c readOnly \ud2b8\ub79c\uc7ad\uc158\uc774 \uc124\uc815\ub41c \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ubbf8\ub9ac \ud655\ubcf4\ub41c \ucee4\ub125\uc158\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 replica db\ub85c \uc694\uccad\uc744 \ud558\uc9c0 \uc54a\uace0 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4. \\n\\nTransactionSynchronizationManager.isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc \ud638\ucd9c \uc2dc currentTransactionReadOnly\ub77c\ub294 `ThreadLocal<Boolean>`\uc5d0 \uc124\uc815\ub41c \uac12\uc744 \ubc18\ud658\ud558\ub294\ub370 readOnly \uc124\uc815\uc774 \ub418\uba74 \uc774 \uac12\uc744 true\ub85c \uc124\uc815\ud55c\ub2e4. \ud558\uc9c0\ub9cc determineCurrentLookupKey\ub97c \ud638\ucd9c\ud558\uc5ec key \uac12\uc744 \uac00\uc838\uc624\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc774\ud6c4\uc5d0 \uc124\uc815\ub418\uae30 \ub54c\ubb38\uc5d0 determineCurrentLookupKey \uba54\uc11c\ub4dc\uc5d0\uc11c \ud56d\uc0c1 DataSourceType.SOURCE\uac00 \ubc18\ud658\ub418\uc5b4 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4. \\n\\nLazyConnectionDataSourceProxy\ub97c \uc124\uc815\ud558\ub294 \uacbd\uc6b0 \uc2e4\uc81c DataSource\ub97c \uc0ac\uc6a9\ud558\ub294 \uc2dc\uc810\uc5d0 \ucee4\ub125\uc158\uc744 \ud68d\ub4dd\ud574\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc124\uc815\ud55c\ub300\ub85c replica db\ub85c \uc870\ud68c \uc694\uccad\uc744 \ud55c\ub2e4. \\n\\n```java title=\\"DataSourceConfiguration\\"\\n@Configuration\\npublic class DataSourceConfiguration {\\n\\n @Bean\\n @Qualifier(SOURCE_NAME)\\n @ConfigurationProperties(prefix = \\"spring.datasource.source\\")\\n public DataSource sourceDataSource() {\\n return DataSourceBuilder.create().build();\\n }\\n\\n @Bean\\n @Qualifier(REPLICA_NAME)\\n @ConfigurationProperties(prefix = \\"spring.datasource.replica\\")\\n public DataSource replicaDataSource() {\\n return DataSourceBuilder.create().build();\\n }\\n\\n @Bean\\n @Qualifier(ROUTING_NAME)\\n public DataSource routingDataSource(\\n @Qualifier(SOURCE_NAME) DataSource sourceDataSource,\\n @Qualifier(REPLICA_NAME) DataSource replicaDataSource\\n ) {\\n return RoutingDataSource.from(Map.of(\\n DataSourceType.SOURCE, sourceDataSource,\\n DataSourceType.REPLICA, replicaDataSource\\n ));\\n }\\n\\n @Bean\\n @Primary\\n public DataSource dataSource(\\n @Qualifier(ROUTING_NAME) DataSource routingDataSource\\n ) {\\n return new LazyConnectionDataSourceProxy(routingDataSource);\\n }\\n}\\n```\\n\\n\ucd5c\uc885\uc801\uc73c\ub85c DataSource \ube48\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\uac00 \ub41c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n DSP[LazyConnectionDataSourceProxy] --\x3e RDS[RoutingDataSource]\\n\\tRDS --\x3e S[SourceDataSource]\\n\\tRDS --\x3e R[ReplicaDataSource]\\n```\\n\\n### \ub3d9\uc791 \ud655\uc778\\n\\n\uac04\ub2e8\ud558\uac8c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud574\uc11c \uc124\uc815\ud55c\ub300\ub85c \ub3d9\uc791\uc774 \ub418\ub294\uc9c0 \ud655\uc778\ud574\ubcf4\uc558\ub2e4. \\nsave \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 `@Transactional`, findById \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 `@Transactional(readOnly = true)`\uac00 \uc124\uc815\ub418\uc5b4\uc788\ub2e4. \\n\ub85c\uadf8\ub97c \ud1b5\ud574 save\uc758 \uacbd\uc6b0 source db\ub85c findById\uc758 \uacbd\uc6b0 replica db\ub85c \uc694\uccad\uc744 \ud558\ub294 \uac83\uc744 \uc54c \uc218 \uc788\ub2e4. \\n\\n```java title=\\"MemberServiceTest\\"\\n@SpringBootTest\\nclass MemberServiceTest {\\n\\n @Autowired\\n private MemberService memberService;\\n\\n @Test\\n void \uc0ac\uc6a9\uc790\ub97c_\uc800\uc7a5\ud55c\ub2e4() {\\n // RoutingDataSource log: readOnly = false\\n memberService.save(\\"bbiac\\");\\n }\\n\\n @Test\\n void \uc0ac\uc6a9\uc790\ub97c_\uc870\ud68c\ud55c\ub2e4() {\\n // RoutingDataSource log: readOnly = true\\n assertThatThrownBy(() -> memberService.findById(MAX_VALUE))\\n .isInstanceOf(NoSuchElementException.class);\\n }\\n}\\n```\\n\\nDB\uc5d0\uc11c\ub294 \ud655\uc778\ud558\ub824\uba74 root \uacc4\uc815\uc73c\ub85c \uc811\uc18d\ud55c \ud6c4 general log\ub97c \ud65c\uc131\ud654 \uc2dc\ud0a8\ub2e4. \\n\\n```sql\\nSET GLOBAL log_output = \'table\';\\nSET GLOBAL general_log = 1;\\n```\\n\\ngeneral log\ub97c \ud65c\uc131\ud654 \ud55c \ud6c4 \uc77d\uae30 \uc804\uc6a9 \uba54\uc11c\ub4dc\ub97c \uc2e4\ud589\ud55c\ub2e4. \\nserver_id, \uc2e4\ud589\ud55c \ucffc\ub9ac\ubb38\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n```sql\\nSELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like \'%select%\';\\n\\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\\n| user_host | thread_id | server_id | convert(argument using utf8) |\\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\\n| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |\\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\\n```\\n\\n\ud655\uc778 \ud6c4 general log\ub97c \ube44\ud65c\uc131\ud654 \ud55c \ud6c4 \ube44\ud65c\uc131\ud654 \ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. \\n```sql\\nSET GLOBAL general_log = 0;\\nSHOW VARIABLES LIKE \'%general%\';\\n\\n+------------------+---------------------------------+\\n| Variable_name | Value |\\n+------------------+---------------------------------+\\n| general_log | OFF |\\n| general_log_file | /var/lib/mysql/4b6b9db98290.log |\\n+------------------+---------------------------------+\\n```\\n\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n16\uc7a5 \ubcf5\uc81c, Real MySQL 8.0 - \ubc31\uc740\ube48, \uc774\uc131\uc6b1 \\n[Replication, MySQL Docs](https://dev.mysql.com/doc/refman/8.1/en/replication.html) \\n[MySql - Master Slave Replication \uad6c\uc870 \ub9cc\ub4e4\uc5b4\ubcf4\uae30](https://huisam.tistory.com/entry/mysql-replication) \\n[Spring \ub808\ud50c\ub9ac\ucf00\uc774\uc158 \ud2b8\ub79c\uc7ad\uc158 \ucc98\ub9ac \ubc29\uc2dd](https://cheese10yun.github.io/spring-transaction/) \\n[replication-datasource](https://github.com/kwon37xi/replication-datasource) \\n[Simplified Guide to MySQL Replication with Docker Compose](https://www.linkedin.com/pulse/simplified-guide-mysql-replication-docker-compose-rakesh-shekhawat/) \\n[Dockerfile\uc5d0\uc11c \uc790\uc8fc \uc4f0\uc774\ub294 \uba85\ub839\uc5b4](https://www.daleseo.com/dockerfile/) \\n[CHANGE REPLICATION SOURCE TO Statement](https://dev.mysql.com/doc/refman/8.1/en/change-replication-source-to.html) \\n[LazyConnectionDataSourceProxy](https://kwonnam.pe.kr/wiki/springframework/lazyconnectiondatasourceproxy) \\n[\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub808\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ud1b5\ud55c \ucffc\ub9ac \uc131\ub2a5 \uac1c\uc120 (feat. Mysql, SpringBoot)](https://hudi.blog/database-replication-with-springboot-and-mysql/) \\n[\ubd80\ud558 \ubd84\uc0b0\uc744 \uc704\ud55c MySQL Replication \uad6c\uc131 \ubc0f \ucffc\ub9ac \uc694\uccad \ubd84\uae30](https://chagokx2.tistory.com/100) \\n[Use Docker Compose, Docker](https://docs.docker.com/get-started/08_using_compose/)"},{"id":"woowacourse-level3-retrospective","metadata":{"permalink":"/woowacourse-level3-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx","source":"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx","title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0","description":"\ud68c\uace0","date":"2023-08-19T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 19\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.945,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0","slug":"woowacourse-level3-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30","permalink":"/db-replication"},"nextItem":{"title":"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","permalink":"/cloudwatch"}},"content":"import logo from \'./logo.png\';\\n\\n### \ud68c\uace0\\n\\n\uc9c0\ub09c 8\uc8fc\ub294 \ub808\ubca8 1, 2 \ub54c\ubcf4\ub2e4 5\ubc30 \uc815\ub3c4 \ube60\ub974\uac8c \uc9c0\ub098\uac04 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4. \\n\ub808\ubca8 3\uc5d0\ub294 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4, \uae30\uc220 \uc678\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4 \ubd80\uc871\ud568\uc774 \ub9ce\uc774 \ubcf4\uc600\ub358 \uac83 \uac19\ub2e4. \\n\ubd80\uc871\ud55c \ubd80\ubd84\uc744 \uc54c\uc558\uae30\uc5d0, \uc55e\uc73c\ub85c \ub354\uc6b1 \uc131\uc7a5\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. \\n\ub0b4\uac00 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \ud300\uc6d0\ub4e4\uc774 \uc798 \ubcf4\ucda9\ud574 \uc918\uc11c \ub4e0\ub4e0\ud588\ub2e4. \\n\\n### \uc544\uc26c\uc6b4 \uc810\\n\\n**\ubb38\uc11c\ud654**\\n\\n\uac1c\uc778\uc801\uc73c\ub85c\ub294 \uae30\uc220 \uc678\uc801\uc73c\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ub0b4\uac00 \ud55c \ubd80\ubd84\uc744 \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c, \uc774\ud574\ud558\uae30 \uc27d\uac8c \ubb38\uc11c\ud654\ub97c \ud588\ub354\ub77c\uba74 \ud300\uc6d0\ub4e4\uc5d0\uac8c \ub354\uc6b1 \ub3c4\uc6c0\uc774 \ub418\uc5c8\uc744 \ud150\ub370 \uc774 \ubd80\ubd84\uc5d0 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ud22c\uc790\ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc5d0\uc11c \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4. \\n\ubc29\ud559 \uae30\uac04 \ub3d9\uc548 \ubb38\uc11c\ud654\ub97c \ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc778 \ube14\ub85c\uadf8 \uc62c\ub9ac\uba74\uc11c \uc870\uae08 \ub354 \ucc44\uc6cc\ubcf4\ub824\uace0 \ud55c\ub2e4. \\n\\n**\ub0b4\uac00 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc774\uc790**\\n\\n\uc798 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc5ec\uc11c\ub77c\ub3c4 \uc911\uac04\uc740 \uac00\ub3c4\ub85d \ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4. \\n\ub9d0\uc744 \ud558\uae30 \uc804\uc5d0 \uc815\ub9ac\ud574\uc11c \uc758\uacac\uc744 \ub0b4\ub294 \uac83, \ubc1c\ud45c \uc900\ube44, \uac10\uc815 \uc870\uc808 \ub4f1\ub4f1\\n\ubabb\ud558\ub294 \ubd80\ubd84\uc744 \uc778\uc9c0\ud558\uace0, \uac1c\uc120\ud558\uc790. \\n\\n**\ucef4\ud3ec\ud2b8 \uc874 \ubc97\uc5b4\ub098\uae30**\\n\\n\uc870\uae08 \ub354 \ub3c4\uc804\uc801\uc73c\ub85c \ubaa9\ud45c\ub97c \uc7a1\uc558\uc73c\uba74 \uc88b\uc558\uc744 \uac83 \uac19\ub2e4. \\n\ub9e4\ubc88 \uadfc\uac70\ub97c \uac00\uc9c0\uace0 \uae30\uc220\uc744 \ub3c4\uc785\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\ud558\uc9c0\ub9cc \uc9c0\uc18d\uc801\uc73c\ub85c \uac1c\uc120\ud558\ub824\uace0 \ud558\ub294 \ubd80\ubd84\uc774 \ub2e4\uc18c \ubd80\uc871\ud588\ub2e4. \\n\\n### \uc88b\uc558\ub358 \uc810\\n\\n**\uc88b\uc558\ub358 \uc810\ub3c4 \ubb38\uc11c\ud654**\\n\\n[\ud300 \ube14\ub85c\uadf8](https://tripdraw.blog)\ub3c4 \uba3c\uc800 \ub3c4\uc785\ud558\uc790\uace0 \uc81c\uc548\ud558\uace0, \ub0b4\uac00 \ud588\ub358 \ubd80\ubd84\uc740 \ubb38\uc11c\ud654\ub97c \uaf64 \ub9ce\uc774 \ud574\uc11c \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ubc31\uc5d4\ub4dc \ud06c\ub8e8 4\uba85\uc774\uc11c \uac19\uc774 \ud55c \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c\ub294 \uae30\ub2a5 \uad6c\ud604\ud55c\ub2e4\uace0 \ubb38\uc11c\ud654\uac00 \uc870\uae08 \ubbf8\ud761\ud574\uc11c \ubcf4\ucda9\uc744 \ud574\uc57c\uaca0\ub2e4. \\n\\n**\ub0b4\uac00 \ub514\uc790\uc778\ud55c \ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0**\\n\\n<img src={logo} width=\\"100\\"/>\\n\\n\ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0\ub97c \ub9cc\ub4e4\uc5c8\ub2e4. \\n\ud300\uc6d0\ub4e4\uc774 \ub300\ud45c \uc0c9\uc0c1(\ud30c\ub780\uc0c9)\uc744 \uc815\ud574\uc92c\uace0, \uc8fc\ub9d0 \ub3d9\uc548 \uc2e0\ub098\uac8c \ub85c\uace0 \ub514\uc790\uc778\uc744 \ud588\ub358 \uac83 \uac19\ub2e4. \\n\uc544\ub798\uc758 D \ubd80\ubd84\uc740 \uc720\ud29c\ube0c \uac15\uc758 \ub4e4\uc73c\uba74\uc11c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\uc11c \ubfcc\ub4ef\ud558\ub2e4. \\n\\n**\uae30\uc220 \uc120\ud0dd\uc758 \uc774\uc720**\\n\\n\uae30\uc220\uc758 \ud559\uc2b5 \ube44\uc6a9, \ud604\uc7ac \uad6c\uc870\uc5d0 \uc801\ud569\ud55c\uc9c0, \uc2e4\uc81c \uac00\uc9c0\uace0 \uc788\ub294 \ub9ac\uc18c\uc2a4\ub97c \uace0\ub824\ud574\uc11c \uae30\uc220 \uc120\ud0dd\uc744 \ud558\uace0, \ub3c4\uc785\ud588\ub358 \ubd80\ubd84\uc774 \uc88b\uc558\ub2e4. \\n100% \uc88b\uc740 \uc120\ud0dd\uc77c \uc21c \uc5c6\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \uc120\ud0dd\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \uc874\uc7ac\ud55c\ub2e4\uba74 \ud655\ub960\uc744 \ub192\ud600\uc8fc\ub294 \uac83 \uac19\ub2e4. \\n\\n### \ub9c8\uce58\uba70\\n\\n\ud50c\ub808\uc774\uc2a4\ud1a0\uc5b4\uc5d0 \uc571\uc774 \uc62c\ub77c\uac00 \uc788\ub294 \uac70 \ub108\ubb34 \uc2e0\uae30\ud558\ub2e4. \\n\uc548\ub4dc\ub85c\uc774\ub4dc \ube0c\ub808\uba58 \uc74c\uc545\ub300(\uba67\ub3fc\uc9c0, \uc218\ub2ec, \ud551\uad6c), \uadf8\ub9ac\uace0 \ubc31\uc5d4\ub4dc \ud300\uc6d0\ub4e4(\uccb4\uc778\uc800, \ud6c4\ucd94, \ub9ac\uc624) \ub108\ubb34 \uace0\uc0dd\uc774 \ub9ce\uc558\ub2e4."},{"id":"cloudwatch","metadata":{"permalink":"/cloudwatch","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md","source":"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md","title":"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","description":"CloudWatch","date":"2023-08-17T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 17\uc77c","tags":[{"label":"cloudwatch","permalink":"/tags/cloudwatch"},{"label":"log","permalink":"/tags/log"},{"label":"monitoring","permalink":"/tags/monitoring"}],"readingTime":5.35,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","slug":"cloudwatch","tags":["cloudwatch","log","monitoring"]},"prevItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0","permalink":"/woowacourse-level3-retrospective"},"nextItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac","permalink":"/route-image-async-with-event"}},"content":"## CloudWatch\\n\\nAWS \ub9ac\uc18c\uc2a4\uc640 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc9c0\ud45c\uc640 \ub85c\uadf8\uc5d0 \ub300\ud55c \ubaa8\ub2c8\ud130\ub9c1\uc744 \uc81c\uacf5\ud558\ub294 \uc11c\ube44\uc2a4\ub2e4. \\n\uc9c0\ud45c\ub97c \uac10\uc2dc\ud558\uc5ec \uc54c\ub9bc\uc744 \ubcf4\ub0b4\ub294 \uae30\ub2a5\ub3c4 \uc81c\uacf5\ud55c\ub2e4. \\n\ud504\ub9ac\ud2f0\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \ub300\uc2dc\ubcf4\ub4dc\ub2f9 3$/M \uc758 \ube44\uc6a9\uc774 \uccad\uad6c\ub418\uace0, \uc9c0\ud45c\ub098 \ub85c\uadf8\uc758 \uc591\uc5d0 \ub530\ub77c \ube44\uc6a9\uc774 \ucd94\uac00\uc801\uc73c\ub85c \uccad\uad6c\ub41c\ub2e4. \\n\uc694\uae08 \uc815\ubcf4\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc815\ubcf4\ub294 [\ub2e4\uc74c \ub9c1\ud06c](https://aws.amazon.com/ko/cloudwatch/pricing/)\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n## CloudWatch Metrics\\n\\n\uae30\ubcf8\uc801\uc73c\ub85c 5\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc218\uc9d1\ub41c\ub2e4. \\n\uc138\ubd80 \ubaa8\ub2c8\ud130\ub9c1(Detailed Monitoring)\uc744 \ud65c\uc131\ud654\ud558\uba74 1\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\ub97c \uc218\uc9d1\ud55c\ub2e4. \\n\ub300\uc2dc\ubcf4\ub4dc\uc5d0\uc11c InstanceId\ub85c \uac80\uc0c9\ud558\uc5ec \uc218\uc9d1\ub41c \uc9c0\ud45c\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.\\n\\n![./cloudwatch1.png](./cloudwatch1.png)\\n\\nCPUUtilization, NetworkIn, NetworkOut\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 \uc9c0\ud45c\ub97c \uc81c\uacf5\ud558\uace0, \uba54\ubaa8\ub9ac, \ub514\uc2a4\ud06c \uacf5\uac04\uacfc \uac19\uc740 \uc9c0\ud45c\ub97c \ud655\uc778\ud558\ub824\uba74 \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\ub97c \uc124\uc815\ud574\uc57c \ud55c\ub2e4.\\n\\n## CloudWatch Agent \uc124\uce58\\n\\nCloudWatch Agent \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\uc640 \ub85c\uadf8\ub97c \uc218\uc9d1\ud560 \uc218 \uc788\ub2e4. \\n\\n### IAM \uc5ed\ud560 \uc124\uc815\\n\\n\uae30\ubcf8\uc801\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4\uac00 CloudWatchAgentServerPolicy\uc5d0 \ub300\ud55c \uad8c\ud55c\uc774 \uc788\uc5b4\uc57c \ud55c\ub2e4. \\nIAM \u2192 \uc5ed\ud560\uc5d0\uc11c \uc5ed\ud560 \uc0dd\uc131\uc744 \ud074\ub9ad\ud55c\ub2e4.\\n\\n![./cloudwatch2.png](./cloudwatch2.png)\\n\\nCloudWatchAgentServerPolicy \uad8c\ud55c \uc815\ucc45\uc744 \uc120\ud0dd\ud558\uace0, \uc801\ub2f9\ud55c \uc5ed\ud560 \uc774\ub984\uc744 \uc785\ub825\ud574\uc11c \uc5ed\ud560\uc744 \uc0dd\uc131\ud55c\ub2e4.\\n\\n![./cloudwatch3.png](./cloudwatch3.png)\\n\\nEC2 \uc778\uc2a4\ud134\uc2a4 \ubaa9\ub85d\uc73c\ub85c \ub4e4\uc5b4\uac00\uc11c, CloudWatch Agent\ub97c \uc124\uce58\ud560 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud074\ub9ad\ud55c\ub2e4. \\n\uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc5d0\uc11c \uc774\uc804\uc5d0 \uc0dd\uc131\ud55c \uc5ed\ud560\uc744 \uc9c0\uc815\ud55c\ub2e4.\\n\\n![./cloudwatch4.png](./cloudwatch4.png)\\n\\n### \uc124\uce58\\n\\n\ud658\uacbd\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\nOS: ubuntu 22.04 \\n\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small (ARM64) \\n\\n\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uce58\ud55c\ub2e4.\\n\\n```bash\\nwget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb\\nsudo dpkg -i -E ./amazon-cloudwatch-agent.deb\\n```\\n\\n[\uc0ac\uc6a9 \uc124\uba85\uc11c](https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html)\uc5d0 \uac01 \uc778\uc2a4\ud134\uc2a4 \uc720\ud615\ub9c8\ub2e4 \ub2e4\uc6b4\ub85c\ub4dc \ub9c1\ud06c\uac00 \uc790\uc138\ud558\uac8c \uc548\ub0b4\ub418\uc5b4 \uc788\ub2e4.\\n\\n### Wizard\\n\\nCloudWatch Wizard\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uc124\uc815 \ud30c\uc77c \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4. \\n\ub85c\uadf8\ub97c \uc218\uc9d1\ud558\ub3c4\ub85d \uc124\uc815\ud558\ub294 \uacbd\uc6b0 Wizard \uc2e4\ud589 \uba85\ub839\uc5b4 \uc785\ub825 \uc804 log \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \ubcf5\uc0ac\ud574\ub450\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec Wizard\ub97c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4. \\n\\n```bash\\nsudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard\\n```\\n\\n\uc124\uc815\uc744 \uc9c4\ud589\ud558\ub2e4 \ubcf4\uba74 \uc124\uc815 \ud30c\uc77c\uc774 \uc5b4\ub5bb\uac8c \uad6c\uc131\ub420\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\ub85c\uadf8\ub97c \ucd94\uac00\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \uc785\ub825\ucc3d\uc774 \ub098\uc624\uba74 \uc900\ube44\ud574\ub480\ub358 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \uc785\ub825\ud55c\ub2e4. \\n\\n![./cloudwatch5.png](./cloudwatch5.png)\\n\\n\uc911\uac04\uc5d0 SSM parameter store\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \uc800\uc7a5\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4. \\n\\n```bash\\nDo you want to store the config in the SSM parameter store?\\n1. yes\\n2. no\\n```\\n\\n\ucd94\uac00\uc801\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 2\ubc88\uc744 \uc120\ud0dd\ud55c\ub2e4. \\nParameter Store \uad00\ub9ac\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uc758 [\ubb38\uc11c](https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/)\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac70 \uac19\ub2e4. \\n\uc124\uc815\uc774 \uc644\ub8cc\ub418\uba74 `/opt/aws/amazon-cloudwatch-agent/bin/config.json` \uc5d0 \uc124\uc815\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc774 \uc800\uc7a5\ub41c\ub2e4. \\n\\n### \uc124\uc815 \ud30c\uc77c \uc801\uc6a9\\n\\n\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uc815\ud30c\uc77c\uc744 \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4. \\nfile \ub4a4\uc5d0\ub294 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub300\ud55c \uc808\ub300\uacbd\ub85c(\uc544\ub798 \uba85\ub839\uc5b4 \uae30\uc900 \uae30\ubcf8 \uc0dd\uc131 \uc704\uce58)\ub97c \uc785\ub825\ud558\uba74 \ub41c\ub2e4. \\n\\n```bash\\nsudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json\\n```\\n\\n### types.db: no such file or directory \uc5d0\ub7ec\\n\\n\ub2e4\uc74c\uacfc \uac19\uc740 \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 types.db \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4.\\n\\n```bash\\nError running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory\\n```\\n\\ntypes.db \ud30c\uc77c \uc0dd\uc131\\n\\n```bash\\nsudo mkdir /usr/share/collectd\\nsudo touch /usr/share/collectd/types.db\\n```\\n\\n### \uc9c0\ud45c \ud655\uc778\\n\\nCloudWatch Metrics\uc5d0 \uac00\ubcf4\uba74 CWAgent\ub77c\ub294 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\uac00 \ucd94\uac00\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. \\n\\n![./cloudwatch6.png](./cloudwatch6.png)\\n\\n\ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ucd94\uac00\ud558\uc5ec \uc9c0\ud45c\uc5d0 \ub300\ud55c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4. \\n\\n```json\\n{\\n \\"metrics\\": {\\n \\"namespace\\": \\"2023-hello-world\\",\\n ......\\n },\\n} \\n```\\n\\n### \ub85c\uadf8\\n\\nCloudWatch \u2192 \ub85c\uadf8 \uadf8\ub8f9\uc73c\ub85c \uac00\uba74 Wizard\ub85c \ucd94\uac00\ud55c \ub85c\uadf8\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.\\n\\n![./cloudwatch7.png](./cloudwatch7.png)\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n[CloudWatch\ub780 \ubb34\uc5c7\uc785\ub2c8\uae4c?](https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html) \\n[Amazon CloudWatch \uc694\uae08](https://aws.amazon.com/ko/cloudwatch/pricing/) \\n[Linux \uc778\uc2a4\ud134\uc2a4 \uc9c0\ud45c](https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html) \\n[\uc11c\ubc84\uc5d0 CloudWatch \uc5d0\uc774\uc804\ud2b8 \uc124\uce58 \ubc0f \uc2e4\ud589](https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html) \\n[CloudWatch Agent\ub97c Parameter Store\uc5d0\uc11c \uad00\ub9ac\ud574 \ubcf4\uae30](https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/) \\n[CloudWatch\uc5d0\uc774\uc804\ud2b8 \uad6c\uc131 \ud30c\uc77c](https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html)"},{"id":"route-image-async-with-event","metadata":{"permalink":"/route-image-async-with-event","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx","source":"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx","title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac","description":"\uc774\uc804 \uae00","date":"2023-08-13T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 13\uc77c","tags":[{"label":"async","permalink":"/tags/async"},{"label":"event","permalink":"/tags/event"}],"readingTime":11.2,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac","slug":"route-image-async-with-event","tags":["async","event"]},"prevItem":{"title":"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","permalink":"/cloudwatch"},"nextItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604","permalink":"/route-image-implementation"}},"content":"## \uc774\uc804 \uae00\\n\\n[\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd](./route-image-intro) \\n[\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604](./route-image-implementation)\\n\\n## \uac1c\uc694\\n\\n\ud604\uc7ac \uc5ec\ud589\uc744 \ub9c8\uce58\ub294 \uacbd\uc6b0, \uac10\uc0c1\uc744 \uc0dd\uc131\ud558\ub294 \uacbd\uc6b0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. \\n\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \uc704\uce58 \uc815\ubcf4\uc758 \uac1c\uc218\uc5d0 \uc815\ube44\ub840\ud558\uc5ec \uc0dd\uc131 \uc2dc\uac04\uc774 \uc99d\uac00\ud55c\ub2e4. \\n\ub530\ub77c\uc11c \ube44\ub3d9\uae30\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\uc5ec \uc0ac\uc6a9\uc790\uc758 \uacbd\ud5d8\uc744 \uac1c\uc120\uc2dc\ud0ac \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n### \uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120\\n\\n\uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc774 \uc8fc\uae30\ub2a5\uc774\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ubd80\uae30\ub2a5\uc774\ub2e4. \\n\ud558\uc9c0\ub9cc \ud604\uc7ac \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc758 \uc751\ub2f5 \uc18d\ub3c4\uac00 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uace0 \uc788\ub2e4. \\n\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uc5ec\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4. \\n\uc18c\uc694 \uc2dc\uac04\uc774 1\ucd08 \uc774\uc0c1 \uac78\ub9ac\ub294 \uacbd\uc6b0\uac00 \uc874\uc7ac\ud558\uae30\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uace0 \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131 \uae30\ub2a5\uc758 \uc751\ub2f5 \uc2dc\uac04\uc744 \uac1c\uc120\ud558\ub294 \uac83\uc774 \ub354 \uc911\uc694\ud558\ub2e4. \\n\\n### \ud655\uc7a5\uc131 \ub300\ube44\\n\\n\ud604\uc7ac 10\ubd84 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc11c\ubc84\uc5d0 \uc800\uc7a5\ud558\uace0 \uc788\ub2e4. \\n\uc870\uae08 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uadf8\ub9ac\ub294 \uacbd\uc6b0 \ud558\ub098\uc758 \uc5ec\ud589\uc5d0 \ub9ce\uc740 \uc704\uce58 \uc815\ubcf4\uac00 \uc800\uc7a5\ub420 \uc218\ubc16\uc5d0 \uc5c6\uace0 \ub530\ub77c\uc11c \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uac78\ub9ac\ub294 \uc2dc\uac04\uc774 \ub354 \uae38\uc5b4\uc9c8 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c \ucd94\ud6c4\uc5d0 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \uacbd\uc6b0\ub97c \ub300\ube44\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\ub294 \uac83\uc774 \ud569\ub2f9\ud558\ub2e4. \\n\\n## \ube44\ub3d9\uae30 \ucc98\ub9ac\\n\\n@Async\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uba54\uc11c\ub4dc\ub97c \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ub9cc\ub4e4 \uc218 \uc788\ub2e4. \\n\\n### \ube44\ub3d9\uae30 \uc124\uc815\\n\\n\uc0ac\uc6a9\ud558\uae30 \uc804\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c EnableAsync \uc124\uc815\uc744 \ud574\uc57c\ud55c\ub2e4. \\n\ud574\ub2f9 \uc124\uc815\uc744 \uc801\uc6a9\ud558\uba74 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc\uc5d0 @Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec\uc8fc\uae30\ub9cc \ud558\uba74 \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud55c\ub2e4. \\n\\n```java title=\\"AsyncConfig\\"\\n@EnableAsync\\n@Configuration\\npublic class AsyncConfig {\\n}\\n```\\n\\n\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \ud560 \ub54c \ub9e4\ubc88 \uc0c8\ub85c\uc6b4 \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ub808\ub4dc \ud480 \uc124\uc815\uc744 \ub530\ub85c \ud574\uc918\uc57c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ThreadPoolTaskExecutor\ub97c \ub530\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc544\ub3c4 \uae30\ubcf8\uc801\uc73c\ub85c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uac00 \uc0dd\uc131\uc744 \ub3c4\uc640\uc900\ub2e4. \\n\\n> In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing.\\n> 7.7. Task Execution and Scheduling, Spring Boot Docs\\n\\n### @Async \uc801\uc6a9\\n\\n\uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\uc5d0 Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ud55c\ub2e4. \\n\\n```java title=\\"RouteImageGenerator\\"\\n@Async\\npublic void generate(\\n List<Double> latitudes,\\n List<Double> longitudes,\\n List<Double> pointedLatitudes,\\n List<Double> pointedLongitudes,\\n Long tripId\\n) {\\n // \uc774\ubbf8\uc9c0 \uc0dd\uc131\\n RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);\\n Coordinates coordinates = Coordinates.of(latitudes, longitudes);\\n Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);\\n drawImage(coordinates, routeImageDrawer, pointedCoordinates);\\n\\n // \uc774\ubbf8\uc9c0 \uc800\uc7a5\\n String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());\\n\\n // \uc790\uc6d0 \ud560\ub2f9 \ud574\uc81c\\n routeImageDrawer.dispose();\\n\\n // \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac12 \ubcc0\uacbd\\n Trip trip = tripRepository.findById(tripId)\\n .orElseThrow();\\n trip.changeRouteImageUrl(imageUrl);\\n tripRepository.save(trip);\\n}\\n```\\n\\n### \ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810\\n\\n\ud604\uc7ac \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uace0 \uc800\uc7a5 \ud6c4, \uc800\uc7a5 \uacbd\ub85c\ub97c DB\uc5d0 \ubc18\uc601\ud574\uc57c \ud55c\ub2e4. \\n\ub530\ub77c\uc11c \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ud615\ud0dc\uac00 \ub418\uba70 \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \ubb38\uc81c\uac00 \uc0dd\uae34\ub2e4. \\n\\n```mermaid\\ngraph LR\\n trip[trip: \uc5ec\ud589 \uad00\ub828 \ud328\ud0a4\uc9c0] --\x3e draw[draw: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294 \ud328\ud0a4\uc9c0]\\n draw --\x3e trip\\n```\\n\\n\uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uacfc \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4. \\n\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tsubgraph draw\\n\\t\\tdirection LR\\n\\t\\tRG[RouteImageGenerator] -- DB \ubc18\uc601 \uc694\uccad --\x3e ILR[ImageLinkTripRepository]\\n\\tend\\n subgraph trip\\n\\t\\tdirection LR\\n\\t\\tTS[TripService] -- \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e RG\\n\\t\\tILRI[ImageLinkTripRepositoryImpl] -- \uad6c\ud604 --\x3e ILR\\n\\tend\\n\\n\\ttrip --\x3e draw\\n```\\n\\n\ud328\ud0a4\uc9c0 \uac04 \uc758\uc874\uc131\uc740 \ud574\uacb0\ub418\uc5c8\uc9c0\ub9cc, \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5\uc744 \uc704\ud574 tripId\ub97c \ubc1b\uc544\uc57c\ud558\ub294 \ub4f1\uc758 \ub17c\ub9ac\uc801\uc778 \uc758\uc874\uc131\uc740 \uc544\uc9c1 \ud574\uacb0\ub418\uc9c0 \uc54a\uc558\ub2e4. \\n\ub530\ub77c\uc11c \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4. \\n\\n## \uc774\ubca4\ud2b8 \uc0ac\uc6a9\\n\\n\uc2a4\ud504\ub9c1\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uba74 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc758 \ube44\uad00\uc2ec\uc0ac(ex. \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131)\uc744 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4.\\n\\n### \uc774\ubca4\ud2b8 \ubc1c\ud589\\n\\n\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \uba3c\uc800 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud574\uc57c \ud55c\ub2e4. \\n\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 ApplicationEventPublisher \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \uc218 \uc788\ub2e4. \\n\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c ApplicationContext\uac00 \uad6c\ud604\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud55c\ub2e4. \\n\\n```java title=\\"TripService & TripUpdateEvent\\"\\npublic void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {\\n ...\\n\\n // \uc774\ubca4\ud2b8 \ubc1c\ud589\\n applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));\\n}\\n\\npublic record TripUpdateEvent(Long tripId) {\\n}\\n```\\n\\n\uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \ub54c \ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc774 \uc911\uc694\ud558\ub2e4. \\n\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\ub294 \ub3c4\uba54\uc778\uc758 \ud589\uc704\ub97c \ub2f4\uace0 \uc788\ub294 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589(ex. RouteImageGenerateEvent)\ud55c\ub2e4\uba74 \ub17c\ub9ac\uc801\uc778 \uc758\uc874 \uad00\uacc4\uac00 \ub0a8\uc544\uc788\uae30\uc5d0 \uc774\ubca4\ud2b8\ub97c \uc801\uc808\ud788 \uc0ac\uc6a9\ud588\ub2e4\uace0 \ubcf4\uae30 \uc5b4\ub835\ub2e4. \\n\ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc740 \uc8fc\uae30\ub2a5\uc774 \uc5b4\ub5a4 \ud589\uc704(ex. TripUpdateEvent)\ub97c \ud588\ub294\uc9c0\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \ub2f4\uaca8\uc788\ub294 \uc774\ubca4\ud2b8\uba85\uc73c\ub85c \ubc1c\ud589\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4. \\n\\n### \uc774\ubca4\ud2b8 \uad6c\ub3c5\\n\\n\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc2e4\ud589\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\uae30 \uc704\ud558\uc5ec `@Async` \uc560\ub108\ud14c\uc774\uc158\uc744 \uc801\uc6a9\ud588\ub2e4. \\n\uc774\ubca4\ud2b8\uc758 \uad6c\ub3c5\uc740 \uc5ec\ud589\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \uc885\ub8cc\ub420 \ub54c \uc5ec\ud589\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \uac00\uc9c0\uace0 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud574 `@TransactionalEventListener`\ub97c \uc0ac\uc6a9\ud588\ub2e4. \\n\\n:::note TransactionPhase \uc124\uc815\\nTransactionPhase\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \uc774\ubca4\ud2b8\ub97c \uc5b4\ub5a4 \ub2e8\uacc4\uc5d0\uc11c \uc218\uc2e0\ud558\uace0 \ucc98\ub9ac\ud560\uc9c0\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.\\n\\nAFTER_COMMIT(\uae30\ubcf8\uac12): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ucee4\ubc0b \ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589 \\nAFTER_ROLLBACK: \ud2b8\ub79c\uc7ad\uc158\uc774 \ub864\ubc31\ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589 \\nAFTER_COMPLETION: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub610\ub294 \ub864\ubc31 \ub418\uc5c8\uc744 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589 \\nBEFORE_COMMIT: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub418\uae30 \uc804 \uc774\ubca4\ud2b8 \uc2e4\ud589 \\n:::\\n\\n\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uae30 \uc704\ud574 @Transactional \uc560\ub108\ud14c\uc774\uc158\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4. \\n\\n```java title=\\"TripUpdateEventHandler\\"\\n@Component\\npublic class TripUpdateEventHandler {\\n\\n private final RouteImageGenerator routeImageGenerator;\\n private final TripRepository tripRepository;\\n\\n public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {\\n this.routeImageGenerator = routeImageGenerator;\\n this.tripRepository = tripRepository;\\n }\\n\\n @Async\\n @TransactionalEventListener(phase = AFTER_COMMIT)\\n public void handle(TripUpdateEvent tripUpdateEvent) {\\n Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());\\n\\n String imageUrl = routeImageGenerator.generate(\\n trip.getLatitudes(),\\n trip.getLongitudes(),\\n trip.getPointedLatitudes(),\\n trip.getPointedLongitudes()\\n );\\n\\n trip.changeRouteImageUrl(imageUrl);\\n tripRepository.save(trip);\\n }\\n}\\n```\\n\\n\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c\uc368 \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ubb38\uc81c\uac00 \ub2e4\uc74c\uacfc \uac19\uc774 \ud574\uacb0\ub418\uc5c8\ub2e4. \\n\ub610\ud55c \uc8fc\uae30\ub2a5\uacfc \ubd80\uae30\ub2a5\uc744 \ubd84\ub9ac\ud568\uc73c\ub85c\uc368 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc5d0 \ub300\ud55c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uc5c8\ub2e4.\\n\\n```mermaid\\ngraph LR\\n subgraph trip\\n TripServcie -- \ubc1c\ud589 --\x3e TripUpdateEvent\\n TripRepository\\n end\\n\\n subgraph draw\\n TripUpdateEventHandler -- \uad6c\ub3c5 \ud6c4 \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e TripUpdateEvent\\n TripUpdateEventHandler -- \uc0dd\uc131\ub41c \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5 --\x3e TripRepository\\n end\\n```\\n\\n### \ud14c\uc2a4\ud2b8\\n\\n\ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud14c\uc2a4\ud2b8\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \ubc29\ubc95\uc774 \uc788\ub2e4. \\n\\nimport Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n<Tabs>\\n<TabItem value=\\"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d\\" label=\\"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d\\">\\n\\n```java\\n@SpringBootTest\\npublic class TripUpdateEventHandlerIntegrationTest {\\n\\n ...\\n\\n @Test\\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\\n // given\\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\\n .willReturn(\uc5ec\ud589());\\n\\n // when\\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\\n\\n // then\\n then(routeImageGenerator)\\n .should(Mockito.timeout(5000).times(1))\\n .generate(any(), any(), any(), any());\\n }\\n}\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d\\" label=\\"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d\\" default>\\n\\n```java\\n@ContextConfiguration(classes = TestSyncConfig.class)\\n@SpringBootTest\\npublic class TripUpdateEventHandlerIntegrationTest {\\n\\n ...\\n\\n @Test\\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\\n // given\\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\\n .willReturn(\uc5ec\ud589());\\n\\n // when\\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\\n\\n // then\\n then(routeImageGenerator)\\n .should(times(1))\\n .generate(any(), any(), any(), any());\\n }\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n\ucc98\uc74c\uc5d0\ub294 \ud14c\uc2a4\ud2b8\uc5d0\uc11c\ub9cc \ub3d9\uae30\ub85c \uc124\uc815 \ud6c4 \uac80\uc99d\ud558\ub824\uace0 \ud588\ub2e4. \\n\ud1b5\ud569 \ud14c\uc2a4\ud2b8\uc5d0\uc120 `\ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1 \uc885\ub8cc\ub418\uc5c8\uc744 \ub54c \ube44\ub3d9\uae30\ub85c \uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0` \uac80\uc99d\uc774 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 \ucd5c\uc885\uc801\uc73c\ub85c `Mockito.timeout` \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \ud1b5\uacfc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4. \\n\\n## \uacb0\uacfc\\n\\n![./time.png](./time.png)\\n\\n\uc704 \uc751\ub2f5 \uc2dc\uac04\uc740 \uc704\uce58 \uc815\ubcf4 1000\uac1c\ub97c \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ud55c \uac12\uc774\ub2e4. \\n\uc751\ub2f5 \uc2dc\uac04\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ud3ec\ud568\ub418\uc9c0 \uc54a\uc544\uc11c \uc131\ub2a5\uc774 \uac1c\uc120\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. \\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n[7.7. Task Execution and Scheduling, Spring Boot Docs](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.task-execution-and-scheduling) \\n[Spring Events, Baeldung](https://www.baeldung.com/spring-events) \\n[\ud68c\uc6d0\uc2dc\uc2a4\ud15c \uc774\ubca4\ud2b8\uae30\ubc18 \uc544\ud0a4\ud14d\ucc98 \uad6c\ucd95\ud558\uae30](https://techblog.woowahan.com/7835/)"},{"id":"route-image-implementation","metadata":{"permalink":"/route-image-implementation","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx","source":"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx","title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604","description":"\uac1c\uc694","date":"2023-08-02T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 2\uc77c","tags":[{"label":"image","permalink":"/tags/image"},{"label":"awt","permalink":"/tags/awt"}],"readingTime":11.665,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604","slug":"route-image-implementation","tags":["image","awt"]},"prevItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac","permalink":"/route-image-async-with-event"},"nextItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c","permalink":"/route-image-python"}},"content":"## \uac1c\uc694\\n\\n\uc5ec\ud589\uc5d0 \ub300\ud55c \uacbd\ub85c\ub97c \ubcf4\uc5ec\uc8fc\uae30 \uc704\ud574 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4. \\n\uacbd\ub85c \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d \ubc0f \uae30\uc220 \uc120\ud0dd\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 [\ub9c1\ud06c](./route-image-intro)\uc5d0 \uc788\ub2e4.\\n\\n### \uad6c\ud604 \uacb0\uacfc\\n\\n![./result.png](./result.png)\\n\\n\uc608\uc2dc \ub370\uc774\ud130\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n**\uc11c\uc6b8\uc5ed(\uc810)** \u2192 \uc2e0\uc0ac\uc5ed \u2192 \ub178\ub7c9\uc9c4\uc5ed \u2192 \ud64d\ub300\uc785\uad6c\uc5ed \u2192 \uc885\ub85c3\uac00\uc5ed \u2192 \uc625\uc218\uc5ed \u2192 **\uad6c\ub85c\uc5ed(\uc810)** \u2192 \uc2e0\ub9bc\uc5ed \u2192 \ubc1c\uc0b0\uc5ed\\n\\n```java title=\\"\uc608\uc2dc \ub370\uc774\ud130\\"\\nList<Double> x = List.of(\\n 126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,\\n 126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639\\n);\\nList<Double> y = List.of(\\n 37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,\\n 37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184\\n);\\nList<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);\\nList<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);\\n```\\n\\n### IMAGE_SIZE & ROUTE_SIZE\\n\\n```java title=\\"RouteImageGenerator.java\\"\\nprivate static final int IMAGE_SIZE = 800;\\nprivate static final int ROUTE_SIZE = 600;\\n```\\n\\n\ucf54\ub4dc\ub97c \ubcf4\uba74 IMAGE_SIZE\uc640 ROUTE_SIZE\uac00 \uc788\ub2e4. \\nIMAGE_SIZE\ub294 \ub9d0 \uadf8\ub300\ub85c \uc774\ubbf8\uc9c0\uc758 width\uc640 height\ub97c \uc758\ubbf8\ud55c\ub2e4. \\nROUTE_SIZE\uc758 \uacbd\uc6b0 \uc0c1\ud558\uc88c\uc6b0 100px \ub9cc\ud07c\uc758 \uac04\uaca9\uc744 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4. \\n\ub530\ub77c\uc11c \uc2e4\uc81c \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub294 600 * 600 \uc0ac\uc774\uc988\ub85c \uc0dd\uc131\ub41c\ub2e4. \\n\\n![./600.png](./600.png)\\n\\n**\uc0ac\uc774\uc988 \ubcc0\uacbd\uc758 \uc774\uc720**\\n\\n255 * 255 \uc815\ub3c4\uc758 \uc791\uc740 \uc0ac\uc774\uc988\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud574\ubcf4\ub824\uace0 \ud588\ub294\ub370, \uc774\ubbf8\uc9c0\uc758 \uc120\uba85\ub3c4\uac00 \uc88b\uc9c0 \uc54a\uc544 800 * 800 \uc0ac\uc774\uc988\ub85c \ubcc0\uacbd\ud588\ub2e4.\\n\\n## \uc8fc\uc694 \ud074\ub798\uc2a4\\n\\n### \uc694\uc57d\\n\\n| \ud074\ub798\uc2a4\uba85 | \uc124\uba85 | \ud2b9\uc774\uc0ac\ud56d |\\n| --- | --- | --- |\\n| Coordinate | \uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \uc704\uce58 \uac12 | \uc88c\ud45c\ub97c \ub73b\ud558\uc9c0\ub9cc \uc5ec\ud589 \ub3c4\uba54\uc778\uc5d0 \ud3ec\ud568\ub41c Point \ud074\ub798\uc2a4\uc640 \uad6c\ubd84\ud558\uae30 \uc704\ud574 longitude, latitude\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 x, y \uc0ac\uc6a9 |\\n| Coordinates | Coordinate\uc758 \uc77c\uae09 \uceec\ub809\uc158 | - |\\n| Position | \uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58 \uac12 | Integer \ud0c0\uc785\uc758 x, y \uc0ac\uc6a9 |\\n| Positions | Positions\uc758 \uc77c\uae09 \uceec\ub809\uc158 | - |\\n| RouteImageDrawer | \uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4 BufferedImage, Graphics2D\ub97c \uac00\uc9c0\uace0 \uc788\uc74c | \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc0c1\uc218\uac00 \uc815\uc758\ub418\uc5b4 \uc788\uc74c |\\n| RouteImageUploader | BufferedImage\ub97c \ubc1b\uc544 \uc11c\ubc84\uc5d0 \uc5c5\ub85c\ub4dc \ud558\ub294 \ud074\ub798\uc2a4 | \ud604\uc7ac \uc5c5\ub85c\ub4dc \uc704\uce58\uac00 \uc815\ud574\uc9c0\uc9c0 \uc54a\uc544 \uc77c\ub2e8 \uae30\ubcf8(\ud504\ub85c\uc81d\ud2b8 \ub8e8\ud2b8) \uc704\uce58\uc5d0 \uc0dd\uc131 |\\n| RouteImageGenerator | \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uace0 \uc5c5\ub85c\ub4dc\ud558\ub294 \uc11c\ube44\uc2a4 | \uc5ec\ud589 \uc885\ub8cc, \uac10\uc0c1 \uc800\uc7a5\uc2dc \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \ud1b5\ud574 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad |\\n| BufferedImage(AWT) | \uc774\ubbf8\uc9c0 \ub370\uc774\ud130\ub97c \ucc98\ub9ac\ud558\uace0 \uc870\uc791\ud558\ub294 \ub370 \uc0ac\uc6a9 | \uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c\uac00 (0, 0) |\\n| Graphics2D(AWT) | \uc120 \uadf8\ub9ac\uae30, \uc0c9\uc0c1 \uad00\ub9ac \ub4f1\uc744 \uc9c0\uc6d0\ud558\ub294 \ud074\ub798\uc2a4 \uc2e4\uc81c \ud574\ub2f9 \ud074\ub798\uc2a4\uc758 draw \uba54\uc11c\ub4dc\ub97c \uacbd\ub85c\ub97c \uadf8\ub9bc | JDK 1.2 \uc774\ud6c4\uc5d0 \ucd94\uac00\ub428, 2D(\ud3c9\uba74) \uadf8\ub798\ud53d \ud658\uacbd\uc744 \uc9c0\uc6d0, bufferedImage.createGraphics \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \uc0dd\uc131 |\\n\\n### \uc758\uc874\uad00\uacc4\\n\\n```mermaid\\ngraph TD\\n C1[Coordinates] --\x3e C[Coordinate]\\n P1[Positions] --\x3e P[Position]\\n\\n\\tRID[RouteImageDrawer] -- \\"\uc911\uc559 \uc815\ub82c\ub41c Positions\ub97c \ubc1b\uc544 \uc774\ubbf8\uc9c0 \uc0dd\uc131\\" --\x3e P1\\n\\tRID --\x3e B[BufferedImage]\\n\\tRID --\x3e G[Graphics2D]\\n\\n\\tC1 -- \\"calculatePositions \uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc704\uce58 \uacc4\uc0b0\\" --\x3e P1\\n\\n\\tRIU[RouteImageUploader] --\x3e B\\n\\tRIG[RouteImageGenerator] --\x3e RID\\n\\tRIG --\x3e RIU\\n\\tRIG --\x3e C1\\n\\tRIG --\x3e P1\\n```\\n\\n### Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)\\n\\n`List<Double>` 2\uac1c(\uc704\ub3c4, \uacbd\ub3c4)\uc778 \ud615\ud0dc\ub85c \uad00\ub9ac\ud558\ub294 \ubc29\ubc95\uc774 \uc788\uc5c8\uc9c0\ub9cc, \uc704\uce58 \uc810\uc744 \uc5ec\ub7ec\uac1c \ucc0d\ub294 \ubd80\ubd84\uc5d0\uc11c \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud574 \uc9c8 \uac83 \uac19\uc544\uc11c Coordinate(x, y)\uc640 \uc77c\uae09 \uceec\ub809\uc158\uc778 Coordinates\ub85c \uad00\ub9ac\ud558\uae30\ub85c \ud588\ub2e4. \\nCoordinates \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub450 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4.\\n\\n- calculatePositions: \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub97c \ubc1b\uc544 \uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \uc0ac\uc6a9\ub420 Positions\ub97c \ubc18\ud658\\n- indexOf: \ub2e4\ub978 Coordinates\ub97c \ubc1b\uc544 \ub3d9\uc77c\ud55c \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4\ub97c \ubc18\ud658\ud558\ub294 \\n\\nPositions \uacc4\uc0b0 \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\uc704\ub3c4, \uacbd\ub3c4 \uac01\uac01\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \ud544\uc694\ud55c \uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4.\\n\\n```java title=\\"Coordinates.java\\"\\n// \ud638\ucd9c\\n// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);\\n// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);\\n\\nprivate List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {\\n Double minValue = Collections.min(values);\\n return values.stream()\\n .map(value -> normalizeCoordinate(value, maxDifference, minValue))\\n .map(value -> mapToPosition(value, routeImageSize))\\n .toList();\\n}\\n\\nprivate double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {\\n return (coordinate - minValue) / maxDifference;\\n}\\n\\nprivate int mapToPosition(Double coordinate, Integer routeImageSize) {\\n return (int) (coordinate * routeImageSize);\\n}\\n```\\n\\n\uc704\ub3c4\ub85c \uc608\uc2dc\ub4e0 \ub0b4\uc6a9\uc774\ub2e4.\\n\\n1. Collections.min(values) \u2192 \uc704\ub3c4 \ub9ac\uc2a4\ud2b8\uc758 \ucd5c\uc18c\uac12\uc744 \uad6c\ud55c\ub2e4.\\n2. normalizeCoordinate \u2192 \uac01\uac01\uc758 \uc704\ub3c4 \uac12\uc5d0\uc11c \ucd5c\uc18c\uac12\uc744 \ube7c\uace0 0 ~ 1 \uc0ac\uc774 \uac12\uc73c\ub85c \ubcc0\ud658 \ud6c4 **\uc704\uacbd\ub3c4\uc758 \ucd5c\ub300 \ucc28\uc774**\ub85c \ub098\ub208\ub2e4.\\n3. mapToPosition \u2192 \uadf8\ub798\ud504 \ud06c\uae30\ub97c \ubc1b\uc544 0 ~ 1 \uc0ac\uc774 \uac12\uc744 \uc2e4\uc81c \uc774\ubbf8\uc9c0\ub97c \uc704\ud55c \uc704\uce58\uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4.\\n\\n### Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)\\n\\nPositions \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub2e4\uc12f \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4.\\n\\n- align: \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\uc640 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\ub97c \ubc1b\uc544 Position \uac12\ub4e4\uc744 \uc911\uc559 \uc815\ub82c\ud55c\ub2e4.\\n- getPositionsByIndexes: \uc778\ub371\uc2a4 \ub9ac\uc2a4\ud2b8\ub97c \ubc1b\uc544 \uc785\ub825\ubc1b\uc740 \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4.\\n- size: \ud06c\uae30\ub97c \ubc18\ud658\ud55c\ub2e4.\\n- xPositions: x \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4.\\n- yPositions: y \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4.\\n\\n\uc911\uc559 \uc815\ub82c \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n```java title=\\"Positions.java\\"\\npublic Positions align(int imageSize, int routeSize) {\\n int xOffset = calculateOffset(Position::x, imageSize);\\n int yOffset = calculateOffset(Position::y, imageSize);\\n\\n return items.stream()\\n .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))\\n .collect(collectingAndThen(toList(), Positions::new));\\n}\\n\\nprivate int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {\\n List<Integer> positions = items.stream()\\n .mapToInt(positionToInteger)\\n .boxed()\\n .toList();\\n\\n int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;\\n return imageSize / 2 - midValue;\\n}\\n```\\n\\n\uc0c1\ud558\uc88c\uc6b0 \uc5ec\ubc31\uc744 \ub3d9\uc77c\ud558\uac8c \uc8fc\uae30 \uc704\ud574\uc11c offset \uac12\uc744 \uad6c\ud574\uc11c x, y \uac12\uc5d0 \uac01\uac01 \ub354\ud558\ub294 \ud615\ud0dc\ub85c \uc911\uc559 \uc815\ub82c\uc744 \uc218\ud589\ud588\ub2e4. \\nBufferedImage\ub97c \uc0ac\uc6a9\ud560 \ub54c \uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c (0, 0) \uae30\uc900\uc73c\ub85c \uc544\ub798\ub85c \ub0b4\ub824\uac08\uc218\ub85d y \uac12\uc774 \ucee4\uc9c0\uace0, \uc624\ub978\ucabd\uc73c\ub85c \uac08 \uc218\ub85d x \uac12\uc774 \ucee4\uc9c4\ub2e4. \\n\\n![./800.png](./800.png)\\n\\n\ub530\ub77c\uc11c \ucd5c\uc885\uc801\uc73c\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud55c \uac12\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uad6c\ud588\ub2e4.\\n\\nx \uac12 \u2192 \uacc4\uc0b0\ud55c offset \uadf8\ub300\ub85c \ub354\ud55c\ub2e4. \\ny \uac12 \u2192 imageSize(800)\uc5d0\uc11c y + offset \uac12\uc744 \ube80\ub2e4. \\n\\n### RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)\\n\\nBufferedImage, Graphics2D\ub97c \ud544\ub4dc\ub85c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub2e4. \\n\uadf8\ub9bc\uc744 \uadf8\ub9ac\uae30 \uc704\ud574 \uc124\uc815\ud55c \uc0c1\uc218\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4.\\n\\n```java title=\\"RouteImageDrawer.java\\"\\n// RGB\uc5d0 \uac01\uac01 8\ube44\ud2b8\uc529 \ud560\ub2f9\ud55c \uac12\uc744 24\ube44\ud2b8 \ud2b8\ub8e8\uceec\ub7ec\ub77c \ubd80\ub978\ub2e4.\\n// \ud574\ub2f9 \uc124\uc815\uc740 24\ube44\ud2b8 + 8\ube44\ud2b8(alpha, \ud22c\uba85\ub3c4)\ub97c \ucd94\uac00\ud55c 32\ube44\ud2b8 \uc774\ubbf8\uc9c0 \ud0c0\uc785\uc774\ub2e4.\\n// \uc774\ub97c RGBA\ub77c\uace0 \ubd80\ub978\ub2e4.\\nprivate static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;\\n// \ubc30\uacbd \ud22c\uba85\uc0c9\\nprivate static final Color TRANSPARENT = new Color(0, 0, 0, 0);\\n// \uacbd\ub85c\ub97c \uc704\ud55c STROKE\\nprivate static final int LINE_STROKE_WIDTH = 7;\\nprivate static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\\n// \uc704\uce58 \uc810\uc744 \uc704\ud55c STROKE\\nprivate static final int POINT_STROKE_WIDTH = 20;\\nprivate static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\\n// \uc548\ud2f0\uc568\ub9ac\uc5b4\uc2f1 \ub4f1 \ud654\uc9c8 \uac1c\uc120\uc744 \uc704\ud55c \uc124\uc815\\nprivate static final Map<Object, Object> renderingHints = Map.of(\\n RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,\\n RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,\\n RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC\\n);\\n```\\n\\nRouteImageDrawer \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \uc138 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4.\\n\\n- drawLine: \uc120\uc744 \uadf8\ub9b0\ub2e4.\\n- drawPoint: \uc810\uc744 \ucc0d\ub294\ub2e4.\\n- dispose: \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud55c\ub2e4. \\n\\ndispose\uc758 \uacbd\uc6b0 \ub0b4\ubd80\uc5d0\uc11c \uc0dd\uc131\ub41c graphics2D\uc5d0 \ub300\ud55c \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud558\ub294 \uba54\uc11c\ub4dc\uc778 graphics2D.dispose\ub97c \ud638\ucd9c\ud55c\ub2e4.\\n\\n## \uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow\\n\\n### 1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44\\n\\n```mermaid\\nsequenceDiagram\\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\\n\\n```\\n\\n### 2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad\\n\\n```mermaid\\nsequenceDiagram\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad\\n```\\n\\n### 3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\\n\\n```mermaid\\nsequenceDiagram\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\\n\\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\\n```\\n\\n### 4. \uc5c5\ub85c\ub4dc \uc694\uccad\\n\\n```mermaid\\nsequenceDiagram\\n \\tRouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\\n \\tRouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\\n \\tRouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\\n```\\n\\n### \uc804\uccb4 Flow\\n\\n```mermaid\\nsequenceDiagram\\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\\n\\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\\n RouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\\n RouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\\n RouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\\n\\t\\n```"},{"id":"route-image-python","metadata":{"permalink":"/route-image-python","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx","source":"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx","title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c","description":"\uac1c\uc694","date":"2023-07-31T00:00:00.000Z","formattedDate":"2023\ub144 7\uc6d4 31\uc77c","tags":[{"label":"Image","permalink":"/tags/image"},{"label":"Python","permalink":"/tags/python"}],"readingTime":6.185,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c","slug":"route-image-python","tags":["Image","Python"]},"prevItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604","permalink":"/route-image-implementation"},"nextItem":{"title":"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30","permalink":"/mock-static-method"}},"content":"### \uac1c\uc694\\n\\n\uc774\uc804\uc5d0 \uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uc870\uc0ac\ud558\uba74\uc11c \ud30c\uc774\uc36c\uc744 \uc0ac\uc6a9\ud55c \ub0b4\uc6a9\uc744 \uc815\ub9ac\ud55c \ub0b4\uc6a9\uc774\ub2e4. \\n\\n### \uc0ac\uc6a9 \uae30\uc220\\n\\n\uc5b8\uc5b4: Python 3.10 \\n\uc774\ubbf8\uc9c0 \uc0dd\uc131: matplotlib \\n\uc11c\ube44\uc2a4: AWS Lambda, AWS API Gateway \\n\uc774\ubbf8\uc9c0 \uc800\uc7a5 \ubc0f URL: AWS S3, AWS CloudFront \\n\\n\ud50c\ub85c\uc6b0\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n```mermaid\\ngraph LR\\n Server -- \uc0dd\uc131 \uc694\uccad --\x3e AG[API Gateway] --\x3e Lambda --\x3e S3\\n Client --\x3e CloudFront --\x3e S3\\n```\\n\\n### \uc694\uad6c\uc0ac\ud56d\\n\\n![./route.png](./route.png)\\n\\n\uc6b0\uce21 \uc0c1\ub2e8\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub824\uace0 \ud55c\ub2e4. \\n\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.\\n\\n- \uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \ubc30\uc5f4\uc744 \uc785\ub825\ubc1b\ub294\ub2e4. \\n- \uc774\ubbf8\uc9c0 \uc0dd\uc131\\n- \uc120\uacfc \uc810 \ud45c\ud604\\n- \ud22c\uba85\ud55c \ubc30\uacbd\uc0c9\\n- \uc704\uacbd\ub3c4 \ucc28\uc774\uac00 \ud06c\ub4e0 \uc791\ub4e0 \uc81c\uacf5\ud558\ub294 \uc774\ubbf8\uc9c0 \ub0b4\uc5d0 \uacbd\ub85c\uac00 \ub2e4 \ud3ec\ud568\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4. \\n\\n### \uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd\\n\\n1. \uc704\uacbd\ub3c4\ub97c \ucc98\ub9ac\ud55c \uac12\uc73c\ub85c \uc9c1\uc811 \uacbd\ub85c\ub97c \uadf8\ub9b0 \ub2e4\uc74c \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5\\n2. \ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac \uc0ac\uc6a9\ud558\uc5ec \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5\\n\\n\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd\uc758 \uacbd\uc6b0 1\ubc88\uacfc 2\ubc88\uc744 \uace0\ubbfc\ud588\uc5c8\ub2e4. \\n\ud30c\uc774\uc36c\uc73c\ub85c\ub294 \ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc778 matplotlib\uc744 \uc0ac\uc6a9\ud588\ub2e4. \\n\\n### \ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604\\n\\n```python\\nimport time\\n\\nimport matplotlib.pyplot as plt\\n\\n\\ndef draw(point):\\n start = time.time()\\n x, y = zip(*point)\\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\\n draw_lines(pixel_x, pixel_y)\\n end = time.time()\\n print(end - start)\\n \\ndef convert_to_pixel_values(x, y):\\n max_diff = max(max(x) - min(x), max(y) - min(y))\\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\\n\\n\\ndef scale_to_pixel_values(points, max_diff):\\n min_value = min(points)\\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\\n return scaled_coordinates\\n\\n\\ndef draw_lines(x, y):\\n figure = plt.gcf()\\n figure.set_size_inches(5, 5)\\n plt.plot(x, y, c = \'w\',linewidth=5)\\n plt.scatter(x[3],y[3], c = \'w\', s = 125)\\n plt.axis(\'off\')\\n plt.savefig(\'name.png\', transparent=True, format=\'png\')\\n\\npoint = [\\n [126.96352960597338, 37.590841000217125],\\n [126.96987292787792, 37.58435564234159],\\n [126.98128481452298, 37.58594375113966],\\n [126.99360339342958, 37.58248524741927],\\n [126.99867565340067, 37.56778118088622],\\n [127.001935378366117, 37.55985240444085],\\n [126.9831048919687, 37.548030119488665],\\n [126.97189273528845, 37.5119879225856],\\n [127.02689859997221, 37.48488593333883]\\n]\\n\\ndraw(point)\\n```\\n\\n\uc0dd\uc131 \uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4. (\uc608\uc2dc\ub97c \uc704\ud574 \uac80\uc740\uc0c9\uc73c\ub85c \ucd9c\ub825)\\n\\n![./routeImage.png](./routeImage.png)\\n\\n### AWS Lambda\\n\\n\uc378\ub124\uc77c \uc0dd\uc131 \uc11c\ubc84\ub97c \ub530\ub85c \ub450\uae30\ub294 \uae30\ub2a5 \ub300\ube44 \ube44\uc6a9\uc774 \ub108\ubb34 \ud074 \uac83\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ub530\ub77c\uc11c \uc11c\ubc84\ub9ac\uc2a4\ub85c \ud30c\uc77c\uc744 \ucc98\ub9ac\ud588\ub2e4. \\n\ucd94\uac00\ub85c s3 \uc811\uadfc\uc740 boto3\ub97c \uc0ac\uc6a9\ud588\ub2e4. \\n\\n### \ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131\\n\\nAmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy \ub450\uac00\uc9c0\ub97c \ucd94\uac00\ud574\uc11c Lambda \uc804\uc6a9 \uc5ed\ud560\uc744 \ub9cc\ub4e4\uc5b4 \uc0ac\uc6a9\ud588\ub2e4. \\n\\n### \ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc\\n\\n\uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \ud655\uc778\ud560 \ub550 \uc704\uce58 \uc810\uc744 \ucc0d\ub294 \uae30\ub2a5\uc744 \ub78c\ub2e4\uc5d0 \ubc30\ud3ec\ud558\uc9c0 \uc54a\uc558\ub2e4. \\n\\n```python\\n\\nimport io\\nimport uuid\\n\\nimport boto3\\nimport matplotlib.pyplot as plt\\n\\nPIXEL = 255\\nBUCKET_NAME = \'image-plot\'\\nS3 = \'s3\'\\n\\ndef lambda_handler(event, context):\\n x = event[\'x\']\\n y = event[\'y\']\\n image_name = str(uuid.uuid4())\\n\\n img_data = draw(x, y)\\n s3 = boto3.client(S3)\\n s3.put_object(Body=img_data.getvalue(), ContentType=\'image/png\', Bucket=BUCKET_NAME, Key=image_name)\\n url = f\'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}\'\\n\\n return {\\n \'statusCode\': 200,\\n \'body\': url\\n }\\n\\ndef draw(x, y):\\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\\n img_data = draw_lines(pixel_x, pixel_y)\\n plt.close()\\n return img_data\\n\\ndef convert_to_pixel_values(x, y):\\n max_diff = max(max(x) - min(x), max(y) - min(y))\\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\\n\\ndef scale_to_pixel_values(points, max_diff):\\n min_value = min(points)\\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\\n pixel_values = [int(p * PIXEL) for p in scaled_coordinates]\\n return pixel_values\\n\\ndef draw_lines(x, y):\\n plt.plot(x, y, \'k-\', linewidth=10)\\n plt.axis(\'off\')\\n img_data = io.BytesIO()\\n plt.savefig(img_data, transparent=True, format=\'png\')\\n img_data.seek(0)\\n return img_data\\n\\n```\\n\\n### Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131\\n\\nmatplotlib\uc758 \uacbd\uc6b0 \uc678\ubd80 \ub77c\uc774\ube0c\ub7ec\ub9ac\uae30 \ub54c\ubb38\uc5d0 \ub530\ub85c Layer\ub97c \ucd94\uac00\ud574\uc57c \ud55c\ub2e4. \\nzip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc5b4\uc11c \uc5c5\ub85c\ub4dc\ud574\uc57c\ud55c\ub2e4. \\n\uc774\ub54c python\uc758 Lambda \ub7f0\ud0c0\uc784\uc5d0 \ub300\ud55c \uacc4\uce35 \uacbd\ub85c\ub294 python\uc774\ub2e4. \\n\ub530\ub77c\uc11c \uc555\ucd95\ud55c zip \ud30c\uc77c\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\ub97c \ub744\uc5b4\uc57c \ud55c\ub2e4. \\n\\n```\\npillow.zip\\n\u2502 python/PIL\\n\u2514 python/Pillow-5.3.0.dist-info\\n```\\n\\nUbuntu \uae30\uc900 \ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc0dd\uc131\uc744 \uc9c4\ud589\ud588\ub2e4. \\n\\n```\\nsudo apt update\\nsudo apt install zip\\nsudo apt install python3-pip\\n\\nmkdir python\\npip3 install matplotlib -t python # pip3 install \uc124\uce58\ud560_\ud328\ud0a4\uc9c0 -t \uc124\uce58_\uacbd\ub85c\\nzip -r my_layer.zip python # zip -r \uc555\ucd95_\ud30c\uc77c\uba85 \uc555\ucd95_\ud30c\uc77c\uc774_\uc874\uc7ac\ud558\ub294_\uacbd\ub85c\\n```\\n\\n### `No module named \'numpy.core._multiarray_umath\'` \uc5d0\ub7ec\\n\\nLayer \ucd94\uac00 \ud6c4 \ub78c\ub2e4 \uc2e4\ud589 \uc2dc \ubc1c\uc0dd\ud55c \uc5d0\ub7ec\uc600\ub2e4. \\n\ucc98\uc74c\uc5d0 mac\uc5d0\uc11c zip \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \uc5c5\ub85c\ub4dc\ud588\ub294\ub370 \ud574\ub2f9 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4. \\n\uc774\ub294 lambda\uac00 \ub3cc\uc544\uac00\ub294 \ub3d9\uc77c\ud55c \ud658\uacbd\uc5d0\uc11c layer\ub97c \uc704\ud55c zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc9c0 \uc54a\uc544\uc11c \ubc1c\uc0dd\ud558\ub294 \ubb38\uc81c\ub2e4. \\n\uac04\ub2e8\ud558\uac8c ec2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c \ub530\ub85c Layer\ub97c \uc0dd\uc131\ud558\uba74 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4. \\n\\n### \uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01\\n\\n\ud504\ub85c\uc81d\ud2b8\uc5d0 Lambda\uc640 Python\uc744 \uc0ac\uc6a9\ud558\ub824\uace0 \ud588\uc9c0\ub9cc \uc544\uc27d\uac8c\ub3c4 \ubc18\ub824\ub2f9\ud588\ub2e4. \\nAWS Lambda\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc778\uc2a4\ud134\uc2a4\uc5d0 \ud574\ub2f9 \ucf54\ub4dc\ub97c \ubc30\ud3ec\ud558\ub294 \uac83\ubcf4\ub2e4 \ub354 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc77c \uc218 \uc788\ub2e4. \\n\ud558\uc9c0\ub9cc \ud604\uc7ac \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uac00\uc6a9 \uac00\ub2a5\ud55c \uc790\uc6d0, \uae30\uc220\uc758 \ub09c\uc774\ub3c4, \uc0ac\uc6a9\ud558\ub294 \ud300\uc6d0\uc744 \uace0\ub824\ud55c\ub2e4\uba74 Lambda\ub294 \uc801\uc815\uae30\uc220\uc774 \uc544\ub2d0 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c \ud574\ub2f9 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\ub97c \uc5b4\ub5bb\uac8c \uc801\uc6a9\ud560\uc9c0 \uc870\uae08 \ub354 \uace0\ub824\ub97c \ud574\uc57c \ub420 \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4. \\n\\n**\ucd5c\uc885\uc801\uc73c\ub85c Java AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.**\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n[AWS Lambda](https://aws.amazon.com/ko/lambda/) \\n[Lambda Layer](https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-layers.html) \\n[Python Lambda \ud568\uc218\uc5d0 \ub300\ud55c .zip \ud30c\uc77c \uc544\uce74\uc774\ube0c \uc791\uc5c5](https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-package.html) \\n[No module named \'numpy.core._multiarray_umath\'](https://gist.github.com/ksmin23/0f3f243408a8497f766b43cf589fea7b) \\n[\uc0ac\ub840\ubcc4\ub85c \uc54c\uc544\ubcf8 \uc548\uc804\ud55c S3 \uc0ac\uc6a9 \uac00\uc774\ub4dc](https://techblog.woowahan.com/6217/)"},{"id":"mock-static-method","metadata":{"permalink":"/mock-static-method","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx","source":"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx","title":"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30","description":"\uac1c\uc694","date":"2023-07-30T00:00:00.000Z","formattedDate":"2023\ub144 7\uc6d4 30\uc77c","tags":[{"label":"Mockito","permalink":"/tags/mockito"},{"label":"static","permalink":"/tags/static"}],"readingTime":2.635,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30","slug":"mock-static-method","tags":["Mockito","static"]},"prevItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c","permalink":"/route-image-python"},"nextItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd","permalink":"/route-image-intro"}},"content":"### \uac1c\uc694\\n\\n\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud55c\ub2e4\ub294 \uac83\uc740 \uac1d\uccb4\uc9c0\ud5a5\uc801\uc778 \uad00\uc810\uc5d0\uc11c \ubcfc \ub54c \uc548\ud2f0\ud328\ud134\uc774\ub2e4. \\n\ud558\uc9c0\ub9cc \ud2b9\uc218\ud55c \uacbd\uc6b0\uc5d0\ub294 \uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc774 \ud544\uc694\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\n\uc608\ub97c \ub4e4\uc5b4 \ub808\uac70\uc2dc \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud55c\ub2e4\ub358\uc9c0, IO \uad00\ub828\ud55c \ubd80\ubd84\uc744 \ud14c\uc2a4\ud2b8 \ud560 \ub54c \uc815\ub9d0 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\ub9cc \uc801\uc6a9\ud560 \uc218 \uc788\uc744 \uac83\uc774\ub2e4. \\n\\n\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba70 ImageIo.write \uba54\uc11c\ub4dc\uac00 \ud638\ucd9c\ub418\ub294 \uc9c0 \uac80\uc99d\uc774 \ud544\uc694\ud588\ub2e4. \\n\ud574\ub2f9 static \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294 \ubd80\ubd84\uc744 \ub530\ub85c RouteImageUploader \ud074\ub798\uc2a4\ub85c \ucd5c\ub300\ud55c \ubd84\ub9ac\ud588\ub2e4. \\n\uc774\ubbf8\uc9c0 \uc800\uc7a5 \uae30\ub2a5 \uc790\uccb4\uac00 \uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc774\uace0, \ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc0ac\ud558\ub294\ub370\ub294 mock\uc744 \uc0ac\uc6a9\ud558\ub294\uac8c \uc801\uc808\ud558\ub2e4\uace0 \ud310\ub2e8\ud588\ub2e4. \\n\\n```java\\npublic void upload(BufferedImage bufferedImage) {\\n File file = new File(\ud30c\uc77c\uacbd\ub85c);\\n try {\\n ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);\\n } catch (IOException e) {\\n throw new DrawException(IMAGE_SAVE_FAIL);\\n }\\n}\\n```\\n\\n### Mocking static methods\\n\\nMockito 3.4.0 \uc774\ud6c4\uc5d0\ub294 static method\ub97c \ubaa8\ud0b9\ud560 \uc218 \uc788\ub294 Mockito.mockStatic \uba54\uc11c\ub4dc\ub97c \uc9c0\uc6d0\ud55c\ub2e4. \\nmockStatic\uc744 \uc0ac\uc6a9\ud558\uba74 `MockedStatic<T>`\uc774 \ubc18\ud658\ub418\ub294\ub370 \uc0ac\uc6a9 \ud6c4 \uaf2d close\ub97c \ud574\uc918\uc57c \ud55c\ub2e4. \\n\\nJUnit\uc758 @BeforeAll\ub85c \uc124\uc815\ud558\uace0 @AfterAll \uba54\uc11c\ub4dc\ub85c \uc885\ub8cc\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\uc9c0\ub9cc `MockedStatic<T>`\uc758 \uc0c1\uc704 \uc778\ud130\ud398\uc774\uc2a4\uc778 ScopedMock\uc774 AutoCloseable\uc744 \uad6c\ud604\ud558\uace0 \uc788\uae30\uc5d0 try-with-resources\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \ub354\uc6b1 \uc88b\uc740 \uac83 \uac19\ub2e4. \\n\\n```java\\n// given\\nBufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);\\nRouteImageUploader routeImageUploader = new RouteImageUploader();\\n\\n// expect\\ntry (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {\\n routeImageUploader.upload(bufferedImage);\\n imageIO.verify(\\n () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),\\n times(1)\\n );\\n}\\n```\\n\\n### \ub9c8\uce58\uba70\\n\\n\uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc740 \uc548\ud2f0\ud328\ud134\uc774\uc73c\ub85c \uc801\uc808\ud55c \ucd94\uc0c1\ud654\ub97c \uc774\uc6a9\ud574 \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc88b\uc740 \ucf54\ub4dc\ub97c \ub9cc\ub4dc\ub294 \uc5f0\uc2b5\uc744 \ud558\uc790. \\n\ud558\uc9c0\ub9cc \ucd94\uc0c1\ud654\ub97c \ud558\uba74 \ud560 \uc218\ub85d \ucf54\ub4dc\uc758 \ubcf5\uc7a1\ub3c4\ub294 \uc99d\uac00\ud55c\ub2e4. \\n\ud56d\uc0c1 \uc0c1\ud669\uc744 \uace0\ub824\ud558\uace0 \uac04\uacb0\ud568\uc744 \ud3ec\uae30\ud560 \ub9cc\ud07c \uc911\uc694\ud55c \ubd80\ubd84\uc778\uc9c0 \uc801\uc808\ud55c \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uace0\ub824\ud558\uc790. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[Mocking static methods](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks) \\n[Mockito mock static methods](https://www.baeldung.com/mockito-mock-static-methods) \\n[Enable mocking static methods in Mockito](https://github.com/mockito/mockito/issues/1013)"},{"id":"route-image-intro","metadata":{"permalink":"/route-image-intro","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx","source":"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx","title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd","description":"./route.png","date":"2023-07-27T00:00:00.000Z","formattedDate":"2023\ub144 7\uc6d4 27\uc77c","tags":[{"label":"image","permalink":"/tags/image"},{"label":"awt","permalink":"/tags/awt"}],"readingTime":5.865,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd","slug":"route-image-intro","tags":["image","awt"]},"prevItem":{"title":"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30","permalink":"/mock-static-method"},"nextItem":{"title":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","permalink":"/java-spring-springboot"}},"content":"![./route.png](./route.png)\\n\\n### \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784\\n\\n\uc704 \uc640\uc774\uc5b4 \ud504\ub808\uc784\uc5d0\uc11c `\uc5ec\ud589 \ud788\uc2a4\ud1a0\ub9ac`\uc640 `\uc5ec\ud589\uc5d0 \ub300\ud55c \uac10\uc0c1\uc744 \uc704\ud55c \uacbd\ub85c \uc774\ubbf8\uc9c0`\uc758 \uacbd\uc6b0 \ub124\uc774\ubc84 \uc9c0\ub3c4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\ub2f9 \uae30\ub2a5\uc744 \uad6c\ud604\ud560 \uc218 \uc5c6\uc73c\ub2c8 \ub2f9\uc5f0\ud788 \ub9f5 API\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub3c4\ud615 \uadf8\ub9ac\uae30 API(\ub124\uc774\ubc84 \ub9f5 API \uae30\uc900 Polyline)\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub2e4. \\n\ub530\ub77c\uc11c \uc774\ubbf8\uc9c0\ub97c \uc9c1\uc811 \uc0dd\uc131\ud558\uac70\ub098, \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uc11c \uc9c1\uc811 \uc704\uacbd\ub3c4\ub97c \uc774\uc6a9\ud558\uc5ec \uadf8\ub824\uc57c \ud55c\ub2e4.\\n\\n\ud574\ub2f9 \uc694\uad6c\uc0ac\ud56d\uc744 \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uae30\ub2a5\uc744 \uac00\uc9c4 \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 \ud544\uc694\ud558\ub2e4.\\n\\n- \uc774\ubbf8\uc9c0 \uc0dd\uc131\\n- \uc120\uacfc \uc810 \ud45c\ud604\\n- \ud22c\uba85\ud55c \ubc30\uacbd\uc0c9\\n\\n\ud604\uc7ac \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \ubc14\uc05c \uc77c\uc815\uacfc \uae30\ub2a5 \uad6c\ud604\uc5d0 \uc788\uc5b4 \uc57d\uac04\uc758 \uc5f0\uc0b0\uc774 \ub4e4\uc5b4\uac04\ub2e4\ub294 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uc5ec \ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30\ub85c \uacb0\uc815\uc744 \ub0b4\ub838\ub2e4.\\n\\n### \uace0\ub824\ud55c \uae30\uc220\\n\\n\ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uae30 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub610\ub294 \uae30\uc220\ub4e4\uc744 \ud655\uc778\ud574 \ubcf4\uc558\ub2e4. \\n\\n- Python\uc758 Matplotlib\\n- **AWT(Abstract Window Toolkit) [\ucd5c\uc885 \uc120\ud0dd]**\\n- \uc774\ubbf8\uc9c0 \ucc98\ub9ac \ub77c\uc774\ube0c\ub7ec\ub9ac \ubc0f Java\uc5d0\uc11c \ub0b4\ubd80\uc801\uc73c\ub85c Matplotlib \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac (\uc6d0\ud558\ub294 \uae30\ub2a5 \uc5c6\uc74c)\\n- Java Swing, Java FX (\ub2e8\uc21c\ud55c \uc120 \uadf8\ub9ac\uae30 + \uc810 \ucc0d\uae30\ub77c \ubd88\ud544\uc694)\\n\\n## Python & Matplotlib\\n\\n\ub370\uc774\ud130 \uc2dc\uac01\ud654 \ub77c\uc774\ube0c\ub7ec\ub9ac \\n\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 0.2\ucd08 \\n\\n- \ucf54\ub4dc\uac00 \uac04\ub2e8\ud574\uc11c \uc720\uc9c0 \ubcf4\uc218\uc131\uc774 \uc88b\ub2e4. \\n- AWS Lambda \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ucef4\ud4e8\ud305 \uc11c\ube44\uc2a4\ub098 FastAPI\uc640 \uac19\uc740 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\ub85c \ucd94\uac00\uc801\uc778 API\ub97c \uad6c\ud604\ud574\uc57c \ud55c\ub2e4.\\n- Spring Boot\uc5d0\uc11c \ucd94\uac00\uc801\uc778 API \ud638\ucd9c\uc744 \ud574\uc57c\ud558\uace0, \ud655\uc7a5\uc131\uacfc \ube44\ub3d9\uae30 \ucc98\ub9ac \ub4f1 \uace0\ub824 \ud574\uc57c \ud560 \ubd80\ubd84\uc774 \ub9ce\ub2e4.\\n\\n### Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\\n\\nPython\uc774 \uc544\ub2cc Java\uc5d0\uc11c\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub3c4 \uace0\ub824\ub97c \ud574\ubd24\uc9c0\ub9cc \uc694\uad6c\uc0ac\ud56d\uc5d0 \uc801\ud569\ud558\uc9c0 \uc54a\uac70\ub098, \uc801\uc740 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac70\uc6b4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc774 \ub9ce\uc544\uc11c \uc81c\uc678\ud588\ub2e4.\\n\\n\ub77c\uc774\ube0c\ub7ec\ub9ac | \uc124\uba85 | \uc81c\uc678 \uc774\uc720\\n-- | -- | --\\nSwing | AWT \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, \ub124\uc774\ud2f0\ube0c UI\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 \ubaa8\ub4e0 \uc6b4\uc601\uccb4\uc81c \uc0c1\uc5d0\uc11c \ub3d9\uc77c\ud55c UI\ub97c \uac00\uc9c0\ub3c4\ub85d \ud568 | \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c\\nJavaFX | Swing \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, 3\ucc28\uc6d0 \uadf8\ub798\ud53d\uc744 \uc9c0\uc6d0\ud568 | \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c\\n[simple-java-plot](https://github.com/yuriy-g/simple-java-plot) | AWT\ub85c \uad6c\ud604\ub41c \ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac | AWT \uae30\ubc18\uc774\uae34 \ud558\uc9c0\ub9cc \uc9c1\uc811 AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc5d0 \ube44\ud574 \uba54\ub9ac\ud2b8\uac00 \uc5c6\uc74c, \ucee4\uc2a4\ud140 \uc124\uc815 \uae30\ub2a5\uc774 \uc5c6\uc74c\\n[matplotlib4j](https://github.com/sh0nk/matplotlib4j) | Matplotlib\ub97c Java\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uac8c \ud558\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac | \ub0b4\ubd80\uc801\uc73c\ub85c \ud30c\uc774\uc36c \uc0ac\uc6a9\ud558\uae30\uc5d0 \ubb34\uac70\uc6c0, \ubc30\uacbd \ud22c\uba85\ud654 \uae30\ub2a5 \uc5c6\uc74c\\n\\n### Java & AWT(Abstract Window Toolkit)\\n\\n\uadf8\ub798\ud53d\uacfc \uc774\ubbf8\uc9c0\ub97c \uadf8\ub9ac\uae30 \uc704\ud55c \ub3c4\uad6c \\n\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 1.75\ucd08 \\n\\n- \ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ubcf4\ub2e4 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc874\uc7ac\ud55c\ub2e4.\\n- \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub2e4\uc18c \uc18c\uc694\ub418\uae30 \ub54c\ubb38\uc5d0 \ube60\ub978 \uc751\ub2f5 \ubc18\ud658\uc744 \uc704\ud574 \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \uace0\ub824\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.\\n- \ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4.\\n\\n### \uae30\uc220 \uc120\ud0dd\\n\\nAWT\uc758 \uacbd\uc6b0 Matplotlib\uc5d0 \ube44\ud574 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc788\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub354 \ub9ce\uc774 \uac78\ub9ac\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4. \\n\ud558\uc9c0\ub9cc \ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub418\ub294 \ubd80\ubd84, Python\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc778 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uace0\ub824\ud558\uc5ec AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.\\n\\n### \uc720\uc9c0 \ubcf4\uc218\\n\\nAWT\ub77c\ub294 \uc0dd\uc18c\ud55c \uae30\uc220\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc720\uc9c0 \ubcf4\uc218\uc131\uc744 \uc704\ud574 \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ub530\ub77c\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ubc29\ubc95\uc73c\ub85c \uacf5\uc720\ud558\uae30\ub85c \ud588\ub2e4. \\n\\n1. \ucf54\ub4dc \ub9ac\ubdf0\uc640 PR\uc744 \ud1b5\ud574 \uc791\uc131\ud55c AWT \ucf54\ub4dc\uc5d0 \ub300\ud55c \uc124\uba85 \ubc0f \ub9ac\ubdf0 \ubc1b\ub294\ub2e4. \\n2. AWT\ub97c \uc0ac\uc6a9\ud55c \ubd80\ubd84\uc744 \ubb38\uc11c\ud654\ud558\uc5ec \uacf5\uc720\ud55c\ub2e4.\\n\\n### \ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00\\n\\n\uae30\uc220 \uc120\ud0dd\uc744 \ud558\uae30 \uc704\ud55c \uc2e4\ud589 \uc2dc\uac04 \uce21\uc815\uc5d0 \uc624\ub958\uac00 \uc788\uc5c8\ub2e4. \\nAWT\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc2e4\ud589 \uc2dc\uac04\uc744 \uc81c\uc678\ud558\uba74 \ud30c\uc774\uc36c\uacfc \ube44\uc2b7\ud55c \uc2dc\uac04\uc548\uc5d0 \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud560 \uc218 \uc788\uc5c8\ub2e4."},{"id":"java-spring-springboot","metadata":{"permalink":"/java-spring-springboot","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx","source":"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx","title":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","description":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","date":"2023-07-24T00:00:00.000Z","formattedDate":"2023\ub144 7\uc6d4 24\uc77c","tags":[{"label":"Java","permalink":"/tags/java"},{"label":"Spring Boot","permalink":"/tags/spring-boot"},{"label":"Spring","permalink":"/tags/spring"}],"readingTime":4.725,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","slug":"java-spring-springboot","tags":["Java","Spring Boot","Spring"]},"prevItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd","permalink":"/route-image-intro"},"nextItem":{"title":"\uc6f9\uc18c\ucf13","permalink":"/websocket"}},"content":"## \uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1\\n\\n\ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1\uc744 \uc0ac\uc6a9\ud558\uac8c \ub418\uc5c8\ub2e4. \\n2.7 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud560 \uc218\ub3c4 \uc788\uc5c8\uc9c0\ub9cc LTS \uae30\uac04\uacfc \ucde8\uc57d\uc810 \ud328\uce58\ub85c \uc778\ud55c \ubc84\uc804\uc5c5 \ub4f1\uc744 \uace0\ub824\ud588\uc744 \ub54c 3.1\uacfc \uc790\ubc14 17\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \ub354 \ud6a8\uc728\uc801\uc774\ub77c\uace0 \ud310\ub2e8\ud588\ub2e4.\\n\\n## \uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d\\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2\uae4c\uc9c0\ub294 \uc790\ubc14 11\uc744 \uc0ac\uc6a9\ud588\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c \uc790\ubc14 11\ubd80\ud130 \uc790\ubc14 17\uae4c\uc9c0\uc758 \ubcc0\uacbd\uc0ac\ud56d\uc744 \uc815\uc2dd \ub9b4\ub9ac\uc988 \uae30\uc900\uc73c\ub85c \uc815\ub9ac\ud574\ubcf4\ub824\uace0 \ud55c\ub2e4.\\n\\n### Switch Expressions(Java 14)\\n\\nJava 14\uc5d0\uc11c\ub294 \uae30\uc874\uc758 Switch \ubb38\uc744 \uac04\uacb0\ud558\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub294 Switch \uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\\n```java\\nenum RESULT {\\n WIN, LOSE, DRAW\\n}\\n\\nRESULT result = RESULT.WIN;\\n\\nint prize = switch (result) {\\n case WIN -> 10_000_000;\\n case LOSE, DRAW -> 5_000_000;\\n\\tdefault -> 0;\\n};\\n```\\n\\n\uc8fc\uc694 \ud2b9\uc9d5\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.\\n\\n- `->` \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 case\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc14\ub85c \ubc18\ud658\ud560 \uc218 \uc788\ub2e4.\\n- case\ub97c \ucf64\ub9c8(`,`)\ub85c \uc5f0\uacb0\ud558\uc5ec \ud558\ub098\uc758 case\uc5d0 \uc5ec\ub7ec \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.\\n- break \ubb38\uc774 \ud544\uc694 \uc5c6\ub2e4.\\n- default \ube14\ub85d\uc744 \ud1b5\ud574 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.\\n\\n### Text Block(Java 15)\\n\\nJava 15\uc5d0\ub294 \uc0c8\ub85c\uc6b4 \ubb38\uc790\uc5f4 \ud45c\ud604\ubc29\uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\uae34 \ubb38\uc790\uc5f4\uc744 + \uc5f0\uc0b0\uc790\uc758 \ub3c4\uc6c0 \uc5c6\uc774 \uac00\ub3c5\uc131\uc788\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub2e4.\\n\\n```java\\n@Repository\\npublic interface PostRepository extends JpaRepository<Post, Long> {\\n @Query(\\"\\"\\"\\n SELECT p FROM Post p\\n WHERE p.title LIKE %:keyword%\\n OR p.content LIKE %:keyword%\\n \\"\\"\\")\\n List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);\\n}\\n```\\n\\n### NPE \uba54\uc2dc\uc9c0(Java 15)\\n\\n```java\\nString name = null;\\nname.chars();\\n\\n/** \\n# before\\njava.lang.NullPointerException\\n\\tat com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)\\n\\n# after\\nCannot invoke \\"String.chars()\\" because \\"name\\" is null\\njava.lang.NullPointerException: Cannot invoke \\"String.chars()\\" because \\"name\\" is null\\n*/\\n```\\n\\n### Record(Java 16)\\n\\nLombok\uc758 `@Data`, kotlin\uc758 data \ud074\ub798\uc2a4\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4. \\nRecord\ub97c \uc120\uc5b8\ud558\ub294 \uacbd\uc6b0 \uc811\uadfc\uc790, \uc0dd\uc131\uc790, equals & hashcode, toString\uc774 \uc81c\uacf5\ub41c\ub2e4. \\n\ub370\uc774\ud130 \uc804\uc1a1 \uc6a9\ub3c4\ub85c \uc801\ud569\ud574 \ubcf4\uc778\ub2e4. \\n\\n```java\\npublic record PostDto(String title, String content) {\\n}\\n```\\n\\n### \ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d\\n\\n\uc774\uc678\uc5d0\ub3c4 stream\uc758 toList, \uc778\uc2a4\ud134\uc2a4\uc758 \ud0c0\uc785\uc744 \uac04\ud3b8\ud558\uac8c \uccb4\ud06c\ud558\ub294 Pattern Matching Instanceof, Sealed class \ub4f1\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\\n## \uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d\\n\\n\uc2a4\ud504\ub9c1\uacfc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\ub3c4 \ub9ce\uc740 \ubcc0\uacbd \uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c \ud544\uc694\ud574\ubcf4\uc774\ub294 \uba87\uac1c \uc815\ub3c4\ub9cc \uc815\ub9ac\ud588\ub2e4. \\n\\n### \uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d\\n\\nJava 17, Jakarta EE 9 \uc774\uc0c1\uc774\uc5b4\uc57c \ud55c\ub2e4.\\n\\n### \ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd\\n\\nJakarta EE 9\uac00 \uc801\uc6a9\ub418\uba74\uc11c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub3c4 \uc804\ubc18\uc801\uc73c\ub85c javax -> jakarta\ub85c \ubcc0\uacbd\ub418\uc5c8\ub2e4. \\n\\n### PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c\\n\\n6.0 \uc774\uc804\uc758 \uacbd\uc6b0 \uae30\ubcf8 \uc124\uc815 \uae30\uc900\uc73c\ub85c `@GetMapping(\\"/hello\\")`\uc640 `@GetMapping(\\"/hello/\\")`\uac00 \ub3d9\uc77c\ud588\ub2e4. \\n6.0 \uc774\ud6c4\uc758 PathPatternParser\uac00 \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\uace0, `/hello`\uc640 `/hello/`\ub294 \uc11c\ub85c \ub2e4\ub978 URL\ub85c \ub9e4\uce6d\ub41c\ub2e4. \\n\\n> PathPatternParser used by default (with the ability to opt into PathMatcher). \\n\\n### HTTP interface client\\n\\n\uc790\ubc14 \uc778\ud130\ud398\uc774\uc2a4\uc640 \uc5b4\ub178\ud14c\uc774\uc158\uc744 \uc774\uc6a9\ud558\uc5ec HTTP \uc694\uccad\uc744 \uc704\ud55c \uc11c\ube44\uc2a4\ub97c \uc815\uc758\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 [\ud1a0\ube44\ub2d8\uc758 \uac15\uc758](https://www.youtube.com/watch?v=Kb37Q5GCyZs)\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4.\\n\\n### \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d\\n\\nGradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6 \\n\uc774\uc678\uc5d0\ub3c4 \uc11c\ub4dc\ud30c\ud2f0\ub4e4\uc758 \ucd5c\uc2e0 \ub9b4\ub9ac\uc988 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c, \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ud574\ub2f9 \ubc84\uc804\uc5d0 \ub9de\ub294 \ub9b4\ub9ac\uc988 \ub178\ud2b8\ub97c \ucc38\uace0\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. \\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n[\uc5b4\ub290\xa0\uc6d4\uae09\uc7c1\uc774\uac1c\ubc1c\uc790\xa0\uc758 \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ub530\ub77c\uc7a1\uae30](https://www.youtube.com/watch?v=1WT6oxchM9M) \\n[\uc790\ubc14 9-16 \uc8fc\uc694 \ud2b9\uc9d5 \ubcf5\uc2b5\ud558\uae30](https://www.youtube.com/watch?v=7SlDdzVk6GE) \\n[Java EE\uc5d0\uc11c Jakarta EE\ub85c\uc758 \uc804\ud658](https://www.samsungsds.com/kr/insights/java_jakarta.html) \\n[Spring 6\uc758 \uc0c8\ub85c\uc6b4 HTTP Interface\uc640 3 \uac00\uc9c0 REST Clients \ub77c\uc774\ube0c \ucf54\ub529](https://www.youtube.com/watch?v=Kb37Q5GCyZs) \\n[What\'s New in Spring Framework 6.x](https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x) \\n[Spring Boot 3.0 Release Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes) \\n[Spring Boot 3.1 Release Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes)"},{"id":"websocket","metadata":{"permalink":"/websocket","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-26-WebSocket.mdx","source":"@site/blog/2023-2/2023-06-26-WebSocket.mdx","title":"\uc6f9\uc18c\ucf13","description":"\uc6f9\uc18c\ucf13","date":"2023-06-26T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 26\uc77c","tags":[{"label":"WebSocket","permalink":"/tags/web-socket"}],"readingTime":4.165,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6f9\uc18c\ucf13","slug":"websocket","tags":["WebSocket"]},"prevItem":{"title":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","permalink":"/java-spring-springboot"},"nextItem":{"title":"Docusaurus","permalink":"/docusaurus"}},"content":"### \uc6f9\uc18c\ucf13\\n\\n\ub2e8\uc77c TCP \uc5f0\uacb0\uc744 \ud1b5\ud574 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ubc84 \uac04 \uc804\uc774\uc911 \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \uc9c0\uc6d0\ud558\ub294 \ud504\ub85c\ud1a0\ucf5c \\n\uc6f9 \ud658\uacbd\uc5d0\uc11c \uc5f0\uc18d\ub41c \ub370\uc774\ud130\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4. \\n\\n\uc6f9\uc18c\ucf13\uc740 HTTP\uc758 \ud3ec\ud2b8\ub97c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uace0 \uac01\uac01 \ud3ec\ud2b8 80\uacfc \ud3ec\ud2b8 443\uc744 \uc0ac\uc6a9\ud558\uc5ec HTTP(ws://) \ubc0f HTTPS(wss://)\ub85c \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ud55c\ub2e4. \\n\\n### \uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd\\n\\n\uc6f9\uc18c\ucf13\uc774 \ub4f1\uc7a5\ud558\uae30 \uc774\uc804, \uc2e4\uc2dc\uac04\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 Polling, Long polling, Streaming \uac19\uc740 \uae30\uc220\uc744 \uc0ac\uc6a9\ud588\uc5b4\uc57c \ud588\ub2e4. \\n\uc774\ub294 \uc2e4\uc2dc\uac04\uc131\uc774\ub098 \uc591\ubc29\ud5a5\uc131\uc744 \ub9cc\uc871\uc2dc\ud0a4\uc9c0 \ubabb\ud588\uace0, HTTP\ub97c \uc774\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uacfc\ub3c4\ud55c \uc624\ubc84\ud5e4\ub4dc\uac00 \ubc1c\uc0dd\ud588\ub2e4. \\n\\n:::note polling, long polling, streaming\\n\\nPolling: \uc8fc\uae30\uc801\uc73c\ub85c \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ubcf4\ub0b4 \uc218\uc2e0\ud560 \uc815\ubcf4\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubc29\ubc95\\n- \uc11c\ubc84\uc5d0\uc11c \ubcf4\ub0bc \ub0b4\uc6a9\uc774 \uc5c6\uc5b4\ub3c4 \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \uc54c \uc218 \uc5c6\ub2e4. \\n- \uacc4\uc18d\ud574\uc11c \uc694\uccad\uc744 \ubcf4\ub0b4 \ud655\uc778\uc744 \ud574\uc57c\ud558\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ubd88\ud544\uc694\ud55c \ubd80\ud558\ub97c \uc8fc\uc5b4\uc57c \ud55c\ub2e4. \\n\\nLong Polling: \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc5d0 \ub300\ud574 \uc751\ub2f5\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uace0 \uc788\ub2e4\uac00 \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud588\uc744\ub54c \uc751\ub2f5\ud558\ub294 \ubc29\ubc95\\n- \ud3f4\ub9c1 \ubc29\uc2dd\ubcf4\ub2e4 \uc11c\ubc84\uc5d0 \uc801\uc740 \ubd80\ud558\ub97c \uc904 \uc218 \uc788\uc9c0\ub9cc, \uc694\uccad\uc758 \uc8fc\uae30\uac00 \uc9e7\uc73c\uba74 \ud3f4\ub9c1\uacfc \ucc28\uc774\uac00 \uc5c6\uc5b4\uc9c4\ub2e4.\\n\\nStreaming: \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 request\ub97c \ubcf4\ub0b4\uba74 \ucee4\ub125\uc158\uc744 \ub9fa\uace0, \uc774 \ucee4\ub125\uc158\uc744 \uc720\uc9c0\ud558\uba74\uc11c \uc11c\ubc84\uac00 \uacc4\uc18d \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95\\n- \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ud558\uace0 \uc2f6\ub2e4\uba74 \uc0c8\ub85c\uc6b4 \ucee4\ub125\uc158\uc744 \ub9fa\uc5b4\uc57c \ud55c\ub2e4. \\n:::\\n\\n### \uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791\\n\\n```mermaid\\nsequenceDiagram\\n participant Client\\n participant Server\\n Client->>Server: Handshake - Upgrade\ub97c \uc774\uc6a9\ud55c WebSocket \uc804\ud658 \uc694\uccad\\n Server->>Client: Handshake - HttpStatus 101(Switching Protocols)\\n\\n Client->>Server: \uc591\ubc29\ud5a5 \ud1b5\uc2e0\\n Server->>Client: \\n\\n Client->>Server: \uc885\ub8cc\\n Server->>Client: \\n```\\n\\n### 1. Upgrade \uc694\uccad\\n\\nWebSocket \ud504\ub85c\ud1a0\ucf5c\ub85c \uc804\ud658\ud558\ub294 HTTP \uc694\uccad\uc744 \ubcf4\ub0b8\ub2e4. \\n\uc774\ub294 HTTP\uc640 \uac19\uc774 80, 443 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud55c\ub2e4. \\n\uc6f9\uc18c\ucf13\uc73c\ub85c \uc804\ud658\ud558\uae30 \uc704\ud574\uc11c\ub294 Upgrade: websocket, Connection: Upgrade \ud5e4\ub354\uac00 \ud544\uc694\ud558\ub2e4. \\nSec-WebSocket-Key\ub294 \uc11c\ubc84\uc5d0\uc11c Sec-WebSocket-Accept\ub97c \uacc4\uc0b0\ud558\uc5ec \uc751\ub2f5\ud558\uace0 \uc774 \uac12\uc774 \uc608\uc0c1\ud55c \uac12\uacfc \ub2e4\ub974\uba74 \uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uc9c0 \uc54a\ub294\ub2e4. \\nSec-WebSocket-Protocol\uc758 \uacbd\uc6b0 \uc11c\ube0c\ud504\ub85c\ud1a0\ucf5c\uc758 \ubaa9\ub85d\uc73c\ub85c \uc11c\ubc84 \uce21\uc5d0\uc11c\ub294 \ud574\ub2f9 \ubaa9\ub85d \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud558\uc5ec \ubc18\ud658\ud574\uc57c \ud55c\ub2e4. \\n\ub9cc\uc57d \uc11c\ubc84\uce21\uc5d0\uc11c \uc5ec\ub7ec \uac1c \uc9c0\uc6d0\uc774 \uac00\ub2a5\ud55c \uacbd\uc6b0 \uc9c0\uc6d0 \uac00\ub2a5\ud55c \ud504\ub85c\ud1a0\ucf5c \uc911 \uccab\ubc88\uc9f8 \ud504\ub85c\ud1a0\ucf5c\uc744 \ud074\ub77c\uc774\uc5b8\ud2b8\uce21\uc73c\ub85c \ubcf4\ub0b8\ub2e4. \\n\\n```\\nGET /chats HTTP/1.1\\nHost: localhost:8080\\nUpgrade: websocket\\nConnection: Upgrade\\nSec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==\\nSec-WebSocket-Protocol: v10.stomp, v11.stomp\\nSec-WebSocket-Version: 13\\nOrigin: http://localhost:8080\\n```\\n\\n### 2. Switching Protocols\\n\\n\uc11c\ubc84\ub294 101 Switching Protocols \uc751\ub2f5\uc744 \ubc18\ud658\ud55c\ub2e4. \\nSec-WebSocket-Accept\uc740 Sec-WebSocket-Key \ub4a4\uc5d0 `258EAFA5-E914-47DA-95CA-C5AB0DC85B11`\ub97c \ubd99\uc774\uace0 SHA1\ub85c \ud574\uc2f1 \ud6c4 Base64\ub85c \uc778\ucf54\ub529\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4. \\n\uc774\ub294 \uc11c\ubc84 \uc6f9\uc18c\ucf13 \ud504\ub85c\ud1a0\ucf5c\uc758 \uc9c0\uc6d0 \uc5ec\ubd80\ub97c \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \uba85\ud655\ud788 \uc54c\ub9ac\uae30 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4. \\n\\n```\\nHTTP/1.1 101 Switching Protocols \\nUpgrade: websocket\\nConnection: Upgrade\\nSec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=\\nSec-WebSocket-Protocol: v10.stomp\\n```\\n\\n### 3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc\\n\\n\uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uba74 \uc6f9\uc18c\ucf13 \ud504\ub808\uc784 \ub2e8\uc704\ub85c \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \ud55c\ub2e4. \\n\uc5f0\uacb0 \uc885\ub8cc\ub97c \uc6d0\ud558\ub294 \uacbd\uc6b0 \ud074\ub77c\uc774\uc5b8\ud2b8, \uc11c\ubc84 \ubaa8\ub450 \uc5f0\uacb0 \uc885\ub8cc\ub97c \uc694\uccad\ud560 \uc218 \uc788\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\nhttps://datatracker.ietf.org/doc/html/rfc6455 \\nhttps://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications \\nhttps://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers \\nhttps://docs.spring.io/spring-framework/reference/web/websocket.html"},{"id":"docusaurus","metadata":{"permalink":"/docusaurus","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx","source":"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx","title":"Docusaurus","description":"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4.","date":"2023-06-18T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 18\uc77c","tags":[{"label":"Documentation","permalink":"/tags/documentation"}],"readingTime":10.095,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Docusaurus","slug":"docusaurus","tags":["Documentation"]},"prevItem":{"title":"\uc6f9\uc18c\ucf13","permalink":"/websocket"},"nextItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0","permalink":"/woowacourse-level2-retrospective"}},"content":"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4. \\n\\n## \uc124\uce58\\n\\n[\uacf5\uc2dd \ud648\ud398\uc774\uc9c0](https://docusaurus.io/docs/installation)\uc5d0 \ub4e4\uc5b4\uac00\uc11c \ucd5c\uc2e0 \ubc84\uc804\uc744 \uc124\uce58\ud55c\ub2e4. \\n\\n```bash\\nyarn create docusaurus\\n````\\n\\n## \ubc30\ud3ec\\n\\n[\ubc30\ud3ec \uc548\ub0b4 \ubb38\uc11c](https://docusaurus.io/docs/next/deployment#deploying-to-github-pages) \\nnetlify\ub098 vercel \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ud50c\ub7ab\ud3fc\uc744 \ucd94\ucc9c\ud558\uace0 \uc788\uace0, \uac04\ub2e8\ud558\uace0, \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \ubc30\ud3ec\ub97c \ud560 \uc218 \uc788\ub2e4. \\n\uc774 \uae00\uc5d0\uc11c\ub294 github pages\ub97c \uc774\uc6a9\ud574\uc11c \ubc30\ud3ec\ud558\ub294 \ubc29\ubc95\uc744 \uc124\uba85\ud55c\ub2e4.\\n\\n### \ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131\\n\\ngithub pages\ub97c \uc774\uc6a9\ud558\ub824\uba74 [\uc608\uc2dc](https://github.com/greeng00se/greeng00se.github.io)\uc640 \uac19\uc774 `username.github.io` \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4. \\n\uc774\ub54c organization\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 `organization.github.io` \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n### \uc124\uc815 \ud30c\uc77c \uc218\uc815\\n\\n```js title=\\"docusaurus.config\\"\\nmodule.exports = {\\n // ...\\n url: \'https://greeng00se.github.io\',\\n baseUrl: \'/\',\\n projectName: \'greeng00se.github.io\',\\n organizationName: \'greeng00se\',\\n trailingSlash: false,\\n // ...\\n};\\n```\\n\\n### \ud1a0\ud070 \uc124\uc815\\n\\ngithub action\uc744 \uc704\ud574 \ubc30\ud3ec\uc6a9 \ud1a0\ud070\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uc5ec \uc0dd\uc131\ud55c \ub808\ud3ec\uc9c0\ud1a0\ub9ac\uc5d0 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c\ub2e4. \\n\uc774 \uae00\uc5d0\uc11c\ub294 \ud1a0\ud070\uc744 \ud074\ub798\uc2dd \ubc29\uc2dd\uc73c\ub85c \uc0dd\uc131\ud588\uace0 \uc2a4\ucf54\ud504\ub294 [repo, user, workflow] \uc744 \uc124\uc815\ud588\ub2e4. \\n\\n![github](./github.png)\\n\\n### \ube0c\ub79c\uce58 \uc0dd\uc131\\n\\ngithub\uc5d0\uc11c gh-pages \ube0c\ub79c\uce58\ub97c \ud558\ub098 \uc0dd\uc131\ud55c\ub2e4. \\nrepository -> settings -> pages -> branch\uc5d0\uc11c \uc0dd\uc131\ud55c gh-pages\ub85c \ube0c\ub79c\uce58\ub97c \ubcc0\uacbd\ud55c\ub2e4. \\n\uc124\uc815\ud55c \ube0c\ub79c\uce58\uac00 \ubc30\ud3ec \ube0c\ub79c\uce58\uac00 \ub418\uba70, \ud574\ub2f9 \ube0c\ub79c\uce58\uc5d0 \uc788\ub294 \ud30c\uc77c\ub4e4\uc744 \uc774\uc6a9\ud574\uc11c \uc815\uc801 \uc6f9\uc0ac\uc774\ud2b8\ub97c \uc81c\uacf5\ud55c\ub2e4. \\n\\n### \uc6cc\ud06c\ud50c\ub85c \uc791\uc131\\n\\nDocusaurus 2.0 \uae30\uc900 Node.js 16.14 \uc774\uc0c1\uc758 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4. \\n\ubc30\ud3ec\uc2dc\uc5d0\ub294 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c DEPLOY_TOKEN \uc744 \uc774\uc6a9\ud569\ub2c8\ub2e4. \\n\\n```yml title=\\".github/workflows/deploy.yml\\"\\nname: blog\\n\\non:\\n push:\\n branches: [main]\\n\\njobs:\\n deploy:\\n name: Deploy to GitHub Pages\\n runs-on: ubuntu-latest\\n steps:\\n - uses: actions/checkout@v2\\n - uses: actions/setup-node@v3\\n with:\\n node-version: 18\\n cache: yarn\\n\\n - name: Install dependencies\\n run: yarn install --frozen-lockfile\\n - name: Build website\\n run: yarn build\\n\\n - name: Deploy to GitHub Pages\\n uses: peaceiris/actions-gh-pages@v3\\n with:\\n github_token: ${{ secrets.DEPLOY_TOKEN }}\\n publish_dir: ./build\\n user_name: github-actions[bot]\\n user_email: 41898282+github-actions[bot]@users.noreply.github.com\\n```\\n\\n## \ub313\uae00 \uae30\ub2a5\\n\\ngiscus\ub97c \uc774\uc6a9\ud558\uc5ec \ub313\uae00 \uae30\ub2a5\uc744 \ucd94\uac00\ud55c\ub2e4. \\n\\n### giscus \uc124\uc815\\n\\n1. \uacf5\uac1c \uc800\uc7a5\uc18c\uc5ec\uc57c \ud55c\ub2e4.\\n2. giscus \uc571\uc774 \uc124\uce58\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4.\\n3. Discussions \uae30\ub2a5\uc774 \ud574\ub2f9 \uc800\uc7a5\uc18c\uc5d0\uc11c \ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4.\\n\\n\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 [giscus](https://giscus.app/ko)\ub97c \ud655\uc778\ud558\uc790.\\n\\n### docusaurus \uc124\uc815\\n\\n[swizzling](https://docusaurus.io/ko/docs/next/swizzling)\uc744 \uc774\uc6a9\ud558\uc5ec \ucef4\ud3ec\ub10c\ud2b8\ub97c \uac10\uc2fc\ub2e4. \\n\uae30\uc874\uc5d0 \uac8c\uc2dc\ubb3c\uc744 giscus\uac00 \ud3ec\ud568\ub41c \ub9ac\uc561\ud2b8 \ucef4\ud3ec\ub10c\ud2b8\ub85c \uac10\uc2f8\ub294 \ud615\ud0dc\uac00 \ub41c\ub2e4. \\n\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec BlogPostItem\uc744 \ucd94\ucd9c\ud560 \uc218 \uc788\ub2e4. \\n\\n```bash\\nyarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap\\n```\\n\\n\uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uba74 `/src/theme/BlogPostItem/index.js` \uc704\uce58\uc5d0 \ud30c\uc77c\uc774 \uc0dd\uc131\ub41c\ub2e4. \\n\ud30c\uc77c\uc758 \ub0b4\uc6a9\uc744 \uc544\ub798\uc640 \uac19\uc774 \uc218\uc815\ud558\uace0, \uc774\ub54c setAttribute \ubd80\ubd84\uc740 \uc801\uc808\ud558\uac8c \uc790\uc2e0\uc758 giscus \uc124\uc815\uc744 \uc774\uc6a9\ud55c\ub2e4. \\n\\n```js title=\\"/src/theme/BlogPostItem/index.js\\"\\nimport OriginalBlogPostItem from \\"@theme-original/BlogPostItem\\";\\nimport React, { useEffect, useRef } from \\"react\\";\\n// @ts-expect-error internal code\\nimport { useColorMode } from \\"@docusaurus/theme-common\\";\\nimport { useBlogPost } from \\"@docusaurus/theme-common/internal\\";\\n\\nconst giscusSelector = \\"iframe.giscus-frame\\";\\n\\nfunction BlogPostItem(props) {\\n const { colorMode } = useColorMode();\\n const { isBlogPostPage } = useBlogPost();\\n const giscusTheme = colorMode === \\"dark\\" ? \\"dark\\" : \\"light\\";\\n const containerRef = useRef(null);\\n\\n useEffect(() => {\\n if (!isBlogPostPage) return;\\n\\n const giscusEl = containerRef.current.querySelector(giscusSelector);\\n\\n const createGiscusEl = () => {\\n const script = document.createElement(\\"script\\");\\n\\n script.src = \\"https://giscus.app/client.js\\";\\n script.setAttribute(\\"data-repo\\", \\"teco-chat/teco-chat.github.io\\");\\n script.setAttribute(\\"data-repo-id\\", \\"R_kgDOJZ5j0Q\\");\\n script.setAttribute(\\"data-category\\", \\"Announcements\\");\\n script.setAttribute(\\"data-category-id\\", \\"DIC_kwDOJZ5j0c4CXS_Q\\");\\n script.setAttribute(\\"data-mapping\\", \\"pathname\\");\\n script.setAttribute(\\"data-strict\\", \\"0\\");\\n script.setAttribute(\\"data-reactions-enabled\\", \\"1\\");\\n script.setAttribute(\\"data-emit-metadata\\", \\"0\\");\\n script.setAttribute(\\"data-input-position\\", \\"bottom\\");\\n script.setAttribute(\\"data-theme\\", giscusTheme);\\n script.setAttribute(\\"data-lang\\", \\"ko\\");\\n script.crossOrigin = \\"anonymous\\";\\n script.async = true;\\n \\n containerRef.current.appendChild(script);\\n };\\n\\n const postThemeMessage = () => {\\n const message = {\\n setConfig: {\\n theme: giscusTheme,\\n }\\n };\\n\\n giscusEl.contentWindow.postMessage({ giscus: message }, \\"https://giscus.app\\");\\n };\\n\\n giscusEl ? postThemeMessage() : createGiscusEl();\\n }, [giscusTheme]);\\n\\n return (\\n <>\\n <OriginalBlogPostItem {...props} />\\n {isBlogPostPage && <div ref={containerRef} />}\\n </>\\n );\\n}\\n\\nexport default BlogPostItem;\\n```\\n\\n## \uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30\\n\\n\uc54c\uace0\ub9ac\uc544\ub97c \uc0ac\uc6a9\ud558\uba74 \uac80\uc0c9 \uae30\ub2a5\uc744 \ucd94\uac00\ud560 \uc218 \uc788\ub2e4. \\n\uc720\ub8cc \ud50c\ub79c\uc774\ub098 netlify\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ud06c\ub864\ub7ec\ub97c \ub530\ub85c \uc81c\uacf5\ud574 \uc8fc\ub294 \uac83 \uac19\ub2e4. \\n\\n\ubb34\ub8cc \ud50c\ub79c\uc740 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uacfc, [docsearch](https://docsearch.algolia.com/)\ub97c \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4. \\ndocsearch\uc5d0 \ub4f1\ub85d\ud55c\ub2e4\uba74 \uc77c\uc8fc\uc77c\uc5d0 \ud55c \ubc88\uc529 \ud06c\ub864\ub9c1\uc774 \uc9c4\ud589\ub41c\ub2e4. \\n\uc774 \uae00\uc5d0\uc11c\ub294 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n- [\uc9c1\uc811 \uc778\ub371\uc2a4 \uc218\uc9d1](https://docsearch.algolia.com/docs/legacy/run-your-own/) \\n- [\uc124\uc815 \ud30c\uc77c](https://docsearch.algolia.com/docs/legacy/config-file)\\n\\n### \uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778\\n\\n\ud68c\uc6d0\uac00\uc785\uc744 \ud558\uace0 \uc0c8\ub85c\uc6b4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131\uc744 \ub204\ub978\ub2e4. \\n\uc0dd\uc131\uc744 \ub2e4 \ub9c8\uce58\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 api \ud0a4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n![algolia](./algolia.png)\\n\\n### \ud0a4 \uc0dd\uc131\\n\\n\uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\uae30 \uc704\ud55c \ud0a4\ub97c \uc0dd\uc131\ud55c\ub2e4. \\naddObject, editSettings, deleteIndex acl(\uc811\uadfc \uc81c\uc5b4 \ubaa9\ub85d)\uc774 \uc788\uc73c\uba74 \ub41c\ub2e4. \\n\\n![key](./key.png)\\n\\n### .env \ud30c\uc77c \uc0dd\uc131\\n\\n\ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354 \uc0c1\ub2e8\uc5d0 .env \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4. \\n\\n```bash title=\\".env\\"\\nAPPLICATION_ID=MVIU5UEMOM\\nAPI_KEY=\uc778\ub371\uc2a4_\uc0dd\uc131\uc6a9_\ud0a4\\n```\\n\\n### config \ud30c\uc77c \uc0dd\uc131\\n\\n\ub9c8\ucc2c\uac00\uc9c0\ub85c \ucd5c\uc0c1\ub2e8\uc5d0 config.json \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4.\\n\uc124\uc815 \ud30c\uc77c\uc740 \ud574\ub2f9 [\ub9c1\ud06c](https://docsearch.algolia.com/docs/legacy/config-file)\ub97c \ucc38\uace0\ud55c\ub2e4. \\n\ub610\ub294 Docusaurus\uc758 [\uc124\uc815 \ud30c\uc77c](https://github.com/algolia/docsearch-configs/blob/master/configs/docusaurus-2.json)\uc744 \ucc38\uace0\ud55c\ub2e4.\\n\\n```json title=\\"config.json\\"\\n{\\n \\"index_name\\": \\"teco\\",\\n \\"start_urls\\": [\\n \\"https://teco-chat.github.io/\\"\\n ],\\n \\"sitemap_urls\\": [\\n \\"https://teco-chat.github.io/sitemap.xml\\"\\n ],\\n \\"sitemap_alternate_links\\": true,\\n \\"stop_urls\\": [\\n \\"/tests\\"\\n ],\\n \\"selectors\\": {\\n \\"lvl0\\": {\\n \\"selector\\": \\"(//ul[contains(@class,\'menu__list\')]//a[contains(@class, \'menu__link menu__link--sublist menu__link--active\')]/text() | //nav[contains(@class, \'navbar\')]//a[contains(@class, \'navbar__link--active\')]/text())[last()]\\",\\n \\"type\\": \\"xpath\\",\\n \\"global\\": true,\\n \\"default_value\\": \\"Documentation\\"\\n },\\n \\"lvl1\\": \\"header h1\\",\\n \\"lvl2\\": \\"article h2\\",\\n \\"lvl3\\": \\"article h3\\",\\n \\"lvl4\\": \\"article h4\\",\\n \\"lvl5\\": \\"article h5, article td:first-child\\",\\n \\"lvl6\\": \\"article h6\\",\\n \\"text\\": \\"article p, article li, article td:last-child\\"\\n },\\n \\"strip_chars\\": \\" .,;:#\\",\\n \\"custom_settings\\": {\\n \\"separatorsToIndex\\": \\"_\\",\\n \\"attributesForFaceting\\": [\\n \\"language\\",\\n \\"version\\",\\n \\"type\\",\\n \\"docusaurus_tag\\"\\n ],\\n \\"attributesToRetrieve\\": [\\n \\"hierarchy\\",\\n \\"content\\",\\n \\"anchor\\",\\n \\"url\\",\\n \\"url_without_anchor\\",\\n \\"type\\"\\n ]\\n },\\n \\"conversation_id\\": [\\n \\"833762294\\"\\n ],\\n \\"nb_hits\\": 46250\\n}\\n```\\n\\n### docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1\\n\\ndocker\uc640 jq\uac00 \ud544\uc694\ud558\ub2e4. \\njq\uac00 \uc124\uce58\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc73c\uba74 mac \uae30\uc900 brew\ub97c \uc774\uc6a9\ud574\uc11c \uc124\uce58\ud560 \uc218 \uc788\ub2e4. \\n\\n```bash\\nbrew install jq\\n```\\n\\n\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec .env\uc640 config.json\uc744 \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1\uc744 \ud55c\ub2e4. \\n\\n```bash\\ndocker run -it --env-file=.env -e \\"CONFIG=$(cat ./config.json | jq -r tostring)\\" algolia/docsearch-scraper\\n```\\n\\n### docusaurus \uc124\uc815\\n\\n\uc804\uc5d0 \ud655\uc778\ud55c APP ID, Search-Only API KEY, IndexName\uc744 \uc774\uc6a9\ud558\uc5ec docusaurus.config \ud30c\uc77c\uc5d0 \uc124\uc815\ud55c\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\nthemeConfig:\\n /** @type {import(\'@docusaurus/preset-classic\').ThemeConfig} */\\n ({\\n ...\\n algolia: {\\n appId: \'MVIU5UEMOM\', // Application ID\\n apiKey: \'b68f378013817d9a190df88cdde226a0\', // Search-Only API Key\\n indexName: \'teco\', // config.json\uc5d0 \uc124\uc815\ud55c \uc778\ub371\uc2a4\uba85\\n contextualSearch: true,\\n },\\n })\\n```\\n\\n## \ubd80\uac00 \uc124\uc815\\n\\n### \ud654\uba74 \uc0c1\ub2e8 Github Icon\\n\\n\ud30c\uc77c \ucd5c\ud558\ub2e8\uc5d0 \uc544\ub798 css \uad6c\ubb38\uc744 \ucd94\uac00\ud55c\ub2e4.\\n\\n```css title=\\"/src/css/custom.css\\"\\n.header-github-link:hover {\\n opacity: 0.6;\\n}\\n\\n.header-github-link:before {\\n content: \'\';\\n width: 24px;\\n height: 24px;\\n display: flex;\\n background: url(\\"data:image/svg+xml,%3Csvg viewBox=\'0 0 24 24\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cpath d=\'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\'/%3E%3C/svg%3E\\")\\n no-repeat;\\n}\\n\\nhtml[data-theme=\'dark\'] .header-github-link:before {\\n background: url(\\"data:image/svg+xml,%3Csvg viewBox=\'0 0 24 24\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cpath fill=\'white\' d=\'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\'/%3E%3C/svg%3E\\")\\n no-repeat;\\n}\\n```\\n\\nthemeconfig -> navbar\uc5d0 github link\ub97c \uc124\uc815\ud55c\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\nnavbar: {\\n title: \'HELLO\',\\n items: [\\n {\\n href: \'https://github.com/greeng00se\',\\n position: \'right\',\\n className: \'header-github-link\',\\n \'aria-label\': \'GitHub repository\',\\n },\\n ],\\n},\\n```\\n\\n### \ucf54\ub4dc\ube14\ub7ed\\n\\njava\ub098 kotlin\uc758 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ud558\uc774\ub77c\uc774\ud305\uc744 \uc9c0\uc6d0\ud574 \uc8fc\uc9c0 \uc54a\ub294\ub2e4. \\nprism \uc124\uc815\uc744 \uc544\ub798\uc640 \uac19\uc774 \ubcc0\uacbd\ud574 \uc900\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\nprism: {\\n theme: lightCodeTheme,\\n darkTheme: darkCodeTheme,\\n additionalLanguages: [\'java\', \'kotlin\'],\\n}\\n```\\n\\n### mermaid\\n\\nmermaid\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 `@docusaurus/theme-mermaid` \ub97c \uc124\uce58\ud574\uc57c \ud55c\ub2e4.\\n\\n```bash\\nyarn add @docusaurus/theme-mermaid\\n```\\n\\n\uc124\uce58 \ud6c4 \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\uc744 \ucd94\uac00\ud55c\ub2e4.\\n\\n```js title=\\"docusaurus.config\\"\\nconst config = {\\n ...\\n markdown: {\\n mermaid: true,\\n },\\n themes: [\\n \'@docusaurus/theme-mermaid\'\\n ],\\n};\\n```\\n\\nthemeConfig\uc5d0\uc11c mermaid\uc758 \ud14c\ub9c8\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\nthemeConfig:\\n /** @type {import(\'@docusaurus/preset-classic\').ThemeConfig} */\\n ({\\n ...\\n mermaid: {\\n theme: {\\n light: \'neutral\', \\n dark: \'dark\'\\n },\\n },\\n }),\\n```\\n\\n### \uad6d\uc81c\ud654 \uc124\uc815\\n\\n\uad6d\uc81c\ud654 \uc124\uc815\uc744 \ud55c\ub2e4\uba74 `Older Entries` \ud615\ud0dc\uc758 \uc124\uba85\uc774 `\ub2e4\uc74c \ud398\uc774\uc9c0` \ub85c \ubcc0\uacbd\ub41c\ub2e4. \\n\uc124\uc815\ud30c\uc77c\uc5d0\uc11c i18n\uc5d0 \uc788\ub294 \ub85c\ucf00\uc77c \uc124\uc815\uc744 ko\ub85c \ubcc0\uacbd\ud558\uba74 \ub41c\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\ni18n: {\\n defaultLocale: \\"ko\\",\\n locales: [\\"ko\\"],\\n},\\n```\\n\\n### \ube14\ub85c\uadf8 \uae00 author\\n\\n\ud300\uc6d0 \ubcc4\ub85c \ubb38\uc11c\ub97c \uad00\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 \uc5b4\ub5a4 \ud300\uc6d0\uc774 \uae00\uc744 \uc791\uc131\ud588\ub294\uc9c0 \uc124\uc815\ud574\uc57c \ud55c\ub2e4. \\n\\n![author](./author.png)\\n\\n`authors.yml` \ud30c\uc77c\uc744 \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790\uc5d0 \ub300\ud55c \uae30\ubcf8 \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\\n```yml title=\\"/blog/authors.yml\\"\\nherb:\\n name: \ud5c8\ube0c\\n title: Backend\\n url: https://github.com/greeng00se\\n image_url: https://github.com/greeng00se.png\\n\\nmallang:\\n name: \ub9d0\ub791\\n title: Backend\\n url: https://github.com/shin-mallang\\n image_url: https://github.com/shin-mallang.png\\n```\\n\\n\ube14\ub85c\uadf8 \uae00\uc744 \uc791\uc131\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc774 authors\uc5d0 \ub123\uc5b4\uc8fc\uae30\ub9cc \ud558\uba74 \ub41c\ub2e4. \\n\\n```mdx\\n---\\nslug: 1\\ntitle: Hello World\\nauthors: [herb, mallang]\\ntags: [hello, docusaurus]\\n---\\n\\n\uccab \ubc88\uc9f8 \ubb38\uc11c \ub0b4\uc6a9\\n```"},{"id":"woowacourse-level2-retrospective","metadata":{"permalink":"/woowacourse-level2-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx","title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0","description":"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.","date":"2023-06-11T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 11\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":2.545,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0","slug":"woowacourse-level2-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"Docusaurus","permalink":"/docusaurus"},"nextItem":{"title":"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0","permalink":"/level2-interview-retrospective"}},"content":"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4. \\n\ube60\ub974\uac8c \uc9c0\ub098\uac00\uc11c \uc870\uae08 \uc544\uc27d\ub2e4. \\n\\n### \ud559\uc2b5\\n\\n\ud68c\uace0\ub97c \uc791\uc131\ud558\uae30 \uc804\uc5d0 \ub808\ubca8 2 \ub3d9\uc548 \ubcf4\ub0c8\ub358 PR\uacfc \ud68c\uace0\ub97c \ucb49 \uc77d\uc5b4\ubd24\ub2e4. \\n\ud56d\uc0c1 \uc544\uc26c\uc6b4 \uacf3\uc740 \uc788\uae30 \ub9c8\ub828\uc774\uc9c0\ub9cc, \uc798 \ud559\uc2b5\ud55c \uac83 \uac19\ub2e4. \\n\ubbf8\uc158\uc744 \ud558\uba74\uc11c \uae30\uc220\uc744 \uc5b4\ub5bb\uac8c \uc120\ud0dd\ud558\uace0, \uc801\uc6a9\ud560 \uac83\uc778\uc9c0 \uace0\ubbfc\ud558\ub294 \uacfc\uc815\uc5d0\uc11c \uaf64\ub098 \ub9ce\uc740 \uc131\uc7a5\uc744 \ud55c \uac83 \uac19\ub2e4. \\n\\n\uace0\ubbfc\uc740 \uae4a\uc5c8\uc9c0\ub9cc \uc774\ub860\uc801\uc778 \ud559\uc2b5\uc774 \ubd80\uc871\ud55c \ub808\ubca8 2\uc600\ub2e4. \\n\ubc29\ud559 \uadf8\ub9ac\uace0 \ub808\ubca8 3 \ub54c\ub294 \uc870\uae08 \ub354 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc744 \ud559\uc2b5\ud558\ub294\ub370 \uc9d1\uc911\ud574\uc57c\uaca0\ub2e4. \\n\\n\uc810\ucc28 \ud559\uc2b5 \ubc94\uc704\uac00 \ub113\uc5b4\uc9c0\uba74\uc11c \uc790\uc5f0\uc2a4\ub7fd\uac8c \ubaa8\ub974\ub294 \ub0b4\uc6a9\uc774 \uc313\uc5ec\uac04\ub2e4. \\n\ud544\uc694\ud55c \ub0b4\uc6a9\uc740 \uc55e\uc73c\ub85c \ucc9c\ucc9c\ud788 \ud559\uc2b5\ud558\uba74 \ub418\ub2c8\uae4c \uc870\uae09\ud574\uc9c0\uc9c0 \ub9d0\uc544\uc57c\uaca0\ub2e4. \\n\\n### \uc218\uba74\\n\\n\ub808\ubca8 2\ub97c \uc9c4\ud589\ud558\ub294 \ub3d9\uc548 \uc218\uba74\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\uc5c8\uace0, \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \uadf8\ub0a0\uc758 \ucee8\ub514\uc158\uc744 \ub9ce\uc774 \uc88c\uc6b0\ud588\ub358 \uac83 \uac19\ub2e4. \\n\uc55e\uc73c\ub85c \uc218\uba74 \uc2dc\uac04\uc744 \ub298\ub9ac\uace0, \uc88b\uc740 \uc218\uba74 \uc2b5\uad00\uc744 \uac00\uc9c0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. \\n\\n### \ud611\uc5c5\\n\\n\ub808\ubca8 2 \ub9c8\uc9c0\ub9c9\uc5d0 \ud611\uc5c5 \ubbf8\uc158\uc774 \uc788\uc5c8\ub2e4. \\n\uc9c0\uae08\uae4c\uc9c0\ub294 \ubc31\uc5d4\ub4dc \ud06c\ub8e8\ub4e4\uacfc \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud558\uba74\uc11c \ud611\uc5c5\uc744 \uacbd\ud5d8\ud588\ub2e4. \\n\uc774\ubc88\uc5d0\ub294 \ud504\ub7f0\ud2b8\uc5d4\ub4dc \ud06c\ub8e8\uc640 \ud611\uc5c5\uc744 \ud588\ub2e4. \uc18c\ud1b5\uc740 \uc798 \ub41c \uac83 \uac19\uc9c0\ub9cc API \uba85\uc138\ub97c \uc815\ud558\ub294 \ubd80\ubd84\uc774 \uc544\uc9c1 \ubbf8\uc219\ud55c \uac83 \uac19\ub2e4. \\n\\n\ub808\ubca8 3 \ub54c\ubd80\ud130 \ubcf8\uaca9\uc801\uc73c\ub85c \ud504\ub85c\uc81d\ud2b8\uac00 \uc2dc\uc791\ub41c\ub2e4. \\n\ud300\uc744 \uc704\ud574 \uc5b4\ub5a4 \uac83\uc744 \ud560 \uc218 \uc788\uc744\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud574\ubd10\uc57c\uaca0\ub2e4. \\n\\n### \ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70\\n\\n\ud68c\uace0 \uc791\uc131\ud558\uba74\uc11c \ub808\ubca8 2\uc5d0\uc11c \ud588\ub358 \uac83\ub4e4\uc744 \ubc18\ucd94\ud574 \ubd24\ub294\ub370 \ubd80\uc871\ud55c \uc810\uc740 \ub9ce\uc558\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \uac00\uace0 \uc788\ub294 \uac83 \uac19\ub2e4.\\n\uc77d\uace0 \uc2f6\uc740 \ucc45\ub3c4 \uc77d\uace0, \ubd80\uc871\ud55c \ubd80\ubd84 \ucc44\uc6b0\uba74\uc11c \uc26c\uc5b4\uc57c\uaca0\ub2e4."},{"id":"level2-interview-retrospective","metadata":{"permalink":"/level2-interview-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx","title":"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0","description":"\ub808\ubca8 \uc778\ud130\ubdf0","date":"2023-06-08T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 8\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.435,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0","slug":"level2-interview-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0","permalink":"/woowacourse-level2-retrospective"},"nextItem":{"title":"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0","permalink":"/order-retrospective"}},"content":"### \ub808\ubca8 \uc778\ud130\ubdf0\\n\\n\ub808\ubca8 1 \ub54c\ub294 \uc900\ube44\ud574\ub454 \ub0b4\uc6a9\uc73c\ub85c \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud574\uc11c \uadf8\ub807\uac8c \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc774 \uc5c6\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c \ub808\ubca8 1 \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0\ub294 \ub808\ubca8 1 \ud68c\uace0\ub97c \uc791\uc131\ud560 \ub54c \ub07c\uc6cc\ub123\uc5c8\ub2e4. \\n\uc774\ubc88\uc5d0\ub294 \ubc94\uc704\ub3c4 \uc81c\ud55c\ub418\uc5b4 \uc788\uc5b4 \uc5b4\ub5bb\uac8c \uc900\ube44\ud574\uc57c \ud560\uc9c0 \ub2f9\ud669\ud588\uace0, \ub2f5\ubcc0\uc5d0\ub3c4 \ubd80\uc871\ud55c \ubd80\ubd84\uc774 \ub9ce\uc558\uc5c8\ub2e4. \\n\uae30\uc5b5\uc774 \uc0ac\ub77c\uc9c0\uae30 \uc804\uc5d0 \ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\ud55c \ub0b4\uc6a9\uc744 \uc81c\uc678\ud558\uace0, \uae30\uc5b5 \ub0a8\ub294 \uac83 \uc704\uc8fc\ub85c \uc791\uc131\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4. \\n\\n### API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd\\n\\n\ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\uc744 \ud588\ub294\ub370 \uc55e\uc73c\ub85c\ub3c4 \ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \ud558\uba74\uc11c \ub3c4\uc6c0 \ub420 \uac83 \uac19\uc740 \ub0b4\uc6a9\uc774 \uc788\uc5b4\uc11c \ub0a8\uaca8\ub450\ub824\uace0 \ud55c\ub2e4. \\n\ubc31\uc5d4\ub4dc \ud300\uc6d0\uc774 \ud568\uaed8 \uc758\uc0ac\uacb0\uc815\uc744 \ud588\uace0, \ubbf8\uc158 \uae30\uac04\uc774 \uc9e7\uc740 \ub9cc\ud07c \ud300 \ucc28\uc6d0\uc5d0\uc11c \ube44\uad50\uc801 \ud559\uc2b5\ud558\uae30 \uc26c\uc6b4 Swagger\ub97c \uc120\ud0dd\ud588\ub2e4. \\n\ucd94\uac00\ub85c \ub4e4\uc5b4\uac00\ub294 \uc2dc\uac04 \ub300\ube44 \ud558\uc774 \ub9ac\ud134\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4\uace0 \ub2f5\ubcc0\ud588\ub2e4.\\n\\n\ud300 \ucc28\uc6d0\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uc5b8\uae09\ud574\uc11c, \ub2e4\uc74c\uacfc \uac19\uc740 \uc88b\uc740 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4.\\n\\n> \ud2b9\ud788 \ud300\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\ud558\ub294 \uacfc\uc815\uc744 \uacf5\uc720\ud574 \uc900 \uc810\uc774 \uc88b\uc558\uace0 \uae30\uc220\uc801 \uc758\uc0ac\uacb0\uc815 \uacfc\uc815\uc5d0\uc11c \ud300\uc758 \ud559\uc2b5\ube44\uc6a9\uc744 \uace0\ub824\ud55c \uc810\uc774 \uc88b\uc558\uc74c. \\n> \uc55e\uc73c\ub85c\ub3c4 \ud559\uc2b5 \ube44\uc6a9\uc740 \uc8fc\uc694\ud558\uac8c \uace0\ub824\ud574\uc57c \ud560 \uc0ac\ud56d\\n>\\n\\n### PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158\\n\\nPUT\uacfc PATCH \ucc28\uc774\ub97c \uc124\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c\ub294 PATCH\ub97c \uc0ac\uc6a9\ud560 \ub54c \ud398\uc774\ub85c\ub4dc\uac00 \uc801\uc5b4\uc9c4\ub2e4\ub294 \ub0b4\uc6a9\uc744 \ube7c\uba39\uace0 \ub2f5\ubcc0\uc744 \ud588\ub2e4. \\n\ud1a0\ud070\uacfc \uc138\uc158\uc758 \uacbd\uc6b0 \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud574\ub2ec\ub77c\ub294 \uc81c\uc57d\uc870\uac74\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\\n\ud574\ub2f9 \ub0b4\uc6a9\uc744 \ub2f5\ubcc0\ud558\uba74\uc11c \uae30\uc220\uc801\uc778 \uae4a\uc774\uac00 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4. \\n\uc2e4\uc81c\ub85c \ub808\ubca8 2 \ub54c \uc774\ub860\uc801\uc778 \ud559\uc2b5 \uc2dc\uac04\uc774 \ub9e4\uc6b0 \uc801\uc5c8\uace0, \uc9d1\uc911\ub825\ub3c4 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4. \\n\uc55e\uc73c\ub85c \uc5b4\ub5bb\uac8c \uae4a\uc774\ub97c \ucc44\uc6b8\uc9c0 \uace0\ubbfc\uc744 \ud560 \uc218 \uc788\ub294 \uc9c8\ubb38\ub4e4\uc774\uc5c8\ub2e4. \\n\\n\ucd94\uac00\ub85c \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud558\ub294 \uac00\uc815\uc744 \ub450\uace0 \ud559\uc2b5\uc744 \ud55c\ub2e4\uba74 \ud070 \ub3c4\uc6c0\uc774 \ub420 \uac70\ub77c\ub294 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4. \\n\\n### \uadf8 \uc678 \uac1c\uc120\ud560 \uc810\\n\\n\uc778\ud130\ubdf0\ud560 \ub54c \ud2b9\uc720\uc758 \ub9d0\ubc84\ub987\uc744 \uac1c\uc120\ud558\uae30 \\n\uc0dd\uac01\ud560 \uc2dc\uac04\uc744 \uac00\uc84c\uc744 \ub54c \\"\ub2e4\uc2dc \ub9d0\uc500\ub4dc\ub824\ub3c4 \ub420\uae4c\uc694?\\"\ub77c\uace0 \ub9d0\ud558\uace0 \ub2f5\ubcc0\uc744 \uc774\uc5b4\ub098\uac00\uae30 \\n\uae30\uc220\uc801\uc73c\ub85c \uae4a\uc774\uac00 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5b4\uc11c \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\uae30 \\n\uc774\uc804\uc5d0 \uacf5\ubd80\ud588\ub358\uac70 \ub418\ub3cc\uc544 \ubcf4\ub294 \uc2dc\uac04 \uac00\uc9c0\uae30"},{"id":"order-retrospective","metadata":{"permalink":"/order-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4: AWS \ubc30\ud3ec","date":"2023-06-04T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 4\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":4.67,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0","slug":"order-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0","permalink":"/level2-interview-retrospective"},"nextItem":{"title":"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604","permalink":"/tecochat-retrospective-3"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: AWS \ubc30\ud3ec \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-shopping-order/pull/7 \\n:::\\n\\n### \uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158\\n\\n\ubc30\ud3ec \ubc0f \ud611\uc5c5\uc744 \ud560 \uc218 \uc788\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\ub9c8\ucf54, \uc6b0\uac00, \uc6b0\ucf54, \uc6b0\uc2a4 \uadf8\ub9ac\uace0 \ub098\uae4c\uc9c0 \ud569\uccd0\uc11c 5\uba85\uc774 \ud55c \ud300\uc774 \ub418\uc5c8\ub2e4. \\n\\n### \ubc30\ud3ec\\n\\n\uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac AWS\ub97c \uc774\uc6a9\ud574 \ubc30\ud3ec\ub97c \ud574\uc57c \ud588\ub2e4. \\n\uac01\uc790 \ud558\ub098\uc758 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc744 \uc218 \uc788\uc5c8\uace0, \ud300 \ubcc4\ub85c DB\ub97c \uc704\ud55c \ucd94\uac00 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc558\ub2e4. \\n\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc791\uc131\ud558\ub294 \uacbd\ud5d8\uc744 \ud574\ubcfc \uc218 \uc788\uc5c8\ub2e4. \\n\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc2dc\uac04\uc744 \ub9ce\uc774 \ud22c\uc790\ud558\uc9c4 \uc54a\uc558\uace0, \ub2e4\uc74c\uacfc \uac19\uc774 \uac04\ub2e8\ud558\uac8c \uc791\uc131\ud588\ub2e4.\\n\\n```bash\\necho \\"Start Deploy Script\\"\\nREPOSITORY_NAME=/home/ubuntu/jwp-shopping-order\\nPROJECT_NAME=jwp-shopping-order\\n\\necho \\"Change Directory\\"\\ncd $REPOSITORY_NAME\\n\\necho \\"Git Pull\\"\\ngit pull origin step2\\n\\necho \\"Build\\"\\n./gradlew bootJar\\n\\necho \\"Copy, Start Server\\"\\nmv ./build/libs/$PROJECT_NAME.jar .\\n\\nPID=$(pgrep -f $PROJECT_NAME)\\n\\nif [ -n $PID ]; then\\n kill -9 $PID\\n\\tsleep 5\\nfi\\n\\nnohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &\\n```\\n\\n### \ud611\uc5c5\\n\\n\uc77c\ub2e8 \uc6b0\uc2a4\ub791 \uc6b0\ucf54\uac00 \uba3c\uc800 \uc7a0\uc2e4\ub85c \uc640\uc918\uc11c \ub108\ubb34 \uac10\uc0ac\ud588\ub2e4. \\n\ubc31\uc5d4\ub4dc\uac00 \uc544\ub2cc \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \ud574\ubcf4\ub294 \uccab \ud611\uc5c5\uc774\ub77c \uc57d\uac04 \ub450\uadfc\uac70\ub838\ub2e4. \\n\uc608\uc0c1\uc678\ub85c \ub300\ud654\uac00 \uc798 \ub418\uc5b4\uc11c, \ube60\ub974\uac8c \uba85\uc138\ub97c \uc815\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n**\uc5ec\ub7ec\uac00\uc9c0 \ubc29\ubc95\uc5d0 \ub300\ud55c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud574\ubcf4\uae30**\\n\\n\ubc31\uc5d4\ub4dc\uc640 \ud14c\uc774\ube14 \uba85\uc138\ub098 \ucfe0\ud3f0 \uad6c\ud604\uc5d0 \ub300\ud574\uc11c \uc774\uc57c\uae30\ud560 \ub54c \uc7a5\ub2e8\uc5d0 \ub300\ud574 \ub9ce\uc774 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4. \\n\uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub9ce\uc774 \ub4e4\uc5ec\uc11c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud588\ub2e4\uba74 \ub354 \uc88b\uc740 \uacb0\uacfc\ubb3c\uc774 \ub098\uc624\uc9c0 \uc54a\uc558\uc744\uae4c? \\n\uc55e\uc73c\ub85c \uc120\ud0dd\uc758 \uc21c\uac04\uc5d0\uc11c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub4e4\uc5ec\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4. \\n\\n### \uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84\\n\\n**expose headers**\\n\\n\uc6f9 \ud398\uc774\uc9c0\uc5d0\uc11c Location \ud5e4\ub354\ub97c \ubc1b\uc744 \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \uc788\uc5c8\ub2e4. \\n\uae30\ubcf8\uc801\uc73c\ub85c [\ud5c8\uc6a9 \ubaa9\ub85d\uc5d0 \uc874\uc7ac\ud558\ub294 \uc751\ub2f5\ud5e4\ub354](https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header)\ub9cc \ubc18\ud658\ud55c\ub2e4\ub294 \uac83\uc744 \ubaa8\ub974\uace0 \uc788\uc5c8\ub2e4. \\n\uc774\ub97c expose headers \uc124\uc815\uc744 \ud1b5\ud574 \ud574\uacb0\ud560 \uc218 \uc788\uc5c8\ub2e4. \\nnginx \uc124\uc815\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \ucd94\uac00\ud574 \uc8fc\uc5c8\ub2e4. \\n\\n```bash\\nadd_header \'Access-Control-Expose-Headers\' \'Location\'\\n```\\n\\n**\uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158** \\n\\n\ub2e8\uc21c \uc870\ud68c \uc694\uccad\uc5d0 \ub300\ud55c \uc131\ub2a5\uc744 \ud5a5\uc0c1\uc2dc\ucf1c\uc900\ub2e4\ub294 \uac83\uc774\ub77c\uace0 \uac04\ub2e8\ud788\ub9cc \uc54c\uace0 \uc788\uc5c8\ub2e4. \\n\uc774\ubc88\uc5d0 \ucf54\uba58\ud2b8\uac00 \ub2ec\ub824\uc11c \uc870\uae08 \ub354 \uc790\uc138\ud788 \uacf5\ubd80\ud574 \ubcf4\uae30\ub85c \ud588\ub2e4. \\nTransactional(readOnly = true)\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc774 \ub3d9\uc791\ud55c\ub2e4.\\n\\nsetReadOnly(true) \uc124\uc815\uc774 \ub41c Connection\uc73c\ub85c \uc5f0\uacb0\uc744 \uc2dc\ub3c4\ub97c \ud55c\ub2e4. \uc774 \uc124\uc815\uc744 \ud558\ub294 \uacbd\uc6b0 DB\ub9c8\ub2e4 \ub2e4\ub974\uac8c \ub3d9\uc791\ud55c\ub2e4.\\n- h2\uc758 Connection \uad6c\ud604\uccb4\ub294 readOnly \uc124\uc815\uc744 \ubb34\uc2dc\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 Transactional \uc801\uc6a9\ub418\uc9c0 \uc54a\ub294\ub2e4. \\n- MySQL 8.0(InnoDB \uc0ac\uc6a9 \uc2dc)\uc758 \uacbd\uc6b0 \uc77d\uae30 \uc804\uc6a9\uc73c\ub85c \uc54c\ub824\uc9c4 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158 ID\ub97c \uc124\uc815\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uc870\ud68c \uc18d\ub3c4\uac00 \ub354 \ube68\ub77c\uc9c4\ub2e4.\\n\\nORM \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 prepareTransactionalConnection\ub97c \ud638\ucd9c\ud55c\ub2e4\uace0 \ud55c\ub2e4. \\n\ucd94\uac00\ub85c \ud604\uc5c5\uc5d0\uc11c\ub294 \uace0\uac00\uc6a9\uc131 \ub0b4\uacb0\ud568\uc131 \ub4f1\uc744 \uc704\ud558\uc5ec \ud074\ub7ec\uc2a4\ud130\ub97c \uad6c\uc131\ud558\uc5ec \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uace0, \uc774 \uacbd\uc6b0 readOnly \uc124\uc815\uc774 \ub418\uc5b4\uc788\ub2e4\uba74 \uc77d\uae30 \uc804\uc6a9 DB\ub85c \uc9c8\uc758\uac00 \ub4e4\uc5b4\uac00\uc11c \ubd80\ud558 \ubd84\uc0b0\uc758 \ud6a8\uacfc\uac00 \uc788\ub2e4\uace0 \ud55c\ub2e4. \\n\\n**DAO\uc5d0 `@Transactional` \uc801\uc6a9** \\n\\nDAO\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \ubcf4\ub294 \uac74 \uc5b4\ub5bb\uaca0\ub0d0\uace0 \ub9ac\ubdf0\uac00 \ub2ec\ub824\uc11c \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4. \\nService \uacc4\uce35\uc5d0 \uc774\ubbf8 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \uc8fc\uace0 \uc788\uae30\uc5d0 \ud544\uc694 \uc5c6\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4. \\nDAO\ub97c \ub2e4\ub978 \uacf3\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574(\ud655\uc7a5\uc131 \uace0\ub824) `@Transactional`\uc744 \uc801\uc6a9\ud558\ub294 \uac83\ub3c4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4."},{"id":"tecochat-retrospective-3","metadata":{"permalink":"/tecochat-retrospective-3","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx","source":"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx","title":"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604","description":"\uac1c\uc694","date":"2023-06-01T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 1\uc77c","tags":[{"label":"TecoChat","permalink":"/tags/teco-chat"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":4.005,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604","slug":"tecochat-retrospective-3","tags":["TecoChat","Retrospective"]},"prevItem":{"title":"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0","permalink":"/order-retrospective"},"nextItem":{"title":"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30","permalink":"/composite"}},"content":"### \uac1c\uc694\\n\\n\uc6d0\ub798 \ubaa9\uc801\uc778 `\ud06c\ub8e8\ub4e4\uc758 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0`\uc744 \uc8fc\uae30 \uc704\ud574 \uc5b4\ub5a4 \uae30\ub2a5\uc744 \ucd94\uac00\ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4. \\n\ub808\ubca8 2\uac00 \uac70\uc758 \ub05d\ub098\uac00\ub294 \uc2dc\uc810, \uadf8\ub3d9\uc548 \ud588\ub358 \uac83\uc744 \uc815\ub9ac\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4. \\n\\n### \ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5\\n\\nGPT\uc5d0\ub3c4 \uc788\ub294 \uae30\ub2a5\uc778\ub370, \ub0b4\uac00 \uc774\uc804\uc5d0 \ud588\ub358 \ucc44\ud305\uc744 \uc774\uc5b4\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4. \\n\uc608\uc804\uc5d0 \uc5b4\ub5a4 \uc9c8\ubb38\uc744 \ub0a8\uacbc\ub294\uc9c0, \ub610\ud55c \ud574\ub2f9 \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub2e4. \\n\\n![chat1](./chat1.png)\\n\\n### \uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5\\n\\n\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc5d0 \ubc18\uc751\ud560 \uc218 \uc788\ub294 \ubb34\uc5b8\uac00\uac00 \uc788\uc5c8\uc73c\uba74 \uc88b\uaca0\ub2e4\ub294 \uc758\uacac\ub4e4\uc774 \ub9ce\uc558\ub2e4. \\n\ub204\uac00 \uc88b\uc544\uc694\ub97c \ub20c\ub800\ub294\uc9c0, \uc5b4\ub5a4 \ucc44\ud305\uc774 \uc88b\uc544\uc694\ub97c \uac00\uc7a5 \ub9ce\uc774 \ubc1b\uc558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4. \\n\ub610\ud55c \ub313\uae00 \ucd94\uac00 \ubc0f \uc0ad\uc81c \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4.\\n\\n### \ud0a4\uc6cc\ub4dc \ucd94\ucd9c\\n\\n\uc5b4\ub5bb\uac8c \ud0a4\uc6cc\ub4dc \ucd94\ucd9c\uc744 \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub294\ub370, \uc77c\ub2e8 GPT\ub97c \uc774\uc6a9\ud574\uc11c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\uae30\ub85c \ud588\ub2e4. \\n\ud574\ub2f9 \ubd80\ubd84\uc740 \uccab \uc9c8\ubb38\uc5d0 \ub300\ud55c \ud0a4\uc6cc\ub4dc\ub9cc \ucd94\ucd9c\ud558\ub3c4\ub85d \ud588\ub2e4. \\n\ubc31\uc5d4\ub4dc\uc5d0\uc120 \ub9d0\ub791\uc774 \uc774\ubca4\ud2b8 \uc774\uc6a9\ud574\uc11c \uccab \ucc44\ud305 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c0\uba74, \ube44\ub3d9\uae30\ub85c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\ub294 \uc9c8\ubb38\uc744 \ucd94\uac00\ub85c \ub0a0\ub9ac\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4. \\nCSV \ud615\uc2dd\uc73c\ub85c GPT\uc5d0\uac8c \ub2f5\ubcc0\uc744 \uc785\ub825\ud574\ub2ec\ub77c\uace0 \uc694\uccad\ubc1b\ub294\ub370, \uc774 \ubd80\ubd84\uc774 \ubb38\uc81c(\ud504\ub86c\ud504\ud2b8 \uc5d4\uc9c0\ub2c8\uc5b4\ub9c1 \ubd80\ubd84\uc774 \ubc18\ud658\ub41c\ub2e4.)\uac00 \uc880 \uc788\ub294 \uac83 \uac19\uc544\uc11c \uac1c\uc120\uc774 \ud544\uc694\ud55c \uac83 \uac19\ub2e4. \\n\\n![chat2](./chat2.png)\\n\\n### \ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5\\n\\n\ub2e4\ub978 \ud06c\ub8e8\ub4e4\uc758 \ucc44\ud305\uc744 \uc77d\ub2e4\uac00 \uad81\uae08\ud55c \uc810\uc774 \uc788\ub2e4\uba74 \ubcf5\uc0ac\ud574\uc11c \ubc14\ub85c \uc9c8\ubb38\uc744 \ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4. \\n\ucc44\ud305\uc774 \ubcf5\uc0ac\ub41c \ud6c4 \ubc14\ub85c GPT\uc640 \ub300\ud654\ub97c \ud560 \uc218 \uc788\ub294 \uba54\uc778 \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud55c\ub2e4. \\n\\n### \uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30\\n\\n![chat3](./chat3.png)\\n\\n\uc704 \ud654\uba74\uc740 \ud68c\uc6d0\uac00\uc785 \ucc3d\uc774\ub2e4. \\n\uc0ac\uc2e4 \uac00\uc7a5 \ub9c8\uc74c\uc5d0 \ub4dc\ub294 \ubd80\ubd84\uc774\uace0, \ud68c\uc6d0\uac00\uc785(\ub2c9\ub124\uc784\ub9cc \uc785\ub825\ud558\uc9c0\ub9cc)\ud560 \ub54c \uc775\uba85\uc744 \uc6d0\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uace0\ubbfc\uc744 \ub3c4\uc640\uc8fc\uac8c \ub054 \uc74c\uc2dd, \uacfc\uc77c, \uacfc\uc790 \ub4f1\uc758 \uc694\uc18c\ub4e4\uc744 \uc785\ub825\ud558\ub3c4\ub85d \uc720\ub3c4\ud588\ub2e4!\\n\ucd94\uac00\ub85c GPT\uc758 \ub2f5\ubcc0\uc774 \uc624\uba74 \uc790\ub3d9\uc73c\ub85c \ud654\uba74\uc744 \uc2a4\ud06c\ub864 \ud574\uc8fc\ub294 \uac83\uacfc \uac19\uc774 \uc0ac\uc6a9\uc131\uc744 \uac1c\uc120\ud574 \ubcf4\ub824\uace0 \ub178\ub825\ud588\uc9c0\ub9cc \uc27d\uc9c0 \uc54a\uc558\ub2e4. \\n\uc81c\uc77c \ud558\uace0 \uc2f6\uc740 \uac83\uc740 \uc2e4\uc81c GPT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ucc98\ub7fc stream/text \uac12\uc744 \ucc98\ub9ac\ud558\uace0 \uc2f6\uc740\ub370 \uc774 \ubd80\ubd84\uc740 \ubc29\ud559 \ub54c \uae30\ud68c\uac00 \ub418\uba74 \ub3c4\uc804\ud574 \ubd10\uc57c\uaca0\ub2e4. \\n\\n### \ud5a5\ud6c4 \uacc4\ud68d\\n\\n\uc2e4\uc81c \ud06c\ub8e8\ub4e4\uc774 \uc0ac\uc6a9\ud574 \uc8fc\ub294 \uc11c\ube44\uc2a4\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\ubcf4\uba74\uc11c \uc0ac\uc6a9\uc790\uc758 \uc785\uc7a5\uc5d0\uc11c \uace0\ubbfc\ub3c4 \ud558\uac8c \ub418\ub294 \uac83 \uac19\ub2e4. \\n\ud06c\ub8e8\ub4e4\uc774 \uc9c1\uc811 \uc0ac\uc6a9\ud574 \uc8fc\ub2c8\uae4c \ub108\ubb34 \uace0\ub9d9\uace0, \ud55c\ud3b8\uc73c\ub85c\ub294 \uc2e0\uae30\ud558\ub2e4. \\n\uc77c\ub2e8 \ubc29\ud559 \ub54c stream/text \uad00\ub828\ub41c \ubd80\ubd84 \ub3d9\uc791\ub418\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\ub824\uace0 \ud558\uace0, \uadf8 \uc678\uc758 \ubd80\ubd84\uc740 \uc870\uae08 \ub354 \uace0\ubbfc\ud574\uc57c\ub420 \uac83 \uac19\ub2e4."},{"id":"composite","metadata":{"permalink":"/composite","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx","source":"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx","title":"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30","description":"\uc694\uad6c\uc0ac\ud56d","date":"2023-05-26T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 26\uc77c","tags":[{"label":"Pattern","permalink":"/tags/pattern"},{"label":"Composite","permalink":"/tags/composite"}],"readingTime":4.74,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30","slug":"composite","tags":["Pattern","Composite"]},"prevItem":{"title":"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604","permalink":"/tecochat-retrospective-3"},"nextItem":{"title":"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0","permalink":"/subway-retrospective"}},"content":"### \uc694\uad6c\uc0ac\ud56d\\n\\n\uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.\\n\\n- \uac70\ub9ac\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45\\n- \ub178\uc120\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45\\n- \uc5f0\ub839\ubcc4 \uc694\uae08 \ud560\uc778 \uc815\ucc45\\n\\n### \uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9\\n\\n\uc694\uae08 \uc815\ucc45\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc778\ud130\ud398\uc774\uc2a4\ub85c \ud45c\ud604\ud560 \uc218 \uc788\ub2e4. \\n\uc694\uae08\uc744 \uacc4\uc0b0\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ucd5c\ub2e8 \uacbd\ub85c \uacc4\uc0b0\uc758 \uacb0\uacfc, \uc0ac\uc6a9\uc790\uc758 \uc815\ubcf4, \uc694\uae08\uc744 \ubc1b\uc544 \uc694\uae08\uc744 \uacc4\uc0b0\ud55c\ub2e4.\\n\\n```java\\npublic interface FarePolicy {\\n int calculate(Path path, Passenger passenger, int fare);\\n}\\n\\npublic class BaseFarePolicy implements FarePolicy { ... }\\npublic class DistanceFarePolicy implements FarePolicy { ... }\\npublic class AgeDiscountFarePolicy implements FarePolicy { ... }\\n```\\n\\n![composite1](./composite1.png)\\n\\n### \ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30\\n\\n\ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub97c \ubaa8\ub450 \uac00\uc9c0\uace0 \uc788\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\ub97c \ub9cc\ub4e4\uc5c8\ub2e4. \\n\uc774 \ub610\ud55c FarePolicy\ub97c \uad6c\ud604\ud55c \ud615\ud0dc\uac00 \ub418\uace0, \ud544\ub4dc\ub85c\ub294 \ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub4e4\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4.\\n\\n```java\\npublic class SubwayFarePolicy implements FarePolicy {\\n\\n private final List<FarePolicy> farePolicies;\\n\\n public SubwayFarePolicy(final List<FarePolicy> farePolicies) {\\n this.farePolicies = farePolicies;\\n }\\n\\n @Override\\n public int calculate(final Path path, final Passenger passenger, final int fare) {\\n int calculatedFare = fare;\\n for (FarePolicy farePolicy : farePolicies) {\\n calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);\\n }\\n return calculatedFare;\\n }\\n}\\n```\\n\\n\ub530\ub77c\uc11c \uadf8\ub9bc\uc73c\ub85c \ubcf8\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4.\\n\\n![composite2](./composite2.png)\\n\\n### \uc815\ucc45\uc758 \uc21c\uc11c\\n\\n\uc9c0\ud558\ucca0 \uc694\uad6c\uc0ac\ud56d\uc740 \uc21c\uc11c\uac00 \uc911\uc694\ud588\ub2e4. \\n\uae08\uc561\uc758 \ucd1d\ud569\uc744 \uad6c\ud558\uace0, \uadf8 \ud6c4\uc5d0 \ud560\uc778 \uc815\ucc45\uc774 \ub4e4\uc5b4\uac00\uc57c\ud588\ub2e4. \\n\ub530\ub77c\uc11c \uc790\uc2dd\ub4e4\uc758 \uc21c\uc11c\ub97c \uad00\ub9ac\ud560 \ub54c \uc8fc\uc758\ub97c \uae30\uc6b8\uc5ec\uc57c \ud588\ub2e4. \\nConfiguration \ud074\ub798\uc2a4\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \uc21c\uc11c\ub97c \uc9c1\uc811 \uc801\uc6a9\uc2dc\ucf30\ub2e4. \\n\\n```java\\n@Configuration\\npublic class FareConfiguration {\\n\\n @Bean\\n public FarePolicy farePolicy() {\\n return new SubwayFarePolicy(List.of(\\n new BaseFarePolicy(),\\n new DistanceFarePolicy(),\\n new AgeDiscountFarePolicy()\\n ));\\n }\\n}\\n```\\n\\n### \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?\\n\\n![composite3](./composite3.png)\\n\\nGOF\uc758 \ub514\uc790\uc778 \ud328\ud134 \ucc45\uc5d0\uc11c\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uba85\ud558\uace0 \uc788\ub2e4.\\n\\n> \ubd80\ubd84\uacfc \uc804\uccb4\uc758 \uacc4\uce35\uc744 \ud45c\ud604\ud558\uae30 \uc704\ud574 \uac1d\uccb4\ub4e4\uc744 \ubaa8\uc544 \ud2b8\ub9ac \uad6c\uc870\ub85c \uad6c\uc131\ud569\ub2c8\ub2e4. \\n\uc0ac\uc6a9\uc790\ub85c \ud558\uc5ec\uae08 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ubcf5\ud569 \uac1d\uccb4\ub97c \ubaa8\ub450 \ub3d9\uc77c\ud558\uac8c \ub2e4\ub8f0 \uc218 \uc788\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc785\ub2c8\ub2e4.\\n> \\n\\n\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4. \\n\uc774 \ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n### \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c\\n\\nComponent\\n\\n- \uc9d1\ud569 \uad00\uacc4\uc5d0 \uc815\uc758\ub420 \ubaa8\ub4e0 \uac1d\uccb4\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4 \\n- ex) \uc694\uae08 \uc815\ucc45(FarePolicy) \\n\\nLeaf\\n\\n- \uac1c\ubcc4 \uac1d\uccb4, \uac1d\uccb4 \ud569\uc131\uc5d0 \uae30\ubcf8\uc774 \ub418\ub294 \uac1d\uccb4\uc758 \ud589\ub3d9 \\n- ex) \uac70\ub9ac \ubcc4 \uc694\uae08 \uc815\ucc45(DistanceFarePolicy) \\n\\nComposite\\n\\n- \uc5ec\ub7ec \uac1c\uc758 \uac1c\ubc1c \uac1d\uccb4\ub97c \ud3ec\ud568\ud558\ub294 \ud569\uc131 \uac1d\uccb4 \\n- ex) \uc9c0\ud558\ucca0 \uc694\uae08 \uc815\ucc45(SubwayFarePolicy) \\n\\nClient\\n\\n- \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8\\n\\n### \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c\\n\\n\ubd80\ubd84 - \uc804\uccb4\uc758 \uad00\uacc4\ub97c \ud45c\ud604\ud558\uace0 \uc2f6\uc744 \ub54c \\nClient \uae30\uc900\uc73c\ub85c Composite\uc640 Leaf\uc758 \ucc28\uc774\ub97c \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc798 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc57c\ub420 \ub54c\\n\\n### \ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84\\n\\n\ud328\ud134\uc740 \uacf5\ud1b5\uc73c\ub85c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc758 \ud15c\ud50c\ub9bf\uc774\ub2e4. \\n\ubc18\ubcf5\ub418\ub294 \ubb38\uc81c\ub97c \ud6a8\uc728\uc801\uc73c\ub85c \ud574\uacb0\ud560 \uc218 \uc788\uc9c0\ub9cc \ud328\ud134\uc5d0 \ub9e4\ubab0\ub418\uc11c\ub294 \uc548\ub41c\ub2e4. \\n\ud328\ud134\uc744 \ub9f9\ubaa9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud574\uc11c\ub294 \uc548\ub418\uace0, \ud604\uc7ac\uc758 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ub530\ub77c \ud328\ud134\uc744 \uc720\ub3d9\uc801\uc73c\ub85c \uc218\uc815\ud574\uac00\uba74\uc11c \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\ud56d\uc0c1 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uc0dd\uac01\ud558\uc790!\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134, GoF\uc758 \ub514\uc790\uc778 \ud328\ud134 \\n\ub514\uc790\uc778 \ud328\ud134\uacfc \ud504\ub808\uc784\uc6cc\ud06c, \uc624\ube0c\uc81d\ud2b8"},{"id":"subway-retrospective","metadata":{"permalink":"/subway-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-subway-path/pull/16","date":"2023-05-25T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 25\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":7.98,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0","slug":"subway-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30","permalink":"/composite"},"nextItem":{"title":"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5","permalink":"/accidental-duplication"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-subway-path/pull/16 \\n2, 3\ub2e8\uacc4: https://github.com/woowacourse/jwp-subway-path/pull/126 \\n:::\\n\\n### \uc9c0\ud558\ucca0 \ubbf8\uc158\\n\\n\uc810\uc810 \uc77c\uc815\uc774 \ub9ce\uc544\uc9c0\ub294 \ub290\ub08c\uc774 \ub4e4\uba74\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc9c4\ub2e4. \\n\uc9c0\ud558\ucca0 \ubbf8\uc158\uc740 \ubc00\ub9ac\ub791 \ud398\uc5b4\ub97c \uc9c4\ud589\ud588\ub2e4. \\n\uac04\ub2e8\ud55c CRUD\ub9cc \uc788\ub358 \uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac, \uc870\uae08 \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. \\n\uc774\ub54c API, \ud14c\uc774\ube14, \ub3c4\uba54\uc778 \uc124\uacc4\ub97c \ud574\uc57c \ud588\ub294\ub370 \uc5b4\ub5a4 \uac83\ubd80\ud130 \ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4. \\nAPI\uc640 \ud14c\uc774\ube14 \uad6c\uc870\ub97c \uc6b0\ub9ac\uac00 \uc815\ud560 \uc218 \uc788\ub294 \uc0c1\ud669\uc774\uc5c8\uace0, \ub3c4\uba54\uc778 \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \ub3c4\uba54\uc778\uc744 \uba3c\uc800 \uad6c\ud604\ud588\ub2e4.\\n\\n**\ub178\uc120\uc758 \uad6c\uac04 \ucd94\uac00 \ubc0f \uc0ad\uc81c**\\n\\n\ub178\uc120\uc744 \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574\uc11c \ubc00\ub9ac\uc640 \uc774\uc57c\uae30\ub97c \ub098\ub234\ub2e4.\\n\\n1. \uad6c\uac04\uc744 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uc804\ubd80 \uc81c\uac70\ud558\uace0 \uc804\ubd80 \ucd94\uac00\ud558\ub294 \ubc29\ubc95\\n2. \ubcc0\uacbd\ub41c \uc694\uc18c\ub9cc \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ubc18\uc601\ud558\ub294 \ubc29\ubc95\\n\\n\ud398\uc5b4 \uc2dc\uac04\uc774 \uc9e7\uc544\uc11c \ub354\uc6b1 \uac04\ub2e8\ud55c 1\ubc88\uc744 \uc120\ud0dd\ud588\uace0, \uc2dc\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\uc2dc\ud0a4\uae30 \uc704\ud574 \ub354 \uac04\ub2e8\ud558\uac8c \uad6c\ud604\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud558\ub294 \uac83\ub3c4 \uc88b\uc740 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\uc600\ub358 \uac83 \uac19\ub2e4. \\n\ucd94\ud6c4 \ud398\uc5b4\uac00 \ub05d\ub098\uace0 \ub9ac\ubdf0\uc5b4\uc778 \uc11c\ube0c\uc6e8\uc774\uac00 \uc77c\ubd80\ubd84\ub9cc \ubc18\uc601\ud558\ub294 \uac83\uc73c\ub85c \uac1c\uc120\ud574 \ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4\uace0 \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ucd94\uac00 \ubc0f \uc81c\uac70\ub41c \uc694\uc18c\ub9cc \ubc18\uc601\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4.\\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n\ubbf8\uc158\uc758 \ub09c\uc774\ub3c4\uac00 \uc62c\ub77c\uac04 \ub9cc\ud07c, \ud398\uc5b4 \ud560 \ub550 \ucee8\ub514\uc158 \uad00\ub9ac\ub3c4 \uc798\ud558\ub824\uace0 \ub178\ub825\ud558\uace0 \ubbf8\uc158 \ud560 \ub54c\ub3c4 \uc9d1\uc911\ud574\uc11c \uc798 \ub05d\ub0b8 \uac83 \uac19\ub2e4. \\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc54c\uc544\uc57c \ud558\ub294 \uac8c \ub9ce\uc544\uc9c0\uba74\uc11c \uac00\ub054 \uc870\ubc14\uc2ec\uc744 \uac00\uc9c8 \ub54c\uac00 \uc788\ub294 \uac83 \uac19\uc740\ub370, \uc870\ubc14\uc2ec\uc744 \uacbd\uacc4\ud560 \ud544\uc694\uac00 \uc788\uc744 \uac83 \uac19\ub2e4. \\n\ubd80\uc871\ud55c \ubd80\ubd84\uc740 \uc778\uc815\ud558\uace0, \uc55e\uc73c\ub85c \ub098\uc544\uac00\uc57c\uaca0\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654**\\n\\n\uc694\uae08 \uc815\ucc45\uc740 \uae30\ubcf8\uc694\uae08 \uc815\ucc45, \uac70\ub9ac\ubcc4 \uc694\uae08 \uc815\ucc45, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc774 \uc788\uc5c8\ub2e4. \\n\uc694\uae08\uc744 \ub354\ud558\ub294 \ubd80\ubd84\uacfc, \ud560\uc778\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5b4\uc11c \uc774 \ub458\uc744 \ubd84\ub9ac\ud560\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc, \uc774 \uc815\ub3c4 \ud06c\uae30\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c\ub294 \uc624\ud788\ub824 \ubd84\ub9ac\ud558\uc9c0 \uc54a\uace0 \ud558\ub098\ub85c \ud569\uce58\ub294 \uac8c \ub354 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ub610\ud55c \ubd84\ub9ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \uc815\ucc45\uc758 \uc21c\uc11c\uac00 \uc911\uc694\ud55c\ub370, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc744 \ub9c8\uc9c0\ub9c9\uc5d0 \ub450\uc5b4\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ucc45\uc784 \uc5f0\uc1c4 \ud328\ud134\ub3c4 \uace0\ub824\ub97c \ud588\uc9c0\ub9cc \uc870\uae08 \ub354 \uac04\uacb0\ud574 \ubcf4\uc774\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \uc120\ud0dd\ud588\ub2e4.\\n\\n**\ub3c4\uba54\uc778\uc5d0 \ud2b9\uc815 \uae30\uc220\uc758 \uc758\uc874\uc131\uc744 \ubd84\ub9ac**\\n\\n\ucc98\uc74c\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uc5d0 jgrapht \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc758\uc874\ud558\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \ub450\uc5b4\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uac00 jgrapht\uc640 \uac15\uacb0\ud569\uc774 \ub418\uc5b4\ubc84\ub838\ub2e4. \\n\ub530\ub77c\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\uc5d0\ub294 \uacbd\ub85c \uac80\uc0c9\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0, \uc138\ubd80 \uad6c\ud604\uc740 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \uc678\ubd80\ub85c \ubd84\ub9ac\ud588\ub2e4. \\n\ucd5c\ub300\ud55c \uac04\uacb0\ud558\uac8c \uad6c\ud604\ud55c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud574\ub3c4, \uc774\ub7f0 \ubd80\ubd84\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uc5b4 \uacb0\ud569\uc744 \ud53c\ud558\ub294 \uac83\uc774 \uc88b\uc744 \uac83 \uac19\ub2e4.\\n\\n:::note \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\\n\\n\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4. \\n\uc774\ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n:::\\n\\n**\uc778\uc218 \ud14c\uc2a4\ud2b8 \uc791\uc131**\\n\\n\uc778\uc218 \ud14c\uc2a4\ud2b8\ub294 \uc0ac\uc6a9\uc790 \uc2a4\ud1a0\ub9ac \uc2dc\ub098\ub9ac\uc624 \uae30\ubc18 \ud14c\uc2a4\ud2b8\ub2e4. \\n\ube0c\ub77c\uc6b4\uc774 \ud574\uc8fc\uc2e0 \uac15\uc758 + \uc720\ud29c\ube0c\uc5d0 \uc788\ub294 \ube0c\ub77c\uc6b4\uc758 \uac15\uc758\ub97c \ubcf4\uace0 \uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0 \uc778\uc218 \ud14c\uc2a4\ud2b8\ub97c \uc801\uc6a9\ud574 \ubcf4\uc558\ub2e4. \\n\uba54\uc11c\ub4dc, \ubcc0\uc218\uba85\uc744 \uc804\ubd80 \ud55c\uae00\ub85c \uc791\uc131\ud588\ub294\ub370 \uc804\uccb4\uc801\uc778 \ud750\ub984\uc744 \uc54c\uae30 \ud3b8\ud558\uace0 \uc77d\uae30\ub3c4 \uc88b\uc558\ub2e4. \\n\uadf8\ub9ac\uace0 \uc778\uc218 \ud14c\uc2a4\ud2b8\uc5d0 \ud544\uc694\ud55c Steps\ub97c \ub9cc\ub4dc\ub294 \uacfc\uc815\uc774 \ub108\ubb34 \uc7ac\ubc0c\uc5c8\ub2e4.\\n\\n\uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4.\\n\\n```java\\n@Nested\\npublic class \ub178\uc120\uc744_\uc804\uccb4_\uc870\ud68c\ud560_\ub54c {\\n\\n @Test\\n void \uc0c1\ud589\uc885\uc810\uc5ed_\ubd80\ud130_\ud558\ud589\uc885\uc810\uc5ed\uc73c\ub85c_\uc815\ub82c\ub41c_\uacb0\uacfc\ub97c_\ubc18\ud658\ud55c\ub2e4() {\\n // given\\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad(\\"2\ud638\uc120\\", \\"\ucd08\ub85d\\", 0);\\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad(\\"2\ud638\uc120\\", \\"\uc7a0\uc2e4\\", \\"\uc7a0\uc2e4\uc0c8\ub0b4\\", 5);\\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad(\\"2\ud638\uc120\\", \\"\uc7a0\uc2e4\uc0c8\ub0b4\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\", \uc624\ub978\ucabd, 5);\\n\\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad(\\"9\ud638\uc120\\", \\"\uace0\ub3d9\\", 0);\\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad(\\"9\ud638\uc120\\", \\"\ubd09\uc740\uc0ac\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\", 3);\\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad(\\"9\ud638\uc120\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\", \\"\uc0bc\uc804\\", \uc624\ub978\ucabd, 7);\\n\\n // when\\n final var \uc870\ud68c_\uacb0\uacfc = \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uc694\uccad();\\n\\n // then\\n \uc694\uccad_\uacb0\uacfc\uc758_\uc0c1\ud0dc\ub97c_\uac80\uc99d\ud55c\ub2e4(\uc870\ud68c_\uacb0\uacfc, \uc815\uc0c1_\uc694\uccad);\\n \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uacb0\uacfc\ub97c_\ud655\uc778\ud55c\ub2e4(\\n \uc870\ud68c_\uacb0\uacfc,\\n \ub178\uc120_\uc815\ubcf4(\\"2\ud638\uc120\\", \\"\ucd08\ub85d\\", 0, \\"\uc7a0\uc2e4\\", \\"\uc7a0\uc2e4\uc0c8\ub0b4\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\"),\\n \ub178\uc120_\uc815\ubcf4(\\"9\ud638\uc120\\", \\"\uace0\ub3d9\\", 0, \\"\ubd09\uc740\uc0ac\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\", \\"\uc0bc\uc804\\")\\n );\\n }\\n}\\n```\\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\uc758\uacac \uc870\uc728\ud558\uae30**\\n\\n\ubc00\ub9ac\uac00 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\uc11c \uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \uc9c4\ud589\uc774 \uc218\uc6d4\ud588\ub2e4. \\n\uc758\uc0ac\uc18c\ud1b5\uc774 \ub9e4\uc6b0 \uc798 \ub3fc\uc11c \uc88b\uc558\uace0 \ub355\ubd84\uc5d0 \uc2dc\uac04 \ub0b4\uc5d0 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574 \ubbf8\uc158\uc744 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\\n**\uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\ud558\uae30**\\n\\n\ubc00\ub9ac\ub294 \ucf54\ub529\uc744 \uc5c4\uccad \uaf3c\uaf3c\ud558\uac8c \ud558\ub294 \uac83 \uac19\ub2e4. \\n\ubcc0\uc218\uba85, \uba54\uc11c\ub4dc\uba85\uc744 \uc911\uc694\ud558\uac8c \uc0dd\uac01\ud588\uace0, \uc88b\uc740 \ubcc0\uc218\uba85\uc744 \uc798 \uc9d3\ub294 \uac83 \uac19\ub2e4. \\n\ub610\ud55c \ucf54\ub529\ud560 \ub54c \ub0b4\uac00 \ud3c9\uc18c\uc5d0 \uc0ac\uc6a9\ud558\ub294 \ucf54\ub529 \ucee8\ubca4\uc158\uc5d0 \ub9de\ucdb0\uc8fc\ub294 \uac83 \uac19\uc544\uc11c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud588\ub2e4! \\n\\n**\ud3b8\ud55c \ubd84\uc704\uae30**\\n\\n\uc804\uccb4\uc801\uc73c\ub85c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud558\uac8c \uc9c4\ud589\ud588\ub358 \uac83 \uac19\ub2e4. \\n\uc77c\uc815\ub3c4 \uadf8\ub807\uace0, \ud398\uc5b4 \uc9c4\ud589\ud560 \ub54c\ub3c4 \uadf8\ub807\uace0 \ud070 \ubb38\uc81c\uac00 \uc5c6\uc5c8\ub358 \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4. \\n\ub098\ub294 \uacfc\uc5f0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c \ud3b8\ud55c \uc0ac\ub78c\uc77c\uae4c?"},{"id":"accidental-duplication","metadata":{"permalink":"/accidental-duplication","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx","source":"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx","title":"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5","description":"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.","date":"2023-05-24T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 24\uc77c","tags":[{"label":"DTO","permalink":"/tags/dto"}],"readingTime":7.525,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5","slug":"accidental-duplication","tags":["DTO"]},"prevItem":{"title":"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0","permalink":"/subway-retrospective"},"nextItem":{"title":"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0","permalink":"/shopping-cart-retrospective"}},"content":"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. \\n\uc694\uccad\uc5d0 \ub2f4\uae34 Body\ub97c \ud1b5\ud574 \uc804\ub2ec\ubc1b\uc740 \uac12\uc744 DTO\ub85c \ub9e4\ud551\ud558\uc5ec \ucd94\uac00\uc640 \uc218\uc815\uc744 \ud588\ub2e4.\\n\\n### \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815\\n\\n![\uc911\ubcf51](./\uc911\ubcf51.png)\\n\\n\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d\ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0\uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ud558\uc9c0\ub9cc \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4. \\n\uc704 \uacbd\uc6b0\ub294 \uc911\ubcf5\uc77c\uae4c? \uc911\ubcf5\uc774 \uc544\ub2d0\uae4c?\\n\\n\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ub9ac\ubdf0\ub97c \ubc1b\uc558\ub2e4.\\n\\n> `ProductSaveRequest`\uc640 `ProductUpdateRequest`\uac00 \uc644\uc804\ud788 \ub3d9\uc77c\ud55c\ub370, \uc7ac\uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc744\uae4c? \ub77c\ub294 \ub9ac\ubdf0\ub97c \ub0a8\uacbc\uc5c8\uc5b4\uc694. \uc0ac\uc2e4 \uc0dd\uc131\uacfc \uc218\uc815\uc740 \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac1c\uc5f0\uc131\uc774 \ub192\uc544\uc11c \ubbf8\ub9ac \ubd84\ub9ac\ud574\ub193\ub294 \uac8c \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\uae34 \ud55c\ub370, \uadf8\ub798\ub3c4 \uc911\ubcf5\uc740 \uc2eb\uc5b4\uc11c \uc800\ub3c4 \uc694\uc998 \uc774\ub7f0\uc800\ub7f0 \ubc29\ubc95\ub4e4\uc744 \uc2dc\ub3c4\ud574\ubcf4\ub294 \uc911 \uc785\ub2c8\ub2e4. \ud5c8\ube0c\ub294 \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc5b4\ub5a4 \uc0dd\uac01\uc744 \uac00\uc9c0\uace0 \uc788\uc744\uc9c0 \uad81\uae08\ud558\ub124\uc694 \u314e\u314e\\n> \\n\\n\uc9c8\ubb38\uc5d0 \ub300\ud574 \uc544\ub798\uc640 \uac19\uc774 \ub2f5\ubcc0\uc744 \ud588\ub2e4.\\n\\n> \uc800\uc7a5\uacfc \uc218\uc815\ud560 \ub54c \ud544\uc694\ud55c \ud544\ub4dc\uac12\uc774 \ub3d9\uc77c\ud558\uc5ec \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c\ub294 \ud558\ub098\ub85c \uc0ac\uc6a9\ud574\ub3c4 \ub41c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud558\uc9c0\ub9cc, \ub9d0\uc500\ud574\uc8fc\uc2e0\ub300\ub85c \uc694\uad6c\uc0ac\ud56d\uc774 \ubcc0\uacbd\ub41c\ub2e4\uba74 \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\ub2e4\uace0 \ud310\ub2e8\ud558\uc600\uc2b5\ub2c8\ub2e4!\\n> \\n\\n### \uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5\\n\\n\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec\uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4.\\n\\n- \uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4.\\n- \uac70\uc9d3\ub41c \uc911\ubcf5, \uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4.\\n\\n\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131\uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.\\n\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc704 \uc0c1\ud669\uc740 \uc6b0\ubc1c\uc801 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc778\ub2e4. \uadf8\ub798\ub3c4 \uc911\ubcf5\uc744 \uc81c\uac70\ud574\ubcfc \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?\\n\\n### \ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c\\n\\n\uc9c0\uae08\uc740 \ucd94\uac00, \uc218\uc815 2\uac00\uc9c0 \uacbd\uc6b0 \ubc16\uc5d0 \uc5c6\uc9c0\ub9cc \uc870\uae08 \ub354 \ubcf5\uc7a1\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc8fc\uc5b4\uc838\uc11c 10\uac00\uc9c0 \uacbd\uc6b0\ub85c \uc785\ub825\uc744 \ubc1b\uc73c\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c\ud560\uae4c? \\n\uc11c\ube44\uc2a4 \uacc4\uce35\uc5d0\uc11c\ub3c4 \uacc4\uce35\uc758 \ubd84\ub9ac\ub97c \uc704\ud574\uc11c \ub2e4\ub978 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uba74 20\uac1c\uc758 DTO\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud560\uae4c? \\n\ub9ac\ubdf0\uc5b4\uac00 \uc54c\ub824\uc900 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \ud1b5\ud574 \uc774\ub97c \ud574\uacb0\ud574\ubcf4\uc790! \\n\\n### \uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc\\n\\n\ud604\uc7ac \ucf54\ub4dc\uc5d0\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\ub2e4. \\nController\uc640 Service\uc5d0\uc11c \uc800\uc7a5, \uc218\uc815\ud560 \ub54c \uac01\uac01\uc758 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.\\n\ud604\uc7ac DTO\ub294 controller, service \ud328\ud0a4\uc9c0 \ub0b4\uc5d0 \uc788\ub294 \uac83\uc774 \uc544\ub2c8\ub77c dto\ub77c\ub294 \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\ud558\uace0 \uc788\ub2e4.\\n\\n```java\\n\u251c\u2500\u2500 controller\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\\n\u251c\u2500\u2500 service\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductService\\n\u251c\u2500\u2500 dto\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\\n```\\n\\n![\uc911\ubcf52](./\uc911\ubcf52.png)\\n\\n### \uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30\\n\\n![\uc911\ubcf53](./\uc911\ubcf53.png)\\n\\n\uc11c\ube44\uc2a4 \ub808\uc774\uc5b4\uc5d0\uc11c \ud544\uc694\ub85c \ud558\ub294 \uac12\ub4e4\uc744 \uc778\ud130\ud398\uc774\uc2a4\ub85c \uc815\uc758\ud55c\ub2e4. \\n\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \uc11c\ube44\uc2a4\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 service \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub85c \uc62e\uaca8\uc900\ub2e4.\\n\\n```java\\n\u251c\u2500\u2500 controller\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\\n\u251c\u2500\u2500 service\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\\n```\\n\\n```java\\npublic interface ProductSaveRequest {\\n\\n String getName();\\n\\n String getImage();\\n\\n Long getPrice();\\n}\\n\\n// ProductService\\npublic Long save(final ProductSaveRequest request) {\\n final Product product = new Product(request.getName(), request.getImage(), request.getPrice());\\n return productDao.saveAndGetId(product);\\n}\\n```\\n\\n### \uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30\\n\\n![\uc911\ubcf54](./\uc911\ubcf54.png)\\n\\n\uc704\uc5d0\uc11c \uc791\uc131\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc791\uc131\ud55c\ub2e4. \\n\uc694\uccad\uc740 ProductRequest \ud074\ub798\uc2a4\ub85c \ubc1b\uace0, \uc11c\ube44\uc2a4\uc5d0 \uc804\ub2ec\ud560 \ub550 \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\uc758 \uba85\uc138\ub9cc \ub9de\ucd94\uba74 \ubb38\uc81c\uc5c6\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n```java\\n\u251c\u2500\u2500 controller\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductController\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductRequest\\n\u251c\u2500\u2500 service\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\\n```\\n\\n```java\\npublic class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {\\n\\n @NotBlank(message = \\"\uc774\ub984\uc740 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\\")\\n @Size(min = 1, max = 100, message = \\"\uc774\ub984\uc740 \ucd5c\uc18c {min}\uc790 \uc774\uc0c1, {max}\uc790 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.\\")\\n private final String name;\\n\\n @NotBlank(message = \\"\uc774\ubbf8\uc9c0\ub294 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\\")\\n private final String image;\\n\\n @Range(message = \\"\uac00\uaca9\uc740 \ucd5c\uc18c {min}\uc6d0 \uc774\uc0c1, {max}\uc6d0 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.\\")\\n private final long price;\\n\\n public ProductRequest(final String name, final String image, final long price) {\\n this.name = name;\\n this.image = image;\\n this.price = price;\\n }\\n\\n @Override\\n public String getName() {\\n return name;\\n }\\n\\n @Override\\n public String getImage() {\\n return image;\\n }\\n\\n @Override\\n public long getPrice() {\\n return price;\\n }\\n}\\n\\n// ProductController\\n@PostMapping(\\"/products\\")\\npublic ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {\\n final Long id = productService.save(request);\\n return ResponseEntity.created(URI.create(\\"/products/\\" + id)).build();\\n}\\n```\\n\\n### \uc815\ub9ac\\n\\n\uc704\uc640 \uac19\uc774 \uad6c\ud604\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc744 \uc5bb\uc744 \uc218 \uc788\ub2e4. \\n\\n1. Service\uc5d0\uc11c \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc694\uccad\uc5d0 \ub300\ud55c DTO\ub97c \uc54c\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4.\\n2. \uacf5\ud1b5\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 DTO\ub97c \uc81c\uc678\ud558\uace0 DTO \ud328\ud0a4\uc9c0\uc5d0 \ub300\ud55c \uacb0\ud569\ub3c4\uac00 \ub0ae\uc544\uc9c0\uace0, \uac01 \ub808\uc774\uc5b4\uc758 \uc751\uc9d1\ub3c4\uac00 \uc99d\uac00\ud55c\ub2e4.\\n3. \uc694\uccad \uac1d\uccb4\ub9cc \ub2e4\ub974\uace0 \uc11c\ube44\uc2a4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ud589\uc704\ub97c \uc218\ud589\ud558\ub294 \uacbd\uc6b0 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.\\n\\n\uc704 \ubc29\ubc95\uc744 \uc9c0\uae08 \ubbf8\uc158\uc5d0\uc11c \ubc14\ub85c \uc801\uc6a9\ud560\uae4c \ud558\ub2e4\uac00, \ub098\uc911\uc5d0 \ud544\uc694\ud560 \ub54c \uc801\uc6a9\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\uc544\uc11c \ubbf8\uc158\uc5d0\ub294 \uc801\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4. \\n\uc0c1\ud669\uc5d0 \ub9de\ucdb0 \uc801\uc7ac\uc801\uc18c\uc5d0 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud574\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4.\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98 16\uc7a5 \ub3c5\ub9bd\uc131, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 \\n[https://techblog.woowahan.com/2647/](https://techblog.woowahan.com/2647/) \\n[https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/](https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/)"},{"id":"shopping-cart-retrospective","metadata":{"permalink":"/shopping-cart-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-shopping-cart/pull/244","date":"2023-05-12T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 12\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":4.845,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0","slug":"shopping-cart-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5","permalink":"/accidental-duplication"},"nextItem":{"title":"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0","permalink":"/web-racing-car-retrospective"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-shopping-cart/pull/244 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-shopping-cart/pull/300 \\n:::\\n\\n### \uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\\n\\n\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc740 \ube14\ub799\ucea3\uc774\ub791 \uc9c4\ud589\ud588\ub2e4. \\n\uc694\uad6c\uc0ac\ud56d\uc774 \uc5c4\uccad \ubcf5\uc7a1\ud55c \ubbf8\uc158\uc740 \uc544\ub2c8\uc5c8\uace0, \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \uae30\ubcf8\uc801\uc778 CRUD\ub97c \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n2\ub2e8\uacc4\uc5d0\uc11c\ub294 Basic \uc778\uc99d\uc744 \ud1b5\ud574 \uc790\uc2e0\uc758 \uc7a5\ubc14\uad6c\ub2c8\uc5d0\ub9cc \uc0c1\ud488\uc744 \ub2f4\uace0, \uc81c\uac70\ud560 \uc218 \uc788\ub3c4\ub85d \uad6c\ud604\ud558\ub294 \uc694\uad6c\uc0ac\ud56d\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\nInterceptor\ub098 Argument Resolver\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\uac00 \ub192\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc870\uae08 \ub354 \uc54c\uc544\uac04 \ub290\ub08c\uc774\ub2e4. \\n\uc774\uc804\uc5d0 \uc2a4\ud504\ub9c1 \uc0ac\uc6a9\ud560 \ub54c\ub294 \uc544\ubb34 \uc0dd\uac01 \uc5c6\uc774 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub294\ub370, \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \ub54c \uadfc\uac70\uac00 \uc0dd\uae30\uace0 \uc788\ub294 \uac83 \uac19\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**DTO \uc6b0\ubc1c\uc801 \uc911\ubcf5**\\n\\n\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. \\n\\n![dto1](./dto1.png)\\n\\n\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d \ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0 \uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\uc744 \ud588\uace0, \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4. \\n\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec \uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4. \\n\\n- \uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4.\\n- \uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4.\\n\\n\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131 \uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4. \\n\ub530\ub77c\uc11c \ub9ac\ubdf0\uc5b4 \uc6e8\uc9c0\uac00 \uc544\ub798\uc640 \uac19\uc774 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\uace0 \uc54c\ub824\uc8fc\uc168\ub2e4. \\n\\n![dto2](./dto2.png)\\n\\n**Interceptor\uc5d0\uc11c \uc778\uc99d\ud55c \uac12 \uc7ac\uc0ac\uc6a9**\\n\\n\uc0ac\uc2e4 \uc870\ud68c\ub97c \ub450 \ubc88 \ud558\uae30 \uc2eb\uc5b4\uc11c \ub2e4\uc591\ud55c \ubc29\ubc95\uc744 \uc0dd\uac01\ud588\uc5c8\ub294\ub370 \uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 ThreadLocal\uc744 \uc0ac\uc6a9\ud588\ub2e4. \\n\uc77c\ub2e8 Tomcat\uc740 \uc694\uccad\ub9c8\ub2e4 \ub2e4\ub978 \uc2a4\ub808\ub4dc\ub97c \uc0ac\uc6a9\ud558\uace0, Interceptor\uc5d0\uc11c \uc870\ud68c\ud574\uc11c \ub9cc\ub4e0 Credential\uc744 ThreadLocal\uc5d0 \ub123\uc5b4\ub450\uc5c8\ub2e4\uac00 ArgumentResolver\uc5d0\uc11c \uaebc\ub0b8 \ub2e4\uc74c ThreadLocal\uc744 clear \ud558\uba74 \ubb38\uc81c\uac00 \uc5c6\uc744 \uac70\ub77c \ud310\ub2e8\ud588\ub2e4. \\n\\n\ub9ac\ubdf0\uc5b4\uc778 \uc6e8\uc9c0\uc5d0\uac8c\ub3c4 \uc5b4\ub5a4 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560\uc9c0 \uad81\uae08\uc99d\uc744 \uc791\uc131\ud588\uc5c8\ub2e4. \\n\uc6e8\uc9c0\ub294 email\uc5d0 index\ub97c \uac78\uc5b4\ub450\uace0 dao \uc7ac\uc870\ud68c\ub97c \uc0ac\uc6a9\ud560 \uac83\uc774\ub77c\uace0 \ud588\ub2e4. \\n\uc7ac\uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 db\uc5d0 \uc778\ub371\uc2a4\ub97c \uac78 \uc0dd\uac01\uc740 \ud558\uc9c0 \ubabb\ud588\ub294\ub370, \uc81c\uc77c \uc9c1\uad00\uc801\uc774\uace0 \uc88b\uc740 \ubc29\ubc95\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\uae30\ub85d**\\n\\n\ube14\ub799\ucea3\uc740 \uae30\ub85d\uc744 \uad49\uc7a5\ud788 \uc798 \ud558\ub294 \ud06c\ub8e8\uc600\ub2e4. \\n\ub178\uc158\uc5d0 \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ud588\ub358 \ub0b4\uc6a9 + \uace0\ubbfc\ud588\ub358 \ubd80\ubd84 + \ud68c\uace0\ub97c \uaf3c\uaf3c\ud558\uac8c \uae30\ub85d\ud574\uc11c \uacf5\uc720\ud574 \uc8fc\uc5c8\ub2e4. \\n\ucd94\uac00\uc801\uc73c\ub85c \uc774\ubaa8\uc9c0\ub97c \uc801\uadf9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\uc5ec \ub354\uc6b1 \uc88b\uc558\ub2e4!\\n\\n**\uc758\uacac \uc77c\uce58\uc2dc\ud0a4\uae30**\\n\\n\ud398\uc5b4 \uc2dc\uac04\uc740 \ud55c\uc815\ub418\uc5b4 \uc788\uace0, \uae30\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574\uc57c \ud55c\ub2e4. \\n\ub530\ub77c\uc11c \uc801\ub2f9\ud788 \ud0c0\ud611\uc744 \ubd10\uc11c \uc758\uacac\uc744 \ube60\ub974\uac8c \uc218\uc6a9\ud574 \ub370\ub4dc\ub77c\uc778\uc744 \ub9de\ucd94\ub294 \uac83\ub3c4 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\ube14\ub799\ucea3\uc740 \ub0b4 \uc758\uacac\uc744 \uc798 \ub4e4\uc5b4\uc92c\uace0, \ub355\ubd84\uc5d0 \ub9c9\ud788\ub294 \ubd80\ubd84 \uc5c6\uc774 \ube60\ub974\uac8c \ubbf8\uc158\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n\ube68\ub9ac \uce5c\ud574\uc84c\uace0, \uc758\uc0ac\uc18c\ud1b5\uc774 \uc798 \ub3fc\uc11c \uc7ac\ubc0c\uac8c \ucf54\ub529\ud560 \uc218 \uc788\uc5c8\ub2e4!"},{"id":"web-racing-car-retrospective","metadata":{"permalink":"/web-racing-car-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-racingcar/pull/24","date":"2023-05-02T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 2\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.6,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0","slug":"web-racing-car-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0","permalink":"/shopping-cart-retrospective"},"nextItem":{"title":"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec","permalink":"/tecochat-retrospective-2"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-racingcar/pull/24 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-racingcar/pull/128 \\n:::\\n\\n### \uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158\\n\\n\uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud55c\ub2e4\uace0 \uc2dc\uac04\uc774 \ub9ce\uc774 \uc5c6\uc5b4\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc84c\ub2e4. \\n\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158\uc5d0\uc11c\ub294 \ube44\ubc84\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4. \\n\ub808\ubca8 2\uc5d0\uc11c \uc9c4\ud589\ud558\ub294 \uccab \ubbf8\uc158\uc774\ub77c \ub9ce\uc774 \uae34\uc7a5\ub418\uc5c8\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ube44\ubc84\ub791 \ucd08\ubc18\uc5d0 \ub9db\uc788\ub294 \uac83\ub3c4 \ub9ce\uc774 \uba39\uc73c\uba74\uc11c \ube68\ub9ac \uce5c\ud574\uc838\uc11c \uc7ac\ubc0c\uac8c \ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n\uc2a4\ud504\ub9c1\uc744 \uc870\uae08 \uc0ac\uc6a9\ud560 \uc904 \uc54c\uc544\uc11c, \ube44\ubc84\ub791 \uac19\uc774 \ud559\uc2b5\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4. \\n\uccab \ubbf8\uc158\uc774\ub77c \uadf8\ub7f0\uc9c0 \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc740 \uc5c6\uc5c8\uace0, \ucd5c\ub300\ud55c \uae54\ub054\ud558\uac8c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\ub09c\uc774\ub3c4 \ub192\uc740 \ubbf8\uc158\uc774 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ub9ac\ubdf0\uc5b4\uc778 \ub77c\ube48\uc5d0\uac8c \uce6d\ucc2c\uc744 \ub9ce\uc774 \ubc1b\uc544\uc11c \uae30\ubd84\uc774 \uc88b\uc558\ub2e4. \\n\ub77c\ube48 \uac10\uc0ac\ud569\ub2c8\ub2e4! \\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n\ucee8\ub514\uc158\ub3c4 \uc88b\uc9c0 \uc54a\uace0 \uc5f4\uc815\ub3c4 \uc2dd\uc740 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4. \\n\ubbf8\uc158\uc774 \ub2e4\uc18c \uc5ec\uc720\ub86d\ub2e4\uace0 \ub290\uaef4\uc838\uc11c, \uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ubd84\ub3c4 \uc798 \uad00\ub9ac\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4. \\n\ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud574\uc11c \ud398\uc5b4\uc5d0\uac8c \ub9ce\uc774 \ubbf8\uc548\ud588\uace0, \ub098 \uc790\uc2e0\uc5d0\uac8c \uc544\uc26c\uc6e0\ub358 \ubd80\ubd84\uc774 \ub9ce\uc558\ub2e4. \\n\\n\uc9c0\ub09c\ubc88 \ud68c\uace0\ub97c \ub2e4\uc2dc \ubcf4\ub294\ub370 \uc9d1\uc911\uc744 \uc798 \ubabb\ud55c \uacbd\uc6b0\uac00 \ub9ce\uc740 \uac83 \uac19\ub2e4. \\n\ub3c4\uc804\uc801\uc774\uc9c0 \uc54a\uac70\ub098 \uc2dc\uac04\uc774 \ubd80\uc871\ud558\uc9c0 \uc54a\uc73c\uba74 \uc9d1\uc911\uc744 \uc798 \ubabb\ud558\ub294 \uac83 \uac19\ub2e4. \\n\uba38\ub9bf\uc18d\uc5d0\uc11c \uc2dc\uac04\uc801 \uc5ec\uc720\uac00 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \ub54c\uac00 \uac00\uc7a5 \uc704\ud5d8\ud55c \uc21c\uac04\uc778 \uac83 \uac19\ub2e4. \\n\\n\ud568\uaed8 \uc790\ub77c\uae30\uc5d0\uc11c \ub098\uc628 `\ub09c\uc774\ub3c4 \ub192\uc774\uae30`\uac00 \ud544\uc694\ud574\uc9c0\ub294 \uc21c\uac04\uc774\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**\uc911\uc694\ub3c4\uac00 \uc788\ub294 \uc5b4\ub178\ud14c\uc774\uc158\ubd80\ud130 \ud074\ub798\uc2a4 \uc774\ub984\uc5d0 \uac00\uae5d\uac8c \uba85\uc2dc\ud558\uae30**\\n\\n```java\\n@SuppressWarnings(\\"NonAsciiCharacters\\")\\n@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)\\n@Transactional\\n@AutoConfigureMockMvc\\n@SpringBootTest\\npublic class RacingGameIntegrationTest {\\n```\\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\ube44\ubc84\uc758 \uc131\uaca9** \\n\ube44\ubc84\uac00 \uc131\uaca9\uc774 \uc88b\uc544\uc11c \ud3b8\ud558\uac8c \ud398\uc5b4\ub97c \ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc131\uae09\ud558\uc9c0 \uc54a\uace0 \uc5ec\uc720\ub85c\uc6cc\uc11c \uc88b\uc558\ub2e4. \\n\\n**\ubbf8\uc158\uc5d0 \uc9d1\uc911\ud558\ub294 \ubd80\ubd84** \\n\ub0b4\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud588\ub294\ub370\ub3c4 \uac19\uc774 \ud398\uc5b4\ub97c \uc798 \uc9c4\ud589\ud55c \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4. \\n\ube44\ubc84\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud574\uc11c \uadf8\ub807\uc9c0 \uc54a\uc558\ub098 \uc0dd\uac01\ud588\ub2e4. \\n\uadfc\uc721\ub9e8 \ube44\ubc84\ub77c \uadf8\ub7f0\uc9c0 \uccb4\ub825\uc774 \uc88b\uc544\uc11c \uadf8\ub7f0\uac00? \\n\uc911\uac04\uc5d0 \uc798 \uc548 \uc26c\uace0\ub3c4 \uc9d1\uc911\ud574\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac78 \ubcf4\uace0 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n**\ud559\uc2b5\uc5d0 \ub300\ud55c \uc5f4\uc815** \\n\ucd94\uac00\uc801\uc73c\ub85c \uc54c\uace0 \uc2f6\uc740 \ubd80\ubd84\uc744 \ub530\ub85c \ud559\uc2b5\ud558\ub294 \uc5f4\uc815\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ube44\ubc84\uc640 \uc2a4\ud504\ub9c1\uc5d0 \ub300\ud574 \uc54c\uc544\uac00\ub294 \uc2dc\uac04\uc744 \ub9ce\uc774 \uac00\uc9c4 \ubd80\ubd84\uc774 \ub9e4\uc6b0 \uc88b\uc558\ub2e4. \\n\ub098\ub3c4 5\uc6d4\ubd80\ud130 \uc870\uae08 \ub354 \ud654\uc774\ud305 \ud574\uc57c\uaca0\ub2e4."},{"id":"tecochat-retrospective-2","metadata":{"permalink":"/tecochat-retrospective-2","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx","source":"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx","title":"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec","description":"\ud504\ub860\ud2b8\uc5d4\ud2b8","date":"2023-05-01T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 1\uc77c","tags":[{"label":"TecoChat","permalink":"/tags/teco-chat"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":4.67,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec","slug":"tecochat-retrospective-2","tags":["TecoChat","Retrospective"]},"prevItem":{"title":"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0","permalink":"/web-racing-car-retrospective"},"nextItem":{"title":"Jenkins\ub85c CI/CD \uc124\uc815","permalink":"/jenkins"}},"content":"### \ud504\ub860\ud2b8\uc5d4\ud2b8\\n\\n\ub2c9\ub124\uc784\uc744 \uc785\ub825\ud558\uc5ec \uac04\ub2e8\ud788 \ub85c\uadf8\uc778\ud558\ub294 \ud654\uba74, \ucc44\ud305 \ubaa9\ub85d\uc744 \ubcf4\uc5ec\uc8fc\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\uace0 \ub2e8\uc77c \ucc44\ud305\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\ub2e4. \\n\ucd94\uac00\ub85c \ucc44\ud305\uc744 \uc774\uc5b4\ub098\uac08 \uc218 \uc788\uac8c \ud558\ub294 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4. \\n\uc790\uc798\ud558\uac8c \uc2e0\uacbd \uc4f8 \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c, \ud504\ub860\ud2b8\uc5d4\ub4dc \ud558\ub294 \uc0ac\ub78c\ub4e4\uc774 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4. \\n\uc5ec\uc720\uac00 \ub41c\ub2e4\uba74 \uc790\uc2e0\uc758 \ucc44\ud305\uc744 \ubcfc \uc218 \uc788\ub294 \uae30\ub2a5\uc774\ub098, \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub294 \uae30\ub2a5, \ub313\uae00 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud560 \uc608\uc815\uc774\ub2e4. \\n\\n### \ubc31\uc5d4\ub4dc\\n\\n\ucd5c\ub300\ud55c \ube68\ub9ac \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uae30\ub85c \uc815\ud574\uc11c, \ubc31\uc5d4\ub4dc\ub294 \ub9d0\ub791\uc774 \uc77c\ub2e8 \ub2e4 \ub9cc\ub4e4\uace0 \uc788\ub2e4. \\n\ub9d0\ub791\uc774 \ud55c \ubd80\ubd84\uc774 \ub108\ubb34 \ub9ce\uc544\uc11c \ub0b4\uac00 \ubabb \ub530\ub77c\uac00\ub294 \uac83 \uac19\ub2e4. \\n\ub098\uc911\uc5d0 \ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc774\ud574\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. \\n\\n### Http Request Header\\n\\n\uc544\uc9c1 \uc778\uc99d\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ud558\uc9c0 \uc54a\uc544\uc11c \uc694\uccad \ud5e4\ub354\uc5d0 \uc774\ub984\uc744 \ubcf4\ub0b4\uae30\ub85c \ud588\ub2e4. \\n\ub9d0\ub791\uc774 \ud55c\uae00\uc740 \uc548\ub41c\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c Base64\ub85c \uc778\ucf54\ub529\ud558\uace0, \ubc31\uc5d4\ub4dc\uc5d0\uc11c \ub514\ucf54\ub529 \ud558\uc5ec \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4. \\n\uc544\ub798\ub294 pinia\uc5d0 \uc788\ub294 name \uac12\uc744 \uc778\ucf54\ub529 \ud558\ub294 \ucf54\ub4dc\ub2e4. deprecated \ub418\uc5c8\ub2e4\ub294\ub370, \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560 \uc904 \ubab0\ub77c\uc11c \uc77c\ub2e8 \uc774\uac78 \uc0ac\uc6a9\ud588\ub2e4. \\n\\n```ts\\nconst encodedName = () => {\\n const uriComponent = unescape(encodeURIComponent(name.value));\\n return btoa(uriComponent);\\n};\\n```\\n\\n### Elastic Beanstalk\\n\\n\uac00\uc7a5 \ube60\ub974\uac8c \ubc31\uc5d4\ub4dc\ub97c \ubc30\ud3ec\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ubb58\uc9c0 \uace0\ubbfc\ud558\ub2e4\uac00 Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4. \\nElastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uba74 \uc778\ud504\ub77c\uc5d0 \ub300\ud574 \uc798 \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ube60\ub974\uac8c \ubc30\ud3ec\ud558\uace0 \uad00\ub9ac\ud560 \uc218 \uc788\ub2e4. \\n\ubaa8\ub2c8\ud130\ub9c1, \ub85c\uae45, \ub85c\ub4dc \ubc38\ub7f0\uc2f1 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4. \\n\\n### Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac\\n\\n\ucd08\uae30 \uc124\uc815 \uc2dc RDS\ub97c \uc5f0\uacb0\ud558\uace0 \uc124\uc815 \uc644\ub8cc \ud6c4 \ubd84\ub9ac\ud55c\ub2e4\uba74, Beanstalk \uc778\uc2a4\ud134\uc2a4 -> RDS \uc694\uccad \uc2dc \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc744 \uc548 \ud574\ub3c4 \ub41c\ub2e4. \\nRDS \ubd84\ub9ac \uc2dc Beanstalk\uc5d0 \uae30\ubcf8\uc801\uc73c\ub85c \uc124\uc815\ub418\uc5b4 \uc788\ub294 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD\uc640 \uac19\uc740 \ud658\uacbd \ubcc0\uc218\uac00 \uac19\uc774 \uc81c\uac70\ub41c\ub2e4. \\n\ucd94\uac00\ub85c Elastic Beanstalk\ub85c RDS\ub97c \uc124\uc815\ud558\uba74 \uae30\ubcf8 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uba85\uc740 ebdb\ub2e4. \\n\\n### Elastic Beanstalk nginx \uc124\uc815\\n\\n\uc5c5\ub85c\ub4dc\ud558\ub294 zip \ud30c\uc77c \ub0b4\ubd80\uc5d0 `.platform/nginx/conf.d/` \uacbd\ub85c\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ucd94\uac00\ud558\uba74 nginx \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\\n### Jenkins\\n\\n\ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc77c\uc77c\ud788 \ubc30\ud3ec\ud558\uae30 \ubd88\ud3b8\ud574\uc11c Jenkins\ub97c \uc774\uc6a9\ud558\uc5ec Repository\uc5d0 \ucf54\ub4dc\ub97c push \ud560 \ub54c \uc790\ub3d9\uc73c\ub85c \ubc30\ud3ec\uac00 \ub418\uac8c \uc124\uc815\ud558\uae30\ub85c \ud588\ub2e4. \\n\uc791\ub144\uc5d0 \ud655\uc778\ud588\uc744 \ub550 2022\ub144 12\uc6d4 31\uc77c\uae4c\uc9c0 EC2 ARM \uae30\ubc18 t4g.small\uc774 \ubb34\ub8cc\uc600\ub294\ub370, \ub2e4\uc2dc \ub4e4\uc5b4\uac00 \ubcf4\ub2c8 2023\ub144\uae4c\uc9c0 12\uc6d4 31\uc77c\uae4c\uc9c0 t4g.small\uc744 \ubb34\ub8cc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5c8\ub2e4. \\nt4g.small\uc740 \ub7a8\uc774 2G\uc778\ub370, \uc608\uc804\uc5d0\ub294 \ubd80\uc871\ud558\uc9c0 \uc54a\uc558\ub2e4\uace0 \uc0dd\uac01\ud588\ub294\ub370 Java 17\uc744 \uc368\uc11c \uadf8\ub7f0\uac00 \ube4c\ub4dc \ud560 \ub54c \ub7a8\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\uc544\uc11c Swap \uba54\ubaa8\ub9ac 2\uae30\uac00\ub97c \ucd94\uac00\ub85c \uc124\uc815\ud588\ub2e4. \\n\ucd94\uac00\ub85c build.gradle\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8 \uc2dc \uc0ac\uc6a9\ud558\ub294 \ub7a8\uc744 \ub298\ub9b4 \uc218 \uc788\ub2e4. \uae30\ubcf8\uac12\uc740 512MB\ub77c\uace0 \ud55c\ub2e4. \\n\\n```groovy\\ntest {\\n maxHeapSize = \\"1024m\\"\\n}\\n```\\n\\n### Jenkins Blue Ocean\\n\\nBlue Ocean\uc740 Jenkins Pipeline\uc744 \uad6c\uc131\ud558\ub294 \ub370\uc5d0 \uc788\uc5b4 \ud3b8\ub9ac\ud558\uac8c \ud574\uc8fc\ub294 \ub3c4\uad6c\ub2e4. \\n\uc2dc\uac01\ud654\ub3c4 \uc798 \ub418\uc5b4\uc788\uace0, \uc124\uc815\ub3c4 \ud3b8\ub9ac\ud55c \uac83 \uac19\ub2e4. \\n\uc624\ub298 \uc801\uc6a9\ud574 \ubcf4\ub2c8 \ub7a8\uc774 \ubd80\uc871\ud558\uc5ec \uc911\uac04\uc5d0 \uc798 \uc548\ub418\uae30\ub3c4 \ud558\uace0 \uadf8\ub798\uc11c \uadf8\ub0e5 \\"Pipeline\ub9cc \uc0ac\uc6a9\ud560 \uac78 \uadf8\ub7ac\ub098?\\" \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[Elastic Beanstalk, AWS](https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/Welcome.html) \\n[EC2 AWS Graviton, AWS](https://aws.amazon.com/ko/ec2/graviton/) \\n[Default Memory Settings, AWS](https://docs.gradle.org/current/userguide/upgrading_version_4.html#rel5.0:default_memory_settings)"},{"id":"jenkins","metadata":{"permalink":"/jenkins","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx","source":"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx","title":"Jenkins\ub85c CI/CD \uc124\uc815","description":"\uc124\uc815 \ud658\uacbd","date":"2023-04-30T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 30\uc77c","tags":[{"label":"Jenkins","permalink":"/tags/jenkins"},{"label":"Elastic Beanstalk","permalink":"/tags/elastic-beanstalk"}],"readingTime":7.495,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Jenkins\ub85c CI/CD \uc124\uc815","slug":"jenkins","tags":["Jenkins","Elastic Beanstalk"]},"prevItem":{"title":"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec","permalink":"/tecochat-retrospective-2"},"nextItem":{"title":"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30","permalink":"/tecochat-retrospective-1"}},"content":"### \uc124\uc815 \ud658\uacbd\\n\\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc774\ubbf8\uc9c0: Amazon Linux 2023 AMI \\n\uc544\ud0a4\ud14d\uccd0: ARM \\n\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small \\n\ud658\uacbd \uad6c\uc131\uc774 \uc644\ub8cc\ub41c Elastic Beanstalk \\n\ub2e8\uc77c Spring Boot \ud504\ub85c\uc81d\ud2b8\uac00 \uc874\uc7ac\ud558\ub294 Github Repository\\n\\n### \\\\[EC2 CLI\\\\] Swap \uba54\ubaa8\ub9ac \uc124\uc815\\n\\nt4g.small\uc774 \ub7a8\uc774 2G\uc778\ub370 \ub7a8\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \ub290\uaef4\uc838\uc11c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud588\ub2e4. \\n\uc544\ub798 \uba85\ub839\uc5b4\ub97c \ub530\ub77c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud558\uace0 free -h \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uc798 \uc124\uc815\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n``` bash\\n# fallocate \uc774\uc6a9\ud558\uc5ec \uc2a4\uc651 \ud30c\uc77c \uc0dd\uc131\\nsudo fallocate -l 2G /swapfile\\n\\n# \uad8c\ud55c \uc124\uc815\\nsudo chmod 600 /swapfile\\n\\n# \ud30c\uc77c\uc744 Swap \ud3ec\ub9f7\uc73c\ub85c \ubcc0\uacbd \ud6c4 \uc2dc\uc2a4\ud15c\uc5d0 \ub4f1\ub85d\\nsudo mkswap /swapfile\\nsudo swapon /swapfile\\n\\n# Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9\\n# \ucd5c\ud558\ub2e8\uc5d0 \ub2e4\uc74c \uad6c\ubb38 \uc124\uc815 -> /swapfile swap swap defaults 0 0\\nsudo vim /etc/fstab\\n```\\n\\n\\n### \\\\[EC2 CLI\\\\] jenkins \uc124\uce58\\n\\n```bash\\nsudo wget -O /etc/yum.repos.d/jenkins.repo \\\\\\n https://pkg.jenkins.io/redhat-stable/jenkins.repo\\nsudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key\\nsudo yum upgrade\\nsudo yum install java-17-amazon-corretto-devel\\nsudo yum install jenkins\\nsudo systemctl daemon-reload\\n```\\n\\n[Jenkins \uacf5\uc2dd \ud648\ud398\uc774\uc9c0](https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos) \ub97c \ucc38\uace0\ud558\uc5ec \uc124\uce58\ud558\ub294 \uac8c \uc88b\ub2e4.\\n\\n### \\\\[EC2 CLI\\\\] Jenkins \uc2dc\uc791\\n\\n```bash\\nsudo systemctl enable jenkins\\nsudo systemctl start jenkins\\n```\\n\\nenable\ub85c \uc124\uc815\ud558\uc5ec \ubd80\ud305\uc2dc \uc790\ub3d9\uc2dc\uc791 \ub418\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4.\\n\\n### \\\\[EC2 CLI\\\\] nginx & git \uc124\uce58\\n\\n```bash\\nsudo yum install nginx\\nsudo systemctl enable nginx\\nsudo systemctl start nginx\\n\\nsudo yum install git\\n```\\n\\nnginx\uc640 \ucf54\ub4dc\ub97c \ubd88\ub7ec\uc62c \ub54c \uc0ac\uc6a9\ud560 git\uc744 \uc124\uce58\ud55c\ub2e4.\\n\\n### \\\\[EC2 CLI\\\\] nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815\\n\\n\uc544\ub798 \uc124\uc815 \ud30c\uc77c\uc740 \uacf5\uc2dd \ud648\ud398\uc774\uc9c0\uc5d0\uc11c \uc548\ub0b4\ud55c \uae30\ubcf8\uc801\uc778 \uc124\uc815 \ud30c\uc77c\uc774\ub2e4.\\n\\n```bash\\nupstream jenkins {\\n keepalive 32; # keepalive connections\\n server 127.0.0.1:8080; # jenkins ip and port\\n}\\n\\n# Required for Jenkins websocket agents\\nmap $http_upgrade $connection_upgrade {\\n default upgrade;\\n \'\' close;\\n}\\n\\nserver {\\n listen 80; # Listen on port 80 for IPv4 requests\\n\\n server_name jenkins.example.com; # replace \'jenkins.example.com\' with your server domain name\\n\\n # this is the jenkins web root directory\\n # (mentioned in the output of \\"systemctl cat jenkins\\")\\n root /var/run/jenkins/war/;\\n\\n access_log /var/log/nginx/jenkins.access.log;\\n error_log /var/log/nginx/jenkins.error.log;\\n\\n # pass through headers from Jenkins that Nginx considers invalid\\n ignore_invalid_headers off;\\n\\n location ~ \\"^/static/[0-9a-fA-F]{8}\\\\/(.*)$\\" {\\n # rewrite all static files into requests to the root\\n # E.g /static/12345678/css/something.css will become /css/something.css\\n rewrite \\"^/static/[0-9a-fA-F]{8}\\\\/(.*)\\" /$1 last;\\n }\\n\\n location /userContent {\\n # have nginx handle all the static requests to userContent folder\\n # note : This is the $JENKINS_HOME dir\\n root /var/lib/jenkins/;\\n if (!-f $request_filename){\\n # this file does not exist, might be a directory or a /**view** url\\n rewrite (.*) /$1 last;\\n break;\\n }\\n sendfile on;\\n }\\n\\n location / {\\n sendfile off;\\n proxy_pass http://jenkins;\\n proxy_redirect default;\\n proxy_http_version 1.1;\\n\\n # Required for Jenkins websocket agents\\n proxy_set_header Connection $connection_upgrade;\\n proxy_set_header Upgrade $http_upgrade;\\n\\n proxy_set_header Host $host;\\n proxy_set_header X-Real-IP $remote_addr;\\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\\n proxy_set_header X-Forwarded-Proto $scheme;\\n proxy_max_temp_file_size 0;\\n\\n #this is the maximum upload size\\n client_max_body_size 10m;\\n client_body_buffer_size 128k;\\n\\n proxy_connect_timeout 90;\\n proxy_send_timeout 90;\\n proxy_read_timeout 90;\\n proxy_buffering off;\\n proxy_request_buffering off; # Required for HTTP CLI commands\\n proxy_set_header Connection \\"\\"; # Clear for keepalive\\n }\\n\\n}\\n```\\n\\nJenkins\ub294 8080 \ud3ec\ud2b8\ub85c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc\ub97c \uc124\uc815\ud574\uc900\ub2e4. \\n`/etc/nginx/conf.d`\xa0\uc544\ub798\xa0`default.conf`\xa0\ud30c\uc77c\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uace0 \uc704\uc640 \uac19\uc774 \uc785\ub825\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4. \\nnginx\uc758 \uae30\ubcf8 \uc124\uc815 \ud30c\uc77c\uc5d0 \uc874\uc7ac\ud558\ub294\xa0`include /etc/nginx/conf.d/*.conf;`\xa0\uc124\uc815 \ub54c\ubb38\uc5d0\xa0`.conf`\xa0\ub85c \ub05d\ub09c\ub2e4\uba74 \uc124\uc815\uc774 \uc801\uc6a9\ub41c\ub2e4. \\n\uc124\uc815 \ud6c4\xa0`sudo nginx -t`\ub85c \uc124\uc815\ud30c\uc77c\uc774 \uc815\uc0c1\uc778\uc9c0 \ud655\uc778\ud558\uace0,\xa0`sudo systemctl restart nginx`\xa0\uba85\ub839\uc5b4\ub85c nginx\ub97c \uc7ac\uc2dc\uc791\ud55c\ub2e4. \\n\\n### \\\\[Jenkins\\\\] Jenkins \uc811\uc18d\\n\\nJenkins\ub97c \uc124\uce58\ud55c EC2 \uc778\uc2a4\ud134\uc2a4 \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc5d0 80\ubc88 \ud3ec\ud2b8\uac00 \uc5f4\ub824\uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. \\nEC2\uc758 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \uc785\ub825\ud558\uace0 \ub4e4\uc5b4\uac00\uba74 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\ub77c\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4.\\n\\n![jenkins-start](./jenkins-start.png)\\n\\n\ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud574\uc57c \ud558\ub294\ub370 `sudo cat /var/lib/jenkins/secrets/initialAdminPasswor` \ub97c \uc785\ub825\ud574 \ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc5bb\uc744 \uc218 \uc788\ub2e4. \\n\ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\uba74 \ud50c\ub7ec\uadf8\uc778 \uc124\uc815 \ucc3d\uc774 \ub098\uc62c\ud150\ub370 `install suggested plugins`\uc744 \ud074\ub9ad\ud558\uc5ec Jenkins\uac00 \ucd94\ucc9c\ud558\ub294 \uae30\ubcf8 \ud50c\ub7ec\uadf8\uc778\ub4e4\uc744 \uc124\uce58\ud558\uba74 \ub41c\ub2e4. \\n\ud50c\ub7ec\uadf8\uc778\uc744 \uc124\uce58\ud558\uba74 \uacc4\uc815 \ubc0f \uc8fc\uc18c \uc124\uc815\uc744 \ud574\uc57c\ud558\ub294\ub370 \uc774\uac74 \ud3b8\ud558\uac8c \uc124\uc815\ud558\uba74 \ub41c\ub2e4. \\n\\n### \\\\[Jenkins\\\\] Jenkins Blue Ocean \uc124\uce58\\n\\nJenkins \uad00\ub9ac \u2192 Plugin Manager\uc5d0\uc11c Blue Ocean\uc744 \uac80\uc0c9\ud574 \uc124\uce58\ud55c\ub2e4.\\n\\n### \\\\[AWS IAM & EC2\\\\] IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30\\n\\nS3\uc640 Elastic Beanstalk\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc744 \ubd80\uc5ec\ud558\ub824\uba74 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk \ub450 \uac1c\uc758 \uc815\ucc45\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uc5ed\ud560\uc744 \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4. \\nIAM\uc5d0\uc11c \ub2e4\uc74c\uacfc \uac19\uc774 \uc5ed\ud560\uc744 \ud558\ub098 \uc0c8\ub85c \uc0dd\uc131\ud55c\ub2e4.\\n\\n1. \uc5d4\ud130\ud2f0 \uc120\ud0dd\\n\\n![aws-iam1](./aws-iam1.png)\\n\\n2. \uad8c\ud55c \ucd94\uac00\\n\\n![aws-iam2](./aws-iam2.png)\\n\\n3. \uc774\ub984 \uc9c0\uc815, \uac80\ud1a0 \ubc0f \uc0dd\uc131\\n\\n![aws-iam3](./aws-iam3.png)\\n\\n4. \uc0dd\uc131\ud55c IAM EC2 Jenkins \uc778\uc2a4\ud134\uc2a4\ub97c \uc120\ud0dd\ud558\uace0, \uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc744 \ub20c\ub7ec Role \uc124\uc815\\n\\n![aws-iam4](./aws-iam4.png)\\n\\n### \\\\[AWS S3\\\\] Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131\\n\\n\ubc84\ud0b7\uc744 \uc0dd\uc131\ud560 \ub54c \ub2e4\uc74c \uc124\uc815\uc744 \uc81c\uc678\ud558\uace0 \ubaa8\ub450 \ucc28\ub2e8 \ud65c\uc131\ud654\ub97c \ud574\uc900\ub2e4.\\n\\n- `\uc0c8 ACL(\uc561\uc138\uc2a4 \uc81c\uc5b4 \ubaa9\ub85d)\uc744 \ud1b5\ud574 \ubd80\uc5ec\ub41c \ubc84\ud0b7 \ubc0f \uac1d\uccb4\uc5d0 \ub300\ud55c \ud37c\ube14\ub9ad \uc561\uc138\uc2a4 \ucc28\ub2e8`\\n\\n![aws-s3](./aws-s3.png)\\n\\n### \\\\[Github\\\\] Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131\\n\\nrepo, user:email \uad8c\ud55c\uc774 \uc788\ub294 \ud1a0\ud070\uc774 \ud544\uc694\ud558\ub2e4. \\n\\n### \\\\[Jenkins\\\\] \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791\\n\\n![jenkins-blue-ocean1](./jenkins-blue-ocean1.png)\\n\\n\ube14\ub8e8 \uc624\uc158 \uc5f4\uae30\ub85c \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc0dd\uc131\ud55c\ub2e4. \\n\ud1a0\ud070 \uc785\ub825 \u2192 \uc870\uc9c1 \uc120\ud0dd \u2192 CI/CD \uc124\uc815\ud560 Repository \uc120\ud0dd\uc744 \ud558\uba74 \ud30c\uc774\ud504\ub77c\uc778 \ucc3d\uc73c\ub85c \ub118\uc5b4\uac04\ub2e4. \\nJenkinsfile\uc744 \uc9c1\uc811 \uc791\uc131\ud558\uc5ec \uc124\uc815\ud558\uae30 \uc704\ud574 \uac04\ub2e8\ud558\uac8c print \ud558\ub098 \ucd9c\ub825\ud558\ub294 \uac83\uc73c\ub85c \uc124\uc815\ud588\ub2e4. \\n\\n![jenkins-blue-ocean2](./jenkins-blue-ocean2.png)\\n\\n\ud30c\uc774\ud504\ub77c\uc778\uc774 \uc2e4\ud589\ub420 \ud150\ub370 pipeline status\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \ucd08\ub85d\ubd88\uc774 \ub728\uba74 \ub41c\ub2e4.\\n\\n![jenkins-blue-ocean3](./jenkins-blue-ocean3.png)\\n\\n### \\\\[Github Repsoitory\\\\] Jenkinsfile \uc124\uc815\\n\\n\ube14\ub8e8 \uc624\uc158 \uc2dc\uc791\uc744 \ud1b5\ud574 \uc124\uc815\ud558\uba74 Jenkinsfile\uc774 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc9c0\uace0, \uc544\ub798\uc640 \uac19\uc774 \uc6d0\ud558\ub294 \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc124\uc815\ud55c\ub2e4.\\n\\n```bash\\npipeline {\\n agent any\\n stages {\\n stage(\'build and test\') {\\n steps {\\n sh \'/gradlew clean build\'\\n }\\n }\\n stage(\'zip\') {\\n steps {\\n sh \'mv ./build/libs/woowachat.jar .\'\\n sh \'zip -r woowachat.zip .platform delivery.jar Procfile\'\\n }\\n }\\n stage(\'upload\') {\\n steps {\\n sh \'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2\'\\n }\\n }\\n stage(\'deploy\') {\\n steps {\\n sh \'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket=\\"woowa-chat\\",S3Key=\\"woowachat.zip\\"\'\\n sh \'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}\'\\n }\\n }\\n }\\n}\\n```\\n\\n### \\\\[Github\\\\] Webhooks \uc124\uc815\\n\\n![github-hook](./github-hook.png)\\n\\npush \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud560 \ub54c `http://Jenkins\uc8fc\uc18c/github-webhook/` \ub85c post request\ub97c \ud558\ub3c4\ub85d \uc6f9\ud6c5\uc744 \uc124\uc815\ud55c\ub2e4.\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[Install Jenkins - CentOS, Jenkins](https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos) \\n[Nginx Reverse Proxy Configuration, Jenkins](https://www.jenkins.io/doc/book/system-administration/reverse-proxy-configuration-nginx/) \\n[Amazon Corretto 17 JDK Install, AWS](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html) \\n[Amazon Linux 2023 packages, AWS](https://docs.aws.amazon.com/linux/al2023/release-notes/all-packages-al2023-20230419.html)"},{"id":"tecochat-retrospective-1","metadata":{"permalink":"/tecochat-retrospective-1","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx","source":"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx","title":"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30","description":"4\uc6d4 21\uc77c \uae08\uc694\uc77c","date":"2023-04-22T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 22\uc77c","tags":[{"label":"TecoChat","permalink":"/tags/teco-chat"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":5.68,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30","slug":"tecochat-retrospective-1","tags":["TecoChat","Retrospective"]},"prevItem":{"title":"Jenkins\ub85c CI/CD \uc124\uc815","permalink":"/jenkins"},"nextItem":{"title":"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c","permalink":"/book-leadership-and-self-deception"}},"content":"### 4\uc6d4 21\uc77c \uae08\uc694\uc77c\\n\\n\ub808\ubca8 2\ub97c \uc2dc\uc791\ud55c \ub4a4 \ub0b4\uac00 \ud559\uc2b5\uc5d0 \ub300\ud55c \ubc29\ud5a5\uc744 \uc783\uc5b4\ubc84\ub838\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4. \\n\ub808\ubca8 3, 4\uc5d0\uc11c \ub098\ub9cc\uc758 \uac15\uc810\uc744 \uac00\uc9c0\uace0 \uc2f6\uc5b4 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4. \\n\ub2e8\uc21c\ud788 \uc2a4\ud504\ub9c1\uc744 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ud6a8\uc728\uc774 \ub9ce\uc774 \ub5a8\uc5b4\uc9c4\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uae00\uc4f0\uae30 \uc218\uc0c1\uc73c\ub85c \ubc1b\uc740 \ucfe0\ud3f0\uc744 \uc0ac\uc6a9\ud574 \ube0c\ub77c\uc6b4\uc5d0\uac8c \ucee4\ud53c\ucc57\uc744 \uc2e0\uccad\ud588\uace0, \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud574\ubcf4\ub77c\ub294 \ub2f5\uc744 \ubc1b\uc558\ub2e4. \\n\\n\ub098\ub294 \uc544\uc774\ub514\uc5b4\ub97c \ubabb\ub0b4\ub294 \ud3b8\uc778\ub370 \ube0c\ub77c\uc6b4\uc774 \uc544\uc774\ub514\uc5b4\uae4c\uc9c0 \ub358\uc838\uc8fc\uc168\ub2e4. \\n`Chat-GPT \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uace0, \ud574\ub2f9 \ud06c\ub8e8\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc744 \uacf5\uc720\ud560 \uc218 \uc788\ub294 \uac74 \uc5b4\ub5a4\uc9c0?` \\n\\n\uae30\uc220\uc774 \ubaa9\uc801\uc778 \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4\ub294 \ub2f5\ubcc0\uc744 \ub4e4\uc5c8\uace0, \ud63c\uc790 \uc544\ub2c8\uba74 \ud398\uc5b4\ud560 \uc218 \uc788\uc744 \uc815\ub3c4\uc758 \uc778\uc6d0\uc73c\ub85c \uc9c4\ud589\ud558\uba74 \uc88b\uaca0\ub2e4\uace0 \ud558\uc168\ub2e4. \\n\ud504\ub860\ud2b8\ub791 \uac04\ub2e8\ud558\uac8c \ubc30\ud3ec\uae4c\uc9c0 \ud574\ubcf8 \uacbd\ud5d8\uc774 \uc788\uc5b4\uc11c \ud63c\uc790\ud574\ub3c4 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uc744 \uac83 \uac19\uc544\uc11c \ud63c\uc790 \ud558\uae30\ub85c \ub9c8\uc74c\uc744 \uba39\uc5c8\ub2e4. \\n\\n\uc774\uac74 \ubabb\ucc38\uc9c0\\n\\n### \ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?\\n\\n\ucee4\ud53c\ucc57\uc774 \ub05d\ub098\uace0 \uc9d1\uc73c\ub85c \ub3cc\uc544\uac00\ub294 \uae38\uc5d0 \ubc14\ub85c \ub3c4\uba54\uc778\uc744 \uad6c\ub9e4\ud558\ub824\uace0 namecheap\uc5d0\uc11c \uc801\ub2f9\ud55c \ub3c4\uba54\uc778\uc774 \uc5c6\uc744\uae4c \uac80\uc0c9\uc744 \uacc4\uc18d\ud588\ub2e4. \\n\ub9c8\uce58 \uc5b4\ub9b4 \ub54c \ud588\ub358 \uac8c\uc784 \ub2c9\ub124\uc784 \uc815\ud558\ub294 \uac83\ucc98\ub7fc \uc2dc\uac04\uc774 \uc624\ub798 \uac78\ub838\ub2e4. \\ndev, io, chat \ub3c4\uba54\uc778\uc774 \ud6c4\ubcf4\uc600\uace0 \uc9d1 \uac00\ub294 \uae38\uc5d0 \uacb0\uc815\ub9cc \ud558\ub2e4\uac00 \uad6c\ub9e4\ud558\uc9c0 \ubabb\ud588\ub2e4.\\n\\n### \ub9d0\ub791\uc758 DM\\n\\n\uc9d1\uc5d0 \uac00\uc11c \ubc25\uc744 \uba39\uace0 \ub9d0\ub791\uc774\ub791 DM \ud558\ub2e4 \ud504\ub85c\uc81d\ud2b8\ub97c \uac19\uc774 \ud558\uc790\ub294 \uc774\uc57c\uae30\uac00 \ub098\uc654\ub2e4. \\n\uc6b0\ud14c\ucf54 \ucd5c\uace0 \uace0\uc218 \ub9d0\ub791\uc758 \uc694\uad6c\ub77c \uc218\ub77d\ud558\uc9c0 \uc54a\uc73c\uba74 \ud6c4\ud3ed\ud48d\uc744 \uac10\ub2f9\ud560 \uc218 \uc5c6\uc5c8\ub2e4. \\n\\n\uc774\ub7f0\uc800\ub7f0 \ub300\ud654\ub97c \ub098\ub204\ub2e4\uac00 \ub09c \ube60\ub974\uac8c \ud504\ub85c\ud1a0\ud0c0\uc785\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\uace0 \uc2f6\uc5b4\uc11c \ud504\ub860\ud2b8\ub97c \uad6c\ud604\ud55c\ub2e4\uace0 \ud588\uace0, \ub9d0\ub791\uc740 GPT api\ub97c \uc870\uc0ac\ud558\uae30\ub85c \ud588\ub2e4. \\n\ucd94\uac00\ub85c \ub3c4\uba54\uc778\uc5d0 \uad00\ud55c \uc774\uc57c\uae30\ub97c \ud558\ub2e4\uac00 woowachat\uc774 \uc5b8\uae09\ub418\uc5c8\uace0, namecheap\uc5d0\uc11c chat \ub3c4\uba54\uc778\uc744 \uc0ac\uc6a9\ud55c woowa.chat\uc73c\ub85c \uad6c\ub9e4\ud588\ub2e4. \\n\uc774\ud6c4\uc5d0 teco.chat\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4!\\n\\n### \ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec\\n\\n\ud1a0\uc694\uc77c\uc5d0 \uad6c\ub9e4\ud55c \ub3c4\uba54\uc778\uc744 CDN, \ubcf4\uc548 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\ub294 Cloudflare\uc5d0 \ub3c4\uba54\uc778 \ub4f1\ub85d\uc744 \ud588\ub2e4. \\n\ub098\uc5d0\uac8c \uc775\uc219\ud55c Nuxt3\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\uace0, Cloudflare Pages\ub97c \uc774\uc6a9\ud558\uc5ec \ubc30\ud3ec\ud588\ub2e4. \\n\\n### GPT\\n\\n\ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud558\ub2c8 api limit\uc774 \uc788\uc5b4 \ubd84\ub2f9 3\ubc88\ubc16\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4. \\n\uc77c\ub2e8 \ubc31\uc5d4\ub4dc\ub97c \uad6c\ucd95\ud558\uae30 \uc804\uc5d0\ub294 \ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud560 \uc0dd\uac01\uc774\ub2e4. \\n\\n### Sonarcloud\\n\\n\uc815\uc801 \ucf54\ub4dc \ubd84\uc11d \ub3c4\uad6c\ub85c Sonarcloud\ub97c \uc801\uc6a9\ud588\ub2e4. \\nSonarcloud\ub294 SonarQube\uc758 SaaS \ubc84\uc804\uc774\uace0 \uc0ac\uc6a9\uc774 \ub9e4\uc6b0 \ud3b8\ud558\ub2e4. \\n\uc608\uc804\uc5d0 Sonarcloud\ub97c \uc0ac\uc6a9\ud560 \ub550 \ubc84\ud2bc \uba87 \ubc88 \ub204\ub974\uba74 \uc801\uc6a9\ud560 \uc218 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \ubc14\ub85c github action\uc744 \uc0ac\uc6a9\ud558\ub77c\ub294 \uc548\ub0b4 \ud398\uc774\uc9c0\ub85c \uc774\ub3d9\ud588\ub2e4. \\nSonarcloud\uac00 \uc790\uccb4\uc801\uc73c\ub85c github repository\uc5d0 push \ud558\uba74 \uc815\uc801 \ubd84\uc11d\uc744 \ud574\uc8fc\ub294 \uae30\ub2a5\uc744 \uc6d0\ud588\uace0, Administration -> Analysis Method\uc5d0 Automatic Analysis\ub97c \uc124\uc815\ud558\ub2c8 \ub418\uc5c8\ub2e4. \\n\ub108\ubb34 \uaf41\uaf41 \uc228\uaca8\uc838\uc788\ub124\\n\\n### Tiptap\\n\\n\ucf54\ub4dc \ud558\uc774\ub77c\uc774\ud305 \uae30\ub2a5\uc744 \ub123\uace0 \uc2f6\uc5b4\uc11c Tiptap\uc744 \uc0ac\uc6a9\ud588\ub2e4. \\nTiptap\uc740 Headless WYSIWYG \uc5d0\ub514\ud130\ub85c \uc0ac\uc6a9\uc790 \uc815\uc758 \uae30\ub2a5\uc5d0 \ud2b9\ud654\ub418\uc5b4\uc788\ub294 \uc5d0\ub514\ud130\ub2e4. \\n\uc544\uc9c1 Tiptap\uc774 \uc81c\uacf5\ud558\ub294 \ubaa8\ub4e0 \uae30\ub2a5\uc744 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc0ac\uc6a9\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc CodeBlockLowlight \ud50c\ub7ec\uadf8\uc778\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucf54\ub4dc \ube14\ub85d\uc744 \uc608\uc058\uac8c \ucd9c\ub825\ud560 \uc218 \uc788\uc5c8\ub2e4. \\napi \ubc18\ud658\uac12 \uadf8\ub300\ub85c tiptap\uc758 content\uc5d0 \uc124\uc815\ud588\ub354\ub2c8 \ucf54\ub4dc \ube14\ub85d\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc544\uc11c \ubc31 \ud2f1 3\uac1c\ub97c `<pre><code>`\ub85c \ubcc0\ud658\ud588\ub2e4. \\n\ucd94\uac00\ub85c \ub744\uc5b4\uc4f0\uae30\ub3c4 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc544\uc11c `\\\\n`\ub97c `<br>`\ud0dc\uadf8\ub85c \ubcc0\ud658\ud588\ub2e4. \\n\ubcc0\ud658\ud558\ub294 \ub85c\uc9c1\uc740 GPT\uc758 \ub3c4\uc6c0\uc744 \ub9ce\uc774 \ubc1b\uc558\ub2e4. \\n\\n```ts\\nconst replaceCodeFences = (input: String) => {\\n const codeFencesRegex = /```([\\\\w-]*)\\\\n([\\\\s\\\\S]*?)\\\\n```/g;\\n return input\\n .replace(codeFencesRegex, (match, p1, p2) => {\\n const languageClass = p1 ? ` class=\\"language-${p1}\\"` : \\"\\";\\n return `<pre><code${languageClass}>${p2}</code></pre>`;\\n })\\n .replace(/\\\\n/g, \\"<br>\\");\\n};\\n```\\n\\nTiptap\uc744 \uc801\uc6a9\ud558\ub2c8 \ub2e4\uc74c\uacfc \uac19\uc774 \uae54\ub054\ud55c \ucf54\ub4dc \ube14\ub85d\uc744 \ubcfc \uc218 \uc788\uc5c8\ub2e4. \\n\\n![tecochat](./teco-chat.png)\\n\\n### \ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9\\n\\n\ud0c0\uc774\ud2c0\uc740 \ubc30\ub2ec\uc758\ubbfc\uc871 \ub3c4\ud604\uccb4, \ub0b4\uc6a9\uc740 IBM Plex Sans\ub97c \uc0ac\uc6a9\ud588\ub2e4. \\n\ucd94\uac00\ub85c favicon\ub3c4 \uac04\ub2e8\ud558\uac8c \uc801\uc6a9\ud574\uc11c \ub9cc\uc871\uc2a4\ub7ec\uc6e0\ub2e4."},{"id":"book-leadership-and-self-deception","metadata":{"permalink":"/book-leadership-and-self-deception","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx","source":"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx","title":"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c","description":"\ucc45 \uc815\ubcf4","date":"2023-04-08T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 8\uc77c","tags":[{"label":"Book","permalink":"/tags/book"}],"readingTime":5.16,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c","slug":"book-leadership-and-self-deception","tags":["Book"]},"prevItem":{"title":"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30","permalink":"/tecochat-retrospective-1"},"nextItem":{"title":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","permalink":"/innodb-lock"}},"content":"### \ucc45 \uc815\ubcf4\\n\\n> \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c \\n> \uc544\ube48\uc800\uc5f0\uad6c\uc18c\\n> \\n\\n### \uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18\\n\\n\ucc45\uc5d0\uc11c\ub294 \uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc744 \ub2e4\ub8ec\ub2e4. \\n- \uc790\uae30\uae30\ub9cc: \uc790\uc2e0\uc758 \ubb38\uc81c\ub97c \uc778\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 \\n- \uc790\uae30\ubc30\ubc18: \ub2e4\ub978 \uc0ac\ub78c\uc744 \uc704\ud574 \ubb34\uc5b8\uac00 \ud574\uc57c\ub9cc \ud55c\ub2e4\ub294 \uc0dd\uac01\uc744 \ubc18\ud558\ub294 \ud589\uc704\\n\\n\uc790\uae30\ubc30\ubc18\uc744 \ud55c\ub2e4\uba74 \uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uac00 \ub41c\ub2e4. \\n\uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uc5d0 \ube60\uc9c0\ub294 \uac83\uc744 \ucc45\uc5d0\uc11c\ub294 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac04\ub2e4\uace0 \ud45c\ud604\ud55c\ub2e4. \\n\\n### \uc77d\uace0 \ub098\uc11c\\n\\n\ucd5c\uadfc\uc5d0 \uc77d\uc740 \ucc45 \uc911 \uac00\uc7a5 \ub9c8\uc74c\uc774 \ubd88\ud3b8\ud588\ub2e4. \\n\uadf8\ub807\uae30\uc5d0 \ub354\ub354\uc6b1 \ub098\uc5d0\uac8c \ud544\uc694\ud55c \ub0b4\uc6a9\uc774 \ub2f4\uaca8\uc788\uc5c8\ub2e4. \\n\\n\uc0b4\uba74\uc11c \ub9ce\uc740 \uc120\ud0dd\uc758 \uc21c\uac04\uc774 \uc874\uc7ac\ud588\uace0, \uadf8 \uc21c\uac04\ub9c8\ub2e4 \uc790\uae30\ubc30\ubc18\uc744 \ud0dd\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4. \\n\uc791\uac8c\ub294 \uc9d1\uc548\uc77c\uc744 \ud574\uc57c \ud558\ub294\ub370 \ubab8\uc774 \uc870\uae08 \ud798\ub4e4\ub2e4\uace0 \ud558\uc9c0 \uc54a\uac70\ub098 \\n\ud06c\uac8c\ub294 \uc798\ubabb\uc744 \uc778\uc815\ud574\uc57c \ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uadf8\ub7ec\uc9c0 \uc54a\uc740 \uacbd\uc6b0\uac00 \uc788\uc5c8\ub2e4. \\n\uc774\ub7f0 \uc0c1\ud669\uc774 \ubc18\ubcf5\ub418\uc5b4 \uacb0\uad6d \uc0c1\uc790 \uc548\uc5d0 \ub098 \uc790\uc2e0\uc744 \uac00\ub450\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4. \\n\\n\ub354 \ub098\uc740 \uc0b6\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \uc9c0\uc18d\uc801\uc73c\ub85c \ud655\uc778\ud558\uace0, \uc0c1\uc790 \ubc16\uc73c\ub85c \ub098\uac00\ub824\ub294 \uc5f0\uc2b5\uc744 \ud574\uc57c\uaca0\ub2e4. \\n\ub113\uc740 \uc2dc\uc120\uc744 \uac00\uc9c0\uace0, \ud56d\uc0c1 \ub0b4\uac00 \ud2c0\ub9b4 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc0dd\uac01\ud558\uace0 \uc0b4\uc544\uac00\uc790. \\n\\n### \ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4\\n\\n> \uc6b0\ub9ac\uc758 \uc0dd\uac01\uc740 \uc9c0\uc2dd\ubcf4\ub2e4 \uc791\ub2e4. \\n\uc6b0\ub9ac\uc758 \uc9c0\uc2dd\uc740 \uc0ac\ub791\ubcf4\ub2e4 \uc791\ub2e4. \\n\uc6b0\ub9ac\uc758 \uc0ac\ub791\uc740 \uc874\uc7ac\ubcf4\ub2e4 \uc791\ub2e4. \\n\uadf8\ub9ac\uace0 \uc6b0\ub9ac\uac00 \uc0dd\uac01\ud558\ub294 \ub098\ub294 \uc2e4\uc81c\uc758 \ub098\ubcf4\ub2e4 \uadf8\ub9cc\ud07c \uc791\ub2e4. \\nR. D. \ub7ad \\np.19\\n>\\n\\n> \uc6b0\ub9ac\uac00 \uc678\uc801\uc73c\ub85c \uc5b4\ub5a4 \ud589\ub3d9\uc744 \ud558\ub4e0\uc9c0 \uac04\uc5d0, \uc0ac\ub78c\ub4e4\uc740 \uc6b0\ub9ac \ub9c8\uc74c\uc5d0\uc11c \uadf8\ub4e4\uc744 \uc5b4\ub5bb\uac8c \ub300\ud558\uace0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \uc8fc\ub85c \ubc18\uc751\ud569\ub2c8\ub2e4. \\n\uc6b0\ub9ac\uac00 \uc0ac\ub78c\ub4e4\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \ub290\ub07c\uac8c \ub418\ub294\uc9c0\ub294 \uc6b0\ub9ac\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \ud639\uc740 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \ub2ec\ub77c\uc9c0\uac8c \ub429\ub2c8\ub2e4. \\np.66\\n>\\n\\n> \ube44\ub09c\uc740 \uac10\uc815\uc5d0 \uc18d\ud558\uace0 \ub099\uad00\uc740 \uc758\uc9c0\uc5d0 \uc18d\ud55c\ub2e4. \\n\uc778\uac04\uc740 \uac10\uc815\ubcf4\ub2e4 \ub354 \ud070 \uc874\uc7ac\uc774\ub2e4. \\n\uc54c\ub7ad, \ud0c1\ub2db\ud55c \\np.103\\n>\\n\\n> \uc6b0\ub9ac\uac00 \uc790\uc2e0\uc5d0\uac8c\ub9cc \uc9d1\uc911\ud558\uace0 \uc788\ub294 \ud55c, \ud63c\uc790\uc11c \uc77c\ud558\ub294 \uac83 \uc774\uc0c1\uc758 \ucc3d\uc870\uc801\uc778 \uacb0\uacfc\ub098 \ud611\ub825\uc744 \uc774\ub04c\uc5b4 \ub0b8\ub2e4\ub294 \uac83\uc740 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4. \\n\uc624\ub298\ub0a0 \uacbd\uc81c \ud658\uacbd\uc5d0\uc11c\ub294 \ud63c\uc790\uc11c\ub294 \uc77c\uc758 \uacb0\uacfc\ub97c \ud0c1\uc6d4\ud558\uac8c \ub9cc\ub4e4\uc5b4 \ub0b4\uae30\uac00 \uc5b4\ub835\uc2b5\ub2c8\ub2e4. \\n\ub0b4\uac00 \uc911\uc2ec\uc774\uc5b4\uc57c \ub41c\ub2e4\ub294 \ud3d0\uc1c4\uc801\uc778 \uc0ac\uace0\ub294 \ud568\uaed8 \uc77c\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uc5f4\uc815\uc744 \ubd88\ub7ec\uc624\uc9c0 \ubabb\ud569\ub2c8\ub2e4. \\np.175\\n> \\n\\n> \uc194\uc9c1\ud568\uc740 \uc6b0\ub9ac\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\ub294 \uc5f4\uc1e0\uc785\ub2c8\ub2e4. \\n\uadf8\uac83\uc740 \uc790\uc2e0\uc758 \ud589\ub3d9\uacfc \uad00\ub828\ub41c \uc0ac\ub78c\uc5d0 \ub300\ud574 \uae30\uaebc\uc774 \uc0ac\uacfc\ub97c \ud558\ub294 \uac83\uc785\ub2c8\ub2e4. \\n\uadf8\uac83\ub9cc\uc774 \uc2e4\ud0c0\ub798\ucc98\ub7fc \uc5c9\ud0a8 \uad00\uacc4\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc774\uc8e0. \\np.188\\n> \\n\\n> \ub204\uad70\uac00\ub97c \ub098\uc640 \uac19\uc774 \ub3d9\uc77c\ud55c \uac00\uce58\ub97c \uc9c0\ub2cc \ud55c \uc778\uac04\uc73c\ub85c \uc0dd\uac01\ud574\uc11c \uadf8 \uc0ac\ub78c\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \ubc16\uc5d0 \uacc4\uc18d \uba38\ubb34\ub974\uace0 \uc2f6\uc740 \uc5f4\ub9dd\uc774 \uc0dd\uae38 \ub54c, \ub098\ub294 \uc774\ubbf8 \uadf8 \uc0ac\ub78c\uc5d0 \ub300\ud574 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub2e4. \\np.214\\n> \\n\\n> \ub300\ubd80\ubd84\uc758 \uc0ac\ub78c\ub4e4\uc774 \uad00\uacc4 \uae30\uc220\uc744 \uac00\uc9c0\uace0 \uadf8\ub4e4\uc774 \uacaa\uace0 \uc788\ub294 \ubb38\uc81c\ub97c \ubc14\ub85c\uc7a1\uc73c\ub824\uace0 \ud558\ub294 \ub178\ub825\uc774 \uacb0\uc2e4\uc744 \uc5bb\uc9c0 \ubabb\ud558\ub294 \uac83\uc740 \uacb0\ucf54 \uadf8\ub7ec\ud55c \uae30\uc220 \ubd80\uc871 \ub54c\ubb38\uc5d0 \uc0dd\uae30\ub294 \uac83\uc774 \uc544\ub2d9\ub2c8\ub2e4. \\n\uadf8\uac83\ub4e4\uc740 \uc790\uae30\ubc30\ubc18 \ub54c\ubb38\uc5d0 \uc0dd\uaca8\ub0a9\ub2c8\ub2e4. \\np.224\\n>\\n\\n> \uc6b0\ub9ac\ub294 \ud568\uaed8 \uc77c\ud558\uace0 \uc6b0\ub9ac\uc640 \ud568\uaed8 \uc0b4\uc544\uac00\ub294 \uc0ac\ub78c\uc774 \uc9c4\uc815\uc73c\ub85c \ub204\uad6c\uc778\uc9c0 \uc54c\uc9c0 \ubabb\ud569\ub2c8\ub2e4. \\n\uc6b0\ub9ac\uac00 \uadf8\ub4e4\uacfc \uc9c4\uc815\uc73c\ub85c \ud568\uaed8 \uc18c\ud1b5\ud558\uae30 \uc804\uae4c\uc9c0\ub294 \uc6b0\ub9ac\ub294 \uadf8\ub4e4\uc758 \uac00\uce58\ub97c \uc798 \ubaa8\ub985\ub2c8\ub2e4. \\n\uc6b0\ub9ac\uc758 \uc704\ub300\ud568\uc774\ub780 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc758 \uc704\ub300\ud55c \uc810\uc744 \ubc1c\uacac\ud574 \uc8fc\ub294 \uac83\uc5d0 \uc788\uc2b5\ub2c8\ub2e4. \\np.280\\n>"},{"id":"innodb-lock","metadata":{"permalink":"/innodb-lock","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx","source":"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx","title":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","description":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","date":"2023-04-07T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 7\uc77c","tags":[{"label":"DataBase","permalink":"/tags/data-base"},{"label":"Lock","permalink":"/tags/lock"},{"label":"InnoDB","permalink":"/tags/inno-db"}],"readingTime":5.805,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","slug":"innodb-lock","tags":["DataBase","Lock","InnoDB"]},"prevItem":{"title":"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c","permalink":"/book-leadership-and-self-deception"},"nextItem":{"title":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","permalink":"/mysql-lock"}},"content":"## InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08\\n\\nMySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08\uacfc \ubcc4\uac1c\ub85c \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub0b4\ubd80\uc5d0\uc11c \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4. \\n\ubcf4\ud1b5 \uba85\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\ub294 \ub4dc\ubb3c\uace0, \uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ubb35\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc774 \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n\ub3d9\uc2dc\uc131 \uc81c\uc5b4 \ubc29\uc2dd\uc5d0\ub294 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uacfc \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc774 \uc788\ub2e4. \\nInnoDB\ub294 \uae30\ubcf8\uc801\uc73c\ub85c MVCC(\ub2e4\uc911 \ubc84\uc804 \ub3d9\uc2dc\uc131 \uc81c\uc5b4)\ub97c \ud1b5\ud574 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uace0 \ub77d\uc744 \ud1b5\ud574 \ud2b9\uc815 \uc0c1\ud669\uc5d0\uc11c \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n:::note \ub099\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(OCC, Optimistic concurrency control)\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \uc11c\ub85c \ucda9\ub3cc\ud558\uc9c0 \uc54a\ub294\ub2e4\uace0 \uac00\uc815\ud558\ub294 \ubc29\uc2dd \\n\\n:::\\n\\n:::note \ube44\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(PCC, Pessimistic Concurrency Control)\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \ucda9\ub3cc\ud558\ub294 \uac00\uc815\ud558\uc5d0 \uc7a0\uae08\uc744 \uac70\ub294 \ubc29\uc2dd \\n\uc77c\ubc18\uc801\uc73c\ub85c\xa0Shared Lock, Exclusive Lock\uc744 \ud1b5\ud574 \uc774\ub97c \uad6c\ud604\ud55c\ub2e4.\\n\\n:::\\n\\n### Shared & Exclusive Locks\\n\\nInnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc218\ud589\ud560 \ub54c \uacf5\uc720 \uc7a0\uae08\uacfc \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n**\uacf5\uc720 \uc7a0\uae08(S, shared lock)**\\n\\n\ub370\uc774\ud130 \uc870\ud68c\ub97c \uc704\ud55c \ub77d, \uc77d\uae30 \uc7a0\uae08(read lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4. \\n\ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uae30\uac00 \uac00\ub2a5\ud558\uc9c0\ub9cc, \uc4f0\uae30\ub294 \ubd88\uac00\ub2a5\ud558\ub2e4. \\n\uc608) `SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;`\\n\\n**\ubc30\ud0c0\uc801 \uc7a0\uae08(X, exclusive lock)** \\n\\n\ub370\uc774\ud130 \ubcc0\uacbd\uc744 \uc704\ud55c \ub77d, \uc4f0\uae30 \uc7a0\uae08(write lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4. \\n\ub77d\uc744 \uac74 \ud2b8\ub79c\uc7ad\uc158\ub9cc\uc774 \ud574\ub2f9 \ub370\uc774\ud130\uc5d0 \uc811\uadfc \uac00\ub2a5\ud558\ub2e4. \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \uc77d\uae30, \uc4f0\uae30\uac00 \ubd88\uac00\ub2a5\ud558\ub2e4. \\n\uc608) `SELECT * FROM table_name WHERE id = 1 FOR UPDATE;`\\n\\n### Intention Locks\\n\\nInnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uacfc \ud14c\uc774\ube14 \uc7a0\uae08\uc758 \uacf5\uc874\uc744 \uc704\ud574 \uc778\ud14d\uc158 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4. \\n\ud14c\uc774\ube14\uc5d0 \uc788\ub294 \ub85c\uc6b0\uc5d0 \ub300\ud574\uc11c \ub098\uc911\uc5d0 \uc694\uccad\ub418\ub294 \uac83\uc774 \uc5b4\ub5a4 \ud615\ud0dc\uc758 \uc7a0\uae08\uc778\uc9c0 \uac00\ub9ac\ud0a4\uae30 \uc704\ud574 \uc0ac\uc6a9\ub41c\ub2e4. \\n\uae30\ubcf8\uc801\uc73c\ub85c \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uc744 \uc218\ud589\ud558\uae30 \uc804\uc5d0 \uc778\ud150\uc158 \uc7a0\uae08\uc744 \uba3c\uc800 \ud68d\ub4dd\ud55c\ub2e4. \\n\uc778\ud150\uc158 \ub77d\uc740 \uae30\ubcf8\uc801\uc73c\ub85c \ucda9\ub3cc\uc744 \ubc29\uc9c0\ud558\uace0 \ub370\ub4dc\ub77d\uc744 \ubc29\uc9c0\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. \\n\\n**\uc778\ud150\uc158 \uacf5\uc720 \uc7a0\uae08(IS, intention shared lock)**\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \uacf5\uc720 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.\\n\\n**\uc778\ud150\uc158 \ubc30\ud0c0\uc801 \uc7a0\uae08(IX, intention exclusive lock)** \\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.\\n\\n** \uc7a0\uae08\uac04\uc758 \ud638\ud658\uc131 **\\n\\n| | X | IX | S | IS |\\n| --- | --- | --- | --- | --- |\\n| X | Conflict | Conflict | Conflict | Conflict |\\n| IX | Conflict | Compatible | Conflict | Compatible |\\n| S | Conflict | Conflict | Compatible | Compatible |\\n| IS | Conflict | Compatible | Compatible | Compatible |\\n\\n### Record Locks\\n\\n\ub808\ucf54\ub4dc \uc790\uccb4\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4. \\nInnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc740 \ub808\ucf54\ub4dc \uc790\uccb4\uac00 \uc544\ub2c8\ub77c \uc778\ub371\uc2a4\uc758 \ub808\ucf54\ub4dc\ub97c \uc7a0\uadfc\ub2e4. \\n\\n### Gap Locks\\n\\n\ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4. \\n\ub808\ucf54\ub4dc\uc640 \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\uc5d0 \uc0c8\ub85c\uc6b4 \ub808\ucf54\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc744 \uc81c\uc5b4\ud558\uace0, \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc758 \uc77c\ubd80\ub85c \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n### Next-Key Locks\\n\\n\ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4. \\n`REPEATABLE READ` \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ud32c\ud140 \ub9ac\ub4dc\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud55c \uc7a0\uae08\uc774\ub2e4. \\n\\n### AUTO-INC Locks\\n\\n`AUTO_INCREMENT` \uce7c\ub9bc\uc774 \uc0ac\uc6a9\ub41c \ud14c\uc774\ube14\uc5d0 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \ub808\ucf54\ub4dc\uac00 `INSERT`\ub418\ub294 \uacbd\uc6b0, \uac01 \ub808\ucf54\ub4dc\ub294 \uc911\ubcf5\ub418\uc9c0 \uc54a\uace0 \uc800\uc7a5\ub41c \uc21c\uc11c\ub300\ub85c \uc99d\uac00\ud558\ub294 \uc77c\ub828\ubc88\ud638 \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4. \\nInnoDB \ub294 \ub0b4\ubd80\uc801\uc73c\ub85c AUTO-INC \ub77d\uc774\ub77c\uace0 \ud558\ub294 \ud14c\uc774\ube14 \uc218\uc900\uc758 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158\uacfc \uad00\uacc4 \uc5c6\uc774 `INSERT`\ub098 `REPLACE` \ubb38\uc7a5\uc5d0\uc11c `AUTO_INCREMENT` \uac12\uc744 \uac00\uc838\uc624\ub294 \uc21c\uac04\ub9cc \ub77d\uc774 \uac78\ub838\ub2e4\uac00 \ud574\uc81c\ub41c\ub2e4.\\n\\n### \uc7a0\uae08 \uc608\uc2dc\\n\\n```sql\\n-- \ub808\ucf54\ub4dc\ub294 id \uae30\uc900 10, 20, 30, 40, 50\uc774 \uc788\ub2e4\uace0 \uac00\uc815\\n-- Record Locks: 10\uc5d0 \ub300\ud574 \ub77d\uc774 \uac78\ub9b0\ub2e4.\\nSELECT * FROM table_name where id = 10 for update;\\n\\n-- Gap Locks: 51\ubd80\ud130 PositiveInfinity\uae4c\uc9c0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\\nSELECT * FROM table_name where id > 100 for update;\\n\\n-- Next-Key Locks: 21\ubd80\ud130 30, 31\ubd80\ud130 40\uc5d0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\\nSELECT * FROM table_name where id BETWEEN 25 AND 35 for update;\\n```\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\nReal My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1 \\n[Optimistic and Pessimistic record locking, IBM](https://www.ibm.com/docs/en/rational-clearquest/9.0.0?topic=clearquest-optimistic-pessimistic-record-locking) \\n[MySQL Innodb Locks, cecil1018](https://cecil1018.wordpress.com/2016/06/18/mysql-innodb-locks/) \\n[MySQL 8.0 InnoDB Locks, MySQL](https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html) \\n[Locks Set by Different SQL Statements in InnoDB, MySQL](https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html)"},{"id":"mysql-lock","metadata":{"permalink":"/mysql-lock","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx","source":"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx","title":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","description":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","date":"2023-04-06T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 6\uc77c","tags":[{"label":"DataBase","permalink":"/tags/data-base"},{"label":"Lock","permalink":"/tags/lock"},{"label":"MySQL","permalink":"/tags/my-sql"}],"readingTime":4.405,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","slug":"mysql-lock","tags":["DataBase","Lock","MySQL"]},"prevItem":{"title":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","permalink":"/innodb-lock"},"nextItem":{"title":"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900","permalink":"/transaction-and-isolation"}},"content":"## MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08\\n\\nMySQL\uc5d0\uc11c\uc758 \ub77d\uc740 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub808\ubca8\uacfc, MySQL \uc5d4\uc9c4 \ub808\ubca8\ub85c \ub098\ub20c \uc218 \uc788\ub2e4. \\nMySQL \uc5d4\uc9c4 \ub808\ubca8\uc758 \uc7a0\uae08\uc740 \ubaa8\ub4e0 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce5c\ub2e4. \\n\\n### \uae00\ub85c\ubc8c \ub77d(Global lock)\\n\\nMySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08 \uc911 \uac00\uc7a5 \ub113\uc740 \ubc94\uc704\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \uc7a0\uae08\uc774\ub2e4. \\n - \uc601\ud5a5\uc744 \ubbf8\uce58\ub294 \ubc94\uc704\ub294 \ud574\ub2f9 \uc11c\ubc84 \uc804\uccb4\uc774\ub2e4.\\n - \uc791\uc5c5 \ub300\uc0c1 \ud14c\uc774\ube14, \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0c1\uad00 \uc5c6\uc774 \ub3d9\uc77c\ud558\uac8c \uc601\ud5a5\uc744 \ubc1b\ub294\ub2e4.\\n\\n\ud55c \uc138\uc158\uc5d0\uc11c \uae00\ub85c\ubc8c \ub77d\uc744 \ud68d\ub4dd\ud558\uba74 \ud574\uc81c \ub420 \ub54c \uae4c\uc9c0 \uc870\ud68c\ub97c \uc81c\uc678\ud55c \ub300\ubd80\ubd84\uc758 \uba85\ub839\uc774 \ub300\uae30 \uc0c1\ud0dc\uac00 \ub41c\ub2e4. \\n\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc874\uc7ac\ud558\ub294 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub300\ud574 \uc77c\uad00\ub41c \ubc31\uc5c5\uc744 \ubc1b\uc544\uc57c\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4. \\nInnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c\ub294 \ubc31\uc5c5 \uc2dc \uc870\uae08 \ub354 \uac00\ubcbc\uc6b4 \ubc31\uc5c5 \ub77d\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. \\n\\n```sql\\n-- GLOBAL LOCK\\nFLUSH TABLES WITH READ LOCK;\\n-- UNLOCK\\nUNLOCK TABLES;\\n\\n-- BACKUP LOCK\\nLOCK INSTANCE FOR BACKUP;\\n-- UNLOCK\\nUNLOCK INSTANCE;\\n```\\n\\n:::note MyISAM\\n\\nMySQL 5.5 \ubc84\uc804 \uc774\uc804\uc758 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uace0, SELECT \uc791\uc5c5 \uc18d\ub3c4\uac00 \ube60\ub974\ub2e4.\\n\\n:::\\n\\n### \ud14c\uc774\ube14 \ub77d(Table lock)\\n\\n\uac1c\ubcc4 \ud14c\uc774\ube14 \ub2e8\uc704\ub85c \uc124\uc815\ub418\ub294 \uc7a0\uae08\uc774\ub2e4. \\n\uba85\uc2dc\uc801 \ub610\ub294 \ubb35\uc2dc\uc801\uc73c\ub85c \ud2b9\uc815 \ud14c\uc774\ube14\uc758 \ub77d\uc744 \ud68d\ub4dd\ud560 \uc218 \uc788\ub2e4. \\n\ubb35\uc2dc\uc801 \ub77d\uc740 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub294 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uba74 \ubc1c\uc0dd\ud55c\ub2e4. \\nInnoDB \ud14c\uc774\ube14\uc5d0\ub294 DML \ucffc\ub9ac\ub294 \ubb34\uc2dc\ub418\uace0 DDL \uc77c \uacbd\uc6b0\uc5d0\ub9cc \ubb35\uc2dc\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud55c\ub2e4.\\n\\n```sql\\n-- TABLE LOCK\\nLOCK TABLES table_name [ READ | WRITE ]\\n\\n-- UNLOCK\\nUNLOCK TABLES;\\n```\\n\\n### \ub124\uc784\ub4dc \ub77d(Named lock)\\n\\n\uc784\uc758\uc758 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \uc124\uc815\ud560 \uc218 \uc788\ub294 \uc7a0\uae08\uc73c\ub85c \uc720\uc800 \ub808\ubca8 \ub77d\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4. \\n\uc5ec\ub7ec \uc2a4\ub808\ub4dc\ub098 \ud504\ub85c\uc138\uc2a4\uac00 \ub3d9\uc77c\ud55c \ub370\uc774\ud130\ub97c \uc218\uc815\ud558\ub824\ub294 \uacbd\uc6b0, \ub3d9\uc2dc\uc5d0 \uc218\uc815\ud558\uc9c0 \ubabb\ud558\ub3c4\ub85d \ubcf4\ud638\ud560 \uc218 \uc788\ub2e4. \\n\\n```sql\\n-- aGVyYg== \ub77c\ub294 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08 \ud68d\ub4dd, \uc774\ubbf8 \uc7a0\uae08\uc744 \uc0ac\uc6a9\uc911\uc778 \uacbd\uc6b0 1\ucd08 \ub3d9\uc548\ub9cc \ub300\uae30\\nSELECT GET_LOCK(\'aGVyYg==\', 1);\\n\\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc774 \uc124\uc815\ub418\uc5b4 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.\\nSELECT IS_FREE_LOCK(\'aGVyYg==\');\\n\\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4.\\nSELECT RELEASE_LOCK(\'aGVyYg==\');\\n\\n-- \uc704 3\uac1c \ud568\uc218 \ubaa8\ub450 \uc815\uc0c1\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud558\uac70\ub098 \ud574\uc81c\ud55c \uacbd\uc6b0\uc5d0 1\uc744, \uc544\ub2c8\uba74 0\uc744 \ubc18\ud658\ud55c\ub2e4.\\n\\n-- \ubaa8\ub4e0 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4. \ud574\uc81c\ub41c \uc7a0\uae08\uc758 \uac1c\uc218\ub97c \ubc18\ud658\ud55c\ub2e4.\\nSELECT RELEASE_ALL_LOCKS();\\n```\\n\\n### \uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)\\n\\n\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac1d\uccb4\uc758 \uc774\ub984\uc774\ub098 \uad6c\uc870\ub97c \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \ud68d\ub4dd\ud558\ub294 \uc7a0\uae08\uc774\ub2e4. \\n\uba85\uc2dc\uc801\uc73c\ub85c \ud68d\ub4dd \ub610\ub294 \ud574\uc81c \ud560 \uc218 \uc5c6\uc9c0\ub9cc \ud14c\uc774\ube14\uc758 \uc774\ub984\uc744 \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4. \\n\ubcf4\ud1b5 \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc2e4\uc2dc\uac04\uc73c\ub85c \ud14c\uc774\ube14\uc744 \ubc14\uafd4\uc57c\ud558\ub294 \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\ub41c\ub2e4.\\n\\n```sql\\n-- \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \ubcc4\ub3c4\uc758 \uc784\uc2dc \ud14c\uc774\ube14\uc5d0 \uc11c\ube44\uc2a4\uc6a9 \ub7ad\ud0b9 \ub370\uc774\ud130 \uc0dd\uc131 \ud6c4 \uae30\uc874 \ud14c\uc774\ube14\uc744 \ubc31\uc5c5\ud558\ub294 \uacbd\uc6b0\\n-- \uc544\ub798 \uad6c\ubb38 \uc2e4\ud589 \uc2dc \uba54\ud0c0\ub370\uc774\ud130 \ub77d\uc744 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.\\nRENAME TABLE rank TO rank_backup, rank_new TO rank;\\n```\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\nReal My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1 \\n[MySQL\uc758 User Level Lock\ub97c \ud65c\uc6a9\ud55c\ub2e4\uba74?, gywndi](https://gywn.net/2013/12/mysql-user-level-lock/) \\n[Locking Functions, MySQL 5.7 Reference](https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html#function_release-all-locks) \\n[Locking Functions, MySQL 8.0 Reference](https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_release-all-locks)"},{"id":"transaction-and-isolation","metadata":{"permalink":"/transaction-and-isolation","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx","source":"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx","title":"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900","description":"\ud2b8\ub79c\uc7ad\uc158(Transaction)","date":"2023-04-05T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 5\uc77c","tags":[{"label":"DataBase","permalink":"/tags/data-base"},{"label":"Transaction","permalink":"/tags/transaction"},{"label":"Isolation","permalink":"/tags/isolation"}],"readingTime":9.57,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900","slug":"transaction-and-isolation","tags":["DataBase","Transaction","Isolation"]},"prevItem":{"title":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","permalink":"/mysql-lock"},"nextItem":{"title":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed","permalink":"/test-double"}},"content":"## \ud2b8\ub79c\uc7ad\uc158(Transaction)\\n\\n\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \ub17c\ub9ac\uc801 \uae30\ub2a5\uc744 \uc218\ud589\ud558\uae30 \uc704\ud55c \uc791\uc5c5\uc758 \ub2e8\uc704\ub97c \ub9d0\ud55c\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158\uc740 \uc791\uc5c5\uc758 \uc644\uc804\uc131\uacfc \ub370\uc774\ud130\uc758 \uc815\ud569\uc131\uc744 \ubcf4\uc7a5\ud574 \uc900\ub2e4. \\n\ub17c\ub9ac\uc801\uc778 \uc791\uc5c5 \uc14b\uc744 \uc644\ubcbd\ud558\uac8c \ucc98\ub9ac\ud558\uac70\ub098, \uc624\ub958 \uc2dc \uc791\uc5c5\uc758 \uc77c\ubd80\ub9cc \uc801\uc6a9\ub418\ub294 \ud604\uc0c1\uc744 \ub9c9\uc544\uc900\ub2e4. \\n\\n### \ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)\\n\\n\uc6d0\uc790\uc131(Atomicity): \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \uc2e4\ud589\ub41c \uc791\uc5c5\ub4e4\uc740 \ubaa8\ub450 \uc131\uacf5\ud558\uac70\ub098, \uc2e4\ud328\ud574\uc57c \ud55c\ub2e4. \\n\uc77c\uad00\uc131(Consistency): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc218\ud589\ub418\uae30 \uc804\uacfc \ud6c4\uc5d0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc77c\uad00\ub41c \uc0c1\ud0dc\ub97c \uc720\uc9c0\ud574\uc57c \ud55c\ub2e4. \\n\uaca9\ub9ac\uc131(Isolation): \uac01\uac01\uc758 \ud2b8\ub79c\uc7ad\uc158\uc740 \ub3c5\ub9bd\uc801\uc774\ub77c \uc11c\ub85c\uc5d0\uac8c \uc601\ud5a5\uc744 \uc8fc\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4. \\n\uc9c0\uc18d\uc131(Durability): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc131\uacf5\uc801\uc73c\ub85c \uc644\ub8cc\ub41c\ub2e4\uba74 \uc601\uad6c\uc801\uc73c\ub85c \uacb0\uacfc\uc5d0 \ubc18\uc601\ub418\uc5b4\uc57c \ud55c\ub2e4. \\n\\n### \ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc740 \uaf2d \ud544\uc694\ud55c \ucd5c\uc18c\uc758 \ucf54\ub4dc\uc5d0\ub9cc \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.(\ud2b8\ub79c\uc7ad\uc158\uc758 \ubc94\uc704\ub97c \ucd5c\uc18c\ud654\ud558\ub77c) \\n\uad6c\ud604\ud574\uc57c \ud558\ub294 \uc5c5\ubb34\uc5d0 \ub530\ub77c \ud2b8\ub79c\uc7ad\uc158\uc744 \ubb36\uac70\ub098 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uace0, \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\ub294 \uacbd\uc6b0 \ubc18\ub4dc\uc2dc \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4. \\n\\n:::info \uc65c \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\uc744 \ub54c \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud560\uae4c? \ud83e\udd14\\n\\n\ub370\uc774\ud130\uc758 \uc77c\uad00\uc131\uacfc \uc548\uc804\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4. \\n\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc744 \ud2b8\ub79c\uc7ad\uc158 \ub0b4\ubd80\uc5d0 \ud3ec\ud568\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \\n- \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc911\uac04\uc5d0 \uc2e4\ud328\ud560 \uac00\ub2a5\uc131(\uc548\uc804\uc131 X)\\n- \ud1b5\uc2e0\uc73c\ub85c \uc778\ud574 \ub370\uc774\ud130\uac00 \ubcc0\uacbd\ub420 \uc218 \uc788\ub294 \ubd80\ubd84(\uc77c\uad00\uc131 X)\\n\\n:::\\n\\n## \uaca9\ub9ac \uc218\uc900(Isolation level)\\n\\n\uc5ec\ub7ec \ud2b8\ub79c\uc7ad\uc158\uc774 \ub3d9\uc2dc\uc5d0 \ucc98\ub9ac\ub420 \ub54c \ud2b9\uc815 \ud2b8\ub79c\uc7ad\uc158\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\uc758 \uc870\ud68c \ubc0f \ubcc0\uacbd\uc744 \ud5c8\uc6a9\ud560\uc9c0 \uacb0\uc815\ud558\ub294 \uac83\uc744 \ub9d0\ud55c\ub2e4. \\n\uaca9\ub9ac \uc218\uc900\uc774 \ub192\uc544\uc9c8 \uc218\ub85d \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\uc774 \ub5a8\uc5b4\uc9c0\ub294 \uac83\uc774 \uc77c\ubc18\uc801\uc774\uc9c0\ub9cc, `SERIALIZABLE`\uc774 \uc544\ub2c8\ub77c\uba74 \ud06c\uac8c \uc131\ub2a5\uc758 \uc800\ud558\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4. \\n\\n### READ UNCOMMITTED\\n\\n\uac01 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\uc758 \ubcc0\uacbd \ub0b4\uc6a9\uc774 `COMMIT`\uc774\ub098 `ROLLBACK` \uc5ec\ubd80\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcf4\uc778\ub2e4. \\n\ub354\ud2f0 \ub9ac\ub4dc \ud604\uc0c1\uc774 \ubc1c\uc0dd\ud558\uae30 \ub54c\ubb38\uc5d0 \uc815\ud569\uc131\uc758 \ubb38\uc81c\uac00 \ub9ce\uc740 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4. \\nMySQL \uc0ac\uc6a9\uc2dc \ucd5c\uc18c `READ COMMITTED` \uc774\uc0c1\uc758 \uaca9\ub9ac \uc218\uc900 \uc0ac\uc6a9\uc744 \uad8c\uc7a5\ud55c\ub2e4. \\n\\n```mermaid\\n---\\ntitle: READ UNCOMMITTED\\n---\\nsequenceDiagram\\n Alice->>Database: BEGIN\\n Alice->>Database: INSERT(Alice)\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice\\n Alice->>Database: COMMIT(Alice)\\n```\\n\\n### READ COMMITTED\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 `COMMIT`\uc774 \uc644\ub8cc\ub41c \ub370\uc774\ud130\ub9cc \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc870\ud68c\ud560 \uc218 \uc788\ub2e4. \\n\uc624\ub77c\ud074 DBMS\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4. \\n`REPEATABLE READ`\uac00 \ubcf4\uc7a5\ub418\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 `NON-REPEATABLE READ` \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\\n```mermaid\\n---\\ntitle: READ COMMITTED\\n---\\nsequenceDiagram\\n Alice->>Database: BEGIN\\n Alice->>Database: UPDATE(Alice to Bob)\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice(Undo log)\\n Alice->>Database: COMMIT\\n```\\n\\n### REPEATABLE READ\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \uc2dc\uc791\ub418\uae30 \uc804\uc5d0 `COMMIT`\uc774 \uc644\ub8cc\ub41c \ub0b4\uc6a9\uc5d0 \ub300\ud574\uc11c\ub9cc \uc870\ud68c\ud560 \uc218 \uc788\ub2e4. \\nMySQL\uc758 InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4. \\nMVCC\ub97c \uc774\uc6a9\ud574 \uc5b8\ub450(Undo) \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \uc774\uc804 \ub370\uc774\ud130\ub97c \uc774\uc6a9\ud574 \ub3d9\uc77c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c\ub294 \ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc5ec\uc904 \uc218 \uc788\uac8c \ubcf4\uc7a5\ud55c\ub2e4. \\n\ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc7a5\ud558\ub294 \ubc29\ubc95\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n - \ubaa8\ub4e0 InnoDB \ud2b8\ub79c\uc7ad\uc158\uc740 \uc21c\ucc28\uc801\uc73c\ub85c \uc99d\uac00\ud558\ub294 \uace0\uc720\ud55c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ub97c \uac00\uc9c4\ub2e4.\\n - Undo \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \ub808\ucf54\ub4dc\uc5d0\ub294 \ubcc0\uacbd\uc744 \ubc1c\uc0dd\uc2dc\ud0a8 \ud2b8\ub79c\uc7ad\uc158\uc758 \ubc88\ud638\uac00 \ud3ec\ud568\ub418\uc5b4\uc788\ub2e4.\\n - Undo \uc601\uc5ed\uc758 \ubc31\uc5c5\ub41c \ub370\uc774\ud130\ub294 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774 \ubd88\ud544\uc694\ud558\ub2e4\uace0 \ud310\ub2e8\ud558\ub294 \uacbd\uc6b0 \uc0ad\uc81c\ub41c\ub2e4.\\n - `REPEATABLE READ` \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c\ub294 MVCC\ub97c \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \uac00\uc7a5 \uc624\ub798\ub41c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ubcf4\ub2e4 \uc55e\uc120 Undo \uc601\uc5ed\uc758 \ub370\uc774\ud130\ub294 \uc0ad\uc81c\ud558\uc9c0 \uc54a\ub294\ub2e4. \\n\\nInnoDB\uc5d0\uc11c\ub294 \uac2d \ub77d\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc744 \uc774\uc6a9\ud558\uc5ec \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc744 \ubc29\uc9c0\ud55c\ub2e4. \\n\\n```mermaid\\n---\\ntitle: REPEATABLE READ\\n---\\nsequenceDiagram\\n participant Alice\\n participant Database\\n participant Bob\\n Bob->>Database: BEGIN(TRX-ID: 1)\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice\\n Alice->>Database: BEGIN(TRX-ID: 2)\\n Alice->>Database: UPDATE(Alice to Bob)\\n Alice->>Database: COMMIT\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice(Undo log)\\n```\\n\\n:::note \uac2d \ub78d(Gap lock)\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d(Next-key lock)\\n\\n\uac2d \ub77d: \ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4. \\n\ub125\uc2a4\ud2b8 \ud0a4 \ub77d: \ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4.\\n\\n:::\\n\\n:::note MVCC(Multi Version Concurrency Control)\\n\\n\ub3d9\uc2dc\uc131\uc744 \uc81c\uc5b4\ud558\ub294 \ubc29\ubc95 \uc911 \ud558\ub098\ub85c \ud558\ub098\uc758 \ub808\ucf54\ub4dc\uc5d0 \ub300\ud574 \uc5ec\ub7ec \uac1c\uc758 \ubc84\uc804\uc774 \ub3d9\uc2dc\uc5d0 \uad00\ub9ac\ub418\ub294 \uac83\uc774\ub2e4.\\n - PostgreSQL\uc740 \ub2e4\uc911 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\ub294 \uac83\uc73c\ub85c MVCC\ub97c \uad6c\ud604\ud55c\ub2e4.\\n - Oracle, InnoDB\ub294 `Undo log`\ub97c \uc774\uc6a9\ud574 \uc774 \uae30\ub2a5\uc744 \uad6c\ud604\ud55c\ub2e4.(\ucd5c\uc2e0 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub9cc DB\uc5d0 \uc800\uc7a5)\\n\\n\uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uc77d\uad00\ub41c \uc77d\uae30\ub97c \uc81c\uacf5\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4.\\n\\n:::\\n\\n### SERIALIZABLE\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc744 \uc21c\ucc28\uc801\uc73c\ub85c \uc9c4\ud589\uc2dc\ud0a4\ub294 \uaca9\ub9ac \uc218\uc900\uc774\uace0 \ub530\ub77c\uc11c \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\ub3c4 \ub2e4\ub978 \uaca9\ub9ac \uc218\uc900\ubcf4\ub2e4 \ub5a8\uc5b4\uc9c4\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uace0 \uc4f0\ub294 \ub808\ucf54\ub4dc\ub97c \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\ub294 \uc811\uadfc\ud560 \uc218 \uc5c6\uace0 \ub2e8\uc21c\ud55c \uc77d\uae30 \uc791\uc5c5\ub3c4 \uacf5\uc720 \uc7a0\uae08(\uc77d\uae30 \uc7a0\uae08)\uc744 \ud68d\ub4dd\ud574\uc57c\ub9cc \ud55c\ub2e4. \\nInnoDB\uc5d0\uc11c\ub294 \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc774 `REPEATABLE READ` \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ubc1c\uc0dd\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uad73\uc774 \uc0ac\uc6a9\ud560 \ud544\uc694\ub294 \uc5c6\ub2e4. \\n\\n## \uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c\\n\\n\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ub354\ud2f0 \ub9ac\ub4dc, \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c, \ud32c\ud140 \ub9ac\ub4dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\\n| \uaca9\ub9ac \uc218\uc900 / \ubd80\uc815\ud569 \ubb38\uc81c | \ub354\ud2f0 \ub9ac\ub4dc | \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c | \ud32c\ud140 \ub9ac\ub4dc |\\n| --- | --- | --- | --- |\\n| READ UNCOMMITTED | O | O | O |\\n| READ COMMITTED | X | O | O |\\n| REPEATABLE READ | X | X | O(InnoDB\ub294 X) |\\n| SERIALIZABLE | X | X | X |\\n\\n### \ub354\ud2f0 \ub9ac\ub4dc(Dirty read)\\n\\n\uc5b4\ub5a4 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ucc98\ub9ac\ud55c \uc791\uc5c5\uc774 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc558\uc5b4\ub3c4 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcfc \uc218 \uc788\ub294 \ud604\uc0c1 \\n\ud2b8\ub79c\uc7ad\uc158 \uaca9\ub9ac \uc218\uc900\uc774 READ UNCOMMITTED\uc77c \ub54c \ubc1c\uc0dd\ud55c\ub2e4. \\n\uc608) B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uace0 \ucee4\ubc0b\uc744 \ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, A\uac00 \ud574\ub2f9 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud560 \uc218 \uc788\ub294 \uacbd\uc6b0\\n\\n### \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)\\n\\n\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc758 \uac19\uc740 \ud589\uc5d0 \ub450 \ubc88 \uc774\uc0c1 \uc870\ud68c\uac00 \ubc1c\uc0dd\ud588\ub294\ub370, \uadf8 \uac12\uc774 \ub2e4\ub978 \ud604\uc0c1 \\n\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc5ec\ub7ec \ubc88 \uc870\ud68c\ud558\ub358 \uc911 B\uac00 \ub808\ucf54\ub4dc\ub97c \ubcc0\uacbd\ud558\uc5ec A\uac00 \uc870\ud68c\ud55c \uac12\uc774 \ub2ec\ub77c\uc9c0\ub294 \uacbd\uc6b0 \\n\\n```mermaid\\n---\\ntitle: NON REPEATABLE READ\\n---\\nsequenceDiagram\\n participant Alice\\n participant Database\\n participant Bob\\n Bob->>Database: BEGIN\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice\\n Alice->>Database: BEGIN\\n Alice->>Database: UPDATE(Alice to Bob)\\n Alice->>Database: COMMIT\\n Bob->>Database: SELECT\\n Database->>+Bob: Bob\\n```\\n\\n### \ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)\\n\\n\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ucffc\ub9ac \uc218\ud589\uc2dc, \uc218\ud589 \uacb0\uacfc\uac00 \ub2e4\ub978 \ud604\uc0c1 \\n\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud558\uace0 B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uc5ec A\uac00 \ub2e4\uc2dc \uc870\ud68c\ud560 \ub54c \uc874\uc7ac\ud558\uc9c0 \uc54a\uc740 \ub808\ucf54\ub4dc\uac00 \uc870\ud68c\ub418\ub294 \uacbd\uc6b0 \\n\\n```mermaid\\n---\\ntitle: PHANTOM READ\\n---\\nsequenceDiagram\\n participant Alice\\n participant Database\\n participant Bob\\n Bob->>Database: BEGIN(TRX-ID: 1)\\n Bob->>Database: SELECT COUNT\\n Database->>+Bob: 1\\n Alice->>Database: BEGIN(TRX-ID: 2)\\n Alice->>Database: INSERT(Bob)\\n Alice->>Database: COMMIT\\n Bob->>Database: SELECT COUNT\\n Database->>+Bob: 2\\n```\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\nReal My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1 \\n[Isolation Level, MySQL](https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html)"},{"id":"test-double","metadata":{"permalink":"/test-double","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx","source":"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx","title":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed","description":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?","date":"2023-04-04T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 4\uc77c","tags":[{"label":"Test","permalink":"/tags/test"},{"label":"Mock","permalink":"/tags/mock"}],"readingTime":4.52,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed","slug":"test-double","tags":["Test","Mock"]},"prevItem":{"title":"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900","permalink":"/transaction-and-isolation"},"nextItem":{"title":"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870","permalink":"/java-class-file"}},"content":"### \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?\\n\\n\ubaa8\ub4e0 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \uac00\uc9dc \uc758\uc874\uc131\uc744 \uc758\ubbf8\ud558\uace0, \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud589\ub420 \ub54c \ub2e4\ub978 \uac1d\uccb4\ub97c \ub300\uc2e0\ud55c\ub2e4. \\nGerard Meszaros\uc758 xUnit Test Patterns\ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ub2e4\uc12f \uac00\uc9c0(\ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774, \ubaa9, \ud398\uc774\ud06c)\ub85c \uad6c\ubd84\ud55c\ub2e4.\\n\\n\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \uae30\ubcf8 \uba54\ucee4\ub2c8\uc998\uc740 \ub2e4\ud615\uc131\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774\ub2e4. \\n\uc678\ubd80 \uc11c\ube44\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uacbd\uc6b0, \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc815\uc758\ud558\uace0 \uc678\ubd80 \uc11c\ube44\uc2a4 \ub300\uc2e0 \ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\uc758 \uad6c\ud604\uccb4\ub97c \uc0dd\uc131\ud558\ub294 \uac83\uc774\ub2e4.\\n\\n**\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \ud0c0\uc785 \uacc4\uce35 \uad6c\uc870**\\n\\n```mermaid\\nflowchart LR\\n Mock --\x3e Spy --\x3e Stub --\x3e Dummy --\x3e TestDouble\\n Fake --\x3e TestDouble\\n```\\n\\n### \ub354\ubbf8(Dummy)\\n\\n\uac00\uc7a5 \ub2e8\uc21c\ud558\uace0, \uc6d0\uc2dc\uc801\uc778 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub2e4. \\n\uae30\ubcf8\uc801\uc73c\ub85c \uc544\ubb34 \uc77c\ub3c4 \ud558\uc9c0 \uc54a\ub294 \uad6c\ud604\uccb4\ub85c \uc778\uc2a4\ud134\uc2a4\ud654\uac00 \ud544\uc694\ud55c \uacbd\uc6b0 \uc0ac\uc6a9\ud55c\ub2e4. \\n\ub9cc\uc57d \uba54\uc11c\ub4dc\uac00 \ubb34\uc5b8\uac00 \ubc18\ud658\uc744 \ud574\uc57c\ud558\ub294 \uacbd\uc6b0 0, null\uacfc \uac19\uc740 \uac12\uc744 \ubc18\ud658\ud55c\ub2e4. \\n\\n### \uc2a4\ud141(Stub)\\n\\n\uc2dc\ub098\ub9ac\uc624\ub9c8\ub2e4 \ub2e4\ub978 \uac12(\ubbf8\ub9ac \uc900\ube44 \ub41c \uacb0\uacfc)\uc744 \ubc18\ud658\ud55c\ub2e4. \\n\uc774\ub97c \ud1b5\ud574 \ud2b9\uc815 \uc870\uac74\uc5d0\uc11c \uba54\uc11c\ub4dc\uac00 \uc608\uc0c1\ud55c\ub300\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n### \uc2a4\ud30c\uc774(Spy)\\n\\n\uc2a4\ud141\uacfc \uc720\uc0ac\ud558\uc9c0\ub9cc \ud638\ucd9c \uc5ec\ubd80\ub97c \uae30\ub85d\ud558\uac70\ub098 \ud638\ucd9c\ud560 \ub54c \uc804\ub2ec\ud55c \uc778\uc790\uac12\uc744 \uae30\ub85d\ud560 \uc218 \uc788\ub2e4. \\n\uc608) \uba54\uc77c \uc804\uc1a1 \uae30\ub2a5\uc744 \uac00\uc9c4 \uac1d\uccb4\ub97c \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc73c\ub85c \uad6c\ud604\ud588\uc744 \ub54c \uba54\uc77c \uc804\uc1a1 \ud69f\uc218\ub97c \uae30\ub85d\ud55c\ub2e4. \\n\\n### \ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)\\n\\n\ubaa9\uc740 \ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774\ub97c \ud3ec\ud568\ud55c\ub2e4. \\n\ud638\ucd9c \uc2dc \uc0ac\uc804\uc5d0 \uc815\uc758\ub41c \uacb0\uacfc\ub97c \ubc18\ud658\ud558\uace0, \uc608\uc0c1\uce58 \ubabb\ud55c \ud638\ucd9c\uc774 \uc788\uc744 \uacbd\uc6b0 \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4. \\n\ub610\ud55c \ud638\ucd9c\uc5d0 \ub300\ud55c \uac80\uc99d\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\\n### \uac00\uc9dc(Fake)\\n\\nDOC\uc640 \ub3d9\uc77c\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\uc9c0\ub9cc, \ub354\uc6b1 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ub41c \uac83\uc774\ub2e4. \\n\uc608) \uc2e4\uc81c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc720\uc0ac\ud558\uac8c \ub3d9\uc791\ud558\ub294 \uac00\uc9dc \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\ub2e4. \\n\\n:::note DOC(depended-on component)\\n\\n\uc758\uc874 \uad6c\uc131 \uc694\uc18c, DOC\ub97c \ud14c\uc2a4\ud2b8 \ub354\ube14\ub85c \ub300\uccb4\ud560 \uc218 \uc788\ub2e4. \\n\ud14c\uc2a4\ud2b8 \ub354\ube14\uc740 DOC\uc640 \ub3d9\uc77c\ud55c API\ub97c \uc81c\uacf5\ud574\uc57c \ud55c\ub2e4. \\n\\n:::\\n\\n### \uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84\\n\\n\ub2e8\uc704 \ud14c\uc2a4\ud2b8 p.149 \uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ud06c\uac8c \ubaa9\uacfc \uc2a4\ud141\uc73c\ub85c \uad6c\ubd84\ud55c\ub2e4. \\n\ubaa9\uc740 SUT\uc640 \uad00\ub828\ub41c \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ubc18\uba74, \uc2a4\ud141\uc740 \ub2e8\uc21c \ubaa8\ubc29\ub9cc \ud55c\ub2e4. \\n\\n| TestDouble | Mock | Stub |\\n| --- | --- | --- |\\n| \ud3ec\ud568 \uc720\ud615 | \ubaa9, \uc2a4\ud30c\uc774 | \uc2a4\ud141, \ub354\ubbf8, \ud398\uc774\ud06c |\\n| \uc6a9\ub3c4 | \uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ub370 \uc0ac\uc6a9 | \ub0b4\ubd80\ub85c \ub4e4\uc5b4\uc624\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\ub294 \ub370 \uc0ac\uc6a9 |\\n| \uc124\uba85 | SUT\uac00 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9 | SUT\uac00 \uc785\ub825 \ub370\uc774\ud130\ub97c \uc5bb\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9\\n| \uc608\uc2dc | \uc774\uba54\uc77c \ubc1c\uc1a1 | \ub370\uc774\ud130 \uac80\uc0c9 |\\n\\n:::note SUT(system under test)\\n\\n\ud14c\uc2a4\ud2b8 \ub300\uc0c1 \uc2dc\uc2a4\ud15c \\n\ud14c\uc2a4\ud2b8\ub97c \ud558\ub824\ub294 \ub300\uc0c1\\n\\n:::\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30 - 3\uc7a5 \uace0\uae09 \ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 \\n\ub2e8\uc704 \ud14c\uc2a4\ud2b8 - 5\uc7a5 \ubaa9\uacfc \ud14c\uc2a4\ud2b8 \ucde8\uc57d\uc131, \ube14\ub77c\ub514\ubbf8\ub974 \ucf54\ub9ac\ucf54\ud504 \\n\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uc2dc\uc791\ud558\uae30 - 7\uc7a5 \ub300\uc5ed, \ucd5c\ubc94\uade0 \\n[\ud14c\uc2a4\ud2b8 \ub354\ube14, Martin Fowler](https://www.martinfowler.com/bliki/TestDouble.html) \\n[\ud14c\uc2a4\ud2b8 \uad00\ub828 \uc6a9\uc5b4 \uc815\ub9ac, Johngrib](https://johngrib.github.io/wiki/test-terms/) \\n[Test Double, Gerard Meszaros](http://xunitpatterns.com/Test%20Double.html)"},{"id":"java-class-file","metadata":{"permalink":"/java-class-file","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx","source":"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx","title":"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870","description":"\ud074\ub798\uc2a4 \ud30c\uc77c","date":"2023-04-03T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 3\uc77c","tags":[{"label":"Java","permalink":"/tags/java"},{"label":"Class","permalink":"/tags/class"}],"readingTime":5.63,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870","slug":"java-class-file","tags":["Java","Class"]},"prevItem":{"title":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed","permalink":"/test-double"},"nextItem":{"title":"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30","permalink":"/custom-jdbc-template"}},"content":"### \ud074\ub798\uc2a4 \ud30c\uc77c\\n\\n\uc790\ubc14 \uc18c\uc2a4\ucf54\ub4dc\uac00 \uc2e4\ud589\uc774 \ub418\ub824\uba74 \uc790\ubc14 \ucef4\ud30c\uc77c\ub7ec(javac)\ub97c \ud1b5\ud574 \uc18c\uc2a4\ucf54\ub4dc\ub97c \ud074\ub798\uc2a4\ud30c\uc77c\ub85c \ubcc0\ud658\ud574\uc57c \ud55c\ub2e4. \\n\ucef4\ud30c\uc77c\ub41c \ud074\ub798\uc2a4\ud30c\uc77c\uc740 \uc5b4\ub5a4 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\uc744\uae4c?\\n\\n### \ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd\\n\\n8\ube44\ud2b8 \ubc14\uc774\ud2b8\uc758 \uc2a4\ud2b8\ub9bc\uc73c\ub85c \uad6c\uc131\ub41c\ub2e4. \\n16\ube44\ud2b8 \ubc0f 32\ube44\ud2b8\uc758 \ub370\uc774\ud130\ub294 \uac01\uac01 2\uac1c, 4\uac1c\uc758 \uc5f0\uc18d\ub41c 8\ube44\ud2b8\ub97c \uc77d\uc5b4\uc11c \uad6c\uc131\ub41c\ub2e4. \\n\uba40\ud2f0\ubc14\uc774\ud2b8\uc758 \uacbd\uc6b0 \ud56d\uc0c1 big endian \uc21c\uc11c\ub85c \uc800\uc7a5\ub41c\ub2e4. \\n\\nu1 \u2192 unsigned 1byte \\nu2 \u2192 unsigned 2byte \\nu4 \u2192 unsigned 4byte \\n\\n### \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870\\n\\n```\\nClassFile {\\n u4 magic;\\n u2 minor_version;\\n u2 major_version;\\n u2 constant_pool_count;\\n cp_info constant_pool[constant_pool_count-1];\\n u2 access_flags;\\n u2 this_class;\\n u2 super_class;\\n u2 interfaces_count;\\n u2 interfaces[interfaces_count];\\n u2 fields_count;\\n field_info fields[fields_count];\\n u2 methods_count;\\n method_info methods[methods_count];\\n u2 attributes_count;\\n attribute_info attributes[attributes_count];\\n}\\n```\\n\\n### \ub9e4\uc9c1\ub118\ubc84\\n\\n\ubaa8\ub4e0 \ud074\ub798\uc2a4 \ud30c\uc77c\uc740 0xCAFEBABE\ub77c\ub294 \ub9e4\uc9c1\ub118\ubc84\ub85c \uc2dc\uc791\ud55c\ub2e4. \\n\ubcf4\ud1b5 \ub9e4\uc9c1\ub118\ubc84\ub294 \ud30c\uc77c \uc885\ub958\ub97c \uc2dd\ubcc4\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n### \ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804\\n\\n\ud074\ub798\uc2a4 \ud30c\uc77c \ubc84\uc804 \uac12\uc740 \ud074\ub798\uc2a4\ub85c\ub354\uc758 \ud638\ud658\uc131 \ubcf4\uc7a5\uc744 \uc704\ud574 \uaf2d \ud544\uc694\ud55c \uac12\uc774\ub2e4. \\n- Java 17 \ubc84\uc804\uc73c\ub85c \ube4c\ub4dc\ud55c\ub2e4\uba74 class version 61 ex) 00 00 00 3D\\n\\n\ud638\ud658\ub418\uc9c0 \uc54a\ub294 \ubc84\uc804\uc758 \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \ub85c\ub529\ud558\ub824\uace0 \ud558\ub294 \uacbd\uc6b0 \ub7f0\ud0c0\uc784\uc5d0 `UnsupportedClassVersionError` \uc608\uc678\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\\n**class\xa0file format major versions**\\n\\n| Java SE | Released | Major | Supported majors |\\n| --- | --- | --- | --- |\\n| 8 | March 2014 | 52 | 45 .. 52 |\\n| 9 | September 2017 | 53 | 45 .. 53 |\\n| 10 | March 2018 | 54 | 45 .. 54 |\\n| 11 | September 2018 | 55 | 45 .. 55 |\\n| 12 | March 2019 | 56 | 45 .. 56 |\\n| 13 | September 2019 | 57 | 45 .. 57 |\\n| 14 | March 2020 | 58 | 45 .. 58 |\\n| 15 | September 2020 | 59 | 45 .. 59 |\\n| 16 | March 2021 | 60 | 45 .. 60 |\\n| 17 | September 2021 | 61 | 45 .. 61 |\\n\\n### \uc0c1\uc218 \ud480\\n\\n2\ubc14\uc774\ud2b8\uc758 \uc0c1\uc218\uc758 \uac1c\uc218\uac12\uc774 \uba3c\uc800\uc624\uace0 \uadf8 \ub4a4\ub85c \ucf54\ub4dc\uc5d0 \ub4f1\uc7a5\ud558\ub294 \uc0c1\uc218\uac12\uc774 \ubaa8\uc5ec\uc788\ub2e4. \\n\ud074\ub798\uc2a4\uba85, \uc0c1\uc218\uba85, \uc0c1\uc218 \uac12, \ud544\ub4dc\uba85, \uba54\uc11c\ub4dc\uba85\uacfc \uac19\uc740 \uac12\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4. \\nJVM\uc740 \ucf54\ub4dc \uc2e4\ud589 \uc2dc \ub7f0\ud0c0\uc784\uc5d0 \ubc30\uce58\ub41c \uba54\ubaa8\ub9ac\uac00 \uc544\ub2c8\ub77c, \ud574\ub2f9 \uc0c1\uc218 \ud480 \ud14c\uc774\ube14\uc744 \ucc3e\uc544\ubcf4\uace0 \ud544\uc694\ud55c \uac12\uc744 \ucc38\uc870\ud55c\ub2e4.\\n\\n### \uc561\uc138\uc2a4 \ud50c\ub798\uadf8\\n\\n\ud074\ub798\uc2a4, \uc778\ud130\ud398\uc774\uc2a4\uc640 \uac19\uc740 \ud30c\uc77c\uc758 \uc18d\uc131\uc744 \ud45c\uc2dc\ud55c\ub2e4. \\n\uc608\ub97c \ub4e4\uc5b4 public interface\ub85c \uc815\uc758\ub41c \uc778\ud130\ud398\uc774\uc2a4\uc758 \ud50c\ub798\uadf8\ub294 0x0601\uc774\ub2e4. \\n- \uacc4\uc0b0\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. `ACC_PUBLIC` xor `ACC_INTERFACE` xor `ACC_ABSTRACT`\\n\\n\uacf5\uc2dd\ubb38\uc11c\uc5d0 \ub4e4\uc5b4\uac00\uba74 \uac01 \ud50c\ub798\uadf8\uc5d0 \ub300\ud55c \uc124\uba85 + \ud50c\ub798\uadf8 \uc124\uc815\uc2dc \ub3d9\uc2dc\uc5d0 \uc124\uc815\ub418\uba74 \uc548\ub418\ub294 \ud50c\ub798\uadf8\uc640 \uac19\uc740 \uc124\uba85\uc774 \uc790\uc138\ud558\uac8c \ub098\uc640\uc788\ub2e4.\\n\\n**Class access and property modifiers**\\n\\n| Flag Name | Value | Interpretation |\\n| --- | --- | --- |\\n| ACC_PUBLIC | 0x0001 | Declared\xa0public; may be accessed from outside its package. |\\n| ACC_FINAL | 0x0010 | Declared\xa0final; no subclasses allowed. |\\n| ACC_SUPER | 0x0020 | Treat superclass methods specially when invoked by the\xa0invokespecial\xa0instruction. |\\n| ACC_INTERFACE | 0x0200 | Is an interface, not a class. |\\n| ACC_ABSTRACT | 0x0400 | Declared\xa0abstract; must not be instantiated. |\\n| ACC_SYNTHETIC | 0x1000 | Declared synthetic; not present in the source code. |\\n| ACC_ANNOTATION | 0x2000 | Declared as an annotation type. |\\n| ACC_ENUM | 0x4000 | Declared as an\xa0enum\xa0type. |\\n| ACC_MODULE | 0x8000 | Is a module, not a class or interface. |\\n\\n### this_class\\n\\n\ud074\ub798\uc2a4\uba85\uacfc \uac19\uc740 \uc774\ub984\uc744 \ud45c\ud604\ud558\ub294 \uac12\uc73c\ub85c, \uc0c1\uc218 \ud480\uc5d0\uc11c \ud074\ub798\uc2a4\uba85\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4. \\n\ud574\ub2f9 \uc778\ub371\uc2a4\uc758 \ud56d\ubaa9\uc740 `CONSTANT_Class_infoclass` \ud615\uc2dd\uc758 \uac12\uc774\uc5b4\uc57c \ud55c\ub2e4. \\n\\n### super_class\\n\\n\uc0c1\uc218 \ud480\uc5d0\uc11c \uc288\ud37c \ud074\ub798\uc2a4\uc758 \uc774\ub984\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4. \\n\uc544\ubb34\uac83\ub3c4 \uc0c1\uc18d\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\uc758 \uacbd\uc6b0 `java.lang.Object`\uc758 \uc778\ub371\uc2a4 \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4.\\n\\n### interface, field, method\\n\\n\uac01\uac01\uc758 \uac1c\uc218\uc640, \uc815\ubcf4\uc5d0 \ub300\ud55c \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4. \\ninterface, field, method\ub97c \ud45c\uc2dc\ud558\ub294 \ubc29\ubc95\uc774 \uac01\uac01 \ub2e4\ub974\uace0, \uc811\uadfc\uc790\uc5d0 \ub300\ud55c \ud50c\ub798\uadf8\ub3c4 \uac01\uac01 \ub2e4\ub974\ub2e4.\\n\\n### attributes\\n\\n\ud574\ub2f9 \ud074\ub798\uc2a4 \ud30c\uc77c\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucd94\uac00 \uc815\ubcf4\uc758 \ubaa8\uc74c\uc774\ub2e4. \uc608) \uc18c\uc2a4\ud30c\uc77c\uba85 \\n\uc815\ud574\uc9c4 \ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \uad6c\uc870\ub97c \ud655\uc7a5\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. \\n\\n### \ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234\\n\\nIntelliJ plugin - BinEd \\nIntelliJ plugin - jclasslib Bytecode Viewer\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n2\uc7a5 JVM \uc774\uc57c\uae30, \uc790\ubc14 \ucd5c\uc801\ud654 \\n[Class file in Java, File Format](https://docs.fileformat.com/ko/programming/class/) \\n[java se11 Class \ud30c\uc77c \ud615\uc2dd, Oracle](https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html) \\n[java se17 Class \ud30c\uc77c \ud615\uc2dd, Oracle](https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html)"},{"id":"custom-jdbc-template","metadata":{"permalink":"/custom-jdbc-template","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx","source":"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx","title":"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30","description":"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.","date":"2023-04-02T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 2\uc77c","tags":[{"label":"JDBC","permalink":"/tags/jdbc"},{"label":"Java","permalink":"/tags/java"}],"readingTime":9.025,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30","slug":"custom-jdbc-template","tags":["JDBC","Java"]},"prevItem":{"title":"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870","permalink":"/java-class-file"},"nextItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0","permalink":"/woowacourse-level1-retrospective"}},"content":"import Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4. \\n\uc774 \ub54c JDBC\ub97c \uc0ac\uc6a9\ud560 \ub54c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 \ucee4\ub125\uc158\uc744 \uc5bb\uace0, try-with-resource\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc774 \ubc18\ubcf5\ub418\uc5c8\ub2e4. \\n\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc774\uc6a9\ud558\uc5ec \ub098\ub9cc\uc758 JdbcTemplate\uc744 \ub9cc\ub4e4\uc5b4\ubcf4\uc558\ub2e4. \\n\\n### \uae30\uc874 \ucf54\ub4dc\\n\\n<Tabs>\\n<TabItem value=\\"User\\" label=\\"User\\" default>\\n\\n```java\\npublic class User {\\n private final int id;\\n private final String name;\\n\\n public User(final int id, final String name) {\\n this.id = id;\\n this.name = name;\\n }\\n\\n public int getId() {\\n return id;\\n }\\n\\n public String getName() {\\n return name;\\n }\\n}\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"UserDao\\" label=\\"UserDao\\">\\n\\n```java\\npublic class UserDao {\\n private final ConnectionPool connectionPool;\\n\\n public UserDao(final ConnectionPool connectionPool) {\\n this.connectionPool = connectionPool;\\n }\\n\\n public void insert(final String name) {\\n final Connection connection = connectionPool.getConnection();\\n final String query = \\"INSERT INTO User (name) VALUES (?)\\";\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n preparedStatement.setString(1, name);\\n preparedStatement.executeUpdate();\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n\\n public void delete(final int userId) {\\n final Connection connection = connectionPool.getConnection();\\n final String query = \\"DELETE FROM user WHERE id = ?\\";\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n preparedStatement.setInt(1, userId);\\n preparedStatement.executeUpdate();\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n\\n public User findById(final int userId) {\\n final Connection connection = connectionPool.getConnection();\\n final String query = \\"SELECT * FROM user WHERE id = ?\\";\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n preparedStatement.setInt(1, userId);\\n final ResultSet resultSet = preparedStatement.executeQuery();\\n if (resultSet.next()) {\\n return new User(\\n resultSet.getInt(\\"id\\"),\\n resultSet.getString(\\"name\\")\\n );\\n }\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n return null;\\n }\\n\\n public List<User> findAll() {\\n final Connection connection = connectionPool.getConnection();\\n final String query = \\"SELECT * FROM user\\";\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n final ResultSet resultSet = preparedStatement.executeQuery();\\n final List<User> result = new ArrayList<>();\\n while (resultSet.next()) {\\n result.add(new User(\\n resultSet.getInt(\\"id\\"),\\n resultSet.getString(\\"name\\")\\n ));\\n }\\n return result;\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n}\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"ConnectionPool\\" label=\\"ConnectionPool\\">\\n\\n```java\\npublic class ConnectionPool {\\n private static final String SERVER = \\"localhost:13306\\";\\n private static final String DATABASE = \\"chess\\";\\n private static final String OPTION = \\"?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true\\";\\n private static final String URL = \\"jdbc:mysql://\\" + SERVER + \\"/\\" + DATABASE + OPTION;\\n private static final String USERNAME = \\"root\\";\\n private static final String PASSWORD = \\"root\\";\\n\\n private final AtomicInteger index = new AtomicInteger();\\n private final List<Connection> connections;\\n\\n public ConnectionPool(final int connectionCount) {\\n connections = generateConnections(connectionCount);\\n }\\n\\n private List<Connection> generateConnections(final int connectionCount) {\\n return Stream.generate(this::generateConnection)\\n .limit(connectionCount)\\n .collect(toList());\\n }\\n\\n private Connection generateConnection() {\\n try {\\n return DriverManager.getConnection(URL, USERNAME, PASSWORD);\\n } catch (SQLException e) {\\n throw new IllegalStateException(\\"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\\");\\n }\\n }\\n\\n public Connection getConnection() {\\n int currentIndex = index.getAndIncrement();\\n return connections.get(currentIndex % connections.size());\\n }\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n### SELECT, DELETE \uc911\ubcf5 \uc81c\uac70\\n\\n\ubcc0\ud558\uc9c0 \uc54a\ub294 \ubd80\ubd84: try-with-resource, preparedStatement\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84, executeUpdate\ub85c \uc2e4\ud589 \ub4f1\ub4f1 \\n\ubcc0\ud558\ub294 \ubd80\ubd84: SQL Query, \ub9e4\uac1c\ubcc0\uc218 \\n\\n\ub2e4\uc74c\uacfc \uac19\uc774 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\ub294 \ubd80\ubd84\uc744 \ubd84\ub9ac\ud558\uace0 \uac00\ubcc0\uc778\uc218\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 SELECT\uc640 DELETE\uc758 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. \\n\\n```java\\npublic void insert(final String name) {\\n final String query = \\"INSERT INTO User (name) VALUES (?)\\";\\n executeUpdate(query, name);\\n}\\n\\npublic void delete(final int userId) {\\n final String query = \\"DELETE FROM user WHERE user_id = ?\\";\\n executeUpdate(query, userId);\\n}\\n\\nprivate void executeUpdate(final String query, final Object... parameters) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n preparedStatement.executeUpdate();\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n}\\n```\\n\\n### \uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758\\n\\n\uc870\ud68c\ub294 INSERT, DELETE\uc640 \ub2ec\ub9ac \uac12\uc744 \ubc18\ud658\ubc1b\uc544\uc57c \ud558\uae30 \ub54c\ubb38\uc5d0 \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4. \\n\uc774 \ub54c \ucf5c\ubc31\uc774\ub77c\ub294 \uac83\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. \\n\\n:::note \ucf5c\ubc31(Callback)\\n\\n\ud504\ub85c\uadf8\ub798\ubc0d\uc5d0\uc11c \ucf5c\ubc31\uc740 \ub2e4\ub978 \ucf54\ub4dc\uc758 \uc778\uc218\ub85c \ub118\uaca8\uc8fc\ub294 \uc2e4\ud589 \uac00\ub2a5\ud55c \ucf54\ub4dc\ub97c \ub73b\ud55c\ub2e4. \\n\uc790\ubc14\uc5d0\uc11c\ub294 \ub78c\ub2e4\ub098 \uc775\uba85 \ud074\ub798\uc2a4\ub97c \ub118\uaca8\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n```mermaid\\nflowchart LR\\n \ud074\ub77c\uc774\uc5b8\ud2b8 -- \ucf5c\ubc31\uc804\ub2ec --\x3e \uba54\uc11c\ub4dc\\n \uba54\uc11c\ub4dc -- \ub0b4\ubd80\ud638\ucd9c --\x3e \uc804\ub2ec\ubc1b\uc740\ucf5c\ubc31\\n```\\n\\n:::\\n\\n\\n\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uc870\ud68c\ud558\uace0, \ud574\ub2f9 \uac12\uc744 \uac1d\uccb4\ub85c \ub9e4\ud551\ud558\uc5ec \uac12\uc744 \ubc18\ud658\ud574\uc57c \ud55c\ub2e4. \\nexecuteQuery\ub85c \uc870\ud68c\ud55c \uac12\uc740 ResultSet \uc548\uc5d0 \ub4e4\uc5b4\uac00\uc788\ub2e4. \\n\uc774\ub97c \uc6d0\ud558\ub294 \ud0c0\uc785\uc758 \uac12\uc73c\ub85c \ubcc0\ud658\ud574\uc57c\ud558\ub2c8 \uc77c\ub2e8 \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud55c\ub2e4. \\n\\n```java\\n@FunctionalInterface\\npublic interface RowMapper {\\n User mapRow(final ResultSet resultSet) throws SQLException;\\n}\\n```\\n\\n### \uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c\\n\\n\uc704\uc5d0\uc11c \uc815\uc758\ud55c RowMapper\ub97c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc5b4\ub5bb\uac8c \uc0ac\uc6a9\ud574\uc57c \ud560\uae4c? \\n\uc544\ub798\uc640 \uac19\uc774 SQL \ucffc\ub9ac, RowMapper, \ud30c\ub77c\ubbf8\ud130\ub97c \ubd84\ub9ac\ud55c \uba54\uc11c\ub4dc\uc5d0 \ub118\uaca8\uc8fc\uace0 \ucffc\ub9ac \uc2e4\ud589 \ud6c4 \ub9e4\ud551\ud55c \uac12\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. \\n\\n```java\\npublic User findById(final int userId) {\\n final String query = \\"SELECT * FROM user WHERE id = ?\\";\\n return queryForSingleResult(query, resultSet -> {\\n final int id = resultSet.getInt(\\"id\\");\\n final String name = resultSet.getString(\\"name\\");\\n return new User(id, name);\\n }, userId);\\n}\\n\\nprivate User queryForSingleResult(\\n final String query,\\n final RowMapper rowMapper,\\n final Object... parameters\\n) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\\n if (resultSet.next()) {\\n return rowMapper.mapRow(resultSet);\\n }\\n return null;\\n } catch (SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n}\\n\\nprivate ResultSet executeQuery(\\n final PreparedStatement preparedStatement,\\n final Object[] parameters) throws SQLException {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n return preparedStatement.executeQuery();\\n}\\n```\\n\\n### \uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c\\n\\n\ub2e8\uac74 \uc870\ud68c\uc640 \uc720\uc0ac\ud558\ub2e4.\\n\\n```java\\npublic List<User> findAll() {\\n final String query = \\"SELECT * FROM user\\";\\n return query(query, resultSet -> {\\n final int id = resultSet.getInt(\\"id\\");\\n final String name = resultSet.getString(\\"name\\");\\n return new User(id, name);\\n });\\n}\\n\\nprivate List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\\n final List<User> result = new ArrayList<>();\\n while (resultSet.next()) {\\n result.add(rowMapper.mapRow(resultSet));\\n }\\n return result;\\n } catch (SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n}\\n\\nprivate ResultSet executeQuery(\\n final PreparedStatement preparedStatement,\\n final Object[] parameters) throws SQLException {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n return preparedStatement.executeQuery();\\n}\\n```\\n\\n### \uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30\\n\\n\uc704\uc758 \ucf54\ub4dc\ub294 User\ub97c \uc870\ud68c\ud560 \ub54c\ub9cc \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. \\n\uc544\ub798\uc640 \uac19\uc774 \uc81c\ub124\ub9ad\uc744 \uc801\uc6a9\ud558\uc5ec \ub2e4\ub978 Dao\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\ud558\ub3c4\ub85d \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4.\\n\\n```java\\n@FunctionalInterface\\npublic interface RowMapper<T> {\\n T mapRow(final ResultSet resultSet) throws SQLException;\\n}\\n\\nprivate <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\\nprivate <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\\n```\\n\\n### \uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30\\n\\n\uba54\uc11c\ub4dc\ub85c \ubd84\ub9ac\ud55c \ubd80\ubd84\uc744 JdbcTemplate\uc774\ub77c\ub294 \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uc5b4 \uc62e\uae34\ub2e4. \\n\ub610\ud55c null\uc744 \ubc18\ud658\ud558\uae30 \ubcf4\ub2e8 Optional\ub85c \uac10\uc2f8\uc11c \ubc18\ud658\ud558\ub3c4\ub85d \ubcc0\uacbd\ud55c\ub2e4. \\n\ucd5c\uc885\uc801\uc73c\ub85c \uc544\ub798\uc640 \uac19\uc740 \ucf54\ub4dc\uac00 \uc644\uc131\ub41c\ub2e4.\\n\\n<Tabs>\\n<TabItem value=\\"UserDao\\" label=\\"UserDao\\" default>\\n\\n```java\\npublic class UserDao {\\n private final RowMapper<User> rowMapper = resultSet -> {\\n final int id = resultSet.getInt(\\"id\\");\\n final String name = resultSet.getString(\\"name\\");\\n return new User(id, name);\\n };\\n private final JdbcTemplate jdbcTemplate;\\n\\n public UserDao(final JdbcTemplate jdbcTemplate) {\\n this.jdbcTemplate = jdbcTemplate;\\n }\\n\\n public void insert(final String name) {\\n final String query = \\"INSERT INTO User (name) VALUES (?)\\";\\n jdbcTemplate.executeUpdate(query, name);\\n }\\n\\n public void delete(final int userId) {\\n final String query = \\"DELETE FROM user WHERE user_id = ?\\";\\n jdbcTemplate.executeUpdate(query, userId);\\n }\\n\\n public Optional<User> findById(final int userId) {\\n final String query = \\"SELECT * FROM user WHERE id = ?\\";\\n return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);\\n }\\n\\n public List<User> findAll() {\\n final String query = \\"SELECT * FROM user\\";\\n return jdbcTemplate.query(query, rowMapper);\\n }\\n}\\n```\\n\\n</TabItem>\\n<TabItem value=\\"JdbcTemplate\\" label=\\"JdbcTemplate\\" default>\\n\\n```java\\npublic class JdbcTemplate {\\n private final ConnectionPool connectionPool;\\n\\n public JdbcTemplate(final ConnectionPool connectionPool) {\\n this.connectionPool = connectionPool;\\n }\\n\\n public void executeUpdate(final String query, final Object... parameters) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n preparedStatement.executeUpdate();\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n\\n public <T> Optional<T> queryForSingleResult(\\n final String query,\\n final RowMapper<T> rowMapper,\\n final Object... parameters\\n ) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\\n if (resultSet.next()) {\\n return Optional.of(rowMapper.mapRow(resultSet));\\n }\\n return Optional.empty();\\n } catch (SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n\\n private ResultSet executeQuery(\\n final PreparedStatement preparedStatement,\\n final Object[] parameters\\n ) throws SQLException {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n return preparedStatement.executeQuery();\\n }\\n\\n public <T> List<T> query(\\n final String query,\\n final RowMapper<T> rowMapper,\\n final Object... parameters\\n ) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\\n final List<T> result = new ArrayList<>();\\n while (resultSet.next()) {\\n result.add(rowMapper.mapRow(resultSet));\\n }\\n return result;\\n } catch (SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n}\\n```\\n\\n</TabItem>\\n</Tabs>"},{"id":"woowacourse-level1-retrospective","metadata":{"permalink":"/woowacourse-level1-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx","title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0","description":"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.","date":"2023-04-01T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 1\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":7.48,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0","slug":"woowacourse-level1-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30","permalink":"/custom-jdbc-template"},"nextItem":{"title":"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0","permalink":"/chess-retrospective"}},"content":"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4. \\n\uc6b0\ud14c\ucf54\ub97c \uc2dc\uc791\ud558\uae30 \uc804 \ub0b4\uac00 \uc815\ud574\ub450\uc5c8\ub358 \ubaa9\ud45c \uc774\uc0c1\uc73c\ub85c \ub2ec\uc131\ud588\uae30 \ub54c\ubb38\uc5d0 \ub9e4\uc6b0 \ub9cc\uc871\uc2a4\ub7fd\ub2e4. \\n\ud63c\uc790 \ub3c5\ud559\uc744 \ud560 \ub550 \uc774 \ubc29\ud5a5\uc73c\ub85c \uacf5\ubd80\ud558\ub294 \uac8c \ub9de\ub294\uc9c0 \uacc4\uc18d \ubc18\ucd94\ud558\ub2e4 \uacb0\uad6d \ubb34\uae30\ub825\ud568\uc5d0 \ube60\uc838\ub4e4\uc5c8\ub2e4. \\n\ud558\uc9c0\ub9cc \uc774\uc81c\ub294 \uac19\uc774 \uacf5\ubd80\ud560 \uc0ac\ub78c\ub3c4 \uc788\uace0, \uc774\uc57c\uae30\ud560 \uc0ac\ub78c\ub3c4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc990\uae30\ub294 \uc77c\ub9cc \ub0a8\uc740 \uac83 \uac19\ub2e4. \\n\\n### Keep\\n\\n**\ub098\ub9cc\uc758 \ub8e8\ud2f4 \ub9cc\ub4e4\uae30** \\n\\n\uc2a4\uc2a4\ub85c\uac00 \uc678\ubd80\uc758 \uc601\ud5a5\uc744 \ub9ce\uc774 \ubc1b\ub294\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\ucd5c\ub300\ud55c \uafb8\uc900\ud788 \ud560 \uc218 \uc788\ub294 \uc2dc\uac04\uc744 \ub9cc\ub4dc\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\n\ub9e4\uc77c 8\uc2dc\uc5d0 \ub3c4\ucc29\ud558\uc5ec \uc544\uce68\uc5d0 \ud574\uc57c \ud560 \uc77c\uc744 \uc815\ub9ac\ud558\uac70\ub098, \uc6b0\uc120\uc21c\uc704\uc5d0 \ub530\ub77c \ucc98\ub9ac\ud558\uace0 \\n\uc18c\ud654\ub2a5\ub825\uc774 \ubd80\uc871\ud558\uae30 \ub54c\ubb38\uc5d0 \uc810\uc2ec\uc740 \ub3c4\uc2dc\ub77d(\uadf8\ub798\ubd24\uc790 \uacc4\ub7802\uac1c)\uc744 \uc900\ube44\ud558\uace0 \\n\ud56d\uc0c1 \ub611\uac19\uc740 \ucee8\ub514\uc158\uc744 \uc720\uc9c0\ud558\uae30 \uc704\ud574 \ud56d\uc0c1 6\uc2dc\uc5d0 \uc9d1\uc5d0 \uac04\ub2e4. \\n\uc774\uc81c \ubc14\ube60\uc9c8 \ud14c\ub2c8 \uc77c\ucc0d \uc9d1\uc5d0 \uac00\ub294 \uc77c\uc740 \uc5b4\uca54 \uc218 \uc5c6\uc774 \uc904\uc5b4\ub4e4\uaca0\uc9c0\ub9cc\ud83d\ude22 \\n\\n\uc120\ud0dd\ub3c4 \ube44\uc6a9\uc774\ub2e4. \uc55e\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\uc774 \ud544\uc694 \uc5c6\ub294 \ubd80\ubd84\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\ub4e4\uc5b4\uc57c\uaca0\ub2e4. \\n\\n**\ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uae30** \\n\\n10\uba85 \uc815\ub3c4\uc758 \ud06c\ub8e8\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b0\uace0 \uce5c\ud558\uac8c \uc9c0\ub0b8\ub2e4\uba74 \uc131\uacf5\uc801\uc774\ub77c\uace0 \uc0dd\uac01\ud588\uc5c8\ub2e4. \\n\ud558\ub2e4 \ubcf4\ub2c8 \ub354 \ub9ce\uc740 \ud06c\ub8e8\ub4e4\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b4 \uac83 \uac19\ub2e4. \\n\uc55e\uc73c\ub85c\ub3c4 \ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uace0 \uc544\ubb34 \ub54c\ub098 \ub9d0\uc744 \uac78 \uc218 \uc788\ub294 \ud06c\ub8e8\uac00 \ub298\uc5b4\ub098\uae38 :) \\n\\n**\uae00\uc4f0\uae30** \\n\\n\uae00\uc744 \uc798 \uc4f0\ub294 \ud3b8\uc740 \uc544\ub2c8\uc9c0\ub9cc \uafb8\uc900\ud788 \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\ub9e4 \ubbf8\uc158\ub9c8\ub2e4 \ud68c\uace0\ub97c \uc791\uc131\ud558\ub2c8 \uc0dd\uac01\ub3c4 \uc815\ub9ac\ub418\uace0 \uac1c\uc120\uc810\ub3c4 \ucc3e\uc744 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\ub2e4. \\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc5d0\ub294 \ub808\ubca8\ub9c8\ub2e4 \uae00\uc4f0\uae30\ub97c \uc9c4\ud589\ud558\ub294\ub370, \uc6b4\uc774 \uc88b\uac8c \uae00\uc4f0\uae30 \uc0c1\uc744 \ubc1b\uc558\ub2e4. \\n\uc0ac\uc2e4 \uac89\uc73c\ub85c \ub4dc\ub7ec\ub0b4\uc9c0 \uc54a\uc558\uc9c0\ub9cc \uaf2d \ubc1b\uc544\ubcf4\uace0 \uc2f6\uc5c8\ub2e4. \\n\uae00\uc4f0\uae30 \uc870\uc6d0, \ud22c\ud45c\ud574 \uc900 \ud06c\ub8e8\ub4e4\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4. \\n\\n**\ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514** \\n\\n\ub204\ub204, \uc8fc\ub178, \ub2e4\uc990, \ub9d0\ub791, \ubc15\uc2a4\ud130, \uc624\uc789, \uae43\uc9f1\uc640 \ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514\ub97c \uc9c4\ud589\ud588\ub2e4. \\n\uacfc\uc5f0 \ub3c4\uc6c0\uc774 \ub420\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud558\uba74\uc11c \uc131\uc7a5\uc744 \ub9ce\uc774 \ud55c \uac83 \uac19\ub2e4. \\n\ud22c\uc790\ud55c \uc2dc\uac04 \ub300\ube44 \uac00\uc131\ube44\uac00 \uc88b\uc740 \ud65c\ub3d9\uc774\uc5c8\ub2e4. \\n\ub204\ub204\uac00 \uc2a4\ud130\ub514\uc7a5\uc778\ub370 \uacfc\uc5f0 \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00\ub824\ub098? \\n\\n**\ub808\ubca8 \uc778\ud130\ubdf0**\\n\\n\uc778\ud130\ubdf0\ud560 \ub54c \ub9ce\uc774 \ub5a8\uc9c0 \uc54a\uc544\uc11c \uc88b\uc558\ub2e4. \\n\ub0a8\ub4e4 \uc55e\uc5d0\uc11c \uc774\uc57c\uae30\ub97c \ud558\uac70\ub098, \uba74\uc811\uc744 \ubcf4\uba74 \ud56d\uc0c1 \uc5c4\uccad \ub5a8\uc5b4\uc11c \uac71\uc815\ud588\ub294\ub370 \\n\uae30\uc220\uc801\uc778 \uc9c8\ubb38\uc744 \ubc1b\uc558\uc744 \ub54c \ub5a8\uc9c0 \uc54a\uace0 \uc798 \ub300\ub2f5\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \ub2e4\ub978 \ud06c\ub8e8\uac00 \uc9c8\ubb38\ud588\uc744 \ub54c, \ucd5c\ub300\ud55c \uc774\ud574\ud558\uae30 \uc27d\uac8c \uc124\uba85\ud558\ub824\uace0 \ud588\ub358 \uacbd\ud5d8\uc774 \ub3c4\uc6c0\uc774 \ub41c \uac83 \uac19\ub2e4. \\n\uc774\ud6c4 \ub808\ubca8 \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc740 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\ub2e4. \\n- \ub300\ub2f5\ud558\uba74\uc11c \uc9c8\ubb38\uc744 \uacc4\uc18d \uc0dd\uac01\ud558\uba70 \uc78a\uc5b4\ubc84\ub9ac\uc9c0 \ub9d0\uae30 \\n- \ub450\uad04\uc2dd \ud45c\ud604\\n- \uc124\uba85\ud558\ub2e4\uac00 \uc798\ubabb \uc124\uba85\ud55c \uac83 \uac19\uc73c\uba74 \ub2e4 \ub04a\uace0 \ub2e4\uc2dc \uc774\uc57c\uae30\ud574\ub3c4 \ub420\uc9c0 \ubb3c\uc5b4\ubcf4\uae30 \\n- \uc124\uba85\ud560 \uc218 \uc788\uc744\ub9cc\ud07c \uc2dc\uac04 \ucda9\ubd84\ud788 \uac00\uc9c0\uae30\\n- \uc778\ud130\ubdf0\uc5b4\uc758 \uc9c8\ubb38 \uc758\ub3c4\ub97c \uba85\ud655\ud788 \uc774\ud574\ud558\uc9c0 \ubabb\ud588\ub2e4\uba74 \uc758\ub3c4 \ub2e4\uc2dc \ubb3c\uc5b4\ubcf4\uae30\\n- \ub05d\ub9fa\ub294 \ubd80\ubd84 \uc5f0\uc2b5\ud558\uae30(\uc790\uc2e0\uac10 \uc788\uac8c)\\n- \uae30\uc220\uc801\uc778 \uc9d1\ucc29\uac00\uc9c0\uae30\\n- \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud788 \uc900\ube44\ud588\uc73c\uba74 \ud611\uc5c5 \uad00\ub828 \uc9c8\ubb38\ub3c4 \uc900\ube44\ud558\uae30\\n\\n### Problem\\n\\n**\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d** \\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uac00\uc7a5 \uc5b4\ub824\uc6b4 \ud65c\ub3d9 \uc911 \ud558\ub098\ub77c\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\ud398\uc5b4\ub294 \ub9e4\ubc88 \ubc14\ub00c\uace0, \ubbf8\uc158\uc758 \ubcf5\uc7a1\ub3c4\ub3c4 \uc99d\uac00\ud558\uae30 \ub54c\ubb38\uc778 \uac83 \uac19\ub2e4. \\n\uc18c\ud1b5 \ub2a5\ub825, \uc2dc\uac04\uad00\ub9ac\uac00 \ubd80\uc871\ud588\uace0, \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\uc558\ub2e4. \\n\ud558\uc9c0\ub9cc \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uace0, \ud68c\uace0\ub97c \ud558\ub2e4 \ubcf4\ub2c8 \ub098\ub9cc\uc758 \ub178\ud558\uc6b0\uac00 \uc313\uc774\ub294 \ub290\ub08c\uc774\ub2e4. \\n\ub808\ubca8 2\uc5d0\uc11c\ub294 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc120\ud558\uc5ec \ud568\uaed8\ud558\uace0 \uc2f6\uc740 \ud398\uc5b4\uac00 \ub418\uace0 \uc2f6\ub2e4. \\n\\n**\uc9d1\uc911\ud558\ub294 \uc2dc\uac04\u23f1\ufe0f \ubd80\uc871** \\n\\n\ub808\ubca8 1\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc9d1\uc911\ud558\ub294 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4. \\n\uc774\ub978 \uc544\uce68\uacfc \uc624\ud6c4\uc5d0 \uac1c\uc778\uc801\uc73c\ub85c \uc9d1\uc911\ud560 \uc218 \uc788\ub294 \uacf5\uac04\uc744 \uc608\uc57d\ud574\uc11c \uc628\uc804\ud788 \ub098\ub9cc\uc758 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. \\n\\n### Try\\n\\n**\ud5c8\ube0c\ud83c\udf3f\uc640\uc758 \ud2f0\ud0c0\uc784?** \\n\\n\uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc744 \ub298\ub9b4 \ubc29\ubc95\uc744 \uc0dd\uac01\ud558\ub2e4\uac00 \ub300\ud654\ub97c \ub098\ub204\uc9c0 \ubabb\ud55c \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \uae5c\uc9dd \ucee4\ud53c\ucc57\uc744 \ud558\uba74 \uc5b4\ub5a8\uae4c \uc0dd\uac01\ud588\ub2e4. \\n\uc608\ub97c \ub4e4\uc5b4 \uc7a1\ub2f4\ubc29\uc5d0 `\uc800\uc640 \ucee4\ud53c\ucc57 \ud558\uc2e4 \ubd84 :)` \ud558\uba74\uc11c \uc62c\ub9b4 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. \\n\ucc38\uc5ec\ud558\ub294 \uc0ac\ub78c\uc774 \uc788\uc744\uc9c0, \uc548 \uc88b\uac8c \ubcf4\ub294 \uac8c \uc544\ub2d0\uc9c0 \uac71\uc815\ub418\uc9c0\ub9cc \uadf8\ub798\ub3c4 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4. \\n\uc800\ub791 \ud5c8\ube0c\ud2f0 \ud55c\uc794 \ud558\uc2e4\ub798\uc694? \\n\\n**\uae30\uc220\uc801\uc778 \ubd80\ubd84** \\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc5d0 \uc870\uae08 \ub354 \ubb34\uac8c\ub97c \ub450\ub2e4 \ubcf4\ub2c8 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc774 \ubd80\uc871\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uc2dc\uac04\uc758 \uc5ec\uc720\uac00 \ub420 \ub54c \ucc45\uc744 \uc870\uae08\uc529 \uc77d\uc5b4\uc57c\uaca0\ub2e4. \\n\ube14\ub85c\uadf8\uc5d0 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \ub9ce\uc774 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\ub294 \uc2dc\uac04\ub3c4 \uac00\uc838\uc57c\uaca0\ub2e4. \\n\\n### \ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70 \\n\\n\uc2dc\uac04\uc774 \ube60\ub974\uac8c \ud758\ub7ec\uac14\ub2e4. \\n\ud0c0\uc778\uc5d0\uac8c \uc88b\uc740 \uc601\ud5a5\uc744 \uc8fc\uae30\uc704\ud574, \ubc29\ud559\ub3d9\uc548 \ub098\ub97c \ucc59\uae30\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. \\n\ub610\ud55c \ud568\uaed8 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc744 \ubaa9\ud45c\ub85c \uc55e\uc73c\ub85c\ub3c4 \uafb8\uc900\ud788 \uc758\uc2dd\uc801 \ub178\ub825\uc744 \ud574\uc57c\uaca0\ub2e4."},{"id":"chess-retrospective","metadata":{"permalink":"/chess-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0","description":"1, 2\ub2e8\uacc4//github.com/woowacourse/java-chess/pull/441","date":"2023-03-31T00:00:00.000Z","formattedDate":"2023\ub144 3\uc6d4 31\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":7.705,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0","slug":"chess-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0","permalink":"/woowacourse-level1-retrospective"},"nextItem":{"title":"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134","permalink":"/grasp"}},"content":":::note PR \ub9c1\ud06c \\n1, 2\ub2e8\uacc4: https://github.com/woowacourse/java-chess/pull/441 \\n3, 4\ub2e8\uacc4: https://github.com/woowacourse/java-chess/pull/529 \\n:::\\n\\n### \uccb4\uc2a4\\n\uccb4\uc2a4 \ubbf8\uc158\uc5d0\ub294 \uac00\ube44\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4! \\n\uccb4\uc2a4\ub294 \uc774\uc804 \ubbf8\uc158\ub4e4\ubcf4\ub2e4 \ud6e8\uc52c \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778\uc774\uc5c8\ub2e4. \\n\ud558\uc9c0\ub9cc \uac00\ube44\uc640 \ub098\ub294 \uccb4\uc2a4 \ub3c4\uba54\uc778\uc774 \uc775\uc219\ud574\uc11c \ub354 \ud3b8\ud55c \ub9c8\uc74c\uc73c\ub85c \uc2dc\uc791\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc5b4\ub824\uc6e0\ub358 \ubd80\ubd84\uc740 \uae30\ubb3c\uc758 \uc774\ub3d9, \uc774\ub3d9\uc2dc \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4. \\n \\n\uac00\ube44\uac00 \uc9d1\uc5d0\uac00\uc11c\ub3c4 \uae30\ubb3c\uc758 \uc774\ub3d9 \uad00\ub828\ud574 \uc0dd\uac01 \uc815\ub9ac\ud55c \uae00\uc744 \ubcf4\ub0b4\uc918\uc11c \ub354\uc6b1 \ube68\ub9ac \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ucd5c\uc885\uc801\uc73c\ub85c \uacb0\uc815\ud55c \ubd80\ubd84\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n**\uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5\uc5ec\ubd80** \\nRank\uc640 File\uc740 \uac01\uac01 \uc704\uce58\uac12\uc744 \uac00\uc9c0\uace0 \uc788\uace0, \uac12\uc758 \ucc28\uc774\ub97c \uc774\uc6a9\ud574\uc11c \uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uacc4\uc0b0\ud588\ub2e4. \\n\uc9c1\uc120 \u2192 Rank\uc640 File \ucc28\uc774 \uc911 \ud558\ub098\uac00 0\uc774\uc5b4\uc57c \ud55c\ub2e4. \\n\ub300\uac01\uc120 \u2192 Rank\uc640 File \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \uac19\uc544\uc57c \ud55c\ub2e4. ex) abs(-2) == abs(2) \\n\ub098\uc774\ud2b8 \u2192 \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \ud558\ub098\ub294 2 \ub098\uba38\uc9c0 \ud558\ub098\ub294 1\uc774\uc5b4\uc57c \ud55c\ub2e4.\\n\\n**\ub3c4\ucc29 \uce78\uc758 \uae30\ubb3c \uc5ec\ubd80** \\n\uc544\uad70 \u2192 \uc774\ub3d9\uc774 \ubd88\uac00\ub2a5\ud558\ub2e4. \\n\uc801\uad70 \u2192 \uc774\ub3d9\uc774 \uac00\ub2a5\ud558\ub2e4. \uc801\uad70\uc744 \uc7a1\ub294\ub2e4. \\n\\n**\uc911\uac04\uc5d0 \uae30\ubb3c \uc874\uc7ac \uc5ec\ubd80** \\n\uc774\ub3d9 \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\uba74 \uc548\ub41c\ub2e4. \\n\\n**\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0ac\uc6a9** \\n\uccb4\uc2a4 \ubbf8\uc158\uc740 \ud2b9\ubcc4\ud558\uac8c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc5f0\uacb0\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5c8\ub2e4. \\n\uccb4\uc2a4 \uac8c\uc784\uc758 \uc0c1\ud0dc\ub97c \ub2e4\uc74c\uc758 \ub450\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uc815\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n- \uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95 \\n- \uae30\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uac8c\uc784\uc744 \ubd88\ub7ec\uc640 \uae30\ubcf4\ub300\ub85c \uc774\ub3d9\uc2dc\ud0a4\ub294 \ubc29\ubc95 \\n\\n\uae30\ubb3c\uc774 \uc774\ub3d9\ud560 \ub54c\ub9c8\ub2e4 \uac12\uc744 \uc800\uc7a5\ud558\uace0 \uc2f6\uc5c8\uace0, \uae30\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud588\ub2e4. \\n\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\uc9c0 \uc54a\uc740 \uc774\uc720\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n- \ud134\uacfc \uac19\uc740 \ubd80\uac00\uc801\uc778 \uc694\uc18c\ub97c \uc800\uc7a5\ud574\uc57c \ud55c\ub2e4. \\n- \uc774\ub3d9\uc744 \ud560 \ub54c \uae30\ubb3c\uc774 \uc7a1\ud788\ub294 \uacbd\uc6b0 update \ucffc\ub9ac(\uc774\ub3d9 \uae30\ubb3c)\uc640 delete(\uc7a1\ud78c \uae30\ubb3c) 2\uac1c\uc758 \ucffc\ub9ac\ub97c \ub0a0\ub824\uc57c \ud55c\ub2e4. \\n- \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ub3c4\uba54\uc778\uc758 \ubcc0\uacbd\uc774 \ud06c\uac8c(\ucd08\uae30 \uc0c1\ud0dc\ub97c \uad6c\uc131\ud558\ub294 \ubd80\ubd84) \uc77c\uc5b4\ub098\uc57c \ud55c\ub2e4. \\n\\n\uc815\ub9ac\ud558\uc790\uba74 \uae30\ubb3c \uc804\uccb4 \uc800\uc7a5\uacfc \uae30\ubcf4 \uc800\uc7a5\uc740 \ub2e4\uc74c\uacfc \ucc28\uc774\uac00 \uc788\ub2e4. \\n\ubcf4\ub4dc\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc\uc5d0\uc11c 32\uac1c\uc758 Insert \ucffc\ub9ac(\uae30\ubb3c\uc758 \uc704\uce58) + \uae30\ubb3c \uc774\ub3d9 \uc2dc \uc6c0\uc9c1\uc784 \ubcc0\uacbd(\uc7a1\ud788\ub294 \uacbd\uc6b0 2\uac1c\uc758 \ucffc\ub9ac) \\n\uae30\ubcf4\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uad6c\uc131 + \uc800\uc7a5\ub41c \uae30\ubcf4\ub97c select \ucffc\ub9ac\ub85c \uc870\ud68c\ud574\uc11c \uc0ac\uc6a9(1\ud68c) + insert \ucffc\ub9ac(\uc774\ub3d9 \ub2f9 1\ud68c)\\n\\n\ucd94\uac00\ub85c \uae30\ubcf4\uc800\uc7a5\uc774 \uad6c\ud604\ub3c4 \ub354\uc6b1 \uac04\ub2e8\ud558\ub2e4. \ud83d\udc4d \\n\\n**\ubd80\uac00\uc801\uc778 \ubd80\ubd84**\\n\\n\ub9ac\ubdf0\uc5b4\uc778 \ucc30\ub9ac\ud83c\udf6b\uac00 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \uac8c\uc784\uc774 \uc9c4\ud589\ub41c\ub2e4\uba74 \uc5b4\ub5a8\uc9c0? \uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ub2e4\uc591\ud55c \uc2dc\ub3c4\ub97c \ud574\ubd24\ub2e4. \\n- \ub204\ub204\uc758 \ub3c4\uc6c0\uc73c\ub85c ConnectionPool \uad6c\ud604 \\n- ThreadLocal \uc0ac\uc6a9\ud574\uc11c \uc4f0\ub808\ub4dc \ubcc4 \uc138\uc158 \uad00\ub9ac \\n- \uc2e4\uc81c\ub85c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4\uc5d0\uc11c \uccb4\uc2a4 \uac8c\uc784\uc774 \uc9c4\ud589\ub418\ub294 Board\ub97c ConcurrentHashMap\uc73c\ub85c \uc800\uc7a5(\uc0ac\uc2e4 \uc774 \ubd80\ubd84\uc740 \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ud544\uc694\uc5c6\uc9c0\ub9cc 2\uba85\uc774 \uc11c\ub85c \uac8c\uc784\ud558\ub294 \uacbd\uc6b0\ub97c \uc0dd\uac01\ud574\uc11c \ub123\uc5b4\ubcf4\uc558\ub2e4.) \\n\\n\ub450 \uba85\uc774 \uc11c\ub85c \uac19\uc740 \ubc29\uc5d0 \uc785\uc7a5\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4\uba74 \ucd9c\ub825\ud558\ub294 \ubd80\ubd84\uc774 \uae4c\ub2e4\ub85c\uc6cc\uc9c8 \uac83 \uac19\ub2e4\uace0 \uc608\uc0c1\ub418\uc5b4(Board\uc5d0 \uc635\uc800\ubc84 \ud328\ud134\uc744 \uc0ac\uc6a9\ud574\uc57c\ub418\ub098?) \ud574\ubcfc \uc5c4\ub450\uac00 \ub098\uc9c0 \uc54a\uc558\ub2e4. \\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n**\uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc9c0 \ubabb\ud55c \ubd80\ubd84** \\nDB \uad00\ub828 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\ub3c4\uba54\uc778 \ub85c\uc9c1\uc5d0\ub9cc \uc9d1\uc911\ud558\ub2e4\ubcf4\ub2c8 \uc815\uc801 \uc911\uc694\ud55c DB\uc758 \ucf54\ub4dc\uc758 \uc608\uc678\ucc98\ub9ac, \ube48 \uac12\uc744 \ubc18\ud658 \ud558\ub294 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucc98\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\ud558\uc9c0\ub9cc \ucc30\ub9ac\uc758 \uaf3c\uaf3c\ud55c \ub9ac\ubdf0\ub85c DB\ubd80\ubd84\uacfc \ub098\ub9cc\uc758 JdbcTemplate\uc744 \uae54\ub054\ud558\uac8c \uad6c\ud604\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n**\uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ub2f4\uac10** \\n\ucd08\ubc18\uc5d0\ub294 \uc5ec\uc720\ub86d\uc9c0\ub9cc \uc81c\ucd9c \ub9c8\uac10\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \uc218\ub85d \uc0ac\ub78c\uc774 \uae09\ud574\uc9c0\ub294 \uac83 \uac19\ub2e4. \\n\ub2e4\uc74c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\ud560 \ub550 \uc18d\ub3c4\ub97c \uc870\uc808\ud558\uace0, \ub9c8\uc74c\uc5d0 \uc5ec\uc720\ub97c \uac00\uc838\uc57c\uaca0\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**DAO \uc911\ubcf5 \uc81c\uac70**\\n\\n\ud504\ub864\ub85c\uadf8\uc5d0 [\uae00](https://prolog.techcourse.co.kr/studylogs/2947)\uc744 \uc791\uc131\ud588\ub2e4. \\nDAO\ub97c \uc791\uc131\ud558\ub294\ub370 try-catch-resources\uc640 \uc5ec\ub7ec \ucf54\ub4dc\uac00 \uc911\ubcf5\ub418\uc11c \uc81c\uac70\ud558\uace0\uc2f6\uc5c8\ub2e4. \\n\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc73c\ub85c \uae54\ub054\ud558\uac8c \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\udc4d\\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\ud398\uc5b4 \uc0dd\uac01\ud558\uae30** \\n\uac00\ube44\ub294 \ub204\uad6c\ubcf4\ub2e4 \ud398\uc5b4\ub97c \uc0dd\uac01\ud558\uace0, \ubc30\ub824\ud574\uc8fc\ub294 \ud398\uc5b4\uc600\ub2e4. \\n\uc911\uac04 \uc911\uac04 \ub2f9 \ub5a8\uc5b4\uc9c8\uae4c\ubd10 \uac71\uc815\ub3c4 \ud574\uc8fc\uace0, \ub098\uc758 \ucee8\ub514\uc158\ub3c4 \ud655\uc778\ud574\uc92c\ub2e4! \\n\\n**\ubbf8\uc158 \ubab0\uc785\ud558\uae30** \\n\ucd5c\uadfc\uc5d0 \ubbf8\uc158\uc5d0 \uc798 \ubab0\uc785\ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\uac00\ube44\ub294 \ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \ubbf8\uc158\uc5d0 \ub300\ud55c \ubab0\uc785\ub3c4\uac00 \ub9e4\uc6b0 \uc88b\uc558\ub2e4. \\n\uc9d1\uc5d0\uac00\uc11c\ub3c4 \uccb4\uc2a4 \uc774\ub3d9\uc5d0 \ub300\ud55c \ub85c\uc9c1\uc744 \uc5b4\ub5bb\uac8c \uad6c\ud604\ud560 \uc9c0 \uc0dd\uac01\ud55c \ub4a4 \uaf3c\uaf3c\ud574\uc11c \uc815\ub9ac\ud574\uc11c \ub098\uc5d0\uac8c \ubcf4\ub0b4\uc8fc\uc5c8\ub2e4. \\n\ub355\ubd84\uc5d0 \ub098\ub3c4 \uac00\ube44\uc758 \uc0dd\uac01\uc744 \uc54c \uc218 \uc788\uc5b4\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294\ub370 \uac00\uc18d\ub3c4\uac00 \ubd99\uc740 \uac83 \uac19\ub2e4. \\n\ub610\ud55c \ubbf8\uc158\uc744 \uc798 \ub9c8\ubb34\ub9ac\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c\uc774 \uc804\ub2ec\ub418\uc11c \uadf8\ub7f0\uc9c0 \ub098\ub3c4 \ub369\ub2ec\uc544 \uc5f4\uc2ec\ud788 \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\ude04 \\n\\n**\uc194\uc9c1\ud568** \\n\uba3c\uc800 \ud68c\uace0\ud558\uc790\uace0 \ub9d0 \uac78\uc5b4\uc918\uc11c \uc815\ub9d0 \uace0\ub9c8\uc6e0\ub2e4\uace0 \ud45c\ud604\ud574\uc8fc\ub294 \ubd80\ubd84 \\n\ubaa8\ub974\ub294\uac8c \uc788\uc73c\uba74 \uc194\uc9c1\ud558\uac8c \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84 \\n\ub098\uc758 \uc758\uacac\uc744 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud55c \uc0c1\ud0dc\ub85c \uc804\ub2ec\ud560 \ub54c \uc774\ud574\uac00 \uc548\ub418\uc5c8\ub2e4\uace0 \uc815\ud655\ud788 \uc804\ub2ec\ud574\uc8fc\ub294 \ubd80\ubd84 \\n\uc194\uc9c1\ud568\uc740 \ud398\uc5b4\ud560 \ub54c \uc911\uc694\ud55c \ubd80\ubd84\uc778 \uac83 \uac19\ub2e4. \\n\\n\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ucc30\ub9ac\ud83c\udf6b \uccb4\uc2a4 \ubbf8\uc158\ub54c \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0 \ub0a8\uaca8\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4!"},{"id":"grasp","metadata":{"permalink":"/grasp","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-30-GRASP.mdx","source":"@site/blog/2023-1/2023-03-30-GRASP.mdx","title":"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134","description":"GRASP(General Responsibility Assignment Software Pattern)","date":"2023-03-30T00:00:00.000Z","formattedDate":"2023\ub144 3\uc6d4 30\uc77c","tags":[{"label":"GRASP","permalink":"/tags/grasp"},{"label":"OOP","permalink":"/tags/oop"}],"readingTime":8.085,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134","slug":"grasp","tags":["GRASP","OOP"]},"prevItem":{"title":"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0","permalink":"/chess-retrospective"},"nextItem":{"title":"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0","permalink":"/blackjack-retrospective"}},"content":"### GRASP(General Responsibility Assignment Software Pattern)\\n\\n\ud06c\ub808\uc774\uadf8 \ub77c\ub9cc\uc758 Applying UML and Patterns\uc774\ub77c\ub294 \ucc45\uc5d0\uc11c \ub098\uc628 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134\\n\\n\uac01 \ud328\ud134\ub9c8\ub2e4 Solution\uacfc Problem\ub85c \uad6c\uc131\ub418\uc5b4 \uc788\ub2e4.\\n\\n### \uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)\\n\\nQ: \uac1d\uccb4\uc5d0 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uae30\ubcf8 \uc6d0\uce59\uc740 \ubb34\uc5c7\uc778\uac00?\\n\\nA: \ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub370 \ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \ud074\ub798\uc2a4(\uc815\ubcf4 \uc804\ubb38\uac00)\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4.\\n\\n\uc815\ubcf4\uc640 \ud589\ub3d9\uc744 \uac00\uae4c\uc6b4 \uacf3\uc5d0 \uc704\uce58\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \ucea1\uc290\ud654\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4.\\n\\n\ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \uac1d\uccb4\ub4e4\ub85c \ucc45\uc784\uc774 \ubd84\uc0b0\ub41c\ub2e4.\\n\\n### \ucc3d\uc870\uc790 \ud328\ud134(Creator)\\n\\nQ: \ub204\uac00 \uac1d\uccb4 A\ub97c \uc0dd\uc131\ud558\ub294\uac00?\\n\\nA: \ub2e4\uc74c\uc758 \uc870\uac74\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\uc871\ud558\ub294 \uac1d\uccb4\uc5d0\uac8c \uac1d\uccb4 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4.\\n\\n- B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4.\\n- B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4.\\n- B\uac00 A \uac1d\uccb4\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4.\\n- B\uac00 A \uac1d\uccb4\uc758 \ucd08\uae30\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4.\\n\\n\uc0dd\uc131 \uc608\uc815\uc778 \uac1d\uccb4\uc640 \uc5f0\uad00\ub418\uc5b4 \uc788\ub294 \uac1d\uccb4\uac00 \uc0dd\uc131 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uac8c \ub41c\ub2e4\uba74, \uc774\ubbf8 \ud574\ub2f9 \uac1d\uccb4\uc640 \uacb0\ud569\ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\uac8c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4.\\n\\n### \ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)\\n\\nQ: \uc758\uc874\uc131\uc744 \ub0ae\ucd94\uace0 \ubcc0\ud654\uc758 \uc601\ud5a5\uc744 \uc904\uc774\uba70 \uc7ac\uc0ac\uc6a9\uc131\uc744 \uc99d\uac00\uc2dc\ud0a4\ub294 \ubc29\ubc95\uc740?\\n\\nA: \uc804\uccb4\uc801\uc778 \uacb0\ud569\uc774 \ub0ae\uac8c \uc720\uc9c0\ub418\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4.\\n\\n> \uacb0\ud569\ub3c4(Coupling)\\n\uac1d\uccb4 \uc0ac\uc774\uc758 \uc758\uc874\uc131\uc774 \uacfc\ud55c \uacbd\uc6b0 \uacb0\ud569\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4.\\n- \uc624\ube0c\uc81d\ud2b8 p.17\\n> \\n\\n\uacb0\ud569\ub3c4\ub97c \ub0ae\ucd98\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4.\\n\\n- \ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\uc758 \ubcc0\ud654\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294\ub2e4.\\n- \uc7ac\uc0ac\uc6a9\uc774 \ud3b8\ub9ac\ud574\uc9c4\ub2e4.\\n- \ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\uc758\uc874\ud558\ub294 \ud074\ub798\uc2a4\uac00 \uc801\uae30 \ub54c\ubb38\uc5d0)\\n\\n### \ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)\\n\\nQ. \uac1d\uccb4\ub97c \uad00\ub9ac\ud558\uae30 \uc27d\uac8c \ud558\ub824\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?\\n\\nA. \ub192\uc740 \uc751\uc9d1\ub3c4\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4.\\n\\n> \uc751\uc9d1\ub3c4(Cohesion)\\n\uc5f0\uad00\ub41c \uc791\uc5c5\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc5f0\uad00\uc131 \uc5c6\ub294 \uc791\uc5c5\uc740 \ub2e4\ub978 \uac1d\uccb4\uc5d0\uac8c \uc704\uc784\ud558\ub294 \uac1d\uccb4\ub97c \uac00\ub9ac\ucf1c \uc751\uc9d1\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4.\\n- \uc624\ube0c\uc81d\ud2b8 p.26\\n> \\n\\n\ubcc0\uacbd\uc758 \uc774\uc720\uc5d0 \ub530\ub77c \ud074\ub798\uc2a4\ub97c \ubd84\ub9ac\ud55c\ub2e4\uba74 \uc751\uc9d1\ub3c4\ub97c \ub192\uc77c \uc218 \uc788\uace0, \uc751\uc9d1\ub3c4\uac00 \ub192\uc544\uc9c4\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4.\\n\\n- \ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\ud560\ub2f9\ub41c \ucc45\uc784\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0)\\n- \uc720\uc9c0\ubcf4\uc218\uac00 \uc26c\uc6cc\uc9c4\ub2e4.\\n- \ub0ae\uc740 \uacb0\ud569\ub3c4 \ub610\ud55c \uc9c0\uc6d0\ud55c\ub2e4.\\n- \uc751\uc9d1\ub3c4\uac00 \ub192\uc740 \ud074\ub798\uc2a4\ub294 \ud2b9\uc815\ud55c \ubaa9\uc801\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc7ac\uc0ac\uc6a9\ud558\uae30 \uc88b\ub2e4.\\n\\n### \ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)\\n\\nQ. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uac83\uc740 \ub204\uac00 \ub2f4\ub2f9\ud574\uc57c \ud558\ub294\uac00?\\n\\nA. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 Controller \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4.\\n\\n\uc5b4\ub5a4 \uc11c\ube0c\uc2dc\uc2a4\ud15c\uc774 \uc874\uc7ac\ud55c\ub2e4\uace0 \uac00\uc815\ud560 \ub54c\\n\\n- \uc9c1\uc811\uc801\uc73c\ub85c \uac1d\uccb4\uc5d0 \uc811\uadfc\ud558\uc5ec \ud504\ub85c\uadf8\ub7a8\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uacb0\ud569\ub3c4\uac00 \uc0c1\uc2b9\ud55c\ub2e4.\\n- \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc5d0 \ub4e4\uc5b4\uc624\ub294 \uc694\uccad\uc744 \ucc98\ub9ac\ud574\uc8fc\ub294 \ucee8\ud2b8\ub864\ub7ec\uac00 \uc788\ub2e4\uba74 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 \ud574\ub2f9 \ucee8\ud2b8\ub864\ub7ec\ub9cc \uc54c\uba74 \ub41c\ub2e4.\\n- \ub9cc\uc57d \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc758 \ubcc0\uacbd\uc774 \uc0dd\uacbc\uc744 \ub54c \uc678\ubd80\uc5d0 \ubbf8\uce58\ub294 \uc601\ud5a5\ub3c4 \uc904\uc5b4\ub4e0\ub2e4.\\n\\n### \ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)\\n\\nQ. \uac1d\uccb4\uc758 \ud0c0\uc785\uc5d0 \ub530\ub77c \ud589\ub3d9\uc774 \ubc14\ub010\ub2e4\uba74 \ucc45\uc784\uc744 \uc5b4\ub5bb\uac8c \ud560\ub2f9\ud574\uc57c \ud560\uae4c?\\n\\nA. OOP\uac00 \uc9c0\uc6d0\ud558\ub294 \ub2e4\ud615\uc131\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ud65c\uc6a9\ud55c\ub2e4. (\uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0 \ud589\ub3d9\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uad6c\ud604)\\n\\n\uac1d\uccb4\uc758 \uc885\ub958\uc5d0 \ub530\ub77c \ubd84\uae30\ud558\ub294 \uc870\uac74\ubb38\uc774 \uc544\ub2cc \ub2e4\ud615\uc131\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4.\\n\\n\uc0c8\ub85c\uc6b4 \ud0c0\uc785\uc774 \ucd94\uac00\ub418\uc5c8\uc744 \ub54c \uc870\uac74\ubb38\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uae30\uc874\uc758 \uc870\uac74\ubb38\uc744 \uc218\uc815\ud574\uc57c \ud558\uc9c0\ub9cc \ub2e4\ud615\uc131\uc744 \ud65c\uc6a9\ud558\uba74 \uc27d\uac8c \ud655\uc7a5\ud560 \uc218 \uc788\ub2e4.\\n\\n### \ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)\\n\\nQ. \uc5b4\ub5bb\uac8c \ud558\uba74 \ubcc0\uacbd\uc774 \ub2e4\ub978 \uc694\uc18c\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub3c4\ub85d \ubc29\uc9c0\ud560 \uc218 \uc788\uc744\uae4c?\\n\\nA. \ubcc0\ud654\uac00 \uc608\uc0c1\ub418\ub294 \uc9c0\uc810\uc744 \uc2dd\ubcc4\ud558\uace0, \uc8fc\uc704\uc5d0 \uc548\uc815\ub41c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ud615\uc131\ud558\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4.\\n\\n### \uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)\\n\\nQ. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc758 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud558\uace0 \uc2f6\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?\\n\\nA. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ub2e4\ub978 \uac1d\uccb4\ub97c \ub450\uc5b4 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud560 \uc218 \uc788\ub2e4.\\n\\n\uc911\uc7ac\uc790 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ud558\ub098\uc758 \uac1d\uccb4\ub97c \ucd94\uac00\ud558\uc5ec \ubcf5\uc7a1\ud55c \uad00\uacc4\ub97c \ub2e8\uc21c\ud654\ud560 \uc218 \uc788\ub2e4.\\n\\n\uc911\uac04\uc5d0 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub454\ub2e4\uba74 \ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)\uc5d0 \ud574\ub2f9\ub41c\ub2e4.\\n\\n### \uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)\\n\\nQ. \ucc45\uc784\uc744 \ud560\ub2f9\ud55c \ub3c4\uba54\uc778 \uac1d\uccb4\uac00 Low Coupling, High Cohesion, \uc7ac\uc0ac\uc6a9\uc131 \ub4f1\uc758 \ubaa9\uc801\uc744 \uc704\ubc18\ud55c\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?\\n\\nA. \ub3c4\uba54\uc778 \uac1c\ub150\uc744 \ud3ec\ud568\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uace0 \ub9e4\uc6b0 \uc751\uc9d1\ub41c \ucc45\uc784\uc744 \ud560\ub2f9\ud560 \uc218 \uc788\ub2e4.\\n\\n\ud589\ub3d9\uc744 \ucd94\uac00\ud560 \ub54c, \ud574\ub2f9 \ucc45\uc784\uc744 \uc218\ud589\ud560 \ub3c4\uba54\uc778 \uac1c\ub150\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \ub3c4\uba54\uc778\uacfc \ubb34\uad00\ud55c \uc778\uacf5\uc801\uc778 \uac1d\uccb4\ub97c \ub9cc\ub4e0\ub2e4\uc74c \ud574\ub2f9 \uac1d\uccb4\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4.\\n\\n\uac1d\uccb4\uac00 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud574\uc57c \ud560 \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4\uace0, \uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134\uc744 \uc801\uc6a9\ud558\uc5ec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud558\ub77c\ub294 \ucc45\uc784\uc744 \uac00\uc9c0\ub77c\uace0 \ud558\uc9c0 \uc54a\ub294\ub2e4.\\n\\n\uc608) \uc0c1\uc810\uacfc \uace0\uac1d \ud074\ub798\uc2a4\uac00 \uc788\uace0 \uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uace0 \uac00\uc815\\n\\n- \uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0 \uac70\ub798\ub97c \ud558\ub824\uba74 \ud658\uc804\uc744 \ud574\uc57c\ud55c\ub2e4.\\n- \ub450 \ud074\ub798\uc2a4 \ub2e4 \ud658\uc804\uc5d0 \ub300\ud55c \ucc45\uc784\uc744 \ubd80\uc5ec\ud558\uae30 \uc560\ub9e4\ud558\ub2e4\uba74 \ud658\uc804\uc744 \ucc45\uc784\ud558\ub294 \ud074\ub798\uc2a4\ub97c \ucd94\uac00\ud558\uace0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\uc624\ube0c\uc81d\ud2b8 5\uc7a5. \ucc45\uc784 \ud560\ub2f9\ud558\uae30, [\uc870\uc601\ud638](http://aeternum.egloos.com/)\\n\\nApplying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman\\n\\n[GRASP, \ud55c\ube5b \ub124\ud2b8\uc6cc\ud06c](https://www.hanbit.co.kr/network/category/category_view.html?cms_code=CMS8586826397)"},{"id":"blackjack-retrospective","metadata":{"permalink":"/blackjack-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx","title":"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/java-blackjack/pull/427","date":"2023-03-14T00:00:00.000Z","formattedDate":"2023\ub144 3\uc6d4 14\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":5.17,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0","slug":"blackjack-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134","permalink":"/grasp"},"nextItem":{"title":"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0","permalink":"/ladder-retrospective"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/java-blackjack/pull/427 \\n2\ub2e8\uacc4: https://github.com/woowacourse/java-blackjack/pull/537 \\n:::\\n\\n### \ube14\ub799\uc7ad\\n\\n\ube14\ub799\uc7ad \ubbf8\uc158\uc5d0\uc11c\ub294 \ud6c4\ucd94\uc640 \ud398\uc5b4(\uc870\ubbf8\ub8cc \ub4c0\uc624?)\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4. \\n\uc774\ubc88\uc5d0\ub294 \uc2e4\uc218\ud558\uc9c0 \uc54a\uace0, \ubc14\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uc9c0 \uc54a\uace0 \uce5c\ud574\uc9c0\uae30 \ubd80\ud130 \uc2dc\uc791\ud588\ub2e4. \\n\\n\ube14\ub799\uc7ad\uc740 \uad6c\ud604\ud574\uc57c \ub420 \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud560 \uac83 \uac19\uc558\uc9c0\ub9cc \\n\ud6c4\ucd94\uc640 \ud568\uaed8 \uc804\ub7b5\uc801(\uc0bc\uc77c\uc808\uc5d0 \ubbf8\uc158 \uc774\uc57c\uae30 \ub098\ub204\uae30)\uc73c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud574 \uc2dc\uac04 \ub0b4\uc5d0 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n\ubbf8\uc158\uc744 \ub05d\ub098\uace0 \ud68c\uace0\ub97c \ud588\uc744 \ub54c \ud6c4\ucd94\uac00 \uace0\ubbfc\uac70\ub9ac\ub97c \ud558\ub098 \ub0b4\uc92c\ub2e4. \\n\\"\ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \uc555\ubc15\uac10\uc744 \ub290\ub07c\ub294 \ud398\uc5b4\uac00 \uc788\ub2e4\uba74 \ud5c8\ube0c\uac00 \ud574\uc904 \uc218 \uc788\ub294\uac8c \ubb50\uac00 \uc788\uc744\uae4c?\\" \\n\\n\uacf0\uacf0\ud788 \uc0dd\uac01\ud574\ubd24\uc9c0\ub9cc \uc27d\uac8c \ub2f5\uc744 \ub0b4\ub9b4 \uc218 \uc5c6\uc5c8\ub2e4. \\n\uc911\uac04 \uc911\uac04 \ud68c\uace0\ub97c \ud558\uace0, \ub098\uc758 \uc18c\ud504\ud2b8\uc2a4\ud0ac\uc744 \ub192\ud788\ub294\uac8c \ub2f5\uc77c\uae4c? \\n\ubd80\ub2f4\uac10\uc744 \ub290\ub07c\uc9c0 \uc54a\uace0 \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub420 \uc218 \uc788\ub3c4\ub85d \uacc4\uc18d \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4. \\n\\n\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc0dd\uac01\uc774 \ub9ce\uc544\uc838\uc11c \uc804 \ub9ac\ubdf0\uc5b4\uc778 \ud130\ud2c0\ud83d\udc22\uacfc\ub3c4 \ub300\ud654\ub97c \ub098\ub204\uc5c8\ub2e4. \\n\ud130\ud2c0\uc740 \uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84(\uad81\uadf9\uc801\uc778 \ubaa9\ud45c\uc778 \uc88b\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uac83)\uc5d0 \uc9d1\uc911\ud574\ubcf4\ub77c\uace0 \ud558\uc168\ub2e4. \\n\\n\uc88b\uc740 \ucf54\ub4dc, \uc88b\uc740 \ud398\uc5b4\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc77c\ub2e8 \uc9c0\uc18d\uc801\uc73c\ub85c \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4.\\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n**\ud398\uc5b4 \uc2e0\uacbd\uc4f0\uae30** \\n\uc774\ubc88 \ud398\uc5b4\ud560 \ub54c \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub0b4\ubcf4\ub3c4\ub85d \ud588\ub2e4. \uadf8\ub807\uae30\uc5d0 \ub108\ubb34 \uc758\uacac\uc744 \uac15\ud558\uac8c \ubc00\uc5b4\ubd99\uc778 \ub290\ub08c\uc774 \ub4e4\uc5b4\uc11c \ubbf8\uc548\ud588\ub2e4. \\n\ud6c4\ucd94\uac00 \uc555\ubc15\uc744 \ub290\uaf08\uc744 \uc218\ub3c4 \uc788\uc744 \uac83 \uac19\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4. \\n\uc911\uac04 \uc911\uac04 \uc791\uc740 \ud68c\uace0\ub97c \uc9c4\ud589\ud574\ubcf4\ub294 \uac83\uc774 \uc88b\uc744\uae4c?\\n\\n**\uccb4\ub825 \uad00\ub9ac** \\n\uc694\uc998 \uc798 \ubabb\uba39\ub294 \uac83 \uac19\ub2e4. \\n\uc55e\uc73c\ub85c \uc0b4 \ub0a0\uc774 \ub9ce\uc740\ub370 \uc798 \ucc59\uaca8\uba39\uace0, \ud798\ub0b4\uc57c\uaca0\ub2e4.\\n\\n**\uc911\uac04 \uc911\uac04 \ub3cc\uc544\ubcf4\uae30** \\n\uc774\ubc88 \ubbf8\uc158\uacfc \uad00\ub828\ub41c \ub0b4\uc6a9\uc740 \uc544\ub2c8\uc9c0\ub9cc \uc6b0\ud14c\ucf54\ub97c \uc798 \ud65c\uc6a9 \ud558\uace0 \uc788\ub294\uc9c0 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4. \\n\ub0b4\uac00 \uc6b0\ud14c\ucf54\uc5d0 \uc9c0\uc6d0\ud55c \uc774\uc720\ub97c \ud56d\uc0c1 \uc78a\uc9c0 \uc54a\uc544\uc57c\uaca0\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**\uc0c1\ud0dc \ud328\ud134** \\n\uac1d\uccb4\uc758 \ub0b4\ubd80 \uc0c1\ud0dc\uc5d0 \ub530\ub77c \uc2a4\uc2a4\ub85c \ud589\ub3d9\uc744 \ubcc0\uacbd\ud558\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc73c\ub85c if/else/switch\uc640 \uac19\uc740 \uc870\uac74\ubb38\uc744 \ud6a8\uacfc\uc801\uc73c\ub85c \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. \\n\ube14\ub799\uc7ad \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc0c1\ud0dc \ud328\ud134\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ucc98\uc74c \uc801\uc6a9\ud574\ubcf4\uc558\ub2e4. \\n\ucc98\uc74c \uc801\uc6a9\ud558\uae30 \uc804\uc5d0\ub294 \ubcc4\ub85c\ub77c\uace0 \uc0dd\uac01\ud588\ub294\ub370, \uc0dd\uac01\ubcf4\ub2e4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4. \\n\\n**\uc77c\uad00\uc131, \uac00\ub3c5\uc131, \ucd94\uc0c1\ud654** \\n\uc774\ubc88 \ub9ac\ubdf0\uc5b4\ub294 \uac80\ud504\ud83c\udf6b \uc600\ub2e4! \\n\uac80\ud504\uc758 \ub9ac\ubdf0\ub294 \uac04\uacb0\ud568\uc5d0 \uad00\ub828\ub41c \ub0b4\uc6a9\uc774 \ub9ce\uc558\ub2e4. \\n\uc77c\uad00\uc131\uc774 \uc788\ub294 \ucf54\ub4dc, \uac00\ub3c5\uc131\uc774 \uc88b\uc740 \ucf54\ub4dc, \ucd94\uc0c1\ud654\uac00 \uc798 \ub418\uc5b4\uc788\ub294 \ucf54\ub4dc \\n\uc77d\uae30 \uc88b\uace0, \uac04\uacb0\ud55c \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \ubc29\ubc95\uc744 \ubc30\uc6b4 \uac83 \uac19\ub2e4. \\n\ucf54\ub4dc\ub97c \ubc14\ub77c\ubcf4\ub294 \uc2dc\uc810\uc774 \ud558\ub098 \ub298\uc5b4\ub09c \uae30\ubd84\uc774\ub2e4!(\uc55e\uc73c\ub85c \uc801\uc6a9\ud558\ub294 \uac83\uc740 \ub098\uc758 \ubaab\uc774\uc9c0\ub9cc) \\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\uc0dd\uac01 \uc815\ub9ac** \\n\uc911\uac04 \uc911\uac04 \ud604\uc7ac \uc0c1\ud669\uc5d0 \ub300\ud574 \uadf8\ub9bc\uc744 \uadf8\ub9ac\uac70\ub098, \uae00\uc744 \uc801\uc73c\uba74\uc11c \uc815\ub9ac\ud55c\ub2e4. \\n\ud398\uc5b4\uc640 \ub3d9\uc77c\ud55c \ubd80\ubd84\uc744 \uc774\ud574\ud558\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. \\n\uc9c4\ud589\ud558\ub294\ub370 \ub9e4\uc6b0 \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\ub098\ub3c4 \ub2e4\uc74c \ud398\uc5b4\ub54c\ubd80\ud130 \ud39c\uc774\ub791 \uc885\uc774\ub97c \uc900\ube44\ud574\uc57c\uaca0\ub2e4.\\n\\n**\uac00\uac10\uc5c6\uc774 \uc758\uacac\uc744 \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84** \\n\uc9c4\ud589 \uc0c1\ud669\uc5d0 \ub300\ud55c \ubd80\ubd84, \uc9c4\ud589 \uc18d\ub3c4, \uc9c0\uae08 \uc790\uc2e0\uc774 \uc774\ud574\ud558\uace0 \uc788\ub294 \ubd80\ubd84\uc744 \ub9d0\ud574\uc918\uc11c \ud3b8\ud588\ub2e4. \\n\ud68c\uace0\ub54c\ub3c4 \uc11c\ub85c \uc194\uc9c1\ud558\uac8c \uc758\uacac\uc744 \uc8fc\uace0 \ubc1b\uc544\uc11c \uc88b\uc558\ub2e4. \\n\\n**\ub3c4\uba54\uc778 \uc5b8\uc5b4\uc5d0 \uc2e0\uacbd\uc4f0\ub294 \ubd80\ubd84** \\n\ud074\ub798\uc2a4\uba85, \ubcc0\uc218\uba85\uacfc \uac19\uc740 \uc5b8\uc5b4\ub97c \uc138\uc2ec\ud558\uac8c \uc2e0\uacbd\uc4f4\ub2e4. \\n\uc694\uad6c\uc0ac\ud56d \uc815\ub9ac\ub3c4 \uae54\ub054\ud558\uac8c \uc798\ud558\ub294 \uac83 \uac19\ub2e4. \\n\\n\ud6c4\ucd94 \ucd5c\uace0 \ud83d\udc4d"},{"id":"ladder-retrospective","metadata":{"permalink":"/ladder-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/java-ladder/pull/97","date":"2023-02-26T00:00:00.000Z","formattedDate":"2023\ub144 2\uc6d4 26\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":10.285,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0","slug":"ladder-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0","permalink":"/blackjack-retrospective"},"nextItem":{"title":"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0","permalink":"/racing-car-retrospective"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/java-ladder/pull/97 \\n2\ub2e8\uacc4: https://github.com/woowacourse/java-ladder/pull/234 \\n:::\\n\\n### \uc0ac\ub2e4\ub9ac \ud0c0\uae30\\n\\n\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc6b0\uac00\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4. \\n\uc774\uc804 \ubbf8\uc158\uacfc \ub2ec\ub9ac TDD\ub85c \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ud544\uc218\uc600\uae30 \ub54c\ubb38\uc5d0 \uc775\uc219\ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, \uc6b0\uac00\uc640 \ubbf8\uc158\uc5d0 \uad00\ud55c \uc18c\ud1b5\uc774 \uc798 \ub418\uc5b4\uc11c \ud070 \ubb38\uc81c \uc5c6\uc774 \ubbf8\uc158\uc744 \ub9c8\ubb34\ub9ac\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n\uc6b0\uac00\uc640 \uc774\uc57c\uae30\uac00 \uc798 \ud1b5\ud574\uc11c \uadf8\ub7f0\uc9c0 1\ub2e8\uacc4\ub294 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub294\ub370, 2\ub2e8\uacc4\uc5d0\uc11c \ub9ce\uc774 \uace0\uc804\ud55c \uac83 \uac19\ub2e4.\\n\\n2\ub2e8\uacc4\uc5d0\uc11c\ub294 2\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ud574\ubd24\ub2e4.\\n\\n1. LadderGame\uc5d0\uc11c Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\\n2. Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c Ladder\uc5d0\uac8c Position\uc744 \ub118\uaca8\uc8fc\uba70 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95\\n\\n### Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\\n\\n\uc0ac\uc2e4\uc0c1 index\ub97c Ladder\uc5d0\uac8c \ub118\uaca8\uc8fc\uace0, \ud574\ub2f9 index\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc1b\ub294 \ubc29\ubc95\uacfc \uc720\uc0ac\ud588\ub2e4. \\n\uad6c\ud604\ud558\uace0 \ub098\ub2c8 \ub2e4\ub978 \ud074\ub798\uc2a4\ub4e4\uc774 Position\uc5d0 \ub300\ud55c \uc758\uc874\ub3c4\uac00 \ub108\ubb34 \ub192\uc740 \uac83 \uac19\uc558\ub2e4. \\n\ub610\ud55c Players\uac00 \ubcc4\ub2e4\ub978 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uc9c0 \uc54a\ub2e4\uace0 \ub290\uaf08\ub2e4. \\n\\n```mermaid\\ngraph TD\\n\\n LadderGameController --\x3e LadderGame\\n LadderGame --\x3e Ladder\\n LadderGame --\x3e Players\\n LadderGame --\x3e Items\\n\\n Ladder --\x3e Line\\n Line --\x3e LineStatus\\n\\n LadderGame --\x3e Position\\n Ladder --\x3e Position\\n Items --\x3e Position\\n Line --\x3e Position\\n Players --\x3e Position\\n\\n LadderGame --\x3e LadderGameResult\\n\\n Items --\x3e Item\\n Players --\x3e Player\\n\\n LadderGameController --\x3e InputView\\n LadderGameController --\x3e OutputView\\n\\n```\\n\\n```java\\npublic LadderGameResult play() {\\n final Map<Player, Item> result = new LinkedHashMap<>();\\n // \uc0ac\uc6a9\uc790 \uc218\ub9cc\ud07c Position\uc744 \uac00\uc838\uc640\uc11c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4.\\n for (Position position : Position.range(players.count())) {\\n final Position resultPosition = ladder.play(position);\\n result.put(players.get(position), items.get(resultPosition));\\n }\\n return new LadderGameResult(result);\\n}\\n```\\n\\n### Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\\n\\nPosition\uc5d0 \ub300\ud55c \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub294 Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c, Player\uac00 Ladder\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4. \\n\uc774 \ubc29\ubc95\uc774 \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc704\ud574\uc11c \uac1d\uccb4\ub4e4\uc774 \uae34\ubc00\ud558\uac8c \ud611\ub825\ud558\uace0, \uc870\uae08 \ub354 \ucc45\uc784\uc758 \ubd84\ubc30\uac00 \uc798 \ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\uc774 \ub418\uc5c8\ub2e4. \\n\\n```mermaid\\ngraph TD\\n\\n LadderGameController --\x3e LadderGame\\n LadderGame --\x3e Ladder\\n LadderGame --\x3e Players\\n LadderGame --\x3e Items\\n\\n Ladder --\x3e Line\\n Line --\x3e LineStatus\\n Line --\x3e Position\\n\\n Players --\x3e Ladder\\n Player --\x3e Ladder\\n\\n Item --\x3e Position\\n Player --\x3e Position\\n\\n\\n LadderGame --\x3e LadderGameResult\\n\\n Items --\x3e Item --\x3e ItemName\\n Players --\x3e Player --\x3e PlayerName\\n\\n LadderGameController --\x3e InputView\\n LadderGameController --\x3e OutputView\\n\\n OutputView --\x3e LadderMessageGenerator\\n```\\n\\n```java\\npublic LadderGameResult play() {\\n // \ucc38\uac00\uc790\ub4e4\uc5d0\uac8c \uc0ac\ub2e4\ub9ac\ub97c \uc804\ub2ec\ud574\uc11c \uc0ac\ub2e4\ub9ac\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \ud55c\ub2e4.\\n final Map<Player, Position> playResult = players.play(ladder);\\n\\n final Map<Player, Item> result = new LinkedHashMap<>();\\n for (Player player : playResult.keySet()) {\\n result.put(player, toItem(playResult.get(player)));\\n }\\n return new LadderGameResult(result);\\n}\\n```\\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n**\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\uc5d0 \uc2dc\uac04\uc744 \ub4e4\uc774\uae30** \\n\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc815\ud558\ub294\ub370 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ub4e4\uc5ec\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uc0ac\ub2e4\ub9ac \ud0c0\uae30\uc758 \uc2e4\ud589 \uacb0\uacfc\ub97c Item\uc73c\ub85c \uc9d3\ub2e4\ub2c8.. \ubb54\uac00 \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\ub2e4. \\n\uc774\uc804 \ubbf8\uc158\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c, \uba85\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \ubd80\uc871\ud568\uc744 \ub9ce\uc774 \ub290\uaf08\ub2e4. \\n\\n**\ud398\uc5b4\uc640 \uc870\uae08 \ub354 \uce5c\ud574\uc9c0\uae30** \\n\uccab\ub0a0\uc740 \ud398\uc5b4\uc640 \uce5c\ud574\uc9c0\ub294 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \uac00\uc838\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uc6b0\uac00\ub791 \ud68c\uace0\ud560 \ub54c \ub0b4\uac00 \uc2dc\uc791\ud558\uc790\ub9c8\uc790 \ucee8\ubca4\uc158 \uc815\ud558\uc790\uace0 \ud574\uc11c \ub9ce\uc774 \ub2f9\ud669\uc2a4\ub7ec\uc6e0\ub2e4\uace0 \ud55c\ub2e4. \uc6b0\uac00 \ubbf8\uc548.. \ud83e\udd72\\n\\n**README\ub97c \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c** \\n\uc774\uc0c1\ud558\uac8c \ucf54\ub529\uc5d0 \uc9d1\uc911\ud558\uba74 README\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\uba74\uc11c \uac19\uc774 \ucee4\ubc0b \ud558\ub294 \uac78 \ud56d\uc0c1 \uae4c\uba39\ub294\ub2e4. \\n\ub2e4\uc74c \ubbf8\uc158\uc5d0\ub294 \uc870\uae08 \ub354 \uc2e0\uacbd \uc368\uc57c\uaca0\ub2e4.\\n\\n**\uc88b\uc740 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud558\uae30** \\n\uccab PR\ub54c \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \uc9c8\ubb38\uc744 \ub0a8\uae30\uc9c0 \ubabb\ud588\ub2e4. \\n\ub9ac\ubdf0\uc5b4\uc640\uc758 \uc2dc\uac04\uc774 \uc18c\uc911\ud55c \uc2dc\uac04\uc774\ub77c\ub294 \uac83\uc744 \uae4c\uba39\uc9c0 \ub9d0\uace0, \ub098\uc758 \uc131\uc7a5\uc5d0 \ub3c4\uc6c0\uc774 \ub420 \uc218 \uc788\ub294 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud574\uc57c\uaca0\ub2e4. \\n\\n**PR \ud6c4\uc5d0\ub3c4 \uaf3c\uaf3c\ud558\uac8c \ud655\uc778\ud558\uae30** \\n\ubd84\uba85 \uc54c\uace0 \uc788\ub294 \ubd80\ubd84\uc774\uc9c0\ub9cc, \ub193\uce5c \ubd80\ubd84\uc774 \ub9ce\uc740 \uac83 \uac19\uc558\ub2e4. \\nPR \ud558\uae30 \uc804\uc5d0\ub3c4 \uacc4\uc18d \ud655\uc778\uc744 \ud588\uc9c0\ub9cc, \uc544\ubb34\ub798\ub3c4 IntelliJ\uc5d0\uc11c \ubcf4\ub2c8 \ucf54\ub4dc\uc5d0 \uc775\uc219\ud574\uc838\uc11c \uadf8\ub7f0\uc9c0 \ubcc0\uacbd\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc798 \uc548\ubcf4\uc600\ub2e4. \\ngithub pr\uc5d0\uc11c\ub294 \uc804\uccb4 \ubcc0\uacbd\uc0ac\ud56d\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc73c\ub2c8 PR \ud6c4\uc5d0\ub3c4 \uaf2d \ud655\uc778\ud574\uc57c\uaca0\ub2e4.\\n\\n**\uc801\uadf9\uc801\uc73c\ub85c \ub098\uc758 \uc758\uacac\uc744 \ub9d0\ud558\uae30** \\n\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ud398\uc5b4\uc758 \uc758\uacac\uc774 \uad1c\ucc2e\ub2e4\uace0 \uc0dd\uac01\ud558\uba74 \uc218\uc6a9 \ud6c4 \uac1c\uc120\uc744 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\uc5c8\ub294\ub370, \uc870\uae08 \ub354 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ud5a5\uc774 \uc788\ub2e4\uba74 \ub098\ub3c4 \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub9d0\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\uc774 \ub4e0\ub2e4. \\n\ub098\ub3c4 \uc124\ub4dd\ud558\ub294 \ud798\uc744 \uae30\ub974\uace0, \ud398\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc744 \uc54c \uc218 \uc788\uace0, \uacb0\uacfc\ubb3c\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub098\uc624\uc9c0 \uc54a\uc744\uae4c? (\uace0\ubbfc \ub4e4\uc5b4\uc8fc\uc2e0 \ub9ac\ubdf0\uc5b4 \ud130\ud2c0\ud83d\udc22 \uac10\uc0ac\ud569\ub2c8\ub2e4.)\\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**\uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784** \\nPlayers\uac00 Position\uc744 \uc0dd\uc131\ud558\uace0 Player\uc758 \uc0dd\uc131\uc790\uc5d0 \ub123\uc5b4\uc8fc\uc5c8\ub2e4. \ud558\uc9c0\ub9cc \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ub828\ub41c \ucf54\uba58\ud2b8\uac00 \ub2ec\ub838\ub2e4.\\n\uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uc0dd\uac01\ud574 \ubcf4\ub2c8 Position\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uac74 Player\uae30 \ub54c\ubb38\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 Player\uac00 \ub2f4\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4. \\n\\n\uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud55c \ud328\ud134\uc73c\ub85c GRASP\uc758 Creator \ud328\ud134\uc774 \uc788\ub294\ub370 \ub2e4\uc74c\uc758 \uc694\uc18c\ub97c \ucd5c\ub300\ud55c \ub9cc\uc871\ud558\ub294 \ud074\ub798\uc2a4\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \\n- B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4.\\n- B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4.\\n- B\uac00 A\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4.\\n- B\uac00 A\uc758 \ucd08\uae43\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4. \\n\\n\uc2e4\uc81c\ub85c \uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud574\uc11c \uae4a\uc774 \uc0dd\uac01\ud558\uba74\uc11c \ucf54\ub529\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc2dc\uc57c\uac00 \ub113\uc5b4\uc9c4 \uac83 \uac19\ub2e4.\\n\\n**\ud328\ud0a4\uc9c0 \ubd84\ub9ac \uae30\uc900** \\n\ud328\ud0a4\uc9c0 \ubd84\ub9ac\uc5d0 \ub300\ud55c \ub098\ub9cc\uc758 \uae30\uc900\uc774 \uc544\uc9c1 \uba85\ud655\ud558\uc9c0 \uc54a\uc544 \uc9c8\ubb38\uc774 \ub4e4\uc5b4\uc640\ub3c4 \uba85\ud655\ud558\uac8c \ub2f5\ubcc0\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\ub9c8\uc9c0\ub9c9 \uc81c\ucd9c \uc804\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub97c \ubd84\ub9ac\ud574 \ubd24\ub294\ub370, \uae30\uc900\uc774 \uba85\ud655\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \uc88b\uc9c0 \uc54a\uc740 \uc120\ud0dd\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.\\n\ud604\uc7ac \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud06c\uae30\uac00 \uadf8\ub807\uac8c \ud06c\uc9c0 \uc54a\uc73c\ub2c8, domain \ud328\ud0a4\uc9c0\uc5d0\uc11c \uc138\ubd80 \ud328\ud0a4\uc9c0\ub85c \ubd84\ub9ac\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub420 \uac83 \uac19\ub2e4. \\n\\n**\uc0ac\uc6a9\ud558\ub294 \ucabd\uc5d0\uc11c \uc0dd\uac01\ud558\uae30 & \uc608\uce21\uac00\ub2a5\ud55c \ucf54\ub4dc \uc791\uc131\ud558\uae30** \\nPosition\uc5d0\uc11c \ub2e4\uc74c \uc704\uce58\ub098 \uc774\uc804 \uc704\uce58\ub97c \ubc18\ud658\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud5c8\uc6a9 \ubc94\uc704(0~19)\uac00 \ubc97\uc5b4\ub09c\ub2e4\uba74, \uc758\ubbf8 \uc5c6\ub294 \uac12\uc774 \ub4e4\uc5b4\uac04 Position\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud588\ub2e4. \\n\uc774\uac74 Position\uc744 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc744 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \ucf54\ub529\uc774\uc5c8\ub294\ub370, \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 0~19\uc758 \uac12\uc774 \ubcf4\uc7a5\ub418\uc5b4 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uac83\uc774\uae30 \ub54c\ubb38\uc774\ub2e4. \\n\ub530\ub77c\uc11c hasNext, hasPrevious\ub77c\ub294 \uc774\uc804 \uac12, \uc774\ud6c4 \uac12\uc774 \ubc94\uc704 \ub0b4\uc5d0 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ucd94\uac00\ud558\uace0, \uae30\uc874\uc758 \uac12\uc744 \uac00\uc838\uc624\ub294 \uba54\uc11c\ub4dc\ub294 \ubc94\uc704\uac00 \ubc97\uc5b4\ub098\uba74 \uc608\uc678\ub97c \ub358\uc9c0\ub294 \ubc29\ud5a5\uc73c\ub85c \ud574\uacb0\ud558\uc600\ub2e4. \\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n\ubc1d\uc740 \uae30\uc6b4\uc744 \uac00\uc9c0\uace0 \uc788\uace0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \uce5c\ud654\ub825\uc774 \uc88b\uc740 \uac83 \uac19\uc558\ub2e4. \\n\uc774\ubc88\uc5d0 \ud398\uc5b4 \ud560 \ub54c \ucee8\ub514\uc158 \uad00\ub9ac\ub97c \uc81c\ub300\ub85c \ubabb\ud574\uc11c \ub9ce\uc774 \ubbf8\uc548\ud588\ub2e4. \ub2e4\uc74c\uc5d0\ub294 \ucd5c\uc0c1\uc758 \ucee8\ub514\uc158\uc73c\ub85c \ud398\uc5b4\ub97c \uc900\ube44\ud574 \ubd10\uc57c\uaca0\ub2e4. \\n\uadf8\ub9ac\uace0 \uc6b0\uac00\ub791 \ud398\uc5b4\ub97c \ud558\uace0 \ub098\uc11c, \ub098\ub3c4 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \ub354 \uc798 \uc9c0\ub0b4\ubd10\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5b4 \uc870\uae08 \ub354 \uc6a9\uae30\ub97c \ub0b4 \uc7a1\ub2f4 \uc911\uc774\ub2e4! \\n\\n\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589\uc774 \uc798 \ub418\uc5c8\ub2e4. \\n\ub610\ud55c \ud398\uc5b4 \uc9c4\ud589\uc774 \ub290\ub9b0 \uac83 \uac19\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c \uc548\uc815\uc801\uc73c\ub85c \uc2dc\uac04 \uc548\uc5d0 \ubbf8\uc158\uc744 \uc644\ub8cc\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589 \uc18d\ub3c4\uc5d0 \ub300\ud574 \uc870\uae08 \ub354 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4!\\n\\n\ud56d\uc0c1 \uc9c0\ub098\uac08 \ub54c\ub9c8\ub2e4 \uc6c3\uc5b4\uc8fc\ub294\ub370, \ub098\ub3c4 \uc790\uc8fc \uc6c3\uc5b4\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uc6c3\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uc0ac\ub78c\uc774 \ubc1d\uc544 \ubcf4\uc5ec\uc11c \ub108\ubb34 \uc88b\uc740 \uac83 \uac19\ub2e4!"},{"id":"racing-car-retrospective","metadata":{"permalink":"/racing-car-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/java-racingcar/pull/510","date":"2023-02-14T00:00:00.000Z","formattedDate":"2023\ub144 2\uc6d4 14\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":7.625,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0","slug":"racing-car-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"prevItem":{"title":"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0","permalink":"/ladder-retrospective"},"nextItem":{"title":"Parameterized Tests","permalink":"/parameterized-tests"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/java-racingcar/pull/510 \\n2\ub2e8\uacc4: https://github.com/woowacourse/java-racingcar/pull/538 \\n:::\\n\\n### \uc790\ub3d9\ucc28 \uacbd\uc8fc\\n\\n\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158\uc5d0\uc11c\ub294 \ub2e4\uc990\uacfc \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4. \\n\uc6b0\ud14c\ucf54 \ub4e4\uc5b4\uc640\uc11c \uccab \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\uc774\ub77c \ub9ce\uc774 \ub5a8\ub838\uc9c0\ub9cc, \ub2e4\uc990\uc774 \ub300\ud654\ub97c \uc798 \uc774\ub04c\uc5b4\uc918 \ub108\ubb34 \uc990\uac70\uc6e0\ub2e4. \\n\\n\uccab\ub0a0\uc740 \uac04\ub2e8\ud788 \ucee8\ubca4\uc158\uacfc \ud658\uacbd\uc744 \uc124\uc815\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc84c\uace0 \ub2e4\uc74c \ub0a0\ubd80\ud130 \uc790\ub3d9\ucc28 \uacbd\uc8fc\ub97c \uc2dc\uc791\ud588\ub2e4. \\n\uc2dc\uc791\uc740 \uac04\ub2e8\ud558\uac8c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud558\uace0, \uc5b4\ub5bb\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud560\uc9c0 \uac19\uc774 \uace0\ubbfc\ud588\ub2e4. \\n\\n\uc2dc\uc791\ud558\uae30 \uc804 \uc544\ub798\uc640 \uac19\uc774 mermaid\ub97c \uc774\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc5d0 \ub300\ud574\uc11c \uac04\ub2e8\ud55c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uace0 \uc2dc\uc791\ud588\ub2e4. \\nmermaid\ub294 \ucf54\ub4dc\ub85c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \uc0dd\uc131 \ud574\uc8fc\ub294 \ub3c4\uad6c\ub85c \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc774 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.\\n\\n- \ucf54\ub4dc \uae30\ubc18\uc774\ub77c \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \uc0dd\uac01\ud55c \uac83\uc744 \uc2dc\uac01\ud654\ud560 \uc218 \uc788\ub2e4. \\n- github\uc5d0\uc11c mermaid\ub97c \uc9c0\uc6d0\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \ucf54\ub4dc\ub97c \uc774\ud574\ud560 \uc218 \uc788\ub294 \ubd80\uac00\uc801\uc778 \uc815\ubcf4\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.\\n\\n```mermaid\\n---\\ntitle: \uc790\ub3d9\ucc28 \uacbd\uc8fc \uccab \ub9ac\ubdf0 \uc694\uccad\uc2dc \uad6c\uc870\\n---\\ngraph TD\\n Cars --\x3e Car\\n Car --\x3e Name\\n Car --\x3e Position\\n RacingGame --\x3e Count\\n RacingGame --\x3e NumberGenerator\\n RacingGame --\x3e Cars\\n RacingCarController --\x3e RacingGame\\n RandomNumberGenerator -.-> NumberGenerator\\n RacingCarController --\x3e InputView\\n InputView --\x3e InputValidator\\n RacingCarController --\x3e OutputView\\n```\\n\\n\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \ub370 \ud070 \uc5b4\ub824\uc6c0\uc774 \uc788\uc9c0\ub294 \uc54a\uc558\uace0, \ud398\uc5b4\ub97c \ub9c8\uce58\uae30 \uc804 \uc11c\ub85c \uace0\ubbfc\ub418\ub294 \ubd80\ubd84\uc744 \uc815\ub9ac\ud588\uc744 \ub54c \uc88b\uc558\ub2e4.\\n\\n\ud398\uc5b4\ud558\uba74\uc11c \uc798\ud588\ub2e4\uace0 \uc0dd\uac01\ud588\ub358 \uc810\uc740 \uc11c\ub85c\uc758 \uc0dd\uac01\uacfc \ub9ac\ubdf0 \ubc1b\uc740 \uac83\uc744 \uacf5\uc720\ud55c \uac83\uc774\ub2e4. \\n\ub9ac\ud329\ud130\ub9c1\uc744 \uc5b4\ub5bb\uac8c \ud588\ub294\uc9c0? \uc774\ub7f0 \ub9ac\ubdf0\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \uc0dd\uac01\ud558\ub294\uc9c0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c8 \uc218 \uc788\uc5c8\ub2e4.\\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n\ub9ac\ud329\ud130\ub9c1\uc774 \ub05d\ub09c \ud6c4 \uba54\uc11c\ub4dc\uba85, \ud14c\uc2a4\ud2b8\uc2dc \ucd9c\ub825\ud558\ub294 \uba54\uc2dc\uc9c0\uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\uac00 \ub9ce\uc774 \ub2ec\ub838\ub2e4. \\n\uac1d\uccb4\uac00 \uc5b4\ub5a4 \ucc45\uc784\uacfc \uc5ed\ud560\uc744 \uac00\uc9c0\ub294\uc9c0 \uc0dd\uac01\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uba85\ud655\ud55c \uba54\uc11c\ub4dc\uba85\uc744 \uc791\uc131\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n\ud3c9\uc18c\uc5d0 \ud504\ub85c\uadf8\ub798\ubc0d \uc774\uc57c\uae30\uac00 \uc544\ub2cc \ub2e4\ub978 \uc8fc\uc81c\ub85c \uc774\uc57c\uae30\ud558\uba74 \uc798 \ub4e4\uc73c\ub824\uace0 \ud558\ub294 \ud3b8\uc774\uc9c0\ub9cc \\n\ub0b4\uac00 \uc88b\uc544\ud558\ub294 \uc8fc\uc81c, \uad00\uc2ec\uac00\ub294 \uc8fc\uc81c\uc778 \ud504\ub85c\uadf8\ub798\ubc0d\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub97c \ud560 \ub550 \ub9d0\uc774 \ub9ce\uc544\uc9c4\ub2e4. \\n\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130\ub294 \ub354 \ub9ce\uc740 \uc2dc\uac04\uc744 \ud398\uc5b4\uc758 \uc758\uacac\uacfc \uc774\uc57c\uae30\ub97c \ub4e3\ub294 \uacf3\uc5d0 \uc0ac\uc6a9\ud574\uc57c\uaca0\ub2e4.\\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**Assertions extracting**\\n\\n\uacb0\uacfc \ub0b4\ubd80\uc5d0 \uc788\ub294 \uac12\uc744 \ud655\uc778\ud558\uace0 \uc2f6\uc744 \ub54c extracting \ud0a4\uc6cc\ub4dc\ub97c \uc774\uc6a9\ud574\uc11c \ub0b4\ubd80\uc758 \uac12\uc744 \uac80\uc99d\ud560 \uc218 \uc788\ub2e4. \\n\uc774\uc804\uc5d0\ub294 \ud544\uc694\uc5d0 \ub530\ub77c stream\uc744 \uc774\uc6a9\ud558\uc5ec \uac80\uc99d\ud560 \uac12\uc744 \uc0dd\uc131\ud588\uc9c0\ub9cc, \ud574\ub2f9 \ubc29\ubc95\uc744 \uc774\uc6a9\ud574\uc11c \uc808\ucc28\ub97c \uc904\uc77c \uc218 \uc788\uc5c8\ub2e4.\\n\\n```java\\n@Test\\nvoid extracting() {\\n final Cars cars = new Cars(List.of(\\"car1\\", \\"car2\\"));\\n\\n assertThat(cars.getCars())\\n .extracting(Car::getName)\\n .containsExactly(\\"car1\\", \\"car2\\");\\n}\\n```\\n\\n---\\n\\n\uc544\ub798\ub294 \ub9ac\ubdf0\uc5b4\ub2d8\uacfc \ub300\ud654\ub97c \ub098\ub204\uba74\uc11c \uc5bb\uc740 \ub2f5\ubcc0 + \ub098\uc758 \uc758\uacac\uc774\ub2e4.\\n\\n**\uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8**\\n\\n\ud14c\uc2a4\ud2b8 \ub300\uc0c1\uc774 \uac80\uc99d\ub41c \uac83\uc774\ub77c\uba74 \uc791\uc131\ud558\uc9c0 \uc54a\uac70\ub098, \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uc791\uc131\ud55c\ub2e4. \\n\uc774\uac74 \uac1c\uc778\uc801\uc778 \uc0dd\uac01\uc774\uc9c0\ub9cc \ub0b4\uac00 \uc548\uc815\uac10\uc774 \ub4e4 \uc218 \uc788\uc744 \uc815\ub3c4\ub85c \ucd9c\ub825 \ubc94\uc704 \ub0b4\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud558\ub294\uc9c0 \uc815\ub3c4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?\\n\\n**\ub2e8\uc21c \uc704\uc784\uc744 \ud558\ub294 \uba54\uc11c\ub4dc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8**\\n\\n\uc704\uc784\uc774\ub77c\ub294 \uac83\uc740 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \ub118\uaca8\uc900\ub2e4\ub294 \uac83\uc774\ub2e4. \\n\ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc99d\ud558\ub294 \uac83\ubcf4\ub2e4 \uacb0\uacfc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\ub2e8\uc21c\ud788 \uc704\uc784\ub9cc \ud558\ub294 \ud14c\uc2a4\ud2b8\uc758 \uacbd\uc6b0 \uacb0\uacfc\ub97c \uac80\uc99d\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8\uac00 \uc911\ubcf5\ub418\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c \uc911\ubcf5\ub41c \ud14c\uc2a4\ud2b8\ub97c \uc904\uc774\uae30 \uc704\ud574 \ub0b4\ubd80\uc758 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0 \uac80\uc99d\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\ub294 \uac83\uc744 \uc54c\uac8c \ub418\uc5c8\uc9c0\ub9cc \\n\uc548\uc815\uc801\uc73c\ub85c \uacb0\uacfc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc778 \uac83 \uac19\ub2e4.\\n\\n**\ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c getter \uc0ac\uc6a9**\\n\\n\ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\ub85c \ub3c4\uba54\uc778\uc5d0 \uc0c8\ub85c\uc6b4 \uba54\uc11c\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc740 \uc88b\uc9c0 \ubabb\ud558\ub2e4. \\n\ud544\uc694\uc758 \uacbd\uc6b0 \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc9c0\ub9cc, \uae30\uc874\uc5d0 \uc788\ub294 \uba54\uc11c\ub4dc\ub4e4\uc744 \ud65c\uc6a9\ud574\ubcf4\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4. \\n\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub9e4\uc6b0 \ub3d9\uc758\ud558\uace0, \uc55e\uc73c\ub85c\ub3c4 \ucd5c\ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \ucf54\ub4dc\ub97c \ub3c4\uba54\uc778\uc5d0 \uc791\uc131\ud558\uc9c0 \uc54a\uc744 \uac83 \uac19\ub2e4.\\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n\uc9c8\ubb38\uc774\ub098 \uc0dd\uac01\ud560 \uc810\uc774 \uc788\uc744 \ub54c \ub9e4\uc6b0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uac83 \uac19\uc558\ub2e4. \\n\uc0dd\uac01\uc744 \uc815\ub9ac\ud55c \ud6c4 \uc790\uc2e0\uc758 \uc758\uacac\uc744 \uba85\ub8cc\ud558\uac8c \uc804\ub2ec\ud574\uc8fc\uc5c8\ub2e4. \\n\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc2dd\uc744 \ud6a8\uc728\uc801\uc73c\ub85c \uc2b5\ub4dd\ud55c\ub2e4. \\n\ub09c \uc0dd\uac01\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc740 \ucc44\ub85c \ub0b4\ubc84\ub824 \ub454 \uc595\uc740 \uc9c0\uc2dd\uc774 \ub9ce\uc740 \uac83 \uac19\ub2e4. (\uc774\ub7f0 \uac83\ub3c4 \uc544\ub294 \uac83\uc774\ub77c\uace0 \ud560 \uc218 \uc788\uc744\uae4c?) \\n\uc55e\uc73c\ub85c \uc870\uae08 \ub354 \uba38\ub9bf\uc18d\uc5d0\uc11c \uc815\ub9ac\ud558\uace0, \ubb38\uc81c\uc5d0 \ub300\ud574 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \ub298\ub824\uc57c\uaca0\ub2e4.\\n\\n\uac1c\ubc1c\uc5d0 \uc5f4\uc815\uc744 \uac00\uc9c4 \uac8c \ub290\uaef4\uc9c4\ub2e4. \\n\ub098\ub3c4 \uac1c\ubc1c\uc744 \uc88b\uc544\ud558\uc9c0\ub9cc, \ucd5c\uadfc\uc5d0\ub294 \uc758\uc9c0\uac00 \uc57d\ud574\uc84c\uc5c8\ub2e4. \\n\uc5f4\uc815\uc774 \uac00\ub4dd\ud55c \uc0ac\ub78c\uc744 \ub9cc\ub098\ub2c8 \ub098\ub3c4 \uc5f4\uc815\uc801\uc778 \uc0ac\ub78c\uc774 \ub418\ub294 \uac83 \uac19\ub2e4.\\n\\n\uce6d\ucc2c\uc744 \ub9ce\uc774 \ud574\uc900\ub2e4. \ub2e8\uc21c\ud788 \ub9ce\uc774 \ud574\uc8fc\ub294 \uac83\uc774 \uc544\ub2c8\ub77c, \uc9c4\uc2ec\uc744 \ub2f4\uae34 \uce6d\ucc2c\uc744 \ud574\uc92c\ub2e4. \\n\uce6d\ucc2c\uc740 \uace0\ub798\ub3c4 \ucda4\ucd94\uac8c \ud558\ub358\uac00? \\n\uadf8\ub798\uc11c \uc990\uac70\uc6b4 \ub9c8\uc74c\uc73c\ub85c \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud588\uc5c8\ub358 \uac83 \uac19\ub2e4.\\n\\n\uc5b4\ub5a4 \uc774\uc720 \ub54c\ubb38\uc778\uc9c0 \ubaa8\ub974\uaca0\uc9c0\ub9cc \uac19\uc774 \ud398\uc5b4\ud558\ub294\ub370 \ud3b8\ud55c \ub9c8\uc74c\uc774 \ub4e4\uc5c8\ub2e4. \\n\uc774\uac74 \ubc14\ub85c \ubc30\uc6b8 \uc218 \uc5c6\uc9c0\ub9cc. \\n\ub098\ub3c4 \uac19\uc774 \uc77c\ud560 \ub54c \ud3b8\ud55c \uc0ac\ub78c, \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub418\uae30 \uc704\ud574 \uae4a\uc774 \uace0\ubbfc\ud574\ubd10\uc57c\uaca0\ub2e4."},{"id":"parameterized-tests","metadata":{"permalink":"/parameterized-tests","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-12-Parameterized Tests.mdx","source":"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx","title":"Parameterized Tests","description":"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.","date":"2023-02-12T00:00:00.000Z","formattedDate":"2023\ub144 2\uc6d4 12\uc77c","tags":[{"label":"Java","permalink":"/tags/java"}],"readingTime":3.17,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Parameterized Tests","slug":"parameterized-tests","tags":["Java"]},"prevItem":{"title":"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0","permalink":"/racing-car-retrospective"},"nextItem":{"title":"IntelliJ \uc124\uc815","permalink":"/intellij-settings"}},"content":"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4. \\n\uc774 \ub54c `@ParameterizedTest`\ub97c \uc0ac\uc6a9\ud558\uba74 \ub2e8\uc77c \ud14c\uc2a4\ud2b8\ub97c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc5ec\ub7ec \ubc88 \ubc18\ubcf5\ud560 \uc218 \uc788\ub2e4.\\n\\n## Argument Sources\\n\\n`@ParameterizedTest`\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \ucd5c\uc18c \ud558\ub098 \uc774\uc0c1\uc758 Source \uc560\ub178\ud14c\uc774\uc158\uc774 \ud544\uc694\ud558\ub2e4. \\nJUnit\uc774 \uc81c\uacf5\ud558\ub294 \ub2e4\uc591\ud55c Source\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0, \ud14c\uc2a4\ud2b8\uc5d0 \ub9de\ucdb0 \ub2e4\uc591\ud558\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n### Value Source\\n\\n\uac12\uc744 \uc774\uc6a9\ud558\uc5ec \uc81c\uacf5\ud558\ub294 \ud615\ud0dc\ub85c, \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4. \\n- short, int, long, float, double\\n- byte, char, boolean, String, Class \\n\\n```java\\n@ParameterizedTest\\n@ValueSource(ints = {1, 100, Integer.MAX_VALUE})\\nvoid valueTest(final int value) {\\n Assertions.assertThat(value).isPositive();\\n}\\n```\\n\\n### Null & Empty Source\\n\\nnull \uac12, \ube48 \uac12\uc744 \uc81c\uacf5\ud55c\ub2e4. \\nEmpty Source\uc758 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc5d0 \ud55c\ud574 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.\\n- String\\n- java.util.List, java.util.Set, java.util.Map\\n- primitive arrays \u2014 ex) int[]\\n- object arrays \u2014 ex) String[]\\n\\n```java\\n@ParameterizedTest\\n@NullAndEmptySource\\nvoid nullAndEmptyTest(final String value) {\\n Assertions.assertThat(value).isNullOrEmpty();\\n}\\n```\\n\\n### Enum Source\\n\\nEnumSource\ub97c \uc774\uc6a9\ud558\uc5ec Enum \ub610\ud55c \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.\\n\\n```java\\nenum Day {\\n MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\\n}\\n\\n@ParameterizedTest\\n@EnumSource(Day.class)\\nvoid enumTest(final Day day) {\\n assertThat(day).isInstanceOf(Day.class);\\n}\\n```\\n\\n\ub2e4\uc74c\uacfc \uac19\uc774 mode \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b9\uc9d5 Enum\uc744 \uc81c\uc678\ud558\uac70\ub098, \ud3ec\ud568\uc2dc\ud0ac \uc218 \uc788\ub2e4. (default: Mode.Include)\\n\\n```java\\n@ParameterizedTest\\n@EnumSource(value = Day.class, names = {\\"SATURDAY\\", \\"SUNDAY\\"}, mode = Mode.EXCLUDE)\\nvoid enumTest(final Day day) {\\n // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY\\n assertThat(day).isInstanceOf(Day.class);\\n}\\n```\\n\\n### CSV Source\\n\\ncsv \ud615\uc2dd\uc758 \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud55c\ub2e4. \\n\uad6c\ubd84\uc790\uc758 \uae30\ubcf8\uac12\uc740 \uc27c\ud45c(,)\ub85c \uad6c\ubd84\uc790\ub97c \ubcc0\uacbd\ud558\uace0 \uc2f6\uc744 \ub550 delimeter \uac12\uc744 \ub530\ub85c \uc804\ub2ec\ud558\uc5ec \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\uac1c\uc778\uc801\uc73c\ub85c 2\uac1c \uc815\ub3c4\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc804\ub2ec\ud558\ub294 \uacbd\uc6b0 CsvSource\ub97c \uc0ac\uc6a9\ud55c\ub2e4.\\n\\n```java\\n@ParameterizedTest\\n@CsvSource({\\"1,1\\", \\"2,4\\", \\"3,9\\", \\"4,16\\"})\\nvoid csvTest(final int number, final int result) {\\n assertThat(number * number).isEqualTo(result);\\n}\\n```\\n\\n### Method Source\\n\\n\ubcf5\uc7a1\ud55c \ud0c0\uc785\uc758 \uac12\uc744 \uc804\ub2ec\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4. \\n\uba54\uc11c\ub4dc\uba85\uc744 \uc785\ub825\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4. \\n\uba54\uc11c\ub4dc\uba85\uc744 \ub530\ub85c \uc785\ub825\ud558\uc9c0 \uc54a\uc73c\uba74 \ud14c\uc2a4\ud2b8\uba85\uacfc \ub3d9\uc77c\ud55c static \uba54\uc11c\ub4dc\uac00 \uc9c0\uc815\ub41c\ub2e4.\\n\\n```java\\n@ParameterizedTest\\n@MethodSource\\nvoid methodTest(final List<Integer> numbers, final int count) {\\n assertThat(numbers).hasSize(count);\\n}\\n\\nprivate static Stream<Arguments> methodTest() {\\n return Stream.of(\\n Arguments.of(List.of(1), 1),\\n Arguments.of(List.of(1, 2), 2),\\n Arguments.of(List.of(1, 2, 3), 3)\\n );\\n}\\n```\\n\\n### ETC.\\n\\n\uc704\uc5d0\uc11c \uc5b8\uae09\ud55c \ubc29\ubc95 \uc774\uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ubc29\ubc95\uc73c\ub85c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.\\n\\n- CSV \ud30c\uc77c\uc744 \uc774\uc6a9\ud55c CsvFileSource\\n- ArgumentsProvider \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \uc774\uc6a9\ud558\ub294 ArgumentsSource\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n- [Guide to JUnit 5 Parameterized Tests](https://www.baeldung.com/parameterized-tests-junit-5)"},{"id":"intellij-settings","metadata":{"permalink":"/intellij-settings","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx","source":"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx","title":"IntelliJ \uc124\uc815","description":"Import \uc790\ub3d9 \uc801\uc6a9","date":"2023-01-30T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 30\uc77c","tags":[{"label":"IntelliJ","permalink":"/tags/intelli-j"}],"readingTime":0.465,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"IntelliJ \uc124\uc815","slug":"intellij-settings","tags":["IntelliJ"]},"prevItem":{"title":"Parameterized Tests","permalink":"/parameterized-tests"},"nextItem":{"title":"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95","permalink":"/kotlin-null"}},"content":"### Import \uc790\ub3d9 \uc801\uc6a9\\n\\nPrefrences > Editor > General > Auto Import > Add unambiguous imports on the fly\\n\\n![auto-import](./auto-import.png)\\n\\n### \uc800\uc7a5\uc2dc \ub3d9\uc791\\n\\nPrefrences > Tools > Actions on Save\\n\\n![actions-on-save](./actions-on-save.png)\\n\\nReformat Code: Code Reformmating\\n\\nOptimize imports: \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 Import \uc81c\uac70\\n\\nRearrange: Code Style > Arrangement \uc124\uc815 \uae30\ubc18 \ucf54\ub4dc \uc7ac\uc815\ub82c\\n\\n### \uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9\\n\\nPrefrences > Editor > Code Style > Java > Code Generation > Final Modifier\\n\\n![final-modifier](./final-modifier.png)"},{"id":"kotlin-null","metadata":{"permalink":"/kotlin-null","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx","source":"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx","title":"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95","description":"nullable \ud0c0\uc785","date":"2023-01-16T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 16\uc77c","tags":[{"label":"Kotlin","permalink":"/tags/kotlin"}],"readingTime":4.225,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95","slug":"kotlin-null","tags":["Kotlin"]},"prevItem":{"title":"IntelliJ \uc124\uc815","permalink":"/intellij-settings"},"nextItem":{"title":"JSR-310","permalink":"/jsr-310"}},"content":"import Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n### nullable \ud0c0\uc785\\n\\n\ucf54\ud2c0\ub9b0\uc740 `NullPointerException` \uc608\uc678\ub97c \ucd5c\ub300\ud55c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 \ud0c0\uc785 \uc2dc\uc2a4\ud15c\uc774 \uc124\uacc4\ub418\uc5b4 \uc788\ub2e4. \\n\uc774\ub294 \uc2e4\ud589 \uc2dc\uc810\uc774 \uc544\ub2cc \ucef4\ud30c\uc77c \uc2dc \ubbf8\ub9ac \uc624\ub958\uac00 \ubc1c\uc0dd\ud560 \uac00\ub2a5\uc131\uc774 \uc788\ub294 \ubd80\ubd84\uc744 \ubbf8\ub9ac \uac10\uc9c0\ud558\uc5ec NPE \ubc1c\uc0dd\uc758 \uac00\ub2a5\uc131\uc744 \uc904\uc5ec\uc900\ub2e4.\\n\\n\ucf54\ud2c0\ub9b0\uc758 \uacbd\uc6b0 nullable \ud0c0\uc785\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \ud45c\ud604\ud55c\ub2e4.\\n\\n```kotlin\\nval number: Int?\\n```\\n\\n\ud0c0\uc785 \ub4a4\uc5d0 `?`\ub97c \ubd99\uc5ec \ud574\ub2f9 \uac12\uc774 null\uc774 \ub420 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4. \\n\ub9cc\uc57d `?`\ub97c \ubd99\uc774\uc9c0 \uc54a\uc744 \ub54c null\uc744 \ubc1b\ub294 \uacbd\uc6b0 \ucef4\ud30c\uc77c \uc2dc \uc624\ub958\uac00 \ubc1c\uc0dd\ud55c\ub2e4.\\n\\n### `?.` Safe Calls \uc5f0\uc0b0\uc790\\n\\n\uc790\ubc14\uc5d0\uc11c NPE\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 null\uc744 \ucc98\ub9ac\ud558\ub294 \uac00\uc7a5 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c\ub294 \ubd84\uae30\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.\\n\\n\ucf54\ud2c0\ub9b0\uc740 \uc548\uc804\ud55c \ud638\ucd9c \uc5f0\uc0b0\uc790\uc778 `?.` \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4. \\n\ub530\ub77c\uc11c \ucc38\uc870 \uac12\uc774 null\uc774 \uc544\ub2d0 \uacbd\uc6b0\uc5d0\ub9cc \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\ucc38\uc870 \uac12\uc774 null\uc778 \uacbd\uc6b0 \uba54\uc11c\ub4dc \ud638\ucd9c\uc774 \ubb34\uc2dc\ub418\uace0, null\uc744 \ubc18\ud658\ud55c\ub2e4. \\n\\n<Tabs>\\n<TabItem value=\\"Java\\" label=\\"Java\\" default>\\n\\n```java\\npublic String repeat(String word) {\\n if (word == null) {\\n return null;\\n }\\n return word.repeat(2);\\n}\\n```\\n\\n</TabItem>\\n<TabItem value=\\"Kotlin\\" label=\\"Kotlin\\">\\n\\n```kotlin\\nfun repeat(word: String?): String? {\\n return word?.repeat(2)\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n### `?:` \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\\n\\n\ucc38\uc870\ud558\ub824\ub294 \uac12\uc774 null\uc77c \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud558\uace0 \uc2f6\uc744 \ub54c\ub294 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c? \\n\ucf54\ud2c0\ub9b0\uc740 null\uc774 \uc544\ub2cc \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \ub54c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4.\\n\\n<Tabs>\\n<TabItem value=\\"Java\\" label=\\"Java\\" default>\\n\\n```java\\npublic String stringSafe(String word) {\\n if (word == null) {\\n return \\"\\";\\n }\\n return word;\\n}\\n```\\n\\n</TabItem>\\n<TabItem value=\\"Kotlin\\" label=\\"Kotlin\\">\\n\\n```kotlin\\nfun stringSafe(word: String?): String {\\n return word ?: \\"\\"\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 throw\ub3c4 \uc2dd\uc774\uae30 \ub54c\ubb38\uc5d0 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4. \\n\uc608\ub97c \ub4e4\uc5b4 \uc0ac\uc6a9\uc790 \uc815\ubcf4\uac00 \uc788\ub294 \uc800\uc7a5\uc18c\uc5d0 \ucc3e\ub294 \uc0ac\uc6a9\uc790\uac00 \uc5c6\ub294 \uacbd\uc6b0 \uc544\ub798\uc640 \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n```kotlin\\nuserRepository.findByName(name) ?: throw IllegalArgumentException()\\n```\\n\\n### `!!` \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790\\n\\n!! \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud55c\ub2e4\uba74 \uac15\uc81c\ub85c \uc5b4\ub5a4 \uac12\uc774\ub4e0 non-nullable \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4. \\n\ud558\uc9c0\ub9cc null\uc778 \uac12\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4\uba74 NPE\uac00 \ubc1c\uc0dd\ud558\uac8c \ub41c\ub2e4. \\n\uc77c\ubc18\uc801\uc778 \uacbd\uc6b0\uc5d0\ub294 !! \uc5f0\uc0b0\uc790\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc704\ud5d8\ud558\ub2e4. \\n\uc0ac\uc6a9\ud558\uae30 \uc27d\uc9c0\ub9cc, \ub9ac\uc2a4\ud06c\uac00 \ud06c\uace0 \ud639\uc2dc\ub098 \ud574\ub2f9 \uac12\uc774 \ucd94\ud6c4\uc5d0\ub294 null\uc774 \ub420 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc591\ud574\uc57c \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.\\n\\n```kotlin\\nval length: Int = word!!.length\\n```\\n\\n### `as?` \uc548\uc804\ud55c \uce90\uc2a4\ud305\\n\\n\ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \ub54c \uc9c0\uc815\ud55c \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc5c6\ub2e4\uba74 `ClassCastException`\uc774 \ubc1c\uc0dd\ud55c\ub2e4. \\n\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 as \ub4a4\uc5d0 ?\ub97c \ubd99\uc5ec \uc548\uc804\ud558\uac8c \ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c \ubbf8\ub9ac \ubcc0\ud658 \uac00\ub2a5\ud55c \ud0c0\uc785\uc778\uc9c0 \ud655\uc778\ud558\uc9c0 \uc54a\uace0, \uc548\uc804\ud558\uac8c \ud0c0\uc785\uc744 \ubcc0\ud658 \ud560 \uc218 \uc788\ub2e4. \\n\\n\ud0c0\uc785 \ubcc0\ud658\uc774 \ubd88\uac00\ub2a5 \ud560 \uacbd\uc6b0 \uc608\uc678\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uace0 null\uc744 \ubc18\ud658\ud55c\ub2e4.\\n\\n```kotlin\\nval value: Int? = something as? Int\\n```\\n\\n### List\uc5d0\uc11c\uc758 null \ucc98\ub9ac\\n\\nList\uc5d0\ub294 null\uc774 \uc544\ub2cc \uac12\ub9cc \ubc18\ud658\ud558\ub294 `filterNotNull` \uc720\ud2f8\ub9ac\ud2f0 \uba54\uc11c\ub4dc\ub97c \uc81c\uacf5\ud55c\ub2e4.\\n\\n```kotlin\\nval foodsWithNull: List<String?> = listOf(\\"Pizza\\", \\"Cheese\\", null, \\"Potato\\")\\nval foods = foodsWithNull.filterNotNull()\\n```\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n- [Kotlin in Action](https://product.kyobobook.co.kr/detail/S000001804588)\\n- [Effective Kotlin Item 8](https://product.kyobobook.co.kr/detail/S000001033129)\\n- [Comprehensive Guide to Null Safety in Kotlin](https://www.baeldung.com/kotlin/null-safety)\\n- [Kotlin NullSafety](https://kotlinlang.org/docs/null-safety.html)"},{"id":"jsr-310","metadata":{"permalink":"/jsr-310","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-08-JSR-310.mdx","source":"@site/blog/2023-1/2023-01-08-JSR-310.mdx","title":"JSR-310","description":"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API","date":"2023-01-08T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 8\uc77c","tags":[{"label":"Java","permalink":"/tags/java"},{"label":"Time","permalink":"/tags/time"}],"readingTime":1.685,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"JSR-310","slug":"jsr-310","tags":["Java","Time"]},"prevItem":{"title":"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95","permalink":"/kotlin-null"},"nextItem":{"title":"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574","permalink":"/the-essence-of-object-orientation"}},"content":"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API \\nISO-8601\uc744 \uae30\ubc18\uc73c\ub85c \uc791\uc131 \\n\uc124\uacc4 \ubaa9\ud45c \u2192 \ubd88\ubcc0, Fluent API, \uba85\ud655\ud558\uace0 \uba85\uc2dc\uc801, \ud655\uc7a5 \uac00\ub2a5\uc131\\n\\n:::note ISO-8601\\n\\n\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc5d0 \uad00\ub828\ub41c \ub370\uc774\ud130\ub97c \ub2e4\ub8e8\ub294 \uad6d\uc81c \ud45c\uc900\\n\\n:::\\n\\n### LocalDate, LocalTime, LocalDateTime\\n\\n\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4\\n\\n### Instant\\n\\n\uc720\ub2c9\uc2a4 \uc2dc\uac04(1970-01-01, 00:00:00 UTC) \uae30\uc900\uc73c\ub85c \ud2b9\uc815 \uc9c0\uc810\uae4c\uc9c0\uc758 \uc2dc\uac04\uc744 \ucd08\ub85c \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4 \\n\uae30\uacc4\uc758 \uad00\uc810\uc5d0\uc11c \uc2dc\uac04 \ud45c\ud604\\n\\n### Duration, Period\\n\\n\uac04\uaca9\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4\\n\\n### TemporalAdjusters\\n\\n\ubcf5\uc7a1\ud55c \ub0a0\uc9dc \uc870\uc815\uc774 \ud544\uc694\ud560 \ub54c \uc0ac\uc6a9 \\n\ud544\uc694\ud55c \uacbd\uc6b0 \ub2e4\uc74c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\uc5ec \ucee4\uc2a4\ud140 TemporalAdjuster\ub97c \uad6c\ud604 \uac00\ub2a5\\n\\n```java\\n@FunctionalInterface\\npublic interface TemporalAdjuster {\\n Temporal adjustInto(Temporal temporal);\\n}\\n```\\n\\n### DateTimeFormatter\\n\\n\ub0a0\uc9dc\uc640 \uc2dc\uac04 \ud3ec\ub9f7 \ud074\ub798\uc2a4 \\n\ud2b9\uc815 \ub0a0\uc9dc \ud328\ud134\uc774\ub098, DateTimeFormatterBuilder\ub97c \uc774\uc6a9\ud574\uc11c \ucee4\uc2a4\ud140\ud55c \ud3ec\ub9f7\uc744 \uc0dd\uc131 \uac00\ub2a5\\n\\n### ZoneId, ZoneOffset\\n\\nZoneId\ub294 \uc9c0\uc5ed ID\ub294 `\u2018\uc9c0\uc5ed/\ub3c4\uc2dc\u2019` \ud615\uc2dd, ZoneOffset\uc740 \uc2dc\ucc28 UTC \uae30\uc900 \uace0\uc815\ub41c \uc2dc\uac04 \ucc28\uc774 \uc774\uc6a9 \\nZoneId\uc758 \uacbd\uc6b0 IANA Time Zone Database\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc9c0\uc5ed \uc9d1\ud569 \uc815\ubcf4 \uc0ac\uc6a9\\n\\n```java\\nInstant instant = Instant.now();\\nLocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);\\n```\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n- [\ubaa8\ub358 \uc790\ubc14 \uc778 \uc561\uc158](https://product.kyobobook.co.kr/detail/S000001810171)\\n- [Java\uc758 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API](https://d2.naver.com/helloworld/645609)\\n- [ISO-8601](https://www.w3.org/TR/NOTE-datetime)\\n- [JSR-310 Spec](https://download.oracle.com/otn-pub/jcp/date_time-0.2-edr-oth-JSpec/date_time-0_2-edr-spec.pdf?AuthParam=1673171124_74a718be92efe4911c6977c02965aff4)\\n- [Temporal Adjuster](https://www.baeldung.com/java-temporal-adjuster)\\n- [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)"},{"id":"the-essence-of-object-orientation","metadata":{"permalink":"/the-essence-of-object-orientation","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx","source":"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx","title":"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574","description":"\ucc45 \uc815\ubcf4","date":"2023-01-07T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 7\uc77c","tags":[{"label":"Book","permalink":"/tags/book"}],"readingTime":5.415,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574","slug":"the-essence-of-object-orientation","tags":["Book"]},"prevItem":{"title":"JSR-310","permalink":"/jsr-310"},"nextItem":{"title":"2022\ub144 \ud68c\uace0","permalink":"/2022-retrospective"}},"content":"### \ucc45 \uc815\ubcf4\\n\\n> \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574 \\n> \uc870\uc601\ud638\\n> \\n\\n### \uc77d\uace0 \ub098\uc11c\\n\\n\uc870\uc601\ud638\ub2d8\uc758 \uc624\ube0c\uc81d\ud2b8\ub97c \uc77d\uace0 \ub098\uc11c \ub2e4\uc2dc \ud55c \ubc88 \uc77d\uc5b4\ubcf4\uc558\ub2e4. \\n\uc544\uc9c1 \uc774\ud574\uac00 \uc548\ub418\ub294 \ubd80\ubd84\uc774 \ub9ce\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ud56d\uc0c1 \uc0c8\ub85c\uc6c0\uc744 \ub290\ub080\ub2e4. \\n\ub354\ud560 \ub098\uc704 \uc5c6\uc774 \ud73c\ub96d\ud55c \uac1d\uccb4\uc9c0\ud5a5 \ucc45\uc774\uace0, \uc870\uae08 \ub354 \uacf5\ubd80\ud558\uace0 \ub2e4\uc2dc \uc77d\uc5b4\ubd10\uc57c\ub420 \uac83 \uac19\ub2e4. \\n\\n\ucee4\ud53c \uc804\ubb38\uc810, \uc9c0\ud558\ucca0 \ub178\uc120\ub3c4, \uc774\uc0c1\ud55c \ub098\ub77c\uc758 \uc5d8\ub9ac\uc2a4\ub97c \uc608\uc2dc\ub85c \ub4e0 \uc124\uba85\uc774 \ub108\ubb34 \uc88b\uc558\uace0 \\n\uc88b\uc740 \ub0b4\uc6a9\uc744 \ub2f4\uace0 \uc788\uc9c0\ub9cc \uadf8\ub807\ub2e4\uace0 \ub108\ubb34 \ubb34\uac81\uc9c0 \uc54a\uc544 \uac00\ubccd\uac8c \uc77d\uae30\ub3c4 \uc88b\uc740 \uac83 \uac19\ub2e4.\\n\\n### \ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173\\n\\n\ud611\ub825\uc744 \ub2e8\uc21c\ud558\uac8c \ub9cc\ub4e0\ub2e4.\\n\\n- \uc758\ub3c4\ub97c \uba85\ud655\ud558\uac8c \ud45c\ud604 \u2192 \ud611\ub825\uc758 \ubcf5\uc7a1\ud568 \uc800\ud558\\n- \ucc45\uc784\uc758 \ucd94\uc0c1\ud654\\n\\n\uc678\ubd80\uc640 \ub0b4\ubd80\ub97c \uba85\ud655\ud558\uac8c \ubd84\ub9ac\ud55c\ub2e4.\\n\\n- \uc694\uccad\ud558\ub294 \uac1d\uccb4\uac00 \ubab0\ub77c\ub3c4 \ub418\ub294 \ubd80\ubd84\uc774 \ucea1\uc290\ud654\ub428\uc73c\ub85c \uc778\ud130\ud398\uc774\uc2a4\uc640 \uad6c\ud604\uc758 \ubd84\ub9ac\\n\\n\ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub0b4\ubd80\uc801\uc778 \ubc29\ubc95\uc744 \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 \uc678\ubd80\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub294\ub2e4.\\n\\n- \ubcc0\uacbd\uc758 \ud30c\uae09\ud6a8\uacfc\ub97c \uac1d\uccb4 \ub0b4\ubd80\ub85c \ucea1\uc290\ud654 \u2192 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \uac1d\uccb4\uc640\uc758 \uacb0\ud569\ub3c4 \uc800\ud558\\n\\n\ud611\ub825\uc758 \ub300\uc0c1\uc744 \ub2e4\uc591\ud558\uac8c \uc120\ud0dd\ud560 \uc218 \uc788\ub294 \uc720\uc5f0\uc131\uc744 \uc81c\uacf5\ud55c\ub2e4.\\n\\n- \uc720\uc5f0\ud55c \uc124\uacc4 \u2192 \uc7ac\uc0ac\uc6a9\uc131 \uc99d\uac00\\n\\n\uac1d\uccb4\uc758 \uc5ed\ud560\uc744 \uc774\ud574\ud558\uae30 \uc26c\uc6cc\uc9c4\ub2e4.\\n\\n- \uc751\uc9d1\ub3c4\ub97c \ub192\uc740 \uc0c1\ud0dc\ub85c \uc720\uc9c0\\n\\n### \ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4\\n\\n> \uac1d\uccb4\uc9c0\ud5a5\uc758 \ubaa9\ud45c\ub294 \uc2e4\uc138\uacc4\ub97c \ubaa8\ubc29\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\\n\uc624\ud788\ub824 \uc0c8\ub85c\uc6b4 \uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uac1c\ubc1c\uc790\uc758 \uc5ed\ud560\uc740 \ub2e8\uc21c\ud788 \uc2e4\uc138\uacc4\ub97c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc548\uc73c\ub85c \uc62e\uaca8 \ub2f4\ub294 \uac83\uc774 \uc544\ub2c8\ub77c \uace0\uac1d\uacfc \uc0ac\uc6a9\uc790\ub97c \ub9cc\uc871\uc2dc\ud0ac \uc218 \uc788\ub294 \uc2e0\uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\\np.21\\n> \\n\\n> \uacfc\uac70\uc758 \uc804\ud1b5\uc801\uc778 \uac1c\ubc1c \ubc29\ubc95\uc740 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uc5c4\uaca9\ud558\uac8c \uad6c\ubd84\ud55c\ub2e4.\\n\uc774\uc5d0 \ubc18\ud574 \uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c\ub294 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uac1d\uccb4\ub77c\ub294 \ud558\ub098\uc758 \ud2c0 \uc548\uc5d0 \ud568\uaed8 \ubb36\uc5b4 \ub193\uc74c\uc73c\ub85c\uc368 \uac1d\uccb4\uc758 \uc790\uc728\uc131\uc744 \ubcf4\uc7a5\ud55c\ub2e4.\\n\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub85c \uad6c\uc131\ub41c \uacf5\ub3d9\uccb4\ub294 \uc720\uc9c0 \ubcf4\uc218\uac00 \uc27d\uace0 \uc7ac\uc0ac\uc6a9\uc774 \uc6a9\uc774\ud55c \uc2dc\uc2a4\ud15c\uc744 \uad6c\ucd95\ud560 \uc218 \uc788\ub294 \uac00\ub2a5\uc131\uc744 \uc81c\uc2dc\ud55c\ub2e4.\\np.33\\n> \\n\\n> **\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubcf8\uc9c8**\\n> \\n> \\n> \uc2dc\uc2a4\ud15c\uc744 \uc0c1\ud638\uc791\uc6a9\ud558\ub294 \uc790\uc728\uc801\uc778 \uac1d\uccb4\ub4e4\uc758 \uacf5\ub3d9\uccb4\ub85c \ubc14\ub77c\ubcf4\uace0 \uac1d\uccb4\ub97c \uc774\uc6a9\ud574 \uc2dc\uc2a4\ud15c\uc744 \ubd84\ud560\ud558\ub294 \ubc29\ubc95\\n> \\n> \uc790\uc728\uc801\uc778 \uac1d\uccb4\ub780 \uc0c1\ud0dc\uc640 \ud589\uc704\ub97c \ud568\uaed8 \uc9c0\ub2c8\uba70 \uc2a4\uc2a4\ub85c \uc790\uae30 \uc790\uc2e0\uc744 \ucc45\uc784\uc9c0\ub294 \uac1d\uccb4\ub97c \uc758\ubbf8\ud55c\ub2e4.\\n> \\n> \uac1d\uccb4\ub294 \uc2dc\uc2a4\ud15c\uc758 \ud589\uc704\ub97c \uad6c\ud604\ud558\uae30 \uc704\ud574 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud55c\ub2e4. \uac01 \uac1d\uccb4\ub294 \ud611\ub825 \ub0b4\uc5d0\uc11c \uc815\ud574\uc9c4 \uc5ed\ud560\uc744 \uc218\ud589\ud558\uba70 \uc5ed\ud560\uc740 \uad00\ub828\ub41c \ucc45\uc784\uc758 \uc9d1\ud569\uc774\ub2e4.\\n> \\n> \uac1d\uccb4\ub294 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud558\uae30 \uc704\ud574 \uba54\uc2dc\uc9c0\ub97c \uc804\uc1a1\ud558\uace0, \uba54\uc2dc\uc9c0\ub97c \uc218\uc2e0\ud55c \uac1d\uccb4\ub294 \uba54\uc2dc\uc9c0\ub97c \ucc98\ub9ac\ud558\ub294 \ub370 \uc801\ud569\ud55c \uba54\uc11c\ub4dc\ub97c \uc790\uc728\uc801\uc73c\ub85c \uc120\ud0dd\ud55c\ub2e4.\\n> p.35\\n> \\n\\n> \ud074\ub798\uc2a4\uc758 \uad6c\uc870\uc640 \uba54\uc11c\ub4dc\uac00 \uc544\ub2c8\ub77c \uac1d\uccb4\uc758 \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc5d0 \uc9d1\uc911\ud558\ub77c.\\n\uac1d\uccb4\uc9c0\ud5a5\uc740 \uac1d\uccb4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774\uc9c0 \ud074\ub798\uc2a4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\\np.38\\n> \\n\\n> \uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c \uc911\uc694\ud55c \uac83\uc740 \ub3d9\uc801\uc73c\ub85c \ubcc0\ud558\ub294 \uac1d\uccb4\uc758 \u2018\uc0c1\ud0dc\u2019\uc640 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\ub294 \u2018\ud589\uc704\u2019\ub2e4.\\n\ud074\ub798\uc2a4\ub294 \ud0c0\uc785\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud574 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uad6c\ud604 \uba54\ucee4\ub2c8\uc998\uc774\ub77c\ub294 \uc0ac\uc2e4\uc744 \uae30\uc5b5\ud558\ub77c.\\np.105\\n> \\n\\n> \ucc45\uc784 \uc8fc\ub3c4 \uc124\uacc4\uc758 \ud575\uc2ec\uc740 \uc5b4\ub5a4 \ud589\uc704\uac00 \ud544\uc694\ud55c\uc9c0\ub97c \uba3c\uc800 \uacb0\uc815\ud55c \ud6c4\uc5d0 \uc774 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac1d\uccb4\ub97c \uacb0\uc815\ud558\ub294 \uac83\uc774\ub2e4.\\n\uc774 \uacfc\uc815\uc744 \ud754\ud788 What/Who \uc0ac\uc774\ud074\uc774\ub77c\uace0 \ud55c\ub2e4.\\n\u2019\uc5b4\ub5a4 \ud589\uc704(What)\u2019\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud55c \ud6c4 \u2018\ub204\uac00(who)\u2019 \uadf8 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud574\uc57c \ud55c\ub2e4.\\n\uc5ec\uae30\uc11c \u2018\uc5b4\ub5a4 \ud589\uc704\u2019\uac00 \ubc14\ub85c \uba54\uc2dc\uc9c0\ub2e4.\\np.158\\n>"},{"id":"2022-retrospective","metadata":{"permalink":"/2022-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx","title":"2022\ub144 \ud68c\uace0","description":"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70","date":"2023-01-02T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 2\uc77c","tags":[{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.705,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"2022\ub144 \ud68c\uace0","slug":"2022-retrospective","tags":["Retrospective"]},"prevItem":{"title":"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574","permalink":"/the-essence-of-object-orientation"},"nextItem":{"title":"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.","permalink":"/book-writer"}},"content":"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70 \\n\\n### \uc804\uc5ed\\n\\n\uc57d 1\ub144 6\uac1c\uc6d4\uac04\uc758 \uacf5\uad70 \uc815\ubcf4\ubcf4\ud638\ubcd1 \uc0dd\ud65c\uc744 \ub9c8\uce58\uace0 \uc804\uc5ed\uc744 \ud588\ub2e4. \\n\uc870\uae30 \uc804\uc5ed \ub54c\ubb38\uc5d0 2021\ub144 12\uc6d4\uc5d0 \ub098\uc654\uc9c0\ub9cc, \uc2e4\uc81c \uc804\uc5ed \ub0a0\uc9dc\ub294 2022\ub144\uc774\ub2c8 \ud68c\uace0\uc5d0 \uc801\uc5b4\ub3c4 \uc0c1\uad00\uc5c6\uaca0\uc9c0. \\n\\n\uc870\uae08 \ub354 \ubbf8\ub798\uc5d0 \ub300\ud55c \uc0dd\uac01\uc744 \ud574\ubcfc\uac78 \uadf8\ub7ac\ub2e4. \\n\uc804\uc5ed\uc744 \ud588\uc9c0\ub9cc \ubb50 \ud558\ub098 \uc81c\ub300\ub85c \ud560 \uc904 \uc544\ub294 \uac83\ub3c4 \uc5c6\uc73c\ub2c8 \ub113\uc740 \ubc14\ub2f7\uc18d\uc5d0 \ub369\uadf8\ub7ec\ub2c8 \ub193\uc544\uc9c4 \uae30\ubd84\uc774 \uad1c\ud788 \ub4e4\uc5c8\uc5c8\ub2e4. \\n\uc77c\ucc0d \uc0dd\uac01\uc744 \uc815\ub9ac\ud558\uc5ec \ubc29\ud5a5\uc744 \uc7a1\uc9c0 \ubabb\ud588\uae30\uc5d0 \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub0a8\uc558\ub2e4. \\n\\n### \uc790\ubc14\\n\\n\uc804\uc5ed\uc744 \ud558\uace0 \uc9c4\ub85c\ub97c \uace0\ubbfc\ud558\ub2e4 \ud5a5\ub85c\ub2d8\uc758 [\uc790\ubc14 \uacf5\ud654\uad6d](https://jojoldu.tistory.com/609) \ud3ec\uc2a4\ud305\uc744 \uc77d\uace0 \ub098\uc11c \uc790\ubc14 \uacf5\ubd80\ub97c \uc2dc\uc791\ud588\ub2e4. \\n\uc720\uba85\ud55c \uc778\ud504\ub7f0\uc758 \uae40\uc601\ud55c\ub2d8\uc758 \uc2a4\ud504\ub9c1 \uac15\uc758\ub3c4 \uc788\uace0, \uc88b\uc740 \uc790\ubc14 \uac1c\ubc1c \uc11c\uc801\uc774 \ub9ce\uc544\uc11c \ub3c5\ud559\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4. \\n\ud558\ub2e4 \ubcf4\ub2c8 \uc790\ubc14\uc640 \uc2a4\ud504\ub9c1\uc744 \uacf5\ubd80\ud558\uba74\uc11c \u201c\uc65c \uc9c4\uc791\ud558\uc9c0 \uc54a\uc558\uc9c0\u201d\ub77c\ub294 \uc0dd\uac01\ub3c4 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4. \\n\uc591\uc9c8\uc758 \uc790\ub8cc\ub3c4 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0, \uc608\uc804\uc5d0 \ub178\ub4dc\ub85c \uac1c\ubc1c\ud588\uc744 \ub54c \ud480\uc9c0 \ubabb\ud588\ub358 \ub2f5\ub2f5\ud568\uc744 \ub9ce\uc774 \ud574\uc18c\ud588\ub358 \uac83 \uac19\ub2e4.\\n\\n23\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae4a\uac8c \uc790\ubc14\ub97c \uacf5\ubd80\ud574\ubcfc \uc0dd\uac01\uc774\ub2e4. \\n\uc5b8\uc5b4\ub97c \ud558\ub098 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ub9ce\uc740 \ub3c4\uc6c0\uc774 \ub418\ub294 \uac83 \uac19\ub2e4.\\n\\n### \uc2a4\ud130\ub514\\n\\n\uae40\uc601\ud55c\ub2d8\uc758 \uac15\uc758\ub97c \uac70\uc758 \ub2e4 \ub4e4\uc5c8\uc744 \ub54c\ucbe4, \ud56d\uc0c1 \uac15\uc758\uc5d0\uc11c \uc5b8\uae09\ub418\ub294 \ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1\uc744 \uc77d\uc5b4\ubcf4\uace0 \uc2f6\uc5b4\uc84c\uace0 \\n\ud63c\uc790 \uacf5\ubd80\ud558\uae30\uc5d0\ub294 \ub3d9\uae30\ubd80\uc5ec\ub3c4 \ubd80\uc871\ud588\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud130\ub514\ub97c \uc2dc\uc791\ud588\ub2e4. \\n\ub2e4\ub978 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\uc744 \ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uacf5\ubd80\ub97c \ud560 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\uc9c0\ub9cc \ub098\uc5d0\uac8c\ub294 \ub0b4\uc6a9\uc774 \uaf64\ub098 \uc5b4\ub824\uc6cc\uc11c \uc2dc\uac04\uc744 \ub9ce\uc774 \uc18c\ube44\ud588\ub2e4. \\n\uac19\uc774 \uc2a4\ud130\ub514\ud558\uc2dc\ub294 \ubd84\uacfc 7\uac1c\uc6d4 \ub3d9\uc548 \uc2a4\ud130\ub514\ub97c \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00 \ucd1d 3\uad8c\uc758 \ucc45\uc744 \uc77d\uc744 \uc218 \uc788\uc5c8\ub2e4.\\n\\n### \uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\\n\\n\uad70 \ubcf5\ubb34 \uc911\uc77c \ub54c \uc9c0\uc6d0\ud588\ub2e4 \ub5a8\uc5b4\uc9c4 \uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ub2e4\uc2dc \uc9c0\uc6d0\ud588\ub2e4. \\n\uc774\ubc88 \uc5f0\ub3c4\uc5d0 \ucde8\uc5c5\uc744 \ud558\ub294 \uac8c \ubaa9\ud45c\uc600\uc9c0\ub9cc \ub0b4\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \ud2b9\ubcc4\ud55c \ubb34\uae30\uac00 \uc5c6\ub2e4\ub294 \uac78 \uae68\ub2ec\uc558\ub2e4. \\n\uc801\uc9c0 \uc54a\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574 \uc900\ube44\ub97c \ud588\uace0, \uac10\uc0ac\ud558\uac8c\ub3c4 \uc774\ubc88\uc5d0\ub294 \ucd5c\uc885 \ud569\uaca9\uc744 \ud588\ub2e4. \\n\\n\ub09c \uc0ac\ub78c\ub4e4\uacfc \uc18c\ud1b5\ud558\uace0, \ud611\uc5c5\ud558\ub294 \ub2a5\ub825\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc744 \ub9ce\uc774 \ud588\ub2e4. \\n\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ud1b5\ud574 \uadf8 \ube48 \ubd80\ubd84\uc744 \ucc44\uc6b0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. \\n\\n### 2023\ub144\uc5d0\ub294\\n\\n\ub9c8\uc74c\uc758 \uc5ec\uc720\uac00 \uc5c6\uc5c8\ub358 2022\ub144\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\ud558\uace0 \uc2f6\uc740 \uac74 \ub9ce\uc9c0\ub9cc, \uc774\ubc88\uc5d0\ub294 \uc5ec\uc720\ub97c \uac00\uc9c0\uace0 \ud560 \uc218 \uc788\ub294 \uac83\uc5d0 \ucd5c\uc120\uc744 \ub2e4\ud574\uc57c\uaca0\ub2e4."},{"id":"book-writer","metadata":{"permalink":"/book-writer","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx","source":"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx","title":"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.","description":"\ucc45 \uc815\ubcf4","date":"2023-01-01T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 1\uc77c","tags":[{"label":"Book","permalink":"/tags/book"}],"readingTime":4.425,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.","slug":"book-writer","tags":["Book"]},"prevItem":{"title":"2022\ub144 \ud68c\uace0","permalink":"/2022-retrospective"}},"content":"### \ucc45 \uc815\ubcf4\\n\\n> \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \\n> \ubc15\uc194\ubbf8 \\n>\\n\\n### \uc77d\uace0 \ub098\uc11c\\n\\n\uc800\uc790\uc758 \uacbd\ud5d8\uacfc \ud568\uaed8 \uae00\uc4f0\uae30\uc5d0 \ub300\ud55c \uac00\ubcbc\uc6b4 \uc870\uc5b8\uc774 \ub2f4\uaca8\uc788\uc5b4 \uac00\ubccd\uac8c \uc77d\uae30 \uc88b\uc558\ub2e4. \\n\uae00\uc744 \uc798 \uc791\uc131\ud574 \ubcf4\uace0 \uc2f6\uc744 \ub54c \uc801\uc6a9\ud574 \ubcfc \uc218 \uc788\ub294 \uc815\ubcf4\uac00 \ub9ce\uc544\uc11c \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub2e4. \\n\\n\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\uc758 \ud504\ub9ac\ucf54\uc2a4\ub97c \uc9c4\ud589\ud560 \ub54c \ud6c4\uae30\ub97c \uc791\uc131\ud558\uace0 \ub098\uba74 \ud56d\uc0c1 \uae00\uc774 \ub531\ub531\ud558\ub2e4\ub294 \ub290\ub08c\uc744 \ubc1b\uc558\ub2e4. \\n\ub2e4\ub978 \uc9c0\uc6d0\uc790\ub4e4\uc758 \uc77d\uae30 \ud3b8\ud558\uace0, \ubc1d\uc740 \ub290\ub08c\uc744 \uc8fc\ub294 \uae00\uc744 \ubcf4\uba74 \ubd80\ub7ec\uc6b4 \ub9c8\uc74c\uc744 \uac00\uc9c0\uae30\ub3c4 \ud588\ub2e4. \\n\uc774 \ucc45\uc744 \uc77d\uc5c8\uc73c\ub2c8 2023\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae00\uc744 \uc798 \uc801\uc5b4\ubcf4\ub824\uace0 \ud55c\ub2e4.\\n\\n### \ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4\\n\\n> \ubb38\uc7a5\uc774 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74\\n\ub0b4\uc6a9\uc744 \uc77c\ubaa9\uc694\uc5f0\ud558\uac8c \uc815\ub9ac\ud588\uace0, \uae00\uc758 \uc758\ub3c4\ub3c4 \uc090\ub6a4\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub3c4 \uc801\uc808\ud55c \uac83\uc73c\ub85c \uace8\ub790\ub294\ub370\u2026 \uadf8\ub7f0\ub370\ub3c4 \uc5b4\ub518\uac00\uac00 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74? \ucd95\ucd95 \ucc98\uc9c0\uace0 \ub530\ubd84\ud558\ub2e4\uba74? \ub9d0\uaf2c\ub9ac\ub97c \ubaa8\uc870\ub9ac \u2018~\ub2e4\u2019\ub85c \ud1b5\uc77c\ud55c \uac74 \uc544\ub2cc\uc9c0 \uc810\uac80\ud574 \ubcf4\uc138\uc694.\\n> \\n\\n> \ub9d0\uaf2c\ub9ac\ub97c \uc798 \uac16\uace0 \ub180\uc544\uc57c \ud569\ub2c8\ub2e4. \ubb38\uc7a5\uc758 \ub9c8\uc9c0\ub9c9 \uae00\uc790\ub97c \ub9e4\ubc88 \ub2e4\ub974\uac8c \uace0\uccd0\uc4f0\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uae00\uc5d0 \ud65c\uae30\ub97c \ub354\ud560 \uc218 \uc788\uc8e0. \ub54c\ub860 \ubb38\uc7a5\uc744 \ub2e4 \ub9c8\uce58\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub85c\ub9cc \ub05d\ub9fa\ub294 \uac83\ub3c4 \ubc29\ubc95. \ubb38\uc7a5\uacfc \ubb38\uc7a5 \uc0ac\uc774\uc5d0 \uc27c\ud45c\uac00 \ub4e4\uc5b4\uc11c\uba70 \uae00 \uc804\uccb4\uc5d0 \ud65c\uae30\uac00 \ub3cc\uac8c \ub3fc\uc694. \ubb38\uc7a5\uc758 \uae38\uc774\ub3c4 \ub2e4\ucc44\ub85c\uc6cc\uc9c0\ub294 \ub355\ubd84\uc5d0 \ub364\uc73c\ub85c \uc5bb\uac8c \ub418\ub294 \uac83\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ubc14\ub85c, \uae00\uc758 \ub9ac\ub4ec.\\n> \\n\\n> \uc774\uc804 \ubb38\uc7a5\uc5d0\uc11c \ub05d\ub09c \uae00\uc790\ub85c, \ub2e4\uc74c \ubb38\uc7a5\uc744 \ub05d\ub9fa\uc9c0 \uc54a\uae30. \ud55c\ub450 \ubb38\ub2e8\ub9c8\ub2e4 \ub2e8\uc5b4 \uc218\uc900\uc758 \uc544\uc8fc \uc9e7\uc740 \ubb38\uc7a5 \ubc30\uce58\ud558\uae30.\\n> \\n\\n> \uae00\uc758 \uc9c4\uc9dc \uc774\uc720, \uae00\uc758 \uc9c4\uc9dc \ubaa9\uc801, \uae00\uc758 \uc9c4\uc9dc \ub300\uc0c1\uc744 \ucc3e\uc73c\ub824\uace0 \uc560\uc37c\uc2b5\ub2c8\ub2e4. \uc9c0\uae08\ucc98\ub7fc \ud2c0\uc744 \ub5a0\uc62c\ub9b0\ub2e4\uac70\ub098, \ub208\uce58\ub97c \ubcf8\ub2e4\uac70\ub098, \uc815\uce58\uc801\uc778 \uc148\ub3c4 \ud558\uc9c0 \uc54a\uc558\uc5b4\uc694.\\n> \\n\\n> \uc81c\ubaa9\uc740 \uc9e7\uac8c, \ubcf4\uae30 \uc27d\uac8c, \uc77d\uae30 \uc27d\uac8c, \ubc1c\uc74c\uc774 \ube44\uc2b7\ud558\uac8c, \uc21c\uc11c\ub97c \ubc14\uafd4\uc11c\\n> \\n\\n> \uae00\uc744 \ub9c8\uc9c0\ub9c9\uc73c\ub85c \ub2e4\ub4ec\uc744 \ub54c, \ub178\ub798\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \ubc29\ubc95\uc740 \uc5c6\uc744\uc9c0 \uace0\ubbfc\ud574\ubd05\ub2c8\ub2e4. \uac10\ud788 \uac00 \ub2ff\uc744 \uc218 \uc5c6\ub294 \ubaa9\ud45c\uc774\uaca0\uc9c0\ub9cc, \ud560 \uc218 \uc788\ub294 \ucd5c\uc18c\ud55c\uc758 \ub9ac\ub4ec\uc774\ub77c\ub3c4 \ubd99\uc5ec\uc8fc\uace0 \uc2f6\uc5b4\uc694.\\n> \\n\\n> \uc5ec\ub294 \ub9d0\uacfc \ub9c8\uc9c0\ub9c9 \ub9d0\uc5d0 \uc791\uc815\ud558\uace0 \ub9c8\uc74c\uc744 \ub2f4\ub294 \uc5f0\uc2b5\uc744 \ud574\ubd05\uc2dc\ub2e4. \uae00\uc758 \uc5b4\ub290 \uad6c\uc11d\uc774\ub77c\ub3c4 \ubed4\ud55c \uae00\uc790\ub294 \ub0a8\uae30\uc9c0 \uc54a\uaca0\ub178\ub77c \ub2e4\uc9d0\ud558\uba70 \uc368\ubcf4\ub294 \uac81\ub2c8\ub2e4. \ub098\ub9cc\uc774 \uac00\uc9c4 \uc720\uc77c\ud55c \uba54\uc2dc\uc9c0\uc5d0 \uc9d1\uc911\ud558\uba74\uc11c\uc694. \uadf8\ub7fc \uc0dd\uac01\uc774 \ub2ec\ub77c\uc9c0\uace0, \uace0\ub974\ub294 \ub2e8\uc5b4\ub3c4 \ub2ec\ub77c\uc9c0\uace0, \ub0a8\uae34 \ubb38\uc7a5\ub3c4 \ub2ec\ub77c\uc838\uc694. \uacb0\uad6d\uc5d0\ub294 \uae00\uc744 \uc4f4 \uc0ac\ub78c\uc778 \ub098 \uc790\uc2e0\ub3c4 \ub0a8\ub2ec\ub77c\uc9c8 \uac81\ub2c8\ub2e4.\\n> \\n\\n> \ub9de\ucda4\ubc95\uc740 \uc911\uc694\ud569\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \ub9de\ucda4\ubc95\ubcf4\ub2e4 \ub354 \uc911\uc694\ud55c \uac74 \uac70\uae30\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc785\ub2c8\ub2e4. \ub0b4 \ub9c8\uc74c\uc744 \uae00\uc5d0 \ub2f4\uc544 \uc2e4\uc5b4 \ubcf4\ub0b4\uae30 \uc804, \ub9de\ucda4\ubc95\uc744 \uc810\uac80\ud558\ub294 \uc774\uc720 \uc5ed\uc2dc \uadf8\uac81\ub2c8\ub2e4. \uc624\uc9c1 \ub0b4 \ub9c8\uc74c\uc774 \ub0a8\uc5d0\uac8c \uc77d\ud788\ub294 \ub3d9\uc548 \ubc29\ud574\uac00 \ub418\uc9c0 \uc54a\uae30\ub97c \ubc14\ub77c\uae30 \ub54c\ubb38\uc774\uc8e0. \ub0b4\uac00 \uc4f4 \uae00\ub3c4, \ub0a8\uc774 \uc4f4 \uae00\ub3c4. \uc5b8\uc81c\ub098 \uadf8 \uc548\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc774 \uba3c\uc800\uc785\ub2c8\ub2e4.\\n> \\n\\n> \uae00\uc744 \uc4f4\ub2e4\uace0 \uae00\uc774 \uc644\uc131\ub418\ub294 \uac8c \uc544\ub2c8\uc5d0\uc694. \uae00\uacfc \ub2ee\uc740 \ubaa8\uc2b5\uc73c\ub85c \uc0b4 \ub54c, \uae00\uc740 \ube44\ub85c\uc18c \uc644\uc131\ub429\ub2c8\ub2e4.\\n>"}]}')}}]); \ No newline at end of file diff --git a/assets/js/b2b675dd.adafc1ef.js b/assets/js/b2b675dd.adafc1ef.js new file mode 100644 index 000000000..13ac40959 --- /dev/null +++ b/assets/js/b2b675dd.adafc1ef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[533],{28017:n=>{n.exports=JSON.parse('{"blogPosts":[{"id":"refactoring-retrospective","metadata":{"permalink":"/refactoring-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-refactoring/pull/465","date":"2023-10-31T00:00:00.000Z","formattedDate":"2023\ub144 10\uc6d4 31\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":8.095,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0","slug":"refactoring-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"nextItem":{"title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/jdbc-retrospective"}},"content":":::note PR \ub9c1\ud06c\\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-refactoring/pull/465 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-refactoring/pull/547 \\n3\ub2e8\uacc4: https://github.com/woowacourse/jwp-refactoring/pull/610 \\n4\ub2e8\uacc4: https://github.com/woowacourse/jwp-refactoring/pull/721 \\n:::\\n\\n### \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158\\n\\n\uc694\uad6c\uc0ac\ud56d \uc791\uc131 \u2192 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud55c \ucf54\ub4dc \ubcf4\ud638 \u2192 \ub9ac\ud329\ud130\ub9c1 \u2192 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1 \u2192 \uba40\ud2f0\ubaa8\ub4c8 \uc21c\uc11c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4. \\n\ubbf8\uc158\uc5d0 \uc628\uc804\ud788 \uc9d1\uc911\ud558\uace0 \uc2f6\uc5c8\uc9c0\ub9cc, \ud504\ub85c\uc81d\ud2b8\uc640 \ubcd1\ud589\ud558\uba74\uc11c \uc9c4\ud589\ud588\uae30\uc5d0 \uc5b4\ub290\uc815\ub3c4 \ud0c0\ud611\ubcf4\uace0 \uc9c4\ud589\ud55c \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c \uc544\uc26c\uc6e0\ub2e4. \\n\\n### 1, 2\ub2e8\uacc4\\n\\n1\ub2e8\uacc4\ub294 \uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud558\uace0, \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ucd94\ud6c4\uc5d0 \ub9ac\ud329\ud130\ub9c1 \ud560 \ub54c \uc548\uc815\uac10 \uc788\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\ub3c4\ub85d \uc900\ube44\ud558\ub294 \uacfc\uc815\uc774\uc5c8\ub2e4. \\n\uc694\uad6c\uc0ac\ud56d\uc744 \uc791\uc131\ud560 \ub54c \uc81c\uacf5\ub41c \uc6a9\uc5b4 \uc0ac\uc804\uc744 \ucd5c\ub300\ud55c \ud65c\uc6a9\ud558\uba74\uc11c \uae30\uc874\uc758 \ucf54\ub4dc\ub97c \ubcf4\uba74\uc11c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud588\ub2e4. \\n\ud14c\uc2a4\ud2b8\ub294 \uc2dc\uac04 \uad00\uacc4\uc0c1 API, \uc11c\ube44\uc2a4 \ub458 \uc911 \ud558\ub098\ub9cc \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4. \\n\\n\ucd5c\uc885\uc801\uc73c\ub85c \uc11c\ube44\uc2a4 \uae30\uc900\uc73c\ub85c \ud1b5\ud569 \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud588\ub294\ub370 \uc57d\uac04 \ud6c4\ud68c\ub418\ub294 \uacb0\uc815\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\ub9ac\ud329\ud130\ub9c1 \uacfc\uc815\uc5d0\uc11c API \uba85\uc138\uac00 \ubc14\ub00c\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4\ub294 \uac83\uc744 \uae30\uc900\uc744 \uc7a1\uace0 \uc774\ubc88 \ubbf8\uc158\uc744 \ud55c\ub2e4\uace0 \uac00\uc815\ud588\uc744 \ub54c API \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\uace0, \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ub354 \uc548\uc815\uac10 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\n2\ub2e8\uacc4\ub294 \uc791\uc131\ub41c \ud14c\uc2a4\ud2b8 \uae30\ubc18\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\uc11c\ube44\uc2a4\uc5d0\uc11c \ub3c4\uba54\uc778\uc744 \uc9c1\uc811 \ubc18\ud658\ud558\ub294 \uad6c\uc870\uc600\ub294\ub370, \ub3c4\uba54\uc778\uc5d0 JPA\ub97c \uc801\uc6a9\ud558\uba74 \uae30\uc874 \uba85\uc138\uc640 \ub2ec\ub77c\uc9c8 \uac83\uc744 \uc6b0\ub824\ud574\uc11c DTO\ub85c \uc218\uc815\ud558\ub294 \uc791\uc5c5\uc744 \uba3c\uc800 \uc9c4\ud589\ud588\ub2e4. \\nDTO \uc774\ud6c4\uc5d0 \uc11c\ube44\uc2a4\uc5d0 \uc788\ub294 \ub85c\uc9c1\uc744 \ub3c4\uba54\uc778\uc73c\ub85c \uc774\ub3d9\uc2dc\ud0a4\uace0, \ucd5c\uc885\uc801\uc73c\ub85c JPA\ub97c \uc801\uc6a9\ud558\ub294 \uc21c\uc11c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud588\ub2e4. \\n\uc774 \uacfc\uc815\uc5d0\uc11c \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \uc591\ubc29\ud5a5\uc778 \ubd80\ubd84\ub3c4 \uc0dd\uaca8\ub0ac\ub2e4. \\n\\n### \uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\\n\\n\uc911\uac04\uc5d0 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\uc5d0 \uad00\ud55c \uc81c\uc774\uc2a8\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4. \\n\uc18c\ud504\ud2b8\uc6e8\uc5b4\uc758 \ubcf5\uc7a1\uc131\uc744 \ub2e4\ub8e8\ub294 \uc9c0\ud61c\ub294 \uc5d0\ub9ad \uc5d0\ubc18\uc2a4\uc758 \uc800\uc11c `\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4`\uc758 \ubd80\uc81c\uc774\ub2e4. \\n\\n\ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\ub294 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4, \uc804\uc220\uc801 \uc124\uacc4\uac00 \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4. \\n\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4, \uc804\ub7b5\uc801 \uc124\uacc4\uac00 \uc804\uccb4\uc758 90%\uc5d0 \ud574\ub2f9\ud560 \uc815\ub3c4\ub85c \uc911\uc694\ud558\ub2e4\uace0 \ud55c\ub2e4. \ub610\ud55c \uc804\uc220\uc801 \uc124\uacc4\ub9cc \ud558\ub294 \uacbd\uc6b0\ub97c DDD Lite \ub77c\uace0 \ud55c\ub2e4. \\n\\n\uac04\ub2e8\ud788 \ub3c4\uba54\uc778 \uc8fc\ub3c4 \uc124\uacc4\uc5d0\uc11c \ub098\uc624\ub294 \ub2e8\uc5b4\ub97c \uc815\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n| \ub2e8\uc5b4 | \uc124\uba85 |\\n| --- | --- |\\n| \ub3c4\uba54\uc778 | \uc18c\ud504\ud2b8\uc6e8\uc5b4\ub85c \ud574\uacb0\ud558\uace0\uc790 \ud558\ub294 \ubb38\uc81c \uc601\uc5ed |\\n| \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8 | \ud574\uacb0 \uc601\uc5ed, \uad00\uc2ec\uc0ac\ub97c \ubd84\ub9ac\ud558\uace0 \uaca9\ub9ac\ud558\uc5ec \ubb38\uc81c \ud574\uacb0\uc5d0 \uc9d1\uc911\ud560 \ubc94\uc704 |\\n| \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4 | \ud504\ub85c\uc81d\ud2b8\uc5d0 \uc774\ud574\uad00\uacc4\uc790\ub4e4\uc758 \uacf5\ud1b5\ub41c \uc5b8\uc5b4\ub85c, \uc11c\ub85c\uc758 \uc758\uc0ac\uc18c\ud1b5 \ube44\uc6a9\uc744 \uc904\uc774\uae30 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 \uc5b8\uc5b4 |\\n| \uc804\ub7b5\uc801 \uc124\uacc4 | \ub3c4\uba54\uc778 \uc804\ubb38\uac00\uc640 \uac1c\ubc1c\uc790\uac00 \ud568\uaed8 \uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec \ub3c4\uba54\uc778\uacfc \uad00\ub828\ub41c \uc9c0\uc2dd\uc744 \uc774\ud574\ud558\uace0 \uc774\ub97c \ubc14\ud0d5\uc73c\ub85c \uacbd\uacc4\ub97c \ub098\ub220 \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc815\uc758\ud558\uace0, \ucee8\ud14d\uc2a4\ud2b8 \ub9f5\uc744 \uc0dd\uc131\ud558\ub294 \uac83\uc744 \ud3ec\ud568\ud558\ub294 \uacfc\uc815 |\\n| \uc804\uc220\uc801 \uc124\uacc4 | \uc804\ub7b5\uc801 \uc124\uacc4\uc5d0\uc11c \uc815\uc758\ud55c \ubc14\uc6b4\ub514\ub4dc \ucee8\ud14d\uc2a4\ud2b8\uc640 \ub3c4\uba54\uc778\uc744 \uc774\uc6a9\ud558\uc5ec \uc560\uadf8\ub9ac\uac70\ud2b8, Entity\uc640 VO, Repository \ub4f1\uc744 \uad6c\ud604\ud558\ub294 \uacfc\uc815 |\\n\\n\uc774 \uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ub0b4\uc6a9\ub4e4\uc774 \ub098\uc654\uc9c0\ub9cc, \uc9c0\uc2dd\uc744 \uc81c\ub300\ub85c \ud761\uc218\ud558\uc9c0\ub294 \ubabb\ud588\ub2e4. \\n\\n### 3, 4\ub2e8\uacc4\\n\\n\uc81c\uc774\uc2a8\uc758 \uac15\uc758\ub97c \ub4e3\uace0, \uc870\uc601\ud638\ub2d8\uc758 \uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5 \uc720\ud29c\ube0c \uc601\uc0c1\uc744 \ubcf8 \ub2e4\uc74c 3, 4\ub2e8\uacc4\ub97c \uc9c4\ud589\ud588\ub2e4. \\n\\n3\ub2e8\uacc4\ub294 \uc758\uc874\uc131 \ub9ac\ud329\ud130\ub9c1\uc5d0 \uad00\ud55c \ub0b4\uc6a9\uc774\uc5c8\ub2e4. \ud074\ub798\uc2a4 \uac04 \ubc29\ud5a5, \ud328\ud0a4\uc9c0 \uac04 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc774 \ub418\ub3c4\ub85d \ub9ac\ud329\ud130\ub9c1\uc744 \uc9c4\ud589\ud574\uc57c \ud588\uc5c8\ub2e4. \\n\ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4\ub4e4\uc744 \ubb36\uace0, \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uae30 \uc704\ud574 \uc0dd\uba85\uc8fc\uae30\uac00 \ub2e4\ub974\ub2e4\uba74 id\ub97c \uc774\uc6a9\ud558\uc5ec \ucc38\uc870\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4. \\n\\n\uc758\uc874\uc131\uc744 \ubd84\ub9ac\ud558\uae30 \uc704\ud574 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. \uc774\ubca4\ud2b8\ub294 \ud604\uc7ac \uae30\uc900\uc73c\ub85c \uacfc\uac70\uc5d0 \ubc8c\uc5b4\uc9c4 \uac83\uc744 \ud45c\ud604\ud558\uae30 \ub54c\ubb38\uc5d0 \uc774\ubca4\ud2b8\uba85\uc740 \uacfc\uac70 \uc2dc\uc81c\uac00 \ub418\uc5b4\uc57c\ud558\ub294 \uac83\uc744 \uc54c\uc558\ub2e4. \\n\ucc98\uc74c\uc5d0\ub294 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud588\uc9c0\ub9cc, \uc11c\ube44\uc2a4 \ub85c\uc9c1\uc744 \ucd5c\ub300\ud55c \uac04\ub2e8\ud558\uac8c \ud558\uae30 \uc704\ud574 \ub3c4\uba54\uc778 \uc774\ubca4\ud2b8\ub3c4 \uc0ac\uc6a9\ud574\ubcf4\uc558\ub2e4. \\n\\n4\ub2e8\uacc4\ub294 \uba40\ud2f0\ubaa8\ub4c8\ub85c \ubd84\ub9ac\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub294\ub370 3\ub2e8\uacc4\uc5d0\uc11c \ubd84\ub9ac\ud574\ub454 \ud328\ud0a4\uc9c0 \uadf8\ub300\ub85c \ubd84\ub9ac\ud558\uc9c0\ub294 \uc54a\uc558\ub2e4. \\n3\ub2e8\uacc4\uc5d0\uc11c\ub294 \ud568\uaed8 \uc0dd\uc131\ub418\uace0 \uc0ad\uc81c\ub418\ub294 \uac1d\uccb4 \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ud588\ub2e4. 4\ub2e8\uacc4\uc5d0\uc11c\ub294 \ub0b4\uac00 \uc778\uc2dd\ud558\uae30 \ud3b8\ud55c \uae30\uc900\uc73c\ub85c \ubd84\ub9ac\ub97c \ud588\ub2e4. \\n\uc544\uc9c1 \ubd84\ub9ac\ud55c \uae30\uc900\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \ubaa8\ud638\ud588\uace0, \uc774\uc5d0 \ub300\ud55c \uacf5\ubd80\ub97c \uc870\uae08 \ub354 \ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tsubgraph Table\\n\\t\\tOrderTable --\x3e TableGroup\\n\\tend\\n\\tsubgraph Order\\n\\t\\tO\\n\\tend\\n O[Order] --\x3e OrderTable\\n\\tsubgraph Menu\\n\\t\\tM[Menu] --\x3e MenuGroup\\n\\t\\tM --\x3e Product\\n\\tend\\n\\tO --\x3e M\\n```\\n\\n\ucd94\uac00\ub85c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc704\ud55c \uc9c1\uc811 \uc791\uc131\ud55c `@ServiceTest` \ucee4\uc2a4\ud140 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc788\uc5c8\ub294\ub370, \uc0c1\uc704 \ubaa8\ub4c8\uc758 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \ub9cc\ub4e0 \ud074\ub798\uc2a4\ub97c \ud558\uc704 \ubaa8\ub4c8\uc5d0\uc11c\ub294 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c TestFixtures\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\uacb0\ud588\ub2e4. \\n\\n### \ub9c8\ubb34\ub9ac\\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc758 \ub9c8\uc9c0\ub9c9 \ubbf8\uc158\uc774\ub2c8 \ub9cc\ud07c, \uac00\uc7a5 \ud765\ubbf8\ub85c\uc6b4 \ubbf8\uc158\uc774\uc5c8\uace0 \ubc30\uc6b8\uc810\ub3c4 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4. \\n\ubc14\uc05c \uae30\uac04\uc774\ub77c \ub9ce\uc740 \ub9ac\ubdf0\ub97c \ub0a8\uae30\uc9c0 \ubabb\ud588\ub358 \ub9ac\ubdf0\uc774 \ud638\uc774\uc5d0\uac8c \ubbf8\uc548\ud558\uace0, \ucf54\uba58\ud2b8 \uaf3c\uaf3c\ud558\uac8c \ub2ec\uc544\uc8fc\uace0 \ubbf8\uc158\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub3c4 \uc624\ud504\ub77c\uc778\uc73c\ub85c \ub9ce\uc774 \ub098\ub208 \ub9ac\ubdf0\uc5b4 \ud14c\uc624\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4. \\n\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[\ub3c4\uba54\uc778 \uc6d0\uc815\ub300, \uc6b0\uc544\ucf58 2021](https://www.youtube.com/watch?v=kmUneexSxk0) \\n[\uc6b0\uc544\ud55c\uac1d\uccb4\uc9c0\ud5a5, \uc6b0\uc544\ud55c\ud14c\ud06c\uc138\ubbf8\ub098](https://www.youtube.com/watch?v=dJ5C4qRqAgA) \\n[TestFixtures, \uad8c\ub0a8\ub2d8](https://kwonnam.pe.kr/wiki/gradle/testfixtures)"},{"id":"jdbc-retrospective","metadata":{"permalink":"/jdbc-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-jdbc/pull/267","date":"2023-10-10T00:00:00.000Z","formattedDate":"2023\ub144 10\uc6d4 10\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.83,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","slug":"jdbc-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0","permalink":"/refactoring-retrospective"},"nextItem":{"title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/mvc-retrospective"}},"content":":::note PR \ub9c1\ud06c\\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358 \\n3\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448 \\n4\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515 \\n:::\\n\\n### Jdbc \uad6c\ud604\\n\\n\uc774\ubc88 \ubbf8\uc158\uc740 Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uace0, Transaction \uacbd\uacc4 \uc124\uc815\uacfc \ub3d9\uae30\ud654\ud558\ub294 \ubd80\ubd84\uc744 \uad6c\ud604\ud574 \ubcf4\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\ubbf8\uc158 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n- JDBC \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uba74\uc11c \uc911\ubcf5\uc744 \uc81c\uac70\ud558\ub294 \uc5f0\uc2b5\uc744 \ud55c\ub2e4.\\n- \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\ub97c \ub192\uc778\ub2e4.\\n\\n\ucd5c\ub300\ud55c Java\uac00 \uc81c\uacf5\ud558\ub294 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud588\ub2e4. \\n\\n### JdbcTemplate\\n\\nJdbcTemplate\uc740 Connection\uc744 \uc774\uc6a9\ud558\uc5ec PreparedStatement\ub97c \uc0dd\uc131\ud558\ub294 \ubd80\ubd84, \uadf8\ub9ac\uace0 PreparedStatement\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ubd84\ub9ac\ud588\ub2e4. \\n\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc801\uc808\ud558\uac8c \uc801\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \ube44\uad50\uc801 \uac04\ub2e8\ud558\uac8c \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\uc608\uc804\uc5d0\ub3c4 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c [JdbcTemplate\uc744 \uad6c\ud604](./custom-jdbc-template)\ud55c \uc801\uc774 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \uc790\uc6d0 \ud560\ub2f9\uacfc \ud574\uc81c \ubd80\ubd84\uc5d0 \ub300\ud55c \uc911\ubcf5\ub3c4 \uc81c\uac70\ud588\ub2e4. \\n\\n```java\\npublic class JdbcTemplate {\\n\\n private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);\\n\\n private final DataSource dataSource;\\n private final StatementCreator statementCreator;\\n private final StatementExecutor statementExecutor;\\n\\n public JdbcTemplate(final DataSource dataSource) {\\n this(dataSource, new StatementCreator(), new StatementExecutor());\\n }\\n\\n JdbcTemplate(\\n final DataSource dataSource,\\n final StatementCreator statementCreator,\\n final StatementExecutor statementExecutor\\n ) {\\n this.dataSource = dataSource;\\n this.statementCreator = statementCreator;\\n this.statementExecutor = statementExecutor;\\n }\\n\\n private <T> T query(\\n final String sql,\\n final PreparedStatementCallback<T> preparedStatementCallback,\\n final Object... parameters\\n ) {\\n final Connection connection = DataSourceUtils.getConnection(dataSource);\\n try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {\\n return preparedStatementCallback.execute(preparedStatement);\\n } catch (final SQLException e) {\\n log.error(e.getMessage(), e);\\n throw new DataAccessException(e);\\n } finally {\\n DataSourceUtils.releaseConnection(connection, dataSource);\\n }\\n }\\n\\n public void update(final String sql, final Object... parameters) {\\n query(sql, PreparedStatement::executeUpdate, parameters);\\n }\\n\\n public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\\n final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\\n if (results.size() > 1) {\\n throw new DataAccessException(\\"2\uac1c \uc774\uc0c1\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\\");\\n }\\n return results.stream().findAny();\\n }\\n\\n public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\\n return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\\n }\\n}\\n```\\n\\n### \ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9\\n\\n3, 4\ub2e8\uacc4\ub294 \uae30\uc874\uc758 \ucf54\ub4dc\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uace0 \ub05d\ub098\ub294 \ubd80\ubd84\uc778 \ud2b8\ub79c\uc7ad\uc158 \uacbd\uacc4\ub97c \uc124\uc815\ud558\uace0 ThreadLocal\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654(Transaction synchronization)\ub97c \uc801\uc6a9\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654\ub780 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uae30 \uc704\ud55c Connection \uac1d\uccb4\ub97c ThreadLocal\uacfc \uac19\uc740 \uacf5\uac04\uc5d0 \ub530\ub85c \uc800\uc7a5 \ud6c4, \ud544\uc694\ud560 \ub54c \uc800\uc7a5\ub41c Connection\uc744 \uac00\uc838\ub2e4 \uc0ac\uc6a9\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4. \\n\uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub294\ub370, ThreadLocal\uc5d0 Connection \uac1d\uccb4\uac00 \uc544\ub2cc, Connection \uac1d\uccb4\uc640 Transaction\uc774 \uc9c4\ud589 \uc911\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 flag\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \uc800\uc7a5\ud574\uc11c \uc0ac\uc6a9\ud558\ub3c4\ub85d \ud588\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tTransactionTemplate --\x3e TransactionManager\\n\\tTransactionManager --\x3e TransactionSynchronizationManager\\n\\tDataSourceUtils --\x3e TransactionSynchronizationManager\\n\\tJdbcTemplate --\x3e DataSourceUtils\\n```\\n\\n### \ub9c8\ubb34\ub9ac\\n\\nJdbc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c AOP\ub098 Transactional\uc5d0 \ub300\ud55c \ud559\uc2b5 \ud14c\uc2a4\ud2b8\ub3c4 \uc9c4\ud589\ud558\uace0, \uc57d\uac04 \uc54c\ucc2c \ubbf8\uc158\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\uaf3c\uaf3c\ud788 \ucf54\ub4dc\ub97c \ubd10\uc900 \ub9ac\ubdf0\uc5b4 \ud638\uc774 \uadf8\ub9ac\uace0 \uc5f0\ud734 \ub3d9\uc548 \uacc4\uc18d \ud2f0\ud0a4\ud0c0\uce74 \ud558\uba74\uc11c \uc7ac\ubc0c\uac8c \ub9ac\ubdf0\ud55c \ubbfc\ud2b8\uc5d0\uac8c \uac10\uc0ac\ud558\ub2e4. \\n\ud68c\uace0 \uc774\ub9cc \ub05d\ub0b4\uace0 \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud558\ub7ec\uac00\uc57c\uaca0\ub2e4. \ud83d\ude0a"},{"id":"mvc-retrospective","metadata":{"permalink":"/mvc-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-mvc/pull/404","date":"2023-10-07T00:00:00.000Z","formattedDate":"2023\ub144 10\uc6d4 7\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":5.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","slug":"mvc-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/jdbc-retrospective"},"nextItem":{"title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","permalink":"/spring-test-isolation"}},"content":":::note PR \ub9c1\ud06c\\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-mvc/pull/404 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-mvc/pull/465 \\n3\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-mvc/pull/580 \\n:::\\n\\n### MVC \uad6c\ud604\\n\\nReflection\uc744 \uc774\uc6a9\ud558\uc5ec Spring MVC\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\ubbf8\uc158\uc758 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\uc558\ub2e4.\\n\\n- MVC \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uad6c\ud604\ud558\uba74\uc11c \ub0b4\ubd80 \ub3d9\uc791 \uc6d0\ub9ac\ub97c \ud559\uc2b5\ud55c\ub2e4.\\n- \uc810\uc9c4\uc801\uc778 \ub9ac\ud329\ud1a0\ub9c1\uc744 \uacbd\ud5d8\ud55c\ub2e4.\\n\\n\ubbf8\uc158\uc758 \ubaa9\ud45c\uc640 \ub354\ubd88\uc5b4 \uac01 \ud074\ub798\uc2a4\ub4e4\uc774 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \uc801\uc808\ud788 \uac00\uc9c0\ub3c4\ub85d \ud558\uace0, \ud328\ud0a4\uc9c0\uc758 \uc758\uc874 \ubc29\ud5a5\uc744 \uace0\ubbfc\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac83\uc5d0 \uc911\uc810\uc744 \ub450\uc5c8\ub2e4. \\n\\n### \uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18 \ud504\ub808\uc784\uc6cc\ud06c \ub9cc\ub4e4\uae30\\n\\n\uae30\uc874 \ucf54\ub4dc\uc5d0 ManualHandlerMapping\uc774\ub77c\ub294 \uc11c\ube14\ub9bf\uc744 \uc9c1\uc811 \ub4f1\ub85d\ud574\uc11c \uc0ac\uc6a9\ud558\ub294 HandlerMapping \ud074\ub798\uc2a4\uac00 \uc788\uc5c8\uace0, 1\ub2e8\uacc4\uc5d0\uc11c\ub294 \uc560\ub108\ud14c\uc774\uc158 \uae30\ubc18\uc758 AnnotationHandlerMapping\uc744 \uad6c\ud604\ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 @Controller, @RequestMapping\uc744 Reflection\uc744 \uc774\uc6a9\ud558\uc5ec \uc2a4\uce94\ud558\uace0, \ud578\ub4e4\ub7ec \ub9e4\ud551\uc744 \ub4f1\ub85d\ud558\ub294 \ubd80\ubd84\uae4c\uc9c0 \uc9c4\ud589\ud574\uc57c \ud588\ub2e4. \\n\ud14c\uc624\uac00 @GetMapping\uc774\ub098 @PostMapping \ubd80\ubd84\ub3c4 \uc9c4\ud589\ud558\uba74 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4\uace0 \ud574\uc11c \uac19\uc774 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4. \\n\ucd94\uac00\ub85c \ubbf8\uc158 \uc694\uad6c\uc0ac\ud56d\uc740 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ud074\ub798\uc2a4 \ub808\ubca8\uc5d0 \uc801\uc6a9\ub41c @RequestMapping\ub3c4 \ub3d9\uc791\ud558\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\uc558\ub2e4. \\n\\n```mermaid\\ngraph LR\\n AHM[AnnotationHandlerMapping] --\x3e AS[AnnotationScanner]\\n\\tAHM --\x3e HKG[HandlerKeyGenerator] --\x3e HMAP[HttpMappingAnnotationParser]\\n```\\n\\n\ub2e4\uc74c\uacfc \uac19\uc740 Flow\ub85c Handler(\uc2e4\uc81c \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uba54\uc11c\ub4dc) \ub4f1\ub85d\uc744 \uc9c4\ud589\ud55c\ub2e4. \\n\\n1. @Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 \uc815\ubcf4\ub97c \uc2a4\uce94\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4. \\n2. @Controller\uac00 \uc801\uc6a9\ub41c \ud074\ub798\uc2a4\uc758 @RequestMapping\uc774 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\ub4e4\uc758 \uc815\ubcf4\ub97c \ubc18\ud658\ud55c\ub2e4. \\n3. \uac01 \uba54\uc11c\ub4dc\ub4e4\uc744 \uc21c\ud68c\ud558\uba70 HandlerKey(uri + httpMethod \uc815\ubcf4)\uc640 HandlerExecution(\uc778\uc2a4\ud134\uc2a4 + \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc)\uc744 \uc0dd\uc131\ud558\uc5ec `Map<HandlerKey, HandlerExecution>`\uc5d0 \ucd94\uac00\ud55c\ub2e4. \\n\\nAnnotationHandlerMapping\uc758 initialize \uba54\uc11c\ub4dc\uc5d0\uc11c Handler\ub97c \ub4f1\ub85d\ud55c\ub2e4. \ucf54\ub4dc\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n```java title=AnnotationHandlerMapping\\npublic void initialize() {\\n if (!initialized.compareAndSet(false, true)) {\\n return;\\n }\\n\\n final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();\\n final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());\\n for (final Method method : methods) {\\n final ControllerInstance controller = controllers.get(method.getDeclaringClass());\\n final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);\\n final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);\\n handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));\\n }\\n\\n log.info(\\"Initialized AnnotationHandlerMapping!\\");\\n handlerExecutions.keySet().forEach(key -> log.info(\\"key: {}, Handler: {}\\", key, handlerExecutions.get(key)));\\n}\\n```\\n\\n### Legacy MVC\uc640 @MVC \ud1b5\ud569\\n\\n2\ub2e8\uacc4\ub294 Legacy MVC\uc640 AnnotationHandlerMapping\uc744 \ud1b5\ud569\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4. \\n\uae30\uc874\uc758 MVC\uc640 \uc560\ub108\ud14c\uc774\uc158\uc774 \uc801\uc6a9\ub41c MVC \ub450 \uac1c\ub97c \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5b4\uc57c \ud5c0\ub2e4. \\n\ub300\ub7b5\uc801\uc778 \ud750\ub984\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n1. DispatcherServlet.service(request, response) \ud638\ucd9c\\n2. HandlerMappings\ub97c \ud1b5\ud574 \uc785\ub825\ubc1b\uc740 request\uc5d0 \ud574\ub2f9\ud558\ub294 Handler \uc870\ud68c\\n3. HandlerAdapters\ub97c \ud1b5\ud574 Handler\ub97c \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub294 HandlerAdapter \uc870\ud68c\\n4. HandlerAdapter\uc758.handle \uba54\uc11c\ub4dc \uc2e4\ud589\\n5. View\uc758 render \ud638\ucd9c\\n\\n```mermaid\\ngraph LR\\n D[DispatcherServlet]\\n D --\x3e HMS[HandlerMappings]\\n D --\x3e HAS[HandlerAdapters]\\n\\n\\tHMS --\x3e HandlerMapping\\n\\tsubgraph HandlerMapping\\n\\t\\tdirection BT\\n\\t\\tAHM[AnnotationHandlerMapping] --\x3e HM[HandlerMapping]\\n\\t\\tMHM[ManualHandlerMapping] --\x3e HM\\n\\tend\\n\\n\\tHAS --\x3e HandlerAdapter\\n\\tsubgraph HandlerAdapter\\n\\t\\tdirection BT\\n\\t\\tHEHA[HandlerExecutionHandlerAdapter] --\x3e HA[HandlerAdapter]\\n\\t\\tCHA[ControllerHandlerAdapter] --\x3e HA\\n\\tend\\n```\\n\\n### \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815\\n\\n\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4. \\n\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4.\\n\\n```mermaid\\ngraph LR\\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking\\n```\\n\\n\ub0b4\uc6a9\uc774 \uae38\uc5b4\uc838\uc11c [\ub2e4\uc74c \ubb38\uc11c](./web-application-evolution)\uc5d0 \uc815\ub9ac\ud588\ub2e4.\\n\\n### \ucd94\uc0c1\uc801\uc778 \uac1c\ub150 \ud559\uc2b5 \ubc29\ubc95\\n\\n\uc9c1\uad00\uc801\uc774\uc9c0 \uc54a\uc740 \ucd94\uc0c1\uc801\uc778 \uac1c\ub150\uc744 \ud559\uc2b5\ud560 \ub54c\ub294 \uac1c\ub150\uc758 \uad6c\ud604\uc744 \ucc38\uace0\ud558\uba74 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \ud55c\ub2e4.\\n\\n| \uac1c\ub150 | \uad6c\ud604 |\\n| ---- | ------------------------------------------------ |\\n| OOP | Java |\\n| WAS | Tomcat, Jetty |\\n| IoC | Spring BeanFactory, Servlet Container, Framework |\\n| DI | Spring BeanFactory |\\n\\n### \uc815\ub9ac\\n\\n\uc9c0\uae08\uae4c\uc9c0 \uc2a4\ud504\ub9c1\uc758 DispatcherServlet\uc758 \ub3d9\uc791\uc744 \uc774\ub860\uc801\uc73c\ub85c\ub9cc \uc54c\uace0 \uc788\uc5c8\ub294\ub370, \uc2e4\uc81c\ub85c \uad6c\ud604\ud574 \ubcf4\ub2c8 \uc870\uae08 \ub354 \uc774\ud574\uac00 \uc798 \uac00\ub294 \uac83 \uac19\ub2e4. \\n\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c \ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub8e8\uce74, \ub9ac\ubdf0\uc774\ub294 \ud5e4\ub098\uc600\ub2e4. \\n\ub9e4 \ub2e8\uacc4\ub9c8\ub2e4 \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0\ud574 \uc900 \ub8e8\uce74\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\uace0, \ud5e4\ub098\uc5d0\uac8c \uc774\uc0c1\ud55c \ub9ac\ubdf0\ub97c \ub9ce\uc774 \ub0a8\uae34 \uac83 \uac19\uc740\ub370 \uaf3c\uaf3c\ud788 \ubc18\uc601\ud574\uc918\uc11c \uac10\uc0ac\ud558\ub2e4. \\n\uc624\ub7ab\ub3d9\uc548 \uae30\ub2e4\ub824\uc654\ub358 \ub808\ubca8 4 \ubbf8\uc158\uc774 \ud558\ub098\uc529 \ub9c8\ubb34\ub9ac \ub420 \ub54c \ub9c8\ub2e4 \uc544\uc26c\uc6c0\uc774 \ub0a8\ub294\ub2e4."},{"id":"spring-test-isolation","metadata":{"permalink":"/spring-test-isolation","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md","source":"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md","title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","description":"\ud14c\uc2a4\ud2b8 \uaca9\ub9ac","date":"2023-10-03T00:00:00.000Z","formattedDate":"2023\ub144 10\uc6d4 3\uc77c","tags":[{"label":"test","permalink":"/tags/test"}],"readingTime":4.315,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","slug":"spring-test-isolation","tags":["test"]},"unlisted":false,"prevItem":{"title":"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/mvc-retrospective"},"nextItem":{"title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","permalink":"/web-application-evolution"}},"content":"### \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\\n\\n\ud14c\uc2a4\ud2b8\uc758 \uc21c\uc11c\uc5d0 \ub530\ub77c \uc131\uacf5 \uc2e4\ud328 \uc5ec\ubd80\uac00 \uacb0\uc815\ub418\ub294 \ube44\uacb0\uc815\uc801\uc778(non-determinism) \ud14c\uc2a4\ud2b8\uac00 \ub418\uc5b4\uc11c\ub294 \uc548\ub418\uace0, \ud14c\uc2a4\ud2b8\ub294 \ud56d\uc0c1 \uc21c\uc11c\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc218\ud589\ub418\ub3c4\ub85d \ubcf4\uc7a5\ub418\uc5b4\uc57c \ud55c\ub2e4. \uc77c\ubc18\uc801\uc73c\ub85c \uc790\uc6d0\uc758 \uacf5\uc720, \uc678\ubd80 API, \uc2dc\uac04 \ub4f1\uc73c\ub85c \ube44\uacb0\uc815\uc801\uc778 \ud14c\uc2a4\ud2b8\uac00 \ub41c\ub2e4. \uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \uc0ac\uc6a9\ud558\uac70\ub098, \ucee8\ud14d\uc2a4\ud2b8\ub97c \uc7ac\uc2e4\ud589\ud558\ub294 `@DirtiesContext`, \uc790\uc6d0\uc744 \ucd08\uae30\ud654\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uc774\ud6c4\uc5d0 \ud14c\uc774\ube14\uc744 \ub864\ubc31 \ud558\ub294 `@Transactional`\ub4f1 \ub2e4\uc591\ud55c \ubc29\ubc95\uc774 \uc788\ub2e4. \\n\ud574\ub2f9 \uae00\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc5d0\uc11c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc790\uc6d0\uc758 \uacf5\uc720\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud574 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ub97c \uc218\ud589\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc124\uba85\ud55c\ub2e4. \\n\\n:::note Independent - FIRST\\n\\n\ud14c\uc2a4\ud2b8\ub07c\ub9ac \uc11c\ub85c \uc758\uc874\ud558\uba74 \uc548 \ub41c\ub2e4. \\n\uc11c\ub85c \uc758\uc874\ud558\uac8c \ub41c\ub2e4\uba74 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \ub54c, \ub610 \ub2e4\ub978 \ud558\ub098\uc758 \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud328\ud560 \uc218 \uc788\ub2e4. \\n\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc5d0 \uc758\uc874\ud558\uc9c0 \uc54a\uace0, \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589 \uac00\ub2a5\ud55c \ud14c\uc2a4\ud2b8\uac00 \uc88b\uc740 \ud14c\uc2a4\ud2b8\ub2e4. \\n\\n:::\\n\\n### TestExecutionListener\\n\\n\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 TextExecutionListner\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 \ud14c\uc2a4\ud2b8 \uc2e4\ud589 \ub2e8\uacc4\uc5d0\uc11c \uc774\ubca4\ud2b8\ub97c \uc218\uc2e0\ud560 \uc218 \uc788\ub2e4. \\n\uc774\ub97c \uc774\uc6a9\ud558\uba74 JUnit\uc758 @BeforeEach\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uacfc \uc720\uc0ac\ud558\uac8c, \ud14c\uc2a4\ud2b8\uc758 \uc0dd\uba85\uc8fc\uae30 \uc774\uc804 \ub610\ub294 \uc774\ud6c4\uc5d0 \ud544\uc694\ud55c \uc791\uc5c5\uc744 \uc2e4\ud589\uc2dc\ud0ac \uc218 \uc788\ub2e4. \\n\\n```java title=TextExecutionListner\\npublic interface TestExecutionListener {\\n default void beforeTestClass(TestContext testContext) throws Exception {}\\n default void prepareTestInstance(TestContext testContext) throws Exception {}\\n default void beforeTestMethod(TestContext testContext) throws Exception {}\\n default void beforeTestExecution(TestContext testContext) throws Exception {}\\n default void afterTestExecution(TestContext testContext) throws Exception {}\\n default void afterTestMethod(TestContext testContext) throws Exception {}\\n default void afterTestClass(TestContext testContext) throws Exception {}\\n}\\n```\\n\\n### AbstractTestExecutionListener \uc0c1\uc18d\ud558\uc5ec \uad6c\ud604\\n\\nAbstractTestExecutionListener\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac \ud658\uacbd\uc744 \ub9cc\ub4e4\uc5b4\uc8fc\ub294 \ud074\ub798\uc2a4\ub85c, \uc778\ud130\ud398\uc774\uc2a4\uc778 TextExecutionListner\uc640 \ub2ec\ub9ac Ordered\uac00 \uad6c\ud604\ub418\uc5b4 \uc788\uc5b4 \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ubc1b\uc544 \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub294 \ud504\ub808\uc784\uc6cc\ud06c\uac00 \uc81c\uacf5\ud558\ub294 \ub9ac\uc2a4\ub108 \ub2e4\uc74c\uc5d0 \uc2e4\ud589\uc2dc\ud0a4\ub3c4\ub85d \ud574\uc900\ub2e4. \\n\ub2e4\uc74c\uacfc \uac19\uc774 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac01\uac01\uc758 \ud14c\uc774\ube14\uc5d0 \ud574\ub2f9\ud558\ub294 Truncate \ucffc\ub9ac\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc870\ud68c\ud558\uace0, Test \uba54\uc11c\ub4dc\uac00 \ub05d\ub0a0\ub54c \ub9c8\ub2e4 \ud574\ub2f9 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uc5ec \ud14c\uc774\ube14\uc744 \ucd08\uae30\ud654\uc2dc\ud0a4\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. \\n\\n```java title=DatabaseCleaner\\n\\npublic class DatabaseCleaner extends AbstractTestExecutionListener {\\n\\n private static final String TRUNCATE_TABLE_QUERY = \\"\\"\\"\\n SELECT Concat(\'TRUNCATE TABLE \', TABLE_NAME, \';\') \\n FROM INFORMATION_SCHEMA.TABLES\\n WHERE TABLE_SCHEMA = \'PUBLIC\'\\n \\"\\"\\";\\n\\n @Override\\n public void afterTestMethod(TestContext testContext) {\\n JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);\\n List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);\\n truncateTables(jdbcTemplate, truncateTableQueries);\\n }\\n\\n private JdbcTemplate getJdbcTemplate(TestContext testContext) {\\n return testContext.getApplicationContext().getBean(JdbcTemplate.class);\\n }\\n\\n private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {\\n return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);\\n }\\n\\n private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {\\n jdbcTemplate.execute(\\"SET REFERENTIAL_INTEGRITY FALSE\\");\\n truncateTableQueries.forEach(jdbcTemplate::execute);\\n jdbcTemplate.execute(\\"SET REFERENTIAL_INTEGRITY TRUE\\");\\n }\\n}\\n\\n```\\n\\n### Listener \ub4f1\ub85d\\n\\n@TestExecutionListeners\ub97c \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790 \uc815\uc758 \ub9ac\uc2a4\ub108\ub97c \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4. \\nmergeMode\uc758 \uae30\ubcf8\uac12\uc740 REPLACE_DEFAULTS\ub85c \ub9ac\uc2a4\ub108\uac00 \uc774\ubbf8 \uc874\uc7ac\ud558\ub294 \uacbd\uc6b0 \ub4f1\ub85d\ub41c \ub9ac\uc2a4\ub108\ub85c \ubcc0\uacbd\ub41c\ub2e4. \\nMERGE_WITH_DEFAULTS\ub85c \uc124\uc815\ud55c\ub2e4\uba74 Ordered \uae30\uc900\uc73c\ub85c \uc21c\uc11c\uac00 \uacb0\uc815\ub41c\ub2e4. \\n\uc774\ud6c4 \uaca9\ub9ac\uac00 \ud544\uc694\ud55c \ud14c\uc2a4\ud2b8\ub4e4\uc740 \ub2e4\uc74c\uc758 \ucd94\uc0c1 \ud074\ub798\uc2a4\ub97c \uc0c1\uc18d\ud558\uc5ec \uc0ac\uc6a9\ud558\uba74 \ub41c\ub2e4. \\n\\n```java title=AcceptanceTest\\n\\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\\n@TestExecutionListeners(\\n value = DatabaseCleaner.class,\\n mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS\\n)\\npublic abstract class AcceptanceTest {\\n\\n @LocalServerPort\\n private int port;\\n\\n @BeforeEach\\n public void setUp() {\\n RestAssured.port = port;\\n }\\n}\\n\\n```\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[The Spring TestExecutionListener, Baeldung](https://www.baeldung.com/spring-testexecutionlistener) \\n[\uc778\uc218\ud14c\uc2a4\ud2b8\uc5d0\uc11c \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\ud558\uae30, \ud14c\ucf54\ube14](https://tecoble.techcourse.co.kr/post/2020-09-15-test-isolation/) \\n[Eradicating Non-Determinism in Tests, martin fowler](https://martinfowler.com/articles/nonDeterminism.html) \\n[@SpringBootTest\uc758 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac\uc2dc\ud0a4\uae30, MangKyu](https://mangkyu.tistory.com/264)"},{"id":"web-application-evolution","metadata":{"permalink":"/web-application-evolution","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx","source":"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx","title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","description":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","date":"2023-09-30T00:00:00.000Z","formattedDate":"2023\ub144 9\uc6d4 30\uc77c","tags":[{"label":"web application","permalink":"/tags/web-application"}],"readingTime":7.5,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","slug":"web-application-evolution","tags":["web application"]},"unlisted":false,"prevItem":{"title":"\uc2a4\ud504\ub9c1 \ud14c\uc2a4\ud2b8 \uaca9\ub9ac","permalink":"/spring-test-isolation"},"nextItem":{"title":"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45","permalink":"/log-async-exception"}},"content":"### \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815\\n\\n\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815 \ub300\ud55c \uad6c\uad6c\uc758 \uac15\uc758\uac00 \uc788\uc5c8\ub2e4. \\n\uac04\ub2e8\ud558\uac8c \uc815\ub9ac\ud558\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ud750\ub984\uc73c\ub85c \uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \ubc1c\uc804\ud588\ub2e4. \\n\uc6d0\ub798 \ud68c\uace0\uc5d0 \uc791\uc131\ud558\ub824\uace0 \ud588\uc9c0\ub9cc, \uc815\ub9ac\ud558\ub2e4 \ubcf4\ub2c8 \uc870\uae08 \uae38\uc5b4\uc838\uc11c \ub530\ub85c \ubd84\ub9ac\ud588\ub2e4. \\n\\n```mermaid\\ngraph LR\\n WWW --\x3e CGI(Common Gateway Interface) --\x3e Servlet --\x3e JSP --\x3e MVC --\x3e Framework --\x3e Non-Blocking\\n```\\n\\n### WWW(1989)\\n\\n\uc815\uc801 \ud398\uc774\uc9c0\ub97c \uc81c\uacf5\ud558\ub294 \uc6f9 \uc11c\ubc84\ub97c \uc2dc\uc791\uc73c\ub85c \ub3d9\uc801 \ud398\uc774\uc9c0\uac00 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 CGI\uac00 \ub4f1\uc7a5\ud588\ub2e4. \\n\\n### CGI(1993) \\n\\nCGI\ub294 \ub3d9\uc801 \ucf58\ud150\uce20\ub97c \uc81c\uacf5\ud558\uae30 \uc704\ud55c \uaddc\uc57d\uc73c\ub85c, \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc774\uc6a9\ud574\uc11c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ucf1c \uc815\ubcf4\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\ub97c \uc2e4\ud589\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ub9ce\uc740 \ubd80\ud558\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc774\ub7ec\ud55c \ub2e8\uc810\uc744 \uadf9\ubcf5\ud558\uae30 \uc704\ud574 \ub098\uc628 \uac83\uc774 Servlet\uc774\ub2e4. \\n\\n### Servlet(1996)\\n\\nServlet\uc740 \uc6f9 \uc11c\ubc84\uc5d0\uc11c \uc2e4\ud589\ub418\ub294 \uc790\ubc14 \ud504\ub85c\uadf8\ub7a8\uc73c\ub85c HTTP\ub97c \uc774\uc6a9\ud558\uc5ec \uc6f9 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc744 \uc218\uc2e0\ud558\uace0 \uc751\ub2f5\ud55c\ub2e4. CGI\uc640 \ub2e4\ub974\uac8c \ub9e4 \uc694\uccad\ub9c8\ub2e4 \ud504\ub85c\uc138\uc2a4\uac00 \uc544\ub2cc \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uc5ec \uc751\ub2f5\ud55c\ub2e4. \\n\ud558\uc9c0\ub9cc View \uc601\uc5ed\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uae30 \uc704\ud574 Servlet\uc758 \uc18c\uc2a4 \ucf54\ub4dc\ub97c \uc54c\uc544\uc57c \ud558\ub294 \ub4f1 \ubcf5\uc7a1\ub3c4\uac00 \ub108\ubb34 \ub192\uc558\ub2e4. \ub530\ub77c\uc11c \ud574\ub2f9 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 JSP\uac00 \ub4f1\uc7a5\ud588\ub2e4. \\n\\n### JSP(1999)\\n\\nJSP\ub294 HTML\uc5d0 \uc790\ubc14 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \ub3d9\uc801 \uc6f9 \ud398\uc774\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\uc220\ub85c, \uc720\uc0ac\ud55c \uae30\uc220\ub85c\ub294 ASP, PHP\uac00 \uc788\ub2e4. \\nJSP\ub9cc \uc0ac\uc6a9\ud558\uc5ec \ud504\ub85c\uadf8\ub798\ubc0d\ud55c\ub2e4\uba74 Model 1, \uc544\ub798 \uad6c\uc131\ub3c4\uc640 \uac19\uc774 JSP\uac00 View \uc601\uc5ed\ub9cc \ub2f4\ub2f9\ud55c\ub2e4\uba74 Model 2\ub77c\uace0 \ud55c\ub2e4. \\n\\n```mermaid\\n---\\ntitle: JSP Model 2\\n---\\ngraph LR\\n Client -- Request --\x3e Servlet <-- JDBC --\x3e Database\\n\\tServlet --\x3e Bean\\n\\tServlet --\x3e JSP\\n\\tBean <--\x3e JSP\\n\\tJSP -- Response --\x3e Client\\n```\\n\\n### MVC(2000)\\n\\n\uc704 JSP\uc758 \uad6c\uc131\ub3c4\ub97c \ubcf4\uba74 \ud604\uc7ac MVC\uc640 \ub9e4\uc6b0 \uc720\uc0ac\ud55c\ub370, Govind Seshadri\ub77c\ub294 \uc0ac\ub78c\uc774 JSP Model 2\ub97c MVC \ud328\ud134\uc73c\ub85c \uacf5\uc2dd\ud654\ub97c \uc81c\uc548\ud588\ub2e4. \\n\\n> I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern. \\n> Govind Seshadri\\n\\n\uc774\ub54c MVC \ud328\ud134\uc774 \ucc98\uc74c \ud0c4\uc0dd\ud55c \uac83\uc740 \uc544\ub2c8\uace0, \uc11c\ubc84 \uce21 \uad6c\ud604\uc774\ub77c\uace0 \ud558\ub294 \uac83\uc744 \ubcf4\ub2c8 MVC\uac00 \ucc98\uc74c \ub4f1\uc7a5\ud55c \uac74 \uc544\ub2cc \uac83 \uac19\ub2e4. \\n[\ud574\ub2f9 \ubb38\uc11c](https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html)\ub97c \ubcf4\uba74 MVC\ub77c\ub294 \uc6a9\uc5b4\uc758 \ub4f1\uc7a5\uc740 1978\ub144\uc5d0 \ub4f1\uc7a5\ud55c \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4. \\n\\n### Spring Framework(2003)\\n\\nSpring\uc740 \ubcf5\uc7a1\ud588\ub358 J2EE\uc744 \ub300\uccb4\ud558\uae30 \uc704\ud574 2003\ub144\uc5d0 \ub4f1\uc7a5\ud588\ub2e4. \\nJ2EE\ub294 \uc6f9 \uae30\ubc18\uc758 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\uae30 \uc704\ud55c \ud50c\ub7ab\ud3fc\uc73c\ub85c \uc704\uc5d0\uc11c \uc124\uba85\ud55c Servlet, JSP, EJB \ub4f1\uc758 \uae30\uc220\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub2e4. \\n\ud558\uc9c0\ub9cc \uc774\uc911 EJB\ub77c\ub294 \uae30\uc220\uc774 J2EE\uc758 \ud575\uc2ec \uae30\uc220\uc774\uc5c8\ub294\ub370, \ud574\ub2f9 \uae30\uc220\uc774 \ub9e4\uc6b0 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub9ce\uc558\ub2e4\uace0 \ud55c\ub2e4. \\n2002\ub144\uc5d0 Rod Johnson\uc774 EJB\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 J2EE \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uad6c\ucd95\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc800\uc220\ud55c `Expert One-to-One J2EE Development`\ub77c\ub294 \ucc45\uc744 \ubc1c\ud589\ud588\uace0, \ucd9c\uac04 \ud6c4 Juergen Hoeller, Yann Caroff\uac00 Rod Johnson\uc5d0\uac8c \uc624\ud508\uc18c\uc2a4 \uc81c\uc548\uc744 \ud558\uc5ec \uc2a4\ud504\ub9c1\uc774 \ud0c4\uc0dd\ud588\ub2e4\uace0 \ud55c\ub2e4. \\n\\n\uc2a4\ud504\ub9c1\uc740 \uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\uba70, \uc774 \ub355\ubd84\uc5d0 \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc788\ub2e4. \\n\\n### WebFlux \uc774\uc804 Servlet 3.0(2009), 3.1(2013)\\n\\nTomcat\uc758 NIO \ub3d9\uc791 \ubc29\uc2dd\uc744 \ubcf4\uba74 Poller\uac00 \uc18c\ucf13 \ucee4\ub125\uc158\uc744 \ub4e4\uace0 \uc788\ub2e4\uac00 \ucc98\ub9ac\uac00 \uac00\ub2a5\ud560 \ub54c \uc2a4\ub808\ub4dc\ub97c \ud560\ub2f9\ud558\ub294 \uc2dd\uc73c\ub85c \ucc98\ub9ac\ub97c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \ud560\ub2f9 \ud6c4 Servlet\uacfc \ud1b5\uc2e0\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \uc694\uccad\uc774 \ub05d\ub0a0 \ub54c\uae4c\uc9c0 \uc2a4\ub808\ub4dc\ub97c \uc810\uc720\ud558\uace0 \uc788\uc5c8\uace0, \uc2a4\ub808\ub4dc \uc810\uc720\ub85c \uc778\ud574 \uc694\uccad\uc774 max thread\uc5d0 \ub3c4\ub2ec\ud558\uba74 \uc694\uccad\uc744 \ucc98\ub9ac\ud560 \uc218 \uc5c6\uc5c8\ub2e4. \\n\uadf8\ub798\uc11c \ube44\ub3d9\uae30 \ubc29\uc2dd\uc758 Servlet\uc774 Servlet 3.0\uc5d0 \ub4f1\uc7a5\ud588\ub2e4. \ud558\uc9c0\ub9cc \uc804\ud1b5\uc801\uc778 I/O \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc740 \ube14\ub85c\ud0b9 \ubc29\uc2dd\uc73c\ub85c \ub3d9\uc791\ud588\ub2e4. Servlet 3.1\uc5d0\uc11c \ub17c\ube14\ub85c\ud0b9 I/O\uac00 \ucd94\uac00\ub418\uc5c8\uc9c0\ub9cc, \ub9ce\uc774 \uc0ac\uc6a9\ub418\uc9c0 \uc54a\uc558\ub2e4\uace0 \ud55c\ub2e4. \\n\\n### Spring WebFlux(2017)\\n\\n\uc801\uc740 \uc218\uc758 \uc2a4\ub808\ub4dc\ub85c \ub3d9\uc2dc\uc131\uc744 \ucc98\ub9ac\ud558\uace0, \uc801\uc740 \ub9ac\uc18c\uc2a4\ub85c \ud655\uc7a5\uc774 \uac00\ub2a5\ud55c \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd\uc758 \uc6f9 \uae30\uc220\uc774 \ud544\uc694\ud588\uace0, \uae30\uc874\uc758 Servlet\uc758 \uacbd\uc6b0 \ube44\ub3d9\uae30\ub97c \uc9c0\uc6d0\ud55c\ub2e4 \ud574\ub3c4 \ub3d9\uae30\uc2dd API\ub4e4\uc774 \ub9ce\uc774 \ub0a8\uc544\uc788\uc5c8\uae30 \ub54c\ubb38\uc5d0 \uc774\ub7ec\ud55c Servlet\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294 \uae30\uc220\uc774 \ud544\uc694\ud588\ub2e4. \ub610\ud55c \uae30\uc874\uc5d0 Netty\uc640 \uac19\uc774 \ube44\ub3d9\uae30, \ub17c\ube14\ub85c\ud0b9 \ubc29\uc2dd \uc11c\ubc84\ub85c \uc790\ub9ac\ub97c \uc798 \uc7a1\uc740 \uc11c\ubc84\ub97c \uc704\ud574 Spring WebFlux\uac00 \ub4f1\uc7a5\ud588\ub2e4. \\n\ucd94\uac00\ub85c \ub370\uc774\ud130 \uc811\uadfc\uc744 \uc704\ud574 \uc0ac\uc6a9\ud558\ub294 JDBC\uc758 \uacbd\uc6b0 Blocking API\ub77c, Spring Webflux\uc5d0\uc11c\ub294 R2DBC\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uace0 \ud55c\ub2e4. \\n\\n### \ub9c8\uce58\uba70\\n\\n\ud574\ub2f9 \uc815\ub9ac \ub0b4\uc6a9\uc758 \uacbd\uc6b0 Async, Non Blocking \uad00\ub828\ub41c \ub0b4\uc6a9\uc744 \uae4a\uac8c \uacf5\ubd80\ud55c \uc801\uc774 \uc5c6\uc5b4\uc11c \uc815\ud655\ud558\uc9c0 \uc54a\uc744 \uc218 \uc788\ub2e4. \\n\uadf8\ub798\ub3c4 \uae30\uc220\uc758 \ub4f1\uc7a5 \ubc30\uacbd\uc774\ub098 \uacfc\uc815\uc744 \uc54c\uace0 \uc788\ub2e4\uba74 \uc870\uae08 \ub354 \uae4a\uc774 \uc788\ub294 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0\uc774 \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ubc1c\uc804 \uacfc\uc815, \uad6c\uad6c \uac15\uc758 \\n[Dynamic Content with CGI, Apache Tutorial](https://httpd.apache.org/docs/trunk/en/howto/cgi.html) \\n[History of Spring and the Spring Framework, Spring](https://docs.spring.io/spring-framework/reference/overview.html#overview-history) \\n[Understanding JavaServer Pages Model 2 architecture, Govind Seshadri](https://www.infoworld.com/article/2076557/understanding-javaserver-pages-model-2-architecture.html) \\n[MVC, XEROX PARC](https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html) \\n[Expert One-to-One J2EE Development, Rod Johnson](https://www.amazon.com/Expert-One-One-Development-without/dp/0764558315) \\n[\ubc30\ub2ec\uc758\ubbfc\uc871 \ucd5c\uc804\ubc29 \uc2dc\uc2a4\ud15c! \u2018\uac00\uac8c\ub178\ucd9c \uc2dc\uc2a4\ud15c\u2019\uc744 \uc18c\uac1c\ud569\ub2c8\ub2e4, \ubc30\ub2ec\uc758\ubbfc\uc871](https://techblog.woowahan.com/2667/) \\n[Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu](https://www.infoworld.com/article/2077995/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html)\\n[WebFlux Overview, Spring](https://docs.spring.io/spring-framework/reference/web/webflux/new-framework.html)\\n[Spring WebFlux\uc640 Armeria\ub97c \uc774\uc6a9\ud558\uc5ec Microservice\uc5d0 \ud544\uc694\ud55c Reactive + RPC \ub3d9\uc2dc\uc5d0 \uc7a1\uae30, Naver D2](https://d2.naver.com/helloworld/6080222) \\n[Spring WebFlux\ub780 \ubb34\uc5c7\uc77c\uae4c](https://tweety1121.tistory.com/entry/Spring-WebFlux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C)"},{"id":"log-async-exception","metadata":{"permalink":"/log-async-exception","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx","source":"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx","title":"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45","description":"\ubb38\uc81c \uc0c1\ud669","date":"2023-09-18T00:00:00.000Z","formattedDate":"2023\ub144 9\uc6d4 18\uc77c","tags":[{"label":"async","permalink":"/tags/async"},{"label":"exception","permalink":"/tags/exception"}],"readingTime":3.615,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45","slug":"log-async-exception","tags":["async","exception"]},"unlisted":false,"prevItem":{"title":"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815","permalink":"/web-application-evolution"},"nextItem":{"title":"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/tomcat-retrospective"}},"content":"### \ubb38\uc81c \uc0c1\ud669\\n\\n\ud604\uc7ac \ud2b8\ub9bd\ub4dc\ub85c\uc6b0\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ub418\uace0 \uc788\ub2e4. \ub85c\uadf8\ub97c \ud655\uc778\ud558\ub294 \ub3c4\uc911 `@Async`\uac00 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ub85c\uadf8\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \ucd9c\ub825\ub418\uc9c0 \uc54a\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4. \\n\ud655\uc778\ud574 \ubcf4\ub2c8 Spring\uc758 `@ControllerAdvice` + `@ExceptionHandler`\uc758 \uacbd\uc6b0 \ub3d9\uae30 \uc608\uc678\ub9cc \ucc98\ub9ac\ud558\uace0, \ube44\ub3d9\uae30 \uc608\uc678\ub97c \ucc98\ub9ac\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \ubc1c\uc0dd\ud55c \ubb38\uc81c\uc600\ub2e4. \\n\\n### \ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815\\n\\n\uc2a4\ud504\ub9c1 4.1 \ubd80\ud130 \uc81c\uacf5\ub418\ub294 [AsyncUncaughtExceptionHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html)\uc758 \uacbd\uc6b0 \ubc18\ud658 \ud0c0\uc785\uc774 void\uc778 \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\ub97c \uc608\uc678 \ucc98\ub9ac\ud558\uae30 \uc27d\ub3c4\ub85d \ub3c4\uc640\uc900\ub2e4. \\n\\n\ub530\ub77c\uc11c AsyncUncaughtExceptionHandler \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud574\uc11c \uc608\uc678\ub97c \ud578\ub4e4\ub9c1\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud588\ub2e4. \\n\uae30\uc874\uc758 \ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \uc608\uc678\uac00 \ubc1c\uc0dd\ud560 \ub54c \uc2e4\ud589 \ud750\ub984\uc744 \ucd94\uc801\ud558\uae30 \uc704\ud574 MDC(Mapped Diagnostic Context)\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4. \\n\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\ub3c4 \ub9c8\ucc2c\uac00\uc9c0\ub85c MDC\uc758 \uc815\ubcf4\ub97c \uac00\uc838\uc640\uc11c \ub85c\uadf8\ub97c \ucd9c\ub825\ud558\ub3c4\ub85d \uc124\uc815\ud588\ub2e4. \\n\\n```java title=AsyncExceptionHandler\\n@Slf4j\\npublic class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {\\n\\n private static final String LOG_FORMAT = \\"[%s] %s\\";\\n\\n @Override\\n public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {\\n log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);\\n }\\n}\\n```\\n\\nAsyncExceptionHandler\uc758 \uacbd\uc6b0 AsyncConfigurer\ub97c \uad6c\ud604\ud55c Configuration \ud074\ub798\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4. \\ngetAsyncUncaughtExceptionHandler() \uba54\uc11c\ub4dc\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec AsyncExceptionHandler\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uba74 \ub41c\ub2e4. \\n\\n```java title=AsyncConfig\\n@EnableAsync\\n@Configuration\\npublic class AsyncConfig implements AsyncConfigurer {\\n\\n @Override\\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\\n return new AsyncExceptionHandler();\\n }\\n}\\n```\\n\\n\uc774\uc81c \ube44\ub3d9\uae30 \uc0c1\ud669\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 AsyncUncaughtExceptionHandler\uc758 \uad6c\ud604\uccb4\uc778 AsyncExceptionHandler\uac00 \uc608\uc678\ub97c \uc7a1\uc544 \ucc98\ub9ac\ud55c\ub2e4. \\n\\n### MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c\\n\\n\ube44\ub3d9\uae30 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \ubcc4\ub3c4\uc758 \uc2a4\ub808\ub4dc\uc5d0\uc11c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 ThreadLocal \uae30\ubc18\uc73c\ub85c \ub3d9\uc791\ud558\ub294 MDC\uc758 \uc815\ubcf4\ub97c \uc5bb\uc5b4\uc62c \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4. \\n\\n![./mdc-null.png](./mdc-null.png)\\n\\n\uc2a4\ud504\ub9c1 4.3 \uc774\uc0c1\ubd80\ud130 \uc81c\uacf5\ub418\ub294 [TaskDecorator](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html)\ub97c \uc774\uc6a9\ud558\uba74 TaskExecutor\ub97c \ucee4\uc2a4\ud130\ub9c8\uc774\uc9d5 \ud560 \uc218 \uc788\ub2e4. TaskDecorator\ub97c \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \ud558\ub098 \uc0dd\uc131\ud558\uace0, Task\uac00 \uc2e4\ud589\ub418\uae30 \uc804 MDC\uc758 \uc815\ubcf4\ub97c \ubcf5\uc0ac\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. \\n\\n```java title=MdcTaskDecorator\\npublic class MdcTaskDecorator implements TaskDecorator {\\n\\n @Override\\n public Runnable decorate(final Runnable runnable) {\\n Map<String, String> threadContext = MDC.getCopyOfContextMap();\\n return () -> {\\n MDC.setContextMap(threadContext);\\n runnable.run();\\n };\\n }\\n}\\n```\\n\\n\uc0dd\uc131\ud55c Decorator \ud074\ub798\uc2a4\ub97c \uc124\uc815 \ud30c\uc77c\uc5d0 \ub4f1\ub85d\ud574 \uc900\ub2e4.\\n\\n```java title=AsyncConfig\\n@RequiredArgsConstructor\\n@EnableAsync\\n@Configuration\\npublic class AsyncConfig implements AsyncConfigurer {\\n\\n private final AsyncConfigurationProperties properties;\\n\\n @Bean\\n public ThreadPoolTaskExecutor taskExecutor() {\\n ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();\\n executor.setCorePoolSize(properties.coreSize());\\n executor.setMaxPoolSize(properties.maxSize());\\n executor.setQueueCapacity(properties.queueCapacity());\\n \\n // highlight-next-line\\n executor.setTaskDecorator(new MdcTaskDecorator());\\n executor.setWaitForTasksToCompleteOnShutdown(true);\\n executor.initialize();\\n return executor;\\n }\\n\\n @Override\\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\\n return new AsyncExceptionHandler();\\n }\\n}\\n```\\n\\n\uc124\uc815 \ud6c4\uc5d0\ub294 \uc815\uc0c1\uc801\uc73c\ub85c MDC\uc5d0 \ub4e4\uc5b4\uac00 \uc788\ub294 UUID\uac00 \ucd9c\ub825\ub418\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4.\\n\\n![./mdc-not-null.png](./mdc-not-null.png)\\n\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[spring async, baeldung](https://www.baeldung.com/spring-async) \\n[@Async will not call by @ControllerAdvice for global exception](https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception) \\n[Spring \uc758 \ub3d9\uae30, \ube44\ub3d9\uae30, \ubc30\uce58 \ucc98\ub9ac\uc2dc \ud56d\uc0c1 context \ub97c \uc720\uc9c0\ud558\uace0 \ub85c\uae45\ud558\uae30, \uac15\ub0a8\uc5b8\ub2c8](https://blog.gangnamunni.com/post/mdc-context-task-decorator/) \\n[TaskDecorator, Spring docs](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html) \\n[AsyncUncaughtExceptionHandler](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html)"},{"id":"tomcat-retrospective","metadata":{"permalink":"/tomcat-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","description":"1, 2\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-http/pull/302","date":"2023-09-11T00:00:00.000Z","formattedDate":"2023\ub144 9\uc6d4 11\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":12.345,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","slug":"tomcat-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45","permalink":"/log-async-exception"},"nextItem":{"title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958","permalink":"/performance-test-type"}},"content":":::note PR \ub9c1\ud06c \\n1, 2\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-http/pull/302 \\n3, 4\ub2e8\uacc4: https://github.com/woowacourse/jwp-dashboard-http/pull/431\\n:::\\n\\n### \ud1b0\ucea3 \uad6c\ud604\\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c0\uc6d0\ud560 \ub54c \uac1d\uccb4\uc9c0\ud5a5\uacfc \uad00\ub828\ub41c \ubbf8\uc158\ub3c4 \uae30\ub300\ub97c \ub9ce\uc774 \ud588\uc9c0\ub9cc \ub808\ubca8 4\uc5d0 \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc774 \uc815\ub9d0 \ud558\uace0 \uc2f6\uc5c8\ub2e4. \\n\uadf8\ub798\uc11c \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc744\uae4c\ub77c\ub294 \uac71\uc815 \ubc18, \ubbf8\uc158\uc5d0 \ub300\ud55c \uae30\ub300 \ubc18\uc73c\ub85c \ubd80\ud47c \ub9c8\uc74c\uc744 \uac00\uc9c0\uace0 \ubbf8\uc158\uc744 \uc2dc\uc791\ud588\ub358 \uac83 \uac19\ub2e4. \\n\\n\uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc801\uc808\ud558\uac8c \ucd94\uc0c1\ud654\ud558\uace0, \ubbf8\uc158\uc758 \ubcf8\uc9c8\uc744 \uc774\ud574\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158\uc740 [RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616/)\uc5d0 \uba85\uc2dc\ub41c \uc2a4\ud399(\uc644\ubcbd\ud558\uc9c0 \uc54a\uc9c0\ub9cc \ubbf8\uc158\uc5d0\uc11c \uc8fc\uc5b4\uc9c4 \uc694\uad6c\uc0ac\ud56d\ub9cc \ub9cc\uc871\ud558\ub3c4\ub85d)\uc73c\ub85c \uc694\uccad\uc744 \ubc1b\uc544 \ucc98\ub9ac \ud6c4 \ubc18\ud658\ud558\ub294\ub370 \uc9d1\uc911\ud588\ub2e4. \\n\\n### \ub2e4\uc774\uc5b4\uadf8\ub7a8\\n\\nCatalina\ub294 Tomcat\uc758 \uc11c\ube14\ub9bf \ucee8\ud14c\uc774\ub108, Coyote\ub294 HTTP 1.1 \uc6f9 \uc11c\ubc84\ub97c \uc9c0\uc6d0\ud558\ub294 \uad6c\uc131 \uc694\uc18c\ub77c\uace0 \uc0dd\uac01\ud558\uace0 \uc544\ub798\uc640 \uac19\uc774 \uad6c\uc131\ud588\ub2e4. \\n\uc0ac\uc2e4 \ub0b4\ubd80 \uad6c\uc870\ub97c \uae4a\uac8c \uacf5\ubd80\ud560 \uc2dc\uac04\uc744 \uac00\uc9c0\uc9c0 \ubabb\ud574\uc11c \uac01 \uad6c\uc131 \uc694\uc18c\uac00 \uc65c \ud574\ub2f9 \uc704\uce58\uc5d0 \uc788\ub294\uc9c0 \uc644\ubcbd\ud558\uac8c \uc124\uba85\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc774\uac74 \uc5ec\uae30\uc5d0 \uc788\uc73c\uba74 \uc88b\uc744 \uac83 \uac19\uc740\ub370? \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e4\uba74 \uc801\uc808\ud55c \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\uc2dc\ud0a4\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\ub2e4. \\n\ub610\ud55c \uc801\uc808\ud558\uac8c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc744 \ub2e8\ubc29\ud5a5\uc73c\ub85c \ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tsubgraph coyote\\n\\t\\tHP[Http11Processor] --\x3e A\\n\\t\\tHP --\x3e HttpRequestParser\\n\\t\\tHP --\x3e HttpResponseGenerator\\n\\t\\tA[Adapter]\\n end\\n\\n subgraph catalina\\n\\t\\tRA[RequestAdapter] -.-> A\\n\\t\\tAC[AbstractController] -.-> C[Controller]\\n\\t\\tStaticController -.-> AC\\n\\t\\tSM[SessionManger] -.-> Manager\\n\\t\\tTC[Tomcat] --\x3e RA\\n\\t\\tRA --\x3e C\\n\\t\\tRA --\x3e Manager\\n\\t\\tRA --\x3e RM\\n\\t\\tRM[RequestMapper] --\x3e C\\n end\\n\\n subgraph jwp\\n\\t\\tLC[LoginController] -.-> AC\\n\\t\\tApplication --\x3e TC\\n end\\n\\n```\\n\\n### \ucf54\ub4dc \ub9ac\ubdf0 \\n\\n\ud06c\ub8e8 \uc911 \ud55c \uba85\uc774 \ub098\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\uace0, \ub0b4\uac00 \ub2e4\ub978 \ud06c\ub8e8\uc758 \ub9ac\ubdf0\uc5b4\uac00 \ub418\ub294 \ud615\ud0dc\ub85c \uc9c4\ud589\uc774 \ub418\uc5c8\ub2e4. \\n\ub098\uc758 \ub9ac\ubdf0\uc5b4\ub294 \ub514\ub178, \ub9ac\ubdf0\uc774\ub294 \ud544\ub9bd\uc774\uc5c8\ub2e4. \\n\\n\ub514\ub178(\ub9e4\uc758 \ub208\uc774 \uc544\ub2cc \uacf5\ub8e1\uc758 \ub208?)\uac00 \ub9e4\uc6b0 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud574\uc8fc\uc5b4\uc11c \uc870\uae08 \ub354 \ub098\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \uc218 \uc788\uc5c8\uace0, \ud544\ub9bd\uc758 \ucf54\ub4dc\uc5d0\uc11c\ub294 \uaf3c\uaf3c\ud558\uac8c \uc608\uc678\ucc98\ub9ac \ud558\ub294 \ubd80\ubd84\uc744 \ubc30\uc6b8 \uc218 \uc788\uc5c8\ub2e4. \\n\ud55c \uac00\uc9c0 \uc544\uc26c\uc6b4 \uc810\uc740 \ud544\ub9bd\uc5d0\uac8c \uc791\uc131\ud55c \ub098\uc758 \ucf54\uba58\ud2b8\ub4e4\uc774 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uacbd\ud5d8 \uae30\ubc18\uc73c\ub85c \uc791\uc131\ud55c \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uadfc\uac70\uac00 \uc870\uae08 \ubd80\uc871\ud588\uace0, \uc815\ub9ac\ub418\uc9c0 \uc54a\uc740 \ubd80\ubd84\uc774 \ub9ce\uc558\ub358 \uac83 \uac19\ub2e4. \\n\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130 \ub9ac\ubdf0\ud560 \ub54c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ub354 \uc88b\uc740 \ub0b4\uc6a9\uc744 \ud06c\ub8e8\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. \\n\\n### SessionConfig\\n\\n\ubbf8\uc158\uc744 \uc9c4\ud589 \uc911 catalina \ud328\ud0a4\uc9c0\uc758 Session \uad00\ub828 \ubd80\ubd84\uc744 \ubcf4\uba74\uc11c \uc911\ubcf5 \ub85c\uc9c1\uc744 \uac1c\uc120\ud574 \ubcfc \uc218 \uc788\uc744 \uac83 \uac19\uc544 [\ucee8\ud2b8\ub9ac\ubdf0\ud2b8](https://github.com/apache/tomcat/pull/660)\ub97c \uc2dc\ub3c4\ud588\ub2e4. \\n\uc138\uc158 \ucfe0\ud0a4\uc758 \uc774\ub984\uc744 \uac00\uc838\uc624\ub294 Util \ud074\ub798\uc2a4\uc758 \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub294\ub370 \uae30\ubcf8 \uac12\uc740 JSESSIONID \uc9c0\ub9cc \uc124\uc815\uc5d0 \ub530\ub77c\uc11c \uc138\uc158 \ucfe0\ud0a4\uba85\uc744 \ub2e4\ub974\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ub85c\uc9c1\uc774 \uc788\ub294 \uac83\uc73c\ub85c \uc0dd\uac01\ud588\ub2e4. \\n\uae30\uc874\uc758 \ucf54\ub4dc\ub294 \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \ucf54\ub4dc\uc758 \ud750\ub984\uc774 \uc77c\uce58\ud558\uc9c0 \uc54a\uc544\uc11c \uc57d\uac04 \uc774\ud574\ud558\uae30 \uc5b4\ub824\uc6e0\ub2e4. \\n\\n\ucd08\uae30\uc5d0 \uc694\uccad\ud588\ub358 PR\uc740 \uae30\uc874\uc758 \ucf54\ub4dc\ubcf4\ub2e4 \uc804\uccb4\uc801\uc73c\ub85c \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, context\uac00 null\uc778 \uacbd\uc6b0 \ubc14\ub85c \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud568\uc73c\ub85c\uc368 \uc131\ub2a5 \uac1c\uc120\uc758 \ud6a8\uacfc\uac00 \uc788\uc744 \uac70\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uba54\uc778\ud14c\uc774\ub108\uc778 Mark Thomas \ud615\uc774 \ud574\ub2f9 \ub85c\uc9c1\uc758 \uacbd\uc6b0 \ucef4\ud30c\uc77c\ub7ec\uac00 \ud574\ub2f9 \ubd80\ubd84\uc744 \ucd5c\uc801\ud654 \ud560 \uc218 \uc788\uc744 \uac70\ub77c\uace0 \uae30\ub300\ud55c\ub2e4\uace0 \ud588\uace0, \uac00\ub3c5\uc131\uc744 \uac1c\uc120\uc2dc\ucf1c\ubcf4\ub77c\uace0 \uc870\uc5b8\ud574\uc8fc\uc168\ub2e4. \\n\ucef4\ud30c\uc77c\ub7ec \ucd5c\uc801\ud654\ub294 \uace0\ub824\ud574\ubcf4\uc9c0 \ubabb\ud55c \ubd80\ubd84\uc778\ub370, \uc55e\uc73c\ub85c \ud559\uc2b5\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc0b0\ub354\ubbf8\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n\ub0a8\uaca8\uc900 \ucf54\uba58\ud2b8\uc5d0 \ub530\ub77c \ucd5c\uc885\uc801\uc73c\ub85c\ub294 \uc911\ubcf5\ub41c \ucf54\ub4dc\ub97c \uc904\uc774\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc218\uc815\ud588\ub2e4. \\n\uacb0\uacfc\uc801\uc73c\ub85c \uae30\uc874 \ub85c\uc9c1 \ub300\ube44 \ube44\uad50 \uc5f0\uc0b0\uc744 \ud55c \ubc88 \uc904\uc77c \uc218 \uc788\uc5c8\uace0, \uba85\uc2dc\ub41c \uc8fc\uc11d\uc758 \ub0b4\uc6a9\uacfc \uc720\uc0ac\ud55c \ud750\ub984\uc758 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc5ec \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub9ac\ud329\ud130\ub9c1\uc744 \ud588\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\nimport Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n<Tabs>\\n<TabItem value=\\"\uae30\uc874\\" label=\\"\uae30\uc874\\">\\n\\n```java\\npublic static String getSessionCookieName(Context context) {\\n\\n String result = getConfiguredSessionCookieName(context);\\n\\n if (result == null) {\\n result = DEFAULT_SESSION_COOKIE_NAME;\\n }\\n\\n return result;\\n}\\n\\npublic static String getSessionUriParamName(Context context) {\\n\\n String result = getConfiguredSessionCookieName(context);\\n\\n if (result == null) {\\n result = DEFAULT_SESSION_PARAMETER_NAME;\\n }\\n\\n return result;\\n}\\n\\nprivate static String getConfiguredSessionCookieName(Context context) {\\n\\n // Priority is:\\n // 1. Cookie name defined in context\\n // 2. Cookie name configured for app\\n // 3. Default defined by spec\\n if (context != null) {\\n String cookieName = context.getSessionCookieName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n\\n SessionCookieConfig scc =\\n context.getServletContext().getSessionCookieConfig();\\n cookieName = scc.getName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n }\\n\\n return null;\\n}\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"PR \uc694\uccad\\" label=\\"PR \uc694\uccad\\">\\n\\n```java\\npublic static String getSessionCookieName(Context context) {\\n if (context == null) {\\n return DEFAULT_SESSION_COOKIE_NAME;\\n }\\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\\n}\\n\\npublic static String getSessionUriParamName(Context context) {\\n if (context == null) {\\n return DEFAULT_SESSION_PARAMETER_NAME;\\n }\\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\\n}\\n\\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\\n // Priority is:\\n // 1. Cookie name defined in context\\n // 2. Cookie name configured for app\\n // 3. Default defined by spec\\n String cookieName = context.getSessionCookieName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n\\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\\n cookieName = scc.getName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n\\n return defaultName;\\n}\\n```\\n</TabItem>\\n\\n<TabItem value=\\"\ucd5c\uc885\\" label=\\"\ucd5c\uc885\\">\\n\\n```java\\npublic static String getSessionCookieName(Context context) {\\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME);\\n}\\n\\npublic static String getSessionUriParamName(Context context) {\\n return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME);\\n}\\n\\nprivate static String getConfiguredSessionCookieName(Context context, String defaultName) {\\n // Priority is:\\n // 1. Cookie name defined in context\\n // 2. Cookie name configured for app\\n // 3. Default defined by spec\\n if (context != null) {\\n String cookieName = context.getSessionCookieName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n\\n SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig();\\n cookieName = scc.getName();\\n if (cookieName != null && cookieName.length() > 0) {\\n return cookieName;\\n }\\n }\\n return defaultName;\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n### HTTP \uc218\uc5c5\\n\\n\ubbf8\uc158 \uc911\uac04\uc5d0 \uc9c4\ud589\ub418\uc5c8\ub358 HTTP \uc218\uc5c5\uc5d0\ub294 HTTP\ub97c \uc801\uc808\ud558\uac8c \ud65c\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4. \\n\ud56d\uc0c1 \uc131\ub2a5 \uac1c\uc120\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub2e8\uc5d0\uc11c \ucd5c\uc801\ud654\ud574\ubcf4\ub824\uace0 \ub178\ub825\uc744 \ud588\uc9c0\ub9cc, \ub354 \uc801\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574\uc11c \ud6a8\uc728\uc801\uc73c\ub85c \uc131\ub2a5\uc744 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574 \uc54c \uc218 \uc788\uc5c8\ub358 \uc218\uc5c5\uc774\uc5c8\ub2e4. \\nHTTP \uc555\ucd95, HTTP \uce90\uc2f1, \ub9ac\uc18c\uc2a4 \ucd5c\uc801\ud654 \uae30\ubc95\uc5d0 \ub300\ud574 \ud559\uc2b5\ud588\ub2e4. \\n\\n\uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \ub2e4\uc74c \uc635\uc158\uc744 \uc124\uc815\ud558\uc5ec http\uc758 \uc1a1\uc218\uc2e0\uc758 \uc555\ucd95\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\ub2e4. \\n\\n```yml\\nserver:\\n compression:\\n enabled: true\\n```\\n\\n\uc218\uc5c5 \uc911 \ud574\ub2f9 \uc555\ucd95 \uc131\ub2a5\uc774 \uc88b\ub2e4\uba74 \uc65c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\uc11c\ub294 \uae30\ubcf8 \uac12\uc73c\ub85c \uc124\uc815\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\uc9c0 \uad81\uae08\ud574\uc84c\ub2e4. \\n\uad81\uae08\uc99d\uc744 \ud574\uc18c\ud558\uc9c0 \ubabb\ud588\ub294\ub370 \ub9d0\ub791\uc774 \uc7a1\ub2f4 \ucc44\ub110\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc740 [issue](https://github.com/spring-projects/spring-boot/issues/21369)\ub97c \ucc3e\uc544\uc8fc\uc5c8\ub2e4. \\n\ub0b4\uc6a9\uc744 \uc694\uc57d\ud574 \ubcf4\uc790\uba74 WAS \ubcc4\ub85c \uc555\ucd95\uc744 \ud558\uae30 \uc704\ud574 \uc124\uc815\ud574\uc57c \ud558\ub294 \uac83\uc774 \ub2e4\ub974\uace0, \ubb34\uc870\uac74 \uc555\ucd95\uc744 \ud558\ub294 \uac83\uc774 \ucd5c\uc801\uc758 \uacbd\uc6b0\uac00 \uc544\ub2d0 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uae30\ubcf8\uac12\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 \uac19\ub2e4. \\n\\n> If you\'re developing a public-facing application then it\'s probably likely gzip compression would be worthwhile. If, however, you\'re a microservice application and you\'re in a dataceter, you may well prefer to reduce CPU load because you know you\'ll only be talking to other microservices and you have a reliable gigabit network.\\n\\nPhil Webb \ud615\ub2d8\uc758 \ub9d0\uc5d0 \ub530\ub974\uba74 \uc77c\ubc18\uc801\uc778 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uac1c\ubc1c\ud558\ub294 \uacbd\uc6b0 gzip \uc555\ucd95\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc9c0\ub9cc, MSA \ud658\uacbd + \ub370\uc774\ud130 \uc13c\ud130\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \uc624\uc9c1 \ub2e4\ub978 MSA \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uacfc \ud1b5\uc2e0\ud558\uace0, \uace0\uc131\ub2a5 \ub124\ud2b8\uc6cc\ud06c\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0 CPU \ubd80\ud558\ub97c \uc904\uc774\ub294 \uac83\uc774 \uc6b0\uc120\uc2dc \ub420 \uc218\ub3c4 \uc788\ub2e4\ub294 \uac83\uc774\uc5c8\ub2e4. \\n\\n\uc774\uc678\uc5d0\ub3c4 \uc758\ub3c4\ud558\uc9c0 \uc54a\uc740 \uce90\uc2f1\uc744 \ub9c9\uae30 \uc704\ud574 \ud734\ub9ac\uc2a4\ud2f1 \uce90\uc2f1\uc744 \uc81c\uac70\ud558\uac70\ub098, \uac1c\uc778 \uc815\ubcf4 \uc720\ucd9c\uc744 \ub9c9\uae30 \uc704\ud574 \uc751\ub2f5 \ud5e4\ub354\uc5d0 private\uc744 \uc124\uc815, ETag\ub3c4 \ud559\uc2b5\ud588\ub2e4. \\n\\n:::note ETag\\nETag HTTP \uc751\ub2f5 \ud5e4\ub354\ub294 \ud2b9\uc815 \ubc84\uc804\uc758 \ub9ac\uc18c\uc2a4\ub97c \uc2dd\ubcc4\ud558\ub294 \uc2dd\ubcc4\uc790\ub2e4. \\n\uc6f9 \uc11c\ubc84\uac00 \ub0b4\uc6a9\uc744 \ud655\uc778\ud558\uace0 \ubcc0\ud558\uc9c0 \uc54a\uc558\uc73c\uba74, \uc6f9 \uc11c\ubc84\ub85c full \uc694\uccad\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0, \uce90\uc2dc\uac00 \ub354 \ud6a8\uc728\uc801\uc774\uac8c \ub41c\ub2e4. \\nMDN\\n:::\\n\\n### Thread \uc218\uc5c5\\n\\n\uc2a4\ub808\ub4dc\uc5d0 \ub300\ud55c \uc218\uc5c5\uc744 \ub4e4\uc5c8\uc9c0\ub9cc, \ubcf5\uc7a1\ud55c \ub0b4\uc6a9\ub3c4 \uc6cc\ub099 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0 \uc124\uba85\ud558\ub77c\uace0 \ud558\uba74 \uc798 \ubabb\ud560 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e0\ub2e4. \\n\ud604\uc7ac \ud504\ub85c\uc81d\ud2b8, \ubbf8\uc158, \ud14c\ucf54\ud1a1 \uc900\ube44\ub97c \ubcd1\ud589\ud574\uc57c \ud574\uc11c \uc138\ubd80\uc801\uc778 \ub0b4\uc6a9\uc740 \uc2dc\uac04 \ub0a0 \ub54c \ubcf5\uc2b5\ud558\ub824\uace0 \ud55c\ub2e4. \\n\\n\uc2a4\ub808\ub4dc\ub97c \uc774\ud574\ud558\uace0, WAS\uc5d0 \uc2a4\ub808\ub4dc \uc124\uc815 \uad00\ub828\ud55c \uc2e4\uc2b5\uc774 \uc788\uc5c8\ub294\ub370 \ud14c\uc624\uc640 \uac19\uc774 1\uc2dc\uac04 \uc815\ub3c4 \ud398\uc5b4\ub85c Thread \uc2e4\uc2b5\uc744 \uc9c4\ud589\ud574 \ubcf4\uc558\ub2e4. \\n\ud559\uc2b5\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n`threads.max`: Tomcat\uc758 \ucd5c\ub300 \uc2a4\ub808\ub4dc \uac1c\uc218 \\n`max-connections`: Tomcat\uc774 \uc720\uc9c0\ud560 \uc218 \uc788\ub294 \ucd5c\ub300 \ucee4\ub125\uc158 \uac1c\uc218 \\n`accept-count`: \ucd5c\ub300 \uc5f0\uacb0 \uc218\uc5d0 \ub3c4\ub2ec\ud588\uc744 \ub54c \uc5f0\uacb0 \uc694\uccad\uc5d0 \ub300\ud574 \uc6b4\uc601 \uccb4\uc81c\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub300\uae30\uc5f4\uc758 \ucd5c\ub300 \uae38\uc774. \ud574\ub2f9 Queue\uc5d0 \uc694\uccad\uc774 \uc313\uc774\ub294 \uac83\uc740 Tomcat\uc774 \ub354 \uc774\uc0c1 \uc694\uccad\uc744 \ubc1b\uc744 \uc218 \uc5c6\ub2e4\ub294 \ub73b\uc774\ub2e4. accpet-count queue\uc5d0\ub3c4 \uc694\uccad\uc774 \uac00\ub4dd\ucc28\uba74 \uadf8 \uc774\ud6c4\uc5d0 \uc624\ub294 \uc694\uccad\uc740 \uac70\ubd80\ub41c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n C(\\"Client\\") -- request --\x3e ACQ(\\"\uc6b4\uc601\uccb4\uc81c\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue \\n size = accept-count\\") --\x3e TCQ(\\"Tomcat Connector\uc5d0 \uc758\ud574 \uad00\ub9ac\ub418\ub294 Queue\\n size = max-connections\\") --\x3e TP(\\"Thread Pool\\n size = threads.max\\")\\n```\\n\\n### \ub9c8\uce58\uba70\\n\\n\uc2dc\uac04\uc740 \ub108\ubb34 \ube60\ub974\uac8c \uac00\uace0 \ud560 \uc77c\uc740 \ub9ce\uc740 \uac83 \uac19\ub2e4. \\n\uc6b0\uc120\uc21c\uc704\ub97c \uc798 \uc815\ud558\uace0 \ud559\uc2b5\uc744 \uc9c4\ud589\ud574\uc57c\uaca0\ub2e4. \\n\ud604\uc7ac \ub370\uc774\ud130 \ub2e4\ub8e8\ub294 \ubd80\ubd84(DB)\uc5d0 \ub300\ud55c \ud559\uc2b5\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\ub2e4. \ud574\ub2f9 \ubd80\ubd84\uc740 \ud14c\ucf54\ud1a1\uc774 \ub05d\ub098\ub294\ub300\ub85c \ucc44\uc6cc\uc57c\uaca0\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[RFC 2616](https://datatracker.ietf.org/doc/html/rfc2616/) \\n[ETag, mdn](https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/ETag) \\n[Apache Tomcat 8 Configuration Reference](https://tomcat.apache.org/tomcat-8.5-doc/config/http.html) \\n[Apache Tomcat Tuning, Terry Cho](https://bcho.tistory.com/788) \\n[maxThreads, maxConnections, acceptCount\ub85c Tomcat \ud29c\ub2dd\ud558\uae30](https://dev-ws.tistory.com/96)"},{"id":"performance-test-type","metadata":{"permalink":"/performance-test-type","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx","source":"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx","title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958","description":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8","date":"2023-09-10T00:00:00.000Z","formattedDate":"2023\ub144 9\uc6d4 10\uc77c","tags":[{"label":"performance test","permalink":"/tags/performance-test"}],"readingTime":5.8,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958","slug":"performance-test-type","tags":["performance test"]},"unlisted":false,"prevItem":{"title":"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0","permalink":"/tomcat-retrospective"},"nextItem":{"title":"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30","permalink":"/db-replication"}},"content":"## \uc131\ub2a5 \ud14c\uc2a4\ud2b8\\n\\nAPI\uc758 \uc694\uccad\uc774 \ub9ce\uc740 \uc0c1\ud669\uc5d0\uc11c \uc11c\ubc84\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8\\n\\n\uc2dc\uc2a4\ud15c\uc5d0 \ubd80\ud558\uac00 \uac78\ub9ac\uba74 \ubb38\uc81c \uc0c1\ud669\uc774 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \\n\ub2e4\uc591\ud55c \uc0c1\ud669\uc5d0 \ub300\ube44\ud574\uc11c \uc131\ub2a5 \ud14c\uc2a4\ud2b8\ub97c \ud574\uc57c\ud55c\ub2e4. \\n\\n![./test.png](./test.png)\\n\\n### \uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8(Smoke Test)\\n\\n\ucd5c\uc18c\ud55c\uc758 \ubd80\ud558\ub97c \uc8fc\uc5b4 \uc2dc\uc2a4\ud15c\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\nVU\ub97c \ucd5c\uc18c\ud55c\uc73c\ub85c \ub450\uace0, \uc9e7\uc740 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \ud14c\uc2a4\ud2b8\ud55c\ub2e4. \\n\ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \uc2dc\uc791\ud558\uae30 \uc804\uc5d0 \uc2a4\ubaa8\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud568\uc73c\ub85c\uc368 \ud14c\uc2a4\ud2b8 \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc624\ub958\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\uace0, \uc131\ub2a5 \uc9c0\ud45c\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \uc218\uc9d1, \ubaa8\ub2c8\ud130\ub9c1 \ub418\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n:::note \uac00\uc0c1 \uc0ac\uc6a9\uc790(VU)\\n\uac00\uc0c1 \uc0ac\uc6a9\uc790\ub294 \uc11c\ubc84 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0 \ub300\ud574 \ud2b9\uc815 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c\ub2e4. \\n\uc774\ub294 \ub2e4\ub978 \uac00\uc0c1 \uc0ac\uc6a9\uc790\uc640 \ub3c5\ub9bd\uc801\uc73c\ub85c \uc2e4\ud589\ub418\uba70, \uc5ec\ub7ec \uac00\uc0c1 \uc0ac\uc6a9\uc790\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub3d9\uc2dc \uc5f0\uacb0\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\uc2a4\ub808\ub4dc\ub77c\uace0 \uc0dd\uac01\ud558\uba74 \ub41c\ub2e4. \\n:::\\n\\n### \uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8(Spike Test)\\n\\n\uc0ac\uc6a9\ub7c9\uc774 \uae09\uc99d\ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uacac\ub514\uace0 \uc131\ub2a5\uc5d0 \ubb38\uc81c\uac00 \uc5c6\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\n\ud2f0\ucf13 \ubc1c\uae09, \ud560\uc778 \ucfe0\ud3f0 \ubc1c\uae09\uacfc \uac19\uc740 \uc774\ubca4\ud2b8\ub97c \ud558\ub294 \uacbd\uc6b0 \ub300\uaddc\ubaa8 \ud2b8\ub798\ud53d\uc774 \ub4e4\uc5b4\uc628\ub2e4. \\n\uc2a4\ud30c\uc774\ud06c \ud14c\uc2a4\ud2b8\ub97c \ud1b5\ud574 \uae09\uc99d\ud558\ub294 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\uace0, \ubd80\ud558\ub97c \uc798 \ubc84\ud2f0\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n### \ubd80\ud558 \ud14c\uc2a4\ud2b8(Load Test)\\n\\n\ubaa9\ud46f\uac12\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \uacac\ub51c \uc218 \uc788\uc744\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\n\uc77c\ubc18\uc801\uc778 \ubd80\ud558 \uc0c1\ud669\uc5d0\uc11c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8\ub2e4. \\n\ub7a8\ud504\uc5c5 \ub610\ub294 \ubb19\ud46f\uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ubd80\ud558 \uae30\uac04\ub3d9\uc548 \uc131\ub2a5\uc774 \ubb38\uc81c\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\uace0, \uc2dc\uc2a4\ud15c \ubcc0\uacbd \ud6c4\uc5d0\ub3c4 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \ub3cc\ub824 \ub3d9\uc77c\ud558\uac8c \ubaa9\ud46f\uac12\uc744 \ucc98\ub9ac\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n:::note \ub7a8\ud504 \uc5c5(Ramp-up)\\n\ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud574 \uc124\uc815\ud55c \uac00\uc0c1 \uc0ac\uc6a9\uc790 \uc218\uc5d0 \ub3c4\ub2ec\ud558\ub294 \ub370 \uac78\ub9ac\ub294 \uc2dc\uac04\\n:::\\n\\n### \uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8(Stress Test) \\n\\n\uc2dc\uc2a4\ud15c\uc758 \ucd5c\ub300\uce58\uc5d0 \ud574\ub2f9\ub418\ub294 \ubd80\ud558\ub97c \ubc1b\uc558\uc744 \ub54c \uc2dc\uc2a4\ud15c\uc774 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\n\uadf8\ub798\ud504\ub97c \ubd24\uc744 \ub54c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc640 \uc720\uc0ac\ud55c \ud615\ud0dc\ub85c \ubcf4\uc774\uc9c0\ub9cc, \ubd80\ud558\ub7c9\uc774 \ub2e4\ub974\ub2e4. \\n\uc77c\ubc18\uc801\uc73c\ub85c \ud3c9\uade0\uc801\uc778 \ubaa9\ud46f\uac12 \ub300\ube44 \uc791\uac8c\ub294 50% \uc774\uc0c1, \ud544\uc694\uc758 \uacbd\uc6b0 \uadf8 \uc774\uc0c1\uc73c\ub85c \ubd80\ud558\ub97c \uc900\ub2e4. \\n\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub294 \ubd80\ud558 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud55c \ud6c4\uc5d0\ub9cc \uc2e4\ud589\ud574\uc57c \ud55c\ub2e4. \ubd80\ud558 \ud14c\uc2a4\ud2b8\uac00 \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\uc740 \uc0c1\ud669\uc5d0\uc11c \uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc2e4\ud589\ud558\ub294 \uacbd\uc6b0\uc5d0\ub294 \ubcd1\ubaa9 \uc9c0\uc810\uc774\ub098 \ubb38\uc81c \uc0c1\ud669\uc744 \ucc3e\uae30 \uc5b4\ub824\uc6cc\uc9c4\ub2e4. \\n\ub610\ud55c \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc5d0\uc11c \uc0ac\uc6a9\ud55c \uc2a4\ud06c\ub9bd\ud2b8\ub97c VU\uac12(\uc2a4\ub808\ub4dc \uc218)\ub9cc \uc218\uc815\ud558\uc5ec \uc7ac\uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\\n### \ub0b4\uad6c \ud14c\uc2a4\ud2b8(Endurance Test) \\n\\n\ud3c9\uade0 \uc0ac\uc6a9\ub960\ub85c \uc77c\uc815 \ubd80\ud558\ub97c \uc9c0\uc18d\uc801\uc73c\ub85c \uc8fc\uba70 \uc2dc\uc2a4\ud15c\uc774 \ubb38\uc81c\ub418\ub294 \uc9c0\uc810\uc744 \ud655\uc778\ud558\ub294 \ud14c\uc2a4\ud2b8 \\n\\n\ud761\uc218 \ud14c\uc2a4\ud2b8(Soak Test)\ub77c\uace0\ub3c4 \ud558\uba70, \uae30\ubcf8\uc801\uc778 \ubd80\ud558 \ud14c\uc2a4\ud2b8\uc758 \ubcc0\ud615\uc774\ub77c\uace0 \ubcfc \uc218 \uc788\ub2e4. \\n\ub2e4\ub978 \ud14c\uc2a4\ud2b8\uc640 \ub2ec\ub9ac \uae34 \uc2dc\uac04\ub3d9\uc548 \ud14c\uc2a4\ud2b8\ub97c \ud558\ub294 \uac83\uc774 \ud2b9\uc9d5\uc774\uba70, \uba54\ubaa8\ub9ac \ub204\uc218 \ubb38\uc81c\uc640 \uac19\uc774 \uc7a5\uc2dc\uac04 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc2e4\ud589\ud560 \ub54c \uc2dc\uc2a4\ud15c\uc758 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \ubd80\ubd84\uc744 \ud655\uc778\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4. \\n\\n### \uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8(Breakpoint Test)\\n\\n\uc784\uacc4 \uc9c0\uc810\uc744 \ucc3e\uae30 \uc704\ud574 \ubd80\ud558\ub97c \uc810\uc9c4\uc801\uc73c\ub85c \uc99d\uac00\uc2dc\ud0a4\uba70 \uc9c4\ud589\ud558\ub294 \ud14c\uc2a4\ud2b8\\n\\n\ubb38\uc81c\ub418\ub294 \ubd80\ubd84\uc744 \ub354 \ube68\ub9ac \ucc3e\uae30 \uc704\ud574 \ub2e4\ub978 \ud14c\uc2a4\ud2b8\ub97c \ud1b5\uacfc\ud55c \ub2e4\uc74c\uc5d0 \uc911\ub2e8\uc810 \ud14c\uc2a4\ud2b8\ub97c \uc9c4\ud589\ud558\uace0, \uc774 \ub54c \uc810\uc9c4\uc801\uc73c\ub85c \ubd80\ud558\ub97c \ub298\ub824\ub098\uac00\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\uc2a4\ud2b8\ub808\uc2a4 \ud14c\uc2a4\ud2b8\ub97c \uc131\ub2a5 \ud29c\ub2dd\uacfc \ubc18\ubcf5\ud574\uc11c \uc9c4\ud589\ud55c\ub2e4\uba74, \uc2dc\uc2a4\ud15c\uc744 \ub354\uc6b1 \ubc1c\uc804\uc2dc\ud0ac \uc218 \uc788\ub2e4. \\n\ub2e4\ub9cc Auto Scaling\uc774 \uc801\uc6a9\ub41c \ud074\ub77c\uc6b0\ub4dc \ud658\uacbd\uc5d0\uc11c\ub294 \uc9c4\ud589\ud558\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[Load test types, k6](https://k6.io/docs/test-types/load-test-types/) \\n\uc790\ubc14 \ucd5c\uc801\ud654 - \ubca4\uc800\ubbfc J. \uc5d0\ubc88\uc2a4, \uc81c\uc784\uc2a4 \uace0\ud504, \ud06c\ub9ac\uc2a4 \ub274\ub79c\ub4dc \\n\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04"},{"id":"db-replication","metadata":{"permalink":"/db-replication","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx","source":"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx","title":"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30","description":"\ubcf5\uc81c(Replication)","date":"2023-08-22T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 22\uc77c","tags":[{"label":"mysql","permalink":"/tags/mysql"},{"label":"replication","permalink":"/tags/replication"}],"readingTime":21,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30","slug":"db-replication","tags":["mysql","replication"]},"unlisted":false,"prevItem":{"title":"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958","permalink":"/performance-test-type"},"nextItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0","permalink":"/woowacourse-level3-retrospective"}},"content":"## \ubcf5\uc81c(Replication)\\n\\n\ud55c \uc11c\ubc84\uc5d0\uc11c \ub2e4\ub978 \uc11c\ubc84\ub85c \ub370\uc774\ud130\ub97c \ub3d9\uae30\ud654\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4. \\n\uc6d0\ubcf8 \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Primary \ub610\ub294 Source \ub77c\uace0 \ubd80\ub974\uace0, \ubcf5\uc81c\ub41c \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Secondary \ub610\ub294 Replica \ub77c\uace0 \ubd80\ub978\ub2e4. \\n\\n### \ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720\\n\\n**1. \uc2a4\ucf00\uc77c \uc544\uc6c3**\\n\\n\uc0ac\uc6a9\uc790\uc758 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0, \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uac00\ud574\uc9c0\ub294 \ubd80\ud558\ub3c4 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc99d\uac00\ud55c\ub2e4. \\n\uc774\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud574 \ubcf5\uc81c\ub97c \ud1b5\ud55c \uc2a4\ucf00\uc77c \uc544\uc6c3\uc744 \uc801\uc6a9\ud558\uc5ec \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucffc\ub9ac\ub4e4\uc744 \uac01\uac01\uc758 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub85c \ubd84\uc0b0 \uc2dc\ud0ac \uc218 \uc788\ub2e4. \\n\\n**2. \ub370\uc774\ud130 \ubc31\uc5c5**\\n\\n\uc2e4\uc81c \uc6b4\uc601\ub418\ub294 \uc11c\ube44\uc2a4\uac00 \uc0ac\uc6a9\ud558\uace0 \uc788\ub294 DB\uc5d0\uc11c \ubc31\uc5c5\uc744 \uc9c4\ud589\ud558\ub294 \uacbd\uc6b0, \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c \uc2e4\uc81c \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc774 \uac00\uc9c0 \uc54a\ub3c4\ub85d \ubcf5\uc81c\ub97c \ud1b5\ud574 Replica \uc11c\ubc84\ub97c \uad6c\ucd95\ud558\uc5ec, Replica \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ub97c \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\uc73c\ub85c \uc601\ud5a5\uc744 \ucd5c\uc18c\ud654 \ud560 \uc218 \uc788\ub2e4. \\n\\n**3. \ub370\uc774\ud130 \ubd84\uc11d**\\n\\n\ubc31\uc5c5\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc7a1\ud558\uace0 \ubb34\uac70\uc6b4 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\uc758 \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4. \\n\ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc81c\ub97c \uc0ac\uc6a9\ud574 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ud658\uacbd\uc744 \ub9cc\ub4e4 \uc218 \uc788\ub2e4. \\n\\n**4. \ub370\uc774\ud130\uc758 \uc9c0\ub9ac\uc801 \ubd84\uc0b0**\\n\\n\ube60\ub978 \uc751\ub2f5\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc11c\ubc84\uc5d0 \uac00\uae5d\uac8c \uc11c\ubc84\ub97c \uad6c\uc131\ud558\uac70\ub098, \uace0\uac00\uc6a9\uc131(High Availability)\uc744 \uc704\ud574\uc11c\ub3c4 \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n### \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c\\n\\nMySQL \uc11c\ubc84\uc5d0\uc11c \ubc1c\uc0dd\ud558\ub294 \ubcc0\uacbd\uc0ac\ud56d\uc5d0 \ub300\ud55c \ub85c\uadf8 \ud30c\uc77c\uc744 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub77c\uace0 \ud55c\ub2e4. \\n\ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ud1b5\ud574 \ub370\uc774\ud130 \ubcc0\uacbd, \ud14c\uc774\ube14 \uad6c\uc870 \ubcc0\uacbd, \uacc4\uc815\uc774\ub098 \uad8c\ud55c \ubcc0\uacbd\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc800\uc7a5\ub41c\ub2e4. \\nMySQL\uc758 \ubcf5\uc81c\ub294 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 \uc788\ub2e4. \uc774\ub97c Replica \uc11c\ubc84\ub85c \uc804\ub2ec\ud558\uace0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \ub370\uc774\ud130\ub97c \ubcc0\uacbd \uc0ac\ud56d\uc744 \ubc18\uc601\ud55c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tsubgraph Replica\\n\\t\\tdirection TB\\n\\t\\tIO[Replication I/O thread] -- save --\x3e RL[Relay Log]\\n\\t\\tSQL[Replication SQL Thread] -- read --\x3e RL\\n\\tend\\n\\n\\tsubgraph Source\\n\\t\\tdirection TB\\n\\t\\tBLD[Binary Log Dump Thread] -- Send Binary Log Dump--\x3e IO\\n\\tend\\n\\n```\\n\\n:::note \uc2a4\ub808\ub4dc\ubcc4 \uc5ed\ud560\\n\\nBinary Log Dump Thread: \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc758 \ub0b4\uc6a9\uc744 Replica \uc11c\ubc84\ub85c \uc804\ub2ec \\nReplication I/O Thread: Binary \ub85c\uadf8 \uc774\ubca4\ud2b8\ub97c \uac00\uc838\uc640 \ub85c\uceec \uc11c\ubc84\uc758 \ud30c\uc77c(Relay Log)\ub85c \uc800\uc7a5 \\nReplication SQL Thread: \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc774\ubca4\ud2b8\ub97c \uc77d\uace0 \uc2e4\ud589\\n\\n:::\\n\\n### \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810\\n\\n\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc740 \uc11c\ubc84\uc5d0 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud588\uc744 \ub54c \ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0 \ubcc0\uacbd\uc774 \uae4c\ub2e4\ub86d\ub2e4. \\n\ud1a0\ud3f4\ub85c\uc9c0\ub780 \ub124\ud2b8\uc6cc\ud06c\uc758 \uc694\uc18c\ub4e4\uc744 \ubb3c\ub9ac\uc801\uc73c\ub85c \uc5f0\uacb0\ud574 \ub193\uc740 \uac83, \ub610\ub294 \uadf8 \uc5f0\uacb0 \ubc29\uc2dd\uc744 \ub9d0\ud55c\ub2e4.\\n\\n```mermaid\\ngraph TD\\n\\tA[A binary-log:300] --\x3e B[B Binary-log:300]\\n\\tA[A binary-log:300] --\x3e C[C Binary-log:200]\\n```\\n\\n\uc704\uc640 \uac19\uc774 Source \uc11c\ubc84, Replica 2\ub300\uac00 \uc874\uc7ac\ud558\uace0, C \uc11c\ubc84\uc5d0 \ubcf5\uc81c \uc9c0\uc5f0\uc774 \ub418\uc5c8\uc744 \ub54c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\\n```mermaid\\ngraph TD\\n\\tA[A binary-log:300]\\n\\tB[B Binary-log:300] --\x3e C[C Binary-log:200 \ubb38\uc81c \ubc1c\uc0dd]\\n```\\n\\nA \uc11c\ubc84\uc5d0\uc11c \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 B \uc11c\ubc84\ub97c Source \uc11c\ubc84\ub85c \uc2b9\uaca9\ud558\uace0, C\uc5d0\uac8c \uc870\ud68c \ucffc\ub9ac\ub97c \ubd84\uc0b0\uc2dc\ud0a8\ub2e4. \\n\ud558\uc9c0\ub9cc \uc5ec\uae30\uc11c C \uc11c\ubc84\uc5d0\ub294 A \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\uac00 \uc548\ub418\uc5c8\uc73c\ub2c8 \uc870\ud68c \uc2dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\ub4a4\ub2a6\uac8c B \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\ub97c \ud558\ub824\uace0 \ud574\ub3c4, \uc5b4\ub5a4 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8, \uc5b4\ub5a4 \uc704\uce58\uc640 \ub3d9\uae30\ud654\ud574\uc57c\ud558\ub294\uc9c0 \uc54c\uae30 \uc5b4\ub835\ub2e4. \\n\\n### \uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c\\n\\nGTID \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ubc1c\uc0dd\ud55c \uc774\ubca4\ud2b8\uc5d0 \uace0\uc720\ud55c \uc2dd\ubcc4\uac12\uc744 \ubd80\uc5ec\ud55c\ub2e4\uba74, \ub3d9\uae30\ud654\uc5d0 \ub300\ud55c \ubb38\uc81c\ub97c \uac04\ub2e8\ud558\uac8c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4. \\n\uc704\uc758 \uc608\uc2dc\uc640 \uac19\uc774 \ubcf5\uc81c \uc9c0\uc5f0\uacfc \ud568\uaed8 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\ud574\ub3c4 \ud2b9\uc815 GTID \ubd80\ud130 \ubcf5\uc81c\ub97c \uc7ac\uac1c\ud558\uba74 \ub41c\ub2e4. \\n\\n:::note GTID\\n\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0\uc5d0 \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \uc11c\ubc84\uc5d0\uc11c \uace0\uc720\ud558\ub3c4\ub85d \uac01 \uc774\ubca4\ud2b8\uc5d0 \ubd80\uc5ec\ub41c \uc2dd\ubcc4\uac12 \\n[source_id]:[transaction_id]\ub85c \uad6c\uc131\ub418\uba70, source_id\ub294 \uc11c\ubc84\ub97c \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc774\uace0 transaction_id\ub294 \ucee4\ubc0b\ub41c \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc73c\ub85c 1\uc529 \uc99d\uac00\ud558\ub294 \ud615\ud0dc\ub85c \ubc1c\uae09\ub41c\ub2e4. \\n:::\\n\\n### \ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0\\n\\n**\uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131**\\n\\n\uac00\uc7a5 \uac04\ub2e8\ud55c \uad6c\uc131\uc73c\ub85c \uc81c\uc77c \ub9ce\uc774 \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4. \\nreplica \uc11c\ubc84\ub97c \uc77d\uae30 \uc804\uc6a9, \uc608\ube44 \uc11c\ubc84, \ubc31\uc5c5 \uc6a9\ub3c4\ub85c \ub9ce\uc774 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\\n W -- \uc77d\uae30 --\x3e R\\n S[Source] --\x3e R[Replica]\\n```\\n\\n**\uba40\ud2f0 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131**\\n\\n2\uac1c\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4. \\n\ud558\ub098\uc758 replica\ub294 \uc608\ube44 \uc6a9\ub3c4\ub85c \ub0a8\uaca8\ub450\ub294 \ud615\ud0dc\ub2e4. \\n\ucd94\ud6c4\uc5d0 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0 \uc608\ube44 \uc6a9\ub3c4\uc758 replica\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c \uc77d\uae30 \uc694\uccad\uc758 \ubd80\ud558 \ubd84\uc0b0\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\\n```mermaid\\ngraph LR\\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\\n W -- \uc77d\uae30 --\x3e R1\\n S[Source] --\x3e R1[Replica1]\\n S --\x3e R2[Replica2]\\n```\\n\\n**\uccb4\uc778 \ubcf5\uc81c \uad6c\uc131**\\n\\nreplica \uc11c\ubc84\uac00 \ub9ce\uc740 \uacbd\uc6b0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \uc804\ub2ec\ud558\ub294 \uc791\uc5c5 \uc790\uccb4\uac00 \ubd80\ud558\uac00 \ub420 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c 1:M:M \uad6c\uc870\ub85c \uccb4\uc778 \ubcf5\uc81c \uad6c\uc131\uc744 \uace0\ub824\ud560 \uc218 \uc788\ub2e4. \\n\\n```mermaid\\ngraph LR\\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\\n W -- \uc77d\uae30 --\x3e R1\\n S[Source] --\x3e R1[Replica1]\\n S --\x3e R2[Replica2]\\n S --\x3e R3[Replica3]\\n\\n R3 --\x3e R3-1[Replica 3-1]\\n R3 --\x3e R3-2[Replica 3-2]\\n\\n B[Batch Server] --\x3e R3-2\\n```\\n\\n**\ub4c0\uc5bc \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131**\\n\\n2\uac1c\uc758 MySQL \uc11c\ubc84 \ubaa8\ub450 \uc77d\uae30\uc640 \uc4f0\uae30\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d \ud558\ub294 \uad6c\uc131\uc774\ub2e4. \\n\uac01 \uc11c\ubc84\uc5d0\uc11c \ubcc0\uacbd\ub41c \ub370\uc774\ud130\ub294 \ub2e4\ub978 \uc11c\ubc84\uc5d0 \ubc18\uc601\ub41c\ub2e4. \\n\ubaa9\uc801\uc5d0 \ub530\ub77c ACTIVE-ACTIVE \ud615\ud0dc \ub610\ub294 ACTIVE-PASSIVE \ud615\ud0dc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. \\nACTIVE-PASSIVE \ud615\ud0dc\uc778 \uacbd\uc6b0 \uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131\uacfc \ub3d9\uc77c\ud574\ubcf4\uc774\uc9c0\ub9cc, ACTIVE \uc11c\ubc84\uc5d0\uc11c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uba74 \uc124\uc815\uc758 \ubcc0\uacbd\uc5c6\uc774 PASSIVE \uc11c\ubc84\ub85c \uc4f0\uae30 \uc791\uc5c5\uc744 \uc804\ud658\ud560 \uc218 \uc788\ub2e4\ub294 \uac83\uc774 \uc7a5\uc810\uc774\ub2e4. \\n\\n```mermaid\\ngraph LR\\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR1\\n W -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR2\\n SR1[Source/Replica 1] --\x3e SR2[Source/Replica 2]\\n```\\n\\n:::note ACTIVE-ACTIVE, ACTIVE-PASSIVE\\nACTIVE-ACTIVE: 2\uac1c\uc758 \uc11c\ubc84 \ubaa8\ub450 \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc \\nACTIVE-PASSIVE: \ud558\ub098\uc758 \uc11c\ubc84\uc5d0\uc11c\ub9cc \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc\\n:::\\n\\n**\uba40\ud2f0 \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131**\\n\\n\uc5ec\ub7ec\uac1c\uc758 source \uc11c\ubc84\uc640 \ud558\ub098\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \uad6c\uc131\uc774\ub2e4. \\n\uc774\ub294 source \uc11c\ubc84\uc758 \ub370\uc774\ud130\ub97c \ud55c \uacf3\uc5d0 \ubc31\uc5c5\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9, \uc5ec\ub7ec \uc11c\ubc84\uc5d0 \uc874\uc7ac\ud558\ub294 \ub370\uc774\ud130\ub97c \ud1b5\ud569, \uc0e4\ub529\ub418\uc5b4\uc788\ub294 \ud14c\uc774\ube14 \ub370\uc774\ud130\ub97c \ud1b5\ud569\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n S1[Source 1] --\x3e R[Replica]\\n S2[Source 2] --\x3e R\\n```\\n\\n## \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30\\n\\nmysql 2\ub300\ub97c \uc774\uc6a9\ud558\uc5ec replication\uc744 \uad6c\uc131\ud558\uace0, spring boot application\uc73c\ub85c source, replica \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc811\uadfc\ud574\ubcf4\ub294 \uc608\uc81c\uc774\ub2e4. \\n[https://github.com/bbiac/db-replication](https://github.com/bbiac/db-replication) \\n\\n### MySQL \ud658\uacbd \uad6c\uc131\\n\\nMySQL \ubc84\uc804\uc740 8.1\uc744 \uc0ac\uc6a9\ud588\ub2e4. \\n13306, 13307 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud574\uc11c MySQL \uc11c\ubc84 2\ub300\ub97c \ub744\uc6e0\ub2e4. \\n\ub610\ud55c \uc0ac\uc2e4 IP \ub300\uc5ed\uc73c\ub85c \ud1b5\uc2e0\ud560 \uc218 \uc788\ub3c4\ub85d \ucee4\uc2a4\ud140 \ub124\ud2b8\uc6cc\ud06c\ub97c \ucd94\uac00\ud588\ub2e4. \\n\\n```yml\\nversion: \'3.8\'\\n\\nservices:\\n source:\\n platform: linux/x86_64\\n image: mysql:latest\\n restart: always\\n container_name: mysql-source\\n environment:\\n TZ: \'Asia/Seoul\'\\n MYSQL_DATABASE: \'db\'\\n MYSQL_USER: \'user\'\\n MYSQL_PASSWORD: \'password\'\\n MYSQL_ROOT_PASSWORD: \'password\'\\n ports:\\n - \\"13306:3306\\"\\n volumes:\\n - db-source:/var/lib/mysql\\n - db-source:/var/lib/mysql-files\\n - ./docker/source.cnf:/etc/mysql/my.cnf\\n networks:\\n - mysql_network\\n\\n replica:\\n platform: linux/x86_64\\n image: mysql:latest\\n restart: always\\n container_name: mysql-replica\\n environment:\\n TZ: \'Asia/Seoul\'\\n MYSQL_DATABASE: \'db\'\\n MYSQL_USER: \'user\'\\n MYSQL_PASSWORD: \'password\'\\n MYSQL_ROOT_PASSWORD: \'password\'\\n ports:\\n - \\"13307:3306\\"\\n volumes:\\n - db-replica:/var/lib/mysql\\n - db-replica:/var/lib/mysql-files\\n - ./docker/replica.cnf:/etc/mysql/my.cnf\\n networks:\\n - mysql_network\\n\\nvolumes:\\n db-source:\\n db-replica:\\n\\nnetworks:\\n mysql_network:\\n driver: bridge\\n```\\n\\n\ub610\ud55c source, replica \uac01\uac01 \ub2e4\uc74c\uacfc \uac19\uc774 db \uc124\uc815\uc744 \ud588\ub2e4. \\n\\n| \uc124\uc815 | \uc124\uba85 |\\n| --- | --- |\\n| server_id | \uac01\uac01\uc758 mysql \ub9c8\ub2e4 \uace0\uc720\ud55c \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4. |\\n| log_bin | \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815\uc73c\ub85c \uc808\ub300\uacbd\ub85c\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 /var/lib/mysql \uc544\ub798 \ud574\ub2f9 log_bin\uc5d0 \uc124\uc815\ub41c \uac12\uc73c\ub85c \ub85c\uadf8\uac00 \uc0dd\uc131\ub41c\ub2e4. |\\n| sync_binlog | N\uac1c\uc758 \ud2b8\ub79c\uc7ad\uc158 \ub2f9 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ub514\uc2a4\ud06c\uc640 \ub3d9\uae30\ud654 \uc791\uc5c5\uc744 \ud558\ub3c4\ub85d \ud55c\ub2e4.\xa01\uc740 \uae30\ubcf8\uac12\uc73c\ub85c \uc548\uc815\uc801\uc774\uc9c0\ub9cc, \uac00\uc7a5 \ub290\ub9ac\ub2e4. |\\n| relay_log | \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815 |\\n| relay_log_purge | \ud544\uc694 \uc5c6\ub294 \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc744 \uc790\ub3d9\uc73c\ub85c \uc0ad\uc81c\ud558\ub294 \uc635\uc158 |\\n| read_only | \uc77d\uae30 \uc804\uc6a9 \uc124\uc815 |\\n| log_replica_updates | Replication SQL Thread\ub85c \uc778\ud574 \uc2e4\ud589\ub418\ub294 \uc815\ubcf4\ub97c \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc5d0 \uae30\ub85d \ucd94\ud6c4\uc5d0 \uc18c\uc2a4 \uc11c\ubc84\ub85c \uc2b9\uaca9\ub418\ub294 \uacbd\uc6b0\ub97c \uace0\ub824\ud558\uba74 \uc124\uc815\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. |\\n\\nimport Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n<Tabs>\\n<TabItem value=\\"Source\\" label=\\"Source\\">\\n\\n```cnf title=\\"/docker/source.cnf\\"\\n[mysqld]\\nserver_id=1\\nlog_bin=mysql-bin\\nsync_binlog=1\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"Replica\\" label=\\"Replica\\">\\n\\n```cnf title=\\"/docker/replica.cnf\\"\\n[mysqld]\\nserver_id=2\\nrelay_log=mysql-relay-bin\\nrelay_log_purge=ON\\nread_only\\nlog_replica_updates\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n### \ub3c4\ucee4 \uc2e4\ud589\\n\\ndocker-compose up \uba85\ub839\uc5b4\ub85c docker-compose \uc124\uc815\uc73c\ub85c docker\ub97c \ub744\uc6b4\ub2e4. \\n-d \uc635\uc158\uc744 \ubd99\uc774\uba74 \ubc31\uadf8\ub77c\uc6b4\ub4dc \ubaa8\ub4dc\ub85c \uc2e4\ud589\ub41c\ub2e4. \\n\\n```\\ndocker-compose up -d\\n```\\n\\n### replication slave \uad8c\ud55c \uc124\uc815\\n\\nREPLICATION SLAVE \uad8c\ud55c\uc774 \uc124\uc815\ub418\uc5b4 \uc788\uc5b4\uc57c replica \uc11c\ubc84\uc5d0\uc11c source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec \ub85c\uadf8\ub97c \uc77d\uc5b4\uc62c \uc218 \uc788\ub2e4. \\nsource \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec user \uacc4\uc815\uc5d0 \ud574\ub2f9 \uad8c\ud55c\uc744 \uc124\uc815\ud574\uc900\ub2e4. \\n\\nSOURCE \uc811\uc18d\\n\\n```bash\\ndocker exec -it mysql-source mysql -u root -p\\n```\\n\\nuser \uacc4\uc815\uc5d0 REPLICATION SLAVE \uad8c\ud55c \ucd94\uac00\\n\\n```mysql\\nGRANT REPLICATION SLAVE ON *.* TO \'user\'@\'%\';\\nFLUSH PRIVILEGES;\\n```\\n\\n### SOURCE DB \uc815\ubcf4 \ud655\uc778\\n\\nreplica \uc124\uc815\uc5d0 \ud544\uc694\ud55c source db\uc758 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c\uba85\uacfc Position\uc744 \ud655\uc778\ud55c\ub2e4. \\nPosition \uac12\uc740 \uc2e4\uc81c \ud30c\uc77c\uc758 \ubc14\uc774\ud2b8 \uc218\ub97c \uc758\ubbf8\ud55c\ub2e4. \\n\ud655\uc778\ud55c File(SOURCE_LOG_FILE)\uacfc Position(SOURCE_LOG_POS) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4.\\n\\n```mysql\\nSHOW MASTER STATUS;\\n\\n+------------------+----------+--------------+------------------+-------------------+\\n| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\\n+------------------+----------+--------------+------------------+-------------------+\\n| mysql-bin.000003 | 1082 | | | |\\n+------------------+----------+--------------+------------------+-------------------+\\n```\\n\\n### SOURCE ip \uc8fc\uc18c \ud655\uc778\\n\\ndocker inspect -f \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uba74 \ud574\ub2f9 \ucee8\ud14c\uc774\ub108\uc758 \uc138\ubd80 \uc815\ubcf4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud574 docker-compose \ud30c\uc77c\uc5d0 \uc124\uc815\ud574\ub454 mysql_network\uc5d0\uc11c \uc0ac\uc6a9\ub418\ub294 \uc0ac\uc124 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \ud655\uc778\ud55c\ub2e4. \\n\\n```bash\\ndocker inspect -f \\"{{with index .NetworkSettings.Networks \\\\\\"db-replication_mysql_network\\\\\\"}}{{.IPAddress}}{{end}}\\" mysql-source\\n```\\n\\nip \uc8fc\uc18c\uac00 \ub098\uc624\uc9c0 \uc54a\ub294 \uacbd\uc6b0 docker inspect mysql-source\ub85c \ud655\uc778\ud55c\ub2e4. \\n\ud655\uc778\ud55c IP\uc8fc\uc18c(SOURCE_HOST) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4.\\n\\n### replica mysql \uc811\uc18d\\n\\nsource db\uc5d0 \uc811\uc18d\ud588\ub358 \ubc29\ubc95\uacfc \ub3d9\uc77c\ud558\uac8c replica db\uc5d0 \uc811\uc18d\ud55c\ub2e4. \\n\\n```bash\\ndocker exec -it mysql-replica mysql -u root -p\\n```\\n\\n### replica \uc124\uc815\\n\\n\uc774\uc804\uc5d0 source db\uc5d0\uc11c \uc5bb\uc5c8\ub358 \uc815\ubcf4\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc5ec replica \uc124\uc815\uc744 \uc9c4\ud589\ud55c\ub2e4. \\n\uc2e4\uc81c DB \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc73c\ub85c source DB\uc758 \ud30c\uc77c\uc744 \ubcf5\uc81c\ud574\uc57c\ud558\uc9c0\ub9cc \ud604\uc7ac \ubcf5\uc81c\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ubd80\ubd84\uc740 \uc0dd\ub7b5\ud588\ub2e4. \\nSOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS \ub97c \uc801\uc808\ud788 \ubcc0\uacbd\ud55c\ub2e4.\\n\\n```mysql\\nSTOP REPLICA;\\n\\nCHANGE REPLICATION SOURCE TO \\nSOURCE_HOST=\'172.29.0.2\', \\nSOURCE_USER=\'user\', \\nSOURCE_PASSWORD=\'password\', \\nSOURCE_LOG_FILE=\'mysql-bin.000001\', \\nSOURCE_LOG_POS=0, \\nGET_SOURCE_PUBLIC_KEY=1;\\n\\nSTART REPLICA;\\n```\\n\\n### \uc124\uc815 \ud655\uc778\\n\\n```mysql\\nSHOW REPLICA STATUS;\\n\\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\\n| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |\\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\\n| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |\\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\\n```\\n\\nReplica_IO_Running, Replica_SQL_Running \uac12\uc774 YES\ub77c\uba74 \uc815\uc0c1\uc801\uc73c\ub85c replication \uad6c\uc131\uc774 \uc644\ub8cc\ub41c \uac83\uc774\ub2e4. \\n\\n\uc124\uc815\uc744 \ub9c8\uce5c \ud6c4 source db\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 create table \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud55c\ub2e4. \\nreplica db\uc5d0 \ub3d9\uc77c\ud55c member table\uc774 \uc0dd\uc131\ub41c \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n```sql\\nCREATE TABLE member\\n(\\n id BIGINT PRIMARY KEY AUTO_INCREMENT,\\n name VARCHAR(255)\\n);\\n```\\n\\n## \uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30\\n\\n\uc77c\ubc18\uc801\uc778 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 source, \uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158\uc778 \uacbd\uc6b0 replica\ub85c \uc694\uccad\uc774 \uac00\ub3c4\ub85d \uad6c\uc131\ud574\ubcf4\uc790. \\n\\n### Environment \uc124\uc815\\n\\n\ub2e4\uc74c\uacfc \uac19\uc774 source, replica\ub85c \uad6c\ubd84\ud558\uc5ec \uc124\uc815\ud55c\ub2e4. \\n\\n```yml title=\\"application.yml\\"\\nspring:\\n datasource:\\n source:\\n username: user\\n password: password\\n driver-class-name: com.mysql.cj.jdbc.Driver\\n jdbc-url: jdbc:mysql://localhost:13306/db\\n replica:\\n username: user\\n password: password\\n driver-class-name: com.mysql.cj.jdbc.Driver\\n jdbc-url: jdbc:mysql://localhost:13307/db\\n```\\n\\n### DataSourceType \uc124\uc815\\n\\n\ub2e8\uc21c \ubb38\uc790\uc5f4\ub85c\ub3c4 \uad6c\ubd84\ud560 \uc218 \uc788\uc9c0\ub9cc, enum\uc744 \uc774\uc6a9\ud574\uc11c \ud2b8\ub79c\uc7ad\uc158\uc744 \uad6c\ubd84\ud558\ub3c4\ub85d \uc0dd\uc131\ud55c\ub2e4. \\nKey\ub294 \ucd94\ud6c4\uc5d0 \ube48 \uc124\uc815\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n```java title=\\"DataSourceType\\"\\npublic enum DataSourceType {\\n SOURCE(SOURCE_NAME),\\n REPLICA(REPLICA_NAME),\\n ;\\n\\n private final String key;\\n\\n DataSourceType(String key) {\\n this.key = key;\\n }\\n\\n public static class Key {\\n public static final String ROUTING_NAME = \\"ROUTING\\";\\n public static final String SOURCE_NAME = \\"SOURCE\\";\\n public static final String REPLICA_NAME = \\"REPLICA\\";\\n }\\n}\\n```\\n\\n### AbstractRoutingDataSource \uc124\uc815\\n\\n\uc2a4\ud504\ub9c1\uc774 \uc9c0\uc6d0\ud574\uc8fc\ub294 AbstractRoutingDataSource\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSource\ub97c \ud5a5\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. \\n\\n\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub294 `Map<DataSourceKey, DataSource>`\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\uc744 \ubc1b\uc544 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4. \\n- setDefaultTargetDataSource: \uae30\ubcf8 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4. \\n- setTargetDataSources: \ub9f5 \ud615\ud0dc\ub85c \ubc1b\uc740 \ub370\uc774\ud130 \uc18c\uc2a4 \uac12\ub4e4\uc744 \uc124\uc815\ud55c\ub2e4. \\n\\ndetermineCurrentLookupKey\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. \\n- isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \ud2b8\ub79c\uc7ad\uc158\uc774 \uc77d\uae30 \uc804\uc6a9\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n- DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uace0, \ubc18\ud658\ud55c \uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ub370\uc774\ud130 \uc18c\uc2a4\uac00 \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n```java title=\\"RoutingDataSource\\"\\npublic class RoutingDataSource extends AbstractRoutingDataSource {\\n\\n private final Logger log = LoggerFactory.getLogger(getClass());\\n\\n public static RoutingDataSource from(Map<Object, Object> dataSources) {\\n RoutingDataSource routingDataSource = new RoutingDataSource();\\n routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));\\n routingDataSource.setTargetDataSources(dataSources);\\n return routingDataSource;\\n }\\n\\n @Override\\n protected Object determineCurrentLookupKey() {\\n boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();\\n\\n if (readOnly) {\\n log.info(\\"readOnly = true, request to replica\\");\\n return DataSourceType.REPLICA;\\n }\\n log.info(\\"readOnly = false, request to source\\");\\n return DataSourceType.SOURCE;\\n }\\n}\\n```\\n\\n### DataSource \uc124\uc815\\n\\n\uc704\uc5d0\uc11c\ubd80\ud130 \uc21c\uc11c\ub300\ub85c Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy \uc124\uc815\uc774\ub2e4. \\n\uc2a4\ud504\ub9c1\uc740 \ud2b8\ub79c\uc7ad\uc158 \uc2dc\uc791\uc2dc\uc5d0 \ucee4\ub125\uc158\uc758 \uc0ac\uc6a9\uc5ec\ubd80\uc640 \uc0c1\uad00\uc5c6\uc774 \ucee4\ub125\uc158\uc744 \ud655\ubcf4\ud55c\ub2e4. \\n\ub530\ub77c\uc11c readOnly \ud2b8\ub79c\uc7ad\uc158\uc774 \uc124\uc815\ub41c \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ubbf8\ub9ac \ud655\ubcf4\ub41c \ucee4\ub125\uc158\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 replica db\ub85c \uc694\uccad\uc744 \ud558\uc9c0 \uc54a\uace0 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4. \\n\\nTransactionSynchronizationManager.isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc \ud638\ucd9c \uc2dc currentTransactionReadOnly\ub77c\ub294 `ThreadLocal<Boolean>`\uc5d0 \uc124\uc815\ub41c \uac12\uc744 \ubc18\ud658\ud558\ub294\ub370 readOnly \uc124\uc815\uc774 \ub418\uba74 \uc774 \uac12\uc744 true\ub85c \uc124\uc815\ud55c\ub2e4. \ud558\uc9c0\ub9cc determineCurrentLookupKey\ub97c \ud638\ucd9c\ud558\uc5ec key \uac12\uc744 \uac00\uc838\uc624\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc774\ud6c4\uc5d0 \uc124\uc815\ub418\uae30 \ub54c\ubb38\uc5d0 determineCurrentLookupKey \uba54\uc11c\ub4dc\uc5d0\uc11c \ud56d\uc0c1 DataSourceType.SOURCE\uac00 \ubc18\ud658\ub418\uc5b4 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4. \\n\\nLazyConnectionDataSourceProxy\ub97c \uc124\uc815\ud558\ub294 \uacbd\uc6b0 \uc2e4\uc81c DataSource\ub97c \uc0ac\uc6a9\ud558\ub294 \uc2dc\uc810\uc5d0 \ucee4\ub125\uc158\uc744 \ud68d\ub4dd\ud574\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc124\uc815\ud55c\ub300\ub85c replica db\ub85c \uc870\ud68c \uc694\uccad\uc744 \ud55c\ub2e4. \\n\\n```java title=\\"DataSourceConfiguration\\"\\n@Configuration\\npublic class DataSourceConfiguration {\\n\\n @Bean\\n @Qualifier(SOURCE_NAME)\\n @ConfigurationProperties(prefix = \\"spring.datasource.source\\")\\n public DataSource sourceDataSource() {\\n return DataSourceBuilder.create().build();\\n }\\n\\n @Bean\\n @Qualifier(REPLICA_NAME)\\n @ConfigurationProperties(prefix = \\"spring.datasource.replica\\")\\n public DataSource replicaDataSource() {\\n return DataSourceBuilder.create().build();\\n }\\n\\n @Bean\\n @Qualifier(ROUTING_NAME)\\n public DataSource routingDataSource(\\n @Qualifier(SOURCE_NAME) DataSource sourceDataSource,\\n @Qualifier(REPLICA_NAME) DataSource replicaDataSource\\n ) {\\n return RoutingDataSource.from(Map.of(\\n DataSourceType.SOURCE, sourceDataSource,\\n DataSourceType.REPLICA, replicaDataSource\\n ));\\n }\\n\\n @Bean\\n @Primary\\n public DataSource dataSource(\\n @Qualifier(ROUTING_NAME) DataSource routingDataSource\\n ) {\\n return new LazyConnectionDataSourceProxy(routingDataSource);\\n }\\n}\\n```\\n\\n\ucd5c\uc885\uc801\uc73c\ub85c DataSource \ube48\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\uac00 \ub41c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n DSP[LazyConnectionDataSourceProxy] --\x3e RDS[RoutingDataSource]\\n\\tRDS --\x3e S[SourceDataSource]\\n\\tRDS --\x3e R[ReplicaDataSource]\\n```\\n\\n### \ub3d9\uc791 \ud655\uc778\\n\\n\uac04\ub2e8\ud558\uac8c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud574\uc11c \uc124\uc815\ud55c\ub300\ub85c \ub3d9\uc791\uc774 \ub418\ub294\uc9c0 \ud655\uc778\ud574\ubcf4\uc558\ub2e4. \\nsave \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 `@Transactional`, findById \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 `@Transactional(readOnly = true)`\uac00 \uc124\uc815\ub418\uc5b4\uc788\ub2e4. \\n\ub85c\uadf8\ub97c \ud1b5\ud574 save\uc758 \uacbd\uc6b0 source db\ub85c findById\uc758 \uacbd\uc6b0 replica db\ub85c \uc694\uccad\uc744 \ud558\ub294 \uac83\uc744 \uc54c \uc218 \uc788\ub2e4. \\n\\n```java title=\\"MemberServiceTest\\"\\n@SpringBootTest\\nclass MemberServiceTest {\\n\\n @Autowired\\n private MemberService memberService;\\n\\n @Test\\n void \uc0ac\uc6a9\uc790\ub97c_\uc800\uc7a5\ud55c\ub2e4() {\\n // RoutingDataSource log: readOnly = false\\n memberService.save(\\"bbiac\\");\\n }\\n\\n @Test\\n void \uc0ac\uc6a9\uc790\ub97c_\uc870\ud68c\ud55c\ub2e4() {\\n // RoutingDataSource log: readOnly = true\\n assertThatThrownBy(() -> memberService.findById(MAX_VALUE))\\n .isInstanceOf(NoSuchElementException.class);\\n }\\n}\\n```\\n\\nDB\uc5d0\uc11c\ub294 \ud655\uc778\ud558\ub824\uba74 root \uacc4\uc815\uc73c\ub85c \uc811\uc18d\ud55c \ud6c4 general log\ub97c \ud65c\uc131\ud654 \uc2dc\ud0a8\ub2e4. \\n\\n```sql\\nSET GLOBAL log_output = \'table\';\\nSET GLOBAL general_log = 1;\\n```\\n\\ngeneral log\ub97c \ud65c\uc131\ud654 \ud55c \ud6c4 \uc77d\uae30 \uc804\uc6a9 \uba54\uc11c\ub4dc\ub97c \uc2e4\ud589\ud55c\ub2e4. \\nserver_id, \uc2e4\ud589\ud55c \ucffc\ub9ac\ubb38\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n```sql\\nSELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like \'%select%\';\\n\\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\\n| user_host | thread_id | server_id | convert(argument using utf8) |\\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\\n| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |\\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\\n```\\n\\n\ud655\uc778 \ud6c4 general log\ub97c \ube44\ud65c\uc131\ud654 \ud55c \ud6c4 \ube44\ud65c\uc131\ud654 \ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. \\n```sql\\nSET GLOBAL general_log = 0;\\nSHOW VARIABLES LIKE \'%general%\';\\n\\n+------------------+---------------------------------+\\n| Variable_name | Value |\\n+------------------+---------------------------------+\\n| general_log | OFF |\\n| general_log_file | /var/lib/mysql/4b6b9db98290.log |\\n+------------------+---------------------------------+\\n```\\n\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n16\uc7a5 \ubcf5\uc81c, Real MySQL 8.0 - \ubc31\uc740\ube48, \uc774\uc131\uc6b1 \\n[Replication, MySQL Docs](https://dev.mysql.com/doc/refman/8.1/en/replication.html) \\n[MySql - Master Slave Replication \uad6c\uc870 \ub9cc\ub4e4\uc5b4\ubcf4\uae30](https://huisam.tistory.com/entry/mysql-replication) \\n[Spring \ub808\ud50c\ub9ac\ucf00\uc774\uc158 \ud2b8\ub79c\uc7ad\uc158 \ucc98\ub9ac \ubc29\uc2dd](https://cheese10yun.github.io/spring-transaction/) \\n[replication-datasource](https://github.com/kwon37xi/replication-datasource) \\n[Simplified Guide to MySQL Replication with Docker Compose](https://www.linkedin.com/pulse/simplified-guide-mysql-replication-docker-compose-rakesh-shekhawat/) \\n[Dockerfile\uc5d0\uc11c \uc790\uc8fc \uc4f0\uc774\ub294 \uba85\ub839\uc5b4](https://www.daleseo.com/dockerfile/) \\n[CHANGE REPLICATION SOURCE TO Statement](https://dev.mysql.com/doc/refman/8.1/en/change-replication-source-to.html) \\n[LazyConnectionDataSourceProxy](https://kwonnam.pe.kr/wiki/springframework/lazyconnectiondatasourceproxy) \\n[\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub808\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ud1b5\ud55c \ucffc\ub9ac \uc131\ub2a5 \uac1c\uc120 (feat. Mysql, SpringBoot)](https://hudi.blog/database-replication-with-springboot-and-mysql/) \\n[\ubd80\ud558 \ubd84\uc0b0\uc744 \uc704\ud55c MySQL Replication \uad6c\uc131 \ubc0f \ucffc\ub9ac \uc694\uccad \ubd84\uae30](https://chagokx2.tistory.com/100) \\n[Use Docker Compose, Docker](https://docs.docker.com/get-started/08_using_compose/)"},{"id":"woowacourse-level3-retrospective","metadata":{"permalink":"/woowacourse-level3-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx","source":"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx","title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0","description":"\ud68c\uace0","date":"2023-08-19T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 19\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.945,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0","slug":"woowacourse-level3-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30","permalink":"/db-replication"},"nextItem":{"title":"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","permalink":"/cloudwatch"}},"content":"import logo from \'./logo.png\';\\n\\n### \ud68c\uace0\\n\\n\uc9c0\ub09c 8\uc8fc\ub294 \ub808\ubca8 1, 2 \ub54c\ubcf4\ub2e4 5\ubc30 \uc815\ub3c4 \ube60\ub974\uac8c \uc9c0\ub098\uac04 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4. \\n\ub808\ubca8 3\uc5d0\ub294 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4, \uae30\uc220 \uc678\uc801\uc778 \ubd80\ubd84\uc5d0\uc11c\ub3c4 \ubd80\uc871\ud568\uc774 \ub9ce\uc774 \ubcf4\uc600\ub358 \uac83 \uac19\ub2e4. \\n\ubd80\uc871\ud55c \ubd80\ubd84\uc744 \uc54c\uc558\uae30\uc5d0, \uc55e\uc73c\ub85c \ub354\uc6b1 \uc131\uc7a5\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. \\n\ub0b4\uac00 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \ud300\uc6d0\ub4e4\uc774 \uc798 \ubcf4\ucda9\ud574 \uc918\uc11c \ub4e0\ub4e0\ud588\ub2e4. \\n\\n### \uc544\uc26c\uc6b4 \uc810\\n\\n**\ubb38\uc11c\ud654**\\n\\n\uac1c\uc778\uc801\uc73c\ub85c\ub294 \uae30\uc220 \uc678\uc801\uc73c\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ub0b4\uac00 \ud55c \ubd80\ubd84\uc744 \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c, \uc774\ud574\ud558\uae30 \uc27d\uac8c \ubb38\uc11c\ud654\ub97c \ud588\ub354\ub77c\uba74 \ud300\uc6d0\ub4e4\uc5d0\uac8c \ub354\uc6b1 \ub3c4\uc6c0\uc774 \ub418\uc5c8\uc744 \ud150\ub370 \uc774 \ubd80\ubd84\uc5d0 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ud22c\uc790\ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc5d0\uc11c \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4. \\n\ubc29\ud559 \uae30\uac04 \ub3d9\uc548 \ubb38\uc11c\ud654\ub97c \ud558\uc9c0 \ubabb\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc778 \ube14\ub85c\uadf8 \uc62c\ub9ac\uba74\uc11c \uc870\uae08 \ub354 \ucc44\uc6cc\ubcf4\ub824\uace0 \ud55c\ub2e4. \\n\\n**\ub0b4\uac00 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc774\uc790**\\n\\n\uc798 \ubabb\ud558\ub294 \ubd80\ubd84\uc774\ub77c\uba74 \uc2dc\uac04\uc744 \ub4e4\uc5ec\uc11c\ub77c\ub3c4 \uc911\uac04\uc740 \uac00\ub3c4\ub85d \ud574\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4. \\n\ub9d0\uc744 \ud558\uae30 \uc804\uc5d0 \uc815\ub9ac\ud574\uc11c \uc758\uacac\uc744 \ub0b4\ub294 \uac83, \ubc1c\ud45c \uc900\ube44, \uac10\uc815 \uc870\uc808 \ub4f1\ub4f1\\n\ubabb\ud558\ub294 \ubd80\ubd84\uc744 \uc778\uc9c0\ud558\uace0, \uac1c\uc120\ud558\uc790. \\n\\n**\ucef4\ud3ec\ud2b8 \uc874 \ubc97\uc5b4\ub098\uae30**\\n\\n\uc870\uae08 \ub354 \ub3c4\uc804\uc801\uc73c\ub85c \ubaa9\ud45c\ub97c \uc7a1\uc558\uc73c\uba74 \uc88b\uc558\uc744 \uac83 \uac19\ub2e4. \\n\ub9e4\ubc88 \uadfc\uac70\ub97c \uac00\uc9c0\uace0 \uae30\uc220\uc744 \ub3c4\uc785\ud558\uace0, \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\ud558\uc9c0\ub9cc \uc9c0\uc18d\uc801\uc73c\ub85c \uac1c\uc120\ud558\ub824\uace0 \ud558\ub294 \ubd80\ubd84\uc774 \ub2e4\uc18c \ubd80\uc871\ud588\ub2e4. \\n\\n### \uc88b\uc558\ub358 \uc810\\n\\n**\uc88b\uc558\ub358 \uc810\ub3c4 \ubb38\uc11c\ud654**\\n\\n[\ud300 \ube14\ub85c\uadf8](https://tripdraw.blog)\ub3c4 \uba3c\uc800 \ub3c4\uc785\ud558\uc790\uace0 \uc81c\uc548\ud558\uace0, \ub0b4\uac00 \ud588\ub358 \ubd80\ubd84\uc740 \ubb38\uc11c\ud654\ub97c \uaf64 \ub9ce\uc774 \ud574\uc11c \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ubc31\uc5d4\ub4dc \ud06c\ub8e8 4\uba85\uc774\uc11c \uac19\uc774 \ud55c \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c\ub294 \uae30\ub2a5 \uad6c\ud604\ud55c\ub2e4\uace0 \ubb38\uc11c\ud654\uac00 \uc870\uae08 \ubbf8\ud761\ud574\uc11c \ubcf4\ucda9\uc744 \ud574\uc57c\uaca0\ub2e4. \\n\\n**\ub0b4\uac00 \ub514\uc790\uc778\ud55c \ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0**\\n\\n<img src={logo} width=\\"100\\"/>\\n\\n\ud2b8\ub9bd\ub4dc\ub85c\uc6b0 \ub85c\uace0\ub97c \ub9cc\ub4e4\uc5c8\ub2e4. \\n\ud300\uc6d0\ub4e4\uc774 \ub300\ud45c \uc0c9\uc0c1(\ud30c\ub780\uc0c9)\uc744 \uc815\ud574\uc92c\uace0, \uc8fc\ub9d0 \ub3d9\uc548 \uc2e0\ub098\uac8c \ub85c\uace0 \ub514\uc790\uc778\uc744 \ud588\ub358 \uac83 \uac19\ub2e4. \\n\uc544\ub798\uc758 D \ubd80\ubd84\uc740 \uc720\ud29c\ube0c \uac15\uc758 \ub4e4\uc73c\uba74\uc11c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\uc11c \ubfcc\ub4ef\ud558\ub2e4. \\n\\n**\uae30\uc220 \uc120\ud0dd\uc758 \uc774\uc720**\\n\\n\uae30\uc220\uc758 \ud559\uc2b5 \ube44\uc6a9, \ud604\uc7ac \uad6c\uc870\uc5d0 \uc801\ud569\ud55c\uc9c0, \uc2e4\uc81c \uac00\uc9c0\uace0 \uc788\ub294 \ub9ac\uc18c\uc2a4\ub97c \uace0\ub824\ud574\uc11c \uae30\uc220 \uc120\ud0dd\uc744 \ud558\uace0, \ub3c4\uc785\ud588\ub358 \ubd80\ubd84\uc774 \uc88b\uc558\ub2e4. \\n100% \uc88b\uc740 \uc120\ud0dd\uc77c \uc21c \uc5c6\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \uc120\ud0dd\uc5d0 \ub300\ud55c \uadfc\uac70\uac00 \uc874\uc7ac\ud55c\ub2e4\uba74 \ud655\ub960\uc744 \ub192\ud600\uc8fc\ub294 \uac83 \uac19\ub2e4. \\n\\n### \ub9c8\uce58\uba70\\n\\n\ud50c\ub808\uc774\uc2a4\ud1a0\uc5b4\uc5d0 \uc571\uc774 \uc62c\ub77c\uac00 \uc788\ub294 \uac70 \ub108\ubb34 \uc2e0\uae30\ud558\ub2e4. \\n\uc548\ub4dc\ub85c\uc774\ub4dc \ube0c\ub808\uba58 \uc74c\uc545\ub300(\uba67\ub3fc\uc9c0, \uc218\ub2ec, \ud551\uad6c), \uadf8\ub9ac\uace0 \ubc31\uc5d4\ub4dc \ud300\uc6d0\ub4e4(\uccb4\uc778\uc800, \ud6c4\ucd94, \ub9ac\uc624) \ub108\ubb34 \uace0\uc0dd\uc774 \ub9ce\uc558\ub2e4."},{"id":"cloudwatch","metadata":{"permalink":"/cloudwatch","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md","source":"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md","title":"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","description":"CloudWatch","date":"2023-08-17T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 17\uc77c","tags":[{"label":"cloudwatch","permalink":"/tags/cloudwatch"},{"label":"log","permalink":"/tags/log"},{"label":"monitoring","permalink":"/tags/monitoring"}],"readingTime":5.35,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","slug":"cloudwatch","tags":["cloudwatch","log","monitoring"]},"unlisted":false,"prevItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0","permalink":"/woowacourse-level3-retrospective"},"nextItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac","permalink":"/route-image-async-with-event"}},"content":"## CloudWatch\\n\\nAWS \ub9ac\uc18c\uc2a4\uc640 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc9c0\ud45c\uc640 \ub85c\uadf8\uc5d0 \ub300\ud55c \ubaa8\ub2c8\ud130\ub9c1\uc744 \uc81c\uacf5\ud558\ub294 \uc11c\ube44\uc2a4\ub2e4. \\n\uc9c0\ud45c\ub97c \uac10\uc2dc\ud558\uc5ec \uc54c\ub9bc\uc744 \ubcf4\ub0b4\ub294 \uae30\ub2a5\ub3c4 \uc81c\uacf5\ud55c\ub2e4. \\n\ud504\ub9ac\ud2f0\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \ub300\uc2dc\ubcf4\ub4dc\ub2f9 3$/M \uc758 \ube44\uc6a9\uc774 \uccad\uad6c\ub418\uace0, \uc9c0\ud45c\ub098 \ub85c\uadf8\uc758 \uc591\uc5d0 \ub530\ub77c \ube44\uc6a9\uc774 \ucd94\uac00\uc801\uc73c\ub85c \uccad\uad6c\ub41c\ub2e4. \\n\uc694\uae08 \uc815\ubcf4\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc815\ubcf4\ub294 [\ub2e4\uc74c \ub9c1\ud06c](https://aws.amazon.com/ko/cloudwatch/pricing/)\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n## CloudWatch Metrics\\n\\n\uae30\ubcf8\uc801\uc73c\ub85c 5\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc218\uc9d1\ub41c\ub2e4. \\n\uc138\ubd80 \ubaa8\ub2c8\ud130\ub9c1(Detailed Monitoring)\uc744 \ud65c\uc131\ud654\ud558\uba74 1\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\ub97c \uc218\uc9d1\ud55c\ub2e4. \\n\ub300\uc2dc\ubcf4\ub4dc\uc5d0\uc11c InstanceId\ub85c \uac80\uc0c9\ud558\uc5ec \uc218\uc9d1\ub41c \uc9c0\ud45c\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.\\n\\n![./cloudwatch1.png](./cloudwatch1.png)\\n\\nCPUUtilization, NetworkIn, NetworkOut\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 \uc9c0\ud45c\ub97c \uc81c\uacf5\ud558\uace0, \uba54\ubaa8\ub9ac, \ub514\uc2a4\ud06c \uacf5\uac04\uacfc \uac19\uc740 \uc9c0\ud45c\ub97c \ud655\uc778\ud558\ub824\uba74 \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\ub97c \uc124\uc815\ud574\uc57c \ud55c\ub2e4.\\n\\n## CloudWatch Agent \uc124\uce58\\n\\nCloudWatch Agent \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\uc640 \ub85c\uadf8\ub97c \uc218\uc9d1\ud560 \uc218 \uc788\ub2e4. \\n\\n### IAM \uc5ed\ud560 \uc124\uc815\\n\\n\uae30\ubcf8\uc801\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4\uac00 CloudWatchAgentServerPolicy\uc5d0 \ub300\ud55c \uad8c\ud55c\uc774 \uc788\uc5b4\uc57c \ud55c\ub2e4. \\nIAM \u2192 \uc5ed\ud560\uc5d0\uc11c \uc5ed\ud560 \uc0dd\uc131\uc744 \ud074\ub9ad\ud55c\ub2e4.\\n\\n![./cloudwatch2.png](./cloudwatch2.png)\\n\\nCloudWatchAgentServerPolicy \uad8c\ud55c \uc815\ucc45\uc744 \uc120\ud0dd\ud558\uace0, \uc801\ub2f9\ud55c \uc5ed\ud560 \uc774\ub984\uc744 \uc785\ub825\ud574\uc11c \uc5ed\ud560\uc744 \uc0dd\uc131\ud55c\ub2e4.\\n\\n![./cloudwatch3.png](./cloudwatch3.png)\\n\\nEC2 \uc778\uc2a4\ud134\uc2a4 \ubaa9\ub85d\uc73c\ub85c \ub4e4\uc5b4\uac00\uc11c, CloudWatch Agent\ub97c \uc124\uce58\ud560 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud074\ub9ad\ud55c\ub2e4. \\n\uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc5d0\uc11c \uc774\uc804\uc5d0 \uc0dd\uc131\ud55c \uc5ed\ud560\uc744 \uc9c0\uc815\ud55c\ub2e4.\\n\\n![./cloudwatch4.png](./cloudwatch4.png)\\n\\n### \uc124\uce58\\n\\n\ud658\uacbd\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\nOS: ubuntu 22.04 \\n\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small (ARM64) \\n\\n\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uce58\ud55c\ub2e4.\\n\\n```bash\\nwget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb\\nsudo dpkg -i -E ./amazon-cloudwatch-agent.deb\\n```\\n\\n[\uc0ac\uc6a9 \uc124\uba85\uc11c](https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html)\uc5d0 \uac01 \uc778\uc2a4\ud134\uc2a4 \uc720\ud615\ub9c8\ub2e4 \ub2e4\uc6b4\ub85c\ub4dc \ub9c1\ud06c\uac00 \uc790\uc138\ud558\uac8c \uc548\ub0b4\ub418\uc5b4 \uc788\ub2e4.\\n\\n### Wizard\\n\\nCloudWatch Wizard\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uc124\uc815 \ud30c\uc77c \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4. \\n\ub85c\uadf8\ub97c \uc218\uc9d1\ud558\ub3c4\ub85d \uc124\uc815\ud558\ub294 \uacbd\uc6b0 Wizard \uc2e4\ud589 \uba85\ub839\uc5b4 \uc785\ub825 \uc804 log \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \ubcf5\uc0ac\ud574\ub450\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec Wizard\ub97c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4. \\n\\n```bash\\nsudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard\\n```\\n\\n\uc124\uc815\uc744 \uc9c4\ud589\ud558\ub2e4 \ubcf4\uba74 \uc124\uc815 \ud30c\uc77c\uc774 \uc5b4\ub5bb\uac8c \uad6c\uc131\ub420\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\ub85c\uadf8\ub97c \ucd94\uac00\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \uc785\ub825\ucc3d\uc774 \ub098\uc624\uba74 \uc900\ube44\ud574\ub480\ub358 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \uc785\ub825\ud55c\ub2e4. \\n\\n![./cloudwatch5.png](./cloudwatch5.png)\\n\\n\uc911\uac04\uc5d0 SSM parameter store\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \uc800\uc7a5\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4. \\n\\n```bash\\nDo you want to store the config in the SSM parameter store?\\n1. yes\\n2. no\\n```\\n\\n\ucd94\uac00\uc801\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 2\ubc88\uc744 \uc120\ud0dd\ud55c\ub2e4. \\nParameter Store \uad00\ub9ac\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uc758 [\ubb38\uc11c](https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/)\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac70 \uac19\ub2e4. \\n\uc124\uc815\uc774 \uc644\ub8cc\ub418\uba74 `/opt/aws/amazon-cloudwatch-agent/bin/config.json` \uc5d0 \uc124\uc815\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc774 \uc800\uc7a5\ub41c\ub2e4. \\n\\n### \uc124\uc815 \ud30c\uc77c \uc801\uc6a9\\n\\n\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uc815\ud30c\uc77c\uc744 \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4. \\nfile \ub4a4\uc5d0\ub294 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub300\ud55c \uc808\ub300\uacbd\ub85c(\uc544\ub798 \uba85\ub839\uc5b4 \uae30\uc900 \uae30\ubcf8 \uc0dd\uc131 \uc704\uce58)\ub97c \uc785\ub825\ud558\uba74 \ub41c\ub2e4. \\n\\n```bash\\nsudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json\\n```\\n\\n### types.db: no such file or directory \uc5d0\ub7ec\\n\\n\ub2e4\uc74c\uacfc \uac19\uc740 \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 types.db \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4.\\n\\n```bash\\nError running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory\\n```\\n\\ntypes.db \ud30c\uc77c \uc0dd\uc131\\n\\n```bash\\nsudo mkdir /usr/share/collectd\\nsudo touch /usr/share/collectd/types.db\\n```\\n\\n### \uc9c0\ud45c \ud655\uc778\\n\\nCloudWatch Metrics\uc5d0 \uac00\ubcf4\uba74 CWAgent\ub77c\ub294 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\uac00 \ucd94\uac00\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. \\n\\n![./cloudwatch6.png](./cloudwatch6.png)\\n\\n\ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ucd94\uac00\ud558\uc5ec \uc9c0\ud45c\uc5d0 \ub300\ud55c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4. \\n\\n```json\\n{\\n \\"metrics\\": {\\n \\"namespace\\": \\"2023-hello-world\\",\\n ......\\n },\\n} \\n```\\n\\n### \ub85c\uadf8\\n\\nCloudWatch \u2192 \ub85c\uadf8 \uadf8\ub8f9\uc73c\ub85c \uac00\uba74 Wizard\ub85c \ucd94\uac00\ud55c \ub85c\uadf8\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.\\n\\n![./cloudwatch7.png](./cloudwatch7.png)\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n[CloudWatch\ub780 \ubb34\uc5c7\uc785\ub2c8\uae4c?](https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html) \\n[Amazon CloudWatch \uc694\uae08](https://aws.amazon.com/ko/cloudwatch/pricing/) \\n[Linux \uc778\uc2a4\ud134\uc2a4 \uc9c0\ud45c](https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html) \\n[\uc11c\ubc84\uc5d0 CloudWatch \uc5d0\uc774\uc804\ud2b8 \uc124\uce58 \ubc0f \uc2e4\ud589](https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html) \\n[CloudWatch Agent\ub97c Parameter Store\uc5d0\uc11c \uad00\ub9ac\ud574 \ubcf4\uae30](https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/) \\n[CloudWatch\uc5d0\uc774\uc804\ud2b8 \uad6c\uc131 \ud30c\uc77c](https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html)"},{"id":"route-image-async-with-event","metadata":{"permalink":"/route-image-async-with-event","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx","source":"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx","title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac","description":"\uc774\uc804 \uae00","date":"2023-08-13T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 13\uc77c","tags":[{"label":"async","permalink":"/tags/async"},{"label":"event","permalink":"/tags/event"}],"readingTime":11.2,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac","slug":"route-image-async-with-event","tags":["async","event"]},"unlisted":false,"prevItem":{"title":"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","permalink":"/cloudwatch"},"nextItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604","permalink":"/route-image-implementation"}},"content":"## \uc774\uc804 \uae00\\n\\n[\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd](./route-image-intro) \\n[\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604](./route-image-implementation)\\n\\n## \uac1c\uc694\\n\\n\ud604\uc7ac \uc5ec\ud589\uc744 \ub9c8\uce58\ub294 \uacbd\uc6b0, \uac10\uc0c1\uc744 \uc0dd\uc131\ud558\ub294 \uacbd\uc6b0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. \\n\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \uc704\uce58 \uc815\ubcf4\uc758 \uac1c\uc218\uc5d0 \uc815\ube44\ub840\ud558\uc5ec \uc0dd\uc131 \uc2dc\uac04\uc774 \uc99d\uac00\ud55c\ub2e4. \\n\ub530\ub77c\uc11c \ube44\ub3d9\uae30\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\uc5ec \uc0ac\uc6a9\uc790\uc758 \uacbd\ud5d8\uc744 \uac1c\uc120\uc2dc\ud0ac \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n### \uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120\\n\\n\uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc774 \uc8fc\uae30\ub2a5\uc774\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ubd80\uae30\ub2a5\uc774\ub2e4. \\n\ud558\uc9c0\ub9cc \ud604\uc7ac \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc758 \uc751\ub2f5 \uc18d\ub3c4\uac00 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uace0 \uc788\ub2e4. \\n\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uc5ec\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4. \\n\uc18c\uc694 \uc2dc\uac04\uc774 1\ucd08 \uc774\uc0c1 \uac78\ub9ac\ub294 \uacbd\uc6b0\uac00 \uc874\uc7ac\ud558\uae30\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uace0 \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131 \uae30\ub2a5\uc758 \uc751\ub2f5 \uc2dc\uac04\uc744 \uac1c\uc120\ud558\ub294 \uac83\uc774 \ub354 \uc911\uc694\ud558\ub2e4. \\n\\n### \ud655\uc7a5\uc131 \ub300\ube44\\n\\n\ud604\uc7ac 10\ubd84 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc11c\ubc84\uc5d0 \uc800\uc7a5\ud558\uace0 \uc788\ub2e4. \\n\uc870\uae08 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uadf8\ub9ac\ub294 \uacbd\uc6b0 \ud558\ub098\uc758 \uc5ec\ud589\uc5d0 \ub9ce\uc740 \uc704\uce58 \uc815\ubcf4\uac00 \uc800\uc7a5\ub420 \uc218\ubc16\uc5d0 \uc5c6\uace0 \ub530\ub77c\uc11c \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uac78\ub9ac\ub294 \uc2dc\uac04\uc774 \ub354 \uae38\uc5b4\uc9c8 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c \ucd94\ud6c4\uc5d0 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \uacbd\uc6b0\ub97c \ub300\ube44\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\ub294 \uac83\uc774 \ud569\ub2f9\ud558\ub2e4. \\n\\n## \ube44\ub3d9\uae30 \ucc98\ub9ac\\n\\n@Async\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uba54\uc11c\ub4dc\ub97c \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ub9cc\ub4e4 \uc218 \uc788\ub2e4. \\n\\n### \ube44\ub3d9\uae30 \uc124\uc815\\n\\n\uc0ac\uc6a9\ud558\uae30 \uc804\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c EnableAsync \uc124\uc815\uc744 \ud574\uc57c\ud55c\ub2e4. \\n\ud574\ub2f9 \uc124\uc815\uc744 \uc801\uc6a9\ud558\uba74 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc\uc5d0 @Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec\uc8fc\uae30\ub9cc \ud558\uba74 \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud55c\ub2e4. \\n\\n```java title=\\"AsyncConfig\\"\\n@EnableAsync\\n@Configuration\\npublic class AsyncConfig {\\n}\\n```\\n\\n\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \ud560 \ub54c \ub9e4\ubc88 \uc0c8\ub85c\uc6b4 \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ub808\ub4dc \ud480 \uc124\uc815\uc744 \ub530\ub85c \ud574\uc918\uc57c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ThreadPoolTaskExecutor\ub97c \ub530\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc544\ub3c4 \uae30\ubcf8\uc801\uc73c\ub85c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uac00 \uc0dd\uc131\uc744 \ub3c4\uc640\uc900\ub2e4. \\n\\n> In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing.\\n> 7.7. Task Execution and Scheduling, Spring Boot Docs\\n\\n### @Async \uc801\uc6a9\\n\\n\uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\uc5d0 Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ud55c\ub2e4. \\n\\n```java title=\\"RouteImageGenerator\\"\\n@Async\\npublic void generate(\\n List<Double> latitudes,\\n List<Double> longitudes,\\n List<Double> pointedLatitudes,\\n List<Double> pointedLongitudes,\\n Long tripId\\n) {\\n // \uc774\ubbf8\uc9c0 \uc0dd\uc131\\n RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);\\n Coordinates coordinates = Coordinates.of(latitudes, longitudes);\\n Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);\\n drawImage(coordinates, routeImageDrawer, pointedCoordinates);\\n\\n // \uc774\ubbf8\uc9c0 \uc800\uc7a5\\n String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());\\n\\n // \uc790\uc6d0 \ud560\ub2f9 \ud574\uc81c\\n routeImageDrawer.dispose();\\n\\n // \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac12 \ubcc0\uacbd\\n Trip trip = tripRepository.findById(tripId)\\n .orElseThrow();\\n trip.changeRouteImageUrl(imageUrl);\\n tripRepository.save(trip);\\n}\\n```\\n\\n### \ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810\\n\\n\ud604\uc7ac \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uace0 \uc800\uc7a5 \ud6c4, \uc800\uc7a5 \uacbd\ub85c\ub97c DB\uc5d0 \ubc18\uc601\ud574\uc57c \ud55c\ub2e4. \\n\ub530\ub77c\uc11c \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ud615\ud0dc\uac00 \ub418\uba70 \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \ubb38\uc81c\uac00 \uc0dd\uae34\ub2e4. \\n\\n```mermaid\\ngraph LR\\n trip[trip: \uc5ec\ud589 \uad00\ub828 \ud328\ud0a4\uc9c0] --\x3e draw[draw: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294 \ud328\ud0a4\uc9c0]\\n draw --\x3e trip\\n```\\n\\n\uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uacfc \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4. \\n\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4. \\n\\n```mermaid\\ngraph LR\\n\\tsubgraph draw\\n\\t\\tdirection LR\\n\\t\\tRG[RouteImageGenerator] -- DB \ubc18\uc601 \uc694\uccad --\x3e ILR[ImageLinkTripRepository]\\n\\tend\\n subgraph trip\\n\\t\\tdirection LR\\n\\t\\tTS[TripService] -- \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e RG\\n\\t\\tILRI[ImageLinkTripRepositoryImpl] -- \uad6c\ud604 --\x3e ILR\\n\\tend\\n\\n\\ttrip --\x3e draw\\n```\\n\\n\ud328\ud0a4\uc9c0 \uac04 \uc758\uc874\uc131\uc740 \ud574\uacb0\ub418\uc5c8\uc9c0\ub9cc, \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5\uc744 \uc704\ud574 tripId\ub97c \ubc1b\uc544\uc57c\ud558\ub294 \ub4f1\uc758 \ub17c\ub9ac\uc801\uc778 \uc758\uc874\uc131\uc740 \uc544\uc9c1 \ud574\uacb0\ub418\uc9c0 \uc54a\uc558\ub2e4. \\n\ub530\ub77c\uc11c \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4. \\n\\n## \uc774\ubca4\ud2b8 \uc0ac\uc6a9\\n\\n\uc2a4\ud504\ub9c1\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uba74 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc758 \ube44\uad00\uc2ec\uc0ac(ex. \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131)\uc744 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4.\\n\\n### \uc774\ubca4\ud2b8 \ubc1c\ud589\\n\\n\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \uba3c\uc800 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud574\uc57c \ud55c\ub2e4. \\n\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 ApplicationEventPublisher \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \uc218 \uc788\ub2e4. \\n\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c ApplicationContext\uac00 \uad6c\ud604\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud55c\ub2e4. \\n\\n```java title=\\"TripService & TripUpdateEvent\\"\\npublic void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {\\n ...\\n\\n // \uc774\ubca4\ud2b8 \ubc1c\ud589\\n applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));\\n}\\n\\npublic record TripUpdateEvent(Long tripId) {\\n}\\n```\\n\\n\uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \ub54c \ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc774 \uc911\uc694\ud558\ub2e4. \\n\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\ub294 \ub3c4\uba54\uc778\uc758 \ud589\uc704\ub97c \ub2f4\uace0 \uc788\ub294 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589(ex. RouteImageGenerateEvent)\ud55c\ub2e4\uba74 \ub17c\ub9ac\uc801\uc778 \uc758\uc874 \uad00\uacc4\uac00 \ub0a8\uc544\uc788\uae30\uc5d0 \uc774\ubca4\ud2b8\ub97c \uc801\uc808\ud788 \uc0ac\uc6a9\ud588\ub2e4\uace0 \ubcf4\uae30 \uc5b4\ub835\ub2e4. \\n\ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc740 \uc8fc\uae30\ub2a5\uc774 \uc5b4\ub5a4 \ud589\uc704(ex. TripUpdateEvent)\ub97c \ud588\ub294\uc9c0\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \ub2f4\uaca8\uc788\ub294 \uc774\ubca4\ud2b8\uba85\uc73c\ub85c \ubc1c\ud589\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4. \\n\\n### \uc774\ubca4\ud2b8 \uad6c\ub3c5\\n\\n\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc2e4\ud589\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\uae30 \uc704\ud558\uc5ec `@Async` \uc560\ub108\ud14c\uc774\uc158\uc744 \uc801\uc6a9\ud588\ub2e4. \\n\uc774\ubca4\ud2b8\uc758 \uad6c\ub3c5\uc740 \uc5ec\ud589\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \uc885\ub8cc\ub420 \ub54c \uc5ec\ud589\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \uac00\uc9c0\uace0 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud574 `@TransactionalEventListener`\ub97c \uc0ac\uc6a9\ud588\ub2e4. \\n\\n:::note TransactionPhase \uc124\uc815\\nTransactionPhase\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \uc774\ubca4\ud2b8\ub97c \uc5b4\ub5a4 \ub2e8\uacc4\uc5d0\uc11c \uc218\uc2e0\ud558\uace0 \ucc98\ub9ac\ud560\uc9c0\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.\\n\\nAFTER_COMMIT(\uae30\ubcf8\uac12): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ucee4\ubc0b \ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589 \\nAFTER_ROLLBACK: \ud2b8\ub79c\uc7ad\uc158\uc774 \ub864\ubc31\ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589 \\nAFTER_COMPLETION: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub610\ub294 \ub864\ubc31 \ub418\uc5c8\uc744 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589 \\nBEFORE_COMMIT: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub418\uae30 \uc804 \uc774\ubca4\ud2b8 \uc2e4\ud589 \\n:::\\n\\n\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uae30 \uc704\ud574 @Transactional \uc560\ub108\ud14c\uc774\uc158\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4. \\n\\n```java title=\\"TripUpdateEventHandler\\"\\n@Component\\npublic class TripUpdateEventHandler {\\n\\n private final RouteImageGenerator routeImageGenerator;\\n private final TripRepository tripRepository;\\n\\n public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {\\n this.routeImageGenerator = routeImageGenerator;\\n this.tripRepository = tripRepository;\\n }\\n\\n @Async\\n @TransactionalEventListener(phase = AFTER_COMMIT)\\n public void handle(TripUpdateEvent tripUpdateEvent) {\\n Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());\\n\\n String imageUrl = routeImageGenerator.generate(\\n trip.getLatitudes(),\\n trip.getLongitudes(),\\n trip.getPointedLatitudes(),\\n trip.getPointedLongitudes()\\n );\\n\\n trip.changeRouteImageUrl(imageUrl);\\n tripRepository.save(trip);\\n }\\n}\\n```\\n\\n\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c\uc368 \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ubb38\uc81c\uac00 \ub2e4\uc74c\uacfc \uac19\uc774 \ud574\uacb0\ub418\uc5c8\ub2e4. \\n\ub610\ud55c \uc8fc\uae30\ub2a5\uacfc \ubd80\uae30\ub2a5\uc744 \ubd84\ub9ac\ud568\uc73c\ub85c\uc368 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc5d0 \ub300\ud55c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uc5c8\ub2e4.\\n\\n```mermaid\\ngraph LR\\n subgraph trip\\n TripServcie -- \ubc1c\ud589 --\x3e TripUpdateEvent\\n TripRepository\\n end\\n\\n subgraph draw\\n TripUpdateEventHandler -- \uad6c\ub3c5 \ud6c4 \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e TripUpdateEvent\\n TripUpdateEventHandler -- \uc0dd\uc131\ub41c \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5 --\x3e TripRepository\\n end\\n```\\n\\n### \ud14c\uc2a4\ud2b8\\n\\n\ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud14c\uc2a4\ud2b8\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \ubc29\ubc95\uc774 \uc788\ub2e4. \\n\\nimport Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n<Tabs>\\n<TabItem value=\\"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d\\" label=\\"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d\\">\\n\\n```java\\n@SpringBootTest\\npublic class TripUpdateEventHandlerIntegrationTest {\\n\\n ...\\n\\n @Test\\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\\n // given\\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\\n .willReturn(\uc5ec\ud589());\\n\\n // when\\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\\n\\n // then\\n then(routeImageGenerator)\\n .should(Mockito.timeout(5000).times(1))\\n .generate(any(), any(), any(), any());\\n }\\n}\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d\\" label=\\"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d\\" default>\\n\\n```java\\n@ContextConfiguration(classes = TestSyncConfig.class)\\n@SpringBootTest\\npublic class TripUpdateEventHandlerIntegrationTest {\\n\\n ...\\n\\n @Test\\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\\n // given\\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\\n .willReturn(\uc5ec\ud589());\\n\\n // when\\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\\n\\n // then\\n then(routeImageGenerator)\\n .should(times(1))\\n .generate(any(), any(), any(), any());\\n }\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n\ucc98\uc74c\uc5d0\ub294 \ud14c\uc2a4\ud2b8\uc5d0\uc11c\ub9cc \ub3d9\uae30\ub85c \uc124\uc815 \ud6c4 \uac80\uc99d\ud558\ub824\uace0 \ud588\ub2e4. \\n\ud1b5\ud569 \ud14c\uc2a4\ud2b8\uc5d0\uc120 `\ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1 \uc885\ub8cc\ub418\uc5c8\uc744 \ub54c \ube44\ub3d9\uae30\ub85c \uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0` \uac80\uc99d\uc774 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 \ucd5c\uc885\uc801\uc73c\ub85c `Mockito.timeout` \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \ud1b5\uacfc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4. \\n\\n## \uacb0\uacfc\\n\\n![./time.png](./time.png)\\n\\n\uc704 \uc751\ub2f5 \uc2dc\uac04\uc740 \uc704\uce58 \uc815\ubcf4 1000\uac1c\ub97c \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ud55c \uac12\uc774\ub2e4. \\n\uc751\ub2f5 \uc2dc\uac04\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ud3ec\ud568\ub418\uc9c0 \uc54a\uc544\uc11c \uc131\ub2a5\uc774 \uac1c\uc120\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. \\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n[7.7. Task Execution and Scheduling, Spring Boot Docs](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.task-execution-and-scheduling) \\n[Spring Events, Baeldung](https://www.baeldung.com/spring-events) \\n[\ud68c\uc6d0\uc2dc\uc2a4\ud15c \uc774\ubca4\ud2b8\uae30\ubc18 \uc544\ud0a4\ud14d\ucc98 \uad6c\ucd95\ud558\uae30](https://techblog.woowahan.com/7835/)"},{"id":"route-image-implementation","metadata":{"permalink":"/route-image-implementation","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx","source":"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx","title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604","description":"\uac1c\uc694","date":"2023-08-02T00:00:00.000Z","formattedDate":"2023\ub144 8\uc6d4 2\uc77c","tags":[{"label":"image","permalink":"/tags/image"},{"label":"awt","permalink":"/tags/awt"}],"readingTime":11.665,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604","slug":"route-image-implementation","tags":["image","awt"]},"unlisted":false,"prevItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac","permalink":"/route-image-async-with-event"},"nextItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c","permalink":"/route-image-python"}},"content":"## \uac1c\uc694\\n\\n\uc5ec\ud589\uc5d0 \ub300\ud55c \uacbd\ub85c\ub97c \ubcf4\uc5ec\uc8fc\uae30 \uc704\ud574 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4. \\n\uacbd\ub85c \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d \ubc0f \uae30\uc220 \uc120\ud0dd\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 [\ub9c1\ud06c](./route-image-intro)\uc5d0 \uc788\ub2e4.\\n\\n### \uad6c\ud604 \uacb0\uacfc\\n\\n![./result.png](./result.png)\\n\\n\uc608\uc2dc \ub370\uc774\ud130\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n**\uc11c\uc6b8\uc5ed(\uc810)** \u2192 \uc2e0\uc0ac\uc5ed \u2192 \ub178\ub7c9\uc9c4\uc5ed \u2192 \ud64d\ub300\uc785\uad6c\uc5ed \u2192 \uc885\ub85c3\uac00\uc5ed \u2192 \uc625\uc218\uc5ed \u2192 **\uad6c\ub85c\uc5ed(\uc810)** \u2192 \uc2e0\ub9bc\uc5ed \u2192 \ubc1c\uc0b0\uc5ed\\n\\n```java title=\\"\uc608\uc2dc \ub370\uc774\ud130\\"\\nList<Double> x = List.of(\\n 126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,\\n 126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639\\n);\\nList<Double> y = List.of(\\n 37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,\\n 37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184\\n);\\nList<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);\\nList<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);\\n```\\n\\n### IMAGE_SIZE & ROUTE_SIZE\\n\\n```java title=\\"RouteImageGenerator.java\\"\\nprivate static final int IMAGE_SIZE = 800;\\nprivate static final int ROUTE_SIZE = 600;\\n```\\n\\n\ucf54\ub4dc\ub97c \ubcf4\uba74 IMAGE_SIZE\uc640 ROUTE_SIZE\uac00 \uc788\ub2e4. \\nIMAGE_SIZE\ub294 \ub9d0 \uadf8\ub300\ub85c \uc774\ubbf8\uc9c0\uc758 width\uc640 height\ub97c \uc758\ubbf8\ud55c\ub2e4. \\nROUTE_SIZE\uc758 \uacbd\uc6b0 \uc0c1\ud558\uc88c\uc6b0 100px \ub9cc\ud07c\uc758 \uac04\uaca9\uc744 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4. \\n\ub530\ub77c\uc11c \uc2e4\uc81c \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub294 600 * 600 \uc0ac\uc774\uc988\ub85c \uc0dd\uc131\ub41c\ub2e4. \\n\\n![./600.png](./600.png)\\n\\n**\uc0ac\uc774\uc988 \ubcc0\uacbd\uc758 \uc774\uc720**\\n\\n255 * 255 \uc815\ub3c4\uc758 \uc791\uc740 \uc0ac\uc774\uc988\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud574\ubcf4\ub824\uace0 \ud588\ub294\ub370, \uc774\ubbf8\uc9c0\uc758 \uc120\uba85\ub3c4\uac00 \uc88b\uc9c0 \uc54a\uc544 800 * 800 \uc0ac\uc774\uc988\ub85c \ubcc0\uacbd\ud588\ub2e4.\\n\\n## \uc8fc\uc694 \ud074\ub798\uc2a4\\n\\n### \uc694\uc57d\\n\\n| \ud074\ub798\uc2a4\uba85 | \uc124\uba85 | \ud2b9\uc774\uc0ac\ud56d |\\n| --- | --- | --- |\\n| Coordinate | \uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \uc704\uce58 \uac12 | \uc88c\ud45c\ub97c \ub73b\ud558\uc9c0\ub9cc \uc5ec\ud589 \ub3c4\uba54\uc778\uc5d0 \ud3ec\ud568\ub41c Point \ud074\ub798\uc2a4\uc640 \uad6c\ubd84\ud558\uae30 \uc704\ud574 longitude, latitude\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 x, y \uc0ac\uc6a9 |\\n| Coordinates | Coordinate\uc758 \uc77c\uae09 \uceec\ub809\uc158 | - |\\n| Position | \uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58 \uac12 | Integer \ud0c0\uc785\uc758 x, y \uc0ac\uc6a9 |\\n| Positions | Positions\uc758 \uc77c\uae09 \uceec\ub809\uc158 | - |\\n| RouteImageDrawer | \uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4 BufferedImage, Graphics2D\ub97c \uac00\uc9c0\uace0 \uc788\uc74c | \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc0c1\uc218\uac00 \uc815\uc758\ub418\uc5b4 \uc788\uc74c |\\n| RouteImageUploader | BufferedImage\ub97c \ubc1b\uc544 \uc11c\ubc84\uc5d0 \uc5c5\ub85c\ub4dc \ud558\ub294 \ud074\ub798\uc2a4 | \ud604\uc7ac \uc5c5\ub85c\ub4dc \uc704\uce58\uac00 \uc815\ud574\uc9c0\uc9c0 \uc54a\uc544 \uc77c\ub2e8 \uae30\ubcf8(\ud504\ub85c\uc81d\ud2b8 \ub8e8\ud2b8) \uc704\uce58\uc5d0 \uc0dd\uc131 |\\n| RouteImageGenerator | \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uace0 \uc5c5\ub85c\ub4dc\ud558\ub294 \uc11c\ube44\uc2a4 | \uc5ec\ud589 \uc885\ub8cc, \uac10\uc0c1 \uc800\uc7a5\uc2dc \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \ud1b5\ud574 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad |\\n| BufferedImage(AWT) | \uc774\ubbf8\uc9c0 \ub370\uc774\ud130\ub97c \ucc98\ub9ac\ud558\uace0 \uc870\uc791\ud558\ub294 \ub370 \uc0ac\uc6a9 | \uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c\uac00 (0, 0) |\\n| Graphics2D(AWT) | \uc120 \uadf8\ub9ac\uae30, \uc0c9\uc0c1 \uad00\ub9ac \ub4f1\uc744 \uc9c0\uc6d0\ud558\ub294 \ud074\ub798\uc2a4 \uc2e4\uc81c \ud574\ub2f9 \ud074\ub798\uc2a4\uc758 draw \uba54\uc11c\ub4dc\ub97c \uacbd\ub85c\ub97c \uadf8\ub9bc | JDK 1.2 \uc774\ud6c4\uc5d0 \ucd94\uac00\ub428, 2D(\ud3c9\uba74) \uadf8\ub798\ud53d \ud658\uacbd\uc744 \uc9c0\uc6d0, bufferedImage.createGraphics \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \uc0dd\uc131 |\\n\\n### \uc758\uc874\uad00\uacc4\\n\\n```mermaid\\ngraph TD\\n C1[Coordinates] --\x3e C[Coordinate]\\n P1[Positions] --\x3e P[Position]\\n\\n\\tRID[RouteImageDrawer] -- \\"\uc911\uc559 \uc815\ub82c\ub41c Positions\ub97c \ubc1b\uc544 \uc774\ubbf8\uc9c0 \uc0dd\uc131\\" --\x3e P1\\n\\tRID --\x3e B[BufferedImage]\\n\\tRID --\x3e G[Graphics2D]\\n\\n\\tC1 -- \\"calculatePositions \uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc704\uce58 \uacc4\uc0b0\\" --\x3e P1\\n\\n\\tRIU[RouteImageUploader] --\x3e B\\n\\tRIG[RouteImageGenerator] --\x3e RID\\n\\tRIG --\x3e RIU\\n\\tRIG --\x3e C1\\n\\tRIG --\x3e P1\\n```\\n\\n### Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)\\n\\n`List<Double>` 2\uac1c(\uc704\ub3c4, \uacbd\ub3c4)\uc778 \ud615\ud0dc\ub85c \uad00\ub9ac\ud558\ub294 \ubc29\ubc95\uc774 \uc788\uc5c8\uc9c0\ub9cc, \uc704\uce58 \uc810\uc744 \uc5ec\ub7ec\uac1c \ucc0d\ub294 \ubd80\ubd84\uc5d0\uc11c \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud574 \uc9c8 \uac83 \uac19\uc544\uc11c Coordinate(x, y)\uc640 \uc77c\uae09 \uceec\ub809\uc158\uc778 Coordinates\ub85c \uad00\ub9ac\ud558\uae30\ub85c \ud588\ub2e4. \\nCoordinates \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub450 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4.\\n\\n- calculatePositions: \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub97c \ubc1b\uc544 \uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \uc0ac\uc6a9\ub420 Positions\ub97c \ubc18\ud658\\n- indexOf: \ub2e4\ub978 Coordinates\ub97c \ubc1b\uc544 \ub3d9\uc77c\ud55c \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4\ub97c \ubc18\ud658\ud558\ub294 \\n\\nPositions \uacc4\uc0b0 \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\uc704\ub3c4, \uacbd\ub3c4 \uac01\uac01\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \ud544\uc694\ud55c \uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4.\\n\\n```java title=\\"Coordinates.java\\"\\n// \ud638\ucd9c\\n// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);\\n// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);\\n\\nprivate List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {\\n Double minValue = Collections.min(values);\\n return values.stream()\\n .map(value -> normalizeCoordinate(value, maxDifference, minValue))\\n .map(value -> mapToPosition(value, routeImageSize))\\n .toList();\\n}\\n\\nprivate double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {\\n return (coordinate - minValue) / maxDifference;\\n}\\n\\nprivate int mapToPosition(Double coordinate, Integer routeImageSize) {\\n return (int) (coordinate * routeImageSize);\\n}\\n```\\n\\n\uc704\ub3c4\ub85c \uc608\uc2dc\ub4e0 \ub0b4\uc6a9\uc774\ub2e4.\\n\\n1. Collections.min(values) \u2192 \uc704\ub3c4 \ub9ac\uc2a4\ud2b8\uc758 \ucd5c\uc18c\uac12\uc744 \uad6c\ud55c\ub2e4.\\n2. normalizeCoordinate \u2192 \uac01\uac01\uc758 \uc704\ub3c4 \uac12\uc5d0\uc11c \ucd5c\uc18c\uac12\uc744 \ube7c\uace0 0 ~ 1 \uc0ac\uc774 \uac12\uc73c\ub85c \ubcc0\ud658 \ud6c4 **\uc704\uacbd\ub3c4\uc758 \ucd5c\ub300 \ucc28\uc774**\ub85c \ub098\ub208\ub2e4.\\n3. mapToPosition \u2192 \uadf8\ub798\ud504 \ud06c\uae30\ub97c \ubc1b\uc544 0 ~ 1 \uc0ac\uc774 \uac12\uc744 \uc2e4\uc81c \uc774\ubbf8\uc9c0\ub97c \uc704\ud55c \uc704\uce58\uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4.\\n\\n### Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)\\n\\nPositions \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub2e4\uc12f \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4.\\n\\n- align: \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\uc640 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\ub97c \ubc1b\uc544 Position \uac12\ub4e4\uc744 \uc911\uc559 \uc815\ub82c\ud55c\ub2e4.\\n- getPositionsByIndexes: \uc778\ub371\uc2a4 \ub9ac\uc2a4\ud2b8\ub97c \ubc1b\uc544 \uc785\ub825\ubc1b\uc740 \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4.\\n- size: \ud06c\uae30\ub97c \ubc18\ud658\ud55c\ub2e4.\\n- xPositions: x \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4.\\n- yPositions: y \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4.\\n\\n\uc911\uc559 \uc815\ub82c \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n```java title=\\"Positions.java\\"\\npublic Positions align(int imageSize, int routeSize) {\\n int xOffset = calculateOffset(Position::x, imageSize);\\n int yOffset = calculateOffset(Position::y, imageSize);\\n\\n return items.stream()\\n .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))\\n .collect(collectingAndThen(toList(), Positions::new));\\n}\\n\\nprivate int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {\\n List<Integer> positions = items.stream()\\n .mapToInt(positionToInteger)\\n .boxed()\\n .toList();\\n\\n int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;\\n return imageSize / 2 - midValue;\\n}\\n```\\n\\n\uc0c1\ud558\uc88c\uc6b0 \uc5ec\ubc31\uc744 \ub3d9\uc77c\ud558\uac8c \uc8fc\uae30 \uc704\ud574\uc11c offset \uac12\uc744 \uad6c\ud574\uc11c x, y \uac12\uc5d0 \uac01\uac01 \ub354\ud558\ub294 \ud615\ud0dc\ub85c \uc911\uc559 \uc815\ub82c\uc744 \uc218\ud589\ud588\ub2e4. \\nBufferedImage\ub97c \uc0ac\uc6a9\ud560 \ub54c \uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c (0, 0) \uae30\uc900\uc73c\ub85c \uc544\ub798\ub85c \ub0b4\ub824\uac08\uc218\ub85d y \uac12\uc774 \ucee4\uc9c0\uace0, \uc624\ub978\ucabd\uc73c\ub85c \uac08 \uc218\ub85d x \uac12\uc774 \ucee4\uc9c4\ub2e4. \\n\\n![./800.png](./800.png)\\n\\n\ub530\ub77c\uc11c \ucd5c\uc885\uc801\uc73c\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud55c \uac12\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uad6c\ud588\ub2e4.\\n\\nx \uac12 \u2192 \uacc4\uc0b0\ud55c offset \uadf8\ub300\ub85c \ub354\ud55c\ub2e4. \\ny \uac12 \u2192 imageSize(800)\uc5d0\uc11c y + offset \uac12\uc744 \ube80\ub2e4. \\n\\n### RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)\\n\\nBufferedImage, Graphics2D\ub97c \ud544\ub4dc\ub85c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub2e4. \\n\uadf8\ub9bc\uc744 \uadf8\ub9ac\uae30 \uc704\ud574 \uc124\uc815\ud55c \uc0c1\uc218\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4.\\n\\n```java title=\\"RouteImageDrawer.java\\"\\n// RGB\uc5d0 \uac01\uac01 8\ube44\ud2b8\uc529 \ud560\ub2f9\ud55c \uac12\uc744 24\ube44\ud2b8 \ud2b8\ub8e8\uceec\ub7ec\ub77c \ubd80\ub978\ub2e4.\\n// \ud574\ub2f9 \uc124\uc815\uc740 24\ube44\ud2b8 + 8\ube44\ud2b8(alpha, \ud22c\uba85\ub3c4)\ub97c \ucd94\uac00\ud55c 32\ube44\ud2b8 \uc774\ubbf8\uc9c0 \ud0c0\uc785\uc774\ub2e4.\\n// \uc774\ub97c RGBA\ub77c\uace0 \ubd80\ub978\ub2e4.\\nprivate static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;\\n// \ubc30\uacbd \ud22c\uba85\uc0c9\\nprivate static final Color TRANSPARENT = new Color(0, 0, 0, 0);\\n// \uacbd\ub85c\ub97c \uc704\ud55c STROKE\\nprivate static final int LINE_STROKE_WIDTH = 7;\\nprivate static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\\n// \uc704\uce58 \uc810\uc744 \uc704\ud55c STROKE\\nprivate static final int POINT_STROKE_WIDTH = 20;\\nprivate static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\\n// \uc548\ud2f0\uc568\ub9ac\uc5b4\uc2f1 \ub4f1 \ud654\uc9c8 \uac1c\uc120\uc744 \uc704\ud55c \uc124\uc815\\nprivate static final Map<Object, Object> renderingHints = Map.of(\\n RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,\\n RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,\\n RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC\\n);\\n```\\n\\nRouteImageDrawer \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \uc138 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4.\\n\\n- drawLine: \uc120\uc744 \uadf8\ub9b0\ub2e4.\\n- drawPoint: \uc810\uc744 \ucc0d\ub294\ub2e4.\\n- dispose: \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud55c\ub2e4. \\n\\ndispose\uc758 \uacbd\uc6b0 \ub0b4\ubd80\uc5d0\uc11c \uc0dd\uc131\ub41c graphics2D\uc5d0 \ub300\ud55c \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud558\ub294 \uba54\uc11c\ub4dc\uc778 graphics2D.dispose\ub97c \ud638\ucd9c\ud55c\ub2e4.\\n\\n## \uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow\\n\\n### 1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44\\n\\n```mermaid\\nsequenceDiagram\\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\\n\\n```\\n\\n### 2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad\\n\\n```mermaid\\nsequenceDiagram\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad\\n```\\n\\n### 3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\\n\\n```mermaid\\nsequenceDiagram\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\\n\\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\\n```\\n\\n### 4. \uc5c5\ub85c\ub4dc \uc694\uccad\\n\\n```mermaid\\nsequenceDiagram\\n \\tRouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\\n \\tRouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\\n \\tRouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\\n```\\n\\n### \uc804\uccb4 Flow\\n\\n```mermaid\\nsequenceDiagram\\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad\\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\\n\\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\\n RouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\\n RouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\\n RouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\\n\\t\\n```"},{"id":"route-image-python","metadata":{"permalink":"/route-image-python","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx","source":"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx","title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c","description":"\uac1c\uc694","date":"2023-07-31T00:00:00.000Z","formattedDate":"2023\ub144 7\uc6d4 31\uc77c","tags":[{"label":"Image","permalink":"/tags/image"},{"label":"Python","permalink":"/tags/python"}],"readingTime":6.185,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c","slug":"route-image-python","tags":["Image","Python"]},"unlisted":false,"prevItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604","permalink":"/route-image-implementation"},"nextItem":{"title":"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30","permalink":"/mock-static-method"}},"content":"### \uac1c\uc694\\n\\n\uc774\uc804\uc5d0 \uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uc870\uc0ac\ud558\uba74\uc11c \ud30c\uc774\uc36c\uc744 \uc0ac\uc6a9\ud55c \ub0b4\uc6a9\uc744 \uc815\ub9ac\ud55c \ub0b4\uc6a9\uc774\ub2e4. \\n\\n### \uc0ac\uc6a9 \uae30\uc220\\n\\n\uc5b8\uc5b4: Python 3.10 \\n\uc774\ubbf8\uc9c0 \uc0dd\uc131: matplotlib \\n\uc11c\ube44\uc2a4: AWS Lambda, AWS API Gateway \\n\uc774\ubbf8\uc9c0 \uc800\uc7a5 \ubc0f URL: AWS S3, AWS CloudFront \\n\\n\ud50c\ub85c\uc6b0\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n```mermaid\\ngraph LR\\n Server -- \uc0dd\uc131 \uc694\uccad --\x3e AG[API Gateway] --\x3e Lambda --\x3e S3\\n Client --\x3e CloudFront --\x3e S3\\n```\\n\\n### \uc694\uad6c\uc0ac\ud56d\\n\\n![./route.png](./route.png)\\n\\n\uc6b0\uce21 \uc0c1\ub2e8\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub824\uace0 \ud55c\ub2e4. \\n\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.\\n\\n- \uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \ubc30\uc5f4\uc744 \uc785\ub825\ubc1b\ub294\ub2e4. \\n- \uc774\ubbf8\uc9c0 \uc0dd\uc131\\n- \uc120\uacfc \uc810 \ud45c\ud604\\n- \ud22c\uba85\ud55c \ubc30\uacbd\uc0c9\\n- \uc704\uacbd\ub3c4 \ucc28\uc774\uac00 \ud06c\ub4e0 \uc791\ub4e0 \uc81c\uacf5\ud558\ub294 \uc774\ubbf8\uc9c0 \ub0b4\uc5d0 \uacbd\ub85c\uac00 \ub2e4 \ud3ec\ud568\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4. \\n\\n### \uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd\\n\\n1. \uc704\uacbd\ub3c4\ub97c \ucc98\ub9ac\ud55c \uac12\uc73c\ub85c \uc9c1\uc811 \uacbd\ub85c\ub97c \uadf8\ub9b0 \ub2e4\uc74c \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5\\n2. \ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac \uc0ac\uc6a9\ud558\uc5ec \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5\\n\\n\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd\uc758 \uacbd\uc6b0 1\ubc88\uacfc 2\ubc88\uc744 \uace0\ubbfc\ud588\uc5c8\ub2e4. \\n\ud30c\uc774\uc36c\uc73c\ub85c\ub294 \ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc778 matplotlib\uc744 \uc0ac\uc6a9\ud588\ub2e4. \\n\\n### \ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604\\n\\n```python\\nimport time\\n\\nimport matplotlib.pyplot as plt\\n\\n\\ndef draw(point):\\n start = time.time()\\n x, y = zip(*point)\\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\\n draw_lines(pixel_x, pixel_y)\\n end = time.time()\\n print(end - start)\\n \\ndef convert_to_pixel_values(x, y):\\n max_diff = max(max(x) - min(x), max(y) - min(y))\\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\\n\\n\\ndef scale_to_pixel_values(points, max_diff):\\n min_value = min(points)\\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\\n return scaled_coordinates\\n\\n\\ndef draw_lines(x, y):\\n figure = plt.gcf()\\n figure.set_size_inches(5, 5)\\n plt.plot(x, y, c = \'w\',linewidth=5)\\n plt.scatter(x[3],y[3], c = \'w\', s = 125)\\n plt.axis(\'off\')\\n plt.savefig(\'name.png\', transparent=True, format=\'png\')\\n\\npoint = [\\n [126.96352960597338, 37.590841000217125],\\n [126.96987292787792, 37.58435564234159],\\n [126.98128481452298, 37.58594375113966],\\n [126.99360339342958, 37.58248524741927],\\n [126.99867565340067, 37.56778118088622],\\n [127.001935378366117, 37.55985240444085],\\n [126.9831048919687, 37.548030119488665],\\n [126.97189273528845, 37.5119879225856],\\n [127.02689859997221, 37.48488593333883]\\n]\\n\\ndraw(point)\\n```\\n\\n\uc0dd\uc131 \uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4. (\uc608\uc2dc\ub97c \uc704\ud574 \uac80\uc740\uc0c9\uc73c\ub85c \ucd9c\ub825)\\n\\n![./routeImage.png](./routeImage.png)\\n\\n### AWS Lambda\\n\\n\uc378\ub124\uc77c \uc0dd\uc131 \uc11c\ubc84\ub97c \ub530\ub85c \ub450\uae30\ub294 \uae30\ub2a5 \ub300\ube44 \ube44\uc6a9\uc774 \ub108\ubb34 \ud074 \uac83\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ub530\ub77c\uc11c \uc11c\ubc84\ub9ac\uc2a4\ub85c \ud30c\uc77c\uc744 \ucc98\ub9ac\ud588\ub2e4. \\n\ucd94\uac00\ub85c s3 \uc811\uadfc\uc740 boto3\ub97c \uc0ac\uc6a9\ud588\ub2e4. \\n\\n### \ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131\\n\\nAmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy \ub450\uac00\uc9c0\ub97c \ucd94\uac00\ud574\uc11c Lambda \uc804\uc6a9 \uc5ed\ud560\uc744 \ub9cc\ub4e4\uc5b4 \uc0ac\uc6a9\ud588\ub2e4. \\n\\n### \ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc\\n\\n\uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \ud655\uc778\ud560 \ub550 \uc704\uce58 \uc810\uc744 \ucc0d\ub294 \uae30\ub2a5\uc744 \ub78c\ub2e4\uc5d0 \ubc30\ud3ec\ud558\uc9c0 \uc54a\uc558\ub2e4. \\n\\n```python\\n\\nimport io\\nimport uuid\\n\\nimport boto3\\nimport matplotlib.pyplot as plt\\n\\nPIXEL = 255\\nBUCKET_NAME = \'image-plot\'\\nS3 = \'s3\'\\n\\ndef lambda_handler(event, context):\\n x = event[\'x\']\\n y = event[\'y\']\\n image_name = str(uuid.uuid4())\\n\\n img_data = draw(x, y)\\n s3 = boto3.client(S3)\\n s3.put_object(Body=img_data.getvalue(), ContentType=\'image/png\', Bucket=BUCKET_NAME, Key=image_name)\\n url = f\'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}\'\\n\\n return {\\n \'statusCode\': 200,\\n \'body\': url\\n }\\n\\ndef draw(x, y):\\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\\n img_data = draw_lines(pixel_x, pixel_y)\\n plt.close()\\n return img_data\\n\\ndef convert_to_pixel_values(x, y):\\n max_diff = max(max(x) - min(x), max(y) - min(y))\\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\\n\\ndef scale_to_pixel_values(points, max_diff):\\n min_value = min(points)\\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\\n pixel_values = [int(p * PIXEL) for p in scaled_coordinates]\\n return pixel_values\\n\\ndef draw_lines(x, y):\\n plt.plot(x, y, \'k-\', linewidth=10)\\n plt.axis(\'off\')\\n img_data = io.BytesIO()\\n plt.savefig(img_data, transparent=True, format=\'png\')\\n img_data.seek(0)\\n return img_data\\n\\n```\\n\\n### Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131\\n\\nmatplotlib\uc758 \uacbd\uc6b0 \uc678\ubd80 \ub77c\uc774\ube0c\ub7ec\ub9ac\uae30 \ub54c\ubb38\uc5d0 \ub530\ub85c Layer\ub97c \ucd94\uac00\ud574\uc57c \ud55c\ub2e4. \\nzip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc5b4\uc11c \uc5c5\ub85c\ub4dc\ud574\uc57c\ud55c\ub2e4. \\n\uc774\ub54c python\uc758 Lambda \ub7f0\ud0c0\uc784\uc5d0 \ub300\ud55c \uacc4\uce35 \uacbd\ub85c\ub294 python\uc774\ub2e4. \\n\ub530\ub77c\uc11c \uc555\ucd95\ud55c zip \ud30c\uc77c\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\ub97c \ub744\uc5b4\uc57c \ud55c\ub2e4. \\n\\n```\\npillow.zip\\n\u2502 python/PIL\\n\u2514 python/Pillow-5.3.0.dist-info\\n```\\n\\nUbuntu \uae30\uc900 \ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc0dd\uc131\uc744 \uc9c4\ud589\ud588\ub2e4. \\n\\n```\\nsudo apt update\\nsudo apt install zip\\nsudo apt install python3-pip\\n\\nmkdir python\\npip3 install matplotlib -t python # pip3 install \uc124\uce58\ud560_\ud328\ud0a4\uc9c0 -t \uc124\uce58_\uacbd\ub85c\\nzip -r my_layer.zip python # zip -r \uc555\ucd95_\ud30c\uc77c\uba85 \uc555\ucd95_\ud30c\uc77c\uc774_\uc874\uc7ac\ud558\ub294_\uacbd\ub85c\\n```\\n\\n### `No module named \'numpy.core._multiarray_umath\'` \uc5d0\ub7ec\\n\\nLayer \ucd94\uac00 \ud6c4 \ub78c\ub2e4 \uc2e4\ud589 \uc2dc \ubc1c\uc0dd\ud55c \uc5d0\ub7ec\uc600\ub2e4. \\n\ucc98\uc74c\uc5d0 mac\uc5d0\uc11c zip \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \uc5c5\ub85c\ub4dc\ud588\ub294\ub370 \ud574\ub2f9 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4. \\n\uc774\ub294 lambda\uac00 \ub3cc\uc544\uac00\ub294 \ub3d9\uc77c\ud55c \ud658\uacbd\uc5d0\uc11c layer\ub97c \uc704\ud55c zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc9c0 \uc54a\uc544\uc11c \ubc1c\uc0dd\ud558\ub294 \ubb38\uc81c\ub2e4. \\n\uac04\ub2e8\ud558\uac8c ec2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c \ub530\ub85c Layer\ub97c \uc0dd\uc131\ud558\uba74 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4. \\n\\n### \uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01\\n\\n\ud504\ub85c\uc81d\ud2b8\uc5d0 Lambda\uc640 Python\uc744 \uc0ac\uc6a9\ud558\ub824\uace0 \ud588\uc9c0\ub9cc \uc544\uc27d\uac8c\ub3c4 \ubc18\ub824\ub2f9\ud588\ub2e4. \\nAWS Lambda\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc778\uc2a4\ud134\uc2a4\uc5d0 \ud574\ub2f9 \ucf54\ub4dc\ub97c \ubc30\ud3ec\ud558\ub294 \uac83\ubcf4\ub2e4 \ub354 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc77c \uc218 \uc788\ub2e4. \\n\ud558\uc9c0\ub9cc \ud604\uc7ac \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uac00\uc6a9 \uac00\ub2a5\ud55c \uc790\uc6d0, \uae30\uc220\uc758 \ub09c\uc774\ub3c4, \uc0ac\uc6a9\ud558\ub294 \ud300\uc6d0\uc744 \uace0\ub824\ud55c\ub2e4\uba74 Lambda\ub294 \uc801\uc815\uae30\uc220\uc774 \uc544\ub2d0 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c \ud574\ub2f9 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\ub97c \uc5b4\ub5bb\uac8c \uc801\uc6a9\ud560\uc9c0 \uc870\uae08 \ub354 \uace0\ub824\ub97c \ud574\uc57c \ub420 \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4. \\n\\n**\ucd5c\uc885\uc801\uc73c\ub85c Java AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.**\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n[AWS Lambda](https://aws.amazon.com/ko/lambda/) \\n[Lambda Layer](https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-layers.html) \\n[Python Lambda \ud568\uc218\uc5d0 \ub300\ud55c .zip \ud30c\uc77c \uc544\uce74\uc774\ube0c \uc791\uc5c5](https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-package.html) \\n[No module named \'numpy.core._multiarray_umath\'](https://gist.github.com/ksmin23/0f3f243408a8497f766b43cf589fea7b) \\n[\uc0ac\ub840\ubcc4\ub85c \uc54c\uc544\ubcf8 \uc548\uc804\ud55c S3 \uc0ac\uc6a9 \uac00\uc774\ub4dc](https://techblog.woowahan.com/6217/)"},{"id":"mock-static-method","metadata":{"permalink":"/mock-static-method","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx","source":"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx","title":"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30","description":"\uac1c\uc694","date":"2023-07-30T00:00:00.000Z","formattedDate":"2023\ub144 7\uc6d4 30\uc77c","tags":[{"label":"Mockito","permalink":"/tags/mockito"},{"label":"static","permalink":"/tags/static"}],"readingTime":2.635,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30","slug":"mock-static-method","tags":["Mockito","static"]},"unlisted":false,"prevItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c","permalink":"/route-image-python"},"nextItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd","permalink":"/route-image-intro"}},"content":"### \uac1c\uc694\\n\\n\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud55c\ub2e4\ub294 \uac83\uc740 \uac1d\uccb4\uc9c0\ud5a5\uc801\uc778 \uad00\uc810\uc5d0\uc11c \ubcfc \ub54c \uc548\ud2f0\ud328\ud134\uc774\ub2e4. \\n\ud558\uc9c0\ub9cc \ud2b9\uc218\ud55c \uacbd\uc6b0\uc5d0\ub294 \uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc774 \ud544\uc694\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\n\uc608\ub97c \ub4e4\uc5b4 \ub808\uac70\uc2dc \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud55c\ub2e4\ub358\uc9c0, IO \uad00\ub828\ud55c \ubd80\ubd84\uc744 \ud14c\uc2a4\ud2b8 \ud560 \ub54c \uc815\ub9d0 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\ub9cc \uc801\uc6a9\ud560 \uc218 \uc788\uc744 \uac83\uc774\ub2e4. \\n\\n\ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba70 ImageIo.write \uba54\uc11c\ub4dc\uac00 \ud638\ucd9c\ub418\ub294 \uc9c0 \uac80\uc99d\uc774 \ud544\uc694\ud588\ub2e4. \\n\ud574\ub2f9 static \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294 \ubd80\ubd84\uc744 \ub530\ub85c RouteImageUploader \ud074\ub798\uc2a4\ub85c \ucd5c\ub300\ud55c \ubd84\ub9ac\ud588\ub2e4. \\n\uc774\ubbf8\uc9c0 \uc800\uc7a5 \uae30\ub2a5 \uc790\uccb4\uac00 \uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc774\uace0, \ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc0ac\ud558\ub294\ub370\ub294 mock\uc744 \uc0ac\uc6a9\ud558\ub294\uac8c \uc801\uc808\ud558\ub2e4\uace0 \ud310\ub2e8\ud588\ub2e4. \\n\\n```java\\npublic void upload(BufferedImage bufferedImage) {\\n File file = new File(\ud30c\uc77c\uacbd\ub85c);\\n try {\\n ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);\\n } catch (IOException e) {\\n throw new DrawException(IMAGE_SAVE_FAIL);\\n }\\n}\\n```\\n\\n### Mocking static methods\\n\\nMockito 3.4.0 \uc774\ud6c4\uc5d0\ub294 static method\ub97c \ubaa8\ud0b9\ud560 \uc218 \uc788\ub294 Mockito.mockStatic \uba54\uc11c\ub4dc\ub97c \uc9c0\uc6d0\ud55c\ub2e4. \\nmockStatic\uc744 \uc0ac\uc6a9\ud558\uba74 `MockedStatic<T>`\uc774 \ubc18\ud658\ub418\ub294\ub370 \uc0ac\uc6a9 \ud6c4 \uaf2d close\ub97c \ud574\uc918\uc57c \ud55c\ub2e4. \\n\\nJUnit\uc758 @BeforeAll\ub85c \uc124\uc815\ud558\uace0 @AfterAll \uba54\uc11c\ub4dc\ub85c \uc885\ub8cc\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\uc9c0\ub9cc `MockedStatic<T>`\uc758 \uc0c1\uc704 \uc778\ud130\ud398\uc774\uc2a4\uc778 ScopedMock\uc774 AutoCloseable\uc744 \uad6c\ud604\ud558\uace0 \uc788\uae30\uc5d0 try-with-resources\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \ub354\uc6b1 \uc88b\uc740 \uac83 \uac19\ub2e4. \\n\\n```java\\n// given\\nBufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);\\nRouteImageUploader routeImageUploader = new RouteImageUploader();\\n\\n// expect\\ntry (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {\\n routeImageUploader.upload(bufferedImage);\\n imageIO.verify(\\n () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),\\n times(1)\\n );\\n}\\n```\\n\\n### \ub9c8\uce58\uba70\\n\\n\uc815\uc801 \uba54\uc11c\ub4dc\ub97c \ubaa8\ud0b9\ud558\ub294 \uac83\uc740 \uc548\ud2f0\ud328\ud134\uc774\uc73c\ub85c \uc801\uc808\ud55c \ucd94\uc0c1\ud654\ub97c \uc774\uc6a9\ud574 \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc88b\uc740 \ucf54\ub4dc\ub97c \ub9cc\ub4dc\ub294 \uc5f0\uc2b5\uc744 \ud558\uc790. \\n\ud558\uc9c0\ub9cc \ucd94\uc0c1\ud654\ub97c \ud558\uba74 \ud560 \uc218\ub85d \ucf54\ub4dc\uc758 \ubcf5\uc7a1\ub3c4\ub294 \uc99d\uac00\ud55c\ub2e4. \\n\ud56d\uc0c1 \uc0c1\ud669\uc744 \uace0\ub824\ud558\uace0 \uac04\uacb0\ud568\uc744 \ud3ec\uae30\ud560 \ub9cc\ud07c \uc911\uc694\ud55c \ubd80\ubd84\uc778\uc9c0 \uc801\uc808\ud55c \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uace0\ub824\ud558\uc790. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[Mocking static methods](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks) \\n[Mockito mock static methods](https://www.baeldung.com/mockito-mock-static-methods) \\n[Enable mocking static methods in Mockito](https://github.com/mockito/mockito/issues/1013)"},{"id":"route-image-intro","metadata":{"permalink":"/route-image-intro","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx","source":"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx","title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd","description":"./route.png","date":"2023-07-27T00:00:00.000Z","formattedDate":"2023\ub144 7\uc6d4 27\uc77c","tags":[{"label":"image","permalink":"/tags/image"},{"label":"awt","permalink":"/tags/awt"}],"readingTime":5.865,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd","slug":"route-image-intro","tags":["image","awt"]},"unlisted":false,"prevItem":{"title":"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30","permalink":"/mock-static-method"},"nextItem":{"title":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","permalink":"/java-spring-springboot"}},"content":"![./route.png](./route.png)\\n\\n### \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \ucc45\uc784\\n\\n\uc704 \uc640\uc774\uc5b4 \ud504\ub808\uc784\uc5d0\uc11c `\uc5ec\ud589 \ud788\uc2a4\ud1a0\ub9ac`\uc640 `\uc5ec\ud589\uc5d0 \ub300\ud55c \uac10\uc0c1\uc744 \uc704\ud55c \uacbd\ub85c \uc774\ubbf8\uc9c0`\uc758 \uacbd\uc6b0 \ub124\uc774\ubc84 \uc9c0\ub3c4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud574\ub2f9 \uae30\ub2a5\uc744 \uad6c\ud604\ud560 \uc218 \uc5c6\uc73c\ub2c8 \ub2f9\uc5f0\ud788 \ub9f5 API\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \ub3c4\ud615 \uadf8\ub9ac\uae30 API(\ub124\uc774\ubc84 \ub9f5 API \uae30\uc900 Polyline)\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc5c6\ub2e4. \\n\ub530\ub77c\uc11c \uc774\ubbf8\uc9c0\ub97c \uc9c1\uc811 \uc0dd\uc131\ud558\uac70\ub098, \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uc11c \uc9c1\uc811 \uc704\uacbd\ub3c4\ub97c \uc774\uc6a9\ud558\uc5ec \uadf8\ub824\uc57c \ud55c\ub2e4.\\n\\n\ud574\ub2f9 \uc694\uad6c\uc0ac\ud56d\uc744 \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uae30\ub2a5\uc744 \uac00\uc9c4 \ub77c\uc774\ube0c\ub7ec\ub9ac\uac00 \ud544\uc694\ud558\ub2e4.\\n\\n- \uc774\ubbf8\uc9c0 \uc0dd\uc131\\n- \uc120\uacfc \uc810 \ud45c\ud604\\n- \ud22c\uba85\ud55c \ubc30\uacbd\uc0c9\\n\\n\ud604\uc7ac \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \ubc14\uc05c \uc77c\uc815\uacfc \uae30\ub2a5 \uad6c\ud604\uc5d0 \uc788\uc5b4 \uc57d\uac04\uc758 \uc5f0\uc0b0\uc774 \ub4e4\uc5b4\uac04\ub2e4\ub294 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uc5ec \ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30\ub85c \uacb0\uc815\uc744 \ub0b4\ub838\ub2e4.\\n\\n### \uace0\ub824\ud55c \uae30\uc220\\n\\n\ubc31\uc5d4\ub4dc\uc5d0\uc11c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uae30 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 \ub77c\uc774\ube0c\ub7ec\ub9ac \ub610\ub294 \uae30\uc220\ub4e4\uc744 \ud655\uc778\ud574 \ubcf4\uc558\ub2e4. \\n\\n- Python\uc758 Matplotlib\\n- **AWT(Abstract Window Toolkit) [\ucd5c\uc885 \uc120\ud0dd]**\\n- \uc774\ubbf8\uc9c0 \ucc98\ub9ac \ub77c\uc774\ube0c\ub7ec\ub9ac \ubc0f Java\uc5d0\uc11c \ub0b4\ubd80\uc801\uc73c\ub85c Matplotlib \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac (\uc6d0\ud558\ub294 \uae30\ub2a5 \uc5c6\uc74c)\\n- Java Swing, Java FX (\ub2e8\uc21c\ud55c \uc120 \uadf8\ub9ac\uae30 + \uc810 \ucc0d\uae30\ub77c \ubd88\ud544\uc694)\\n\\n## Python & Matplotlib\\n\\n\ub370\uc774\ud130 \uc2dc\uac01\ud654 \ub77c\uc774\ube0c\ub7ec\ub9ac \\n\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 0.2\ucd08 \\n\\n- \ucf54\ub4dc\uac00 \uac04\ub2e8\ud574\uc11c \uc720\uc9c0 \ubcf4\uc218\uc131\uc774 \uc88b\ub2e4. \\n- AWS Lambda \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ucef4\ud4e8\ud305 \uc11c\ube44\uc2a4\ub098 FastAPI\uc640 \uac19\uc740 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\ub85c \ucd94\uac00\uc801\uc778 API\ub97c \uad6c\ud604\ud574\uc57c \ud55c\ub2e4.\\n- Spring Boot\uc5d0\uc11c \ucd94\uac00\uc801\uc778 API \ud638\ucd9c\uc744 \ud574\uc57c\ud558\uace0, \ud655\uc7a5\uc131\uacfc \ube44\ub3d9\uae30 \ucc98\ub9ac \ub4f1 \uace0\ub824 \ud574\uc57c \ud560 \ubd80\ubd84\uc774 \ub9ce\ub2e4.\\n\\n### Java AWT \uc774\uc678\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\\n\\nPython\uc774 \uc544\ub2cc Java\uc5d0\uc11c\uc758 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub3c4 \uace0\ub824\ub97c \ud574\ubd24\uc9c0\ub9cc \uc694\uad6c\uc0ac\ud56d\uc5d0 \uc801\ud569\ud558\uc9c0 \uc54a\uac70\ub098, \uc801\uc740 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac70\uc6b4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc774 \ub9ce\uc544\uc11c \uc81c\uc678\ud588\ub2e4.\\n\\n\ub77c\uc774\ube0c\ub7ec\ub9ac | \uc124\uba85 | \uc81c\uc678 \uc774\uc720\\n-- | -- | --\\nSwing | AWT \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, \ub124\uc774\ud2f0\ube0c UI\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 \ubaa8\ub4e0 \uc6b4\uc601\uccb4\uc81c \uc0c1\uc5d0\uc11c \ub3d9\uc77c\ud55c UI\ub97c \uac00\uc9c0\ub3c4\ub85d \ud568 | \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c\\nJavaFX | Swing \uc774\ud6c4\uc5d0 \ub098\uc628 GUI \ub77c\uc774\ube0c\ub7ec\ub9ac, 3\ucc28\uc6d0 \uadf8\ub798\ud53d\uc744 \uc9c0\uc6d0\ud568 | \uc694\uad6c\uc0ac\ud56d\uc5d0 \ube44\ud574 \ubb34\uac81\uace0 \ubcf5\uc7a1\ub3c4\uac00 \ub192\uc74c\\n[simple-java-plot](https://github.com/yuriy-g/simple-java-plot) | AWT\ub85c \uad6c\ud604\ub41c \ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac | AWT \uae30\ubc18\uc774\uae34 \ud558\uc9c0\ub9cc \uc9c1\uc811 AWT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc5d0 \ube44\ud574 \uba54\ub9ac\ud2b8\uac00 \uc5c6\uc74c, \ucee4\uc2a4\ud140 \uc124\uc815 \uae30\ub2a5\uc774 \uc5c6\uc74c\\n[matplotlib4j](https://github.com/sh0nk/matplotlib4j) | Matplotlib\ub97c Java\uc5d0\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uac8c \ud558\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac | \ub0b4\ubd80\uc801\uc73c\ub85c \ud30c\uc774\uc36c \uc0ac\uc6a9\ud558\uae30\uc5d0 \ubb34\uac70\uc6c0, \ubc30\uacbd \ud22c\uba85\ud654 \uae30\ub2a5 \uc5c6\uc74c\\n\\n### Java & AWT(Abstract Window Toolkit)\\n\\n\uadf8\ub798\ud53d\uacfc \uc774\ubbf8\uc9c0\ub97c \uadf8\ub9ac\uae30 \uc704\ud55c \ub3c4\uad6c \\n\uc774\ubbf8\uc9c0 \uc0dd\uc131 \ubc0f \ub85c\uceec\uc5d0 \uc800\uc7a5\uae4c\uc9c0 \uac78\ub9ac\ub294 \uc2dc\uac04: 1.75\ucd08 \\n\\n- \ud50c\ub85c\ud305 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ubcf4\ub2e4 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc874\uc7ac\ud55c\ub2e4.\\n- \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub2e4\uc18c \uc18c\uc694\ub418\uae30 \ub54c\ubb38\uc5d0 \ube60\ub978 \uc751\ub2f5 \ubc18\ud658\uc744 \uc704\ud574 \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \uace0\ub824\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4.\\n- \ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4.\\n\\n### \uae30\uc220 \uc120\ud0dd\\n\\nAWT\uc758 \uacbd\uc6b0 Matplotlib\uc5d0 \ube44\ud574 \uad6c\ud604\uc758 \ub09c\uc774\ub3c4\uac00 \ub2e4\uc18c \uc788\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ub354 \ub9ce\uc774 \uac78\ub9ac\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4. \\n\ud558\uc9c0\ub9cc \ucd94\uac00\uc801\uc778 api \ud638\ucd9c\uc744 \ud558\uc9c0 \uc54a\uc544\ub3c4 \ub418\ub294 \ubd80\ubd84, Python\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc778 \uc6f9 \ud504\ub808\uc784\uc6cc\ud06c\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uace0\ub824\ud558\uc5ec AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.\\n\\n### \uc720\uc9c0 \ubcf4\uc218\\n\\nAWT\ub77c\ub294 \uc0dd\uc18c\ud55c \uae30\uc220\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc720\uc9c0 \ubcf4\uc218\uc131\uc744 \uc704\ud574 \ud300\uc6d0\ub4e4\uacfc \uacf5\uc720\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ub530\ub77c\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ubc29\ubc95\uc73c\ub85c \uacf5\uc720\ud558\uae30\ub85c \ud588\ub2e4. \\n\\n1. \ucf54\ub4dc \ub9ac\ubdf0\uc640 PR\uc744 \ud1b5\ud574 \uc791\uc131\ud55c AWT \ucf54\ub4dc\uc5d0 \ub300\ud55c \uc124\uba85 \ubc0f \ub9ac\ubdf0 \ubc1b\ub294\ub2e4. \\n2. AWT\ub97c \uc0ac\uc6a9\ud55c \ubd80\ubd84\uc744 \ubb38\uc11c\ud654\ud558\uc5ec \uacf5\uc720\ud55c\ub2e4.\\n\\n### \ub808\ubca8 3\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70 \ub0b4\uc6a9 \ucd94\uac00\\n\\n\uae30\uc220 \uc120\ud0dd\uc744 \ud558\uae30 \uc704\ud55c \uc2e4\ud589 \uc2dc\uac04 \uce21\uc815\uc5d0 \uc624\ub958\uac00 \uc788\uc5c8\ub2e4. \\nAWT\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc2e4\ud589 \uc2dc\uac04\uc744 \uc81c\uc678\ud558\uba74 \ud30c\uc774\uc36c\uacfc \ube44\uc2b7\ud55c \uc2dc\uac04\uc548\uc5d0 \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud560 \uc218 \uc788\uc5c8\ub2e4."},{"id":"java-spring-springboot","metadata":{"permalink":"/java-spring-springboot","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx","source":"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx","title":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","description":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","date":"2023-07-24T00:00:00.000Z","formattedDate":"2023\ub144 7\uc6d4 24\uc77c","tags":[{"label":"Java","permalink":"/tags/java"},{"label":"Spring Boot","permalink":"/tags/spring-boot"},{"label":"Spring","permalink":"/tags/spring"}],"readingTime":4.725,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","slug":"java-spring-springboot","tags":["Java","Spring Boot","Spring"]},"unlisted":false,"prevItem":{"title":"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd","permalink":"/route-image-intro"},"nextItem":{"title":"\uc6f9\uc18c\ucf13","permalink":"/websocket"}},"content":"## \uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1\\n\\n\ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1\uc744 \uc0ac\uc6a9\ud558\uac8c \ub418\uc5c8\ub2e4. \\n2.7 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud560 \uc218\ub3c4 \uc788\uc5c8\uc9c0\ub9cc LTS \uae30\uac04\uacfc \ucde8\uc57d\uc810 \ud328\uce58\ub85c \uc778\ud55c \ubc84\uc804\uc5c5 \ub4f1\uc744 \uace0\ub824\ud588\uc744 \ub54c 3.1\uacfc \uc790\ubc14 17\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \ub354 \ud6a8\uc728\uc801\uc774\ub77c\uace0 \ud310\ub2e8\ud588\ub2e4.\\n\\n## \uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d\\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2\uae4c\uc9c0\ub294 \uc790\ubc14 11\uc744 \uc0ac\uc6a9\ud588\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c \uc790\ubc14 11\ubd80\ud130 \uc790\ubc14 17\uae4c\uc9c0\uc758 \ubcc0\uacbd\uc0ac\ud56d\uc744 \uc815\uc2dd \ub9b4\ub9ac\uc988 \uae30\uc900\uc73c\ub85c \uc815\ub9ac\ud574\ubcf4\ub824\uace0 \ud55c\ub2e4.\\n\\n### Switch Expressions(Java 14)\\n\\nJava 14\uc5d0\uc11c\ub294 \uae30\uc874\uc758 Switch \ubb38\uc744 \uac04\uacb0\ud558\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub294 Switch \uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\\n```java\\nenum RESULT {\\n WIN, LOSE, DRAW\\n}\\n\\nRESULT result = RESULT.WIN;\\n\\nint prize = switch (result) {\\n case WIN -> 10_000_000;\\n case LOSE, DRAW -> 5_000_000;\\n\\tdefault -> 0;\\n};\\n```\\n\\n\uc8fc\uc694 \ud2b9\uc9d5\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.\\n\\n- `->` \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 case\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc14\ub85c \ubc18\ud658\ud560 \uc218 \uc788\ub2e4.\\n- case\ub97c \ucf64\ub9c8(`,`)\ub85c \uc5f0\uacb0\ud558\uc5ec \ud558\ub098\uc758 case\uc5d0 \uc5ec\ub7ec \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.\\n- break \ubb38\uc774 \ud544\uc694 \uc5c6\ub2e4.\\n- default \ube14\ub85d\uc744 \ud1b5\ud574 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.\\n\\n### Text Block(Java 15)\\n\\nJava 15\uc5d0\ub294 \uc0c8\ub85c\uc6b4 \ubb38\uc790\uc5f4 \ud45c\ud604\ubc29\uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\uae34 \ubb38\uc790\uc5f4\uc744 + \uc5f0\uc0b0\uc790\uc758 \ub3c4\uc6c0 \uc5c6\uc774 \uac00\ub3c5\uc131\uc788\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub2e4.\\n\\n```java\\n@Repository\\npublic interface PostRepository extends JpaRepository<Post, Long> {\\n @Query(\\"\\"\\"\\n SELECT p FROM Post p\\n WHERE p.title LIKE %:keyword%\\n OR p.content LIKE %:keyword%\\n \\"\\"\\")\\n List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);\\n}\\n```\\n\\n### NPE \uba54\uc2dc\uc9c0(Java 15)\\n\\n```java\\nString name = null;\\nname.chars();\\n\\n/** \\n# before\\njava.lang.NullPointerException\\n\\tat com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)\\n\\n# after\\nCannot invoke \\"String.chars()\\" because \\"name\\" is null\\njava.lang.NullPointerException: Cannot invoke \\"String.chars()\\" because \\"name\\" is null\\n*/\\n```\\n\\n### Record(Java 16)\\n\\nLombok\uc758 `@Data`, kotlin\uc758 data \ud074\ub798\uc2a4\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4. \\nRecord\ub97c \uc120\uc5b8\ud558\ub294 \uacbd\uc6b0 \uc811\uadfc\uc790, \uc0dd\uc131\uc790, equals & hashcode, toString\uc774 \uc81c\uacf5\ub41c\ub2e4. \\n\ub370\uc774\ud130 \uc804\uc1a1 \uc6a9\ub3c4\ub85c \uc801\ud569\ud574 \ubcf4\uc778\ub2e4. \\n\\n```java\\npublic record PostDto(String title, String content) {\\n}\\n```\\n\\n### \ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d\\n\\n\uc774\uc678\uc5d0\ub3c4 stream\uc758 toList, \uc778\uc2a4\ud134\uc2a4\uc758 \ud0c0\uc785\uc744 \uac04\ud3b8\ud558\uac8c \uccb4\ud06c\ud558\ub294 Pattern Matching Instanceof, Sealed class \ub4f1\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\\n## \uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d\\n\\n\uc2a4\ud504\ub9c1\uacfc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\ub3c4 \ub9ce\uc740 \ubcc0\uacbd \uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c \ud544\uc694\ud574\ubcf4\uc774\ub294 \uba87\uac1c \uc815\ub3c4\ub9cc \uc815\ub9ac\ud588\ub2e4. \\n\\n### \uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d\\n\\nJava 17, Jakarta EE 9 \uc774\uc0c1\uc774\uc5b4\uc57c \ud55c\ub2e4.\\n\\n### \ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd\\n\\nJakarta EE 9\uac00 \uc801\uc6a9\ub418\uba74\uc11c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub3c4 \uc804\ubc18\uc801\uc73c\ub85c javax -> jakarta\ub85c \ubcc0\uacbd\ub418\uc5c8\ub2e4. \\n\\n### PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c\\n\\n6.0 \uc774\uc804\uc758 \uacbd\uc6b0 \uae30\ubcf8 \uc124\uc815 \uae30\uc900\uc73c\ub85c `@GetMapping(\\"/hello\\")`\uc640 `@GetMapping(\\"/hello/\\")`\uac00 \ub3d9\uc77c\ud588\ub2e4. \\n6.0 \uc774\ud6c4\uc758 PathPatternParser\uac00 \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\uace0, `/hello`\uc640 `/hello/`\ub294 \uc11c\ub85c \ub2e4\ub978 URL\ub85c \ub9e4\uce6d\ub41c\ub2e4. \\n\\n> PathPatternParser used by default (with the ability to opt into PathMatcher). \\n\\n### HTTP interface client\\n\\n\uc790\ubc14 \uc778\ud130\ud398\uc774\uc2a4\uc640 \uc5b4\ub178\ud14c\uc774\uc158\uc744 \uc774\uc6a9\ud558\uc5ec HTTP \uc694\uccad\uc744 \uc704\ud55c \uc11c\ube44\uc2a4\ub97c \uc815\uc758\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 [\ud1a0\ube44\ub2d8\uc758 \uac15\uc758](https://www.youtube.com/watch?v=Kb37Q5GCyZs)\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4.\\n\\n### \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d\\n\\nGradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6 \\n\uc774\uc678\uc5d0\ub3c4 \uc11c\ub4dc\ud30c\ud2f0\ub4e4\uc758 \ucd5c\uc2e0 \ub9b4\ub9ac\uc988 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c, \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ud574\ub2f9 \ubc84\uc804\uc5d0 \ub9de\ub294 \ub9b4\ub9ac\uc988 \ub178\ud2b8\ub97c \ucc38\uace0\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. \\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n[\uc5b4\ub290\xa0\uc6d4\uae09\uc7c1\uc774\uac1c\ubc1c\uc790\xa0\uc758 \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ub530\ub77c\uc7a1\uae30](https://www.youtube.com/watch?v=1WT6oxchM9M) \\n[\uc790\ubc14 9-16 \uc8fc\uc694 \ud2b9\uc9d5 \ubcf5\uc2b5\ud558\uae30](https://www.youtube.com/watch?v=7SlDdzVk6GE) \\n[Java EE\uc5d0\uc11c Jakarta EE\ub85c\uc758 \uc804\ud658](https://www.samsungsds.com/kr/insights/java_jakarta.html) \\n[Spring 6\uc758 \uc0c8\ub85c\uc6b4 HTTP Interface\uc640 3 \uac00\uc9c0 REST Clients \ub77c\uc774\ube0c \ucf54\ub529](https://www.youtube.com/watch?v=Kb37Q5GCyZs) \\n[What\'s New in Spring Framework 6.x](https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x) \\n[Spring Boot 3.0 Release Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes) \\n[Spring Boot 3.1 Release Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes)"},{"id":"websocket","metadata":{"permalink":"/websocket","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-26-WebSocket.mdx","source":"@site/blog/2023-2/2023-06-26-WebSocket.mdx","title":"\uc6f9\uc18c\ucf13","description":"\uc6f9\uc18c\ucf13","date":"2023-06-26T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 26\uc77c","tags":[{"label":"WebSocket","permalink":"/tags/web-socket"}],"readingTime":4.165,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6f9\uc18c\ucf13","slug":"websocket","tags":["WebSocket"]},"unlisted":false,"prevItem":{"title":"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1","permalink":"/java-spring-springboot"},"nextItem":{"title":"Docusaurus","permalink":"/docusaurus"}},"content":"### \uc6f9\uc18c\ucf13\\n\\n\ub2e8\uc77c TCP \uc5f0\uacb0\uc744 \ud1b5\ud574 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ubc84 \uac04 \uc804\uc774\uc911 \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \uc9c0\uc6d0\ud558\ub294 \ud504\ub85c\ud1a0\ucf5c \\n\uc6f9 \ud658\uacbd\uc5d0\uc11c \uc5f0\uc18d\ub41c \ub370\uc774\ud130\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4. \\n\\n\uc6f9\uc18c\ucf13\uc740 HTTP\uc758 \ud3ec\ud2b8\ub97c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uace0 \uac01\uac01 \ud3ec\ud2b8 80\uacfc \ud3ec\ud2b8 443\uc744 \uc0ac\uc6a9\ud558\uc5ec HTTP(ws://) \ubc0f HTTPS(wss://)\ub85c \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ud55c\ub2e4. \\n\\n### \uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd\\n\\n\uc6f9\uc18c\ucf13\uc774 \ub4f1\uc7a5\ud558\uae30 \uc774\uc804, \uc2e4\uc2dc\uac04\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 Polling, Long polling, Streaming \uac19\uc740 \uae30\uc220\uc744 \uc0ac\uc6a9\ud588\uc5b4\uc57c \ud588\ub2e4. \\n\uc774\ub294 \uc2e4\uc2dc\uac04\uc131\uc774\ub098 \uc591\ubc29\ud5a5\uc131\uc744 \ub9cc\uc871\uc2dc\ud0a4\uc9c0 \ubabb\ud588\uace0, HTTP\ub97c \uc774\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uacfc\ub3c4\ud55c \uc624\ubc84\ud5e4\ub4dc\uac00 \ubc1c\uc0dd\ud588\ub2e4. \\n\\n:::note polling, long polling, streaming\\n\\nPolling: \uc8fc\uae30\uc801\uc73c\ub85c \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ubcf4\ub0b4 \uc218\uc2e0\ud560 \uc815\ubcf4\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubc29\ubc95\\n- \uc11c\ubc84\uc5d0\uc11c \ubcf4\ub0bc \ub0b4\uc6a9\uc774 \uc5c6\uc5b4\ub3c4 \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \uc54c \uc218 \uc5c6\ub2e4. \\n- \uacc4\uc18d\ud574\uc11c \uc694\uccad\uc744 \ubcf4\ub0b4 \ud655\uc778\uc744 \ud574\uc57c\ud558\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ubd88\ud544\uc694\ud55c \ubd80\ud558\ub97c \uc8fc\uc5b4\uc57c \ud55c\ub2e4. \\n\\nLong Polling: \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc5d0 \ub300\ud574 \uc751\ub2f5\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uace0 \uc788\ub2e4\uac00 \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud588\uc744\ub54c \uc751\ub2f5\ud558\ub294 \ubc29\ubc95\\n- \ud3f4\ub9c1 \ubc29\uc2dd\ubcf4\ub2e4 \uc11c\ubc84\uc5d0 \uc801\uc740 \ubd80\ud558\ub97c \uc904 \uc218 \uc788\uc9c0\ub9cc, \uc694\uccad\uc758 \uc8fc\uae30\uac00 \uc9e7\uc73c\uba74 \ud3f4\ub9c1\uacfc \ucc28\uc774\uac00 \uc5c6\uc5b4\uc9c4\ub2e4.\\n\\nStreaming: \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 request\ub97c \ubcf4\ub0b4\uba74 \ucee4\ub125\uc158\uc744 \ub9fa\uace0, \uc774 \ucee4\ub125\uc158\uc744 \uc720\uc9c0\ud558\uba74\uc11c \uc11c\ubc84\uac00 \uacc4\uc18d \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95\\n- \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ud558\uace0 \uc2f6\ub2e4\uba74 \uc0c8\ub85c\uc6b4 \ucee4\ub125\uc158\uc744 \ub9fa\uc5b4\uc57c \ud55c\ub2e4. \\n:::\\n\\n### \uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791\\n\\n```mermaid\\nsequenceDiagram\\n participant Client\\n participant Server\\n Client->>Server: Handshake - Upgrade\ub97c \uc774\uc6a9\ud55c WebSocket \uc804\ud658 \uc694\uccad\\n Server->>Client: Handshake - HttpStatus 101(Switching Protocols)\\n\\n Client->>Server: \uc591\ubc29\ud5a5 \ud1b5\uc2e0\\n Server->>Client: \\n\\n Client->>Server: \uc885\ub8cc\\n Server->>Client: \\n```\\n\\n### 1. Upgrade \uc694\uccad\\n\\nWebSocket \ud504\ub85c\ud1a0\ucf5c\ub85c \uc804\ud658\ud558\ub294 HTTP \uc694\uccad\uc744 \ubcf4\ub0b8\ub2e4. \\n\uc774\ub294 HTTP\uc640 \uac19\uc774 80, 443 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud55c\ub2e4. \\n\uc6f9\uc18c\ucf13\uc73c\ub85c \uc804\ud658\ud558\uae30 \uc704\ud574\uc11c\ub294 Upgrade: websocket, Connection: Upgrade \ud5e4\ub354\uac00 \ud544\uc694\ud558\ub2e4. \\nSec-WebSocket-Key\ub294 \uc11c\ubc84\uc5d0\uc11c Sec-WebSocket-Accept\ub97c \uacc4\uc0b0\ud558\uc5ec \uc751\ub2f5\ud558\uace0 \uc774 \uac12\uc774 \uc608\uc0c1\ud55c \uac12\uacfc \ub2e4\ub974\uba74 \uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uc9c0 \uc54a\ub294\ub2e4. \\nSec-WebSocket-Protocol\uc758 \uacbd\uc6b0 \uc11c\ube0c\ud504\ub85c\ud1a0\ucf5c\uc758 \ubaa9\ub85d\uc73c\ub85c \uc11c\ubc84 \uce21\uc5d0\uc11c\ub294 \ud574\ub2f9 \ubaa9\ub85d \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud558\uc5ec \ubc18\ud658\ud574\uc57c \ud55c\ub2e4. \\n\ub9cc\uc57d \uc11c\ubc84\uce21\uc5d0\uc11c \uc5ec\ub7ec \uac1c \uc9c0\uc6d0\uc774 \uac00\ub2a5\ud55c \uacbd\uc6b0 \uc9c0\uc6d0 \uac00\ub2a5\ud55c \ud504\ub85c\ud1a0\ucf5c \uc911 \uccab\ubc88\uc9f8 \ud504\ub85c\ud1a0\ucf5c\uc744 \ud074\ub77c\uc774\uc5b8\ud2b8\uce21\uc73c\ub85c \ubcf4\ub0b8\ub2e4. \\n\\n```\\nGET /chats HTTP/1.1\\nHost: localhost:8080\\nUpgrade: websocket\\nConnection: Upgrade\\nSec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==\\nSec-WebSocket-Protocol: v10.stomp, v11.stomp\\nSec-WebSocket-Version: 13\\nOrigin: http://localhost:8080\\n```\\n\\n### 2. Switching Protocols\\n\\n\uc11c\ubc84\ub294 101 Switching Protocols \uc751\ub2f5\uc744 \ubc18\ud658\ud55c\ub2e4. \\nSec-WebSocket-Accept\uc740 Sec-WebSocket-Key \ub4a4\uc5d0 `258EAFA5-E914-47DA-95CA-C5AB0DC85B11`\ub97c \ubd99\uc774\uace0 SHA1\ub85c \ud574\uc2f1 \ud6c4 Base64\ub85c \uc778\ucf54\ub529\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4. \\n\uc774\ub294 \uc11c\ubc84 \uc6f9\uc18c\ucf13 \ud504\ub85c\ud1a0\ucf5c\uc758 \uc9c0\uc6d0 \uc5ec\ubd80\ub97c \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \uba85\ud655\ud788 \uc54c\ub9ac\uae30 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4. \\n\\n```\\nHTTP/1.1 101 Switching Protocols \\nUpgrade: websocket\\nConnection: Upgrade\\nSec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=\\nSec-WebSocket-Protocol: v10.stomp\\n```\\n\\n### 3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc\\n\\n\uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uba74 \uc6f9\uc18c\ucf13 \ud504\ub808\uc784 \ub2e8\uc704\ub85c \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \ud55c\ub2e4. \\n\uc5f0\uacb0 \uc885\ub8cc\ub97c \uc6d0\ud558\ub294 \uacbd\uc6b0 \ud074\ub77c\uc774\uc5b8\ud2b8, \uc11c\ubc84 \ubaa8\ub450 \uc5f0\uacb0 \uc885\ub8cc\ub97c \uc694\uccad\ud560 \uc218 \uc788\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\nhttps://datatracker.ietf.org/doc/html/rfc6455 \\nhttps://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications \\nhttps://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers \\nhttps://docs.spring.io/spring-framework/reference/web/websocket.html"},{"id":"docusaurus","metadata":{"permalink":"/docusaurus","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx","source":"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx","title":"Docusaurus","description":"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4.","date":"2023-06-18T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 18\uc77c","tags":[{"label":"Documentation","permalink":"/tags/documentation"}],"readingTime":10.095,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Docusaurus","slug":"docusaurus","tags":["Documentation"]},"unlisted":false,"prevItem":{"title":"\uc6f9\uc18c\ucf13","permalink":"/websocket"},"nextItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0","permalink":"/woowacourse-level2-retrospective"}},"content":"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4. \\n\\n## \uc124\uce58\\n\\n[\uacf5\uc2dd \ud648\ud398\uc774\uc9c0](https://docusaurus.io/docs/installation)\uc5d0 \ub4e4\uc5b4\uac00\uc11c \ucd5c\uc2e0 \ubc84\uc804\uc744 \uc124\uce58\ud55c\ub2e4. \\n\\n```bash\\nyarn create docusaurus\\n````\\n\\n## \ubc30\ud3ec\\n\\n[\ubc30\ud3ec \uc548\ub0b4 \ubb38\uc11c](https://docusaurus.io/docs/next/deployment#deploying-to-github-pages) \\nnetlify\ub098 vercel \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ud50c\ub7ab\ud3fc\uc744 \ucd94\ucc9c\ud558\uace0 \uc788\uace0, \uac04\ub2e8\ud558\uace0, \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \ubc30\ud3ec\ub97c \ud560 \uc218 \uc788\ub2e4. \\n\uc774 \uae00\uc5d0\uc11c\ub294 github pages\ub97c \uc774\uc6a9\ud574\uc11c \ubc30\ud3ec\ud558\ub294 \ubc29\ubc95\uc744 \uc124\uba85\ud55c\ub2e4.\\n\\n### \ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131\\n\\ngithub pages\ub97c \uc774\uc6a9\ud558\ub824\uba74 [\uc608\uc2dc](https://github.com/greeng00se/greeng00se.github.io)\uc640 \uac19\uc774 `username.github.io` \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4. \\n\uc774\ub54c organization\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 `organization.github.io` \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n### \uc124\uc815 \ud30c\uc77c \uc218\uc815\\n\\n```js title=\\"docusaurus.config\\"\\nmodule.exports = {\\n // ...\\n url: \'https://greeng00se.github.io\',\\n baseUrl: \'/\',\\n projectName: \'greeng00se.github.io\',\\n organizationName: \'greeng00se\',\\n trailingSlash: false,\\n // ...\\n};\\n```\\n\\n### \ud1a0\ud070 \uc124\uc815\\n\\ngithub action\uc744 \uc704\ud574 \ubc30\ud3ec\uc6a9 \ud1a0\ud070\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uc5ec \uc0dd\uc131\ud55c \ub808\ud3ec\uc9c0\ud1a0\ub9ac\uc5d0 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c\ub2e4. \\n\uc774 \uae00\uc5d0\uc11c\ub294 \ud1a0\ud070\uc744 \ud074\ub798\uc2dd \ubc29\uc2dd\uc73c\ub85c \uc0dd\uc131\ud588\uace0 \uc2a4\ucf54\ud504\ub294 [repo, user, workflow] \uc744 \uc124\uc815\ud588\ub2e4. \\n\\n![github](./github.png)\\n\\n### \ube0c\ub79c\uce58 \uc0dd\uc131\\n\\ngithub\uc5d0\uc11c gh-pages \ube0c\ub79c\uce58\ub97c \ud558\ub098 \uc0dd\uc131\ud55c\ub2e4. \\nrepository -> settings -> pages -> branch\uc5d0\uc11c \uc0dd\uc131\ud55c gh-pages\ub85c \ube0c\ub79c\uce58\ub97c \ubcc0\uacbd\ud55c\ub2e4. \\n\uc124\uc815\ud55c \ube0c\ub79c\uce58\uac00 \ubc30\ud3ec \ube0c\ub79c\uce58\uac00 \ub418\uba70, \ud574\ub2f9 \ube0c\ub79c\uce58\uc5d0 \uc788\ub294 \ud30c\uc77c\ub4e4\uc744 \uc774\uc6a9\ud574\uc11c \uc815\uc801 \uc6f9\uc0ac\uc774\ud2b8\ub97c \uc81c\uacf5\ud55c\ub2e4. \\n\\n### \uc6cc\ud06c\ud50c\ub85c \uc791\uc131\\n\\nDocusaurus 2.0 \uae30\uc900 Node.js 16.14 \uc774\uc0c1\uc758 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4. \\n\ubc30\ud3ec\uc2dc\uc5d0\ub294 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c DEPLOY_TOKEN \uc744 \uc774\uc6a9\ud569\ub2c8\ub2e4. \\n\\n```yml title=\\".github/workflows/deploy.yml\\"\\nname: blog\\n\\non:\\n push:\\n branches: [main]\\n\\njobs:\\n deploy:\\n name: Deploy to GitHub Pages\\n runs-on: ubuntu-latest\\n steps:\\n - uses: actions/checkout@v2\\n - uses: actions/setup-node@v3\\n with:\\n node-version: 18\\n cache: yarn\\n\\n - name: Install dependencies\\n run: yarn install --frozen-lockfile\\n - name: Build website\\n run: yarn build\\n\\n - name: Deploy to GitHub Pages\\n uses: peaceiris/actions-gh-pages@v3\\n with:\\n github_token: ${{ secrets.DEPLOY_TOKEN }}\\n publish_dir: ./build\\n user_name: github-actions[bot]\\n user_email: 41898282+github-actions[bot]@users.noreply.github.com\\n```\\n\\n## \ub313\uae00 \uae30\ub2a5\\n\\ngiscus\ub97c \uc774\uc6a9\ud558\uc5ec \ub313\uae00 \uae30\ub2a5\uc744 \ucd94\uac00\ud55c\ub2e4. \\n\\n### giscus \uc124\uc815\\n\\n1. \uacf5\uac1c \uc800\uc7a5\uc18c\uc5ec\uc57c \ud55c\ub2e4.\\n2. giscus \uc571\uc774 \uc124\uce58\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4.\\n3. Discussions \uae30\ub2a5\uc774 \ud574\ub2f9 \uc800\uc7a5\uc18c\uc5d0\uc11c \ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4.\\n\\n\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 [giscus](https://giscus.app/ko)\ub97c \ud655\uc778\ud558\uc790.\\n\\n### docusaurus \uc124\uc815\\n\\n[swizzling](https://docusaurus.io/ko/docs/next/swizzling)\uc744 \uc774\uc6a9\ud558\uc5ec \ucef4\ud3ec\ub10c\ud2b8\ub97c \uac10\uc2fc\ub2e4. \\n\uae30\uc874\uc5d0 \uac8c\uc2dc\ubb3c\uc744 giscus\uac00 \ud3ec\ud568\ub41c \ub9ac\uc561\ud2b8 \ucef4\ud3ec\ub10c\ud2b8\ub85c \uac10\uc2f8\ub294 \ud615\ud0dc\uac00 \ub41c\ub2e4. \\n\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec BlogPostItem\uc744 \ucd94\ucd9c\ud560 \uc218 \uc788\ub2e4. \\n\\n```bash\\nyarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap\\n```\\n\\n\uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uba74 `/src/theme/BlogPostItem/index.js` \uc704\uce58\uc5d0 \ud30c\uc77c\uc774 \uc0dd\uc131\ub41c\ub2e4. \\n\ud30c\uc77c\uc758 \ub0b4\uc6a9\uc744 \uc544\ub798\uc640 \uac19\uc774 \uc218\uc815\ud558\uace0, \uc774\ub54c setAttribute \ubd80\ubd84\uc740 \uc801\uc808\ud558\uac8c \uc790\uc2e0\uc758 giscus \uc124\uc815\uc744 \uc774\uc6a9\ud55c\ub2e4. \\n\\n```js title=\\"/src/theme/BlogPostItem/index.js\\"\\nimport OriginalBlogPostItem from \\"@theme-original/BlogPostItem\\";\\nimport React, { useEffect, useRef } from \\"react\\";\\n// @ts-expect-error internal code\\nimport { useColorMode } from \\"@docusaurus/theme-common\\";\\nimport { useBlogPost } from \\"@docusaurus/theme-common/internal\\";\\n\\nconst giscusSelector = \\"iframe.giscus-frame\\";\\n\\nfunction BlogPostItem(props) {\\n const { colorMode } = useColorMode();\\n const { isBlogPostPage } = useBlogPost();\\n const giscusTheme = colorMode === \\"dark\\" ? \\"dark\\" : \\"light\\";\\n const containerRef = useRef(null);\\n\\n useEffect(() => {\\n if (!isBlogPostPage) return;\\n\\n const giscusEl = containerRef.current.querySelector(giscusSelector);\\n\\n const createGiscusEl = () => {\\n const script = document.createElement(\\"script\\");\\n\\n script.src = \\"https://giscus.app/client.js\\";\\n script.setAttribute(\\"data-repo\\", \\"teco-chat/teco-chat.github.io\\");\\n script.setAttribute(\\"data-repo-id\\", \\"R_kgDOJZ5j0Q\\");\\n script.setAttribute(\\"data-category\\", \\"Announcements\\");\\n script.setAttribute(\\"data-category-id\\", \\"DIC_kwDOJZ5j0c4CXS_Q\\");\\n script.setAttribute(\\"data-mapping\\", \\"pathname\\");\\n script.setAttribute(\\"data-strict\\", \\"0\\");\\n script.setAttribute(\\"data-reactions-enabled\\", \\"1\\");\\n script.setAttribute(\\"data-emit-metadata\\", \\"0\\");\\n script.setAttribute(\\"data-input-position\\", \\"bottom\\");\\n script.setAttribute(\\"data-theme\\", giscusTheme);\\n script.setAttribute(\\"data-lang\\", \\"ko\\");\\n script.crossOrigin = \\"anonymous\\";\\n script.async = true;\\n \\n containerRef.current.appendChild(script);\\n };\\n\\n const postThemeMessage = () => {\\n const message = {\\n setConfig: {\\n theme: giscusTheme,\\n }\\n };\\n\\n giscusEl.contentWindow.postMessage({ giscus: message }, \\"https://giscus.app\\");\\n };\\n\\n giscusEl ? postThemeMessage() : createGiscusEl();\\n }, [giscusTheme]);\\n\\n return (\\n <>\\n <OriginalBlogPostItem {...props} />\\n {isBlogPostPage && <div ref={containerRef} />}\\n </>\\n );\\n}\\n\\nexport default BlogPostItem;\\n```\\n\\n## \uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30\\n\\n\uc54c\uace0\ub9ac\uc544\ub97c \uc0ac\uc6a9\ud558\uba74 \uac80\uc0c9 \uae30\ub2a5\uc744 \ucd94\uac00\ud560 \uc218 \uc788\ub2e4. \\n\uc720\ub8cc \ud50c\ub79c\uc774\ub098 netlify\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ud06c\ub864\ub7ec\ub97c \ub530\ub85c \uc81c\uacf5\ud574 \uc8fc\ub294 \uac83 \uac19\ub2e4. \\n\\n\ubb34\ub8cc \ud50c\ub79c\uc740 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uacfc, [docsearch](https://docsearch.algolia.com/)\ub97c \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4. \\ndocsearch\uc5d0 \ub4f1\ub85d\ud55c\ub2e4\uba74 \uc77c\uc8fc\uc77c\uc5d0 \ud55c \ubc88\uc529 \ud06c\ub864\ub9c1\uc774 \uc9c4\ud589\ub41c\ub2e4. \\n\uc774 \uae00\uc5d0\uc11c\ub294 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n- [\uc9c1\uc811 \uc778\ub371\uc2a4 \uc218\uc9d1](https://docsearch.algolia.com/docs/legacy/run-your-own/) \\n- [\uc124\uc815 \ud30c\uc77c](https://docsearch.algolia.com/docs/legacy/config-file)\\n\\n### \uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778\\n\\n\ud68c\uc6d0\uac00\uc785\uc744 \ud558\uace0 \uc0c8\ub85c\uc6b4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131\uc744 \ub204\ub978\ub2e4. \\n\uc0dd\uc131\uc744 \ub2e4 \ub9c8\uce58\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 api \ud0a4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n![algolia](./algolia.png)\\n\\n### \ud0a4 \uc0dd\uc131\\n\\n\uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\uae30 \uc704\ud55c \ud0a4\ub97c \uc0dd\uc131\ud55c\ub2e4. \\naddObject, editSettings, deleteIndex acl(\uc811\uadfc \uc81c\uc5b4 \ubaa9\ub85d)\uc774 \uc788\uc73c\uba74 \ub41c\ub2e4. \\n\\n![key](./key.png)\\n\\n### .env \ud30c\uc77c \uc0dd\uc131\\n\\n\ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354 \uc0c1\ub2e8\uc5d0 .env \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4. \\n\\n```bash title=\\".env\\"\\nAPPLICATION_ID=MVIU5UEMOM\\nAPI_KEY=\uc778\ub371\uc2a4_\uc0dd\uc131\uc6a9_\ud0a4\\n```\\n\\n### config \ud30c\uc77c \uc0dd\uc131\\n\\n\ub9c8\ucc2c\uac00\uc9c0\ub85c \ucd5c\uc0c1\ub2e8\uc5d0 config.json \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4.\\n\uc124\uc815 \ud30c\uc77c\uc740 \ud574\ub2f9 [\ub9c1\ud06c](https://docsearch.algolia.com/docs/legacy/config-file)\ub97c \ucc38\uace0\ud55c\ub2e4. \\n\ub610\ub294 Docusaurus\uc758 [\uc124\uc815 \ud30c\uc77c](https://github.com/algolia/docsearch-configs/blob/master/configs/docusaurus-2.json)\uc744 \ucc38\uace0\ud55c\ub2e4.\\n\\n```json title=\\"config.json\\"\\n{\\n \\"index_name\\": \\"teco\\",\\n \\"start_urls\\": [\\n \\"https://teco-chat.github.io/\\"\\n ],\\n \\"sitemap_urls\\": [\\n \\"https://teco-chat.github.io/sitemap.xml\\"\\n ],\\n \\"sitemap_alternate_links\\": true,\\n \\"stop_urls\\": [\\n \\"/tests\\"\\n ],\\n \\"selectors\\": {\\n \\"lvl0\\": {\\n \\"selector\\": \\"(//ul[contains(@class,\'menu__list\')]//a[contains(@class, \'menu__link menu__link--sublist menu__link--active\')]/text() | //nav[contains(@class, \'navbar\')]//a[contains(@class, \'navbar__link--active\')]/text())[last()]\\",\\n \\"type\\": \\"xpath\\",\\n \\"global\\": true,\\n \\"default_value\\": \\"Documentation\\"\\n },\\n \\"lvl1\\": \\"header h1\\",\\n \\"lvl2\\": \\"article h2\\",\\n \\"lvl3\\": \\"article h3\\",\\n \\"lvl4\\": \\"article h4\\",\\n \\"lvl5\\": \\"article h5, article td:first-child\\",\\n \\"lvl6\\": \\"article h6\\",\\n \\"text\\": \\"article p, article li, article td:last-child\\"\\n },\\n \\"strip_chars\\": \\" .,;:#\\",\\n \\"custom_settings\\": {\\n \\"separatorsToIndex\\": \\"_\\",\\n \\"attributesForFaceting\\": [\\n \\"language\\",\\n \\"version\\",\\n \\"type\\",\\n \\"docusaurus_tag\\"\\n ],\\n \\"attributesToRetrieve\\": [\\n \\"hierarchy\\",\\n \\"content\\",\\n \\"anchor\\",\\n \\"url\\",\\n \\"url_without_anchor\\",\\n \\"type\\"\\n ]\\n },\\n \\"conversation_id\\": [\\n \\"833762294\\"\\n ],\\n \\"nb_hits\\": 46250\\n}\\n```\\n\\n### docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1\\n\\ndocker\uc640 jq\uac00 \ud544\uc694\ud558\ub2e4. \\njq\uac00 \uc124\uce58\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc73c\uba74 mac \uae30\uc900 brew\ub97c \uc774\uc6a9\ud574\uc11c \uc124\uce58\ud560 \uc218 \uc788\ub2e4. \\n\\n```bash\\nbrew install jq\\n```\\n\\n\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec .env\uc640 config.json\uc744 \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1\uc744 \ud55c\ub2e4. \\n\\n```bash\\ndocker run -it --env-file=.env -e \\"CONFIG=$(cat ./config.json | jq -r tostring)\\" algolia/docsearch-scraper\\n```\\n\\n### docusaurus \uc124\uc815\\n\\n\uc804\uc5d0 \ud655\uc778\ud55c APP ID, Search-Only API KEY, IndexName\uc744 \uc774\uc6a9\ud558\uc5ec docusaurus.config \ud30c\uc77c\uc5d0 \uc124\uc815\ud55c\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\nthemeConfig:\\n /** @type {import(\'@docusaurus/preset-classic\').ThemeConfig} */\\n ({\\n ...\\n algolia: {\\n appId: \'MVIU5UEMOM\', // Application ID\\n apiKey: \'b68f378013817d9a190df88cdde226a0\', // Search-Only API Key\\n indexName: \'teco\', // config.json\uc5d0 \uc124\uc815\ud55c \uc778\ub371\uc2a4\uba85\\n contextualSearch: true,\\n },\\n })\\n```\\n\\n## \ubd80\uac00 \uc124\uc815\\n\\n### \ud654\uba74 \uc0c1\ub2e8 Github Icon\\n\\n\ud30c\uc77c \ucd5c\ud558\ub2e8\uc5d0 \uc544\ub798 css \uad6c\ubb38\uc744 \ucd94\uac00\ud55c\ub2e4.\\n\\n```css title=\\"/src/css/custom.css\\"\\n.header-github-link:hover {\\n opacity: 0.6;\\n}\\n\\n.header-github-link:before {\\n content: \'\';\\n width: 24px;\\n height: 24px;\\n display: flex;\\n background: url(\\"data:image/svg+xml,%3Csvg viewBox=\'0 0 24 24\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cpath d=\'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\'/%3E%3C/svg%3E\\")\\n no-repeat;\\n}\\n\\nhtml[data-theme=\'dark\'] .header-github-link:before {\\n background: url(\\"data:image/svg+xml,%3Csvg viewBox=\'0 0 24 24\' xmlns=\'http://www.w3.org/2000/svg\'%3E%3Cpath fill=\'white\' d=\'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\'/%3E%3C/svg%3E\\")\\n no-repeat;\\n}\\n```\\n\\nthemeconfig -> navbar\uc5d0 github link\ub97c \uc124\uc815\ud55c\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\nnavbar: {\\n title: \'HELLO\',\\n items: [\\n {\\n href: \'https://github.com/greeng00se\',\\n position: \'right\',\\n className: \'header-github-link\',\\n \'aria-label\': \'GitHub repository\',\\n },\\n ],\\n},\\n```\\n\\n### \ucf54\ub4dc\ube14\ub7ed\\n\\njava\ub098 kotlin\uc758 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ud558\uc774\ub77c\uc774\ud305\uc744 \uc9c0\uc6d0\ud574 \uc8fc\uc9c0 \uc54a\ub294\ub2e4. \\nprism \uc124\uc815\uc744 \uc544\ub798\uc640 \uac19\uc774 \ubcc0\uacbd\ud574 \uc900\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\nprism: {\\n theme: lightCodeTheme,\\n darkTheme: darkCodeTheme,\\n additionalLanguages: [\'java\', \'kotlin\'],\\n}\\n```\\n\\n### mermaid\\n\\nmermaid\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 `@docusaurus/theme-mermaid` \ub97c \uc124\uce58\ud574\uc57c \ud55c\ub2e4.\\n\\n```bash\\nyarn add @docusaurus/theme-mermaid\\n```\\n\\n\uc124\uce58 \ud6c4 \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\uc744 \ucd94\uac00\ud55c\ub2e4.\\n\\n```js title=\\"docusaurus.config\\"\\nconst config = {\\n ...\\n markdown: {\\n mermaid: true,\\n },\\n themes: [\\n \'@docusaurus/theme-mermaid\'\\n ],\\n};\\n```\\n\\nthemeConfig\uc5d0\uc11c mermaid\uc758 \ud14c\ub9c8\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\nthemeConfig:\\n /** @type {import(\'@docusaurus/preset-classic\').ThemeConfig} */\\n ({\\n ...\\n mermaid: {\\n theme: {\\n light: \'neutral\', \\n dark: \'dark\'\\n },\\n },\\n }),\\n```\\n\\n### \uad6d\uc81c\ud654 \uc124\uc815\\n\\n\uad6d\uc81c\ud654 \uc124\uc815\uc744 \ud55c\ub2e4\uba74 `Older Entries` \ud615\ud0dc\uc758 \uc124\uba85\uc774 `\ub2e4\uc74c \ud398\uc774\uc9c0` \ub85c \ubcc0\uacbd\ub41c\ub2e4. \\n\uc124\uc815\ud30c\uc77c\uc5d0\uc11c i18n\uc5d0 \uc788\ub294 \ub85c\ucf00\uc77c \uc124\uc815\uc744 ko\ub85c \ubcc0\uacbd\ud558\uba74 \ub41c\ub2e4. \\n\\n```js title=\\"docusaurus.config\\"\\ni18n: {\\n defaultLocale: \\"ko\\",\\n locales: [\\"ko\\"],\\n},\\n```\\n\\n### \ube14\ub85c\uadf8 \uae00 author\\n\\n\ud300\uc6d0 \ubcc4\ub85c \ubb38\uc11c\ub97c \uad00\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 \uc5b4\ub5a4 \ud300\uc6d0\uc774 \uae00\uc744 \uc791\uc131\ud588\ub294\uc9c0 \uc124\uc815\ud574\uc57c \ud55c\ub2e4. \\n\\n![author](./author.png)\\n\\n`authors.yml` \ud30c\uc77c\uc744 \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790\uc5d0 \ub300\ud55c \uae30\ubcf8 \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\\n```yml title=\\"/blog/authors.yml\\"\\nherb:\\n name: \ud5c8\ube0c\\n title: Backend\\n url: https://github.com/greeng00se\\n image_url: https://github.com/greeng00se.png\\n\\nmallang:\\n name: \ub9d0\ub791\\n title: Backend\\n url: https://github.com/shin-mallang\\n image_url: https://github.com/shin-mallang.png\\n```\\n\\n\ube14\ub85c\uadf8 \uae00\uc744 \uc791\uc131\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc774 authors\uc5d0 \ub123\uc5b4\uc8fc\uae30\ub9cc \ud558\uba74 \ub41c\ub2e4. \\n\\n```mdx\\n---\\nslug: 1\\ntitle: Hello World\\nauthors: [herb, mallang]\\ntags: [hello, docusaurus]\\n---\\n\\n\uccab \ubc88\uc9f8 \ubb38\uc11c \ub0b4\uc6a9\\n```"},{"id":"woowacourse-level2-retrospective","metadata":{"permalink":"/woowacourse-level2-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx","title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0","description":"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4.","date":"2023-06-11T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 11\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":2.545,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0","slug":"woowacourse-level2-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"Docusaurus","permalink":"/docusaurus"},"nextItem":{"title":"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0","permalink":"/level2-interview-retrospective"}},"content":"23\ub144\uc758 6\uc6d4\uc774 \uc624\uace0, \ub808\ubca8 2\uac00 \ub05d\ub0ac\ub2e4. \\n\ube60\ub974\uac8c \uc9c0\ub098\uac00\uc11c \uc870\uae08 \uc544\uc27d\ub2e4. \\n\\n### \ud559\uc2b5\\n\\n\ud68c\uace0\ub97c \uc791\uc131\ud558\uae30 \uc804\uc5d0 \ub808\ubca8 2 \ub3d9\uc548 \ubcf4\ub0c8\ub358 PR\uacfc \ud68c\uace0\ub97c \ucb49 \uc77d\uc5b4\ubd24\ub2e4. \\n\ud56d\uc0c1 \uc544\uc26c\uc6b4 \uacf3\uc740 \uc788\uae30 \ub9c8\ub828\uc774\uc9c0\ub9cc, \uc798 \ud559\uc2b5\ud55c \uac83 \uac19\ub2e4. \\n\ubbf8\uc158\uc744 \ud558\uba74\uc11c \uae30\uc220\uc744 \uc5b4\ub5bb\uac8c \uc120\ud0dd\ud558\uace0, \uc801\uc6a9\ud560 \uac83\uc778\uc9c0 \uace0\ubbfc\ud558\ub294 \uacfc\uc815\uc5d0\uc11c \uaf64\ub098 \ub9ce\uc740 \uc131\uc7a5\uc744 \ud55c \uac83 \uac19\ub2e4. \\n\\n\uace0\ubbfc\uc740 \uae4a\uc5c8\uc9c0\ub9cc \uc774\ub860\uc801\uc778 \ud559\uc2b5\uc774 \ubd80\uc871\ud55c \ub808\ubca8 2\uc600\ub2e4. \\n\ubc29\ud559 \uadf8\ub9ac\uace0 \ub808\ubca8 3 \ub54c\ub294 \uc870\uae08 \ub354 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc744 \ud559\uc2b5\ud558\ub294\ub370 \uc9d1\uc911\ud574\uc57c\uaca0\ub2e4. \\n\\n\uc810\ucc28 \ud559\uc2b5 \ubc94\uc704\uac00 \ub113\uc5b4\uc9c0\uba74\uc11c \uc790\uc5f0\uc2a4\ub7fd\uac8c \ubaa8\ub974\ub294 \ub0b4\uc6a9\uc774 \uc313\uc5ec\uac04\ub2e4. \\n\ud544\uc694\ud55c \ub0b4\uc6a9\uc740 \uc55e\uc73c\ub85c \ucc9c\ucc9c\ud788 \ud559\uc2b5\ud558\uba74 \ub418\ub2c8\uae4c \uc870\uae09\ud574\uc9c0\uc9c0 \ub9d0\uc544\uc57c\uaca0\ub2e4. \\n\\n### \uc218\uba74\\n\\n\ub808\ubca8 2\ub97c \uc9c4\ud589\ud558\ub294 \ub3d9\uc548 \uc218\uba74\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\uc5c8\uace0, \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \uadf8\ub0a0\uc758 \ucee8\ub514\uc158\uc744 \ub9ce\uc774 \uc88c\uc6b0\ud588\ub358 \uac83 \uac19\ub2e4. \\n\uc55e\uc73c\ub85c \uc218\uba74 \uc2dc\uac04\uc744 \ub298\ub9ac\uace0, \uc88b\uc740 \uc218\uba74 \uc2b5\uad00\uc744 \uac00\uc9c0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. \\n\\n### \ud611\uc5c5\\n\\n\ub808\ubca8 2 \ub9c8\uc9c0\ub9c9\uc5d0 \ud611\uc5c5 \ubbf8\uc158\uc774 \uc788\uc5c8\ub2e4. \\n\uc9c0\uae08\uae4c\uc9c0\ub294 \ubc31\uc5d4\ub4dc \ud06c\ub8e8\ub4e4\uacfc \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud558\uba74\uc11c \ud611\uc5c5\uc744 \uacbd\ud5d8\ud588\ub2e4. \\n\uc774\ubc88\uc5d0\ub294 \ud504\ub7f0\ud2b8\uc5d4\ub4dc \ud06c\ub8e8\uc640 \ud611\uc5c5\uc744 \ud588\ub2e4. \uc18c\ud1b5\uc740 \uc798 \ub41c \uac83 \uac19\uc9c0\ub9cc API \uba85\uc138\ub97c \uc815\ud558\ub294 \ubd80\ubd84\uc774 \uc544\uc9c1 \ubbf8\uc219\ud55c \uac83 \uac19\ub2e4. \\n\\n\ub808\ubca8 3 \ub54c\ubd80\ud130 \ubcf8\uaca9\uc801\uc73c\ub85c \ud504\ub85c\uc81d\ud2b8\uac00 \uc2dc\uc791\ub41c\ub2e4. \\n\ud300\uc744 \uc704\ud574 \uc5b4\ub5a4 \uac83\uc744 \ud560 \uc218 \uc788\uc744\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud574\ubd10\uc57c\uaca0\ub2e4. \\n\\n### \ub808\ubca8 2\ub97c \ub9c8\ubb34\ub9ac\ud558\uba70\\n\\n\ud68c\uace0 \uc791\uc131\ud558\uba74\uc11c \ub808\ubca8 2\uc5d0\uc11c \ud588\ub358 \uac83\ub4e4\uc744 \ubc18\ucd94\ud574 \ubd24\ub294\ub370 \ubd80\uc871\ud55c \uc810\uc740 \ub9ce\uc558\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \uac00\uace0 \uc788\ub294 \uac83 \uac19\ub2e4.\\n\uc77d\uace0 \uc2f6\uc740 \ucc45\ub3c4 \uc77d\uace0, \ubd80\uc871\ud55c \ubd80\ubd84 \ucc44\uc6b0\uba74\uc11c \uc26c\uc5b4\uc57c\uaca0\ub2e4."},{"id":"level2-interview-retrospective","metadata":{"permalink":"/level2-interview-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx","title":"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0","description":"\ub808\ubca8 \uc778\ud130\ubdf0","date":"2023-06-08T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 8\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.435,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0","slug":"level2-interview-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0","permalink":"/woowacourse-level2-retrospective"},"nextItem":{"title":"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0","permalink":"/order-retrospective"}},"content":"### \ub808\ubca8 \uc778\ud130\ubdf0\\n\\n\ub808\ubca8 1 \ub54c\ub294 \uc900\ube44\ud574\ub454 \ub0b4\uc6a9\uc73c\ub85c \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud574\uc11c \uadf8\ub807\uac8c \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc774 \uc5c6\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c \ub808\ubca8 1 \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0\ub294 \ub808\ubca8 1 \ud68c\uace0\ub97c \uc791\uc131\ud560 \ub54c \ub07c\uc6cc\ub123\uc5c8\ub2e4. \\n\uc774\ubc88\uc5d0\ub294 \ubc94\uc704\ub3c4 \uc81c\ud55c\ub418\uc5b4 \uc788\uc5b4 \uc5b4\ub5bb\uac8c \uc900\ube44\ud574\uc57c \ud560\uc9c0 \ub2f9\ud669\ud588\uace0, \ub2f5\ubcc0\uc5d0\ub3c4 \ubd80\uc871\ud55c \ubd80\ubd84\uc774 \ub9ce\uc558\uc5c8\ub2e4. \\n\uae30\uc5b5\uc774 \uc0ac\ub77c\uc9c0\uae30 \uc804\uc5d0 \ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\ud55c \ub0b4\uc6a9\uc744 \uc81c\uc678\ud558\uace0, \uae30\uc5b5 \ub0a8\ub294 \uac83 \uc704\uc8fc\ub85c \uc791\uc131\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4. \\n\\n### API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd\\n\\n\ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\uc744 \ud588\ub294\ub370 \uc55e\uc73c\ub85c\ub3c4 \ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \ud558\uba74\uc11c \ub3c4\uc6c0 \ub420 \uac83 \uac19\uc740 \ub0b4\uc6a9\uc774 \uc788\uc5b4\uc11c \ub0a8\uaca8\ub450\ub824\uace0 \ud55c\ub2e4. \\n\ubc31\uc5d4\ub4dc \ud300\uc6d0\uc774 \ud568\uaed8 \uc758\uc0ac\uacb0\uc815\uc744 \ud588\uace0, \ubbf8\uc158 \uae30\uac04\uc774 \uc9e7\uc740 \ub9cc\ud07c \ud300 \ucc28\uc6d0\uc5d0\uc11c \ube44\uad50\uc801 \ud559\uc2b5\ud558\uae30 \uc26c\uc6b4 Swagger\ub97c \uc120\ud0dd\ud588\ub2e4. \\n\ucd94\uac00\ub85c \ub4e4\uc5b4\uac00\ub294 \uc2dc\uac04 \ub300\ube44 \ud558\uc774 \ub9ac\ud134\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4\uace0 \ub2f5\ubcc0\ud588\ub2e4.\\n\\n\ud300 \ucc28\uc6d0\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uc5b8\uae09\ud574\uc11c, \ub2e4\uc74c\uacfc \uac19\uc740 \uc88b\uc740 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4.\\n\\n> \ud2b9\ud788 \ud300\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\ud558\ub294 \uacfc\uc815\uc744 \uacf5\uc720\ud574 \uc900 \uc810\uc774 \uc88b\uc558\uace0 \uae30\uc220\uc801 \uc758\uc0ac\uacb0\uc815 \uacfc\uc815\uc5d0\uc11c \ud300\uc758 \ud559\uc2b5\ube44\uc6a9\uc744 \uace0\ub824\ud55c \uc810\uc774 \uc88b\uc558\uc74c. \\n> \uc55e\uc73c\ub85c\ub3c4 \ud559\uc2b5 \ube44\uc6a9\uc740 \uc8fc\uc694\ud558\uac8c \uace0\ub824\ud574\uc57c \ud560 \uc0ac\ud56d\\n>\\n\\n### PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158\\n\\nPUT\uacfc PATCH \ucc28\uc774\ub97c \uc124\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c\ub294 PATCH\ub97c \uc0ac\uc6a9\ud560 \ub54c \ud398\uc774\ub85c\ub4dc\uac00 \uc801\uc5b4\uc9c4\ub2e4\ub294 \ub0b4\uc6a9\uc744 \ube7c\uba39\uace0 \ub2f5\ubcc0\uc744 \ud588\ub2e4. \\n\ud1a0\ud070\uacfc \uc138\uc158\uc758 \uacbd\uc6b0 \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud574\ub2ec\ub77c\ub294 \uc81c\uc57d\uc870\uac74\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\n\\n\ud574\ub2f9 \ub0b4\uc6a9\uc744 \ub2f5\ubcc0\ud558\uba74\uc11c \uae30\uc220\uc801\uc778 \uae4a\uc774\uac00 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4. \\n\uc2e4\uc81c\ub85c \ub808\ubca8 2 \ub54c \uc774\ub860\uc801\uc778 \ud559\uc2b5 \uc2dc\uac04\uc774 \ub9e4\uc6b0 \uc801\uc5c8\uace0, \uc9d1\uc911\ub825\ub3c4 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4. \\n\uc55e\uc73c\ub85c \uc5b4\ub5bb\uac8c \uae4a\uc774\ub97c \ucc44\uc6b8\uc9c0 \uace0\ubbfc\uc744 \ud560 \uc218 \uc788\ub294 \uc9c8\ubb38\ub4e4\uc774\uc5c8\ub2e4. \\n\\n\ucd94\uac00\ub85c \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud558\ub294 \uac00\uc815\uc744 \ub450\uace0 \ud559\uc2b5\uc744 \ud55c\ub2e4\uba74 \ud070 \ub3c4\uc6c0\uc774 \ub420 \uac70\ub77c\ub294 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4. \\n\\n### \uadf8 \uc678 \uac1c\uc120\ud560 \uc810\\n\\n\uc778\ud130\ubdf0\ud560 \ub54c \ud2b9\uc720\uc758 \ub9d0\ubc84\ub987\uc744 \uac1c\uc120\ud558\uae30 \\n\uc0dd\uac01\ud560 \uc2dc\uac04\uc744 \uac00\uc84c\uc744 \ub54c \\"\ub2e4\uc2dc \ub9d0\uc500\ub4dc\ub824\ub3c4 \ub420\uae4c\uc694?\\"\ub77c\uace0 \ub9d0\ud558\uace0 \ub2f5\ubcc0\uc744 \uc774\uc5b4\ub098\uac00\uae30 \\n\uae30\uc220\uc801\uc73c\ub85c \uae4a\uc774\uac00 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5b4\uc11c \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\uae30 \\n\uc774\uc804\uc5d0 \uacf5\ubd80\ud588\ub358\uac70 \ub418\ub3cc\uc544 \ubcf4\ub294 \uc2dc\uac04 \uac00\uc9c0\uae30"},{"id":"order-retrospective","metadata":{"permalink":"/order-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4: AWS \ubc30\ud3ec","date":"2023-06-04T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 4\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":4.67,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0","slug":"order-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0","permalink":"/level2-interview-retrospective"},"nextItem":{"title":"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604","permalink":"/tecochat-retrospective-3"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: AWS \ubc30\ud3ec \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-shopping-order/pull/7 \\n:::\\n\\n### \uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158\\n\\n\ubc30\ud3ec \ubc0f \ud611\uc5c5\uc744 \ud560 \uc218 \uc788\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n\ub9c8\ucf54, \uc6b0\uac00, \uc6b0\ucf54, \uc6b0\uc2a4 \uadf8\ub9ac\uace0 \ub098\uae4c\uc9c0 \ud569\uccd0\uc11c 5\uba85\uc774 \ud55c \ud300\uc774 \ub418\uc5c8\ub2e4. \\n\\n### \ubc30\ud3ec\\n\\n\uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac AWS\ub97c \uc774\uc6a9\ud574 \ubc30\ud3ec\ub97c \ud574\uc57c \ud588\ub2e4. \\n\uac01\uc790 \ud558\ub098\uc758 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc744 \uc218 \uc788\uc5c8\uace0, \ud300 \ubcc4\ub85c DB\ub97c \uc704\ud55c \ucd94\uac00 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc558\ub2e4. \\n\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc791\uc131\ud558\ub294 \uacbd\ud5d8\uc744 \ud574\ubcfc \uc218 \uc788\uc5c8\ub2e4. \\n\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc2dc\uac04\uc744 \ub9ce\uc774 \ud22c\uc790\ud558\uc9c4 \uc54a\uc558\uace0, \ub2e4\uc74c\uacfc \uac19\uc774 \uac04\ub2e8\ud558\uac8c \uc791\uc131\ud588\ub2e4.\\n\\n```bash\\necho \\"Start Deploy Script\\"\\nREPOSITORY_NAME=/home/ubuntu/jwp-shopping-order\\nPROJECT_NAME=jwp-shopping-order\\n\\necho \\"Change Directory\\"\\ncd $REPOSITORY_NAME\\n\\necho \\"Git Pull\\"\\ngit pull origin step2\\n\\necho \\"Build\\"\\n./gradlew bootJar\\n\\necho \\"Copy, Start Server\\"\\nmv ./build/libs/$PROJECT_NAME.jar .\\n\\nPID=$(pgrep -f $PROJECT_NAME)\\n\\nif [ -n $PID ]; then\\n kill -9 $PID\\n\\tsleep 5\\nfi\\n\\nnohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &\\n```\\n\\n### \ud611\uc5c5\\n\\n\uc77c\ub2e8 \uc6b0\uc2a4\ub791 \uc6b0\ucf54\uac00 \uba3c\uc800 \uc7a0\uc2e4\ub85c \uc640\uc918\uc11c \ub108\ubb34 \uac10\uc0ac\ud588\ub2e4. \\n\ubc31\uc5d4\ub4dc\uac00 \uc544\ub2cc \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \ud574\ubcf4\ub294 \uccab \ud611\uc5c5\uc774\ub77c \uc57d\uac04 \ub450\uadfc\uac70\ub838\ub2e4. \\n\uc608\uc0c1\uc678\ub85c \ub300\ud654\uac00 \uc798 \ub418\uc5b4\uc11c, \ube60\ub974\uac8c \uba85\uc138\ub97c \uc815\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n**\uc5ec\ub7ec\uac00\uc9c0 \ubc29\ubc95\uc5d0 \ub300\ud55c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud574\ubcf4\uae30**\\n\\n\ubc31\uc5d4\ub4dc\uc640 \ud14c\uc774\ube14 \uba85\uc138\ub098 \ucfe0\ud3f0 \uad6c\ud604\uc5d0 \ub300\ud574\uc11c \uc774\uc57c\uae30\ud560 \ub54c \uc7a5\ub2e8\uc5d0 \ub300\ud574 \ub9ce\uc774 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4. \\n\uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub9ce\uc774 \ub4e4\uc5ec\uc11c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud588\ub2e4\uba74 \ub354 \uc88b\uc740 \uacb0\uacfc\ubb3c\uc774 \ub098\uc624\uc9c0 \uc54a\uc558\uc744\uae4c? \\n\uc55e\uc73c\ub85c \uc120\ud0dd\uc758 \uc21c\uac04\uc5d0\uc11c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub4e4\uc5ec\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4. \\n\\n### \uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84\\n\\n**expose headers**\\n\\n\uc6f9 \ud398\uc774\uc9c0\uc5d0\uc11c Location \ud5e4\ub354\ub97c \ubc1b\uc744 \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \uc788\uc5c8\ub2e4. \\n\uae30\ubcf8\uc801\uc73c\ub85c [\ud5c8\uc6a9 \ubaa9\ub85d\uc5d0 \uc874\uc7ac\ud558\ub294 \uc751\ub2f5\ud5e4\ub354](https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header)\ub9cc \ubc18\ud658\ud55c\ub2e4\ub294 \uac83\uc744 \ubaa8\ub974\uace0 \uc788\uc5c8\ub2e4. \\n\uc774\ub97c expose headers \uc124\uc815\uc744 \ud1b5\ud574 \ud574\uacb0\ud560 \uc218 \uc788\uc5c8\ub2e4. \\nnginx \uc124\uc815\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \ucd94\uac00\ud574 \uc8fc\uc5c8\ub2e4. \\n\\n```bash\\nadd_header \'Access-Control-Expose-Headers\' \'Location\'\\n```\\n\\n**\uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158** \\n\\n\ub2e8\uc21c \uc870\ud68c \uc694\uccad\uc5d0 \ub300\ud55c \uc131\ub2a5\uc744 \ud5a5\uc0c1\uc2dc\ucf1c\uc900\ub2e4\ub294 \uac83\uc774\ub77c\uace0 \uac04\ub2e8\ud788\ub9cc \uc54c\uace0 \uc788\uc5c8\ub2e4. \\n\uc774\ubc88\uc5d0 \ucf54\uba58\ud2b8\uac00 \ub2ec\ub824\uc11c \uc870\uae08 \ub354 \uc790\uc138\ud788 \uacf5\ubd80\ud574 \ubcf4\uae30\ub85c \ud588\ub2e4. \\nTransactional(readOnly = true)\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc774 \ub3d9\uc791\ud55c\ub2e4.\\n\\nsetReadOnly(true) \uc124\uc815\uc774 \ub41c Connection\uc73c\ub85c \uc5f0\uacb0\uc744 \uc2dc\ub3c4\ub97c \ud55c\ub2e4. \uc774 \uc124\uc815\uc744 \ud558\ub294 \uacbd\uc6b0 DB\ub9c8\ub2e4 \ub2e4\ub974\uac8c \ub3d9\uc791\ud55c\ub2e4.\\n- h2\uc758 Connection \uad6c\ud604\uccb4\ub294 readOnly \uc124\uc815\uc744 \ubb34\uc2dc\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 Transactional \uc801\uc6a9\ub418\uc9c0 \uc54a\ub294\ub2e4. \\n- MySQL 8.0(InnoDB \uc0ac\uc6a9 \uc2dc)\uc758 \uacbd\uc6b0 \uc77d\uae30 \uc804\uc6a9\uc73c\ub85c \uc54c\ub824\uc9c4 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158 ID\ub97c \uc124\uc815\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uc870\ud68c \uc18d\ub3c4\uac00 \ub354 \ube68\ub77c\uc9c4\ub2e4.\\n\\nORM \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 prepareTransactionalConnection\ub97c \ud638\ucd9c\ud55c\ub2e4\uace0 \ud55c\ub2e4. \\n\ucd94\uac00\ub85c \ud604\uc5c5\uc5d0\uc11c\ub294 \uace0\uac00\uc6a9\uc131 \ub0b4\uacb0\ud568\uc131 \ub4f1\uc744 \uc704\ud558\uc5ec \ud074\ub7ec\uc2a4\ud130\ub97c \uad6c\uc131\ud558\uc5ec \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uace0, \uc774 \uacbd\uc6b0 readOnly \uc124\uc815\uc774 \ub418\uc5b4\uc788\ub2e4\uba74 \uc77d\uae30 \uc804\uc6a9 DB\ub85c \uc9c8\uc758\uac00 \ub4e4\uc5b4\uac00\uc11c \ubd80\ud558 \ubd84\uc0b0\uc758 \ud6a8\uacfc\uac00 \uc788\ub2e4\uace0 \ud55c\ub2e4. \\n\\n**DAO\uc5d0 `@Transactional` \uc801\uc6a9** \\n\\nDAO\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \ubcf4\ub294 \uac74 \uc5b4\ub5bb\uaca0\ub0d0\uace0 \ub9ac\ubdf0\uac00 \ub2ec\ub824\uc11c \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4. \\nService \uacc4\uce35\uc5d0 \uc774\ubbf8 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \uc8fc\uace0 \uc788\uae30\uc5d0 \ud544\uc694 \uc5c6\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4. \\nDAO\ub97c \ub2e4\ub978 \uacf3\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574(\ud655\uc7a5\uc131 \uace0\ub824) `@Transactional`\uc744 \uc801\uc6a9\ud558\ub294 \uac83\ub3c4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4."},{"id":"tecochat-retrospective-3","metadata":{"permalink":"/tecochat-retrospective-3","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx","source":"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx","title":"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604","description":"\uac1c\uc694","date":"2023-06-01T00:00:00.000Z","formattedDate":"2023\ub144 6\uc6d4 1\uc77c","tags":[{"label":"TecoChat","permalink":"/tags/teco-chat"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":4.005,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604","slug":"tecochat-retrospective-3","tags":["TecoChat","Retrospective"]},"unlisted":false,"prevItem":{"title":"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0","permalink":"/order-retrospective"},"nextItem":{"title":"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30","permalink":"/composite"}},"content":"### \uac1c\uc694\\n\\n\uc6d0\ub798 \ubaa9\uc801\uc778 `\ud06c\ub8e8\ub4e4\uc758 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0`\uc744 \uc8fc\uae30 \uc704\ud574 \uc5b4\ub5a4 \uae30\ub2a5\uc744 \ucd94\uac00\ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4. \\n\ub808\ubca8 2\uac00 \uac70\uc758 \ub05d\ub098\uac00\ub294 \uc2dc\uc810, \uadf8\ub3d9\uc548 \ud588\ub358 \uac83\uc744 \uc815\ub9ac\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4. \\n\\n### \ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5\\n\\nGPT\uc5d0\ub3c4 \uc788\ub294 \uae30\ub2a5\uc778\ub370, \ub0b4\uac00 \uc774\uc804\uc5d0 \ud588\ub358 \ucc44\ud305\uc744 \uc774\uc5b4\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4. \\n\uc608\uc804\uc5d0 \uc5b4\ub5a4 \uc9c8\ubb38\uc744 \ub0a8\uacbc\ub294\uc9c0, \ub610\ud55c \ud574\ub2f9 \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub2e4. \\n\\n![chat1](./chat1.png)\\n\\n### \uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5\\n\\n\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc5d0 \ubc18\uc751\ud560 \uc218 \uc788\ub294 \ubb34\uc5b8\uac00\uac00 \uc788\uc5c8\uc73c\uba74 \uc88b\uaca0\ub2e4\ub294 \uc758\uacac\ub4e4\uc774 \ub9ce\uc558\ub2e4. \\n\ub204\uac00 \uc88b\uc544\uc694\ub97c \ub20c\ub800\ub294\uc9c0, \uc5b4\ub5a4 \ucc44\ud305\uc774 \uc88b\uc544\uc694\ub97c \uac00\uc7a5 \ub9ce\uc774 \ubc1b\uc558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4. \\n\ub610\ud55c \ub313\uae00 \ucd94\uac00 \ubc0f \uc0ad\uc81c \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4.\\n\\n### \ud0a4\uc6cc\ub4dc \ucd94\ucd9c\\n\\n\uc5b4\ub5bb\uac8c \ud0a4\uc6cc\ub4dc \ucd94\ucd9c\uc744 \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub294\ub370, \uc77c\ub2e8 GPT\ub97c \uc774\uc6a9\ud574\uc11c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\uae30\ub85c \ud588\ub2e4. \\n\ud574\ub2f9 \ubd80\ubd84\uc740 \uccab \uc9c8\ubb38\uc5d0 \ub300\ud55c \ud0a4\uc6cc\ub4dc\ub9cc \ucd94\ucd9c\ud558\ub3c4\ub85d \ud588\ub2e4. \\n\ubc31\uc5d4\ub4dc\uc5d0\uc120 \ub9d0\ub791\uc774 \uc774\ubca4\ud2b8 \uc774\uc6a9\ud574\uc11c \uccab \ucc44\ud305 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c0\uba74, \ube44\ub3d9\uae30\ub85c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\ub294 \uc9c8\ubb38\uc744 \ucd94\uac00\ub85c \ub0a0\ub9ac\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4. \\nCSV \ud615\uc2dd\uc73c\ub85c GPT\uc5d0\uac8c \ub2f5\ubcc0\uc744 \uc785\ub825\ud574\ub2ec\ub77c\uace0 \uc694\uccad\ubc1b\ub294\ub370, \uc774 \ubd80\ubd84\uc774 \ubb38\uc81c(\ud504\ub86c\ud504\ud2b8 \uc5d4\uc9c0\ub2c8\uc5b4\ub9c1 \ubd80\ubd84\uc774 \ubc18\ud658\ub41c\ub2e4.)\uac00 \uc880 \uc788\ub294 \uac83 \uac19\uc544\uc11c \uac1c\uc120\uc774 \ud544\uc694\ud55c \uac83 \uac19\ub2e4. \\n\\n![chat2](./chat2.png)\\n\\n### \ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5\\n\\n\ub2e4\ub978 \ud06c\ub8e8\ub4e4\uc758 \ucc44\ud305\uc744 \uc77d\ub2e4\uac00 \uad81\uae08\ud55c \uc810\uc774 \uc788\ub2e4\uba74 \ubcf5\uc0ac\ud574\uc11c \ubc14\ub85c \uc9c8\ubb38\uc744 \ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4. \\n\ucc44\ud305\uc774 \ubcf5\uc0ac\ub41c \ud6c4 \ubc14\ub85c GPT\uc640 \ub300\ud654\ub97c \ud560 \uc218 \uc788\ub294 \uba54\uc778 \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud55c\ub2e4. \\n\\n### \uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30\\n\\n![chat3](./chat3.png)\\n\\n\uc704 \ud654\uba74\uc740 \ud68c\uc6d0\uac00\uc785 \ucc3d\uc774\ub2e4. \\n\uc0ac\uc2e4 \uac00\uc7a5 \ub9c8\uc74c\uc5d0 \ub4dc\ub294 \ubd80\ubd84\uc774\uace0, \ud68c\uc6d0\uac00\uc785(\ub2c9\ub124\uc784\ub9cc \uc785\ub825\ud558\uc9c0\ub9cc)\ud560 \ub54c \uc775\uba85\uc744 \uc6d0\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uace0\ubbfc\uc744 \ub3c4\uc640\uc8fc\uac8c \ub054 \uc74c\uc2dd, \uacfc\uc77c, \uacfc\uc790 \ub4f1\uc758 \uc694\uc18c\ub4e4\uc744 \uc785\ub825\ud558\ub3c4\ub85d \uc720\ub3c4\ud588\ub2e4!\\n\ucd94\uac00\ub85c GPT\uc758 \ub2f5\ubcc0\uc774 \uc624\uba74 \uc790\ub3d9\uc73c\ub85c \ud654\uba74\uc744 \uc2a4\ud06c\ub864 \ud574\uc8fc\ub294 \uac83\uacfc \uac19\uc774 \uc0ac\uc6a9\uc131\uc744 \uac1c\uc120\ud574 \ubcf4\ub824\uace0 \ub178\ub825\ud588\uc9c0\ub9cc \uc27d\uc9c0 \uc54a\uc558\ub2e4. \\n\uc81c\uc77c \ud558\uace0 \uc2f6\uc740 \uac83\uc740 \uc2e4\uc81c GPT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ucc98\ub7fc stream/text \uac12\uc744 \ucc98\ub9ac\ud558\uace0 \uc2f6\uc740\ub370 \uc774 \ubd80\ubd84\uc740 \ubc29\ud559 \ub54c \uae30\ud68c\uac00 \ub418\uba74 \ub3c4\uc804\ud574 \ubd10\uc57c\uaca0\ub2e4. \\n\\n### \ud5a5\ud6c4 \uacc4\ud68d\\n\\n\uc2e4\uc81c \ud06c\ub8e8\ub4e4\uc774 \uc0ac\uc6a9\ud574 \uc8fc\ub294 \uc11c\ube44\uc2a4\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\ubcf4\uba74\uc11c \uc0ac\uc6a9\uc790\uc758 \uc785\uc7a5\uc5d0\uc11c \uace0\ubbfc\ub3c4 \ud558\uac8c \ub418\ub294 \uac83 \uac19\ub2e4. \\n\ud06c\ub8e8\ub4e4\uc774 \uc9c1\uc811 \uc0ac\uc6a9\ud574 \uc8fc\ub2c8\uae4c \ub108\ubb34 \uace0\ub9d9\uace0, \ud55c\ud3b8\uc73c\ub85c\ub294 \uc2e0\uae30\ud558\ub2e4. \\n\uc77c\ub2e8 \ubc29\ud559 \ub54c stream/text \uad00\ub828\ub41c \ubd80\ubd84 \ub3d9\uc791\ub418\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\ub824\uace0 \ud558\uace0, \uadf8 \uc678\uc758 \ubd80\ubd84\uc740 \uc870\uae08 \ub354 \uace0\ubbfc\ud574\uc57c\ub420 \uac83 \uac19\ub2e4."},{"id":"composite","metadata":{"permalink":"/composite","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx","source":"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx","title":"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30","description":"\uc694\uad6c\uc0ac\ud56d","date":"2023-05-26T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 26\uc77c","tags":[{"label":"Pattern","permalink":"/tags/pattern"},{"label":"Composite","permalink":"/tags/composite"}],"readingTime":4.74,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30","slug":"composite","tags":["Pattern","Composite"]},"unlisted":false,"prevItem":{"title":"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604","permalink":"/tecochat-retrospective-3"},"nextItem":{"title":"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0","permalink":"/subway-retrospective"}},"content":"### \uc694\uad6c\uc0ac\ud56d\\n\\n\uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.\\n\\n- \uac70\ub9ac\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45\\n- \ub178\uc120\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45\\n- \uc5f0\ub839\ubcc4 \uc694\uae08 \ud560\uc778 \uc815\ucc45\\n\\n### \uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9\\n\\n\uc694\uae08 \uc815\ucc45\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc778\ud130\ud398\uc774\uc2a4\ub85c \ud45c\ud604\ud560 \uc218 \uc788\ub2e4. \\n\uc694\uae08\uc744 \uacc4\uc0b0\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ucd5c\ub2e8 \uacbd\ub85c \uacc4\uc0b0\uc758 \uacb0\uacfc, \uc0ac\uc6a9\uc790\uc758 \uc815\ubcf4, \uc694\uae08\uc744 \ubc1b\uc544 \uc694\uae08\uc744 \uacc4\uc0b0\ud55c\ub2e4.\\n\\n```java\\npublic interface FarePolicy {\\n int calculate(Path path, Passenger passenger, int fare);\\n}\\n\\npublic class BaseFarePolicy implements FarePolicy { ... }\\npublic class DistanceFarePolicy implements FarePolicy { ... }\\npublic class AgeDiscountFarePolicy implements FarePolicy { ... }\\n```\\n\\n![composite1](./composite1.png)\\n\\n### \ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30\\n\\n\ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub97c \ubaa8\ub450 \uac00\uc9c0\uace0 \uc788\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\ub97c \ub9cc\ub4e4\uc5c8\ub2e4. \\n\uc774 \ub610\ud55c FarePolicy\ub97c \uad6c\ud604\ud55c \ud615\ud0dc\uac00 \ub418\uace0, \ud544\ub4dc\ub85c\ub294 \ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub4e4\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4.\\n\\n```java\\npublic class SubwayFarePolicy implements FarePolicy {\\n\\n private final List<FarePolicy> farePolicies;\\n\\n public SubwayFarePolicy(final List<FarePolicy> farePolicies) {\\n this.farePolicies = farePolicies;\\n }\\n\\n @Override\\n public int calculate(final Path path, final Passenger passenger, final int fare) {\\n int calculatedFare = fare;\\n for (FarePolicy farePolicy : farePolicies) {\\n calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);\\n }\\n return calculatedFare;\\n }\\n}\\n```\\n\\n\ub530\ub77c\uc11c \uadf8\ub9bc\uc73c\ub85c \ubcf8\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4.\\n\\n![composite2](./composite2.png)\\n\\n### \uc815\ucc45\uc758 \uc21c\uc11c\\n\\n\uc9c0\ud558\ucca0 \uc694\uad6c\uc0ac\ud56d\uc740 \uc21c\uc11c\uac00 \uc911\uc694\ud588\ub2e4. \\n\uae08\uc561\uc758 \ucd1d\ud569\uc744 \uad6c\ud558\uace0, \uadf8 \ud6c4\uc5d0 \ud560\uc778 \uc815\ucc45\uc774 \ub4e4\uc5b4\uac00\uc57c\ud588\ub2e4. \\n\ub530\ub77c\uc11c \uc790\uc2dd\ub4e4\uc758 \uc21c\uc11c\ub97c \uad00\ub9ac\ud560 \ub54c \uc8fc\uc758\ub97c \uae30\uc6b8\uc5ec\uc57c \ud588\ub2e4. \\nConfiguration \ud074\ub798\uc2a4\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \uc21c\uc11c\ub97c \uc9c1\uc811 \uc801\uc6a9\uc2dc\ucf30\ub2e4. \\n\\n```java\\n@Configuration\\npublic class FareConfiguration {\\n\\n @Bean\\n public FarePolicy farePolicy() {\\n return new SubwayFarePolicy(List.of(\\n new BaseFarePolicy(),\\n new DistanceFarePolicy(),\\n new AgeDiscountFarePolicy()\\n ));\\n }\\n}\\n```\\n\\n### \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?\\n\\n![composite3](./composite3.png)\\n\\nGOF\uc758 \ub514\uc790\uc778 \ud328\ud134 \ucc45\uc5d0\uc11c\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uba85\ud558\uace0 \uc788\ub2e4.\\n\\n> \ubd80\ubd84\uacfc \uc804\uccb4\uc758 \uacc4\uce35\uc744 \ud45c\ud604\ud558\uae30 \uc704\ud574 \uac1d\uccb4\ub4e4\uc744 \ubaa8\uc544 \ud2b8\ub9ac \uad6c\uc870\ub85c \uad6c\uc131\ud569\ub2c8\ub2e4. \\n\uc0ac\uc6a9\uc790\ub85c \ud558\uc5ec\uae08 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ubcf5\ud569 \uac1d\uccb4\ub97c \ubaa8\ub450 \ub3d9\uc77c\ud558\uac8c \ub2e4\ub8f0 \uc218 \uc788\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc785\ub2c8\ub2e4.\\n> \\n\\n\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4. \\n\uc774 \ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n### \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c\\n\\nComponent\\n\\n- \uc9d1\ud569 \uad00\uacc4\uc5d0 \uc815\uc758\ub420 \ubaa8\ub4e0 \uac1d\uccb4\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4 \\n- ex) \uc694\uae08 \uc815\ucc45(FarePolicy) \\n\\nLeaf\\n\\n- \uac1c\ubcc4 \uac1d\uccb4, \uac1d\uccb4 \ud569\uc131\uc5d0 \uae30\ubcf8\uc774 \ub418\ub294 \uac1d\uccb4\uc758 \ud589\ub3d9 \\n- ex) \uac70\ub9ac \ubcc4 \uc694\uae08 \uc815\ucc45(DistanceFarePolicy) \\n\\nComposite\\n\\n- \uc5ec\ub7ec \uac1c\uc758 \uac1c\ubc1c \uac1d\uccb4\ub97c \ud3ec\ud568\ud558\ub294 \ud569\uc131 \uac1d\uccb4 \\n- ex) \uc9c0\ud558\ucca0 \uc694\uae08 \uc815\ucc45(SubwayFarePolicy) \\n\\nClient\\n\\n- \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8\\n\\n### \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c\\n\\n\ubd80\ubd84 - \uc804\uccb4\uc758 \uad00\uacc4\ub97c \ud45c\ud604\ud558\uace0 \uc2f6\uc744 \ub54c \\nClient \uae30\uc900\uc73c\ub85c Composite\uc640 Leaf\uc758 \ucc28\uc774\ub97c \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc798 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc57c\ub420 \ub54c\\n\\n### \ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84\\n\\n\ud328\ud134\uc740 \uacf5\ud1b5\uc73c\ub85c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc758 \ud15c\ud50c\ub9bf\uc774\ub2e4. \\n\ubc18\ubcf5\ub418\ub294 \ubb38\uc81c\ub97c \ud6a8\uc728\uc801\uc73c\ub85c \ud574\uacb0\ud560 \uc218 \uc788\uc9c0\ub9cc \ud328\ud134\uc5d0 \ub9e4\ubab0\ub418\uc11c\ub294 \uc548\ub41c\ub2e4. \\n\ud328\ud134\uc744 \ub9f9\ubaa9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud574\uc11c\ub294 \uc548\ub418\uace0, \ud604\uc7ac\uc758 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ub530\ub77c \ud328\ud134\uc744 \uc720\ub3d9\uc801\uc73c\ub85c \uc218\uc815\ud574\uac00\uba74\uc11c \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\ud56d\uc0c1 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uc0dd\uac01\ud558\uc790!\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134, GoF\uc758 \ub514\uc790\uc778 \ud328\ud134 \\n\ub514\uc790\uc778 \ud328\ud134\uacfc \ud504\ub808\uc784\uc6cc\ud06c, \uc624\ube0c\uc81d\ud2b8"},{"id":"subway-retrospective","metadata":{"permalink":"/subway-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-subway-path/pull/16","date":"2023-05-25T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 25\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":7.98,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0","slug":"subway-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30","permalink":"/composite"},"nextItem":{"title":"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5","permalink":"/accidental-duplication"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-subway-path/pull/16 \\n2, 3\ub2e8\uacc4: https://github.com/woowacourse/jwp-subway-path/pull/126 \\n:::\\n\\n### \uc9c0\ud558\ucca0 \ubbf8\uc158\\n\\n\uc810\uc810 \uc77c\uc815\uc774 \ub9ce\uc544\uc9c0\ub294 \ub290\ub08c\uc774 \ub4e4\uba74\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc9c4\ub2e4. \\n\uc9c0\ud558\ucca0 \ubbf8\uc158\uc740 \ubc00\ub9ac\ub791 \ud398\uc5b4\ub97c \uc9c4\ud589\ud588\ub2e4. \\n\uac04\ub2e8\ud55c CRUD\ub9cc \uc788\ub358 \uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac, \uc870\uae08 \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. \\n\uc774\ub54c API, \ud14c\uc774\ube14, \ub3c4\uba54\uc778 \uc124\uacc4\ub97c \ud574\uc57c \ud588\ub294\ub370 \uc5b4\ub5a4 \uac83\ubd80\ud130 \ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4. \\nAPI\uc640 \ud14c\uc774\ube14 \uad6c\uc870\ub97c \uc6b0\ub9ac\uac00 \uc815\ud560 \uc218 \uc788\ub294 \uc0c1\ud669\uc774\uc5c8\uace0, \ub3c4\uba54\uc778 \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud588\uae30 \ub54c\ubb38\uc5d0 \ub3c4\uba54\uc778\uc744 \uba3c\uc800 \uad6c\ud604\ud588\ub2e4.\\n\\n**\ub178\uc120\uc758 \uad6c\uac04 \ucd94\uac00 \ubc0f \uc0ad\uc81c**\\n\\n\ub178\uc120\uc744 \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc5d0 \ub300\ud574\uc11c \ubc00\ub9ac\uc640 \uc774\uc57c\uae30\ub97c \ub098\ub234\ub2e4.\\n\\n1. \uad6c\uac04\uc744 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uc804\ubd80 \uc81c\uac70\ud558\uace0 \uc804\ubd80 \ucd94\uac00\ud558\ub294 \ubc29\ubc95\\n2. \ubcc0\uacbd\ub41c \uc694\uc18c\ub9cc \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ubc18\uc601\ud558\ub294 \ubc29\ubc95\\n\\n\ud398\uc5b4 \uc2dc\uac04\uc774 \uc9e7\uc544\uc11c \ub354\uc6b1 \uac04\ub2e8\ud55c 1\ubc88\uc744 \uc120\ud0dd\ud588\uace0, \uc2dc\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\uc2dc\ud0a4\uae30 \uc704\ud574 \ub354 \uac04\ub2e8\ud558\uac8c \uad6c\ud604\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud558\ub294 \uac83\ub3c4 \uc88b\uc740 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\uc600\ub358 \uac83 \uac19\ub2e4. \\n\ucd94\ud6c4 \ud398\uc5b4\uac00 \ub05d\ub098\uace0 \ub9ac\ubdf0\uc5b4\uc778 \uc11c\ube0c\uc6e8\uc774\uac00 \uc77c\ubd80\ubd84\ub9cc \ubc18\uc601\ud558\ub294 \uac83\uc73c\ub85c \uac1c\uc120\ud574 \ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4\uace0 \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ucd94\uac00 \ubc0f \uc81c\uac70\ub41c \uc694\uc18c\ub9cc \ubc18\uc601\ud558\ub3c4\ub85d \ubcc0\uacbd\ud588\ub2e4.\\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n\ubbf8\uc158\uc758 \ub09c\uc774\ub3c4\uac00 \uc62c\ub77c\uac04 \ub9cc\ud07c, \ud398\uc5b4 \ud560 \ub550 \ucee8\ub514\uc158 \uad00\ub9ac\ub3c4 \uc798\ud558\ub824\uace0 \ub178\ub825\ud558\uace0 \ubbf8\uc158 \ud560 \ub54c\ub3c4 \uc9d1\uc911\ud574\uc11c \uc798 \ub05d\ub0b8 \uac83 \uac19\ub2e4. \\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc54c\uc544\uc57c \ud558\ub294 \uac8c \ub9ce\uc544\uc9c0\uba74\uc11c \uac00\ub054 \uc870\ubc14\uc2ec\uc744 \uac00\uc9c8 \ub54c\uac00 \uc788\ub294 \uac83 \uac19\uc740\ub370, \uc870\ubc14\uc2ec\uc744 \uacbd\uacc4\ud560 \ud544\uc694\uac00 \uc788\uc744 \uac83 \uac19\ub2e4. \\n\ubd80\uc871\ud55c \ubd80\ubd84\uc740 \uc778\uc815\ud558\uace0, \uc55e\uc73c\ub85c \ub098\uc544\uac00\uc57c\uaca0\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654**\\n\\n\uc694\uae08 \uc815\ucc45\uc740 \uae30\ubcf8\uc694\uae08 \uc815\ucc45, \uac70\ub9ac\ubcc4 \uc694\uae08 \uc815\ucc45, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc774 \uc788\uc5c8\ub2e4. \\n\uc694\uae08\uc744 \ub354\ud558\ub294 \ubd80\ubd84\uacfc, \ud560\uc778\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5b4\uc11c \uc774 \ub458\uc744 \ubd84\ub9ac\ud560\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc, \uc774 \uc815\ub3c4 \ud06c\uae30\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c\ub294 \uc624\ud788\ub824 \ubd84\ub9ac\ud558\uc9c0 \uc54a\uace0 \ud558\ub098\ub85c \ud569\uce58\ub294 \uac8c \ub354 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ub610\ud55c \ubd84\ub9ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \uc815\ucc45\uc758 \uc21c\uc11c\uac00 \uc911\uc694\ud55c\ub370, \uc5f0\ub839\ubcc4 \ud560\uc778 \uc815\ucc45\uc744 \ub9c8\uc9c0\ub9c9\uc5d0 \ub450\uc5b4\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ucc45\uc784 \uc5f0\uc1c4 \ud328\ud134\ub3c4 \uace0\ub824\ub97c \ud588\uc9c0\ub9cc \uc870\uae08 \ub354 \uac04\uacb0\ud574 \ubcf4\uc774\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \uc120\ud0dd\ud588\ub2e4.\\n\\n**\ub3c4\uba54\uc778\uc5d0 \ud2b9\uc815 \uae30\uc220\uc758 \uc758\uc874\uc131\uc744 \ubd84\ub9ac**\\n\\n\ucc98\uc74c\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uc5d0 jgrapht \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc758\uc874\ud558\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \ub450\uc5b4\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0\uac00 jgrapht\uc640 \uac15\uacb0\ud569\uc774 \ub418\uc5b4\ubc84\ub838\ub2e4. \\n\ub530\ub77c\uc11c \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\uc5d0\ub294 \uacbd\ub85c \uac80\uc0c9\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0, \uc138\ubd80 \uad6c\ud604\uc740 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \uc678\ubd80\ub85c \ubd84\ub9ac\ud588\ub2e4. \\n\ucd5c\ub300\ud55c \uac04\uacb0\ud558\uac8c \uad6c\ud604\ud55c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud574\ub3c4, \uc774\ub7f0 \ubd80\ubd84\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uc5b4 \uacb0\ud569\uc744 \ud53c\ud558\ub294 \uac83\uc774 \uc88b\uc744 \uac83 \uac19\ub2e4.\\n\\n:::note \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\\n\\n\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4. \\n\uc774\ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n:::\\n\\n**\uc778\uc218 \ud14c\uc2a4\ud2b8 \uc791\uc131**\\n\\n\uc778\uc218 \ud14c\uc2a4\ud2b8\ub294 \uc0ac\uc6a9\uc790 \uc2a4\ud1a0\ub9ac \uc2dc\ub098\ub9ac\uc624 \uae30\ubc18 \ud14c\uc2a4\ud2b8\ub2e4. \\n\ube0c\ub77c\uc6b4\uc774 \ud574\uc8fc\uc2e0 \uac15\uc758 + \uc720\ud29c\ube0c\uc5d0 \uc788\ub294 \ube0c\ub77c\uc6b4\uc758 \uac15\uc758\ub97c \ubcf4\uace0 \uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0 \uc778\uc218 \ud14c\uc2a4\ud2b8\ub97c \uc801\uc6a9\ud574 \ubcf4\uc558\ub2e4. \\n\uba54\uc11c\ub4dc, \ubcc0\uc218\uba85\uc744 \uc804\ubd80 \ud55c\uae00\ub85c \uc791\uc131\ud588\ub294\ub370 \uc804\uccb4\uc801\uc778 \ud750\ub984\uc744 \uc54c\uae30 \ud3b8\ud558\uace0 \uc77d\uae30\ub3c4 \uc88b\uc558\ub2e4. \\n\uadf8\ub9ac\uace0 \uc778\uc218 \ud14c\uc2a4\ud2b8\uc5d0 \ud544\uc694\ud55c Steps\ub97c \ub9cc\ub4dc\ub294 \uacfc\uc815\uc774 \ub108\ubb34 \uc7ac\ubc0c\uc5c8\ub2e4.\\n\\n\uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4.\\n\\n```java\\n@Nested\\npublic class \ub178\uc120\uc744_\uc804\uccb4_\uc870\ud68c\ud560_\ub54c {\\n\\n @Test\\n void \uc0c1\ud589\uc885\uc810\uc5ed_\ubd80\ud130_\ud558\ud589\uc885\uc810\uc5ed\uc73c\ub85c_\uc815\ub82c\ub41c_\uacb0\uacfc\ub97c_\ubc18\ud658\ud55c\ub2e4() {\\n // given\\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad(\\"2\ud638\uc120\\", \\"\ucd08\ub85d\\", 0);\\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad(\\"2\ud638\uc120\\", \\"\uc7a0\uc2e4\\", \\"\uc7a0\uc2e4\uc0c8\ub0b4\\", 5);\\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad(\\"2\ud638\uc120\\", \\"\uc7a0\uc2e4\uc0c8\ub0b4\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\", \uc624\ub978\ucabd, 5);\\n\\n \ub178\uc120_\uc0dd\uc131_\uc694\uccad(\\"9\ud638\uc120\\", \\"\uace0\ub3d9\\", 0);\\n \ub178\uc120\uc5d0_\uad6c\uac04\uc774_\uc874\uc7ac\ud558\uc9c0_\uc54a\uc744_\ub54c_\ucd08\uae30_\uad6c\uac04_\uc0dd\uc131_\uc694\uccad(\\"9\ud638\uc120\\", \\"\ubd09\uc740\uc0ac\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\", 3);\\n \uad6c\uac04_\uc0dd\uc131_\uc694\uccad(\\"9\ud638\uc120\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\", \\"\uc0bc\uc804\\", \uc624\ub978\ucabd, 7);\\n\\n // when\\n final var \uc870\ud68c_\uacb0\uacfc = \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uc694\uccad();\\n\\n // then\\n \uc694\uccad_\uacb0\uacfc\uc758_\uc0c1\ud0dc\ub97c_\uac80\uc99d\ud55c\ub2e4(\uc870\ud68c_\uacb0\uacfc, \uc815\uc0c1_\uc694\uccad);\\n \ub178\uc120_\uc804\uccb4_\uc870\ud68c_\uacb0\uacfc\ub97c_\ud655\uc778\ud55c\ub2e4(\\n \uc870\ud68c_\uacb0\uacfc,\\n \ub178\uc120_\uc815\ubcf4(\\"2\ud638\uc120\\", \\"\ucd08\ub85d\\", 0, \\"\uc7a0\uc2e4\\", \\"\uc7a0\uc2e4\uc0c8\ub0b4\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\"),\\n \ub178\uc120_\uc815\ubcf4(\\"9\ud638\uc120\\", \\"\uace0\ub3d9\\", 0, \\"\ubd09\uc740\uc0ac\\", \\"\uc885\ud569\uc6b4\ub3d9\uc7a5\\", \\"\uc0bc\uc804\\")\\n );\\n }\\n}\\n```\\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\uc758\uacac \uc870\uc728\ud558\uae30**\\n\\n\ubc00\ub9ac\uac00 \ud544\uc694\ud55c \ubd80\ubd84\uc5d0\uc11c \uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \uc9c4\ud589\uc774 \uc218\uc6d4\ud588\ub2e4. \\n\uc758\uc0ac\uc18c\ud1b5\uc774 \ub9e4\uc6b0 \uc798 \ub3fc\uc11c \uc88b\uc558\uace0 \ub355\ubd84\uc5d0 \uc2dc\uac04 \ub0b4\uc5d0 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574 \ubbf8\uc158\uc744 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\\n**\uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\ud558\uae30**\\n\\n\ubc00\ub9ac\ub294 \ucf54\ub529\uc744 \uc5c4\uccad \uaf3c\uaf3c\ud558\uac8c \ud558\ub294 \uac83 \uac19\ub2e4. \\n\ubcc0\uc218\uba85, \uba54\uc11c\ub4dc\uba85\uc744 \uc911\uc694\ud558\uac8c \uc0dd\uac01\ud588\uace0, \uc88b\uc740 \ubcc0\uc218\uba85\uc744 \uc798 \uc9d3\ub294 \uac83 \uac19\ub2e4. \\n\ub610\ud55c \ucf54\ub529\ud560 \ub54c \ub0b4\uac00 \ud3c9\uc18c\uc5d0 \uc0ac\uc6a9\ud558\ub294 \ucf54\ub529 \ucee8\ubca4\uc158\uc5d0 \ub9de\ucdb0\uc8fc\ub294 \uac83 \uac19\uc544\uc11c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud588\ub2e4! \\n\\n**\ud3b8\ud55c \ubd84\uc704\uae30**\\n\\n\uc804\uccb4\uc801\uc73c\ub85c \ud398\uc5b4 \ud560 \ub54c \ud3b8\ud558\uac8c \uc9c4\ud589\ud588\ub358 \uac83 \uac19\ub2e4. \\n\uc77c\uc815\ub3c4 \uadf8\ub807\uace0, \ud398\uc5b4 \uc9c4\ud589\ud560 \ub54c\ub3c4 \uadf8\ub807\uace0 \ud070 \ubb38\uc81c\uac00 \uc5c6\uc5c8\ub358 \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4. \\n\ub098\ub294 \uacfc\uc5f0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c \ud3b8\ud55c \uc0ac\ub78c\uc77c\uae4c?"},{"id":"accidental-duplication","metadata":{"permalink":"/accidental-duplication","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx","source":"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx","title":"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5","description":"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.","date":"2023-05-24T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 24\uc77c","tags":[{"label":"DTO","permalink":"/tags/dto"}],"readingTime":7.525,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5","slug":"accidental-duplication","tags":["DTO"]},"unlisted":false,"prevItem":{"title":"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0","permalink":"/subway-retrospective"},"nextItem":{"title":"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0","permalink":"/shopping-cart-retrospective"}},"content":"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. \\n\uc694\uccad\uc5d0 \ub2f4\uae34 Body\ub97c \ud1b5\ud574 \uc804\ub2ec\ubc1b\uc740 \uac12\uc744 DTO\ub85c \ub9e4\ud551\ud558\uc5ec \ucd94\uac00\uc640 \uc218\uc815\uc744 \ud588\ub2e4.\\n\\n### \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815\\n\\n![\uc911\ubcf51](./\uc911\ubcf51.png)\\n\\n\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d\ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0\uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ud558\uc9c0\ub9cc \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4. \\n\uc704 \uacbd\uc6b0\ub294 \uc911\ubcf5\uc77c\uae4c? \uc911\ubcf5\uc774 \uc544\ub2d0\uae4c?\\n\\n\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ub9ac\ubdf0\ub97c \ubc1b\uc558\ub2e4.\\n\\n> `ProductSaveRequest`\uc640 `ProductUpdateRequest`\uac00 \uc644\uc804\ud788 \ub3d9\uc77c\ud55c\ub370, \uc7ac\uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc744\uae4c? \ub77c\ub294 \ub9ac\ubdf0\ub97c \ub0a8\uacbc\uc5c8\uc5b4\uc694. \uc0ac\uc2e4 \uc0dd\uc131\uacfc \uc218\uc815\uc740 \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac1c\uc5f0\uc131\uc774 \ub192\uc544\uc11c \ubbf8\ub9ac \ubd84\ub9ac\ud574\ub193\ub294 \uac8c \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\uae34 \ud55c\ub370, \uadf8\ub798\ub3c4 \uc911\ubcf5\uc740 \uc2eb\uc5b4\uc11c \uc800\ub3c4 \uc694\uc998 \uc774\ub7f0\uc800\ub7f0 \ubc29\ubc95\ub4e4\uc744 \uc2dc\ub3c4\ud574\ubcf4\ub294 \uc911 \uc785\ub2c8\ub2e4. \ud5c8\ube0c\ub294 \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc5b4\ub5a4 \uc0dd\uac01\uc744 \uac00\uc9c0\uace0 \uc788\uc744\uc9c0 \uad81\uae08\ud558\ub124\uc694 \u314e\u314e\\n> \\n\\n\uc9c8\ubb38\uc5d0 \ub300\ud574 \uc544\ub798\uc640 \uac19\uc774 \ub2f5\ubcc0\uc744 \ud588\ub2e4.\\n\\n> \uc800\uc7a5\uacfc \uc218\uc815\ud560 \ub54c \ud544\uc694\ud55c \ud544\ub4dc\uac12\uc774 \ub3d9\uc77c\ud558\uc5ec \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c\ub294 \ud558\ub098\ub85c \uc0ac\uc6a9\ud574\ub3c4 \ub41c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud558\uc9c0\ub9cc, \ub9d0\uc500\ud574\uc8fc\uc2e0\ub300\ub85c \uc694\uad6c\uc0ac\ud56d\uc774 \ubcc0\uacbd\ub41c\ub2e4\uba74 \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\ub2e4\uace0 \ud310\ub2e8\ud558\uc600\uc2b5\ub2c8\ub2e4!\\n> \\n\\n### \uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5\\n\\n\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec\uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4.\\n\\n- \uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4.\\n- \uac70\uc9d3\ub41c \uc911\ubcf5, \uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4.\\n\\n\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131\uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.\\n\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc704 \uc0c1\ud669\uc740 \uc6b0\ubc1c\uc801 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc778\ub2e4. \uadf8\ub798\ub3c4 \uc911\ubcf5\uc744 \uc81c\uac70\ud574\ubcfc \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?\\n\\n### \ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c\\n\\n\uc9c0\uae08\uc740 \ucd94\uac00, \uc218\uc815 2\uac00\uc9c0 \uacbd\uc6b0 \ubc16\uc5d0 \uc5c6\uc9c0\ub9cc \uc870\uae08 \ub354 \ubcf5\uc7a1\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc8fc\uc5b4\uc838\uc11c 10\uac00\uc9c0 \uacbd\uc6b0\ub85c \uc785\ub825\uc744 \ubc1b\uc73c\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c\ud560\uae4c? \\n\uc11c\ube44\uc2a4 \uacc4\uce35\uc5d0\uc11c\ub3c4 \uacc4\uce35\uc758 \ubd84\ub9ac\ub97c \uc704\ud574\uc11c \ub2e4\ub978 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uba74 20\uac1c\uc758 DTO\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud560\uae4c? \\n\ub9ac\ubdf0\uc5b4\uac00 \uc54c\ub824\uc900 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \ud1b5\ud574 \uc774\ub97c \ud574\uacb0\ud574\ubcf4\uc790! \\n\\n### \uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc\\n\\n\ud604\uc7ac \ucf54\ub4dc\uc5d0\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\ub2e4. \\nController\uc640 Service\uc5d0\uc11c \uc800\uc7a5, \uc218\uc815\ud560 \ub54c \uac01\uac01\uc758 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.\\n\ud604\uc7ac DTO\ub294 controller, service \ud328\ud0a4\uc9c0 \ub0b4\uc5d0 \uc788\ub294 \uac83\uc774 \uc544\ub2c8\ub77c dto\ub77c\ub294 \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\ud558\uace0 \uc788\ub2e4.\\n\\n```java\\n\u251c\u2500\u2500 controller\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\\n\u251c\u2500\u2500 service\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductService\\n\u251c\u2500\u2500 dto\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\\n```\\n\\n![\uc911\ubcf52](./\uc911\ubcf52.png)\\n\\n### \uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30\\n\\n![\uc911\ubcf53](./\uc911\ubcf53.png)\\n\\n\uc11c\ube44\uc2a4 \ub808\uc774\uc5b4\uc5d0\uc11c \ud544\uc694\ub85c \ud558\ub294 \uac12\ub4e4\uc744 \uc778\ud130\ud398\uc774\uc2a4\ub85c \uc815\uc758\ud55c\ub2e4. \\n\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \uc11c\ube44\uc2a4\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 service \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub85c \uc62e\uaca8\uc900\ub2e4.\\n\\n```java\\n\u251c\u2500\u2500 controller\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\\n\u251c\u2500\u2500 service\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\\n```\\n\\n```java\\npublic interface ProductSaveRequest {\\n\\n String getName();\\n\\n String getImage();\\n\\n Long getPrice();\\n}\\n\\n// ProductService\\npublic Long save(final ProductSaveRequest request) {\\n final Product product = new Product(request.getName(), request.getImage(), request.getPrice());\\n return productDao.saveAndGetId(product);\\n}\\n```\\n\\n### \uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30\\n\\n![\uc911\ubcf54](./\uc911\ubcf54.png)\\n\\n\uc704\uc5d0\uc11c \uc791\uc131\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc791\uc131\ud55c\ub2e4. \\n\uc694\uccad\uc740 ProductRequest \ud074\ub798\uc2a4\ub85c \ubc1b\uace0, \uc11c\ube44\uc2a4\uc5d0 \uc804\ub2ec\ud560 \ub550 \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\uc758 \uba85\uc138\ub9cc \ub9de\ucd94\uba74 \ubb38\uc81c\uc5c6\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n```java\\n\u251c\u2500\u2500 controller\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductController\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductRequest\\n\u251c\u2500\u2500 service\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\\n```\\n\\n```java\\npublic class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {\\n\\n @NotBlank(message = \\"\uc774\ub984\uc740 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\\")\\n @Size(min = 1, max = 100, message = \\"\uc774\ub984\uc740 \ucd5c\uc18c {min}\uc790 \uc774\uc0c1, {max}\uc790 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.\\")\\n private final String name;\\n\\n @NotBlank(message = \\"\uc774\ubbf8\uc9c0\ub294 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\\")\\n private final String image;\\n\\n @Range(message = \\"\uac00\uaca9\uc740 \ucd5c\uc18c {min}\uc6d0 \uc774\uc0c1, {max}\uc6d0 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.\\")\\n private final long price;\\n\\n public ProductRequest(final String name, final String image, final long price) {\\n this.name = name;\\n this.image = image;\\n this.price = price;\\n }\\n\\n @Override\\n public String getName() {\\n return name;\\n }\\n\\n @Override\\n public String getImage() {\\n return image;\\n }\\n\\n @Override\\n public long getPrice() {\\n return price;\\n }\\n}\\n\\n// ProductController\\n@PostMapping(\\"/products\\")\\npublic ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {\\n final Long id = productService.save(request);\\n return ResponseEntity.created(URI.create(\\"/products/\\" + id)).build();\\n}\\n```\\n\\n### \uc815\ub9ac\\n\\n\uc704\uc640 \uac19\uc774 \uad6c\ud604\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc744 \uc5bb\uc744 \uc218 \uc788\ub2e4. \\n\\n1. Service\uc5d0\uc11c \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc694\uccad\uc5d0 \ub300\ud55c DTO\ub97c \uc54c\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4.\\n2. \uacf5\ud1b5\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 DTO\ub97c \uc81c\uc678\ud558\uace0 DTO \ud328\ud0a4\uc9c0\uc5d0 \ub300\ud55c \uacb0\ud569\ub3c4\uac00 \ub0ae\uc544\uc9c0\uace0, \uac01 \ub808\uc774\uc5b4\uc758 \uc751\uc9d1\ub3c4\uac00 \uc99d\uac00\ud55c\ub2e4.\\n3. \uc694\uccad \uac1d\uccb4\ub9cc \ub2e4\ub974\uace0 \uc11c\ube44\uc2a4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ud589\uc704\ub97c \uc218\ud589\ud558\ub294 \uacbd\uc6b0 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.\\n\\n\uc704 \ubc29\ubc95\uc744 \uc9c0\uae08 \ubbf8\uc158\uc5d0\uc11c \ubc14\ub85c \uc801\uc6a9\ud560\uae4c \ud558\ub2e4\uac00, \ub098\uc911\uc5d0 \ud544\uc694\ud560 \ub54c \uc801\uc6a9\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\uc544\uc11c \ubbf8\uc158\uc5d0\ub294 \uc801\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4. \\n\uc0c1\ud669\uc5d0 \ub9de\ucdb0 \uc801\uc7ac\uc801\uc18c\uc5d0 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud574\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4.\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98 16\uc7a5 \ub3c5\ub9bd\uc131, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 \\n[https://techblog.woowahan.com/2647/](https://techblog.woowahan.com/2647/) \\n[https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/](https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/)"},{"id":"shopping-cart-retrospective","metadata":{"permalink":"/shopping-cart-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-shopping-cart/pull/244","date":"2023-05-12T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 12\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":4.845,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0","slug":"shopping-cart-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5","permalink":"/accidental-duplication"},"nextItem":{"title":"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0","permalink":"/web-racing-car-retrospective"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-shopping-cart/pull/244 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-shopping-cart/pull/300 \\n:::\\n\\n### \uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\\n\\n\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc740 \ube14\ub799\ucea3\uc774\ub791 \uc9c4\ud589\ud588\ub2e4. \\n\uc694\uad6c\uc0ac\ud56d\uc774 \uc5c4\uccad \ubcf5\uc7a1\ud55c \ubbf8\uc158\uc740 \uc544\ub2c8\uc5c8\uace0, \uc2a4\ud504\ub9c1\uc744 \uc0ac\uc6a9\ud558\uc5ec \uae30\ubcf8\uc801\uc778 CRUD\ub97c \uad6c\ud604\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4. \\n2\ub2e8\uacc4\uc5d0\uc11c\ub294 Basic \uc778\uc99d\uc744 \ud1b5\ud574 \uc790\uc2e0\uc758 \uc7a5\ubc14\uad6c\ub2c8\uc5d0\ub9cc \uc0c1\ud488\uc744 \ub2f4\uace0, \uc81c\uac70\ud560 \uc218 \uc788\ub3c4\ub85d \uad6c\ud604\ud558\ub294 \uc694\uad6c\uc0ac\ud56d\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. \\nInterceptor\ub098 Argument Resolver\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\uac00 \ub192\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc870\uae08 \ub354 \uc54c\uc544\uac04 \ub290\ub08c\uc774\ub2e4. \\n\uc774\uc804\uc5d0 \uc2a4\ud504\ub9c1 \uc0ac\uc6a9\ud560 \ub54c\ub294 \uc544\ubb34 \uc0dd\uac01 \uc5c6\uc774 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub294\ub370, \ucf54\ub4dc\ub97c \uc791\uc131\ud560 \ub54c \uadfc\uac70\uac00 \uc0dd\uae30\uace0 \uc788\ub294 \uac83 \uac19\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**DTO \uc6b0\ubc1c\uc801 \uc911\ubcf5**\\n\\n\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4. \\n\\n![dto1](./dto1.png)\\n\\n\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d \ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0 \uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\uc744 \ud588\uace0, \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4. \\n\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec \uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4. \\n\\n- \uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4.\\n- \uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4.\\n\\n\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131 \uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4. \\n\ub530\ub77c\uc11c \ub9ac\ubdf0\uc5b4 \uc6e8\uc9c0\uac00 \uc544\ub798\uc640 \uac19\uc774 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\uace0 \uc54c\ub824\uc8fc\uc168\ub2e4. \\n\\n![dto2](./dto2.png)\\n\\n**Interceptor\uc5d0\uc11c \uc778\uc99d\ud55c \uac12 \uc7ac\uc0ac\uc6a9**\\n\\n\uc0ac\uc2e4 \uc870\ud68c\ub97c \ub450 \ubc88 \ud558\uae30 \uc2eb\uc5b4\uc11c \ub2e4\uc591\ud55c \ubc29\ubc95\uc744 \uc0dd\uac01\ud588\uc5c8\ub294\ub370 \uc774\ubc88 \ubbf8\uc158\uc5d0\uc11c\ub294 ThreadLocal\uc744 \uc0ac\uc6a9\ud588\ub2e4. \\n\uc77c\ub2e8 Tomcat\uc740 \uc694\uccad\ub9c8\ub2e4 \ub2e4\ub978 \uc2a4\ub808\ub4dc\ub97c \uc0ac\uc6a9\ud558\uace0, Interceptor\uc5d0\uc11c \uc870\ud68c\ud574\uc11c \ub9cc\ub4e0 Credential\uc744 ThreadLocal\uc5d0 \ub123\uc5b4\ub450\uc5c8\ub2e4\uac00 ArgumentResolver\uc5d0\uc11c \uaebc\ub0b8 \ub2e4\uc74c ThreadLocal\uc744 clear \ud558\uba74 \ubb38\uc81c\uac00 \uc5c6\uc744 \uac70\ub77c \ud310\ub2e8\ud588\ub2e4. \\n\\n\ub9ac\ubdf0\uc5b4\uc778 \uc6e8\uc9c0\uc5d0\uac8c\ub3c4 \uc5b4\ub5a4 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560\uc9c0 \uad81\uae08\uc99d\uc744 \uc791\uc131\ud588\uc5c8\ub2e4. \\n\uc6e8\uc9c0\ub294 email\uc5d0 index\ub97c \uac78\uc5b4\ub450\uace0 dao \uc7ac\uc870\ud68c\ub97c \uc0ac\uc6a9\ud560 \uac83\uc774\ub77c\uace0 \ud588\ub2e4. \\n\uc7ac\uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 db\uc5d0 \uc778\ub371\uc2a4\ub97c \uac78 \uc0dd\uac01\uc740 \ud558\uc9c0 \ubabb\ud588\ub294\ub370, \uc81c\uc77c \uc9c1\uad00\uc801\uc774\uace0 \uc88b\uc740 \ubc29\ubc95\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\uae30\ub85d**\\n\\n\ube14\ub799\ucea3\uc740 \uae30\ub85d\uc744 \uad49\uc7a5\ud788 \uc798 \ud558\ub294 \ud06c\ub8e8\uc600\ub2e4. \\n\ub178\uc158\uc5d0 \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \ud588\ub358 \ub0b4\uc6a9 + \uace0\ubbfc\ud588\ub358 \ubd80\ubd84 + \ud68c\uace0\ub97c \uaf3c\uaf3c\ud558\uac8c \uae30\ub85d\ud574\uc11c \uacf5\uc720\ud574 \uc8fc\uc5c8\ub2e4. \\n\ucd94\uac00\uc801\uc73c\ub85c \uc774\ubaa8\uc9c0\ub97c \uc801\uadf9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\uc5ec \ub354\uc6b1 \uc88b\uc558\ub2e4!\\n\\n**\uc758\uacac \uc77c\uce58\uc2dc\ud0a4\uae30**\\n\\n\ud398\uc5b4 \uc2dc\uac04\uc740 \ud55c\uc815\ub418\uc5b4 \uc788\uace0, \uae30\uac04 \ub0b4 \uc694\uad6c\uc0ac\ud56d\uc744 \ub9cc\uc871\ud574\uc57c \ud55c\ub2e4. \\n\ub530\ub77c\uc11c \uc801\ub2f9\ud788 \ud0c0\ud611\uc744 \ubd10\uc11c \uc758\uacac\uc744 \ube60\ub974\uac8c \uc218\uc6a9\ud574 \ub370\ub4dc\ub77c\uc778\uc744 \ub9de\ucd94\ub294 \uac83\ub3c4 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\ube14\ub799\ucea3\uc740 \ub0b4 \uc758\uacac\uc744 \uc798 \ub4e4\uc5b4\uc92c\uace0, \ub355\ubd84\uc5d0 \ub9c9\ud788\ub294 \ubd80\ubd84 \uc5c6\uc774 \ube60\ub974\uac8c \ubbf8\uc158\uc744 \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n\ube68\ub9ac \uce5c\ud574\uc84c\uace0, \uc758\uc0ac\uc18c\ud1b5\uc774 \uc798 \ub3fc\uc11c \uc7ac\ubc0c\uac8c \ucf54\ub529\ud560 \uc218 \uc788\uc5c8\ub2e4!"},{"id":"web-racing-car-retrospective","metadata":{"permalink":"/web-racing-car-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/jwp-racingcar/pull/24","date":"2023-05-02T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 2\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.6,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0","slug":"web-racing-car-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0","permalink":"/shopping-cart-retrospective"},"nextItem":{"title":"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec","permalink":"/tecochat-retrospective-2"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/jwp-racingcar/pull/24 \\n2\ub2e8\uacc4: https://github.com/woowacourse/jwp-racingcar/pull/128 \\n:::\\n\\n### \uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158\\n\\n\uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud55c\ub2e4\uace0 \uc2dc\uac04\uc774 \ub9ce\uc774 \uc5c6\uc5b4\uc11c \ud68c\uace0\uac00 \ub2a6\uc5b4\uc84c\ub2e4. \\n\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158\uc5d0\uc11c\ub294 \ube44\ubc84\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4. \\n\ub808\ubca8 2\uc5d0\uc11c \uc9c4\ud589\ud558\ub294 \uccab \ubbf8\uc158\uc774\ub77c \ub9ce\uc774 \uae34\uc7a5\ub418\uc5c8\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ube44\ubc84\ub791 \ucd08\ubc18\uc5d0 \ub9db\uc788\ub294 \uac83\ub3c4 \ub9ce\uc774 \uba39\uc73c\uba74\uc11c \ube68\ub9ac \uce5c\ud574\uc838\uc11c \uc7ac\ubc0c\uac8c \ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n\uc2a4\ud504\ub9c1\uc744 \uc870\uae08 \uc0ac\uc6a9\ud560 \uc904 \uc54c\uc544\uc11c, \ube44\ubc84\ub791 \uac19\uc774 \ud559\uc2b5\ud558\uba74\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub2e4. \\n\uccab \ubbf8\uc158\uc774\ub77c \uadf8\ub7f0\uc9c0 \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc740 \uc5c6\uc5c8\uace0, \ucd5c\ub300\ud55c \uae54\ub054\ud558\uac8c \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\ub09c\uc774\ub3c4 \ub192\uc740 \ubbf8\uc158\uc774 \uc544\ub2c8\uc5c8\uc9c0\ub9cc \ub9ac\ubdf0\uc5b4\uc778 \ub77c\ube48\uc5d0\uac8c \uce6d\ucc2c\uc744 \ub9ce\uc774 \ubc1b\uc544\uc11c \uae30\ubd84\uc774 \uc88b\uc558\ub2e4. \\n\ub77c\ube48 \uac10\uc0ac\ud569\ub2c8\ub2e4! \\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n\ucee8\ub514\uc158\ub3c4 \uc88b\uc9c0 \uc54a\uace0 \uc5f4\uc815\ub3c4 \uc2dd\uc740 \uac83 \uac19\uc740 \ub290\ub08c\uc774 \ub4e4\uc5c8\ub2e4. \\n\ubbf8\uc158\uc774 \ub2e4\uc18c \uc5ec\uc720\ub86d\ub2e4\uace0 \ub290\uaef4\uc838\uc11c, \uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ubd84\ub3c4 \uc798 \uad00\ub9ac\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4. \\n\ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud574\uc11c \ud398\uc5b4\uc5d0\uac8c \ub9ce\uc774 \ubbf8\uc548\ud588\uace0, \ub098 \uc790\uc2e0\uc5d0\uac8c \uc544\uc26c\uc6e0\ub358 \ubd80\ubd84\uc774 \ub9ce\uc558\ub2e4. \\n\\n\uc9c0\ub09c\ubc88 \ud68c\uace0\ub97c \ub2e4\uc2dc \ubcf4\ub294\ub370 \uc9d1\uc911\uc744 \uc798 \ubabb\ud55c \uacbd\uc6b0\uac00 \ub9ce\uc740 \uac83 \uac19\ub2e4. \\n\ub3c4\uc804\uc801\uc774\uc9c0 \uc54a\uac70\ub098 \uc2dc\uac04\uc774 \ubd80\uc871\ud558\uc9c0 \uc54a\uc73c\uba74 \uc9d1\uc911\uc744 \uc798 \ubabb\ud558\ub294 \uac83 \uac19\ub2e4. \\n\uba38\ub9bf\uc18d\uc5d0\uc11c \uc2dc\uac04\uc801 \uc5ec\uc720\uac00 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \ub54c\uac00 \uac00\uc7a5 \uc704\ud5d8\ud55c \uc21c\uac04\uc778 \uac83 \uac19\ub2e4. \\n\\n\ud568\uaed8 \uc790\ub77c\uae30\uc5d0\uc11c \ub098\uc628 `\ub09c\uc774\ub3c4 \ub192\uc774\uae30`\uac00 \ud544\uc694\ud574\uc9c0\ub294 \uc21c\uac04\uc774\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**\uc911\uc694\ub3c4\uac00 \uc788\ub294 \uc5b4\ub178\ud14c\uc774\uc158\ubd80\ud130 \ud074\ub798\uc2a4 \uc774\ub984\uc5d0 \uac00\uae5d\uac8c \uba85\uc2dc\ud558\uae30**\\n\\n```java\\n@SuppressWarnings(\\"NonAsciiCharacters\\")\\n@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)\\n@Transactional\\n@AutoConfigureMockMvc\\n@SpringBootTest\\npublic class RacingGameIntegrationTest {\\n```\\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\ube44\ubc84\uc758 \uc131\uaca9** \\n\ube44\ubc84\uac00 \uc131\uaca9\uc774 \uc88b\uc544\uc11c \ud3b8\ud558\uac8c \ud398\uc5b4\ub97c \ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc131\uae09\ud558\uc9c0 \uc54a\uace0 \uc5ec\uc720\ub85c\uc6cc\uc11c \uc88b\uc558\ub2e4. \\n\\n**\ubbf8\uc158\uc5d0 \uc9d1\uc911\ud558\ub294 \ubd80\ubd84** \\n\ub0b4\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud558\uc9c0 \ubabb\ud588\ub294\ub370\ub3c4 \uac19\uc774 \ud398\uc5b4\ub97c \uc798 \uc9c4\ud589\ud55c \uac83 \uac19\uc544\uc11c \uc88b\uc558\ub2e4. \\n\ube44\ubc84\uac00 \ubbf8\uc158\uc5d0 \uc798 \uc9d1\uc911\ud574\uc11c \uadf8\ub807\uc9c0 \uc54a\uc558\ub098 \uc0dd\uac01\ud588\ub2e4. \\n\uadfc\uc721\ub9e8 \ube44\ubc84\ub77c \uadf8\ub7f0\uc9c0 \uccb4\ub825\uc774 \uc88b\uc544\uc11c \uadf8\ub7f0\uac00? \\n\uc911\uac04\uc5d0 \uc798 \uc548 \uc26c\uace0\ub3c4 \uc9d1\uc911\ud574\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \uac78 \ubcf4\uace0 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n**\ud559\uc2b5\uc5d0 \ub300\ud55c \uc5f4\uc815** \\n\ucd94\uac00\uc801\uc73c\ub85c \uc54c\uace0 \uc2f6\uc740 \ubd80\ubd84\uc744 \ub530\ub85c \ud559\uc2b5\ud558\ub294 \uc5f4\uc815\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\ube44\ubc84\uc640 \uc2a4\ud504\ub9c1\uc5d0 \ub300\ud574 \uc54c\uc544\uac00\ub294 \uc2dc\uac04\uc744 \ub9ce\uc774 \uac00\uc9c4 \ubd80\ubd84\uc774 \ub9e4\uc6b0 \uc88b\uc558\ub2e4. \\n\ub098\ub3c4 5\uc6d4\ubd80\ud130 \uc870\uae08 \ub354 \ud654\uc774\ud305 \ud574\uc57c\uaca0\ub2e4."},{"id":"tecochat-retrospective-2","metadata":{"permalink":"/tecochat-retrospective-2","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx","source":"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx","title":"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec","description":"\ud504\ub860\ud2b8\uc5d4\ud2b8","date":"2023-05-01T00:00:00.000Z","formattedDate":"2023\ub144 5\uc6d4 1\uc77c","tags":[{"label":"TecoChat","permalink":"/tags/teco-chat"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":4.67,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec","slug":"tecochat-retrospective-2","tags":["TecoChat","Retrospective"]},"unlisted":false,"prevItem":{"title":"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0","permalink":"/web-racing-car-retrospective"},"nextItem":{"title":"Jenkins\ub85c CI/CD \uc124\uc815","permalink":"/jenkins"}},"content":"### \ud504\ub860\ud2b8\uc5d4\ud2b8\\n\\n\ub2c9\ub124\uc784\uc744 \uc785\ub825\ud558\uc5ec \uac04\ub2e8\ud788 \ub85c\uadf8\uc778\ud558\ub294 \ud654\uba74, \ucc44\ud305 \ubaa9\ub85d\uc744 \ubcf4\uc5ec\uc8fc\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\uace0 \ub2e8\uc77c \ucc44\ud305\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\ub2e4. \\n\ucd94\uac00\ub85c \ucc44\ud305\uc744 \uc774\uc5b4\ub098\uac08 \uc218 \uc788\uac8c \ud558\ub294 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4. \\n\uc790\uc798\ud558\uac8c \uc2e0\uacbd \uc4f8 \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c, \ud504\ub860\ud2b8\uc5d4\ub4dc \ud558\ub294 \uc0ac\ub78c\ub4e4\uc774 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4. \\n\uc5ec\uc720\uac00 \ub41c\ub2e4\uba74 \uc790\uc2e0\uc758 \ucc44\ud305\uc744 \ubcfc \uc218 \uc788\ub294 \uae30\ub2a5\uc774\ub098, \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub294 \uae30\ub2a5, \ub313\uae00 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud560 \uc608\uc815\uc774\ub2e4. \\n\\n### \ubc31\uc5d4\ub4dc\\n\\n\ucd5c\ub300\ud55c \ube68\ub9ac \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uae30\ub85c \uc815\ud574\uc11c, \ubc31\uc5d4\ub4dc\ub294 \ub9d0\ub791\uc774 \uc77c\ub2e8 \ub2e4 \ub9cc\ub4e4\uace0 \uc788\ub2e4. \\n\ub9d0\ub791\uc774 \ud55c \ubd80\ubd84\uc774 \ub108\ubb34 \ub9ce\uc544\uc11c \ub0b4\uac00 \ubabb \ub530\ub77c\uac00\ub294 \uac83 \uac19\ub2e4. \\n\ub098\uc911\uc5d0 \ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc774\ud574\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. \\n\\n### Http Request Header\\n\\n\uc544\uc9c1 \uc778\uc99d\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ud558\uc9c0 \uc54a\uc544\uc11c \uc694\uccad \ud5e4\ub354\uc5d0 \uc774\ub984\uc744 \ubcf4\ub0b4\uae30\ub85c \ud588\ub2e4. \\n\ub9d0\ub791\uc774 \ud55c\uae00\uc740 \uc548\ub41c\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c Base64\ub85c \uc778\ucf54\ub529\ud558\uace0, \ubc31\uc5d4\ub4dc\uc5d0\uc11c \ub514\ucf54\ub529 \ud558\uc5ec \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4. \\n\uc544\ub798\ub294 pinia\uc5d0 \uc788\ub294 name \uac12\uc744 \uc778\ucf54\ub529 \ud558\ub294 \ucf54\ub4dc\ub2e4. deprecated \ub418\uc5c8\ub2e4\ub294\ub370, \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560 \uc904 \ubab0\ub77c\uc11c \uc77c\ub2e8 \uc774\uac78 \uc0ac\uc6a9\ud588\ub2e4. \\n\\n```ts\\nconst encodedName = () => {\\n const uriComponent = unescape(encodeURIComponent(name.value));\\n return btoa(uriComponent);\\n};\\n```\\n\\n### Elastic Beanstalk\\n\\n\uac00\uc7a5 \ube60\ub974\uac8c \ubc31\uc5d4\ub4dc\ub97c \ubc30\ud3ec\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ubb58\uc9c0 \uace0\ubbfc\ud558\ub2e4\uac00 Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4. \\nElastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uba74 \uc778\ud504\ub77c\uc5d0 \ub300\ud574 \uc798 \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ube60\ub974\uac8c \ubc30\ud3ec\ud558\uace0 \uad00\ub9ac\ud560 \uc218 \uc788\ub2e4. \\n\ubaa8\ub2c8\ud130\ub9c1, \ub85c\uae45, \ub85c\ub4dc \ubc38\ub7f0\uc2f1 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4. \\n\\n### Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac\\n\\n\ucd08\uae30 \uc124\uc815 \uc2dc RDS\ub97c \uc5f0\uacb0\ud558\uace0 \uc124\uc815 \uc644\ub8cc \ud6c4 \ubd84\ub9ac\ud55c\ub2e4\uba74, Beanstalk \uc778\uc2a4\ud134\uc2a4 -> RDS \uc694\uccad \uc2dc \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc744 \uc548 \ud574\ub3c4 \ub41c\ub2e4. \\nRDS \ubd84\ub9ac \uc2dc Beanstalk\uc5d0 \uae30\ubcf8\uc801\uc73c\ub85c \uc124\uc815\ub418\uc5b4 \uc788\ub294 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD\uc640 \uac19\uc740 \ud658\uacbd \ubcc0\uc218\uac00 \uac19\uc774 \uc81c\uac70\ub41c\ub2e4. \\n\ucd94\uac00\ub85c Elastic Beanstalk\ub85c RDS\ub97c \uc124\uc815\ud558\uba74 \uae30\ubcf8 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uba85\uc740 ebdb\ub2e4. \\n\\n### Elastic Beanstalk nginx \uc124\uc815\\n\\n\uc5c5\ub85c\ub4dc\ud558\ub294 zip \ud30c\uc77c \ub0b4\ubd80\uc5d0 `.platform/nginx/conf.d/` \uacbd\ub85c\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ucd94\uac00\ud558\uba74 nginx \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\\n### Jenkins\\n\\n\ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc77c\uc77c\ud788 \ubc30\ud3ec\ud558\uae30 \ubd88\ud3b8\ud574\uc11c Jenkins\ub97c \uc774\uc6a9\ud558\uc5ec Repository\uc5d0 \ucf54\ub4dc\ub97c push \ud560 \ub54c \uc790\ub3d9\uc73c\ub85c \ubc30\ud3ec\uac00 \ub418\uac8c \uc124\uc815\ud558\uae30\ub85c \ud588\ub2e4. \\n\uc791\ub144\uc5d0 \ud655\uc778\ud588\uc744 \ub550 2022\ub144 12\uc6d4 31\uc77c\uae4c\uc9c0 EC2 ARM \uae30\ubc18 t4g.small\uc774 \ubb34\ub8cc\uc600\ub294\ub370, \ub2e4\uc2dc \ub4e4\uc5b4\uac00 \ubcf4\ub2c8 2023\ub144\uae4c\uc9c0 12\uc6d4 31\uc77c\uae4c\uc9c0 t4g.small\uc744 \ubb34\ub8cc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5c8\ub2e4. \\nt4g.small\uc740 \ub7a8\uc774 2G\uc778\ub370, \uc608\uc804\uc5d0\ub294 \ubd80\uc871\ud558\uc9c0 \uc54a\uc558\ub2e4\uace0 \uc0dd\uac01\ud588\ub294\ub370 Java 17\uc744 \uc368\uc11c \uadf8\ub7f0\uac00 \ube4c\ub4dc \ud560 \ub54c \ub7a8\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\uc544\uc11c Swap \uba54\ubaa8\ub9ac 2\uae30\uac00\ub97c \ucd94\uac00\ub85c \uc124\uc815\ud588\ub2e4. \\n\ucd94\uac00\ub85c build.gradle\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8 \uc2dc \uc0ac\uc6a9\ud558\ub294 \ub7a8\uc744 \ub298\ub9b4 \uc218 \uc788\ub2e4. \uae30\ubcf8\uac12\uc740 512MB\ub77c\uace0 \ud55c\ub2e4. \\n\\n```groovy\\ntest {\\n maxHeapSize = \\"1024m\\"\\n}\\n```\\n\\n### Jenkins Blue Ocean\\n\\nBlue Ocean\uc740 Jenkins Pipeline\uc744 \uad6c\uc131\ud558\ub294 \ub370\uc5d0 \uc788\uc5b4 \ud3b8\ub9ac\ud558\uac8c \ud574\uc8fc\ub294 \ub3c4\uad6c\ub2e4. \\n\uc2dc\uac01\ud654\ub3c4 \uc798 \ub418\uc5b4\uc788\uace0, \uc124\uc815\ub3c4 \ud3b8\ub9ac\ud55c \uac83 \uac19\ub2e4. \\n\uc624\ub298 \uc801\uc6a9\ud574 \ubcf4\ub2c8 \ub7a8\uc774 \ubd80\uc871\ud558\uc5ec \uc911\uac04\uc5d0 \uc798 \uc548\ub418\uae30\ub3c4 \ud558\uace0 \uadf8\ub798\uc11c \uadf8\ub0e5 \\"Pipeline\ub9cc \uc0ac\uc6a9\ud560 \uac78 \uadf8\ub7ac\ub098?\\" \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4. \\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[Elastic Beanstalk, AWS](https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/Welcome.html) \\n[EC2 AWS Graviton, AWS](https://aws.amazon.com/ko/ec2/graviton/) \\n[Default Memory Settings, AWS](https://docs.gradle.org/current/userguide/upgrading_version_4.html#rel5.0:default_memory_settings)"},{"id":"jenkins","metadata":{"permalink":"/jenkins","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx","source":"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx","title":"Jenkins\ub85c CI/CD \uc124\uc815","description":"\uc124\uc815 \ud658\uacbd","date":"2023-04-30T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 30\uc77c","tags":[{"label":"Jenkins","permalink":"/tags/jenkins"},{"label":"Elastic Beanstalk","permalink":"/tags/elastic-beanstalk"}],"readingTime":7.495,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Jenkins\ub85c CI/CD \uc124\uc815","slug":"jenkins","tags":["Jenkins","Elastic Beanstalk"]},"unlisted":false,"prevItem":{"title":"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec","permalink":"/tecochat-retrospective-2"},"nextItem":{"title":"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30","permalink":"/tecochat-retrospective-1"}},"content":"### \uc124\uc815 \ud658\uacbd\\n\\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc774\ubbf8\uc9c0: Amazon Linux 2023 AMI \\n\uc544\ud0a4\ud14d\uccd0: ARM \\n\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small \\n\ud658\uacbd \uad6c\uc131\uc774 \uc644\ub8cc\ub41c Elastic Beanstalk \\n\ub2e8\uc77c Spring Boot \ud504\ub85c\uc81d\ud2b8\uac00 \uc874\uc7ac\ud558\ub294 Github Repository\\n\\n### \\\\[EC2 CLI\\\\] Swap \uba54\ubaa8\ub9ac \uc124\uc815\\n\\nt4g.small\uc774 \ub7a8\uc774 2G\uc778\ub370 \ub7a8\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \ub290\uaef4\uc838\uc11c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud588\ub2e4. \\n\uc544\ub798 \uba85\ub839\uc5b4\ub97c \ub530\ub77c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud558\uace0 free -h \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uc798 \uc124\uc815\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n``` bash\\n# fallocate \uc774\uc6a9\ud558\uc5ec \uc2a4\uc651 \ud30c\uc77c \uc0dd\uc131\\nsudo fallocate -l 2G /swapfile\\n\\n# \uad8c\ud55c \uc124\uc815\\nsudo chmod 600 /swapfile\\n\\n# \ud30c\uc77c\uc744 Swap \ud3ec\ub9f7\uc73c\ub85c \ubcc0\uacbd \ud6c4 \uc2dc\uc2a4\ud15c\uc5d0 \ub4f1\ub85d\\nsudo mkswap /swapfile\\nsudo swapon /swapfile\\n\\n# Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9\\n# \ucd5c\ud558\ub2e8\uc5d0 \ub2e4\uc74c \uad6c\ubb38 \uc124\uc815 -> /swapfile swap swap defaults 0 0\\nsudo vim /etc/fstab\\n```\\n\\n\\n### \\\\[EC2 CLI\\\\] jenkins \uc124\uce58\\n\\n```bash\\nsudo wget -O /etc/yum.repos.d/jenkins.repo \\\\\\n https://pkg.jenkins.io/redhat-stable/jenkins.repo\\nsudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key\\nsudo yum upgrade\\nsudo yum install java-17-amazon-corretto-devel\\nsudo yum install jenkins\\nsudo systemctl daemon-reload\\n```\\n\\n[Jenkins \uacf5\uc2dd \ud648\ud398\uc774\uc9c0](https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos) \ub97c \ucc38\uace0\ud558\uc5ec \uc124\uce58\ud558\ub294 \uac8c \uc88b\ub2e4.\\n\\n### \\\\[EC2 CLI\\\\] Jenkins \uc2dc\uc791\\n\\n```bash\\nsudo systemctl enable jenkins\\nsudo systemctl start jenkins\\n```\\n\\nenable\ub85c \uc124\uc815\ud558\uc5ec \ubd80\ud305\uc2dc \uc790\ub3d9\uc2dc\uc791 \ub418\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4.\\n\\n### \\\\[EC2 CLI\\\\] nginx & git \uc124\uce58\\n\\n```bash\\nsudo yum install nginx\\nsudo systemctl enable nginx\\nsudo systemctl start nginx\\n\\nsudo yum install git\\n```\\n\\nnginx\uc640 \ucf54\ub4dc\ub97c \ubd88\ub7ec\uc62c \ub54c \uc0ac\uc6a9\ud560 git\uc744 \uc124\uce58\ud55c\ub2e4.\\n\\n### \\\\[EC2 CLI\\\\] nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815\\n\\n\uc544\ub798 \uc124\uc815 \ud30c\uc77c\uc740 \uacf5\uc2dd \ud648\ud398\uc774\uc9c0\uc5d0\uc11c \uc548\ub0b4\ud55c \uae30\ubcf8\uc801\uc778 \uc124\uc815 \ud30c\uc77c\uc774\ub2e4.\\n\\n```bash\\nupstream jenkins {\\n keepalive 32; # keepalive connections\\n server 127.0.0.1:8080; # jenkins ip and port\\n}\\n\\n# Required for Jenkins websocket agents\\nmap $http_upgrade $connection_upgrade {\\n default upgrade;\\n \'\' close;\\n}\\n\\nserver {\\n listen 80; # Listen on port 80 for IPv4 requests\\n\\n server_name jenkins.example.com; # replace \'jenkins.example.com\' with your server domain name\\n\\n # this is the jenkins web root directory\\n # (mentioned in the output of \\"systemctl cat jenkins\\")\\n root /var/run/jenkins/war/;\\n\\n access_log /var/log/nginx/jenkins.access.log;\\n error_log /var/log/nginx/jenkins.error.log;\\n\\n # pass through headers from Jenkins that Nginx considers invalid\\n ignore_invalid_headers off;\\n\\n location ~ \\"^/static/[0-9a-fA-F]{8}\\\\/(.*)$\\" {\\n # rewrite all static files into requests to the root\\n # E.g /static/12345678/css/something.css will become /css/something.css\\n rewrite \\"^/static/[0-9a-fA-F]{8}\\\\/(.*)\\" /$1 last;\\n }\\n\\n location /userContent {\\n # have nginx handle all the static requests to userContent folder\\n # note : This is the $JENKINS_HOME dir\\n root /var/lib/jenkins/;\\n if (!-f $request_filename){\\n # this file does not exist, might be a directory or a /**view** url\\n rewrite (.*) /$1 last;\\n break;\\n }\\n sendfile on;\\n }\\n\\n location / {\\n sendfile off;\\n proxy_pass http://jenkins;\\n proxy_redirect default;\\n proxy_http_version 1.1;\\n\\n # Required for Jenkins websocket agents\\n proxy_set_header Connection $connection_upgrade;\\n proxy_set_header Upgrade $http_upgrade;\\n\\n proxy_set_header Host $host;\\n proxy_set_header X-Real-IP $remote_addr;\\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\\n proxy_set_header X-Forwarded-Proto $scheme;\\n proxy_max_temp_file_size 0;\\n\\n #this is the maximum upload size\\n client_max_body_size 10m;\\n client_body_buffer_size 128k;\\n\\n proxy_connect_timeout 90;\\n proxy_send_timeout 90;\\n proxy_read_timeout 90;\\n proxy_buffering off;\\n proxy_request_buffering off; # Required for HTTP CLI commands\\n proxy_set_header Connection \\"\\"; # Clear for keepalive\\n }\\n\\n}\\n```\\n\\nJenkins\ub294 8080 \ud3ec\ud2b8\ub85c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc\ub97c \uc124\uc815\ud574\uc900\ub2e4. \\n`/etc/nginx/conf.d`\xa0\uc544\ub798\xa0`default.conf`\xa0\ud30c\uc77c\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uace0 \uc704\uc640 \uac19\uc774 \uc785\ub825\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4. \\nnginx\uc758 \uae30\ubcf8 \uc124\uc815 \ud30c\uc77c\uc5d0 \uc874\uc7ac\ud558\ub294\xa0`include /etc/nginx/conf.d/*.conf;`\xa0\uc124\uc815 \ub54c\ubb38\uc5d0\xa0`.conf`\xa0\ub85c \ub05d\ub09c\ub2e4\uba74 \uc124\uc815\uc774 \uc801\uc6a9\ub41c\ub2e4. \\n\uc124\uc815 \ud6c4\xa0`sudo nginx -t`\ub85c \uc124\uc815\ud30c\uc77c\uc774 \uc815\uc0c1\uc778\uc9c0 \ud655\uc778\ud558\uace0,\xa0`sudo systemctl restart nginx`\xa0\uba85\ub839\uc5b4\ub85c nginx\ub97c \uc7ac\uc2dc\uc791\ud55c\ub2e4. \\n\\n### \\\\[Jenkins\\\\] Jenkins \uc811\uc18d\\n\\nJenkins\ub97c \uc124\uce58\ud55c EC2 \uc778\uc2a4\ud134\uc2a4 \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc5d0 80\ubc88 \ud3ec\ud2b8\uac00 \uc5f4\ub824\uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. \\nEC2\uc758 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \uc785\ub825\ud558\uace0 \ub4e4\uc5b4\uac00\uba74 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\ub77c\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4.\\n\\n![jenkins-start](./jenkins-start.png)\\n\\n\ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud574\uc57c \ud558\ub294\ub370 `sudo cat /var/lib/jenkins/secrets/initialAdminPasswor` \ub97c \uc785\ub825\ud574 \ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc5bb\uc744 \uc218 \uc788\ub2e4. \\n\ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\uba74 \ud50c\ub7ec\uadf8\uc778 \uc124\uc815 \ucc3d\uc774 \ub098\uc62c\ud150\ub370 `install suggested plugins`\uc744 \ud074\ub9ad\ud558\uc5ec Jenkins\uac00 \ucd94\ucc9c\ud558\ub294 \uae30\ubcf8 \ud50c\ub7ec\uadf8\uc778\ub4e4\uc744 \uc124\uce58\ud558\uba74 \ub41c\ub2e4. \\n\ud50c\ub7ec\uadf8\uc778\uc744 \uc124\uce58\ud558\uba74 \uacc4\uc815 \ubc0f \uc8fc\uc18c \uc124\uc815\uc744 \ud574\uc57c\ud558\ub294\ub370 \uc774\uac74 \ud3b8\ud558\uac8c \uc124\uc815\ud558\uba74 \ub41c\ub2e4. \\n\\n### \\\\[Jenkins\\\\] Jenkins Blue Ocean \uc124\uce58\\n\\nJenkins \uad00\ub9ac \u2192 Plugin Manager\uc5d0\uc11c Blue Ocean\uc744 \uac80\uc0c9\ud574 \uc124\uce58\ud55c\ub2e4.\\n\\n### \\\\[AWS IAM & EC2\\\\] IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30\\n\\nS3\uc640 Elastic Beanstalk\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc744 \ubd80\uc5ec\ud558\ub824\uba74 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk \ub450 \uac1c\uc758 \uc815\ucc45\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uc5ed\ud560\uc744 \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4. \\nIAM\uc5d0\uc11c \ub2e4\uc74c\uacfc \uac19\uc774 \uc5ed\ud560\uc744 \ud558\ub098 \uc0c8\ub85c \uc0dd\uc131\ud55c\ub2e4.\\n\\n1. \uc5d4\ud130\ud2f0 \uc120\ud0dd\\n\\n![aws-iam1](./aws-iam1.png)\\n\\n2. \uad8c\ud55c \ucd94\uac00\\n\\n![aws-iam2](./aws-iam2.png)\\n\\n3. \uc774\ub984 \uc9c0\uc815, \uac80\ud1a0 \ubc0f \uc0dd\uc131\\n\\n![aws-iam3](./aws-iam3.png)\\n\\n4. \uc0dd\uc131\ud55c IAM EC2 Jenkins \uc778\uc2a4\ud134\uc2a4\ub97c \uc120\ud0dd\ud558\uace0, \uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc744 \ub20c\ub7ec Role \uc124\uc815\\n\\n![aws-iam4](./aws-iam4.png)\\n\\n### \\\\[AWS S3\\\\] Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131\\n\\n\ubc84\ud0b7\uc744 \uc0dd\uc131\ud560 \ub54c \ub2e4\uc74c \uc124\uc815\uc744 \uc81c\uc678\ud558\uace0 \ubaa8\ub450 \ucc28\ub2e8 \ud65c\uc131\ud654\ub97c \ud574\uc900\ub2e4.\\n\\n- `\uc0c8 ACL(\uc561\uc138\uc2a4 \uc81c\uc5b4 \ubaa9\ub85d)\uc744 \ud1b5\ud574 \ubd80\uc5ec\ub41c \ubc84\ud0b7 \ubc0f \uac1d\uccb4\uc5d0 \ub300\ud55c \ud37c\ube14\ub9ad \uc561\uc138\uc2a4 \ucc28\ub2e8`\\n\\n![aws-s3](./aws-s3.png)\\n\\n### \\\\[Github\\\\] Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131\\n\\nrepo, user:email \uad8c\ud55c\uc774 \uc788\ub294 \ud1a0\ud070\uc774 \ud544\uc694\ud558\ub2e4. \\n\\n### \\\\[Jenkins\\\\] \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791\\n\\n![jenkins-blue-ocean1](./jenkins-blue-ocean1.png)\\n\\n\ube14\ub8e8 \uc624\uc158 \uc5f4\uae30\ub85c \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc0dd\uc131\ud55c\ub2e4. \\n\ud1a0\ud070 \uc785\ub825 \u2192 \uc870\uc9c1 \uc120\ud0dd \u2192 CI/CD \uc124\uc815\ud560 Repository \uc120\ud0dd\uc744 \ud558\uba74 \ud30c\uc774\ud504\ub77c\uc778 \ucc3d\uc73c\ub85c \ub118\uc5b4\uac04\ub2e4. \\nJenkinsfile\uc744 \uc9c1\uc811 \uc791\uc131\ud558\uc5ec \uc124\uc815\ud558\uae30 \uc704\ud574 \uac04\ub2e8\ud558\uac8c print \ud558\ub098 \ucd9c\ub825\ud558\ub294 \uac83\uc73c\ub85c \uc124\uc815\ud588\ub2e4. \\n\\n![jenkins-blue-ocean2](./jenkins-blue-ocean2.png)\\n\\n\ud30c\uc774\ud504\ub77c\uc778\uc774 \uc2e4\ud589\ub420 \ud150\ub370 pipeline status\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \ucd08\ub85d\ubd88\uc774 \ub728\uba74 \ub41c\ub2e4.\\n\\n![jenkins-blue-ocean3](./jenkins-blue-ocean3.png)\\n\\n### \\\\[Github Repsoitory\\\\] Jenkinsfile \uc124\uc815\\n\\n\ube14\ub8e8 \uc624\uc158 \uc2dc\uc791\uc744 \ud1b5\ud574 \uc124\uc815\ud558\uba74 Jenkinsfile\uc774 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc9c0\uace0, \uc544\ub798\uc640 \uac19\uc774 \uc6d0\ud558\ub294 \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc124\uc815\ud55c\ub2e4.\\n\\n```bash\\npipeline {\\n agent any\\n stages {\\n stage(\'build and test\') {\\n steps {\\n sh \'/gradlew clean build\'\\n }\\n }\\n stage(\'zip\') {\\n steps {\\n sh \'mv ./build/libs/woowachat.jar .\'\\n sh \'zip -r woowachat.zip .platform delivery.jar Procfile\'\\n }\\n }\\n stage(\'upload\') {\\n steps {\\n sh \'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2\'\\n }\\n }\\n stage(\'deploy\') {\\n steps {\\n sh \'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket=\\"woowa-chat\\",S3Key=\\"woowachat.zip\\"\'\\n sh \'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}\'\\n }\\n }\\n }\\n}\\n```\\n\\n### \\\\[Github\\\\] Webhooks \uc124\uc815\\n\\n![github-hook](./github-hook.png)\\n\\npush \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud560 \ub54c `http://Jenkins\uc8fc\uc18c/github-webhook/` \ub85c post request\ub97c \ud558\ub3c4\ub85d \uc6f9\ud6c5\uc744 \uc124\uc815\ud55c\ub2e4.\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n[Install Jenkins - CentOS, Jenkins](https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos) \\n[Nginx Reverse Proxy Configuration, Jenkins](https://www.jenkins.io/doc/book/system-administration/reverse-proxy-configuration-nginx/) \\n[Amazon Corretto 17 JDK Install, AWS](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html) \\n[Amazon Linux 2023 packages, AWS](https://docs.aws.amazon.com/linux/al2023/release-notes/all-packages-al2023-20230419.html)"},{"id":"tecochat-retrospective-1","metadata":{"permalink":"/tecochat-retrospective-1","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx","source":"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx","title":"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30","description":"4\uc6d4 21\uc77c \uae08\uc694\uc77c","date":"2023-04-22T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 22\uc77c","tags":[{"label":"TecoChat","permalink":"/tags/teco-chat"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":5.68,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30","slug":"tecochat-retrospective-1","tags":["TecoChat","Retrospective"]},"unlisted":false,"prevItem":{"title":"Jenkins\ub85c CI/CD \uc124\uc815","permalink":"/jenkins"},"nextItem":{"title":"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c","permalink":"/book-leadership-and-self-deception"}},"content":"### 4\uc6d4 21\uc77c \uae08\uc694\uc77c\\n\\n\ub808\ubca8 2\ub97c \uc2dc\uc791\ud55c \ub4a4 \ub0b4\uac00 \ud559\uc2b5\uc5d0 \ub300\ud55c \ubc29\ud5a5\uc744 \uc783\uc5b4\ubc84\ub838\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4. \\n\ub808\ubca8 3, 4\uc5d0\uc11c \ub098\ub9cc\uc758 \uac15\uc810\uc744 \uac00\uc9c0\uace0 \uc2f6\uc5b4 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4. \\n\ub2e8\uc21c\ud788 \uc2a4\ud504\ub9c1\uc744 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ud6a8\uc728\uc774 \ub9ce\uc774 \ub5a8\uc5b4\uc9c4\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uae00\uc4f0\uae30 \uc218\uc0c1\uc73c\ub85c \ubc1b\uc740 \ucfe0\ud3f0\uc744 \uc0ac\uc6a9\ud574 \ube0c\ub77c\uc6b4\uc5d0\uac8c \ucee4\ud53c\ucc57\uc744 \uc2e0\uccad\ud588\uace0, \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud574\ubcf4\ub77c\ub294 \ub2f5\uc744 \ubc1b\uc558\ub2e4. \\n\\n\ub098\ub294 \uc544\uc774\ub514\uc5b4\ub97c \ubabb\ub0b4\ub294 \ud3b8\uc778\ub370 \ube0c\ub77c\uc6b4\uc774 \uc544\uc774\ub514\uc5b4\uae4c\uc9c0 \ub358\uc838\uc8fc\uc168\ub2e4. \\n`Chat-GPT \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uace0, \ud574\ub2f9 \ud06c\ub8e8\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc744 \uacf5\uc720\ud560 \uc218 \uc788\ub294 \uac74 \uc5b4\ub5a4\uc9c0?` \\n\\n\uae30\uc220\uc774 \ubaa9\uc801\uc778 \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4\ub294 \ub2f5\ubcc0\uc744 \ub4e4\uc5c8\uace0, \ud63c\uc790 \uc544\ub2c8\uba74 \ud398\uc5b4\ud560 \uc218 \uc788\uc744 \uc815\ub3c4\uc758 \uc778\uc6d0\uc73c\ub85c \uc9c4\ud589\ud558\uba74 \uc88b\uaca0\ub2e4\uace0 \ud558\uc168\ub2e4. \\n\ud504\ub860\ud2b8\ub791 \uac04\ub2e8\ud558\uac8c \ubc30\ud3ec\uae4c\uc9c0 \ud574\ubcf8 \uacbd\ud5d8\uc774 \uc788\uc5b4\uc11c \ud63c\uc790\ud574\ub3c4 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uc744 \uac83 \uac19\uc544\uc11c \ud63c\uc790 \ud558\uae30\ub85c \ub9c8\uc74c\uc744 \uba39\uc5c8\ub2e4. \\n\\n\uc774\uac74 \ubabb\ucc38\uc9c0\\n\\n### \ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?\\n\\n\ucee4\ud53c\ucc57\uc774 \ub05d\ub098\uace0 \uc9d1\uc73c\ub85c \ub3cc\uc544\uac00\ub294 \uae38\uc5d0 \ubc14\ub85c \ub3c4\uba54\uc778\uc744 \uad6c\ub9e4\ud558\ub824\uace0 namecheap\uc5d0\uc11c \uc801\ub2f9\ud55c \ub3c4\uba54\uc778\uc774 \uc5c6\uc744\uae4c \uac80\uc0c9\uc744 \uacc4\uc18d\ud588\ub2e4. \\n\ub9c8\uce58 \uc5b4\ub9b4 \ub54c \ud588\ub358 \uac8c\uc784 \ub2c9\ub124\uc784 \uc815\ud558\ub294 \uac83\ucc98\ub7fc \uc2dc\uac04\uc774 \uc624\ub798 \uac78\ub838\ub2e4. \\ndev, io, chat \ub3c4\uba54\uc778\uc774 \ud6c4\ubcf4\uc600\uace0 \uc9d1 \uac00\ub294 \uae38\uc5d0 \uacb0\uc815\ub9cc \ud558\ub2e4\uac00 \uad6c\ub9e4\ud558\uc9c0 \ubabb\ud588\ub2e4.\\n\\n### \ub9d0\ub791\uc758 DM\\n\\n\uc9d1\uc5d0 \uac00\uc11c \ubc25\uc744 \uba39\uace0 \ub9d0\ub791\uc774\ub791 DM \ud558\ub2e4 \ud504\ub85c\uc81d\ud2b8\ub97c \uac19\uc774 \ud558\uc790\ub294 \uc774\uc57c\uae30\uac00 \ub098\uc654\ub2e4. \\n\uc6b0\ud14c\ucf54 \ucd5c\uace0 \uace0\uc218 \ub9d0\ub791\uc758 \uc694\uad6c\ub77c \uc218\ub77d\ud558\uc9c0 \uc54a\uc73c\uba74 \ud6c4\ud3ed\ud48d\uc744 \uac10\ub2f9\ud560 \uc218 \uc5c6\uc5c8\ub2e4. \\n\\n\uc774\ub7f0\uc800\ub7f0 \ub300\ud654\ub97c \ub098\ub204\ub2e4\uac00 \ub09c \ube60\ub974\uac8c \ud504\ub85c\ud1a0\ud0c0\uc785\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\uace0 \uc2f6\uc5b4\uc11c \ud504\ub860\ud2b8\ub97c \uad6c\ud604\ud55c\ub2e4\uace0 \ud588\uace0, \ub9d0\ub791\uc740 GPT api\ub97c \uc870\uc0ac\ud558\uae30\ub85c \ud588\ub2e4. \\n\ucd94\uac00\ub85c \ub3c4\uba54\uc778\uc5d0 \uad00\ud55c \uc774\uc57c\uae30\ub97c \ud558\ub2e4\uac00 woowachat\uc774 \uc5b8\uae09\ub418\uc5c8\uace0, namecheap\uc5d0\uc11c chat \ub3c4\uba54\uc778\uc744 \uc0ac\uc6a9\ud55c woowa.chat\uc73c\ub85c \uad6c\ub9e4\ud588\ub2e4. \\n\uc774\ud6c4\uc5d0 teco.chat\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4!\\n\\n### \ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec\\n\\n\ud1a0\uc694\uc77c\uc5d0 \uad6c\ub9e4\ud55c \ub3c4\uba54\uc778\uc744 CDN, \ubcf4\uc548 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\ub294 Cloudflare\uc5d0 \ub3c4\uba54\uc778 \ub4f1\ub85d\uc744 \ud588\ub2e4. \\n\ub098\uc5d0\uac8c \uc775\uc219\ud55c Nuxt3\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\uace0, Cloudflare Pages\ub97c \uc774\uc6a9\ud558\uc5ec \ubc30\ud3ec\ud588\ub2e4. \\n\\n### GPT\\n\\n\ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud558\ub2c8 api limit\uc774 \uc788\uc5b4 \ubd84\ub2f9 3\ubc88\ubc16\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4. \\n\uc77c\ub2e8 \ubc31\uc5d4\ub4dc\ub97c \uad6c\ucd95\ud558\uae30 \uc804\uc5d0\ub294 \ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud560 \uc0dd\uac01\uc774\ub2e4. \\n\\n### Sonarcloud\\n\\n\uc815\uc801 \ucf54\ub4dc \ubd84\uc11d \ub3c4\uad6c\ub85c Sonarcloud\ub97c \uc801\uc6a9\ud588\ub2e4. \\nSonarcloud\ub294 SonarQube\uc758 SaaS \ubc84\uc804\uc774\uace0 \uc0ac\uc6a9\uc774 \ub9e4\uc6b0 \ud3b8\ud558\ub2e4. \\n\uc608\uc804\uc5d0 Sonarcloud\ub97c \uc0ac\uc6a9\ud560 \ub550 \ubc84\ud2bc \uba87 \ubc88 \ub204\ub974\uba74 \uc801\uc6a9\ud560 \uc218 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \ubc14\ub85c github action\uc744 \uc0ac\uc6a9\ud558\ub77c\ub294 \uc548\ub0b4 \ud398\uc774\uc9c0\ub85c \uc774\ub3d9\ud588\ub2e4. \\nSonarcloud\uac00 \uc790\uccb4\uc801\uc73c\ub85c github repository\uc5d0 push \ud558\uba74 \uc815\uc801 \ubd84\uc11d\uc744 \ud574\uc8fc\ub294 \uae30\ub2a5\uc744 \uc6d0\ud588\uace0, Administration -> Analysis Method\uc5d0 Automatic Analysis\ub97c \uc124\uc815\ud558\ub2c8 \ub418\uc5c8\ub2e4. \\n\ub108\ubb34 \uaf41\uaf41 \uc228\uaca8\uc838\uc788\ub124\\n\\n### Tiptap\\n\\n\ucf54\ub4dc \ud558\uc774\ub77c\uc774\ud305 \uae30\ub2a5\uc744 \ub123\uace0 \uc2f6\uc5b4\uc11c Tiptap\uc744 \uc0ac\uc6a9\ud588\ub2e4. \\nTiptap\uc740 Headless WYSIWYG \uc5d0\ub514\ud130\ub85c \uc0ac\uc6a9\uc790 \uc815\uc758 \uae30\ub2a5\uc5d0 \ud2b9\ud654\ub418\uc5b4\uc788\ub294 \uc5d0\ub514\ud130\ub2e4. \\n\uc544\uc9c1 Tiptap\uc774 \uc81c\uacf5\ud558\ub294 \ubaa8\ub4e0 \uae30\ub2a5\uc744 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc0ac\uc6a9\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc CodeBlockLowlight \ud50c\ub7ec\uadf8\uc778\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucf54\ub4dc \ube14\ub85d\uc744 \uc608\uc058\uac8c \ucd9c\ub825\ud560 \uc218 \uc788\uc5c8\ub2e4. \\napi \ubc18\ud658\uac12 \uadf8\ub300\ub85c tiptap\uc758 content\uc5d0 \uc124\uc815\ud588\ub354\ub2c8 \ucf54\ub4dc \ube14\ub85d\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc544\uc11c \ubc31 \ud2f1 3\uac1c\ub97c `<pre><code>`\ub85c \ubcc0\ud658\ud588\ub2e4. \\n\ucd94\uac00\ub85c \ub744\uc5b4\uc4f0\uae30\ub3c4 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc544\uc11c `\\\\n`\ub97c `<br>`\ud0dc\uadf8\ub85c \ubcc0\ud658\ud588\ub2e4. \\n\ubcc0\ud658\ud558\ub294 \ub85c\uc9c1\uc740 GPT\uc758 \ub3c4\uc6c0\uc744 \ub9ce\uc774 \ubc1b\uc558\ub2e4. \\n\\n```ts\\nconst replaceCodeFences = (input: String) => {\\n const codeFencesRegex = /```([\\\\w-]*)\\\\n([\\\\s\\\\S]*?)\\\\n```/g;\\n return input\\n .replace(codeFencesRegex, (match, p1, p2) => {\\n const languageClass = p1 ? ` class=\\"language-${p1}\\"` : \\"\\";\\n return `<pre><code${languageClass}>${p2}</code></pre>`;\\n })\\n .replace(/\\\\n/g, \\"<br>\\");\\n};\\n```\\n\\nTiptap\uc744 \uc801\uc6a9\ud558\ub2c8 \ub2e4\uc74c\uacfc \uac19\uc774 \uae54\ub054\ud55c \ucf54\ub4dc \ube14\ub85d\uc744 \ubcfc \uc218 \uc788\uc5c8\ub2e4. \\n\\n![tecochat](./teco-chat.png)\\n\\n### \ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9\\n\\n\ud0c0\uc774\ud2c0\uc740 \ubc30\ub2ec\uc758\ubbfc\uc871 \ub3c4\ud604\uccb4, \ub0b4\uc6a9\uc740 IBM Plex Sans\ub97c \uc0ac\uc6a9\ud588\ub2e4. \\n\ucd94\uac00\ub85c favicon\ub3c4 \uac04\ub2e8\ud558\uac8c \uc801\uc6a9\ud574\uc11c \ub9cc\uc871\uc2a4\ub7ec\uc6e0\ub2e4."},{"id":"book-leadership-and-self-deception","metadata":{"permalink":"/book-leadership-and-self-deception","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx","source":"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx","title":"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c","description":"\ucc45 \uc815\ubcf4","date":"2023-04-08T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 8\uc77c","tags":[{"label":"Book","permalink":"/tags/book"}],"readingTime":5.16,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c","slug":"book-leadership-and-self-deception","tags":["Book"]},"unlisted":false,"prevItem":{"title":"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30","permalink":"/tecochat-retrospective-1"},"nextItem":{"title":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","permalink":"/innodb-lock"}},"content":"### \ucc45 \uc815\ubcf4\\n\\n> \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c \\n> \uc544\ube48\uc800\uc5f0\uad6c\uc18c\\n> \\n\\n### \uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18\\n\\n\ucc45\uc5d0\uc11c\ub294 \uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc744 \ub2e4\ub8ec\ub2e4. \\n- \uc790\uae30\uae30\ub9cc: \uc790\uc2e0\uc758 \ubb38\uc81c\ub97c \uc778\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 \\n- \uc790\uae30\ubc30\ubc18: \ub2e4\ub978 \uc0ac\ub78c\uc744 \uc704\ud574 \ubb34\uc5b8\uac00 \ud574\uc57c\ub9cc \ud55c\ub2e4\ub294 \uc0dd\uac01\uc744 \ubc18\ud558\ub294 \ud589\uc704\\n\\n\uc790\uae30\ubc30\ubc18\uc744 \ud55c\ub2e4\uba74 \uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uac00 \ub41c\ub2e4. \\n\uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uc5d0 \ube60\uc9c0\ub294 \uac83\uc744 \ucc45\uc5d0\uc11c\ub294 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac04\ub2e4\uace0 \ud45c\ud604\ud55c\ub2e4. \\n\\n### \uc77d\uace0 \ub098\uc11c\\n\\n\ucd5c\uadfc\uc5d0 \uc77d\uc740 \ucc45 \uc911 \uac00\uc7a5 \ub9c8\uc74c\uc774 \ubd88\ud3b8\ud588\ub2e4. \\n\uadf8\ub807\uae30\uc5d0 \ub354\ub354\uc6b1 \ub098\uc5d0\uac8c \ud544\uc694\ud55c \ub0b4\uc6a9\uc774 \ub2f4\uaca8\uc788\uc5c8\ub2e4. \\n\\n\uc0b4\uba74\uc11c \ub9ce\uc740 \uc120\ud0dd\uc758 \uc21c\uac04\uc774 \uc874\uc7ac\ud588\uace0, \uadf8 \uc21c\uac04\ub9c8\ub2e4 \uc790\uae30\ubc30\ubc18\uc744 \ud0dd\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4. \\n\uc791\uac8c\ub294 \uc9d1\uc548\uc77c\uc744 \ud574\uc57c \ud558\ub294\ub370 \ubab8\uc774 \uc870\uae08 \ud798\ub4e4\ub2e4\uace0 \ud558\uc9c0 \uc54a\uac70\ub098 \\n\ud06c\uac8c\ub294 \uc798\ubabb\uc744 \uc778\uc815\ud574\uc57c \ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uadf8\ub7ec\uc9c0 \uc54a\uc740 \uacbd\uc6b0\uac00 \uc788\uc5c8\ub2e4. \\n\uc774\ub7f0 \uc0c1\ud669\uc774 \ubc18\ubcf5\ub418\uc5b4 \uacb0\uad6d \uc0c1\uc790 \uc548\uc5d0 \ub098 \uc790\uc2e0\uc744 \uac00\ub450\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4. \\n\\n\ub354 \ub098\uc740 \uc0b6\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \uc9c0\uc18d\uc801\uc73c\ub85c \ud655\uc778\ud558\uace0, \uc0c1\uc790 \ubc16\uc73c\ub85c \ub098\uac00\ub824\ub294 \uc5f0\uc2b5\uc744 \ud574\uc57c\uaca0\ub2e4. \\n\ub113\uc740 \uc2dc\uc120\uc744 \uac00\uc9c0\uace0, \ud56d\uc0c1 \ub0b4\uac00 \ud2c0\ub9b4 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc0dd\uac01\ud558\uace0 \uc0b4\uc544\uac00\uc790. \\n\\n### \ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4\\n\\n> \uc6b0\ub9ac\uc758 \uc0dd\uac01\uc740 \uc9c0\uc2dd\ubcf4\ub2e4 \uc791\ub2e4. \\n\uc6b0\ub9ac\uc758 \uc9c0\uc2dd\uc740 \uc0ac\ub791\ubcf4\ub2e4 \uc791\ub2e4. \\n\uc6b0\ub9ac\uc758 \uc0ac\ub791\uc740 \uc874\uc7ac\ubcf4\ub2e4 \uc791\ub2e4. \\n\uadf8\ub9ac\uace0 \uc6b0\ub9ac\uac00 \uc0dd\uac01\ud558\ub294 \ub098\ub294 \uc2e4\uc81c\uc758 \ub098\ubcf4\ub2e4 \uadf8\ub9cc\ud07c \uc791\ub2e4. \\nR. D. \ub7ad \\np.19\\n>\\n\\n> \uc6b0\ub9ac\uac00 \uc678\uc801\uc73c\ub85c \uc5b4\ub5a4 \ud589\ub3d9\uc744 \ud558\ub4e0\uc9c0 \uac04\uc5d0, \uc0ac\ub78c\ub4e4\uc740 \uc6b0\ub9ac \ub9c8\uc74c\uc5d0\uc11c \uadf8\ub4e4\uc744 \uc5b4\ub5bb\uac8c \ub300\ud558\uace0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \uc8fc\ub85c \ubc18\uc751\ud569\ub2c8\ub2e4. \\n\uc6b0\ub9ac\uac00 \uc0ac\ub78c\ub4e4\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \ub290\ub07c\uac8c \ub418\ub294\uc9c0\ub294 \uc6b0\ub9ac\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \ud639\uc740 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \ub2ec\ub77c\uc9c0\uac8c \ub429\ub2c8\ub2e4. \\np.66\\n>\\n\\n> \ube44\ub09c\uc740 \uac10\uc815\uc5d0 \uc18d\ud558\uace0 \ub099\uad00\uc740 \uc758\uc9c0\uc5d0 \uc18d\ud55c\ub2e4. \\n\uc778\uac04\uc740 \uac10\uc815\ubcf4\ub2e4 \ub354 \ud070 \uc874\uc7ac\uc774\ub2e4. \\n\uc54c\ub7ad, \ud0c1\ub2db\ud55c \\np.103\\n>\\n\\n> \uc6b0\ub9ac\uac00 \uc790\uc2e0\uc5d0\uac8c\ub9cc \uc9d1\uc911\ud558\uace0 \uc788\ub294 \ud55c, \ud63c\uc790\uc11c \uc77c\ud558\ub294 \uac83 \uc774\uc0c1\uc758 \ucc3d\uc870\uc801\uc778 \uacb0\uacfc\ub098 \ud611\ub825\uc744 \uc774\ub04c\uc5b4 \ub0b8\ub2e4\ub294 \uac83\uc740 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4. \\n\uc624\ub298\ub0a0 \uacbd\uc81c \ud658\uacbd\uc5d0\uc11c\ub294 \ud63c\uc790\uc11c\ub294 \uc77c\uc758 \uacb0\uacfc\ub97c \ud0c1\uc6d4\ud558\uac8c \ub9cc\ub4e4\uc5b4 \ub0b4\uae30\uac00 \uc5b4\ub835\uc2b5\ub2c8\ub2e4. \\n\ub0b4\uac00 \uc911\uc2ec\uc774\uc5b4\uc57c \ub41c\ub2e4\ub294 \ud3d0\uc1c4\uc801\uc778 \uc0ac\uace0\ub294 \ud568\uaed8 \uc77c\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uc5f4\uc815\uc744 \ubd88\ub7ec\uc624\uc9c0 \ubabb\ud569\ub2c8\ub2e4. \\np.175\\n> \\n\\n> \uc194\uc9c1\ud568\uc740 \uc6b0\ub9ac\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\ub294 \uc5f4\uc1e0\uc785\ub2c8\ub2e4. \\n\uadf8\uac83\uc740 \uc790\uc2e0\uc758 \ud589\ub3d9\uacfc \uad00\ub828\ub41c \uc0ac\ub78c\uc5d0 \ub300\ud574 \uae30\uaebc\uc774 \uc0ac\uacfc\ub97c \ud558\ub294 \uac83\uc785\ub2c8\ub2e4. \\n\uadf8\uac83\ub9cc\uc774 \uc2e4\ud0c0\ub798\ucc98\ub7fc \uc5c9\ud0a8 \uad00\uacc4\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc774\uc8e0. \\np.188\\n> \\n\\n> \ub204\uad70\uac00\ub97c \ub098\uc640 \uac19\uc774 \ub3d9\uc77c\ud55c \uac00\uce58\ub97c \uc9c0\ub2cc \ud55c \uc778\uac04\uc73c\ub85c \uc0dd\uac01\ud574\uc11c \uadf8 \uc0ac\ub78c\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \ubc16\uc5d0 \uacc4\uc18d \uba38\ubb34\ub974\uace0 \uc2f6\uc740 \uc5f4\ub9dd\uc774 \uc0dd\uae38 \ub54c, \ub098\ub294 \uc774\ubbf8 \uadf8 \uc0ac\ub78c\uc5d0 \ub300\ud574 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub2e4. \\np.214\\n> \\n\\n> \ub300\ubd80\ubd84\uc758 \uc0ac\ub78c\ub4e4\uc774 \uad00\uacc4 \uae30\uc220\uc744 \uac00\uc9c0\uace0 \uadf8\ub4e4\uc774 \uacaa\uace0 \uc788\ub294 \ubb38\uc81c\ub97c \ubc14\ub85c\uc7a1\uc73c\ub824\uace0 \ud558\ub294 \ub178\ub825\uc774 \uacb0\uc2e4\uc744 \uc5bb\uc9c0 \ubabb\ud558\ub294 \uac83\uc740 \uacb0\ucf54 \uadf8\ub7ec\ud55c \uae30\uc220 \ubd80\uc871 \ub54c\ubb38\uc5d0 \uc0dd\uae30\ub294 \uac83\uc774 \uc544\ub2d9\ub2c8\ub2e4. \\n\uadf8\uac83\ub4e4\uc740 \uc790\uae30\ubc30\ubc18 \ub54c\ubb38\uc5d0 \uc0dd\uaca8\ub0a9\ub2c8\ub2e4. \\np.224\\n>\\n\\n> \uc6b0\ub9ac\ub294 \ud568\uaed8 \uc77c\ud558\uace0 \uc6b0\ub9ac\uc640 \ud568\uaed8 \uc0b4\uc544\uac00\ub294 \uc0ac\ub78c\uc774 \uc9c4\uc815\uc73c\ub85c \ub204\uad6c\uc778\uc9c0 \uc54c\uc9c0 \ubabb\ud569\ub2c8\ub2e4. \\n\uc6b0\ub9ac\uac00 \uadf8\ub4e4\uacfc \uc9c4\uc815\uc73c\ub85c \ud568\uaed8 \uc18c\ud1b5\ud558\uae30 \uc804\uae4c\uc9c0\ub294 \uc6b0\ub9ac\ub294 \uadf8\ub4e4\uc758 \uac00\uce58\ub97c \uc798 \ubaa8\ub985\ub2c8\ub2e4. \\n\uc6b0\ub9ac\uc758 \uc704\ub300\ud568\uc774\ub780 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc758 \uc704\ub300\ud55c \uc810\uc744 \ubc1c\uacac\ud574 \uc8fc\ub294 \uac83\uc5d0 \uc788\uc2b5\ub2c8\ub2e4. \\np.280\\n>"},{"id":"innodb-lock","metadata":{"permalink":"/innodb-lock","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx","source":"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx","title":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","description":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","date":"2023-04-07T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 7\uc77c","tags":[{"label":"DataBase","permalink":"/tags/data-base"},{"label":"Lock","permalink":"/tags/lock"},{"label":"InnoDB","permalink":"/tags/inno-db"}],"readingTime":5.805,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","slug":"innodb-lock","tags":["DataBase","Lock","InnoDB"]},"unlisted":false,"prevItem":{"title":"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c","permalink":"/book-leadership-and-self-deception"},"nextItem":{"title":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","permalink":"/mysql-lock"}},"content":"## InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08\\n\\nMySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08\uacfc \ubcc4\uac1c\ub85c \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub0b4\ubd80\uc5d0\uc11c \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4. \\n\ubcf4\ud1b5 \uba85\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\ub294 \ub4dc\ubb3c\uace0, \uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ubb35\uc2dc\uc801\uc73c\ub85c \uc7a0\uae08\uc774 \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n\ub3d9\uc2dc\uc131 \uc81c\uc5b4 \ubc29\uc2dd\uc5d0\ub294 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uacfc \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc774 \uc788\ub2e4. \\nInnoDB\ub294 \uae30\ubcf8\uc801\uc73c\ub85c MVCC(\ub2e4\uc911 \ubc84\uc804 \ub3d9\uc2dc\uc131 \uc81c\uc5b4)\ub97c \ud1b5\ud574 \ub099\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uace0 \ub77d\uc744 \ud1b5\ud574 \ud2b9\uc815 \uc0c1\ud669\uc5d0\uc11c \ube44\uad00\uc801\uc778 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n:::note \ub099\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(OCC, Optimistic concurrency control)\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \uc11c\ub85c \ucda9\ub3cc\ud558\uc9c0 \uc54a\ub294\ub2e4\uace0 \uac00\uc815\ud558\ub294 \ubc29\uc2dd \\n\\n:::\\n\\n:::note \ube44\uad00\uc801 \ub3d9\uc2dc\uc131 \uc81c\uc5b4(PCC, Pessimistic Concurrency Control)\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \ucda9\ub3cc\ud558\ub294 \uac00\uc815\ud558\uc5d0 \uc7a0\uae08\uc744 \uac70\ub294 \ubc29\uc2dd \\n\uc77c\ubc18\uc801\uc73c\ub85c\xa0Shared Lock, Exclusive Lock\uc744 \ud1b5\ud574 \uc774\ub97c \uad6c\ud604\ud55c\ub2e4.\\n\\n:::\\n\\n### Shared & Exclusive Locks\\n\\nInnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704\uc758 \uc7a0\uae08\uc744 \uc218\ud589\ud560 \ub54c \uacf5\uc720 \uc7a0\uae08\uacfc \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \\n\\n**\uacf5\uc720 \uc7a0\uae08(S, shared lock)**\\n\\n\ub370\uc774\ud130 \uc870\ud68c\ub97c \uc704\ud55c \ub77d, \uc77d\uae30 \uc7a0\uae08(read lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4. \\n\ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uae30\uac00 \uac00\ub2a5\ud558\uc9c0\ub9cc, \uc4f0\uae30\ub294 \ubd88\uac00\ub2a5\ud558\ub2e4. \\n\uc608) `SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;`\\n\\n**\ubc30\ud0c0\uc801 \uc7a0\uae08(X, exclusive lock)** \\n\\n\ub370\uc774\ud130 \ubcc0\uacbd\uc744 \uc704\ud55c \ub77d, \uc4f0\uae30 \uc7a0\uae08(write lock)\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4. \\n\ub77d\uc744 \uac74 \ud2b8\ub79c\uc7ad\uc158\ub9cc\uc774 \ud574\ub2f9 \ub370\uc774\ud130\uc5d0 \uc811\uadfc \uac00\ub2a5\ud558\ub2e4. \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \uc77d\uae30, \uc4f0\uae30\uac00 \ubd88\uac00\ub2a5\ud558\ub2e4. \\n\uc608) `SELECT * FROM table_name WHERE id = 1 FOR UPDATE;`\\n\\n### Intention Locks\\n\\nInnoDB\ub294 \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uacfc \ud14c\uc774\ube14 \uc7a0\uae08\uc758 \uacf5\uc874\uc744 \uc704\ud574 \uc778\ud14d\uc158 \uc7a0\uae08\uc744 \uc9c0\uc6d0\ud55c\ub2e4. \\n\ud14c\uc774\ube14\uc5d0 \uc788\ub294 \ub85c\uc6b0\uc5d0 \ub300\ud574\uc11c \ub098\uc911\uc5d0 \uc694\uccad\ub418\ub294 \uac83\uc774 \uc5b4\ub5a4 \ud615\ud0dc\uc758 \uc7a0\uae08\uc778\uc9c0 \uac00\ub9ac\ud0a4\uae30 \uc704\ud574 \uc0ac\uc6a9\ub41c\ub2e4. \\n\uae30\ubcf8\uc801\uc73c\ub85c \ub85c\uc6b0 \ub2e8\uc704 \uc7a0\uae08\uc744 \uc218\ud589\ud558\uae30 \uc804\uc5d0 \uc778\ud150\uc158 \uc7a0\uae08\uc744 \uba3c\uc800 \ud68d\ub4dd\ud55c\ub2e4. \\n\uc778\ud150\uc158 \ub77d\uc740 \uae30\ubcf8\uc801\uc73c\ub85c \ucda9\ub3cc\uc744 \ubc29\uc9c0\ud558\uace0 \ub370\ub4dc\ub77d\uc744 \ubc29\uc9c0\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. \\n\\n**\uc778\ud150\uc158 \uacf5\uc720 \uc7a0\uae08(IS, intention shared lock)**\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \uacf5\uc720 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.\\n\\n**\uc778\ud150\uc158 \ubc30\ud0c0\uc801 \uc7a0\uae08(IX, intention exclusive lock)** \\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \ud14c\uc774\ube14\uc758 \uac1c\ubcc4 \ub85c\uc6b0\uc5d0 \ub300\ud55c \ubc30\ud0c0\uc801 \uc7a0\uae08\uc744 \uc218\ud589\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.\\n\\n** \uc7a0\uae08\uac04\uc758 \ud638\ud658\uc131 **\\n\\n| | X | IX | S | IS |\\n| --- | --- | --- | --- | --- |\\n| X | Conflict | Conflict | Conflict | Conflict |\\n| IX | Conflict | Compatible | Conflict | Compatible |\\n| S | Conflict | Conflict | Compatible | Compatible |\\n| IS | Conflict | Compatible | Compatible | Compatible |\\n\\n### Record Locks\\n\\n\ub808\ucf54\ub4dc \uc790\uccb4\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4. \\nInnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc740 \ub808\ucf54\ub4dc \uc790\uccb4\uac00 \uc544\ub2c8\ub77c \uc778\ub371\uc2a4\uc758 \ub808\ucf54\ub4dc\ub97c \uc7a0\uadfc\ub2e4. \\n\\n### Gap Locks\\n\\n\ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4. \\n\ub808\ucf54\ub4dc\uc640 \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\uc5d0 \uc0c8\ub85c\uc6b4 \ub808\ucf54\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc744 \uc81c\uc5b4\ud558\uace0, \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc758 \uc77c\ubd80\ub85c \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n### Next-Key Locks\\n\\n\ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4. \\n`REPEATABLE READ` \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ud32c\ud140 \ub9ac\ub4dc\ub97c \ubc29\uc9c0\ud558\uae30 \uc704\ud55c \uc7a0\uae08\uc774\ub2e4. \\n\\n### AUTO-INC Locks\\n\\n`AUTO_INCREMENT` \uce7c\ub9bc\uc774 \uc0ac\uc6a9\ub41c \ud14c\uc774\ube14\uc5d0 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \ub808\ucf54\ub4dc\uac00 `INSERT`\ub418\ub294 \uacbd\uc6b0, \uac01 \ub808\ucf54\ub4dc\ub294 \uc911\ubcf5\ub418\uc9c0 \uc54a\uace0 \uc800\uc7a5\ub41c \uc21c\uc11c\ub300\ub85c \uc99d\uac00\ud558\ub294 \uc77c\ub828\ubc88\ud638 \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4. \\nInnoDB \ub294 \ub0b4\ubd80\uc801\uc73c\ub85c AUTO-INC \ub77d\uc774\ub77c\uace0 \ud558\ub294 \ud14c\uc774\ube14 \uc218\uc900\uc758 \uc7a0\uae08\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158\uacfc \uad00\uacc4 \uc5c6\uc774 `INSERT`\ub098 `REPLACE` \ubb38\uc7a5\uc5d0\uc11c `AUTO_INCREMENT` \uac12\uc744 \uac00\uc838\uc624\ub294 \uc21c\uac04\ub9cc \ub77d\uc774 \uac78\ub838\ub2e4\uac00 \ud574\uc81c\ub41c\ub2e4.\\n\\n### \uc7a0\uae08 \uc608\uc2dc\\n\\n```sql\\n-- \ub808\ucf54\ub4dc\ub294 id \uae30\uc900 10, 20, 30, 40, 50\uc774 \uc788\ub2e4\uace0 \uac00\uc815\\n-- Record Locks: 10\uc5d0 \ub300\ud574 \ub77d\uc774 \uac78\ub9b0\ub2e4.\\nSELECT * FROM table_name where id = 10 for update;\\n\\n-- Gap Locks: 51\ubd80\ud130 PositiveInfinity\uae4c\uc9c0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\\nSELECT * FROM table_name where id > 100 for update;\\n\\n-- Next-Key Locks: 21\ubd80\ud130 30, 31\ubd80\ud130 40\uc5d0 \ub77d\uc774 \uac78\ub9b0\ub2e4.\\nSELECT * FROM table_name where id BETWEEN 25 AND 35 for update;\\n```\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\nReal My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1 \\n[Optimistic and Pessimistic record locking, IBM](https://www.ibm.com/docs/en/rational-clearquest/9.0.0?topic=clearquest-optimistic-pessimistic-record-locking) \\n[MySQL Innodb Locks, cecil1018](https://cecil1018.wordpress.com/2016/06/18/mysql-innodb-locks/) \\n[MySQL 8.0 InnoDB Locks, MySQL](https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html) \\n[Locks Set by Different SQL Statements in InnoDB, MySQL](https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html)"},{"id":"mysql-lock","metadata":{"permalink":"/mysql-lock","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx","source":"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx","title":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","description":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","date":"2023-04-06T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 6\uc77c","tags":[{"label":"DataBase","permalink":"/tags/data-base"},{"label":"Lock","permalink":"/tags/lock"},{"label":"MySQL","permalink":"/tags/my-sql"}],"readingTime":4.405,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","slug":"mysql-lock","tags":["DataBase","Lock","MySQL"]},"unlisted":false,"prevItem":{"title":"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08","permalink":"/innodb-lock"},"nextItem":{"title":"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900","permalink":"/transaction-and-isolation"}},"content":"## MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08\\n\\nMySQL\uc5d0\uc11c\uc758 \ub77d\uc740 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub808\ubca8\uacfc, MySQL \uc5d4\uc9c4 \ub808\ubca8\ub85c \ub098\ub20c \uc218 \uc788\ub2e4. \\nMySQL \uc5d4\uc9c4 \ub808\ubca8\uc758 \uc7a0\uae08\uc740 \ubaa8\ub4e0 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce5c\ub2e4. \\n\\n### \uae00\ub85c\ubc8c \ub77d(Global lock)\\n\\nMySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08 \uc911 \uac00\uc7a5 \ub113\uc740 \ubc94\uc704\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \uc7a0\uae08\uc774\ub2e4. \\n - \uc601\ud5a5\uc744 \ubbf8\uce58\ub294 \ubc94\uc704\ub294 \ud574\ub2f9 \uc11c\ubc84 \uc804\uccb4\uc774\ub2e4.\\n - \uc791\uc5c5 \ub300\uc0c1 \ud14c\uc774\ube14, \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0c1\uad00 \uc5c6\uc774 \ub3d9\uc77c\ud558\uac8c \uc601\ud5a5\uc744 \ubc1b\ub294\ub2e4.\\n\\n\ud55c \uc138\uc158\uc5d0\uc11c \uae00\ub85c\ubc8c \ub77d\uc744 \ud68d\ub4dd\ud558\uba74 \ud574\uc81c \ub420 \ub54c \uae4c\uc9c0 \uc870\ud68c\ub97c \uc81c\uc678\ud55c \ub300\ubd80\ubd84\uc758 \uba85\ub839\uc774 \ub300\uae30 \uc0c1\ud0dc\uac00 \ub41c\ub2e4. \\n\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc874\uc7ac\ud558\ub294 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub300\ud574 \uc77c\uad00\ub41c \ubc31\uc5c5\uc744 \ubc1b\uc544\uc57c\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4. \\nInnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c\ub294 \ubc31\uc5c5 \uc2dc \uc870\uae08 \ub354 \uac00\ubcbc\uc6b4 \ubc31\uc5c5 \ub77d\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. \\n\\n```sql\\n-- GLOBAL LOCK\\nFLUSH TABLES WITH READ LOCK;\\n-- UNLOCK\\nUNLOCK TABLES;\\n\\n-- BACKUP LOCK\\nLOCK INSTANCE FOR BACKUP;\\n-- UNLOCK\\nUNLOCK INSTANCE;\\n```\\n\\n:::note MyISAM\\n\\nMySQL 5.5 \ubc84\uc804 \uc774\uc804\uc758 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uace0, SELECT \uc791\uc5c5 \uc18d\ub3c4\uac00 \ube60\ub974\ub2e4.\\n\\n:::\\n\\n### \ud14c\uc774\ube14 \ub77d(Table lock)\\n\\n\uac1c\ubcc4 \ud14c\uc774\ube14 \ub2e8\uc704\ub85c \uc124\uc815\ub418\ub294 \uc7a0\uae08\uc774\ub2e4. \\n\uba85\uc2dc\uc801 \ub610\ub294 \ubb35\uc2dc\uc801\uc73c\ub85c \ud2b9\uc815 \ud14c\uc774\ube14\uc758 \ub77d\uc744 \ud68d\ub4dd\ud560 \uc218 \uc788\ub2e4. \\n\ubb35\uc2dc\uc801 \ub77d\uc740 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub294 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uba74 \ubc1c\uc0dd\ud55c\ub2e4. \\nInnoDB \ud14c\uc774\ube14\uc5d0\ub294 DML \ucffc\ub9ac\ub294 \ubb34\uc2dc\ub418\uace0 DDL \uc77c \uacbd\uc6b0\uc5d0\ub9cc \ubb35\uc2dc\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud55c\ub2e4.\\n\\n```sql\\n-- TABLE LOCK\\nLOCK TABLES table_name [ READ | WRITE ]\\n\\n-- UNLOCK\\nUNLOCK TABLES;\\n```\\n\\n### \ub124\uc784\ub4dc \ub77d(Named lock)\\n\\n\uc784\uc758\uc758 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \uc124\uc815\ud560 \uc218 \uc788\ub294 \uc7a0\uae08\uc73c\ub85c \uc720\uc800 \ub808\ubca8 \ub77d\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4. \\n\uc5ec\ub7ec \uc2a4\ub808\ub4dc\ub098 \ud504\ub85c\uc138\uc2a4\uac00 \ub3d9\uc77c\ud55c \ub370\uc774\ud130\ub97c \uc218\uc815\ud558\ub824\ub294 \uacbd\uc6b0, \ub3d9\uc2dc\uc5d0 \uc218\uc815\ud558\uc9c0 \ubabb\ud558\ub3c4\ub85d \ubcf4\ud638\ud560 \uc218 \uc788\ub2e4. \\n\\n```sql\\n-- aGVyYg== \ub77c\ub294 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08 \ud68d\ub4dd, \uc774\ubbf8 \uc7a0\uae08\uc744 \uc0ac\uc6a9\uc911\uc778 \uacbd\uc6b0 1\ucd08 \ub3d9\uc548\ub9cc \ub300\uae30\\nSELECT GET_LOCK(\'aGVyYg==\', 1);\\n\\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc774 \uc124\uc815\ub418\uc5b4 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.\\nSELECT IS_FREE_LOCK(\'aGVyYg==\');\\n\\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4.\\nSELECT RELEASE_LOCK(\'aGVyYg==\');\\n\\n-- \uc704 3\uac1c \ud568\uc218 \ubaa8\ub450 \uc815\uc0c1\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud558\uac70\ub098 \ud574\uc81c\ud55c \uacbd\uc6b0\uc5d0 1\uc744, \uc544\ub2c8\uba74 0\uc744 \ubc18\ud658\ud55c\ub2e4.\\n\\n-- \ubaa8\ub4e0 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4. \ud574\uc81c\ub41c \uc7a0\uae08\uc758 \uac1c\uc218\ub97c \ubc18\ud658\ud55c\ub2e4.\\nSELECT RELEASE_ALL_LOCKS();\\n```\\n\\n### \uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)\\n\\n\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac1d\uccb4\uc758 \uc774\ub984\uc774\ub098 \uad6c\uc870\ub97c \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \ud68d\ub4dd\ud558\ub294 \uc7a0\uae08\uc774\ub2e4. \\n\uba85\uc2dc\uc801\uc73c\ub85c \ud68d\ub4dd \ub610\ub294 \ud574\uc81c \ud560 \uc218 \uc5c6\uc9c0\ub9cc \ud14c\uc774\ube14\uc758 \uc774\ub984\uc744 \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4. \\n\ubcf4\ud1b5 \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc2e4\uc2dc\uac04\uc73c\ub85c \ud14c\uc774\ube14\uc744 \ubc14\uafd4\uc57c\ud558\ub294 \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\ub41c\ub2e4.\\n\\n```sql\\n-- \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \ubcc4\ub3c4\uc758 \uc784\uc2dc \ud14c\uc774\ube14\uc5d0 \uc11c\ube44\uc2a4\uc6a9 \ub7ad\ud0b9 \ub370\uc774\ud130 \uc0dd\uc131 \ud6c4 \uae30\uc874 \ud14c\uc774\ube14\uc744 \ubc31\uc5c5\ud558\ub294 \uacbd\uc6b0\\n-- \uc544\ub798 \uad6c\ubb38 \uc2e4\ud589 \uc2dc \uba54\ud0c0\ub370\uc774\ud130 \ub77d\uc744 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.\\nRENAME TABLE rank TO rank_backup, rank_new TO rank;\\n```\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\nReal My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1 \\n[MySQL\uc758 User Level Lock\ub97c \ud65c\uc6a9\ud55c\ub2e4\uba74?, gywndi](https://gywn.net/2013/12/mysql-user-level-lock/) \\n[Locking Functions, MySQL 5.7 Reference](https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html#function_release-all-locks) \\n[Locking Functions, MySQL 8.0 Reference](https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_release-all-locks)"},{"id":"transaction-and-isolation","metadata":{"permalink":"/transaction-and-isolation","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx","source":"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx","title":"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900","description":"\ud2b8\ub79c\uc7ad\uc158(Transaction)","date":"2023-04-05T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 5\uc77c","tags":[{"label":"DataBase","permalink":"/tags/data-base"},{"label":"Transaction","permalink":"/tags/transaction"},{"label":"Isolation","permalink":"/tags/isolation"}],"readingTime":9.57,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900","slug":"transaction-and-isolation","tags":["DataBase","Transaction","Isolation"]},"unlisted":false,"prevItem":{"title":"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08","permalink":"/mysql-lock"},"nextItem":{"title":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed","permalink":"/test-double"}},"content":"## \ud2b8\ub79c\uc7ad\uc158(Transaction)\\n\\n\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \ub17c\ub9ac\uc801 \uae30\ub2a5\uc744 \uc218\ud589\ud558\uae30 \uc704\ud55c \uc791\uc5c5\uc758 \ub2e8\uc704\ub97c \ub9d0\ud55c\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158\uc740 \uc791\uc5c5\uc758 \uc644\uc804\uc131\uacfc \ub370\uc774\ud130\uc758 \uc815\ud569\uc131\uc744 \ubcf4\uc7a5\ud574 \uc900\ub2e4. \\n\ub17c\ub9ac\uc801\uc778 \uc791\uc5c5 \uc14b\uc744 \uc644\ubcbd\ud558\uac8c \ucc98\ub9ac\ud558\uac70\ub098, \uc624\ub958 \uc2dc \uc791\uc5c5\uc758 \uc77c\ubd80\ub9cc \uc801\uc6a9\ub418\ub294 \ud604\uc0c1\uc744 \ub9c9\uc544\uc900\ub2e4. \\n\\n### \ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)\\n\\n\uc6d0\uc790\uc131(Atomicity): \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \uc2e4\ud589\ub41c \uc791\uc5c5\ub4e4\uc740 \ubaa8\ub450 \uc131\uacf5\ud558\uac70\ub098, \uc2e4\ud328\ud574\uc57c \ud55c\ub2e4. \\n\uc77c\uad00\uc131(Consistency): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc218\ud589\ub418\uae30 \uc804\uacfc \ud6c4\uc5d0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc77c\uad00\ub41c \uc0c1\ud0dc\ub97c \uc720\uc9c0\ud574\uc57c \ud55c\ub2e4. \\n\uaca9\ub9ac\uc131(Isolation): \uac01\uac01\uc758 \ud2b8\ub79c\uc7ad\uc158\uc740 \ub3c5\ub9bd\uc801\uc774\ub77c \uc11c\ub85c\uc5d0\uac8c \uc601\ud5a5\uc744 \uc8fc\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4. \\n\uc9c0\uc18d\uc131(Durability): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc131\uacf5\uc801\uc73c\ub85c \uc644\ub8cc\ub41c\ub2e4\uba74 \uc601\uad6c\uc801\uc73c\ub85c \uacb0\uacfc\uc5d0 \ubc18\uc601\ub418\uc5b4\uc57c \ud55c\ub2e4. \\n\\n### \ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc740 \uaf2d \ud544\uc694\ud55c \ucd5c\uc18c\uc758 \ucf54\ub4dc\uc5d0\ub9cc \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.(\ud2b8\ub79c\uc7ad\uc158\uc758 \ubc94\uc704\ub97c \ucd5c\uc18c\ud654\ud558\ub77c) \\n\uad6c\ud604\ud574\uc57c \ud558\ub294 \uc5c5\ubb34\uc5d0 \ub530\ub77c \ud2b8\ub79c\uc7ad\uc158\uc744 \ubb36\uac70\ub098 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uace0, \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\ub294 \uacbd\uc6b0 \ubc18\ub4dc\uc2dc \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4. \\n\\n:::info \uc65c \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\uc744 \ub54c \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud560\uae4c? \ud83e\udd14\\n\\n\ub370\uc774\ud130\uc758 \uc77c\uad00\uc131\uacfc \uc548\uc804\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4. \\n\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc744 \ud2b8\ub79c\uc7ad\uc158 \ub0b4\ubd80\uc5d0 \ud3ec\ud568\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. \\n- \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc911\uac04\uc5d0 \uc2e4\ud328\ud560 \uac00\ub2a5\uc131(\uc548\uc804\uc131 X)\\n- \ud1b5\uc2e0\uc73c\ub85c \uc778\ud574 \ub370\uc774\ud130\uac00 \ubcc0\uacbd\ub420 \uc218 \uc788\ub294 \ubd80\ubd84(\uc77c\uad00\uc131 X)\\n\\n:::\\n\\n## \uaca9\ub9ac \uc218\uc900(Isolation level)\\n\\n\uc5ec\ub7ec \ud2b8\ub79c\uc7ad\uc158\uc774 \ub3d9\uc2dc\uc5d0 \ucc98\ub9ac\ub420 \ub54c \ud2b9\uc815 \ud2b8\ub79c\uc7ad\uc158\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\uc758 \uc870\ud68c \ubc0f \ubcc0\uacbd\uc744 \ud5c8\uc6a9\ud560\uc9c0 \uacb0\uc815\ud558\ub294 \uac83\uc744 \ub9d0\ud55c\ub2e4. \\n\uaca9\ub9ac \uc218\uc900\uc774 \ub192\uc544\uc9c8 \uc218\ub85d \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\uc774 \ub5a8\uc5b4\uc9c0\ub294 \uac83\uc774 \uc77c\ubc18\uc801\uc774\uc9c0\ub9cc, `SERIALIZABLE`\uc774 \uc544\ub2c8\ub77c\uba74 \ud06c\uac8c \uc131\ub2a5\uc758 \uc800\ud558\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4. \\n\\n### READ UNCOMMITTED\\n\\n\uac01 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\uc758 \ubcc0\uacbd \ub0b4\uc6a9\uc774 `COMMIT`\uc774\ub098 `ROLLBACK` \uc5ec\ubd80\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcf4\uc778\ub2e4. \\n\ub354\ud2f0 \ub9ac\ub4dc \ud604\uc0c1\uc774 \ubc1c\uc0dd\ud558\uae30 \ub54c\ubb38\uc5d0 \uc815\ud569\uc131\uc758 \ubb38\uc81c\uac00 \ub9ce\uc740 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4. \\nMySQL \uc0ac\uc6a9\uc2dc \ucd5c\uc18c `READ COMMITTED` \uc774\uc0c1\uc758 \uaca9\ub9ac \uc218\uc900 \uc0ac\uc6a9\uc744 \uad8c\uc7a5\ud55c\ub2e4. \\n\\n```mermaid\\n---\\ntitle: READ UNCOMMITTED\\n---\\nsequenceDiagram\\n Alice->>Database: BEGIN\\n Alice->>Database: INSERT(Alice)\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice\\n Alice->>Database: COMMIT(Alice)\\n```\\n\\n### READ COMMITTED\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 `COMMIT`\uc774 \uc644\ub8cc\ub41c \ub370\uc774\ud130\ub9cc \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc870\ud68c\ud560 \uc218 \uc788\ub2e4. \\n\uc624\ub77c\ud074 DBMS\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4. \\n`REPEATABLE READ`\uac00 \ubcf4\uc7a5\ub418\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 `NON-REPEATABLE READ` \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\\n```mermaid\\n---\\ntitle: READ COMMITTED\\n---\\nsequenceDiagram\\n Alice->>Database: BEGIN\\n Alice->>Database: UPDATE(Alice to Bob)\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice(Undo log)\\n Alice->>Database: COMMIT\\n```\\n\\n### REPEATABLE READ\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc774 \uc2dc\uc791\ub418\uae30 \uc804\uc5d0 `COMMIT`\uc774 \uc644\ub8cc\ub41c \ub0b4\uc6a9\uc5d0 \ub300\ud574\uc11c\ub9cc \uc870\ud68c\ud560 \uc218 \uc788\ub2e4. \\nMySQL\uc758 InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4. \\nMVCC\ub97c \uc774\uc6a9\ud574 \uc5b8\ub450(Undo) \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \uc774\uc804 \ub370\uc774\ud130\ub97c \uc774\uc6a9\ud574 \ub3d9\uc77c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c\ub294 \ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc5ec\uc904 \uc218 \uc788\uac8c \ubcf4\uc7a5\ud55c\ub2e4. \\n\ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc7a5\ud558\ub294 \ubc29\ubc95\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n - \ubaa8\ub4e0 InnoDB \ud2b8\ub79c\uc7ad\uc158\uc740 \uc21c\ucc28\uc801\uc73c\ub85c \uc99d\uac00\ud558\ub294 \uace0\uc720\ud55c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ub97c \uac00\uc9c4\ub2e4.\\n - Undo \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \ub808\ucf54\ub4dc\uc5d0\ub294 \ubcc0\uacbd\uc744 \ubc1c\uc0dd\uc2dc\ud0a8 \ud2b8\ub79c\uc7ad\uc158\uc758 \ubc88\ud638\uac00 \ud3ec\ud568\ub418\uc5b4\uc788\ub2e4.\\n - Undo \uc601\uc5ed\uc758 \ubc31\uc5c5\ub41c \ub370\uc774\ud130\ub294 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774 \ubd88\ud544\uc694\ud558\ub2e4\uace0 \ud310\ub2e8\ud558\ub294 \uacbd\uc6b0 \uc0ad\uc81c\ub41c\ub2e4.\\n - `REPEATABLE READ` \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c\ub294 MVCC\ub97c \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \uac00\uc7a5 \uc624\ub798\ub41c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ubcf4\ub2e4 \uc55e\uc120 Undo \uc601\uc5ed\uc758 \ub370\uc774\ud130\ub294 \uc0ad\uc81c\ud558\uc9c0 \uc54a\ub294\ub2e4. \\n\\nInnoDB\uc5d0\uc11c\ub294 \uac2d \ub77d\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc744 \uc774\uc6a9\ud558\uc5ec \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc744 \ubc29\uc9c0\ud55c\ub2e4. \\n\\n```mermaid\\n---\\ntitle: REPEATABLE READ\\n---\\nsequenceDiagram\\n participant Alice\\n participant Database\\n participant Bob\\n Bob->>Database: BEGIN(TRX-ID: 1)\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice\\n Alice->>Database: BEGIN(TRX-ID: 2)\\n Alice->>Database: UPDATE(Alice to Bob)\\n Alice->>Database: COMMIT\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice(Undo log)\\n```\\n\\n:::note \uac2d \ub78d(Gap lock)\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d(Next-key lock)\\n\\n\uac2d \ub77d: \ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4. \\n\ub125\uc2a4\ud2b8 \ud0a4 \ub77d: \ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4.\\n\\n:::\\n\\n:::note MVCC(Multi Version Concurrency Control)\\n\\n\ub3d9\uc2dc\uc131\uc744 \uc81c\uc5b4\ud558\ub294 \ubc29\ubc95 \uc911 \ud558\ub098\ub85c \ud558\ub098\uc758 \ub808\ucf54\ub4dc\uc5d0 \ub300\ud574 \uc5ec\ub7ec \uac1c\uc758 \ubc84\uc804\uc774 \ub3d9\uc2dc\uc5d0 \uad00\ub9ac\ub418\ub294 \uac83\uc774\ub2e4.\\n - PostgreSQL\uc740 \ub2e4\uc911 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\ub294 \uac83\uc73c\ub85c MVCC\ub97c \uad6c\ud604\ud55c\ub2e4.\\n - Oracle, InnoDB\ub294 `Undo log`\ub97c \uc774\uc6a9\ud574 \uc774 \uae30\ub2a5\uc744 \uad6c\ud604\ud55c\ub2e4.(\ucd5c\uc2e0 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub9cc DB\uc5d0 \uc800\uc7a5)\\n\\n\uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uc77d\uad00\ub41c \uc77d\uae30\ub97c \uc81c\uacf5\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4.\\n\\n:::\\n\\n### SERIALIZABLE\\n\\n\ud2b8\ub79c\uc7ad\uc158\uc744 \uc21c\ucc28\uc801\uc73c\ub85c \uc9c4\ud589\uc2dc\ud0a4\ub294 \uaca9\ub9ac \uc218\uc900\uc774\uace0 \ub530\ub77c\uc11c \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\ub3c4 \ub2e4\ub978 \uaca9\ub9ac \uc218\uc900\ubcf4\ub2e4 \ub5a8\uc5b4\uc9c4\ub2e4. \\n\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uace0 \uc4f0\ub294 \ub808\ucf54\ub4dc\ub97c \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\ub294 \uc811\uadfc\ud560 \uc218 \uc5c6\uace0 \ub2e8\uc21c\ud55c \uc77d\uae30 \uc791\uc5c5\ub3c4 \uacf5\uc720 \uc7a0\uae08(\uc77d\uae30 \uc7a0\uae08)\uc744 \ud68d\ub4dd\ud574\uc57c\ub9cc \ud55c\ub2e4. \\nInnoDB\uc5d0\uc11c\ub294 \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc774 `REPEATABLE READ` \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ubc1c\uc0dd\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uad73\uc774 \uc0ac\uc6a9\ud560 \ud544\uc694\ub294 \uc5c6\ub2e4. \\n\\n## \uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c\\n\\n\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ub354\ud2f0 \ub9ac\ub4dc, \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c, \ud32c\ud140 \ub9ac\ub4dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\\n| \uaca9\ub9ac \uc218\uc900 / \ubd80\uc815\ud569 \ubb38\uc81c | \ub354\ud2f0 \ub9ac\ub4dc | \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c | \ud32c\ud140 \ub9ac\ub4dc |\\n| --- | --- | --- | --- |\\n| READ UNCOMMITTED | O | O | O |\\n| READ COMMITTED | X | O | O |\\n| REPEATABLE READ | X | X | O(InnoDB\ub294 X) |\\n| SERIALIZABLE | X | X | X |\\n\\n### \ub354\ud2f0 \ub9ac\ub4dc(Dirty read)\\n\\n\uc5b4\ub5a4 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ucc98\ub9ac\ud55c \uc791\uc5c5\uc774 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc558\uc5b4\ub3c4 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcfc \uc218 \uc788\ub294 \ud604\uc0c1 \\n\ud2b8\ub79c\uc7ad\uc158 \uaca9\ub9ac \uc218\uc900\uc774 READ UNCOMMITTED\uc77c \ub54c \ubc1c\uc0dd\ud55c\ub2e4. \\n\uc608) B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uace0 \ucee4\ubc0b\uc744 \ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, A\uac00 \ud574\ub2f9 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud560 \uc218 \uc788\ub294 \uacbd\uc6b0\\n\\n### \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)\\n\\n\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc758 \uac19\uc740 \ud589\uc5d0 \ub450 \ubc88 \uc774\uc0c1 \uc870\ud68c\uac00 \ubc1c\uc0dd\ud588\ub294\ub370, \uadf8 \uac12\uc774 \ub2e4\ub978 \ud604\uc0c1 \\n\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc5ec\ub7ec \ubc88 \uc870\ud68c\ud558\ub358 \uc911 B\uac00 \ub808\ucf54\ub4dc\ub97c \ubcc0\uacbd\ud558\uc5ec A\uac00 \uc870\ud68c\ud55c \uac12\uc774 \ub2ec\ub77c\uc9c0\ub294 \uacbd\uc6b0 \\n\\n```mermaid\\n---\\ntitle: NON REPEATABLE READ\\n---\\nsequenceDiagram\\n participant Alice\\n participant Database\\n participant Bob\\n Bob->>Database: BEGIN\\n Bob->>Database: SELECT\\n Database->>+Bob: Alice\\n Alice->>Database: BEGIN\\n Alice->>Database: UPDATE(Alice to Bob)\\n Alice->>Database: COMMIT\\n Bob->>Database: SELECT\\n Database->>+Bob: Bob\\n```\\n\\n### \ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)\\n\\n\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ucffc\ub9ac \uc218\ud589\uc2dc, \uc218\ud589 \uacb0\uacfc\uac00 \ub2e4\ub978 \ud604\uc0c1 \\n\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud558\uace0 B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uc5ec A\uac00 \ub2e4\uc2dc \uc870\ud68c\ud560 \ub54c \uc874\uc7ac\ud558\uc9c0 \uc54a\uc740 \ub808\ucf54\ub4dc\uac00 \uc870\ud68c\ub418\ub294 \uacbd\uc6b0 \\n\\n```mermaid\\n---\\ntitle: PHANTOM READ\\n---\\nsequenceDiagram\\n participant Alice\\n participant Database\\n participant Bob\\n Bob->>Database: BEGIN(TRX-ID: 1)\\n Bob->>Database: SELECT COUNT\\n Database->>+Bob: 1\\n Alice->>Database: BEGIN(TRX-ID: 2)\\n Alice->>Database: INSERT(Bob)\\n Alice->>Database: COMMIT\\n Bob->>Database: SELECT COUNT\\n Database->>+Bob: 2\\n```\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\nReal My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1 \\n[Isolation Level, MySQL](https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html)"},{"id":"test-double","metadata":{"permalink":"/test-double","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx","source":"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx","title":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed","description":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?","date":"2023-04-04T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 4\uc77c","tags":[{"label":"Test","permalink":"/tags/test"},{"label":"Mock","permalink":"/tags/mock"}],"readingTime":4.52,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed","slug":"test-double","tags":["Test","Mock"]},"unlisted":false,"prevItem":{"title":"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900","permalink":"/transaction-and-isolation"},"nextItem":{"title":"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870","permalink":"/java-class-file"}},"content":"### \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?\\n\\n\ubaa8\ub4e0 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \uac00\uc9dc \uc758\uc874\uc131\uc744 \uc758\ubbf8\ud558\uace0, \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud589\ub420 \ub54c \ub2e4\ub978 \uac1d\uccb4\ub97c \ub300\uc2e0\ud55c\ub2e4. \\nGerard Meszaros\uc758 xUnit Test Patterns\ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ub2e4\uc12f \uac00\uc9c0(\ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774, \ubaa9, \ud398\uc774\ud06c)\ub85c \uad6c\ubd84\ud55c\ub2e4.\\n\\n\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \uae30\ubcf8 \uba54\ucee4\ub2c8\uc998\uc740 \ub2e4\ud615\uc131\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774\ub2e4. \\n\uc678\ubd80 \uc11c\ube44\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uacbd\uc6b0, \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc815\uc758\ud558\uace0 \uc678\ubd80 \uc11c\ube44\uc2a4 \ub300\uc2e0 \ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\uc758 \uad6c\ud604\uccb4\ub97c \uc0dd\uc131\ud558\ub294 \uac83\uc774\ub2e4.\\n\\n**\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \ud0c0\uc785 \uacc4\uce35 \uad6c\uc870**\\n\\n```mermaid\\nflowchart LR\\n Mock --\x3e Spy --\x3e Stub --\x3e Dummy --\x3e TestDouble\\n Fake --\x3e TestDouble\\n```\\n\\n### \ub354\ubbf8(Dummy)\\n\\n\uac00\uc7a5 \ub2e8\uc21c\ud558\uace0, \uc6d0\uc2dc\uc801\uc778 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub2e4. \\n\uae30\ubcf8\uc801\uc73c\ub85c \uc544\ubb34 \uc77c\ub3c4 \ud558\uc9c0 \uc54a\ub294 \uad6c\ud604\uccb4\ub85c \uc778\uc2a4\ud134\uc2a4\ud654\uac00 \ud544\uc694\ud55c \uacbd\uc6b0 \uc0ac\uc6a9\ud55c\ub2e4. \\n\ub9cc\uc57d \uba54\uc11c\ub4dc\uac00 \ubb34\uc5b8\uac00 \ubc18\ud658\uc744 \ud574\uc57c\ud558\ub294 \uacbd\uc6b0 0, null\uacfc \uac19\uc740 \uac12\uc744 \ubc18\ud658\ud55c\ub2e4. \\n\\n### \uc2a4\ud141(Stub)\\n\\n\uc2dc\ub098\ub9ac\uc624\ub9c8\ub2e4 \ub2e4\ub978 \uac12(\ubbf8\ub9ac \uc900\ube44 \ub41c \uacb0\uacfc)\uc744 \ubc18\ud658\ud55c\ub2e4. \\n\uc774\ub97c \ud1b5\ud574 \ud2b9\uc815 \uc870\uac74\uc5d0\uc11c \uba54\uc11c\ub4dc\uac00 \uc608\uc0c1\ud55c\ub300\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. \\n\\n### \uc2a4\ud30c\uc774(Spy)\\n\\n\uc2a4\ud141\uacfc \uc720\uc0ac\ud558\uc9c0\ub9cc \ud638\ucd9c \uc5ec\ubd80\ub97c \uae30\ub85d\ud558\uac70\ub098 \ud638\ucd9c\ud560 \ub54c \uc804\ub2ec\ud55c \uc778\uc790\uac12\uc744 \uae30\ub85d\ud560 \uc218 \uc788\ub2e4. \\n\uc608) \uba54\uc77c \uc804\uc1a1 \uae30\ub2a5\uc744 \uac00\uc9c4 \uac1d\uccb4\ub97c \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc73c\ub85c \uad6c\ud604\ud588\uc744 \ub54c \uba54\uc77c \uc804\uc1a1 \ud69f\uc218\ub97c \uae30\ub85d\ud55c\ub2e4. \\n\\n### \ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)\\n\\n\ubaa9\uc740 \ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774\ub97c \ud3ec\ud568\ud55c\ub2e4. \\n\ud638\ucd9c \uc2dc \uc0ac\uc804\uc5d0 \uc815\uc758\ub41c \uacb0\uacfc\ub97c \ubc18\ud658\ud558\uace0, \uc608\uc0c1\uce58 \ubabb\ud55c \ud638\ucd9c\uc774 \uc788\uc744 \uacbd\uc6b0 \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4. \\n\ub610\ud55c \ud638\ucd9c\uc5d0 \ub300\ud55c \uac80\uc99d\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\\n### \uac00\uc9dc(Fake)\\n\\nDOC\uc640 \ub3d9\uc77c\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\uc9c0\ub9cc, \ub354\uc6b1 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ub41c \uac83\uc774\ub2e4. \\n\uc608) \uc2e4\uc81c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc720\uc0ac\ud558\uac8c \ub3d9\uc791\ud558\ub294 \uac00\uc9dc \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\ub2e4. \\n\\n:::note DOC(depended-on component)\\n\\n\uc758\uc874 \uad6c\uc131 \uc694\uc18c, DOC\ub97c \ud14c\uc2a4\ud2b8 \ub354\ube14\ub85c \ub300\uccb4\ud560 \uc218 \uc788\ub2e4. \\n\ud14c\uc2a4\ud2b8 \ub354\ube14\uc740 DOC\uc640 \ub3d9\uc77c\ud55c API\ub97c \uc81c\uacf5\ud574\uc57c \ud55c\ub2e4. \\n\\n:::\\n\\n### \uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84\\n\\n\ub2e8\uc704 \ud14c\uc2a4\ud2b8 p.149 \uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ud06c\uac8c \ubaa9\uacfc \uc2a4\ud141\uc73c\ub85c \uad6c\ubd84\ud55c\ub2e4. \\n\ubaa9\uc740 SUT\uc640 \uad00\ub828\ub41c \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ubc18\uba74, \uc2a4\ud141\uc740 \ub2e8\uc21c \ubaa8\ubc29\ub9cc \ud55c\ub2e4. \\n\\n| TestDouble | Mock | Stub |\\n| --- | --- | --- |\\n| \ud3ec\ud568 \uc720\ud615 | \ubaa9, \uc2a4\ud30c\uc774 | \uc2a4\ud141, \ub354\ubbf8, \ud398\uc774\ud06c |\\n| \uc6a9\ub3c4 | \uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ub370 \uc0ac\uc6a9 | \ub0b4\ubd80\ub85c \ub4e4\uc5b4\uc624\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\ub294 \ub370 \uc0ac\uc6a9 |\\n| \uc124\uba85 | SUT\uac00 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9 | SUT\uac00 \uc785\ub825 \ub370\uc774\ud130\ub97c \uc5bb\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9\\n| \uc608\uc2dc | \uc774\uba54\uc77c \ubc1c\uc1a1 | \ub370\uc774\ud130 \uac80\uc0c9 |\\n\\n:::note SUT(system under test)\\n\\n\ud14c\uc2a4\ud2b8 \ub300\uc0c1 \uc2dc\uc2a4\ud15c \\n\ud14c\uc2a4\ud2b8\ub97c \ud558\ub824\ub294 \ub300\uc0c1\\n\\n:::\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30 - 3\uc7a5 \uace0\uae09 \ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4 \\n\ub2e8\uc704 \ud14c\uc2a4\ud2b8 - 5\uc7a5 \ubaa9\uacfc \ud14c\uc2a4\ud2b8 \ucde8\uc57d\uc131, \ube14\ub77c\ub514\ubbf8\ub974 \ucf54\ub9ac\ucf54\ud504 \\n\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uc2dc\uc791\ud558\uae30 - 7\uc7a5 \ub300\uc5ed, \ucd5c\ubc94\uade0 \\n[\ud14c\uc2a4\ud2b8 \ub354\ube14, Martin Fowler](https://www.martinfowler.com/bliki/TestDouble.html) \\n[\ud14c\uc2a4\ud2b8 \uad00\ub828 \uc6a9\uc5b4 \uc815\ub9ac, Johngrib](https://johngrib.github.io/wiki/test-terms/) \\n[Test Double, Gerard Meszaros](http://xunitpatterns.com/Test%20Double.html)"},{"id":"java-class-file","metadata":{"permalink":"/java-class-file","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx","source":"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx","title":"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870","description":"\ud074\ub798\uc2a4 \ud30c\uc77c","date":"2023-04-03T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 3\uc77c","tags":[{"label":"Java","permalink":"/tags/java"},{"label":"Class","permalink":"/tags/class"}],"readingTime":5.63,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870","slug":"java-class-file","tags":["Java","Class"]},"unlisted":false,"prevItem":{"title":"\ud14c\uc2a4\ud2b8 \ub300\uc5ed","permalink":"/test-double"},"nextItem":{"title":"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30","permalink":"/custom-jdbc-template"}},"content":"### \ud074\ub798\uc2a4 \ud30c\uc77c\\n\\n\uc790\ubc14 \uc18c\uc2a4\ucf54\ub4dc\uac00 \uc2e4\ud589\uc774 \ub418\ub824\uba74 \uc790\ubc14 \ucef4\ud30c\uc77c\ub7ec(javac)\ub97c \ud1b5\ud574 \uc18c\uc2a4\ucf54\ub4dc\ub97c \ud074\ub798\uc2a4\ud30c\uc77c\ub85c \ubcc0\ud658\ud574\uc57c \ud55c\ub2e4. \\n\ucef4\ud30c\uc77c\ub41c \ud074\ub798\uc2a4\ud30c\uc77c\uc740 \uc5b4\ub5a4 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\uc744\uae4c?\\n\\n### \ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd\\n\\n8\ube44\ud2b8 \ubc14\uc774\ud2b8\uc758 \uc2a4\ud2b8\ub9bc\uc73c\ub85c \uad6c\uc131\ub41c\ub2e4. \\n16\ube44\ud2b8 \ubc0f 32\ube44\ud2b8\uc758 \ub370\uc774\ud130\ub294 \uac01\uac01 2\uac1c, 4\uac1c\uc758 \uc5f0\uc18d\ub41c 8\ube44\ud2b8\ub97c \uc77d\uc5b4\uc11c \uad6c\uc131\ub41c\ub2e4. \\n\uba40\ud2f0\ubc14\uc774\ud2b8\uc758 \uacbd\uc6b0 \ud56d\uc0c1 big endian \uc21c\uc11c\ub85c \uc800\uc7a5\ub41c\ub2e4. \\n\\nu1 \u2192 unsigned 1byte \\nu2 \u2192 unsigned 2byte \\nu4 \u2192 unsigned 4byte \\n\\n### \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870\\n\\n```\\nClassFile {\\n u4 magic;\\n u2 minor_version;\\n u2 major_version;\\n u2 constant_pool_count;\\n cp_info constant_pool[constant_pool_count-1];\\n u2 access_flags;\\n u2 this_class;\\n u2 super_class;\\n u2 interfaces_count;\\n u2 interfaces[interfaces_count];\\n u2 fields_count;\\n field_info fields[fields_count];\\n u2 methods_count;\\n method_info methods[methods_count];\\n u2 attributes_count;\\n attribute_info attributes[attributes_count];\\n}\\n```\\n\\n### \ub9e4\uc9c1\ub118\ubc84\\n\\n\ubaa8\ub4e0 \ud074\ub798\uc2a4 \ud30c\uc77c\uc740 0xCAFEBABE\ub77c\ub294 \ub9e4\uc9c1\ub118\ubc84\ub85c \uc2dc\uc791\ud55c\ub2e4. \\n\ubcf4\ud1b5 \ub9e4\uc9c1\ub118\ubc84\ub294 \ud30c\uc77c \uc885\ub958\ub97c \uc2dd\ubcc4\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9\ub41c\ub2e4. \\n\\n### \ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804\\n\\n\ud074\ub798\uc2a4 \ud30c\uc77c \ubc84\uc804 \uac12\uc740 \ud074\ub798\uc2a4\ub85c\ub354\uc758 \ud638\ud658\uc131 \ubcf4\uc7a5\uc744 \uc704\ud574 \uaf2d \ud544\uc694\ud55c \uac12\uc774\ub2e4. \\n- Java 17 \ubc84\uc804\uc73c\ub85c \ube4c\ub4dc\ud55c\ub2e4\uba74 class version 61 ex) 00 00 00 3D\\n\\n\ud638\ud658\ub418\uc9c0 \uc54a\ub294 \ubc84\uc804\uc758 \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \ub85c\ub529\ud558\ub824\uace0 \ud558\ub294 \uacbd\uc6b0 \ub7f0\ud0c0\uc784\uc5d0 `UnsupportedClassVersionError` \uc608\uc678\uac00 \ubc1c\uc0dd\ud55c\ub2e4. \\n\\n**class\xa0file format major versions**\\n\\n| Java SE | Released | Major | Supported majors |\\n| --- | --- | --- | --- |\\n| 8 | March 2014 | 52 | 45 .. 52 |\\n| 9 | September 2017 | 53 | 45 .. 53 |\\n| 10 | March 2018 | 54 | 45 .. 54 |\\n| 11 | September 2018 | 55 | 45 .. 55 |\\n| 12 | March 2019 | 56 | 45 .. 56 |\\n| 13 | September 2019 | 57 | 45 .. 57 |\\n| 14 | March 2020 | 58 | 45 .. 58 |\\n| 15 | September 2020 | 59 | 45 .. 59 |\\n| 16 | March 2021 | 60 | 45 .. 60 |\\n| 17 | September 2021 | 61 | 45 .. 61 |\\n\\n### \uc0c1\uc218 \ud480\\n\\n2\ubc14\uc774\ud2b8\uc758 \uc0c1\uc218\uc758 \uac1c\uc218\uac12\uc774 \uba3c\uc800\uc624\uace0 \uadf8 \ub4a4\ub85c \ucf54\ub4dc\uc5d0 \ub4f1\uc7a5\ud558\ub294 \uc0c1\uc218\uac12\uc774 \ubaa8\uc5ec\uc788\ub2e4. \\n\ud074\ub798\uc2a4\uba85, \uc0c1\uc218\uba85, \uc0c1\uc218 \uac12, \ud544\ub4dc\uba85, \uba54\uc11c\ub4dc\uba85\uacfc \uac19\uc740 \uac12\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4. \\nJVM\uc740 \ucf54\ub4dc \uc2e4\ud589 \uc2dc \ub7f0\ud0c0\uc784\uc5d0 \ubc30\uce58\ub41c \uba54\ubaa8\ub9ac\uac00 \uc544\ub2c8\ub77c, \ud574\ub2f9 \uc0c1\uc218 \ud480 \ud14c\uc774\ube14\uc744 \ucc3e\uc544\ubcf4\uace0 \ud544\uc694\ud55c \uac12\uc744 \ucc38\uc870\ud55c\ub2e4.\\n\\n### \uc561\uc138\uc2a4 \ud50c\ub798\uadf8\\n\\n\ud074\ub798\uc2a4, \uc778\ud130\ud398\uc774\uc2a4\uc640 \uac19\uc740 \ud30c\uc77c\uc758 \uc18d\uc131\uc744 \ud45c\uc2dc\ud55c\ub2e4. \\n\uc608\ub97c \ub4e4\uc5b4 public interface\ub85c \uc815\uc758\ub41c \uc778\ud130\ud398\uc774\uc2a4\uc758 \ud50c\ub798\uadf8\ub294 0x0601\uc774\ub2e4. \\n- \uacc4\uc0b0\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. `ACC_PUBLIC` xor `ACC_INTERFACE` xor `ACC_ABSTRACT`\\n\\n\uacf5\uc2dd\ubb38\uc11c\uc5d0 \ub4e4\uc5b4\uac00\uba74 \uac01 \ud50c\ub798\uadf8\uc5d0 \ub300\ud55c \uc124\uba85 + \ud50c\ub798\uadf8 \uc124\uc815\uc2dc \ub3d9\uc2dc\uc5d0 \uc124\uc815\ub418\uba74 \uc548\ub418\ub294 \ud50c\ub798\uadf8\uc640 \uac19\uc740 \uc124\uba85\uc774 \uc790\uc138\ud558\uac8c \ub098\uc640\uc788\ub2e4.\\n\\n**Class access and property modifiers**\\n\\n| Flag Name | Value | Interpretation |\\n| --- | --- | --- |\\n| ACC_PUBLIC | 0x0001 | Declared\xa0public; may be accessed from outside its package. |\\n| ACC_FINAL | 0x0010 | Declared\xa0final; no subclasses allowed. |\\n| ACC_SUPER | 0x0020 | Treat superclass methods specially when invoked by the\xa0invokespecial\xa0instruction. |\\n| ACC_INTERFACE | 0x0200 | Is an interface, not a class. |\\n| ACC_ABSTRACT | 0x0400 | Declared\xa0abstract; must not be instantiated. |\\n| ACC_SYNTHETIC | 0x1000 | Declared synthetic; not present in the source code. |\\n| ACC_ANNOTATION | 0x2000 | Declared as an annotation type. |\\n| ACC_ENUM | 0x4000 | Declared as an\xa0enum\xa0type. |\\n| ACC_MODULE | 0x8000 | Is a module, not a class or interface. |\\n\\n### this_class\\n\\n\ud074\ub798\uc2a4\uba85\uacfc \uac19\uc740 \uc774\ub984\uc744 \ud45c\ud604\ud558\ub294 \uac12\uc73c\ub85c, \uc0c1\uc218 \ud480\uc5d0\uc11c \ud074\ub798\uc2a4\uba85\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4. \\n\ud574\ub2f9 \uc778\ub371\uc2a4\uc758 \ud56d\ubaa9\uc740 `CONSTANT_Class_infoclass` \ud615\uc2dd\uc758 \uac12\uc774\uc5b4\uc57c \ud55c\ub2e4. \\n\\n### super_class\\n\\n\uc0c1\uc218 \ud480\uc5d0\uc11c \uc288\ud37c \ud074\ub798\uc2a4\uc758 \uc774\ub984\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4. \\n\uc544\ubb34\uac83\ub3c4 \uc0c1\uc18d\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\uc758 \uacbd\uc6b0 `java.lang.Object`\uc758 \uc778\ub371\uc2a4 \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4.\\n\\n### interface, field, method\\n\\n\uac01\uac01\uc758 \uac1c\uc218\uc640, \uc815\ubcf4\uc5d0 \ub300\ud55c \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4. \\ninterface, field, method\ub97c \ud45c\uc2dc\ud558\ub294 \ubc29\ubc95\uc774 \uac01\uac01 \ub2e4\ub974\uace0, \uc811\uadfc\uc790\uc5d0 \ub300\ud55c \ud50c\ub798\uadf8\ub3c4 \uac01\uac01 \ub2e4\ub974\ub2e4.\\n\\n### attributes\\n\\n\ud574\ub2f9 \ud074\ub798\uc2a4 \ud30c\uc77c\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucd94\uac00 \uc815\ubcf4\uc758 \ubaa8\uc74c\uc774\ub2e4. \uc608) \uc18c\uc2a4\ud30c\uc77c\uba85 \\n\uc815\ud574\uc9c4 \ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \uad6c\uc870\ub97c \ud655\uc7a5\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. \\n\\n### \ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234\\n\\nIntelliJ plugin - BinEd \\nIntelliJ plugin - jclasslib Bytecode Viewer\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n2\uc7a5 JVM \uc774\uc57c\uae30, \uc790\ubc14 \ucd5c\uc801\ud654 \\n[Class file in Java, File Format](https://docs.fileformat.com/ko/programming/class/) \\n[java se11 Class \ud30c\uc77c \ud615\uc2dd, Oracle](https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html) \\n[java se17 Class \ud30c\uc77c \ud615\uc2dd, Oracle](https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html)"},{"id":"custom-jdbc-template","metadata":{"permalink":"/custom-jdbc-template","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx","source":"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx","title":"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30","description":"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.","date":"2023-04-02T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 2\uc77c","tags":[{"label":"JDBC","permalink":"/tags/jdbc"},{"label":"Java","permalink":"/tags/java"}],"readingTime":9.025,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30","slug":"custom-jdbc-template","tags":["JDBC","Java"]},"unlisted":false,"prevItem":{"title":"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870","permalink":"/java-class-file"},"nextItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0","permalink":"/woowacourse-level1-retrospective"}},"content":"import Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4. \\n\uc774 \ub54c JDBC\ub97c \uc0ac\uc6a9\ud560 \ub54c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 \ucee4\ub125\uc158\uc744 \uc5bb\uace0, try-with-resource\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc774 \ubc18\ubcf5\ub418\uc5c8\ub2e4. \\n\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc774\uc6a9\ud558\uc5ec \ub098\ub9cc\uc758 JdbcTemplate\uc744 \ub9cc\ub4e4\uc5b4\ubcf4\uc558\ub2e4. \\n\\n### \uae30\uc874 \ucf54\ub4dc\\n\\n<Tabs>\\n<TabItem value=\\"User\\" label=\\"User\\" default>\\n\\n```java\\npublic class User {\\n private final int id;\\n private final String name;\\n\\n public User(final int id, final String name) {\\n this.id = id;\\n this.name = name;\\n }\\n\\n public int getId() {\\n return id;\\n }\\n\\n public String getName() {\\n return name;\\n }\\n}\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"UserDao\\" label=\\"UserDao\\">\\n\\n```java\\npublic class UserDao {\\n private final ConnectionPool connectionPool;\\n\\n public UserDao(final ConnectionPool connectionPool) {\\n this.connectionPool = connectionPool;\\n }\\n\\n public void insert(final String name) {\\n final Connection connection = connectionPool.getConnection();\\n final String query = \\"INSERT INTO User (name) VALUES (?)\\";\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n preparedStatement.setString(1, name);\\n preparedStatement.executeUpdate();\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n\\n public void delete(final int userId) {\\n final Connection connection = connectionPool.getConnection();\\n final String query = \\"DELETE FROM user WHERE id = ?\\";\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n preparedStatement.setInt(1, userId);\\n preparedStatement.executeUpdate();\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n\\n public User findById(final int userId) {\\n final Connection connection = connectionPool.getConnection();\\n final String query = \\"SELECT * FROM user WHERE id = ?\\";\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n preparedStatement.setInt(1, userId);\\n final ResultSet resultSet = preparedStatement.executeQuery();\\n if (resultSet.next()) {\\n return new User(\\n resultSet.getInt(\\"id\\"),\\n resultSet.getString(\\"name\\")\\n );\\n }\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n return null;\\n }\\n\\n public List<User> findAll() {\\n final Connection connection = connectionPool.getConnection();\\n final String query = \\"SELECT * FROM user\\";\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n final ResultSet resultSet = preparedStatement.executeQuery();\\n final List<User> result = new ArrayList<>();\\n while (resultSet.next()) {\\n result.add(new User(\\n resultSet.getInt(\\"id\\"),\\n resultSet.getString(\\"name\\")\\n ));\\n }\\n return result;\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n}\\n```\\n\\n</TabItem>\\n\\n<TabItem value=\\"ConnectionPool\\" label=\\"ConnectionPool\\">\\n\\n```java\\npublic class ConnectionPool {\\n private static final String SERVER = \\"localhost:13306\\";\\n private static final String DATABASE = \\"chess\\";\\n private static final String OPTION = \\"?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true\\";\\n private static final String URL = \\"jdbc:mysql://\\" + SERVER + \\"/\\" + DATABASE + OPTION;\\n private static final String USERNAME = \\"root\\";\\n private static final String PASSWORD = \\"root\\";\\n\\n private final AtomicInteger index = new AtomicInteger();\\n private final List<Connection> connections;\\n\\n public ConnectionPool(final int connectionCount) {\\n connections = generateConnections(connectionCount);\\n }\\n\\n private List<Connection> generateConnections(final int connectionCount) {\\n return Stream.generate(this::generateConnection)\\n .limit(connectionCount)\\n .collect(toList());\\n }\\n\\n private Connection generateConnection() {\\n try {\\n return DriverManager.getConnection(URL, USERNAME, PASSWORD);\\n } catch (SQLException e) {\\n throw new IllegalStateException(\\"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.\\");\\n }\\n }\\n\\n public Connection getConnection() {\\n int currentIndex = index.getAndIncrement();\\n return connections.get(currentIndex % connections.size());\\n }\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n### SELECT, DELETE \uc911\ubcf5 \uc81c\uac70\\n\\n\ubcc0\ud558\uc9c0 \uc54a\ub294 \ubd80\ubd84: try-with-resource, preparedStatement\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84, executeUpdate\ub85c \uc2e4\ud589 \ub4f1\ub4f1 \\n\ubcc0\ud558\ub294 \ubd80\ubd84: SQL Query, \ub9e4\uac1c\ubcc0\uc218 \\n\\n\ub2e4\uc74c\uacfc \uac19\uc774 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\ub294 \ubd80\ubd84\uc744 \ubd84\ub9ac\ud558\uace0 \uac00\ubcc0\uc778\uc218\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 SELECT\uc640 DELETE\uc758 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. \\n\\n```java\\npublic void insert(final String name) {\\n final String query = \\"INSERT INTO User (name) VALUES (?)\\";\\n executeUpdate(query, name);\\n}\\n\\npublic void delete(final int userId) {\\n final String query = \\"DELETE FROM user WHERE user_id = ?\\";\\n executeUpdate(query, userId);\\n}\\n\\nprivate void executeUpdate(final String query, final Object... parameters) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n preparedStatement.executeUpdate();\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n}\\n```\\n\\n### \uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758\\n\\n\uc870\ud68c\ub294 INSERT, DELETE\uc640 \ub2ec\ub9ac \uac12\uc744 \ubc18\ud658\ubc1b\uc544\uc57c \ud558\uae30 \ub54c\ubb38\uc5d0 \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4. \\n\uc774 \ub54c \ucf5c\ubc31\uc774\ub77c\ub294 \uac83\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. \\n\\n:::note \ucf5c\ubc31(Callback)\\n\\n\ud504\ub85c\uadf8\ub798\ubc0d\uc5d0\uc11c \ucf5c\ubc31\uc740 \ub2e4\ub978 \ucf54\ub4dc\uc758 \uc778\uc218\ub85c \ub118\uaca8\uc8fc\ub294 \uc2e4\ud589 \uac00\ub2a5\ud55c \ucf54\ub4dc\ub97c \ub73b\ud55c\ub2e4. \\n\uc790\ubc14\uc5d0\uc11c\ub294 \ub78c\ub2e4\ub098 \uc775\uba85 \ud074\ub798\uc2a4\ub97c \ub118\uaca8\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n```mermaid\\nflowchart LR\\n \ud074\ub77c\uc774\uc5b8\ud2b8 -- \ucf5c\ubc31\uc804\ub2ec --\x3e \uba54\uc11c\ub4dc\\n \uba54\uc11c\ub4dc -- \ub0b4\ubd80\ud638\ucd9c --\x3e \uc804\ub2ec\ubc1b\uc740\ucf5c\ubc31\\n```\\n\\n:::\\n\\n\\n\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uc870\ud68c\ud558\uace0, \ud574\ub2f9 \uac12\uc744 \uac1d\uccb4\ub85c \ub9e4\ud551\ud558\uc5ec \uac12\uc744 \ubc18\ud658\ud574\uc57c \ud55c\ub2e4. \\nexecuteQuery\ub85c \uc870\ud68c\ud55c \uac12\uc740 ResultSet \uc548\uc5d0 \ub4e4\uc5b4\uac00\uc788\ub2e4. \\n\uc774\ub97c \uc6d0\ud558\ub294 \ud0c0\uc785\uc758 \uac12\uc73c\ub85c \ubcc0\ud658\ud574\uc57c\ud558\ub2c8 \uc77c\ub2e8 \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud55c\ub2e4. \\n\\n```java\\n@FunctionalInterface\\npublic interface RowMapper {\\n User mapRow(final ResultSet resultSet) throws SQLException;\\n}\\n```\\n\\n### \uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c\\n\\n\uc704\uc5d0\uc11c \uc815\uc758\ud55c RowMapper\ub97c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc5b4\ub5bb\uac8c \uc0ac\uc6a9\ud574\uc57c \ud560\uae4c? \\n\uc544\ub798\uc640 \uac19\uc774 SQL \ucffc\ub9ac, RowMapper, \ud30c\ub77c\ubbf8\ud130\ub97c \ubd84\ub9ac\ud55c \uba54\uc11c\ub4dc\uc5d0 \ub118\uaca8\uc8fc\uace0 \ucffc\ub9ac \uc2e4\ud589 \ud6c4 \ub9e4\ud551\ud55c \uac12\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. \\n\\n```java\\npublic User findById(final int userId) {\\n final String query = \\"SELECT * FROM user WHERE id = ?\\";\\n return queryForSingleResult(query, resultSet -> {\\n final int id = resultSet.getInt(\\"id\\");\\n final String name = resultSet.getString(\\"name\\");\\n return new User(id, name);\\n }, userId);\\n}\\n\\nprivate User queryForSingleResult(\\n final String query,\\n final RowMapper rowMapper,\\n final Object... parameters\\n) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\\n if (resultSet.next()) {\\n return rowMapper.mapRow(resultSet);\\n }\\n return null;\\n } catch (SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n}\\n\\nprivate ResultSet executeQuery(\\n final PreparedStatement preparedStatement,\\n final Object[] parameters) throws SQLException {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n return preparedStatement.executeQuery();\\n}\\n```\\n\\n### \uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c\\n\\n\ub2e8\uac74 \uc870\ud68c\uc640 \uc720\uc0ac\ud558\ub2e4.\\n\\n```java\\npublic List<User> findAll() {\\n final String query = \\"SELECT * FROM user\\";\\n return query(query, resultSet -> {\\n final int id = resultSet.getInt(\\"id\\");\\n final String name = resultSet.getString(\\"name\\");\\n return new User(id, name);\\n });\\n}\\n\\nprivate List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\\n final List<User> result = new ArrayList<>();\\n while (resultSet.next()) {\\n result.add(rowMapper.mapRow(resultSet));\\n }\\n return result;\\n } catch (SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n}\\n\\nprivate ResultSet executeQuery(\\n final PreparedStatement preparedStatement,\\n final Object[] parameters) throws SQLException {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n return preparedStatement.executeQuery();\\n}\\n```\\n\\n### \uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30\\n\\n\uc704\uc758 \ucf54\ub4dc\ub294 User\ub97c \uc870\ud68c\ud560 \ub54c\ub9cc \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. \\n\uc544\ub798\uc640 \uac19\uc774 \uc81c\ub124\ub9ad\uc744 \uc801\uc6a9\ud558\uc5ec \ub2e4\ub978 Dao\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\ud558\ub3c4\ub85d \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4.\\n\\n```java\\n@FunctionalInterface\\npublic interface RowMapper<T> {\\n T mapRow(final ResultSet resultSet) throws SQLException;\\n}\\n\\nprivate <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\\nprivate <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\\n```\\n\\n### \uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30\\n\\n\uba54\uc11c\ub4dc\ub85c \ubd84\ub9ac\ud55c \ubd80\ubd84\uc744 JdbcTemplate\uc774\ub77c\ub294 \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uc5b4 \uc62e\uae34\ub2e4. \\n\ub610\ud55c null\uc744 \ubc18\ud658\ud558\uae30 \ubcf4\ub2e8 Optional\ub85c \uac10\uc2f8\uc11c \ubc18\ud658\ud558\ub3c4\ub85d \ubcc0\uacbd\ud55c\ub2e4. \\n\ucd5c\uc885\uc801\uc73c\ub85c \uc544\ub798\uc640 \uac19\uc740 \ucf54\ub4dc\uac00 \uc644\uc131\ub41c\ub2e4.\\n\\n<Tabs>\\n<TabItem value=\\"UserDao\\" label=\\"UserDao\\" default>\\n\\n```java\\npublic class UserDao {\\n private final RowMapper<User> rowMapper = resultSet -> {\\n final int id = resultSet.getInt(\\"id\\");\\n final String name = resultSet.getString(\\"name\\");\\n return new User(id, name);\\n };\\n private final JdbcTemplate jdbcTemplate;\\n\\n public UserDao(final JdbcTemplate jdbcTemplate) {\\n this.jdbcTemplate = jdbcTemplate;\\n }\\n\\n public void insert(final String name) {\\n final String query = \\"INSERT INTO User (name) VALUES (?)\\";\\n jdbcTemplate.executeUpdate(query, name);\\n }\\n\\n public void delete(final int userId) {\\n final String query = \\"DELETE FROM user WHERE user_id = ?\\";\\n jdbcTemplate.executeUpdate(query, userId);\\n }\\n\\n public Optional<User> findById(final int userId) {\\n final String query = \\"SELECT * FROM user WHERE id = ?\\";\\n return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);\\n }\\n\\n public List<User> findAll() {\\n final String query = \\"SELECT * FROM user\\";\\n return jdbcTemplate.query(query, rowMapper);\\n }\\n}\\n```\\n\\n</TabItem>\\n<TabItem value=\\"JdbcTemplate\\" label=\\"JdbcTemplate\\" default>\\n\\n```java\\npublic class JdbcTemplate {\\n private final ConnectionPool connectionPool;\\n\\n public JdbcTemplate(final ConnectionPool connectionPool) {\\n this.connectionPool = connectionPool;\\n }\\n\\n public void executeUpdate(final String query, final Object... parameters) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n preparedStatement.executeUpdate();\\n } catch (final SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n\\n public <T> Optional<T> queryForSingleResult(\\n final String query,\\n final RowMapper<T> rowMapper,\\n final Object... parameters\\n ) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\\n if (resultSet.next()) {\\n return Optional.of(rowMapper.mapRow(resultSet));\\n }\\n return Optional.empty();\\n } catch (SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n\\n private ResultSet executeQuery(\\n final PreparedStatement preparedStatement,\\n final Object[] parameters\\n ) throws SQLException {\\n for (int i = 1; i <= parameters.length; i++) {\\n preparedStatement.setObject(i, parameters[i - 1]);\\n }\\n return preparedStatement.executeQuery();\\n }\\n\\n public <T> List<T> query(\\n final String query,\\n final RowMapper<T> rowMapper,\\n final Object... parameters\\n ) {\\n final Connection connection = connectionPool.getConnection();\\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\\n final List<T> result = new ArrayList<>();\\n while (resultSet.next()) {\\n result.add(rowMapper.mapRow(resultSet));\\n }\\n return result;\\n } catch (SQLException e) {\\n throw new IllegalArgumentException(e.getMessage());\\n }\\n }\\n}\\n```\\n\\n</TabItem>\\n</Tabs>"},{"id":"woowacourse-level1-retrospective","metadata":{"permalink":"/woowacourse-level1-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx","source":"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx","title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0","description":"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4.","date":"2023-04-01T00:00:00.000Z","formattedDate":"2023\ub144 4\uc6d4 1\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":7.48,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0","slug":"woowacourse-level1-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30","permalink":"/custom-jdbc-template"},"nextItem":{"title":"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0","permalink":"/chess-retrospective"}},"content":"\ub808\ubca8 1\uc774 \ub05d\ub0ac\ub2e4. \\n\uc6b0\ud14c\ucf54\ub97c \uc2dc\uc791\ud558\uae30 \uc804 \ub0b4\uac00 \uc815\ud574\ub450\uc5c8\ub358 \ubaa9\ud45c \uc774\uc0c1\uc73c\ub85c \ub2ec\uc131\ud588\uae30 \ub54c\ubb38\uc5d0 \ub9e4\uc6b0 \ub9cc\uc871\uc2a4\ub7fd\ub2e4. \\n\ud63c\uc790 \ub3c5\ud559\uc744 \ud560 \ub550 \uc774 \ubc29\ud5a5\uc73c\ub85c \uacf5\ubd80\ud558\ub294 \uac8c \ub9de\ub294\uc9c0 \uacc4\uc18d \ubc18\ucd94\ud558\ub2e4 \uacb0\uad6d \ubb34\uae30\ub825\ud568\uc5d0 \ube60\uc838\ub4e4\uc5c8\ub2e4. \\n\ud558\uc9c0\ub9cc \uc774\uc81c\ub294 \uac19\uc774 \uacf5\ubd80\ud560 \uc0ac\ub78c\ub3c4 \uc788\uace0, \uc774\uc57c\uae30\ud560 \uc0ac\ub78c\ub3c4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc990\uae30\ub294 \uc77c\ub9cc \ub0a8\uc740 \uac83 \uac19\ub2e4. \\n\\n### Keep\\n\\n**\ub098\ub9cc\uc758 \ub8e8\ud2f4 \ub9cc\ub4e4\uae30** \\n\\n\uc2a4\uc2a4\ub85c\uac00 \uc678\ubd80\uc758 \uc601\ud5a5\uc744 \ub9ce\uc774 \ubc1b\ub294\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\ucd5c\ub300\ud55c \uafb8\uc900\ud788 \ud560 \uc218 \uc788\ub294 \uc2dc\uac04\uc744 \ub9cc\ub4dc\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\\n\ub9e4\uc77c 8\uc2dc\uc5d0 \ub3c4\ucc29\ud558\uc5ec \uc544\uce68\uc5d0 \ud574\uc57c \ud560 \uc77c\uc744 \uc815\ub9ac\ud558\uac70\ub098, \uc6b0\uc120\uc21c\uc704\uc5d0 \ub530\ub77c \ucc98\ub9ac\ud558\uace0 \\n\uc18c\ud654\ub2a5\ub825\uc774 \ubd80\uc871\ud558\uae30 \ub54c\ubb38\uc5d0 \uc810\uc2ec\uc740 \ub3c4\uc2dc\ub77d(\uadf8\ub798\ubd24\uc790 \uacc4\ub7802\uac1c)\uc744 \uc900\ube44\ud558\uace0 \\n\ud56d\uc0c1 \ub611\uac19\uc740 \ucee8\ub514\uc158\uc744 \uc720\uc9c0\ud558\uae30 \uc704\ud574 \ud56d\uc0c1 6\uc2dc\uc5d0 \uc9d1\uc5d0 \uac04\ub2e4. \\n\uc774\uc81c \ubc14\ube60\uc9c8 \ud14c\ub2c8 \uc77c\ucc0d \uc9d1\uc5d0 \uac00\ub294 \uc77c\uc740 \uc5b4\uca54 \uc218 \uc5c6\uc774 \uc904\uc5b4\ub4e4\uaca0\uc9c0\ub9cc\ud83d\ude22 \\n\\n\uc120\ud0dd\ub3c4 \ube44\uc6a9\uc774\ub2e4. \uc55e\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\uc774 \ud544\uc694 \uc5c6\ub294 \ubd80\ubd84\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\ub4e4\uc5b4\uc57c\uaca0\ub2e4. \\n\\n**\ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uae30** \\n\\n10\uba85 \uc815\ub3c4\uc758 \ud06c\ub8e8\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b0\uace0 \uce5c\ud558\uac8c \uc9c0\ub0b8\ub2e4\uba74 \uc131\uacf5\uc801\uc774\ub77c\uace0 \uc0dd\uac01\ud588\uc5c8\ub2e4. \\n\ud558\ub2e4 \ubcf4\ub2c8 \ub354 \ub9ce\uc740 \ud06c\ub8e8\ub4e4\uc758 \ub2c9\ub124\uc784\uc744 \uc678\uc6b4 \uac83 \uac19\ub2e4. \\n\uc55e\uc73c\ub85c\ub3c4 \ud06c\ub8e8\ub4e4\uacfc \uce5c\ud558\uac8c \uc9c0\ub0b4\uace0 \uc544\ubb34 \ub54c\ub098 \ub9d0\uc744 \uac78 \uc218 \uc788\ub294 \ud06c\ub8e8\uac00 \ub298\uc5b4\ub098\uae38 :) \\n\\n**\uae00\uc4f0\uae30** \\n\\n\uae00\uc744 \uc798 \uc4f0\ub294 \ud3b8\uc740 \uc544\ub2c8\uc9c0\ub9cc \uafb8\uc900\ud788 \uc791\uc131\ud558\ub824\uace0 \ub178\ub825\ud588\ub2e4. \\n\ub9e4 \ubbf8\uc158\ub9c8\ub2e4 \ud68c\uace0\ub97c \uc791\uc131\ud558\ub2c8 \uc0dd\uac01\ub3c4 \uc815\ub9ac\ub418\uace0 \uac1c\uc120\uc810\ub3c4 \ucc3e\uc744 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\ub2e4. \\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\uc5d0\ub294 \ub808\ubca8\ub9c8\ub2e4 \uae00\uc4f0\uae30\ub97c \uc9c4\ud589\ud558\ub294\ub370, \uc6b4\uc774 \uc88b\uac8c \uae00\uc4f0\uae30 \uc0c1\uc744 \ubc1b\uc558\ub2e4. \\n\uc0ac\uc2e4 \uac89\uc73c\ub85c \ub4dc\ub7ec\ub0b4\uc9c0 \uc54a\uc558\uc9c0\ub9cc \uaf2d \ubc1b\uc544\ubcf4\uace0 \uc2f6\uc5c8\ub2e4. \\n\uae00\uc4f0\uae30 \uc870\uc6d0, \ud22c\ud45c\ud574 \uc900 \ud06c\ub8e8\ub4e4\uc5d0\uac8c \ub108\ubb34 \uac10\uc0ac\ud558\ub2e4. \\n\\n**\ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514** \\n\\n\ub204\ub204, \uc8fc\ub178, \ub2e4\uc990, \ub9d0\ub791, \ubc15\uc2a4\ud130, \uc624\uc789, \uae43\uc9f1\uc640 \ucf54\ub4dc \ub9ac\ubdf0 \uc2a4\ud130\ub514\ub97c \uc9c4\ud589\ud588\ub2e4. \\n\uacfc\uc5f0 \ub3c4\uc6c0\uc774 \ub420\uae4c \uc0dd\uac01\ud588\uc9c0\ub9cc \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \ucf54\ub4dc \ub9ac\ubdf0\ub97c \ud558\uba74\uc11c \uc131\uc7a5\uc744 \ub9ce\uc774 \ud55c \uac83 \uac19\ub2e4. \\n\ud22c\uc790\ud55c \uc2dc\uac04 \ub300\ube44 \uac00\uc131\ube44\uac00 \uc88b\uc740 \ud65c\ub3d9\uc774\uc5c8\ub2e4. \\n\ub204\ub204\uac00 \uc2a4\ud130\ub514\uc7a5\uc778\ub370 \uacfc\uc5f0 \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00\ub824\ub098? \\n\\n**\ub808\ubca8 \uc778\ud130\ubdf0**\\n\\n\uc778\ud130\ubdf0\ud560 \ub54c \ub9ce\uc774 \ub5a8\uc9c0 \uc54a\uc544\uc11c \uc88b\uc558\ub2e4. \\n\ub0a8\ub4e4 \uc55e\uc5d0\uc11c \uc774\uc57c\uae30\ub97c \ud558\uac70\ub098, \uba74\uc811\uc744 \ubcf4\uba74 \ud56d\uc0c1 \uc5c4\uccad \ub5a8\uc5b4\uc11c \uac71\uc815\ud588\ub294\ub370 \\n\uae30\uc220\uc801\uc778 \uc9c8\ubb38\uc744 \ubc1b\uc558\uc744 \ub54c \ub5a8\uc9c0 \uc54a\uace0 \uc798 \ub300\ub2f5\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \ub2e4\ub978 \ud06c\ub8e8\uac00 \uc9c8\ubb38\ud588\uc744 \ub54c, \ucd5c\ub300\ud55c \uc774\ud574\ud558\uae30 \uc27d\uac8c \uc124\uba85\ud558\ub824\uace0 \ud588\ub358 \uacbd\ud5d8\uc774 \ub3c4\uc6c0\uc774 \ub41c \uac83 \uac19\ub2e4. \\n\uc774\ud6c4 \ub808\ubca8 \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc740 \ubd80\ubd84\uc744 \uace0\ub824\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\ub2e4. \\n- \ub300\ub2f5\ud558\uba74\uc11c \uc9c8\ubb38\uc744 \uacc4\uc18d \uc0dd\uac01\ud558\uba70 \uc78a\uc5b4\ubc84\ub9ac\uc9c0 \ub9d0\uae30 \\n- \ub450\uad04\uc2dd \ud45c\ud604\\n- \uc124\uba85\ud558\ub2e4\uac00 \uc798\ubabb \uc124\uba85\ud55c \uac83 \uac19\uc73c\uba74 \ub2e4 \ub04a\uace0 \ub2e4\uc2dc \uc774\uc57c\uae30\ud574\ub3c4 \ub420\uc9c0 \ubb3c\uc5b4\ubcf4\uae30 \\n- \uc124\uba85\ud560 \uc218 \uc788\uc744\ub9cc\ud07c \uc2dc\uac04 \ucda9\ubd84\ud788 \uac00\uc9c0\uae30\\n- \uc778\ud130\ubdf0\uc5b4\uc758 \uc9c8\ubb38 \uc758\ub3c4\ub97c \uba85\ud655\ud788 \uc774\ud574\ud558\uc9c0 \ubabb\ud588\ub2e4\uba74 \uc758\ub3c4 \ub2e4\uc2dc \ubb3c\uc5b4\ubcf4\uae30\\n- \ub05d\ub9fa\ub294 \ubd80\ubd84 \uc5f0\uc2b5\ud558\uae30(\uc790\uc2e0\uac10 \uc788\uac8c)\\n- \uae30\uc220\uc801\uc778 \uc9d1\ucc29\uac00\uc9c0\uae30\\n- \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud788 \uc900\ube44\ud588\uc73c\uba74 \ud611\uc5c5 \uad00\ub828 \uc9c8\ubb38\ub3c4 \uc900\ube44\ud558\uae30\\n\\n### Problem\\n\\n**\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d** \\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uac00\uc7a5 \uc5b4\ub824\uc6b4 \ud65c\ub3d9 \uc911 \ud558\ub098\ub77c\uace0 \uc0dd\uac01\ud55c\ub2e4. \\n\ud398\uc5b4\ub294 \ub9e4\ubc88 \ubc14\ub00c\uace0, \ubbf8\uc158\uc758 \ubcf5\uc7a1\ub3c4\ub3c4 \uc99d\uac00\ud558\uae30 \ub54c\ubb38\uc778 \uac83 \uac19\ub2e4. \\n\uc18c\ud1b5 \ub2a5\ub825, \uc2dc\uac04\uad00\ub9ac\uac00 \ubd80\uc871\ud588\uace0, \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\uc558\ub2e4. \\n\ud558\uc9c0\ub9cc \ud398\uc5b4\ub97c \uc9c4\ud589\ud558\uace0, \ud68c\uace0\ub97c \ud558\ub2e4 \ubcf4\ub2c8 \ub098\ub9cc\uc758 \ub178\ud558\uc6b0\uac00 \uc313\uc774\ub294 \ub290\ub08c\uc774\ub2e4. \\n\ub808\ubca8 2\uc5d0\uc11c\ub294 \ubd80\uc871\ud588\ub358 \ubd80\ubd84\uc744 \uac1c\uc120\ud558\uc5ec \ud568\uaed8\ud558\uace0 \uc2f6\uc740 \ud398\uc5b4\uac00 \ub418\uace0 \uc2f6\ub2e4. \\n\\n**\uc9d1\uc911\ud558\ub294 \uc2dc\uac04\u23f1\ufe0f \ubd80\uc871** \\n\\n\ub808\ubca8 1\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc9d1\uc911\ud558\ub294 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4. \\n\uc774\ub978 \uc544\uce68\uacfc \uc624\ud6c4\uc5d0 \uac1c\uc778\uc801\uc73c\ub85c \uc9d1\uc911\ud560 \uc218 \uc788\ub294 \uacf5\uac04\uc744 \uc608\uc57d\ud574\uc11c \uc628\uc804\ud788 \ub098\ub9cc\uc758 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. \\n\\n### Try\\n\\n**\ud5c8\ube0c\ud83c\udf3f\uc640\uc758 \ud2f0\ud0c0\uc784?** \\n\\n\uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc744 \ub298\ub9b4 \ubc29\ubc95\uc744 \uc0dd\uac01\ud558\ub2e4\uac00 \ub300\ud654\ub97c \ub098\ub204\uc9c0 \ubabb\ud55c \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \uae5c\uc9dd \ucee4\ud53c\ucc57\uc744 \ud558\uba74 \uc5b4\ub5a8\uae4c \uc0dd\uac01\ud588\ub2e4. \\n\uc608\ub97c \ub4e4\uc5b4 \uc7a1\ub2f4\ubc29\uc5d0 `\uc800\uc640 \ucee4\ud53c\ucc57 \ud558\uc2e4 \ubd84 :)` \ud558\uba74\uc11c \uc62c\ub9b4 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. \\n\ucc38\uc5ec\ud558\ub294 \uc0ac\ub78c\uc774 \uc788\uc744\uc9c0, \uc548 \uc88b\uac8c \ubcf4\ub294 \uac8c \uc544\ub2d0\uc9c0 \uac71\uc815\ub418\uc9c0\ub9cc \uadf8\ub798\ub3c4 \uc7ac\ubc0c\uc744 \uac83 \uac19\ub2e4. \\n\uc800\ub791 \ud5c8\ube0c\ud2f0 \ud55c\uc794 \ud558\uc2e4\ub798\uc694? \\n\\n**\uae30\uc220\uc801\uc778 \ubd80\ubd84** \\n\\n\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \uc0dd\ud65c\uc744 \ud558\uba74\uc11c \uc18c\ud504\ud2b8 \uc2a4\ud0ac\uc5d0 \uc870\uae08 \ub354 \ubb34\uac8c\ub97c \ub450\ub2e4 \ubcf4\ub2c8 \uc774\ub860\uc801\uc778 \ubd80\ubd84\uc774 \ubd80\uc871\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uc2dc\uac04\uc758 \uc5ec\uc720\uac00 \ub420 \ub54c \ucc45\uc744 \uc870\uae08\uc529 \uc77d\uc5b4\uc57c\uaca0\ub2e4. \\n\ube14\ub85c\uadf8\uc5d0 \uae30\uc220\uc801\uc778 \ubd80\ubd84\uc744 \ub9ce\uc774 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\ub294 \uc2dc\uac04\ub3c4 \uac00\uc838\uc57c\uaca0\ub2e4. \\n\\n### \ub808\ubca8 1\uc744 \ub9c8\ubb34\ub9ac\ud558\uba70 \\n\\n\uc2dc\uac04\uc774 \ube60\ub974\uac8c \ud758\ub7ec\uac14\ub2e4. \\n\ud0c0\uc778\uc5d0\uac8c \uc88b\uc740 \uc601\ud5a5\uc744 \uc8fc\uae30\uc704\ud574, \ubc29\ud559\ub3d9\uc548 \ub098\ub97c \ucc59\uae30\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. \\n\ub610\ud55c \ud568\uaed8 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc744 \ubaa9\ud45c\ub85c \uc55e\uc73c\ub85c\ub3c4 \uafb8\uc900\ud788 \uc758\uc2dd\uc801 \ub178\ub825\uc744 \ud574\uc57c\uaca0\ub2e4."},{"id":"chess-retrospective","metadata":{"permalink":"/chess-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0","description":"1, 2\ub2e8\uacc4//github.com/woowacourse/java-chess/pull/441","date":"2023-03-31T00:00:00.000Z","formattedDate":"2023\ub144 3\uc6d4 31\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":7.705,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0","slug":"chess-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0","permalink":"/woowacourse-level1-retrospective"},"nextItem":{"title":"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134","permalink":"/grasp"}},"content":":::note PR \ub9c1\ud06c \\n1, 2\ub2e8\uacc4: https://github.com/woowacourse/java-chess/pull/441 \\n3, 4\ub2e8\uacc4: https://github.com/woowacourse/java-chess/pull/529 \\n:::\\n\\n### \uccb4\uc2a4\\n\uccb4\uc2a4 \ubbf8\uc158\uc5d0\ub294 \uac00\ube44\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4! \\n\uccb4\uc2a4\ub294 \uc774\uc804 \ubbf8\uc158\ub4e4\ubcf4\ub2e4 \ud6e8\uc52c \ubcf5\uc7a1\ud55c \ub3c4\uba54\uc778\uc774\uc5c8\ub2e4. \\n\ud558\uc9c0\ub9cc \uac00\ube44\uc640 \ub098\ub294 \uccb4\uc2a4 \ub3c4\uba54\uc778\uc774 \uc775\uc219\ud574\uc11c \ub354 \ud3b8\ud55c \ub9c8\uc74c\uc73c\ub85c \uc2dc\uc791\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc5b4\ub824\uc6e0\ub358 \ubd80\ubd84\uc740 \uae30\ubb3c\uc758 \uc774\ub3d9, \uc774\ub3d9\uc2dc \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubd80\ubd84\uc774\uc5c8\ub2e4. \\n \\n\uac00\ube44\uac00 \uc9d1\uc5d0\uac00\uc11c\ub3c4 \uae30\ubb3c\uc758 \uc774\ub3d9 \uad00\ub828\ud574 \uc0dd\uac01 \uc815\ub9ac\ud55c \uae00\uc744 \ubcf4\ub0b4\uc918\uc11c \ub354\uc6b1 \ube68\ub9ac \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ucd5c\uc885\uc801\uc73c\ub85c \uacb0\uc815\ud55c \ubd80\ubd84\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n\\n**\uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5\uc5ec\ubd80** \\nRank\uc640 File\uc740 \uac01\uac01 \uc704\uce58\uac12\uc744 \uac00\uc9c0\uace0 \uc788\uace0, \uac12\uc758 \ucc28\uc774\ub97c \uc774\uc6a9\ud574\uc11c \uac01 \uae30\ubb3c\uc758 \uc774\ub3d9 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uacc4\uc0b0\ud588\ub2e4. \\n\uc9c1\uc120 \u2192 Rank\uc640 File \ucc28\uc774 \uc911 \ud558\ub098\uac00 0\uc774\uc5b4\uc57c \ud55c\ub2e4. \\n\ub300\uac01\uc120 \u2192 Rank\uc640 File \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \uac19\uc544\uc57c \ud55c\ub2e4. ex) abs(-2) == abs(2) \\n\ub098\uc774\ud2b8 \u2192 \ucc28\uc774\uc758 \uc808\ub300\uac12\uc774 \ud558\ub098\ub294 2 \ub098\uba38\uc9c0 \ud558\ub098\ub294 1\uc774\uc5b4\uc57c \ud55c\ub2e4.\\n\\n**\ub3c4\ucc29 \uce78\uc758 \uae30\ubb3c \uc5ec\ubd80** \\n\uc544\uad70 \u2192 \uc774\ub3d9\uc774 \ubd88\uac00\ub2a5\ud558\ub2e4. \\n\uc801\uad70 \u2192 \uc774\ub3d9\uc774 \uac00\ub2a5\ud558\ub2e4. \uc801\uad70\uc744 \uc7a1\ub294\ub2e4. \\n\\n**\uc911\uac04\uc5d0 \uae30\ubb3c \uc874\uc7ac \uc5ec\ubd80** \\n\uc774\ub3d9 \uacbd\ub85c\uc5d0 \uae30\ubb3c\uc774 \uc874\uc7ac\ud558\uba74 \uc548\ub41c\ub2e4. \\n\\n**\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0ac\uc6a9** \\n\uccb4\uc2a4 \ubbf8\uc158\uc740 \ud2b9\ubcc4\ud558\uac8c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc5f0\uacb0\ud558\ub294 \ubd80\ubd84\uc774 \uc788\uc5c8\ub2e4. \\n\uccb4\uc2a4 \uac8c\uc784\uc758 \uc0c1\ud0dc\ub97c \ub2e4\uc74c\uc758 \ub450\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uc815\ud560 \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n- \uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95 \\n- \uae30\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uac8c\uc784\uc744 \ubd88\ub7ec\uc640 \uae30\ubcf4\ub300\ub85c \uc774\ub3d9\uc2dc\ud0a4\ub294 \ubc29\ubc95 \\n\\n\uae30\ubb3c\uc774 \uc774\ub3d9\ud560 \ub54c\ub9c8\ub2e4 \uac12\uc744 \uc800\uc7a5\ud558\uace0 \uc2f6\uc5c8\uace0, \uae30\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc744 \uc120\ud0dd\ud588\ub2e4. \\n\uae30\ubb3c \uc804\uccb4\ub97c \uc800\uc7a5\ud558\uc9c0 \uc54a\uc740 \uc774\uc720\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. \\n- \ud134\uacfc \uac19\uc740 \ubd80\uac00\uc801\uc778 \uc694\uc18c\ub97c \uc800\uc7a5\ud574\uc57c \ud55c\ub2e4. \\n- \uc774\ub3d9\uc744 \ud560 \ub54c \uae30\ubb3c\uc774 \uc7a1\ud788\ub294 \uacbd\uc6b0 update \ucffc\ub9ac(\uc774\ub3d9 \uae30\ubb3c)\uc640 delete(\uc7a1\ud78c \uae30\ubb3c) 2\uac1c\uc758 \ucffc\ub9ac\ub97c \ub0a0\ub824\uc57c \ud55c\ub2e4. \\n- \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ub3c4\uba54\uc778\uc758 \ubcc0\uacbd\uc774 \ud06c\uac8c(\ucd08\uae30 \uc0c1\ud0dc\ub97c \uad6c\uc131\ud558\ub294 \ubd80\ubd84) \uc77c\uc5b4\ub098\uc57c \ud55c\ub2e4. \\n\\n\uc815\ub9ac\ud558\uc790\uba74 \uae30\ubb3c \uc804\uccb4 \uc800\uc7a5\uacfc \uae30\ubcf4 \uc800\uc7a5\uc740 \ub2e4\uc74c\uacfc \ucc28\uc774\uac00 \uc788\ub2e4. \\n\ubcf4\ub4dc\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc\uc5d0\uc11c 32\uac1c\uc758 Insert \ucffc\ub9ac(\uae30\ubb3c\uc758 \uc704\uce58) + \uae30\ubb3c \uc774\ub3d9 \uc2dc \uc6c0\uc9c1\uc784 \ubcc0\uacbd(\uc7a1\ud788\ub294 \uacbd\uc6b0 2\uac1c\uc758 \ucffc\ub9ac) \\n\uae30\ubcf4\uc800\uc7a5: \ucd08\uae30\uc0c1\ud0dc \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uad6c\uc131 + \uc800\uc7a5\ub41c \uae30\ubcf4\ub97c select \ucffc\ub9ac\ub85c \uc870\ud68c\ud574\uc11c \uc0ac\uc6a9(1\ud68c) + insert \ucffc\ub9ac(\uc774\ub3d9 \ub2f9 1\ud68c)\\n\\n\ucd94\uac00\ub85c \uae30\ubcf4\uc800\uc7a5\uc774 \uad6c\ud604\ub3c4 \ub354\uc6b1 \uac04\ub2e8\ud558\ub2e4. \ud83d\udc4d \\n\\n**\ubd80\uac00\uc801\uc778 \ubd80\ubd84**\\n\\n\ub9ac\ubdf0\uc5b4\uc778 \ucc30\ub9ac\ud83c\udf6b\uac00 \ub3d9\uc2dc\uc5d0 \uc5ec\ub7ec \uac8c\uc784\uc774 \uc9c4\ud589\ub41c\ub2e4\uba74 \uc5b4\ub5a8\uc9c0? \uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\ub97c \ub0a8\uaca8\uc8fc\uc154\uc11c \ub2e4\uc591\ud55c \uc2dc\ub3c4\ub97c \ud574\ubd24\ub2e4. \\n- \ub204\ub204\uc758 \ub3c4\uc6c0\uc73c\ub85c ConnectionPool \uad6c\ud604 \\n- ThreadLocal \uc0ac\uc6a9\ud574\uc11c \uc4f0\ub808\ub4dc \ubcc4 \uc138\uc158 \uad00\ub9ac \\n- \uc2e4\uc81c\ub85c \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ub0b4\uc5d0\uc11c \uccb4\uc2a4 \uac8c\uc784\uc774 \uc9c4\ud589\ub418\ub294 Board\ub97c ConcurrentHashMap\uc73c\ub85c \uc800\uc7a5(\uc0ac\uc2e4 \uc774 \ubd80\ubd84\uc740 \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c \ud544\uc694\uc5c6\uc9c0\ub9cc 2\uba85\uc774 \uc11c\ub85c \uac8c\uc784\ud558\ub294 \uacbd\uc6b0\ub97c \uc0dd\uac01\ud574\uc11c \ub123\uc5b4\ubcf4\uc558\ub2e4.) \\n\\n\ub450 \uba85\uc774 \uc11c\ub85c \uac19\uc740 \ubc29\uc5d0 \uc785\uc7a5\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4\uba74 \ucd9c\ub825\ud558\ub294 \ubd80\ubd84\uc774 \uae4c\ub2e4\ub85c\uc6cc\uc9c8 \uac83 \uac19\ub2e4\uace0 \uc608\uc0c1\ub418\uc5b4(Board\uc5d0 \uc635\uc800\ubc84 \ud328\ud134\uc744 \uc0ac\uc6a9\ud574\uc57c\ub418\ub098?) \ud574\ubcfc \uc5c4\ub450\uac00 \ub098\uc9c0 \uc54a\uc558\ub2e4. \\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n**\uaf3c\uaf3c\ud558\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc9c0 \ubabb\ud55c \ubd80\ubd84** \\nDB \uad00\ub828 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucf54\ub529\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\ub3c4\uba54\uc778 \ub85c\uc9c1\uc5d0\ub9cc \uc9d1\uc911\ud558\ub2e4\ubcf4\ub2c8 \uc815\uc801 \uc911\uc694\ud55c DB\uc758 \ucf54\ub4dc\uc758 \uc608\uc678\ucc98\ub9ac, \ube48 \uac12\uc744 \ubc18\ud658 \ud558\ub294 \ubd80\ubd84\uc744 \uaf3c\uaf3c\ud558\uac8c \ucc98\ub9ac\ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\ud558\uc9c0\ub9cc \ucc30\ub9ac\uc758 \uaf3c\uaf3c\ud55c \ub9ac\ubdf0\ub85c DB\ubd80\ubd84\uacfc \ub098\ub9cc\uc758 JdbcTemplate\uc744 \uae54\ub054\ud558\uac8c \uad6c\ud604\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n**\uc2dc\uac04\uc5d0 \ub300\ud55c \ubd80\ub2f4\uac10** \\n\ucd08\ubc18\uc5d0\ub294 \uc5ec\uc720\ub86d\uc9c0\ub9cc \uc81c\ucd9c \ub9c8\uac10\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \uc218\ub85d \uc0ac\ub78c\uc774 \uae09\ud574\uc9c0\ub294 \uac83 \uac19\ub2e4. \\n\ub2e4\uc74c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\ud560 \ub550 \uc18d\ub3c4\ub97c \uc870\uc808\ud558\uace0, \ub9c8\uc74c\uc5d0 \uc5ec\uc720\ub97c \uac00\uc838\uc57c\uaca0\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**DAO \uc911\ubcf5 \uc81c\uac70**\\n\\n\ud504\ub864\ub85c\uadf8\uc5d0 [\uae00](https://prolog.techcourse.co.kr/studylogs/2947)\uc744 \uc791\uc131\ud588\ub2e4. \\nDAO\ub97c \uc791\uc131\ud558\ub294\ub370 try-catch-resources\uc640 \uc5ec\ub7ec \ucf54\ub4dc\uac00 \uc911\ubcf5\ub418\uc11c \uc81c\uac70\ud558\uace0\uc2f6\uc5c8\ub2e4. \\n\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc73c\ub85c \uae54\ub054\ud558\uac8c \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\udc4d\\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\ud398\uc5b4 \uc0dd\uac01\ud558\uae30** \\n\uac00\ube44\ub294 \ub204\uad6c\ubcf4\ub2e4 \ud398\uc5b4\ub97c \uc0dd\uac01\ud558\uace0, \ubc30\ub824\ud574\uc8fc\ub294 \ud398\uc5b4\uc600\ub2e4. \\n\uc911\uac04 \uc911\uac04 \ub2f9 \ub5a8\uc5b4\uc9c8\uae4c\ubd10 \uac71\uc815\ub3c4 \ud574\uc8fc\uace0, \ub098\uc758 \ucee8\ub514\uc158\ub3c4 \ud655\uc778\ud574\uc92c\ub2e4! \\n\\n**\ubbf8\uc158 \ubab0\uc785\ud558\uae30** \\n\ucd5c\uadfc\uc5d0 \ubbf8\uc158\uc5d0 \uc798 \ubab0\uc785\ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\uac00\ube44\ub294 \ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \ubbf8\uc158\uc5d0 \ub300\ud55c \ubab0\uc785\ub3c4\uac00 \ub9e4\uc6b0 \uc88b\uc558\ub2e4. \\n\uc9d1\uc5d0\uac00\uc11c\ub3c4 \uccb4\uc2a4 \uc774\ub3d9\uc5d0 \ub300\ud55c \ub85c\uc9c1\uc744 \uc5b4\ub5bb\uac8c \uad6c\ud604\ud560 \uc9c0 \uc0dd\uac01\ud55c \ub4a4 \uaf3c\uaf3c\ud574\uc11c \uc815\ub9ac\ud574\uc11c \ub098\uc5d0\uac8c \ubcf4\ub0b4\uc8fc\uc5c8\ub2e4. \\n\ub355\ubd84\uc5d0 \ub098\ub3c4 \uac00\ube44\uc758 \uc0dd\uac01\uc744 \uc54c \uc218 \uc788\uc5b4\uc11c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294\ub370 \uac00\uc18d\ub3c4\uac00 \ubd99\uc740 \uac83 \uac19\ub2e4. \\n\ub610\ud55c \ubbf8\uc158\uc744 \uc798 \ub9c8\ubb34\ub9ac\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c\uc774 \uc804\ub2ec\ub418\uc11c \uadf8\ub7f0\uc9c0 \ub098\ub3c4 \ub369\ub2ec\uc544 \uc5f4\uc2ec\ud788 \ubbf8\uc158\uc744 \ud560 \uc218 \uc788\uc5c8\ub2e4.\ud83d\ude04 \\n\\n**\uc194\uc9c1\ud568** \\n\uba3c\uc800 \ud68c\uace0\ud558\uc790\uace0 \ub9d0 \uac78\uc5b4\uc918\uc11c \uc815\ub9d0 \uace0\ub9c8\uc6e0\ub2e4\uace0 \ud45c\ud604\ud574\uc8fc\ub294 \ubd80\ubd84 \\n\ubaa8\ub974\ub294\uac8c \uc788\uc73c\uba74 \uc194\uc9c1\ud558\uac8c \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84 \\n\ub098\uc758 \uc758\uacac\uc744 \uc815\ub9ac\ud558\uc9c0 \ubabb\ud55c \uc0c1\ud0dc\ub85c \uc804\ub2ec\ud560 \ub54c \uc774\ud574\uac00 \uc548\ub418\uc5c8\ub2e4\uace0 \uc815\ud655\ud788 \uc804\ub2ec\ud574\uc8fc\ub294 \ubd80\ubd84 \\n\uc194\uc9c1\ud568\uc740 \ud398\uc5b4\ud560 \ub54c \uc911\uc694\ud55c \ubd80\ubd84\uc778 \uac83 \uac19\ub2e4. \\n\\n\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ucc30\ub9ac\ud83c\udf6b \uccb4\uc2a4 \ubbf8\uc158\ub54c \uaf3c\uaf3c\ud558\uac8c \ub9ac\ubdf0 \ub0a8\uaca8\uc8fc\uc154\uc11c \uac10\uc0ac\ud569\ub2c8\ub2e4!"},{"id":"grasp","metadata":{"permalink":"/grasp","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-30-GRASP.mdx","source":"@site/blog/2023-1/2023-03-30-GRASP.mdx","title":"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134","description":"GRASP(General Responsibility Assignment Software Pattern)","date":"2023-03-30T00:00:00.000Z","formattedDate":"2023\ub144 3\uc6d4 30\uc77c","tags":[{"label":"GRASP","permalink":"/tags/grasp"},{"label":"OOP","permalink":"/tags/oop"}],"readingTime":8.085,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134","slug":"grasp","tags":["GRASP","OOP"]},"unlisted":false,"prevItem":{"title":"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0","permalink":"/chess-retrospective"},"nextItem":{"title":"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0","permalink":"/blackjack-retrospective"}},"content":"### GRASP(General Responsibility Assignment Software Pattern)\\n\\n\ud06c\ub808\uc774\uadf8 \ub77c\ub9cc\uc758 Applying UML and Patterns\uc774\ub77c\ub294 \ucc45\uc5d0\uc11c \ub098\uc628 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134\\n\\n\uac01 \ud328\ud134\ub9c8\ub2e4 Solution\uacfc Problem\ub85c \uad6c\uc131\ub418\uc5b4 \uc788\ub2e4.\\n\\n### \uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)\\n\\nQ: \uac1d\uccb4\uc5d0 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uae30\ubcf8 \uc6d0\uce59\uc740 \ubb34\uc5c7\uc778\uac00?\\n\\nA: \ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub370 \ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \ud074\ub798\uc2a4(\uc815\ubcf4 \uc804\ubb38\uac00)\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4.\\n\\n\uc815\ubcf4\uc640 \ud589\ub3d9\uc744 \uac00\uae4c\uc6b4 \uacf3\uc5d0 \uc704\uce58\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \ucea1\uc290\ud654\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4.\\n\\n\ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \uac1d\uccb4\ub4e4\ub85c \ucc45\uc784\uc774 \ubd84\uc0b0\ub41c\ub2e4.\\n\\n### \ucc3d\uc870\uc790 \ud328\ud134(Creator)\\n\\nQ: \ub204\uac00 \uac1d\uccb4 A\ub97c \uc0dd\uc131\ud558\ub294\uac00?\\n\\nA: \ub2e4\uc74c\uc758 \uc870\uac74\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\uc871\ud558\ub294 \uac1d\uccb4\uc5d0\uac8c \uac1d\uccb4 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4.\\n\\n- B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4.\\n- B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4.\\n- B\uac00 A \uac1d\uccb4\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4.\\n- B\uac00 A \uac1d\uccb4\uc758 \ucd08\uae30\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4.\\n\\n\uc0dd\uc131 \uc608\uc815\uc778 \uac1d\uccb4\uc640 \uc5f0\uad00\ub418\uc5b4 \uc788\ub294 \uac1d\uccb4\uac00 \uc0dd\uc131 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uac8c \ub41c\ub2e4\uba74, \uc774\ubbf8 \ud574\ub2f9 \uac1d\uccb4\uc640 \uacb0\ud569\ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\uac8c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4.\\n\\n### \ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)\\n\\nQ: \uc758\uc874\uc131\uc744 \ub0ae\ucd94\uace0 \ubcc0\ud654\uc758 \uc601\ud5a5\uc744 \uc904\uc774\uba70 \uc7ac\uc0ac\uc6a9\uc131\uc744 \uc99d\uac00\uc2dc\ud0a4\ub294 \ubc29\ubc95\uc740?\\n\\nA: \uc804\uccb4\uc801\uc778 \uacb0\ud569\uc774 \ub0ae\uac8c \uc720\uc9c0\ub418\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4.\\n\\n> \uacb0\ud569\ub3c4(Coupling)\\n\uac1d\uccb4 \uc0ac\uc774\uc758 \uc758\uc874\uc131\uc774 \uacfc\ud55c \uacbd\uc6b0 \uacb0\ud569\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4.\\n- \uc624\ube0c\uc81d\ud2b8 p.17\\n> \\n\\n\uacb0\ud569\ub3c4\ub97c \ub0ae\ucd98\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4.\\n\\n- \ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\uc758 \ubcc0\ud654\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294\ub2e4.\\n- \uc7ac\uc0ac\uc6a9\uc774 \ud3b8\ub9ac\ud574\uc9c4\ub2e4.\\n- \ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\uc758\uc874\ud558\ub294 \ud074\ub798\uc2a4\uac00 \uc801\uae30 \ub54c\ubb38\uc5d0)\\n\\n### \ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)\\n\\nQ. \uac1d\uccb4\ub97c \uad00\ub9ac\ud558\uae30 \uc27d\uac8c \ud558\ub824\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?\\n\\nA. \ub192\uc740 \uc751\uc9d1\ub3c4\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4.\\n\\n> \uc751\uc9d1\ub3c4(Cohesion)\\n\uc5f0\uad00\ub41c \uc791\uc5c5\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc5f0\uad00\uc131 \uc5c6\ub294 \uc791\uc5c5\uc740 \ub2e4\ub978 \uac1d\uccb4\uc5d0\uac8c \uc704\uc784\ud558\ub294 \uac1d\uccb4\ub97c \uac00\ub9ac\ucf1c \uc751\uc9d1\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4.\\n- \uc624\ube0c\uc81d\ud2b8 p.26\\n> \\n\\n\ubcc0\uacbd\uc758 \uc774\uc720\uc5d0 \ub530\ub77c \ud074\ub798\uc2a4\ub97c \ubd84\ub9ac\ud55c\ub2e4\uba74 \uc751\uc9d1\ub3c4\ub97c \ub192\uc77c \uc218 \uc788\uace0, \uc751\uc9d1\ub3c4\uac00 \ub192\uc544\uc9c4\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4.\\n\\n- \ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\ud560\ub2f9\ub41c \ucc45\uc784\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0)\\n- \uc720\uc9c0\ubcf4\uc218\uac00 \uc26c\uc6cc\uc9c4\ub2e4.\\n- \ub0ae\uc740 \uacb0\ud569\ub3c4 \ub610\ud55c \uc9c0\uc6d0\ud55c\ub2e4.\\n- \uc751\uc9d1\ub3c4\uac00 \ub192\uc740 \ud074\ub798\uc2a4\ub294 \ud2b9\uc815\ud55c \ubaa9\uc801\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc7ac\uc0ac\uc6a9\ud558\uae30 \uc88b\ub2e4.\\n\\n### \ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)\\n\\nQ. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uac83\uc740 \ub204\uac00 \ub2f4\ub2f9\ud574\uc57c \ud558\ub294\uac00?\\n\\nA. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 Controller \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4.\\n\\n\uc5b4\ub5a4 \uc11c\ube0c\uc2dc\uc2a4\ud15c\uc774 \uc874\uc7ac\ud55c\ub2e4\uace0 \uac00\uc815\ud560 \ub54c\\n\\n- \uc9c1\uc811\uc801\uc73c\ub85c \uac1d\uccb4\uc5d0 \uc811\uadfc\ud558\uc5ec \ud504\ub85c\uadf8\ub7a8\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uacb0\ud569\ub3c4\uac00 \uc0c1\uc2b9\ud55c\ub2e4.\\n- \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc5d0 \ub4e4\uc5b4\uc624\ub294 \uc694\uccad\uc744 \ucc98\ub9ac\ud574\uc8fc\ub294 \ucee8\ud2b8\ub864\ub7ec\uac00 \uc788\ub2e4\uba74 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 \ud574\ub2f9 \ucee8\ud2b8\ub864\ub7ec\ub9cc \uc54c\uba74 \ub41c\ub2e4.\\n- \ub9cc\uc57d \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc758 \ubcc0\uacbd\uc774 \uc0dd\uacbc\uc744 \ub54c \uc678\ubd80\uc5d0 \ubbf8\uce58\ub294 \uc601\ud5a5\ub3c4 \uc904\uc5b4\ub4e0\ub2e4.\\n\\n### \ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)\\n\\nQ. \uac1d\uccb4\uc758 \ud0c0\uc785\uc5d0 \ub530\ub77c \ud589\ub3d9\uc774 \ubc14\ub010\ub2e4\uba74 \ucc45\uc784\uc744 \uc5b4\ub5bb\uac8c \ud560\ub2f9\ud574\uc57c \ud560\uae4c?\\n\\nA. OOP\uac00 \uc9c0\uc6d0\ud558\ub294 \ub2e4\ud615\uc131\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ud65c\uc6a9\ud55c\ub2e4. (\uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0 \ud589\ub3d9\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uad6c\ud604)\\n\\n\uac1d\uccb4\uc758 \uc885\ub958\uc5d0 \ub530\ub77c \ubd84\uae30\ud558\ub294 \uc870\uac74\ubb38\uc774 \uc544\ub2cc \ub2e4\ud615\uc131\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4.\\n\\n\uc0c8\ub85c\uc6b4 \ud0c0\uc785\uc774 \ucd94\uac00\ub418\uc5c8\uc744 \ub54c \uc870\uac74\ubb38\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uae30\uc874\uc758 \uc870\uac74\ubb38\uc744 \uc218\uc815\ud574\uc57c \ud558\uc9c0\ub9cc \ub2e4\ud615\uc131\uc744 \ud65c\uc6a9\ud558\uba74 \uc27d\uac8c \ud655\uc7a5\ud560 \uc218 \uc788\ub2e4.\\n\\n### \ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)\\n\\nQ. \uc5b4\ub5bb\uac8c \ud558\uba74 \ubcc0\uacbd\uc774 \ub2e4\ub978 \uc694\uc18c\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub3c4\ub85d \ubc29\uc9c0\ud560 \uc218 \uc788\uc744\uae4c?\\n\\nA. \ubcc0\ud654\uac00 \uc608\uc0c1\ub418\ub294 \uc9c0\uc810\uc744 \uc2dd\ubcc4\ud558\uace0, \uc8fc\uc704\uc5d0 \uc548\uc815\ub41c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ud615\uc131\ud558\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4.\\n\\n### \uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)\\n\\nQ. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc758 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud558\uace0 \uc2f6\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?\\n\\nA. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ub2e4\ub978 \uac1d\uccb4\ub97c \ub450\uc5b4 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud560 \uc218 \uc788\ub2e4.\\n\\n\uc911\uc7ac\uc790 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ud558\ub098\uc758 \uac1d\uccb4\ub97c \ucd94\uac00\ud558\uc5ec \ubcf5\uc7a1\ud55c \uad00\uacc4\ub97c \ub2e8\uc21c\ud654\ud560 \uc218 \uc788\ub2e4.\\n\\n\uc911\uac04\uc5d0 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub454\ub2e4\uba74 \ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)\uc5d0 \ud574\ub2f9\ub41c\ub2e4.\\n\\n### \uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)\\n\\nQ. \ucc45\uc784\uc744 \ud560\ub2f9\ud55c \ub3c4\uba54\uc778 \uac1d\uccb4\uac00 Low Coupling, High Cohesion, \uc7ac\uc0ac\uc6a9\uc131 \ub4f1\uc758 \ubaa9\uc801\uc744 \uc704\ubc18\ud55c\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?\\n\\nA. \ub3c4\uba54\uc778 \uac1c\ub150\uc744 \ud3ec\ud568\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uace0 \ub9e4\uc6b0 \uc751\uc9d1\ub41c \ucc45\uc784\uc744 \ud560\ub2f9\ud560 \uc218 \uc788\ub2e4.\\n\\n\ud589\ub3d9\uc744 \ucd94\uac00\ud560 \ub54c, \ud574\ub2f9 \ucc45\uc784\uc744 \uc218\ud589\ud560 \ub3c4\uba54\uc778 \uac1c\ub150\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \ub3c4\uba54\uc778\uacfc \ubb34\uad00\ud55c \uc778\uacf5\uc801\uc778 \uac1d\uccb4\ub97c \ub9cc\ub4e0\ub2e4\uc74c \ud574\ub2f9 \uac1d\uccb4\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4.\\n\\n\uac1d\uccb4\uac00 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud574\uc57c \ud560 \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4\uace0, \uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134\uc744 \uc801\uc6a9\ud558\uc5ec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud558\ub77c\ub294 \ucc45\uc784\uc744 \uac00\uc9c0\ub77c\uace0 \ud558\uc9c0 \uc54a\ub294\ub2e4.\\n\\n\uc608) \uc0c1\uc810\uacfc \uace0\uac1d \ud074\ub798\uc2a4\uac00 \uc788\uace0 \uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uace0 \uac00\uc815\\n\\n- \uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0 \uac70\ub798\ub97c \ud558\ub824\uba74 \ud658\uc804\uc744 \ud574\uc57c\ud55c\ub2e4.\\n- \ub450 \ud074\ub798\uc2a4 \ub2e4 \ud658\uc804\uc5d0 \ub300\ud55c \ucc45\uc784\uc744 \ubd80\uc5ec\ud558\uae30 \uc560\ub9e4\ud558\ub2e4\uba74 \ud658\uc804\uc744 \ucc45\uc784\ud558\ub294 \ud074\ub798\uc2a4\ub97c \ucd94\uac00\ud558\uace0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n\uc624\ube0c\uc81d\ud2b8 5\uc7a5. \ucc45\uc784 \ud560\ub2f9\ud558\uae30, [\uc870\uc601\ud638](http://aeternum.egloos.com/)\\n\\nApplying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman\\n\\n[GRASP, \ud55c\ube5b \ub124\ud2b8\uc6cc\ud06c](https://www.hanbit.co.kr/network/category/category_view.html?cms_code=CMS8586826397)"},{"id":"blackjack-retrospective","metadata":{"permalink":"/blackjack-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx","title":"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/java-blackjack/pull/427","date":"2023-03-14T00:00:00.000Z","formattedDate":"2023\ub144 3\uc6d4 14\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":5.17,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0","slug":"blackjack-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134","permalink":"/grasp"},"nextItem":{"title":"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0","permalink":"/ladder-retrospective"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/java-blackjack/pull/427 \\n2\ub2e8\uacc4: https://github.com/woowacourse/java-blackjack/pull/537 \\n:::\\n\\n### \ube14\ub799\uc7ad\\n\\n\ube14\ub799\uc7ad \ubbf8\uc158\uc5d0\uc11c\ub294 \ud6c4\ucd94\uc640 \ud398\uc5b4(\uc870\ubbf8\ub8cc \ub4c0\uc624?)\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4. \\n\uc774\ubc88\uc5d0\ub294 \uc2e4\uc218\ud558\uc9c0 \uc54a\uace0, \ubc14\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uc9c0 \uc54a\uace0 \uce5c\ud574\uc9c0\uae30 \ubd80\ud130 \uc2dc\uc791\ud588\ub2e4. \\n\\n\ube14\ub799\uc7ad\uc740 \uad6c\ud604\ud574\uc57c \ub420 \ub0b4\uc6a9\uc774 \ub9ce\uc544 \uc2dc\uac04\uc774 \ub9ce\uc774 \ubd80\uc871\ud560 \uac83 \uac19\uc558\uc9c0\ub9cc \\n\ud6c4\ucd94\uc640 \ud568\uaed8 \uc804\ub7b5\uc801(\uc0bc\uc77c\uc808\uc5d0 \ubbf8\uc158 \uc774\uc57c\uae30 \ub098\ub204\uae30)\uc73c\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud574 \uc2dc\uac04 \ub0b4\uc5d0 \uc81c\ucd9c\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n\ubbf8\uc158\uc744 \ub05d\ub098\uace0 \ud68c\uace0\ub97c \ud588\uc744 \ub54c \ud6c4\ucd94\uac00 \uace0\ubbfc\uac70\ub9ac\ub97c \ud558\ub098 \ub0b4\uc92c\ub2e4. \\n\\"\ud398\uc5b4\ub97c \uc9c4\ud589\ud560 \ub54c \uc555\ubc15\uac10\uc744 \ub290\ub07c\ub294 \ud398\uc5b4\uac00 \uc788\ub2e4\uba74 \ud5c8\ube0c\uac00 \ud574\uc904 \uc218 \uc788\ub294\uac8c \ubb50\uac00 \uc788\uc744\uae4c?\\" \\n\\n\uacf0\uacf0\ud788 \uc0dd\uac01\ud574\ubd24\uc9c0\ub9cc \uc27d\uac8c \ub2f5\uc744 \ub0b4\ub9b4 \uc218 \uc5c6\uc5c8\ub2e4. \\n\uc911\uac04 \uc911\uac04 \ud68c\uace0\ub97c \ud558\uace0, \ub098\uc758 \uc18c\ud504\ud2b8\uc2a4\ud0ac\uc744 \ub192\ud788\ub294\uac8c \ub2f5\uc77c\uae4c? \\n\ubd80\ub2f4\uac10\uc744 \ub290\ub07c\uc9c0 \uc54a\uace0 \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub420 \uc218 \uc788\ub3c4\ub85d \uacc4\uc18d \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4. \\n\\n\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc0dd\uac01\uc774 \ub9ce\uc544\uc838\uc11c \uc804 \ub9ac\ubdf0\uc5b4\uc778 \ud130\ud2c0\ud83d\udc22\uacfc\ub3c4 \ub300\ud654\ub97c \ub098\ub204\uc5c8\ub2e4. \\n\ud130\ud2c0\uc740 \uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84(\uad81\uadf9\uc801\uc778 \ubaa9\ud45c\uc778 \uc88b\uc740 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \uac83)\uc5d0 \uc9d1\uc911\ud574\ubcf4\ub77c\uace0 \ud558\uc168\ub2e4. \\n\\n\uc88b\uc740 \ucf54\ub4dc, \uc88b\uc740 \ud398\uc5b4\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc77c\ub2e8 \uc9c0\uc18d\uc801\uc73c\ub85c \uc0dd\uac01\ud574\ubd10\uc57c\uaca0\ub2e4.\\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n**\ud398\uc5b4 \uc2e0\uacbd\uc4f0\uae30** \\n\uc774\ubc88 \ud398\uc5b4\ud560 \ub54c \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub0b4\ubcf4\ub3c4\ub85d \ud588\ub2e4. \uadf8\ub807\uae30\uc5d0 \ub108\ubb34 \uc758\uacac\uc744 \uac15\ud558\uac8c \ubc00\uc5b4\ubd99\uc778 \ub290\ub08c\uc774 \ub4e4\uc5b4\uc11c \ubbf8\uc548\ud588\ub2e4. \\n\ud6c4\ucd94\uac00 \uc555\ubc15\uc744 \ub290\uaf08\uc744 \uc218\ub3c4 \uc788\uc744 \uac83 \uac19\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4. \\n\uc911\uac04 \uc911\uac04 \uc791\uc740 \ud68c\uace0\ub97c \uc9c4\ud589\ud574\ubcf4\ub294 \uac83\uc774 \uc88b\uc744\uae4c?\\n\\n**\uccb4\ub825 \uad00\ub9ac** \\n\uc694\uc998 \uc798 \ubabb\uba39\ub294 \uac83 \uac19\ub2e4. \\n\uc55e\uc73c\ub85c \uc0b4 \ub0a0\uc774 \ub9ce\uc740\ub370 \uc798 \ucc59\uaca8\uba39\uace0, \ud798\ub0b4\uc57c\uaca0\ub2e4.\\n\\n**\uc911\uac04 \uc911\uac04 \ub3cc\uc544\ubcf4\uae30** \\n\uc774\ubc88 \ubbf8\uc158\uacfc \uad00\ub828\ub41c \ub0b4\uc6a9\uc740 \uc544\ub2c8\uc9c0\ub9cc \uc6b0\ud14c\ucf54\ub97c \uc798 \ud65c\uc6a9 \ud558\uace0 \uc788\ub294\uc9c0 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4. \\n\ub0b4\uac00 \uc6b0\ud14c\ucf54\uc5d0 \uc9c0\uc6d0\ud55c \uc774\uc720\ub97c \ud56d\uc0c1 \uc78a\uc9c0 \uc54a\uc544\uc57c\uaca0\ub2e4. \\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**\uc0c1\ud0dc \ud328\ud134** \\n\uac1d\uccb4\uc758 \ub0b4\ubd80 \uc0c1\ud0dc\uc5d0 \ub530\ub77c \uc2a4\uc2a4\ub85c \ud589\ub3d9\uc744 \ubcc0\uacbd\ud558\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc73c\ub85c if/else/switch\uc640 \uac19\uc740 \uc870\uac74\ubb38\uc744 \ud6a8\uacfc\uc801\uc73c\ub85c \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. \\n\ube14\ub799\uc7ad \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c \uc0c1\ud0dc \ud328\ud134\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ucc98\uc74c \uc801\uc6a9\ud574\ubcf4\uc558\ub2e4. \\n\ucc98\uc74c \uc801\uc6a9\ud558\uae30 \uc804\uc5d0\ub294 \ubcc4\ub85c\ub77c\uace0 \uc0dd\uac01\ud588\ub294\ub370, \uc0dd\uac01\ubcf4\ub2e4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4. \\n\\n**\uc77c\uad00\uc131, \uac00\ub3c5\uc131, \ucd94\uc0c1\ud654** \\n\uc774\ubc88 \ub9ac\ubdf0\uc5b4\ub294 \uac80\ud504\ud83c\udf6b \uc600\ub2e4! \\n\uac80\ud504\uc758 \ub9ac\ubdf0\ub294 \uac04\uacb0\ud568\uc5d0 \uad00\ub828\ub41c \ub0b4\uc6a9\uc774 \ub9ce\uc558\ub2e4. \\n\uc77c\uad00\uc131\uc774 \uc788\ub294 \ucf54\ub4dc, \uac00\ub3c5\uc131\uc774 \uc88b\uc740 \ucf54\ub4dc, \ucd94\uc0c1\ud654\uac00 \uc798 \ub418\uc5b4\uc788\ub294 \ucf54\ub4dc \\n\uc77d\uae30 \uc88b\uace0, \uac04\uacb0\ud55c \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud558\ub294 \ubc29\ubc95\uc744 \ubc30\uc6b4 \uac83 \uac19\ub2e4. \\n\ucf54\ub4dc\ub97c \ubc14\ub77c\ubcf4\ub294 \uc2dc\uc810\uc774 \ud558\ub098 \ub298\uc5b4\ub09c \uae30\ubd84\uc774\ub2e4!(\uc55e\uc73c\ub85c \uc801\uc6a9\ud558\ub294 \uac83\uc740 \ub098\uc758 \ubaab\uc774\uc9c0\ub9cc) \\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n**\uc0dd\uac01 \uc815\ub9ac** \\n\uc911\uac04 \uc911\uac04 \ud604\uc7ac \uc0c1\ud669\uc5d0 \ub300\ud574 \uadf8\ub9bc\uc744 \uadf8\ub9ac\uac70\ub098, \uae00\uc744 \uc801\uc73c\uba74\uc11c \uc815\ub9ac\ud55c\ub2e4. \\n\ud398\uc5b4\uc640 \ub3d9\uc77c\ud55c \ubd80\ubd84\uc744 \uc774\ud574\ud558\uace0 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. \\n\uc9c4\ud589\ud558\ub294\ub370 \ub9e4\uc6b0 \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\ub098\ub3c4 \ub2e4\uc74c \ud398\uc5b4\ub54c\ubd80\ud130 \ud39c\uc774\ub791 \uc885\uc774\ub97c \uc900\ube44\ud574\uc57c\uaca0\ub2e4.\\n\\n**\uac00\uac10\uc5c6\uc774 \uc758\uacac\uc744 \ub9d0\ud574\uc8fc\ub294 \ubd80\ubd84** \\n\uc9c4\ud589 \uc0c1\ud669\uc5d0 \ub300\ud55c \ubd80\ubd84, \uc9c4\ud589 \uc18d\ub3c4, \uc9c0\uae08 \uc790\uc2e0\uc774 \uc774\ud574\ud558\uace0 \uc788\ub294 \ubd80\ubd84\uc744 \ub9d0\ud574\uc918\uc11c \ud3b8\ud588\ub2e4. \\n\ud68c\uace0\ub54c\ub3c4 \uc11c\ub85c \uc194\uc9c1\ud558\uac8c \uc758\uacac\uc744 \uc8fc\uace0 \ubc1b\uc544\uc11c \uc88b\uc558\ub2e4. \\n\\n**\ub3c4\uba54\uc778 \uc5b8\uc5b4\uc5d0 \uc2e0\uacbd\uc4f0\ub294 \ubd80\ubd84** \\n\ud074\ub798\uc2a4\uba85, \ubcc0\uc218\uba85\uacfc \uac19\uc740 \uc5b8\uc5b4\ub97c \uc138\uc2ec\ud558\uac8c \uc2e0\uacbd\uc4f4\ub2e4. \\n\uc694\uad6c\uc0ac\ud56d \uc815\ub9ac\ub3c4 \uae54\ub054\ud558\uac8c \uc798\ud558\ub294 \uac83 \uac19\ub2e4. \\n\\n\ud6c4\ucd94 \ucd5c\uace0 \ud83d\udc4d"},{"id":"ladder-retrospective","metadata":{"permalink":"/ladder-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/java-ladder/pull/97","date":"2023-02-26T00:00:00.000Z","formattedDate":"2023\ub144 2\uc6d4 26\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":10.285,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0","slug":"ladder-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0","permalink":"/blackjack-retrospective"},"nextItem":{"title":"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0","permalink":"/racing-car-retrospective"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/java-ladder/pull/97 \\n2\ub2e8\uacc4: https://github.com/woowacourse/java-ladder/pull/234 \\n:::\\n\\n### \uc0ac\ub2e4\ub9ac \ud0c0\uae30\\n\\n\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc6b0\uac00\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4. \\n\uc774\uc804 \ubbf8\uc158\uacfc \ub2ec\ub9ac TDD\ub85c \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ud544\uc218\uc600\uae30 \ub54c\ubb38\uc5d0 \uc775\uc219\ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, \uc6b0\uac00\uc640 \ubbf8\uc158\uc5d0 \uad00\ud55c \uc18c\ud1b5\uc774 \uc798 \ub418\uc5b4\uc11c \ud070 \ubb38\uc81c \uc5c6\uc774 \ubbf8\uc158\uc744 \ub9c8\ubb34\ub9ac\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\\n\uc6b0\uac00\uc640 \uc774\uc57c\uae30\uac00 \uc798 \ud1b5\ud574\uc11c \uadf8\ub7f0\uc9c0 1\ub2e8\uacc4\ub294 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub294\ub370, 2\ub2e8\uacc4\uc5d0\uc11c \ub9ce\uc774 \uace0\uc804\ud55c \uac83 \uac19\ub2e4.\\n\\n2\ub2e8\uacc4\uc5d0\uc11c\ub294 2\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ud574\ubd24\ub2e4.\\n\\n1. LadderGame\uc5d0\uc11c Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\\n2. Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c Ladder\uc5d0\uac8c Position\uc744 \ub118\uaca8\uc8fc\uba70 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95\\n\\n### Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\\n\\n\uc0ac\uc2e4\uc0c1 index\ub97c Ladder\uc5d0\uac8c \ub118\uaca8\uc8fc\uace0, \ud574\ub2f9 index\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc1b\ub294 \ubc29\ubc95\uacfc \uc720\uc0ac\ud588\ub2e4. \\n\uad6c\ud604\ud558\uace0 \ub098\ub2c8 \ub2e4\ub978 \ud074\ub798\uc2a4\ub4e4\uc774 Position\uc5d0 \ub300\ud55c \uc758\uc874\ub3c4\uac00 \ub108\ubb34 \ub192\uc740 \uac83 \uac19\uc558\ub2e4. \\n\ub610\ud55c Players\uac00 \ubcc4\ub2e4\ub978 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uc9c0 \uc54a\ub2e4\uace0 \ub290\uaf08\ub2e4. \\n\\n```mermaid\\ngraph TD\\n\\n LadderGameController --\x3e LadderGame\\n LadderGame --\x3e Ladder\\n LadderGame --\x3e Players\\n LadderGame --\x3e Items\\n\\n Ladder --\x3e Line\\n Line --\x3e LineStatus\\n\\n LadderGame --\x3e Position\\n Ladder --\x3e Position\\n Items --\x3e Position\\n Line --\x3e Position\\n Players --\x3e Position\\n\\n LadderGame --\x3e LadderGameResult\\n\\n Items --\x3e Item\\n Players --\x3e Player\\n\\n LadderGameController --\x3e InputView\\n LadderGameController --\x3e OutputView\\n\\n```\\n\\n```java\\npublic LadderGameResult play() {\\n final Map<Player, Item> result = new LinkedHashMap<>();\\n // \uc0ac\uc6a9\uc790 \uc218\ub9cc\ud07c Position\uc744 \uac00\uc838\uc640\uc11c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4.\\n for (Position position : Position.range(players.count())) {\\n final Position resultPosition = ladder.play(position);\\n result.put(players.get(position), items.get(resultPosition));\\n }\\n return new LadderGameResult(result);\\n}\\n```\\n\\n### Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\\n\\nPosition\uc5d0 \ub300\ud55c \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub294 Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c, Player\uac00 Ladder\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4. \\n\uc774 \ubc29\ubc95\uc774 \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc704\ud574\uc11c \uac1d\uccb4\ub4e4\uc774 \uae34\ubc00\ud558\uac8c \ud611\ub825\ud558\uace0, \uc870\uae08 \ub354 \ucc45\uc784\uc758 \ubd84\ubc30\uac00 \uc798 \ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\uc774 \ub418\uc5c8\ub2e4. \\n\\n```mermaid\\ngraph TD\\n\\n LadderGameController --\x3e LadderGame\\n LadderGame --\x3e Ladder\\n LadderGame --\x3e Players\\n LadderGame --\x3e Items\\n\\n Ladder --\x3e Line\\n Line --\x3e LineStatus\\n Line --\x3e Position\\n\\n Players --\x3e Ladder\\n Player --\x3e Ladder\\n\\n Item --\x3e Position\\n Player --\x3e Position\\n\\n\\n LadderGame --\x3e LadderGameResult\\n\\n Items --\x3e Item --\x3e ItemName\\n Players --\x3e Player --\x3e PlayerName\\n\\n LadderGameController --\x3e InputView\\n LadderGameController --\x3e OutputView\\n\\n OutputView --\x3e LadderMessageGenerator\\n```\\n\\n```java\\npublic LadderGameResult play() {\\n // \ucc38\uac00\uc790\ub4e4\uc5d0\uac8c \uc0ac\ub2e4\ub9ac\ub97c \uc804\ub2ec\ud574\uc11c \uc0ac\ub2e4\ub9ac\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \ud55c\ub2e4.\\n final Map<Player, Position> playResult = players.play(ladder);\\n\\n final Map<Player, Item> result = new LinkedHashMap<>();\\n for (Player player : playResult.keySet()) {\\n result.put(player, toItem(playResult.get(player)));\\n }\\n return new LadderGameResult(result);\\n}\\n```\\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n**\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\uc5d0 \uc2dc\uac04\uc744 \ub4e4\uc774\uae30** \\n\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc815\ud558\ub294\ub370 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ub4e4\uc5ec\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uc0ac\ub2e4\ub9ac \ud0c0\uae30\uc758 \uc2e4\ud589 \uacb0\uacfc\ub97c Item\uc73c\ub85c \uc9d3\ub2e4\ub2c8.. \ubb54\uac00 \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\ub2e4. \\n\uc774\uc804 \ubbf8\uc158\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c, \uba85\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \ubd80\uc871\ud568\uc744 \ub9ce\uc774 \ub290\uaf08\ub2e4. \\n\\n**\ud398\uc5b4\uc640 \uc870\uae08 \ub354 \uce5c\ud574\uc9c0\uae30** \\n\uccab\ub0a0\uc740 \ud398\uc5b4\uc640 \uce5c\ud574\uc9c0\ub294 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \uac00\uc838\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uc6b0\uac00\ub791 \ud68c\uace0\ud560 \ub54c \ub0b4\uac00 \uc2dc\uc791\ud558\uc790\ub9c8\uc790 \ucee8\ubca4\uc158 \uc815\ud558\uc790\uace0 \ud574\uc11c \ub9ce\uc774 \ub2f9\ud669\uc2a4\ub7ec\uc6e0\ub2e4\uace0 \ud55c\ub2e4. \uc6b0\uac00 \ubbf8\uc548.. \ud83e\udd72\\n\\n**README\ub97c \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c** \\n\uc774\uc0c1\ud558\uac8c \ucf54\ub529\uc5d0 \uc9d1\uc911\ud558\uba74 README\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\uba74\uc11c \uac19\uc774 \ucee4\ubc0b \ud558\ub294 \uac78 \ud56d\uc0c1 \uae4c\uba39\ub294\ub2e4. \\n\ub2e4\uc74c \ubbf8\uc158\uc5d0\ub294 \uc870\uae08 \ub354 \uc2e0\uacbd \uc368\uc57c\uaca0\ub2e4.\\n\\n**\uc88b\uc740 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud558\uae30** \\n\uccab PR\ub54c \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \uc9c8\ubb38\uc744 \ub0a8\uae30\uc9c0 \ubabb\ud588\ub2e4. \\n\ub9ac\ubdf0\uc5b4\uc640\uc758 \uc2dc\uac04\uc774 \uc18c\uc911\ud55c \uc2dc\uac04\uc774\ub77c\ub294 \uac83\uc744 \uae4c\uba39\uc9c0 \ub9d0\uace0, \ub098\uc758 \uc131\uc7a5\uc5d0 \ub3c4\uc6c0\uc774 \ub420 \uc218 \uc788\ub294 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud574\uc57c\uaca0\ub2e4. \\n\\n**PR \ud6c4\uc5d0\ub3c4 \uaf3c\uaf3c\ud558\uac8c \ud655\uc778\ud558\uae30** \\n\ubd84\uba85 \uc54c\uace0 \uc788\ub294 \ubd80\ubd84\uc774\uc9c0\ub9cc, \ub193\uce5c \ubd80\ubd84\uc774 \ub9ce\uc740 \uac83 \uac19\uc558\ub2e4. \\nPR \ud558\uae30 \uc804\uc5d0\ub3c4 \uacc4\uc18d \ud655\uc778\uc744 \ud588\uc9c0\ub9cc, \uc544\ubb34\ub798\ub3c4 IntelliJ\uc5d0\uc11c \ubcf4\ub2c8 \ucf54\ub4dc\uc5d0 \uc775\uc219\ud574\uc838\uc11c \uadf8\ub7f0\uc9c0 \ubcc0\uacbd\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc798 \uc548\ubcf4\uc600\ub2e4. \\ngithub pr\uc5d0\uc11c\ub294 \uc804\uccb4 \ubcc0\uacbd\uc0ac\ud56d\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc73c\ub2c8 PR \ud6c4\uc5d0\ub3c4 \uaf2d \ud655\uc778\ud574\uc57c\uaca0\ub2e4.\\n\\n**\uc801\uadf9\uc801\uc73c\ub85c \ub098\uc758 \uc758\uacac\uc744 \ub9d0\ud558\uae30** \\n\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ud398\uc5b4\uc758 \uc758\uacac\uc774 \uad1c\ucc2e\ub2e4\uace0 \uc0dd\uac01\ud558\uba74 \uc218\uc6a9 \ud6c4 \uac1c\uc120\uc744 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\uc5c8\ub294\ub370, \uc870\uae08 \ub354 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ud5a5\uc774 \uc788\ub2e4\uba74 \ub098\ub3c4 \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub9d0\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\uc774 \ub4e0\ub2e4. \\n\ub098\ub3c4 \uc124\ub4dd\ud558\ub294 \ud798\uc744 \uae30\ub974\uace0, \ud398\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc744 \uc54c \uc218 \uc788\uace0, \uacb0\uacfc\ubb3c\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub098\uc624\uc9c0 \uc54a\uc744\uae4c? (\uace0\ubbfc \ub4e4\uc5b4\uc8fc\uc2e0 \ub9ac\ubdf0\uc5b4 \ud130\ud2c0\ud83d\udc22 \uac10\uc0ac\ud569\ub2c8\ub2e4.)\\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**\uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784** \\nPlayers\uac00 Position\uc744 \uc0dd\uc131\ud558\uace0 Player\uc758 \uc0dd\uc131\uc790\uc5d0 \ub123\uc5b4\uc8fc\uc5c8\ub2e4. \ud558\uc9c0\ub9cc \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ub828\ub41c \ucf54\uba58\ud2b8\uac00 \ub2ec\ub838\ub2e4.\\n\uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uc0dd\uac01\ud574 \ubcf4\ub2c8 Position\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uac74 Player\uae30 \ub54c\ubb38\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 Player\uac00 \ub2f4\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4. \\n\\n\uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud55c \ud328\ud134\uc73c\ub85c GRASP\uc758 Creator \ud328\ud134\uc774 \uc788\ub294\ub370 \ub2e4\uc74c\uc758 \uc694\uc18c\ub97c \ucd5c\ub300\ud55c \ub9cc\uc871\ud558\ub294 \ud074\ub798\uc2a4\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \\n- B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4.\\n- B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4.\\n- B\uac00 A\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4.\\n- B\uac00 A\uc758 \ucd08\uae43\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4. \\n\\n\uc2e4\uc81c\ub85c \uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud574\uc11c \uae4a\uc774 \uc0dd\uac01\ud558\uba74\uc11c \ucf54\ub529\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc2dc\uc57c\uac00 \ub113\uc5b4\uc9c4 \uac83 \uac19\ub2e4.\\n\\n**\ud328\ud0a4\uc9c0 \ubd84\ub9ac \uae30\uc900** \\n\ud328\ud0a4\uc9c0 \ubd84\ub9ac\uc5d0 \ub300\ud55c \ub098\ub9cc\uc758 \uae30\uc900\uc774 \uc544\uc9c1 \uba85\ud655\ud558\uc9c0 \uc54a\uc544 \uc9c8\ubb38\uc774 \ub4e4\uc5b4\uc640\ub3c4 \uba85\ud655\ud558\uac8c \ub2f5\ubcc0\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4. \\n\ub9c8\uc9c0\ub9c9 \uc81c\ucd9c \uc804\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub97c \ubd84\ub9ac\ud574 \ubd24\ub294\ub370, \uae30\uc900\uc774 \uba85\ud655\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \uc88b\uc9c0 \uc54a\uc740 \uc120\ud0dd\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.\\n\ud604\uc7ac \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud06c\uae30\uac00 \uadf8\ub807\uac8c \ud06c\uc9c0 \uc54a\uc73c\ub2c8, domain \ud328\ud0a4\uc9c0\uc5d0\uc11c \uc138\ubd80 \ud328\ud0a4\uc9c0\ub85c \ubd84\ub9ac\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub420 \uac83 \uac19\ub2e4. \\n\\n**\uc0ac\uc6a9\ud558\ub294 \ucabd\uc5d0\uc11c \uc0dd\uac01\ud558\uae30 & \uc608\uce21\uac00\ub2a5\ud55c \ucf54\ub4dc \uc791\uc131\ud558\uae30** \\nPosition\uc5d0\uc11c \ub2e4\uc74c \uc704\uce58\ub098 \uc774\uc804 \uc704\uce58\ub97c \ubc18\ud658\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud5c8\uc6a9 \ubc94\uc704(0~19)\uac00 \ubc97\uc5b4\ub09c\ub2e4\uba74, \uc758\ubbf8 \uc5c6\ub294 \uac12\uc774 \ub4e4\uc5b4\uac04 Position\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud588\ub2e4. \\n\uc774\uac74 Position\uc744 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc744 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \ucf54\ub529\uc774\uc5c8\ub294\ub370, \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 0~19\uc758 \uac12\uc774 \ubcf4\uc7a5\ub418\uc5b4 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uac83\uc774\uae30 \ub54c\ubb38\uc774\ub2e4. \\n\ub530\ub77c\uc11c hasNext, hasPrevious\ub77c\ub294 \uc774\uc804 \uac12, \uc774\ud6c4 \uac12\uc774 \ubc94\uc704 \ub0b4\uc5d0 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ucd94\uac00\ud558\uace0, \uae30\uc874\uc758 \uac12\uc744 \uac00\uc838\uc624\ub294 \uba54\uc11c\ub4dc\ub294 \ubc94\uc704\uac00 \ubc97\uc5b4\ub098\uba74 \uc608\uc678\ub97c \ub358\uc9c0\ub294 \ubc29\ud5a5\uc73c\ub85c \ud574\uacb0\ud558\uc600\ub2e4. \\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n\ubc1d\uc740 \uae30\uc6b4\uc744 \uac00\uc9c0\uace0 \uc788\uace0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \uce5c\ud654\ub825\uc774 \uc88b\uc740 \uac83 \uac19\uc558\ub2e4. \\n\uc774\ubc88\uc5d0 \ud398\uc5b4 \ud560 \ub54c \ucee8\ub514\uc158 \uad00\ub9ac\ub97c \uc81c\ub300\ub85c \ubabb\ud574\uc11c \ub9ce\uc774 \ubbf8\uc548\ud588\ub2e4. \ub2e4\uc74c\uc5d0\ub294 \ucd5c\uc0c1\uc758 \ucee8\ub514\uc158\uc73c\ub85c \ud398\uc5b4\ub97c \uc900\ube44\ud574 \ubd10\uc57c\uaca0\ub2e4. \\n\uadf8\ub9ac\uace0 \uc6b0\uac00\ub791 \ud398\uc5b4\ub97c \ud558\uace0 \ub098\uc11c, \ub098\ub3c4 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \ub354 \uc798 \uc9c0\ub0b4\ubd10\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5b4 \uc870\uae08 \ub354 \uc6a9\uae30\ub97c \ub0b4 \uc7a1\ub2f4 \uc911\uc774\ub2e4! \\n\\n\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589\uc774 \uc798 \ub418\uc5c8\ub2e4. \\n\ub610\ud55c \ud398\uc5b4 \uc9c4\ud589\uc774 \ub290\ub9b0 \uac83 \uac19\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c \uc548\uc815\uc801\uc73c\ub85c \uc2dc\uac04 \uc548\uc5d0 \ubbf8\uc158\uc744 \uc644\ub8cc\ud560 \uc218 \uc788\uc5c8\ub2e4. \\n\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589 \uc18d\ub3c4\uc5d0 \ub300\ud574 \uc870\uae08 \ub354 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4!\\n\\n\ud56d\uc0c1 \uc9c0\ub098\uac08 \ub54c\ub9c8\ub2e4 \uc6c3\uc5b4\uc8fc\ub294\ub370, \ub098\ub3c4 \uc790\uc8fc \uc6c3\uc5b4\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\uc6c3\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uc0ac\ub78c\uc774 \ubc1d\uc544 \ubcf4\uc5ec\uc11c \ub108\ubb34 \uc88b\uc740 \uac83 \uac19\ub2e4!"},{"id":"racing-car-retrospective","metadata":{"permalink":"/racing-car-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx","title":"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0","description":"1\ub2e8\uacc4//github.com/woowacourse/java-racingcar/pull/510","date":"2023-02-14T00:00:00.000Z","formattedDate":"2023\ub144 2\uc6d4 14\uc77c","tags":[{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse"},{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":7.625,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0","slug":"racing-car-retrospective","tags":["Woowahan Techcourse","Retrospective"]},"unlisted":false,"prevItem":{"title":"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0","permalink":"/ladder-retrospective"},"nextItem":{"title":"Parameterized Tests","permalink":"/parameterized-tests"}},"content":":::note PR \ub9c1\ud06c \\n1\ub2e8\uacc4: https://github.com/woowacourse/java-racingcar/pull/510 \\n2\ub2e8\uacc4: https://github.com/woowacourse/java-racingcar/pull/538 \\n:::\\n\\n### \uc790\ub3d9\ucc28 \uacbd\uc8fc\\n\\n\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158\uc5d0\uc11c\ub294 \ub2e4\uc990\uacfc \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4. \\n\uc6b0\ud14c\ucf54 \ub4e4\uc5b4\uc640\uc11c \uccab \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\uc774\ub77c \ub9ce\uc774 \ub5a8\ub838\uc9c0\ub9cc, \ub2e4\uc990\uc774 \ub300\ud654\ub97c \uc798 \uc774\ub04c\uc5b4\uc918 \ub108\ubb34 \uc990\uac70\uc6e0\ub2e4. \\n\\n\uccab\ub0a0\uc740 \uac04\ub2e8\ud788 \ucee8\ubca4\uc158\uacfc \ud658\uacbd\uc744 \uc124\uc815\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc84c\uace0 \ub2e4\uc74c \ub0a0\ubd80\ud130 \uc790\ub3d9\ucc28 \uacbd\uc8fc\ub97c \uc2dc\uc791\ud588\ub2e4. \\n\uc2dc\uc791\uc740 \uac04\ub2e8\ud558\uac8c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud558\uace0, \uc5b4\ub5bb\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud560\uc9c0 \uac19\uc774 \uace0\ubbfc\ud588\ub2e4. \\n\\n\uc2dc\uc791\ud558\uae30 \uc804 \uc544\ub798\uc640 \uac19\uc774 mermaid\ub97c \uc774\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc5d0 \ub300\ud574\uc11c \uac04\ub2e8\ud55c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uace0 \uc2dc\uc791\ud588\ub2e4. \\nmermaid\ub294 \ucf54\ub4dc\ub85c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \uc0dd\uc131 \ud574\uc8fc\ub294 \ub3c4\uad6c\ub85c \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc774 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.\\n\\n- \ucf54\ub4dc \uae30\ubc18\uc774\ub77c \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \uc0dd\uac01\ud55c \uac83\uc744 \uc2dc\uac01\ud654\ud560 \uc218 \uc788\ub2e4. \\n- github\uc5d0\uc11c mermaid\ub97c \uc9c0\uc6d0\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \ucf54\ub4dc\ub97c \uc774\ud574\ud560 \uc218 \uc788\ub294 \ubd80\uac00\uc801\uc778 \uc815\ubcf4\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.\\n\\n```mermaid\\n---\\ntitle: \uc790\ub3d9\ucc28 \uacbd\uc8fc \uccab \ub9ac\ubdf0 \uc694\uccad\uc2dc \uad6c\uc870\\n---\\ngraph TD\\n Cars --\x3e Car\\n Car --\x3e Name\\n Car --\x3e Position\\n RacingGame --\x3e Count\\n RacingGame --\x3e NumberGenerator\\n RacingGame --\x3e Cars\\n RacingCarController --\x3e RacingGame\\n RandomNumberGenerator -.-> NumberGenerator\\n RacingCarController --\x3e InputView\\n InputView --\x3e InputValidator\\n RacingCarController --\x3e OutputView\\n```\\n\\n\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \ub370 \ud070 \uc5b4\ub824\uc6c0\uc774 \uc788\uc9c0\ub294 \uc54a\uc558\uace0, \ud398\uc5b4\ub97c \ub9c8\uce58\uae30 \uc804 \uc11c\ub85c \uace0\ubbfc\ub418\ub294 \ubd80\ubd84\uc744 \uc815\ub9ac\ud588\uc744 \ub54c \uc88b\uc558\ub2e4.\\n\\n\ud398\uc5b4\ud558\uba74\uc11c \uc798\ud588\ub2e4\uace0 \uc0dd\uac01\ud588\ub358 \uc810\uc740 \uc11c\ub85c\uc758 \uc0dd\uac01\uacfc \ub9ac\ubdf0 \ubc1b\uc740 \uac83\uc744 \uacf5\uc720\ud55c \uac83\uc774\ub2e4. \\n\ub9ac\ud329\ud130\ub9c1\uc744 \uc5b4\ub5bb\uac8c \ud588\ub294\uc9c0? \uc774\ub7f0 \ub9ac\ubdf0\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \uc0dd\uac01\ud558\ub294\uc9c0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c8 \uc218 \uc788\uc5c8\ub2e4.\\n\\n### \ubd80\uc871\ud588\ub358 \ubd80\ubd84\\n\\n\ub9ac\ud329\ud130\ub9c1\uc774 \ub05d\ub09c \ud6c4 \uba54\uc11c\ub4dc\uba85, \ud14c\uc2a4\ud2b8\uc2dc \ucd9c\ub825\ud558\ub294 \uba54\uc2dc\uc9c0\uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\uac00 \ub9ce\uc774 \ub2ec\ub838\ub2e4. \\n\uac1d\uccb4\uac00 \uc5b4\ub5a4 \ucc45\uc784\uacfc \uc5ed\ud560\uc744 \uac00\uc9c0\ub294\uc9c0 \uc0dd\uac01\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uba85\ud655\ud55c \uba54\uc11c\ub4dc\uba85\uc744 \uc791\uc131\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. \\n\\n\ud3c9\uc18c\uc5d0 \ud504\ub85c\uadf8\ub798\ubc0d \uc774\uc57c\uae30\uac00 \uc544\ub2cc \ub2e4\ub978 \uc8fc\uc81c\ub85c \uc774\uc57c\uae30\ud558\uba74 \uc798 \ub4e4\uc73c\ub824\uace0 \ud558\ub294 \ud3b8\uc774\uc9c0\ub9cc \\n\ub0b4\uac00 \uc88b\uc544\ud558\ub294 \uc8fc\uc81c, \uad00\uc2ec\uac00\ub294 \uc8fc\uc81c\uc778 \ud504\ub85c\uadf8\ub798\ubc0d\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub97c \ud560 \ub550 \ub9d0\uc774 \ub9ce\uc544\uc9c4\ub2e4. \\n\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130\ub294 \ub354 \ub9ce\uc740 \uc2dc\uac04\uc744 \ud398\uc5b4\uc758 \uc758\uacac\uacfc \uc774\uc57c\uae30\ub97c \ub4e3\ub294 \uacf3\uc5d0 \uc0ac\uc6a9\ud574\uc57c\uaca0\ub2e4.\\n\\n### \uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84\\n\\n**Assertions extracting**\\n\\n\uacb0\uacfc \ub0b4\ubd80\uc5d0 \uc788\ub294 \uac12\uc744 \ud655\uc778\ud558\uace0 \uc2f6\uc744 \ub54c extracting \ud0a4\uc6cc\ub4dc\ub97c \uc774\uc6a9\ud574\uc11c \ub0b4\ubd80\uc758 \uac12\uc744 \uac80\uc99d\ud560 \uc218 \uc788\ub2e4. \\n\uc774\uc804\uc5d0\ub294 \ud544\uc694\uc5d0 \ub530\ub77c stream\uc744 \uc774\uc6a9\ud558\uc5ec \uac80\uc99d\ud560 \uac12\uc744 \uc0dd\uc131\ud588\uc9c0\ub9cc, \ud574\ub2f9 \ubc29\ubc95\uc744 \uc774\uc6a9\ud574\uc11c \uc808\ucc28\ub97c \uc904\uc77c \uc218 \uc788\uc5c8\ub2e4.\\n\\n```java\\n@Test\\nvoid extracting() {\\n final Cars cars = new Cars(List.of(\\"car1\\", \\"car2\\"));\\n\\n assertThat(cars.getCars())\\n .extracting(Car::getName)\\n .containsExactly(\\"car1\\", \\"car2\\");\\n}\\n```\\n\\n---\\n\\n\uc544\ub798\ub294 \ub9ac\ubdf0\uc5b4\ub2d8\uacfc \ub300\ud654\ub97c \ub098\ub204\uba74\uc11c \uc5bb\uc740 \ub2f5\ubcc0 + \ub098\uc758 \uc758\uacac\uc774\ub2e4.\\n\\n**\uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8**\\n\\n\ud14c\uc2a4\ud2b8 \ub300\uc0c1\uc774 \uac80\uc99d\ub41c \uac83\uc774\ub77c\uba74 \uc791\uc131\ud558\uc9c0 \uc54a\uac70\ub098, \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uc791\uc131\ud55c\ub2e4. \\n\uc774\uac74 \uac1c\uc778\uc801\uc778 \uc0dd\uac01\uc774\uc9c0\ub9cc \ub0b4\uac00 \uc548\uc815\uac10\uc774 \ub4e4 \uc218 \uc788\uc744 \uc815\ub3c4\ub85c \ucd9c\ub825 \ubc94\uc704 \ub0b4\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud558\ub294\uc9c0 \uc815\ub3c4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?\\n\\n**\ub2e8\uc21c \uc704\uc784\uc744 \ud558\ub294 \uba54\uc11c\ub4dc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8**\\n\\n\uc704\uc784\uc774\ub77c\ub294 \uac83\uc740 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \ub118\uaca8\uc900\ub2e4\ub294 \uac83\uc774\ub2e4. \\n\ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc99d\ud558\ub294 \uac83\ubcf4\ub2e4 \uacb0\uacfc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. \\n\ub2e8\uc21c\ud788 \uc704\uc784\ub9cc \ud558\ub294 \ud14c\uc2a4\ud2b8\uc758 \uacbd\uc6b0 \uacb0\uacfc\ub97c \uac80\uc99d\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8\uac00 \uc911\ubcf5\ub418\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4. \\n\ub530\ub77c\uc11c \uc911\ubcf5\ub41c \ud14c\uc2a4\ud2b8\ub97c \uc904\uc774\uae30 \uc704\ud574 \ub0b4\ubd80\uc758 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0 \uac80\uc99d\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\ub294 \uac83\uc744 \uc54c\uac8c \ub418\uc5c8\uc9c0\ub9cc \\n\uc548\uc815\uc801\uc73c\ub85c \uacb0\uacfc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc778 \uac83 \uac19\ub2e4.\\n\\n**\ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c getter \uc0ac\uc6a9**\\n\\n\ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\ub85c \ub3c4\uba54\uc778\uc5d0 \uc0c8\ub85c\uc6b4 \uba54\uc11c\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc740 \uc88b\uc9c0 \ubabb\ud558\ub2e4. \\n\ud544\uc694\uc758 \uacbd\uc6b0 \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc9c0\ub9cc, \uae30\uc874\uc5d0 \uc788\ub294 \uba54\uc11c\ub4dc\ub4e4\uc744 \ud65c\uc6a9\ud574\ubcf4\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4. \\n\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub9e4\uc6b0 \ub3d9\uc758\ud558\uace0, \uc55e\uc73c\ub85c\ub3c4 \ucd5c\ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \ucf54\ub4dc\ub97c \ub3c4\uba54\uc778\uc5d0 \uc791\uc131\ud558\uc9c0 \uc54a\uc744 \uac83 \uac19\ub2e4.\\n\\n### \ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84\\n\\n\uc9c8\ubb38\uc774\ub098 \uc0dd\uac01\ud560 \uc810\uc774 \uc788\uc744 \ub54c \ub9e4\uc6b0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uac83 \uac19\uc558\ub2e4. \\n\uc0dd\uac01\uc744 \uc815\ub9ac\ud55c \ud6c4 \uc790\uc2e0\uc758 \uc758\uacac\uc744 \uba85\ub8cc\ud558\uac8c \uc804\ub2ec\ud574\uc8fc\uc5c8\ub2e4. \\n\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc2dd\uc744 \ud6a8\uc728\uc801\uc73c\ub85c \uc2b5\ub4dd\ud55c\ub2e4. \\n\ub09c \uc0dd\uac01\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc740 \ucc44\ub85c \ub0b4\ubc84\ub824 \ub454 \uc595\uc740 \uc9c0\uc2dd\uc774 \ub9ce\uc740 \uac83 \uac19\ub2e4. (\uc774\ub7f0 \uac83\ub3c4 \uc544\ub294 \uac83\uc774\ub77c\uace0 \ud560 \uc218 \uc788\uc744\uae4c?) \\n\uc55e\uc73c\ub85c \uc870\uae08 \ub354 \uba38\ub9bf\uc18d\uc5d0\uc11c \uc815\ub9ac\ud558\uace0, \ubb38\uc81c\uc5d0 \ub300\ud574 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \ub298\ub824\uc57c\uaca0\ub2e4.\\n\\n\uac1c\ubc1c\uc5d0 \uc5f4\uc815\uc744 \uac00\uc9c4 \uac8c \ub290\uaef4\uc9c4\ub2e4. \\n\ub098\ub3c4 \uac1c\ubc1c\uc744 \uc88b\uc544\ud558\uc9c0\ub9cc, \ucd5c\uadfc\uc5d0\ub294 \uc758\uc9c0\uac00 \uc57d\ud574\uc84c\uc5c8\ub2e4. \\n\uc5f4\uc815\uc774 \uac00\ub4dd\ud55c \uc0ac\ub78c\uc744 \ub9cc\ub098\ub2c8 \ub098\ub3c4 \uc5f4\uc815\uc801\uc778 \uc0ac\ub78c\uc774 \ub418\ub294 \uac83 \uac19\ub2e4.\\n\\n\uce6d\ucc2c\uc744 \ub9ce\uc774 \ud574\uc900\ub2e4. \ub2e8\uc21c\ud788 \ub9ce\uc774 \ud574\uc8fc\ub294 \uac83\uc774 \uc544\ub2c8\ub77c, \uc9c4\uc2ec\uc744 \ub2f4\uae34 \uce6d\ucc2c\uc744 \ud574\uc92c\ub2e4. \\n\uce6d\ucc2c\uc740 \uace0\ub798\ub3c4 \ucda4\ucd94\uac8c \ud558\ub358\uac00? \\n\uadf8\ub798\uc11c \uc990\uac70\uc6b4 \ub9c8\uc74c\uc73c\ub85c \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud588\uc5c8\ub358 \uac83 \uac19\ub2e4.\\n\\n\uc5b4\ub5a4 \uc774\uc720 \ub54c\ubb38\uc778\uc9c0 \ubaa8\ub974\uaca0\uc9c0\ub9cc \uac19\uc774 \ud398\uc5b4\ud558\ub294\ub370 \ud3b8\ud55c \ub9c8\uc74c\uc774 \ub4e4\uc5c8\ub2e4. \\n\uc774\uac74 \ubc14\ub85c \ubc30\uc6b8 \uc218 \uc5c6\uc9c0\ub9cc. \\n\ub098\ub3c4 \uac19\uc774 \uc77c\ud560 \ub54c \ud3b8\ud55c \uc0ac\ub78c, \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub418\uae30 \uc704\ud574 \uae4a\uc774 \uace0\ubbfc\ud574\ubd10\uc57c\uaca0\ub2e4."},{"id":"parameterized-tests","metadata":{"permalink":"/parameterized-tests","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-12-Parameterized Tests.mdx","source":"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx","title":"Parameterized Tests","description":"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4.","date":"2023-02-12T00:00:00.000Z","formattedDate":"2023\ub144 2\uc6d4 12\uc77c","tags":[{"label":"Java","permalink":"/tags/java"}],"readingTime":3.17,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Parameterized Tests","slug":"parameterized-tests","tags":["Java"]},"unlisted":false,"prevItem":{"title":"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0","permalink":"/racing-car-retrospective"},"nextItem":{"title":"IntelliJ \uc124\uc815","permalink":"/intellij-settings"}},"content":"\ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud558\ub2e4\ubcf4\uba74 \ub9e4\uac1c\ubcc0\uc218\uc5d0 \ub530\ub77c \ubc18\ubcf5\uc774 \ub418\ub294 \ud14c\uc2a4\ud2b8\ub4e4\uc774 \uc0dd\uae34\ub2e4. \\n\uc774 \ub54c `@ParameterizedTest`\ub97c \uc0ac\uc6a9\ud558\uba74 \ub2e8\uc77c \ud14c\uc2a4\ud2b8\ub97c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc5ec\ub7ec \ubc88 \ubc18\ubcf5\ud560 \uc218 \uc788\ub2e4.\\n\\n## Argument Sources\\n\\n`@ParameterizedTest`\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \ucd5c\uc18c \ud558\ub098 \uc774\uc0c1\uc758 Source \uc560\ub178\ud14c\uc774\uc158\uc774 \ud544\uc694\ud558\ub2e4. \\nJUnit\uc774 \uc81c\uacf5\ud558\ub294 \ub2e4\uc591\ud55c Source\uac00 \uc788\uae30 \ub54c\ubb38\uc5d0, \ud14c\uc2a4\ud2b8\uc5d0 \ub9de\ucdb0 \ub2e4\uc591\ud558\uac8c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n### Value Source\\n\\n\uac12\uc744 \uc774\uc6a9\ud558\uc5ec \uc81c\uacf5\ud558\ub294 \ud615\ud0dc\ub85c, \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4. \\n- short, int, long, float, double\\n- byte, char, boolean, String, Class \\n\\n```java\\n@ParameterizedTest\\n@ValueSource(ints = {1, 100, Integer.MAX_VALUE})\\nvoid valueTest(final int value) {\\n Assertions.assertThat(value).isPositive();\\n}\\n```\\n\\n### Null & Empty Source\\n\\nnull \uac12, \ube48 \uac12\uc744 \uc81c\uacf5\ud55c\ub2e4. \\nEmpty Source\uc758 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc740 \ud0c0\uc785\uc5d0 \ud55c\ud574 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.\\n- String\\n- java.util.List, java.util.Set, java.util.Map\\n- primitive arrays \u2014 ex) int[]\\n- object arrays \u2014 ex) String[]\\n\\n```java\\n@ParameterizedTest\\n@NullAndEmptySource\\nvoid nullAndEmptyTest(final String value) {\\n Assertions.assertThat(value).isNullOrEmpty();\\n}\\n```\\n\\n### Enum Source\\n\\nEnumSource\ub97c \uc774\uc6a9\ud558\uc5ec Enum \ub610\ud55c \ub9e4\uac1c\ubcc0\uc218\ub85c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.\\n\\n```java\\nenum Day {\\n MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;\\n}\\n\\n@ParameterizedTest\\n@EnumSource(Day.class)\\nvoid enumTest(final Day day) {\\n assertThat(day).isInstanceOf(Day.class);\\n}\\n```\\n\\n\ub2e4\uc74c\uacfc \uac19\uc774 mode \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b9\uc9d5 Enum\uc744 \uc81c\uc678\ud558\uac70\ub098, \ud3ec\ud568\uc2dc\ud0ac \uc218 \uc788\ub2e4. (default: Mode.Include)\\n\\n```java\\n@ParameterizedTest\\n@EnumSource(value = Day.class, names = {\\"SATURDAY\\", \\"SUNDAY\\"}, mode = Mode.EXCLUDE)\\nvoid enumTest(final Day day) {\\n // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY\\n assertThat(day).isInstanceOf(Day.class);\\n}\\n```\\n\\n### CSV Source\\n\\ncsv \ud615\uc2dd\uc758 \uac12\uc744 \uc774\uc6a9\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud55c\ub2e4. \\n\uad6c\ubd84\uc790\uc758 \uae30\ubcf8\uac12\uc740 \uc27c\ud45c(,)\ub85c \uad6c\ubd84\uc790\ub97c \ubcc0\uacbd\ud558\uace0 \uc2f6\uc744 \ub550 delimeter \uac12\uc744 \ub530\ub85c \uc804\ub2ec\ud558\uc5ec \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\uac1c\uc778\uc801\uc73c\ub85c 2\uac1c \uc815\ub3c4\uc758 \uac12\uc744 \ub9e4\uac1c\ubcc0\uc218\ub85c \uc804\ub2ec\ud558\ub294 \uacbd\uc6b0 CsvSource\ub97c \uc0ac\uc6a9\ud55c\ub2e4.\\n\\n```java\\n@ParameterizedTest\\n@CsvSource({\\"1,1\\", \\"2,4\\", \\"3,9\\", \\"4,16\\"})\\nvoid csvTest(final int number, final int result) {\\n assertThat(number * number).isEqualTo(result);\\n}\\n```\\n\\n### Method Source\\n\\n\ubcf5\uc7a1\ud55c \ud0c0\uc785\uc758 \uac12\uc744 \uc804\ub2ec\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4. \\n\uba54\uc11c\ub4dc\uba85\uc744 \uc785\ub825\ud558\uc5ec \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4. \\n\uba54\uc11c\ub4dc\uba85\uc744 \ub530\ub85c \uc785\ub825\ud558\uc9c0 \uc54a\uc73c\uba74 \ud14c\uc2a4\ud2b8\uba85\uacfc \ub3d9\uc77c\ud55c static \uba54\uc11c\ub4dc\uac00 \uc9c0\uc815\ub41c\ub2e4.\\n\\n```java\\n@ParameterizedTest\\n@MethodSource\\nvoid methodTest(final List<Integer> numbers, final int count) {\\n assertThat(numbers).hasSize(count);\\n}\\n\\nprivate static Stream<Arguments> methodTest() {\\n return Stream.of(\\n Arguments.of(List.of(1), 1),\\n Arguments.of(List.of(1, 2), 2),\\n Arguments.of(List.of(1, 2, 3), 3)\\n );\\n}\\n```\\n\\n### ETC.\\n\\n\uc704\uc5d0\uc11c \uc5b8\uae09\ud55c \ubc29\ubc95 \uc774\uc678\uc5d0\ub3c4 \ub2e4\uc591\ud55c \ubc29\ubc95\uc73c\ub85c \ub9e4\uac1c\ubcc0\uc218\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.\\n\\n- CSV \ud30c\uc77c\uc744 \uc774\uc6a9\ud55c CsvFileSource\\n- ArgumentsProvider \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \uc774\uc6a9\ud558\ub294 ArgumentsSource\\n\\n## \ucc38\uace0 \uc790\ub8cc\\n\\n- [Guide to JUnit 5 Parameterized Tests](https://www.baeldung.com/parameterized-tests-junit-5)"},{"id":"intellij-settings","metadata":{"permalink":"/intellij-settings","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx","source":"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx","title":"IntelliJ \uc124\uc815","description":"Import \uc790\ub3d9 \uc801\uc6a9","date":"2023-01-30T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 30\uc77c","tags":[{"label":"IntelliJ","permalink":"/tags/intelli-j"}],"readingTime":0.465,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"IntelliJ \uc124\uc815","slug":"intellij-settings","tags":["IntelliJ"]},"unlisted":false,"prevItem":{"title":"Parameterized Tests","permalink":"/parameterized-tests"},"nextItem":{"title":"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95","permalink":"/kotlin-null"}},"content":"### Import \uc790\ub3d9 \uc801\uc6a9\\n\\nPrefrences > Editor > General > Auto Import > Add unambiguous imports on the fly\\n\\n![auto-import](./auto-import.png)\\n\\n### \uc800\uc7a5\uc2dc \ub3d9\uc791\\n\\nPrefrences > Tools > Actions on Save\\n\\n![actions-on-save](./actions-on-save.png)\\n\\nReformat Code: Code Reformmating\\n\\nOptimize imports: \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 Import \uc81c\uac70\\n\\nRearrange: Code Style > Arrangement \uc124\uc815 \uae30\ubc18 \ucf54\ub4dc \uc7ac\uc815\ub82c\\n\\n### \uba54\uc18c\ub4dc \ucd94\ucd9c, \ubcc0\uc218 \ucd94\ucd9c\uc2dc final \uc801\uc6a9\\n\\nPrefrences > Editor > Code Style > Java > Code Generation > Final Modifier\\n\\n![final-modifier](./final-modifier.png)"},{"id":"kotlin-null","metadata":{"permalink":"/kotlin-null","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx","source":"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx","title":"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95","description":"nullable \ud0c0\uc785","date":"2023-01-16T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 16\uc77c","tags":[{"label":"Kotlin","permalink":"/tags/kotlin"}],"readingTime":4.225,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95","slug":"kotlin-null","tags":["Kotlin"]},"unlisted":false,"prevItem":{"title":"IntelliJ \uc124\uc815","permalink":"/intellij-settings"},"nextItem":{"title":"JSR-310","permalink":"/jsr-310"}},"content":"import Tabs from \\"@theme/Tabs\\";\\nimport TabItem from \\"@theme/TabItem\\";\\n\\n### nullable \ud0c0\uc785\\n\\n\ucf54\ud2c0\ub9b0\uc740 `NullPointerException` \uc608\uc678\ub97c \ucd5c\ub300\ud55c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 \ud0c0\uc785 \uc2dc\uc2a4\ud15c\uc774 \uc124\uacc4\ub418\uc5b4 \uc788\ub2e4. \\n\uc774\ub294 \uc2e4\ud589 \uc2dc\uc810\uc774 \uc544\ub2cc \ucef4\ud30c\uc77c \uc2dc \ubbf8\ub9ac \uc624\ub958\uac00 \ubc1c\uc0dd\ud560 \uac00\ub2a5\uc131\uc774 \uc788\ub294 \ubd80\ubd84\uc744 \ubbf8\ub9ac \uac10\uc9c0\ud558\uc5ec NPE \ubc1c\uc0dd\uc758 \uac00\ub2a5\uc131\uc744 \uc904\uc5ec\uc900\ub2e4.\\n\\n\ucf54\ud2c0\ub9b0\uc758 \uacbd\uc6b0 nullable \ud0c0\uc785\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \ud45c\ud604\ud55c\ub2e4.\\n\\n```kotlin\\nval number: Int?\\n```\\n\\n\ud0c0\uc785 \ub4a4\uc5d0 `?`\ub97c \ubd99\uc5ec \ud574\ub2f9 \uac12\uc774 null\uc774 \ub420 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4. \\n\ub9cc\uc57d `?`\ub97c \ubd99\uc774\uc9c0 \uc54a\uc744 \ub54c null\uc744 \ubc1b\ub294 \uacbd\uc6b0 \ucef4\ud30c\uc77c \uc2dc \uc624\ub958\uac00 \ubc1c\uc0dd\ud55c\ub2e4.\\n\\n### `?.` Safe Calls \uc5f0\uc0b0\uc790\\n\\n\uc790\ubc14\uc5d0\uc11c NPE\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 null\uc744 \ucc98\ub9ac\ud558\ub294 \uac00\uc7a5 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c\ub294 \ubd84\uae30\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.\\n\\n\ucf54\ud2c0\ub9b0\uc740 \uc548\uc804\ud55c \ud638\ucd9c \uc5f0\uc0b0\uc790\uc778 `?.` \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4. \\n\ub530\ub77c\uc11c \ucc38\uc870 \uac12\uc774 null\uc774 \uc544\ub2d0 \uacbd\uc6b0\uc5d0\ub9cc \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\ucc38\uc870 \uac12\uc774 null\uc778 \uacbd\uc6b0 \uba54\uc11c\ub4dc \ud638\ucd9c\uc774 \ubb34\uc2dc\ub418\uace0, null\uc744 \ubc18\ud658\ud55c\ub2e4. \\n\\n<Tabs>\\n<TabItem value=\\"Java\\" label=\\"Java\\" default>\\n\\n```java\\npublic String repeat(String word) {\\n if (word == null) {\\n return null;\\n }\\n return word.repeat(2);\\n}\\n```\\n\\n</TabItem>\\n<TabItem value=\\"Kotlin\\" label=\\"Kotlin\\">\\n\\n```kotlin\\nfun repeat(word: String?): String? {\\n return word?.repeat(2)\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n### `?:` \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\\n\\n\ucc38\uc870\ud558\ub824\ub294 \uac12\uc774 null\uc77c \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud558\uace0 \uc2f6\uc744 \ub54c\ub294 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c? \\n\ucf54\ud2c0\ub9b0\uc740 null\uc774 \uc544\ub2cc \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \ub54c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4.\\n\\n<Tabs>\\n<TabItem value=\\"Java\\" label=\\"Java\\" default>\\n\\n```java\\npublic String stringSafe(String word) {\\n if (word == null) {\\n return \\"\\";\\n }\\n return word;\\n}\\n```\\n\\n</TabItem>\\n<TabItem value=\\"Kotlin\\" label=\\"Kotlin\\">\\n\\n```kotlin\\nfun stringSafe(word: String?): String {\\n return word ?: \\"\\"\\n}\\n```\\n\\n</TabItem>\\n</Tabs>\\n\\n\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 throw\ub3c4 \uc2dd\uc774\uae30 \ub54c\ubb38\uc5d0 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4. \\n\uc608\ub97c \ub4e4\uc5b4 \uc0ac\uc6a9\uc790 \uc815\ubcf4\uac00 \uc788\ub294 \uc800\uc7a5\uc18c\uc5d0 \ucc3e\ub294 \uc0ac\uc6a9\uc790\uac00 \uc5c6\ub294 \uacbd\uc6b0 \uc544\ub798\uc640 \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.\\n\\n```kotlin\\nuserRepository.findByName(name) ?: throw IllegalArgumentException()\\n```\\n\\n### `!!` \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790\\n\\n!! \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud55c\ub2e4\uba74 \uac15\uc81c\ub85c \uc5b4\ub5a4 \uac12\uc774\ub4e0 non-nullable \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4. \\n\ud558\uc9c0\ub9cc null\uc778 \uac12\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4\uba74 NPE\uac00 \ubc1c\uc0dd\ud558\uac8c \ub41c\ub2e4. \\n\uc77c\ubc18\uc801\uc778 \uacbd\uc6b0\uc5d0\ub294 !! \uc5f0\uc0b0\uc790\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc704\ud5d8\ud558\ub2e4. \\n\uc0ac\uc6a9\ud558\uae30 \uc27d\uc9c0\ub9cc, \ub9ac\uc2a4\ud06c\uac00 \ud06c\uace0 \ud639\uc2dc\ub098 \ud574\ub2f9 \uac12\uc774 \ucd94\ud6c4\uc5d0\ub294 null\uc774 \ub420 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc591\ud574\uc57c \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4.\\n\\n```kotlin\\nval length: Int = word!!.length\\n```\\n\\n### `as?` \uc548\uc804\ud55c \uce90\uc2a4\ud305\\n\\n\ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \ub54c \uc9c0\uc815\ud55c \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc5c6\ub2e4\uba74 `ClassCastException`\uc774 \ubc1c\uc0dd\ud55c\ub2e4. \\n\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 as \ub4a4\uc5d0 ?\ub97c \ubd99\uc5ec \uc548\uc804\ud558\uac8c \ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \uc218 \uc788\ub2e4. \\n\ub530\ub77c\uc11c \ubbf8\ub9ac \ubcc0\ud658 \uac00\ub2a5\ud55c \ud0c0\uc785\uc778\uc9c0 \ud655\uc778\ud558\uc9c0 \uc54a\uace0, \uc548\uc804\ud558\uac8c \ud0c0\uc785\uc744 \ubcc0\ud658 \ud560 \uc218 \uc788\ub2e4. \\n\\n\ud0c0\uc785 \ubcc0\ud658\uc774 \ubd88\uac00\ub2a5 \ud560 \uacbd\uc6b0 \uc608\uc678\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uace0 null\uc744 \ubc18\ud658\ud55c\ub2e4.\\n\\n```kotlin\\nval value: Int? = something as? Int\\n```\\n\\n### List\uc5d0\uc11c\uc758 null \ucc98\ub9ac\\n\\nList\uc5d0\ub294 null\uc774 \uc544\ub2cc \uac12\ub9cc \ubc18\ud658\ud558\ub294 `filterNotNull` \uc720\ud2f8\ub9ac\ud2f0 \uba54\uc11c\ub4dc\ub97c \uc81c\uacf5\ud55c\ub2e4.\\n\\n```kotlin\\nval foodsWithNull: List<String?> = listOf(\\"Pizza\\", \\"Cheese\\", null, \\"Potato\\")\\nval foods = foodsWithNull.filterNotNull()\\n```\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n- [Kotlin in Action](https://product.kyobobook.co.kr/detail/S000001804588)\\n- [Effective Kotlin Item 8](https://product.kyobobook.co.kr/detail/S000001033129)\\n- [Comprehensive Guide to Null Safety in Kotlin](https://www.baeldung.com/kotlin/null-safety)\\n- [Kotlin NullSafety](https://kotlinlang.org/docs/null-safety.html)"},{"id":"jsr-310","metadata":{"permalink":"/jsr-310","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-08-JSR-310.mdx","source":"@site/blog/2023-1/2023-01-08-JSR-310.mdx","title":"JSR-310","description":"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API","date":"2023-01-08T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 8\uc77c","tags":[{"label":"Java","permalink":"/tags/java"},{"label":"Time","permalink":"/tags/time"}],"readingTime":1.685,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"JSR-310","slug":"jsr-310","tags":["Java","Time"]},"unlisted":false,"prevItem":{"title":"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95","permalink":"/kotlin-null"},"nextItem":{"title":"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574","permalink":"/the-essence-of-object-orientation"}},"content":"\uc774\uc804\uc5d0 \ub9ce\uc740 \ubb38\uc81c\uac00 \uc788\ub358 \uc790\ubc14\uc758 \ud074\ub798\uc2a4(Calendar, Date)\ub97c \ub300\uccb4\ud558\ub294 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API \\nISO-8601\uc744 \uae30\ubc18\uc73c\ub85c \uc791\uc131 \\n\uc124\uacc4 \ubaa9\ud45c \u2192 \ubd88\ubcc0, Fluent API, \uba85\ud655\ud558\uace0 \uba85\uc2dc\uc801, \ud655\uc7a5 \uac00\ub2a5\uc131\\n\\n:::note ISO-8601\\n\\n\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc5d0 \uad00\ub828\ub41c \ub370\uc774\ud130\ub97c \ub2e4\ub8e8\ub294 \uad6d\uc81c \ud45c\uc900\\n\\n:::\\n\\n### LocalDate, LocalTime, LocalDateTime\\n\\n\ub0a0\uc9dc\uc640 \uc2dc\uac04\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4\\n\\n### Instant\\n\\n\uc720\ub2c9\uc2a4 \uc2dc\uac04(1970-01-01, 00:00:00 UTC) \uae30\uc900\uc73c\ub85c \ud2b9\uc815 \uc9c0\uc810\uae4c\uc9c0\uc758 \uc2dc\uac04\uc744 \ucd08\ub85c \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4 \\n\uae30\uacc4\uc758 \uad00\uc810\uc5d0\uc11c \uc2dc\uac04 \ud45c\ud604\\n\\n### Duration, Period\\n\\n\uac04\uaca9\uc744 \ud45c\ud604\ud558\ub294 \ud074\ub798\uc2a4\\n\\n### TemporalAdjusters\\n\\n\ubcf5\uc7a1\ud55c \ub0a0\uc9dc \uc870\uc815\uc774 \ud544\uc694\ud560 \ub54c \uc0ac\uc6a9 \\n\ud544\uc694\ud55c \uacbd\uc6b0 \ub2e4\uc74c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\uc5ec \ucee4\uc2a4\ud140 TemporalAdjuster\ub97c \uad6c\ud604 \uac00\ub2a5\\n\\n```java\\n@FunctionalInterface\\npublic interface TemporalAdjuster {\\n Temporal adjustInto(Temporal temporal);\\n}\\n```\\n\\n### DateTimeFormatter\\n\\n\ub0a0\uc9dc\uc640 \uc2dc\uac04 \ud3ec\ub9f7 \ud074\ub798\uc2a4 \\n\ud2b9\uc815 \ub0a0\uc9dc \ud328\ud134\uc774\ub098, DateTimeFormatterBuilder\ub97c \uc774\uc6a9\ud574\uc11c \ucee4\uc2a4\ud140\ud55c \ud3ec\ub9f7\uc744 \uc0dd\uc131 \uac00\ub2a5\\n\\n### ZoneId, ZoneOffset\\n\\nZoneId\ub294 \uc9c0\uc5ed ID\ub294 `\u2018\uc9c0\uc5ed/\ub3c4\uc2dc\u2019` \ud615\uc2dd, ZoneOffset\uc740 \uc2dc\ucc28 UTC \uae30\uc900 \uace0\uc815\ub41c \uc2dc\uac04 \ucc28\uc774 \uc774\uc6a9 \\nZoneId\uc758 \uacbd\uc6b0 IANA Time Zone Database\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc9c0\uc5ed \uc9d1\ud569 \uc815\ubcf4 \uc0ac\uc6a9\\n\\n```java\\nInstant instant = Instant.now();\\nLocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);\\n```\\n\\n### \ucc38\uace0 \uc790\ub8cc\\n\\n- [\ubaa8\ub358 \uc790\ubc14 \uc778 \uc561\uc158](https://product.kyobobook.co.kr/detail/S000001810171)\\n- [Java\uc758 \ub0a0\uc9dc\uc640 \uc2dc\uac04 API](https://d2.naver.com/helloworld/645609)\\n- [ISO-8601](https://www.w3.org/TR/NOTE-datetime)\\n- [JSR-310 Spec](https://download.oracle.com/otn-pub/jcp/date_time-0.2-edr-oth-JSpec/date_time-0_2-edr-spec.pdf?AuthParam=1673171124_74a718be92efe4911c6977c02965aff4)\\n- [Temporal Adjuster](https://www.baeldung.com/java-temporal-adjuster)\\n- [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html)"},{"id":"the-essence-of-object-orientation","metadata":{"permalink":"/the-essence-of-object-orientation","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx","source":"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx","title":"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574","description":"\ucc45 \uc815\ubcf4","date":"2023-01-07T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 7\uc77c","tags":[{"label":"Book","permalink":"/tags/book"}],"readingTime":5.415,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574","slug":"the-essence-of-object-orientation","tags":["Book"]},"unlisted":false,"prevItem":{"title":"JSR-310","permalink":"/jsr-310"},"nextItem":{"title":"2022\ub144 \ud68c\uace0","permalink":"/2022-retrospective"}},"content":"### \ucc45 \uc815\ubcf4\\n\\n> \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574 \\n> \uc870\uc601\ud638\\n> \\n\\n### \uc77d\uace0 \ub098\uc11c\\n\\n\uc870\uc601\ud638\ub2d8\uc758 \uc624\ube0c\uc81d\ud2b8\ub97c \uc77d\uace0 \ub098\uc11c \ub2e4\uc2dc \ud55c \ubc88 \uc77d\uc5b4\ubcf4\uc558\ub2e4. \\n\uc544\uc9c1 \uc774\ud574\uac00 \uc548\ub418\ub294 \ubd80\ubd84\uc774 \ub9ce\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ud56d\uc0c1 \uc0c8\ub85c\uc6c0\uc744 \ub290\ub080\ub2e4. \\n\ub354\ud560 \ub098\uc704 \uc5c6\uc774 \ud73c\ub96d\ud55c \uac1d\uccb4\uc9c0\ud5a5 \ucc45\uc774\uace0, \uc870\uae08 \ub354 \uacf5\ubd80\ud558\uace0 \ub2e4\uc2dc \uc77d\uc5b4\ubd10\uc57c\ub420 \uac83 \uac19\ub2e4. \\n\\n\ucee4\ud53c \uc804\ubb38\uc810, \uc9c0\ud558\ucca0 \ub178\uc120\ub3c4, \uc774\uc0c1\ud55c \ub098\ub77c\uc758 \uc5d8\ub9ac\uc2a4\ub97c \uc608\uc2dc\ub85c \ub4e0 \uc124\uba85\uc774 \ub108\ubb34 \uc88b\uc558\uace0 \\n\uc88b\uc740 \ub0b4\uc6a9\uc744 \ub2f4\uace0 \uc788\uc9c0\ub9cc \uadf8\ub807\ub2e4\uace0 \ub108\ubb34 \ubb34\uac81\uc9c0 \uc54a\uc544 \uac00\ubccd\uac8c \uc77d\uae30\ub3c4 \uc88b\uc740 \uac83 \uac19\ub2e4.\\n\\n### \ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173\\n\\n\ud611\ub825\uc744 \ub2e8\uc21c\ud558\uac8c \ub9cc\ub4e0\ub2e4.\\n\\n- \uc758\ub3c4\ub97c \uba85\ud655\ud558\uac8c \ud45c\ud604 \u2192 \ud611\ub825\uc758 \ubcf5\uc7a1\ud568 \uc800\ud558\\n- \ucc45\uc784\uc758 \ucd94\uc0c1\ud654\\n\\n\uc678\ubd80\uc640 \ub0b4\ubd80\ub97c \uba85\ud655\ud558\uac8c \ubd84\ub9ac\ud55c\ub2e4.\\n\\n- \uc694\uccad\ud558\ub294 \uac1d\uccb4\uac00 \ubab0\ub77c\ub3c4 \ub418\ub294 \ubd80\ubd84\uc774 \ucea1\uc290\ud654\ub428\uc73c\ub85c \uc778\ud130\ud398\uc774\uc2a4\uc640 \uad6c\ud604\uc758 \ubd84\ub9ac\\n\\n\ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub0b4\ubd80\uc801\uc778 \ubc29\ubc95\uc744 \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 \uc678\ubd80\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub294\ub2e4.\\n\\n- \ubcc0\uacbd\uc758 \ud30c\uae09\ud6a8\uacfc\ub97c \uac1d\uccb4 \ub0b4\ubd80\ub85c \ucea1\uc290\ud654 \u2192 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \uac1d\uccb4\uc640\uc758 \uacb0\ud569\ub3c4 \uc800\ud558\\n\\n\ud611\ub825\uc758 \ub300\uc0c1\uc744 \ub2e4\uc591\ud558\uac8c \uc120\ud0dd\ud560 \uc218 \uc788\ub294 \uc720\uc5f0\uc131\uc744 \uc81c\uacf5\ud55c\ub2e4.\\n\\n- \uc720\uc5f0\ud55c \uc124\uacc4 \u2192 \uc7ac\uc0ac\uc6a9\uc131 \uc99d\uac00\\n\\n\uac1d\uccb4\uc758 \uc5ed\ud560\uc744 \uc774\ud574\ud558\uae30 \uc26c\uc6cc\uc9c4\ub2e4.\\n\\n- \uc751\uc9d1\ub3c4\ub97c \ub192\uc740 \uc0c1\ud0dc\ub85c \uc720\uc9c0\\n\\n### \ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4\\n\\n> \uac1d\uccb4\uc9c0\ud5a5\uc758 \ubaa9\ud45c\ub294 \uc2e4\uc138\uacc4\ub97c \ubaa8\ubc29\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\\n\uc624\ud788\ub824 \uc0c8\ub85c\uc6b4 \uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uac1c\ubc1c\uc790\uc758 \uc5ed\ud560\uc740 \ub2e8\uc21c\ud788 \uc2e4\uc138\uacc4\ub97c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc548\uc73c\ub85c \uc62e\uaca8 \ub2f4\ub294 \uac83\uc774 \uc544\ub2c8\ub77c \uace0\uac1d\uacfc \uc0ac\uc6a9\uc790\ub97c \ub9cc\uc871\uc2dc\ud0ac \uc218 \uc788\ub294 \uc2e0\uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\\np.21\\n> \\n\\n> \uacfc\uac70\uc758 \uc804\ud1b5\uc801\uc778 \uac1c\ubc1c \ubc29\ubc95\uc740 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uc5c4\uaca9\ud558\uac8c \uad6c\ubd84\ud55c\ub2e4.\\n\uc774\uc5d0 \ubc18\ud574 \uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c\ub294 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uac1d\uccb4\ub77c\ub294 \ud558\ub098\uc758 \ud2c0 \uc548\uc5d0 \ud568\uaed8 \ubb36\uc5b4 \ub193\uc74c\uc73c\ub85c\uc368 \uac1d\uccb4\uc758 \uc790\uc728\uc131\uc744 \ubcf4\uc7a5\ud55c\ub2e4.\\n\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub85c \uad6c\uc131\ub41c \uacf5\ub3d9\uccb4\ub294 \uc720\uc9c0 \ubcf4\uc218\uac00 \uc27d\uace0 \uc7ac\uc0ac\uc6a9\uc774 \uc6a9\uc774\ud55c \uc2dc\uc2a4\ud15c\uc744 \uad6c\ucd95\ud560 \uc218 \uc788\ub294 \uac00\ub2a5\uc131\uc744 \uc81c\uc2dc\ud55c\ub2e4.\\np.33\\n> \\n\\n> **\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubcf8\uc9c8**\\n> \\n> \\n> \uc2dc\uc2a4\ud15c\uc744 \uc0c1\ud638\uc791\uc6a9\ud558\ub294 \uc790\uc728\uc801\uc778 \uac1d\uccb4\ub4e4\uc758 \uacf5\ub3d9\uccb4\ub85c \ubc14\ub77c\ubcf4\uace0 \uac1d\uccb4\ub97c \uc774\uc6a9\ud574 \uc2dc\uc2a4\ud15c\uc744 \ubd84\ud560\ud558\ub294 \ubc29\ubc95\\n> \\n> \uc790\uc728\uc801\uc778 \uac1d\uccb4\ub780 \uc0c1\ud0dc\uc640 \ud589\uc704\ub97c \ud568\uaed8 \uc9c0\ub2c8\uba70 \uc2a4\uc2a4\ub85c \uc790\uae30 \uc790\uc2e0\uc744 \ucc45\uc784\uc9c0\ub294 \uac1d\uccb4\ub97c \uc758\ubbf8\ud55c\ub2e4.\\n> \\n> \uac1d\uccb4\ub294 \uc2dc\uc2a4\ud15c\uc758 \ud589\uc704\ub97c \uad6c\ud604\ud558\uae30 \uc704\ud574 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud55c\ub2e4. \uac01 \uac1d\uccb4\ub294 \ud611\ub825 \ub0b4\uc5d0\uc11c \uc815\ud574\uc9c4 \uc5ed\ud560\uc744 \uc218\ud589\ud558\uba70 \uc5ed\ud560\uc740 \uad00\ub828\ub41c \ucc45\uc784\uc758 \uc9d1\ud569\uc774\ub2e4.\\n> \\n> \uac1d\uccb4\ub294 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud558\uae30 \uc704\ud574 \uba54\uc2dc\uc9c0\ub97c \uc804\uc1a1\ud558\uace0, \uba54\uc2dc\uc9c0\ub97c \uc218\uc2e0\ud55c \uac1d\uccb4\ub294 \uba54\uc2dc\uc9c0\ub97c \ucc98\ub9ac\ud558\ub294 \ub370 \uc801\ud569\ud55c \uba54\uc11c\ub4dc\ub97c \uc790\uc728\uc801\uc73c\ub85c \uc120\ud0dd\ud55c\ub2e4.\\n> p.35\\n> \\n\\n> \ud074\ub798\uc2a4\uc758 \uad6c\uc870\uc640 \uba54\uc11c\ub4dc\uac00 \uc544\ub2c8\ub77c \uac1d\uccb4\uc758 \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc5d0 \uc9d1\uc911\ud558\ub77c.\\n\uac1d\uccb4\uc9c0\ud5a5\uc740 \uac1d\uccb4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774\uc9c0 \ud074\ub798\uc2a4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\\np.38\\n> \\n\\n> \uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c \uc911\uc694\ud55c \uac83\uc740 \ub3d9\uc801\uc73c\ub85c \ubcc0\ud558\ub294 \uac1d\uccb4\uc758 \u2018\uc0c1\ud0dc\u2019\uc640 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\ub294 \u2018\ud589\uc704\u2019\ub2e4.\\n\ud074\ub798\uc2a4\ub294 \ud0c0\uc785\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud574 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uad6c\ud604 \uba54\ucee4\ub2c8\uc998\uc774\ub77c\ub294 \uc0ac\uc2e4\uc744 \uae30\uc5b5\ud558\ub77c.\\np.105\\n> \\n\\n> \ucc45\uc784 \uc8fc\ub3c4 \uc124\uacc4\uc758 \ud575\uc2ec\uc740 \uc5b4\ub5a4 \ud589\uc704\uac00 \ud544\uc694\ud55c\uc9c0\ub97c \uba3c\uc800 \uacb0\uc815\ud55c \ud6c4\uc5d0 \uc774 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac1d\uccb4\ub97c \uacb0\uc815\ud558\ub294 \uac83\uc774\ub2e4.\\n\uc774 \uacfc\uc815\uc744 \ud754\ud788 What/Who \uc0ac\uc774\ud074\uc774\ub77c\uace0 \ud55c\ub2e4.\\n\u2019\uc5b4\ub5a4 \ud589\uc704(What)\u2019\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud55c \ud6c4 \u2018\ub204\uac00(who)\u2019 \uadf8 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud574\uc57c \ud55c\ub2e4.\\n\uc5ec\uae30\uc11c \u2018\uc5b4\ub5a4 \ud589\uc704\u2019\uac00 \ubc14\ub85c \uba54\uc2dc\uc9c0\ub2e4.\\np.158\\n>"},{"id":"2022-retrospective","metadata":{"permalink":"/2022-retrospective","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx","source":"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx","title":"2022\ub144 \ud68c\uace0","description":"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70","date":"2023-01-02T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 2\uc77c","tags":[{"label":"Retrospective","permalink":"/tags/retrospective"}],"readingTime":3.705,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"2022\ub144 \ud68c\uace0","slug":"2022-retrospective","tags":["Retrospective"]},"unlisted":false,"prevItem":{"title":"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574","permalink":"/the-essence-of-object-orientation"},"nextItem":{"title":"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.","permalink":"/book-writer"}},"content":"\uc801\ub2f9\ud55c \uc804\ud658\uc810, 2022\ub144\uc744 \ub3cc\uc544\ubcf4\uba70 \\n\\n### \uc804\uc5ed\\n\\n\uc57d 1\ub144 6\uac1c\uc6d4\uac04\uc758 \uacf5\uad70 \uc815\ubcf4\ubcf4\ud638\ubcd1 \uc0dd\ud65c\uc744 \ub9c8\uce58\uace0 \uc804\uc5ed\uc744 \ud588\ub2e4. \\n\uc870\uae30 \uc804\uc5ed \ub54c\ubb38\uc5d0 2021\ub144 12\uc6d4\uc5d0 \ub098\uc654\uc9c0\ub9cc, \uc2e4\uc81c \uc804\uc5ed \ub0a0\uc9dc\ub294 2022\ub144\uc774\ub2c8 \ud68c\uace0\uc5d0 \uc801\uc5b4\ub3c4 \uc0c1\uad00\uc5c6\uaca0\uc9c0. \\n\\n\uc870\uae08 \ub354 \ubbf8\ub798\uc5d0 \ub300\ud55c \uc0dd\uac01\uc744 \ud574\ubcfc\uac78 \uadf8\ub7ac\ub2e4. \\n\uc804\uc5ed\uc744 \ud588\uc9c0\ub9cc \ubb50 \ud558\ub098 \uc81c\ub300\ub85c \ud560 \uc904 \uc544\ub294 \uac83\ub3c4 \uc5c6\uc73c\ub2c8 \ub113\uc740 \ubc14\ub2f7\uc18d\uc5d0 \ub369\uadf8\ub7ec\ub2c8 \ub193\uc544\uc9c4 \uae30\ubd84\uc774 \uad1c\ud788 \ub4e4\uc5c8\uc5c8\ub2e4. \\n\uc77c\ucc0d \uc0dd\uac01\uc744 \uc815\ub9ac\ud558\uc5ec \ubc29\ud5a5\uc744 \uc7a1\uc9c0 \ubabb\ud588\uae30\uc5d0 \uc544\uc26c\uc6c0\uc774 \ub9ce\uc774 \ub0a8\uc558\ub2e4. \\n\\n### \uc790\ubc14\\n\\n\uc804\uc5ed\uc744 \ud558\uace0 \uc9c4\ub85c\ub97c \uace0\ubbfc\ud558\ub2e4 \ud5a5\ub85c\ub2d8\uc758 [\uc790\ubc14 \uacf5\ud654\uad6d](https://jojoldu.tistory.com/609) \ud3ec\uc2a4\ud305\uc744 \uc77d\uace0 \ub098\uc11c \uc790\ubc14 \uacf5\ubd80\ub97c \uc2dc\uc791\ud588\ub2e4. \\n\uc720\uba85\ud55c \uc778\ud504\ub7f0\uc758 \uae40\uc601\ud55c\ub2d8\uc758 \uc2a4\ud504\ub9c1 \uac15\uc758\ub3c4 \uc788\uace0, \uc88b\uc740 \uc790\ubc14 \uac1c\ubc1c \uc11c\uc801\uc774 \ub9ce\uc544\uc11c \ub3c5\ud559\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4. \\n\ud558\ub2e4 \ubcf4\ub2c8 \uc790\ubc14\uc640 \uc2a4\ud504\ub9c1\uc744 \uacf5\ubd80\ud558\uba74\uc11c \u201c\uc65c \uc9c4\uc791\ud558\uc9c0 \uc54a\uc558\uc9c0\u201d\ub77c\ub294 \uc0dd\uac01\ub3c4 \ub9ce\uc774 \ub4e4\uc5c8\ub2e4. \\n\uc591\uc9c8\uc758 \uc790\ub8cc\ub3c4 \ub9ce\uc558\uae30 \ub54c\ubb38\uc5d0, \uc608\uc804\uc5d0 \ub178\ub4dc\ub85c \uac1c\ubc1c\ud588\uc744 \ub54c \ud480\uc9c0 \ubabb\ud588\ub358 \ub2f5\ub2f5\ud568\uc744 \ub9ce\uc774 \ud574\uc18c\ud588\ub358 \uac83 \uac19\ub2e4.\\n\\n23\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae4a\uac8c \uc790\ubc14\ub97c \uacf5\ubd80\ud574\ubcfc \uc0dd\uac01\uc774\ub2e4. \\n\uc5b8\uc5b4\ub97c \ud558\ub098 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ub9ce\uc740 \ub3c4\uc6c0\uc774 \ub418\ub294 \uac83 \uac19\ub2e4.\\n\\n### \uc2a4\ud130\ub514\\n\\n\uae40\uc601\ud55c\ub2d8\uc758 \uac15\uc758\ub97c \uac70\uc758 \ub2e4 \ub4e4\uc5c8\uc744 \ub54c\ucbe4, \ud56d\uc0c1 \uac15\uc758\uc5d0\uc11c \uc5b8\uae09\ub418\ub294 \ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1\uc744 \uc77d\uc5b4\ubcf4\uace0 \uc2f6\uc5b4\uc84c\uace0 \\n\ud63c\uc790 \uacf5\ubd80\ud558\uae30\uc5d0\ub294 \ub3d9\uae30\ubd80\uc5ec\ub3c4 \ubd80\uc871\ud588\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud130\ub514\ub97c \uc2dc\uc791\ud588\ub2e4. \\n\ub2e4\ub978 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\uc744 \ud574\uc57c \ud588\uae30 \ub54c\ubb38\uc5d0 \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uacf5\ubd80\ub97c \ud560 \uc218 \uc788\uc5b4\uc11c \uc88b\uc558\uc9c0\ub9cc \ub098\uc5d0\uac8c\ub294 \ub0b4\uc6a9\uc774 \uaf64\ub098 \uc5b4\ub824\uc6cc\uc11c \uc2dc\uac04\uc744 \ub9ce\uc774 \uc18c\ube44\ud588\ub2e4. \\n\uac19\uc774 \uc2a4\ud130\ub514\ud558\uc2dc\ub294 \ubd84\uacfc 7\uac1c\uc6d4 \ub3d9\uc548 \uc2a4\ud130\ub514\ub97c \uafb8\uc900\ud788 \uc774\uc5b4\ub098\uac00 \ucd1d 3\uad8c\uc758 \ucc45\uc744 \uc77d\uc744 \uc218 \uc788\uc5c8\ub2e4.\\n\\n### \uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\\n\\n\uad70 \ubcf5\ubb34 \uc911\uc77c \ub54c \uc9c0\uc6d0\ud588\ub2e4 \ub5a8\uc5b4\uc9c4 \uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ub2e4\uc2dc \uc9c0\uc6d0\ud588\ub2e4. \\n\uc774\ubc88 \uc5f0\ub3c4\uc5d0 \ucde8\uc5c5\uc744 \ud558\ub294 \uac8c \ubaa9\ud45c\uc600\uc9c0\ub9cc \ub0b4\uac00 \uac00\uc9c0\uace0 \uc788\ub294 \ud2b9\ubcc4\ud55c \ubb34\uae30\uac00 \uc5c6\ub2e4\ub294 \uac78 \uae68\ub2ec\uc558\ub2e4. \\n\uc801\uc9c0 \uc54a\uc740 \uc2dc\uac04\uc744 \ud22c\uc790\ud574 \uc900\ube44\ub97c \ud588\uace0, \uac10\uc0ac\ud558\uac8c\ub3c4 \uc774\ubc88\uc5d0\ub294 \ucd5c\uc885 \ud569\uaca9\uc744 \ud588\ub2e4. \\n\\n\ub09c \uc0ac\ub78c\ub4e4\uacfc \uc18c\ud1b5\ud558\uace0, \ud611\uc5c5\ud558\ub294 \ub2a5\ub825\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc744 \ub9ce\uc774 \ud588\ub2e4. \\n\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\ub97c \ud1b5\ud574 \uadf8 \ube48 \ubd80\ubd84\uc744 \ucc44\uc6b0\ub3c4\ub85d \ub178\ub825\ud574\uc57c\uaca0\ub2e4. \\n\\n### 2023\ub144\uc5d0\ub294\\n\\n\ub9c8\uc74c\uc758 \uc5ec\uc720\uac00 \uc5c6\uc5c8\ub358 2022\ub144\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4. \\n\ud558\uace0 \uc2f6\uc740 \uac74 \ub9ce\uc9c0\ub9cc, \uc774\ubc88\uc5d0\ub294 \uc5ec\uc720\ub97c \uac00\uc9c0\uace0 \ud560 \uc218 \uc788\ub294 \uac83\uc5d0 \ucd5c\uc120\uc744 \ub2e4\ud574\uc57c\uaca0\ub2e4."},{"id":"book-writer","metadata":{"permalink":"/book-writer","editUrl":"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx","source":"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx","title":"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.","description":"\ucc45 \uc815\ubcf4","date":"2023-01-01T00:00:00.000Z","formattedDate":"2023\ub144 1\uc6d4 1\uc77c","tags":[{"label":"Book","permalink":"/tags/book"}],"readingTime":4.425,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.","slug":"book-writer","tags":["Book"]},"unlisted":false,"prevItem":{"title":"2022\ub144 \ud68c\uace0","permalink":"/2022-retrospective"}},"content":"### \ucc45 \uc815\ubcf4\\n\\n> \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \\n> \ubc15\uc194\ubbf8 \\n>\\n\\n### \uc77d\uace0 \ub098\uc11c\\n\\n\uc800\uc790\uc758 \uacbd\ud5d8\uacfc \ud568\uaed8 \uae00\uc4f0\uae30\uc5d0 \ub300\ud55c \uac00\ubcbc\uc6b4 \uc870\uc5b8\uc774 \ub2f4\uaca8\uc788\uc5b4 \uac00\ubccd\uac8c \uc77d\uae30 \uc88b\uc558\ub2e4. \\n\uae00\uc744 \uc798 \uc791\uc131\ud574 \ubcf4\uace0 \uc2f6\uc744 \ub54c \uc801\uc6a9\ud574 \ubcfc \uc218 \uc788\ub294 \uc815\ubcf4\uac00 \ub9ce\uc544\uc11c \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub2e4. \\n\\n\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\uc758 \ud504\ub9ac\ucf54\uc2a4\ub97c \uc9c4\ud589\ud560 \ub54c \ud6c4\uae30\ub97c \uc791\uc131\ud558\uace0 \ub098\uba74 \ud56d\uc0c1 \uae00\uc774 \ub531\ub531\ud558\ub2e4\ub294 \ub290\ub08c\uc744 \ubc1b\uc558\ub2e4. \\n\ub2e4\ub978 \uc9c0\uc6d0\uc790\ub4e4\uc758 \uc77d\uae30 \ud3b8\ud558\uace0, \ubc1d\uc740 \ub290\ub08c\uc744 \uc8fc\ub294 \uae00\uc744 \ubcf4\uba74 \ubd80\ub7ec\uc6b4 \ub9c8\uc74c\uc744 \uac00\uc9c0\uae30\ub3c4 \ud588\ub2e4. \\n\uc774 \ucc45\uc744 \uc77d\uc5c8\uc73c\ub2c8 2023\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae00\uc744 \uc798 \uc801\uc5b4\ubcf4\ub824\uace0 \ud55c\ub2e4.\\n\\n### \ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4\\n\\n> \ubb38\uc7a5\uc774 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74\\n\ub0b4\uc6a9\uc744 \uc77c\ubaa9\uc694\uc5f0\ud558\uac8c \uc815\ub9ac\ud588\uace0, \uae00\uc758 \uc758\ub3c4\ub3c4 \uc090\ub6a4\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub3c4 \uc801\uc808\ud55c \uac83\uc73c\ub85c \uace8\ub790\ub294\ub370\u2026 \uadf8\ub7f0\ub370\ub3c4 \uc5b4\ub518\uac00\uac00 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74? \ucd95\ucd95 \ucc98\uc9c0\uace0 \ub530\ubd84\ud558\ub2e4\uba74? \ub9d0\uaf2c\ub9ac\ub97c \ubaa8\uc870\ub9ac \u2018~\ub2e4\u2019\ub85c \ud1b5\uc77c\ud55c \uac74 \uc544\ub2cc\uc9c0 \uc810\uac80\ud574 \ubcf4\uc138\uc694.\\n> \\n\\n> \ub9d0\uaf2c\ub9ac\ub97c \uc798 \uac16\uace0 \ub180\uc544\uc57c \ud569\ub2c8\ub2e4. \ubb38\uc7a5\uc758 \ub9c8\uc9c0\ub9c9 \uae00\uc790\ub97c \ub9e4\ubc88 \ub2e4\ub974\uac8c \uace0\uccd0\uc4f0\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uae00\uc5d0 \ud65c\uae30\ub97c \ub354\ud560 \uc218 \uc788\uc8e0. \ub54c\ub860 \ubb38\uc7a5\uc744 \ub2e4 \ub9c8\uce58\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub85c\ub9cc \ub05d\ub9fa\ub294 \uac83\ub3c4 \ubc29\ubc95. \ubb38\uc7a5\uacfc \ubb38\uc7a5 \uc0ac\uc774\uc5d0 \uc27c\ud45c\uac00 \ub4e4\uc5b4\uc11c\uba70 \uae00 \uc804\uccb4\uc5d0 \ud65c\uae30\uac00 \ub3cc\uac8c \ub3fc\uc694. \ubb38\uc7a5\uc758 \uae38\uc774\ub3c4 \ub2e4\ucc44\ub85c\uc6cc\uc9c0\ub294 \ub355\ubd84\uc5d0 \ub364\uc73c\ub85c \uc5bb\uac8c \ub418\ub294 \uac83\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ubc14\ub85c, \uae00\uc758 \ub9ac\ub4ec.\\n> \\n\\n> \uc774\uc804 \ubb38\uc7a5\uc5d0\uc11c \ub05d\ub09c \uae00\uc790\ub85c, \ub2e4\uc74c \ubb38\uc7a5\uc744 \ub05d\ub9fa\uc9c0 \uc54a\uae30. \ud55c\ub450 \ubb38\ub2e8\ub9c8\ub2e4 \ub2e8\uc5b4 \uc218\uc900\uc758 \uc544\uc8fc \uc9e7\uc740 \ubb38\uc7a5 \ubc30\uce58\ud558\uae30.\\n> \\n\\n> \uae00\uc758 \uc9c4\uc9dc \uc774\uc720, \uae00\uc758 \uc9c4\uc9dc \ubaa9\uc801, \uae00\uc758 \uc9c4\uc9dc \ub300\uc0c1\uc744 \ucc3e\uc73c\ub824\uace0 \uc560\uc37c\uc2b5\ub2c8\ub2e4. \uc9c0\uae08\ucc98\ub7fc \ud2c0\uc744 \ub5a0\uc62c\ub9b0\ub2e4\uac70\ub098, \ub208\uce58\ub97c \ubcf8\ub2e4\uac70\ub098, \uc815\uce58\uc801\uc778 \uc148\ub3c4 \ud558\uc9c0 \uc54a\uc558\uc5b4\uc694.\\n> \\n\\n> \uc81c\ubaa9\uc740 \uc9e7\uac8c, \ubcf4\uae30 \uc27d\uac8c, \uc77d\uae30 \uc27d\uac8c, \ubc1c\uc74c\uc774 \ube44\uc2b7\ud558\uac8c, \uc21c\uc11c\ub97c \ubc14\uafd4\uc11c\\n> \\n\\n> \uae00\uc744 \ub9c8\uc9c0\ub9c9\uc73c\ub85c \ub2e4\ub4ec\uc744 \ub54c, \ub178\ub798\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \ubc29\ubc95\uc740 \uc5c6\uc744\uc9c0 \uace0\ubbfc\ud574\ubd05\ub2c8\ub2e4. \uac10\ud788 \uac00 \ub2ff\uc744 \uc218 \uc5c6\ub294 \ubaa9\ud45c\uc774\uaca0\uc9c0\ub9cc, \ud560 \uc218 \uc788\ub294 \ucd5c\uc18c\ud55c\uc758 \ub9ac\ub4ec\uc774\ub77c\ub3c4 \ubd99\uc5ec\uc8fc\uace0 \uc2f6\uc5b4\uc694.\\n> \\n\\n> \uc5ec\ub294 \ub9d0\uacfc \ub9c8\uc9c0\ub9c9 \ub9d0\uc5d0 \uc791\uc815\ud558\uace0 \ub9c8\uc74c\uc744 \ub2f4\ub294 \uc5f0\uc2b5\uc744 \ud574\ubd05\uc2dc\ub2e4. \uae00\uc758 \uc5b4\ub290 \uad6c\uc11d\uc774\ub77c\ub3c4 \ubed4\ud55c \uae00\uc790\ub294 \ub0a8\uae30\uc9c0 \uc54a\uaca0\ub178\ub77c \ub2e4\uc9d0\ud558\uba70 \uc368\ubcf4\ub294 \uac81\ub2c8\ub2e4. \ub098\ub9cc\uc774 \uac00\uc9c4 \uc720\uc77c\ud55c \uba54\uc2dc\uc9c0\uc5d0 \uc9d1\uc911\ud558\uba74\uc11c\uc694. \uadf8\ub7fc \uc0dd\uac01\uc774 \ub2ec\ub77c\uc9c0\uace0, \uace0\ub974\ub294 \ub2e8\uc5b4\ub3c4 \ub2ec\ub77c\uc9c0\uace0, \ub0a8\uae34 \ubb38\uc7a5\ub3c4 \ub2ec\ub77c\uc838\uc694. \uacb0\uad6d\uc5d0\ub294 \uae00\uc744 \uc4f4 \uc0ac\ub78c\uc778 \ub098 \uc790\uc2e0\ub3c4 \ub0a8\ub2ec\ub77c\uc9c8 \uac81\ub2c8\ub2e4.\\n> \\n\\n> \ub9de\ucda4\ubc95\uc740 \uc911\uc694\ud569\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \ub9de\ucda4\ubc95\ubcf4\ub2e4 \ub354 \uc911\uc694\ud55c \uac74 \uac70\uae30\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc785\ub2c8\ub2e4. \ub0b4 \ub9c8\uc74c\uc744 \uae00\uc5d0 \ub2f4\uc544 \uc2e4\uc5b4 \ubcf4\ub0b4\uae30 \uc804, \ub9de\ucda4\ubc95\uc744 \uc810\uac80\ud558\ub294 \uc774\uc720 \uc5ed\uc2dc \uadf8\uac81\ub2c8\ub2e4. \uc624\uc9c1 \ub0b4 \ub9c8\uc74c\uc774 \ub0a8\uc5d0\uac8c \uc77d\ud788\ub294 \ub3d9\uc548 \ubc29\ud574\uac00 \ub418\uc9c0 \uc54a\uae30\ub97c \ubc14\ub77c\uae30 \ub54c\ubb38\uc774\uc8e0. \ub0b4\uac00 \uc4f4 \uae00\ub3c4, \ub0a8\uc774 \uc4f4 \uae00\ub3c4. \uc5b8\uc81c\ub098 \uadf8 \uc548\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc774 \uba3c\uc800\uc785\ub2c8\ub2e4.\\n> \\n\\n> \uae00\uc744 \uc4f4\ub2e4\uace0 \uae00\uc774 \uc644\uc131\ub418\ub294 \uac8c \uc544\ub2c8\uc5d0\uc694. \uae00\uacfc \ub2ee\uc740 \ubaa8\uc2b5\uc73c\ub85c \uc0b4 \ub54c, \uae00\uc740 \ube44\ub85c\uc18c \uc644\uc131\ub429\ub2c8\ub2e4.\\n>"}]}')}}]); \ No newline at end of file diff --git a/assets/js/b2c8756c.4aff2828.js b/assets/js/b2c8756c.4aff2828.js new file mode 100644 index 000000000..4c626987e --- /dev/null +++ b/assets/js/b2c8756c.4aff2828.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1213],{80936:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>c,toc:()=>a});var t=r(85893),o=r(3905);const s={title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",slug:"order-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,c={permalink:"/order-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4: AWS \ubc30\ud3ec",date:"2023-06-04T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 4\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.67,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",slug:"order-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",permalink:"/level2-interview-retrospective"},nextItem:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",permalink:"/tecochat-retrospective-3"}},l={authorsImageUrls:[]},a=[{value:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158",id:"\uc7a5\ubc14\uad6c\ub2c8-\uc8fc\ubb38-\ubbf8\uc158",level:3},{value:"\ubc30\ud3ec",id:"\ubc30\ud3ec",level:3},{value:"\ud611\uc5c5",id:"\ud611\uc5c5",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84",id:"\uc0c8\ub85c-\ubc30\uc6b4-\ubd80\ubd84",level:3}];function p(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(n.p,{children:["1\ub2e8\uacc4: AWS \ubc30\ud3ec",(0,t.jsx)(n.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/jwp-shopping-order/pull/7",children:"https://github.com/woowacourse/jwp-shopping-order/pull/7"})]})}),"\n",(0,t.jsx)(n.h3,{id:"\uc7a5\ubc14\uad6c\ub2c8-\uc8fc\ubb38-\ubbf8\uc158",children:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158"}),"\n",(0,t.jsxs)(n.p,{children:["\ubc30\ud3ec \ubc0f \ud611\uc5c5\uc744 \ud560 \uc218 \uc788\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub9c8\ucf54, \uc6b0\uac00, \uc6b0\ucf54, \uc6b0\uc2a4 \uadf8\ub9ac\uace0 \ub098\uae4c\uc9c0 \ud569\uccd0\uc11c 5\uba85\uc774 \ud55c \ud300\uc774 \ub418\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc30\ud3ec",children:"\ubc30\ud3ec"}),"\n",(0,t.jsxs)(n.p,{children:["\uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac AWS\ub97c \uc774\uc6a9\ud574 \ubc30\ud3ec\ub97c \ud574\uc57c \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uac01\uc790 \ud558\ub098\uc758 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc744 \uc218 \uc788\uc5c8\uace0, \ud300 \ubcc4\ub85c DB\ub97c \uc704\ud55c \ucd94\uac00 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc791\uc131\ud558\ub294 \uacbd\ud5d8\uc744 \ud574\ubcfc \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc2dc\uac04\uc744 \ub9ce\uc774 \ud22c\uc790\ud558\uc9c4 \uc54a\uc558\uace0, \ub2e4\uc74c\uacfc \uac19\uc774 \uac04\ub2e8\ud558\uac8c \uc791\uc131\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "Start Deploy Script"\nREPOSITORY_NAME=/home/ubuntu/jwp-shopping-order\nPROJECT_NAME=jwp-shopping-order\n\necho "Change Directory"\ncd $REPOSITORY_NAME\n\necho "Git Pull"\ngit pull origin step2\n\necho "Build"\n./gradlew bootJar\n\necho "Copy, Start Server"\nmv ./build/libs/$PROJECT_NAME.jar .\n\nPID=$(pgrep -f $PROJECT_NAME)\n\nif [ -n $PID ]; then\n kill -9 $PID\n\tsleep 5\nfi\n\nnohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &\n'})}),"\n",(0,t.jsx)(n.h3,{id:"\ud611\uc5c5",children:"\ud611\uc5c5"}),"\n",(0,t.jsxs)(n.p,{children:["\uc77c\ub2e8 \uc6b0\uc2a4\ub791 \uc6b0\ucf54\uac00 \uba3c\uc800 \uc7a0\uc2e4\ub85c \uc640\uc918\uc11c \ub108\ubb34 \uac10\uc0ac\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc31\uc5d4\ub4dc\uac00 \uc544\ub2cc \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \ud574\ubcf4\ub294 \uccab \ud611\uc5c5\uc774\ub77c \uc57d\uac04 \ub450\uadfc\uac70\ub838\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc608\uc0c1\uc678\ub85c \ub300\ud654\uac00 \uc798 \ub418\uc5b4\uc11c, \ube60\ub974\uac8c \uba85\uc138\ub97c \uc815\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uc5ec\ub7ec\uac00\uc9c0 \ubc29\ubc95\uc5d0 \ub300\ud55c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud574\ubcf4\uae30"})}),"\n",(0,t.jsxs)(n.p,{children:["\ubc31\uc5d4\ub4dc\uc640 \ud14c\uc774\ube14 \uba85\uc138\ub098 \ucfe0\ud3f0 \uad6c\ud604\uc5d0 \ub300\ud574\uc11c \uc774\uc57c\uae30\ud560 \ub54c \uc7a5\ub2e8\uc5d0 \ub300\ud574 \ub9ce\uc774 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub9ce\uc774 \ub4e4\uc5ec\uc11c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud588\ub2e4\uba74 \ub354 \uc88b\uc740 \uacb0\uacfc\ubb3c\uc774 \ub098\uc624\uc9c0 \uc54a\uc558\uc744\uae4c?",(0,t.jsx)(n.br,{}),"\n","\uc55e\uc73c\ub85c \uc120\ud0dd\uc758 \uc21c\uac04\uc5d0\uc11c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub4e4\uc5ec\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc0c8\ub85c-\ubc30\uc6b4-\ubd80\ubd84",children:"\uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"expose headers"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc6f9 \ud398\uc774\uc9c0\uc5d0\uc11c Location \ud5e4\ub354\ub97c \ubc1b\uc744 \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c ",(0,t.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header",children:"\ud5c8\uc6a9 \ubaa9\ub85d\uc5d0 \uc874\uc7ac\ud558\ub294 \uc751\ub2f5\ud5e4\ub354"}),"\ub9cc \ubc18\ud658\ud55c\ub2e4\ub294 \uac83\uc744 \ubaa8\ub974\uace0 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub97c expose headers \uc124\uc815\uc744 \ud1b5\ud574 \ud574\uacb0\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","nginx \uc124\uc815\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \ucd94\uac00\ud574 \uc8fc\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"add_header 'Access-Control-Expose-Headers' 'Location'\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158"})}),"\n",(0,t.jsxs)(n.p,{children:["\ub2e8\uc21c \uc870\ud68c \uc694\uccad\uc5d0 \ub300\ud55c \uc131\ub2a5\uc744 \ud5a5\uc0c1\uc2dc\ucf1c\uc900\ub2e4\ub294 \uac83\uc774\ub77c\uace0 \uac04\ub2e8\ud788\ub9cc \uc54c\uace0 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ubc88\uc5d0 \ucf54\uba58\ud2b8\uac00 \ub2ec\ub824\uc11c \uc870\uae08 \ub354 \uc790\uc138\ud788 \uacf5\ubd80\ud574 \ubcf4\uae30\ub85c \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Transactional(readOnly = true)\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc774 \ub3d9\uc791\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:"setReadOnly(true) \uc124\uc815\uc774 \ub41c Connection\uc73c\ub85c \uc5f0\uacb0\uc744 \uc2dc\ub3c4\ub97c \ud55c\ub2e4. \uc774 \uc124\uc815\uc744 \ud558\ub294 \uacbd\uc6b0 DB\ub9c8\ub2e4 \ub2e4\ub974\uac8c \ub3d9\uc791\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"h2\uc758 Connection \uad6c\ud604\uccb4\ub294 readOnly \uc124\uc815\uc744 \ubb34\uc2dc\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 Transactional \uc801\uc6a9\ub418\uc9c0 \uc54a\ub294\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"MySQL 8.0(InnoDB \uc0ac\uc6a9 \uc2dc)\uc758 \uacbd\uc6b0 \uc77d\uae30 \uc804\uc6a9\uc73c\ub85c \uc54c\ub824\uc9c4 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158 ID\ub97c \uc124\uc815\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uc870\ud68c \uc18d\ub3c4\uac00 \ub354 \ube68\ub77c\uc9c4\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["ORM \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 prepareTransactionalConnection\ub97c \ud638\ucd9c\ud55c\ub2e4\uace0 \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ud604\uc5c5\uc5d0\uc11c\ub294 \uace0\uac00\uc6a9\uc131 \ub0b4\uacb0\ud568\uc131 \ub4f1\uc744 \uc704\ud558\uc5ec \ud074\ub7ec\uc2a4\ud130\ub97c \uad6c\uc131\ud558\uc5ec \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uace0, \uc774 \uacbd\uc6b0 readOnly \uc124\uc815\uc774 \ub418\uc5b4\uc788\ub2e4\uba74 \uc77d\uae30 \uc804\uc6a9 DB\ub85c \uc9c8\uc758\uac00 \ub4e4\uc5b4\uac00\uc11c \ubd80\ud558 \ubd84\uc0b0\uc758 \ud6a8\uacfc\uac00 \uc788\ub2e4\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsxs)(n.strong,{children:["DAO\uc5d0 ",(0,t.jsx)(n.code,{children:"@Transactional"})," \uc801\uc6a9"]})}),"\n",(0,t.jsxs)(n.p,{children:["DAO\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \ubcf4\ub294 \uac74 \uc5b4\ub5bb\uaca0\ub0d0\uace0 \ub9ac\ubdf0\uac00 \ub2ec\ub824\uc11c \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Service \uacc4\uce35\uc5d0 \uc774\ubbf8 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \uc8fc\uace0 \uc788\uae30\uc5d0 \ud544\uc694 \uc5c6\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","DAO\ub97c \ub2e4\ub978 \uacf3\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574(\ud655\uc7a5\uc131 \uace0\ub824) ",(0,t.jsx)(n.code,{children:"@Transactional"}),"\uc744 \uc801\uc6a9\ud558\ub294 \uac83\ub3c4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4."]})]})}function d(e={}){const{wrapper:n}={...(0,o.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?s(Object(r),!0).forEach((function(n){o(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function c(e,n){if(null==e)return{};var r,t,o=function(e,n){if(null==e)return{};var r,t,o={},s=Object.keys(e);for(t=0;t<s.length;t++)r=s[t],n.indexOf(r)>=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t<s.length;t++)r=s[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=t.createContext({}),a=function(e){var n=t.useContext(l),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),h=a(r),u=o,j=h["".concat(l,".").concat(u)]||h[u]||p[u]||s;return r?t.createElement(j,i(i({ref:n},d),{},{components:r})):t.createElement(j,i({ref:n},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/b2c8756c.a59a1417.js b/assets/js/b2c8756c.a59a1417.js deleted file mode 100644 index 0b5c59d4d..000000000 --- a/assets/js/b2c8756c.a59a1417.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1213],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=c(r),d=a,k=m["".concat(i,".").concat(d)]||m[d]||u[d]||o;return r?n.createElement(k,p(p({ref:t},s),{},{components:r})):n.createElement(k,p({ref:t},s))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,p=new Array(o);p[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,p[1]=l;for(var c=2;c<o;c++)p[c]=r[c];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},31419:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",slug:"order-retrospective",tags:["Woowahan Techcourse","Retrospective"]},p=void 0,l={permalink:"/order-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4: AWS \ubc30\ud3ec",date:"2023-06-04T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 4\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.67,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",slug:"order-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",permalink:"/level2-interview-retrospective"},nextItem:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",permalink:"/tecochat-retrospective-3"}},i={authorsImageUrls:[]},c=[{value:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158",id:"\uc7a5\ubc14\uad6c\ub2c8-\uc8fc\ubb38-\ubbf8\uc158",level:3},{value:"\ubc30\ud3ec",id:"\ubc30\ud3ec",level:3},{value:"\ud611\uc5c5",id:"\ud611\uc5c5",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84",id:"\uc0c8\ub85c-\ubc30\uc6b4-\ubd80\ubd84",level:3}],s={toc:c};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: AWS \ubc30\ud3ec",(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-shopping-order/pull/7"},"https://github.com/woowacourse/jwp-shopping-order/pull/7")," ")),(0,a.kt)("h3",{id:"\uc7a5\ubc14\uad6c\ub2c8-\uc8fc\ubb38-\ubbf8\uc158"},"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158"),(0,a.kt)("p",null,"\ubc30\ud3ec \ubc0f \ud611\uc5c5\uc744 \ud560 \uc218 \uc788\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9c8\ucf54, \uc6b0\uac00, \uc6b0\ucf54, \uc6b0\uc2a4 \uadf8\ub9ac\uace0 \ub098\uae4c\uc9c0 \ud569\uccd0\uc11c 5\uba85\uc774 \ud55c \ud300\uc774 \ub418\uc5c8\ub2e4. "),(0,a.kt)("h3",{id:"\ubc30\ud3ec"},"\ubc30\ud3ec"),(0,a.kt)("p",null,"\uc774\uc804 \ubbf8\uc158\ub4e4\uacfc \ub2ec\ub9ac AWS\ub97c \uc774\uc6a9\ud574 \ubc30\ud3ec\ub97c \ud574\uc57c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac01\uc790 \ud558\ub098\uc758 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc744 \uc218 \uc788\uc5c8\uace0, \ud300 \ubcc4\ub85c DB\ub97c \uc704\ud55c \ucd94\uac00 \uc778\uc2a4\ud134\uc2a4\ub97c \uc81c\uacf5\ubc1b\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\ub97c \uc791\uc131\ud558\ub294 \uacbd\ud5d8\uc744 \ud574\ubcfc \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc30\ud3ec \uc2a4\ud06c\ub9bd\ud2b8\uc5d0 \uc2dc\uac04\uc744 \ub9ce\uc774 \ud22c\uc790\ud558\uc9c4 \uc54a\uc558\uace0, \ub2e4\uc74c\uacfc \uac19\uc774 \uac04\ub2e8\ud558\uac8c \uc791\uc131\ud588\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},'echo "Start Deploy Script"\nREPOSITORY_NAME=/home/ubuntu/jwp-shopping-order\nPROJECT_NAME=jwp-shopping-order\n\necho "Change Directory"\ncd $REPOSITORY_NAME\n\necho "Git Pull"\ngit pull origin step2\n\necho "Build"\n./gradlew bootJar\n\necho "Copy, Start Server"\nmv ./build/libs/$PROJECT_NAME.jar .\n\nPID=$(pgrep -f $PROJECT_NAME)\n\nif [ -n $PID ]; then\n kill -9 $PID\n sleep 5\nfi\n\nnohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &\n')),(0,a.kt)("h3",{id:"\ud611\uc5c5"},"\ud611\uc5c5"),(0,a.kt)("p",null,"\uc77c\ub2e8 \uc6b0\uc2a4\ub791 \uc6b0\ucf54\uac00 \uba3c\uc800 \uc7a0\uc2e4\ub85c \uc640\uc918\uc11c \ub108\ubb34 \uac10\uc0ac\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc31\uc5d4\ub4dc\uac00 \uc544\ub2cc \ub2e4\ub978 \ud06c\ub8e8\ub4e4\uacfc \ud574\ubcf4\ub294 \uccab \ud611\uc5c5\uc774\ub77c \uc57d\uac04 \ub450\uadfc\uac70\ub838\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\uc0c1\uc678\ub85c \ub300\ud654\uac00 \uc798 \ub418\uc5b4\uc11c, \ube60\ub974\uac8c \uba85\uc138\ub97c \uc815\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc5ec\ub7ec\uac00\uc9c0 \ubc29\ubc95\uc5d0 \ub300\ud55c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud574\ubcf4\uae30")),(0,a.kt)("p",null,"\ubc31\uc5d4\ub4dc\uc640 \ud14c\uc774\ube14 \uba85\uc138\ub098 \ucfe0\ud3f0 \uad6c\ud604\uc5d0 \ub300\ud574\uc11c \uc774\uc57c\uae30\ud560 \ub54c \uc7a5\ub2e8\uc5d0 \ub300\ud574 \ub9ce\uc774 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub9ce\uc774 \ub4e4\uc5ec\uc11c \uc7a5\ub2e8\uc810\uc744 \uace0\ub824\ud588\ub2e4\uba74 \ub354 \uc88b\uc740 \uacb0\uacfc\ubb3c\uc774 \ub098\uc624\uc9c0 \uc54a\uc558\uc744\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc120\ud0dd\uc758 \uc21c\uac04\uc5d0\uc11c \uc870\uae08 \ub354 \uc2dc\uac04\uc744 \ub4e4\uc5ec\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4. "),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ubc30\uc6b4-\ubd80\ubd84"},"\uc0c8\ub85c \ubc30\uc6b4 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"expose headers")),(0,a.kt)("p",null,"\uc6f9 \ud398\uc774\uc9c0\uc5d0\uc11c Location \ud5e4\ub354\ub97c \ubc1b\uc744 \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c ",(0,a.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_response_header"},"\ud5c8\uc6a9 \ubaa9\ub85d\uc5d0 \uc874\uc7ac\ud558\ub294 \uc751\ub2f5\ud5e4\ub354"),"\ub9cc \ubc18\ud658\ud55c\ub2e4\ub294 \uac83\uc744 \ubaa8\ub974\uace0 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c expose headers \uc124\uc815\uc744 \ud1b5\ud574 \ud574\uacb0\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","nginx \uc124\uc815\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \ucd94\uac00\ud574 \uc8fc\uc5c8\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"add_header 'Access-Control-Expose-Headers' 'Location'\n")),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158")," "),(0,a.kt)("p",null,"\ub2e8\uc21c \uc870\ud68c \uc694\uccad\uc5d0 \ub300\ud55c \uc131\ub2a5\uc744 \ud5a5\uc0c1\uc2dc\ucf1c\uc900\ub2e4\ub294 \uac83\uc774\ub77c\uace0 \uac04\ub2e8\ud788\ub9cc \uc54c\uace0 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0 \ucf54\uba58\ud2b8\uac00 \ub2ec\ub824\uc11c \uc870\uae08 \ub354 \uc790\uc138\ud788 \uacf5\ubd80\ud574 \ubcf4\uae30\ub85c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Transactional(readOnly = true)\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ub2e4\uc74c\uacfc \uac19\uc774 \ub3d9\uc791\ud55c\ub2e4."),(0,a.kt)("p",null,"setReadOnly(true) \uc124\uc815\uc774 \ub41c Connection\uc73c\ub85c \uc5f0\uacb0\uc744 \uc2dc\ub3c4\ub97c \ud55c\ub2e4. \uc774 \uc124\uc815\uc744 \ud558\ub294 \uacbd\uc6b0 DB\ub9c8\ub2e4 \ub2e4\ub974\uac8c \ub3d9\uc791\ud55c\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"h2\uc758 Connection \uad6c\ud604\uccb4\ub294 readOnly \uc124\uc815\uc744 \ubb34\uc2dc\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 Transactional \uc801\uc6a9\ub418\uc9c0 \uc54a\ub294\ub2e4. "),(0,a.kt)("li",{parentName:"ul"},"MySQL 8.0(InnoDB \uc0ac\uc6a9 \uc2dc)\uc758 \uacbd\uc6b0 \uc77d\uae30 \uc804\uc6a9\uc73c\ub85c \uc54c\ub824\uc9c4 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158 ID\ub97c \uc124\uc815\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uc870\ud68c \uc18d\ub3c4\uac00 \ub354 \ube68\ub77c\uc9c4\ub2e4.")),(0,a.kt)("p",null,"ORM \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 prepareTransactionalConnection\ub97c \ud638\ucd9c\ud55c\ub2e4\uace0 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ud604\uc5c5\uc5d0\uc11c\ub294 \uace0\uac00\uc6a9\uc131 \ub0b4\uacb0\ud568\uc131 \ub4f1\uc744 \uc704\ud558\uc5ec \ud074\ub7ec\uc2a4\ud130\ub97c \uad6c\uc131\ud558\uc5ec \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uace0, \uc774 \uacbd\uc6b0 readOnly \uc124\uc815\uc774 \ub418\uc5b4\uc788\ub2e4\uba74 \uc77d\uae30 \uc804\uc6a9 DB\ub85c \uc9c8\uc758\uac00 \ub4e4\uc5b4\uac00\uc11c \ubd80\ud558 \ubd84\uc0b0\uc758 \ud6a8\uacfc\uac00 \uc788\ub2e4\uace0 \ud55c\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"DAO\uc5d0 ",(0,a.kt)("inlineCode",{parentName:"strong"},"@Transactional")," \uc801\uc6a9")," "),(0,a.kt)("p",null,"DAO\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \ubcf4\ub294 \uac74 \uc5b4\ub5bb\uaca0\ub0d0\uace0 \ub9ac\ubdf0\uac00 \ub2ec\ub824\uc11c \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Service \uacc4\uce35\uc5d0 \uc774\ubbf8 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud574 \uc8fc\uace0 \uc788\uae30\uc5d0 \ud544\uc694 \uc5c6\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","DAO\ub97c \ub2e4\ub978 \uacf3\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ud2b8\ub79c\uc7ad\uc158\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574(\ud655\uc7a5\uc131 \uace0\ub824) ",(0,a.kt)("inlineCode",{parentName:"p"},"@Transactional"),"\uc744 \uc801\uc6a9\ud558\ub294 \uac83\ub3c4 \uad1c\ucc2e\uc740 \uac83 \uac19\ub2e4."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b2ebb6fd.301d7a2d.js b/assets/js/b2ebb6fd.301d7a2d.js new file mode 100644 index 000000000..2cb279a35 --- /dev/null +++ b/assets/js/b2ebb6fd.301d7a2d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4091],{8343:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var i=s(85893),t=s(3905);const a={title:"Jenkins\ub85c CI/CD \uc124\uc815",slug:"jenkins",tags:["Jenkins","Elastic Beanstalk"]},r=void 0,l={permalink:"/jenkins",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",source:"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",title:"Jenkins\ub85c CI/CD \uc124\uc815",description:"\uc124\uc815 \ud658\uacbd",date:"2023-04-30T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 30\uc77c",tags:[{label:"Jenkins",permalink:"/tags/jenkins"},{label:"Elastic Beanstalk",permalink:"/tags/elastic-beanstalk"}],readingTime:7.495,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Jenkins\ub85c CI/CD \uc124\uc815",slug:"jenkins",tags:["Jenkins","Elastic Beanstalk"]},unlisted:!1,prevItem:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",permalink:"/tecochat-retrospective-2"},nextItem:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",permalink:"/tecochat-retrospective-1"}},o={authorsImageUrls:[]},c=[{value:"\uc124\uc815 \ud658\uacbd",id:"\uc124\uc815-\ud658\uacbd",level:3},{value:"[EC2 CLI] Swap \uba54\ubaa8\ub9ac \uc124\uc815",id:"ec2-cli-swap-\uba54\ubaa8\ub9ac-\uc124\uc815",level:3},{value:"[EC2 CLI] jenkins \uc124\uce58",id:"ec2-cli-jenkins-\uc124\uce58",level:3},{value:"[EC2 CLI] Jenkins \uc2dc\uc791",id:"ec2-cli-jenkins-\uc2dc\uc791",level:3},{value:"[EC2 CLI] nginx & git \uc124\uce58",id:"ec2-cli-nginx--git-\uc124\uce58",level:3},{value:"[EC2 CLI] nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815",id:"ec2-cli-nginx-\ub9ac\ubc84\uc2a4-\ud504\ub85d\uc2dc-\uc124\uc815",level:3},{value:"[Jenkins] Jenkins \uc811\uc18d",id:"jenkins-jenkins-\uc811\uc18d",level:3},{value:"[Jenkins] Jenkins Blue Ocean \uc124\uce58",id:"jenkins-jenkins-blue-ocean-\uc124\uce58",level:3},{value:"[AWS IAM & EC2] IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30",id:"aws-iam--ec2-iam\uc73c\ub85c-ec2-\uc778\uc2a4\ud134\uc2a4-\uad8c\ud55c-\uc124\uc815\ud558\uae30",level:3},{value:"[AWS S3] Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131",id:"aws-s3-jar-\ud30c\uc77c\uc744-\uc5c5\ub85c\ub4dc-\ud560-s3-\ubc84\ud0b7-\uc0dd\uc131",level:3},{value:"[Github] Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131",id:"github-blue-ocean\uc5d0\uc11c-\ud30c\uc774\ud504\ub77c\uc778-\uc0dd\uc131\uc5d0-\ud544\uc694\ud55c-github-token-\uc0dd\uc131",level:3},{value:"[Jenkins] \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791",id:"jenkins-\ube14\ub8e8-\uc624\uc158-\uc2dc\uc791",level:3},{value:"[Github Repsoitory] Jenkinsfile \uc124\uc815",id:"github-repsoitory-jenkinsfile-\uc124\uc815",level:3},{value:"[Github] Webhooks \uc124\uc815",id:"github-webhooks-\uc124\uc815",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",br:"br",code:"code",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.ah)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"\uc124\uc815-\ud658\uacbd",children:"\uc124\uc815 \ud658\uacbd"}),"\n",(0,i.jsxs)(n.p,{children:["\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc774\ubbf8\uc9c0: Amazon Linux 2023 AMI",(0,i.jsx)(n.br,{}),"\n","\uc544\ud0a4\ud14d\uccd0: ARM",(0,i.jsx)(n.br,{}),"\n","\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small",(0,i.jsx)(n.br,{}),"\n","\ud658\uacbd \uad6c\uc131\uc774 \uc644\ub8cc\ub41c Elastic Beanstalk",(0,i.jsx)(n.br,{}),"\n","\ub2e8\uc77c Spring Boot \ud504\ub85c\uc81d\ud2b8\uac00 \uc874\uc7ac\ud558\ub294 Github Repository"]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-swap-\uba54\ubaa8\ub9ac-\uc124\uc815",children:"[EC2 CLI] Swap \uba54\ubaa8\ub9ac \uc124\uc815"}),"\n",(0,i.jsxs)(n.p,{children:["t4g.small\uc774 \ub7a8\uc774 2G\uc778\ub370 \ub7a8\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \ub290\uaef4\uc838\uc11c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc544\ub798 \uba85\ub839\uc5b4\ub97c \ub530\ub77c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud558\uace0 free -h \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uc798 \uc124\uc815\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"# fallocate \uc774\uc6a9\ud558\uc5ec \uc2a4\uc651 \ud30c\uc77c \uc0dd\uc131\nsudo fallocate -l 2G /swapfile\n\n# \uad8c\ud55c \uc124\uc815\nsudo chmod 600 /swapfile\n\n# \ud30c\uc77c\uc744 Swap \ud3ec\ub9f7\uc73c\ub85c \ubcc0\uacbd \ud6c4 \uc2dc\uc2a4\ud15c\uc5d0 \ub4f1\ub85d\nsudo mkswap /swapfile\nsudo swapon /swapfile\n\n# Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9\n# \ucd5c\ud558\ub2e8\uc5d0 \ub2e4\uc74c \uad6c\ubb38 \uc124\uc815 -> /swapfile swap swap defaults 0 0\nsudo vim /etc/fstab\n"})}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-jenkins-\uc124\uce58",children:"[EC2 CLI] jenkins \uc124\uce58"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo wget -O /etc/yum.repos.d/jenkins.repo \\\n https://pkg.jenkins.io/redhat-stable/jenkins.repo\nsudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key\nsudo yum upgrade\nsudo yum install java-17-amazon-corretto-devel\nsudo yum install jenkins\nsudo systemctl daemon-reload\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos",children:"Jenkins \uacf5\uc2dd \ud648\ud398\uc774\uc9c0"})," \ub97c \ucc38\uace0\ud558\uc5ec \uc124\uce58\ud558\ub294 \uac8c \uc88b\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-jenkins-\uc2dc\uc791",children:"[EC2 CLI] Jenkins \uc2dc\uc791"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl enable jenkins\nsudo systemctl start jenkins\n"})}),"\n",(0,i.jsx)(n.p,{children:"enable\ub85c \uc124\uc815\ud558\uc5ec \ubd80\ud305\uc2dc \uc790\ub3d9\uc2dc\uc791 \ub418\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-nginx--git-\uc124\uce58",children:"[EC2 CLI] nginx & git \uc124\uce58"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo yum install nginx\nsudo systemctl enable nginx\nsudo systemctl start nginx\n\nsudo yum install git\n"})}),"\n",(0,i.jsx)(n.p,{children:"nginx\uc640 \ucf54\ub4dc\ub97c \ubd88\ub7ec\uc62c \ub54c \uc0ac\uc6a9\ud560 git\uc744 \uc124\uce58\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"ec2-cli-nginx-\ub9ac\ubc84\uc2a4-\ud504\ub85d\uc2dc-\uc124\uc815",children:"[EC2 CLI] nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815"}),"\n",(0,i.jsx)(n.p,{children:"\uc544\ub798 \uc124\uc815 \ud30c\uc77c\uc740 \uacf5\uc2dd \ud648\ud398\uc774\uc9c0\uc5d0\uc11c \uc548\ub0b4\ud55c \uae30\ubcf8\uc801\uc778 \uc124\uc815 \ud30c\uc77c\uc774\ub2e4."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'upstream jenkins {\n keepalive 32; # keepalive connections\n server 127.0.0.1:8080; # jenkins ip and port\n}\n\n# Required for Jenkins websocket agents\nmap $http_upgrade $connection_upgrade {\n default upgrade;\n \'\' close;\n}\n\nserver {\n listen 80; # Listen on port 80 for IPv4 requests\n\n server_name jenkins.example.com; # replace \'jenkins.example.com\' with your server domain name\n\n # this is the jenkins web root directory\n # (mentioned in the output of "systemctl cat jenkins")\n root /var/run/jenkins/war/;\n\n access_log /var/log/nginx/jenkins.access.log;\n error_log /var/log/nginx/jenkins.error.log;\n\n # pass through headers from Jenkins that Nginx considers invalid\n ignore_invalid_headers off;\n\n location ~ "^/static/[0-9a-fA-F]{8}\\/(.*)$" {\n # rewrite all static files into requests to the root\n # E.g /static/12345678/css/something.css will become /css/something.css\n rewrite "^/static/[0-9a-fA-F]{8}\\/(.*)" /$1 last;\n }\n\n location /userContent {\n # have nginx handle all the static requests to userContent folder\n # note : This is the $JENKINS_HOME dir\n root /var/lib/jenkins/;\n if (!-f $request_filename){\n # this file does not exist, might be a directory or a /**view** url\n rewrite (.*) /$1 last;\n break;\n }\n sendfile on;\n }\n\n location / {\n sendfile off;\n proxy_pass http://jenkins;\n proxy_redirect default;\n proxy_http_version 1.1;\n\n # Required for Jenkins websocket agents\n proxy_set_header Connection $connection_upgrade;\n proxy_set_header Upgrade $http_upgrade;\n\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_max_temp_file_size 0;\n\n #this is the maximum upload size\n client_max_body_size 10m;\n client_body_buffer_size 128k;\n\n proxy_connect_timeout 90;\n proxy_send_timeout 90;\n proxy_read_timeout 90;\n proxy_buffering off;\n proxy_request_buffering off; # Required for HTTP CLI commands\n proxy_set_header Connection ""; # Clear for keepalive\n }\n\n}\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Jenkins\ub294 8080 \ud3ec\ud2b8\ub85c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc\ub97c \uc124\uc815\ud574\uc900\ub2e4.",(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.code,{children:"/etc/nginx/conf.d"}),"\xa0\uc544\ub798\xa0",(0,i.jsx)(n.code,{children:"default.conf"}),"\xa0\ud30c\uc77c\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uace0 \uc704\uc640 \uac19\uc774 \uc785\ub825\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","nginx\uc758 \uae30\ubcf8 \uc124\uc815 \ud30c\uc77c\uc5d0 \uc874\uc7ac\ud558\ub294\xa0",(0,i.jsx)(n.code,{children:"include /etc/nginx/conf.d/*.conf;"}),"\xa0\uc124\uc815 \ub54c\ubb38\uc5d0\xa0",(0,i.jsx)(n.code,{children:".conf"}),"\xa0\ub85c \ub05d\ub09c\ub2e4\uba74 \uc124\uc815\uc774 \uc801\uc6a9\ub41c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc124\uc815 \ud6c4\xa0",(0,i.jsx)(n.code,{children:"sudo nginx -t"}),"\ub85c \uc124\uc815\ud30c\uc77c\uc774 \uc815\uc0c1\uc778\uc9c0 \ud655\uc778\ud558\uace0,\xa0",(0,i.jsx)(n.code,{children:"sudo systemctl restart nginx"}),"\xa0\uba85\ub839\uc5b4\ub85c nginx\ub97c \uc7ac\uc2dc\uc791\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"jenkins-jenkins-\uc811\uc18d",children:"[Jenkins] Jenkins \uc811\uc18d"}),"\n",(0,i.jsxs)(n.p,{children:["Jenkins\ub97c \uc124\uce58\ud55c EC2 \uc778\uc2a4\ud134\uc2a4 \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc5d0 80\ubc88 \ud3ec\ud2b8\uac00 \uc5f4\ub824\uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","EC2\uc758 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \uc785\ub825\ud558\uace0 \ub4e4\uc5b4\uac00\uba74 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\ub77c\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"jenkins-start",src:s(71399).Z+"",width:"2008",height:"1836"})}),"\n",(0,i.jsxs)(n.p,{children:["\ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud574\uc57c \ud558\ub294\ub370 ",(0,i.jsx)(n.code,{children:"sudo cat /var/lib/jenkins/secrets/initialAdminPasswor"})," \ub97c \uc785\ub825\ud574 \ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc5bb\uc744 \uc218 \uc788\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\uba74 \ud50c\ub7ec\uadf8\uc778 \uc124\uc815 \ucc3d\uc774 \ub098\uc62c\ud150\ub370 ",(0,i.jsx)(n.code,{children:"install suggested plugins"}),"\uc744 \ud074\ub9ad\ud558\uc5ec Jenkins\uac00 \ucd94\ucc9c\ud558\ub294 \uae30\ubcf8 \ud50c\ub7ec\uadf8\uc778\ub4e4\uc744 \uc124\uce58\ud558\uba74 \ub41c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ud50c\ub7ec\uadf8\uc778\uc744 \uc124\uce58\ud558\uba74 \uacc4\uc815 \ubc0f \uc8fc\uc18c \uc124\uc815\uc744 \ud574\uc57c\ud558\ub294\ub370 \uc774\uac74 \ud3b8\ud558\uac8c \uc124\uc815\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"jenkins-jenkins-blue-ocean-\uc124\uce58",children:"[Jenkins] Jenkins Blue Ocean \uc124\uce58"}),"\n",(0,i.jsx)(n.p,{children:"Jenkins \uad00\ub9ac \u2192 Plugin Manager\uc5d0\uc11c Blue Ocean\uc744 \uac80\uc0c9\ud574 \uc124\uce58\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"aws-iam--ec2-iam\uc73c\ub85c-ec2-\uc778\uc2a4\ud134\uc2a4-\uad8c\ud55c-\uc124\uc815\ud558\uae30",children:"[AWS IAM & EC2] IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30"}),"\n",(0,i.jsxs)(n.p,{children:["S3\uc640 Elastic Beanstalk\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc744 \ubd80\uc5ec\ud558\ub824\uba74 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk \ub450 \uac1c\uc758 \uc815\ucc45\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uc5ed\ud560\uc744 \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","IAM\uc5d0\uc11c \ub2e4\uc74c\uacfc \uac19\uc774 \uc5ed\ud560\uc744 \ud558\ub098 \uc0c8\ub85c \uc0dd\uc131\ud55c\ub2e4."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"\uc5d4\ud130\ud2f0 \uc120\ud0dd"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-iam1",src:s(30618).Z+"",width:"2282",height:"1028"})}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsx)(n.li,{children:"\uad8c\ud55c \ucd94\uac00"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-iam2",src:s(56786).Z+"",width:"2300",height:"880"})}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsx)(n.li,{children:"\uc774\ub984 \uc9c0\uc815, \uac80\ud1a0 \ubc0f \uc0dd\uc131"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-iam3",src:s(63303).Z+"",width:"1872",height:"1724"})}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsx)(n.li,{children:"\uc0dd\uc131\ud55c IAM EC2 Jenkins \uc778\uc2a4\ud134\uc2a4\ub97c \uc120\ud0dd\ud558\uace0, \uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc744 \ub20c\ub7ec Role \uc124\uc815"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-iam4",src:s(82150).Z+"",width:"2264",height:"602"})}),"\n",(0,i.jsx)(n.h3,{id:"aws-s3-jar-\ud30c\uc77c\uc744-\uc5c5\ub85c\ub4dc-\ud560-s3-\ubc84\ud0b7-\uc0dd\uc131",children:"[AWS S3] Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131"}),"\n",(0,i.jsx)(n.p,{children:"\ubc84\ud0b7\uc744 \uc0dd\uc131\ud560 \ub54c \ub2e4\uc74c \uc124\uc815\uc744 \uc81c\uc678\ud558\uace0 \ubaa8\ub450 \ucc28\ub2e8 \ud65c\uc131\ud654\ub97c \ud574\uc900\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"\uc0c8 ACL(\uc561\uc138\uc2a4 \uc81c\uc5b4 \ubaa9\ub85d)\uc744 \ud1b5\ud574 \ubd80\uc5ec\ub41c \ubc84\ud0b7 \ubc0f \uac1d\uccb4\uc5d0 \ub300\ud55c \ud37c\ube14\ub9ad \uc561\uc138\uc2a4 \ucc28\ub2e8"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"aws-s3",src:s(36238).Z+"",width:"1636",height:"1258"})}),"\n",(0,i.jsx)(n.h3,{id:"github-blue-ocean\uc5d0\uc11c-\ud30c\uc774\ud504\ub77c\uc778-\uc0dd\uc131\uc5d0-\ud544\uc694\ud55c-github-token-\uc0dd\uc131",children:"[Github] Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131"}),"\n",(0,i.jsxs)(n.p,{children:["repo, user",":email"," \uad8c\ud55c\uc774 \uc788\ub294 \ud1a0\ud070\uc774 \ud544\uc694\ud558\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"jenkins-\ube14\ub8e8-\uc624\uc158-\uc2dc\uc791",children:"[Jenkins] \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"jenkins-blue-ocean1",src:s(29666).Z+"",width:"2390",height:"1372"})}),"\n",(0,i.jsxs)(n.p,{children:["\ube14\ub8e8 \uc624\uc158 \uc5f4\uae30\ub85c \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc0dd\uc131\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ud1a0\ud070 \uc785\ub825 \u2192 \uc870\uc9c1 \uc120\ud0dd \u2192 CI/CD \uc124\uc815\ud560 Repository \uc120\ud0dd\uc744 \ud558\uba74 \ud30c\uc774\ud504\ub77c\uc778 \ucc3d\uc73c\ub85c \ub118\uc5b4\uac04\ub2e4.",(0,i.jsx)(n.br,{}),"\n","Jenkinsfile\uc744 \uc9c1\uc811 \uc791\uc131\ud558\uc5ec \uc124\uc815\ud558\uae30 \uc704\ud574 \uac04\ub2e8\ud558\uac8c print \ud558\ub098 \ucd9c\ub825\ud558\ub294 \uac83\uc73c\ub85c \uc124\uc815\ud588\ub2e4."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"jenkins-blue-ocean2",src:s(49614).Z+"",width:"2076",height:"638"})}),"\n",(0,i.jsx)(n.p,{children:"\ud30c\uc774\ud504\ub77c\uc778\uc774 \uc2e4\ud589\ub420 \ud150\ub370 pipeline status\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \ucd08\ub85d\ubd88\uc774 \ub728\uba74 \ub41c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"jenkins-blue-ocean3",src:s(71079).Z+"",width:"1084",height:"626"})}),"\n",(0,i.jsx)(n.h3,{id:"github-repsoitory-jenkinsfile-\uc124\uc815",children:"[Github Repsoitory] Jenkinsfile \uc124\uc815"}),"\n",(0,i.jsx)(n.p,{children:"\ube14\ub8e8 \uc624\uc158 \uc2dc\uc791\uc744 \ud1b5\ud574 \uc124\uc815\ud558\uba74 Jenkinsfile\uc774 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc9c0\uace0, \uc544\ub798\uc640 \uac19\uc774 \uc6d0\ud558\ub294 \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc124\uc815\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"pipeline {\n agent any\n stages {\n stage('build and test') {\n steps {\n sh '/gradlew clean build'\n }\n }\n stage('zip') {\n steps {\n sh 'mv ./build/libs/woowachat.jar .'\n sh 'zip -r woowachat.zip .platform delivery.jar Procfile'\n }\n }\n stage('upload') {\n steps {\n sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'\n }\n }\n stage('deploy') {\n steps {\n sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket=\"woowa-chat\",S3Key=\"woowachat.zip\"'\n sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'\n }\n }\n }\n}\n"})}),"\n",(0,i.jsx)(n.h3,{id:"github-webhooks-\uc124\uc815",children:"[Github] Webhooks \uc124\uc815"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"github-hook",src:s(36642).Z+"",width:"1428",height:"1148"})}),"\n",(0,i.jsxs)(n.p,{children:["push \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud560 \ub54c ",(0,i.jsx)(n.code,{children:"http://Jenkins\uc8fc\uc18c/github-webhook/"})," \ub85c post request\ub97c \ud558\ub3c4\ub85d \uc6f9\ud6c5\uc744 \uc124\uc815\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos",children:"Install Jenkins - CentOS, Jenkins"}),(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.a,{href:"https://www.jenkins.io/doc/book/system-administration/reverse-proxy-configuration-nginx/",children:"Nginx Reverse Proxy Configuration, Jenkins"}),(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html",children:"Amazon Corretto 17 JDK Install, AWS"}),(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.a,{href:"https://docs.aws.amazon.com/linux/al2023/release-notes/all-packages-al2023-20230419.html",children:"Amazon Linux 2023 packages, AWS"})]})]})}function h(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},3905:(e,n,s)=>{s.d(n,{ah:()=>c});var i=s(67294);function t(e,n,s){return n in e?Object.defineProperty(e,n,{value:s,enumerable:!0,configurable:!0,writable:!0}):e[n]=s,e}function a(e,n){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),s.push.apply(s,i)}return s}function r(e){for(var n=1;n<arguments.length;n++){var s=null!=arguments[n]?arguments[n]:{};n%2?a(Object(s),!0).forEach((function(n){t(e,n,s[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(s)):a(Object(s)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(s,n))}))}return e}function l(e,n){if(null==e)return{};var s,i,t=function(e,n){if(null==e)return{};var s,i,t={},a=Object.keys(e);for(i=0;i<a.length;i++)s=a[i],n.indexOf(s)>=0||(t[s]=e[s]);return t}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(i=0;i<a.length;i++)s=a[i],n.indexOf(s)>=0||Object.prototype.propertyIsEnumerable.call(e,s)&&(t[s]=e[s])}return t}var o=i.createContext({}),c=function(e){var n=i.useContext(o),s=n;return e&&(s="function"==typeof e?e(n):r(r({},n),e)),s},d={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},h=i.forwardRef((function(e,n){var s=e.components,t=e.mdxType,a=e.originalType,o=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=c(s),u=t,j=p["".concat(o,".").concat(u)]||p[u]||d[u]||a;return s?i.createElement(j,r(r({ref:n},h),{},{components:s})):i.createElement(j,r({ref:n},h))}));h.displayName="MDXCreateElement"},30618:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-iam1-e6d63be6b9f41d63e91d604138e6b07c.png"},56786:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-iam2-557683fc91b1c22330d081d6050dfe82.png"},63303:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-iam3-94248e9194dd58bb16d0289af47a4260.png"},82150:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-iam4-54ccc5a4e64d31f7eeab89d39ebf772f.png"},36238:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/aws-s3-757380d36e5492c962f75dae024994e5.png"},36642:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/github-hook-e9ebe0acb3ff0086ecebbd8c857ffe39.png"},29666:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/jenkins-blue-ocean1-bd108d887d700ea081e4b0a3d83ad459.png"},49614:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/jenkins-blue-ocean2-408c6c90e4a5371becc4d1013fba1212.png"},71079:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/jenkins-blue-ocean3-4050a206b3efe95a3c9f39c3f7a47ad7.png"},71399:(e,n,s)=>{s.d(n,{Z:()=>i});const i=s.p+"assets/images/jenkins-start-dce0d7051054c398d2a707c75c685234.png"}}]); \ No newline at end of file diff --git a/assets/js/b2ebb6fd.a5bc8099.js b/assets/js/b2ebb6fd.a5bc8099.js deleted file mode 100644 index e1f1c64d0..000000000 --- a/assets/js/b2ebb6fd.a5bc8099.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4091],{3905:(e,n,t)=>{t.d(n,{Zo:()=>c,kt:()=>d});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function r(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?s(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function l(e,n){if(null==e)return{};var t,a,i=function(e,n){if(null==e)return{};var t,a,i={},s=Object.keys(e);for(a=0;a<s.length;a++)t=s[a],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a<s.length;a++)t=s[a],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var o=a.createContext({}),p=function(e){var n=a.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):r(r({},n),e)),t},c=function(e){var n=p(e.components);return a.createElement(o.Provider,{value:n},e.children)},k={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},u=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,s=e.originalType,o=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=p(t),d=i,m=u["".concat(o,".").concat(d)]||u[d]||k[d]||s;return t?a.createElement(m,r(r({ref:n},c),{},{components:t})):a.createElement(m,r({ref:n},c))}));function d(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var s=t.length,r=new Array(s);r[0]=u;var l={};for(var o in n)hasOwnProperty.call(n,o)&&(l[o]=n[o]);l.originalType=e,l.mdxType="string"==typeof e?e:i,r[1]=l;for(var p=2;p<s;p++)r[p]=t[p];return a.createElement.apply(null,r)}return a.createElement.apply(null,t)}u.displayName="MDXCreateElement"},34604:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>k,frontMatter:()=>s,metadata:()=>l,toc:()=>p});var a=t(87462),i=(t(67294),t(3905));const s={title:"Jenkins\ub85c CI/CD \uc124\uc815",slug:"jenkins",tags:["Jenkins","Elastic Beanstalk"]},r=void 0,l={permalink:"/jenkins",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",source:"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",title:"Jenkins\ub85c CI/CD \uc124\uc815",description:"\uc124\uc815 \ud658\uacbd",date:"2023-04-30T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 30\uc77c",tags:[{label:"Jenkins",permalink:"/tags/jenkins"},{label:"Elastic Beanstalk",permalink:"/tags/elastic-beanstalk"}],readingTime:7.495,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Jenkins\ub85c CI/CD \uc124\uc815",slug:"jenkins",tags:["Jenkins","Elastic Beanstalk"]},prevItem:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",permalink:"/tecochat-retrospective-2"},nextItem:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",permalink:"/tecochat-retrospective-1"}},o={authorsImageUrls:[]},p=[{value:"\uc124\uc815 \ud658\uacbd",id:"\uc124\uc815-\ud658\uacbd",level:3},{value:"[EC2 CLI] Swap \uba54\ubaa8\ub9ac \uc124\uc815",id:"ec2-cli-swap-\uba54\ubaa8\ub9ac-\uc124\uc815",level:3},{value:"[EC2 CLI] jenkins \uc124\uce58",id:"ec2-cli-jenkins-\uc124\uce58",level:3},{value:"[EC2 CLI] Jenkins \uc2dc\uc791",id:"ec2-cli-jenkins-\uc2dc\uc791",level:3},{value:"[EC2 CLI] nginx & git \uc124\uce58",id:"ec2-cli-nginx--git-\uc124\uce58",level:3},{value:"[EC2 CLI] nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815",id:"ec2-cli-nginx-\ub9ac\ubc84\uc2a4-\ud504\ub85d\uc2dc-\uc124\uc815",level:3},{value:"[Jenkins] Jenkins \uc811\uc18d",id:"jenkins-jenkins-\uc811\uc18d",level:3},{value:"[Jenkins] Jenkins Blue Ocean \uc124\uce58",id:"jenkins-jenkins-blue-ocean-\uc124\uce58",level:3},{value:"[AWS IAM & EC2] IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30",id:"aws-iam--ec2-iam\uc73c\ub85c-ec2-\uc778\uc2a4\ud134\uc2a4-\uad8c\ud55c-\uc124\uc815\ud558\uae30",level:3},{value:"[AWS S3] Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131",id:"aws-s3-jar-\ud30c\uc77c\uc744-\uc5c5\ub85c\ub4dc-\ud560-s3-\ubc84\ud0b7-\uc0dd\uc131",level:3},{value:"[Github] Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131",id:"github-blue-ocean\uc5d0\uc11c-\ud30c\uc774\ud504\ub77c\uc778-\uc0dd\uc131\uc5d0-\ud544\uc694\ud55c-github-token-\uc0dd\uc131",level:3},{value:"[Jenkins] \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791",id:"jenkins-\ube14\ub8e8-\uc624\uc158-\uc2dc\uc791",level:3},{value:"[Github Repsoitory] Jenkinsfile \uc124\uc815",id:"github-repsoitory-jenkinsfile-\uc124\uc815",level:3},{value:"[Github] Webhooks \uc124\uc815",id:"github-webhooks-\uc124\uc815",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:p};function k(e){let{components:n,...s}=e;return(0,i.kt)("wrapper",(0,a.Z)({},c,s,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h3",{id:"\uc124\uc815-\ud658\uacbd"},"\uc124\uc815 \ud658\uacbd"),(0,i.kt)("p",null,"\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc774\ubbf8\uc9c0: Amazon Linux 2023 AMI",(0,i.kt)("br",{parentName:"p"}),"\n","\uc544\ud0a4\ud14d\uccd0: ARM",(0,i.kt)("br",{parentName:"p"}),"\n","\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small",(0,i.kt)("br",{parentName:"p"}),"\n","\ud658\uacbd \uad6c\uc131\uc774 \uc644\ub8cc\ub41c Elastic Beanstalk",(0,i.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc77c Spring Boot \ud504\ub85c\uc81d\ud2b8\uac00 \uc874\uc7ac\ud558\ub294 Github Repository"),(0,i.kt)("h3",{id:"ec2-cli-swap-\uba54\ubaa8\ub9ac-\uc124\uc815"},"[","EC2 CLI","]"," Swap \uba54\ubaa8\ub9ac \uc124\uc815"),(0,i.kt)("p",null,"t4g.small\uc774 \ub7a8\uc774 2G\uc778\ub370 \ub7a8\uc774 \ubd80\uc871\ud558\ub2e4\uace0 \ub290\uaef4\uc838\uc11c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud588\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\uc544\ub798 \uba85\ub839\uc5b4\ub97c \ub530\ub77c swap \uba54\ubaa8\ub9ac\ub97c \uc124\uc815\ud558\uace0 free -h \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uc798 \uc124\uc815\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"# fallocate \uc774\uc6a9\ud558\uc5ec \uc2a4\uc651 \ud30c\uc77c \uc0dd\uc131\nsudo fallocate -l 2G /swapfile\n\n# \uad8c\ud55c \uc124\uc815\nsudo chmod 600 /swapfile\n\n# \ud30c\uc77c\uc744 Swap \ud3ec\ub9f7\uc73c\ub85c \ubcc0\uacbd \ud6c4 \uc2dc\uc2a4\ud15c\uc5d0 \ub4f1\ub85d\nsudo mkswap /swapfile\nsudo swapon /swapfile\n\n# Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9\n# \ucd5c\ud558\ub2e8\uc5d0 \ub2e4\uc74c \uad6c\ubb38 \uc124\uc815 -> /swapfile swap swap defaults 0 0\nsudo vim /etc/fstab\n")),(0,i.kt)("h3",{id:"ec2-cli-jenkins-\uc124\uce58"},"[","EC2 CLI","]"," jenkins \uc124\uce58"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo wget -O /etc/yum.repos.d/jenkins.repo \\\n https://pkg.jenkins.io/redhat-stable/jenkins.repo\nsudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key\nsudo yum upgrade\nsudo yum install java-17-amazon-corretto-devel\nsudo yum install jenkins\nsudo systemctl daemon-reload\n")),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos"},"Jenkins \uacf5\uc2dd \ud648\ud398\uc774\uc9c0")," \ub97c \ucc38\uace0\ud558\uc5ec \uc124\uce58\ud558\ub294 \uac8c \uc88b\ub2e4."),(0,i.kt)("h3",{id:"ec2-cli-jenkins-\uc2dc\uc791"},"[","EC2 CLI","]"," Jenkins \uc2dc\uc791"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo systemctl enable jenkins\nsudo systemctl start jenkins\n")),(0,i.kt)("p",null,"enable\ub85c \uc124\uc815\ud558\uc5ec \ubd80\ud305\uc2dc \uc790\ub3d9\uc2dc\uc791 \ub418\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."),(0,i.kt)("h3",{id:"ec2-cli-nginx--git-\uc124\uce58"},"[","EC2 CLI","]"," nginx & git \uc124\uce58"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo yum install nginx\nsudo systemctl enable nginx\nsudo systemctl start nginx\n\nsudo yum install git\n")),(0,i.kt)("p",null,"nginx\uc640 \ucf54\ub4dc\ub97c \ubd88\ub7ec\uc62c \ub54c \uc0ac\uc6a9\ud560 git\uc744 \uc124\uce58\ud55c\ub2e4."),(0,i.kt)("h3",{id:"ec2-cli-nginx-\ub9ac\ubc84\uc2a4-\ud504\ub85d\uc2dc-\uc124\uc815"},"[","EC2 CLI","]"," nginx \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc \uc124\uc815"),(0,i.kt)("p",null,"\uc544\ub798 \uc124\uc815 \ud30c\uc77c\uc740 \uacf5\uc2dd \ud648\ud398\uc774\uc9c0\uc5d0\uc11c \uc548\ub0b4\ud55c \uae30\ubcf8\uc801\uc778 \uc124\uc815 \ud30c\uc77c\uc774\ub2e4."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'upstream jenkins {\n keepalive 32; # keepalive connections\n server 127.0.0.1:8080; # jenkins ip and port\n}\n\n# Required for Jenkins websocket agents\nmap $http_upgrade $connection_upgrade {\n default upgrade;\n \'\' close;\n}\n\nserver {\n listen 80; # Listen on port 80 for IPv4 requests\n\n server_name jenkins.example.com; # replace \'jenkins.example.com\' with your server domain name\n\n # this is the jenkins web root directory\n # (mentioned in the output of "systemctl cat jenkins")\n root /var/run/jenkins/war/;\n\n access_log /var/log/nginx/jenkins.access.log;\n error_log /var/log/nginx/jenkins.error.log;\n\n # pass through headers from Jenkins that Nginx considers invalid\n ignore_invalid_headers off;\n\n location ~ "^/static/[0-9a-fA-F]{8}\\/(.*)$" {\n # rewrite all static files into requests to the root\n # E.g /static/12345678/css/something.css will become /css/something.css\n rewrite "^/static/[0-9a-fA-F]{8}\\/(.*)" /$1 last;\n }\n\n location /userContent {\n # have nginx handle all the static requests to userContent folder\n # note : This is the $JENKINS_HOME dir\n root /var/lib/jenkins/;\n if (!-f $request_filename){\n # this file does not exist, might be a directory or a /**view** url\n rewrite (.*) /$1 last;\n break;\n }\n sendfile on;\n }\n\n location / {\n sendfile off;\n proxy_pass http://jenkins;\n proxy_redirect default;\n proxy_http_version 1.1;\n\n # Required for Jenkins websocket agents\n proxy_set_header Connection $connection_upgrade;\n proxy_set_header Upgrade $http_upgrade;\n\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_max_temp_file_size 0;\n\n #this is the maximum upload size\n client_max_body_size 10m;\n client_body_buffer_size 128k;\n\n proxy_connect_timeout 90;\n proxy_send_timeout 90;\n proxy_read_timeout 90;\n proxy_buffering off;\n proxy_request_buffering off; # Required for HTTP CLI commands\n proxy_set_header Connection ""; # Clear for keepalive\n }\n\n}\n')),(0,i.kt)("p",null,"Jenkins\ub294 8080 \ud3ec\ud2b8\ub85c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubc84\uc2a4 \ud504\ub85d\uc2dc\ub97c \uc124\uc815\ud574\uc900\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/nginx/conf.d"),"\xa0\uc544\ub798\xa0",(0,i.kt)("inlineCode",{parentName:"p"},"default.conf"),"\xa0\ud30c\uc77c\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uace0 \uc704\uc640 \uac19\uc774 \uc785\ub825\ud558\uace0 \uc800\uc7a5\ud55c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","nginx\uc758 \uae30\ubcf8 \uc124\uc815 \ud30c\uc77c\uc5d0 \uc874\uc7ac\ud558\ub294\xa0",(0,i.kt)("inlineCode",{parentName:"p"},"include /etc/nginx/conf.d/*.conf;"),"\xa0\uc124\uc815 \ub54c\ubb38\uc5d0\xa0",(0,i.kt)("inlineCode",{parentName:"p"},".conf"),"\xa0\ub85c \ub05d\ub09c\ub2e4\uba74 \uc124\uc815\uc774 \uc801\uc6a9\ub41c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\uc124\uc815 \ud6c4\xa0",(0,i.kt)("inlineCode",{parentName:"p"},"sudo nginx -t"),"\ub85c \uc124\uc815\ud30c\uc77c\uc774 \uc815\uc0c1\uc778\uc9c0 \ud655\uc778\ud558\uace0,\xa0",(0,i.kt)("inlineCode",{parentName:"p"},"sudo systemctl restart nginx"),"\xa0\uba85\ub839\uc5b4\ub85c nginx\ub97c \uc7ac\uc2dc\uc791\ud55c\ub2e4. "),(0,i.kt)("h3",{id:"jenkins-jenkins-\uc811\uc18d"},"[","Jenkins","]"," Jenkins \uc811\uc18d"),(0,i.kt)("p",null,"Jenkins\ub97c \uc124\uce58\ud55c EC2 \uc778\uc2a4\ud134\uc2a4 \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc5d0 80\ubc88 \ud3ec\ud2b8\uac00 \uc5f4\ub824\uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","EC2\uc758 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \uc785\ub825\ud558\uace0 \ub4e4\uc5b4\uac00\uba74 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\ub77c\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"jenkins-start",src:t(71399).Z,width:"2008",height:"1836"})),(0,i.kt)("p",null,"\ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud574\uc57c \ud558\ub294\ub370 ",(0,i.kt)("inlineCode",{parentName:"p"},"sudo cat /var/lib/jenkins/secrets/initialAdminPasswor")," \ub97c \uc785\ub825\ud574 \ucd08\uae30 \ube44\ubc00\ubc88\ud638\ub97c \uc5bb\uc744 \uc218 \uc788\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\uba74 \ud50c\ub7ec\uadf8\uc778 \uc124\uc815 \ucc3d\uc774 \ub098\uc62c\ud150\ub370 ",(0,i.kt)("inlineCode",{parentName:"p"},"install suggested plugins"),"\uc744 \ud074\ub9ad\ud558\uc5ec Jenkins\uac00 \ucd94\ucc9c\ud558\ub294 \uae30\ubcf8 \ud50c\ub7ec\uadf8\uc778\ub4e4\uc744 \uc124\uce58\ud558\uba74 \ub41c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\ud50c\ub7ec\uadf8\uc778\uc744 \uc124\uce58\ud558\uba74 \uacc4\uc815 \ubc0f \uc8fc\uc18c \uc124\uc815\uc744 \ud574\uc57c\ud558\ub294\ub370 \uc774\uac74 \ud3b8\ud558\uac8c \uc124\uc815\ud558\uba74 \ub41c\ub2e4. "),(0,i.kt)("h3",{id:"jenkins-jenkins-blue-ocean-\uc124\uce58"},"[","Jenkins","]"," Jenkins Blue Ocean \uc124\uce58"),(0,i.kt)("p",null,"Jenkins \uad00\ub9ac \u2192 Plugin Manager\uc5d0\uc11c Blue Ocean\uc744 \uac80\uc0c9\ud574 \uc124\uce58\ud55c\ub2e4."),(0,i.kt)("h3",{id:"aws-iam--ec2-iam\uc73c\ub85c-ec2-\uc778\uc2a4\ud134\uc2a4-\uad8c\ud55c-\uc124\uc815\ud558\uae30"},"[","AWS IAM & EC2","]"," IAM\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4 \uad8c\ud55c \uc124\uc815\ud558\uae30"),(0,i.kt)("p",null,"S3\uc640 Elastic Beanstalk\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc744 \ubd80\uc5ec\ud558\ub824\uba74 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk \ub450 \uac1c\uc758 \uc815\ucc45\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uc5ed\ud560\uc744 \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","IAM\uc5d0\uc11c \ub2e4\uc74c\uacfc \uac19\uc774 \uc5ed\ud560\uc744 \ud558\ub098 \uc0c8\ub85c \uc0dd\uc131\ud55c\ub2e4."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"\uc5d4\ud130\ud2f0 \uc120\ud0dd")),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-iam1",src:t(30618).Z,width:"2282",height:"1028"})),(0,i.kt)("ol",{start:2},(0,i.kt)("li",{parentName:"ol"},"\uad8c\ud55c \ucd94\uac00")),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-iam2",src:t(56786).Z,width:"2300",height:"880"})),(0,i.kt)("ol",{start:3},(0,i.kt)("li",{parentName:"ol"},"\uc774\ub984 \uc9c0\uc815, \uac80\ud1a0 \ubc0f \uc0dd\uc131")),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-iam3",src:t(63303).Z,width:"1872",height:"1724"})),(0,i.kt)("ol",{start:4},(0,i.kt)("li",{parentName:"ol"},"\uc0dd\uc131\ud55c IAM EC2 Jenkins \uc778\uc2a4\ud134\uc2a4\ub97c \uc120\ud0dd\ud558\uace0, \uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc744 \ub20c\ub7ec Role \uc124\uc815")),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-iam4",src:t(82150).Z,width:"2264",height:"602"})),(0,i.kt)("h3",{id:"aws-s3-jar-\ud30c\uc77c\uc744-\uc5c5\ub85c\ub4dc-\ud560-s3-\ubc84\ud0b7-\uc0dd\uc131"},"[","AWS S3","]"," Jar \ud30c\uc77c\uc744 \uc5c5\ub85c\ub4dc \ud560 S3 \ubc84\ud0b7 \uc0dd\uc131"),(0,i.kt)("p",null,"\ubc84\ud0b7\uc744 \uc0dd\uc131\ud560 \ub54c \ub2e4\uc74c \uc124\uc815\uc744 \uc81c\uc678\ud558\uace0 \ubaa8\ub450 \ucc28\ub2e8 \ud65c\uc131\ud654\ub97c \ud574\uc900\ub2e4."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("inlineCode",{parentName:"li"},"\uc0c8 ACL(\uc561\uc138\uc2a4 \uc81c\uc5b4 \ubaa9\ub85d)\uc744 \ud1b5\ud574 \ubd80\uc5ec\ub41c \ubc84\ud0b7 \ubc0f \uac1d\uccb4\uc5d0 \ub300\ud55c \ud37c\ube14\ub9ad \uc561\uc138\uc2a4 \ucc28\ub2e8"))),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"aws-s3",src:t(36238).Z,width:"1636",height:"1258"})),(0,i.kt)("h3",{id:"github-blue-ocean\uc5d0\uc11c-\ud30c\uc774\ud504\ub77c\uc778-\uc0dd\uc131\uc5d0-\ud544\uc694\ud55c-github-token-\uc0dd\uc131"},"[","Github","]"," Blue Ocean\uc5d0\uc11c \ud30c\uc774\ud504\ub77c\uc778 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c Github Token \uc0dd\uc131"),(0,i.kt)("p",null,"repo, user:email \uad8c\ud55c\uc774 \uc788\ub294 \ud1a0\ud070\uc774 \ud544\uc694\ud558\ub2e4. "),(0,i.kt)("h3",{id:"jenkins-\ube14\ub8e8-\uc624\uc158-\uc2dc\uc791"},"[","Jenkins","]"," \ube14\ub8e8 \uc624\uc158 \uc2dc\uc791"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"jenkins-blue-ocean1",src:t(29666).Z,width:"2390",height:"1372"})),(0,i.kt)("p",null,"\ube14\ub8e8 \uc624\uc158 \uc5f4\uae30\ub85c \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc0dd\uc131\ud55c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\ud1a0\ud070 \uc785\ub825 \u2192 \uc870\uc9c1 \uc120\ud0dd \u2192 CI/CD \uc124\uc815\ud560 Repository \uc120\ud0dd\uc744 \ud558\uba74 \ud30c\uc774\ud504\ub77c\uc778 \ucc3d\uc73c\ub85c \ub118\uc5b4\uac04\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","Jenkinsfile\uc744 \uc9c1\uc811 \uc791\uc131\ud558\uc5ec \uc124\uc815\ud558\uae30 \uc704\ud574 \uac04\ub2e8\ud558\uac8c print \ud558\ub098 \ucd9c\ub825\ud558\ub294 \uac83\uc73c\ub85c \uc124\uc815\ud588\ub2e4. "),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"jenkins-blue-ocean2",src:t(49614).Z,width:"2076",height:"638"})),(0,i.kt)("p",null,"\ud30c\uc774\ud504\ub77c\uc778\uc774 \uc2e4\ud589\ub420 \ud150\ub370 pipeline status\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \ucd08\ub85d\ubd88\uc774 \ub728\uba74 \ub41c\ub2e4."),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"jenkins-blue-ocean3",src:t(71079).Z,width:"1084",height:"626"})),(0,i.kt)("h3",{id:"github-repsoitory-jenkinsfile-\uc124\uc815"},"[","Github Repsoitory","]"," Jenkinsfile \uc124\uc815"),(0,i.kt)("p",null,"\ube14\ub8e8 \uc624\uc158 \uc2dc\uc791\uc744 \ud1b5\ud574 \uc124\uc815\ud558\uba74 Jenkinsfile\uc774 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc9c0\uace0, \uc544\ub798\uc640 \uac19\uc774 \uc6d0\ud558\ub294 \ud30c\uc774\ud504\ub77c\uc778\uc744 \uc124\uc815\ud55c\ub2e4."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"pipeline {\n agent any\n stages {\n stage('build and test') {\n steps {\n sh '/gradlew clean build'\n }\n }\n stage('zip') {\n steps {\n sh 'mv ./build/libs/woowachat.jar .'\n sh 'zip -r woowachat.zip .platform delivery.jar Procfile'\n }\n }\n stage('upload') {\n steps {\n sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'\n }\n }\n stage('deploy') {\n steps {\n sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket=\"woowa-chat\",S3Key=\"woowachat.zip\"'\n sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'\n }\n }\n }\n}\n")),(0,i.kt)("h3",{id:"github-webhooks-\uc124\uc815"},"[","Github","]"," Webhooks \uc124\uc815"),(0,i.kt)("p",null,(0,i.kt)("img",{alt:"github-hook",src:t(36642).Z,width:"1428",height:"1148"})),(0,i.kt)("p",null,"push \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud560 \ub54c ",(0,i.kt)("inlineCode",{parentName:"p"},"http://Jenkins\uc8fc\uc18c/github-webhook/")," \ub85c post request\ub97c \ud558\ub3c4\ub85d \uc6f9\ud6c5\uc744 \uc124\uc815\ud55c\ub2e4."),(0,i.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,i.kt)("p",null,(0,i.kt)("a",{parentName:"p",href:"https://www.jenkins.io/doc/book/installing/linux/#red-hat-centos"},"Install Jenkins - CentOS, Jenkins"),(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("a",{parentName:"p",href:"https://www.jenkins.io/doc/book/system-administration/reverse-proxy-configuration-nginx/"},"Nginx Reverse Proxy Configuration, Jenkins"),(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/amazon-linux-install.html"},"Amazon Corretto 17 JDK Install, AWS"),(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/linux/al2023/release-notes/all-packages-al2023-20230419.html"},"Amazon Linux 2023 packages, AWS")))}k.isMDXComponent=!0},30618:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-iam1-e6d63be6b9f41d63e91d604138e6b07c.png"},56786:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-iam2-557683fc91b1c22330d081d6050dfe82.png"},63303:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-iam3-94248e9194dd58bb16d0289af47a4260.png"},82150:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-iam4-54ccc5a4e64d31f7eeab89d39ebf772f.png"},36238:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/aws-s3-757380d36e5492c962f75dae024994e5.png"},36642:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/github-hook-e9ebe0acb3ff0086ecebbd8c857ffe39.png"},29666:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/jenkins-blue-ocean1-bd108d887d700ea081e4b0a3d83ad459.png"},49614:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/jenkins-blue-ocean2-408c6c90e4a5371becc4d1013fba1212.png"},71079:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/jenkins-blue-ocean3-4050a206b3efe95a3c9f39c3f7a47ad7.png"},71399:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/jenkins-start-dce0d7051054c398d2a707c75c685234.png"}}]); \ No newline at end of file diff --git a/assets/js/b301b20b.98eff9ce.js b/assets/js/b301b20b.b1bb1de7.js similarity index 82% rename from assets/js/b301b20b.98eff9ce.js rename to assets/js/b301b20b.b1bb1de7.js index cd0a44e5e..613eaa2e9 100644 --- a/assets/js/b301b20b.98eff9ce.js +++ b/assets/js/b301b20b.b1bb1de7.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3637],{83150:e=>{e.exports=JSON.parse('{"label":"replication","permalink":"/tags/replication","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3637],{83150:e=>{e.exports=JSON.parse('{"label":"replication","permalink":"/tags/replication","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/b36d2d1d.c9ee00e8.js b/assets/js/b36d2d1d.df006be2.js similarity index 84% rename from assets/js/b36d2d1d.c9ee00e8.js rename to assets/js/b36d2d1d.df006be2.js index 27e5f8cd7..ea21c34c9 100644 --- a/assets/js/b36d2d1d.c9ee00e8.js +++ b/assets/js/b36d2d1d.df006be2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1257],{7903:e=>{e.exports=JSON.parse('{"label":"latency","permalink":"/docs/tags/latency","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc131\ub2a5/Throughput\uacfc Latency","title":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","description":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","permalink":"/docs/performance/throughput-latency"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1257],{7903:e=>{e.exports=JSON.parse('{"label":"latency","permalink":"/docs/tags/latency","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc131\ub2a5/Throughput\uacfc Latency","title":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","description":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","permalink":"/docs/performance/throughput-latency"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/b41adc00.626950e4.js b/assets/js/b41adc00.626950e4.js deleted file mode 100644 index 4963d6cf4..000000000 --- a/assets/js/b41adc00.626950e4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1391],{3905:(e,t,a)=>{a.d(t,{Zo:()=>s,kt:()=>d});var r=a(67294);function n(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function o(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,r)}return a}function c(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?o(Object(a),!0).forEach((function(t){n(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function p(e,t){if(null==e)return{};var a,r,n=function(e,t){if(null==e)return{};var a,r,n={},o=Object.keys(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||(n[a]=e[a]);return n}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)a=o[r],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(n[a]=e[a])}return n}var l=r.createContext({}),i=function(e){var t=r.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):c(c({},t),e)),a},s=function(e){var t=i(e.components);return r.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var a=e.components,n=e.mdxType,o=e.originalType,l=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),m=i(a),d=n,b=m["".concat(l,".").concat(d)]||m[d]||u[d]||o;return a?r.createElement(b,c(c({ref:t},s),{},{components:a})):r.createElement(b,c({ref:t},s))}));function d(e,t){var a=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var o=a.length,c=new Array(o);c[0]=m;var p={};for(var l in t)hasOwnProperty.call(t,l)&&(p[l]=t[l]);p.originalType=e,p.mdxType="string"==typeof e?e:n,c[1]=p;for(var i=2;i<o;i++)c[i]=a[i];return r.createElement.apply(null,c)}return r.createElement.apply(null,a)}m.displayName="MDXCreateElement"},56783:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>p,toc:()=>i});var r=a(87462),n=(a(67294),a(3905));const o={title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"jdbc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,p={permalink:"/jdbc-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-jdbc/pull/267",date:"2023-10-10T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 10\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.83,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"jdbc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",permalink:"/refactoring-retrospective"},nextItem:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/mvc-retrospective"}},l={authorsImageUrls:[]},i=[{value:"Jdbc \uad6c\ud604",id:"jdbc-\uad6c\ud604",level:3},{value:"JdbcTemplate",id:"jdbctemplate",level:3},{value:"\ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9",id:"\ud2b8\ub79c\uc7ad\uc158-\uc801\uc6a9",level:3},{value:"\ub9c8\ubb34\ub9ac",id:"\ub9c8\ubb34\ub9ac",level:3}],s={toc:i};function u(e){let{components:t,...a}=e;return(0,n.kt)("wrapper",(0,r.Z)({},s,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("admonition",{title:"PR \ub9c1\ud06c",type:"note"},(0,n.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267"},"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267"),(0,n.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358"},"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358"),(0,n.kt)("br",{parentName:"p"}),"\n","3\ub2e8\uacc4: ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448"},"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448"),(0,n.kt)("br",{parentName:"p"}),"\n","4\ub2e8\uacc4: ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515"},"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515")," ")),(0,n.kt)("h3",{id:"jdbc-\uad6c\ud604"},"Jdbc \uad6c\ud604"),(0,n.kt)("p",null,"\uc774\ubc88 \ubbf8\uc158\uc740 Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uace0, Transaction \uacbd\uacc4 \uc124\uc815\uacfc \ub3d9\uae30\ud654\ud558\ub294 \ubd80\ubd84\uc744 \uad6c\ud604\ud574 \ubcf4\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ubbf8\uc158 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"JDBC \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uba74\uc11c \uc911\ubcf5\uc744 \uc81c\uac70\ud558\ub294 \uc5f0\uc2b5\uc744 \ud55c\ub2e4."),(0,n.kt)("li",{parentName:"ul"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\ub97c \ub192\uc778\ub2e4.")),(0,n.kt)("p",null,"\ucd5c\ub300\ud55c Java\uac00 \uc81c\uacf5\ud558\ub294 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud588\ub2e4. "),(0,n.kt)("h3",{id:"jdbctemplate"},"JdbcTemplate"),(0,n.kt)("p",null,"JdbcTemplate\uc740 Connection\uc744 \uc774\uc6a9\ud558\uc5ec PreparedStatement\ub97c \uc0dd\uc131\ud558\ub294 \ubd80\ubd84, \uadf8\ub9ac\uace0 PreparedStatement\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ubd84\ub9ac\ud588\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc801\uc808\ud558\uac8c \uc801\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \ube44\uad50\uc801 \uac04\ub2e8\ud558\uac8c \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc608\uc804\uc5d0\ub3c4 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c ",(0,n.kt)("a",{parentName:"p",href:"./custom-jdbc-template"},"JdbcTemplate\uc744 \uad6c\ud604"),"\ud55c \uc801\uc774 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \uc790\uc6d0 \ud560\ub2f9\uacfc \ud574\uc81c \ubd80\ubd84\uc5d0 \ub300\ud55c \uc911\ubcf5\ub3c4 \uc81c\uac70\ud588\ub2e4. "),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-java"},'public class JdbcTemplate {\n\n private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);\n\n private final DataSource dataSource;\n private final StatementCreator statementCreator;\n private final StatementExecutor statementExecutor;\n\n public JdbcTemplate(final DataSource dataSource) {\n this(dataSource, new StatementCreator(), new StatementExecutor());\n }\n\n JdbcTemplate(\n final DataSource dataSource,\n final StatementCreator statementCreator,\n final StatementExecutor statementExecutor\n ) {\n this.dataSource = dataSource;\n this.statementCreator = statementCreator;\n this.statementExecutor = statementExecutor;\n }\n\n private <T> T query(\n final String sql,\n final PreparedStatementCallback<T> preparedStatementCallback,\n final Object... parameters\n ) {\n final Connection connection = DataSourceUtils.getConnection(dataSource);\n try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {\n return preparedStatementCallback.execute(preparedStatement);\n } catch (final SQLException e) {\n log.error(e.getMessage(), e);\n throw new DataAccessException(e);\n } finally {\n DataSourceUtils.releaseConnection(connection, dataSource);\n }\n }\n\n public void update(final String sql, final Object... parameters) {\n query(sql, PreparedStatement::executeUpdate, parameters);\n }\n\n public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\n final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\n if (results.size() > 1) {\n throw new DataAccessException("2\uac1c \uc774\uc0c1\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.");\n }\n return results.stream().findAny();\n }\n\n public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\n return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\n }\n}\n')),(0,n.kt)("h3",{id:"\ud2b8\ub79c\uc7ad\uc158-\uc801\uc6a9"},"\ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9"),(0,n.kt)("p",null,"3, 4\ub2e8\uacc4\ub294 \uae30\uc874\uc758 \ucf54\ub4dc\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uace0 \ub05d\ub098\ub294 \ubd80\ubd84\uc778 \ud2b8\ub79c\uc7ad\uc158 \uacbd\uacc4\ub97c \uc124\uc815\ud558\uace0 ThreadLocal\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654(Transaction synchronization)\ub97c \uc801\uc6a9\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654\ub780 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uae30 \uc704\ud55c Connection \uac1d\uccb4\ub97c ThreadLocal\uacfc \uac19\uc740 \uacf5\uac04\uc5d0 \ub530\ub85c \uc800\uc7a5 \ud6c4, \ud544\uc694\ud560 \ub54c \uc800\uc7a5\ub41c Connection\uc744 \uac00\uc838\ub2e4 \uc0ac\uc6a9\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub294\ub370, ThreadLocal\uc5d0 Connection \uac1d\uccb4\uac00 \uc544\ub2cc, Connection \uac1d\uccb4\uc640 Transaction\uc774 \uc9c4\ud589 \uc911\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 flag\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \uc800\uc7a5\ud574\uc11c \uc0ac\uc6a9\ud558\ub3c4\ub85d \ud588\ub2e4. "),(0,n.kt)("mermaid",{value:"graph LR\n\tTransactionTemplate --\x3e TransactionManager\n\tTransactionManager --\x3e TransactionSynchronizationManager\n\tDataSourceUtils --\x3e TransactionSynchronizationManager\n\tJdbcTemplate --\x3e DataSourceUtils"}),(0,n.kt)("h3",{id:"\ub9c8\ubb34\ub9ac"},"\ub9c8\ubb34\ub9ac"),(0,n.kt)("p",null,"Jdbc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c AOP\ub098 Transactional\uc5d0 \ub300\ud55c \ud559\uc2b5 \ud14c\uc2a4\ud2b8\ub3c4 \uc9c4\ud589\ud558\uace0, \uc57d\uac04 \uc54c\ucc2c \ubbf8\uc158\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\uaf3c\uaf3c\ud788 \ucf54\ub4dc\ub97c \ubd10\uc900 \ub9ac\ubdf0\uc5b4 \ud638\uc774 \uadf8\ub9ac\uace0 \uc5f0\ud734 \ub3d9\uc548 \uacc4\uc18d \ud2f0\ud0a4\ud0c0\uce74 \ud558\uba74\uc11c \uc7ac\ubc0c\uac8c \ub9ac\ubdf0\ud55c \ubbfc\ud2b8\uc5d0\uac8c \uac10\uc0ac\ud558\ub2e4.",(0,n.kt)("br",{parentName:"p"}),"\n","\ud68c\uace0 \uc774\ub9cc \ub05d\ub0b4\uace0 \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud558\ub7ec\uac00\uc57c\uaca0\ub2e4. \ud83d\ude0a"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b41adc00.633c89b0.js b/assets/js/b41adc00.633c89b0.js new file mode 100644 index 000000000..1ba90e545 --- /dev/null +++ b/assets/js/b41adc00.633c89b0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1391],{33849:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var r=n(85893),a=n(3905);const o={title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"jdbc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,i={permalink:"/jdbc-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/jwp-dashboard-jdbc/pull/267",date:"2023-10-10T00:00:00.000Z",formattedDate:"2023\ub144 10\uc6d4 10\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.83,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",slug:"jdbc-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0",permalink:"/refactoring-retrospective"},nextItem:{title:"MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/mvc-retrospective"}},s={authorsImageUrls:[]},l=[{value:"Jdbc \uad6c\ud604",id:"jdbc-\uad6c\ud604",level:3},{value:"JdbcTemplate",id:"jdbctemplate",level:3},{value:"\ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9",id:"\ud2b8\ub79c\uc7ad\uc158-\uc801\uc6a9",level:3},{value:"\ub9c8\ubb34\ub9ac",id:"\ub9c8\ubb34\ub9ac",level:3}];function p(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",mermaid:"mermaid",p:"p",pre:"pre",ul:"ul",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,r.jsxs)(t.p,{children:["1\ub2e8\uacc4: ",(0,r.jsx)(t.a,{href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267",children:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267"}),(0,r.jsx)(t.br,{}),"\n","2\ub2e8\uacc4: ",(0,r.jsx)(t.a,{href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358",children:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358"}),(0,r.jsx)(t.br,{}),"\n","3\ub2e8\uacc4: ",(0,r.jsx)(t.a,{href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448",children:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448"}),(0,r.jsx)(t.br,{}),"\n","4\ub2e8\uacc4: ",(0,r.jsx)(t.a,{href:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515",children:"https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515"})]})}),"\n",(0,r.jsx)(t.h3,{id:"jdbc-\uad6c\ud604",children:"Jdbc \uad6c\ud604"}),"\n",(0,r.jsxs)(t.p,{children:["\uc774\ubc88 \ubbf8\uc158\uc740 Jdbc \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uace0, Transaction \uacbd\uacc4 \uc124\uc815\uacfc \ub3d9\uae30\ud654\ud558\ub294 \ubd80\ubd84\uc744 \uad6c\ud604\ud574 \ubcf4\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ubbf8\uc158 \ubaa9\ud45c\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"JDBC \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uad6c\ud604\ud558\uba74\uc11c \uc911\ubcf5\uc744 \uc81c\uac70\ud558\ub294 \uc5f0\uc2b5\uc744 \ud55c\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\ub3c4\ub97c \ub192\uc778\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"\ucd5c\ub300\ud55c Java\uac00 \uc81c\uacf5\ud558\ub294 \uae30\ub2a5\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub9ac\ud329\ud130\ub9c1 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ucf54\ub4dc\ub97c \uc791\uc131\ud588\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"jdbctemplate",children:"JdbcTemplate"}),"\n",(0,r.jsxs)(t.p,{children:["JdbcTemplate\uc740 Connection\uc744 \uc774\uc6a9\ud558\uc5ec PreparedStatement\ub97c \uc0dd\uc131\ud558\ub294 \ubd80\ubd84, \uadf8\ub9ac\uace0 PreparedStatement\uac00 \uc5b4\ub5bb\uac8c \ub3d9\uc791\ud558\ub294\uc9c0\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ubd84\ub9ac\ud588\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc801\uc808\ud558\uac8c \uc801\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \ube44\uad50\uc801 \uac04\ub2e8\ud558\uac8c \uc81c\uac70\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc608\uc804\uc5d0\ub3c4 \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c ",(0,r.jsx)(t.a,{href:"./custom-jdbc-template",children:"JdbcTemplate\uc744 \uad6c\ud604"}),"\ud55c \uc801\uc774 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \uc790\uc6d0 \ud560\ub2f9\uacfc \ud574\uc81c \ubd80\ubd84\uc5d0 \ub300\ud55c \uc911\ubcf5\ub3c4 \uc81c\uac70\ud588\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-java",children:'public class JdbcTemplate {\n\n private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);\n\n private final DataSource dataSource;\n private final StatementCreator statementCreator;\n private final StatementExecutor statementExecutor;\n\n public JdbcTemplate(final DataSource dataSource) {\n this(dataSource, new StatementCreator(), new StatementExecutor());\n }\n\n JdbcTemplate(\n final DataSource dataSource,\n final StatementCreator statementCreator,\n final StatementExecutor statementExecutor\n ) {\n this.dataSource = dataSource;\n this.statementCreator = statementCreator;\n this.statementExecutor = statementExecutor;\n }\n\n private <T> T query(\n final String sql,\n final PreparedStatementCallback<T> preparedStatementCallback,\n final Object... parameters\n ) {\n final Connection connection = DataSourceUtils.getConnection(dataSource);\n try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {\n return preparedStatementCallback.execute(preparedStatement);\n } catch (final SQLException e) {\n log.error(e.getMessage(), e);\n throw new DataAccessException(e);\n } finally {\n DataSourceUtils.releaseConnection(connection, dataSource);\n }\n }\n\n public void update(final String sql, final Object... parameters) {\n query(sql, PreparedStatement::executeUpdate, parameters);\n }\n\n public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\n final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\n if (results.size() > 1) {\n throw new DataAccessException("2\uac1c \uc774\uc0c1\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.");\n }\n return results.stream().findAny();\n }\n\n public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {\n return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);\n }\n}\n'})}),"\n",(0,r.jsx)(t.h3,{id:"\ud2b8\ub79c\uc7ad\uc158-\uc801\uc6a9",children:"\ud2b8\ub79c\uc7ad\uc158 \uc801\uc6a9"}),"\n",(0,r.jsxs)(t.p,{children:["3, 4\ub2e8\uacc4\ub294 \uae30\uc874\uc758 \ucf54\ub4dc\uc5d0 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uace0 \ub05d\ub098\ub294 \ubd80\ubd84\uc778 \ud2b8\ub79c\uc7ad\uc158 \uacbd\uacc4\ub97c \uc124\uc815\ud558\uace0 ThreadLocal\uc744 \uc774\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654(Transaction synchronization)\ub97c \uc801\uc6a9\ud558\ub294 \ubbf8\uc158\uc774\uc5c8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158 \ub3d9\uae30\ud654\ub780 \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dc\uc791\ud558\uae30 \uc704\ud55c Connection \uac1d\uccb4\ub97c ThreadLocal\uacfc \uac19\uc740 \uacf5\uac04\uc5d0 \ub530\ub85c \uc800\uc7a5 \ud6c4, \ud544\uc694\ud560 \ub54c \uc800\uc7a5\ub41c Connection\uc744 \uac00\uc838\ub2e4 \uc0ac\uc6a9\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ubbf8\uc158\uc744 \uc9c4\ud589\ud588\ub294\ub370, ThreadLocal\uc5d0 Connection \uac1d\uccb4\uac00 \uc544\ub2cc, Connection \uac1d\uccb4\uc640 Transaction\uc774 \uc9c4\ud589 \uc911\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 flag\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub97c \uc800\uc7a5\ud574\uc11c \uc0ac\uc6a9\ud558\ub3c4\ub85d \ud588\ub2e4."]}),"\n",(0,r.jsx)(t.mermaid,{value:"graph LR\n\tTransactionTemplate --\x3e TransactionManager\n\tTransactionManager --\x3e TransactionSynchronizationManager\n\tDataSourceUtils --\x3e TransactionSynchronizationManager\n\tJdbcTemplate --\x3e DataSourceUtils"}),"\n",(0,r.jsx)(t.h3,{id:"\ub9c8\ubb34\ub9ac",children:"\ub9c8\ubb34\ub9ac"}),"\n",(0,r.jsxs)(t.p,{children:["Jdbc \ubbf8\uc158\uc744 \uc9c4\ud589\ud558\uba74\uc11c AOP\ub098 Transactional\uc5d0 \ub300\ud55c \ud559\uc2b5 \ud14c\uc2a4\ud2b8\ub3c4 \uc9c4\ud589\ud558\uace0, \uc57d\uac04 \uc54c\ucc2c \ubbf8\uc158\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uaf3c\uaf3c\ud788 \ucf54\ub4dc\ub97c \ubd10\uc900 \ub9ac\ubdf0\uc5b4 \ud638\uc774 \uadf8\ub9ac\uace0 \uc5f0\ud734 \ub3d9\uc548 \uacc4\uc18d \ud2f0\ud0a4\ud0c0\uce74 \ud558\uba74\uc11c \uc7ac\ubc0c\uac8c \ub9ac\ubdf0\ud55c \ubbfc\ud2b8\uc5d0\uac8c \uac10\uc0ac\ud558\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud68c\uace0 \uc774\ub9cc \ub05d\ub0b4\uace0 \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud558\ub7ec\uac00\uc57c\uaca0\ub2e4. \ud83d\ude0a"]})]})}function d(e={}){const{wrapper:t}={...(0,a.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>l});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),l=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):c(c({},t),e)),n},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=l(n),b=a,m=u["".concat(s,".").concat(b)]||u[b]||p[b]||o;return n?r.createElement(m,c(c({ref:t},d),{},{components:n})):r.createElement(m,c({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/b421ebb7.8b29869e.js b/assets/js/b421ebb7.8b29869e.js deleted file mode 100644 index c57b6b511..000000000 --- a/assets/js/b421ebb7.8b29869e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8518],{3905:(e,t,r)=>{r.d(t,{Zo:()=>i,kt:()=>h});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var u=n.createContext({}),c=function(e){var t=n.useContext(u),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},i=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,u=e.parentName,i=l(e,["components","mdxType","originalType","parentName"]),m=c(r),h=a,d=m["".concat(u,".").concat(h)]||m[h]||s[h]||o;return r?n.createElement(d,p(p({ref:t},i),{},{components:r})):n.createElement(d,p({ref:t},i))}));function h(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,p=new Array(o);p[0]=m;var l={};for(var u in t)hasOwnProperty.call(t,u)&&(l[u]=t[u]);l.originalType=e,l.mdxType="string"==typeof e?e:a,p[1]=l;for(var c=2;c<o;c++)p[c]=r[c];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},20882:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>p,default:()=>s,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",slug:"/performance/throughput-latency",last_update:{date:"2023/08/28"},tags:["throughput","latency"]},p=void 0,l={unversionedId:"\uc131\ub2a5/Throughput\uacfc Latency",id:"\uc131\ub2a5/Throughput\uacfc Latency",title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",description:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",source:"@site/docs/\uc131\ub2a5/Throughput\uacfc Latency.mdx",sourceDirName:"\uc131\ub2a5",slug:"/performance/throughput-latency",permalink:"/docs/performance/throughput-latency",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc131\ub2a5/Throughput\uacfc Latency.mdx",tags:[{label:"throughput",permalink:"/docs/tags/throughput"},{label:"latency",permalink:"/docs/tags/latency"}],version:"current",lastUpdatedAt:1693180800,formattedLastUpdatedAt:"2023\ub144 8\uc6d4 28\uc77c",frontMatter:{title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",slug:"/performance/throughput-latency",last_update:{date:"2023/08/28"},tags:["throughput","latency"]},sidebar:"tutorialSidebar",previous:{title:"Throughput \ubaa9\ud46f\uac12",permalink:"/docs/performance/throughput"},next:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",permalink:"/docs/performance/types"}},u={},c=[{value:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",id:"\uc2dc\uc2a4\ud15c-\uc131\ub2a5-\uc9c0\ud45c",level:3},{value:"Throughput",id:"throughput",level:3},{value:"Latency",id:"latency",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],i={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},i,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uc2dc\uc2a4\ud15c-\uc131\ub2a5-\uc9c0\ud45c"},"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c"),(0,a.kt)("p",null,"\uc2dc\uc2a4\ud15c \uc131\ub2a5\uc740 \uc5b4\ub5bb\uac8c \uce21\uc815\ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("inlineCode",{parentName:"p"},"\uc131\ub2a5\uc774 \ube68\ub77c\uc84c\ub2e4.")," \ub77c\ub294 \uac83\uc744 \uc5b4\ub5bb\uac8c \uc218\uce58\ud654\ud560 \uc218 \uc788\uc744\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c \uc2dc\uc2a4\ud15c \uc131\ub2a5\uc740 Throughput\uacfc Latency\ub77c\ub294 \uc131\ub2a5 \uc9c0\ud45c\ub85c \uce21\uc815\uc744 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"throughput"},"Throughput"),(0,a.kt)("p",null,"\ucd08\ub2f9 \ucc98\ub9ac\ud558\ub294 \uc791\uc5c5\uc758 \uc218, \uc989 \ucc98\ub9ac\ub7c9\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c \ucd08\ub2f9 \uba87 \uac1c\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294\uc9c0(RPS, Request Per Second)\ub97c \uae30\uc900\uc73c\ub85c \uce21\uc815\uc744 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c\uacfc \uac19\uc740 \uc2dc\uc2a4\ud15c\uc774 \uc788\ub2e4\uace0 \uac00\uc815\ud574\ubcf4\uc790."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uc2dc\uc2a4\ud15c A: \ucd08\ub2f9 \uc57d 100\uac1c\uc758 \uc694\uccad \ucc98\ub9ac"),(0,a.kt)("li",{parentName:"ul"},"\uc2dc\uc2a4\ud15c B: \ucd08\ub2f9 \uc57d 200\uac1c\uc758 \uc694\uccad \ucc98\ub9ac")),(0,a.kt)("p",null,"\uc2dc\uc2a4\ud15c B\uac00 \ub3d9\uc2dc\uac04 \ub300\ube44 \ub354 \ub192\uc740 \ucc98\ub9ac\ub7c9\uc744 \ubcf4\uc5ec\uc8fc\uace0 \uc788\uc73c\ub2c8, \uc2dc\uc2a4\ud15c B\uc758 \uc131\ub2a5\uc774 \ub354 \uc88b\ub2e4\uace0 \ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"latency"},"Latency"),(0,a.kt)("p",null,"\uc2dc\uc2a4\ud15c\uc758 \ud3c9\uade0 \uc751\ub2f5 \uc2dc\uac04, \uc989 \ucc98\ub9ac \uc2dc\uac04\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Latency\ub294 \ub2e4\uc74c\uacfc \uac19\uc774 \ub450 \uac00\uc9c0\ub85c \uad6c\ubd84\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("inlineCode",{parentName:"p"},"\uc0ac\uc6a9\uc790\uac00 \ubcf8 \ucc98\ub9ac \uc2dc\uac04"),": \uc0ac\uc6a9\uc790\uac00 \uc694\uccad\uc744 \ubcf4\ub0b4\uace0 \uc751\ub2f5\uc744 \ubc1b\uc744 \ub54c\uae4c\uc9c0\uc758 \uc2dc\uac04",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("inlineCode",{parentName:"p"},"\uc2dc\uc2a4\ud15c\uc5d0\uc11c \ubcf8 \ucc98\ub9ac \uc2dc\uac04"),": \uc2dc\uc2a4\ud15c\uc774 \uc694\uccad\uc744 \ubc1b\uace0 \uc751\ub2f5\uc744 \ubcf4\ub0bc \ub54c\uae4c\uc9c0\uc758 \uc2dc\uac04 "),(0,a.kt)("p",null,"\uc0ac\uc6a9\uc790\uac00 \ubcf8 \ucc98\ub9ac \uc2dc\uac04\uc758 \uacbd\uc6b0 \ub124\ud2b8\uc6cc\ud06c\uc5d0 \ub300\ud55c \uc2dc\uac04\uc774 \ud3ec\ud568\ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc131\ub2a5 \uce21\uc815\uacfc \uac1c\uc120\uc740 \uc2dc\uc2a4\ud15c\uc5d0\uc11c \ubcf8 \ucc98\ub9ac \uc2dc\uac04\uc73c\ub85c \uce21\uc815\ud558\uace0 \uac1c\uc120\ud558\ub294 \uac83\uc774 \ub354 \uc815\ud655\ud574 \ubcf4\uc778\ub2e4. "),(0,a.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc740 \uc2dc\uc2a4\ud15c\uc774 \uc788\ub2e4\uace0 \uac00\uc815\ud574\ubcf4\uc790. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uc2dc\uc2a4\ud15c A: \uc694\uccad\uc2dc \ud3c9\uade0 200ms \ub0b4 \uc751\ub2f5 "),(0,a.kt)("li",{parentName:"ul"},"\uc2dc\uc2a4\ud15c B: \uc694\uccad\uc2dc \ud3c9\uade0 100ms \ub0b4 \uc751\ub2f5 ")),(0,a.kt)("p",null,"\uc2dc\uc2a4\ud15c B\uac00 \uc694\uccad\uc5d0 \ub300\ud55c \uc751\ub2f5\uc774 \ub354 \ube60\ub974\ub2c8, \uc2dc\uc2a4\ud15c B\uc758 \uc131\ub2a5\uc774 \ub354 \uc88b\ub2e4\uace0 \ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/compare/the-difference-between-throughput-and-latency/"},"difference between throughput and latency, AWS")," - \ud574\ub2f9 \ub0b4\uc6a9\uc740 \ub124\ud2b8\uc6cc\ud06c \uae30\uc900\uc774\ub2e4."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b421ebb7.fe44063d.js b/assets/js/b421ebb7.fe44063d.js new file mode 100644 index 000000000..528ad4420 --- /dev/null +++ b/assets/js/b421ebb7.fe44063d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9055],{37058:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>i});var n=r(85893),c=r(3905);const a={title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",slug:"/performance/throughput-latency",last_update:{date:"2023/08/28"},tags:["throughput","latency"]},o=void 0,l={id:"\uc131\ub2a5/Throughput\uacfc Latency",title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",description:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",source:"@site/docs/\uc131\ub2a5/Throughput\uacfc Latency.mdx",sourceDirName:"\uc131\ub2a5",slug:"/performance/throughput-latency",permalink:"/docs/performance/throughput-latency",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc131\ub2a5/Throughput\uacfc Latency.mdx",tags:[{label:"throughput",permalink:"/docs/tags/throughput"},{label:"latency",permalink:"/docs/tags/latency"}],version:"current",lastUpdatedAt:1693180800,formattedLastUpdatedAt:"2023\ub144 8\uc6d4 28\uc77c",frontMatter:{title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",slug:"/performance/throughput-latency",last_update:{date:"2023/08/28"},tags:["throughput","latency"]},sidebar:"tutorialSidebar",previous:{title:"Throughput \ubaa9\ud46f\uac12",permalink:"/docs/performance/throughput"},next:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",permalink:"/docs/performance/types"}},s={},i=[{value:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",id:"\uc2dc\uc2a4\ud15c-\uc131\ub2a5-\uc9c0\ud45c",level:3},{value:"Throughput",id:"throughput",level:3},{value:"Latency",id:"latency",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function u(e){const t={a:"a",br:"br",code:"code",h3:"h3",li:"li",p:"p",ul:"ul",...(0,c.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uc2dc\uc2a4\ud15c-\uc131\ub2a5-\uc9c0\ud45c",children:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c"}),"\n",(0,n.jsxs)(t.p,{children:["\uc2dc\uc2a4\ud15c \uc131\ub2a5\uc740 \uc5b4\ub5bb\uac8c \uce21\uc815\ud560\uae4c?",(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.code,{children:"\uc131\ub2a5\uc774 \ube68\ub77c\uc84c\ub2e4."})," \ub77c\ub294 \uac83\uc744 \uc5b4\ub5bb\uac8c \uc218\uce58\ud654\ud560 \uc218 \uc788\uc744\uae4c?",(0,n.jsx)(t.br,{}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c \uc2dc\uc2a4\ud15c \uc131\ub2a5\uc740 Throughput\uacfc Latency\ub77c\ub294 \uc131\ub2a5 \uc9c0\ud45c\ub85c \uce21\uc815\uc744 \ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"throughput",children:"Throughput"}),"\n",(0,n.jsxs)(t.p,{children:["\ucd08\ub2f9 \ucc98\ub9ac\ud558\ub294 \uc791\uc5c5\uc758 \uc218, \uc989 \ucc98\ub9ac\ub7c9\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc77c\ubc18\uc801\uc73c\ub85c \ucd08\ub2f9 \uba87 \uac1c\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294\uc9c0(RPS, Request Per Second)\ub97c \uae30\uc900\uc73c\ub85c \uce21\uc815\uc744 \ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub2e4\uc74c\uacfc \uac19\uc740 \uc2dc\uc2a4\ud15c\uc774 \uc788\ub2e4\uace0 \uac00\uc815\ud574\ubcf4\uc790."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"\uc2dc\uc2a4\ud15c A: \ucd08\ub2f9 \uc57d 100\uac1c\uc758 \uc694\uccad \ucc98\ub9ac"}),"\n",(0,n.jsx)(t.li,{children:"\uc2dc\uc2a4\ud15c B: \ucd08\ub2f9 \uc57d 200\uac1c\uc758 \uc694\uccad \ucc98\ub9ac"}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"\uc2dc\uc2a4\ud15c B\uac00 \ub3d9\uc2dc\uac04 \ub300\ube44 \ub354 \ub192\uc740 \ucc98\ub9ac\ub7c9\uc744 \ubcf4\uc5ec\uc8fc\uace0 \uc788\uc73c\ub2c8, \uc2dc\uc2a4\ud15c B\uc758 \uc131\ub2a5\uc774 \ub354 \uc88b\ub2e4\uace0 \ud560 \uc218 \uc788\ub2e4."}),"\n",(0,n.jsx)(t.h3,{id:"latency",children:"Latency"}),"\n",(0,n.jsxs)(t.p,{children:["\uc2dc\uc2a4\ud15c\uc758 \ud3c9\uade0 \uc751\ub2f5 \uc2dc\uac04, \uc989 \ucc98\ub9ac \uc2dc\uac04\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","Latency\ub294 \ub2e4\uc74c\uacfc \uac19\uc774 \ub450 \uac00\uc9c0\ub85c \uad6c\ubd84\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"\uc0ac\uc6a9\uc790\uac00 \ubcf8 \ucc98\ub9ac \uc2dc\uac04"}),": \uc0ac\uc6a9\uc790\uac00 \uc694\uccad\uc744 \ubcf4\ub0b4\uace0 \uc751\ub2f5\uc744 \ubc1b\uc744 \ub54c\uae4c\uc9c0\uc758 \uc2dc\uac04",(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.code,{children:"\uc2dc\uc2a4\ud15c\uc5d0\uc11c \ubcf8 \ucc98\ub9ac \uc2dc\uac04"}),": \uc2dc\uc2a4\ud15c\uc774 \uc694\uccad\uc744 \ubc1b\uace0 \uc751\ub2f5\uc744 \ubcf4\ub0bc \ub54c\uae4c\uc9c0\uc758 \uc2dc\uac04"]}),"\n",(0,n.jsxs)(t.p,{children:["\uc0ac\uc6a9\uc790\uac00 \ubcf8 \ucc98\ub9ac \uc2dc\uac04\uc758 \uacbd\uc6b0 \ub124\ud2b8\uc6cc\ud06c\uc5d0 \ub300\ud55c \uc2dc\uac04\uc774 \ud3ec\ud568\ub41c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub530\ub77c\uc11c \uc131\ub2a5 \uce21\uc815\uacfc \uac1c\uc120\uc740 \uc2dc\uc2a4\ud15c\uc5d0\uc11c \ubcf8 \ucc98\ub9ac \uc2dc\uac04\uc73c\ub85c \uce21\uc815\ud558\uace0 \uac1c\uc120\ud558\ub294 \uac83\uc774 \ub354 \uc815\ud655\ud574 \ubcf4\uc778\ub2e4."]}),"\n",(0,n.jsx)(t.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc740 \uc2dc\uc2a4\ud15c\uc774 \uc788\ub2e4\uace0 \uac00\uc815\ud574\ubcf4\uc790."}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"\uc2dc\uc2a4\ud15c A: \uc694\uccad\uc2dc \ud3c9\uade0 200ms \ub0b4 \uc751\ub2f5"}),"\n",(0,n.jsx)(t.li,{children:"\uc2dc\uc2a4\ud15c B: \uc694\uccad\uc2dc \ud3c9\uade0 100ms \ub0b4 \uc751\ub2f5"}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"\uc2dc\uc2a4\ud15c B\uac00 \uc694\uccad\uc5d0 \ub300\ud55c \uc751\ub2f5\uc774 \ub354 \ube60\ub974\ub2c8, \uc2dc\uc2a4\ud15c B\uc758 \uc131\ub2a5\uc774 \ub354 \uc88b\ub2e4\uace0 \ud560 \uc218 \uc788\ub2e4."}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsxs)(t.p,{children:["\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04",(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.a,{href:"https://aws.amazon.com/ko/compare/the-difference-between-throughput-and-latency/",children:"difference between throughput and latency, AWS"})," - \ud574\ub2f9 \ub0b4\uc6a9\uc740 \ub124\ud2b8\uc6cc\ud06c \uae30\uc900\uc774\ub2e4."]})]})}function p(e={}){const{wrapper:t}={...(0,c.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>i});var n=r(67294);function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){c(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,c=function(e,t){if(null==e)return{};var r,n,c={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(c[r]=e[r]);return c}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var s=n.createContext({}),i=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,c=e.mdxType,a=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),h=i(r),d=c,f=h["".concat(s,".").concat(d)]||h[d]||u[d]||a;return r?n.createElement(f,o(o({ref:t},p),{},{components:r})):n.createElement(f,o({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/b6ffb0cb.4afb0eea.js b/assets/js/b6ffb0cb.4afb0eea.js new file mode 100644 index 000000000..200a67677 --- /dev/null +++ b/assets/js/b6ffb0cb.4afb0eea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2156],{1738:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>o,contentTitle:()=>i,default:()=>x,frontMatter:()=>s,metadata:()=>c,toc:()=>l});var t=n(85893),a=n(3905);const s={title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",slug:"racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,c={permalink:"/racing-car-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-racingcar/pull/510",date:"2023-02-14T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 14\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.625,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",slug:"racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",permalink:"/ladder-retrospective"},nextItem:{title:"Parameterized Tests",permalink:"/parameterized-tests"}},o={authorsImageUrls:[]},l=[{value:"\uc790\ub3d9\ucc28 \uacbd\uc8fc",id:"\uc790\ub3d9\ucc28-\uacbd\uc8fc",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function p(e){const r={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",hr:"hr",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(r.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/java-racingcar/pull/510",children:"https://github.com/woowacourse/java-racingcar/pull/510"}),(0,t.jsx)(r.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(r.a,{href:"https://github.com/woowacourse/java-racingcar/pull/538",children:"https://github.com/woowacourse/java-racingcar/pull/538"})]})}),"\n",(0,t.jsx)(r.h3,{id:"\uc790\ub3d9\ucc28-\uacbd\uc8fc",children:"\uc790\ub3d9\ucc28 \uacbd\uc8fc"}),"\n",(0,t.jsxs)(r.p,{children:["\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158\uc5d0\uc11c\ub294 \ub2e4\uc990\uacfc \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc6b0\ud14c\ucf54 \ub4e4\uc5b4\uc640\uc11c \uccab \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\uc774\ub77c \ub9ce\uc774 \ub5a8\ub838\uc9c0\ub9cc, \ub2e4\uc990\uc774 \ub300\ud654\ub97c \uc798 \uc774\ub04c\uc5b4\uc918 \ub108\ubb34 \uc990\uac70\uc6e0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uccab\ub0a0\uc740 \uac04\ub2e8\ud788 \ucee8\ubca4\uc158\uacfc \ud658\uacbd\uc744 \uc124\uc815\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc84c\uace0 \ub2e4\uc74c \ub0a0\ubd80\ud130 \uc790\ub3d9\ucc28 \uacbd\uc8fc\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc2dc\uc791\uc740 \uac04\ub2e8\ud558\uac8c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud558\uace0, \uc5b4\ub5bb\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud560\uc9c0 \uac19\uc774 \uace0\ubbfc\ud588\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc2dc\uc791\ud558\uae30 \uc804 \uc544\ub798\uc640 \uac19\uc774 mermaid\ub97c \uc774\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc5d0 \ub300\ud574\uc11c \uac04\ub2e8\ud55c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uace0 \uc2dc\uc791\ud588\ub2e4.",(0,t.jsx)(r.br,{}),"\n","mermaid\ub294 \ucf54\ub4dc\ub85c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \uc0dd\uc131 \ud574\uc8fc\ub294 \ub3c4\uad6c\ub85c \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc774 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:"\ucf54\ub4dc \uae30\ubc18\uc774\ub77c \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \uc0dd\uac01\ud55c \uac83\uc744 \uc2dc\uac01\ud654\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(r.li,{children:"github\uc5d0\uc11c mermaid\ub97c \uc9c0\uc6d0\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \ucf54\ub4dc\ub97c \uc774\ud574\ud560 \uc218 \uc788\ub294 \ubd80\uac00\uc801\uc778 \uc815\ubcf4\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4."}),"\n"]}),"\n",(0,t.jsx)(r.mermaid,{value:"---\ntitle: \uc790\ub3d9\ucc28 \uacbd\uc8fc \uccab \ub9ac\ubdf0 \uc694\uccad\uc2dc \uad6c\uc870\n---\ngraph TD\n Cars --\x3e Car\n Car --\x3e Name\n Car --\x3e Position\n RacingGame --\x3e Count\n RacingGame --\x3e NumberGenerator\n RacingGame --\x3e Cars\n RacingCarController --\x3e RacingGame\n RandomNumberGenerator -.-> NumberGenerator\n RacingCarController --\x3e InputView\n InputView --\x3e InputValidator\n RacingCarController --\x3e OutputView"}),"\n",(0,t.jsx)(r.p,{children:"\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \ub370 \ud070 \uc5b4\ub824\uc6c0\uc774 \uc788\uc9c0\ub294 \uc54a\uc558\uace0, \ud398\uc5b4\ub97c \ub9c8\uce58\uae30 \uc804 \uc11c\ub85c \uace0\ubbfc\ub418\ub294 \ubd80\ubd84\uc744 \uc815\ub9ac\ud588\uc744 \ub54c \uc88b\uc558\ub2e4."}),"\n",(0,t.jsxs)(r.p,{children:["\ud398\uc5b4\ud558\uba74\uc11c \uc798\ud588\ub2e4\uace0 \uc0dd\uac01\ud588\ub358 \uc810\uc740 \uc11c\ub85c\uc758 \uc0dd\uac01\uacfc \ub9ac\ubdf0 \ubc1b\uc740 \uac83\uc744 \uacf5\uc720\ud55c \uac83\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub9ac\ud329\ud130\ub9c1\uc744 \uc5b4\ub5bb\uac8c \ud588\ub294\uc9c0? \uc774\ub7f0 \ub9ac\ubdf0\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \uc0dd\uac01\ud558\ub294\uc9c0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c8 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:["\ub9ac\ud329\ud130\ub9c1\uc774 \ub05d\ub09c \ud6c4 \uba54\uc11c\ub4dc\uba85, \ud14c\uc2a4\ud2b8\uc2dc \ucd9c\ub825\ud558\ub294 \uba54\uc2dc\uc9c0\uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\uac00 \ub9ce\uc774 \ub2ec\ub838\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uac1d\uccb4\uac00 \uc5b4\ub5a4 \ucc45\uc784\uacfc \uc5ed\ud560\uc744 \uac00\uc9c0\ub294\uc9c0 \uc0dd\uac01\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uba85\ud655\ud55c \uba54\uc11c\ub4dc\uba85\uc744 \uc791\uc131\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\ud3c9\uc18c\uc5d0 \ud504\ub85c\uadf8\ub798\ubc0d \uc774\uc57c\uae30\uac00 \uc544\ub2cc \ub2e4\ub978 \uc8fc\uc81c\ub85c \uc774\uc57c\uae30\ud558\uba74 \uc798 \ub4e4\uc73c\ub824\uace0 \ud558\ub294 \ud3b8\uc774\uc9c0\ub9cc",(0,t.jsx)(r.br,{}),"\n","\ub0b4\uac00 \uc88b\uc544\ud558\ub294 \uc8fc\uc81c, \uad00\uc2ec\uac00\ub294 \uc8fc\uc81c\uc778 \ud504\ub85c\uadf8\ub798\ubc0d\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub97c \ud560 \ub550 \ub9d0\uc774 \ub9ce\uc544\uc9c4\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130\ub294 \ub354 \ub9ce\uc740 \uc2dc\uac04\uc744 \ud398\uc5b4\uc758 \uc758\uacac\uacfc \uc774\uc57c\uae30\ub97c \ub4e3\ub294 \uacf3\uc5d0 \uc0ac\uc6a9\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"Assertions extracting"})}),"\n",(0,t.jsxs)(r.p,{children:["\uacb0\uacfc \ub0b4\ubd80\uc5d0 \uc788\ub294 \uac12\uc744 \ud655\uc778\ud558\uace0 \uc2f6\uc744 \ub54c extracting \ud0a4\uc6cc\ub4dc\ub97c \uc774\uc6a9\ud574\uc11c \ub0b4\ubd80\uc758 \uac12\uc744 \uac80\uc99d\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\uc804\uc5d0\ub294 \ud544\uc694\uc5d0 \ub530\ub77c stream\uc744 \uc774\uc6a9\ud558\uc5ec \uac80\uc99d\ud560 \uac12\uc744 \uc0dd\uc131\ud588\uc9c0\ub9cc, \ud574\ub2f9 \ubc29\ubc95\uc744 \uc774\uc6a9\ud574\uc11c \uc808\ucc28\ub97c \uc904\uc77c \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(r.pre,{children:(0,t.jsx)(r.code,{className:"language-java",children:'@Test\nvoid extracting() {\n final Cars cars = new Cars(List.of("car1", "car2"));\n\n assertThat(cars.getCars())\n .extracting(Car::getName)\n .containsExactly("car1", "car2");\n}\n'})}),"\n",(0,t.jsx)(r.hr,{}),"\n",(0,t.jsx)(r.p,{children:"\uc544\ub798\ub294 \ub9ac\ubdf0\uc5b4\ub2d8\uacfc \ub300\ud654\ub97c \ub098\ub204\uba74\uc11c \uc5bb\uc740 \ub2f5\ubcc0 + \ub098\uc758 \uc758\uacac\uc774\ub2e4."}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8"})}),"\n",(0,t.jsxs)(r.p,{children:["\ud14c\uc2a4\ud2b8 \ub300\uc0c1\uc774 \uac80\uc99d\ub41c \uac83\uc774\ub77c\uba74 \uc791\uc131\ud558\uc9c0 \uc54a\uac70\ub098, \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uc791\uc131\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\uac74 \uac1c\uc778\uc801\uc778 \uc0dd\uac01\uc774\uc9c0\ub9cc \ub0b4\uac00 \uc548\uc815\uac10\uc774 \ub4e4 \uc218 \uc788\uc744 \uc815\ub3c4\ub85c \ucd9c\ub825 \ubc94\uc704 \ub0b4\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud558\ub294\uc9c0 \uc815\ub3c4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?"]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ub2e8\uc21c \uc704\uc784\uc744 \ud558\ub294 \uba54\uc11c\ub4dc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8"})}),"\n",(0,t.jsxs)(r.p,{children:["\uc704\uc784\uc774\ub77c\ub294 \uac83\uc740 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \ub118\uaca8\uc900\ub2e4\ub294 \uac83\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc99d\ud558\ub294 \uac83\ubcf4\ub2e4 \uacb0\uacfc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub2e8\uc21c\ud788 \uc704\uc784\ub9cc \ud558\ub294 \ud14c\uc2a4\ud2b8\uc758 \uacbd\uc6b0 \uacb0\uacfc\ub97c \uac80\uc99d\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8\uac00 \uc911\ubcf5\ub418\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub530\ub77c\uc11c \uc911\ubcf5\ub41c \ud14c\uc2a4\ud2b8\ub97c \uc904\uc774\uae30 \uc704\ud574 \ub0b4\ubd80\uc758 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0 \uac80\uc99d\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\ub294 \uac83\uc744 \uc54c\uac8c \ub418\uc5c8\uc9c0\ub9cc",(0,t.jsx)(r.br,{}),"\n","\uc548\uc815\uc801\uc73c\ub85c \uacb0\uacfc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc778 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:(0,t.jsx)(r.strong,{children:"\ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c getter \uc0ac\uc6a9"})}),"\n",(0,t.jsxs)(r.p,{children:["\ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\ub85c \ub3c4\uba54\uc778\uc5d0 \uc0c8\ub85c\uc6b4 \uba54\uc11c\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc740 \uc88b\uc9c0 \ubabb\ud558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud544\uc694\uc758 \uacbd\uc6b0 \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc9c0\ub9cc, \uae30\uc874\uc5d0 \uc788\ub294 \uba54\uc11c\ub4dc\ub4e4\uc744 \ud65c\uc6a9\ud574\ubcf4\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub9e4\uc6b0 \ub3d9\uc758\ud558\uace0, \uc55e\uc73c\ub85c\ub3c4 \ucd5c\ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \ucf54\ub4dc\ub97c \ub3c4\uba54\uc778\uc5d0 \uc791\uc131\ud558\uc9c0 \uc54a\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsxs)(r.p,{children:["\uc9c8\ubb38\uc774\ub098 \uc0dd\uac01\ud560 \uc810\uc774 \uc788\uc744 \ub54c \ub9e4\uc6b0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uac83 \uac19\uc558\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc0dd\uac01\uc744 \uc815\ub9ac\ud55c \ud6c4 \uc790\uc2e0\uc758 \uc758\uacac\uc744 \uba85\ub8cc\ud558\uac8c \uc804\ub2ec\ud574\uc8fc\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc2dd\uc744 \ud6a8\uc728\uc801\uc73c\ub85c \uc2b5\ub4dd\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub09c \uc0dd\uac01\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc740 \ucc44\ub85c \ub0b4\ubc84\ub824 \ub454 \uc595\uc740 \uc9c0\uc2dd\uc774 \ub9ce\uc740 \uac83 \uac19\ub2e4. (\uc774\ub7f0 \uac83\ub3c4 \uc544\ub294 \uac83\uc774\ub77c\uace0 \ud560 \uc218 \uc788\uc744\uae4c?)",(0,t.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c \uc870\uae08 \ub354 \uba38\ub9bf\uc18d\uc5d0\uc11c \uc815\ub9ac\ud558\uace0, \ubb38\uc81c\uc5d0 \ub300\ud574 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \ub298\ub824\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uac1c\ubc1c\uc5d0 \uc5f4\uc815\uc744 \uac00\uc9c4 \uac8c \ub290\uaef4\uc9c4\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ub098\ub3c4 \uac1c\ubc1c\uc744 \uc88b\uc544\ud558\uc9c0\ub9cc, \ucd5c\uadfc\uc5d0\ub294 \uc758\uc9c0\uac00 \uc57d\ud574\uc84c\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc5f4\uc815\uc774 \uac00\ub4dd\ud55c \uc0ac\ub78c\uc744 \ub9cc\ub098\ub2c8 \ub098\ub3c4 \uc5f4\uc815\uc801\uc778 \uc0ac\ub78c\uc774 \ub418\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uce6d\ucc2c\uc744 \ub9ce\uc774 \ud574\uc900\ub2e4. \ub2e8\uc21c\ud788 \ub9ce\uc774 \ud574\uc8fc\ub294 \uac83\uc774 \uc544\ub2c8\ub77c, \uc9c4\uc2ec\uc744 \ub2f4\uae34 \uce6d\ucc2c\uc744 \ud574\uc92c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uce6d\ucc2c\uc740 \uace0\ub798\ub3c4 \ucda4\ucd94\uac8c \ud558\ub358\uac00?",(0,t.jsx)(r.br,{}),"\n","\uadf8\ub798\uc11c \uc990\uac70\uc6b4 \ub9c8\uc74c\uc73c\ub85c \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud588\uc5c8\ub358 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(r.p,{children:["\uc5b4\ub5a4 \uc774\uc720 \ub54c\ubb38\uc778\uc9c0 \ubaa8\ub974\uaca0\uc9c0\ub9cc \uac19\uc774 \ud398\uc5b4\ud558\ub294\ub370 \ud3b8\ud55c \ub9c8\uc74c\uc774 \ub4e4\uc5c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc774\uac74 \ubc14\ub85c \ubc30\uc6b8 \uc218 \uc5c6\uc9c0\ub9cc.",(0,t.jsx)(r.br,{}),"\n","\ub098\ub3c4 \uac19\uc774 \uc77c\ud560 \ub54c \ud3b8\ud55c \uc0ac\ub78c, \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub418\uae30 \uc704\ud574 \uae4a\uc774 \uace0\ubbfc\ud574\ubd10\uc57c\uaca0\ub2e4."]})]})}function x(e={}){const{wrapper:r}={...(0,a.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>l});var t=n(67294);function a(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function s(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function i(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?s(Object(n),!0).forEach((function(r){a(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function c(e,r){if(null==e)return{};var n,t,a=function(e,r){if(null==e)return{};var n,t,a={},s=Object.keys(e);for(t=0;t<s.length;t++)n=s[t],r.indexOf(n)>=0||(a[n]=e[n]);return a}(e,r);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t<s.length;t++)n=s[t],r.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var o=t.createContext({}),l=function(e){var r=t.useContext(o),n=r;return e&&(n="function"==typeof e?e(r):i(i({},r),e)),n},p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},x=t.forwardRef((function(e,r){var n=e.components,a=e.mdxType,s=e.originalType,o=e.parentName,x=c(e,["components","mdxType","originalType","parentName"]),d=l(n),j=a,h=d["".concat(o,".").concat(j)]||d[j]||p[j]||s;return n?t.createElement(h,i(i({ref:r},x),{},{components:n})):t.createElement(h,i({ref:r},x))}));x.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/b6ffb0cb.5114dc6f.js b/assets/js/b6ffb0cb.5114dc6f.js deleted file mode 100644 index ac8c4f29c..000000000 --- a/assets/js/b6ffb0cb.5114dc6f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2156],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>k});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},s=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),s=c(r),k=a,g=s["".concat(i,".").concat(k)]||s[k]||m[k]||p;return r?n.createElement(g,l(l({ref:t},u),{},{components:r})):n.createElement(g,l({ref:t},u))}));function k(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,l=new Array(p);l[0]=s;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o.mdxType="string"==typeof e?e:a,l[1]=o;for(var c=2;c<p;c++)l[c]=r[c];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}s.displayName="MDXCreateElement"},47682:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>m,frontMatter:()=>p,metadata:()=>o,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const p={title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",slug:"racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},l=void 0,o={permalink:"/racing-car-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-racingcar/pull/510",date:"2023-02-14T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 14\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:7.625,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",slug:"racing-car-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",permalink:"/ladder-retrospective"},nextItem:{title:"Parameterized Tests",permalink:"/parameterized-tests"}},i={authorsImageUrls:[]},c=[{value:"\uc790\ub3d9\ucc28 \uacbd\uc8fc",id:"\uc790\ub3d9\ucc28-\uacbd\uc8fc",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],u={toc:c};function m(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-racingcar/pull/510"},"https://github.com/woowacourse/java-racingcar/pull/510"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-racingcar/pull/538"},"https://github.com/woowacourse/java-racingcar/pull/538")," ")),(0,a.kt)("h3",{id:"\uc790\ub3d9\ucc28-\uacbd\uc8fc"},"\uc790\ub3d9\ucc28 \uacbd\uc8fc"),(0,a.kt)("p",null,"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158\uc5d0\uc11c\ub294 \ub2e4\uc990\uacfc \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ud14c\ucf54 \ub4e4\uc5b4\uc640\uc11c \uccab \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d\uc774\ub77c \ub9ce\uc774 \ub5a8\ub838\uc9c0\ub9cc, \ub2e4\uc990\uc774 \ub300\ud654\ub97c \uc798 \uc774\ub04c\uc5b4\uc918 \ub108\ubb34 \uc990\uac70\uc6e0\ub2e4. "),(0,a.kt)("p",null,"\uccab\ub0a0\uc740 \uac04\ub2e8\ud788 \ucee8\ubca4\uc158\uacfc \ud658\uacbd\uc744 \uc124\uc815\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc84c\uace0 \ub2e4\uc74c \ub0a0\ubd80\ud130 \uc790\ub3d9\ucc28 \uacbd\uc8fc\ub97c \uc2dc\uc791\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2dc\uc791\uc740 \uac04\ub2e8\ud558\uac8c \uc694\uad6c\uc0ac\ud56d\uc744 \uc815\ub9ac\ud558\uace0, \uc5b4\ub5bb\uac8c \ucf54\ub4dc\ub97c \uc791\uc131\ud560\uc9c0 \uac19\uc774 \uace0\ubbfc\ud588\ub2e4. "),(0,a.kt)("p",null,"\uc2dc\uc791\ud558\uae30 \uc804 \uc544\ub798\uc640 \uac19\uc774 mermaid\ub97c \uc774\uc6a9\ud558\uc5ec \uc758\uc874\uc131 \ubc29\ud5a5\uc5d0 \ub300\ud574\uc11c \uac04\ub2e8\ud55c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \ub9cc\ub4e4\uace0 \uc2dc\uc791\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","mermaid\ub294 \ucf54\ub4dc\ub85c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc744 \uc0dd\uc131 \ud574\uc8fc\ub294 \ub3c4\uad6c\ub85c \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc774 \uc788\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\ucf54\ub4dc \uae30\ubc18\uc774\ub77c \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \uc0dd\uac01\ud55c \uac83\uc744 \uc2dc\uac01\ud654\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("li",{parentName:"ul"},"github\uc5d0\uc11c mermaid\ub97c \uc9c0\uc6d0\ud558\uae30 \ub54c\ubb38\uc5d0 \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \ucf54\ub4dc\ub97c \uc774\ud574\ud560 \uc218 \uc788\ub294 \ubd80\uac00\uc801\uc778 \uc815\ubcf4\ub97c \uc81c\uacf5\ud560 \uc218 \uc788\ub2e4.")),(0,a.kt)("mermaid",{value:"---\ntitle: \uc790\ub3d9\ucc28 \uacbd\uc8fc \uccab \ub9ac\ubdf0 \uc694\uccad\uc2dc \uad6c\uc870\n---\ngraph TD\n Cars --\x3e Car\n Car --\x3e Name\n Car --\x3e Position\n RacingGame --\x3e Count\n RacingGame --\x3e NumberGenerator\n RacingGame --\x3e Cars\n RacingCarController --\x3e RacingGame\n RandomNumberGenerator -.-> NumberGenerator\n RacingCarController --\x3e InputView\n InputView --\x3e InputValidator\n RacingCarController --\x3e OutputView"}),(0,a.kt)("p",null,"\ubbf8\uc158\uc744 \uc9c4\ud589\ud558\ub294 \ub370 \ud070 \uc5b4\ub824\uc6c0\uc774 \uc788\uc9c0\ub294 \uc54a\uc558\uace0, \ud398\uc5b4\ub97c \ub9c8\uce58\uae30 \uc804 \uc11c\ub85c \uace0\ubbfc\ub418\ub294 \ubd80\ubd84\uc744 \uc815\ub9ac\ud588\uc744 \ub54c \uc88b\uc558\ub2e4."),(0,a.kt)("p",null,"\ud398\uc5b4\ud558\uba74\uc11c \uc798\ud588\ub2e4\uace0 \uc0dd\uac01\ud588\ub358 \uc810\uc740 \uc11c\ub85c\uc758 \uc0dd\uac01\uacfc \ub9ac\ubdf0 \ubc1b\uc740 \uac83\uc744 \uacf5\uc720\ud55c \uac83\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ud329\ud130\ub9c1\uc744 \uc5b4\ub5bb\uac8c \ud588\ub294\uc9c0? \uc774\ub7f0 \ub9ac\ubdf0\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \uc0dd\uac01\ud558\ub294\uc9c0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c8 \uc218 \uc788\uc5c8\ub2e4."),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,"\ub9ac\ud329\ud130\ub9c1\uc774 \ub05d\ub09c \ud6c4 \uba54\uc11c\ub4dc\uba85, \ud14c\uc2a4\ud2b8\uc2dc \ucd9c\ub825\ud558\ub294 \uba54\uc2dc\uc9c0\uc5d0 \ub300\ud55c \ucf54\uba58\ud2b8\uac00 \ub9ce\uc774 \ub2ec\ub838\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uac1d\uccb4\uac00 \uc5b4\ub5a4 \ucc45\uc784\uacfc \uc5ed\ud560\uc744 \uac00\uc9c0\ub294\uc9c0 \uc0dd\uac01\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uba85\ud655\ud55c \uba54\uc11c\ub4dc\uba85\uc744 \uc791\uc131\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("p",null,"\ud3c9\uc18c\uc5d0 \ud504\ub85c\uadf8\ub798\ubc0d \uc774\uc57c\uae30\uac00 \uc544\ub2cc \ub2e4\ub978 \uc8fc\uc81c\ub85c \uc774\uc57c\uae30\ud558\uba74 \uc798 \ub4e4\uc73c\ub824\uace0 \ud558\ub294 \ud3b8\uc774\uc9c0\ub9cc",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \uc88b\uc544\ud558\ub294 \uc8fc\uc81c, \uad00\uc2ec\uac00\ub294 \uc8fc\uc81c\uc778 \ud504\ub85c\uadf8\ub798\ubc0d\uc5d0 \ub300\ud55c \uc774\uc57c\uae30\ub97c \ud560 \ub550 \ub9d0\uc774 \ub9ce\uc544\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \ubbf8\uc158\ubd80\ud130\ub294 \ub354 \ub9ce\uc740 \uc2dc\uac04\uc744 \ud398\uc5b4\uc758 \uc758\uacac\uacfc \uc774\uc57c\uae30\ub97c \ub4e3\ub294 \uacf3\uc5d0 \uc0ac\uc6a9\ud574\uc57c\uaca0\ub2e4."),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"Assertions extracting")),(0,a.kt)("p",null,"\uacb0\uacfc \ub0b4\ubd80\uc5d0 \uc788\ub294 \uac12\uc744 \ud655\uc778\ud558\uace0 \uc2f6\uc744 \ub54c extracting \ud0a4\uc6cc\ub4dc\ub97c \uc774\uc6a9\ud574\uc11c \ub0b4\ubd80\uc758 \uac12\uc744 \uac80\uc99d\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804\uc5d0\ub294 \ud544\uc694\uc5d0 \ub530\ub77c stream\uc744 \uc774\uc6a9\ud558\uc5ec \uac80\uc99d\ud560 \uac12\uc744 \uc0dd\uc131\ud588\uc9c0\ub9cc, \ud574\ub2f9 \ubc29\ubc95\uc744 \uc774\uc6a9\ud574\uc11c \uc808\ucc28\ub97c \uc904\uc77c \uc218 \uc788\uc5c8\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'@Test\nvoid extracting() {\n final Cars cars = new Cars(List.of("car1", "car2"));\n\n assertThat(cars.getCars())\n .extracting(Car::getName)\n .containsExactly("car1", "car2");\n}\n')),(0,a.kt)("hr",null),(0,a.kt)("p",null,"\uc544\ub798\ub294 \ub9ac\ubdf0\uc5b4\ub2d8\uacfc \ub300\ud654\ub97c \ub098\ub204\uba74\uc11c \uc5bb\uc740 \ub2f5\ubcc0 + \ub098\uc758 \uc758\uacac\uc774\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc81c\uc5b4\ud560 \uc218 \uc5c6\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8")),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8 \ub300\uc0c1\uc774 \uac80\uc99d\ub41c \uac83\uc774\ub77c\uba74 \uc791\uc131\ud558\uc9c0 \uc54a\uac70\ub098, \uc81c\uc5b4\ud560 \uc218 \uc788\ub294 \ubd80\ubd84\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \ub354\uc6b1 \uaf3c\uaf3c\ud558\uac8c \uc791\uc131\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uac74 \uac1c\uc778\uc801\uc778 \uc0dd\uac01\uc774\uc9c0\ub9cc \ub0b4\uac00 \uc548\uc815\uac10\uc774 \ub4e4 \uc218 \uc788\uc744 \uc815\ub3c4\ub85c \ucd9c\ub825 \ubc94\uc704 \ub0b4\uc758 \uacb0\uacfc\ub97c \ubc18\ud658\ud558\ub294\uc9c0 \uc815\ub3c4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ub2e8\uc21c \uc704\uc784\uc744 \ud558\ub294 \uba54\uc11c\ub4dc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8")),(0,a.kt)("p",null,"\uc704\uc784\uc774\ub77c\ub294 \uac83\uc740 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \ub118\uaca8\uc900\ub2e4\ub294 \uac83\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud638\ucd9c \ud69f\uc218\ub97c \uac80\uc99d\ud558\ub294 \uac83\ubcf4\ub2e4 \uacb0\uacfc\uc5d0 \ub300\ud55c \ud14c\uc2a4\ud2b8\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc21c\ud788 \uc704\uc784\ub9cc \ud558\ub294 \ud14c\uc2a4\ud2b8\uc758 \uacbd\uc6b0 \uacb0\uacfc\ub97c \uac80\uc99d\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8\uac00 \uc911\ubcf5\ub418\uc9c0 \uc54a\uc744\uae4c \uc0dd\uac01\ud588\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc911\ubcf5\ub41c \ud14c\uc2a4\ud2b8\ub97c \uc904\uc774\uae30 \uc704\ud574 \ub0b4\ubd80\uc758 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0 \uac80\uc99d\ud558\ub294 \ubc29\ubc95\ub3c4 \uc788\ub2e4\ub294 \uac83\uc744 \uc54c\uac8c \ub418\uc5c8\uc9c0\ub9cc",(0,a.kt)("br",{parentName:"p"}),"\n","\uc548\uc815\uc801\uc73c\ub85c \uacb0\uacfc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc778 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c getter \uc0ac\uc6a9")),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\ub85c \ub3c4\uba54\uc778\uc5d0 \uc0c8\ub85c\uc6b4 \uba54\uc11c\ub4dc\uac00 \uc0dd\uc131\ub418\ub294 \uac83\uc740 \uc88b\uc9c0 \ubabb\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud544\uc694\uc758 \uacbd\uc6b0 \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc9c0\ub9cc, \uae30\uc874\uc5d0 \uc788\ub294 \uba54\uc11c\ub4dc\ub4e4\uc744 \ud65c\uc6a9\ud574\ubcf4\ub294 \uac83\uc774 \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub9e4\uc6b0 \ub3d9\uc758\ud558\uace0, \uc55e\uc73c\ub85c\ub3c4 \ucd5c\ub300\ud55c \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \ucf54\ub4dc\ub97c \ub3c4\uba54\uc778\uc5d0 \uc791\uc131\ud558\uc9c0 \uc54a\uc744 \uac83 \uac19\ub2e4."),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,"\uc9c8\ubb38\uc774\ub098 \uc0dd\uac01\ud560 \uc810\uc774 \uc788\uc744 \ub54c \ub9e4\uc6b0 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uac83 \uac19\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0dd\uac01\uc744 \uc815\ub9ac\ud55c \ud6c4 \uc790\uc2e0\uc758 \uc758\uacac\uc744 \uba85\ub8cc\ud558\uac8c \uc804\ub2ec\ud574\uc8fc\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc2dd\uc744 \ud6a8\uc728\uc801\uc73c\ub85c \uc2b5\ub4dd\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub09c \uc0dd\uac01\uc744 \uc798 \uc815\ub9ac\ud558\uc9c0 \uc54a\uc740 \ucc44\ub85c \ub0b4\ubc84\ub824 \ub454 \uc595\uc740 \uc9c0\uc2dd\uc774 \ub9ce\uc740 \uac83 \uac19\ub2e4. (\uc774\ub7f0 \uac83\ub3c4 \uc544\ub294 \uac83\uc774\ub77c\uace0 \ud560 \uc218 \uc788\uc744\uae4c?)",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc870\uae08 \ub354 \uba38\ub9bf\uc18d\uc5d0\uc11c \uc815\ub9ac\ud558\uace0, \ubb38\uc81c\uc5d0 \ub300\ud574 \uae4a\uac8c \uace0\ubbfc\ud558\ub294 \uc2dc\uac04\uc744 \ub298\ub824\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,"\uac1c\ubc1c\uc5d0 \uc5f4\uc815\uc744 \uac00\uc9c4 \uac8c \ub290\uaef4\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 \uac1c\ubc1c\uc744 \uc88b\uc544\ud558\uc9c0\ub9cc, \ucd5c\uadfc\uc5d0\ub294 \uc758\uc9c0\uac00 \uc57d\ud574\uc84c\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc5f4\uc815\uc774 \uac00\ub4dd\ud55c \uc0ac\ub78c\uc744 \ub9cc\ub098\ub2c8 \ub098\ub3c4 \uc5f4\uc815\uc801\uc778 \uc0ac\ub78c\uc774 \ub418\ub294 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,"\uce6d\ucc2c\uc744 \ub9ce\uc774 \ud574\uc900\ub2e4. \ub2e8\uc21c\ud788 \ub9ce\uc774 \ud574\uc8fc\ub294 \uac83\uc774 \uc544\ub2c8\ub77c, \uc9c4\uc2ec\uc744 \ub2f4\uae34 \uce6d\ucc2c\uc744 \ud574\uc92c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uce6d\ucc2c\uc740 \uace0\ub798\ub3c4 \ucda4\ucd94\uac8c \ud558\ub358\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub798\uc11c \uc990\uac70\uc6b4 \ub9c8\uc74c\uc73c\ub85c \ud398\uc5b4 \ud504\ub85c\uadf8\ub798\ubc0d\uc744 \ud588\uc5c8\ub358 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,"\uc5b4\ub5a4 \uc774\uc720 \ub54c\ubb38\uc778\uc9c0 \ubaa8\ub974\uaca0\uc9c0\ub9cc \uac19\uc774 \ud398\uc5b4\ud558\ub294\ub370 \ud3b8\ud55c \ub9c8\uc74c\uc774 \ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uac74 \ubc14\ub85c \ubc30\uc6b8 \uc218 \uc5c6\uc9c0\ub9cc.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 \uac19\uc774 \uc77c\ud560 \ub54c \ud3b8\ud55c \uc0ac\ub78c, \uac19\uc774 \uc77c\ud558\uace0 \uc2f6\uc740 \uc0ac\ub78c\uc774 \ub418\uae30 \uc704\ud574 \uae4a\uc774 \uace0\ubbfc\ud574\ubd10\uc57c\uaca0\ub2e4."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b7d33121.17983764.js b/assets/js/b7d33121.74e8d043.js similarity index 83% rename from assets/js/b7d33121.17983764.js rename to assets/js/b7d33121.74e8d043.js index 4b6cf6949..73a1bf66e 100644 --- a/assets/js/b7d33121.17983764.js +++ b/assets/js/b7d33121.74e8d043.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7153],{72005:e=>{e.exports=JSON.parse('{"label":"cloudwatch","permalink":"/tags/cloudwatch","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7153],{72005:e=>{e.exports=JSON.parse('{"label":"cloudwatch","permalink":"/tags/cloudwatch","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/b88cb85b.19706a2f.js b/assets/js/b88cb85b.19706a2f.js new file mode 100644 index 000000000..3069acaa2 --- /dev/null +++ b/assets/js/b88cb85b.19706a2f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2293],{95864:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=t(85893),a=t(3905);const o={title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",slug:"/network/load-balancing-algorithm",last_update:{date:"2023/09/05"},tags:["network","load balancing"]},i=void 0,l={id:"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",description:"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)",source:"@site/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998.mdx",sourceDirName:"\ub124\ud2b8\uc6cc\ud06c",slug:"/network/load-balancing-algorithm",permalink:"/docs/network/load-balancing-algorithm",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998.mdx",tags:[{label:"network",permalink:"/docs/tags/network"},{label:"load balancing",permalink:"/docs/tags/load-balancing"}],version:"current",lastUpdatedAt:1693872e3,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 5\uc77c",frontMatter:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",slug:"/network/load-balancing-algorithm",last_update:{date:"2023/09/05"},tags:["network","load balancing"]},sidebar:"tutorialSidebar",previous:{title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",permalink:"/docs/etc/communication"},next:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",permalink:"/docs/network/load-balancing"}},d={},s=[{value:"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)",id:"\ub77c\uc6b4\ub4dc\ub85c\ube48-\ubc29\uc2ddround-robin-method",level:3},{value:"\uac00\uc911 \uae30\ubc18 \ub77c\uc6b4\ub4dc \ub85c\ube48 \ubc29\uc2dd(Weighted Round Robin Method)",id:"\uac00\uc911-\uae30\ubc18-\ub77c\uc6b4\ub4dc-\ub85c\ube48-\ubc29\uc2ddweighted-round-robin-method",level:3},{value:"\ucd5c\uc18c \uc5f0\uacb0 \uae30\ubc18 \ubc29\uc2dd(Least Connection Method)",id:"\ucd5c\uc18c-\uc5f0\uacb0-\uae30\ubc18-\ubc29\uc2ddleast-connection-method",level:3},{value:"IP \ud574\uc2dc \ubc29\uc2dd(IP Hash Method)",id:"ip-\ud574\uc2dc-\ubc29\uc2ddip-hash-method",level:3},{value:"\ucd5c\uc18c \uc751\ub2f5 \uc2dc\uac04 \ubc29\uc2dd(Least Response Time Method)",id:"\ucd5c\uc18c-\uc751\ub2f5-\uc2dc\uac04-\ubc29\uc2ddleast-response-time-method",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function c(e){const n={a:"a",br:"br",h3:"h3",mermaid:"mermaid",p:"p",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"\ub77c\uc6b4\ub4dc\ub85c\ube48-\ubc29\uc2ddround-robin-method",children:"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)"}),"\n",(0,r.jsx)(n.p,{children:"\ud074\ub77c\uc774\uc5b8\ud2b8\ub85c\ubd80\ud130 \ubc1b\uc740 \uc694\uccad\uc744 \ub85c\ub4dc \ubc38\ub7f0\uc2f1 \ub300\uc0c1 \uc11c\ubc84\uc5d0 \uc21c\uc11c\ub300\ub85c \ud560\ub2f9\ubc1b\ub294 \ubc29\uc2dd"}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n LB[Load Balancer] -- 33% --\x3e A\n LB -- 33% --\x3e B\n LB -- 33% --\x3e C"}),"\n",(0,r.jsx)(n.h3,{id:"\uac00\uc911-\uae30\ubc18-\ub77c\uc6b4\ub4dc-\ub85c\ube48-\ubc29\uc2ddweighted-round-robin-method",children:"\uac00\uc911 \uae30\ubc18 \ub77c\uc6b4\ub4dc \ub85c\ube48 \ubc29\uc2dd(Weighted Round Robin Method)"}),"\n",(0,r.jsx)(n.p,{children:"\uc2e4\uc81c \uc11c\ubc84\uc5d0 \uc11c\ub85c \ub2e4\ub978 \ucc98\ub9ac \uc6a9\ub7c9\uc744 \uc9c0\uc815\ud558\ub294 \ubc29\uc2dd"}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n LB[Load Balancer] -- 80% --\x3e A[A \uc11c\ubc84 4]\n LB -- 20% --\x3e B[B \uc11c\ubc84 1]"}),"\n",(0,r.jsx)(n.h3,{id:"\ucd5c\uc18c-\uc5f0\uacb0-\uae30\ubc18-\ubc29\uc2ddleast-connection-method",children:"\ucd5c\uc18c \uc5f0\uacb0 \uae30\ubc18 \ubc29\uc2dd(Least Connection Method)"}),"\n",(0,r.jsx)(n.p,{children:"\ub85c\ub4dc \ubc38\ub7f0\uc11c\ub294 \ud65c\uc131 \uc5f0\uacb0\uc774 \uac00\uc7a5 \uc801\uc740 \uc11c\ubc84\ub97c \ud655\uc778\ud558\uace0 \ud574\ub2f9 \uc11c\ubc84\ub85c \ud2b8\ub798\ud53d\uc744 \uc804\uc1a1"}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n LB[Load Balancer] -- X --\x3e A[A \uc11c\ubc84 \uc5f0\uacb0 \uc218 4]\n LB -- \uc5f0\uacb0\uc218\uac00 \uc801\uc740 \uc11c\ubc84\ub85c \uc120\ud0dd --\x3e B[B \uc11c\ubc84 \uc5f0\uacb0 \uc218 3]"}),"\n",(0,r.jsx)(n.h3,{id:"ip-\ud574\uc2dc-\ubc29\uc2ddip-hash-method",children:"IP \ud574\uc2dc \ubc29\uc2dd(IP Hash Method)"}),"\n",(0,r.jsxs)(n.p,{children:["\uac01 \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0 \ub300\ud574 Hashing key\ub97c \uac00\uc9c0\uace0 \uacbd\ub85c\ub97c \uc9c0\uc815",(0,r.jsx)(n.br,{}),"\n","Hashing key\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 IP + port \ud639\uc740 IP \uc8fc\uc18c\ub9cc\uc73c\ub85c \uacb0\uc815",(0,r.jsx)(n.br,{}),"\n","\uc0ac\uc6a9\uc790\uac00 \ud56d\uc0c1 \ub3d9\uc77c\ud55c \uc11c\ubc84\ub85c \uc5f0\uacb0\ub418\ub294 \uac83\uc744 \ubcf4\uc7a5"]}),"\n",(0,r.jsx)(n.mermaid,{value:'graph LR\n LB[Load Balancer] -- "hash(13.32.45.56)" --\x3e A\n LB -- "hash(142.2.55.24)" --\x3e B\n LB -- "hash(142.2.55.24) \uc7ac\uc694\uccad" --\x3e B'}),"\n",(0,r.jsx)(n.h3,{id:"\ucd5c\uc18c-\uc751\ub2f5-\uc2dc\uac04-\ubc29\uc2ddleast-response-time-method",children:"\ucd5c\uc18c \uc751\ub2f5 \uc2dc\uac04 \ubc29\uc2dd(Least Response Time Method)"}),"\n",(0,r.jsxs)(n.p,{children:["\uc11c\ubc84\uc758 \ud604\uc7ac \uc5f0\uacb0 \uc0c1\ud0dc, \uc751\ub2f5 \uc2dc\uac04 \uace0\ub824\ud558\uc5ec \ud2b8\ub798\ud53d\uc744 \uc804\uc1a1",(0,r.jsx)(n.br,{}),"\n","\uac00\uc7a5 \uc801\uc740 \uc5f0\uacb0 \uc0c1\ud0dc\uc640 \uac00\uc7a5 \uc9e7\uc740 \uc751\ub2f5 \uc2dc\uac04\uc744 \ubcf4\uc774\ub294 \uc11c\ubc84\uc5d0 \uc6b0\uc120\uc801\uc73c\ub85c \ub85c\ub4dc\ub97c \ubc30\ubd84\ud558\ub294 \ubc29\uc2dd"]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n LB[Load Balancer] -- \uc751\ub2f5 \uc2dc\uac04\uc774 \ub354 \ube60\ub974\ub2c8 A \uc11c\ubc84\ub85c \uc804\ub2ec --\x3e A[A \uc751\ub2f5\uc2dc\uac04 100ms]\n LB -- X --\x3e B[B \uc751\ub2f5\uc2dc\uac04 150ms]"}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://aws.amazon.com/ko/what-is/load-balancing/",children:"load balancing, AWS"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://tecoble.techcourse.co.kr/post/2021-11-07-load-balancing/",children:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc5d0 \ub300\ud574 \uc54c\uc544\ubcf4\uc790, \ud14c\ucf54\ube14"})]})]})}function h(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>s});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function l(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var d=r.createContext({}),s=function(e){var n=r.useContext(d),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},c={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},h=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,d=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=s(t),u=a,m=p["".concat(d,".").concat(u)]||p[u]||c[u]||o;return t?r.createElement(m,i(i({ref:n},h),{},{components:t})):r.createElement(m,i({ref:n},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/b88cb85b.58b19204.js b/assets/js/b88cb85b.58b19204.js deleted file mode 100644 index 0e8ad3a6d..000000000 --- a/assets/js/b88cb85b.58b19204.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2293],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var d=a.createContext({}),c=function(e){var t=a.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},p=function(e){var t=c(e.components);return a.createElement(d.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,o=e.originalType,d=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=c(n),m=r,h=u["".concat(d,".").concat(m)]||u[m]||s[m]||o;return n?a.createElement(h,l(l({ref:t},p),{},{components:n})):a.createElement(h,l({ref:t},p))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var o=n.length,l=new Array(o);l[0]=u;var i={};for(var d in t)hasOwnProperty.call(t,d)&&(i[d]=t[d]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var c=2;c<o;c++)l[c]=n[c];return a.createElement.apply(null,l)}return a.createElement.apply(null,n)}u.displayName="MDXCreateElement"},18557:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>s,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var a=n(87462),r=(n(67294),n(3905));const o={title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",slug:"/network/load-balancing-algorithm",last_update:{date:"2023/09/05"},tags:["network","load balancing"]},l=void 0,i={unversionedId:"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",id:"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",description:"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)",source:"@site/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998.mdx",sourceDirName:"\ub124\ud2b8\uc6cc\ud06c",slug:"/network/load-balancing-algorithm",permalink:"/docs/network/load-balancing-algorithm",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998.mdx",tags:[{label:"network",permalink:"/docs/tags/network"},{label:"load balancing",permalink:"/docs/tags/load-balancing"}],version:"current",lastUpdatedAt:1693872e3,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 5\uc77c",frontMatter:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",slug:"/network/load-balancing-algorithm",last_update:{date:"2023/09/05"},tags:["network","load balancing"]},sidebar:"tutorialSidebar",previous:{title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",permalink:"/docs/etc/communication"},next:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",permalink:"/docs/network/load-balancing"}},d={},c=[{value:"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)",id:"\ub77c\uc6b4\ub4dc\ub85c\ube48-\ubc29\uc2ddround-robin-method",level:3},{value:"\uac00\uc911 \uae30\ubc18 \ub77c\uc6b4\ub4dc \ub85c\ube48 \ubc29\uc2dd(Weighted Round Robin Method)",id:"\uac00\uc911-\uae30\ubc18-\ub77c\uc6b4\ub4dc-\ub85c\ube48-\ubc29\uc2ddweighted-round-robin-method",level:3},{value:"\ucd5c\uc18c \uc5f0\uacb0 \uae30\ubc18 \ubc29\uc2dd(Least Connection Method)",id:"\ucd5c\uc18c-\uc5f0\uacb0-\uae30\ubc18-\ubc29\uc2ddleast-connection-method",level:3},{value:"IP \ud574\uc2dc \ubc29\uc2dd(IP Hash Method)",id:"ip-\ud574\uc2dc-\ubc29\uc2ddip-hash-method",level:3},{value:"\ucd5c\uc18c \uc751\ub2f5 \uc2dc\uac04 \ubc29\uc2dd(Least Response Time Method)",id:"\ucd5c\uc18c-\uc751\ub2f5-\uc2dc\uac04-\ubc29\uc2ddleast-response-time-method",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],p={toc:c};function s(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"\ub77c\uc6b4\ub4dc\ub85c\ube48-\ubc29\uc2ddround-robin-method"},"\ub77c\uc6b4\ub4dc\ub85c\ube48 \ubc29\uc2dd(Round Robin Method)"),(0,r.kt)("p",null,"\ud074\ub77c\uc774\uc5b8\ud2b8\ub85c\ubd80\ud130 \ubc1b\uc740 \uc694\uccad\uc744 \ub85c\ub4dc \ubc38\ub7f0\uc2f1 \ub300\uc0c1 \uc11c\ubc84\uc5d0 \uc21c\uc11c\ub300\ub85c \ud560\ub2f9\ubc1b\ub294 \ubc29\uc2dd"),(0,r.kt)("mermaid",{value:"graph LR\n LB[Load Balancer] -- 33% --\x3e A\n LB -- 33% --\x3e B\n LB -- 33% --\x3e C"}),(0,r.kt)("h3",{id:"\uac00\uc911-\uae30\ubc18-\ub77c\uc6b4\ub4dc-\ub85c\ube48-\ubc29\uc2ddweighted-round-robin-method"},"\uac00\uc911 \uae30\ubc18 \ub77c\uc6b4\ub4dc \ub85c\ube48 \ubc29\uc2dd(Weighted Round Robin Method)"),(0,r.kt)("p",null,"\uc2e4\uc81c \uc11c\ubc84\uc5d0 \uc11c\ub85c \ub2e4\ub978 \ucc98\ub9ac \uc6a9\ub7c9\uc744 \uc9c0\uc815\ud558\ub294 \ubc29\uc2dd"),(0,r.kt)("mermaid",{value:"graph LR\n LB[Load Balancer] -- 80% --\x3e A[A \uc11c\ubc84 4]\n LB -- 20% --\x3e B[B \uc11c\ubc84 1]"}),(0,r.kt)("h3",{id:"\ucd5c\uc18c-\uc5f0\uacb0-\uae30\ubc18-\ubc29\uc2ddleast-connection-method"},"\ucd5c\uc18c \uc5f0\uacb0 \uae30\ubc18 \ubc29\uc2dd(Least Connection Method)"),(0,r.kt)("p",null,"\ub85c\ub4dc \ubc38\ub7f0\uc11c\ub294 \ud65c\uc131 \uc5f0\uacb0\uc774 \uac00\uc7a5 \uc801\uc740 \uc11c\ubc84\ub97c \ud655\uc778\ud558\uace0 \ud574\ub2f9 \uc11c\ubc84\ub85c \ud2b8\ub798\ud53d\uc744 \uc804\uc1a1"),(0,r.kt)("mermaid",{value:"graph LR\n LB[Load Balancer] -- X --\x3e A[A \uc11c\ubc84 \uc5f0\uacb0 \uc218 4]\n LB -- \uc5f0\uacb0\uc218\uac00 \uc801\uc740 \uc11c\ubc84\ub85c \uc120\ud0dd --\x3e B[B \uc11c\ubc84 \uc5f0\uacb0 \uc218 3]"}),(0,r.kt)("h3",{id:"ip-\ud574\uc2dc-\ubc29\uc2ddip-hash-method"},"IP \ud574\uc2dc \ubc29\uc2dd(IP Hash Method)"),(0,r.kt)("p",null,"\uac01 \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0 \ub300\ud574 Hashing key\ub97c \uac00\uc9c0\uace0 \uacbd\ub85c\ub97c \uc9c0\uc815",(0,r.kt)("br",{parentName:"p"}),"\n","Hashing key\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 IP + port \ud639\uc740 IP \uc8fc\uc18c\ub9cc\uc73c\ub85c \uacb0\uc815",(0,r.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc6a9\uc790\uac00 \ud56d\uc0c1 \ub3d9\uc77c\ud55c \uc11c\ubc84\ub85c \uc5f0\uacb0\ub418\ub294 \uac83\uc744 \ubcf4\uc7a5"),(0,r.kt)("mermaid",{value:'graph LR\n LB[Load Balancer] -- "hash(13.32.45.56)" --\x3e A\n LB -- "hash(142.2.55.24)" --\x3e B\n LB -- "hash(142.2.55.24) \uc7ac\uc694\uccad" --\x3e B'}),(0,r.kt)("h3",{id:"\ucd5c\uc18c-\uc751\ub2f5-\uc2dc\uac04-\ubc29\uc2ddleast-response-time-method"},"\ucd5c\uc18c \uc751\ub2f5 \uc2dc\uac04 \ubc29\uc2dd(Least Response Time Method)"),(0,r.kt)("p",null,"\uc11c\ubc84\uc758 \ud604\uc7ac \uc5f0\uacb0 \uc0c1\ud0dc, \uc751\ub2f5 \uc2dc\uac04 \uace0\ub824\ud558\uc5ec \ud2b8\ub798\ud53d\uc744 \uc804\uc1a1",(0,r.kt)("br",{parentName:"p"}),"\n","\uac00\uc7a5 \uc801\uc740 \uc5f0\uacb0 \uc0c1\ud0dc\uc640 \uac00\uc7a5 \uc9e7\uc740 \uc751\ub2f5 \uc2dc\uac04\uc744 \ubcf4\uc774\ub294 \uc11c\ubc84\uc5d0 \uc6b0\uc120\uc801\uc73c\ub85c \ub85c\ub4dc\ub97c \ubc30\ubd84\ud558\ub294 \ubc29\uc2dd "),(0,r.kt)("mermaid",{value:"graph LR\n LB[Load Balancer] -- \uc751\ub2f5 \uc2dc\uac04\uc774 \ub354 \ube60\ub974\ub2c8 A \uc11c\ubc84\ub85c \uc804\ub2ec --\x3e A[A \uc751\ub2f5\uc2dc\uac04 100ms]\n LB -- X --\x3e B[B \uc751\ub2f5\uc2dc\uac04 150ms]"}),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/what-is/load-balancing/"},"load balancing, AWS"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://tecoble.techcourse.co.kr/post/2021-11-07-load-balancing/"},"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc5d0 \ub300\ud574 \uc54c\uc544\ubcf4\uc790, \ud14c\ucf54\ube14")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/b9bcab37.2fcdcd9c.js b/assets/js/b9bcab37.341c6751.js similarity index 87% rename from assets/js/b9bcab37.2fcdcd9c.js rename to assets/js/b9bcab37.341c6751.js index 31018c52c..3f1caccf0 100644 --- a/assets/js/b9bcab37.2fcdcd9c.js +++ b/assets/js/b9bcab37.341c6751.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7688],{43632:e=>{e.exports=JSON.parse('{"label":"GRASP","permalink":"/tags/grasp","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7688],{43632:e=>{e.exports=JSON.parse('{"label":"GRASP","permalink":"/tags/grasp","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/bace0b37.3df7fde1.js b/assets/js/bace0b37.3df7fde1.js deleted file mode 100644 index fddcf58be..000000000 --- a/assets/js/bace0b37.3df7fde1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2362],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,l=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=p(n),m=a,g=d["".concat(c,".").concat(m)]||d[m]||s[m]||l;return n?r.createElement(g,o(o({ref:t},u),{},{components:n})):r.createElement(g,o({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=n.length,o=new Array(l);o[0]=d;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i.mdxType="string"==typeof e?e:a,o[1]=i;for(var p=2;p<l;p++)o[p]=n[p];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}d.displayName="MDXCreateElement"},25831:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>s,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var r=n(87462),a=(n(67294),n(3905));const l={title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",slug:"accidental-duplication",tags:["DTO"]},o=void 0,i={permalink:"/accidental-duplication",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",source:"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",description:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",date:"2023-05-24T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 24\uc77c",tags:[{label:"DTO",permalink:"/tags/dto"}],readingTime:7.525,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",slug:"accidental-duplication",tags:["DTO"]},prevItem:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",permalink:"/subway-retrospective"},nextItem:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",permalink:"/shopping-cart-retrospective"}},c={authorsImageUrls:[]},p=[{value:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815",id:"\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158\uc5d0\uc11c\uc758-\uc0c1\ud488-\ucd94\uac00-\ubc0f-\uc218\uc815",level:3},{value:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",id:"\uc911\ubcf5\uacfc-\uc6b0\ubc1c\uc801-\uc911\ubcf5",level:3},{value:"\ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c",id:"\ud558\ub098\ub85c-\uc0ac\uc6a9\ud558\ub294-\uac74-\uc548\uc88b\uc544\ubcf4\uc774\uace0-\uc911\ubcf5\uc740-\uc81c\uac70\ud558\uace0-\uc2f6\uc740-\ub9c8\uc74c",level:3},{value:"\uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc",id:"\uc911\ubcf5-\uc81c\uac70-\uc804-\ucf54\ub4dc",level:3},{value:"\uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30",id:"\uc778\ud130\ud398\uc774\uc2a4-\uc791\uc131\ud558\uae30",level:3},{value:"\uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30",id:"\uad6c\ud604\uccb4-\uc791\uc131\ud558\uae30",level:3},{value:"\uc815\ub9ac",id:"\uc815\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:p};function s(e){let{components:t,...l}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,l,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uccad\uc5d0 \ub2f4\uae34 Body\ub97c \ud1b5\ud574 \uc804\ub2ec\ubc1b\uc740 \uac12\uc744 DTO\ub85c \ub9e4\ud551\ud558\uc5ec \ucd94\uac00\uc640 \uc218\uc815\uc744 \ud588\ub2e4."),(0,a.kt)("h3",{id:"\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158\uc5d0\uc11c\uc758-\uc0c1\ud488-\ucd94\uac00-\ubc0f-\uc218\uc815"},"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"\uc911\ubcf51",src:n(92725).Z,width:"2028",height:"704"})),(0,a.kt)("p",null,"\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d\ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0\uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc704 \uacbd\uc6b0\ub294 \uc911\ubcf5\uc77c\uae4c? \uc911\ubcf5\uc774 \uc544\ub2d0\uae4c?"),(0,a.kt)("p",null,"\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ub9ac\ubdf0\ub97c \ubc1b\uc558\ub2e4."),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},(0,a.kt)("inlineCode",{parentName:"p"},"ProductSaveRequest"),"\uc640 ",(0,a.kt)("inlineCode",{parentName:"p"},"ProductUpdateRequest"),"\uac00 \uc644\uc804\ud788 \ub3d9\uc77c\ud55c\ub370, \uc7ac\uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc744\uae4c? \ub77c\ub294 \ub9ac\ubdf0\ub97c \ub0a8\uacbc\uc5c8\uc5b4\uc694. \uc0ac\uc2e4 \uc0dd\uc131\uacfc \uc218\uc815\uc740 \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac1c\uc5f0\uc131\uc774 \ub192\uc544\uc11c \ubbf8\ub9ac \ubd84\ub9ac\ud574\ub193\ub294 \uac8c \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\uae34 \ud55c\ub370, \uadf8\ub798\ub3c4 \uc911\ubcf5\uc740 \uc2eb\uc5b4\uc11c \uc800\ub3c4 \uc694\uc998 \uc774\ub7f0\uc800\ub7f0 \ubc29\ubc95\ub4e4\uc744 \uc2dc\ub3c4\ud574\ubcf4\ub294 \uc911 \uc785\ub2c8\ub2e4. \ud5c8\ube0c\ub294 \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc5b4\ub5a4 \uc0dd\uac01\uc744 \uac00\uc9c0\uace0 \uc788\uc744\uc9c0 \uad81\uae08\ud558\ub124\uc694 \u314e\u314e")),(0,a.kt)("p",null,"\uc9c8\ubb38\uc5d0 \ub300\ud574 \uc544\ub798\uc640 \uac19\uc774 \ub2f5\ubcc0\uc744 \ud588\ub2e4."),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc800\uc7a5\uacfc \uc218\uc815\ud560 \ub54c \ud544\uc694\ud55c \ud544\ub4dc\uac12\uc774 \ub3d9\uc77c\ud558\uc5ec \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c\ub294 \ud558\ub098\ub85c \uc0ac\uc6a9\ud574\ub3c4 \ub41c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud558\uc9c0\ub9cc, \ub9d0\uc500\ud574\uc8fc\uc2e0\ub300\ub85c \uc694\uad6c\uc0ac\ud56d\uc774 \ubcc0\uacbd\ub41c\ub2e4\uba74 \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\ub2e4\uace0 \ud310\ub2e8\ud558\uc600\uc2b5\ub2c8\ub2e4!")),(0,a.kt)("h3",{id:"\uc911\ubcf5\uacfc-\uc6b0\ubc1c\uc801-\uc911\ubcf5"},"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5"),(0,a.kt)("p",null,"\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec\uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"\uac70\uc9d3\ub41c \uc911\ubcf5, \uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4.")),(0,a.kt)("p",null,"\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131\uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.\n\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc704 \uc0c1\ud669\uc740 \uc6b0\ubc1c\uc801 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc778\ub2e4. \uadf8\ub798\ub3c4 \uc911\ubcf5\uc744 \uc81c\uac70\ud574\ubcfc \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?"),(0,a.kt)("h3",{id:"\ud558\ub098\ub85c-\uc0ac\uc6a9\ud558\ub294-\uac74-\uc548\uc88b\uc544\ubcf4\uc774\uace0-\uc911\ubcf5\uc740-\uc81c\uac70\ud558\uace0-\uc2f6\uc740-\ub9c8\uc74c"},"\ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c"),(0,a.kt)("p",null,"\uc9c0\uae08\uc740 \ucd94\uac00, \uc218\uc815 2\uac00\uc9c0 \uacbd\uc6b0 \ubc16\uc5d0 \uc5c6\uc9c0\ub9cc \uc870\uae08 \ub354 \ubcf5\uc7a1\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc8fc\uc5b4\uc838\uc11c 10\uac00\uc9c0 \uacbd\uc6b0\ub85c \uc785\ub825\uc744 \ubc1b\uc73c\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c\ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc11c\ube44\uc2a4 \uacc4\uce35\uc5d0\uc11c\ub3c4 \uacc4\uce35\uc758 \ubd84\ub9ac\ub97c \uc704\ud574\uc11c \ub2e4\ub978 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uba74 20\uac1c\uc758 DTO\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ubdf0\uc5b4\uac00 \uc54c\ub824\uc900 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \ud1b5\ud574 \uc774\ub97c \ud574\uacb0\ud574\ubcf4\uc790! "),(0,a.kt)("h3",{id:"\uc911\ubcf5-\uc81c\uac70-\uc804-\ucf54\ub4dc"},"\uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc"),(0,a.kt)("p",null,"\ud604\uc7ac \ucf54\ub4dc\uc5d0\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Controller\uc640 Service\uc5d0\uc11c \uc800\uc7a5, \uc218\uc815\ud560 \ub54c \uac01\uac01\uc758 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.\n\ud604\uc7ac DTO\ub294 controller, service \ud328\ud0a4\uc9c0 \ub0b4\uc5d0 \uc788\ub294 \uac83\uc774 \uc544\ub2c8\ub77c dto\ub77c\ub294 \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\ud558\uace0 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductService\n\u251c\u2500\u2500 dto\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n")),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"\uc911\ubcf52",src:n(12314).Z,width:"1528",height:"912"})),(0,a.kt)("h3",{id:"\uc778\ud130\ud398\uc774\uc2a4-\uc791\uc131\ud558\uae30"},"\uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"\uc911\ubcf53",src:n(56531).Z,width:"1518",height:"904"})),(0,a.kt)("p",null,"\uc11c\ube44\uc2a4 \ub808\uc774\uc5b4\uc5d0\uc11c \ud544\uc694\ub85c \ud558\ub294 \uac12\ub4e4\uc744 \uc778\ud130\ud398\uc774\uc2a4\ub85c \uc815\uc758\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \uc11c\ube44\uc2a4\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 service \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub85c \uc62e\uaca8\uc900\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public interface ProductSaveRequest {\n\n String getName();\n\n String getImage();\n\n Long getPrice();\n}\n\n// ProductService\npublic Long save(final ProductSaveRequest request) {\n final Product product = new Product(request.getName(), request.getImage(), request.getPrice());\n return productDao.saveAndGetId(product);\n}\n")),(0,a.kt)("h3",{id:"\uad6c\ud604\uccb4-\uc791\uc131\ud558\uae30"},"\uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"\uc911\ubcf54",src:n(82237).Z,width:"1508",height:"896"})),(0,a.kt)("p",null,"\uc704\uc5d0\uc11c \uc791\uc131\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc791\uc131\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc694\uccad\uc740 ProductRequest \ud074\ub798\uc2a4\ub85c \ubc1b\uace0, \uc11c\ube44\uc2a4\uc5d0 \uc804\ub2ec\ud560 \ub550 \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\uc758 \uba85\uc138\ub9cc \ub9de\ucd94\uba74 \ubb38\uc81c\uc5c6\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductController\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductRequest\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n")),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {\n\n @NotBlank(message = "\uc774\ub984\uc740 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.")\n @Size(min = 1, max = 100, message = "\uc774\ub984\uc740 \ucd5c\uc18c {min}\uc790 \uc774\uc0c1, {max}\uc790 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.")\n private final String name;\n\n @NotBlank(message = "\uc774\ubbf8\uc9c0\ub294 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.")\n private final String image;\n\n @Range(message = "\uac00\uaca9\uc740 \ucd5c\uc18c {min}\uc6d0 \uc774\uc0c1, {max}\uc6d0 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.")\n private final long price;\n\n public ProductRequest(final String name, final String image, final long price) {\n this.name = name;\n this.image = image;\n this.price = price;\n }\n\n @Override\n public String getName() {\n return name;\n }\n\n @Override\n public String getImage() {\n return image;\n }\n\n @Override\n public long getPrice() {\n return price;\n }\n}\n\n// ProductController\n@PostMapping("/products")\npublic ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {\n final Long id = productService.save(request);\n return ResponseEntity.created(URI.create("/products/" + id)).build();\n}\n')),(0,a.kt)("h3",{id:"\uc815\ub9ac"},"\uc815\ub9ac"),(0,a.kt)("p",null,"\uc704\uc640 \uac19\uc774 \uad6c\ud604\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc744 \uc5bb\uc744 \uc218 \uc788\ub2e4. "),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Service\uc5d0\uc11c \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc694\uccad\uc5d0 \ub300\ud55c DTO\ub97c \uc54c\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4."),(0,a.kt)("li",{parentName:"ol"},"\uacf5\ud1b5\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 DTO\ub97c \uc81c\uc678\ud558\uace0 DTO \ud328\ud0a4\uc9c0\uc5d0 \ub300\ud55c \uacb0\ud569\ub3c4\uac00 \ub0ae\uc544\uc9c0\uace0, \uac01 \ub808\uc774\uc5b4\uc758 \uc751\uc9d1\ub3c4\uac00 \uc99d\uac00\ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ol"},"\uc694\uccad \uac1d\uccb4\ub9cc \ub2e4\ub974\uace0 \uc11c\ube44\uc2a4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ud589\uc704\ub97c \uc218\ud589\ud558\ub294 \uacbd\uc6b0 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4.")),(0,a.kt)("p",null,"\uc704 \ubc29\ubc95\uc744 \uc9c0\uae08 \ubbf8\uc158\uc5d0\uc11c \ubc14\ub85c \uc801\uc6a9\ud560\uae4c \ud558\ub2e4\uac00, \ub098\uc911\uc5d0 \ud544\uc694\ud560 \ub54c \uc801\uc6a9\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\uc544\uc11c \ubbf8\uc158\uc5d0\ub294 \uc801\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0c1\ud669\uc5d0 \ub9de\ucdb0 \uc801\uc7ac\uc801\uc18c\uc5d0 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud574\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4."),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98 16\uc7a5 \ub3c5\ub9bd\uc131, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/2647/"},"https://techblog.woowahan.com/2647/"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/"},"https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/")))}s.isMDXComponent=!0},92725:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/\uc911\ubcf51-ccd4f91674b224578f2b295b3fccaf2c.png"},12314:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/\uc911\ubcf52-0b4f9f493909fc139f0e4579f7569a6b.png"},56531:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/\uc911\ubcf53-1b6b93bc790ba29844083df5b70dbd2c.png"},82237:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/\uc911\ubcf54-15b381e0a024487f54608d438e5385f9.png"}}]); \ No newline at end of file diff --git a/assets/js/bace0b37.f928003e.js b/assets/js/bace0b37.f928003e.js new file mode 100644 index 000000000..dda77075f --- /dev/null +++ b/assets/js/bace0b37.f928003e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2362],{10795:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>o});var t=r(85893),c=r(3905);const i={title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",slug:"accidental-duplication",tags:["DTO"]},s=void 0,l={permalink:"/accidental-duplication",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",source:"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",description:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",date:"2023-05-24T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 24\uc77c",tags:[{label:"DTO",permalink:"/tags/dto"}],readingTime:7.525,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",slug:"accidental-duplication",tags:["DTO"]},unlisted:!1,prevItem:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",permalink:"/subway-retrospective"},nextItem:{title:"\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0",permalink:"/shopping-cart-retrospective"}},a={authorsImageUrls:[]},o=[{value:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815",id:"\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158\uc5d0\uc11c\uc758-\uc0c1\ud488-\ucd94\uac00-\ubc0f-\uc218\uc815",level:3},{value:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5",id:"\uc911\ubcf5\uacfc-\uc6b0\ubc1c\uc801-\uc911\ubcf5",level:3},{value:"\ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c",id:"\ud558\ub098\ub85c-\uc0ac\uc6a9\ud558\ub294-\uac74-\uc548\uc88b\uc544\ubcf4\uc774\uace0-\uc911\ubcf5\uc740-\uc81c\uac70\ud558\uace0-\uc2f6\uc740-\ub9c8\uc74c",level:3},{value:"\uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc",id:"\uc911\ubcf5-\uc81c\uac70-\uc804-\ucf54\ub4dc",level:3},{value:"\uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30",id:"\uc778\ud130\ud398\uc774\uc2a4-\uc791\uc131\ud558\uae30",level:3},{value:"\uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30",id:"\uad6c\ud604\uccb4-\uc791\uc131\ud558\uae30",level:3},{value:"\uc815\ub9ac",id:"\uc815\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",br:"br",code:"code",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,c.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc0c1\ud488 \ucd94\uac00\uc640 \uc0c1\ud488 \uc218\uc815\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc694\uccad\uc5d0 \ub2f4\uae34 Body\ub97c \ud1b5\ud574 \uc804\ub2ec\ubc1b\uc740 \uac12\uc744 DTO\ub85c \ub9e4\ud551\ud558\uc5ec \ucd94\uac00\uc640 \uc218\uc815\uc744 \ud588\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc7a5\ubc14\uad6c\ub2c8-\ubbf8\uc158\uc5d0\uc11c\uc758-\uc0c1\ud488-\ucd94\uac00-\ubc0f-\uc218\uc815",children:"\uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158\uc5d0\uc11c\uc758 \uc0c1\ud488 \ucd94\uac00 \ubc0f \uc218\uc815"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"\uc911\ubcf51",src:r(92725).Z+"",width:"2028",height:"704"})}),"\n",(0,t.jsxs)(n.p,{children:["\ud074\ub798\uc2a4\uba85\uc744 \uc81c\uc678\ud558\uace0 \ud544\ub4dc\uc640 \uac80\uc99d\ub85c\uc9c1 \uadf8 \uc678 \ubaa8\ub4e0\uac8c \uac19\uc740 DTO\ub97c \ubcf4\uba70 \uc911\ubcf5\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \ubc18\ub300\ub85c \uc6a9\ub3c4\uac00 \ub2e4\ub974\uae30 \ub54c\ubb38\uc5d0 \uc911\ubcf5\uc774 \uc544\ub2c8\ub77c\uace0 \uc0dd\uac01\ud558\uae30\ub3c4 \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc704 \uacbd\uc6b0\ub294 \uc911\ubcf5\uc77c\uae4c? \uc911\ubcf5\uc774 \uc544\ub2d0\uae4c?"]}),"\n",(0,t.jsx)(n.p,{children:"\uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ub2e4\uc74c\uacfc \uac19\uc740 \ub9ac\ubdf0\ub97c \ubc1b\uc558\ub2e4."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ProductSaveRequest"}),"\uc640 ",(0,t.jsx)(n.code,{children:"ProductUpdateRequest"}),"\uac00 \uc644\uc804\ud788 \ub3d9\uc77c\ud55c\ub370, \uc7ac\uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc744\uae4c? \ub77c\ub294 \ub9ac\ubdf0\ub97c \ub0a8\uacbc\uc5c8\uc5b4\uc694. \uc0ac\uc2e4 \uc0dd\uc131\uacfc \uc218\uc815\uc740 \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac1c\uc5f0\uc131\uc774 \ub192\uc544\uc11c \ubbf8\ub9ac \ubd84\ub9ac\ud574\ub193\ub294 \uac8c \ub354 \uc88b\uc740 \ubc29\ubc95\uc774\uae34 \ud55c\ub370, \uadf8\ub798\ub3c4 \uc911\ubcf5\uc740 \uc2eb\uc5b4\uc11c \uc800\ub3c4 \uc694\uc998 \uc774\ub7f0\uc800\ub7f0 \ubc29\ubc95\ub4e4\uc744 \uc2dc\ub3c4\ud574\ubcf4\ub294 \uc911 \uc785\ub2c8\ub2e4. \ud5c8\ube0c\ub294 \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574 \uc5b4\ub5a4 \uc0dd\uac01\uc744 \uac00\uc9c0\uace0 \uc788\uc744\uc9c0 \uad81\uae08\ud558\ub124\uc694 \u314e\u314e"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\uc9c8\ubb38\uc5d0 \ub300\ud574 \uc544\ub798\uc640 \uac19\uc774 \ub2f5\ubcc0\uc744 \ud588\ub2e4."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uc800\uc7a5\uacfc \uc218\uc815\ud560 \ub54c \ud544\uc694\ud55c \ud544\ub4dc\uac12\uc774 \ub3d9\uc77c\ud558\uc5ec \ud604\uc7ac \uad6c\uc870\uc5d0\uc11c\ub294 \ud558\ub098\ub85c \uc0ac\uc6a9\ud574\ub3c4 \ub41c\ub2e4\uace0 \uc0dd\uac01\uc744 \ud558\uc9c0\ub9cc, \ub9d0\uc500\ud574\uc8fc\uc2e0\ub300\ub85c \uc694\uad6c\uc0ac\ud56d\uc774 \ubcc0\uacbd\ub41c\ub2e4\uba74 \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\ub2e4\uace0 \ud310\ub2e8\ud558\uc600\uc2b5\ub2c8\ub2e4!"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc911\ubcf5\uacfc-\uc6b0\ubc1c\uc801-\uc911\ubcf5",children:"\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5"}),"\n",(0,t.jsx)(n.p,{children:"\ub85c\ubc84\ud2b8 \ub9c8\ud2f4\ub2d8\uc774 \uc9d1\ud544\ud558\uc2e0 \ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98\ub294 \uc544\ub798\uc640 \uac19\uc774 \uc911\ubcf5\uc744 \uc5ec\ub7ec\uac00\uc9c0 \uc885\ub958\ub85c \ub098\ub204\uc5b4 \uc124\uba85\ud558\uace0 \uc788\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc9c4\uc9dc \uc911\ubcf5: \ud55c \uc778\uc2a4\ud134\uc2a4\uac00 \ubcc0\uacbd\ub418\uba74, \ub3d9\uc77c\ud55c \ubcc0\uacbd\uc744 \uadf8 \uc778\uc2a4\ud134\uc2a4\uc758 \ubaa8\ub4dc \ubcf5\uc0ac\ubcf8\uc5d0 \ubc18\ub4dc\uc2dc \uc801\uc6a9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uac70\uc9d3\ub41c \uc911\ubcf5, \uc6b0\ubc1c\uc801 \uc911\ubcf5: \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\ub294 \ub450 \ucf54\ub4dc \uc601\uc5ed\uc774 \uac01\uc790\uc758 \uacbd\ub85c\ub85c \ubc1c\uc804\ud55c\ub2e4\uba74, \uc989 \uc11c\ub85c \ub2e4\ub978 \uc18d\ub3c4\uc640 \ub2e4\ub978 \uc774\uc720\ub85c \ubcc0\uacbd\ub41c\ub2e4\uba74 \uc774 \ub450 \ucf54\ub4dc\ub294 \uc9c4\uc9dc \uc911\ubcf5\uc774 \uc544\ub2c8\ub2e4."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\ucd94\uac00\uc640 \uc218\uc815\uc740 \ucd08\uae30\uc5d0\ub294 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc774\uc9c0\ub9cc \ucd08\uae30 \uc0dd\uc131\uc2dc\uc5d0\ub9cc \uae30\uc785\ud558\ub294 \ub370\uc774\ud130\ub4e4\uc774 \ucd94\uac00\ub418\uac70\ub098, \uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc11c\ub85c \ub2ec\ub77c\uc9c8 \uac00\ub2a5\uc131\uc774 \ub192\uc544\uc9c4\ub2e4.\n\uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc704 \uc0c1\ud669\uc740 \uc6b0\ubc1c\uc801 \uc911\ubcf5\uc73c\ub85c \ubcf4\uc778\ub2e4. \uadf8\ub798\ub3c4 \uc911\ubcf5\uc744 \uc81c\uac70\ud574\ubcfc \uc218 \uc788\uc9c0 \uc54a\uc744\uae4c?"}),"\n",(0,t.jsx)(n.h3,{id:"\ud558\ub098\ub85c-\uc0ac\uc6a9\ud558\ub294-\uac74-\uc548\uc88b\uc544\ubcf4\uc774\uace0-\uc911\ubcf5\uc740-\uc81c\uac70\ud558\uace0-\uc2f6\uc740-\ub9c8\uc74c",children:"\ud558\ub098\ub85c \uc0ac\uc6a9\ud558\ub294 \uac74 \uc548\uc88b\uc544\ubcf4\uc774\uace0, \uc911\ubcf5\uc740 \uc81c\uac70\ud558\uace0 \uc2f6\uc740 \ub9c8\uc74c"}),"\n",(0,t.jsxs)(n.p,{children:["\uc9c0\uae08\uc740 \ucd94\uac00, \uc218\uc815 2\uac00\uc9c0 \uacbd\uc6b0 \ubc16\uc5d0 \uc5c6\uc9c0\ub9cc \uc870\uae08 \ub354 \ubcf5\uc7a1\ud55c \uc694\uad6c\uc0ac\ud56d\uc774 \uc8fc\uc5b4\uc838\uc11c 10\uac00\uc9c0 \uacbd\uc6b0\ub85c \uc785\ub825\uc744 \ubc1b\uc73c\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c\ud560\uae4c?",(0,t.jsx)(n.br,{}),"\n","\uc11c\ube44\uc2a4 \uacc4\uce35\uc5d0\uc11c\ub3c4 \uacc4\uce35\uc758 \ubd84\ub9ac\ub97c \uc704\ud574\uc11c \ub2e4\ub978 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uba74 20\uac1c\uc758 DTO\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud560\uae4c?",(0,t.jsx)(n.br,{}),"\n","\ub9ac\ubdf0\uc5b4\uac00 \uc54c\ub824\uc900 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \ud1b5\ud574 \uc774\ub97c \ud574\uacb0\ud574\ubcf4\uc790!"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc911\ubcf5-\uc81c\uac70-\uc804-\ucf54\ub4dc",children:"\uc911\ubcf5 \uc81c\uac70 \uc804 \ucf54\ub4dc"}),"\n",(0,t.jsxs)(n.p,{children:["\ud604\uc7ac \ucf54\ub4dc\uc5d0\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","Controller\uc640 Service\uc5d0\uc11c \uc800\uc7a5, \uc218\uc815\ud560 \ub54c \uac01\uac01\uc758 DTO\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.\n\ud604\uc7ac DTO\ub294 controller, service \ud328\ud0a4\uc9c0 \ub0b4\uc5d0 \uc788\ub294 \uac83\uc774 \uc544\ub2c8\ub77c dto\ub77c\ub294 \ud328\ud0a4\uc9c0\uc5d0 \uc704\uce58\ud558\uace0 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductService\n\u251c\u2500\u2500 dto\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"\uc911\ubcf52",src:r(12314).Z+"",width:"1528",height:"912"})}),"\n",(0,t.jsx)(n.h3,{id:"\uc778\ud130\ud398\uc774\uc2a4-\uc791\uc131\ud558\uae30",children:"\uc778\ud130\ud398\uc774\uc2a4 \uc791\uc131\ud558\uae30"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"\uc911\ubcf53",src:r(56531).Z+"",width:"1518",height:"904"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc11c\ube44\uc2a4 \ub808\uc774\uc5b4\uc5d0\uc11c \ud544\uc694\ub85c \ud558\ub294 \uac12\ub4e4\uc744 \uc778\ud130\ud398\uc774\uc2a4\ub85c \uc815\uc758\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \uc11c\ube44\uc2a4\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 service \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub85c \uc62e\uaca8\uc900\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductController\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"public interface ProductSaveRequest {\n\n String getName();\n\n String getImage();\n\n Long getPrice();\n}\n\n// ProductService\npublic Long save(final ProductSaveRequest request) {\n final Product product = new Product(request.getName(), request.getImage(), request.getPrice());\n return productDao.saveAndGetId(product);\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\uad6c\ud604\uccb4-\uc791\uc131\ud558\uae30",children:"\uad6c\ud604\uccb4 \uc791\uc131\ud558\uae30"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"\uc911\ubcf54",src:r(82237).Z+"",width:"1508",height:"896"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc704\uc5d0\uc11c \uc791\uc131\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc791\uc131\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc694\uccad\uc740 ProductRequest \ud074\ub798\uc2a4\ub85c \ubc1b\uace0, \uc11c\ube44\uc2a4\uc5d0 \uc804\ub2ec\ud560 \ub550 \ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\uc758 \uba85\uc138\ub9cc \ub9de\ucd94\uba74 \ubb38\uc81c\uc5c6\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"\u251c\u2500\u2500 controller\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductController\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductRequest\n\u251c\u2500\u2500 service\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductService\n\u2502\xa0\xa0 \u251c\u2500\u2500 ProductSaveRequest\n\u2502\xa0\xa0 \u2514\u2500\u2500 ProductUpdateRequest\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:'public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {\n\n @NotBlank(message = "\uc774\ub984\uc740 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.")\n @Size(min = 1, max = 100, message = "\uc774\ub984\uc740 \ucd5c\uc18c {min}\uc790 \uc774\uc0c1, {max}\uc790 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.")\n private final String name;\n\n @NotBlank(message = "\uc774\ubbf8\uc9c0\ub294 \uacf5\ubc31\uc77c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.")\n private final String image;\n\n @Range(message = "\uac00\uaca9\uc740 \ucd5c\uc18c {min}\uc6d0 \uc774\uc0c1, {max}\uc6d0 \uc774\ud558\uc5ec\uc57c \ud569\ub2c8\ub2e4.")\n private final long price;\n\n public ProductRequest(final String name, final String image, final long price) {\n this.name = name;\n this.image = image;\n this.price = price;\n }\n\n @Override\n public String getName() {\n return name;\n }\n\n @Override\n public String getImage() {\n return image;\n }\n\n @Override\n public long getPrice() {\n return price;\n }\n}\n\n// ProductController\n@PostMapping("/products")\npublic ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {\n final Long id = productService.save(request);\n return ResponseEntity.created(URI.create("/products/" + id)).build();\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"\uc815\ub9ac",children:"\uc815\ub9ac"}),"\n",(0,t.jsx)(n.p,{children:"\uc704\uc640 \uac19\uc774 \uad6c\ud604\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc7a5\uc810\uc744 \uc5bb\uc744 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Service\uc5d0\uc11c \ubaa8\ub4e0 \ud074\ub77c\uc774\uc5b8\ud2b8 \uc694\uccad\uc5d0 \ub300\ud55c DTO\ub97c \uc54c\uc9c0 \uc54a\uc544\ub3c4 \ub41c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uacf5\ud1b5\uc801\uc73c\ub85c \uc0ac\uc6a9\ud558\ub294 DTO\ub97c \uc81c\uc678\ud558\uace0 DTO \ud328\ud0a4\uc9c0\uc5d0 \ub300\ud55c \uacb0\ud569\ub3c4\uac00 \ub0ae\uc544\uc9c0\uace0, \uac01 \ub808\uc774\uc5b4\uc758 \uc751\uc9d1\ub3c4\uac00 \uc99d\uac00\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uc694\uccad \uac1d\uccb4\ub9cc \ub2e4\ub974\uace0 \uc11c\ube44\uc2a4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ud589\uc704\ub97c \uc218\ud589\ud558\ub294 \uacbd\uc6b0 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\uc704 \ubc29\ubc95\uc744 \uc9c0\uae08 \ubbf8\uc158\uc5d0\uc11c \ubc14\ub85c \uc801\uc6a9\ud560\uae4c \ud558\ub2e4\uac00, \ub098\uc911\uc5d0 \ud544\uc694\ud560 \ub54c \uc801\uc6a9\ud558\uba74 \ub354 \uc88b\uc744 \uac83 \uac19\uc544\uc11c \ubbf8\uc158\uc5d0\ub294 \uc801\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc0c1\ud669\uc5d0 \ub9de\ucdb0 \uc801\uc7ac\uc801\uc18c\uc5d0 \uc758\uc874 \uc5ed\uc804\uc744 \uc774\uc6a9\ud574\ubcf4\ub294 \uac83\ub3c4 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:["\ud074\ub9b0 \uc544\ud0a4\ud14d\ucc98 16\uc7a5 \ub3c5\ub9bd\uc131, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://techblog.woowahan.com/2647/",children:"https://techblog.woowahan.com/2647/"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/",children:"https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/"})]})]})}function u(e={}){const{wrapper:n}={...(0,c.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>o});var t=r(67294);function c(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){c(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function l(e,n){if(null==e)return{};var r,t,c=function(e,n){if(null==e)return{};var r,t,c={},i=Object.keys(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||(c[r]=e[r]);return c}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var a=t.createContext({}),o=function(e){var n=t.useContext(a),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},u=t.forwardRef((function(e,n){var r=e.components,c=e.mdxType,i=e.originalType,a=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),p=o(r),h=c,g=p["".concat(a,".").concat(h)]||p[h]||d[h]||i;return r?t.createElement(g,s(s({ref:n},u),{},{components:r})):t.createElement(g,s({ref:n},u))}));u.displayName="MDXCreateElement"},92725:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/\uc911\ubcf51-ccd4f91674b224578f2b295b3fccaf2c.png"},12314:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/\uc911\ubcf52-0b4f9f493909fc139f0e4579f7569a6b.png"},56531:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/\uc911\ubcf53-1b6b93bc790ba29844083df5b70dbd2c.png"},82237:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/\uc911\ubcf54-15b381e0a024487f54608d438e5385f9.png"}}]); \ No newline at end of file diff --git a/assets/js/bb221eab.15e3f1c0.js b/assets/js/bb221eab.15e3f1c0.js new file mode 100644 index 000000000..14ef885b4 --- /dev/null +++ b/assets/js/bb221eab.15e3f1c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[711],{98886:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>o});var r=n(85893),s=n(3905);const i={title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",slug:"test-double",tags:["Test","Mock"]},l=void 0,c={permalink:"/test-double",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",source:"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",description:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?",date:"2023-04-04T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 4\uc77c",tags:[{label:"Test",permalink:"/tags/test"},{label:"Mock",permalink:"/tags/mock"}],readingTime:4.52,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",slug:"test-double",tags:["Test","Mock"]},unlisted:!1,prevItem:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",permalink:"/transaction-and-isolation"},nextItem:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",permalink:"/java-class-file"}},d={authorsImageUrls:[]},o=[{value:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?",id:"\ud14c\uc2a4\ud2b8-\ub300\uc5ed\uc774\ub780",level:3},{value:"\ub354\ubbf8(Dummy)",id:"\ub354\ubbf8dummy",level:3},{value:"\uc2a4\ud141(Stub)",id:"\uc2a4\ud141stub",level:3},{value:"\uc2a4\ud30c\uc774(Spy)",id:"\uc2a4\ud30c\uc774spy",level:3},{value:"\ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)",id:"\ubaa9-\ubaa8\uc758-\uac1d\uccb4mock",level:3},{value:"\uac00\uc9dc(Fake)",id:"\uac00\uc9dcfake",level:3},{value:"\uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84",id:"\uc0c1\ud638\uc791\uc6a9\uc5d0-\ub530\ub978-\ubaa9\uacfc-\uc2a4\ud141-\uad6c\ubd84",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function a(e){const t={a:"a",admonition:"admonition",br:"br",h3:"h3",mermaid:"mermaid",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"\ud14c\uc2a4\ud2b8-\ub300\uc5ed\uc774\ub780",children:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?"}),"\n",(0,r.jsxs)(t.p,{children:["\ubaa8\ub4e0 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \uac00\uc9dc \uc758\uc874\uc131\uc744 \uc758\ubbf8\ud558\uace0, \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud589\ub420 \ub54c \ub2e4\ub978 \uac1d\uccb4\ub97c \ub300\uc2e0\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","Gerard Meszaros\uc758 xUnit Test Patterns\ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ub2e4\uc12f \uac00\uc9c0(\ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774, \ubaa9, \ud398\uc774\ud06c)\ub85c \uad6c\ubd84\ud55c\ub2e4."]}),"\n",(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \uae30\ubcf8 \uba54\ucee4\ub2c8\uc998\uc740 \ub2e4\ud615\uc131\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc678\ubd80 \uc11c\ube44\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uacbd\uc6b0, \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc815\uc758\ud558\uace0 \uc678\ubd80 \uc11c\ube44\uc2a4 \ub300\uc2e0 \ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\uc758 \uad6c\ud604\uccb4\ub97c \uc0dd\uc131\ud558\ub294 \uac83\uc774\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.strong,{children:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \ud0c0\uc785 \uacc4\uce35 \uad6c\uc870"})}),"\n",(0,r.jsx)(t.mermaid,{value:"flowchart LR\n Mock --\x3e Spy --\x3e Stub --\x3e Dummy --\x3e TestDouble\n Fake --\x3e TestDouble"}),"\n",(0,r.jsx)(t.h3,{id:"\ub354\ubbf8dummy",children:"\ub354\ubbf8(Dummy)"}),"\n",(0,r.jsxs)(t.p,{children:["\uac00\uc7a5 \ub2e8\uc21c\ud558\uace0, \uc6d0\uc2dc\uc801\uc778 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c \uc544\ubb34 \uc77c\ub3c4 \ud558\uc9c0 \uc54a\ub294 \uad6c\ud604\uccb4\ub85c \uc778\uc2a4\ud134\uc2a4\ud654\uac00 \ud544\uc694\ud55c \uacbd\uc6b0 \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub9cc\uc57d \uba54\uc11c\ub4dc\uac00 \ubb34\uc5b8\uac00 \ubc18\ud658\uc744 \ud574\uc57c\ud558\ub294 \uacbd\uc6b0 0, null\uacfc \uac19\uc740 \uac12\uc744 \ubc18\ud658\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ud141stub",children:"\uc2a4\ud141(Stub)"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2dc\ub098\ub9ac\uc624\ub9c8\ub2e4 \ub2e4\ub978 \uac12(\ubbf8\ub9ac \uc900\ube44 \ub41c \uacb0\uacfc)\uc744 \ubc18\ud658\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub97c \ud1b5\ud574 \ud2b9\uc815 \uc870\uac74\uc5d0\uc11c \uba54\uc11c\ub4dc\uac00 \uc608\uc0c1\ud55c\ub300\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uc2a4\ud30c\uc774spy",children:"\uc2a4\ud30c\uc774(Spy)"}),"\n",(0,r.jsxs)(t.p,{children:["\uc2a4\ud141\uacfc \uc720\uc0ac\ud558\uc9c0\ub9cc \ud638\ucd9c \uc5ec\ubd80\ub97c \uae30\ub85d\ud558\uac70\ub098 \ud638\ucd9c\ud560 \ub54c \uc804\ub2ec\ud55c \uc778\uc790\uac12\uc744 \uae30\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc608) \uba54\uc77c \uc804\uc1a1 \uae30\ub2a5\uc744 \uac00\uc9c4 \uac1d\uccb4\ub97c \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc73c\ub85c \uad6c\ud604\ud588\uc744 \ub54c \uba54\uc77c \uc804\uc1a1 \ud69f\uc218\ub97c \uae30\ub85d\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ubaa9-\ubaa8\uc758-\uac1d\uccb4mock",children:"\ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)"}),"\n",(0,r.jsxs)(t.p,{children:["\ubaa9\uc740 \ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774\ub97c \ud3ec\ud568\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud638\ucd9c \uc2dc \uc0ac\uc804\uc5d0 \uc815\uc758\ub41c \uacb0\uacfc\ub97c \ubc18\ud658\ud558\uace0, \uc608\uc0c1\uce58 \ubabb\ud55c \ud638\ucd9c\uc774 \uc788\uc744 \uacbd\uc6b0 \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub610\ud55c \ud638\ucd9c\uc5d0 \ub300\ud55c \uac80\uc99d\uc744 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uac00\uc9dcfake",children:"\uac00\uc9dc(Fake)"}),"\n",(0,r.jsxs)(t.p,{children:["DOC\uc640 \ub3d9\uc77c\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\uc9c0\ub9cc, \ub354\uc6b1 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ub41c \uac83\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc608) \uc2e4\uc81c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc720\uc0ac\ud558\uac8c \ub3d9\uc791\ud558\ub294 \uac00\uc9dc \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.admonition,{title:"DOC(depended-on component)",type:"note",children:(0,r.jsxs)(t.p,{children:["\uc758\uc874 \uad6c\uc131 \uc694\uc18c, DOC\ub97c \ud14c\uc2a4\ud2b8 \ub354\ube14\ub85c \ub300\uccb4\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ud14c\uc2a4\ud2b8 \ub354\ube14\uc740 DOC\uc640 \ub3d9\uc77c\ud55c API\ub97c \uc81c\uacf5\ud574\uc57c \ud55c\ub2e4."]})}),"\n",(0,r.jsx)(t.h3,{id:"\uc0c1\ud638\uc791\uc6a9\uc5d0-\ub530\ub978-\ubaa9\uacfc-\uc2a4\ud141-\uad6c\ubd84",children:"\uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84"}),"\n",(0,r.jsxs)(t.p,{children:["\ub2e8\uc704 \ud14c\uc2a4\ud2b8 p.149 \uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ud06c\uac8c \ubaa9\uacfc \uc2a4\ud141\uc73c\ub85c \uad6c\ubd84\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ubaa9\uc740 SUT\uc640 \uad00\ub828\ub41c \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ubc18\uba74, \uc2a4\ud141\uc740 \ub2e8\uc21c \ubaa8\ubc29\ub9cc \ud55c\ub2e4."]}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"TestDouble"}),(0,r.jsx)(t.th,{children:"Mock"}),(0,r.jsx)(t.th,{children:"Stub"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"\ud3ec\ud568 \uc720\ud615"}),(0,r.jsx)(t.td,{children:"\ubaa9, \uc2a4\ud30c\uc774"}),(0,r.jsx)(t.td,{children:"\uc2a4\ud141, \ub354\ubbf8, \ud398\uc774\ud06c"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"\uc6a9\ub3c4"}),(0,r.jsx)(t.td,{children:"\uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ub370 \uc0ac\uc6a9"}),(0,r.jsx)(t.td,{children:"\ub0b4\ubd80\ub85c \ub4e4\uc5b4\uc624\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\ub294 \ub370 \uc0ac\uc6a9"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"\uc124\uba85"}),(0,r.jsx)(t.td,{children:"SUT\uac00 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9"}),(0,r.jsx)(t.td,{children:"SUT\uac00 \uc785\ub825 \ub370\uc774\ud130\ub97c \uc5bb\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"\uc608\uc2dc"}),(0,r.jsx)(t.td,{children:"\uc774\uba54\uc77c \ubc1c\uc1a1"}),(0,r.jsx)(t.td,{children:"\ub370\uc774\ud130 \uac80\uc0c9"})]})]})]}),"\n",(0,r.jsx)(t.admonition,{title:"SUT(system under test)",type:"note",children:(0,r.jsxs)(t.p,{children:["\ud14c\uc2a4\ud2b8 \ub300\uc0c1 \uc2dc\uc2a4\ud15c",(0,r.jsx)(t.br,{}),"\n","\ud14c\uc2a4\ud2b8\ub97c \ud558\ub824\ub294 \ub300\uc0c1"]})}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:["\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30 - 3\uc7a5 \uace0\uae09 \ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4",(0,r.jsx)(t.br,{}),"\n","\ub2e8\uc704 \ud14c\uc2a4\ud2b8 - 5\uc7a5 \ubaa9\uacfc \ud14c\uc2a4\ud2b8 \ucde8\uc57d\uc131, \ube14\ub77c\ub514\ubbf8\ub974 \ucf54\ub9ac\ucf54\ud504",(0,r.jsx)(t.br,{}),"\n","\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uc2dc\uc791\ud558\uae30 - 7\uc7a5 \ub300\uc5ed, \ucd5c\ubc94\uade0",(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://www.martinfowler.com/bliki/TestDouble.html",children:"\ud14c\uc2a4\ud2b8 \ub354\ube14, Martin Fowler"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://johngrib.github.io/wiki/test-terms/",children:"\ud14c\uc2a4\ud2b8 \uad00\ub828 \uc6a9\uc5b4 \uc815\ub9ac, Johngrib"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"http://xunitpatterns.com/Test%20Double.html",children:"Test Double, Gerard Meszaros"})]})]})}function h(e={}){const{wrapper:t}={...(0,s.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>o});var r=n(67294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){s(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,r,s=function(e,t){if(null==e)return{};var n,r,s={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var d=r.createContext({}),o=function(e){var t=r.useContext(d),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},a={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,i=e.originalType,d=e.parentName,h=c(e,["components","mdxType","originalType","parentName"]),j=o(n),x=s,u=j["".concat(d,".").concat(x)]||j[x]||a[x]||i;return n?r.createElement(u,l(l({ref:t},h),{},{components:n})):r.createElement(u,l({ref:t},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/bb221eab.ee80a616.js b/assets/js/bb221eab.ee80a616.js deleted file mode 100644 index 05fe8d73a..000000000 --- a/assets/js/bb221eab.ee80a616.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[711],{3905:(t,e,n)=>{n.d(e,{Zo:()=>u,kt:()=>c});var r=n(67294);function a(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}function l(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function p(t){for(var e=1;e<arguments.length;e++){var n=null!=arguments[e]?arguments[e]:{};e%2?l(Object(n),!0).forEach((function(e){a(t,e,n[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(n,e))}))}return t}function o(t,e){if(null==t)return{};var n,r,a=function(t,e){if(null==t)return{};var n,r,a={},l=Object.keys(t);for(r=0;r<l.length;r++)n=l[r],e.indexOf(n)>=0||(a[n]=t[n]);return a}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(r=0;r<l.length;r++)n=l[r],e.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(t,n)&&(a[n]=t[n])}return a}var i=r.createContext({}),m=function(t){var e=r.useContext(i),n=e;return t&&(n="function"==typeof t?t(e):p(p({},e),t)),n},u=function(t){var e=m(t.components);return r.createElement(i.Provider,{value:e},t.children)},k={inlineCode:"code",wrapper:function(t){var e=t.children;return r.createElement(r.Fragment,{},e)}},s=r.forwardRef((function(t,e){var n=t.components,a=t.mdxType,l=t.originalType,i=t.parentName,u=o(t,["components","mdxType","originalType","parentName"]),s=m(n),c=a,d=s["".concat(i,".").concat(c)]||s[c]||k[c]||l;return n?r.createElement(d,p(p({ref:e},u),{},{components:n})):r.createElement(d,p({ref:e},u))}));function c(t,e){var n=arguments,a=e&&e.mdxType;if("string"==typeof t||a){var l=n.length,p=new Array(l);p[0]=s;var o={};for(var i in e)hasOwnProperty.call(e,i)&&(o[i]=e[i]);o.originalType=t,o.mdxType="string"==typeof t?t:a,p[1]=o;for(var m=2;m<l;m++)p[m]=n[m];return r.createElement.apply(null,p)}return r.createElement.apply(null,n)}s.displayName="MDXCreateElement"},59165:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>i,contentTitle:()=>p,default:()=>k,frontMatter:()=>l,metadata:()=>o,toc:()=>m});var r=n(87462),a=(n(67294),n(3905));const l={title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",slug:"test-double",tags:["Test","Mock"]},p=void 0,o={permalink:"/test-double",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",source:"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",description:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?",date:"2023-04-04T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 4\uc77c",tags:[{label:"Test",permalink:"/tags/test"},{label:"Mock",permalink:"/tags/mock"}],readingTime:4.52,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",slug:"test-double",tags:["Test","Mock"]},prevItem:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",permalink:"/transaction-and-isolation"},nextItem:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",permalink:"/java-class-file"}},i={authorsImageUrls:[]},m=[{value:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?",id:"\ud14c\uc2a4\ud2b8-\ub300\uc5ed\uc774\ub780",level:3},{value:"\ub354\ubbf8(Dummy)",id:"\ub354\ubbf8dummy",level:3},{value:"\uc2a4\ud141(Stub)",id:"\uc2a4\ud141stub",level:3},{value:"\uc2a4\ud30c\uc774(Spy)",id:"\uc2a4\ud30c\uc774spy",level:3},{value:"\ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)",id:"\ubaa9-\ubaa8\uc758-\uac1d\uccb4mock",level:3},{value:"\uac00\uc9dc(Fake)",id:"\uac00\uc9dcfake",level:3},{value:"\uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84",id:"\uc0c1\ud638\uc791\uc6a9\uc5d0-\ub530\ub978-\ubaa9\uacfc-\uc2a4\ud141-\uad6c\ubd84",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:m};function k(t){let{components:e,...n}=t;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:e,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ud14c\uc2a4\ud2b8-\ub300\uc5ed\uc774\ub780"},"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub780?"),(0,a.kt)("p",null,"\ubaa8\ub4e0 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8\ub97c \uc704\ud55c \uac00\uc9dc \uc758\uc874\uc131\uc744 \uc758\ubbf8\ud558\uace0, \ud14c\uc2a4\ud2b8\uac00 \uc2e4\ud589\ub420 \ub54c \ub2e4\ub978 \uac1d\uccb4\ub97c \ub300\uc2e0\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Gerard Meszaros\uc758 xUnit Test Patterns\ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ub2e4\uc12f \uac00\uc9c0(\ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774, \ubaa9, \ud398\uc774\ud06c)\ub85c \uad6c\ubd84\ud55c\ub2e4."),(0,a.kt)("p",null,"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \uae30\ubcf8 \uba54\ucee4\ub2c8\uc998\uc740 \ub2e4\ud615\uc131\uc744 \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc678\ubd80 \uc11c\ube44\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ucf54\ub4dc\ub97c \ud14c\uc2a4\ud2b8 \ud558\ub294 \uacbd\uc6b0, \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc815\uc758\ud558\uace0 \uc678\ubd80 \uc11c\ube44\uc2a4 \ub300\uc2e0 \ud14c\uc2a4\ud2b8 \uc6a9\ub3c4\uc758 \uad6c\ud604\uccb4\ub97c \uc0dd\uc131\ud558\ub294 \uac83\uc774\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc758 \ud0c0\uc785 \uacc4\uce35 \uad6c\uc870")),(0,a.kt)("mermaid",{value:"flowchart LR\n Mock --\x3e Spy --\x3e Stub --\x3e Dummy --\x3e TestDouble\n Fake --\x3e TestDouble"}),(0,a.kt)("h3",{id:"\ub354\ubbf8dummy"},"\ub354\ubbf8(Dummy)"),(0,a.kt)("p",null,"\uac00\uc7a5 \ub2e8\uc21c\ud558\uace0, \uc6d0\uc2dc\uc801\uc778 \uc720\ud615\uc758 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ubcf8\uc801\uc73c\ub85c \uc544\ubb34 \uc77c\ub3c4 \ud558\uc9c0 \uc54a\ub294 \uad6c\ud604\uccb4\ub85c \uc778\uc2a4\ud134\uc2a4\ud654\uac00 \ud544\uc694\ud55c \uacbd\uc6b0 \uc0ac\uc6a9\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9cc\uc57d \uba54\uc11c\ub4dc\uac00 \ubb34\uc5b8\uac00 \ubc18\ud658\uc744 \ud574\uc57c\ud558\ub294 \uacbd\uc6b0 0, null\uacfc \uac19\uc740 \uac12\uc744 \ubc18\ud658\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc2a4\ud141stub"},"\uc2a4\ud141(Stub)"),(0,a.kt)("p",null,"\uc2dc\ub098\ub9ac\uc624\ub9c8\ub2e4 \ub2e4\ub978 \uac12(\ubbf8\ub9ac \uc900\ube44 \ub41c \uacb0\uacfc)\uc744 \ubc18\ud658\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c \ud1b5\ud574 \ud2b9\uc815 \uc870\uac74\uc5d0\uc11c \uba54\uc11c\ub4dc\uac00 \uc608\uc0c1\ud55c\ub300\ub85c \ub3d9\uc791\ud558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\uc2a4\ud30c\uc774spy"},"\uc2a4\ud30c\uc774(Spy)"),(0,a.kt)("p",null,"\uc2a4\ud141\uacfc \uc720\uc0ac\ud558\uc9c0\ub9cc \ud638\ucd9c \uc5ec\ubd80\ub97c \uae30\ub85d\ud558\uac70\ub098 \ud638\ucd9c\ud560 \ub54c \uc804\ub2ec\ud55c \uc778\uc790\uac12\uc744 \uae30\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608) \uba54\uc77c \uc804\uc1a1 \uae30\ub2a5\uc744 \uac00\uc9c4 \uac1d\uccb4\ub97c \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc73c\ub85c \uad6c\ud604\ud588\uc744 \ub54c \uba54\uc77c \uc804\uc1a1 \ud69f\uc218\ub97c \uae30\ub85d\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ubaa9-\ubaa8\uc758-\uac1d\uccb4mock"},"\ubaa9, \ubaa8\uc758 \uac1d\uccb4(Mock)"),(0,a.kt)("p",null,"\ubaa9\uc740 \ub354\ubbf8, \uc2a4\ud141, \uc2a4\ud30c\uc774\ub97c \ud3ec\ud568\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud638\ucd9c \uc2dc \uc0ac\uc804\uc5d0 \uc815\uc758\ub41c \uacb0\uacfc\ub97c \ubc18\ud658\ud558\uace0, \uc608\uc0c1\uce58 \ubabb\ud55c \ud638\ucd9c\uc774 \uc788\uc744 \uacbd\uc6b0 \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ud638\ucd9c\uc5d0 \ub300\ud55c \uac80\uc99d\uc744 \ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\uac00\uc9dcfake"},"\uac00\uc9dc(Fake)"),(0,a.kt)("p",null,"DOC\uc640 \ub3d9\uc77c\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\uc9c0\ub9cc, \ub354\uc6b1 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ub41c \uac83\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608) \uc2e4\uc81c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc640 \uc720\uc0ac\ud558\uac8c \ub3d9\uc791\ud558\ub294 \uac00\uc9dc \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4 \ud14c\uc2a4\ud2b8\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("admonition",{title:"DOC(depended-on component)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\uc758\uc874 \uad6c\uc131 \uc694\uc18c, DOC\ub97c \ud14c\uc2a4\ud2b8 \ub354\ube14\ub85c \ub300\uccb4\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc2a4\ud2b8 \ub354\ube14\uc740 DOC\uc640 \ub3d9\uc77c\ud55c API\ub97c \uc81c\uacf5\ud574\uc57c \ud55c\ub2e4. ")),(0,a.kt)("h3",{id:"\uc0c1\ud638\uc791\uc6a9\uc5d0-\ub530\ub978-\ubaa9\uacfc-\uc2a4\ud141-\uad6c\ubd84"},"\uc0c1\ud638\uc791\uc6a9\uc5d0 \ub530\ub978 \ubaa9\uacfc \uc2a4\ud141 \uad6c\ubd84"),(0,a.kt)("p",null,"\ub2e8\uc704 \ud14c\uc2a4\ud2b8 p.149 \uc5d0\uc11c\ub294 \ud14c\uc2a4\ud2b8 \ub300\uc5ed\uc744 \ud06c\uac8c \ubaa9\uacfc \uc2a4\ud141\uc73c\ub85c \uad6c\ubd84\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubaa9\uc740 SUT\uc640 \uad00\ub828\ub41c \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ubc18\uba74, \uc2a4\ud141\uc740 \ub2e8\uc21c \ubaa8\ubc29\ub9cc \ud55c\ub2e4. "),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"TestDouble"),(0,a.kt)("th",{parentName:"tr",align:null},"Mock"),(0,a.kt)("th",{parentName:"tr",align:null},"Stub"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\ud3ec\ud568 \uc720\ud615"),(0,a.kt)("td",{parentName:"tr",align:null},"\ubaa9, \uc2a4\ud30c\uc774"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc2a4\ud141, \ub354\ubbf8, \ud398\uc774\ud06c")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc6a9\ub3c4"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc678\ubd80\ub85c \ub098\uac00\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\uace0 \uac80\uc0ac\ud558\ub294 \ub370 \uc0ac\uc6a9"),(0,a.kt)("td",{parentName:"tr",align:null},"\ub0b4\ubd80\ub85c \ub4e4\uc5b4\uc624\ub294 \uc0c1\ud638\uc791\uc6a9\uc744 \ubaa8\ubc29\ud558\ub294 \ub370 \uc0ac\uc6a9")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc124\uba85"),(0,a.kt)("td",{parentName:"tr",align:null},"SUT\uac00 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9"),(0,a.kt)("td",{parentName:"tr",align:null},"SUT\uac00 \uc785\ub825 \ub370\uc774\ud130\ub97c \uc5bb\uae30 \uc704\ud55c \uc758\uc874\uc131\uc744 \ud638\ucd9c\ud558\ub294 \uac83\uc5d0 \ud574\ub2f9")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"\uc608\uc2dc"),(0,a.kt)("td",{parentName:"tr",align:null},"\uc774\uba54\uc77c \ubc1c\uc1a1"),(0,a.kt)("td",{parentName:"tr",align:null},"\ub370\uc774\ud130 \uac80\uc0c9")))),(0,a.kt)("admonition",{title:"SUT(system under test)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ud14c\uc2a4\ud2b8 \ub300\uc0c1 \uc2dc\uc2a4\ud15c",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc2a4\ud2b8\ub97c \ud558\ub824\ub294 \ub300\uc0c1")),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc7a5\uc778 \uc815\uc2e0 \uc774\uc57c\uae30 - 3\uc7a5 \uace0\uae09 \ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c, \ub85c\ubc84\ud2b8 C. \ub9c8\ud2f4",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc704 \ud14c\uc2a4\ud2b8 - 5\uc7a5 \ubaa9\uacfc \ud14c\uc2a4\ud2b8 \ucde8\uc57d\uc131, \ube14\ub77c\ub514\ubbf8\ub974 \ucf54\ub9ac\ucf54\ud504",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uc2dc\uc791\ud558\uae30 - 7\uc7a5 \ub300\uc5ed, \ucd5c\ubc94\uade0",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.martinfowler.com/bliki/TestDouble.html"},"\ud14c\uc2a4\ud2b8 \ub354\ube14, Martin Fowler"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://johngrib.github.io/wiki/test-terms/"},"\ud14c\uc2a4\ud2b8 \uad00\ub828 \uc6a9\uc5b4 \uc815\ub9ac, Johngrib"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"http://xunitpatterns.com/Test%20Double.html"},"Test Double, Gerard Meszaros")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bbc01ba0.8021a974.js b/assets/js/bbc01ba0.cdcbe419.js similarity index 81% rename from assets/js/bbc01ba0.8021a974.js rename to assets/js/bbc01ba0.cdcbe419.js index e29c0b67d..e09cebe67 100644 --- a/assets/js/bbc01ba0.8021a974.js +++ b/assets/js/bbc01ba0.cdcbe419.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3009],{12333:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3009],{12333:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/bbdd7e52.3be218d1.js b/assets/js/bbdd7e52.3be218d1.js new file mode 100644 index 000000000..711750f79 --- /dev/null +++ b/assets/js/bbdd7e52.3be218d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3396],{49725:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var n=r(85893),c=r(3905);const s={title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",slug:"tecochat-retrospective-3",tags:["TecoChat","Retrospective"]},i=void 0,a={permalink:"/tecochat-retrospective-3",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",source:"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",description:"\uac1c\uc694",date:"2023-06-01T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 1\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.005,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",slug:"tecochat-retrospective-3",tags:["TecoChat","Retrospective"]},unlisted:!1,prevItem:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",permalink:"/order-retrospective"},nextItem:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",permalink:"/composite"}},o={authorsImageUrls:[]},l=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5",id:"\ub098\uc758-\ucc44\ud305-\ud655\uc778\ud558\uace0-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",level:3},{value:"\uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5",id:"\uc88b\uc544\uc694\uc640-\ub313\uae00-\uae30\ub2a5",level:3},{value:"\ud0a4\uc6cc\ub4dc \ucd94\ucd9c",id:"\ud0a4\uc6cc\ub4dc-\ucd94\ucd9c",level:3},{value:"\ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5",id:"\ub2e4\ub978-\ud06c\ub8e8\uc758-\ucc44\ud305-\ubcf5\uc0ac\ud574\uc11c-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",level:3},{value:"\uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30",id:"\uc0ac\uc6a9\uc131-\uace0\ub824\ud558\uae30",level:3},{value:"\ud5a5\ud6c4 \uacc4\ud68d",id:"\ud5a5\ud6c4-\uacc4\ud68d",level:3}];function p(e){const t={br:"br",code:"code",h3:"h3",img:"img",p:"p",...(0,c.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,n.jsxs)(t.p,{children:["\uc6d0\ub798 \ubaa9\uc801\uc778 ",(0,n.jsx)(t.code,{children:"\ud06c\ub8e8\ub4e4\uc758 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0"}),"\uc744 \uc8fc\uae30 \uc704\ud574 \uc5b4\ub5a4 \uae30\ub2a5\uc744 \ucd94\uac00\ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub808\ubca8 2\uac00 \uac70\uc758 \ub05d\ub098\uac00\ub294 \uc2dc\uc810, \uadf8\ub3d9\uc548 \ud588\ub358 \uac83\uc744 \uc815\ub9ac\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ub098\uc758-\ucc44\ud305-\ud655\uc778\ud558\uace0-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",children:"\ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5"}),"\n",(0,n.jsxs)(t.p,{children:["GPT\uc5d0\ub3c4 \uc788\ub294 \uae30\ub2a5\uc778\ub370, \ub0b4\uac00 \uc774\uc804\uc5d0 \ud588\ub358 \ucc44\ud305\uc744 \uc774\uc5b4\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc608\uc804\uc5d0 \uc5b4\ub5a4 \uc9c8\ubb38\uc744 \ub0a8\uacbc\ub294\uc9c0, \ub610\ud55c \ud574\ub2f9 \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"chat1",src:r(49483).Z+"",width:"2878",height:"1316"})}),"\n",(0,n.jsx)(t.h3,{id:"\uc88b\uc544\uc694\uc640-\ub313\uae00-\uae30\ub2a5",children:"\uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5"}),"\n",(0,n.jsxs)(t.p,{children:["\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc5d0 \ubc18\uc751\ud560 \uc218 \uc788\ub294 \ubb34\uc5b8\uac00\uac00 \uc788\uc5c8\uc73c\uba74 \uc88b\uaca0\ub2e4\ub294 \uc758\uacac\ub4e4\uc774 \ub9ce\uc558\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub204\uac00 \uc88b\uc544\uc694\ub97c \ub20c\ub800\ub294\uc9c0, \uc5b4\ub5a4 \ucc44\ud305\uc774 \uc88b\uc544\uc694\ub97c \uac00\uc7a5 \ub9ce\uc774 \ubc1b\uc558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ub610\ud55c \ub313\uae00 \ucd94\uac00 \ubc0f \uc0ad\uc81c \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ud0a4\uc6cc\ub4dc-\ucd94\ucd9c",children:"\ud0a4\uc6cc\ub4dc \ucd94\ucd9c"}),"\n",(0,n.jsxs)(t.p,{children:["\uc5b4\ub5bb\uac8c \ud0a4\uc6cc\ub4dc \ucd94\ucd9c\uc744 \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub294\ub370, \uc77c\ub2e8 GPT\ub97c \uc774\uc6a9\ud574\uc11c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\uae30\ub85c \ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud574\ub2f9 \ubd80\ubd84\uc740 \uccab \uc9c8\ubb38\uc5d0 \ub300\ud55c \ud0a4\uc6cc\ub4dc\ub9cc \ucd94\ucd9c\ud558\ub3c4\ub85d \ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ubc31\uc5d4\ub4dc\uc5d0\uc120 \ub9d0\ub791\uc774 \uc774\ubca4\ud2b8 \uc774\uc6a9\ud574\uc11c \uccab \ucc44\ud305 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c0\uba74, \ube44\ub3d9\uae30\ub85c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\ub294 \uc9c8\ubb38\uc744 \ucd94\uac00\ub85c \ub0a0\ub9ac\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4.",(0,n.jsx)(t.br,{}),"\n","CSV \ud615\uc2dd\uc73c\ub85c GPT\uc5d0\uac8c \ub2f5\ubcc0\uc744 \uc785\ub825\ud574\ub2ec\ub77c\uace0 \uc694\uccad\ubc1b\ub294\ub370, \uc774 \ubd80\ubd84\uc774 \ubb38\uc81c(\ud504\ub86c\ud504\ud2b8 \uc5d4\uc9c0\ub2c8\uc5b4\ub9c1 \ubd80\ubd84\uc774 \ubc18\ud658\ub41c\ub2e4.)\uac00 \uc880 \uc788\ub294 \uac83 \uac19\uc544\uc11c \uac1c\uc120\uc774 \ud544\uc694\ud55c \uac83 \uac19\ub2e4."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"chat2",src:r(50885).Z+"",width:"2394",height:"1048"})}),"\n",(0,n.jsx)(t.h3,{id:"\ub2e4\ub978-\ud06c\ub8e8\uc758-\ucc44\ud305-\ubcf5\uc0ac\ud574\uc11c-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",children:"\ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5"}),"\n",(0,n.jsxs)(t.p,{children:["\ub2e4\ub978 \ud06c\ub8e8\ub4e4\uc758 \ucc44\ud305\uc744 \uc77d\ub2e4\uac00 \uad81\uae08\ud55c \uc810\uc774 \uc788\ub2e4\uba74 \ubcf5\uc0ac\ud574\uc11c \ubc14\ub85c \uc9c8\ubb38\uc744 \ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ucc44\ud305\uc774 \ubcf5\uc0ac\ub41c \ud6c4 \ubc14\ub85c GPT\uc640 \ub300\ud654\ub97c \ud560 \uc218 \uc788\ub294 \uba54\uc778 \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\uc0ac\uc6a9\uc131-\uace0\ub824\ud558\uae30",children:"\uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"chat3",src:r(15153).Z+"",width:"1668",height:"718"})}),"\n",(0,n.jsxs)(t.p,{children:["\uc704 \ud654\uba74\uc740 \ud68c\uc6d0\uac00\uc785 \ucc3d\uc774\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc0ac\uc2e4 \uac00\uc7a5 \ub9c8\uc74c\uc5d0 \ub4dc\ub294 \ubd80\ubd84\uc774\uace0, \ud68c\uc6d0\uac00\uc785(\ub2c9\ub124\uc784\ub9cc \uc785\ub825\ud558\uc9c0\ub9cc)\ud560 \ub54c \uc775\uba85\uc744 \uc6d0\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uace0\ubbfc\uc744 \ub3c4\uc640\uc8fc\uac8c \ub054 \uc74c\uc2dd, \uacfc\uc77c, \uacfc\uc790 \ub4f1\uc758 \uc694\uc18c\ub4e4\uc744 \uc785\ub825\ud558\ub3c4\ub85d \uc720\ub3c4\ud588\ub2e4!\n\ucd94\uac00\ub85c GPT\uc758 \ub2f5\ubcc0\uc774 \uc624\uba74 \uc790\ub3d9\uc73c\ub85c \ud654\uba74\uc744 \uc2a4\ud06c\ub864 \ud574\uc8fc\ub294 \uac83\uacfc \uac19\uc774 \uc0ac\uc6a9\uc131\uc744 \uac1c\uc120\ud574 \ubcf4\ub824\uace0 \ub178\ub825\ud588\uc9c0\ub9cc \uc27d\uc9c0 \uc54a\uc558\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc81c\uc77c \ud558\uace0 \uc2f6\uc740 \uac83\uc740 \uc2e4\uc81c GPT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ucc98\ub7fc stream/text \uac12\uc744 \ucc98\ub9ac\ud558\uace0 \uc2f6\uc740\ub370 \uc774 \ubd80\ubd84\uc740 \ubc29\ud559 \ub54c \uae30\ud68c\uac00 \ub418\uba74 \ub3c4\uc804\ud574 \ubd10\uc57c\uaca0\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ud5a5\ud6c4-\uacc4\ud68d",children:"\ud5a5\ud6c4 \uacc4\ud68d"}),"\n",(0,n.jsxs)(t.p,{children:["\uc2e4\uc81c \ud06c\ub8e8\ub4e4\uc774 \uc0ac\uc6a9\ud574 \uc8fc\ub294 \uc11c\ube44\uc2a4\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\ubcf4\uba74\uc11c \uc0ac\uc6a9\uc790\uc758 \uc785\uc7a5\uc5d0\uc11c \uace0\ubbfc\ub3c4 \ud558\uac8c \ub418\ub294 \uac83 \uac19\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ud06c\ub8e8\ub4e4\uc774 \uc9c1\uc811 \uc0ac\uc6a9\ud574 \uc8fc\ub2c8\uae4c \ub108\ubb34 \uace0\ub9d9\uace0, \ud55c\ud3b8\uc73c\ub85c\ub294 \uc2e0\uae30\ud558\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc77c\ub2e8 \ubc29\ud559 \ub54c stream/text \uad00\ub828\ub41c \ubd80\ubd84 \ub3d9\uc791\ub418\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\ub824\uace0 \ud558\uace0, \uadf8 \uc678\uc758 \ubd80\ubd84\uc740 \uc870\uae08 \ub354 \uace0\ubbfc\ud574\uc57c\ub420 \uac83 \uac19\ub2e4."]})]})}function d(e={}){const{wrapper:t}={...(0,c.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?s(Object(r),!0).forEach((function(t){c(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,c=function(e,t){if(null==e)return{};var r,n,c={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(c[r]=e[r]);return c}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var o=n.createContext({}),l=function(e){var t=n.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,c=e.mdxType,s=e.originalType,o=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),h=l(r),b=c,u=h["".concat(o,".").concat(b)]||h[b]||p[b]||s;return r?n.createElement(u,i(i({ref:t},d),{},{components:r})):n.createElement(u,i({ref:t},d))}));d.displayName="MDXCreateElement"},49483:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat1-e9408e2e2f13bb192541de194ffccc6a.png"},50885:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat2-4b3b653eb2b23b88f19e8cb4177a786c.png"},15153:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat3-12a510067e4d210c13e46b7b99313307.png"}}]); \ No newline at end of file diff --git a/assets/js/bbdd7e52.eb9f3b5d.js b/assets/js/bbdd7e52.eb9f3b5d.js deleted file mode 100644 index cfda42faa..000000000 --- a/assets/js/bbdd7e52.eb9f3b5d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3396],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>b});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},l=Object.keys(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),m=c(r),b=a,d=m["".concat(i,".").concat(b)]||m[b]||u[b]||l;return r?n.createElement(d,o(o({ref:t},s),{},{components:r})):n.createElement(d,o({ref:t},s))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=m;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:a,o[1]=p;for(var c=2;c<l;c++)o[c]=r[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},31120:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const l={title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",slug:"tecochat-retrospective-3",tags:["TecoChat","Retrospective"]},o=void 0,p={permalink:"/tecochat-retrospective-3",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",source:"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",description:"\uac1c\uc694",date:"2023-06-01T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 1\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.005,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",slug:"tecochat-retrospective-3",tags:["TecoChat","Retrospective"]},prevItem:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",permalink:"/order-retrospective"},nextItem:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",permalink:"/composite"}},i={authorsImageUrls:[]},c=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5",id:"\ub098\uc758-\ucc44\ud305-\ud655\uc778\ud558\uace0-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",level:3},{value:"\uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5",id:"\uc88b\uc544\uc694\uc640-\ub313\uae00-\uae30\ub2a5",level:3},{value:"\ud0a4\uc6cc\ub4dc \ucd94\ucd9c",id:"\ud0a4\uc6cc\ub4dc-\ucd94\ucd9c",level:3},{value:"\ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5",id:"\ub2e4\ub978-\ud06c\ub8e8\uc758-\ucc44\ud305-\ubcf5\uc0ac\ud574\uc11c-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5",level:3},{value:"\uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30",id:"\uc0ac\uc6a9\uc131-\uace0\ub824\ud558\uae30",level:3},{value:"\ud5a5\ud6c4 \uacc4\ud68d",id:"\ud5a5\ud6c4-\uacc4\ud68d",level:3}],s={toc:c};function u(e){let{components:t,...l}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,l,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,a.kt)("p",null,"\uc6d0\ub798 \ubaa9\uc801\uc778 ",(0,a.kt)("inlineCode",{parentName:"p"},"\ud06c\ub8e8\ub4e4\uc758 \ud559\uc2b5\uc5d0 \ub3c4\uc6c0"),"\uc744 \uc8fc\uae30 \uc704\ud574 \uc5b4\ub5a4 \uae30\ub2a5\uc744 \ucd94\uac00\ud574\uc57c \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 2\uac00 \uac70\uc758 \ub05d\ub098\uac00\ub294 \uc2dc\uc810, \uadf8\ub3d9\uc548 \ud588\ub358 \uac83\uc744 \uc815\ub9ac\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ub098\uc758-\ucc44\ud305-\ud655\uc778\ud558\uace0-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5"},"\ub098\uc758 \ucc44\ud305 \ud655\uc778\ud558\uace0 \uc774\uc5b4\ud558\ub294 \uae30\ub2a5"),(0,a.kt)("p",null,"GPT\uc5d0\ub3c4 \uc788\ub294 \uae30\ub2a5\uc778\ub370, \ub0b4\uac00 \uc774\uc804\uc5d0 \ud588\ub358 \ucc44\ud305\uc744 \uc774\uc5b4\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\uc804\uc5d0 \uc5b4\ub5a4 \uc9c8\ubb38\uc744 \ub0a8\uacbc\ub294\uc9c0, \ub610\ud55c \ud574\ub2f9 \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"chat1",src:r(49483).Z,width:"2878",height:"1316"})),(0,a.kt)("h3",{id:"\uc88b\uc544\uc694\uc640-\ub313\uae00-\uae30\ub2a5"},"\uc88b\uc544\uc694\uc640 \ub313\uae00 \uae30\ub2a5"),(0,a.kt)("p",null,"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc5d0 \ubc18\uc751\ud560 \uc218 \uc788\ub294 \ubb34\uc5b8\uac00\uac00 \uc788\uc5c8\uc73c\uba74 \uc88b\uaca0\ub2e4\ub294 \uc758\uacac\ub4e4\uc774 \ub9ce\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub204\uac00 \uc88b\uc544\uc694\ub97c \ub20c\ub800\ub294\uc9c0, \uc5b4\ub5a4 \ucc44\ud305\uc774 \uc88b\uc544\uc694\ub97c \uac00\uc7a5 \ub9ce\uc774 \ubc1b\uc558\ub294\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ub313\uae00 \ucd94\uac00 \ubc0f \uc0ad\uc81c \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4."),(0,a.kt)("h3",{id:"\ud0a4\uc6cc\ub4dc-\ucd94\ucd9c"},"\ud0a4\uc6cc\ub4dc \ucd94\ucd9c"),(0,a.kt)("p",null,"\uc5b4\ub5bb\uac8c \ud0a4\uc6cc\ub4dc \ucd94\ucd9c\uc744 \ud560\uc9c0 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub294\ub370, \uc77c\ub2e8 GPT\ub97c \uc774\uc6a9\ud574\uc11c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\uae30\ub85c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \ubd80\ubd84\uc740 \uccab \uc9c8\ubb38\uc5d0 \ub300\ud55c \ud0a4\uc6cc\ub4dc\ub9cc \ucd94\ucd9c\ud558\ub3c4\ub85d \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc31\uc5d4\ub4dc\uc5d0\uc120 \ub9d0\ub791\uc774 \uc774\ubca4\ud2b8 \uc774\uc6a9\ud574\uc11c \uccab \ucc44\ud305 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c0\uba74, \ube44\ub3d9\uae30\ub85c \ud0a4\uc6cc\ub4dc\ub97c \ucd94\ucd9c\ud558\ub294 \uc9c8\ubb38\uc744 \ucd94\uac00\ub85c \ub0a0\ub9ac\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","CSV \ud615\uc2dd\uc73c\ub85c GPT\uc5d0\uac8c \ub2f5\ubcc0\uc744 \uc785\ub825\ud574\ub2ec\ub77c\uace0 \uc694\uccad\ubc1b\ub294\ub370, \uc774 \ubd80\ubd84\uc774 \ubb38\uc81c(\ud504\ub86c\ud504\ud2b8 \uc5d4\uc9c0\ub2c8\uc5b4\ub9c1 \ubd80\ubd84\uc774 \ubc18\ud658\ub41c\ub2e4.)\uac00 \uc880 \uc788\ub294 \uac83 \uac19\uc544\uc11c \uac1c\uc120\uc774 \ud544\uc694\ud55c \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"chat2",src:r(50885).Z,width:"2394",height:"1048"})),(0,a.kt)("h3",{id:"\ub2e4\ub978-\ud06c\ub8e8\uc758-\ucc44\ud305-\ubcf5\uc0ac\ud574\uc11c-\uc774\uc5b4\ud558\ub294-\uae30\ub2a5"},"\ub2e4\ub978 \ud06c\ub8e8\uc758 \ucc44\ud305 \ubcf5\uc0ac\ud574\uc11c \uc774\uc5b4\ud558\ub294 \uae30\ub2a5"),(0,a.kt)("p",null,"\ub2e4\ub978 \ud06c\ub8e8\ub4e4\uc758 \ucc44\ud305\uc744 \uc77d\ub2e4\uac00 \uad81\uae08\ud55c \uc810\uc774 \uc788\ub2e4\uba74 \ubcf5\uc0ac\ud574\uc11c \ubc14\ub85c \uc9c8\ubb38\uc744 \ud560 \uc218 \uc788\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc44\ud305\uc774 \ubcf5\uc0ac\ub41c \ud6c4 \ubc14\ub85c GPT\uc640 \ub300\ud654\ub97c \ud560 \uc218 \uc788\ub294 \uba54\uc778 \ud654\uba74\uc73c\ub85c \uc774\ub3d9\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc0ac\uc6a9\uc131-\uace0\ub824\ud558\uae30"},"\uc0ac\uc6a9\uc131 \uace0\ub824\ud558\uae30"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"chat3",src:r(15153).Z,width:"1668",height:"718"})),(0,a.kt)("p",null,"\uc704 \ud654\uba74\uc740 \ud68c\uc6d0\uac00\uc785 \ucc3d\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc2e4 \uac00\uc7a5 \ub9c8\uc74c\uc5d0 \ub4dc\ub294 \ubd80\ubd84\uc774\uace0, \ud68c\uc6d0\uac00\uc785(\ub2c9\ub124\uc784\ub9cc \uc785\ub825\ud558\uc9c0\ub9cc)\ud560 \ub54c \uc775\uba85\uc744 \uc6d0\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uace0\ubbfc\uc744 \ub3c4\uc640\uc8fc\uac8c \ub054 \uc74c\uc2dd, \uacfc\uc77c, \uacfc\uc790 \ub4f1\uc758 \uc694\uc18c\ub4e4\uc744 \uc785\ub825\ud558\ub3c4\ub85d \uc720\ub3c4\ud588\ub2e4!\n\ucd94\uac00\ub85c GPT\uc758 \ub2f5\ubcc0\uc774 \uc624\uba74 \uc790\ub3d9\uc73c\ub85c \ud654\uba74\uc744 \uc2a4\ud06c\ub864 \ud574\uc8fc\ub294 \uac83\uacfc \uac19\uc774 \uc0ac\uc6a9\uc131\uc744 \uac1c\uc120\ud574 \ubcf4\ub824\uace0 \ub178\ub825\ud588\uc9c0\ub9cc \uc27d\uc9c0 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc81c\uc77c \ud558\uace0 \uc2f6\uc740 \uac83\uc740 \uc2e4\uc81c GPT\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\ucc98\ub7fc stream/text \uac12\uc744 \ucc98\ub9ac\ud558\uace0 \uc2f6\uc740\ub370 \uc774 \ubd80\ubd84\uc740 \ubc29\ud559 \ub54c \uae30\ud68c\uac00 \ub418\uba74 \ub3c4\uc804\ud574 \ubd10\uc57c\uaca0\ub2e4. "),(0,a.kt)("h3",{id:"\ud5a5\ud6c4-\uacc4\ud68d"},"\ud5a5\ud6c4 \uacc4\ud68d"),(0,a.kt)("p",null,"\uc2e4\uc81c \ud06c\ub8e8\ub4e4\uc774 \uc0ac\uc6a9\ud574 \uc8fc\ub294 \uc11c\ube44\uc2a4\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uc5b4\ubcf4\uba74\uc11c \uc0ac\uc6a9\uc790\uc758 \uc785\uc7a5\uc5d0\uc11c \uace0\ubbfc\ub3c4 \ud558\uac8c \ub418\ub294 \uac83 \uac19\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud06c\ub8e8\ub4e4\uc774 \uc9c1\uc811 \uc0ac\uc6a9\ud574 \uc8fc\ub2c8\uae4c \ub108\ubb34 \uace0\ub9d9\uace0, \ud55c\ud3b8\uc73c\ub85c\ub294 \uc2e0\uae30\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ub2e8 \ubc29\ud559 \ub54c stream/text \uad00\ub828\ub41c \ubd80\ubd84 \ub3d9\uc791\ub418\ub3c4\ub85d \uad6c\ud604\ud574\ubcf4\ub824\uace0 \ud558\uace0, \uadf8 \uc678\uc758 \ubd80\ubd84\uc740 \uc870\uae08 \ub354 \uace0\ubbfc\ud574\uc57c\ub420 \uac83 \uac19\ub2e4."))}u.isMDXComponent=!0},49483:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat1-e9408e2e2f13bb192541de194ffccc6a.png"},50885:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat2-4b3b653eb2b23b88f19e8cb4177a786c.png"},15153:(e,t,r)=>{r.d(t,{Z:()=>n});const n=r.p+"assets/images/chat3-12a510067e4d210c13e46b7b99313307.png"}}]); \ No newline at end of file diff --git a/assets/js/bd2d06b5.57d4dcf0.js b/assets/js/bd2d06b5.f610658d.js similarity index 81% rename from assets/js/bd2d06b5.57d4dcf0.js rename to assets/js/bd2d06b5.f610658d.js index afe15d69e..78b434d1b 100644 --- a/assets/js/bd2d06b5.57d4dcf0.js +++ b/assets/js/bd2d06b5.f610658d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9763],{93081:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9763],{93081:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/bd4db8ee.4dd36f14.js b/assets/js/bd4db8ee.4dd36f14.js deleted file mode 100644 index 1078fe69e..000000000 --- a/assets/js/bd4db8ee.4dd36f14.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6883],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>s});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?l(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function o(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},l=Object.keys(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var p=n.createContext({}),m=function(e){var t=n.useContext(p),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},d=function(e){var t=m(e.components);return n.createElement(p.Provider,{value:t},e.children)},b={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),c=m(a),s=r,u=c["".concat(p,".").concat(s)]||c[s]||b[s]||l;return a?n.createElement(u,i(i({ref:t},d),{},{components:a})):n.createElement(u,i({ref:t},d))}));function s(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,i=new Array(l);i[0]=c;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var m=2;m<l;m++)i[m]=a[m];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}c.displayName="MDXCreateElement"},93546:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>b,frontMatter:()=>l,metadata:()=>o,toc:()=>m});var n=a(87462),r=(a(67294),a(3905));const l={title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",slug:"transaction-and-isolation",tags:["DataBase","Transaction","Isolation"]},i=void 0,o={permalink:"/transaction-and-isolation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",source:"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",description:"\ud2b8\ub79c\uc7ad\uc158(Transaction)",date:"2023-04-05T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 5\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Transaction",permalink:"/tags/transaction"},{label:"Isolation",permalink:"/tags/isolation"}],readingTime:9.57,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",slug:"transaction-and-isolation",tags:["DataBase","Transaction","Isolation"]},prevItem:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/mysql-lock"},nextItem:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",permalink:"/test-double"}},p={authorsImageUrls:[]},m=[{value:"\ud2b8\ub79c\uc7ad\uc158(Transaction)",id:"\ud2b8\ub79c\uc7ad\uc158transaction",level:2},{value:"\ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)",id:"\ud2b8\ub79c\uc7ad\uc158\uc758-\uc18d\uc131acid",level:3},{value:"\ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d",id:"\ud2b8\ub79c\uc7ad\uc158-\uc8fc\uc758\uc0ac\ud56d",level:3},{value:"\uaca9\ub9ac \uc218\uc900(Isolation level)",id:"\uaca9\ub9ac-\uc218\uc900isolation-level",level:2},{value:"READ UNCOMMITTED",id:"read-uncommitted",level:3},{value:"READ COMMITTED",id:"read-committed",level:3},{value:"REPEATABLE READ",id:"repeatable-read",level:3},{value:"SERIALIZABLE",id:"serializable",level:3},{value:"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c",id:"\uaca9\ub9ac-\uc218\uc900\uc5d0-\ub530\ub978-\ubd80\uc815\ud569-\ubb38\uc81c",level:2},{value:"\ub354\ud2f0 \ub9ac\ub4dc(Dirty read)",id:"\ub354\ud2f0-\ub9ac\ub4dcdirty-read",level:3},{value:"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)",id:"\ubc18\ubcf5-\uac00\ub2a5\ud558\uc9c0-\uc54a\uc740-\uc870\ud68cnon-repeatable-read",level:3},{value:"\ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)",id:"\ud32c\ud140-\ub9ac\ub4dcphantom-read-phantom-row",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],d={toc:m};function b(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"\ud2b8\ub79c\uc7ad\uc158transaction"},"\ud2b8\ub79c\uc7ad\uc158(Transaction)"),(0,r.kt)("p",null,"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \ub17c\ub9ac\uc801 \uae30\ub2a5\uc744 \uc218\ud589\ud558\uae30 \uc704\ud55c \uc791\uc5c5\uc758 \ub2e8\uc704\ub97c \ub9d0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc740 \uc791\uc5c5\uc758 \uc644\uc804\uc131\uacfc \ub370\uc774\ud130\uc758 \uc815\ud569\uc131\uc744 \ubcf4\uc7a5\ud574 \uc900\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub17c\ub9ac\uc801\uc778 \uc791\uc5c5 \uc14b\uc744 \uc644\ubcbd\ud558\uac8c \ucc98\ub9ac\ud558\uac70\ub098, \uc624\ub958 \uc2dc \uc791\uc5c5\uc758 \uc77c\ubd80\ub9cc \uc801\uc6a9\ub418\ub294 \ud604\uc0c1\uc744 \ub9c9\uc544\uc900\ub2e4. "),(0,r.kt)("h3",{id:"\ud2b8\ub79c\uc7ad\uc158\uc758-\uc18d\uc131acid"},"\ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)"),(0,r.kt)("p",null,"\uc6d0\uc790\uc131(Atomicity): \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \uc2e4\ud589\ub41c \uc791\uc5c5\ub4e4\uc740 \ubaa8\ub450 \uc131\uacf5\ud558\uac70\ub098, \uc2e4\ud328\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc77c\uad00\uc131(Consistency): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc218\ud589\ub418\uae30 \uc804\uacfc \ud6c4\uc5d0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc77c\uad00\ub41c \uc0c1\ud0dc\ub97c \uc720\uc9c0\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uaca9\ub9ac\uc131(Isolation): \uac01\uac01\uc758 \ud2b8\ub79c\uc7ad\uc158\uc740 \ub3c5\ub9bd\uc801\uc774\ub77c \uc11c\ub85c\uc5d0\uac8c \uc601\ud5a5\uc744 \uc8fc\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc9c0\uc18d\uc131(Durability): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc131\uacf5\uc801\uc73c\ub85c \uc644\ub8cc\ub41c\ub2e4\uba74 \uc601\uad6c\uc801\uc73c\ub85c \uacb0\uacfc\uc5d0 \ubc18\uc601\ub418\uc5b4\uc57c \ud55c\ub2e4. "),(0,r.kt)("h3",{id:"\ud2b8\ub79c\uc7ad\uc158-\uc8fc\uc758\uc0ac\ud56d"},"\ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d"),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc740 \uaf2d \ud544\uc694\ud55c \ucd5c\uc18c\uc758 \ucf54\ub4dc\uc5d0\ub9cc \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.(\ud2b8\ub79c\uc7ad\uc158\uc758 \ubc94\uc704\ub97c \ucd5c\uc18c\ud654\ud558\ub77c)",(0,r.kt)("br",{parentName:"p"}),"\n","\uad6c\ud604\ud574\uc57c \ud558\ub294 \uc5c5\ubb34\uc5d0 \ub530\ub77c \ud2b8\ub79c\uc7ad\uc158\uc744 \ubb36\uac70\ub098 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uace0, \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\ub294 \uacbd\uc6b0 \ubc18\ub4dc\uc2dc \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4. "),(0,r.kt)("admonition",{title:"\uc65c \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\uc744 \ub54c \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud560\uae4c? \ud83e\udd14",type:"info"},(0,r.kt)("p",{parentName:"admonition"},"\ub370\uc774\ud130\uc758 \uc77c\uad00\uc131\uacfc \uc548\uc804\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc744 \ud2b8\ub79c\uc7ad\uc158 \ub0b4\ubd80\uc5d0 \ud3ec\ud568\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc911\uac04\uc5d0 \uc2e4\ud328\ud560 \uac00\ub2a5\uc131(\uc548\uc804\uc131 X)"),(0,r.kt)("li",{parentName:"ul"},"\ud1b5\uc2e0\uc73c\ub85c \uc778\ud574 \ub370\uc774\ud130\uac00 \ubcc0\uacbd\ub420 \uc218 \uc788\ub294 \ubd80\ubd84(\uc77c\uad00\uc131 X)"))),(0,r.kt)("h2",{id:"\uaca9\ub9ac-\uc218\uc900isolation-level"},"\uaca9\ub9ac \uc218\uc900(Isolation level)"),(0,r.kt)("p",null,"\uc5ec\ub7ec \ud2b8\ub79c\uc7ad\uc158\uc774 \ub3d9\uc2dc\uc5d0 \ucc98\ub9ac\ub420 \ub54c \ud2b9\uc815 \ud2b8\ub79c\uc7ad\uc158\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\uc758 \uc870\ud68c \ubc0f \ubcc0\uacbd\uc744 \ud5c8\uc6a9\ud560\uc9c0 \uacb0\uc815\ud558\ub294 \uac83\uc744 \ub9d0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uaca9\ub9ac \uc218\uc900\uc774 \ub192\uc544\uc9c8 \uc218\ub85d \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\uc774 \ub5a8\uc5b4\uc9c0\ub294 \uac83\uc774 \uc77c\ubc18\uc801\uc774\uc9c0\ub9cc, ",(0,r.kt)("inlineCode",{parentName:"p"},"SERIALIZABLE"),"\uc774 \uc544\ub2c8\ub77c\uba74 \ud06c\uac8c \uc131\ub2a5\uc758 \uc800\ud558\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4. "),(0,r.kt)("h3",{id:"read-uncommitted"},"READ UNCOMMITTED"),(0,r.kt)("p",null,"\uac01 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\uc758 \ubcc0\uacbd \ub0b4\uc6a9\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"COMMIT"),"\uc774\ub098 ",(0,r.kt)("inlineCode",{parentName:"p"},"ROLLBACK")," \uc5ec\ubd80\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcf4\uc778\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub354\ud2f0 \ub9ac\ub4dc \ud604\uc0c1\uc774 \ubc1c\uc0dd\ud558\uae30 \ub54c\ubb38\uc5d0 \uc815\ud569\uc131\uc758 \ubb38\uc81c\uac00 \ub9ce\uc740 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MySQL \uc0ac\uc6a9\uc2dc \ucd5c\uc18c ",(0,r.kt)("inlineCode",{parentName:"p"},"READ COMMITTED")," \uc774\uc0c1\uc758 \uaca9\ub9ac \uc218\uc900 \uc0ac\uc6a9\uc744 \uad8c\uc7a5\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"---\ntitle: READ UNCOMMITTED\n---\nsequenceDiagram\n Alice->>Database: BEGIN\n Alice->>Database: INSERT(Alice)\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: COMMIT(Alice)"}),(0,r.kt)("h3",{id:"read-committed"},"READ COMMITTED"),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 ",(0,r.kt)("inlineCode",{parentName:"p"},"COMMIT"),"\uc774 \uc644\ub8cc\ub41c \ub370\uc774\ud130\ub9cc \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc870\ud68c\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc624\ub77c\ud074 DBMS\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"REPEATABLE READ"),"\uac00 \ubcf4\uc7a5\ub418\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 ",(0,r.kt)("inlineCode",{parentName:"p"},"NON-REPEATABLE READ")," \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"---\ntitle: READ COMMITTED\n---\nsequenceDiagram\n Alice->>Database: BEGIN\n Alice->>Database: UPDATE(Alice to Bob)\n Bob->>Database: SELECT\n Database->>+Bob: Alice(Undo log)\n Alice->>Database: COMMIT"}),(0,r.kt)("h3",{id:"repeatable-read"},"REPEATABLE READ"),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc2dc\uc791\ub418\uae30 \uc804\uc5d0 ",(0,r.kt)("inlineCode",{parentName:"p"},"COMMIT"),"\uc774 \uc644\ub8cc\ub41c \ub0b4\uc6a9\uc5d0 \ub300\ud574\uc11c\ub9cc \uc870\ud68c\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MySQL\uc758 InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MVCC\ub97c \uc774\uc6a9\ud574 \uc5b8\ub450(Undo) \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \uc774\uc804 \ub370\uc774\ud130\ub97c \uc774\uc6a9\ud574 \ub3d9\uc77c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c\ub294 \ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc5ec\uc904 \uc218 \uc788\uac8c \ubcf4\uc7a5\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc7a5\ud558\ub294 \ubc29\ubc95\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ubaa8\ub4e0 InnoDB \ud2b8\ub79c\uc7ad\uc158\uc740 \uc21c\ucc28\uc801\uc73c\ub85c \uc99d\uac00\ud558\ub294 \uace0\uc720\ud55c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ub97c \uac00\uc9c4\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"Undo \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \ub808\ucf54\ub4dc\uc5d0\ub294 \ubcc0\uacbd\uc744 \ubc1c\uc0dd\uc2dc\ud0a8 \ud2b8\ub79c\uc7ad\uc158\uc758 \ubc88\ud638\uac00 \ud3ec\ud568\ub418\uc5b4\uc788\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"Undo \uc601\uc5ed\uc758 \ubc31\uc5c5\ub41c \ub370\uc774\ud130\ub294 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774 \ubd88\ud544\uc694\ud558\ub2e4\uace0 \ud310\ub2e8\ud558\ub294 \uacbd\uc6b0 \uc0ad\uc81c\ub41c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"REPEATABLE READ")," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c\ub294 MVCC\ub97c \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \uac00\uc7a5 \uc624\ub798\ub41c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ubcf4\ub2e4 \uc55e\uc120 Undo \uc601\uc5ed\uc758 \ub370\uc774\ud130\ub294 \uc0ad\uc81c\ud558\uc9c0 \uc54a\ub294\ub2e4. ")),(0,r.kt)("p",null,"InnoDB\uc5d0\uc11c\ub294 \uac2d \ub77d\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc744 \uc774\uc6a9\ud558\uc5ec \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc744 \ubc29\uc9c0\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"---\ntitle: REPEATABLE READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN(TRX-ID: 1)\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: BEGIN(TRX-ID: 2)\n Alice->>Database: UPDATE(Alice to Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT\n Database->>+Bob: Alice(Undo log)"}),(0,r.kt)("admonition",{title:"\uac2d \ub78d(Gap lock)\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d(Next-key lock)",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\uac2d \ub77d: \ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub125\uc2a4\ud2b8 \ud0a4 \ub77d: \ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4.")),(0,r.kt)("admonition",{title:"MVCC(Multi Version Concurrency Control)",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\ub3d9\uc2dc\uc131\uc744 \uc81c\uc5b4\ud558\ub294 \ubc29\ubc95 \uc911 \ud558\ub098\ub85c \ud558\ub098\uc758 \ub808\ucf54\ub4dc\uc5d0 \ub300\ud574 \uc5ec\ub7ec \uac1c\uc758 \ubc84\uc804\uc774 \ub3d9\uc2dc\uc5d0 \uad00\ub9ac\ub418\ub294 \uac83\uc774\ub2e4."),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"PostgreSQL\uc740 \ub2e4\uc911 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\ub294 \uac83\uc73c\ub85c MVCC\ub97c \uad6c\ud604\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"Oracle, InnoDB\ub294 ",(0,r.kt)("inlineCode",{parentName:"li"},"Undo log"),"\ub97c \uc774\uc6a9\ud574 \uc774 \uae30\ub2a5\uc744 \uad6c\ud604\ud55c\ub2e4.(\ucd5c\uc2e0 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub9cc DB\uc5d0 \uc800\uc7a5)")),(0,r.kt)("p",{parentName:"admonition"},"\uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uc77d\uad00\ub41c \uc77d\uae30\ub97c \uc81c\uacf5\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4.")),(0,r.kt)("h3",{id:"serializable"},"SERIALIZABLE"),(0,r.kt)("p",null,"\ud2b8\ub79c\uc7ad\uc158\uc744 \uc21c\ucc28\uc801\uc73c\ub85c \uc9c4\ud589\uc2dc\ud0a4\ub294 \uaca9\ub9ac \uc218\uc900\uc774\uace0 \ub530\ub77c\uc11c \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\ub3c4 \ub2e4\ub978 \uaca9\ub9ac \uc218\uc900\ubcf4\ub2e4 \ub5a8\uc5b4\uc9c4\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uace0 \uc4f0\ub294 \ub808\ucf54\ub4dc\ub97c \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\ub294 \uc811\uadfc\ud560 \uc218 \uc5c6\uace0 \ub2e8\uc21c\ud55c \uc77d\uae30 \uc791\uc5c5\ub3c4 \uacf5\uc720 \uc7a0\uae08(\uc77d\uae30 \uc7a0\uae08)\uc744 \ud68d\ub4dd\ud574\uc57c\ub9cc \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB\uc5d0\uc11c\ub294 \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"REPEATABLE READ")," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ubc1c\uc0dd\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uad73\uc774 \uc0ac\uc6a9\ud560 \ud544\uc694\ub294 \uc5c6\ub2e4. "),(0,r.kt)("h2",{id:"\uaca9\ub9ac-\uc218\uc900\uc5d0-\ub530\ub978-\ubd80\uc815\ud569-\ubb38\uc81c"},"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c"),(0,r.kt)("p",null,"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ub354\ud2f0 \ub9ac\ub4dc, \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c, \ud32c\ud140 \ub9ac\ub4dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\uaca9\ub9ac \uc218\uc900 / \ubd80\uc815\ud569 \ubb38\uc81c"),(0,r.kt)("th",{parentName:"tr",align:null},"\ub354\ud2f0 \ub9ac\ub4dc"),(0,r.kt)("th",{parentName:"tr",align:null},"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c"),(0,r.kt)("th",{parentName:"tr",align:null},"\ud32c\ud140 \ub9ac\ub4dc"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"READ UNCOMMITTED"),(0,r.kt)("td",{parentName:"tr",align:null},"O"),(0,r.kt)("td",{parentName:"tr",align:null},"O"),(0,r.kt)("td",{parentName:"tr",align:null},"O")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"READ COMMITTED"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"O"),(0,r.kt)("td",{parentName:"tr",align:null},"O")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"REPEATABLE READ"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"O(InnoDB\ub294 X)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"SERIALIZABLE"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"X"),(0,r.kt)("td",{parentName:"tr",align:null},"X")))),(0,r.kt)("h3",{id:"\ub354\ud2f0-\ub9ac\ub4dcdirty-read"},"\ub354\ud2f0 \ub9ac\ub4dc(Dirty read)"),(0,r.kt)("p",null,"\uc5b4\ub5a4 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ucc98\ub9ac\ud55c \uc791\uc5c5\uc774 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc558\uc5b4\ub3c4 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcfc \uc218 \uc788\ub294 \ud604\uc0c1",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158 \uaca9\ub9ac \uc218\uc900\uc774 READ UNCOMMITTED\uc77c \ub54c \ubc1c\uc0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uace0 \ucee4\ubc0b\uc744 \ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, A\uac00 \ud574\ub2f9 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud560 \uc218 \uc788\ub294 \uacbd\uc6b0"),(0,r.kt)("h3",{id:"\ubc18\ubcf5-\uac00\ub2a5\ud558\uc9c0-\uc54a\uc740-\uc870\ud68cnon-repeatable-read"},"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)"),(0,r.kt)("p",null,"\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc758 \uac19\uc740 \ud589\uc5d0 \ub450 \ubc88 \uc774\uc0c1 \uc870\ud68c\uac00 \ubc1c\uc0dd\ud588\ub294\ub370, \uadf8 \uac12\uc774 \ub2e4\ub978 \ud604\uc0c1",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc5ec\ub7ec \ubc88 \uc870\ud68c\ud558\ub358 \uc911 B\uac00 \ub808\ucf54\ub4dc\ub97c \ubcc0\uacbd\ud558\uc5ec A\uac00 \uc870\ud68c\ud55c \uac12\uc774 \ub2ec\ub77c\uc9c0\ub294 \uacbd\uc6b0 "),(0,r.kt)("mermaid",{value:"---\ntitle: NON REPEATABLE READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: BEGIN\n Alice->>Database: UPDATE(Alice to Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT\n Database->>+Bob: Bob"}),(0,r.kt)("h3",{id:"\ud32c\ud140-\ub9ac\ub4dcphantom-read-phantom-row"},"\ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)"),(0,r.kt)("p",null,"\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ucffc\ub9ac \uc218\ud589\uc2dc, \uc218\ud589 \uacb0\uacfc\uac00 \ub2e4\ub978 \ud604\uc0c1",(0,r.kt)("br",{parentName:"p"}),"\n","\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud558\uace0 B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uc5ec A\uac00 \ub2e4\uc2dc \uc870\ud68c\ud560 \ub54c \uc874\uc7ac\ud558\uc9c0 \uc54a\uc740 \ub808\ucf54\ub4dc\uac00 \uc870\ud68c\ub418\ub294 \uacbd\uc6b0 "),(0,r.kt)("mermaid",{value:"---\ntitle: PHANTOM READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN(TRX-ID: 1)\n Bob->>Database: SELECT COUNT\n Database->>+Bob: 1\n Alice->>Database: BEGIN(TRX-ID: 2)\n Alice->>Database: INSERT(Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT COUNT\n Database->>+Bob: 2"}),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html"},"Isolation Level, MySQL")))}b.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/bd4db8ee.65f63b9c.js b/assets/js/bd4db8ee.65f63b9c.js new file mode 100644 index 000000000..853675cf6 --- /dev/null +++ b/assets/js/bd4db8ee.65f63b9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6883],{64855:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>b,frontMatter:()=>i,metadata:()=>s,toc:()=>o});var t=a(85893),r=a(3905);const i={title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",slug:"transaction-and-isolation",tags:["DataBase","Transaction","Isolation"]},l=void 0,s={permalink:"/transaction-and-isolation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",source:"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",description:"\ud2b8\ub79c\uc7ad\uc158(Transaction)",date:"2023-04-05T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 5\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Transaction",permalink:"/tags/transaction"},{label:"Isolation",permalink:"/tags/isolation"}],readingTime:9.57,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",slug:"transaction-and-isolation",tags:["DataBase","Transaction","Isolation"]},unlisted:!1,prevItem:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/mysql-lock"},nextItem:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",permalink:"/test-double"}},c={authorsImageUrls:[]},o=[{value:"\ud2b8\ub79c\uc7ad\uc158(Transaction)",id:"\ud2b8\ub79c\uc7ad\uc158transaction",level:2},{value:"\ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)",id:"\ud2b8\ub79c\uc7ad\uc158\uc758-\uc18d\uc131acid",level:3},{value:"\ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d",id:"\ud2b8\ub79c\uc7ad\uc158-\uc8fc\uc758\uc0ac\ud56d",level:3},{value:"\uaca9\ub9ac \uc218\uc900(Isolation level)",id:"\uaca9\ub9ac-\uc218\uc900isolation-level",level:2},{value:"READ UNCOMMITTED",id:"read-uncommitted",level:3},{value:"READ COMMITTED",id:"read-committed",level:3},{value:"REPEATABLE READ",id:"repeatable-read",level:3},{value:"SERIALIZABLE",id:"serializable",level:3},{value:"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c",id:"\uaca9\ub9ac-\uc218\uc900\uc5d0-\ub530\ub978-\ubd80\uc815\ud569-\ubb38\uc81c",level:2},{value:"\ub354\ud2f0 \ub9ac\ub4dc(Dirty read)",id:"\ub354\ud2f0-\ub9ac\ub4dcdirty-read",level:3},{value:"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)",id:"\ubc18\ubcf5-\uac00\ub2a5\ud558\uc9c0-\uc54a\uc740-\uc870\ud68cnon-repeatable-read",level:3},{value:"\ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)",id:"\ud32c\ud140-\ub9ac\ub4dcphantom-read-phantom-row",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",mermaid:"mermaid",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"\ud2b8\ub79c\uc7ad\uc158transaction",children:"\ud2b8\ub79c\uc7ad\uc158(Transaction)"}),"\n",(0,t.jsxs)(n.p,{children:["\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \ub17c\ub9ac\uc801 \uae30\ub2a5\uc744 \uc218\ud589\ud558\uae30 \uc704\ud55c \uc791\uc5c5\uc758 \ub2e8\uc704\ub97c \ub9d0\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc740 \uc791\uc5c5\uc758 \uc644\uc804\uc131\uacfc \ub370\uc774\ud130\uc758 \uc815\ud569\uc131\uc744 \ubcf4\uc7a5\ud574 \uc900\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub17c\ub9ac\uc801\uc778 \uc791\uc5c5 \uc14b\uc744 \uc644\ubcbd\ud558\uac8c \ucc98\ub9ac\ud558\uac70\ub098, \uc624\ub958 \uc2dc \uc791\uc5c5\uc758 \uc77c\ubd80\ub9cc \uc801\uc6a9\ub418\ub294 \ud604\uc0c1\uc744 \ub9c9\uc544\uc900\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ud2b8\ub79c\uc7ad\uc158\uc758-\uc18d\uc131acid",children:"\ud2b8\ub79c\uc7ad\uc158\uc758 \uc18d\uc131(ACID)"}),"\n",(0,t.jsxs)(n.p,{children:["\uc6d0\uc790\uc131(Atomicity): \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \uc2e4\ud589\ub41c \uc791\uc5c5\ub4e4\uc740 \ubaa8\ub450 \uc131\uacf5\ud558\uac70\ub098, \uc2e4\ud328\ud574\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc77c\uad00\uc131(Consistency): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc218\ud589\ub418\uae30 \uc804\uacfc \ud6c4\uc5d0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \uc77c\uad00\ub41c \uc0c1\ud0dc\ub97c \uc720\uc9c0\ud574\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uaca9\ub9ac\uc131(Isolation): \uac01\uac01\uc758 \ud2b8\ub79c\uc7ad\uc158\uc740 \ub3c5\ub9bd\uc801\uc774\ub77c \uc11c\ub85c\uc5d0\uac8c \uc601\ud5a5\uc744 \uc8fc\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc9c0\uc18d\uc131(Durability): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc131\uacf5\uc801\uc73c\ub85c \uc644\ub8cc\ub41c\ub2e4\uba74 \uc601\uad6c\uc801\uc73c\ub85c \uacb0\uacfc\uc5d0 \ubc18\uc601\ub418\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ud2b8\ub79c\uc7ad\uc158-\uc8fc\uc758\uc0ac\ud56d",children:"\ud2b8\ub79c\uc7ad\uc158 \uc8fc\uc758\uc0ac\ud56d"}),"\n",(0,t.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc740 \uaf2d \ud544\uc694\ud55c \ucd5c\uc18c\uc758 \ucf54\ub4dc\uc5d0\ub9cc \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.(\ud2b8\ub79c\uc7ad\uc158\uc758 \ubc94\uc704\ub97c \ucd5c\uc18c\ud654\ud558\ub77c)",(0,t.jsx)(n.br,{}),"\n","\uad6c\ud604\ud574\uc57c \ud558\ub294 \uc5c5\ubb34\uc5d0 \ub530\ub77c \ud2b8\ub79c\uc7ad\uc158\uc744 \ubb36\uac70\ub098 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uace0, \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\ub294 \uacbd\uc6b0 \ubc18\ub4dc\uc2dc \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4."]}),"\n",(0,t.jsxs)(n.admonition,{title:"\uc65c \ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc788\uc744 \ub54c \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubc30\uc81c\ud574\uc57c \ud560\uae4c? \ud83e\udd14",type:"info",children:[(0,t.jsxs)(n.p,{children:["\ub370\uc774\ud130\uc758 \uc77c\uad00\uc131\uacfc \uc548\uc804\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \ubc30\uc81c\ud574\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc744 \ud2b8\ub79c\uc7ad\uc158 \ub0b4\ubd80\uc5d0 \ud3ec\ud568\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud560 \uc218 \uc788\ub2e4."]}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\ub124\ud2b8\uc6cc\ud06c \uc791\uc5c5\uc774 \uc911\uac04\uc5d0 \uc2e4\ud328\ud560 \uac00\ub2a5\uc131(\uc548\uc804\uc131 X)"}),"\n",(0,t.jsx)(n.li,{children:"\ud1b5\uc2e0\uc73c\ub85c \uc778\ud574 \ub370\uc774\ud130\uac00 \ubcc0\uacbd\ub420 \uc218 \uc788\ub294 \ubd80\ubd84(\uc77c\uad00\uc131 X)"}),"\n"]})]}),"\n",(0,t.jsx)(n.h2,{id:"\uaca9\ub9ac-\uc218\uc900isolation-level",children:"\uaca9\ub9ac \uc218\uc900(Isolation level)"}),"\n",(0,t.jsxs)(n.p,{children:["\uc5ec\ub7ec \ud2b8\ub79c\uc7ad\uc158\uc774 \ub3d9\uc2dc\uc5d0 \ucc98\ub9ac\ub420 \ub54c \ud2b9\uc815 \ud2b8\ub79c\uc7ad\uc158\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\uc758 \uc870\ud68c \ubc0f \ubcc0\uacbd\uc744 \ud5c8\uc6a9\ud560\uc9c0 \uacb0\uc815\ud558\ub294 \uac83\uc744 \ub9d0\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uaca9\ub9ac \uc218\uc900\uc774 \ub192\uc544\uc9c8 \uc218\ub85d \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\uc774 \ub5a8\uc5b4\uc9c0\ub294 \uac83\uc774 \uc77c\ubc18\uc801\uc774\uc9c0\ub9cc, ",(0,t.jsx)(n.code,{children:"SERIALIZABLE"}),"\uc774 \uc544\ub2c8\ub77c\uba74 \ud06c\uac8c \uc131\ub2a5\uc758 \uc800\ud558\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"read-uncommitted",children:"READ UNCOMMITTED"}),"\n",(0,t.jsxs)(n.p,{children:["\uac01 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\uc758 \ubcc0\uacbd \ub0b4\uc6a9\uc774 ",(0,t.jsx)(n.code,{children:"COMMIT"}),"\uc774\ub098 ",(0,t.jsx)(n.code,{children:"ROLLBACK"})," \uc5ec\ubd80\uc5d0 \uc0c1\uad00\uc5c6\uc774 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcf4\uc778\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub354\ud2f0 \ub9ac\ub4dc \ud604\uc0c1\uc774 \ubc1c\uc0dd\ud558\uae30 \ub54c\ubb38\uc5d0 \uc815\ud569\uc131\uc758 \ubb38\uc81c\uac00 \ub9ce\uc740 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MySQL \uc0ac\uc6a9\uc2dc \ucd5c\uc18c ",(0,t.jsx)(n.code,{children:"READ COMMITTED"})," \uc774\uc0c1\uc758 \uaca9\ub9ac \uc218\uc900 \uc0ac\uc6a9\uc744 \uad8c\uc7a5\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: READ UNCOMMITTED\n---\nsequenceDiagram\n Alice->>Database: BEGIN\n Alice->>Database: INSERT(Alice)\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: COMMIT(Alice)"}),"\n",(0,t.jsx)(n.h3,{id:"read-committed",children:"READ COMMITTED"}),"\n",(0,t.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 ",(0,t.jsx)(n.code,{children:"COMMIT"}),"\uc774 \uc644\ub8cc\ub41c \ub370\uc774\ud130\ub9cc \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc870\ud68c\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc624\ub77c\ud074 DBMS\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.code,{children:"REPEATABLE READ"}),"\uac00 \ubcf4\uc7a5\ub418\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 ",(0,t.jsx)(n.code,{children:"NON-REPEATABLE READ"})," \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: READ COMMITTED\n---\nsequenceDiagram\n Alice->>Database: BEGIN\n Alice->>Database: UPDATE(Alice to Bob)\n Bob->>Database: SELECT\n Database->>+Bob: Alice(Undo log)\n Alice->>Database: COMMIT"}),"\n",(0,t.jsx)(n.h3,{id:"repeatable-read",children:"REPEATABLE READ"}),"\n",(0,t.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc774 \uc2dc\uc791\ub418\uae30 \uc804\uc5d0 ",(0,t.jsx)(n.code,{children:"COMMIT"}),"\uc774 \uc644\ub8cc\ub41c \ub0b4\uc6a9\uc5d0 \ub300\ud574\uc11c\ub9cc \uc870\ud68c\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MySQL\uc758 InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\ub294 \uaca9\ub9ac \uc218\uc900\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MVCC\ub97c \uc774\uc6a9\ud574 \uc5b8\ub450(Undo) \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \uc774\uc804 \ub370\uc774\ud130\ub97c \uc774\uc6a9\ud574 \ub3d9\uc77c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c\ub294 \ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc5ec\uc904 \uc218 \uc788\uac8c \ubcf4\uc7a5\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub3d9\uc77c\ud55c \uacb0\uacfc\ub97c \ubcf4\uc7a5\ud558\ub294 \ubc29\ubc95\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\ubaa8\ub4e0 InnoDB \ud2b8\ub79c\uc7ad\uc158\uc740 \uc21c\ucc28\uc801\uc73c\ub85c \uc99d\uac00\ud558\ub294 \uace0\uc720\ud55c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ub97c \uac00\uc9c4\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"Undo \uc601\uc5ed\uc5d0 \ubc31\uc5c5\ub41c \ub808\ucf54\ub4dc\uc5d0\ub294 \ubcc0\uacbd\uc744 \ubc1c\uc0dd\uc2dc\ud0a8 \ud2b8\ub79c\uc7ad\uc158\uc758 \ubc88\ud638\uac00 \ud3ec\ud568\ub418\uc5b4\uc788\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"Undo \uc601\uc5ed\uc758 \ubc31\uc5c5\ub41c \ub370\uc774\ud130\ub294 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774 \ubd88\ud544\uc694\ud558\ub2e4\uace0 \ud310\ub2e8\ud558\ub294 \uacbd\uc6b0 \uc0ad\uc81c\ub41c\ub2e4."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"REPEATABLE READ"})," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c\ub294 MVCC\ub97c \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 \uac00\uc7a5 \uc624\ub798\ub41c \ud2b8\ub79c\uc7ad\uc158 \ubc88\ud638\ubcf4\ub2e4 \uc55e\uc120 Undo \uc601\uc5ed\uc758 \ub370\uc774\ud130\ub294 \uc0ad\uc81c\ud558\uc9c0 \uc54a\ub294\ub2e4."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"InnoDB\uc5d0\uc11c\ub294 \uac2d \ub77d\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d\uc744 \uc774\uc6a9\ud558\uc5ec \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc744 \ubc29\uc9c0\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: REPEATABLE READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN(TRX-ID: 1)\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: BEGIN(TRX-ID: 2)\n Alice->>Database: UPDATE(Alice to Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT\n Database->>+Bob: Alice(Undo log)"}),"\n",(0,t.jsx)(n.admonition,{title:"\uac2d \ub78d(Gap lock)\uacfc \ub125\uc2a4\ud2b8 \ud0a4 \ub77d(Next-key lock)",type:"note",children:(0,t.jsxs)(n.p,{children:["\uac2d \ub77d: \ub808\ucf54\ub4dc\uc640 \ubc14\ub85c \uc778\uc811\ud55c \ub808\ucf54\ub4dc \uc0ac\uc774\uc758 \uac04\uaca9\ub9cc\uc744 \uc7a0\uadf8\ub294 \ub77d\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub125\uc2a4\ud2b8 \ud0a4 \ub77d: \ub808\ucf54\ub4dc \ub77d\uacfc \uac2d \ub77d\uc744 \ud569\uccd0\ub193\uc740 \ud615\ud0dc\uc758 \uc7a0\uae08\uc73c\ub85c \ub808\ucf54\ub4dc\uc640 \uadf8 \ub808\ucf54\ub4dc \uc55e\uc758 \uac2d \ub77d\uc744 \ud3ec\ud568\ud55c\ub2e4."]})}),"\n",(0,t.jsxs)(n.admonition,{title:"MVCC(Multi Version Concurrency Control)",type:"note",children:[(0,t.jsx)(n.p,{children:"\ub3d9\uc2dc\uc131\uc744 \uc81c\uc5b4\ud558\ub294 \ubc29\ubc95 \uc911 \ud558\ub098\ub85c \ud558\ub098\uc758 \ub808\ucf54\ub4dc\uc5d0 \ub300\ud574 \uc5ec\ub7ec \uac1c\uc758 \ubc84\uc804\uc774 \ub3d9\uc2dc\uc5d0 \uad00\ub9ac\ub418\ub294 \uac83\uc774\ub2e4."}),(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"PostgreSQL\uc740 \ub2e4\uc911 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub97c \uc800\uc7a5\ud558\ub294 \uac83\uc73c\ub85c MVCC\ub97c \uad6c\ud604\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.li,{children:["Oracle, InnoDB\ub294 ",(0,t.jsx)(n.code,{children:"Undo log"}),"\ub97c \uc774\uc6a9\ud574 \uc774 \uae30\ub2a5\uc744 \uad6c\ud604\ud55c\ub2e4.(\ucd5c\uc2e0 \ubc84\uc804\uc758 \ub370\uc774\ud130\ub9cc DB\uc5d0 \uc800\uc7a5)"]}),"\n"]}),(0,t.jsx)(n.p,{children:"\uc7a0\uae08\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uc77d\uad00\ub41c \uc77d\uae30\ub97c \uc81c\uacf5\ud558\ub294 \uac83\uc774 \ubaa9\uc801\uc774\ub2e4."})]}),"\n",(0,t.jsx)(n.h3,{id:"serializable",children:"SERIALIZABLE"}),"\n",(0,t.jsxs)(n.p,{children:["\ud2b8\ub79c\uc7ad\uc158\uc744 \uc21c\ucc28\uc801\uc73c\ub85c \uc9c4\ud589\uc2dc\ud0a4\ub294 \uaca9\ub9ac \uc218\uc900\uc774\uace0 \ub530\ub77c\uc11c \ub3d9\uc2dc \ucc98\ub9ac \uc131\ub2a5\ub3c4 \ub2e4\ub978 \uaca9\ub9ac \uc218\uc900\ubcf4\ub2e4 \ub5a8\uc5b4\uc9c4\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc77d\uace0 \uc4f0\ub294 \ub808\ucf54\ub4dc\ub97c \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c\ub294 \uc811\uadfc\ud560 \uc218 \uc5c6\uace0 \ub2e8\uc21c\ud55c \uc77d\uae30 \uc791\uc5c5\ub3c4 \uacf5\uc720 \uc7a0\uae08(\uc77d\uae30 \uc7a0\uae08)\uc744 \ud68d\ub4dd\ud574\uc57c\ub9cc \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","InnoDB\uc5d0\uc11c\ub294 \ud32c\ud140 \ub9ac\ub4dc \ud604\uc0c1\uc774 ",(0,t.jsx)(n.code,{children:"REPEATABLE READ"})," \uaca9\ub9ac \uc218\uc900\uc5d0\uc11c \ubc1c\uc0dd\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uad73\uc774 \uc0ac\uc6a9\ud560 \ud544\uc694\ub294 \uc5c6\ub2e4."]}),"\n",(0,t.jsx)(n.h2,{id:"\uaca9\ub9ac-\uc218\uc900\uc5d0-\ub530\ub978-\ubd80\uc815\ud569-\ubb38\uc81c",children:"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub978 \ubd80\uc815\ud569 \ubb38\uc81c"}),"\n",(0,t.jsx)(n.p,{children:"\uaca9\ub9ac \uc218\uc900\uc5d0 \ub530\ub77c \ub354\ud2f0 \ub9ac\ub4dc, \ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c, \ud32c\ud140 \ub9ac\ub4dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"\uaca9\ub9ac \uc218\uc900 / \ubd80\uc815\ud569 \ubb38\uc81c"}),(0,t.jsx)(n.th,{children:"\ub354\ud2f0 \ub9ac\ub4dc"}),(0,t.jsx)(n.th,{children:"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c"}),(0,t.jsx)(n.th,{children:"\ud32c\ud140 \ub9ac\ub4dc"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"READ UNCOMMITTED"}),(0,t.jsx)(n.td,{children:"O"}),(0,t.jsx)(n.td,{children:"O"}),(0,t.jsx)(n.td,{children:"O"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"READ COMMITTED"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"O"}),(0,t.jsx)(n.td,{children:"O"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"REPEATABLE READ"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"O(InnoDB\ub294 X)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SERIALIZABLE"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"X"}),(0,t.jsx)(n.td,{children:"X"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"\ub354\ud2f0-\ub9ac\ub4dcdirty-read",children:"\ub354\ud2f0 \ub9ac\ub4dc(Dirty read)"}),"\n",(0,t.jsxs)(n.p,{children:["\uc5b4\ub5a4 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ucc98\ub9ac\ud55c \uc791\uc5c5\uc774 \uc644\ub8cc\ub418\uc9c0 \uc54a\uc558\uc5b4\ub3c4 \ub2e4\ub978 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \ubcfc \uc218 \uc788\ub294 \ud604\uc0c1",(0,t.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158 \uaca9\ub9ac \uc218\uc900\uc774 READ UNCOMMITTED\uc77c \ub54c \ubc1c\uc0dd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc608) B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uace0 \ucee4\ubc0b\uc744 \ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, A\uac00 \ud574\ub2f9 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud560 \uc218 \uc788\ub294 \uacbd\uc6b0"]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc18\ubcf5-\uac00\ub2a5\ud558\uc9c0-\uc54a\uc740-\uc870\ud68cnon-repeatable-read",children:"\ubc18\ubcf5 \uac00\ub2a5\ud558\uc9c0 \uc54a\uc740 \uc870\ud68c(Non-repeatable read)"}),"\n",(0,t.jsxs)(n.p,{children:["\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc758 \uac19\uc740 \ud589\uc5d0 \ub450 \ubc88 \uc774\uc0c1 \uc870\ud68c\uac00 \ubc1c\uc0dd\ud588\ub294\ub370, \uadf8 \uac12\uc774 \ub2e4\ub978 \ud604\uc0c1",(0,t.jsx)(n.br,{}),"\n","\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc5ec\ub7ec \ubc88 \uc870\ud68c\ud558\ub358 \uc911 B\uac00 \ub808\ucf54\ub4dc\ub97c \ubcc0\uacbd\ud558\uc5ec A\uac00 \uc870\ud68c\ud55c \uac12\uc774 \ub2ec\ub77c\uc9c0\ub294 \uacbd\uc6b0"]}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: NON REPEATABLE READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN\n Bob->>Database: SELECT\n Database->>+Bob: Alice\n Alice->>Database: BEGIN\n Alice->>Database: UPDATE(Alice to Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT\n Database->>+Bob: Bob"}),"\n",(0,t.jsx)(n.h3,{id:"\ud32c\ud140-\ub9ac\ub4dcphantom-read-phantom-row",children:"\ud32c\ud140 \ub9ac\ub4dc(Phantom read, Phantom row)"}),"\n",(0,t.jsxs)(n.p,{children:["\ud55c \ud2b8\ub79c\uc7ad\uc158 \ub0b4\uc5d0\uc11c \ub3d9\uc77c\ud55c \ucffc\ub9ac \uc218\ud589\uc2dc, \uc218\ud589 \uacb0\uacfc\uac00 \ub2e4\ub978 \ud604\uc0c1",(0,t.jsx)(n.br,{}),"\n","\uc608) A\uac00 \ub808\ucf54\ub4dc\ub97c \uc870\ud68c\ud558\uace0 B\uac00 \ub808\ucf54\ub4dc\ub97c \ucd94\uac00\ud558\uc5ec A\uac00 \ub2e4\uc2dc \uc870\ud68c\ud560 \ub54c \uc874\uc7ac\ud558\uc9c0 \uc54a\uc740 \ub808\ucf54\ub4dc\uac00 \uc870\ud68c\ub418\ub294 \uacbd\uc6b0"]}),"\n",(0,t.jsx)(n.mermaid,{value:"---\ntitle: PHANTOM READ\n---\nsequenceDiagram\n participant Alice\n participant Database\n participant Bob\n Bob->>Database: BEGIN(TRX-ID: 1)\n Bob->>Database: SELECT COUNT\n Database->>+Bob: 1\n Alice->>Database: BEGIN(TRX-ID: 2)\n Alice->>Database: INSERT(Bob)\n Alice->>Database: COMMIT\n Bob->>Database: SELECT COUNT\n Database->>+Bob: 2"}),"\n",(0,t.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:["Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html",children:"Isolation Level, MySQL"})]})]})}function b(e={}){const{wrapper:n}={...(0,r.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,a)=>{a.d(n,{ah:()=>o});var t=a(67294);function r(e,n,a){return n in e?Object.defineProperty(e,n,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[n]=a,e}function i(e,n){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),a.push.apply(a,t)}return a}function l(e){for(var n=1;n<arguments.length;n++){var a=null!=arguments[n]?arguments[n]:{};n%2?i(Object(a),!0).forEach((function(n){r(e,n,a[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):i(Object(a)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(a,n))}))}return e}function s(e,n){if(null==e)return{};var a,t,r=function(e,n){if(null==e)return{};var a,t,r={},i=Object.keys(e);for(t=0;t<i.length;t++)a=i[t],n.indexOf(a)>=0||(r[a]=e[a]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)a=i[t],n.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var c=t.createContext({}),o=function(e){var n=t.useContext(c),a=n;return e&&(a="function"==typeof e?e(n):l(l({},n),e)),a},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},b=t.forwardRef((function(e,n){var a=e.components,r=e.mdxType,i=e.originalType,c=e.parentName,b=s(e,["components","mdxType","originalType","parentName"]),h=o(a),j=r,x=h["".concat(c,".").concat(j)]||h[j]||d[j]||i;return a?t.createElement(x,l(l({ref:n},b),{},{components:a})):t.createElement(x,l({ref:n},b))}));b.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/bd64a762.c0b05caa.js b/assets/js/bd64a762.c0b05caa.js new file mode 100644 index 000000000..d5b7dfa86 --- /dev/null +++ b/assets/js/bd64a762.c0b05caa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5463],{11365:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>l});var n=t(85893),i=t(3905);const o={title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",slug:"/database/query-execution",last_update:{date:"2023/09/25"},tag:["mysql","query"]},a=void 0,s={id:"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",description:"\uc2e4\ud589 \uad6c\uc870",source:"@site/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870.mdx",sourceDirName:"\ub370\uc774\ud130\ubca0\uc774\uc2a4",slug:"/database/query-execution",permalink:"/docs/database/query-execution",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870.mdx",tags:[],version:"current",lastUpdatedAt:16956e5,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 25\uc77c",frontMatter:{title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",slug:"/database/query-execution",last_update:{date:"2023/09/25"},tag:["mysql","query"]},sidebar:"tutorialSidebar",previous:{title:"maximumPoolSize",permalink:"/docs/database/maximumPoolSize"},next:{title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",permalink:"/docs/book/getting-out-of-the-box"}},c={},l=[{value:"\uc2e4\ud589 \uad6c\uc870",id:"\uc2e4\ud589-\uad6c\uc870",level:3},{value:"\ud30c\uc11c(Parser)",id:"\ud30c\uc11cparser",level:3},{value:"\uc804\ucc98\ub9ac\uae30(Preprocessor)",id:"\uc804\ucc98\ub9ac\uae30preprocessor",level:3},{value:"\uc635\ud2f0\ub9c8\uc774\uc800(Optimizer)",id:"\uc635\ud2f0\ub9c8\uc774\uc800optimizer",level:3},{value:"\ucffc\ub9ac \uc2e4\ud589 \uc5d4\uc9c4(Query Execution Engine)",id:"\ucffc\ub9ac-\uc2e4\ud589-\uc5d4\uc9c4query-execution-engine",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function u(e){const r={a:"a",br:"br",h3:"h3",mermaid:"mermaid",p:"p",...(0,i.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h3,{id:"\uc2e4\ud589-\uad6c\uc870",children:"\uc2e4\ud589 \uad6c\uc870"}),"\n",(0,n.jsx)(r.mermaid,{value:'graph BT\n\tsubgraph MySQL[MySQL Engine]\n\t client -- "1. SQL\uc744 \uc2e4\ud589\ud55c\ub2e4." --\x3e parser\n\t\tparser -- "2. SQL\uc744 \ucd5c\uc18c \ub2e8\uc704\ub85c \ubd84\ub9ac\ud558\uc5ec \uad6c\uc131 \uc694\uc18c\ub97c \ud2b8\ub9ac\ub85c \uc791\uc131\ud55c\ub2e4." --\x3e pre-processor\n\t\tpre-processor -- "3. \ud2b8\ub9ac\uc758 \uad6c\uc131 \uc694\uc18c\ub85c \uad8c\ud55c \ubc0f \uc874\uc7ac \uc5ec\ubd80\ub97c \ud655\uc778\ud55c\ub2e4."--\x3e optimizer\n\t\toptimizer -- "4. \uc2e4\ud589\uacc4\ud68d\uc744 \uc804\ub2ec\ud55c\ub2e4." --\x3e QEE[query execution engine]\n\tend\n\n\tQEE <-- "5. \ub370\uc774\ud130\ub97c \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uac00\uc838\uc628\ub2e4" --\x3e SE[storage engine]\n\tQEE -- "6. \uacb0\uacfc\ub97c \uc804\ub2ec\ud55c\ub2e4." --\x3e client'}),"\n",(0,n.jsx)(r.h3,{id:"\ud30c\uc11cparser",children:"\ud30c\uc11c(Parser)"}),"\n",(0,n.jsxs)(r.p,{children:["\uc2e4\ud589\ub41c SQL\ubb38\uc744 \ucd5c\uc18c \ub2e8\uc704\ub85c \ubd84\ub9ac\ud574\uc11c \ud2b8\ub9ac\ub97c \ub9cc\ub4e0\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud2b8\ub9ac\ub97c \ub9cc\ub4e4\uba70 \uae30\ubcf8\uc801\uc778 \ubb38\ubc95 \uac80\uc0ac\ub97c \uc218\ud589\ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc804\ucc98\ub9ac\uae30preprocessor",children:"\uc804\ucc98\ub9ac\uae30(Preprocessor)"}),"\n",(0,n.jsxs)(r.p,{children:["\ud30c\uc11c\uc5d0\uc11c \uc0dd\uc131\ud55c \ud30c\uc11c \ud2b8\ub9ac\ub97c \ubc14\ud0d5\uc73c\ub85c SQL\ubb38\uc5d0 \uad6c\uc870\uc801\uc778 \ubb38\uc81c\uc810\uc774 \uc5c6\ub294\uc9c0 \ud30c\uc545\ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","SQL \uad6c\ubb38\uc5d0 \uc791\uc131\ub41c \ud14c\uc774\ube14, \uc5f4\uacfc \uac19\uc740 \uc624\ube0c\uc81d\ud2b8\uac00 \uc2e4\uc81c\ub85c \uc874\uc7ac\ud558\ub294\uc9c0, \uc811\uadfc \uad8c\ud55c\uc774 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\uc635\ud2f0\ub9c8\uc774\uc800optimizer",children:"\uc635\ud2f0\ub9c8\uc774\uc800(Optimizer)"}),"\n",(0,n.jsxs)(r.p,{children:["\ud30c\uc11c \ud2b8\ub9ac\ub97c \ubc14\ud0d5\uc73c\ub85c \ud544\uc694\ud558\uc9c0 \uc54a\uc740 \uc870\uac74\uc740 \uc81c\uac70\ud558\uac70\ub098 \uc5f0\uc0b0 \uacfc\uc815\uc744 \ub2e8\uc21c\ud654 \uc2dc\ud0a8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud14c\uc774\ube14\uc758 \uc811\uadfc \uc21c\uc11c, \uc778\ub371\uc2a4 \uc0ac\uc6a9 \uc5ec\ubd80\uc640 \uac19\uc740 \uc2e4\ud589 \uacc4\ud68d\uc744 \uc218\ub9bd\ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ucffc\ub9ac-\uc2e4\ud589-\uc5d4\uc9c4query-execution-engine",children:"\ucffc\ub9ac \uc2e4\ud589 \uc5d4\uc9c4(Query Execution Engine)"}),"\n",(0,n.jsxs)(r.p,{children:["\uc635\ud2f0\ub9c8\uc774\uc800\uc5d0\uc11c \uc218\ub9bd\ud55c \uc2e4\ud589 \uacc4\ud68d\uc744 \ucc38\uace0\ud558\uc5ec, \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \ub370\uc774\ud130\ub97c \uac00\uc838\uc628\ub2e4.",(0,n.jsx)(r.br,{}),"\n","MySQL \uc5d4\uc9c4\uc758 \ubd80\ud558\ub97c \uc904\uc774\ub824\uba74 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uac00\uc838\uc624\ub294 \ub370\uc774\ud130\uc591\uc744 \uc904\uc774\ub294 \uac8c \ub9e4\uc6b0 \uc911\uc694\ud558\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsxs)(r.p,{children:["2\uc7a5 SQL \ud29c\ub2dd \uc6a9\uc5b4\ub97c \uc9c1\uad00\uc801\uc73c\ub85c \uc774\ud574\ud558\uae30, \uc5c5\ubb34\uc5d0 \ubc14\ub85c \uc4f0\ub294 SQL \ud29c\ub2dd - \uc591\ubc14\ub978",(0,n.jsx)(r.br,{}),"\n","16\uc7a5 \ubcf5\uc81c, Real MySQL 8.0 - \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,n.jsx)(r.br,{}),"\n",(0,n.jsx)(r.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html",children:"https://dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html"})]})]})}function p(e={}){const{wrapper:r}={...(0,i.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>l});var n=t(67294);function i(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function o(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function a(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?o(Object(t),!0).forEach((function(r){i(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,i=function(e,r){if(null==e)return{};var t,n,i={},o=Object.keys(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||(i[t]=e[t]);return i}(e,r);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)t=o[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var c=n.createContext({}),l=function(e){var r=n.useContext(c),t=r;return e&&(t="function"==typeof e?e(r):a(a({},r),e)),t},u={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},p=n.forwardRef((function(e,r){var t=e.components,i=e.mdxType,o=e.originalType,c=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=l(t),m=i,b=d["".concat(c,".").concat(m)]||d[m]||u[m]||o;return t?n.createElement(b,a(a({ref:r},p),{},{components:t})):n.createElement(b,a({ref:r},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/bd64a762.d1f2c079.js b/assets/js/bd64a762.d1f2c079.js deleted file mode 100644 index 01260fb7e..000000000 --- a/assets/js/bd64a762.d1f2c079.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5463],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>d});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),u=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),m=u(r),d=a,y=m["".concat(p,".").concat(d)]||m[d]||s[d]||o;return r?n.createElement(y,i(i({ref:t},c),{},{components:r})):n.createElement(y,i({ref:t},c))}));function d(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,i[1]=l;for(var u=2;u<o;u++)i[u]=r[u];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},37089:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>s,frontMatter:()=>o,metadata:()=>l,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const o={title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",slug:"/database/query-execution",last_update:{date:"2023/09/25"},tag:["mysql","query"]},i=void 0,l={unversionedId:"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",id:"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",description:"\uc2e4\ud589 \uad6c\uc870",source:"@site/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870.mdx",sourceDirName:"\ub370\uc774\ud130\ubca0\uc774\uc2a4",slug:"/database/query-execution",permalink:"/docs/database/query-execution",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870.mdx",tags:[],version:"current",lastUpdatedAt:16956e5,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 25\uc77c",frontMatter:{title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",slug:"/database/query-execution",last_update:{date:"2023/09/25"},tag:["mysql","query"]},sidebar:"tutorialSidebar",previous:{title:"maximumPoolSize",permalink:"/docs/database/maximumPoolSize"},next:{title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",permalink:"/docs/book/getting-out-of-the-box"}},p={},u=[{value:"\uc2e4\ud589 \uad6c\uc870",id:"\uc2e4\ud589-\uad6c\uc870",level:3},{value:"\ud30c\uc11c(Parser)",id:"\ud30c\uc11cparser",level:3},{value:"\uc804\ucc98\ub9ac\uae30(Preprocessor)",id:"\uc804\ucc98\ub9ac\uae30preprocessor",level:3},{value:"\uc635\ud2f0\ub9c8\uc774\uc800(Optimizer)",id:"\uc635\ud2f0\ub9c8\uc774\uc800optimizer",level:3},{value:"\ucffc\ub9ac \uc2e4\ud589 \uc5d4\uc9c4(Query Execution Engine)",id:"\ucffc\ub9ac-\uc2e4\ud589-\uc5d4\uc9c4query-execution-engine",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:u};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uc2e4\ud589-\uad6c\uc870"},"\uc2e4\ud589 \uad6c\uc870"),(0,a.kt)("mermaid",{value:'graph BT\n\tsubgraph MySQL[MySQL Engine]\n\t client -- "1. SQL\uc744 \uc2e4\ud589\ud55c\ub2e4." --\x3e parser\n\t\tparser -- "2. SQL\uc744 \ucd5c\uc18c \ub2e8\uc704\ub85c \ubd84\ub9ac\ud558\uc5ec \uad6c\uc131 \uc694\uc18c\ub97c \ud2b8\ub9ac\ub85c \uc791\uc131\ud55c\ub2e4." --\x3e pre-processor\n\t\tpre-processor -- "3. \ud2b8\ub9ac\uc758 \uad6c\uc131 \uc694\uc18c\ub85c \uad8c\ud55c \ubc0f \uc874\uc7ac \uc5ec\ubd80\ub97c \ud655\uc778\ud55c\ub2e4."--\x3e optimizer\n\t\toptimizer -- "4. \uc2e4\ud589\uacc4\ud68d\uc744 \uc804\ub2ec\ud55c\ub2e4." --\x3e QEE[query execution engine]\n\tend\n\n\tQEE <-- "5. \ub370\uc774\ud130\ub97c \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uac00\uc838\uc628\ub2e4" --\x3e SE[storage engine]\n\tQEE -- "6. \uacb0\uacfc\ub97c \uc804\ub2ec\ud55c\ub2e4." --\x3e client'}),(0,a.kt)("h3",{id:"\ud30c\uc11cparser"},"\ud30c\uc11c(Parser)"),(0,a.kt)("p",null,"\uc2e4\ud589\ub41c SQL\ubb38\uc744 \ucd5c\uc18c \ub2e8\uc704\ub85c \ubd84\ub9ac\ud574\uc11c \ud2b8\ub9ac\ub97c \ub9cc\ub4e0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub9ac\ub97c \ub9cc\ub4e4\uba70 \uae30\ubcf8\uc801\uc778 \ubb38\ubc95 \uac80\uc0ac\ub97c \uc218\ud589\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc804\ucc98\ub9ac\uae30preprocessor"},"\uc804\ucc98\ub9ac\uae30(Preprocessor)"),(0,a.kt)("p",null,"\ud30c\uc11c\uc5d0\uc11c \uc0dd\uc131\ud55c \ud30c\uc11c \ud2b8\ub9ac\ub97c \ubc14\ud0d5\uc73c\ub85c SQL\ubb38\uc5d0 \uad6c\uc870\uc801\uc778 \ubb38\uc81c\uc810\uc774 \uc5c6\ub294\uc9c0 \ud30c\uc545\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","SQL \uad6c\ubb38\uc5d0 \uc791\uc131\ub41c \ud14c\uc774\ube14, \uc5f4\uacfc \uac19\uc740 \uc624\ube0c\uc81d\ud2b8\uac00 \uc2e4\uc81c\ub85c \uc874\uc7ac\ud558\ub294\uc9c0, \uc811\uadfc \uad8c\ud55c\uc774 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc635\ud2f0\ub9c8\uc774\uc800optimizer"},"\uc635\ud2f0\ub9c8\uc774\uc800(Optimizer)"),(0,a.kt)("p",null,"\ud30c\uc11c \ud2b8\ub9ac\ub97c \ubc14\ud0d5\uc73c\ub85c \ud544\uc694\ud558\uc9c0 \uc54a\uc740 \uc870\uac74\uc740 \uc81c\uac70\ud558\uac70\ub098 \uc5f0\uc0b0 \uacfc\uc815\uc744 \ub2e8\uc21c\ud654 \uc2dc\ud0a8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud14c\uc774\ube14\uc758 \uc811\uadfc \uc21c\uc11c, \uc778\ub371\uc2a4 \uc0ac\uc6a9 \uc5ec\ubd80\uc640 \uac19\uc740 \uc2e4\ud589 \uacc4\ud68d\uc744 \uc218\ub9bd\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ucffc\ub9ac-\uc2e4\ud589-\uc5d4\uc9c4query-execution-engine"},"\ucffc\ub9ac \uc2e4\ud589 \uc5d4\uc9c4(Query Execution Engine)"),(0,a.kt)("p",null,"\uc635\ud2f0\ub9c8\uc774\uc800\uc5d0\uc11c \uc218\ub9bd\ud55c \uc2e4\ud589 \uacc4\ud68d\uc744 \ucc38\uace0\ud558\uc5ec, \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \ub370\uc774\ud130\ub97c \uac00\uc838\uc628\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","MySQL \uc5d4\uc9c4\uc758 \ubd80\ud558\ub97c \uc904\uc774\ub824\uba74 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c \uac00\uc838\uc624\ub294 \ub370\uc774\ud130\uc591\uc744 \uc904\uc774\ub294 \uac8c \ub9e4\uc6b0 \uc911\uc694\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"2\uc7a5 SQL \ud29c\ub2dd \uc6a9\uc5b4\ub97c \uc9c1\uad00\uc801\uc73c\ub85c \uc774\ud574\ud558\uae30, \uc5c5\ubb34\uc5d0 \ubc14\ub85c \uc4f0\ub294 SQL \ud29c\ub2dd - \uc591\ubc14\ub978",(0,a.kt)("br",{parentName:"p"}),"\n","16\uc7a5 \ubcf5\uc81c, Real MySQL 8.0 - \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html"},"https://dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/be497a8d.11ef414c.js b/assets/js/be497a8d.11ef414c.js deleted file mode 100644 index 548f67ac5..000000000 --- a/assets/js/be497a8d.11ef414c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6172],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?s(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):s(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},s=Object.keys(e);for(a=0;a<s.length;a++)n=s[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a<s.length;a++)n=s[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=a.createContext({}),u=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=u(e.components);return a.createElement(o.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,s=e.originalType,o=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),g=u(n),m=r,d=g["".concat(o,".").concat(m)]||g[m]||p[m]||s;return n?a.createElement(d,l(l({ref:t},c),{},{components:n})):a.createElement(d,l({ref:t},c))}));function m(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var s=n.length,l=new Array(s);l[0]=g;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i.mdxType="string"==typeof e?e:r,l[1]=i;for(var u=2;u<s;u++)l[u]=n[u];return a.createElement.apply(null,l)}return a.createElement.apply(null,n)}g.displayName="MDXCreateElement"},45909:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>l,default:()=>p,frontMatter:()=>s,metadata:()=>i,toc:()=>u});var a=n(87462),r=(n(67294),n(3905));const s={title:"Docusaurus",slug:"docusaurus",tags:["Documentation"]},l=void 0,i={permalink:"/docusaurus",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",source:"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",title:"Docusaurus",description:"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4.",date:"2023-06-18T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 18\uc77c",tags:[{label:"Documentation",permalink:"/tags/documentation"}],readingTime:10.095,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Docusaurus",slug:"docusaurus",tags:["Documentation"]},prevItem:{title:"\uc6f9\uc18c\ucf13",permalink:"/websocket"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",permalink:"/woowacourse-level2-retrospective"}},o={authorsImageUrls:[]},u=[{value:"\uc124\uce58",id:"\uc124\uce58",level:2},{value:"\ubc30\ud3ec",id:"\ubc30\ud3ec",level:2},{value:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131",id:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac-\uc0dd\uc131",level:3},{value:"\uc124\uc815 \ud30c\uc77c \uc218\uc815",id:"\uc124\uc815-\ud30c\uc77c-\uc218\uc815",level:3},{value:"\ud1a0\ud070 \uc124\uc815",id:"\ud1a0\ud070-\uc124\uc815",level:3},{value:"\ube0c\ub79c\uce58 \uc0dd\uc131",id:"\ube0c\ub79c\uce58-\uc0dd\uc131",level:3},{value:"\uc6cc\ud06c\ud50c\ub85c \uc791\uc131",id:"\uc6cc\ud06c\ud50c\ub85c-\uc791\uc131",level:3},{value:"\ub313\uae00 \uae30\ub2a5",id:"\ub313\uae00-\uae30\ub2a5",level:2},{value:"giscus \uc124\uc815",id:"giscus-\uc124\uc815",level:3},{value:"docusaurus \uc124\uc815",id:"docusaurus-\uc124\uc815",level:3},{value:"\uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30",id:"\uc54c\uace0\ub9ac\uc544-\uc124\uc815-\ubc0f-\uc9c1\uc811-\uad00\ub9ac\ud558\uae30",level:2},{value:"\uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778",id:"\uc54c\uace0\ub9ac\uc544-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\uc0dd\uc131-\ubc0f-\ud0a4-\ud655\uc778",level:3},{value:"\ud0a4 \uc0dd\uc131",id:"\ud0a4-\uc0dd\uc131",level:3},{value:".env \ud30c\uc77c \uc0dd\uc131",id:"env-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"config \ud30c\uc77c \uc0dd\uc131",id:"config-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1",id:"docker-\uc774\uc6a9\ud558\uc5ec-\ud06c\ub864\ub9c1",level:3},{value:"docusaurus \uc124\uc815",id:"docusaurus-\uc124\uc815-1",level:3},{value:"\ubd80\uac00 \uc124\uc815",id:"\ubd80\uac00-\uc124\uc815",level:2},{value:"\ud654\uba74 \uc0c1\ub2e8 Github Icon",id:"\ud654\uba74-\uc0c1\ub2e8-github-icon",level:3},{value:"\ucf54\ub4dc\ube14\ub7ed",id:"\ucf54\ub4dc\ube14\ub7ed",level:3},{value:"mermaid",id:"mermaid",level:3},{value:"\uad6d\uc81c\ud654 \uc124\uc815",id:"\uad6d\uc81c\ud654-\uc124\uc815",level:3},{value:"\ube14\ub85c\uadf8 \uae00 author",id:"\ube14\ub85c\uadf8-\uae00-author",level:3}],c={toc:u};function p(e){let{components:t,...s}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,s,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4. "),(0,r.kt)("h2",{id:"\uc124\uce58"},"\uc124\uce58"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io/docs/installation"},"\uacf5\uc2dd \ud648\ud398\uc774\uc9c0"),"\uc5d0 \ub4e4\uc5b4\uac00\uc11c \ucd5c\uc2e0 \ubc84\uc804\uc744 \uc124\uce58\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"yarn create docusaurus\n")),(0,r.kt)("h2",{id:"\ubc30\ud3ec"},"\ubc30\ud3ec"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io/docs/next/deployment#deploying-to-github-pages"},"\ubc30\ud3ec \uc548\ub0b4 \ubb38\uc11c"),(0,r.kt)("br",{parentName:"p"}),"\n","netlify\ub098 vercel \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ud50c\ub7ab\ud3fc\uc744 \ucd94\ucc9c\ud558\uace0 \uc788\uace0, \uac04\ub2e8\ud558\uace0, \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \ubc30\ud3ec\ub97c \ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 github pages\ub97c \uc774\uc6a9\ud574\uc11c \ubc30\ud3ec\ud558\ub294 \ubc29\ubc95\uc744 \uc124\uba85\ud55c\ub2e4."),(0,r.kt)("h3",{id:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac-\uc0dd\uc131"},"\ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131"),(0,r.kt)("p",null,"github pages\ub97c \uc774\uc6a9\ud558\ub824\uba74 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/greeng00se/greeng00se.github.io"},"\uc608\uc2dc"),"\uc640 \uac19\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"username.github.io")," \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub54c organization\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ",(0,r.kt)("inlineCode",{parentName:"p"},"organization.github.io")," \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("h3",{id:"\uc124\uc815-\ud30c\uc77c-\uc218\uc815"},"\uc124\uc815 \ud30c\uc77c \uc218\uc815"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"module.exports = {\n // ...\n url: 'https://greeng00se.github.io',\n baseUrl: '/',\n projectName: 'greeng00se.github.io',\n organizationName: 'greeng00se',\n trailingSlash: false,\n // ...\n};\n")),(0,r.kt)("h3",{id:"\ud1a0\ud070-\uc124\uc815"},"\ud1a0\ud070 \uc124\uc815"),(0,r.kt)("p",null,"github action\uc744 \uc704\ud574 \ubc30\ud3ec\uc6a9 \ud1a0\ud070\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uc5ec \uc0dd\uc131\ud55c \ub808\ud3ec\uc9c0\ud1a0\ub9ac\uc5d0 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 \ud1a0\ud070\uc744 \ud074\ub798\uc2dd \ubc29\uc2dd\uc73c\ub85c \uc0dd\uc131\ud588\uace0 \uc2a4\ucf54\ud504\ub294 ","[repo, user, workflow]"," \uc744 \uc124\uc815\ud588\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"github",src:n(29094).Z,width:"1598",height:"1670"})),(0,r.kt)("h3",{id:"\ube0c\ub79c\uce58-\uc0dd\uc131"},"\ube0c\ub79c\uce58 \uc0dd\uc131"),(0,r.kt)("p",null,"github\uc5d0\uc11c gh-pages \ube0c\ub79c\uce58\ub97c \ud558\ub098 \uc0dd\uc131\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","repository -> settings -> pages -> branch\uc5d0\uc11c \uc0dd\uc131\ud55c gh-pages\ub85c \ube0c\ub79c\uce58\ub97c \ubcc0\uacbd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc124\uc815\ud55c \ube0c\ub79c\uce58\uac00 \ubc30\ud3ec \ube0c\ub79c\uce58\uac00 \ub418\uba70, \ud574\ub2f9 \ube0c\ub79c\uce58\uc5d0 \uc788\ub294 \ud30c\uc77c\ub4e4\uc744 \uc774\uc6a9\ud574\uc11c \uc815\uc801 \uc6f9\uc0ac\uc774\ud2b8\ub97c \uc81c\uacf5\ud55c\ub2e4. "),(0,r.kt)("h3",{id:"\uc6cc\ud06c\ud50c\ub85c-\uc791\uc131"},"\uc6cc\ud06c\ud50c\ub85c \uc791\uc131"),(0,r.kt)("p",null,"Docusaurus 2.0 \uae30\uc900 Node.js 16.14 \uc774\uc0c1\uc758 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubc30\ud3ec\uc2dc\uc5d0\ub294 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c DEPLOY_TOKEN \uc744 \uc774\uc6a9\ud569\ub2c8\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml",metastring:'title=".github/workflows/deploy.yml"',title:'".github/workflows/deploy.yml"'},"name: blog\n\non:\n push:\n branches: [main]\n\njobs:\n deploy:\n name: Deploy to GitHub Pages\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n - uses: actions/setup-node@v3\n with:\n node-version: 18\n cache: yarn\n\n - name: Install dependencies\n run: yarn install --frozen-lockfile\n - name: Build website\n run: yarn build\n\n - name: Deploy to GitHub Pages\n uses: peaceiris/actions-gh-pages@v3\n with:\n github_token: ${{ secrets.DEPLOY_TOKEN }}\n publish_dir: ./build\n user_name: github-actions[bot]\n user_email: 41898282+github-actions[bot]@users.noreply.github.com\n")),(0,r.kt)("h2",{id:"\ub313\uae00-\uae30\ub2a5"},"\ub313\uae00 \uae30\ub2a5"),(0,r.kt)("p",null,"giscus\ub97c \uc774\uc6a9\ud558\uc5ec \ub313\uae00 \uae30\ub2a5\uc744 \ucd94\uac00\ud55c\ub2e4. "),(0,r.kt)("h3",{id:"giscus-\uc124\uc815"},"giscus \uc124\uc815"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"\uacf5\uac1c \uc800\uc7a5\uc18c\uc5ec\uc57c \ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ol"},"giscus \uc571\uc774 \uc124\uce58\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ol"},"Discussions \uae30\ub2a5\uc774 \ud574\ub2f9 \uc800\uc7a5\uc18c\uc5d0\uc11c \ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4.")),(0,r.kt)("p",null,"\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 ",(0,r.kt)("a",{parentName:"p",href:"https://giscus.app/ko"},"giscus"),"\ub97c \ud655\uc778\ud558\uc790."),(0,r.kt)("h3",{id:"docusaurus-\uc124\uc815"},"docusaurus \uc124\uc815"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docusaurus.io/ko/docs/next/swizzling"},"swizzling"),"\uc744 \uc774\uc6a9\ud558\uc5ec \ucef4\ud3ec\ub10c\ud2b8\ub97c \uac10\uc2fc\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc5d0 \uac8c\uc2dc\ubb3c\uc744 giscus\uac00 \ud3ec\ud568\ub41c \ub9ac\uc561\ud2b8 \ucef4\ud3ec\ub10c\ud2b8\ub85c \uac10\uc2f8\ub294 \ud615\ud0dc\uac00 \ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec BlogPostItem\uc744 \ucd94\ucd9c\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap\n")),(0,r.kt)("p",null,"\uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uba74 ",(0,r.kt)("inlineCode",{parentName:"p"},"/src/theme/BlogPostItem/index.js")," \uc704\uce58\uc5d0 \ud30c\uc77c\uc774 \uc0dd\uc131\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud30c\uc77c\uc758 \ub0b4\uc6a9\uc744 \uc544\ub798\uc640 \uac19\uc774 \uc218\uc815\ud558\uace0, \uc774\ub54c setAttribute \ubd80\ubd84\uc740 \uc801\uc808\ud558\uac8c \uc790\uc2e0\uc758 giscus \uc124\uc815\uc744 \uc774\uc6a9\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="/src/theme/BlogPostItem/index.js"',title:'"/src/theme/BlogPostItem/index.js"'},'import OriginalBlogPostItem from "@theme-original/BlogPostItem";\nimport React, { useEffect, useRef } from "react";\n// @ts-expect-error internal code\nimport { useColorMode } from "@docusaurus/theme-common";\nimport { useBlogPost } from "@docusaurus/theme-common/internal";\n\nconst giscusSelector = "iframe.giscus-frame";\n\nfunction BlogPostItem(props) {\n const { colorMode } = useColorMode();\n const { isBlogPostPage } = useBlogPost();\n const giscusTheme = colorMode === "dark" ? "dark" : "light";\n const containerRef = useRef(null);\n\n useEffect(() => {\n if (!isBlogPostPage) return;\n\n const giscusEl = containerRef.current.querySelector(giscusSelector);\n\n const createGiscusEl = () => {\n const script = document.createElement("script");\n\n script.src = "https://giscus.app/client.js";\n script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");\n script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");\n script.setAttribute("data-category", "Announcements");\n script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");\n script.setAttribute("data-mapping", "pathname");\n script.setAttribute("data-strict", "0");\n script.setAttribute("data-reactions-enabled", "1");\n script.setAttribute("data-emit-metadata", "0");\n script.setAttribute("data-input-position", "bottom");\n script.setAttribute("data-theme", giscusTheme);\n script.setAttribute("data-lang", "ko");\n script.crossOrigin = "anonymous";\n script.async = true;\n \n containerRef.current.appendChild(script);\n };\n\n const postThemeMessage = () => {\n const message = {\n setConfig: {\n theme: giscusTheme,\n }\n };\n\n giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");\n };\n\n giscusEl ? postThemeMessage() : createGiscusEl();\n }, [giscusTheme]);\n\n return (\n <>\n <OriginalBlogPostItem {...props} />\n {isBlogPostPage && <div ref={containerRef} />}\n </>\n );\n}\n\nexport default BlogPostItem;\n')),(0,r.kt)("h2",{id:"\uc54c\uace0\ub9ac\uc544-\uc124\uc815-\ubc0f-\uc9c1\uc811-\uad00\ub9ac\ud558\uae30"},"\uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30"),(0,r.kt)("p",null,"\uc54c\uace0\ub9ac\uc544\ub97c \uc0ac\uc6a9\ud558\uba74 \uac80\uc0c9 \uae30\ub2a5\uc744 \ucd94\uac00\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc720\ub8cc \ud50c\ub79c\uc774\ub098 netlify\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ud06c\ub864\ub7ec\ub97c \ub530\ub85c \uc81c\uacf5\ud574 \uc8fc\ub294 \uac83 \uac19\ub2e4. "),(0,r.kt)("p",null,"\ubb34\ub8cc \ud50c\ub79c\uc740 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uacfc, ",(0,r.kt)("a",{parentName:"p",href:"https://docsearch.algolia.com/"},"docsearch"),"\ub97c \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","docsearch\uc5d0 \ub4f1\ub85d\ud55c\ub2e4\uba74 \uc77c\uc8fc\uc77c\uc5d0 \ud55c \ubc88\uc529 \ud06c\ub864\ub9c1\uc774 \uc9c4\ud589\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docsearch.algolia.com/docs/legacy/run-your-own/"},"\uc9c1\uc811 \uc778\ub371\uc2a4 \uc218\uc9d1")," "),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://docsearch.algolia.com/docs/legacy/config-file"},"\uc124\uc815 \ud30c\uc77c"))),(0,r.kt)("h3",{id:"\uc54c\uace0\ub9ac\uc544-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\uc0dd\uc131-\ubc0f-\ud0a4-\ud655\uc778"},"\uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778"),(0,r.kt)("p",null,"\ud68c\uc6d0\uac00\uc785\uc744 \ud558\uace0 \uc0c8\ub85c\uc6b4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131\uc744 \ub204\ub978\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc0dd\uc131\uc744 \ub2e4 \ub9c8\uce58\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 api \ud0a4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"algolia",src:n(41785).Z,width:"3194",height:"1520"})),(0,r.kt)("h3",{id:"\ud0a4-\uc0dd\uc131"},"\ud0a4 \uc0dd\uc131"),(0,r.kt)("p",null,"\uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\uae30 \uc704\ud55c \ud0a4\ub97c \uc0dd\uc131\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","addObject, editSettings, deleteIndex acl(\uc811\uadfc \uc81c\uc5b4 \ubaa9\ub85d)\uc774 \uc788\uc73c\uba74 \ub41c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"key",src:n(4730).Z,width:"2496",height:"832"})),(0,r.kt)("h3",{id:"env-\ud30c\uc77c-\uc0dd\uc131"},".env \ud30c\uc77c \uc0dd\uc131"),(0,r.kt)("p",null,"\ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354 \uc0c1\ub2e8\uc5d0 .env \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title=".env"',title:'".env"'},"APPLICATION_ID=MVIU5UEMOM\nAPI_KEY=\uc778\ub371\uc2a4_\uc0dd\uc131\uc6a9_\ud0a4\n")),(0,r.kt)("h3",{id:"config-\ud30c\uc77c-\uc0dd\uc131"},"config \ud30c\uc77c \uc0dd\uc131"),(0,r.kt)("p",null,"\ub9c8\ucc2c\uac00\uc9c0\ub85c \ucd5c\uc0c1\ub2e8\uc5d0 config.json \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4.\n\uc124\uc815 \ud30c\uc77c\uc740 \ud574\ub2f9 ",(0,r.kt)("a",{parentName:"p",href:"https://docsearch.algolia.com/docs/legacy/config-file"},"\ub9c1\ud06c"),"\ub97c \ucc38\uace0\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub610\ub294 Docusaurus\uc758 ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/algolia/docsearch-configs/blob/master/configs/docusaurus-2.json"},"\uc124\uc815 \ud30c\uc77c"),"\uc744 \ucc38\uace0\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="config.json"',title:'"config.json"'},'{\n "index_name": "teco",\n "start_urls": [\n "https://teco-chat.github.io/"\n ],\n "sitemap_urls": [\n "https://teco-chat.github.io/sitemap.xml"\n ],\n "sitemap_alternate_links": true,\n "stop_urls": [\n "/tests"\n ],\n "selectors": {\n "lvl0": {\n "selector": "(//ul[contains(@class,\'menu__list\')]//a[contains(@class, \'menu__link menu__link--sublist menu__link--active\')]/text() | //nav[contains(@class, \'navbar\')]//a[contains(@class, \'navbar__link--active\')]/text())[last()]",\n "type": "xpath",\n "global": true,\n "default_value": "Documentation"\n },\n "lvl1": "header h1",\n "lvl2": "article h2",\n "lvl3": "article h3",\n "lvl4": "article h4",\n "lvl5": "article h5, article td:first-child",\n "lvl6": "article h6",\n "text": "article p, article li, article td:last-child"\n },\n "strip_chars": " .,;:#",\n "custom_settings": {\n "separatorsToIndex": "_",\n "attributesForFaceting": [\n "language",\n "version",\n "type",\n "docusaurus_tag"\n ],\n "attributesToRetrieve": [\n "hierarchy",\n "content",\n "anchor",\n "url",\n "url_without_anchor",\n "type"\n ]\n },\n "conversation_id": [\n "833762294"\n ],\n "nb_hits": 46250\n}\n')),(0,r.kt)("h3",{id:"docker-\uc774\uc6a9\ud558\uc5ec-\ud06c\ub864\ub9c1"},"docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1"),(0,r.kt)("p",null,"docker\uc640 jq\uac00 \ud544\uc694\ud558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","jq\uac00 \uc124\uce58\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc73c\uba74 mac \uae30\uc900 brew\ub97c \uc774\uc6a9\ud574\uc11c \uc124\uce58\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"brew install jq\n")),(0,r.kt)("p",null,"\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec .env\uc640 config.json\uc744 \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1\uc744 \ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper\n')),(0,r.kt)("h3",{id:"docusaurus-\uc124\uc815-1"},"docusaurus \uc124\uc815"),(0,r.kt)("p",null,"\uc804\uc5d0 \ud655\uc778\ud55c APP ID, Search-Only API KEY, IndexName\uc744 \uc774\uc6a9\ud558\uc5ec docusaurus.config \ud30c\uc77c\uc5d0 \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"themeConfig:\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n ({\n ...\n algolia: {\n appId: 'MVIU5UEMOM', // Application ID\n apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key\n indexName: 'teco', // config.json\uc5d0 \uc124\uc815\ud55c \uc778\ub371\uc2a4\uba85\n contextualSearch: true,\n },\n })\n")),(0,r.kt)("h2",{id:"\ubd80\uac00-\uc124\uc815"},"\ubd80\uac00 \uc124\uc815"),(0,r.kt)("h3",{id:"\ud654\uba74-\uc0c1\ub2e8-github-icon"},"\ud654\uba74 \uc0c1\ub2e8 Github Icon"),(0,r.kt)("p",null,"\ud30c\uc77c \ucd5c\ud558\ub2e8\uc5d0 \uc544\ub798 css \uad6c\ubb38\uc744 \ucd94\uac00\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-css",metastring:'title="/src/css/custom.css"',title:'"/src/css/custom.css"'},".header-github-link:hover {\n opacity: 0.6;\n}\n\n.header-github-link:before {\n content: '';\n width: 24px;\n height: 24px;\n display: flex;\n background: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")\n no-repeat;\n}\n\nhtml[data-theme='dark'] .header-github-link:before {\n background: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")\n no-repeat;\n}\n")),(0,r.kt)("p",null,"themeconfig -> navbar\uc5d0 github link\ub97c \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"navbar: {\n title: 'HELLO',\n items: [\n {\n href: 'https://github.com/greeng00se',\n position: 'right',\n className: 'header-github-link',\n 'aria-label': 'GitHub repository',\n },\n ],\n},\n")),(0,r.kt)("h3",{id:"\ucf54\ub4dc\ube14\ub7ed"},"\ucf54\ub4dc\ube14\ub7ed"),(0,r.kt)("p",null,"java\ub098 kotlin\uc758 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ud558\uc774\ub77c\uc774\ud305\uc744 \uc9c0\uc6d0\ud574 \uc8fc\uc9c0 \uc54a\ub294\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","prism \uc124\uc815\uc744 \uc544\ub798\uc640 \uac19\uc774 \ubcc0\uacbd\ud574 \uc900\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"prism: {\n theme: lightCodeTheme,\n darkTheme: darkCodeTheme,\n additionalLanguages: ['java', 'kotlin'],\n}\n")),(0,r.kt)("h3",{id:"mermaid"},"mermaid"),(0,r.kt)("p",null,"mermaid\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 ",(0,r.kt)("inlineCode",{parentName:"p"},"@docusaurus/theme-mermaid")," \ub97c \uc124\uce58\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"yarn add @docusaurus/theme-mermaid\n")),(0,r.kt)("p",null,"\uc124\uce58 \ud6c4 \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\uc744 \ucd94\uac00\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"const config = {\n ...\n markdown: {\n mermaid: true,\n },\n themes: [\n '@docusaurus/theme-mermaid'\n ],\n};\n")),(0,r.kt)("p",null,"themeConfig\uc5d0\uc11c mermaid\uc758 \ud14c\ub9c8\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},"themeConfig:\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n ({\n ...\n mermaid: {\n theme: {\n light: 'neutral', \n dark: 'dark'\n },\n },\n }),\n")),(0,r.kt)("h3",{id:"\uad6d\uc81c\ud654-\uc124\uc815"},"\uad6d\uc81c\ud654 \uc124\uc815"),(0,r.kt)("p",null,"\uad6d\uc81c\ud654 \uc124\uc815\uc744 \ud55c\ub2e4\uba74 ",(0,r.kt)("inlineCode",{parentName:"p"},"Older Entries")," \ud615\ud0dc\uc758 \uc124\uba85\uc774 ",(0,r.kt)("inlineCode",{parentName:"p"},"\ub2e4\uc74c \ud398\uc774\uc9c0")," \ub85c \ubcc0\uacbd\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc124\uc815\ud30c\uc77c\uc5d0\uc11c i18n\uc5d0 \uc788\ub294 \ub85c\ucf00\uc77c \uc124\uc815\uc744 ko\ub85c \ubcc0\uacbd\ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config"',title:'"docusaurus.config"'},'i18n: {\n defaultLocale: "ko",\n locales: ["ko"],\n},\n')),(0,r.kt)("h3",{id:"\ube14\ub85c\uadf8-\uae00-author"},"\ube14\ub85c\uadf8 \uae00 author"),(0,r.kt)("p",null,"\ud300\uc6d0 \ubcc4\ub85c \ubb38\uc11c\ub97c \uad00\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 \uc5b4\ub5a4 \ud300\uc6d0\uc774 \uae00\uc744 \uc791\uc131\ud588\ub294\uc9c0 \uc124\uc815\ud574\uc57c \ud55c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"author",src:n(31897).Z,width:"2362",height:"1076"})),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"authors.yml")," \ud30c\uc77c\uc744 \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790\uc5d0 \ub300\ud55c \uae30\ubcf8 \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml",metastring:'title="/blog/authors.yml"',title:'"/blog/authors.yml"'},"herb:\n name: \ud5c8\ube0c\n title: Backend\n url: https://github.com/greeng00se\n image_url: https://github.com/greeng00se.png\n\nmallang:\n name: \ub9d0\ub791\n title: Backend\n url: https://github.com/shin-mallang\n image_url: https://github.com/shin-mallang.png\n")),(0,r.kt)("p",null,"\ube14\ub85c\uadf8 \uae00\uc744 \uc791\uc131\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc774 authors\uc5d0 \ub123\uc5b4\uc8fc\uae30\ub9cc \ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mdx"},"---\nslug: 1\ntitle: Hello World\nauthors: [herb, mallang]\ntags: [hello, docusaurus]\n---\n\n\uccab \ubc88\uc9f8 \ubb38\uc11c \ub0b4\uc6a9\n")))}p.isMDXComponent=!0},41785:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/algolia-3dbac5c1606f7f0daed9cb27a429db50.png"},31897:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/author-1bd517bb7763257e2139e1063fd92492.png"},29094:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/github-d866f69755a1e17d4f17a262bd30d56d.png"},4730:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/key-2d0b59e69e9ca0b21c49b76159266e74.png"}}]); \ No newline at end of file diff --git a/assets/js/be497a8d.ef83736d.js b/assets/js/be497a8d.ef83736d.js new file mode 100644 index 000000000..ff24d203f --- /dev/null +++ b/assets/js/be497a8d.ef83736d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6172],{92971:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>o});var t=s(85893),r=s(3905);const i={title:"Docusaurus",slug:"docusaurus",tags:["Documentation"]},a=void 0,c={permalink:"/docusaurus",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",source:"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",title:"Docusaurus",description:"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4.",date:"2023-06-18T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 18\uc77c",tags:[{label:"Documentation",permalink:"/tags/documentation"}],readingTime:10.095,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Docusaurus",slug:"docusaurus",tags:["Documentation"]},unlisted:!1,prevItem:{title:"\uc6f9\uc18c\ucf13",permalink:"/websocket"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",permalink:"/woowacourse-level2-retrospective"}},l={authorsImageUrls:[]},o=[{value:"\uc124\uce58",id:"\uc124\uce58",level:2},{value:"\ubc30\ud3ec",id:"\ubc30\ud3ec",level:2},{value:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131",id:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac-\uc0dd\uc131",level:3},{value:"\uc124\uc815 \ud30c\uc77c \uc218\uc815",id:"\uc124\uc815-\ud30c\uc77c-\uc218\uc815",level:3},{value:"\ud1a0\ud070 \uc124\uc815",id:"\ud1a0\ud070-\uc124\uc815",level:3},{value:"\ube0c\ub79c\uce58 \uc0dd\uc131",id:"\ube0c\ub79c\uce58-\uc0dd\uc131",level:3},{value:"\uc6cc\ud06c\ud50c\ub85c \uc791\uc131",id:"\uc6cc\ud06c\ud50c\ub85c-\uc791\uc131",level:3},{value:"\ub313\uae00 \uae30\ub2a5",id:"\ub313\uae00-\uae30\ub2a5",level:2},{value:"giscus \uc124\uc815",id:"giscus-\uc124\uc815",level:3},{value:"docusaurus \uc124\uc815",id:"docusaurus-\uc124\uc815",level:3},{value:"\uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30",id:"\uc54c\uace0\ub9ac\uc544-\uc124\uc815-\ubc0f-\uc9c1\uc811-\uad00\ub9ac\ud558\uae30",level:2},{value:"\uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778",id:"\uc54c\uace0\ub9ac\uc544-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\uc0dd\uc131-\ubc0f-\ud0a4-\ud655\uc778",level:3},{value:"\ud0a4 \uc0dd\uc131",id:"\ud0a4-\uc0dd\uc131",level:3},{value:".env \ud30c\uc77c \uc0dd\uc131",id:"env-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"config \ud30c\uc77c \uc0dd\uc131",id:"config-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1",id:"docker-\uc774\uc6a9\ud558\uc5ec-\ud06c\ub864\ub9c1",level:3},{value:"docusaurus \uc124\uc815",id:"docusaurus-\uc124\uc815-1",level:3},{value:"\ubd80\uac00 \uc124\uc815",id:"\ubd80\uac00-\uc124\uc815",level:2},{value:"\ud654\uba74 \uc0c1\ub2e8 Github Icon",id:"\ud654\uba74-\uc0c1\ub2e8-github-icon",level:3},{value:"\ucf54\ub4dc\ube14\ub7ed",id:"\ucf54\ub4dc\ube14\ub7ed",level:3},{value:"mermaid",id:"mermaid",level:3},{value:"\uad6d\uc81c\ud654 \uc124\uc815",id:"\uad6d\uc81c\ud654-\uc124\uc815",level:3},{value:"\ube14\ub85c\uadf8 \uae00 author",id:"\ube14\ub85c\uadf8-\uae00-author",level:3}];function u(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,r.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"\ud300 \ube14\ub85c\uadf8 \ub610\ub294 \ubb38\uc11c\ud654\ub97c \uc704\ud574 Docusaurus\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud558\ub824\uace0 \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.h2,{id:"\uc124\uce58",children:"\uc124\uce58"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docusaurus.io/docs/installation",children:"\uacf5\uc2dd \ud648\ud398\uc774\uc9c0"}),"\uc5d0 \ub4e4\uc5b4\uac00\uc11c \ucd5c\uc2e0 \ubc84\uc804\uc744 \uc124\uce58\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn create docusaurus\n"})}),"\n",(0,t.jsx)(n.h2,{id:"\ubc30\ud3ec",children:"\ubc30\ud3ec"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docusaurus.io/docs/next/deployment#deploying-to-github-pages",children:"\ubc30\ud3ec \uc548\ub0b4 \ubb38\uc11c"}),(0,t.jsx)(n.br,{}),"\n","netlify\ub098 vercel \uac19\uc740 \uc11c\ubc84\ub9ac\uc2a4 \ud50c\ub7ab\ud3fc\uc744 \ucd94\ucc9c\ud558\uace0 \uc788\uace0, \uac04\ub2e8\ud558\uace0, \ube60\ub978 \uc2dc\uac04 \uc548\uc5d0 \ubc30\ud3ec\ub97c \ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 github pages\ub97c \uc774\uc6a9\ud574\uc11c \ubc30\ud3ec\ud558\ub294 \ubc29\ubc95\uc744 \uc124\uba85\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac-\uc0dd\uc131",children:"\ub808\ud3ec\uc9c0\ud1a0\ub9ac \uc0dd\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["github pages\ub97c \uc774\uc6a9\ud558\ub824\uba74 ",(0,t.jsx)(n.a,{href:"https://github.com/greeng00se/greeng00se.github.io",children:"\uc608\uc2dc"}),"\uc640 \uac19\uc774 ",(0,t.jsx)(n.code,{children:"username.github.io"})," \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc57c \ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub54c organization\uc744 \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ",(0,t.jsx)(n.code,{children:"organization.github.io"})," \ud615\ud0dc\uc758 \ub808\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \uc0dd\uc131\ud574\uc11c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc124\uc815-\ud30c\uc77c-\uc218\uc815",children:"\uc124\uc815 \ud30c\uc77c \uc218\uc815"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"module.exports = {\n // ...\n url: 'https://greeng00se.github.io',\n baseUrl: '/',\n projectName: 'greeng00se.github.io',\n organizationName: 'greeng00se',\n trailingSlash: false,\n // ...\n};\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\ud1a0\ud070-\uc124\uc815",children:"\ud1a0\ud070 \uc124\uc815"}),"\n",(0,t.jsxs)(n.p,{children:["github action\uc744 \uc704\ud574 \ubc30\ud3ec\uc6a9 \ud1a0\ud070\uc744 \ud558\ub098 \uc0dd\uc131\ud558\uc5ec \uc0dd\uc131\ud55c \ub808\ud3ec\uc9c0\ud1a0\ub9ac\uc5d0 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 \ud1a0\ud070\uc744 \ud074\ub798\uc2dd \ubc29\uc2dd\uc73c\ub85c \uc0dd\uc131\ud588\uace0 \uc2a4\ucf54\ud504\ub294 [repo, user, workflow] \uc744 \uc124\uc815\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"github",src:s(29094).Z+"",width:"1598",height:"1670"})}),"\n",(0,t.jsx)(n.h3,{id:"\ube0c\ub79c\uce58-\uc0dd\uc131",children:"\ube0c\ub79c\uce58 \uc0dd\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["github\uc5d0\uc11c gh-pages \ube0c\ub79c\uce58\ub97c \ud558\ub098 \uc0dd\uc131\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","repository -> settings -> pages -> branch\uc5d0\uc11c \uc0dd\uc131\ud55c gh-pages\ub85c \ube0c\ub79c\uce58\ub97c \ubcc0\uacbd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc124\uc815\ud55c \ube0c\ub79c\uce58\uac00 \ubc30\ud3ec \ube0c\ub79c\uce58\uac00 \ub418\uba70, \ud574\ub2f9 \ube0c\ub79c\uce58\uc5d0 \uc788\ub294 \ud30c\uc77c\ub4e4\uc744 \uc774\uc6a9\ud574\uc11c \uc815\uc801 \uc6f9\uc0ac\uc774\ud2b8\ub97c \uc81c\uacf5\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc6cc\ud06c\ud50c\ub85c-\uc791\uc131",children:"\uc6cc\ud06c\ud50c\ub85c \uc791\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["Docusaurus 2.0 \uae30\uc900 Node.js 16.14 \uc774\uc0c1\uc758 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud574\uc57c \ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc30\ud3ec\uc2dc\uc5d0\ub294 Repository secrets\uc73c\ub85c \uc124\uc815\ud55c DEPLOY_TOKEN \uc744 \uc774\uc6a9\ud569\ub2c8\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yml",metastring:'title=".github/workflows/deploy.yml"',children:"name: blog\n\non:\n push:\n branches: [main]\n\njobs:\n deploy:\n name: Deploy to GitHub Pages\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v2\n - uses: actions/setup-node@v3\n with:\n node-version: 18\n cache: yarn\n\n - name: Install dependencies\n run: yarn install --frozen-lockfile\n - name: Build website\n run: yarn build\n\n - name: Deploy to GitHub Pages\n uses: peaceiris/actions-gh-pages@v3\n with:\n github_token: ${{ secrets.DEPLOY_TOKEN }}\n publish_dir: ./build\n user_name: github-actions[bot]\n user_email: 41898282+github-actions[bot]@users.noreply.github.com\n"})}),"\n",(0,t.jsx)(n.h2,{id:"\ub313\uae00-\uae30\ub2a5",children:"\ub313\uae00 \uae30\ub2a5"}),"\n",(0,t.jsx)(n.p,{children:"giscus\ub97c \uc774\uc6a9\ud558\uc5ec \ub313\uae00 \uae30\ub2a5\uc744 \ucd94\uac00\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.h3,{id:"giscus-\uc124\uc815",children:"giscus \uc124\uc815"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"\uacf5\uac1c \uc800\uc7a5\uc18c\uc5ec\uc57c \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"giscus \uc571\uc774 \uc124\uce58\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"Discussions \uae30\ub2a5\uc774 \ud574\ub2f9 \uc800\uc7a5\uc18c\uc5d0\uc11c \ud65c\uc131\ud654\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 ",(0,t.jsx)(n.a,{href:"https://giscus.app/ko",children:"giscus"}),"\ub97c \ud655\uc778\ud558\uc790."]}),"\n",(0,t.jsx)(n.h3,{id:"docusaurus-\uc124\uc815",children:"docusaurus \uc124\uc815"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docusaurus.io/ko/docs/next/swizzling",children:"swizzling"}),"\uc744 \uc774\uc6a9\ud558\uc5ec \ucef4\ud3ec\ub10c\ud2b8\ub97c \uac10\uc2fc\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae30\uc874\uc5d0 \uac8c\uc2dc\ubb3c\uc744 giscus\uac00 \ud3ec\ud568\ub41c \ub9ac\uc561\ud2b8 \ucef4\ud3ec\ub10c\ud2b8\ub85c \uac10\uc2f8\ub294 \ud615\ud0dc\uac00 \ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec BlogPostItem\uc744 \ucd94\ucd9c\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap\n"})}),"\n",(0,t.jsxs)(n.p,{children:["\uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uba74 ",(0,t.jsx)(n.code,{children:"/src/theme/BlogPostItem/index.js"})," \uc704\uce58\uc5d0 \ud30c\uc77c\uc774 \uc0dd\uc131\ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud30c\uc77c\uc758 \ub0b4\uc6a9\uc744 \uc544\ub798\uc640 \uac19\uc774 \uc218\uc815\ud558\uace0, \uc774\ub54c setAttribute \ubd80\ubd84\uc740 \uc801\uc808\ud558\uac8c \uc790\uc2e0\uc758 giscus \uc124\uc815\uc744 \uc774\uc6a9\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="/src/theme/BlogPostItem/index.js"',children:'import OriginalBlogPostItem from "@theme-original/BlogPostItem";\nimport React, { useEffect, useRef } from "react";\n// @ts-expect-error internal code\nimport { useColorMode } from "@docusaurus/theme-common";\nimport { useBlogPost } from "@docusaurus/theme-common/internal";\n\nconst giscusSelector = "iframe.giscus-frame";\n\nfunction BlogPostItem(props) {\n const { colorMode } = useColorMode();\n const { isBlogPostPage } = useBlogPost();\n const giscusTheme = colorMode === "dark" ? "dark" : "light";\n const containerRef = useRef(null);\n\n useEffect(() => {\n if (!isBlogPostPage) return;\n\n const giscusEl = containerRef.current.querySelector(giscusSelector);\n\n const createGiscusEl = () => {\n const script = document.createElement("script");\n\n script.src = "https://giscus.app/client.js";\n script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");\n script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");\n script.setAttribute("data-category", "Announcements");\n script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");\n script.setAttribute("data-mapping", "pathname");\n script.setAttribute("data-strict", "0");\n script.setAttribute("data-reactions-enabled", "1");\n script.setAttribute("data-emit-metadata", "0");\n script.setAttribute("data-input-position", "bottom");\n script.setAttribute("data-theme", giscusTheme);\n script.setAttribute("data-lang", "ko");\n script.crossOrigin = "anonymous";\n script.async = true;\n \n containerRef.current.appendChild(script);\n };\n\n const postThemeMessage = () => {\n const message = {\n setConfig: {\n theme: giscusTheme,\n }\n };\n\n giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");\n };\n\n giscusEl ? postThemeMessage() : createGiscusEl();\n }, [giscusTheme]);\n\n return (\n <>\n <OriginalBlogPostItem {...props} />\n {isBlogPostPage && <div ref={containerRef} />}\n </>\n );\n}\n\nexport default BlogPostItem;\n'})}),"\n",(0,t.jsx)(n.h2,{id:"\uc54c\uace0\ub9ac\uc544-\uc124\uc815-\ubc0f-\uc9c1\uc811-\uad00\ub9ac\ud558\uae30",children:"\uc54c\uace0\ub9ac\uc544 \uc124\uc815 \ubc0f \uc9c1\uc811 \uad00\ub9ac\ud558\uae30"}),"\n",(0,t.jsxs)(n.p,{children:["\uc54c\uace0\ub9ac\uc544\ub97c \uc0ac\uc6a9\ud558\uba74 \uac80\uc0c9 \uae30\ub2a5\uc744 \ucd94\uac00\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc720\ub8cc \ud50c\ub79c\uc774\ub098 netlify\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 \ud06c\ub864\ub7ec\ub97c \ub530\ub85c \uc81c\uacf5\ud574 \uc8fc\ub294 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\ubb34\ub8cc \ud50c\ub79c\uc740 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uacfc, ",(0,t.jsx)(n.a,{href:"https://docsearch.algolia.com/",children:"docsearch"}),"\ub97c \uc774\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","docsearch\uc5d0 \ub4f1\ub85d\ud55c\ub2e4\uba74 \uc77c\uc8fc\uc77c\uc5d0 \ud55c \ubc88\uc529 \ud06c\ub864\ub9c1\uc774 \uc9c4\ud589\ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \uae00\uc5d0\uc11c\ub294 \uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\ub294 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docsearch.algolia.com/docs/legacy/run-your-own/",children:"\uc9c1\uc811 \uc778\ub371\uc2a4 \uc218\uc9d1"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docsearch.algolia.com/docs/legacy/config-file",children:"\uc124\uc815 \ud30c\uc77c"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc54c\uace0\ub9ac\uc544-\uc560\ud50c\ub9ac\ucf00\uc774\uc158-\uc0dd\uc131-\ubc0f-\ud0a4-\ud655\uc778",children:"\uc54c\uace0\ub9ac\uc544 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131 \ubc0f \ud0a4 \ud655\uc778"}),"\n",(0,t.jsxs)(n.p,{children:["\ud68c\uc6d0\uac00\uc785\uc744 \ud558\uace0 \uc0c8\ub85c\uc6b4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0dd\uc131\uc744 \ub204\ub978\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc0dd\uc131\uc744 \ub2e4 \ub9c8\uce58\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 api \ud0a4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"algolia",src:s(41785).Z+"",width:"3194",height:"1520"})}),"\n",(0,t.jsx)(n.h3,{id:"\ud0a4-\uc0dd\uc131",children:"\ud0a4 \uc0dd\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["\uc9c1\uc811 \uc778\ub371\uc2a4\ub97c \uc218\uc9d1\ud558\uae30 \uc704\ud55c \ud0a4\ub97c \uc0dd\uc131\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","addObject, editSettings, deleteIndex acl(\uc811\uadfc \uc81c\uc5b4 \ubaa9\ub85d)\uc774 \uc788\uc73c\uba74 \ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"key",src:s(4730).Z+"",width:"2496",height:"832"})}),"\n",(0,t.jsx)(n.h3,{id:"env-\ud30c\uc77c-\uc0dd\uc131",children:".env \ud30c\uc77c \uc0dd\uc131"}),"\n",(0,t.jsx)(n.p,{children:"\ud504\ub85c\uc81d\ud2b8 \ud3f4\ub354 \uc0c1\ub2e8\uc5d0 .env \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",metastring:'title=".env"',children:"APPLICATION_ID=MVIU5UEMOM\nAPI_KEY=\uc778\ub371\uc2a4_\uc0dd\uc131\uc6a9_\ud0a4\n"})}),"\n",(0,t.jsx)(n.h3,{id:"config-\ud30c\uc77c-\uc0dd\uc131",children:"config \ud30c\uc77c \uc0dd\uc131"}),"\n",(0,t.jsxs)(n.p,{children:["\ub9c8\ucc2c\uac00\uc9c0\ub85c \ucd5c\uc0c1\ub2e8\uc5d0 config.json \ud30c\uc77c\uc744 \uc0dd\uc131\ud55c\ub2e4.\n\uc124\uc815 \ud30c\uc77c\uc740 \ud574\ub2f9 ",(0,t.jsx)(n.a,{href:"https://docsearch.algolia.com/docs/legacy/config-file",children:"\ub9c1\ud06c"}),"\ub97c \ucc38\uace0\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ub294 Docusaurus\uc758 ",(0,t.jsx)(n.a,{href:"https://github.com/algolia/docsearch-configs/blob/master/configs/docusaurus-2.json",children:"\uc124\uc815 \ud30c\uc77c"}),"\uc744 \ucc38\uace0\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",metastring:'title="config.json"',children:'{\n "index_name": "teco",\n "start_urls": [\n "https://teco-chat.github.io/"\n ],\n "sitemap_urls": [\n "https://teco-chat.github.io/sitemap.xml"\n ],\n "sitemap_alternate_links": true,\n "stop_urls": [\n "/tests"\n ],\n "selectors": {\n "lvl0": {\n "selector": "(//ul[contains(@class,\'menu__list\')]//a[contains(@class, \'menu__link menu__link--sublist menu__link--active\')]/text() | //nav[contains(@class, \'navbar\')]//a[contains(@class, \'navbar__link--active\')]/text())[last()]",\n "type": "xpath",\n "global": true,\n "default_value": "Documentation"\n },\n "lvl1": "header h1",\n "lvl2": "article h2",\n "lvl3": "article h3",\n "lvl4": "article h4",\n "lvl5": "article h5, article td:first-child",\n "lvl6": "article h6",\n "text": "article p, article li, article td:last-child"\n },\n "strip_chars": " .,;:#",\n "custom_settings": {\n "separatorsToIndex": "_",\n "attributesForFaceting": [\n "language",\n "version",\n "type",\n "docusaurus_tag"\n ],\n "attributesToRetrieve": [\n "hierarchy",\n "content",\n "anchor",\n "url",\n "url_without_anchor",\n "type"\n ]\n },\n "conversation_id": [\n "833762294"\n ],\n "nb_hits": 46250\n}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"docker-\uc774\uc6a9\ud558\uc5ec-\ud06c\ub864\ub9c1",children:"docker \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1"}),"\n",(0,t.jsxs)(n.p,{children:["docker\uc640 jq\uac00 \ud544\uc694\ud558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","jq\uac00 \uc124\uce58\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc73c\uba74 mac \uae30\uc900 brew\ub97c \uc774\uc6a9\ud574\uc11c \uc124\uce58\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install jq\n"})}),"\n",(0,t.jsx)(n.p,{children:"\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec .env\uc640 config.json\uc744 \uc774\uc6a9\ud558\uc5ec \ud06c\ub864\ub9c1\uc744 \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper\n'})}),"\n",(0,t.jsx)(n.h3,{id:"docusaurus-\uc124\uc815-1",children:"docusaurus \uc124\uc815"}),"\n",(0,t.jsx)(n.p,{children:"\uc804\uc5d0 \ud655\uc778\ud55c APP ID, Search-Only API KEY, IndexName\uc744 \uc774\uc6a9\ud558\uc5ec docusaurus.config \ud30c\uc77c\uc5d0 \uc124\uc815\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"themeConfig:\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n ({\n ...\n algolia: {\n appId: 'MVIU5UEMOM', // Application ID\n apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key\n indexName: 'teco', // config.json\uc5d0 \uc124\uc815\ud55c \uc778\ub371\uc2a4\uba85\n contextualSearch: true,\n },\n })\n"})}),"\n",(0,t.jsx)(n.h2,{id:"\ubd80\uac00-\uc124\uc815",children:"\ubd80\uac00 \uc124\uc815"}),"\n",(0,t.jsx)(n.h3,{id:"\ud654\uba74-\uc0c1\ub2e8-github-icon",children:"\ud654\uba74 \uc0c1\ub2e8 Github Icon"}),"\n",(0,t.jsx)(n.p,{children:"\ud30c\uc77c \ucd5c\ud558\ub2e8\uc5d0 \uc544\ub798 css \uad6c\ubb38\uc744 \ucd94\uac00\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-css",metastring:'title="/src/css/custom.css"',children:".header-github-link:hover {\n opacity: 0.6;\n}\n\n.header-github-link:before {\n content: '';\n width: 24px;\n height: 24px;\n display: flex;\n background: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")\n no-repeat;\n}\n\nhtml[data-theme='dark'] .header-github-link:before {\n background: url(\"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E\")\n no-repeat;\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"themeconfig -> navbar\uc5d0 github link\ub97c \uc124\uc815\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"navbar: {\n title: 'HELLO',\n items: [\n {\n href: 'https://github.com/greeng00se',\n position: 'right',\n className: 'header-github-link',\n 'aria-label': 'GitHub repository',\n },\n ],\n},\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\ucf54\ub4dc\ube14\ub7ed",children:"\ucf54\ub4dc\ube14\ub7ed"}),"\n",(0,t.jsxs)(n.p,{children:["java\ub098 kotlin\uc758 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ud558\uc774\ub77c\uc774\ud305\uc744 \uc9c0\uc6d0\ud574 \uc8fc\uc9c0 \uc54a\ub294\ub2e4.",(0,t.jsx)(n.br,{}),"\n","prism \uc124\uc815\uc744 \uc544\ub798\uc640 \uac19\uc774 \ubcc0\uacbd\ud574 \uc900\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"prism: {\n theme: lightCodeTheme,\n darkTheme: darkCodeTheme,\n additionalLanguages: ['java', 'kotlin'],\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"mermaid",children:"mermaid"}),"\n",(0,t.jsxs)(n.p,{children:["mermaid\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 ",(0,t.jsx)(n.code,{children:"@docusaurus/theme-mermaid"})," \ub97c \uc124\uce58\ud574\uc57c \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn add @docusaurus/theme-mermaid\n"})}),"\n",(0,t.jsx)(n.p,{children:"\uc124\uce58 \ud6c4 \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\uc744 \ucd94\uac00\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"const config = {\n ...\n markdown: {\n mermaid: true,\n },\n themes: [\n '@docusaurus/theme-mermaid'\n ],\n};\n"})}),"\n",(0,t.jsx)(n.p,{children:"themeConfig\uc5d0\uc11c mermaid\uc758 \ud14c\ub9c8\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:"themeConfig:\n /** @type {import('@docusaurus/preset-classic').ThemeConfig} */\n ({\n ...\n mermaid: {\n theme: {\n light: 'neutral', \n dark: 'dark'\n },\n },\n }),\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\uad6d\uc81c\ud654-\uc124\uc815",children:"\uad6d\uc81c\ud654 \uc124\uc815"}),"\n",(0,t.jsxs)(n.p,{children:["\uad6d\uc81c\ud654 \uc124\uc815\uc744 \ud55c\ub2e4\uba74 ",(0,t.jsx)(n.code,{children:"Older Entries"})," \ud615\ud0dc\uc758 \uc124\uba85\uc774 ",(0,t.jsx)(n.code,{children:"\ub2e4\uc74c \ud398\uc774\uc9c0"})," \ub85c \ubcc0\uacbd\ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc124\uc815\ud30c\uc77c\uc5d0\uc11c i18n\uc5d0 \uc788\ub294 \ub85c\ucf00\uc77c \uc124\uc815\uc744 ko\ub85c \ubcc0\uacbd\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",metastring:'title="docusaurus.config"',children:'i18n: {\n defaultLocale: "ko",\n locales: ["ko"],\n},\n'})}),"\n",(0,t.jsx)(n.h3,{id:"\ube14\ub85c\uadf8-\uae00-author",children:"\ube14\ub85c\uadf8 \uae00 author"}),"\n",(0,t.jsx)(n.p,{children:"\ud300\uc6d0 \ubcc4\ub85c \ubb38\uc11c\ub97c \uad00\ub9ac\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc774 \uc5b4\ub5a4 \ud300\uc6d0\uc774 \uae00\uc744 \uc791\uc131\ud588\ub294\uc9c0 \uc124\uc815\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"author",src:s(31897).Z+"",width:"2362",height:"1076"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"authors.yml"})," \ud30c\uc77c\uc744 \uc774\uc6a9\ud558\uc5ec \uc0ac\uc6a9\uc790\uc5d0 \ub300\ud55c \uae30\ubcf8 \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-yml",metastring:'title="/blog/authors.yml"',children:"herb:\n name: \ud5c8\ube0c\n title: Backend\n url: https://github.com/greeng00se\n image_url: https://github.com/greeng00se.png\n\nmallang:\n name: \ub9d0\ub791\n title: Backend\n url: https://github.com/shin-mallang\n image_url: https://github.com/shin-mallang.png\n"})}),"\n",(0,t.jsx)(n.p,{children:"\ube14\ub85c\uadf8 \uae00\uc744 \uc791\uc131\ud560 \ub54c \ub2e4\uc74c\uacfc \uac19\uc774 authors\uc5d0 \ub123\uc5b4\uc8fc\uae30\ub9cc \ud558\uba74 \ub41c\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-mdx",children:"---\nslug: 1\ntitle: Hello World\nauthors: [herb, mallang]\ntags: [hello, docusaurus]\n---\n\n\uccab \ubc88\uc9f8 \ubb38\uc11c \ub0b4\uc6a9\n"})})]})}function d(e={}){const{wrapper:n}={...(0,r.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},3905:(e,n,s)=>{s.d(n,{ah:()=>o});var t=s(67294);function r(e,n,s){return n in e?Object.defineProperty(e,n,{value:s,enumerable:!0,configurable:!0,writable:!0}):e[n]=s,e}function i(e,n){var s=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),s.push.apply(s,t)}return s}function a(e){for(var n=1;n<arguments.length;n++){var s=null!=arguments[n]?arguments[n]:{};n%2?i(Object(s),!0).forEach((function(n){r(e,n,s[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(s)):i(Object(s)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(s,n))}))}return e}function c(e,n){if(null==e)return{};var s,t,r=function(e,n){if(null==e)return{};var s,t,r={},i=Object.keys(e);for(t=0;t<i.length;t++)s=i[t],n.indexOf(s)>=0||(r[s]=e[s]);return r}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)s=i[t],n.indexOf(s)>=0||Object.prototype.propertyIsEnumerable.call(e,s)&&(r[s]=e[s])}return r}var l=t.createContext({}),o=function(e){var n=t.useContext(l),s=n;return e&&(s="function"==typeof e?e(n):a(a({},n),e)),s},u={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var s=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),h=o(s),g=r,p=h["".concat(l,".").concat(g)]||h[g]||u[g]||i;return s?t.createElement(p,a(a({ref:n},d),{},{components:s})):t.createElement(p,a({ref:n},d))}));d.displayName="MDXCreateElement"},41785:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/algolia-3dbac5c1606f7f0daed9cb27a429db50.png"},31897:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/author-1bd517bb7763257e2139e1063fd92492.png"},29094:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/github-d866f69755a1e17d4f17a262bd30d56d.png"},4730:(e,n,s)=>{s.d(n,{Z:()=>t});const t=s.p+"assets/images/key-2d0b59e69e9ca0b21c49b76159266e74.png"}}]); \ No newline at end of file diff --git a/assets/js/c08e7a0d.b69297ab.js b/assets/js/c08e7a0d.9cff8a1c.js similarity index 92% rename from assets/js/c08e7a0d.b69297ab.js rename to assets/js/c08e7a0d.9cff8a1c.js index 064f8b300..6a1e123c8 100644 --- a/assets/js/c08e7a0d.b69297ab.js +++ b/assets/js/c08e7a0d.9cff8a1c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7404],{27625:t=>{t.exports=JSON.parse('{"label":"throughput","permalink":"/docs/tags/throughput","allTagsPath":"/docs/tags","count":2,"items":[{"id":"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12","title":"Throughput \ubaa9\ud46f\uac12","description":"Throughput","permalink":"/docs/performance/throughput"},{"id":"\uc131\ub2a5/Throughput\uacfc Latency","title":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","description":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","permalink":"/docs/performance/throughput-latency"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7404],{27625:t=>{t.exports=JSON.parse('{"label":"throughput","permalink":"/docs/tags/throughput","allTagsPath":"/docs/tags","count":2,"items":[{"id":"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12","title":"Throughput \ubaa9\ud46f\uac12","description":"Throughput","permalink":"/docs/performance/throughput"},{"id":"\uc131\ub2a5/Throughput\uacfc Latency","title":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","description":"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c","permalink":"/docs/performance/throughput-latency"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/c189d18f.67c78fec.js b/assets/js/c189d18f.b76768cd.js similarity index 97% rename from assets/js/c189d18f.67c78fec.js rename to assets/js/c189d18f.b76768cd.js index 248ae7d9a..31bcdbee2 100644 --- a/assets/js/c189d18f.67c78fec.js +++ b/assets/js/c189d18f.b76768cd.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4962],{3470:e=>{e.exports=JSON.parse('{"label":"etc","permalink":"/docs/tags/etc","allTagsPath":"/docs/tags","count":4,"items":[{"id":"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","title":"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","description":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 4\uc6d4 19\uc77c","permalink":"/docs/etc/healthful-growth"},{"id":"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8","title":"\uacbd\ud5d8\uacfc \uc9c8\ubb38","description":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 10\uc6d4 6\uc77c","permalink":"/docs/etc/experience-and-self-question"},{"id":"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","title":"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","description":"\uc5b4\ub5a4 \uae30\uc220\uc744 \ud1b5\ud574\uc11c\ub3c4 \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4.","permalink":"/docs/etc/develop-with-spring"},{"id":"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","title":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","description":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?","permalink":"/docs/etc/communication"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4962],{3470:e=>{e.exports=JSON.parse('{"label":"etc","permalink":"/docs/tags/etc","allTagsPath":"/docs/tags","count":4,"items":[{"id":"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","title":"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","description":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 4\uc6d4 19\uc77c","permalink":"/docs/etc/healthful-growth"},{"id":"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8","title":"\uacbd\ud5d8\uacfc \uc9c8\ubb38","description":"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 10\uc6d4 6\uc77c","permalink":"/docs/etc/experience-and-self-question"},{"id":"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","title":"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","description":"\uc5b4\ub5a4 \uae30\uc220\uc744 \ud1b5\ud574\uc11c\ub3c4 \uc131\uc7a5\ud560 \uc218 \uc788\ub2e4.","permalink":"/docs/etc/develop-with-spring"},{"id":"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","title":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","description":"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798 \ud558\ub294 \uac1c\ubc1c\uc790?","permalink":"/docs/etc/communication"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/c1b17b3f.12ea0995.js b/assets/js/c1b17b3f.12ea0995.js deleted file mode 100644 index 412a471b5..000000000 --- a/assets/js/c1b17b3f.12ea0995.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8927],{3905:(t,e,a)=>{a.d(e,{Zo:()=>i,kt:()=>h});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function o(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?l(Object(a),!0).forEach((function(e){r(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function c(t,e){if(null==t)return{};var a,n,r=function(t,e){if(null==t)return{};var a,n,r={},l=Object.keys(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),d=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},i=function(t){var e=d(t.components);return n.createElement(p.Provider,{value:e},t.children)},u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},s=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,i=c(t,["components","mdxType","originalType","parentName"]),s=d(a),h=r,m=s["".concat(p,".").concat(h)]||s[h]||u[h]||l;return a?n.createElement(m,o(o({ref:e},i),{},{components:a})):n.createElement(m,o({ref:e},i))}));function h(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,o=new Array(l);o[0]=s;var c={};for(var p in e)hasOwnProperty.call(e,p)&&(c[p]=e[p]);c.originalType=t,c.mdxType="string"==typeof t?t:r,o[1]=c;for(var d=2;d<l;d++)o[d]=a[d];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}s.displayName="MDXCreateElement"},29571:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var n=a(87462),r=(a(67294),a(3905));const l={title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"cloudwatch",tags:["cloudwatch","log","monitoring"]},o=void 0,c={permalink:"/cloudwatch",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",source:"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",description:"CloudWatch",date:"2023-08-17T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 17\uc77c",tags:[{label:"cloudwatch",permalink:"/tags/cloudwatch"},{label:"log",permalink:"/tags/log"},{label:"monitoring",permalink:"/tags/monitoring"}],readingTime:5.35,hasTruncateMarker:!1,authors:[],frontMatter:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"cloudwatch",tags:["cloudwatch","log","monitoring"]},prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",permalink:"/woowacourse-level3-retrospective"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",permalink:"/route-image-async-with-event"}},p={authorsImageUrls:[]},d=[{value:"CloudWatch",id:"cloudwatch",level:2},{value:"CloudWatch Metrics",id:"cloudwatch-metrics",level:2},{value:"CloudWatch Agent \uc124\uce58",id:"cloudwatch-agent-\uc124\uce58",level:2},{value:"IAM \uc5ed\ud560 \uc124\uc815",id:"iam-\uc5ed\ud560-\uc124\uc815",level:3},{value:"\uc124\uce58",id:"\uc124\uce58",level:3},{value:"Wizard",id:"wizard",level:3},{value:"\uc124\uc815 \ud30c\uc77c \uc801\uc6a9",id:"\uc124\uc815-\ud30c\uc77c-\uc801\uc6a9",level:3},{value:"types.db: no such file or directory \uc5d0\ub7ec",id:"typesdb-no-such-file-or-directory-\uc5d0\ub7ec",level:3},{value:"\uc9c0\ud45c \ud655\uc778",id:"\uc9c0\ud45c-\ud655\uc778",level:3},{value:"\ub85c\uadf8",id:"\ub85c\uadf8",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],i={toc:d};function u(t){let{components:e,...l}=t;return(0,r.kt)("wrapper",(0,n.Z)({},i,l,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"cloudwatch"},"CloudWatch"),(0,r.kt)("p",null,"AWS \ub9ac\uc18c\uc2a4\uc640 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc9c0\ud45c\uc640 \ub85c\uadf8\uc5d0 \ub300\ud55c \ubaa8\ub2c8\ud130\ub9c1\uc744 \uc81c\uacf5\ud558\ub294 \uc11c\ube44\uc2a4\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc9c0\ud45c\ub97c \uac10\uc2dc\ud558\uc5ec \uc54c\ub9bc\uc744 \ubcf4\ub0b4\ub294 \uae30\ub2a5\ub3c4 \uc81c\uacf5\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud504\ub9ac\ud2f0\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \ub300\uc2dc\ubcf4\ub4dc\ub2f9 3$/M \uc758 \ube44\uc6a9\uc774 \uccad\uad6c\ub418\uace0, \uc9c0\ud45c\ub098 \ub85c\uadf8\uc758 \uc591\uc5d0 \ub530\ub77c \ube44\uc6a9\uc774 \ucd94\uac00\uc801\uc73c\ub85c \uccad\uad6c\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc694\uae08 \uc815\ubcf4\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc815\ubcf4\ub294 ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/cloudwatch/pricing/"},"\ub2e4\uc74c \ub9c1\ud06c"),"\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("h2",{id:"cloudwatch-metrics"},"CloudWatch Metrics"),(0,r.kt)("p",null,"\uae30\ubcf8\uc801\uc73c\ub85c 5\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc218\uc9d1\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc138\ubd80 \ubaa8\ub2c8\ud130\ub9c1(Detailed Monitoring)\uc744 \ud65c\uc131\ud654\ud558\uba74 1\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\ub97c \uc218\uc9d1\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub300\uc2dc\ubcf4\ub4dc\uc5d0\uc11c InstanceId\ub85c \uac80\uc0c9\ud558\uc5ec \uc218\uc9d1\ub41c \uc9c0\ud45c\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch1.png",src:a(86344).Z,width:"3214",height:"1636"})),(0,r.kt)("p",null,"CPUUtilization, NetworkIn, NetworkOut\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 \uc9c0\ud45c\ub97c \uc81c\uacf5\ud558\uace0, \uba54\ubaa8\ub9ac, \ub514\uc2a4\ud06c \uacf5\uac04\uacfc \uac19\uc740 \uc9c0\ud45c\ub97c \ud655\uc778\ud558\ub824\uba74 \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\ub97c \uc124\uc815\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("h2",{id:"cloudwatch-agent-\uc124\uce58"},"CloudWatch Agent \uc124\uce58"),(0,r.kt)("p",null,"CloudWatch Agent \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\uc640 \ub85c\uadf8\ub97c \uc218\uc9d1\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("h3",{id:"iam-\uc5ed\ud560-\uc124\uc815"},"IAM \uc5ed\ud560 \uc124\uc815"),(0,r.kt)("p",null,"\uae30\ubcf8\uc801\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4\uac00 CloudWatchAgentServerPolicy\uc5d0 \ub300\ud55c \uad8c\ud55c\uc774 \uc788\uc5b4\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","IAM \u2192 \uc5ed\ud560\uc5d0\uc11c \uc5ed\ud560 \uc0dd\uc131\uc744 \ud074\ub9ad\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch2.png",src:a(35939).Z,width:"2614",height:"1602"})),(0,r.kt)("p",null,"CloudWatchAgentServerPolicy \uad8c\ud55c \uc815\ucc45\uc744 \uc120\ud0dd\ud558\uace0, \uc801\ub2f9\ud55c \uc5ed\ud560 \uc774\ub984\uc744 \uc785\ub825\ud574\uc11c \uc5ed\ud560\uc744 \uc0dd\uc131\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch3.png",src:a(5001).Z,width:"2650",height:"1616"})),(0,r.kt)("p",null,"EC2 \uc778\uc2a4\ud134\uc2a4 \ubaa9\ub85d\uc73c\ub85c \ub4e4\uc5b4\uac00\uc11c, CloudWatch Agent\ub97c \uc124\uce58\ud560 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud074\ub9ad\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc5d0\uc11c \uc774\uc804\uc5d0 \uc0dd\uc131\ud55c \uc5ed\ud560\uc744 \uc9c0\uc815\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch4.png",src:a(55693).Z,width:"1764",height:"800"})),(0,r.kt)("h3",{id:"\uc124\uce58"},"\uc124\uce58"),(0,r.kt)("p",null,"\ud658\uacbd\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("p",null,"OS: ubuntu 22.04",(0,r.kt)("br",{parentName:"p"}),"\n","\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small (ARM64) "),(0,r.kt)("p",null,"\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uce58\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb\nsudo dpkg -i -E ./amazon-cloudwatch-agent.deb\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html"},"\uc0ac\uc6a9 \uc124\uba85\uc11c"),"\uc5d0 \uac01 \uc778\uc2a4\ud134\uc2a4 \uc720\ud615\ub9c8\ub2e4 \ub2e4\uc6b4\ub85c\ub4dc \ub9c1\ud06c\uac00 \uc790\uc138\ud558\uac8c \uc548\ub0b4\ub418\uc5b4 \uc788\ub2e4."),(0,r.kt)("h3",{id:"wizard"},"Wizard"),(0,r.kt)("p",null,"CloudWatch Wizard\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uc124\uc815 \ud30c\uc77c \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub85c\uadf8\ub97c \uc218\uc9d1\ud558\ub3c4\ub85d \uc124\uc815\ud558\ub294 \uacbd\uc6b0 Wizard \uc2e4\ud589 \uba85\ub839\uc5b4 \uc785\ub825 \uc804 log \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \ubcf5\uc0ac\ud574\ub450\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec Wizard\ub97c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard\n")),(0,r.kt)("p",null,"\uc124\uc815\uc744 \uc9c4\ud589\ud558\ub2e4 \ubcf4\uba74 \uc124\uc815 \ud30c\uc77c\uc774 \uc5b4\ub5bb\uac8c \uad6c\uc131\ub420\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub85c\uadf8\ub97c \ucd94\uac00\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \uc785\ub825\ucc3d\uc774 \ub098\uc624\uba74 \uc900\ube44\ud574\ub480\ub358 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \uc785\ub825\ud55c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch5.png",src:a(41733).Z,width:"2320",height:"1328"})),(0,r.kt)("p",null,"\uc911\uac04\uc5d0 SSM parameter store\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \uc800\uc7a5\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"Do you want to store the config in the SSM parameter store?\n1. yes\n2. no\n")),(0,r.kt)("p",null,"\ucd94\uac00\uc801\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 2\ubc88\uc744 \uc120\ud0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Parameter Store \uad00\ub9ac\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uc758 ",(0,r.kt)("a",{parentName:"p",href:"https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/"},"\ubb38\uc11c"),"\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac70 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc124\uc815\uc774 \uc644\ub8cc\ub418\uba74 ",(0,r.kt)("inlineCode",{parentName:"p"},"/opt/aws/amazon-cloudwatch-agent/bin/config.json")," \uc5d0 \uc124\uc815\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc774 \uc800\uc7a5\ub41c\ub2e4. "),(0,r.kt)("h3",{id:"\uc124\uc815-\ud30c\uc77c-\uc801\uc6a9"},"\uc124\uc815 \ud30c\uc77c \uc801\uc6a9"),(0,r.kt)("p",null,"\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uc815\ud30c\uc77c\uc744 \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","file \ub4a4\uc5d0\ub294 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub300\ud55c \uc808\ub300\uacbd\ub85c(\uc544\ub798 \uba85\ub839\uc5b4 \uae30\uc900 \uae30\ubcf8 \uc0dd\uc131 \uc704\uce58)\ub97c \uc785\ub825\ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json\n")),(0,r.kt)("h3",{id:"typesdb-no-such-file-or-directory-\uc5d0\ub7ec"},"types.db: no such file or directory \uc5d0\ub7ec"),(0,r.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc740 \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 types.db \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory\n")),(0,r.kt)("p",null,"types.db \ud30c\uc77c \uc0dd\uc131"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo mkdir /usr/share/collectd\nsudo touch /usr/share/collectd/types.db\n")),(0,r.kt)("h3",{id:"\uc9c0\ud45c-\ud655\uc778"},"\uc9c0\ud45c \ud655\uc778"),(0,r.kt)("p",null,"CloudWatch Metrics\uc5d0 \uac00\ubcf4\uba74 CWAgent\ub77c\ub294 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\uac00 \ucd94\uac00\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch6.png",src:a(40721).Z,width:"2638",height:"708"})),(0,r.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ucd94\uac00\ud558\uc5ec \uc9c0\ud45c\uc5d0 \ub300\ud55c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "metrics": {\n "namespace": "2023-hello-world",\n ......\n },\n} \n')),(0,r.kt)("h3",{id:"\ub85c\uadf8"},"\ub85c\uadf8"),(0,r.kt)("p",null,"CloudWatch \u2192 \ub85c\uadf8 \uadf8\ub8f9\uc73c\ub85c \uac00\uba74 Wizard\ub85c \ucd94\uac00\ud55c \ub85c\uadf8\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch7.png",src:a(95994).Z,width:"2792",height:"1652"})),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html"},"CloudWatch\ub780 \ubb34\uc5c7\uc785\ub2c8\uae4c?"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/cloudwatch/pricing/"},"Amazon CloudWatch \uc694\uae08"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html"},"Linux \uc778\uc2a4\ud134\uc2a4 \uc9c0\ud45c"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html"},"\uc11c\ubc84\uc5d0 CloudWatch \uc5d0\uc774\uc804\ud2b8 \uc124\uce58 \ubc0f \uc2e4\ud589"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/"},"CloudWatch Agent\ub97c Parameter Store\uc5d0\uc11c \uad00\ub9ac\ud574 \ubcf4\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html"},"CloudWatch\uc5d0\uc774\uc804\ud2b8 \uad6c\uc131 \ud30c\uc77c")))}u.isMDXComponent=!0},86344:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch1-859296155df6c20d0846f1388022a86c.png"},35939:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch2-ca9c26868dec08ea7133e2774f49798a.png"},5001:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch3-da10422b87e1901286b6d3e85e2c01cc.png"},55693:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch4-1e7eddc7e8dd890ac18352e900df8e07.png"},41733:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch5-67d1bd59d4552f4fe481452eddc78a5e.png"},40721:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch6-06ead809f7510938baee41505bc72b97.png"},95994:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch7-a86dfc0db307ddf7d1660d2b9e419c96.png"}}]); \ No newline at end of file diff --git a/assets/js/c1b17b3f.e63c57c6.js b/assets/js/c1b17b3f.e63c57c6.js new file mode 100644 index 000000000..8f275cd7d --- /dev/null +++ b/assets/js/c1b17b3f.e63c57c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8927],{46681:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var a=n(85893),c=n(3905);const r={title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"cloudwatch",tags:["cloudwatch","log","monitoring"]},s=void 0,l={permalink:"/cloudwatch",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",source:"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",description:"CloudWatch",date:"2023-08-17T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 17\uc77c",tags:[{label:"cloudwatch",permalink:"/tags/cloudwatch"},{label:"log",permalink:"/tags/log"},{label:"monitoring",permalink:"/tags/monitoring"}],readingTime:5.35,hasTruncateMarker:!1,authors:[],frontMatter:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"cloudwatch",tags:["cloudwatch","log","monitoring"]},unlisted:!1,prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",permalink:"/woowacourse-level3-retrospective"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",permalink:"/route-image-async-with-event"}},o={authorsImageUrls:[]},d=[{value:"CloudWatch",id:"cloudwatch",level:2},{value:"CloudWatch Metrics",id:"cloudwatch-metrics",level:2},{value:"CloudWatch Agent \uc124\uce58",id:"cloudwatch-agent-\uc124\uce58",level:2},{value:"IAM \uc5ed\ud560 \uc124\uc815",id:"iam-\uc5ed\ud560-\uc124\uc815",level:3},{value:"\uc124\uce58",id:"\uc124\uce58",level:3},{value:"Wizard",id:"wizard",level:3},{value:"\uc124\uc815 \ud30c\uc77c \uc801\uc6a9",id:"\uc124\uc815-\ud30c\uc77c-\uc801\uc6a9",level:3},{value:"types.db: no such file or directory \uc5d0\ub7ec",id:"typesdb-no-such-file-or-directory-\uc5d0\ub7ec",level:3},{value:"\uc9c0\ud45c \ud655\uc778",id:"\uc9c0\ud45c-\ud655\uc778",level:3},{value:"\ub85c\uadf8",id:"\ub85c\uadf8",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function i(e){const t={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,c.ah)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"cloudwatch",children:"CloudWatch"}),"\n",(0,a.jsxs)(t.p,{children:["AWS \ub9ac\uc18c\uc2a4\uc640 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc9c0\ud45c\uc640 \ub85c\uadf8\uc5d0 \ub300\ud55c \ubaa8\ub2c8\ud130\ub9c1\uc744 \uc81c\uacf5\ud558\ub294 \uc11c\ube44\uc2a4\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc9c0\ud45c\ub97c \uac10\uc2dc\ud558\uc5ec \uc54c\ub9bc\uc744 \ubcf4\ub0b4\ub294 \uae30\ub2a5\ub3c4 \uc81c\uacf5\ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\ud504\ub9ac\ud2f0\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \ub300\uc2dc\ubcf4\ub4dc\ub2f9 3$/M \uc758 \ube44\uc6a9\uc774 \uccad\uad6c\ub418\uace0, \uc9c0\ud45c\ub098 \ub85c\uadf8\uc758 \uc591\uc5d0 \ub530\ub77c \ube44\uc6a9\uc774 \ucd94\uac00\uc801\uc73c\ub85c \uccad\uad6c\ub41c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc694\uae08 \uc815\ubcf4\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc815\ubcf4\ub294 ",(0,a.jsx)(t.a,{href:"https://aws.amazon.com/ko/cloudwatch/pricing/",children:"\ub2e4\uc74c \ub9c1\ud06c"}),"\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(t.h2,{id:"cloudwatch-metrics",children:"CloudWatch Metrics"}),"\n",(0,a.jsxs)(t.p,{children:["\uae30\ubcf8\uc801\uc73c\ub85c 5\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc218\uc9d1\ub41c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc138\ubd80 \ubaa8\ub2c8\ud130\ub9c1(Detailed Monitoring)\uc744 \ud65c\uc131\ud654\ud558\uba74 1\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\ub97c \uc218\uc9d1\ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\ub300\uc2dc\ubcf4\ub4dc\uc5d0\uc11c InstanceId\ub85c \uac80\uc0c9\ud558\uc5ec \uc218\uc9d1\ub41c \uc9c0\ud45c\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch1.png",src:n(86344).Z+"",width:"3214",height:"1636"})}),"\n",(0,a.jsx)(t.p,{children:"CPUUtilization, NetworkIn, NetworkOut\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 \uc9c0\ud45c\ub97c \uc81c\uacf5\ud558\uace0, \uba54\ubaa8\ub9ac, \ub514\uc2a4\ud06c \uacf5\uac04\uacfc \uac19\uc740 \uc9c0\ud45c\ub97c \ud655\uc778\ud558\ub824\uba74 \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\ub97c \uc124\uc815\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,a.jsx)(t.h2,{id:"cloudwatch-agent-\uc124\uce58",children:"CloudWatch Agent \uc124\uce58"}),"\n",(0,a.jsx)(t.p,{children:"CloudWatch Agent \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\uc640 \ub85c\uadf8\ub97c \uc218\uc9d1\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.h3,{id:"iam-\uc5ed\ud560-\uc124\uc815",children:"IAM \uc5ed\ud560 \uc124\uc815"}),"\n",(0,a.jsxs)(t.p,{children:["\uae30\ubcf8\uc801\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4\uac00 CloudWatchAgentServerPolicy\uc5d0 \ub300\ud55c \uad8c\ud55c\uc774 \uc788\uc5b4\uc57c \ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","IAM \u2192 \uc5ed\ud560\uc5d0\uc11c \uc5ed\ud560 \uc0dd\uc131\uc744 \ud074\ub9ad\ud55c\ub2e4."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch2.png",src:n(35939).Z+"",width:"2614",height:"1602"})}),"\n",(0,a.jsx)(t.p,{children:"CloudWatchAgentServerPolicy \uad8c\ud55c \uc815\ucc45\uc744 \uc120\ud0dd\ud558\uace0, \uc801\ub2f9\ud55c \uc5ed\ud560 \uc774\ub984\uc744 \uc785\ub825\ud574\uc11c \uc5ed\ud560\uc744 \uc0dd\uc131\ud55c\ub2e4."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch3.png",src:n(5001).Z+"",width:"2650",height:"1616"})}),"\n",(0,a.jsxs)(t.p,{children:["EC2 \uc778\uc2a4\ud134\uc2a4 \ubaa9\ub85d\uc73c\ub85c \ub4e4\uc5b4\uac00\uc11c, CloudWatch Agent\ub97c \uc124\uce58\ud560 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud074\ub9ad\ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc5d0\uc11c \uc774\uc804\uc5d0 \uc0dd\uc131\ud55c \uc5ed\ud560\uc744 \uc9c0\uc815\ud55c\ub2e4."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch4.png",src:n(55693).Z+"",width:"1764",height:"800"})}),"\n",(0,a.jsx)(t.h3,{id:"\uc124\uce58",children:"\uc124\uce58"}),"\n",(0,a.jsx)(t.p,{children:"\ud658\uacbd\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,a.jsxs)(t.p,{children:["OS: ubuntu 22.04",(0,a.jsx)(t.br,{}),"\n","\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small (ARM64)"]}),"\n",(0,a.jsx)(t.p,{children:"\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uce58\ud55c\ub2e4."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb\nsudo dpkg -i -E ./amazon-cloudwatch-agent.deb\n"})}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html",children:"\uc0ac\uc6a9 \uc124\uba85\uc11c"}),"\uc5d0 \uac01 \uc778\uc2a4\ud134\uc2a4 \uc720\ud615\ub9c8\ub2e4 \ub2e4\uc6b4\ub85c\ub4dc \ub9c1\ud06c\uac00 \uc790\uc138\ud558\uac8c \uc548\ub0b4\ub418\uc5b4 \uc788\ub2e4."]}),"\n",(0,a.jsx)(t.h3,{id:"wizard",children:"Wizard"}),"\n",(0,a.jsxs)(t.p,{children:["CloudWatch Wizard\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uc124\uc815 \ud30c\uc77c \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\ub85c\uadf8\ub97c \uc218\uc9d1\ud558\ub3c4\ub85d \uc124\uc815\ud558\ub294 \uacbd\uc6b0 Wizard \uc2e4\ud589 \uba85\ub839\uc5b4 \uc785\ub825 \uc804 log \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \ubcf5\uc0ac\ud574\ub450\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec Wizard\ub97c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard\n"})}),"\n",(0,a.jsxs)(t.p,{children:["\uc124\uc815\uc744 \uc9c4\ud589\ud558\ub2e4 \ubcf4\uba74 \uc124\uc815 \ud30c\uc77c\uc774 \uc5b4\ub5bb\uac8c \uad6c\uc131\ub420\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\ub85c\uadf8\ub97c \ucd94\uac00\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \uc785\ub825\ucc3d\uc774 \ub098\uc624\uba74 \uc900\ube44\ud574\ub480\ub358 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \uc785\ub825\ud55c\ub2e4."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch5.png",src:n(41733).Z+"",width:"2320",height:"1328"})}),"\n",(0,a.jsx)(t.p,{children:"\uc911\uac04\uc5d0 SSM parameter store\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \uc800\uc7a5\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"Do you want to store the config in the SSM parameter store?\n1. yes\n2. no\n"})}),"\n",(0,a.jsxs)(t.p,{children:["\ucd94\uac00\uc801\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 2\ubc88\uc744 \uc120\ud0dd\ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","Parameter Store \uad00\ub9ac\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uc758 ",(0,a.jsx)(t.a,{href:"https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/",children:"\ubb38\uc11c"}),"\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac70 \uac19\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc124\uc815\uc774 \uc644\ub8cc\ub418\uba74 ",(0,a.jsx)(t.code,{children:"/opt/aws/amazon-cloudwatch-agent/bin/config.json"})," \uc5d0 \uc124\uc815\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc774 \uc800\uc7a5\ub41c\ub2e4."]}),"\n",(0,a.jsx)(t.h3,{id:"\uc124\uc815-\ud30c\uc77c-\uc801\uc6a9",children:"\uc124\uc815 \ud30c\uc77c \uc801\uc6a9"}),"\n",(0,a.jsxs)(t.p,{children:["\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uc815\ud30c\uc77c\uc744 \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(t.br,{}),"\n","file \ub4a4\uc5d0\ub294 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub300\ud55c \uc808\ub300\uacbd\ub85c(\uc544\ub798 \uba85\ub839\uc5b4 \uae30\uc900 \uae30\ubcf8 \uc0dd\uc131 \uc704\uce58)\ub97c \uc785\ub825\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json\n"})}),"\n",(0,a.jsx)(t.h3,{id:"typesdb-no-such-file-or-directory-\uc5d0\ub7ec",children:"types.db: no such file or directory \uc5d0\ub7ec"}),"\n",(0,a.jsx)(t.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc740 \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 types.db \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory\n"})}),"\n",(0,a.jsx)(t.p,{children:"types.db \ud30c\uc77c \uc0dd\uc131"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"sudo mkdir /usr/share/collectd\nsudo touch /usr/share/collectd/types.db\n"})}),"\n",(0,a.jsx)(t.h3,{id:"\uc9c0\ud45c-\ud655\uc778",children:"\uc9c0\ud45c \ud655\uc778"}),"\n",(0,a.jsx)(t.p,{children:"CloudWatch Metrics\uc5d0 \uac00\ubcf4\uba74 CWAgent\ub77c\ub294 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\uac00 \ucd94\uac00\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch6.png",src:n(40721).Z+"",width:"2638",height:"708"})}),"\n",(0,a.jsx)(t.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ucd94\uac00\ud558\uc5ec \uc9c0\ud45c\uc5d0 \ub300\ud55c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-json",children:'{\n "metrics": {\n "namespace": "2023-hello-world",\n ......\n },\n} \n'})}),"\n",(0,a.jsx)(t.h3,{id:"\ub85c\uadf8",children:"\ub85c\uadf8"}),"\n",(0,a.jsx)(t.p,{children:"CloudWatch \u2192 \ub85c\uadf8 \uadf8\ub8f9\uc73c\ub85c \uac00\uba74 Wizard\ub85c \ucd94\uac00\ud55c \ub85c\uadf8\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch7.png",src:n(95994).Z+"",width:"2792",height:"1652"})}),"\n",(0,a.jsx)(t.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html",children:"CloudWatch\ub780 \ubb34\uc5c7\uc785\ub2c8\uae4c?"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://aws.amazon.com/ko/cloudwatch/pricing/",children:"Amazon CloudWatch \uc694\uae08"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html",children:"Linux \uc778\uc2a4\ud134\uc2a4 \uc9c0\ud45c"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html",children:"\uc11c\ubc84\uc5d0 CloudWatch \uc5d0\uc774\uc804\ud2b8 \uc124\uce58 \ubc0f \uc2e4\ud589"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/",children:"CloudWatch Agent\ub97c Parameter Store\uc5d0\uc11c \uad00\ub9ac\ud574 \ubcf4\uae30"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html",children:"CloudWatch\uc5d0\uc774\uc804\ud2b8 \uad6c\uc131 \ud30c\uc77c"})]})]})}function h(e={}){const{wrapper:t}={...(0,c.ah)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(i,{...e})}):i(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>d});var a=n(67294);function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){c(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,a,c=function(e,t){if(null==e)return{};var n,a,c={},r=Object.keys(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||(c[n]=e[n]);return c}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(c[n]=e[n])}return c}var o=a.createContext({}),d=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},i={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,c=e.mdxType,r=e.originalType,o=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),u=d(n),p=c,g=u["".concat(o,".").concat(p)]||u[p]||i[p]||r;return n?a.createElement(g,s(s({ref:t},h),{},{components:n})):a.createElement(g,s({ref:t},h))}));h.displayName="MDXCreateElement"},86344:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch1-859296155df6c20d0846f1388022a86c.png"},35939:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch2-ca9c26868dec08ea7133e2774f49798a.png"},5001:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch3-da10422b87e1901286b6d3e85e2c01cc.png"},55693:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch4-1e7eddc7e8dd890ac18352e900df8e07.png"},41733:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch5-67d1bd59d4552f4fe481452eddc78a5e.png"},40721:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch6-06ead809f7510938baee41505bc72b97.png"},95994:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch7-a86dfc0db307ddf7d1660d2b9e419c96.png"}}]); \ No newline at end of file diff --git a/assets/js/c3ea66fe.73186556.js b/assets/js/c3ea66fe.4afcd78f.js similarity index 84% rename from assets/js/c3ea66fe.73186556.js rename to assets/js/c3ea66fe.4afcd78f.js index 24f59f94d..e6c997a50 100644 --- a/assets/js/c3ea66fe.73186556.js +++ b/assets/js/c3ea66fe.4afcd78f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6698],{63504:s=>{s.exports=JSON.parse('{"label":"Isolation","permalink":"/tags/isolation","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6698],{63504:s=>{s.exports=JSON.parse('{"label":"Isolation","permalink":"/tags/isolation","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/c4f5d8e4.325cecb9.js b/assets/js/c4f5d8e4.325cecb9.js new file mode 100644 index 000000000..b269da24a --- /dev/null +++ b/assets/js/c4f5d8e4.325cecb9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4195],{62841:(e,s,t)=>{t.r(s),t.d(s,{default:()=>b});var n=t(52263),u=(t(67294),t(16550)),i=t(85893);function b(){const{siteConfig:e}=(0,n.Z)();return(0,i.jsx)(u.l_,{to:"/blog"})}}}]); \ No newline at end of file diff --git a/assets/js/c4f5d8e4.d37ba840.js b/assets/js/c4f5d8e4.d37ba840.js deleted file mode 100644 index 4c1d48122..000000000 --- a/assets/js/c4f5d8e4.d37ba840.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4195],{62841:(e,t,s)=>{s.r(t),s.d(t,{default:()=>i});var n=s(52263),u=s(67294),c=s(16550);function i(){const{siteConfig:e}=(0,n.Z)();return u.createElement(c.l_,{to:"/blog"})}}}]); \ No newline at end of file diff --git a/assets/js/c55d205b.99ebdf49.js b/assets/js/c55d205b.99ebdf49.js deleted file mode 100644 index 2b5031b05..000000000 --- a/assets/js/c55d205b.99ebdf49.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3438],{3905:(e,n,t)=>{t.d(n,{Zo:()=>u,kt:()=>s});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function l(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?a(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,r,i=function(e,n){if(null==e)return{};var t,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var p=r.createContext({}),c=function(e){var n=r.useContext(p),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},u=function(e){var n=c(e.components);return r.createElement(p.Provider,{value:n},e.children)},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,p=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),m=c(t),s=i,g=m["".concat(p,".").concat(s)]||m[s]||d[s]||a;return t?r.createElement(g,l(l({ref:n},u),{},{components:t})):r.createElement(g,l({ref:n},u))}));function s(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,l=new Array(a);l[0]=m;var o={};for(var p in n)hasOwnProperty.call(n,p)&&(o[p]=n[p]);o.originalType=e,o.mdxType="string"==typeof e?e:i,l[1]=o;for(var c=2;c<a;c++)l[c]=t[c];return r.createElement.apply(null,l)}return r.createElement.apply(null,t)}m.displayName="MDXCreateElement"},83859:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>l,default:()=>d,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var r=t(87462),i=(t(67294),t(3905));const a={title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",slug:"/nginx/command",last_update:{date:"2023/07/05"},tags:["nginx"]},l=void 0,o={unversionedId:"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4",id:"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4",title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",description:"\ud3f4\ub354 \ubc0f \ud30c\uc77c",source:"@site/docs/Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4.mdx",sourceDirName:"Nginx",slug:"/nginx/command",permalink:"/docs/nginx/command",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4.mdx",tags:[{label:"nginx",permalink:"/docs/tags/nginx"}],version:"current",lastUpdatedAt:1688515200,formattedLastUpdatedAt:"2023\ub144 7\uc6d4 5\uc77c",frontMatter:{title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",slug:"/nginx/command",last_update:{date:"2023/07/05"},tags:["nginx"]},sidebar:"tutorialSidebar",previous:{title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",permalink:"/docs/mac/java"},next:{title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",permalink:"/docs/nginx/static-file"}},p={},c=[{value:"\ud3f4\ub354 \ubc0f \ud30c\uc77c",id:"\ud3f4\ub354-\ubc0f-\ud30c\uc77c",level:3},{value:"\uba85\ub839\uc5b4",id:"\uba85\ub839\uc5b4",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:c};function d(e){let{components:n,...t}=e;return(0,i.kt)("wrapper",(0,r.Z)({},u,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h3",{id:"\ud3f4\ub354-\ubc0f-\ud30c\uc77c"},"\ud3f4\ub354 \ubc0f \ud30c\uc77c"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"/etc/nginx/")),(0,i.kt)("p",null,"\uae30\ubcf8 \uc124\uc815\uc774 \uc800\uc7a5\ub41c \ub8e8\ud2b8 \ub514\ub809\ud130\ub9ac"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"/etc/nginx/nginx.conf")),(0,i.kt)("p",null,"\uae30\ubcf8 \uc124\uc815 \ud30c\uc77c\ub85c \ubaa8\ub4e0 \uc124\uc815\uc5d0 \ub300\ud55c \uc9c4\uc785\uc810",(0,i.kt)("br",{parentName:"p"}),"\n","\ub514\ub809\ud130\ub9ac\uc5d0 \uc704\uce58\ud55c \ubaa8\ub4e0 \uc124\uc815 \ud30c\uc77c\uc744 \ud3ec\ud568\ud558\ub294 \ucd5c\uc0c1\uc704 Http \ube14\ub85d\uc744 \ud3ec\ud568\ud55c\ub2e4. "),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash",metastring:'title="nginx\uc5d0 \ud3ec\ud568\ub41c \uc124\uc815 \ud30c\uc77c \ud3ec\ud568 include \uad6c\ubb38"',title:'"nginx\uc5d0',"\ud3ec\ud568\ub41c":!0,"\uc124\uc815":!0,"\ud30c\uc77c":!0,"\ud3ec\ud568":!0,include:!0,'\uad6c\ubb38"':!0},"http {\n ...\n include /etc/nginx/conf.d/*.conf;\n include /etc/nginx/sites-enabled/*;\n}\n")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"/etc/nginx/conf.d/")),(0,i.kt)("p",null,"\uae30\ubcf8 HTTP \uc11c\ubc84 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub300\ud55c \ub514\ub809\ud130\ub9ac",(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("inlineCode",{parentName:"p"},".conf")," \ub85c \ub05d\ub098\ub294 \uacbd\uc6b0 \uc704\uc758 include \uc124\uc815\uc5d0 \uc758\ud574 \ucd5c\uc0c1\uc704 http \ube14\ub85d\uc5d0 \ud3ec\ud568\ub41c\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","conf.d \ub514\ub809\ud130\ub9ac \ub300\uc2e0 site-enabled \ub514\ub809\ud130\ub9ac\uc640 symlink\ub97c \ud1b5\ud574 \uc124\uc815 \ud30c\uc77c\uc744 \uc5f0\uacb0\ud558\ub294 \ubc29\ubc95\uc740 \ub354 \uc774\uc0c1 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4. "),(0,i.kt)("admonition",{title:"NIGNX \uc124\uc815",type:"note"},(0,i.kt)("p",{parentName:"admonition"},"nginx \uc124\uc815\uc758 \uacbd\uc6b0 include \uad6c\ubb38\uc744 \ud65c\uc6a9\ud574 \uad6c\uc870\ud654\ud558\uc5ec \uc124\uc815 \ud30c\uc77c\uc744 \uac04\uacb0\ud558\uac8c \uc720\uc9c0\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.")),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"/var/log/nginx/")),(0,i.kt)("p",null,"\uc5d4\uc9c4\uc5d1\uc2a4 \ub85c\uadf8\uac00 \uc800\uc7a5\ub418\ub294 \ub514\ub809\ud130\ub9ac\ub85c access \ub85c\uadf8\uc640 error \ub85c\uadf8\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,i.kt)("br",{parentName:"p"}),"\n","\ub85c\uadf8 \ud615\uc2dd\uc758 \uacbd\uc6b0 \uc124\uc815 \ud30c\uc77c\uc758 log_format \uad6c\ubb38\uc744 \uc774\uc6a9\ud574\uc11c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4. "),(0,i.kt)("h3",{id:"\uba85\ub839\uc5b4"},"\uba85\ub839\uc5b4"),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"nginx -t")),(0,i.kt)("p",null,"nginx \uc124\uc815\uc774 \uc815\uc0c1\uc778\uc9c0 \ud655\uc778\ud55c\ub2e4. "),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"nginx -T")," "),(0,i.kt)("p",null,"nginx \uc124\uc815 \ud655\uc778\uc758 \uacb0\uacfc\ub97c \uc870\uae08 \ub354 \uc790\uc138\ud558\uac8c \ucd9c\ub825\ud574\uc900\ub2e4. "),(0,i.kt)("p",null,(0,i.kt)("inlineCode",{parentName:"p"},"nginx -s <SIGNAL>")),(0,i.kt)("p",null,"\uc5ec\uae30\uc11c SIGNAL\uc740 \ub2e4\uc74c \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud560 \uc218 \uc788\ub2e4."),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"quit: \uc815\uc0c1\uc801\uc73c\ub85c \uc885\ub8cc(SIGQUIT)"),(0,i.kt)("li",{parentName:"ul"},"reload: \uc124\uc815 \ud30c\uc77c \ub9ac\ub85c\ub4dc(SIGHUP)"),(0,i.kt)("li",{parentName:"ul"},"reopen: \ub85c\uadf8 \ud30c\uc77c\uc744 \ub2e4\uc2dc \uc5f4\ub3c4\ub85d \uc694\uccad(SIGUSR1)"),(0,i.kt)("li",{parentName:"ul"},"stop: \uc885\ub8cc \uc694\uccad(SIGTERM)")),(0,i.kt)("p",null,"\uc5ec\uae30\uc11c SIGQUIT & SIGTREM \ubaa8\ub450 graceful shutdown\uc744 \uc218\ud589\ud55c\ub2e4."),(0,i.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,i.kt)("p",null,"NGINX \ucfe1\ubd81, \ub370\ub9ad \ub514\uc6a9\uae30 p.22 ~ p.23",(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.nginx.com/"},"https://docs.nginx.com/"),(0,i.kt)("br",{parentName:"p"}),"\n",(0,i.kt)("a",{parentName:"p",href:"https://docs.nginx.com/nginx/admin-guide/monitoring/logging/"},"https://docs.nginx.com/nginx/admin-guide/monitoring/logging/")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/c55d205b.aa5a86ab.js b/assets/js/c55d205b.aa5a86ab.js new file mode 100644 index 000000000..877617395 --- /dev/null +++ b/assets/js/c55d205b.aa5a86ab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3438],{36712:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>l,contentTitle:()=>s,default:()=>x,frontMatter:()=>c,metadata:()=>o,toc:()=>d});var r=t(85893),i=t(3905);const c={title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",slug:"/nginx/command",last_update:{date:"2023/07/05"},tags:["nginx"]},s=void 0,o={id:"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4",title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",description:"\ud3f4\ub354 \ubc0f \ud30c\uc77c",source:"@site/docs/Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4.mdx",sourceDirName:"Nginx",slug:"/nginx/command",permalink:"/docs/nginx/command",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4.mdx",tags:[{label:"nginx",permalink:"/docs/tags/nginx"}],version:"current",lastUpdatedAt:1688515200,formattedLastUpdatedAt:"2023\ub144 7\uc6d4 5\uc77c",frontMatter:{title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",slug:"/nginx/command",last_update:{date:"2023/07/05"},tags:["nginx"]},sidebar:"tutorialSidebar",previous:{title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",permalink:"/docs/mac/java"},next:{title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",permalink:"/docs/nginx/static-file"}},l={},d=[{value:"\ud3f4\ub354 \ubc0f \ud30c\uc77c",id:"\ud3f4\ub354-\ubc0f-\ud30c\uc77c",level:3},{value:"\uba85\ub839\uc5b4",id:"\uba85\ub839\uc5b4",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function a(n){const e={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.ah)(),...n.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.h3,{id:"\ud3f4\ub354-\ubc0f-\ud30c\uc77c",children:"\ud3f4\ub354 \ubc0f \ud30c\uc77c"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.code,{children:"/etc/nginx/"})}),"\n",(0,r.jsx)(e.p,{children:"\uae30\ubcf8 \uc124\uc815\uc774 \uc800\uc7a5\ub41c \ub8e8\ud2b8 \ub514\ub809\ud130\ub9ac"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.code,{children:"/etc/nginx/nginx.conf"})}),"\n",(0,r.jsxs)(e.p,{children:["\uae30\ubcf8 \uc124\uc815 \ud30c\uc77c\ub85c \ubaa8\ub4e0 \uc124\uc815\uc5d0 \ub300\ud55c \uc9c4\uc785\uc810",(0,r.jsx)(e.br,{}),"\n","\ub514\ub809\ud130\ub9ac\uc5d0 \uc704\uce58\ud55c \ubaa8\ub4e0 \uc124\uc815 \ud30c\uc77c\uc744 \ud3ec\ud568\ud558\ub294 \ucd5c\uc0c1\uc704 Http \ube14\ub85d\uc744 \ud3ec\ud568\ud55c\ub2e4."]}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",metastring:'title="nginx\uc5d0 \ud3ec\ud568\ub41c \uc124\uc815 \ud30c\uc77c \ud3ec\ud568 include \uad6c\ubb38"',children:"http {\n ...\n include /etc/nginx/conf.d/*.conf;\n include /etc/nginx/sites-enabled/*;\n}\n"})}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.code,{children:"/etc/nginx/conf.d/"})}),"\n",(0,r.jsxs)(e.p,{children:["\uae30\ubcf8 HTTP \uc11c\ubc84 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub300\ud55c \ub514\ub809\ud130\ub9ac",(0,r.jsx)(e.br,{}),"\n",(0,r.jsx)(e.code,{children:".conf"})," \ub85c \ub05d\ub098\ub294 \uacbd\uc6b0 \uc704\uc758 include \uc124\uc815\uc5d0 \uc758\ud574 \ucd5c\uc0c1\uc704 http \ube14\ub85d\uc5d0 \ud3ec\ud568\ub41c\ub2e4.",(0,r.jsx)(e.br,{}),"\n","conf.d \ub514\ub809\ud130\ub9ac \ub300\uc2e0 site-enabled \ub514\ub809\ud130\ub9ac\uc640 symlink\ub97c \ud1b5\ud574 \uc124\uc815 \ud30c\uc77c\uc744 \uc5f0\uacb0\ud558\ub294 \ubc29\ubc95\uc740 \ub354 \uc774\uc0c1 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4."]}),"\n",(0,r.jsx)(e.admonition,{title:"NIGNX \uc124\uc815",type:"note",children:(0,r.jsx)(e.p,{children:"nginx \uc124\uc815\uc758 \uacbd\uc6b0 include \uad6c\ubb38\uc744 \ud65c\uc6a9\ud574 \uad6c\uc870\ud654\ud558\uc5ec \uc124\uc815 \ud30c\uc77c\uc744 \uac04\uacb0\ud558\uac8c \uc720\uc9c0\ud558\ub294 \uac83\uc774 \uc88b\ub2e4."})}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.code,{children:"/var/log/nginx/"})}),"\n",(0,r.jsxs)(e.p,{children:["\uc5d4\uc9c4\uc5d1\uc2a4 \ub85c\uadf8\uac00 \uc800\uc7a5\ub418\ub294 \ub514\ub809\ud130\ub9ac\ub85c access \ub85c\uadf8\uc640 error \ub85c\uadf8\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(e.br,{}),"\n","\ub85c\uadf8 \ud615\uc2dd\uc758 \uacbd\uc6b0 \uc124\uc815 \ud30c\uc77c\uc758 log_format \uad6c\ubb38\uc744 \uc774\uc6a9\ud574\uc11c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(e.h3,{id:"\uba85\ub839\uc5b4",children:"\uba85\ub839\uc5b4"}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.code,{children:"nginx -t"})}),"\n",(0,r.jsx)(e.p,{children:"nginx \uc124\uc815\uc774 \uc815\uc0c1\uc778\uc9c0 \ud655\uc778\ud55c\ub2e4."}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.code,{children:"nginx -T"})}),"\n",(0,r.jsx)(e.p,{children:"nginx \uc124\uc815 \ud655\uc778\uc758 \uacb0\uacfc\ub97c \uc870\uae08 \ub354 \uc790\uc138\ud558\uac8c \ucd9c\ub825\ud574\uc900\ub2e4."}),"\n",(0,r.jsx)(e.p,{children:(0,r.jsx)(e.code,{children:"nginx -s <SIGNAL>"})}),"\n",(0,r.jsx)(e.p,{children:"\uc5ec\uae30\uc11c SIGNAL\uc740 \ub2e4\uc74c \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsxs)(e.ul,{children:["\n",(0,r.jsx)(e.li,{children:"quit: \uc815\uc0c1\uc801\uc73c\ub85c \uc885\ub8cc(SIGQUIT)"}),"\n",(0,r.jsx)(e.li,{children:"reload: \uc124\uc815 \ud30c\uc77c \ub9ac\ub85c\ub4dc(SIGHUP)"}),"\n",(0,r.jsx)(e.li,{children:"reopen: \ub85c\uadf8 \ud30c\uc77c\uc744 \ub2e4\uc2dc \uc5f4\ub3c4\ub85d \uc694\uccad(SIGUSR1)"}),"\n",(0,r.jsx)(e.li,{children:"stop: \uc885\ub8cc \uc694\uccad(SIGTERM)"}),"\n"]}),"\n",(0,r.jsx)(e.p,{children:"\uc5ec\uae30\uc11c SIGQUIT & SIGTREM \ubaa8\ub450 graceful shutdown\uc744 \uc218\ud589\ud55c\ub2e4."}),"\n",(0,r.jsx)(e.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(e.p,{children:["NGINX \ucfe1\ubd81, \ub370\ub9ad \ub514\uc6a9\uae30 p.22 ~ p.23",(0,r.jsx)(e.br,{}),"\n",(0,r.jsx)(e.a,{href:"https://docs.nginx.com/",children:"https://docs.nginx.com/"}),(0,r.jsx)(e.br,{}),"\n",(0,r.jsx)(e.a,{href:"https://docs.nginx.com/nginx/admin-guide/monitoring/logging/",children:"https://docs.nginx.com/nginx/admin-guide/monitoring/logging/"})]})]})}function x(n={}){const{wrapper:e}={...(0,i.ah)(),...n.components};return e?(0,r.jsx)(e,{...n,children:(0,r.jsx)(a,{...n})}):a(n)}},3905:(n,e,t)=>{t.d(e,{ah:()=>d});var r=t(67294);function i(n,e,t){return e in n?Object.defineProperty(n,e,{value:t,enumerable:!0,configurable:!0,writable:!0}):n[e]=t,n}function c(n,e){var t=Object.keys(n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(n);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(n,e).enumerable}))),t.push.apply(t,r)}return t}function s(n){for(var e=1;e<arguments.length;e++){var t=null!=arguments[e]?arguments[e]:{};e%2?c(Object(t),!0).forEach((function(e){i(n,e,t[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(t)):c(Object(t)).forEach((function(e){Object.defineProperty(n,e,Object.getOwnPropertyDescriptor(t,e))}))}return n}function o(n,e){if(null==n)return{};var t,r,i=function(n,e){if(null==n)return{};var t,r,i={},c=Object.keys(n);for(r=0;r<c.length;r++)t=c[r],e.indexOf(t)>=0||(i[t]=n[t]);return i}(n,e);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(n);for(r=0;r<c.length;r++)t=c[r],e.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(n,t)&&(i[t]=n[t])}return i}var l=r.createContext({}),d=function(n){var e=r.useContext(l),t=e;return n&&(t="function"==typeof n?n(e):s(s({},e),n)),t},a={inlineCode:"code",wrapper:function(n){var e=n.children;return r.createElement(r.Fragment,{},e)}},x=r.forwardRef((function(n,e){var t=n.components,i=n.mdxType,c=n.originalType,l=n.parentName,x=o(n,["components","mdxType","originalType","parentName"]),p=d(t),g=i,u=p["".concat(l,".").concat(g)]||p[g]||a[g]||c;return t?r.createElement(u,s(s({ref:e},x),{},{components:t})):r.createElement(u,s({ref:e},x))}));x.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/c60995f6.9c12eb08.js b/assets/js/c60995f6.6ea62df7.js similarity index 85% rename from assets/js/c60995f6.9c12eb08.js rename to assets/js/c60995f6.6ea62df7.js index 2cf1d083a..90660ef8e 100644 --- a/assets/js/c60995f6.9c12eb08.js +++ b/assets/js/c60995f6.6ea62df7.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6199],{62474:i=>{i.exports=JSON.parse('{"label":"nginx","permalink":"/docs/tags/nginx","allTagsPath":"/docs/tags","count":2,"items":[{"id":"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4","title":"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4","description":"\ud3f4\ub354 \ubc0f \ud30c\uc77c","permalink":"/docs/nginx/command"},{"id":"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5","title":"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5","description":"root","permalink":"/docs/nginx/static-file"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6199],{62474:i=>{i.exports=JSON.parse('{"label":"nginx","permalink":"/docs/tags/nginx","allTagsPath":"/docs/tags","count":2,"items":[{"id":"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4","title":"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4","description":"\ud3f4\ub354 \ubc0f \ud30c\uc77c","permalink":"/docs/nginx/command"},{"id":"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5","title":"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5","description":"root","permalink":"/docs/nginx/static-file"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/c60ea0ff.881f4c53.js b/assets/js/c60ea0ff.f14cacef.js similarity index 84% rename from assets/js/c60ea0ff.881f4c53.js rename to assets/js/c60ea0ff.f14cacef.js index c8b9020c9..a8bb91022 100644 --- a/assets/js/c60ea0ff.881f4c53.js +++ b/assets/js/c60ea0ff.f14cacef.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3085],{14072:e=>{e.exports=JSON.parse('{"label":"TecoChat","permalink":"/tags/teco-chat","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3085],{14072:e=>{e.exports=JSON.parse('{"label":"TecoChat","permalink":"/tags/teco-chat","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/c6b037a5.97248574.js b/assets/js/c6b037a5.3ee85e02.js similarity index 77% rename from assets/js/c6b037a5.97248574.js rename to assets/js/c6b037a5.3ee85e02.js index 8ff61a532..694480ee5 100644 --- a/assets/js/c6b037a5.97248574.js +++ b/assets/js/c6b037a5.3ee85e02.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3137],{4030:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3137],{4030:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/c6d04683.2f21610f.js b/assets/js/c6d04683.2f21610f.js new file mode 100644 index 000000000..6c572fdee --- /dev/null +++ b/assets/js/c6d04683.2f21610f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5436],{29316:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>d,frontMatter:()=>l,metadata:()=>c,toc:()=>o});var i=r(85893),t=r(3905);const l={title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",slug:"composite",tags:["Pattern","Composite"]},s=void 0,c={permalink:"/composite",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",source:"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",description:"\uc694\uad6c\uc0ac\ud56d",date:"2023-05-26T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 26\uc77c",tags:[{label:"Pattern",permalink:"/tags/pattern"},{label:"Composite",permalink:"/tags/composite"}],readingTime:4.74,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",slug:"composite",tags:["Pattern","Composite"]},unlisted:!1,prevItem:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",permalink:"/tecochat-retrospective-3"},nextItem:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",permalink:"/subway-retrospective"}},a={authorsImageUrls:[]},o=[{value:"\uc694\uad6c\uc0ac\ud56d",id:"\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9",id:"\uc778\ud130\ud398\uc774\uc2a4-\uc0ac\uc6a9",level:3},{value:"\ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30",id:"\ubaa8\ub4e0-\uc694\uae08-\uc815\ucc45\uc744-\ud3ec\ud568\ud558\ub294-\uc0c8\ub85c\uc6b4-\uc694\uae08-\uc815\ucc45-\ub9cc\ub4e4\uae30",level:3},{value:"\uc815\ucc45\uc758 \uc21c\uc11c",id:"\uc815\ucc45\uc758-\uc21c\uc11c",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc774\ub780",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uad6c\uc131\uc694\uc18c",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uc0ac\uc6a9\uacfc-\uc8fc\uc694-\ubaa9\ud45c",level:3},{value:"\ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84",id:"\ud328\ud134-\uc0ac\uc6a9\uc2dc-\uc8fc\uc758\ud574\uc57c\ud560-\ubd80\ubd84",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const n={blockquote:"blockquote",br:"br",code:"code",h3:"h3",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.ah)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"\uc694\uad6c\uc0ac\ud56d",children:"\uc694\uad6c\uc0ac\ud56d"}),"\n",(0,i.jsx)(n.p,{children:"\uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uac70\ub9ac\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45"}),"\n",(0,i.jsx)(n.li,{children:"\ub178\uc120\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45"}),"\n",(0,i.jsx)(n.li,{children:"\uc5f0\ub839\ubcc4 \uc694\uae08 \ud560\uc778 \uc815\ucc45"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\uc778\ud130\ud398\uc774\uc2a4-\uc0ac\uc6a9",children:"\uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9"}),"\n",(0,i.jsxs)(n.p,{children:["\uc694\uae08 \uc815\ucc45\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc778\ud130\ud398\uc774\uc2a4\ub85c \ud45c\ud604\ud560 \uc218 \uc788\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc694\uae08\uc744 \uacc4\uc0b0\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ucd5c\ub2e8 \uacbd\ub85c \uacc4\uc0b0\uc758 \uacb0\uacfc, \uc0ac\uc6a9\uc790\uc758 \uc815\ubcf4, \uc694\uae08\uc744 \ubc1b\uc544 \uc694\uae08\uc744 \uacc4\uc0b0\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"public interface FarePolicy {\n int calculate(Path path, Passenger passenger, int fare);\n}\n\npublic class BaseFarePolicy implements FarePolicy { ... }\npublic class DistanceFarePolicy implements FarePolicy { ... }\npublic class AgeDiscountFarePolicy implements FarePolicy { ... }\n"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"composite1",src:r(28629).Z+"",width:"1768",height:"554"})}),"\n",(0,i.jsx)(n.h3,{id:"\ubaa8\ub4e0-\uc694\uae08-\uc815\ucc45\uc744-\ud3ec\ud568\ud558\ub294-\uc0c8\ub85c\uc6b4-\uc694\uae08-\uc815\ucc45-\ub9cc\ub4e4\uae30",children:"\ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30"}),"\n",(0,i.jsxs)(n.p,{children:["\ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub97c \ubaa8\ub450 \uac00\uc9c0\uace0 \uc788\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc774 \ub610\ud55c FarePolicy\ub97c \uad6c\ud604\ud55c \ud615\ud0dc\uac00 \ub418\uace0, \ud544\ub4dc\ub85c\ub294 \ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub4e4\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"public class SubwayFarePolicy implements FarePolicy {\n\n private final List<FarePolicy> farePolicies;\n\n public SubwayFarePolicy(final List<FarePolicy> farePolicies) {\n this.farePolicies = farePolicies;\n }\n\n @Override\n public int calculate(final Path path, final Passenger passenger, final int fare) {\n int calculatedFare = fare;\n for (FarePolicy farePolicy : farePolicies) {\n calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);\n }\n return calculatedFare;\n }\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"\ub530\ub77c\uc11c \uadf8\ub9bc\uc73c\ub85c \ubcf8\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"composite2",src:r(33094).Z+"",width:"2020",height:"954"})}),"\n",(0,i.jsx)(n.h3,{id:"\uc815\ucc45\uc758-\uc21c\uc11c",children:"\uc815\ucc45\uc758 \uc21c\uc11c"}),"\n",(0,i.jsxs)(n.p,{children:["\uc9c0\ud558\ucca0 \uc694\uad6c\uc0ac\ud56d\uc740 \uc21c\uc11c\uac00 \uc911\uc694\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uae08\uc561\uc758 \ucd1d\ud569\uc744 \uad6c\ud558\uace0, \uadf8 \ud6c4\uc5d0 \ud560\uc778 \uc815\ucc45\uc774 \ub4e4\uc5b4\uac00\uc57c\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc790\uc2dd\ub4e4\uc758 \uc21c\uc11c\ub97c \uad00\ub9ac\ud560 \ub54c \uc8fc\uc758\ub97c \uae30\uc6b8\uc5ec\uc57c \ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","Configuration \ud074\ub798\uc2a4\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \uc21c\uc11c\ub97c \uc9c1\uc811 \uc801\uc6a9\uc2dc\ucf30\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"@Configuration\npublic class FareConfiguration {\n\n @Bean\n public FarePolicy farePolicy() {\n return new SubwayFarePolicy(List.of(\n new BaseFarePolicy(),\n new DistanceFarePolicy(),\n new AgeDiscountFarePolicy()\n ));\n }\n}\n"})}),"\n",(0,i.jsx)(n.h3,{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc774\ub780",children:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"composite3",src:r(67922).Z+"",width:"1848",height:"482"})}),"\n",(0,i.jsx)(n.p,{children:"GOF\uc758 \ub514\uc790\uc778 \ud328\ud134 \ucc45\uc5d0\uc11c\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uba85\ud558\uace0 \uc788\ub2e4."}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:["\ubd80\ubd84\uacfc \uc804\uccb4\uc758 \uacc4\uce35\uc744 \ud45c\ud604\ud558\uae30 \uc704\ud574 \uac1d\uccb4\ub4e4\uc744 \ubaa8\uc544 \ud2b8\ub9ac \uad6c\uc870\ub85c \uad6c\uc131\ud569\ub2c8\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc0ac\uc6a9\uc790\ub85c \ud558\uc5ec\uae08 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ubcf5\ud569 \uac1d\uccb4\ub97c \ubaa8\ub450 \ub3d9\uc77c\ud558\uac8c \ub2e4\ub8f0 \uc218 \uc788\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc785\ub2c8\ub2e4."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc774 \ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uad6c\uc131\uc694\uc18c",children:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c"}),"\n",(0,i.jsx)(n.p,{children:"Component"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc9d1\ud569 \uad00\uacc4\uc5d0 \uc815\uc758\ub420 \ubaa8\ub4e0 \uac1d\uccb4\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4"}),"\n",(0,i.jsx)(n.li,{children:"ex) \uc694\uae08 \uc815\ucc45(FarePolicy)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Leaf"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uac1c\ubcc4 \uac1d\uccb4, \uac1d\uccb4 \ud569\uc131\uc5d0 \uae30\ubcf8\uc774 \ub418\ub294 \uac1d\uccb4\uc758 \ud589\ub3d9"}),"\n",(0,i.jsx)(n.li,{children:"ex) \uac70\ub9ac \ubcc4 \uc694\uae08 \uc815\ucc45(DistanceFarePolicy)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Composite"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc5ec\ub7ec \uac1c\uc758 \uac1c\ubc1c \uac1d\uccb4\ub97c \ud3ec\ud568\ud558\ub294 \ud569\uc131 \uac1d\uccb4"}),"\n",(0,i.jsx)(n.li,{children:"ex) \uc9c0\ud558\ucca0 \uc694\uae08 \uc815\ucc45(SubwayFarePolicy)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Client"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uc0ac\uc6a9\uacfc-\uc8fc\uc694-\ubaa9\ud45c",children:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c"}),"\n",(0,i.jsxs)(n.p,{children:["\ubd80\ubd84 - \uc804\uccb4\uc758 \uad00\uacc4\ub97c \ud45c\ud604\ud558\uace0 \uc2f6\uc744 \ub54c",(0,i.jsx)(n.br,{}),"\n","Client \uae30\uc900\uc73c\ub85c Composite\uc640 Leaf\uc758 \ucc28\uc774\ub97c \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc798 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc57c\ub420 \ub54c"]}),"\n",(0,i.jsx)(n.h3,{id:"\ud328\ud134-\uc0ac\uc6a9\uc2dc-\uc8fc\uc758\ud574\uc57c\ud560-\ubd80\ubd84",children:"\ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84"}),"\n",(0,i.jsxs)(n.p,{children:["\ud328\ud134\uc740 \uacf5\ud1b5\uc73c\ub85c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc758 \ud15c\ud50c\ub9bf\uc774\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ubc18\ubcf5\ub418\ub294 \ubb38\uc81c\ub97c \ud6a8\uc728\uc801\uc73c\ub85c \ud574\uacb0\ud560 \uc218 \uc788\uc9c0\ub9cc \ud328\ud134\uc5d0 \ub9e4\ubab0\ub418\uc11c\ub294 \uc548\ub41c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ud328\ud134\uc744 \ub9f9\ubaa9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud574\uc11c\ub294 \uc548\ub418\uace0, \ud604\uc7ac\uc758 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ub530\ub77c \ud328\ud134\uc744 \uc720\ub3d9\uc801\uc73c\ub85c \uc218\uc815\ud574\uac00\uba74\uc11c \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ud56d\uc0c1 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uc0dd\uac01\ud558\uc790!"]}),"\n",(0,i.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,i.jsxs)(n.p,{children:["\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134, GoF\uc758 \ub514\uc790\uc778 \ud328\ud134",(0,i.jsx)(n.br,{}),"\n","\ub514\uc790\uc778 \ud328\ud134\uacfc \ud504\ub808\uc784\uc6cc\ud06c, \uc624\ube0c\uc81d\ud2b8"]})]})}function d(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>o});var i=r(67294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function l(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,i)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?l(Object(r),!0).forEach((function(n){t(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function c(e,n){if(null==e)return{};var r,i,t=function(e,n){if(null==e)return{};var r,i,t={},l=Object.keys(e);for(i=0;i<l.length;i++)r=l[i],n.indexOf(r)>=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(i=0;i<l.length;i++)r=l[i],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var a=i.createContext({}),o=function(e){var n=i.useContext(a),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},d=i.forwardRef((function(e,n){var r=e.components,t=e.mdxType,l=e.originalType,a=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=o(r),h=t,j=u["".concat(a,".").concat(h)]||u[h]||p[h]||l;return r?i.createElement(j,s(s({ref:n},d),{},{components:r})):i.createElement(j,s({ref:n},d))}));d.displayName="MDXCreateElement"},28629:(e,n,r)=>{r.d(n,{Z:()=>i});const i=r.p+"assets/images/composite1-6117733e5244b235d9405ba72afb53ed.png"},33094:(e,n,r)=>{r.d(n,{Z:()=>i});const i=r.p+"assets/images/composite2-ac487a832bf12267cc91996ea3a5b9c7.png"},67922:(e,n,r)=>{r.d(n,{Z:()=>i});const i=r.p+"assets/images/composite3-016bf41863692b1f738bc89011687166.png"}}]); \ No newline at end of file diff --git a/assets/js/c6d04683.3ecb01f2.js b/assets/js/c6d04683.3ecb01f2.js deleted file mode 100644 index de9cedd60..000000000 --- a/assets/js/c6d04683.3ecb01f2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5436],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>k});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),c=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),m=c(n),k=r,f=m["".concat(p,".").concat(k)]||m[k]||s[k]||l;return n?a.createElement(f,i(i({ref:t},u),{},{components:n})):a.createElement(f,i({ref:t},u))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=m;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var c=2;c<l;c++)i[c]=n[c];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"},48905:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>s,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var a=n(87462),r=(n(67294),n(3905));const l={title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",slug:"composite",tags:["Pattern","Composite"]},i=void 0,o={permalink:"/composite",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",source:"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",description:"\uc694\uad6c\uc0ac\ud56d",date:"2023-05-26T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 26\uc77c",tags:[{label:"Pattern",permalink:"/tags/pattern"},{label:"Composite",permalink:"/tags/composite"}],readingTime:4.74,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",slug:"composite",tags:["Pattern","Composite"]},prevItem:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",permalink:"/tecochat-retrospective-3"},nextItem:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",permalink:"/subway-retrospective"}},p={authorsImageUrls:[]},c=[{value:"\uc694\uad6c\uc0ac\ud56d",id:"\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9",id:"\uc778\ud130\ud398\uc774\uc2a4-\uc0ac\uc6a9",level:3},{value:"\ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30",id:"\ubaa8\ub4e0-\uc694\uae08-\uc815\ucc45\uc744-\ud3ec\ud568\ud558\ub294-\uc0c8\ub85c\uc6b4-\uc694\uae08-\uc815\ucc45-\ub9cc\ub4e4\uae30",level:3},{value:"\uc815\ucc45\uc758 \uc21c\uc11c",id:"\uc815\ucc45\uc758-\uc21c\uc11c",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc774\ub780",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uad6c\uc131\uc694\uc18c",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uc0ac\uc6a9\uacfc-\uc8fc\uc694-\ubaa9\ud45c",level:3},{value:"\ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84",id:"\ud328\ud134-\uc0ac\uc6a9\uc2dc-\uc8fc\uc758\ud574\uc57c\ud560-\ubd80\ubd84",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:c};function s(e){let{components:t,...l}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,l,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"\uc694\uad6c\uc0ac\ud56d"},"\uc694\uad6c\uc0ac\ud56d"),(0,r.kt)("p",null,"\uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uac70\ub9ac\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45"),(0,r.kt)("li",{parentName:"ul"},"\ub178\uc120\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45"),(0,r.kt)("li",{parentName:"ul"},"\uc5f0\ub839\ubcc4 \uc694\uae08 \ud560\uc778 \uc815\ucc45")),(0,r.kt)("h3",{id:"\uc778\ud130\ud398\uc774\uc2a4-\uc0ac\uc6a9"},"\uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9"),(0,r.kt)("p",null,"\uc694\uae08 \uc815\ucc45\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc778\ud130\ud398\uc774\uc2a4\ub85c \ud45c\ud604\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc694\uae08\uc744 \uacc4\uc0b0\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ucd5c\ub2e8 \uacbd\ub85c \uacc4\uc0b0\uc758 \uacb0\uacfc, \uc0ac\uc6a9\uc790\uc758 \uc815\ubcf4, \uc694\uae08\uc744 \ubc1b\uc544 \uc694\uae08\uc744 \uacc4\uc0b0\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public interface FarePolicy {\n int calculate(Path path, Passenger passenger, int fare);\n}\n\npublic class BaseFarePolicy implements FarePolicy { ... }\npublic class DistanceFarePolicy implements FarePolicy { ... }\npublic class AgeDiscountFarePolicy implements FarePolicy { ... }\n")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"composite1",src:n(28629).Z,width:"1768",height:"554"})),(0,r.kt)("h3",{id:"\ubaa8\ub4e0-\uc694\uae08-\uc815\ucc45\uc744-\ud3ec\ud568\ud558\ub294-\uc0c8\ub85c\uc6b4-\uc694\uae08-\uc815\ucc45-\ub9cc\ub4e4\uae30"},"\ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30"),(0,r.kt)("p",null,"\ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub97c \ubaa8\ub450 \uac00\uc9c0\uace0 \uc788\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \ub610\ud55c FarePolicy\ub97c \uad6c\ud604\ud55c \ud615\ud0dc\uac00 \ub418\uace0, \ud544\ub4dc\ub85c\ub294 \ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub4e4\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public class SubwayFarePolicy implements FarePolicy {\n\n private final List<FarePolicy> farePolicies;\n\n public SubwayFarePolicy(final List<FarePolicy> farePolicies) {\n this.farePolicies = farePolicies;\n }\n\n @Override\n public int calculate(final Path path, final Passenger passenger, final int fare) {\n int calculatedFare = fare;\n for (FarePolicy farePolicy : farePolicies) {\n calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);\n }\n return calculatedFare;\n }\n}\n")),(0,r.kt)("p",null,"\ub530\ub77c\uc11c \uadf8\ub9bc\uc73c\ub85c \ubcf8\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"composite2",src:n(33094).Z,width:"2020",height:"954"})),(0,r.kt)("h3",{id:"\uc815\ucc45\uc758-\uc21c\uc11c"},"\uc815\ucc45\uc758 \uc21c\uc11c"),(0,r.kt)("p",null,"\uc9c0\ud558\ucca0 \uc694\uad6c\uc0ac\ud56d\uc740 \uc21c\uc11c\uac00 \uc911\uc694\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae08\uc561\uc758 \ucd1d\ud569\uc744 \uad6c\ud558\uace0, \uadf8 \ud6c4\uc5d0 \ud560\uc778 \uc815\ucc45\uc774 \ub4e4\uc5b4\uac00\uc57c\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc790\uc2dd\ub4e4\uc758 \uc21c\uc11c\ub97c \uad00\ub9ac\ud560 \ub54c \uc8fc\uc758\ub97c \uae30\uc6b8\uc5ec\uc57c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Configuration \ud074\ub798\uc2a4\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \uc21c\uc11c\ub97c \uc9c1\uc811 \uc801\uc6a9\uc2dc\ucf30\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"@Configuration\npublic class FareConfiguration {\n\n @Bean\n public FarePolicy farePolicy() {\n return new SubwayFarePolicy(List.of(\n new BaseFarePolicy(),\n new DistanceFarePolicy(),\n new AgeDiscountFarePolicy()\n ));\n }\n}\n")),(0,r.kt)("h3",{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc774\ub780"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"composite3",src:n(67922).Z,width:"1848",height:"482"})),(0,r.kt)("p",null,"GOF\uc758 \ub514\uc790\uc778 \ud328\ud134 \ucc45\uc5d0\uc11c\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uba85\ud558\uace0 \uc788\ub2e4."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\ubd80\ubd84\uacfc \uc804\uccb4\uc758 \uacc4\uce35\uc744 \ud45c\ud604\ud558\uae30 \uc704\ud574 \uac1d\uccb4\ub4e4\uc744 \ubaa8\uc544 \ud2b8\ub9ac \uad6c\uc870\ub85c \uad6c\uc131\ud569\ub2c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc6a9\uc790\ub85c \ud558\uc5ec\uae08 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ubcf5\ud569 \uac1d\uccb4\ub97c \ubaa8\ub450 \ub3d9\uc77c\ud558\uac8c \ub2e4\ub8f0 \uc218 \uc788\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc785\ub2c8\ub2e4.")),(0,r.kt)("p",null,"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uad6c\uc131\uc694\uc18c"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c"),(0,r.kt)("p",null,"Component"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc9d1\ud569 \uad00\uacc4\uc5d0 \uc815\uc758\ub420 \ubaa8\ub4e0 \uac1d\uccb4\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4 "),(0,r.kt)("li",{parentName:"ul"},"ex) \uc694\uae08 \uc815\ucc45(FarePolicy) ")),(0,r.kt)("p",null,"Leaf"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uac1c\ubcc4 \uac1d\uccb4, \uac1d\uccb4 \ud569\uc131\uc5d0 \uae30\ubcf8\uc774 \ub418\ub294 \uac1d\uccb4\uc758 \ud589\ub3d9 "),(0,r.kt)("li",{parentName:"ul"},"ex) \uac70\ub9ac \ubcc4 \uc694\uae08 \uc815\ucc45(DistanceFarePolicy) ")),(0,r.kt)("p",null,"Composite"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc5ec\ub7ec \uac1c\uc758 \uac1c\ubc1c \uac1d\uccb4\ub97c \ud3ec\ud568\ud558\ub294 \ud569\uc131 \uac1d\uccb4 "),(0,r.kt)("li",{parentName:"ul"},"ex) \uc9c0\ud558\ucca0 \uc694\uae08 \uc815\ucc45(SubwayFarePolicy) ")),(0,r.kt)("p",null,"Client"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8")),(0,r.kt)("h3",{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uc0ac\uc6a9\uacfc-\uc8fc\uc694-\ubaa9\ud45c"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c"),(0,r.kt)("p",null,"\ubd80\ubd84 - \uc804\uccb4\uc758 \uad00\uacc4\ub97c \ud45c\ud604\ud558\uace0 \uc2f6\uc744 \ub54c",(0,r.kt)("br",{parentName:"p"}),"\n","Client \uae30\uc900\uc73c\ub85c Composite\uc640 Leaf\uc758 \ucc28\uc774\ub97c \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc798 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc57c\ub420 \ub54c"),(0,r.kt)("h3",{id:"\ud328\ud134-\uc0ac\uc6a9\uc2dc-\uc8fc\uc758\ud574\uc57c\ud560-\ubd80\ubd84"},"\ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84"),(0,r.kt)("p",null,"\ud328\ud134\uc740 \uacf5\ud1b5\uc73c\ub85c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc758 \ud15c\ud50c\ub9bf\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubc18\ubcf5\ub418\ub294 \ubb38\uc81c\ub97c \ud6a8\uc728\uc801\uc73c\ub85c \ud574\uacb0\ud560 \uc218 \uc788\uc9c0\ub9cc \ud328\ud134\uc5d0 \ub9e4\ubab0\ub418\uc11c\ub294 \uc548\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud328\ud134\uc744 \ub9f9\ubaa9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud574\uc11c\ub294 \uc548\ub418\uace0, \ud604\uc7ac\uc758 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ub530\ub77c \ud328\ud134\uc744 \uc720\ub3d9\uc801\uc73c\ub85c \uc218\uc815\ud574\uac00\uba74\uc11c \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uc0dd\uac01\ud558\uc790!"),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134, GoF\uc758 \ub514\uc790\uc778 \ud328\ud134",(0,r.kt)("br",{parentName:"p"}),"\n","\ub514\uc790\uc778 \ud328\ud134\uacfc \ud504\ub808\uc784\uc6cc\ud06c, \uc624\ube0c\uc81d\ud2b8"))}s.isMDXComponent=!0},28629:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/composite1-6117733e5244b235d9405ba72afb53ed.png"},33094:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/composite2-ac487a832bf12267cc91996ea3a5b9c7.png"},67922:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/composite3-016bf41863692b1f738bc89011687166.png"}}]); \ No newline at end of file diff --git a/assets/js/c7015929.683ff471.js b/assets/js/c7015929.2bf7c111.js similarity index 87% rename from assets/js/c7015929.683ff471.js rename to assets/js/c7015929.2bf7c111.js index 4bed761b4..081e206b5 100644 --- a/assets/js/c7015929.683ff471.js +++ b/assets/js/c7015929.2bf7c111.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4185],{910:e=>{e.exports=JSON.parse('{"label":"Python","permalink":"/tags/python","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4185],{910:e=>{e.exports=JSON.parse('{"label":"Python","permalink":"/tags/python","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/caf1b628.7ea0263c.js b/assets/js/caf1b628.7ea0263c.js new file mode 100644 index 000000000..e1cdd1772 --- /dev/null +++ b/assets/js/caf1b628.7ea0263c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7230],{36721:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>l,toc:()=>s});var r=t(85893),a=t(3905);const o={title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",slug:"/network/load-balancing",last_update:{date:"2023/09/04"},tags:["network","load balancing"]},i=void 0,l={id:"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1",title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",description:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?",source:"@site/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1.mdx",sourceDirName:"\ub124\ud2b8\uc6cc\ud06c",slug:"/network/load-balancing",permalink:"/docs/network/load-balancing",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1.mdx",tags:[{label:"network",permalink:"/docs/tags/network"},{label:"load balancing",permalink:"/docs/tags/load-balancing"}],version:"current",lastUpdatedAt:1693785600,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 4\uc77c",frontMatter:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",slug:"/network/load-balancing",last_update:{date:"2023/09/04"},tags:["network","load balancing"]},sidebar:"tutorialSidebar",previous:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",permalink:"/docs/network/load-balancing-algorithm"},next:{title:"maximumPoolSize",permalink:"/docs/database/maximumPoolSize"}},c={},s=[{value:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?",id:"\ub85c\ub4dc-\ubc38\ub7f0\uc2f1\uc774\ub780",level:3},{value:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc758 \uc7a5\uc810",id:"\ub85c\ub4dc-\ubc38\ub7f0\uc2f1\uc758-\uc7a5\uc810",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",admonition:"admonition",br:"br",h3:"h3",p:"p",strong:"strong",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"\ub85c\ub4dc-\ubc38\ub7f0\uc2f1\uc774\ub780",children:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?"}),"\n",(0,r.jsxs)(n.p,{children:["\uc11c\ubc84\uac00 \ucc98\ub9ac\ud574\uc57c \ud560 \uc694\uccad\uc744 \uc5ec\ub7ec \ub300\uc758 \uc11c\ubc84\ub85c \ub098\ub204\uc5b4 \ucc98\ub9ac\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc740 \ub85c\ub4dc \ubc38\ub7f0\uc11c\ub97c \ud1b5\ud574 \uc774\ub8e8\uc5b4\uc9c4\ub2e4."]}),"\n",(0,r.jsx)(n.admonition,{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uacfc \ub85c\ub4dc \ubc38\ub7f0\uc11c",type:"note",children:(0,r.jsxs)(n.p,{children:["\ub85c\ub4dc \ubc38\ub7f0\uc2f1: \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc9c0\uc6d0\ud558\ub294 \ub9ac\uc18c\uc2a4 \ud480 \uc804\uccb4\uc5d0 \ub124\ud2b8\uc6cc\ud06c \ud2b8\ub798\ud53d\uc744 \uade0\ub4f1\ud558\uac8c \ubc30\ud3ec\ud558\ub294 \ubc29\ubc95",(0,r.jsx)(n.br,{}),"\n","\ub85c\ub4dc \ubc38\ub7f0\uc11c: \uc0ac\uc6a9\uc790\uc640 \uc11c\ubc84 \uadf8\ub8f9 \uc0ac\uc774\uc5d0 \uc704\uce58\ud558\uba70 \ubcf4\uc774\uc9c0 \uc54a\ub294 \ucd09\uc9c4\uc790 \uc5ed\ud560\uc744 \ud558\uc5ec \ubaa8\ub4e0 \ub9ac\uc18c\uc2a4 \uc11c\ubc84\uac00 \ub3d9\uc77c\ud558\uac8c \uc0ac\uc6a9\ub418\ub3c4\ub85d \ud558\ub294 \ub514\ubc14\uc774\uc2a4"]})}),"\n",(0,r.jsx)(n.h3,{id:"\ub85c\ub4dc-\ubc38\ub7f0\uc2f1\uc758-\uc7a5\uc810",children:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc758 \uc7a5\uc810"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\uac00\uc6a9\uc131"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc11c\ubc84\uc5d0 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ub85c\ub4dc\ubc38\ub7f0\uc11c\uac00 \ud574\ub2f9 \ubb38\uc81c\ub97c \uac10\uc9c0(\ud5ec\uc2a4 \uccb4\ud06c\ub97c \ud1b5\ud574)\ud558\uc5ec \ud2b8\ub798\ud53d\uc744 \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc11c\ubc84\ub85c \ubcf4\ub0c4\uc73c\ub85c\uc368 \ub0b4\uacb0\ud568\uc131\uc744 \ub192\ud78c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub85c\ub4dc\ubc38\ub7f0\uc11c\ub97c \ud65c\uc6a9\ud55c \ubb34\uc911\ub2e8 \ubc30\ud3ec"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\ud655\uc7a5\uc131"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc218\ud3c9 \ud655\uc7a5\uc131(Horizontal Scalability) \uc6a9\uc774",(0,r.jsx)(n.br,{}),"\n","\ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0 AutoScaling\uc744 \ud1b5\ud574 \uc11c\ubc84\ub97c \uc790\ub3d9\uc73c\ub85c \ud655\uc7a5(Scale-out)",(0,r.jsx)(n.br,{}),"\n","\ud2b8\ub798\ud53d\uc774 \uac10\uc18c\ud558\ub294 \uacbd\uc6b0 \ucd95\uc18c(Scale-in)"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\ubcf4\uc548"})}),"\n",(0,r.jsx)(n.p,{children:"\ubd84\uc0b0 \uc11c\ube44\uc2a4 \uac70\ubd80 \uacf5\uaca9(DDoS)\uc774 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ud574\ub2f9 \ud2b8\ub798\ud53d\uc744 \ubd80\ud558 \ubd84\uc0b0\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"\uc131\ub2a5"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc11c\ubc84 \uac04 \ub85c\ub4dc\ub97c \uade0\ub4f1\ud558\uac8c \ubc30\ud3ec\ud558\uc5ec \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc131\ub2a5\uc744 \ud5a5\uc0c1 \uc2dc\ud0a8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud074\ub77c\uc774\uc5b8\ud2b8 \uc694\uccad\uc744 \uc9c0\ub9ac\uc801\uc73c\ub85c \ub354 \uac00\uae4c\uc6b4 \uc11c\ubc84\ub85c \ub9ac\ub2e4\uc774\ub809\uc158\ud558\uc5ec \uc9c0\uc5f0 \uc2dc\uac04\uc744 \ub2e8\ucd95\uc2dc\ud0a8\ub2e4."]}),"\n",(0,r.jsx)(n.admonition,{title:"\ub0b4\uacb0\ud568\uc131(Fault Tolerance)\uacfc \ud655\uc7a5\uc131(Scalability)",type:"note",children:(0,r.jsxs)(n.p,{children:["\ub0b4\uacb0\ud568\uc131: \uc2dc\uc2a4\ud15c\uc758 \uc77c\ubd80 \uad6c\uc131 \uc694\uc18c\uac00 \uc791\ub3d9\ud558\uc9c0 \uc54a\ub354\ub77c\ub3c4 \uacc4\uc18d \uc791\ub3d9\ud560 \uc218 \uc788\ub294 \uae30\ub2a5",(0,r.jsx)(n.br,{}),"\n","\ud655\uc7a5\uc131: \ub300\uaddc\ubaa8\uc801\uc778 \uc7ac\uc124\uacc4/\uc7ac\uc124\uce58 \ub4f1\uc758 \ud544\uc694\uc5c6\uc774 \ud655\uc7a5\uc774 \uc5bc\ub9c8\ub098 \uc27d\uace0 \uac00\ub2a5\ud55c\uac00\uc5d0 \ub300\ud55c \uc6a9\uc774\uc131"]})}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.a,{href:"https://aws.amazon.com/ko/what-is/load-balancing/",children:"load balancing, AWS"})})]})}function p(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>s});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function l(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=r.createContext({}),s=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},p=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,c=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),u=s(t),b=a,m=u["".concat(c,".").concat(b)]||u[b]||d[b]||o;return t?r.createElement(m,i(i({ref:n},p),{},{components:t})):r.createElement(m,i({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/caf1b628.f649b595.js b/assets/js/caf1b628.f649b595.js deleted file mode 100644 index 6aef897fb..000000000 --- a/assets/js/caf1b628.f649b595.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7230],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),c=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),m=c(n),d=a,b=m["".concat(p,".").concat(d)]||m[d]||s[d]||o;return n?r.createElement(b,l(l({ref:t},u),{},{components:n})):r.createElement(b,l({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,l=new Array(o);l[0]=m;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:a,l[1]=i;for(var c=2;c<o;c++)l[c]=n[c];return r.createElement.apply(null,l)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},16711:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>s,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const o={title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",slug:"/network/load-balancing",last_update:{date:"2023/09/04"},tags:["network","load balancing"]},l=void 0,i={unversionedId:"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1",id:"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1",title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",description:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?",source:"@site/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1.mdx",sourceDirName:"\ub124\ud2b8\uc6cc\ud06c",slug:"/network/load-balancing",permalink:"/docs/network/load-balancing",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1.mdx",tags:[{label:"network",permalink:"/docs/tags/network"},{label:"load balancing",permalink:"/docs/tags/load-balancing"}],version:"current",lastUpdatedAt:1693785600,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 4\uc77c",frontMatter:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1",slug:"/network/load-balancing",last_update:{date:"2023/09/04"},tags:["network","load balancing"]},sidebar:"tutorialSidebar",previous:{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998",permalink:"/docs/network/load-balancing-algorithm"},next:{title:"maximumPoolSize",permalink:"/docs/database/maximumPoolSize"}},p={},c=[{value:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?",id:"\ub85c\ub4dc-\ubc38\ub7f0\uc2f1\uc774\ub780",level:3},{value:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc758 \uc7a5\uc810",id:"\ub85c\ub4dc-\ubc38\ub7f0\uc2f1\uc758-\uc7a5\uc810",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:c};function s(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ub85c\ub4dc-\ubc38\ub7f0\uc2f1\uc774\ub780"},"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc774\ub780?"),(0,a.kt)("p",null,"\uc11c\ubc84\uac00 \ucc98\ub9ac\ud574\uc57c \ud560 \uc694\uccad\uc744 \uc5ec\ub7ec \ub300\uc758 \uc11c\ubc84\ub85c \ub098\ub204\uc5b4 \ucc98\ub9ac\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc740 \ub85c\ub4dc \ubc38\ub7f0\uc11c\ub97c \ud1b5\ud574 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. "),(0,a.kt)("admonition",{title:"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uacfc \ub85c\ub4dc \ubc38\ub7f0\uc11c",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ub85c\ub4dc \ubc38\ub7f0\uc2f1: \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc9c0\uc6d0\ud558\ub294 \ub9ac\uc18c\uc2a4 \ud480 \uc804\uccb4\uc5d0 \ub124\ud2b8\uc6cc\ud06c \ud2b8\ub798\ud53d\uc744 \uade0\ub4f1\ud558\uac8c \ubc30\ud3ec\ud558\ub294 \ubc29\ubc95",(0,a.kt)("br",{parentName:"p"}),"\n","\ub85c\ub4dc \ubc38\ub7f0\uc11c: \uc0ac\uc6a9\uc790\uc640 \uc11c\ubc84 \uadf8\ub8f9 \uc0ac\uc774\uc5d0 \uc704\uce58\ud558\uba70 \ubcf4\uc774\uc9c0 \uc54a\ub294 \ucd09\uc9c4\uc790 \uc5ed\ud560\uc744 \ud558\uc5ec \ubaa8\ub4e0 \ub9ac\uc18c\uc2a4 \uc11c\ubc84\uac00 \ub3d9\uc77c\ud558\uac8c \uc0ac\uc6a9\ub418\ub3c4\ub85d \ud558\ub294 \ub514\ubc14\uc774\uc2a4")),(0,a.kt)("h3",{id:"\ub85c\ub4dc-\ubc38\ub7f0\uc2f1\uc758-\uc7a5\uc810"},"\ub85c\ub4dc \ubc38\ub7f0\uc2f1\uc758 \uc7a5\uc810"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uac00\uc6a9\uc131")),(0,a.kt)("p",null,"\uc11c\ubc84\uc5d0 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ub85c\ub4dc\ubc38\ub7f0\uc11c\uac00 \ud574\ub2f9 \ubb38\uc81c\ub97c \uac10\uc9c0(\ud5ec\uc2a4 \uccb4\ud06c\ub97c \ud1b5\ud574)\ud558\uc5ec \ud2b8\ub798\ud53d\uc744 \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc11c\ubc84\ub85c \ubcf4\ub0c4\uc73c\ub85c\uc368 \ub0b4\uacb0\ud568\uc131\uc744 \ub192\ud78c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub85c\ub4dc\ubc38\ub7f0\uc11c\ub97c \ud65c\uc6a9\ud55c \ubb34\uc911\ub2e8 \ubc30\ud3ec "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud655\uc7a5\uc131")),(0,a.kt)("p",null,"\uc218\ud3c9 \ud655\uc7a5\uc131(Horizontal Scalability) \uc6a9\uc774",(0,a.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0 AutoScaling\uc744 \ud1b5\ud574 \uc11c\ubc84\ub97c \uc790\ub3d9\uc73c\ub85c \ud655\uc7a5(Scale-out)",(0,a.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub798\ud53d\uc774 \uac10\uc18c\ud558\ub294 \uacbd\uc6b0 \ucd95\uc18c(Scale-in) "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ubcf4\uc548")),(0,a.kt)("p",null,"\ubd84\uc0b0 \uc11c\ube44\uc2a4 \uac70\ubd80 \uacf5\uaca9(DDoS)\uc774 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ud574\ub2f9 \ud2b8\ub798\ud53d\uc744 \ubd80\ud558 \ubd84\uc0b0\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc131\ub2a5")),(0,a.kt)("p",null,"\uc11c\ubc84 \uac04 \ub85c\ub4dc\ub97c \uade0\ub4f1\ud558\uac8c \ubc30\ud3ec\ud558\uc5ec \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc131\ub2a5\uc744 \ud5a5\uc0c1 \uc2dc\ud0a8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud074\ub77c\uc774\uc5b8\ud2b8 \uc694\uccad\uc744 \uc9c0\ub9ac\uc801\uc73c\ub85c \ub354 \uac00\uae4c\uc6b4 \uc11c\ubc84\ub85c \ub9ac\ub2e4\uc774\ub809\uc158\ud558\uc5ec \uc9c0\uc5f0 \uc2dc\uac04\uc744 \ub2e8\ucd95\uc2dc\ud0a8\ub2e4. "),(0,a.kt)("admonition",{title:"\ub0b4\uacb0\ud568\uc131(Fault Tolerance)\uacfc \ud655\uc7a5\uc131(Scalability)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ub0b4\uacb0\ud568\uc131: \uc2dc\uc2a4\ud15c\uc758 \uc77c\ubd80 \uad6c\uc131 \uc694\uc18c\uac00 \uc791\ub3d9\ud558\uc9c0 \uc54a\ub354\ub77c\ub3c4 \uacc4\uc18d \uc791\ub3d9\ud560 \uc218 \uc788\ub294 \uae30\ub2a5",(0,a.kt)("br",{parentName:"p"}),"\n","\ud655\uc7a5\uc131: \ub300\uaddc\ubaa8\uc801\uc778 \uc7ac\uc124\uacc4/\uc7ac\uc124\uce58 \ub4f1\uc758 \ud544\uc694\uc5c6\uc774 \ud655\uc7a5\uc774 \uc5bc\ub9c8\ub098 \uc27d\uace0 \uac00\ub2a5\ud55c\uac00\uc5d0 \ub300\ud55c \uc6a9\uc774\uc131")),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/what-is/load-balancing/"},"load balancing, AWS")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/cb6229c3.5653afa0.js b/assets/js/cb6229c3.5653afa0.js new file mode 100644 index 000000000..afef57269 --- /dev/null +++ b/assets/js/cb6229c3.5653afa0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7204],{95940:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>i});var t=r(85893),l=r(3905);const a={title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"mysql-lock",tags:["DataBase","Lock","MySQL"]},c=void 0,s={permalink:"/mysql-lock",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",source:"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",description:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",date:"2023-04-06T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 6\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Lock",permalink:"/tags/lock"},{label:"MySQL",permalink:"/tags/my-sql"}],readingTime:4.405,hasTruncateMarker:!1,authors:[],frontMatter:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"mysql-lock",tags:["DataBase","Lock","MySQL"]},unlisted:!1,prevItem:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/innodb-lock"},nextItem:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",permalink:"/transaction-and-isolation"}},o={authorsImageUrls:[]},i=[{value:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",id:"mysql-\uc5d4\uc9c4\uc758-\uc7a0\uae08",level:2},{value:"\uae00\ub85c\ubc8c \ub77d(Global lock)",id:"\uae00\ub85c\ubc8c-\ub77dglobal-lock",level:3},{value:"\ud14c\uc774\ube14 \ub77d(Table lock)",id:"\ud14c\uc774\ube14-\ub77dtable-lock",level:3},{value:"\ub124\uc784\ub4dc \ub77d(Named lock)",id:"\ub124\uc784\ub4dc-\ub77dnamed-lock",level:3},{value:"\uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)",id:"\uba54\ud0c0\ub370\uc774\ud130-\ub77dmetadata-lock",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"mysql-\uc5d4\uc9c4\uc758-\uc7a0\uae08",children:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08"}),"\n",(0,t.jsxs)(n.p,{children:["MySQL\uc5d0\uc11c\uc758 \ub77d\uc740 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub808\ubca8\uacfc, MySQL \uc5d4\uc9c4 \ub808\ubca8\ub85c \ub098\ub20c \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MySQL \uc5d4\uc9c4 \ub808\ubca8\uc758 \uc7a0\uae08\uc740 \ubaa8\ub4e0 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce5c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uae00\ub85c\ubc8c-\ub77dglobal-lock",children:"\uae00\ub85c\ubc8c \ub77d(Global lock)"}),"\n",(0,t.jsx)(n.p,{children:"MySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08 \uc911 \uac00\uc7a5 \ub113\uc740 \ubc94\uc704\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \uc7a0\uae08\uc774\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc601\ud5a5\uc744 \ubbf8\uce58\ub294 \ubc94\uc704\ub294 \ud574\ub2f9 \uc11c\ubc84 \uc804\uccb4\uc774\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uc791\uc5c5 \ub300\uc0c1 \ud14c\uc774\ube14, \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0c1\uad00 \uc5c6\uc774 \ub3d9\uc77c\ud558\uac8c \uc601\ud5a5\uc744 \ubc1b\ub294\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\ud55c \uc138\uc158\uc5d0\uc11c \uae00\ub85c\ubc8c \ub77d\uc744 \ud68d\ub4dd\ud558\uba74 \ud574\uc81c \ub420 \ub54c \uae4c\uc9c0 \uc870\ud68c\ub97c \uc81c\uc678\ud55c \ub300\ubd80\ubd84\uc758 \uba85\ub839\uc774 \ub300\uae30 \uc0c1\ud0dc\uac00 \ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc874\uc7ac\ud558\ub294 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub300\ud574 \uc77c\uad00\ub41c \ubc31\uc5c5\uc744 \ubc1b\uc544\uc57c\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c\ub294 \ubc31\uc5c5 \uc2dc \uc870\uae08 \ub354 \uac00\ubcbc\uc6b4 \ubc31\uc5c5 \ub77d\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sql",children:"-- GLOBAL LOCK\nFLUSH TABLES WITH READ LOCK;\n-- UNLOCK\nUNLOCK TABLES;\n\n-- BACKUP LOCK\nLOCK INSTANCE FOR BACKUP;\n-- UNLOCK\nUNLOCK INSTANCE;\n"})}),"\n",(0,t.jsx)(n.admonition,{title:"MyISAM",type:"note",children:(0,t.jsxs)(n.p,{children:["MySQL 5.5 \ubc84\uc804 \uc774\uc804\uc758 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uace0, SELECT \uc791\uc5c5 \uc18d\ub3c4\uac00 \ube60\ub974\ub2e4."]})}),"\n",(0,t.jsx)(n.h3,{id:"\ud14c\uc774\ube14-\ub77dtable-lock",children:"\ud14c\uc774\ube14 \ub77d(Table lock)"}),"\n",(0,t.jsxs)(n.p,{children:["\uac1c\ubcc4 \ud14c\uc774\ube14 \ub2e8\uc704\ub85c \uc124\uc815\ub418\ub294 \uc7a0\uae08\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba85\uc2dc\uc801 \ub610\ub294 \ubb35\uc2dc\uc801\uc73c\ub85c \ud2b9\uc815 \ud14c\uc774\ube14\uc758 \ub77d\uc744 \ud68d\ub4dd\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubb35\uc2dc\uc801 \ub77d\uc740 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub294 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uba74 \ubc1c\uc0dd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","InnoDB \ud14c\uc774\ube14\uc5d0\ub294 DML \ucffc\ub9ac\ub294 \ubb34\uc2dc\ub418\uace0 DDL \uc77c \uacbd\uc6b0\uc5d0\ub9cc \ubb35\uc2dc\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sql",children:"-- TABLE LOCK\nLOCK TABLES table_name [ READ | WRITE ]\n\n-- UNLOCK\nUNLOCK TABLES;\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\ub124\uc784\ub4dc-\ub77dnamed-lock",children:"\ub124\uc784\ub4dc \ub77d(Named lock)"}),"\n",(0,t.jsxs)(n.p,{children:["\uc784\uc758\uc758 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \uc124\uc815\ud560 \uc218 \uc788\ub294 \uc7a0\uae08\uc73c\ub85c \uc720\uc800 \ub808\ubca8 \ub77d\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc5ec\ub7ec \uc2a4\ub808\ub4dc\ub098 \ud504\ub85c\uc138\uc2a4\uac00 \ub3d9\uc77c\ud55c \ub370\uc774\ud130\ub97c \uc218\uc815\ud558\ub824\ub294 \uacbd\uc6b0, \ub3d9\uc2dc\uc5d0 \uc218\uc815\ud558\uc9c0 \ubabb\ud558\ub3c4\ub85d \ubcf4\ud638\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sql",children:"-- aGVyYg== \ub77c\ub294 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08 \ud68d\ub4dd, \uc774\ubbf8 \uc7a0\uae08\uc744 \uc0ac\uc6a9\uc911\uc778 \uacbd\uc6b0 1\ucd08 \ub3d9\uc548\ub9cc \ub300\uae30\nSELECT GET_LOCK('aGVyYg==', 1);\n\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc774 \uc124\uc815\ub418\uc5b4 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.\nSELECT IS_FREE_LOCK('aGVyYg==');\n\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4.\nSELECT RELEASE_LOCK('aGVyYg==');\n\n-- \uc704 3\uac1c \ud568\uc218 \ubaa8\ub450 \uc815\uc0c1\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud558\uac70\ub098 \ud574\uc81c\ud55c \uacbd\uc6b0\uc5d0 1\uc744, \uc544\ub2c8\uba74 0\uc744 \ubc18\ud658\ud55c\ub2e4.\n\n-- \ubaa8\ub4e0 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4. \ud574\uc81c\ub41c \uc7a0\uae08\uc758 \uac1c\uc218\ub97c \ubc18\ud658\ud55c\ub2e4.\nSELECT RELEASE_ALL_LOCKS();\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\uba54\ud0c0\ub370\uc774\ud130-\ub77dmetadata-lock",children:"\uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)"}),"\n",(0,t.jsxs)(n.p,{children:["\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac1d\uccb4\uc758 \uc774\ub984\uc774\ub098 \uad6c\uc870\ub97c \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \ud68d\ub4dd\ud558\ub294 \uc7a0\uae08\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba85\uc2dc\uc801\uc73c\ub85c \ud68d\ub4dd \ub610\ub294 \ud574\uc81c \ud560 \uc218 \uc5c6\uc9c0\ub9cc \ud14c\uc774\ube14\uc758 \uc774\ub984\uc744 \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubcf4\ud1b5 \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc2e4\uc2dc\uac04\uc73c\ub85c \ud14c\uc774\ube14\uc744 \ubc14\uafd4\uc57c\ud558\ub294 \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sql",children:"-- \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \ubcc4\ub3c4\uc758 \uc784\uc2dc \ud14c\uc774\ube14\uc5d0 \uc11c\ube44\uc2a4\uc6a9 \ub7ad\ud0b9 \ub370\uc774\ud130 \uc0dd\uc131 \ud6c4 \uae30\uc874 \ud14c\uc774\ube14\uc744 \ubc31\uc5c5\ud558\ub294 \uacbd\uc6b0\n-- \uc544\ub798 \uad6c\ubb38 \uc2e4\ud589 \uc2dc \uba54\ud0c0\ub370\uc774\ud130 \ub77d\uc744 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.\nRENAME TABLE rank TO rank_backup, rank_new TO rank;\n"})}),"\n",(0,t.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:["Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://gywn.net/2013/12/mysql-user-level-lock/",children:"MySQL\uc758 User Level Lock\ub97c \ud65c\uc6a9\ud55c\ub2e4\uba74?, gywndi"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html#function_release-all-locks",children:"Locking Functions, MySQL 5.7 Reference"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_release-all-locks",children:"Locking Functions, MySQL 8.0 Reference"})]})]})}function p(e={}){const{wrapper:n}={...(0,l.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>i});var t=r(67294);function l(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function c(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?a(Object(r),!0).forEach((function(n){l(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function s(e,n){if(null==e)return{};var r,t,l=function(e,n){if(null==e)return{};var r,t,l={},a=Object.keys(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||(l[r]=e[r]);return l}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(l[r]=e[r])}return l}var o=t.createContext({}),i=function(e){var n=t.useContext(o),r=n;return e&&(r="function"==typeof e?e(n):c(c({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,l=e.mdxType,a=e.originalType,o=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=i(r),m=l,h=u["".concat(o,".").concat(m)]||u[m]||d[m]||a;return r?t.createElement(h,c(c({ref:n},p),{},{components:r})):t.createElement(h,c({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/cb6229c3.61e1a1f5.js b/assets/js/cb6229c3.61e1a1f5.js deleted file mode 100644 index e99224490..000000000 --- a/assets/js/cb6229c3.61e1a1f5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7204],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),i=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},m=function(e){var t=i(e.components);return a.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},k=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),k=i(n),u=r,y=k["".concat(p,".").concat(u)]||k[u]||s[u]||l;return n?a.createElement(y,o(o({ref:t},m),{},{components:n})):a.createElement(y,o({ref:t},m))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=k;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c.mdxType="string"==typeof e?e:r,o[1]=c;for(var i=2;i<l;i++)o[i]=n[i];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}k.displayName="MDXCreateElement"},26930:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>s,frontMatter:()=>l,metadata:()=>c,toc:()=>i});var a=n(87462),r=(n(67294),n(3905));const l={title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"mysql-lock",tags:["DataBase","Lock","MySQL"]},o=void 0,c={permalink:"/mysql-lock",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",source:"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",description:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",date:"2023-04-06T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 6\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Lock",permalink:"/tags/lock"},{label:"MySQL",permalink:"/tags/my-sql"}],readingTime:4.405,hasTruncateMarker:!1,authors:[],frontMatter:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"mysql-lock",tags:["DataBase","Lock","MySQL"]},prevItem:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/innodb-lock"},nextItem:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",permalink:"/transaction-and-isolation"}},p={authorsImageUrls:[]},i=[{value:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",id:"mysql-\uc5d4\uc9c4\uc758-\uc7a0\uae08",level:2},{value:"\uae00\ub85c\ubc8c \ub77d(Global lock)",id:"\uae00\ub85c\ubc8c-\ub77dglobal-lock",level:3},{value:"\ud14c\uc774\ube14 \ub77d(Table lock)",id:"\ud14c\uc774\ube14-\ub77dtable-lock",level:3},{value:"\ub124\uc784\ub4dc \ub77d(Named lock)",id:"\ub124\uc784\ub4dc-\ub77dnamed-lock",level:3},{value:"\uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)",id:"\uba54\ud0c0\ub370\uc774\ud130-\ub77dmetadata-lock",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],m={toc:i};function s(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"mysql-\uc5d4\uc9c4\uc758-\uc7a0\uae08"},"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08"),(0,r.kt)("p",null,"MySQL\uc5d0\uc11c\uc758 \ub77d\uc740 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub808\ubca8\uacfc, MySQL \uc5d4\uc9c4 \ub808\ubca8\ub85c \ub098\ub20c \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MySQL \uc5d4\uc9c4 \ub808\ubca8\uc758 \uc7a0\uae08\uc740 \ubaa8\ub4e0 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce5c\ub2e4. "),(0,r.kt)("h3",{id:"\uae00\ub85c\ubc8c-\ub77dglobal-lock"},"\uae00\ub85c\ubc8c \ub77d(Global lock)"),(0,r.kt)("p",null,"MySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08 \uc911 \uac00\uc7a5 \ub113\uc740 \ubc94\uc704\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \uc7a0\uae08\uc774\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc601\ud5a5\uc744 \ubbf8\uce58\ub294 \ubc94\uc704\ub294 \ud574\ub2f9 \uc11c\ubc84 \uc804\uccb4\uc774\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc791\uc5c5 \ub300\uc0c1 \ud14c\uc774\ube14, \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0c1\uad00 \uc5c6\uc774 \ub3d9\uc77c\ud558\uac8c \uc601\ud5a5\uc744 \ubc1b\ub294\ub2e4.")),(0,r.kt)("p",null,"\ud55c \uc138\uc158\uc5d0\uc11c \uae00\ub85c\ubc8c \ub77d\uc744 \ud68d\ub4dd\ud558\uba74 \ud574\uc81c \ub420 \ub54c \uae4c\uc9c0 \uc870\ud68c\ub97c \uc81c\uc678\ud55c \ub300\ubd80\ubd84\uc758 \uba85\ub839\uc774 \ub300\uae30 \uc0c1\ud0dc\uac00 \ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc874\uc7ac\ud558\ub294 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub300\ud574 \uc77c\uad00\ub41c \ubc31\uc5c5\uc744 \ubc1b\uc544\uc57c\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c\ub294 \ubc31\uc5c5 \uc2dc \uc870\uae08 \ub354 \uac00\ubcbc\uc6b4 \ubc31\uc5c5 \ub77d\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- GLOBAL LOCK\nFLUSH TABLES WITH READ LOCK;\n-- UNLOCK\nUNLOCK TABLES;\n\n-- BACKUP LOCK\nLOCK INSTANCE FOR BACKUP;\n-- UNLOCK\nUNLOCK INSTANCE;\n")),(0,r.kt)("admonition",{title:"MyISAM",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"MySQL 5.5 \ubc84\uc804 \uc774\uc804\uc758 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uace0, SELECT \uc791\uc5c5 \uc18d\ub3c4\uac00 \ube60\ub974\ub2e4.")),(0,r.kt)("h3",{id:"\ud14c\uc774\ube14-\ub77dtable-lock"},"\ud14c\uc774\ube14 \ub77d(Table lock)"),(0,r.kt)("p",null,"\uac1c\ubcc4 \ud14c\uc774\ube14 \ub2e8\uc704\ub85c \uc124\uc815\ub418\ub294 \uc7a0\uae08\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uba85\uc2dc\uc801 \ub610\ub294 \ubb35\uc2dc\uc801\uc73c\ub85c \ud2b9\uc815 \ud14c\uc774\ube14\uc758 \ub77d\uc744 \ud68d\ub4dd\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubb35\uc2dc\uc801 \ub77d\uc740 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub294 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uba74 \ubc1c\uc0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB \ud14c\uc774\ube14\uc5d0\ub294 DML \ucffc\ub9ac\ub294 \ubb34\uc2dc\ub418\uace0 DDL \uc77c \uacbd\uc6b0\uc5d0\ub9cc \ubb35\uc2dc\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- TABLE LOCK\nLOCK TABLES table_name [ READ | WRITE ]\n\n-- UNLOCK\nUNLOCK TABLES;\n")),(0,r.kt)("h3",{id:"\ub124\uc784\ub4dc-\ub77dnamed-lock"},"\ub124\uc784\ub4dc \ub77d(Named lock)"),(0,r.kt)("p",null,"\uc784\uc758\uc758 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \uc124\uc815\ud560 \uc218 \uc788\ub294 \uc7a0\uae08\uc73c\ub85c \uc720\uc800 \ub808\ubca8 \ub77d\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc5ec\ub7ec \uc2a4\ub808\ub4dc\ub098 \ud504\ub85c\uc138\uc2a4\uac00 \ub3d9\uc77c\ud55c \ub370\uc774\ud130\ub97c \uc218\uc815\ud558\ub824\ub294 \uacbd\uc6b0, \ub3d9\uc2dc\uc5d0 \uc218\uc815\ud558\uc9c0 \ubabb\ud558\ub3c4\ub85d \ubcf4\ud638\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- aGVyYg== \ub77c\ub294 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08 \ud68d\ub4dd, \uc774\ubbf8 \uc7a0\uae08\uc744 \uc0ac\uc6a9\uc911\uc778 \uacbd\uc6b0 1\ucd08 \ub3d9\uc548\ub9cc \ub300\uae30\nSELECT GET_LOCK('aGVyYg==', 1);\n\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc774 \uc124\uc815\ub418\uc5b4 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.\nSELECT IS_FREE_LOCK('aGVyYg==');\n\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4.\nSELECT RELEASE_LOCK('aGVyYg==');\n\n-- \uc704 3\uac1c \ud568\uc218 \ubaa8\ub450 \uc815\uc0c1\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud558\uac70\ub098 \ud574\uc81c\ud55c \uacbd\uc6b0\uc5d0 1\uc744, \uc544\ub2c8\uba74 0\uc744 \ubc18\ud658\ud55c\ub2e4.\n\n-- \ubaa8\ub4e0 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4. \ud574\uc81c\ub41c \uc7a0\uae08\uc758 \uac1c\uc218\ub97c \ubc18\ud658\ud55c\ub2e4.\nSELECT RELEASE_ALL_LOCKS();\n")),(0,r.kt)("h3",{id:"\uba54\ud0c0\ub370\uc774\ud130-\ub77dmetadata-lock"},"\uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)"),(0,r.kt)("p",null,"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac1d\uccb4\uc758 \uc774\ub984\uc774\ub098 \uad6c\uc870\ub97c \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \ud68d\ub4dd\ud558\ub294 \uc7a0\uae08\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uba85\uc2dc\uc801\uc73c\ub85c \ud68d\ub4dd \ub610\ub294 \ud574\uc81c \ud560 \uc218 \uc5c6\uc9c0\ub9cc \ud14c\uc774\ube14\uc758 \uc774\ub984\uc744 \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubcf4\ud1b5 \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc2e4\uc2dc\uac04\uc73c\ub85c \ud14c\uc774\ube14\uc744 \ubc14\uafd4\uc57c\ud558\ub294 \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\ub41c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \ubcc4\ub3c4\uc758 \uc784\uc2dc \ud14c\uc774\ube14\uc5d0 \uc11c\ube44\uc2a4\uc6a9 \ub7ad\ud0b9 \ub370\uc774\ud130 \uc0dd\uc131 \ud6c4 \uae30\uc874 \ud14c\uc774\ube14\uc744 \ubc31\uc5c5\ud558\ub294 \uacbd\uc6b0\n-- \uc544\ub798 \uad6c\ubb38 \uc2e4\ud589 \uc2dc \uba54\ud0c0\ub370\uc774\ud130 \ub77d\uc744 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.\nRENAME TABLE rank TO rank_backup, rank_new TO rank;\n")),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://gywn.net/2013/12/mysql-user-level-lock/"},"MySQL\uc758 User Level Lock\ub97c \ud65c\uc6a9\ud55c\ub2e4\uba74?, gywndi"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html#function_release-all-locks"},"Locking Functions, MySQL 5.7 Reference"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_release-all-locks"},"Locking Functions, MySQL 8.0 Reference")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/cc3bdf2f.5664f42d.js b/assets/js/cc3bdf2f.b73cfef6.js similarity index 84% rename from assets/js/cc3bdf2f.5664f42d.js rename to assets/js/cc3bdf2f.b73cfef6.js index 83502756c..a9b856834 100644 --- a/assets/js/cc3bdf2f.5664f42d.js +++ b/assets/js/cc3bdf2f.b73cfef6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8817],{11135:e=>{e.exports=JSON.parse('{"label":"exception","permalink":"/tags/exception","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8817],{11135:e=>{e.exports=JSON.parse('{"label":"exception","permalink":"/tags/exception","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/cc519f63.46c3d20e.js b/assets/js/cc519f63.46c3d20e.js new file mode 100644 index 000000000..d6fa36b61 --- /dev/null +++ b/assets/js/cc519f63.46c3d20e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5323],{75824:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var i=t(85893),r=t(3905);const o={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",slug:"route-image-implementation",tags:["image","awt"]},a=void 0,s={permalink:"/route-image-implementation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",source:"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",description:"\uac1c\uc694",date:"2023-08-02T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 2\uc77c",tags:[{label:"image",permalink:"/tags/image"},{label:"awt",permalink:"/tags/awt"}],readingTime:11.665,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",slug:"route-image-implementation",tags:["image","awt"]},unlisted:!1,prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",permalink:"/route-image-async-with-event"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",permalink:"/route-image-python"}},l={authorsImageUrls:[]},d=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:2},{value:"\uad6c\ud604 \uacb0\uacfc",id:"\uad6c\ud604-\uacb0\uacfc",level:3},{value:"IMAGE_SIZE & ROUTE_SIZE",id:"image_size--route_size",level:3},{value:"\uc8fc\uc694 \ud074\ub798\uc2a4",id:"\uc8fc\uc694-\ud074\ub798\uc2a4",level:2},{value:"\uc694\uc57d",id:"\uc694\uc57d",level:3},{value:"\uc758\uc874\uad00\uacc4",id:"\uc758\uc874\uad00\uacc4",level:3},{value:"Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)",id:"coordinates\uc704\ub3c4-\uacbd\ub3c4\uc758-\uc77c\uae09-\uceec\ub809\uc158",level:3},{value:"Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)",id:"positions\uc2e4\uc81c-\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc5d0-\uc0ac\uc6a9\ud560-\uc704\uce58",level:3},{value:"RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)",id:"routeimagedrawer\uc2e4\uc81c-\uc774\ubbf8\uc9c0\uc5d0-\uacbd\ub85c\ub97c-\uadf8\ub824\uc8fc\ub294-\ud074\ub798\uc2a4",level:3},{value:"\uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow",id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131-flow",level:2},{value:"1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44",id:"1-\uc774\ubbf8\uc9c0-\uc0dd\uc131-\uc900\ube44",level:3},{value:"2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad",id:"2-\uc120-\uadf8\ub9ac\uae30-\uc694\uccad",level:3},{value:"3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad",id:"3-\uc704\uce58-\uc810-\uadf8\ub9ac\uae30-\uc694\uccad",level:3},{value:"4. \uc5c5\ub85c\ub4dc \uc694\uccad",id:"4-\uc5c5\ub85c\ub4dc-\uc694\uccad",level:3},{value:"\uc804\uccb4 Flow",id:"\uc804\uccb4-flow",level:3}];function c(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.ah)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h2,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,i.jsxs)(n.p,{children:["\uc5ec\ud589\uc5d0 \ub300\ud55c \uacbd\ub85c\ub97c \ubcf4\uc5ec\uc8fc\uae30 \uc704\ud574 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d \ubc0f \uae30\uc220 \uc120\ud0dd\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 ",(0,i.jsx)(n.a,{href:"./route-image-intro",children:"\ub9c1\ud06c"}),"\uc5d0 \uc788\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"\uad6c\ud604-\uacb0\uacfc",children:"\uad6c\ud604 \uacb0\uacfc"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"./result.png",src:t(59563).Z+"",width:"1840",height:"714"})}),"\n",(0,i.jsxs)(n.p,{children:["\uc608\uc2dc \ub370\uc774\ud130\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.",(0,i.jsx)(n.br,{}),"\n",(0,i.jsx)(n.strong,{children:"\uc11c\uc6b8\uc5ed(\uc810)"})," \u2192 \uc2e0\uc0ac\uc5ed \u2192 \ub178\ub7c9\uc9c4\uc5ed \u2192 \ud64d\ub300\uc785\uad6c\uc5ed \u2192 \uc885\ub85c3\uac00\uc5ed \u2192 \uc625\uc218\uc5ed \u2192 ",(0,i.jsx)(n.strong,{children:"\uad6c\ub85c\uc5ed(\uc810)"})," \u2192 \uc2e0\ub9bc\uc5ed \u2192 \ubc1c\uc0b0\uc5ed"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="\uc608\uc2dc \ub370\uc774\ud130"',children:"List<Double> x = List.of(\n 126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,\n 126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639\n);\nList<Double> y = List.of(\n 37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,\n 37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184\n);\nList<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);\nList<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);\n"})}),"\n",(0,i.jsx)(n.h3,{id:"image_size--route_size",children:"IMAGE_SIZE & ROUTE_SIZE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="RouteImageGenerator.java"',children:"private static final int IMAGE_SIZE = 800;\nprivate static final int ROUTE_SIZE = 600;\n"})}),"\n",(0,i.jsxs)(n.p,{children:["\ucf54\ub4dc\ub97c \ubcf4\uba74 IMAGE_SIZE\uc640 ROUTE_SIZE\uac00 \uc788\ub2e4.",(0,i.jsx)(n.br,{}),"\n","IMAGE_SIZE\ub294 \ub9d0 \uadf8\ub300\ub85c \uc774\ubbf8\uc9c0\uc758 width\uc640 height\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","ROUTE_SIZE\uc758 \uacbd\uc6b0 \uc0c1\ud558\uc88c\uc6b0 100px \ub9cc\ud07c\uc758 \uac04\uaca9\uc744 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc2e4\uc81c \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub294 600 * 600 \uc0ac\uc774\uc988\ub85c \uc0dd\uc131\ub41c\ub2e4."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"./600.png",src:t(49812).Z+"",width:"976",height:"970"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"\uc0ac\uc774\uc988 \ubcc0\uacbd\uc758 \uc774\uc720"})}),"\n",(0,i.jsx)(n.p,{children:"255 * 255 \uc815\ub3c4\uc758 \uc791\uc740 \uc0ac\uc774\uc988\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud574\ubcf4\ub824\uace0 \ud588\ub294\ub370, \uc774\ubbf8\uc9c0\uc758 \uc120\uba85\ub3c4\uac00 \uc88b\uc9c0 \uc54a\uc544 800 * 800 \uc0ac\uc774\uc988\ub85c \ubcc0\uacbd\ud588\ub2e4."}),"\n",(0,i.jsx)(n.h2,{id:"\uc8fc\uc694-\ud074\ub798\uc2a4",children:"\uc8fc\uc694 \ud074\ub798\uc2a4"}),"\n",(0,i.jsx)(n.h3,{id:"\uc694\uc57d",children:"\uc694\uc57d"}),"\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"\ud074\ub798\uc2a4\uba85"}),(0,i.jsx)(n.th,{children:"\uc124\uba85"}),(0,i.jsx)(n.th,{children:"\ud2b9\uc774\uc0ac\ud56d"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Coordinate"}),(0,i.jsx)(n.td,{children:"\uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \uc704\uce58 \uac12"}),(0,i.jsx)(n.td,{children:"\uc88c\ud45c\ub97c \ub73b\ud558\uc9c0\ub9cc \uc5ec\ud589 \ub3c4\uba54\uc778\uc5d0 \ud3ec\ud568\ub41c Point \ud074\ub798\uc2a4\uc640 \uad6c\ubd84\ud558\uae30 \uc704\ud574 longitude, latitude\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 x, y \uc0ac\uc6a9"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Coordinates"}),(0,i.jsx)(n.td,{children:"Coordinate\uc758 \uc77c\uae09 \uceec\ub809\uc158"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Position"}),(0,i.jsx)(n.td,{children:"\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58 \uac12"}),(0,i.jsx)(n.td,{children:"Integer \ud0c0\uc785\uc758 x, y \uc0ac\uc6a9"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Positions"}),(0,i.jsx)(n.td,{children:"Positions\uc758 \uc77c\uae09 \uceec\ub809\uc158"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RouteImageDrawer"}),(0,i.jsx)(n.td,{children:"\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4 BufferedImage, Graphics2D\ub97c \uac00\uc9c0\uace0 \uc788\uc74c"}),(0,i.jsx)(n.td,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc0c1\uc218\uac00 \uc815\uc758\ub418\uc5b4 \uc788\uc74c"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RouteImageUploader"}),(0,i.jsx)(n.td,{children:"BufferedImage\ub97c \ubc1b\uc544 \uc11c\ubc84\uc5d0 \uc5c5\ub85c\ub4dc \ud558\ub294 \ud074\ub798\uc2a4"}),(0,i.jsx)(n.td,{children:"\ud604\uc7ac \uc5c5\ub85c\ub4dc \uc704\uce58\uac00 \uc815\ud574\uc9c0\uc9c0 \uc54a\uc544 \uc77c\ub2e8 \uae30\ubcf8(\ud504\ub85c\uc81d\ud2b8 \ub8e8\ud2b8) \uc704\uce58\uc5d0 \uc0dd\uc131"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RouteImageGenerator"}),(0,i.jsx)(n.td,{children:"\uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uace0 \uc5c5\ub85c\ub4dc\ud558\ub294 \uc11c\ube44\uc2a4"}),(0,i.jsx)(n.td,{children:"\uc5ec\ud589 \uc885\ub8cc, \uac10\uc0c1 \uc800\uc7a5\uc2dc \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \ud1b5\ud574 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BufferedImage(AWT)"}),(0,i.jsx)(n.td,{children:"\uc774\ubbf8\uc9c0 \ub370\uc774\ud130\ub97c \ucc98\ub9ac\ud558\uace0 \uc870\uc791\ud558\ub294 \ub370 \uc0ac\uc6a9"}),(0,i.jsx)(n.td,{children:"\uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c\uac00 (0, 0)"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Graphics2D(AWT)"}),(0,i.jsx)(n.td,{children:"\uc120 \uadf8\ub9ac\uae30, \uc0c9\uc0c1 \uad00\ub9ac \ub4f1\uc744 \uc9c0\uc6d0\ud558\ub294 \ud074\ub798\uc2a4 \uc2e4\uc81c \ud574\ub2f9 \ud074\ub798\uc2a4\uc758 draw \uba54\uc11c\ub4dc\ub97c \uacbd\ub85c\ub97c \uadf8\ub9bc"}),(0,i.jsx)(n.td,{children:"JDK 1.2 \uc774\ud6c4\uc5d0 \ucd94\uac00\ub428, 2D(\ud3c9\uba74) \uadf8\ub798\ud53d \ud658\uacbd\uc744 \uc9c0\uc6d0, bufferedImage.createGraphics \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \uc0dd\uc131"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"\uc758\uc874\uad00\uacc4",children:"\uc758\uc874\uad00\uacc4"}),"\n",(0,i.jsx)(n.mermaid,{value:'graph TD\n C1[Coordinates] --\x3e C[Coordinate]\n P1[Positions] --\x3e P[Position]\n\n\tRID[RouteImageDrawer] -- "\uc911\uc559 \uc815\ub82c\ub41c Positions\ub97c \ubc1b\uc544 \uc774\ubbf8\uc9c0 \uc0dd\uc131" --\x3e P1\n\tRID --\x3e B[BufferedImage]\n\tRID --\x3e G[Graphics2D]\n\n\tC1 -- "calculatePositions \uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc704\uce58 \uacc4\uc0b0" --\x3e P1\n\n\tRIU[RouteImageUploader] --\x3e B\n\tRIG[RouteImageGenerator] --\x3e RID\n\tRIG --\x3e RIU\n\tRIG --\x3e C1\n\tRIG --\x3e P1'}),"\n",(0,i.jsx)(n.h3,{id:"coordinates\uc704\ub3c4-\uacbd\ub3c4\uc758-\uc77c\uae09-\uceec\ub809\uc158",children:"Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"List<Double>"})," 2\uac1c(\uc704\ub3c4, \uacbd\ub3c4)\uc778 \ud615\ud0dc\ub85c \uad00\ub9ac\ud558\ub294 \ubc29\ubc95\uc774 \uc788\uc5c8\uc9c0\ub9cc, \uc704\uce58 \uc810\uc744 \uc5ec\ub7ec\uac1c \ucc0d\ub294 \ubd80\ubd84\uc5d0\uc11c \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud574 \uc9c8 \uac83 \uac19\uc544\uc11c Coordinate(x, y)\uc640 \uc77c\uae09 \uceec\ub809\uc158\uc778 Coordinates\ub85c \uad00\ub9ac\ud558\uae30\ub85c \ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","Coordinates \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub450 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"calculatePositions: \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub97c \ubc1b\uc544 \uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \uc0ac\uc6a9\ub420 Positions\ub97c \ubc18\ud658"}),"\n",(0,i.jsx)(n.li,{children:"indexOf: \ub2e4\ub978 Coordinates\ub97c \ubc1b\uc544 \ub3d9\uc77c\ud55c \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4\ub97c \ubc18\ud658\ud558\ub294"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Positions \uacc4\uc0b0 \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc704\ub3c4, \uacbd\ub3c4 \uac01\uac01\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \ud544\uc694\ud55c \uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="Coordinates.java"',children:"// \ud638\ucd9c\n// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);\n// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);\n\nprivate List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {\n Double minValue = Collections.min(values);\n return values.stream()\n .map(value -> normalizeCoordinate(value, maxDifference, minValue))\n .map(value -> mapToPosition(value, routeImageSize))\n .toList();\n}\n\nprivate double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {\n return (coordinate - minValue) / maxDifference;\n}\n\nprivate int mapToPosition(Double coordinate, Integer routeImageSize) {\n return (int) (coordinate * routeImageSize);\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"\uc704\ub3c4\ub85c \uc608\uc2dc\ub4e0 \ub0b4\uc6a9\uc774\ub2e4."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Collections.min(values) \u2192 \uc704\ub3c4 \ub9ac\uc2a4\ud2b8\uc758 \ucd5c\uc18c\uac12\uc744 \uad6c\ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.li,{children:["normalizeCoordinate \u2192 \uac01\uac01\uc758 \uc704\ub3c4 \uac12\uc5d0\uc11c \ucd5c\uc18c\uac12\uc744 \ube7c\uace0 0 ~ 1 \uc0ac\uc774 \uac12\uc73c\ub85c \ubcc0\ud658 \ud6c4 ",(0,i.jsx)(n.strong,{children:"\uc704\uacbd\ub3c4\uc758 \ucd5c\ub300 \ucc28\uc774"}),"\ub85c \ub098\ub208\ub2e4."]}),"\n",(0,i.jsx)(n.li,{children:"mapToPosition \u2192 \uadf8\ub798\ud504 \ud06c\uae30\ub97c \ubc1b\uc544 0 ~ 1 \uc0ac\uc774 \uac12\uc744 \uc2e4\uc81c \uc774\ubbf8\uc9c0\ub97c \uc704\ud55c \uc704\uce58\uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"positions\uc2e4\uc81c-\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc5d0-\uc0ac\uc6a9\ud560-\uc704\uce58",children:"Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)"}),"\n",(0,i.jsx)(n.p,{children:"Positions \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub2e4\uc12f \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"align: \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\uc640 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\ub97c \ubc1b\uc544 Position \uac12\ub4e4\uc744 \uc911\uc559 \uc815\ub82c\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"getPositionsByIndexes: \uc778\ub371\uc2a4 \ub9ac\uc2a4\ud2b8\ub97c \ubc1b\uc544 \uc785\ub825\ubc1b\uc740 \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"size: \ud06c\uae30\ub97c \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"xPositions: x \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"yPositions: y \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"\uc911\uc559 \uc815\ub82c \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="Positions.java"',children:"public Positions align(int imageSize, int routeSize) {\n int xOffset = calculateOffset(Position::x, imageSize);\n int yOffset = calculateOffset(Position::y, imageSize);\n\n return items.stream()\n .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))\n .collect(collectingAndThen(toList(), Positions::new));\n}\n\nprivate int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {\n List<Integer> positions = items.stream()\n .mapToInt(positionToInteger)\n .boxed()\n .toList();\n\n int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;\n return imageSize / 2 - midValue;\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["\uc0c1\ud558\uc88c\uc6b0 \uc5ec\ubc31\uc744 \ub3d9\uc77c\ud558\uac8c \uc8fc\uae30 \uc704\ud574\uc11c offset \uac12\uc744 \uad6c\ud574\uc11c x, y \uac12\uc5d0 \uac01\uac01 \ub354\ud558\ub294 \ud615\ud0dc\ub85c \uc911\uc559 \uc815\ub82c\uc744 \uc218\ud589\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","BufferedImage\ub97c \uc0ac\uc6a9\ud560 \ub54c \uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c (0, 0) \uae30\uc900\uc73c\ub85c \uc544\ub798\ub85c \ub0b4\ub824\uac08\uc218\ub85d y \uac12\uc774 \ucee4\uc9c0\uace0, \uc624\ub978\ucabd\uc73c\ub85c \uac08 \uc218\ub85d x \uac12\uc774 \ucee4\uc9c4\ub2e4."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"./800.png",src:t(77421).Z+"",width:"968",height:"978"})}),"\n",(0,i.jsx)(n.p,{children:"\ub530\ub77c\uc11c \ucd5c\uc885\uc801\uc73c\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud55c \uac12\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uad6c\ud588\ub2e4."}),"\n",(0,i.jsxs)(n.p,{children:["x \uac12 \u2192 \uacc4\uc0b0\ud55c offset \uadf8\ub300\ub85c \ub354\ud55c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","y \uac12 \u2192 imageSize(800)\uc5d0\uc11c y + offset \uac12\uc744 \ube80\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"routeimagedrawer\uc2e4\uc81c-\uc774\ubbf8\uc9c0\uc5d0-\uacbd\ub85c\ub97c-\uadf8\ub824\uc8fc\ub294-\ud074\ub798\uc2a4",children:"RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)"}),"\n",(0,i.jsxs)(n.p,{children:["BufferedImage, Graphics2D\ub97c \ud544\ub4dc\ub85c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uadf8\ub9bc\uc744 \uadf8\ub9ac\uae30 \uc704\ud574 \uc124\uc815\ud55c \uc0c1\uc218\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",metastring:'title="RouteImageDrawer.java"',children:"// RGB\uc5d0 \uac01\uac01 8\ube44\ud2b8\uc529 \ud560\ub2f9\ud55c \uac12\uc744 24\ube44\ud2b8 \ud2b8\ub8e8\uceec\ub7ec\ub77c \ubd80\ub978\ub2e4.\n// \ud574\ub2f9 \uc124\uc815\uc740 24\ube44\ud2b8 + 8\ube44\ud2b8(alpha, \ud22c\uba85\ub3c4)\ub97c \ucd94\uac00\ud55c 32\ube44\ud2b8 \uc774\ubbf8\uc9c0 \ud0c0\uc785\uc774\ub2e4.\n// \uc774\ub97c RGBA\ub77c\uace0 \ubd80\ub978\ub2e4.\nprivate static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;\n// \ubc30\uacbd \ud22c\uba85\uc0c9\nprivate static final Color TRANSPARENT = new Color(0, 0, 0, 0);\n// \uacbd\ub85c\ub97c \uc704\ud55c STROKE\nprivate static final int LINE_STROKE_WIDTH = 7;\nprivate static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\n// \uc704\uce58 \uc810\uc744 \uc704\ud55c STROKE\nprivate static final int POINT_STROKE_WIDTH = 20;\nprivate static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\n// \uc548\ud2f0\uc568\ub9ac\uc5b4\uc2f1 \ub4f1 \ud654\uc9c8 \uac1c\uc120\uc744 \uc704\ud55c \uc124\uc815\nprivate static final Map<Object, Object> renderingHints = Map.of(\n RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,\n RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,\n RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC\n);\n"})}),"\n",(0,i.jsx)(n.p,{children:"RouteImageDrawer \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \uc138 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"drawLine: \uc120\uc744 \uadf8\ub9b0\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"drawPoint: \uc810\uc744 \ucc0d\ub294\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"dispose: \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"dispose\uc758 \uacbd\uc6b0 \ub0b4\ubd80\uc5d0\uc11c \uc0dd\uc131\ub41c graphics2D\uc5d0 \ub300\ud55c \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud558\ub294 \uba54\uc11c\ub4dc\uc778 graphics2D.dispose\ub97c \ud638\ucd9c\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h2,{id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131-flow",children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow"}),"\n",(0,i.jsx)(n.h3,{id:"1-\uc774\ubbf8\uc9c0-\uc0dd\uc131-\uc900\ube44",children:"1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\n"}),"\n",(0,i.jsx)(n.h3,{id:"2-\uc120-\uadf8\ub9ac\uae30-\uc694\uccad",children:"2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad"}),"\n",(0,i.jsx)(n.h3,{id:"3-\uc704\uce58-\uc810-\uadf8\ub9ac\uae30-\uc694\uccad",children:"3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\n\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad"}),"\n",(0,i.jsx)(n.h3,{id:"4-\uc5c5\ub85c\ub4dc-\uc694\uccad",children:"4. \uc5c5\ub85c\ub4dc \uc694\uccad"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n \tRouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\n \tRouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n \tRouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658"}),"\n",(0,i.jsx)(n.h3,{id:"\uc804\uccb4-flow",children:"\uc804\uccb4 Flow"}),"\n",(0,i.jsx)(n.mermaid,{value:"sequenceDiagram\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\n\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\n RouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\n RouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n RouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n\t"})]})}function u(e={}){const{wrapper:n}={...(0,r.ah)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>d});var i=t(67294);function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,i)}return t}function a(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){r(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,i,r=function(e,n){if(null==e)return{};var t,i,r={},o=Object.keys(e);for(i=0;i<o.length;i++)t=o[i],n.indexOf(t)>=0||(r[t]=e[t]);return r}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(i=0;i<o.length;i++)t=o[i],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(r[t]=e[t])}return r}var l=i.createContext({}),d=function(e){var n=i.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):a(a({},n),e)),t},c={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},u=i.forwardRef((function(e,n){var t=e.components,r=e.mdxType,o=e.originalType,l=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),m=d(t),g=r,h=m["".concat(l,".").concat(g)]||m[g]||c[g]||o;return t?i.createElement(h,a(a({ref:n},u),{},{components:t})):i.createElement(h,a({ref:n},u))}));u.displayName="MDXCreateElement"},49812:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/600-50ee65176288cb73d2c777d255460f4f.png"},77421:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/800-88542ba3914ad40b45b999e95df96cdf.png"},59563:(e,n,t)=>{t.d(n,{Z:()=>i});const i=t.p+"assets/images/result-c2887223d62510a96c9c8f733bf5edf6.png"}}]); \ No newline at end of file diff --git a/assets/js/cc519f63.c9506faa.js b/assets/js/cc519f63.c9506faa.js deleted file mode 100644 index 6f0559329..000000000 --- a/assets/js/cc519f63.c9506faa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5323],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},i=Object.keys(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)n=i[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),m=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=m(e.components);return a.createElement(s.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},g=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,i=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),g=m(n),d=r,c=g["".concat(s,".").concat(d)]||g[d]||p[d]||i;return n?a.createElement(c,o(o({ref:t},u),{},{components:n})):a.createElement(c,o({ref:t},u))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=n.length,o=new Array(i);o[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:r,o[1]=l;for(var m=2;m<i;m++)o[m]=n[m];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}g.displayName="MDXCreateElement"},7771:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>l,toc:()=>m});var a=n(87462),r=(n(67294),n(3905));const i={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",slug:"route-image-implementation",tags:["image","awt"]},o=void 0,l={permalink:"/route-image-implementation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",source:"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",description:"\uac1c\uc694",date:"2023-08-02T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 2\uc77c",tags:[{label:"image",permalink:"/tags/image"},{label:"awt",permalink:"/tags/awt"}],readingTime:11.665,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",slug:"route-image-implementation",tags:["image","awt"]},prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",permalink:"/route-image-async-with-event"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",permalink:"/route-image-python"}},s={authorsImageUrls:[]},m=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:2},{value:"\uad6c\ud604 \uacb0\uacfc",id:"\uad6c\ud604-\uacb0\uacfc",level:3},{value:"IMAGE_SIZE & ROUTE_SIZE",id:"image_size--route_size",level:3},{value:"\uc8fc\uc694 \ud074\ub798\uc2a4",id:"\uc8fc\uc694-\ud074\ub798\uc2a4",level:2},{value:"\uc694\uc57d",id:"\uc694\uc57d",level:3},{value:"\uc758\uc874\uad00\uacc4",id:"\uc758\uc874\uad00\uacc4",level:3},{value:"Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)",id:"coordinates\uc704\ub3c4-\uacbd\ub3c4\uc758-\uc77c\uae09-\uceec\ub809\uc158",level:3},{value:"Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)",id:"positions\uc2e4\uc81c-\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc5d0-\uc0ac\uc6a9\ud560-\uc704\uce58",level:3},{value:"RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)",id:"routeimagedrawer\uc2e4\uc81c-\uc774\ubbf8\uc9c0\uc5d0-\uacbd\ub85c\ub97c-\uadf8\ub824\uc8fc\ub294-\ud074\ub798\uc2a4",level:3},{value:"\uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow",id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131-flow",level:2},{value:"1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44",id:"1-\uc774\ubbf8\uc9c0-\uc0dd\uc131-\uc900\ube44",level:3},{value:"2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad",id:"2-\uc120-\uadf8\ub9ac\uae30-\uc694\uccad",level:3},{value:"3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad",id:"3-\uc704\uce58-\uc810-\uadf8\ub9ac\uae30-\uc694\uccad",level:3},{value:"4. \uc5c5\ub85c\ub4dc \uc694\uccad",id:"4-\uc5c5\ub85c\ub4dc-\uc694\uccad",level:3},{value:"\uc804\uccb4 Flow",id:"\uc804\uccb4-flow",level:3}],u={toc:m};function p(e){let{components:t,...i}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,r.kt)("p",null,"\uc5ec\ud589\uc5d0 \ub300\ud55c \uacbd\ub85c\ub97c \ubcf4\uc5ec\uc8fc\uae30 \uc704\ud574 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub294 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d \ubc0f \uae30\uc220 \uc120\ud0dd\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 ",(0,r.kt)("a",{parentName:"p",href:"./route-image-intro"},"\ub9c1\ud06c"),"\uc5d0 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\uad6c\ud604-\uacb0\uacfc"},"\uad6c\ud604 \uacb0\uacfc"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./result.png",src:n(59563).Z,width:"1840",height:"714"})),(0,r.kt)("p",null,"\uc608\uc2dc \ub370\uc774\ud130\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("strong",{parentName:"p"},"\uc11c\uc6b8\uc5ed(\uc810)")," \u2192 \uc2e0\uc0ac\uc5ed \u2192 \ub178\ub7c9\uc9c4\uc5ed \u2192 \ud64d\ub300\uc785\uad6c\uc5ed \u2192 \uc885\ub85c3\uac00\uc5ed \u2192 \uc625\uc218\uc5ed \u2192 ",(0,r.kt)("strong",{parentName:"p"},"\uad6c\ub85c\uc5ed(\uc810)")," \u2192 \uc2e0\ub9bc\uc5ed \u2192 \ubc1c\uc0b0\uc5ed"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="\uc608\uc2dc \ub370\uc774\ud130"',title:'"\uc608\uc2dc','\ub370\uc774\ud130"':!0},"List<Double> x = List.of(\n 126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,\n 126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639\n);\nList<Double> y = List.of(\n 37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,\n 37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184\n);\nList<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);\nList<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);\n")),(0,r.kt)("h3",{id:"image_size--route_size"},"IMAGE_SIZE & ROUTE_SIZE"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="RouteImageGenerator.java"',title:'"RouteImageGenerator.java"'},"private static final int IMAGE_SIZE = 800;\nprivate static final int ROUTE_SIZE = 600;\n")),(0,r.kt)("p",null,"\ucf54\ub4dc\ub97c \ubcf4\uba74 IMAGE_SIZE\uc640 ROUTE_SIZE\uac00 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","IMAGE_SIZE\ub294 \ub9d0 \uadf8\ub300\ub85c \uc774\ubbf8\uc9c0\uc758 width\uc640 height\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","ROUTE_SIZE\uc758 \uacbd\uc6b0 \uc0c1\ud558\uc88c\uc6b0 100px \ub9cc\ud07c\uc758 \uac04\uaca9\uc744 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc2e4\uc81c \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub294 600 * 600 \uc0ac\uc774\uc988\ub85c \uc0dd\uc131\ub41c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./600.png",src:n(49812).Z,width:"976",height:"970"})),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uc0ac\uc774\uc988 \ubcc0\uacbd\uc758 \uc774\uc720")),(0,r.kt)("p",null,"255 ",(0,r.kt)("em",{parentName:"p"}," 255 \uc815\ub3c4\uc758 \uc791\uc740 \uc0ac\uc774\uc988\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud574\ubcf4\ub824\uace0 \ud588\ub294\ub370, \uc774\ubbf8\uc9c0\uc758 \uc120\uba85\ub3c4\uac00 \uc88b\uc9c0 \uc54a\uc544 800 ")," 800 \uc0ac\uc774\uc988\ub85c \ubcc0\uacbd\ud588\ub2e4."),(0,r.kt)("h2",{id:"\uc8fc\uc694-\ud074\ub798\uc2a4"},"\uc8fc\uc694 \ud074\ub798\uc2a4"),(0,r.kt)("h3",{id:"\uc694\uc57d"},"\uc694\uc57d"),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\ud074\ub798\uc2a4\uba85"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"),(0,r.kt)("th",{parentName:"tr",align:null},"\ud2b9\uc774\uc0ac\ud56d"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Coordinate"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \uc704\uce58 \uac12"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc88c\ud45c\ub97c \ub73b\ud558\uc9c0\ub9cc \uc5ec\ud589 \ub3c4\uba54\uc778\uc5d0 \ud3ec\ud568\ub41c Point \ud074\ub798\uc2a4\uc640 \uad6c\ubd84\ud558\uae30 \uc704\ud574 longitude, latitude\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 x, y \uc0ac\uc6a9")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Coordinates"),(0,r.kt)("td",{parentName:"tr",align:null},"Coordinate\uc758 \uc77c\uae09 \uceec\ub809\uc158"),(0,r.kt)("td",{parentName:"tr",align:null},"-")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Position"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58 \uac12"),(0,r.kt)("td",{parentName:"tr",align:null},"Integer \ud0c0\uc785\uc758 x, y \uc0ac\uc6a9")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Positions"),(0,r.kt)("td",{parentName:"tr",align:null},"Positions\uc758 \uc77c\uae09 \uceec\ub809\uc158"),(0,r.kt)("td",{parentName:"tr",align:null},"-")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RouteImageDrawer"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4 BufferedImage, Graphics2D\ub97c \uac00\uc9c0\uace0 \uc788\uc74c"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc0c1\uc218\uac00 \uc815\uc758\ub418\uc5b4 \uc788\uc74c")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RouteImageUploader"),(0,r.kt)("td",{parentName:"tr",align:null},"BufferedImage\ub97c \ubc1b\uc544 \uc11c\ubc84\uc5d0 \uc5c5\ub85c\ub4dc \ud558\ub294 \ud074\ub798\uc2a4"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud604\uc7ac \uc5c5\ub85c\ub4dc \uc704\uce58\uac00 \uc815\ud574\uc9c0\uc9c0 \uc54a\uc544 \uc77c\ub2e8 \uae30\ubcf8(\ud504\ub85c\uc81d\ud2b8 \ub8e8\ud2b8) \uc704\uce58\uc5d0 \uc0dd\uc131")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"RouteImageGenerator"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uace0 \uc5c5\ub85c\ub4dc\ud558\ub294 \uc11c\ube44\uc2a4"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc5ec\ud589 \uc885\ub8cc, \uac10\uc0c1 \uc800\uc7a5\uc2dc \ud574\ub2f9 \ud074\ub798\uc2a4\ub97c \ud1b5\ud574 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"BufferedImage(AWT)"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc774\ubbf8\uc9c0 \ub370\uc774\ud130\ub97c \ucc98\ub9ac\ud558\uace0 \uc870\uc791\ud558\ub294 \ub370 \uc0ac\uc6a9"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c\uac00 (0, 0)")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"Graphics2D(AWT)"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc120 \uadf8\ub9ac\uae30, \uc0c9\uc0c1 \uad00\ub9ac \ub4f1\uc744 \uc9c0\uc6d0\ud558\ub294 \ud074\ub798\uc2a4 \uc2e4\uc81c \ud574\ub2f9 \ud074\ub798\uc2a4\uc758 draw \uba54\uc11c\ub4dc\ub97c \uacbd\ub85c\ub97c \uadf8\ub9bc"),(0,r.kt)("td",{parentName:"tr",align:null},"JDK 1.2 \uc774\ud6c4\uc5d0 \ucd94\uac00\ub428, 2D(\ud3c9\uba74) \uadf8\ub798\ud53d \ud658\uacbd\uc744 \uc9c0\uc6d0, bufferedImage.createGraphics \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \uc0dd\uc131")))),(0,r.kt)("h3",{id:"\uc758\uc874\uad00\uacc4"},"\uc758\uc874\uad00\uacc4"),(0,r.kt)("mermaid",{value:'graph TD\n C1[Coordinates] --\x3e C[Coordinate]\n P1[Positions] --\x3e P[Position]\n\n\tRID[RouteImageDrawer] -- "\uc911\uc559 \uc815\ub82c\ub41c Positions\ub97c \ubc1b\uc544 \uc774\ubbf8\uc9c0 \uc0dd\uc131" --\x3e P1\n\tRID --\x3e B[BufferedImage]\n\tRID --\x3e G[Graphics2D]\n\n\tC1 -- "calculatePositions \uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uc0dd\uc131\uc5d0 \ud544\uc694\ud55c \uc704\uce58 \uacc4\uc0b0" --\x3e P1\n\n\tRIU[RouteImageUploader] --\x3e B\n\tRIG[RouteImageGenerator] --\x3e RID\n\tRIG --\x3e RIU\n\tRIG --\x3e C1\n\tRIG --\x3e P1'}),(0,r.kt)("h3",{id:"coordinates\uc704\ub3c4-\uacbd\ub3c4\uc758-\uc77c\uae09-\uceec\ub809\uc158"},"Coordinates(\uc704\ub3c4, \uacbd\ub3c4\uc758 \uc77c\uae09 \uceec\ub809\uc158)"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"List<Double>")," 2\uac1c(\uc704\ub3c4, \uacbd\ub3c4)\uc778 \ud615\ud0dc\ub85c \uad00\ub9ac\ud558\ub294 \ubc29\ubc95\uc774 \uc788\uc5c8\uc9c0\ub9cc, \uc704\uce58 \uc810\uc744 \uc5ec\ub7ec\uac1c \ucc0d\ub294 \ubd80\ubd84\uc5d0\uc11c \ub85c\uc9c1\uc774 \ubcf5\uc7a1\ud574 \uc9c8 \uac83 \uac19\uc544\uc11c Coordinate(x, y)\uc640 \uc77c\uae09 \uceec\ub809\uc158\uc778 Coordinates\ub85c \uad00\ub9ac\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Coordinates \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub450 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"calculatePositions: \uacbd\ub85c \uc774\ubbf8\uc9c0\uc758 \ud06c\uae30\ub97c \ubc1b\uc544 \uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \uc0ac\uc6a9\ub420 Positions\ub97c \ubc18\ud658"),(0,r.kt)("li",{parentName:"ul"},"indexOf: \ub2e4\ub978 Coordinates\ub97c \ubc1b\uc544 \ub3d9\uc77c\ud55c \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4\ub97c \ubc18\ud658\ud558\ub294 ")),(0,r.kt)("p",null,"Positions \uacc4\uc0b0 \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc704\ub3c4, \uacbd\ub3c4 \uac01\uac01\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc2dc \ud544\uc694\ud55c \uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="Coordinates.java"',title:'"Coordinates.java"'},"// \ud638\ucd9c\n// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);\n// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);\n\nprivate List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {\n Double minValue = Collections.min(values);\n return values.stream()\n .map(value -> normalizeCoordinate(value, maxDifference, minValue))\n .map(value -> mapToPosition(value, routeImageSize))\n .toList();\n}\n\nprivate double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {\n return (coordinate - minValue) / maxDifference;\n}\n\nprivate int mapToPosition(Double coordinate, Integer routeImageSize) {\n return (int) (coordinate * routeImageSize);\n}\n")),(0,r.kt)("p",null,"\uc704\ub3c4\ub85c \uc608\uc2dc\ub4e0 \ub0b4\uc6a9\uc774\ub2e4."),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"Collections.min(values) \u2192 \uc704\ub3c4 \ub9ac\uc2a4\ud2b8\uc758 \ucd5c\uc18c\uac12\uc744 \uad6c\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ol"},"normalizeCoordinate \u2192 \uac01\uac01\uc758 \uc704\ub3c4 \uac12\uc5d0\uc11c \ucd5c\uc18c\uac12\uc744 \ube7c\uace0 0 ~ 1 \uc0ac\uc774 \uac12\uc73c\ub85c \ubcc0\ud658 \ud6c4 ",(0,r.kt)("strong",{parentName:"li"},"\uc704\uacbd\ub3c4\uc758 \ucd5c\ub300 \ucc28\uc774"),"\ub85c \ub098\ub208\ub2e4."),(0,r.kt)("li",{parentName:"ol"},"mapToPosition \u2192 \uadf8\ub798\ud504 \ud06c\uae30\ub97c \ubc1b\uc544 0 ~ 1 \uc0ac\uc774 \uac12\uc744 \uc2e4\uc81c \uc774\ubbf8\uc9c0\ub97c \uc704\ud55c \uc704\uce58\uac12\uc73c\ub85c \ubcc0\ud658\ud55c\ub2e4.")),(0,r.kt)("h3",{id:"positions\uc2e4\uc81c-\uc774\ubbf8\uc9c0-\uc0dd\uc131\uc5d0-\uc0ac\uc6a9\ud560-\uc704\uce58"},"Positions(\uc2e4\uc81c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uc0ac\uc6a9\ud560 \uc704\uce58)"),(0,r.kt)("p",null,"Positions \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \ub2e4\uc12f \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"align: \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\uc640 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0ac\uc774\uc988\ub97c \ubc1b\uc544 Position \uac12\ub4e4\uc744 \uc911\uc559 \uc815\ub82c\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"getPositionsByIndexes: \uc778\ub371\uc2a4 \ub9ac\uc2a4\ud2b8\ub97c \ubc1b\uc544 \uc785\ub825\ubc1b\uc740 \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"size: \ud06c\uae30\ub97c \ubc18\ud658\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"xPositions: x \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"yPositions: y \uac12\ub4e4\uc744 \ubc18\ud658\ud55c\ub2e4.")),(0,r.kt)("p",null,"\uc911\uc559 \uc815\ub82c \ub85c\uc9c1\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="Positions.java"',title:'"Positions.java"'},"public Positions align(int imageSize, int routeSize) {\n int xOffset = calculateOffset(Position::x, imageSize);\n int yOffset = calculateOffset(Position::y, imageSize);\n\n return items.stream()\n .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))\n .collect(collectingAndThen(toList(), Positions::new));\n}\n\nprivate int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {\n List<Integer> positions = items.stream()\n .mapToInt(positionToInteger)\n .boxed()\n .toList();\n\n int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;\n return imageSize / 2 - midValue;\n}\n")),(0,r.kt)("p",null,"\uc0c1\ud558\uc88c\uc6b0 \uc5ec\ubc31\uc744 \ub3d9\uc77c\ud558\uac8c \uc8fc\uae30 \uc704\ud574\uc11c offset \uac12\uc744 \uad6c\ud574\uc11c x, y \uac12\uc5d0 \uac01\uac01 \ub354\ud558\ub294 \ud615\ud0dc\ub85c \uc911\uc559 \uc815\ub82c\uc744 \uc218\ud589\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","BufferedImage\ub97c \uc0ac\uc6a9\ud560 \ub54c \uc67c\ucabd \uc0c1\ub2e8\uc758 \uc88c\ud45c (0, 0) \uae30\uc900\uc73c\ub85c \uc544\ub798\ub85c \ub0b4\ub824\uac08\uc218\ub85d y \uac12\uc774 \ucee4\uc9c0\uace0, \uc624\ub978\ucabd\uc73c\ub85c \uac08 \uc218\ub85d x \uac12\uc774 \ucee4\uc9c4\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./800.png",src:n(77421).Z,width:"968",height:"978"})),(0,r.kt)("p",null,"\ub530\ub77c\uc11c \ucd5c\uc885\uc801\uc73c\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud55c \uac12\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uad6c\ud588\ub2e4."),(0,r.kt)("p",null,"x \uac12 \u2192 \uacc4\uc0b0\ud55c offset \uadf8\ub300\ub85c \ub354\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","y \uac12 \u2192 imageSize(800)\uc5d0\uc11c y + offset \uac12\uc744 \ube80\ub2e4. "),(0,r.kt)("h3",{id:"routeimagedrawer\uc2e4\uc81c-\uc774\ubbf8\uc9c0\uc5d0-\uacbd\ub85c\ub97c-\uadf8\ub824\uc8fc\ub294-\ud074\ub798\uc2a4"},"RouteImageDrawer(\uc2e4\uc81c \uc774\ubbf8\uc9c0\uc5d0 \uacbd\ub85c\ub97c \uadf8\ub824\uc8fc\ub294 \ud074\ub798\uc2a4)"),(0,r.kt)("p",null,"BufferedImage, Graphics2D\ub97c \ud544\ub4dc\ub85c \uac00\uc9c0\uace0 \uc788\ub294 \ud074\ub798\uc2a4\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uadf8\ub9bc\uc744 \uadf8\ub9ac\uae30 \uc704\ud574 \uc124\uc815\ud55c \uc0c1\uc218\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="RouteImageDrawer.java"',title:'"RouteImageDrawer.java"'},"// RGB\uc5d0 \uac01\uac01 8\ube44\ud2b8\uc529 \ud560\ub2f9\ud55c \uac12\uc744 24\ube44\ud2b8 \ud2b8\ub8e8\uceec\ub7ec\ub77c \ubd80\ub978\ub2e4.\n// \ud574\ub2f9 \uc124\uc815\uc740 24\ube44\ud2b8 + 8\ube44\ud2b8(alpha, \ud22c\uba85\ub3c4)\ub97c \ucd94\uac00\ud55c 32\ube44\ud2b8 \uc774\ubbf8\uc9c0 \ud0c0\uc785\uc774\ub2e4.\n// \uc774\ub97c RGBA\ub77c\uace0 \ubd80\ub978\ub2e4.\nprivate static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;\n// \ubc30\uacbd \ud22c\uba85\uc0c9\nprivate static final Color TRANSPARENT = new Color(0, 0, 0, 0);\n// \uacbd\ub85c\ub97c \uc704\ud55c STROKE\nprivate static final int LINE_STROKE_WIDTH = 7;\nprivate static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\n// \uc704\uce58 \uc810\uc744 \uc704\ud55c STROKE\nprivate static final int POINT_STROKE_WIDTH = 20;\nprivate static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);\n// \uc548\ud2f0\uc568\ub9ac\uc5b4\uc2f1 \ub4f1 \ud654\uc9c8 \uac1c\uc120\uc744 \uc704\ud55c \uc124\uc815\nprivate static final Map<Object, Object> renderingHints = Map.of(\n RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,\n RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,\n RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC\n);\n")),(0,r.kt)("p",null,"RouteImageDrawer \ud074\ub798\uc2a4\uc5d0\ub294 \ub2e4\uc74c \uc138 \uac1c\uc758 \uc778\ud130\ud398\uc774\uc2a4\uac00 \uc874\uc7ac\ud55c\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"drawLine: \uc120\uc744 \uadf8\ub9b0\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"drawPoint: \uc810\uc744 \ucc0d\ub294\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"dispose: \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud55c\ub2e4. ")),(0,r.kt)("p",null,"dispose\uc758 \uacbd\uc6b0 \ub0b4\ubd80\uc5d0\uc11c \uc0dd\uc131\ub41c graphics2D\uc5d0 \ub300\ud55c \uc790\uc6d0 \ud560\ub2f9\uc744 \ud574\uc81c\ud558\ub294 \uba54\uc11c\ub4dc\uc778 graphics2D.dispose\ub97c \ud638\ucd9c\ud55c\ub2e4."),(0,r.kt)("h2",{id:"\uc774\ubbf8\uc9c0-\uc0dd\uc131-flow"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131 Flow"),(0,r.kt)("h3",{id:"1-\uc774\ubbf8\uc9c0-\uc0dd\uc131-\uc900\ube44"},"1. \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc900\ube44"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\n"}),(0,r.kt)("h3",{id:"2-\uc120-\uadf8\ub9ac\uae30-\uc694\uccad"},"2. \uc120 \uadf8\ub9ac\uae30 \uc694\uccad"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad"}),(0,r.kt)("h3",{id:"3-\uc704\uce58-\uc810-\uadf8\ub9ac\uae30-\uc694\uccad"},"3. \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\n\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad"}),(0,r.kt)("h3",{id:"4-\uc5c5\ub85c\ub4dc-\uc694\uccad"},"4. \uc5c5\ub85c\ub4dc \uc694\uccad"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n \tRouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\n \tRouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n \tRouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658"}),(0,r.kt)("h3",{id:"\uc804\uccb4-flow"},"\uc804\uccb4 Flow"),(0,r.kt)("mermaid",{value:"sequenceDiagram\n \uc678\ubd80 \ud074\ub798\uc2a4 ->> RouteImageGenerator: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad(\uc704\uacbd\ub3c4, \uc704\uce58 \uc810\uc744 \ucc0d\uc744 \uac12 \uc804\ub2ec)\n RouteImageGenerator->>RouteImageDrawer: ImageSize\ub97c \uc804\ub2ec\ud558\uc5ec \uac1d\uccb4 \uc0dd\uc131, \ub0b4\ubd80\uc5d0\uc11c BufferedImage, Graphincs2D \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc704\uacbd\ub3c4 \uc774\uc6a9\ud558\uc5ec Coordinates1 \uc0dd\uc131\n RouteImageGenerator->>Coordinates2(\uc704\uce58\uc810): \uc704\uce58\uc810 \uc774\uc6a9\ud558\uc5ec Coordinates2 \uc0dd\uc131\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): \uc815\ub82c\ub41c Positions\ub97c \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc815\ub82c\ub41c Positions \ubc18\ud658\n RouteImageGenerator->>RouteImageDrawer: \uc815\ub82c\ub41c Positions\ub97c \uacbd\ub85c \uadf8\ub9ac\uae30 \uc694\uccad\n RouteImageGenerator->>Coordinates1(\uc704\uacbd\ub3c4): Coordinate2(\uc704\uce58\uc810)\ub97c \uc804\ub2ec\ud558\uace0 \ud574\ub2f9 \uc704\uce58\uc810\uacfc \uc77c\uce58\ud558\ub294 Coordinate\uc758 \uc778\ub371\uc2a4 \uc0dd\uc131 \uc694\uccad\n Coordinates1(\uc704\uacbd\ub3c4)->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 \uc778\ub371\uc2a4(List<Integer>) \ubc18\ud658\n RouteImageGenerator->>\uc815\ub82c\ub41c Positions: \uc778\ub371\uc2a4(List<Integer>)\ub97c \uc804\ub2ec\ud558\uc5ec \uc778\ub371\uc2a4\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \uc0dd\uc131 \uc694\uccad\n \uc815\ub82c\ub41c Positions->>RouteImageGenerator: \uc704\uce58\uc810\uc5d0 \ud574\ub2f9\ud558\ub294 Positions \ubc18\ud658(pointPositions)\n\n RouteImageGenerator->>RouteImageDrawer: pointPositions\ub97c \uc804\ub2ec\ud558\uc5ec \uc704\uce58 \uc810 \uadf8\ub9ac\uae30 \uc694\uccad\n RouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer\uc5d0\uc11c getter \uc0ac\uc6a9)\ub97c \uc804\ub2ec\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc800\uc7a5 \uc694\uccad\n RouteImageUploader->>RouteImageGenerator: \uc800\uc7a5 \ud6c4 \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n RouteImageGenerator->>\uc678\ubd80 \ud074\ub798\uc2a4: \uc800\uc7a5\ub41c \uc774\ubbf8\uc9c0\uba85(\ub610\ub294 url) \ubc18\ud658\n\t"}))}p.isMDXComponent=!0},49812:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/600-50ee65176288cb73d2c777d255460f4f.png"},77421:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/800-88542ba3914ad40b45b999e95df96cdf.png"},59563:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/result-c2887223d62510a96c9c8f733bf5edf6.png"}}]); \ No newline at end of file diff --git a/assets/js/ccc49370.7af2b68e.js b/assets/js/ccc49370.7af2b68e.js deleted file mode 100644 index ea25834a3..000000000 --- a/assets/js/ccc49370.7af2b68e.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6103],{65203:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>b});var a=n(67294),r=n(86010),o=n(10833),l=n(35281),i=n(9460),s=n(39058),c=n(857),m=n(87462),u=n(95999),d=n(32244);function g(e){const{nextItem:t,prevItem:n}=e;return a.createElement("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,u.I)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"})},n&&a.createElement(d.Z,(0,m.Z)({},n,{subLabel:a.createElement(u.Z,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post"},"Newer Post")})),t&&a.createElement(d.Z,(0,m.Z)({},t,{subLabel:a.createElement(u.Z,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post"},"Older Post"),isNext:!0})))}function f(){const{assets:e,metadata:t}=(0,i.C)(),{title:n,description:r,date:l,tags:s,authors:c,frontMatter:m}=t,{keywords:u}=m,d=e.image??m.image;return a.createElement(o.d,{title:n,description:r,keywords:u,image:d},a.createElement("meta",{property:"og:type",content:"article"}),a.createElement("meta",{property:"article:published_time",content:l}),c.some((e=>e.url))&&a.createElement("meta",{property:"article:author",content:c.map((e=>e.url)).filter(Boolean).join(",")}),s.length>0&&a.createElement("meta",{property:"article:tag",content:s.map((e=>e.label)).join(",")}))}var p=n(39407);function v(e){let{sidebar:t,children:n}=e;const{metadata:r,toc:o}=(0,i.C)(),{nextItem:l,prevItem:m,frontMatter:u}=r,{hide_table_of_contents:d,toc_min_heading_level:f,toc_max_heading_level:v}=u;return a.createElement(s.Z,{sidebar:t,toc:!d&&o.length>0?a.createElement(p.Z,{toc:o,minHeadingLevel:f,maxHeadingLevel:v}):void 0},a.createElement(c.Z,null,n),(l||m)&&a.createElement(g,{nextItem:l,prevItem:m}))}function b(e){const t=e.content;return a.createElement(i.n,{content:e.content,isBlogPostPage:!0},a.createElement(o.FG,{className:(0,r.Z)(l.k.wrapper.blogPages,l.k.page.blogPostPage)},a.createElement(f,null),a.createElement(v,{sidebar:e.sidebar},a.createElement(t,null))))}},39407:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var a=n(87462),r=n(67294),o=n(86010),l=n(93743);const i="tableOfContents_bqdL";function s(e){let{className:t,...n}=e;return r.createElement("div",{className:(0,o.Z)(i,"thin-scrollbar",t)},r.createElement(l.Z,(0,a.Z)({},n,{linkClassName:"table-of-contents__link toc-highlight",linkActiveClassName:"table-of-contents__link--active"})))}},93743:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var a=n(87462),r=n(67294),o=n(86668);function l(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...r}=e;n>=0?t[n].children.push(r):a.push(r)})),a}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function s(e){const t=e.getBoundingClientRect();return t.top===t.bottom?s(e.parentNode):t}function c(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>s(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(s(a))?a:e[e.indexOf(a)-1]??null}return e[e.length-1]??null}function m(){const e=(0,r.useRef)(0),{navbar:{hideOnScroll:t}}=(0,o.L)();return(0,r.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function u(e){const t=(0,r.useRef)(void 0),n=m();(0,r.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:r,minHeadingLevel:o,maxHeadingLevel:l}=e;function i(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),i=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let r=t;r<=n;r+=1)a.push(`h${r}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:o,maxHeadingLevel:l}),s=c(i,{anchorTopOffset:n.current}),m=e.find((e=>s&&s.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(r),e.classList.add(r),t.current=e):e.classList.remove(r)}(e,e===m)}))}return document.addEventListener("scroll",i),document.addEventListener("resize",i),i(),()=>{document.removeEventListener("scroll",i),document.removeEventListener("resize",i)}}),[e,n])}function d(e){let{toc:t,className:n,linkClassName:a,isChild:o}=e;return t.length?r.createElement("ul",{className:o?void 0:n},t.map((e=>r.createElement("li",{key:e.id},r.createElement("a",{href:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),r.createElement(d,{isChild:!0,toc:e.children,className:n,linkClassName:a}))))):null}const g=r.memo(d);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:s="table-of-contents__link",linkActiveClassName:c,minHeadingLevel:m,maxHeadingLevel:d,...f}=e;const p=(0,o.L)(),v=m??p.tableOfContents.minHeadingLevel,b=d??p.tableOfContents.maxHeadingLevel,h=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,r.useMemo)((()=>i({toc:l(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:v,maxHeadingLevel:b});return u((0,r.useMemo)((()=>{if(s&&c)return{linkClassName:s,linkActiveClassName:c,minHeadingLevel:v,maxHeadingLevel:b}}),[s,c,v,b])),r.createElement(g,(0,a.Z)({toc:h,className:n,linkClassName:s},f))}},857:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var a=n(30390),r=n(67294),o=n(92949),l=n(9460);const i=function(e){const{colorMode:t}=(0,o.I)(),{isBlogPostPage:n}=(0,l.C)(),i="dark"===t?"dark":"light",s=(0,r.useRef)(null);return(0,r.useEffect)((()=>{if(!n)return;const e=s.current.querySelector("iframe.giscus-frame");e?(()=>{const t={setConfig:{theme:i}};e.contentWindow.postMessage({giscus:t},"https://giscus.app")})():(()=>{const e=document.createElement("script");e.src="https://giscus.app/client.js",e.setAttribute("data-repo","greeng00se/greeng00se.github.io"),e.setAttribute("data-repo-id","R_kgDOIRAC3w"),e.setAttribute("data-category","Announcements"),e.setAttribute("data-category-id","DIC_kwDOIRAC384CTcGg"),e.setAttribute("data-mapping","pathname"),e.setAttribute("data-strict","0"),e.setAttribute("data-reactions-enabled","1"),e.setAttribute("data-emit-metadata","0"),e.setAttribute("data-input-position","bottom"),e.setAttribute("data-theme",i),e.setAttribute("data-lang","ko"),e.crossOrigin="anonymous",e.async=!0,s.current.appendChild(e)})()}),[i]),r.createElement(r.Fragment,null,r.createElement(a.Z,e),n&&r.createElement("div",{ref:s}))}},11748:(e,t,n)=>{var a={"./locale":89234,"./locale.js":89234};function r(e){var t=o(e);return n(t)}function o(e){if(!n.o(a,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return a[e]}r.keys=function(){return Object.keys(a)},r.resolve=o,e.exports=r,r.id=11748}}]); \ No newline at end of file diff --git a/assets/js/ccc49370.e0a78056.js b/assets/js/ccc49370.e0a78056.js new file mode 100644 index 000000000..d81d60fe2 --- /dev/null +++ b/assets/js/ccc49370.e0a78056.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6103],{65203:(e,t,n)=>{n.r(t),n.d(t,{default:()=>v});n(67294);var s=n(86010),a=n(10833),i=n(35281),r=n(9460),o=n(61460),l=n(857),c=n(95999),d=n(32244),u=n(85893);function m(e){const{nextItem:t,prevItem:n}=e;return(0,u.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.I)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,u.jsx)(d.Z,{...n,subLabel:(0,u.jsx)(c.Z,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer Post"})}),t&&(0,u.jsx)(d.Z,{...t,subLabel:(0,u.jsx)(c.Z,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older Post"}),isNext:!0})]})}function g(){const{assets:e,metadata:t}=(0,r.C)(),{title:n,description:s,date:i,tags:o,authors:l,frontMatter:c}=t,{keywords:d}=c,m=e.image??c.image;return(0,u.jsxs)(a.d,{title:n,description:s,keywords:d,image:m,children:[(0,u.jsx)("meta",{property:"og:type",content:"article"}),(0,u.jsx)("meta",{property:"article:published_time",content:i}),l.some((e=>e.url))&&(0,u.jsx)("meta",{property:"article:author",content:l.map((e=>e.url)).filter(Boolean).join(",")}),o.length>0&&(0,u.jsx)("meta",{property:"article:tag",content:o.map((e=>e.label)).join(",")})]})}var h=n(39407),f=n(22212);function p(e){let{sidebar:t,children:n}=e;const{metadata:s,toc:a}=(0,r.C)(),{nextItem:i,prevItem:c,frontMatter:d,unlisted:g}=s,{hide_table_of_contents:p,toc_min_heading_level:v,toc_max_heading_level:x}=d;return(0,u.jsxs)(o.Z,{sidebar:t,toc:!p&&a.length>0?(0,u.jsx)(h.Z,{toc:a,minHeadingLevel:v,maxHeadingLevel:x}):void 0,children:[g&&(0,u.jsx)(f.Z,{}),(0,u.jsx)(l.Z,{children:n}),(i||c)&&(0,u.jsx)(m,{nextItem:i,prevItem:c})]})}function v(e){const t=e.content;return(0,u.jsx)(r.n,{content:e.content,isBlogPostPage:!0,children:(0,u.jsxs)(a.FG,{className:(0,s.Z)(i.k.wrapper.blogPages,i.k.page.blogPostPage),children:[(0,u.jsx)(g,{}),(0,u.jsx)(p,{sidebar:e.sidebar,children:(0,u.jsx)(t,{})})]})})}},39407:(e,t,n)=>{n.d(t,{Z:()=>c});n(67294);var s=n(86010),a=n(93743);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var r=n(85893);const o="table-of-contents__link toc-highlight",l="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,r.jsx)("div",{className:(0,s.Z)(i.tableOfContents,"thin-scrollbar",t),children:(0,r.jsx)(a.Z,{...n,linkClassName:o,linkActiveClassName:l})})}},93743:(e,t,n)=>{n.d(t,{Z:()=>f});var s=n(67294),a=n(86668);function i(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):s.push(a)})),s}function r(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=r({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function o(e){const t=e.getBoundingClientRect();return t.top===t.bottom?o(e.parentNode):t}function l(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>o(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(o(s))?s:e[e.indexOf(s)-1]??null}return e[e.length-1]??null}function c(){const e=(0,s.useRef)(0),{navbar:{hideOnScroll:t}}=(0,a.L)();return(0,s.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,s.useRef)(void 0),n=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:r}=e;function o(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),o=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let a=t;a<=n;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:i,maxHeadingLevel:r}),c=l(o,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",o),document.addEventListener("resize",o),o(),()=>{document.removeEventListener("scroll",o),document.removeEventListener("resize",o)}}),[e,n])}var u=n(39960),m=n(85893);function g(e){let{toc:t,className:n,linkClassName:s,isChild:a}=e;return t.length?(0,m.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.Z,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(g,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const h=s.memo(g);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:o="table-of-contents__link",linkActiveClassName:l,minHeadingLevel:c,maxHeadingLevel:u,...g}=e;const f=(0,a.L)(),p=c??f.tableOfContents.minHeadingLevel,v=u??f.tableOfContents.maxHeadingLevel,x=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>r({toc:i(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:p,maxHeadingLevel:v});return d((0,s.useMemo)((()=>{if(o&&l)return{linkClassName:o,linkActiveClassName:l,minHeadingLevel:p,maxHeadingLevel:v}}),[o,l,p,v])),(0,m.jsx)(h,{toc:x,className:n,linkClassName:o,...g})}},22212:(e,t,n)=>{n.d(t,{Z:()=>g});n(67294);var s=n(86010),a=n(95999),i=n(35742),r=n(85893);function o(){return(0,r.jsx)(a.Z,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,r.jsx)(a.Z,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,r.jsx)(i.Z,{children:(0,r.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=n(35281),u=n(59047);function m(e){let{className:t}=e;return(0,r.jsx)(u.Z,{type:"caution",title:(0,r.jsx)(o,{}),className:(0,s.Z)(t,d.k.common.unlistedBanner),children:(0,r.jsx)(l,{})})}function g(e){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(c,{}),(0,r.jsx)(m,{...e})]})}},857:(e,t,n)=>{n.d(t,{Z:()=>l});var s=n(30390),a=n(67294),i=n(92949),r=n(9460),o=n(85893);const l=function(e){const{colorMode:t}=(0,i.I)(),{isBlogPostPage:n}=(0,r.C)(),l="dark"===t?"dark":"light",c=(0,a.useRef)(null);return(0,a.useEffect)((()=>{if(!n)return;const e=c.current.querySelector("iframe.giscus-frame");e?(()=>{const t={setConfig:{theme:l}};e.contentWindow.postMessage({giscus:t},"https://giscus.app")})():(()=>{const e=document.createElement("script");e.src="https://giscus.app/client.js",e.setAttribute("data-repo","greeng00se/greeng00se.github.io"),e.setAttribute("data-repo-id","R_kgDOIRAC3w"),e.setAttribute("data-category","Announcements"),e.setAttribute("data-category-id","DIC_kwDOIRAC384CTcGg"),e.setAttribute("data-mapping","pathname"),e.setAttribute("data-strict","0"),e.setAttribute("data-reactions-enabled","1"),e.setAttribute("data-emit-metadata","0"),e.setAttribute("data-input-position","bottom"),e.setAttribute("data-theme",l),e.setAttribute("data-lang","ko"),e.crossOrigin="anonymous",e.async=!0,c.current.appendChild(e)})()}),[l]),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.Z,{...e}),n&&(0,o.jsx)("div",{ref:c})]})}}}]); \ No newline at end of file diff --git a/assets/js/cd68cda1.533ff58c.js b/assets/js/cd68cda1.533ff58c.js deleted file mode 100644 index 0c035b4d2..000000000 --- a/assets/js/cd68cda1.533ff58c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8683],{3905:(e,n,t)=>{t.d(n,{Zo:()=>s,kt:()=>d});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function c(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function i(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),p=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},s=function(e){var n=p(e.components);return r.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},g=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),g=p(t),d=a,m=g["".concat(l,".").concat(d)]||g[d]||u[d]||o;return t?r.createElement(m,c(c({ref:n},s),{},{components:t})):r.createElement(m,c({ref:n},s))}));function d(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=t.length,c=new Array(o);c[0]=g;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i.mdxType="string"==typeof e?e:a,c[1]=i;for(var p=2;p<o;p++)c[p]=t[p];return r.createElement.apply(null,c)}return r.createElement.apply(null,t)}g.displayName="MDXCreateElement"},66934:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=t(87462),a=(t(67294),t(3905));const o={title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",slug:"log-async-exception",tags:["async","exception"]},c=void 0,i={permalink:"/log-async-exception",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",source:"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",description:"\ubb38\uc81c \uc0c1\ud669",date:"2023-09-18T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 18\uc77c",tags:[{label:"async",permalink:"/tags/async"},{label:"exception",permalink:"/tags/exception"}],readingTime:3.615,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",slug:"log-async-exception",tags:["async","exception"]},prevItem:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",permalink:"/web-application-evolution"},nextItem:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/tomcat-retrospective"}},l={authorsImageUrls:[]},p=[{value:"\ubb38\uc81c \uc0c1\ud669",id:"\ubb38\uc81c-\uc0c1\ud669",level:3},{value:"\ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815",id:"\ube44\ub3d9\uae30-\uc608\uc678-\ubc1c\uc0dd\uc2dc-\ub85c\uae45-\uc124\uc815",level:3},{value:"MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c",id:"mdc-\uc815\ubcf4-\uc5f0\ub3d9-\ubb38\uc81c",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:p};function u(e){let{components:n,...o}=e;return(0,a.kt)("wrapper",(0,r.Z)({},s,o,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ubb38\uc81c-\uc0c1\ud669"},"\ubb38\uc81c \uc0c1\ud669"),(0,a.kt)("p",null,"\ud604\uc7ac \ud2b8\ub9bd\ub4dc\ub85c\uc6b0\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ub418\uace0 \uc788\ub2e4. \ub85c\uadf8\ub97c \ud655\uc778\ud558\ub294 \ub3c4\uc911 ",(0,a.kt)("inlineCode",{parentName:"p"},"@Async"),"\uac00 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ub85c\uadf8\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \ucd9c\ub825\ub418\uc9c0 \uc54a\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud655\uc778\ud574 \ubcf4\ub2c8 Spring\uc758 ",(0,a.kt)("inlineCode",{parentName:"p"},"@ControllerAdvice")," + ",(0,a.kt)("inlineCode",{parentName:"p"},"@ExceptionHandler"),"\uc758 \uacbd\uc6b0 \ub3d9\uae30 \uc608\uc678\ub9cc \ucc98\ub9ac\ud558\uace0, \ube44\ub3d9\uae30 \uc608\uc678\ub97c \ucc98\ub9ac\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \ubc1c\uc0dd\ud55c \ubb38\uc81c\uc600\ub2e4. "),(0,a.kt)("h3",{id:"\ube44\ub3d9\uae30-\uc608\uc678-\ubc1c\uc0dd\uc2dc-\ub85c\uae45-\uc124\uc815"},"\ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815"),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1 4.1 \ubd80\ud130 \uc81c\uacf5\ub418\ub294 ",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html"},"AsyncUncaughtExceptionHandler"),"\uc758 \uacbd\uc6b0 \ubc18\ud658 \ud0c0\uc785\uc774 void\uc778 \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\ub97c \uc608\uc678 \ucc98\ub9ac\ud558\uae30 \uc27d\ub3c4\ub85d \ub3c4\uc640\uc900\ub2e4. "),(0,a.kt)("p",null,"\ub530\ub77c\uc11c AsyncUncaughtExceptionHandler \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud574\uc11c \uc608\uc678\ub97c \ud578\ub4e4\ub9c1\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc758 \ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \uc608\uc678\uac00 \ubc1c\uc0dd\ud560 \ub54c \uc2e4\ud589 \ud750\ub984\uc744 \ucd94\uc801\ud558\uae30 \uc704\ud574 MDC(Mapped Diagnostic Context)\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\ub3c4 \ub9c8\ucc2c\uac00\uc9c0\ub85c MDC\uc758 \uc815\ubcf4\ub97c \uac00\uc838\uc640\uc11c \ub85c\uadf8\ub97c \ucd9c\ub825\ud558\ub3c4\ub85d \uc124\uc815\ud588\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AsyncExceptionHandler",title:"AsyncExceptionHandler"},'@Slf4j\npublic class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {\n\n private static final String LOG_FORMAT = "[%s] %s";\n\n @Override\n public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {\n log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);\n }\n}\n')),(0,a.kt)("p",null,"AsyncExceptionHandler\uc758 \uacbd\uc6b0 AsyncConfigurer\ub97c \uad6c\ud604\ud55c Configuration \ud074\ub798\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","getAsyncUncaughtExceptionHandler() \uba54\uc11c\ub4dc\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec AsyncExceptionHandler\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uba74 \ub41c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AsyncConfig",title:"AsyncConfig"},"@EnableAsync\n@Configuration\npublic class AsyncConfig implements AsyncConfigurer {\n\n @Override\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\n return new AsyncExceptionHandler();\n }\n}\n")),(0,a.kt)("p",null,"\uc774\uc81c \ube44\ub3d9\uae30 \uc0c1\ud669\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 AsyncUncaughtExceptionHandler\uc758 \uad6c\ud604\uccb4\uc778 AsyncExceptionHandler\uac00 \uc608\uc678\ub97c \uc7a1\uc544 \ucc98\ub9ac\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"mdc-\uc815\ubcf4-\uc5f0\ub3d9-\ubb38\uc81c"},"MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c"),(0,a.kt)("p",null,"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \ubcc4\ub3c4\uc758 \uc2a4\ub808\ub4dc\uc5d0\uc11c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 ThreadLocal \uae30\ubc18\uc73c\ub85c \ub3d9\uc791\ud558\ub294 MDC\uc758 \uc815\ubcf4\ub97c \uc5bb\uc5b4\uc62c \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./mdc-null.png",src:t(81450).Z,width:"2236",height:"426"})),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1 4.3 \uc774\uc0c1\ubd80\ud130 \uc81c\uacf5\ub418\ub294 ",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html"},"TaskDecorator"),"\ub97c \uc774\uc6a9\ud558\uba74 TaskExecutor\ub97c \ucee4\uc2a4\ud130\ub9c8\uc774\uc9d5 \ud560 \uc218 \uc788\ub2e4. TaskDecorator\ub97c \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \ud558\ub098 \uc0dd\uc131\ud558\uace0, Task\uac00 \uc2e4\ud589\ub418\uae30 \uc804 MDC\uc758 \uc815\ubcf4\ub97c \ubcf5\uc0ac\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=MdcTaskDecorator",title:"MdcTaskDecorator"},"public class MdcTaskDecorator implements TaskDecorator {\n\n @Override\n public Runnable decorate(final Runnable runnable) {\n Map<String, String> threadContext = MDC.getCopyOfContextMap();\n return () -> {\n MDC.setContextMap(threadContext);\n runnable.run();\n };\n }\n}\n")),(0,a.kt)("p",null,"\uc0dd\uc131\ud55c Decorator \ud074\ub798\uc2a4\ub97c \uc124\uc815 \ud30c\uc77c\uc5d0 \ub4f1\ub85d\ud574 \uc900\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AsyncConfig",title:"AsyncConfig"},"@RequiredArgsConstructor\n@EnableAsync\n@Configuration\npublic class AsyncConfig implements AsyncConfigurer {\n\n private final AsyncConfigurationProperties properties;\n\n @Bean\n public ThreadPoolTaskExecutor taskExecutor() {\n ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();\n executor.setCorePoolSize(properties.coreSize());\n executor.setMaxPoolSize(properties.maxSize());\n executor.setQueueCapacity(properties.queueCapacity());\n \n // highlight-next-line\n executor.setTaskDecorator(new MdcTaskDecorator());\n executor.setWaitForTasksToCompleteOnShutdown(true);\n executor.initialize();\n return executor;\n }\n\n @Override\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\n return new AsyncExceptionHandler();\n }\n}\n")),(0,a.kt)("p",null,"\uc124\uc815 \ud6c4\uc5d0\ub294 \uc815\uc0c1\uc801\uc73c\ub85c MDC\uc5d0 \ub4e4\uc5b4\uac00 \uc788\ub294 UUID\uac00 \ucd9c\ub825\ub418\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./mdc-not-null.png",src:t(97754).Z,width:"2620",height:"440"})),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.baeldung.com/spring-async"},"spring async, baeldung"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception"},"@Async will not call by @ControllerAdvice for global exception"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://blog.gangnamunni.com/post/mdc-context-task-decorator/"},"Spring \uc758 \ub3d9\uae30, \ube44\ub3d9\uae30, \ubc30\uce58 \ucc98\ub9ac\uc2dc \ud56d\uc0c1 context \ub97c \uc720\uc9c0\ud558\uace0 \ub85c\uae45\ud558\uae30, \uac15\ub0a8\uc5b8\ub2c8"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html"},"TaskDecorator, Spring docs"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html"},"AsyncUncaughtExceptionHandler")))}u.isMDXComponent=!0},97754:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/mdc-not-null-2b12c13f4f420a335c9e55dbea503f1b.png"},81450:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/mdc-null-95b3bbdce99ef36ba843986413e0421a.png"}}]); \ No newline at end of file diff --git a/assets/js/cd68cda1.c2b122c5.js b/assets/js/cd68cda1.c2b122c5.js new file mode 100644 index 000000000..ab5040b39 --- /dev/null +++ b/assets/js/cd68cda1.c2b122c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8683],{2915:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var t=r(85893),c=r(3905);const a={title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",slug:"log-async-exception",tags:["async","exception"]},o=void 0,i={permalink:"/log-async-exception",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",source:"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",description:"\ubb38\uc81c \uc0c1\ud669",date:"2023-09-18T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 18\uc77c",tags:[{label:"async",permalink:"/tags/async"},{label:"exception",permalink:"/tags/exception"}],readingTime:3.615,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",slug:"log-async-exception",tags:["async","exception"]},unlisted:!1,prevItem:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",permalink:"/web-application-evolution"},nextItem:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/tomcat-retrospective"}},s={authorsImageUrls:[]},l=[{value:"\ubb38\uc81c \uc0c1\ud669",id:"\ubb38\uc81c-\uc0c1\ud669",level:3},{value:"\ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815",id:"\ube44\ub3d9\uae30-\uc608\uc678-\ubc1c\uc0dd\uc2dc-\ub85c\uae45-\uc124\uc815",level:3},{value:"MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c",id:"mdc-\uc815\ubcf4-\uc5f0\ub3d9-\ubb38\uc81c",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const n={a:"a",br:"br",code:"code",h3:"h3",img:"img",p:"p",pre:"pre",...(0,c.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\ubb38\uc81c-\uc0c1\ud669",children:"\ubb38\uc81c \uc0c1\ud669"}),"\n",(0,t.jsxs)(n.p,{children:["\ud604\uc7ac \ud2b8\ub9bd\ub4dc\ub85c\uc6b0\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ub418\uace0 \uc788\ub2e4. \ub85c\uadf8\ub97c \ud655\uc778\ud558\ub294 \ub3c4\uc911 ",(0,t.jsx)(n.code,{children:"@Async"}),"\uac00 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ub85c\uadf8\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \ucd9c\ub825\ub418\uc9c0 \uc54a\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud655\uc778\ud574 \ubcf4\ub2c8 Spring\uc758 ",(0,t.jsx)(n.code,{children:"@ControllerAdvice"})," + ",(0,t.jsx)(n.code,{children:"@ExceptionHandler"}),"\uc758 \uacbd\uc6b0 \ub3d9\uae30 \uc608\uc678\ub9cc \ucc98\ub9ac\ud558\uace0, \ube44\ub3d9\uae30 \uc608\uc678\ub97c \ucc98\ub9ac\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \ubc1c\uc0dd\ud55c \ubb38\uc81c\uc600\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ube44\ub3d9\uae30-\uc608\uc678-\ubc1c\uc0dd\uc2dc-\ub85c\uae45-\uc124\uc815",children:"\ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815"}),"\n",(0,t.jsxs)(n.p,{children:["\uc2a4\ud504\ub9c1 4.1 \ubd80\ud130 \uc81c\uacf5\ub418\ub294 ",(0,t.jsx)(n.a,{href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html",children:"AsyncUncaughtExceptionHandler"}),"\uc758 \uacbd\uc6b0 \ubc18\ud658 \ud0c0\uc785\uc774 void\uc778 \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\ub97c \uc608\uc678 \ucc98\ub9ac\ud558\uae30 \uc27d\ub3c4\ub85d \ub3c4\uc640\uc900\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\ub530\ub77c\uc11c AsyncUncaughtExceptionHandler \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud574\uc11c \uc608\uc678\ub97c \ud578\ub4e4\ub9c1\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae30\uc874\uc758 \ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \uc608\uc678\uac00 \ubc1c\uc0dd\ud560 \ub54c \uc2e4\ud589 \ud750\ub984\uc744 \ucd94\uc801\ud558\uae30 \uc704\ud574 MDC(Mapped Diagnostic Context)\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\ub3c4 \ub9c8\ucc2c\uac00\uc9c0\ub85c MDC\uc758 \uc815\ubcf4\ub97c \uac00\uc838\uc640\uc11c \ub85c\uadf8\ub97c \ucd9c\ub825\ud558\ub3c4\ub85d \uc124\uc815\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=AsyncExceptionHandler",children:'@Slf4j\npublic class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {\n\n private static final String LOG_FORMAT = "[%s] %s";\n\n @Override\n public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {\n log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["AsyncExceptionHandler\uc758 \uacbd\uc6b0 AsyncConfigurer\ub97c \uad6c\ud604\ud55c Configuration \ud074\ub798\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","getAsyncUncaughtExceptionHandler() \uba54\uc11c\ub4dc\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec AsyncExceptionHandler\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=AsyncConfig",children:"@EnableAsync\n@Configuration\npublic class AsyncConfig implements AsyncConfigurer {\n\n @Override\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\n return new AsyncExceptionHandler();\n }\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"\uc774\uc81c \ube44\ub3d9\uae30 \uc0c1\ud669\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 AsyncUncaughtExceptionHandler\uc758 \uad6c\ud604\uccb4\uc778 AsyncExceptionHandler\uac00 \uc608\uc678\ub97c \uc7a1\uc544 \ucc98\ub9ac\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.h3,{id:"mdc-\uc815\ubcf4-\uc5f0\ub3d9-\ubb38\uc81c",children:"MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c"}),"\n",(0,t.jsx)(n.p,{children:"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \ubcc4\ub3c4\uc758 \uc2a4\ub808\ub4dc\uc5d0\uc11c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 ThreadLocal \uae30\ubc18\uc73c\ub85c \ub3d9\uc791\ud558\ub294 MDC\uc758 \uc815\ubcf4\ub97c \uc5bb\uc5b4\uc62c \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"./mdc-null.png",src:r(81450).Z+"",width:"2236",height:"426"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc2a4\ud504\ub9c1 4.3 \uc774\uc0c1\ubd80\ud130 \uc81c\uacf5\ub418\ub294 ",(0,t.jsx)(n.a,{href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html",children:"TaskDecorator"}),"\ub97c \uc774\uc6a9\ud558\uba74 TaskExecutor\ub97c \ucee4\uc2a4\ud130\ub9c8\uc774\uc9d5 \ud560 \uc218 \uc788\ub2e4. TaskDecorator\ub97c \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \ud558\ub098 \uc0dd\uc131\ud558\uace0, Task\uac00 \uc2e4\ud589\ub418\uae30 \uc804 MDC\uc758 \uc815\ubcf4\ub97c \ubcf5\uc0ac\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=MdcTaskDecorator",children:"public class MdcTaskDecorator implements TaskDecorator {\n\n @Override\n public Runnable decorate(final Runnable runnable) {\n Map<String, String> threadContext = MDC.getCopyOfContextMap();\n return () -> {\n MDC.setContextMap(threadContext);\n runnable.run();\n };\n }\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"\uc0dd\uc131\ud55c Decorator \ud074\ub798\uc2a4\ub97c \uc124\uc815 \ud30c\uc77c\uc5d0 \ub4f1\ub85d\ud574 \uc900\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=AsyncConfig",children:"@RequiredArgsConstructor\n@EnableAsync\n@Configuration\npublic class AsyncConfig implements AsyncConfigurer {\n\n private final AsyncConfigurationProperties properties;\n\n @Bean\n public ThreadPoolTaskExecutor taskExecutor() {\n ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();\n executor.setCorePoolSize(properties.coreSize());\n executor.setMaxPoolSize(properties.maxSize());\n executor.setQueueCapacity(properties.queueCapacity());\n \n // highlight-next-line\n executor.setTaskDecorator(new MdcTaskDecorator());\n executor.setWaitForTasksToCompleteOnShutdown(true);\n executor.initialize();\n return executor;\n }\n\n @Override\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\n return new AsyncExceptionHandler();\n }\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"\uc124\uc815 \ud6c4\uc5d0\ub294 \uc815\uc0c1\uc801\uc73c\ub85c MDC\uc5d0 \ub4e4\uc5b4\uac00 \uc788\ub294 UUID\uac00 \ucd9c\ub825\ub418\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"./mdc-not-null.png",src:r(97754).Z+"",width:"2620",height:"440"})}),"\n",(0,t.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://www.baeldung.com/spring-async",children:"spring async, baeldung"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception",children:"@Async will not call by @ControllerAdvice for global exception"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://blog.gangnamunni.com/post/mdc-context-task-decorator/",children:"Spring \uc758 \ub3d9\uae30, \ube44\ub3d9\uae30, \ubc30\uce58 \ucc98\ub9ac\uc2dc \ud56d\uc0c1 context \ub97c \uc720\uc9c0\ud558\uace0 \ub85c\uae45\ud558\uae30, \uac15\ub0a8\uc5b8\ub2c8"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html",children:"TaskDecorator, Spring docs"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html",children:"AsyncUncaughtExceptionHandler"})]})]})}function d(e={}){const{wrapper:n}={...(0,c.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>l});var t=r(67294);function c(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?a(Object(r),!0).forEach((function(n){c(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function i(e,n){if(null==e)return{};var r,t,c=function(e,n){if(null==e)return{};var r,t,c={},a=Object.keys(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||(c[r]=e[r]);return c}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var s=t.createContext({}),l=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,c=e.mdxType,a=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=l(r),g=c,h=u["".concat(s,".").concat(g)]||u[g]||p[g]||a;return r?t.createElement(h,o(o({ref:n},d),{},{components:r})):t.createElement(h,o({ref:n},d))}));d.displayName="MDXCreateElement"},97754:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/mdc-not-null-2b12c13f4f420a335c9e55dbea503f1b.png"},81450:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/mdc-null-95b3bbdce99ef36ba843986413e0421a.png"}}]); \ No newline at end of file diff --git a/assets/js/cec43d6a.0cb02c7e.js b/assets/js/cec43d6a.0cb02c7e.js new file mode 100644 index 000000000..1f6426981 --- /dev/null +++ b/assets/js/cec43d6a.0cb02c7e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1358],{41056:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>l});var n=r(85893),o=r(3905);const s={title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",slug:"/culture/postmortem",last_update:{date:"2023/06/17"},tags:["postmortem"]},a=void 0,i={id:"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",description:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)",source:"@site/docs/\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c.mdx",sourceDirName:"\ubb38\ud654",slug:"/culture/postmortem",permalink:"/docs/culture/postmortem",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c.mdx",tags:[{label:"postmortem",permalink:"/docs/tags/postmortem"}],version:"current",lastUpdatedAt:168696e4,formattedLastUpdatedAt:"2023\ub144 6\uc6d4 17\uc77c",frontMatter:{title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",slug:"/culture/postmortem",last_update:{date:"2023/06/17"},tags:["postmortem"]},sidebar:"tutorialSidebar",previous:{title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/docs/monitoring/intro"},next:{title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",permalink:"/docs/deploy/zero-downtime"}},c={},l=[{value:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)",id:"\ud3ec\uc2a4\ud2b8-\ubaa8\ud15cpostmortem",level:3},{value:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c\uc5d0 \ub2f4\uaca8\uc57c \ud558\ub294 \ub0b4\uc6a9",id:"\ud3ec\uc2a4\ud2b8-\ubaa8\ud15c\uc5d0-\ub2f4\uaca8\uc57c-\ud558\ub294-\ub0b4\uc6a9",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const t={a:"a",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\ud3ec\uc2a4\ud2b8-\ubaa8\ud15cpostmortem",children:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)"}),"\n",(0,n.jsx)(t.p,{children:"\uc2e4\ud328\ud55c \uadfc\ubcf8 \uc6d0\uc778\uc744 \ubd84\uc11d\ud558\uc5ec \ubb38\uc11c\ub85c \ub0a8\uae30\ub294 \uac83"}),"\n",(0,n.jsx)(t.h3,{id:"\ud3ec\uc2a4\ud2b8-\ubaa8\ud15c\uc5d0-\ub2f4\uaca8\uc57c-\ud558\ub294-\ub0b4\uc6a9",children:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c\uc5d0 \ub2f4\uaca8\uc57c \ud558\ub294 \ub0b4\uc6a9"}),"\n",(0,n.jsxs)(t.p,{children:["\uc0ac\uac74\uc758 \uac1c\uc694",(0,n.jsx)(t.br,{}),"\n","\uc0ac\uac74\uc744 \uc778\uc9c0\ud558\uace0 \ud574\uacb0\uc5d0 \uc774\ub974\uae30\uae4c\uc9c0\uc758 \ud0c0\uc784\ub77c\uc778",(0,n.jsx)(t.br,{}),"\n","\uc0ac\uac74\uc758 \uadfc\ubcf8 \uc6d0\uc778",(0,n.jsx)(t.br,{}),"\n","\uc601\ud5a5\uacfc \ud53c\ud574 \ud3c9\uac00",(0,n.jsx)(t.br,{}),"\n","\ubb38\uc81c\ub97c \uc989\uc2dc \ud574\uacb0\ud558\uae30 \uc704\ud55c \uc870\uce58 \ud56d\ubaa9(\uc18c\uc720\uc790 \uba85\uc2dc)",(0,n.jsx)(t.br,{}),"\n","\uac1c\ubc1c \ubc29\uc9c0\ub97c \uc704\ud55c \uc870\uce58 \ud56d\ubaa9",(0,n.jsx)(t.br,{}),"\n","\ud574\ub2f9 \uacbd\ud5d8\uc5d0\uc11c \uc5bb\uc740 \uad50\ud6c8"]}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsxs)(t.p,{children:["\uad6c\uae00 \uc5d4\uc9c0\ub2c8\uc5b4\ub294 \uc774\ub807\uac8c \uc77c\ud55c\ub2e4, \ud0c0\uc774\ud130\uc2a4 \uc708\ud130\uc2a4, \ud1b0 \ub9e8\uc26c\ub809, \ud558\uc774\ub7fc \ub77c\uc774\ud2b8 p.86",(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.a,{href:"https://techblog.woowahan.com/4886/",children:"\uc6b0\uc544\ud55c \uc7a5\uc560\ub300\uc751"})]})]})}function u(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?s(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),l=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,s=e.originalType,c=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),m=l(r),d=o,b=m["".concat(c,".").concat(d)]||m[d]||p[d]||s;return r?n.createElement(b,a(a({ref:t},u),{},{components:r})):n.createElement(b,a({ref:t},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/cec43d6a.e9cb4ce1.js b/assets/js/cec43d6a.e9cb4ce1.js deleted file mode 100644 index 05638543f..000000000 --- a/assets/js/cec43d6a.e9cb4ce1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1358],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},m=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),u=c(r),d=o,f=u["".concat(i,".").concat(d)]||u[d]||s[d]||a;return r?n.createElement(f,p(p({ref:t},m),{},{components:r})):n.createElement(f,p({ref:t},m))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,p=new Array(a);p[0]=u;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:o,p[1]=l;for(var c=2;c<a;c++)p[c]=r[c];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}u.displayName="MDXCreateElement"},19284:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>s,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",slug:"/culture/postmortem",last_update:{date:"2023/06/17"},tags:["postmortem"]},p=void 0,l={unversionedId:"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",id:"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",description:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)",source:"@site/docs/\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c.mdx",sourceDirName:"\ubb38\ud654",slug:"/culture/postmortem",permalink:"/docs/culture/postmortem",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c.mdx",tags:[{label:"postmortem",permalink:"/docs/tags/postmortem"}],version:"current",lastUpdatedAt:168696e4,formattedLastUpdatedAt:"2023\ub144 6\uc6d4 17\uc77c",frontMatter:{title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",slug:"/culture/postmortem",last_update:{date:"2023/06/17"},tags:["postmortem"]},sidebar:"tutorialSidebar",previous:{title:"\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/docs/monitoring/intro"},next:{title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",permalink:"/docs/deploy/zero-downtime"}},i={},c=[{value:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)",id:"\ud3ec\uc2a4\ud2b8-\ubaa8\ud15cpostmortem",level:3},{value:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c\uc5d0 \ub2f4\uaca8\uc57c \ud558\ub294 \ub0b4\uc6a9",id:"\ud3ec\uc2a4\ud2b8-\ubaa8\ud15c\uc5d0-\ub2f4\uaca8\uc57c-\ud558\ub294-\ub0b4\uc6a9",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],m={toc:c};function s(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"\ud3ec\uc2a4\ud2b8-\ubaa8\ud15cpostmortem"},"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c(Postmortem)"),(0,o.kt)("p",null,"\uc2e4\ud328\ud55c \uadfc\ubcf8 \uc6d0\uc778\uc744 \ubd84\uc11d\ud558\uc5ec \ubb38\uc11c\ub85c \ub0a8\uae30\ub294 \uac83"),(0,o.kt)("h3",{id:"\ud3ec\uc2a4\ud2b8-\ubaa8\ud15c\uc5d0-\ub2f4\uaca8\uc57c-\ud558\ub294-\ub0b4\uc6a9"},"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c\uc5d0 \ub2f4\uaca8\uc57c \ud558\ub294 \ub0b4\uc6a9"),(0,o.kt)("p",null,"\uc0ac\uac74\uc758 \uac1c\uc694",(0,o.kt)("br",{parentName:"p"}),"\n","\uc0ac\uac74\uc744 \uc778\uc9c0\ud558\uace0 \ud574\uacb0\uc5d0 \uc774\ub974\uae30\uae4c\uc9c0\uc758 \ud0c0\uc784\ub77c\uc778",(0,o.kt)("br",{parentName:"p"}),"\n","\uc0ac\uac74\uc758 \uadfc\ubcf8 \uc6d0\uc778",(0,o.kt)("br",{parentName:"p"}),"\n","\uc601\ud5a5\uacfc \ud53c\ud574 \ud3c9\uac00",(0,o.kt)("br",{parentName:"p"}),"\n","\ubb38\uc81c\ub97c \uc989\uc2dc \ud574\uacb0\ud558\uae30 \uc704\ud55c \uc870\uce58 \ud56d\ubaa9(\uc18c\uc720\uc790 \uba85\uc2dc)",(0,o.kt)("br",{parentName:"p"}),"\n","\uac1c\ubc1c \ubc29\uc9c0\ub97c \uc704\ud55c \uc870\uce58 \ud56d\ubaa9",(0,o.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uacbd\ud5d8\uc5d0\uc11c \uc5bb\uc740 \uad50\ud6c8 "),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,"\uad6c\uae00 \uc5d4\uc9c0\ub2c8\uc5b4\ub294 \uc774\ub807\uac8c \uc77c\ud55c\ub2e4, \ud0c0\uc774\ud130\uc2a4 \uc708\ud130\uc2a4, \ud1b0 \ub9e8\uc26c\ub809, \ud558\uc774\ub7fc \ub77c\uc774\ud2b8 p.86",(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/4886/"},"\uc6b0\uc544\ud55c \uc7a5\uc560\ub300\uc751")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/cef46b76.69423224.js b/assets/js/cef46b76.69423224.js new file mode 100644 index 000000000..044b5fbe4 --- /dev/null +++ b/assets/js/cef46b76.69423224.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8644],{91704:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=t(85893),i=t(3905);const r={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",slug:"route-image-python",tags:["Image","Python"]},l=void 0,s={permalink:"/route-image-python",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",source:"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",description:"\uac1c\uc694",date:"2023-07-31T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 31\uc77c",tags:[{label:"Image",permalink:"/tags/image"},{label:"Python",permalink:"/tags/python"}],readingTime:6.185,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",slug:"route-image-python",tags:["Image","Python"]},unlisted:!1,prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",permalink:"/route-image-implementation"},nextItem:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",permalink:"/mock-static-method"}},o={authorsImageUrls:[]},d=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\uc0ac\uc6a9 \uae30\uc220",id:"\uc0ac\uc6a9-\uae30\uc220",level:3},{value:"\uc694\uad6c\uc0ac\ud56d",id:"\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd",id:"\uc774\ubbf8\uc9c0-\ucd9c\ub825-\ubc29\uc2dd",level:3},{value:"\ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604",id:"\ub85c\uceec\uc5d0\uc11c-\uae30\ub2a5-\uad6c\ud604",level:3},{value:"AWS Lambda",id:"aws-lambda",level:3},{value:"\ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131",id:"\ub78c\ub2e4-s3-\uc811\uadfc\uc744-\uc704\ud55c-iam-\uc0dd\uc131",level:3},{value:"\ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc",id:"\ub78c\ub2e4-\ubc30\ud3ec\uc6a9-\ucf54\ub4dc",level:3},{value:"Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131",id:"layer-\ucd94\uac00\ub97c-\uc704\ud55c-zip-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"<code>No module named 'numpy.core._multiarray_umath'</code> \uc5d0\ub7ec",id:"no-module-named-numpycore_multiarray_umath-\uc5d0\ub7ec",level:3},{value:"\uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01",id:"\uc801\uc815\uae30\uc220\uc5d0-\ub300\ud55c-\uc0dd\uac01",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function p(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.ah)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h3,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,a.jsx)(n.p,{children:"\uc774\uc804\uc5d0 \uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uc870\uc0ac\ud558\uba74\uc11c \ud30c\uc774\uc36c\uc744 \uc0ac\uc6a9\ud55c \ub0b4\uc6a9\uc744 \uc815\ub9ac\ud55c \ub0b4\uc6a9\uc774\ub2e4."}),"\n",(0,a.jsx)(n.h3,{id:"\uc0ac\uc6a9-\uae30\uc220",children:"\uc0ac\uc6a9 \uae30\uc220"}),"\n",(0,a.jsxs)(n.p,{children:["\uc5b8\uc5b4: Python 3.10",(0,a.jsx)(n.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131: matplotlib",(0,a.jsx)(n.br,{}),"\n","\uc11c\ube44\uc2a4: AWS Lambda, AWS API Gateway",(0,a.jsx)(n.br,{}),"\n","\uc774\ubbf8\uc9c0 \uc800\uc7a5 \ubc0f URL: AWS S3, AWS CloudFront"]}),"\n",(0,a.jsx)(n.p,{children:"\ud50c\ub85c\uc6b0\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n Server -- \uc0dd\uc131 \uc694\uccad --\x3e AG[API Gateway] --\x3e Lambda --\x3e S3\n Client --\x3e CloudFront --\x3e S3"}),"\n",(0,a.jsx)(n.h3,{id:"\uc694\uad6c\uc0ac\ud56d",children:"\uc694\uad6c\uc0ac\ud56d"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"./route.png",src:t(13533).Z+"",width:"1014",height:"902"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc6b0\uce21 \uc0c1\ub2e8\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub824\uace0 \ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \ubc30\uc5f4\uc744 \uc785\ub825\ubc1b\ub294\ub2e4."}),"\n",(0,a.jsx)(n.li,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131"}),"\n",(0,a.jsx)(n.li,{children:"\uc120\uacfc \uc810 \ud45c\ud604"}),"\n",(0,a.jsx)(n.li,{children:"\ud22c\uba85\ud55c \ubc30\uacbd\uc0c9"}),"\n",(0,a.jsx)(n.li,{children:"\uc704\uacbd\ub3c4 \ucc28\uc774\uac00 \ud06c\ub4e0 \uc791\ub4e0 \uc81c\uacf5\ud558\ub294 \uc774\ubbf8\uc9c0 \ub0b4\uc5d0 \uacbd\ub85c\uac00 \ub2e4 \ud3ec\ud568\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4."}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"\uc774\ubbf8\uc9c0-\ucd9c\ub825-\ubc29\uc2dd",children:"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"\uc704\uacbd\ub3c4\ub97c \ucc98\ub9ac\ud55c \uac12\uc73c\ub85c \uc9c1\uc811 \uacbd\ub85c\ub97c \uadf8\ub9b0 \ub2e4\uc74c \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5"}),"\n",(0,a.jsx)(n.li,{children:"\ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac \uc0ac\uc6a9\ud558\uc5ec \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5"}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd\uc758 \uacbd\uc6b0 1\ubc88\uacfc 2\ubc88\uc744 \uace0\ubbfc\ud588\uc5c8\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud30c\uc774\uc36c\uc73c\ub85c\ub294 \ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc778 matplotlib\uc744 \uc0ac\uc6a9\ud588\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\ub85c\uceec\uc5d0\uc11c-\uae30\ub2a5-\uad6c\ud604",children:"\ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:"import time\n\nimport matplotlib.pyplot as plt\n\n\ndef draw(point):\n start = time.time()\n x, y = zip(*point)\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\n draw_lines(pixel_x, pixel_y)\n end = time.time()\n print(end - start)\n \ndef convert_to_pixel_values(x, y):\n max_diff = max(max(x) - min(x), max(y) - min(y))\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\n\n\ndef scale_to_pixel_values(points, max_diff):\n min_value = min(points)\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\n return scaled_coordinates\n\n\ndef draw_lines(x, y):\n figure = plt.gcf()\n figure.set_size_inches(5, 5)\n plt.plot(x, y, c = 'w',linewidth=5)\n plt.scatter(x[3],y[3], c = 'w', s = 125)\n plt.axis('off')\n plt.savefig('name.png', transparent=True, format='png')\n\npoint = [\n [126.96352960597338, 37.590841000217125],\n [126.96987292787792, 37.58435564234159],\n [126.98128481452298, 37.58594375113966],\n [126.99360339342958, 37.58248524741927],\n [126.99867565340067, 37.56778118088622],\n [127.001935378366117, 37.55985240444085],\n [126.9831048919687, 37.548030119488665],\n [126.97189273528845, 37.5119879225856],\n [127.02689859997221, 37.48488593333883]\n]\n\ndraw(point)\n"})}),"\n",(0,a.jsx)(n.p,{children:"\uc0dd\uc131 \uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4. (\uc608\uc2dc\ub97c \uc704\ud574 \uac80\uc740\uc0c9\uc73c\ub85c \ucd9c\ub825)"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"./routeImage.png",src:t(46365).Z+"",width:"500",height:"500"})}),"\n",(0,a.jsx)(n.h3,{id:"aws-lambda",children:"AWS Lambda"}),"\n",(0,a.jsxs)(n.p,{children:["\uc378\ub124\uc77c \uc0dd\uc131 \uc11c\ubc84\ub97c \ub530\ub85c \ub450\uae30\ub294 \uae30\ub2a5 \ub300\ube44 \ube44\uc6a9\uc774 \ub108\ubb34 \ud074 \uac83\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc11c\ubc84\ub9ac\uc2a4\ub85c \ud30c\uc77c\uc744 \ucc98\ub9ac\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c s3 \uc811\uadfc\uc740 boto3\ub97c \uc0ac\uc6a9\ud588\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\ub78c\ub2e4-s3-\uc811\uadfc\uc744-\uc704\ud55c-iam-\uc0dd\uc131",children:"\ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131"}),"\n",(0,a.jsx)(n.p,{children:"AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy \ub450\uac00\uc9c0\ub97c \ucd94\uac00\ud574\uc11c Lambda \uc804\uc6a9 \uc5ed\ud560\uc744 \ub9cc\ub4e4\uc5b4 \uc0ac\uc6a9\ud588\ub2e4."}),"\n",(0,a.jsx)(n.h3,{id:"\ub78c\ub2e4-\ubc30\ud3ec\uc6a9-\ucf54\ub4dc",children:"\ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc"}),"\n",(0,a.jsx)(n.p,{children:"\uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \ud655\uc778\ud560 \ub550 \uc704\uce58 \uc810\uc744 \ucc0d\ub294 \uae30\ub2a5\uc744 \ub78c\ub2e4\uc5d0 \ubc30\ud3ec\ud558\uc9c0 \uc54a\uc558\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",children:"\nimport io\nimport uuid\n\nimport boto3\nimport matplotlib.pyplot as plt\n\nPIXEL = 255\nBUCKET_NAME = 'image-plot'\nS3 = 's3'\n\ndef lambda_handler(event, context):\n x = event['x']\n y = event['y']\n image_name = str(uuid.uuid4())\n\n img_data = draw(x, y)\n s3 = boto3.client(S3)\n s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)\n url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'\n\n return {\n 'statusCode': 200,\n 'body': url\n }\n\ndef draw(x, y):\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\n img_data = draw_lines(pixel_x, pixel_y)\n plt.close()\n return img_data\n\ndef convert_to_pixel_values(x, y):\n max_diff = max(max(x) - min(x), max(y) - min(y))\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\n\ndef scale_to_pixel_values(points, max_diff):\n min_value = min(points)\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\n pixel_values = [int(p * PIXEL) for p in scaled_coordinates]\n return pixel_values\n\ndef draw_lines(x, y):\n plt.plot(x, y, 'k-', linewidth=10)\n plt.axis('off')\n img_data = io.BytesIO()\n plt.savefig(img_data, transparent=True, format='png')\n img_data.seek(0)\n return img_data\n\n"})}),"\n",(0,a.jsx)(n.h3,{id:"layer-\ucd94\uac00\ub97c-\uc704\ud55c-zip-\ud30c\uc77c-\uc0dd\uc131",children:"Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131"}),"\n",(0,a.jsxs)(n.p,{children:["matplotlib\uc758 \uacbd\uc6b0 \uc678\ubd80 \ub77c\uc774\ube0c\ub7ec\ub9ac\uae30 \ub54c\ubb38\uc5d0 \ub530\ub85c Layer\ub97c \ucd94\uac00\ud574\uc57c \ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc5b4\uc11c \uc5c5\ub85c\ub4dc\ud574\uc57c\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc774\ub54c python\uc758 Lambda \ub7f0\ud0c0\uc784\uc5d0 \ub300\ud55c \uacc4\uce35 \uacbd\ub85c\ub294 python\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc555\ucd95\ud55c zip \ud30c\uc77c\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\ub97c \ub744\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"pillow.zip\n\u2502 python/PIL\n\u2514 python/Pillow-5.3.0.dist-info\n"})}),"\n",(0,a.jsx)(n.p,{children:"Ubuntu \uae30\uc900 \ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc0dd\uc131\uc744 \uc9c4\ud589\ud588\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"sudo apt update\nsudo apt install zip\nsudo apt install python3-pip\n\nmkdir python\npip3 install matplotlib -t python # pip3 install \uc124\uce58\ud560_\ud328\ud0a4\uc9c0 -t \uc124\uce58_\uacbd\ub85c\nzip -r my_layer.zip python # zip -r \uc555\ucd95_\ud30c\uc77c\uba85 \uc555\ucd95_\ud30c\uc77c\uc774_\uc874\uc7ac\ud558\ub294_\uacbd\ub85c\n"})}),"\n",(0,a.jsxs)(n.h3,{id:"no-module-named-numpycore_multiarray_umath-\uc5d0\ub7ec",children:[(0,a.jsx)(n.code,{children:"No module named 'numpy.core._multiarray_umath'"})," \uc5d0\ub7ec"]}),"\n",(0,a.jsxs)(n.p,{children:["Layer \ucd94\uac00 \ud6c4 \ub78c\ub2e4 \uc2e4\ud589 \uc2dc \ubc1c\uc0dd\ud55c \uc5d0\ub7ec\uc600\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ucc98\uc74c\uc5d0 mac\uc5d0\uc11c zip \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \uc5c5\ub85c\ub4dc\ud588\ub294\ub370 \ud574\ub2f9 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc774\ub294 lambda\uac00 \ub3cc\uc544\uac00\ub294 \ub3d9\uc77c\ud55c \ud658\uacbd\uc5d0\uc11c layer\ub97c \uc704\ud55c zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc9c0 \uc54a\uc544\uc11c \ubc1c\uc0dd\ud558\ub294 \ubb38\uc81c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uac04\ub2e8\ud558\uac8c ec2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c \ub530\ub85c Layer\ub97c \uc0dd\uc131\ud558\uba74 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\uc801\uc815\uae30\uc220\uc5d0-\ub300\ud55c-\uc0dd\uac01",children:"\uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01"}),"\n",(0,a.jsxs)(n.p,{children:["\ud504\ub85c\uc81d\ud2b8\uc5d0 Lambda\uc640 Python\uc744 \uc0ac\uc6a9\ud558\ub824\uace0 \ud588\uc9c0\ub9cc \uc544\uc27d\uac8c\ub3c4 \ubc18\ub824\ub2f9\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","AWS Lambda\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc778\uc2a4\ud134\uc2a4\uc5d0 \ud574\ub2f9 \ucf54\ub4dc\ub97c \ubc30\ud3ec\ud558\ub294 \uac83\ubcf4\ub2e4 \ub354 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc77c \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \ud604\uc7ac \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uac00\uc6a9 \uac00\ub2a5\ud55c \uc790\uc6d0, \uae30\uc220\uc758 \ub09c\uc774\ub3c4, \uc0ac\uc6a9\ud558\ub294 \ud300\uc6d0\uc744 \uace0\ub824\ud55c\ub2e4\uba74 Lambda\ub294 \uc801\uc815\uae30\uc220\uc774 \uc544\ub2d0 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ud574\ub2f9 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\ub97c \uc5b4\ub5bb\uac8c \uc801\uc6a9\ud560\uc9c0 \uc870\uae08 \ub354 \uace0\ub824\ub97c \ud574\uc57c \ub420 \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\ucd5c\uc885\uc801\uc73c\ub85c Java AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4."})}),"\n",(0,a.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://aws.amazon.com/ko/lambda/",children:"AWS Lambda"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-layers.html",children:"Lambda Layer"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-package.html",children:"Python Lambda \ud568\uc218\uc5d0 \ub300\ud55c .zip \ud30c\uc77c \uc544\uce74\uc774\ube0c \uc791\uc5c5"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://gist.github.com/ksmin23/0f3f243408a8497f766b43cf589fea7b",children:"No module named 'numpy.core._multiarray_umath'"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://techblog.woowahan.com/6217/",children:"\uc0ac\ub840\ubcc4\ub85c \uc54c\uc544\ubcf8 \uc548\uc804\ud55c S3 \uc0ac\uc6a9 \uac00\uc774\ub4dc"})]})]})}function c(e={}){const{wrapper:n}={...(0,i.ah)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>d});var a=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function l(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?r(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):r(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function s(e,n){if(null==e)return{};var t,a,i=function(e,n){if(null==e)return{};var t,a,i={},r=Object.keys(e);for(a=0;a<r.length;a++)t=r[a],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)t=r[a],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var o=a.createContext({}),d=function(e){var n=a.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},p={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},c=a.forwardRef((function(e,n){var t=e.components,i=e.mdxType,r=e.originalType,o=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),m=d(t),x=i,u=m["".concat(o,".").concat(x)]||m[x]||p[x]||r;return t?a.createElement(u,l(l({ref:n},c),{},{components:t})):a.createElement(u,l({ref:n},c))}));c.displayName="MDXCreateElement"},13533:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png"},46365:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/routeImage-0eac25ba9b356cd034ade6e062c1ce19.png"}}]); \ No newline at end of file diff --git a/assets/js/cef46b76.722e08ea.js b/assets/js/cef46b76.722e08ea.js deleted file mode 100644 index e69289577..000000000 --- a/assets/js/cef46b76.722e08ea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8644],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>c});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function p(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var o=a.createContext({}),m=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):p(p({},t),e)),n},u=function(e){var t=m(e.components);return a.createElement(o.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,o=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),d=m(n),c=r,y=d["".concat(o,".").concat(c)]||d[c]||s[c]||l;return n?a.createElement(y,p(p({ref:t},u),{},{components:n})):a.createElement(y,p({ref:t},u))}));function c(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,p=new Array(l);p[0]=d;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i.mdxType="string"==typeof e?e:r,p[1]=i;for(var m=2;m<l;m++)p[m]=n[m];return a.createElement.apply(null,p)}return a.createElement.apply(null,n)}d.displayName="MDXCreateElement"},32390:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>p,default:()=>s,frontMatter:()=>l,metadata:()=>i,toc:()=>m});var a=n(87462),r=(n(67294),n(3905));const l={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",slug:"route-image-python",tags:["Image","Python"]},p=void 0,i={permalink:"/route-image-python",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",source:"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",description:"\uac1c\uc694",date:"2023-07-31T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 31\uc77c",tags:[{label:"Image",permalink:"/tags/image"},{label:"Python",permalink:"/tags/python"}],readingTime:6.185,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c",slug:"route-image-python",tags:["Image","Python"]},prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",permalink:"/route-image-implementation"},nextItem:{title:"Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30",permalink:"/mock-static-method"}},o={authorsImageUrls:[]},m=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\uc0ac\uc6a9 \uae30\uc220",id:"\uc0ac\uc6a9-\uae30\uc220",level:3},{value:"\uc694\uad6c\uc0ac\ud56d",id:"\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd",id:"\uc774\ubbf8\uc9c0-\ucd9c\ub825-\ubc29\uc2dd",level:3},{value:"\ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604",id:"\ub85c\uceec\uc5d0\uc11c-\uae30\ub2a5-\uad6c\ud604",level:3},{value:"AWS Lambda",id:"aws-lambda",level:3},{value:"\ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131",id:"\ub78c\ub2e4-s3-\uc811\uadfc\uc744-\uc704\ud55c-iam-\uc0dd\uc131",level:3},{value:"\ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc",id:"\ub78c\ub2e4-\ubc30\ud3ec\uc6a9-\ucf54\ub4dc",level:3},{value:"Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131",id:"layer-\ucd94\uac00\ub97c-\uc704\ud55c-zip-\ud30c\uc77c-\uc0dd\uc131",level:3},{value:"<code>No module named 'numpy.core._multiarray_umath'</code> \uc5d0\ub7ec",id:"no-module-named-numpycore_multiarray_umath-\uc5d0\ub7ec",level:3},{value:"\uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01",id:"\uc801\uc815\uae30\uc220\uc5d0-\ub300\ud55c-\uc0dd\uac01",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],u={toc:m};function s(e){let{components:t,...l}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,l,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,r.kt)("p",null,"\uc774\uc804\uc5d0 \uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \uc870\uc0ac\ud558\uba74\uc11c \ud30c\uc774\uc36c\uc744 \uc0ac\uc6a9\ud55c \ub0b4\uc6a9\uc744 \uc815\ub9ac\ud55c \ub0b4\uc6a9\uc774\ub2e4. "),(0,r.kt)("h3",{id:"\uc0ac\uc6a9-\uae30\uc220"},"\uc0ac\uc6a9 \uae30\uc220"),(0,r.kt)("p",null,"\uc5b8\uc5b4: Python 3.10",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc0dd\uc131: matplotlib",(0,r.kt)("br",{parentName:"p"}),"\n","\uc11c\ube44\uc2a4: AWS Lambda, AWS API Gateway",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ubbf8\uc9c0 \uc800\uc7a5 \ubc0f URL: AWS S3, AWS CloudFront "),(0,r.kt)("p",null,"\ud50c\ub85c\uc6b0\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n Server -- \uc0dd\uc131 \uc694\uccad --\x3e AG[API Gateway] --\x3e Lambda --\x3e S3\n Client --\x3e CloudFront --\x3e S3"}),(0,r.kt)("h3",{id:"\uc694\uad6c\uc0ac\ud56d"},"\uc694\uad6c\uc0ac\ud56d"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./route.png",src:n(13533).Z,width:"1014",height:"902"})),(0,r.kt)("p",null,"\uc6b0\uce21 \uc0c1\ub2e8\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\ub824\uace0 \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \ub300\ud55c \uc694\uad6c\uc0ac\ud56d\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc704\ub3c4, \uacbd\ub3c4\ub85c \uc774\ub8e8\uc5b4\uc9c4 \ubc30\uc5f4\uc744 \uc785\ub825\ubc1b\ub294\ub2e4. "),(0,r.kt)("li",{parentName:"ul"},"\uc774\ubbf8\uc9c0 \uc0dd\uc131"),(0,r.kt)("li",{parentName:"ul"},"\uc120\uacfc \uc810 \ud45c\ud604"),(0,r.kt)("li",{parentName:"ul"},"\ud22c\uba85\ud55c \ubc30\uacbd\uc0c9"),(0,r.kt)("li",{parentName:"ul"},"\uc704\uacbd\ub3c4 \ucc28\uc774\uac00 \ud06c\ub4e0 \uc791\ub4e0 \uc81c\uacf5\ud558\ub294 \uc774\ubbf8\uc9c0 \ub0b4\uc5d0 \uacbd\ub85c\uac00 \ub2e4 \ud3ec\ud568\ub418\uc5b4 \uc788\uc5b4\uc57c \ud55c\ub2e4. ")),(0,r.kt)("h3",{id:"\uc774\ubbf8\uc9c0-\ucd9c\ub825-\ubc29\uc2dd"},"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"\uc704\uacbd\ub3c4\ub97c \ucc98\ub9ac\ud55c \uac12\uc73c\ub85c \uc9c1\uc811 \uacbd\ub85c\ub97c \uadf8\ub9b0 \ub2e4\uc74c \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5"),(0,r.kt)("li",{parentName:"ol"},"\ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac \uc0ac\uc6a9\ud558\uc5ec \uc774\ubbf8\uc9c0 \ud615\ud0dc\ub85c \uc800\uc7a5")),(0,r.kt)("p",null,"\uc774\ubbf8\uc9c0 \ucd9c\ub825 \ubc29\uc2dd\uc758 \uacbd\uc6b0 1\ubc88\uacfc 2\ubc88\uc744 \uace0\ubbfc\ud588\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud30c\uc774\uc36c\uc73c\ub85c\ub294 \ud50c\ub86f\uc744 \uadf8\ub824\uc8fc\ub294 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc778 matplotlib\uc744 \uc0ac\uc6a9\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\ub85c\uceec\uc5d0\uc11c-\uae30\ub2a5-\uad6c\ud604"},"\ub85c\uceec\uc5d0\uc11c \uae30\ub2a5 \uad6c\ud604"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"import time\n\nimport matplotlib.pyplot as plt\n\n\ndef draw(point):\n start = time.time()\n x, y = zip(*point)\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\n draw_lines(pixel_x, pixel_y)\n end = time.time()\n print(end - start)\n \ndef convert_to_pixel_values(x, y):\n max_diff = max(max(x) - min(x), max(y) - min(y))\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\n\n\ndef scale_to_pixel_values(points, max_diff):\n min_value = min(points)\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\n return scaled_coordinates\n\n\ndef draw_lines(x, y):\n figure = plt.gcf()\n figure.set_size_inches(5, 5)\n plt.plot(x, y, c = 'w',linewidth=5)\n plt.scatter(x[3],y[3], c = 'w', s = 125)\n plt.axis('off')\n plt.savefig('name.png', transparent=True, format='png')\n\npoint = [\n [126.96352960597338, 37.590841000217125],\n [126.96987292787792, 37.58435564234159],\n [126.98128481452298, 37.58594375113966],\n [126.99360339342958, 37.58248524741927],\n [126.99867565340067, 37.56778118088622],\n [127.001935378366117, 37.55985240444085],\n [126.9831048919687, 37.548030119488665],\n [126.97189273528845, 37.5119879225856],\n [127.02689859997221, 37.48488593333883]\n]\n\ndraw(point)\n")),(0,r.kt)("p",null,"\uc0dd\uc131 \uacb0\uacfc\ub294 \uc544\ub798\uc640 \uac19\ub2e4. (\uc608\uc2dc\ub97c \uc704\ud574 \uac80\uc740\uc0c9\uc73c\ub85c \ucd9c\ub825)"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./routeImage.png",src:n(46365).Z,width:"500",height:"500"})),(0,r.kt)("h3",{id:"aws-lambda"},"AWS Lambda"),(0,r.kt)("p",null,"\uc378\ub124\uc77c \uc0dd\uc131 \uc11c\ubc84\ub97c \ub530\ub85c \ub450\uae30\ub294 \uae30\ub2a5 \ub300\ube44 \ube44\uc6a9\uc774 \ub108\ubb34 \ud074 \uac83\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc11c\ubc84\ub9ac\uc2a4\ub85c \ud30c\uc77c\uc744 \ucc98\ub9ac\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c s3 \uc811\uadfc\uc740 boto3\ub97c \uc0ac\uc6a9\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\ub78c\ub2e4-s3-\uc811\uadfc\uc744-\uc704\ud55c-iam-\uc0dd\uc131"},"\ub78c\ub2e4 S3 \uc811\uadfc\uc744 \uc704\ud55c IAM \uc0dd\uc131"),(0,r.kt)("p",null,"AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy \ub450\uac00\uc9c0\ub97c \ucd94\uac00\ud574\uc11c Lambda \uc804\uc6a9 \uc5ed\ud560\uc744 \ub9cc\ub4e4\uc5b4 \uc0ac\uc6a9\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\ub78c\ub2e4-\ubc30\ud3ec\uc6a9-\ucf54\ub4dc"},"\ub78c\ub2e4 \ubc30\ud3ec\uc6a9 \ucf54\ub4dc"),(0,r.kt)("p",null,"\uae30\uc220 \uad6c\ud604 \uac00\ub2a5 \uc5ec\ubd80\ub97c \ud655\uc778\ud560 \ub550 \uc704\uce58 \uc810\uc744 \ucc0d\ub294 \uae30\ub2a5\uc744 \ub78c\ub2e4\uc5d0 \ubc30\ud3ec\ud558\uc9c0 \uc54a\uc558\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-python"},"\nimport io\nimport uuid\n\nimport boto3\nimport matplotlib.pyplot as plt\n\nPIXEL = 255\nBUCKET_NAME = 'image-plot'\nS3 = 's3'\n\ndef lambda_handler(event, context):\n x = event['x']\n y = event['y']\n image_name = str(uuid.uuid4())\n\n img_data = draw(x, y)\n s3 = boto3.client(S3)\n s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)\n url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'\n\n return {\n 'statusCode': 200,\n 'body': url\n }\n\ndef draw(x, y):\n pixel_x, pixel_y = convert_to_pixel_values(x, y)\n img_data = draw_lines(pixel_x, pixel_y)\n plt.close()\n return img_data\n\ndef convert_to_pixel_values(x, y):\n max_diff = max(max(x) - min(x), max(y) - min(y))\n return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)\n\ndef scale_to_pixel_values(points, max_diff):\n min_value = min(points)\n scaled_coordinates = [(p - min_value) / max_diff for p in points]\n pixel_values = [int(p * PIXEL) for p in scaled_coordinates]\n return pixel_values\n\ndef draw_lines(x, y):\n plt.plot(x, y, 'k-', linewidth=10)\n plt.axis('off')\n img_data = io.BytesIO()\n plt.savefig(img_data, transparent=True, format='png')\n img_data.seek(0)\n return img_data\n\n")),(0,r.kt)("h3",{id:"layer-\ucd94\uac00\ub97c-\uc704\ud55c-zip-\ud30c\uc77c-\uc0dd\uc131"},"Layer \ucd94\uac00\ub97c \uc704\ud55c zip \ud30c\uc77c \uc0dd\uc131"),(0,r.kt)("p",null,"matplotlib\uc758 \uacbd\uc6b0 \uc678\ubd80 \ub77c\uc774\ube0c\ub7ec\ub9ac\uae30 \ub54c\ubb38\uc5d0 \ub530\ub85c Layer\ub97c \ucd94\uac00\ud574\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc5b4\uc11c \uc5c5\ub85c\ub4dc\ud574\uc57c\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub54c python\uc758 Lambda \ub7f0\ud0c0\uc784\uc5d0 \ub300\ud55c \uacc4\uce35 \uacbd\ub85c\ub294 python\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc555\ucd95\ud55c zip \ud30c\uc77c\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\ub97c \ub744\uc5b4\uc57c \ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"pillow.zip\n\u2502 python/PIL\n\u2514 python/Pillow-5.3.0.dist-info\n")),(0,r.kt)("p",null,"Ubuntu \uae30\uc900 \ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc0dd\uc131\uc744 \uc9c4\ud589\ud588\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"sudo apt update\nsudo apt install zip\nsudo apt install python3-pip\n\nmkdir python\npip3 install matplotlib -t python # pip3 install \uc124\uce58\ud560_\ud328\ud0a4\uc9c0 -t \uc124\uce58_\uacbd\ub85c\nzip -r my_layer.zip python # zip -r \uc555\ucd95_\ud30c\uc77c\uba85 \uc555\ucd95_\ud30c\uc77c\uc774_\uc874\uc7ac\ud558\ub294_\uacbd\ub85c\n")),(0,r.kt)("h3",{id:"no-module-named-numpycore_multiarray_umath-\uc5d0\ub7ec"},(0,r.kt)("inlineCode",{parentName:"h3"},"No module named 'numpy.core._multiarray_umath'")," \uc5d0\ub7ec"),(0,r.kt)("p",null,"Layer \ucd94\uac00 \ud6c4 \ub78c\ub2e4 \uc2e4\ud589 \uc2dc \ubc1c\uc0dd\ud55c \uc5d0\ub7ec\uc600\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucc98\uc74c\uc5d0 mac\uc5d0\uc11c zip \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \uc5c5\ub85c\ub4dc\ud588\ub294\ub370 \ud574\ub2f9 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 lambda\uac00 \ub3cc\uc544\uac00\ub294 \ub3d9\uc77c\ud55c \ud658\uacbd\uc5d0\uc11c layer\ub97c \uc704\ud55c zip \ud30c\uc77c\uc744 \ub9cc\ub4e4\uc9c0 \uc54a\uc544\uc11c \ubc1c\uc0dd\ud558\ub294 \ubb38\uc81c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud558\uac8c ec2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c \ub530\ub85c Layer\ub97c \uc0dd\uc131\ud558\uba74 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uc9c0 \uc54a\ub294\ub2e4. "),(0,r.kt)("h3",{id:"\uc801\uc815\uae30\uc220\uc5d0-\ub300\ud55c-\uc0dd\uac01"},"\uc801\uc815\uae30\uc220\uc5d0 \ub300\ud55c \uc0dd\uac01"),(0,r.kt)("p",null,"\ud504\ub85c\uc81d\ud2b8\uc5d0 Lambda\uc640 Python\uc744 \uc0ac\uc6a9\ud558\ub824\uace0 \ud588\uc9c0\ub9cc \uc544\uc27d\uac8c\ub3c4 \ubc18\ub824\ub2f9\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","AWS Lambda\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc778\uc2a4\ud134\uc2a4\uc5d0 \ud574\ub2f9 \ucf54\ub4dc\ub97c \ubc30\ud3ec\ud558\ub294 \uac83\ubcf4\ub2e4 \ub354 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc77c \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ud604\uc7ac \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uac00\uc6a9 \uac00\ub2a5\ud55c \uc790\uc6d0, \uae30\uc220\uc758 \ub09c\uc774\ub3c4, \uc0ac\uc6a9\ud558\ub294 \ud300\uc6d0\uc744 \uace0\ub824\ud55c\ub2e4\uba74 Lambda\ub294 \uc801\uc815\uae30\uc220\uc774 \uc544\ub2d0 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ud574\ub2f9 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\ub97c \uc5b4\ub5bb\uac8c \uc801\uc6a9\ud560\uc9c0 \uc870\uae08 \ub354 \uace0\ub824\ub97c \ud574\uc57c \ub420 \uac83\uc73c\ub85c \ubcf4\uc778\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\ucd5c\uc885\uc801\uc73c\ub85c Java AWT\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \uacb0\uc815\ud588\ub2e4.")),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/lambda/"},"AWS Lambda"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-layers.html"},"Lambda Layer"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-package.html"},"Python Lambda \ud568\uc218\uc5d0 \ub300\ud55c .zip \ud30c\uc77c \uc544\uce74\uc774\ube0c \uc791\uc5c5"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://gist.github.com/ksmin23/0f3f243408a8497f766b43cf589fea7b"},"No module named 'numpy.core._multiarray_umath'"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/6217/"},"\uc0ac\ub840\ubcc4\ub85c \uc54c\uc544\ubcf8 \uc548\uc804\ud55c S3 \uc0ac\uc6a9 \uac00\uc774\ub4dc")))}s.isMDXComponent=!0},13533:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png"},46365:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/routeImage-0eac25ba9b356cd034ade6e062c1ce19.png"}}]); \ No newline at end of file diff --git a/assets/js/cf8e491a.20189b57.js b/assets/js/cf8e491a.464ac15a.js similarity index 59% rename from assets/js/cf8e491a.20189b57.js rename to assets/js/cf8e491a.464ac15a.js index 8de855721..26b1bbfc4 100644 --- a/assets/js/cf8e491a.20189b57.js +++ b/assets/js/cf8e491a.464ac15a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5870],{19799:e=>{e.exports=JSON.parse('{"label":"awt","permalink":"/tags/awt","allTagsPath":"/tags","count":2}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5870],{19799:e=>{e.exports=JSON.parse('{"label":"awt","permalink":"/tags/awt","allTagsPath":"/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/d0840b01.850cded6.js b/assets/js/d0840b01.30f98a8b.js similarity index 55% rename from assets/js/d0840b01.850cded6.js rename to assets/js/d0840b01.30f98a8b.js index 678c4c9ce..73a7e288c 100644 --- a/assets/js/d0840b01.850cded6.js +++ b/assets/js/d0840b01.30f98a8b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8037],{20317:a=>{a.exports=JSON.parse('{"label":"Transaction","permalink":"/tags/transaction","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8037],{20317:s=>{s.exports=JSON.parse('{"label":"Transaction","permalink":"/tags/transaction","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/d1e1bea4.03ce7300.js b/assets/js/d1e1bea4.03ce7300.js deleted file mode 100644 index e3fe5acc0..000000000 --- a/assets/js/d1e1bea4.03ce7300.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7945],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),p=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),d=p(r),m=a,f=d["".concat(i,".").concat(m)]||d[m]||s[m]||o;return r?n.createElement(f,l(l({ref:t},u),{},{components:r})):n.createElement(f,l({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,l=new Array(o);l[0]=d;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c.mdxType="string"==typeof e?e:a,l[1]=c;for(var p=2;p<o;p++)l[p]=r[p];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},98120:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>s,frontMatter:()=>o,metadata:()=>c,toc:()=>p});var n=r(87462),a=(r(67294),r(3905));const o={title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",slug:"/mac/java",last_update:{date:"2023/09/20"}},l=void 0,c={unversionedId:"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",id:"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",description:"\uc124\uce58\ub41c \uc790\ubc14 \ubc84\uc804 \ud655\uc778",source:"@site/docs/MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd.md",sourceDirName:"MAC",slug:"/mac/java",permalink:"/docs/mac/java",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd.md",tags:[],version:"current",lastUpdatedAt:1695168e3,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 20\uc77c",frontMatter:{title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",slug:"/mac/java",last_update:{date:"2023/09/20"}},sidebar:"tutorialSidebar",previous:{title:"SequencedCollection",permalink:"/docs/java/sequenced-collection"},next:{title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",permalink:"/docs/nginx/command"}},i={},p=[{value:"\uc124\uce58\ub41c \uc790\ubc14 \ubc84\uc804 \ud655\uc778",id:"\uc124\uce58\ub41c-\uc790\ubc14-\ubc84\uc804-\ud655\uc778",level:3},{value:"\uc790\ubc14 \uc124\uce58",id:"\uc790\ubc14-\uc124\uce58",level:3},{value:"\uc790\ubc14 11 \ubc84\uc804\uc73c\ub85c \ubcc0\uacbd",id:"\uc790\ubc14-11-\ubc84\uc804\uc73c\ub85c-\ubcc0\uacbd",level:3},{value:"\ud130\ubbf8\ub110 \uc7ac\uc2dc\uc791\uc2dc\uc5d0\ub3c4 \uc790\ubc14 \ubc84\uc804 \uc720\uc9c0",id:"\ud130\ubbf8\ub110-\uc7ac\uc2dc\uc791\uc2dc\uc5d0\ub3c4-\uc790\ubc14-\ubc84\uc804-\uc720\uc9c0",level:3}],u={toc:p};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uc124\uce58\ub41c-\uc790\ubc14-\ubc84\uc804-\ud655\uc778"},"\uc124\uce58\ub41c \uc790\ubc14 \ubc84\uc804 \ud655\uc778"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"/usr/libexec/java_home -V\n")),(0,a.kt)("h3",{id:"\uc790\ubc14-\uc124\uce58"},"\uc790\ubc14 \uc124\uce58"),(0,a.kt)("p",null,"brew\ub97c \ucd5c\uc2e0 \ubc84\uc804\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8\ud558\uace0 jdk\ub97c \uac80\uc0c9\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"brew update\nbrew search jdk\n")),(0,a.kt)("p",null,"\ud544\uc694\ud55c \ubc84\uc804\uc744 \uc120\ud0dd\ud558\uc5ec \uc124\uce58\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"brew install openjdk@11\n")),(0,a.kt)("h3",{id:"\uc790\ubc14-11-\ubc84\uc804\uc73c\ub85c-\ubcc0\uacbd"},"\uc790\ubc14 11 \ubc84\uc804\uc73c\ub85c \ubcc0\uacbd"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre"},"export JAVA_HOME=$(/usr/libexec/java_home -v 11)\n")),(0,a.kt)("h3",{id:"\ud130\ubbf8\ub110-\uc7ac\uc2dc\uc791\uc2dc\uc5d0\ub3c4-\uc790\ubc14-\ubc84\uc804-\uc720\uc9c0"},"\ud130\ubbf8\ub110 \uc7ac\uc2dc\uc791\uc2dc\uc5d0\ub3c4 \uc790\ubc14 \ubc84\uc804 \uc720\uc9c0"),(0,a.kt)("p",null,"~/.zshrc \ud30c\uc77c \uc544\ub798 JAVA_HOME \ud658\uacbd\ubcc0\uc218 \uc124\uc815 \uba85\ub839\uc5b4\ub97c \ucd94\uac00\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh",metastring:"title=~/.zshrc",title:"~/.zshrc"},"export JAVA_HOME=$(/usr/libexec/java_home -v 11)\n")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d1e1bea4.5c79d869.js b/assets/js/d1e1bea4.5c79d869.js new file mode 100644 index 000000000..c4196e0d4 --- /dev/null +++ b/assets/js/d1e1bea4.5c79d869.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7945],{32228:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>a,metadata:()=>o,toc:()=>s});var n=r(85893),c=r(3905);const a={title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",slug:"/mac/java",last_update:{date:"2023/09/20"}},i=void 0,o={id:"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",description:"\uc124\uce58\ub41c \uc790\ubc14 \ubc84\uc804 \ud655\uc778",source:"@site/docs/MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd.md",sourceDirName:"MAC",slug:"/mac/java",permalink:"/docs/mac/java",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd.md",tags:[],version:"current",lastUpdatedAt:1695168e3,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 20\uc77c",frontMatter:{title:"\ub9e5 OS \uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd",slug:"/mac/java",last_update:{date:"2023/09/20"}},sidebar:"tutorialSidebar",previous:{title:"SequencedCollection",permalink:"/docs/java/sequenced-collection"},next:{title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",permalink:"/docs/nginx/command"}},l={},s=[{value:"\uc124\uce58\ub41c \uc790\ubc14 \ubc84\uc804 \ud655\uc778",id:"\uc124\uce58\ub41c-\uc790\ubc14-\ubc84\uc804-\ud655\uc778",level:3},{value:"\uc790\ubc14 \uc124\uce58",id:"\uc790\ubc14-\uc124\uce58",level:3},{value:"\uc790\ubc14 11 \ubc84\uc804\uc73c\ub85c \ubcc0\uacbd",id:"\uc790\ubc14-11-\ubc84\uc804\uc73c\ub85c-\ubcc0\uacbd",level:3},{value:"\ud130\ubbf8\ub110 \uc7ac\uc2dc\uc791\uc2dc\uc5d0\ub3c4 \uc790\ubc14 \ubc84\uc804 \uc720\uc9c0",id:"\ud130\ubbf8\ub110-\uc7ac\uc2dc\uc791\uc2dc\uc5d0\ub3c4-\uc790\ubc14-\ubc84\uc804-\uc720\uc9c0",level:3}];function d(e){const t={code:"code",h3:"h3",p:"p",pre:"pre",...(0,c.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uc124\uce58\ub41c-\uc790\ubc14-\ubc84\uc804-\ud655\uc778",children:"\uc124\uce58\ub41c \uc790\ubc14 \ubc84\uc804 \ud655\uc778"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"/usr/libexec/java_home -V\n"})}),"\n",(0,n.jsx)(t.h3,{id:"\uc790\ubc14-\uc124\uce58",children:"\uc790\ubc14 \uc124\uce58"}),"\n",(0,n.jsx)(t.p,{children:"brew\ub97c \ucd5c\uc2e0 \ubc84\uc804\uc73c\ub85c \uc5c5\ub370\uc774\ud2b8\ud558\uace0 jdk\ub97c \uac80\uc0c9\ud55c\ub2e4."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"brew update\nbrew search jdk\n"})}),"\n",(0,n.jsx)(t.p,{children:"\ud544\uc694\ud55c \ubc84\uc804\uc744 \uc120\ud0dd\ud558\uc5ec \uc124\uce58\ud55c\ub2e4."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"brew install openjdk@11\n"})}),"\n",(0,n.jsx)(t.h3,{id:"\uc790\ubc14-11-\ubc84\uc804\uc73c\ub85c-\ubcc0\uacbd",children:"\uc790\ubc14 11 \ubc84\uc804\uc73c\ub85c \ubcc0\uacbd"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"export JAVA_HOME=$(/usr/libexec/java_home -v 11)\n"})}),"\n",(0,n.jsx)(t.h3,{id:"\ud130\ubbf8\ub110-\uc7ac\uc2dc\uc791\uc2dc\uc5d0\ub3c4-\uc790\ubc14-\ubc84\uc804-\uc720\uc9c0",children:"\ud130\ubbf8\ub110 \uc7ac\uc2dc\uc791\uc2dc\uc5d0\ub3c4 \uc790\ubc14 \ubc84\uc804 \uc720\uc9c0"}),"\n",(0,n.jsx)(t.p,{children:"~/.zshrc \ud30c\uc77c \uc544\ub798 JAVA_HOME \ud658\uacbd\ubcc0\uc218 \uc124\uc815 \uba85\ub839\uc5b4\ub97c \ucd94\uac00\ud55c\ub2e4."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-sh",metastring:"title=~/.zshrc",children:"export JAVA_HOME=$(/usr/libexec/java_home -v 11)\n"})})]})}function p(e={}){const{wrapper:t}={...(0,c.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>s});var n=r(67294);function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){c(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,c=function(e,t){if(null==e)return{};var r,n,c={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(c[r]=e[r]);return c}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var l=n.createContext({}),s=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,c=e.mdxType,a=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=s(r),h=c,j=u["".concat(l,".").concat(h)]||u[h]||d[h]||a;return r?n.createElement(j,i(i({ref:t},p),{},{components:r})):n.createElement(j,i({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/d2770bf7.15235f36.js b/assets/js/d2770bf7.b1baa87f.js similarity index 77% rename from assets/js/d2770bf7.15235f36.js rename to assets/js/d2770bf7.b1baa87f.js index 9591d9b3e..9f10c587c 100644 --- a/assets/js/d2770bf7.15235f36.js +++ b/assets/js/d2770bf7.b1baa87f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[843],{41156:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[843],{41156:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/d28e30d7.1e157fc3.js b/assets/js/d28e30d7.1e157fc3.js deleted file mode 100644 index 2512f4d75..000000000 --- a/assets/js/d28e30d7.1e157fc3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6671],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var l=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);t&&(l=l.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,l)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function u(e,t){if(null==e)return{};var n,l,a=function(e,t){if(null==e)return{};var n,l,a={},r=Object.keys(e);for(l=0;l<r.length;l++)n=r[l],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(l=0;l<r.length;l++)n=r[l],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=l.createContext({}),s=function(e){var t=l.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},c=function(e){var t=s(e.components);return l.createElement(i.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return l.createElement(l.Fragment,{},t)}},d=l.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,i=e.parentName,c=u(e,["components","mdxType","originalType","parentName"]),d=s(n),m=a,f=d["".concat(i,".").concat(m)]||d[m]||p[m]||r;return n?l.createElement(f,o(o({ref:t},c),{},{components:n})):l.createElement(f,o({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,o=new Array(r);o[0]=d;var u={};for(var i in t)hasOwnProperty.call(t,i)&&(u[i]=t[i]);u.originalType=e,u.mdxType="string"==typeof e?e:a,o[1]=u;for(var s=2;s<r;s++)o[s]=n[s];return l.createElement.apply(null,o)}return l.createElement.apply(null,n)}d.displayName="MDXCreateElement"},85162:(e,t,n)=>{n.d(t,{Z:()=>o});var l=n(67294),a=n(86010);const r="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return l.createElement("div",{role:"tabpanel",className:(0,a.Z)(r,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>w});var l=n(87462),a=n(67294),r=n(86010),o=n(12466),u=n(16550),i=n(91980),s=n(67392),c=n(50012);function p(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:l,default:a}}=e;return{value:t,label:n,attributes:l,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??p(n);return function(e){const t=(0,s.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function f(e){let{queryString:t=!1,groupId:n}=e;const l=(0,u.k6)(),r=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,i._X)(r),(0,a.useCallback)((e=>{if(!r)return;const t=new URLSearchParams(l.location.search);t.set(r,e),l.replace({...l.location,search:t.toString()})}),[r,l])]}function b(e){const{defaultValue:t,queryString:n=!1,groupId:l}=e,r=d(e),[o,u]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const l=n.find((e=>e.default))??n[0];if(!l)throw new Error("Unexpected error: 0 tabValues");return l.value}({defaultValue:t,tabValues:r}))),[i,s]=f({queryString:n,groupId:l}),[p,b]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[l,r]=(0,c.Nk)(n);return[l,(0,a.useCallback)((e=>{n&&r.set(e)}),[n,r])]}({groupId:l}),k=(()=>{const e=i??p;return m({value:e,tabValues:r})?e:null})();(0,a.useLayoutEffect)((()=>{k&&u(k)}),[k]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:r}))throw new Error(`Can't select invalid tab value=${e}`);u(e),s(e),b(e)}),[s,b,r]),tabValues:r}}var k=n(72389);const g="tabList__CuJ",v="tabItem_LNqP";function h(e){let{className:t,block:n,selectedValue:u,selectValue:i,tabValues:s}=e;const c=[],{blockElementScrollPositionUntilNextRender:p}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=c.indexOf(t),l=s[n].value;l!==u&&(p(t),i(l))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=c.indexOf(e.currentTarget)+1;t=c[n]??c[0];break}case"ArrowLeft":{const n=c.indexOf(e.currentTarget)-1;t=c[n]??c[c.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.Z)("tabs",{"tabs--block":n},t)},s.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,l.Z)({role:"tab",tabIndex:u===t?0:-1,"aria-selected":u===t,key:t,ref:e=>c.push(e),onKeyDown:m,onClick:d},o,{className:(0,r.Z)("tabs__item",v,o?.className,{"tabs__item--active":u===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:l}=e;const r=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=r.find((e=>e.props.value===l));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},r.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==l}))))}function N(e){const t=b(e);return a.createElement("div",{className:(0,r.Z)("tabs-container",g)},a.createElement(h,(0,l.Z)({},e,t)),a.createElement(y,(0,l.Z)({},e,t)))}function w(e){const t=(0,k.Z)();return a.createElement(N,(0,l.Z)({key:String(t)},e))}},27464:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>m,frontMatter:()=>u,metadata:()=>s,toc:()=>p});var l=n(87462),a=(n(67294),n(3905)),r=n(74866),o=n(85162);const u={title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",slug:"kotlin-null",tags:["Kotlin"]},i=void 0,s={permalink:"/kotlin-null",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",source:"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",description:"nullable \ud0c0\uc785",date:"2023-01-16T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 16\uc77c",tags:[{label:"Kotlin",permalink:"/tags/kotlin"}],readingTime:4.225,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",slug:"kotlin-null",tags:["Kotlin"]},prevItem:{title:"IntelliJ \uc124\uc815",permalink:"/intellij-settings"},nextItem:{title:"JSR-310",permalink:"/jsr-310"}},c={authorsImageUrls:[]},p=[{value:"nullable \ud0c0\uc785",id:"nullable-\ud0c0\uc785",level:3},{value:"<code>?.</code> Safe Calls \uc5f0\uc0b0\uc790",id:"-safe-calls-\uc5f0\uc0b0\uc790",level:3},{value:"<code>?:</code> \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790",id:"-\uc5d8\ube44\uc2a4-\uc5f0\uc0b0\uc790",level:3},{value:"<code>!!</code> \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790",id:"-\ub110-\uc544\ub2d8-\ub2e8\uc5b8-\uc5f0\uc0b0\uc790",level:3},{value:"<code>as?</code> \uc548\uc804\ud55c \uce90\uc2a4\ud305",id:"as-\uc548\uc804\ud55c-\uce90\uc2a4\ud305",level:3},{value:"List\uc5d0\uc11c\uc758 null \ucc98\ub9ac",id:"list\uc5d0\uc11c\uc758-null-\ucc98\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],d={toc:p};function m(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,l.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"nullable-\ud0c0\uc785"},"nullable \ud0c0\uc785"),(0,a.kt)("p",null,"\ucf54\ud2c0\ub9b0\uc740 ",(0,a.kt)("inlineCode",{parentName:"p"},"NullPointerException")," \uc608\uc678\ub97c \ucd5c\ub300\ud55c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 \ud0c0\uc785 \uc2dc\uc2a4\ud15c\uc774 \uc124\uacc4\ub418\uc5b4 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 \uc2e4\ud589 \uc2dc\uc810\uc774 \uc544\ub2cc \ucef4\ud30c\uc77c \uc2dc \ubbf8\ub9ac \uc624\ub958\uac00 \ubc1c\uc0dd\ud560 \uac00\ub2a5\uc131\uc774 \uc788\ub294 \ubd80\ubd84\uc744 \ubbf8\ub9ac \uac10\uc9c0\ud558\uc5ec NPE \ubc1c\uc0dd\uc758 \uac00\ub2a5\uc131\uc744 \uc904\uc5ec\uc900\ub2e4."),(0,a.kt)("p",null,"\ucf54\ud2c0\ub9b0\uc758 \uacbd\uc6b0 nullable \ud0c0\uc785\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \ud45c\ud604\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"val number: Int?\n")),(0,a.kt)("p",null,"\ud0c0\uc785 \ub4a4\uc5d0 ",(0,a.kt)("inlineCode",{parentName:"p"},"?"),"\ub97c \ubd99\uc5ec \ud574\ub2f9 \uac12\uc774 null\uc774 \ub420 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9cc\uc57d ",(0,a.kt)("inlineCode",{parentName:"p"},"?"),"\ub97c \ubd99\uc774\uc9c0 \uc54a\uc744 \ub54c null\uc744 \ubc1b\ub294 \uacbd\uc6b0 \ucef4\ud30c\uc77c \uc2dc \uc624\ub958\uac00 \ubc1c\uc0dd\ud55c\ub2e4."),(0,a.kt)("h3",{id:"-safe-calls-\uc5f0\uc0b0\uc790"},(0,a.kt)("inlineCode",{parentName:"h3"},"?.")," Safe Calls \uc5f0\uc0b0\uc790"),(0,a.kt)("p",null,"\uc790\ubc14\uc5d0\uc11c NPE\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 null\uc744 \ucc98\ub9ac\ud558\ub294 \uac00\uc7a5 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c\ub294 \ubd84\uae30\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4."),(0,a.kt)("p",null,"\ucf54\ud2c0\ub9b0\uc740 \uc548\uc804\ud55c \ud638\ucd9c \uc5f0\uc0b0\uc790\uc778 ",(0,a.kt)("inlineCode",{parentName:"p"},"?.")," \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ucc38\uc870 \uac12\uc774 null\uc774 \uc544\ub2d0 \uacbd\uc6b0\uc5d0\ub9cc \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucc38\uc870 \uac12\uc774 null\uc778 \uacbd\uc6b0 \uba54\uc11c\ub4dc \ud638\ucd9c\uc774 \ubb34\uc2dc\ub418\uace0, null\uc744 \ubc18\ud658\ud55c\ub2e4. "),(0,a.kt)(r.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Java",label:"Java",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public String repeat(String word) {\n if (word == null) {\n return null;\n }\n return word.repeat(2);\n}\n"))),(0,a.kt)(o.Z,{value:"Kotlin",label:"Kotlin",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"fun repeat(word: String?): String? {\n return word?.repeat(2)\n}\n")))),(0,a.kt)("h3",{id:"-\uc5d8\ube44\uc2a4-\uc5f0\uc0b0\uc790"},(0,a.kt)("inlineCode",{parentName:"h3"},"?:")," \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790"),(0,a.kt)("p",null,"\ucc38\uc870\ud558\ub824\ub294 \uac12\uc774 null\uc77c \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud558\uace0 \uc2f6\uc744 \ub54c\ub294 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\ucf54\ud2c0\ub9b0\uc740 null\uc774 \uc544\ub2cc \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \ub54c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4."),(0,a.kt)(r.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"Java",label:"Java",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public String stringSafe(String word) {\n if (word == null) {\n return "";\n }\n return word;\n}\n'))),(0,a.kt)(o.Z,{value:"Kotlin",label:"Kotlin",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'fun stringSafe(word: String?): String {\n return word ?: ""\n}\n')))),(0,a.kt)("p",null,"\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 throw\ub3c4 \uc2dd\uc774\uae30 \ub54c\ubb38\uc5d0 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\ub97c \ub4e4\uc5b4 \uc0ac\uc6a9\uc790 \uc815\ubcf4\uac00 \uc788\ub294 \uc800\uc7a5\uc18c\uc5d0 \ucc3e\ub294 \uc0ac\uc6a9\uc790\uac00 \uc5c6\ub294 \uacbd\uc6b0 \uc544\ub798\uc640 \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"userRepository.findByName(name) ?: throw IllegalArgumentException()\n")),(0,a.kt)("h3",{id:"-\ub110-\uc544\ub2d8-\ub2e8\uc5b8-\uc5f0\uc0b0\uc790"},(0,a.kt)("inlineCode",{parentName:"h3"},"!!")," \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790"),(0,a.kt)("p",null,"!! \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud55c\ub2e4\uba74 \uac15\uc81c\ub85c \uc5b4\ub5a4 \uac12\uc774\ub4e0 non-nullable \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc null\uc778 \uac12\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4\uba74 NPE\uac00 \ubc1c\uc0dd\ud558\uac8c \ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ubc18\uc801\uc778 \uacbd\uc6b0\uc5d0\ub294 !! \uc5f0\uc0b0\uc790\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc704\ud5d8\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc6a9\ud558\uae30 \uc27d\uc9c0\ub9cc, \ub9ac\uc2a4\ud06c\uac00 \ud06c\uace0 \ud639\uc2dc\ub098 \ud574\ub2f9 \uac12\uc774 \ucd94\ud6c4\uc5d0\ub294 null\uc774 \ub420 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc591\ud574\uc57c \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"val length: Int = word!!.length\n")),(0,a.kt)("h3",{id:"as-\uc548\uc804\ud55c-\uce90\uc2a4\ud305"},(0,a.kt)("inlineCode",{parentName:"h3"},"as?")," \uc548\uc804\ud55c \uce90\uc2a4\ud305"),(0,a.kt)("p",null,"\ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \ub54c \uc9c0\uc815\ud55c \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc5c6\ub2e4\uba74 ",(0,a.kt)("inlineCode",{parentName:"p"},"ClassCastException"),"\uc774 \ubc1c\uc0dd\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 as \ub4a4\uc5d0 ?\ub97c \ubd99\uc5ec \uc548\uc804\ud558\uac8c \ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ubbf8\ub9ac \ubcc0\ud658 \uac00\ub2a5\ud55c \ud0c0\uc785\uc778\uc9c0 \ud655\uc778\ud558\uc9c0 \uc54a\uace0, \uc548\uc804\ud558\uac8c \ud0c0\uc785\uc744 \ubcc0\ud658 \ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("p",null,"\ud0c0\uc785 \ubcc0\ud658\uc774 \ubd88\uac00\ub2a5 \ud560 \uacbd\uc6b0 \uc608\uc678\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uace0 null\uc744 \ubc18\ud658\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},"val value: Int? = something as? Int\n")),(0,a.kt)("h3",{id:"list\uc5d0\uc11c\uc758-null-\ucc98\ub9ac"},"List\uc5d0\uc11c\uc758 null \ucc98\ub9ac"),(0,a.kt)("p",null,"List\uc5d0\ub294 null\uc774 \uc544\ub2cc \uac12\ub9cc \ubc18\ud658\ud558\ub294 ",(0,a.kt)("inlineCode",{parentName:"p"},"filterNotNull")," \uc720\ud2f8\ub9ac\ud2f0 \uba54\uc11c\ub4dc\ub97c \uc81c\uacf5\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-kotlin"},'val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")\nval foods = foodsWithNull.filterNotNull()\n')),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://product.kyobobook.co.kr/detail/S000001804588"},"Kotlin in Action")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://product.kyobobook.co.kr/detail/S000001033129"},"Effective Kotlin Item 8")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://www.baeldung.com/kotlin/null-safety"},"Comprehensive Guide to Null Safety in Kotlin")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"https://kotlinlang.org/docs/null-safety.html"},"Kotlin NullSafety"))))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d28e30d7.489aca7d.js b/assets/js/d28e30d7.489aca7d.js new file mode 100644 index 000000000..507ef1812 --- /dev/null +++ b/assets/js/d28e30d7.489aca7d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6671],{70633:(e,n,l)=>{l.r(n),l.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>u,toc:()=>d});var r=l(85893),t=l(3905),a=l(74866),s=l(85162);const i={title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",slug:"kotlin-null",tags:["Kotlin"]},o=void 0,u={permalink:"/kotlin-null",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",source:"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",description:"nullable \ud0c0\uc785",date:"2023-01-16T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 16\uc77c",tags:[{label:"Kotlin",permalink:"/tags/kotlin"}],readingTime:4.225,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95",slug:"kotlin-null",tags:["Kotlin"]},unlisted:!1,prevItem:{title:"IntelliJ \uc124\uc815",permalink:"/intellij-settings"},nextItem:{title:"JSR-310",permalink:"/jsr-310"}},c={authorsImageUrls:[]},d=[{value:"nullable \ud0c0\uc785",id:"nullable-\ud0c0\uc785",level:3},{value:"<code>?.</code> Safe Calls \uc5f0\uc0b0\uc790",id:"-safe-calls-\uc5f0\uc0b0\uc790",level:3},{value:"<code>?:</code> \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790",id:"-\uc5d8\ube44\uc2a4-\uc5f0\uc0b0\uc790",level:3},{value:"<code>!!</code> \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790",id:"-\ub110-\uc544\ub2d8-\ub2e8\uc5b8-\uc5f0\uc0b0\uc790",level:3},{value:"<code>as?</code> \uc548\uc804\ud55c \uce90\uc2a4\ud305",id:"as-\uc548\uc804\ud55c-\uce90\uc2a4\ud305",level:3},{value:"List\uc5d0\uc11c\uc758 null \ucc98\ub9ac",id:"list\uc5d0\uc11c\uc758-null-\ucc98\ub9ac",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function h(e){const n={a:"a",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"nullable-\ud0c0\uc785",children:"nullable \ud0c0\uc785"}),"\n",(0,r.jsxs)(n.p,{children:["\ucf54\ud2c0\ub9b0\uc740 ",(0,r.jsx)(n.code,{children:"NullPointerException"})," \uc608\uc678\ub97c \ucd5c\ub300\ud55c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 \ud0c0\uc785 \uc2dc\uc2a4\ud15c\uc774 \uc124\uacc4\ub418\uc5b4 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ub294 \uc2e4\ud589 \uc2dc\uc810\uc774 \uc544\ub2cc \ucef4\ud30c\uc77c \uc2dc \ubbf8\ub9ac \uc624\ub958\uac00 \ubc1c\uc0dd\ud560 \uac00\ub2a5\uc131\uc774 \uc788\ub294 \ubd80\ubd84\uc744 \ubbf8\ub9ac \uac10\uc9c0\ud558\uc5ec NPE \ubc1c\uc0dd\uc758 \uac00\ub2a5\uc131\uc744 \uc904\uc5ec\uc900\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\ucf54\ud2c0\ub9b0\uc758 \uacbd\uc6b0 nullable \ud0c0\uc785\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \ud45c\ud604\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"val number: Int?\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\ud0c0\uc785 \ub4a4\uc5d0 ",(0,r.jsx)(n.code,{children:"?"}),"\ub97c \ubd99\uc5ec \ud574\ub2f9 \uac12\uc774 null\uc774 \ub420 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub9cc\uc57d ",(0,r.jsx)(n.code,{children:"?"}),"\ub97c \ubd99\uc774\uc9c0 \uc54a\uc744 \ub54c null\uc744 \ubc1b\ub294 \uacbd\uc6b0 \ucef4\ud30c\uc77c \uc2dc \uc624\ub958\uac00 \ubc1c\uc0dd\ud55c\ub2e4."]}),"\n",(0,r.jsxs)(n.h3,{id:"-safe-calls-\uc5f0\uc0b0\uc790",children:[(0,r.jsx)(n.code,{children:"?."})," Safe Calls \uc5f0\uc0b0\uc790"]}),"\n",(0,r.jsx)(n.p,{children:"\uc790\ubc14\uc5d0\uc11c NPE\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uae30 \uc704\ud574 null\uc744 \ucc98\ub9ac\ud558\ub294 \uac00\uc7a5 \uac04\ub2e8\ud55c \ubc29\ubc95\uc73c\ub85c\ub294 \ubd84\uae30\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4."}),"\n",(0,r.jsxs)(n.p,{children:["\ucf54\ud2c0\ub9b0\uc740 \uc548\uc804\ud55c \ud638\ucd9c \uc5f0\uc0b0\uc790\uc778 ",(0,r.jsx)(n.code,{children:"?."})," \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ucc38\uc870 \uac12\uc774 null\uc774 \uc544\ub2d0 \uacbd\uc6b0\uc5d0\ub9cc \uba54\uc11c\ub4dc \ud638\ucd9c\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucc38\uc870 \uac12\uc774 null\uc778 \uacbd\uc6b0 \uba54\uc11c\ub4dc \ud638\ucd9c\uc774 \ubb34\uc2dc\ub418\uace0, null\uc744 \ubc18\ud658\ud55c\ub2e4."]}),"\n",(0,r.jsxs)(a.Z,{children:[(0,r.jsx)(s.Z,{value:"Java",label:"Java",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public String repeat(String word) {\n if (word == null) {\n return null;\n }\n return word.repeat(2);\n}\n"})})}),(0,r.jsx)(s.Z,{value:"Kotlin",label:"Kotlin",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"fun repeat(word: String?): String? {\n return word?.repeat(2)\n}\n"})})})]}),"\n",(0,r.jsxs)(n.h3,{id:"-\uc5d8\ube44\uc2a4-\uc5f0\uc0b0\uc790",children:[(0,r.jsx)(n.code,{children:"?:"})," \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790"]}),"\n",(0,r.jsxs)(n.p,{children:["\ucc38\uc870\ud558\ub824\ub294 \uac12\uc774 null\uc77c \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \ubc18\ud658\ud558\uace0 \uc2f6\uc744 \ub54c\ub294 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?",(0,r.jsx)(n.br,{}),"\n","\ucf54\ud2c0\ub9b0\uc740 null\uc774 \uc544\ub2cc \uacbd\uc6b0 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \ub54c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc9c0\uc6d0\ud55c\ub2e4."]}),"\n",(0,r.jsxs)(a.Z,{children:[(0,r.jsx)(s.Z,{value:"Java",label:"Java",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public String stringSafe(String word) {\n if (word == null) {\n return "";\n }\n return word;\n}\n'})})}),(0,r.jsx)(s.Z,{value:"Kotlin",label:"Kotlin",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:'fun stringSafe(word: String?): String {\n return word ?: ""\n}\n'})})})]}),"\n",(0,r.jsxs)(n.p,{children:["\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 throw\ub3c4 \uc2dd\uc774\uae30 \ub54c\ubb38\uc5d0 \uc5d8\ube44\uc2a4 \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uc608\uc678\ub97c \ub358\uc9c8 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc608\ub97c \ub4e4\uc5b4 \uc0ac\uc6a9\uc790 \uc815\ubcf4\uac00 \uc788\ub294 \uc800\uc7a5\uc18c\uc5d0 \ucc3e\ub294 \uc0ac\uc6a9\uc790\uac00 \uc5c6\ub294 \uacbd\uc6b0 \uc544\ub798\uc640 \uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"userRepository.findByName(name) ?: throw IllegalArgumentException()\n"})}),"\n",(0,r.jsxs)(n.h3,{id:"-\ub110-\uc544\ub2d8-\ub2e8\uc5b8-\uc5f0\uc0b0\uc790",children:[(0,r.jsx)(n.code,{children:"!!"})," \ub110 \uc544\ub2d8 \ub2e8\uc5b8 \uc5f0\uc0b0\uc790"]}),"\n",(0,r.jsxs)(n.p,{children:["!! \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud55c\ub2e4\uba74 \uac15\uc81c\ub85c \uc5b4\ub5a4 \uac12\uc774\ub4e0 non-nullable \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc null\uc778 \uac12\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4\uba74 NPE\uac00 \ubc1c\uc0dd\ud558\uac8c \ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc77c\ubc18\uc801\uc778 \uacbd\uc6b0\uc5d0\ub294 !! \uc5f0\uc0b0\uc790\ub97c \uc0ac\uc6a9\ud558\ub294 \uac83\uc740 \uc704\ud5d8\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc0ac\uc6a9\ud558\uae30 \uc27d\uc9c0\ub9cc, \ub9ac\uc2a4\ud06c\uac00 \ud06c\uace0 \ud639\uc2dc\ub098 \ud574\ub2f9 \uac12\uc774 \ucd94\ud6c4\uc5d0\ub294 null\uc774 \ub420 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc9c0\uc591\ud574\uc57c \ub41c\ub2e4\uace0 \uc0dd\uac01\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"val length: Int = word!!.length\n"})}),"\n",(0,r.jsxs)(n.h3,{id:"as-\uc548\uc804\ud55c-\uce90\uc2a4\ud305",children:[(0,r.jsx)(n.code,{children:"as?"})," \uc548\uc804\ud55c \uce90\uc2a4\ud305"]}),"\n",(0,r.jsxs)(n.p,{children:["\ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \ub54c \uc9c0\uc815\ud55c \ud0c0\uc785\uc73c\ub85c \ubcc0\uacbd\ud560 \uc218 \uc5c6\ub2e4\uba74 ",(0,r.jsx)(n.code,{children:"ClassCastException"}),"\uc774 \ubc1c\uc0dd\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 as \ub4a4\uc5d0 ?\ub97c \ubd99\uc5ec \uc548\uc804\ud558\uac8c \ud0c0\uc785 \ubcc0\ud658\uc744 \ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ubbf8\ub9ac \ubcc0\ud658 \uac00\ub2a5\ud55c \ud0c0\uc785\uc778\uc9c0 \ud655\uc778\ud558\uc9c0 \uc54a\uace0, \uc548\uc804\ud558\uac8c \ud0c0\uc785\uc744 \ubcc0\ud658 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\ud0c0\uc785 \ubcc0\ud658\uc774 \ubd88\uac00\ub2a5 \ud560 \uacbd\uc6b0 \uc608\uc678\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\uc9c0 \uc54a\uace0 null\uc744 \ubc18\ud658\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"val value: Int? = something as? Int\n"})}),"\n",(0,r.jsx)(n.h3,{id:"list\uc5d0\uc11c\uc758-null-\ucc98\ub9ac",children:"List\uc5d0\uc11c\uc758 null \ucc98\ub9ac"}),"\n",(0,r.jsxs)(n.p,{children:["List\uc5d0\ub294 null\uc774 \uc544\ub2cc \uac12\ub9cc \ubc18\ud658\ud558\ub294 ",(0,r.jsx)(n.code,{children:"filterNotNull"})," \uc720\ud2f8\ub9ac\ud2f0 \uba54\uc11c\ub4dc\ub97c \uc81c\uacf5\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:'val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")\nval foods = foodsWithNull.filterNotNull()\n'})}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://product.kyobobook.co.kr/detail/S000001804588",children:"Kotlin in Action"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://product.kyobobook.co.kr/detail/S000001033129",children:"Effective Kotlin Item 8"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://www.baeldung.com/kotlin/null-safety",children:"Comprehensive Guide to Null Safety in Kotlin"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://kotlinlang.org/docs/null-safety.html",children:"Kotlin NullSafety"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},3905:(e,n,l)=>{l.d(n,{ah:()=>u});var r=l(67294);function t(e,n,l){return n in e?Object.defineProperty(e,n,{value:l,enumerable:!0,configurable:!0,writable:!0}):e[n]=l,e}function a(e,n){var l=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),l.push.apply(l,r)}return l}function s(e){for(var n=1;n<arguments.length;n++){var l=null!=arguments[n]?arguments[n]:{};n%2?a(Object(l),!0).forEach((function(n){t(e,n,l[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(l)):a(Object(l)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(l,n))}))}return e}function i(e,n){if(null==e)return{};var l,r,t=function(e,n){if(null==e)return{};var l,r,t={},a=Object.keys(e);for(r=0;r<a.length;r++)l=a[r],n.indexOf(l)>=0||(t[l]=e[l]);return t}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)l=a[r],n.indexOf(l)>=0||Object.prototype.propertyIsEnumerable.call(e,l)&&(t[l]=e[l])}return t}var o=r.createContext({}),u=function(e){var n=r.useContext(o),l=n;return e&&(l="function"==typeof e?e(n):s(s({},n),e)),l},c={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var l=e.components,t=e.mdxType,a=e.originalType,o=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),h=u(l),p=t,f=h["".concat(o,".").concat(p)]||h[p]||c[p]||a;return l?r.createElement(f,s(s({ref:n},d),{},{components:l})):r.createElement(f,s({ref:n},d))}));d.displayName="MDXCreateElement"},85162:(e,n,l)=>{l.d(n,{Z:()=>s});l(67294);var r=l(86010);const t={tabItem:"tabItem_Ymn6"};var a=l(85893);function s(e){let{children:n,hidden:l,className:s}=e;return(0,a.jsx)("div",{role:"tabpanel",className:(0,r.Z)(t.tabItem,s),hidden:l,children:n})}},74866:(e,n,l)=>{l.d(n,{Z:()=>w});var r=l(67294),t=l(86010),a=l(12466),s=l(16550),i=l(20469),o=l(91980),u=l(67392),c=l(50012);function d(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:l}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:l,attributes:r,default:t}}=e;return{value:n,label:l,attributes:r,default:t}}))}(l);return function(e){const n=(0,u.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,l])}function p(e){let{value:n,tabValues:l}=e;return l.some((e=>e.value===n))}function f(e){let{queryString:n=!1,groupId:l}=e;const t=(0,s.k6)(),a=function(e){let{queryString:n=!1,groupId:l}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!l)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return l??null}({queryString:n,groupId:l});return[(0,o._X)(a),(0,r.useCallback)((e=>{if(!a)return;const n=new URLSearchParams(t.location.search);n.set(a,e),t.replace({...t.location,search:n.toString()})}),[a,t])]}function b(e){const{defaultValue:n,queryString:l=!1,groupId:t}=e,a=h(e),[s,o]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:l}=e;if(0===l.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!p({value:n,tabValues:l}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${l.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=l.find((e=>e.default))??l[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:a}))),[u,d]=f({queryString:l,groupId:t}),[b,j]=function(e){let{groupId:n}=e;const l=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,a]=(0,c.Nk)(l);return[t,(0,r.useCallback)((e=>{l&&a.set(e)}),[l,a])]}({groupId:t}),m=(()=>{const e=u??b;return p({value:e,tabValues:a})?e:null})();(0,i.Z)((()=>{m&&o(m)}),[m]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!p({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);o(e),d(e),j(e)}),[d,j,a]),tabValues:a}}var j=l(72389);const m={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=l(85893);function g(e){let{className:n,block:l,selectedValue:r,selectValue:s,tabValues:i}=e;const o=[],{blockElementScrollPositionUntilNextRender:u}=(0,a.o5)(),c=e=>{const n=e.currentTarget,l=o.indexOf(n),t=i[l].value;t!==r&&(u(n),s(t))},d=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const l=o.indexOf(e.currentTarget)+1;n=o[l]??o[0];break}case"ArrowLeft":{const l=o.indexOf(e.currentTarget)-1;n=o[l]??o[o.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.Z)("tabs",{"tabs--block":l},n),children:i.map((e=>{let{value:n,label:l,attributes:a}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>o.push(e),onKeyDown:d,onClick:c,...a,className:(0,t.Z)("tabs__item",m.tabItem,a?.className,{"tabs__item--active":r===n}),children:l??n},n)}))})}function v(e){let{lazy:n,children:l,selectedValue:t}=e;const a=(Array.isArray(l)?l:[l]).filter(Boolean);if(n){const e=a.find((e=>e.props.value===t));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:a.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function y(e){const n=b(e);return(0,x.jsxs)("div",{className:(0,t.Z)("tabs-container",m.tabList),children:[(0,x.jsx)(g,{...e,...n}),(0,x.jsx)(v,{...e,...n})]})}function w(e){const n=(0,j.Z)();return(0,x.jsx)(y,{...e,children:d(e.children)},String(n))}}}]); \ No newline at end of file diff --git a/assets/js/d350f5d9.3f436aab.js b/assets/js/d350f5d9.668ec20f.js similarity index 88% rename from assets/js/d350f5d9.3f436aab.js rename to assets/js/d350f5d9.668ec20f.js index 973286531..248841034 100644 --- a/assets/js/d350f5d9.3f436aab.js +++ b/assets/js/d350f5d9.668ec20f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2098],{82622:e=>{e.exports=JSON.parse('{"label":"test","permalink":"/tags/test","allTagsPath":"/tags","count":2}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2098],{82622:e=>{e.exports=JSON.parse('{"label":"test","permalink":"/tags/test","allTagsPath":"/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/d361ad2d.23351413.js b/assets/js/d361ad2d.23351413.js deleted file mode 100644 index 5058d2be3..000000000 --- a/assets/js/d361ad2d.23351413.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2247],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>g});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function u(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),l=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},c=function(e){var t=l(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},h=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,c=u(e,["components","mdxType","originalType","parentName"]),h=l(r),g=o,d=h["".concat(i,".").concat(g)]||h[g]||s[g]||a;return r?n.createElement(d,p(p({ref:t},c),{},{components:r})):n.createElement(d,p({ref:t},c))}));function g(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,p=new Array(a);p[0]=h;var u={};for(var i in t)hasOwnProperty.call(t,i)&&(u[i]=t[i]);u.originalType=e,u.mdxType="string"==typeof e?e:o,p[1]=u;for(var l=2;l<a;l++)p[l]=r[l];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}h.displayName="MDXCreateElement"},40237:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>s,frontMatter:()=>a,metadata:()=>u,toc:()=>l});var n=r(87462),o=(r(67294),r(3905));const a={title:"Throughput \ubaa9\ud46f\uac12",slug:"/performance/throughput",last_update:{date:"2023/09/09"},tags:["throughput"]},p=void 0,u={unversionedId:"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12",id:"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12",title:"Throughput \ubaa9\ud46f\uac12",description:"Throughput",source:"@site/docs/\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12.mdx",sourceDirName:"\uc131\ub2a5",slug:"/performance/throughput",permalink:"/docs/performance/throughput",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12.mdx",tags:[{label:"throughput",permalink:"/docs/tags/throughput"}],version:"current",lastUpdatedAt:1694217600,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 9\uc77c",frontMatter:{title:"Throughput \ubaa9\ud46f\uac12",slug:"/performance/throughput",last_update:{date:"2023/09/09"},tags:["throughput"]},sidebar:"tutorialSidebar",previous:{title:"\ud328\ud0a4\uc9c0",permalink:"/docs/design/package"},next:{title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",permalink:"/docs/performance/throughput-latency"}},i={},l=[{value:"Throughput",id:"throughput",level:3},{value:"\uacc4\uc0b0 \uc608\uc2dc",id:"\uacc4\uc0b0-\uc608\uc2dc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:l};function s(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"throughput"},"Throughput"),(0,o.kt)("p",null,"1\uc77c \uc0ac\uc6a9\uc790 \uc218, 1\uba85\ub2f9 1\uc77c \ud3c9\uade0 \uc811\uc18d \uc218, 1\uc77c \ud3c9\uade0 \uc811\uc18d \uc218\uc5d0 \ub300\ud55c \ud53c\ud06c \ub54c\uc758 \ubc30\uc728\uc744 \ud655\uc778\ud55c\ub2e4. "),(0,o.kt)("admonition",{title:"throughput",type:"note"},(0,o.kt)("p",{parentName:"admonition"},"1\uc77c \ucd1d \uc811\uc18d \uc218: 1\uc77c \uc0ac\uc6a9\uc790 \uc218 x 1\uc778\ub2f9 1\uc77c \ud3c9\uade0 \uc811\uc18d \uc218",(0,o.kt)("br",{parentName:"p"}),"\n","1\uc77c \ud3c9\uade0 rps: 1\uc77c \ucd1d \uc811\uc18d \uc218 / 86400",(0,o.kt)("br",{parentName:"p"}),"\n","\ucd5c\ub300 rps: 1\uc77c \ud3c9\uade0 rps x \ucd5c\ub300 \ud53c\ud06c \ub54c\uc758 \ube44\uc728(\ud3c9\uade0 \uc811\uc18d \uc218 \ub300\ube44)")),(0,o.kt)("p",null,"\ucd5c\ub300 rps * \uc548\uc804\uacc4\uc218(2 ~ 3\ubc30)\ub97c Throughput\uc758 \ubaa9\ud45c\uce58\ub85c \ud55c\ub2e4. "),(0,o.kt)("h3",{id:"\uacc4\uc0b0-\uc608\uc2dc"},"\uacc4\uc0b0 \uc608\uc2dc"),(0,o.kt)("p",null,"DAU: 10\ub9cc\uba85",(0,o.kt)("br",{parentName:"p"}),"\n","1\uba85\ub2f9 \ud3c9\uade0 \uc811\uc18d\uc218: 10\ud68c",(0,o.kt)("br",{parentName:"p"}),"\n","\ud3c9\uade0 \uc811\uc18d \uc218 \ub300\ube44 \ucd5c\ub300 \ud53c\ud06c \ube44\uc728: 4\ubc30",(0,o.kt)("br",{parentName:"p"}),"\n","\uc548\uc804\uacc4\uc218: 3\ubc30 "),(0,o.kt)("p",null,"100000 x 10 / 86400 x 4 x 3 -> \uc57d 138rps "),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,"\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d361ad2d.edd5acc2.js b/assets/js/d361ad2d.edd5acc2.js new file mode 100644 index 000000000..08b9ebd60 --- /dev/null +++ b/assets/js/d361ad2d.edd5acc2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2247],{14448:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>l,frontMatter:()=>u,metadata:()=>a,toc:()=>c});var n=r(85893),o=r(3905);const u={title:"Throughput \ubaa9\ud46f\uac12",slug:"/performance/throughput",last_update:{date:"2023/09/09"},tags:["throughput"]},i=void 0,a={id:"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12",title:"Throughput \ubaa9\ud46f\uac12",description:"Throughput",source:"@site/docs/\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12.mdx",sourceDirName:"\uc131\ub2a5",slug:"/performance/throughput",permalink:"/docs/performance/throughput",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12.mdx",tags:[{label:"throughput",permalink:"/docs/tags/throughput"}],version:"current",lastUpdatedAt:1694217600,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 9\uc77c",frontMatter:{title:"Throughput \ubaa9\ud46f\uac12",slug:"/performance/throughput",last_update:{date:"2023/09/09"},tags:["throughput"]},sidebar:"tutorialSidebar",previous:{title:"\ud328\ud0a4\uc9c0",permalink:"/docs/design/package"},next:{title:"\uc2dc\uc2a4\ud15c \uc131\ub2a5 \uc9c0\ud45c",permalink:"/docs/performance/throughput-latency"}},p={},c=[{value:"Throughput",id:"throughput",level:3},{value:"\uacc4\uc0b0 \uc608\uc2dc",id:"\uacc4\uc0b0-\uc608\uc2dc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function s(e){const t={admonition:"admonition",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"throughput",children:"Throughput"}),"\n",(0,n.jsx)(t.p,{children:"1\uc77c \uc0ac\uc6a9\uc790 \uc218, 1\uba85\ub2f9 1\uc77c \ud3c9\uade0 \uc811\uc18d \uc218, 1\uc77c \ud3c9\uade0 \uc811\uc18d \uc218\uc5d0 \ub300\ud55c \ud53c\ud06c \ub54c\uc758 \ubc30\uc728\uc744 \ud655\uc778\ud55c\ub2e4."}),"\n",(0,n.jsx)(t.admonition,{title:"throughput",type:"note",children:(0,n.jsxs)(t.p,{children:["1\uc77c \ucd1d \uc811\uc18d \uc218: 1\uc77c \uc0ac\uc6a9\uc790 \uc218 x 1\uc778\ub2f9 1\uc77c \ud3c9\uade0 \uc811\uc18d \uc218",(0,n.jsx)(t.br,{}),"\n","1\uc77c \ud3c9\uade0 rps: 1\uc77c \ucd1d \uc811\uc18d \uc218 / 86400",(0,n.jsx)(t.br,{}),"\n","\ucd5c\ub300 rps: 1\uc77c \ud3c9\uade0 rps x \ucd5c\ub300 \ud53c\ud06c \ub54c\uc758 \ube44\uc728(\ud3c9\uade0 \uc811\uc18d \uc218 \ub300\ube44)"]})}),"\n",(0,n.jsx)(t.p,{children:"\ucd5c\ub300 rps * \uc548\uc804\uacc4\uc218(2 ~ 3\ubc30)\ub97c Throughput\uc758 \ubaa9\ud45c\uce58\ub85c \ud55c\ub2e4."}),"\n",(0,n.jsx)(t.h3,{id:"\uacc4\uc0b0-\uc608\uc2dc",children:"\uacc4\uc0b0 \uc608\uc2dc"}),"\n",(0,n.jsxs)(t.p,{children:["DAU: 10\ub9cc\uba85",(0,n.jsx)(t.br,{}),"\n","1\uba85\ub2f9 \ud3c9\uade0 \uc811\uc18d\uc218: 10\ud68c",(0,n.jsx)(t.br,{}),"\n","\ud3c9\uade0 \uc811\uc18d \uc218 \ub300\ube44 \ucd5c\ub300 \ud53c\ud06c \ube44\uc728: 4\ubc30",(0,n.jsx)(t.br,{}),"\n","\uc548\uc804\uacc4\uc218: 3\ubc30"]}),"\n",(0,n.jsx)(t.p,{children:"100000 x 10 / 86400 x 4 x 3 -> \uc57d 138rps"}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsx)(t.p,{children:"\uc544\ub9c8\uc874 \uc6f9 \uc11c\ube44\uc2a4 \ubd80\ud558 \ud14c\uc2a4\ud2b8 \uc785\ubb38 - \ub098\uce74\uac00\uc640 \ud0c0\ub8e8\ud558\uce58, \ubaa8\ub9ac\uc2dc\ud0c0 \ucf04"})]})}function l(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(s,{...e})}):s(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>c});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function u(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?u(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):u(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},u=Object.keys(e);for(n=0;n<u.length;n++)r=u[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var u=Object.getOwnPropertySymbols(e);for(n=0;n<u.length;n++)r=u[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},l=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,u=e.originalType,p=e.parentName,l=a(e,["components","mdxType","originalType","parentName"]),h=c(r),d=o,g=h["".concat(p,".").concat(d)]||h[d]||s[d]||u;return r?n.createElement(g,i(i({ref:t},l),{},{components:r})):n.createElement(g,i({ref:t},l))}));l.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/d5bb232a.2a47f439.js b/assets/js/d5bb232a.2a47f439.js deleted file mode 100644 index 798e03296..000000000 --- a/assets/js/d5bb232a.2a47f439.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3651],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>k});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),c=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),m=c(n),k=r,f=m["".concat(p,".").concat(k)]||m[k]||s[k]||l;return n?a.createElement(f,i(i({ref:t},u),{},{components:n})):a.createElement(f,i({ref:t},u))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=m;var o={};for(var p in t)hasOwnProperty.call(t,p)&&(o[p]=t[p]);o.originalType=e,o.mdxType="string"==typeof e?e:r,i[1]=o;for(var c=2;c<l;c++)i[c]=n[c];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"},14345:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>s,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var a=n(87462),r=(n(67294),n(3905));const l={title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",slug:"composite",tags:["Pattern","Composite"]},i=void 0,o={permalink:"/composite",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",source:"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",description:"\uc694\uad6c\uc0ac\ud56d",date:"2023-05-26T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 26\uc77c",tags:[{label:"Pattern",permalink:"/tags/pattern"},{label:"Composite",permalink:"/tags/composite"}],readingTime:4.74,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",slug:"composite",tags:["Pattern","Composite"]},prevItem:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",permalink:"/tecochat-retrospective-3"},nextItem:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",permalink:"/subway-retrospective"}},p={authorsImageUrls:[]},c=[{value:"\uc694\uad6c\uc0ac\ud56d",id:"\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9",id:"\uc778\ud130\ud398\uc774\uc2a4-\uc0ac\uc6a9",level:3},{value:"\ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30",id:"\ubaa8\ub4e0-\uc694\uae08-\uc815\ucc45\uc744-\ud3ec\ud568\ud558\ub294-\uc0c8\ub85c\uc6b4-\uc694\uae08-\uc815\ucc45-\ub9cc\ub4e4\uae30",level:3},{value:"\uc815\ucc45\uc758 \uc21c\uc11c",id:"\uc815\ucc45\uc758-\uc21c\uc11c",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc774\ub780",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uad6c\uc131\uc694\uc18c",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uc0ac\uc6a9\uacfc-\uc8fc\uc694-\ubaa9\ud45c",level:3},{value:"\ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84",id:"\ud328\ud134-\uc0ac\uc6a9\uc2dc-\uc8fc\uc758\ud574\uc57c\ud560-\ubd80\ubd84",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:c};function s(e){let{components:t,...l}=e;return(0,r.kt)("wrapper",(0,a.Z)({},u,l,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"\uc694\uad6c\uc0ac\ud56d"},"\uc694\uad6c\uc0ac\ud56d"),(0,r.kt)("p",null,"\uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uac70\ub9ac\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45"),(0,r.kt)("li",{parentName:"ul"},"\ub178\uc120\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45"),(0,r.kt)("li",{parentName:"ul"},"\uc5f0\ub839\ubcc4 \uc694\uae08 \ud560\uc778 \uc815\ucc45")),(0,r.kt)("h3",{id:"\uc778\ud130\ud398\uc774\uc2a4-\uc0ac\uc6a9"},"\uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9"),(0,r.kt)("p",null,"\uc694\uae08 \uc815\ucc45\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc778\ud130\ud398\uc774\uc2a4\ub85c \ud45c\ud604\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc694\uae08\uc744 \uacc4\uc0b0\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ucd5c\ub2e8 \uacbd\ub85c \uacc4\uc0b0\uc758 \uacb0\uacfc, \uc0ac\uc6a9\uc790\uc758 \uc815\ubcf4, \uc694\uae08\uc744 \ubc1b\uc544 \uc694\uae08\uc744 \uacc4\uc0b0\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public interface FarePolicy {\n int calculate(Path path, Passenger passenger, int fare);\n}\n\npublic class BaseFarePolicy implements FarePolicy { ... }\npublic class DistanceFarePolicy implements FarePolicy { ... }\npublic class AgeDiscountFarePolicy implements FarePolicy { ... }\n")),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"composite1",src:n(28629).Z,width:"1768",height:"554"})),(0,r.kt)("h3",{id:"\ubaa8\ub4e0-\uc694\uae08-\uc815\ucc45\uc744-\ud3ec\ud568\ud558\ub294-\uc0c8\ub85c\uc6b4-\uc694\uae08-\uc815\ucc45-\ub9cc\ub4e4\uae30"},"\ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30"),(0,r.kt)("p",null,"\ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub97c \ubaa8\ub450 \uac00\uc9c0\uace0 \uc788\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \ub610\ud55c FarePolicy\ub97c \uad6c\ud604\ud55c \ud615\ud0dc\uac00 \ub418\uace0, \ud544\ub4dc\ub85c\ub294 \ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub4e4\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public class SubwayFarePolicy implements FarePolicy {\n\n private final List<FarePolicy> farePolicies;\n\n public SubwayFarePolicy(final List<FarePolicy> farePolicies) {\n this.farePolicies = farePolicies;\n }\n\n @Override\n public int calculate(final Path path, final Passenger passenger, final int fare) {\n int calculatedFare = fare;\n for (FarePolicy farePolicy : farePolicies) {\n calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);\n }\n return calculatedFare;\n }\n}\n")),(0,r.kt)("p",null,"\ub530\ub77c\uc11c \uadf8\ub9bc\uc73c\ub85c \ubcf8\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"composite2",src:n(33094).Z,width:"2020",height:"954"})),(0,r.kt)("h3",{id:"\uc815\ucc45\uc758-\uc21c\uc11c"},"\uc815\ucc45\uc758 \uc21c\uc11c"),(0,r.kt)("p",null,"\uc9c0\ud558\ucca0 \uc694\uad6c\uc0ac\ud56d\uc740 \uc21c\uc11c\uac00 \uc911\uc694\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae08\uc561\uc758 \ucd1d\ud569\uc744 \uad6c\ud558\uace0, \uadf8 \ud6c4\uc5d0 \ud560\uc778 \uc815\ucc45\uc774 \ub4e4\uc5b4\uac00\uc57c\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc790\uc2dd\ub4e4\uc758 \uc21c\uc11c\ub97c \uad00\ub9ac\ud560 \ub54c \uc8fc\uc758\ub97c \uae30\uc6b8\uc5ec\uc57c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Configuration \ud074\ub798\uc2a4\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \uc21c\uc11c\ub97c \uc9c1\uc811 \uc801\uc6a9\uc2dc\ucf30\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"@Configuration\npublic class FareConfiguration {\n\n @Bean\n public FarePolicy farePolicy() {\n return new SubwayFarePolicy(List.of(\n new BaseFarePolicy(),\n new DistanceFarePolicy(),\n new AgeDiscountFarePolicy()\n ));\n }\n}\n")),(0,r.kt)("h3",{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc774\ub780"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"composite3",src:n(67922).Z,width:"1848",height:"482"})),(0,r.kt)("p",null,"GOF\uc758 \ub514\uc790\uc778 \ud328\ud134 \ucc45\uc5d0\uc11c\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uba85\ud558\uace0 \uc788\ub2e4."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\ubd80\ubd84\uacfc \uc804\uccb4\uc758 \uacc4\uce35\uc744 \ud45c\ud604\ud558\uae30 \uc704\ud574 \uac1d\uccb4\ub4e4\uc744 \ubaa8\uc544 \ud2b8\ub9ac \uad6c\uc870\ub85c \uad6c\uc131\ud569\ub2c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc6a9\uc790\ub85c \ud558\uc5ec\uae08 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ubcf5\ud569 \uac1d\uccb4\ub97c \ubaa8\ub450 \ub3d9\uc77c\ud558\uac8c \ub2e4\ub8f0 \uc218 \uc788\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc785\ub2c8\ub2e4.")),(0,r.kt)("p",null,"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uad6c\uc131\uc694\uc18c"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c"),(0,r.kt)("p",null,"Component"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc9d1\ud569 \uad00\uacc4\uc5d0 \uc815\uc758\ub420 \ubaa8\ub4e0 \uac1d\uccb4\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4 "),(0,r.kt)("li",{parentName:"ul"},"ex) \uc694\uae08 \uc815\ucc45(FarePolicy) ")),(0,r.kt)("p",null,"Leaf"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uac1c\ubcc4 \uac1d\uccb4, \uac1d\uccb4 \ud569\uc131\uc5d0 \uae30\ubcf8\uc774 \ub418\ub294 \uac1d\uccb4\uc758 \ud589\ub3d9 "),(0,r.kt)("li",{parentName:"ul"},"ex) \uac70\ub9ac \ubcc4 \uc694\uae08 \uc815\ucc45(DistanceFarePolicy) ")),(0,r.kt)("p",null,"Composite"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc5ec\ub7ec \uac1c\uc758 \uac1c\ubc1c \uac1d\uccb4\ub97c \ud3ec\ud568\ud558\ub294 \ud569\uc131 \uac1d\uccb4 "),(0,r.kt)("li",{parentName:"ul"},"ex) \uc9c0\ud558\ucca0 \uc694\uae08 \uc815\ucc45(SubwayFarePolicy) ")),(0,r.kt)("p",null,"Client"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8")),(0,r.kt)("h3",{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uc0ac\uc6a9\uacfc-\uc8fc\uc694-\ubaa9\ud45c"},"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c"),(0,r.kt)("p",null,"\ubd80\ubd84 - \uc804\uccb4\uc758 \uad00\uacc4\ub97c \ud45c\ud604\ud558\uace0 \uc2f6\uc744 \ub54c",(0,r.kt)("br",{parentName:"p"}),"\n","Client \uae30\uc900\uc73c\ub85c Composite\uc640 Leaf\uc758 \ucc28\uc774\ub97c \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc798 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc57c\ub420 \ub54c"),(0,r.kt)("h3",{id:"\ud328\ud134-\uc0ac\uc6a9\uc2dc-\uc8fc\uc758\ud574\uc57c\ud560-\ubd80\ubd84"},"\ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84"),(0,r.kt)("p",null,"\ud328\ud134\uc740 \uacf5\ud1b5\uc73c\ub85c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc758 \ud15c\ud50c\ub9bf\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubc18\ubcf5\ub418\ub294 \ubb38\uc81c\ub97c \ud6a8\uc728\uc801\uc73c\ub85c \ud574\uacb0\ud560 \uc218 \uc788\uc9c0\ub9cc \ud328\ud134\uc5d0 \ub9e4\ubab0\ub418\uc11c\ub294 \uc548\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud328\ud134\uc744 \ub9f9\ubaa9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud574\uc11c\ub294 \uc548\ub418\uace0, \ud604\uc7ac\uc758 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ub530\ub77c \ud328\ud134\uc744 \uc720\ub3d9\uc801\uc73c\ub85c \uc218\uc815\ud574\uac00\uba74\uc11c \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud56d\uc0c1 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uc0dd\uac01\ud558\uc790!"),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134, GoF\uc758 \ub514\uc790\uc778 \ud328\ud134",(0,r.kt)("br",{parentName:"p"}),"\n","\ub514\uc790\uc778 \ud328\ud134\uacfc \ud504\ub808\uc784\uc6cc\ud06c, \uc624\ube0c\uc81d\ud2b8"))}s.isMDXComponent=!0},28629:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/composite1-6117733e5244b235d9405ba72afb53ed.png"},33094:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/composite2-ac487a832bf12267cc91996ea3a5b9c7.png"},67922:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/composite3-016bf41863692b1f738bc89011687166.png"}}]); \ No newline at end of file diff --git a/assets/js/d5bb232a.61c24a0e.js b/assets/js/d5bb232a.61c24a0e.js new file mode 100644 index 000000000..401cb2fa7 --- /dev/null +++ b/assets/js/d5bb232a.61c24a0e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3651],{46116:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>d,frontMatter:()=>l,metadata:()=>c,toc:()=>o});var i=r(85893),t=r(3905);const l={title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",slug:"composite",tags:["Pattern","Composite"]},s=void 0,c={permalink:"/composite",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",source:"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",description:"\uc694\uad6c\uc0ac\ud56d",date:"2023-05-26T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 26\uc77c",tags:[{label:"Pattern",permalink:"/tags/pattern"},{label:"Composite",permalink:"/tags/composite"}],readingTime:4.74,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30",slug:"composite",tags:["Pattern","Composite"]},unlisted:!1,prevItem:{title:"[\ud14c\ucf54\ucc57] 3. \uae30\ub2a5 \uad6c\ud604",permalink:"/tecochat-retrospective-3"},nextItem:{title:"\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0",permalink:"/subway-retrospective"}},a={authorsImageUrls:[]},o=[{value:"\uc694\uad6c\uc0ac\ud56d",id:"\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9",id:"\uc778\ud130\ud398\uc774\uc2a4-\uc0ac\uc6a9",level:3},{value:"\ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30",id:"\ubaa8\ub4e0-\uc694\uae08-\uc815\ucc45\uc744-\ud3ec\ud568\ud558\ub294-\uc0c8\ub85c\uc6b4-\uc694\uae08-\uc815\ucc45-\ub9cc\ub4e4\uae30",level:3},{value:"\uc815\ucc45\uc758 \uc21c\uc11c",id:"\uc815\ucc45\uc758-\uc21c\uc11c",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc774\ub780",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uad6c\uc131\uc694\uc18c",level:3},{value:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c",id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uc0ac\uc6a9\uacfc-\uc8fc\uc694-\ubaa9\ud45c",level:3},{value:"\ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84",id:"\ud328\ud134-\uc0ac\uc6a9\uc2dc-\uc8fc\uc758\ud574\uc57c\ud560-\ubd80\ubd84",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const n={blockquote:"blockquote",br:"br",code:"code",h3:"h3",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.ah)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"\uc694\uad6c\uc0ac\ud56d",children:"\uc694\uad6c\uc0ac\ud56d"}),"\n",(0,i.jsx)(n.p,{children:"\uc9c0\ud558\ucca0 \ubbf8\uc158\uc5d0\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uc694\uad6c\uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uac70\ub9ac\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45"}),"\n",(0,i.jsx)(n.li,{children:"\ub178\uc120\ubcc4 \ucd94\uac00 \uc694\uae08 \uc815\ucc45"}),"\n",(0,i.jsx)(n.li,{children:"\uc5f0\ub839\ubcc4 \uc694\uae08 \ud560\uc778 \uc815\ucc45"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\uc778\ud130\ud398\uc774\uc2a4-\uc0ac\uc6a9",children:"\uc778\ud130\ud398\uc774\uc2a4 \uc0ac\uc6a9"}),"\n",(0,i.jsxs)(n.p,{children:["\uc694\uae08 \uc815\ucc45\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc778\ud130\ud398\uc774\uc2a4\ub85c \ud45c\ud604\ud560 \uc218 \uc788\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc694\uae08\uc744 \uacc4\uc0b0\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ucd5c\ub2e8 \uacbd\ub85c \uacc4\uc0b0\uc758 \uacb0\uacfc, \uc0ac\uc6a9\uc790\uc758 \uc815\ubcf4, \uc694\uae08\uc744 \ubc1b\uc544 \uc694\uae08\uc744 \uacc4\uc0b0\ud55c\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"public interface FarePolicy {\n int calculate(Path path, Passenger passenger, int fare);\n}\n\npublic class BaseFarePolicy implements FarePolicy { ... }\npublic class DistanceFarePolicy implements FarePolicy { ... }\npublic class AgeDiscountFarePolicy implements FarePolicy { ... }\n"})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"composite1",src:r(28629).Z+"",width:"1768",height:"554"})}),"\n",(0,i.jsx)(n.h3,{id:"\ubaa8\ub4e0-\uc694\uae08-\uc815\ucc45\uc744-\ud3ec\ud568\ud558\ub294-\uc0c8\ub85c\uc6b4-\uc694\uae08-\uc815\ucc45-\ub9cc\ub4e4\uae30",children:"\ubaa8\ub4e0 \uc694\uae08 \uc815\ucc45\uc744 \ud3ec\ud568\ud558\ub294 \uc0c8\ub85c\uc6b4 \uc694\uae08 \uc815\ucc45 \ub9cc\ub4e4\uae30"}),"\n",(0,i.jsxs)(n.p,{children:["\ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub97c \ubaa8\ub450 \uac00\uc9c0\uace0 \uc788\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc774 \ub610\ud55c FarePolicy\ub97c \uad6c\ud604\ud55c \ud615\ud0dc\uac00 \ub418\uace0, \ud544\ub4dc\ub85c\ub294 \ub098\uba38\uc9c0 \uad6c\ud604\uccb4\ub4e4\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"public class SubwayFarePolicy implements FarePolicy {\n\n private final List<FarePolicy> farePolicies;\n\n public SubwayFarePolicy(final List<FarePolicy> farePolicies) {\n this.farePolicies = farePolicies;\n }\n\n @Override\n public int calculate(final Path path, final Passenger passenger, final int fare) {\n int calculatedFare = fare;\n for (FarePolicy farePolicy : farePolicies) {\n calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);\n }\n return calculatedFare;\n }\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"\ub530\ub77c\uc11c \uadf8\ub9bc\uc73c\ub85c \ubcf8\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"composite2",src:r(33094).Z+"",width:"2020",height:"954"})}),"\n",(0,i.jsx)(n.h3,{id:"\uc815\ucc45\uc758-\uc21c\uc11c",children:"\uc815\ucc45\uc758 \uc21c\uc11c"}),"\n",(0,i.jsxs)(n.p,{children:["\uc9c0\ud558\ucca0 \uc694\uad6c\uc0ac\ud56d\uc740 \uc21c\uc11c\uac00 \uc911\uc694\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uae08\uc561\uc758 \ucd1d\ud569\uc744 \uad6c\ud558\uace0, \uadf8 \ud6c4\uc5d0 \ud560\uc778 \uc815\ucc45\uc774 \ub4e4\uc5b4\uac00\uc57c\ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc790\uc2dd\ub4e4\uc758 \uc21c\uc11c\ub97c \uad00\ub9ac\ud560 \ub54c \uc8fc\uc758\ub97c \uae30\uc6b8\uc5ec\uc57c \ud588\ub2e4.",(0,i.jsx)(n.br,{}),"\n","Configuration \ud074\ub798\uc2a4\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \uc21c\uc11c\ub97c \uc9c1\uc811 \uc801\uc6a9\uc2dc\ucf30\ub2e4."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-java",children:"@Configuration\npublic class FareConfiguration {\n\n @Bean\n public FarePolicy farePolicy() {\n return new SubwayFarePolicy(List.of(\n new BaseFarePolicy(),\n new DistanceFarePolicy(),\n new AgeDiscountFarePolicy()\n ));\n }\n}\n"})}),"\n",(0,i.jsx)(n.h3,{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc774\ub780",children:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc774\ub780?"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"composite3",src:r(67922).Z+"",width:"1848",height:"482"})}),"\n",(0,i.jsx)(n.p,{children:"GOF\uc758 \ub514\uc790\uc778 \ud328\ud134 \ucc45\uc5d0\uc11c\ub294 \ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uba85\ud558\uace0 \uc788\ub2e4."}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsxs)(n.p,{children:["\ubd80\ubd84\uacfc \uc804\uccb4\uc758 \uacc4\uce35\uc744 \ud45c\ud604\ud558\uae30 \uc704\ud574 \uac1d\uccb4\ub4e4\uc744 \ubaa8\uc544 \ud2b8\ub9ac \uad6c\uc870\ub85c \uad6c\uc131\ud569\ub2c8\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc0ac\uc6a9\uc790\ub85c \ud558\uc5ec\uae08 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ubcf5\ud569 \uac1d\uccb4\ub97c \ubaa8\ub450 \ub3d9\uc77c\ud558\uac8c \ub2e4\ub8f0 \uc218 \uc788\ub3c4\ub85d \ud558\ub294 \ud328\ud134\uc785\ub2c8\ub2e4."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc740 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud55c \uac1c\ubcc4 \uac1d\uccb4\uac00 \uc874\uc7ac\ud558\uace0, \uadf8 \uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\ub294 \ud558\ub098\uc758 \uad6c\ud604\uccb4\uac00 \ub530\ub85c \uc874\uc7ac\ud558\ub294 \ud328\ud134\uc774\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\uc774 \ub54c \uc0ac\uc6a9\uc790\ub294 \uac1c\ubcc4 \uac1d\uccb4\uc640 \ud569\uc131 \uac1d\uccb4(\uac1c\ubcc4 \uac1d\uccb4\ub4e4\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294)\ub97c \ub611\uac19\uc774 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,i.jsx)(n.h3,{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uad6c\uc131\uc694\uc18c",children:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uad6c\uc131\uc694\uc18c"}),"\n",(0,i.jsx)(n.p,{children:"Component"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc9d1\ud569 \uad00\uacc4\uc5d0 \uc815\uc758\ub420 \ubaa8\ub4e0 \uac1d\uccb4\uc5d0 \ub300\ud55c \uc778\ud130\ud398\uc774\uc2a4"}),"\n",(0,i.jsx)(n.li,{children:"ex) \uc694\uae08 \uc815\ucc45(FarePolicy)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Leaf"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uac1c\ubcc4 \uac1d\uccb4, \uac1d\uccb4 \ud569\uc131\uc5d0 \uae30\ubcf8\uc774 \ub418\ub294 \uac1d\uccb4\uc758 \ud589\ub3d9"}),"\n",(0,i.jsx)(n.li,{children:"ex) \uac70\ub9ac \ubcc4 \uc694\uae08 \uc815\ucc45(DistanceFarePolicy)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Composite"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc5ec\ub7ec \uac1c\uc758 \uac1c\ubc1c \uac1d\uccb4\ub97c \ud3ec\ud568\ud558\ub294 \ud569\uc131 \uac1d\uccb4"}),"\n",(0,i.jsx)(n.li,{children:"ex) \uc9c0\ud558\ucca0 \uc694\uae08 \uc815\ucc45(SubwayFarePolicy)"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Client"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ud074\ub77c\uc774\uc5b8\ud2b8"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ucef4\ud3ec\uc9c0\ud2b8-\ud328\ud134\uc758-\uc0ac\uc6a9\uacfc-\uc8fc\uc694-\ubaa9\ud45c",children:"\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc758 \uc0ac\uc6a9\uacfc \uc8fc\uc694 \ubaa9\ud45c"}),"\n",(0,i.jsxs)(n.p,{children:["\ubd80\ubd84 - \uc804\uccb4\uc758 \uad00\uacc4\ub97c \ud45c\ud604\ud558\uace0 \uc2f6\uc744 \ub54c",(0,i.jsx)(n.br,{}),"\n","Client \uae30\uc900\uc73c\ub85c Composite\uc640 Leaf\uc758 \ucc28\uc774\ub97c \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc798 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub3c4\ub85d \ud574\uc57c\ub420 \ub54c"]}),"\n",(0,i.jsx)(n.h3,{id:"\ud328\ud134-\uc0ac\uc6a9\uc2dc-\uc8fc\uc758\ud574\uc57c\ud560-\ubd80\ubd84",children:"\ud328\ud134 \uc0ac\uc6a9\uc2dc \uc8fc\uc758\ud574\uc57c\ud560 \ubd80\ubd84"}),"\n",(0,i.jsxs)(n.p,{children:["\ud328\ud134\uc740 \uacf5\ud1b5\uc73c\ub85c \uc0ac\uc6a9 \uac00\ub2a5\ud55c \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc758 \ud15c\ud50c\ub9bf\uc774\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ubc18\ubcf5\ub418\ub294 \ubb38\uc81c\ub97c \ud6a8\uc728\uc801\uc73c\ub85c \ud574\uacb0\ud560 \uc218 \uc788\uc9c0\ub9cc \ud328\ud134\uc5d0 \ub9e4\ubab0\ub418\uc11c\ub294 \uc548\ub41c\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ud328\ud134\uc744 \ub9f9\ubaa9\uc801\uc73c\ub85c \uc0ac\uc6a9\ud574\uc11c\ub294 \uc548\ub418\uace0, \ud604\uc7ac\uc758 \uc694\uad6c\uc0ac\ud56d\uc5d0 \ub530\ub77c \ud328\ud134\uc744 \uc720\ub3d9\uc801\uc73c\ub85c \uc218\uc815\ud574\uac00\uba74\uc11c \uc801\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,i.jsx)(n.br,{}),"\n","\ud56d\uc0c1 \ud2b8\ub808\uc774\ub4dc\uc624\ud504\ub97c \uc0dd\uac01\ud558\uc790!"]}),"\n",(0,i.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,i.jsxs)(n.p,{children:["\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134, GoF\uc758 \ub514\uc790\uc778 \ud328\ud134",(0,i.jsx)(n.br,{}),"\n","\ub514\uc790\uc778 \ud328\ud134\uacfc \ud504\ub808\uc784\uc6cc\ud06c, \uc624\ube0c\uc81d\ud2b8"]})]})}function d(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>o});var i=r(67294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function l(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,i)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?l(Object(r),!0).forEach((function(n){t(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function c(e,n){if(null==e)return{};var r,i,t=function(e,n){if(null==e)return{};var r,i,t={},l=Object.keys(e);for(i=0;i<l.length;i++)r=l[i],n.indexOf(r)>=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(i=0;i<l.length;i++)r=l[i],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var a=i.createContext({}),o=function(e){var n=i.useContext(a),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},d=i.forwardRef((function(e,n){var r=e.components,t=e.mdxType,l=e.originalType,a=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=o(r),h=t,j=u["".concat(a,".").concat(h)]||u[h]||p[h]||l;return r?i.createElement(j,s(s({ref:n},d),{},{components:r})):i.createElement(j,s({ref:n},d))}));d.displayName="MDXCreateElement"},28629:(e,n,r)=>{r.d(n,{Z:()=>i});const i=r.p+"assets/images/composite1-6117733e5244b235d9405ba72afb53ed.png"},33094:(e,n,r)=>{r.d(n,{Z:()=>i});const i=r.p+"assets/images/composite2-ac487a832bf12267cc91996ea3a5b9c7.png"},67922:(e,n,r)=>{r.d(n,{Z:()=>i});const i=r.p+"assets/images/composite3-016bf41863692b1f738bc89011687166.png"}}]); \ No newline at end of file diff --git a/assets/js/d65e25b7.04063c18.js b/assets/js/d65e25b7.04063c18.js new file mode 100644 index 000000000..3416c3067 --- /dev/null +++ b/assets/js/d65e25b7.04063c18.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7776],{60626:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>l,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=t(85893),a=t(3905),i=t(74866),s=t(85162);const o={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",slug:"route-image-async-with-event",tags:["async","event"]},l=void 0,c={permalink:"/route-image-async-with-event",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",source:"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",description:"\uc774\uc804 \uae00",date:"2023-08-13T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 13\uc77c",tags:[{label:"async",permalink:"/tags/async"},{label:"event",permalink:"/tags/event"}],readingTime:11.2,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",slug:"route-image-async-with-event",tags:["async","event"]},unlisted:!1,prevItem:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/cloudwatch"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",permalink:"/route-image-implementation"}},u={authorsImageUrls:[]},d=[{value:"\uc774\uc804 \uae00",id:"\uc774\uc804-\uae00",level:2},{value:"\uac1c\uc694",id:"\uac1c\uc694",level:2},{value:"\uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120",id:"\uc8fc\uae30\ub2a5\uc758-\uc751\ub2f5\uc18d\ub3c4-\uac1c\uc120",level:3},{value:"\ud655\uc7a5\uc131 \ub300\ube44",id:"\ud655\uc7a5\uc131-\ub300\ube44",level:3},{value:"\ube44\ub3d9\uae30 \ucc98\ub9ac",id:"\ube44\ub3d9\uae30-\ucc98\ub9ac",level:2},{value:"\ube44\ub3d9\uae30 \uc124\uc815",id:"\ube44\ub3d9\uae30-\uc124\uc815",level:3},{value:"@Async \uc801\uc6a9",id:"async-\uc801\uc6a9",level:3},{value:"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810",id:"\ube44\ub3d9\uae30-\ucc98\ub9ac\uc2dc-\ubb38\uc81c\uc810",level:3},{value:"\uc774\ubca4\ud2b8 \uc0ac\uc6a9",id:"\uc774\ubca4\ud2b8-\uc0ac\uc6a9",level:2},{value:"\uc774\ubca4\ud2b8 \ubc1c\ud589",id:"\uc774\ubca4\ud2b8-\ubc1c\ud589",level:3},{value:"\uc774\ubca4\ud2b8 \uad6c\ub3c5",id:"\uc774\ubca4\ud2b8-\uad6c\ub3c5",level:3},{value:"\ud14c\uc2a4\ud2b8",id:"\ud14c\uc2a4\ud2b8",level:3},{value:"\uacb0\uacfc",id:"\uacb0\uacfc",level:2},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function p(e){const n={a:"a",admonition:"admonition",blockquote:"blockquote",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",mermaid:"mermaid",p:"p",pre:"pre",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"\uc774\uc804-\uae00",children:"\uc774\uc804 \uae00"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"./route-image-intro",children:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"./route-image-implementation",children:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604"})]}),"\n",(0,r.jsx)(n.h2,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,r.jsxs)(n.p,{children:["\ud604\uc7ac \uc5ec\ud589\uc744 \ub9c8\uce58\ub294 \uacbd\uc6b0, \uac10\uc0c1\uc744 \uc0dd\uc131\ud558\ub294 \uacbd\uc6b0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \uc704\uce58 \uc815\ubcf4\uc758 \uac1c\uc218\uc5d0 \uc815\ube44\ub840\ud558\uc5ec \uc0dd\uc131 \uc2dc\uac04\uc774 \uc99d\uac00\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ube44\ub3d9\uae30\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\uc5ec \uc0ac\uc6a9\uc790\uc758 \uacbd\ud5d8\uc744 \uac1c\uc120\uc2dc\ud0ac \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc8fc\uae30\ub2a5\uc758-\uc751\ub2f5\uc18d\ub3c4-\uac1c\uc120",children:"\uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120"}),"\n",(0,r.jsxs)(n.p,{children:["\uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc774 \uc8fc\uae30\ub2a5\uc774\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ubd80\uae30\ub2a5\uc774\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \ud604\uc7ac \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc758 \uc751\ub2f5 \uc18d\ub3c4\uac00 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uace0 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uc5ec\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc18c\uc694 \uc2dc\uac04\uc774 1\ucd08 \uc774\uc0c1 \uac78\ub9ac\ub294 \uacbd\uc6b0\uac00 \uc874\uc7ac\ud558\uae30\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uace0 \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131 \uae30\ub2a5\uc758 \uc751\ub2f5 \uc2dc\uac04\uc744 \uac1c\uc120\ud558\ub294 \uac83\uc774 \ub354 \uc911\uc694\ud558\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ud655\uc7a5\uc131-\ub300\ube44",children:"\ud655\uc7a5\uc131 \ub300\ube44"}),"\n",(0,r.jsxs)(n.p,{children:["\ud604\uc7ac 10\ubd84 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc11c\ubc84\uc5d0 \uc800\uc7a5\ud558\uace0 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc870\uae08 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uadf8\ub9ac\ub294 \uacbd\uc6b0 \ud558\ub098\uc758 \uc5ec\ud589\uc5d0 \ub9ce\uc740 \uc704\uce58 \uc815\ubcf4\uac00 \uc800\uc7a5\ub420 \uc218\ubc16\uc5d0 \uc5c6\uace0 \ub530\ub77c\uc11c \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uac78\ub9ac\ub294 \uc2dc\uac04\uc774 \ub354 \uae38\uc5b4\uc9c8 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ucd94\ud6c4\uc5d0 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \uacbd\uc6b0\ub97c \ub300\ube44\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\ub294 \uac83\uc774 \ud569\ub2f9\ud558\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\ube44\ub3d9\uae30-\ucc98\ub9ac",children:"\ube44\ub3d9\uae30 \ucc98\ub9ac"}),"\n",(0,r.jsx)(n.p,{children:"@Async\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uba54\uc11c\ub4dc\ub97c \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ub9cc\ub4e4 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"\ube44\ub3d9\uae30-\uc124\uc815",children:"\ube44\ub3d9\uae30 \uc124\uc815"}),"\n",(0,r.jsxs)(n.p,{children:["\uc0ac\uc6a9\ud558\uae30 \uc804\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c EnableAsync \uc124\uc815\uc744 \ud574\uc57c\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud574\ub2f9 \uc124\uc815\uc744 \uc801\uc6a9\ud558\uba74 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc\uc5d0 @Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec\uc8fc\uae30\ub9cc \ud558\uba74 \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",metastring:'title="AsyncConfig"',children:"@EnableAsync\n@Configuration\npublic class AsyncConfig {\n}\n"})}),"\n",(0,r.jsx)(n.p,{children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \ud560 \ub54c \ub9e4\ubc88 \uc0c8\ub85c\uc6b4 \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ub808\ub4dc \ud480 \uc124\uc815\uc744 \ub530\ub85c \ud574\uc918\uc57c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ThreadPoolTaskExecutor\ub97c \ub530\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc544\ub3c4 \uae30\ubcf8\uc801\uc73c\ub85c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uac00 \uc0dd\uc131\uc744 \ub3c4\uc640\uc900\ub2e4."}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing.\n7.7. Task Execution and Scheduling, Spring Boot Docs"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"async-\uc801\uc6a9",children:"@Async \uc801\uc6a9"}),"\n",(0,r.jsx)(n.p,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\uc5d0 Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ud55c\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",metastring:'title="RouteImageGenerator"',children:"@Async\npublic void generate(\n List<Double> latitudes,\n List<Double> longitudes,\n List<Double> pointedLatitudes,\n List<Double> pointedLongitudes,\n Long tripId\n) {\n // \uc774\ubbf8\uc9c0 \uc0dd\uc131\n RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);\n Coordinates coordinates = Coordinates.of(latitudes, longitudes);\n Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);\n drawImage(coordinates, routeImageDrawer, pointedCoordinates);\n\n // \uc774\ubbf8\uc9c0 \uc800\uc7a5\n String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());\n\n // \uc790\uc6d0 \ud560\ub2f9 \ud574\uc81c\n routeImageDrawer.dispose();\n\n // \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac12 \ubcc0\uacbd\n Trip trip = tripRepository.findById(tripId)\n .orElseThrow();\n trip.changeRouteImageUrl(imageUrl);\n tripRepository.save(trip);\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\ube44\ub3d9\uae30-\ucc98\ub9ac\uc2dc-\ubb38\uc81c\uc810",children:"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810"}),"\n",(0,r.jsxs)(n.p,{children:["\ud604\uc7ac \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uace0 \uc800\uc7a5 \ud6c4, \uc800\uc7a5 \uacbd\ub85c\ub97c DB\uc5d0 \ubc18\uc601\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ud615\ud0dc\uac00 \ub418\uba70 \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \ubb38\uc81c\uac00 \uc0dd\uae34\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n trip[trip: \uc5ec\ud589 \uad00\ub828 \ud328\ud0a4\uc9c0] --\x3e draw[draw: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294 \ud328\ud0a4\uc9c0]\n draw --\x3e trip"}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uacfc \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n\tsubgraph draw\n\t\tdirection LR\n\t\tRG[RouteImageGenerator] -- DB \ubc18\uc601 \uc694\uccad --\x3e ILR[ImageLinkTripRepository]\n\tend\n subgraph trip\n\t\tdirection LR\n\t\tTS[TripService] -- \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e RG\n\t\tILRI[ImageLinkTripRepositoryImpl] -- \uad6c\ud604 --\x3e ILR\n\tend\n\n\ttrip --\x3e draw"}),"\n",(0,r.jsxs)(n.p,{children:["\ud328\ud0a4\uc9c0 \uac04 \uc758\uc874\uc131\uc740 \ud574\uacb0\ub418\uc5c8\uc9c0\ub9cc, \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5\uc744 \uc704\ud574 tripId\ub97c \ubc1b\uc544\uc57c\ud558\ub294 \ub4f1\uc758 \ub17c\ub9ac\uc801\uc778 \uc758\uc874\uc131\uc740 \uc544\uc9c1 \ud574\uacb0\ub418\uc9c0 \uc54a\uc558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\uc774\ubca4\ud2b8-\uc0ac\uc6a9",children:"\uc774\ubca4\ud2b8 \uc0ac\uc6a9"}),"\n",(0,r.jsx)(n.p,{children:"\uc2a4\ud504\ub9c1\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uba74 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc758 \ube44\uad00\uc2ec\uc0ac(ex. \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131)\uc744 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"\uc774\ubca4\ud2b8-\ubc1c\ud589",children:"\uc774\ubca4\ud2b8 \ubc1c\ud589"}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \uba3c\uc800 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 ApplicationEventPublisher \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c ApplicationContext\uac00 \uad6c\ud604\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",metastring:'title="TripService & TripUpdateEvent"',children:"public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {\n ...\n\n // \uc774\ubca4\ud2b8 \ubc1c\ud589\n applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));\n}\n\npublic record TripUpdateEvent(Long tripId) {\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \ub54c \ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc774 \uc911\uc694\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\ub294 \ub3c4\uba54\uc778\uc758 \ud589\uc704\ub97c \ub2f4\uace0 \uc788\ub294 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589(ex. RouteImageGenerateEvent)\ud55c\ub2e4\uba74 \ub17c\ub9ac\uc801\uc778 \uc758\uc874 \uad00\uacc4\uac00 \ub0a8\uc544\uc788\uae30\uc5d0 \uc774\ubca4\ud2b8\ub97c \uc801\uc808\ud788 \uc0ac\uc6a9\ud588\ub2e4\uace0 \ubcf4\uae30 \uc5b4\ub835\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc740 \uc8fc\uae30\ub2a5\uc774 \uc5b4\ub5a4 \ud589\uc704(ex. TripUpdateEvent)\ub97c \ud588\ub294\uc9c0\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \ub2f4\uaca8\uc788\ub294 \uc774\ubca4\ud2b8\uba85\uc73c\ub85c \ubc1c\ud589\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc774\ubca4\ud2b8-\uad6c\ub3c5",children:"\uc774\ubca4\ud2b8 \uad6c\ub3c5"}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc2e4\ud589\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\uae30 \uc704\ud558\uc5ec ",(0,r.jsx)(n.code,{children:"@Async"})," \uc560\ub108\ud14c\uc774\uc158\uc744 \uc801\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ubca4\ud2b8\uc758 \uad6c\ub3c5\uc740 \uc5ec\ud589\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \uc885\ub8cc\ub420 \ub54c \uc5ec\ud589\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \uac00\uc9c0\uace0 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud574 ",(0,r.jsx)(n.code,{children:"@TransactionalEventListener"}),"\ub97c \uc0ac\uc6a9\ud588\ub2e4."]}),"\n",(0,r.jsxs)(n.admonition,{title:"TransactionPhase \uc124\uc815",type:"note",children:[(0,r.jsx)(n.p,{children:"TransactionPhase\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \uc774\ubca4\ud2b8\ub97c \uc5b4\ub5a4 \ub2e8\uacc4\uc5d0\uc11c \uc218\uc2e0\ud558\uace0 \ucc98\ub9ac\ud560\uc9c0\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."}),(0,r.jsxs)(n.p,{children:["AFTER_COMMIT(\uae30\ubcf8\uac12): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ucee4\ubc0b \ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,r.jsx)(n.br,{}),"\n","AFTER_ROLLBACK: \ud2b8\ub79c\uc7ad\uc158\uc774 \ub864\ubc31\ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,r.jsx)(n.br,{}),"\n","AFTER_COMPLETION: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub610\ub294 \ub864\ubc31 \ub418\uc5c8\uc744 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,r.jsx)(n.br,{}),"\n","BEFORE_COMMIT: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub418\uae30 \uc804 \uc774\ubca4\ud2b8 \uc2e4\ud589"]})]}),"\n",(0,r.jsx)(n.p,{children:"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uae30 \uc704\ud574 @Transactional \uc560\ub108\ud14c\uc774\uc158\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",metastring:'title="TripUpdateEventHandler"',children:"@Component\npublic class TripUpdateEventHandler {\n\n private final RouteImageGenerator routeImageGenerator;\n private final TripRepository tripRepository;\n\n public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {\n this.routeImageGenerator = routeImageGenerator;\n this.tripRepository = tripRepository;\n }\n\n @Async\n @TransactionalEventListener(phase = AFTER_COMMIT)\n public void handle(TripUpdateEvent tripUpdateEvent) {\n Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());\n\n String imageUrl = routeImageGenerator.generate(\n trip.getLatitudes(),\n trip.getLongitudes(),\n trip.getPointedLatitudes(),\n trip.getPointedLongitudes()\n );\n\n trip.changeRouteImageUrl(imageUrl);\n tripRepository.save(trip);\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c\uc368 \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ubb38\uc81c\uac00 \ub2e4\uc74c\uacfc \uac19\uc774 \ud574\uacb0\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub610\ud55c \uc8fc\uae30\ub2a5\uacfc \ubd80\uae30\ub2a5\uc744 \ubd84\ub9ac\ud568\uc73c\ub85c\uc368 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc5d0 \ub300\ud55c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uc5c8\ub2e4."]}),"\n",(0,r.jsx)(n.mermaid,{value:"graph LR\n subgraph trip\n TripServcie -- \ubc1c\ud589 --\x3e TripUpdateEvent\n TripRepository\n end\n\n subgraph draw\n TripUpdateEventHandler -- \uad6c\ub3c5 \ud6c4 \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e TripUpdateEvent\n TripUpdateEventHandler -- \uc0dd\uc131\ub41c \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5 --\x3e TripRepository\n end"}),"\n",(0,r.jsx)(n.h3,{id:"\ud14c\uc2a4\ud2b8",children:"\ud14c\uc2a4\ud2b8"}),"\n",(0,r.jsx)(n.p,{children:"\ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud14c\uc2a4\ud2b8\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \ubc29\ubc95\uc774 \uc788\ub2e4."}),"\n","\n","\n",(0,r.jsxs)(i.Z,{children:[(0,r.jsx)(s.Z,{value:"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d",label:"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@SpringBootTest\npublic class TripUpdateEventHandlerIntegrationTest {\n\n ...\n\n @Test\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\n // given\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\n .willReturn(\uc5ec\ud589());\n\n // when\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\n\n // then\n then(routeImageGenerator)\n .should(Mockito.timeout(5000).times(1))\n .generate(any(), any(), any(), any());\n }\n}\n"})})}),(0,r.jsx)(s.Z,{value:"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d",label:"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@ContextConfiguration(classes = TestSyncConfig.class)\n@SpringBootTest\npublic class TripUpdateEventHandlerIntegrationTest {\n\n ...\n\n @Test\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\n // given\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\n .willReturn(\uc5ec\ud589());\n\n // when\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\n\n // then\n then(routeImageGenerator)\n .should(times(1))\n .generate(any(), any(), any(), any());\n }\n}\n"})})})]}),"\n",(0,r.jsxs)(n.p,{children:["\ucc98\uc74c\uc5d0\ub294 \ud14c\uc2a4\ud2b8\uc5d0\uc11c\ub9cc \ub3d9\uae30\ub85c \uc124\uc815 \ud6c4 \uac80\uc99d\ud558\ub824\uace0 \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud1b5\ud569 \ud14c\uc2a4\ud2b8\uc5d0\uc120 ",(0,r.jsx)(n.code,{children:"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1 \uc885\ub8cc\ub418\uc5c8\uc744 \ub54c \ube44\ub3d9\uae30\ub85c \uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0"})," \uac80\uc99d\uc774 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 \ucd5c\uc885\uc801\uc73c\ub85c ",(0,r.jsx)(n.code,{children:"Mockito.timeout"})," \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \ud1b5\uacfc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\uacb0\uacfc",children:"\uacb0\uacfc"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"./time.png",src:t(89297).Z+"",width:"1682",height:"678"})}),"\n",(0,r.jsxs)(n.p,{children:["\uc704 \uc751\ub2f5 \uc2dc\uac04\uc740 \uc704\uce58 \uc815\ubcf4 1000\uac1c\ub97c \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ud55c \uac12\uc774\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc751\ub2f5 \uc2dc\uac04\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ud3ec\ud568\ub418\uc9c0 \uc54a\uc544\uc11c \uc131\ub2a5\uc774 \uac1c\uc120\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.task-execution-and-scheduling",children:"7.7. Task Execution and Scheduling, Spring Boot Docs"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.baeldung.com/spring-events",children:"Spring Events, Baeldung"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://techblog.woowahan.com/7835/",children:"\ud68c\uc6d0\uc2dc\uc2a4\ud15c \uc774\ubca4\ud2b8\uae30\ubc18 \uc544\ud0a4\ud14d\ucc98 \uad6c\ucd95\ud558\uae30"})]})]})}function h(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>c});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?i(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),p=c(t),h=a,g=p["".concat(l,".").concat(h)]||p[h]||u[h]||i;return t?r.createElement(g,s(s({ref:n},d),{},{components:t})):r.createElement(g,s({ref:n},d))}));d.displayName="MDXCreateElement"},85162:(e,n,t)=>{t.d(n,{Z:()=>s});t(67294);var r=t(86010);const a={tabItem:"tabItem_Ymn6"};var i=t(85893);function s(e){let{children:n,hidden:t,className:s}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,r.Z)(a.tabItem,s),hidden:t,children:n})}},74866:(e,n,t)=>{t.d(n,{Z:()=>T});var r=t(67294),a=t(86010),i=t(12466),s=t(16550),o=t(20469),l=t(91980),c=t(67392),u=t(50012);function d(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:a}}=e;return{value:n,label:t,attributes:r,default:a}}))}(t);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function h(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function g(e){let{queryString:n=!1,groupId:t}=e;const a=(0,s.k6)(),i=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,l._X)(i),(0,r.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function m(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=p(e),[s,l]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!h({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:i}))),[c,d]=g({queryString:t,groupId:a}),[m,b]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,u.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),v=(()=>{const e=c??m;return h({value:e,tabValues:i})?e:null})();(0,o.Z)((()=>{v&&l(v)}),[v]);return{selectedValue:s,selectValue:(0,r.useCallback)((e=>{if(!h({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),d(e),b(e)}),[d,b,i]),tabValues:i}}var b=t(72389);const v={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=t(85893);function j(e){let{className:n,block:t,selectedValue:r,selectValue:s,tabValues:o}=e;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,i.o5)(),u=e=>{const n=e.currentTarget,t=l.indexOf(n),a=o[t].value;a!==r&&(c(n),s(a))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=l.indexOf(e.currentTarget)+1;n=l[t]??l[0];break}case"ArrowLeft":{const t=l.indexOf(e.currentTarget)-1;n=l[t]??l[l.length-1];break}}n?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.Z)("tabs",{"tabs--block":t},n),children:o.map((e=>{let{value:n,label:t,attributes:i}=e;return(0,x.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>l.push(e),onKeyDown:d,onClick:u,...i,className:(0,a.Z)("tabs__item",v.tabItem,i?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function f(e){let{lazy:n,children:t,selectedValue:a}=e;const i=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a})))})}function y(e){const n=m(e);return(0,x.jsxs)("div",{className:(0,a.Z)("tabs-container",v.tabList),children:[(0,x.jsx)(j,{...e,...n}),(0,x.jsx)(f,{...e,...n})]})}function T(e){const n=(0,b.Z)();return(0,x.jsx)(y,{...e,children:d(e.children)},String(n))}},89297:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/time-8bef9a6cf2dcace85f12ae5624da94f5.png"}}]); \ No newline at end of file diff --git a/assets/js/d65e25b7.e3ba3748.js b/assets/js/d65e25b7.e3ba3748.js deleted file mode 100644 index 16f3e54d9..000000000 --- a/assets/js/d65e25b7.e3ba3748.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7776],{3905:(e,t,n)=>{n.d(t,{Zo:()=>s,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var p=r.createContext({}),u=function(e){var t=r.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},s=function(e){var t=u(e.components);return r.createElement(p.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),d=u(n),m=a,g=d["".concat(p,".").concat(m)]||d[m]||c[m]||i;return n?r.createElement(g,o(o({ref:t},s),{},{components:n})):r.createElement(g,o({ref:t},s))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=d;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var u=2;u<i;u++)o[u]=n[u];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}d.displayName="MDXCreateElement"},85162:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(67294),a=n(86010);const i="tabItem_Ymn6";function o(e){let{children:t,hidden:n,className:o}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(i,o),hidden:n},t)}},74866:(e,t,n)=>{n.d(t,{Z:()=>E});var r=n(87462),a=n(67294),i=n(86010),o=n(12466),l=n(16550),p=n(91980),u=n(67392),s=n(50012);function c(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:n,attributes:r,default:a}}=e;return{value:t,label:n,attributes:r,default:a}}))}function d(e){const{values:t,children:n}=e;return(0,a.useMemo)((()=>{const e=t??c(n);return function(e){const t=(0,u.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,n])}function m(e){let{value:t,tabValues:n}=e;return n.some((e=>e.value===t))}function g(e){let{queryString:t=!1,groupId:n}=e;const r=(0,l.k6)(),i=function(e){let{queryString:t=!1,groupId:n}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:t,groupId:n});return[(0,p._X)(i),(0,a.useCallback)((e=>{if(!i)return;const t=new URLSearchParams(r.location.search);t.set(i,e),r.replace({...r.location,search:t.toString()})}),[i,r])]}function v(e){const{defaultValue:t,queryString:n=!1,groupId:r}=e,i=d(e),[o,l]=(0,a.useState)((()=>function(e){let{defaultValue:t,tabValues:n}=e;if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!m({value:t,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${n.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const r=n.find((e=>e.default))??n[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:t,tabValues:i}))),[p,u]=g({queryString:n,groupId:r}),[c,v]=function(e){let{groupId:t}=e;const n=function(e){return e?`docusaurus.tab.${e}`:null}(t),[r,i]=(0,s.Nk)(n);return[r,(0,a.useCallback)((e=>{n&&i.set(e)}),[n,i])]}({groupId:r}),b=(()=>{const e=p??c;return m({value:e,tabValues:i})?e:null})();(0,a.useLayoutEffect)((()=>{b&&l(b)}),[b]);return{selectedValue:o,selectValue:(0,a.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);l(e),u(e),v(e)}),[u,v,i]),tabValues:i}}var b=n(72389);const h="tabList__CuJ",k="tabItem_LNqP";function f(e){let{className:t,block:n,selectedValue:l,selectValue:p,tabValues:u}=e;const s=[],{blockElementScrollPositionUntilNextRender:c}=(0,o.o5)(),d=e=>{const t=e.currentTarget,n=s.indexOf(t),r=u[n].value;r!==l&&(c(t),p(r))},m=e=>{let t=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const n=s.indexOf(e.currentTarget)+1;t=s[n]??s[0];break}case"ArrowLeft":{const n=s.indexOf(e.currentTarget)-1;t=s[n]??s[s.length-1];break}}t?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.Z)("tabs",{"tabs--block":n},t)},u.map((e=>{let{value:t,label:n,attributes:o}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:l===t?0:-1,"aria-selected":l===t,key:t,ref:e=>s.push(e),onKeyDown:m,onClick:d},o,{className:(0,i.Z)("tabs__item",k,o?.className,{"tabs__item--active":l===t})}),n??t)})))}function y(e){let{lazy:t,children:n,selectedValue:r}=e;const i=(Array.isArray(n)?n:[n]).filter(Boolean);if(t){const e=i.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},i.map(((e,t)=>(0,a.cloneElement)(e,{key:t,hidden:e.props.value!==r}))))}function T(e){const t=v(e);return a.createElement("div",{className:(0,i.Z)("tabs-container",h)},a.createElement(f,(0,r.Z)({},e,t)),a.createElement(y,(0,r.Z)({},e,t)))}function E(e){const t=(0,b.Z)();return a.createElement(T,(0,r.Z)({key:String(t)},e))}},8e4:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>p,default:()=>m,frontMatter:()=>l,metadata:()=>u,toc:()=>c});var r=n(87462),a=(n(67294),n(3905)),i=n(74866),o=n(85162);const l={title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",slug:"route-image-async-with-event",tags:["async","event"]},p=void 0,u={permalink:"/route-image-async-with-event",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",source:"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",description:"\uc774\uc804 \uae00",date:"2023-08-13T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 13\uc77c",tags:[{label:"async",permalink:"/tags/async"},{label:"event",permalink:"/tags/event"}],readingTime:11.2,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",slug:"route-image-async-with-event",tags:["async","event"]},prevItem:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",permalink:"/cloudwatch"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604",permalink:"/route-image-implementation"}},s={authorsImageUrls:[]},c=[{value:"\uc774\uc804 \uae00",id:"\uc774\uc804-\uae00",level:2},{value:"\uac1c\uc694",id:"\uac1c\uc694",level:2},{value:"\uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120",id:"\uc8fc\uae30\ub2a5\uc758-\uc751\ub2f5\uc18d\ub3c4-\uac1c\uc120",level:3},{value:"\ud655\uc7a5\uc131 \ub300\ube44",id:"\ud655\uc7a5\uc131-\ub300\ube44",level:3},{value:"\ube44\ub3d9\uae30 \ucc98\ub9ac",id:"\ube44\ub3d9\uae30-\ucc98\ub9ac",level:2},{value:"\ube44\ub3d9\uae30 \uc124\uc815",id:"\ube44\ub3d9\uae30-\uc124\uc815",level:3},{value:"@Async \uc801\uc6a9",id:"async-\uc801\uc6a9",level:3},{value:"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810",id:"\ube44\ub3d9\uae30-\ucc98\ub9ac\uc2dc-\ubb38\uc81c\uc810",level:3},{value:"\uc774\ubca4\ud2b8 \uc0ac\uc6a9",id:"\uc774\ubca4\ud2b8-\uc0ac\uc6a9",level:2},{value:"\uc774\ubca4\ud2b8 \ubc1c\ud589",id:"\uc774\ubca4\ud2b8-\ubc1c\ud589",level:3},{value:"\uc774\ubca4\ud2b8 \uad6c\ub3c5",id:"\uc774\ubca4\ud2b8-\uad6c\ub3c5",level:3},{value:"\ud14c\uc2a4\ud2b8",id:"\ud14c\uc2a4\ud2b8",level:3},{value:"\uacb0\uacfc",id:"\uacb0\uacfc",level:2},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],d={toc:c};function m(e){let{components:t,...l}=e;return(0,a.kt)("wrapper",(0,r.Z)({},d,l,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"\uc774\uc804-\uae00"},"\uc774\uc804 \uae00"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"./route-image-intro"},"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"./route-image-implementation"},"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604")),(0,a.kt)("h2",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,a.kt)("p",null,"\ud604\uc7ac \uc5ec\ud589\uc744 \ub9c8\uce58\ub294 \uacbd\uc6b0, \uac10\uc0c1\uc744 \uc0dd\uc131\ud558\ub294 \uacbd\uc6b0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \uc704\uce58 \uc815\ubcf4\uc758 \uac1c\uc218\uc5d0 \uc815\ube44\ub840\ud558\uc5ec \uc0dd\uc131 \uc2dc\uac04\uc774 \uc99d\uac00\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ube44\ub3d9\uae30\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\uc5ec \uc0ac\uc6a9\uc790\uc758 \uacbd\ud5d8\uc744 \uac1c\uc120\uc2dc\ud0ac \uc218 \uc788\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4. "),(0,a.kt)("h3",{id:"\uc8fc\uae30\ub2a5\uc758-\uc751\ub2f5\uc18d\ub3c4-\uac1c\uc120"},"\uc8fc\uae30\ub2a5\uc758 \uc751\ub2f5\uc18d\ub3c4 \uac1c\uc120"),(0,a.kt)("p",null,"\uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc774 \uc8fc\uae30\ub2a5\uc774\uace0, \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ubd80\uae30\ub2a5\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \ud604\uc7ac \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131\uc758 \uc751\ub2f5 \uc18d\ub3c4\uac00 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uc5ec\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc0ac\uc6a9\uc5d0 \ubb38\uc81c\uac00 \ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc18c\uc694 \uc2dc\uac04\uc774 1\ucd08 \uc774\uc0c1 \uac78\ub9ac\ub294 \uacbd\uc6b0\uac00 \uc874\uc7ac\ud558\uae30\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ube44\ub3d9\uae30 \ucc98\ub9ac\ud558\uace0 \uc5ec\ud589 \uc885\ub8cc\uc640 \uac10\uc0c1 \uc0dd\uc131 \uae30\ub2a5\uc758 \uc751\ub2f5 \uc2dc\uac04\uc744 \uac1c\uc120\ud558\ub294 \uac83\uc774 \ub354 \uc911\uc694\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\ud655\uc7a5\uc131-\ub300\ube44"},"\ud655\uc7a5\uc131 \ub300\ube44"),(0,a.kt)("p",null,"\ud604\uc7ac 10\ubd84 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc11c\ubc84\uc5d0 \uc800\uc7a5\ud558\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc870\uae08 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uadf8\ub9ac\ub294 \uacbd\uc6b0 \ud558\ub098\uc758 \uc5ec\ud589\uc5d0 \ub9ce\uc740 \uc704\uce58 \uc815\ubcf4\uac00 \uc800\uc7a5\ub420 \uc218\ubc16\uc5d0 \uc5c6\uace0 \ub530\ub77c\uc11c \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc5d0 \uac78\ub9ac\ub294 \uc2dc\uac04\uc774 \ub354 \uae38\uc5b4\uc9c8 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ucd94\ud6c4\uc5d0 \ub354 \uc9e7\uc740 \uac04\uaca9\uc73c\ub85c \uc704\uce58 \uc815\ubcf4\ub97c \uc800\uc7a5\ud558\ub294 \uacbd\uc6b0\ub97c \ub300\ube44\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\ub294 \uac83\uc774 \ud569\ub2f9\ud558\ub2e4. "),(0,a.kt)("h2",{id:"\ube44\ub3d9\uae30-\ucc98\ub9ac"},"\ube44\ub3d9\uae30 \ucc98\ub9ac"),(0,a.kt)("p",null,"@Async\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uba54\uc11c\ub4dc\ub97c \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ub9cc\ub4e4 \uc218 \uc788\ub2e4. "),(0,a.kt)("h3",{id:"\ube44\ub3d9\uae30-\uc124\uc815"},"\ube44\ub3d9\uae30 \uc124\uc815"),(0,a.kt)("p",null,"\uc0ac\uc6a9\ud558\uae30 \uc804\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ud558\ub098 \ub9cc\ub4e4\uc5b4\uc11c EnableAsync \uc124\uc815\uc744 \ud574\uc57c\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uc124\uc815\uc744 \uc801\uc6a9\ud558\uba74 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc2e4\ud589\ud558\ub824\ub294 \uba54\uc11c\ub4dc\uc5d0 @Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec\uc8fc\uae30\ub9cc \ud558\uba74 \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="AsyncConfig"',title:'"AsyncConfig"'},"@EnableAsync\n@Configuration\npublic class AsyncConfig {\n}\n")),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \uae30\ubcf8\uc801\uc73c\ub85c \ube44\ub3d9\uae30 \ucc98\ub9ac\ub97c \ud560 \ub54c \ub9e4\ubc88 \uc0c8\ub85c\uc6b4 \uc2a4\ub808\ub4dc\ub97c \uc0dd\uc131\ud558\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ub808\ub4dc \ud480 \uc124\uc815\uc744 \ub530\ub85c \ud574\uc918\uc57c \ud55c\ub2e4. \ud558\uc9c0\ub9cc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \uacbd\uc6b0 ThreadPoolTaskExecutor\ub97c \ub530\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\uc544\ub3c4 \uae30\ubcf8\uc801\uc73c\ub85c \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uac00 \uc0dd\uc131\uc744 \ub3c4\uc640\uc900\ub2e4. "),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing.\n7.7. Task Execution and Scheduling, Spring Boot Docs")),(0,a.kt)("h3",{id:"async-\uc801\uc6a9"},"@Async \uc801\uc6a9"),(0,a.kt)("p",null,"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uae30\uc5d0 Async \uc560\ub108\ud14c\uc774\uc158\uc744 \ubd99\uc5ec \ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub3c4\ub85d \ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="RouteImageGenerator"',title:'"RouteImageGenerator"'},"@Async\npublic void generate(\n List<Double> latitudes,\n List<Double> longitudes,\n List<Double> pointedLatitudes,\n List<Double> pointedLongitudes,\n Long tripId\n) {\n // \uc774\ubbf8\uc9c0 \uc0dd\uc131\n RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);\n Coordinates coordinates = Coordinates.of(latitudes, longitudes);\n Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);\n drawImage(coordinates, routeImageDrawer, pointedCoordinates);\n\n // \uc774\ubbf8\uc9c0 \uc800\uc7a5\n String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());\n\n // \uc790\uc6d0 \ud560\ub2f9 \ud574\uc81c\n routeImageDrawer.dispose();\n\n // \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac12 \ubcc0\uacbd\n Trip trip = tripRepository.findById(tripId)\n .orElseThrow();\n trip.changeRouteImageUrl(imageUrl);\n tripRepository.save(trip);\n}\n")),(0,a.kt)("h3",{id:"\ube44\ub3d9\uae30-\ucc98\ub9ac\uc2dc-\ubb38\uc81c\uc810"},"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc2dc \ubb38\uc81c\uc810"),(0,a.kt)("p",null,"\ud604\uc7ac \uc774\ubbf8\uc9c0 \uc0dd\uc131\uc744 \ud558\uace0 \uc800\uc7a5 \ud6c4, \uc800\uc7a5 \uacbd\ub85c\ub97c DB\uc5d0 \ubc18\uc601\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ud615\ud0dc\uac00 \ub418\uba70 \uc758\uc874\uc131 \ubc29\ud5a5\uc774 \ubb38\uc81c\uac00 \uc0dd\uae34\ub2e4. "),(0,a.kt)("mermaid",{value:"graph LR\n trip[trip: \uc5ec\ud589 \uad00\ub828 \ud328\ud0a4\uc9c0] --\x3e draw[draw: \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc744 \ud3ec\ud568\ud558\uace0 \uc788\ub294 \ud328\ud0a4\uc9c0]\n draw --\x3e trip"}),(0,a.kt)("p",null,"\uc774\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uacfc \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uad6c\uc870\uac00 \ub41c\ub2e4. "),(0,a.kt)("mermaid",{value:"graph LR\n\tsubgraph draw\n\t\tdirection LR\n\t\tRG[RouteImageGenerator] -- DB \ubc18\uc601 \uc694\uccad --\x3e ILR[ImageLinkTripRepository]\n\tend\n subgraph trip\n\t\tdirection LR\n\t\tTS[TripService] -- \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e RG\n\t\tILRI[ImageLinkTripRepositoryImpl] -- \uad6c\ud604 --\x3e ILR\n\tend\n\n\ttrip --\x3e draw"}),(0,a.kt)("p",null,"\ud328\ud0a4\uc9c0 \uac04 \uc758\uc874\uc131\uc740 \ud574\uacb0\ub418\uc5c8\uc9c0\ub9cc, \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5\uc744 \uc704\ud574 tripId\ub97c \ubc1b\uc544\uc57c\ud558\ub294 \ub4f1\uc758 \ub17c\ub9ac\uc801\uc778 \uc758\uc874\uc131\uc740 \uc544\uc9c1 \ud574\uacb0\ub418\uc9c0 \uc54a\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4. "),(0,a.kt)("h2",{id:"\uc774\ubca4\ud2b8-\uc0ac\uc6a9"},"\uc774\ubca4\ud2b8 \uc0ac\uc6a9"),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\uba74 \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc758 \ube44\uad00\uc2ec\uc0ac(ex. \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131)\uc744 \ud6a8\uc728\uc801\uc778 \ubc29\ubc95\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("h3",{id:"\uc774\ubca4\ud2b8-\ubc1c\ud589"},"\uc774\ubca4\ud2b8 \ubc1c\ud589"),(0,a.kt)("p",null,"\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud558\ub824\uba74 \uba3c\uc800 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 ApplicationEventPublisher \uc778\ud130\ud398\uc774\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uc778\ud130\ud398\uc774\uc2a4\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c ApplicationContext\uac00 \uad6c\ud604\ud558\uc5ec \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="TripService & TripUpdateEvent"',title:'"TripService',"&":!0,'TripUpdateEvent"':!0},"public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {\n ...\n\n // \uc774\ubca4\ud2b8 \ubc1c\ud589\n applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));\n}\n\npublic record TripUpdateEvent(Long tripId) {\n}\n")),(0,a.kt)("p",null,"\uc774\ubca4\ud2b8\ub97c \ubc1c\ud589\ud560 \ub54c \ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc774 \uc911\uc694\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\ub294 \ub3c4\uba54\uc778\uc758 \ud589\uc704\ub97c \ub2f4\uace0 \uc788\ub294 \uc774\ubca4\ud2b8\ub97c \ubc1c\ud589(ex. RouteImageGenerateEvent)\ud55c\ub2e4\uba74 \ub17c\ub9ac\uc801\uc778 \uc758\uc874 \uad00\uacc4\uac00 \ub0a8\uc544\uc788\uae30\uc5d0 \uc774\ubca4\ud2b8\ub97c \uc801\uc808\ud788 \uc0ac\uc6a9\ud588\ub2e4\uace0 \ubcf4\uae30 \uc5b4\ub835\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc1c\ud589\ud558\ub294 \uc774\ubca4\ud2b8\uba85\uc740 \uc8fc\uae30\ub2a5\uc774 \uc5b4\ub5a4 \ud589\uc704(ex. TripUpdateEvent)\ub97c \ud588\ub294\uc9c0\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \ub2f4\uaca8\uc788\ub294 \uc774\ubca4\ud2b8\uba85\uc73c\ub85c \ubc1c\ud589\ud558\ub294 \uac83\uc774 \uc911\uc694\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\uc774\ubca4\ud2b8-\uad6c\ub3c5"},"\uc774\ubca4\ud2b8 \uad6c\ub3c5"),(0,a.kt)("p",null,"\uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc2e4\ud589\ud558\ub294 \uba54\uc11c\ub4dc\ub294 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ud558\uae30 \uc704\ud558\uc5ec ",(0,a.kt)("inlineCode",{parentName:"p"},"@Async")," \uc560\ub108\ud14c\uc774\uc158\uc744 \uc801\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubca4\ud2b8\uc758 \uad6c\ub3c5\uc740 \uc5ec\ud589\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \uc885\ub8cc\ub420 \ub54c \uc5ec\ud589\uc5d0 \ub300\ud55c \uc815\ubcf4\ub97c \uac00\uc9c0\uace0 \uacbd\ub85c \uc774\ubbf8\uc9c0\ub97c \uc0dd\uc131\ud558\uae30 \uc704\ud574 ",(0,a.kt)("inlineCode",{parentName:"p"},"@TransactionalEventListener"),"\ub97c \uc0ac\uc6a9\ud588\ub2e4. "),(0,a.kt)("admonition",{title:"TransactionPhase \uc124\uc815",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"TransactionPhase\uc744 \uc0ac\uc6a9\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158 \uc774\ubca4\ud2b8\ub97c \uc5b4\ub5a4 \ub2e8\uacc4\uc5d0\uc11c \uc218\uc2e0\ud558\uace0 \ucc98\ub9ac\ud560\uc9c0\ub97c \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("p",{parentName:"admonition"},"AFTER_COMMIT(\uae30\ubcf8\uac12): \ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ucee4\ubc0b \ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,a.kt)("br",{parentName:"p"}),"\n","AFTER_ROLLBACK: \ud2b8\ub79c\uc7ad\uc158\uc774 \ub864\ubc31\ub418\ub294 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,a.kt)("br",{parentName:"p"}),"\n","AFTER_COMPLETION: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub610\ub294 \ub864\ubc31 \ub418\uc5c8\uc744 \uacbd\uc6b0 \uc774\ubca4\ud2b8 \uc2e4\ud589",(0,a.kt)("br",{parentName:"p"}),"\n","BEFORE_COMMIT: \ud2b8\ub79c\uc7ad\uc158\uc774 \ucee4\ubc0b \ub418\uae30 \uc804 \uc774\ubca4\ud2b8 \uc2e4\ud589 ")),(0,a.kt)("p",null,"\uc774\ubbf8\uc9c0 \uc0dd\uc131\uc758 \uacbd\uc6b0 \ud2b8\ub79c\uc7ad\uc158\uc5d0\uc11c \uc81c\uc678\ud558\uae30 \uc704\ud574 @Transactional \uc560\ub108\ud14c\uc774\uc158\uc744 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="TripUpdateEventHandler"',title:'"TripUpdateEventHandler"'},"@Component\npublic class TripUpdateEventHandler {\n\n private final RouteImageGenerator routeImageGenerator;\n private final TripRepository tripRepository;\n\n public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {\n this.routeImageGenerator = routeImageGenerator;\n this.tripRepository = tripRepository;\n }\n\n @Async\n @TransactionalEventListener(phase = AFTER_COMMIT)\n public void handle(TripUpdateEvent tripUpdateEvent) {\n Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());\n\n String imageUrl = routeImageGenerator.generate(\n trip.getLatitudes(),\n trip.getLongitudes(),\n trip.getPointedLatitudes(),\n trip.getPointedLongitudes()\n );\n\n trip.changeRouteImageUrl(imageUrl);\n tripRepository.save(trip);\n }\n}\n")),(0,a.kt)("p",null,"\uc774\ubca4\ud2b8\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c\uc368 \ud328\ud0a4\uc9c0 \uac04 \uc21c\ud658 \ucc38\uc870 \ubb38\uc81c\uac00 \ub2e4\uc74c\uacfc \uac19\uc774 \ud574\uacb0\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \uc8fc\uae30\ub2a5\uacfc \ubd80\uae30\ub2a5\uc744 \ubd84\ub9ac\ud568\uc73c\ub85c\uc368 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc5d0 \ub300\ud55c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\ucd94\uc5c8\ub2e4."),(0,a.kt)("mermaid",{value:"graph LR\n subgraph trip\n TripServcie -- \ubc1c\ud589 --\x3e TripUpdateEvent\n TripRepository\n end\n\n subgraph draw\n TripUpdateEventHandler -- \uad6c\ub3c5 \ud6c4 \uc774\ubbf8\uc9c0 \uc0dd\uc131 --\x3e TripUpdateEvent\n TripUpdateEventHandler -- \uc0dd\uc131\ub41c \uc774\ubbf8\uc9c0 \uacbd\ub85c \uc800\uc7a5 --\x3e TripRepository\n end"}),(0,a.kt)("h3",{id:"\ud14c\uc2a4\ud2b8"},"\ud14c\uc2a4\ud2b8"),(0,a.kt)("p",null,"\ube44\ub3d9\uae30\ub85c \ub3d9\uc791\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud14c\uc2a4\ud2b8\ud558\uae30 \uc704\ud574\uc11c\ub294 \uc544\ub798\uc640 \uac19\uc740 \ubc29\ubc95\uc774 \uc788\ub2e4. "),(0,a.kt)(i.Z,{mdxType:"Tabs"},(0,a.kt)(o.Z,{value:"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d",label:"\ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \uc885\ub8cc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30 \ud6c4 \uac80\uc99d",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@SpringBootTest\npublic class TripUpdateEventHandlerIntegrationTest {\n\n ...\n\n @Test\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\n // given\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\n .willReturn(\uc5ec\ud589());\n\n // when\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\n\n // then\n then(routeImageGenerator)\n .should(Mockito.timeout(5000).times(1))\n .generate(any(), any(), any(), any());\n }\n}\n"))),(0,a.kt)(o.Z,{value:"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d",label:"\ud14c\uc2a4\ud2b8 \ud560 \ub54c\ub9cc \ube44\ub3d9\uae30\ub97c \ub3d9\uae30\ub85c \ubcc0\uacbd\ud558\uc5ec \uac80\uc99d",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@ContextConfiguration(classes = TestSyncConfig.class)\n@SpringBootTest\npublic class TripUpdateEventHandlerIntegrationTest {\n\n ...\n\n @Test\n void \uc5ec\ud589\uc218\uc815_\uc774\ubca4\ud2b8\ub97c_\ubc1c\uc0dd\uc2dc\ud0a4\uba74_\uc774\ubbf8\uc9c0\ub97c_\uc0dd\uc131_\uc694\uccad\uc744_\ud55c\ub2e4() {\n // given\n TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);\n given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))\n .willReturn(\uc5ec\ud589());\n\n // when\n transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));\n\n // then\n then(routeImageGenerator)\n .should(times(1))\n .generate(any(), any(), any(), any());\n }\n}\n")))),(0,a.kt)("p",null,"\ucc98\uc74c\uc5d0\ub294 \ud14c\uc2a4\ud2b8\uc5d0\uc11c\ub9cc \ub3d9\uae30\ub85c \uc124\uc815 \ud6c4 \uac80\uc99d\ud558\ub824\uace0 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud1b5\ud569 \ud14c\uc2a4\ud2b8\uc5d0\uc120 ",(0,a.kt)("inlineCode",{parentName:"p"},"\ud2b8\ub79c\uc7ad\uc158\uc774 \uc815\uc0c1 \uc885\ub8cc\ub418\uc5c8\uc744 \ub54c \ube44\ub3d9\uae30\ub85c \uc774\ubca4\ud2b8\ub97c \uad6c\ub3c5\ud558\uc5ec \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud558\ub294\uc9c0")," \uac80\uc99d\uc774 \ud544\uc694\ud588\uae30 \ub54c\ubb38\uc5d0 \ucd5c\uc885\uc801\uc73c\ub85c ",(0,a.kt)("inlineCode",{parentName:"p"},"Mockito.timeout")," \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\uac00 \ud1b5\uacfc\ub420 \ub54c\uae4c\uc9c0 \ub300\uae30\ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4. "),(0,a.kt)("h2",{id:"\uacb0\uacfc"},"\uacb0\uacfc"),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./time.png",src:n(89297).Z,width:"1682",height:"678"})),(0,a.kt)("p",null,"\uc704 \uc751\ub2f5 \uc2dc\uac04\uc740 \uc704\uce58 \uc815\ubcf4 1000\uac1c\ub97c \uae30\uc900\uc73c\ub85c \ud14c\uc2a4\ud2b8\ud55c \uac12\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc751\ub2f5 \uc2dc\uac04\uc5d0 \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uc2dc\uac04\uc774 \ud3ec\ud568\ub418\uc9c0 \uc54a\uc544\uc11c \uc131\ub2a5\uc774 \uac1c\uc120\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. "),(0,a.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.task-execution-and-scheduling"},"7.7. Task Execution and Scheduling, Spring Boot Docs"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.baeldung.com/spring-events"},"Spring Events, Baeldung"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://techblog.woowahan.com/7835/"},"\ud68c\uc6d0\uc2dc\uc2a4\ud15c \uc774\ubca4\ud2b8\uae30\ubc18 \uc544\ud0a4\ud14d\ucc98 \uad6c\ucd95\ud558\uae30")))}m.isMDXComponent=!0},89297:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/time-8bef9a6cf2dcace85f12ae5624da94f5.png"}}]); \ No newline at end of file diff --git a/assets/js/d6638f30.965323b3.js b/assets/js/d6638f30.965323b3.js deleted file mode 100644 index 4cd59f0d3..000000000 --- a/assets/js/d6638f30.965323b3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3476],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),s=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},m=function(e){var t=s(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,i=e.parentName,m=p(e,["components","mdxType","originalType","parentName"]),d=s(r),u=o,y=d["".concat(i,".").concat(u)]||d[u]||c[u]||a;return r?n.createElement(y,l(l({ref:t},m),{},{components:r})):n.createElement(y,l({ref:t},m))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=d;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:o,l[1]=p;for(var s=2;s<a;s++)l[s]=r[s];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},54336:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>a,metadata:()=>p,toc:()=>s});var n=r(87462),o=(r(67294),r(3905));const a={title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",slug:"/deploy/zero-downtime",last_update:{date:"2023/09/24"},tags:["deploy","zero-downtime"]},l=void 0,p={unversionedId:"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec",id:"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec",title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",description:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",source:"@site/docs/\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec.mdx",sourceDirName:"\ubc30\ud3ec",slug:"/deploy/zero-downtime",permalink:"/docs/deploy/zero-downtime",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec.mdx",tags:[{label:"deploy",permalink:"/docs/tags/deploy"},{label:"zero-downtime",permalink:"/docs/tags/zero-downtime"}],version:"current",lastUpdatedAt:1695513600,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 24\uc77c",frontMatter:{title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",slug:"/deploy/zero-downtime",last_update:{date:"2023/09/24"},tags:["deploy","zero-downtime"]},sidebar:"tutorialSidebar",previous:{title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",permalink:"/docs/culture/postmortem"},next:{title:"\ud328\ud0a4\uc9c0",permalink:"/docs/design/package"}},i={},s=[{value:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",id:"\ubb34\uc911\ub2e8-\ubc30\ud3ec",level:3},{value:"\ub864\ub9c1 \ubc30\ud3ec(Rolling Deployment)",id:"\ub864\ub9c1-\ubc30\ud3ecrolling-deployment",level:3},{value:"\ube14\ub8e8 \uadf8\ub9b0 \ubc30\ud3ec(Blue/Green Deployment)",id:"\ube14\ub8e8-\uadf8\ub9b0-\ubc30\ud3ecbluegreen-deployment",level:3},{value:"\uce74\ub098\ub9ac \ubc30\ud3ec(Canary Deployment)",id:"\uce74\ub098\ub9ac-\ubc30\ud3eccanary-deployment",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],m={toc:s};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"\ubb34\uc911\ub2e8-\ubc30\ud3ec"},"\ubb34\uc911\ub2e8 \ubc30\ud3ec"),(0,o.kt)("p",null,"\uc6b4\uc601\uc911\uc778 \uc11c\ubc84\ub97c \uc911\ub2e8\ud558\uc9c0 \uc54a\uace0, \uc0c8\ub85c\uc6b4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ubc30\ud3ec\ud558\ub294 \uac83",(0,o.kt)("br",{parentName:"p"}),"\n","\ub85c\ub4dc\ubc38\ub7f0\uc11c\ub97c \ud1b5\ud574 \ud2b8\ub798\ud53d\uc744 \uc81c\uc5b4\ud558\ub294 \ubc29\ubc95\uc73c\ub85c \ubc30\ud3ec\ud560 \uc218 \uc788\ub2e4. "),(0,o.kt)("h3",{id:"\ub864\ub9c1-\ubc30\ud3ecrolling-deployment"},"\ub864\ub9c1 \ubc30\ud3ec(Rolling Deployment)"),(0,o.kt)("p",null,"\uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \uc2e4\ud589\ub418\ub294 \ud658\uacbd\uc744 \uc644\uc804\ud788 \uc804\ud658\ud558\uc5ec, \uc774\uc804 \ubc84\uc804\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc73c\ub85c \uc810\uc9c4\uc801\uc73c\ub85c \ub300\uccb4\ud558\ub294 \uc804\ub7b5\uc774\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ub864\ub9c1 \ubc30\ud3ec\ub294 \uc77c\ubc18\uc801\uc73c\ub85c \ube14\ub8e8/\uadf8\ub9b0 \ubc30\ud3ec\ubcf4\ub2e4 \ube60\ub974\uc9c0\ub9cc, \ube14\ub8e8/\uadf8\ub9b0 \ubc30\ud3ec\uc640 \ub2ec\ub9ac \uaca9\ub9ac\ub41c \ud658\uacbd\uc5d0\uc11c \ubc30\ud3ec\uac00 \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\ub294\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uaca9\ub9ac\ub41c \ud658\uacbd\uc5d0\uc11c \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0, \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc774 \uc774\uc804 \ubc84\uc804\uacfc \ud638\ud658\uc774 \ub418\uc9c0 \uc54a\ub294\ub2e4\uba74 \ubc30\ud3ec \uc2dc\uc810\uc5d0 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uac70\ub098, \ubc30\ud3ec \uc2e4\ud328\uc2dc \ub864\ubc31\uc744 \ud558\uae30 \uc5b4\ub824\uc6cc\uc9c8 \uc218 \uc788\ub2e4. "),(0,o.kt)("h3",{id:"\ube14\ub8e8-\uadf8\ub9b0-\ubc30\ud3ecbluegreen-deployment"},"\ube14\ub8e8 \uadf8\ub9b0 \ubc30\ud3ec(Blue/Green Deployment)"),(0,o.kt)("p",null,"\ube14\ub8e8\ub97c \uc774\uc804 \ubc84\uc804, \uadf8\ub9b0\uc744 \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc73c\ub85c \uad6c\uc131\ud55c \ud6c4, \ub85c\ub4dc\ubc38\ub7f0\uc11c\ub97c \uc774\uc6a9\ud558\uc5ec \uadf8\ub9b0\uc73c\ub85c \ud2b8\ub798\ud53d\uc744 \uc804\ud658\ud558\ub294 \ubc30\ud3ec \ubc29\uc2dd\uc774\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ubc30\ud3ec\uac00 \uc2e4\ud328\ud560 \uacbd\uc6b0, \uac04\ub2e8\ud558\uac8c \ub864\ubc31\uc744 \ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \ubc30\ud3ec \uc704\ud5d8\uc744 \uc904\uc77c \uc218 \uc788\uc9c0\ub9cc \uc2dc\uc2a4\ud15c \uc790\uc6d0\uc774 \ub450 \ubc30\ub85c \ud544\uc694\ud558\ub2e4\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4. "),(0,o.kt)("h3",{id:"\uce74\ub098\ub9ac-\ubc30\ud3eccanary-deployment"},"\uce74\ub098\ub9ac \ubc30\ud3ec(Canary Deployment)"),(0,o.kt)("p",null,"\uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ub2e8\uacc4\uc801\uc73c\ub85c \ubc30\ud3ec\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc704\ud5d8\uc744 \uc54c\ub824\uc8fc\ub294 \uce74\ub098\ub9ac\uc544 \uc0c8\ub97c \ud0c4\uad11\uc5d0 \uba3c\uc800 \ubcf4\ub0b4\ub294 \uac83 \ucc98\ub7fc, \uc77c\uc815 \ube44\uc728\uc744 \uba3c\uc800 \uc2e0\ubc84\uc804\uc73c\ub85c \uc804\ud658\ud558\uace0 \ubb38\uc81c\uac00 \uc5c6\ub294 \uacbd\uc6b0 \ub298\ub824\ub098\uac00\ub294 \ud615\ud0dc\ub85c \ubc30\ud3ec\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uce74\ub098\ub9ac\ub294 \ud14c\uc2a4\ud2b8\uac00 \ubd80\uc871\ud558\uac70\ub098 \uc2e0\ub8b0\ud560 \uc218 \uc5c6\ub294 \uacbd\uc6b0, \uc0c8 \ub9b4\ub9ac\uc2a4\uc758 \uc548\uc815\uc131\uc5d0 \ub300\ud55c \ud655\uc2e0\uc774 \uc5c6\ub294 \uacbd\uc6b0\uc5d0 \uc8fc\ub85c \uc0ac\uc6a9\ub41c\ub2e4. "),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://www.samsungsds.com/kr/insights/1256264_4627.html"},"\ubb34\uc911\ub2e8 \ubc30\ud3ec \uc544\ud0a4\ud14d\ucc98, SAMSUNG SDS"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/rolling-deployments.html"},"Rolling Deployments, AWS"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://codefresh.io/learn/software-deployment/"},"Software Deployment, codefresh"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://blog.container-solutions.com/deployment-strategies"},"Deployment Strategies, Etienne Tremel")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d6638f30.a35df1f5.js b/assets/js/d6638f30.a35df1f5.js new file mode 100644 index 000000000..54a756691 --- /dev/null +++ b/assets/js/d6638f30.a35df1f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3476],{36022:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>p,frontMatter:()=>l,metadata:()=>i,toc:()=>c});var r=n(85893),o=n(3905);const l={title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",slug:"/deploy/zero-downtime",last_update:{date:"2023/09/24"},tags:["deploy","zero-downtime"]},s=void 0,i={id:"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec",title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",description:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",source:"@site/docs/\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec.mdx",sourceDirName:"\ubc30\ud3ec",slug:"/deploy/zero-downtime",permalink:"/docs/deploy/zero-downtime",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec.mdx",tags:[{label:"deploy",permalink:"/docs/tags/deploy"},{label:"zero-downtime",permalink:"/docs/tags/zero-downtime"}],version:"current",lastUpdatedAt:1695513600,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 24\uc77c",frontMatter:{title:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",slug:"/deploy/zero-downtime",last_update:{date:"2023/09/24"},tags:["deploy","zero-downtime"]},sidebar:"tutorialSidebar",previous:{title:"\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c",permalink:"/docs/culture/postmortem"},next:{title:"\ud328\ud0a4\uc9c0",permalink:"/docs/design/package"}},a={},c=[{value:"\ubb34\uc911\ub2e8 \ubc30\ud3ec",id:"\ubb34\uc911\ub2e8-\ubc30\ud3ec",level:3},{value:"\ub864\ub9c1 \ubc30\ud3ec(Rolling Deployment)",id:"\ub864\ub9c1-\ubc30\ud3ecrolling-deployment",level:3},{value:"\ube14\ub8e8 \uadf8\ub9b0 \ubc30\ud3ec(Blue/Green Deployment)",id:"\ube14\ub8e8-\uadf8\ub9b0-\ubc30\ud3ecbluegreen-deployment",level:3},{value:"\uce74\ub098\ub9ac \ubc30\ud3ec(Canary Deployment)",id:"\uce74\ub098\ub9ac-\ubc30\ud3eccanary-deployment",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={a:"a",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"\ubb34\uc911\ub2e8-\ubc30\ud3ec",children:"\ubb34\uc911\ub2e8 \ubc30\ud3ec"}),"\n",(0,r.jsxs)(t.p,{children:["\uc6b4\uc601\uc911\uc778 \uc11c\ubc84\ub97c \uc911\ub2e8\ud558\uc9c0 \uc54a\uace0, \uc0c8\ub85c\uc6b4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ubc30\ud3ec\ud558\ub294 \uac83",(0,r.jsx)(t.br,{}),"\n","\ub85c\ub4dc\ubc38\ub7f0\uc11c\ub97c \ud1b5\ud574 \ud2b8\ub798\ud53d\uc744 \uc81c\uc5b4\ud558\ub294 \ubc29\ubc95\uc73c\ub85c \ubc30\ud3ec\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ub864\ub9c1-\ubc30\ud3ecrolling-deployment",children:"\ub864\ub9c1 \ubc30\ud3ec(Rolling Deployment)"}),"\n",(0,r.jsxs)(t.p,{children:["\uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc774 \uc2e4\ud589\ub418\ub294 \ud658\uacbd\uc744 \uc644\uc804\ud788 \uc804\ud658\ud558\uc5ec, \uc774\uc804 \ubc84\uc804\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc73c\ub85c \uc810\uc9c4\uc801\uc73c\ub85c \ub300\uccb4\ud558\ub294 \uc804\ub7b5\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub864\ub9c1 \ubc30\ud3ec\ub294 \uc77c\ubc18\uc801\uc73c\ub85c \ube14\ub8e8/\uadf8\ub9b0 \ubc30\ud3ec\ubcf4\ub2e4 \ube60\ub974\uc9c0\ub9cc, \ube14\ub8e8/\uadf8\ub9b0 \ubc30\ud3ec\uc640 \ub2ec\ub9ac \uaca9\ub9ac\ub41c \ud658\uacbd\uc5d0\uc11c \ubc30\ud3ec\uac00 \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\ub294\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uaca9\ub9ac\ub41c \ud658\uacbd\uc5d0\uc11c \uc774\ub8e8\uc5b4\uc9c0\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0, \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc774 \uc774\uc804 \ubc84\uc804\uacfc \ud638\ud658\uc774 \ub418\uc9c0 \uc54a\ub294\ub2e4\uba74 \ubc30\ud3ec \uc2dc\uc810\uc5d0 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uac70\ub098, \ubc30\ud3ec \uc2e4\ud328\uc2dc \ub864\ubc31\uc744 \ud558\uae30 \uc5b4\ub824\uc6cc\uc9c8 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ube14\ub8e8-\uadf8\ub9b0-\ubc30\ud3ecbluegreen-deployment",children:"\ube14\ub8e8 \uadf8\ub9b0 \ubc30\ud3ec(Blue/Green Deployment)"}),"\n",(0,r.jsxs)(t.p,{children:["\ube14\ub8e8\ub97c \uc774\uc804 \ubc84\uc804, \uadf8\ub9b0\uc744 \uc0c8\ub85c\uc6b4 \ubc84\uc804\uc73c\ub85c \uad6c\uc131\ud55c \ud6c4, \ub85c\ub4dc\ubc38\ub7f0\uc11c\ub97c \uc774\uc6a9\ud558\uc5ec \uadf8\ub9b0\uc73c\ub85c \ud2b8\ub798\ud53d\uc744 \uc804\ud658\ud558\ub294 \ubc30\ud3ec \ubc29\uc2dd\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ubc30\ud3ec\uac00 \uc2e4\ud328\ud560 \uacbd\uc6b0, \uac04\ub2e8\ud558\uac8c \ub864\ubc31\uc744 \ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \ubc30\ud3ec \uc704\ud5d8\uc744 \uc904\uc77c \uc218 \uc788\uc9c0\ub9cc \uc2dc\uc2a4\ud15c \uc790\uc6d0\uc774 \ub450 \ubc30\ub85c \ud544\uc694\ud558\ub2e4\ub294 \ub2e8\uc810\uc774 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\uce74\ub098\ub9ac-\ubc30\ud3eccanary-deployment",children:"\uce74\ub098\ub9ac \ubc30\ud3ec(Canary Deployment)"}),"\n",(0,r.jsxs)(t.p,{children:["\uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ub2e8\uacc4\uc801\uc73c\ub85c \ubc30\ud3ec\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc704\ud5d8\uc744 \uc54c\ub824\uc8fc\ub294 \uce74\ub098\ub9ac\uc544 \uc0c8\ub97c \ud0c4\uad11\uc5d0 \uba3c\uc800 \ubcf4\ub0b4\ub294 \uac83 \ucc98\ub7fc, \uc77c\uc815 \ube44\uc728\uc744 \uba3c\uc800 \uc2e0\ubc84\uc804\uc73c\ub85c \uc804\ud658\ud558\uace0 \ubb38\uc81c\uac00 \uc5c6\ub294 \uacbd\uc6b0 \ub298\ub824\ub098\uac00\ub294 \ud615\ud0dc\ub85c \ubc30\ud3ec\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uce74\ub098\ub9ac\ub294 \ud14c\uc2a4\ud2b8\uac00 \ubd80\uc871\ud558\uac70\ub098 \uc2e0\ub8b0\ud560 \uc218 \uc5c6\ub294 \uacbd\uc6b0, \uc0c8 \ub9b4\ub9ac\uc2a4\uc758 \uc548\uc815\uc131\uc5d0 \ub300\ud55c \ud655\uc2e0\uc774 \uc5c6\ub294 \uacbd\uc6b0\uc5d0 \uc8fc\ub85c \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://www.samsungsds.com/kr/insights/1256264_4627.html",children:"\ubb34\uc911\ub2e8 \ubc30\ud3ec \uc544\ud0a4\ud14d\ucc98, SAMSUNG SDS"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://docs.aws.amazon.com/whitepapers/latest/overview-deployment-options/rolling-deployments.html",children:"Rolling Deployments, AWS"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://codefresh.io/learn/software-deployment/",children:"Software Deployment, codefresh"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://blog.container-solutions.com/deployment-strategies",children:"Deployment Strategies, Etienne Tremel"})]})]})}function p(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>c});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function i(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var a=r.createContext({}),c=function(e){var t=r.useContext(a),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},p=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,l=e.originalType,a=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(n),u=o,y=m["".concat(a,".").concat(u)]||m[u]||d[u]||l;return n?r.createElement(y,s(s({ref:t},p),{},{components:n})):r.createElement(y,s({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/d6a3d698.f4578e6a.js b/assets/js/d6a3d698.a57e5d29.js similarity index 87% rename from assets/js/d6a3d698.f4578e6a.js rename to assets/js/d6a3d698.a57e5d29.js index ed28ea1fd..a7a666235 100644 --- a/assets/js/d6a3d698.f4578e6a.js +++ b/assets/js/d6a3d698.a57e5d29.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2890],{39477:e=>{e.exports=JSON.parse('{"label":"image","permalink":"/tags/image","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2890],{39477:e=>{e.exports=JSON.parse('{"label":"image","permalink":"/tags/image","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/d7955594.19c09353.js b/assets/js/d7955594.19c09353.js deleted file mode 100644 index ddd598b67..000000000 --- a/assets/js/d7955594.19c09353.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[588],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>d});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function i(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?l(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):l(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},l=Object.keys(e);for(r=0;r<l.length;r++)t=l[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)t=l[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var u=r.createContext({}),c=function(e){var n=r.useContext(u),t=n;return e&&(t="function"==typeof e?e(n):i(i({},n),e)),t},p=function(e){var n=c(e.components);return r.createElement(u.Provider,{value:n},e.children)},s={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},m=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,l=e.originalType,u=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=c(t),d=a,f=m["".concat(u,".").concat(d)]||m[d]||s[d]||l;return t?r.createElement(f,i(i({ref:n},p),{},{components:t})):r.createElement(f,i({ref:n},p))}));function d(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var l=t.length,i=new Array(l);i[0]=m;var o={};for(var u in n)hasOwnProperty.call(n,u)&&(o[u]=n[u]);o.originalType=e,o.mdxType="string"==typeof e?e:a,i[1]=o;for(var c=2;c<l;c++)i[c]=t[c];return r.createElement.apply(null,i)}return r.createElement.apply(null,t)}m.displayName="MDXCreateElement"},85162:(e,n,t)=>{t.d(n,{Z:()=>i});var r=t(67294),a=t(86010);const l="tabItem_Ymn6";function i(e){let{children:n,hidden:t,className:i}=e;return r.createElement("div",{role:"tabpanel",className:(0,a.Z)(l,i),hidden:t},n)}},74866:(e,n,t)=>{t.d(n,{Z:()=>w});var r=t(87462),a=t(67294),l=t(86010),i=t(12466),o=t(16550),u=t(91980),c=t(67392),p=t(50012);function s(e){return function(e){return a.Children.map(e,(e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:a}}=e;return{value:n,label:t,attributes:r,default:a}}))}function m(e){const{values:n,children:t}=e;return(0,a.useMemo)((()=>{const e=n??s(t);return function(e){const n=(0,c.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function d(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function f(e){let{queryString:n=!1,groupId:t}=e;const r=(0,o.k6)(),l=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,u._X)(l),(0,a.useCallback)((e=>{if(!l)return;const n=new URLSearchParams(r.location.search);n.set(l,e),r.replace({...r.location,search:n.toString()})}),[l,r])]}function g(e){const{defaultValue:n,queryString:t=!1,groupId:r}=e,l=m(e),[i,o]=(0,a.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!d({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:l}))),[u,c]=f({queryString:t,groupId:r}),[s,g]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[r,l]=(0,p.Nk)(t);return[r,(0,a.useCallback)((e=>{t&&l.set(e)}),[t,l])]}({groupId:r}),S=(()=>{const e=u??s;return d({value:e,tabValues:l})?e:null})();(0,a.useLayoutEffect)((()=>{S&&o(S)}),[S]);return{selectedValue:i,selectValue:(0,a.useCallback)((e=>{if(!d({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);o(e),c(e),g(e)}),[c,g,l]),tabValues:l}}var S=t(72389);const b="tabList__CuJ",y="tabItem_LNqP";function v(e){let{className:n,block:t,selectedValue:o,selectValue:u,tabValues:c}=e;const p=[],{blockElementScrollPositionUntilNextRender:s}=(0,i.o5)(),m=e=>{const n=e.currentTarget,t=p.indexOf(n),r=c[t].value;r!==o&&(s(n),u(r))},d=e=>{let n=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const t=p.indexOf(e.currentTarget)+1;n=p[t]??p[0];break}case"ArrowLeft":{const t=p.indexOf(e.currentTarget)-1;n=p[t]??p[p.length-1];break}}n?.focus()};return a.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":t},n)},c.map((e=>{let{value:n,label:t,attributes:i}=e;return a.createElement("li",(0,r.Z)({role:"tab",tabIndex:o===n?0:-1,"aria-selected":o===n,key:n,ref:e=>p.push(e),onKeyDown:d,onClick:m},i,{className:(0,l.Z)("tabs__item",y,i?.className,{"tabs__item--active":o===n})}),t??n)})))}function E(e){let{lazy:n,children:t,selectedValue:r}=e;const l=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=l.find((e=>e.props.value===r));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return a.createElement("div",{className:"margin-top--md"},l.map(((e,n)=>(0,a.cloneElement)(e,{key:n,hidden:e.props.value!==r}))))}function h(e){const n=g(e);return a.createElement("div",{className:(0,l.Z)("tabs-container",b)},a.createElement(v,(0,r.Z)({},e,n)),a.createElement(E,(0,r.Z)({},e,n)))}function w(e){const n=(0,S.Z)();return a.createElement(h,(0,r.Z)({key:String(n)},e))}},89788:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>p,contentTitle:()=>u,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>s});var r=t(87462),a=(t(67294),t(3905)),l=t(74866),i=t(85162);const o={title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",slug:"custom-jdbc-template",tags:["JDBC","Java"]},u=void 0,c={permalink:"/custom-jdbc-template",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",source:"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",description:"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.",date:"2023-04-02T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 2\uc77c",tags:[{label:"JDBC",permalink:"/tags/jdbc"},{label:"Java",permalink:"/tags/java"}],readingTime:9.025,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",slug:"custom-jdbc-template",tags:["JDBC","Java"]},prevItem:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",permalink:"/java-class-file"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",permalink:"/woowacourse-level1-retrospective"}},p={authorsImageUrls:[]},s=[{value:"\uae30\uc874 \ucf54\ub4dc",id:"\uae30\uc874-\ucf54\ub4dc",level:3},{value:"SELECT, DELETE \uc911\ubcf5 \uc81c\uac70",id:"select-delete-\uc911\ubcf5-\uc81c\uac70",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---1-\ucf5c\ubc31\uc744-\uc704\ud55c-\uc778\ud130\ud398\uc774\uc2a4-\uc815\uc758",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---2-\ub2e8\uac74-\uc870\ud68c",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---3-\ub2e4\uac74-\uc870\ud68c",level:3},{value:"\uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30",id:"\uc81c\ub124\ub9ad-\uc0ac\uc6a9\ud558\uae30",level:3},{value:"\uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30",id:"\uba54\uc11c\ub4dc-\ubd84\ub9ac\ud55c-\ubd80\ubd84-\ud074\ub798\uc2a4\ub85c-\ubd84\ub9ac\ud558\uae30--optional-\uc0ac\uc6a9\ud558\uae30",level:3}],m={toc:s};function d(e){let{components:n,...t}=e;return(0,a.kt)("wrapper",(0,r.Z)({},m,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c JDBC\ub97c \uc0ac\uc6a9\ud560 \ub54c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 \ucee4\ub125\uc158\uc744 \uc5bb\uace0, try-with-resource\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc774 \ubc18\ubcf5\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc774\uc6a9\ud558\uc5ec \ub098\ub9cc\uc758 JdbcTemplate\uc744 \ub9cc\ub4e4\uc5b4\ubcf4\uc558\ub2e4. "),(0,a.kt)("h3",{id:"\uae30\uc874-\ucf54\ub4dc"},"\uae30\uc874 \ucf54\ub4dc"),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(i.Z,{value:"User",label:"User",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public class User {\n private final int id;\n private final String name;\n\n public User(final int id, final String name) {\n this.id = id;\n this.name = name;\n }\n\n public int getId() {\n return id;\n }\n\n public String getName() {\n return name;\n }\n}\n"))),(0,a.kt)(i.Z,{value:"UserDao",label:"UserDao",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public class UserDao {\n private final ConnectionPool connectionPool;\n\n public UserDao(final ConnectionPool connectionPool) {\n this.connectionPool = connectionPool;\n }\n\n public void insert(final String name) {\n final Connection connection = connectionPool.getConnection();\n final String query = "INSERT INTO User (name) VALUES (?)";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setString(1, name);\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public void delete(final int userId) {\n final Connection connection = connectionPool.getConnection();\n final String query = "DELETE FROM user WHERE id = ?";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setInt(1, userId);\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public User findById(final int userId) {\n final Connection connection = connectionPool.getConnection();\n final String query = "SELECT * FROM user WHERE id = ?";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setInt(1, userId);\n final ResultSet resultSet = preparedStatement.executeQuery();\n if (resultSet.next()) {\n return new User(\n resultSet.getInt("id"),\n resultSet.getString("name")\n );\n }\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n return null;\n }\n\n public List<User> findAll() {\n final Connection connection = connectionPool.getConnection();\n final String query = "SELECT * FROM user";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n final ResultSet resultSet = preparedStatement.executeQuery();\n final List<User> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(new User(\n resultSet.getInt("id"),\n resultSet.getString("name")\n ));\n }\n return result;\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n}\n'))),(0,a.kt)(i.Z,{value:"ConnectionPool",label:"ConnectionPool",mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public class ConnectionPool {\n private static final String SERVER = "localhost:13306";\n private static final String DATABASE = "chess";\n private static final String OPTION = "?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";\n private static final String URL = "jdbc:mysql://" + SERVER + "/" + DATABASE + OPTION;\n private static final String USERNAME = "root";\n private static final String PASSWORD = "root";\n\n private final AtomicInteger index = new AtomicInteger();\n private final List<Connection> connections;\n\n public ConnectionPool(final int connectionCount) {\n connections = generateConnections(connectionCount);\n }\n\n private List<Connection> generateConnections(final int connectionCount) {\n return Stream.generate(this::generateConnection)\n .limit(connectionCount)\n .collect(toList());\n }\n\n private Connection generateConnection() {\n try {\n return DriverManager.getConnection(URL, USERNAME, PASSWORD);\n } catch (SQLException e) {\n throw new IllegalStateException("\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.");\n }\n }\n\n public Connection getConnection() {\n int currentIndex = index.getAndIncrement();\n return connections.get(currentIndex % connections.size());\n }\n}\n')))),(0,a.kt)("h3",{id:"select-delete-\uc911\ubcf5-\uc81c\uac70"},"SELECT, DELETE \uc911\ubcf5 \uc81c\uac70"),(0,a.kt)("p",null,"\ubcc0\ud558\uc9c0 \uc54a\ub294 \ubd80\ubd84: try-with-resource, preparedStatement\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84, executeUpdate\ub85c \uc2e4\ud589 \ub4f1\ub4f1",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcc0\ud558\ub294 \ubd80\ubd84: SQL Query, \ub9e4\uac1c\ubcc0\uc218 "),(0,a.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\ub294 \ubd80\ubd84\uc744 \ubd84\ub9ac\ud558\uace0 \uac00\ubcc0\uc778\uc218\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 SELECT\uc640 DELETE\uc758 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public void insert(final String name) {\n final String query = "INSERT INTO User (name) VALUES (?)";\n executeUpdate(query, name);\n}\n\npublic void delete(final int userId) {\n final String query = "DELETE FROM user WHERE user_id = ?";\n executeUpdate(query, userId);\n}\n\nprivate void executeUpdate(final String query, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n')),(0,a.kt)("h3",{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---1-\ucf5c\ubc31\uc744-\uc704\ud55c-\uc778\ud130\ud398\uc774\uc2a4-\uc815\uc758"},"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758"),(0,a.kt)("p",null,"\uc870\ud68c\ub294 INSERT, DELETE\uc640 \ub2ec\ub9ac \uac12\uc744 \ubc18\ud658\ubc1b\uc544\uc57c \ud558\uae30 \ub54c\ubb38\uc5d0 \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ub54c \ucf5c\ubc31\uc774\ub77c\ub294 \uac83\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4. "),(0,a.kt)("admonition",{title:"\ucf5c\ubc31(Callback)",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"\ud504\ub85c\uadf8\ub798\ubc0d\uc5d0\uc11c \ucf5c\ubc31\uc740 \ub2e4\ub978 \ucf54\ub4dc\uc758 \uc778\uc218\ub85c \ub118\uaca8\uc8fc\ub294 \uc2e4\ud589 \uac00\ub2a5\ud55c \ucf54\ub4dc\ub97c \ub73b\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\ubc14\uc5d0\uc11c\ub294 \ub78c\ub2e4\ub098 \uc775\uba85 \ud074\ub798\uc2a4\ub97c \ub118\uaca8\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("mermaid",{parentName:"admonition",value:"flowchart LR\n \ud074\ub77c\uc774\uc5b8\ud2b8 -- \ucf5c\ubc31\uc804\ub2ec --\x3e \uba54\uc11c\ub4dc\n \uba54\uc11c\ub4dc -- \ub0b4\ubd80\ud638\ucd9c --\x3e \uc804\ub2ec\ubc1b\uc740\ucf5c\ubc31"})),(0,a.kt)("p",null,"\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uc870\ud68c\ud558\uace0, \ud574\ub2f9 \uac12\uc744 \uac1d\uccb4\ub85c \ub9e4\ud551\ud558\uc5ec \uac12\uc744 \ubc18\ud658\ud574\uc57c \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","executeQuery\ub85c \uc870\ud68c\ud55c \uac12\uc740 ResultSet \uc548\uc5d0 \ub4e4\uc5b4\uac00\uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c \uc6d0\ud558\ub294 \ud0c0\uc785\uc758 \uac12\uc73c\ub85c \ubcc0\ud658\ud574\uc57c\ud558\ub2c8 \uc77c\ub2e8 \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@FunctionalInterface\npublic interface RowMapper {\n User mapRow(final ResultSet resultSet) throws SQLException;\n}\n")),(0,a.kt)("h3",{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---2-\ub2e8\uac74-\uc870\ud68c"},"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c"),(0,a.kt)("p",null,"\uc704\uc5d0\uc11c \uc815\uc758\ud55c RowMapper\ub97c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc5b4\ub5bb\uac8c \uc0ac\uc6a9\ud574\uc57c \ud560\uae4c?",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc640 \uac19\uc774 SQL \ucffc\ub9ac, RowMapper, \ud30c\ub77c\ubbf8\ud130\ub97c \ubd84\ub9ac\ud55c \uba54\uc11c\ub4dc\uc5d0 \ub118\uaca8\uc8fc\uace0 \ucffc\ub9ac \uc2e4\ud589 \ud6c4 \ub9e4\ud551\ud55c \uac12\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public User findById(final int userId) {\n final String query = "SELECT * FROM user WHERE id = ?";\n return queryForSingleResult(query, resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n }, userId);\n}\n\nprivate User queryForSingleResult(\n final String query,\n final RowMapper rowMapper,\n final Object... parameters\n) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n if (resultSet.next()) {\n return rowMapper.mapRow(resultSet);\n }\n return null;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n\nprivate ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n}\n')),(0,a.kt)("h3",{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---3-\ub2e4\uac74-\uc870\ud68c"},"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c"),(0,a.kt)("p",null,"\ub2e8\uac74 \uc870\ud68c\uc640 \uc720\uc0ac\ud558\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public List<User> findAll() {\n final String query = "SELECT * FROM user";\n return query(query, resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n });\n}\n\nprivate List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n final List<User> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(rowMapper.mapRow(resultSet));\n }\n return result;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n\nprivate ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n}\n')),(0,a.kt)("h3",{id:"\uc81c\ub124\ub9ad-\uc0ac\uc6a9\ud558\uae30"},"\uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30"),(0,a.kt)("p",null,"\uc704\uc758 \ucf54\ub4dc\ub294 User\ub97c \uc870\ud68c\ud560 \ub54c\ub9cc \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc640 \uac19\uc774 \uc81c\ub124\ub9ad\uc744 \uc801\uc6a9\ud558\uc5ec \ub2e4\ub978 Dao\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\ud558\ub3c4\ub85d \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"@FunctionalInterface\npublic interface RowMapper<T> {\n T mapRow(final ResultSet resultSet) throws SQLException;\n}\n\nprivate <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\nprivate <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\n")),(0,a.kt)("h3",{id:"\uba54\uc11c\ub4dc-\ubd84\ub9ac\ud55c-\ubd80\ubd84-\ud074\ub798\uc2a4\ub85c-\ubd84\ub9ac\ud558\uae30--optional-\uc0ac\uc6a9\ud558\uae30"},"\uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30"),(0,a.kt)("p",null,"\uba54\uc11c\ub4dc\ub85c \ubd84\ub9ac\ud55c \ubd80\ubd84\uc744 JdbcTemplate\uc774\ub77c\ub294 \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uc5b4 \uc62e\uae34\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c null\uc744 \ubc18\ud658\ud558\uae30 \ubcf4\ub2e8 Optional\ub85c \uac10\uc2f8\uc11c \ubc18\ud658\ud558\ub3c4\ub85d \ubcc0\uacbd\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd5c\uc885\uc801\uc73c\ub85c \uc544\ub798\uc640 \uac19\uc740 \ucf54\ub4dc\uac00 \uc644\uc131\ub41c\ub2e4."),(0,a.kt)(l.Z,{mdxType:"Tabs"},(0,a.kt)(i.Z,{value:"UserDao",label:"UserDao",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},'public class UserDao {\n private final RowMapper<User> rowMapper = resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n };\n private final JdbcTemplate jdbcTemplate;\n\n public UserDao(final JdbcTemplate jdbcTemplate) {\n this.jdbcTemplate = jdbcTemplate;\n }\n\n public void insert(final String name) {\n final String query = "INSERT INTO User (name) VALUES (?)";\n jdbcTemplate.executeUpdate(query, name);\n }\n\n public void delete(final int userId) {\n final String query = "DELETE FROM user WHERE user_id = ?";\n jdbcTemplate.executeUpdate(query, userId);\n }\n\n public Optional<User> findById(final int userId) {\n final String query = "SELECT * FROM user WHERE id = ?";\n return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);\n }\n\n public List<User> findAll() {\n final String query = "SELECT * FROM user";\n return jdbcTemplate.query(query, rowMapper);\n }\n}\n'))),(0,a.kt)(i.Z,{value:"JdbcTemplate",label:"JdbcTemplate",default:!0,mdxType:"TabItem"},(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public class JdbcTemplate {\n private final ConnectionPool connectionPool;\n\n public JdbcTemplate(final ConnectionPool connectionPool) {\n this.connectionPool = connectionPool;\n }\n\n public void executeUpdate(final String query, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public <T> Optional<T> queryForSingleResult(\n final String query,\n final RowMapper<T> rowMapper,\n final Object... parameters\n ) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n if (resultSet.next()) {\n return Optional.of(rowMapper.mapRow(resultSet));\n }\n return Optional.empty();\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n private ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters\n ) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n }\n\n public <T> List<T> query(\n final String query,\n final RowMapper<T> rowMapper,\n final Object... parameters\n ) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n final List<T> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(rowMapper.mapRow(resultSet));\n }\n return result;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n}\n")))))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d7955594.3de2f6cf.js b/assets/js/d7955594.3de2f6cf.js new file mode 100644 index 000000000..b10e33471 --- /dev/null +++ b/assets/js/d7955594.3de2f6cf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[588],{18751:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>u,contentTitle:()=>c,default:()=>m,frontMatter:()=>o,metadata:()=>s,toc:()=>p});var r=t(85893),a=t(3905),i=t(74866),l=t(85162);const o={title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",slug:"custom-jdbc-template",tags:["JDBC","Java"]},c=void 0,s={permalink:"/custom-jdbc-template",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",source:"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",description:"\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.",date:"2023-04-02T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 2\uc77c",tags:[{label:"JDBC",permalink:"/tags/jdbc"},{label:"Java",permalink:"/tags/java"}],readingTime:9.025,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",slug:"custom-jdbc-template",tags:["JDBC","Java"]},unlisted:!1,prevItem:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",permalink:"/java-class-file"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 1 \ud68c\uace0",permalink:"/woowacourse-level1-retrospective"}},u={authorsImageUrls:[]},p=[{value:"\uae30\uc874 \ucf54\ub4dc",id:"\uae30\uc874-\ucf54\ub4dc",level:3},{value:"SELECT, DELETE \uc911\ubcf5 \uc81c\uac70",id:"select-delete-\uc911\ubcf5-\uc81c\uac70",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---1-\ucf5c\ubc31\uc744-\uc704\ud55c-\uc778\ud130\ud398\uc774\uc2a4-\uc815\uc758",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---2-\ub2e8\uac74-\uc870\ud68c",level:3},{value:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c",id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---3-\ub2e4\uac74-\uc870\ud68c",level:3},{value:"\uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30",id:"\uc81c\ub124\ub9ad-\uc0ac\uc6a9\ud558\uae30",level:3},{value:"\uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30",id:"\uba54\uc11c\ub4dc-\ubd84\ub9ac\ud55c-\ubd80\ubd84-\ud074\ub798\uc2a4\ub85c-\ubd84\ub9ac\ud558\uae30--optional-\uc0ac\uc6a9\ud558\uae30",level:3}];function d(e){const n={admonition:"admonition",br:"br",code:"code",h3:"h3",mermaid:"mermaid",p:"p",pre:"pre",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.p,{children:["\uccb4\uc2a4 \ubbf8\uc158\uc5d0\uc11c\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uac00\uc838\uc624\uae30 \uc704\ud574 DAO\ub97c \uc0ac\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774 \ub54c JDBC\ub97c \uc0ac\uc6a9\ud560 \ub54c \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc758 \ucee4\ub125\uc158\uc744 \uc5bb\uace0, try-with-resource\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\uc774 \ubc18\ubcf5\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud15c\ud50c\ub9bf \ucf5c\ubc31 \ud328\ud134\uc744 \uc774\uc6a9\ud558\uc5ec \ub098\ub9cc\uc758 JdbcTemplate\uc744 \ub9cc\ub4e4\uc5b4\ubcf4\uc558\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uae30\uc874-\ucf54\ub4dc",children:"\uae30\uc874 \ucf54\ub4dc"}),"\n",(0,r.jsxs)(i.Z,{children:[(0,r.jsx)(l.Z,{value:"User",label:"User",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public class User {\n private final int id;\n private final String name;\n\n public User(final int id, final String name) {\n this.id = id;\n this.name = name;\n }\n\n public int getId() {\n return id;\n }\n\n public String getName() {\n return name;\n }\n}\n"})})}),(0,r.jsx)(l.Z,{value:"UserDao",label:"UserDao",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public class UserDao {\n private final ConnectionPool connectionPool;\n\n public UserDao(final ConnectionPool connectionPool) {\n this.connectionPool = connectionPool;\n }\n\n public void insert(final String name) {\n final Connection connection = connectionPool.getConnection();\n final String query = "INSERT INTO User (name) VALUES (?)";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setString(1, name);\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public void delete(final int userId) {\n final Connection connection = connectionPool.getConnection();\n final String query = "DELETE FROM user WHERE id = ?";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setInt(1, userId);\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public User findById(final int userId) {\n final Connection connection = connectionPool.getConnection();\n final String query = "SELECT * FROM user WHERE id = ?";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n preparedStatement.setInt(1, userId);\n final ResultSet resultSet = preparedStatement.executeQuery();\n if (resultSet.next()) {\n return new User(\n resultSet.getInt("id"),\n resultSet.getString("name")\n );\n }\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n return null;\n }\n\n public List<User> findAll() {\n final Connection connection = connectionPool.getConnection();\n final String query = "SELECT * FROM user";\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n final ResultSet resultSet = preparedStatement.executeQuery();\n final List<User> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(new User(\n resultSet.getInt("id"),\n resultSet.getString("name")\n ));\n }\n return result;\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n}\n'})})}),(0,r.jsx)(l.Z,{value:"ConnectionPool",label:"ConnectionPool",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public class ConnectionPool {\n private static final String SERVER = "localhost:13306";\n private static final String DATABASE = "chess";\n private static final String OPTION = "?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";\n private static final String URL = "jdbc:mysql://" + SERVER + "/" + DATABASE + OPTION;\n private static final String USERNAME = "root";\n private static final String PASSWORD = "root";\n\n private final AtomicInteger index = new AtomicInteger();\n private final List<Connection> connections;\n\n public ConnectionPool(final int connectionCount) {\n connections = generateConnections(connectionCount);\n }\n\n private List<Connection> generateConnections(final int connectionCount) {\n return Stream.generate(this::generateConnection)\n .limit(connectionCount)\n .collect(toList());\n }\n\n private Connection generateConnection() {\n try {\n return DriverManager.getConnection(URL, USERNAME, PASSWORD);\n } catch (SQLException e) {\n throw new IllegalStateException("\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.");\n }\n }\n\n public Connection getConnection() {\n int currentIndex = index.getAndIncrement();\n return connections.get(currentIndex % connections.size());\n }\n}\n'})})})]}),"\n",(0,r.jsx)(n.h3,{id:"select-delete-\uc911\ubcf5-\uc81c\uac70",children:"SELECT, DELETE \uc911\ubcf5 \uc81c\uac70"}),"\n",(0,r.jsxs)(n.p,{children:["\ubcc0\ud558\uc9c0 \uc54a\ub294 \ubd80\ubd84: try-with-resource, preparedStatement\ub97c \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84, executeUpdate\ub85c \uc2e4\ud589 \ub4f1\ub4f1",(0,r.jsx)(n.br,{}),"\n","\ubcc0\ud558\ub294 \ubd80\ubd84: SQL Query, \ub9e4\uac1c\ubcc0\uc218"]}),"\n",(0,r.jsx)(n.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\ub294 \ubd80\ubd84\uc744 \ubd84\ub9ac\ud558\uace0 \uac00\ubcc0\uc778\uc218\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uba74 SELECT\uc640 DELETE\uc758 \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public void insert(final String name) {\n final String query = "INSERT INTO User (name) VALUES (?)";\n executeUpdate(query, name);\n}\n\npublic void delete(final int userId) {\n final String query = "DELETE FROM user WHERE user_id = ?";\n executeUpdate(query, userId);\n}\n\nprivate void executeUpdate(final String query, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---1-\ucf5c\ubc31\uc744-\uc704\ud55c-\uc778\ud130\ud398\uc774\uc2a4-\uc815\uc758",children:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 1. \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4 \uc815\uc758"}),"\n",(0,r.jsxs)(n.p,{children:["\uc870\ud68c\ub294 INSERT, DELETE\uc640 \ub2ec\ub9ac \uac12\uc744 \ubc18\ud658\ubc1b\uc544\uc57c \ud558\uae30 \ub54c\ubb38\uc5d0 \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774 \ub54c \ucf5c\ubc31\uc774\ub77c\ub294 \uac83\uc744 \uc0ac\uc6a9\ud558\uc5ec \uc911\ubcf5\uc744 \uc81c\uac70\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsxs)(n.admonition,{title:"\ucf5c\ubc31(Callback)",type:"note",children:[(0,r.jsxs)(n.p,{children:["\ud504\ub85c\uadf8\ub798\ubc0d\uc5d0\uc11c \ucf5c\ubc31\uc740 \ub2e4\ub978 \ucf54\ub4dc\uc758 \uc778\uc218\ub85c \ub118\uaca8\uc8fc\ub294 \uc2e4\ud589 \uac00\ub2a5\ud55c \ucf54\ub4dc\ub97c \ub73b\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc790\ubc14\uc5d0\uc11c\ub294 \ub78c\ub2e4\ub098 \uc775\uba85 \ud074\ub798\uc2a4\ub97c \ub118\uaca8\uc11c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),(0,r.jsx)(n.mermaid,{value:"flowchart LR\n \ud074\ub77c\uc774\uc5b8\ud2b8 -- \ucf5c\ubc31\uc804\ub2ec --\x3e \uba54\uc11c\ub4dc\n \uba54\uc11c\ub4dc -- \ub0b4\ubd80\ud638\ucd9c --\x3e \uc804\ub2ec\ubc1b\uc740\ucf5c\ubc31"})]}),"\n",(0,r.jsxs)(n.p,{children:["\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uac12\uc744 \uc870\ud68c\ud558\uace0, \ud574\ub2f9 \uac12\uc744 \uac1d\uccb4\ub85c \ub9e4\ud551\ud558\uc5ec \uac12\uc744 \ubc18\ud658\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","executeQuery\ub85c \uc870\ud68c\ud55c \uac12\uc740 ResultSet \uc548\uc5d0 \ub4e4\uc5b4\uac00\uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ub97c \uc6d0\ud558\ub294 \ud0c0\uc785\uc758 \uac12\uc73c\ub85c \ubcc0\ud658\ud574\uc57c\ud558\ub2c8 \uc77c\ub2e8 \ucf5c\ubc31\uc744 \uc704\ud55c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub9cc\ub4e4\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@FunctionalInterface\npublic interface RowMapper {\n User mapRow(final ResultSet resultSet) throws SQLException;\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---2-\ub2e8\uac74-\uc870\ud68c",children:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 2. \ub2e8\uac74 \uc870\ud68c"}),"\n",(0,r.jsxs)(n.p,{children:["\uc704\uc5d0\uc11c \uc815\uc758\ud55c RowMapper\ub97c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc5b4\ub5bb\uac8c \uc0ac\uc6a9\ud574\uc57c \ud560\uae4c?",(0,r.jsx)(n.br,{}),"\n","\uc544\ub798\uc640 \uac19\uc774 SQL \ucffc\ub9ac, RowMapper, \ud30c\ub77c\ubbf8\ud130\ub97c \ubd84\ub9ac\ud55c \uba54\uc11c\ub4dc\uc5d0 \ub118\uaca8\uc8fc\uace0 \ucffc\ub9ac \uc2e4\ud589 \ud6c4 \ub9e4\ud551\ud55c \uac12\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public User findById(final int userId) {\n final String query = "SELECT * FROM user WHERE id = ?";\n return queryForSingleResult(query, resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n }, userId);\n}\n\nprivate User queryForSingleResult(\n final String query,\n final RowMapper rowMapper,\n final Object... parameters\n) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n if (resultSet.next()) {\n return rowMapper.mapRow(resultSet);\n }\n return null;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n\nprivate ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"\uc870\ud68c-\ubd84\ub9ac\ud558\uae30---3-\ub2e4\uac74-\uc870\ud68c",children:"\uc870\ud68c \ubd84\ub9ac\ud558\uae30 - 3. \ub2e4\uac74 \uc870\ud68c"}),"\n",(0,r.jsx)(n.p,{children:"\ub2e8\uac74 \uc870\ud68c\uc640 \uc720\uc0ac\ud558\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public List<User> findAll() {\n final String query = "SELECT * FROM user";\n return query(query, resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n });\n}\n\nprivate List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n final List<User> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(rowMapper.mapRow(resultSet));\n }\n return result;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n}\n\nprivate ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"\uc81c\ub124\ub9ad-\uc0ac\uc6a9\ud558\uae30",children:"\uc81c\ub124\ub9ad \uc0ac\uc6a9\ud558\uae30"}),"\n",(0,r.jsxs)(n.p,{children:["\uc704\uc758 \ucf54\ub4dc\ub294 User\ub97c \uc870\ud68c\ud560 \ub54c\ub9cc \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc544\ub798\uc640 \uac19\uc774 \uc81c\ub124\ub9ad\uc744 \uc801\uc6a9\ud558\uc5ec \ub2e4\ub978 Dao\uc5d0\uc11c\ub3c4 \uc0ac\uc6a9 \uac00\ub2a5\ud558\ub3c4\ub85d \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"@FunctionalInterface\npublic interface RowMapper<T> {\n T mapRow(final ResultSet resultSet) throws SQLException;\n}\n\nprivate <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\nprivate <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\uba54\uc11c\ub4dc-\ubd84\ub9ac\ud55c-\ubd80\ubd84-\ud074\ub798\uc2a4\ub85c-\ubd84\ub9ac\ud558\uae30--optional-\uc0ac\uc6a9\ud558\uae30",children:"\uba54\uc11c\ub4dc \ubd84\ub9ac\ud55c \ubd80\ubd84 \ud074\ub798\uc2a4\ub85c \ubd84\ub9ac\ud558\uae30 + Optional \uc0ac\uc6a9\ud558\uae30"}),"\n",(0,r.jsxs)(n.p,{children:["\uba54\uc11c\ub4dc\ub85c \ubd84\ub9ac\ud55c \ubd80\ubd84\uc744 JdbcTemplate\uc774\ub77c\ub294 \ud074\ub798\uc2a4\ub97c \ub9cc\ub4e4\uc5b4 \uc62e\uae34\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub610\ud55c null\uc744 \ubc18\ud658\ud558\uae30 \ubcf4\ub2e8 Optional\ub85c \uac10\uc2f8\uc11c \ubc18\ud658\ud558\ub3c4\ub85d \ubcc0\uacbd\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd5c\uc885\uc801\uc73c\ub85c \uc544\ub798\uc640 \uac19\uc740 \ucf54\ub4dc\uac00 \uc644\uc131\ub41c\ub2e4."]}),"\n",(0,r.jsxs)(i.Z,{children:[(0,r.jsx)(l.Z,{value:"UserDao",label:"UserDao",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'public class UserDao {\n private final RowMapper<User> rowMapper = resultSet -> {\n final int id = resultSet.getInt("id");\n final String name = resultSet.getString("name");\n return new User(id, name);\n };\n private final JdbcTemplate jdbcTemplate;\n\n public UserDao(final JdbcTemplate jdbcTemplate) {\n this.jdbcTemplate = jdbcTemplate;\n }\n\n public void insert(final String name) {\n final String query = "INSERT INTO User (name) VALUES (?)";\n jdbcTemplate.executeUpdate(query, name);\n }\n\n public void delete(final int userId) {\n final String query = "DELETE FROM user WHERE user_id = ?";\n jdbcTemplate.executeUpdate(query, userId);\n }\n\n public Optional<User> findById(final int userId) {\n final String query = "SELECT * FROM user WHERE id = ?";\n return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);\n }\n\n public List<User> findAll() {\n final String query = "SELECT * FROM user";\n return jdbcTemplate.query(query, rowMapper);\n }\n}\n'})})}),(0,r.jsx)(l.Z,{value:"JdbcTemplate",label:"JdbcTemplate",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public class JdbcTemplate {\n private final ConnectionPool connectionPool;\n\n public JdbcTemplate(final ConnectionPool connectionPool) {\n this.connectionPool = connectionPool;\n }\n\n public void executeUpdate(final String query, final Object... parameters) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n preparedStatement.executeUpdate();\n } catch (final SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n public <T> Optional<T> queryForSingleResult(\n final String query,\n final RowMapper<T> rowMapper,\n final Object... parameters\n ) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n if (resultSet.next()) {\n return Optional.of(rowMapper.mapRow(resultSet));\n }\n return Optional.empty();\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n\n private ResultSet executeQuery(\n final PreparedStatement preparedStatement,\n final Object[] parameters\n ) throws SQLException {\n for (int i = 1; i <= parameters.length; i++) {\n preparedStatement.setObject(i, parameters[i - 1]);\n }\n return preparedStatement.executeQuery();\n }\n\n public <T> List<T> query(\n final String query,\n final RowMapper<T> rowMapper,\n final Object... parameters\n ) {\n final Connection connection = connectionPool.getConnection();\n try (final PreparedStatement preparedStatement = connection.prepareStatement(query);\n final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {\n final List<T> result = new ArrayList<>();\n while (resultSet.next()) {\n result.add(rowMapper.mapRow(resultSet));\n }\n return result;\n } catch (SQLException e) {\n throw new IllegalArgumentException(e.getMessage());\n }\n }\n}\n"})})})]})]})}function m(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>s});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function l(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?i(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function o(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=r.createContext({}),s=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},p=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,c=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),d=s(t),m=a,f=d["".concat(c,".").concat(m)]||d[m]||u[m]||i;return t?r.createElement(f,l(l({ref:n},p),{},{components:t})):r.createElement(f,l({ref:n},p))}));p.displayName="MDXCreateElement"},85162:(e,n,t)=>{t.d(n,{Z:()=>l});t(67294);var r=t(86010);const a={tabItem:"tabItem_Ymn6"};var i=t(85893);function l(e){let{children:n,hidden:t,className:l}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,r.Z)(a.tabItem,l),hidden:t,children:n})}},74866:(e,n,t)=>{t.d(n,{Z:()=>j});var r=t(67294),a=t(86010),i=t(12466),l=t(16550),o=t(20469),c=t(91980),s=t(67392),u=t(50012);function p(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function d(e){const{values:n,children:t}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return p(e).map((e=>{let{props:{value:n,label:t,attributes:r,default:a}}=e;return{value:n,label:t,attributes:r,default:a}}))}(t);return function(e){const n=(0,s.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,t])}function m(e){let{value:n,tabValues:t}=e;return t.some((e=>e.value===n))}function f(e){let{queryString:n=!1,groupId:t}=e;const a=(0,l.k6)(),i=function(e){let{queryString:n=!1,groupId:t}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!t)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:n,groupId:t});return[(0,c._X)(i),(0,r.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(a.location.search);n.set(i,e),a.replace({...a.location,search:n.toString()})}),[i,a])]}function S(e){const{defaultValue:n,queryString:t=!1,groupId:a}=e,i=d(e),[l,c]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:t}=e;if(0===t.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!m({value:n,tabValues:t}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${t.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=t.find((e=>e.default))??t[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:i}))),[s,p]=f({queryString:t,groupId:a}),[S,g]=function(e){let{groupId:n}=e;const t=function(e){return e?`docusaurus.tab.${e}`:null}(n),[a,i]=(0,u.Nk)(t);return[a,(0,r.useCallback)((e=>{t&&i.set(e)}),[t,i])]}({groupId:a}),b=(()=>{const e=s??S;return m({value:e,tabValues:i})?e:null})();(0,o.Z)((()=>{b&&c(b)}),[b]);return{selectedValue:l,selectValue:(0,r.useCallback)((e=>{if(!m({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);c(e),p(e),g(e)}),[p,g,i]),tabValues:i}}var g=t(72389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var h=t(85893);function x(e){let{className:n,block:t,selectedValue:r,selectValue:l,tabValues:o}=e;const c=[],{blockElementScrollPositionUntilNextRender:s}=(0,i.o5)(),u=e=>{const n=e.currentTarget,t=c.indexOf(n),a=o[t].value;a!==r&&(s(n),l(a))},p=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const t=c.indexOf(e.currentTarget)+1;n=c[t]??c[0];break}case"ArrowLeft":{const t=c.indexOf(e.currentTarget)-1;n=c[t]??c[c.length-1];break}}n?.focus()};return(0,h.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,a.Z)("tabs",{"tabs--block":t},n),children:o.map((e=>{let{value:n,label:t,attributes:i}=e;return(0,h.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>c.push(e),onKeyDown:p,onClick:u,...i,className:(0,a.Z)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":r===n}),children:t??n},n)}))})}function y(e){let{lazy:n,children:t,selectedValue:a}=e;const i=(Array.isArray(t)?t:[t]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===a));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return(0,h.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==a})))})}function v(e){const n=S(e);return(0,h.jsxs)("div",{className:(0,a.Z)("tabs-container",b.tabList),children:[(0,h.jsx)(x,{...e,...n}),(0,h.jsx)(y,{...e,...n})]})}function j(e){const n=(0,g.Z)();return(0,h.jsx)(v,{...e,children:p(e.children)},String(n))}}}]); \ No newline at end of file diff --git a/assets/js/d86f7a37.ca7f1316.js b/assets/js/d86f7a37.ca7f1316.js new file mode 100644 index 000000000..eb00a2cbb --- /dev/null +++ b/assets/js/d86f7a37.ca7f1316.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3392],{98034:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>g,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var r=n(85893),i=n(3905);const a={title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",slug:"/nginx/static-file",last_update:{date:"2023/08/04"},tags:["nginx"]},s=void 0,o={id:"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5",title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",description:"root",source:"@site/docs/Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5.mdx",sourceDirName:"Nginx",slug:"/nginx/static-file",permalink:"/docs/nginx/static-file",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5.mdx",tags:[{label:"nginx",permalink:"/docs/tags/nginx"}],version:"current",lastUpdatedAt:1691107200,formattedLastUpdatedAt:"2023\ub144 8\uc6d4 4\uc77c",frontMatter:{title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",slug:"/nginx/static-file",last_update:{date:"2023/08/04"},tags:["nginx"]},sidebar:"tutorialSidebar",previous:{title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",permalink:"/docs/nginx/command"},next:{title:"\ubb38\uc11c",permalink:"/docs/"}},l={},c=[{value:"root",id:"root",level:3},{value:"alias",id:"alias",level:3},{value:"try_files",id:"try_files",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const t={a:"a",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"root",children:"root"}),"\n",(0,r.jsxs)(t.p,{children:["\ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \ud30c\uc77c\uc744 \uc81c\uacf5\ud560 \ub54c \uc0ac\uc6a9\ub418\ub294 \uacbd\ub85c\ub97c \uc9c0\uc815\ud558\ub294 \ub370 \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","root\uc758 \uacbd\uc6b0 locaiton\uc73c\ub85c \ub118\uc5b4\uc628 \uacbd\ub85c\ub97c root \uacbd\ub85c \ub4a4\uc5d0 \ucd94\uac00\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",metastring:"title=root",children:"# localhost/images/1.png \ud638\ucd9c /var/www/images/images/1.png \uac80\uc0c9\nlocation /images/ {\n root /var/www/images;\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"alias",children:"alias"}),"\n",(0,r.jsx)(t.p,{children:"location\uc73c\ub85c \ub9e4\uce6d\ub41c \ubd80\ubd84\uc744 \uc81c\uac70\ud55c\ub2e4."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",metastring:"title=alias",children:"# localhost/images/1.png \ud638\ucd9c /var/www/images/1.png \uac80\uc0c9\nlocation /images/ {\n alias /var/www/images;\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"try_files",children:"try_files"}),"\n",(0,r.jsxs)(t.p,{children:["try_files \ub514\ub809\ud2f0\ube0c\ub97c \uc774\uc6a9\ud574\uc11c \ud30c\uc77c\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\uc73c\uba74 \uc801\uc808\ud55c \uac12\uc744 \ubc18\ud658\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc124\uc815\ud558\uc9c0 \uc54a\uc73c\uba74 \uae30\ubcf8\uc73c\ub85c 404\ub97c \ubc18\ud658\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"location /images/ {\n alias /var/www/images;\n try_files $uri $uri/ =404;\n}\n"})}),"\n",(0,r.jsx)(t.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 proxy \uc124\uc815\uc73c\ub85c\ub3c4 \uad6c\uc131\ud560 \uc218\ub3c4 \uc788\ub2e4."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"location /images/ {\n root /root;\n try_files $uri $uri/ default-image;\n}\n\nlocation default-image {\n proxy_pass http://localhost/images/default_image.jpg;\n}\n"})}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.a,{href:"https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/",children:"Serving Static Content"})})]})}function g(e={}){const{wrapper:t}={...(0,i.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>c});var r=n(67294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?a(Object(n),!0).forEach((function(t){i(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):a(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function o(e,t){if(null==e)return{};var n,r,i=function(e,t){if(null==e)return{};var n,r,i={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,g=o(e,["components","mdxType","originalType","parentName"]),p=c(n),u=i,m=p["".concat(l,".").concat(u)]||p[u]||d[u]||a;return n?r.createElement(m,s(s({ref:t},g),{},{components:n})):r.createElement(m,s({ref:t},g))}));g.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/d86f7a37.cb912e58.js b/assets/js/d86f7a37.cb912e58.js deleted file mode 100644 index ef635a541..000000000 --- a/assets/js/d86f7a37.cb912e58.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3392],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>m});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?i(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),g=c(n),m=a,d=g["".concat(s,".").concat(m)]||g[m]||u[m]||i;return n?r.createElement(d,o(o({ref:t},p),{},{components:n})):r.createElement(d,o({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=g;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var c=2;c<i;c++)o[c]=n[c];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}g.displayName="MDXCreateElement"},10823:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const i={title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",slug:"/nginx/static-file",last_update:{date:"2023/08/04"},tags:["nginx"]},o=void 0,l={unversionedId:"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5",id:"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5",title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",description:"root",source:"@site/docs/Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5.mdx",sourceDirName:"Nginx",slug:"/nginx/static-file",permalink:"/docs/nginx/static-file",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5.mdx",tags:[{label:"nginx",permalink:"/docs/tags/nginx"}],version:"current",lastUpdatedAt:1691107200,formattedLastUpdatedAt:"2023\ub144 8\uc6d4 4\uc77c",frontMatter:{title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",slug:"/nginx/static-file",last_update:{date:"2023/08/04"},tags:["nginx"]},sidebar:"tutorialSidebar",previous:{title:"\uad6c\uc870 \ubc0f \uba85\ub839\uc5b4",permalink:"/docs/nginx/command"},next:{title:"\ubb38\uc11c",permalink:"/docs/"}},s={},c=[{value:"root",id:"root",level:3},{value:"alias",id:"alias",level:3},{value:"try_files",id:"try_files",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],p={toc:c};function u(e){let{components:t,...n}=e;return(0,a.kt)("wrapper",(0,r.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"root"},"root"),(0,a.kt)("p",null,"\ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \ud30c\uc77c\uc744 \uc81c\uacf5\ud560 \ub54c \uc0ac\uc6a9\ub418\ub294 \uacbd\ub85c\ub97c \uc9c0\uc815\ud558\ub294 \ub370 \uc0ac\uc6a9\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","root\uc758 \uacbd\uc6b0 locaiton\uc73c\ub85c \ub118\uc5b4\uc628 \uacbd\ub85c\ub97c root \uacbd\ub85c \ub4a4\uc5d0 \ucd94\uac00\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash",metastring:"title=root",title:"root"},"# localhost/images/1.png \ud638\ucd9c /var/www/images/images/1.png \uac80\uc0c9\nlocation /images/ {\n root /var/www/images;\n}\n")),(0,a.kt)("h3",{id:"alias"},"alias"),(0,a.kt)("p",null,"location\uc73c\ub85c \ub9e4\uce6d\ub41c \ubd80\ubd84\uc744 \uc81c\uac70\ud55c\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash",metastring:"title=alias",title:"alias"},"# localhost/images/1.png \ud638\ucd9c /var/www/images/1.png \uac80\uc0c9\nlocation /images/ {\n alias /var/www/images;\n}\n")),(0,a.kt)("h3",{id:"try_files"},"try_files"),(0,a.kt)("p",null,"try_files \ub514\ub809\ud2f0\ube0c\ub97c \uc774\uc6a9\ud574\uc11c \ud30c\uc77c\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\uc73c\uba74 \uc801\uc808\ud55c \uac12\uc744 \ubc18\ud658\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc124\uc815\ud558\uc9c0 \uc54a\uc73c\uba74 \uae30\ubcf8\uc73c\ub85c 404\ub97c \ubc18\ud658\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"location /images/ {\n alias /var/www/images;\n try_files $uri $uri/ =404;\n}\n")),(0,a.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 proxy \uc124\uc815\uc73c\ub85c\ub3c4 \uad6c\uc131\ud560 \uc218\ub3c4 \uc788\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-bash"},"location /images/ {\n root /root;\n try_files $uri $uri/ default-image;\n}\n\nlocation default-image {\n proxy_pass http://localhost/images/default_image.jpg;\n}\n")),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/"},"Serving Static Content")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d8775059.2c1a33ff.js b/assets/js/d8775059.2c1a33ff.js deleted file mode 100644 index d84907453..000000000 --- a/assets/js/d8775059.2c1a33ff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6387],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?p(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):p(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},p=Object.keys(e);for(r=0;r<p.length;r++)n=p[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(r=0;r<p.length;r++)n=p[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),c=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=c(n),d=a,k=m["".concat(i,".").concat(d)]||m[d]||s[d]||p;return n?r.createElement(k,o(o({ref:t},u),{},{components:n})):r.createElement(k,o({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=n.length,o=new Array(p);o[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var c=2;c<p;c++)o[c]=n[c];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},98809:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>s,frontMatter:()=>p,metadata:()=>l,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const p={title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",slug:"tecochat-retrospective-1",tags:["TecoChat","Retrospective"]},o=void 0,l={permalink:"/tecochat-retrospective-1",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",source:"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",description:"4\uc6d4 21\uc77c \uae08\uc694\uc77c",date:"2023-04-22T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 22\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.68,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",slug:"tecochat-retrospective-1",tags:["TecoChat","Retrospective"]},prevItem:{title:"Jenkins\ub85c CI/CD \uc124\uc815",permalink:"/jenkins"},nextItem:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",permalink:"/book-leadership-and-self-deception"}},i={authorsImageUrls:[]},c=[{value:"4\uc6d4 21\uc77c \uae08\uc694\uc77c",id:"4\uc6d4-21\uc77c-\uae08\uc694\uc77c",level:3},{value:"\ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?",id:"\ub3c4\uba54\uc778-\uad6c\uc785-\uc131\uacf5",level:3},{value:"\ub9d0\ub791\uc758 DM",id:"\ub9d0\ub791\uc758-dm",level:3},{value:"\ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec",id:"\ub3c4\uba54\uc778-\uc124\uc815-\ubc0f-\ubc30\ud3ec",level:3},{value:"GPT",id:"gpt",level:3},{value:"Sonarcloud",id:"sonarcloud",level:3},{value:"Tiptap",id:"tiptap",level:3},{value:"\ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9",id:"\ud3f0\ud2b8-\ubc0f-favicon-\uc801\uc6a9",level:3}],u={toc:c};function s(e){let{components:t,...p}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,p,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"4\uc6d4-21\uc77c-\uae08\uc694\uc77c"},"4\uc6d4 21\uc77c \uae08\uc694\uc77c"),(0,a.kt)("p",null,"\ub808\ubca8 2\ub97c \uc2dc\uc791\ud55c \ub4a4 \ub0b4\uac00 \ud559\uc2b5\uc5d0 \ub300\ud55c \ubc29\ud5a5\uc744 \uc783\uc5b4\ubc84\ub838\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 3, 4\uc5d0\uc11c \ub098\ub9cc\uc758 \uac15\uc810\uc744 \uac00\uc9c0\uace0 \uc2f6\uc5b4 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc21c\ud788 \uc2a4\ud504\ub9c1\uc744 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ud6a8\uc728\uc774 \ub9ce\uc774 \ub5a8\uc5b4\uc9c4\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae00\uc4f0\uae30 \uc218\uc0c1\uc73c\ub85c \ubc1b\uc740 \ucfe0\ud3f0\uc744 \uc0ac\uc6a9\ud574 \ube0c\ub77c\uc6b4\uc5d0\uac8c \ucee4\ud53c\ucc57\uc744 \uc2e0\uccad\ud588\uace0, \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud574\ubcf4\ub77c\ub294 \ub2f5\uc744 \ubc1b\uc558\ub2e4. "),(0,a.kt)("p",null,"\ub098\ub294 \uc544\uc774\ub514\uc5b4\ub97c \ubabb\ub0b4\ub294 \ud3b8\uc778\ub370 \ube0c\ub77c\uc6b4\uc774 \uc544\uc774\ub514\uc5b4\uae4c\uc9c0 \ub358\uc838\uc8fc\uc168\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("inlineCode",{parentName:"p"},"Chat-GPT \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uace0, \ud574\ub2f9 \ud06c\ub8e8\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc744 \uacf5\uc720\ud560 \uc218 \uc788\ub294 \uac74 \uc5b4\ub5a4\uc9c0?")," "),(0,a.kt)("p",null,"\uae30\uc220\uc774 \ubaa9\uc801\uc778 \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4\ub294 \ub2f5\ubcc0\uc744 \ub4e4\uc5c8\uace0, \ud63c\uc790 \uc544\ub2c8\uba74 \ud398\uc5b4\ud560 \uc218 \uc788\uc744 \uc815\ub3c4\uc758 \uc778\uc6d0\uc73c\ub85c \uc9c4\ud589\ud558\uba74 \uc88b\uaca0\ub2e4\uace0 \ud558\uc168\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud504\ub860\ud2b8\ub791 \uac04\ub2e8\ud558\uac8c \ubc30\ud3ec\uae4c\uc9c0 \ud574\ubcf8 \uacbd\ud5d8\uc774 \uc788\uc5b4\uc11c \ud63c\uc790\ud574\ub3c4 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uc744 \uac83 \uac19\uc544\uc11c \ud63c\uc790 \ud558\uae30\ub85c \ub9c8\uc74c\uc744 \uba39\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc774\uac74 \ubabb\ucc38\uc9c0"),(0,a.kt)("h3",{id:"\ub3c4\uba54\uc778-\uad6c\uc785-\uc131\uacf5"},"\ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?"),(0,a.kt)("p",null,"\ucee4\ud53c\ucc57\uc774 \ub05d\ub098\uace0 \uc9d1\uc73c\ub85c \ub3cc\uc544\uac00\ub294 \uae38\uc5d0 \ubc14\ub85c \ub3c4\uba54\uc778\uc744 \uad6c\ub9e4\ud558\ub824\uace0 namecheap\uc5d0\uc11c \uc801\ub2f9\ud55c \ub3c4\uba54\uc778\uc774 \uc5c6\uc744\uae4c \uac80\uc0c9\uc744 \uacc4\uc18d\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9c8\uce58 \uc5b4\ub9b4 \ub54c \ud588\ub358 \uac8c\uc784 \ub2c9\ub124\uc784 \uc815\ud558\ub294 \uac83\ucc98\ub7fc \uc2dc\uac04\uc774 \uc624\ub798 \uac78\ub838\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","dev, io, chat \ub3c4\uba54\uc778\uc774 \ud6c4\ubcf4\uc600\uace0 \uc9d1 \uac00\ub294 \uae38\uc5d0 \uacb0\uc815\ub9cc \ud558\ub2e4\uac00 \uad6c\ub9e4\ud558\uc9c0 \ubabb\ud588\ub2e4."),(0,a.kt)("h3",{id:"\ub9d0\ub791\uc758-dm"},"\ub9d0\ub791\uc758 DM"),(0,a.kt)("p",null,"\uc9d1\uc5d0 \uac00\uc11c \ubc25\uc744 \uba39\uace0 \ub9d0\ub791\uc774\ub791 DM \ud558\ub2e4 \ud504\ub85c\uc81d\ud2b8\ub97c \uac19\uc774 \ud558\uc790\ub294 \uc774\uc57c\uae30\uac00 \ub098\uc654\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ud14c\ucf54 \ucd5c\uace0 \uace0\uc218 \ub9d0\ub791\uc758 \uc694\uad6c\ub77c \uc218\ub77d\ud558\uc9c0 \uc54a\uc73c\uba74 \ud6c4\ud3ed\ud48d\uc744 \uac10\ub2f9\ud560 \uc218 \uc5c6\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc774\ub7f0\uc800\ub7f0 \ub300\ud654\ub97c \ub098\ub204\ub2e4\uac00 \ub09c \ube60\ub974\uac8c \ud504\ub85c\ud1a0\ud0c0\uc785\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\uace0 \uc2f6\uc5b4\uc11c \ud504\ub860\ud2b8\ub97c \uad6c\ud604\ud55c\ub2e4\uace0 \ud588\uace0, \ub9d0\ub791\uc740 GPT api\ub97c \uc870\uc0ac\ud558\uae30\ub85c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ub3c4\uba54\uc778\uc5d0 \uad00\ud55c \uc774\uc57c\uae30\ub97c \ud558\ub2e4\uac00 woowachat\uc774 \uc5b8\uae09\ub418\uc5c8\uace0, namecheap\uc5d0\uc11c chat \ub3c4\uba54\uc778\uc744 \uc0ac\uc6a9\ud55c woowa.chat\uc73c\ub85c \uad6c\ub9e4\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ud6c4\uc5d0 teco.chat\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4!"),(0,a.kt)("h3",{id:"\ub3c4\uba54\uc778-\uc124\uc815-\ubc0f-\ubc30\ud3ec"},"\ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec"),(0,a.kt)("p",null,"\ud1a0\uc694\uc77c\uc5d0 \uad6c\ub9e4\ud55c \ub3c4\uba54\uc778\uc744 CDN, \ubcf4\uc548 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\ub294 Cloudflare\uc5d0 \ub3c4\uba54\uc778 \ub4f1\ub85d\uc744 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\uc5d0\uac8c \uc775\uc219\ud55c Nuxt3\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\uace0, Cloudflare Pages\ub97c \uc774\uc6a9\ud558\uc5ec \ubc30\ud3ec\ud588\ub2e4. "),(0,a.kt)("h3",{id:"gpt"},"GPT"),(0,a.kt)("p",null,"\ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud558\ub2c8 api limit\uc774 \uc788\uc5b4 \ubd84\ub2f9 3\ubc88\ubc16\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ub2e8 \ubc31\uc5d4\ub4dc\ub97c \uad6c\ucd95\ud558\uae30 \uc804\uc5d0\ub294 \ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud560 \uc0dd\uac01\uc774\ub2e4. "),(0,a.kt)("h3",{id:"sonarcloud"},"Sonarcloud"),(0,a.kt)("p",null,"\uc815\uc801 \ucf54\ub4dc \ubd84\uc11d \ub3c4\uad6c\ub85c Sonarcloud\ub97c \uc801\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Sonarcloud\ub294 SonarQube\uc758 SaaS \ubc84\uc804\uc774\uace0 \uc0ac\uc6a9\uc774 \ub9e4\uc6b0 \ud3b8\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\uc804\uc5d0 Sonarcloud\ub97c \uc0ac\uc6a9\ud560 \ub550 \ubc84\ud2bc \uba87 \ubc88 \ub204\ub974\uba74 \uc801\uc6a9\ud560 \uc218 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \ubc14\ub85c github action\uc744 \uc0ac\uc6a9\ud558\ub77c\ub294 \uc548\ub0b4 \ud398\uc774\uc9c0\ub85c \uc774\ub3d9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Sonarcloud\uac00 \uc790\uccb4\uc801\uc73c\ub85c github repository\uc5d0 push \ud558\uba74 \uc815\uc801 \ubd84\uc11d\uc744 \ud574\uc8fc\ub294 \uae30\ub2a5\uc744 \uc6d0\ud588\uace0, Administration -> Analysis Method\uc5d0 Automatic Analysis\ub97c \uc124\uc815\ud558\ub2c8 \ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub108\ubb34 \uaf41\uaf41 \uc228\uaca8\uc838\uc788\ub124"),(0,a.kt)("h3",{id:"tiptap"},"Tiptap"),(0,a.kt)("p",null,"\ucf54\ub4dc \ud558\uc774\ub77c\uc774\ud305 \uae30\ub2a5\uc744 \ub123\uace0 \uc2f6\uc5b4\uc11c Tiptap\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Tiptap\uc740 Headless WYSIWYG \uc5d0\ub514\ud130\ub85c \uc0ac\uc6a9\uc790 \uc815\uc758 \uae30\ub2a5\uc5d0 \ud2b9\ud654\ub418\uc5b4\uc788\ub294 \uc5d0\ub514\ud130\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\uc9c1 Tiptap\uc774 \uc81c\uacf5\ud558\ub294 \ubaa8\ub4e0 \uae30\ub2a5\uc744 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc0ac\uc6a9\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc CodeBlockLowlight \ud50c\ub7ec\uadf8\uc778\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucf54\ub4dc \ube14\ub85d\uc744 \uc608\uc058\uac8c \ucd9c\ub825\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","api \ubc18\ud658\uac12 \uadf8\ub300\ub85c tiptap\uc758 content\uc5d0 \uc124\uc815\ud588\ub354\ub2c8 \ucf54\ub4dc \ube14\ub85d\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc544\uc11c \ubc31 \ud2f1 3\uac1c\ub97c ",(0,a.kt)("inlineCode",{parentName:"p"},"<pre><code>"),"\ub85c \ubcc0\ud658\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ub744\uc5b4\uc4f0\uae30\ub3c4 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc544\uc11c ",(0,a.kt)("inlineCode",{parentName:"p"},"\\n"),"\ub97c ",(0,a.kt)("inlineCode",{parentName:"p"},"<br>"),"\ud0dc\uadf8\ub85c \ubcc0\ud658\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcc0\ud658\ud558\ub294 \ub85c\uc9c1\uc740 GPT\uc758 \ub3c4\uc6c0\uc744 \ub9ce\uc774 \ubc1b\uc558\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},'const replaceCodeFences = (input: String) => {\n const codeFencesRegex = /```([\\w-]*)\\n([\\s\\S]*?)\\n```/g;\n return input\n .replace(codeFencesRegex, (match, p1, p2) => {\n const languageClass = p1 ? ` class="language-${p1}"` : "";\n return `<pre><code${languageClass}>${p2}</code></pre>`;\n })\n .replace(/\\n/g, "<br>");\n};\n')),(0,a.kt)("p",null,"Tiptap\uc744 \uc801\uc6a9\ud558\ub2c8 \ub2e4\uc74c\uacfc \uac19\uc774 \uae54\ub054\ud55c \ucf54\ub4dc \ube14\ub85d\uc744 \ubcfc \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"tecochat",src:n(49124).Z,width:"2388",height:"1500"})),(0,a.kt)("h3",{id:"\ud3f0\ud2b8-\ubc0f-favicon-\uc801\uc6a9"},"\ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9"),(0,a.kt)("p",null,"\ud0c0\uc774\ud2c0\uc740 \ubc30\ub2ec\uc758\ubbfc\uc871 \ub3c4\ud604\uccb4, \ub0b4\uc6a9\uc740 IBM Plex Sans\ub97c \uc0ac\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c favicon\ub3c4 \uac04\ub2e8\ud558\uac8c \uc801\uc6a9\ud574\uc11c \ub9cc\uc871\uc2a4\ub7ec\uc6e0\ub2e4."))}s.isMDXComponent=!0},49124:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/teco-chat-6b4f31b3d961878efc5c506fc167df1f.png"}}]); \ No newline at end of file diff --git a/assets/js/d8775059.f37a361d.js b/assets/js/d8775059.f37a361d.js new file mode 100644 index 000000000..2655d0b3e --- /dev/null +++ b/assets/js/d8775059.f37a361d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6387],{33604:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var r=t(85893),c=t(3905);const a={title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",slug:"tecochat-retrospective-1",tags:["TecoChat","Retrospective"]},s=void 0,i={permalink:"/tecochat-retrospective-1",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",source:"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",description:"4\uc6d4 21\uc77c \uae08\uc694\uc77c",date:"2023-04-22T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 22\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.68,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",slug:"tecochat-retrospective-1",tags:["TecoChat","Retrospective"]},unlisted:!1,prevItem:{title:"Jenkins\ub85c CI/CD \uc124\uc815",permalink:"/jenkins"},nextItem:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",permalink:"/book-leadership-and-self-deception"}},o={authorsImageUrls:[]},l=[{value:"4\uc6d4 21\uc77c \uae08\uc694\uc77c",id:"4\uc6d4-21\uc77c-\uae08\uc694\uc77c",level:3},{value:"\ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?",id:"\ub3c4\uba54\uc778-\uad6c\uc785-\uc131\uacf5",level:3},{value:"\ub9d0\ub791\uc758 DM",id:"\ub9d0\ub791\uc758-dm",level:3},{value:"\ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec",id:"\ub3c4\uba54\uc778-\uc124\uc815-\ubc0f-\ubc30\ud3ec",level:3},{value:"GPT",id:"gpt",level:3},{value:"Sonarcloud",id:"sonarcloud",level:3},{value:"Tiptap",id:"tiptap",level:3},{value:"\ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9",id:"\ud3f0\ud2b8-\ubc0f-favicon-\uc801\uc6a9",level:3}];function p(e){const n={br:"br",code:"code",h3:"h3",img:"img",p:"p",pre:"pre",...(0,c.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"4\uc6d4-21\uc77c-\uae08\uc694\uc77c",children:"4\uc6d4 21\uc77c \uae08\uc694\uc77c"}),"\n",(0,r.jsxs)(n.p,{children:["\ub808\ubca8 2\ub97c \uc2dc\uc791\ud55c \ub4a4 \ub0b4\uac00 \ud559\uc2b5\uc5d0 \ub300\ud55c \ubc29\ud5a5\uc744 \uc783\uc5b4\ubc84\ub838\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub808\ubca8 3, 4\uc5d0\uc11c \ub098\ub9cc\uc758 \uac15\uc810\uc744 \uac00\uc9c0\uace0 \uc2f6\uc5b4 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub2e8\uc21c\ud788 \uc2a4\ud504\ub9c1\uc744 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ud6a8\uc728\uc774 \ub9ce\uc774 \ub5a8\uc5b4\uc9c4\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uae00\uc4f0\uae30 \uc218\uc0c1\uc73c\ub85c \ubc1b\uc740 \ucfe0\ud3f0\uc744 \uc0ac\uc6a9\ud574 \ube0c\ub77c\uc6b4\uc5d0\uac8c \ucee4\ud53c\ucc57\uc744 \uc2e0\uccad\ud588\uace0, \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud574\ubcf4\ub77c\ub294 \ub2f5\uc744 \ubc1b\uc558\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ub098\ub294 \uc544\uc774\ub514\uc5b4\ub97c \ubabb\ub0b4\ub294 \ud3b8\uc778\ub370 \ube0c\ub77c\uc6b4\uc774 \uc544\uc774\ub514\uc5b4\uae4c\uc9c0 \ub358\uc838\uc8fc\uc168\ub2e4.",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.code,{children:"Chat-GPT \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uace0, \ud574\ub2f9 \ud06c\ub8e8\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc744 \uacf5\uc720\ud560 \uc218 \uc788\ub294 \uac74 \uc5b4\ub5a4\uc9c0?"})]}),"\n",(0,r.jsxs)(n.p,{children:["\uae30\uc220\uc774 \ubaa9\uc801\uc778 \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4\ub294 \ub2f5\ubcc0\uc744 \ub4e4\uc5c8\uace0, \ud63c\uc790 \uc544\ub2c8\uba74 \ud398\uc5b4\ud560 \uc218 \uc788\uc744 \uc815\ub3c4\uc758 \uc778\uc6d0\uc73c\ub85c \uc9c4\ud589\ud558\uba74 \uc88b\uaca0\ub2e4\uace0 \ud558\uc168\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud504\ub860\ud2b8\ub791 \uac04\ub2e8\ud558\uac8c \ubc30\ud3ec\uae4c\uc9c0 \ud574\ubcf8 \uacbd\ud5d8\uc774 \uc788\uc5b4\uc11c \ud63c\uc790\ud574\ub3c4 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uc744 \uac83 \uac19\uc544\uc11c \ud63c\uc790 \ud558\uae30\ub85c \ub9c8\uc74c\uc744 \uba39\uc5c8\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\uc774\uac74 \ubabb\ucc38\uc9c0"}),"\n",(0,r.jsx)(n.h3,{id:"\ub3c4\uba54\uc778-\uad6c\uc785-\uc131\uacf5",children:"\ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?"}),"\n",(0,r.jsxs)(n.p,{children:["\ucee4\ud53c\ucc57\uc774 \ub05d\ub098\uace0 \uc9d1\uc73c\ub85c \ub3cc\uc544\uac00\ub294 \uae38\uc5d0 \ubc14\ub85c \ub3c4\uba54\uc778\uc744 \uad6c\ub9e4\ud558\ub824\uace0 namecheap\uc5d0\uc11c \uc801\ub2f9\ud55c \ub3c4\uba54\uc778\uc774 \uc5c6\uc744\uae4c \uac80\uc0c9\uc744 \uacc4\uc18d\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub9c8\uce58 \uc5b4\ub9b4 \ub54c \ud588\ub358 \uac8c\uc784 \ub2c9\ub124\uc784 \uc815\ud558\ub294 \uac83\ucc98\ub7fc \uc2dc\uac04\uc774 \uc624\ub798 \uac78\ub838\ub2e4.",(0,r.jsx)(n.br,{}),"\n","dev, io, chat \ub3c4\uba54\uc778\uc774 \ud6c4\ubcf4\uc600\uace0 \uc9d1 \uac00\ub294 \uae38\uc5d0 \uacb0\uc815\ub9cc \ud558\ub2e4\uac00 \uad6c\ub9e4\ud558\uc9c0 \ubabb\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ub9d0\ub791\uc758-dm",children:"\ub9d0\ub791\uc758 DM"}),"\n",(0,r.jsxs)(n.p,{children:["\uc9d1\uc5d0 \uac00\uc11c \ubc25\uc744 \uba39\uace0 \ub9d0\ub791\uc774\ub791 DM \ud558\ub2e4 \ud504\ub85c\uc81d\ud2b8\ub97c \uac19\uc774 \ud558\uc790\ub294 \uc774\uc57c\uae30\uac00 \ub098\uc654\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc6b0\ud14c\ucf54 \ucd5c\uace0 \uace0\uc218 \ub9d0\ub791\uc758 \uc694\uad6c\ub77c \uc218\ub77d\ud558\uc9c0 \uc54a\uc73c\uba74 \ud6c4\ud3ed\ud48d\uc744 \uac10\ub2f9\ud560 \uc218 \uc5c6\uc5c8\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ub7f0\uc800\ub7f0 \ub300\ud654\ub97c \ub098\ub204\ub2e4\uac00 \ub09c \ube60\ub974\uac8c \ud504\ub85c\ud1a0\ud0c0\uc785\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\uace0 \uc2f6\uc5b4\uc11c \ud504\ub860\ud2b8\ub97c \uad6c\ud604\ud55c\ub2e4\uace0 \ud588\uace0, \ub9d0\ub791\uc740 GPT api\ub97c \uc870\uc0ac\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ub3c4\uba54\uc778\uc5d0 \uad00\ud55c \uc774\uc57c\uae30\ub97c \ud558\ub2e4\uac00 woowachat\uc774 \uc5b8\uae09\ub418\uc5c8\uace0, namecheap\uc5d0\uc11c chat \ub3c4\uba54\uc778\uc744 \uc0ac\uc6a9\ud55c woowa.chat\uc73c\ub85c \uad6c\ub9e4\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ud6c4\uc5d0 teco.chat\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4!"]}),"\n",(0,r.jsx)(n.h3,{id:"\ub3c4\uba54\uc778-\uc124\uc815-\ubc0f-\ubc30\ud3ec",children:"\ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec"}),"\n",(0,r.jsxs)(n.p,{children:["\ud1a0\uc694\uc77c\uc5d0 \uad6c\ub9e4\ud55c \ub3c4\uba54\uc778\uc744 CDN, \ubcf4\uc548 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\ub294 Cloudflare\uc5d0 \ub3c4\uba54\uc778 \ub4f1\ub85d\uc744 \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub098\uc5d0\uac8c \uc775\uc219\ud55c Nuxt3\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\uace0, Cloudflare Pages\ub97c \uc774\uc6a9\ud558\uc5ec \ubc30\ud3ec\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"gpt",children:"GPT"}),"\n",(0,r.jsxs)(n.p,{children:["\ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud558\ub2c8 api limit\uc774 \uc788\uc5b4 \ubd84\ub2f9 3\ubc88\ubc16\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc77c\ub2e8 \ubc31\uc5d4\ub4dc\ub97c \uad6c\ucd95\ud558\uae30 \uc804\uc5d0\ub294 \ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud560 \uc0dd\uac01\uc774\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"sonarcloud",children:"Sonarcloud"}),"\n",(0,r.jsxs)(n.p,{children:["\uc815\uc801 \ucf54\ub4dc \ubd84\uc11d \ub3c4\uad6c\ub85c Sonarcloud\ub97c \uc801\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Sonarcloud\ub294 SonarQube\uc758 SaaS \ubc84\uc804\uc774\uace0 \uc0ac\uc6a9\uc774 \ub9e4\uc6b0 \ud3b8\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc608\uc804\uc5d0 Sonarcloud\ub97c \uc0ac\uc6a9\ud560 \ub550 \ubc84\ud2bc \uba87 \ubc88 \ub204\ub974\uba74 \uc801\uc6a9\ud560 \uc218 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \ubc14\ub85c github action\uc744 \uc0ac\uc6a9\ud558\ub77c\ub294 \uc548\ub0b4 \ud398\uc774\uc9c0\ub85c \uc774\ub3d9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Sonarcloud\uac00 \uc790\uccb4\uc801\uc73c\ub85c github repository\uc5d0 push \ud558\uba74 \uc815\uc801 \ubd84\uc11d\uc744 \ud574\uc8fc\ub294 \uae30\ub2a5\uc744 \uc6d0\ud588\uace0, Administration -> Analysis Method\uc5d0 Automatic Analysis\ub97c \uc124\uc815\ud558\ub2c8 \ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub108\ubb34 \uaf41\uaf41 \uc228\uaca8\uc838\uc788\ub124"]}),"\n",(0,r.jsx)(n.h3,{id:"tiptap",children:"Tiptap"}),"\n",(0,r.jsxs)(n.p,{children:["\ucf54\ub4dc \ud558\uc774\ub77c\uc774\ud305 \uae30\ub2a5\uc744 \ub123\uace0 \uc2f6\uc5b4\uc11c Tiptap\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Tiptap\uc740 Headless WYSIWYG \uc5d0\ub514\ud130\ub85c \uc0ac\uc6a9\uc790 \uc815\uc758 \uae30\ub2a5\uc5d0 \ud2b9\ud654\ub418\uc5b4\uc788\ub294 \uc5d0\ub514\ud130\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc544\uc9c1 Tiptap\uc774 \uc81c\uacf5\ud558\ub294 \ubaa8\ub4e0 \uae30\ub2a5\uc744 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc0ac\uc6a9\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc CodeBlockLowlight \ud50c\ub7ec\uadf8\uc778\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucf54\ub4dc \ube14\ub85d\uc744 \uc608\uc058\uac8c \ucd9c\ub825\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","api \ubc18\ud658\uac12 \uadf8\ub300\ub85c tiptap\uc758 content\uc5d0 \uc124\uc815\ud588\ub354\ub2c8 \ucf54\ub4dc \ube14\ub85d\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc544\uc11c \ubc31 \ud2f1 3\uac1c\ub97c ",(0,r.jsx)(n.code,{children:"<pre><code>"}),"\ub85c \ubcc0\ud658\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ub744\uc5b4\uc4f0\uae30\ub3c4 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc544\uc11c ",(0,r.jsx)(n.code,{children:"\\n"}),"\ub97c ",(0,r.jsx)(n.code,{children:"<br>"}),"\ud0dc\uadf8\ub85c \ubcc0\ud658\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubcc0\ud658\ud558\ub294 \ub85c\uc9c1\uc740 GPT\uc758 \ub3c4\uc6c0\uc744 \ub9ce\uc774 \ubc1b\uc558\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const replaceCodeFences = (input: String) => {\n const codeFencesRegex = /```([\\w-]*)\\n([\\s\\S]*?)\\n```/g;\n return input\n .replace(codeFencesRegex, (match, p1, p2) => {\n const languageClass = p1 ? ` class="language-${p1}"` : "";\n return `<pre><code${languageClass}>${p2}</code></pre>`;\n })\n .replace(/\\n/g, "<br>");\n};\n'})}),"\n",(0,r.jsx)(n.p,{children:"Tiptap\uc744 \uc801\uc6a9\ud558\ub2c8 \ub2e4\uc74c\uacfc \uac19\uc774 \uae54\ub054\ud55c \ucf54\ub4dc \ube14\ub85d\uc744 \ubcfc \uc218 \uc788\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"tecochat",src:t(49124).Z+"",width:"2388",height:"1500"})}),"\n",(0,r.jsx)(n.h3,{id:"\ud3f0\ud2b8-\ubc0f-favicon-\uc801\uc6a9",children:"\ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9"}),"\n",(0,r.jsxs)(n.p,{children:["\ud0c0\uc774\ud2c0\uc740 \ubc30\ub2ec\uc758\ubbfc\uc871 \ub3c4\ud604\uccb4, \ub0b4\uc6a9\uc740 IBM Plex Sans\ub97c \uc0ac\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c favicon\ub3c4 \uac04\ub2e8\ud558\uac8c \uc801\uc6a9\ud574\uc11c \ub9cc\uc871\uc2a4\ub7ec\uc6e0\ub2e4."]})]})}function d(e={}){const{wrapper:n}={...(0,c.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>l});var r=t(67294);function c(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?a(Object(t),!0).forEach((function(n){c(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function i(e,n){if(null==e)return{};var t,r,c=function(e,n){if(null==e)return{};var t,r,c={},a=Object.keys(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||(c[t]=e[t]);return c}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(c[t]=e[t])}return c}var o=r.createContext({}),l=function(e){var n=r.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,c=e.mdxType,a=e.originalType,o=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),h=l(t),u=c,j=h["".concat(o,".").concat(u)]||h[u]||p[u]||a;return t?r.createElement(j,s(s({ref:n},d),{},{components:t})):r.createElement(j,s({ref:n},d))}));d.displayName="MDXCreateElement"},49124:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/teco-chat-6b4f31b3d961878efc5c506fc167df1f.png"}}]); \ No newline at end of file diff --git a/assets/js/d88bdb28.4d81ac29.js b/assets/js/d88bdb28.d72f94d3.js similarity index 81% rename from assets/js/d88bdb28.4d81ac29.js rename to assets/js/d88bdb28.d72f94d3.js index 2da943b01..685fae00a 100644 --- a/assets/js/d88bdb28.4d81ac29.js +++ b/assets/js/d88bdb28.d72f94d3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9788],{29417:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9788],{29417:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/d8cdf5ef.1054df5c.js b/assets/js/d8cdf5ef.1054df5c.js deleted file mode 100644 index 492715c63..000000000 --- a/assets/js/d8cdf5ef.1054df5c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5919],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var p=n.createContext({}),l=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,p=e.parentName,s=c(e,["components","mdxType","originalType","parentName"]),d=l(r),m=a,f=d["".concat(p,".").concat(m)]||d[m]||u[m]||o;return r?n.createElement(f,i(i({ref:t},s),{},{components:r})):n.createElement(f,i({ref:t},s))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=d;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c.mdxType="string"==typeof e?e:a,i[1]=c;for(var l=2;l<o;l++)i[l]=r[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},11311:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var n=r(87462),a=(r(67294),r(3905));const o={title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",slug:"/etc/experience-and-self-question",last_update:{date:"2023/09/01"},tags:["etc"]},i=void 0,c={unversionedId:"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8",id:"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8",title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",description:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 10\uc6d4 6\uc77c",source:"@site/docs/\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8.mdx",sourceDirName:"\uae30\ud0c0",slug:"/etc/experience-and-self-question",permalink:"/docs/etc/experience-and-self-question",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8.mdx",tags:[{label:"etc",permalink:"/docs/tags/etc"}],version:"current",lastUpdatedAt:1693526400,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 1\uc77c",frontMatter:{title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",slug:"/etc/experience-and-self-question",last_update:{date:"2023/09/01"},tags:["etc"]},sidebar:"tutorialSidebar",previous:{title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",permalink:"/docs/etc/develop-with-spring"},next:{title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",permalink:"/docs/etc/communication"}},p={},l=[{value:"\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8",id:"\uc790\uae30-\uc8fc\ub3c4\uc801\uc73c\ub85c-\ubb38\uc81c\ub97c-\ud574\uacb0\ud558\uae30-\uc704\ud55c-\ub3c4\uc804-\uacbd\ud5d8",level:3},{value:"\uc790\uc2e0\uc5d0\uac8c \ub358\uc838\ubd10\uc57c\ud560 \uc9c8\ubb38",id:"\uc790\uc2e0\uc5d0\uac8c-\ub358\uc838\ubd10\uc57c\ud560-\uc9c8\ubb38",level:3}],s={toc:l};function u(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 10\uc6d4 6\uc77c",(0,a.kt)("br",{parentName:"p"}),"\n","\ud3ec\ube44 \ud2b9\uac15"),(0,a.kt)("h3",{id:"\uc790\uae30-\uc8fc\ub3c4\uc801\uc73c\ub85c-\ubb38\uc81c\ub97c-\ud574\uacb0\ud558\uae30-\uc704\ud55c-\ub3c4\uc804-\uacbd\ud5d8"},"\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8"),(0,a.kt)("p",null,"\ud300 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \ubc1c\uc0dd\ud55c \ud300\uc6d0 \uac04\uc758 \uac08\ub4f1\uc744 \ud574\uacb0\ud558\uae30 \uc704\ud574 \ub3c4\uc804\ud55c \uacbd\ud5d8",(0,a.kt)("br",{parentName:"p"}),"\n","\ud300 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uc2e4 \uc0ac\uc6a9\uc790\ub97c \ubaa8\uc9d1\ud558\uae30 \uc704\ud574 \ub3c4\uc804\ud55c \uacbd\ud5d8",(0,a.kt)("br",{parentName:"p"}),"\n","\ud300\uc5d0\uc11c \uad00\uc2ec\uc744 \uac00\uc9c0\uc9c0 \uc54a\ub294 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ub05d\uae4c\uc9c0 \ub3c4\uc804\ud55c \uacbd\ud5d8",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \ub04c\ub9ac\ub294 \uc8fc\uc81c\uc5d0 \ub300\ud574 \uae4a\uc774 \uc788\uac8c \ud559\uc2b5\ud558\uace0 \ud504\ub85c\uc81d\ud2b8\uc5d0 \uc801\uc6a9\ud55c \uacbd\ud5d8",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\uc6a9\uc790 \uacbd\ud5d8\uc744 \ud55c \ub2e8\uacc4 \ub354 \ub192\uc774\uae30 \uc704\ud574 \ub3c4\uc804\ud55c \uacbd\ud5d8",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2f9\uc5f0\ud558\ub2e4 \uc0dd\uac01\ud558\ub294 \ud574\uacb0\ucc45\uc5d0 \uc758\uad6c\uc2ec\uc744 \uac00\uc9c0\uace0 \uc0c8\ub85c\uc6b4 \uc811\uadfc \ubc29\uc2dd\uc73c\ub85c \ub3c4\uc804\ud55c \uacbd\ud5d8 "),(0,a.kt)("h3",{id:"\uc790\uc2e0\uc5d0\uac8c-\ub358\uc838\ubd10\uc57c\ud560-\uc9c8\ubb38"},"\uc790\uc2e0\uc5d0\uac8c \ub358\uc838\ubd10\uc57c\ud560 \uc9c8\ubb38"),(0,a.kt)("p",null,"\ub098\ub294 \ud504\ub85c\uadf8\ub798\ubc0d \uc790\uccb4\ub97c \uc990\uae30\uace0 \uc788\ub294\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub294 \uc65c \ud504\ub85c\uadf8\ub798\uba38\uac00 \ub418\ub824\uace0 \ud558\ub294\uac00?",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub294 \ub098\ub2f5\uac8c \uc0b4\uace0 \uc788\ub098?",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub294 \uc8fc\ub3c4\uc801\uc73c\ub85c \uc0b4\uace0 \uc788\ub098?"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/d8cdf5ef.23e4a2d1.js b/assets/js/d8cdf5ef.23e4a2d1.js new file mode 100644 index 000000000..56374a00a --- /dev/null +++ b/assets/js/d8cdf5ef.23e4a2d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5919],{79101:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var n=r(85893),c=r(3905);const i={title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",slug:"/etc/experience-and-self-question",last_update:{date:"2023/09/01"},tags:["etc"]},s=void 0,o={id:"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8",title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",description:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 10\uc6d4 6\uc77c",source:"@site/docs/\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8.mdx",sourceDirName:"\uae30\ud0c0",slug:"/etc/experience-and-self-question",permalink:"/docs/etc/experience-and-self-question",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8.mdx",tags:[{label:"etc",permalink:"/docs/tags/etc"}],version:"current",lastUpdatedAt:1693526400,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 1\uc77c",frontMatter:{title:"\uacbd\ud5d8\uacfc \uc9c8\ubb38",slug:"/etc/experience-and-self-question",last_update:{date:"2023/09/01"},tags:["etc"]},sidebar:"tutorialSidebar",previous:{title:"\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30",permalink:"/docs/etc/develop-with-spring"},next:{title:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00",permalink:"/docs/etc/communication"}},a={},l=[{value:"\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8",id:"\uc790\uae30-\uc8fc\ub3c4\uc801\uc73c\ub85c-\ubb38\uc81c\ub97c-\ud574\uacb0\ud558\uae30-\uc704\ud55c-\ub3c4\uc804-\uacbd\ud5d8",level:3},{value:"\uc790\uc2e0\uc5d0\uac8c \ub358\uc838\ubd10\uc57c\ud560 \uc9c8\ubb38",id:"\uc790\uc2e0\uc5d0\uac8c-\ub358\uc838\ubd10\uc57c\ud560-\uc9c8\ubb38",level:3}];function p(e){const t={br:"br",h3:"h3",p:"p",...(0,c.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 2023\ub144 10\uc6d4 6\uc77c",(0,n.jsx)(t.br,{}),"\n","\ud3ec\ube44 \ud2b9\uac15"]}),"\n",(0,n.jsx)(t.h3,{id:"\uc790\uae30-\uc8fc\ub3c4\uc801\uc73c\ub85c-\ubb38\uc81c\ub97c-\ud574\uacb0\ud558\uae30-\uc704\ud55c-\ub3c4\uc804-\uacbd\ud5d8",children:"\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8"}),"\n",(0,n.jsxs)(t.p,{children:["\ud300 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \ubc1c\uc0dd\ud55c \ud300\uc6d0 \uac04\uc758 \uac08\ub4f1\uc744 \ud574\uacb0\ud558\uae30 \uc704\ud574 \ub3c4\uc804\ud55c \uacbd\ud5d8",(0,n.jsx)(t.br,{}),"\n","\ud300 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uc2e4 \uc0ac\uc6a9\uc790\ub97c \ubaa8\uc9d1\ud558\uae30 \uc704\ud574 \ub3c4\uc804\ud55c \uacbd\ud5d8",(0,n.jsx)(t.br,{}),"\n","\ud300\uc5d0\uc11c \uad00\uc2ec\uc744 \uac00\uc9c0\uc9c0 \uc54a\ub294 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud574 \ub05d\uae4c\uc9c0 \ub3c4\uc804\ud55c \uacbd\ud5d8",(0,n.jsx)(t.br,{}),"\n","\ub0b4\uac00 \ub04c\ub9ac\ub294 \uc8fc\uc81c\uc5d0 \ub300\ud574 \uae4a\uc774 \uc788\uac8c \ud559\uc2b5\ud558\uace0 \ud504\ub85c\uc81d\ud2b8\uc5d0 \uc801\uc6a9\ud55c \uacbd\ud5d8",(0,n.jsx)(t.br,{}),"\n","\uc0ac\uc6a9\uc790 \uacbd\ud5d8\uc744 \ud55c \ub2e8\uacc4 \ub354 \ub192\uc774\uae30 \uc704\ud574 \ub3c4\uc804\ud55c \uacbd\ud5d8",(0,n.jsx)(t.br,{}),"\n","\ub2f9\uc5f0\ud558\ub2e4 \uc0dd\uac01\ud558\ub294 \ud574\uacb0\ucc45\uc5d0 \uc758\uad6c\uc2ec\uc744 \uac00\uc9c0\uace0 \uc0c8\ub85c\uc6b4 \uc811\uadfc \ubc29\uc2dd\uc73c\ub85c \ub3c4\uc804\ud55c \uacbd\ud5d8"]}),"\n",(0,n.jsx)(t.h3,{id:"\uc790\uc2e0\uc5d0\uac8c-\ub358\uc838\ubd10\uc57c\ud560-\uc9c8\ubb38",children:"\uc790\uc2e0\uc5d0\uac8c \ub358\uc838\ubd10\uc57c\ud560 \uc9c8\ubb38"}),"\n",(0,n.jsxs)(t.p,{children:["\ub098\ub294 \ud504\ub85c\uadf8\ub798\ubc0d \uc790\uccb4\ub97c \uc990\uae30\uace0 \uc788\ub294\uac00?",(0,n.jsx)(t.br,{}),"\n","\ub098\ub294 \uc65c \ud504\ub85c\uadf8\ub798\uba38\uac00 \ub418\ub824\uace0 \ud558\ub294\uac00?",(0,n.jsx)(t.br,{}),"\n","\ub098\ub294 \ub098\ub2f5\uac8c \uc0b4\uace0 \uc788\ub098?",(0,n.jsx)(t.br,{}),"\n","\ub098\ub294 \uc8fc\ub3c4\uc801\uc73c\ub85c \uc0b4\uace0 \uc788\ub098?"]})]})}function u(e={}){const{wrapper:t}={...(0,c.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){c(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function o(e,t){if(null==e)return{};var r,n,c=function(e,t){if(null==e)return{};var r,n,c={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(c[r]=e[r]);return c}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var a=n.createContext({}),l=function(e){var t=n.useContext(a),r=t;return e&&(r="function"==typeof e?e(t):s(s({},t),e)),r},p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,c=e.mdxType,i=e.originalType,a=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=l(r),f=c,b=d["".concat(a,".").concat(f)]||d[f]||p[f]||i;return r?n.createElement(b,s(s({ref:t},u),{},{components:r})):n.createElement(b,s({ref:t},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/da14f319.cc63b465.js b/assets/js/da14f319.cc63b465.js new file mode 100644 index 000000000..5349977e0 --- /dev/null +++ b/assets/js/da14f319.cc63b465.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5485],{96893:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var t=n(85893),o=n(3905);const i={title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",slug:"/spring/essence",last_update:{date:"2023/10/05"},tags:["spring"]},s=void 0,c={id:"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",description:'\uc2a4\ud504\ub9c1\uc758 \ud575\uc2ec \uac1c\ubc1c\uc790\ub4e4\uc774 \uc4f4 Professional Spring Framework \ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc758 \uc815\uc218(essence)\ub294 "\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\ub294 \uac83" \uc774\ub77c\uace0 \ud588\ub2e4.',source:"@site/docs/\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5.md",sourceDirName:"\uc2a4\ud504\ub9c1",slug:"/spring/essence",permalink:"/docs/spring/essence",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5.md",tags:[{label:"spring",permalink:"/docs/tags/spring"}],version:"current",lastUpdatedAt:1696464e3,formattedLastUpdatedAt:"2023\ub144 10\uc6d4 5\uc77c",frontMatter:{title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",slug:"/spring/essence",last_update:{date:"2023/10/05"},tags:["spring"]},sidebar:"tutorialSidebar",previous:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",permalink:"/docs/performance/types"},next:{title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",permalink:"/docs/architecture/virtical-slice-architecture"}},a={},l=[{value:"POJO(Plain Old Java Object)",id:"pojoplain-old-java-object",level:3},{value:"IoC/DI(Inversion of Control/Dependency Injection)",id:"iocdiinversion-of-controldependency-injection",level:3},{value:"AOP(Aspect Oriented Programming)",id:"aopaspect-oriented-programming",level:3},{value:"PSA(Portable Service Abstraction)",id:"psaportable-service-abstraction",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const r={a:"a",blockquote:"blockquote",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.p,{children:'\uc2a4\ud504\ub9c1\uc758 \ud575\uc2ec \uac1c\ubc1c\uc790\ub4e4\uc774 \uc4f4 Professional Spring Framework \ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc758 \uc815\uc218(essence)\ub294 "\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\ub294 \uac83" \uc774\ub77c\uace0 \ud588\ub2e4.'}),"\n",(0,t.jsx)(r.h3,{id:"pojoplain-old-java-object",children:"POJO(Plain Old Java Object)"}),"\n",(0,t.jsx)(r.p,{children:"\uac1d\uc81c\uc9c0\ud5a5\uc801\uc778 \uc6d0\ub9ac\uc5d0 \ucda9\uc2e4\ud558\uba74\uc11c, \ud658\uacbd\uacfc \uae30\uc220\uc5d0 \uc885\uc18d\ub418\uc9c0 \uc54a\uace0 \ud544\uc694\uc5d0 \ub530\ub77c \uc7ac\ud65c\uc6a9\ub420 \uc218 \uc788\ub294 \ubc29\uc2dd\uc73c\ub85c \uc124\uacc4\ub41c \uc624\ube0c\uc81d\ud2b8\n\uc2a4\ud504\ub9c1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc740 POJO\ub97c \uc774\uc6a9\ud574\uc11c \ub9cc\ub4e0 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ucf54\ub4dc\uc640, POJO\uac00 \uc5b4\ub5bb\uac8c \uad00\uacc4\ub97c \ub9fa\uace0 \ub3d9\uc791\ud558\ub294\uc9c0 \uc815\uc758\ud574\ub193\uc740 \uc124\uacc4 \uc815\ubcf4\ub85c \uad6c\ubd84\ub41c\ub2e4."}),"\n",(0,t.jsx)(r.h3,{id:"iocdiinversion-of-controldependency-injection",children:"IoC/DI(Inversion of Control/Dependency Injection)"}),"\n",(0,t.jsxs)(r.p,{children:["\uc81c\uc5b4\uc758 \uc5ed\uc804(IoC)\uc740 \uc2a4\ud504\ub9c1\uc5d0\uc11c\ub9cc \uc801\uc6a9\ub418\ub294 \uac1c\ub150\uc740 \uc544\ub2c8\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uac04\ub2e8\ud558\uac8c \uc124\uba85\ud558\uc790\uba74 \ud504\ub85c\uadf8\ub7a8\uc758 \uc81c\uc5b4 \ud750\ub984 \uad6c\uc870\uac00 \ubc14\ub00c\ub294 \uac83\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud504\ub808\uc784\uc6cc\ud06c\ub294 \uc81c\uc5b4\uc758 \uc5ed\uc804\uc774 \uc801\uc6a9\ub41c \ub300\ud45c\uc801\uc778 \uae30\uc220\uc774\ub77c\uace0 \ubcfc \uc218 \uc788\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc758\uc874\uc131 \uc8fc\uc785(DI)\uc740 \ud074\ub798\uc2a4 \uc0ac\uc774\uc758 \uc758\uc874\uad00\uacc4\ub97c \uc124\uc815 \uc815\ubcf4\ub97c \ubc14\ud0d5\uc73c\ub85c \ucee8\ud14c\uc774\ub108\uac00 \uc790\ub3d9\uc801\uc73c\ub85c \uc5f0\uacb0\ud574 \uc8fc\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc2a4\ud504\ub9c1\uc740 IoC/DI\ub97c \ud1b5\ud574 \uc2f1\uae00\ud1a4 \ud615\ud0dc\uc758 \uc624\ube0c\uc81d\ud2b8\uc758 \uc0dd\uc131, \uad00\uacc4 \uc124\uc815, \uacf5\uae09\uc5d0 \ub300\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4. \uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 IoC \ucee8\ud14c\uc774\ub108 \ub610\ub294 DI \ucee8\ud14c\uc774\ub108\ub77c\uace0\ub3c4 \ubd88\ub9b0\ub2e4."]}),"\n",(0,t.jsx)(r.p,{children:"\ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 DI \ucee8\ud14c\uc774\ub108\ub77c\ub294 \uc6a9\uc5b4\uc5d0 \ub300\ud574 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uba85\ud558\uace0 \uc788\ub2e4."}),"\n",(0,t.jsxs)(r.blockquote,{children:["\n",(0,t.jsxs)(r.p,{children:["IoC\uac00 \ub9e4\uc6b0 \ub290\uc2a8\ud558\uac8c \uc815\uc758\ub3fc\uc11c \ud3ed\ub113\uac8c \uc0ac\uc6a9\ub418\ub294 \uc6a9\uc5b4\ub77c\ub294 \uc810\uc774\ub2e4. \ub54c\ubb38\uc5d0 \uc2a4\ud504\ub9c1\uc744 IoC \ucee8\ud14c\uc774\ub108\ub77c\uace0\ub9cc \ud574\uc11c\ub294 \uc2a4\ud504\ub9c1\uc774 \uc81c\uacf5\ud558\ub294 \uae30\ub2a5\uc758 \ud2b9\uc9d5\uc744 \uba85\ud655\ud558\uac8c \uc124\uba85\ud558\uc9c0 \ubabb\ud55c\ub2e4. \u2026 \uc0c8\ub85c\uc6b4 \uc6a9\uc5b4\ub97c \ub9cc\ub4dc\ub294 \ub370 \ud0c1\uc6d4\ud55c \uc7ac\ub2a5\uc774 \uc788\ub294 \uba87\uba87 \uc0ac\ub78c\uc758 \uc81c\uc548\uc73c\ub85c \uc2a4\ud504\ub9c1\uc774 \uc81c\uacf5\ud558\ub294 IoC \ubc29\uc2dd\uc758 \ud575\uc2ec\uc744 \uc9da\uc5b4\uc8fc\ub294 \uc758\uc874\uad00\uacc4 \uc8fc\uc785(DI)\uc774\ub77c\ub294, \uc880 \ub354 \uc758\ub3c4\uac00 \uba85\ud655\ud788 \ub4dc\ub7ec\ub098\ub294 \uc774\ub984\uc744 \uc0ac\uc6a9\ud558\uae30 \uc2dc\uc791\ud588\ub2e4. \uc2a4\ud504\ub9c1 IoC \uae30\ub2a5\uc758 \ub300\ud45c\uc801\uc778 \ub3d9\uc791\uc6d0\ub9ac\ub294 \uc8fc\ub85c \uc758\uc874\uad00\uacc4 \uc8fc\uc785\uc774\ub77c\uace0 \ubd88\ub9b0\ub2e4. \u2026 \uadf8\ub798\uc11c \ucd08\uae30\uc5d0\ub294 \uc8fc\ub85c IoC \ucee8\ud14c\uc774\ub108\ub77c\uace0 \ubd88\ub9ac\ub358 \uc2a4\ud504\ub9c1\uc774 \uc9c0\uae08\uc740 \uc758\uc874\uad00\uacc4 \uc8fc\uc785 \ucee8\ud14c\uc774\ub108 \ub610\ub294 DI \ucee8\ud14c\uc774\ub108\ub77c\uace0 \ub9ce\uc774 \ubd88\ub9b0\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1 p.111"]}),"\n"]}),"\n",(0,t.jsx)(r.h3,{id:"aopaspect-oriented-programming",children:"AOP(Aspect Oriented Programming)"}),"\n",(0,t.jsxs)(r.p,{children:["\uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ud575\uc2ec\uc801\uc778 \uae30\ub2a5\uc5d0\uc11c \ubd80\uac00\uc801\uc778 \uae30\ub2a5\uc744 \ubd84\ub9ac\ud574\uc11c \ubaa8\ub4c8\ud654\ud558\ub294 \uac83",(0,t.jsx)(r.br,{}),"\n","\uc608) \ud575\uc2ec \uae30\ub2a5 = \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1, \ubd80\uac00 \uae30\ub2a5 = \ub85c\uae45, \ud2b8\ub79c\uc7ad\uc158",(0,t.jsx)(r.br,{}),"\n","\uad00\uc810 \uc9c0\ud5a5 \ud504\ub85c\uadf8\ub798\ubc0d\uc774\ub77c\uace0 \ud558\ub294\ub370 \uc774\ub294 OOP\uc640 \uac19\uc774 \ub3c5\ub9bd\uc801\uc778 \ud504\ub85c\uadf8\ub798\ubc0d \ud328\ub7ec\ub2e4\uc784\uc774 \uc544\ub2cc \ubcf4\uc870\uc801\uc778 \uae30\uc220\uc774\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"psaportable-service-abstraction",children:"PSA(Portable Service Abstraction)"}),"\n",(0,t.jsxs)(r.p,{children:["\ud658\uacbd\uacfc \uc138\ubd80 \uae30\uc220\uc758 \ubcc0\ud654\uc5d0 \uad00\uacc4\uc5c6\uc774 \uc77c\uad00\ub41c \ubc29\uc2dd\uc73c\ub85c \uae30\uc220\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\uac8c \ud574\uc8fc\ub294 \uae30\uc220\uc774\ub2e4.",(0,t.jsx)(r.br,{}),"\n","POJO\ub85c \uac1c\ubc1c\ub41c \ucf54\ub4dc\ub294 \ud2b9\uc815 \ud658\uacbd\uc774\ub098 \uad6c\ud604 \ubc29\uc2dd\uc5d0 \uc885\uc18d\uc801\uc774\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4.",(0,t.jsx)(r.br,{}),"\n","\uc2a4\ud504\ub9c1\uc740 POJO \ucf54\ub4dc\uac00 \ud2b9\uc815 \uae30\uc220\uc5d0 \uc885\uc18d\ub418\uc9c0 \uc54a\uac8c \uc77c\uad00\uc131 \uc788\ub294 \uc11c\ube44\uc2a4 \ucd94\uc0c1\ud654 \uae30\uc220\uc744 \uc81c\uacf5\ud55c\ub2e4."]}),"\n",(0,t.jsx)(r.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(r.p,{children:[(0,t.jsx)(r.a,{href:"https://docs.spring.io/spring-framework/reference/",children:"Spring Core, Spring.io"}),(0,t.jsx)(r.br,{}),"\n","\ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1 3.1, \uc774\uc77c\ubbfc"]})]})}function d(e={}){const{wrapper:r}={...(0,o.ah)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,r,n)=>{n.d(r,{ah:()=>l});var t=n(67294);function o(e,r,n){return r in e?Object.defineProperty(e,r,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[r]=n,e}function i(e,r){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);r&&(t=t.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),n.push.apply(n,t)}return n}function s(e){for(var r=1;r<arguments.length;r++){var n=null!=arguments[r]?arguments[r]:{};r%2?i(Object(n),!0).forEach((function(r){o(e,r,n[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):i(Object(n)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(n,r))}))}return e}function c(e,r){if(null==e)return{};var n,t,o=function(e,r){if(null==e)return{};var n,t,o={},i=Object.keys(e);for(t=0;t<i.length;t++)n=i[t],r.indexOf(n)>=0||(o[n]=e[n]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)n=i[t],r.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var a=t.createContext({}),l=function(e){var r=t.useContext(a),n=r;return e&&(n="function"==typeof e?e(r):s(s({},r),e)),n},p={inlineCode:"code",wrapper:function(e){var r=e.children;return t.createElement(t.Fragment,{},r)}},d=t.forwardRef((function(e,r){var n=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),u=l(n),b=o,j=u["".concat(a,".").concat(b)]||u[b]||p[b]||i;return n?t.createElement(j,s(s({ref:r},d),{},{components:n})):t.createElement(j,s({ref:r},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/da14f319.f8f3a39f.js b/assets/js/da14f319.f8f3a39f.js deleted file mode 100644 index 43600bdea..000000000 --- a/assets/js/da14f319.f8f3a39f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5485],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,s=p(e,["components","mdxType","originalType","parentName"]),d=c(r),m=o,b=d["".concat(l,".").concat(m)]||d[m]||u[m]||a;return r?n.createElement(b,i(i({ref:t},s),{},{components:r})):n.createElement(b,i({ref:t},s))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=d;var p={};for(var l in t)hasOwnProperty.call(t,l)&&(p[l]=t[l]);p.originalType=e,p.mdxType="string"==typeof e?e:o,i[1]=p;for(var c=2;c<a;c++)i[c]=r[c];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},77168:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>p,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",slug:"/spring/essence",last_update:{date:"2023/10/05"},tags:["spring"]},i=void 0,p={unversionedId:"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",id:"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",description:'\uc2a4\ud504\ub9c1\uc758 \ud575\uc2ec \uac1c\ubc1c\uc790\ub4e4\uc774 \uc4f4 Professional Spring Framework \ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc758 \uc815\uc218(essence)\ub294 "\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\ub294 \uac83" \uc774\ub77c\uace0 \ud588\ub2e4.',source:"@site/docs/\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5.md",sourceDirName:"\uc2a4\ud504\ub9c1",slug:"/spring/essence",permalink:"/docs/spring/essence",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5.md",tags:[{label:"spring",permalink:"/docs/tags/spring"}],version:"current",lastUpdatedAt:1696464e3,formattedLastUpdatedAt:"2023\ub144 10\uc6d4 5\uc77c",frontMatter:{title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",slug:"/spring/essence",last_update:{date:"2023/10/05"},tags:["spring"]},sidebar:"tutorialSidebar",previous:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc720\ud615",permalink:"/docs/performance/types"},next:{title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",permalink:"/docs/architecture/virtical-slice-architecture"}},l={},c=[{value:"POJO(Plain Old Java Object)",id:"pojoplain-old-java-object",level:3},{value:"IoC/DI(Inversion of Control/Dependency Injection)",id:"iocdiinversion-of-controldependency-injection",level:3},{value:"AOP(Aspect Oriented Programming)",id:"aopaspect-oriented-programming",level:3},{value:"PSA(Portable Service Abstraction)",id:"psaportable-service-abstraction",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:c};function u(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,'\uc2a4\ud504\ub9c1\uc758 \ud575\uc2ec \uac1c\ubc1c\uc790\ub4e4\uc774 \uc4f4 Professional Spring Framework \ub77c\ub294 \ucc45\uc5d0\uc11c\ub294 \uc2a4\ud504\ub9c1\uc758 \uc815\uc218(essence)\ub294 "\uc5d4\ud130\ud504\ub77c\uc774\uc988 \uc11c\ube44\uc2a4 \uae30\ub2a5\uc744 POJO\uc5d0 \uc81c\uacf5\ud558\ub294 \uac83" \uc774\ub77c\uace0 \ud588\ub2e4. '),(0,o.kt)("h3",{id:"pojoplain-old-java-object"},"POJO(Plain Old Java Object)"),(0,o.kt)("p",null,"\uac1d\uc81c\uc9c0\ud5a5\uc801\uc778 \uc6d0\ub9ac\uc5d0 \ucda9\uc2e4\ud558\uba74\uc11c, \ud658\uacbd\uacfc \uae30\uc220\uc5d0 \uc885\uc18d\ub418\uc9c0 \uc54a\uace0 \ud544\uc694\uc5d0 \ub530\ub77c \uc7ac\ud65c\uc6a9\ub420 \uc218 \uc788\ub294 \ubc29\uc2dd\uc73c\ub85c \uc124\uacc4\ub41c \uc624\ube0c\uc81d\ud2b8\n\uc2a4\ud504\ub9c1 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc740 POJO\ub97c \uc774\uc6a9\ud574\uc11c \ub9cc\ub4e0 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ucf54\ub4dc\uc640, POJO\uac00 \uc5b4\ub5bb\uac8c \uad00\uacc4\ub97c \ub9fa\uace0 \ub3d9\uc791\ud558\ub294\uc9c0 \uc815\uc758\ud574\ub193\uc740 \uc124\uacc4 \uc815\ubcf4\ub85c \uad6c\ubd84\ub41c\ub2e4."),(0,o.kt)("h3",{id:"iocdiinversion-of-controldependency-injection"},"IoC/DI(Inversion of Control/Dependency Injection)"),(0,o.kt)("p",null,"\uc81c\uc5b4\uc758 \uc5ed\uc804(IoC)\uc740 \uc2a4\ud504\ub9c1\uc5d0\uc11c\ub9cc \uc801\uc6a9\ub418\ub294 \uac1c\ub150\uc740 \uc544\ub2c8\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uac04\ub2e8\ud558\uac8c \uc124\uba85\ud558\uc790\uba74 \ud504\ub85c\uadf8\ub7a8\uc758 \uc81c\uc5b4 \ud750\ub984 \uad6c\uc870\uac00 \ubc14\ub00c\ub294 \uac83\uc774\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ud504\ub808\uc784\uc6cc\ud06c\ub294 \uc81c\uc5b4\uc758 \uc5ed\uc804\uc774 \uc801\uc6a9\ub41c \ub300\ud45c\uc801\uc778 \uae30\uc220\uc774\ub77c\uace0 \ubcfc \uc218 \uc788\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc758\uc874\uc131 \uc8fc\uc785(DI)\uc740 \ud074\ub798\uc2a4 \uc0ac\uc774\uc758 \uc758\uc874\uad00\uacc4\ub97c \uc124\uc815 \uc815\ubcf4\ub97c \ubc14\ud0d5\uc73c\ub85c \ucee8\ud14c\uc774\ub108\uac00 \uc790\ub3d9\uc801\uc73c\ub85c \uc5f0\uacb0\ud574 \uc8fc\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud504\ub9c1\uc740 IoC/DI\ub97c \ud1b5\ud574 \uc2f1\uae00\ud1a4 \ud615\ud0dc\uc758 \uc624\ube0c\uc81d\ud2b8\uc758 \uc0dd\uc131, \uad00\uacc4 \uc124\uc815, \uacf5\uae09\uc5d0 \ub300\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4. \uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 IoC \ucee8\ud14c\uc774\ub108 \ub610\ub294 DI \ucee8\ud14c\uc774\ub108\ub77c\uace0\ub3c4 \ubd88\ub9b0\ub2e4. "),(0,o.kt)("p",null,"\ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1\uc5d0\uc11c\ub294 DI \ucee8\ud14c\uc774\ub108\ub77c\ub294 \uc6a9\uc5b4\uc5d0 \ub300\ud574 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uba85\ud558\uace0 \uc788\ub2e4. "),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"IoC\uac00 \ub9e4\uc6b0 \ub290\uc2a8\ud558\uac8c \uc815\uc758\ub3fc\uc11c \ud3ed\ub113\uac8c \uc0ac\uc6a9\ub418\ub294 \uc6a9\uc5b4\ub77c\ub294 \uc810\uc774\ub2e4. \ub54c\ubb38\uc5d0 \uc2a4\ud504\ub9c1\uc744 IoC \ucee8\ud14c\uc774\ub108\ub77c\uace0\ub9cc \ud574\uc11c\ub294 \uc2a4\ud504\ub9c1\uc774 \uc81c\uacf5\ud558\ub294 \uae30\ub2a5\uc758 \ud2b9\uc9d5\uc744 \uba85\ud655\ud558\uac8c \uc124\uba85\ud558\uc9c0 \ubabb\ud55c\ub2e4. \u2026 \uc0c8\ub85c\uc6b4 \uc6a9\uc5b4\ub97c \ub9cc\ub4dc\ub294 \ub370 \ud0c1\uc6d4\ud55c \uc7ac\ub2a5\uc774 \uc788\ub294 \uba87\uba87 \uc0ac\ub78c\uc758 \uc81c\uc548\uc73c\ub85c \uc2a4\ud504\ub9c1\uc774 \uc81c\uacf5\ud558\ub294 IoC \ubc29\uc2dd\uc758 \ud575\uc2ec\uc744 \uc9da\uc5b4\uc8fc\ub294 \uc758\uc874\uad00\uacc4 \uc8fc\uc785(DI)\uc774\ub77c\ub294, \uc880 \ub354 \uc758\ub3c4\uac00 \uba85\ud655\ud788 \ub4dc\ub7ec\ub098\ub294 \uc774\ub984\uc744 \uc0ac\uc6a9\ud558\uae30 \uc2dc\uc791\ud588\ub2e4. \uc2a4\ud504\ub9c1 IoC \uae30\ub2a5\uc758 \ub300\ud45c\uc801\uc778 \ub3d9\uc791\uc6d0\ub9ac\ub294 \uc8fc\ub85c \uc758\uc874\uad00\uacc4 \uc8fc\uc785\uc774\ub77c\uace0 \ubd88\ub9b0\ub2e4. \u2026 \uadf8\ub798\uc11c \ucd08\uae30\uc5d0\ub294 \uc8fc\ub85c IoC \ucee8\ud14c\uc774\ub108\ub77c\uace0 \ubd88\ub9ac\ub358 \uc2a4\ud504\ub9c1\uc774 \uc9c0\uae08\uc740 \uc758\uc874\uad00\uacc4 \uc8fc\uc785 \ucee8\ud14c\uc774\ub108 \ub610\ub294 DI \ucee8\ud14c\uc774\ub108\ub77c\uace0 \ub9ce\uc774 \ubd88\ub9b0\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1 p.111")),(0,o.kt)("h3",{id:"aopaspect-oriented-programming"},"AOP(Aspect Oriented Programming)"),(0,o.kt)("p",null,"\uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \ud575\uc2ec\uc801\uc778 \uae30\ub2a5\uc5d0\uc11c \ubd80\uac00\uc801\uc778 \uae30\ub2a5\uc744 \ubd84\ub9ac\ud574\uc11c \ubaa8\ub4c8\ud654\ud558\ub294 \uac83",(0,o.kt)("br",{parentName:"p"}),"\n","\uc608) \ud575\uc2ec \uae30\ub2a5 = \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1, \ubd80\uac00 \uae30\ub2a5 = \ub85c\uae45, \ud2b8\ub79c\uc7ad\uc158",(0,o.kt)("br",{parentName:"p"}),"\n","\uad00\uc810 \uc9c0\ud5a5 \ud504\ub85c\uadf8\ub798\ubc0d\uc774\ub77c\uace0 \ud558\ub294\ub370 \uc774\ub294 OOP\uc640 \uac19\uc774 \ub3c5\ub9bd\uc801\uc778 \ud504\ub85c\uadf8\ub798\ubc0d \ud328\ub7ec\ub2e4\uc784\uc774 \uc544\ub2cc \ubcf4\uc870\uc801\uc778 \uae30\uc220\uc774\ub2e4."),(0,o.kt)("h3",{id:"psaportable-service-abstraction"},"PSA(Portable Service Abstraction)"),(0,o.kt)("p",null,"\ud658\uacbd\uacfc \uc138\ubd80 \uae30\uc220\uc758 \ubcc0\ud654\uc5d0 \uad00\uacc4\uc5c6\uc774 \uc77c\uad00\ub41c \ubc29\uc2dd\uc73c\ub85c \uae30\uc220\uc5d0 \uc811\uadfc\ud560 \uc218 \uc788\uac8c \ud574\uc8fc\ub294 \uae30\uc220\uc774\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","POJO\ub85c \uac1c\ubc1c\ub41c \ucf54\ub4dc\ub294 \ud2b9\uc815 \ud658\uacbd\uc774\ub098 \uad6c\ud604 \ubc29\uc2dd\uc5d0 \uc885\uc18d\uc801\uc774\uc9c0 \uc54a\uc544\uc57c \ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud504\ub9c1\uc740 POJO \ucf54\ub4dc\uac00 \ud2b9\uc815 \uae30\uc220\uc5d0 \uc885\uc18d\ub418\uc9c0 \uc54a\uac8c \uc77c\uad00\uc131 \uc788\ub294 \uc11c\ube44\uc2a4 \ucd94\uc0c1\ud654 \uae30\uc220\uc744 \uc81c\uacf5\ud55c\ub2e4. "),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/reference/"},"Spring Core, Spring.io"),(0,o.kt)("br",{parentName:"p"}),"\n","\ud1a0\ube44\uc758 \uc2a4\ud504\ub9c1 3.1, \uc774\uc77c\ubbfc"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dab4c683.14fde9f3.js b/assets/js/dab4c683.29c4f1c4.js similarity index 77% rename from assets/js/dab4c683.14fde9f3.js rename to assets/js/dab4c683.29c4f1c4.js index 20d31fdd4..6a45bf2db 100644 --- a/assets/js/dab4c683.14fde9f3.js +++ b/assets/js/dab4c683.29c4f1c4.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6058],{67315:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6058],{67315:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/daff1d93.268aa82a.js b/assets/js/daff1d93.268aa82a.js new file mode 100644 index 000000000..ed20363de --- /dev/null +++ b/assets/js/daff1d93.268aa82a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1659],{99239:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>l,metadata:()=>i,toc:()=>a});var t=r(85893),s=r(3905);const l={title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",slug:"book-leadership-and-self-deception",tags:["Book"]},o=void 0,i={permalink:"/book-leadership-and-self-deception",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",source:"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",description:"\ucc45 \uc815\ubcf4",date:"2023-04-08T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 8\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:5.16,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",slug:"book-leadership-and-self-deception",tags:["Book"]},unlisted:!1,prevItem:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",permalink:"/tecochat-retrospective-1"},nextItem:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/innodb-lock"}},c={authorsImageUrls:[]},a=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18",id:"\uc790\uae30\uae30\ub9cc\uacfc-\uc790\uae30\ubc30\ubc18",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}];function b(e){const n={blockquote:"blockquote",br:"br",h3:"h3",li:"li",p:"p",ul:"ul",...(0,s.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\ucc45-\uc815\ubcf4",children:"\ucc45 \uc815\ubcf4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",(0,t.jsx)(n.br,{}),"\n","\uc544\ube48\uc800\uc5f0\uad6c\uc18c"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc790\uae30\uae30\ub9cc\uacfc-\uc790\uae30\ubc30\ubc18",children:"\uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18"}),"\n",(0,t.jsx)(n.p,{children:"\ucc45\uc5d0\uc11c\ub294 \uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc744 \ub2e4\ub8ec\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc790\uae30\uae30\ub9cc: \uc790\uc2e0\uc758 \ubb38\uc81c\ub97c \uc778\uc815\ud558\uc9c0 \uc54a\ub294 \uac83"}),"\n",(0,t.jsx)(n.li,{children:"\uc790\uae30\ubc30\ubc18: \ub2e4\ub978 \uc0ac\ub78c\uc744 \uc704\ud574 \ubb34\uc5b8\uac00 \ud574\uc57c\ub9cc \ud55c\ub2e4\ub294 \uc0dd\uac01\uc744 \ubc18\ud558\ub294 \ud589\uc704"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\uc790\uae30\ubc30\ubc18\uc744 \ud55c\ub2e4\uba74 \uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uac00 \ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uc5d0 \ube60\uc9c0\ub294 \uac83\uc744 \ucc45\uc5d0\uc11c\ub294 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac04\ub2e4\uace0 \ud45c\ud604\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uc77d\uace0-\ub098\uc11c",children:"\uc77d\uace0 \ub098\uc11c"}),"\n",(0,t.jsxs)(n.p,{children:["\ucd5c\uadfc\uc5d0 \uc77d\uc740 \ucc45 \uc911 \uac00\uc7a5 \ub9c8\uc74c\uc774 \ubd88\ud3b8\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\ub807\uae30\uc5d0 \ub354\ub354\uc6b1 \ub098\uc5d0\uac8c \ud544\uc694\ud55c \ub0b4\uc6a9\uc774 \ub2f4\uaca8\uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\uc0b4\uba74\uc11c \ub9ce\uc740 \uc120\ud0dd\uc758 \uc21c\uac04\uc774 \uc874\uc7ac\ud588\uace0, \uadf8 \uc21c\uac04\ub9c8\ub2e4 \uc790\uae30\ubc30\ubc18\uc744 \ud0dd\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc791\uac8c\ub294 \uc9d1\uc548\uc77c\uc744 \ud574\uc57c \ud558\ub294\ub370 \ubab8\uc774 \uc870\uae08 \ud798\ub4e4\ub2e4\uace0 \ud558\uc9c0 \uc54a\uac70\ub098",(0,t.jsx)(n.br,{}),"\n","\ud06c\uac8c\ub294 \uc798\ubabb\uc744 \uc778\uc815\ud574\uc57c \ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uadf8\ub7ec\uc9c0 \uc54a\uc740 \uacbd\uc6b0\uac00 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ub7f0 \uc0c1\ud669\uc774 \ubc18\ubcf5\ub418\uc5b4 \uacb0\uad6d \uc0c1\uc790 \uc548\uc5d0 \ub098 \uc790\uc2e0\uc744 \uac00\ub450\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\ub354 \ub098\uc740 \uc0b6\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \uc9c0\uc18d\uc801\uc73c\ub85c \ud655\uc778\ud558\uace0, \uc0c1\uc790 \ubc16\uc73c\ub85c \ub098\uac00\ub824\ub294 \uc5f0\uc2b5\uc744 \ud574\uc57c\uaca0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub113\uc740 \uc2dc\uc120\uc744 \uac00\uc9c0\uace0, \ud56d\uc0c1 \ub0b4\uac00 \ud2c0\ub9b4 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc0dd\uac01\ud558\uace0 \uc0b4\uc544\uac00\uc790."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",children:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc6b0\ub9ac\uc758 \uc0dd\uac01\uc740 \uc9c0\uc2dd\ubcf4\ub2e4 \uc791\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uc758 \uc9c0\uc2dd\uc740 \uc0ac\ub791\ubcf4\ub2e4 \uc791\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uc758 \uc0ac\ub791\uc740 \uc874\uc7ac\ubcf4\ub2e4 \uc791\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\ub9ac\uace0 \uc6b0\ub9ac\uac00 \uc0dd\uac01\ud558\ub294 \ub098\ub294 \uc2e4\uc81c\uc758 \ub098\ubcf4\ub2e4 \uadf8\ub9cc\ud07c \uc791\ub2e4.",(0,t.jsx)(n.br,{}),"\n","R. D. \ub7ad",(0,t.jsx)(n.br,{}),"\n","p.19"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc6b0\ub9ac\uac00 \uc678\uc801\uc73c\ub85c \uc5b4\ub5a4 \ud589\ub3d9\uc744 \ud558\ub4e0\uc9c0 \uac04\uc5d0, \uc0ac\ub78c\ub4e4\uc740 \uc6b0\ub9ac \ub9c8\uc74c\uc5d0\uc11c \uadf8\ub4e4\uc744 \uc5b4\ub5bb\uac8c \ub300\ud558\uace0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \uc8fc\ub85c \ubc18\uc751\ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uac00 \uc0ac\ub78c\ub4e4\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \ub290\ub07c\uac8c \ub418\ub294\uc9c0\ub294 \uc6b0\ub9ac\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \ud639\uc740 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \ub2ec\ub77c\uc9c0\uac8c \ub429\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.66"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\ube44\ub09c\uc740 \uac10\uc815\uc5d0 \uc18d\ud558\uace0 \ub099\uad00\uc740 \uc758\uc9c0\uc5d0 \uc18d\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc778\uac04\uc740 \uac10\uc815\ubcf4\ub2e4 \ub354 \ud070 \uc874\uc7ac\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc54c\ub7ad, \ud0c1\ub2db\ud55c",(0,t.jsx)(n.br,{}),"\n","p.103"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc6b0\ub9ac\uac00 \uc790\uc2e0\uc5d0\uac8c\ub9cc \uc9d1\uc911\ud558\uace0 \uc788\ub294 \ud55c, \ud63c\uc790\uc11c \uc77c\ud558\ub294 \uac83 \uc774\uc0c1\uc758 \ucc3d\uc870\uc801\uc778 \uacb0\uacfc\ub098 \ud611\ub825\uc744 \uc774\ub04c\uc5b4 \ub0b8\ub2e4\ub294 \uac83\uc740 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc624\ub298\ub0a0 \uacbd\uc81c \ud658\uacbd\uc5d0\uc11c\ub294 \ud63c\uc790\uc11c\ub294 \uc77c\uc758 \uacb0\uacfc\ub97c \ud0c1\uc6d4\ud558\uac8c \ub9cc\ub4e4\uc5b4 \ub0b4\uae30\uac00 \uc5b4\ub835\uc2b5\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub0b4\uac00 \uc911\uc2ec\uc774\uc5b4\uc57c \ub41c\ub2e4\ub294 \ud3d0\uc1c4\uc801\uc778 \uc0ac\uace0\ub294 \ud568\uaed8 \uc77c\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uc5f4\uc815\uc744 \ubd88\ub7ec\uc624\uc9c0 \ubabb\ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.175"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc194\uc9c1\ud568\uc740 \uc6b0\ub9ac\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\ub294 \uc5f4\uc1e0\uc785\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\uac83\uc740 \uc790\uc2e0\uc758 \ud589\ub3d9\uacfc \uad00\ub828\ub41c \uc0ac\ub78c\uc5d0 \ub300\ud574 \uae30\uaebc\uc774 \uc0ac\uacfc\ub97c \ud558\ub294 \uac83\uc785\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\uac83\ub9cc\uc774 \uc2e4\ud0c0\ub798\ucc98\ub7fc \uc5c9\ud0a8 \uad00\uacc4\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc774\uc8e0.",(0,t.jsx)(n.br,{}),"\n","p.188"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\ub204\uad70\uac00\ub97c \ub098\uc640 \uac19\uc774 \ub3d9\uc77c\ud55c \uac00\uce58\ub97c \uc9c0\ub2cc \ud55c \uc778\uac04\uc73c\ub85c \uc0dd\uac01\ud574\uc11c \uadf8 \uc0ac\ub78c\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \ubc16\uc5d0 \uacc4\uc18d \uba38\ubb34\ub974\uace0 \uc2f6\uc740 \uc5f4\ub9dd\uc774 \uc0dd\uae38 \ub54c, \ub098\ub294 \uc774\ubbf8 \uadf8 \uc0ac\ub78c\uc5d0 \ub300\ud574 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.214"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\ub300\ubd80\ubd84\uc758 \uc0ac\ub78c\ub4e4\uc774 \uad00\uacc4 \uae30\uc220\uc744 \uac00\uc9c0\uace0 \uadf8\ub4e4\uc774 \uacaa\uace0 \uc788\ub294 \ubb38\uc81c\ub97c \ubc14\ub85c\uc7a1\uc73c\ub824\uace0 \ud558\ub294 \ub178\ub825\uc774 \uacb0\uc2e4\uc744 \uc5bb\uc9c0 \ubabb\ud558\ub294 \uac83\uc740 \uacb0\ucf54 \uadf8\ub7ec\ud55c \uae30\uc220 \ubd80\uc871 \ub54c\ubb38\uc5d0 \uc0dd\uae30\ub294 \uac83\uc774 \uc544\ub2d9\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\uac83\ub4e4\uc740 \uc790\uae30\ubc30\ubc18 \ub54c\ubb38\uc5d0 \uc0dd\uaca8\ub0a9\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.224"]}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uc6b0\ub9ac\ub294 \ud568\uaed8 \uc77c\ud558\uace0 \uc6b0\ub9ac\uc640 \ud568\uaed8 \uc0b4\uc544\uac00\ub294 \uc0ac\ub78c\uc774 \uc9c4\uc815\uc73c\ub85c \ub204\uad6c\uc778\uc9c0 \uc54c\uc9c0 \ubabb\ud569\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uac00 \uadf8\ub4e4\uacfc \uc9c4\uc815\uc73c\ub85c \ud568\uaed8 \uc18c\ud1b5\ud558\uae30 \uc804\uae4c\uc9c0\ub294 \uc6b0\ub9ac\ub294 \uadf8\ub4e4\uc758 \uac00\uce58\ub97c \uc798 \ubaa8\ub985\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\ub9ac\uc758 \uc704\ub300\ud568\uc774\ub780 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc758 \uc704\ub300\ud55c \uc810\uc744 \ubc1c\uacac\ud574 \uc8fc\ub294 \uac83\uc5d0 \uc788\uc2b5\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","p.280"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,s.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(b,{...e})}):b(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function s(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function l(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?l(Object(r),!0).forEach((function(n){s(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function i(e,n){if(null==e)return{};var r,t,s=function(e,n){if(null==e)return{};var r,t,s={},l=Object.keys(e);for(t=0;t<l.length;t++)r=l[t],n.indexOf(r)>=0||(s[r]=e[r]);return s}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(t=0;t<l.length;t++)r=l[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(s[r]=e[r])}return s}var c=t.createContext({}),a=function(e){var n=t.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},b={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,s=e.mdxType,l=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),j=a(r),d=s,x=j["".concat(c,".").concat(d)]||j[d]||b[d]||l;return r?t.createElement(x,o(o({ref:n},p),{},{components:r})):t.createElement(x,o({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/daff1d93.928fbfe7.js b/assets/js/daff1d93.928fbfe7.js deleted file mode 100644 index 5ad5d8c2f..000000000 --- a/assets/js/daff1d93.928fbfe7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1659],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function p(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?p(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):p(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},p=Object.keys(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)r=p[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var k=n.createContext({}),u=function(e){var t=n.useContext(k),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},c=function(e){var t=u(e.components);return n.createElement(k.Provider,{value:t},e.children)},i={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,p=e.originalType,k=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),b=u(r),m=a,s=b["".concat(k,".").concat(m)]||b[m]||i[m]||p;return r?n.createElement(s,o(o({ref:t},c),{},{components:r})):n.createElement(s,o({ref:t},c))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=r.length,o=new Array(p);o[0]=b;var l={};for(var k in t)hasOwnProperty.call(t,k)&&(l[k]=t[k]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var u=2;u<p;u++)o[u]=r[u];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}b.displayName="MDXCreateElement"},26016:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>k,contentTitle:()=>o,default:()=>i,frontMatter:()=>p,metadata:()=>l,toc:()=>u});var n=r(87462),a=(r(67294),r(3905));const p={title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",slug:"book-leadership-and-self-deception",tags:["Book"]},o=void 0,l={permalink:"/book-leadership-and-self-deception",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",source:"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",description:"\ucc45 \uc815\ubcf4",date:"2023-04-08T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 8\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:5.16,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",slug:"book-leadership-and-self-deception",tags:["Book"]},prevItem:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",permalink:"/tecochat-retrospective-1"},nextItem:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/innodb-lock"}},k={authorsImageUrls:[]},u=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18",id:"\uc790\uae30\uae30\ub9cc\uacfc-\uc790\uae30\ubc30\ubc18",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}],c={toc:u};function i(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ucc45-\uc815\ubcf4"},"\ucc45 \uc815\ubcf4"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\ube48\uc800\uc5f0\uad6c\uc18c")),(0,a.kt)("h3",{id:"\uc790\uae30\uae30\ub9cc\uacfc-\uc790\uae30\ubc30\ubc18"},"\uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18"),(0,a.kt)("p",null,"\ucc45\uc5d0\uc11c\ub294 \uc790\uae30\uae30\ub9cc\uacfc \uc790\uae30\ubc30\ubc18\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc744 \ub2e4\ub8ec\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"\uc790\uae30\uae30\ub9cc: \uc790\uc2e0\uc758 \ubb38\uc81c\ub97c \uc778\uc815\ud558\uc9c0 \uc54a\ub294 \uac83 "),(0,a.kt)("li",{parentName:"ul"},"\uc790\uae30\ubc30\ubc18: \ub2e4\ub978 \uc0ac\ub78c\uc744 \uc704\ud574 \ubb34\uc5b8\uac00 \ud574\uc57c\ub9cc \ud55c\ub2e4\ub294 \uc0dd\uac01\uc744 \ubc18\ud558\ub294 \ud589\uc704")),(0,a.kt)("p",null,"\uc790\uae30\ubc30\ubc18\uc744 \ud55c\ub2e4\uba74 \uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uac00 \ub41c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc790\uae30\uae30\ub9cc \uc0c1\ud0dc\uc5d0 \ube60\uc9c0\ub294 \uac83\uc744 \ucc45\uc5d0\uc11c\ub294 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac04\ub2e4\uace0 \ud45c\ud604\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\uc77d\uace0-\ub098\uc11c"},"\uc77d\uace0 \ub098\uc11c"),(0,a.kt)("p",null,"\ucd5c\uadfc\uc5d0 \uc77d\uc740 \ucc45 \uc911 \uac00\uc7a5 \ub9c8\uc74c\uc774 \ubd88\ud3b8\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub807\uae30\uc5d0 \ub354\ub354\uc6b1 \ub098\uc5d0\uac8c \ud544\uc694\ud55c \ub0b4\uc6a9\uc774 \ub2f4\uaca8\uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc0b4\uba74\uc11c \ub9ce\uc740 \uc120\ud0dd\uc758 \uc21c\uac04\uc774 \uc874\uc7ac\ud588\uace0, \uadf8 \uc21c\uac04\ub9c8\ub2e4 \uc790\uae30\ubc30\ubc18\uc744 \ud0dd\ud558\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc791\uac8c\ub294 \uc9d1\uc548\uc77c\uc744 \ud574\uc57c \ud558\ub294\ub370 \ubab8\uc774 \uc870\uae08 \ud798\ub4e4\ub2e4\uace0 \ud558\uc9c0 \uc54a\uac70\ub098",(0,a.kt)("br",{parentName:"p"}),"\n","\ud06c\uac8c\ub294 \uc798\ubabb\uc744 \uc778\uc815\ud574\uc57c \ud558\ub294 \uc0c1\ud669\uc5d0\uc11c \uadf8\ub7ec\uc9c0 \uc54a\uc740 \uacbd\uc6b0\uac00 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ub7f0 \uc0c1\ud669\uc774 \ubc18\ubcf5\ub418\uc5b4 \uacb0\uad6d \uc0c1\uc790 \uc548\uc5d0 \ub098 \uc790\uc2e0\uc744 \uac00\ub450\ub294 \uacbd\uc6b0\uac00 \ub9ce\uc558\ub2e4. "),(0,a.kt)("p",null,"\ub354 \ub098\uc740 \uc0b6\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \uc9c0\uc18d\uc801\uc73c\ub85c \ud655\uc778\ud558\uace0, \uc0c1\uc790 \ubc16\uc73c\ub85c \ub098\uac00\ub824\ub294 \uc5f0\uc2b5\uc744 \ud574\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub113\uc740 \uc2dc\uc120\uc744 \uac00\uc9c0\uace0, \ud56d\uc0c1 \ub0b4\uac00 \ud2c0\ub9b4 \uc218 \uc788\ub2e4\ub294 \uac83\uc744 \uc0dd\uac01\ud558\uace0 \uc0b4\uc544\uac00\uc790. "),(0,a.kt)("h3",{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4"},"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc6b0\ub9ac\uc758 \uc0dd\uac01\uc740 \uc9c0\uc2dd\ubcf4\ub2e4 \uc791\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uc758 \uc9c0\uc2dd\uc740 \uc0ac\ub791\ubcf4\ub2e4 \uc791\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uc758 \uc0ac\ub791\uc740 \uc874\uc7ac\ubcf4\ub2e4 \uc791\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub9ac\uace0 \uc6b0\ub9ac\uac00 \uc0dd\uac01\ud558\ub294 \ub098\ub294 \uc2e4\uc81c\uc758 \ub098\ubcf4\ub2e4 \uadf8\ub9cc\ud07c \uc791\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","R. D. \ub7ad",(0,a.kt)("br",{parentName:"p"}),"\n","p.19")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc6b0\ub9ac\uac00 \uc678\uc801\uc73c\ub85c \uc5b4\ub5a4 \ud589\ub3d9\uc744 \ud558\ub4e0\uc9c0 \uac04\uc5d0, \uc0ac\ub78c\ub4e4\uc740 \uc6b0\ub9ac \ub9c8\uc74c\uc5d0\uc11c \uadf8\ub4e4\uc744 \uc5b4\ub5bb\uac8c \ub300\ud558\uace0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \uc8fc\ub85c \ubc18\uc751\ud569\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uac00 \uc0ac\ub78c\ub4e4\uc5d0 \ub300\ud574 \uc5b4\ub5bb\uac8c \ub290\ub07c\uac8c \ub418\ub294\uc9c0\ub294 \uc6b0\ub9ac\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub294\uc9c0 \ud639\uc740 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294\uc9c0\uc5d0 \ub530\ub77c \ub2ec\ub77c\uc9c0\uac8c \ub429\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.66")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\ube44\ub09c\uc740 \uac10\uc815\uc5d0 \uc18d\ud558\uace0 \ub099\uad00\uc740 \uc758\uc9c0\uc5d0 \uc18d\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc778\uac04\uc740 \uac10\uc815\ubcf4\ub2e4 \ub354 \ud070 \uc874\uc7ac\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc54c\ub7ad, \ud0c1\ub2db\ud55c",(0,a.kt)("br",{parentName:"p"}),"\n","p.103")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc6b0\ub9ac\uac00 \uc790\uc2e0\uc5d0\uac8c\ub9cc \uc9d1\uc911\ud558\uace0 \uc788\ub294 \ud55c, \ud63c\uc790\uc11c \uc77c\ud558\ub294 \uac83 \uc774\uc0c1\uc758 \ucc3d\uc870\uc801\uc778 \uacb0\uacfc\ub098 \ud611\ub825\uc744 \uc774\ub04c\uc5b4 \ub0b8\ub2e4\ub294 \uac83\uc740 \ubd88\uac00\ub2a5\ud569\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc624\ub298\ub0a0 \uacbd\uc81c \ud658\uacbd\uc5d0\uc11c\ub294 \ud63c\uc790\uc11c\ub294 \uc77c\uc758 \uacb0\uacfc\ub97c \ud0c1\uc6d4\ud558\uac8c \ub9cc\ub4e4\uc5b4 \ub0b4\uae30\uac00 \uc5b4\ub835\uc2b5\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub0b4\uac00 \uc911\uc2ec\uc774\uc5b4\uc57c \ub41c\ub2e4\ub294 \ud3d0\uc1c4\uc801\uc778 \uc0ac\uace0\ub294 \ud568\uaed8 \uc77c\ud558\ub294 \uc0ac\ub78c\ub4e4\uc758 \uc5f4\uc815\uc744 \ubd88\ub7ec\uc624\uc9c0 \ubabb\ud569\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.175")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc194\uc9c1\ud568\uc740 \uc6b0\ub9ac\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud558\ub294 \uc5f4\uc1e0\uc785\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\uac83\uc740 \uc790\uc2e0\uc758 \ud589\ub3d9\uacfc \uad00\ub828\ub41c \uc0ac\ub78c\uc5d0 \ub300\ud574 \uae30\uaebc\uc774 \uc0ac\uacfc\ub97c \ud558\ub294 \uac83\uc785\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\uac83\ub9cc\uc774 \uc2e4\ud0c0\ub798\ucc98\ub7fc \uc5c9\ud0a8 \uad00\uacc4\uc758 \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc774\uc8e0.",(0,a.kt)("br",{parentName:"p"}),"\n","p.188")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\ub204\uad70\uac00\ub97c \ub098\uc640 \uac19\uc774 \ub3d9\uc77c\ud55c \uac00\uce58\ub97c \uc9c0\ub2cc \ud55c \uc778\uac04\uc73c\ub85c \uc0dd\uac01\ud574\uc11c \uadf8 \uc0ac\ub78c\uc744 \uc704\ud574 \ub0b4\uac00 \uc0c1\uc790 \ubc16\uc5d0 \uacc4\uc18d \uba38\ubb34\ub974\uace0 \uc2f6\uc740 \uc5f4\ub9dd\uc774 \uc0dd\uae38 \ub54c, \ub098\ub294 \uc774\ubbf8 \uadf8 \uc0ac\ub78c\uc5d0 \ub300\ud574 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.214")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\ub300\ubd80\ubd84\uc758 \uc0ac\ub78c\ub4e4\uc774 \uad00\uacc4 \uae30\uc220\uc744 \uac00\uc9c0\uace0 \uadf8\ub4e4\uc774 \uacaa\uace0 \uc788\ub294 \ubb38\uc81c\ub97c \ubc14\ub85c\uc7a1\uc73c\ub824\uace0 \ud558\ub294 \ub178\ub825\uc774 \uacb0\uc2e4\uc744 \uc5bb\uc9c0 \ubabb\ud558\ub294 \uac83\uc740 \uacb0\ucf54 \uadf8\ub7ec\ud55c \uae30\uc220 \ubd80\uc871 \ub54c\ubb38\uc5d0 \uc0dd\uae30\ub294 \uac83\uc774 \uc544\ub2d9\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\uac83\ub4e4\uc740 \uc790\uae30\ubc30\ubc18 \ub54c\ubb38\uc5d0 \uc0dd\uaca8\ub0a9\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.224")),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\uc6b0\ub9ac\ub294 \ud568\uaed8 \uc77c\ud558\uace0 \uc6b0\ub9ac\uc640 \ud568\uaed8 \uc0b4\uc544\uac00\ub294 \uc0ac\ub78c\uc774 \uc9c4\uc815\uc73c\ub85c \ub204\uad6c\uc778\uc9c0 \uc54c\uc9c0 \ubabb\ud569\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uac00 \uadf8\ub4e4\uacfc \uc9c4\uc815\uc73c\ub85c \ud568\uaed8 \uc18c\ud1b5\ud558\uae30 \uc804\uae4c\uc9c0\ub294 \uc6b0\ub9ac\ub294 \uadf8\ub4e4\uc758 \uac00\uce58\ub97c \uc798 \ubaa8\ub985\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ub9ac\uc758 \uc704\ub300\ud568\uc774\ub780 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc758 \uc704\ub300\ud55c \uc810\uc744 \ubc1c\uacac\ud574 \uc8fc\ub294 \uac83\uc5d0 \uc788\uc2b5\ub2c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","p.280")))}i.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/db86613e.2743f870.js b/assets/js/db86613e.2743f870.js deleted file mode 100644 index ed543d25c..000000000 --- a/assets/js/db86613e.2743f870.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9458],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>u});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function c(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var p=a.createContext({}),i=function(e){var t=a.useContext(p),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},m=function(e){var t=i(e.components);return a.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},k=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,p=e.parentName,m=c(e,["components","mdxType","originalType","parentName"]),k=i(n),u=r,y=k["".concat(p,".").concat(u)]||k[u]||s[u]||l;return n?a.createElement(y,o(o({ref:t},m),{},{components:n})):a.createElement(y,o({ref:t},m))}));function u(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,o=new Array(l);o[0]=k;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c.mdxType="string"==typeof e?e:r,o[1]=c;for(var i=2;i<l;i++)o[i]=n[i];return a.createElement.apply(null,o)}return a.createElement.apply(null,n)}k.displayName="MDXCreateElement"},58967:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>s,frontMatter:()=>l,metadata:()=>c,toc:()=>i});var a=n(87462),r=(n(67294),n(3905));const l={title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"mysql-lock",tags:["DataBase","Lock","MySQL"]},o=void 0,c={permalink:"/mysql-lock",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",source:"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",description:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",date:"2023-04-06T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 6\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Lock",permalink:"/tags/lock"},{label:"MySQL",permalink:"/tags/my-sql"}],readingTime:4.405,hasTruncateMarker:!1,authors:[],frontMatter:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"mysql-lock",tags:["DataBase","Lock","MySQL"]},prevItem:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/innodb-lock"},nextItem:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",permalink:"/transaction-and-isolation"}},p={authorsImageUrls:[]},i=[{value:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",id:"mysql-\uc5d4\uc9c4\uc758-\uc7a0\uae08",level:2},{value:"\uae00\ub85c\ubc8c \ub77d(Global lock)",id:"\uae00\ub85c\ubc8c-\ub77dglobal-lock",level:3},{value:"\ud14c\uc774\ube14 \ub77d(Table lock)",id:"\ud14c\uc774\ube14-\ub77dtable-lock",level:3},{value:"\ub124\uc784\ub4dc \ub77d(Named lock)",id:"\ub124\uc784\ub4dc-\ub77dnamed-lock",level:3},{value:"\uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)",id:"\uba54\ud0c0\ub370\uc774\ud130-\ub77dmetadata-lock",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],m={toc:i};function s(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"mysql-\uc5d4\uc9c4\uc758-\uc7a0\uae08"},"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08"),(0,r.kt)("p",null,"MySQL\uc5d0\uc11c\uc758 \ub77d\uc740 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub808\ubca8\uacfc, MySQL \uc5d4\uc9c4 \ub808\ubca8\ub85c \ub098\ub20c \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MySQL \uc5d4\uc9c4 \ub808\ubca8\uc758 \uc7a0\uae08\uc740 \ubaa8\ub4e0 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce5c\ub2e4. "),(0,r.kt)("h3",{id:"\uae00\ub85c\ubc8c-\ub77dglobal-lock"},"\uae00\ub85c\ubc8c \ub77d(Global lock)"),(0,r.kt)("p",null,"MySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08 \uc911 \uac00\uc7a5 \ub113\uc740 \ubc94\uc704\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \uc7a0\uae08\uc774\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc601\ud5a5\uc744 \ubbf8\uce58\ub294 \ubc94\uc704\ub294 \ud574\ub2f9 \uc11c\ubc84 \uc804\uccb4\uc774\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc791\uc5c5 \ub300\uc0c1 \ud14c\uc774\ube14, \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0c1\uad00 \uc5c6\uc774 \ub3d9\uc77c\ud558\uac8c \uc601\ud5a5\uc744 \ubc1b\ub294\ub2e4.")),(0,r.kt)("p",null,"\ud55c \uc138\uc158\uc5d0\uc11c \uae00\ub85c\ubc8c \ub77d\uc744 \ud68d\ub4dd\ud558\uba74 \ud574\uc81c \ub420 \ub54c \uae4c\uc9c0 \uc870\ud68c\ub97c \uc81c\uc678\ud55c \ub300\ubd80\ubd84\uc758 \uba85\ub839\uc774 \ub300\uae30 \uc0c1\ud0dc\uac00 \ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc874\uc7ac\ud558\ub294 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub300\ud574 \uc77c\uad00\ub41c \ubc31\uc5c5\uc744 \ubc1b\uc544\uc57c\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c\ub294 \ubc31\uc5c5 \uc2dc \uc870\uae08 \ub354 \uac00\ubcbc\uc6b4 \ubc31\uc5c5 \ub77d\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- GLOBAL LOCK\nFLUSH TABLES WITH READ LOCK;\n-- UNLOCK\nUNLOCK TABLES;\n\n-- BACKUP LOCK\nLOCK INSTANCE FOR BACKUP;\n-- UNLOCK\nUNLOCK INSTANCE;\n")),(0,r.kt)("admonition",{title:"MyISAM",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"MySQL 5.5 \ubc84\uc804 \uc774\uc804\uc758 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uace0, SELECT \uc791\uc5c5 \uc18d\ub3c4\uac00 \ube60\ub974\ub2e4.")),(0,r.kt)("h3",{id:"\ud14c\uc774\ube14-\ub77dtable-lock"},"\ud14c\uc774\ube14 \ub77d(Table lock)"),(0,r.kt)("p",null,"\uac1c\ubcc4 \ud14c\uc774\ube14 \ub2e8\uc704\ub85c \uc124\uc815\ub418\ub294 \uc7a0\uae08\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uba85\uc2dc\uc801 \ub610\ub294 \ubb35\uc2dc\uc801\uc73c\ub85c \ud2b9\uc815 \ud14c\uc774\ube14\uc758 \ub77d\uc744 \ud68d\ub4dd\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubb35\uc2dc\uc801 \ub77d\uc740 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub294 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uba74 \ubc1c\uc0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","InnoDB \ud14c\uc774\ube14\uc5d0\ub294 DML \ucffc\ub9ac\ub294 \ubb34\uc2dc\ub418\uace0 DDL \uc77c \uacbd\uc6b0\uc5d0\ub9cc \ubb35\uc2dc\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- TABLE LOCK\nLOCK TABLES table_name [ READ | WRITE ]\n\n-- UNLOCK\nUNLOCK TABLES;\n")),(0,r.kt)("h3",{id:"\ub124\uc784\ub4dc-\ub77dnamed-lock"},"\ub124\uc784\ub4dc \ub77d(Named lock)"),(0,r.kt)("p",null,"\uc784\uc758\uc758 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \uc124\uc815\ud560 \uc218 \uc788\ub294 \uc7a0\uae08\uc73c\ub85c \uc720\uc800 \ub808\ubca8 \ub77d\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc5ec\ub7ec \uc2a4\ub808\ub4dc\ub098 \ud504\ub85c\uc138\uc2a4\uac00 \ub3d9\uc77c\ud55c \ub370\uc774\ud130\ub97c \uc218\uc815\ud558\ub824\ub294 \uacbd\uc6b0, \ub3d9\uc2dc\uc5d0 \uc218\uc815\ud558\uc9c0 \ubabb\ud558\ub3c4\ub85d \ubcf4\ud638\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- aGVyYg== \ub77c\ub294 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08 \ud68d\ub4dd, \uc774\ubbf8 \uc7a0\uae08\uc744 \uc0ac\uc6a9\uc911\uc778 \uacbd\uc6b0 1\ucd08 \ub3d9\uc548\ub9cc \ub300\uae30\nSELECT GET_LOCK('aGVyYg==', 1);\n\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc774 \uc124\uc815\ub418\uc5b4 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.\nSELECT IS_FREE_LOCK('aGVyYg==');\n\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4.\nSELECT RELEASE_LOCK('aGVyYg==');\n\n-- \uc704 3\uac1c \ud568\uc218 \ubaa8\ub450 \uc815\uc0c1\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud558\uac70\ub098 \ud574\uc81c\ud55c \uacbd\uc6b0\uc5d0 1\uc744, \uc544\ub2c8\uba74 0\uc744 \ubc18\ud658\ud55c\ub2e4.\n\n-- \ubaa8\ub4e0 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4. \ud574\uc81c\ub41c \uc7a0\uae08\uc758 \uac1c\uc218\ub97c \ubc18\ud658\ud55c\ub2e4.\nSELECT RELEASE_ALL_LOCKS();\n")),(0,r.kt)("h3",{id:"\uba54\ud0c0\ub370\uc774\ud130-\ub77dmetadata-lock"},"\uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)"),(0,r.kt)("p",null,"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac1d\uccb4\uc758 \uc774\ub984\uc774\ub098 \uad6c\uc870\ub97c \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \ud68d\ub4dd\ud558\ub294 \uc7a0\uae08\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uba85\uc2dc\uc801\uc73c\ub85c \ud68d\ub4dd \ub610\ub294 \ud574\uc81c \ud560 \uc218 \uc5c6\uc9c0\ub9cc \ud14c\uc774\ube14\uc758 \uc774\ub984\uc744 \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubcf4\ud1b5 \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc2e4\uc2dc\uac04\uc73c\ub85c \ud14c\uc774\ube14\uc744 \ubc14\uafd4\uc57c\ud558\ub294 \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\ub41c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"-- \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \ubcc4\ub3c4\uc758 \uc784\uc2dc \ud14c\uc774\ube14\uc5d0 \uc11c\ube44\uc2a4\uc6a9 \ub7ad\ud0b9 \ub370\uc774\ud130 \uc0dd\uc131 \ud6c4 \uae30\uc874 \ud14c\uc774\ube14\uc744 \ubc31\uc5c5\ud558\ub294 \uacbd\uc6b0\n-- \uc544\ub798 \uad6c\ubb38 \uc2e4\ud589 \uc2dc \uba54\ud0c0\ub370\uc774\ud130 \ub77d\uc744 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.\nRENAME TABLE rank TO rank_backup, rank_new TO rank;\n")),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://gywn.net/2013/12/mysql-user-level-lock/"},"MySQL\uc758 User Level Lock\ub97c \ud65c\uc6a9\ud55c\ub2e4\uba74?, gywndi"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html#function_release-all-locks"},"Locking Functions, MySQL 5.7 Reference"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_release-all-locks"},"Locking Functions, MySQL 8.0 Reference")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/db86613e.2f8f2d5c.js b/assets/js/db86613e.2f8f2d5c.js new file mode 100644 index 000000000..803d1a903 --- /dev/null +++ b/assets/js/db86613e.2f8f2d5c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9458],{82549:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>i});var t=r(85893),l=r(3905);const a={title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"mysql-lock",tags:["DataBase","Lock","MySQL"]},c=void 0,s={permalink:"/mysql-lock",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",source:"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",description:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",date:"2023-04-06T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 6\uc77c",tags:[{label:"DataBase",permalink:"/tags/data-base"},{label:"Lock",permalink:"/tags/lock"},{label:"MySQL",permalink:"/tags/my-sql"}],readingTime:4.405,hasTruncateMarker:!1,authors:[],frontMatter:{title:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",slug:"mysql-lock",tags:["DataBase","Lock","MySQL"]},unlisted:!1,prevItem:{title:"InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08",permalink:"/innodb-lock"},nextItem:{title:"\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900",permalink:"/transaction-and-isolation"}},o={authorsImageUrls:[]},i=[{value:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08",id:"mysql-\uc5d4\uc9c4\uc758-\uc7a0\uae08",level:2},{value:"\uae00\ub85c\ubc8c \ub77d(Global lock)",id:"\uae00\ub85c\ubc8c-\ub77dglobal-lock",level:3},{value:"\ud14c\uc774\ube14 \ub77d(Table lock)",id:"\ud14c\uc774\ube14-\ub77dtable-lock",level:3},{value:"\ub124\uc784\ub4dc \ub77d(Named lock)",id:"\ub124\uc784\ub4dc-\ub77dnamed-lock",level:3},{value:"\uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)",id:"\uba54\ud0c0\ub370\uc774\ud130-\ub77dmetadata-lock",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h2,{id:"mysql-\uc5d4\uc9c4\uc758-\uc7a0\uae08",children:"MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08"}),"\n",(0,t.jsxs)(n.p,{children:["MySQL\uc5d0\uc11c\uc758 \ub77d\uc740 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4 \ub808\ubca8\uacfc, MySQL \uc5d4\uc9c4 \ub808\ubca8\ub85c \ub098\ub20c \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","MySQL \uc5d4\uc9c4 \ub808\ubca8\uc758 \uc7a0\uae08\uc740 \ubaa8\ub4e0 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce5c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\uae00\ub85c\ubc8c-\ub77dglobal-lock",children:"\uae00\ub85c\ubc8c \ub77d(Global lock)"}),"\n",(0,t.jsx)(n.p,{children:"MySQL\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uc7a0\uae08 \uc911 \uac00\uc7a5 \ub113\uc740 \ubc94\uc704\ub97c \uac00\uc9c0\uace0 \uc788\ub294 \uc7a0\uae08\uc774\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc601\ud5a5\uc744 \ubbf8\uce58\ub294 \ubc94\uc704\ub294 \ud574\ub2f9 \uc11c\ubc84 \uc804\uccb4\uc774\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"\uc791\uc5c5 \ub300\uc0c1 \ud14c\uc774\ube14, \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc0c1\uad00 \uc5c6\uc774 \ub3d9\uc77c\ud558\uac8c \uc601\ud5a5\uc744 \ubc1b\ub294\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["\ud55c \uc138\uc158\uc5d0\uc11c \uae00\ub85c\ubc8c \ub77d\uc744 \ud68d\ub4dd\ud558\uba74 \ud574\uc81c \ub420 \ub54c \uae4c\uc9c0 \uc870\ud68c\ub97c \uc81c\uc678\ud55c \ub300\ubd80\ubd84\uc758 \uba85\ub839\uc774 \ub300\uae30 \uc0c1\ud0dc\uac00 \ub41c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc874\uc7ac\ud558\ub294 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub300\ud574 \uc77c\uad00\ub41c \ubc31\uc5c5\uc744 \ubc1b\uc544\uc57c\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc5d0\uc11c\ub294 \ubc31\uc5c5 \uc2dc \uc870\uae08 \ub354 \uac00\ubcbc\uc6b4 \ubc31\uc5c5 \ub77d\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sql",children:"-- GLOBAL LOCK\nFLUSH TABLES WITH READ LOCK;\n-- UNLOCK\nUNLOCK TABLES;\n\n-- BACKUP LOCK\nLOCK INSTANCE FOR BACKUP;\n-- UNLOCK\nUNLOCK INSTANCE;\n"})}),"\n",(0,t.jsx)(n.admonition,{title:"MyISAM",type:"note",children:(0,t.jsxs)(n.p,{children:["MySQL 5.5 \ubc84\uc804 \uc774\uc804\uc758 \uae30\ubcf8 \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud2b8\ub79c\uc7ad\uc158\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uace0, SELECT \uc791\uc5c5 \uc18d\ub3c4\uac00 \ube60\ub974\ub2e4."]})}),"\n",(0,t.jsx)(n.h3,{id:"\ud14c\uc774\ube14-\ub77dtable-lock",children:"\ud14c\uc774\ube14 \ub77d(Table lock)"}),"\n",(0,t.jsxs)(n.p,{children:["\uac1c\ubcc4 \ud14c\uc774\ube14 \ub2e8\uc704\ub85c \uc124\uc815\ub418\ub294 \uc7a0\uae08\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba85\uc2dc\uc801 \ub610\ub294 \ubb35\uc2dc\uc801\uc73c\ub85c \ud2b9\uc815 \ud14c\uc774\ube14\uc758 \ub77d\uc744 \ud68d\ub4dd\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubb35\uc2dc\uc801 \ub77d\uc740 MyISAM\uc774\ub098 MEMORY \ud14c\uc774\ube14\uc5d0 \ub370\uc774\ud130\ub97c \ubcc0\uacbd\ud558\ub294 \ucffc\ub9ac\ub97c \uc2e4\ud589\ud558\uba74 \ubc1c\uc0dd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","InnoDB \ud14c\uc774\ube14\uc5d0\ub294 DML \ucffc\ub9ac\ub294 \ubb34\uc2dc\ub418\uace0 DDL \uc77c \uacbd\uc6b0\uc5d0\ub9cc \ubb35\uc2dc\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sql",children:"-- TABLE LOCK\nLOCK TABLES table_name [ READ | WRITE ]\n\n-- UNLOCK\nUNLOCK TABLES;\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\ub124\uc784\ub4dc-\ub77dnamed-lock",children:"\ub124\uc784\ub4dc \ub77d(Named lock)"}),"\n",(0,t.jsxs)(n.p,{children:["\uc784\uc758\uc758 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \uc124\uc815\ud560 \uc218 \uc788\ub294 \uc7a0\uae08\uc73c\ub85c \uc720\uc800 \ub808\ubca8 \ub77d\uc73c\ub85c\ub3c4 \ubd88\ub9b0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc5ec\ub7ec \uc2a4\ub808\ub4dc\ub098 \ud504\ub85c\uc138\uc2a4\uac00 \ub3d9\uc77c\ud55c \ub370\uc774\ud130\ub97c \uc218\uc815\ud558\ub824\ub294 \uacbd\uc6b0, \ub3d9\uc2dc\uc5d0 \uc218\uc815\ud558\uc9c0 \ubabb\ud558\ub3c4\ub85d \ubcf4\ud638\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sql",children:"-- aGVyYg== \ub77c\ub294 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08 \ud68d\ub4dd, \uc774\ubbf8 \uc7a0\uae08\uc744 \uc0ac\uc6a9\uc911\uc778 \uacbd\uc6b0 1\ucd08 \ub3d9\uc548\ub9cc \ub300\uae30\nSELECT GET_LOCK('aGVyYg==', 1);\n\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc774 \uc124\uc815\ub418\uc5b4 \uc788\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.\nSELECT IS_FREE_LOCK('aGVyYg==');\n\n-- \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4.\nSELECT RELEASE_LOCK('aGVyYg==');\n\n-- \uc704 3\uac1c \ud568\uc218 \ubaa8\ub450 \uc815\uc0c1\uc801\uc73c\ub85c \ub77d\uc744 \ud68d\ub4dd\ud558\uac70\ub098 \ud574\uc81c\ud55c \uacbd\uc6b0\uc5d0 1\uc744, \uc544\ub2c8\uba74 0\uc744 \ubc18\ud658\ud55c\ub2e4.\n\n-- \ubaa8\ub4e0 \ubb38\uc790\uc5f4\uc5d0 \ub300\ud55c \uc7a0\uae08\uc744 \ud574\uc81c\ud55c\ub2e4. \ud574\uc81c\ub41c \uc7a0\uae08\uc758 \uac1c\uc218\ub97c \ubc18\ud658\ud55c\ub2e4.\nSELECT RELEASE_ALL_LOCKS();\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\uba54\ud0c0\ub370\uc774\ud130-\ub77dmetadata-lock",children:"\uba54\ud0c0\ub370\uc774\ud130 \ub77d(Metadata lock)"}),"\n",(0,t.jsxs)(n.p,{children:["\ub370\uc774\ud130\ubca0\uc774\uc2a4 \uac1d\uccb4\uc758 \uc774\ub984\uc774\ub098 \uad6c\uc870\ub97c \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \ud68d\ub4dd\ud558\ub294 \uc7a0\uae08\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uba85\uc2dc\uc801\uc73c\ub85c \ud68d\ub4dd \ub610\ub294 \ud574\uc81c \ud560 \uc218 \uc5c6\uc9c0\ub9cc \ud14c\uc774\ube14\uc758 \uc774\ub984\uc744 \ubcc0\uacbd\ud558\ub294 \uacbd\uc6b0 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubcf4\ud1b5 \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc2e4\uc2dc\uac04\uc73c\ub85c \ud14c\uc774\ube14\uc744 \ubc14\uafd4\uc57c\ud558\ub294 \uacbd\uc6b0\uc5d0 \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sql",children:"-- \ubc30\uce58 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \ubcc4\ub3c4\uc758 \uc784\uc2dc \ud14c\uc774\ube14\uc5d0 \uc11c\ube44\uc2a4\uc6a9 \ub7ad\ud0b9 \ub370\uc774\ud130 \uc0dd\uc131 \ud6c4 \uae30\uc874 \ud14c\uc774\ube14\uc744 \ubc31\uc5c5\ud558\ub294 \uacbd\uc6b0\n-- \uc544\ub798 \uad6c\ubb38 \uc2e4\ud589 \uc2dc \uba54\ud0c0\ub370\uc774\ud130 \ub77d\uc744 \uc790\ub3d9\uc73c\ub85c \ud68d\ub4dd\ud55c\ub2e4.\nRENAME TABLE rank TO rank_backup, rank_new TO rank;\n"})}),"\n",(0,t.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:["Real My SQL 8.0 - 5\uc7a5 \ud2b8\ub79c\uc7ad\uc158\uacfc \uc7a0\uae08, \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://gywn.net/2013/12/mysql-user-level-lock/",children:"MySQL\uc758 User Level Lock\ub97c \ud65c\uc6a9\ud55c\ub2e4\uba74?, gywndi"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/5.7/en/locking-functions.html#function_release-all-locks",children:"Locking Functions, MySQL 5.7 Reference"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_release-all-locks",children:"Locking Functions, MySQL 8.0 Reference"})]})]})}function p(e={}){const{wrapper:n}={...(0,l.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>i});var t=r(67294);function l(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function c(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?a(Object(r),!0).forEach((function(n){l(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function s(e,n){if(null==e)return{};var r,t,l=function(e,n){if(null==e)return{};var r,t,l={},a=Object.keys(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||(l[r]=e[r]);return l}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(l[r]=e[r])}return l}var o=t.createContext({}),i=function(e){var n=t.useContext(o),r=n;return e&&(r="function"==typeof e?e(n):c(c({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,l=e.mdxType,a=e.originalType,o=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=i(r),m=l,h=u["".concat(o,".").concat(m)]||u[m]||d[m]||a;return r?t.createElement(h,c(c({ref:n},p),{},{components:r})):t.createElement(h,c({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/dca6a1e3.373e22d0.js b/assets/js/dca6a1e3.373e22d0.js deleted file mode 100644 index f3fdc5845..000000000 --- a/assets/js/dca6a1e3.373e22d0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3239],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>b});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function p(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?o(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):o(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},o=Object.keys(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n<o.length;n++)r=o[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),c=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=c(r),b=a,v=m["".concat(i,".").concat(b)]||m[b]||s[b]||o;return r?n.createElement(v,p(p({ref:t},u),{},{components:r})):n.createElement(v,p({ref:t},u))}));function b(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,p=new Array(o);p[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,p[1]=l;for(var c=2;c<o;c++)p[c]=r[c];return n.createElement.apply(null,p)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},52589:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>p,default:()=>s,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var n=r(87462),a=(r(67294),r(3905));const o={title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",slug:"level2-interview-retrospective",tags:["Woowahan Techcourse","Retrospective"]},p=void 0,l={permalink:"/level2-interview-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",description:"\ub808\ubca8 \uc778\ud130\ubdf0",date:"2023-06-08T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 8\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.435,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",slug:"level2-interview-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",permalink:"/woowacourse-level2-retrospective"},nextItem:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",permalink:"/order-retrospective"}},i={authorsImageUrls:[]},c=[{value:"\ub808\ubca8 \uc778\ud130\ubdf0",id:"\ub808\ubca8-\uc778\ud130\ubdf0",level:3},{value:"API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd",id:"api-\ubb38\uc11c-\ub3c4\uad6c-\uc120\ud0dd",level:3},{value:"PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158",id:"put\uacfc-patch--\ud1a0\ud070\uacfc-\uc138\uc158",level:3},{value:"\uadf8 \uc678 \uac1c\uc120\ud560 \uc810",id:"\uadf8-\uc678-\uac1c\uc120\ud560-\uc810",level:3}],u={toc:c};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ub808\ubca8-\uc778\ud130\ubdf0"},"\ub808\ubca8 \uc778\ud130\ubdf0"),(0,a.kt)("p",null,"\ub808\ubca8 1 \ub54c\ub294 \uc900\ube44\ud574\ub454 \ub0b4\uc6a9\uc73c\ub85c \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud574\uc11c \uadf8\ub807\uac8c \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc774 \uc5c6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ub808\ubca8 1 \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0\ub294 \ub808\ubca8 1 \ud68c\uace0\ub97c \uc791\uc131\ud560 \ub54c \ub07c\uc6cc\ub123\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0\ub294 \ubc94\uc704\ub3c4 \uc81c\ud55c\ub418\uc5b4 \uc788\uc5b4 \uc5b4\ub5bb\uac8c \uc900\ube44\ud574\uc57c \ud560\uc9c0 \ub2f9\ud669\ud588\uace0, \ub2f5\ubcc0\uc5d0\ub3c4 \ubd80\uc871\ud55c \ubd80\ubd84\uc774 \ub9ce\uc558\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc5b5\uc774 \uc0ac\ub77c\uc9c0\uae30 \uc804\uc5d0 \ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\ud55c \ub0b4\uc6a9\uc744 \uc81c\uc678\ud558\uace0, \uae30\uc5b5 \ub0a8\ub294 \uac83 \uc704\uc8fc\ub85c \uc791\uc131\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"api-\ubb38\uc11c-\ub3c4\uad6c-\uc120\ud0dd"},"API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd"),(0,a.kt)("p",null,"\ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\uc744 \ud588\ub294\ub370 \uc55e\uc73c\ub85c\ub3c4 \ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \ud558\uba74\uc11c \ub3c4\uc6c0 \ub420 \uac83 \uac19\uc740 \ub0b4\uc6a9\uc774 \uc788\uc5b4\uc11c \ub0a8\uaca8\ub450\ub824\uace0 \ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubc31\uc5d4\ub4dc \ud300\uc6d0\uc774 \ud568\uaed8 \uc758\uc0ac\uacb0\uc815\uc744 \ud588\uace0, \ubbf8\uc158 \uae30\uac04\uc774 \uc9e7\uc740 \ub9cc\ud07c \ud300 \ucc28\uc6d0\uc5d0\uc11c \ube44\uad50\uc801 \ud559\uc2b5\ud558\uae30 \uc26c\uc6b4 Swagger\ub97c \uc120\ud0dd\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ub4e4\uc5b4\uac00\ub294 \uc2dc\uac04 \ub300\ube44 \ud558\uc774 \ub9ac\ud134\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4\uace0 \ub2f5\ubcc0\ud588\ub2e4."),(0,a.kt)("p",null,"\ud300 \ucc28\uc6d0\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uc5b8\uae09\ud574\uc11c, \ub2e4\uc74c\uacfc \uac19\uc740 \uc88b\uc740 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4."),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"\ud2b9\ud788 \ud300\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\ud558\ub294 \uacfc\uc815\uc744 \uacf5\uc720\ud574 \uc900 \uc810\uc774 \uc88b\uc558\uace0 \uae30\uc220\uc801 \uc758\uc0ac\uacb0\uc815 \uacfc\uc815\uc5d0\uc11c \ud300\uc758 \ud559\uc2b5\ube44\uc6a9\uc744 \uace0\ub824\ud55c \uc810\uc774 \uc88b\uc558\uc74c.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c\ub3c4 \ud559\uc2b5 \ube44\uc6a9\uc740 \uc8fc\uc694\ud558\uac8c \uace0\ub824\ud574\uc57c \ud560 \uc0ac\ud56d")),(0,a.kt)("h3",{id:"put\uacfc-patch--\ud1a0\ud070\uacfc-\uc138\uc158"},"PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158"),(0,a.kt)("p",null,"PUT\uacfc PATCH \ucc28\uc774\ub97c \uc124\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c\ub294 PATCH\ub97c \uc0ac\uc6a9\ud560 \ub54c \ud398\uc774\ub85c\ub4dc\uac00 \uc801\uc5b4\uc9c4\ub2e4\ub294 \ub0b4\uc6a9\uc744 \ube7c\uba39\uace0 \ub2f5\ubcc0\uc744 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud1a0\ud070\uacfc \uc138\uc158\uc758 \uacbd\uc6b0 \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud574\ub2ec\ub77c\ub294 \uc81c\uc57d\uc870\uac74\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ud574\ub2f9 \ub0b4\uc6a9\uc744 \ub2f5\ubcc0\ud558\uba74\uc11c \uae30\uc220\uc801\uc778 \uae4a\uc774\uac00 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc2e4\uc81c\ub85c \ub808\ubca8 2 \ub54c \uc774\ub860\uc801\uc778 \ud559\uc2b5 \uc2dc\uac04\uc774 \ub9e4\uc6b0 \uc801\uc5c8\uace0, \uc9d1\uc911\ub825\ub3c4 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc55e\uc73c\ub85c \uc5b4\ub5bb\uac8c \uae4a\uc774\ub97c \ucc44\uc6b8\uc9c0 \uace0\ubbfc\uc744 \ud560 \uc218 \uc788\ub294 \uc9c8\ubb38\ub4e4\uc774\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\ucd94\uac00\ub85c \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud558\ub294 \uac00\uc815\uc744 \ub450\uace0 \ud559\uc2b5\uc744 \ud55c\ub2e4\uba74 \ud070 \ub3c4\uc6c0\uc774 \ub420 \uac70\ub77c\ub294 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4. "),(0,a.kt)("h3",{id:"\uadf8-\uc678-\uac1c\uc120\ud560-\uc810"},"\uadf8 \uc678 \uac1c\uc120\ud560 \uc810"),(0,a.kt)("p",null,"\uc778\ud130\ubdf0\ud560 \ub54c \ud2b9\uc720\uc758 \ub9d0\ubc84\ub987\uc744 \uac1c\uc120\ud558\uae30",(0,a.kt)("br",{parentName:"p"}),"\n",'\uc0dd\uac01\ud560 \uc2dc\uac04\uc744 \uac00\uc84c\uc744 \ub54c "\ub2e4\uc2dc \ub9d0\uc500\ub4dc\ub824\ub3c4 \ub420\uae4c\uc694?"\ub77c\uace0 \ub9d0\ud558\uace0 \ub2f5\ubcc0\uc744 \uc774\uc5b4\ub098\uac00\uae30',(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc220\uc801\uc73c\ub85c \uae4a\uc774\uac00 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5b4\uc11c \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\uae30",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804\uc5d0 \uacf5\ubd80\ud588\ub358\uac70 \ub418\ub3cc\uc544 \ubcf4\ub294 \uc2dc\uac04 \uac00\uc9c0\uae30"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dca6a1e3.52680b40.js b/assets/js/dca6a1e3.52680b40.js new file mode 100644 index 000000000..251dcc185 --- /dev/null +++ b/assets/js/dca6a1e3.52680b40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3239],{25386:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>u,frontMatter:()=>i,metadata:()=>s,toc:()=>l});var n=t(85893),o=t(3905);const i={title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",slug:"level2-interview-retrospective",tags:["Woowahan Techcourse","Retrospective"]},c=void 0,s={permalink:"/level2-interview-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",source:"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",description:"\ub808\ubca8 \uc778\ud130\ubdf0",date:"2023-06-08T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 8\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:3.435,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0",slug:"level2-interview-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2 \ud68c\uace0",permalink:"/woowacourse-level2-retrospective"},nextItem:{title:"\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0",permalink:"/order-retrospective"}},a={authorsImageUrls:[]},l=[{value:"\ub808\ubca8 \uc778\ud130\ubdf0",id:"\ub808\ubca8-\uc778\ud130\ubdf0",level:3},{value:"API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd",id:"api-\ubb38\uc11c-\ub3c4\uad6c-\uc120\ud0dd",level:3},{value:"PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158",id:"put\uacfc-patch--\ud1a0\ud070\uacfc-\uc138\uc158",level:3},{value:"\uadf8 \uc678 \uac1c\uc120\ud560 \uc810",id:"\uadf8-\uc678-\uac1c\uc120\ud560-\uc810",level:3}];function p(e){const r={blockquote:"blockquote",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h3,{id:"\ub808\ubca8-\uc778\ud130\ubdf0",children:"\ub808\ubca8 \uc778\ud130\ubdf0"}),"\n",(0,n.jsxs)(r.p,{children:["\ub808\ubca8 1 \ub54c\ub294 \uc900\ube44\ud574\ub454 \ub0b4\uc6a9\uc73c\ub85c \uc778\ud130\ubdf0\ub97c \uc9c4\ud589\ud574\uc11c \uadf8\ub807\uac8c \ud2b9\ubcc4\ud55c \ubd80\ubd84\uc774 \uc5c6\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ub530\ub77c\uc11c \ub808\ubca8 1 \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0\ub294 \ub808\ubca8 1 \ud68c\uace0\ub97c \uc791\uc131\ud560 \ub54c \ub07c\uc6cc\ub123\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc774\ubc88\uc5d0\ub294 \ubc94\uc704\ub3c4 \uc81c\ud55c\ub418\uc5b4 \uc788\uc5b4 \uc5b4\ub5bb\uac8c \uc900\ube44\ud574\uc57c \ud560\uc9c0 \ub2f9\ud669\ud588\uace0, \ub2f5\ubcc0\uc5d0\ub3c4 \ubd80\uc871\ud55c \ubd80\ubd84\uc774 \ub9ce\uc558\uc5c8\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uae30\uc5b5\uc774 \uc0ac\ub77c\uc9c0\uae30 \uc804\uc5d0 \ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\ud55c \ub0b4\uc6a9\uc744 \uc81c\uc678\ud558\uace0, \uae30\uc5b5 \ub0a8\ub294 \uac83 \uc704\uc8fc\ub85c \uc791\uc131\ud574 \ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,n.jsx)(r.h3,{id:"api-\ubb38\uc11c-\ub3c4\uad6c-\uc120\ud0dd",children:"API \ubb38\uc11c \ub3c4\uad6c \uc120\ud0dd"}),"\n",(0,n.jsxs)(r.p,{children:["\ud070 \ubb38\uc81c \uc5c6\uc774 \ub2f5\ubcc0\uc744 \ud588\ub294\ub370 \uc55e\uc73c\ub85c\ub3c4 \ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \ud558\uba74\uc11c \ub3c4\uc6c0 \ub420 \uac83 \uac19\uc740 \ub0b4\uc6a9\uc774 \uc788\uc5b4\uc11c \ub0a8\uaca8\ub450\ub824\uace0 \ud55c\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ubc31\uc5d4\ub4dc \ud300\uc6d0\uc774 \ud568\uaed8 \uc758\uc0ac\uacb0\uc815\uc744 \ud588\uace0, \ubbf8\uc158 \uae30\uac04\uc774 \uc9e7\uc740 \ub9cc\ud07c \ud300 \ucc28\uc6d0\uc5d0\uc11c \ube44\uad50\uc801 \ud559\uc2b5\ud558\uae30 \uc26c\uc6b4 Swagger\ub97c \uc120\ud0dd\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ucd94\uac00\ub85c \ub4e4\uc5b4\uac00\ub294 \uc2dc\uac04 \ub300\ube44 \ud558\uc774 \ub9ac\ud134\uc774\ub77c\uace0 \uc0dd\uac01\ud588\ub2e4\uace0 \ub2f5\ubcc0\ud588\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:"\ud300 \ucc28\uc6d0\uc758 \ud559\uc2b5 \ube44\uc6a9\uc744 \uc5b8\uae09\ud574\uc11c, \ub2e4\uc74c\uacfc \uac19\uc740 \uc88b\uc740 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4."}),"\n",(0,n.jsxs)(r.blockquote,{children:["\n",(0,n.jsxs)(r.p,{children:["\ud2b9\ud788 \ud300\uc73c\ub85c \uc758\uc0ac\uacb0\uc815\ud558\ub294 \uacfc\uc815\uc744 \uacf5\uc720\ud574 \uc900 \uc810\uc774 \uc88b\uc558\uace0 \uae30\uc220\uc801 \uc758\uc0ac\uacb0\uc815 \uacfc\uc815\uc5d0\uc11c \ud300\uc758 \ud559\uc2b5\ube44\uc6a9\uc744 \uace0\ub824\ud55c \uc810\uc774 \uc88b\uc558\uc74c.",(0,n.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c\ub3c4 \ud559\uc2b5 \ube44\uc6a9\uc740 \uc8fc\uc694\ud558\uac8c \uace0\ub824\ud574\uc57c \ud560 \uc0ac\ud56d"]}),"\n"]}),"\n",(0,n.jsx)(r.h3,{id:"put\uacfc-patch--\ud1a0\ud070\uacfc-\uc138\uc158",children:"PUT\uacfc PATCH & \ud1a0\ud070\uacfc \uc138\uc158"}),"\n",(0,n.jsxs)(r.p,{children:["PUT\uacfc PATCH \ucc28\uc774\ub97c \uc124\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c\ub294 PATCH\ub97c \uc0ac\uc6a9\ud560 \ub54c \ud398\uc774\ub85c\ub4dc\uac00 \uc801\uc5b4\uc9c4\ub2e4\ub294 \ub0b4\uc6a9\uc744 \ube7c\uba39\uace0 \ub2f5\ubcc0\uc744 \ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\ud1a0\ud070\uacfc \uc138\uc158\uc758 \uacbd\uc6b0 \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud574\ub2ec\ub77c\ub294 \uc81c\uc57d\uc870\uac74\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4."]}),"\n",(0,n.jsxs)(r.p,{children:["\ud574\ub2f9 \ub0b4\uc6a9\uc744 \ub2f5\ubcc0\ud558\uba74\uc11c \uae30\uc220\uc801\uc778 \uae4a\uc774\uac00 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc2e4\uc81c\ub85c \ub808\ubca8 2 \ub54c \uc774\ub860\uc801\uc778 \ud559\uc2b5 \uc2dc\uac04\uc774 \ub9e4\uc6b0 \uc801\uc5c8\uace0, \uc9d1\uc911\ub825\ub3c4 \ub9ce\uc774 \ubd80\uc871\ud588\ub2e4.",(0,n.jsx)(r.br,{}),"\n","\uc55e\uc73c\ub85c \uc5b4\ub5bb\uac8c \uae4a\uc774\ub97c \ucc44\uc6b8\uc9c0 \uace0\ubbfc\uc744 \ud560 \uc218 \uc788\ub294 \uc9c8\ubb38\ub4e4\uc774\uc5c8\ub2e4."]}),"\n",(0,n.jsx)(r.p,{children:"\ucd94\uac00\ub85c \uae30\uc220\uc744 \uc798 \ubaa8\ub974\ub294 \uc0ac\ub78c\uc5d0\uac8c \uc124\uba85\ud558\ub294 \uac00\uc815\uc744 \ub450\uace0 \ud559\uc2b5\uc744 \ud55c\ub2e4\uba74 \ud070 \ub3c4\uc6c0\uc774 \ub420 \uac70\ub77c\ub294 \ud53c\ub4dc\ubc31\uc744 \ubc1b\uc558\ub2e4."}),"\n",(0,n.jsx)(r.h3,{id:"\uadf8-\uc678-\uac1c\uc120\ud560-\uc810",children:"\uadf8 \uc678 \uac1c\uc120\ud560 \uc810"}),"\n",(0,n.jsxs)(r.p,{children:["\uc778\ud130\ubdf0\ud560 \ub54c \ud2b9\uc720\uc758 \ub9d0\ubc84\ub987\uc744 \uac1c\uc120\ud558\uae30",(0,n.jsx)(r.br,{}),"\n",'\uc0dd\uac01\ud560 \uc2dc\uac04\uc744 \uac00\uc84c\uc744 \ub54c "\ub2e4\uc2dc \ub9d0\uc500\ub4dc\ub824\ub3c4 \ub420\uae4c\uc694?"\ub77c\uace0 \ub9d0\ud558\uace0 \ub2f5\ubcc0\uc744 \uc774\uc5b4\ub098\uac00\uae30',(0,n.jsx)(r.br,{}),"\n","\uae30\uc220\uc801\uc73c\ub85c \uae4a\uc774\uac00 \ubd80\uc871\ud558\ub2e4\uace0 \uc0dd\uac01\uc774 \ub9ce\uc774 \ub4e4\uc5b4\uc11c \uc870\uae08 \ub354 \uae4a\uac8c \uacf5\ubd80\ud558\uace0 \uc815\ub9ac\ud558\uae30",(0,n.jsx)(r.br,{}),"\n","\uc774\uc804\uc5d0 \uacf5\ubd80\ud588\ub358\uac70 \ub418\ub3cc\uc544 \ubcf4\ub294 \uc2dc\uac04 \uac00\uc9c0\uae30"]})]})}function u(e={}){const{wrapper:r}={...(0,o.ah)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},3905:(e,r,t)=>{t.d(r,{ah:()=>l});var n=t(67294);function o(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function i(e,r){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);r&&(n=n.filter((function(r){return Object.getOwnPropertyDescriptor(e,r).enumerable}))),t.push.apply(t,n)}return t}function c(e){for(var r=1;r<arguments.length;r++){var t=null!=arguments[r]?arguments[r]:{};r%2?i(Object(t),!0).forEach((function(r){o(e,r,t[r])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(r){Object.defineProperty(e,r,Object.getOwnPropertyDescriptor(t,r))}))}return e}function s(e,r){if(null==e)return{};var t,n,o=function(e,r){if(null==e)return{};var t,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||(o[t]=e[t]);return o}(e,r);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)t=i[n],r.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var a=n.createContext({}),l=function(e){var r=n.useContext(a),t=r;return e&&(t="function"==typeof e?e(r):c(c({},r),e)),t},p={inlineCode:"code",wrapper:function(e){var r=e.children;return n.createElement(n.Fragment,{},r)}},u=n.forwardRef((function(e,r){var t=e.components,o=e.mdxType,i=e.originalType,a=e.parentName,u=s(e,["components","mdxType","originalType","parentName"]),b=l(t),h=o,d=b["".concat(a,".").concat(h)]||b[h]||p[h]||i;return t?n.createElement(d,c(c({ref:r},u),{},{components:t})):n.createElement(d,c({ref:r},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/df147deb.036e49b2.js b/assets/js/df147deb.036e49b2.js deleted file mode 100644 index 90c8f67c6..000000000 --- a/assets/js/df147deb.036e49b2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5103],{3905:(e,t,r)=>{r.d(t,{Zo:()=>d,kt:()=>c});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function p(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},l=Object.keys(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var i=n.createContext({}),s=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},d=function(e){var t=s(e.components);return n.createElement(i.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},u=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,i=e.parentName,d=p(e,["components","mdxType","originalType","parentName"]),u=s(r),c=a,k=u["".concat(i,".").concat(c)]||u[c]||m[c]||l;return r?n.createElement(k,o(o({ref:t},d),{},{components:r})):n.createElement(k,o({ref:t},d))}));function c(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=u;var p={};for(var i in t)hasOwnProperty.call(t,i)&&(p[i]=t[i]);p.originalType=e,p.mdxType="string"==typeof e?e:a,o[1]=p;for(var s=2;s<l;s++)o[s]=r[s];return n.createElement.apply(null,o)}return n.createElement.apply(null,r)}u.displayName="MDXCreateElement"},78134:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>m,frontMatter:()=>l,metadata:()=>p,toc:()=>s});var n=r(87462),a=(r(67294),r(3905));const l={title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",slug:"ladder-retrospective",tags:["Woowahan Techcourse","Retrospective"]},o=void 0,p={permalink:"/ladder-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-ladder/pull/97",date:"2023-02-26T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 26\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:10.285,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",slug:"ladder-retrospective",tags:["Woowahan Techcourse","Retrospective"]},prevItem:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",permalink:"/blackjack-retrospective"},nextItem:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",permalink:"/racing-car-retrospective"}},i={authorsImageUrls:[]},s=[{value:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30",id:"\uc0ac\ub2e4\ub9ac-\ud0c0\uae30",level:3},{value:"Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95",id:"position-\uae30\uc900\uc73c\ub85c-\uc0ac\ub2e4\ub9ac-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",level:3},{value:"Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95",id:"player\uc5d0\uac8c-ladder\ub97c-\uc804\ub2ec\ud558\uc5ec-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}],d={toc:s};function m(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},d,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{title:"PR \ub9c1\ud06c ",type:"note"},(0,a.kt)("p",{parentName:"admonition"},"1\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-ladder/pull/97"},"https://github.com/woowacourse/java-ladder/pull/97"),(0,a.kt)("br",{parentName:"p"}),"\n","2\ub2e8\uacc4: ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/woowacourse/java-ladder/pull/234"},"https://github.com/woowacourse/java-ladder/pull/234")," ")),(0,a.kt)("h3",{id:"\uc0ac\ub2e4\ub9ac-\ud0c0\uae30"},"\uc0ac\ub2e4\ub9ac \ud0c0\uae30"),(0,a.kt)("p",null,"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc6b0\uac00\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804 \ubbf8\uc158\uacfc \ub2ec\ub9ac TDD\ub85c \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ud544\uc218\uc600\uae30 \ub54c\ubb38\uc5d0 \uc775\uc219\ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, \uc6b0\uac00\uc640 \ubbf8\uc158\uc5d0 \uad00\ud55c \uc18c\ud1b5\uc774 \uc798 \ub418\uc5b4\uc11c \ud070 \ubb38\uc81c \uc5c6\uc774 \ubbf8\uc158\uc744 \ub9c8\ubb34\ub9ac\ud560 \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc6b0\uac00\uc640 \uc774\uc57c\uae30\uac00 \uc798 \ud1b5\ud574\uc11c \uadf8\ub7f0\uc9c0 1\ub2e8\uacc4\ub294 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub294\ub370, 2\ub2e8\uacc4\uc5d0\uc11c \ub9ce\uc774 \uace0\uc804\ud55c \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,"2\ub2e8\uacc4\uc5d0\uc11c\ub294 2\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ud574\ubd24\ub2e4."),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"LadderGame\uc5d0\uc11c Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"),(0,a.kt)("li",{parentName:"ol"},"Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c Ladder\uc5d0\uac8c Position\uc744 \ub118\uaca8\uc8fc\uba70 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95")),(0,a.kt)("h3",{id:"position-\uae30\uc900\uc73c\ub85c-\uc0ac\ub2e4\ub9ac-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95"},"Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"),(0,a.kt)("p",null,"\uc0ac\uc2e4\uc0c1 index\ub97c Ladder\uc5d0\uac8c \ub118\uaca8\uc8fc\uace0, \ud574\ub2f9 index\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc1b\ub294 \ubc29\ubc95\uacfc \uc720\uc0ac\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uad6c\ud604\ud558\uace0 \ub098\ub2c8 \ub2e4\ub978 \ud074\ub798\uc2a4\ub4e4\uc774 Position\uc5d0 \ub300\ud55c \uc758\uc874\ub3c4\uac00 \ub108\ubb34 \ub192\uc740 \uac83 \uac19\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c Players\uac00 \ubcc4\ub2e4\ub978 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uc9c0 \uc54a\ub2e4\uace0 \ub290\uaf08\ub2e4. "),(0,a.kt)("mermaid",{value:"graph TD\n\n LadderGameController --\x3e LadderGame\n LadderGame --\x3e Ladder\n LadderGame --\x3e Players\n LadderGame --\x3e Items\n\n Ladder --\x3e Line\n Line --\x3e LineStatus\n\n LadderGame --\x3e Position\n Ladder --\x3e Position\n Items --\x3e Position\n Line --\x3e Position\n Players --\x3e Position\n\n LadderGame --\x3e LadderGameResult\n\n Items --\x3e Item\n Players --\x3e Player\n\n LadderGameController --\x3e InputView\n LadderGameController --\x3e OutputView\n"}),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public LadderGameResult play() {\n final Map<Player, Item> result = new LinkedHashMap<>();\n // \uc0ac\uc6a9\uc790 \uc218\ub9cc\ud07c Position\uc744 \uac00\uc838\uc640\uc11c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4.\n for (Position position : Position.range(players.count())) {\n final Position resultPosition = ladder.play(position);\n result.put(players.get(position), items.get(resultPosition));\n }\n return new LadderGameResult(result);\n}\n")),(0,a.kt)("h3",{id:"player\uc5d0\uac8c-ladder\ub97c-\uc804\ub2ec\ud558\uc5ec-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95"},"Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"),(0,a.kt)("p",null,"Position\uc5d0 \ub300\ud55c \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub294 Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c, Player\uac00 Ladder\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774 \ubc29\ubc95\uc774 \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc704\ud574\uc11c \uac1d\uccb4\ub4e4\uc774 \uae34\ubc00\ud558\uac8c \ud611\ub825\ud558\uace0, \uc870\uae08 \ub354 \ucc45\uc784\uc758 \ubd84\ubc30\uac00 \uc798 \ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\uc774 \ub418\uc5c8\ub2e4. "),(0,a.kt)("mermaid",{value:"graph TD\n\n LadderGameController --\x3e LadderGame\n LadderGame --\x3e Ladder\n LadderGame --\x3e Players\n LadderGame --\x3e Items\n\n Ladder --\x3e Line\n Line --\x3e LineStatus\n Line --\x3e Position\n\n Players --\x3e Ladder\n Player --\x3e Ladder\n\n Item --\x3e Position\n Player --\x3e Position\n\n\n LadderGame --\x3e LadderGameResult\n\n Items --\x3e Item --\x3e ItemName\n Players --\x3e Player --\x3e PlayerName\n\n LadderGameController --\x3e InputView\n LadderGameController --\x3e OutputView\n\n OutputView --\x3e LadderMessageGenerator"}),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java"},"public LadderGameResult play() {\n // \ucc38\uac00\uc790\ub4e4\uc5d0\uac8c \uc0ac\ub2e4\ub9ac\ub97c \uc804\ub2ec\ud574\uc11c \uc0ac\ub2e4\ub9ac\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \ud55c\ub2e4.\n final Map<Player, Position> playResult = players.play(ladder);\n\n final Map<Player, Item> result = new LinkedHashMap<>();\n for (Player player : playResult.keySet()) {\n result.put(player, toItem(playResult.get(player)));\n }\n return new LadderGameResult(result);\n}\n")),(0,a.kt)("h3",{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84"},"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\uc5d0 \uc2dc\uac04\uc744 \ub4e4\uc774\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc815\ud558\ub294\ub370 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ub4e4\uc5ec\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc0ac\ub2e4\ub9ac \ud0c0\uae30\uc758 \uc2e4\ud589 \uacb0\uacfc\ub97c Item\uc73c\ub85c \uc9d3\ub2e4\ub2c8.. \ubb54\uac00 \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc804 \ubbf8\uc158\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c, \uba85\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \ubd80\uc871\ud568\uc744 \ub9ce\uc774 \ub290\uaf08\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud398\uc5b4\uc640 \uc870\uae08 \ub354 \uce5c\ud574\uc9c0\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uccab\ub0a0\uc740 \ud398\uc5b4\uc640 \uce5c\ud574\uc9c0\ub294 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \uac00\uc838\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\uac00\ub791 \ud68c\uace0\ud560 \ub54c \ub0b4\uac00 \uc2dc\uc791\ud558\uc790\ub9c8\uc790 \ucee8\ubca4\uc158 \uc815\ud558\uc790\uace0 \ud574\uc11c \ub9ce\uc774 \ub2f9\ud669\uc2a4\ub7ec\uc6e0\ub2e4\uace0 \ud55c\ub2e4. \uc6b0\uac00 \ubbf8\uc548.. \ud83e\udd72"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"README\ub97c \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uc0c1\ud558\uac8c \ucf54\ub529\uc5d0 \uc9d1\uc911\ud558\uba74 README\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\uba74\uc11c \uac19\uc774 \ucee4\ubc0b \ud558\ub294 \uac78 \ud56d\uc0c1 \uae4c\uba39\ub294\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \ubbf8\uc158\uc5d0\ub294 \uc870\uae08 \ub354 \uc2e0\uacbd \uc368\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc88b\uc740 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uccab PR\ub54c \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \uc9c8\ubb38\uc744 \ub0a8\uae30\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9ac\ubdf0\uc5b4\uc640\uc758 \uc2dc\uac04\uc774 \uc18c\uc911\ud55c \uc2dc\uac04\uc774\ub77c\ub294 \uac83\uc744 \uae4c\uba39\uc9c0 \ub9d0\uace0, \ub098\uc758 \uc131\uc7a5\uc5d0 \ub3c4\uc6c0\uc774 \ub420 \uc218 \uc788\ub294 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud574\uc57c\uaca0\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"PR \ud6c4\uc5d0\ub3c4 \uaf3c\uaf3c\ud558\uac8c \ud655\uc778\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\ubd84\uba85 \uc54c\uace0 \uc788\ub294 \ubd80\ubd84\uc774\uc9c0\ub9cc, \ub193\uce5c \ubd80\ubd84\uc774 \ub9ce\uc740 \uac83 \uac19\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","PR \ud558\uae30 \uc804\uc5d0\ub3c4 \uacc4\uc18d \ud655\uc778\uc744 \ud588\uc9c0\ub9cc, \uc544\ubb34\ub798\ub3c4 IntelliJ\uc5d0\uc11c \ubcf4\ub2c8 \ucf54\ub4dc\uc5d0 \uc775\uc219\ud574\uc838\uc11c \uadf8\ub7f0\uc9c0 \ubcc0\uacbd\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc798 \uc548\ubcf4\uc600\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","github pr\uc5d0\uc11c\ub294 \uc804\uccb4 \ubcc0\uacbd\uc0ac\ud56d\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc73c\ub2c8 PR \ud6c4\uc5d0\ub3c4 \uaf2d \ud655\uc778\ud574\uc57c\uaca0\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc801\uadf9\uc801\uc73c\ub85c \ub098\uc758 \uc758\uacac\uc744 \ub9d0\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ud398\uc5b4\uc758 \uc758\uacac\uc774 \uad1c\ucc2e\ub2e4\uace0 \uc0dd\uac01\ud558\uba74 \uc218\uc6a9 \ud6c4 \uac1c\uc120\uc744 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\uc5c8\ub294\ub370, \uc870\uae08 \ub354 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ud5a5\uc774 \uc788\ub2e4\uba74 \ub098\ub3c4 \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub9d0\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\ub3c4 \uc124\ub4dd\ud558\ub294 \ud798\uc744 \uae30\ub974\uace0, \ud398\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc744 \uc54c \uc218 \uc788\uace0, \uacb0\uacfc\ubb3c\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub098\uc624\uc9c0 \uc54a\uc744\uae4c? (\uace0\ubbfc \ub4e4\uc5b4\uc8fc\uc2e0 \ub9ac\ubdf0\uc5b4 \ud130\ud2c0\ud83d\udc22 \uac10\uc0ac\ud569\ub2c8\ub2e4.)"),(0,a.kt)("h3",{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84"},"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784"),(0,a.kt)("br",{parentName:"p"}),"\n","Players\uac00 Position\uc744 \uc0dd\uc131\ud558\uace0 Player\uc758 \uc0dd\uc131\uc790\uc5d0 \ub123\uc5b4\uc8fc\uc5c8\ub2e4. \ud558\uc9c0\ub9cc \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ub828\ub41c \ucf54\uba58\ud2b8\uac00 \ub2ec\ub838\ub2e4.\n\uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uc0dd\uac01\ud574 \ubcf4\ub2c8 Position\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uac74 Player\uae30 \ub54c\ubb38\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 Player\uac00 \ub2f4\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud55c \ud328\ud134\uc73c\ub85c GRASP\uc758 Creator \ud328\ud134\uc774 \uc788\ub294\ub370 \ub2e4\uc74c\uc758 \uc694\uc18c\ub97c \ucd5c\ub300\ud55c \ub9cc\uc871\ud558\ub294 \ud074\ub798\uc2a4\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4. "),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"B\uac00 A\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4."),(0,a.kt)("li",{parentName:"ul"},"B\uac00 A\uc758 \ucd08\uae43\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4. ")),(0,a.kt)("p",null,"\uc2e4\uc81c\ub85c \uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud574\uc11c \uae4a\uc774 \uc0dd\uac01\ud558\uba74\uc11c \ucf54\ub529\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc2dc\uc57c\uac00 \ub113\uc5b4\uc9c4 \uac83 \uac19\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\ud328\ud0a4\uc9c0 \ubd84\ub9ac \uae30\uc900"),(0,a.kt)("br",{parentName:"p"}),"\n","\ud328\ud0a4\uc9c0 \ubd84\ub9ac\uc5d0 \ub300\ud55c \ub098\ub9cc\uc758 \uae30\uc900\uc774 \uc544\uc9c1 \uba85\ud655\ud558\uc9c0 \uc54a\uc544 \uc9c8\ubb38\uc774 \ub4e4\uc5b4\uc640\ub3c4 \uba85\ud655\ud558\uac8c \ub2f5\ubcc0\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9c8\uc9c0\ub9c9 \uc81c\ucd9c \uc804\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub97c \ubd84\ub9ac\ud574 \ubd24\ub294\ub370, \uae30\uc900\uc774 \uba85\ud655\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \uc88b\uc9c0 \uc54a\uc740 \uc120\ud0dd\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.\n\ud604\uc7ac \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud06c\uae30\uac00 \uadf8\ub807\uac8c \ud06c\uc9c0 \uc54a\uc73c\ub2c8, domain \ud328\ud0a4\uc9c0\uc5d0\uc11c \uc138\ubd80 \ud328\ud0a4\uc9c0\ub85c \ubd84\ub9ac\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub420 \uac83 \uac19\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("strong",{parentName:"p"},"\uc0ac\uc6a9\ud558\ub294 \ucabd\uc5d0\uc11c \uc0dd\uac01\ud558\uae30 & \uc608\uce21\uac00\ub2a5\ud55c \ucf54\ub4dc \uc791\uc131\ud558\uae30"),(0,a.kt)("br",{parentName:"p"}),"\n","Position\uc5d0\uc11c \ub2e4\uc74c \uc704\uce58\ub098 \uc774\uc804 \uc704\uce58\ub97c \ubc18\ud658\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud5c8\uc6a9 \ubc94\uc704(0~19)\uac00 \ubc97\uc5b4\ub09c\ub2e4\uba74, \uc758\ubbf8 \uc5c6\ub294 \uac12\uc774 \ub4e4\uc5b4\uac04 Position\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\uac74 Position\uc744 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc744 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \ucf54\ub529\uc774\uc5c8\ub294\ub370, \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 0~19\uc758 \uac12\uc774 \ubcf4\uc7a5\ub418\uc5b4 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uac83\uc774\uae30 \ub54c\ubb38\uc774\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c hasNext, hasPrevious\ub77c\ub294 \uc774\uc804 \uac12, \uc774\ud6c4 \uac12\uc774 \ubc94\uc704 \ub0b4\uc5d0 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ucd94\uac00\ud558\uace0, \uae30\uc874\uc758 \uac12\uc744 \uac00\uc838\uc624\ub294 \uba54\uc11c\ub4dc\ub294 \ubc94\uc704\uac00 \ubc97\uc5b4\ub098\uba74 \uc608\uc678\ub97c \ub358\uc9c0\ub294 \ubc29\ud5a5\uc73c\ub85c \ud574\uacb0\ud558\uc600\ub2e4. "),(0,a.kt)("h3",{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84"},"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"),(0,a.kt)("p",null,"\ubc1d\uc740 \uae30\uc6b4\uc744 \uac00\uc9c0\uace0 \uc788\uace0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \uce5c\ud654\ub825\uc774 \uc88b\uc740 \uac83 \uac19\uc558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ubc88\uc5d0 \ud398\uc5b4 \ud560 \ub54c \ucee8\ub514\uc158 \uad00\ub9ac\ub97c \uc81c\ub300\ub85c \ubabb\ud574\uc11c \ub9ce\uc774 \ubbf8\uc548\ud588\ub2e4. \ub2e4\uc74c\uc5d0\ub294 \ucd5c\uc0c1\uc758 \ucee8\ub514\uc158\uc73c\ub85c \ud398\uc5b4\ub97c \uc900\ube44\ud574 \ubd10\uc57c\uaca0\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uadf8\ub9ac\uace0 \uc6b0\uac00\ub791 \ud398\uc5b4\ub97c \ud558\uace0 \ub098\uc11c, \ub098\ub3c4 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \ub354 \uc798 \uc9c0\ub0b4\ubd10\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5b4 \uc870\uae08 \ub354 \uc6a9\uae30\ub97c \ub0b4 \uc7a1\ub2f4 \uc911\uc774\ub2e4! "),(0,a.kt)("p",null,"\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589\uc774 \uc798 \ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \ud398\uc5b4 \uc9c4\ud589\uc774 \ub290\ub9b0 \uac83 \uac19\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c \uc548\uc815\uc801\uc73c\ub85c \uc2dc\uac04 \uc548\uc5d0 \ubbf8\uc158\uc744 \uc644\ub8cc\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589 \uc18d\ub3c4\uc5d0 \ub300\ud574 \uc870\uae08 \ub354 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4!"),(0,a.kt)("p",null,"\ud56d\uc0c1 \uc9c0\ub098\uac08 \ub54c\ub9c8\ub2e4 \uc6c3\uc5b4\uc8fc\ub294\ub370, \ub098\ub3c4 \uc790\uc8fc \uc6c3\uc5b4\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6c3\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uc0ac\ub78c\uc774 \ubc1d\uc544 \ubcf4\uc5ec\uc11c \ub108\ubb34 \uc88b\uc740 \uac83 \uac19\ub2e4!"))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/df147deb.ff087a25.js b/assets/js/df147deb.ff087a25.js new file mode 100644 index 000000000..dc020866d --- /dev/null +++ b/assets/js/df147deb.ff087a25.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5103],{43420:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>x,frontMatter:()=>s,metadata:()=>l,toc:()=>d});var t=r(85893),a=r(3905);const s={title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",slug:"ladder-retrospective",tags:["Woowahan Techcourse","Retrospective"]},i=void 0,l={permalink:"/ladder-retrospective",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",source:"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",description:"1\ub2e8\uacc4//github.com/woowacourse/java-ladder/pull/97",date:"2023-02-26T00:00:00.000Z",formattedDate:"2023\ub144 2\uc6d4 26\uc77c",tags:[{label:"Woowahan Techcourse",permalink:"/tags/woowahan-techcourse"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:10.285,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0",slug:"ladder-retrospective",tags:["Woowahan Techcourse","Retrospective"]},unlisted:!1,prevItem:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",permalink:"/blackjack-retrospective"},nextItem:{title:"\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0",permalink:"/racing-car-retrospective"}},o={authorsImageUrls:[]},d=[{value:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30",id:"\uc0ac\ub2e4\ub9ac-\ud0c0\uae30",level:3},{value:"Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95",id:"position-\uae30\uc900\uc73c\ub85c-\uc0ac\ub2e4\ub9ac-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",level:3},{value:"Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95",id:"player\uc5d0\uac8c-ladder\ub97c-\uc804\ub2ec\ud558\uc5ec-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",level:3},{value:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84",id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",level:3},{value:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84",id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",level:3},{value:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84",id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",level:3}];function c(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",del:"del",h3:"h3",li:"li",mermaid:"mermaid",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.admonition,{title:"PR \ub9c1\ud06c",type:"note",children:(0,t.jsxs)(n.p,{children:["1\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/java-ladder/pull/97",children:"https://github.com/woowacourse/java-ladder/pull/97"}),(0,t.jsx)(n.br,{}),"\n","2\ub2e8\uacc4: ",(0,t.jsx)(n.a,{href:"https://github.com/woowacourse/java-ladder/pull/234",children:"https://github.com/woowacourse/java-ladder/pull/234"})]})}),"\n",(0,t.jsx)(n.h3,{id:"\uc0ac\ub2e4\ub9ac-\ud0c0\uae30",children:"\uc0ac\ub2e4\ub9ac \ud0c0\uae30"}),"\n",(0,t.jsxs)(n.p,{children:["\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158\uc5d0\uc11c\ub294 \uc6b0\uac00\uc640 \ud398\uc5b4\uac00 \ub9e4\uce6d\ub418\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\uc804 \ubbf8\uc158\uacfc \ub2ec\ub9ac TDD\ub85c \uc9c4\ud589\ud558\ub294 \uac83\uc774 \ud544\uc218\uc600\uae30 \ub54c\ubb38\uc5d0 \uc775\uc219\ud558\uc9c0 \uc54a\uc558\uc9c0\ub9cc, \uc6b0\uac00\uc640 \ubbf8\uc158\uc5d0 \uad00\ud55c \uc18c\ud1b5\uc774 \uc798 \ub418\uc5b4\uc11c \ud070 \ubb38\uc81c \uc5c6\uc774 \ubbf8\uc158\uc744 \ub9c8\ubb34\ub9ac\ud560 \uc218 \uc788\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:"\uc6b0\uac00\uc640 \uc774\uc57c\uae30\uac00 \uc798 \ud1b5\ud574\uc11c \uadf8\ub7f0\uc9c0 1\ub2e8\uacc4\ub294 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uac8c \uc9c4\ud589\ud560 \uc218 \uc788\uc5c8\ub294\ub370, 2\ub2e8\uacc4\uc5d0\uc11c \ub9ce\uc774 \uace0\uc804\ud55c \uac83 \uac19\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:"2\ub2e8\uacc4\uc5d0\uc11c\ub294 2\uac00\uc9c0 \ubc29\ubc95\uc73c\ub85c \uad6c\ud604\ud574\ubd24\ub2e4."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"LadderGame\uc5d0\uc11c Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsx)(n.li,{children:"Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c Ladder\uc5d0\uac8c Position\uc744 \ub118\uaca8\uc8fc\uba70 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"position-\uae30\uc900\uc73c\ub85c-\uc0ac\ub2e4\ub9ac-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",children:"Position \uae30\uc900\uc73c\ub85c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsxs)(n.p,{children:["\uc0ac\uc2e4\uc0c1 index\ub97c Ladder\uc5d0\uac8c \ub118\uaca8\uc8fc\uace0, \ud574\ub2f9 index\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc1b\ub294 \ubc29\ubc95\uacfc \uc720\uc0ac\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uad6c\ud604\ud558\uace0 \ub098\ub2c8 \ub2e4\ub978 \ud074\ub798\uc2a4\ub4e4\uc774 Position\uc5d0 \ub300\ud55c \uc758\uc874\ub3c4\uac00 \ub108\ubb34 \ub192\uc740 \uac83 \uac19\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ud55c Players\uac00 \ubcc4\ub2e4\ub978 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uc9c0 \uc54a\ub2e4\uace0 \ub290\uaf08\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph TD\n\n LadderGameController --\x3e LadderGame\n LadderGame --\x3e Ladder\n LadderGame --\x3e Players\n LadderGame --\x3e Items\n\n Ladder --\x3e Line\n Line --\x3e LineStatus\n\n LadderGame --\x3e Position\n Ladder --\x3e Position\n Items --\x3e Position\n Line --\x3e Position\n Players --\x3e Position\n\n LadderGame --\x3e LadderGameResult\n\n Items --\x3e Item\n Players --\x3e Player\n\n LadderGameController --\x3e InputView\n LadderGameController --\x3e OutputView\n"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"public LadderGameResult play() {\n final Map<Player, Item> result = new LinkedHashMap<>();\n // \uc0ac\uc6a9\uc790 \uc218\ub9cc\ud07c Position\uc744 \uac00\uc838\uc640\uc11c \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc9c4\ud589\ud55c\ub2e4.\n for (Position position : Position.range(players.count())) {\n final Position resultPosition = ladder.play(position);\n result.put(players.get(position), items.get(resultPosition));\n }\n return new LadderGameResult(result);\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"player\uc5d0\uac8c-ladder\ub97c-\uc804\ub2ec\ud558\uc5ec-\uac8c\uc784\uc744-\uc9c4\ud589\ud558\ub294-\ubc29\ubc95",children:"Player\uc5d0\uac8c Ladder\ub97c \uc804\ub2ec\ud558\uc5ec \uac8c\uc784\uc744 \uc9c4\ud589\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsxs)(n.p,{children:["Position\uc5d0 \ub300\ud55c \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub294 Player\uc5d0\uac8c Ladder\ub97c \ub118\uaca8\uc11c, Player\uac00 Ladder\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \uad6c\ud604\ud558\uc600\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \ubc29\ubc95\uc774 \uc0ac\ub2e4\ub9ac \uac8c\uc784\uc744 \uc704\ud574\uc11c \uac1d\uccb4\ub4e4\uc774 \uae34\ubc00\ud558\uac8c \ud611\ub825\ud558\uace0, \uc870\uae08 \ub354 \ucc45\uc784\uc758 \ubd84\ubc30\uac00 \uc798 \ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\uc774 \ub418\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.mermaid,{value:"graph TD\n\n LadderGameController --\x3e LadderGame\n LadderGame --\x3e Ladder\n LadderGame --\x3e Players\n LadderGame --\x3e Items\n\n Ladder --\x3e Line\n Line --\x3e LineStatus\n Line --\x3e Position\n\n Players --\x3e Ladder\n Player --\x3e Ladder\n\n Item --\x3e Position\n Player --\x3e Position\n\n\n LadderGame --\x3e LadderGameResult\n\n Items --\x3e Item --\x3e ItemName\n Players --\x3e Player --\x3e PlayerName\n\n LadderGameController --\x3e InputView\n LadderGameController --\x3e OutputView\n\n OutputView --\x3e LadderMessageGenerator"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",children:"public LadderGameResult play() {\n // \ucc38\uac00\uc790\ub4e4\uc5d0\uac8c \uc0ac\ub2e4\ub9ac\ub97c \uc804\ub2ec\ud574\uc11c \uc0ac\ub2e4\ub9ac\uc5d0\uac8c \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub3c4\ub85d \ud55c\ub2e4.\n final Map<Player, Position> playResult = players.play(ladder);\n\n final Map<Player, Item> result = new LinkedHashMap<>();\n for (Player player : playResult.keySet()) {\n result.put(player, toItem(playResult.get(player)));\n }\n return new LadderGameResult(result);\n}\n"})}),"\n",(0,t.jsx)(n.h3,{id:"\ubd80\uc871\ud588\ub358-\ubd80\ubd84",children:"\ubd80\uc871\ud588\ub358 \ubd80\ubd84"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\uc5d0 \uc2dc\uac04\uc744 \ub4e4\uc774\uae30"}),(0,t.jsx)(n.br,{}),"\n","\uc720\ube44\ucffc\ud130\uc2a4 \uc5b8\uc5b4\ub97c \uc815\ud558\ub294\ub370 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \ub4e4\uc5ec\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc0ac\ub2e4\ub9ac \ud0c0\uae30\uc758 \uc2e4\ud589 \uacb0\uacfc\ub97c Item\uc73c\ub85c \uc9d3\ub2e4\ub2c8.. \ubb54\uac00 \ub9cc\uc871\uc2a4\ub7fd\uc9c0 \uc54a\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\uc804 \ubbf8\uc158\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c, \uba85\uba85\ud558\ub294 \ubd80\ubd84\uc5d0\uc11c \ubd80\uc871\ud568\uc744 \ub9ce\uc774 \ub290\uaf08\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\ud398\uc5b4\uc640 \uc870\uae08 \ub354 \uce5c\ud574\uc9c0\uae30"}),(0,t.jsx)(n.br,{}),"\n","\uccab\ub0a0\uc740 \ud398\uc5b4\uc640 \uce5c\ud574\uc9c0\ub294 \uc2dc\uac04\uc744 \uc870\uae08 \ub354 \uac00\uc838\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6b0\uac00\ub791 \ud68c\uace0\ud560 \ub54c \ub0b4\uac00 \uc2dc\uc791\ud558\uc790\ub9c8\uc790 \ucee8\ubca4\uc158 \uc815\ud558\uc790\uace0 \ud574\uc11c \ub9ce\uc774 \ub2f9\ud669\uc2a4\ub7ec\uc6e0\ub2e4\uace0 \ud55c\ub2e4. \uc6b0\uac00 \ubbf8\uc548.. \ud83e\udd72"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"README\ub97c \uc870\uae08 \ub354 \uaf3c\uaf3c\ud558\uac8c"}),(0,t.jsx)(n.br,{}),"\n","\uc774\uc0c1\ud558\uac8c \ucf54\ub529\uc5d0 \uc9d1\uc911\ud558\uba74 README\ub97c \uc5c5\ub370\uc774\ud2b8\ud558\uba74\uc11c \uac19\uc774 \ucee4\ubc0b \ud558\ub294 \uac78 \ud56d\uc0c1 \uae4c\uba39\ub294\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub2e4\uc74c \ubbf8\uc158\uc5d0\ub294 \uc870\uae08 \ub354 \uc2e0\uacbd \uc368\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uc88b\uc740 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud558\uae30"}),(0,t.jsx)(n.br,{}),"\n","\uccab PR\ub54c \ub9ac\ubdf0\uc5b4\uc5d0\uac8c \uc9c8\ubb38\uc744 \ub0a8\uae30\uc9c0 \ubabb\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub9ac\ubdf0\uc5b4\uc640\uc758 \uc2dc\uac04\uc774 \uc18c\uc911\ud55c \uc2dc\uac04\uc774\ub77c\ub294 \uac83\uc744 \uae4c\uba39\uc9c0 \ub9d0\uace0, \ub098\uc758 \uc131\uc7a5\uc5d0 \ub3c4\uc6c0\uc774 \ub420 \uc218 \uc788\ub294 \uc9c8\ubb38\uc744 \uc0dd\uac01\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"PR \ud6c4\uc5d0\ub3c4 \uaf3c\uaf3c\ud558\uac8c \ud655\uc778\ud558\uae30"}),(0,t.jsx)(n.br,{}),"\n","\ubd84\uba85 \uc54c\uace0 \uc788\ub294 \ubd80\ubd84\uc774\uc9c0\ub9cc, \ub193\uce5c \ubd80\ubd84\uc774 \ub9ce\uc740 \uac83 \uac19\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","PR \ud558\uae30 \uc804\uc5d0\ub3c4 \uacc4\uc18d \ud655\uc778\uc744 \ud588\uc9c0\ub9cc, \uc544\ubb34\ub798\ub3c4 IntelliJ\uc5d0\uc11c \ubcf4\ub2c8 \ucf54\ub4dc\uc5d0 \uc775\uc219\ud574\uc838\uc11c \uadf8\ub7f0\uc9c0 \ubcc0\uacbd\ud574\uc57c \ud560 \ubd80\ubd84\uc774 \uc798 \uc548\ubcf4\uc600\ub2e4.",(0,t.jsx)(n.br,{}),"\n","github pr\uc5d0\uc11c\ub294 \uc804\uccb4 \ubcc0\uacbd\uc0ac\ud56d\uc744 \ud655\uc778\ud560 \uc218 \uc788\uc73c\ub2c8 PR \ud6c4\uc5d0\ub3c4 \uaf2d \ud655\uc778\ud574\uc57c\uaca0\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uc801\uadf9\uc801\uc73c\ub85c \ub098\uc758 \uc758\uacac\uc744 \ub9d0\ud558\uae30"}),(0,t.jsx)(n.br,{}),"\n","\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\ub294 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \ud398\uc5b4\uc758 \uc758\uacac\uc774 \uad1c\ucc2e\ub2e4\uace0 \uc0dd\uac01\ud558\uba74 \uc218\uc6a9 \ud6c4 \uac1c\uc120\uc744 \ud558\ub294 \ubc29\ud5a5\uc73c\ub85c \uc9c4\ud589\uc744 \ud588\uc5c8\ub294\ub370, \uc870\uae08 \ub354 \uac1c\uc120\ud560 \uc218 \uc788\ub294 \ubc29\ud5a5\uc774 \uc788\ub2e4\uba74 \ub098\ub3c4 \uc801\uadf9\uc801\uc73c\ub85c \uc758\uacac\uc744 \ub9d0\ud574\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\uc774 \ub4e0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub098\ub3c4 \uc124\ub4dd\ud558\ub294 \ud798\uc744 \uae30\ub974\uace0, \ud398\uc5b4\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc744 \uc54c \uc218 \uc788\uace0, \uacb0\uacfc\ubb3c\ub3c4 \uc88b\uc740 \ubc29\ud5a5\uc73c\ub85c \ub098\uc624\uc9c0 \uc54a\uc744\uae4c? (\uace0\ubbfc \ub4e4\uc5b4\uc8fc\uc2e0 \ub9ac\ubdf0\uc5b4 \ud130\ud2c0\ud83d\udc22 \uac10\uc0ac\ud569\ub2c8\ub2e4.)"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc0c8\ub85c-\ud559\uc2b5\ud55c-\ubd80\ubd84",children:"\uc0c8\ub85c \ud559\uc2b5\ud55c \ubd80\ubd84"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784"}),(0,t.jsx)(n.br,{}),"\n","Players\uac00 Position\uc744 \uc0dd\uc131\ud558\uace0 Player\uc758 \uc0dd\uc131\uc790\uc5d0 \ub123\uc5b4\uc8fc\uc5c8\ub2e4. \ud558\uc9c0\ub9cc \uc774 \ubd80\ubd84\uc5d0 \ub300\ud574\uc11c \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ub828\ub41c \ucf54\uba58\ud2b8\uac00 \ub2ec\ub838\ub2e4.\n\uc2dc\uac04\uc744 \uac00\uc9c0\uace0 \uc0dd\uac01\ud574 \ubcf4\ub2c8 Position\uc744 \uac00\uc9c0\uace0 \uc788\ub294 \uac74 Player\uae30 \ub54c\ubb38\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 Player\uac00 \ub2f4\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4."]}),"\n",(0,t.jsx)(n.p,{children:"\uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud55c \ud328\ud134\uc73c\ub85c GRASP\uc758 Creator \ud328\ud134\uc774 \uc788\ub294\ub370 \ub2e4\uc74c\uc758 \uc694\uc18c\ub97c \ucd5c\ub300\ud55c \ub9cc\uc871\ud558\ub294 \ud074\ub798\uc2a4\uc5d0 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uac83\uc774 \uc88b\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"B\uac00 A\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.li,{children:"B\uac00 A\uc758 \ucd08\uae43\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\uc2e4\uc81c\ub85c \uac1d\uccb4\uc758 \uc0dd\uc131 \ucc45\uc784\uc5d0 \uad00\ud574\uc11c \uae4a\uc774 \uc0dd\uac01\ud558\uba74\uc11c \ucf54\ub529\uc744 \ud558\uc9c0 \uc54a\uc558\ub294\ub370, \uc774\ubc88 \ubbf8\uc158\uc744 \ud1b5\ud574 \uc2dc\uc57c\uac00 \ub113\uc5b4\uc9c4 \uac83 \uac19\ub2e4."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\ud328\ud0a4\uc9c0 \ubd84\ub9ac \uae30\uc900"}),(0,t.jsx)(n.br,{}),"\n","\ud328\ud0a4\uc9c0 \ubd84\ub9ac\uc5d0 \ub300\ud55c \ub098\ub9cc\uc758 \uae30\uc900\uc774 \uc544\uc9c1 \uba85\ud655\ud558\uc9c0 \uc54a\uc544 \uc9c8\ubb38\uc774 \ub4e4\uc5b4\uc640\ub3c4 \uba85\ud655\ud558\uac8c \ub2f5\ubcc0\uc744 \ud558\uc9c0 \ubabb\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub9c8\uc9c0\ub9c9 \uc81c\ucd9c \uc804\uc5d0 \ub3c4\uba54\uc778 \ud328\ud0a4\uc9c0 \ub0b4\ubd80\ub97c \ubd84\ub9ac\ud574 \ubd24\ub294\ub370, \uae30\uc900\uc774 \uba85\ud655\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \uc88b\uc9c0 \uc54a\uc740 \uc120\ud0dd\uc774\uc5c8\ub358 \uac83 \uac19\ub2e4.\n\ud604\uc7ac \uc9c4\ud589\ud558\ub294 \ubbf8\uc158\uc758 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ud06c\uae30\uac00 \uadf8\ub807\uac8c \ud06c\uc9c0 \uc54a\uc73c\ub2c8, domain \ud328\ud0a4\uc9c0\uc5d0\uc11c \uc138\ubd80 \ud328\ud0a4\uc9c0\ub85c \ubd84\ub9ac\ud558\uc9c0 \uc54a\uc544\ub3c4 \ub420 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"\uc0ac\uc6a9\ud558\ub294 \ucabd\uc5d0\uc11c \uc0dd\uac01\ud558\uae30 & \uc608\uce21\uac00\ub2a5\ud55c \ucf54\ub4dc \uc791\uc131\ud558\uae30"}),(0,t.jsx)(n.br,{}),"\n","Position\uc5d0\uc11c \ub2e4\uc74c \uc704\uce58\ub098 \uc774\uc804 \uc704\uce58\ub97c \ubc18\ud658\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ud5c8\uc6a9 \ubc94\uc704(0",(0,t.jsxs)(n.del,{children:["19)\uac00 \ubc97\uc5b4\ub09c\ub2e4\uba74, \uc758\ubbf8 \uc5c6\ub294 \uac12\uc774 \ub4e4\uc5b4\uac04 Position\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\uac74 Position\uc744 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc744 \uace0\ub824\ud558\uc9c0 \ubabb\ud55c \ucf54\ub529\uc774\uc5c8\ub294\ub370, \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 0"]}),"19\uc758 \uac12\uc774 \ubcf4\uc7a5\ub418\uc5b4 \uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uac83\uc774\uae30 \ub54c\ubb38\uc774\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c hasNext, hasPrevious\ub77c\ub294 \uc774\uc804 \uac12, \uc774\ud6c4 \uac12\uc774 \ubc94\uc704 \ub0b4\uc5d0 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \uba54\uc11c\ub4dc\ub97c \ucd94\uac00\ud558\uace0, \uae30\uc874\uc758 \uac12\uc744 \uac00\uc838\uc624\ub294 \uba54\uc11c\ub4dc\ub294 \ubc94\uc704\uac00 \ubc97\uc5b4\ub098\uba74 \uc608\uc678\ub97c \ub358\uc9c0\ub294 \ubc29\ud5a5\uc73c\ub85c \ud574\uacb0\ud558\uc600\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ud398\uc5b4\uc5d0\uac8c-\ubc30\uc6b8-\ubd80\ubd84",children:"\ud398\uc5b4\uc5d0\uac8c \ubc30\uc6b8 \ubd80\ubd84"}),"\n",(0,t.jsxs)(n.p,{children:["\ubc1d\uc740 \uae30\uc6b4\uc744 \uac00\uc9c0\uace0 \uc788\uace0 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \uce5c\ud654\ub825\uc774 \uc88b\uc740 \uac83 \uac19\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774\ubc88\uc5d0 \ud398\uc5b4 \ud560 \ub54c \ucee8\ub514\uc158 \uad00\ub9ac\ub97c \uc81c\ub300\ub85c \ubabb\ud574\uc11c \ub9ce\uc774 \ubbf8\uc548\ud588\ub2e4. \ub2e4\uc74c\uc5d0\ub294 \ucd5c\uc0c1\uc758 \ucee8\ub514\uc158\uc73c\ub85c \ud398\uc5b4\ub97c \uc900\ube44\ud574 \ubd10\uc57c\uaca0\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uadf8\ub9ac\uace0 \uc6b0\uac00\ub791 \ud398\uc5b4\ub97c \ud558\uace0 \ub098\uc11c, \ub098\ub3c4 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uacfc \ub354 \uc798 \uc9c0\ub0b4\ubd10\uc57c\uaca0\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5b4 \uc870\uae08 \ub354 \uc6a9\uae30\ub97c \ub0b4 \uc7a1\ub2f4 \uc911\uc774\ub2e4!"]}),"\n",(0,t.jsxs)(n.p,{children:["\uc758\uacac\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ub0b4\uc918\uc11c \ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589\uc774 \uc798 \ub418\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub610\ud55c \ud398\uc5b4 \uc9c4\ud589\uc774 \ub290\ub9b0 \uac83 \uac19\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c \uc548\uc815\uc801\uc73c\ub85c \uc2dc\uac04 \uc548\uc5d0 \ubbf8\uc158\uc744 \uc644\ub8cc\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud398\uc5b4\ud504\ub85c\uadf8\ub798\ubc0d \uc9c4\ud589 \uc18d\ub3c4\uc5d0 \ub300\ud574 \uc870\uae08 \ub354 \uc0dd\uac01\uc744 \ud574\ubd10\uc57c\uaca0\ub2e4!"]}),"\n",(0,t.jsxs)(n.p,{children:["\ud56d\uc0c1 \uc9c0\ub098\uac08 \ub54c\ub9c8\ub2e4 \uc6c3\uc5b4\uc8fc\ub294\ub370, \ub098\ub3c4 \uc790\uc8fc \uc6c3\uc5b4\uc57c\uaca0\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc6c3\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uc0ac\ub78c\uc774 \ubc1d\uc544 \ubcf4\uc5ec\uc11c \ub108\ubb34 \uc88b\uc740 \uac83 \uac19\ub2e4!"]})]})}function x(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>d});var t=r(67294);function a(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?s(Object(r),!0).forEach((function(n){a(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function l(e,n){if(null==e)return{};var r,t,a=function(e,n){if(null==e)return{};var r,t,a={},s=Object.keys(e);for(t=0;t<s.length;t++)r=s[t],n.indexOf(r)>=0||(a[r]=e[r]);return a}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(t=0;t<s.length;t++)r=s[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var o=t.createContext({}),d=function(e){var n=t.useContext(o),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},c={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},x=t.forwardRef((function(e,n){var r=e.components,a=e.mdxType,s=e.originalType,o=e.parentName,x=l(e,["components","mdxType","originalType","parentName"]),p=d(r),u=a,j=p["".concat(o,".").concat(u)]||p[u]||c[u]||s;return r?t.createElement(j,i(i({ref:n},x),{},{components:r})):t.createElement(j,i({ref:n},x))}));x.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/df203c0f.3bef6881.js b/assets/js/df203c0f.3bef6881.js new file mode 100644 index 000000000..73195900e --- /dev/null +++ b/assets/js/df203c0f.3bef6881.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9924],{59047:(e,n,t)=>{t.d(n,{Z:()=>M});var i=t(67294),s=t(85893);function o(e){const{mdxAdmonitionTitle:n,rest:t}=function(e){const n=i.Children.toArray(e),t=n.find((e=>i.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),o=n.filter((e=>e!==t)),l=t?.props.children;return{mdxAdmonitionTitle:l,rest:o.length>0?(0,s.jsx)(s.Fragment,{children:o}):null}}(e.children),o=e.title??n;return{...e,...o&&{title:o},children:t}}var l=t(86010),a=t(95999),r=t(35281);const c={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function d(e){let{type:n,className:t,children:i}=e;return(0,s.jsx)("div",{className:(0,l.Z)(r.k.common.admonition,r.k.common.admonitionType(n),c.admonition,t),children:i})}function u(e){let{icon:n,title:t}=e;return(0,s.jsxs)("div",{className:c.admonitionHeading,children:[(0,s.jsx)("span",{className:c.admonitionIcon,children:n}),t]})}function h(e){let{children:n}=e;return n?(0,s.jsx)("div",{className:c.admonitionContent,children:n}):null}function m(e){const{type:n,icon:t,title:i,children:o,className:l}=e;return(0,s.jsxs)(d,{type:n,className:l,children:[(0,s.jsx)(u,{title:i,icon:t}),(0,s.jsx)(h,{children:o})]})}function g(e){return(0,s.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const x={icon:(0,s.jsx)(g,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function f(e){return(0,s.jsx)(m,{...x,...e,className:(0,l.Z)("alert alert--secondary",e.className),children:e.children})}function j(e){return(0,s.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const p={icon:(0,s.jsx)(j,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function v(e){return(0,s.jsx)(m,{...p,...e,className:(0,l.Z)("alert alert--success",e.className),children:e.children})}function N(e){return(0,s.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const Z={icon:(0,s.jsx)(N,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function w(e){return(0,s.jsx)(m,{...Z,...e,className:(0,l.Z)("alert alert--info",e.className),children:e.children})}function T(e){return(0,s.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const b={icon:(0,s.jsx)(T,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function y(e){return(0,s.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const z={icon:(0,s.jsx)(y,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const C={icon:(0,s.jsx)(T,{}),title:(0,s.jsx)(a.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const k={...{note:f,tip:v,info:w,warning:function(e){return(0,s.jsx)(m,{...b,...e,className:(0,l.Z)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,s.jsx)(m,{...z,...e,className:(0,l.Z)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,s.jsx)(f,{title:"secondary",...e}),important:e=>(0,s.jsx)(w,{title:"important",...e}),success:e=>(0,s.jsx)(v,{title:"success",...e}),caution:function(e){return(0,s.jsx)(m,{...C,...e,className:(0,l.Z)("alert alert--warning",e.className),children:e.children})}}};function M(e){const n=o(e),t=(i=n.type,k[i]||(console.warn(`No admonition component found for admonition type "${i}". Using Info as fallback.`),k.info));var i;return(0,s.jsx)(t,{...n})}},40491:(e,n,t)=>{t.r(n),t.d(n,{default:()=>j});t(67294);var i=t(86010),s=t(39960),o=t(88824),l=t(10833),a=t(35281),r=t(95999),c=t(90197),d=t(22212),u=t(92503),h=t(85893);function m(e){const n=function(){const{selectMessage:e}=(0,o.c)();return n=>e(n,(0,r.I)({id:"theme.docs.tagDocListPageTitle.nDocsTagged",description:'Pluralized label for "{count} docs tagged". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One doc tagged|{count} docs tagged"},{count:n}))}();return(0,r.I)({id:"theme.docs.tagDocListPageTitle",description:"The title of the page for a docs tag",message:'{nDocsTagged} with "{tagName}"'},{nDocsTagged:n(e.tag.count),tagName:e.tag.label})}function g(e){let{doc:n}=e;return(0,h.jsxs)("article",{className:"margin-vert--lg",children:[(0,h.jsx)(s.Z,{to:n.permalink,children:(0,h.jsx)(u.Z,{as:"h2",children:n.title})}),n.description&&(0,h.jsx)("p",{children:n.description})]})}function x(e){let{title:n}=e;return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(l.d,{title:n}),(0,h.jsx)(c.Z,{tag:"doc_tag_doc_list"})]})}function f(e){let{tag:n,title:t}=e;return(0,h.jsx)(l.FG,{className:(0,i.Z)(a.k.page.docsTagDocListPage),children:(0,h.jsx)("div",{className:"container margin-vert--lg",children:(0,h.jsx)("div",{className:"row",children:(0,h.jsxs)("main",{className:"col col--8 col--offset-2",children:[n.unlisted&&(0,h.jsx)(d.Z,{}),(0,h.jsxs)("header",{className:"margin-bottom--xl",children:[(0,h.jsx)(u.Z,{as:"h1",children:t}),(0,h.jsx)(s.Z,{href:n.allTagsPath,children:(0,h.jsx)(r.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,h.jsx)("section",{className:"margin-vert--lg",children:n.items.map((e=>(0,h.jsx)(g,{doc:e},e.id)))})]})})})})}function j(e){const n=m(e);return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(x,{...e,title:n}),(0,h.jsx)(f,{...e,title:n})]})}},22212:(e,n,t)=>{t.d(n,{Z:()=>m});t(67294);var i=t(86010),s=t(95999),o=t(35742),l=t(85893);function a(){return(0,l.jsx)(s.Z,{id:"theme.unlistedContent.title",description:"The unlisted content banner title",children:"Unlisted page"})}function r(){return(0,l.jsx)(s.Z,{id:"theme.unlistedContent.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function c(){return(0,l.jsx)(o.Z,{children:(0,l.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}var d=t(35281),u=t(59047);function h(e){let{className:n}=e;return(0,l.jsx)(u.Z,{type:"caution",title:(0,l.jsx)(a,{}),className:(0,i.Z)(n,d.k.common.unlistedBanner),children:(0,l.jsx)(r,{})})}function m(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(c,{}),(0,l.jsx)(h,{...e})]})}},88824:(e,n,t)=>{t.d(n,{c:()=>c});var i=t(67294),s=t(52263);const o=["zero","one","two","few","many","other"];function l(e){return o.filter((n=>e.includes(n)))}const a={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function r(){const{i18n:{currentLocale:e}}=(0,s.Z)();return(0,i.useMemo)((()=>{try{return function(e){const n=new Intl.PluralRules(e);return{locale:e,pluralForms:l(n.resolvedOptions().pluralCategories),select:e=>n.select(e)}}(e)}catch(n){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${n.message}\n`),a}}),[e])}function c(){const e=r();return{selectMessage:(n,t)=>function(e,n,t){const i=e.split("|");if(1===i.length)return i[0];i.length>t.pluralForms.length&&console.error(`For locale=${t.locale}, a maximum of ${t.pluralForms.length} plural forms are expected (${t.pluralForms.join(",")}), but the message contains ${i.length}: ${e}`);const s=t.select(n),o=t.pluralForms.indexOf(s);return i[Math.min(o,i.length-1)]}(t,n,e)}}}}]); \ No newline at end of file diff --git a/assets/js/df203c0f.c891d774.js b/assets/js/df203c0f.c891d774.js deleted file mode 100644 index 17f7d2b10..000000000 --- a/assets/js/df203c0f.c891d774.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9924],{40491:(e,t,l)=>{l.r(t),l.d(t,{default:()=>d});var a=l(67294),n=l(86010),r=l(39960),s=l(88824),c=l(10833),o=l(35281),i=l(95999),u=l(7452),m=l(90197);function g(e){let{doc:t}=e;return a.createElement("article",{className:"margin-vert--lg"},a.createElement(r.Z,{to:t.permalink},a.createElement("h2",null,t.title)),t.description&&a.createElement("p",null,t.description))}function d(e){let{tag:t}=e;const l=function(){const{selectMessage:e}=(0,s.c)();return t=>e(t,(0,i.I)({id:"theme.docs.tagDocListPageTitle.nDocsTagged",description:'Pluralized label for "{count} docs tagged". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One doc tagged|{count} docs tagged"},{count:t}))}(),d=(0,i.I)({id:"theme.docs.tagDocListPageTitle",description:"The title of the page for a docs tag",message:'{nDocsTagged} with "{tagName}"'},{nDocsTagged:l(t.count),tagName:t.label});return a.createElement(c.FG,{className:(0,n.Z)(o.k.wrapper.docsPages,o.k.page.docsTagDocListPage)},a.createElement(c.d,{title:d}),a.createElement(m.Z,{tag:"doc_tag_doc_list"}),a.createElement(u.Z,null,a.createElement("div",{className:"container margin-vert--lg"},a.createElement("div",{className:"row"},a.createElement("main",{className:"col col--8 col--offset-2"},a.createElement("header",{className:"margin-bottom--xl"},a.createElement("h1",null,d),a.createElement(r.Z,{href:t.allTagsPath},a.createElement(i.Z,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page"},"View All Tags"))),a.createElement("section",{className:"margin-vert--lg"},t.items.map((e=>a.createElement(g,{key:e.id,doc:e})))))))))}},88824:(e,t,l)=>{l.d(t,{c:()=>i});var a=l(67294),n=l(52263);const r=["zero","one","two","few","many","other"];function s(e){return r.filter((t=>e.includes(t)))}const c={locale:"en",pluralForms:s(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,n.Z)();return(0,a.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:s(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),c}}),[e])}function i(){const e=o();return{selectMessage:(t,l)=>function(e,t,l){const a=e.split("|");if(1===a.length)return a[0];a.length>l.pluralForms.length&&console.error(`For locale=${l.locale}, a maximum of ${l.pluralForms.length} plural forms are expected (${l.pluralForms.join(",")}), but the message contains ${a.length}: ${e}`);const n=l.select(t),r=l.pluralForms.indexOf(n);return a[Math.min(r,a.length-1)]}(l,t,e)}}}}]); \ No newline at end of file diff --git a/assets/js/df862072.cebd22e7.js b/assets/js/df862072.8d335144.js similarity index 88% rename from assets/js/df862072.cebd22e7.js rename to assets/js/df862072.8d335144.js index 3e56066c6..7a7a10787 100644 --- a/assets/js/df862072.cebd22e7.js +++ b/assets/js/df862072.8d335144.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7474],{24827:e=>{e.exports=JSON.parse('{"label":"Book","permalink":"/tags/book","allTagsPath":"/tags","count":3}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7474],{24827:e=>{e.exports=JSON.parse('{"label":"Book","permalink":"/tags/book","allTagsPath":"/tags","count":3,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/dfc7013c.e658333c.js b/assets/js/dfc7013c.e658333c.js deleted file mode 100644 index d12f29f48..000000000 --- a/assets/js/dfc7013c.e658333c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5857],{3905:(t,e,a)=>{a.d(e,{Zo:()=>s,kt:()=>k});var n=a(67294);function l(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function r(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function i(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?r(Object(a),!0).forEach((function(e){l(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):r(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function p(t,e){if(null==t)return{};var a,n,l=function(t,e){if(null==t)return{};var a,n,l={},r=Object.keys(t);for(n=0;n<r.length;n++)a=r[n],e.indexOf(a)>=0||(l[a]=t[a]);return l}(t,e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);for(n=0;n<r.length;n++)a=r[n],e.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(l[a]=t[a])}return l}var u=n.createContext({}),m=function(t){var e=n.useContext(u),a=e;return t&&(a="function"==typeof t?t(e):i(i({},e),t)),a},s=function(t){var e=m(t.components);return n.createElement(u.Provider,{value:e},t.children)},o={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},d=n.forwardRef((function(t,e){var a=t.components,l=t.mdxType,r=t.originalType,u=t.parentName,s=p(t,["components","mdxType","originalType","parentName"]),d=m(a),k=l,c=d["".concat(u,".").concat(k)]||d[k]||o[k]||r;return a?n.createElement(c,i(i({ref:e},s),{},{components:a})):n.createElement(c,i({ref:e},s))}));function k(t,e){var a=arguments,l=e&&e.mdxType;if("string"==typeof t||l){var r=a.length,i=new Array(r);i[0]=d;var p={};for(var u in e)hasOwnProperty.call(e,u)&&(p[u]=e[u]);p.originalType=t,p.mdxType="string"==typeof t?t:l,i[1]=p;for(var m=2;m<r;m++)i[m]=a[m];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}d.displayName="MDXCreateElement"},57515:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>u,contentTitle:()=>i,default:()=>o,frontMatter:()=>r,metadata:()=>p,toc:()=>m});var n=a(87462),l=(a(67294),a(3905));const r={title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",slug:"java-class-file",tags:["Java","Class"]},i=void 0,p={permalink:"/java-class-file",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",source:"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",description:"\ud074\ub798\uc2a4 \ud30c\uc77c",date:"2023-04-03T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 3\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Class",permalink:"/tags/class"}],readingTime:5.63,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",slug:"java-class-file",tags:["Java","Class"]},prevItem:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",permalink:"/test-double"},nextItem:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",permalink:"/custom-jdbc-template"}},u={authorsImageUrls:[]},m=[{value:"\ud074\ub798\uc2a4 \ud30c\uc77c",id:"\ud074\ub798\uc2a4-\ud30c\uc77c",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd",id:"\ud074\ub798\uc2a4-\ud30c\uc77c\uc758-\ub370\uc774\ud130-\ud615\uc2dd",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\uad6c\uc870",level:3},{value:"\ub9e4\uc9c1\ub118\ubc84",id:"\ub9e4\uc9c1\ub118\ubc84",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud3ec\ub9f7-\ubc84\uc804",level:3},{value:"\uc0c1\uc218 \ud480",id:"\uc0c1\uc218-\ud480",level:3},{value:"\uc561\uc138\uc2a4 \ud50c\ub798\uadf8",id:"\uc561\uc138\uc2a4-\ud50c\ub798\uadf8",level:3},{value:"this_class",id:"this_class",level:3},{value:"super_class",id:"super_class",level:3},{value:"interface, field, method",id:"interface-field-method",level:3},{value:"attributes",id:"attributes",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud655\uc778\ud558\uba74\uc11c-\uc0ac\uc6a9\ud55c-\ud234",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:m};function o(t){let{components:e,...a}=t;return(0,l.kt)("wrapper",(0,n.Z)({},s,a,{components:e,mdxType:"MDXLayout"}),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c"},"\ud074\ub798\uc2a4 \ud30c\uc77c"),(0,l.kt)("p",null,"\uc790\ubc14 \uc18c\uc2a4\ucf54\ub4dc\uac00 \uc2e4\ud589\uc774 \ub418\ub824\uba74 \uc790\ubc14 \ucef4\ud30c\uc77c\ub7ec(javac)\ub97c \ud1b5\ud574 \uc18c\uc2a4\ucf54\ub4dc\ub97c \ud074\ub798\uc2a4\ud30c\uc77c\ub85c \ubcc0\ud658\ud574\uc57c \ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ucef4\ud30c\uc77c\ub41c \ud074\ub798\uc2a4\ud30c\uc77c\uc740 \uc5b4\ub5a4 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\uc744\uae4c?"),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c\uc758-\ub370\uc774\ud130-\ud615\uc2dd"},"\ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd"),(0,l.kt)("p",null,"8\ube44\ud2b8 \ubc14\uc774\ud2b8\uc758 \uc2a4\ud2b8\ub9bc\uc73c\ub85c \uad6c\uc131\ub41c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","16\ube44\ud2b8 \ubc0f 32\ube44\ud2b8\uc758 \ub370\uc774\ud130\ub294 \uac01\uac01 2\uac1c, 4\uac1c\uc758 \uc5f0\uc18d\ub41c 8\ube44\ud2b8\ub97c \uc77d\uc5b4\uc11c \uad6c\uc131\ub41c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\uba40\ud2f0\ubc14\uc774\ud2b8\uc758 \uacbd\uc6b0 \ud56d\uc0c1 big endian \uc21c\uc11c\ub85c \uc800\uc7a5\ub41c\ub2e4. "),(0,l.kt)("p",null,"u1 \u2192 unsigned 1byte",(0,l.kt)("br",{parentName:"p"}),"\n","u2 \u2192 unsigned 2byte",(0,l.kt)("br",{parentName:"p"}),"\n","u4 \u2192 unsigned 4byte "),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\uad6c\uc870"},"\ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre"},"ClassFile {\n u4 magic;\n u2 minor_version;\n u2 major_version;\n u2 constant_pool_count;\n cp_info constant_pool[constant_pool_count-1];\n u2 access_flags;\n u2 this_class;\n u2 super_class;\n u2 interfaces_count;\n u2 interfaces[interfaces_count];\n u2 fields_count;\n field_info fields[fields_count];\n u2 methods_count;\n method_info methods[methods_count];\n u2 attributes_count;\n attribute_info attributes[attributes_count];\n}\n")),(0,l.kt)("h3",{id:"\ub9e4\uc9c1\ub118\ubc84"},"\ub9e4\uc9c1\ub118\ubc84"),(0,l.kt)("p",null,"\ubaa8\ub4e0 \ud074\ub798\uc2a4 \ud30c\uc77c\uc740 0xCAFEBABE\ub77c\ub294 \ub9e4\uc9c1\ub118\ubc84\ub85c \uc2dc\uc791\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ubcf4\ud1b5 \ub9e4\uc9c1\ub118\ubc84\ub294 \ud30c\uc77c \uc885\ub958\ub97c \uc2dd\ubcc4\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9\ub41c\ub2e4. "),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud3ec\ub9f7-\ubc84\uc804"},"\ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804"),(0,l.kt)("p",null,"\ud074\ub798\uc2a4 \ud30c\uc77c \ubc84\uc804 \uac12\uc740 \ud074\ub798\uc2a4\ub85c\ub354\uc758 \ud638\ud658\uc131 \ubcf4\uc7a5\uc744 \uc704\ud574 \uaf2d \ud544\uc694\ud55c \uac12\uc774\ub2e4. "),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"Java 17 \ubc84\uc804\uc73c\ub85c \ube4c\ub4dc\ud55c\ub2e4\uba74 class version 61 ex) 00 00 00 3D")),(0,l.kt)("p",null,"\ud638\ud658\ub418\uc9c0 \uc54a\ub294 \ubc84\uc804\uc758 \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \ub85c\ub529\ud558\ub824\uace0 \ud558\ub294 \uacbd\uc6b0 \ub7f0\ud0c0\uc784\uc5d0 ",(0,l.kt)("inlineCode",{parentName:"p"},"UnsupportedClassVersionError")," \uc608\uc678\uac00 \ubc1c\uc0dd\ud55c\ub2e4. "),(0,l.kt)("p",null,(0,l.kt)("strong",{parentName:"p"},"class\xa0file format major versions")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Java SE"),(0,l.kt)("th",{parentName:"tr",align:null},"Released"),(0,l.kt)("th",{parentName:"tr",align:null},"Major"),(0,l.kt)("th",{parentName:"tr",align:null},"Supported majors"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"8"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2014"),(0,l.kt)("td",{parentName:"tr",align:null},"52"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 52")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"9"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2017"),(0,l.kt)("td",{parentName:"tr",align:null},"53"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 53")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"10"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2018"),(0,l.kt)("td",{parentName:"tr",align:null},"54"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 54")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"11"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2018"),(0,l.kt)("td",{parentName:"tr",align:null},"55"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 55")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"12"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2019"),(0,l.kt)("td",{parentName:"tr",align:null},"56"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 56")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"13"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2019"),(0,l.kt)("td",{parentName:"tr",align:null},"57"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 57")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"14"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2020"),(0,l.kt)("td",{parentName:"tr",align:null},"58"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 58")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"15"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2020"),(0,l.kt)("td",{parentName:"tr",align:null},"59"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 59")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"16"),(0,l.kt)("td",{parentName:"tr",align:null},"March 2021"),(0,l.kt)("td",{parentName:"tr",align:null},"60"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 60")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"17"),(0,l.kt)("td",{parentName:"tr",align:null},"September 2021"),(0,l.kt)("td",{parentName:"tr",align:null},"61"),(0,l.kt)("td",{parentName:"tr",align:null},"45 .. 61")))),(0,l.kt)("h3",{id:"\uc0c1\uc218-\ud480"},"\uc0c1\uc218 \ud480"),(0,l.kt)("p",null,"2\ubc14\uc774\ud2b8\uc758 \uc0c1\uc218\uc758 \uac1c\uc218\uac12\uc774 \uba3c\uc800\uc624\uace0 \uadf8 \ub4a4\ub85c \ucf54\ub4dc\uc5d0 \ub4f1\uc7a5\ud558\ub294 \uc0c1\uc218\uac12\uc774 \ubaa8\uc5ec\uc788\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ud074\ub798\uc2a4\uba85, \uc0c1\uc218\uba85, \uc0c1\uc218 \uac12, \ud544\ub4dc\uba85, \uba54\uc11c\ub4dc\uba85\uacfc \uac19\uc740 \uac12\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","JVM\uc740 \ucf54\ub4dc \uc2e4\ud589 \uc2dc \ub7f0\ud0c0\uc784\uc5d0 \ubc30\uce58\ub41c \uba54\ubaa8\ub9ac\uac00 \uc544\ub2c8\ub77c, \ud574\ub2f9 \uc0c1\uc218 \ud480 \ud14c\uc774\ube14\uc744 \ucc3e\uc544\ubcf4\uace0 \ud544\uc694\ud55c \uac12\uc744 \ucc38\uc870\ud55c\ub2e4."),(0,l.kt)("h3",{id:"\uc561\uc138\uc2a4-\ud50c\ub798\uadf8"},"\uc561\uc138\uc2a4 \ud50c\ub798\uadf8"),(0,l.kt)("p",null,"\ud074\ub798\uc2a4, \uc778\ud130\ud398\uc774\uc2a4\uc640 \uac19\uc740 \ud30c\uc77c\uc758 \uc18d\uc131\uc744 \ud45c\uc2dc\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\uc608\ub97c \ub4e4\uc5b4 public interface\ub85c \uc815\uc758\ub41c \uc778\ud130\ud398\uc774\uc2a4\uc758 \ud50c\ub798\uadf8\ub294 0x0601\uc774\ub2e4. "),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uacc4\uc0b0\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. ",(0,l.kt)("inlineCode",{parentName:"li"},"ACC_PUBLIC")," xor ",(0,l.kt)("inlineCode",{parentName:"li"},"ACC_INTERFACE")," xor ",(0,l.kt)("inlineCode",{parentName:"li"},"ACC_ABSTRACT"))),(0,l.kt)("p",null,"\uacf5\uc2dd\ubb38\uc11c\uc5d0 \ub4e4\uc5b4\uac00\uba74 \uac01 \ud50c\ub798\uadf8\uc5d0 \ub300\ud55c \uc124\uba85 + \ud50c\ub798\uadf8 \uc124\uc815\uc2dc \ub3d9\uc2dc\uc5d0 \uc124\uc815\ub418\uba74 \uc548\ub418\ub294 \ud50c\ub798\uadf8\uc640 \uac19\uc740 \uc124\uba85\uc774 \uc790\uc138\ud558\uac8c \ub098\uc640\uc788\ub2e4."),(0,l.kt)("p",null,(0,l.kt)("strong",{parentName:"p"},"Class access and property modifiers")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Flag Name"),(0,l.kt)("th",{parentName:"tr",align:null},"Value"),(0,l.kt)("th",{parentName:"tr",align:null},"Interpretation"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_PUBLIC"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0001"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared\xa0public; may be accessed from outside its package.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_FINAL"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0010"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared\xa0final; no subclasses allowed.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_SUPER"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0020"),(0,l.kt)("td",{parentName:"tr",align:null},"Treat superclass methods specially when invoked by the\xa0invokespecial\xa0instruction.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_INTERFACE"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0200"),(0,l.kt)("td",{parentName:"tr",align:null},"Is an interface, not a class.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_ABSTRACT"),(0,l.kt)("td",{parentName:"tr",align:null},"0x0400"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared\xa0abstract; must not be instantiated.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_SYNTHETIC"),(0,l.kt)("td",{parentName:"tr",align:null},"0x1000"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared synthetic; not present in the source code.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_ANNOTATION"),(0,l.kt)("td",{parentName:"tr",align:null},"0x2000"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared as an annotation type.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_ENUM"),(0,l.kt)("td",{parentName:"tr",align:null},"0x4000"),(0,l.kt)("td",{parentName:"tr",align:null},"Declared as an\xa0enum\xa0type.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"ACC_MODULE"),(0,l.kt)("td",{parentName:"tr",align:null},"0x8000"),(0,l.kt)("td",{parentName:"tr",align:null},"Is a module, not a class or interface.")))),(0,l.kt)("h3",{id:"this_class"},"this_class"),(0,l.kt)("p",null,"\ud074\ub798\uc2a4\uba85\uacfc \uac19\uc740 \uc774\ub984\uc744 \ud45c\ud604\ud558\ub294 \uac12\uc73c\ub85c, \uc0c1\uc218 \ud480\uc5d0\uc11c \ud074\ub798\uc2a4\uba85\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ud574\ub2f9 \uc778\ub371\uc2a4\uc758 \ud56d\ubaa9\uc740 ",(0,l.kt)("inlineCode",{parentName:"p"},"CONSTANT_Class_infoclass")," \ud615\uc2dd\uc758 \uac12\uc774\uc5b4\uc57c \ud55c\ub2e4. "),(0,l.kt)("h3",{id:"super_class"},"super_class"),(0,l.kt)("p",null,"\uc0c1\uc218 \ud480\uc5d0\uc11c \uc288\ud37c \ud074\ub798\uc2a4\uc758 \uc774\ub984\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\uc544\ubb34\uac83\ub3c4 \uc0c1\uc18d\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\uc758 \uacbd\uc6b0 ",(0,l.kt)("inlineCode",{parentName:"p"},"java.lang.Object"),"\uc758 \uc778\ub371\uc2a4 \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4."),(0,l.kt)("h3",{id:"interface-field-method"},"interface, field, method"),(0,l.kt)("p",null,"\uac01\uac01\uc758 \uac1c\uc218\uc640, \uc815\ubcf4\uc5d0 \ub300\ud55c \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","interface, field, method\ub97c \ud45c\uc2dc\ud558\ub294 \ubc29\ubc95\uc774 \uac01\uac01 \ub2e4\ub974\uace0, \uc811\uadfc\uc790\uc5d0 \ub300\ud55c \ud50c\ub798\uadf8\ub3c4 \uac01\uac01 \ub2e4\ub974\ub2e4."),(0,l.kt)("h3",{id:"attributes"},"attributes"),(0,l.kt)("p",null,"\ud574\ub2f9 \ud074\ub798\uc2a4 \ud30c\uc77c\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucd94\uac00 \uc815\ubcf4\uc758 \ubaa8\uc74c\uc774\ub2e4. \uc608) \uc18c\uc2a4\ud30c\uc77c\uba85",(0,l.kt)("br",{parentName:"p"}),"\n","\uc815\ud574\uc9c4 \ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \uad6c\uc870\ub97c \ud655\uc7a5\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4. "),(0,l.kt)("h3",{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud655\uc778\ud558\uba74\uc11c-\uc0ac\uc6a9\ud55c-\ud234"},"\ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234"),(0,l.kt)("p",null,"IntelliJ plugin - BinEd",(0,l.kt)("br",{parentName:"p"}),"\n","IntelliJ plugin - jclasslib Bytecode Viewer"),(0,l.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,l.kt)("p",null,"2\uc7a5 JVM \uc774\uc57c\uae30, \uc790\ubc14 \ucd5c\uc801\ud654",(0,l.kt)("br",{parentName:"p"}),"\n",(0,l.kt)("a",{parentName:"p",href:"https://docs.fileformat.com/ko/programming/class/"},"Class file in Java, File Format"),(0,l.kt)("br",{parentName:"p"}),"\n",(0,l.kt)("a",{parentName:"p",href:"https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html"},"java se11 Class \ud30c\uc77c \ud615\uc2dd, Oracle"),(0,l.kt)("br",{parentName:"p"}),"\n",(0,l.kt)("a",{parentName:"p",href:"https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html"},"java se17 Class \ud30c\uc77c \ud615\uc2dd, Oracle")))}o.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dfc7013c.f3d89c0c.js b/assets/js/dfc7013c.f3d89c0c.js new file mode 100644 index 000000000..4f4c4e348 --- /dev/null +++ b/assets/js/dfc7013c.f3d89c0c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5857],{10032:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>c,contentTitle:()=>d,default:()=>j,frontMatter:()=>l,metadata:()=>i,toc:()=>a});var r=n(85893),t=n(3905);const l={title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",slug:"java-class-file",tags:["Java","Class"]},d=void 0,i={permalink:"/java-class-file",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",source:"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",description:"\ud074\ub798\uc2a4 \ud30c\uc77c",date:"2023-04-03T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 3\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Class",permalink:"/tags/class"}],readingTime:5.63,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ubc14 \ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",slug:"java-class-file",tags:["Java","Class"]},unlisted:!1,prevItem:{title:"\ud14c\uc2a4\ud2b8 \ub300\uc5ed",permalink:"/test-double"},nextItem:{title:"\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30",permalink:"/custom-jdbc-template"}},c={authorsImageUrls:[]},a=[{value:"\ud074\ub798\uc2a4 \ud30c\uc77c",id:"\ud074\ub798\uc2a4-\ud30c\uc77c",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd",id:"\ud074\ub798\uc2a4-\ud30c\uc77c\uc758-\ub370\uc774\ud130-\ud615\uc2dd",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\uad6c\uc870",level:3},{value:"\ub9e4\uc9c1\ub118\ubc84",id:"\ub9e4\uc9c1\ub118\ubc84",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud3ec\ub9f7-\ubc84\uc804",level:3},{value:"\uc0c1\uc218 \ud480",id:"\uc0c1\uc218-\ud480",level:3},{value:"\uc561\uc138\uc2a4 \ud50c\ub798\uadf8",id:"\uc561\uc138\uc2a4-\ud50c\ub798\uadf8",level:3},{value:"this_class",id:"this_class",level:3},{value:"super_class",id:"super_class",level:3},{value:"interface, field, method",id:"interface-field-method",level:3},{value:"attributes",id:"attributes",level:3},{value:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234",id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud655\uc778\ud558\uba74\uc11c-\uc0ac\uc6a9\ud55c-\ud234",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function h(e){const s={a:"a",br:"br",code:"code",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c",children:"\ud074\ub798\uc2a4 \ud30c\uc77c"}),"\n",(0,r.jsxs)(s.p,{children:["\uc790\ubc14 \uc18c\uc2a4\ucf54\ub4dc\uac00 \uc2e4\ud589\uc774 \ub418\ub824\uba74 \uc790\ubc14 \ucef4\ud30c\uc77c\ub7ec(javac)\ub97c \ud1b5\ud574 \uc18c\uc2a4\ucf54\ub4dc\ub97c \ud074\ub798\uc2a4\ud30c\uc77c\ub85c \ubcc0\ud658\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\ucef4\ud30c\uc77c\ub41c \ud074\ub798\uc2a4\ud30c\uc77c\uc740 \uc5b4\ub5a4 \uad6c\uc870\ub85c \ub418\uc5b4\uc788\uc744\uae4c?"]}),"\n",(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c\uc758-\ub370\uc774\ud130-\ud615\uc2dd",children:"\ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \ub370\uc774\ud130 \ud615\uc2dd"}),"\n",(0,r.jsxs)(s.p,{children:["8\ube44\ud2b8 \ubc14\uc774\ud2b8\uc758 \uc2a4\ud2b8\ub9bc\uc73c\ub85c \uad6c\uc131\ub41c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","16\ube44\ud2b8 \ubc0f 32\ube44\ud2b8\uc758 \ub370\uc774\ud130\ub294 \uac01\uac01 2\uac1c, 4\uac1c\uc758 \uc5f0\uc18d\ub41c 8\ube44\ud2b8\ub97c \uc77d\uc5b4\uc11c \uad6c\uc131\ub41c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\uba40\ud2f0\ubc14\uc774\ud2b8\uc758 \uacbd\uc6b0 \ud56d\uc0c1 big endian \uc21c\uc11c\ub85c \uc800\uc7a5\ub41c\ub2e4."]}),"\n",(0,r.jsxs)(s.p,{children:["u1 \u2192 unsigned 1byte",(0,r.jsx)(s.br,{}),"\n","u2 \u2192 unsigned 2byte",(0,r.jsx)(s.br,{}),"\n","u4 \u2192 unsigned 4byte"]}),"\n",(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\uad6c\uc870",children:"\ud074\ub798\uc2a4 \ud30c\uc77c \uad6c\uc870"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"ClassFile {\n u4 magic;\n u2 minor_version;\n u2 major_version;\n u2 constant_pool_count;\n cp_info constant_pool[constant_pool_count-1];\n u2 access_flags;\n u2 this_class;\n u2 super_class;\n u2 interfaces_count;\n u2 interfaces[interfaces_count];\n u2 fields_count;\n field_info fields[fields_count];\n u2 methods_count;\n method_info methods[methods_count];\n u2 attributes_count;\n attribute_info attributes[attributes_count];\n}\n"})}),"\n",(0,r.jsx)(s.h3,{id:"\ub9e4\uc9c1\ub118\ubc84",children:"\ub9e4\uc9c1\ub118\ubc84"}),"\n",(0,r.jsxs)(s.p,{children:["\ubaa8\ub4e0 \ud074\ub798\uc2a4 \ud30c\uc77c\uc740 0xCAFEBABE\ub77c\ub294 \ub9e4\uc9c1\ub118\ubc84\ub85c \uc2dc\uc791\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\ubcf4\ud1b5 \ub9e4\uc9c1\ub118\ubc84\ub294 \ud30c\uc77c \uc885\ub958\ub97c \uc2dd\ubcc4\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9\ub41c\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud3ec\ub9f7-\ubc84\uc804",children:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud3ec\ub9f7 \ubc84\uc804"}),"\n",(0,r.jsx)(s.p,{children:"\ud074\ub798\uc2a4 \ud30c\uc77c \ubc84\uc804 \uac12\uc740 \ud074\ub798\uc2a4\ub85c\ub354\uc758 \ud638\ud658\uc131 \ubcf4\uc7a5\uc744 \uc704\ud574 \uaf2d \ud544\uc694\ud55c \uac12\uc774\ub2e4."}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Java 17 \ubc84\uc804\uc73c\ub85c \ube4c\ub4dc\ud55c\ub2e4\uba74 class version 61 ex) 00 00 00 3D"}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["\ud638\ud658\ub418\uc9c0 \uc54a\ub294 \ubc84\uc804\uc758 \ud074\ub798\uc2a4 \ud30c\uc77c\uc744 \ub85c\ub529\ud558\ub824\uace0 \ud558\ub294 \uacbd\uc6b0 \ub7f0\ud0c0\uc784\uc5d0 ",(0,r.jsx)(s.code,{children:"UnsupportedClassVersionError"})," \uc608\uc678\uac00 \ubc1c\uc0dd\ud55c\ub2e4."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"class\xa0file format major versions"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Java SE"}),(0,r.jsx)(s.th,{children:"Released"}),(0,r.jsx)(s.th,{children:"Major"}),(0,r.jsx)(s.th,{children:"Supported majors"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"8"}),(0,r.jsx)(s.td,{children:"March 2014"}),(0,r.jsx)(s.td,{children:"52"}),(0,r.jsx)(s.td,{children:"45 .. 52"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"9"}),(0,r.jsx)(s.td,{children:"September 2017"}),(0,r.jsx)(s.td,{children:"53"}),(0,r.jsx)(s.td,{children:"45 .. 53"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"10"}),(0,r.jsx)(s.td,{children:"March 2018"}),(0,r.jsx)(s.td,{children:"54"}),(0,r.jsx)(s.td,{children:"45 .. 54"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"11"}),(0,r.jsx)(s.td,{children:"September 2018"}),(0,r.jsx)(s.td,{children:"55"}),(0,r.jsx)(s.td,{children:"45 .. 55"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"12"}),(0,r.jsx)(s.td,{children:"March 2019"}),(0,r.jsx)(s.td,{children:"56"}),(0,r.jsx)(s.td,{children:"45 .. 56"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"13"}),(0,r.jsx)(s.td,{children:"September 2019"}),(0,r.jsx)(s.td,{children:"57"}),(0,r.jsx)(s.td,{children:"45 .. 57"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"14"}),(0,r.jsx)(s.td,{children:"March 2020"}),(0,r.jsx)(s.td,{children:"58"}),(0,r.jsx)(s.td,{children:"45 .. 58"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"15"}),(0,r.jsx)(s.td,{children:"September 2020"}),(0,r.jsx)(s.td,{children:"59"}),(0,r.jsx)(s.td,{children:"45 .. 59"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"16"}),(0,r.jsx)(s.td,{children:"March 2021"}),(0,r.jsx)(s.td,{children:"60"}),(0,r.jsx)(s.td,{children:"45 .. 60"})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"17"}),(0,r.jsx)(s.td,{children:"September 2021"}),(0,r.jsx)(s.td,{children:"61"}),(0,r.jsx)(s.td,{children:"45 .. 61"})]})]})]}),"\n",(0,r.jsx)(s.h3,{id:"\uc0c1\uc218-\ud480",children:"\uc0c1\uc218 \ud480"}),"\n",(0,r.jsxs)(s.p,{children:["2\ubc14\uc774\ud2b8\uc758 \uc0c1\uc218\uc758 \uac1c\uc218\uac12\uc774 \uba3c\uc800\uc624\uace0 \uadf8 \ub4a4\ub85c \ucf54\ub4dc\uc5d0 \ub4f1\uc7a5\ud558\ub294 \uc0c1\uc218\uac12\uc774 \ubaa8\uc5ec\uc788\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\ud074\ub798\uc2a4\uba85, \uc0c1\uc218\uba85, \uc0c1\uc218 \uac12, \ud544\ub4dc\uba85, \uba54\uc11c\ub4dc\uba85\uacfc \uac19\uc740 \uac12\ub4e4\uc774 \uc874\uc7ac\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","JVM\uc740 \ucf54\ub4dc \uc2e4\ud589 \uc2dc \ub7f0\ud0c0\uc784\uc5d0 \ubc30\uce58\ub41c \uba54\ubaa8\ub9ac\uac00 \uc544\ub2c8\ub77c, \ud574\ub2f9 \uc0c1\uc218 \ud480 \ud14c\uc774\ube14\uc744 \ucc3e\uc544\ubcf4\uace0 \ud544\uc694\ud55c \uac12\uc744 \ucc38\uc870\ud55c\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"\uc561\uc138\uc2a4-\ud50c\ub798\uadf8",children:"\uc561\uc138\uc2a4 \ud50c\ub798\uadf8"}),"\n",(0,r.jsxs)(s.p,{children:["\ud074\ub798\uc2a4, \uc778\ud130\ud398\uc774\uc2a4\uc640 \uac19\uc740 \ud30c\uc77c\uc758 \uc18d\uc131\uc744 \ud45c\uc2dc\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\uc608\ub97c \ub4e4\uc5b4 public interface\ub85c \uc815\uc758\ub41c \uc778\ud130\ud398\uc774\uc2a4\uc758 \ud50c\ub798\uadf8\ub294 0x0601\uc774\ub2e4."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["\uacc4\uc0b0\uc740 \ub2e4\uc74c\uacfc \uac19\uc774 \uc774\ub8e8\uc5b4\uc9c4\ub2e4. ",(0,r.jsx)(s.code,{children:"ACC_PUBLIC"})," xor ",(0,r.jsx)(s.code,{children:"ACC_INTERFACE"})," xor ",(0,r.jsx)(s.code,{children:"ACC_ABSTRACT"})]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:"\uacf5\uc2dd\ubb38\uc11c\uc5d0 \ub4e4\uc5b4\uac00\uba74 \uac01 \ud50c\ub798\uadf8\uc5d0 \ub300\ud55c \uc124\uba85 + \ud50c\ub798\uadf8 \uc124\uc815\uc2dc \ub3d9\uc2dc\uc5d0 \uc124\uc815\ub418\uba74 \uc548\ub418\ub294 \ud50c\ub798\uadf8\uc640 \uac19\uc740 \uc124\uba85\uc774 \uc790\uc138\ud558\uac8c \ub098\uc640\uc788\ub2e4."}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Class access and property modifiers"})}),"\n",(0,r.jsxs)(s.table,{children:[(0,r.jsx)(s.thead,{children:(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.th,{children:"Flag Name"}),(0,r.jsx)(s.th,{children:"Value"}),(0,r.jsx)(s.th,{children:"Interpretation"})]})}),(0,r.jsxs)(s.tbody,{children:[(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_PUBLIC"}),(0,r.jsx)(s.td,{children:"0x0001"}),(0,r.jsx)(s.td,{children:"Declared\xa0public; may be accessed from outside its package."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_FINAL"}),(0,r.jsx)(s.td,{children:"0x0010"}),(0,r.jsx)(s.td,{children:"Declared\xa0final; no subclasses allowed."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_SUPER"}),(0,r.jsx)(s.td,{children:"0x0020"}),(0,r.jsx)(s.td,{children:"Treat superclass methods specially when invoked by the\xa0invokespecial\xa0instruction."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_INTERFACE"}),(0,r.jsx)(s.td,{children:"0x0200"}),(0,r.jsx)(s.td,{children:"Is an interface, not a class."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_ABSTRACT"}),(0,r.jsx)(s.td,{children:"0x0400"}),(0,r.jsx)(s.td,{children:"Declared\xa0abstract; must not be instantiated."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_SYNTHETIC"}),(0,r.jsx)(s.td,{children:"0x1000"}),(0,r.jsx)(s.td,{children:"Declared synthetic; not present in the source code."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_ANNOTATION"}),(0,r.jsx)(s.td,{children:"0x2000"}),(0,r.jsx)(s.td,{children:"Declared as an annotation type."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_ENUM"}),(0,r.jsx)(s.td,{children:"0x4000"}),(0,r.jsx)(s.td,{children:"Declared as an\xa0enum\xa0type."})]}),(0,r.jsxs)(s.tr,{children:[(0,r.jsx)(s.td,{children:"ACC_MODULE"}),(0,r.jsx)(s.td,{children:"0x8000"}),(0,r.jsx)(s.td,{children:"Is a module, not a class or interface."})]})]})]}),"\n",(0,r.jsx)(s.h3,{id:"this_class",children:"this_class"}),"\n",(0,r.jsxs)(s.p,{children:["\ud074\ub798\uc2a4\uba85\uacfc \uac19\uc740 \uc774\ub984\uc744 \ud45c\ud604\ud558\ub294 \uac12\uc73c\ub85c, \uc0c1\uc218 \ud480\uc5d0\uc11c \ud074\ub798\uc2a4\uba85\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\ud574\ub2f9 \uc778\ub371\uc2a4\uc758 \ud56d\ubaa9\uc740 ",(0,r.jsx)(s.code,{children:"CONSTANT_Class_infoclass"})," \ud615\uc2dd\uc758 \uac12\uc774\uc5b4\uc57c \ud55c\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"super_class",children:"super_class"}),"\n",(0,r.jsxs)(s.p,{children:["\uc0c1\uc218 \ud480\uc5d0\uc11c \uc288\ud37c \ud074\ub798\uc2a4\uc758 \uc774\ub984\uacfc \uc77c\uce58\ud558\ub294 \ud56d\ubaa9\uc758 \uc778\ub371\uc2a4\ub97c \ucc38\uc870\ud55c\ub2e4.",(0,r.jsx)(s.br,{}),"\n","\uc544\ubb34\uac83\ub3c4 \uc0c1\uc18d\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\uc758 \uacbd\uc6b0 ",(0,r.jsx)(s.code,{children:"java.lang.Object"}),"\uc758 \uc778\ub371\uc2a4 \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"interface-field-method",children:"interface, field, method"}),"\n",(0,r.jsxs)(s.p,{children:["\uac01\uac01\uc758 \uac1c\uc218\uc640, \uc815\ubcf4\uc5d0 \ub300\ud55c \uac12\uc774 \ub4e4\uc5b4\uc788\ub2e4.",(0,r.jsx)(s.br,{}),"\n","interface, field, method\ub97c \ud45c\uc2dc\ud558\ub294 \ubc29\ubc95\uc774 \uac01\uac01 \ub2e4\ub974\uace0, \uc811\uadfc\uc790\uc5d0 \ub300\ud55c \ud50c\ub798\uadf8\ub3c4 \uac01\uac01 \ub2e4\ub974\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"attributes",children:"attributes"}),"\n",(0,r.jsxs)(s.p,{children:["\ud574\ub2f9 \ud074\ub798\uc2a4 \ud30c\uc77c\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucd94\uac00 \uc815\ubcf4\uc758 \ubaa8\uc74c\uc774\ub2e4. \uc608) \uc18c\uc2a4\ud30c\uc77c\uba85",(0,r.jsx)(s.br,{}),"\n","\uc815\ud574\uc9c4 \ud074\ub798\uc2a4 \ud30c\uc77c\uc758 \uad6c\uc870\ub97c \ud655\uc7a5\ud558\ub294 \uc5ed\ud560\uc744 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(s.h3,{id:"\ud074\ub798\uc2a4-\ud30c\uc77c-\ud655\uc778\ud558\uba74\uc11c-\uc0ac\uc6a9\ud55c-\ud234",children:"\ud074\ub798\uc2a4 \ud30c\uc77c \ud655\uc778\ud558\uba74\uc11c \uc0ac\uc6a9\ud55c \ud234"}),"\n",(0,r.jsxs)(s.p,{children:["IntelliJ plugin - BinEd",(0,r.jsx)(s.br,{}),"\n","IntelliJ plugin - jclasslib Bytecode Viewer"]}),"\n",(0,r.jsx)(s.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(s.p,{children:["2\uc7a5 JVM \uc774\uc57c\uae30, \uc790\ubc14 \ucd5c\uc801\ud654",(0,r.jsx)(s.br,{}),"\n",(0,r.jsx)(s.a,{href:"https://docs.fileformat.com/ko/programming/class/",children:"Class file in Java, File Format"}),(0,r.jsx)(s.br,{}),"\n",(0,r.jsx)(s.a,{href:"https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html",children:"java se11 Class \ud30c\uc77c \ud615\uc2dd, Oracle"}),(0,r.jsx)(s.br,{}),"\n",(0,r.jsx)(s.a,{href:"https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-4.html",children:"java se17 Class \ud30c\uc77c \ud615\uc2dd, Oracle"})]})]})}function j(e={}){const{wrapper:s}={...(0,t.ah)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},3905:(e,s,n)=>{n.d(s,{ah:()=>a});var r=n(67294);function t(e,s,n){return s in e?Object.defineProperty(e,s,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[s]=n,e}function l(e,s){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);s&&(r=r.filter((function(s){return Object.getOwnPropertyDescriptor(e,s).enumerable}))),n.push.apply(n,r)}return n}function d(e){for(var s=1;s<arguments.length;s++){var n=null!=arguments[s]?arguments[s]:{};s%2?l(Object(n),!0).forEach((function(s){t(e,s,n[s])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(s){Object.defineProperty(e,s,Object.getOwnPropertyDescriptor(n,s))}))}return e}function i(e,s){if(null==e)return{};var n,r,t=function(e,s){if(null==e)return{};var n,r,t={},l=Object.keys(e);for(r=0;r<l.length;r++)n=l[r],s.indexOf(n)>=0||(t[n]=e[n]);return t}(e,s);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)n=l[r],s.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(t[n]=e[n])}return t}var c=r.createContext({}),a=function(e){var s=r.useContext(c),n=s;return e&&(n="function"==typeof e?e(s):d(d({},s),e)),n},h={inlineCode:"code",wrapper:function(e){var s=e.children;return r.createElement(r.Fragment,{},s)}},j=r.forwardRef((function(e,s){var n=e.components,t=e.mdxType,l=e.originalType,c=e.parentName,j=i(e,["components","mdxType","originalType","parentName"]),x=a(n),o=t,u=x["".concat(c,".").concat(o)]||x[o]||h[o]||l;return n?r.createElement(u,d(d({ref:s},j),{},{components:n})):r.createElement(u,d({ref:s},j))}));j.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/e073eb07.48315c69.js b/assets/js/e073eb07.2ce17648.js similarity index 81% rename from assets/js/e073eb07.48315c69.js rename to assets/js/e073eb07.2ce17648.js index 0399d53ba..cd9b2656e 100644 --- a/assets/js/e073eb07.48315c69.js +++ b/assets/js/e073eb07.2ce17648.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5819],{57743:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5819],{57743:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/e0e4666e.a51bac0c.js b/assets/js/e0e4666e.cc580050.js similarity index 86% rename from assets/js/e0e4666e.a51bac0c.js rename to assets/js/e0e4666e.cc580050.js index 2db57b02e..189d71910 100644 --- a/assets/js/e0e4666e.a51bac0c.js +++ b/assets/js/e0e4666e.cc580050.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4665],{16482:e=>{e.exports=JSON.parse('{"label":"MySQL","permalink":"/tags/my-sql","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4665],{16482:e=>{e.exports=JSON.parse('{"label":"MySQL","permalink":"/tags/my-sql","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/e1735da7.09484f33.js b/assets/js/e1735da7.09484f33.js deleted file mode 100644 index 3a0f241ec..000000000 --- a/assets/js/e1735da7.09484f33.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1611],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>k});var a=n(67294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?l(Object(n),!0).forEach((function(t){r(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):l(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},l=Object.keys(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(a=0;a<l.length;a++)n=l[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),o=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=o(e.components);return a.createElement(s.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,l=e.originalType,s=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),m=o(n),k=r,d=m["".concat(s,".").concat(k)]||m[k]||u[k]||l;return n?a.createElement(d,i(i({ref:t},c),{},{components:n})):a.createElement(d,i({ref:t},c))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=n.length,i=new Array(l);i[0]=m;var p={};for(var s in t)hasOwnProperty.call(t,s)&&(p[s]=t[s]);p.originalType=e,p.mdxType="string"==typeof e?e:r,i[1]=p;for(var o=2;o<l;o++)i[o]=n[o];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}m.displayName="MDXCreateElement"},9753:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>o});var a=n(87462),r=(n(67294),n(3905));const l={title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",slug:"tecochat-retrospective-2",tags:["TecoChat","Retrospective"]},i=void 0,p={permalink:"/tecochat-retrospective-2",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",source:"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",description:"\ud504\ub860\ud2b8\uc5d4\ud2b8",date:"2023-05-01T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 1\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.67,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",slug:"tecochat-retrospective-2",tags:["TecoChat","Retrospective"]},prevItem:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",permalink:"/web-racing-car-retrospective"},nextItem:{title:"Jenkins\ub85c CI/CD \uc124\uc815",permalink:"/jenkins"}},s={authorsImageUrls:[]},o=[{value:"\ud504\ub860\ud2b8\uc5d4\ud2b8",id:"\ud504\ub860\ud2b8\uc5d4\ud2b8",level:3},{value:"\ubc31\uc5d4\ub4dc",id:"\ubc31\uc5d4\ub4dc",level:3},{value:"Http Request Header",id:"http-request-header",level:3},{value:"Elastic Beanstalk",id:"elastic-beanstalk",level:3},{value:"Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac",id:"elastic-beanstalk-rds-\uc124\uc815-\ud6c4-\ubd84\ub9ac",level:3},{value:"Elastic Beanstalk nginx \uc124\uc815",id:"elastic-beanstalk-nginx-\uc124\uc815",level:3},{value:"Jenkins",id:"jenkins",level:3},{value:"Jenkins Blue Ocean",id:"jenkins-blue-ocean",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:o};function u(e){let{components:t,...n}=e;return(0,r.kt)("wrapper",(0,a.Z)({},c,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"\ud504\ub860\ud2b8\uc5d4\ud2b8"},"\ud504\ub860\ud2b8\uc5d4\ud2b8"),(0,r.kt)("p",null,"\ub2c9\ub124\uc784\uc744 \uc785\ub825\ud558\uc5ec \uac04\ub2e8\ud788 \ub85c\uadf8\uc778\ud558\ub294 \ud654\uba74, \ucc44\ud305 \ubaa9\ub85d\uc744 \ubcf4\uc5ec\uc8fc\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\uace0 \ub2e8\uc77c \ucc44\ud305\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ucc44\ud305\uc744 \uc774\uc5b4\ub098\uac08 \uc218 \uc788\uac8c \ud558\ub294 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc790\uc798\ud558\uac8c \uc2e0\uacbd \uc4f8 \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c, \ud504\ub860\ud2b8\uc5d4\ub4dc \ud558\ub294 \uc0ac\ub78c\ub4e4\uc774 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc5ec\uc720\uac00 \ub41c\ub2e4\uba74 \uc790\uc2e0\uc758 \ucc44\ud305\uc744 \ubcfc \uc218 \uc788\ub294 \uae30\ub2a5\uc774\ub098, \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub294 \uae30\ub2a5, \ub313\uae00 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud560 \uc608\uc815\uc774\ub2e4. "),(0,r.kt)("h3",{id:"\ubc31\uc5d4\ub4dc"},"\ubc31\uc5d4\ub4dc"),(0,r.kt)("p",null,"\ucd5c\ub300\ud55c \ube68\ub9ac \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uae30\ub85c \uc815\ud574\uc11c, \ubc31\uc5d4\ub4dc\ub294 \ub9d0\ub791\uc774 \uc77c\ub2e8 \ub2e4 \ub9cc\ub4e4\uace0 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub9d0\ub791\uc774 \ud55c \ubd80\ubd84\uc774 \ub108\ubb34 \ub9ce\uc544\uc11c \ub0b4\uac00 \ubabb \ub530\ub77c\uac00\ub294 \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub098\uc911\uc5d0 \ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc774\ud574\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4. "),(0,r.kt)("h3",{id:"http-request-header"},"Http Request Header"),(0,r.kt)("p",null,"\uc544\uc9c1 \uc778\uc99d\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ud558\uc9c0 \uc54a\uc544\uc11c \uc694\uccad \ud5e4\ub354\uc5d0 \uc774\ub984\uc744 \ubcf4\ub0b4\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub9d0\ub791\uc774 \ud55c\uae00\uc740 \uc548\ub41c\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c Base64\ub85c \uc778\ucf54\ub529\ud558\uace0, \ubc31\uc5d4\ub4dc\uc5d0\uc11c \ub514\ucf54\ub529 \ud558\uc5ec \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\ub294 pinia\uc5d0 \uc788\ub294 name \uac12\uc744 \uc778\ucf54\ub529 \ud558\ub294 \ucf54\ub4dc\ub2e4. deprecated \ub418\uc5c8\ub2e4\ub294\ub370, \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560 \uc904 \ubab0\ub77c\uc11c \uc77c\ub2e8 \uc774\uac78 \uc0ac\uc6a9\ud588\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-ts"},"const encodedName = () => {\n const uriComponent = unescape(encodeURIComponent(name.value));\n return btoa(uriComponent);\n};\n")),(0,r.kt)("h3",{id:"elastic-beanstalk"},"Elastic Beanstalk"),(0,r.kt)("p",null,"\uac00\uc7a5 \ube60\ub974\uac8c \ubc31\uc5d4\ub4dc\ub97c \ubc30\ud3ec\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ubb58\uc9c0 \uace0\ubbfc\ud558\ub2e4\uac00 Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uba74 \uc778\ud504\ub77c\uc5d0 \ub300\ud574 \uc798 \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ube60\ub974\uac8c \ubc30\ud3ec\ud558\uace0 \uad00\ub9ac\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubaa8\ub2c8\ud130\ub9c1, \ub85c\uae45, \ub85c\ub4dc \ubc38\ub7f0\uc2f1 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4. "),(0,r.kt)("h3",{id:"elastic-beanstalk-rds-\uc124\uc815-\ud6c4-\ubd84\ub9ac"},"Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac"),(0,r.kt)("p",null,"\ucd08\uae30 \uc124\uc815 \uc2dc RDS\ub97c \uc5f0\uacb0\ud558\uace0 \uc124\uc815 \uc644\ub8cc \ud6c4 \ubd84\ub9ac\ud55c\ub2e4\uba74, Beanstalk \uc778\uc2a4\ud134\uc2a4 -> RDS \uc694\uccad \uc2dc \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc744 \uc548 \ud574\ub3c4 \ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","RDS \ubd84\ub9ac \uc2dc Beanstalk\uc5d0 \uae30\ubcf8\uc801\uc73c\ub85c \uc124\uc815\ub418\uc5b4 \uc788\ub294 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD\uc640 \uac19\uc740 \ud658\uacbd \ubcc0\uc218\uac00 \uac19\uc774 \uc81c\uac70\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c Elastic Beanstalk\ub85c RDS\ub97c \uc124\uc815\ud558\uba74 \uae30\ubcf8 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uba85\uc740 ebdb\ub2e4. "),(0,r.kt)("h3",{id:"elastic-beanstalk-nginx-\uc124\uc815"},"Elastic Beanstalk nginx \uc124\uc815"),(0,r.kt)("p",null,"\uc5c5\ub85c\ub4dc\ud558\ub294 zip \ud30c\uc77c \ub0b4\ubd80\uc5d0 ",(0,r.kt)("inlineCode",{parentName:"p"},".platform/nginx/conf.d/")," \uacbd\ub85c\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ucd94\uac00\ud558\uba74 nginx \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("h3",{id:"jenkins"},"Jenkins"),(0,r.kt)("p",null,"\ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc77c\uc77c\ud788 \ubc30\ud3ec\ud558\uae30 \ubd88\ud3b8\ud574\uc11c Jenkins\ub97c \uc774\uc6a9\ud558\uc5ec Repository\uc5d0 \ucf54\ub4dc\ub97c push \ud560 \ub54c \uc790\ub3d9\uc73c\ub85c \ubc30\ud3ec\uac00 \ub418\uac8c \uc124\uc815\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc791\ub144\uc5d0 \ud655\uc778\ud588\uc744 \ub550 2022\ub144 12\uc6d4 31\uc77c\uae4c\uc9c0 EC2 ARM \uae30\ubc18 t4g.small\uc774 \ubb34\ub8cc\uc600\ub294\ub370, \ub2e4\uc2dc \ub4e4\uc5b4\uac00 \ubcf4\ub2c8 2023\ub144\uae4c\uc9c0 12\uc6d4 31\uc77c\uae4c\uc9c0 t4g.small\uc744 \ubb34\ub8cc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","t4g.small\uc740 \ub7a8\uc774 2G\uc778\ub370, \uc608\uc804\uc5d0\ub294 \ubd80\uc871\ud558\uc9c0 \uc54a\uc558\ub2e4\uace0 \uc0dd\uac01\ud588\ub294\ub370 Java 17\uc744 \uc368\uc11c \uadf8\ub7f0\uac00 \ube4c\ub4dc \ud560 \ub54c \ub7a8\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\uc544\uc11c Swap \uba54\ubaa8\ub9ac 2\uae30\uac00\ub97c \ucd94\uac00\ub85c \uc124\uc815\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c build.gradle\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8 \uc2dc \uc0ac\uc6a9\ud558\ub294 \ub7a8\uc744 \ub298\ub9b4 \uc218 \uc788\ub2e4. \uae30\ubcf8\uac12\uc740 512MB\ub77c\uace0 \ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-groovy"},'test {\n maxHeapSize = "1024m"\n}\n')),(0,r.kt)("h3",{id:"jenkins-blue-ocean"},"Jenkins Blue Ocean"),(0,r.kt)("p",null,"Blue Ocean\uc740 Jenkins Pipeline\uc744 \uad6c\uc131\ud558\ub294 \ub370\uc5d0 \uc788\uc5b4 \ud3b8\ub9ac\ud558\uac8c \ud574\uc8fc\ub294 \ub3c4\uad6c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc2dc\uac01\ud654\ub3c4 \uc798 \ub418\uc5b4\uc788\uace0, \uc124\uc815\ub3c4 \ud3b8\ub9ac\ud55c \uac83 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",'\uc624\ub298 \uc801\uc6a9\ud574 \ubcf4\ub2c8 \ub7a8\uc774 \ubd80\uc871\ud558\uc5ec \uc911\uac04\uc5d0 \uc798 \uc548\ub418\uae30\ub3c4 \ud558\uace0 \uadf8\ub798\uc11c \uadf8\ub0e5 "Pipeline\ub9cc \uc0ac\uc6a9\ud560 \uac78 \uadf8\ub7ac\ub098?" \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4. '),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/Welcome.html"},"Elastic Beanstalk, AWS"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/ec2/graviton/"},"EC2 AWS Graviton, AWS"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.gradle.org/current/userguide/upgrading_version_4.html#rel5.0:default_memory_settings"},"Default Memory Settings, AWS")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e1735da7.7747f2b7.js b/assets/js/e1735da7.7747f2b7.js new file mode 100644 index 000000000..3e0d51f73 --- /dev/null +++ b/assets/js/e1735da7.7747f2b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1611],{79784:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>s,metadata:()=>i,toc:()=>o});var r=t(85893),a=t(3905);const s={title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",slug:"tecochat-retrospective-2",tags:["TecoChat","Retrospective"]},l=void 0,i={permalink:"/tecochat-retrospective-2",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",source:"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",description:"\ud504\ub860\ud2b8\uc5d4\ud2b8",date:"2023-05-01T00:00:00.000Z",formattedDate:"2023\ub144 5\uc6d4 1\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:4.67,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 2. \ubc30\ud3ec",slug:"tecochat-retrospective-2",tags:["TecoChat","Retrospective"]},unlisted:!1,prevItem:{title:"\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0",permalink:"/web-racing-car-retrospective"},nextItem:{title:"Jenkins\ub85c CI/CD \uc124\uc815",permalink:"/jenkins"}},c={authorsImageUrls:[]},o=[{value:"\ud504\ub860\ud2b8\uc5d4\ud2b8",id:"\ud504\ub860\ud2b8\uc5d4\ud2b8",level:3},{value:"\ubc31\uc5d4\ub4dc",id:"\ubc31\uc5d4\ub4dc",level:3},{value:"Http Request Header",id:"http-request-header",level:3},{value:"Elastic Beanstalk",id:"elastic-beanstalk",level:3},{value:"Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac",id:"elastic-beanstalk-rds-\uc124\uc815-\ud6c4-\ubd84\ub9ac",level:3},{value:"Elastic Beanstalk nginx \uc124\uc815",id:"elastic-beanstalk-nginx-\uc124\uc815",level:3},{value:"Jenkins",id:"jenkins",level:3},{value:"Jenkins Blue Ocean",id:"jenkins-blue-ocean",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",br:"br",code:"code",h3:"h3",p:"p",pre:"pre",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"\ud504\ub860\ud2b8\uc5d4\ud2b8",children:"\ud504\ub860\ud2b8\uc5d4\ud2b8"}),"\n",(0,r.jsxs)(n.p,{children:["\ub2c9\ub124\uc784\uc744 \uc785\ub825\ud558\uc5ec \uac04\ub2e8\ud788 \ub85c\uadf8\uc778\ud558\ub294 \ud654\uba74, \ucc44\ud305 \ubaa9\ub85d\uc744 \ubcf4\uc5ec\uc8fc\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\uace0 \ub2e8\uc77c \ucc44\ud305\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub294 \ud654\uba74\ub3c4 \ub9cc\ub4e4\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ucc44\ud305\uc744 \uc774\uc5b4\ub098\uac08 \uc218 \uc788\uac8c \ud558\ub294 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc790\uc798\ud558\uac8c \uc2e0\uacbd \uc4f8 \ubd80\ubd84\uc774 \ub9ce\uc544\uc11c, \ud504\ub860\ud2b8\uc5d4\ub4dc \ud558\ub294 \uc0ac\ub78c\ub4e4\uc774 \ub300\ub2e8\ud558\ub2e4\uace0 \uc0dd\uac01\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc5ec\uc720\uac00 \ub41c\ub2e4\uba74 \uc790\uc2e0\uc758 \ucc44\ud305\uc744 \ubcfc \uc218 \uc788\ub294 \uae30\ub2a5\uc774\ub098, \ucc44\ud305\uc744 \uc774\uc5b4\uc11c \ud560 \uc218 \uc788\ub294 \uae30\ub2a5, \ub313\uae00 \uae30\ub2a5\ub3c4 \ucd94\uac00\ud560 \uc608\uc815\uc774\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ubc31\uc5d4\ub4dc",children:"\ubc31\uc5d4\ub4dc"}),"\n",(0,r.jsxs)(n.p,{children:["\ucd5c\ub300\ud55c \ube68\ub9ac \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uae30\ub85c \uc815\ud574\uc11c, \ubc31\uc5d4\ub4dc\ub294 \ub9d0\ub791\uc774 \uc77c\ub2e8 \ub2e4 \ub9cc\ub4e4\uace0 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub9d0\ub791\uc774 \ud55c \ubd80\ubd84\uc774 \ub108\ubb34 \ub9ce\uc544\uc11c \ub0b4\uac00 \ubabb \ub530\ub77c\uac00\ub294 \uac83 \uac19\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub098\uc911\uc5d0 \ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc774\ud574\ud558\ub294 \uc2dc\uac04\uc744 \uac00\uc838\uc57c\uaca0\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"http-request-header",children:"Http Request Header"}),"\n",(0,r.jsxs)(n.p,{children:["\uc544\uc9c1 \uc778\uc99d\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \ud558\uc9c0 \uc54a\uc544\uc11c \uc694\uccad \ud5e4\ub354\uc5d0 \uc774\ub984\uc744 \ubcf4\ub0b4\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub9d0\ub791\uc774 \ud55c\uae00\uc740 \uc548\ub41c\ub2e4\uace0 \ub9d0\ud574\uc918\uc11c Base64\ub85c \uc778\ucf54\ub529\ud558\uace0, \ubc31\uc5d4\ub4dc\uc5d0\uc11c \ub514\ucf54\ub529 \ud558\uc5ec \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc544\ub798\ub294 pinia\uc5d0 \uc788\ub294 name \uac12\uc744 \uc778\ucf54\ub529 \ud558\ub294 \ucf54\ub4dc\ub2e4. deprecated \ub418\uc5c8\ub2e4\ub294\ub370, \ub2e4\ub978 \ubc29\ubc95\uc744 \uc0ac\uc6a9\ud560 \uc904 \ubab0\ub77c\uc11c \uc77c\ub2e8 \uc774\uac78 \uc0ac\uc6a9\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"const encodedName = () => {\n const uriComponent = unescape(encodeURIComponent(name.value));\n return btoa(uriComponent);\n};\n"})}),"\n",(0,r.jsx)(n.h3,{id:"elastic-beanstalk",children:"Elastic Beanstalk"}),"\n",(0,r.jsxs)(n.p,{children:["\uac00\uc7a5 \ube60\ub974\uac8c \ubc31\uc5d4\ub4dc\ub97c \ubc30\ud3ec\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ubb58\uc9c0 \uace0\ubbfc\ud558\ub2e4\uac00 Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Elastic Beanstalk\ub97c \uc0ac\uc6a9\ud558\uba74 \uc778\ud504\ub77c\uc5d0 \ub300\ud574 \uc798 \uc54c\uc9c0 \ubabb\ud574\ub3c4 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ube60\ub974\uac8c \ubc30\ud3ec\ud558\uace0 \uad00\ub9ac\ud560 \uc218 \uc788\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubaa8\ub2c8\ud130\ub9c1, \ub85c\uae45, \ub85c\ub4dc \ubc38\ub7f0\uc2f1 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"elastic-beanstalk-rds-\uc124\uc815-\ud6c4-\ubd84\ub9ac",children:"Elastic Beanstalk RDS \uc124\uc815 \ud6c4 \ubd84\ub9ac"}),"\n",(0,r.jsxs)(n.p,{children:["\ucd08\uae30 \uc124\uc815 \uc2dc RDS\ub97c \uc5f0\uacb0\ud558\uace0 \uc124\uc815 \uc644\ub8cc \ud6c4 \ubd84\ub9ac\ud55c\ub2e4\uba74, Beanstalk \uc778\uc2a4\ud134\uc2a4 -> RDS \uc694\uccad \uc2dc \uc778\ubc14\uc6b4\ub4dc \uc124\uc815\uc744 \uc548 \ud574\ub3c4 \ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","RDS \ubd84\ub9ac \uc2dc Beanstalk\uc5d0 \uae30\ubcf8\uc801\uc73c\ub85c \uc124\uc815\ub418\uc5b4 \uc788\ub294 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD\uc640 \uac19\uc740 \ud658\uacbd \ubcc0\uc218\uac00 \uac19\uc774 \uc81c\uac70\ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c Elastic Beanstalk\ub85c RDS\ub97c \uc124\uc815\ud558\uba74 \uae30\ubcf8 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uba85\uc740 ebdb\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"elastic-beanstalk-nginx-\uc124\uc815",children:"Elastic Beanstalk nginx \uc124\uc815"}),"\n",(0,r.jsxs)(n.p,{children:["\uc5c5\ub85c\ub4dc\ud558\ub294 zip \ud30c\uc77c \ub0b4\ubd80\uc5d0 ",(0,r.jsx)(n.code,{children:".platform/nginx/conf.d/"})," \uacbd\ub85c\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \ucd94\uac00\ud558\uba74 nginx \uc124\uc815\uc744 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"jenkins",children:"Jenkins"}),"\n",(0,r.jsxs)(n.p,{children:["\ubc31\uc5d4\ub4dc \ucf54\ub4dc\ub97c \uc77c\uc77c\ud788 \ubc30\ud3ec\ud558\uae30 \ubd88\ud3b8\ud574\uc11c Jenkins\ub97c \uc774\uc6a9\ud558\uc5ec Repository\uc5d0 \ucf54\ub4dc\ub97c push \ud560 \ub54c \uc790\ub3d9\uc73c\ub85c \ubc30\ud3ec\uac00 \ub418\uac8c \uc124\uc815\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc791\ub144\uc5d0 \ud655\uc778\ud588\uc744 \ub550 2022\ub144 12\uc6d4 31\uc77c\uae4c\uc9c0 EC2 ARM \uae30\ubc18 t4g.small\uc774 \ubb34\ub8cc\uc600\ub294\ub370, \ub2e4\uc2dc \ub4e4\uc5b4\uac00 \ubcf4\ub2c8 2023\ub144\uae4c\uc9c0 12\uc6d4 31\uc77c\uae4c\uc9c0 t4g.small\uc744 \ubb34\ub8cc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","t4g.small\uc740 \ub7a8\uc774 2G\uc778\ub370, \uc608\uc804\uc5d0\ub294 \ubd80\uc871\ud558\uc9c0 \uc54a\uc558\ub2e4\uace0 \uc0dd\uac01\ud588\ub294\ub370 Java 17\uc744 \uc368\uc11c \uadf8\ub7f0\uac00 \ube4c\ub4dc \ud560 \ub54c \ub7a8\uc774 \ub9ce\uc774 \ubd80\uc871\ud55c \uac83 \uac19\uc544\uc11c Swap \uba54\ubaa8\ub9ac 2\uae30\uac00\ub97c \ucd94\uac00\ub85c \uc124\uc815\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c build.gradle\uc5d0\uc11c \uc544\ub798\uc640 \uac19\uc774 \uc124\uc815\ud55c\ub2e4\uba74 \ud14c\uc2a4\ud2b8 \uc2dc \uc0ac\uc6a9\ud558\ub294 \ub7a8\uc744 \ub298\ub9b4 \uc218 \uc788\ub2e4. \uae30\ubcf8\uac12\uc740 512MB\ub77c\uace0 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-groovy",children:'test {\n maxHeapSize = "1024m"\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"jenkins-blue-ocean",children:"Jenkins Blue Ocean"}),"\n",(0,r.jsxs)(n.p,{children:["Blue Ocean\uc740 Jenkins Pipeline\uc744 \uad6c\uc131\ud558\ub294 \ub370\uc5d0 \uc788\uc5b4 \ud3b8\ub9ac\ud558\uac8c \ud574\uc8fc\ub294 \ub3c4\uad6c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc2dc\uac01\ud654\ub3c4 \uc798 \ub418\uc5b4\uc788\uace0, \uc124\uc815\ub3c4 \ud3b8\ub9ac\ud55c \uac83 \uac19\ub2e4.",(0,r.jsx)(n.br,{}),"\n",'\uc624\ub298 \uc801\uc6a9\ud574 \ubcf4\ub2c8 \ub7a8\uc774 \ubd80\uc871\ud558\uc5ec \uc911\uac04\uc5d0 \uc798 \uc548\ub418\uae30\ub3c4 \ud558\uace0 \uadf8\ub798\uc11c \uadf8\ub0e5 "Pipeline\ub9cc \uc0ac\uc6a9\ud560 \uac78 \uadf8\ub7ac\ub098?" \ub77c\ub294 \uc0dd\uac01\uc774 \ub4e0\ub2e4.']}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/Welcome.html",children:"Elastic Beanstalk, AWS"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://aws.amazon.com/ko/ec2/graviton/",children:"EC2 AWS Graviton, AWS"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://docs.gradle.org/current/userguide/upgrading_version_4.html#rel5.0:default_memory_settings",children:"Default Memory Settings, AWS"})]})]})}function p(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>o});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function l(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?s(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function i(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},s=Object.keys(e);for(r=0;r<s.length;r++)t=s[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)t=s[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var c=r.createContext({}),o=function(e){var n=r.useContext(c),t=n;return e&&(t="function"==typeof e?e(n):l(l({},n),e)),t},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},p=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=o(t),h=a,b=u["".concat(c,".").concat(h)]||u[h]||d[h]||s;return t?r.createElement(b,l(l({ref:n},p),{},{components:t})):r.createElement(b,l({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/e1a06456.e3f8fecc.js b/assets/js/e1a06456.e3f8fecc.js deleted file mode 100644 index 763cbbe5d..000000000 --- a/assets/js/e1a06456.e3f8fecc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9910],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},k={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=c(r),u=o,b=m["".concat(p,".").concat(u)]||m[u]||k[u]||a;return r?n.createElement(b,i(i({ref:t},s),{},{components:r})):n.createElement(b,i({ref:t},s))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c<a;c++)i[c]=r[c];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},34117:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>k,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={title:"\uc6f9\uc18c\ucf13",slug:"websocket",tags:["WebSocket"]},i=void 0,l={permalink:"/websocket",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-26-WebSocket.mdx",source:"@site/blog/2023-2/2023-06-26-WebSocket.mdx",title:"\uc6f9\uc18c\ucf13",description:"\uc6f9\uc18c\ucf13",date:"2023-06-26T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 26\uc77c",tags:[{label:"WebSocket",permalink:"/tags/web-socket"}],readingTime:4.165,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9\uc18c\ucf13",slug:"websocket",tags:["WebSocket"]},prevItem:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",permalink:"/java-spring-springboot"},nextItem:{title:"Docusaurus",permalink:"/docusaurus"}},p={authorsImageUrls:[]},c=[{value:"\uc6f9\uc18c\ucf13",id:"\uc6f9\uc18c\ucf13",level:3},{value:"\uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd",id:"\uc6f9\uc18c\ucf13-\ub4f1\uc7a5-\ubc30\uacbd",level:3},{value:"\uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791",id:"\uc6f9\uc18c\ucf13\uc758-\ub3d9\uc791",level:3},{value:"1. Upgrade \uc694\uccad",id:"1-upgrade-\uc694\uccad",level:3},{value:"2. Switching Protocols",id:"2-switching-protocols",level:3},{value:"3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc",id:"3-\ud1b5\uc2e0-\ud6c4-\uc885\ub8cc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:c};function k(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"\uc6f9\uc18c\ucf13"},"\uc6f9\uc18c\ucf13"),(0,o.kt)("p",null,"\ub2e8\uc77c TCP \uc5f0\uacb0\uc744 \ud1b5\ud574 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ubc84 \uac04 \uc804\uc774\uc911 \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \uc9c0\uc6d0\ud558\ub294 \ud504\ub85c\ud1a0\ucf5c",(0,o.kt)("br",{parentName:"p"}),"\n","\uc6f9 \ud658\uacbd\uc5d0\uc11c \uc5f0\uc18d\ub41c \ub370\uc774\ud130\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4. "),(0,o.kt)("p",null,"\uc6f9\uc18c\ucf13\uc740 HTTP\uc758 \ud3ec\ud2b8\ub97c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uace0 \uac01\uac01 \ud3ec\ud2b8 80\uacfc \ud3ec\ud2b8 443\uc744 \uc0ac\uc6a9\ud558\uc5ec HTTP(ws://) \ubc0f HTTPS(wss://)\ub85c \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ud55c\ub2e4. "),(0,o.kt)("h3",{id:"\uc6f9\uc18c\ucf13-\ub4f1\uc7a5-\ubc30\uacbd"},"\uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd"),(0,o.kt)("p",null,"\uc6f9\uc18c\ucf13\uc774 \ub4f1\uc7a5\ud558\uae30 \uc774\uc804, \uc2e4\uc2dc\uac04\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 Polling, Long polling, Streaming \uac19\uc740 \uae30\uc220\uc744 \uc0ac\uc6a9\ud588\uc5b4\uc57c \ud588\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 \uc2e4\uc2dc\uac04\uc131\uc774\ub098 \uc591\ubc29\ud5a5\uc131\uc744 \ub9cc\uc871\uc2dc\ud0a4\uc9c0 \ubabb\ud588\uace0, HTTP\ub97c \uc774\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uacfc\ub3c4\ud55c \uc624\ubc84\ud5e4\ub4dc\uac00 \ubc1c\uc0dd\ud588\ub2e4. "),(0,o.kt)("admonition",{title:"polling, long polling, streaming",type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Polling: \uc8fc\uae30\uc801\uc73c\ub85c \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ubcf4\ub0b4 \uc218\uc2e0\ud560 \uc815\ubcf4\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubc29\ubc95"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},"\uc11c\ubc84\uc5d0\uc11c \ubcf4\ub0bc \ub0b4\uc6a9\uc774 \uc5c6\uc5b4\ub3c4 \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \uc54c \uc218 \uc5c6\ub2e4. "),(0,o.kt)("li",{parentName:"ul"},"\uacc4\uc18d\ud574\uc11c \uc694\uccad\uc744 \ubcf4\ub0b4 \ud655\uc778\uc744 \ud574\uc57c\ud558\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ubd88\ud544\uc694\ud55c \ubd80\ud558\ub97c \uc8fc\uc5b4\uc57c \ud55c\ub2e4. ")),(0,o.kt)("p",{parentName:"admonition"},"Long Polling: \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc5d0 \ub300\ud574 \uc751\ub2f5\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uace0 \uc788\ub2e4\uac00 \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud588\uc744\ub54c \uc751\ub2f5\ud558\ub294 \ubc29\ubc95"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},"\ud3f4\ub9c1 \ubc29\uc2dd\ubcf4\ub2e4 \uc11c\ubc84\uc5d0 \uc801\uc740 \ubd80\ud558\ub97c \uc904 \uc218 \uc788\uc9c0\ub9cc, \uc694\uccad\uc758 \uc8fc\uae30\uac00 \uc9e7\uc73c\uba74 \ud3f4\ub9c1\uacfc \ucc28\uc774\uac00 \uc5c6\uc5b4\uc9c4\ub2e4.")),(0,o.kt)("p",{parentName:"admonition"},"Streaming: \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 request\ub97c \ubcf4\ub0b4\uba74 \ucee4\ub125\uc158\uc744 \ub9fa\uace0, \uc774 \ucee4\ub125\uc158\uc744 \uc720\uc9c0\ud558\uba74\uc11c \uc11c\ubc84\uac00 \uacc4\uc18d \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},"\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ud558\uace0 \uc2f6\ub2e4\uba74 \uc0c8\ub85c\uc6b4 \ucee4\ub125\uc158\uc744 \ub9fa\uc5b4\uc57c \ud55c\ub2e4. "))),(0,o.kt)("h3",{id:"\uc6f9\uc18c\ucf13\uc758-\ub3d9\uc791"},"\uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791"),(0,o.kt)("mermaid",{value:"sequenceDiagram\n participant Client\n participant Server\n Client->>Server: Handshake - Upgrade\ub97c \uc774\uc6a9\ud55c WebSocket \uc804\ud658 \uc694\uccad\n Server->>Client: Handshake - HttpStatus 101(Switching Protocols)\n\n Client->>Server: \uc591\ubc29\ud5a5 \ud1b5\uc2e0\n Server->>Client: \n\n Client->>Server: \uc885\ub8cc\n Server->>Client: "}),(0,o.kt)("h3",{id:"1-upgrade-\uc694\uccad"},"1. Upgrade \uc694\uccad"),(0,o.kt)("p",null,"WebSocket \ud504\ub85c\ud1a0\ucf5c\ub85c \uc804\ud658\ud558\ub294 HTTP \uc694\uccad\uc744 \ubcf4\ub0b8\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 HTTP\uc640 \uac19\uc774 80, 443 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc6f9\uc18c\ucf13\uc73c\ub85c \uc804\ud658\ud558\uae30 \uc704\ud574\uc11c\ub294 Upgrade: websocket, Connection: Upgrade \ud5e4\ub354\uac00 \ud544\uc694\ud558\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","Sec-WebSocket-Key\ub294 \uc11c\ubc84\uc5d0\uc11c Sec-WebSocket-Accept\ub97c \uacc4\uc0b0\ud558\uc5ec \uc751\ub2f5\ud558\uace0 \uc774 \uac12\uc774 \uc608\uc0c1\ud55c \uac12\uacfc \ub2e4\ub974\uba74 \uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","Sec-WebSocket-Protocol\uc758 \uacbd\uc6b0 \uc11c\ube0c\ud504\ub85c\ud1a0\ucf5c\uc758 \ubaa9\ub85d\uc73c\ub85c \uc11c\ubc84 \uce21\uc5d0\uc11c\ub294 \ud574\ub2f9 \ubaa9\ub85d \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud558\uc5ec \ubc18\ud658\ud574\uc57c \ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ub9cc\uc57d \uc11c\ubc84\uce21\uc5d0\uc11c \uc5ec\ub7ec \uac1c \uc9c0\uc6d0\uc774 \uac00\ub2a5\ud55c \uacbd\uc6b0 \uc9c0\uc6d0 \uac00\ub2a5\ud55c \ud504\ub85c\ud1a0\ucf5c \uc911 \uccab\ubc88\uc9f8 \ud504\ub85c\ud1a0\ucf5c\uc744 \ud074\ub77c\uc774\uc5b8\ud2b8\uce21\uc73c\ub85c \ubcf4\ub0b8\ub2e4. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"GET /chats HTTP/1.1\nHost: localhost:8080\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==\nSec-WebSocket-Protocol: v10.stomp, v11.stomp\nSec-WebSocket-Version: 13\nOrigin: http://localhost:8080\n")),(0,o.kt)("h3",{id:"2-switching-protocols"},"2. Switching Protocols"),(0,o.kt)("p",null,"\uc11c\ubc84\ub294 101 Switching Protocols \uc751\ub2f5\uc744 \ubc18\ud658\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","Sec-WebSocket-Accept\uc740 Sec-WebSocket-Key \ub4a4\uc5d0 ",(0,o.kt)("inlineCode",{parentName:"p"},"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"),"\ub97c \ubd99\uc774\uace0 SHA1\ub85c \ud574\uc2f1 \ud6c4 Base64\ub85c \uc778\ucf54\ub529\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 \uc11c\ubc84 \uc6f9\uc18c\ucf13 \ud504\ub85c\ud1a0\ucf5c\uc758 \uc9c0\uc6d0 \uc5ec\ubd80\ub97c \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \uba85\ud655\ud788 \uc54c\ub9ac\uae30 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"HTTP/1.1 101 Switching Protocols \nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=\nSec-WebSocket-Protocol: v10.stomp\n")),(0,o.kt)("h3",{id:"3-\ud1b5\uc2e0-\ud6c4-\uc885\ub8cc"},"3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc"),(0,o.kt)("p",null,"\uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uba74 \uc6f9\uc18c\ucf13 \ud504\ub808\uc784 \ub2e8\uc704\ub85c \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc5f0\uacb0 \uc885\ub8cc\ub97c \uc6d0\ud558\ub294 \uacbd\uc6b0 \ud074\ub77c\uc774\uc5b8\ud2b8, \uc11c\ubc84 \ubaa8\ub450 \uc5f0\uacb0 \uc885\ub8cc\ub97c \uc694\uccad\ud560 \uc218 \uc788\ub2e4. "),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc6455"},"https://datatracker.ietf.org/doc/html/rfc6455"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications"},"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers"},"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/reference/web/websocket.html"},"https://docs.spring.io/spring-framework/reference/web/websocket.html")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e1a06456.e625e406.js b/assets/js/e1a06456.e625e406.js new file mode 100644 index 000000000..030b40c00 --- /dev/null +++ b/assets/js/e1a06456.e625e406.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9910],{54885:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>c,metadata:()=>s,toc:()=>a});var r=n(85893),o=n(3905);const c={title:"\uc6f9\uc18c\ucf13",slug:"websocket",tags:["WebSocket"]},i=void 0,s={permalink:"/websocket",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-26-WebSocket.mdx",source:"@site/blog/2023-2/2023-06-26-WebSocket.mdx",title:"\uc6f9\uc18c\ucf13",description:"\uc6f9\uc18c\ucf13",date:"2023-06-26T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 26\uc77c",tags:[{label:"WebSocket",permalink:"/tags/web-socket"}],readingTime:4.165,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9\uc18c\ucf13",slug:"websocket",tags:["WebSocket"]},unlisted:!1,prevItem:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",permalink:"/java-spring-springboot"},nextItem:{title:"Docusaurus",permalink:"/docusaurus"}},l={authorsImageUrls:[]},a=[{value:"\uc6f9\uc18c\ucf13",id:"\uc6f9\uc18c\ucf13",level:3},{value:"\uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd",id:"\uc6f9\uc18c\ucf13-\ub4f1\uc7a5-\ubc30\uacbd",level:3},{value:"\uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791",id:"\uc6f9\uc18c\ucf13\uc758-\ub3d9\uc791",level:3},{value:"1. Upgrade \uc694\uccad",id:"1-upgrade-\uc694\uccad",level:3},{value:"2. Switching Protocols",id:"2-switching-protocols",level:3},{value:"3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc",id:"3-\ud1b5\uc2e0-\ud6c4-\uc885\ub8cc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",mermaid:"mermaid",p:"p",pre:"pre",ul:"ul",...(0,o.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"\uc6f9\uc18c\ucf13",children:"\uc6f9\uc18c\ucf13"}),"\n",(0,r.jsxs)(t.p,{children:["\ub2e8\uc77c TCP \uc5f0\uacb0\uc744 \ud1b5\ud574 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ubc84 \uac04 \uc804\uc774\uc911 \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \uc9c0\uc6d0\ud558\ub294 \ud504\ub85c\ud1a0\ucf5c",(0,r.jsx)(t.br,{}),"\n","\uc6f9 \ud658\uacbd\uc5d0\uc11c \uc5f0\uc18d\ub41c \ub370\uc774\ud130\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:"\uc6f9\uc18c\ucf13\uc740 HTTP\uc758 \ud3ec\ud2b8\ub97c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uace0 \uac01\uac01 \ud3ec\ud2b8 80\uacfc \ud3ec\ud2b8 443\uc744 \uc0ac\uc6a9\ud558\uc5ec HTTP(ws://) \ubc0f HTTPS(wss://)\ub85c \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ud55c\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"\uc6f9\uc18c\ucf13-\ub4f1\uc7a5-\ubc30\uacbd",children:"\uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd"}),"\n",(0,r.jsxs)(t.p,{children:["\uc6f9\uc18c\ucf13\uc774 \ub4f1\uc7a5\ud558\uae30 \uc774\uc804, \uc2e4\uc2dc\uac04\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 Polling, Long polling, Streaming \uac19\uc740 \uae30\uc220\uc744 \uc0ac\uc6a9\ud588\uc5b4\uc57c \ud588\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub294 \uc2e4\uc2dc\uac04\uc131\uc774\ub098 \uc591\ubc29\ud5a5\uc131\uc744 \ub9cc\uc871\uc2dc\ud0a4\uc9c0 \ubabb\ud588\uace0, HTTP\ub97c \uc774\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uacfc\ub3c4\ud55c \uc624\ubc84\ud5e4\ub4dc\uac00 \ubc1c\uc0dd\ud588\ub2e4."]}),"\n",(0,r.jsxs)(t.admonition,{title:"polling, long polling, streaming",type:"note",children:[(0,r.jsx)(t.p,{children:"Polling: \uc8fc\uae30\uc801\uc73c\ub85c \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ubcf4\ub0b4 \uc218\uc2e0\ud560 \uc815\ubcf4\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubc29\ubc95"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\uc11c\ubc84\uc5d0\uc11c \ubcf4\ub0bc \ub0b4\uc6a9\uc774 \uc5c6\uc5b4\ub3c4 \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \uc54c \uc218 \uc5c6\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"\uacc4\uc18d\ud574\uc11c \uc694\uccad\uc744 \ubcf4\ub0b4 \ud655\uc778\uc744 \ud574\uc57c\ud558\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ubd88\ud544\uc694\ud55c \ubd80\ud558\ub97c \uc8fc\uc5b4\uc57c \ud55c\ub2e4."}),"\n"]}),(0,r.jsx)(t.p,{children:"Long Polling: \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc5d0 \ub300\ud574 \uc751\ub2f5\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uace0 \uc788\ub2e4\uac00 \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud588\uc744\ub54c \uc751\ub2f5\ud558\ub294 \ubc29\ubc95"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\ud3f4\ub9c1 \ubc29\uc2dd\ubcf4\ub2e4 \uc11c\ubc84\uc5d0 \uc801\uc740 \ubd80\ud558\ub97c \uc904 \uc218 \uc788\uc9c0\ub9cc, \uc694\uccad\uc758 \uc8fc\uae30\uac00 \uc9e7\uc73c\uba74 \ud3f4\ub9c1\uacfc \ucc28\uc774\uac00 \uc5c6\uc5b4\uc9c4\ub2e4."}),"\n"]}),(0,r.jsx)(t.p,{children:"Streaming: \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 request\ub97c \ubcf4\ub0b4\uba74 \ucee4\ub125\uc158\uc744 \ub9fa\uace0, \uc774 \ucee4\ub125\uc158\uc744 \uc720\uc9c0\ud558\uba74\uc11c \uc11c\ubc84\uac00 \uacc4\uc18d \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ud558\uace0 \uc2f6\ub2e4\uba74 \uc0c8\ub85c\uc6b4 \ucee4\ub125\uc158\uc744 \ub9fa\uc5b4\uc57c \ud55c\ub2e4."}),"\n"]})]}),"\n",(0,r.jsx)(t.h3,{id:"\uc6f9\uc18c\ucf13\uc758-\ub3d9\uc791",children:"\uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791"}),"\n",(0,r.jsx)(t.mermaid,{value:"sequenceDiagram\n participant Client\n participant Server\n Client->>Server: Handshake - Upgrade\ub97c \uc774\uc6a9\ud55c WebSocket \uc804\ud658 \uc694\uccad\n Server->>Client: Handshake - HttpStatus 101(Switching Protocols)\n\n Client->>Server: \uc591\ubc29\ud5a5 \ud1b5\uc2e0\n Server->>Client: \n\n Client->>Server: \uc885\ub8cc\n Server->>Client: "}),"\n",(0,r.jsx)(t.h3,{id:"1-upgrade-\uc694\uccad",children:"1. Upgrade \uc694\uccad"}),"\n",(0,r.jsxs)(t.p,{children:["WebSocket \ud504\ub85c\ud1a0\ucf5c\ub85c \uc804\ud658\ud558\ub294 HTTP \uc694\uccad\uc744 \ubcf4\ub0b8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub294 HTTP\uc640 \uac19\uc774 80, 443 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc6f9\uc18c\ucf13\uc73c\ub85c \uc804\ud658\ud558\uae30 \uc704\ud574\uc11c\ub294 Upgrade: websocket, Connection: Upgrade \ud5e4\ub354\uac00 \ud544\uc694\ud558\ub2e4.",(0,r.jsx)(t.br,{}),"\n","Sec-WebSocket-Key\ub294 \uc11c\ubc84\uc5d0\uc11c Sec-WebSocket-Accept\ub97c \uacc4\uc0b0\ud558\uc5ec \uc751\ub2f5\ud558\uace0 \uc774 \uac12\uc774 \uc608\uc0c1\ud55c \uac12\uacfc \ub2e4\ub974\uba74 \uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,r.jsx)(t.br,{}),"\n","Sec-WebSocket-Protocol\uc758 \uacbd\uc6b0 \uc11c\ube0c\ud504\ub85c\ud1a0\ucf5c\uc758 \ubaa9\ub85d\uc73c\ub85c \uc11c\ubc84 \uce21\uc5d0\uc11c\ub294 \ud574\ub2f9 \ubaa9\ub85d \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud558\uc5ec \ubc18\ud658\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub9cc\uc57d \uc11c\ubc84\uce21\uc5d0\uc11c \uc5ec\ub7ec \uac1c \uc9c0\uc6d0\uc774 \uac00\ub2a5\ud55c \uacbd\uc6b0 \uc9c0\uc6d0 \uac00\ub2a5\ud55c \ud504\ub85c\ud1a0\ucf5c \uc911 \uccab\ubc88\uc9f8 \ud504\ub85c\ud1a0\ucf5c\uc744 \ud074\ub77c\uc774\uc5b8\ud2b8\uce21\uc73c\ub85c \ubcf4\ub0b8\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"GET /chats HTTP/1.1\nHost: localhost:8080\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==\nSec-WebSocket-Protocol: v10.stomp, v11.stomp\nSec-WebSocket-Version: 13\nOrigin: http://localhost:8080\n"})}),"\n",(0,r.jsx)(t.h3,{id:"2-switching-protocols",children:"2. Switching Protocols"}),"\n",(0,r.jsxs)(t.p,{children:["\uc11c\ubc84\ub294 101 Switching Protocols \uc751\ub2f5\uc744 \ubc18\ud658\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","Sec-WebSocket-Accept\uc740 Sec-WebSocket-Key \ub4a4\uc5d0 ",(0,r.jsx)(t.code,{children:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"}),"\ub97c \ubd99\uc774\uace0 SHA1\ub85c \ud574\uc2f1 \ud6c4 Base64\ub85c \uc778\ucf54\ub529\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub294 \uc11c\ubc84 \uc6f9\uc18c\ucf13 \ud504\ub85c\ud1a0\ucf5c\uc758 \uc9c0\uc6d0 \uc5ec\ubd80\ub97c \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \uba85\ud655\ud788 \uc54c\ub9ac\uae30 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"HTTP/1.1 101 Switching Protocols \nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=\nSec-WebSocket-Protocol: v10.stomp\n"})}),"\n",(0,r.jsx)(t.h3,{id:"3-\ud1b5\uc2e0-\ud6c4-\uc885\ub8cc",children:"3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:["\uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uba74 \uc6f9\uc18c\ucf13 \ud504\ub808\uc784 \ub2e8\uc704\ub85c \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc5f0\uacb0 \uc885\ub8cc\ub97c \uc6d0\ud558\ub294 \uacbd\uc6b0 \ud074\ub77c\uc774\uc5b8\ud2b8, \uc11c\ubc84 \ubaa8\ub450 \uc5f0\uacb0 \uc885\ub8cc\ub97c \uc694\uccad\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc6455",children:"https://datatracker.ietf.org/doc/html/rfc6455"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications",children:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers",children:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://docs.spring.io/spring-framework/reference/web/websocket.html",children:"https://docs.spring.io/spring-framework/reference/web/websocket.html"})]})]})}function d(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>a});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},c=Object.keys(e);for(r=0;r<c.length;r++)n=c[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r<c.length;r++)n=c[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),a=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,c=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),h=a(n),b=o,g=h["".concat(l,".").concat(b)]||h[b]||p[b]||c;return n?r.createElement(g,i(i({ref:t},d),{},{components:n})):r.createElement(g,i({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/e21c8cc4.cea3918b.js b/assets/js/e21c8cc4.0c8d5bd8.js similarity index 81% rename from assets/js/e21c8cc4.cea3918b.js rename to assets/js/e21c8cc4.0c8d5bd8.js index 979b6cd47..d64006ec4 100644 --- a/assets/js/e21c8cc4.cea3918b.js +++ b/assets/js/e21c8cc4.0c8d5bd8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6049],{48765:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6049],{48765:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/e2326195.6b12f1d6.js b/assets/js/e2326195.6b12f1d6.js deleted file mode 100644 index d6fd0f6a3..000000000 --- a/assets/js/e2326195.6b12f1d6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9467],{3905:(e,n,t)=>{t.d(n,{Zo:()=>s,kt:()=>d});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function c(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?o(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function i(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)t=o[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),p=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},s=function(e){var n=p(e.components);return r.createElement(l.Provider,{value:n},e.children)},u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},g=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),g=p(t),d=a,m=g["".concat(l,".").concat(d)]||g[d]||u[d]||o;return t?r.createElement(m,c(c({ref:n},s),{},{components:t})):r.createElement(m,c({ref:n},s))}));function d(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var o=t.length,c=new Array(o);c[0]=g;var i={};for(var l in n)hasOwnProperty.call(n,l)&&(i[l]=n[l]);i.originalType=e,i.mdxType="string"==typeof e?e:a,c[1]=i;for(var p=2;p<o;p++)c[p]=t[p];return r.createElement.apply(null,c)}return r.createElement.apply(null,t)}g.displayName="MDXCreateElement"},8169:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>i,toc:()=>p});var r=t(87462),a=(t(67294),t(3905));const o={title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",slug:"log-async-exception",tags:["async","exception"]},c=void 0,i={permalink:"/log-async-exception",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",source:"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",description:"\ubb38\uc81c \uc0c1\ud669",date:"2023-09-18T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 18\uc77c",tags:[{label:"async",permalink:"/tags/async"},{label:"exception",permalink:"/tags/exception"}],readingTime:3.615,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",slug:"log-async-exception",tags:["async","exception"]},prevItem:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",permalink:"/web-application-evolution"},nextItem:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/tomcat-retrospective"}},l={authorsImageUrls:[]},p=[{value:"\ubb38\uc81c \uc0c1\ud669",id:"\ubb38\uc81c-\uc0c1\ud669",level:3},{value:"\ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815",id:"\ube44\ub3d9\uae30-\uc608\uc678-\ubc1c\uc0dd\uc2dc-\ub85c\uae45-\uc124\uc815",level:3},{value:"MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c",id:"mdc-\uc815\ubcf4-\uc5f0\ub3d9-\ubb38\uc81c",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:p};function u(e){let{components:n,...o}=e;return(0,a.kt)("wrapper",(0,r.Z)({},s,o,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\ubb38\uc81c-\uc0c1\ud669"},"\ubb38\uc81c \uc0c1\ud669"),(0,a.kt)("p",null,"\ud604\uc7ac \ud2b8\ub9bd\ub4dc\ub85c\uc6b0\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ub418\uace0 \uc788\ub2e4. \ub85c\uadf8\ub97c \ud655\uc778\ud558\ub294 \ub3c4\uc911 ",(0,a.kt)("inlineCode",{parentName:"p"},"@Async"),"\uac00 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ub85c\uadf8\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \ucd9c\ub825\ub418\uc9c0 \uc54a\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud655\uc778\ud574 \ubcf4\ub2c8 Spring\uc758 ",(0,a.kt)("inlineCode",{parentName:"p"},"@ControllerAdvice")," + ",(0,a.kt)("inlineCode",{parentName:"p"},"@ExceptionHandler"),"\uc758 \uacbd\uc6b0 \ub3d9\uae30 \uc608\uc678\ub9cc \ucc98\ub9ac\ud558\uace0, \ube44\ub3d9\uae30 \uc608\uc678\ub97c \ucc98\ub9ac\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \ubc1c\uc0dd\ud55c \ubb38\uc81c\uc600\ub2e4. "),(0,a.kt)("h3",{id:"\ube44\ub3d9\uae30-\uc608\uc678-\ubc1c\uc0dd\uc2dc-\ub85c\uae45-\uc124\uc815"},"\ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815"),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1 4.1 \ubd80\ud130 \uc81c\uacf5\ub418\ub294 ",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html"},"AsyncUncaughtExceptionHandler"),"\uc758 \uacbd\uc6b0 \ubc18\ud658 \ud0c0\uc785\uc774 void\uc778 \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\ub97c \uc608\uc678 \ucc98\ub9ac\ud558\uae30 \uc27d\ub3c4\ub85d \ub3c4\uc640\uc900\ub2e4. "),(0,a.kt)("p",null,"\ub530\ub77c\uc11c AsyncUncaughtExceptionHandler \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud574\uc11c \uc608\uc678\ub97c \ud578\ub4e4\ub9c1\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\uc874\uc758 \ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \uc608\uc678\uac00 \ubc1c\uc0dd\ud560 \ub54c \uc2e4\ud589 \ud750\ub984\uc744 \ucd94\uc801\ud558\uae30 \uc704\ud574 MDC(Mapped Diagnostic Context)\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\ub3c4 \ub9c8\ucc2c\uac00\uc9c0\ub85c MDC\uc758 \uc815\ubcf4\ub97c \uac00\uc838\uc640\uc11c \ub85c\uadf8\ub97c \ucd9c\ub825\ud558\ub3c4\ub85d \uc124\uc815\ud588\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AsyncExceptionHandler",title:"AsyncExceptionHandler"},'@Slf4j\npublic class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {\n\n private static final String LOG_FORMAT = "[%s] %s";\n\n @Override\n public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {\n log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);\n }\n}\n')),(0,a.kt)("p",null,"AsyncExceptionHandler\uc758 \uacbd\uc6b0 AsyncConfigurer\ub97c \uad6c\ud604\ud55c Configuration \ud074\ub798\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","getAsyncUncaughtExceptionHandler() \uba54\uc11c\ub4dc\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec AsyncExceptionHandler\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uba74 \ub41c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AsyncConfig",title:"AsyncConfig"},"@EnableAsync\n@Configuration\npublic class AsyncConfig implements AsyncConfigurer {\n\n @Override\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\n return new AsyncExceptionHandler();\n }\n}\n")),(0,a.kt)("p",null,"\uc774\uc81c \ube44\ub3d9\uae30 \uc0c1\ud669\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 AsyncUncaughtExceptionHandler\uc758 \uad6c\ud604\uccb4\uc778 AsyncExceptionHandler\uac00 \uc608\uc678\ub97c \uc7a1\uc544 \ucc98\ub9ac\ud55c\ub2e4. "),(0,a.kt)("h3",{id:"mdc-\uc815\ubcf4-\uc5f0\ub3d9-\ubb38\uc81c"},"MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c"),(0,a.kt)("p",null,"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \ubcc4\ub3c4\uc758 \uc2a4\ub808\ub4dc\uc5d0\uc11c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 ThreadLocal \uae30\ubc18\uc73c\ub85c \ub3d9\uc791\ud558\ub294 MDC\uc758 \uc815\ubcf4\ub97c \uc5bb\uc5b4\uc62c \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./mdc-null.png",src:t(81450).Z,width:"2236",height:"426"})),(0,a.kt)("p",null,"\uc2a4\ud504\ub9c1 4.3 \uc774\uc0c1\ubd80\ud130 \uc81c\uacf5\ub418\ub294 ",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html"},"TaskDecorator"),"\ub97c \uc774\uc6a9\ud558\uba74 TaskExecutor\ub97c \ucee4\uc2a4\ud130\ub9c8\uc774\uc9d5 \ud560 \uc218 \uc788\ub2e4. TaskDecorator\ub97c \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \ud558\ub098 \uc0dd\uc131\ud558\uace0, Task\uac00 \uc2e4\ud589\ub418\uae30 \uc804 MDC\uc758 \uc815\ubcf4\ub97c \ubcf5\uc0ac\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=MdcTaskDecorator",title:"MdcTaskDecorator"},"public class MdcTaskDecorator implements TaskDecorator {\n\n @Override\n public Runnable decorate(final Runnable runnable) {\n Map<String, String> threadContext = MDC.getCopyOfContextMap();\n return () -> {\n MDC.setContextMap(threadContext);\n runnable.run();\n };\n }\n}\n")),(0,a.kt)("p",null,"\uc0dd\uc131\ud55c Decorator \ud074\ub798\uc2a4\ub97c \uc124\uc815 \ud30c\uc77c\uc5d0 \ub4f1\ub85d\ud574 \uc900\ub2e4."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-java",metastring:"title=AsyncConfig",title:"AsyncConfig"},"@RequiredArgsConstructor\n@EnableAsync\n@Configuration\npublic class AsyncConfig implements AsyncConfigurer {\n\n private final AsyncConfigurationProperties properties;\n\n @Bean\n public ThreadPoolTaskExecutor taskExecutor() {\n ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();\n executor.setCorePoolSize(properties.coreSize());\n executor.setMaxPoolSize(properties.maxSize());\n executor.setQueueCapacity(properties.queueCapacity());\n \n // highlight-next-line\n executor.setTaskDecorator(new MdcTaskDecorator());\n executor.setWaitForTasksToCompleteOnShutdown(true);\n executor.initialize();\n return executor;\n }\n\n @Override\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\n return new AsyncExceptionHandler();\n }\n}\n")),(0,a.kt)("p",null,"\uc124\uc815 \ud6c4\uc5d0\ub294 \uc815\uc0c1\uc801\uc73c\ub85c MDC\uc5d0 \ub4e4\uc5b4\uac00 \uc788\ub294 UUID\uac00 \ucd9c\ub825\ub418\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4."),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"./mdc-not-null.png",src:t(97754).Z,width:"2620",height:"440"})),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://www.baeldung.com/spring-async"},"spring async, baeldung"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception"},"@Async will not call by @ControllerAdvice for global exception"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://blog.gangnamunni.com/post/mdc-context-task-decorator/"},"Spring \uc758 \ub3d9\uae30, \ube44\ub3d9\uae30, \ubc30\uce58 \ucc98\ub9ac\uc2dc \ud56d\uc0c1 context \ub97c \uc720\uc9c0\ud558\uace0 \ub85c\uae45\ud558\uae30, \uac15\ub0a8\uc5b8\ub2c8"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html"},"TaskDecorator, Spring docs"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html"},"AsyncUncaughtExceptionHandler")))}u.isMDXComponent=!0},97754:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/mdc-not-null-2b12c13f4f420a335c9e55dbea503f1b.png"},81450:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/mdc-null-95b3bbdce99ef36ba843986413e0421a.png"}}]); \ No newline at end of file diff --git a/assets/js/e2326195.c1345a1c.js b/assets/js/e2326195.c1345a1c.js new file mode 100644 index 000000000..878856abb --- /dev/null +++ b/assets/js/e2326195.c1345a1c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[9467],{45682:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var t=r(85893),c=r(3905);const a={title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",slug:"log-async-exception",tags:["async","exception"]},o=void 0,i={permalink:"/log-async-exception",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",source:"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",description:"\ubb38\uc81c \uc0c1\ud669",date:"2023-09-18T00:00:00.000Z",formattedDate:"2023\ub144 9\uc6d4 18\uc77c",tags:[{label:"async",permalink:"/tags/async"},{label:"exception",permalink:"/tags/exception"}],readingTime:3.615,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\ube44\ub3d9\uae30 \uc608\uc678 \ub85c\uae45",slug:"log-async-exception",tags:["async","exception"]},unlisted:!1,prevItem:{title:"\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815",permalink:"/web-application-evolution"},nextItem:{title:"\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0",permalink:"/tomcat-retrospective"}},s={authorsImageUrls:[]},l=[{value:"\ubb38\uc81c \uc0c1\ud669",id:"\ubb38\uc81c-\uc0c1\ud669",level:3},{value:"\ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815",id:"\ube44\ub3d9\uae30-\uc608\uc678-\ubc1c\uc0dd\uc2dc-\ub85c\uae45-\uc124\uc815",level:3},{value:"MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c",id:"mdc-\uc815\ubcf4-\uc5f0\ub3d9-\ubb38\uc81c",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const n={a:"a",br:"br",code:"code",h3:"h3",img:"img",p:"p",pre:"pre",...(0,c.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\ubb38\uc81c-\uc0c1\ud669",children:"\ubb38\uc81c \uc0c1\ud669"}),"\n",(0,t.jsxs)(n.p,{children:["\ud604\uc7ac \ud2b8\ub9bd\ub4dc\ub85c\uc6b0\uc758 \uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131 \uae30\ub2a5\uc740 \ube44\ub3d9\uae30\ub85c \ucc98\ub9ac\ub418\uace0 \uc788\ub2e4. \ub85c\uadf8\ub97c \ud655\uc778\ud558\ub294 \ub3c4\uc911 ",(0,t.jsx)(n.code,{children:"@Async"}),"\uac00 \uc801\uc6a9\ub41c \uba54\uc11c\ub4dc\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ub85c\uadf8\uac00 \uc815\uc0c1\uc801\uc73c\ub85c \ucd9c\ub825\ub418\uc9c0 \uc54a\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ud655\uc778\ud574 \ubcf4\ub2c8 Spring\uc758 ",(0,t.jsx)(n.code,{children:"@ControllerAdvice"})," + ",(0,t.jsx)(n.code,{children:"@ExceptionHandler"}),"\uc758 \uacbd\uc6b0 \ub3d9\uae30 \uc608\uc678\ub9cc \ucc98\ub9ac\ud558\uace0, \ube44\ub3d9\uae30 \uc608\uc678\ub97c \ucc98\ub9ac\ud558\uc9c0 \uc54a\uc558\uae30 \ub54c\ubb38\uc5d0 \ubc1c\uc0dd\ud55c \ubb38\uc81c\uc600\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ube44\ub3d9\uae30-\uc608\uc678-\ubc1c\uc0dd\uc2dc-\ub85c\uae45-\uc124\uc815",children:"\ube44\ub3d9\uae30 \uc608\uc678 \ubc1c\uc0dd\uc2dc \ub85c\uae45 \uc124\uc815"}),"\n",(0,t.jsxs)(n.p,{children:["\uc2a4\ud504\ub9c1 4.1 \ubd80\ud130 \uc81c\uacf5\ub418\ub294 ",(0,t.jsx)(n.a,{href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html",children:"AsyncUncaughtExceptionHandler"}),"\uc758 \uacbd\uc6b0 \ubc18\ud658 \ud0c0\uc785\uc774 void\uc778 \ube44\ub3d9\uae30 \uba54\uc11c\ub4dc\ub97c \uc608\uc678 \ucc98\ub9ac\ud558\uae30 \uc27d\ub3c4\ub85d \ub3c4\uc640\uc900\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\ub530\ub77c\uc11c AsyncUncaughtExceptionHandler \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud574\uc11c \uc608\uc678\ub97c \ud578\ub4e4\ub9c1\ud558\ub294 \ud074\ub798\uc2a4\ub97c \uc0dd\uc131\ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae30\uc874\uc758 \ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \uc608\uc678\uac00 \ubc1c\uc0dd\ud560 \ub54c \uc2e4\ud589 \ud750\ub984\uc744 \ucd94\uc801\ud558\uae30 \uc704\ud574 MDC(Mapped Diagnostic Context)\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac\ub3c4 \ub9c8\ucc2c\uac00\uc9c0\ub85c MDC\uc758 \uc815\ubcf4\ub97c \uac00\uc838\uc640\uc11c \ub85c\uadf8\ub97c \ucd9c\ub825\ud558\ub3c4\ub85d \uc124\uc815\ud588\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=AsyncExceptionHandler",children:'@Slf4j\npublic class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {\n\n private static final String LOG_FORMAT = "[%s] %s";\n\n @Override\n public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {\n log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["AsyncExceptionHandler\uc758 \uacbd\uc6b0 AsyncConfigurer\ub97c \uad6c\ud604\ud55c Configuration \ud074\ub798\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub4f1\ub85d\ud560 \uc218 \uc788\ub2e4.",(0,t.jsx)(n.br,{}),"\n","getAsyncUncaughtExceptionHandler() \uba54\uc11c\ub4dc\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec AsyncExceptionHandler\ub97c \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=AsyncConfig",children:"@EnableAsync\n@Configuration\npublic class AsyncConfig implements AsyncConfigurer {\n\n @Override\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\n return new AsyncExceptionHandler();\n }\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"\uc774\uc81c \ube44\ub3d9\uae30 \uc0c1\ud669\uc5d0\uc11c \uc608\uc678\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 AsyncUncaughtExceptionHandler\uc758 \uad6c\ud604\uccb4\uc778 AsyncExceptionHandler\uac00 \uc608\uc678\ub97c \uc7a1\uc544 \ucc98\ub9ac\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.h3,{id:"mdc-\uc815\ubcf4-\uc5f0\ub3d9-\ubb38\uc81c",children:"MDC \uc815\ubcf4 \uc5f0\ub3d9 \ubb38\uc81c"}),"\n",(0,t.jsx)(n.p,{children:"\ube44\ub3d9\uae30 \ucc98\ub9ac\uc758 \uacbd\uc6b0 \ubcc4\ub3c4\uc758 \uc2a4\ub808\ub4dc\uc5d0\uc11c \ub3d9\uc791\ud558\uae30 \ub54c\ubb38\uc5d0 ThreadLocal \uae30\ubc18\uc73c\ub85c \ub3d9\uc791\ud558\ub294 MDC\uc758 \uc815\ubcf4\ub97c \uc5bb\uc5b4\uc62c \uc218 \uc5c6\ub294 \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"./mdc-null.png",src:r(81450).Z+"",width:"2236",height:"426"})}),"\n",(0,t.jsxs)(n.p,{children:["\uc2a4\ud504\ub9c1 4.3 \uc774\uc0c1\ubd80\ud130 \uc81c\uacf5\ub418\ub294 ",(0,t.jsx)(n.a,{href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html",children:"TaskDecorator"}),"\ub97c \uc774\uc6a9\ud558\uba74 TaskExecutor\ub97c \ucee4\uc2a4\ud130\ub9c8\uc774\uc9d5 \ud560 \uc218 \uc788\ub2e4. TaskDecorator\ub97c \uad6c\ud604\ud55c \ud074\ub798\uc2a4\ub97c \ud558\ub098 \uc0dd\uc131\ud558\uace0, Task\uac00 \uc2e4\ud589\ub418\uae30 \uc804 MDC\uc758 \uc815\ubcf4\ub97c \ubcf5\uc0ac\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=MdcTaskDecorator",children:"public class MdcTaskDecorator implements TaskDecorator {\n\n @Override\n public Runnable decorate(final Runnable runnable) {\n Map<String, String> threadContext = MDC.getCopyOfContextMap();\n return () -> {\n MDC.setContextMap(threadContext);\n runnable.run();\n };\n }\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"\uc0dd\uc131\ud55c Decorator \ud074\ub798\uc2a4\ub97c \uc124\uc815 \ud30c\uc77c\uc5d0 \ub4f1\ub85d\ud574 \uc900\ub2e4."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-java",metastring:"title=AsyncConfig",children:"@RequiredArgsConstructor\n@EnableAsync\n@Configuration\npublic class AsyncConfig implements AsyncConfigurer {\n\n private final AsyncConfigurationProperties properties;\n\n @Bean\n public ThreadPoolTaskExecutor taskExecutor() {\n ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();\n executor.setCorePoolSize(properties.coreSize());\n executor.setMaxPoolSize(properties.maxSize());\n executor.setQueueCapacity(properties.queueCapacity());\n \n // highlight-next-line\n executor.setTaskDecorator(new MdcTaskDecorator());\n executor.setWaitForTasksToCompleteOnShutdown(true);\n executor.initialize();\n return executor;\n }\n\n @Override\n public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {\n return new AsyncExceptionHandler();\n }\n}\n"})}),"\n",(0,t.jsx)(n.p,{children:"\uc124\uc815 \ud6c4\uc5d0\ub294 \uc815\uc0c1\uc801\uc73c\ub85c MDC\uc5d0 \ub4e4\uc5b4\uac00 \uc788\ub294 UUID\uac00 \ucd9c\ub825\ub418\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"./mdc-not-null.png",src:r(97754).Z+"",width:"2620",height:"440"})}),"\n",(0,t.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://www.baeldung.com/spring-async",children:"spring async, baeldung"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception",children:"@Async will not call by @ControllerAdvice for global exception"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://blog.gangnamunni.com/post/mdc-context-task-decorator/",children:"Spring \uc758 \ub3d9\uae30, \ube44\ub3d9\uae30, \ubc30\uce58 \ucc98\ub9ac\uc2dc \ud56d\uc0c1 context \ub97c \uc720\uc9c0\ud558\uace0 \ub85c\uae45\ud558\uae30, \uac15\ub0a8\uc5b8\ub2c8"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html",children:"TaskDecorator, Spring docs"}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.a,{href:"https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html",children:"AsyncUncaughtExceptionHandler"})]})]})}function d(e={}){const{wrapper:n}={...(0,c.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>l});var t=r(67294);function c(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function a(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function o(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?a(Object(r),!0).forEach((function(n){c(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function i(e,n){if(null==e)return{};var r,t,c=function(e,n){if(null==e)return{};var r,t,c={},a=Object.keys(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||(c[r]=e[r]);return c}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(t=0;t<a.length;t++)r=a[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var s=t.createContext({}),l=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):o(o({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,c=e.mdxType,a=e.originalType,s=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=l(r),g=c,h=u["".concat(s,".").concat(g)]||u[g]||p[g]||a;return r?t.createElement(h,o(o({ref:n},d),{},{components:r})):t.createElement(h,o({ref:n},d))}));d.displayName="MDXCreateElement"},97754:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/mdc-not-null-2b12c13f4f420a335c9e55dbea503f1b.png"},81450:(e,n,r)=>{r.d(n,{Z:()=>t});const t=r.p+"assets/images/mdc-null-95b3bbdce99ef36ba843986413e0421a.png"}}]); \ No newline at end of file diff --git a/assets/js/e2de2dbb.9ac0053b.js b/assets/js/e2de2dbb.441ed42b.js similarity index 88% rename from assets/js/e2de2dbb.9ac0053b.js rename to assets/js/e2de2dbb.441ed42b.js index f57c0780d..b2ac4d4d8 100644 --- a/assets/js/e2de2dbb.9ac0053b.js +++ b/assets/js/e2de2dbb.441ed42b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6710],{47023:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6710],{47023:a=>{a.exports=JSON.parse('{"label":"Java","permalink":"/tags/java","allTagsPath":"/tags","count":5,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/e5e44a85.87bbc8e5.js b/assets/js/e5e44a85.f463dc37.js similarity index 89% rename from assets/js/e5e44a85.87bbc8e5.js rename to assets/js/e5e44a85.f463dc37.js index 60ae78418..eae32d43f 100644 --- a/assets/js/e5e44a85.87bbc8e5.js +++ b/assets/js/e5e44a85.f463dc37.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1253],{42310:e=>{e.exports=JSON.parse('{"label":"deploy","permalink":"/docs/tags/deploy","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","title":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","description":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","permalink":"/docs/deploy/zero-downtime"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1253],{42310:e=>{e.exports=JSON.parse('{"label":"deploy","permalink":"/docs/tags/deploy","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","title":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","description":"\ubb34\uc911\ub2e8 \ubc30\ud3ec","permalink":"/docs/deploy/zero-downtime"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/e6a6ed43.a7a88c94.js b/assets/js/e6a6ed43.a7a88c94.js new file mode 100644 index 000000000..6c7366a8f --- /dev/null +++ b/assets/js/e6a6ed43.a7a88c94.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5300],{66940:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>a});var i=r(85893),l=r(3905);const t={title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",slug:"grasp",tags:["GRASP","OOP"]},s=void 0,o={permalink:"/grasp",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-30-GRASP.mdx",source:"@site/blog/2023-1/2023-03-30-GRASP.mdx",title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",description:"GRASP(General Responsibility Assignment Software Pattern)",date:"2023-03-30T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 30\uc77c",tags:[{label:"GRASP",permalink:"/tags/grasp"},{label:"OOP",permalink:"/tags/oop"}],readingTime:8.085,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",slug:"grasp",tags:["GRASP","OOP"]},unlisted:!1,prevItem:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",permalink:"/chess-retrospective"},nextItem:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",permalink:"/blackjack-retrospective"}},c={authorsImageUrls:[]},a=[{value:"GRASP(General Responsibility Assignment Software Pattern)",id:"graspgeneral-responsibility-assignment-software-pattern",level:3},{value:"\uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)",id:"\uc815\ubcf4-\uc804\ubb38\uac00-\ud328\ud134information-expert",level:3},{value:"\ucc3d\uc870\uc790 \ud328\ud134(Creator)",id:"\ucc3d\uc870\uc790-\ud328\ud134creator",level:3},{value:"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)",id:"\ub0ae\uc740-\uacb0\ud569\ub3c4-\ud328\ud134low-coupling",level:3},{value:"\ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)",id:"\ub192\uc740-\uc751\uc9d1\ub3c4-\ud328\ud134high-cohesion",level:3},{value:"\ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)",id:"\ucee8\ud2b8\ub864\ub7ec-\ud328\ud134controller",level:3},{value:"\ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)",id:"\ub2e4\ud615\uc131-\ud328\ud134polymorphism",level:3},{value:"\ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)",id:"\ubcc0\uacbd-\ubcf4\ud638-\ud328\ud134protected-variations",level:3},{value:"\uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)",id:"\uac04\uc811-\ucc38\uc870-\ud328\ud134indirection",level:3},{value:"\uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)",id:"\uc21c\uc218\ud55c-\uac00\uacf5\ubb3c-\ud328\ud134pure-fabrication",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",h3:"h3",li:"li",p:"p",ul:"ul",...(0,l.ah)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"graspgeneral-responsibility-assignment-software-pattern",children:"GRASP(General Responsibility Assignment Software Pattern)"}),"\n",(0,i.jsx)(n.p,{children:"\ud06c\ub808\uc774\uadf8 \ub77c\ub9cc\uc758 Applying UML and Patterns\uc774\ub77c\ub294 \ucc45\uc5d0\uc11c \ub098\uc628 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134"}),"\n",(0,i.jsx)(n.p,{children:"\uac01 \ud328\ud134\ub9c8\ub2e4 Solution\uacfc Problem\ub85c \uad6c\uc131\ub418\uc5b4 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\uc815\ubcf4-\uc804\ubb38\uac00-\ud328\ud134information-expert",children:"\uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)"}),"\n",(0,i.jsx)(n.p,{children:"Q: \uac1d\uccb4\uc5d0 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uae30\ubcf8 \uc6d0\uce59\uc740 \ubb34\uc5c7\uc778\uac00?"}),"\n",(0,i.jsx)(n.p,{children:"A: \ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub370 \ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \ud074\ub798\uc2a4(\uc815\ubcf4 \uc804\ubb38\uac00)\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc815\ubcf4\uc640 \ud589\ub3d9\uc744 \uac00\uae4c\uc6b4 \uacf3\uc5d0 \uc704\uce58\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \ucea1\uc290\ud654\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \uac1d\uccb4\ub4e4\ub85c \ucc45\uc784\uc774 \ubd84\uc0b0\ub41c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\ucc3d\uc870\uc790-\ud328\ud134creator",children:"\ucc3d\uc870\uc790 \ud328\ud134(Creator)"}),"\n",(0,i.jsx)(n.p,{children:"Q: \ub204\uac00 \uac1d\uccb4 A\ub97c \uc0dd\uc131\ud558\ub294\uac00?"}),"\n",(0,i.jsx)(n.p,{children:"A: \ub2e4\uc74c\uc758 \uc870\uac74\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\uc871\ud558\ub294 \uac1d\uccb4\uc5d0\uac8c \uac1d\uccb4 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\uc758 \ucd08\uae30\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"\uc0dd\uc131 \uc608\uc815\uc778 \uac1d\uccb4\uc640 \uc5f0\uad00\ub418\uc5b4 \uc788\ub294 \uac1d\uccb4\uac00 \uc0dd\uc131 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uac8c \ub41c\ub2e4\uba74, \uc774\ubbf8 \ud574\ub2f9 \uac1d\uccb4\uc640 \uacb0\ud569\ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\uac8c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\ub0ae\uc740-\uacb0\ud569\ub3c4-\ud328\ud134low-coupling",children:"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)"}),"\n",(0,i.jsx)(n.p,{children:"Q: \uc758\uc874\uc131\uc744 \ub0ae\ucd94\uace0 \ubcc0\ud654\uc758 \uc601\ud5a5\uc744 \uc904\uc774\uba70 \uc7ac\uc0ac\uc6a9\uc131\uc744 \uc99d\uac00\uc2dc\ud0a4\ub294 \ubc29\ubc95\uc740?"}),"\n",(0,i.jsx)(n.p,{children:"A: \uc804\uccb4\uc801\uc778 \uacb0\ud569\uc774 \ub0ae\uac8c \uc720\uc9c0\ub418\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"\uacb0\ud569\ub3c4(Coupling)\n\uac1d\uccb4 \uc0ac\uc774\uc758 \uc758\uc874\uc131\uc774 \uacfc\ud55c \uacbd\uc6b0 \uacb0\ud569\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc624\ube0c\uc81d\ud2b8 p.17"}),"\n"]}),"\n",(0,i.jsx)(n.blockquote,{children:"\n"}),"\n",(0,i.jsx)(n.p,{children:"\uacb0\ud569\ub3c4\ub97c \ub0ae\ucd98\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\uc758 \ubcc0\ud654\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\uc7ac\uc0ac\uc6a9\uc774 \ud3b8\ub9ac\ud574\uc9c4\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\uc758\uc874\ud558\ub294 \ud074\ub798\uc2a4\uac00 \uc801\uae30 \ub54c\ubb38\uc5d0)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ub192\uc740-\uc751\uc9d1\ub3c4-\ud328\ud134high-cohesion",children:"\ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \uac1d\uccb4\ub97c \uad00\ub9ac\ud558\uae30 \uc27d\uac8c \ud558\ub824\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. \ub192\uc740 \uc751\uc9d1\ub3c4\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"\uc751\uc9d1\ub3c4(Cohesion)\n\uc5f0\uad00\ub41c \uc791\uc5c5\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc5f0\uad00\uc131 \uc5c6\ub294 \uc791\uc5c5\uc740 \ub2e4\ub978 \uac1d\uccb4\uc5d0\uac8c \uc704\uc784\ud558\ub294 \uac1d\uccb4\ub97c \uac00\ub9ac\ucf1c \uc751\uc9d1\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc624\ube0c\uc81d\ud2b8 p.26"}),"\n"]}),"\n",(0,i.jsx)(n.blockquote,{children:"\n"}),"\n",(0,i.jsx)(n.p,{children:"\ubcc0\uacbd\uc758 \uc774\uc720\uc5d0 \ub530\ub77c \ud074\ub798\uc2a4\ub97c \ubd84\ub9ac\ud55c\ub2e4\uba74 \uc751\uc9d1\ub3c4\ub97c \ub192\uc77c \uc218 \uc788\uace0, \uc751\uc9d1\ub3c4\uac00 \ub192\uc544\uc9c4\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\ud560\ub2f9\ub41c \ucc45\uc784\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0)"}),"\n",(0,i.jsx)(n.li,{children:"\uc720\uc9c0\ubcf4\uc218\uac00 \uc26c\uc6cc\uc9c4\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ub610\ud55c \uc9c0\uc6d0\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\uc751\uc9d1\ub3c4\uac00 \ub192\uc740 \ud074\ub798\uc2a4\ub294 \ud2b9\uc815\ud55c \ubaa9\uc801\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc7ac\uc0ac\uc6a9\ud558\uae30 \uc88b\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ucee8\ud2b8\ub864\ub7ec-\ud328\ud134controller",children:"\ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uac83\uc740 \ub204\uac00 \ub2f4\ub2f9\ud574\uc57c \ud558\ub294\uac00?"}),"\n",(0,i.jsx)(n.p,{children:"A. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 Controller \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc5b4\ub5a4 \uc11c\ube0c\uc2dc\uc2a4\ud15c\uc774 \uc874\uc7ac\ud55c\ub2e4\uace0 \uac00\uc815\ud560 \ub54c"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc9c1\uc811\uc801\uc73c\ub85c \uac1d\uccb4\uc5d0 \uc811\uadfc\ud558\uc5ec \ud504\ub85c\uadf8\ub7a8\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uacb0\ud569\ub3c4\uac00 \uc0c1\uc2b9\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\uc11c\ube0c \uc2dc\uc2a4\ud15c\uc5d0 \ub4e4\uc5b4\uc624\ub294 \uc694\uccad\uc744 \ucc98\ub9ac\ud574\uc8fc\ub294 \ucee8\ud2b8\ub864\ub7ec\uac00 \uc788\ub2e4\uba74 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 \ud574\ub2f9 \ucee8\ud2b8\ub864\ub7ec\ub9cc \uc54c\uba74 \ub41c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\ub9cc\uc57d \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc758 \ubcc0\uacbd\uc774 \uc0dd\uacbc\uc744 \ub54c \uc678\ubd80\uc5d0 \ubbf8\uce58\ub294 \uc601\ud5a5\ub3c4 \uc904\uc5b4\ub4e0\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ub2e4\ud615\uc131-\ud328\ud134polymorphism",children:"\ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \uac1d\uccb4\uc758 \ud0c0\uc785\uc5d0 \ub530\ub77c \ud589\ub3d9\uc774 \ubc14\ub010\ub2e4\uba74 \ucc45\uc784\uc744 \uc5b4\ub5bb\uac8c \ud560\ub2f9\ud574\uc57c \ud560\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. OOP\uac00 \uc9c0\uc6d0\ud558\ub294 \ub2e4\ud615\uc131\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ud65c\uc6a9\ud55c\ub2e4. (\uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0 \ud589\ub3d9\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uad6c\ud604)"}),"\n",(0,i.jsx)(n.p,{children:"\uac1d\uccb4\uc758 \uc885\ub958\uc5d0 \ub530\ub77c \ubd84\uae30\ud558\ub294 \uc870\uac74\ubb38\uc774 \uc544\ub2cc \ub2e4\ud615\uc131\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc0c8\ub85c\uc6b4 \ud0c0\uc785\uc774 \ucd94\uac00\ub418\uc5c8\uc744 \ub54c \uc870\uac74\ubb38\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uae30\uc874\uc758 \uc870\uac74\ubb38\uc744 \uc218\uc815\ud574\uc57c \ud558\uc9c0\ub9cc \ub2e4\ud615\uc131\uc744 \ud65c\uc6a9\ud558\uba74 \uc27d\uac8c \ud655\uc7a5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\ubcc0\uacbd-\ubcf4\ud638-\ud328\ud134protected-variations",children:"\ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \uc5b4\ub5bb\uac8c \ud558\uba74 \ubcc0\uacbd\uc774 \ub2e4\ub978 \uc694\uc18c\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub3c4\ub85d \ubc29\uc9c0\ud560 \uc218 \uc788\uc744\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. \ubcc0\ud654\uac00 \uc608\uc0c1\ub418\ub294 \uc9c0\uc810\uc744 \uc2dd\ubcc4\ud558\uace0, \uc8fc\uc704\uc5d0 \uc548\uc815\ub41c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ud615\uc131\ud558\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\uac04\uc811-\ucc38\uc870-\ud328\ud134indirection",children:"\uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc758 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud558\uace0 \uc2f6\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ub2e4\ub978 \uac1d\uccb4\ub97c \ub450\uc5b4 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc911\uc7ac\uc790 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ud558\ub098\uc758 \uac1d\uccb4\ub97c \ucd94\uac00\ud558\uc5ec \ubcf5\uc7a1\ud55c \uad00\uacc4\ub97c \ub2e8\uc21c\ud654\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc911\uac04\uc5d0 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub454\ub2e4\uba74 \ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)\uc5d0 \ud574\ub2f9\ub41c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\uc21c\uc218\ud55c-\uac00\uacf5\ubb3c-\ud328\ud134pure-fabrication",children:"\uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \ucc45\uc784\uc744 \ud560\ub2f9\ud55c \ub3c4\uba54\uc778 \uac1d\uccb4\uac00 Low Coupling, High Cohesion, \uc7ac\uc0ac\uc6a9\uc131 \ub4f1\uc758 \ubaa9\uc801\uc744 \uc704\ubc18\ud55c\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. \ub3c4\uba54\uc778 \uac1c\ub150\uc744 \ud3ec\ud568\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uace0 \ub9e4\uc6b0 \uc751\uc9d1\ub41c \ucc45\uc784\uc744 \ud560\ub2f9\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\ud589\ub3d9\uc744 \ucd94\uac00\ud560 \ub54c, \ud574\ub2f9 \ucc45\uc784\uc744 \uc218\ud589\ud560 \ub3c4\uba54\uc778 \uac1c\ub150\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \ub3c4\uba54\uc778\uacfc \ubb34\uad00\ud55c \uc778\uacf5\uc801\uc778 \uac1d\uccb4\ub97c \ub9cc\ub4e0\ub2e4\uc74c \ud574\ub2f9 \uac1d\uccb4\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uac1d\uccb4\uac00 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud574\uc57c \ud560 \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4\uace0, \uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134\uc744 \uc801\uc6a9\ud558\uc5ec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud558\ub77c\ub294 \ucc45\uc784\uc744 \uac00\uc9c0\ub77c\uace0 \ud558\uc9c0 \uc54a\ub294\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc608) \uc0c1\uc810\uacfc \uace0\uac1d \ud074\ub798\uc2a4\uac00 \uc788\uace0 \uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uace0 \uac00\uc815"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0 \uac70\ub798\ub97c \ud558\ub824\uba74 \ud658\uc804\uc744 \ud574\uc57c\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\ub450 \ud074\ub798\uc2a4 \ub2e4 \ud658\uc804\uc5d0 \ub300\ud55c \ucc45\uc784\uc744 \ubd80\uc5ec\ud558\uae30 \uc560\ub9e4\ud558\ub2e4\uba74 \ud658\uc804\uc744 \ucc45\uc784\ud558\ub294 \ud074\ub798\uc2a4\ub97c \ucd94\uac00\ud558\uace0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,i.jsxs)(n.p,{children:["\uc624\ube0c\uc81d\ud2b8 5\uc7a5. \ucc45\uc784 \ud560\ub2f9\ud558\uae30, ",(0,i.jsx)(n.a,{href:"http://aeternum.egloos.com/",children:"\uc870\uc601\ud638"})]}),"\n",(0,i.jsx)(n.p,{children:"Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://www.hanbit.co.kr/network/category/category_view.html?cms_code=CMS8586826397",children:"GRASP, \ud55c\ube5b \ub124\ud2b8\uc6cc\ud06c"})})]})}function h(e={}){const{wrapper:n}={...(0,l.ah)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var i=r(67294);function l(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function t(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,i)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?t(Object(r),!0).forEach((function(n){l(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):t(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function o(e,n){if(null==e)return{};var r,i,l=function(e,n){if(null==e)return{};var r,i,l={},t=Object.keys(e);for(i=0;i<t.length;i++)r=t[i],n.indexOf(r)>=0||(l[r]=e[r]);return l}(e,n);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);for(i=0;i<t.length;i++)r=t[i],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(l[r]=e[r])}return l}var c=i.createContext({}),a=function(e){var n=i.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},h=i.forwardRef((function(e,n){var r=e.components,l=e.mdxType,t=e.originalType,c=e.parentName,h=o(e,["components","mdxType","originalType","parentName"]),p=a(r),j=l,x=p["".concat(c,".").concat(j)]||p[j]||d[j]||t;return r?i.createElement(x,s(s({ref:n},h),{},{components:r})):i.createElement(x,s({ref:n},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/e6a6ed43.db308191.js b/assets/js/e6a6ed43.db308191.js deleted file mode 100644 index 0c3ebfd8f..000000000 --- a/assets/js/e6a6ed43.db308191.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5300],{3905:(e,t,l)=>{l.d(t,{Zo:()=>c,kt:()=>m});var n=l(67294);function r(e,t,l){return t in e?Object.defineProperty(e,t,{value:l,enumerable:!0,configurable:!0,writable:!0}):e[t]=l,e}function a(e,t){var l=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),l.push.apply(l,n)}return l}function o(e){for(var t=1;t<arguments.length;t++){var l=null!=arguments[t]?arguments[t]:{};t%2?a(Object(l),!0).forEach((function(t){r(e,t,l[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(l)):a(Object(l)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(l,t))}))}return e}function i(e,t){if(null==e)return{};var l,n,r=function(e,t){if(null==e)return{};var l,n,r={},a=Object.keys(e);for(n=0;n<a.length;n++)l=a[n],t.indexOf(l)>=0||(r[l]=e[l]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)l=a[n],t.indexOf(l)>=0||Object.prototype.propertyIsEnumerable.call(e,l)&&(r[l]=e[l])}return r}var p=n.createContext({}),u=function(e){var t=n.useContext(p),l=t;return e&&(l="function"==typeof e?e(t):o(o({},t),e)),l},c=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var l=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),k=u(l),m=r,g=k["".concat(p,".").concat(m)]||k[m]||s[m]||a;return l?n.createElement(g,o(o({ref:t},c),{},{components:l})):n.createElement(g,o({ref:t},c))}));function m(e,t){var l=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=l.length,o=new Array(a);o[0]=k;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var u=2;u<a;u++)o[u]=l[u];return n.createElement.apply(null,o)}return n.createElement.apply(null,l)}k.displayName="MDXCreateElement"},19463:(e,t,l)=>{l.r(t),l.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>s,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var n=l(87462),r=(l(67294),l(3905));const a={title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",slug:"grasp",tags:["GRASP","OOP"]},o=void 0,i={permalink:"/grasp",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-30-GRASP.mdx",source:"@site/blog/2023-1/2023-03-30-GRASP.mdx",title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",description:"GRASP(General Responsibility Assignment Software Pattern)",date:"2023-03-30T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 30\uc77c",tags:[{label:"GRASP",permalink:"/tags/grasp"},{label:"OOP",permalink:"/tags/oop"}],readingTime:8.085,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",slug:"grasp",tags:["GRASP","OOP"]},prevItem:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",permalink:"/chess-retrospective"},nextItem:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",permalink:"/blackjack-retrospective"}},p={authorsImageUrls:[]},u=[{value:"GRASP(General Responsibility Assignment Software Pattern)",id:"graspgeneral-responsibility-assignment-software-pattern",level:3},{value:"\uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)",id:"\uc815\ubcf4-\uc804\ubb38\uac00-\ud328\ud134information-expert",level:3},{value:"\ucc3d\uc870\uc790 \ud328\ud134(Creator)",id:"\ucc3d\uc870\uc790-\ud328\ud134creator",level:3},{value:"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)",id:"\ub0ae\uc740-\uacb0\ud569\ub3c4-\ud328\ud134low-coupling",level:3},{value:"\ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)",id:"\ub192\uc740-\uc751\uc9d1\ub3c4-\ud328\ud134high-cohesion",level:3},{value:"\ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)",id:"\ucee8\ud2b8\ub864\ub7ec-\ud328\ud134controller",level:3},{value:"\ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)",id:"\ub2e4\ud615\uc131-\ud328\ud134polymorphism",level:3},{value:"\ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)",id:"\ubcc0\uacbd-\ubcf4\ud638-\ud328\ud134protected-variations",level:3},{value:"\uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)",id:"\uac04\uc811-\ucc38\uc870-\ud328\ud134indirection",level:3},{value:"\uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)",id:"\uc21c\uc218\ud55c-\uac00\uacf5\ubb3c-\ud328\ud134pure-fabrication",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:u};function s(e){let{components:t,...l}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,l,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"graspgeneral-responsibility-assignment-software-pattern"},"GRASP(General Responsibility Assignment Software Pattern)"),(0,r.kt)("p",null,"\ud06c\ub808\uc774\uadf8 \ub77c\ub9cc\uc758 Applying UML and Patterns\uc774\ub77c\ub294 \ucc45\uc5d0\uc11c \ub098\uc628 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134"),(0,r.kt)("p",null,"\uac01 \ud328\ud134\ub9c8\ub2e4 Solution\uacfc Problem\ub85c \uad6c\uc131\ub418\uc5b4 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\uc815\ubcf4-\uc804\ubb38\uac00-\ud328\ud134information-expert"},"\uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)"),(0,r.kt)("p",null,"Q: \uac1d\uccb4\uc5d0 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uae30\ubcf8 \uc6d0\uce59\uc740 \ubb34\uc5c7\uc778\uac00?"),(0,r.kt)("p",null,"A: \ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub370 \ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \ud074\ub798\uc2a4(\uc815\ubcf4 \uc804\ubb38\uac00)\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4."),(0,r.kt)("p",null,"\uc815\ubcf4\uc640 \ud589\ub3d9\uc744 \uac00\uae4c\uc6b4 \uacf3\uc5d0 \uc704\uce58\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \ucea1\uc290\ud654\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,"\ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \uac1d\uccb4\ub4e4\ub85c \ucc45\uc784\uc774 \ubd84\uc0b0\ub41c\ub2e4."),(0,r.kt)("h3",{id:"\ucc3d\uc870\uc790-\ud328\ud134creator"},"\ucc3d\uc870\uc790 \ud328\ud134(Creator)"),(0,r.kt)("p",null,"Q: \ub204\uac00 \uac1d\uccb4 A\ub97c \uc0dd\uc131\ud558\ub294\uac00?"),(0,r.kt)("p",null,"A: \ub2e4\uc74c\uc758 \uc870\uac74\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\uc871\ud558\ub294 \uac1d\uccb4\uc5d0\uac8c \uac1d\uccb4 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\uc758 \ucd08\uae30\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4.")),(0,r.kt)("p",null,"\uc0dd\uc131 \uc608\uc815\uc778 \uac1d\uccb4\uc640 \uc5f0\uad00\ub418\uc5b4 \uc788\ub294 \uac1d\uccb4\uac00 \uc0dd\uc131 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uac8c \ub41c\ub2e4\uba74, \uc774\ubbf8 \ud574\ub2f9 \uac1d\uccb4\uc640 \uacb0\ud569\ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\uac8c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\ub0ae\uc740-\uacb0\ud569\ub3c4-\ud328\ud134low-coupling"},"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)"),(0,r.kt)("p",null,"Q: \uc758\uc874\uc131\uc744 \ub0ae\ucd94\uace0 \ubcc0\ud654\uc758 \uc601\ud5a5\uc744 \uc904\uc774\uba70 \uc7ac\uc0ac\uc6a9\uc131\uc744 \uc99d\uac00\uc2dc\ud0a4\ub294 \ubc29\ubc95\uc740?"),(0,r.kt)("p",null,"A: \uc804\uccb4\uc801\uc778 \uacb0\ud569\uc774 \ub0ae\uac8c \uc720\uc9c0\ub418\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\uacb0\ud569\ub3c4(Coupling)\n\uac1d\uccb4 \uc0ac\uc774\uc758 \uc758\uc874\uc131\uc774 \uacfc\ud55c \uacbd\uc6b0 \uacb0\ud569\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4."),(0,r.kt)("ul",{parentName:"blockquote"},(0,r.kt)("li",{parentName:"ul"},"\uc624\ube0c\uc81d\ud2b8 p.17"))),(0,r.kt)("p",null,"\uacb0\ud569\ub3c4\ub97c \ub0ae\ucd98\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\uc758 \ubcc0\ud654\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc7ac\uc0ac\uc6a9\uc774 \ud3b8\ub9ac\ud574\uc9c4\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\uc758\uc874\ud558\ub294 \ud074\ub798\uc2a4\uac00 \uc801\uae30 \ub54c\ubb38\uc5d0)")),(0,r.kt)("h3",{id:"\ub192\uc740-\uc751\uc9d1\ub3c4-\ud328\ud134high-cohesion"},"\ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)"),(0,r.kt)("p",null,"Q. \uac1d\uccb4\ub97c \uad00\ub9ac\ud558\uae30 \uc27d\uac8c \ud558\ub824\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"),(0,r.kt)("p",null,"A. \ub192\uc740 \uc751\uc9d1\ub3c4\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\uc751\uc9d1\ub3c4(Cohesion)\n\uc5f0\uad00\ub41c \uc791\uc5c5\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc5f0\uad00\uc131 \uc5c6\ub294 \uc791\uc5c5\uc740 \ub2e4\ub978 \uac1d\uccb4\uc5d0\uac8c \uc704\uc784\ud558\ub294 \uac1d\uccb4\ub97c \uac00\ub9ac\ucf1c \uc751\uc9d1\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4."),(0,r.kt)("ul",{parentName:"blockquote"},(0,r.kt)("li",{parentName:"ul"},"\uc624\ube0c\uc81d\ud2b8 p.26"))),(0,r.kt)("p",null,"\ubcc0\uacbd\uc758 \uc774\uc720\uc5d0 \ub530\ub77c \ud074\ub798\uc2a4\ub97c \ubd84\ub9ac\ud55c\ub2e4\uba74 \uc751\uc9d1\ub3c4\ub97c \ub192\uc77c \uc218 \uc788\uace0, \uc751\uc9d1\ub3c4\uac00 \ub192\uc544\uc9c4\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\ud560\ub2f9\ub41c \ucc45\uc784\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0)"),(0,r.kt)("li",{parentName:"ul"},"\uc720\uc9c0\ubcf4\uc218\uac00 \uc26c\uc6cc\uc9c4\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ub610\ud55c \uc9c0\uc6d0\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc751\uc9d1\ub3c4\uac00 \ub192\uc740 \ud074\ub798\uc2a4\ub294 \ud2b9\uc815\ud55c \ubaa9\uc801\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc7ac\uc0ac\uc6a9\ud558\uae30 \uc88b\ub2e4.")),(0,r.kt)("h3",{id:"\ucee8\ud2b8\ub864\ub7ec-\ud328\ud134controller"},"\ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)"),(0,r.kt)("p",null,"Q. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uac83\uc740 \ub204\uac00 \ub2f4\ub2f9\ud574\uc57c \ud558\ub294\uac00?"),(0,r.kt)("p",null,"A. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 Controller \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("p",null,"\uc5b4\ub5a4 \uc11c\ube0c\uc2dc\uc2a4\ud15c\uc774 \uc874\uc7ac\ud55c\ub2e4\uace0 \uac00\uc815\ud560 \ub54c"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc9c1\uc811\uc801\uc73c\ub85c \uac1d\uccb4\uc5d0 \uc811\uadfc\ud558\uc5ec \ud504\ub85c\uadf8\ub7a8\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uacb0\ud569\ub3c4\uac00 \uc0c1\uc2b9\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc11c\ube0c \uc2dc\uc2a4\ud15c\uc5d0 \ub4e4\uc5b4\uc624\ub294 \uc694\uccad\uc744 \ucc98\ub9ac\ud574\uc8fc\ub294 \ucee8\ud2b8\ub864\ub7ec\uac00 \uc788\ub2e4\uba74 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 \ud574\ub2f9 \ucee8\ud2b8\ub864\ub7ec\ub9cc \uc54c\uba74 \ub41c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ub9cc\uc57d \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc758 \ubcc0\uacbd\uc774 \uc0dd\uacbc\uc744 \ub54c \uc678\ubd80\uc5d0 \ubbf8\uce58\ub294 \uc601\ud5a5\ub3c4 \uc904\uc5b4\ub4e0\ub2e4.")),(0,r.kt)("h3",{id:"\ub2e4\ud615\uc131-\ud328\ud134polymorphism"},"\ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)"),(0,r.kt)("p",null,"Q. \uac1d\uccb4\uc758 \ud0c0\uc785\uc5d0 \ub530\ub77c \ud589\ub3d9\uc774 \ubc14\ub010\ub2e4\uba74 \ucc45\uc784\uc744 \uc5b4\ub5bb\uac8c \ud560\ub2f9\ud574\uc57c \ud560\uae4c?"),(0,r.kt)("p",null,"A. OOP\uac00 \uc9c0\uc6d0\ud558\ub294 \ub2e4\ud615\uc131\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ud65c\uc6a9\ud55c\ub2e4. (\uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0 \ud589\ub3d9\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uad6c\ud604)"),(0,r.kt)("p",null,"\uac1d\uccb4\uc758 \uc885\ub958\uc5d0 \ub530\ub77c \ubd84\uae30\ud558\ub294 \uc870\uac74\ubb38\uc774 \uc544\ub2cc \ub2e4\ud615\uc131\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4."),(0,r.kt)("p",null,"\uc0c8\ub85c\uc6b4 \ud0c0\uc785\uc774 \ucd94\uac00\ub418\uc5c8\uc744 \ub54c \uc870\uac74\ubb38\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uae30\uc874\uc758 \uc870\uac74\ubb38\uc744 \uc218\uc815\ud574\uc57c \ud558\uc9c0\ub9cc \ub2e4\ud615\uc131\uc744 \ud65c\uc6a9\ud558\uba74 \uc27d\uac8c \ud655\uc7a5\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\ubcc0\uacbd-\ubcf4\ud638-\ud328\ud134protected-variations"},"\ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)"),(0,r.kt)("p",null,"Q. \uc5b4\ub5bb\uac8c \ud558\uba74 \ubcc0\uacbd\uc774 \ub2e4\ub978 \uc694\uc18c\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub3c4\ub85d \ubc29\uc9c0\ud560 \uc218 \uc788\uc744\uae4c?"),(0,r.kt)("p",null,"A. \ubcc0\ud654\uac00 \uc608\uc0c1\ub418\ub294 \uc9c0\uc810\uc744 \uc2dd\ubcc4\ud558\uace0, \uc8fc\uc704\uc5d0 \uc548\uc815\ub41c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ud615\uc131\ud558\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("h3",{id:"\uac04\uc811-\ucc38\uc870-\ud328\ud134indirection"},"\uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)"),(0,r.kt)("p",null,"Q. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc758 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud558\uace0 \uc2f6\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"),(0,r.kt)("p",null,"A. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ub2e4\ub978 \uac1d\uccb4\ub97c \ub450\uc5b4 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,"\uc911\uc7ac\uc790 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ud558\ub098\uc758 \uac1d\uccb4\ub97c \ucd94\uac00\ud558\uc5ec \ubcf5\uc7a1\ud55c \uad00\uacc4\ub97c \ub2e8\uc21c\ud654\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,"\uc911\uac04\uc5d0 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub454\ub2e4\uba74 \ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)\uc5d0 \ud574\ub2f9\ub41c\ub2e4."),(0,r.kt)("h3",{id:"\uc21c\uc218\ud55c-\uac00\uacf5\ubb3c-\ud328\ud134pure-fabrication"},"\uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)"),(0,r.kt)("p",null,"Q. \ucc45\uc784\uc744 \ud560\ub2f9\ud55c \ub3c4\uba54\uc778 \uac1d\uccb4\uac00 Low Coupling, High Cohesion, \uc7ac\uc0ac\uc6a9\uc131 \ub4f1\uc758 \ubaa9\uc801\uc744 \uc704\ubc18\ud55c\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"),(0,r.kt)("p",null,"A. \ub3c4\uba54\uc778 \uac1c\ub150\uc744 \ud3ec\ud568\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uace0 \ub9e4\uc6b0 \uc751\uc9d1\ub41c \ucc45\uc784\uc744 \ud560\ub2f9\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,"\ud589\ub3d9\uc744 \ucd94\uac00\ud560 \ub54c, \ud574\ub2f9 \ucc45\uc784\uc744 \uc218\ud589\ud560 \ub3c4\uba54\uc778 \uac1c\ub150\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \ub3c4\uba54\uc778\uacfc \ubb34\uad00\ud55c \uc778\uacf5\uc801\uc778 \uac1d\uccb4\ub97c \ub9cc\ub4e0\ub2e4\uc74c \ud574\ub2f9 \uac1d\uccb4\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4."),(0,r.kt)("p",null,"\uac1d\uccb4\uac00 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud574\uc57c \ud560 \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4\uace0, \uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134\uc744 \uc801\uc6a9\ud558\uc5ec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud558\ub77c\ub294 \ucc45\uc784\uc744 \uac00\uc9c0\ub77c\uace0 \ud558\uc9c0 \uc54a\ub294\ub2e4."),(0,r.kt)("p",null,"\uc608) \uc0c1\uc810\uacfc \uace0\uac1d \ud074\ub798\uc2a4\uac00 \uc788\uace0 \uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uace0 \uac00\uc815"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0 \uac70\ub798\ub97c \ud558\ub824\uba74 \ud658\uc804\uc744 \ud574\uc57c\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ub450 \ud074\ub798\uc2a4 \ub2e4 \ud658\uc804\uc5d0 \ub300\ud55c \ucc45\uc784\uc744 \ubd80\uc5ec\ud558\uae30 \uc560\ub9e4\ud558\ub2e4\uba74 \ud658\uc804\uc744 \ucc45\uc784\ud558\ub294 \ud074\ub798\uc2a4\ub97c \ucd94\uac00\ud558\uace0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.")),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"\uc624\ube0c\uc81d\ud2b8 5\uc7a5. \ucc45\uc784 \ud560\ub2f9\ud558\uae30, ",(0,r.kt)("a",{parentName:"p",href:"http://aeternum.egloos.com/"},"\uc870\uc601\ud638")),(0,r.kt)("p",null,"Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://www.hanbit.co.kr/network/category/category_view.html?cms_code=CMS8586826397"},"GRASP, \ud55c\ube5b \ub124\ud2b8\uc6cc\ud06c")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e6e259a5.51ae33b3.js b/assets/js/e6e259a5.51ae33b3.js deleted file mode 100644 index 40a6ab99e..000000000 --- a/assets/js/e6e259a5.51ae33b3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3771],{3905:(e,t,a)=>{a.d(t,{Zo:()=>u,kt:()=>f});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function p(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function l(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?p(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):p(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function o(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},p=Object.keys(e);for(n=0;n<p.length;n++)a=p[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(n=0;n<p.length;n++)a=p[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var i=n.createContext({}),s=function(e){var t=n.useContext(i),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},u=function(e){var t=s(e.components);return n.createElement(i.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,p=e.originalType,i=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),d=s(a),f=r,m=d["".concat(i,".").concat(f)]||d[f]||c[f]||p;return a?n.createElement(m,l(l({ref:t},u),{},{components:a})):n.createElement(m,l({ref:t},u))}));function f(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var p=a.length,l=new Array(p);l[0]=d;var o={};for(var i in t)hasOwnProperty.call(t,i)&&(o[i]=t[i]);o.originalType=e,o.mdxType="string"==typeof e?e:r,l[1]=o;for(var s=2;s<p;s++)l[s]=a[s];return n.createElement.apply(null,l)}return n.createElement.apply(null,a)}d.displayName="MDXCreateElement"},5352:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>c,frontMatter:()=>p,metadata:()=>o,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const p={title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",slug:"/linux/swap",last_update:{date:"2023/07/20",author:"\ud5c8\ube0c"}},l=void 0,o={unversionedId:"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815",id:"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815",title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",description:"Swap \uba54\ubaa8\ub9ac",source:"@site/docs/\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815.md",sourceDirName:"\ub9ac\ub205\uc2a4",slug:"/linux/swap",permalink:"/docs/linux/swap",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815.md",tags:[],version:"current",lastUpdatedBy:"\ud5c8\ube0c",lastUpdatedAt:1689811200,formattedLastUpdatedAt:"2023\ub144 7\uc6d4 20\uc77c",frontMatter:{title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",slug:"/linux/swap",last_update:{date:"2023/07/20",author:"\ud5c8\ube0c"}},sidebar:"tutorialSidebar",previous:{title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",permalink:"/docs/book/getting-out-of-the-box"},next:{title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",permalink:"/docs/linux/shell"}},i={},s=[{value:"Swap \uba54\ubaa8\ub9ac",id:"swap-\uba54\ubaa8\ub9ac",level:3},{value:"\uc124\uc815",id:"\uc124\uc815",level:3},{value:"Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9",id:"swap-\uba54\ubaa8\ub9ac-\ubd80\ud305\uc2dc-\uc790\ub3d9\uc73c\ub85c-\ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d-\uc801\uc6a9",level:3},{value:"Swap \uba54\ubaa8\ub9ac \uc801\uc6a9\ub418\uc5c8\ub294\uc9c0 \ud655\uc778",id:"swap-\uba54\ubaa8\ub9ac-\uc801\uc6a9\ub418\uc5c8\ub294\uc9c0-\ud655\uc778",level:3},{value:"Swap \uba54\ubaa8\ub9ac \ube44\ud65c\uc131\ud654",id:"swap-\uba54\ubaa8\ub9ac-\ube44\ud65c\uc131\ud654",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],u={toc:s};function c(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},u,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"swap-\uba54\ubaa8\ub9ac"},"Swap \uba54\ubaa8\ub9ac"),(0,r.kt)("p",null,"\ud558\ub4dc\ub514\uc2a4\ud06c \uacf5\uac04\uc758 \uc77c\ubd80\ubd84\uc744 \uba54\ubaa8\ub9ac\ub85c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\ub4dc\ub514\uc2a4\ud06c\ub97c \uc0ac\uc6a9\ud558\ub294 \ub9cc\ud07c \uae30\uc874 \uba54\ubaa8\ub9ac\ubcf4\ub2e4 \uc18d\ub3c4\uac00 \ud604\uc800\ud788 \ub5a8\uc5b4\uc9c4\ub2e4."),(0,r.kt)("h3",{id:"\uc124\uc815"},"\uc124\uc815"),(0,r.kt)("p",null,"\ubcf4\ud1b5 Swap \ud30c\uc77c\uc758 \uc6a9\ub7c9\uc740 \uae30\uc874 \uba54\ubaa8\ub9ac\uc758 1.5~2\ubc30 \uc815\ub3c4\uc758 \uc6a9\ub7c9\uc744 \uad8c\uc7a5\ud558\uace0 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","fallocate\ub610\ub294 dd \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec \uc2a4\uc651 \ud30c\uc77c\uc744 \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# fallocate\nsudo fallocate -l 2G /swapfile\n\n# dd\nsudo dd if=/dev/zero of=/swapfile bs=1MiB count=2048\n")),(0,r.kt)("p",null,"\uc77c\ubc18 \uc0ac\uc6a9\uc790\uac00 \ud574\ub2f9 \ud30c\uc77c\uc5d0 \uc811\uadfc\ud560 \uc218 \uc5c6\ub3c4\ub85d \uad8c\ud55c\uc744 \uc124\uc815\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo chmod 600 /swapfile\n")),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ud30c\uc77c\uc744 Swap \ud3ec\ub9f7\uc73c\ub85c \ubcc0\uacbd \ud6c4 \uc2dc\uc2a4\ud15c\uc5d0 \ub4f1\ub85d\ud55c\ub2e4.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo mkswap /swapfile\nsudo swapon /swapfile\n")),(0,r.kt)("h3",{id:"swap-\uba54\ubaa8\ub9ac-\ubd80\ud305\uc2dc-\uc790\ub3d9\uc73c\ub85c-\ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d-\uc801\uc6a9"},"Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9"),(0,r.kt)("p",null,"\uc778\uc2a4\ud134\uc2a4\uac00 \uc885\ub8cc\ub418\uac70\ub098 \uc7ac\ubd80\ud305\uc744 \ud558\ub294 \uacbd\uc6b0 Swap \uc124\uc815\uc774 \ucd08\uae30\ud654\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("inlineCode",{parentName:"p"},"/etc/fstab")," \ud30c\uc77c\uc744 \uc218\uc815\ud558\uc5ec Swap \uba54\ubaa8\ub9ac\ub97c \uc601\uad6c\uc801\uc73c\ub85c \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ud574\ub2f9 \ud30c\uc77c\uc740 \ub9ac\ub205\uc2a4 \ubd80\ud305\uc2dc \ub9c8\uc6b4\ud2b8\uc815\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uc788\ub2e4.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# vim\uc744 \uc774\uc6a9\ud558\uc5ec \ud574\ub2f9 \ud30c\uc77c\uc744 \uc218\uc815\ud55c\ub2e4.\nsudo vim /etc/fstab\n# \ucd5c\ud558\ub2e8\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815\ud558\uba74 \ub41c\ub2e4.\n/swapfile swap swap defaults 0 0\n")),(0,r.kt)("h3",{id:"swap-\uba54\ubaa8\ub9ac-\uc801\uc6a9\ub418\uc5c8\ub294\uc9c0-\ud655\uc778"},"Swap \uba54\ubaa8\ub9ac \uc801\uc6a9\ub418\uc5c8\ub294\uc9c0 \ud655\uc778"),(0,r.kt)("p",null,"\ub9ac\ub205\uc2a4\uc5d0\uc11c\ub294 ",(0,r.kt)("inlineCode",{parentName:"p"},"free")," \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uba54\ubaa8\ub9ac\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","-h \uc635\uc158\uc744 \uc8fc\uba74 \uc880 \ub354 \uc77d\uae30 \ud3b8\ud55c \ud615\ud0dc\ub85c \ucd9c\ub825\ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"free -h\n total used free shared buff/cache available\nMem: 905Mi 570Mi 65Mi 0.0Ki 270Mi 186Mi\nSwap: 2.0Gi 626Mi 1.4Gi\n")),(0,r.kt)("p",null,"\uc544\ub798\uc5d0 Swap \uba54\ubaa8\ub9ac\uac00 \uc801\uc6a9\ub418\uc5b4\uc788\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c ",(0,r.kt)("inlineCode",{parentName:"p"},"swapon")," \uba85\ub839\uc5b4\ub85c\ub3c4 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("h3",{id:"swap-\uba54\ubaa8\ub9ac-\ube44\ud65c\uc131\ud654"},"Swap \uba54\ubaa8\ub9ac \ube44\ud65c\uc131\ud654"),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},"swapoff")," \uba85\ub839\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ud65c\uc131\ud654 \ud55c \ud6c4 \ud30c\uc77c\uc744 \uc0ad\uc81c\ud558\uba74 \ub41c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"# swap \uc124\uc815\ud55c \ud30c\uc77c \ube44\ud65c\uc131\ud654\nsudo swapoff -v /swapfile\n# \uc0ad\uc81c\nsudo rm /swapfile\n")),(0,r.kt)("p",null,"\ub9cc\uc57d ",(0,r.kt)("inlineCode",{parentName:"p"},"/etc/fstab"),"\uc5d0 \uac12\uc744 \uc124\uc815\ud588\uc744 \uacbd\uc6b0 \ud574\ub2f9 \uac12\uc744 \uc9c0\uc6cc\uc57c\ud55c\ub2e4."),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-20-04/"},"How to Add Swap Space on Ubuntu 20.04, Lunuxize")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e6e259a5.f5d4fe6a.js b/assets/js/e6e259a5.f5d4fe6a.js new file mode 100644 index 000000000..71d447b04 --- /dev/null +++ b/assets/js/e6e259a5.f5d4fe6a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3771],{9801:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>s,metadata:()=>i,toc:()=>o});var a=r(85893),t=r(3905);const s={title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",slug:"/linux/swap",last_update:{date:"2023/07/20",author:"\ud5c8\ube0c"}},l=void 0,i={id:"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815",title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",description:"Swap \uba54\ubaa8\ub9ac",source:"@site/docs/\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815.md",sourceDirName:"\ub9ac\ub205\uc2a4",slug:"/linux/swap",permalink:"/docs/linux/swap",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815.md",tags:[],version:"current",lastUpdatedBy:"\ud5c8\ube0c",lastUpdatedAt:1689811200,formattedLastUpdatedAt:"2023\ub144 7\uc6d4 20\uc77c",frontMatter:{title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",slug:"/linux/swap",last_update:{date:"2023/07/20",author:"\ud5c8\ube0c"}},sidebar:"tutorialSidebar",previous:{title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",permalink:"/docs/book/getting-out-of-the-box"},next:{title:"\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815",permalink:"/docs/linux/shell"}},c={},o=[{value:"Swap \uba54\ubaa8\ub9ac",id:"swap-\uba54\ubaa8\ub9ac",level:3},{value:"\uc124\uc815",id:"\uc124\uc815",level:3},{value:"Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9",id:"swap-\uba54\ubaa8\ub9ac-\ubd80\ud305\uc2dc-\uc790\ub3d9\uc73c\ub85c-\ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d-\uc801\uc6a9",level:3},{value:"Swap \uba54\ubaa8\ub9ac \uc801\uc6a9\ub418\uc5c8\ub294\uc9c0 \ud655\uc778",id:"swap-\uba54\ubaa8\ub9ac-\uc801\uc6a9\ub418\uc5c8\ub294\uc9c0-\ud655\uc778",level:3},{value:"Swap \uba54\ubaa8\ub9ac \ube44\ud65c\uc131\ud654",id:"swap-\uba54\ubaa8\ub9ac-\ube44\ud65c\uc131\ud654",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function d(e){const n={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.ah)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h3,{id:"swap-\uba54\ubaa8\ub9ac",children:"Swap \uba54\ubaa8\ub9ac"}),"\n",(0,a.jsxs)(n.p,{children:["\ud558\ub4dc\ub514\uc2a4\ud06c \uacf5\uac04\uc758 \uc77c\ubd80\ubd84\uc744 \uba54\ubaa8\ub9ac\ub85c \uc0ac\uc6a9\ud558\ub294 \ubc29\ubc95\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud558\ub4dc\ub514\uc2a4\ud06c\ub97c \uc0ac\uc6a9\ud558\ub294 \ub9cc\ud07c \uae30\uc874 \uba54\ubaa8\ub9ac\ubcf4\ub2e4 \uc18d\ub3c4\uac00 \ud604\uc800\ud788 \ub5a8\uc5b4\uc9c4\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\uc124\uc815",children:"\uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["\ubcf4\ud1b5 Swap \ud30c\uc77c\uc758 \uc6a9\ub7c9\uc740 \uae30\uc874 \uba54\ubaa8\ub9ac\uc758 1.5~2\ubc30 \uc815\ub3c4\uc758 \uc6a9\ub7c9\uc744 \uad8c\uc7a5\ud558\uace0 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","fallocate\ub610\ub294 dd \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud558\uc5ec \uc2a4\uc651 \ud30c\uc77c\uc744 \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# fallocate\nsudo fallocate -l 2G /swapfile\n\n# dd\nsudo dd if=/dev/zero of=/swapfile bs=1MiB count=2048\n"})}),"\n",(0,a.jsx)(n.p,{children:"\uc77c\ubc18 \uc0ac\uc6a9\uc790\uac00 \ud574\ub2f9 \ud30c\uc77c\uc5d0 \uc811\uadfc\ud560 \uc218 \uc5c6\ub3c4\ub85d \uad8c\ud55c\uc744 \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"sudo chmod 600 /swapfile\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud30c\uc77c\uc744 Swap \ud3ec\ub9f7\uc73c\ub85c \ubcc0\uacbd \ud6c4 \uc2dc\uc2a4\ud15c\uc5d0 \ub4f1\ub85d\ud55c\ub2e4."}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"sudo mkswap /swapfile\nsudo swapon /swapfile\n"})}),"\n",(0,a.jsx)(n.h3,{id:"swap-\uba54\ubaa8\ub9ac-\ubd80\ud305\uc2dc-\uc790\ub3d9\uc73c\ub85c-\ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d-\uc801\uc6a9",children:"Swap \uba54\ubaa8\ub9ac \ubd80\ud305\uc2dc \uc790\ub3d9\uc73c\ub85c \ub9c8\uc6b4\ud2b8\ud558\ub3c4\ub85d \uc801\uc6a9"}),"\n",(0,a.jsxs)(n.p,{children:["\uc778\uc2a4\ud134\uc2a4\uac00 \uc885\ub8cc\ub418\uac70\ub098 \uc7ac\ubd80\ud305\uc744 \ud558\ub294 \uacbd\uc6b0 Swap \uc124\uc815\uc774 \ucd08\uae30\ud654\ub41c\ub2e4.",(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.code,{children:"/etc/fstab"})," \ud30c\uc77c\uc744 \uc218\uc815\ud558\uc5ec Swap \uba54\ubaa8\ub9ac\ub97c \uc601\uad6c\uc801\uc73c\ub85c \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"\ud574\ub2f9 \ud30c\uc77c\uc740 \ub9ac\ub205\uc2a4 \ubd80\ud305\uc2dc \ub9c8\uc6b4\ud2b8\uc815\ubcf4\ub97c \uc800\uc7a5\ud558\uace0 \uc788\ub2e4."}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# vim\uc744 \uc774\uc6a9\ud558\uc5ec \ud574\ub2f9 \ud30c\uc77c\uc744 \uc218\uc815\ud55c\ub2e4.\nsudo vim /etc/fstab\n# \ucd5c\ud558\ub2e8\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815\ud558\uba74 \ub41c\ub2e4.\n/swapfile swap swap defaults 0 0\n"})}),"\n",(0,a.jsx)(n.h3,{id:"swap-\uba54\ubaa8\ub9ac-\uc801\uc6a9\ub418\uc5c8\ub294\uc9c0-\ud655\uc778",children:"Swap \uba54\ubaa8\ub9ac \uc801\uc6a9\ub418\uc5c8\ub294\uc9c0 \ud655\uc778"}),"\n",(0,a.jsxs)(n.p,{children:["\ub9ac\ub205\uc2a4\uc5d0\uc11c\ub294 ",(0,a.jsx)(n.code,{children:"free"})," \uba85\ub839\uc5b4\ub97c \ud1b5\ud574 \uba54\ubaa8\ub9ac\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","-h \uc635\uc158\uc744 \uc8fc\uba74 \uc880 \ub354 \uc77d\uae30 \ud3b8\ud55c \ud615\ud0dc\ub85c \ucd9c\ub825\ub41c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"free -h\n total used free shared buff/cache available\nMem: 905Mi 570Mi 65Mi 0.0Ki 270Mi 186Mi\nSwap: 2.0Gi 626Mi 1.4Gi\n"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc544\ub798\uc5d0 Swap \uba54\ubaa8\ub9ac\uac00 \uc801\uc6a9\ub418\uc5b4\uc788\ub294 \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c ",(0,a.jsx)(n.code,{children:"swapon"})," \uba85\ub839\uc5b4\ub85c\ub3c4 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"swap-\uba54\ubaa8\ub9ac-\ube44\ud65c\uc131\ud654",children:"Swap \uba54\ubaa8\ub9ac \ube44\ud65c\uc131\ud654"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"swapoff"})," \uba85\ub839\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ube44\ud65c\uc131\ud654 \ud55c \ud6c4 \ud30c\uc77c\uc744 \uc0ad\uc81c\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"# swap \uc124\uc815\ud55c \ud30c\uc77c \ube44\ud65c\uc131\ud654\nsudo swapoff -v /swapfile\n# \uc0ad\uc81c\nsudo rm /swapfile\n"})}),"\n",(0,a.jsxs)(n.p,{children:["\ub9cc\uc57d ",(0,a.jsx)(n.code,{children:"/etc/fstab"}),"\uc5d0 \uac12\uc744 \uc124\uc815\ud588\uc744 \uacbd\uc6b0 \ud574\ub2f9 \uac12\uc744 \uc9c0\uc6cc\uc57c\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-20-04/",children:"How to Add Swap Space on Ubuntu 20.04, Lunuxize"})})]})}function p(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>o});var a=r(67294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,a)}return r}function l(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?s(Object(r),!0).forEach((function(n){t(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function i(e,n){if(null==e)return{};var r,a,t=function(e,n){if(null==e)return{};var r,a,t={},s=Object.keys(e);for(a=0;a<s.length;a++)r=s[a],n.indexOf(r)>=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a<s.length;a++)r=s[a],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var c=a.createContext({}),o=function(e){var n=a.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):l(l({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},p=a.forwardRef((function(e,n){var r=e.components,t=e.mdxType,s=e.originalType,c=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),u=o(r),h=t,f=u["".concat(c,".").concat(h)]||u[h]||d[h]||s;return r?a.createElement(f,l(l({ref:n},p),{},{components:r})):a.createElement(f,l({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/e8d6e7ce.71026c4f.js b/assets/js/e8d6e7ce.9dce5fc8.js similarity index 81% rename from assets/js/e8d6e7ce.71026c4f.js rename to assets/js/e8d6e7ce.9dce5fc8.js index e945974c1..0356d7ae6 100644 --- a/assets/js/e8d6e7ce.71026c4f.js +++ b/assets/js/e8d6e7ce.9dce5fc8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3912],{65245:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3912],{65245:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/e9eabc5d.641504bc.js b/assets/js/e9eabc5d.641504bc.js deleted file mode 100644 index 5910422fb..000000000 --- a/assets/js/e9eabc5d.641504bc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1112],{3905:(e,t,l)=>{l.d(t,{Zo:()=>c,kt:()=>m});var n=l(67294);function r(e,t,l){return t in e?Object.defineProperty(e,t,{value:l,enumerable:!0,configurable:!0,writable:!0}):e[t]=l,e}function a(e,t){var l=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),l.push.apply(l,n)}return l}function o(e){for(var t=1;t<arguments.length;t++){var l=null!=arguments[t]?arguments[t]:{};t%2?a(Object(l),!0).forEach((function(t){r(e,t,l[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(l)):a(Object(l)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(l,t))}))}return e}function i(e,t){if(null==e)return{};var l,n,r=function(e,t){if(null==e)return{};var l,n,r={},a=Object.keys(e);for(n=0;n<a.length;n++)l=a[n],t.indexOf(l)>=0||(r[l]=e[l]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)l=a[n],t.indexOf(l)>=0||Object.prototype.propertyIsEnumerable.call(e,l)&&(r[l]=e[l])}return r}var p=n.createContext({}),u=function(e){var t=n.useContext(p),l=t;return e&&(l="function"==typeof e?e(t):o(o({},t),e)),l},c=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var l=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),k=u(l),m=r,g=k["".concat(p,".").concat(m)]||k[m]||s[m]||a;return l?n.createElement(g,o(o({ref:t},c),{},{components:l})):n.createElement(g,o({ref:t},c))}));function m(e,t){var l=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=l.length,o=new Array(a);o[0]=k;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var u=2;u<a;u++)o[u]=l[u];return n.createElement.apply(null,o)}return n.createElement.apply(null,l)}k.displayName="MDXCreateElement"},778:(e,t,l)=>{l.r(t),l.d(t,{assets:()=>p,contentTitle:()=>o,default:()=>s,frontMatter:()=>a,metadata:()=>i,toc:()=>u});var n=l(87462),r=(l(67294),l(3905));const a={title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",slug:"grasp",tags:["GRASP","OOP"]},o=void 0,i={permalink:"/grasp",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-30-GRASP.mdx",source:"@site/blog/2023-1/2023-03-30-GRASP.mdx",title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",description:"GRASP(General Responsibility Assignment Software Pattern)",date:"2023-03-30T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 30\uc77c",tags:[{label:"GRASP",permalink:"/tags/grasp"},{label:"OOP",permalink:"/tags/oop"}],readingTime:8.085,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",slug:"grasp",tags:["GRASP","OOP"]},prevItem:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",permalink:"/chess-retrospective"},nextItem:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",permalink:"/blackjack-retrospective"}},p={authorsImageUrls:[]},u=[{value:"GRASP(General Responsibility Assignment Software Pattern)",id:"graspgeneral-responsibility-assignment-software-pattern",level:3},{value:"\uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)",id:"\uc815\ubcf4-\uc804\ubb38\uac00-\ud328\ud134information-expert",level:3},{value:"\ucc3d\uc870\uc790 \ud328\ud134(Creator)",id:"\ucc3d\uc870\uc790-\ud328\ud134creator",level:3},{value:"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)",id:"\ub0ae\uc740-\uacb0\ud569\ub3c4-\ud328\ud134low-coupling",level:3},{value:"\ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)",id:"\ub192\uc740-\uc751\uc9d1\ub3c4-\ud328\ud134high-cohesion",level:3},{value:"\ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)",id:"\ucee8\ud2b8\ub864\ub7ec-\ud328\ud134controller",level:3},{value:"\ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)",id:"\ub2e4\ud615\uc131-\ud328\ud134polymorphism",level:3},{value:"\ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)",id:"\ubcc0\uacbd-\ubcf4\ud638-\ud328\ud134protected-variations",level:3},{value:"\uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)",id:"\uac04\uc811-\ucc38\uc870-\ud328\ud134indirection",level:3},{value:"\uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)",id:"\uc21c\uc218\ud55c-\uac00\uacf5\ubb3c-\ud328\ud134pure-fabrication",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],c={toc:u};function s(e){let{components:t,...l}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,l,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h3",{id:"graspgeneral-responsibility-assignment-software-pattern"},"GRASP(General Responsibility Assignment Software Pattern)"),(0,r.kt)("p",null,"\ud06c\ub808\uc774\uadf8 \ub77c\ub9cc\uc758 Applying UML and Patterns\uc774\ub77c\ub294 \ucc45\uc5d0\uc11c \ub098\uc628 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134"),(0,r.kt)("p",null,"\uac01 \ud328\ud134\ub9c8\ub2e4 Solution\uacfc Problem\ub85c \uad6c\uc131\ub418\uc5b4 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\uc815\ubcf4-\uc804\ubb38\uac00-\ud328\ud134information-expert"},"\uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)"),(0,r.kt)("p",null,"Q: \uac1d\uccb4\uc5d0 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uae30\ubcf8 \uc6d0\uce59\uc740 \ubb34\uc5c7\uc778\uac00?"),(0,r.kt)("p",null,"A: \ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub370 \ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \ud074\ub798\uc2a4(\uc815\ubcf4 \uc804\ubb38\uac00)\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4."),(0,r.kt)("p",null,"\uc815\ubcf4\uc640 \ud589\ub3d9\uc744 \uac00\uae4c\uc6b4 \uacf3\uc5d0 \uc704\uce58\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \ucea1\uc290\ud654\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,"\ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \uac1d\uccb4\ub4e4\ub85c \ucc45\uc784\uc774 \ubd84\uc0b0\ub41c\ub2e4."),(0,r.kt)("h3",{id:"\ucc3d\uc870\uc790-\ud328\ud134creator"},"\ucc3d\uc870\uc790 \ud328\ud134(Creator)"),(0,r.kt)("p",null,"Q: \ub204\uac00 \uac1d\uccb4 A\ub97c \uc0dd\uc131\ud558\ub294\uac00?"),(0,r.kt)("p",null,"A: \ub2e4\uc74c\uc758 \uc870\uac74\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\uc871\ud558\ub294 \uac1d\uccb4\uc5d0\uac8c \uac1d\uccb4 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"B\uac00 A \uac1d\uccb4\uc758 \ucd08\uae30\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4.")),(0,r.kt)("p",null,"\uc0dd\uc131 \uc608\uc815\uc778 \uac1d\uccb4\uc640 \uc5f0\uad00\ub418\uc5b4 \uc788\ub294 \uac1d\uccb4\uac00 \uc0dd\uc131 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uac8c \ub41c\ub2e4\uba74, \uc774\ubbf8 \ud574\ub2f9 \uac1d\uccb4\uc640 \uacb0\ud569\ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\uac8c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\ub0ae\uc740-\uacb0\ud569\ub3c4-\ud328\ud134low-coupling"},"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)"),(0,r.kt)("p",null,"Q: \uc758\uc874\uc131\uc744 \ub0ae\ucd94\uace0 \ubcc0\ud654\uc758 \uc601\ud5a5\uc744 \uc904\uc774\uba70 \uc7ac\uc0ac\uc6a9\uc131\uc744 \uc99d\uac00\uc2dc\ud0a4\ub294 \ubc29\ubc95\uc740?"),(0,r.kt)("p",null,"A: \uc804\uccb4\uc801\uc778 \uacb0\ud569\uc774 \ub0ae\uac8c \uc720\uc9c0\ub418\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\uacb0\ud569\ub3c4(Coupling)\n\uac1d\uccb4 \uc0ac\uc774\uc758 \uc758\uc874\uc131\uc774 \uacfc\ud55c \uacbd\uc6b0 \uacb0\ud569\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4."),(0,r.kt)("ul",{parentName:"blockquote"},(0,r.kt)("li",{parentName:"ul"},"\uc624\ube0c\uc81d\ud2b8 p.17"))),(0,r.kt)("p",null,"\uacb0\ud569\ub3c4\ub97c \ub0ae\ucd98\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\uc758 \ubcc0\ud654\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc7ac\uc0ac\uc6a9\uc774 \ud3b8\ub9ac\ud574\uc9c4\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\uc758\uc874\ud558\ub294 \ud074\ub798\uc2a4\uac00 \uc801\uae30 \ub54c\ubb38\uc5d0)")),(0,r.kt)("h3",{id:"\ub192\uc740-\uc751\uc9d1\ub3c4-\ud328\ud134high-cohesion"},"\ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)"),(0,r.kt)("p",null,"Q. \uac1d\uccb4\ub97c \uad00\ub9ac\ud558\uae30 \uc27d\uac8c \ud558\ub824\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"),(0,r.kt)("p",null,"A. \ub192\uc740 \uc751\uc9d1\ub3c4\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"\uc751\uc9d1\ub3c4(Cohesion)\n\uc5f0\uad00\ub41c \uc791\uc5c5\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc5f0\uad00\uc131 \uc5c6\ub294 \uc791\uc5c5\uc740 \ub2e4\ub978 \uac1d\uccb4\uc5d0\uac8c \uc704\uc784\ud558\ub294 \uac1d\uccb4\ub97c \uac00\ub9ac\ucf1c \uc751\uc9d1\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4."),(0,r.kt)("ul",{parentName:"blockquote"},(0,r.kt)("li",{parentName:"ul"},"\uc624\ube0c\uc81d\ud2b8 p.26"))),(0,r.kt)("p",null,"\ubcc0\uacbd\uc758 \uc774\uc720\uc5d0 \ub530\ub77c \ud074\ub798\uc2a4\ub97c \ubd84\ub9ac\ud55c\ub2e4\uba74 \uc751\uc9d1\ub3c4\ub97c \ub192\uc77c \uc218 \uc788\uace0, \uc751\uc9d1\ub3c4\uac00 \ub192\uc544\uc9c4\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\ud560\ub2f9\ub41c \ucc45\uc784\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0)"),(0,r.kt)("li",{parentName:"ul"},"\uc720\uc9c0\ubcf4\uc218\uac00 \uc26c\uc6cc\uc9c4\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ub610\ud55c \uc9c0\uc6d0\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc751\uc9d1\ub3c4\uac00 \ub192\uc740 \ud074\ub798\uc2a4\ub294 \ud2b9\uc815\ud55c \ubaa9\uc801\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc7ac\uc0ac\uc6a9\ud558\uae30 \uc88b\ub2e4.")),(0,r.kt)("h3",{id:"\ucee8\ud2b8\ub864\ub7ec-\ud328\ud134controller"},"\ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)"),(0,r.kt)("p",null,"Q. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uac83\uc740 \ub204\uac00 \ub2f4\ub2f9\ud574\uc57c \ud558\ub294\uac00?"),(0,r.kt)("p",null,"A. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 Controller \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("p",null,"\uc5b4\ub5a4 \uc11c\ube0c\uc2dc\uc2a4\ud15c\uc774 \uc874\uc7ac\ud55c\ub2e4\uace0 \uac00\uc815\ud560 \ub54c"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc9c1\uc811\uc801\uc73c\ub85c \uac1d\uccb4\uc5d0 \uc811\uadfc\ud558\uc5ec \ud504\ub85c\uadf8\ub7a8\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uacb0\ud569\ub3c4\uac00 \uc0c1\uc2b9\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\uc11c\ube0c \uc2dc\uc2a4\ud15c\uc5d0 \ub4e4\uc5b4\uc624\ub294 \uc694\uccad\uc744 \ucc98\ub9ac\ud574\uc8fc\ub294 \ucee8\ud2b8\ub864\ub7ec\uac00 \uc788\ub2e4\uba74 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 \ud574\ub2f9 \ucee8\ud2b8\ub864\ub7ec\ub9cc \uc54c\uba74 \ub41c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ub9cc\uc57d \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc758 \ubcc0\uacbd\uc774 \uc0dd\uacbc\uc744 \ub54c \uc678\ubd80\uc5d0 \ubbf8\uce58\ub294 \uc601\ud5a5\ub3c4 \uc904\uc5b4\ub4e0\ub2e4.")),(0,r.kt)("h3",{id:"\ub2e4\ud615\uc131-\ud328\ud134polymorphism"},"\ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)"),(0,r.kt)("p",null,"Q. \uac1d\uccb4\uc758 \ud0c0\uc785\uc5d0 \ub530\ub77c \ud589\ub3d9\uc774 \ubc14\ub010\ub2e4\uba74 \ucc45\uc784\uc744 \uc5b4\ub5bb\uac8c \ud560\ub2f9\ud574\uc57c \ud560\uae4c?"),(0,r.kt)("p",null,"A. OOP\uac00 \uc9c0\uc6d0\ud558\ub294 \ub2e4\ud615\uc131\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ud65c\uc6a9\ud55c\ub2e4. (\uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0 \ud589\ub3d9\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uad6c\ud604)"),(0,r.kt)("p",null,"\uac1d\uccb4\uc758 \uc885\ub958\uc5d0 \ub530\ub77c \ubd84\uae30\ud558\ub294 \uc870\uac74\ubb38\uc774 \uc544\ub2cc \ub2e4\ud615\uc131\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4."),(0,r.kt)("p",null,"\uc0c8\ub85c\uc6b4 \ud0c0\uc785\uc774 \ucd94\uac00\ub418\uc5c8\uc744 \ub54c \uc870\uac74\ubb38\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uae30\uc874\uc758 \uc870\uac74\ubb38\uc744 \uc218\uc815\ud574\uc57c \ud558\uc9c0\ub9cc \ub2e4\ud615\uc131\uc744 \ud65c\uc6a9\ud558\uba74 \uc27d\uac8c \ud655\uc7a5\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("h3",{id:"\ubcc0\uacbd-\ubcf4\ud638-\ud328\ud134protected-variations"},"\ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)"),(0,r.kt)("p",null,"Q. \uc5b4\ub5bb\uac8c \ud558\uba74 \ubcc0\uacbd\uc774 \ub2e4\ub978 \uc694\uc18c\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub3c4\ub85d \ubc29\uc9c0\ud560 \uc218 \uc788\uc744\uae4c?"),(0,r.kt)("p",null,"A. \ubcc0\ud654\uac00 \uc608\uc0c1\ub418\ub294 \uc9c0\uc810\uc744 \uc2dd\ubcc4\ud558\uace0, \uc8fc\uc704\uc5d0 \uc548\uc815\ub41c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ud615\uc131\ud558\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("h3",{id:"\uac04\uc811-\ucc38\uc870-\ud328\ud134indirection"},"\uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)"),(0,r.kt)("p",null,"Q. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc758 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud558\uace0 \uc2f6\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"),(0,r.kt)("p",null,"A. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ub2e4\ub978 \uac1d\uccb4\ub97c \ub450\uc5b4 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,"\uc911\uc7ac\uc790 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ud558\ub098\uc758 \uac1d\uccb4\ub97c \ucd94\uac00\ud558\uc5ec \ubcf5\uc7a1\ud55c \uad00\uacc4\ub97c \ub2e8\uc21c\ud654\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,"\uc911\uac04\uc5d0 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub454\ub2e4\uba74 \ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)\uc5d0 \ud574\ub2f9\ub41c\ub2e4."),(0,r.kt)("h3",{id:"\uc21c\uc218\ud55c-\uac00\uacf5\ubb3c-\ud328\ud134pure-fabrication"},"\uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)"),(0,r.kt)("p",null,"Q. \ucc45\uc784\uc744 \ud560\ub2f9\ud55c \ub3c4\uba54\uc778 \uac1d\uccb4\uac00 Low Coupling, High Cohesion, \uc7ac\uc0ac\uc6a9\uc131 \ub4f1\uc758 \ubaa9\uc801\uc744 \uc704\ubc18\ud55c\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"),(0,r.kt)("p",null,"A. \ub3c4\uba54\uc778 \uac1c\ub150\uc744 \ud3ec\ud568\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uace0 \ub9e4\uc6b0 \uc751\uc9d1\ub41c \ucc45\uc784\uc744 \ud560\ub2f9\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,"\ud589\ub3d9\uc744 \ucd94\uac00\ud560 \ub54c, \ud574\ub2f9 \ucc45\uc784\uc744 \uc218\ud589\ud560 \ub3c4\uba54\uc778 \uac1c\ub150\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \ub3c4\uba54\uc778\uacfc \ubb34\uad00\ud55c \uc778\uacf5\uc801\uc778 \uac1d\uccb4\ub97c \ub9cc\ub4e0\ub2e4\uc74c \ud574\ub2f9 \uac1d\uccb4\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4."),(0,r.kt)("p",null,"\uac1d\uccb4\uac00 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud574\uc57c \ud560 \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4\uace0, \uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134\uc744 \uc801\uc6a9\ud558\uc5ec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud558\ub77c\ub294 \ucc45\uc784\uc744 \uac00\uc9c0\ub77c\uace0 \ud558\uc9c0 \uc54a\ub294\ub2e4."),(0,r.kt)("p",null,"\uc608) \uc0c1\uc810\uacfc \uace0\uac1d \ud074\ub798\uc2a4\uac00 \uc788\uace0 \uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uace0 \uac00\uc815"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"\uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0 \uac70\ub798\ub97c \ud558\ub824\uba74 \ud658\uc804\uc744 \ud574\uc57c\ud55c\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"\ub450 \ud074\ub798\uc2a4 \ub2e4 \ud658\uc804\uc5d0 \ub300\ud55c \ucc45\uc784\uc744 \ubd80\uc5ec\ud558\uae30 \uc560\ub9e4\ud558\ub2e4\uba74 \ud658\uc804\uc744 \ucc45\uc784\ud558\ub294 \ud074\ub798\uc2a4\ub97c \ucd94\uac00\ud558\uace0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.")),(0,r.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"\uc624\ube0c\uc81d\ud2b8 5\uc7a5. \ucc45\uc784 \ud560\ub2f9\ud558\uae30, ",(0,r.kt)("a",{parentName:"p",href:"http://aeternum.egloos.com/"},"\uc870\uc601\ud638")),(0,r.kt)("p",null,"Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://www.hanbit.co.kr/network/category/category_view.html?cms_code=CMS8586826397"},"GRASP, \ud55c\ube5b \ub124\ud2b8\uc6cc\ud06c")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/e9eabc5d.fcb4962f.js b/assets/js/e9eabc5d.fcb4962f.js new file mode 100644 index 000000000..19e7882c1 --- /dev/null +++ b/assets/js/e9eabc5d.fcb4962f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1112],{40376:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>a});var i=r(85893),l=r(3905);const t={title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",slug:"grasp",tags:["GRASP","OOP"]},s=void 0,o={permalink:"/grasp",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-03-30-GRASP.mdx",source:"@site/blog/2023-1/2023-03-30-GRASP.mdx",title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",description:"GRASP(General Responsibility Assignment Software Pattern)",date:"2023-03-30T00:00:00.000Z",formattedDate:"2023\ub144 3\uc6d4 30\uc77c",tags:[{label:"GRASP",permalink:"/tags/grasp"},{label:"OOP",permalink:"/tags/oop"}],readingTime:8.085,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc77c\ubc18\uc801\uc778 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134",slug:"grasp",tags:["GRASP","OOP"]},unlisted:!1,prevItem:{title:"\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0",permalink:"/chess-retrospective"},nextItem:{title:"\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0",permalink:"/blackjack-retrospective"}},c={authorsImageUrls:[]},a=[{value:"GRASP(General Responsibility Assignment Software Pattern)",id:"graspgeneral-responsibility-assignment-software-pattern",level:3},{value:"\uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)",id:"\uc815\ubcf4-\uc804\ubb38\uac00-\ud328\ud134information-expert",level:3},{value:"\ucc3d\uc870\uc790 \ud328\ud134(Creator)",id:"\ucc3d\uc870\uc790-\ud328\ud134creator",level:3},{value:"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)",id:"\ub0ae\uc740-\uacb0\ud569\ub3c4-\ud328\ud134low-coupling",level:3},{value:"\ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)",id:"\ub192\uc740-\uc751\uc9d1\ub3c4-\ud328\ud134high-cohesion",level:3},{value:"\ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)",id:"\ucee8\ud2b8\ub864\ub7ec-\ud328\ud134controller",level:3},{value:"\ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)",id:"\ub2e4\ud615\uc131-\ud328\ud134polymorphism",level:3},{value:"\ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)",id:"\ubcc0\uacbd-\ubcf4\ud638-\ud328\ud134protected-variations",level:3},{value:"\uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)",id:"\uac04\uc811-\ucc38\uc870-\ud328\ud134indirection",level:3},{value:"\uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)",id:"\uc21c\uc218\ud55c-\uac00\uacf5\ubb3c-\ud328\ud134pure-fabrication",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={a:"a",blockquote:"blockquote",h3:"h3",li:"li",p:"p",ul:"ul",...(0,l.ah)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h3,{id:"graspgeneral-responsibility-assignment-software-pattern",children:"GRASP(General Responsibility Assignment Software Pattern)"}),"\n",(0,i.jsx)(n.p,{children:"\ud06c\ub808\uc774\uadf8 \ub77c\ub9cc\uc758 Applying UML and Patterns\uc774\ub77c\ub294 \ucc45\uc5d0\uc11c \ub098\uc628 \ucc45\uc784 \ud560\ub2f9\uc744 \uc704\ud55c \ud328\ud134"}),"\n",(0,i.jsx)(n.p,{children:"\uac01 \ud328\ud134\ub9c8\ub2e4 Solution\uacfc Problem\ub85c \uad6c\uc131\ub418\uc5b4 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\uc815\ubcf4-\uc804\ubb38\uac00-\ud328\ud134information-expert",children:"\uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134(Information Expert)"}),"\n",(0,i.jsx)(n.p,{children:"Q: \uac1d\uccb4\uc5d0 \ucc45\uc784\uc744 \ud560\ub2f9\ud558\ub294 \uae30\ubcf8 \uc6d0\uce59\uc740 \ubb34\uc5c7\uc778\uac00?"}),"\n",(0,i.jsx)(n.p,{children:"A: \ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub370 \ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \ud074\ub798\uc2a4(\uc815\ubcf4 \uc804\ubb38\uac00)\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc815\ubcf4\uc640 \ud589\ub3d9\uc744 \uac00\uae4c\uc6b4 \uacf3\uc5d0 \uc704\uce58\uc2dc\ud0a4\uae30 \ub54c\ubb38\uc5d0 \ucea1\uc290\ud654\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\ud544\uc694\ud55c \uc815\ubcf4\ub97c \uac00\uc9c4 \uac1d\uccb4\ub4e4\ub85c \ucc45\uc784\uc774 \ubd84\uc0b0\ub41c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\ucc3d\uc870\uc790-\ud328\ud134creator",children:"\ucc3d\uc870\uc790 \ud328\ud134(Creator)"}),"\n",(0,i.jsx)(n.p,{children:"Q: \ub204\uac00 \uac1d\uccb4 A\ub97c \uc0dd\uc131\ud558\ub294\uac00?"}),"\n",(0,i.jsx)(n.p,{children:"A: \ub2e4\uc74c\uc758 \uc870\uac74\uc744 \ucd5c\ub300\ud55c \ub9ce\uc774 \ub9cc\uc871\ud558\ub294 \uac1d\uccb4\uc5d0\uac8c \uac1d\uccb4 \uc0dd\uc131 \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \ud3ec\ud568 \ub610\ub294 \ucc38\uc870\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \uae30\ub85d\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\ub97c \uae34\ubc00\ud558\uac8c \uc0ac\uc6a9\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"B\uac00 A \uac1d\uccb4\uc758 \ucd08\uae30\uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"\uc0dd\uc131 \uc608\uc815\uc778 \uac1d\uccb4\uc640 \uc5f0\uad00\ub418\uc5b4 \uc788\ub294 \uac1d\uccb4\uac00 \uc0dd\uc131 \ucc45\uc784\uc744 \uac00\uc9c0\uace0 \uc788\uac8c \ub41c\ub2e4\uba74, \uc774\ubbf8 \ud574\ub2f9 \uac1d\uccb4\uc640 \uacb0\ud569\ub418\uc5b4\uc788\ub2e4\uace0 \uc0dd\uac01\ud560 \uc218 \uc788\ub2e4. \ub530\ub77c\uc11c \uc804\uccb4\uc801\uc778 \uacb0\ud569\ub3c4\ub97c \ub0ae\uac8c \uc720\uc9c0\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\ub0ae\uc740-\uacb0\ud569\ub3c4-\ud328\ud134low-coupling",children:"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ud328\ud134(Low Coupling)"}),"\n",(0,i.jsx)(n.p,{children:"Q: \uc758\uc874\uc131\uc744 \ub0ae\ucd94\uace0 \ubcc0\ud654\uc758 \uc601\ud5a5\uc744 \uc904\uc774\uba70 \uc7ac\uc0ac\uc6a9\uc131\uc744 \uc99d\uac00\uc2dc\ud0a4\ub294 \ubc29\ubc95\uc740?"}),"\n",(0,i.jsx)(n.p,{children:"A: \uc804\uccb4\uc801\uc778 \uacb0\ud569\uc774 \ub0ae\uac8c \uc720\uc9c0\ub418\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"\uacb0\ud569\ub3c4(Coupling)\n\uac1d\uccb4 \uc0ac\uc774\uc758 \uc758\uc874\uc131\uc774 \uacfc\ud55c \uacbd\uc6b0 \uacb0\ud569\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc624\ube0c\uc81d\ud2b8 p.17"}),"\n"]}),"\n",(0,i.jsx)(n.blockquote,{children:"\n"}),"\n",(0,i.jsx)(n.p,{children:"\uacb0\ud569\ub3c4\ub97c \ub0ae\ucd98\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\ub2e4\ub978 \uad6c\uc131 \uc694\uc18c\uc758 \ubcc0\ud654\uc5d0 \uc601\ud5a5\uc744 \ubc1b\uc9c0 \uc54a\ub294\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\uc7ac\uc0ac\uc6a9\uc774 \ud3b8\ub9ac\ud574\uc9c4\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\uc758\uc874\ud558\ub294 \ud074\ub798\uc2a4\uac00 \uc801\uae30 \ub54c\ubb38\uc5d0)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ub192\uc740-\uc751\uc9d1\ub3c4-\ud328\ud134high-cohesion",children:"\ub192\uc740 \uc751\uc9d1\ub3c4 \ud328\ud134(High Cohesion)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \uac1d\uccb4\ub97c \uad00\ub9ac\ud558\uae30 \uc27d\uac8c \ud558\ub824\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. \ub192\uc740 \uc751\uc9d1\ub3c4\ub97c \uc720\uc9c0\ud560 \uc218 \uc788\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsxs)(n.blockquote,{children:["\n",(0,i.jsx)(n.p,{children:"\uc751\uc9d1\ub3c4(Cohesion)\n\uc5f0\uad00\ub41c \uc791\uc5c5\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc5f0\uad00\uc131 \uc5c6\ub294 \uc791\uc5c5\uc740 \ub2e4\ub978 \uac1d\uccb4\uc5d0\uac8c \uc704\uc784\ud558\ub294 \uac1d\uccb4\ub97c \uac00\ub9ac\ucf1c \uc751\uc9d1\ub3c4\uac00 \ub192\ub2e4\uace0 \ub9d0\ud55c\ub2e4."}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc624\ube0c\uc81d\ud2b8 p.26"}),"\n"]}),"\n",(0,i.jsx)(n.blockquote,{children:"\n"}),"\n",(0,i.jsx)(n.p,{children:"\ubcc0\uacbd\uc758 \uc774\uc720\uc5d0 \ub530\ub77c \ud074\ub798\uc2a4\ub97c \ubd84\ub9ac\ud55c\ub2e4\uba74 \uc751\uc9d1\ub3c4\ub97c \ub192\uc77c \uc218 \uc788\uace0, \uc751\uc9d1\ub3c4\uac00 \ub192\uc544\uc9c4\ub2e4\uba74 \ub2e4\uc74c\uacfc \uac19\uc740 \uc774\uc810\uc774 \uc788\ub2e4."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\ud574\ub2f9 \ud074\ub798\uc2a4\uc5d0 \ub300\ud55c \uc774\ud574\uac00 \uc26c\uc6cc\uc9c4\ub2e4. (\ud560\ub2f9\ub41c \ucc45\uc784\ub9cc\uc744 \uc218\ud589\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0)"}),"\n",(0,i.jsx)(n.li,{children:"\uc720\uc9c0\ubcf4\uc218\uac00 \uc26c\uc6cc\uc9c4\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\ub0ae\uc740 \uacb0\ud569\ub3c4 \ub610\ud55c \uc9c0\uc6d0\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\uc751\uc9d1\ub3c4\uac00 \ub192\uc740 \ud074\ub798\uc2a4\ub294 \ud2b9\uc815\ud55c \ubaa9\uc801\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc7ac\uc0ac\uc6a9\ud558\uae30 \uc88b\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ucee8\ud2b8\ub864\ub7ec-\ud328\ud134controller",children:"\ucee8\ud2b8\ub864\ub7ec \ud328\ud134(Controller)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 \uac83\uc740 \ub204\uac00 \ub2f4\ub2f9\ud574\uc57c \ud558\ub294\uac00?"}),"\n",(0,i.jsx)(n.p,{children:"A. \uc0ac\uc6a9\uc790\uc758 \uc694\uccad\uc744 \ucc98\ub9ac\ud558\ub294 Controller \uac1d\uccb4\ub97c \ub9cc\ub4e4\uc5b4\uc11c \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc5b4\ub5a4 \uc11c\ube0c\uc2dc\uc2a4\ud15c\uc774 \uc874\uc7ac\ud55c\ub2e4\uace0 \uac00\uc815\ud560 \ub54c"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc9c1\uc811\uc801\uc73c\ub85c \uac1d\uccb4\uc5d0 \uc811\uadfc\ud558\uc5ec \ud504\ub85c\uadf8\ub7a8\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uacb0\ud569\ub3c4\uac00 \uc0c1\uc2b9\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\uc11c\ube0c \uc2dc\uc2a4\ud15c\uc5d0 \ub4e4\uc5b4\uc624\ub294 \uc694\uccad\uc744 \ucc98\ub9ac\ud574\uc8fc\ub294 \ucee8\ud2b8\ub864\ub7ec\uac00 \uc788\ub2e4\uba74 \uc0ac\uc6a9\ud558\ub294 \uc785\uc7a5\uc5d0\uc11c\ub294 \ud574\ub2f9 \ucee8\ud2b8\ub864\ub7ec\ub9cc \uc54c\uba74 \ub41c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\ub9cc\uc57d \uc11c\ube0c \uc2dc\uc2a4\ud15c\uc758 \ubcc0\uacbd\uc774 \uc0dd\uacbc\uc744 \ub54c \uc678\ubd80\uc5d0 \ubbf8\uce58\ub294 \uc601\ud5a5\ub3c4 \uc904\uc5b4\ub4e0\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ub2e4\ud615\uc131-\ud328\ud134polymorphism",children:"\ub2e4\ud615\uc131 \ud328\ud134(Polymorphism)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \uac1d\uccb4\uc758 \ud0c0\uc785\uc5d0 \ub530\ub77c \ud589\ub3d9\uc774 \ubc14\ub010\ub2e4\uba74 \ucc45\uc784\uc744 \uc5b4\ub5bb\uac8c \ud560\ub2f9\ud574\uc57c \ud560\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. OOP\uac00 \uc9c0\uc6d0\ud558\ub294 \ub2e4\ud615\uc131\uc744 \uc801\uadf9\uc801\uc73c\ub85c \ud65c\uc6a9\ud55c\ub2e4. (\uc778\ud130\ud398\uc774\uc2a4\ub97c \ub450\uace0 \ud589\ub3d9\uc5d0 \ub300\ud55c \ubd80\ubd84\uc744 \uad6c\ud604)"}),"\n",(0,i.jsx)(n.p,{children:"\uac1d\uccb4\uc758 \uc885\ub958\uc5d0 \ub530\ub77c \ubd84\uae30\ud558\ub294 \uc870\uac74\ubb38\uc774 \uc544\ub2cc \ub2e4\ud615\uc131\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \uc88b\uc740 \ubc29\ubc95\uc774\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc0c8\ub85c\uc6b4 \ud0c0\uc785\uc774 \ucd94\uac00\ub418\uc5c8\uc744 \ub54c \uc870\uac74\ubb38\uc744 \uc0ac\uc6a9\ud55c\ub2e4\uba74 \uae30\uc874\uc758 \uc870\uac74\ubb38\uc744 \uc218\uc815\ud574\uc57c \ud558\uc9c0\ub9cc \ub2e4\ud615\uc131\uc744 \ud65c\uc6a9\ud558\uba74 \uc27d\uac8c \ud655\uc7a5\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\ubcc0\uacbd-\ubcf4\ud638-\ud328\ud134protected-variations",children:"\ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \uc5b4\ub5bb\uac8c \ud558\uba74 \ubcc0\uacbd\uc774 \ub2e4\ub978 \uc694\uc18c\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub3c4\ub85d \ubc29\uc9c0\ud560 \uc218 \uc788\uc744\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. \ubcc0\ud654\uac00 \uc608\uc0c1\ub418\ub294 \uc9c0\uc810\uc744 \uc2dd\ubcc4\ud558\uace0, \uc8fc\uc704\uc5d0 \uc548\uc815\ub41c \uc778\ud130\ud398\uc774\uc2a4\ub97c \ud615\uc131\ud558\ub3c4\ub85d \ucc45\uc784\uc744 \ud560\ub2f9\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\uac04\uc811-\ucc38\uc870-\ud328\ud134indirection",children:"\uac04\uc811 \ucc38\uc870 \ud328\ud134(Indirection)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc758 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud558\uace0 \uc2f6\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ub2e4\ub978 \uac1d\uccb4\ub97c \ub450\uc5b4 \uc9c1\uc811\uc801\uc778 \uc5f0\uacb0\uc744 \ud53c\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc911\uc7ac\uc790 \ud328\ud134\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub450 \uac1d\uccb4 \uc0ac\uc774\uc5d0 \ub610 \ud558\ub098\uc758 \uac1d\uccb4\ub97c \ucd94\uac00\ud558\uc5ec \ubcf5\uc7a1\ud55c \uad00\uacc4\ub97c \ub2e8\uc21c\ud654\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc911\uac04\uc5d0 \uc778\ud130\ud398\uc774\uc2a4\ub97c \ub454\ub2e4\uba74 \ubcc0\uacbd \ubcf4\ud638 \ud328\ud134(Protected Variations)\uc5d0 \ud574\ub2f9\ub41c\ub2e4."}),"\n",(0,i.jsx)(n.h3,{id:"\uc21c\uc218\ud55c-\uac00\uacf5\ubb3c-\ud328\ud134pure-fabrication",children:"\uc21c\uc218\ud55c \uac00\uacf5\ubb3c \ud328\ud134(Pure Fabrication)"}),"\n",(0,i.jsx)(n.p,{children:"Q. \ucc45\uc784\uc744 \ud560\ub2f9\ud55c \ub3c4\uba54\uc778 \uac1d\uccb4\uac00 Low Coupling, High Cohesion, \uc7ac\uc0ac\uc6a9\uc131 \ub4f1\uc758 \ubaa9\uc801\uc744 \uc704\ubc18\ud55c\ub2e4\uba74 \uc5b4\ub5bb\uac8c \ud574\uc57c \ud560\uae4c?"}),"\n",(0,i.jsx)(n.p,{children:"A. \ub3c4\uba54\uc778 \uac1c\ub150\uc744 \ud3ec\ud568\ud558\uc9c0 \uc54a\ub294 \ud074\ub798\uc2a4\ub97c \ud558\ub098 \ub9cc\ub4e4\uace0 \ub9e4\uc6b0 \uc751\uc9d1\ub41c \ucc45\uc784\uc744 \ud560\ub2f9\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\ud589\ub3d9\uc744 \ucd94\uac00\ud560 \ub54c, \ud574\ub2f9 \ucc45\uc784\uc744 \uc218\ud589\ud560 \ub3c4\uba54\uc778 \uac1c\ub150\uc774 \uc874\uc7ac\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 \ub3c4\uba54\uc778\uacfc \ubb34\uad00\ud55c \uc778\uacf5\uc801\uc778 \uac1d\uccb4\ub97c \ub9cc\ub4e0\ub2e4\uc74c \ud574\ub2f9 \uac1d\uccb4\uc5d0\uac8c \ucc45\uc784\uc744 \ud560\ub2f9\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uac1d\uccb4\uac00 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud574\uc57c \ud560 \uac12\uc744 \uac00\uc9c0\uace0 \uc788\ub2e4\uace0, \uc815\ubcf4 \uc804\ubb38\uac00 \ud328\ud134\uc744 \uc801\uc6a9\ud558\uc5ec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc800\uc7a5\ud558\ub77c\ub294 \ucc45\uc784\uc744 \uac00\uc9c0\ub77c\uace0 \ud558\uc9c0 \uc54a\ub294\ub2e4."}),"\n",(0,i.jsx)(n.p,{children:"\uc608) \uc0c1\uc810\uacfc \uace0\uac1d \ud074\ub798\uc2a4\uac00 \uc788\uace0 \uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\ub2e4\uace0 \uac00\uc815"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"\uc11c\ub85c \ub2e4\ub978 \ud1b5\ud654\ub97c \uc0ac\uc6a9\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0 \uac70\ub798\ub97c \ud558\ub824\uba74 \ud658\uc804\uc744 \ud574\uc57c\ud55c\ub2e4."}),"\n",(0,i.jsx)(n.li,{children:"\ub450 \ud074\ub798\uc2a4 \ub2e4 \ud658\uc804\uc5d0 \ub300\ud55c \ucc45\uc784\uc744 \ubd80\uc5ec\ud558\uae30 \uc560\ub9e4\ud558\ub2e4\uba74 \ud658\uc804\uc744 \ucc45\uc784\ud558\ub294 \ud074\ub798\uc2a4\ub97c \ucd94\uac00\ud558\uace0 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4."}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,i.jsxs)(n.p,{children:["\uc624\ube0c\uc81d\ud2b8 5\uc7a5. \ucc45\uc784 \ud560\ub2f9\ud558\uae30, ",(0,i.jsx)(n.a,{href:"http://aeternum.egloos.com/",children:"\uc870\uc601\ud638"})]}),"\n",(0,i.jsx)(n.p,{children:"Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"https://www.hanbit.co.kr/network/category/category_view.html?cms_code=CMS8586826397",children:"GRASP, \ud55c\ube5b \ub124\ud2b8\uc6cc\ud06c"})})]})}function h(e={}){const{wrapper:n}={...(0,l.ah)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var i=r(67294);function l(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function t(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);n&&(i=i.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,i)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?t(Object(r),!0).forEach((function(n){l(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):t(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function o(e,n){if(null==e)return{};var r,i,l=function(e,n){if(null==e)return{};var r,i,l={},t=Object.keys(e);for(i=0;i<t.length;i++)r=t[i],n.indexOf(r)>=0||(l[r]=e[r]);return l}(e,n);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);for(i=0;i<t.length;i++)r=t[i],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(l[r]=e[r])}return l}var c=i.createContext({}),a=function(e){var n=i.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},d={inlineCode:"code",wrapper:function(e){var n=e.children;return i.createElement(i.Fragment,{},n)}},h=i.forwardRef((function(e,n){var r=e.components,l=e.mdxType,t=e.originalType,c=e.parentName,h=o(e,["components","mdxType","originalType","parentName"]),p=a(r),j=l,x=p["".concat(c,".").concat(j)]||p[j]||d[j]||t;return r?i.createElement(x,s(s({ref:n},h),{},{components:r})):i.createElement(x,s({ref:n},h))}));h.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/eae2a611.d922a965.js b/assets/js/eae2a611.d922a965.js deleted file mode 100644 index cd8adaaae..000000000 --- a/assets/js/eae2a611.d922a965.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6180],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>m});var n=r(67294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){a(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,a=function(e,t){if(null==e)return{};var r,n,a={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var o=n.createContext({}),p=function(e){var t=n.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(o.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,i=e.originalType,o=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=p(r),m=a,f=d["".concat(o,".").concat(m)]||d[m]||s[m]||i;return r?n.createElement(f,c(c({ref:t},u),{},{components:r})):n.createElement(f,c({ref:t},u))}));function m(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=r.length,c=new Array(i);c[0]=d;var l={};for(var o in t)hasOwnProperty.call(t,o)&&(l[o]=t[o]);l.originalType=e,l.mdxType="string"==typeof e?e:a,c[1]=l;for(var p=2;p<i;p++)c[p]=r[p];return n.createElement.apply(null,c)}return n.createElement.apply(null,r)}d.displayName="MDXCreateElement"},87990:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>o,contentTitle:()=>c,default:()=>s,frontMatter:()=>i,metadata:()=>l,toc:()=>p});var n=r(87462),a=(r(67294),r(3905));const i={title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",slug:"/architecture/virtical-slice-architecture",last_update:{date:"2023/09/22"},tags:["architecture"]},c=void 0,l={unversionedId:"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",id:"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",description:"\uac1c\uc694",source:"@site/docs/\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98.mdx",sourceDirName:"\uc544\ud0a4\ud14d\ucc98",slug:"/architecture/virtical-slice-architecture",permalink:"/docs/architecture/virtical-slice-architecture",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98.mdx",tags:[{label:"architecture",permalink:"/docs/tags/architecture"}],version:"current",lastUpdatedAt:1695340800,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 22\uc77c",frontMatter:{title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",slug:"/architecture/virtical-slice-architecture",last_update:{date:"2023/09/22"},tags:["architecture"]},sidebar:"tutorialSidebar",previous:{title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",permalink:"/docs/spring/essence"},next:{title:"FIRST",permalink:"/docs/test/first"}},o={},p=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\ud2b9\uc9d5",id:"\ud2b9\uc9d5",level:3},{value:"\uc8fc\uc758 \uc0ac\ud56d",id:"\uc8fc\uc758-\uc0ac\ud56d",level:3},{value:"\ud14c\uc2a4\ud2b8 \uc791\uc131",id:"\ud14c\uc2a4\ud2b8-\uc791\uc131",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:p};function s(e){let{components:t,...r}=e;return(0,a.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"\uac1c\uc694"},"\uac1c\uc694"),(0,a.kt)("p",null,"\uae30\uc874\uc758 Layered Architecture \u2192 \ub808\uc774\uc5b4\ubcc4 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \ub098\ub220\uc11c \uad6c\ud604",(0,a.kt)("br",{parentName:"p"}),"\n","Virtical Slice Architecture \u2192 Feature\ub77c\ub294 \ud558\ub098\uc758 \ud074\ub798\uc2a4\uc5d0 \uc751\uc9d1\uc2dc\ucf1c \uad6c\ud604\ud558\ub294 \uad6c\uc870"),(0,a.kt)("h3",{id:"\ud2b9\uc9d5"},"\ud2b9\uc9d5"),(0,a.kt)("p",null,"Transactional\uacfc Controller\uac00 \uac19\uc774 \ubd99\uc5b4\uc788\ub294 \ud615\ud0dc\ub97c \ub748\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ube60\ub978 \ud53c\ub4dc\ubc31 \uc0ac\uc774\ud074\uc744 \uac00\uc9c4 \uc2e0\uaddc \uc11c\ube44\uc2a4\uc758 \uacbd\uc6b0 \ud575\uc2ec \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\uc774 \uac00\ub2a5\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae30\ub2a5\ubcc4\ub85c \uad6c\ud604\ud558\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc774\ub4dc \uc774\ud399\ud2b8\uac00 \uc801\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc791\uc740 \uaddc\ubaa8\uc758 \uc870\uc9c1, \ucf54\ub4dc \ud488\uc9c8 \uad00\ub9ac\uac00 \uc774\ub8e8\uc5b4\uc9c0\ub294 \uc870\uc9c1\uc5d0 \uc801\ud569\ud558\ub2e4. "),(0,a.kt)("h3",{id:"\uc8fc\uc758-\uc0ac\ud56d"},"\uc8fc\uc758 \uc0ac\ud56d"),(0,a.kt)("p",null,"\ud55c \uacf3\uc5d0 \uae30\ub2a5\uc774 \uc9d1\uc911\ub418\uc5b4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud30c\uac8c\ud2f0 \ucf54\ub4dc\uac00 \ub418\uc9c0 \uc54a\ub3c4\ub85d \uc9c0\uc18d\uc801\uc73c\ub85c \ucf54\ub4dc \ud488\uc9c8\uc744 \uad00\ub9ac\ud574\uc57c\ud55c\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","DB\uc5d0 \ubc14\ub85c \uc811\uadfc\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 DB \uc911\uc2ec\uc758 \uac1c\ubc1c\uc774 \ub418\uc9c0 \uc54a\ub3c4\ub85d \uc8fc\uc758\ud574\uc57c \ud55c\ub2e4. "),(0,a.kt)("h3",{id:"\ud14c\uc2a4\ud2b8-\uc791\uc131"},"\ud14c\uc2a4\ud2b8 \uc791\uc131"),(0,a.kt)("p",null,"API \u2192 \ud1b5\ud569 \ud14c\uc2a4\ud2b8\n\ub3c4\uba54\uc778 -> \ub2e8\uc704 \ud14c\uc2a4\ud2b8"),(0,a.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,a.kt)("p",null,"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98, \uc720\uc2a4\ucf58 23",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=SUiWfhAhgQw&t=2116s"},"Vertical Slice Architecture, NDC, Jimmy Bogard"),(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("a",{parentName:"p",href:"https://www.jimmybogard.com/vertical-slice-architecture/"},"Vertical Slice Architecture, Jimmy Bogard")))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/eae2a611.e9e2c2a6.js b/assets/js/eae2a611.e9e2c2a6.js new file mode 100644 index 000000000..941569cfe --- /dev/null +++ b/assets/js/eae2a611.e9e2c2a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6180],{47599:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>o});var n=r(85893),c=r(3905);const i={title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",slug:"/architecture/virtical-slice-architecture",last_update:{date:"2023/09/22"},tags:["architecture"]},a=void 0,l={id:"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",description:"\uac1c\uc694",source:"@site/docs/\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98.mdx",sourceDirName:"\uc544\ud0a4\ud14d\ucc98",slug:"/architecture/virtical-slice-architecture",permalink:"/docs/architecture/virtical-slice-architecture",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98.mdx",tags:[{label:"architecture",permalink:"/docs/tags/architecture"}],version:"current",lastUpdatedAt:1695340800,formattedLastUpdatedAt:"2023\ub144 9\uc6d4 22\uc77c",frontMatter:{title:"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98",slug:"/architecture/virtical-slice-architecture",last_update:{date:"2023/09/22"},tags:["architecture"]},sidebar:"tutorialSidebar",previous:{title:"\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5",permalink:"/docs/spring/essence"},next:{title:"FIRST",permalink:"/docs/test/first"}},s={},o=[{value:"\uac1c\uc694",id:"\uac1c\uc694",level:3},{value:"\ud2b9\uc9d5",id:"\ud2b9\uc9d5",level:3},{value:"\uc8fc\uc758 \uc0ac\ud56d",id:"\uc8fc\uc758-\uc0ac\ud56d",level:3},{value:"\ud14c\uc2a4\ud2b8 \uc791\uc131",id:"\ud14c\uc2a4\ud2b8-\uc791\uc131",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function u(e){const t={a:"a",br:"br",h3:"h3",p:"p",...(0,c.ah)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.h3,{id:"\uac1c\uc694",children:"\uac1c\uc694"}),"\n",(0,n.jsxs)(t.p,{children:["\uae30\uc874\uc758 Layered Architecture \u2192 \ub808\uc774\uc5b4\ubcc4 \uc5ed\ud560\uacfc \ucc45\uc784\uc744 \ub098\ub220\uc11c \uad6c\ud604",(0,n.jsx)(t.br,{}),"\n","Virtical Slice Architecture \u2192 Feature\ub77c\ub294 \ud558\ub098\uc758 \ud074\ub798\uc2a4\uc5d0 \uc751\uc9d1\uc2dc\ucf1c \uad6c\ud604\ud558\ub294 \uad6c\uc870"]}),"\n",(0,n.jsx)(t.h3,{id:"\ud2b9\uc9d5",children:"\ud2b9\uc9d5"}),"\n",(0,n.jsxs)(t.p,{children:["Transactional\uacfc Controller\uac00 \uac19\uc774 \ubd99\uc5b4\uc788\ub294 \ud615\ud0dc\ub97c \ub748\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\ube60\ub978 \ud53c\ub4dc\ubc31 \uc0ac\uc774\ud074\uc744 \uac00\uc9c4 \uc2e0\uaddc \uc11c\ube44\uc2a4\uc758 \uacbd\uc6b0 \ud575\uc2ec \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc5d0 \uc9d1\uc911\uc774 \uac00\ub2a5\ud558\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uae30\ub2a5\ubcc4\ub85c \uad6c\ud604\ud558\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc774\ub4dc \uc774\ud399\ud2b8\uac00 \uc801\ub2e4.",(0,n.jsx)(t.br,{}),"\n","\uc791\uc740 \uaddc\ubaa8\uc758 \uc870\uc9c1, \ucf54\ub4dc \ud488\uc9c8 \uad00\ub9ac\uac00 \uc774\ub8e8\uc5b4\uc9c0\ub294 \uc870\uc9c1\uc5d0 \uc801\ud569\ud558\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\uc8fc\uc758-\uc0ac\ud56d",children:"\uc8fc\uc758 \uc0ac\ud56d"}),"\n",(0,n.jsxs)(t.p,{children:["\ud55c \uacf3\uc5d0 \uae30\ub2a5\uc774 \uc9d1\uc911\ub418\uc5b4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc2a4\ud30c\uac8c\ud2f0 \ucf54\ub4dc\uac00 \ub418\uc9c0 \uc54a\ub3c4\ub85d \uc9c0\uc18d\uc801\uc73c\ub85c \ucf54\ub4dc \ud488\uc9c8\uc744 \uad00\ub9ac\ud574\uc57c\ud55c\ub2e4.",(0,n.jsx)(t.br,{}),"\n","DB\uc5d0 \ubc14\ub85c \uc811\uadfc\ud560 \uc218 \uc788\uae30 \ub54c\ubb38\uc5d0 DB \uc911\uc2ec\uc758 \uac1c\ubc1c\uc774 \ub418\uc9c0 \uc54a\ub3c4\ub85d \uc8fc\uc758\ud574\uc57c \ud55c\ub2e4."]}),"\n",(0,n.jsx)(t.h3,{id:"\ud14c\uc2a4\ud2b8-\uc791\uc131",children:"\ud14c\uc2a4\ud2b8 \uc791\uc131"}),"\n",(0,n.jsx)(t.p,{children:"API \u2192 \ud1b5\ud569 \ud14c\uc2a4\ud2b8\n\ub3c4\uba54\uc778 -> \ub2e8\uc704 \ud14c\uc2a4\ud2b8"}),"\n",(0,n.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,n.jsxs)(t.p,{children:["\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98, \uc720\uc2a4\ucf58 23",(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.a,{href:"https://www.youtube.com/watch?v=SUiWfhAhgQw&t=2116s",children:"Vertical Slice Architecture, NDC, Jimmy Bogard"}),(0,n.jsx)(t.br,{}),"\n",(0,n.jsx)(t.a,{href:"https://www.jimmybogard.com/vertical-slice-architecture/",children:"Vertical Slice Architecture, Jimmy Bogard"})]})]})}function d(e={}){const{wrapper:t}={...(0,c.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>o});var n=r(67294);function c(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){c(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,c=function(e,t){if(null==e)return{};var r,n,c={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(c[r]=e[r]);return c}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(c[r]=e[r])}return c}var s=n.createContext({}),o=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,c=e.mdxType,i=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=o(r),h=c,f=p["".concat(s,".").concat(h)]||p[h]||u[h]||i;return r?n.createElement(f,a(a({ref:t},d),{},{components:r})):n.createElement(f,a({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/ee1dd2ad.69ff89bd.js b/assets/js/ee1dd2ad.8c78f348.js similarity index 77% rename from assets/js/ee1dd2ad.69ff89bd.js rename to assets/js/ee1dd2ad.8c78f348.js index 2337d8e8a..9d1cab239 100644 --- a/assets/js/ee1dd2ad.69ff89bd.js +++ b/assets/js/ee1dd2ad.8c78f348.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5435],{48834:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5435],{48834:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/ee92877e.d75057f6.js b/assets/js/ee92877e.be8e94b0.js similarity index 81% rename from assets/js/ee92877e.d75057f6.js rename to assets/js/ee92877e.be8e94b0.js index 4dedfbb4f..fe7d2f599 100644 --- a/assets/js/ee92877e.d75057f6.js +++ b/assets/js/ee92877e.be8e94b0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8716],{41106:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8716],{41106:e=>{e.exports=JSON.parse('{"label":"Retrospective","permalink":"/tags/retrospective","allTagsPath":"/tags","count":20,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/eff1d58f.886bd191.js b/assets/js/eff1d58f.886bd191.js new file mode 100644 index 000000000..9f1ed2af9 --- /dev/null +++ b/assets/js/eff1d58f.886bd191.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4137],{68801:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>d,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var r=t(85893),c=t(3905);const a={title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",slug:"tecochat-retrospective-1",tags:["TecoChat","Retrospective"]},s=void 0,i={permalink:"/tecochat-retrospective-1",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",source:"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",description:"4\uc6d4 21\uc77c \uae08\uc694\uc77c",date:"2023-04-22T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 22\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.68,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",slug:"tecochat-retrospective-1",tags:["TecoChat","Retrospective"]},unlisted:!1,prevItem:{title:"Jenkins\ub85c CI/CD \uc124\uc815",permalink:"/jenkins"},nextItem:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",permalink:"/book-leadership-and-self-deception"}},o={authorsImageUrls:[]},l=[{value:"4\uc6d4 21\uc77c \uae08\uc694\uc77c",id:"4\uc6d4-21\uc77c-\uae08\uc694\uc77c",level:3},{value:"\ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?",id:"\ub3c4\uba54\uc778-\uad6c\uc785-\uc131\uacf5",level:3},{value:"\ub9d0\ub791\uc758 DM",id:"\ub9d0\ub791\uc758-dm",level:3},{value:"\ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec",id:"\ub3c4\uba54\uc778-\uc124\uc815-\ubc0f-\ubc30\ud3ec",level:3},{value:"GPT",id:"gpt",level:3},{value:"Sonarcloud",id:"sonarcloud",level:3},{value:"Tiptap",id:"tiptap",level:3},{value:"\ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9",id:"\ud3f0\ud2b8-\ubc0f-favicon-\uc801\uc6a9",level:3}];function p(e){const n={br:"br",code:"code",h3:"h3",img:"img",p:"p",pre:"pre",...(0,c.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"4\uc6d4-21\uc77c-\uae08\uc694\uc77c",children:"4\uc6d4 21\uc77c \uae08\uc694\uc77c"}),"\n",(0,r.jsxs)(n.p,{children:["\ub808\ubca8 2\ub97c \uc2dc\uc791\ud55c \ub4a4 \ub0b4\uac00 \ud559\uc2b5\uc5d0 \ub300\ud55c \ubc29\ud5a5\uc744 \uc783\uc5b4\ubc84\ub838\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub808\ubca8 3, 4\uc5d0\uc11c \ub098\ub9cc\uc758 \uac15\uc810\uc744 \uac00\uc9c0\uace0 \uc2f6\uc5b4 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub2e8\uc21c\ud788 \uc2a4\ud504\ub9c1\uc744 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ud6a8\uc728\uc774 \ub9ce\uc774 \ub5a8\uc5b4\uc9c4\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uae00\uc4f0\uae30 \uc218\uc0c1\uc73c\ub85c \ubc1b\uc740 \ucfe0\ud3f0\uc744 \uc0ac\uc6a9\ud574 \ube0c\ub77c\uc6b4\uc5d0\uac8c \ucee4\ud53c\ucc57\uc744 \uc2e0\uccad\ud588\uace0, \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud574\ubcf4\ub77c\ub294 \ub2f5\uc744 \ubc1b\uc558\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\ub098\ub294 \uc544\uc774\ub514\uc5b4\ub97c \ubabb\ub0b4\ub294 \ud3b8\uc778\ub370 \ube0c\ub77c\uc6b4\uc774 \uc544\uc774\ub514\uc5b4\uae4c\uc9c0 \ub358\uc838\uc8fc\uc168\ub2e4.",(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.code,{children:"Chat-GPT \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uace0, \ud574\ub2f9 \ud06c\ub8e8\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc744 \uacf5\uc720\ud560 \uc218 \uc788\ub294 \uac74 \uc5b4\ub5a4\uc9c0?"})]}),"\n",(0,r.jsxs)(n.p,{children:["\uae30\uc220\uc774 \ubaa9\uc801\uc778 \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4\ub294 \ub2f5\ubcc0\uc744 \ub4e4\uc5c8\uace0, \ud63c\uc790 \uc544\ub2c8\uba74 \ud398\uc5b4\ud560 \uc218 \uc788\uc744 \uc815\ub3c4\uc758 \uc778\uc6d0\uc73c\ub85c \uc9c4\ud589\ud558\uba74 \uc88b\uaca0\ub2e4\uace0 \ud558\uc168\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ud504\ub860\ud2b8\ub791 \uac04\ub2e8\ud558\uac8c \ubc30\ud3ec\uae4c\uc9c0 \ud574\ubcf8 \uacbd\ud5d8\uc774 \uc788\uc5b4\uc11c \ud63c\uc790\ud574\ub3c4 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uc744 \uac83 \uac19\uc544\uc11c \ud63c\uc790 \ud558\uae30\ub85c \ub9c8\uc74c\uc744 \uba39\uc5c8\ub2e4."]}),"\n",(0,r.jsx)(n.p,{children:"\uc774\uac74 \ubabb\ucc38\uc9c0"}),"\n",(0,r.jsx)(n.h3,{id:"\ub3c4\uba54\uc778-\uad6c\uc785-\uc131\uacf5",children:"\ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?"}),"\n",(0,r.jsxs)(n.p,{children:["\ucee4\ud53c\ucc57\uc774 \ub05d\ub098\uace0 \uc9d1\uc73c\ub85c \ub3cc\uc544\uac00\ub294 \uae38\uc5d0 \ubc14\ub85c \ub3c4\uba54\uc778\uc744 \uad6c\ub9e4\ud558\ub824\uace0 namecheap\uc5d0\uc11c \uc801\ub2f9\ud55c \ub3c4\uba54\uc778\uc774 \uc5c6\uc744\uae4c \uac80\uc0c9\uc744 \uacc4\uc18d\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub9c8\uce58 \uc5b4\ub9b4 \ub54c \ud588\ub358 \uac8c\uc784 \ub2c9\ub124\uc784 \uc815\ud558\ub294 \uac83\ucc98\ub7fc \uc2dc\uac04\uc774 \uc624\ub798 \uac78\ub838\ub2e4.",(0,r.jsx)(n.br,{}),"\n","dev, io, chat \ub3c4\uba54\uc778\uc774 \ud6c4\ubcf4\uc600\uace0 \uc9d1 \uac00\ub294 \uae38\uc5d0 \uacb0\uc815\ub9cc \ud558\ub2e4\uac00 \uad6c\ub9e4\ud558\uc9c0 \ubabb\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\ub9d0\ub791\uc758-dm",children:"\ub9d0\ub791\uc758 DM"}),"\n",(0,r.jsxs)(n.p,{children:["\uc9d1\uc5d0 \uac00\uc11c \ubc25\uc744 \uba39\uace0 \ub9d0\ub791\uc774\ub791 DM \ud558\ub2e4 \ud504\ub85c\uc81d\ud2b8\ub97c \uac19\uc774 \ud558\uc790\ub294 \uc774\uc57c\uae30\uac00 \ub098\uc654\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc6b0\ud14c\ucf54 \ucd5c\uace0 \uace0\uc218 \ub9d0\ub791\uc758 \uc694\uad6c\ub77c \uc218\ub77d\ud558\uc9c0 \uc54a\uc73c\uba74 \ud6c4\ud3ed\ud48d\uc744 \uac10\ub2f9\ud560 \uc218 \uc5c6\uc5c8\ub2e4."]}),"\n",(0,r.jsxs)(n.p,{children:["\uc774\ub7f0\uc800\ub7f0 \ub300\ud654\ub97c \ub098\ub204\ub2e4\uac00 \ub09c \ube60\ub974\uac8c \ud504\ub85c\ud1a0\ud0c0\uc785\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\uace0 \uc2f6\uc5b4\uc11c \ud504\ub860\ud2b8\ub97c \uad6c\ud604\ud55c\ub2e4\uace0 \ud588\uace0, \ub9d0\ub791\uc740 GPT api\ub97c \uc870\uc0ac\ud558\uae30\ub85c \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ub3c4\uba54\uc778\uc5d0 \uad00\ud55c \uc774\uc57c\uae30\ub97c \ud558\ub2e4\uac00 woowachat\uc774 \uc5b8\uae09\ub418\uc5c8\uace0, namecheap\uc5d0\uc11c chat \ub3c4\uba54\uc778\uc744 \uc0ac\uc6a9\ud55c woowa.chat\uc73c\ub85c \uad6c\ub9e4\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc774\ud6c4\uc5d0 teco.chat\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4!"]}),"\n",(0,r.jsx)(n.h3,{id:"\ub3c4\uba54\uc778-\uc124\uc815-\ubc0f-\ubc30\ud3ec",children:"\ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec"}),"\n",(0,r.jsxs)(n.p,{children:["\ud1a0\uc694\uc77c\uc5d0 \uad6c\ub9e4\ud55c \ub3c4\uba54\uc778\uc744 CDN, \ubcf4\uc548 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\ub294 Cloudflare\uc5d0 \ub3c4\uba54\uc778 \ub4f1\ub85d\uc744 \ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub098\uc5d0\uac8c \uc775\uc219\ud55c Nuxt3\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\uace0, Cloudflare Pages\ub97c \uc774\uc6a9\ud558\uc5ec \ubc30\ud3ec\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"gpt",children:"GPT"}),"\n",(0,r.jsxs)(n.p,{children:["\ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud558\ub2c8 api limit\uc774 \uc788\uc5b4 \ubd84\ub2f9 3\ubc88\ubc16\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc77c\ub2e8 \ubc31\uc5d4\ub4dc\ub97c \uad6c\ucd95\ud558\uae30 \uc804\uc5d0\ub294 \ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud560 \uc0dd\uac01\uc774\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"sonarcloud",children:"Sonarcloud"}),"\n",(0,r.jsxs)(n.p,{children:["\uc815\uc801 \ucf54\ub4dc \ubd84\uc11d \ub3c4\uad6c\ub85c Sonarcloud\ub97c \uc801\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Sonarcloud\ub294 SonarQube\uc758 SaaS \ubc84\uc804\uc774\uace0 \uc0ac\uc6a9\uc774 \ub9e4\uc6b0 \ud3b8\ud558\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc608\uc804\uc5d0 Sonarcloud\ub97c \uc0ac\uc6a9\ud560 \ub550 \ubc84\ud2bc \uba87 \ubc88 \ub204\ub974\uba74 \uc801\uc6a9\ud560 \uc218 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \ubc14\ub85c github action\uc744 \uc0ac\uc6a9\ud558\ub77c\ub294 \uc548\ub0b4 \ud398\uc774\uc9c0\ub85c \uc774\ub3d9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Sonarcloud\uac00 \uc790\uccb4\uc801\uc73c\ub85c github repository\uc5d0 push \ud558\uba74 \uc815\uc801 \ubd84\uc11d\uc744 \ud574\uc8fc\ub294 \uae30\ub2a5\uc744 \uc6d0\ud588\uace0, Administration -> Analysis Method\uc5d0 Automatic Analysis\ub97c \uc124\uc815\ud558\ub2c8 \ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub108\ubb34 \uaf41\uaf41 \uc228\uaca8\uc838\uc788\ub124"]}),"\n",(0,r.jsx)(n.h3,{id:"tiptap",children:"Tiptap"}),"\n",(0,r.jsxs)(n.p,{children:["\ucf54\ub4dc \ud558\uc774\ub77c\uc774\ud305 \uae30\ub2a5\uc744 \ub123\uace0 \uc2f6\uc5b4\uc11c Tiptap\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Tiptap\uc740 Headless WYSIWYG \uc5d0\ub514\ud130\ub85c \uc0ac\uc6a9\uc790 \uc815\uc758 \uae30\ub2a5\uc5d0 \ud2b9\ud654\ub418\uc5b4\uc788\ub294 \uc5d0\ub514\ud130\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc544\uc9c1 Tiptap\uc774 \uc81c\uacf5\ud558\ub294 \ubaa8\ub4e0 \uae30\ub2a5\uc744 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc0ac\uc6a9\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc CodeBlockLowlight \ud50c\ub7ec\uadf8\uc778\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucf54\ub4dc \ube14\ub85d\uc744 \uc608\uc058\uac8c \ucd9c\ub825\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","api \ubc18\ud658\uac12 \uadf8\ub300\ub85c tiptap\uc758 content\uc5d0 \uc124\uc815\ud588\ub354\ub2c8 \ucf54\ub4dc \ube14\ub85d\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc544\uc11c \ubc31 \ud2f1 3\uac1c\ub97c ",(0,r.jsx)(n.code,{children:"<pre><code>"}),"\ub85c \ubcc0\ud658\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c \ub744\uc5b4\uc4f0\uae30\ub3c4 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc544\uc11c ",(0,r.jsx)(n.code,{children:"\\n"}),"\ub97c ",(0,r.jsx)(n.code,{children:"<br>"}),"\ud0dc\uadf8\ub85c \ubcc0\ud658\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ubcc0\ud658\ud558\ub294 \ub85c\uc9c1\uc740 GPT\uc758 \ub3c4\uc6c0\uc744 \ub9ce\uc774 \ubc1b\uc558\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const replaceCodeFences = (input: String) => {\n const codeFencesRegex = /```([\\w-]*)\\n([\\s\\S]*?)\\n```/g;\n return input\n .replace(codeFencesRegex, (match, p1, p2) => {\n const languageClass = p1 ? ` class="language-${p1}"` : "";\n return `<pre><code${languageClass}>${p2}</code></pre>`;\n })\n .replace(/\\n/g, "<br>");\n};\n'})}),"\n",(0,r.jsx)(n.p,{children:"Tiptap\uc744 \uc801\uc6a9\ud558\ub2c8 \ub2e4\uc74c\uacfc \uac19\uc774 \uae54\ub054\ud55c \ucf54\ub4dc \ube14\ub85d\uc744 \ubcfc \uc218 \uc788\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"tecochat",src:t(49124).Z+"",width:"2388",height:"1500"})}),"\n",(0,r.jsx)(n.h3,{id:"\ud3f0\ud2b8-\ubc0f-favicon-\uc801\uc6a9",children:"\ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9"}),"\n",(0,r.jsxs)(n.p,{children:["\ud0c0\uc774\ud2c0\uc740 \ubc30\ub2ec\uc758\ubbfc\uc871 \ub3c4\ud604\uccb4, \ub0b4\uc6a9\uc740 IBM Plex Sans\ub97c \uc0ac\uc6a9\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ucd94\uac00\ub85c favicon\ub3c4 \uac04\ub2e8\ud558\uac8c \uc801\uc6a9\ud574\uc11c \ub9cc\uc871\uc2a4\ub7ec\uc6e0\ub2e4."]})]})}function d(e={}){const{wrapper:n}={...(0,c.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>l});var r=t(67294);function c(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?a(Object(t),!0).forEach((function(n){c(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):a(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function i(e,n){if(null==e)return{};var t,r,c=function(e,n){if(null==e)return{};var t,r,c={},a=Object.keys(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||(c[t]=e[t]);return c}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)t=a[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(c[t]=e[t])}return c}var o=r.createContext({}),l=function(e){var n=r.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,c=e.mdxType,a=e.originalType,o=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),h=l(t),u=c,j=h["".concat(o,".").concat(u)]||h[u]||p[u]||a;return t?r.createElement(j,s(s({ref:n},d),{},{components:t})):r.createElement(j,s({ref:n},d))}));d.displayName="MDXCreateElement"},49124:(e,n,t)=>{t.d(n,{Z:()=>r});const r=t.p+"assets/images/teco-chat-6b4f31b3d961878efc5c506fc167df1f.png"}}]); \ No newline at end of file diff --git a/assets/js/eff1d58f.ac84edda.js b/assets/js/eff1d58f.ac84edda.js deleted file mode 100644 index 322d94e93..000000000 --- a/assets/js/eff1d58f.ac84edda.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4137],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>d});var r=n(67294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?p(Object(n),!0).forEach((function(t){a(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):p(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,r,a=function(e,t){if(null==e)return{};var n,r,a={},p=Object.keys(e);for(r=0;r<p.length;r++)n=p[r],t.indexOf(n)>=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(r=0;r<p.length;r++)n=p[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var i=r.createContext({}),c=function(e){var t=r.useContext(i),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=c(e.components);return r.createElement(i.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,p=e.originalType,i=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=c(n),d=a,k=m["".concat(i,".").concat(d)]||m[d]||s[d]||p;return n?r.createElement(k,o(o({ref:t},u),{},{components:n})):r.createElement(k,o({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var p=n.length,o=new Array(p);o[0]=m;var l={};for(var i in t)hasOwnProperty.call(t,i)&&(l[i]=t[i]);l.originalType=e,l.mdxType="string"==typeof e?e:a,o[1]=l;for(var c=2;c<p;c++)o[c]=n[c];return r.createElement.apply(null,o)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},93097:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>s,frontMatter:()=>p,metadata:()=>l,toc:()=>c});var r=n(87462),a=(n(67294),n(3905));const p={title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",slug:"tecochat-retrospective-1",tags:["TecoChat","Retrospective"]},o=void 0,l={permalink:"/tecochat-retrospective-1",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",source:"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",description:"4\uc6d4 21\uc77c \uae08\uc694\uc77c",date:"2023-04-22T00:00:00.000Z",formattedDate:"2023\ub144 4\uc6d4 22\uc77c",tags:[{label:"TecoChat",permalink:"/tags/teco-chat"},{label:"Retrospective",permalink:"/tags/retrospective"}],readingTime:5.68,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ud14c\ucf54\ucc57] 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30",slug:"tecochat-retrospective-1",tags:["TecoChat","Retrospective"]},prevItem:{title:"Jenkins\ub85c CI/CD \uc124\uc815",permalink:"/jenkins"},nextItem:{title:"[\ucc45] \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c",permalink:"/book-leadership-and-self-deception"}},i={authorsImageUrls:[]},c=[{value:"4\uc6d4 21\uc77c \uae08\uc694\uc77c",id:"4\uc6d4-21\uc77c-\uae08\uc694\uc77c",level:3},{value:"\ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?",id:"\ub3c4\uba54\uc778-\uad6c\uc785-\uc131\uacf5",level:3},{value:"\ub9d0\ub791\uc758 DM",id:"\ub9d0\ub791\uc758-dm",level:3},{value:"\ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec",id:"\ub3c4\uba54\uc778-\uc124\uc815-\ubc0f-\ubc30\ud3ec",level:3},{value:"GPT",id:"gpt",level:3},{value:"Sonarcloud",id:"sonarcloud",level:3},{value:"Tiptap",id:"tiptap",level:3},{value:"\ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9",id:"\ud3f0\ud2b8-\ubc0f-favicon-\uc801\uc6a9",level:3}],u={toc:c};function s(e){let{components:t,...p}=e;return(0,a.kt)("wrapper",(0,r.Z)({},u,p,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h3",{id:"4\uc6d4-21\uc77c-\uae08\uc694\uc77c"},"4\uc6d4 21\uc77c \uae08\uc694\uc77c"),(0,a.kt)("p",null,"\ub808\ubca8 2\ub97c \uc2dc\uc791\ud55c \ub4a4 \ub0b4\uac00 \ud559\uc2b5\uc5d0 \ub300\ud55c \ubc29\ud5a5\uc744 \uc783\uc5b4\ubc84\ub838\ub2e4\ub294 \uc0dd\uac01\uc774 \ub4e4\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub808\ubca8 3, 4\uc5d0\uc11c \ub098\ub9cc\uc758 \uac15\uc810\uc744 \uac00\uc9c0\uace0 \uc2f6\uc5b4 \uace0\ubbfc\uc744 \ub9ce\uc774 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub2e8\uc21c\ud788 \uc2a4\ud504\ub9c1\uc744 \uae4a\uac8c \uacf5\ubd80\ud558\ub294 \uac74 \ud6a8\uc728\uc774 \ub9ce\uc774 \ub5a8\uc5b4\uc9c4\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uae00\uc4f0\uae30 \uc218\uc0c1\uc73c\ub85c \ubc1b\uc740 \ucfe0\ud3f0\uc744 \uc0ac\uc6a9\ud574 \ube0c\ub77c\uc6b4\uc5d0\uac8c \ucee4\ud53c\ucc57\uc744 \uc2e0\uccad\ud588\uace0, \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \ud574\ubcf4\ub77c\ub294 \ub2f5\uc744 \ubc1b\uc558\ub2e4. "),(0,a.kt)("p",null,"\ub098\ub294 \uc544\uc774\ub514\uc5b4\ub97c \ubabb\ub0b4\ub294 \ud3b8\uc778\ub370 \ube0c\ub77c\uc6b4\uc774 \uc544\uc774\ub514\uc5b4\uae4c\uc9c0 \ub358\uc838\uc8fc\uc168\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n",(0,a.kt)("inlineCode",{parentName:"p"},"Chat-GPT \uc11c\ube44\uc2a4\ub97c \ud06c\ub8e8\ub4e4\uc5d0\uac8c \uc81c\uacf5\ud558\uace0, \ud574\ub2f9 \ud06c\ub8e8\ub4e4\uc774 \uc9c8\ubb38\ud55c \ub0b4\uc6a9\uc744 \uacf5\uc720\ud560 \uc218 \uc788\ub294 \uac74 \uc5b4\ub5a4\uc9c0?")," "),(0,a.kt)("p",null,"\uae30\uc220\uc774 \ubaa9\uc801\uc778 \uc0ac\uc774\ub4dc \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4\ub294 \ub2f5\ubcc0\uc744 \ub4e4\uc5c8\uace0, \ud63c\uc790 \uc544\ub2c8\uba74 \ud398\uc5b4\ud560 \uc218 \uc788\uc744 \uc815\ub3c4\uc758 \uc778\uc6d0\uc73c\ub85c \uc9c4\ud589\ud558\uba74 \uc88b\uaca0\ub2e4\uace0 \ud558\uc168\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ud504\ub860\ud2b8\ub791 \uac04\ub2e8\ud558\uac8c \ubc30\ud3ec\uae4c\uc9c0 \ud574\ubcf8 \uacbd\ud5d8\uc774 \uc788\uc5b4\uc11c \ud63c\uc790\ud574\ub3c4 \ud06c\uac8c \uc5b4\ub835\uc9c0 \uc54a\uc744 \uac83 \uac19\uc544\uc11c \ud63c\uc790 \ud558\uae30\ub85c \ub9c8\uc74c\uc744 \uba39\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc774\uac74 \ubabb\ucc38\uc9c0"),(0,a.kt)("h3",{id:"\ub3c4\uba54\uc778-\uad6c\uc785-\uc131\uacf5"},"\ub3c4\uba54\uc778 \uad6c\uc785 \uc131\uacf5?"),(0,a.kt)("p",null,"\ucee4\ud53c\ucc57\uc774 \ub05d\ub098\uace0 \uc9d1\uc73c\ub85c \ub3cc\uc544\uac00\ub294 \uae38\uc5d0 \ubc14\ub85c \ub3c4\uba54\uc778\uc744 \uad6c\ub9e4\ud558\ub824\uace0 namecheap\uc5d0\uc11c \uc801\ub2f9\ud55c \ub3c4\uba54\uc778\uc774 \uc5c6\uc744\uae4c \uac80\uc0c9\uc744 \uacc4\uc18d\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub9c8\uce58 \uc5b4\ub9b4 \ub54c \ud588\ub358 \uac8c\uc784 \ub2c9\ub124\uc784 \uc815\ud558\ub294 \uac83\ucc98\ub7fc \uc2dc\uac04\uc774 \uc624\ub798 \uac78\ub838\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","dev, io, chat \ub3c4\uba54\uc778\uc774 \ud6c4\ubcf4\uc600\uace0 \uc9d1 \uac00\ub294 \uae38\uc5d0 \uacb0\uc815\ub9cc \ud558\ub2e4\uac00 \uad6c\ub9e4\ud558\uc9c0 \ubabb\ud588\ub2e4."),(0,a.kt)("h3",{id:"\ub9d0\ub791\uc758-dm"},"\ub9d0\ub791\uc758 DM"),(0,a.kt)("p",null,"\uc9d1\uc5d0 \uac00\uc11c \ubc25\uc744 \uba39\uace0 \ub9d0\ub791\uc774\ub791 DM \ud558\ub2e4 \ud504\ub85c\uc81d\ud2b8\ub97c \uac19\uc774 \ud558\uc790\ub294 \uc774\uc57c\uae30\uac00 \ub098\uc654\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc6b0\ud14c\ucf54 \ucd5c\uace0 \uace0\uc218 \ub9d0\ub791\uc758 \uc694\uad6c\ub77c \uc218\ub77d\ud558\uc9c0 \uc54a\uc73c\uba74 \ud6c4\ud3ed\ud48d\uc744 \uac10\ub2f9\ud560 \uc218 \uc5c6\uc5c8\ub2e4. "),(0,a.kt)("p",null,"\uc774\ub7f0\uc800\ub7f0 \ub300\ud654\ub97c \ub098\ub204\ub2e4\uac00 \ub09c \ube60\ub974\uac8c \ud504\ub85c\ud1a0\ud0c0\uc785\uc744 \ub9cc\ub4e4\uc5b4 \ubcf4\uace0 \uc2f6\uc5b4\uc11c \ud504\ub860\ud2b8\ub97c \uad6c\ud604\ud55c\ub2e4\uace0 \ud588\uace0, \ub9d0\ub791\uc740 GPT api\ub97c \uc870\uc0ac\ud558\uae30\ub85c \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ub3c4\uba54\uc778\uc5d0 \uad00\ud55c \uc774\uc57c\uae30\ub97c \ud558\ub2e4\uac00 woowachat\uc774 \uc5b8\uae09\ub418\uc5c8\uace0, namecheap\uc5d0\uc11c chat \ub3c4\uba54\uc778\uc744 \uc0ac\uc6a9\ud55c woowa.chat\uc73c\ub85c \uad6c\ub9e4\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc774\ud6c4\uc5d0 teco.chat\uc73c\ub85c \ubcc0\uacbd\ud588\ub2e4!"),(0,a.kt)("h3",{id:"\ub3c4\uba54\uc778-\uc124\uc815-\ubc0f-\ubc30\ud3ec"},"\ub3c4\uba54\uc778 \uc124\uc815 \ubc0f \ubc30\ud3ec"),(0,a.kt)("p",null,"\ud1a0\uc694\uc77c\uc5d0 \uad6c\ub9e4\ud55c \ub3c4\uba54\uc778\uc744 CDN, \ubcf4\uc548 \ub4f1 \ub2e4\uc591\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud558\ub294 Cloudflare\uc5d0 \ub3c4\uba54\uc778 \ub4f1\ub85d\uc744 \ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub098\uc5d0\uac8c \uc775\uc219\ud55c Nuxt3\ub97c \uc0ac\uc6a9\ud558\uae30\ub85c \ud588\uace0, Cloudflare Pages\ub97c \uc774\uc6a9\ud558\uc5ec \ubc30\ud3ec\ud588\ub2e4. "),(0,a.kt)("h3",{id:"gpt"},"GPT"),(0,a.kt)("p",null,"\ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud558\ub2c8 api limit\uc774 \uc788\uc5b4 \ubd84\ub2f9 3\ubc88\ubc16\uc5d0 \uc0ac\uc6a9\ud560 \uc218 \uc5c6\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc77c\ub2e8 \ubc31\uc5d4\ub4dc\ub97c \uad6c\ucd95\ud558\uae30 \uc804\uc5d0\ub294 \ubb34\ub8cc \ud06c\ub808\ub527\uc744 \uc0ac\uc6a9\ud560 \uc0dd\uac01\uc774\ub2e4. "),(0,a.kt)("h3",{id:"sonarcloud"},"Sonarcloud"),(0,a.kt)("p",null,"\uc815\uc801 \ucf54\ub4dc \ubd84\uc11d \ub3c4\uad6c\ub85c Sonarcloud\ub97c \uc801\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Sonarcloud\ub294 SonarQube\uc758 SaaS \ubc84\uc804\uc774\uace0 \uc0ac\uc6a9\uc774 \ub9e4\uc6b0 \ud3b8\ud558\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc608\uc804\uc5d0 Sonarcloud\ub97c \uc0ac\uc6a9\ud560 \ub550 \ubc84\ud2bc \uba87 \ubc88 \ub204\ub974\uba74 \uc801\uc6a9\ud560 \uc218 \uc788\uc5c8\ub294\ub370, \uc774\ubc88\uc5d0\ub294 \ubc14\ub85c github action\uc744 \uc0ac\uc6a9\ud558\ub77c\ub294 \uc548\ub0b4 \ud398\uc774\uc9c0\ub85c \uc774\ub3d9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Sonarcloud\uac00 \uc790\uccb4\uc801\uc73c\ub85c github repository\uc5d0 push \ud558\uba74 \uc815\uc801 \ubd84\uc11d\uc744 \ud574\uc8fc\ub294 \uae30\ub2a5\uc744 \uc6d0\ud588\uace0, Administration -> Analysis Method\uc5d0 Automatic Analysis\ub97c \uc124\uc815\ud558\ub2c8 \ub418\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ub108\ubb34 \uaf41\uaf41 \uc228\uaca8\uc838\uc788\ub124"),(0,a.kt)("h3",{id:"tiptap"},"Tiptap"),(0,a.kt)("p",null,"\ucf54\ub4dc \ud558\uc774\ub77c\uc774\ud305 \uae30\ub2a5\uc744 \ub123\uace0 \uc2f6\uc5b4\uc11c Tiptap\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","Tiptap\uc740 Headless WYSIWYG \uc5d0\ub514\ud130\ub85c \uc0ac\uc6a9\uc790 \uc815\uc758 \uae30\ub2a5\uc5d0 \ud2b9\ud654\ub418\uc5b4\uc788\ub294 \uc5d0\ub514\ud130\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\uc544\uc9c1 Tiptap\uc774 \uc81c\uacf5\ud558\ub294 \ubaa8\ub4e0 \uae30\ub2a5\uc744 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc0ac\uc6a9\ud558\uc9c0\ub294 \ubabb\ud558\uc9c0\ub9cc CodeBlockLowlight \ud50c\ub7ec\uadf8\uc778\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucf54\ub4dc \ube14\ub85d\uc744 \uc608\uc058\uac8c \ucd9c\ub825\ud560 \uc218 \uc788\uc5c8\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","api \ubc18\ud658\uac12 \uadf8\ub300\ub85c tiptap\uc758 content\uc5d0 \uc124\uc815\ud588\ub354\ub2c8 \ucf54\ub4dc \ube14\ub85d\uc774 \uc124\uc815\ub418\uc9c0 \uc54a\uc544\uc11c \ubc31 \ud2f1 3\uac1c\ub97c ",(0,a.kt)("inlineCode",{parentName:"p"},"<pre><code>"),"\ub85c \ubcc0\ud658\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c \ub744\uc5b4\uc4f0\uae30\ub3c4 \uc801\uc6a9\ub418\uc9c0 \uc54a\uc544\uc11c ",(0,a.kt)("inlineCode",{parentName:"p"},"\\n"),"\ub97c ",(0,a.kt)("inlineCode",{parentName:"p"},"<br>"),"\ud0dc\uadf8\ub85c \ubcc0\ud658\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ubcc0\ud658\ud558\ub294 \ub85c\uc9c1\uc740 GPT\uc758 \ub3c4\uc6c0\uc744 \ub9ce\uc774 \ubc1b\uc558\ub2e4. "),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-ts"},'const replaceCodeFences = (input: String) => {\n const codeFencesRegex = /```([\\w-]*)\\n([\\s\\S]*?)\\n```/g;\n return input\n .replace(codeFencesRegex, (match, p1, p2) => {\n const languageClass = p1 ? ` class="language-${p1}"` : "";\n return `<pre><code${languageClass}>${p2}</code></pre>`;\n })\n .replace(/\\n/g, "<br>");\n};\n')),(0,a.kt)("p",null,"Tiptap\uc744 \uc801\uc6a9\ud558\ub2c8 \ub2e4\uc74c\uacfc \uac19\uc774 \uae54\ub054\ud55c \ucf54\ub4dc \ube14\ub85d\uc744 \ubcfc \uc218 \uc788\uc5c8\ub2e4. "),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"tecochat",src:n(49124).Z,width:"2388",height:"1500"})),(0,a.kt)("h3",{id:"\ud3f0\ud2b8-\ubc0f-favicon-\uc801\uc6a9"},"\ud3f0\ud2b8 \ubc0f favicon \uc801\uc6a9"),(0,a.kt)("p",null,"\ud0c0\uc774\ud2c0\uc740 \ubc30\ub2ec\uc758\ubbfc\uc871 \ub3c4\ud604\uccb4, \ub0b4\uc6a9\uc740 IBM Plex Sans\ub97c \uc0ac\uc6a9\ud588\ub2e4.",(0,a.kt)("br",{parentName:"p"}),"\n","\ucd94\uac00\ub85c favicon\ub3c4 \uac04\ub2e8\ud558\uac8c \uc801\uc6a9\ud574\uc11c \ub9cc\uc871\uc2a4\ub7ec\uc6e0\ub2e4."))}s.isMDXComponent=!0},49124:(e,t,n)=>{n.d(t,{Z:()=>r});const r=n.p+"assets/images/teco-chat-6b4f31b3d961878efc5c506fc167df1f.png"}}]); \ No newline at end of file diff --git a/assets/js/f06cb3e2.536ef825.js b/assets/js/f06cb3e2.536ef825.js new file mode 100644 index 000000000..545e85f4d --- /dev/null +++ b/assets/js/f06cb3e2.536ef825.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2620],{43487:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>u,contentTitle:()=>c,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var a=r(85893),t=r(3905),i=r(74866),l=r(85162);const s={title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",slug:"db-replication",tags:["mysql","replication"]},c=void 0,o={permalink:"/db-replication",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",source:"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",description:"\ubcf5\uc81c(Replication)",date:"2023-08-22T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 22\uc77c",tags:[{label:"mysql",permalink:"/tags/mysql"},{label:"replication",permalink:"/tags/replication"}],readingTime:21,hasTruncateMarker:!1,authors:[],frontMatter:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",slug:"db-replication",tags:["mysql","replication"]},unlisted:!1,prevItem:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",permalink:"/performance-test-type"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",permalink:"/woowacourse-level3-retrospective"}},u={authorsImageUrls:[]},d=[{value:"\ubcf5\uc81c(Replication)",id:"\ubcf5\uc81creplication",level:2},{value:"\ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720",id:"\ubcf5\uc81c\ub97c-\ud558\ub294-\uc774\uc720",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ud30c\uc77c-\uc704\uce58-\uae30\ubc18-\ubcf5\uc81c",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd\uc758-\ubb38\uc81c\uc810",level:3},{value:"\uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c",id:"\uae00\ub85c\ubc8c-\ud2b8\ub79c\uc7ad\uc158-\uc544\uc774\ub514gtid-\uae30\ubc18-\ubcf5\uc81c",level:3},{value:"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0",id:"\ubcf5\uc81c-\ud1a0\ud3f4\ub85c\uc9c0",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd-replication-\uad6c\uc131\ud558\uae30",level:2},{value:"MySQL \ud658\uacbd \uad6c\uc131",id:"mysql-\ud658\uacbd-\uad6c\uc131",level:3},{value:"\ub3c4\ucee4 \uc2e4\ud589",id:"\ub3c4\ucee4-\uc2e4\ud589",level:3},{value:"replication slave \uad8c\ud55c \uc124\uc815",id:"replication-slave-\uad8c\ud55c-\uc124\uc815",level:3},{value:"SOURCE DB \uc815\ubcf4 \ud655\uc778",id:"source-db-\uc815\ubcf4-\ud655\uc778",level:3},{value:"SOURCE ip \uc8fc\uc18c \ud655\uc778",id:"source-ip-\uc8fc\uc18c-\ud655\uc778",level:3},{value:"replica mysql \uc811\uc18d",id:"replica-mysql-\uc811\uc18d",level:3},{value:"replica \uc124\uc815",id:"replica-\uc124\uc815",level:3},{value:"\uc124\uc815 \ud655\uc778",id:"\uc124\uc815-\ud655\uc778",level:3},{value:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30",id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8\ub85c-db-\uc811\uadfc\ud558\uae30",level:2},{value:"Environment \uc124\uc815",id:"environment-\uc124\uc815",level:3},{value:"DataSourceType \uc124\uc815",id:"datasourcetype-\uc124\uc815",level:3},{value:"AbstractRoutingDataSource \uc124\uc815",id:"abstractroutingdatasource-\uc124\uc815",level:3},{value:"DataSource \uc124\uc815",id:"datasource-\uc124\uc815",level:3},{value:"\ub3d9\uc791 \ud655\uc778",id:"\ub3d9\uc791-\ud655\uc778",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function p(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",mermaid:"mermaid",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.ah)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.h2,{id:"\ubcf5\uc81creplication",children:"\ubcf5\uc81c(Replication)"}),"\n",(0,a.jsxs)(n.p,{children:["\ud55c \uc11c\ubc84\uc5d0\uc11c \ub2e4\ub978 \uc11c\ubc84\ub85c \ub370\uc774\ud130\ub97c \ub3d9\uae30\ud654\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc6d0\ubcf8 \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Primary \ub610\ub294 Source \ub77c\uace0 \ubd80\ub974\uace0, \ubcf5\uc81c\ub41c \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Secondary \ub610\ub294 Replica \ub77c\uace0 \ubd80\ub978\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\ubcf5\uc81c\ub97c-\ud558\ub294-\uc774\uc720",children:"\ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"1. \uc2a4\ucf00\uc77c \uc544\uc6c3"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc0ac\uc6a9\uc790\uc758 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0, \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uac00\ud574\uc9c0\ub294 \ubd80\ud558\ub3c4 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc99d\uac00\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc774\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud574 \ubcf5\uc81c\ub97c \ud1b5\ud55c \uc2a4\ucf00\uc77c \uc544\uc6c3\uc744 \uc801\uc6a9\ud558\uc5ec \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucffc\ub9ac\ub4e4\uc744 \uac01\uac01\uc758 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub85c \ubd84\uc0b0 \uc2dc\ud0ac \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"2. \ub370\uc774\ud130 \ubc31\uc5c5"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc2e4\uc81c \uc6b4\uc601\ub418\ub294 \uc11c\ube44\uc2a4\uac00 \uc0ac\uc6a9\ud558\uace0 \uc788\ub294 DB\uc5d0\uc11c \ubc31\uc5c5\uc744 \uc9c4\ud589\ud558\ub294 \uacbd\uc6b0, \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc2e4\uc81c \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc774 \uac00\uc9c0 \uc54a\ub3c4\ub85d \ubcf5\uc81c\ub97c \ud1b5\ud574 Replica \uc11c\ubc84\ub97c \uad6c\ucd95\ud558\uc5ec, Replica \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ub97c \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\uc73c\ub85c \uc601\ud5a5\uc744 \ucd5c\uc18c\ud654 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"3. \ub370\uc774\ud130 \ubd84\uc11d"})}),"\n",(0,a.jsxs)(n.p,{children:["\ubc31\uc5c5\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc7a1\ud558\uace0 \ubb34\uac70\uc6b4 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\uc758 \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc81c\ub97c \uc0ac\uc6a9\ud574 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ud658\uacbd\uc744 \ub9cc\ub4e4 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"4. \ub370\uc774\ud130\uc758 \uc9c0\ub9ac\uc801 \ubd84\uc0b0"})}),"\n",(0,a.jsx)(n.p,{children:"\ube60\ub978 \uc751\ub2f5\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc11c\ubc84\uc5d0 \uac00\uae5d\uac8c \uc11c\ubc84\ub97c \uad6c\uc131\ud558\uac70\ub098, \uace0\uac00\uc6a9\uc131(High Availability)\uc744 \uc704\ud574\uc11c\ub3c4 \uc0ac\uc6a9\ub41c\ub2e4."}),"\n",(0,a.jsx)(n.h3,{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ud30c\uc77c-\uc704\uce58-\uae30\ubc18-\ubcf5\uc81c",children:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c"}),"\n",(0,a.jsxs)(n.p,{children:["MySQL \uc11c\ubc84\uc5d0\uc11c \ubc1c\uc0dd\ud558\ub294 \ubcc0\uacbd\uc0ac\ud56d\uc5d0 \ub300\ud55c \ub85c\uadf8 \ud30c\uc77c\uc744 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub77c\uace0 \ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ud1b5\ud574 \ub370\uc774\ud130 \ubcc0\uacbd, \ud14c\uc774\ube14 \uad6c\uc870 \ubcc0\uacbd, \uacc4\uc815\uc774\ub098 \uad8c\ud55c \ubcc0\uacbd\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc800\uc7a5\ub41c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","MySQL\uc758 \ubcf5\uc81c\ub294 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 \uc788\ub2e4. \uc774\ub97c Replica \uc11c\ubc84\ub85c \uc804\ub2ec\ud558\uace0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \ub370\uc774\ud130\ub97c \ubcc0\uacbd \uc0ac\ud56d\uc744 \ubc18\uc601\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n\tsubgraph Replica\n\t\tdirection TB\n\t\tIO[Replication I/O thread] -- save --\x3e RL[Relay Log]\n\t\tSQL[Replication SQL Thread] -- read --\x3e RL\n\tend\n\n\tsubgraph Source\n\t\tdirection TB\n\t\tBLD[Binary Log Dump Thread] -- Send Binary Log Dump--\x3e IO\n\tend\n"}),"\n",(0,a.jsx)(n.admonition,{title:"\uc2a4\ub808\ub4dc\ubcc4 \uc5ed\ud560",type:"note",children:(0,a.jsxs)(n.p,{children:["Binary Log Dump Thread: \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc758 \ub0b4\uc6a9\uc744 Replica \uc11c\ubc84\ub85c \uc804\ub2ec",(0,a.jsx)(n.br,{}),"\n","Replication I/O Thread: Binary \ub85c\uadf8 \uc774\ubca4\ud2b8\ub97c \uac00\uc838\uc640 \ub85c\uceec \uc11c\ubc84\uc758 \ud30c\uc77c(Relay Log)\ub85c \uc800\uc7a5",(0,a.jsx)(n.br,{}),"\n","Replication SQL Thread: \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc774\ubca4\ud2b8\ub97c \uc77d\uace0 \uc2e4\ud589"]})}),"\n",(0,a.jsx)(n.h3,{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd\uc758-\ubb38\uc81c\uc810",children:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810"}),"\n",(0,a.jsxs)(n.p,{children:["\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc740 \uc11c\ubc84\uc5d0 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud588\uc744 \ub54c \ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0 \ubcc0\uacbd\uc774 \uae4c\ub2e4\ub86d\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud1a0\ud3f4\ub85c\uc9c0\ub780 \ub124\ud2b8\uc6cc\ud06c\uc758 \uc694\uc18c\ub4e4\uc744 \ubb3c\ub9ac\uc801\uc73c\ub85c \uc5f0\uacb0\ud574 \ub193\uc740 \uac83, \ub610\ub294 \uadf8 \uc5f0\uacb0 \ubc29\uc2dd\uc744 \ub9d0\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph TD\n\tA[A binary-log:300] --\x3e B[B Binary-log:300]\n\tA[A binary-log:300] --\x3e C[C Binary-log:200]"}),"\n",(0,a.jsx)(n.p,{children:"\uc704\uc640 \uac19\uc774 Source \uc11c\ubc84, Replica 2\ub300\uac00 \uc874\uc7ac\ud558\uace0, C \uc11c\ubc84\uc5d0 \ubcf5\uc81c \uc9c0\uc5f0\uc774 \ub418\uc5c8\uc744 \ub54c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.mermaid,{value:"graph TD\n\tA[A binary-log:300]\n\tB[B Binary-log:300] --\x3e C[C Binary-log:200 \ubb38\uc81c \ubc1c\uc0dd]"}),"\n",(0,a.jsxs)(n.p,{children:["A \uc11c\ubc84\uc5d0\uc11c \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 B \uc11c\ubc84\ub97c Source \uc11c\ubc84\ub85c \uc2b9\uaca9\ud558\uace0, C\uc5d0\uac8c \uc870\ud68c \ucffc\ub9ac\ub97c \ubd84\uc0b0\uc2dc\ud0a8\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud558\uc9c0\ub9cc \uc5ec\uae30\uc11c C \uc11c\ubc84\uc5d0\ub294 A \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\uac00 \uc548\ub418\uc5c8\uc73c\ub2c8 \uc870\ud68c \uc2dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub4a4\ub2a6\uac8c B \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\ub97c \ud558\ub824\uace0 \ud574\ub3c4, \uc5b4\ub5a4 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8, \uc5b4\ub5a4 \uc704\uce58\uc640 \ub3d9\uae30\ud654\ud574\uc57c\ud558\ub294\uc9c0 \uc54c\uae30 \uc5b4\ub835\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"\uae00\ub85c\ubc8c-\ud2b8\ub79c\uc7ad\uc158-\uc544\uc774\ub514gtid-\uae30\ubc18-\ubcf5\uc81c",children:"\uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c"}),"\n",(0,a.jsxs)(n.p,{children:["GTID \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ubc1c\uc0dd\ud55c \uc774\ubca4\ud2b8\uc5d0 \uace0\uc720\ud55c \uc2dd\ubcc4\uac12\uc744 \ubd80\uc5ec\ud55c\ub2e4\uba74, \ub3d9\uae30\ud654\uc5d0 \ub300\ud55c \ubb38\uc81c\ub97c \uac04\ub2e8\ud558\uac8c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc704\uc758 \uc608\uc2dc\uc640 \uac19\uc774 \ubcf5\uc81c \uc9c0\uc5f0\uacfc \ud568\uaed8 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\ud574\ub3c4 \ud2b9\uc815 GTID \ubd80\ud130 \ubcf5\uc81c\ub97c \uc7ac\uac1c\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,a.jsx)(n.admonition,{title:"GTID",type:"note",children:(0,a.jsxs)(n.p,{children:["\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0\uc5d0 \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \uc11c\ubc84\uc5d0\uc11c \uace0\uc720\ud558\ub3c4\ub85d \uac01 \uc774\ubca4\ud2b8\uc5d0 \ubd80\uc5ec\ub41c \uc2dd\ubcc4\uac12",(0,a.jsx)(n.br,{}),"\n","[source_id]:[transaction_id]\ub85c \uad6c\uc131\ub418\uba70, source_id\ub294 \uc11c\ubc84\ub97c \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc774\uace0 transaction_id\ub294 \ucee4\ubc0b\ub41c \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc73c\ub85c 1\uc529 \uc99d\uac00\ud558\ub294 \ud615\ud0dc\ub85c \ubc1c\uae09\ub41c\ub2e4."]})}),"\n",(0,a.jsx)(n.h3,{id:"\ubcf5\uc81c-\ud1a0\ud3f4\ub85c\uc9c0",children:"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["\uac00\uc7a5 \uac04\ub2e8\ud55c \uad6c\uc131\uc73c\ub85c \uc81c\uc77c \ub9ce\uc774 \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4.",(0,a.jsx)(n.br,{}),"\n","replica \uc11c\ubc84\ub97c \uc77d\uae30 \uc804\uc6a9, \uc608\ube44 \uc11c\ubc84, \ubc31\uc5c5 \uc6a9\ub3c4\ub85c \ub9ce\uc774 \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R\n S[Source] --\x3e R[Replica]"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\uba40\ud2f0 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["2\uac1c\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud558\ub098\uc758 replica\ub294 \uc608\ube44 \uc6a9\ub3c4\ub85c \ub0a8\uaca8\ub450\ub294 \ud615\ud0dc\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ucd94\ud6c4\uc5d0 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0 \uc608\ube44 \uc6a9\ub3c4\uc758 replica\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c \uc77d\uae30 \uc694\uccad\uc758 \ubd80\ud558 \ubd84\uc0b0\uc744 \ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R1\n S[Source] --\x3e R1[Replica1]\n S --\x3e R2[Replica2]"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\uccb4\uc778 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["replica \uc11c\ubc84\uac00 \ub9ce\uc740 \uacbd\uc6b0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \uc804\ub2ec\ud558\ub294 \uc791\uc5c5 \uc790\uccb4\uac00 \ubd80\ud558\uac00 \ub420 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c 1:M",":M"," \uad6c\uc870\ub85c \uccb4\uc778 \ubcf5\uc81c \uad6c\uc131\uc744 \uace0\ub824\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R1\n S[Source] --\x3e R1[Replica1]\n S --\x3e R2[Replica2]\n S --\x3e R3[Replica3]\n\n R3 --\x3e R3-1[Replica 3-1]\n R3 --\x3e R3-2[Replica 3-2]\n\n B[Batch Server] --\x3e R3-2"}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\ub4c0\uc5bc \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["2\uac1c\uc758 MySQL \uc11c\ubc84 \ubaa8\ub450 \uc77d\uae30\uc640 \uc4f0\uae30\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d \ud558\ub294 \uad6c\uc131\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uac01 \uc11c\ubc84\uc5d0\uc11c \ubcc0\uacbd\ub41c \ub370\uc774\ud130\ub294 \ub2e4\ub978 \uc11c\ubc84\uc5d0 \ubc18\uc601\ub41c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ubaa9\uc801\uc5d0 \ub530\ub77c ACTIVE-ACTIVE \ud615\ud0dc \ub610\ub294 ACTIVE-PASSIVE \ud615\ud0dc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","ACTIVE-PASSIVE \ud615\ud0dc\uc778 \uacbd\uc6b0 \uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131\uacfc \ub3d9\uc77c\ud574\ubcf4\uc774\uc9c0\ub9cc, ACTIVE \uc11c\ubc84\uc5d0\uc11c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uba74 \uc124\uc815\uc758 \ubcc0\uacbd\uc5c6\uc774 PASSIVE \uc11c\ubc84\ub85c \uc4f0\uae30 \uc791\uc5c5\uc744 \uc804\ud658\ud560 \uc218 \uc788\ub2e4\ub294 \uac83\uc774 \uc7a5\uc810\uc774\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR1\n W -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR2\n SR1[Source/Replica 1] --\x3e SR2[Source/Replica 2]"}),"\n",(0,a.jsx)(n.admonition,{title:"ACTIVE-ACTIVE, ACTIVE-PASSIVE",type:"note",children:(0,a.jsxs)(n.p,{children:["ACTIVE-ACTIVE: 2\uac1c\uc758 \uc11c\ubc84 \ubaa8\ub450 \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc",(0,a.jsx)(n.br,{}),"\n","ACTIVE-PASSIVE: \ud558\ub098\uc758 \uc11c\ubc84\uc5d0\uc11c\ub9cc \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc"]})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"\uba40\ud2f0 \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131"})}),"\n",(0,a.jsxs)(n.p,{children:["\uc5ec\ub7ec\uac1c\uc758 source \uc11c\ubc84\uc640 \ud558\ub098\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \uad6c\uc131\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc774\ub294 source \uc11c\ubc84\uc758 \ub370\uc774\ud130\ub97c \ud55c \uacf3\uc5d0 \ubc31\uc5c5\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9, \uc5ec\ub7ec \uc11c\ubc84\uc5d0 \uc874\uc7ac\ud558\ub294 \ub370\uc774\ud130\ub97c \ud1b5\ud569, \uc0e4\ub529\ub418\uc5b4\uc788\ub294 \ud14c\uc774\ube14 \ub370\uc774\ud130\ub97c \ud1b5\ud569\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n S1[Source 1] --\x3e R[Replica]\n S2[Source 2] --\x3e R"}),"\n",(0,a.jsx)(n.h2,{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd-replication-\uad6c\uc131\ud558\uae30",children:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30"}),"\n",(0,a.jsxs)(n.p,{children:["mysql 2\ub300\ub97c \uc774\uc6a9\ud558\uc5ec replication\uc744 \uad6c\uc131\ud558\uace0, spring boot application\uc73c\ub85c source, replica \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc811\uadfc\ud574\ubcf4\ub294 \uc608\uc81c\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://github.com/bbiac/db-replication",children:"https://github.com/bbiac/db-replication"})]}),"\n",(0,a.jsx)(n.h3,{id:"mysql-\ud658\uacbd-\uad6c\uc131",children:"MySQL \ud658\uacbd \uad6c\uc131"}),"\n",(0,a.jsxs)(n.p,{children:["MySQL \ubc84\uc804\uc740 8.1\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","13306, 13307 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud574\uc11c MySQL \uc11c\ubc84 2\ub300\ub97c \ub744\uc6e0\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub610\ud55c \uc0ac\uc2e4 IP \ub300\uc5ed\uc73c\ub85c \ud1b5\uc2e0\ud560 \uc218 \uc788\ub3c4\ub85d \ucee4\uc2a4\ud140 \ub124\ud2b8\uc6cc\ud06c\ub97c \ucd94\uac00\ud588\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yml",children:"version: '3.8'\n\nservices:\n source:\n platform: linux/x86_64\n image: mysql:latest\n restart: always\n container_name: mysql-source\n environment:\n TZ: 'Asia/Seoul'\n MYSQL_DATABASE: 'db'\n MYSQL_USER: 'user'\n MYSQL_PASSWORD: 'password'\n MYSQL_ROOT_PASSWORD: 'password'\n ports:\n - \"13306:3306\"\n volumes:\n - db-source:/var/lib/mysql\n - db-source:/var/lib/mysql-files\n - ./docker/source.cnf:/etc/mysql/my.cnf\n networks:\n - mysql_network\n\n replica:\n platform: linux/x86_64\n image: mysql:latest\n restart: always\n container_name: mysql-replica\n environment:\n TZ: 'Asia/Seoul'\n MYSQL_DATABASE: 'db'\n MYSQL_USER: 'user'\n MYSQL_PASSWORD: 'password'\n MYSQL_ROOT_PASSWORD: 'password'\n ports:\n - \"13307:3306\"\n volumes:\n - db-replica:/var/lib/mysql\n - db-replica:/var/lib/mysql-files\n - ./docker/replica.cnf:/etc/mysql/my.cnf\n networks:\n - mysql_network\n\nvolumes:\n db-source:\n db-replica:\n\nnetworks:\n mysql_network:\n driver: bridge\n"})}),"\n",(0,a.jsx)(n.p,{children:"\ub610\ud55c source, replica \uac01\uac01 \ub2e4\uc74c\uacfc \uac19\uc774 db \uc124\uc815\uc744 \ud588\ub2e4."}),"\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"\uc124\uc815"}),(0,a.jsx)(n.th,{children:"\uc124\uba85"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"server_id"}),(0,a.jsx)(n.td,{children:"\uac01\uac01\uc758 mysql \ub9c8\ub2e4 \uace0\uc720\ud55c \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"log_bin"}),(0,a.jsx)(n.td,{children:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815\uc73c\ub85c \uc808\ub300\uacbd\ub85c\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 /var/lib/mysql \uc544\ub798 \ud574\ub2f9 log_bin\uc5d0 \uc124\uc815\ub41c \uac12\uc73c\ub85c \ub85c\uadf8\uac00 \uc0dd\uc131\ub41c\ub2e4."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"sync_binlog"}),(0,a.jsx)(n.td,{children:"N\uac1c\uc758 \ud2b8\ub79c\uc7ad\uc158 \ub2f9 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ub514\uc2a4\ud06c\uc640 \ub3d9\uae30\ud654 \uc791\uc5c5\uc744 \ud558\ub3c4\ub85d \ud55c\ub2e4.\xa01\uc740 \uae30\ubcf8\uac12\uc73c\ub85c \uc548\uc815\uc801\uc774\uc9c0\ub9cc, \uac00\uc7a5 \ub290\ub9ac\ub2e4."})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"relay_log"}),(0,a.jsx)(n.td,{children:"\ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"relay_log_purge"}),(0,a.jsx)(n.td,{children:"\ud544\uc694 \uc5c6\ub294 \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc744 \uc790\ub3d9\uc73c\ub85c \uc0ad\uc81c\ud558\ub294 \uc635\uc158"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"read_only"}),(0,a.jsx)(n.td,{children:"\uc77d\uae30 \uc804\uc6a9 \uc124\uc815"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"log_replica_updates"}),(0,a.jsx)(n.td,{children:"Replication SQL Thread\ub85c \uc778\ud574 \uc2e4\ud589\ub418\ub294 \uc815\ubcf4\ub97c \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc5d0 \uae30\ub85d \ucd94\ud6c4\uc5d0 \uc18c\uc2a4 \uc11c\ubc84\ub85c \uc2b9\uaca9\ub418\ub294 \uacbd\uc6b0\ub97c \uace0\ub824\ud558\uba74 \uc124\uc815\ud558\ub294 \uac83\uc774 \uc88b\ub2e4."})]})]})]}),"\n","\n","\n",(0,a.jsxs)(i.Z,{children:[(0,a.jsx)(l.Z,{value:"Source",label:"Source",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-cnf",metastring:'title="/docker/source.cnf"',children:"[mysqld]\nserver_id=1\nlog_bin=mysql-bin\nsync_binlog=1\n"})})}),(0,a.jsx)(l.Z,{value:"Replica",label:"Replica",children:(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-cnf",metastring:'title="/docker/replica.cnf"',children:"[mysqld]\nserver_id=2\nrelay_log=mysql-relay-bin\nrelay_log_purge=ON\nread_only\nlog_replica_updates\n"})})})]}),"\n",(0,a.jsx)(n.h3,{id:"\ub3c4\ucee4-\uc2e4\ud589",children:"\ub3c4\ucee4 \uc2e4\ud589"}),"\n",(0,a.jsxs)(n.p,{children:["docker-compose up \uba85\ub839\uc5b4\ub85c docker-compose \uc124\uc815\uc73c\ub85c docker\ub97c \ub744\uc6b4\ub2e4.",(0,a.jsx)(n.br,{}),"\n","-d \uc635\uc158\uc744 \ubd99\uc774\uba74 \ubc31\uadf8\ub77c\uc6b4\ub4dc \ubaa8\ub4dc\ub85c \uc2e4\ud589\ub41c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"docker-compose up -d\n"})}),"\n",(0,a.jsx)(n.h3,{id:"replication-slave-\uad8c\ud55c-\uc124\uc815",children:"replication slave \uad8c\ud55c \uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["REPLICATION SLAVE \uad8c\ud55c\uc774 \uc124\uc815\ub418\uc5b4 \uc788\uc5b4\uc57c replica \uc11c\ubc84\uc5d0\uc11c source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec \ub85c\uadf8\ub97c \uc77d\uc5b4\uc62c \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec user \uacc4\uc815\uc5d0 \ud574\ub2f9 \uad8c\ud55c\uc744 \uc124\uc815\ud574\uc900\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:"SOURCE \uc811\uc18d"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"docker exec -it mysql-source mysql -u root -p\n"})}),"\n",(0,a.jsx)(n.p,{children:"user \uacc4\uc815\uc5d0 REPLICATION SLAVE \uad8c\ud55c \ucd94\uac00"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-mysql",children:"GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';\nFLUSH PRIVILEGES;\n"})}),"\n",(0,a.jsx)(n.h3,{id:"source-db-\uc815\ubcf4-\ud655\uc778",children:"SOURCE DB \uc815\ubcf4 \ud655\uc778"}),"\n",(0,a.jsxs)(n.p,{children:["replica \uc124\uc815\uc5d0 \ud544\uc694\ud55c source db\uc758 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c\uba85\uacfc Position\uc744 \ud655\uc778\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","Position \uac12\uc740 \uc2e4\uc81c \ud30c\uc77c\uc758 \ubc14\uc774\ud2b8 \uc218\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud655\uc778\ud55c File(SOURCE_LOG_FILE)\uacfc Position(SOURCE_LOG_POS) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-mysql",children:"SHOW MASTER STATUS;\n\n+------------------+----------+--------------+------------------+-------------------+\n| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\n+------------------+----------+--------------+------------------+-------------------+\n| mysql-bin.000003 | 1082 | | | |\n+------------------+----------+--------------+------------------+-------------------+\n"})}),"\n",(0,a.jsx)(n.h3,{id:"source-ip-\uc8fc\uc18c-\ud655\uc778",children:"SOURCE ip \uc8fc\uc18c \ud655\uc778"}),"\n",(0,a.jsxs)(n.p,{children:["docker inspect -f \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uba74 \ud574\ub2f9 \ucee8\ud14c\uc774\ub108\uc758 \uc138\ubd80 \uc815\ubcf4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud574 docker-compose \ud30c\uc77c\uc5d0 \uc124\uc815\ud574\ub454 mysql_network\uc5d0\uc11c \uc0ac\uc6a9\ub418\ub294 \uc0ac\uc124 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \ud655\uc778\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'docker inspect -f "{{with index .NetworkSettings.Networks \\"db-replication_mysql_network\\"}}{{.IPAddress}}{{end}}" mysql-source\n'})}),"\n",(0,a.jsxs)(n.p,{children:["ip \uc8fc\uc18c\uac00 \ub098\uc624\uc9c0 \uc54a\ub294 \uacbd\uc6b0 docker inspect mysql-source\ub85c \ud655\uc778\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ud655\uc778\ud55c IP\uc8fc\uc18c(SOURCE_HOST) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.h3,{id:"replica-mysql-\uc811\uc18d",children:"replica mysql \uc811\uc18d"}),"\n",(0,a.jsx)(n.p,{children:"source db\uc5d0 \uc811\uc18d\ud588\ub358 \ubc29\ubc95\uacfc \ub3d9\uc77c\ud558\uac8c replica db\uc5d0 \uc811\uc18d\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"docker exec -it mysql-replica mysql -u root -p\n"})}),"\n",(0,a.jsx)(n.h3,{id:"replica-\uc124\uc815",children:"replica \uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["\uc774\uc804\uc5d0 source db\uc5d0\uc11c \uc5bb\uc5c8\ub358 \uc815\ubcf4\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc5ec replica \uc124\uc815\uc744 \uc9c4\ud589\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc2e4\uc81c DB \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc73c\ub85c source DB\uc758 \ud30c\uc77c\uc744 \ubcf5\uc81c\ud574\uc57c\ud558\uc9c0\ub9cc \ud604\uc7ac \ubcf5\uc81c\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ubd80\ubd84\uc740 \uc0dd\ub7b5\ud588\ub2e4.",(0,a.jsx)(n.br,{}),"\n","SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS \ub97c \uc801\uc808\ud788 \ubcc0\uacbd\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-mysql",children:"STOP REPLICA;\n\nCHANGE REPLICATION SOURCE TO \nSOURCE_HOST='172.29.0.2', \nSOURCE_USER='user', \nSOURCE_PASSWORD='password', \nSOURCE_LOG_FILE='mysql-bin.000001', \nSOURCE_LOG_POS=0, \nGET_SOURCE_PUBLIC_KEY=1;\n\nSTART REPLICA;\n"})}),"\n",(0,a.jsx)(n.h3,{id:"\uc124\uc815-\ud655\uc778",children:"\uc124\uc815 \ud655\uc778"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-mysql",children:"SHOW REPLICA STATUS;\n\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n"})}),"\n",(0,a.jsx)(n.p,{children:"Replica_IO_Running, Replica_SQL_Running \uac12\uc774 YES\ub77c\uba74 \uc815\uc0c1\uc801\uc73c\ub85c replication \uad6c\uc131\uc774 \uc644\ub8cc\ub41c \uac83\uc774\ub2e4."}),"\n",(0,a.jsxs)(n.p,{children:["\uc124\uc815\uc744 \ub9c8\uce5c \ud6c4 source db\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 create table \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","replica db\uc5d0 \ub3d9\uc77c\ud55c member table\uc774 \uc0dd\uc131\ub41c \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:"CREATE TABLE member\n(\n id BIGINT PRIMARY KEY AUTO_INCREMENT,\n name VARCHAR(255)\n);\n"})}),"\n",(0,a.jsx)(n.h2,{id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8\ub85c-db-\uc811\uadfc\ud558\uae30",children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30"}),"\n",(0,a.jsx)(n.p,{children:"\uc77c\ubc18\uc801\uc778 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 source, \uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158\uc778 \uacbd\uc6b0 replica\ub85c \uc694\uccad\uc774 \uac00\ub3c4\ub85d \uad6c\uc131\ud574\ubcf4\uc790."}),"\n",(0,a.jsx)(n.h3,{id:"environment-\uc124\uc815",children:"Environment \uc124\uc815"}),"\n",(0,a.jsx)(n.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 source, replica\ub85c \uad6c\ubd84\ud558\uc5ec \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-yml",metastring:'title="application.yml"',children:"spring:\n datasource:\n source:\n username: user\n password: password\n driver-class-name: com.mysql.cj.jdbc.Driver\n jdbc-url: jdbc:mysql://localhost:13306/db\n replica:\n username: user\n password: password\n driver-class-name: com.mysql.cj.jdbc.Driver\n jdbc-url: jdbc:mysql://localhost:13307/db\n"})}),"\n",(0,a.jsx)(n.h3,{id:"datasourcetype-\uc124\uc815",children:"DataSourceType \uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["\ub2e8\uc21c \ubb38\uc790\uc5f4\ub85c\ub3c4 \uad6c\ubd84\ud560 \uc218 \uc788\uc9c0\ub9cc, enum\uc744 \uc774\uc6a9\ud574\uc11c \ud2b8\ub79c\uc7ad\uc158\uc744 \uad6c\ubd84\ud558\ub3c4\ub85d \uc0dd\uc131\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","Key\ub294 \ucd94\ud6c4\uc5d0 \ube48 \uc124\uc815\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-java",metastring:'title="DataSourceType"',children:'public enum DataSourceType {\n SOURCE(SOURCE_NAME),\n REPLICA(REPLICA_NAME),\n ;\n\n private final String key;\n\n DataSourceType(String key) {\n this.key = key;\n }\n\n public static class Key {\n public static final String ROUTING_NAME = "ROUTING";\n public static final String SOURCE_NAME = "SOURCE";\n public static final String REPLICA_NAME = "REPLICA";\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"abstractroutingdatasource-\uc124\uc815",children:"AbstractRoutingDataSource \uc124\uc815"}),"\n",(0,a.jsx)(n.p,{children:"\uc2a4\ud504\ub9c1\uc774 \uc9c0\uc6d0\ud574\uc8fc\ub294 AbstractRoutingDataSource\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSource\ub97c \ud5a5\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsxs)(n.p,{children:["\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub294 ",(0,a.jsx)(n.code,{children:"Map<DataSourceKey, DataSource>"}),"\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\uc744 \ubc1b\uc544 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4."]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"setDefaultTargetDataSource: \uae30\ubcf8 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.li,{children:"setTargetDataSources: \ub9f5 \ud615\ud0dc\ub85c \ubc1b\uc740 \ub370\uc774\ud130 \uc18c\uc2a4 \uac12\ub4e4\uc744 \uc124\uc815\ud55c\ub2e4."}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"determineCurrentLookupKey\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \ud2b8\ub79c\uc7ad\uc158\uc774 \uc77d\uae30 \uc804\uc6a9\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(n.li,{children:"DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uace0, \ubc18\ud658\ud55c \uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ub370\uc774\ud130 \uc18c\uc2a4\uac00 \uc0ac\uc6a9\ub41c\ub2e4."}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-java",metastring:'title="RoutingDataSource"',children:'public class RoutingDataSource extends AbstractRoutingDataSource {\n\n private final Logger log = LoggerFactory.getLogger(getClass());\n\n public static RoutingDataSource from(Map<Object, Object> dataSources) {\n RoutingDataSource routingDataSource = new RoutingDataSource();\n routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));\n routingDataSource.setTargetDataSources(dataSources);\n return routingDataSource;\n }\n\n @Override\n protected Object determineCurrentLookupKey() {\n boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();\n\n if (readOnly) {\n log.info("readOnly = true, request to replica");\n return DataSourceType.REPLICA;\n }\n log.info("readOnly = false, request to source");\n return DataSourceType.SOURCE;\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"datasource-\uc124\uc815",children:"DataSource \uc124\uc815"}),"\n",(0,a.jsxs)(n.p,{children:["\uc704\uc5d0\uc11c\ubd80\ud130 \uc21c\uc11c\ub300\ub85c Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy \uc124\uc815\uc774\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\uc2a4\ud504\ub9c1\uc740 \ud2b8\ub79c\uc7ad\uc158 \uc2dc\uc791\uc2dc\uc5d0 \ucee4\ub125\uc158\uc758 \uc0ac\uc6a9\uc5ec\ubd80\uc640 \uc0c1\uad00\uc5c6\uc774 \ucee4\ub125\uc158\uc744 \ud655\ubcf4\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c readOnly \ud2b8\ub79c\uc7ad\uc158\uc774 \uc124\uc815\ub41c \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ubbf8\ub9ac \ud655\ubcf4\ub41c \ucee4\ub125\uc158\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 replica db\ub85c \uc694\uccad\uc744 \ud558\uc9c0 \uc54a\uace0 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4."]}),"\n",(0,a.jsxs)(n.p,{children:["TransactionSynchronizationManager.isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc \ud638\ucd9c \uc2dc currentTransactionReadOnly\ub77c\ub294 ",(0,a.jsx)(n.code,{children:"ThreadLocal<Boolean>"}),"\uc5d0 \uc124\uc815\ub41c \uac12\uc744 \ubc18\ud658\ud558\ub294\ub370 readOnly \uc124\uc815\uc774 \ub418\uba74 \uc774 \uac12\uc744 true\ub85c \uc124\uc815\ud55c\ub2e4. \ud558\uc9c0\ub9cc determineCurrentLookupKey\ub97c \ud638\ucd9c\ud558\uc5ec key \uac12\uc744 \uac00\uc838\uc624\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc774\ud6c4\uc5d0 \uc124\uc815\ub418\uae30 \ub54c\ubb38\uc5d0 determineCurrentLookupKey \uba54\uc11c\ub4dc\uc5d0\uc11c \ud56d\uc0c1 DataSourceType.SOURCE\uac00 \ubc18\ud658\ub418\uc5b4 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4."]}),"\n",(0,a.jsx)(n.p,{children:"LazyConnectionDataSourceProxy\ub97c \uc124\uc815\ud558\ub294 \uacbd\uc6b0 \uc2e4\uc81c DataSource\ub97c \uc0ac\uc6a9\ud558\ub294 \uc2dc\uc810\uc5d0 \ucee4\ub125\uc158\uc744 \ud68d\ub4dd\ud574\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc124\uc815\ud55c\ub300\ub85c replica db\ub85c \uc870\ud68c \uc694\uccad\uc744 \ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-java",metastring:'title="DataSourceConfiguration"',children:'@Configuration\npublic class DataSourceConfiguration {\n\n @Bean\n @Qualifier(SOURCE_NAME)\n @ConfigurationProperties(prefix = "spring.datasource.source")\n public DataSource sourceDataSource() {\n return DataSourceBuilder.create().build();\n }\n\n @Bean\n @Qualifier(REPLICA_NAME)\n @ConfigurationProperties(prefix = "spring.datasource.replica")\n public DataSource replicaDataSource() {\n return DataSourceBuilder.create().build();\n }\n\n @Bean\n @Qualifier(ROUTING_NAME)\n public DataSource routingDataSource(\n @Qualifier(SOURCE_NAME) DataSource sourceDataSource,\n @Qualifier(REPLICA_NAME) DataSource replicaDataSource\n ) {\n return RoutingDataSource.from(Map.of(\n DataSourceType.SOURCE, sourceDataSource,\n DataSourceType.REPLICA, replicaDataSource\n ));\n }\n\n @Bean\n @Primary\n public DataSource dataSource(\n @Qualifier(ROUTING_NAME) DataSource routingDataSource\n ) {\n return new LazyConnectionDataSourceProxy(routingDataSource);\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"\ucd5c\uc885\uc801\uc73c\ub85c DataSource \ube48\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\uac00 \ub41c\ub2e4."}),"\n",(0,a.jsx)(n.mermaid,{value:"graph LR\n DSP[LazyConnectionDataSourceProxy] --\x3e RDS[RoutingDataSource]\n\tRDS --\x3e S[SourceDataSource]\n\tRDS --\x3e R[ReplicaDataSource]"}),"\n",(0,a.jsx)(n.h3,{id:"\ub3d9\uc791-\ud655\uc778",children:"\ub3d9\uc791 \ud655\uc778"}),"\n",(0,a.jsxs)(n.p,{children:["\uac04\ub2e8\ud558\uac8c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud574\uc11c \uc124\uc815\ud55c\ub300\ub85c \ub3d9\uc791\uc774 \ub418\ub294\uc9c0 \ud655\uc778\ud574\ubcf4\uc558\ub2e4.",(0,a.jsx)(n.br,{}),"\n","save \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 ",(0,a.jsx)(n.code,{children:"@Transactional"}),", findById \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 ",(0,a.jsx)(n.code,{children:"@Transactional(readOnly = true)"}),"\uac00 \uc124\uc815\ub418\uc5b4\uc788\ub2e4.",(0,a.jsx)(n.br,{}),"\n","\ub85c\uadf8\ub97c \ud1b5\ud574 save\uc758 \uacbd\uc6b0 source db\ub85c findById\uc758 \uacbd\uc6b0 replica db\ub85c \uc694\uccad\uc744 \ud558\ub294 \uac83\uc744 \uc54c \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-java",metastring:'title="MemberServiceTest"',children:'@SpringBootTest\nclass MemberServiceTest {\n\n @Autowired\n private MemberService memberService;\n\n @Test\n void \uc0ac\uc6a9\uc790\ub97c_\uc800\uc7a5\ud55c\ub2e4() {\n // RoutingDataSource log: readOnly = false\n memberService.save("bbiac");\n }\n\n @Test\n void \uc0ac\uc6a9\uc790\ub97c_\uc870\ud68c\ud55c\ub2e4() {\n // RoutingDataSource log: readOnly = true\n assertThatThrownBy(() -> memberService.findById(MAX_VALUE))\n .isInstanceOf(NoSuchElementException.class);\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"DB\uc5d0\uc11c\ub294 \ud655\uc778\ud558\ub824\uba74 root \uacc4\uc815\uc73c\ub85c \uc811\uc18d\ud55c \ud6c4 general log\ub97c \ud65c\uc131\ud654 \uc2dc\ud0a8\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:"SET GLOBAL log_output = 'table';\nSET GLOBAL general_log = 1;\n"})}),"\n",(0,a.jsxs)(n.p,{children:["general log\ub97c \ud65c\uc131\ud654 \ud55c \ud6c4 \uc77d\uae30 \uc804\uc6a9 \uba54\uc11c\ub4dc\ub97c \uc2e4\ud589\ud55c\ub2e4.",(0,a.jsx)(n.br,{}),"\n","server_id, \uc2e4\ud589\ud55c \ucffc\ub9ac\ubb38\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:"SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';\n\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n| user_host | thread_id | server_id | convert(argument using utf8) |\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n"})}),"\n",(0,a.jsx)(n.p,{children:"\ud655\uc778 \ud6c4 general log\ub97c \ube44\ud65c\uc131\ud654 \ud55c \ud6c4 \ube44\ud65c\uc131\ud654 \ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sql",children:"SET GLOBAL general_log = 0;\nSHOW VARIABLES LIKE '%general%';\n\n+------------------+---------------------------------+\n| Variable_name | Value |\n+------------------+---------------------------------+\n| general_log | OFF |\n| general_log_file | /var/lib/mysql/4b6b9db98290.log |\n+------------------+---------------------------------+\n"})}),"\n",(0,a.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,a.jsxs)(n.p,{children:["16\uc7a5 \ubcf5\uc81c, Real MySQL 8.0 - \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.1/en/replication.html",children:"Replication, MySQL Docs"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://huisam.tistory.com/entry/mysql-replication",children:"MySql - Master Slave Replication \uad6c\uc870 \ub9cc\ub4e4\uc5b4\ubcf4\uae30"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://cheese10yun.github.io/spring-transaction/",children:"Spring \ub808\ud50c\ub9ac\ucf00\uc774\uc158 \ud2b8\ub79c\uc7ad\uc158 \ucc98\ub9ac \ubc29\uc2dd"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://github.com/kwon37xi/replication-datasource",children:"replication-datasource"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://www.linkedin.com/pulse/simplified-guide-mysql-replication-docker-compose-rakesh-shekhawat/",children:"Simplified Guide to MySQL Replication with Docker Compose"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://www.daleseo.com/dockerfile/",children:"Dockerfile\uc5d0\uc11c \uc790\uc8fc \uc4f0\uc774\ub294 \uba85\ub839\uc5b4"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://dev.mysql.com/doc/refman/8.1/en/change-replication-source-to.html",children:"CHANGE REPLICATION SOURCE TO Statement"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://kwonnam.pe.kr/wiki/springframework/lazyconnectiondatasourceproxy",children:"LazyConnectionDataSourceProxy"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://hudi.blog/database-replication-with-springboot-and-mysql/",children:"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub808\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ud1b5\ud55c \ucffc\ub9ac \uc131\ub2a5 \uac1c\uc120 (feat. Mysql, SpringBoot)"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://chagokx2.tistory.com/100",children:"\ubd80\ud558 \ubd84\uc0b0\uc744 \uc704\ud55c MySQL Replication \uad6c\uc131 \ubc0f \ucffc\ub9ac \uc694\uccad \ubd84\uae30"}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.a,{href:"https://docs.docker.com/get-started/08_using_compose/",children:"Use Docker Compose, Docker"})]})]})}function h(e={}){const{wrapper:n}={...(0,t.ah)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>o});var a=r(67294);function t(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,a)}return r}function l(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){t(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function s(e,n){if(null==e)return{};var r,a,t=function(e,n){if(null==e)return{};var r,a,t={},i=Object.keys(e);for(a=0;a<i.length;a++)r=i[a],n.indexOf(r)>=0||(t[r]=e[r]);return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(a=0;a<i.length;a++)r=i[a],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(t[r]=e[r])}return t}var c=a.createContext({}),o=function(e){var n=a.useContext(c),r=n;return e&&(r="function"==typeof e?e(n):l(l({},n),e)),r},u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var r=e.components,t=e.mdxType,i=e.originalType,c=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),p=o(r),h=t,S=p["".concat(c,".").concat(h)]||p[h]||u[h]||i;return r?a.createElement(S,l(l({ref:n},d),{},{components:r})):a.createElement(S,l({ref:n},d))}));d.displayName="MDXCreateElement"},85162:(e,n,r)=>{r.d(n,{Z:()=>l});r(67294);var a=r(86010);const t={tabItem:"tabItem_Ymn6"};var i=r(85893);function l(e){let{children:n,hidden:r,className:l}=e;return(0,i.jsx)("div",{role:"tabpanel",className:(0,a.Z)(t.tabItem,l),hidden:r,children:n})}},74866:(e,n,r)=>{r.d(n,{Z:()=>R});var a=r(67294),t=r(86010),i=r(12466),l=r(16550),s=r(20469),c=r(91980),o=r(67392),u=r(50012);function d(e){return a.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,a.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function p(e){const{values:n,children:r}=e;return(0,a.useMemo)((()=>{const e=n??function(e){return d(e).map((e=>{let{props:{value:n,label:r,attributes:a,default:t}}=e;return{value:n,label:r,attributes:a,default:t}}))}(r);return function(e){const n=(0,o.l)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,r])}function h(e){let{value:n,tabValues:r}=e;return r.some((e=>e.value===n))}function S(e){let{queryString:n=!1,groupId:r}=e;const t=(0,l.k6)(),i=function(e){let{queryString:n=!1,groupId:r}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:n,groupId:r});return[(0,c._X)(i),(0,a.useCallback)((e=>{if(!i)return;const n=new URLSearchParams(t.location.search);n.set(i,e),t.replace({...t.location,search:n.toString()})}),[i,t])]}function x(e){const{defaultValue:n,queryString:r=!1,groupId:t}=e,i=p(e),[l,c]=(0,a.useState)((()=>function(e){let{defaultValue:n,tabValues:r}=e;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!h({value:n,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${r.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const a=r.find((e=>e.default))??r[0];if(!a)throw new Error("Unexpected error: 0 tabValues");return a.value}({defaultValue:n,tabValues:i}))),[o,d]=S({queryString:r,groupId:t}),[x,m]=function(e){let{groupId:n}=e;const r=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,i]=(0,u.Nk)(r);return[t,(0,a.useCallback)((e=>{r&&i.set(e)}),[r,i])]}({groupId:t}),b=(()=>{const e=o??x;return h({value:e,tabValues:i})?e:null})();(0,s.Z)((()=>{b&&c(b)}),[b]);return{selectedValue:l,selectValue:(0,a.useCallback)((e=>{if(!h({value:e,tabValues:i}))throw new Error(`Can't select invalid tab value=${e}`);c(e),d(e),m(e)}),[d,m,i]),tabValues:i}}var m=r(72389);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var j=r(85893);function g(e){let{className:n,block:r,selectedValue:a,selectValue:l,tabValues:s}=e;const c=[],{blockElementScrollPositionUntilNextRender:o}=(0,i.o5)(),u=e=>{const n=e.currentTarget,r=c.indexOf(n),t=s[r].value;t!==a&&(o(n),l(t))},d=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{const r=c.indexOf(e.currentTarget)+1;n=c[r]??c[0];break}case"ArrowLeft":{const r=c.indexOf(e.currentTarget)-1;n=c[r]??c[c.length-1];break}}n?.focus()};return(0,j.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.Z)("tabs",{"tabs--block":r},n),children:s.map((e=>{let{value:n,label:r,attributes:i}=e;return(0,j.jsx)("li",{role:"tab",tabIndex:a===n?0:-1,"aria-selected":a===n,ref:e=>c.push(e),onKeyDown:d,onClick:u,...i,className:(0,t.Z)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":a===n}),children:r??n},n)}))})}function _(e){let{lazy:n,children:r,selectedValue:t}=e;const i=(Array.isArray(r)?r:[r]).filter(Boolean);if(n){const e=i.find((e=>e.props.value===t));return e?(0,a.cloneElement)(e,{className:"margin-top--md"}):null}return(0,j.jsx)("div",{className:"margin-top--md",children:i.map(((e,n)=>(0,a.cloneElement)(e,{key:n,hidden:e.props.value!==t})))})}function y(e){const n=x(e);return(0,j.jsxs)("div",{className:(0,t.Z)("tabs-container",b.tabList),children:[(0,j.jsx)(g,{...e,...n}),(0,j.jsx)(_,{...e,...n})]})}function R(e){const n=(0,m.Z)();return(0,j.jsx)(y,{...e,children:d(e.children)},String(n))}}}]); \ No newline at end of file diff --git a/assets/js/f06cb3e2.e9cf765a.js b/assets/js/f06cb3e2.e9cf765a.js deleted file mode 100644 index 28a18b946..000000000 --- a/assets/js/f06cb3e2.e9cf765a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2620],{3905:(e,t,a)=>{a.d(t,{Zo:()=>p,kt:()=>d});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function o(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?l(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function i(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},l=Object.keys(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var u=n.createContext({}),c=function(e){var t=n.useContext(u),a=t;return e&&(a="function"==typeof e?e(t):o(o({},t),e)),a},p=function(e){var t=c(e.components);return n.createElement(u.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,u=e.parentName,p=i(e,["components","mdxType","originalType","parentName"]),m=c(a),d=r,k=m["".concat(u,".").concat(d)]||m[d]||s[d]||l;return a?n.createElement(k,o(o({ref:t},p),{},{components:a})):n.createElement(k,o({ref:t},p))}));function d(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,o=new Array(l);o[0]=m;var i={};for(var u in t)hasOwnProperty.call(t,u)&&(i[u]=t[u]);i.originalType=e,i.mdxType="string"==typeof e?e:r,o[1]=i;for(var c=2;c<l;c++)o[c]=a[c];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}m.displayName="MDXCreateElement"},85162:(e,t,a)=>{a.d(t,{Z:()=>o});var n=a(67294),r=a(86010);const l="tabItem_Ymn6";function o(e){let{children:t,hidden:a,className:o}=e;return n.createElement("div",{role:"tabpanel",className:(0,r.Z)(l,o),hidden:a},t)}},74866:(e,t,a)=>{a.d(t,{Z:()=>v});var n=a(87462),r=a(67294),l=a(86010),o=a(12466),i=a(16550),u=a(91980),c=a(67392),p=a(50012);function s(e){return function(e){return r.Children.map(e,(e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}(e).map((e=>{let{props:{value:t,label:a,attributes:n,default:r}}=e;return{value:t,label:a,attributes:n,default:r}}))}function m(e){const{values:t,children:a}=e;return(0,r.useMemo)((()=>{const e=t??s(a);return function(e){const t=(0,c.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[t,a])}function d(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function k(e){let{queryString:t=!1,groupId:a}=e;const n=(0,i.k6)(),l=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,u._X)(l),(0,r.useCallback)((e=>{if(!l)return;const t=new URLSearchParams(n.location.search);t.set(l,e),n.replace({...n.location,search:t.toString()})}),[l,n])]}function S(e){const{defaultValue:t,queryString:a=!1,groupId:n}=e,l=m(e),[o,i]=(0,r.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(t){if(!d({value:t,tabValues:a}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const n=a.find((e=>e.default))??a[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:t,tabValues:l}))),[u,c]=k({queryString:a,groupId:n}),[s,S]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[n,l]=(0,p.Nk)(a);return[n,(0,r.useCallback)((e=>{a&&l.set(e)}),[a,l])]}({groupId:n}),g=(()=>{const e=u??s;return d({value:e,tabValues:l})?e:null})();(0,r.useLayoutEffect)((()=>{g&&i(g)}),[g]);return{selectedValue:o,selectValue:(0,r.useCallback)((e=>{if(!d({value:e,tabValues:l}))throw new Error(`Can't select invalid tab value=${e}`);i(e),c(e),S(e)}),[c,S,l]),tabValues:l}}var g=a(72389);const b="tabList__CuJ",y="tabItem_LNqP";function _(e){let{className:t,block:a,selectedValue:i,selectValue:u,tabValues:c}=e;const p=[],{blockElementScrollPositionUntilNextRender:s}=(0,o.o5)(),m=e=>{const t=e.currentTarget,a=p.indexOf(t),n=c[a].value;n!==i&&(s(t),u(n))},d=e=>{let t=null;switch(e.key){case"Enter":m(e);break;case"ArrowRight":{const a=p.indexOf(e.currentTarget)+1;t=p[a]??p[0];break}case"ArrowLeft":{const a=p.indexOf(e.currentTarget)-1;t=p[a]??p[p.length-1];break}}t?.focus()};return r.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":a},t)},c.map((e=>{let{value:t,label:a,attributes:o}=e;return r.createElement("li",(0,n.Z)({role:"tab",tabIndex:i===t?0:-1,"aria-selected":i===t,key:t,ref:e=>p.push(e),onKeyDown:d,onClick:m},o,{className:(0,l.Z)("tabs__item",y,o?.className,{"tabs__item--active":i===t})}),a??t)})))}function N(e){let{lazy:t,children:a,selectedValue:n}=e;const l=(Array.isArray(a)?a:[a]).filter(Boolean);if(t){const e=l.find((e=>e.props.value===n));return e?(0,r.cloneElement)(e,{className:"margin-top--md"}):null}return r.createElement("div",{className:"margin-top--md"},l.map(((e,t)=>(0,r.cloneElement)(e,{key:t,hidden:e.props.value!==n}))))}function R(e){const t=S(e);return r.createElement("div",{className:(0,l.Z)("tabs-container",b)},r.createElement(_,(0,n.Z)({},e,t)),r.createElement(N,(0,n.Z)({},e,t)))}function v(e){const t=(0,g.Z)();return r.createElement(R,(0,n.Z)({key:String(t)},e))}},7729:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>p,contentTitle:()=>u,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>s});var n=a(87462),r=(a(67294),a(3905)),l=a(74866),o=a(85162);const i={title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",slug:"db-replication",tags:["mysql","replication"]},u=void 0,c={permalink:"/db-replication",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",source:"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",description:"\ubcf5\uc81c(Replication)",date:"2023-08-22T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 22\uc77c",tags:[{label:"mysql",permalink:"/tags/mysql"},{label:"replication",permalink:"/tags/replication"}],readingTime:21,hasTruncateMarker:!1,authors:[],frontMatter:{title:"DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30",slug:"db-replication",tags:["mysql","replication"]},prevItem:{title:"\uc131\ub2a5 \ud14c\uc2a4\ud2b8 \uc885\ub958",permalink:"/performance-test-type"},nextItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",permalink:"/woowacourse-level3-retrospective"}},p={authorsImageUrls:[]},s=[{value:"\ubcf5\uc81c(Replication)",id:"\ubcf5\uc81creplication",level:2},{value:"\ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720",id:"\ubcf5\uc81c\ub97c-\ud558\ub294-\uc774\uc720",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ud30c\uc77c-\uc704\uce58-\uae30\ubc18-\ubcf5\uc81c",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd\uc758-\ubb38\uc81c\uc810",level:3},{value:"\uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c",id:"\uae00\ub85c\ubc8c-\ud2b8\ub79c\uc7ad\uc158-\uc544\uc774\ub514gtid-\uae30\ubc18-\ubcf5\uc81c",level:3},{value:"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0",id:"\ubcf5\uc81c-\ud1a0\ud3f4\ub85c\uc9c0",level:3},{value:"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30",id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd-replication-\uad6c\uc131\ud558\uae30",level:2},{value:"MySQL \ud658\uacbd \uad6c\uc131",id:"mysql-\ud658\uacbd-\uad6c\uc131",level:3},{value:"\ub3c4\ucee4 \uc2e4\ud589",id:"\ub3c4\ucee4-\uc2e4\ud589",level:3},{value:"replication slave \uad8c\ud55c \uc124\uc815",id:"replication-slave-\uad8c\ud55c-\uc124\uc815",level:3},{value:"SOURCE DB \uc815\ubcf4 \ud655\uc778",id:"source-db-\uc815\ubcf4-\ud655\uc778",level:3},{value:"SOURCE ip \uc8fc\uc18c \ud655\uc778",id:"source-ip-\uc8fc\uc18c-\ud655\uc778",level:3},{value:"replica mysql \uc811\uc18d",id:"replica-mysql-\uc811\uc18d",level:3},{value:"replica \uc124\uc815",id:"replica-\uc124\uc815",level:3},{value:"\uc124\uc815 \ud655\uc778",id:"\uc124\uc815-\ud655\uc778",level:3},{value:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30",id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8\ub85c-db-\uc811\uadfc\ud558\uae30",level:2},{value:"Environment \uc124\uc815",id:"environment-\uc124\uc815",level:3},{value:"DataSourceType \uc124\uc815",id:"datasourcetype-\uc124\uc815",level:3},{value:"AbstractRoutingDataSource \uc124\uc815",id:"abstractroutingdatasource-\uc124\uc815",level:3},{value:"DataSource \uc124\uc815",id:"datasource-\uc124\uc815",level:3},{value:"\ub3d9\uc791 \ud655\uc778",id:"\ub3d9\uc791-\ud655\uc778",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],m={toc:s};function d(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"\ubcf5\uc81creplication"},"\ubcf5\uc81c(Replication)"),(0,r.kt)("p",null,"\ud55c \uc11c\ubc84\uc5d0\uc11c \ub2e4\ub978 \uc11c\ubc84\ub85c \ub370\uc774\ud130\ub97c \ub3d9\uae30\ud654\ud558\ub294 \uac83\uc744 \uc758\ubbf8\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc6d0\ubcf8 \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Primary \ub610\ub294 Source \ub77c\uace0 \ubd80\ub974\uace0, \ubcf5\uc81c\ub41c \ub370\uc774\ud130\ub97c \uac00\uc9c0\ub294 \uc11c\ubc84\ub97c Secondary \ub610\ub294 Replica \ub77c\uace0 \ubd80\ub978\ub2e4. "),(0,r.kt)("h3",{id:"\ubcf5\uc81c\ub97c-\ud558\ub294-\uc774\uc720"},"\ubcf5\uc81c\ub97c \ud558\ub294 \uc774\uc720"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"1. \uc2a4\ucf00\uc77c \uc544\uc6c3")),(0,r.kt)("p",null,"\uc0ac\uc6a9\uc790\uc758 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0, \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uac00\ud574\uc9c0\ub294 \ubd80\ud558\ub3c4 \uc790\uc5f0\uc2a4\ub7fd\uac8c \uc99d\uac00\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub97c \ucc98\ub9ac\ud558\uae30 \uc704\ud574 \ubcf5\uc81c\ub97c \ud1b5\ud55c \uc2a4\ucf00\uc77c \uc544\uc6c3\uc744 \uc801\uc6a9\ud558\uc5ec \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 \ucffc\ub9ac\ub4e4\uc744 \uac01\uac01\uc758 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub85c \ubd84\uc0b0 \uc2dc\ud0ac \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"2. \ub370\uc774\ud130 \ubc31\uc5c5")),(0,r.kt)("p",null,"\uc2e4\uc81c \uc6b4\uc601\ub418\ub294 \uc11c\ube44\uc2a4\uac00 \uc0ac\uc6a9\ud558\uace0 \uc788\ub294 DB\uc5d0\uc11c \ubc31\uc5c5\uc744 \uc9c4\ud589\ud558\ub294 \uacbd\uc6b0, \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc2e4\uc81c \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc774 \uac00\uc9c0 \uc54a\ub3c4\ub85d \ubcf5\uc81c\ub97c \ud1b5\ud574 Replica \uc11c\ubc84\ub97c \uad6c\ucd95\ud558\uc5ec, Replica \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ub97c \uc9c4\ud589\ud558\ub294 \ubc29\ubc95\uc73c\ub85c \uc601\ud5a5\uc744 \ucd5c\uc18c\ud654 \ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"3. \ub370\uc774\ud130 \ubd84\uc11d")),(0,r.kt)("p",null,"\ubc31\uc5c5\uacfc \ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc7a1\ud558\uace0 \ubb34\uac70\uc6b4 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\uc758 \uc11c\ube44\uc2a4\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce60 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub9c8\ucc2c\uac00\uc9c0\ub85c \ubcf5\uc81c\ub97c \uc0ac\uc6a9\ud574 \ubd84\uc11d\uc6a9 \ucffc\ub9ac\ub97c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub294 \ud658\uacbd\uc744 \ub9cc\ub4e4 \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"4. \ub370\uc774\ud130\uc758 \uc9c0\ub9ac\uc801 \ubd84\uc0b0")),(0,r.kt)("p",null,"\ube60\ub978 \uc751\ub2f5\uc744 \uc704\ud574 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \uc11c\ubc84\uc5d0 \uac00\uae5d\uac8c \uc11c\ubc84\ub97c \uad6c\uc131\ud558\uac70\ub098, \uace0\uac00\uc6a9\uc131(High Availability)\uc744 \uc704\ud574\uc11c\ub3c4 \uc0ac\uc6a9\ub41c\ub2e4. "),(0,r.kt)("h3",{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ud30c\uc77c-\uc704\uce58-\uae30\ubc18-\ubcf5\uc81c"},"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uc704\uce58 \uae30\ubc18 \ubcf5\uc81c"),(0,r.kt)("p",null,"MySQL \uc11c\ubc84\uc5d0\uc11c \ubc1c\uc0dd\ud558\ub294 \ubcc0\uacbd\uc0ac\ud56d\uc5d0 \ub300\ud55c \ub85c\uadf8 \ud30c\uc77c\uc744 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub77c\uace0 \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ud1b5\ud574 \ub370\uc774\ud130 \ubcc0\uacbd, \ud14c\uc774\ube14 \uad6c\uc870 \ubcc0\uacbd, \uacc4\uc815\uc774\ub098 \uad8c\ud55c \ubcc0\uacbd\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc800\uc7a5\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","MySQL\uc758 \ubcf5\uc81c\ub294 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \uad6c\ud604\ub418\uc5b4 \uc788\ub2e4. \uc774\ub97c Replica \uc11c\ubc84\ub85c \uc804\ub2ec\ud558\uace0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \uae30\ubc18\uc73c\ub85c \ub370\uc774\ud130\ub97c \ubcc0\uacbd \uc0ac\ud56d\uc744 \ubc18\uc601\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n\tsubgraph Replica\n\t\tdirection TB\n\t\tIO[Replication I/O thread] -- save --\x3e RL[Relay Log]\n\t\tSQL[Replication SQL Thread] -- read --\x3e RL\n\tend\n\n\tsubgraph Source\n\t\tdirection TB\n\t\tBLD[Binary Log Dump Thread] -- Send Binary Log Dump--\x3e IO\n\tend\n"}),(0,r.kt)("admonition",{title:"\uc2a4\ub808\ub4dc\ubcc4 \uc5ed\ud560",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"Binary Log Dump Thread: \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc758 \ub0b4\uc6a9\uc744 Replica \uc11c\ubc84\ub85c \uc804\ub2ec",(0,r.kt)("br",{parentName:"p"}),"\n","Replication I/O Thread: Binary \ub85c\uadf8 \uc774\ubca4\ud2b8\ub97c \uac00\uc838\uc640 \ub85c\uceec \uc11c\ubc84\uc758 \ud30c\uc77c(Relay Log)\ub85c \uc800\uc7a5",(0,r.kt)("br",{parentName:"p"}),"\n","Replication SQL Thread: \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc774\ubca4\ud2b8\ub97c \uc77d\uace0 \uc2e4\ud589")),(0,r.kt)("h3",{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd\uc758-\ubb38\uc81c\uc810"},"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc758 \ubb38\uc81c\uc810"),(0,r.kt)("p",null,"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd\uc740 \uc11c\ubc84\uc5d0 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud588\uc744 \ub54c \ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0 \ubcc0\uacbd\uc774 \uae4c\ub2e4\ub86d\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud1a0\ud3f4\ub85c\uc9c0\ub780 \ub124\ud2b8\uc6cc\ud06c\uc758 \uc694\uc18c\ub4e4\uc744 \ubb3c\ub9ac\uc801\uc73c\ub85c \uc5f0\uacb0\ud574 \ub193\uc740 \uac83, \ub610\ub294 \uadf8 \uc5f0\uacb0 \ubc29\uc2dd\uc744 \ub9d0\ud55c\ub2e4."),(0,r.kt)("mermaid",{value:"graph TD\n\tA[A binary-log:300] --\x3e B[B Binary-log:300]\n\tA[A binary-log:300] --\x3e C[C Binary-log:200]"}),(0,r.kt)("p",null,"\uc704\uc640 \uac19\uc774 Source \uc11c\ubc84, Replica 2\ub300\uac00 \uc874\uc7ac\ud558\uace0, C \uc11c\ubc84\uc5d0 \ubcf5\uc81c \uc9c0\uc5f0\uc774 \ub418\uc5c8\uc744 \ub54c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph TD\n\tA[A binary-log:300]\n\tB[B Binary-log:300] --\x3e C[C Binary-log:200 \ubb38\uc81c \ubc1c\uc0dd]"}),(0,r.kt)("p",null,"A \uc11c\ubc84\uc5d0\uc11c \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 B \uc11c\ubc84\ub97c Source \uc11c\ubc84\ub85c \uc2b9\uaca9\ud558\uace0, C\uc5d0\uac8c \uc870\ud68c \ucffc\ub9ac\ub97c \ubd84\uc0b0\uc2dc\ud0a8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\uc9c0\ub9cc \uc5ec\uae30\uc11c C \uc11c\ubc84\uc5d0\ub294 A \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\uac00 \uc548\ub418\uc5c8\uc73c\ub2c8 \uc870\ud68c \uc2dc \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub4a4\ub2a6\uac8c B \uc11c\ubc84\uc640 \ub3d9\uae30\ud654\ub97c \ud558\ub824\uace0 \ud574\ub3c4, \uc5b4\ub5a4 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8, \uc5b4\ub5a4 \uc704\uce58\uc640 \ub3d9\uae30\ud654\ud574\uc57c\ud558\ub294\uc9c0 \uc54c\uae30 \uc5b4\ub835\ub2e4. "),(0,r.kt)("h3",{id:"\uae00\ub85c\ubc8c-\ud2b8\ub79c\uc7ad\uc158-\uc544\uc774\ub514gtid-\uae30\ubc18-\ubcf5\uc81c"},"\uae00\ub85c\ubc8c \ud2b8\ub79c\uc7ad\uc158 \uc544\uc774\ub514(GTID) \uae30\ubc18 \ubcf5\uc81c"),(0,r.kt)("p",null,"GTID \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud558\uc5ec \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ubc1c\uc0dd\ud55c \uc774\ubca4\ud2b8\uc5d0 \uace0\uc720\ud55c \uc2dd\ubcc4\uac12\uc744 \ubd80\uc5ec\ud55c\ub2e4\uba74, \ub3d9\uae30\ud654\uc5d0 \ub300\ud55c \ubb38\uc81c\ub97c \uac04\ub2e8\ud558\uac8c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc704\uc758 \uc608\uc2dc\uc640 \uac19\uc774 \ubcf5\uc81c \uc9c0\uc5f0\uacfc \ud568\uaed8 \uc7a5\uc560\uac00 \ubc1c\uc0dd\ud55c\ub2e4\ud574\ub3c4 \ud2b9\uc815 GTID \ubd80\ud130 \ubcf5\uc81c\ub97c \uc7ac\uac1c\ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("admonition",{title:"GTID",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0\uc5d0 \ucc38\uc5ec\ud55c \ubaa8\ub4e0 \uc11c\ubc84\uc5d0\uc11c \uace0\uc720\ud558\ub3c4\ub85d \uac01 \uc774\ubca4\ud2b8\uc5d0 \ubd80\uc5ec\ub41c \uc2dd\ubcc4\uac12",(0,r.kt)("br",{parentName:"p"}),"\n","[source_id]",":","[transaction_id]","\ub85c \uad6c\uc131\ub418\uba70, source_id\ub294 \uc11c\ubc84\ub97c \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc774\uace0 transaction_id\ub294 \ucee4\ubc0b\ub41c \ud2b8\ub79c\uc7ad\uc158\uc744 \uc2dd\ubcc4\ud558\uae30 \uc704\ud55c \uac12\uc73c\ub85c 1\uc529 \uc99d\uac00\ud558\ub294 \ud615\ud0dc\ub85c \ubc1c\uae09\ub41c\ub2e4. ")),(0,r.kt)("h3",{id:"\ubcf5\uc81c-\ud1a0\ud3f4\ub85c\uc9c0"},"\ubcf5\uc81c \ud1a0\ud3f4\ub85c\uc9c0"),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"\uac00\uc7a5 \uac04\ub2e8\ud55c \uad6c\uc131\uc73c\ub85c \uc81c\uc77c \ub9ce\uc774 \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","replica \uc11c\ubc84\ub97c \uc77d\uae30 \uc804\uc6a9, \uc608\ube44 \uc11c\ubc84, \ubc31\uc5c5 \uc6a9\ub3c4\ub85c \ub9ce\uc774 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R\n S[Source] --\x3e R[Replica]"}),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uba40\ud2f0 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"2\uac1c\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \ud615\ud0dc\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud558\ub098\uc758 replica\ub294 \uc608\ube44 \uc6a9\ub3c4\ub85c \ub0a8\uaca8\ub450\ub294 \ud615\ud0dc\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ucd94\ud6c4\uc5d0 \ud2b8\ub798\ud53d\uc774 \uc99d\uac00\ud558\ub294 \uacbd\uc6b0 \uc608\ube44 \uc6a9\ub3c4\uc758 replica\ub97c \uc0ac\uc6a9\ud568\uc73c\ub85c \uc77d\uae30 \uc694\uccad\uc758 \ubd80\ud558 \ubd84\uc0b0\uc744 \ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R1\n S[Source] --\x3e R1[Replica1]\n S --\x3e R2[Replica2]"}),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uccb4\uc778 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"replica \uc11c\ubc84\uac00 \ub9ce\uc740 \uacbd\uc6b0 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \uc804\ub2ec\ud558\ub294 \uc791\uc5c5 \uc790\uccb4\uac00 \ubd80\ud558\uac00 \ub420 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c 1:M:M \uad6c\uc870\ub85c \uccb4\uc778 \ubcf5\uc81c \uad6c\uc131\uc744 \uace0\ub824\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e S\n W -- \uc77d\uae30 --\x3e R1\n S[Source] --\x3e R1[Replica1]\n S --\x3e R2[Replica2]\n S --\x3e R3[Replica3]\n\n R3 --\x3e R3-1[Replica 3-1]\n R3 --\x3e R3-2[Replica 3-2]\n\n B[Batch Server] --\x3e R3-2"}),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\ub4c0\uc5bc \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"2\uac1c\uc758 MySQL \uc11c\ubc84 \ubaa8\ub450 \uc77d\uae30\uc640 \uc4f0\uae30\uac00 \uac00\ub2a5\ud558\ub3c4\ub85d \ud558\ub294 \uad6c\uc131\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uac01 \uc11c\ubc84\uc5d0\uc11c \ubcc0\uacbd\ub41c \ub370\uc774\ud130\ub294 \ub2e4\ub978 \uc11c\ubc84\uc5d0 \ubc18\uc601\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ubaa9\uc801\uc5d0 \ub530\ub77c ACTIVE-ACTIVE \ud615\ud0dc \ub610\ub294 ACTIVE-PASSIVE \ud615\ud0dc\ub85c \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","ACTIVE-PASSIVE \ud615\ud0dc\uc778 \uacbd\uc6b0 \uc2f1\uae00 \ub808\ud50c\ub9ac\uce74 \ubcf5\uc81c \uad6c\uc131\uacfc \ub3d9\uc77c\ud574\ubcf4\uc774\uc9c0\ub9cc, ACTIVE \uc11c\ubc84\uc5d0\uc11c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uba74 \uc124\uc815\uc758 \ubcc0\uacbd\uc5c6\uc774 PASSIVE \uc11c\ubc84\ub85c \uc4f0\uae30 \uc791\uc5c5\uc744 \uc804\ud658\ud560 \uc218 \uc788\ub2e4\ub294 \uac83\uc774 \uc7a5\uc810\uc774\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n W[Web Server] -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR1\n W -- \uc77d\uae30 + \uc4f0\uae30 --\x3e SR2\n SR1[Source/Replica 1] --\x3e SR2[Source/Replica 2]"}),(0,r.kt)("admonition",{title:"ACTIVE-ACTIVE, ACTIVE-PASSIVE",type:"note"},(0,r.kt)("p",{parentName:"admonition"},"ACTIVE-ACTIVE: 2\uac1c\uc758 \uc11c\ubc84 \ubaa8\ub450 \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc",(0,r.kt)("br",{parentName:"p"}),"\n","ACTIVE-PASSIVE: \ud558\ub098\uc758 \uc11c\ubc84\uc5d0\uc11c\ub9cc \uc4f0\uae30 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ud615\ud0dc")),(0,r.kt)("p",null,(0,r.kt)("strong",{parentName:"p"},"\uba40\ud2f0 \uc18c\uc2a4 \ubcf5\uc81c \uad6c\uc131")),(0,r.kt)("p",null,"\uc5ec\ub7ec\uac1c\uc758 source \uc11c\ubc84\uc640 \ud558\ub098\uc758 replica \uc11c\ubc84\ub97c \uc0ac\uc6a9\ud558\ub294 \uad6c\uc131\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 source \uc11c\ubc84\uc758 \ub370\uc774\ud130\ub97c \ud55c \uacf3\uc5d0 \ubc31\uc5c5\ud558\ub294 \uc6a9\ub3c4\ub85c \uc0ac\uc6a9, \uc5ec\ub7ec \uc11c\ubc84\uc5d0 \uc874\uc7ac\ud558\ub294 \ub370\uc774\ud130\ub97c \ud1b5\ud569, \uc0e4\ub529\ub418\uc5b4\uc788\ub294 \ud14c\uc774\ube14 \ub370\uc774\ud130\ub97c \ud1b5\ud569\ud560 \ub54c \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n S1[Source 1] --\x3e R[Replica]\n S2[Source 2] --\x3e R"}),(0,r.kt)("h2",{id:"\ubc14\uc774\ub108\ub9ac-\ub85c\uadf8-\ubc29\uc2dd-replication-\uad6c\uc131\ud558\uae30"},"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ubc29\uc2dd Replication \uad6c\uc131\ud558\uae30"),(0,r.kt)("p",null,"mysql 2\ub300\ub97c \uc774\uc6a9\ud558\uc5ec replication\uc744 \uad6c\uc131\ud558\uace0, spring boot application\uc73c\ub85c source, replica \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0 \uc811\uadfc\ud574\ubcf4\ub294 \uc608\uc81c\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/bbiac/db-replication"},"https://github.com/bbiac/db-replication")," "),(0,r.kt)("h3",{id:"mysql-\ud658\uacbd-\uad6c\uc131"},"MySQL \ud658\uacbd \uad6c\uc131"),(0,r.kt)("p",null,"MySQL \ubc84\uc804\uc740 8.1\uc744 \uc0ac\uc6a9\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","13306, 13307 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud574\uc11c MySQL \uc11c\ubc84 2\ub300\ub97c \ub744\uc6e0\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub610\ud55c \uc0ac\uc2e4 IP \ub300\uc5ed\uc73c\ub85c \ud1b5\uc2e0\ud560 \uc218 \uc788\ub3c4\ub85d \ucee4\uc2a4\ud140 \ub124\ud2b8\uc6cc\ud06c\ub97c \ucd94\uac00\ud588\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml"},"version: '3.8'\n\nservices:\n source:\n platform: linux/x86_64\n image: mysql:latest\n restart: always\n container_name: mysql-source\n environment:\n TZ: 'Asia/Seoul'\n MYSQL_DATABASE: 'db'\n MYSQL_USER: 'user'\n MYSQL_PASSWORD: 'password'\n MYSQL_ROOT_PASSWORD: 'password'\n ports:\n - \"13306:3306\"\n volumes:\n - db-source:/var/lib/mysql\n - db-source:/var/lib/mysql-files\n - ./docker/source.cnf:/etc/mysql/my.cnf\n networks:\n - mysql_network\n\n replica:\n platform: linux/x86_64\n image: mysql:latest\n restart: always\n container_name: mysql-replica\n environment:\n TZ: 'Asia/Seoul'\n MYSQL_DATABASE: 'db'\n MYSQL_USER: 'user'\n MYSQL_PASSWORD: 'password'\n MYSQL_ROOT_PASSWORD: 'password'\n ports:\n - \"13307:3306\"\n volumes:\n - db-replica:/var/lib/mysql\n - db-replica:/var/lib/mysql-files\n - ./docker/replica.cnf:/etc/mysql/my.cnf\n networks:\n - mysql_network\n\nvolumes:\n db-source:\n db-replica:\n\nnetworks:\n mysql_network:\n driver: bridge\n")),(0,r.kt)("p",null,"\ub610\ud55c source, replica \uac01\uac01 \ub2e4\uc74c\uacfc \uac19\uc774 db \uc124\uc815\uc744 \ud588\ub2e4. "),(0,r.kt)("table",null,(0,r.kt)("thead",{parentName:"table"},(0,r.kt)("tr",{parentName:"thead"},(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uc815"),(0,r.kt)("th",{parentName:"tr",align:null},"\uc124\uba85"))),(0,r.kt)("tbody",{parentName:"table"},(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"server_id"),(0,r.kt)("td",{parentName:"tr",align:null},"\uac01\uac01\uc758 mysql \ub9c8\ub2e4 \uace0\uc720\ud55c \uac12\uc744 \uac00\uc838\uc57c \ud55c\ub2e4.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"log_bin"),(0,r.kt)("td",{parentName:"tr",align:null},"\ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815\uc73c\ub85c \uc808\ub300\uacbd\ub85c\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74 /var/lib/mysql \uc544\ub798 \ud574\ub2f9 log_bin\uc5d0 \uc124\uc815\ub41c \uac12\uc73c\ub85c \ub85c\uadf8\uac00 \uc0dd\uc131\ub41c\ub2e4.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"sync_binlog"),(0,r.kt)("td",{parentName:"tr",align:null},"N\uac1c\uc758 \ud2b8\ub79c\uc7ad\uc158 \ub2f9 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\ub97c \ub514\uc2a4\ud06c\uc640 \ub3d9\uae30\ud654 \uc791\uc5c5\uc744 \ud558\ub3c4\ub85d \ud55c\ub2e4.\xa01\uc740 \uae30\ubcf8\uac12\uc73c\ub85c \uc548\uc815\uc801\uc774\uc9c0\ub9cc, \uac00\uc7a5 \ub290\ub9ac\ub2e4.")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"relay_log"),(0,r.kt)("td",{parentName:"tr",align:null},"\ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c \uacbd\ub85c \uc124\uc815")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"relay_log_purge"),(0,r.kt)("td",{parentName:"tr",align:null},"\ud544\uc694 \uc5c6\ub294 \ub9b4\ub808\uc774 \ub85c\uadf8 \ud30c\uc77c\uc744 \uc790\ub3d9\uc73c\ub85c \uc0ad\uc81c\ud558\ub294 \uc635\uc158")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"read_only"),(0,r.kt)("td",{parentName:"tr",align:null},"\uc77d\uae30 \uc804\uc6a9 \uc124\uc815")),(0,r.kt)("tr",{parentName:"tbody"},(0,r.kt)("td",{parentName:"tr",align:null},"log_replica_updates"),(0,r.kt)("td",{parentName:"tr",align:null},"Replication SQL Thread\ub85c \uc778\ud574 \uc2e4\ud589\ub418\ub294 \uc815\ubcf4\ub97c \ubc14\uc774\ub108\ub9ac \ub85c\uadf8\uc5d0 \uae30\ub85d \ucd94\ud6c4\uc5d0 \uc18c\uc2a4 \uc11c\ubc84\ub85c \uc2b9\uaca9\ub418\ub294 \uacbd\uc6b0\ub97c \uace0\ub824\ud558\uba74 \uc124\uc815\ud558\ub294 \uac83\uc774 \uc88b\ub2e4.")))),(0,r.kt)(l.Z,{mdxType:"Tabs"},(0,r.kt)(o.Z,{value:"Source",label:"Source",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-cnf",metastring:'title="/docker/source.cnf"',title:'"/docker/source.cnf"'},"[mysqld]\nserver_id=1\nlog_bin=mysql-bin\nsync_binlog=1\n"))),(0,r.kt)(o.Z,{value:"Replica",label:"Replica",mdxType:"TabItem"},(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-cnf",metastring:'title="/docker/replica.cnf"',title:'"/docker/replica.cnf"'},"[mysqld]\nserver_id=2\nrelay_log=mysql-relay-bin\nrelay_log_purge=ON\nread_only\nlog_replica_updates\n")))),(0,r.kt)("h3",{id:"\ub3c4\ucee4-\uc2e4\ud589"},"\ub3c4\ucee4 \uc2e4\ud589"),(0,r.kt)("p",null,"docker-compose up \uba85\ub839\uc5b4\ub85c docker-compose \uc124\uc815\uc73c\ub85c docker\ub97c \ub744\uc6b4\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","-d \uc635\uc158\uc744 \ubd99\uc774\uba74 \ubc31\uadf8\ub77c\uc6b4\ub4dc \ubaa8\ub4dc\ub85c \uc2e4\ud589\ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"docker-compose up -d\n")),(0,r.kt)("h3",{id:"replication-slave-\uad8c\ud55c-\uc124\uc815"},"replication slave \uad8c\ud55c \uc124\uc815"),(0,r.kt)("p",null,"REPLICATION SLAVE \uad8c\ud55c\uc774 \uc124\uc815\ub418\uc5b4 \uc788\uc5b4\uc57c replica \uc11c\ubc84\uc5d0\uc11c source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec \ub85c\uadf8\ub97c \uc77d\uc5b4\uc62c \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","source \uc11c\ubc84\uc5d0 \uc811\uadfc\ud558\uc5ec user \uacc4\uc815\uc5d0 \ud574\ub2f9 \uad8c\ud55c\uc744 \uc124\uc815\ud574\uc900\ub2e4. "),(0,r.kt)("p",null,"SOURCE \uc811\uc18d"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"docker exec -it mysql-source mysql -u root -p\n")),(0,r.kt)("p",null,"user \uacc4\uc815\uc5d0 REPLICATION SLAVE \uad8c\ud55c \ucd94\uac00"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mysql"},"GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';\nFLUSH PRIVILEGES;\n")),(0,r.kt)("h3",{id:"source-db-\uc815\ubcf4-\ud655\uc778"},"SOURCE DB \uc815\ubcf4 \ud655\uc778"),(0,r.kt)("p",null,"replica \uc124\uc815\uc5d0 \ud544\uc694\ud55c source db\uc758 \ubc14\uc774\ub108\ub9ac \ub85c\uadf8 \ud30c\uc77c\uba85\uacfc Position\uc744 \ud655\uc778\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Position \uac12\uc740 \uc2e4\uc81c \ud30c\uc77c\uc758 \ubc14\uc774\ud2b8 \uc218\ub97c \uc758\ubbf8\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud655\uc778\ud55c File(SOURCE_LOG_FILE)\uacfc Position(SOURCE_LOG_POS) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mysql"},"SHOW MASTER STATUS;\n\n+------------------+----------+--------------+------------------+-------------------+\n| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\n+------------------+----------+--------------+------------------+-------------------+\n| mysql-bin.000003 | 1082 | | | |\n+------------------+----------+--------------+------------------+-------------------+\n")),(0,r.kt)("h3",{id:"source-ip-\uc8fc\uc18c-\ud655\uc778"},"SOURCE ip \uc8fc\uc18c \ud655\uc778"),(0,r.kt)("p",null,"docker inspect -f \uc635\uc158\uc744 \uc0ac\uc6a9\ud558\uba74 \ud574\ub2f9 \ucee8\ud14c\uc774\ub108\uc758 \uc138\ubd80 \uc815\ubcf4\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc774\uc6a9\ud574 docker-compose \ud30c\uc77c\uc5d0 \uc124\uc815\ud574\ub454 mysql_network\uc5d0\uc11c \uc0ac\uc6a9\ub418\ub294 \uc0ac\uc124 \uc544\uc774\ud53c \uc8fc\uc18c\ub97c \ud655\uc778\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},'docker inspect -f "{{with index .NetworkSettings.Networks \\"db-replication_mysql_network\\"}}{{.IPAddress}}{{end}}" mysql-source\n')),(0,r.kt)("p",null,"ip \uc8fc\uc18c\uac00 \ub098\uc624\uc9c0 \uc54a\ub294 \uacbd\uc6b0 docker inspect mysql-source\ub85c \ud655\uc778\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud655\uc778\ud55c IP\uc8fc\uc18c(SOURCE_HOST) \uac12\uc740 replica \uc124\uc815\uc5d0\uc11c \uc0ac\uc6a9\ud55c\ub2e4."),(0,r.kt)("h3",{id:"replica-mysql-\uc811\uc18d"},"replica mysql \uc811\uc18d"),(0,r.kt)("p",null,"source db\uc5d0 \uc811\uc18d\ud588\ub358 \ubc29\ubc95\uacfc \ub3d9\uc77c\ud558\uac8c replica db\uc5d0 \uc811\uc18d\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"docker exec -it mysql-replica mysql -u root -p\n")),(0,r.kt)("h3",{id:"replica-\uc124\uc815"},"replica \uc124\uc815"),(0,r.kt)("p",null,"\uc774\uc804\uc5d0 source db\uc5d0\uc11c \uc5bb\uc5c8\ub358 \uc815\ubcf4\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc5ec replica \uc124\uc815\uc744 \uc9c4\ud589\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc2e4\uc81c DB \uc11c\ubc84\uc5d0\uc11c \ubcf5\uc81c\ud558\ub294 \uacbd\uc6b0 \ucd94\uac00\uc801\uc73c\ub85c source DB\uc758 \ud30c\uc77c\uc744 \ubcf5\uc81c\ud574\uc57c\ud558\uc9c0\ub9cc \ud604\uc7ac \ubcf5\uc81c\ud560 \ub370\uc774\ud130\uac00 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \ud574\ub2f9 \ubd80\ubd84\uc740 \uc0dd\ub7b5\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS \ub97c \uc801\uc808\ud788 \ubcc0\uacbd\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mysql"},"STOP REPLICA;\n\nCHANGE REPLICATION SOURCE TO \nSOURCE_HOST='172.29.0.2', \nSOURCE_USER='user', \nSOURCE_PASSWORD='password', \nSOURCE_LOG_FILE='mysql-bin.000001', \nSOURCE_LOG_POS=0, \nGET_SOURCE_PUBLIC_KEY=1;\n\nSTART REPLICA;\n")),(0,r.kt)("h3",{id:"\uc124\uc815-\ud655\uc778"},"\uc124\uc815 \ud655\uc778"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-mysql"},"SHOW REPLICA STATUS;\n\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |\n+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+\n")),(0,r.kt)("p",null,"Replica_IO_Running, Replica_SQL_Running \uac12\uc774 YES\ub77c\uba74 \uc815\uc0c1\uc801\uc73c\ub85c replication \uad6c\uc131\uc774 \uc644\ub8cc\ub41c \uac83\uc774\ub2e4. "),(0,r.kt)("p",null,"\uc124\uc815\uc744 \ub9c8\uce5c \ud6c4 source db\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 create table \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","replica db\uc5d0 \ub3d9\uc77c\ud55c member table\uc774 \uc0dd\uc131\ub41c \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"CREATE TABLE member\n(\n id BIGINT PRIMARY KEY AUTO_INCREMENT,\n name VARCHAR(255)\n);\n")),(0,r.kt)("h2",{id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8\ub85c-db-\uc811\uadfc\ud558\uae30"},"\uc2a4\ud504\ub9c1 \ubd80\ud2b8\ub85c DB \uc811\uadfc\ud558\uae30"),(0,r.kt)("p",null,"\uc77c\ubc18\uc801\uc778 \ud2b8\ub79c\uc7ad\uc158\uc758 \uacbd\uc6b0 source, \uc77d\uae30 \uc804\uc6a9 \ud2b8\ub79c\uc7ad\uc158\uc778 \uacbd\uc6b0 replica\ub85c \uc694\uccad\uc774 \uac00\ub3c4\ub85d \uad6c\uc131\ud574\ubcf4\uc790. "),(0,r.kt)("h3",{id:"environment-\uc124\uc815"},"Environment \uc124\uc815"),(0,r.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 source, replica\ub85c \uad6c\ubd84\ud558\uc5ec \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-yml",metastring:'title="application.yml"',title:'"application.yml"'},"spring:\n datasource:\n source:\n username: user\n password: password\n driver-class-name: com.mysql.cj.jdbc.Driver\n jdbc-url: jdbc:mysql://localhost:13306/db\n replica:\n username: user\n password: password\n driver-class-name: com.mysql.cj.jdbc.Driver\n jdbc-url: jdbc:mysql://localhost:13307/db\n")),(0,r.kt)("h3",{id:"datasourcetype-\uc124\uc815"},"DataSourceType \uc124\uc815"),(0,r.kt)("p",null,"\ub2e8\uc21c \ubb38\uc790\uc5f4\ub85c\ub3c4 \uad6c\ubd84\ud560 \uc218 \uc788\uc9c0\ub9cc, enum\uc744 \uc774\uc6a9\ud574\uc11c \ud2b8\ub79c\uc7ad\uc158\uc744 \uad6c\ubd84\ud558\ub3c4\ub85d \uc0dd\uc131\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Key\ub294 \ucd94\ud6c4\uc5d0 \ube48 \uc124\uc815\uc5d0 \uc0ac\uc6a9\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="DataSourceType"',title:'"DataSourceType"'},'public enum DataSourceType {\n SOURCE(SOURCE_NAME),\n REPLICA(REPLICA_NAME),\n ;\n\n private final String key;\n\n DataSourceType(String key) {\n this.key = key;\n }\n\n public static class Key {\n public static final String ROUTING_NAME = "ROUTING";\n public static final String SOURCE_NAME = "SOURCE";\n public static final String REPLICA_NAME = "REPLICA";\n }\n}\n')),(0,r.kt)("h3",{id:"abstractroutingdatasource-\uc124\uc815"},"AbstractRoutingDataSource \uc124\uc815"),(0,r.kt)("p",null,"\uc2a4\ud504\ub9c1\uc774 \uc9c0\uc6d0\ud574\uc8fc\ub294 AbstractRoutingDataSource\ub97c \uc0c1\uc18d\ubc1b\uc544 \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSource\ub97c \ud5a5\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("p",null,"\uc815\uc801 \ud329\ud130\ub9ac \uba54\uc11c\ub4dc\ub294 Map<DataSourceKey, DataSource>\uc5d0 \ud574\ub2f9\ud558\ub294 \uac12\uc744 \ubc1b\uc544 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"setDefaultTargetDataSource: \uae30\ubcf8 \ub370\uc774\ud130 \uc18c\uc2a4\ub97c \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("li",{parentName:"ul"},"setTargetDataSources: \ub9f5 \ud615\ud0dc\ub85c \ubc1b\uc740 \ub370\uc774\ud130 \uc18c\uc2a4 \uac12\ub4e4\uc744 \uc124\uc815\ud55c\ub2e4. ")),(0,r.kt)("p",null,"determineCurrentLookupKey\ub97c \uc624\ubc84\ub77c\uc774\ub529\ud558\uc5ec \ud2b8\ub79c\uc7ad\uc158\uc758 \uc77d\uae30 \uc5ec\ubd80\uc5d0 \ub530\ub77c \ub2e4\ub978 DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud55c\ub2e4. "),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc\ub97c \ud1b5\ud574 \ud2b8\ub79c\uc7ad\uc158\uc774 \uc77d\uae30 \uc804\uc6a9\uc778\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("li",{parentName:"ul"},"DataSourceType\uc744 \ubc18\ud658\ud558\ub3c4\ub85d \uc124\uc815\ud558\uace0, \ubc18\ud658\ud55c \uac12\uc5d0 \ud574\ub2f9\ud558\ub294 \ub370\uc774\ud130 \uc18c\uc2a4\uac00 \uc0ac\uc6a9\ub41c\ub2e4. ")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="RoutingDataSource"',title:'"RoutingDataSource"'},'public class RoutingDataSource extends AbstractRoutingDataSource {\n\n private final Logger log = LoggerFactory.getLogger(getClass());\n\n public static RoutingDataSource from(Map<Object, Object> dataSources) {\n RoutingDataSource routingDataSource = new RoutingDataSource();\n routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));\n routingDataSource.setTargetDataSources(dataSources);\n return routingDataSource;\n }\n\n @Override\n protected Object determineCurrentLookupKey() {\n boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();\n\n if (readOnly) {\n log.info("readOnly = true, request to replica");\n return DataSourceType.REPLICA;\n }\n log.info("readOnly = false, request to source");\n return DataSourceType.SOURCE;\n }\n}\n')),(0,r.kt)("h3",{id:"datasource-\uc124\uc815"},"DataSource \uc124\uc815"),(0,r.kt)("p",null,"\uc704\uc5d0\uc11c\ubd80\ud130 \uc21c\uc11c\ub300\ub85c Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy \uc124\uc815\uc774\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc2a4\ud504\ub9c1\uc740 \ud2b8\ub79c\uc7ad\uc158 \uc2dc\uc791\uc2dc\uc5d0 \ucee4\ub125\uc158\uc758 \uc0ac\uc6a9\uc5ec\ubd80\uc640 \uc0c1\uad00\uc5c6\uc774 \ucee4\ub125\uc158\uc744 \ud655\ubcf4\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c readOnly \ud2b8\ub79c\uc7ad\uc158\uc774 \uc124\uc815\ub41c \uba54\uc11c\ub4dc\ub97c \uc0ac\uc6a9\ud558\ub354\ub77c\ub3c4 \ubbf8\ub9ac \ud655\ubcf4\ub41c \ucee4\ub125\uc158\uc744 \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 replica db\ub85c \uc694\uccad\uc744 \ud558\uc9c0 \uc54a\uace0 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4. "),(0,r.kt)("p",null,"TransactionSynchronizationManager.isCurrentTransactionReadOnly() \uba54\uc11c\ub4dc \ud638\ucd9c \uc2dc currentTransactionReadOnly\ub77c\ub294 ",(0,r.kt)("inlineCode",{parentName:"p"},"ThreadLocal<Boolean>"),"\uc5d0 \uc124\uc815\ub41c \uac12\uc744 \ubc18\ud658\ud558\ub294\ub370 readOnly \uc124\uc815\uc774 \ub418\uba74 \uc774 \uac12\uc744 true\ub85c \uc124\uc815\ud55c\ub2e4. \ud558\uc9c0\ub9cc determineCurrentLookupKey\ub97c \ud638\ucd9c\ud558\uc5ec key \uac12\uc744 \uac00\uc838\uc624\ub294 \ubd80\ubd84\ubcf4\ub2e4 \uc774\ud6c4\uc5d0 \uc124\uc815\ub418\uae30 \ub54c\ubb38\uc5d0 determineCurrentLookupKey \uba54\uc11c\ub4dc\uc5d0\uc11c \ud56d\uc0c1 DataSourceType.SOURCE\uac00 \ubc18\ud658\ub418\uc5b4 source db\ub85c \uc694\uccad\uc744 \ud55c\ub2e4. "),(0,r.kt)("p",null,"LazyConnectionDataSourceProxy\ub97c \uc124\uc815\ud558\ub294 \uacbd\uc6b0 \uc2e4\uc81c DataSource\ub97c \uc0ac\uc6a9\ud558\ub294 \uc2dc\uc810\uc5d0 \ucee4\ub125\uc158\uc744 \ud68d\ub4dd\ud574\uc11c \uc0ac\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uc124\uc815\ud55c\ub300\ub85c replica db\ub85c \uc870\ud68c \uc694\uccad\uc744 \ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="DataSourceConfiguration"',title:'"DataSourceConfiguration"'},'@Configuration\npublic class DataSourceConfiguration {\n\n @Bean\n @Qualifier(SOURCE_NAME)\n @ConfigurationProperties(prefix = "spring.datasource.source")\n public DataSource sourceDataSource() {\n return DataSourceBuilder.create().build();\n }\n\n @Bean\n @Qualifier(REPLICA_NAME)\n @ConfigurationProperties(prefix = "spring.datasource.replica")\n public DataSource replicaDataSource() {\n return DataSourceBuilder.create().build();\n }\n\n @Bean\n @Qualifier(ROUTING_NAME)\n public DataSource routingDataSource(\n @Qualifier(SOURCE_NAME) DataSource sourceDataSource,\n @Qualifier(REPLICA_NAME) DataSource replicaDataSource\n ) {\n return RoutingDataSource.from(Map.of(\n DataSourceType.SOURCE, sourceDataSource,\n DataSourceType.REPLICA, replicaDataSource\n ));\n }\n\n @Bean\n @Primary\n public DataSource dataSource(\n @Qualifier(ROUTING_NAME) DataSource routingDataSource\n ) {\n return new LazyConnectionDataSourceProxy(routingDataSource);\n }\n}\n')),(0,r.kt)("p",null,"\ucd5c\uc885\uc801\uc73c\ub85c DataSource \ube48\uc740 \ub2e4\uc74c\uacfc \uac19\uc740 \ud615\ud0dc\uac00 \ub41c\ub2e4. "),(0,r.kt)("mermaid",{value:"graph LR\n DSP[LazyConnectionDataSourceProxy] --\x3e RDS[RoutingDataSource]\n\tRDS --\x3e S[SourceDataSource]\n\tRDS --\x3e R[ReplicaDataSource]"}),(0,r.kt)("h3",{id:"\ub3d9\uc791-\ud655\uc778"},"\ub3d9\uc791 \ud655\uc778"),(0,r.kt)("p",null,"\uac04\ub2e8\ud558\uac8c \ud14c\uc2a4\ud2b8\ub97c \uc791\uc131\ud574\uc11c \uc124\uc815\ud55c\ub300\ub85c \ub3d9\uc791\uc774 \ub418\ub294\uc9c0 \ud655\uc778\ud574\ubcf4\uc558\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","save \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 ",(0,r.kt)("inlineCode",{parentName:"p"},"@Transactional"),", findById \uba54\uc11c\ub4dc\uc758 \uacbd\uc6b0 ",(0,r.kt)("inlineCode",{parentName:"p"},"@Transactional(readOnly = true)"),"\uac00 \uc124\uc815\ub418\uc5b4\uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub85c\uadf8\ub97c \ud1b5\ud574 save\uc758 \uacbd\uc6b0 source db\ub85c findById\uc758 \uacbd\uc6b0 replica db\ub85c \uc694\uccad\uc744 \ud558\ub294 \uac83\uc744 \uc54c \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java",metastring:'title="MemberServiceTest"',title:'"MemberServiceTest"'},'@SpringBootTest\nclass MemberServiceTest {\n\n @Autowired\n private MemberService memberService;\n\n @Test\n void \uc0ac\uc6a9\uc790\ub97c_\uc800\uc7a5\ud55c\ub2e4() {\n // RoutingDataSource log: readOnly = false\n memberService.save("bbiac");\n }\n\n @Test\n void \uc0ac\uc6a9\uc790\ub97c_\uc870\ud68c\ud55c\ub2e4() {\n // RoutingDataSource log: readOnly = true\n assertThatThrownBy(() -> memberService.findById(MAX_VALUE))\n .isInstanceOf(NoSuchElementException.class);\n }\n}\n')),(0,r.kt)("p",null,"DB\uc5d0\uc11c\ub294 \ud655\uc778\ud558\ub824\uba74 root \uacc4\uc815\uc73c\ub85c \uc811\uc18d\ud55c \ud6c4 general log\ub97c \ud65c\uc131\ud654 \uc2dc\ud0a8\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"SET GLOBAL log_output = 'table';\nSET GLOBAL general_log = 1;\n")),(0,r.kt)("p",null,"general log\ub97c \ud65c\uc131\ud654 \ud55c \ud6c4 \uc77d\uae30 \uc804\uc6a9 \uba54\uc11c\ub4dc\ub97c \uc2e4\ud589\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","server_id, \uc2e4\ud589\ud55c \ucffc\ub9ac\ubb38\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';\n\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n| user_host | thread_id | server_id | convert(argument using utf8) |\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |\n+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+\n")),(0,r.kt)("p",null,"\ud655\uc778 \ud6c4 general log\ub97c \ube44\ud65c\uc131\ud654 \ud55c \ud6c4 \ube44\ud65c\uc131\ud654 \ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sql"},"SET GLOBAL general_log = 0;\nSHOW VARIABLES LIKE '%general%';\n\n+------------------+---------------------------------+\n| Variable_name | Value |\n+------------------+---------------------------------+\n| general_log | OFF |\n| general_log_file | /var/lib/mysql/4b6b9db98290.log |\n+------------------+---------------------------------+\n")),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,"16\uc7a5 \ubcf5\uc81c, Real MySQL 8.0 - \ubc31\uc740\ube48, \uc774\uc131\uc6b1",(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.1/en/replication.html"},"Replication, MySQL Docs"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://huisam.tistory.com/entry/mysql-replication"},"MySql - Master Slave Replication \uad6c\uc870 \ub9cc\ub4e4\uc5b4\ubcf4\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://cheese10yun.github.io/spring-transaction/"},"Spring \ub808\ud50c\ub9ac\ucf00\uc774\uc158 \ud2b8\ub79c\uc7ad\uc158 \ucc98\ub9ac \ubc29\uc2dd"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/kwon37xi/replication-datasource"},"replication-datasource"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.linkedin.com/pulse/simplified-guide-mysql-replication-docker-compose-rakesh-shekhawat/"},"Simplified Guide to MySQL Replication with Docker Compose"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.daleseo.com/dockerfile/"},"Dockerfile\uc5d0\uc11c \uc790\uc8fc \uc4f0\uc774\ub294 \uba85\ub839\uc5b4"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.mysql.com/doc/refman/8.1/en/change-replication-source-to.html"},"CHANGE REPLICATION SOURCE TO Statement"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://kwonnam.pe.kr/wiki/springframework/lazyconnectiondatasourceproxy"},"LazyConnectionDataSourceProxy"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://hudi.blog/database-replication-with-springboot-and-mysql/"},"\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub808\ud50c\ub9ac\ucf00\uc774\uc158\uc744 \ud1b5\ud55c \ucffc\ub9ac \uc131\ub2a5 \uac1c\uc120 (feat. Mysql, SpringBoot)"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://chagokx2.tistory.com/100"},"\ubd80\ud558 \ubd84\uc0b0\uc744 \uc704\ud55c MySQL Replication \uad6c\uc131 \ubc0f \ucffc\ub9ac \uc694\uccad \ubd84\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.docker.com/get-started/08_using_compose/"},"Use Docker Compose, Docker")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f0978ee1.fc391fa7.js b/assets/js/f0978ee1.a0902758.js similarity index 59% rename from assets/js/f0978ee1.fc391fa7.js rename to assets/js/f0978ee1.a0902758.js index e9f949c90..22cb50b62 100644 --- a/assets/js/f0978ee1.fc391fa7.js +++ b/assets/js/f0978ee1.a0902758.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7740],{69366:e=>{e.exports=JSON.parse('{"label":"awt","permalink":"/tags/awt","allTagsPath":"/tags","count":2}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[7740],{69366:e=>{e.exports=JSON.parse('{"label":"awt","permalink":"/tags/awt","allTagsPath":"/tags","count":2,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/f156dfb9.5680e4f0.js b/assets/js/f156dfb9.ffae126d.js similarity index 88% rename from assets/js/f156dfb9.5680e4f0.js rename to assets/js/f156dfb9.ffae126d.js index 2d43704ec..04344b794 100644 --- a/assets/js/f156dfb9.5680e4f0.js +++ b/assets/js/f156dfb9.ffae126d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5602],{83311:e=>{e.exports=JSON.parse('{"label":"Time","permalink":"/tags/time","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5602],{83311:e=>{e.exports=JSON.parse('{"label":"Time","permalink":"/tags/time","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/f25de701.505cef98.js b/assets/js/f25de701.505cef98.js deleted file mode 100644 index 4fcd2dea4..000000000 --- a/assets/js/f25de701.505cef98.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2245],{3905:(t,e,a)=>{a.d(e,{Zo:()=>i,kt:()=>h});var n=a(67294);function r(t,e,a){return e in t?Object.defineProperty(t,e,{value:a,enumerable:!0,configurable:!0,writable:!0}):t[e]=a,t}function l(t,e){var a=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),a.push.apply(a,n)}return a}function o(t){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?l(Object(a),!0).forEach((function(e){r(t,e,a[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(a,e))}))}return t}function c(t,e){if(null==t)return{};var a,n,r=function(t,e){if(null==t)return{};var a,n,r={},l=Object.keys(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||(r[a]=t[a]);return r}(t,e);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(t);for(n=0;n<l.length;n++)a=l[n],e.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(t,a)&&(r[a]=t[a])}return r}var p=n.createContext({}),d=function(t){var e=n.useContext(p),a=e;return t&&(a="function"==typeof t?t(e):o(o({},e),t)),a},i=function(t){var e=d(t.components);return n.createElement(p.Provider,{value:e},t.children)},u={inlineCode:"code",wrapper:function(t){var e=t.children;return n.createElement(n.Fragment,{},e)}},s=n.forwardRef((function(t,e){var a=t.components,r=t.mdxType,l=t.originalType,p=t.parentName,i=c(t,["components","mdxType","originalType","parentName"]),s=d(a),h=r,m=s["".concat(p,".").concat(h)]||s[h]||u[h]||l;return a?n.createElement(m,o(o({ref:e},i),{},{components:a})):n.createElement(m,o({ref:e},i))}));function h(t,e){var a=arguments,r=e&&e.mdxType;if("string"==typeof t||r){var l=a.length,o=new Array(l);o[0]=s;var c={};for(var p in e)hasOwnProperty.call(e,p)&&(c[p]=e[p]);c.originalType=t,c.mdxType="string"==typeof t?t:r,o[1]=c;for(var d=2;d<l;d++)o[d]=a[d];return n.createElement.apply(null,o)}return n.createElement.apply(null,a)}s.displayName="MDXCreateElement"},87875:(t,e,a)=>{a.r(e),a.d(e,{assets:()=>p,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>c,toc:()=>d});var n=a(87462),r=(a(67294),a(3905));const l={title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"cloudwatch",tags:["cloudwatch","log","monitoring"]},o=void 0,c={permalink:"/cloudwatch",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",source:"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",description:"CloudWatch",date:"2023-08-17T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 17\uc77c",tags:[{label:"cloudwatch",permalink:"/tags/cloudwatch"},{label:"log",permalink:"/tags/log"},{label:"monitoring",permalink:"/tags/monitoring"}],readingTime:5.35,hasTruncateMarker:!1,authors:[],frontMatter:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"cloudwatch",tags:["cloudwatch","log","monitoring"]},prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",permalink:"/woowacourse-level3-retrospective"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",permalink:"/route-image-async-with-event"}},p={authorsImageUrls:[]},d=[{value:"CloudWatch",id:"cloudwatch",level:2},{value:"CloudWatch Metrics",id:"cloudwatch-metrics",level:2},{value:"CloudWatch Agent \uc124\uce58",id:"cloudwatch-agent-\uc124\uce58",level:2},{value:"IAM \uc5ed\ud560 \uc124\uc815",id:"iam-\uc5ed\ud560-\uc124\uc815",level:3},{value:"\uc124\uce58",id:"\uc124\uce58",level:3},{value:"Wizard",id:"wizard",level:3},{value:"\uc124\uc815 \ud30c\uc77c \uc801\uc6a9",id:"\uc124\uc815-\ud30c\uc77c-\uc801\uc6a9",level:3},{value:"types.db: no such file or directory \uc5d0\ub7ec",id:"typesdb-no-such-file-or-directory-\uc5d0\ub7ec",level:3},{value:"\uc9c0\ud45c \ud655\uc778",id:"\uc9c0\ud45c-\ud655\uc778",level:3},{value:"\ub85c\uadf8",id:"\ub85c\uadf8",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],i={toc:d};function u(t){let{components:e,...l}=t;return(0,r.kt)("wrapper",(0,n.Z)({},i,l,{components:e,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"cloudwatch"},"CloudWatch"),(0,r.kt)("p",null,"AWS \ub9ac\uc18c\uc2a4\uc640 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc9c0\ud45c\uc640 \ub85c\uadf8\uc5d0 \ub300\ud55c \ubaa8\ub2c8\ud130\ub9c1\uc744 \uc81c\uacf5\ud558\ub294 \uc11c\ube44\uc2a4\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc9c0\ud45c\ub97c \uac10\uc2dc\ud558\uc5ec \uc54c\ub9bc\uc744 \ubcf4\ub0b4\ub294 \uae30\ub2a5\ub3c4 \uc81c\uacf5\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ud504\ub9ac\ud2f0\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \ub300\uc2dc\ubcf4\ub4dc\ub2f9 3$/M \uc758 \ube44\uc6a9\uc774 \uccad\uad6c\ub418\uace0, \uc9c0\ud45c\ub098 \ub85c\uadf8\uc758 \uc591\uc5d0 \ub530\ub77c \ube44\uc6a9\uc774 \ucd94\uac00\uc801\uc73c\ub85c \uccad\uad6c\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc694\uae08 \uc815\ubcf4\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc815\ubcf4\ub294 ",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/cloudwatch/pricing/"},"\ub2e4\uc74c \ub9c1\ud06c"),"\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("h2",{id:"cloudwatch-metrics"},"CloudWatch Metrics"),(0,r.kt)("p",null,"\uae30\ubcf8\uc801\uc73c\ub85c 5\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc218\uc9d1\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc138\ubd80 \ubaa8\ub2c8\ud130\ub9c1(Detailed Monitoring)\uc744 \ud65c\uc131\ud654\ud558\uba74 1\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\ub97c \uc218\uc9d1\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub300\uc2dc\ubcf4\ub4dc\uc5d0\uc11c InstanceId\ub85c \uac80\uc0c9\ud558\uc5ec \uc218\uc9d1\ub41c \uc9c0\ud45c\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch1.png",src:a(86344).Z,width:"3214",height:"1636"})),(0,r.kt)("p",null,"CPUUtilization, NetworkIn, NetworkOut\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 \uc9c0\ud45c\ub97c \uc81c\uacf5\ud558\uace0, \uba54\ubaa8\ub9ac, \ub514\uc2a4\ud06c \uacf5\uac04\uacfc \uac19\uc740 \uc9c0\ud45c\ub97c \ud655\uc778\ud558\ub824\uba74 \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\ub97c \uc124\uc815\ud574\uc57c \ud55c\ub2e4."),(0,r.kt)("h2",{id:"cloudwatch-agent-\uc124\uce58"},"CloudWatch Agent \uc124\uce58"),(0,r.kt)("p",null,"CloudWatch Agent \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\uc640 \ub85c\uadf8\ub97c \uc218\uc9d1\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("h3",{id:"iam-\uc5ed\ud560-\uc124\uc815"},"IAM \uc5ed\ud560 \uc124\uc815"),(0,r.kt)("p",null,"\uae30\ubcf8\uc801\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4\uac00 CloudWatchAgentServerPolicy\uc5d0 \ub300\ud55c \uad8c\ud55c\uc774 \uc788\uc5b4\uc57c \ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","IAM \u2192 \uc5ed\ud560\uc5d0\uc11c \uc5ed\ud560 \uc0dd\uc131\uc744 \ud074\ub9ad\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch2.png",src:a(35939).Z,width:"2614",height:"1602"})),(0,r.kt)("p",null,"CloudWatchAgentServerPolicy \uad8c\ud55c \uc815\ucc45\uc744 \uc120\ud0dd\ud558\uace0, \uc801\ub2f9\ud55c \uc5ed\ud560 \uc774\ub984\uc744 \uc785\ub825\ud574\uc11c \uc5ed\ud560\uc744 \uc0dd\uc131\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch3.png",src:a(5001).Z,width:"2650",height:"1616"})),(0,r.kt)("p",null,"EC2 \uc778\uc2a4\ud134\uc2a4 \ubaa9\ub85d\uc73c\ub85c \ub4e4\uc5b4\uac00\uc11c, CloudWatch Agent\ub97c \uc124\uce58\ud560 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud074\ub9ad\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc5d0\uc11c \uc774\uc804\uc5d0 \uc0dd\uc131\ud55c \uc5ed\ud560\uc744 \uc9c0\uc815\ud55c\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch4.png",src:a(55693).Z,width:"1764",height:"800"})),(0,r.kt)("h3",{id:"\uc124\uce58"},"\uc124\uce58"),(0,r.kt)("p",null,"\ud658\uacbd\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4. "),(0,r.kt)("p",null,"OS: ubuntu 22.04",(0,r.kt)("br",{parentName:"p"}),"\n","\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small (ARM64) "),(0,r.kt)("p",null,"\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uce58\ud55c\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb\nsudo dpkg -i -E ./amazon-cloudwatch-agent.deb\n")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html"},"\uc0ac\uc6a9 \uc124\uba85\uc11c"),"\uc5d0 \uac01 \uc778\uc2a4\ud134\uc2a4 \uc720\ud615\ub9c8\ub2e4 \ub2e4\uc6b4\ub85c\ub4dc \ub9c1\ud06c\uac00 \uc790\uc138\ud558\uac8c \uc548\ub0b4\ub418\uc5b4 \uc788\ub2e4."),(0,r.kt)("h3",{id:"wizard"},"Wizard"),(0,r.kt)("p",null,"CloudWatch Wizard\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uc124\uc815 \ud30c\uc77c \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub85c\uadf8\ub97c \uc218\uc9d1\ud558\ub3c4\ub85d \uc124\uc815\ud558\ub294 \uacbd\uc6b0 Wizard \uc2e4\ud589 \uba85\ub839\uc5b4 \uc785\ub825 \uc804 log \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \ubcf5\uc0ac\ud574\ub450\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec Wizard\ub97c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard\n")),(0,r.kt)("p",null,"\uc124\uc815\uc744 \uc9c4\ud589\ud558\ub2e4 \ubcf4\uba74 \uc124\uc815 \ud30c\uc77c\uc774 \uc5b4\ub5bb\uac8c \uad6c\uc131\ub420\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub85c\uadf8\ub97c \ucd94\uac00\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \uc785\ub825\ucc3d\uc774 \ub098\uc624\uba74 \uc900\ube44\ud574\ub480\ub358 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \uc785\ub825\ud55c\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch5.png",src:a(41733).Z,width:"2320",height:"1328"})),(0,r.kt)("p",null,"\uc911\uac04\uc5d0 SSM parameter store\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \uc800\uc7a5\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"Do you want to store the config in the SSM parameter store?\n1. yes\n2. no\n")),(0,r.kt)("p",null,"\ucd94\uac00\uc801\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 2\ubc88\uc744 \uc120\ud0dd\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Parameter Store \uad00\ub9ac\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uc758 ",(0,r.kt)("a",{parentName:"p",href:"https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/"},"\ubb38\uc11c"),"\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac70 \uac19\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc124\uc815\uc774 \uc644\ub8cc\ub418\uba74 ",(0,r.kt)("inlineCode",{parentName:"p"},"/opt/aws/amazon-cloudwatch-agent/bin/config.json")," \uc5d0 \uc124\uc815\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc774 \uc800\uc7a5\ub41c\ub2e4. "),(0,r.kt)("h3",{id:"\uc124\uc815-\ud30c\uc77c-\uc801\uc6a9"},"\uc124\uc815 \ud30c\uc77c \uc801\uc6a9"),(0,r.kt)("p",null,"\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uc815\ud30c\uc77c\uc744 \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","file \ub4a4\uc5d0\ub294 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub300\ud55c \uc808\ub300\uacbd\ub85c(\uc544\ub798 \uba85\ub839\uc5b4 \uae30\uc900 \uae30\ubcf8 \uc0dd\uc131 \uc704\uce58)\ub97c \uc785\ub825\ud558\uba74 \ub41c\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json\n")),(0,r.kt)("h3",{id:"typesdb-no-such-file-or-directory-\uc5d0\ub7ec"},"types.db: no such file or directory \uc5d0\ub7ec"),(0,r.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc740 \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 types.db \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory\n")),(0,r.kt)("p",null,"types.db \ud30c\uc77c \uc0dd\uc131"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"sudo mkdir /usr/share/collectd\nsudo touch /usr/share/collectd/types.db\n")),(0,r.kt)("h3",{id:"\uc9c0\ud45c-\ud655\uc778"},"\uc9c0\ud45c \ud655\uc778"),(0,r.kt)("p",null,"CloudWatch Metrics\uc5d0 \uac00\ubcf4\uba74 CWAgent\ub77c\ub294 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\uac00 \ucd94\uac00\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. "),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch6.png",src:a(40721).Z,width:"2638",height:"708"})),(0,r.kt)("p",null,"\ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ucd94\uac00\ud558\uc5ec \uc9c0\ud45c\uc5d0 \ub300\ud55c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json"},'{\n "metrics": {\n "namespace": "2023-hello-world",\n ......\n },\n} \n')),(0,r.kt)("h3",{id:"\ub85c\uadf8"},"\ub85c\uadf8"),(0,r.kt)("p",null,"CloudWatch \u2192 \ub85c\uadf8 \uadf8\ub8f9\uc73c\ub85c \uac00\uba74 Wizard\ub85c \ucd94\uac00\ud55c \ub85c\uadf8\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"./cloudwatch7.png",src:a(95994).Z,width:"2792",height:"1652"})),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html"},"CloudWatch\ub780 \ubb34\uc5c7\uc785\ub2c8\uae4c?"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://aws.amazon.com/ko/cloudwatch/pricing/"},"Amazon CloudWatch \uc694\uae08"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html"},"Linux \uc778\uc2a4\ud134\uc2a4 \uc9c0\ud45c"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html"},"\uc11c\ubc84\uc5d0 CloudWatch \uc5d0\uc774\uc804\ud2b8 \uc124\uce58 \ubc0f \uc2e4\ud589"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/"},"CloudWatch Agent\ub97c Parameter Store\uc5d0\uc11c \uad00\ub9ac\ud574 \ubcf4\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html"},"CloudWatch\uc5d0\uc774\uc804\ud2b8 \uad6c\uc131 \ud30c\uc77c")))}u.isMDXComponent=!0},86344:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch1-859296155df6c20d0846f1388022a86c.png"},35939:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch2-ca9c26868dec08ea7133e2774f49798a.png"},5001:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch3-da10422b87e1901286b6d3e85e2c01cc.png"},55693:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch4-1e7eddc7e8dd890ac18352e900df8e07.png"},41733:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch5-67d1bd59d4552f4fe481452eddc78a5e.png"},40721:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch6-06ead809f7510938baee41505bc72b97.png"},95994:(t,e,a)=>{a.d(e,{Z:()=>n});const n=a.p+"assets/images/cloudwatch7-a86dfc0db307ddf7d1660d2b9e419c96.png"}}]); \ No newline at end of file diff --git a/assets/js/f25de701.7bd01fad.js b/assets/js/f25de701.7bd01fad.js new file mode 100644 index 000000000..f5ff61f32 --- /dev/null +++ b/assets/js/f25de701.7bd01fad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2245],{45414:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var a=n(85893),c=n(3905);const r={title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"cloudwatch",tags:["cloudwatch","log","monitoring"]},s=void 0,l={permalink:"/cloudwatch",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",source:"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",description:"CloudWatch",date:"2023-08-17T00:00:00.000Z",formattedDate:"2023\ub144 8\uc6d4 17\uc77c",tags:[{label:"cloudwatch",permalink:"/tags/cloudwatch"},{label:"log",permalink:"/tags/log"},{label:"monitoring",permalink:"/tags/monitoring"}],readingTime:5.35,hasTruncateMarker:!1,authors:[],frontMatter:{title:"CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131",slug:"cloudwatch",tags:["cloudwatch","log","monitoring"]},unlisted:!1,prevItem:{title:"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 3 \ud68c\uace0",permalink:"/woowacourse-level3-retrospective"},nextItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac",permalink:"/route-image-async-with-event"}},o={authorsImageUrls:[]},d=[{value:"CloudWatch",id:"cloudwatch",level:2},{value:"CloudWatch Metrics",id:"cloudwatch-metrics",level:2},{value:"CloudWatch Agent \uc124\uce58",id:"cloudwatch-agent-\uc124\uce58",level:2},{value:"IAM \uc5ed\ud560 \uc124\uc815",id:"iam-\uc5ed\ud560-\uc124\uc815",level:3},{value:"\uc124\uce58",id:"\uc124\uce58",level:3},{value:"Wizard",id:"wizard",level:3},{value:"\uc124\uc815 \ud30c\uc77c \uc801\uc6a9",id:"\uc124\uc815-\ud30c\uc77c-\uc801\uc6a9",level:3},{value:"types.db: no such file or directory \uc5d0\ub7ec",id:"typesdb-no-such-file-or-directory-\uc5d0\ub7ec",level:3},{value:"\uc9c0\ud45c \ud655\uc778",id:"\uc9c0\ud45c-\ud655\uc778",level:3},{value:"\ub85c\uadf8",id:"\ub85c\uadf8",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function i(e){const t={a:"a",br:"br",code:"code",h2:"h2",h3:"h3",img:"img",p:"p",pre:"pre",...(0,c.ah)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"cloudwatch",children:"CloudWatch"}),"\n",(0,a.jsxs)(t.p,{children:["AWS \ub9ac\uc18c\uc2a4\uc640 \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc758 \uc9c0\ud45c\uc640 \ub85c\uadf8\uc5d0 \ub300\ud55c \ubaa8\ub2c8\ud130\ub9c1\uc744 \uc81c\uacf5\ud558\ub294 \uc11c\ube44\uc2a4\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc9c0\ud45c\ub97c \uac10\uc2dc\ud558\uc5ec \uc54c\ub9bc\uc744 \ubcf4\ub0b4\ub294 \uae30\ub2a5\ub3c4 \uc81c\uacf5\ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\ud504\ub9ac\ud2f0\uc5b4\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 \ub300\uc2dc\ubcf4\ub4dc\ub2f9 3$/M \uc758 \ube44\uc6a9\uc774 \uccad\uad6c\ub418\uace0, \uc9c0\ud45c\ub098 \ub85c\uadf8\uc758 \uc591\uc5d0 \ub530\ub77c \ube44\uc6a9\uc774 \ucd94\uac00\uc801\uc73c\ub85c \uccad\uad6c\ub41c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc694\uae08 \uc815\ubcf4\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \uc815\ubcf4\ub294 ",(0,a.jsx)(t.a,{href:"https://aws.amazon.com/ko/cloudwatch/pricing/",children:"\ub2e4\uc74c \ub9c1\ud06c"}),"\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(t.h2,{id:"cloudwatch-metrics",children:"CloudWatch Metrics"}),"\n",(0,a.jsxs)(t.p,{children:["\uae30\ubcf8\uc801\uc73c\ub85c 5\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\uc5d0 \ub300\ud55c \uc815\ubcf4\uac00 \uc218\uc9d1\ub41c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc138\ubd80 \ubaa8\ub2c8\ud130\ub9c1(Detailed Monitoring)\uc744 \ud65c\uc131\ud654\ud558\uba74 1\ubd84\ub9c8\ub2e4 \uc9c0\ud45c\ub97c \uc218\uc9d1\ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\ub300\uc2dc\ubcf4\ub4dc\uc5d0\uc11c InstanceId\ub85c \uac80\uc0c9\ud558\uc5ec \uc218\uc9d1\ub41c \uc9c0\ud45c\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch1.png",src:n(86344).Z+"",width:"3214",height:"1636"})}),"\n",(0,a.jsx)(t.p,{children:"CPUUtilization, NetworkIn, NetworkOut\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 \uc9c0\ud45c\ub97c \uc81c\uacf5\ud558\uace0, \uba54\ubaa8\ub9ac, \ub514\uc2a4\ud06c \uacf5\uac04\uacfc \uac19\uc740 \uc9c0\ud45c\ub97c \ud655\uc778\ud558\ub824\uba74 \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\ub97c \uc124\uc815\ud574\uc57c \ud55c\ub2e4."}),"\n",(0,a.jsx)(t.h2,{id:"cloudwatch-agent-\uc124\uce58",children:"CloudWatch Agent \uc124\uce58"}),"\n",(0,a.jsx)(t.p,{children:"CloudWatch Agent \uc0ac\uc6a9\uc790 \uc9c0\uc815 \uc9c0\ud45c\uc640 \ub85c\uadf8\ub97c \uc218\uc9d1\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.h3,{id:"iam-\uc5ed\ud560-\uc124\uc815",children:"IAM \uc5ed\ud560 \uc124\uc815"}),"\n",(0,a.jsxs)(t.p,{children:["\uae30\ubcf8\uc801\uc73c\ub85c EC2 \uc778\uc2a4\ud134\uc2a4\uac00 CloudWatchAgentServerPolicy\uc5d0 \ub300\ud55c \uad8c\ud55c\uc774 \uc788\uc5b4\uc57c \ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","IAM \u2192 \uc5ed\ud560\uc5d0\uc11c \uc5ed\ud560 \uc0dd\uc131\uc744 \ud074\ub9ad\ud55c\ub2e4."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch2.png",src:n(35939).Z+"",width:"2614",height:"1602"})}),"\n",(0,a.jsx)(t.p,{children:"CloudWatchAgentServerPolicy \uad8c\ud55c \uc815\ucc45\uc744 \uc120\ud0dd\ud558\uace0, \uc801\ub2f9\ud55c \uc5ed\ud560 \uc774\ub984\uc744 \uc785\ub825\ud574\uc11c \uc5ed\ud560\uc744 \uc0dd\uc131\ud55c\ub2e4."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch3.png",src:n(5001).Z+"",width:"2650",height:"1616"})}),"\n",(0,a.jsxs)(t.p,{children:["EC2 \uc778\uc2a4\ud134\uc2a4 \ubaa9\ub85d\uc73c\ub85c \ub4e4\uc5b4\uac00\uc11c, CloudWatch Agent\ub97c \uc124\uce58\ud560 EC2 \uc778\uc2a4\ud134\uc2a4\ub97c \ud074\ub9ad\ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc791\uc5c5 \u2192 \ubcf4\uc548 \u2192 IAM \uc5ed\ud560 \uc218\uc815\uc5d0\uc11c \uc774\uc804\uc5d0 \uc0dd\uc131\ud55c \uc5ed\ud560\uc744 \uc9c0\uc815\ud55c\ub2e4."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch4.png",src:n(55693).Z+"",width:"1764",height:"800"})}),"\n",(0,a.jsx)(t.h3,{id:"\uc124\uce58",children:"\uc124\uce58"}),"\n",(0,a.jsx)(t.p,{children:"\ud658\uacbd\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,a.jsxs)(t.p,{children:["OS: ubuntu 22.04",(0,a.jsx)(t.br,{}),"\n","\uc778\uc2a4\ud134\uc2a4 \uc720\ud615: t4g.small (ARM64)"]}),"\n",(0,a.jsx)(t.p,{children:"\uc544\ub798 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uce58\ud55c\ub2e4."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb\nsudo dpkg -i -E ./amazon-cloudwatch-agent.deb\n"})}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html",children:"\uc0ac\uc6a9 \uc124\uba85\uc11c"}),"\uc5d0 \uac01 \uc778\uc2a4\ud134\uc2a4 \uc720\ud615\ub9c8\ub2e4 \ub2e4\uc6b4\ub85c\ub4dc \ub9c1\ud06c\uac00 \uc790\uc138\ud558\uac8c \uc548\ub0b4\ub418\uc5b4 \uc788\ub2e4."]}),"\n",(0,a.jsx)(t.h3,{id:"wizard",children:"Wizard"}),"\n",(0,a.jsxs)(t.p,{children:["CloudWatch Wizard\ub97c \uc0ac\uc6a9\ud558\uba74 \uac04\ub2e8\ud558\uac8c \uc124\uc815 \ud30c\uc77c \uc0dd\uc131\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\ub85c\uadf8\ub97c \uc218\uc9d1\ud558\ub3c4\ub85d \uc124\uc815\ud558\ub294 \uacbd\uc6b0 Wizard \uc2e4\ud589 \uba85\ub839\uc5b4 \uc785\ub825 \uc804 log \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \ubcf5\uc0ac\ud574\ub450\ub294 \uac83\uc774 \uc88b\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec Wizard\ub97c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard\n"})}),"\n",(0,a.jsxs)(t.p,{children:["\uc124\uc815\uc744 \uc9c4\ud589\ud558\ub2e4 \ubcf4\uba74 \uc124\uc815 \ud30c\uc77c\uc774 \uc5b4\ub5bb\uac8c \uad6c\uc131\ub420\uc9c0 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\ub85c\uadf8\ub97c \ucd94\uac00\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \uc785\ub825\ucc3d\uc774 \ub098\uc624\uba74 \uc900\ube44\ud574\ub480\ub358 \ub85c\uadf8 \ud30c\uc77c\uc758 \uc808\ub300 \uacbd\ub85c\ub97c \uc785\ub825\ud55c\ub2e4."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch5.png",src:n(41733).Z+"",width:"2320",height:"1328"})}),"\n",(0,a.jsx)(t.p,{children:"\uc911\uac04\uc5d0 SSM parameter store\uc5d0 \uc124\uc815 \ud30c\uc77c\uc744 \uc800\uc7a5\ud560 \uac83\uc774\ub0d0\uace0 \ubb3c\uc5b4\ubcf4\ub294 \ucc3d\uc774 \ub098\uc628\ub2e4."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"Do you want to store the config in the SSM parameter store?\n1. yes\n2. no\n"})}),"\n",(0,a.jsxs)(t.p,{children:["\ucd94\uac00\uc801\uc73c\ub85c \uc124\uc815\ud558\uc9c0 \uc54a\ub294 \uacbd\uc6b0 2\ubc88\uc744 \uc120\ud0dd\ud55c\ub2e4.",(0,a.jsx)(t.br,{}),"\n","Parameter Store \uad00\ub9ac\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc740 \ub2e4\uc74c\uc758 ",(0,a.jsx)(t.a,{href:"https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/",children:"\ubb38\uc11c"}),"\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac70 \uac19\ub2e4.",(0,a.jsx)(t.br,{}),"\n","\uc124\uc815\uc774 \uc644\ub8cc\ub418\uba74 ",(0,a.jsx)(t.code,{children:"/opt/aws/amazon-cloudwatch-agent/bin/config.json"})," \uc5d0 \uc124\uc815\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc774 \uc800\uc7a5\ub41c\ub2e4."]}),"\n",(0,a.jsx)(t.h3,{id:"\uc124\uc815-\ud30c\uc77c-\uc801\uc6a9",children:"\uc124\uc815 \ud30c\uc77c \uc801\uc6a9"}),"\n",(0,a.jsxs)(t.p,{children:["\uc544\ub798\uc758 \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc5ec \uc124\uc815\ud30c\uc77c\uc744 \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4.",(0,a.jsx)(t.br,{}),"\n","file \ub4a4\uc5d0\ub294 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub300\ud55c \uc808\ub300\uacbd\ub85c(\uc544\ub798 \uba85\ub839\uc5b4 \uae30\uc900 \uae30\ubcf8 \uc0dd\uc131 \uc704\uce58)\ub97c \uc785\ub825\ud558\uba74 \ub41c\ub2e4."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json\n"})}),"\n",(0,a.jsx)(t.h3,{id:"typesdb-no-such-file-or-directory-\uc5d0\ub7ec",children:"types.db: no such file or directory \uc5d0\ub7ec"}),"\n",(0,a.jsx)(t.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc740 \uc5d0\ub7ec\uac00 \ubc1c\uc0dd\ud55c\ub2e4\uba74 types.db \ud30c\uc77c\uc744 \uc0dd\uc131\ud574\uc11c \ubb38\uc81c\ub97c \ud574\uacb0\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory\n"})}),"\n",(0,a.jsx)(t.p,{children:"types.db \ud30c\uc77c \uc0dd\uc131"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"sudo mkdir /usr/share/collectd\nsudo touch /usr/share/collectd/types.db\n"})}),"\n",(0,a.jsx)(t.h3,{id:"\uc9c0\ud45c-\ud655\uc778",children:"\uc9c0\ud45c \ud655\uc778"}),"\n",(0,a.jsx)(t.p,{children:"CloudWatch Metrics\uc5d0 \uac00\ubcf4\uba74 CWAgent\ub77c\ub294 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\uac00 \ucd94\uac00\ub41c \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch6.png",src:n(40721).Z+"",width:"2638",height:"708"})}),"\n",(0,a.jsx)(t.p,{children:"\ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815 \ud30c\uc77c\uc5d0 \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ucd94\uac00\ud558\uc5ec \uc9c0\ud45c\uc5d0 \ub300\ud55c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub97c \ubcc0\uacbd\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-json",children:'{\n "metrics": {\n "namespace": "2023-hello-world",\n ......\n },\n} \n'})}),"\n",(0,a.jsx)(t.h3,{id:"\ub85c\uadf8",children:"\ub85c\uadf8"}),"\n",(0,a.jsx)(t.p,{children:"CloudWatch \u2192 \ub85c\uadf8 \uadf8\ub8f9\uc73c\ub85c \uac00\uba74 Wizard\ub85c \ucd94\uac00\ud55c \ub85c\uadf8\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4."}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"./cloudwatch7.png",src:n(95994).Z+"",width:"2792",height:"1652"})}),"\n",(0,a.jsx)(t.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html",children:"CloudWatch\ub780 \ubb34\uc5c7\uc785\ub2c8\uae4c?"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://aws.amazon.com/ko/cloudwatch/pricing/",children:"Amazon CloudWatch \uc694\uae08"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html",children:"Linux \uc778\uc2a4\ud134\uc2a4 \uc9c0\ud45c"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html",children:"\uc11c\ubc84\uc5d0 CloudWatch \uc5d0\uc774\uc804\ud2b8 \uc124\uce58 \ubc0f \uc2e4\ud589"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/",children:"CloudWatch Agent\ub97c Parameter Store\uc5d0\uc11c \uad00\ub9ac\ud574 \ubcf4\uae30"}),(0,a.jsx)(t.br,{}),"\n",(0,a.jsx)(t.a,{href:"https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html",children:"CloudWatch\uc5d0\uc774\uc804\ud2b8 \uad6c\uc131 \ud30c\uc77c"})]})]})}function h(e={}){const{wrapper:t}={...(0,c.ah)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(i,{...e})}):i(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>d});var a=n(67294);function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function s(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){c(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function l(e,t){if(null==e)return{};var n,a,c=function(e,t){if(null==e)return{};var n,a,c={},r=Object.keys(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||(c[n]=e[n]);return c}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(c[n]=e[n])}return c}var o=a.createContext({}),d=function(e){var t=a.useContext(o),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},i={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,c=e.mdxType,r=e.originalType,o=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),u=d(n),p=c,g=u["".concat(o,".").concat(p)]||u[p]||i[p]||r;return n?a.createElement(g,s(s({ref:t},h),{},{components:n})):a.createElement(g,s({ref:t},h))}));h.displayName="MDXCreateElement"},86344:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch1-859296155df6c20d0846f1388022a86c.png"},35939:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch2-ca9c26868dec08ea7133e2774f49798a.png"},5001:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch3-da10422b87e1901286b6d3e85e2c01cc.png"},55693:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch4-1e7eddc7e8dd890ac18352e900df8e07.png"},41733:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch5-67d1bd59d4552f4fe481452eddc78a5e.png"},40721:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch6-06ead809f7510938baee41505bc72b97.png"},95994:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/cloudwatch7-a86dfc0db307ddf7d1660d2b9e419c96.png"}}]); \ No newline at end of file diff --git a/assets/js/f3493919.36beefc1.js b/assets/js/f3493919.36beefc1.js new file mode 100644 index 000000000..4bbb45468 --- /dev/null +++ b/assets/js/f3493919.36beefc1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8476],{30169:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>c,toc:()=>a});var r=t(85893),i=t(3905);const l={title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",slug:"/book/getting-out-of-the-box",last_update:{date:"2023/04/08"},tags:["book"]},o=void 0,c={id:"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",description:"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac",source:"@site/docs/\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30.mdx",sourceDirName:"\ub3c4\uc11c",slug:"/book/getting-out-of-the-box",permalink:"/docs/book/getting-out-of-the-box",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30.mdx",tags:[{label:"book",permalink:"/docs/tags/book"}],version:"current",lastUpdatedAt:1680912e3,formattedLastUpdatedAt:"2023\ub144 4\uc6d4 8\uc77c",frontMatter:{title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",slug:"/book/getting-out-of-the-box",last_update:{date:"2023/04/08"},tags:["book"]},sidebar:"tutorialSidebar",previous:{title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",permalink:"/docs/database/query-execution"},next:{title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",permalink:"/docs/linux/swap"}},s={},a=[{value:"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac",id:"\ufe0f-\uc790\uae30\ubc30\ubc18\uc758-\uc6d0\ub9ac",level:3},{value:"\u274c \uc0c1\uc790 \uc548\uc5d0\uc11c \uc18c\uc6a9\uc5c6\ub294 \uc77c",id:"-\uc0c1\uc790-\uc548\uc5d0\uc11c-\uc18c\uc6a9\uc5c6\ub294-\uc77c",level:3},{value:"\ud83d\udcd6 \ud559\uc2b5\uc790\ub8cc",id:"-\ud559\uc2b5\uc790\ub8cc",level:3},{value:"\ud83c\udfc3 \uc2e4\ucc9c\ud558\uae30",id:"-\uc2e4\ucc9c\ud558\uae30",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function d(e){const n={h3:"h3",li:"li",ol:"ol",p:"p",...(0,i.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h3,{id:"\ufe0f-\uc790\uae30\ubc30\ubc18\uc758-\uc6d0\ub9ac",children:"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"\ub2e4\ub978 \uc0ac\ub78c\uc744 \uc704\ud574 \ub0b4\uac00 \ubb34\uc5c7\uc778\uac00 \ud574\uc57c\ub9cc \ud55c\ub2e4\ub294 \uc0dd\uac01\uacfc \ub290\ub08c\uc5d0 \ub300\ud574 \ubc18\ud558\ub294 \ud589\uc704\ub97c \uc790\uae30\ubc30\ubc18\uc774\ub77c\uace0 \ud55c\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"\ub0b4\uac00 \uc790\uae30\ubc30\ubc18\ud560 \ub54c, \ub098\ub294 \uc790\uae30\ubc30\ubc18\uc744 \uc815\ub2f9\ud654\uc2dc\ud0a4\ub294 \ubc29\uc2dd\uc73c\ub85c \uc138\uc0c1\uc744 \ubcf4\uae30 \uc2dc\uc791\ud55c\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"\uc790\uc2e0\uc744 \uc815\ub2f9\ud654\uc2dc\ud0a4\ub294 \ubc29\uc2dd\uc73c\ub85c \uc138\uc0c1\uc744 \ubcfc \ub54c, \uc0ac\uc2e4\uc744 \ubcf4\ub294 \ub098\uc758 \uc2dc\uac01\uc740 \uc65c\uace1\ub41c\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"\uc790\uae30\ubc30\ubc18\ud560 \ub54c, \ub098\ub294 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac00\uac8c \ub41c\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"\uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc5b4\ub5a4 \uc0c1\uc790\ub4e4\uc740 \ub098\uc758 \ud2b9\uc131\uc774 \ub418\uace0 \uc77c\uc0c1\uc801\uc73c\ub85c \ub098\ub294 \uadf8 \uc0c1\uc790\ub4e4\uc744 \uc9c0\ub2c8\uace0 \ub2e4\ub2cc\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"\ub0b4\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\uc74c\uc73c\ub85c \uc778\ud558\uc5ec, \ub098\ub294 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\ub3c4 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac00\ub3c4\ub85d \uc774\ub04c\uac8c \ub41c\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"\uc0c1\uc790 \uc548\uc5d0\uc11c \uc6b0\ub9ac\ub294 \uc11c\ub85c \uc798\ubabb \ub300\ud558\ub294 \uac83\uc744 \ubd80\ucd94\uae30\uace0 \uc0c1\ud638 \uc815\ub2f9\ud654\ub97c \uc5bb\uac8c \ub41c\ub2e4. \uc6b0\ub9ac\ub294 \uc11c\ub85c\uc5d0\uac8c \uc0c1\uc790 \uc548\uc5d0 \uba38\ubb3c\uae30 \uc704\ud55c \uc774\uc720\ub97c \uc8fc\ub3c4\ub85d \uacf5\ubaa8\ud55c\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"-\uc0c1\uc790-\uc548\uc5d0\uc11c-\uc18c\uc6a9\uc5c6\ub294-\uc77c",children:"\u274c \uc0c1\uc790 \uc548\uc5d0\uc11c \uc18c\uc6a9\uc5c6\ub294 \uc77c"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc744 \ubcc0\ud654\uc2dc\ud0a4\ub824\uace0 \ud558\ub294 \uac83"}),"\n",(0,r.jsx)(n.li,{children:'\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c "\ub9de\ucdb0\uc8fc\uae30" \uc704\ud574 \ucd5c\uc120\uc744 \ub2e4\ud558\uae30'}),"\n",(0,r.jsx)(n.li,{children:"\ub450\uace0 \ub5a0\ub098\uae30"}),"\n",(0,r.jsx)(n.li,{children:"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158"}),"\n",(0,r.jsx)(n.li,{children:"\uc0c8\ub85c\uc6b4 \uae30\uc220\uc774\ub098 \ud14c\ud06c\ub2c9 \ud65c\uc6a9\ud558\uae30"}),"\n",(0,r.jsx)(n.li,{children:"\ub098\uc758 \ud589\ub3d9\uc744 \ubcc0\ud654\uc2dc\ud0a4\ub294 \uac83"}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"-\ud559\uc2b5\uc790\ub8cc",children:"\ud83d\udcd6 \ud559\uc2b5\uc790\ub8cc"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:'\uc790\uae30\ubc30\ubc18\uc740 \uc790\uae30\uae30\ub9cc\uacfc "\uc0c1\uc790"\uc548\uc73c\ub85c \uc774\ub048\ub2e4.'}),"\n",(0,r.jsx)(n.li,{children:"\uc0c1\uc790 \uc548\uc5d0 \uc788\uc744 \ub54c, \ub2f9\uc2e0\uc740 \uacb0\uacfc(\uc131\uacfc)\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc5c6\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"\ub2f9\uc2e0\uc758 \uc601\ud5a5\ub825\uacfc \uc131\uacf5\uc758 \ud06c\uae30\ub294 \uc5bc\ub9c8\ub098 \uc0c1\uc790 \ubc16\uc5d0 \uc874\uc7ac\ud558\ub290\ub0d0\uc5d0 \ub2ec\ub824\uc788\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c \uc800\ud56d\ud558\ub294 \uac83\uc744 \uadf8\ub9cc\ub458 \ub54c \ub2f9\uc2e0\uc740 \uc0c1\uc790 \ubc16\uc5d0 \uc788\uac8c \ub41c\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"-\uc2e4\ucc9c\ud558\uae30",children:"\ud83c\udfc3 \uc2e4\ucc9c\ud558\uae30"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"\uc644\ubcbd\ud574\uc9c0\ub824\uace0 \ub178\ub825\ud558\uc9c0 \ub9d0\uace0, \uc9c0\uae08\ubcf4\ub2e4 \ub354 \uc88b\uc544\uc9c0\ub824\uace0 \ub178\ub825\ud558\ub77c."}),"\n",(0,r.jsx)(n.li,{children:"\uc544\uc9c1 \ud559\uc2b5\ub0b4\uc6a9\uc744 \uc54c\uc9c0 \ubabb\ud558\ub294 \uc0ac\ub78c\ub4e4\uc5d0\uac8c '\uc0c1\uc790'\ub098 \uae30\ud0c0 \ub2e8\uc5b4\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc9c0 \ub9c8\ub77c. \ub2e4\ub9cc \ub2f9\uc2e0 \uc790\uc2e0\uc758 \uc0b6\uc5d0\uc11c \uadf8 \uc6d0\ub9ac\ub4e4\uc744 \uc801\uc6a9\ud558\ub77c."}),"\n",(0,r.jsx)(n.li,{children:"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc758 \uc0c1\uc790\ub97c \ucc3e\uc9c0 \ub9d0\uace0, \uba3c\uc800 \ub2f9\uc2e0 \uc790\uc2e0\uc758 \uc0c1\uc790\ub97c \ucc3e\uc544\ub77c."}),"\n",(0,r.jsx)(n.li,{children:"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub2e4\uace0 \ud790\ub09c\ud558\uc9c0 \ub9d0\uace0, \ub2f9\uc2e0\uc774 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub3c4\ub85d \ub178\ub825\ud558\ub77c."}),"\n",(0,r.jsx)(n.li,{children:"\ub2f9\uc2e0\uc774 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub2e4\ub294 \uac83\uc744 \ubc1c\uacac\ud588\uc744 \ub54c \uc790\uc2e0\uc5d0 \ub300\ud574 \ud3ec\uae30\ud558\uc9c0 \ub9c8\ub77c. \uacc4\uc18d \ub178\ub825\ud558\ub77c."}),"\n",(0,r.jsx)(n.li,{children:"\ub2f9\uc2e0\uc774 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub2e4\ub294 \uac83\uc744 \ubd80\uc778\ud558\uc9c0 \ub9c8\ub77c. \uc0ac\uacfc\ud558\uace0, \uacc4\uc18d\ud574\uc11c \uc804\uc9c4\ud558\ub77c. \ubbf8\ub798\uc5d0 \ub2e4\ub978 \uc0ac\ub78c\uc5d0\uac8c \ub354 \ub3c4\uc6c0\uc774 \ub418\ub3c4\ub85d \ub178\ub825\ud558\ub77c."}),"\n",(0,r.jsx)(n.li,{children:"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc798\ubabb\ud558\uace0 \uc788\ub294 \uac83\uc5d0 \ucd08\uc810\uc744 \ub9de\ucd94\uc9c0 \ub9c8\ub77c. \uadf8\ub4e4\uc744 \ub3d5\uae30 \uc704\ud574 \ub2f9\uc2e0\uc774 \uc62c\ubc14\ub974\uac8c \ud589\ud560 \uc218 \uc788\ub294 \uc77c\uc5d0 \ucd08\uc810\uc744 \ub9de\ucdb0\ub77c."}),"\n",(0,r.jsx)(n.li,{children:"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \ub2f9\uc2e0\uc744 \ub3d5\uace0 \uc788\ub294\uc9c0\uc5d0 \ub300\ud574 \uc5fc\ub824\ud558\uc9c0 \ub9c8\ub77c. \ub2f9\uc2e0\uc774 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc744 \ub3d5\uace0 \uc788\ub294\uc9c0\uc5d0 \ub300\ud574 \uac71\uc815\ud558\ub77c."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsx)(n.p,{children:"\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c, \uc544\ube48\uc800\uc5f0\uad6c\uc18c"})]})}function u(e={}){const{wrapper:n}={...(0,i.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>a});var r=t(67294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function l(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?l(Object(t),!0).forEach((function(n){i(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):l(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function c(e,n){if(null==e)return{};var t,r,i=function(e,n){if(null==e)return{};var t,r,i={},l=Object.keys(e);for(r=0;r<l.length;r++)t=l[r],n.indexOf(t)>=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(r=0;r<l.length;r++)t=l[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var s=r.createContext({}),a=function(e){var n=r.useContext(s),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},d={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,l=e.originalType,s=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),h=a(t),p=i,j=h["".concat(s,".").concat(p)]||h[p]||d[p]||l;return t?r.createElement(j,o(o({ref:n},u),{},{components:t})):r.createElement(j,o({ref:n},u))}));u.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/f3493919.b7bbf831.js b/assets/js/f3493919.b7bbf831.js deleted file mode 100644 index 9e34ed37d..000000000 --- a/assets/js/f3493919.b7bbf831.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8476],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function i(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},u=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},s=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,u=i(e,["components","mdxType","originalType","parentName"]),s=c(r),d=o,k=s["".concat(p,".").concat(d)]||s[d]||m[d]||a;return r?n.createElement(k,l(l({ref:t},u),{},{components:r})):n.createElement(k,l({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,l=new Array(a);l[0]=s;var i={};for(var p in t)hasOwnProperty.call(t,p)&&(i[p]=t[p]);i.originalType=e,i.mdxType="string"==typeof e?e:o,l[1]=i;for(var c=2;c<a;c++)l[c]=r[c];return n.createElement.apply(null,l)}return n.createElement.apply(null,r)}s.displayName="MDXCreateElement"},88439:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>l,default:()=>m,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",slug:"/book/getting-out-of-the-box",last_update:{date:"2023/04/08"},tags:["book"]},l=void 0,i={unversionedId:"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",id:"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",description:"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac",source:"@site/docs/\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30.mdx",sourceDirName:"\ub3c4\uc11c",slug:"/book/getting-out-of-the-box",permalink:"/docs/book/getting-out-of-the-box",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30.mdx",tags:[{label:"book",permalink:"/docs/tags/book"}],version:"current",lastUpdatedAt:1680912e3,formattedLastUpdatedAt:"2023\ub144 4\uc6d4 8\uc77c",frontMatter:{title:"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30",slug:"/book/getting-out-of-the-box",last_update:{date:"2023/04/08"},tags:["book"]},sidebar:"tutorialSidebar",previous:{title:"\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870",permalink:"/docs/database/query-execution"},next:{title:"Swap \uba54\ubaa8\ub9ac \uc124\uc815",permalink:"/docs/linux/swap"}},p={},c=[{value:"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac",id:"\ufe0f-\uc790\uae30\ubc30\ubc18\uc758-\uc6d0\ub9ac",level:3},{value:"\u274c \uc0c1\uc790 \uc548\uc5d0\uc11c \uc18c\uc6a9\uc5c6\ub294 \uc77c",id:"-\uc0c1\uc790-\uc548\uc5d0\uc11c-\uc18c\uc6a9\uc5c6\ub294-\uc77c",level:3},{value:"\ud83d\udcd6 \ud559\uc2b5\uc790\ub8cc",id:"-\ud559\uc2b5\uc790\ub8cc",level:3},{value:"\ud83c\udfc3 \uc2e4\ucc9c\ud558\uae30",id:"-\uc2e4\ucc9c\ud558\uae30",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],u={toc:c};function m(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"\ufe0f-\uc790\uae30\ubc30\ubc18\uc758-\uc6d0\ub9ac"},"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"\ub2e4\ub978 \uc0ac\ub78c\uc744 \uc704\ud574 \ub0b4\uac00 \ubb34\uc5c7\uc778\uac00 \ud574\uc57c\ub9cc \ud55c\ub2e4\ub294 \uc0dd\uac01\uacfc \ub290\ub08c\uc5d0 \ub300\ud574 \ubc18\ud558\ub294 \ud589\uc704\ub97c \uc790\uae30\ubc30\ubc18\uc774\ub77c\uace0 \ud55c\ub2e4. "),(0,o.kt)("li",{parentName:"ol"},"\ub0b4\uac00 \uc790\uae30\ubc30\ubc18\ud560 \ub54c, \ub098\ub294 \uc790\uae30\ubc30\ubc18\uc744 \uc815\ub2f9\ud654\uc2dc\ud0a4\ub294 \ubc29\uc2dd\uc73c\ub85c \uc138\uc0c1\uc744 \ubcf4\uae30 \uc2dc\uc791\ud55c\ub2e4. "),(0,o.kt)("li",{parentName:"ol"},"\uc790\uc2e0\uc744 \uc815\ub2f9\ud654\uc2dc\ud0a4\ub294 \ubc29\uc2dd\uc73c\ub85c \uc138\uc0c1\uc744 \ubcfc \ub54c, \uc0ac\uc2e4\uc744 \ubcf4\ub294 \ub098\uc758 \uc2dc\uac01\uc740 \uc65c\uace1\ub41c\ub2e4. "),(0,o.kt)("li",{parentName:"ol"},"\uc790\uae30\ubc30\ubc18\ud560 \ub54c, \ub098\ub294 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac00\uac8c \ub41c\ub2e4. "),(0,o.kt)("li",{parentName:"ol"},"\uc2dc\uac04\uc774 \uc9c0\ub098\uba74\uc11c \uc5b4\ub5a4 \uc0c1\uc790\ub4e4\uc740 \ub098\uc758 \ud2b9\uc131\uc774 \ub418\uace0 \uc77c\uc0c1\uc801\uc73c\ub85c \ub098\ub294 \uadf8 \uc0c1\uc790\ub4e4\uc744 \uc9c0\ub2c8\uace0 \ub2e4\ub2cc\ub2e4."),(0,o.kt)("li",{parentName:"ol"},"\ub0b4\uac00 \uc0c1\uc790 \uc548\uc5d0 \uc788\uc74c\uc73c\ub85c \uc778\ud558\uc5ec, \ub098\ub294 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\ub3c4 \uc0c1\uc790 \uc548\uc5d0 \ub4e4\uc5b4\uac00\ub3c4\ub85d \uc774\ub04c\uac8c \ub41c\ub2e4. "),(0,o.kt)("li",{parentName:"ol"},"\uc0c1\uc790 \uc548\uc5d0\uc11c \uc6b0\ub9ac\ub294 \uc11c\ub85c \uc798\ubabb \ub300\ud558\ub294 \uac83\uc744 \ubd80\ucd94\uae30\uace0 \uc0c1\ud638 \uc815\ub2f9\ud654\ub97c \uc5bb\uac8c \ub41c\ub2e4. \uc6b0\ub9ac\ub294 \uc11c\ub85c\uc5d0\uac8c \uc0c1\uc790 \uc548\uc5d0 \uba38\ubb3c\uae30 \uc704\ud55c \uc774\uc720\ub97c \uc8fc\ub3c4\ub85d \uacf5\ubaa8\ud55c\ub2e4. ")),(0,o.kt)("h3",{id:"-\uc0c1\uc790-\uc548\uc5d0\uc11c-\uc18c\uc6a9\uc5c6\ub294-\uc77c"},"\u274c \uc0c1\uc790 \uc548\uc5d0\uc11c \uc18c\uc6a9\uc5c6\ub294 \uc77c"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc744 \ubcc0\ud654\uc2dc\ud0a4\ub824\uace0 \ud558\ub294 \uac83"),(0,o.kt)("li",{parentName:"ol"},'\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c "\ub9de\ucdb0\uc8fc\uae30" \uc704\ud574 \ucd5c\uc120\uc744 \ub2e4\ud558\uae30'),(0,o.kt)("li",{parentName:"ol"},"\ub450\uace0 \ub5a0\ub098\uae30"),(0,o.kt)("li",{parentName:"ol"},"\ucee4\ubba4\ub2c8\ucf00\uc774\uc158"),(0,o.kt)("li",{parentName:"ol"},"\uc0c8\ub85c\uc6b4 \uae30\uc220\uc774\ub098 \ud14c\ud06c\ub2c9 \ud65c\uc6a9\ud558\uae30"),(0,o.kt)("li",{parentName:"ol"},"\ub098\uc758 \ud589\ub3d9\uc744 \ubcc0\ud654\uc2dc\ud0a4\ub294 \uac83")),(0,o.kt)("h3",{id:"-\ud559\uc2b5\uc790\ub8cc"},"\ud83d\udcd6 \ud559\uc2b5\uc790\ub8cc"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},'\uc790\uae30\ubc30\ubc18\uc740 \uc790\uae30\uae30\ub9cc\uacfc "\uc0c1\uc790"\uc548\uc73c\ub85c \uc774\ub048\ub2e4. '),(0,o.kt)("li",{parentName:"ol"},"\uc0c1\uc790 \uc548\uc5d0 \uc788\uc744 \ub54c, \ub2f9\uc2e0\uc740 \uacb0\uacfc(\uc131\uacfc)\uc5d0 \uc9d1\uc911\ud560 \uc218 \uc5c6\ub2e4. "),(0,o.kt)("li",{parentName:"ol"},"\ub2f9\uc2e0\uc758 \uc601\ud5a5\ub825\uacfc \uc131\uacf5\uc758 \ud06c\uae30\ub294 \uc5bc\ub9c8\ub098 \uc0c1\uc790 \ubc16\uc5d0 \uc874\uc7ac\ud558\ub290\ub0d0\uc5d0 \ub2ec\ub824\uc788\ub2e4. "),(0,o.kt)("li",{parentName:"ol"},"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc5d0\uac8c \uc800\ud56d\ud558\ub294 \uac83\uc744 \uadf8\ub9cc\ub458 \ub54c \ub2f9\uc2e0\uc740 \uc0c1\uc790 \ubc16\uc5d0 \uc788\uac8c \ub41c\ub2e4. ")),(0,o.kt)("h3",{id:"-\uc2e4\ucc9c\ud558\uae30"},"\ud83c\udfc3 \uc2e4\ucc9c\ud558\uae30"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"\uc644\ubcbd\ud574\uc9c0\ub824\uace0 \ub178\ub825\ud558\uc9c0 \ub9d0\uace0, \uc9c0\uae08\ubcf4\ub2e4 \ub354 \uc88b\uc544\uc9c0\ub824\uace0 \ub178\ub825\ud558\ub77c. "),(0,o.kt)("li",{parentName:"ol"},"\uc544\uc9c1 \ud559\uc2b5\ub0b4\uc6a9\uc744 \uc54c\uc9c0 \ubabb\ud558\ub294 \uc0ac\ub78c\ub4e4\uc5d0\uac8c '\uc0c1\uc790'\ub098 \uae30\ud0c0 \ub2e8\uc5b4\ub4e4\uc744 \uc0ac\uc6a9\ud558\uc9c0 \ub9c8\ub77c. \ub2e4\ub9cc \ub2f9\uc2e0 \uc790\uc2e0\uc758 \uc0b6\uc5d0\uc11c \uadf8 \uc6d0\ub9ac\ub4e4\uc744 \uc801\uc6a9\ud558\ub77c."),(0,o.kt)("li",{parentName:"ol"},"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc758 \uc0c1\uc790\ub97c \ucc3e\uc9c0 \ub9d0\uace0, \uba3c\uc800 \ub2f9\uc2e0 \uc790\uc2e0\uc758 \uc0c1\uc790\ub97c \ucc3e\uc544\ub77c."),(0,o.kt)("li",{parentName:"ol"},"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub2e4\uace0 \ud790\ub09c\ud558\uc9c0 \ub9d0\uace0, \ub2f9\uc2e0\uc774 \uc0c1\uc790 \ubc16\uc5d0 \uc788\ub3c4\ub85d \ub178\ub825\ud558\ub77c."),(0,o.kt)("li",{parentName:"ol"},"\ub2f9\uc2e0\uc774 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub2e4\ub294 \uac83\uc744 \ubc1c\uacac\ud588\uc744 \ub54c \uc790\uc2e0\uc5d0 \ub300\ud574 \ud3ec\uae30\ud558\uc9c0 \ub9c8\ub77c. \uacc4\uc18d \ub178\ub825\ud558\ub77c."),(0,o.kt)("li",{parentName:"ol"},"\ub2f9\uc2e0\uc774 \uc0c1\uc790 \uc548\uc5d0 \uc788\ub2e4\ub294 \uac83\uc744 \ubd80\uc778\ud558\uc9c0 \ub9c8\ub77c. \uc0ac\uacfc\ud558\uace0, \uacc4\uc18d\ud574\uc11c \uc804\uc9c4\ud558\ub77c. \ubbf8\ub798\uc5d0 \ub2e4\ub978 \uc0ac\ub78c\uc5d0\uac8c \ub354 \ub3c4\uc6c0\uc774 \ub418\ub3c4\ub85d \ub178\ub825\ud558\ub77c."),(0,o.kt)("li",{parentName:"ol"},"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \uc798\ubabb\ud558\uace0 \uc788\ub294 \uac83\uc5d0 \ucd08\uc810\uc744 \ub9de\ucd94\uc9c0 \ub9c8\ub77c. \uadf8\ub4e4\uc744 \ub3d5\uae30 \uc704\ud574 \ub2f9\uc2e0\uc774 \uc62c\ubc14\ub974\uac8c \ud589\ud560 \uc218 \uc788\ub294 \uc77c\uc5d0 \ucd08\uc810\uc744 \ub9de\ucdb0\ub77c."),(0,o.kt)("li",{parentName:"ol"},"\ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc774 \ub2f9\uc2e0\uc744 \ub3d5\uace0 \uc788\ub294\uc9c0\uc5d0 \ub300\ud574 \uc5fc\ub824\ud558\uc9c0 \ub9c8\ub77c. \ub2f9\uc2e0\uc774 \ub2e4\ub978 \uc0ac\ub78c\ub4e4\uc744 \ub3d5\uace0 \uc788\ub294\uc9c0\uc5d0 \ub300\ud574 \uac71\uc815\ud558\ub77c. ")),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,"\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c, \uc544\ube48\uc800\uc5f0\uad6c\uc18c"))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f4c6e7e6.ae84b9cb.js b/assets/js/f4c6e7e6.fdbb534a.js similarity index 89% rename from assets/js/f4c6e7e6.ae84b9cb.js rename to assets/js/f4c6e7e6.fdbb534a.js index cc1942bfe..5cd5f0d81 100644 --- a/assets/js/f4c6e7e6.ae84b9cb.js +++ b/assets/js/f4c6e7e6.fdbb534a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[31],{77922:e=>{e.exports=JSON.parse('{"label":"book","permalink":"/docs/tags/book","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","title":"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","description":"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac","permalink":"/docs/book/getting-out-of-the-box"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[31],{77922:e=>{e.exports=JSON.parse('{"label":"book","permalink":"/docs/tags/book","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","title":"\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","description":"\u26a0\ufe0f \uc790\uae30\ubc30\ubc18\uc758 \uc6d0\ub9ac","permalink":"/docs/book/getting-out-of-the-box"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/f63a747b.189a7c8a.js b/assets/js/f63a747b.276c7afe.js similarity index 77% rename from assets/js/f63a747b.189a7c8a.js rename to assets/js/f63a747b.276c7afe.js index 909be3e23..548cb97c7 100644 --- a/assets/js/f63a747b.189a7c8a.js +++ b/assets/js/f63a747b.276c7afe.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5131],{81723:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5131],{81723:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/f6807fb4.be958d21.js b/assets/js/f6807fb4.f409010b.js similarity index 85% rename from assets/js/f6807fb4.be958d21.js rename to assets/js/f6807fb4.f409010b.js index f3ac50d95..d7a2bff40 100644 --- a/assets/js/f6807fb4.be958d21.js +++ b/assets/js/f6807fb4.f409010b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4788],{39836:e=>{e.exports=JSON.parse('{"label":"architecture","permalink":"/docs/tags/architecture","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","title":"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","description":"\uac1c\uc694","permalink":"/docs/architecture/virtical-slice-architecture"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[4788],{39836:e=>{e.exports=JSON.parse('{"label":"architecture","permalink":"/docs/tags/architecture","allTagsPath":"/docs/tags","count":1,"items":[{"id":"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","title":"\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","description":"\uac1c\uc694","permalink":"/docs/architecture/virtical-slice-architecture"}],"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/f7b9d2f4.46e8275d.js b/assets/js/f7b9d2f4.b710b8ae.js similarity index 77% rename from assets/js/f7b9d2f4.46e8275d.js rename to assets/js/f7b9d2f4.b710b8ae.js index 17a2710e4..afdf919e9 100644 --- a/assets/js/f7b9d2f4.46e8275d.js +++ b/assets/js/f7b9d2f4.b710b8ae.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2958],{53122:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[2958],{53122:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/f8409a7e.bddfd935.js b/assets/js/f8409a7e.bddfd935.js deleted file mode 100644 index d1421fbac..000000000 --- a/assets/js/f8409a7e.bddfd935.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3206],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},u=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},s={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),f=p(r),d=o,m=f["".concat(l,".").concat(d)]||f[d]||s[d]||i;return r?n.createElement(m,a(a({ref:t},u),{},{components:r})):n.createElement(m,a({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=f;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:o,a[1]=c;for(var p=2;p<i;p++)a[p]=r[p];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}f.displayName="MDXCreateElement"},69568:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>s,frontMatter:()=>i,metadata:()=>c,toc:()=>p});var n=r(87462),o=(r(67294),r(3905));const i={id:"intro",title:"\ubb38\uc11c",slug:"/"},a=void 0,c={unversionedId:"intro",id:"intro",title:"\ubb38\uc11c",description:"\ub9c8\uc74c\uc5d0 \ub4e0 \ud0a4\uc6cc\ub4dc \uc815\ub9ac",source:"@site/docs/intro.mdx",sourceDirName:".",slug:"/",permalink:"/docs/",draft:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/intro.mdx",tags:[],version:"current",lastUpdatedAt:1698935181,formattedLastUpdatedAt:"2023\ub144 11\uc6d4 2\uc77c",frontMatter:{id:"intro",title:"\ubb38\uc11c",slug:"/"},sidebar:"tutorialSidebar",previous:{title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",permalink:"/docs/nginx/static-file"},next:{title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",permalink:"/docs/etc/healthful-growth"}},l={},p=[],u={toc:p};function s(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"\ub9c8\uc74c\uc5d0 \ub4e0 \ud0a4\uc6cc\ub4dc \uc815\ub9ac"))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f8409a7e.dfd38fb7.js b/assets/js/f8409a7e.dfd38fb7.js new file mode 100644 index 000000000..93a14f8e5 --- /dev/null +++ b/assets/js/f8409a7e.dfd38fb7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[3206],{29325:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>s,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var n=r(85893),o=r(3905);const i={id:"intro",title:"\ubb38\uc11c",slug:"/"},c=void 0,a={id:"intro",title:"\ubb38\uc11c",description:"\ub9c8\uc74c\uc5d0 \ub4e0 \ud0a4\uc6cc\ub4dc \uc815\ub9ac",source:"@site/docs/intro.mdx",sourceDirName:".",slug:"/",permalink:"/docs/",draft:!1,unlisted:!1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/docs/intro.mdx",tags:[],version:"current",lastUpdatedAt:1699095400,formattedLastUpdatedAt:"2023\ub144 11\uc6d4 4\uc77c",frontMatter:{id:"intro",title:"\ubb38\uc11c",slug:"/"},sidebar:"tutorialSidebar",previous:{title:"\uc815\uc801 \ucee8\ud150\uce20 \uc81c\uacf5",permalink:"/docs/nginx/static-file"},next:{title:"\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30",permalink:"/docs/etc/healthful-growth"}},s={},l=[];function u(e){const t={p:"p",...(0,o.ah)(),...e.components};return(0,n.jsx)(t.p,{children:"\ub9c8\uc74c\uc5d0 \ub4e0 \ud0a4\uc6cc\ub4dc \uc815\ub9ac"})}function p(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},3905:(e,t,r)=>{r.d(t,{ah:()=>l});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?i(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function a(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},i=Object.keys(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n<i.length;n++)r=i[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},p=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=a(e,["components","mdxType","originalType","parentName"]),f=l(r),d=o,m=f["".concat(s,".").concat(d)]||f[d]||u[d]||i;return r?n.createElement(m,c(c({ref:t},p),{},{components:r})):n.createElement(m,c({ref:t},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/f87bdf62.b1ec672d.js b/assets/js/f87bdf62.b1ec672d.js new file mode 100644 index 000000000..61b349f17 --- /dev/null +++ b/assets/js/f87bdf62.b1ec672d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6750],{52449:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>c,metadata:()=>s,toc:()=>a});var r=n(85893),o=n(3905);const c={title:"\uc6f9\uc18c\ucf13",slug:"websocket",tags:["WebSocket"]},i=void 0,s={permalink:"/websocket",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-26-WebSocket.mdx",source:"@site/blog/2023-2/2023-06-26-WebSocket.mdx",title:"\uc6f9\uc18c\ucf13",description:"\uc6f9\uc18c\ucf13",date:"2023-06-26T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 26\uc77c",tags:[{label:"WebSocket",permalink:"/tags/web-socket"}],readingTime:4.165,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9\uc18c\ucf13",slug:"websocket",tags:["WebSocket"]},unlisted:!1,prevItem:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",permalink:"/java-spring-springboot"},nextItem:{title:"Docusaurus",permalink:"/docusaurus"}},l={authorsImageUrls:[]},a=[{value:"\uc6f9\uc18c\ucf13",id:"\uc6f9\uc18c\ucf13",level:3},{value:"\uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd",id:"\uc6f9\uc18c\ucf13-\ub4f1\uc7a5-\ubc30\uacbd",level:3},{value:"\uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791",id:"\uc6f9\uc18c\ucf13\uc758-\ub3d9\uc791",level:3},{value:"1. Upgrade \uc694\uccad",id:"1-upgrade-\uc694\uccad",level:3},{value:"2. Switching Protocols",id:"2-switching-protocols",level:3},{value:"3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc",id:"3-\ud1b5\uc2e0-\ud6c4-\uc885\ub8cc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}];function p(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",h3:"h3",li:"li",mermaid:"mermaid",p:"p",pre:"pre",ul:"ul",...(0,o.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.h3,{id:"\uc6f9\uc18c\ucf13",children:"\uc6f9\uc18c\ucf13"}),"\n",(0,r.jsxs)(t.p,{children:["\ub2e8\uc77c TCP \uc5f0\uacb0\uc744 \ud1b5\ud574 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ubc84 \uac04 \uc804\uc774\uc911 \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \uc9c0\uc6d0\ud558\ub294 \ud504\ub85c\ud1a0\ucf5c",(0,r.jsx)(t.br,{}),"\n","\uc6f9 \ud658\uacbd\uc5d0\uc11c \uc5f0\uc18d\ub41c \ub370\uc774\ud130\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.p,{children:"\uc6f9\uc18c\ucf13\uc740 HTTP\uc758 \ud3ec\ud2b8\ub97c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uace0 \uac01\uac01 \ud3ec\ud2b8 80\uacfc \ud3ec\ud2b8 443\uc744 \uc0ac\uc6a9\ud558\uc5ec HTTP(ws://) \ubc0f HTTPS(wss://)\ub85c \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ud55c\ub2e4."}),"\n",(0,r.jsx)(t.h3,{id:"\uc6f9\uc18c\ucf13-\ub4f1\uc7a5-\ubc30\uacbd",children:"\uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd"}),"\n",(0,r.jsxs)(t.p,{children:["\uc6f9\uc18c\ucf13\uc774 \ub4f1\uc7a5\ud558\uae30 \uc774\uc804, \uc2e4\uc2dc\uac04\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 Polling, Long polling, Streaming \uac19\uc740 \uae30\uc220\uc744 \uc0ac\uc6a9\ud588\uc5b4\uc57c \ud588\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub294 \uc2e4\uc2dc\uac04\uc131\uc774\ub098 \uc591\ubc29\ud5a5\uc131\uc744 \ub9cc\uc871\uc2dc\ud0a4\uc9c0 \ubabb\ud588\uace0, HTTP\ub97c \uc774\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uacfc\ub3c4\ud55c \uc624\ubc84\ud5e4\ub4dc\uac00 \ubc1c\uc0dd\ud588\ub2e4."]}),"\n",(0,r.jsxs)(t.admonition,{title:"polling, long polling, streaming",type:"note",children:[(0,r.jsx)(t.p,{children:"Polling: \uc8fc\uae30\uc801\uc73c\ub85c \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ubcf4\ub0b4 \uc218\uc2e0\ud560 \uc815\ubcf4\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubc29\ubc95"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\uc11c\ubc84\uc5d0\uc11c \ubcf4\ub0bc \ub0b4\uc6a9\uc774 \uc5c6\uc5b4\ub3c4 \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \uc54c \uc218 \uc5c6\ub2e4."}),"\n",(0,r.jsx)(t.li,{children:"\uacc4\uc18d\ud574\uc11c \uc694\uccad\uc744 \ubcf4\ub0b4 \ud655\uc778\uc744 \ud574\uc57c\ud558\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ubd88\ud544\uc694\ud55c \ubd80\ud558\ub97c \uc8fc\uc5b4\uc57c \ud55c\ub2e4."}),"\n"]}),(0,r.jsx)(t.p,{children:"Long Polling: \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc5d0 \ub300\ud574 \uc751\ub2f5\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uace0 \uc788\ub2e4\uac00 \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud588\uc744\ub54c \uc751\ub2f5\ud558\ub294 \ubc29\ubc95"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\ud3f4\ub9c1 \ubc29\uc2dd\ubcf4\ub2e4 \uc11c\ubc84\uc5d0 \uc801\uc740 \ubd80\ud558\ub97c \uc904 \uc218 \uc788\uc9c0\ub9cc, \uc694\uccad\uc758 \uc8fc\uae30\uac00 \uc9e7\uc73c\uba74 \ud3f4\ub9c1\uacfc \ucc28\uc774\uac00 \uc5c6\uc5b4\uc9c4\ub2e4."}),"\n"]}),(0,r.jsx)(t.p,{children:"Streaming: \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 request\ub97c \ubcf4\ub0b4\uba74 \ucee4\ub125\uc158\uc744 \ub9fa\uace0, \uc774 \ucee4\ub125\uc158\uc744 \uc720\uc9c0\ud558\uba74\uc11c \uc11c\ubc84\uac00 \uacc4\uc18d \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ud558\uace0 \uc2f6\ub2e4\uba74 \uc0c8\ub85c\uc6b4 \ucee4\ub125\uc158\uc744 \ub9fa\uc5b4\uc57c \ud55c\ub2e4."}),"\n"]})]}),"\n",(0,r.jsx)(t.h3,{id:"\uc6f9\uc18c\ucf13\uc758-\ub3d9\uc791",children:"\uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791"}),"\n",(0,r.jsx)(t.mermaid,{value:"sequenceDiagram\n participant Client\n participant Server\n Client->>Server: Handshake - Upgrade\ub97c \uc774\uc6a9\ud55c WebSocket \uc804\ud658 \uc694\uccad\n Server->>Client: Handshake - HttpStatus 101(Switching Protocols)\n\n Client->>Server: \uc591\ubc29\ud5a5 \ud1b5\uc2e0\n Server->>Client: \n\n Client->>Server: \uc885\ub8cc\n Server->>Client: "}),"\n",(0,r.jsx)(t.h3,{id:"1-upgrade-\uc694\uccad",children:"1. Upgrade \uc694\uccad"}),"\n",(0,r.jsxs)(t.p,{children:["WebSocket \ud504\ub85c\ud1a0\ucf5c\ub85c \uc804\ud658\ud558\ub294 HTTP \uc694\uccad\uc744 \ubcf4\ub0b8\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub294 HTTP\uc640 \uac19\uc774 80, 443 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc6f9\uc18c\ucf13\uc73c\ub85c \uc804\ud658\ud558\uae30 \uc704\ud574\uc11c\ub294 Upgrade: websocket, Connection: Upgrade \ud5e4\ub354\uac00 \ud544\uc694\ud558\ub2e4.",(0,r.jsx)(t.br,{}),"\n","Sec-WebSocket-Key\ub294 \uc11c\ubc84\uc5d0\uc11c Sec-WebSocket-Accept\ub97c \uacc4\uc0b0\ud558\uc5ec \uc751\ub2f5\ud558\uace0 \uc774 \uac12\uc774 \uc608\uc0c1\ud55c \uac12\uacfc \ub2e4\ub974\uba74 \uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,r.jsx)(t.br,{}),"\n","Sec-WebSocket-Protocol\uc758 \uacbd\uc6b0 \uc11c\ube0c\ud504\ub85c\ud1a0\ucf5c\uc758 \ubaa9\ub85d\uc73c\ub85c \uc11c\ubc84 \uce21\uc5d0\uc11c\ub294 \ud574\ub2f9 \ubaa9\ub85d \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud558\uc5ec \ubc18\ud658\ud574\uc57c \ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\ub9cc\uc57d \uc11c\ubc84\uce21\uc5d0\uc11c \uc5ec\ub7ec \uac1c \uc9c0\uc6d0\uc774 \uac00\ub2a5\ud55c \uacbd\uc6b0 \uc9c0\uc6d0 \uac00\ub2a5\ud55c \ud504\ub85c\ud1a0\ucf5c \uc911 \uccab\ubc88\uc9f8 \ud504\ub85c\ud1a0\ucf5c\uc744 \ud074\ub77c\uc774\uc5b8\ud2b8\uce21\uc73c\ub85c \ubcf4\ub0b8\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"GET /chats HTTP/1.1\nHost: localhost:8080\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==\nSec-WebSocket-Protocol: v10.stomp, v11.stomp\nSec-WebSocket-Version: 13\nOrigin: http://localhost:8080\n"})}),"\n",(0,r.jsx)(t.h3,{id:"2-switching-protocols",children:"2. Switching Protocols"}),"\n",(0,r.jsxs)(t.p,{children:["\uc11c\ubc84\ub294 101 Switching Protocols \uc751\ub2f5\uc744 \ubc18\ud658\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","Sec-WebSocket-Accept\uc740 Sec-WebSocket-Key \ub4a4\uc5d0 ",(0,r.jsx)(t.code,{children:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"}),"\ub97c \ubd99\uc774\uace0 SHA1\ub85c \ud574\uc2f1 \ud6c4 Base64\ub85c \uc778\ucf54\ub529\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc774\ub294 \uc11c\ubc84 \uc6f9\uc18c\ucf13 \ud504\ub85c\ud1a0\ucf5c\uc758 \uc9c0\uc6d0 \uc5ec\ubd80\ub97c \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \uba85\ud655\ud788 \uc54c\ub9ac\uae30 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"HTTP/1.1 101 Switching Protocols \nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=\nSec-WebSocket-Protocol: v10.stomp\n"})}),"\n",(0,r.jsx)(t.h3,{id:"3-\ud1b5\uc2e0-\ud6c4-\uc885\ub8cc",children:"3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:["\uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uba74 \uc6f9\uc18c\ucf13 \ud504\ub808\uc784 \ub2e8\uc704\ub85c \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \ud55c\ub2e4.",(0,r.jsx)(t.br,{}),"\n","\uc5f0\uacb0 \uc885\ub8cc\ub97c \uc6d0\ud558\ub294 \uacbd\uc6b0 \ud074\ub77c\uc774\uc5b8\ud2b8, \uc11c\ubc84 \ubaa8\ub450 \uc5f0\uacb0 \uc885\ub8cc\ub97c \uc694\uccad\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(t.h3,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://datatracker.ietf.org/doc/html/rfc6455",children:"https://datatracker.ietf.org/doc/html/rfc6455"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications",children:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers",children:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers"}),(0,r.jsx)(t.br,{}),"\n",(0,r.jsx)(t.a,{href:"https://docs.spring.io/spring-framework/reference/web/websocket.html",children:"https://docs.spring.io/spring-framework/reference/web/websocket.html"})]})]})}function d(e={}){const{wrapper:t}={...(0,o.ah)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},3905:(e,t,n)=>{n.d(t,{ah:()=>a});var r=n(67294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?c(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):c(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},c=Object.keys(e);for(r=0;r<c.length;r++)n=c[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r<c.length;r++)n=c[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),a=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},d=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,c=e.originalType,l=e.parentName,d=s(e,["components","mdxType","originalType","parentName"]),h=a(n),b=o,g=h["".concat(l,".").concat(b)]||h[b]||p[b]||c;return n?r.createElement(g,i(i({ref:t},d),{},{components:n})):r.createElement(g,i({ref:t},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/f87bdf62.d6d127e8.js b/assets/js/f87bdf62.d6d127e8.js deleted file mode 100644 index b4e0d2a4c..000000000 --- a/assets/js/f87bdf62.d6d127e8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[6750],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>u});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?a(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):a(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function l(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},a=Object.keys(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)r=a[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),c=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},s=function(e){var t=c(e.components);return n.createElement(p.Provider,{value:t},e.children)},k={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,p=e.parentName,s=l(e,["components","mdxType","originalType","parentName"]),m=c(r),u=o,b=m["".concat(p,".").concat(u)]||m[u]||k[u]||a;return r?n.createElement(b,i(i({ref:t},s),{},{components:r})):n.createElement(b,i({ref:t},s))}));function u(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=m;var l={};for(var p in t)hasOwnProperty.call(t,p)&&(l[p]=t[p]);l.originalType=e,l.mdxType="string"==typeof e?e:o,i[1]=l;for(var c=2;c<a;c++)i[c]=r[c];return n.createElement.apply(null,i)}return n.createElement.apply(null,r)}m.displayName="MDXCreateElement"},19426:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>k,frontMatter:()=>a,metadata:()=>l,toc:()=>c});var n=r(87462),o=(r(67294),r(3905));const a={title:"\uc6f9\uc18c\ucf13",slug:"websocket",tags:["WebSocket"]},i=void 0,l={permalink:"/websocket",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-2/2023-06-26-WebSocket.mdx",source:"@site/blog/2023-2/2023-06-26-WebSocket.mdx",title:"\uc6f9\uc18c\ucf13",description:"\uc6f9\uc18c\ucf13",date:"2023-06-26T00:00:00.000Z",formattedDate:"2023\ub144 6\uc6d4 26\uc77c",tags:[{label:"WebSocket",permalink:"/tags/web-socket"}],readingTime:4.165,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc6f9\uc18c\ucf13",slug:"websocket",tags:["WebSocket"]},prevItem:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",permalink:"/java-spring-springboot"},nextItem:{title:"Docusaurus",permalink:"/docusaurus"}},p={authorsImageUrls:[]},c=[{value:"\uc6f9\uc18c\ucf13",id:"\uc6f9\uc18c\ucf13",level:3},{value:"\uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd",id:"\uc6f9\uc18c\ucf13-\ub4f1\uc7a5-\ubc30\uacbd",level:3},{value:"\uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791",id:"\uc6f9\uc18c\ucf13\uc758-\ub3d9\uc791",level:3},{value:"1. Upgrade \uc694\uccad",id:"1-upgrade-\uc694\uccad",level:3},{value:"2. Switching Protocols",id:"2-switching-protocols",level:3},{value:"3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc",id:"3-\ud1b5\uc2e0-\ud6c4-\uc885\ub8cc",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:3}],s={toc:c};function k(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"\uc6f9\uc18c\ucf13"},"\uc6f9\uc18c\ucf13"),(0,o.kt)("p",null,"\ub2e8\uc77c TCP \uc5f0\uacb0\uc744 \ud1b5\ud574 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ubc84 \uac04 \uc804\uc774\uc911 \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \uc9c0\uc6d0\ud558\ub294 \ud504\ub85c\ud1a0\ucf5c",(0,o.kt)("br",{parentName:"p"}),"\n","\uc6f9 \ud658\uacbd\uc5d0\uc11c \uc5f0\uc18d\ub41c \ub370\uc774\ud130\ub97c \uc2e4\uc2dc\uac04\uc73c\ub85c \ucc98\ub9ac\ud560 \uc218 \uc788\ub2e4. "),(0,o.kt)("p",null,"\uc6f9\uc18c\ucf13\uc740 HTTP\uc758 \ud3ec\ud2b8\ub97c \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uace0 \uac01\uac01 \ud3ec\ud2b8 80\uacfc \ud3ec\ud2b8 443\uc744 \uc0ac\uc6a9\ud558\uc5ec HTTP(ws://) \ubc0f HTTPS(wss://)\ub85c \uc11c\ubc84\uc5d0 \uc5f0\uacb0\ud55c\ub2e4. "),(0,o.kt)("h3",{id:"\uc6f9\uc18c\ucf13-\ub4f1\uc7a5-\ubc30\uacbd"},"\uc6f9\uc18c\ucf13 \ub4f1\uc7a5 \ubc30\uacbd"),(0,o.kt)("p",null,"\uc6f9\uc18c\ucf13\uc774 \ub4f1\uc7a5\ud558\uae30 \uc774\uc804, \uc2e4\uc2dc\uac04\uc131\uc744 \ubcf4\uc7a5\ud558\uae30 \uc704\ud574 Polling, Long polling, Streaming \uac19\uc740 \uae30\uc220\uc744 \uc0ac\uc6a9\ud588\uc5b4\uc57c \ud588\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 \uc2e4\uc2dc\uac04\uc131\uc774\ub098 \uc591\ubc29\ud5a5\uc131\uc744 \ub9cc\uc871\uc2dc\ud0a4\uc9c0 \ubabb\ud588\uace0, HTTP\ub97c \uc774\uc6a9\ud558\uae30 \ub54c\ubb38\uc5d0 \uacfc\ub3c4\ud55c \uc624\ubc84\ud5e4\ub4dc\uac00 \ubc1c\uc0dd\ud588\ub2e4. "),(0,o.kt)("admonition",{title:"polling, long polling, streaming",type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Polling: \uc8fc\uae30\uc801\uc73c\ub85c \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ubcf4\ub0b4 \uc218\uc2e0\ud560 \uc815\ubcf4\uac00 \uc788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ubc29\ubc95"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},"\uc11c\ubc84\uc5d0\uc11c \ubcf4\ub0bc \ub0b4\uc6a9\uc774 \uc5c6\uc5b4\ub3c4 \ud074\ub77c\uc774\uc5b8\ud2b8\ub294 \uc54c \uc218 \uc5c6\ub2e4. "),(0,o.kt)("li",{parentName:"ul"},"\uacc4\uc18d\ud574\uc11c \uc694\uccad\uc744 \ubcf4\ub0b4 \ud655\uc778\uc744 \ud574\uc57c\ud558\uae30 \ub54c\ubb38\uc5d0 \uc11c\ubc84\uc5d0 \ubd88\ud544\uc694\ud55c \ubd80\ud558\ub97c \uc8fc\uc5b4\uc57c \ud55c\ub2e4. ")),(0,o.kt)("p",{parentName:"admonition"},"Long Polling: \ud074\ub77c\uc774\uc5b8\ud2b8\uc758 \uc694\uccad\uc5d0 \ub300\ud574 \uc751\ub2f5\uc744 \ubcf4\ub0b4\uc9c0 \uc54a\uace0 \uc788\ub2e4\uac00 \uc774\ubca4\ud2b8\uac00 \ubc1c\uc0dd\ud588\uc744\ub54c \uc751\ub2f5\ud558\ub294 \ubc29\ubc95"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},"\ud3f4\ub9c1 \ubc29\uc2dd\ubcf4\ub2e4 \uc11c\ubc84\uc5d0 \uc801\uc740 \ubd80\ud558\ub97c \uc904 \uc218 \uc788\uc9c0\ub9cc, \uc694\uccad\uc758 \uc8fc\uae30\uac00 \uc9e7\uc73c\uba74 \ud3f4\ub9c1\uacfc \ucc28\uc774\uac00 \uc5c6\uc5b4\uc9c4\ub2e4.")),(0,o.kt)("p",{parentName:"admonition"},"Streaming: \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 request\ub97c \ubcf4\ub0b4\uba74 \ucee4\ub125\uc158\uc744 \ub9fa\uace0, \uc774 \ucee4\ub125\uc158\uc744 \uc720\uc9c0\ud558\uba74\uc11c \uc11c\ubc84\uac00 \uacc4\uc18d \ub370\uc774\ud130\ub97c \ubcf4\ub0b4\ub294 \ubc29\ubc95"),(0,o.kt)("ul",{parentName:"admonition"},(0,o.kt)("li",{parentName:"ul"},"\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc11c\ubc84\uc5d0 \uc694\uccad\uc744 \ud558\uace0 \uc2f6\ub2e4\uba74 \uc0c8\ub85c\uc6b4 \ucee4\ub125\uc158\uc744 \ub9fa\uc5b4\uc57c \ud55c\ub2e4. "))),(0,o.kt)("h3",{id:"\uc6f9\uc18c\ucf13\uc758-\ub3d9\uc791"},"\uc6f9\uc18c\ucf13\uc758 \ub3d9\uc791"),(0,o.kt)("mermaid",{value:"sequenceDiagram\n participant Client\n participant Server\n Client->>Server: Handshake - Upgrade\ub97c \uc774\uc6a9\ud55c WebSocket \uc804\ud658 \uc694\uccad\n Server->>Client: Handshake - HttpStatus 101(Switching Protocols)\n\n Client->>Server: \uc591\ubc29\ud5a5 \ud1b5\uc2e0\n Server->>Client: \n\n Client->>Server: \uc885\ub8cc\n Server->>Client: "}),(0,o.kt)("h3",{id:"1-upgrade-\uc694\uccad"},"1. Upgrade \uc694\uccad"),(0,o.kt)("p",null,"WebSocket \ud504\ub85c\ud1a0\ucf5c\ub85c \uc804\ud658\ud558\ub294 HTTP \uc694\uccad\uc744 \ubcf4\ub0b8\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 HTTP\uc640 \uac19\uc774 80, 443 \ud3ec\ud2b8\ub97c \uc0ac\uc6a9\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc6f9\uc18c\ucf13\uc73c\ub85c \uc804\ud658\ud558\uae30 \uc704\ud574\uc11c\ub294 Upgrade: websocket, Connection: Upgrade \ud5e4\ub354\uac00 \ud544\uc694\ud558\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","Sec-WebSocket-Key\ub294 \uc11c\ubc84\uc5d0\uc11c Sec-WebSocket-Accept\ub97c \uacc4\uc0b0\ud558\uc5ec \uc751\ub2f5\ud558\uace0 \uc774 \uac12\uc774 \uc608\uc0c1\ud55c \uac12\uacfc \ub2e4\ub974\uba74 \uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uc9c0 \uc54a\ub294\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","Sec-WebSocket-Protocol\uc758 \uacbd\uc6b0 \uc11c\ube0c\ud504\ub85c\ud1a0\ucf5c\uc758 \ubaa9\ub85d\uc73c\ub85c \uc11c\ubc84 \uce21\uc5d0\uc11c\ub294 \ud574\ub2f9 \ubaa9\ub85d \uc911 \ud558\ub098\ub97c \uc120\ud0dd\ud558\uc5ec \ubc18\ud658\ud574\uc57c \ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ub9cc\uc57d \uc11c\ubc84\uce21\uc5d0\uc11c \uc5ec\ub7ec \uac1c \uc9c0\uc6d0\uc774 \uac00\ub2a5\ud55c \uacbd\uc6b0 \uc9c0\uc6d0 \uac00\ub2a5\ud55c \ud504\ub85c\ud1a0\ucf5c \uc911 \uccab\ubc88\uc9f8 \ud504\ub85c\ud1a0\ucf5c\uc744 \ud074\ub77c\uc774\uc5b8\ud2b8\uce21\uc73c\ub85c \ubcf4\ub0b8\ub2e4. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"GET /chats HTTP/1.1\nHost: localhost:8080\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==\nSec-WebSocket-Protocol: v10.stomp, v11.stomp\nSec-WebSocket-Version: 13\nOrigin: http://localhost:8080\n")),(0,o.kt)("h3",{id:"2-switching-protocols"},"2. Switching Protocols"),(0,o.kt)("p",null,"\uc11c\ubc84\ub294 101 Switching Protocols \uc751\ub2f5\uc744 \ubc18\ud658\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","Sec-WebSocket-Accept\uc740 Sec-WebSocket-Key \ub4a4\uc5d0 ",(0,o.kt)("inlineCode",{parentName:"p"},"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"),"\ub97c \ubd99\uc774\uace0 SHA1\ub85c \ud574\uc2f1 \ud6c4 Base64\ub85c \uc778\ucf54\ub529\ud558\uc5ec \ubc18\ud658\ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc774\ub294 \uc11c\ubc84 \uc6f9\uc18c\ucf13 \ud504\ub85c\ud1a0\ucf5c\uc758 \uc9c0\uc6d0 \uc5ec\ubd80\ub97c \ud074\ub77c\uc774\uc5b8\ud2b8\uc5d0\uac8c \uba85\ud655\ud788 \uc54c\ub9ac\uae30 \uc704\ud574 \uc874\uc7ac\ud55c\ub2e4. "),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre"},"HTTP/1.1 101 Switching Protocols \nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=\nSec-WebSocket-Protocol: v10.stomp\n")),(0,o.kt)("h3",{id:"3-\ud1b5\uc2e0-\ud6c4-\uc885\ub8cc"},"3. \ud1b5\uc2e0 \ud6c4 \uc885\ub8cc"),(0,o.kt)("p",null,"\uc5f0\uacb0\uc774 \uc218\ub9bd\ub418\uba74 \uc6f9\uc18c\ucf13 \ud504\ub808\uc784 \ub2e8\uc704\ub85c \uc591\ubc29\ud5a5 \ud1b5\uc2e0\uc744 \ud55c\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc5f0\uacb0 \uc885\ub8cc\ub97c \uc6d0\ud558\ub294 \uacbd\uc6b0 \ud074\ub77c\uc774\uc5b8\ud2b8, \uc11c\ubc84 \ubaa8\ub450 \uc5f0\uacb0 \uc885\ub8cc\ub97c \uc694\uccad\ud560 \uc218 \uc788\ub2e4. "),(0,o.kt)("h3",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://datatracker.ietf.org/doc/html/rfc6455"},"https://datatracker.ietf.org/doc/html/rfc6455"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications"},"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers"},"https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers"),(0,o.kt)("br",{parentName:"p"}),"\n",(0,o.kt)("a",{parentName:"p",href:"https://docs.spring.io/spring-framework/reference/web/websocket.html"},"https://docs.spring.io/spring-framework/reference/web/websocket.html")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f90d0c52.28880251.js b/assets/js/f90d0c52.28880251.js deleted file mode 100644 index 1111b8863..000000000 --- a/assets/js/f90d0c52.28880251.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5294],{3905:(e,t,n)=>{n.d(t,{Zo:()=>i,kt:()=>s});var r=n(67294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function a(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?o(Object(n),!0).forEach((function(t){l(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):o(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function p(e,t){if(null==e)return{};var n,r,l=function(e,t){if(null==e)return{};var n,r,l={},o=Object.keys(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r<o.length;r++)n=o[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var u=r.createContext({}),c=function(e){var t=r.useContext(u),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},i=function(e){var t=c(e.components);return r.createElement(u.Provider,{value:t},e.children)},k={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,l=e.mdxType,o=e.originalType,u=e.parentName,i=p(e,["components","mdxType","originalType","parentName"]),m=c(n),s=l,b=m["".concat(u,".").concat(s)]||m[s]||k[s]||o;return n?r.createElement(b,a(a({ref:t},i),{},{components:n})):r.createElement(b,a({ref:t},i))}));function s(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var o=n.length,a=new Array(o);a[0]=m;var p={};for(var u in t)hasOwnProperty.call(t,u)&&(p[u]=t[u]);p.originalType=e,p.mdxType="string"==typeof e?e:l,a[1]=p;for(var c=2;c<o;c++)a[c]=n[c];return r.createElement.apply(null,a)}return r.createElement.apply(null,n)}m.displayName="MDXCreateElement"},85749:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>a,default:()=>k,frontMatter:()=>o,metadata:()=>p,toc:()=>c});var r=n(87462),l=(n(67294),n(3905));const o={title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",slug:"the-essence-of-object-orientation",tags:["Book"]},a=void 0,p={permalink:"/the-essence-of-object-orientation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",source:"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",description:"\ucc45 \uc815\ubcf4",date:"2023-01-07T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 7\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:5.415,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",slug:"the-essence-of-object-orientation",tags:["Book"]},prevItem:{title:"JSR-310",permalink:"/jsr-310"},nextItem:{title:"2022\ub144 \ud68c\uace0",permalink:"/2022-retrospective"}},u={authorsImageUrls:[]},c=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173",id:"\ucc45\uc784\uc758-\uc790\uc728\uc131\uc744-\uac15\uc870\ud558\ub294-\uc774\uc720-p173",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}],i={toc:c};function k(e){let{components:t,...n}=e;return(0,l.kt)("wrapper",(0,r.Z)({},i,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h3",{id:"\ucc45-\uc815\ubcf4"},"\ucc45 \uc815\ubcf4"),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",(0,l.kt)("br",{parentName:"p"}),"\n","\uc870\uc601\ud638")),(0,l.kt)("h3",{id:"\uc77d\uace0-\ub098\uc11c"},"\uc77d\uace0 \ub098\uc11c"),(0,l.kt)("p",null,"\uc870\uc601\ud638\ub2d8\uc758 \uc624\ube0c\uc81d\ud2b8\ub97c \uc77d\uace0 \ub098\uc11c \ub2e4\uc2dc \ud55c \ubc88 \uc77d\uc5b4\ubcf4\uc558\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\uc544\uc9c1 \uc774\ud574\uac00 \uc548\ub418\ub294 \ubd80\ubd84\uc774 \ub9ce\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ud56d\uc0c1 \uc0c8\ub85c\uc6c0\uc744 \ub290\ub080\ub2e4.",(0,l.kt)("br",{parentName:"p"}),"\n","\ub354\ud560 \ub098\uc704 \uc5c6\uc774 \ud73c\ub96d\ud55c \uac1d\uccb4\uc9c0\ud5a5 \ucc45\uc774\uace0, \uc870\uae08 \ub354 \uacf5\ubd80\ud558\uace0 \ub2e4\uc2dc \uc77d\uc5b4\ubd10\uc57c\ub420 \uac83 \uac19\ub2e4. "),(0,l.kt)("p",null,"\ucee4\ud53c \uc804\ubb38\uc810, \uc9c0\ud558\ucca0 \ub178\uc120\ub3c4, \uc774\uc0c1\ud55c \ub098\ub77c\uc758 \uc5d8\ub9ac\uc2a4\ub97c \uc608\uc2dc\ub85c \ub4e0 \uc124\uba85\uc774 \ub108\ubb34 \uc88b\uc558\uace0",(0,l.kt)("br",{parentName:"p"}),"\n","\uc88b\uc740 \ub0b4\uc6a9\uc744 \ub2f4\uace0 \uc788\uc9c0\ub9cc \uadf8\ub807\ub2e4\uace0 \ub108\ubb34 \ubb34\uac81\uc9c0 \uc54a\uc544 \uac00\ubccd\uac8c \uc77d\uae30\ub3c4 \uc88b\uc740 \uac83 \uac19\ub2e4."),(0,l.kt)("h3",{id:"\ucc45\uc784\uc758-\uc790\uc728\uc131\uc744-\uac15\uc870\ud558\ub294-\uc774\uc720-p173"},"\ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173"),(0,l.kt)("p",null,"\ud611\ub825\uc744 \ub2e8\uc21c\ud558\uac8c \ub9cc\ub4e0\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uc758\ub3c4\ub97c \uba85\ud655\ud558\uac8c \ud45c\ud604 \u2192 \ud611\ub825\uc758 \ubcf5\uc7a1\ud568 \uc800\ud558"),(0,l.kt)("li",{parentName:"ul"},"\ucc45\uc784\uc758 \ucd94\uc0c1\ud654")),(0,l.kt)("p",null,"\uc678\ubd80\uc640 \ub0b4\ubd80\ub97c \uba85\ud655\ud558\uac8c \ubd84\ub9ac\ud55c\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uc694\uccad\ud558\ub294 \uac1d\uccb4\uac00 \ubab0\ub77c\ub3c4 \ub418\ub294 \ubd80\ubd84\uc774 \ucea1\uc290\ud654\ub428\uc73c\ub85c \uc778\ud130\ud398\uc774\uc2a4\uc640 \uad6c\ud604\uc758 \ubd84\ub9ac")),(0,l.kt)("p",null,"\ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub0b4\ubd80\uc801\uc778 \ubc29\ubc95\uc744 \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 \uc678\ubd80\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub294\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\ubcc0\uacbd\uc758 \ud30c\uae09\ud6a8\uacfc\ub97c \uac1d\uccb4 \ub0b4\ubd80\ub85c \ucea1\uc290\ud654 \u2192 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \uac1d\uccb4\uc640\uc758 \uacb0\ud569\ub3c4 \uc800\ud558")),(0,l.kt)("p",null,"\ud611\ub825\uc758 \ub300\uc0c1\uc744 \ub2e4\uc591\ud558\uac8c \uc120\ud0dd\ud560 \uc218 \uc788\ub294 \uc720\uc5f0\uc131\uc744 \uc81c\uacf5\ud55c\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uc720\uc5f0\ud55c \uc124\uacc4 \u2192 \uc7ac\uc0ac\uc6a9\uc131 \uc99d\uac00")),(0,l.kt)("p",null,"\uac1d\uccb4\uc758 \uc5ed\ud560\uc744 \uc774\ud574\ud558\uae30 \uc26c\uc6cc\uc9c4\ub2e4."),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},"\uc751\uc9d1\ub3c4\ub97c \ub192\uc740 \uc0c1\ud0dc\ub85c \uc720\uc9c0")),(0,l.kt)("h3",{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4"},"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubaa9\ud45c\ub294 \uc2e4\uc138\uacc4\ub97c \ubaa8\ubc29\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\n\uc624\ud788\ub824 \uc0c8\ub85c\uc6b4 \uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uac1c\ubc1c\uc790\uc758 \uc5ed\ud560\uc740 \ub2e8\uc21c\ud788 \uc2e4\uc138\uacc4\ub97c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc548\uc73c\ub85c \uc62e\uaca8 \ub2f4\ub294 \uac83\uc774 \uc544\ub2c8\ub77c \uace0\uac1d\uacfc \uc0ac\uc6a9\uc790\ub97c \ub9cc\uc871\uc2dc\ud0ac \uc218 \uc788\ub294 \uc2e0\uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\np.21")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\uacfc\uac70\uc758 \uc804\ud1b5\uc801\uc778 \uac1c\ubc1c \ubc29\ubc95\uc740 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uc5c4\uaca9\ud558\uac8c \uad6c\ubd84\ud55c\ub2e4.\n\uc774\uc5d0 \ubc18\ud574 \uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c\ub294 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uac1d\uccb4\ub77c\ub294 \ud558\ub098\uc758 \ud2c0 \uc548\uc5d0 \ud568\uaed8 \ubb36\uc5b4 \ub193\uc74c\uc73c\ub85c\uc368 \uac1d\uccb4\uc758 \uc790\uc728\uc131\uc744 \ubcf4\uc7a5\ud55c\ub2e4.\n\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub85c \uad6c\uc131\ub41c \uacf5\ub3d9\uccb4\ub294 \uc720\uc9c0 \ubcf4\uc218\uac00 \uc27d\uace0 \uc7ac\uc0ac\uc6a9\uc774 \uc6a9\uc774\ud55c \uc2dc\uc2a4\ud15c\uc744 \uad6c\ucd95\ud560 \uc218 \uc788\ub294 \uac00\ub2a5\uc131\uc744 \uc81c\uc2dc\ud55c\ub2e4.\np.33")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},(0,l.kt)("strong",{parentName:"p"},"\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubcf8\uc9c8")),(0,l.kt)("p",{parentName:"blockquote"},"\uc2dc\uc2a4\ud15c\uc744 \uc0c1\ud638\uc791\uc6a9\ud558\ub294 \uc790\uc728\uc801\uc778 \uac1d\uccb4\ub4e4\uc758 \uacf5\ub3d9\uccb4\ub85c \ubc14\ub77c\ubcf4\uace0 \uac1d\uccb4\ub97c \uc774\uc6a9\ud574 \uc2dc\uc2a4\ud15c\uc744 \ubd84\ud560\ud558\ub294 \ubc29\ubc95"),(0,l.kt)("p",{parentName:"blockquote"},"\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub780 \uc0c1\ud0dc\uc640 \ud589\uc704\ub97c \ud568\uaed8 \uc9c0\ub2c8\uba70 \uc2a4\uc2a4\ub85c \uc790\uae30 \uc790\uc2e0\uc744 \ucc45\uc784\uc9c0\ub294 \uac1d\uccb4\ub97c \uc758\ubbf8\ud55c\ub2e4."),(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\ub294 \uc2dc\uc2a4\ud15c\uc758 \ud589\uc704\ub97c \uad6c\ud604\ud558\uae30 \uc704\ud574 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud55c\ub2e4. \uac01 \uac1d\uccb4\ub294 \ud611\ub825 \ub0b4\uc5d0\uc11c \uc815\ud574\uc9c4 \uc5ed\ud560\uc744 \uc218\ud589\ud558\uba70 \uc5ed\ud560\uc740 \uad00\ub828\ub41c \ucc45\uc784\uc758 \uc9d1\ud569\uc774\ub2e4."),(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\ub294 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud558\uae30 \uc704\ud574 \uba54\uc2dc\uc9c0\ub97c \uc804\uc1a1\ud558\uace0, \uba54\uc2dc\uc9c0\ub97c \uc218\uc2e0\ud55c \uac1d\uccb4\ub294 \uba54\uc2dc\uc9c0\ub97c \ucc98\ub9ac\ud558\ub294 \ub370 \uc801\ud569\ud55c \uba54\uc11c\ub4dc\ub97c \uc790\uc728\uc801\uc73c\ub85c \uc120\ud0dd\ud55c\ub2e4.\np.35")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\ud074\ub798\uc2a4\uc758 \uad6c\uc870\uc640 \uba54\uc11c\ub4dc\uac00 \uc544\ub2c8\ub77c \uac1d\uccb4\uc758 \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc5d0 \uc9d1\uc911\ud558\ub77c.\n\uac1d\uccb4\uc9c0\ud5a5\uc740 \uac1d\uccb4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774\uc9c0 \ud074\ub798\uc2a4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\np.38")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c \uc911\uc694\ud55c \uac83\uc740 \ub3d9\uc801\uc73c\ub85c \ubcc0\ud558\ub294 \uac1d\uccb4\uc758 \u2018\uc0c1\ud0dc\u2019\uc640 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\ub294 \u2018\ud589\uc704\u2019\ub2e4.\n\ud074\ub798\uc2a4\ub294 \ud0c0\uc785\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud574 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uad6c\ud604 \uba54\ucee4\ub2c8\uc998\uc774\ub77c\ub294 \uc0ac\uc2e4\uc744 \uae30\uc5b5\ud558\ub77c.\np.105")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"\ucc45\uc784 \uc8fc\ub3c4 \uc124\uacc4\uc758 \ud575\uc2ec\uc740 \uc5b4\ub5a4 \ud589\uc704\uac00 \ud544\uc694\ud55c\uc9c0\ub97c \uba3c\uc800 \uacb0\uc815\ud55c \ud6c4\uc5d0 \uc774 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac1d\uccb4\ub97c \uacb0\uc815\ud558\ub294 \uac83\uc774\ub2e4.\n\uc774 \uacfc\uc815\uc744 \ud754\ud788 What/Who \uc0ac\uc774\ud074\uc774\ub77c\uace0 \ud55c\ub2e4.\n\u2019\uc5b4\ub5a4 \ud589\uc704(What)\u2019\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud55c \ud6c4 \u2018\ub204\uac00(who)\u2019 \uadf8 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud574\uc57c \ud55c\ub2e4.\n\uc5ec\uae30\uc11c \u2018\uc5b4\ub5a4 \ud589\uc704\u2019\uac00 \ubc14\ub85c \uba54\uc2dc\uc9c0\ub2e4.\np.158")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f90d0c52.7f1a329c.js b/assets/js/f90d0c52.7f1a329c.js new file mode 100644 index 000000000..b8f73e523 --- /dev/null +++ b/assets/js/f90d0c52.7f1a329c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[5294],{47522:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=r(85893),l=r(3905);const i={title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",slug:"the-essence-of-object-orientation",tags:["Book"]},s=void 0,c={permalink:"/the-essence-of-object-orientation",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",source:"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",description:"\ucc45 \uc815\ubcf4",date:"2023-01-07T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 7\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:5.415,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",slug:"the-essence-of-object-orientation",tags:["Book"]},unlisted:!1,prevItem:{title:"JSR-310",permalink:"/jsr-310"},nextItem:{title:"2022\ub144 \ud68c\uace0",permalink:"/2022-retrospective"}},o={authorsImageUrls:[]},a=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173",id:"\ucc45\uc784\uc758-\uc790\uc728\uc131\uc744-\uac15\uc870\ud558\ub294-\uc774\uc720-p173",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}];function p(e){const n={blockquote:"blockquote",br:"br",h3:"h3",li:"li",p:"p",strong:"strong",ul:"ul",...(0,l.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\ucc45-\uc815\ubcf4",children:"\ucc45 \uc815\ubcf4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574",(0,t.jsx)(n.br,{}),"\n","\uc870\uc601\ud638"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc77d\uace0-\ub098\uc11c",children:"\uc77d\uace0 \ub098\uc11c"}),"\n",(0,t.jsxs)(n.p,{children:["\uc870\uc601\ud638\ub2d8\uc758 \uc624\ube0c\uc81d\ud2b8\ub97c \uc77d\uace0 \ub098\uc11c \ub2e4\uc2dc \ud55c \ubc88 \uc77d\uc5b4\ubcf4\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc544\uc9c1 \uc774\ud574\uac00 \uc548\ub418\ub294 \ubd80\ubd84\uc774 \ub9ce\uc9c0\ub9cc, \uadf8\ub798\ub3c4 \ud56d\uc0c1 \uc0c8\ub85c\uc6c0\uc744 \ub290\ub080\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub354\ud560 \ub098\uc704 \uc5c6\uc774 \ud73c\ub96d\ud55c \uac1d\uccb4\uc9c0\ud5a5 \ucc45\uc774\uace0, \uc870\uae08 \ub354 \uacf5\ubd80\ud558\uace0 \ub2e4\uc2dc \uc77d\uc5b4\ubd10\uc57c\ub420 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\ucee4\ud53c \uc804\ubb38\uc810, \uc9c0\ud558\ucca0 \ub178\uc120\ub3c4, \uc774\uc0c1\ud55c \ub098\ub77c\uc758 \uc5d8\ub9ac\uc2a4\ub97c \uc608\uc2dc\ub85c \ub4e0 \uc124\uba85\uc774 \ub108\ubb34 \uc88b\uc558\uace0",(0,t.jsx)(n.br,{}),"\n","\uc88b\uc740 \ub0b4\uc6a9\uc744 \ub2f4\uace0 \uc788\uc9c0\ub9cc \uadf8\ub807\ub2e4\uace0 \ub108\ubb34 \ubb34\uac81\uc9c0 \uc54a\uc544 \uac00\ubccd\uac8c \uc77d\uae30\ub3c4 \uc88b\uc740 \uac83 \uac19\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ucc45\uc784\uc758-\uc790\uc728\uc131\uc744-\uac15\uc870\ud558\ub294-\uc774\uc720-p173",children:"\ucc45\uc784\uc758 \uc790\uc728\uc131\uc744 \uac15\uc870\ud558\ub294 \uc774\uc720 p.173"}),"\n",(0,t.jsx)(n.p,{children:"\ud611\ub825\uc744 \ub2e8\uc21c\ud558\uac8c \ub9cc\ub4e0\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc758\ub3c4\ub97c \uba85\ud655\ud558\uac8c \ud45c\ud604 \u2192 \ud611\ub825\uc758 \ubcf5\uc7a1\ud568 \uc800\ud558"}),"\n",(0,t.jsx)(n.li,{children:"\ucc45\uc784\uc758 \ucd94\uc0c1\ud654"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\uc678\ubd80\uc640 \ub0b4\ubd80\ub97c \uba85\ud655\ud558\uac8c \ubd84\ub9ac\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc694\uccad\ud558\ub294 \uac1d\uccb4\uac00 \ubab0\ub77c\ub3c4 \ub418\ub294 \ubd80\ubd84\uc774 \ucea1\uc290\ud654\ub428\uc73c\ub85c \uc778\ud130\ud398\uc774\uc2a4\uc640 \uad6c\ud604\uc758 \ubd84\ub9ac"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\ucc45\uc784\uc744 \uc218\ud589\ud558\ub294 \ub0b4\ubd80\uc801\uc778 \ubc29\ubc95\uc744 \ubcc0\uacbd\ud558\ub354\ub77c\ub3c4 \uc678\ubd80\uc5d0 \uc601\ud5a5\uc744 \ubbf8\uce58\uc9c0 \uc54a\ub294\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\ubcc0\uacbd\uc758 \ud30c\uae09\ud6a8\uacfc\ub97c \uac1d\uccb4 \ub0b4\ubd80\ub85c \ucea1\uc290\ud654 \u2192 \uba54\uc2dc\uc9c0\ub97c \ubcf4\ub0b4\ub294 \uac1d\uccb4\uc640\uc758 \uacb0\ud569\ub3c4 \uc800\ud558"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\ud611\ub825\uc758 \ub300\uc0c1\uc744 \ub2e4\uc591\ud558\uac8c \uc120\ud0dd\ud560 \uc218 \uc788\ub294 \uc720\uc5f0\uc131\uc744 \uc81c\uacf5\ud55c\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc720\uc5f0\ud55c \uc124\uacc4 \u2192 \uc7ac\uc0ac\uc6a9\uc131 \uc99d\uac00"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\uc758 \uc5ed\ud560\uc744 \uc774\ud574\ud558\uae30 \uc26c\uc6cc\uc9c4\ub2e4."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"\uc751\uc9d1\ub3c4\ub97c \ub192\uc740 \uc0c1\ud0dc\ub85c \uc720\uc9c0"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",children:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubaa9\ud45c\ub294 \uc2e4\uc138\uacc4\ub97c \ubaa8\ubc29\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\n\uc624\ud788\ub824 \uc0c8\ub85c\uc6b4 \uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\n\uc18c\ud504\ud2b8\uc6e8\uc5b4 \uac1c\ubc1c\uc790\uc758 \uc5ed\ud560\uc740 \ub2e8\uc21c\ud788 \uc2e4\uc138\uacc4\ub97c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc548\uc73c\ub85c \uc62e\uaca8 \ub2f4\ub294 \uac83\uc774 \uc544\ub2c8\ub77c \uace0\uac1d\uacfc \uc0ac\uc6a9\uc790\ub97c \ub9cc\uc871\uc2dc\ud0ac \uc218 \uc788\ub294 \uc2e0\uc138\uacc4\ub97c \ucc3d\uc870\ud558\ub294 \uac83\uc774\ub2e4.\np.21"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uacfc\uac70\uc758 \uc804\ud1b5\uc801\uc778 \uac1c\ubc1c \ubc29\ubc95\uc740 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uc5c4\uaca9\ud558\uac8c \uad6c\ubd84\ud55c\ub2e4.\n\uc774\uc5d0 \ubc18\ud574 \uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c\ub294 \ub370\uc774\ud130\uc640 \ud504\ub85c\uc138\uc2a4\ub97c \uac1d\uccb4\ub77c\ub294 \ud558\ub098\uc758 \ud2c0 \uc548\uc5d0 \ud568\uaed8 \ubb36\uc5b4 \ub193\uc74c\uc73c\ub85c\uc368 \uac1d\uccb4\uc758 \uc790\uc728\uc131\uc744 \ubcf4\uc7a5\ud55c\ub2e4.\n\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub85c \uad6c\uc131\ub41c \uacf5\ub3d9\uccb4\ub294 \uc720\uc9c0 \ubcf4\uc218\uac00 \uc27d\uace0 \uc7ac\uc0ac\uc6a9\uc774 \uc6a9\uc774\ud55c \uc2dc\uc2a4\ud15c\uc744 \uad6c\ucd95\ud560 \uc218 \uc788\ub294 \uac00\ub2a5\uc131\uc744 \uc81c\uc2dc\ud55c\ub2e4.\np.33"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"\uac1d\uccb4\uc9c0\ud5a5\uc758 \ubcf8\uc9c8"})}),"\n",(0,t.jsx)(n.p,{children:"\uc2dc\uc2a4\ud15c\uc744 \uc0c1\ud638\uc791\uc6a9\ud558\ub294 \uc790\uc728\uc801\uc778 \uac1d\uccb4\ub4e4\uc758 \uacf5\ub3d9\uccb4\ub85c \ubc14\ub77c\ubcf4\uace0 \uac1d\uccb4\ub97c \uc774\uc6a9\ud574 \uc2dc\uc2a4\ud15c\uc744 \ubd84\ud560\ud558\ub294 \ubc29\ubc95"}),"\n",(0,t.jsx)(n.p,{children:"\uc790\uc728\uc801\uc778 \uac1d\uccb4\ub780 \uc0c1\ud0dc\uc640 \ud589\uc704\ub97c \ud568\uaed8 \uc9c0\ub2c8\uba70 \uc2a4\uc2a4\ub85c \uc790\uae30 \uc790\uc2e0\uc744 \ucc45\uc784\uc9c0\ub294 \uac1d\uccb4\ub97c \uc758\ubbf8\ud55c\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\ub294 \uc2dc\uc2a4\ud15c\uc758 \ud589\uc704\ub97c \uad6c\ud604\ud558\uae30 \uc704\ud574 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud55c\ub2e4. \uac01 \uac1d\uccb4\ub294 \ud611\ub825 \ub0b4\uc5d0\uc11c \uc815\ud574\uc9c4 \uc5ed\ud560\uc744 \uc218\ud589\ud558\uba70 \uc5ed\ud560\uc740 \uad00\ub828\ub41c \ucc45\uc784\uc758 \uc9d1\ud569\uc774\ub2e4."}),"\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\ub294 \ub2e4\ub978 \uac1d\uccb4\uc640 \ud611\ub825\ud558\uae30 \uc704\ud574 \uba54\uc2dc\uc9c0\ub97c \uc804\uc1a1\ud558\uace0, \uba54\uc2dc\uc9c0\ub97c \uc218\uc2e0\ud55c \uac1d\uccb4\ub294 \uba54\uc2dc\uc9c0\ub97c \ucc98\ub9ac\ud558\ub294 \ub370 \uc801\ud569\ud55c \uba54\uc11c\ub4dc\ub97c \uc790\uc728\uc801\uc73c\ub85c \uc120\ud0dd\ud55c\ub2e4.\np.35"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ud074\ub798\uc2a4\uc758 \uad6c\uc870\uc640 \uba54\uc11c\ub4dc\uac00 \uc544\ub2c8\ub77c \uac1d\uccb4\uc758 \uc5ed\ud560, \ucc45\uc784, \ud611\ub825\uc5d0 \uc9d1\uc911\ud558\ub77c.\n\uac1d\uccb4\uc9c0\ud5a5\uc740 \uac1d\uccb4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774\uc9c0 \ud074\ub798\uc2a4\ub97c \uc9c0\ud5a5\ud558\ub294 \uac83\uc774 \uc544\ub2c8\ub2e4.\np.38"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uac1d\uccb4\uc9c0\ud5a5\uc5d0\uc11c \uc911\uc694\ud55c \uac83\uc740 \ub3d9\uc801\uc73c\ub85c \ubcc0\ud558\ub294 \uac1d\uccb4\uc758 \u2018\uc0c1\ud0dc\u2019\uc640 \uc0c1\ud0dc\ub97c \ubcc0\uacbd\ud558\ub294 \u2018\ud589\uc704\u2019\ub2e4.\n\ud074\ub798\uc2a4\ub294 \ud0c0\uc785\uc744 \uad6c\ud604\ud558\uae30 \uc704\ud574 \ud504\ub85c\uadf8\ub798\ubc0d \uc5b8\uc5b4\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 \uad6c\ud604 \uba54\ucee4\ub2c8\uc998\uc774\ub77c\ub294 \uc0ac\uc2e4\uc744 \uae30\uc5b5\ud558\ub77c.\np.105"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ucc45\uc784 \uc8fc\ub3c4 \uc124\uacc4\uc758 \ud575\uc2ec\uc740 \uc5b4\ub5a4 \ud589\uc704\uac00 \ud544\uc694\ud55c\uc9c0\ub97c \uba3c\uc800 \uacb0\uc815\ud55c \ud6c4\uc5d0 \uc774 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac1d\uccb4\ub97c \uacb0\uc815\ud558\ub294 \uac83\uc774\ub2e4.\n\uc774 \uacfc\uc815\uc744 \ud754\ud788 What/Who \uc0ac\uc774\ud074\uc774\ub77c\uace0 \ud55c\ub2e4.\n\u2019\uc5b4\ub5a4 \ud589\uc704(What)\u2019\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud55c \ud6c4 \u2018\ub204\uac00(who)\u2019 \uadf8 \ud589\uc704\ub97c \uc218\ud589\ud560 \uac83\uc778\uc9c0 \uacb0\uc815\ud574\uc57c \ud55c\ub2e4.\n\uc5ec\uae30\uc11c \u2018\uc5b4\ub5a4 \ud589\uc704\u2019\uac00 \ubc14\ub85c \uba54\uc2dc\uc9c0\ub2e4.\np.158"}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,l.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function l(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function i(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function s(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?i(Object(r),!0).forEach((function(n){l(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):i(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function c(e,n){if(null==e)return{};var r,t,l=function(e,n){if(null==e)return{};var r,t,l={},i=Object.keys(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||(l[r]=e[r]);return l}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(t=0;t<i.length;t++)r=i[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(l[r]=e[r])}return l}var o=t.createContext({}),a=function(e){var n=t.useContext(o),r=n;return e&&(r="function"==typeof e?e(n):s(s({},n),e)),r},p={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},d=t.forwardRef((function(e,n){var r=e.components,l=e.mdxType,i=e.originalType,o=e.parentName,d=c(e,["components","mdxType","originalType","parentName"]),h=a(r),u=l,j=h["".concat(o,".").concat(u)]||h[u]||p[u]||i;return r?t.createElement(j,s(s({ref:n},d),{},{components:r})):t.createElement(j,s({ref:n},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/fa3d3942.73543988.js b/assets/js/fa3d3942.73543988.js new file mode 100644 index 000000000..c00f73ae2 --- /dev/null +++ b/assets/js/fa3d3942.73543988.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[916],{28227:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>l,toc:()=>a});var t=r(85893),o=r(3905);const c={title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",slug:"book-writer",tags:["Book"]},i=void 0,l={permalink:"/book-writer",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",source:"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",description:"\ucc45 \uc815\ubcf4",date:"2023-01-01T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 1\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:4.425,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",slug:"book-writer",tags:["Book"]},unlisted:!1,prevItem:{title:"2022\ub144 \ud68c\uace0",permalink:"/2022-retrospective"}},s={authorsImageUrls:[]},a=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}];function u(e){const n={blockquote:"blockquote",br:"br",h3:"h3",p:"p",...(0,o.ah)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h3,{id:"\ucc45-\uc815\ubcf4",children:"\ucc45 \uc815\ubcf4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ubc15\uc194\ubbf8"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"\uc77d\uace0-\ub098\uc11c",children:"\uc77d\uace0 \ub098\uc11c"}),"\n",(0,t.jsxs)(n.p,{children:["\uc800\uc790\uc758 \uacbd\ud5d8\uacfc \ud568\uaed8 \uae00\uc4f0\uae30\uc5d0 \ub300\ud55c \uac00\ubcbc\uc6b4 \uc870\uc5b8\uc774 \ub2f4\uaca8\uc788\uc5b4 \uac00\ubccd\uac8c \uc77d\uae30 \uc88b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uae00\uc744 \uc798 \uc791\uc131\ud574 \ubcf4\uace0 \uc2f6\uc744 \ub54c \uc801\uc6a9\ud574 \ubcfc \uc218 \uc788\ub294 \uc815\ubcf4\uac00 \ub9ce\uc544\uc11c \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub2e4."]}),"\n",(0,t.jsxs)(n.p,{children:["\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\uc758 \ud504\ub9ac\ucf54\uc2a4\ub97c \uc9c4\ud589\ud560 \ub54c \ud6c4\uae30\ub97c \uc791\uc131\ud558\uace0 \ub098\uba74 \ud56d\uc0c1 \uae00\uc774 \ub531\ub531\ud558\ub2e4\ub294 \ub290\ub08c\uc744 \ubc1b\uc558\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\ub2e4\ub978 \uc9c0\uc6d0\uc790\ub4e4\uc758 \uc77d\uae30 \ud3b8\ud558\uace0, \ubc1d\uc740 \ub290\ub08c\uc744 \uc8fc\ub294 \uae00\uc744 \ubcf4\uba74 \ubd80\ub7ec\uc6b4 \ub9c8\uc74c\uc744 \uac00\uc9c0\uae30\ub3c4 \ud588\ub2e4.",(0,t.jsx)(n.br,{}),"\n","\uc774 \ucc45\uc744 \uc77d\uc5c8\uc73c\ub2c8 2023\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae00\uc744 \uc798 \uc801\uc5b4\ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,t.jsx)(n.h3,{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",children:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ubb38\uc7a5\uc774 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74\n\ub0b4\uc6a9\uc744 \uc77c\ubaa9\uc694\uc5f0\ud558\uac8c \uc815\ub9ac\ud588\uace0, \uae00\uc758 \uc758\ub3c4\ub3c4 \uc090\ub6a4\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub3c4 \uc801\uc808\ud55c \uac83\uc73c\ub85c \uace8\ub790\ub294\ub370\u2026 \uadf8\ub7f0\ub370\ub3c4 \uc5b4\ub518\uac00\uac00 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74? \ucd95\ucd95 \ucc98\uc9c0\uace0 \ub530\ubd84\ud558\ub2e4\uba74? \ub9d0\uaf2c\ub9ac\ub97c \ubaa8\uc870\ub9ac \u2018~\ub2e4\u2019\ub85c \ud1b5\uc77c\ud55c \uac74 \uc544\ub2cc\uc9c0 \uc810\uac80\ud574 \ubcf4\uc138\uc694."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ub9d0\uaf2c\ub9ac\ub97c \uc798 \uac16\uace0 \ub180\uc544\uc57c \ud569\ub2c8\ub2e4. \ubb38\uc7a5\uc758 \ub9c8\uc9c0\ub9c9 \uae00\uc790\ub97c \ub9e4\ubc88 \ub2e4\ub974\uac8c \uace0\uccd0\uc4f0\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uae00\uc5d0 \ud65c\uae30\ub97c \ub354\ud560 \uc218 \uc788\uc8e0. \ub54c\ub860 \ubb38\uc7a5\uc744 \ub2e4 \ub9c8\uce58\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub85c\ub9cc \ub05d\ub9fa\ub294 \uac83\ub3c4 \ubc29\ubc95. \ubb38\uc7a5\uacfc \ubb38\uc7a5 \uc0ac\uc774\uc5d0 \uc27c\ud45c\uac00 \ub4e4\uc5b4\uc11c\uba70 \uae00 \uc804\uccb4\uc5d0 \ud65c\uae30\uac00 \ub3cc\uac8c \ub3fc\uc694. \ubb38\uc7a5\uc758 \uae38\uc774\ub3c4 \ub2e4\ucc44\ub85c\uc6cc\uc9c0\ub294 \ub355\ubd84\uc5d0 \ub364\uc73c\ub85c \uc5bb\uac8c \ub418\ub294 \uac83\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ubc14\ub85c, \uae00\uc758 \ub9ac\ub4ec."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uc774\uc804 \ubb38\uc7a5\uc5d0\uc11c \ub05d\ub09c \uae00\uc790\ub85c, \ub2e4\uc74c \ubb38\uc7a5\uc744 \ub05d\ub9fa\uc9c0 \uc54a\uae30. \ud55c\ub450 \ubb38\ub2e8\ub9c8\ub2e4 \ub2e8\uc5b4 \uc218\uc900\uc758 \uc544\uc8fc \uc9e7\uc740 \ubb38\uc7a5 \ubc30\uce58\ud558\uae30."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uae00\uc758 \uc9c4\uc9dc \uc774\uc720, \uae00\uc758 \uc9c4\uc9dc \ubaa9\uc801, \uae00\uc758 \uc9c4\uc9dc \ub300\uc0c1\uc744 \ucc3e\uc73c\ub824\uace0 \uc560\uc37c\uc2b5\ub2c8\ub2e4. \uc9c0\uae08\ucc98\ub7fc \ud2c0\uc744 \ub5a0\uc62c\ub9b0\ub2e4\uac70\ub098, \ub208\uce58\ub97c \ubcf8\ub2e4\uac70\ub098, \uc815\uce58\uc801\uc778 \uc148\ub3c4 \ud558\uc9c0 \uc54a\uc558\uc5b4\uc694."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uc81c\ubaa9\uc740 \uc9e7\uac8c, \ubcf4\uae30 \uc27d\uac8c, \uc77d\uae30 \uc27d\uac8c, \ubc1c\uc74c\uc774 \ube44\uc2b7\ud558\uac8c, \uc21c\uc11c\ub97c \ubc14\uafd4\uc11c"}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uae00\uc744 \ub9c8\uc9c0\ub9c9\uc73c\ub85c \ub2e4\ub4ec\uc744 \ub54c, \ub178\ub798\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \ubc29\ubc95\uc740 \uc5c6\uc744\uc9c0 \uace0\ubbfc\ud574\ubd05\ub2c8\ub2e4. \uac10\ud788 \uac00 \ub2ff\uc744 \uc218 \uc5c6\ub294 \ubaa9\ud45c\uc774\uaca0\uc9c0\ub9cc, \ud560 \uc218 \uc788\ub294 \ucd5c\uc18c\ud55c\uc758 \ub9ac\ub4ec\uc774\ub77c\ub3c4 \ubd99\uc5ec\uc8fc\uace0 \uc2f6\uc5b4\uc694."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uc5ec\ub294 \ub9d0\uacfc \ub9c8\uc9c0\ub9c9 \ub9d0\uc5d0 \uc791\uc815\ud558\uace0 \ub9c8\uc74c\uc744 \ub2f4\ub294 \uc5f0\uc2b5\uc744 \ud574\ubd05\uc2dc\ub2e4. \uae00\uc758 \uc5b4\ub290 \uad6c\uc11d\uc774\ub77c\ub3c4 \ubed4\ud55c \uae00\uc790\ub294 \ub0a8\uae30\uc9c0 \uc54a\uaca0\ub178\ub77c \ub2e4\uc9d0\ud558\uba70 \uc368\ubcf4\ub294 \uac81\ub2c8\ub2e4. \ub098\ub9cc\uc774 \uac00\uc9c4 \uc720\uc77c\ud55c \uba54\uc2dc\uc9c0\uc5d0 \uc9d1\uc911\ud558\uba74\uc11c\uc694. \uadf8\ub7fc \uc0dd\uac01\uc774 \ub2ec\ub77c\uc9c0\uace0, \uace0\ub974\ub294 \ub2e8\uc5b4\ub3c4 \ub2ec\ub77c\uc9c0\uace0, \ub0a8\uae34 \ubb38\uc7a5\ub3c4 \ub2ec\ub77c\uc838\uc694. \uacb0\uad6d\uc5d0\ub294 \uae00\uc744 \uc4f4 \uc0ac\ub78c\uc778 \ub098 \uc790\uc2e0\ub3c4 \ub0a8\ub2ec\ub77c\uc9c8 \uac81\ub2c8\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\ub9de\ucda4\ubc95\uc740 \uc911\uc694\ud569\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \ub9de\ucda4\ubc95\ubcf4\ub2e4 \ub354 \uc911\uc694\ud55c \uac74 \uac70\uae30\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc785\ub2c8\ub2e4. \ub0b4 \ub9c8\uc74c\uc744 \uae00\uc5d0 \ub2f4\uc544 \uc2e4\uc5b4 \ubcf4\ub0b4\uae30 \uc804, \ub9de\ucda4\ubc95\uc744 \uc810\uac80\ud558\ub294 \uc774\uc720 \uc5ed\uc2dc \uadf8\uac81\ub2c8\ub2e4. \uc624\uc9c1 \ub0b4 \ub9c8\uc74c\uc774 \ub0a8\uc5d0\uac8c \uc77d\ud788\ub294 \ub3d9\uc548 \ubc29\ud574\uac00 \ub418\uc9c0 \uc54a\uae30\ub97c \ubc14\ub77c\uae30 \ub54c\ubb38\uc774\uc8e0. \ub0b4\uac00 \uc4f4 \uae00\ub3c4, \ub0a8\uc774 \uc4f4 \uae00\ub3c4. \uc5b8\uc81c\ub098 \uadf8 \uc548\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc774 \uba3c\uc800\uc785\ub2c8\ub2e4."}),"\n"]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"\uae00\uc744 \uc4f4\ub2e4\uace0 \uae00\uc774 \uc644\uc131\ub418\ub294 \uac8c \uc544\ub2c8\uc5d0\uc694. \uae00\uacfc \ub2ee\uc740 \ubaa8\uc2b5\uc73c\ub85c \uc0b4 \ub54c, \uae00\uc740 \ube44\ub85c\uc18c \uc644\uc131\ub429\ub2c8\ub2e4."}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,o.ah)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},3905:(e,n,r)=>{r.d(n,{ah:()=>a});var t=r(67294);function o(e,n,r){return n in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function c(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function i(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?c(Object(r),!0).forEach((function(n){o(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):c(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function l(e,n){if(null==e)return{};var r,t,o=function(e,n){if(null==e)return{};var r,t,o={},c=Object.keys(e);for(t=0;t<c.length;t++)r=c[t],n.indexOf(r)>=0||(o[r]=e[r]);return o}(e,n);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(t=0;t<c.length;t++)r=c[t],n.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=t.createContext({}),a=function(e){var n=t.useContext(s),r=n;return e&&(r="function"==typeof e?e(n):i(i({},n),e)),r},u={inlineCode:"code",wrapper:function(e){var n=e.children;return t.createElement(t.Fragment,{},n)}},p=t.forwardRef((function(e,n){var r=e.components,o=e.mdxType,c=e.originalType,s=e.parentName,p=l(e,["components","mdxType","originalType","parentName"]),d=a(r),b=o,h=d["".concat(s,".").concat(b)]||d[b]||u[b]||c;return r?t.createElement(h,i(i({ref:n},p),{},{components:r})):t.createElement(h,i({ref:n},p))}));p.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/fa3d3942.9d73b73f.js b/assets/js/fa3d3942.9d73b73f.js deleted file mode 100644 index 7fc033310..000000000 --- a/assets/js/fa3d3942.9d73b73f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[916],{3905:(e,t,r)=>{r.d(t,{Zo:()=>i,kt:()=>m});var n=r(67294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?l(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):l(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function c(e,t){if(null==e)return{};var r,n,o=function(e,t){if(null==e)return{};var r,n,o={},l=Object.keys(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)r=l[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var p=n.createContext({}),u=function(e){var t=n.useContext(p),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},i=function(e){var t=u(e.components);return n.createElement(p.Provider,{value:t},e.children)},k={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},b=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,l=e.originalType,p=e.parentName,i=c(e,["components","mdxType","originalType","parentName"]),b=u(r),m=o,s=b["".concat(p,".").concat(m)]||b[m]||k[m]||l;return r?n.createElement(s,a(a({ref:t},i),{},{components:r})):n.createElement(s,a({ref:t},i))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var l=r.length,a=new Array(l);a[0]=b;var c={};for(var p in t)hasOwnProperty.call(t,p)&&(c[p]=t[p]);c.originalType=e,c.mdxType="string"==typeof e?e:o,a[1]=c;for(var u=2;u<l;u++)a[u]=r[u];return n.createElement.apply(null,a)}return n.createElement.apply(null,r)}b.displayName="MDXCreateElement"},53036:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>p,contentTitle:()=>a,default:()=>k,frontMatter:()=>l,metadata:()=>c,toc:()=>u});var n=r(87462),o=(r(67294),r(3905));const l={title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",slug:"book-writer",tags:["Book"]},a=void 0,c={permalink:"/book-writer",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",source:"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",description:"\ucc45 \uc815\ubcf4",date:"2023-01-01T00:00:00.000Z",formattedDate:"2023\ub144 1\uc6d4 1\uc77c",tags:[{label:"Book",permalink:"/tags/book"}],readingTime:4.425,hasTruncateMarker:!1,authors:[],frontMatter:{title:"[\ucc45] \uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",slug:"book-writer",tags:["Book"]},prevItem:{title:"2022\ub144 \ud68c\uace0",permalink:"/2022-retrospective"}},p={authorsImageUrls:[]},u=[{value:"\ucc45 \uc815\ubcf4",id:"\ucc45-\uc815\ubcf4",level:3},{value:"\uc77d\uace0 \ub098\uc11c",id:"\uc77d\uace0-\ub098\uc11c",level:3},{value:"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4",id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4",level:3}],i={toc:u};function k(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,n.Z)({},i,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h3",{id:"\ucc45-\uc815\ubcf4"},"\ucc45 \uc815\ubcf4"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ubc15\uc194\ubbf8 ")),(0,o.kt)("h3",{id:"\uc77d\uace0-\ub098\uc11c"},"\uc77d\uace0 \ub098\uc11c"),(0,o.kt)("p",null,"\uc800\uc790\uc758 \uacbd\ud5d8\uacfc \ud568\uaed8 \uae00\uc4f0\uae30\uc5d0 \ub300\ud55c \uac00\ubcbc\uc6b4 \uc870\uc5b8\uc774 \ub2f4\uaca8\uc788\uc5b4 \uac00\ubccd\uac8c \uc77d\uae30 \uc88b\uc558\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uae00\uc744 \uc798 \uc791\uc131\ud574 \ubcf4\uace0 \uc2f6\uc744 \ub54c \uc801\uc6a9\ud574 \ubcfc \uc218 \uc788\ub294 \uc815\ubcf4\uac00 \ub9ce\uc544\uc11c \ub3c4\uc6c0\uc774 \ub418\uc5c8\ub2e4. "),(0,o.kt)("p",null,"\uc6b0\uc544\ud55c \ud14c\ud06c\ucf54\uc2a4\uc758 \ud504\ub9ac\ucf54\uc2a4\ub97c \uc9c4\ud589\ud560 \ub54c \ud6c4\uae30\ub97c \uc791\uc131\ud558\uace0 \ub098\uba74 \ud56d\uc0c1 \uae00\uc774 \ub531\ub531\ud558\ub2e4\ub294 \ub290\ub08c\uc744 \ubc1b\uc558\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\ub2e4\ub978 \uc9c0\uc6d0\uc790\ub4e4\uc758 \uc77d\uae30 \ud3b8\ud558\uace0, \ubc1d\uc740 \ub290\ub08c\uc744 \uc8fc\ub294 \uae00\uc744 \ubcf4\uba74 \ubd80\ub7ec\uc6b4 \ub9c8\uc74c\uc744 \uac00\uc9c0\uae30\ub3c4 \ud588\ub2e4.",(0,o.kt)("br",{parentName:"p"}),"\n","\uc774 \ucc45\uc744 \uc77d\uc5c8\uc73c\ub2c8 2023\ub144\uc5d0\ub294 \uc870\uae08 \ub354 \uae00\uc744 \uc798 \uc801\uc5b4\ubcf4\ub824\uace0 \ud55c\ub2e4."),(0,o.kt)("h3",{id:"\ubc11\uc904-\uce5c-\ubb38\uc7a5\ub4e4"},"\ubc11\uc904 \uce5c \ubb38\uc7a5\ub4e4"),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\ubb38\uc7a5\uc774 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74\n\ub0b4\uc6a9\uc744 \uc77c\ubaa9\uc694\uc5f0\ud558\uac8c \uc815\ub9ac\ud588\uace0, \uae00\uc758 \uc758\ub3c4\ub3c4 \uc090\ub6a4\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub3c4 \uc801\uc808\ud55c \uac83\uc73c\ub85c \uace8\ub790\ub294\ub370\u2026 \uadf8\ub7f0\ub370\ub3c4 \uc5b4\ub518\uac00\uac00 \uc2ec\uc2ec\ud558\uace0 \uc9c0\ub8e8\ud558\ub2e4\uba74? \ucd95\ucd95 \ucc98\uc9c0\uace0 \ub530\ubd84\ud558\ub2e4\uba74? \ub9d0\uaf2c\ub9ac\ub97c \ubaa8\uc870\ub9ac \u2018~\ub2e4\u2019\ub85c \ud1b5\uc77c\ud55c \uac74 \uc544\ub2cc\uc9c0 \uc810\uac80\ud574 \ubcf4\uc138\uc694.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\ub9d0\uaf2c\ub9ac\ub97c \uc798 \uac16\uace0 \ub180\uc544\uc57c \ud569\ub2c8\ub2e4. \ubb38\uc7a5\uc758 \ub9c8\uc9c0\ub9c9 \uae00\uc790\ub97c \ub9e4\ubc88 \ub2e4\ub974\uac8c \uace0\uccd0\uc4f0\ub294 \uac83\ub9cc\uc73c\ub85c\ub3c4 \uae00\uc5d0 \ud65c\uae30\ub97c \ub354\ud560 \uc218 \uc788\uc8e0. \ub54c\ub860 \ubb38\uc7a5\uc744 \ub2e4 \ub9c8\uce58\uc9c0 \uc54a\uace0, \ub2e8\uc5b4\ub85c\ub9cc \ub05d\ub9fa\ub294 \uac83\ub3c4 \ubc29\ubc95. \ubb38\uc7a5\uacfc \ubb38\uc7a5 \uc0ac\uc774\uc5d0 \uc27c\ud45c\uac00 \ub4e4\uc5b4\uc11c\uba70 \uae00 \uc804\uccb4\uc5d0 \ud65c\uae30\uac00 \ub3cc\uac8c \ub3fc\uc694. \ubb38\uc7a5\uc758 \uae38\uc774\ub3c4 \ub2e4\ucc44\ub85c\uc6cc\uc9c0\ub294 \ub355\ubd84\uc5d0 \ub364\uc73c\ub85c \uc5bb\uac8c \ub418\ub294 \uac83\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \ubc14\ub85c, \uae00\uc758 \ub9ac\ub4ec.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uc774\uc804 \ubb38\uc7a5\uc5d0\uc11c \ub05d\ub09c \uae00\uc790\ub85c, \ub2e4\uc74c \ubb38\uc7a5\uc744 \ub05d\ub9fa\uc9c0 \uc54a\uae30. \ud55c\ub450 \ubb38\ub2e8\ub9c8\ub2e4 \ub2e8\uc5b4 \uc218\uc900\uc758 \uc544\uc8fc \uc9e7\uc740 \ubb38\uc7a5 \ubc30\uce58\ud558\uae30.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uae00\uc758 \uc9c4\uc9dc \uc774\uc720, \uae00\uc758 \uc9c4\uc9dc \ubaa9\uc801, \uae00\uc758 \uc9c4\uc9dc \ub300\uc0c1\uc744 \ucc3e\uc73c\ub824\uace0 \uc560\uc37c\uc2b5\ub2c8\ub2e4. \uc9c0\uae08\ucc98\ub7fc \ud2c0\uc744 \ub5a0\uc62c\ub9b0\ub2e4\uac70\ub098, \ub208\uce58\ub97c \ubcf8\ub2e4\uac70\ub098, \uc815\uce58\uc801\uc778 \uc148\ub3c4 \ud558\uc9c0 \uc54a\uc558\uc5b4\uc694.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uc81c\ubaa9\uc740 \uc9e7\uac8c, \ubcf4\uae30 \uc27d\uac8c, \uc77d\uae30 \uc27d\uac8c, \ubc1c\uc74c\uc774 \ube44\uc2b7\ud558\uac8c, \uc21c\uc11c\ub97c \ubc14\uafd4\uc11c")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uae00\uc744 \ub9c8\uc9c0\ub9c9\uc73c\ub85c \ub2e4\ub4ec\uc744 \ub54c, \ub178\ub798\uc5d0 \uac00\uae4c\uc6cc\uc9c8 \ubc29\ubc95\uc740 \uc5c6\uc744\uc9c0 \uace0\ubbfc\ud574\ubd05\ub2c8\ub2e4. \uac10\ud788 \uac00 \ub2ff\uc744 \uc218 \uc5c6\ub294 \ubaa9\ud45c\uc774\uaca0\uc9c0\ub9cc, \ud560 \uc218 \uc788\ub294 \ucd5c\uc18c\ud55c\uc758 \ub9ac\ub4ec\uc774\ub77c\ub3c4 \ubd99\uc5ec\uc8fc\uace0 \uc2f6\uc5b4\uc694.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uc5ec\ub294 \ub9d0\uacfc \ub9c8\uc9c0\ub9c9 \ub9d0\uc5d0 \uc791\uc815\ud558\uace0 \ub9c8\uc74c\uc744 \ub2f4\ub294 \uc5f0\uc2b5\uc744 \ud574\ubd05\uc2dc\ub2e4. \uae00\uc758 \uc5b4\ub290 \uad6c\uc11d\uc774\ub77c\ub3c4 \ubed4\ud55c \uae00\uc790\ub294 \ub0a8\uae30\uc9c0 \uc54a\uaca0\ub178\ub77c \ub2e4\uc9d0\ud558\uba70 \uc368\ubcf4\ub294 \uac81\ub2c8\ub2e4. \ub098\ub9cc\uc774 \uac00\uc9c4 \uc720\uc77c\ud55c \uba54\uc2dc\uc9c0\uc5d0 \uc9d1\uc911\ud558\uba74\uc11c\uc694. \uadf8\ub7fc \uc0dd\uac01\uc774 \ub2ec\ub77c\uc9c0\uace0, \uace0\ub974\ub294 \ub2e8\uc5b4\ub3c4 \ub2ec\ub77c\uc9c0\uace0, \ub0a8\uae34 \ubb38\uc7a5\ub3c4 \ub2ec\ub77c\uc838\uc694. \uacb0\uad6d\uc5d0\ub294 \uae00\uc744 \uc4f4 \uc0ac\ub78c\uc778 \ub098 \uc790\uc2e0\ub3c4 \ub0a8\ub2ec\ub77c\uc9c8 \uac81\ub2c8\ub2e4.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\ub9de\ucda4\ubc95\uc740 \uc911\uc694\ud569\ub2c8\ub2e4. \ud558\uc9c0\ub9cc \ub9de\ucda4\ubc95\ubcf4\ub2e4 \ub354 \uc911\uc694\ud55c \uac74 \uac70\uae30\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc785\ub2c8\ub2e4. \ub0b4 \ub9c8\uc74c\uc744 \uae00\uc5d0 \ub2f4\uc544 \uc2e4\uc5b4 \ubcf4\ub0b4\uae30 \uc804, \ub9de\ucda4\ubc95\uc744 \uc810\uac80\ud558\ub294 \uc774\uc720 \uc5ed\uc2dc \uadf8\uac81\ub2c8\ub2e4. \uc624\uc9c1 \ub0b4 \ub9c8\uc74c\uc774 \ub0a8\uc5d0\uac8c \uc77d\ud788\ub294 \ub3d9\uc548 \ubc29\ud574\uac00 \ub418\uc9c0 \uc54a\uae30\ub97c \ubc14\ub77c\uae30 \ub54c\ubb38\uc774\uc8e0. \ub0b4\uac00 \uc4f4 \uae00\ub3c4, \ub0a8\uc774 \uc4f4 \uae00\ub3c4. \uc5b8\uc81c\ub098 \uadf8 \uc548\uc5d0 \ub2f4\uae34 \ub9c8\uc74c\uc774 \uba3c\uc800\uc785\ub2c8\ub2e4.")),(0,o.kt)("blockquote",null,(0,o.kt)("p",{parentName:"blockquote"},"\uae00\uc744 \uc4f4\ub2e4\uace0 \uae00\uc774 \uc644\uc131\ub418\ub294 \uac8c \uc544\ub2c8\uc5d0\uc694. \uae00\uacfc \ub2ee\uc740 \ubaa8\uc2b5\uc73c\ub85c \uc0b4 \ub54c, \uae00\uc740 \ube44\ub85c\uc18c \uc644\uc131\ub429\ub2c8\ub2e4.")))}k.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/fe8cce0a.5b81fa8f.js b/assets/js/fe8cce0a.08ba84b5.js similarity index 84% rename from assets/js/fe8cce0a.5b81fa8f.js rename to assets/js/fe8cce0a.08ba84b5.js index 358b7a42e..bf70724ad 100644 --- a/assets/js/fe8cce0a.5b81fa8f.js +++ b/assets/js/fe8cce0a.08ba84b5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[955],{78535:e=>{e.exports=JSON.parse('{"label":"IntelliJ","permalink":"/tags/intelli-j","allTagsPath":"/tags","count":1}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[955],{78535:e=>{e.exports=JSON.parse('{"label":"IntelliJ","permalink":"/tags/intelli-j","allTagsPath":"/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/fed8bc04.ba13b2b6.js b/assets/js/fed8bc04.4f833fe3.js similarity index 77% rename from assets/js/fed8bc04.ba13b2b6.js rename to assets/js/fed8bc04.4f833fe3.js index 176f1ef0d..0da6c0dee 100644 --- a/assets/js/fed8bc04.ba13b2b6.js +++ b/assets/js/fed8bc04.4f833fe3.js @@ -1 +1 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8110],{96375:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[8110],{96375:e=>{e.exports=JSON.parse('{"label":"Woowahan Techcourse","permalink":"/tags/woowahan-techcourse","allTagsPath":"/tags","count":16,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/ff4c6c5e.8132bff2.js b/assets/js/ff4c6c5e.8132bff2.js new file mode 100644 index 000000000..f506d497c --- /dev/null +++ b/assets/js/ff4c6c5e.8132bff2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[820],{68007:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var r=t(85893),a=t(3905);const i={title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",slug:"java-spring-springboot",tags:["Java","Spring Boot","Spring"]},s=void 0,l={permalink:"/java-spring-springboot",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",source:"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",description:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",date:"2023-07-24T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 24\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Spring Boot",permalink:"/tags/spring-boot"},{label:"Spring",permalink:"/tags/spring"}],readingTime:4.725,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",slug:"java-spring-springboot",tags:["Java","Spring Boot","Spring"]},unlisted:!1,prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",permalink:"/route-image-intro"},nextItem:{title:"\uc6f9\uc18c\ucf13",permalink:"/websocket"}},o={authorsImageUrls:[]},c=[{value:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",id:"\uc790\ubc14-17-\uc2a4\ud504\ub9c1-60-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-31",level:2},{value:"\uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d",id:"\uc790\ubc14-\ubcc0\uacbd-\uc0ac\ud56d",level:2},{value:"Switch Expressions(Java 14)",id:"switch-expressionsjava-14",level:3},{value:"Text Block(Java 15)",id:"text-blockjava-15",level:3},{value:"NPE \uba54\uc2dc\uc9c0(Java 15)",id:"npe-\uba54\uc2dc\uc9c0java-15",level:3},{value:"Record(Java 16)",id:"recordjava-16",level:3},{value:"\ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d",id:"\ucd94\uac00\uc801\uc778-\ubcc0\uacbd\uc0ac\ud56d",level:3},{value:"\uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ubcc0\uacbd-\uc0ac\ud56d",level:2},{value:"\uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd",id:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4-\ubcc0\uacbd",level:3},{value:"PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c",id:"pathpatternparser---trailing-slash-\ud5c8\uc6a9\ud558\uc9c0-\uc54a\uc74c",level:3},{value:"HTTP interface client",id:"http-interface-client",level:3},{value:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ucd5c\uc18c-\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}];function h(e){const n={a:"a",blockquote:"blockquote",br:"br",code:"code",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.ah)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"\uc790\ubc14-17-\uc2a4\ud504\ub9c1-60-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-31",children:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1"}),"\n",(0,r.jsxs)(n.p,{children:["\ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1\uc744 \uc0ac\uc6a9\ud558\uac8c \ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","2.7 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud560 \uc218\ub3c4 \uc788\uc5c8\uc9c0\ub9cc LTS \uae30\uac04\uacfc \ucde8\uc57d\uc810 \ud328\uce58\ub85c \uc778\ud55c \ubc84\uc804\uc5c5 \ub4f1\uc744 \uace0\ub824\ud588\uc744 \ub54c 3.1\uacfc \uc790\ubc14 17\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \ub354 \ud6a8\uc728\uc801\uc774\ub77c\uace0 \ud310\ub2e8\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\uc790\ubc14-\ubcc0\uacbd-\uc0ac\ud56d",children:"\uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d"}),"\n",(0,r.jsxs)(n.p,{children:["\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2\uae4c\uc9c0\ub294 \uc790\ubc14 11\uc744 \uc0ac\uc6a9\ud588\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \uc790\ubc14 11\ubd80\ud130 \uc790\ubc14 17\uae4c\uc9c0\uc758 \ubcc0\uacbd\uc0ac\ud56d\uc744 \uc815\uc2dd \ub9b4\ub9ac\uc988 \uae30\uc900\uc73c\ub85c \uc815\ub9ac\ud574\ubcf4\ub824\uace0 \ud55c\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"switch-expressionsjava-14",children:"Switch Expressions(Java 14)"}),"\n",(0,r.jsx)(n.p,{children:"Java 14\uc5d0\uc11c\ub294 \uae30\uc874\uc758 Switch \ubb38\uc744 \uac04\uacb0\ud558\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub294 Switch \uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"enum RESULT {\n WIN, LOSE, DRAW\n}\n\nRESULT result = RESULT.WIN;\n\nint prize = switch (result) {\n case WIN -> 10_000_000;\n case LOSE, DRAW -> 5_000_000;\n\tdefault -> 0;\n};\n"})}),"\n",(0,r.jsx)(n.p,{children:"\uc8fc\uc694 \ud2b9\uc9d5\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"->"})," \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 case\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc14\ub85c \ubc18\ud658\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsxs)(n.li,{children:["case\ub97c \ucf64\ub9c8(",(0,r.jsx)(n.code,{children:","}),")\ub85c \uc5f0\uacb0\ud558\uc5ec \ud558\ub098\uc758 case\uc5d0 \uc5ec\ub7ec \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.li,{children:"break \ubb38\uc774 \ud544\uc694 \uc5c6\ub2e4."}),"\n",(0,r.jsx)(n.li,{children:"default \ube14\ub85d\uc744 \ud1b5\ud574 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"text-blockjava-15",children:"Text Block(Java 15)"}),"\n",(0,r.jsxs)(n.p,{children:["Java 15\uc5d0\ub294 \uc0c8\ub85c\uc6b4 \ubb38\uc790\uc5f4 \ud45c\ud604\ubc29\uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uae34 \ubb38\uc790\uc5f4\uc744 + \uc5f0\uc0b0\uc790\uc758 \ub3c4\uc6c0 \uc5c6\uc774 \uac00\ub3c5\uc131\uc788\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'@Repository\npublic interface PostRepository extends JpaRepository<Post, Long> {\n @Query("""\n SELECT p FROM Post p\n WHERE p.title LIKE %:keyword%\n OR p.content LIKE %:keyword%\n """)\n List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);\n}\n'})}),"\n",(0,r.jsx)(n.h3,{id:"npe-\uba54\uc2dc\uc9c0java-15",children:"NPE \uba54\uc2dc\uc9c0(Java 15)"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:'String name = null;\nname.chars();\n\n/** \n# before\njava.lang.NullPointerException\n\tat com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)\n\n# after\nCannot invoke "String.chars()" because "name" is null\njava.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null\n*/\n'})}),"\n",(0,r.jsx)(n.h3,{id:"recordjava-16",children:"Record(Java 16)"}),"\n",(0,r.jsxs)(n.p,{children:["Lombok\uc758 ",(0,r.jsx)(n.code,{children:"@Data"}),", kotlin\uc758 data \ud074\ub798\uc2a4\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","Record\ub97c \uc120\uc5b8\ud558\ub294 \uacbd\uc6b0 \uc811\uadfc\uc790, \uc0dd\uc131\uc790, equals & hashcode, toString\uc774 \uc81c\uacf5\ub41c\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub370\uc774\ud130 \uc804\uc1a1 \uc6a9\ub3c4\ub85c \uc801\ud569\ud574 \ubcf4\uc778\ub2e4."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-java",children:"public record PostDto(String title, String content) {\n}\n"})}),"\n",(0,r.jsx)(n.h3,{id:"\ucd94\uac00\uc801\uc778-\ubcc0\uacbd\uc0ac\ud56d",children:"\ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d"}),"\n",(0,r.jsx)(n.p,{children:"\uc774\uc678\uc5d0\ub3c4 stream\uc758 toList, \uc778\uc2a4\ud134\uc2a4\uc758 \ud0c0\uc785\uc744 \uac04\ud3b8\ud558\uac8c \uccb4\ud06c\ud558\ub294 Pattern Matching Instanceof, Sealed class \ub4f1\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.h2,{id:"\uc2a4\ud504\ub9c1-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ubcc0\uacbd-\uc0ac\ud56d",children:"\uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d"}),"\n",(0,r.jsxs)(n.p,{children:["\uc2a4\ud504\ub9c1\uacfc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\ub3c4 \ub9ce\uc740 \ubcc0\uacbd \uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\ub530\ub77c\uc11c \ud544\uc694\ud574\ubcf4\uc774\ub294 \uba87\uac1c \uc815\ub3c4\ub9cc \uc815\ub9ac\ud588\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc2a4\ud504\ub9c1-\uc694\uad6c\uc0ac\ud56d",children:"\uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d"}),"\n",(0,r.jsx)(n.p,{children:"Java 17, Jakarta EE 9 \uc774\uc0c1\uc774\uc5b4\uc57c \ud55c\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4-\ubcc0\uacbd",children:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd"}),"\n",(0,r.jsx)(n.p,{children:"Jakarta EE 9\uac00 \uc801\uc6a9\ub418\uba74\uc11c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub3c4 \uc804\ubc18\uc801\uc73c\ub85c javax -> jakarta\ub85c \ubcc0\uacbd\ub418\uc5c8\ub2e4."}),"\n",(0,r.jsx)(n.h3,{id:"pathpatternparser---trailing-slash-\ud5c8\uc6a9\ud558\uc9c0-\uc54a\uc74c",children:"PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c"}),"\n",(0,r.jsxs)(n.p,{children:["6.0 \uc774\uc804\uc758 \uacbd\uc6b0 \uae30\ubcf8 \uc124\uc815 \uae30\uc900\uc73c\ub85c ",(0,r.jsx)(n.code,{children:'@GetMapping("/hello")'}),"\uc640 ",(0,r.jsx)(n.code,{children:'@GetMapping("/hello/")'}),"\uac00 \ub3d9\uc77c\ud588\ub2e4.",(0,r.jsx)(n.br,{}),"\n","6.0 \uc774\ud6c4\uc758 PathPatternParser\uac00 \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\uace0, ",(0,r.jsx)(n.code,{children:"/hello"}),"\uc640 ",(0,r.jsx)(n.code,{children:"/hello/"}),"\ub294 \uc11c\ub85c \ub2e4\ub978 URL\ub85c \ub9e4\uce6d\ub41c\ub2e4."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:"PathPatternParser used by default (with the ability to opt into PathMatcher)."}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"http-interface-client",children:"HTTP interface client"}),"\n",(0,r.jsxs)(n.p,{children:["\uc790\ubc14 \uc778\ud130\ud398\uc774\uc2a4\uc640 \uc5b4\ub178\ud14c\uc774\uc158\uc744 \uc774\uc6a9\ud558\uc5ec HTTP \uc694\uccad\uc744 \uc704\ud55c \uc11c\ube44\uc2a4\ub97c \uc815\uc758\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,r.jsx)(n.br,{}),"\n","\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 ",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=Kb37Q5GCyZs",children:"\ud1a0\ube44\ub2d8\uc758 \uac15\uc758"}),"\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsx)(n.h3,{id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ucd5c\uc18c-\uc694\uad6c\uc0ac\ud56d",children:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d"}),"\n",(0,r.jsxs)(n.p,{children:["Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6",(0,r.jsx)(n.br,{}),"\n","\uc774\uc678\uc5d0\ub3c4 \uc11c\ub4dc\ud30c\ud2f0\ub4e4\uc758 \ucd5c\uc2e0 \ub9b4\ub9ac\uc988 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c, \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ud574\ub2f9 \ubc84\uc804\uc5d0 \ub9de\ub294 \ub9b4\ub9ac\uc988 \ub178\ud2b8\ub97c \ucc38\uace0\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4."]}),"\n",(0,r.jsx)(n.h2,{id:"\ucc38\uace0-\uc790\ub8cc",children:"\ucc38\uace0 \uc790\ub8cc"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=1WT6oxchM9M",children:"\uc5b4\ub290\xa0\uc6d4\uae09\uc7c1\uc774\uac1c\ubc1c\uc790\xa0\uc758 \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ub530\ub77c\uc7a1\uae30"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=7SlDdzVk6GE",children:"\uc790\ubc14 9-16 \uc8fc\uc694 \ud2b9\uc9d5 \ubcf5\uc2b5\ud558\uae30"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.samsungsds.com/kr/insights/java_jakarta.html",children:"Java EE\uc5d0\uc11c Jakarta EE\ub85c\uc758 \uc804\ud658"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://www.youtube.com/watch?v=Kb37Q5GCyZs",children:"Spring 6\uc758 \uc0c8\ub85c\uc6b4 HTTP Interface\uc640 3 \uac00\uc9c0 REST Clients \ub77c\uc774\ube0c \ucf54\ub529"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x",children:"What's New in Spring Framework 6.x"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes",children:"Spring Boot 3.0 Release Notes"}),(0,r.jsx)(n.br,{}),"\n",(0,r.jsx)(n.a,{href:"https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes",children:"Spring Boot 3.1 Release Notes"})]})]})}function d(e={}){const{wrapper:n}={...(0,a.ah)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},3905:(e,n,t)=>{t.d(n,{ah:()=>c});var r=t(67294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?i(Object(t),!0).forEach((function(n){a(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):i(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function l(e,n){if(null==e)return{};var t,r,a=function(e,n){if(null==e)return{};var t,r,a={},i=Object.keys(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var o=r.createContext({}),c=function(e){var n=r.useContext(o),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},h={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,o=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=c(t),j=a,u=p["".concat(o,".").concat(j)]||p[j]||h[j]||i;return t?r.createElement(u,s(s({ref:n},d),{},{components:t})):r.createElement(u,s({ref:n},d))}));d.displayName="MDXCreateElement"}}]); \ No newline at end of file diff --git a/assets/js/ff4c6c5e.cbf81af0.js b/assets/js/ff4c6c5e.cbf81af0.js deleted file mode 100644 index 277f99db9..000000000 --- a/assets/js/ff4c6c5e.cbf81af0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[820],{3905:(e,t,a)=>{a.d(t,{Zo:()=>c,kt:()=>m});var n=a(67294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function l(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t<arguments.length;t++){var a=null!=arguments[t]?arguments[t]:{};t%2?l(Object(a),!0).forEach((function(t){r(e,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(a)):l(Object(a)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(a,t))}))}return e}function p(e,t){if(null==e)return{};var a,n,r=function(e,t){if(null==e)return{};var a,n,r={},l=Object.keys(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n<l.length;n++)a=l[n],t.indexOf(a)>=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var o=n.createContext({}),s=function(e){var t=n.useContext(o),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},c=function(e){var t=s(e.components);return n.createElement(o.Provider,{value:t},e.children)},u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},k=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,l=e.originalType,o=e.parentName,c=p(e,["components","mdxType","originalType","parentName"]),k=s(a),m=r,g=k["".concat(o,".").concat(m)]||k[m]||u[m]||l;return a?n.createElement(g,i(i({ref:t},c),{},{components:a})):n.createElement(g,i({ref:t},c))}));function m(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var l=a.length,i=new Array(l);i[0]=k;var p={};for(var o in t)hasOwnProperty.call(t,o)&&(p[o]=t[o]);p.originalType=e,p.mdxType="string"==typeof e?e:r,i[1]=p;for(var s=2;s<l;s++)i[s]=a[s];return n.createElement.apply(null,i)}return n.createElement.apply(null,a)}k.displayName="MDXCreateElement"},23856:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>l,metadata:()=>p,toc:()=>s});var n=a(87462),r=(a(67294),a(3905));const l={title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",slug:"java-spring-springboot",tags:["Java","Spring Boot","Spring"]},i=void 0,p={permalink:"/java-spring-springboot",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",source:"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",description:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",date:"2023-07-24T00:00:00.000Z",formattedDate:"2023\ub144 7\uc6d4 24\uc77c",tags:[{label:"Java",permalink:"/tags/java"},{label:"Spring Boot",permalink:"/tags/spring-boot"},{label:"Spring",permalink:"/tags/spring"}],readingTime:4.725,hasTruncateMarker:!1,authors:[],frontMatter:{title:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",slug:"java-spring-springboot",tags:["Java","Spring Boot","Spring"]},prevItem:{title:"\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd",permalink:"/route-image-intro"},nextItem:{title:"\uc6f9\uc18c\ucf13",permalink:"/websocket"}},o={authorsImageUrls:[]},s=[{value:"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1",id:"\uc790\ubc14-17-\uc2a4\ud504\ub9c1-60-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-31",level:2},{value:"\uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d",id:"\uc790\ubc14-\ubcc0\uacbd-\uc0ac\ud56d",level:2},{value:"Switch Expressions(Java 14)",id:"switch-expressionsjava-14",level:3},{value:"Text Block(Java 15)",id:"text-blockjava-15",level:3},{value:"NPE \uba54\uc2dc\uc9c0(Java 15)",id:"npe-\uba54\uc2dc\uc9c0java-15",level:3},{value:"Record(Java 16)",id:"recordjava-16",level:3},{value:"\ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d",id:"\ucd94\uac00\uc801\uc778-\ubcc0\uacbd\uc0ac\ud56d",level:3},{value:"\uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ubcc0\uacbd-\uc0ac\ud56d",level:2},{value:"\uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd",id:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4-\ubcc0\uacbd",level:3},{value:"PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c",id:"pathpatternparser---trailing-slash-\ud5c8\uc6a9\ud558\uc9c0-\uc54a\uc74c",level:3},{value:"HTTP interface client",id:"http-interface-client",level:3},{value:"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d",id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ucd5c\uc18c-\uc694\uad6c\uc0ac\ud56d",level:3},{value:"\ucc38\uace0 \uc790\ub8cc",id:"\ucc38\uace0-\uc790\ub8cc",level:2}],c={toc:s};function u(e){let{components:t,...a}=e;return(0,r.kt)("wrapper",(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"\uc790\ubc14-17-\uc2a4\ud504\ub9c1-60-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-31"},"\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1"),(0,r.kt)("p",null,"\ud300 \ud504\ub85c\uc81d\ud2b8\ub97c \uc9c4\ud589\ud558\uba74\uc11c \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1\uc744 \uc0ac\uc6a9\ud558\uac8c \ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","2.7 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud560 \uc218\ub3c4 \uc788\uc5c8\uc9c0\ub9cc LTS \uae30\uac04\uacfc \ucde8\uc57d\uc810 \ud328\uce58\ub85c \uc778\ud55c \ubc84\uc804\uc5c5 \ub4f1\uc744 \uace0\ub824\ud588\uc744 \ub54c 3.1\uacfc \uc790\ubc14 17\uc744 \uc0ac\uc6a9\ud558\ub294 \uac83\uc774 \ub354 \ud6a8\uc728\uc801\uc774\ub77c\uace0 \ud310\ub2e8\ud588\ub2e4."),(0,r.kt)("h2",{id:"\uc790\ubc14-\ubcc0\uacbd-\uc0ac\ud56d"},"\uc790\ubc14 \ubcc0\uacbd \uc0ac\ud56d"),(0,r.kt)("p",null,"\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca8 2\uae4c\uc9c0\ub294 \uc790\ubc14 11\uc744 \uc0ac\uc6a9\ud588\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \uc790\ubc14 11\ubd80\ud130 \uc790\ubc14 17\uae4c\uc9c0\uc758 \ubcc0\uacbd\uc0ac\ud56d\uc744 \uc815\uc2dd \ub9b4\ub9ac\uc988 \uae30\uc900\uc73c\ub85c \uc815\ub9ac\ud574\ubcf4\ub824\uace0 \ud55c\ub2e4."),(0,r.kt)("h3",{id:"switch-expressionsjava-14"},"Switch Expressions(Java 14)"),(0,r.kt)("p",null,"Java 14\uc5d0\uc11c\ub294 \uae30\uc874\uc758 Switch \ubb38\uc744 \uac04\uacb0\ud558\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub294 Switch \uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"enum RESULT {\n WIN, LOSE, DRAW\n}\n\nRESULT result = RESULT.WIN;\n\nint prize = switch (result) {\n case WIN -> 10_000_000;\n case LOSE, DRAW -> 5_000_000;\n default -> 0;\n};\n")),(0,r.kt)("p",null,"\uc8fc\uc694 \ud2b9\uc9d5\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4."),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("inlineCode",{parentName:"li"},"->")," \uc5f0\uc0b0\uc790\ub97c \uc774\uc6a9\ud558\uc5ec \uac01 case\uc5d0 \ub300\ud55c \uacb0\uacfc\ub97c \ubc14\ub85c \ubc18\ud658\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"case\ub97c \ucf64\ub9c8(",(0,r.kt)("inlineCode",{parentName:"li"},","),")\ub85c \uc5f0\uacb0\ud558\uc5ec \ud558\ub098\uc758 case\uc5d0 \uc5ec\ub7ec \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"break \ubb38\uc774 \ud544\uc694 \uc5c6\ub2e4."),(0,r.kt)("li",{parentName:"ul"},"default \ube14\ub85d\uc744 \ud1b5\ud574 \uae30\ubcf8 \uac12\uc744 \uc9c0\uc815\ud560 \uc218 \uc788\ub2e4.")),(0,r.kt)("h3",{id:"text-blockjava-15"},"Text Block(Java 15)"),(0,r.kt)("p",null,"Java 15\uc5d0\ub294 \uc0c8\ub85c\uc6b4 \ubb38\uc790\uc5f4 \ud45c\ud604\ubc29\uc2dd\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uae34 \ubb38\uc790\uc5f4\uc744 + \uc5f0\uc0b0\uc790\uc758 \ub3c4\uc6c0 \uc5c6\uc774 \uac00\ub3c5\uc131\uc788\uac8c \uc791\uc131\ud560 \uc218 \uc788\ub2e4."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},'@Repository\npublic interface PostRepository extends JpaRepository<Post, Long> {\n @Query("""\n SELECT p FROM Post p\n WHERE p.title LIKE %:keyword%\n OR p.content LIKE %:keyword%\n """)\n List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);\n}\n')),(0,r.kt)("h3",{id:"npe-\uba54\uc2dc\uc9c0java-15"},"NPE \uba54\uc2dc\uc9c0(Java 15)"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},'String name = null;\nname.chars();\n\n/** \n# before\njava.lang.NullPointerException\n at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)\n\n# after\nCannot invoke "String.chars()" because "name" is null\njava.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null\n*/\n')),(0,r.kt)("h3",{id:"recordjava-16"},"Record(Java 16)"),(0,r.kt)("p",null,"Lombok\uc758 ",(0,r.kt)("inlineCode",{parentName:"p"},"@Data"),", kotlin\uc758 data \ud074\ub798\uc2a4\uc640 \uc720\uc0ac\ud55c \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","Record\ub97c \uc120\uc5b8\ud558\ub294 \uacbd\uc6b0 \uc811\uadfc\uc790, \uc0dd\uc131\uc790, equals & hashcode, toString\uc774 \uc81c\uacf5\ub41c\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub370\uc774\ud130 \uc804\uc1a1 \uc6a9\ub3c4\ub85c \uc801\ud569\ud574 \ubcf4\uc778\ub2e4. "),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-java"},"public record PostDto(String title, String content) {\n}\n")),(0,r.kt)("h3",{id:"\ucd94\uac00\uc801\uc778-\ubcc0\uacbd\uc0ac\ud56d"},"\ucd94\uac00\uc801\uc778 \ubcc0\uacbd\uc0ac\ud56d"),(0,r.kt)("p",null,"\uc774\uc678\uc5d0\ub3c4 stream\uc758 toList, \uc778\uc2a4\ud134\uc2a4\uc758 \ud0c0\uc785\uc744 \uac04\ud3b8\ud558\uac8c \uccb4\ud06c\ud558\ub294 Pattern Matching Instanceof, Sealed class \ub4f1\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4. "),(0,r.kt)("h2",{id:"\uc2a4\ud504\ub9c1-\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ubcc0\uacbd-\uc0ac\ud56d"},"\uc2a4\ud504\ub9c1, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ubcc0\uacbd \uc0ac\ud56d"),(0,r.kt)("p",null,"\uc2a4\ud504\ub9c1\uacfc \uc2a4\ud504\ub9c1 \ubd80\ud2b8\uc5d0\ub3c4 \ub9ce\uc740 \ubcc0\uacbd \uc0ac\ud56d\uc774 \uc788\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\ub530\ub77c\uc11c \ud544\uc694\ud574\ubcf4\uc774\ub294 \uba87\uac1c \uc815\ub3c4\ub9cc \uc815\ub9ac\ud588\ub2e4. "),(0,r.kt)("h3",{id:"\uc2a4\ud504\ub9c1-\uc694\uad6c\uc0ac\ud56d"},"\uc2a4\ud504\ub9c1 \uc694\uad6c\uc0ac\ud56d"),(0,r.kt)("p",null,"Java 17, Jakarta EE 9 \uc774\uc0c1\uc774\uc5b4\uc57c \ud55c\ub2e4."),(0,r.kt)("h3",{id:"\ub124\uc784\uc2a4\ud398\uc774\uc2a4-\ubcc0\uacbd"},"\ub124\uc784\uc2a4\ud398\uc774\uc2a4 \ubcc0\uacbd"),(0,r.kt)("p",null,"Jakarta EE 9\uac00 \uc801\uc6a9\ub418\uba74\uc11c \ub124\uc784\uc2a4\ud398\uc774\uc2a4\ub3c4 \uc804\ubc18\uc801\uc73c\ub85c javax -> jakarta\ub85c \ubcc0\uacbd\ub418\uc5c8\ub2e4. "),(0,r.kt)("h3",{id:"pathpatternparser---trailing-slash-\ud5c8\uc6a9\ud558\uc9c0-\uc54a\uc74c"},"PathPatternParser - trailing slash \ud5c8\uc6a9\ud558\uc9c0 \uc54a\uc74c"),(0,r.kt)("p",null,"6.0 \uc774\uc804\uc758 \uacbd\uc6b0 \uae30\ubcf8 \uc124\uc815 \uae30\uc900\uc73c\ub85c ",(0,r.kt)("inlineCode",{parentName:"p"},'@GetMapping("/hello")'),"\uc640 ",(0,r.kt)("inlineCode",{parentName:"p"},'@GetMapping("/hello/")'),"\uac00 \ub3d9\uc77c\ud588\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","6.0 \uc774\ud6c4\uc758 PathPatternParser\uac00 \uae30\ubcf8\uc73c\ub85c \uc0ac\uc6a9\ub418\uace0, ",(0,r.kt)("inlineCode",{parentName:"p"},"/hello"),"\uc640 ",(0,r.kt)("inlineCode",{parentName:"p"},"/hello/"),"\ub294 \uc11c\ub85c \ub2e4\ub978 URL\ub85c \ub9e4\uce6d\ub41c\ub2e4. "),(0,r.kt)("blockquote",null,(0,r.kt)("p",{parentName:"blockquote"},"PathPatternParser used by default (with the ability to opt into PathMatcher). ")),(0,r.kt)("h3",{id:"http-interface-client"},"HTTP interface client"),(0,r.kt)("p",null,"\uc790\ubc14 \uc778\ud130\ud398\uc774\uc2a4\uc640 \uc5b4\ub178\ud14c\uc774\uc158\uc744 \uc774\uc6a9\ud558\uc5ec HTTP \uc694\uccad\uc744 \uc704\ud55c \uc11c\ube44\uc2a4\ub97c \uc815\uc758\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc774 \ucd94\uac00\ub418\uc5c8\ub2e4.",(0,r.kt)("br",{parentName:"p"}),"\n","\uc790\uc138\ud55c \ub0b4\uc6a9\uc740 ",(0,r.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=Kb37Q5GCyZs"},"\ud1a0\ube44\ub2d8\uc758 \uac15\uc758"),"\ub97c \ucc38\uace0\ud558\uba74 \uc88b\uc744 \uac83 \uac19\ub2e4."),(0,r.kt)("h3",{id:"\uc2a4\ud504\ub9c1-\ubd80\ud2b8-\ucd5c\uc18c-\uc694\uad6c\uc0ac\ud56d"},"\uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ucd5c\uc18c \uc694\uad6c\uc0ac\ud56d"),(0,r.kt)("p",null,"Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6",(0,r.kt)("br",{parentName:"p"}),"\n","\uc774\uc678\uc5d0\ub3c4 \uc11c\ub4dc\ud30c\ud2f0\ub4e4\uc758 \ucd5c\uc2e0 \ub9b4\ub9ac\uc988 \ubc84\uc804\uc744 \uc0ac\uc6a9\ud568\uc73c\ub85c, \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\ub294 \uacbd\uc6b0 \ud574\ub2f9 \ubc84\uc804\uc5d0 \ub9de\ub294 \ub9b4\ub9ac\uc988 \ub178\ud2b8\ub97c \ucc38\uace0\ud560 \uc218 \uc788\uc744 \uac83 \uac19\ub2e4. "),(0,r.kt)("h2",{id:"\ucc38\uace0-\uc790\ub8cc"},"\ucc38\uace0 \uc790\ub8cc"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=1WT6oxchM9M"},"\uc5b4\ub290\xa0\uc6d4\uae09\uc7c1\uc774\uac1c\ubc1c\uc790\xa0\uc758 \uc2a4\ud504\ub9c1 \ubd80\ud2b8 \ub530\ub77c\uc7a1\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=7SlDdzVk6GE"},"\uc790\ubc14 9-16 \uc8fc\uc694 \ud2b9\uc9d5 \ubcf5\uc2b5\ud558\uae30"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.samsungsds.com/kr/insights/java_jakarta.html"},"Java EE\uc5d0\uc11c Jakarta EE\ub85c\uc758 \uc804\ud658"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://www.youtube.com/watch?v=Kb37Q5GCyZs"},"Spring 6\uc758 \uc0c8\ub85c\uc6b4 HTTP Interface\uc640 3 \uac00\uc9c0 REST Clients \ub77c\uc774\ube0c \ucf54\ub529"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x"},"What's New in Spring Framework 6.x"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes"},"Spring Boot 3.0 Release Notes"),(0,r.kt)("br",{parentName:"p"}),"\n",(0,r.kt)("a",{parentName:"p",href:"https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes"},"Spring Boot 3.1 Release Notes")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.8092b600.js b/assets/js/main.8092b600.js deleted file mode 100644 index f8e245602..000000000 --- a/assets/js/main.8092b600.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.8092b600.js.LICENSE.txt */ -(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[179],{20830:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});var a=n(67294);function r(){return a.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},a.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var a=n(67294),r=n(87462),o=n(68356),i=n.n(o),s=n(16887);const l={"00931cc3":[()=>n.e(5669).then(n.t.bind(n,92291,19)),"~blog/default/page-30-25c.json",92291],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,24524)),"@theme/BlogTagsListPage",24524],"02689328":[()=>n.e(6346).then(n.t.bind(n,5577,19)),"~blog/default/tags-data-base-page-3-9db.json",5577],"0281109c":[()=>n.e(422).then(n.t.bind(n,25266,19)),"~blog/default/tags-jenkins-2e5-list.json",25266],"02ede3c9":[()=>n.e(4934).then(n.t.bind(n,51226,19)),"~blog/default/tags-retrospective-page-18-40f.json",51226],"04644f5f":[()=>n.e(2625).then(n.bind(n,73787)),"@site/docs/\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00.mdx",73787],"04c55e47":[()=>n.e(4275).then(n.t.bind(n,26888,19)),"~blog/default/page-49-c29.json",26888],"051528db":[()=>n.e(5753).then(n.bind(n,85742)),"@site/docs/\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815.md",85742],"0571a526":[()=>n.e(6204).then(n.bind(n,77397)),"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",77397],"05b907fc":[()=>n.e(734).then(n.t.bind(n,92943,19)),"~blog/default/tags-retrospective-page-8-5ab-list.json",92943],"0746167d":[()=>n.e(1113).then(n.t.bind(n,19758,19)),"~blog/default/tags-elastic-beanstalk-119-list.json",19758],"08726fcf":[()=>n.e(5487).then(n.t.bind(n,38441,19)),"~blog/default/tags-java-page-4-c22-list.json",38441],"087c46fa":[()=>n.e(96).then(n.t.bind(n,25774,19)),"~blog/default/tags-spring-boot-889.json",25774],"08e37dbc":[()=>n.e(1328).then(n.bind(n,10634)),"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",10634],"09fbb6bd":[()=>n.e(5964).then(n.t.bind(n,41679,19)),"~blog/default/page-16-d6c.json",41679],"0a2eaa84":[()=>n.e(8942).then(n.t.bind(n,52930,19)),"~blog/default/tags-data-base-4e8.json",52930],"0c071de2":[()=>n.e(321).then(n.t.bind(n,23125,19)),"~blog/default/page-2-b45.json",23125],"0c390f0d":[()=>n.e(6550).then(n.t.bind(n,13321,19)),"~blog/default/tags-retrospective-page-19-af8.json",13321],"0cb009d1":[()=>n.e(116).then(n.t.bind(n,66643,19)),"~blog/default/tags-event-f04.json",66643],"0e33a907":[()=>n.e(3092).then(n.bind(n,81204)),"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx?truncated=true",81204],"101b58de":[()=>n.e(6084).then(n.bind(n,67365)),"@site/blog/2023-1/2023-01-08-JSR-310.mdx",67365],"101cf32b":[()=>n.e(9239).then(n.t.bind(n,30880,19)),"~blog/default/page-45-7ec.json",30880],"1236fad7":[()=>n.e(6515).then(n.bind(n,25088)),"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",25088],"1251d98b":[()=>n.e(6276).then(n.bind(n,25075)),"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",25075],"12cbeba7":[()=>n.e(6508).then(n.t.bind(n,16134,19)),"~blog/default/page-29-e3c.json",16134],"130df38c":[()=>n.e(6493).then(n.bind(n,46963)),"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",46963],"1398b403":[()=>n.e(5652).then(n.t.bind(n,93561,19)),"~blog/default/tags-retrospective-page-20-737.json",93561],14164549:[()=>n.e(7268).then(n.t.bind(n,11279,19)),"~blog/default/tags-book-baf-list.json",11279],"14dc1923":[()=>n.e(7403).then(n.bind(n,25731)),"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",25731],"15eddcef":[()=>n.e(4209).then(n.t.bind(n,28539,19)),"~blog/default/page-47-adb.json",28539],"15f27552":[()=>n.e(1079).then(n.t.bind(n,11539,19)),"~blog/default/tags-retrospective-page-19-af8-list.json",11539],"1664646a":[()=>n.e(8036).then(n.bind(n,46657)),"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx?truncated=true",46657],"16cc6f3a":[()=>n.e(425).then(n.t.bind(n,12946,19)),"~blog/default/tags-retrospective-page-15-26b.json",12946],"16f719ab":[()=>n.e(9875).then(n.bind(n,83377)),"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",83377],"1781b1c4":[()=>n.e(5785).then(n.bind(n,10945)),"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",10945],17896441:[()=>Promise.all([n.e(532),n.e(4),n.e(7918)]).then(n.bind(n,78945)),"@theme/DocItem",78945],"1893cb59":[()=>n.e(286).then(n.t.bind(n,16269,19)),"~blog/default/tags-java-page-2-8c6.json",16269],"18c69d70":[()=>n.e(9171).then(n.t.bind(n,7085,19)),"/home/runner/work/greeng00se.github.io/greeng00se.github.io/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],"198f8d8a":[()=>n.e(9059).then(n.t.bind(n,17238,19)),"~blog/default/tags-java-page-3-b02-list.json",17238],"19f4ae8e":[()=>n.e(8161).then(n.t.bind(n,25680,19)),"~blog/default/tags-log-5ad.json",25680],"1a3abee6":[()=>n.e(5035).then(n.t.bind(n,87753,19)),"~blog/default/tags-retrospective-page-17-636.json",87753],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,39172)),"@theme/SearchPage",39172],"1a665c6f":[()=>n.e(454).then(n.t.bind(n,28767,19)),"~blog/default/tags-test-435-list.json",28767],"1a6b9123":[()=>n.e(9874).then(n.t.bind(n,14343,19)),"~blog/default/tags-teco-chat-page-3-007.json",14343],"1bb997fc":[()=>n.e(9713).then(n.t.bind(n,66014,19)),"~blog/default/page-44-cef.json",66014],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,19963)),"@theme/DocPage",19963],"1c93669b":[()=>n.e(6526).then(n.t.bind(n,37579,19)),"~docs/default/tag-docs-tags-monitoring-149.json",37579],"1d81daa1":[()=>n.e(7681).then(n.t.bind(n,76725,19)),"~blog/default/tags-mock-330.json",76725],"1e8ecffe":[()=>n.e(3333).then(n.bind(n,54141)),"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",54141],"1f05d14a":[()=>Promise.all([n.e(532),n.e(656)]).then(n.bind(n,65945)),"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx?truncated=true",65945],"1f61820a":[()=>n.e(2233).then(n.bind(n,16432)),"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx?truncated=true",16432],"1fbde614":[()=>n.e(8243).then(n.t.bind(n,87304,19)),"~blog/default/tags-monitoring-a8a-list.json",87304],"20e99c2a":[()=>n.e(3530).then(n.t.bind(n,19507,19)),"~blog/default/tags-documentation-ee3-list.json",19507],"211d6170":[()=>n.e(3109).then(n.t.bind(n,41078,19)),"~docs/default/tag-docs-tags-package-d2b.json",41078],"21294bbb":[()=>n.e(9412).then(n.bind(n,86182)),"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",86182],"21d253a0":[()=>n.e(1853).then(n.t.bind(n,63986,19)),"~blog/default/tags-woowahan-techcourse-page-10-f03-list.json",63986],"21e890b0":[()=>n.e(8288).then(n.t.bind(n,551,19)),"~blog/default/tags-retrospective-page-14-99d-list.json",551],"226700de":[()=>n.e(6035).then(n.t.bind(n,41961,19)),"~blog/default/page-25-52d.json",41961],"24b9bc70":[()=>n.e(5798).then(n.bind(n,8518)),"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",8518],"255134d9":[()=>n.e(8151).then(n.t.bind(n,30753,19)),"~blog/default/tags-composite-240.json",30753],"269a2f75":[()=>n.e(1994).then(n.t.bind(n,52358,19)),"~blog/default/tags-static-b68.json",52358],"26dc40bf":[()=>n.e(5237).then(n.bind(n,97783)),"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx?truncated=true",97783],"270346fa":[()=>n.e(7975).then(n.t.bind(n,89424,19)),"~blog/default/page-28-907.json",89424],"274c9143":[()=>n.e(6984).then(n.t.bind(n,90058,19)),"~blog/default/tags-java-a6e.json",90058],"280572f1":[()=>n.e(324).then(n.t.bind(n,77874,19)),"~blog/default/tags-mysql-331.json",77874],"2832e534":[()=>n.e(2476).then(n.t.bind(n,69870,19)),"~blog/default/page-13-99f.json",69870],"28a1570f":[()=>n.e(448).then(n.t.bind(n,92252,19)),"~blog/default/tags-elastic-beanstalk-119.json",92252],"290b0a56":[()=>n.e(4212).then(n.bind(n,82544)),"@site/docs/Java/SequencedCollection.mdx",82544],"2a8faff0":[()=>n.e(7901).then(n.t.bind(n,1150,19)),"~blog/default/tags-test-435.json",1150],"2b22d492":[()=>n.e(7652).then(n.t.bind(n,56986,19)),"~blog/default/tags-retrospective-page-3-ee4-list.json",56986],"2b479afe":[()=>n.e(9591).then(n.t.bind(n,16973,19)),"~blog/default/tags-mockito-3c0-list.json",16973],"2bfe7c0b":[()=>n.e(1762).then(n.t.bind(n,82670,19)),"~blog/default/tags-book-page-2-bc6.json",82670],"2c446262":[()=>n.e(7797).then(n.t.bind(n,16402,19)),"~docs/default/tag-docs-tags-collection-64e.json",16402],"2c9f5501":[()=>n.e(7775).then(n.bind(n,73917)),"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx?truncated=true",73917],"2d3b202f":[()=>n.e(1196).then(n.t.bind(n,42524,19)),"~blog/default/tags-book-baf.json",42524],"2d9296e4":[()=>n.e(3483).then(n.t.bind(n,89429,19)),"~blog/default/tags-pattern-b4e.json",89429],"2e10a69c":[()=>n.e(7581).then(n.t.bind(n,9981,19)),"~blog/default/page-38-d34.json",9981],"2f43e44a":[()=>n.e(6743).then(n.t.bind(n,52396,19)),"~blog/default/tags-grasp-418-list.json",52396],"302370be":[()=>n.e(1883).then(n.bind(n,91867)),"@site/docs/\ud14c\uc2a4\ud2b8/FIRST.mdx",91867],"303c1e60":[()=>n.e(2656).then(n.t.bind(n,39529,19)),"~blog/default/tags-retrospective-page-4-3a3.json",39529],"309173fa":[()=>n.e(1793).then(n.t.bind(n,22684,19)),"~blog/default/tags-data-base-4e8-list.json",22684],"32397cb2":[()=>n.e(548).then(n.t.bind(n,22050,19)),"~blog/default/tags-awt-page-2-eb4-list.json",22050],"327fa616":[()=>n.e(3407).then(n.bind(n,94634)),"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",94634],"32b2299c":[()=>n.e(970).then(n.t.bind(n,5280,19)),"~blog/default/page-41-fe1.json",5280],33736670:[()=>n.e(2742).then(n.t.bind(n,80700,19)),"~blog/default/tags-class-eca.json",80700],"35293ec4":[()=>n.e(7697).then(n.t.bind(n,14,19)),"~blog/default/page-20-038.json",14],"35b2eb5a":[()=>n.e(372).then(n.t.bind(n,97815,19)),"~blog/default/tags-java-page-5-b71-list.json",97815],"366ddb85":[()=>n.e(3691).then(n.bind(n,2406)),"@site/docs/\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30.mdx",2406],"3680bd07":[()=>n.e(5173).then(n.t.bind(n,2003,19)),"~blog/default/tags-web-application-b52.json",2003],"3720c009":[()=>Promise.all([n.e(532),n.e(3751)]).then(n.bind(n,10727)),"@theme/DocTagsListPage",10727],"372ccfe9":[()=>n.e(9111).then(n.bind(n,50673)),"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx?truncated=true",50673],"38bf29ad":[()=>n.e(1285).then(n.t.bind(n,26514,19)),"~docs/default/tag-docs-tags-load-balancing-180.json",26514],"38d8699e":[()=>n.e(471).then(n.t.bind(n,97481,19)),"~blog/default/page-15-208.json",97481],"3972c49f":[()=>n.e(6629).then(n.t.bind(n,91782,19)),"~blog/default/tags-web-socket-c6e-list.json",91782],"39ee6679":[()=>n.e(5717).then(n.t.bind(n,83636,19)),"~blog/default/tags-woowahan-techcourse-b50.json",83636],"3b0f99e8":[()=>n.e(3553).then(n.t.bind(n,20034,19)),"~blog/default/tags-jenkins-2e5.json",20034],"3b12d42b":[()=>n.e(8107).then(n.t.bind(n,50244,19)),"~docs/default/tag-docs-tags-java-ce1.json",50244],"3b18521e":[()=>n.e(2773).then(n.t.bind(n,8086,19)),"~blog/default/tags-mockito-3c0.json",8086],"3c5aea38":[()=>n.e(6250).then(n.t.bind(n,56516,19)),"~blog/default/tags-retrospective-page-12-8cf.json",56516],"3c9c1743":[()=>n.e(5900).then(n.t.bind(n,1353,19)),"~blog/default/tags-woowahan-techcourse-page-15-e2a-list.json",1353],"3d6c40c1":[()=>n.e(8509).then(n.t.bind(n,3440,19)),"~blog/default/tags-monitoring-a8a.json",3440],"3dd4d232":[()=>n.e(7727).then(n.bind(n,74135)),"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",74135],"3ed04b60":[()=>n.e(7157).then(n.t.bind(n,84792,19)),"~blog/default/tags-spring-de1.json",84792],"3f6ea930":[()=>n.e(5186).then(n.bind(n,42096)),"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx",42096],"41b4728f":[()=>n.e(8628).then(n.t.bind(n,30171,19)),"~blog/default/tags-spring-boot-889-list.json",30171],"41c44b28":[()=>n.e(8106).then(n.bind(n,48272)),"@site/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd.mdx",48272],"42957a8d":[()=>n.e(9312).then(n.bind(n,1335)),"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",1335],"43a97218":[()=>n.e(4815).then(n.t.bind(n,65215,19)),"~blog/default/tags-retrospective-page-5-22d-list.json",65215],"43fcf0e9":[()=>n.e(6468).then(n.t.bind(n,94822,19)),"~blog/default/tags-woowahan-techcourse-page-9-065.json",94822],"4430ab79":[()=>n.e(5553).then(n.t.bind(n,2750,19)),"~docs/default/tag-docs-tags-zero-downtime-b1f.json",2750],"4485017c":[()=>n.e(1906).then(n.bind(n,23224)),"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",23224],"448c20a0":[()=>n.e(7680).then(n.bind(n,64586)),"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",64586],"4515250b":[()=>n.e(9304).then(n.t.bind(n,88767,19)),"~blog/default/tags-exception-644-list.json",88767],"451db21d":[()=>n.e(1475).then(n.bind(n,48193)),"@site/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59.mdx",48193],"454a6d0d":[()=>n.e(4104).then(n.bind(n,33482)),"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",33482],"489347ff":[()=>n.e(2793).then(n.t.bind(n,40526,19)),"~blog/default/tags-web-socket-c6e.json",40526],"48faf148":[()=>n.e(7328).then(n.bind(n,59455)),"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx?truncated=true",59455],"492a6565":[()=>n.e(9702).then(n.t.bind(n,44929,19)),"~blog/default/tags-lock-page-2-819-list.json",44929],"494882d1":[()=>n.e(4471).then(n.t.bind(n,2098,19)),"~blog/default/page-37-cb2.json",2098],"4959fc42":[()=>n.e(240).then(n.t.bind(n,80897,19)),"~blog/default/page-14-0a2.json",80897],"49b8d9dd":[()=>n.e(1103).then(n.t.bind(n,64420,19)),"~blog/default/tags-inno-db-59e.json",64420],"49f0f498":[()=>n.e(4433).then(n.t.bind(n,40719,19)),"~blog/default/tags-retrospective-page-16-226.json",40719],"4a1c8300":[()=>n.e(3324).then(n.bind(n,37750)),"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",37750],"4b2fba3e":[()=>n.e(328).then(n.t.bind(n,98234,19)),"~blog/default/tags-image-page-3-942-list.json",98234],"4b79a3c9":[()=>Promise.all([n.e(532),n.e(5838)]).then(n.bind(n,60036)),"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",60036],"4d43abad":[()=>n.e(3365).then(n.bind(n,4859)),"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx?truncated=true",4859],"5088fe06":[()=>n.e(80).then(n.t.bind(n,86819,19)),"~blog/default/tags-log-5ad-list.json",86819],"509d519c":[()=>n.e(743).then(n.t.bind(n,24469,19)),"/home/runner/work/greeng00se.github.io/greeng00se.github.io/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",24469],"52106a5f":[()=>n.e(9396).then(n.bind(n,63338)),"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx?truncated=true",63338],"530ffa4f":[()=>n.e(4818).then(n.bind(n,17105)),"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",17105],"533bfc57":[()=>n.e(5100).then(n.t.bind(n,4371,19)),"~blog/default/tags-retrospective-page-2-e2b-list.json",4371],"537817cb":[()=>n.e(3457).then(n.bind(n,49577)),"@site/blog/2023-1/2023-01-08-JSR-310.mdx?truncated=true",49577],"53e4509a":[()=>n.e(4722).then(n.t.bind(n,32259,19)),"~blog/default/page-46-6b3.json",32259],"54150be7":[()=>n.e(5088).then(n.t.bind(n,98707,19)),"~blog/default/tags-java-page-2-8c6-list.json",98707],"546ec22f":[()=>n.e(5635).then(n.t.bind(n,34223,19)),"~blog/default/tags-performance-test-2b7.json",34223],"54cb095e":[()=>n.e(7009).then(n.t.bind(n,95159,19)),"~blog/default/page-26-a44.json",95159],"55960ee5":[()=>n.e(4121).then(n.t.bind(n,88070,19)),"~docs/default/tags-list-current-prop-15a.json",88070],"562496aa":[()=>n.e(6161).then(n.t.bind(n,68146,19)),"~blog/default/tags-image-page-2-cc3.json",68146],"564337ec":[()=>n.e(5649).then(n.t.bind(n,8563,19)),"~blog/default/tags-retrospective-page-7-3e2-list.json",8563],"56e576e5":[()=>n.e(8262).then(n.t.bind(n,86556,19)),"~blog/default/tags-performance-test-2b7-list.json",86556],"5a29fbab":[()=>n.e(7857).then(n.t.bind(n,25381,19)),"~blog/default/tags-woowahan-techcourse-b50-list.json",25381],"5a473bed":[()=>n.e(9686).then(n.bind(n,94429)),"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",94429],"5a6c6934":[()=>n.e(5953).then(n.t.bind(n,48630,19)),"~blog/default/tags-dto-cb6.json",48630],"5c07bdab":[()=>n.e(6300).then(n.bind(n,23438)),"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",23438],"5c38e66e":[()=>n.e(5521).then(n.t.bind(n,28638,19)),"~blog/default/tags-woowahan-techcourse-page-10-f03.json",28638],"5d4cff52":[()=>n.e(1252).then(n.bind(n,73688)),"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",73688],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,36809)),"@generated/docusaurus.config",36809],"5eed1665":[()=>n.e(8142).then(n.t.bind(n,19729,19)),"~blog/default/tags-lock-529-list.json",19729],"5f81b25c":[()=>n.e(4889).then(n.t.bind(n,29492,19)),"~blog/default/page-27-eb3.json",29492],"5feaaaeb":[()=>n.e(2967).then(n.t.bind(n,49978,19)),"~blog/default/tags-retrospective-page-20-737-list.json",49978],"5ffd2c10":[()=>n.e(2100).then(n.t.bind(n,86515,19)),"~docs/default/tag-docs-tags-jpa-c8c.json",86515],"6093f82b":[()=>n.e(6017).then(n.t.bind(n,30708,19)),"~blog/default/page-9-361.json",30708],"633582b9":[()=>n.e(2448).then(n.t.bind(n,32401,19)),"~blog/default/tags-kotlin-6ac.json",32401],"635a92d5":[()=>n.e(7891).then(n.t.bind(n,72126,19)),"~blog/default/page-24-fbb.json",72126],"6412e40a":[()=>n.e(5421).then(n.t.bind(n,97677,19)),"~blog/default/tags-woowahan-techcourse-page-12-5ba-list.json",97677],"6425a984":[()=>n.e(5467).then(n.t.bind(n,95377,19)),"~blog/default/tags-woowahan-techcourse-page-4-bcd-list.json",95377],"64868a43":[()=>n.e(1501).then(n.t.bind(n,33159,19)),"~blog/default/page-39-76c.json",33159],"64f377d6":[()=>n.e(732).then(n.t.bind(n,62898,19)),"~blog/default/tags-woowahan-techcourse-page-11-6c9-list.json",62898],"6552f31f":[()=>n.e(917).then(n.bind(n,29693)),"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",29693],"6675e9ab":[()=>n.e(1255).then(n.bind(n,72336)),"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",72336],"66d1c769":[()=>n.e(7476).then(n.t.bind(n,80122,19)),"~blog/default/tags-data-base-page-2-3a7-list.json",80122],"672a376b":[()=>n.e(2579).then(n.t.bind(n,41690,19)),"~blog/default/tags-woowahan-techcourse-page-8-93a.json",41690],"6875c492":[()=>Promise.all([n.e(532),n.e(4),n.e(6048),n.e(8610)]).then(n.bind(n,41714)),"@theme/BlogTagsPostsPage",41714],"69a75ff2":[()=>n.e(7181).then(n.t.bind(n,12761,19)),"~blog/default/page-48-ebc.json",12761],"69c28c32":[()=>n.e(1065).then(n.t.bind(n,99263,19)),"~blog/default/page-36-1da.json",99263],"6a19354d":[()=>n.e(693).then(n.t.bind(n,36232,19)),"~blog/default/tags-lock-529.json",36232],"6b4e1191":[()=>n.e(838).then(n.bind(n,980)),"@site/docs/\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30.mdx",980],"6b54f6a4":[()=>Promise.all([n.e(532),n.e(4558)]).then(n.bind(n,23826)),"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx?truncated=true",23826],"6b69808d":[()=>n.e(5990).then(n.bind(n,5069)),"@site/docs/JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551.mdx",5069],"6ba49b42":[()=>n.e(498).then(n.t.bind(n,64450,19)),"~blog/default/tags-test-page-2-d33-list.json",64450],"6bc709ad":[()=>n.e(9393).then(n.t.bind(n,81399,19)),"~blog/default/tags-retrospective-page-6-594-list.json",81399],"6c38e270":[()=>n.e(7247).then(n.t.bind(n,51914,19)),"~docs/default/tag-docs-tags-sequenced-12d.json",51914],"6c674d03":[()=>n.e(7600).then(n.t.bind(n,80372,19)),"~docs/default/tag-docs-tags-network-cb4.json",80372],"6cfe3a99":[()=>n.e(5319).then(n.t.bind(n,91227,19)),"~blog/default/tags-cloudwatch-6c7-list.json",91227],"6d4355d3":[()=>n.e(3122).then(n.t.bind(n,37438,19)),"~blog/default/tags-async-page-2-246.json",37438],"6dd1c948":[()=>n.e(7064).then(n.t.bind(n,76376,19)),"~blog/default/page-34-16c.json",76376],"6f385a52":[()=>n.e(6608).then(n.bind(n,65468)),"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx?truncated=true",65468],"70275fcd":[()=>n.e(7412).then(n.t.bind(n,81191,19)),"~blog/default/page-42-ca9.json",81191],70834889:[()=>n.e(7344).then(n.bind(n,6777)),"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx?truncated=true",6777],"70a12cc4":[()=>n.e(5682).then(n.t.bind(n,17085,19)),"~blog/default/tags-static-b68-list.json",17085],"7159c7ff":[()=>n.e(3287).then(n.bind(n,92553)),"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx?truncated=true",92553],"72657f57":[()=>n.e(9581).then(n.bind(n,8046)),"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",8046],"73688d5c":[()=>n.e(6908).then(n.bind(n,60641)),"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx?truncated=true",60641],"7405ea58":[()=>n.e(2345).then(n.t.bind(n,40702,19)),"~blog/default/tags-retrospective-page-11-e3c-list.json",40702],"75121fd5":[()=>n.e(5335).then(n.t.bind(n,30674,19)),"~blog/default/tags-image-97d.json",30674],"754fb852":[()=>n.e(988).then(n.t.bind(n,38242,19)),"~blog/default/page-32-596.json",38242],"75f50328":[()=>n.e(7511).then(n.t.bind(n,58695,19)),"~blog/default/tags-mysql-331-list.json",58695],"7762a24e":[()=>n.e(2753).then(n.t.bind(n,55095,19)),"~blog/default/page-4-365.json",55095],"77f5fc5d":[()=>n.e(3625).then(n.t.bind(n,32215,19)),"~blog/default/tags-retrospective-page-16-226-list.json",32215],"7881a85f":[()=>n.e(7108).then(n.t.bind(n,1855,19)),"~blog/default/page-51-74a.json",1855],"79a97f4e":[()=>n.e(6412).then(n.bind(n,82792)),"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx?truncated=true",82792],"7af1d52f":[()=>n.e(2334).then(n.t.bind(n,59565,19)),"~blog/default/page-6-d10.json",59565],"7bbc420e":[()=>n.e(4311).then(n.t.bind(n,41691,19)),"~blog/default/tags-documentation-ee3.json",41691],"7c660760":[()=>n.e(2087).then(n.t.bind(n,91870,19)),"~blog/default/tags-woowahan-techcourse-page-9-065-list.json",91870],"7e4c1ed7":[()=>n.e(1653).then(n.t.bind(n,83297,19)),"~docs/default/tag-docs-tags-postmortem-ede.json",83297],"7e59392d":[()=>n.e(7281).then(n.t.bind(n,33202,19)),"~blog/default/tags-retrospective-page-9-473-list.json",33202],"7fbacf84":[()=>n.e(5797).then(n.t.bind(n,58701,19)),"~blog/default/tags-spring-de1-list.json",58701],"7fd9a574":[()=>n.e(2889).then(n.t.bind(n,5863,19)),"~blog/default/tags-retrospective-page-14-99d.json",5863],"80960b4b":[()=>n.e(7599).then(n.t.bind(n,28386,19)),"~blog/default/page-21-7a8.json",28386],"814f3328":[()=>n.e(2535).then(n.t.bind(n,45641,19)),"~blog/default/blog-post-list-prop-default.json",45641],"829fa7b9":[()=>n.e(9391).then(n.bind(n,22895)),"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",22895],"86b4da3d":[()=>n.e(952).then(n.t.bind(n,44149,19)),"~blog/default/tags-woowahan-techcourse-page-2-567.json",44149],"87070fc3":[()=>n.e(6124).then(n.bind(n,74161)),"@site/docs/\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",74161],"871c1e5a":[()=>n.e(5966).then(n.t.bind(n,71247,19)),"~blog/default/page-23-651.json",71247],"8720c147":[()=>n.e(470).then(n.bind(n,55810)),"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",55810],"8a24850b":[()=>n.e(741).then(n.bind(n,12401)),"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",12401],"8a27aeff":[()=>n.e(71).then(n.bind(n,17442)),"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx?truncated=true",17442],"8ad2f007":[()=>n.e(8360).then(n.bind(n,96431)),"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx?truncated=true",96431],"8b79a48d":[()=>n.e(9287).then(n.t.bind(n,59070,19)),"~blog/default/tags-retrospective-page-9-473.json",59070],"8c6c0796":[()=>n.e(2816).then(n.t.bind(n,59123,19)),"~blog/default/tags-retrospective-2fb.json",59123],"8d05b77c":[()=>n.e(4149).then(n.t.bind(n,22801,19)),"~blog/default/page-5-264.json",22801],"8d7288fe":[()=>n.e(4801).then(n.t.bind(n,71830,19)),"~blog/default/tags-class-eca-list.json",71830],"8da65e83":[()=>n.e(9427).then(n.t.bind(n,1341,19)),"~blog/default/tags-woowahan-techcourse-page-4-bcd.json",1341],"8dc09bac":[()=>n.e(8338).then(n.t.bind(n,28881,19)),"~blog/default/tags-event-f04-list.json",28881],"8e498bb6":[()=>n.e(1436).then(n.t.bind(n,50257,19)),"~blog/default/tags-java-page-3-b02.json",50257],"8e9dc6b3":[()=>n.e(7709).then(n.t.bind(n,65548,19)),"~blog/default/tags-web-application-b52-list.json",65548],"8fbd512b":[()=>n.e(5873).then(n.t.bind(n,15,19)),"~blog/default/tags-async-326.json",15],"905ecccc":[()=>Promise.all([n.e(532),n.e(2939)]).then(n.bind(n,1057)),"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",1057],"92ade856":[()=>Promise.all([n.e(532),n.e(1772)]).then(n.bind(n,68499)),"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx?truncated=true",68499],"92fef07b":[()=>n.e(300).then(n.bind(n,21474)),"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",21474],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"96adae60":[()=>n.e(172).then(n.t.bind(n,54217,19)),"~blog/default/page-19-21b.json",54217],"981f7647":[()=>n.e(2947).then(n.bind(n,51077)),"@site/docs/\uc124\uacc4/\ud328\ud0a4\uc9c0.mdx",51077],"9b43eac8":[()=>n.e(9286).then(n.bind(n,44284)),"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",44284],"9b56b618":[()=>n.e(9538).then(n.t.bind(n,37e3,19)),"~blog/default/tags-awt-0e2-list.json",37e3],"9bad5ae7":[()=>n.e(2153).then(n.bind(n,2163)),"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx?truncated=true",2163],"9bbc65ac":[()=>n.e(7210).then(n.t.bind(n,51020,19)),"~docs/default/tag-docs-tags-test-8ab.json",51020],"9c6e5a12":[()=>n.e(2145).then(n.bind(n,22059)),"@site/docs/\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.mdx",22059],"9ca52986":[()=>n.e(3490).then(n.t.bind(n,92016,19)),"~blog/default/tags-lock-page-2-819.json",92016],"9cfe8fd1":[()=>n.e(7725).then(n.t.bind(n,97113,19)),"~blog/default/page-18-46d.json",97113],"9d1fd2b0":[()=>n.e(7972).then(n.bind(n,15361)),"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",15361],"9d8ee3a8":[()=>n.e(5962).then(n.t.bind(n,71297,19)),"~blog/default/tags-oop-03c.json",71297],"9dc4119a":[()=>n.e(6490).then(n.t.bind(n,4408,19)),"~blog/default/tags-retrospective-page-10-4a6-list.json",4408],"9dec6b67":[()=>n.e(8524).then(n.t.bind(n,88221,19)),"~blog/default/tags-data-base-page-2-3a7.json",88221],"9e2e3982":[()=>n.e(7617).then(n.bind(n,57214)),"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",57214],"9e4087bc":[()=>n.e(3608).then(n.bind(n,63169)),"@theme/BlogArchivePage",63169],"9e4ad429":[()=>n.e(5406).then(n.t.bind(n,16060,19)),"~docs/default/tag-docs-tags-performance-339.json",16060],"9f586ca3":[()=>n.e(3673).then(n.t.bind(n,41912,19)),"~blog/default/tags-async-page-2-246-list.json",41912],"9fae68e2":[()=>n.e(297).then(n.t.bind(n,77536,19)),"~blog/default/tags-kotlin-6ac-list.json",77536],a0410ab5:[()=>n.e(7843).then(n.t.bind(n,76970,19)),"~blog/default/tags-retrospective-page-7-3e2.json",76970],a14ec7b5:[()=>n.e(3833).then(n.bind(n,9756)),"@site/docs/\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8.mdx",9756],a1877440:[()=>n.e(7648).then(n.t.bind(n,23235,19)),"~blog/default/tags-async-326-list.json",23235],a3614f73:[()=>n.e(8474).then(n.bind(n,8797)),"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",8797],a3dddb77:[()=>n.e(475).then(n.t.bind(n,5479,19)),"~blog/default/tags-java-page-4-c22.json",5479],a4349a81:[()=>n.e(9623).then(n.t.bind(n,32318,19)),"~blog/default/tags-woowahan-techcourse-page-15-e2a.json",32318],a4a1e915:[()=>n.e(3671).then(n.t.bind(n,60166,19)),"~blog/default/tags-retrospective-2fb-list.json",60166],a539c018:[()=>n.e(5758).then(n.t.bind(n,99844,19)),"~blog/default/tags-woowahan-techcourse-page-16-b44.json",99844],a5557bb9:[()=>n.e(5991).then(n.t.bind(n,93885,19)),"~blog/default/index.json",93885],a59d28a9:[()=>n.e(2012).then(n.bind(n,44122)),"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx?truncated=true",44122],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(4),n.e(6048),n.e(3089)]).then(n.bind(n,80046)),"@theme/BlogListPage",80046],a710d533:[()=>Promise.all([n.e(532),n.e(1711)]).then(n.bind(n,95220)),"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",95220],a7e0d18f:[()=>n.e(3519).then(n.t.bind(n,59462,19)),"~docs/default/tag-docs-tags-spring-3d9.json",59462],a85e626a:[()=>n.e(9092).then(n.t.bind(n,48458,19)),"~blog/default/tags-jdbc-4bd.json",48458],a896be03:[()=>n.e(2526).then(n.t.bind(n,64030,19)),"~blog/default/tags-woowahan-techcourse-page-6-429.json",64030],a8cba70f:[()=>n.e(2261).then(n.bind(n,61629)),"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx?truncated=true",61629],a9221bd5:[()=>n.e(5507).then(n.t.bind(n,40319,19)),"~blog/default/tags-inno-db-59e-list.json",40319],a9c2b81a:[()=>n.e(2266).then(n.t.bind(n,52882,19)),"~blog/default/tags-woowahan-techcourse-page-16-b44-list.json",52882],aa73a035:[()=>n.e(5371).then(n.bind(n,17231)),"@site/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool.mdx",17231],aacfeabc:[()=>n.e(8909).then(n.bind(n,79407)),"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx?truncated=true",79407],abb0816f:[()=>n.e(4174).then(n.t.bind(n,82969,19)),"~blog/default/tags-woowahan-techcourse-page-7-5bd-list.json",82969],abc83b7f:[()=>n.e(2215).then(n.t.bind(n,8412,19)),"~blog/default/tags-retrospective-page-2-e2b.json",8412],ac23d7ee:[()=>n.e(3213).then(n.t.bind(n,43943,19)),"~blog/default/tags-woowahan-techcourse-page-3-9a8-list.json",43943],ac3fdf5d:[()=>n.e(8548).then(n.bind(n,26094)),"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",26094],ad3b7b62:[()=>n.e(26).then(n.bind(n,55097)),"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",55097],ae1d6508:[()=>n.e(2181).then(n.t.bind(n,83486,19)),"~blog/default/tags-composite-240-list.json",83486],ae3384b2:[()=>n.e(2965).then(n.t.bind(n,15745,19)),"/home/runner/work/greeng00se.github.io/greeng00se.github.io/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",15745],ae82353f:[()=>n.e(6420).then(n.bind(n,49968)),"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md?truncated=true",49968],af81a133:[()=>n.e(7787).then(n.t.bind(n,13800,19)),"~blog/default/tags-teco-chat-d21.json",13800],b2b675dd:[()=>n.e(533).then(n.t.bind(n,28017,19)),"~blog/default/blog-c06.json",28017],b2c8756c:[()=>n.e(1213).then(n.bind(n,31419)),"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",31419],b2ebb6fd:[()=>n.e(4091).then(n.bind(n,34604)),"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",34604],b301b20b:[()=>n.e(3637).then(n.t.bind(n,83150,19)),"~blog/default/tags-replication-56b.json",83150],b36d2d1d:[()=>n.e(1257).then(n.t.bind(n,7903,19)),"~docs/default/tag-docs-tags-latency-735.json",7903],b41adc00:[()=>n.e(1391).then(n.bind(n,56783)),"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",56783],b421ebb7:[()=>n.e(8518).then(n.bind(n,20882)),"@site/docs/\uc131\ub2a5/Throughput\uacfc Latency.mdx",20882],b474adfe:[()=>n.e(573).then(n.t.bind(n,85419,19)),"~blog/default/tags-image-page-2-cc3-list.json",85419],b5f3dcc5:[()=>n.e(7723).then(n.t.bind(n,23005,19)),"~blog/default/tags-retrospective-page-15-26b-list.json",23005],b6ffb0cb:[()=>n.e(2156).then(n.bind(n,47682)),"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",47682],b7d33121:[()=>n.e(7153).then(n.t.bind(n,72005,19)),"~blog/default/tags-cloudwatch-6c7.json",72005],b88cb85b:[()=>n.e(2293).then(n.bind(n,18557)),"@site/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998.mdx",18557],b9bcab37:[()=>n.e(7688).then(n.t.bind(n,43632,19)),"~blog/default/tags-grasp-418.json",43632],bace0b37:[()=>n.e(2362).then(n.bind(n,25831)),"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",25831],bb221eab:[()=>n.e(711).then(n.bind(n,59165)),"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx?truncated=true",59165],bbc01ba0:[()=>n.e(3009).then(n.t.bind(n,12333,19)),"~blog/default/tags-retrospective-page-10-4a6.json",12333],bbc3f62a:[()=>n.e(8894).then(n.t.bind(n,51842,19)),"~blog/default/tags-woowahan-techcourse-page-13-8ae-list.json",51842],bbceb8f1:[()=>n.e(653).then(n.t.bind(n,26529,19)),"~blog/default/tags-woowahan-techcourse-page-5-ac5-list.json",26529],bbdd7e52:[()=>n.e(3396).then(n.bind(n,31120)),"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",31120],bd2d06b5:[()=>n.e(9763).then(n.t.bind(n,93081,19)),"~blog/default/tags-retrospective-page-3-ee4.json",93081],bd4db8ee:[()=>n.e(6883).then(n.bind(n,93546)),"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",93546],bd64a762:[()=>n.e(5463).then(n.bind(n,37089)),"@site/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870.mdx",37089],be497a8d:[()=>n.e(6172).then(n.bind(n,45909)),"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx?truncated=true",45909],bf933b37:[()=>n.e(3095).then(n.t.bind(n,52954,19)),"~blog/default/tags-my-sql-46a-list.json",52954],c037d168:[()=>n.e(6587).then(n.t.bind(n,41235,19)),"~blog/default/tags-transaction-ea3-list.json",41235],c08e7a0d:[()=>n.e(7404).then(n.t.bind(n,27625,19)),"~docs/default/tag-docs-tags-throughput-8fc.json",27625],c0cb7215:[()=>n.e(7966).then(n.t.bind(n,66109,19)),"~blog/default/tags-book-page-2-bc6-list.json",66109],c189d18f:[()=>n.e(4962).then(n.t.bind(n,3470,19)),"~docs/default/tag-docs-tags-etc-c52.json",3470],c1b17b3f:[()=>n.e(8927).then(n.bind(n,29571)),"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",29571],c29bedb9:[()=>n.e(9242).then(n.t.bind(n,44025,19)),"~blog/default/page-35-8fd.json",44025],c3ea66fe:[()=>n.e(6698).then(n.t.bind(n,63504,19)),"~blog/default/tags-isolation-79d.json",63504],c4f5d8e4:[()=>n.e(4195).then(n.bind(n,62841)),"@site/src/pages/index.js",62841],c55d205b:[()=>n.e(3438).then(n.bind(n,83859)),"@site/docs/Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4.mdx",83859],c573638f:[()=>n.e(964).then(n.t.bind(n,28866,19)),"~blog/default/tags-tags-c2b.json",28866],c6004f62:[()=>n.e(5892).then(n.t.bind(n,37567,19)),"~blog/default/tags-mock-330-list.json",37567],c60995f6:[()=>n.e(6199).then(n.t.bind(n,62474,19)),"~docs/default/tag-docs-tags-nginx-3b7.json",62474],c60ea0ff:[()=>n.e(3085).then(n.t.bind(n,14072,19)),"~blog/default/tags-teco-chat-page-2-d4f.json",14072],c6b037a5:[()=>n.e(3137).then(n.t.bind(n,4030,19)),"~blog/default/tags-woowahan-techcourse-page-14-c67.json",4030],c6d04683:[()=>n.e(5436).then(n.bind(n,48905)),"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",48905],c7015929:[()=>n.e(4185).then(n.t.bind(n,910,19)),"~blog/default/tags-python-687.json",910],c92f81ac:[()=>n.e(4393).then(n.t.bind(n,10767,19)),"~blog/default/tags-replication-56b-list.json",10767],caf1b628:[()=>n.e(7230).then(n.bind(n,16711)),"@site/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1.mdx",16711],cb6229c3:[()=>n.e(7204).then(n.bind(n,26930)),"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",26930],cc3bdf2f:[()=>n.e(8817).then(n.t.bind(n,11135,19)),"~blog/default/tags-exception-644.json",11135],cc519f63:[()=>n.e(5323).then(n.bind(n,7771)),"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",7771],ccc49370:[()=>Promise.all([n.e(532),n.e(4),n.e(6048),n.e(6103)]).then(n.bind(n,65203)),"@theme/BlogPostPage",65203],cd68cda1:[()=>n.e(8683).then(n.bind(n,66934)),"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx?truncated=true",66934],cec43d6a:[()=>n.e(1358).then(n.bind(n,19284)),"@site/docs/\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c.mdx",19284],cef46b76:[()=>n.e(8644).then(n.bind(n,32390)),"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",32390],cf8e491a:[()=>n.e(5870).then(n.t.bind(n,19799,19)),"~blog/default/tags-awt-0e2.json",19799],d0277431:[()=>n.e(846).then(n.t.bind(n,4838,19)),"~blog/default/tags-dto-cb6-list.json",4838],d0840b01:[()=>n.e(8037).then(n.t.bind(n,20317,19)),"~blog/default/tags-transaction-ea3.json",20317],d09f7e4b:[()=>n.e(3098).then(n.t.bind(n,84057,19)),"~blog/default/tags-teco-chat-page-3-007-list.json",84057],d0e4cdf1:[()=>n.e(5465).then(n.t.bind(n,64020,19)),"~blog/default/page-7-3c3.json",64020],d126aabd:[()=>n.e(1675).then(n.t.bind(n,7220,19)),"~blog/default/tags-retrospective-page-4-3a3-list.json",7220],d1cef389:[()=>n.e(9310).then(n.t.bind(n,40836,19)),"~blog/default/page-17-62c.json",40836],d1e1bea4:[()=>n.e(7945).then(n.bind(n,98120)),"@site/docs/MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd.md",98120],d202e2c5:[()=>n.e(7175).then(n.t.bind(n,3395,19)),"~blog/default/tags-oop-03c-list.json",3395],d2611248:[()=>n.e(8561).then(n.t.bind(n,81667,19)),"~blog/default/page-43-b0a.json",81667],d2770bf7:[()=>n.e(843).then(n.t.bind(n,41156,19)),"~blog/default/tags-woowahan-techcourse-page-11-6c9.json",41156],d28e30d7:[()=>Promise.all([n.e(532),n.e(6671)]).then(n.bind(n,27464)),"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",27464],d2935d14:[()=>n.e(3259).then(n.t.bind(n,92158,19)),"~blog/default/tags-isolation-79d-list.json",92158],d350f5d9:[()=>n.e(2098).then(n.t.bind(n,82622,19)),"~blog/default/tags-test-page-2-d33.json",82622],d361ad2d:[()=>n.e(2247).then(n.bind(n,40237)),"@site/docs/\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12.mdx",40237],d368e73e:[()=>n.e(7954).then(n.t.bind(n,71965,19)),"~blog/default/tags-image-97d-list.json",71965],d40f51e1:[()=>n.e(9633).then(n.t.bind(n,9415,19)),"~blog/default/tags-jdbc-4bd-list.json",9415],d50fd269:[()=>n.e(100).then(n.t.bind(n,38132,19)),"~blog/default/page-31-308.json",38132],d5bb232a:[()=>n.e(3651).then(n.bind(n,14345)),"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx?truncated=true",14345],d5dfecc2:[()=>n.e(1677).then(n.t.bind(n,83335,19)),"~blog/default/tags-teco-chat-page-2-d4f-list.json",83335],d60e2b0c:[()=>n.e(8174).then(n.t.bind(n,36927,19)),"~blog/default/tags-retrospective-page-17-636-list.json",36927],d65e25b7:[()=>Promise.all([n.e(532),n.e(7776)]).then(n.bind(n,8e4)),"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx?truncated=true",8e4],d6638f30:[()=>n.e(3476).then(n.bind(n,54336)),"@site/docs/\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec.mdx",54336],d6a3d698:[()=>n.e(2890).then(n.t.bind(n,39477,19)),"~blog/default/tags-image-page-3-942.json",39477],d7955594:[()=>Promise.all([n.e(532),n.e(588)]).then(n.bind(n,89788)),"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",89788],d86f7a37:[()=>n.e(3392).then(n.bind(n,10823)),"@site/docs/Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5.mdx",10823],d8775059:[()=>n.e(6387).then(n.bind(n,98809)),"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",98809],d88bdb28:[()=>n.e(9788).then(n.t.bind(n,29417,19)),"~blog/default/tags-retrospective-page-13-49c.json",29417],d8cdf5ef:[()=>n.e(5919).then(n.bind(n,11311)),"@site/docs/\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8.mdx",11311],da14f319:[()=>n.e(5485).then(n.bind(n,77168)),"@site/docs/\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5.md",77168],dab4c683:[()=>n.e(6058).then(n.t.bind(n,67315,19)),"~blog/default/tags-woowahan-techcourse-page-3-9a8.json",67315],daff1d93:[()=>n.e(1659).then(n.bind(n,26016)),"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx?truncated=true",26016],db7928b3:[()=>n.e(5046).then(n.t.bind(n,11478,19)),"~blog/default/tags-intelli-j-2bf-list.json",11478],db86613e:[()=>n.e(9458).then(n.bind(n,58967)),"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx?truncated=true",58967],dca6a1e3:[()=>n.e(3239).then(n.bind(n,52589)),"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx?truncated=true",52589],dcf70953:[()=>n.e(1761).then(n.t.bind(n,83769,19)),"/home/runner/work/greeng00se.github.io/greeng00se.github.io/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",83769],ddf9e0bd:[()=>n.e(2542).then(n.t.bind(n,84039,19)),"~blog/default/tags-woowahan-techcourse-page-8-93a-list.json",84039],df147deb:[()=>n.e(5103).then(n.bind(n,78134)),"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",78134],df203c0f:[()=>n.e(9924).then(n.bind(n,40491)),"@theme/DocTagDocListPage",40491],df862072:[()=>n.e(7474).then(n.t.bind(n,24827,19)),"~blog/default/tags-book-page-3-a93.json",24827],dfa84138:[()=>n.e(1434).then(n.t.bind(n,22483,19)),"~blog/default/tags-data-base-page-3-9db-list.json",22483],dfc7013c:[()=>n.e(5857).then(n.bind(n,57515)),"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx?truncated=true",57515],e073eb07:[()=>n.e(5819).then(n.t.bind(n,57743,19)),"~blog/default/tags-retrospective-page-11-e3c.json",57743],e0d68441:[()=>n.e(628).then(n.t.bind(n,75301,19)),"~blog/default/tags-retrospective-page-12-8cf-list.json",75301],e0e4666e:[()=>n.e(4665).then(n.t.bind(n,16482,19)),"~blog/default/tags-my-sql-46a.json",16482],e1735da7:[()=>n.e(1611).then(n.bind(n,9753)),"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx?truncated=true",9753],e1a06456:[()=>n.e(9910).then(n.bind(n,34117)),"@site/blog/2023-2/2023-06-26-WebSocket.mdx",34117],e21c8cc4:[()=>n.e(6049).then(n.t.bind(n,48765,19)),"~blog/default/tags-retrospective-page-8-5ab.json",48765],e2326195:[()=>n.e(9467).then(n.bind(n,8169)),"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",8169],e2de2dbb:[()=>n.e(6710).then(n.t.bind(n,47023,19)),"~blog/default/tags-java-page-5-b71.json",47023],e4ebfe18:[()=>n.e(9940).then(n.t.bind(n,57954,19)),"~blog/default/page-3-02e.json",57954],e5e44a85:[()=>n.e(1253).then(n.t.bind(n,42310,19)),"~docs/default/tag-docs-tags-deploy-f3b.json",42310],e6a6ed43:[()=>n.e(5300).then(n.bind(n,19463)),"@site/blog/2023-1/2023-03-30-GRASP.mdx?truncated=true",19463],e6e259a5:[()=>n.e(3771).then(n.bind(n,5352)),"@site/docs/\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815.md",5352],e7d2a655:[()=>n.e(8652).then(n.t.bind(n,71501,19)),"~blog/default/tags-woowahan-techcourse-page-2-567-list.json",71501],e8d6e7ce:[()=>n.e(3912).then(n.t.bind(n,65245,19)),"~blog/default/tags-retrospective-page-6-594.json",65245],e9624b4f:[()=>n.e(4564).then(n.t.bind(n,11780,19)),"~blog/default/tags-retrospective-page-13-49c-list.json",11780],e9eabc5d:[()=>n.e(1112).then(n.bind(n,778)),"@site/blog/2023-1/2023-03-30-GRASP.mdx",778],e9ff60ad:[()=>n.e(2530).then(n.t.bind(n,10242,19)),"~blog/default/tags-pattern-b4e-list.json",10242],eae2a611:[()=>n.e(6180).then(n.bind(n,87990)),"@site/docs/\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98.mdx",87990],ee1dd2ad:[()=>n.e(5435).then(n.t.bind(n,48834,19)),"~blog/default/tags-woowahan-techcourse-page-13-8ae.json",48834],ee92877e:[()=>n.e(8716).then(n.t.bind(n,41106,19)),"~blog/default/tags-retrospective-page-5-22d.json",41106],eec33099:[()=>n.e(4953).then(n.t.bind(n,80133,19)),"~blog/default/page-40-397.json",80133],ef5b2427:[()=>n.e(9606).then(n.t.bind(n,50195,19)),"~blog/default/page-22-f33.json",50195],eff1d58f:[()=>n.e(4137).then(n.bind(n,93097)),"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx?truncated=true",93097],f01ceada:[()=>n.e(724).then(n.t.bind(n,62563,19)),"~blog/default/page-50-0b0.json",62563],f042b56c:[()=>n.e(8919).then(n.t.bind(n,27490,19)),"~blog/default/tags-teco-chat-d21-list.json",27490],f06cb3e2:[()=>Promise.all([n.e(532),n.e(2620)]).then(n.bind(n,7729)),"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",7729],f078e301:[()=>n.e(1926).then(n.t.bind(n,18385,19)),"~blog/default/tags-woowahan-techcourse-page-6-429-list.json",18385],f0978ee1:[()=>n.e(7740).then(n.t.bind(n,69366,19)),"~blog/default/tags-awt-page-2-eb4.json",69366],f156dfb9:[()=>n.e(5602).then(n.t.bind(n,83311,19)),"~blog/default/tags-time-471.json",83311],f25de701:[()=>n.e(2245).then(n.bind(n,87875)),"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md?truncated=true",87875],f332d221:[()=>n.e(2717).then(n.t.bind(n,99371,19)),"~blog/default/page-10-857.json",99371],f3493919:[()=>n.e(8476).then(n.bind(n,88439)),"@site/docs/\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30.mdx",88439],f3e308ad:[()=>n.e(6123).then(n.t.bind(n,16240,19)),"~blog/default/page-33-758.json",16240],f4c6e7e6:[()=>n.e(31).then(n.t.bind(n,77922,19)),"~docs/default/tag-docs-tags-book-8e4.json",77922],f4f49e13:[()=>n.e(6887).then(n.t.bind(n,26329,19)),"~blog/default/page-12-b6a.json",26329],f580a9d0:[()=>n.e(9887).then(n.t.bind(n,78989,19)),"~blog/default/tags-python-687-list.json",78989],f63a747b:[()=>n.e(5131).then(n.t.bind(n,81723,19)),"~blog/default/tags-woowahan-techcourse-page-7-5bd.json",81723],f6807fb4:[()=>n.e(4788).then(n.t.bind(n,39836,19)),"~docs/default/tag-docs-tags-architecture-68d.json",39836],f75a8651:[()=>n.e(8882).then(n.t.bind(n,44633,19)),"~blog/default/page-8-8c2.json",44633],f7b9d2f4:[()=>n.e(2958).then(n.t.bind(n,53122,19)),"~blog/default/tags-woowahan-techcourse-page-12-5ba.json",53122],f8409a7e:[()=>n.e(3206).then(n.bind(n,69568)),"@site/docs/intro.mdx",69568],f87bdf62:[()=>n.e(6750).then(n.bind(n,19426)),"@site/blog/2023-2/2023-06-26-WebSocket.mdx?truncated=true",19426],f90d0c52:[()=>n.e(5294).then(n.bind(n,85749)),"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",85749],fa3d3942:[()=>n.e(916).then(n.bind(n,53036)),"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",53036],fb48356a:[()=>n.e(9534).then(n.t.bind(n,78215,19)),"~blog/default/tags-retrospective-page-18-40f-list.json",78215],fb861301:[()=>n.e(7563).then(n.t.bind(n,17036,19)),"~blog/default/tags-woowahan-techcourse-page-14-c67-list.json",17036],fbd57548:[()=>n.e(6837).then(n.t.bind(n,30990,19)),"~blog/default/page-11-f65.json",30990],fd5d2408:[()=>n.e(3614).then(n.t.bind(n,64631,19)),"~blog/default/tags-time-471-list.json",64631],fe273484:[()=>n.e(8355).then(n.t.bind(n,53034,19)),"~blog/default/tags-java-a6e-list.json",53034],fe8cce0a:[()=>n.e(955).then(n.t.bind(n,78535,19)),"~blog/default/tags-intelli-j-2bf.json",78535],fed8bc04:[()=>n.e(8110).then(n.t.bind(n,96375,19)),"~blog/default/tags-woowahan-techcourse-page-5-ac5.json",96375],ff4c6c5e:[()=>n.e(820).then(n.bind(n,23856)),"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",23856],ffb0fa11:[()=>n.e(7400).then(n.t.bind(n,58214,19)),"~blog/default/tags-book-page-3-a93-list.json",58214]};function c(e){let{error:t,retry:n,pastDelay:r}=e;return t?a.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},a.createElement("p",null,String(t)),a.createElement("div",null,a.createElement("button",{type:"button",onClick:n},"Retry"))):r?a.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},a.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},a.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},a.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},a.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),a.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),a.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),a.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},a.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),a.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),a.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),a.createElement("circle",{cx:"22",cy:"22",r:"8"},a.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(99670),d=n(30226);function p(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return a.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},a.createElement(n,t))}});const o=s[`${e}-${t}`],p={},f=[],g=[],m=(0,u.Z)(o);return Object.entries(m).forEach((e=>{let[t,n]=e;const a=l[n];a&&(p[t]=a[0],f.push(a[1]),g.push(a[2]))})),i().Map({loading:c,loader:p,modules:f,webpack:()=>g,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,a]=t;const r=a.default;if(!r)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof r&&"function"!=typeof r||Object.keys(a).filter((e=>"default"!==e)).forEach((e=>{r[e]=a[e]}));let o=i;const s=n.split(".");s.slice(0,-1).forEach((e=>{o=o[e]})),o[s[s.length-1]]=r}));const s=i.__comp;delete i.__comp;const l=i.__context;return delete i.__context,a.createElement(d.z,{value:l},a.createElement(s,(0,r.Z)({},i,n)))}})}const f=[{path:"/2022-retrospective",component:p("/2022-retrospective","624"),exact:!0},{path:"/accidental-duplication",component:p("/accidental-duplication","d17"),exact:!0},{path:"/blackjack-retrospective",component:p("/blackjack-retrospective","595"),exact:!0},{path:"/blog",component:p("/blog","3d8"),exact:!0},{path:"/book-leadership-and-self-deception",component:p("/book-leadership-and-self-deception","ddd"),exact:!0},{path:"/book-writer",component:p("/book-writer","3c9"),exact:!0},{path:"/chess-retrospective",component:p("/chess-retrospective","168"),exact:!0},{path:"/cloudwatch",component:p("/cloudwatch","cb1"),exact:!0},{path:"/composite",component:p("/composite","302"),exact:!0},{path:"/custom-jdbc-template",component:p("/custom-jdbc-template","cfa"),exact:!0},{path:"/db-replication",component:p("/db-replication","6f2"),exact:!0},{path:"/docs/tags",component:p("/docs/tags","820"),exact:!0},{path:"/docs/tags/architecture",component:p("/docs/tags/architecture","f3f"),exact:!0},{path:"/docs/tags/book",component:p("/docs/tags/book","c20"),exact:!0},{path:"/docs/tags/collection",component:p("/docs/tags/collection","b80"),exact:!0},{path:"/docs/tags/deploy",component:p("/docs/tags/deploy","591"),exact:!0},{path:"/docs/tags/etc",component:p("/docs/tags/etc","338"),exact:!0},{path:"/docs/tags/java",component:p("/docs/tags/java","08c"),exact:!0},{path:"/docs/tags/jpa",component:p("/docs/tags/jpa","f95"),exact:!0},{path:"/docs/tags/latency",component:p("/docs/tags/latency","e82"),exact:!0},{path:"/docs/tags/load-balancing",component:p("/docs/tags/load-balancing","0be"),exact:!0},{path:"/docs/tags/monitoring",component:p("/docs/tags/monitoring","50f"),exact:!0},{path:"/docs/tags/network",component:p("/docs/tags/network","322"),exact:!0},{path:"/docs/tags/nginx",component:p("/docs/tags/nginx","ecc"),exact:!0},{path:"/docs/tags/package",component:p("/docs/tags/package","593"),exact:!0},{path:"/docs/tags/performance",component:p("/docs/tags/performance","a3d"),exact:!0},{path:"/docs/tags/postmortem",component:p("/docs/tags/postmortem","4b0"),exact:!0},{path:"/docs/tags/sequenced",component:p("/docs/tags/sequenced","e0d"),exact:!0},{path:"/docs/tags/spring",component:p("/docs/tags/spring","f99"),exact:!0},{path:"/docs/tags/test",component:p("/docs/tags/test","b58"),exact:!0},{path:"/docs/tags/throughput",component:p("/docs/tags/throughput","206"),exact:!0},{path:"/docs/tags/zero-downtime",component:p("/docs/tags/zero-downtime","389"),exact:!0},{path:"/docusaurus",component:p("/docusaurus","926"),exact:!0},{path:"/grasp",component:p("/grasp","f9b"),exact:!0},{path:"/innodb-lock",component:p("/innodb-lock","d18"),exact:!0},{path:"/intellij-settings",component:p("/intellij-settings","80e"),exact:!0},{path:"/java-class-file",component:p("/java-class-file","50e"),exact:!0},{path:"/java-spring-springboot",component:p("/java-spring-springboot","bed"),exact:!0},{path:"/jdbc-retrospective",component:p("/jdbc-retrospective","158"),exact:!0},{path:"/jenkins",component:p("/jenkins","48c"),exact:!0},{path:"/jsr-310",component:p("/jsr-310","7f9"),exact:!0},{path:"/kotlin-null",component:p("/kotlin-null","8d3"),exact:!0},{path:"/ladder-retrospective",component:p("/ladder-retrospective","7ea"),exact:!0},{path:"/level2-interview-retrospective",component:p("/level2-interview-retrospective","c75"),exact:!0},{path:"/log-async-exception",component:p("/log-async-exception","a44"),exact:!0},{path:"/mock-static-method",component:p("/mock-static-method","fd3"),exact:!0},{path:"/mvc-retrospective",component:p("/mvc-retrospective","96d"),exact:!0},{path:"/mysql-lock",component:p("/mysql-lock","3cb"),exact:!0},{path:"/order-retrospective",component:p("/order-retrospective","a11"),exact:!0},{path:"/page/10",component:p("/page/10","c2c"),exact:!0},{path:"/page/11",component:p("/page/11","89b"),exact:!0},{path:"/page/12",component:p("/page/12","155"),exact:!0},{path:"/page/13",component:p("/page/13","ece"),exact:!0},{path:"/page/14",component:p("/page/14","1f9"),exact:!0},{path:"/page/15",component:p("/page/15","cc0"),exact:!0},{path:"/page/16",component:p("/page/16","813"),exact:!0},{path:"/page/17",component:p("/page/17","843"),exact:!0},{path:"/page/18",component:p("/page/18","84a"),exact:!0},{path:"/page/19",component:p("/page/19","e4e"),exact:!0},{path:"/page/2",component:p("/page/2","256"),exact:!0},{path:"/page/20",component:p("/page/20","30e"),exact:!0},{path:"/page/21",component:p("/page/21","553"),exact:!0},{path:"/page/22",component:p("/page/22","a88"),exact:!0},{path:"/page/23",component:p("/page/23","edf"),exact:!0},{path:"/page/24",component:p("/page/24","915"),exact:!0},{path:"/page/25",component:p("/page/25","4aa"),exact:!0},{path:"/page/26",component:p("/page/26","ec5"),exact:!0},{path:"/page/27",component:p("/page/27","339"),exact:!0},{path:"/page/28",component:p("/page/28","376"),exact:!0},{path:"/page/29",component:p("/page/29","ea0"),exact:!0},{path:"/page/3",component:p("/page/3","d5c"),exact:!0},{path:"/page/30",component:p("/page/30","2ff"),exact:!0},{path:"/page/31",component:p("/page/31","d32"),exact:!0},{path:"/page/32",component:p("/page/32","02d"),exact:!0},{path:"/page/33",component:p("/page/33","3d4"),exact:!0},{path:"/page/34",component:p("/page/34","4d2"),exact:!0},{path:"/page/35",component:p("/page/35","b81"),exact:!0},{path:"/page/36",component:p("/page/36","598"),exact:!0},{path:"/page/37",component:p("/page/37","eda"),exact:!0},{path:"/page/38",component:p("/page/38","9cf"),exact:!0},{path:"/page/39",component:p("/page/39","27d"),exact:!0},{path:"/page/4",component:p("/page/4","b0c"),exact:!0},{path:"/page/40",component:p("/page/40","744"),exact:!0},{path:"/page/41",component:p("/page/41","793"),exact:!0},{path:"/page/42",component:p("/page/42","0ee"),exact:!0},{path:"/page/43",component:p("/page/43","345"),exact:!0},{path:"/page/44",component:p("/page/44","3c4"),exact:!0},{path:"/page/45",component:p("/page/45","6e5"),exact:!0},{path:"/page/46",component:p("/page/46","d10"),exact:!0},{path:"/page/47",component:p("/page/47","280"),exact:!0},{path:"/page/48",component:p("/page/48","8df"),exact:!0},{path:"/page/49",component:p("/page/49","282"),exact:!0},{path:"/page/5",component:p("/page/5","87c"),exact:!0},{path:"/page/50",component:p("/page/50","3c4"),exact:!0},{path:"/page/51",component:p("/page/51","658"),exact:!0},{path:"/page/6",component:p("/page/6","a58"),exact:!0},{path:"/page/7",component:p("/page/7","bb8"),exact:!0},{path:"/page/8",component:p("/page/8","2f3"),exact:!0},{path:"/page/9",component:p("/page/9","88d"),exact:!0},{path:"/parameterized-tests",component:p("/parameterized-tests","1fb"),exact:!0},{path:"/performance-test-type",component:p("/performance-test-type","df3"),exact:!0},{path:"/racing-car-retrospective",component:p("/racing-car-retrospective","ebc"),exact:!0},{path:"/refactoring-retrospective",component:p("/refactoring-retrospective","ab4"),exact:!0},{path:"/route-image-async-with-event",component:p("/route-image-async-with-event","832"),exact:!0},{path:"/route-image-implementation",component:p("/route-image-implementation","b0f"),exact:!0},{path:"/route-image-intro",component:p("/route-image-intro","7e7"),exact:!0},{path:"/route-image-python",component:p("/route-image-python","dfd"),exact:!0},{path:"/search",component:p("/search","c1e"),exact:!0},{path:"/shopping-cart-retrospective",component:p("/shopping-cart-retrospective","28b"),exact:!0},{path:"/spring-test-isolation",component:p("/spring-test-isolation","8ed"),exact:!0},{path:"/subway-retrospective",component:p("/subway-retrospective","7db"),exact:!0},{path:"/tags",component:p("/tags","4bf"),exact:!0},{path:"/tags/async",component:p("/tags/async","a21"),exact:!0},{path:"/tags/async/page/2",component:p("/tags/async/page/2","436"),exact:!0},{path:"/tags/awt",component:p("/tags/awt","9e3"),exact:!0},{path:"/tags/awt/page/2",component:p("/tags/awt/page/2","b68"),exact:!0},{path:"/tags/book",component:p("/tags/book","4df"),exact:!0},{path:"/tags/book/page/2",component:p("/tags/book/page/2","88a"),exact:!0},{path:"/tags/book/page/3",component:p("/tags/book/page/3","128"),exact:!0},{path:"/tags/class",component:p("/tags/class","d3d"),exact:!0},{path:"/tags/cloudwatch",component:p("/tags/cloudwatch","264"),exact:!0},{path:"/tags/composite",component:p("/tags/composite","931"),exact:!0},{path:"/tags/data-base",component:p("/tags/data-base","2fe"),exact:!0},{path:"/tags/data-base/page/2",component:p("/tags/data-base/page/2","049"),exact:!0},{path:"/tags/data-base/page/3",component:p("/tags/data-base/page/3","9ac"),exact:!0},{path:"/tags/documentation",component:p("/tags/documentation","86d"),exact:!0},{path:"/tags/dto",component:p("/tags/dto","bef"),exact:!0},{path:"/tags/elastic-beanstalk",component:p("/tags/elastic-beanstalk","164"),exact:!0},{path:"/tags/event",component:p("/tags/event","56a"),exact:!0},{path:"/tags/exception",component:p("/tags/exception","5b1"),exact:!0},{path:"/tags/grasp",component:p("/tags/grasp","130"),exact:!0},{path:"/tags/image",component:p("/tags/image","067"),exact:!0},{path:"/tags/image/page/2",component:p("/tags/image/page/2","88a"),exact:!0},{path:"/tags/image/page/3",component:p("/tags/image/page/3","acc"),exact:!0},{path:"/tags/inno-db",component:p("/tags/inno-db","2aa"),exact:!0},{path:"/tags/intelli-j",component:p("/tags/intelli-j","aaa"),exact:!0},{path:"/tags/isolation",component:p("/tags/isolation","bab"),exact:!0},{path:"/tags/java",component:p("/tags/java","60d"),exact:!0},{path:"/tags/java/page/2",component:p("/tags/java/page/2","d9f"),exact:!0},{path:"/tags/java/page/3",component:p("/tags/java/page/3","d2c"),exact:!0},{path:"/tags/java/page/4",component:p("/tags/java/page/4","c97"),exact:!0},{path:"/tags/java/page/5",component:p("/tags/java/page/5","6c7"),exact:!0},{path:"/tags/jdbc",component:p("/tags/jdbc","667"),exact:!0},{path:"/tags/jenkins",component:p("/tags/jenkins","590"),exact:!0},{path:"/tags/kotlin",component:p("/tags/kotlin","b84"),exact:!0},{path:"/tags/lock",component:p("/tags/lock","059"),exact:!0},{path:"/tags/lock/page/2",component:p("/tags/lock/page/2","2e3"),exact:!0},{path:"/tags/log",component:p("/tags/log","0ae"),exact:!0},{path:"/tags/mock",component:p("/tags/mock","9dd"),exact:!0},{path:"/tags/mockito",component:p("/tags/mockito","3de"),exact:!0},{path:"/tags/monitoring",component:p("/tags/monitoring","775"),exact:!0},{path:"/tags/my-sql",component:p("/tags/my-sql","214"),exact:!0},{path:"/tags/mysql",component:p("/tags/mysql","79d"),exact:!0},{path:"/tags/oop",component:p("/tags/oop","613"),exact:!0},{path:"/tags/pattern",component:p("/tags/pattern","5e4"),exact:!0},{path:"/tags/performance-test",component:p("/tags/performance-test","d3e"),exact:!0},{path:"/tags/python",component:p("/tags/python","7fe"),exact:!0},{path:"/tags/replication",component:p("/tags/replication","77b"),exact:!0},{path:"/tags/retrospective",component:p("/tags/retrospective","b64"),exact:!0},{path:"/tags/retrospective/page/10",component:p("/tags/retrospective/page/10","ba6"),exact:!0},{path:"/tags/retrospective/page/11",component:p("/tags/retrospective/page/11","c54"),exact:!0},{path:"/tags/retrospective/page/12",component:p("/tags/retrospective/page/12","443"),exact:!0},{path:"/tags/retrospective/page/13",component:p("/tags/retrospective/page/13","b71"),exact:!0},{path:"/tags/retrospective/page/14",component:p("/tags/retrospective/page/14","e01"),exact:!0},{path:"/tags/retrospective/page/15",component:p("/tags/retrospective/page/15","64b"),exact:!0},{path:"/tags/retrospective/page/16",component:p("/tags/retrospective/page/16","703"),exact:!0},{path:"/tags/retrospective/page/17",component:p("/tags/retrospective/page/17","2d8"),exact:!0},{path:"/tags/retrospective/page/18",component:p("/tags/retrospective/page/18","1fd"),exact:!0},{path:"/tags/retrospective/page/19",component:p("/tags/retrospective/page/19","d19"),exact:!0},{path:"/tags/retrospective/page/2",component:p("/tags/retrospective/page/2","8bf"),exact:!0},{path:"/tags/retrospective/page/20",component:p("/tags/retrospective/page/20","f75"),exact:!0},{path:"/tags/retrospective/page/3",component:p("/tags/retrospective/page/3","998"),exact:!0},{path:"/tags/retrospective/page/4",component:p("/tags/retrospective/page/4","23f"),exact:!0},{path:"/tags/retrospective/page/5",component:p("/tags/retrospective/page/5","b0c"),exact:!0},{path:"/tags/retrospective/page/6",component:p("/tags/retrospective/page/6","58e"),exact:!0},{path:"/tags/retrospective/page/7",component:p("/tags/retrospective/page/7","133"),exact:!0},{path:"/tags/retrospective/page/8",component:p("/tags/retrospective/page/8","c6e"),exact:!0},{path:"/tags/retrospective/page/9",component:p("/tags/retrospective/page/9","a37"),exact:!0},{path:"/tags/spring",component:p("/tags/spring","ab2"),exact:!0},{path:"/tags/spring-boot",component:p("/tags/spring-boot","eb7"),exact:!0},{path:"/tags/static",component:p("/tags/static","dd5"),exact:!0},{path:"/tags/teco-chat",component:p("/tags/teco-chat","7a9"),exact:!0},{path:"/tags/teco-chat/page/2",component:p("/tags/teco-chat/page/2","fbf"),exact:!0},{path:"/tags/teco-chat/page/3",component:p("/tags/teco-chat/page/3","c3d"),exact:!0},{path:"/tags/test",component:p("/tags/test","84f"),exact:!0},{path:"/tags/test/page/2",component:p("/tags/test/page/2","3a8"),exact:!0},{path:"/tags/time",component:p("/tags/time","f3d"),exact:!0},{path:"/tags/transaction",component:p("/tags/transaction","622"),exact:!0},{path:"/tags/web-application",component:p("/tags/web-application","4a3"),exact:!0},{path:"/tags/web-socket",component:p("/tags/web-socket","e59"),exact:!0},{path:"/tags/woowahan-techcourse",component:p("/tags/woowahan-techcourse","77a"),exact:!0},{path:"/tags/woowahan-techcourse/page/10",component:p("/tags/woowahan-techcourse/page/10","156"),exact:!0},{path:"/tags/woowahan-techcourse/page/11",component:p("/tags/woowahan-techcourse/page/11","703"),exact:!0},{path:"/tags/woowahan-techcourse/page/12",component:p("/tags/woowahan-techcourse/page/12","38f"),exact:!0},{path:"/tags/woowahan-techcourse/page/13",component:p("/tags/woowahan-techcourse/page/13","ddd"),exact:!0},{path:"/tags/woowahan-techcourse/page/14",component:p("/tags/woowahan-techcourse/page/14","65c"),exact:!0},{path:"/tags/woowahan-techcourse/page/15",component:p("/tags/woowahan-techcourse/page/15","a2e"),exact:!0},{path:"/tags/woowahan-techcourse/page/16",component:p("/tags/woowahan-techcourse/page/16","53e"),exact:!0},{path:"/tags/woowahan-techcourse/page/2",component:p("/tags/woowahan-techcourse/page/2","047"),exact:!0},{path:"/tags/woowahan-techcourse/page/3",component:p("/tags/woowahan-techcourse/page/3","d3f"),exact:!0},{path:"/tags/woowahan-techcourse/page/4",component:p("/tags/woowahan-techcourse/page/4","5b6"),exact:!0},{path:"/tags/woowahan-techcourse/page/5",component:p("/tags/woowahan-techcourse/page/5","135"),exact:!0},{path:"/tags/woowahan-techcourse/page/6",component:p("/tags/woowahan-techcourse/page/6","5e8"),exact:!0},{path:"/tags/woowahan-techcourse/page/7",component:p("/tags/woowahan-techcourse/page/7","a11"),exact:!0},{path:"/tags/woowahan-techcourse/page/8",component:p("/tags/woowahan-techcourse/page/8","a7b"),exact:!0},{path:"/tags/woowahan-techcourse/page/9",component:p("/tags/woowahan-techcourse/page/9","be6"),exact:!0},{path:"/tecochat-retrospective-1",component:p("/tecochat-retrospective-1","ed9"),exact:!0},{path:"/tecochat-retrospective-2",component:p("/tecochat-retrospective-2","fc4"),exact:!0},{path:"/tecochat-retrospective-3",component:p("/tecochat-retrospective-3","6f4"),exact:!0},{path:"/test-double",component:p("/test-double","8ea"),exact:!0},{path:"/the-essence-of-object-orientation",component:p("/the-essence-of-object-orientation","9a2"),exact:!0},{path:"/tomcat-retrospective",component:p("/tomcat-retrospective","5a3"),exact:!0},{path:"/transaction-and-isolation",component:p("/transaction-and-isolation","d60"),exact:!0},{path:"/web-application-evolution",component:p("/web-application-evolution","c55"),exact:!0},{path:"/web-racing-car-retrospective",component:p("/web-racing-car-retrospective","ccb"),exact:!0},{path:"/websocket",component:p("/websocket","5c1"),exact:!0},{path:"/woowacourse-level1-retrospective",component:p("/woowacourse-level1-retrospective","a6a"),exact:!0},{path:"/woowacourse-level2-retrospective",component:p("/woowacourse-level2-retrospective","758"),exact:!0},{path:"/woowacourse-level3-retrospective",component:p("/woowacourse-level3-retrospective","4e5"),exact:!0},{path:"/docs",component:p("/docs","fab"),routes:[{path:"/docs",component:p("/docs","818"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/architecture/virtical-slice-architecture",component:p("/docs/architecture/virtical-slice-architecture","825"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/book/getting-out-of-the-box",component:p("/docs/book/getting-out-of-the-box","8e1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/culture/postmortem",component:p("/docs/culture/postmortem","420"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/database/maximumPoolSize",component:p("/docs/database/maximumPoolSize","9ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/database/query-execution",component:p("/docs/database/query-execution","7b8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/deploy/zero-downtime",component:p("/docs/deploy/zero-downtime","20f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/design/package",component:p("/docs/design/package","274"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/etc/communication",component:p("/docs/etc/communication","9c1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/etc/develop-with-spring",component:p("/docs/etc/develop-with-spring","9ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/etc/experience-and-self-question",component:p("/docs/etc/experience-and-self-question","d25"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/etc/healthful-growth",component:p("/docs/etc/healthful-growth","fcf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/java/sequenced-collection",component:p("/docs/java/sequenced-collection","bda"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/jpa/key",component:p("/docs/jpa/key","68b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/linux/shell",component:p("/docs/linux/shell","c5b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/linux/swap",component:p("/docs/linux/swap","9d5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/mac/java",component:p("/docs/mac/java","5a9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/monitoring/intro",component:p("/docs/monitoring/intro","5db"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/network/load-balancing",component:p("/docs/network/load-balancing","caa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/network/load-balancing-algorithm",component:p("/docs/network/load-balancing-algorithm","a4d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/nginx/command",component:p("/docs/nginx/command","0e3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/nginx/static-file",component:p("/docs/nginx/static-file","629"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/performance/throughput",component:p("/docs/performance/throughput","56a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/performance/throughput-latency",component:p("/docs/performance/throughput-latency","12a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/performance/types",component:p("/docs/performance/types","c08"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/spring/essence",component:p("/docs/spring/essence","4c6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/test/benefit",component:p("/docs/test/benefit","6c8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/test/first",component:p("/docs/test/first","566"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/test/heuristics",component:p("/docs/test/heuristics","b35"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/test/stairstep",component:p("/docs/test/stairstep","a57"),exact:!0,sidebar:"tutorialSidebar"}]},{path:"/",component:p("/","3ce"),exact:!0},{path:"/",component:p("/","956"),exact:!0},{path:"*",component:p("*")}]},98934:(e,t,n)=>{"use strict";n.d(t,{_:()=>r,t:()=>o});var a=n(67294);const r=a.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,a.useState)(!1);return(0,a.useEffect)((()=>{o(!0)}),[]),a.createElement(r.Provider,{value:n},t)}},97221:(e,t,n)=>{"use strict";var a=n(67294),r=n(73935),o=n(73727),i=n(70405),s=n(10412);const l=[n(56657),n(32497),n(3310),n(18320),n(52295)];var c=n(723),u=n(16550),d=n(18790);function p(e){let{children:t}=e;return a.createElement(a.Fragment,null,t)}var f=n(87462),g=n(35742),m=n(52263),h=n(44996),b=n(86668),v=n(10833),y=n(94711),w=n(19727),_=n(43320),x=n(18780),k=n(90197);function E(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,m.Z)(),n=(0,y.l)();return a.createElement(g.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:r}]=e;return a.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:r})})),a.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function S(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,m.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,m.Z)(),{pathname:a}=(0,u.TH)();return e+(0,x.applyTrailingSlash)((0,h.Z)(a),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return a.createElement(g.Z,null,a.createElement("meta",{property:"og:url",content:o}),a.createElement("link",{rel:"canonical",href:o}))}function T(){const{i18n:{currentLocale:e}}=(0,m.Z)(),{metadata:t,image:n}=(0,b.L)();return a.createElement(a.Fragment,null,a.createElement(g.Z,null,a.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),a.createElement("body",{className:w.h})),n&&a.createElement(v.d,{image:n}),a.createElement(S,null),a.createElement(E,null),a.createElement(k.Z,{tag:_.HX,locale:e}),a.createElement(g.Z,null,t.map(((e,t)=>a.createElement("meta",(0,f.Z)({key:t},e))))))}const C=new Map;function A(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var L=n(98934),P=n(58940);function N(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];const r=l.map((t=>(t.default?.[e]??t[e])?.(...n)));return()=>r.forEach((e=>e?.()))}const j=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,a.useLayoutEffect)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const a=t.pathname===n.pathname,r=t.hash===n.hash,o=t.search===n.search;if(a&&r&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1));document.getElementById(e)?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),N("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class M extends a.Component{constructor(e){super(e),this.previousLocation=void 0,this.routeUpdateCleanupCb=void 0,this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?N("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=N("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return a.createElement(j,{previousLocation:this.previousLocation,location:t},a.createElement(u.AW,{location:t,render:()=>e}))}}const R=M,I="__docusaurus-base-url-issue-banner-container",D="__docusaurus-base-url-issue-banner-suggestion-container",B="__DOCUSAURUS_INSERT_BASEURL_BANNER";function F(e){return`\nwindow['${B}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${B}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${I}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="__docusaurus-base-url-issue-banner" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${D}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n var suggestionContainer = document.getElementById('${D}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function $(){const{siteConfig:{baseUrl:e}}=(0,m.Z)();return(0,a.useLayoutEffect)((()=>{window[B]=!1}),[]),a.createElement(a.Fragment,null,!s.Z.canUseDOM&&a.createElement(g.Z,null,a.createElement("script",null,F(e))),a.createElement("div",{id:I}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,m.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?a.createElement($,null):null}function z(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:r,localeConfigs:o}}=(0,m.Z)(),i=(0,h.Z)(e),{htmlLang:s,direction:l}=o[r];return a.createElement(g.Z,null,a.createElement("html",{lang:s,dir:l}),a.createElement("title",null,t),a.createElement("meta",{property:"og:title",content:t}),a.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&a.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&a.createElement("link",{rel:"icon",href:i}))}var Z=n(44763),H=n(72389);function V(){const e=(0,H.Z)();return a.createElement(g.Z,null,a.createElement("html",{"data-has-hydrated":e}))}function q(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return a.createElement(Z.Z,null,a.createElement(P.M,null,a.createElement(L.t,null,a.createElement(p,null,a.createElement(z,null),a.createElement(T,null),a.createElement(U,null),a.createElement(R,{location:A(t)},e)),a.createElement(V,null))))}var W=n(16887);const G=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const a=document.createElement("link");a.setAttribute("rel","prefetch"),a.setAttribute("href",e),a.onload=()=>t(),a.onerror=()=>n();(document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode)?.appendChild(a)}))}:function(e){return new Promise(((t,n)=>{const a=new XMLHttpRequest;a.open("GET",e,!0),a.withCredentials=!0,a.onload=()=>{200===a.status?t():n()},a.send(null)}))};var K=n(99670);const Y=new Set,Q=new Set,X=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,J={prefetch(e){if(!(e=>!X()&&!Q.has(e)&&!Y.has(e))(e))return!1;Y.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(W).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,K.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?G(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!X()&&!Q.has(e))(e)&&(Q.add(e),O(e))},ee=Object.freeze(J);if(s.Z.canUseDOM){window.docusaurus=ee;const e=r.hydrate;O(window.location.pathname).then((()=>{e(a.createElement(i.B6,null,a.createElement(o.VK,null,a.createElement(q,null))),document.getElementById("__docusaurus"))}))}},58940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var a=n(67294),r=n(36809);const o=JSON.parse('{"docusaurus-plugin-google-gtag":{"default":{"trackingID":["G-17TREGCW4H"],"anonymizeIP":true,"id":"default"}},"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"intro","docs":[{"id":"intro","path":"/docs/","sidebar":"tutorialSidebar"},{"id":"Java/SequencedCollection","path":"/docs/java/sequenced-collection","sidebar":"tutorialSidebar"},{"id":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551","path":"/docs/jpa/key","sidebar":"tutorialSidebar"},{"id":"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","path":"/docs/mac/java","sidebar":"tutorialSidebar"},{"id":"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4","path":"/docs/nginx/command","sidebar":"tutorialSidebar"},{"id":"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5","path":"/docs/nginx/static-file","sidebar":"tutorialSidebar"},{"id":"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","path":"/docs/etc/healthful-growth","sidebar":"tutorialSidebar"},{"id":"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","path":"/docs/etc/develop-with-spring","sidebar":"tutorialSidebar"},{"id":"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8","path":"/docs/etc/experience-and-self-question","sidebar":"tutorialSidebar"},{"id":"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","path":"/docs/etc/communication","sidebar":"tutorialSidebar"},{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","path":"/docs/network/load-balancing","sidebar":"tutorialSidebar"},{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","path":"/docs/network/load-balancing-algorithm","sidebar":"tutorialSidebar"},{"id":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool","path":"/docs/database/maximumPoolSize","sidebar":"tutorialSidebar"},{"id":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","path":"/docs/database/query-execution","sidebar":"tutorialSidebar"},{"id":"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","path":"/docs/book/getting-out-of-the-box","sidebar":"tutorialSidebar"},{"id":"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815","path":"/docs/linux/swap","sidebar":"tutorialSidebar"},{"id":"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","path":"/docs/linux/shell","sidebar":"tutorialSidebar"},{"id":"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","path":"/docs/monitoring/intro","sidebar":"tutorialSidebar"},{"id":"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","path":"/docs/culture/postmortem","sidebar":"tutorialSidebar"},{"id":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","path":"/docs/deploy/zero-downtime","sidebar":"tutorialSidebar"},{"id":"\uc124\uacc4/\ud328\ud0a4\uc9c0","path":"/docs/design/package","sidebar":"tutorialSidebar"},{"id":"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12","path":"/docs/performance/throughput","sidebar":"tutorialSidebar"},{"id":"\uc131\ub2a5/Throughput\uacfc Latency","path":"/docs/performance/throughput-latency","sidebar":"tutorialSidebar"},{"id":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","path":"/docs/performance/types","sidebar":"tutorialSidebar"},{"id":"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","path":"/docs/spring/essence","sidebar":"tutorialSidebar"},{"id":"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","path":"/docs/architecture/virtical-slice-architecture","sidebar":"tutorialSidebar"},{"id":"\ud14c\uc2a4\ud2b8/FIRST","path":"/docs/test/first","sidebar":"tutorialSidebar"},{"id":"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","path":"/docs/test/stairstep","sidebar":"tutorialSidebar"},{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59","path":"/docs/test/heuristics","sidebar":"tutorialSidebar"},{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","path":"/docs/test/benefit","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/jpa/key","label":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"ko","locales":["ko"],"path":"i18n","currentLocale":"ko","localeConfigs":{"ko":{"label":"\ud55c\uad6d\uc5b4","direction":"ltr","htmlLang":"ko","calendar":"gregory","path":"ko"}}}');var s=n(57529);const l=JSON.parse('{"docusaurusVersion":"2.4.3","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.3"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.3"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.3"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"2.4.3"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.3"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.3"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.4.3"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"2.4.3"}}}'),c={siteConfig:r.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},u=a.createContext(c);function d(e){let{children:t}=e;return a.createElement(u.Provider,{value:c},t)}},44763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var a=n(67294),r=n(10412),o=n(35742),i=n(18780),s=n(7452);function l(e){let{error:t,tryAgain:n}=e;return a.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},a.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),a.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),a.createElement(c,{error:t}))}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return a.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function u(e){let{error:t,tryAgain:n}=e;return a.createElement(p,{fallback:()=>a.createElement(l,{error:t,tryAgain:n})},a.createElement(o.Z,null,a.createElement("title",null,"Page Error")),a.createElement(s.Z,null,a.createElement(l,{error:t,tryAgain:n})))}const d=e=>a.createElement(u,e);class p extends a.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){r.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},10412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const a="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,r={canUseDOM:a,canUseEventListeners:a&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:a&&"IntersectionObserver"in window,canUseViewport:a&&"screen"in window}},35742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=n(67294),r=n(70405);function o(e){return a.createElement(r.ql,e)}},39960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var a=n(87462),r=n(67294),o=n(73727),i=n(18780),s=n(52263),l=n(13919),c=n(10412);const u=r.createContext({collectLink:()=>{}});var d=n(44996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:g,isActive:m,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,s.Z)(),{withBaseUrl:_}=(0,d.C)(),x=(0,r.useContext)(u),k=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>k.current));const E=p||f;const S=(0,l.Z)(E),T=E?.replace("pathname://","");let C=void 0!==T?(A=T,b&&(e=>e.startsWith("/"))(A)?_(A):A):void 0;var A;C&&S&&(C=(0,i.applyTrailingSlash)(C,{trailingSlash:y,baseUrl:w}));const L=(0,r.useRef)(!1),P=n?o.OL:o.rU,N=c.Z.canUseIntersectionObserver,j=(0,r.useRef)(),O=()=>{L.current||null==C||(window.docusaurus.preload(C),L.current=!0)};(0,r.useEffect)((()=>(!N&&S&&null!=C&&window.docusaurus.prefetch(C),()=>{N&&j.current&&j.current.disconnect()})),[j,C,N,S]);const M=C?.startsWith("#")??!1,R=!C||!S||M;return R||h||x.collectLink(C),R?r.createElement("a",(0,a.Z)({ref:k,href:C},E&&!S&&{target:"_blank",rel:"noopener noreferrer"},v)):r.createElement(P,(0,a.Z)({},v,{onMouseEnter:O,onTouchStart:O,innerRef:e=>{k.current=e,N&&e&&S&&(j.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(j.current.unobserve(e),j.current.disconnect(),null!=C&&window.docusaurus.prefetch(C))}))})),j.current.observe(e))},to:C},n&&{isActive:m,activeClassName:g}))}const f=r.forwardRef(p)},95999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l,I:()=>s});var a=n(67294);function r(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,a.isValidElement)(e)))?n.map(((e,t)=>(0,a.isValidElement)(e)?a.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(57529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function s(e,t){let{message:n,id:a}=e;return r(i({message:n,id:a}),t)}function l(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const s=i({message:t,id:n});return a.createElement(a.Fragment,null,r(s,o))}},29935:(e,t,n)=>{"use strict";n.d(t,{m:()=>a});const a="default"},13919:(e,t,n)=>{"use strict";function a(e){return/^(?:\w*:|\/\/)/.test(e)}function r(e){return void 0!==e&&!a(e)}n.d(t,{Z:()=>r,b:()=>a})},44996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var a=n(67294),r=n(52263),o=n(13919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,r.Z)(),n=(0,a.useCallback)(((n,a)=>function(e,t,n,a){let{forcePrependBaseUrl:r=!1,absolute:i=!1}=void 0===a?{}:a;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(r)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,a)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},52263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=n(67294),r=n(58940);function o(){return(0,a.useContext)(r._)}},72389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=n(67294),r=n(98934);function o(){return(0,a.useContext)(r._)}},99670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[r,o]=n;const i=a?`${a}.${r}`:r;var s;"object"==typeof(s=o)&&s&&Object.keys(s).length>0?e(o,i):t[i]=o}))}(e),t}},30226:(e,t,n)=>{"use strict";n.d(t,{_:()=>r,z:()=>o});var a=n(67294);const r=a.createContext(null);function o(e){let{children:t,value:n}=e;const o=a.useContext(r),i=(0,a.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const a={...t.data,...n?.data};return{plugin:t.plugin,data:a}}({parent:o,value:n})),[o,n]);return a.createElement(r.Provider,{value:i},t)}},80143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>b,gA:()=>f,WS:()=>g,_r:()=>d,Jo:()=>v,zh:()=>p,yW:()=>h,gB:()=>m});var a=n(16550),r=n(52263),o=n(29935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,r.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,a.LX)(t,{path:e.path,exact:!1,strict:!1})))}function c(e,t){const n=l(e,t),r=n?.docs.find((e=>!!(0,a.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:r,alternateDocVersions:r?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((a=>{a.id===t&&(n[e.name]=a)}))})),n}(r.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,p=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const a=i(e)?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,a.TH)();return function(e,t,n){void 0===n&&(n={});const r=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,a.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=r?{pluginId:r[0],pluginData:r[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function g(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,a.TH)();if(!t)return;return{activePlugin:t,activeVersion:l(t.pluginData,n)}}function m(e){return p(e).versions}function h(e){const t=p(e);return s(t)}function b(e){const t=p(e),{pathname:n}=(0,a.TH)();return c(t,n)}function v(e){const t=p(e),{pathname:n}=(0,a.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},56657:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});const a={onRouteDidUpdate(e){let{location:t,previousLocation:n}=e;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((()=>{window.gtag("event","page_view",{page_title:document.title,page_location:window.location.href,page_path:t.pathname+t.search+t.hash})}))}}},18320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var a=n(74865),r=n.n(a);r().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{r().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){r().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var a=n(87410),r=n(36809);!function(e){const{themeConfig:{prism:t}}=r.default,{additionalLanguages:a}=t;globalThis.Prism=e,a.forEach((e=>{n(52811)(`./prism-${e}`)})),delete globalThis.Prism}(a.Z)},39471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=n(67294);const r="iconExternalLink_nPIU";function o(e){let{width:t=13.5,height:n=13.5}=e;return a.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r},a.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7452:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Ot});var a=n(67294),r=n(86010),o=n(44763),i=n(10833),s=n(87462),l=n(16550),c=n(95999),u=n(85936);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,a.useRef)(null),{action:t}=(0,l.k6)(),n=(0,a.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,u.S)((n=>{let{location:a}=n;e.current&&!a.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,c.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??g,{containerRef:n,onClick:r}=f();return a.createElement("div",{ref:n,role:"region","aria-label":g},a.createElement("a",(0,s.Z)({},e,{href:`#${d}`,onClick:r}),t))}var h=n(35281),b=n(19727);const v="skipToContent_fXgn";function y(){return a.createElement(m,{className:v})}var w=n(86668),_=n(59689);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:i,...l}=e;return a.createElement("svg",(0,s.Z)({viewBox:"0 0 15 15",width:t,height:n},l),a.createElement("g",{stroke:r,strokeWidth:o},a.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const k="closeButton_CVFx";function E(e){return a.createElement("button",(0,s.Z)({type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,r.Z)("clean-btn close",k,e.className)}),a.createElement(x,{width:14,height:14,strokeWidth:3.1}))}const S="content_knG7";function T(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return a.createElement("div",(0,s.Z)({},e,{className:(0,r.Z)(S,e.className),dangerouslySetInnerHTML:{__html:n}}))}const C="announcementBar_mb4j",A="announcementBarPlaceholder_vyr4",L="announcementBarClose_gvF7",P="announcementBarContent_xLdY";function N(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,_.nT)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:i}=e;return a.createElement("div",{className:C,style:{backgroundColor:r,color:o},role:"banner"},i&&a.createElement("div",{className:A}),a.createElement(T,{className:P}),i&&a.createElement(E,{onClick:n,className:L}))}var j=n(93163),O=n(12466);var M=n(902),R=n(13102);const I=a.createContext(null);function D(e){let{children:t}=e;const n=function(){const e=(0,j.e)(),t=(0,R.HY)(),[n,r]=(0,a.useState)(!1),o=null!==t.component,i=(0,M.D9)(o);return(0,a.useEffect)((()=>{o&&!i&&r(!0)}),[o,i]),(0,a.useEffect)((()=>{o?e.shown||r(!0):r(!1)}),[e.shown,o]),(0,a.useMemo)((()=>[n,r]),[n])}();return a.createElement(I.Provider,{value:n},t)}function B(e){if(e.component){const t=e.component;return a.createElement(t,e.props)}}function F(){const e=(0,a.useContext)(I);if(!e)throw new M.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,r=(0,a.useCallback)((()=>n(!1)),[n]),o=(0,R.HY)();return(0,a.useMemo)((()=>({shown:t,hide:r,content:B(o)})),[r,o,t])}function $(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=F();return a.createElement("div",{className:"navbar-sidebar"},t,a.createElement("div",{className:(0,r.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},a.createElement("div",{className:"navbar-sidebar__item menu"},n),a.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var U=n(92949),z=n(72389);function Z(e){return a.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),a.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function H(e){return a.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),a.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const V={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const s=(0,z.Z)(),l=(0,c.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return a.createElement("div",{className:(0,r.Z)(V.toggle,t)},a.createElement("button",{className:(0,r.Z)("clean-btn",V.toggleButton,!s&&V.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!s,title:l,"aria-label":l,"aria-live":"polite"},a.createElement(Z,{className:(0,r.Z)(V.toggleIcon,V.lightToggleIcon)}),a.createElement(H,{className:(0,r.Z)(V.toggleIcon,V.darkToggleIcon)})))}const W=a.memo(q),G="darkNavbarColorModeToggle_X3D1";function K(e){let{className:t}=e;const n=(0,w.L)().navbar.style,r=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,U.I)();return r?null:a.createElement(W,{className:t,buttonClassName:"dark"===n?G:void 0,value:o,onChange:i})}var Y=n(21327);function Q(){return a.createElement(Y.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function X(){const e=(0,j.e)();return a.createElement("button",{type:"button","aria-label":(0,c.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},a.createElement(x,{color:"var(--ifm-color-emphasis-600)"}))}function J(){return a.createElement("div",{className:"navbar-sidebar__brand"},a.createElement(Q,null),a.createElement(K,{className:"margin-right--md"}),a.createElement(X,null))}var ee=n(39960),te=n(44996),ne=n(13919),ae=n(98022),re=n(39471);function oe(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:i,html:l,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const p=(0,te.Z)(r),f=(0,te.Z)(t),g=(0,te.Z)(o,{forcePrependBaseUrl:!0}),m=i&&o&&!(0,ne.Z)(o),h=l?{dangerouslySetInnerHTML:{__html:l}}:{children:a.createElement(a.Fragment,null,i,m&&a.createElement(re.Z,c&&{width:12,height:12}))};return o?a.createElement(ee.Z,(0,s.Z)({href:u?g:o},d,h)):a.createElement(ee.Z,(0,s.Z)({to:p,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?(0,ae.F)(n,t.pathname):t.pathname.startsWith(f)},d,h))}function ie(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=a.createElement(oe,(0,s.Z)({className:(0,r.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?a.createElement("li",null,i):i}function se(e){let{className:t,isDropdownItem:n,...o}=e;return a.createElement("li",{className:"menu__list-item"},a.createElement(oe,(0,s.Z)({className:(0,r.Z)("menu__link",t)},o)))}function le(e){let{mobile:t=!1,position:n,...r}=e;const o=t?se:ie;return a.createElement(o,(0,s.Z)({},r,{activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ce=n(86043),ue=n(48596),de=n(52263);function pe(e,t){return e.some((e=>function(e,t){return!!(0,ue.Mg)(e.to,t)||!!(0,ae.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function fe(e){let{items:t,position:n,className:o,onClick:i,...l}=e;const c=(0,a.useRef)(null),[u,d]=(0,a.useState)(!1);return(0,a.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),a.createElement("div",{ref:c,className:(0,r.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},a.createElement(oe,(0,s.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:l.to?void 0:"#",className:(0,r.Z)("navbar__link",o)},l,{onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),l.children??l.label),a.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>a.createElement(qe,(0,s.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function ge(e){let{items:t,className:n,position:o,onClick:i,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,de.Z)(),{pathname:t}=(0,l.TH)();return t.replace(e,"/")}(),d=pe(t,u),{collapsed:p,toggleCollapsed:f,setCollapsed:g}=(0,ce.u)({initialState:()=>!d});return(0,a.useEffect)((()=>{d&&g(!d)}),[u,d,g]),a.createElement("li",{className:(0,r.Z)("menu__list-item",{"menu__list-item--collapsed":p})},a.createElement(oe,(0,s.Z)({role:"button",className:(0,r.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),f()}}),c.children??c.label),a.createElement(ce.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p},t.map(((e,t)=>a.createElement(qe,(0,s.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function me(e){let{mobile:t=!1,...n}=e;const r=t?ge:fe;return a.createElement(r,n)}var he=n(94711);function be(e){let{width:t=20,height:n=20,...r}=e;return a.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},r),a.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const ve="iconLanguage_nlXk";function ye(){return a.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},a.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var we=n(20830),_e=["translations"];function xe(){return xe=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},xe.apply(this,arguments)}function ke(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var a,r,o=[],i=!0,s=!1;try{for(n=n.call(e);!(i=(a=n.next()).done)&&(o.push(a.value),!t||o.length!==t);i=!0);}catch(l){s=!0,r=l}finally{try{i||null==n.return||n.return()}finally{if(s)throw r}}return o}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return Ee(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Ee(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Ee(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=new Array(t);n<t;n++)a[n]=e[n];return a}function Se(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var Te="Ctrl";var Ce=a.forwardRef((function(e,t){var n=e.translations,r=void 0===n?{}:n,o=Se(e,_e),i=r.buttonText,s=void 0===i?"Search":i,l=r.buttonAriaLabel,c=void 0===l?"Search":l,u=ke((0,a.useState)(null),2),d=u[0],p=u[1];return(0,a.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(Te))}),[]),a.createElement("button",xe({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},o,{ref:t}),a.createElement("span",{className:"DocSearch-Button-Container"},a.createElement(we.W,null),a.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),a.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&a.createElement(a.Fragment,null,a.createElement("kbd",{className:"DocSearch-Button-Key"},d===Te?a.createElement(ye,null):d),a.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Ae=n(35742),Le=n(66177),Pe=n(239),Ne=n(43320);var je=n(73935);const Oe={button:{buttonText:(0,c.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,c.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,c.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,c.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,c.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,c.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,c.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,c.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,c.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,c.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,c.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,c.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,c.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,c.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,c.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,c.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,c.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,c.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,c.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,c.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,c.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,c.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,c.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,c.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,c.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,c.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,c.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Me=null;function Re(e){let{hit:t,children:n}=e;return a.createElement(ee.Z,{to:t.url},n)}function Ie(e){let{state:t,onClose:n}=e;const r=(0,Le.M)();return a.createElement(ee.Z,{to:r(t.query),onClick:n},a.createElement(c.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits}},"See all {count} results"))}function De(e){let{contextualSearch:t,externalUrlRegex:r,...o}=e;const{siteMetadata:i}=(0,de.Z)(),c=(0,Pe.l)(),u=function(){const{locale:e,tags:t}=(0,Ne._q)();return[`language:${e}`,t.map((e=>`docusaurus_tag:${e}`))]}(),d=o.searchParameters?.facetFilters??[],p=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(u,d):d,f={...o.searchParameters,facetFilters:p},g=(0,l.k6)(),m=(0,a.useRef)(null),h=(0,a.useRef)(null),[b,v]=(0,a.useState)(!1),[y,w]=(0,a.useState)(void 0),_=(0,a.useCallback)((()=>Me?Promise.resolve():Promise.all([n.e(6780).then(n.bind(n,76780)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,46945)),Promise.all([n.e(532),n.e(2090)]).then(n.bind(n,18894))]).then((e=>{let[{DocSearchModal:t}]=e;Me=t}))),[]),x=(0,a.useCallback)((()=>{_().then((()=>{m.current=document.createElement("div"),document.body.insertBefore(m.current,document.body.firstChild),v(!0)}))}),[_,v]),k=(0,a.useCallback)((()=>{v(!1),m.current?.remove()}),[v]),E=(0,a.useCallback)((e=>{_().then((()=>{v(!0),w(e.key)}))}),[_,v,w]),S=(0,a.useRef)({navigate(e){let{itemUrl:t}=e;(0,ae.F)(r,t)?window.location.href=t:g.push(t)}}).current,T=(0,a.useRef)((e=>o.transformItems?o.transformItems(e):e.map((e=>({...e,url:c(e.url)}))))).current,C=(0,a.useMemo)((()=>e=>a.createElement(Ie,(0,s.Z)({},e,{onClose:k}))),[k]),A=(0,a.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",i.docusaurusVersion),e)),[i.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,r=e.onClose,o=e.onInput,i=e.searchButtonRef;a.useEffect((function(){function e(e){(27===e.keyCode&&t||"k"===e.key.toLowerCase()&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?r():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&o&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&o(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,r,o,i])}({isOpen:b,onOpen:x,onClose:k,onInput:E,searchButtonRef:h}),a.createElement(a.Fragment,null,a.createElement(Ae.Z,null,a.createElement("link",{rel:"preconnect",href:`https://${o.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})),a.createElement(Ce,{onTouchStart:_,onFocus:_,onMouseOver:_,onClick:x,ref:h,translations:Oe.button}),b&&Me&&m.current&&(0,je.createPortal)(a.createElement(Me,(0,s.Z)({onClose:k,initialScrollY:window.scrollY,initialQuery:y,navigator:S,transformItems:T,hitComponent:Re,transformSearchClient:A},o.searchPagePath&&{resultsFooterComponent:C},o,{searchParameters:f,placeholder:Oe.placeholder,translations:Oe.modal})),m.current))}function Be(){const{siteConfig:e}=(0,de.Z)();return a.createElement(De,e.themeConfig.algolia)}const Fe="searchBox_ZlJk";function $e(e){let{children:t,className:n}=e;return a.createElement("div",{className:(0,r.Z)(n,Fe)},t)}var Ue=n(80143),ze=n(53438);var Ze=n(60373);const He=e=>e.docs.find((t=>t.id===e.mainDocId));const Ve={default:le,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,de.Z)(),p=(0,he.l)(),{search:f,hash:g}=(0,l.TH)(),m=[...n,...u.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${g}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],h=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return a.createElement(me,(0,s.Z)({},o,{mobile:t,label:a.createElement(a.Fragment,null,a.createElement(be,{className:ve}),h),items:m}))},search:function(e){let{mobile:t,className:n}=e;return t?null:a.createElement($e,{className:n},a.createElement(Be,null))},dropdown:me,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const s=i?"li":"div";return a.createElement(s,{className:(0,r.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:i}=(0,Ue.Iw)(r),l=(0,ze.vY)(t,r);return null===l?null:a.createElement(le,(0,s.Z)({exact:!0},o,{isActive:()=>i?.path===l.path||!!i?.sidebar&&i.sidebar===l.sidebar,label:n??l.id,to:l.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:i}=(0,Ue.Iw)(r),l=(0,ze.oz)(t,r).link;if(!l)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return a.createElement(le,(0,s.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??l.label,to:l.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const i=(0,ze.lO)(r)[0],l=t??i.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return a.createElement(le,(0,s.Z)({},o,{label:l,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:p}=(0,l.TH)(),f=(0,Ue.Iw)(n),g=(0,Ue.gB)(n),{savePreferredVersionName:m}=(0,Ze.J)(n),h=[...o,...g.map((e=>{const t=f.alternateDocVersions[e.name]??He(e);return{label:e.label,to:`${t.path}${d}${p}`,isActive:()=>e===f.activeVersion,onClick:()=>m(e.name)}})),...i],b=(0,ze.lO)(n)[0],v=t&&h.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&h.length>1?void 0:He(b).path;return h.length<=1?a.createElement(le,(0,s.Z)({},u,{mobile:t,label:v,to:y,isActive:r?()=>!1:void 0})):a.createElement(me,(0,s.Z)({},u,{mobile:t,label:v,to:y,items:h,isActive:r?()=>!1:void 0}))}};function qe(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ve[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return a.createElement(o,n)}function We(){const e=(0,j.e)(),t=(0,w.L)().navbar.items;return a.createElement("ul",{className:"menu__list"},t.map(((t,n)=>a.createElement(qe,(0,s.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ge(e){return a.createElement("button",(0,s.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),a.createElement(c.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Ke(){const e=0===(0,w.L)().navbar.items.length,t=F();return a.createElement(a.Fragment,null,!e&&a.createElement(Ge,{onClick:()=>t.hide()}),t.content)}function Ye(){const e=(0,j.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,a.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?a.createElement($,{header:a.createElement(J,null),primaryMenu:a.createElement(We,null),secondaryMenu:a.createElement(Ke,null)}):null}const Qe="navbarHideable_m1mJ",Xe="navbarHidden_jGov";function Je(e){return a.createElement("div",(0,s.Z)({role:"presentation"},e,{className:(0,r.Z)("navbar-sidebar__backdrop",e.className)}))}function et(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,j.e)(),{navbarRef:s,isNavbarVisible:l}=function(e){const[t,n]=(0,a.useState)(e),r=(0,a.useRef)(!1),o=(0,a.useRef)(0),i=(0,a.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,O.RF)(((t,a)=>{let{scrollY:i}=t;if(!e)return;if(i<o.current)return void n(!0);if(r.current)return void(r.current=!1);const s=a?.scrollY,l=document.documentElement.scrollHeight-o.current,c=window.innerHeight;s&&i>=s?n(!1):i+c<l&&n(!0)})),(0,u.S)((t=>{if(!e)return;const a=t.location.hash;if(a?document.getElementById(a.substring(1)):void 0)return r.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return a.createElement("nav",{ref:s,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,r.Z)("navbar","navbar--fixed-top",n&&[Qe,!l&&Xe],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,a.createElement(Je,{onClick:i.toggle}),a.createElement(Ye,null))}var tt=n(18780);const nt="errorBoundaryError_a6uf";function at(e){return a.createElement("button",(0,s.Z)({type:"button"},e),a.createElement(c.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function rt(e){let{error:t}=e;const n=(0,tt.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return a.createElement("p",{className:nt},n)}class ot extends a.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}function it(e){let{width:t=30,height:n=30,className:r,...o}=e;return a.createElement("svg",(0,s.Z)({className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),a.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function st(){const{toggle:e,shown:t}=(0,j.e)();return a.createElement("button",{onClick:e,"aria-label":(0,c.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},a.createElement(it,null))}const lt="colorModeToggle_DEke";function ct(e){let{items:t}=e;return a.createElement(a.Fragment,null,t.map(((e,t)=>a.createElement(ot,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},a.createElement(qe,e)))))}function ut(e){let{left:t,right:n}=e;return a.createElement("div",{className:"navbar__inner"},a.createElement("div",{className:"navbar__items"},t),a.createElement("div",{className:"navbar__items navbar__items--right"},n))}function dt(){const e=(0,j.e)(),t=(0,w.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??"right")}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return a.createElement(ut,{left:a.createElement(a.Fragment,null,!e.disabled&&a.createElement(st,null),a.createElement(Q,null),a.createElement(ct,{items:n})),right:a.createElement(a.Fragment,null,a.createElement(ct,{items:r}),a.createElement(K,{className:lt}),!o&&a.createElement($e,null,a.createElement(Be,null)))})}function pt(){return a.createElement(et,null,a.createElement(dt,null))}function ft(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:i,...l}=t,c=(0,te.Z)(n),u=(0,te.Z)(r,{forcePrependBaseUrl:!0});return a.createElement(ee.Z,(0,s.Z)({className:"footer__link-item"},r?{href:i?u:r}:{to:c},l),o,r&&!(0,ne.Z)(r)&&a.createElement(re.Z,null))}function gt(e){let{item:t}=e;return t.html?a.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):a.createElement("li",{key:t.href??t.to,className:"footer__item"},a.createElement(ft,{item:t}))}function mt(e){let{column:t}=e;return a.createElement("div",{className:"col footer__col"},a.createElement("div",{className:"footer__title"},t.title),a.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>a.createElement(gt,{key:t,item:e})))))}function ht(e){let{columns:t}=e;return a.createElement("div",{className:"row footer__links"},t.map(((e,t)=>a.createElement(mt,{key:t,column:e}))))}function bt(){return a.createElement("span",{className:"footer__link-separator"},"\xb7")}function vt(e){let{item:t}=e;return t.html?a.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):a.createElement(ft,{item:t})}function yt(e){let{links:t}=e;return a.createElement("div",{className:"footer__links text--center"},a.createElement("div",{className:"footer__links"},t.map(((e,n)=>a.createElement(a.Fragment,{key:n},a.createElement(vt,{item:e}),t.length!==n+1&&a.createElement(bt,null))))))}function wt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?a.createElement(ht,{columns:t}):a.createElement(yt,{links:t})}var _t=n(50941);const xt="footerLogoLink_BH7S";function kt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,te.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return a.createElement(_t.Z,{className:(0,r.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function Et(e){let{logo:t}=e;return t.href?a.createElement(ee.Z,{href:t.href,className:xt,target:t.target},a.createElement(kt,{logo:t})):a.createElement(kt,{logo:t})}function St(e){let{copyright:t}=e;return a.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Tt(e){let{style:t,links:n,logo:o,copyright:i}=e;return a.createElement("footer",{className:(0,r.Z)("footer",{"footer--dark":"dark"===t})},a.createElement("div",{className:"container container-fluid"},n,(o||i)&&a.createElement("div",{className:"footer__bottom text--center"},o&&a.createElement("div",{className:"margin-bottom--sm"},o),i)))}function Ct(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return a.createElement(Tt,{style:o,links:n&&n.length>0&&a.createElement(wt,{links:n}),logo:r&&a.createElement(Et,{logo:r}),copyright:t&&a.createElement(St,{copyright:t})})}const At=a.memo(Ct),Lt=(0,M.Qc)([U.S,_.pl,O.OC,Ze.L5,i.VC,function(e){let{children:t}=e;return a.createElement(R.n2,null,a.createElement(j.M,null,a.createElement(D,null,t)))}]);function Pt(e){let{children:t}=e;return a.createElement(Lt,null,t)}function Nt(e){let{error:t,tryAgain:n}=e;return a.createElement("main",{className:"container margin-vert--xl"},a.createElement("div",{className:"row"},a.createElement("div",{className:"col col--6 col--offset-3"},a.createElement("h1",{className:"hero__title"},a.createElement(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),a.createElement("div",{className:"margin-vert--lg"},a.createElement(at,{onClick:n,className:"button button--primary shadow--lw"})),a.createElement("hr",null),a.createElement("div",{className:"margin-vert--md"},a.createElement(rt,{error:t})))))}const jt="mainWrapper_z2l0";function Ot(e){const{children:t,noFooter:n,wrapperClassName:s,title:l,description:c}=e;return(0,b.t)(),a.createElement(Pt,null,a.createElement(i.d,{title:l,description:c}),a.createElement(y,null),a.createElement(N,null),a.createElement(pt,null),a.createElement("div",{id:d,className:(0,r.Z)(h.k.wrapper.main,jt,s)},a.createElement(o.Z,{fallback:e=>a.createElement(Nt,e)},t)),!n&&a.createElement(At,null))}},21327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var a=n(87462),r=n(67294),o=n(39960),i=n(44996),s=n(52263),l=n(86668),c=n(50941);function u(e){let{logo:t,alt:n,imageClassName:a}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},s=r.createElement(c.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return a?r.createElement("div",{className:a},s):s}function d(e){const{siteConfig:{title:t}}=(0,s.Z)(),{navbar:{title:n,logo:c}}=(0,l.L)(),{imageClassName:d,titleClassName:p,...f}=e,g=(0,i.Z)(c?.href||"/"),m=n?"":t,h=c?.alt??m;return r.createElement(o.Z,(0,a.Z)({to:g},f,c?.target&&{target:c.target}),c&&r.createElement(u,{logo:c,alt:h,imageClassName:d}),null!=n&&r.createElement("b",{className:p},n))}},90197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=n(67294),r=n(35742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return a.createElement(r.Z,null,t&&a.createElement("meta",{name:"docusaurus_locale",content:t}),n&&a.createElement("meta",{name:"docusaurus_version",content:n}),o&&a.createElement("meta",{name:"docusaurus_tag",content:o}),i&&a.createElement("meta",{name:"docsearch:language",content:i}),n&&a.createElement("meta",{name:"docsearch:version",content:n}),o&&a.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},50941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var a=n(87462),r=n(67294),o=n(86010),i=n(72389),s=n(92949);const l={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,s.I)(),{sources:c,className:u,alt:d,...p}=e,f=t?"dark"===n?["dark"]:["light"]:["light","dark"];return r.createElement(r.Fragment,null,f.map((e=>r.createElement("img",(0,a.Z)({key:e,src:c[e],alt:d,className:(0,o.Z)(l.themedImage,l[`themedImage--${e}`],u)},p)))))}},86043:(e,t,n)=>{"use strict";n.d(t,{u:()=>s,z:()=>m});var a=n(87462),r=n(67294),o=n(10412),i=n(91442);function s(e){let{initialState:t}=e;const[n,a]=(0,r.useState)(t??!1),o=(0,r.useCallback)((()=>{a((e=>!e))}),[]);return{collapsed:n,setCollapsed:a,toggleCollapsed:o}}const l={display:"none",overflow:"hidden",height:"0px"},c={display:"block",overflow:"visible",height:"auto"};function u(e,t){const n=t?l:c;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function d(e){let{collapsibleRef:t,collapsed:n,animation:a}=e;const o=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=a?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${a?.easing??"ease-in-out"}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return u(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=l.height,e.style.overflow=l.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,a])}function p(e){if(!o.Z.canUseDOM)return e?l:c}function f(e){let{as:t="div",collapsed:n,children:a,animation:o,onCollapseTransitionEnd:i,className:s,disableSSRStyle:l}=e;const c=(0,r.useRef)(null);return d({collapsibleRef:c,collapsed:n,animation:o}),r.createElement(t,{ref:c,style:l?void 0:p(n),onTransitionEnd:e=>{"height"===e.propertyName&&(u(c.current,n),i?.(n))},className:s},a)}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,r.useState)(!t),[s,l]=(0,r.useState)(t);return(0,r.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,r.useLayoutEffect)((()=>{o&&l(t)}),[o,t]),o?r.createElement(f,(0,a.Z)({},n,{collapsed:s})):null}function m(e){let{lazy:t,...n}=e;const a=t?g:f;return r.createElement(a,n)}},59689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>g,pl:()=>f});var a=n(67294),r=n(72389),o=n(50012),i=n(902),s=n(86668);const l=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),u=()=>"true"===l.get(),d=e=>l.set(String(e)),p=a.createContext(null);function f(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,r.Z)(),[n,o]=(0,a.useState)((()=>!!t&&u()));(0,a.useEffect)((()=>{o(u())}),[]);const i=(0,a.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,a.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const a=t!==n;c.set(t),a&&d(!1),!a&&u()||o(!1)}),[e]),(0,a.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return a.createElement(p.Provider,{value:n},t)}function g(){const e=(0,a.useContext)(p);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},92949:(e,t,n)=>{"use strict";n.d(t,{I:()=>h,S:()=>m});var a=n(67294),r=n(10412),o=n(902),i=n(50012),s=n(86668);const l=a.createContext(void 0),c="theme",u=(0,i.WA)(c),d="light",p="dark",f=e=>e===p?p:d;function g(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[o,i]=(0,a.useState)((e=>r.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e))(e));(0,a.useEffect)((()=>{t&&u.del()}),[t]);const l=(0,a.useCallback)((function(t,a){void 0===a&&(a={});const{persist:r=!0}=a;t?(i(t),r&&(e=>{u.set(f(e))})(t)):(i(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p:d:e),u.del())}),[n,e]);(0,a.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,a.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&l(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,l]);const g=(0,a.useRef)(!1);return(0,a.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),a=()=>{window.matchMedia("print").matches||g.current?g.current=window.matchMedia("print").matches:l(null)};return e.addListener(a),()=>e.removeListener(a)}),[l,t,n]),(0,a.useMemo)((()=>({colorMode:o,setColorMode:l,get isDarkTheme(){return o===p},setLightTheme(){l(d)},setDarkTheme(){l(p)}})),[o,l])}function m(e){let{children:t}=e;const n=g();return a.createElement(l.Provider,{value:n},t)}function h(){const e=(0,a.useContext)(l);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},60373:(e,t,n)=>{"use strict";n.d(t,{J:()=>y,L5:()=>b,Oh:()=>w});var a=n(67294),r=n(80143),o=n(29935),i=n(86668),s=n(53438),l=n(902),c=n(50012);const u=e=>`docs-preferred-version-${e}`,d=(e,t,n)=>{(0,c.WA)(u(e),{persistence:t}).set(n)},p=(e,t)=>(0,c.WA)(u(e),{persistence:t}).get(),f=(e,t)=>{(0,c.WA)(u(e),{persistence:t}).del()};const g=a.createContext(null);function m(){const e=(0,r._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,a.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,a.useState)((()=>(e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}]))))(n)));(0,a.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:a}=e;function r(e){const t=p(e,n);return a[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(f(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,r(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,a.useMemo)((()=>({savePreferredVersion:function(e,n){d(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return a.createElement(g.Provider,{value:n},t)}function b(e){let{children:t}=e;return s.cE?a.createElement(h,null,t):a.createElement(a.Fragment,null,t)}function v(){const e=(0,a.useContext)(g);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function y(e){void 0===e&&(e=o.m);const t=(0,r.zh)(e),[n,i]=v(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,a.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function w(){const e=(0,r._r)(),[t]=v();function n(n){const a=e[n],{preferredVersionName:r}=t[n];return a.versions.find((e=>e.name===r))??null}const a=Object.keys(e);return Object.fromEntries(a.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,b:()=>s});var a=n(67294),r=n(902);const o=Symbol("EmptyContext"),i=a.createContext(o);function s(e){let{children:t,name:n,items:r}=e;const o=(0,a.useMemo)((()=>n&&r?{name:n,items:r}:null),[n,r]);return a.createElement(i.Provider,{value:o},t)}function l(){const e=(0,a.useContext)(i);if(e===o)throw new r.i6("DocsSidebarProvider");return e}},93163:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>p});var a=n(67294),r=n(13102),o=n(87524),i=n(91980),s=n(86668),l=n(902);const c=a.createContext(void 0);function u(){const e=function(){const e=(0,r.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[l,c]=(0,a.useState)(!1);(0,i.Rb)((()=>{if(l)return c(!1),!1}));const u=(0,a.useCallback)((()=>{c((e=>!e))}),[]);return(0,a.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,a.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:l})),[e,n,u,l])}function d(e){let{children:t}=e;const n=u();return a.createElement(c.Provider,{value:n},t)}function p(){const e=a.useContext(c);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},13102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>s,Zo:()=>l,n2:()=>i});var a=n(67294),r=n(902);const o=a.createContext(null);function i(e){let{children:t}=e;const n=(0,a.useState)({component:null,props:null});return a.createElement(o.Provider,{value:n},t)}function s(){const e=(0,a.useContext)(o);if(!e)throw new r.i6("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const i=(0,a.useContext)(o);if(!i)throw new r.i6("NavbarSecondaryMenuContentProvider");const[,s]=i,l=(0,r.Ql)(n);return(0,a.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,a.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},19727:(e,t,n)=>{"use strict";n.d(t,{h:()=>r,t:()=>o});var a=n(67294);const r="navigation-with-keyboard";function o(){(0,a.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(r),"mousedown"===e.type&&document.body.classList.remove(r)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(r),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},66177:(e,t,n)=>{"use strict";n.d(t,{K:()=>i,M:()=>s});var a=n(67294),r=n(52263),o=n(91980);function i(){return(0,o.Nc)("q")}function s(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,r.Z)(),{algolia:{searchPagePath:n}}=t;return(0,a.useCallback)((t=>`${e}${n}?q=${encodeURIComponent(t)}`),[e,n])}},87524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var a=n(67294),r=n(10412);const o="desktop",i="mobile",s="ssr";function l(){return r.Z.canUseDOM?window.innerWidth>996?o:i:s}function c(){const[e,t]=(0,a.useState)((()=>l()));return(0,a.useEffect)((()=>{function e(){t(l())}return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(undefined)}}),[]),e}},35281:(e,t,n)=>{"use strict";n.d(t,{k:()=>a});const a={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},91442:(e,t,n)=>{"use strict";function a(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>a})},53438:(e,t,n)=>{"use strict";n.d(t,{Wl:()=>p,_F:()=>g,cE:()=>d,hI:()=>w,lO:()=>b,oz:()=>v,s1:()=>h,vY:()=>y});var a=n(67294),r=n(16550),o=n(18790),i=n(80143),s=n(60373),l=n(1116),c=n(67392),u=n(48596);const d=!!i._r;function p(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=p(t);if(e)return e}}}const f=(e,t)=>void 0!==e&&(0,u.Mg)(e,t);function g(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||((e,t)=>e.some((e=>g(e,t))))(e.items,t))}function m(e){let{sidebarItems:t,pathname:n,onlyCategories:a=!1}=e;const r=[];return function e(t){for(const o of t)if("category"===o.type&&((0,u.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,u.Mg)(o.href,n)){return a&&"category"!==o.type||r.unshift(o),!0}return!1}(t),r}function h(){const e=(0,l.V)(),{pathname:t}=(0,r.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?m({sidebarItems:e.items,pathname:t}):null}function b(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),r=(0,i.yW)(e);return(0,a.useMemo)((()=>(0,c.j)([t,n,r].filter(Boolean))),[t,n,r])}function v(e,t){const n=b(t);return(0,a.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),a=t.find((t=>t[0]===e));if(!a)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return a[1]}),[e,n])}function y(e,t){const n=b(t);return(0,a.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),a=t.find((t=>t.id===e));if(!a){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.j)(t.map((e=>e.id))).join("\n- ")}`)}return a}),[e,n])}function w(e){let{route:t,versionMetadata:n}=e;const a=(0,r.TH)(),i=t.routes,s=i.find((e=>(0,r.LX)(a.pathname,e)));if(!s)return null;const l=s.sidebar,c=l?n.docsSidebars[l]:void 0;return{docElement:(0,o.H)(i),sidebarName:l,sidebarItems:c}}},82128:(e,t,n)=>{"use strict";n.d(t,{p:()=>r});var a=n(52263);function r(e){const{siteConfig:t}=(0,a.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}},91980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>c,Rb:()=>s,_X:()=>l});var a=n(67294),r=n(16550),o=n(61688),i=n(902);function s(e){!function(e){const t=(0,r.k6)(),n=(0,i.zX)(e);(0,a.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function l(e){return function(e){const t=(0,r.k6)();return(0,o.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function c(e){const t=l(e)??"",n=function(){const e=(0,r.k6)();return(0,a.useCallback)(((t,n,a)=>{const r=new URLSearchParams(e.location.search);n?r.set(t,n):r.delete(t),(a?.push?e.push:e.replace)({search:r.toString()})}),[e])}();return[t,(0,a.useCallback)(((t,a)=>{n(e,t,a)}),[n,e])]}},67392:(e,t,n)=>{"use strict";function a(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,a)=>e.findIndex((e=>t(e,n)))!==a))}function r(e){return Array.from(new Set(e))}n.d(t,{j:()=>r,l:()=>a})},10833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var a=n(67294),r=n(86010),o=n(35742),i=n(30226);function s(){const e=a.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(44996),c=n(82128);function u(e){let{title:t,description:n,keywords:r,image:i,children:s}=e;const u=(0,c.p)(t),{withBaseUrl:d}=(0,l.C)(),p=i?d(i,{absolute:!0}):void 0;return a.createElement(o.Z,null,t&&a.createElement("title",null,u),t&&a.createElement("meta",{property:"og:title",content:u}),n&&a.createElement("meta",{name:"description",content:n}),n&&a.createElement("meta",{property:"og:description",content:n}),r&&a.createElement("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&a.createElement("meta",{property:"og:image",content:p}),p&&a.createElement("meta",{name:"twitter:image",content:p}),s)}const d=a.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=a.useContext(d),s=(0,r.Z)(i,t);return a.createElement(d.Provider,{value:s},a.createElement(o.Z,null,a.createElement("html",{className:s})),n)}function f(e){let{children:t}=e;const n=s(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return a.createElement(p,{className:(0,r.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>l,i6:()=>s,zX:()=>o});var a=n(67294);const r=n(10412).Z.canUseDOM?a.useLayoutEffect:a.useEffect;function o(e){const t=(0,a.useRef)(e);return r((()=>{t.current=e}),[e]),(0,a.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,a.useRef)();return r((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,a.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return a.createElement(a.Fragment,null,e.reduceRight(((e,t)=>a.createElement(t,null,e)),n))}}},98022:(e,t,n)=>{"use strict";function a(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>a})},48596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var a=n(67294),r=n(723),o=n(52263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,a.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function a(e){return e.path===t&&!0===e.exact}function r(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(a)||e(t.filter(r).flatMap((e=>e.routes??[])))}(n)}({routes:r.Z,baseUrl:e})),[e])}},12466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>l,RF:()=>d,o5:()=>p});var a=n(67294),r=n(10412),o=n(72389),i=n(902);const s=a.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,a.useRef)(!0);return(0,a.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return a.createElement(s.Provider,{value:n},t)}function c(){const e=(0,a.useContext)(s);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>r.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),r=(0,a.useRef)(u()),o=(0,i.zX)(e);(0,a.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,r.current),r.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=c(),t=function(){const e=(0,a.useRef)({elem:null,top:0}),t=(0,a.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,a.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const a=t.getBoundingClientRect().top-n;return a&&window.scrollBy({left:0,top:a}),e.current={elem:null,top:0},{restored:0!==a}}),[]);return(0,a.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,a.useRef)(void 0),r=(0,a.useCallback)((a=>{t.save(a),e.disableScrollEvents(),n.current=()=>{const{restored:a}=t.restore();if(n.current=void 0,a){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,a.useLayoutEffect)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:r}}function f(){const e=(0,a.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function a(){const r=document.documentElement.scrollTop;(n&&r>e||!n&&r<e)&&(t=requestAnimationFrame(a),window.scrollTo(0,Math.floor(.85*(r-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},43320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>l,os:()=>s});var a=n(80143),r=n(52263),o=n(60373);const i="default";function s(e,t){return`docs-${e}-${t}`}function l(){const{i18n:e}=(0,r.Z)(),t=(0,a._r)(),n=(0,a.WS)(),l=(0,o.Oh)();const c=[i,...Object.keys(t).map((function(e){const a=n?.activePlugin.pluginId===e?n.activeVersion:void 0,r=l[e],o=t[e].versions.find((e=>e.isLast));return s(e,(a??r??o).name)}))];return{locale:e.currentLocale,tags:c}}},50012:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>d,WA:()=>u});var a=n(67294),r=n(61688);const o="localStorage";function i(e){let{key:t,oldValue:n,newValue:a,storage:r}=e;if(n===a)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,a,window.location.href,r),window.dispatchEvent(o)}function s(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,l||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),l=!0),null}var t}let l=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=s(t?.persistence);return null===n?c:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const a=n.getItem(e);n.setItem(e,t),i({key:e,oldValue:a,newValue:t,storage:n})}catch(a){console.error(`Docusaurus storage error, can't set ${e}=${t}`,a)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),i({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const a=a=>{a.storageArea===n&&a.key===e&&t(a)};return window.addEventListener("storage",a),()=>window.removeEventListener("storage",a)}catch(a){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,a),()=>{}}}}}function d(e,t){const n=(0,a.useRef)((()=>null===e?c:u(e,t))).current(),o=(0,a.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,r.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},94711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var a=n(52263),r=n(16550),o=n(18780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,a.Z)(),{pathname:l}=(0,r.TH)(),c=(0,o.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},85936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var a=n(67294),r=n(16550),o=n(902);function i(e){const t=(0,r.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,a.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},86668:(e,t,n)=>{"use strict";n.d(t,{L:()=>r});var a=n(52263);function r(){return(0,a.Z)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>r});var a=n(52263);function r(){const{siteConfig:{themeConfig:e}}=(0,a.Z)();return e}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var a=n(67294),r=n(98022),o=n(44996),i=n(6278);function s(){const{withBaseUrl:e}=(0,o.C)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,i.L)();return(0,a.useCallback)((a=>{const o=new URL(a);if((0,r.F)(t,o.href))return a;const i=`${o.pathname+o.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(i,n))}),[e,t,n])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:a}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[r]=e.split(/[#?]/),o="/"===r||r===a?r:(i=r,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(r,o)}},54143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},18780:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var r=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return a(r).default}});var o=n(54143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},86010:(e,t,n)=>{"use strict";function a(e){var t,n,r="";if("string"==typeof e||"number"==typeof e)r+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=a(e[t]))&&(r&&(r+=" "),r+=n);else for(t in e)e[t]&&(r&&(r+=" "),r+=t);return r}n.d(t,{Z:()=>r});const r=function(){for(var e,t,n=0,r="";n<arguments.length;)(e=arguments[n++])&&(t=a(e))&&(r&&(r+=" "),r+=t);return r}},42358:(e,t,n)=>{"use strict";n.d(t,{lX:()=>k,q_:()=>L,ob:()=>m,PP:()=>N,Ep:()=>g,Hp:()=>h});var a=n(87462);function r(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,a=n+1,r=e.length;a<r;n+=1,a+=1)e[n]=e[a];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,a=e&&e.split("/")||[],i=t&&t.split("/")||[],s=e&&r(e),l=t&&r(t),c=s||l;if(e&&r(e)?i=a:a.length&&(i.pop(),i=i.concat(a)),!i.length)return"/";if(i.length){var u=i[i.length-1];n="."===u||".."===u||""===u}else n=!1;for(var d=0,p=i.length;p>=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&r(i[0])||i.unshift("");var g=i.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};function s(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}const l=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,a){return e(t,n[a])}));if("object"==typeof t||"object"==typeof n){var a=s(t),r=s(n);return a!==t||r!==n?e(a,r):Object.keys(Object.assign({},t,n)).every((function(a){return e(t[a],n[a])}))}return!1};var c=n(38776);function u(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function p(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function f(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function g(e){var t=e.pathname,n=e.search,a=e.hash,r=t||"/";return n&&"?"!==n&&(r+="?"===n.charAt(0)?n:"?"+n),a&&"#"!==a&&(r+="#"===a.charAt(0)?a:"#"+a),r}function m(e,t,n,r){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",a="",r=t.indexOf("#");-1!==r&&(a=t.substr(r),t=t.substr(0,r));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===a?"":a}}(e),o.state=t):(void 0===(o=(0,a.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),r?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,r.pathname)):o.pathname=r.pathname:o.pathname||(o.pathname="/"),o}function h(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&l(e.state,t.state)}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,a,r){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof a?a(o,r):r(!0):r(!1!==o)}else r(!0)},appendListener:function(e){var n=!0;function a(){n&&e.apply(void 0,arguments)}return t.push(a),function(){n=!1,t=t.filter((function(e){return e!==a}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),a=0;a<e;a++)n[a]=arguments[a];t.forEach((function(e){return e.apply(void 0,n)}))}}}var v=!("undefined"==typeof window||!window.document||!window.document.createElement);function y(e,t){t(window.confirm(e))}var w="popstate",_="hashchange";function x(){try{return window.history.state||{}}catch(e){return{}}}function k(e){void 0===e&&(e={}),v||(0,c.Z)(!1);var t,n=window.history,r=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,o=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,s=i.forceRefresh,l=void 0!==s&&s,d=i.getUserConfirmation,h=void 0===d?y:d,k=i.keyLength,E=void 0===k?6:k,S=e.basename?f(u(e.basename)):"";function T(e){var t=e||{},n=t.key,a=t.state,r=window.location,o=r.pathname+r.search+r.hash;return S&&(o=p(o,S)),m(o,a,n)}function C(){return Math.random().toString(36).substr(2,E)}var A=b();function L(e){(0,a.Z)(U,e),U.length=n.length,A.notifyListeners(U.location,U.action)}function P(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||O(T(e.state))}function N(){O(T(x()))}var j=!1;function O(e){if(j)j=!1,L();else{A.confirmTransitionTo(e,"POP",h,(function(t){t?L({action:"POP",location:e}):function(e){var t=U.location,n=R.indexOf(t.key);-1===n&&(n=0);var a=R.indexOf(e.key);-1===a&&(a=0);var r=n-a;r&&(j=!0,D(r))}(e)}))}}var M=T(x()),R=[M.key];function I(e){return S+g(e)}function D(e){n.go(e)}var B=0;function F(e){1===(B+=e)&&1===e?(window.addEventListener(w,P),o&&window.addEventListener(_,N)):0===B&&(window.removeEventListener(w,P),o&&window.removeEventListener(_,N))}var $=!1;var U={length:n.length,action:"POP",location:M,createHref:I,push:function(e,t){var a="PUSH",o=m(e,t,C(),U.location);A.confirmTransitionTo(o,a,h,(function(e){if(e){var t=I(o),i=o.key,s=o.state;if(r)if(n.pushState({key:i,state:s},null,t),l)window.location.href=t;else{var c=R.indexOf(U.location.key),u=R.slice(0,c+1);u.push(o.key),R=u,L({action:a,location:o})}else window.location.href=t}}))},replace:function(e,t){var a="REPLACE",o=m(e,t,C(),U.location);A.confirmTransitionTo(o,a,h,(function(e){if(e){var t=I(o),i=o.key,s=o.state;if(r)if(n.replaceState({key:i,state:s},null,t),l)window.location.replace(t);else{var c=R.indexOf(U.location.key);-1!==c&&(R[c]=o.key),L({action:a,location:o})}else window.location.replace(t)}}))},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=A.setPrompt(e);return $||(F(1),$=!0),function(){return $&&($=!1,F(-1)),t()}},listen:function(e){var t=A.appendListener(e);return F(1),function(){F(-1),t()}}};return U}var E="hashchange",S={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+d(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:d,decodePath:u},slash:{encodePath:u,decodePath:u}};function T(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function C(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function A(e){window.location.replace(T(window.location.href)+"#"+e)}function L(e){void 0===e&&(e={}),v||(0,c.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),r=n.getUserConfirmation,o=void 0===r?y:r,i=n.hashType,s=void 0===i?"slash":i,l=e.basename?f(u(e.basename)):"",d=S[s],h=d.encodePath,w=d.decodePath;function _(){var e=w(C());return l&&(e=p(e,l)),m(e)}var x=b();function k(e){(0,a.Z)($,e),$.length=t.length,x.notifyListeners($.location,$.action)}var L=!1,P=null;function N(){var e,t,n=C(),a=h(n);if(n!==a)A(a);else{var r=_(),i=$.location;if(!L&&(t=r,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(P===g(r))return;P=null,function(e){if(L)L=!1,k();else{var t="POP";x.confirmTransitionTo(e,t,o,(function(n){n?k({action:t,location:e}):function(e){var t=$.location,n=R.lastIndexOf(g(t));-1===n&&(n=0);var a=R.lastIndexOf(g(e));-1===a&&(a=0);var r=n-a;r&&(L=!0,I(r))}(e)}))}}(r)}}var j=C(),O=h(j);j!==O&&A(O);var M=_(),R=[g(M)];function I(e){t.go(e)}var D=0;function B(e){1===(D+=e)&&1===e?window.addEventListener(E,N):0===D&&window.removeEventListener(E,N)}var F=!1;var $={length:t.length,action:"POP",location:M,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=T(window.location.href)),n+"#"+h(l+g(e))},push:function(e,t){var n="PUSH",a=m(e,void 0,void 0,$.location);x.confirmTransitionTo(a,n,o,(function(e){if(e){var t=g(a),r=h(l+t);if(C()!==r){P=t,function(e){window.location.hash=e}(r);var o=R.lastIndexOf(g($.location)),i=R.slice(0,o+1);i.push(t),R=i,k({action:n,location:a})}else k()}}))},replace:function(e,t){var n="REPLACE",a=m(e,void 0,void 0,$.location);x.confirmTransitionTo(a,n,o,(function(e){if(e){var t=g(a),r=h(l+t);C()!==r&&(P=t,A(r));var o=R.indexOf(g($.location));-1!==o&&(R[o]=t),k({action:n,location:a})}}))},go:I,goBack:function(){I(-1)},goForward:function(){I(1)},block:function(e){void 0===e&&(e=!1);var t=x.setPrompt(e);return F||(B(1),F=!0),function(){return F&&(F=!1,B(-1)),t()}},listen:function(e){var t=x.appendListener(e);return B(1),function(){B(-1),t()}}};return $}function P(e,t,n){return Math.min(Math.max(e,t),n)}function N(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,r=t.initialEntries,o=void 0===r?["/"]:r,i=t.initialIndex,s=void 0===i?0:i,l=t.keyLength,c=void 0===l?6:l,u=b();function d(e){(0,a.Z)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function p(){return Math.random().toString(36).substr(2,c)}var f=P(s,0,o.length-1),h=o.map((function(e){return m(e,void 0,"string"==typeof e?p():e.key||p())})),v=g;function y(e){var t=P(w.index+e,0,w.entries.length-1),a=w.entries[t];u.confirmTransitionTo(a,"POP",n,(function(e){e?d({action:"POP",location:a,index:t}):d()}))}var w={length:h.length,action:"POP",location:h[f],index:f,entries:h,createHref:v,push:function(e,t){var a="PUSH",r=m(e,t,p(),w.location);u.confirmTransitionTo(r,a,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,r):n.push(r),d({action:a,location:r,index:t,entries:n})}}))},replace:function(e,t){var a="REPLACE",r=m(e,t,p(),w.location);u.confirmTransitionTo(r,a,n,(function(e){e&&(w.entries[w.index]=r,d({action:a,location:r}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},8679:(e,t,n)=>{"use strict";var a=n(59864),r={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return a.isMemo(e)?i:s[e.$$typeof]||r}s[a.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[a.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,a){if("string"!=typeof n){if(g){var r=f(n);r&&r!==g&&e(t,r,a)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),m=l(n),h=0;h<i.length;++h){var b=i[h];if(!(o[b]||a&&a[b]||m&&m[b]||s&&s[b])){var v=p(n,b);try{c(t,b,v)}catch(y){}}}}return t}},41143:e=>{"use strict";e.exports=function(e,t,n,a,r,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,a,r,o,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},32497:(e,t,n)=>{"use strict";n.r(t)},52295:(e,t,n)=>{"use strict";n.r(t)},74865:function(e,t,n){var a,r;a=function(){var e,t,n={version:"0.2.0"},a=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function r(e,t,n){return e<t?t:e>n?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var r;return(r="translate3d"===a.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===a.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,r}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(a[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=r(e,a.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(a.barSelector),u=a.speed,d=a.easing;return o.offsetWidth,s((function(t){""===a.positionUsing&&(a.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),a.trickleSpeed)};return a.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*r(Math.random()*t,.1,.95)),t=r(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*a.trickleRate)},e=0,t=0,n.promise=function(a){return a&&"resolved"!==a.state()?(0===t&&n.start(),e++,t++,a.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=a.template;var r,i=t.querySelector(a.barSelector),s=e?"-100":o(n.status||0),c=document.querySelector(a.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),a.showSpinner||(r=t.querySelector(a.spinnerSelector))&&f(r),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(a.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function a(t){var n=document.body.style;if(t in n)return t;for(var a,r=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);r--;)if((a=e[r]+o)in n)return a;return t}function r(e){return e=n(e),t[e]||(t[e]=a(e))}function o(e,t,n){t=r(t),e.style[t]=n}return function(e,t){var n,a,r=arguments;if(2==r.length)for(n in t)void 0!==(a=t[n])&&t.hasOwnProperty(n)&&o(e,n,a);else o(e,r[1],r[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),a=n+t;c(n,t)||(e.className=a.substring(1))}function d(e,t){var n,a=p(e);c(e,t)&&(n=a.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(r="function"==typeof a?a.call(t,n,t,e):a)||(e.exports=r)},27418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable;function r(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var a={};return"abcdefghijklmnopqrst".split("").forEach((function(e){a[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},a)).join("")}catch(r){return!1}}()?Object.assign:function(e,o){for(var i,s,l=r(e),c=1;c<arguments.length;c++){for(var u in i=Object(arguments[c]))n.call(i,u)&&(l[u]=i[u]);if(t){s=t(i);for(var d=0;d<s.length;d++)a.call(i,s[d])&&(l[s[d]]=i[s[d]])}}return l}},87410:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},a={util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var r,o;switch(n=n||{},a.util.type(t)){case"Object":if(o=a.util.objId(t),n[o])return n[o];for(var i in r={},n[o]=r,t)t.hasOwnProperty(i)&&(r[i]=e(t[i],n));return r;case"Array":return o=a.util.objId(t),n[o]?n[o]:(r=[],n[o]=r,t.forEach((function(t,a){r[a]=e(t,n)})),r);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var a="no-"+t;e;){var r=e.classList;if(r.contains(t))return!0;if(r.contains(a))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=a.util.clone(a.languages[e]);for(var r in t)n[r]=t[r];return n},insertBefore:function(e,t,n,r){var o=(r=r||a.languages)[e],i={};for(var s in o)if(o.hasOwnProperty(s)){if(s==t)for(var l in n)n.hasOwnProperty(l)&&(i[l]=n[l]);n.hasOwnProperty(s)||(i[s]=o[s])}var c=r[e];return r[e]=i,a.languages.DFS(a.languages,(function(t,n){n===c&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,r,o){o=o||{};var i=a.util.objId;for(var s in t)if(t.hasOwnProperty(s)){n.call(t,s,t[s],r||s);var l=t[s],c=a.util.type(l);"Object"!==c||o[i(l)]?"Array"!==c||o[i(l)]||(o[i(l)]=!0,e(l,n,s,o)):(o[i(l)]=!0,e(l,n,null,o))}}},plugins:{},highlight:function(e,t,n){var o={code:e,grammar:t,language:n};return a.hooks.run("before-tokenize",o),o.tokens=a.tokenize(o.code,o.grammar),a.hooks.run("after-tokenize",o),r.stringify(a.util.encode(o.tokens),o.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var a in n)t[a]=n[a];delete t.rest}var r=new s;return l(r,r.head,e),i(e,r,t,r.head,0),function(e){var t=[],n=e.head.next;for(;n!==e.tail;)t.push(n.value),n=n.next;return t}(r)},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var r,o=0;r=n[o++];)r(t)}},Token:r};function r(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length}function o(e,t,n,a){e.lastIndex=t;var r=e.exec(n);if(r&&a&&r[1]){var o=r[1].length;r.index+=o,r[0]=r[0].slice(o)}return r}function i(e,t,n,s,u,d){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var f=n[p];f=Array.isArray(f)?f:[f];for(var g=0;g<f.length;++g){if(d&&d.cause==p+","+g)return;var m=f[g],h=m.inside,b=!!m.lookbehind,v=!!m.greedy,y=m.alias;if(v&&!m.pattern.global){var w=m.pattern.toString().match(/[imsuy]*$/)[0];m.pattern=RegExp(m.pattern.source,w+"g")}for(var _=m.pattern||m,x=s.next,k=u;x!==t.tail&&!(d&&k>=d.reach);k+=x.value.length,x=x.next){var E=x.value;if(t.length>e.length)return;if(!(E instanceof r)){var S,T=1;if(v){if(!(S=o(_,k,e,b))||S.index>=e.length)break;var C=S.index,A=S.index+S[0].length,L=k;for(L+=x.value.length;C>=L;)L+=(x=x.next).value.length;if(k=L-=x.value.length,x.value instanceof r)continue;for(var P=x;P!==t.tail&&(L<A||"string"==typeof P.value);P=P.next)T++,L+=P.value.length;T--,E=e.slice(k,L),S.index-=k}else if(!(S=o(_,0,E,b)))continue;C=S.index;var N=S[0],j=E.slice(0,C),O=E.slice(C+N.length),M=k+E.length;d&&M>d.reach&&(d.reach=M);var R=x.prev;if(j&&(R=l(t,R,j),k+=j.length),c(t,R,T),x=l(t,R,new r(p,h?a.tokenize(N,h):N,y,N)),O&&l(t,x,O),T>1){var I={cause:p+","+g,reach:M};i(e,t,n,x.prev,k,I),d&&I.reach>d.reach&&(d.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var a=t.next,r={value:n,prev:t,next:a};return t.next=r,a.prev=r,e.length++,r}function c(e,t,n){for(var a=t.next,r=0;r<n&&a!==e.tail;r++)a=a.next;t.next=a,a.prev=t,e.length-=r}return r.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var r="";return t.forEach((function(t){r+=e(t,n)})),r}var o={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(o.classes,i):o.classes.push(i)),a.hooks.run("wrap",o);var s="";for(var l in o.attributes)s+=" "+l+'="'+(o.attributes[l]||"").replace(/"/g,""")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+s+">"+o.content+"</"+o.tag+">"},a}(),r=a;a.default=a,r.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},r.languages.markup.tag.inside["attr-value"].inside.entity=r.languages.markup.entity,r.languages.markup.doctype.inside["internal-subset"].inside=r.languages.markup,r.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(r.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:r.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i;var a={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}};a["language-"+t]={pattern:/[\s\S]+/,inside:r.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:a},r.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(r.languages.markup.tag,"addAttribute",{value:function(e,t){r.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:r.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),r.languages.html=r.languages.markup,r.languages.mathml=r.languages.markup,r.languages.svg=r.languages.markup,r.languages.xml=r.languages.extend("markup",{}),r.languages.ssml=r.languages.xml,r.languages.atom=r.languages.xml,r.languages.rss=r.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},a={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:a},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:a},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:a.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:a.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var r=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=a.variable[1].inside,i=0;i<r.length;i++)o[r[i]]=e.languages.bash[r[i]];e.languages.shell=e.languages.bash}(r),r.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},r.languages.c=r.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),r.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),r.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},r.languages.c.string],char:r.languages.c.char,comment:r.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:r.languages.c}}}}),r.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete r.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(r),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(r),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var a={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},r={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:a,number:r,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:a,number:r})}(r),r.languages.javascript=r.languages.extend("clike",{"class-name":[r.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),r.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,r.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:r.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:r.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:r.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:r.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:r.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),r.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:r.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),r.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),r.languages.markup&&(r.languages.markup.tag.addInlined("script","javascript"),r.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),r.languages.js=r.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(r),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,a="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",r=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return a})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return a}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return a})).replace(/<<key>>/g,(function(){return"(?:"+r+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(r),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var a=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,r=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return a})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+r+o+"(?:"+r+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+r+o+")(?:"+r+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(a),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+r+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+r+"$"),inside:{"table-header":{pattern:RegExp(a),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,a=t.length;n<a;n++){var r=t[n];if("code"===r.type){var o=r.content[1],i=r.content[3];if(o&&i&&"code-language"===o.type&&"code-block"===i.type&&"string"==typeof o.content){var s=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),l="language-"+(s=(/[a-z][\w-]*/i.exec(s)||[""])[0].toLowerCase());i.alias?"string"==typeof i.alias?i.alias=[i.alias,l]:i.alias.push(l):i.alias=[l]}}else e(r.content)}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",a=0,r=t.classes.length;a<r;a++){var o=t.classes[a],c=/language-(.+)/.exec(o);if(c){n=c[1];break}}var u,d=e.languages[n];if(d)t.content=e.highlight((u=t.content,u.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;if("#"===(t=t.toLowerCase())[0])return n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),l(n);var a=s[t];return a||e}))),d,n);else if(n&&"none"!==n&&e.plugins.autoloader){var p="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random());t.attributes.id=p,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(p);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))}))}}}));var i=RegExp(e.languages.markup.tag.pattern.source,"gi"),s={amp:"&",lt:"<",gt:">",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(r),r.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:r.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},r.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var a=t[n++];if("keyword"===a.type&&"mutation"===a.content){var r=[];if(d(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var o=p(/^\($/,/^\)$/);if(-1===o)continue;for(;n<o;n++){var i=u(0);"variable"===i.type&&(f(i,"variable-input"),r.push(i.content))}n=o+1}if(d(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),r.length>0)){var s=p(/^\{$/,/^\}$/);if(-1===s)continue;for(var l=n;l<s;l++){var c=t[l];"variable"===c.type&&r.indexOf(c.content)>=0&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var a=u(n+t);if(!a||a.type!==e[n])return!1}return!0}function p(e,a){for(var r=1,o=n;o<t.length;o++){var i=t[o],s=i.content;if("punctuation"===i.type&&"string"==typeof s)if(e.test(s))r++;else if(a.test(s)&&0===--r)return o}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),r.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,a=t.inside.interpolation,r=a.inside["interpolation-punctuation"],o=a.pattern.source;function i(t,a){if(e.languages[t])return{pattern:RegExp("((?:"+a+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function l(t,n,a){var r={code:t,grammar:n,language:a};return e.hooks.run("before-tokenize",r),r.tokens=e.tokenize(r.code,r.grammar),e.hooks.run("after-tokenize",r),r.tokens}function c(t){var n={};n["interpolation-punctuation"]=r;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,l(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,a.alias,t)}function u(t,n,a){var r=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=l(r.map((function(e){if("string"==typeof e)return e;for(var n,r=e.content;-1!==t.indexOf(n=s(i++,a)););return u[n]=r,n})).join(""),n,a),p=Object.keys(u);return i=0,function e(t){for(var n=0;n<t.length;n++){if(i>=p.length)return;var a=t[n];if("string"==typeof a||"string"==typeof a.content){var r=p[i],o="string"==typeof a?a:a.content,s=o.indexOf(r);if(-1!==s){++i;var l=o.substring(0,s),d=c(u[r]),f=o.substring(s+r.length),g=[];if(l&&g.push(l),g.push(d),f){var m=[f];e(m),g.push.apply(g,m)}"string"==typeof a?(t.splice.apply(t,[n,1].concat(g)),n+=g.length-1):a.content=g}}else{var h=a.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(a,d,"language-"+a,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function p(e){return"string"==typeof e?e:Array.isArray(e)?e.map(p).join(""):p(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var a=0,r=n.length;a<r;a++){var o=n[a];if("string"!=typeof o){var i=o.content;if(Array.isArray(i))if("template-string"===o.type){var s=i[1];if(3===i.length&&"string"!=typeof s&&"embedded-code"===s.type){var l=p(s),c=s.alias,d=Array.isArray(c)?c[0]:c,f=e.languages[d];if(!f)continue;i[1]=u(l,f,d)}}else t(i);else"string"!=typeof i&&t([i])}}}(t.tokens)}))}(r),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(r),function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],a=0;a<n.length;a++){var r=n[a],o=e.languages.javascript[r];"RegExp"===e.util.type(o)&&(o=e.languages.javascript[r]={pattern:o});var i=o.inside||{};o.inside=i,i["maybe-class-name"]=/^[A-Z][\s\S]*/}}(r),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,a=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,r=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function o(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return a})).replace(/<SPREAD>/g,(function(){return r})),RegExp(e,t)}r=o(r).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},s=function(t){for(var n=[],a=0;a<t.length;a++){var r=t[a],o=!1;if("string"!=typeof r&&("tag"===r.type&&r.content[0]&&"tag"===r.content[0].type?"</"===r.content[0].content[0].content?n.length>0&&n[n.length-1].tagName===i(r.content[0].content[1])&&n.pop():"/>"===r.content[r.content.length-1].content||n.push({tagName:i(r.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===r.type&&"{"===r.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===r.type&&"}"===r.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof r)&&n.length>0&&0===n[n.length-1].openedBraces){var l=i(r);a<t.length-1&&("string"==typeof t[a+1]||"plain-text"===t[a+1].type)&&(l+=i(t[a+1]),t.splice(a+1,1)),a>0&&("string"==typeof t[a-1]||"plain-text"===t[a-1].type)&&(l=i(t[a-1])+l,t.splice(a-1,1),a--),t[a]=new e.Token("plain-text",l,null,l)}r.content&&"string"!=typeof r.content&&s(r.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(r),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var a=t[n],r=[];/^\w+$/.test(n)||r.push(/\w+/.exec(n)[0]),"diff"===n&&r.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+a+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:r,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(r),r.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},r.languages.go=r.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),r.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete r.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,a,r,o){if(n.language===a){var i=n.tokenStack=[];n.code=n.code.replace(r,(function(e){if("function"==typeof o&&!o(e))return e;for(var r,s=i.length;-1!==n.code.indexOf(r=t(a,s));)++s;return i[s]=e,r})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,a){if(n.language===a&&n.tokenStack){n.grammar=e.languages[a];var r=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l<s.length&&!(r>=o.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[r],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(a,u),g=p.indexOf(f);if(g>-1){++r;var m=p.substring(0,g),h=new e.Token(a,e.tokenize(d,n.grammar),"language-"+a,d),b=p.substring(g+f.length),v=[];m&&v.push.apply(v,i([m])),v.push(h),b&&v.push.apply(v,i([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(r),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(r),r.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},r.languages.webmanifest=r.languages.json,r.languages.less=r.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),r.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),r.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},r.languages.objectivec=r.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete r.languages.objectivec["class-name"],r.languages.objc=r.languages.objectivec,r.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},r.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},r.languages.python["string-interpolation"].inside.interpolation.inside.rest=r.languages.python,r.languages.py=r.languages.python,r.languages.reason=r.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),r.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete r.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(r),r.languages.scss=r.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),r.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),r.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),r.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),r.languages.scss.atrule.inside.rest=r.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},a={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};a.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:a}},a.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:a}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:a}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:a}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:a}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:a.interpolation}},rest:a}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:a.interpolation,comment:a.comment,punctuation:/[{},]/}},func:a.func,string:a.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:a.interpolation,punctuation:/[{}()\[\];:.]/}}(r),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(r),r.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=r},40485:()=>{!function(e){var t={pattern:/((?:^|[^\\$])(?:\\{2})*)\$(?:\w+|\{[^{}]*\})/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:null}}};e.languages.groovy=e.languages.extend("clike",{string:{pattern:/'''(?:[^\\]|\\[\s\S])*?'''|'(?:\\.|[^\\'\r\n])*'/,greedy:!0},keyword:/\b(?:abstract|as|assert|boolean|break|byte|case|catch|char|class|const|continue|def|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|in|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,number:/\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?\d+)?)[glidf]?\b/i,operator:{pattern:/(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,lookbehind:!0},punctuation:/\.+|[{}[\];(),:$]/}),e.languages.insertBefore("groovy","string",{shebang:{pattern:/#!.+/,alias:"comment",greedy:!0},"interpolation-string":{pattern:/"""(?:[^\\]|\\[\s\S])*?"""|(["/])(?:\\.|(?!\1)[^\\\r\n])*\1|\$\/(?:[^/$]|\$(?:[/$]|(?![/$]))|\/(?!\$))*\/\$/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}}}),e.languages.insertBefore("groovy","punctuation",{"spock-block":/\b(?:and|cleanup|expect|given|setup|then|when|where):/}),e.languages.insertBefore("groovy","function",{annotation:{pattern:/(^|[^.])@\w+/,lookbehind:!0,alias:"punctuation"}}),t.inside.expression.inside=e.languages.groovy}(Prism)},52503:()=>{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,a={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[a,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:a.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:a.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:a.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},32334:()=>{!function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(Prism)},52811:(e,t,n)=>{var a={"./prism-groovy":40485,"./prism-java":52503,"./prism-kotlin":32334};function r(e){var t=o(e);return n(t)}function o(e){if(!n.o(a,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return a[e]}r.keys=function(){return Object.keys(a)},r.resolve=o,e.exports=r,r.id=52811},92703:(e,t,n)=>{"use strict";var a=n(50414);function r(){}function o(){}o.resetWarningCache=r,e.exports=function(){function e(e,t,n,r,o,i){if(i!==a){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:r};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var a=n(67294),r=n(27418),o=n(63840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}if(!a)throw Error(i(227));var s=new Set,l={};function c(e,t){u(e,t),u(e+"Capture",t)}function u(e,t){for(l[e]=t,e=0;e<t.length;e++)s.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f=Object.prototype.hasOwnProperty,g={},m={};function h(e,t,n,a,r,o,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=a,this.attributeNamespace=r,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=i}var b={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){b[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];b[t]=new h(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){b[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){b[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){b[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){b[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){b[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){b[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){b[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var v=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function w(e,t,n,a){var r=b.hasOwnProperty(t)?b[t]:null;(null!==r?0===r.type:!a&&(2<t.length&&("o"===t[0]||"O"===t[0])&&("n"===t[1]||"N"===t[1])))||(function(e,t,n,a){if(null==t||function(e,t,n,a){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!a&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,a))return!0;if(a)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,r,a)&&(n=null),a||null===r?function(e){return!!f.call(m,e)||!f.call(g,e)&&(p.test(e)?m[e]=!0:(g[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):r.mustUseProperty?e[r.propertyName]=null===n?3!==r.type&&"":n:(t=r.attributeName,a=r.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(r=r.type)||4===r&&!0===n?"":""+n,a?e.setAttributeNS(a,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(v,y);b[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),b.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){b[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var _=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,x=60103,k=60106,E=60107,S=60108,T=60114,C=60109,A=60110,L=60112,P=60113,N=60120,j=60115,O=60116,M=60121,R=60128,I=60129,D=60130,B=60131;if("function"==typeof Symbol&&Symbol.for){var F=Symbol.for;x=F("react.element"),k=F("react.portal"),E=F("react.fragment"),S=F("react.strict_mode"),T=F("react.profiler"),C=F("react.provider"),A=F("react.context"),L=F("react.forward_ref"),P=F("react.suspense"),N=F("react.suspense_list"),j=F("react.memo"),O=F("react.lazy"),M=F("react.block"),F("react.scope"),R=F("react.opaque.id"),I=F("react.debug_trace_mode"),D=F("react.offscreen"),B=F("react.legacy_hidden")}var $,U="function"==typeof Symbol&&Symbol.iterator;function z(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=U&&e[U]||e["@@iterator"])?e:null}function Z(e){if(void 0===$)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);$=t&&t[1]||""}return"\n"+$+e}var H=!1;function V(e,t){if(!e||H)return"";H=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(l){var a=l}Reflect.construct(e,[],t)}else{try{t.call()}catch(l){a=l}e.call(t.prototype)}else{try{throw Error()}catch(l){a=l}e()}}catch(l){if(l&&a&&"string"==typeof l.stack){for(var r=l.stack.split("\n"),o=a.stack.split("\n"),i=r.length-1,s=o.length-1;1<=i&&0<=s&&r[i]!==o[s];)s--;for(;1<=i&&0<=s;i--,s--)if(r[i]!==o[s]){if(1!==i||1!==s)do{if(i--,0>--s||r[i]!==o[s])return"\n"+r[i].replace(" at new "," at ")}while(1<=i&&0<=s);break}}}finally{H=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?Z(e):""}function q(e){switch(e.tag){case 5:return Z(e.type);case 16:return Z("Lazy");case 13:return Z("Suspense");case 19:return Z("SuspenseList");case 0:case 2:case 15:return e=V(e.type,!1);case 11:return e=V(e.type.render,!1);case 22:return e=V(e.type._render,!1);case 1:return e=V(e.type,!0);default:return""}}function W(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case E:return"Fragment";case k:return"Portal";case T:return"Profiler";case S:return"StrictMode";case P:return"Suspense";case N:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case A:return(e.displayName||"Context")+".Consumer";case C:return(e._context.displayName||"Context")+".Provider";case L:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case j:return W(e.type);case M:return W(e._render);case O:t=e._payload,e=e._init;try{return W(e(t))}catch(n){}}return null}function G(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function K(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function Y(e){e._valueTracker||(e._valueTracker=function(e){var t=K(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),a=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var r=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return r.call(this)},set:function(e){a=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return a},setValue:function(e){a=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function Q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),a="";return e&&(a=K(e)?e.checked?"true":"false":e.value),(e=a)!==n&&(t.setValue(e),!0)}function X(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function J(e,t){var n=t.checked;return r({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function ee(e,t){var n=null==t.defaultValue?"":t.defaultValue,a=null!=t.checked?t.checked:t.defaultChecked;n=G(null!=t.value?t.value:n),e._wrapperState={initialChecked:a,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function te(e,t){null!=(t=t.checked)&&w(e,"checked",t,!1)}function ne(e,t){te(e,t);var n=G(t.value),a=t.type;if(null!=n)"number"===a?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===a||"reset"===a)return void e.removeAttribute("value");t.hasOwnProperty("value")?re(e,t.type,n):t.hasOwnProperty("defaultValue")&&re(e,t.type,G(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function ae(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var a=t.type;if(!("submit"!==a&&"reset"!==a||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function re(e,t,n){"number"===t&&X(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function oe(e,t){return e=r({children:void 0},t),(t=function(e){var t="";return a.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function ie(e,t,n,a){if(e=e.options,t){t={};for(var r=0;r<n.length;r++)t["$"+n[r]]=!0;for(n=0;n<e.length;n++)r=t.hasOwnProperty("$"+e[n].value),e[n].selected!==r&&(e[n].selected=r),r&&a&&(e[n].defaultSelected=!0)}else{for(n=""+G(n),t=null,r=0;r<e.length;r++){if(e[r].value===n)return e[r].selected=!0,void(a&&(e[r].defaultSelected=!0));null!==t||e[r].disabled||(t=e[r])}null!==t&&(t.selected=!0)}}function se(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(i(91));return r({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function le(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(i(92));if(Array.isArray(n)){if(!(1>=n.length))throw Error(i(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:G(n)}}function ce(e,t){var n=G(t.value),a=G(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=a&&(e.defaultValue=""+a)}function ue(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var de="http://www.w3.org/1999/xhtml",pe="http://www.w3.org/2000/svg";function fe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function ge(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?fe(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var me,he,be=(he=function(e,t){if(e.namespaceURI!==pe||"innerHTML"in e)e.innerHTML=t;else{for((me=me||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=me.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,a){MSApp.execUnsafeLocalFunction((function(){return he(e,t)}))}:he);function ve(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var ye={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},we=["Webkit","ms","Moz","O"];function _e(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||ye.hasOwnProperty(e)&&ye[e]?(""+t).trim():t+"px"}function xe(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var a=0===n.indexOf("--"),r=_e(n,t[n],a);"float"===n&&(n="cssFloat"),a?e.setProperty(n,r):e[n]=r}}Object.keys(ye).forEach((function(e){we.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),ye[t]=ye[e]}))}));var ke=r({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Ee(e,t){if(t){if(ke[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(i(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(i(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(i(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(i(62))}}function Se(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}function Te(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var Ce=null,Ae=null,Le=null;function Pe(e){if(e=ar(e)){if("function"!=typeof Ce)throw Error(i(280));var t=e.stateNode;t&&(t=or(t),Ce(e.stateNode,e.type,t))}}function Ne(e){Ae?Le?Le.push(e):Le=[e]:Ae=e}function je(){if(Ae){var e=Ae,t=Le;if(Le=Ae=null,Pe(e),t)for(e=0;e<t.length;e++)Pe(t[e])}}function Oe(e,t){return e(t)}function Me(e,t,n,a,r){return e(t,n,a,r)}function Re(){}var Ie=Oe,De=!1,Be=!1;function Fe(){null===Ae&&null===Le||(Re(),je())}function $e(e,t){var n=e.stateNode;if(null===n)return null;var a=or(n);if(null===a)return null;n=a[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(a=!a.disabled)||(a=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!a;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(i(231,t,typeof n));return n}var Ue=!1;if(d)try{var ze={};Object.defineProperty(ze,"passive",{get:function(){Ue=!0}}),window.addEventListener("test",ze,ze),window.removeEventListener("test",ze,ze)}catch(he){Ue=!1}function Ze(e,t,n,a,r,o,i,s,l){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(u){this.onError(u)}}var He=!1,Ve=null,qe=!1,We=null,Ge={onError:function(e){He=!0,Ve=e}};function Ke(e,t,n,a,r,o,i,s,l){He=!1,Ve=null,Ze.apply(Ge,arguments)}function Ye(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Qe(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Xe(e){if(Ye(e)!==e)throw Error(i(188))}function Je(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ye(e)))throw Error(i(188));return t!==e?null:e}for(var n=e,a=t;;){var r=n.return;if(null===r)break;var o=r.alternate;if(null===o){if(null!==(a=r.return)){n=a;continue}break}if(r.child===o.child){for(o=r.child;o;){if(o===n)return Xe(r),e;if(o===a)return Xe(r),t;o=o.sibling}throw Error(i(188))}if(n.return!==a.return)n=r,a=o;else{for(var s=!1,l=r.child;l;){if(l===n){s=!0,n=r,a=o;break}if(l===a){s=!0,a=r,n=o;break}l=l.sibling}if(!s){for(l=o.child;l;){if(l===n){s=!0,n=o,a=r;break}if(l===a){s=!0,a=o,n=r;break}l=l.sibling}if(!s)throw Error(i(189))}}if(n.alternate!==a)throw Error(i(190))}if(3!==n.tag)throw Error(i(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function et(e,t){for(var n=e.alternate;null!==t;){if(t===e||t===n)return!0;t=t.return}return!1}var tt,nt,at,rt,ot=!1,it=[],st=null,lt=null,ct=null,ut=new Map,dt=new Map,pt=[],ft="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function gt(e,t,n,a,r){return{blockedOn:e,domEventName:t,eventSystemFlags:16|n,nativeEvent:r,targetContainers:[a]}}function mt(e,t){switch(e){case"focusin":case"focusout":st=null;break;case"dragenter":case"dragleave":lt=null;break;case"mouseover":case"mouseout":ct=null;break;case"pointerover":case"pointerout":ut.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":dt.delete(t.pointerId)}}function ht(e,t,n,a,r,o){return null===e||e.nativeEvent!==o?(e=gt(t,n,a,r,o),null!==t&&(null!==(t=ar(t))&&nt(t)),e):(e.eventSystemFlags|=a,t=e.targetContainers,null!==r&&-1===t.indexOf(r)&&t.push(r),e)}function bt(e){var t=nr(e.target);if(null!==t){var n=Ye(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Qe(n)))return e.blockedOn=t,void rt(e.lanePriority,(function(){o.unstable_runWithPriority(e.priority,(function(){at(n)}))}))}else if(3===t&&n.stateNode.hydrate)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function vt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Jt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=ar(n))&&nt(t),e.blockedOn=n,!1;t.shift()}return!0}function yt(e,t,n){vt(e)&&n.delete(t)}function wt(){for(ot=!1;0<it.length;){var e=it[0];if(null!==e.blockedOn){null!==(e=ar(e.blockedOn))&&tt(e);break}for(var t=e.targetContainers;0<t.length;){var n=Jt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n){e.blockedOn=n;break}t.shift()}null===e.blockedOn&&it.shift()}null!==st&&vt(st)&&(st=null),null!==lt&&vt(lt)&&(lt=null),null!==ct&&vt(ct)&&(ct=null),ut.forEach(yt),dt.forEach(yt)}function _t(e,t){e.blockedOn===t&&(e.blockedOn=null,ot||(ot=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,wt)))}function xt(e){function t(t){return _t(t,e)}if(0<it.length){_t(it[0],e);for(var n=1;n<it.length;n++){var a=it[n];a.blockedOn===e&&(a.blockedOn=null)}}for(null!==st&&_t(st,e),null!==lt&&_t(lt,e),null!==ct&&_t(ct,e),ut.forEach(t),dt.forEach(t),n=0;n<pt.length;n++)(a=pt[n]).blockedOn===e&&(a.blockedOn=null);for(;0<pt.length&&null===(n=pt[0]).blockedOn;)bt(n),null===n.blockedOn&&pt.shift()}function kt(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var Et={animationend:kt("Animation","AnimationEnd"),animationiteration:kt("Animation","AnimationIteration"),animationstart:kt("Animation","AnimationStart"),transitionend:kt("Transition","TransitionEnd")},St={},Tt={};function Ct(e){if(St[e])return St[e];if(!Et[e])return e;var t,n=Et[e];for(t in n)if(n.hasOwnProperty(t)&&t in Tt)return St[e]=n[t];return e}d&&(Tt=document.createElement("div").style,"AnimationEvent"in window||(delete Et.animationend.animation,delete Et.animationiteration.animation,delete Et.animationstart.animation),"TransitionEvent"in window||delete Et.transitionend.transition);var At=Ct("animationend"),Lt=Ct("animationiteration"),Pt=Ct("animationstart"),Nt=Ct("transitionend"),jt=new Map,Ot=new Map,Mt=["abort","abort",At,"animationEnd",Lt,"animationIteration",Pt,"animationStart","canplay","canPlay","canplaythrough","canPlayThrough","durationchange","durationChange","emptied","emptied","encrypted","encrypted","ended","ended","error","error","gotpointercapture","gotPointerCapture","load","load","loadeddata","loadedData","loadedmetadata","loadedMetadata","loadstart","loadStart","lostpointercapture","lostPointerCapture","playing","playing","progress","progress","seeking","seeking","stalled","stalled","suspend","suspend","timeupdate","timeUpdate",Nt,"transitionEnd","waiting","waiting"];function Rt(e,t){for(var n=0;n<e.length;n+=2){var a=e[n],r=e[n+1];r="on"+(r[0].toUpperCase()+r.slice(1)),Ot.set(a,t),jt.set(a,r),c(r,[a])}}(0,o.unstable_now)();var It=8;function Dt(e){if(0!=(1&e))return It=15,1;if(0!=(2&e))return It=14,2;if(0!=(4&e))return It=13,4;var t=24&e;return 0!==t?(It=12,t):0!=(32&e)?(It=11,32):0!==(t=192&e)?(It=10,t):0!=(256&e)?(It=9,256):0!==(t=3584&e)?(It=8,t):0!=(4096&e)?(It=7,4096):0!==(t=4186112&e)?(It=6,t):0!==(t=62914560&e)?(It=5,t):67108864&e?(It=4,67108864):0!=(134217728&e)?(It=3,134217728):0!==(t=805306368&e)?(It=2,t):0!=(1073741824&e)?(It=1,1073741824):(It=8,e)}function Bt(e,t){var n=e.pendingLanes;if(0===n)return It=0;var a=0,r=0,o=e.expiredLanes,i=e.suspendedLanes,s=e.pingedLanes;if(0!==o)a=o,r=It=15;else if(0!==(o=134217727&n)){var l=o&~i;0!==l?(a=Dt(l),r=It):0!==(s&=o)&&(a=Dt(s),r=It)}else 0!==(o=n&~i)?(a=Dt(o),r=It):0!==s&&(a=Dt(s),r=It);if(0===a)return 0;if(a=n&((0>(a=31-Ht(a))?0:1<<a)<<1)-1,0!==t&&t!==a&&0==(t&i)){if(Dt(t),r<=It)return t;It=r}if(0!==(t=e.entangledLanes))for(e=e.entanglements,t&=a;0<t;)r=1<<(n=31-Ht(t)),a|=e[n],t&=~r;return a}function Ft(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function $t(e,t){switch(e){case 15:return 1;case 14:return 2;case 12:return 0===(e=Ut(24&~t))?$t(10,t):e;case 10:return 0===(e=Ut(192&~t))?$t(8,t):e;case 8:return 0===(e=Ut(3584&~t))&&(0===(e=Ut(4186112&~t))&&(e=512)),e;case 2:return 0===(t=Ut(805306368&~t))&&(t=268435456),t}throw Error(i(358,e))}function Ut(e){return e&-e}function zt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function Zt(e,t,n){e.pendingLanes|=t;var a=t-1;e.suspendedLanes&=a,e.pingedLanes&=a,(e=e.eventTimes)[t=31-Ht(t)]=n}var Ht=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(Vt(e)/qt|0)|0},Vt=Math.log,qt=Math.LN2;var Wt=o.unstable_UserBlockingPriority,Gt=o.unstable_runWithPriority,Kt=!0;function Yt(e,t,n,a){De||Re();var r=Xt,o=De;De=!0;try{Me(r,e,t,n,a)}finally{(De=o)||Fe()}}function Qt(e,t,n,a){Gt(Wt,Xt.bind(null,e,t,n,a))}function Xt(e,t,n,a){var r;if(Kt)if((r=0==(4&t))&&0<it.length&&-1<ft.indexOf(e))e=gt(null,e,t,n,a),it.push(e);else{var o=Jt(e,t,n,a);if(null===o)r&&mt(e,a);else{if(r){if(-1<ft.indexOf(e))return e=gt(o,e,t,n,a),void it.push(e);if(function(e,t,n,a,r){switch(t){case"focusin":return st=ht(st,e,t,n,a,r),!0;case"dragenter":return lt=ht(lt,e,t,n,a,r),!0;case"mouseover":return ct=ht(ct,e,t,n,a,r),!0;case"pointerover":var o=r.pointerId;return ut.set(o,ht(ut.get(o)||null,e,t,n,a,r)),!0;case"gotpointercapture":return o=r.pointerId,dt.set(o,ht(dt.get(o)||null,e,t,n,a,r)),!0}return!1}(o,e,t,n,a))return;mt(e,a)}Ra(e,t,a,null,n)}}}function Jt(e,t,n,a){var r=Te(a);if(null!==(r=nr(r))){var o=Ye(r);if(null===o)r=null;else{var i=o.tag;if(13===i){if(null!==(r=Qe(o)))return r;r=null}else if(3===i){if(o.stateNode.hydrate)return 3===o.tag?o.stateNode.containerInfo:null;r=null}else o!==r&&(r=null)}}return Ra(e,t,a,r,n),null}var en=null,tn=null,nn=null;function an(){if(nn)return nn;var e,t,n=tn,a=n.length,r="value"in en?en.value:en.textContent,o=r.length;for(e=0;e<a&&n[e]===r[e];e++);var i=a-e;for(t=1;t<=i&&n[a-t]===r[o-t];t++);return nn=r.slice(e,1<t?1-t:void 0)}function rn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function on(){return!0}function sn(){return!1}function ln(e){function t(t,n,a,r,o){for(var i in this._reactName=t,this._targetInst=a,this.type=n,this.nativeEvent=r,this.target=o,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(r):r[i]);return this.isDefaultPrevented=(null!=r.defaultPrevented?r.defaultPrevented:!1===r.returnValue)?on:sn,this.isPropagationStopped=sn,this}return r(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=on)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=on)},persist:function(){},isPersistent:on}),t}var cn,un,dn,pn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},fn=ln(pn),gn=r({},pn,{view:0,detail:0}),mn=ln(gn),hn=r({},gn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:An,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==dn&&(dn&&"mousemove"===e.type?(cn=e.screenX-dn.screenX,un=e.screenY-dn.screenY):un=cn=0,dn=e),cn)},movementY:function(e){return"movementY"in e?e.movementY:un}}),bn=ln(hn),vn=ln(r({},hn,{dataTransfer:0})),yn=ln(r({},gn,{relatedTarget:0})),wn=ln(r({},pn,{animationName:0,elapsedTime:0,pseudoElement:0})),_n=r({},pn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),xn=ln(_n),kn=ln(r({},pn,{data:0})),En={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},Sn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Tn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Cn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=Tn[e])&&!!t[e]}function An(){return Cn}var Ln=r({},gn,{key:function(e){if(e.key){var t=En[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=rn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?Sn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:An,charCode:function(e){return"keypress"===e.type?rn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?rn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Pn=ln(Ln),Nn=ln(r({},hn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),jn=ln(r({},gn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:An})),On=ln(r({},pn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Mn=r({},hn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Rn=ln(Mn),In=[9,13,27,32],Dn=d&&"CompositionEvent"in window,Bn=null;d&&"documentMode"in document&&(Bn=document.documentMode);var Fn=d&&"TextEvent"in window&&!Bn,$n=d&&(!Dn||Bn&&8<Bn&&11>=Bn),Un=String.fromCharCode(32),zn=!1;function Zn(e,t){switch(e){case"keyup":return-1!==In.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Hn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Vn=!1;var qn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Wn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!qn[e.type]:"textarea"===t}function Gn(e,t,n,a){Ne(a),0<(t=Da(t,"onChange")).length&&(n=new fn("onChange","change",null,n,a),e.push({event:n,listeners:t}))}var Kn=null,Yn=null;function Qn(e){La(e,0)}function Xn(e){if(Q(rr(e)))return e}function Jn(e,t){if("change"===e)return t}var ea=!1;if(d){var ta;if(d){var na="oninput"in document;if(!na){var aa=document.createElement("div");aa.setAttribute("oninput","return;"),na="function"==typeof aa.oninput}ta=na}else ta=!1;ea=ta&&(!document.documentMode||9<document.documentMode)}function ra(){Kn&&(Kn.detachEvent("onpropertychange",oa),Yn=Kn=null)}function oa(e){if("value"===e.propertyName&&Xn(Yn)){var t=[];if(Gn(t,Yn,e,Te(e)),e=Qn,De)e(t);else{De=!0;try{Oe(e,t)}finally{De=!1,Fe()}}}}function ia(e,t,n){"focusin"===e?(ra(),Yn=n,(Kn=t).attachEvent("onpropertychange",oa)):"focusout"===e&&ra()}function sa(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Xn(Yn)}function la(e,t){if("click"===e)return Xn(t)}function ca(e,t){if("input"===e||"change"===e)return Xn(t)}var ua="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},da=Object.prototype.hasOwnProperty;function pa(e,t){if(ua(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),a=Object.keys(t);if(n.length!==a.length)return!1;for(a=0;a<n.length;a++)if(!da.call(t,n[a])||!ua(e[n[a]],t[n[a]]))return!1;return!0}function fa(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function ga(e,t){var n,a=fa(e);for(e=0;a;){if(3===a.nodeType){if(n=e+a.textContent.length,e<=t&&n>=t)return{node:a,offset:t-e};e=n}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=fa(a)}}function ma(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?ma(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function ha(){for(var e=window,t=X();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(a){n=!1}if(!n)break;t=X((e=t.contentWindow).document)}return t}function ba(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var va=d&&"documentMode"in document&&11>=document.documentMode,ya=null,wa=null,_a=null,xa=!1;function ka(e,t,n){var a=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;xa||null==ya||ya!==X(a)||("selectionStart"in(a=ya)&&ba(a)?a={start:a.selectionStart,end:a.selectionEnd}:a={anchorNode:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset},_a&&pa(_a,a)||(_a=a,0<(a=Da(wa,"onSelect")).length&&(t=new fn("onSelect","select",null,t,n),e.push({event:t,listeners:a}),t.target=ya)))}Rt("cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange".split(" "),0),Rt("drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel".split(" "),1),Rt(Mt,2);for(var Ea="change selectionchange textInput compositionstart compositionend compositionupdate".split(" "),Sa=0;Sa<Ea.length;Sa++)Ot.set(Ea[Sa],0);u("onMouseEnter",["mouseout","mouseover"]),u("onMouseLeave",["mouseout","mouseover"]),u("onPointerEnter",["pointerout","pointerover"]),u("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Ta="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Ca=new Set("cancel close invalid load scroll toggle".split(" ").concat(Ta));function Aa(e,t,n){var a=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,a,r,o,s,l,c){if(Ke.apply(this,arguments),He){if(!He)throw Error(i(198));var u=Ve;He=!1,Ve=null,qe||(qe=!0,We=u)}}(a,t,void 0,e),e.currentTarget=null}function La(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var a=e[n],r=a.event;a=a.listeners;e:{var o=void 0;if(t)for(var i=a.length-1;0<=i;i--){var s=a[i],l=s.instance,c=s.currentTarget;if(s=s.listener,l!==o&&r.isPropagationStopped())break e;Aa(r,s,c),o=l}else for(i=0;i<a.length;i++){if(l=(s=a[i]).instance,c=s.currentTarget,s=s.listener,l!==o&&r.isPropagationStopped())break e;Aa(r,s,c),o=l}}}if(qe)throw e=We,qe=!1,We=null,e}function Pa(e,t){var n=ir(t),a=e+"__bubble";n.has(a)||(Ma(t,e,2,!1),n.add(a))}var Na="_reactListening"+Math.random().toString(36).slice(2);function ja(e){e[Na]||(e[Na]=!0,s.forEach((function(t){Ca.has(t)||Oa(t,!1,e,null),Oa(t,!0,e,null)})))}function Oa(e,t,n,a){var r=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,o=n;if("selectionchange"===e&&9!==n.nodeType&&(o=n.ownerDocument),null!==a&&!t&&Ca.has(e)){if("scroll"!==e)return;r|=2,o=a}var i=ir(o),s=e+"__"+(t?"capture":"bubble");i.has(s)||(t&&(r|=4),Ma(o,e,r,t),i.add(s))}function Ma(e,t,n,a){var r=Ot.get(t);switch(void 0===r?2:r){case 0:r=Yt;break;case 1:r=Qt;break;default:r=Xt}n=r.bind(null,t,n,e),r=void 0,!Ue||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(r=!0),a?void 0!==r?e.addEventListener(t,n,{capture:!0,passive:r}):e.addEventListener(t,n,!0):void 0!==r?e.addEventListener(t,n,{passive:r}):e.addEventListener(t,n,!1)}function Ra(e,t,n,a,r){var o=a;if(0==(1&t)&&0==(2&t)&&null!==a)e:for(;;){if(null===a)return;var i=a.tag;if(3===i||4===i){var s=a.stateNode.containerInfo;if(s===r||8===s.nodeType&&s.parentNode===r)break;if(4===i)for(i=a.return;null!==i;){var l=i.tag;if((3===l||4===l)&&((l=i.stateNode.containerInfo)===r||8===l.nodeType&&l.parentNode===r))return;i=i.return}for(;null!==s;){if(null===(i=nr(s)))return;if(5===(l=i.tag)||6===l){a=o=i;continue e}s=s.parentNode}}a=a.return}!function(e,t,n){if(Be)return e(t,n);Be=!0;try{Ie(e,t,n)}finally{Be=!1,Fe()}}((function(){var a=o,r=Te(n),i=[];e:{var s=jt.get(e);if(void 0!==s){var l=fn,c=e;switch(e){case"keypress":if(0===rn(n))break e;case"keydown":case"keyup":l=Pn;break;case"focusin":c="focus",l=yn;break;case"focusout":c="blur",l=yn;break;case"beforeblur":case"afterblur":l=yn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":l=bn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":l=vn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":l=jn;break;case At:case Lt:case Pt:l=wn;break;case Nt:l=On;break;case"scroll":l=mn;break;case"wheel":l=Rn;break;case"copy":case"cut":case"paste":l=xn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":l=Nn}var u=0!=(4&t),d=!u&&"scroll"===e,p=u?null!==s?s+"Capture":null:s;u=[];for(var f,g=a;null!==g;){var m=(f=g).stateNode;if(5===f.tag&&null!==m&&(f=m,null!==p&&(null!=(m=$e(g,p))&&u.push(Ia(g,m,f)))),d)break;g=g.return}0<u.length&&(s=new l(s,c,null,n,r),i.push({event:s,listeners:u}))}}if(0==(7&t)){if(l="mouseout"===e||"pointerout"===e,(!(s="mouseover"===e||"pointerover"===e)||0!=(16&t)||!(c=n.relatedTarget||n.fromElement)||!nr(c)&&!c[er])&&(l||s)&&(s=r.window===r?r:(s=r.ownerDocument)?s.defaultView||s.parentWindow:window,l?(l=a,null!==(c=(c=n.relatedTarget||n.toElement)?nr(c):null)&&(c!==(d=Ye(c))||5!==c.tag&&6!==c.tag)&&(c=null)):(l=null,c=a),l!==c)){if(u=bn,m="onMouseLeave",p="onMouseEnter",g="mouse","pointerout"!==e&&"pointerover"!==e||(u=Nn,m="onPointerLeave",p="onPointerEnter",g="pointer"),d=null==l?s:rr(l),f=null==c?s:rr(c),(s=new u(m,g+"leave",l,n,r)).target=d,s.relatedTarget=f,m=null,nr(r)===a&&((u=new u(p,g+"enter",c,n,r)).target=f,u.relatedTarget=d,m=u),d=m,l&&c)e:{for(p=c,g=0,f=u=l;f;f=Ba(f))g++;for(f=0,m=p;m;m=Ba(m))f++;for(;0<g-f;)u=Ba(u),g--;for(;0<f-g;)p=Ba(p),f--;for(;g--;){if(u===p||null!==p&&u===p.alternate)break e;u=Ba(u),p=Ba(p)}u=null}else u=null;null!==l&&Fa(i,s,l,u,!1),null!==c&&null!==d&&Fa(i,d,c,u,!0)}if("select"===(l=(s=a?rr(a):window).nodeName&&s.nodeName.toLowerCase())||"input"===l&&"file"===s.type)var h=Jn;else if(Wn(s))if(ea)h=ca;else{h=sa;var b=ia}else(l=s.nodeName)&&"input"===l.toLowerCase()&&("checkbox"===s.type||"radio"===s.type)&&(h=la);switch(h&&(h=h(e,a))?Gn(i,h,n,r):(b&&b(e,s,a),"focusout"===e&&(b=s._wrapperState)&&b.controlled&&"number"===s.type&&re(s,"number",s.value)),b=a?rr(a):window,e){case"focusin":(Wn(b)||"true"===b.contentEditable)&&(ya=b,wa=a,_a=null);break;case"focusout":_a=wa=ya=null;break;case"mousedown":xa=!0;break;case"contextmenu":case"mouseup":case"dragend":xa=!1,ka(i,n,r);break;case"selectionchange":if(va)break;case"keydown":case"keyup":ka(i,n,r)}var v;if(Dn)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else Vn?Zn(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&($n&&"ko"!==n.locale&&(Vn||"onCompositionStart"!==y?"onCompositionEnd"===y&&Vn&&(v=an()):(tn="value"in(en=r)?en.value:en.textContent,Vn=!0)),0<(b=Da(a,y)).length&&(y=new kn(y,e,null,n,r),i.push({event:y,listeners:b}),v?y.data=v:null!==(v=Hn(n))&&(y.data=v))),(v=Fn?function(e,t){switch(e){case"compositionend":return Hn(t);case"keypress":return 32!==t.which?null:(zn=!0,Un);case"textInput":return(e=t.data)===Un&&zn?null:e;default:return null}}(e,n):function(e,t){if(Vn)return"compositionend"===e||!Dn&&Zn(e,t)?(e=an(),nn=tn=en=null,Vn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return $n&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(a=Da(a,"onBeforeInput")).length&&(r=new kn("onBeforeInput","beforeinput",null,n,r),i.push({event:r,listeners:a}),r.data=v))}La(i,t)}))}function Ia(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Da(e,t){for(var n=t+"Capture",a=[];null!==e;){var r=e,o=r.stateNode;5===r.tag&&null!==o&&(r=o,null!=(o=$e(e,n))&&a.unshift(Ia(e,o,r)),null!=(o=$e(e,t))&&a.push(Ia(e,o,r))),e=e.return}return a}function Ba(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Fa(e,t,n,a,r){for(var o=t._reactName,i=[];null!==n&&n!==a;){var s=n,l=s.alternate,c=s.stateNode;if(null!==l&&l===a)break;5===s.tag&&null!==c&&(s=c,r?null!=(l=$e(n,o))&&i.unshift(Ia(n,l,s)):r||null!=(l=$e(n,o))&&i.push(Ia(n,l,s))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}function $a(){}var Ua=null,za=null;function Za(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function Ha(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var Va="function"==typeof setTimeout?setTimeout:void 0,qa="function"==typeof clearTimeout?clearTimeout:void 0;function Wa(e){1===e.nodeType?e.textContent="":9===e.nodeType&&(null!=(e=e.body)&&(e.textContent=""))}function Ga(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Ka(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var Ya=0;var Qa=Math.random().toString(36).slice(2),Xa="__reactFiber$"+Qa,Ja="__reactProps$"+Qa,er="__reactContainer$"+Qa,tr="__reactEvents$"+Qa;function nr(e){var t=e[Xa];if(t)return t;for(var n=e.parentNode;n;){if(t=n[er]||n[Xa]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Ka(e);null!==e;){if(n=e[Xa])return n;e=Ka(e)}return t}n=(e=n).parentNode}return null}function ar(e){return!(e=e[Xa]||e[er])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function rr(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(i(33))}function or(e){return e[Ja]||null}function ir(e){var t=e[tr];return void 0===t&&(t=e[tr]=new Set),t}var sr=[],lr=-1;function cr(e){return{current:e}}function ur(e){0>lr||(e.current=sr[lr],sr[lr]=null,lr--)}function dr(e,t){lr++,sr[lr]=e.current,e.current=t}var pr={},fr=cr(pr),gr=cr(!1),mr=pr;function hr(e,t){var n=e.type.contextTypes;if(!n)return pr;var a=e.stateNode;if(a&&a.__reactInternalMemoizedUnmaskedChildContext===t)return a.__reactInternalMemoizedMaskedChildContext;var r,o={};for(r in n)o[r]=t[r];return a&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function br(e){return null!=(e=e.childContextTypes)}function vr(){ur(gr),ur(fr)}function yr(e,t,n){if(fr.current!==pr)throw Error(i(168));dr(fr,t),dr(gr,n)}function wr(e,t,n){var a=e.stateNode;if(e=t.childContextTypes,"function"!=typeof a.getChildContext)return n;for(var o in a=a.getChildContext())if(!(o in e))throw Error(i(108,W(t)||"Unknown",o));return r({},n,a)}function _r(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||pr,mr=fr.current,dr(fr,e),dr(gr,gr.current),!0}function xr(e,t,n){var a=e.stateNode;if(!a)throw Error(i(169));n?(e=wr(e,t,mr),a.__reactInternalMemoizedMergedChildContext=e,ur(gr),ur(fr),dr(fr,e)):ur(gr),dr(gr,n)}var kr=null,Er=null,Sr=o.unstable_runWithPriority,Tr=o.unstable_scheduleCallback,Cr=o.unstable_cancelCallback,Ar=o.unstable_shouldYield,Lr=o.unstable_requestPaint,Pr=o.unstable_now,Nr=o.unstable_getCurrentPriorityLevel,jr=o.unstable_ImmediatePriority,Or=o.unstable_UserBlockingPriority,Mr=o.unstable_NormalPriority,Rr=o.unstable_LowPriority,Ir=o.unstable_IdlePriority,Dr={},Br=void 0!==Lr?Lr:function(){},Fr=null,$r=null,Ur=!1,zr=Pr(),Zr=1e4>zr?Pr:function(){return Pr()-zr};function Hr(){switch(Nr()){case jr:return 99;case Or:return 98;case Mr:return 97;case Rr:return 96;case Ir:return 95;default:throw Error(i(332))}}function Vr(e){switch(e){case 99:return jr;case 98:return Or;case 97:return Mr;case 96:return Rr;case 95:return Ir;default:throw Error(i(332))}}function qr(e,t){return e=Vr(e),Sr(e,t)}function Wr(e,t,n){return e=Vr(e),Tr(e,t,n)}function Gr(){if(null!==$r){var e=$r;$r=null,Cr(e)}Kr()}function Kr(){if(!Ur&&null!==Fr){Ur=!0;var e=0;try{var t=Fr;qr(99,(function(){for(;e<t.length;e++){var n=t[e];do{n=n(!0)}while(null!==n)}})),Fr=null}catch(n){throw null!==Fr&&(Fr=Fr.slice(e+1)),Tr(jr,Gr),n}finally{Ur=!1}}}var Yr=_.ReactCurrentBatchConfig;function Qr(e,t){if(e&&e.defaultProps){for(var n in t=r({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var Xr=cr(null),Jr=null,eo=null,to=null;function no(){to=eo=Jr=null}function ao(e){var t=Xr.current;ur(Xr),e.type._context._currentValue=t}function ro(e,t){for(;null!==e;){var n=e.alternate;if((e.childLanes&t)===t){if(null===n||(n.childLanes&t)===t)break;n.childLanes|=t}else e.childLanes|=t,null!==n&&(n.childLanes|=t);e=e.return}}function oo(e,t){Jr=e,to=eo=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(Di=!0),e.firstContext=null)}function io(e,t){if(to!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(to=e,t=1073741823),t={context:e,observedBits:t,next:null},null===eo){if(null===Jr)throw Error(i(308));eo=t,Jr.dependencies={lanes:0,firstContext:t,responders:null}}else eo=eo.next=t;return e._currentValue}var so=!1;function lo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function co(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function uo(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function po(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function fo(e,t){var n=e.updateQueue,a=e.alternate;if(null!==a&&n===(a=a.updateQueue)){var r=null,o=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===o?r=o=i:o=o.next=i,n=n.next}while(null!==n);null===o?r=o=t:o=o.next=t}else r=o=t;return n={baseState:a.baseState,firstBaseUpdate:r,lastBaseUpdate:o,shared:a.shared,effects:a.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function go(e,t,n,a){var o=e.updateQueue;so=!1;var i=o.firstBaseUpdate,s=o.lastBaseUpdate,l=o.shared.pending;if(null!==l){o.shared.pending=null;var c=l,u=c.next;c.next=null,null===s?i=u:s.next=u,s=c;var d=e.alternate;if(null!==d){var p=(d=d.updateQueue).lastBaseUpdate;p!==s&&(null===p?d.firstBaseUpdate=u:p.next=u,d.lastBaseUpdate=c)}}if(null!==i){for(p=o.baseState,s=0,d=u=c=null;;){l=i.lane;var f=i.eventTime;if((a&l)===l){null!==d&&(d=d.next={eventTime:f,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var g=e,m=i;switch(l=t,f=n,m.tag){case 1:if("function"==typeof(g=m.payload)){p=g.call(f,p,l);break e}p=g;break e;case 3:g.flags=-4097&g.flags|64;case 0:if(null==(l="function"==typeof(g=m.payload)?g.call(f,p,l):g))break e;p=r({},p,l);break e;case 2:so=!0}}null!==i.callback&&(e.flags|=32,null===(l=o.effects)?o.effects=[i]:l.push(i))}else f={eventTime:f,lane:l,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(u=d=f,c=p):d=d.next=f,s|=l;if(null===(i=i.next)){if(null===(l=o.shared.pending))break;i=l.next,l.next=null,o.lastBaseUpdate=l,o.shared.pending=null}}null===d&&(c=p),o.baseState=c,o.firstBaseUpdate=u,o.lastBaseUpdate=d,Us|=s,e.lanes=s,e.memoizedState=p}}function mo(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var a=e[t],r=a.callback;if(null!==r){if(a.callback=null,a=n,"function"!=typeof r)throw Error(i(191,r));r.call(a)}}}var ho=(new a.Component).refs;function bo(e,t,n,a){n=null==(n=n(a,t=e.memoizedState))?t:r({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var vo={isMounted:function(e){return!!(e=e._reactInternals)&&Ye(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var a=pl(),r=fl(e),o=uo(a,r);o.payload=t,null!=n&&(o.callback=n),po(e,o),gl(e,r,a)},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var a=pl(),r=fl(e),o=uo(a,r);o.tag=1,o.payload=t,null!=n&&(o.callback=n),po(e,o),gl(e,r,a)},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=pl(),a=fl(e),r=uo(n,a);r.tag=2,null!=t&&(r.callback=t),po(e,r),gl(e,a,n)}};function yo(e,t,n,a,r,o,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(a,o,i):!t.prototype||!t.prototype.isPureReactComponent||(!pa(n,a)||!pa(r,o))}function wo(e,t,n){var a=!1,r=pr,o=t.contextType;return"object"==typeof o&&null!==o?o=io(o):(r=br(t)?mr:fr.current,o=(a=null!=(a=t.contextTypes))?hr(e,r):pr),t=new t(n,o),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=vo,e.stateNode=t,t._reactInternals=e,a&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=r,e.__reactInternalMemoizedMaskedChildContext=o),t}function _o(e,t,n,a){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,a),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,a),t.state!==e&&vo.enqueueReplaceState(t,t.state,null)}function xo(e,t,n,a){var r=e.stateNode;r.props=n,r.state=e.memoizedState,r.refs=ho,lo(e);var o=t.contextType;"object"==typeof o&&null!==o?r.context=io(o):(o=br(t)?mr:fr.current,r.context=hr(e,o)),go(e,n,r,a),r.state=e.memoizedState,"function"==typeof(o=t.getDerivedStateFromProps)&&(bo(e,t,o,n),r.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof r.getSnapshotBeforeUpdate||"function"!=typeof r.UNSAFE_componentWillMount&&"function"!=typeof r.componentWillMount||(t=r.state,"function"==typeof r.componentWillMount&&r.componentWillMount(),"function"==typeof r.UNSAFE_componentWillMount&&r.UNSAFE_componentWillMount(),t!==r.state&&vo.enqueueReplaceState(r,r.state,null),go(e,n,r,a),r.state=e.memoizedState),"function"==typeof r.componentDidMount&&(e.flags|=4)}var ko=Array.isArray;function Eo(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(i(309));var a=n.stateNode}if(!a)throw Error(i(147,e));var r=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===r?t.ref:(t=function(e){var t=a.refs;t===ho&&(t=a.refs={}),null===e?delete t[r]:t[r]=e},t._stringRef=r,t)}if("string"!=typeof e)throw Error(i(284));if(!n._owner)throw Error(i(290,e))}return e}function So(e,t){if("textarea"!==e.type)throw Error(i(31,"[object Object]"===Object.prototype.toString.call(t)?"object with keys {"+Object.keys(t).join(", ")+"}":t))}function To(e){function t(t,n){if(e){var a=t.lastEffect;null!==a?(a.nextEffect=n,t.lastEffect=n):t.firstEffect=t.lastEffect=n,n.nextEffect=null,n.flags=8}}function n(n,a){if(!e)return null;for(;null!==a;)t(n,a),a=a.sibling;return null}function a(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function r(e,t){return(e=ql(e,t)).index=0,e.sibling=null,e}function o(t,n,a){return t.index=a,e?null!==(a=t.alternate)?(a=a.index)<n?(t.flags=2,n):a:(t.flags=2,n):n}function s(t){return e&&null===t.alternate&&(t.flags=2),t}function l(e,t,n,a){return null===t||6!==t.tag?((t=Yl(n,e.mode,a)).return=e,t):((t=r(t,n)).return=e,t)}function c(e,t,n,a){return null!==t&&t.elementType===n.type?((a=r(t,n.props)).ref=Eo(e,t,n),a.return=e,a):((a=Wl(n.type,n.key,n.props,null,e.mode,a)).ref=Eo(e,t,n),a.return=e,a)}function u(e,t,n,a){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Ql(n,e.mode,a)).return=e,t):((t=r(t,n.children||[])).return=e,t)}function d(e,t,n,a,o){return null===t||7!==t.tag?((t=Gl(n,e.mode,a,o)).return=e,t):((t=r(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t||"number"==typeof t)return(t=Yl(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case x:return(n=Wl(t.type,t.key,t.props,null,e.mode,n)).ref=Eo(e,null,t),n.return=e,n;case k:return(t=Ql(t,e.mode,n)).return=e,t}if(ko(t)||z(t))return(t=Gl(t,e.mode,n,null)).return=e,t;So(e,t)}return null}function f(e,t,n,a){var r=null!==t?t.key:null;if("string"==typeof n||"number"==typeof n)return null!==r?null:l(e,t,""+n,a);if("object"==typeof n&&null!==n){switch(n.$$typeof){case x:return n.key===r?n.type===E?d(e,t,n.props.children,a,r):c(e,t,n,a):null;case k:return n.key===r?u(e,t,n,a):null}if(ko(n)||z(n))return null!==r?null:d(e,t,n,a,null);So(e,n)}return null}function g(e,t,n,a,r){if("string"==typeof a||"number"==typeof a)return l(t,e=e.get(n)||null,""+a,r);if("object"==typeof a&&null!==a){switch(a.$$typeof){case x:return e=e.get(null===a.key?n:a.key)||null,a.type===E?d(t,e,a.props.children,r,a.key):c(t,e,a,r);case k:return u(t,e=e.get(null===a.key?n:a.key)||null,a,r)}if(ko(a)||z(a))return d(t,e=e.get(n)||null,a,r,null);So(t,a)}return null}function m(r,i,s,l){for(var c=null,u=null,d=i,m=i=0,h=null;null!==d&&m<s.length;m++){d.index>m?(h=d,d=null):h=d.sibling;var b=f(r,d,s[m],l);if(null===b){null===d&&(d=h);break}e&&d&&null===b.alternate&&t(r,d),i=o(b,i,m),null===u?c=b:u.sibling=b,u=b,d=h}if(m===s.length)return n(r,d),c;if(null===d){for(;m<s.length;m++)null!==(d=p(r,s[m],l))&&(i=o(d,i,m),null===u?c=d:u.sibling=d,u=d);return c}for(d=a(r,d);m<s.length;m++)null!==(h=g(d,r,m,s[m],l))&&(e&&null!==h.alternate&&d.delete(null===h.key?m:h.key),i=o(h,i,m),null===u?c=h:u.sibling=h,u=h);return e&&d.forEach((function(e){return t(r,e)})),c}function h(r,s,l,c){var u=z(l);if("function"!=typeof u)throw Error(i(150));if(null==(l=u.call(l)))throw Error(i(151));for(var d=u=null,m=s,h=s=0,b=null,v=l.next();null!==m&&!v.done;h++,v=l.next()){m.index>h?(b=m,m=null):b=m.sibling;var y=f(r,m,v.value,c);if(null===y){null===m&&(m=b);break}e&&m&&null===y.alternate&&t(r,m),s=o(y,s,h),null===d?u=y:d.sibling=y,d=y,m=b}if(v.done)return n(r,m),u;if(null===m){for(;!v.done;h++,v=l.next())null!==(v=p(r,v.value,c))&&(s=o(v,s,h),null===d?u=v:d.sibling=v,d=v);return u}for(m=a(r,m);!v.done;h++,v=l.next())null!==(v=g(m,r,h,v.value,c))&&(e&&null!==v.alternate&&m.delete(null===v.key?h:v.key),s=o(v,s,h),null===d?u=v:d.sibling=v,d=v);return e&&m.forEach((function(e){return t(r,e)})),u}return function(e,a,o,l){var c="object"==typeof o&&null!==o&&o.type===E&&null===o.key;c&&(o=o.props.children);var u="object"==typeof o&&null!==o;if(u)switch(o.$$typeof){case x:e:{for(u=o.key,c=a;null!==c;){if(c.key===u){if(7===c.tag){if(o.type===E){n(e,c.sibling),(a=r(c,o.props.children)).return=e,e=a;break e}}else if(c.elementType===o.type){n(e,c.sibling),(a=r(c,o.props)).ref=Eo(e,c,o),a.return=e,e=a;break e}n(e,c);break}t(e,c),c=c.sibling}o.type===E?((a=Gl(o.props.children,e.mode,l,o.key)).return=e,e=a):((l=Wl(o.type,o.key,o.props,null,e.mode,l)).ref=Eo(e,a,o),l.return=e,e=l)}return s(e);case k:e:{for(c=o.key;null!==a;){if(a.key===c){if(4===a.tag&&a.stateNode.containerInfo===o.containerInfo&&a.stateNode.implementation===o.implementation){n(e,a.sibling),(a=r(a,o.children||[])).return=e,e=a;break e}n(e,a);break}t(e,a),a=a.sibling}(a=Ql(o,e.mode,l)).return=e,e=a}return s(e)}if("string"==typeof o||"number"==typeof o)return o=""+o,null!==a&&6===a.tag?(n(e,a.sibling),(a=r(a,o)).return=e,e=a):(n(e,a),(a=Yl(o,e.mode,l)).return=e,e=a),s(e);if(ko(o))return m(e,a,o,l);if(z(o))return h(e,a,o,l);if(u&&So(e,o),void 0===o&&!c)switch(e.tag){case 1:case 22:case 0:case 11:case 15:throw Error(i(152,W(e.type)||"Component"))}return n(e,a)}}var Co=To(!0),Ao=To(!1),Lo={},Po=cr(Lo),No=cr(Lo),jo=cr(Lo);function Oo(e){if(e===Lo)throw Error(i(174));return e}function Mo(e,t){switch(dr(jo,t),dr(No,e),dr(Po,Lo),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:ge(null,"");break;default:t=ge(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}ur(Po),dr(Po,t)}function Ro(){ur(Po),ur(No),ur(jo)}function Io(e){Oo(jo.current);var t=Oo(Po.current),n=ge(t,e.type);t!==n&&(dr(No,e),dr(Po,n))}function Do(e){No.current===e&&(ur(Po),ur(No))}var Bo=cr(0);function Fo(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var $o=null,Uo=null,zo=!1;function Zo(e,t){var n=Hl(5,null,null,0);n.elementType="DELETED",n.type="DELETED",n.stateNode=t,n.return=e,n.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=n,e.lastEffect=n):e.firstEffect=e.lastEffect=n}function Ho(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,!0);default:return!1}}function Vo(e){if(zo){var t=Uo;if(t){var n=t;if(!Ho(e,t)){if(!(t=Ga(n.nextSibling))||!Ho(e,t))return e.flags=-1025&e.flags|2,zo=!1,void($o=e);Zo($o,n)}$o=e,Uo=Ga(t.firstChild)}else e.flags=-1025&e.flags|2,zo=!1,$o=e}}function qo(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;$o=e}function Wo(e){if(e!==$o)return!1;if(!zo)return qo(e),zo=!0,!1;var t=e.type;if(5!==e.tag||"head"!==t&&"body"!==t&&!Ha(t,e.memoizedProps))for(t=Uo;t;)Zo(e,t),t=Ga(t.nextSibling);if(qo(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(i(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){Uo=Ga(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}Uo=null}}else Uo=$o?Ga(e.stateNode.nextSibling):null;return!0}function Go(){Uo=$o=null,zo=!1}var Ko=[];function Yo(){for(var e=0;e<Ko.length;e++)Ko[e]._workInProgressVersionPrimary=null;Ko.length=0}var Qo=_.ReactCurrentDispatcher,Xo=_.ReactCurrentBatchConfig,Jo=0,ei=null,ti=null,ni=null,ai=!1,ri=!1;function oi(){throw Error(i(321))}function ii(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!ua(e[n],t[n]))return!1;return!0}function si(e,t,n,a,r,o){if(Jo=o,ei=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,Qo.current=null===e||null===e.memoizedState?Oi:Mi,e=n(a,r),ri){o=0;do{if(ri=!1,!(25>o))throw Error(i(301));o+=1,ni=ti=null,t.updateQueue=null,Qo.current=Ri,e=n(a,r)}while(ri)}if(Qo.current=ji,t=null!==ti&&null!==ti.next,Jo=0,ni=ti=ei=null,ai=!1,t)throw Error(i(300));return e}function li(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ni?ei.memoizedState=ni=e:ni=ni.next=e,ni}function ci(){if(null===ti){var e=ei.alternate;e=null!==e?e.memoizedState:null}else e=ti.next;var t=null===ni?ei.memoizedState:ni.next;if(null!==t)ni=t,ti=e;else{if(null===e)throw Error(i(310));e={memoizedState:(ti=e).memoizedState,baseState:ti.baseState,baseQueue:ti.baseQueue,queue:ti.queue,next:null},null===ni?ei.memoizedState=ni=e:ni=ni.next=e}return ni}function ui(e,t){return"function"==typeof t?t(e):t}function di(e){var t=ci(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var a=ti,r=a.baseQueue,o=n.pending;if(null!==o){if(null!==r){var s=r.next;r.next=o.next,o.next=s}a.baseQueue=r=o,n.pending=null}if(null!==r){r=r.next,a=a.baseState;var l=s=o=null,c=r;do{var u=c.lane;if((Jo&u)===u)null!==l&&(l=l.next={lane:0,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null}),a=c.eagerReducer===e?c.eagerState:e(a,c.action);else{var d={lane:u,action:c.action,eagerReducer:c.eagerReducer,eagerState:c.eagerState,next:null};null===l?(s=l=d,o=a):l=l.next=d,ei.lanes|=u,Us|=u}c=c.next}while(null!==c&&c!==r);null===l?o=a:l.next=s,ua(a,t.memoizedState)||(Di=!0),t.memoizedState=a,t.baseState=o,t.baseQueue=l,n.lastRenderedState=a}return[t.memoizedState,n.dispatch]}function pi(e){var t=ci(),n=t.queue;if(null===n)throw Error(i(311));n.lastRenderedReducer=e;var a=n.dispatch,r=n.pending,o=t.memoizedState;if(null!==r){n.pending=null;var s=r=r.next;do{o=e(o,s.action),s=s.next}while(s!==r);ua(o,t.memoizedState)||(Di=!0),t.memoizedState=o,null===t.baseQueue&&(t.baseState=o),n.lastRenderedState=o}return[o,a]}function fi(e,t,n){var a=t._getVersion;a=a(t._source);var r=t._workInProgressVersionPrimary;if(null!==r?e=r===a:(e=e.mutableReadLanes,(e=(Jo&e)===e)&&(t._workInProgressVersionPrimary=a,Ko.push(t))),e)return n(t._source);throw Ko.push(t),Error(i(350))}function gi(e,t,n,a){var r=Os;if(null===r)throw Error(i(349));var o=t._getVersion,s=o(t._source),l=Qo.current,c=l.useState((function(){return fi(r,t,n)})),u=c[1],d=c[0];c=ni;var p=e.memoizedState,f=p.refs,g=f.getSnapshot,m=p.source;p=p.subscribe;var h=ei;return e.memoizedState={refs:f,source:t,subscribe:a},l.useEffect((function(){f.getSnapshot=n,f.setSnapshot=u;var e=o(t._source);if(!ua(s,e)){e=n(t._source),ua(d,e)||(u(e),e=fl(h),r.mutableReadLanes|=e&r.pendingLanes),e=r.mutableReadLanes,r.entangledLanes|=e;for(var a=r.entanglements,i=e;0<i;){var l=31-Ht(i),c=1<<l;a[l]|=e,i&=~c}}}),[n,t,a]),l.useEffect((function(){return a(t._source,(function(){var e=f.getSnapshot,n=f.setSnapshot;try{n(e(t._source));var a=fl(h);r.mutableReadLanes|=a&r.pendingLanes}catch(o){n((function(){throw o}))}}))}),[t,a]),ua(g,n)&&ua(m,t)&&ua(p,a)||((e={pending:null,dispatch:null,lastRenderedReducer:ui,lastRenderedState:d}).dispatch=u=Ni.bind(null,ei,e),c.queue=e,c.baseQueue=null,d=fi(r,t,n),c.memoizedState=c.baseState=d),d}function mi(e,t,n){return gi(ci(),e,t,n)}function hi(e){var t=li();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:ui,lastRenderedState:e}).dispatch=Ni.bind(null,ei,e),[t.memoizedState,e]}function bi(e,t,n,a){return e={tag:e,create:t,destroy:n,deps:a,next:null},null===(t=ei.updateQueue)?(t={lastEffect:null},ei.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(a=n.next,n.next=e,e.next=a,t.lastEffect=e),e}function vi(e){return e={current:e},li().memoizedState=e}function yi(){return ci().memoizedState}function wi(e,t,n,a){var r=li();ei.flags|=e,r.memoizedState=bi(1|t,n,void 0,void 0===a?null:a)}function _i(e,t,n,a){var r=ci();a=void 0===a?null:a;var o=void 0;if(null!==ti){var i=ti.memoizedState;if(o=i.destroy,null!==a&&ii(a,i.deps))return void bi(t,n,o,a)}ei.flags|=e,r.memoizedState=bi(1|t,n,o,a)}function xi(e,t){return wi(516,4,e,t)}function ki(e,t){return _i(516,4,e,t)}function Ei(e,t){return _i(4,2,e,t)}function Si(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Ti(e,t,n){return n=null!=n?n.concat([e]):null,_i(4,2,Si.bind(null,t,e),n)}function Ci(){}function Ai(e,t){var n=ci();t=void 0===t?null:t;var a=n.memoizedState;return null!==a&&null!==t&&ii(t,a[1])?a[0]:(n.memoizedState=[e,t],e)}function Li(e,t){var n=ci();t=void 0===t?null:t;var a=n.memoizedState;return null!==a&&null!==t&&ii(t,a[1])?a[0]:(e=e(),n.memoizedState=[e,t],e)}function Pi(e,t){var n=Hr();qr(98>n?98:n,(function(){e(!0)})),qr(97<n?97:n,(function(){var n=Xo.transition;Xo.transition=1;try{e(!1),t()}finally{Xo.transition=n}}))}function Ni(e,t,n){var a=pl(),r=fl(e),o={lane:r,action:n,eagerReducer:null,eagerState:null,next:null},i=t.pending;if(null===i?o.next=o:(o.next=i.next,i.next=o),t.pending=o,i=e.alternate,e===ei||null!==i&&i===ei)ri=ai=!0;else{if(0===e.lanes&&(null===i||0===i.lanes)&&null!==(i=t.lastRenderedReducer))try{var s=t.lastRenderedState,l=i(s,n);if(o.eagerReducer=i,o.eagerState=l,ua(l,s))return}catch(c){}gl(e,r,a)}}var ji={readContext:io,useCallback:oi,useContext:oi,useEffect:oi,useImperativeHandle:oi,useLayoutEffect:oi,useMemo:oi,useReducer:oi,useRef:oi,useState:oi,useDebugValue:oi,useDeferredValue:oi,useTransition:oi,useMutableSource:oi,useOpaqueIdentifier:oi,unstable_isNewReconciler:!1},Oi={readContext:io,useCallback:function(e,t){return li().memoizedState=[e,void 0===t?null:t],e},useContext:io,useEffect:xi,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,wi(4,2,Si.bind(null,t,e),n)},useLayoutEffect:function(e,t){return wi(4,2,e,t)},useMemo:function(e,t){var n=li();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var a=li();return t=void 0!==n?n(t):t,a.memoizedState=a.baseState=t,e=(e=a.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:t}).dispatch=Ni.bind(null,ei,e),[a.memoizedState,e]},useRef:vi,useState:hi,useDebugValue:Ci,useDeferredValue:function(e){var t=hi(e),n=t[0],a=t[1];return xi((function(){var t=Xo.transition;Xo.transition=1;try{a(e)}finally{Xo.transition=t}}),[e]),n},useTransition:function(){var e=hi(!1),t=e[0];return vi(e=Pi.bind(null,e[1])),[e,t]},useMutableSource:function(e,t,n){var a=li();return a.memoizedState={refs:{getSnapshot:t,setSnapshot:null},source:e,subscribe:n},gi(a,e,t,n)},useOpaqueIdentifier:function(){if(zo){var e=!1,t=function(e){return{$$typeof:R,toString:e,valueOf:e}}((function(){throw e||(e=!0,n("r:"+(Ya++).toString(36))),Error(i(355))})),n=hi(t)[1];return 0==(2&ei.mode)&&(ei.flags|=516,bi(5,(function(){n("r:"+(Ya++).toString(36))}),void 0,null)),t}return hi(t="r:"+(Ya++).toString(36)),t},unstable_isNewReconciler:!1},Mi={readContext:io,useCallback:Ai,useContext:io,useEffect:ki,useImperativeHandle:Ti,useLayoutEffect:Ei,useMemo:Li,useReducer:di,useRef:yi,useState:function(){return di(ui)},useDebugValue:Ci,useDeferredValue:function(e){var t=di(ui),n=t[0],a=t[1];return ki((function(){var t=Xo.transition;Xo.transition=1;try{a(e)}finally{Xo.transition=t}}),[e]),n},useTransition:function(){var e=di(ui)[0];return[yi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return di(ui)[0]},unstable_isNewReconciler:!1},Ri={readContext:io,useCallback:Ai,useContext:io,useEffect:ki,useImperativeHandle:Ti,useLayoutEffect:Ei,useMemo:Li,useReducer:pi,useRef:yi,useState:function(){return pi(ui)},useDebugValue:Ci,useDeferredValue:function(e){var t=pi(ui),n=t[0],a=t[1];return ki((function(){var t=Xo.transition;Xo.transition=1;try{a(e)}finally{Xo.transition=t}}),[e]),n},useTransition:function(){var e=pi(ui)[0];return[yi().current,e]},useMutableSource:mi,useOpaqueIdentifier:function(){return pi(ui)[0]},unstable_isNewReconciler:!1},Ii=_.ReactCurrentOwner,Di=!1;function Bi(e,t,n,a){t.child=null===e?Ao(t,null,n,a):Co(t,e.child,n,a)}function Fi(e,t,n,a,r){n=n.render;var o=t.ref;return oo(t,r),a=si(e,t,n,a,o,r),null===e||Di?(t.flags|=1,Bi(e,t,a,r),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~r,os(e,t,r))}function $i(e,t,n,a,r,o){if(null===e){var i=n.type;return"function"!=typeof i||Vl(i)||void 0!==i.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Wl(n.type,null,a,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=i,Ui(e,t,i,a,r,o))}return i=e.child,0==(r&o)&&(r=i.memoizedProps,(n=null!==(n=n.compare)?n:pa)(r,a)&&e.ref===t.ref)?os(e,t,o):(t.flags|=1,(e=ql(i,a)).ref=t.ref,e.return=t,t.child=e)}function Ui(e,t,n,a,r,o){if(null!==e&&pa(e.memoizedProps,a)&&e.ref===t.ref){if(Di=!1,0==(o&r))return t.lanes=e.lanes,os(e,t,o);0!=(16384&e.flags)&&(Di=!0)}return Hi(e,t,n,a,o)}function zi(e,t,n){var a=t.pendingProps,r=a.children,o=null!==e?e.memoizedState:null;if("hidden"===a.mode||"unstable-defer-without-hiding"===a.mode)if(0==(4&t.mode))t.memoizedState={baseLanes:0},xl(t,n);else{if(0==(1073741824&n))return e=null!==o?o.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e},xl(t,e),null;t.memoizedState={baseLanes:0},xl(t,null!==o?o.baseLanes:n)}else null!==o?(a=o.baseLanes|n,t.memoizedState=null):a=n,xl(t,a);return Bi(e,t,r,n),t.child}function Zi(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=128)}function Hi(e,t,n,a,r){var o=br(n)?mr:fr.current;return o=hr(t,o),oo(t,r),n=si(e,t,n,a,o,r),null===e||Di?(t.flags|=1,Bi(e,t,n,r),t.child):(t.updateQueue=e.updateQueue,t.flags&=-517,e.lanes&=~r,os(e,t,r))}function Vi(e,t,n,a,r){if(br(n)){var o=!0;_r(t)}else o=!1;if(oo(t,r),null===t.stateNode)null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),wo(t,n,a),xo(t,n,a,r),a=!0;else if(null===e){var i=t.stateNode,s=t.memoizedProps;i.props=s;var l=i.context,c=n.contextType;"object"==typeof c&&null!==c?c=io(c):c=hr(t,c=br(n)?mr:fr.current);var u=n.getDerivedStateFromProps,d="function"==typeof u||"function"==typeof i.getSnapshotBeforeUpdate;d||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(s!==a||l!==c)&&_o(t,i,a,c),so=!1;var p=t.memoizedState;i.state=p,go(t,a,i,r),l=t.memoizedState,s!==a||p!==l||gr.current||so?("function"==typeof u&&(bo(t,n,u,a),l=t.memoizedState),(s=so||yo(t,n,s,a,p,l,c))?(d||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4)):("function"==typeof i.componentDidMount&&(t.flags|=4),t.memoizedProps=a,t.memoizedState=l),i.props=a,i.state=l,i.context=c,a=s):("function"==typeof i.componentDidMount&&(t.flags|=4),a=!1)}else{i=t.stateNode,co(e,t),s=t.memoizedProps,c=t.type===t.elementType?s:Qr(t.type,s),i.props=c,d=t.pendingProps,p=i.context,"object"==typeof(l=n.contextType)&&null!==l?l=io(l):l=hr(t,l=br(n)?mr:fr.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(s!==d||p!==l)&&_o(t,i,a,l),so=!1,p=t.memoizedState,i.state=p,go(t,a,i,r);var g=t.memoizedState;s!==d||p!==g||gr.current||so?("function"==typeof f&&(bo(t,n,f,a),g=t.memoizedState),(c=so||yo(t,n,c,a,p,g,l))?(u||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(a,g,l),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(a,g,l)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=256)):("function"!=typeof i.componentDidUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),t.memoizedProps=a,t.memoizedState=g),i.props=a,i.state=g,i.context=l,a=c):("function"!=typeof i.componentDidUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=256),a=!1)}return qi(e,t,n,a,o,r)}function qi(e,t,n,a,r,o){Zi(e,t);var i=0!=(64&t.flags);if(!a&&!i)return r&&xr(t,n,!1),os(e,t,o);a=t.stateNode,Ii.current=t;var s=i&&"function"!=typeof n.getDerivedStateFromError?null:a.render();return t.flags|=1,null!==e&&i?(t.child=Co(t,e.child,null,o),t.child=Co(t,null,s,o)):Bi(e,t,s,o),t.memoizedState=a.state,r&&xr(t,n,!0),t.child}function Wi(e){var t=e.stateNode;t.pendingContext?yr(0,t.pendingContext,t.pendingContext!==t.context):t.context&&yr(0,t.context,!1),Mo(e,t.containerInfo)}var Gi,Ki,Yi,Qi={dehydrated:null,retryLane:0};function Xi(e,t,n){var a,r=t.pendingProps,o=Bo.current,i=!1;return(a=0!=(64&t.flags))||(a=(null===e||null!==e.memoizedState)&&0!=(2&o)),a?(i=!0,t.flags&=-65):null!==e&&null===e.memoizedState||void 0===r.fallback||!0===r.unstable_avoidThisFallback||(o|=1),dr(Bo,1&o),null===e?(void 0!==r.fallback&&Vo(t),e=r.children,o=r.fallback,i?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,e):"number"==typeof r.unstable_expectedLoadTime?(e=Ji(t,e,o,n),t.child.memoizedState={baseLanes:n},t.memoizedState=Qi,t.lanes=33554432,e):((n=Kl({mode:"visible",children:e},t.mode,n,null)).return=t,t.child=n)):(e.memoizedState,i?(r=ts(e,t,r.children,r.fallback,n),i=t.child,o=e.child.memoizedState,i.memoizedState=null===o?{baseLanes:n}:{baseLanes:o.baseLanes|n},i.childLanes=e.childLanes&~n,t.memoizedState=Qi,r):(n=es(e,t,r.children,n),t.memoizedState=null,n))}function Ji(e,t,n,a){var r=e.mode,o=e.child;return t={mode:"hidden",children:t},0==(2&r)&&null!==o?(o.childLanes=0,o.pendingProps=t):o=Kl(t,r,0,null),n=Gl(n,r,a,null),o.return=e,n.return=e,o.sibling=n,e.child=o,n}function es(e,t,n,a){var r=e.child;return e=r.sibling,n=ql(r,{mode:"visible",children:n}),0==(2&t.mode)&&(n.lanes=a),n.return=t,n.sibling=null,null!==e&&(e.nextEffect=null,e.flags=8,t.firstEffect=t.lastEffect=e),t.child=n}function ts(e,t,n,a,r){var o=t.mode,i=e.child;e=i.sibling;var s={mode:"hidden",children:n};return 0==(2&o)&&t.child!==i?((n=t.child).childLanes=0,n.pendingProps=s,null!==(i=n.lastEffect)?(t.firstEffect=n.firstEffect,t.lastEffect=i,i.nextEffect=null):t.firstEffect=t.lastEffect=null):n=ql(i,s),null!==e?a=ql(e,a):(a=Gl(a,o,r,null)).flags|=2,a.return=t,n.return=t,n.sibling=a,t.child=n,a}function ns(e,t){e.lanes|=t;var n=e.alternate;null!==n&&(n.lanes|=t),ro(e.return,t)}function as(e,t,n,a,r,o){var i=e.memoizedState;null===i?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:a,tail:n,tailMode:r,lastEffect:o}:(i.isBackwards=t,i.rendering=null,i.renderingStartTime=0,i.last=a,i.tail=n,i.tailMode=r,i.lastEffect=o)}function rs(e,t,n){var a=t.pendingProps,r=a.revealOrder,o=a.tail;if(Bi(e,t,a.children,n),0!=(2&(a=Bo.current)))a=1&a|2,t.flags|=64;else{if(null!==e&&0!=(64&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&ns(e,n);else if(19===e.tag)ns(e,n);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}a&=1}if(dr(Bo,a),0==(2&t.mode))t.memoizedState=null;else switch(r){case"forwards":for(n=t.child,r=null;null!==n;)null!==(e=n.alternate)&&null===Fo(e)&&(r=n),n=n.sibling;null===(n=r)?(r=t.child,t.child=null):(r=n.sibling,n.sibling=null),as(t,!1,r,n,o,t.lastEffect);break;case"backwards":for(n=null,r=t.child,t.child=null;null!==r;){if(null!==(e=r.alternate)&&null===Fo(e)){t.child=r;break}e=r.sibling,r.sibling=n,n=r,r=e}as(t,!0,n,null,o,t.lastEffect);break;case"together":as(t,!1,null,null,void 0,t.lastEffect);break;default:t.memoizedState=null}return t.child}function os(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Us|=t.lanes,0!=(n&t.childLanes)){if(null!==e&&t.child!==e.child)throw Error(i(153));if(null!==t.child){for(n=ql(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=ql(e,e.pendingProps)).return=t;n.sibling=null}return t.child}return null}function is(e,t){if(!zo)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var a=null;null!==n;)null!==n.alternate&&(a=n),n=n.sibling;null===a?t||null===e.tail?e.tail=null:e.tail.sibling=null:a.sibling=null}}function ss(e,t,n){var a=t.pendingProps;switch(t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return br(t.type)&&vr(),null;case 3:return Ro(),ur(gr),ur(fr),Yo(),(a=t.stateNode).pendingContext&&(a.context=a.pendingContext,a.pendingContext=null),null!==e&&null!==e.child||(Wo(t)?t.flags|=4:a.hydrate||(t.flags|=256)),null;case 5:Do(t);var o=Oo(jo.current);if(n=t.type,null!==e&&null!=t.stateNode)Ki(e,t,n,a),e.ref!==t.ref&&(t.flags|=128);else{if(!a){if(null===t.stateNode)throw Error(i(166));return null}if(e=Oo(Po.current),Wo(t)){a=t.stateNode,n=t.type;var s=t.memoizedProps;switch(a[Xa]=t,a[Ja]=s,n){case"dialog":Pa("cancel",a),Pa("close",a);break;case"iframe":case"object":case"embed":Pa("load",a);break;case"video":case"audio":for(e=0;e<Ta.length;e++)Pa(Ta[e],a);break;case"source":Pa("error",a);break;case"img":case"image":case"link":Pa("error",a),Pa("load",a);break;case"details":Pa("toggle",a);break;case"input":ee(a,s),Pa("invalid",a);break;case"select":a._wrapperState={wasMultiple:!!s.multiple},Pa("invalid",a);break;case"textarea":le(a,s),Pa("invalid",a)}for(var c in Ee(n,s),e=null,s)s.hasOwnProperty(c)&&(o=s[c],"children"===c?"string"==typeof o?a.textContent!==o&&(e=["children",o]):"number"==typeof o&&a.textContent!==""+o&&(e=["children",""+o]):l.hasOwnProperty(c)&&null!=o&&"onScroll"===c&&Pa("scroll",a));switch(n){case"input":Y(a),ae(a,s,!0);break;case"textarea":Y(a),ue(a);break;case"select":case"option":break;default:"function"==typeof s.onClick&&(a.onclick=$a)}a=e,t.updateQueue=a,null!==a&&(t.flags|=4)}else{switch(c=9===o.nodeType?o:o.ownerDocument,e===de&&(e=fe(n)),e===de?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof a.is?e=c.createElement(n,{is:a.is}):(e=c.createElement(n),"select"===n&&(c=e,a.multiple?c.multiple=!0:a.size&&(c.size=a.size))):e=c.createElementNS(e,n),e[Xa]=t,e[Ja]=a,Gi(e,t),t.stateNode=e,c=Se(n,a),n){case"dialog":Pa("cancel",e),Pa("close",e),o=a;break;case"iframe":case"object":case"embed":Pa("load",e),o=a;break;case"video":case"audio":for(o=0;o<Ta.length;o++)Pa(Ta[o],e);o=a;break;case"source":Pa("error",e),o=a;break;case"img":case"image":case"link":Pa("error",e),Pa("load",e),o=a;break;case"details":Pa("toggle",e),o=a;break;case"input":ee(e,a),o=J(e,a),Pa("invalid",e);break;case"option":o=oe(e,a);break;case"select":e._wrapperState={wasMultiple:!!a.multiple},o=r({},a,{value:void 0}),Pa("invalid",e);break;case"textarea":le(e,a),o=se(e,a),Pa("invalid",e);break;default:o=a}Ee(n,o);var u=o;for(s in u)if(u.hasOwnProperty(s)){var d=u[s];"style"===s?xe(e,d):"dangerouslySetInnerHTML"===s?null!=(d=d?d.__html:void 0)&&be(e,d):"children"===s?"string"==typeof d?("textarea"!==n||""!==d)&&ve(e,d):"number"==typeof d&&ve(e,""+d):"suppressContentEditableWarning"!==s&&"suppressHydrationWarning"!==s&&"autoFocus"!==s&&(l.hasOwnProperty(s)?null!=d&&"onScroll"===s&&Pa("scroll",e):null!=d&&w(e,s,d,c))}switch(n){case"input":Y(e),ae(e,a,!1);break;case"textarea":Y(e),ue(e);break;case"option":null!=a.value&&e.setAttribute("value",""+G(a.value));break;case"select":e.multiple=!!a.multiple,null!=(s=a.value)?ie(e,!!a.multiple,s,!1):null!=a.defaultValue&&ie(e,!!a.multiple,a.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=$a)}Za(n,a)&&(t.flags|=4)}null!==t.ref&&(t.flags|=128)}return null;case 6:if(e&&null!=t.stateNode)Yi(0,t,e.memoizedProps,a);else{if("string"!=typeof a&&null===t.stateNode)throw Error(i(166));n=Oo(jo.current),Oo(Po.current),Wo(t)?(a=t.stateNode,n=t.memoizedProps,a[Xa]=t,a.nodeValue!==n&&(t.flags|=4)):((a=(9===n.nodeType?n:n.ownerDocument).createTextNode(a))[Xa]=t,t.stateNode=a)}return null;case 13:return ur(Bo),a=t.memoizedState,0!=(64&t.flags)?(t.lanes=n,t):(a=null!==a,n=!1,null===e?void 0!==t.memoizedProps.fallback&&Wo(t):n=null!==e.memoizedState,a&&!n&&0!=(2&t.mode)&&(null===e&&!0!==t.memoizedProps.unstable_avoidThisFallback||0!=(1&Bo.current)?0===Bs&&(Bs=3):(0!==Bs&&3!==Bs||(Bs=4),null===Os||0==(134217727&Us)&&0==(134217727&zs)||vl(Os,Rs))),(a||n)&&(t.flags|=4),null);case 4:return Ro(),null===e&&ja(t.stateNode.containerInfo),null;case 10:return ao(t),null;case 19:if(ur(Bo),null===(a=t.memoizedState))return null;if(s=0!=(64&t.flags),null===(c=a.rendering))if(s)is(a,!1);else{if(0!==Bs||null!==e&&0!=(64&e.flags))for(e=t.child;null!==e;){if(null!==(c=Fo(e))){for(t.flags|=64,is(a,!1),null!==(s=c.updateQueue)&&(t.updateQueue=s,t.flags|=4),null===a.lastEffect&&(t.firstEffect=null),t.lastEffect=a.lastEffect,a=n,n=t.child;null!==n;)e=a,(s=n).flags&=2,s.nextEffect=null,s.firstEffect=null,s.lastEffect=null,null===(c=s.alternate)?(s.childLanes=0,s.lanes=e,s.child=null,s.memoizedProps=null,s.memoizedState=null,s.updateQueue=null,s.dependencies=null,s.stateNode=null):(s.childLanes=c.childLanes,s.lanes=c.lanes,s.child=c.child,s.memoizedProps=c.memoizedProps,s.memoizedState=c.memoizedState,s.updateQueue=c.updateQueue,s.type=c.type,e=c.dependencies,s.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return dr(Bo,1&Bo.current|2),t.child}e=e.sibling}null!==a.tail&&Zr()>qs&&(t.flags|=64,s=!0,is(a,!1),t.lanes=33554432)}else{if(!s)if(null!==(e=Fo(c))){if(t.flags|=64,s=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),is(a,!0),null===a.tail&&"hidden"===a.tailMode&&!c.alternate&&!zo)return null!==(t=t.lastEffect=a.lastEffect)&&(t.nextEffect=null),null}else 2*Zr()-a.renderingStartTime>qs&&1073741824!==n&&(t.flags|=64,s=!0,is(a,!1),t.lanes=33554432);a.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=a.last)?n.sibling=c:t.child=c,a.last=c)}return null!==a.tail?(n=a.tail,a.rendering=n,a.tail=n.sibling,a.lastEffect=t.lastEffect,a.renderingStartTime=Zr(),n.sibling=null,t=Bo.current,dr(Bo,s?1&t|2:1&t),n):null;case 23:case 24:return kl(),null!==e&&null!==e.memoizedState!=(null!==t.memoizedState)&&"unstable-defer-without-hiding"!==a.mode&&(t.flags|=4),null}throw Error(i(156,t.tag))}function ls(e){switch(e.tag){case 1:br(e.type)&&vr();var t=e.flags;return 4096&t?(e.flags=-4097&t|64,e):null;case 3:if(Ro(),ur(gr),ur(fr),Yo(),0!=(64&(t=e.flags)))throw Error(i(285));return e.flags=-4097&t|64,e;case 5:return Do(e),null;case 13:return ur(Bo),4096&(t=e.flags)?(e.flags=-4097&t|64,e):null;case 19:return ur(Bo),null;case 4:return Ro(),null;case 10:return ao(e),null;case 23:case 24:return kl(),null;default:return null}}function cs(e,t){try{var n="",a=t;do{n+=q(a),a=a.return}while(a);var r=n}catch(o){r="\nError generating stack: "+o.message+"\n"+o.stack}return{value:e,source:t,stack:r}}function us(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}Gi=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Ki=function(e,t,n,a){var o=e.memoizedProps;if(o!==a){e=t.stateNode,Oo(Po.current);var i,s=null;switch(n){case"input":o=J(e,o),a=J(e,a),s=[];break;case"option":o=oe(e,o),a=oe(e,a),s=[];break;case"select":o=r({},o,{value:void 0}),a=r({},a,{value:void 0}),s=[];break;case"textarea":o=se(e,o),a=se(e,a),s=[];break;default:"function"!=typeof o.onClick&&"function"==typeof a.onClick&&(e.onclick=$a)}for(d in Ee(n,a),n=null,o)if(!a.hasOwnProperty(d)&&o.hasOwnProperty(d)&&null!=o[d])if("style"===d){var c=o[d];for(i in c)c.hasOwnProperty(i)&&(n||(n={}),n[i]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(l.hasOwnProperty(d)?s||(s=[]):(s=s||[]).push(d,null));for(d in a){var u=a[d];if(c=null!=o?o[d]:void 0,a.hasOwnProperty(d)&&u!==c&&(null!=u||null!=c))if("style"===d)if(c){for(i in c)!c.hasOwnProperty(i)||u&&u.hasOwnProperty(i)||(n||(n={}),n[i]="");for(i in u)u.hasOwnProperty(i)&&c[i]!==u[i]&&(n||(n={}),n[i]=u[i])}else n||(s||(s=[]),s.push(d,n)),n=u;else"dangerouslySetInnerHTML"===d?(u=u?u.__html:void 0,c=c?c.__html:void 0,null!=u&&c!==u&&(s=s||[]).push(d,u)):"children"===d?"string"!=typeof u&&"number"!=typeof u||(s=s||[]).push(d,""+u):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(l.hasOwnProperty(d)?(null!=u&&"onScroll"===d&&Pa("scroll",e),s||c===u||(s=[])):"object"==typeof u&&null!==u&&u.$$typeof===R?u.toString():(s=s||[]).push(d,u))}n&&(s=s||[]).push("style",n);var d=s;(t.updateQueue=d)&&(t.flags|=4)}},Yi=function(e,t,n,a){n!==a&&(t.flags|=4)};var ds="function"==typeof WeakMap?WeakMap:Map;function ps(e,t,n){(n=uo(-1,n)).tag=3,n.payload={element:null};var a=t.value;return n.callback=function(){Ys||(Ys=!0,Qs=a),us(0,t)},n}function fs(e,t,n){(n=uo(-1,n)).tag=3;var a=e.type.getDerivedStateFromError;if("function"==typeof a){var r=t.value;n.payload=function(){return us(0,t),a(r)}}var o=e.stateNode;return null!==o&&"function"==typeof o.componentDidCatch&&(n.callback=function(){"function"!=typeof a&&(null===Xs?Xs=new Set([this]):Xs.add(this),us(0,t));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}var gs="function"==typeof WeakSet?WeakSet:Set;function ms(e){var t=e.ref;if(null!==t)if("function"==typeof t)try{t(null)}catch(n){$l(e,n)}else t.current=null}function hs(e,t){switch(t.tag){case 0:case 11:case 15:case 22:case 5:case 6:case 4:case 17:return;case 1:if(256&t.flags&&null!==e){var n=e.memoizedProps,a=e.memoizedState;t=(e=t.stateNode).getSnapshotBeforeUpdate(t.elementType===t.type?n:Qr(t.type,n),a),e.__reactInternalSnapshotBeforeUpdate=t}return;case 3:return void(256&t.flags&&Wa(t.stateNode.containerInfo))}throw Error(i(163))}function bs(e,t,n){switch(n.tag){case 0:case 11:case 15:case 22:if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{if(3==(3&e.tag)){var a=e.create;e.destroy=a()}e=e.next}while(e!==t)}if(null!==(t=null!==(t=n.updateQueue)?t.lastEffect:null)){e=t=t.next;do{var r=e;a=r.next,0!=(4&(r=r.tag))&&0!=(1&r)&&(Dl(n,e),Il(n,e)),e=a}while(e!==t)}return;case 1:return e=n.stateNode,4&n.flags&&(null===t?e.componentDidMount():(a=n.elementType===n.type?t.memoizedProps:Qr(n.type,t.memoizedProps),e.componentDidUpdate(a,t.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(t=n.updateQueue)&&mo(n,t,e));case 3:if(null!==(t=n.updateQueue)){if(e=null,null!==n.child)switch(n.child.tag){case 5:case 1:e=n.child.stateNode}mo(n,t,e)}return;case 5:return e=n.stateNode,void(null===t&&4&n.flags&&Za(n.type,n.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:case 23:case 24:return;case 13:return void(null===n.memoizedState&&(n=n.alternate,null!==n&&(n=n.memoizedState,null!==n&&(n=n.dehydrated,null!==n&&xt(n)))))}throw Error(i(163))}function vs(e,t){for(var n=e;;){if(5===n.tag){var a=n.stateNode;if(t)"function"==typeof(a=a.style).setProperty?a.setProperty("display","none","important"):a.display="none";else{a=n.stateNode;var r=n.memoizedProps.style;r=null!=r&&r.hasOwnProperty("display")?r.display:null,a.style.display=_e("display",r)}}else if(6===n.tag)n.stateNode.nodeValue=t?"":n.memoizedProps;else if((23!==n.tag&&24!==n.tag||null===n.memoizedState||n===e)&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return;n=n.return}n.sibling.return=n.return,n=n.sibling}}function ys(e,t){if(Er&&"function"==typeof Er.onCommitFiberUnmount)try{Er.onCommitFiberUnmount(kr,t)}catch(o){}switch(t.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=t.updateQueue)&&null!==(e=e.lastEffect)){var n=e=e.next;do{var a=n,r=a.destroy;if(a=a.tag,void 0!==r)if(0!=(4&a))Dl(t,n);else{a=t;try{r()}catch(o){$l(a,o)}}n=n.next}while(n!==e)}break;case 1:if(ms(t),"function"==typeof(e=t.stateNode).componentWillUnmount)try{e.props=t.memoizedProps,e.state=t.memoizedState,e.componentWillUnmount()}catch(o){$l(t,o)}break;case 5:ms(t);break;case 4:Ss(e,t)}}function ws(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function _s(e){return 5===e.tag||3===e.tag||4===e.tag}function xs(e){e:{for(var t=e.return;null!==t;){if(_s(t))break e;t=t.return}throw Error(i(160))}var n=t;switch(t=n.stateNode,n.tag){case 5:var a=!1;break;case 3:case 4:t=t.containerInfo,a=!0;break;default:throw Error(i(161))}16&n.flags&&(ve(t,""),n.flags&=-17);e:t:for(n=e;;){for(;null===n.sibling;){if(null===n.return||_s(n.return)){n=null;break e}n=n.return}for(n.sibling.return=n.return,n=n.sibling;5!==n.tag&&6!==n.tag&&18!==n.tag;){if(2&n.flags)continue t;if(null===n.child||4===n.tag)continue t;n.child.return=n,n=n.child}if(!(2&n.flags)){n=n.stateNode;break e}}a?ks(e,n,t):Es(e,n,t)}function ks(e,t,n){var a=e.tag,r=5===a||6===a;if(r)e=r?e.stateNode:e.stateNode.instance,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=$a));else if(4!==a&&null!==(e=e.child))for(ks(e,t,n),e=e.sibling;null!==e;)ks(e,t,n),e=e.sibling}function Es(e,t,n){var a=e.tag,r=5===a||6===a;if(r)e=r?e.stateNode:e.stateNode.instance,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==a&&null!==(e=e.child))for(Es(e,t,n),e=e.sibling;null!==e;)Es(e,t,n),e=e.sibling}function Ss(e,t){for(var n,a,r=t,o=!1;;){if(!o){o=r.return;e:for(;;){if(null===o)throw Error(i(160));switch(n=o.stateNode,o.tag){case 5:a=!1;break e;case 3:case 4:n=n.containerInfo,a=!0;break e}o=o.return}o=!0}if(5===r.tag||6===r.tag){e:for(var s=e,l=r,c=l;;)if(ys(s,c),null!==c.child&&4!==c.tag)c.child.return=c,c=c.child;else{if(c===l)break e;for(;null===c.sibling;){if(null===c.return||c.return===l)break e;c=c.return}c.sibling.return=c.return,c=c.sibling}a?(s=n,l=r.stateNode,8===s.nodeType?s.parentNode.removeChild(l):s.removeChild(l)):n.removeChild(r.stateNode)}else if(4===r.tag){if(null!==r.child){n=r.stateNode.containerInfo,a=!0,r.child.return=r,r=r.child;continue}}else if(ys(e,r),null!==r.child){r.child.return=r,r=r.child;continue}if(r===t)break;for(;null===r.sibling;){if(null===r.return||r.return===t)return;4===(r=r.return).tag&&(o=!1)}r.sibling.return=r.return,r=r.sibling}}function Ts(e,t){switch(t.tag){case 0:case 11:case 14:case 15:case 22:var n=t.updateQueue;if(null!==(n=null!==n?n.lastEffect:null)){var a=n=n.next;do{3==(3&a.tag)&&(e=a.destroy,a.destroy=void 0,void 0!==e&&e()),a=a.next}while(a!==n)}return;case 1:case 12:case 17:return;case 5:if(null!=(n=t.stateNode)){a=t.memoizedProps;var r=null!==e?e.memoizedProps:a;e=t.type;var o=t.updateQueue;if(t.updateQueue=null,null!==o){for(n[Ja]=a,"input"===e&&"radio"===a.type&&null!=a.name&&te(n,a),Se(e,r),t=Se(e,a),r=0;r<o.length;r+=2){var s=o[r],l=o[r+1];"style"===s?xe(n,l):"dangerouslySetInnerHTML"===s?be(n,l):"children"===s?ve(n,l):w(n,s,l,t)}switch(e){case"input":ne(n,a);break;case"textarea":ce(n,a);break;case"select":e=n._wrapperState.wasMultiple,n._wrapperState.wasMultiple=!!a.multiple,null!=(o=a.value)?ie(n,!!a.multiple,o,!1):e!==!!a.multiple&&(null!=a.defaultValue?ie(n,!!a.multiple,a.defaultValue,!0):ie(n,!!a.multiple,a.multiple?[]:"",!1))}}}return;case 6:if(null===t.stateNode)throw Error(i(162));return void(t.stateNode.nodeValue=t.memoizedProps);case 3:return void((n=t.stateNode).hydrate&&(n.hydrate=!1,xt(n.containerInfo)));case 13:return null!==t.memoizedState&&(Vs=Zr(),vs(t.child,!0)),void Cs(t);case 19:return void Cs(t);case 23:case 24:return void vs(t,null!==t.memoizedState)}throw Error(i(163))}function Cs(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new gs),t.forEach((function(t){var a=zl.bind(null,e,t);n.has(t)||(n.add(t),t.then(a,a))}))}}function As(e,t){return null!==e&&(null===(e=e.memoizedState)||null!==e.dehydrated)&&(null!==(t=t.memoizedState)&&null===t.dehydrated)}var Ls=Math.ceil,Ps=_.ReactCurrentDispatcher,Ns=_.ReactCurrentOwner,js=0,Os=null,Ms=null,Rs=0,Is=0,Ds=cr(0),Bs=0,Fs=null,$s=0,Us=0,zs=0,Zs=0,Hs=null,Vs=0,qs=1/0;function Ws(){qs=Zr()+500}var Gs,Ks=null,Ys=!1,Qs=null,Xs=null,Js=!1,el=null,tl=90,nl=[],al=[],rl=null,ol=0,il=null,sl=-1,ll=0,cl=0,ul=null,dl=!1;function pl(){return 0!=(48&js)?Zr():-1!==sl?sl:sl=Zr()}function fl(e){if(0==(2&(e=e.mode)))return 1;if(0==(4&e))return 99===Hr()?1:2;if(0===ll&&(ll=$s),0!==Yr.transition){0!==cl&&(cl=null!==Hs?Hs.pendingLanes:0),e=ll;var t=4186112&~cl;return 0===(t&=-t)&&(0===(t=(e=4186112&~e)&-e)&&(t=8192)),t}return e=Hr(),0!=(4&js)&&98===e?e=$t(12,ll):e=$t(e=function(e){switch(e){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(e),ll),e}function gl(e,t,n){if(50<ol)throw ol=0,il=null,Error(i(185));if(null===(e=ml(e,t)))return null;Zt(e,t,n),e===Os&&(zs|=t,4===Bs&&vl(e,Rs));var a=Hr();1===t?0!=(8&js)&&0==(48&js)?yl(e):(hl(e,n),0===js&&(Ws(),Gr())):(0==(4&js)||98!==a&&99!==a||(null===rl?rl=new Set([e]):rl.add(e)),hl(e,n)),Hs=e}function ml(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}function hl(e,t){for(var n=e.callbackNode,a=e.suspendedLanes,r=e.pingedLanes,o=e.expirationTimes,s=e.pendingLanes;0<s;){var l=31-Ht(s),c=1<<l,u=o[l];if(-1===u){if(0==(c&a)||0!=(c&r)){u=t,Dt(c);var d=It;o[l]=10<=d?u+250:6<=d?u+5e3:-1}}else u<=t&&(e.expiredLanes|=c);s&=~c}if(a=Bt(e,e===Os?Rs:0),t=It,0===a)null!==n&&(n!==Dr&&Cr(n),e.callbackNode=null,e.callbackPriority=0);else{if(null!==n){if(e.callbackPriority===t)return;n!==Dr&&Cr(n)}15===t?(n=yl.bind(null,e),null===Fr?(Fr=[n],$r=Tr(jr,Kr)):Fr.push(n),n=Dr):14===t?n=Wr(99,yl.bind(null,e)):(n=function(e){switch(e){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(i(358,e))}}(t),n=Wr(n,bl.bind(null,e))),e.callbackPriority=t,e.callbackNode=n}}function bl(e){if(sl=-1,cl=ll=0,0!=(48&js))throw Error(i(327));var t=e.callbackNode;if(Rl()&&e.callbackNode!==t)return null;var n=Bt(e,e===Os?Rs:0);if(0===n)return null;var a=n,r=js;js|=16;var o=Tl();for(Os===e&&Rs===a||(Ws(),El(e,a));;)try{Ll();break}catch(l){Sl(e,l)}if(no(),Ps.current=o,js=r,null!==Ms?a=0:(Os=null,Rs=0,a=Bs),0!=($s&zs))El(e,0);else if(0!==a){if(2===a&&(js|=64,e.hydrate&&(e.hydrate=!1,Wa(e.containerInfo)),0!==(n=Ft(e))&&(a=Cl(e,n))),1===a)throw t=Fs,El(e,0),vl(e,n),hl(e,Zr()),t;switch(e.finishedWork=e.current.alternate,e.finishedLanes=n,a){case 0:case 1:throw Error(i(345));case 2:case 5:jl(e);break;case 3:if(vl(e,n),(62914560&n)===n&&10<(a=Vs+500-Zr())){if(0!==Bt(e,0))break;if(((r=e.suspendedLanes)&n)!==n){pl(),e.pingedLanes|=e.suspendedLanes&r;break}e.timeoutHandle=Va(jl.bind(null,e),a);break}jl(e);break;case 4:if(vl(e,n),(4186112&n)===n)break;for(a=e.eventTimes,r=-1;0<n;){var s=31-Ht(n);o=1<<s,(s=a[s])>r&&(r=s),n&=~o}if(n=r,10<(n=(120>(n=Zr()-n)?120:480>n?480:1080>n?1080:1920>n?1920:3e3>n?3e3:4320>n?4320:1960*Ls(n/1960))-n)){e.timeoutHandle=Va(jl.bind(null,e),n);break}jl(e);break;default:throw Error(i(329))}}return hl(e,Zr()),e.callbackNode===t?bl.bind(null,e):null}function vl(e,t){for(t&=~Zs,t&=~zs,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-Ht(t),a=1<<n;e[n]=-1,t&=~a}}function yl(e){if(0!=(48&js))throw Error(i(327));if(Rl(),e===Os&&0!=(e.expiredLanes&Rs)){var t=Rs,n=Cl(e,t);0!=($s&zs)&&(n=Cl(e,t=Bt(e,t)))}else n=Cl(e,t=Bt(e,0));if(0!==e.tag&&2===n&&(js|=64,e.hydrate&&(e.hydrate=!1,Wa(e.containerInfo)),0!==(t=Ft(e))&&(n=Cl(e,t))),1===n)throw n=Fs,El(e,0),vl(e,t),hl(e,Zr()),n;return e.finishedWork=e.current.alternate,e.finishedLanes=t,jl(e),hl(e,Zr()),null}function wl(e,t){var n=js;js|=1;try{return e(t)}finally{0===(js=n)&&(Ws(),Gr())}}function _l(e,t){var n=js;js&=-2,js|=8;try{return e(t)}finally{0===(js=n)&&(Ws(),Gr())}}function xl(e,t){dr(Ds,Is),Is|=t,$s|=t}function kl(){Is=Ds.current,ur(Ds)}function El(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,qa(n)),null!==Ms)for(n=Ms.return;null!==n;){var a=n;switch(a.tag){case 1:null!=(a=a.type.childContextTypes)&&vr();break;case 3:Ro(),ur(gr),ur(fr),Yo();break;case 5:Do(a);break;case 4:Ro();break;case 13:case 19:ur(Bo);break;case 10:ao(a);break;case 23:case 24:kl()}n=n.return}Os=e,Ms=ql(e.current,null),Rs=Is=$s=t,Bs=0,Fs=null,Zs=zs=Us=0}function Sl(e,t){for(;;){var n=Ms;try{if(no(),Qo.current=ji,ai){for(var a=ei.memoizedState;null!==a;){var r=a.queue;null!==r&&(r.pending=null),a=a.next}ai=!1}if(Jo=0,ni=ti=ei=null,ri=!1,Ns.current=null,null===n||null===n.return){Bs=1,Fs=t,Ms=null;break}e:{var o=e,i=n.return,s=n,l=t;if(t=Rs,s.flags|=2048,s.firstEffect=s.lastEffect=null,null!==l&&"object"==typeof l&&"function"==typeof l.then){var c=l;if(0==(2&s.mode)){var u=s.alternate;u?(s.updateQueue=u.updateQueue,s.memoizedState=u.memoizedState,s.lanes=u.lanes):(s.updateQueue=null,s.memoizedState=null)}var d=0!=(1&Bo.current),p=i;do{var f;if(f=13===p.tag){var g=p.memoizedState;if(null!==g)f=null!==g.dehydrated;else{var m=p.memoizedProps;f=void 0!==m.fallback&&(!0!==m.unstable_avoidThisFallback||!d)}}if(f){var h=p.updateQueue;if(null===h){var b=new Set;b.add(c),p.updateQueue=b}else h.add(c);if(0==(2&p.mode)){if(p.flags|=64,s.flags|=16384,s.flags&=-2981,1===s.tag)if(null===s.alternate)s.tag=17;else{var v=uo(-1,1);v.tag=2,po(s,v)}s.lanes|=1;break e}l=void 0,s=t;var y=o.pingCache;if(null===y?(y=o.pingCache=new ds,l=new Set,y.set(c,l)):void 0===(l=y.get(c))&&(l=new Set,y.set(c,l)),!l.has(s)){l.add(s);var w=Ul.bind(null,o,c,s);c.then(w,w)}p.flags|=4096,p.lanes=t;break e}p=p.return}while(null!==p);l=Error((W(s.type)||"A React component")+" suspended while rendering, but no fallback UI was specified.\n\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.")}5!==Bs&&(Bs=2),l=cs(l,s),p=i;do{switch(p.tag){case 3:o=l,p.flags|=4096,t&=-t,p.lanes|=t,fo(p,ps(0,o,t));break e;case 1:o=l;var _=p.type,x=p.stateNode;if(0==(64&p.flags)&&("function"==typeof _.getDerivedStateFromError||null!==x&&"function"==typeof x.componentDidCatch&&(null===Xs||!Xs.has(x)))){p.flags|=4096,t&=-t,p.lanes|=t,fo(p,fs(p,o,t));break e}}p=p.return}while(null!==p)}Nl(n)}catch(k){t=k,Ms===n&&null!==n&&(Ms=n=n.return);continue}break}}function Tl(){var e=Ps.current;return Ps.current=ji,null===e?ji:e}function Cl(e,t){var n=js;js|=16;var a=Tl();for(Os===e&&Rs===t||El(e,t);;)try{Al();break}catch(r){Sl(e,r)}if(no(),js=n,Ps.current=a,null!==Ms)throw Error(i(261));return Os=null,Rs=0,Bs}function Al(){for(;null!==Ms;)Pl(Ms)}function Ll(){for(;null!==Ms&&!Ar();)Pl(Ms)}function Pl(e){var t=Gs(e.alternate,e,Is);e.memoizedProps=e.pendingProps,null===t?Nl(e):Ms=t,Ns.current=null}function Nl(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(2048&t.flags)){if(null!==(n=ss(n,t,Is)))return void(Ms=n);if(24!==(n=t).tag&&23!==n.tag||null===n.memoizedState||0!=(1073741824&Is)||0==(4&n.mode)){for(var a=0,r=n.child;null!==r;)a|=r.lanes|r.childLanes,r=r.sibling;n.childLanes=a}null!==e&&0==(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=t.firstEffect),null!==t.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=t.firstEffect),e.lastEffect=t.lastEffect),1<t.flags&&(null!==e.lastEffect?e.lastEffect.nextEffect=t:e.firstEffect=t,e.lastEffect=t))}else{if(null!==(n=ls(t)))return n.flags&=2047,void(Ms=n);null!==e&&(e.firstEffect=e.lastEffect=null,e.flags|=2048)}if(null!==(t=t.sibling))return void(Ms=t);Ms=t=e}while(null!==t);0===Bs&&(Bs=5)}function jl(e){var t=Hr();return qr(99,Ol.bind(null,e,t)),null}function Ol(e,t){do{Rl()}while(null!==el);if(0!=(48&js))throw Error(i(327));var n=e.finishedWork;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(i(177));e.callbackNode=null;var a=n.lanes|n.childLanes,r=a,o=e.pendingLanes&~r;e.pendingLanes=r,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=r,e.mutableReadLanes&=r,e.entangledLanes&=r,r=e.entanglements;for(var s=e.eventTimes,l=e.expirationTimes;0<o;){var c=31-Ht(o),u=1<<c;r[c]=0,s[c]=-1,l[c]=-1,o&=~u}if(null!==rl&&0==(24&a)&&rl.has(e)&&rl.delete(e),e===Os&&(Ms=Os=null,Rs=0),1<n.flags?null!==n.lastEffect?(n.lastEffect.nextEffect=n,a=n.firstEffect):a=n:a=n.firstEffect,null!==a){if(r=js,js|=32,Ns.current=null,Ua=Kt,ba(s=ha())){if("selectionStart"in s)l={start:s.selectionStart,end:s.selectionEnd};else e:if(l=(l=s.ownerDocument)&&l.defaultView||window,(u=l.getSelection&&l.getSelection())&&0!==u.rangeCount){l=u.anchorNode,o=u.anchorOffset,c=u.focusNode,u=u.focusOffset;try{l.nodeType,c.nodeType}catch(T){l=null;break e}var d=0,p=-1,f=-1,g=0,m=0,h=s,b=null;t:for(;;){for(var v;h!==l||0!==o&&3!==h.nodeType||(p=d+o),h!==c||0!==u&&3!==h.nodeType||(f=d+u),3===h.nodeType&&(d+=h.nodeValue.length),null!==(v=h.firstChild);)b=h,h=v;for(;;){if(h===s)break t;if(b===l&&++g===o&&(p=d),b===c&&++m===u&&(f=d),null!==(v=h.nextSibling))break;b=(h=b).parentNode}h=v}l=-1===p||-1===f?null:{start:p,end:f}}else l=null;l=l||{start:0,end:0}}else l=null;za={focusedElem:s,selectionRange:l},Kt=!1,ul=null,dl=!1,Ks=a;do{try{Ml()}catch(T){if(null===Ks)throw Error(i(330));$l(Ks,T),Ks=Ks.nextEffect}}while(null!==Ks);ul=null,Ks=a;do{try{for(s=e;null!==Ks;){var y=Ks.flags;if(16&y&&ve(Ks.stateNode,""),128&y){var w=Ks.alternate;if(null!==w){var _=w.ref;null!==_&&("function"==typeof _?_(null):_.current=null)}}switch(1038&y){case 2:xs(Ks),Ks.flags&=-3;break;case 6:xs(Ks),Ks.flags&=-3,Ts(Ks.alternate,Ks);break;case 1024:Ks.flags&=-1025;break;case 1028:Ks.flags&=-1025,Ts(Ks.alternate,Ks);break;case 4:Ts(Ks.alternate,Ks);break;case 8:Ss(s,l=Ks);var x=l.alternate;ws(l),null!==x&&ws(x)}Ks=Ks.nextEffect}}catch(T){if(null===Ks)throw Error(i(330));$l(Ks,T),Ks=Ks.nextEffect}}while(null!==Ks);if(_=za,w=ha(),y=_.focusedElem,s=_.selectionRange,w!==y&&y&&y.ownerDocument&&ma(y.ownerDocument.documentElement,y)){null!==s&&ba(y)&&(w=s.start,void 0===(_=s.end)&&(_=w),"selectionStart"in y?(y.selectionStart=w,y.selectionEnd=Math.min(_,y.value.length)):(_=(w=y.ownerDocument||document)&&w.defaultView||window).getSelection&&(_=_.getSelection(),l=y.textContent.length,x=Math.min(s.start,l),s=void 0===s.end?x:Math.min(s.end,l),!_.extend&&x>s&&(l=s,s=x,x=l),l=ga(y,x),o=ga(y,s),l&&o&&(1!==_.rangeCount||_.anchorNode!==l.node||_.anchorOffset!==l.offset||_.focusNode!==o.node||_.focusOffset!==o.offset)&&((w=w.createRange()).setStart(l.node,l.offset),_.removeAllRanges(),x>s?(_.addRange(w),_.extend(o.node,o.offset)):(w.setEnd(o.node,o.offset),_.addRange(w))))),w=[];for(_=y;_=_.parentNode;)1===_.nodeType&&w.push({element:_,left:_.scrollLeft,top:_.scrollTop});for("function"==typeof y.focus&&y.focus(),y=0;y<w.length;y++)(_=w[y]).element.scrollLeft=_.left,_.element.scrollTop=_.top}Kt=!!Ua,za=Ua=null,e.current=n,Ks=a;do{try{for(y=e;null!==Ks;){var k=Ks.flags;if(36&k&&bs(y,Ks.alternate,Ks),128&k){w=void 0;var E=Ks.ref;if(null!==E){var S=Ks.stateNode;Ks.tag,w=S,"function"==typeof E?E(w):E.current=w}}Ks=Ks.nextEffect}}catch(T){if(null===Ks)throw Error(i(330));$l(Ks,T),Ks=Ks.nextEffect}}while(null!==Ks);Ks=null,Br(),js=r}else e.current=n;if(Js)Js=!1,el=e,tl=t;else for(Ks=a;null!==Ks;)t=Ks.nextEffect,Ks.nextEffect=null,8&Ks.flags&&((k=Ks).sibling=null,k.stateNode=null),Ks=t;if(0===(a=e.pendingLanes)&&(Xs=null),1===a?e===il?ol++:(ol=0,il=e):ol=0,n=n.stateNode,Er&&"function"==typeof Er.onCommitFiberRoot)try{Er.onCommitFiberRoot(kr,n,void 0,64==(64&n.current.flags))}catch(T){}if(hl(e,Zr()),Ys)throw Ys=!1,e=Qs,Qs=null,e;return 0!=(8&js)||Gr(),null}function Ml(){for(;null!==Ks;){var e=Ks.alternate;dl||null===ul||(0!=(8&Ks.flags)?et(Ks,ul)&&(dl=!0):13===Ks.tag&&As(e,Ks)&&et(Ks,ul)&&(dl=!0));var t=Ks.flags;0!=(256&t)&&hs(e,Ks),0==(512&t)||Js||(Js=!0,Wr(97,(function(){return Rl(),null}))),Ks=Ks.nextEffect}}function Rl(){if(90!==tl){var e=97<tl?97:tl;return tl=90,qr(e,Bl)}return!1}function Il(e,t){nl.push(t,e),Js||(Js=!0,Wr(97,(function(){return Rl(),null})))}function Dl(e,t){al.push(t,e),Js||(Js=!0,Wr(97,(function(){return Rl(),null})))}function Bl(){if(null===el)return!1;var e=el;if(el=null,0!=(48&js))throw Error(i(331));var t=js;js|=32;var n=al;al=[];for(var a=0;a<n.length;a+=2){var r=n[a],o=n[a+1],s=r.destroy;if(r.destroy=void 0,"function"==typeof s)try{s()}catch(c){if(null===o)throw Error(i(330));$l(o,c)}}for(n=nl,nl=[],a=0;a<n.length;a+=2){r=n[a],o=n[a+1];try{var l=r.create;r.destroy=l()}catch(c){if(null===o)throw Error(i(330));$l(o,c)}}for(l=e.current.firstEffect;null!==l;)e=l.nextEffect,l.nextEffect=null,8&l.flags&&(l.sibling=null,l.stateNode=null),l=e;return js=t,Gr(),!0}function Fl(e,t,n){po(e,t=ps(0,t=cs(n,t),1)),t=pl(),null!==(e=ml(e,1))&&(Zt(e,1,t),hl(e,t))}function $l(e,t){if(3===e.tag)Fl(e,e,t);else for(var n=e.return;null!==n;){if(3===n.tag){Fl(n,e,t);break}if(1===n.tag){var a=n.stateNode;if("function"==typeof n.type.getDerivedStateFromError||"function"==typeof a.componentDidCatch&&(null===Xs||!Xs.has(a))){var r=fs(n,e=cs(t,e),1);if(po(n,r),r=pl(),null!==(n=ml(n,1)))Zt(n,1,r),hl(n,r);else if("function"==typeof a.componentDidCatch&&(null===Xs||!Xs.has(a)))try{a.componentDidCatch(t,e)}catch(o){}break}}n=n.return}}function Ul(e,t,n){var a=e.pingCache;null!==a&&a.delete(t),t=pl(),e.pingedLanes|=e.suspendedLanes&n,Os===e&&(Rs&n)===n&&(4===Bs||3===Bs&&(62914560&Rs)===Rs&&500>Zr()-Vs?El(e,0):Zs|=n),hl(e,t)}function zl(e,t){var n=e.stateNode;null!==n&&n.delete(t),0===(t=0)&&(0==(2&(t=e.mode))?t=1:0==(4&t)?t=99===Hr()?1:2:(0===ll&&(ll=$s),0===(t=Ut(62914560&~ll))&&(t=4194304))),n=pl(),null!==(e=ml(e,t))&&(Zt(e,t,n),hl(e,n))}function Zl(e,t,n,a){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=a,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function Hl(e,t,n,a){return new Zl(e,t,n,a)}function Vl(e){return!(!(e=e.prototype)||!e.isReactComponent)}function ql(e,t){var n=e.alternate;return null===n?((n=Hl(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.nextEffect=null,n.firstEffect=null,n.lastEffect=null),n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Wl(e,t,n,a,r,o){var s=2;if(a=e,"function"==typeof e)Vl(e)&&(s=1);else if("string"==typeof e)s=5;else e:switch(e){case E:return Gl(n.children,r,o,t);case I:s=8,r|=16;break;case S:s=8,r|=1;break;case T:return(e=Hl(12,n,t,8|r)).elementType=T,e.type=T,e.lanes=o,e;case P:return(e=Hl(13,n,t,r)).type=P,e.elementType=P,e.lanes=o,e;case N:return(e=Hl(19,n,t,r)).elementType=N,e.lanes=o,e;case D:return Kl(n,r,o,t);case B:return(e=Hl(24,n,t,r)).elementType=B,e.lanes=o,e;default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case C:s=10;break e;case A:s=9;break e;case L:s=11;break e;case j:s=14;break e;case O:s=16,a=null;break e;case M:s=22;break e}throw Error(i(130,null==e?e:typeof e,""))}return(t=Hl(s,n,t,r)).elementType=e,t.type=a,t.lanes=o,t}function Gl(e,t,n,a){return(e=Hl(7,e,a,t)).lanes=n,e}function Kl(e,t,n,a){return(e=Hl(23,e,a,t)).elementType=D,e.lanes=n,e}function Yl(e,t,n){return(e=Hl(6,e,null,t)).lanes=n,e}function Ql(e,t,n){return(t=Hl(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Xl(e,t,n){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=n,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=zt(0),this.expirationTimes=zt(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=zt(0),this.mutableSourceEagerHydrationData=null}function Jl(e,t,n){var a=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:k,key:null==a?null:""+a,children:e,containerInfo:t,implementation:n}}function ec(e,t,n,a){var r=t.current,o=pl(),s=fl(r);e:if(n){t:{if(Ye(n=n._reactInternals)!==n||1!==n.tag)throw Error(i(170));var l=n;do{switch(l.tag){case 3:l=l.stateNode.context;break t;case 1:if(br(l.type)){l=l.stateNode.__reactInternalMemoizedMergedChildContext;break t}}l=l.return}while(null!==l);throw Error(i(171))}if(1===n.tag){var c=n.type;if(br(c)){n=wr(n,c,l);break e}}n=l}else n=pr;return null===t.context?t.context=n:t.pendingContext=n,(t=uo(o,s)).payload={element:e},null!==(a=void 0===a?null:a)&&(t.callback=a),po(r,t),gl(r,s,o),s}function tc(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function nc(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function ac(e,t){nc(e,t),(e=e.alternate)&&nc(e,t)}function rc(e,t,n){var a=null!=n&&null!=n.hydrationOptions&&n.hydrationOptions.mutableSources||null;if(n=new Xl(e,t,null!=n&&!0===n.hydrate),t=Hl(3,null,null,2===t?7:1===t?3:0),n.current=t,t.stateNode=n,lo(t),e[er]=n.current,ja(8===e.nodeType?e.parentNode:e),a)for(e=0;e<a.length;e++){var r=(t=a[e])._getVersion;r=r(t._source),null==n.mutableSourceEagerHydrationData?n.mutableSourceEagerHydrationData=[t,r]:n.mutableSourceEagerHydrationData.push(t,r)}this._internalRoot=n}function oc(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function ic(e,t,n,a,r){var o=n._reactRootContainer;if(o){var i=o._internalRoot;if("function"==typeof r){var s=r;r=function(){var e=tc(i);s.call(e)}}ec(t,i,e,r)}else{if(o=n._reactRootContainer=function(e,t){if(t||(t=!(!(t=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==t.nodeType||!t.hasAttribute("data-reactroot"))),!t)for(var n;n=e.lastChild;)e.removeChild(n);return new rc(e,0,t?{hydrate:!0}:void 0)}(n,a),i=o._internalRoot,"function"==typeof r){var l=r;r=function(){var e=tc(i);l.call(e)}}_l((function(){ec(t,i,e,r)}))}return tc(i)}function sc(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!oc(t))throw Error(i(200));return Jl(e,t,null,n)}Gs=function(e,t,n){var a=t.lanes;if(null!==e)if(e.memoizedProps!==t.pendingProps||gr.current)Di=!0;else{if(0==(n&a)){switch(Di=!1,t.tag){case 3:Wi(t),Go();break;case 5:Io(t);break;case 1:br(t.type)&&_r(t);break;case 4:Mo(t,t.stateNode.containerInfo);break;case 10:a=t.memoizedProps.value;var r=t.type._context;dr(Xr,r._currentValue),r._currentValue=a;break;case 13:if(null!==t.memoizedState)return 0!=(n&t.child.childLanes)?Xi(e,t,n):(dr(Bo,1&Bo.current),null!==(t=os(e,t,n))?t.sibling:null);dr(Bo,1&Bo.current);break;case 19:if(a=0!=(n&t.childLanes),0!=(64&e.flags)){if(a)return rs(e,t,n);t.flags|=64}if(null!==(r=t.memoizedState)&&(r.rendering=null,r.tail=null,r.lastEffect=null),dr(Bo,Bo.current),a)break;return null;case 23:case 24:return t.lanes=0,zi(e,t,n)}return os(e,t,n)}Di=0!=(16384&e.flags)}else Di=!1;switch(t.lanes=0,t.tag){case 2:if(a=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,r=hr(t,fr.current),oo(t,n),r=si(null,t,a,e,r,n),t.flags|=1,"object"==typeof r&&null!==r&&"function"==typeof r.render&&void 0===r.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,br(a)){var o=!0;_r(t)}else o=!1;t.memoizedState=null!==r.state&&void 0!==r.state?r.state:null,lo(t);var s=a.getDerivedStateFromProps;"function"==typeof s&&bo(t,a,s,e),r.updater=vo,t.stateNode=r,r._reactInternals=t,xo(t,a,e,n),t=qi(null,t,a,!0,o,n)}else t.tag=0,Bi(null,t,r,n),t=t.child;return t;case 16:r=t.elementType;e:{switch(null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),e=t.pendingProps,r=(o=r._init)(r._payload),t.type=r,o=t.tag=function(e){if("function"==typeof e)return Vl(e)?1:0;if(null!=e){if((e=e.$$typeof)===L)return 11;if(e===j)return 14}return 2}(r),e=Qr(r,e),o){case 0:t=Hi(null,t,r,e,n);break e;case 1:t=Vi(null,t,r,e,n);break e;case 11:t=Fi(null,t,r,e,n);break e;case 14:t=$i(null,t,r,Qr(r.type,e),a,n);break e}throw Error(i(306,r,""))}return t;case 0:return a=t.type,r=t.pendingProps,Hi(e,t,a,r=t.elementType===a?r:Qr(a,r),n);case 1:return a=t.type,r=t.pendingProps,Vi(e,t,a,r=t.elementType===a?r:Qr(a,r),n);case 3:if(Wi(t),a=t.updateQueue,null===e||null===a)throw Error(i(282));if(a=t.pendingProps,r=null!==(r=t.memoizedState)?r.element:null,co(e,t),go(t,a,null,n),(a=t.memoizedState.element)===r)Go(),t=os(e,t,n);else{if((o=(r=t.stateNode).hydrate)&&(Uo=Ga(t.stateNode.containerInfo.firstChild),$o=t,o=zo=!0),o){if(null!=(e=r.mutableSourceEagerHydrationData))for(r=0;r<e.length;r+=2)(o=e[r])._workInProgressVersionPrimary=e[r+1],Ko.push(o);for(n=Ao(t,null,a,n),t.child=n;n;)n.flags=-3&n.flags|1024,n=n.sibling}else Bi(e,t,a,n),Go();t=t.child}return t;case 5:return Io(t),null===e&&Vo(t),a=t.type,r=t.pendingProps,o=null!==e?e.memoizedProps:null,s=r.children,Ha(a,r)?s=null:null!==o&&Ha(a,o)&&(t.flags|=16),Zi(e,t),Bi(e,t,s,n),t.child;case 6:return null===e&&Vo(t),null;case 13:return Xi(e,t,n);case 4:return Mo(t,t.stateNode.containerInfo),a=t.pendingProps,null===e?t.child=Co(t,null,a,n):Bi(e,t,a,n),t.child;case 11:return a=t.type,r=t.pendingProps,Fi(e,t,a,r=t.elementType===a?r:Qr(a,r),n);case 7:return Bi(e,t,t.pendingProps,n),t.child;case 8:case 12:return Bi(e,t,t.pendingProps.children,n),t.child;case 10:e:{a=t.type._context,r=t.pendingProps,s=t.memoizedProps,o=r.value;var l=t.type._context;if(dr(Xr,l._currentValue),l._currentValue=o,null!==s)if(l=s.value,0===(o=ua(l,o)?0:0|("function"==typeof a._calculateChangedBits?a._calculateChangedBits(l,o):1073741823))){if(s.children===r.children&&!gr.current){t=os(e,t,n);break e}}else for(null!==(l=t.child)&&(l.return=t);null!==l;){var c=l.dependencies;if(null!==c){s=l.child;for(var u=c.firstContext;null!==u;){if(u.context===a&&0!=(u.observedBits&o)){1===l.tag&&((u=uo(-1,n&-n)).tag=2,po(l,u)),l.lanes|=n,null!==(u=l.alternate)&&(u.lanes|=n),ro(l.return,n),c.lanes|=n;break}u=u.next}}else s=10===l.tag&&l.type===t.type?null:l.child;if(null!==s)s.return=l;else for(s=l;null!==s;){if(s===t){s=null;break}if(null!==(l=s.sibling)){l.return=s.return,s=l;break}s=s.return}l=s}Bi(e,t,r.children,n),t=t.child}return t;case 9:return r=t.type,a=(o=t.pendingProps).children,oo(t,n),a=a(r=io(r,o.unstable_observedBits)),t.flags|=1,Bi(e,t,a,n),t.child;case 14:return o=Qr(r=t.type,t.pendingProps),$i(e,t,r,o=Qr(r.type,o),a,n);case 15:return Ui(e,t,t.type,t.pendingProps,a,n);case 17:return a=t.type,r=t.pendingProps,r=t.elementType===a?r:Qr(a,r),null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2),t.tag=1,br(a)?(e=!0,_r(t)):e=!1,oo(t,n),wo(t,a,r),xo(t,a,r,n),qi(null,t,a,!0,e,n);case 19:return rs(e,t,n);case 23:case 24:return zi(e,t,n)}throw Error(i(156,t.tag))},rc.prototype.render=function(e){ec(e,this._internalRoot,null,null)},rc.prototype.unmount=function(){var e=this._internalRoot,t=e.containerInfo;ec(null,e,null,(function(){t[er]=null}))},tt=function(e){13===e.tag&&(gl(e,4,pl()),ac(e,4))},nt=function(e){13===e.tag&&(gl(e,67108864,pl()),ac(e,67108864))},at=function(e){if(13===e.tag){var t=pl(),n=fl(e);gl(e,n,t),ac(e,n)}},rt=function(e,t){return t()},Ce=function(e,t,n){switch(t){case"input":if(ne(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var a=n[t];if(a!==e&&a.form===e.form){var r=or(a);if(!r)throw Error(i(90));Q(a),ne(a,r)}}}break;case"textarea":ce(e,n);break;case"select":null!=(t=n.value)&&ie(e,!!n.multiple,t,!1)}},Oe=wl,Me=function(e,t,n,a,r){var o=js;js|=4;try{return qr(98,e.bind(null,t,n,a,r))}finally{0===(js=o)&&(Ws(),Gr())}},Re=function(){0==(49&js)&&(function(){if(null!==rl){var e=rl;rl=null,e.forEach((function(e){e.expiredLanes|=24&e.pendingLanes,hl(e,Zr())}))}Gr()}(),Rl())},Ie=function(e,t){var n=js;js|=2;try{return e(t)}finally{0===(js=n)&&(Ws(),Gr())}};var lc={Events:[ar,rr,or,Ne,je,Rl,{current:!1}]},cc={findFiberByHostInstance:nr,bundleType:0,version:"17.0.2",rendererPackageName:"react-dom"},uc={bundleType:cc.bundleType,version:cc.version,rendererPackageName:cc.rendererPackageName,rendererConfig:cc.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:_.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Je(e))?null:e.stateNode},findFiberByHostInstance:cc.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var dc=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!dc.isDisabled&&dc.supportsFiber)try{kr=dc.inject(uc),Er=dc}catch(he){}}t.createPortal=sc,t.hydrate=function(e,t,n){if(!oc(t))throw Error(i(200));return ic(null,e,t,!0,n)}},73935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(64448)},69590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,a="function"==typeof Set,r="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var s,l,c,u;if(Array.isArray(e)){if((s=e.length)!=i.length)return!1;for(l=s;0!=l--;)if(!o(e[l],i[l]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!i.has(l.value[0]))return!1;for(u=e.entries();!(l=u.next()).done;)if(!o(l.value[1],i.get(l.value[0])))return!1;return!0}if(a&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!i.has(l.value[0]))return!1;return!0}if(r&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((s=e.length)!=i.length)return!1;for(l=s;0!=l--;)if(e[l]!==i[l])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===i.toString();if((s=(c=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(l=s;0!=l--;)if(!Object.prototype.hasOwnProperty.call(i,c[l]))return!1;if(t&&e instanceof Element)return!1;for(l=s;0!=l--;)if(("_owner"!==c[l]&&"__v"!==c[l]&&"__o"!==c[l]||!e.$$typeof)&&!o(e[c[l]],i[c[l]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},70405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>V,ql:()=>J});var a=n(67294),r=n(45697),o=n.n(r),i=n(69590),s=n.n(i),l=n(41143),c=n.n(l),u=n(96774),d=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},p.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,g(e,t)}function g(e,t){return g=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},g(e,t)}function m(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)t.indexOf(n=o[a])>=0||(r[n]=e[n]);return r}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},v={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(h).map((function(e){return h[e]})),_={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},x=Object.keys(_).reduce((function(e,t){return e[_[t]]=t,e}),{}),k=function(e,t){for(var n=e.length-1;n>=0;n-=1){var a=e[n];if(Object.prototype.hasOwnProperty.call(a,t))return a[t]}return null},E=function(e){var t=k(e,h.TITLE),n=k(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var a=k(e,"defaultTitle");return t||a||void 0},S=function(e){return k(e,"onChangeClientState")||function(){}},T=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},C=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var a=Object.keys(n),r=0;r<a.length;r+=1){var o=a[r].toLowerCase();if(-1!==e.indexOf(o)&&n[o])return t.concat(n)}return t}),[])},A=function(e,t,n){var a={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var r={};n.filter((function(e){for(var n,o=Object.keys(e),i=0;i<o.length;i+=1){var s=o[i],l=s.toLowerCase();-1===t.indexOf(l)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===l&&"stylesheet"===e[l].toLowerCase()||(n=l),-1===t.indexOf(s)||"innerHTML"!==s&&"cssText"!==s&&"itemprop"!==s||(n=s)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return a[n]||(a[n]={}),r[n]||(r[n]={}),!a[n][c]&&(r[n][c]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var o=Object.keys(r),i=0;i<o.length;i+=1){var s=o[i],l=p({},a[s],r[s]);a[s]=l}return e}),[]).reverse()},L=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},P=function(e){return Array.isArray(e)?e.join(""):e},N=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),a=0;a<n.length;a+=1)if(t[n[a]]&&t[n[a]].includes(e[n[a]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},j=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},O=[h.NOSCRIPT,h.SCRIPT,h.STYLE],M=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},R=function(e){return Object.keys(e).reduce((function(t,n){var a=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+a:a}),"")},I=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[_[n]||n]=e[n],t}),t)},D=function(e,t){return t.map((function(t,n){var r,o=((r={key:n})["data-rh"]=!0,r);return Object.keys(t).forEach((function(e){var n=_[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),a.createElement(e,o)}))},B=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(r={key:e=t.title})["data-rh"]=!0,o=I(n,r),[a.createElement(h.TITLE,o,e)];var e,n,r,o},toString:function(){return function(e,t,n,a){var r=R(n),o=P(t);return r?"<"+e+' data-rh="true" '+r+">"+M(o,a)+"</"+e+">":"<"+e+' data-rh="true">'+M(o,a)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return I(t)},toString:function(){return R(t)}};default:return{toComponent:function(){return D(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,a){var r=Object.keys(a).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var r=void 0===a[t]?t:t+'="'+M(a[t],n)+'"';return e?e+" "+r:r}),""),o=a.innerHTML||a.cssText||"",i=-1===O.indexOf(e);return t+"<"+e+' data-rh="true" '+r+(i?"/>":">"+o+"</"+e+">")}),"")}(e,t,n)}}}},F=function(e){var t=e.baseTag,n=e.bodyAttributes,a=e.encode,r=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,s=e.title,l=void 0===s?"":s,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var g=function(e){var t=e.linkTags,n=e.scriptTags,a=e.encode,r=N(e.metaTags,y),o=N(t,b),i=N(n,v);return{priorityMethods:{toComponent:function(){return[].concat(D(h.META,r.priority),D(h.LINK,o.priority),D(h.SCRIPT,i.priority))},toString:function(){return B(h.META,r.priority,a)+" "+B(h.LINK,o.priority,a)+" "+B(h.SCRIPT,i.priority,a)}},metaTags:r.default,linkTags:o.default,scriptTags:i.default}}(e);f=g.priorityMethods,u=g.linkTags,d=g.metaTags,p=g.scriptTags}return{priority:f,base:B(h.BASE,t,a),bodyAttributes:B("bodyAttributes",n,a),htmlAttributes:B("htmlAttributes",r,a),link:B(h.LINK,u,a),meta:B(h.META,d,a),noscript:B(h.NOSCRIPT,o,a),script:B(h.SCRIPT,p,a),style:B(h.STYLE,i,a),title:B(h.TITLE,{title:l,titleAttributes:c},a)}},$=[],U=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?$:n.instances},add:function(e){(n.canUseDOM?$:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?$:n.instances).indexOf(e);(n.canUseDOM?$:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=F({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},z=a.createContext({}),Z=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),H="undefined"!=typeof document,V=function(e){function t(n){var a;return(a=e.call(this,n)||this).helmetData=new U(a.props.context,t.canUseDOM),a}return f(t,e),t.prototype.render=function(){return a.createElement(z.Provider,{value:this.helmetData.value},this.props.children)},t}(a.Component);V.canUseDOM=H,V.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},V.defaultProps={context:{}},V.displayName="HelmetProvider";var q=function(e,t){var n,a=document.head||document.querySelector(h.HEAD),r=a.querySelectorAll(e+"[data-rh]"),o=[].slice.call(r),i=[];return t&&t.length&&t.forEach((function(t){var a=document.createElement(e);for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&("innerHTML"===r?a.innerHTML=t.innerHTML:"cssText"===r?a.styleSheet?a.styleSheet.cssText=t.cssText:a.appendChild(document.createTextNode(t.cssText)):a.setAttribute(r,void 0===t[r]?"":t[r]));a.setAttribute("data-rh","true"),o.some((function(e,t){return n=t,a.isEqualNode(e)}))?o.splice(n,1):i.push(a)})),o.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return a.appendChild(e)})),{oldTags:o,newTags:i}},W=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var a=n.getAttribute("data-rh"),r=a?a.split(","):[],o=[].concat(r),i=Object.keys(t),s=0;s<i.length;s+=1){var l=i[s],c=t[l]||"";n.getAttribute(l)!==c&&n.setAttribute(l,c),-1===r.indexOf(l)&&r.push(l);var u=o.indexOf(l);-1!==u&&o.splice(u,1)}for(var d=o.length-1;d>=0;d-=1)n.removeAttribute(o[d]);r.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},G=function(e,t){var n=e.baseTag,a=e.htmlAttributes,r=e.linkTags,o=e.metaTags,i=e.noscriptTags,s=e.onChangeClientState,l=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;W(h.BODY,e.bodyAttributes),W(h.HTML,a),function(e,t){void 0!==e&&document.title!==e&&(document.title=P(e)),W(h.TITLE,t)}(u,d);var p={baseTag:q(h.BASE,n),linkTags:q(h.LINK,r),metaTags:q(h.META,o),noscriptTags:q(h.NOSCRIPT,i),scriptTags:q(h.SCRIPT,l),styleTags:q(h.STYLE,c)},f={},g={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,a=t.oldTags;n.length&&(f[e]=n),a.length&&(g[e]=p[e].oldTags)})),t&&t(),s(e,f,g)},K=null,Y=function(e){function t(){for(var t,n=arguments.length,a=new Array(n),r=0;r<n;r++)a[r]=arguments[r];return(t=e.call.apply(e,[this].concat(a))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,a=n.setHelmet,r=null,o=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:C(["href"],e),bodyAttributes:T("bodyAttributes",e),defer:k(e,"defer"),encode:k(e,"encodeSpecialCharacters"),htmlAttributes:T("htmlAttributes",e),linkTags:A(h.LINK,["rel","href"],e),metaTags:A(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:A(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:S(e),scriptTags:A(h.SCRIPT,["src","innerHTML"],e),styleTags:A(h.STYLE,["cssText"],e),title:E(e),titleAttributes:T("titleAttributes",e),prioritizeSeoTags:L(e,"prioritizeSeoTags")});V.canUseDOM?(t=o,K&&cancelAnimationFrame(K),t.defer?K=requestAnimationFrame((function(){G(t,(function(){K=null}))})):(G(t),K=null)):F&&(r=F(o)),a(r)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(a.Component);Y.propTypes={context:Z.isRequired},Y.displayName="HelmetDispatcher";var Q=["children"],X=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!s()(j(this.props,"helmetData"),j(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,a=e.arrayTypeChildren;return p({},a,((t={})[n.type]=[].concat(a[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,a=e.child,r=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(a.type){case h.TITLE:return p({},r,((t={})[a.type]=i,t.titleAttributes=p({},o),t));case h.BODY:return p({},r,{bodyAttributes:p({},o)});case h.HTML:return p({},r,{htmlAttributes:p({},o)});default:return p({},r,((n={})[a.type]=p({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var a;n=p({},n,((a={})[t]=e[t],a))})),n},n.warnOnInvalidChildren=function(e,t){return c()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,r={};return a.Children.forEach(e,(function(e){if(e&&e.props){var a=e.props,o=a.children,i=m(a,Q),s=Object.keys(i).reduce((function(e,t){return e[x[t]||t]=i[t],e}),{}),l=e.type;switch("symbol"==typeof l?l=l.toString():n.warnOnInvalidChildren(e,o),l){case h.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:r=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:r,newChildProps:s,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:s,nestedChildren:o})}}})),this.mapArrayTypeChildrenToProps(r,t)},n.render=function(){var e=this.props,t=e.children,n=m(e,X),r=p({},n),o=n.helmetData;return t&&(r=this.mapChildrenToProps(t,r)),!o||o instanceof U||(o=new U(o.context,o.instances)),o?a.createElement(Y,p({},r,{context:o.value,helmetData:void 0})):a.createElement(z.Consumer,null,(function(e){return a.createElement(Y,p({},r,{context:e}))}))},t}(a.Component);J.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},69921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,a=n?Symbol.for("react.element"):60103,r=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,s=n?Symbol.for("react.profiler"):60114,l=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,g=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,v=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function _(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case a:switch(e=e.type){case u:case d:case o:case s:case i:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case h:case m:case l:return e;default:return t}}case r:return t}}}function x(e){return _(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=l,t.Element=a,t.ForwardRef=p,t.Fragment=o,t.Lazy=h,t.Memo=m,t.Portal=r,t.Profiler=s,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return x(e)||_(e)===u},t.isConcurrentMode=x,t.isContextConsumer=function(e){return _(e)===c},t.isContextProvider=function(e){return _(e)===l},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===a},t.isForwardRef=function(e){return _(e)===p},t.isFragment=function(e){return _(e)===o},t.isLazy=function(e){return _(e)===h},t.isMemo=function(e){return _(e)===m},t.isPortal=function(e){return _(e)===r},t.isProfiler=function(e){return _(e)===s},t.isStrictMode=function(e){return _(e)===i},t.isSuspense=function(e){return _(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===d||e===s||e===i||e===f||e===g||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===m||e.$$typeof===l||e.$$typeof===c||e.$$typeof===p||e.$$typeof===v||e.$$typeof===y||e.$$typeof===w||e.$$typeof===b)},t.typeOf=_},59864:(e,t,n)=>{"use strict";e.exports=n(69921)},68356:(e,t,n)=>{"use strict";function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},i.apply(this,arguments)}var s=n(67294),l=n(45697),c=[],u=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(a){var r=d(e[a]);r.loading?t.loading=!0:(t.loaded[a]=r.loaded,t.error=r.error),n.push(r.promise),r.promise.then((function(e){t.loaded[a]=e})).catch((function(e){t.error=e}))}))}catch(a){t.error=a}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return s.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function g(e,t){var d,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var g=i({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),m=null;function h(){return m||(m=e(g.loader)),m.promise}return c.push(h),"function"==typeof g.webpack&&u.push((function(){if((0,g.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),p=d=function(t){function n(n){var a;return o(r(r(a=t.call(this,n)||this)),"retry",(function(){a.setState({error:null,loading:!0,timedOut:!1}),m=e(g.loader),a._loadModule()})),h(),a.state={error:m.error,pastDelay:!1,timedOut:!1,loading:m.loading,loaded:m.loaded},a}a(n,t),n.preload=function(){return h()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(g.modules)&&g.modules.forEach((function(t){e.context.loadable.report(t)})),m.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof g.delay&&(0===g.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),g.delay)),"number"==typeof g.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),g.timeout));var n=function(){t({error:m.error,loaded:m.loaded,loading:m.loading}),e._clearTimeouts()};m.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?s.createElement(g.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?g.render(this.state.loaded,this.props):null},n}(s.Component),o(d,"contextTypes",{loadable:l.shape({report:l.func.isRequired})}),p}function m(e){return g(d,e)}m.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return g(p,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}a(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return s.Children.only(this.props.children)},t}(s.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}o(h,"propTypes",{report:l.func.isRequired}),o(h,"childContextTypes",{loadable:l.shape({report:l.func.isRequired}).isRequired}),m.Capture=h,m.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},m.preloadReady=function(){return new Promise((function(e,t){b(u).then(e,e)}))},e.exports=m},18790:(e,t,n)=>{"use strict";n.d(t,{H:()=>s,f:()=>i});var a=n(16550),r=n(87462),o=n(67294);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var r=e.path?(0,a.LX)(t,e):n.length?n[n.length-1].match:a.F0.computeRootMatch(t);return r&&(n.push({route:e,match:r}),e.routes&&i(e.routes,t,n)),r})),n}function s(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?o.createElement(a.rs,n,e.map((function(e,n){return o.createElement(a.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,r.Z)({},n,{},t,{route:e})):o.createElement(e.component,(0,r.Z)({},n,t,{route:e}))}})}))):null}},73727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>y,VK:()=>u,rU:()=>h});var a=n(16550),r=n(75068),o=n(67294),i=n(42358),s=n(87462),l=n(63366),c=n(38776),u=function(e){function t(){for(var t,n=arguments.length,a=new Array(n),r=0;r<n;r++)a[r]=arguments[r];return(t=e.call.apply(e,[this].concat(a))||this).history=(0,i.lX)(t.props),t}return(0,r.Z)(t,e),t.prototype.render=function(){return o.createElement(a.F0,{history:this.history,children:this.props.children})},t}(o.Component);o.Component;var d=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,i.ob)(e,null,null,t):e},f=function(e){return e},g=o.forwardRef;void 0===g&&(g=f);var m=g((function(e,t){var n=e.innerRef,a=e.navigate,r=e.onClick,i=(0,l.Z)(e,["innerRef","navigate","onClick"]),c=i.target,u=(0,s.Z)({},i,{onClick:function(e){try{r&&r(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),a())}});return u.ref=f!==g&&t||n,o.createElement("a",u)}));var h=g((function(e,t){var n=e.component,r=void 0===n?m:n,u=e.replace,h=e.to,b=e.innerRef,v=(0,l.Z)(e,["component","replace","to","innerRef"]);return o.createElement(a.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=e.history,a=p(d(h,e.location),e.location),l=a?n.createHref(a):"",m=(0,s.Z)({},v,{href:l,navigate:function(){var t=d(h,e.location),a=(0,i.Ep)(e.location)===(0,i.Ep)(p(t));(u||a?n.replace:n.push)(t)}});return f!==g?m.ref=t||b:m.innerRef=b,o.createElement(r,m)}))})),b=function(e){return e},v=o.forwardRef;void 0===v&&(v=b);var y=v((function(e,t){var n=e["aria-current"],r=void 0===n?"page":n,i=e.activeClassName,u=void 0===i?"active":i,f=e.activeStyle,g=e.className,m=e.exact,y=e.isActive,w=e.location,_=e.sensitive,x=e.strict,k=e.style,E=e.to,S=e.innerRef,T=(0,l.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return o.createElement(a.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=w||e.location,i=p(d(E,n),n),l=i.pathname,C=l&&l.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),A=C?(0,a.LX)(n.pathname,{path:C,exact:m,sensitive:_,strict:x}):null,L=!!(y?y(A,n):A),P="function"==typeof g?g(L):g,N="function"==typeof k?k(L):k;L&&(P=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(P,u),N=(0,s.Z)({},N,f));var j=(0,s.Z)({"aria-current":L&&r||null,className:P,style:N,to:i},T);return b!==v?j.ref=t||S:j.innerRef=S,o.createElement(h,j)}))}))},16550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>L,F0:()=>w,LX:()=>A,TH:()=>B,k6:()=>D,l_:()=>S,rs:()=>R,s6:()=>y});var a=n(75068),r=n(67294),o=n(45697),i=n.n(o),s=n(42358),l=n(38776),c=n(87462),u=n(39658),d=n.n(u),p=(n(59864),n(63366)),f=(n(8679),1073741823),g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};function m(e){var t=[];return{on:function(e){t.push(e)},off:function(e){t=t.filter((function(t){return t!==e}))},get:function(){return e},set:function(n,a){e=n,t.forEach((function(t){return t(e,a)}))}}}var h=r.createContext||function(e,t){var n,o,s="__create-react-context-"+function(){var e="__global_unique_id__";return g[e]=(g[e]||0)+1}()+"__",l=function(e){function n(){for(var t,n=arguments.length,a=new Array(n),r=0;r<n;r++)a[r]=arguments[r];return(t=e.call.apply(e,[this].concat(a))||this).emitter=m(t.props.value),t}(0,a.Z)(n,e);var r=n.prototype;return r.getChildContext=function(){var e;return(e={})[s]=this.emitter,e},r.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,a=this.props.value,r=e.value;((o=a)===(i=r)?0!==o||1/o==1/i:o!=o&&i!=i)?n=0:(n="function"==typeof t?t(a,r):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var o,i},r.render=function(){return this.props.children},n}(r.Component);l.childContextTypes=((n={})[s]=i().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,a=new Array(n),r=0;r<n;r++)a[r]=arguments[r];return(e=t.call.apply(t,[this].concat(a))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,a.Z)(n,t);var r=n.prototype;return r.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},r.componentDidMount=function(){this.context[s]&&this.context[s].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},r.componentWillUnmount=function(){this.context[s]&&this.context[s].off(this.onUpdate)},r.getValue=function(){return this.context[s]?this.context[s].get():e},r.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(r.Component);return c.contextTypes=((o={})[s]=i().object,o),{Provider:l,Consumer:c}},b=function(e){var t=h();return t.displayName=e,t},v=b("Router-History"),y=b("Router"),w=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,a.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return r.createElement(y.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},r.createElement(v.Provider,{children:this.props.children||null,value:this.props.history}))},t}(r.Component);r.Component;var _=function(e){function t(){return e.apply(this,arguments)||this}(0,a.Z)(t,e);var n=t.prototype;return n.componentDidMount=function(){this.props.onMount&&this.props.onMount.call(this,this)},n.componentDidUpdate=function(e){this.props.onUpdate&&this.props.onUpdate.call(this,this,e)},n.componentWillUnmount=function(){this.props.onUnmount&&this.props.onUnmount.call(this,this)},n.render=function(){return null},t}(r.Component);var x={},k=0;function E(e,t){return void 0===e&&(e="/"),void 0===t&&(t={}),"/"===e?e:function(e){if(x[e])return x[e];var t=d().compile(e);return k<1e4&&(x[e]=t,k++),t}(e)(t,{pretty:!0})}function S(e){var t=e.computedMatch,n=e.to,a=e.push,o=void 0!==a&&a;return r.createElement(y.Consumer,null,(function(e){e||(0,l.Z)(!1);var a=e.history,i=e.staticContext,u=o?a.push:a.replace,d=(0,s.ob)(t?"string"==typeof n?E(n,t.params):(0,c.Z)({},n,{pathname:E(n.pathname,t.params)}):n);return i?(u(d),null):r.createElement(_,{onMount:function(){u(d)},onUpdate:function(e,t){var n=(0,s.ob)(t.to);(0,s.Hp)(n,(0,c.Z)({},d,{key:n.key}))||u(d)},to:n})}))}var T={},C=0;function A(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,a=n.path,r=n.exact,o=void 0!==r&&r,i=n.strict,s=void 0!==i&&i,l=n.sensitive,c=void 0!==l&&l;return[].concat(a).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var a=function(e,t){var n=""+t.end+t.strict+t.sensitive,a=T[n]||(T[n]={});if(a[e])return a[e];var r=[],o={regexp:d()(e,r,t),keys:r};return C<1e4&&(a[e]=o,C++),o}(n,{end:o,strict:s,sensitive:c}),r=a.regexp,i=a.keys,l=r.exec(e);if(!l)return null;var u=l[0],p=l.slice(1),f=e===u;return o&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:i.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var L=function(e){function t(){return e.apply(this,arguments)||this}return(0,a.Z)(t,e),t.prototype.render=function(){var e=this;return r.createElement(y.Consumer,null,(function(t){t||(0,l.Z)(!1);var n=e.props.location||t.location,a=e.props.computedMatch?e.props.computedMatch:e.props.path?A(n.pathname,e.props):t.match,o=(0,c.Z)({},t,{location:n,match:a}),i=e.props,s=i.children,u=i.component,d=i.render;return Array.isArray(s)&&function(e){return 0===r.Children.count(e)}(s)&&(s=null),r.createElement(y.Provider,{value:o},o.match?s?"function"==typeof s?s(o):s:u?r.createElement(u,o):d?d(o):null:"function"==typeof s?s(o):null)}))},t}(r.Component);function P(e){return"/"===e.charAt(0)?e:"/"+e}function N(e,t){if(!e)return t;var n=P(e);return 0!==t.pathname.indexOf(n)?t:(0,c.Z)({},t,{pathname:t.pathname.substr(n.length)})}function j(e){return"string"==typeof e?e:(0,s.Ep)(e)}function O(e){return function(){(0,l.Z)(!1)}}function M(){}r.Component;var R=function(e){function t(){return e.apply(this,arguments)||this}return(0,a.Z)(t,e),t.prototype.render=function(){var e=this;return r.createElement(y.Consumer,null,(function(t){t||(0,l.Z)(!1);var n,a,o=e.props.location||t.location;return r.Children.forEach(e.props.children,(function(e){if(null==a&&r.isValidElement(e)){n=e;var i=e.props.path||e.props.from;a=i?A(o.pathname,(0,c.Z)({},e.props,{path:i})):t.match}})),a?r.cloneElement(n,{location:o,computedMatch:a}):null}))},t}(r.Component);var I=r.useContext;function D(){return I(v)}function B(){return I(y).location}},39658:(e,t,n)=>{var a=n(5826);e.exports=f,e.exports.parse=o,e.exports.compile=function(e,t){return s(o(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=p;var r=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,a=[],o=0,i=0,s="",u=t&&t.delimiter||"/";null!=(n=r.exec(e));){var d=n[0],p=n[1],f=n.index;if(s+=e.slice(i,f),i=f+d.length,p)s+=p[1];else{var g=e[i],m=n[2],h=n[3],b=n[4],v=n[5],y=n[6],w=n[7];s&&(a.push(s),s="");var _=null!=m&&null!=g&&g!==m,x="+"===y||"*"===y,k="?"===y||"*"===y,E=n[2]||u,S=b||v;a.push({name:h||o++,prefix:m||"",delimiter:E,optional:k,repeat:x,partial:_,asterisk:!!w,pattern:S?c(S):w?".*":"[^"+l(E)+"]+?"})}}return i<e.length&&(s+=e.substr(i)),s&&a.push(s),a}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function s(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++)"object"==typeof e[r]&&(n[r]=new RegExp("^(?:"+e[r].pattern+")$",d(t)));return function(t,r){for(var o="",s=t||{},l=(r||{}).pretty?i:encodeURIComponent,c=0;c<e.length;c++){var u=e[c];if("string"!=typeof u){var d,p=s[u.name];if(null==p){if(u.optional){u.partial&&(o+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(a(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var f=0;f<p.length;f++){if(d=l(p[f]),!n[c].test(d))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(d)+"`");o+=(0===f?u.prefix:u.delimiter)+d}}else{if(d=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):l(p),!n[c].test(d))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+d+'"');o+=u.prefix+d}}else o+=u}return o}}function l(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function p(e,t,n){a(t)||(n=t||n,t=[]);for(var r=(n=n||{}).strict,o=!1!==n.end,i="",s=0;s<e.length;s++){var c=e[s];if("string"==typeof c)i+=l(c);else{var p=l(c.prefix),f="(?:"+c.pattern+")";t.push(c),c.repeat&&(f+="(?:"+p+f+")*"),i+=f=c.optional?c.partial?p+"("+f+")?":"(?:"+p+"("+f+"))?":p+"("+f+")"}}var g=l(n.delimiter||"/"),m=i.slice(-g.length)===g;return r||(i=(m?i.slice(0,-g.length):i)+"(?:"+g+"(?=$))?"),i+=o?"$":r&&m?"":"(?="+g+"|$)",u(new RegExp("^"+i,d(n)),t)}function f(e,t,n){return a(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var a=0;a<n.length;a++)t.push({name:a,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):a(e)?function(e,t,n){for(var a=[],r=0;r<e.length;r++)a.push(f(e[r],t,n).source);return u(new RegExp("(?:"+a.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return p(o(e,n),t,n)}(e,t,n)}},72408:(e,t,n)=>{"use strict";var a=n(27418),r=60103,o=60106;t.Fragment=60107,t.StrictMode=60108,t.Profiler=60114;var i=60109,s=60110,l=60112;t.Suspense=60113;var c=60115,u=60116;if("function"==typeof Symbol&&Symbol.for){var d=Symbol.for;r=d("react.element"),o=d("react.portal"),t.Fragment=d("react.fragment"),t.StrictMode=d("react.strict_mode"),t.Profiler=d("react.profiler"),i=d("react.provider"),s=d("react.context"),l=d("react.forward_ref"),t.Suspense=d("react.suspense"),c=d("react.memo"),u=d("react.lazy")}var p="function"==typeof Symbol&&Symbol.iterator;function f(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},m={};function h(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||g}function b(){}function v(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||g}h.prototype.isReactComponent={},h.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(f(85));this.updater.enqueueSetState(this,e,t,"setState")},h.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=h.prototype;var y=v.prototype=new b;y.constructor=v,a(y,h.prototype),y.isPureReactComponent=!0;var w={current:null},_=Object.prototype.hasOwnProperty,x={key:!0,ref:!0,__self:!0,__source:!0};function k(e,t,n){var a,o={},i=null,s=null;if(null!=t)for(a in void 0!==t.ref&&(s=t.ref),void 0!==t.key&&(i=""+t.key),t)_.call(t,a)&&!x.hasOwnProperty(a)&&(o[a]=t[a]);var l=arguments.length-2;if(1===l)o.children=n;else if(1<l){for(var c=Array(l),u=0;u<l;u++)c[u]=arguments[u+2];o.children=c}if(e&&e.defaultProps)for(a in l=e.defaultProps)void 0===o[a]&&(o[a]=l[a]);return{$$typeof:r,type:e,key:i,ref:s,props:o,_owner:w.current}}function E(e){return"object"==typeof e&&null!==e&&e.$$typeof===r}var S=/\/+/g;function T(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function C(e,t,n,a,i){var s=typeof e;"undefined"!==s&&"boolean"!==s||(e=null);var l=!1;if(null===e)l=!0;else switch(s){case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case r:case o:l=!0}}if(l)return i=i(l=e),e=""===a?"."+T(l,0):a,Array.isArray(i)?(n="",null!=e&&(n=e.replace(S,"$&/")+"/"),C(i,t,n,"",(function(e){return e}))):null!=i&&(E(i)&&(i=function(e,t){return{$$typeof:r,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,n+(!i.key||l&&l.key===i.key?"":(""+i.key).replace(S,"$&/")+"/")+e)),t.push(i)),1;if(l=0,a=""===a?".":a+":",Array.isArray(e))for(var c=0;c<e.length;c++){var u=a+T(s=e[c],c);l+=C(s,t,n,u,i)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=p&&e[p]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),c=0;!(s=e.next()).done;)l+=C(s=s.value,t,n,u=a+T(s,c++),i);else if("object"===s)throw t=""+e,Error(f(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t));return l}function A(e,t,n){if(null==e)return e;var a=[],r=0;return C(e,a,"","",(function(e){return t.call(n,e,r++)})),a}function L(e){if(-1===e._status){var t=e._result;t=t(),e._status=0,e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}if(1===e._status)return e._result;throw e._result}var P={current:null};function N(){var e=P.current;if(null===e)throw Error(f(321));return e}var j={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:w,IsSomeRendererActing:{current:!1},assign:a};t.Children={map:A,forEach:function(e,t,n){A(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return A(e,(function(){t++})),t},toArray:function(e){return A(e,(function(e){return e}))||[]},only:function(e){if(!E(e))throw Error(f(143));return e}},t.Component=h,t.PureComponent=v,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=j,t.cloneElement=function(e,t,n){if(null==e)throw Error(f(267,e));var o=a({},e.props),i=e.key,s=e.ref,l=e._owner;if(null!=t){if(void 0!==t.ref&&(s=t.ref,l=w.current),void 0!==t.key&&(i=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(u in t)_.call(t,u)&&!x.hasOwnProperty(u)&&(o[u]=void 0===t[u]&&void 0!==c?c[u]:t[u])}var u=arguments.length-2;if(1===u)o.children=n;else if(1<u){c=Array(u);for(var d=0;d<u;d++)c[d]=arguments[d+2];o.children=c}return{$$typeof:r,type:e.type,key:i,ref:s,props:o,_owner:l}},t.createContext=function(e,t){return void 0===t&&(t=null),(e={$$typeof:s,_calculateChangedBits:t,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=k,t.createFactory=function(e){var t=k.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:l,render:e}},t.isValidElement=E,t.lazy=function(e){return{$$typeof:u,_payload:{_status:-1,_result:e},_init:L}},t.memo=function(e,t){return{$$typeof:c,type:e,compare:void 0===t?null:t}},t.useCallback=function(e,t){return N().useCallback(e,t)},t.useContext=function(e,t){return N().useContext(e,t)},t.useDebugValue=function(){},t.useEffect=function(e,t){return N().useEffect(e,t)},t.useImperativeHandle=function(e,t,n){return N().useImperativeHandle(e,t,n)},t.useLayoutEffect=function(e,t){return N().useLayoutEffect(e,t)},t.useMemo=function(e,t){return N().useMemo(e,t)},t.useReducer=function(e,t,n){return N().useReducer(e,t,n)},t.useRef=function(e){return N().useRef(e)},t.useState=function(e){return N().useState(e)},t.version="17.0.2"},67294:(e,t,n)=>{"use strict";e.exports=n(72408)},60053:(e,t)=>{"use strict";var n,a,r,o;if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var s=Date,l=s.now();t.unstable_now=function(){return s.now()-l}}if("undefined"==typeof window||"function"!=typeof MessageChannel){var c=null,u=null,d=function(){if(null!==c)try{var e=t.unstable_now();c(!0,e),c=null}catch(n){throw setTimeout(d,0),n}};n=function(e){null!==c?setTimeout(n,0,e):(c=e,setTimeout(d,0))},a=function(e,t){u=setTimeout(e,t)},r=function(){clearTimeout(u)},t.unstable_shouldYield=function(){return!1},o=t.unstable_forceFrameRate=function(){}}else{var p=window.setTimeout,f=window.clearTimeout;if("undefined"!=typeof console){var g=window.cancelAnimationFrame;"function"!=typeof window.requestAnimationFrame&&console.error("This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills"),"function"!=typeof g&&console.error("This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills")}var m=!1,h=null,b=-1,v=5,y=0;t.unstable_shouldYield=function(){return t.unstable_now()>=y},o=function(){},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):v=0<e?Math.floor(1e3/e):5};var w=new MessageChannel,_=w.port2;w.port1.onmessage=function(){if(null!==h){var e=t.unstable_now();y=e+v;try{h(!0,e)?_.postMessage(null):(m=!1,h=null)}catch(n){throw _.postMessage(null),n}}else m=!1},n=function(e){h=e,m||(m=!0,_.postMessage(null))},a=function(e,n){b=p((function(){e(t.unstable_now())}),n)},r=function(){f(b),b=-1}}function x(e,t){var n=e.length;e.push(t);e:for(;;){var a=n-1>>>1,r=e[a];if(!(void 0!==r&&0<S(r,t)))break e;e[a]=t,e[n]=r,n=a}}function k(e){return void 0===(e=e[0])?null:e}function E(e){var t=e[0];if(void 0!==t){var n=e.pop();if(n!==t){e[0]=n;e:for(var a=0,r=e.length;a<r;){var o=2*(a+1)-1,i=e[o],s=o+1,l=e[s];if(void 0!==i&&0>S(i,n))void 0!==l&&0>S(l,i)?(e[a]=l,e[s]=n,a=s):(e[a]=i,e[o]=n,a=o);else{if(!(void 0!==l&&0>S(l,n)))break e;e[a]=l,e[s]=n,a=s}}}return t}return null}function S(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var T=[],C=[],A=1,L=null,P=3,N=!1,j=!1,O=!1;function M(e){for(var t=k(C);null!==t;){if(null===t.callback)E(C);else{if(!(t.startTime<=e))break;E(C),t.sortIndex=t.expirationTime,x(T,t)}t=k(C)}}function R(e){if(O=!1,M(e),!j)if(null!==k(T))j=!0,n(I);else{var t=k(C);null!==t&&a(R,t.startTime-e)}}function I(e,n){j=!1,O&&(O=!1,r()),N=!0;var o=P;try{for(M(n),L=k(T);null!==L&&(!(L.expirationTime>n)||e&&!t.unstable_shouldYield());){var i=L.callback;if("function"==typeof i){L.callback=null,P=L.priorityLevel;var s=i(L.expirationTime<=n);n=t.unstable_now(),"function"==typeof s?L.callback=s:L===k(T)&&E(T),M(n)}else E(T);L=k(T)}if(null!==L)var l=!0;else{var c=k(C);null!==c&&a(R,c.startTime-n),l=!1}return l}finally{L=null,P=o,N=!1}}var D=o;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){j||N||(j=!0,n(I))},t.unstable_getCurrentPriorityLevel=function(){return P},t.unstable_getFirstCallbackNode=function(){return k(T)},t.unstable_next=function(e){switch(P){case 1:case 2:case 3:var t=3;break;default:t=P}var n=P;P=t;try{return e()}finally{P=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=D,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=P;P=e;try{return t()}finally{P=n}},t.unstable_scheduleCallback=function(e,o,i){var s=t.unstable_now();switch("object"==typeof i&&null!==i?i="number"==typeof(i=i.delay)&&0<i?s+i:s:i=s,e){case 1:var l=-1;break;case 2:l=250;break;case 5:l=1073741823;break;case 4:l=1e4;break;default:l=5e3}return e={id:A++,callback:o,priorityLevel:e,startTime:i,expirationTime:l=i+l,sortIndex:-1},i>s?(e.sortIndex=i,x(C,e),null===k(T)&&e===k(C)&&(O?r():O=!0,a(R,i-s))):(e.sortIndex=l,x(T,e),j||N||(j=!0,n(I))),e},t.unstable_wrapCallback=function(e){var t=P;return function(){var n=P;P=t;try{return e.apply(this,arguments)}finally{P=n}}}},63840:(e,t,n)=>{"use strict";e.exports=n(60053)},96774:e=>{e.exports=function(e,t,n,a){var r=n?n.call(a,e,t):void 0;if(void 0!==r)return!!r;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(var s=Object.prototype.hasOwnProperty.bind(t),l=0;l<o.length;l++){var c=o[l];if(!s(c))return!1;var u=e[c],d=t[c];if(!1===(r=n?n.call(a,u,d,c):void 0)||void 0===r&&u!==d)return!1}return!0}},53250:(e,t,n)=>{"use strict";var a=n(67294);var r="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t},o=a.useState,i=a.useEffect,s=a.useLayoutEffect,l=a.useDebugValue;function c(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!r(e,n)}catch(a){return!0}}var u="undefined"==typeof window||void 0===window.document||void 0===window.document.createElement?function(e,t){return t()}:function(e,t){var n=t(),a=o({inst:{value:n,getSnapshot:t}}),r=a[0].inst,u=a[1];return s((function(){r.value=n,r.getSnapshot=t,c(r)&&u({inst:r})}),[e,n,t]),i((function(){return c(r)&&u({inst:r}),e((function(){c(r)&&u({inst:r})}))}),[e]),l(n),n};t.useSyncExternalStore=void 0!==a.useSyncExternalStore?a.useSyncExternalStore:u},61688:(e,t,n)=>{"use strict";e.exports=n(53250)},36809:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});const a={title:"GG",url:"https://greeng00se.github.io",baseUrl:"/",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",favicon:"img/duck.png",organizationName:"greeng00se",projectName:"greeng00se.github.io",trailingSlash:!1,i18n:{defaultLocale:"ko",locales:["ko"],path:"i18n",localeConfigs:{}},markdown:{mermaid:!0},themes:["@docusaurus/theme-mermaid"],presets:[["classic",{blog:{showReadingTime:!0,routeBasePath:"/",archiveBasePath:"/blog",postsPerPage:1,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/"},docs:{sidebarPath:"/home/runner/work/greeng00se.github.io/greeng00se.github.io/sidebars.js",showLastUpdateTime:!0,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/"},theme:{customCss:"/home/runner/work/greeng00se.github.io/greeng00se.github.io/src/css/custom.css"},gtag:{trackingID:"G-17TREGCW4H",anonymizeIP:!0},sitemap:{changefreq:"weekly",priority:.5,ignorePatterns:["/tags/**","/docs/**","/page/**"],filename:"sitemap.xml"}}]],themeConfig:{navbar:{title:"greeng\xf6\xf6se",items:[{to:"/blog",label:"\ube14\ub85c\uadf8",position:"left"},{position:"left",type:"doc",label:"\ubb38\uc11c",docId:"intro"},{href:"https://github.com/greeng00se",position:"right",className:"header-github-link","aria-label":"GitHub repository"}],hideOnScroll:!1},algolia:{appId:"YSMNU47L51",apiKey:"16caa11a7af7bf5db56b5f640fa738cd",indexName:"gh",contextualSearch:!0,searchParameters:{},searchPagePath:"search"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:["java","kotlin","groovy"],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},metadata:[{name:"google-site-verification",content:"APK6j79LMymudgmQDTV8u_RYyncFYyuFUjY9A0hVPv4"}],colorMode:{defaultMode:"dark",respectPrefersColorScheme:!0,disableSwitch:!1},mermaid:{theme:{light:"neutral",dark:"dark"},options:{}},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},baseUrlIssueBanner:!0,onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},plugins:[],scripts:[],headTags:[],stylesheets:[],clientModules:[],tagline:"",titleDelimiter:"|",noIndex:!1}},87462:(e,t,n)=>{"use strict";function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},a.apply(this,arguments)}n.d(t,{Z:()=>a})},75068:(e,t,n)=>{"use strict";function a(e,t){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},a(e,t)}function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,a(e,t)}n.d(t,{Z:()=>r})},63366:(e,t,n)=>{"use strict";function a(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}n.d(t,{Z:()=>a})},38776:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});var a="Invariant failed";function r(e,t){if(!e)throw new Error(a)}},57529:e=>{"use strict";e.exports=JSON.parse('{"theme.AnnouncementBar.closeButtonAriaLabel":"\ub2eb\uae30","theme.BackToTopButton.buttonAriaLabel":"\ub9e8 \uc704\ub85c \uc2a4\ud06c\ub864\ud558\uae30","theme.CodeBlock.copied":"\ubcf5\uc0ac\ud588\uc2b5\ub2c8\ub2e4","theme.CodeBlock.copy":"\ubcf5\uc0ac","theme.CodeBlock.copyButtonAriaLabel":"\ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ucf54\ub4dc \ubcf5\uc0ac","theme.CodeBlock.wordWrapToggle":"\uc904 \ubc14\uafc8 \uc804\ud658","theme.DocSidebarItem.toggleCollapsedCategoryAriaLabel":"\uc811\uc744 \uc218 \uc788\ub294 \uc0ac\uc774\ub4dc\ubc14 \ubd84\ub958 \'{label}\' \uc811\uae30(\ud3bc\uce58\uae30)","theme.ErrorPageContent.title":"\ud398\uc774\uc9c0\uc5d0 \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4.","theme.ErrorPageContent.tryAgain":"\ub2e4\uc2dc \uc2dc\ub3c4\ud574 \ubcf4\uc138\uc694","theme.NavBar.navAriaLabel":"Main","theme.NotFound.p1":"\uc6d0\ud558\ub294 \ud398\uc774\uc9c0\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.","theme.NotFound.p2":"\uc0ac\uc774\ud2b8 \uad00\ub9ac\uc790\uc5d0\uac8c \ub9c1\ud06c\uac00 \uae68\uc9c4 \uac83\uc744 \uc54c\ub824\uc8fc\uc138\uc694.","theme.NotFound.title":"\ud398\uc774\uc9c0\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.","theme.TOCCollapsible.toggleButtonLabel":"\uc774 \ud398\uc774\uc9c0\uc5d0\uc11c","theme.admonition.caution":"\uc8fc\uc758","theme.admonition.danger":"\uc704\ud5d8","theme.admonition.info":"\uc815\ubcf4","theme.admonition.note":"\ub178\ud2b8","theme.admonition.tip":"\ud301","theme.blog.archive.description":"\uac8c\uc2dc\ubb3c \ubaa9\ub85d","theme.blog.archive.title":"\uac8c\uc2dc\ubb3c \ubaa9\ub85d","theme.blog.paginator.navAriaLabel":"\ube14\ub85c\uadf8 \uac8c\uc2dc\ubb3c \ubaa9\ub85d \ud0d0\uc0c9","theme.blog.paginator.newerEntries":"\uc774\uc804 \ud398\uc774\uc9c0","theme.blog.paginator.olderEntries":"\ub2e4\uc74c \ud398\uc774\uc9c0","theme.blog.post.paginator.navAriaLabel":"\ube14\ub85c\uadf8 \uac8c\uc2dc\ubb3c \ud0d0\uc0c9","theme.blog.post.paginator.newerPost":"\uc774\uc804 \uac8c\uc2dc\ubb3c","theme.blog.post.paginator.olderPost":"\ub2e4\uc74c \uac8c\uc2dc\ubb3c","theme.blog.post.plurals":"{count}\uac1c \uac8c\uc2dc\ubb3c","theme.blog.post.readMore":"\uc790\uc138\ud788 \ubcf4\uae30","theme.blog.post.readMoreLabel":"{title} \uc5d0 \ub300\ud574 \ub354 \uc77d\uc5b4\ubcf4\uae30","theme.blog.post.readingTime.plurals":"\uc57d {readingTime}\ubd84","theme.blog.sidebar.navAriaLabel":"\ucd5c\uadfc \ube14\ub85c\uadf8 \ubb38\uc11c \ub458\ub7ec\ubcf4\uae30","theme.blog.tagTitle":"\\"{tagName}\\" \ud0dc\uadf8\ub85c \uc5f0\uacb0\ub41c {nPosts}\uac1c\uc758 \uac8c\uc2dc\ubb3c\uc774 \uc788\uc2b5\ub2c8\ub2e4.","theme.colorToggle.ariaLabel":"\uc5b4\ub450\uc6b4 \ubaa8\ub4dc\uc640 \ubc1d\uc740 \ubaa8\ub4dc \uc804\ud658\ud558\uae30 (\ud604\uc7ac {mode})","theme.colorToggle.ariaLabel.mode.dark":"\uc5b4\ub450\uc6b4 \ubaa8\ub4dc","theme.colorToggle.ariaLabel.mode.light":"\ubc1d\uc740 \ubaa8\ub4dc","theme.common.editThisPage":"\ud398\uc774\uc9c0 \ud3b8\uc9d1","theme.common.headingLinkTitle":"{heading}\uc5d0 \ub300\ud55c \uc9c1\uc811 \ub9c1\ud06c","theme.common.skipToMainContent":"\ubcf8\ubb38\uc73c\ub85c \uac74\ub108\ub6f0\uae30","theme.docs.DocCard.categoryDescription":"{count} \ud56d\ubaa9","theme.docs.breadcrumbs.home":"\ud648","theme.docs.breadcrumbs.navAriaLabel":"Breadcrumbs","theme.docs.paginator.navAriaLabel":"\ubb38\uc11c \ud398\uc774\uc9c0","theme.docs.paginator.next":"\ub2e4\uc74c","theme.docs.paginator.previous":"\uc774\uc804","theme.docs.sidebar.closeSidebarButtonAriaLabel":"Close navigation bar","theme.docs.sidebar.collapseButtonAriaLabel":"\uc0ac\uc774\ub4dc\ubc14 \uc228\uae30\uae30","theme.docs.sidebar.collapseButtonTitle":"\uc0ac\uc774\ub4dc\ubc14 \uc228\uae30\uae30","theme.docs.sidebar.expandButtonAriaLabel":"\uc0ac\uc774\ub4dc\ubc14 \uc5f4\uae30","theme.docs.sidebar.expandButtonTitle":"\uc0ac\uc774\ub4dc\ubc14 \uc5f4\uae30","theme.docs.sidebar.navAriaLabel":"Docs sidebar","theme.docs.sidebar.toggleSidebarButtonAriaLabel":"Toggle navigation bar","theme.docs.tagDocListPageTitle":"{nDocsTagged} \\"{tagName}\\" \ud0dc\uadf8\uc5d0 \ubd84\ub958\ub418\uc5c8\uc2b5\ub2c8\ub2e4","theme.docs.tagDocListPageTitle.nDocsTagged":"{count}\uac1c \ubb38\uc11c\uac00","theme.docs.versionBadge.label":"\ubc84\uc804: {versionLabel}","theme.docs.versions.latestVersionLinkLabel":"\ucd5c\uc2e0 \ubc84\uc804","theme.docs.versions.latestVersionSuggestionLabel":"\ucd5c\uc2e0 \ubb38\uc11c\ub294 {latestVersionLink} ({versionLabel})\uc744 \ud655\uc778\ud558\uc138\uc694.","theme.docs.versions.unmaintainedVersionLabel":"{siteTitle} {versionLabel} \ubb38\uc11c\ub294 \ub354 \uc774\uc0c1 \uc5c5\ub370\uc774\ud2b8\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.","theme.docs.versions.unreleasedVersionLabel":"{siteTitle} {versionLabel} \ubb38\uc11c\ub294 \uc544\uc9c1 \uc815\uc2dd \uacf5\uac1c\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.","theme.lastUpdated.atDate":" {date}\uc5d0","theme.lastUpdated.byUser":" {user}\uac00","theme.lastUpdated.lastUpdatedAtBy":"\ucd5c\uc885 \uc218\uc815: {atDate}{byUser}","theme.navbar.mobileLanguageDropdown.label":"\uc5b8\uc5b4","theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel":"\u2190 \uba54\uc778 \uba54\ub274\ub85c \ub3cc\uc544\uac00\uae30","theme.navbar.mobileVersionsDropdown.label":"\ubc84\uc804","theme.tags.tagsListLabel":"\ud0dc\uadf8:","theme.tags.tagsPageLink":"\ubaa8\ub4e0 \ud0dc\uadf8 \ubcf4\uae30","theme.tags.tagsPageTitle":"\ud0dc\uadf8","theme.SearchBar.label":"\uac80\uc0c9","theme.SearchBar.seeAll":"{count}\uac1c\uc758 \uacb0\uacfc \ud655\uc778\ud558\uae30","theme.SearchModal.errorScreen.helpText":"\uc778\ud130\ub137 \uc5f0\uacb0\uc744 \ub2e4\uc2dc \ud655\uc778\ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.","theme.SearchModal.errorScreen.titleText":"\uacb0\uacfc\ub97c \ubd88\ub7ec\uc62c \uc218 \uc5c6\uc74c","theme.SearchModal.footer.closeKeyAriaLabel":"Esc \ud0a4","theme.SearchModal.footer.closeText":"\ub85c \uc885\ub8cc","theme.SearchModal.footer.navigateDownKeyAriaLabel":"\ud654\uc0b4\ud45c \uc544\ub798 \ud0a4","theme.SearchModal.footer.navigateText":"\ub85c \uc774\ub3d9","theme.SearchModal.footer.navigateUpKeyAriaLabel":"\ud654\uc0b4\ud45c \uc704 \ud0a4","theme.SearchModal.footer.searchByText":"\uac80\uc0c9 \uc81c\uacf5","theme.SearchModal.footer.selectKeyAriaLabel":"\uc5d4\ud130 \ud0a4","theme.SearchModal.footer.selectText":"\ub85c \uc120\ud0dd","theme.SearchModal.noResultsScreen.noResultsText":"\uac80\uc0c9 \uacb0\uacfc \uc5c6\uc74c","theme.SearchModal.noResultsScreen.reportMissingResultsLinkText":"\uc54c\ub824\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.","theme.SearchModal.noResultsScreen.reportMissingResultsText":"\uac80\uc0c9 \uacb0\uacfc\uac00 \uc5c6\ub294 \uac83\uc774 \uc624\ub958\ub77c\uace0 \uc0dd\uac01\ub418\uc2ed\ub2c8\uae4c?","theme.SearchModal.noResultsScreen.suggestedQueryText":"\ub2e4\ub978 \ucd94\ucc9c \uac80\uc0c9\uc5b4","theme.SearchModal.placeholder":"\ubb38\uc11c \uac80\uc0c9","theme.SearchModal.searchBox.cancelButtonText":"\ucde8\uc18c","theme.SearchModal.searchBox.resetButtonTitle":"\uac80\uc0c9\uc5b4 \ucd08\uae30\ud654","theme.SearchModal.startScreen.favoriteSearchesTitle":"\uc990\uaca8\ucc3e\uae30","theme.SearchModal.startScreen.noRecentSearchesText":"\ucd5c\uadfc \uac80\uc0c9\uc5b4 \uc5c6\uc74c","theme.SearchModal.startScreen.recentSearchesTitle":"\ucd5c\uadfc","theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle":"\uc774 \uac80\uc0c9\uc5b4\ub97c \uc990\uaca8\ucc3e\uae30\uc5d0\uc11c \uc0ad\uc81c","theme.SearchModal.startScreen.removeRecentSearchButtonTitle":"\uc774 \uac80\uc0c9\uc5b4\ub97c \ucd5c\uadfc \uac80\uc0c9\uc5b4\uc5d0\uc11c \uc0ad\uc81c","theme.SearchModal.startScreen.saveRecentSearchButtonTitle":"\uc774 \uac80\uc0c9\uc5b4\ub97c \uc800\uc7a5","theme.SearchPage.algoliaLabel":"Algolia\ub85c \uac80\uc0c9","theme.SearchPage.documentsFound.plurals":"{count}\uac1c\uc758 \ubb38\uc11c\ub97c \ucc3e\uc558\uc2b5\ub2c8\ub2e4.","theme.SearchPage.emptyResultsTitle":"\ubb38\uc11c\ub97c \uac80\uc0c9\ud569\ub2c8\ub2e4.","theme.SearchPage.existingResultsTitle":"\\"{query}\\" \uac80\uc0c9 \uacb0\uacfc","theme.SearchPage.fetchingNewResults":"\uc0c8\ub85c\uc6b4 \uac80\uc0c9 \uacb0\uacfc\ub97c \ubd88\ub7ec\uc624\ub294 \uc911\uc785\ub2c8\ub2e4.","theme.SearchPage.inputLabel":"\uac80\uc0c9","theme.SearchPage.inputPlaceholder":"\uac80\uc0c9\uc5b4\ub97c \uc785\ub825\ud558\uc138\uc694.","theme.SearchPage.noResultsText":"\uac80\uc0c9 \uacb0\uacfc\uac00 \uc5c6\uc2b5\ub2c8\ub2e4."}')},16887:e=>{"use strict";e.exports=JSON.parse('{"/2022-retrospective-624":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"9b43eac8"},"/accidental-duplication-d17":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"bace0b37"},"/blackjack-retrospective-595":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"3dd4d232"},"/blog-3d8":{"__comp":"9e4087bc","__context":{"plugin":"509d519c"},"archive":"b2b675dd"},"/book-leadership-and-self-deception-ddd":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"829fa7b9"},"/book-writer-3c9":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"fa3d3942"},"/chess-retrospective-168":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"8a24850b"},"/cloudwatch-cb1":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"c1b17b3f"},"/composite-302":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"c6d04683"},"/custom-jdbc-template-cfa":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"d7955594"},"/db-replication-6f2":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"f06cb3e2"},"/docs/tags-820":{"__comp":"3720c009","__context":{"plugin":"dcf70953"},"tags":"55960ee5"},"/docs/tags/architecture-f3f":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"f6807fb4"},"/docs/tags/book-c20":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"f4c6e7e6"},"/docs/tags/collection-b80":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"2c446262"},"/docs/tags/deploy-591":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"e5e44a85"},"/docs/tags/etc-338":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"c189d18f"},"/docs/tags/java-08c":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"3b12d42b"},"/docs/tags/jpa-f95":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"5ffd2c10"},"/docs/tags/latency-e82":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"b36d2d1d"},"/docs/tags/load-balancing-0be":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"38bf29ad"},"/docs/tags/monitoring-50f":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"1c93669b"},"/docs/tags/network-322":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"6c674d03"},"/docs/tags/nginx-ecc":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"c60995f6"},"/docs/tags/package-593":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"211d6170"},"/docs/tags/performance-a3d":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"9e4ad429"},"/docs/tags/postmortem-4b0":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"7e4c1ed7"},"/docs/tags/sequenced-e0d":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"6c38e270"},"/docs/tags/spring-f99":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"a7e0d18f"},"/docs/tags/test-b58":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"9bbc65ac"},"/docs/tags/throughput-206":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"c08e7a0d"},"/docs/tags/zero-downtime-389":{"__comp":"df203c0f","__context":{"plugin":"dcf70953"},"tag":"4430ab79"},"/docusaurus-926":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"1236fad7"},"/grasp-f9b":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"e9eabc5d"},"/innodb-lock-d18":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"130df38c"},"/intellij-settings-80e":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"14dc1923"},"/java-class-file-50e":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"8720c147"},"/java-spring-springboot-bed":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"ff4c6c5e"},"/jdbc-retrospective-158":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"b41adc00"},"/jenkins-48c":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"b2ebb6fd"},"/jsr-310-7f9":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"101b58de"},"/kotlin-null-8d3":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"d28e30d7"},"/ladder-retrospective-7ea":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"327fa616"},"/level2-interview-retrospective-c75":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"6552f31f"},"/log-async-exception-a44":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"e2326195"},"/mock-static-method-fd3":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"42957a8d"},"/mvc-retrospective-96d":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"5a473bed"},"/mysql-lock-3cb":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"cb6229c3"},"/order-retrospective-a11":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"b2c8756c"},"/page/10-c2c":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"0e33a907"}],"metadata":"f332d221"},"/page/11-89b":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f25de701"}],"metadata":"fbd57548"},"/page/12-155":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d65e25b7"}],"metadata":"f4f49e13"},"/page/13-ece":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"7159c7ff"}],"metadata":"2832e534"},"/page/14-1f9":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a59d28a9"}],"metadata":"4959fc42"},"/page/15-cc0":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8ad2f007"}],"metadata":"38d8699e"},"/page/16-813":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4d43abad"}],"metadata":"09fbb6bd"},"/page/17-843":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"26dc40bf"}],"metadata":"d1cef389"},"/page/18-84a":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f87bdf62"}],"metadata":"9cfe8fd1"},"/page/19-e4e":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"be497a8d"}],"metadata":"96adae60"},"/page/2-256":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5c07bdab"}],"metadata":"0c071de2"},"/page/20-30e":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"79a97f4e"}],"metadata":"35293ec4"},"/page/21-553":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dca6a1e3"}],"metadata":"80960b4b"},"/page/22-a88":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"08e37dbc"}],"metadata":"ef5b2427"},"/page/23-edf":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"48faf148"}],"metadata":"871c1e5a"},"/page/24-915":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d5bb232a"}],"metadata":"635a92d5"},"/page/25-4aa":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1781b1c4"}],"metadata":"226700de"},"/page/26-ec5":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6f385a52"}],"metadata":"54cb095e"},"/page/27-339":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ad3b7b62"}],"metadata":"5f81b25c"},"/page/28-376":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"21294bbb"}],"metadata":"270346fa"},"/page/29-ea0":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e1735da7"}],"metadata":"12cbeba7"},"/page/3-d5c":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5d4cff52"}],"metadata":"e4ebfe18"},"/page/30-2ff":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"aacfeabc"}],"metadata":"00931cc3"},"/page/31-d32":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"eff1d58f"}],"metadata":"d50fd269"},"/page/32-02d":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"daff1d93"}],"metadata":"754fb852"},"/page/33-3d4":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"9bad5ae7"}],"metadata":"f3e308ad"},"/page/34-4d2":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"db86613e"}],"metadata":"6dd1c948"},"/page/35-b81":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"73688d5c"}],"metadata":"c29bedb9"},"/page/36-598":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"bb221eab"}],"metadata":"69c28c32"},"/page/37-eda":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dfc7013c"}],"metadata":"494882d1"},"/page/38-9cf":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6b54f6a4"}],"metadata":"2e10a69c"},"/page/39-27d":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a8cba70f"}],"metadata":"64868a43"},"/page/4-b0c":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ae82353f"}],"metadata":"7762a24e"},"/page/40-744":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1251d98b"}],"metadata":"eec33099"},"/page/41-793":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e6a6ed43"}],"metadata":"32b2299c"},"/page/42-0ee":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4485017c"}],"metadata":"70275fcd"},"/page/43-345":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"df147deb"}],"metadata":"d2611248"},"/page/44-3c4":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"b6ffb0cb"}],"metadata":"1bb997fc"},"/page/45-6e5":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1f61820a"}],"metadata":"101cf32b"},"/page/46-d10":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"52106a5f"}],"metadata":"53e4509a"},"/page/47-280":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1f05d14a"}],"metadata":"15eddcef"},"/page/48-8df":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"537817cb"}],"metadata":"69a75ff2"},"/page/49-282":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"2c9f5501"}],"metadata":"04c55e47"},"/page/5-87c":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1664646a"}],"metadata":"8d05b77c"},"/page/50-3c4":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8a27aeff"}],"metadata":"f01ceada"},"/page/51-658":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"372ccfe9"}],"metadata":"7881a85f"},"/page/6-a58":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"cd68cda1"}],"metadata":"7af1d52f"},"/page/7-bb8":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"905ecccc"}],"metadata":"d0e4cdf1"},"/page/8-2f3":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"70834889"}],"metadata":"f75a8651"},"/page/9-88d":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"92ade856"}],"metadata":"6093f82b"},"/parameterized-tests-1fb":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"3f6ea930"},"/performance-test-type-df3":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"0571a526"},"/racing-car-retrospective-ebc":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"92fef07b"},"/refactoring-retrospective-ab4":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"1e8ecffe"},"/route-image-async-with-event-832":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"4b79a3c9"},"/route-image-implementation-b0f":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"cc519f63"},"/route-image-intro-7e7":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"9e2e3982"},"/route-image-python-dfd":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"cef46b76"},"/search-c1e":{"__comp":"1a4e3797","__context":{"plugin":"18c69d70"}},"/shopping-cart-retrospective-28b":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"6675e9ab"},"/spring-test-isolation-8ed":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"448c20a0"},"/subway-retrospective-7db":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"16f719ab"},"/tags-4bf":{"__comp":"01a85c17","__context":{"plugin":"509d519c"},"sidebar":"814f3328","tags":"c573638f"},"/tags/async-a21":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"cd68cda1"}],"tag":"8fbd512b","listMetadata":"a1877440"},"/tags/async/page/2-436":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d65e25b7"}],"tag":"6d4355d3","listMetadata":"9f586ca3"},"/tags/awt-9e3":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"7159c7ff"}],"tag":"cf8e491a","listMetadata":"9b56b618"},"/tags/awt/page/2-b68":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4d43abad"}],"tag":"f0978ee1","listMetadata":"32397cb2"},"/tags/book-4df":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"daff1d93"}],"tag":"2d3b202f","listMetadata":"14164549"},"/tags/book/page/2-88a":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"2c9f5501"}],"tag":"2bfe7c0b","listMetadata":"c0cb7215"},"/tags/book/page/3-128":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"372ccfe9"}],"tag":"df862072","listMetadata":"ffb0fa11"},"/tags/class-d3d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dfc7013c"}],"tag":"33736670","listMetadata":"8d7288fe"},"/tags/cloudwatch-264":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f25de701"}],"tag":"b7d33121","listMetadata":"6cfe3a99"},"/tags/composite-931":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d5bb232a"}],"tag":"255134d9","listMetadata":"ae1d6508"},"/tags/data-base-2fe":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"9bad5ae7"}],"tag":"0a2eaa84","listMetadata":"309173fa"},"/tags/data-base/page/2-049":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"db86613e"}],"tag":"9dec6b67","listMetadata":"66d1c769"},"/tags/data-base/page/3-9ac":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"73688d5c"}],"tag":"02689328","listMetadata":"dfa84138"},"/tags/documentation-86d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"be497a8d"}],"tag":"7bbc420e","listMetadata":"20e99c2a"},"/tags/dto-bef":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6f385a52"}],"tag":"5a6c6934","listMetadata":"d0277431"},"/tags/elastic-beanstalk-164":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"aacfeabc"}],"tag":"28a1570f","listMetadata":"0746167d"},"/tags/event-56a":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d65e25b7"}],"tag":"0cb009d1","listMetadata":"8dc09bac"},"/tags/exception-5b1":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"cd68cda1"}],"tag":"cc3bdf2f","listMetadata":"4515250b"},"/tags/grasp-130":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e6a6ed43"}],"tag":"b9bcab37","listMetadata":"2f43e44a"},"/tags/image-067":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"7159c7ff"}],"tag":"75121fd5","listMetadata":"d368e73e"},"/tags/image/page/2-88a":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a59d28a9"}],"tag":"562496aa","listMetadata":"b474adfe"},"/tags/image/page/3-acc":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4d43abad"}],"tag":"d6a3d698","listMetadata":"4b2fba3e"},"/tags/inno-db-2aa":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"9bad5ae7"}],"tag":"49b8d9dd","listMetadata":"a9221bd5"},"/tags/intelli-j-aaa":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"52106a5f"}],"tag":"fe8cce0a","listMetadata":"db7928b3"},"/tags/isolation-bab":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"73688d5c"}],"tag":"c3ea66fe","listMetadata":"d2935d14"},"/tags/java-60d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"26dc40bf"}],"tag":"274c9143","listMetadata":"fe273484"},"/tags/java/page/2-d9f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dfc7013c"}],"tag":"1893cb59","listMetadata":"54150be7"},"/tags/java/page/3-d2c":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6b54f6a4"}],"tag":"8e498bb6","listMetadata":"198f8d8a"},"/tags/java/page/4-c97":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1f61820a"}],"tag":"a3dddb77","listMetadata":"08726fcf"},"/tags/java/page/5-6c7":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"537817cb"}],"tag":"e2de2dbb","listMetadata":"35b2eb5a"},"/tags/jdbc-667":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6b54f6a4"}],"tag":"a85e626a","listMetadata":"d40f51e1"},"/tags/jenkins-590":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"aacfeabc"}],"tag":"3b0f99e8","listMetadata":"0281109c"},"/tags/kotlin-b84":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1f05d14a"}],"tag":"633582b9","listMetadata":"9fae68e2"},"/tags/lock-059":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"9bad5ae7"}],"tag":"6a19354d","listMetadata":"5eed1665"},"/tags/lock/page/2-2e3":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"db86613e"}],"tag":"9ca52986","listMetadata":"492a6565"},"/tags/log-0ae":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f25de701"}],"tag":"19f4ae8e","listMetadata":"5088fe06"},"/tags/mock-9dd":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"bb221eab"}],"tag":"1d81daa1","listMetadata":"c6004f62"},"/tags/mockito-3de":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8ad2f007"}],"tag":"3b18521e","listMetadata":"2b479afe"},"/tags/monitoring-775":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f25de701"}],"tag":"3d6c40c1","listMetadata":"1fbde614"},"/tags/my-sql-214":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"db86613e"}],"tag":"e0e4666e","listMetadata":"bf933b37"},"/tags/mysql-79d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"92ade856"}],"tag":"280572f1","listMetadata":"75f50328"},"/tags/oop-613":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e6a6ed43"}],"tag":"9d8ee3a8","listMetadata":"d202e2c5"},"/tags/pattern-5e4":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d5bb232a"}],"tag":"2d9296e4","listMetadata":"e9ff60ad"},"/tags/performance-test-d3e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"70834889"}],"tag":"546ec22f","listMetadata":"56e576e5"},"/tags/python-7fe":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a59d28a9"}],"tag":"c7015929","listMetadata":"f580a9d0"},"/tags/replication-77b":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"92ade856"}],"tag":"b301b20b","listMetadata":"c92f81ac"},"/tags/retrospective-b64":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"530ffa4f"}],"tag":"8c6c0796","listMetadata":"a4a1e915"},"/tags/retrospective/page/10-ba6":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1781b1c4"}],"tag":"bbc01ba0","listMetadata":"9dc4119a"},"/tags/retrospective/page/11-c54":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ad3b7b62"}],"tag":"e073eb07","listMetadata":"7405ea58"},"/tags/retrospective/page/12-443":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"21294bbb"}],"tag":"3c5aea38","listMetadata":"e0d68441"},"/tags/retrospective/page/13-b71":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e1735da7"}],"tag":"d88bdb28","listMetadata":"e9624b4f"},"/tags/retrospective/page/14-e01":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"eff1d58f"}],"tag":"7fd9a574","listMetadata":"21e890b0"},"/tags/retrospective/page/15-64b":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a8cba70f"}],"tag":"16cc6f3a","listMetadata":"b5f3dcc5"},"/tags/retrospective/page/16-703":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1251d98b"}],"tag":"49f0f498","listMetadata":"77f5fc5d"},"/tags/retrospective/page/17-2d8":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4485017c"}],"tag":"1a3abee6","listMetadata":"d60e2b0c"},"/tags/retrospective/page/18-1fd":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"df147deb"}],"tag":"02ede3c9","listMetadata":"fb48356a"},"/tags/retrospective/page/19-d19":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"b6ffb0cb"}],"tag":"0c390f0d","listMetadata":"15f27552"},"/tags/retrospective/page/2-8bf":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5c07bdab"}],"tag":"abc83b7f","listMetadata":"533bfc57"},"/tags/retrospective/page/20-f75":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8a27aeff"}],"tag":"1398b403","listMetadata":"5feaaaeb"},"/tags/retrospective/page/3-998":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5d4cff52"}],"tag":"bd2d06b5","listMetadata":"2b22d492"},"/tags/retrospective/page/4-23f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"905ecccc"}],"tag":"303c1e60","listMetadata":"d126aabd"},"/tags/retrospective/page/5-b0c":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"0e33a907"}],"tag":"ee92877e","listMetadata":"43a97218"},"/tags/retrospective/page/6-58e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"79a97f4e"}],"tag":"e8d6e7ce","listMetadata":"6bc709ad"},"/tags/retrospective/page/7-133":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dca6a1e3"}],"tag":"a0410ab5","listMetadata":"564337ec"},"/tags/retrospective/page/8-c6e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"08e37dbc"}],"tag":"e21c8cc4","listMetadata":"05b907fc"},"/tags/retrospective/page/9-a37":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"48faf148"}],"tag":"8b79a48d","listMetadata":"7e59392d"},"/tags/spring-ab2":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"26dc40bf"}],"tag":"3ed04b60","listMetadata":"7fbacf84"},"/tags/spring-boot-eb7":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"26dc40bf"}],"tag":"087c46fa","listMetadata":"41b4728f"},"/tags/static-dd5":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8ad2f007"}],"tag":"269a2f75","listMetadata":"70a12cc4"},"/tags/teco-chat-7a9":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"48faf148"}],"tag":"af81a133","listMetadata":"f042b56c"},"/tags/teco-chat/page/2-fbf":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e1735da7"}],"tag":"c60ea0ff","listMetadata":"d5dfecc2"},"/tags/teco-chat/page/3-c3d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"eff1d58f"}],"tag":"1a6b9123","listMetadata":"d09f7e4b"},"/tags/test-84f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ae82353f"}],"tag":"2a8faff0","listMetadata":"1a665c6f"},"/tags/test/page/2-3a8":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"bb221eab"}],"tag":"d350f5d9","listMetadata":"6ba49b42"},"/tags/time-f3d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"537817cb"}],"tag":"f156dfb9","listMetadata":"fd5d2408"},"/tags/transaction-622":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"73688d5c"}],"tag":"d0840b01","listMetadata":"c037d168"},"/tags/web-application-4a3":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1664646a"}],"tag":"3680bd07","listMetadata":"8e9dc6b3"},"/tags/web-socket-e59":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f87bdf62"}],"tag":"489347ff","listMetadata":"3972c49f"},"/tags/woowahan-techcourse-77a":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"530ffa4f"}],"tag":"39ee6679","listMetadata":"5a29fbab"},"/tags/woowahan-techcourse/page/10-156":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ad3b7b62"}],"tag":"5c38e66e","listMetadata":"21d253a0"},"/tags/woowahan-techcourse/page/11-703":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"21294bbb"}],"tag":"d2770bf7","listMetadata":"64f377d6"},"/tags/woowahan-techcourse/page/12-38f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a8cba70f"}],"tag":"f7b9d2f4","listMetadata":"6412e40a"},"/tags/woowahan-techcourse/page/13-ddd":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1251d98b"}],"tag":"ee1dd2ad","listMetadata":"bbc3f62a"},"/tags/woowahan-techcourse/page/14-65c":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4485017c"}],"tag":"c6b037a5","listMetadata":"fb861301"},"/tags/woowahan-techcourse/page/15-a2e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"df147deb"}],"tag":"a4349a81","listMetadata":"3c9c1743"},"/tags/woowahan-techcourse/page/16-53e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"b6ffb0cb"}],"tag":"a539c018","listMetadata":"a9c2b81a"},"/tags/woowahan-techcourse/page/2-047":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5c07bdab"}],"tag":"86b4da3d","listMetadata":"e7d2a655"},"/tags/woowahan-techcourse/page/3-d3f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5d4cff52"}],"tag":"dab4c683","listMetadata":"ac23d7ee"},"/tags/woowahan-techcourse/page/4-5b6":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"905ecccc"}],"tag":"8da65e83","listMetadata":"6425a984"},"/tags/woowahan-techcourse/page/5-135":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"0e33a907"}],"tag":"fed8bc04","listMetadata":"bbceb8f1"},"/tags/woowahan-techcourse/page/6-5e8":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"79a97f4e"}],"tag":"a896be03","listMetadata":"f078e301"},"/tags/woowahan-techcourse/page/7-a11":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dca6a1e3"}],"tag":"f63a747b","listMetadata":"abb0816f"},"/tags/woowahan-techcourse/page/8-a7b":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"08e37dbc"}],"tag":"672a376b","listMetadata":"ddf9e0bd"},"/tags/woowahan-techcourse/page/9-be6":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1781b1c4"}],"tag":"43fcf0e9","listMetadata":"7c660760"},"/tecochat-retrospective-1-ed9":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"d8775059"},"/tecochat-retrospective-2-fc4":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"454a6d0d"},"/tecochat-retrospective-3-6f4":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"bbdd7e52"},"/test-double-8ea":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"24b9bc70"},"/the-essence-of-object-orientation-9a2":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"f90d0c52"},"/tomcat-retrospective-5a3":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"a710d533"},"/transaction-and-isolation-d60":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"bd4db8ee"},"/web-application-evolution-c55":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"ac3fdf5d"},"/web-racing-car-retrospective-ccb":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"72657f57"},"/websocket-5c1":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"e1a06456"},"/woowacourse-level1-retrospective-a6a":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"a3614f73"},"/woowacourse-level2-retrospective-758":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"9d1fd2b0"},"/woowacourse-level3-retrospective-4e5":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"4a1c8300"},"/docs-fab":{"__comp":"1be78505","__context":{"plugin":"dcf70953"},"versionMetadata":"935f2afb"},"/docs-818":{"__comp":"17896441","content":"f8409a7e"},"/docs/architecture/virtical-slice-architecture-825":{"__comp":"17896441","content":"eae2a611"},"/docs/book/getting-out-of-the-box-8e1":{"__comp":"17896441","content":"f3493919"},"/docs/culture/postmortem-420":{"__comp":"17896441","content":"cec43d6a"},"/docs/database/maximumPoolSize-9ab":{"__comp":"17896441","content":"aa73a035"},"/docs/database/query-execution-7b8":{"__comp":"17896441","content":"bd64a762"},"/docs/deploy/zero-downtime-20f":{"__comp":"17896441","content":"d6638f30"},"/docs/design/package-274":{"__comp":"17896441","content":"981f7647"},"/docs/etc/communication-9c1":{"__comp":"17896441","content":"04644f5f"},"/docs/etc/develop-with-spring-9ab":{"__comp":"17896441","content":"366ddb85"},"/docs/etc/experience-and-self-question-d25":{"__comp":"17896441","content":"d8cdf5ef"},"/docs/etc/healthful-growth-fcf":{"__comp":"17896441","content":"6b4e1191"},"/docs/java/sequenced-collection-bda":{"__comp":"17896441","content":"290b0a56"},"/docs/jpa/key-68b":{"__comp":"17896441","content":"6b69808d"},"/docs/linux/shell-c5b":{"__comp":"17896441","content":"051528db"},"/docs/linux/swap-9d5":{"__comp":"17896441","content":"e6e259a5"},"/docs/mac/java-5a9":{"__comp":"17896441","content":"d1e1bea4"},"/docs/monitoring/intro-5db":{"__comp":"17896441","content":"9c6e5a12"},"/docs/network/load-balancing-caa":{"__comp":"17896441","content":"caf1b628"},"/docs/network/load-balancing-algorithm-a4d":{"__comp":"17896441","content":"b88cb85b"},"/docs/nginx/command-0e3":{"__comp":"17896441","content":"c55d205b"},"/docs/nginx/static-file-629":{"__comp":"17896441","content":"d86f7a37"},"/docs/performance/throughput-56a":{"__comp":"17896441","content":"d361ad2d"},"/docs/performance/throughput-latency-12a":{"__comp":"17896441","content":"b421ebb7"},"/docs/performance/types-c08":{"__comp":"17896441","content":"87070fc3"},"/docs/spring/essence-4c6":{"__comp":"17896441","content":"da14f319"},"/docs/test/benefit-6c8":{"__comp":"17896441","content":"41c44b28"},"/docs/test/first-566":{"__comp":"17896441","content":"302370be"},"/docs/test/heuristics-b35":{"__comp":"17896441","content":"451db21d"},"/docs/test/stairstep-a57":{"__comp":"17896441","content":"a14ec7b5"},"/-3ce":{"__comp":"c4f5d8e4","__context":{"plugin":"ae3384b2"},"config":"5e9f5e1a"},"/-956":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"530ffa4f"}],"metadata":"a5557bb9"}}')}},e=>{e.O(0,[532],(()=>{return t=97221,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/main.eea870a2.js b/assets/js/main.eea870a2.js new file mode 100644 index 000000000..2acdeae1e --- /dev/null +++ b/assets/js/main.eea870a2.js @@ -0,0 +1,2 @@ +/*! For license information please see main.eea870a2.js.LICENSE.txt */ +(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[179],{20830:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});var a=n(67294);function r(){return a.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},a.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});n(67294);var a=n(68356),r=n.n(a),o=n(16887);const i={"00931cc3":[()=>n.e(5669).then(n.t.bind(n,92291,19)),"~blog/default/page-30-25c.json",92291],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,24524)),"@theme/BlogTagsListPage",24524],"02689328":[()=>n.e(6346).then(n.t.bind(n,5577,19)),"~blog/default/tags-data-base-page-3-9db.json",5577],"0281109c":[()=>n.e(422).then(n.t.bind(n,25266,19)),"~blog/default/tags-jenkins-2e5-list.json",25266],"02ede3c9":[()=>n.e(4934).then(n.t.bind(n,51226,19)),"~blog/default/tags-retrospective-page-18-40f.json",51226],"04644f5f":[()=>n.e(2625).then(n.bind(n,37895)),"@site/docs/\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00.mdx",37895],"04c55e47":[()=>n.e(4275).then(n.t.bind(n,26888,19)),"~blog/default/page-49-c29.json",26888],"051528db":[()=>n.e(5753).then(n.bind(n,29837)),"@site/docs/\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815.md",29837],"0571a526":[()=>n.e(6204).then(n.bind(n,93516)),"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",93516],"05b907fc":[()=>n.e(734).then(n.t.bind(n,92943,19)),"~blog/default/tags-retrospective-page-8-5ab-list.json",92943],"0746167d":[()=>n.e(1113).then(n.t.bind(n,19758,19)),"~blog/default/tags-elastic-beanstalk-119-list.json",19758],"08726fcf":[()=>n.e(5487).then(n.t.bind(n,38441,19)),"~blog/default/tags-java-page-4-c22-list.json",38441],"087c46fa":[()=>n.e(96).then(n.t.bind(n,25774,19)),"~blog/default/tags-spring-boot-889.json",25774],"08e37dbc":[()=>n.e(1328).then(n.bind(n,95883)),"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",95883],"09fbb6bd":[()=>n.e(5964).then(n.t.bind(n,41679,19)),"~blog/default/page-16-d6c.json",41679],"0a2eaa84":[()=>n.e(8942).then(n.t.bind(n,52930,19)),"~blog/default/tags-data-base-4e8.json",52930],"0c071de2":[()=>n.e(321).then(n.t.bind(n,23125,19)),"~blog/default/page-2-b45.json",23125],"0c390f0d":[()=>n.e(6550).then(n.t.bind(n,13321,19)),"~blog/default/tags-retrospective-page-19-af8.json",13321],"0cb009d1":[()=>n.e(116).then(n.t.bind(n,66643,19)),"~blog/default/tags-event-f04.json",66643],"0e33a907":[()=>n.e(3092).then(n.bind(n,33520)),"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx?truncated=true",33520],"101b58de":[()=>n.e(6084).then(n.bind(n,86942)),"@site/blog/2023-1/2023-01-08-JSR-310.mdx",86942],"101cf32b":[()=>n.e(9239).then(n.t.bind(n,30880,19)),"~blog/default/page-45-7ec.json",30880],"1236fad7":[()=>n.e(6515).then(n.bind(n,38491)),"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx",38491],"1251d98b":[()=>n.e(6276).then(n.bind(n,40469)),"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",40469],"12cbeba7":[()=>n.e(6508).then(n.t.bind(n,16134,19)),"~blog/default/page-29-e3c.json",16134],"130df38c":[()=>n.e(6493).then(n.bind(n,83278)),"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",83278],"1398b403":[()=>n.e(5652).then(n.t.bind(n,93561,19)),"~blog/default/tags-retrospective-page-20-737.json",93561],14164549:[()=>n.e(7268).then(n.t.bind(n,11279,19)),"~blog/default/tags-book-baf-list.json",11279],"14dc1923":[()=>n.e(7403).then(n.bind(n,40742)),"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx",40742],"15eddcef":[()=>n.e(4209).then(n.t.bind(n,28539,19)),"~blog/default/page-47-adb.json",28539],"15f27552":[()=>n.e(1079).then(n.t.bind(n,11539,19)),"~blog/default/tags-retrospective-page-19-af8-list.json",11539],"1664646a":[()=>n.e(8036).then(n.bind(n,60367)),"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx?truncated=true",60367],"16cc6f3a":[()=>n.e(425).then(n.t.bind(n,12946,19)),"~blog/default/tags-retrospective-page-15-26b.json",12946],"16f719ab":[()=>n.e(9875).then(n.bind(n,3081)),"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx",3081],"1781b1c4":[()=>n.e(5785).then(n.bind(n,16865)),"@site/blog/2023-2/2023-05-25-\uc9c0\ud558\ucca0 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",16865],17896441:[()=>Promise.all([n.e(532),n.e(4926),n.e(7918)]).then(n.bind(n,78945)),"@theme/DocItem",78945],"1893cb59":[()=>n.e(286).then(n.t.bind(n,16269,19)),"~blog/default/tags-java-page-2-8c6.json",16269],"18c69d70":[()=>n.e(9171).then(n.t.bind(n,7085,19)),"/home/runner/work/greeng00se.github.io/greeng00se.github.io/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],"198f8d8a":[()=>n.e(9059).then(n.t.bind(n,17238,19)),"~blog/default/tags-java-page-3-b02-list.json",17238],"19f4ae8e":[()=>n.e(8161).then(n.t.bind(n,25680,19)),"~blog/default/tags-log-5ad.json",25680],"1a3abee6":[()=>n.e(5035).then(n.t.bind(n,87753,19)),"~blog/default/tags-retrospective-page-17-636.json",87753],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,39172)),"@theme/SearchPage",39172],"1a665c6f":[()=>n.e(454).then(n.t.bind(n,28767,19)),"~blog/default/tags-test-435-list.json",28767],"1a6b9123":[()=>n.e(9874).then(n.t.bind(n,14343,19)),"~blog/default/tags-teco-chat-page-3-007.json",14343],"1bb997fc":[()=>n.e(9713).then(n.t.bind(n,66014,19)),"~blog/default/page-44-cef.json",66014],"1c93669b":[()=>n.e(6526).then(n.t.bind(n,37579,19)),"~docs/default/tag-docs-tags-monitoring-149.json",37579],"1d81daa1":[()=>n.e(7681).then(n.t.bind(n,76725,19)),"~blog/default/tags-mock-330.json",76725],"1e8ecffe":[()=>n.e(3333).then(n.bind(n,58307)),"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx",58307],"1f05d14a":[()=>Promise.all([n.e(532),n.e(656)]).then(n.bind(n,9938)),"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx?truncated=true",9938],"1f61820a":[()=>n.e(2233).then(n.bind(n,74123)),"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx?truncated=true",74123],"1fbde614":[()=>n.e(8243).then(n.t.bind(n,87304,19)),"~blog/default/tags-monitoring-a8a-list.json",87304],"20e99c2a":[()=>n.e(3530).then(n.t.bind(n,19507,19)),"~blog/default/tags-documentation-ee3-list.json",19507],"211d6170":[()=>n.e(3109).then(n.t.bind(n,41078,19)),"~docs/default/tag-docs-tags-package-d2b.json",41078],"21294bbb":[()=>n.e(9412).then(n.bind(n,72794)),"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",72794],"21d253a0":[()=>n.e(1853).then(n.t.bind(n,63986,19)),"~blog/default/tags-woowahan-techcourse-page-10-f03-list.json",63986],"21e890b0":[()=>n.e(8288).then(n.t.bind(n,551,19)),"~blog/default/tags-retrospective-page-14-99d-list.json",551],"226700de":[()=>n.e(6035).then(n.t.bind(n,41961,19)),"~blog/default/page-25-52d.json",41961],"24b9bc70":[()=>n.e(5798).then(n.bind(n,58346)),"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx",58346],"255134d9":[()=>n.e(8151).then(n.t.bind(n,30753,19)),"~blog/default/tags-composite-240.json",30753],"269a2f75":[()=>n.e(1994).then(n.t.bind(n,52358,19)),"~blog/default/tags-static-b68.json",52358],"26dc40bf":[()=>n.e(5237).then(n.bind(n,55338)),"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx?truncated=true",55338],"270346fa":[()=>n.e(7975).then(n.t.bind(n,89424,19)),"~blog/default/page-28-907.json",89424],"274c9143":[()=>n.e(6984).then(n.t.bind(n,90058,19)),"~blog/default/tags-java-a6e.json",90058],"280572f1":[()=>n.e(324).then(n.t.bind(n,77874,19)),"~blog/default/tags-mysql-331.json",77874],"2832e534":[()=>n.e(2476).then(n.t.bind(n,69870,19)),"~blog/default/page-13-99f.json",69870],"28a1570f":[()=>n.e(448).then(n.t.bind(n,92252,19)),"~blog/default/tags-elastic-beanstalk-119.json",92252],"290b0a56":[()=>n.e(4212).then(n.bind(n,37260)),"@site/docs/Java/SequencedCollection.mdx",37260],"2a8faff0":[()=>n.e(7901).then(n.t.bind(n,1150,19)),"~blog/default/tags-test-435.json",1150],"2b22d492":[()=>n.e(7652).then(n.t.bind(n,56986,19)),"~blog/default/tags-retrospective-page-3-ee4-list.json",56986],"2b479afe":[()=>n.e(9591).then(n.t.bind(n,16973,19)),"~blog/default/tags-mockito-3c0-list.json",16973],"2bfe7c0b":[()=>n.e(1762).then(n.t.bind(n,82670,19)),"~blog/default/tags-book-page-2-bc6.json",82670],"2c446262":[()=>n.e(7797).then(n.t.bind(n,16402,19)),"~docs/default/tag-docs-tags-collection-64e.json",16402],"2c9f5501":[()=>n.e(7775).then(n.bind(n,75040)),"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx?truncated=true",75040],"2d3b202f":[()=>n.e(1196).then(n.t.bind(n,42524,19)),"~blog/default/tags-book-baf.json",42524],"2d9296e4":[()=>n.e(3483).then(n.t.bind(n,89429,19)),"~blog/default/tags-pattern-b4e.json",89429],"2e10a69c":[()=>n.e(7581).then(n.t.bind(n,9981,19)),"~blog/default/page-38-d34.json",9981],"2f43e44a":[()=>n.e(6743).then(n.t.bind(n,52396,19)),"~blog/default/tags-grasp-418-list.json",52396],"302370be":[()=>n.e(1883).then(n.bind(n,21779)),"@site/docs/\ud14c\uc2a4\ud2b8/FIRST.mdx",21779],"303c1e60":[()=>n.e(2656).then(n.t.bind(n,39529,19)),"~blog/default/tags-retrospective-page-4-3a3.json",39529],"309173fa":[()=>n.e(1793).then(n.t.bind(n,22684,19)),"~blog/default/tags-data-base-4e8-list.json",22684],"32397cb2":[()=>n.e(548).then(n.t.bind(n,22050,19)),"~blog/default/tags-awt-page-2-eb4-list.json",22050],"327fa616":[()=>n.e(3407).then(n.bind(n,79748)),"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx",79748],"32b2299c":[()=>n.e(970).then(n.t.bind(n,5280,19)),"~blog/default/page-41-fe1.json",5280],33736670:[()=>n.e(2742).then(n.t.bind(n,80700,19)),"~blog/default/tags-class-eca.json",80700],"35293ec4":[()=>n.e(7697).then(n.t.bind(n,14,19)),"~blog/default/page-20-038.json",14],"35b2eb5a":[()=>n.e(372).then(n.t.bind(n,97815,19)),"~blog/default/tags-java-page-5-b71-list.json",97815],"366ddb85":[()=>n.e(3691).then(n.bind(n,33751)),"@site/docs/\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30.mdx",33751],"3680bd07":[()=>n.e(5173).then(n.t.bind(n,2003,19)),"~blog/default/tags-web-application-b52.json",2003],"3720c009":[()=>Promise.all([n.e(532),n.e(3751)]).then(n.bind(n,10727)),"@theme/DocTagsListPage",10727],"372ccfe9":[()=>n.e(9111).then(n.bind(n,21063)),"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx?truncated=true",21063],"38bf29ad":[()=>n.e(1285).then(n.t.bind(n,26514,19)),"~docs/default/tag-docs-tags-load-balancing-180.json",26514],"38d8699e":[()=>n.e(471).then(n.t.bind(n,97481,19)),"~blog/default/page-15-208.json",97481],"3972c49f":[()=>n.e(6629).then(n.t.bind(n,91782,19)),"~blog/default/tags-web-socket-c6e-list.json",91782],"39ee6679":[()=>n.e(5717).then(n.t.bind(n,83636,19)),"~blog/default/tags-woowahan-techcourse-b50.json",83636],"3b0f99e8":[()=>n.e(3553).then(n.t.bind(n,20034,19)),"~blog/default/tags-jenkins-2e5.json",20034],"3b12d42b":[()=>n.e(8107).then(n.t.bind(n,50244,19)),"~docs/default/tag-docs-tags-java-ce1.json",50244],"3b18521e":[()=>n.e(2773).then(n.t.bind(n,8086,19)),"~blog/default/tags-mockito-3c0.json",8086],"3c5aea38":[()=>n.e(6250).then(n.t.bind(n,56516,19)),"~blog/default/tags-retrospective-page-12-8cf.json",56516],"3c9c1743":[()=>n.e(5900).then(n.t.bind(n,1353,19)),"~blog/default/tags-woowahan-techcourse-page-15-e2a-list.json",1353],"3d6c40c1":[()=>n.e(8509).then(n.t.bind(n,3440,19)),"~blog/default/tags-monitoring-a8a.json",3440],"3dd4d232":[()=>n.e(7727).then(n.bind(n,22195)),"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx",22195],"3ed04b60":[()=>n.e(7157).then(n.t.bind(n,84792,19)),"~blog/default/tags-spring-de1.json",84792],"3f6ea930":[()=>n.e(5186).then(n.bind(n,74818)),"@site/blog/2023-1/2023-02-12-Parameterized Tests.mdx",74818],"41b4728f":[()=>n.e(8628).then(n.t.bind(n,30171,19)),"~blog/default/tags-spring-boot-889-list.json",30171],"41c44b28":[()=>n.e(8106).then(n.bind(n,8819)),"@site/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd.mdx",8819],"42957a8d":[()=>n.e(9312).then(n.bind(n,62206)),"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx",62206],"43a97218":[()=>n.e(4815).then(n.t.bind(n,65215,19)),"~blog/default/tags-retrospective-page-5-22d-list.json",65215],"43fcf0e9":[()=>n.e(6468).then(n.t.bind(n,94822,19)),"~blog/default/tags-woowahan-techcourse-page-9-065.json",94822],"4430ab79":[()=>n.e(5553).then(n.t.bind(n,2750,19)),"~docs/default/tag-docs-tags-zero-downtime-b1f.json",2750],"4485017c":[()=>n.e(1906).then(n.bind(n,36169)),"@site/blog/2023-1/2023-03-14-\ube14\ub799\uc7ad \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",36169],"448c20a0":[()=>n.e(7680).then(n.bind(n,14079)),"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md",14079],"4515250b":[()=>n.e(9304).then(n.t.bind(n,88767,19)),"~blog/default/tags-exception-644-list.json",88767],"451db21d":[()=>n.e(1475).then(n.bind(n,71904)),"@site/docs/\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59.mdx",71904],"454a6d0d":[()=>n.e(4104).then(n.bind(n,98592)),"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx",98592],"489347ff":[()=>n.e(2793).then(n.t.bind(n,40526,19)),"~blog/default/tags-web-socket-c6e.json",40526],"48faf148":[()=>n.e(7328).then(n.bind(n,50973)),"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx?truncated=true",50973],"492a6565":[()=>n.e(9702).then(n.t.bind(n,44929,19)),"~blog/default/tags-lock-page-2-819-list.json",44929],"494882d1":[()=>n.e(4471).then(n.t.bind(n,2098,19)),"~blog/default/page-37-cb2.json",2098],"4959fc42":[()=>n.e(240).then(n.t.bind(n,80897,19)),"~blog/default/page-14-0a2.json",80897],"49b8d9dd":[()=>n.e(1103).then(n.t.bind(n,64420,19)),"~blog/default/tags-inno-db-59e.json",64420],"49f0f498":[()=>n.e(4433).then(n.t.bind(n,40719,19)),"~blog/default/tags-retrospective-page-16-226.json",40719],"4a1c8300":[()=>n.e(3324).then(n.bind(n,74122)),"@site/blog/2023-3/2023-08-19-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca83 \ud68c\uace0/2023-08-19-\ub808\ubca8 3 \ud68c\uace0.mdx",74122],"4b2fba3e":[()=>n.e(328).then(n.t.bind(n,98234,19)),"~blog/default/tags-image-page-3-942-list.json",98234],"4b79a3c9":[()=>Promise.all([n.e(532),n.e(5838)]).then(n.bind(n,261)),"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx",261],"4d43abad":[()=>n.e(3365).then(n.bind(n,79766)),"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx?truncated=true",79766],"5088fe06":[()=>n.e(80).then(n.t.bind(n,86819,19)),"~blog/default/tags-log-5ad-list.json",86819],"509d519c":[()=>n.e(743).then(n.t.bind(n,24469,19)),"/home/runner/work/greeng00se.github.io/greeng00se.github.io/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",24469],"52106a5f":[()=>n.e(9396).then(n.bind(n,68973)),"@site/blog/2023-1/2023-01-30-IntelliJ \uc124\uc815.mdx/index.mdx?truncated=true",68973],"530ffa4f":[()=>n.e(4818).then(n.bind(n,17804)),"@site/blog/2023-4/2023-10-31-\ub808\uac70\uc2dc \ucf54\ub4dc \ub9ac\ud329\ud130\ub9c1 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",17804],"533bfc57":[()=>n.e(5100).then(n.t.bind(n,4371,19)),"~blog/default/tags-retrospective-page-2-e2b-list.json",4371],"537817cb":[()=>n.e(3457).then(n.bind(n,75088)),"@site/blog/2023-1/2023-01-08-JSR-310.mdx?truncated=true",75088],"53e4509a":[()=>n.e(4722).then(n.t.bind(n,32259,19)),"~blog/default/page-46-6b3.json",32259],"54150be7":[()=>n.e(5088).then(n.t.bind(n,98707,19)),"~blog/default/tags-java-page-2-8c6-list.json",98707],"546ec22f":[()=>n.e(5635).then(n.t.bind(n,34223,19)),"~blog/default/tags-performance-test-2b7.json",34223],"54cb095e":[()=>n.e(7009).then(n.t.bind(n,95159,19)),"~blog/default/page-26-a44.json",95159],"55960ee5":[()=>n.e(4121).then(n.t.bind(n,88070,19)),"~docs/default/tags-list-current-prop-15a.json",88070],"562496aa":[()=>n.e(6161).then(n.t.bind(n,68146,19)),"~blog/default/tags-image-page-2-cc3.json",68146],"564337ec":[()=>n.e(5649).then(n.t.bind(n,8563,19)),"~blog/default/tags-retrospective-page-7-3e2-list.json",8563],"56e576e5":[()=>n.e(8262).then(n.t.bind(n,86556,19)),"~blog/default/tags-performance-test-2b7-list.json",86556],"5a29fbab":[()=>n.e(7857).then(n.t.bind(n,25381,19)),"~blog/default/tags-woowahan-techcourse-b50-list.json",25381],"5a473bed":[()=>n.e(9686).then(n.bind(n,52857)),"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",52857],"5a6c6934":[()=>n.e(5953).then(n.t.bind(n,48630,19)),"~blog/default/tags-dto-cb6.json",48630],"5c07bdab":[()=>n.e(6300).then(n.bind(n,50701)),"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",50701],"5c38e66e":[()=>n.e(5521).then(n.t.bind(n,28638,19)),"~blog/default/tags-woowahan-techcourse-page-10-f03.json",28638],"5d4cff52":[()=>n.e(1252).then(n.bind(n,88653)),"@site/blog/2023-4/2023-10-07-MVC \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",88653],"5e95c892":[()=>n.e(9661).then(n.bind(n,41892)),"@theme/DocsRoot",41892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,36809)),"@generated/docusaurus.config",36809],"5eed1665":[()=>n.e(8142).then(n.t.bind(n,19729,19)),"~blog/default/tags-lock-529-list.json",19729],"5f81b25c":[()=>n.e(4889).then(n.t.bind(n,29492,19)),"~blog/default/page-27-eb3.json",29492],"5feaaaeb":[()=>n.e(2967).then(n.t.bind(n,49978,19)),"~blog/default/tags-retrospective-page-20-737-list.json",49978],"5ffd2c10":[()=>n.e(2100).then(n.t.bind(n,86515,19)),"~docs/default/tag-docs-tags-jpa-c8c.json",86515],"6093f82b":[()=>n.e(6017).then(n.t.bind(n,30708,19)),"~blog/default/page-9-361.json",30708],"633582b9":[()=>n.e(2448).then(n.t.bind(n,32401,19)),"~blog/default/tags-kotlin-6ac.json",32401],"635a92d5":[()=>n.e(7891).then(n.t.bind(n,72126,19)),"~blog/default/page-24-fbb.json",72126],"6412e40a":[()=>n.e(5421).then(n.t.bind(n,97677,19)),"~blog/default/tags-woowahan-techcourse-page-12-5ba-list.json",97677],"6425a984":[()=>n.e(5467).then(n.t.bind(n,95377,19)),"~blog/default/tags-woowahan-techcourse-page-4-bcd-list.json",95377],"64868a43":[()=>n.e(1501).then(n.t.bind(n,33159,19)),"~blog/default/page-39-76c.json",33159],"64f377d6":[()=>n.e(732).then(n.t.bind(n,62898,19)),"~blog/default/tags-woowahan-techcourse-page-11-6c9-list.json",62898],"6552f31f":[()=>n.e(917).then(n.bind(n,84112)),"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx",84112],"6675e9ab":[()=>n.e(1255).then(n.bind(n,29218)),"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx",29218],"66d1c769":[()=>n.e(7476).then(n.t.bind(n,80122,19)),"~blog/default/tags-data-base-page-2-3a7-list.json",80122],"672a376b":[()=>n.e(2579).then(n.t.bind(n,41690,19)),"~blog/default/tags-woowahan-techcourse-page-8-93a.json",41690],"6875c492":[()=>Promise.all([n.e(532),n.e(4926),n.e(130),n.e(8610)]).then(n.bind(n,41714)),"@theme/BlogTagsPostsPage",41714],"69a75ff2":[()=>n.e(7181).then(n.t.bind(n,12761,19)),"~blog/default/page-48-ebc.json",12761],"69c28c32":[()=>n.e(1065).then(n.t.bind(n,99263,19)),"~blog/default/page-36-1da.json",99263],"6a19354d":[()=>n.e(693).then(n.t.bind(n,36232,19)),"~blog/default/tags-lock-529.json",36232],"6b4e1191":[()=>n.e(838).then(n.bind(n,88078)),"@site/docs/\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30.mdx",88078],"6b54f6a4":[()=>Promise.all([n.e(532),n.e(4558)]).then(n.bind(n,57211)),"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx?truncated=true",57211],"6b69808d":[()=>n.e(5990).then(n.bind(n,35703)),"@site/docs/JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551.mdx",35703],"6ba49b42":[()=>n.e(498).then(n.t.bind(n,64450,19)),"~blog/default/tags-test-page-2-d33-list.json",64450],"6bc709ad":[()=>n.e(9393).then(n.t.bind(n,81399,19)),"~blog/default/tags-retrospective-page-6-594-list.json",81399],"6c38e270":[()=>n.e(7247).then(n.t.bind(n,51914,19)),"~docs/default/tag-docs-tags-sequenced-12d.json",51914],"6c674d03":[()=>n.e(7600).then(n.t.bind(n,80372,19)),"~docs/default/tag-docs-tags-network-cb4.json",80372],"6cfe3a99":[()=>n.e(5319).then(n.t.bind(n,91227,19)),"~blog/default/tags-cloudwatch-6c7-list.json",91227],"6d4355d3":[()=>n.e(3122).then(n.t.bind(n,37438,19)),"~blog/default/tags-async-page-2-246.json",37438],"6dd1c948":[()=>n.e(7064).then(n.t.bind(n,76376,19)),"~blog/default/page-34-16c.json",76376],"6f385a52":[()=>n.e(6608).then(n.bind(n,54413)),"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx?truncated=true",54413],"70275fcd":[()=>n.e(7412).then(n.t.bind(n,81191,19)),"~blog/default/page-42-ca9.json",81191],70834889:[()=>n.e(7344).then(n.bind(n,56135)),"@site/blog/2023-3/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8/2023-09-10-\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx?truncated=true",56135],"70a12cc4":[()=>n.e(5682).then(n.t.bind(n,17085,19)),"~blog/default/tags-static-b68-list.json",17085],"7159c7ff":[()=>n.e(3287).then(n.bind(n,67219)),"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx?truncated=true",67219],"72657f57":[()=>n.e(9581).then(n.bind(n,32262)),"@site/blog/2023-2/2023-05-02-\uc6f9 \uc790\ub3d9\ucc28 \ubbf8\uc158 \ud68c\uace0.mdx",32262],"73688d5c":[()=>n.e(6908).then(n.bind(n,90465)),"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx?truncated=true",90465],"7405ea58":[()=>n.e(2345).then(n.t.bind(n,40702,19)),"~blog/default/tags-retrospective-page-11-e3c-list.json",40702],"75121fd5":[()=>n.e(5335).then(n.t.bind(n,30674,19)),"~blog/default/tags-image-97d.json",30674],"754fb852":[()=>n.e(988).then(n.t.bind(n,38242,19)),"~blog/default/page-32-596.json",38242],"75f50328":[()=>n.e(7511).then(n.t.bind(n,58695,19)),"~blog/default/tags-mysql-331-list.json",58695],"7762a24e":[()=>n.e(2753).then(n.t.bind(n,55095,19)),"~blog/default/page-4-365.json",55095],"77f5fc5d":[()=>n.e(3625).then(n.t.bind(n,32215,19)),"~blog/default/tags-retrospective-page-16-226-list.json",32215],"7881a85f":[()=>n.e(7108).then(n.t.bind(n,1855,19)),"~blog/default/page-51-74a.json",1855],"79a97f4e":[()=>n.e(6412).then(n.bind(n,13408)),"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx?truncated=true",13408],"7af1d52f":[()=>n.e(2334).then(n.t.bind(n,59565,19)),"~blog/default/page-6-d10.json",59565],"7bbc420e":[()=>n.e(4311).then(n.t.bind(n,41691,19)),"~blog/default/tags-documentation-ee3.json",41691],"7c660760":[()=>n.e(2087).then(n.t.bind(n,91870,19)),"~blog/default/tags-woowahan-techcourse-page-9-065-list.json",91870],"7e4c1ed7":[()=>n.e(1653).then(n.t.bind(n,83297,19)),"~docs/default/tag-docs-tags-postmortem-ede.json",83297],"7e59392d":[()=>n.e(7281).then(n.t.bind(n,33202,19)),"~blog/default/tags-retrospective-page-9-473-list.json",33202],"7fbacf84":[()=>n.e(5797).then(n.t.bind(n,58701,19)),"~blog/default/tags-spring-de1-list.json",58701],"7fd9a574":[()=>n.e(2889).then(n.t.bind(n,5863,19)),"~blog/default/tags-retrospective-page-14-99d.json",5863],"80960b4b":[()=>n.e(7599).then(n.t.bind(n,28386,19)),"~blog/default/page-21-7a8.json",28386],"814f3328":[()=>n.e(2535).then(n.t.bind(n,45641,19)),"~blog/default/blog-post-list-prop-default.json",45641],"829fa7b9":[()=>n.e(9391).then(n.bind(n,4565)),"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx",4565],"86b4da3d":[()=>n.e(952).then(n.t.bind(n,44149,19)),"~blog/default/tags-woowahan-techcourse-page-2-567.json",44149],"87070fc3":[()=>n.e(6124).then(n.bind(n,4679)),"@site/docs/\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8.mdx",4679],"871c1e5a":[()=>n.e(5966).then(n.t.bind(n,71247,19)),"~blog/default/page-23-651.json",71247],"8720c147":[()=>n.e(470).then(n.bind(n,75712)),"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx",75712],"8a24850b":[()=>n.e(741).then(n.bind(n,86331)),"@site/blog/2023-1/2023-03-31-\uccb4\uc2a4 \ubbf8\uc158 \ud68c\uace0.mdx",86331],"8a27aeff":[()=>n.e(71).then(n.bind(n,57041)),"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx?truncated=true",57041],"8ad2f007":[()=>n.e(8360).then(n.bind(n,6073)),"@site/blog/2023-3/2023-07-30-Mockito \uc774\uc6a9\ud574\uc11c static \uba54\uc11c\ub4dc \ubaa8\ud0b9\ud558\uae30.mdx?truncated=true",6073],"8b79a48d":[()=>n.e(9287).then(n.t.bind(n,59070,19)),"~blog/default/tags-retrospective-page-9-473.json",59070],"8c6c0796":[()=>n.e(2816).then(n.t.bind(n,59123,19)),"~blog/default/tags-retrospective-2fb.json",59123],"8d05b77c":[()=>n.e(4149).then(n.t.bind(n,22801,19)),"~blog/default/page-5-264.json",22801],"8d7288fe":[()=>n.e(4801).then(n.t.bind(n,71830,19)),"~blog/default/tags-class-eca-list.json",71830],"8da65e83":[()=>n.e(9427).then(n.t.bind(n,1341,19)),"~blog/default/tags-woowahan-techcourse-page-4-bcd.json",1341],"8dc09bac":[()=>n.e(8338).then(n.t.bind(n,28881,19)),"~blog/default/tags-event-f04-list.json",28881],"8e498bb6":[()=>n.e(1436).then(n.t.bind(n,50257,19)),"~blog/default/tags-java-page-3-b02.json",50257],"8e9dc6b3":[()=>n.e(7709).then(n.t.bind(n,65548,19)),"~blog/default/tags-web-application-b52-list.json",65548],"8fbd512b":[()=>n.e(5873).then(n.t.bind(n,15,19)),"~blog/default/tags-async-326.json",15],"905ecccc":[()=>Promise.all([n.e(532),n.e(2939)]).then(n.bind(n,76306)),"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",76306],"92ade856":[()=>Promise.all([n.e(532),n.e(1772)]).then(n.bind(n,31824)),"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx?truncated=true",31824],"92fef07b":[()=>n.e(300).then(n.bind(n,41632)),"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx",41632],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"96adae60":[()=>n.e(172).then(n.t.bind(n,54217,19)),"~blog/default/page-19-21b.json",54217],"981f7647":[()=>n.e(2947).then(n.bind(n,52070)),"@site/docs/\uc124\uacc4/\ud328\ud0a4\uc9c0.mdx",52070],"9b43eac8":[()=>n.e(9286).then(n.bind(n,8617)),"@site/blog/2023-1/2023-01-02-2022\ub144 \ud68c\uace0.mdx",8617],"9b56b618":[()=>n.e(9538).then(n.t.bind(n,37e3,19)),"~blog/default/tags-awt-0e2-list.json",37e3],"9bad5ae7":[()=>n.e(2153).then(n.bind(n,27555)),"@site/blog/2023-2/2023-04-07-InnoDB \uc2a4\ud1a0\ub9ac\uc9c0 \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx?truncated=true",27555],"9bbc65ac":[()=>n.e(7210).then(n.t.bind(n,51020,19)),"~docs/default/tag-docs-tags-test-8ab.json",51020],"9c6e5a12":[()=>n.e(2145).then(n.bind(n,81145)),"@site/docs/\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.mdx",81145],"9ca52986":[()=>n.e(3490).then(n.t.bind(n,92016,19)),"~blog/default/tags-lock-page-2-819.json",92016],"9cfe8fd1":[()=>n.e(7725).then(n.t.bind(n,97113,19)),"~blog/default/page-18-46d.json",97113],"9d1fd2b0":[()=>n.e(7972).then(n.bind(n,30138)),"@site/blog/2023-2/2023-06-11-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca82 \ud68c\uace0.mdx",30138],"9d8ee3a8":[()=>n.e(5962).then(n.t.bind(n,71297,19)),"~blog/default/tags-oop-03c.json",71297],"9dc4119a":[()=>n.e(6490).then(n.t.bind(n,4408,19)),"~blog/default/tags-retrospective-page-10-4a6-list.json",4408],"9dec6b67":[()=>n.e(8524).then(n.t.bind(n,88221,19)),"~blog/default/tags-data-base-page-2-3a7.json",88221],"9e2e3982":[()=>n.e(7617).then(n.bind(n,15448)),"@site/blog/2023-3/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd/2023-07-27-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uae30\uc220 \uc120\ud0dd.mdx",15448],"9e4087bc":[()=>n.e(3608).then(n.bind(n,63169)),"@theme/BlogArchivePage",63169],"9e4ad429":[()=>n.e(5406).then(n.t.bind(n,16060,19)),"~docs/default/tag-docs-tags-performance-339.json",16060],"9f586ca3":[()=>n.e(3673).then(n.t.bind(n,41912,19)),"~blog/default/tags-async-page-2-246-list.json",41912],"9fae68e2":[()=>n.e(297).then(n.t.bind(n,77536,19)),"~blog/default/tags-kotlin-6ac-list.json",77536],a0410ab5:[()=>n.e(7843).then(n.t.bind(n,76970,19)),"~blog/default/tags-retrospective-page-7-3e2.json",76970],a14ec7b5:[()=>n.e(3833).then(n.bind(n,44720)),"@site/docs/\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8.mdx",44720],a1877440:[()=>n.e(7648).then(n.t.bind(n,23235,19)),"~blog/default/tags-async-326-list.json",23235],a3614f73:[()=>n.e(8474).then(n.bind(n,15899)),"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx",15899],a3dddb77:[()=>n.e(475).then(n.t.bind(n,5479,19)),"~blog/default/tags-java-page-4-c22.json",5479],a4349a81:[()=>n.e(9623).then(n.t.bind(n,32318,19)),"~blog/default/tags-woowahan-techcourse-page-15-e2a.json",32318],a4a1e915:[()=>n.e(3671).then(n.t.bind(n,60166,19)),"~blog/default/tags-retrospective-2fb-list.json",60166],a539c018:[()=>n.e(5758).then(n.t.bind(n,99844,19)),"~blog/default/tags-woowahan-techcourse-page-16-b44.json",99844],a5557bb9:[()=>n.e(5991).then(n.t.bind(n,93885,19)),"~blog/default/index.json",93885],a59d28a9:[()=>n.e(2012).then(n.bind(n,63600)),"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx?truncated=true",63600],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(4926),n.e(130),n.e(3089)]).then(n.bind(n,80046)),"@theme/BlogListPage",80046],a710d533:[()=>Promise.all([n.e(532),n.e(1711)]).then(n.bind(n,42089)),"@site/blog/2023-3/2023-09-11-\ud1b0\ucea3 \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",42089],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a7e0d18f:[()=>n.e(3519).then(n.t.bind(n,59462,19)),"~docs/default/tag-docs-tags-spring-3d9.json",59462],a85e626a:[()=>n.e(9092).then(n.t.bind(n,48458,19)),"~blog/default/tags-jdbc-4bd.json",48458],a896be03:[()=>n.e(2526).then(n.t.bind(n,64030,19)),"~blog/default/tags-woowahan-techcourse-page-6-429.json",64030],a8cba70f:[()=>n.e(2261).then(n.bind(n,58367)),"@site/blog/2023-2/2023-04-01-\uc6b0\uc544\ud55c\ud14c\ud06c\ucf54\uc2a4 \ub808\ubca81 \ud68c\uace0.mdx?truncated=true",58367],a9221bd5:[()=>n.e(5507).then(n.t.bind(n,40319,19)),"~blog/default/tags-inno-db-59e-list.json",40319],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,12674)),"@theme/DocRoot",12674],a9c2b81a:[()=>n.e(2266).then(n.t.bind(n,52882,19)),"~blog/default/tags-woowahan-techcourse-page-16-b44-list.json",52882],aa73a035:[()=>n.e(5371).then(n.bind(n,54717)),"@site/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool.mdx",54717],aacfeabc:[()=>n.e(8909).then(n.bind(n,60965)),"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx?truncated=true",60965],abb0816f:[()=>n.e(4174).then(n.t.bind(n,82969,19)),"~blog/default/tags-woowahan-techcourse-page-7-5bd-list.json",82969],abc83b7f:[()=>n.e(2215).then(n.t.bind(n,8412,19)),"~blog/default/tags-retrospective-page-2-e2b.json",8412],ac23d7ee:[()=>n.e(3213).then(n.t.bind(n,43943,19)),"~blog/default/tags-woowahan-techcourse-page-3-9a8-list.json",43943],ac3fdf5d:[()=>n.e(8548).then(n.bind(n,40911)),"@site/blog/2023-3/2023-09-30-\uc6f9 \uc560\ud50c\ub9ac\ucf00\uc774\uc158 \ubc1c\uc804 \uacfc\uc815.mdx",40911],ad3b7b62:[()=>n.e(26).then(n.bind(n,76556)),"@site/blog/2023-2/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0/2023-05-12-\uc6f9 \uc7a5\ubc14\uad6c\ub2c8 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",76556],ae1d6508:[()=>n.e(2181).then(n.t.bind(n,83486,19)),"~blog/default/tags-composite-240-list.json",83486],ae3384b2:[()=>n.e(2965).then(n.t.bind(n,15745,19)),"/home/runner/work/greeng00se.github.io/greeng00se.github.io/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",15745],ae82353f:[()=>n.e(6420).then(n.bind(n,96046)),"@site/blog/2023-4/2023-10-03-\ud14c\uc2a4\ud2b8 \uaca9\ub9ac.md?truncated=true",96046],af81a133:[()=>n.e(7787).then(n.t.bind(n,13800,19)),"~blog/default/tags-teco-chat-d21.json",13800],b2b675dd:[()=>n.e(533).then(n.t.bind(n,28017,19)),"~blog/default/blog-c06.json",28017],b2c8756c:[()=>n.e(1213).then(n.bind(n,80936)),"@site/blog/2023-2/2023-06-04-\uc7a5\ubc14\uad6c\ub2c8 \uc8fc\ubb38 \ubbf8\uc158 \ud68c\uace0.mdx",80936],b2ebb6fd:[()=>n.e(4091).then(n.bind(n,8343)),"@site/blog/2023-2/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815/2023-04-30-Jenkins\ub85c \ubc30\ud3ec \uc790\ub3d9\ud654 \uc124\uc815.mdx",8343],b301b20b:[()=>n.e(3637).then(n.t.bind(n,83150,19)),"~blog/default/tags-replication-56b.json",83150],b36d2d1d:[()=>n.e(1257).then(n.t.bind(n,7903,19)),"~docs/default/tag-docs-tags-latency-735.json",7903],b41adc00:[()=>n.e(1391).then(n.bind(n,33849)),"@site/blog/2023-4/2023-10-10-Jdbc \uad6c\ud604 \ubbf8\uc158 \ud68c\uace0.mdx",33849],b421ebb7:[()=>n.e(9055).then(n.bind(n,37058)),"@site/docs/\uc131\ub2a5/Throughput\uacfc Latency.mdx",37058],b474adfe:[()=>n.e(573).then(n.t.bind(n,85419,19)),"~blog/default/tags-image-page-2-cc3-list.json",85419],b5f3dcc5:[()=>n.e(7723).then(n.t.bind(n,23005,19)),"~blog/default/tags-retrospective-page-15-26b-list.json",23005],b6ffb0cb:[()=>n.e(2156).then(n.bind(n,1738)),"@site/blog/2023-1/2023-02-14-\uc790\ub3d9\ucc28 \uacbd\uc8fc \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",1738],b7d33121:[()=>n.e(7153).then(n.t.bind(n,72005,19)),"~blog/default/tags-cloudwatch-6c7.json",72005],b88cb85b:[()=>n.e(2293).then(n.bind(n,95864)),"@site/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998.mdx",95864],b9bcab37:[()=>n.e(7688).then(n.t.bind(n,43632,19)),"~blog/default/tags-grasp-418.json",43632],bace0b37:[()=>n.e(2362).then(n.bind(n,10795)),"@site/blog/2023-2/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5/2023-05-24-\uc911\ubcf5\uacfc \uc6b0\ubc1c\uc801 \uc911\ubcf5.mdx",10795],bb221eab:[()=>n.e(711).then(n.bind(n,98886)),"@site/blog/2023-2/2023-04-04-\ud14c\uc2a4\ud2b8 \ub300\uc5ed.mdx?truncated=true",98886],bbc01ba0:[()=>n.e(3009).then(n.t.bind(n,12333,19)),"~blog/default/tags-retrospective-page-10-4a6.json",12333],bbc3f62a:[()=>n.e(8894).then(n.t.bind(n,51842,19)),"~blog/default/tags-woowahan-techcourse-page-13-8ae-list.json",51842],bbceb8f1:[()=>n.e(653).then(n.t.bind(n,26529,19)),"~blog/default/tags-woowahan-techcourse-page-5-ac5-list.json",26529],bbdd7e52:[()=>n.e(3396).then(n.bind(n,49725)),"@site/blog/2023-2/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604/2023-06-01-\ud14c\ucf54\ucc57 3. \uae30\ub2a5 \uad6c\ud604.mdx",49725],bd2d06b5:[()=>n.e(9763).then(n.t.bind(n,93081,19)),"~blog/default/tags-retrospective-page-3-ee4.json",93081],bd4db8ee:[()=>n.e(6883).then(n.bind(n,64855)),"@site/blog/2023-2/2023-04-05-\ud2b8\ub79c\uc7ad\uc158\uacfc \uaca9\ub9ac\uc218\uc900.mdx",64855],bd64a762:[()=>n.e(5463).then(n.bind(n,11365)),"@site/docs/\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870.mdx",11365],be497a8d:[()=>n.e(6172).then(n.bind(n,92971)),"@site/blog/2023-2/2023-06-18-Docusaurus/2023-06-18-Docusaurus.mdx?truncated=true",92971],bf933b37:[()=>n.e(3095).then(n.t.bind(n,52954,19)),"~blog/default/tags-my-sql-46a-list.json",52954],c037d168:[()=>n.e(6587).then(n.t.bind(n,41235,19)),"~blog/default/tags-transaction-ea3-list.json",41235],c08e7a0d:[()=>n.e(7404).then(n.t.bind(n,27625,19)),"~docs/default/tag-docs-tags-throughput-8fc.json",27625],c0cb7215:[()=>n.e(7966).then(n.t.bind(n,66109,19)),"~blog/default/tags-book-page-2-bc6-list.json",66109],c189d18f:[()=>n.e(4962).then(n.t.bind(n,3470,19)),"~docs/default/tag-docs-tags-etc-c52.json",3470],c1b17b3f:[()=>n.e(8927).then(n.bind(n,46681)),"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md",46681],c29bedb9:[()=>n.e(9242).then(n.t.bind(n,44025,19)),"~blog/default/page-35-8fd.json",44025],c3ea66fe:[()=>n.e(6698).then(n.t.bind(n,63504,19)),"~blog/default/tags-isolation-79d.json",63504],c4f5d8e4:[()=>n.e(4195).then(n.bind(n,62841)),"@site/src/pages/index.js",62841],c55d205b:[()=>n.e(3438).then(n.bind(n,36712)),"@site/docs/Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4.mdx",36712],c573638f:[()=>n.e(964).then(n.t.bind(n,28866,19)),"~blog/default/tags-tags-c2b.json",28866],c6004f62:[()=>n.e(5892).then(n.t.bind(n,37567,19)),"~blog/default/tags-mock-330-list.json",37567],c60995f6:[()=>n.e(6199).then(n.t.bind(n,62474,19)),"~docs/default/tag-docs-tags-nginx-3b7.json",62474],c60ea0ff:[()=>n.e(3085).then(n.t.bind(n,14072,19)),"~blog/default/tags-teco-chat-page-2-d4f.json",14072],c6b037a5:[()=>n.e(3137).then(n.t.bind(n,4030,19)),"~blog/default/tags-woowahan-techcourse-page-14-c67.json",4030],c6d04683:[()=>n.e(5436).then(n.bind(n,29316)),"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx",29316],c7015929:[()=>n.e(4185).then(n.t.bind(n,910,19)),"~blog/default/tags-python-687.json",910],c92f81ac:[()=>n.e(4393).then(n.t.bind(n,10767,19)),"~blog/default/tags-replication-56b-list.json",10767],caf1b628:[()=>n.e(7230).then(n.bind(n,36721)),"@site/docs/\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1.mdx",36721],cb6229c3:[()=>n.e(7204).then(n.bind(n,95940)),"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx",95940],cc3bdf2f:[()=>n.e(8817).then(n.t.bind(n,11135,19)),"~blog/default/tags-exception-644.json",11135],cc519f63:[()=>n.e(5323).then(n.bind(n,75824)),"@site/blog/2023-3/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604/2023-08-02-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \uad6c\ud604.mdx",75824],ccc49370:[()=>Promise.all([n.e(532),n.e(4926),n.e(130),n.e(6103)]).then(n.bind(n,65203)),"@theme/BlogPostPage",65203],cd68cda1:[()=>n.e(8683).then(n.bind(n,2915)),"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx?truncated=true",2915],cec43d6a:[()=>n.e(1358).then(n.bind(n,41056)),"@site/docs/\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c.mdx",41056],cef46b76:[()=>n.e(8644).then(n.bind(n,91704)),"@site/blog/2023-3/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c/2023-07-31-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ud30c\uc774\uc36c.mdx",91704],cf8e491a:[()=>n.e(5870).then(n.t.bind(n,19799,19)),"~blog/default/tags-awt-0e2.json",19799],d0277431:[()=>n.e(846).then(n.t.bind(n,4838,19)),"~blog/default/tags-dto-cb6-list.json",4838],d0840b01:[()=>n.e(8037).then(n.t.bind(n,20317,19)),"~blog/default/tags-transaction-ea3.json",20317],d09f7e4b:[()=>n.e(3098).then(n.t.bind(n,84057,19)),"~blog/default/tags-teco-chat-page-3-007-list.json",84057],d0e4cdf1:[()=>n.e(5465).then(n.t.bind(n,64020,19)),"~blog/default/page-7-3c3.json",64020],d126aabd:[()=>n.e(1675).then(n.t.bind(n,7220,19)),"~blog/default/tags-retrospective-page-4-3a3-list.json",7220],d1cef389:[()=>n.e(9310).then(n.t.bind(n,40836,19)),"~blog/default/page-17-62c.json",40836],d1e1bea4:[()=>n.e(7945).then(n.bind(n,32228)),"@site/docs/MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd.md",32228],d202e2c5:[()=>n.e(7175).then(n.t.bind(n,3395,19)),"~blog/default/tags-oop-03c-list.json",3395],d2611248:[()=>n.e(8561).then(n.t.bind(n,81667,19)),"~blog/default/page-43-b0a.json",81667],d2770bf7:[()=>n.e(843).then(n.t.bind(n,41156,19)),"~blog/default/tags-woowahan-techcourse-page-11-6c9.json",41156],d28e30d7:[()=>Promise.all([n.e(532),n.e(6671)]).then(n.bind(n,70633)),"@site/blog/2023-1/2023-01-16-Kotlin\uc5d0\uc11c null\uc744 \ub2e4\ub8e8\ub294 \ubc29\ubc95.mdx",70633],d2935d14:[()=>n.e(3259).then(n.t.bind(n,92158,19)),"~blog/default/tags-isolation-79d-list.json",92158],d350f5d9:[()=>n.e(2098).then(n.t.bind(n,82622,19)),"~blog/default/tags-test-page-2-d33.json",82622],d361ad2d:[()=>n.e(2247).then(n.bind(n,14448)),"@site/docs/\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12.mdx",14448],d368e73e:[()=>n.e(7954).then(n.t.bind(n,71965,19)),"~blog/default/tags-image-97d-list.json",71965],d40f51e1:[()=>n.e(9633).then(n.t.bind(n,9415,19)),"~blog/default/tags-jdbc-4bd-list.json",9415],d50fd269:[()=>n.e(100).then(n.t.bind(n,38132,19)),"~blog/default/page-31-308.json",38132],d5bb232a:[()=>n.e(3651).then(n.bind(n,46116)),"@site/blog/2023-2/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30/2023-05-26-\ucef4\ud3ec\uc9c0\ud2b8 \ud328\ud134\uc73c\ub85c \uc694\uae08 \uc815\ucc45 \ucd94\uc0c1\ud654\ud558\uae30.mdx?truncated=true",46116],d5dfecc2:[()=>n.e(1677).then(n.t.bind(n,83335,19)),"~blog/default/tags-teco-chat-page-2-d4f-list.json",83335],d60e2b0c:[()=>n.e(8174).then(n.t.bind(n,36927,19)),"~blog/default/tags-retrospective-page-17-636-list.json",36927],d65e25b7:[()=>Promise.all([n.e(532),n.e(7776)]).then(n.bind(n,60626)),"@site/blog/2023-3/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac/2023-08-13-\uacbd\ub85c \uc774\ubbf8\uc9c0 \uc0dd\uc131\ud558\uae30 - \ube44\ub3d9\uae30 \ucc98\ub9ac.mdx?truncated=true",60626],d6638f30:[()=>n.e(3476).then(n.bind(n,36022)),"@site/docs/\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec.mdx",36022],d6a3d698:[()=>n.e(2890).then(n.t.bind(n,39477,19)),"~blog/default/tags-image-page-3-942.json",39477],d7955594:[()=>Promise.all([n.e(532),n.e(588)]).then(n.bind(n,18751)),"@site/blog/2023-2/2023-04-02-\ucee4\uc2a4\ud140 JdbcTemplate \ub9cc\ub4e4\uae30.mdx",18751],d86f7a37:[()=>n.e(3392).then(n.bind(n,98034)),"@site/docs/Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5.mdx",98034],d8775059:[()=>n.e(6387).then(n.bind(n,33604)),"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx",33604],d88bdb28:[()=>n.e(9788).then(n.t.bind(n,29417,19)),"~blog/default/tags-retrospective-page-13-49c.json",29417],d8cdf5ef:[()=>n.e(5919).then(n.bind(n,79101)),"@site/docs/\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8.mdx",79101],da14f319:[()=>n.e(5485).then(n.bind(n,96893)),"@site/docs/\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5.md",96893],dab4c683:[()=>n.e(6058).then(n.t.bind(n,67315,19)),"~blog/default/tags-woowahan-techcourse-page-3-9a8.json",67315],daff1d93:[()=>n.e(1659).then(n.bind(n,99239)),"@site/blog/2023-2/2023-04-08-\uc0c1\uc790 \ubc16\uc5d0 \uc788\ub294 \uc0ac\ub78c.mdx?truncated=true",99239],db7928b3:[()=>n.e(5046).then(n.t.bind(n,11478,19)),"~blog/default/tags-intelli-j-2bf-list.json",11478],db86613e:[()=>n.e(9458).then(n.bind(n,82549)),"@site/blog/2023-2/2023-04-06-MySQL \uc5d4\uc9c4\uc758 \uc7a0\uae08.mdx?truncated=true",82549],dca6a1e3:[()=>n.e(3239).then(n.bind(n,25386)),"@site/blog/2023-2/2023-06-08-\ub808\ubca8 2 - \ub808\ubca8 \uc778\ud130\ubdf0 \ud68c\uace0.mdx?truncated=true",25386],dcf70953:[()=>n.e(1761).then(n.t.bind(n,83769,19)),"/home/runner/work/greeng00se.github.io/greeng00se.github.io/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",83769],ddf9e0bd:[()=>n.e(2542).then(n.t.bind(n,84039,19)),"~blog/default/tags-woowahan-techcourse-page-8-93a-list.json",84039],df147deb:[()=>n.e(5103).then(n.bind(n,43420)),"@site/blog/2023-1/2023-02-26-\uc0ac\ub2e4\ub9ac \ud0c0\uae30 \ubbf8\uc158 \ud68c\uace0.mdx?truncated=true",43420],df203c0f:[()=>Promise.all([n.e(532),n.e(9924)]).then(n.bind(n,40491)),"@theme/DocTagDocListPage",40491],df862072:[()=>n.e(7474).then(n.t.bind(n,24827,19)),"~blog/default/tags-book-page-3-a93.json",24827],dfa84138:[()=>n.e(1434).then(n.t.bind(n,22483,19)),"~blog/default/tags-data-base-page-3-9db-list.json",22483],dfc7013c:[()=>n.e(5857).then(n.bind(n,10032)),"@site/blog/2023-2/2023-04-03-\uc790\ubc14 \ud074\ub798\uc2a4\ud30c\uc77c \uad6c\uc870.mdx?truncated=true",10032],e073eb07:[()=>n.e(5819).then(n.t.bind(n,57743,19)),"~blog/default/tags-retrospective-page-11-e3c.json",57743],e0d68441:[()=>n.e(628).then(n.t.bind(n,75301,19)),"~blog/default/tags-retrospective-page-12-8cf-list.json",75301],e0e4666e:[()=>n.e(4665).then(n.t.bind(n,16482,19)),"~blog/default/tags-my-sql-46a.json",16482],e1735da7:[()=>n.e(1611).then(n.bind(n,79784)),"@site/blog/2023-2/2023-05-01-\ud14c\ucf54\ucc57 2. \ubc30\ud3ec.mdx?truncated=true",79784],e1a06456:[()=>n.e(9910).then(n.bind(n,54885)),"@site/blog/2023-2/2023-06-26-WebSocket.mdx",54885],e21c8cc4:[()=>n.e(6049).then(n.t.bind(n,48765,19)),"~blog/default/tags-retrospective-page-8-5ab.json",48765],e2326195:[()=>n.e(9467).then(n.bind(n,45682)),"@site/blog/2023-3/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac/2023-09-18-\ube44\ub3d9\uae30 \uc608\uc678 \ucc98\ub9ac.mdx",45682],e2de2dbb:[()=>n.e(6710).then(n.t.bind(n,47023,19)),"~blog/default/tags-java-page-5-b71.json",47023],e4ebfe18:[()=>n.e(9940).then(n.t.bind(n,57954,19)),"~blog/default/page-3-02e.json",57954],e5e44a85:[()=>n.e(1253).then(n.t.bind(n,42310,19)),"~docs/default/tag-docs-tags-deploy-f3b.json",42310],e6a6ed43:[()=>n.e(5300).then(n.bind(n,66940)),"@site/blog/2023-1/2023-03-30-GRASP.mdx?truncated=true",66940],e6e259a5:[()=>n.e(3771).then(n.bind(n,9801)),"@site/docs/\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815.md",9801],e7d2a655:[()=>n.e(8652).then(n.t.bind(n,71501,19)),"~blog/default/tags-woowahan-techcourse-page-2-567-list.json",71501],e8d6e7ce:[()=>n.e(3912).then(n.t.bind(n,65245,19)),"~blog/default/tags-retrospective-page-6-594.json",65245],e9624b4f:[()=>n.e(4564).then(n.t.bind(n,11780,19)),"~blog/default/tags-retrospective-page-13-49c-list.json",11780],e9eabc5d:[()=>n.e(1112).then(n.bind(n,40376)),"@site/blog/2023-1/2023-03-30-GRASP.mdx",40376],e9ff60ad:[()=>n.e(2530).then(n.t.bind(n,10242,19)),"~blog/default/tags-pattern-b4e-list.json",10242],eae2a611:[()=>n.e(6180).then(n.bind(n,47599)),"@site/docs/\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98.mdx",47599],ee1dd2ad:[()=>n.e(5435).then(n.t.bind(n,48834,19)),"~blog/default/tags-woowahan-techcourse-page-13-8ae.json",48834],ee92877e:[()=>n.e(8716).then(n.t.bind(n,41106,19)),"~blog/default/tags-retrospective-page-5-22d.json",41106],eec33099:[()=>n.e(4953).then(n.t.bind(n,80133,19)),"~blog/default/page-40-397.json",80133],ef5b2427:[()=>n.e(9606).then(n.t.bind(n,50195,19)),"~blog/default/page-22-f33.json",50195],eff1d58f:[()=>n.e(4137).then(n.bind(n,68801)),"@site/blog/2023-2/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30/2023-04-22-\ud14c\ucf54\ucc57 1. \ud504\ub85c\ud1a0\ud0c0\uc785 \ub9cc\ub4e4\uae30.mdx?truncated=true",68801],f01ceada:[()=>n.e(724).then(n.t.bind(n,62563,19)),"~blog/default/page-50-0b0.json",62563],f042b56c:[()=>n.e(8919).then(n.t.bind(n,27490,19)),"~blog/default/tags-teco-chat-d21-list.json",27490],f06cb3e2:[()=>Promise.all([n.e(532),n.e(2620)]).then(n.bind(n,43487)),"@site/blog/2023-3/2023-08-22-DB \ubcf5\uc81c, @Transactional\uc5d0 \ub530\ub77c \uc694\uccad \ubd84\ub9ac\ud574\ubcf4\uae30.mdx",43487],f078e301:[()=>n.e(1926).then(n.t.bind(n,18385,19)),"~blog/default/tags-woowahan-techcourse-page-6-429-list.json",18385],f0978ee1:[()=>n.e(7740).then(n.t.bind(n,69366,19)),"~blog/default/tags-awt-page-2-eb4.json",69366],f156dfb9:[()=>n.e(5602).then(n.t.bind(n,83311,19)),"~blog/default/tags-time-471.json",83311],f25de701:[()=>n.e(2245).then(n.bind(n,45414)),"@site/blog/2023-3/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131/2023-08-17-CloudWatch\ub97c \uc774\uc6a9\ud55c \ub85c\uae45, \uba54\ud2b8\ub9ad \ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131.md?truncated=true",45414],f332d221:[()=>n.e(2717).then(n.t.bind(n,99371,19)),"~blog/default/page-10-857.json",99371],f3493919:[()=>n.e(8476).then(n.bind(n,30169)),"@site/docs/\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30.mdx",30169],f3e308ad:[()=>n.e(6123).then(n.t.bind(n,16240,19)),"~blog/default/page-33-758.json",16240],f4c6e7e6:[()=>n.e(31).then(n.t.bind(n,77922,19)),"~docs/default/tag-docs-tags-book-8e4.json",77922],f4f49e13:[()=>n.e(6887).then(n.t.bind(n,26329,19)),"~blog/default/page-12-b6a.json",26329],f580a9d0:[()=>n.e(9887).then(n.t.bind(n,78989,19)),"~blog/default/tags-python-687-list.json",78989],f63a747b:[()=>n.e(5131).then(n.t.bind(n,81723,19)),"~blog/default/tags-woowahan-techcourse-page-7-5bd.json",81723],f6807fb4:[()=>n.e(4788).then(n.t.bind(n,39836,19)),"~docs/default/tag-docs-tags-architecture-68d.json",39836],f75a8651:[()=>n.e(8882).then(n.t.bind(n,44633,19)),"~blog/default/page-8-8c2.json",44633],f7b9d2f4:[()=>n.e(2958).then(n.t.bind(n,53122,19)),"~blog/default/tags-woowahan-techcourse-page-12-5ba.json",53122],f8409a7e:[()=>n.e(3206).then(n.bind(n,29325)),"@site/docs/intro.mdx",29325],f87bdf62:[()=>n.e(6750).then(n.bind(n,52449)),"@site/blog/2023-2/2023-06-26-WebSocket.mdx?truncated=true",52449],f90d0c52:[()=>n.e(5294).then(n.bind(n,47522)),"@site/blog/2023-1/2023-01-07-\uac1d\uccb4\uc9c0\ud5a5\uc758 \uc0ac\uc2e4\uacfc \uc624\ud574.mdx",47522],fa3d3942:[()=>n.e(916).then(n.bind(n,28227)),"@site/blog/2023-1/2023-01-01-\uae00, \uc6b0\ub9ac\ub3c4 \uc798 \uc4f8 \uc218 \uc788\uc2b5\ub2c8\ub2e4.mdx",28227],fb48356a:[()=>n.e(9534).then(n.t.bind(n,78215,19)),"~blog/default/tags-retrospective-page-18-40f-list.json",78215],fb861301:[()=>n.e(7563).then(n.t.bind(n,17036,19)),"~blog/default/tags-woowahan-techcourse-page-14-c67-list.json",17036],fbd57548:[()=>n.e(6837).then(n.t.bind(n,30990,19)),"~blog/default/page-11-f65.json",30990],fd5d2408:[()=>n.e(3614).then(n.t.bind(n,64631,19)),"~blog/default/tags-time-471-list.json",64631],fe273484:[()=>n.e(8355).then(n.t.bind(n,53034,19)),"~blog/default/tags-java-a6e-list.json",53034],fe8cce0a:[()=>n.e(955).then(n.t.bind(n,78535,19)),"~blog/default/tags-intelli-j-2bf.json",78535],fed8bc04:[()=>n.e(8110).then(n.t.bind(n,96375,19)),"~blog/default/tags-woowahan-techcourse-page-5-ac5.json",96375],ff4c6c5e:[()=>n.e(820).then(n.bind(n,68007)),"@site/blog/2023-3/2023-07-24-\uc790\ubc14 17, \uc2a4\ud504\ub9c1 6.0, \uc2a4\ud504\ub9c1 \ubd80\ud2b8 3.1.mdx",68007],ffb0fa11:[()=>n.e(7400).then(n.t.bind(n,58214,19)),"~blog/default/tags-book-page-3-a93-list.json",58214]};var s=n(85893);function l(e){let{error:t,retry:n,pastDelay:a}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):a?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var c=n(99670),u=n(30226);function d(e,t){if("*"===e)return r()({loading:l,loader:()=>n.e(7856).then(n.bind(n,51772)),modules:["@theme/NotFound"],webpack:()=>[51772],render(e,t){const n=e.default;return(0,s.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const a=o[`${e}-${t}`],d={},p=[],f=[],g=(0,c.Z)(a);return Object.entries(g).forEach((e=>{let[t,n]=e;const a=i[n];a&&(d[t]=a[0],p.push(a[1]),f.push(a[2]))})),r().Map({loading:l,loader:d,modules:p,webpack:()=>f,render(t,n){const r=JSON.parse(JSON.stringify(a));Object.entries(t).forEach((t=>{let[n,a]=t;const o=a.default;if(!o)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof o&&"function"!=typeof o||Object.keys(a).filter((e=>"default"!==e)).forEach((e=>{o[e]=a[e]}));let i=r;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=o}));const o=r.__comp;delete r.__comp;const i=r.__context;return delete r.__context,(0,s.jsx)(u.z,{value:i,children:(0,s.jsx)(o,{...r,...n})})}})}const p=[{path:"/2022-retrospective",component:d("/2022-retrospective","624"),exact:!0},{path:"/accidental-duplication",component:d("/accidental-duplication","d17"),exact:!0},{path:"/blackjack-retrospective",component:d("/blackjack-retrospective","595"),exact:!0},{path:"/blog",component:d("/blog","3d8"),exact:!0},{path:"/book-leadership-and-self-deception",component:d("/book-leadership-and-self-deception","ddd"),exact:!0},{path:"/book-writer",component:d("/book-writer","3c9"),exact:!0},{path:"/chess-retrospective",component:d("/chess-retrospective","168"),exact:!0},{path:"/cloudwatch",component:d("/cloudwatch","cb1"),exact:!0},{path:"/composite",component:d("/composite","302"),exact:!0},{path:"/custom-jdbc-template",component:d("/custom-jdbc-template","cfa"),exact:!0},{path:"/db-replication",component:d("/db-replication","6f2"),exact:!0},{path:"/docusaurus",component:d("/docusaurus","926"),exact:!0},{path:"/grasp",component:d("/grasp","f9b"),exact:!0},{path:"/innodb-lock",component:d("/innodb-lock","d18"),exact:!0},{path:"/intellij-settings",component:d("/intellij-settings","80e"),exact:!0},{path:"/java-class-file",component:d("/java-class-file","50e"),exact:!0},{path:"/java-spring-springboot",component:d("/java-spring-springboot","bed"),exact:!0},{path:"/jdbc-retrospective",component:d("/jdbc-retrospective","158"),exact:!0},{path:"/jenkins",component:d("/jenkins","48c"),exact:!0},{path:"/jsr-310",component:d("/jsr-310","7f9"),exact:!0},{path:"/kotlin-null",component:d("/kotlin-null","8d3"),exact:!0},{path:"/ladder-retrospective",component:d("/ladder-retrospective","7ea"),exact:!0},{path:"/level2-interview-retrospective",component:d("/level2-interview-retrospective","c75"),exact:!0},{path:"/log-async-exception",component:d("/log-async-exception","a44"),exact:!0},{path:"/mock-static-method",component:d("/mock-static-method","fd3"),exact:!0},{path:"/mvc-retrospective",component:d("/mvc-retrospective","96d"),exact:!0},{path:"/mysql-lock",component:d("/mysql-lock","3cb"),exact:!0},{path:"/order-retrospective",component:d("/order-retrospective","a11"),exact:!0},{path:"/page/10",component:d("/page/10","c2c"),exact:!0},{path:"/page/11",component:d("/page/11","89b"),exact:!0},{path:"/page/12",component:d("/page/12","155"),exact:!0},{path:"/page/13",component:d("/page/13","ece"),exact:!0},{path:"/page/14",component:d("/page/14","1f9"),exact:!0},{path:"/page/15",component:d("/page/15","cc0"),exact:!0},{path:"/page/16",component:d("/page/16","813"),exact:!0},{path:"/page/17",component:d("/page/17","843"),exact:!0},{path:"/page/18",component:d("/page/18","84a"),exact:!0},{path:"/page/19",component:d("/page/19","e4e"),exact:!0},{path:"/page/2",component:d("/page/2","256"),exact:!0},{path:"/page/20",component:d("/page/20","30e"),exact:!0},{path:"/page/21",component:d("/page/21","553"),exact:!0},{path:"/page/22",component:d("/page/22","a88"),exact:!0},{path:"/page/23",component:d("/page/23","edf"),exact:!0},{path:"/page/24",component:d("/page/24","915"),exact:!0},{path:"/page/25",component:d("/page/25","4aa"),exact:!0},{path:"/page/26",component:d("/page/26","ec5"),exact:!0},{path:"/page/27",component:d("/page/27","339"),exact:!0},{path:"/page/28",component:d("/page/28","376"),exact:!0},{path:"/page/29",component:d("/page/29","ea0"),exact:!0},{path:"/page/3",component:d("/page/3","d5c"),exact:!0},{path:"/page/30",component:d("/page/30","2ff"),exact:!0},{path:"/page/31",component:d("/page/31","d32"),exact:!0},{path:"/page/32",component:d("/page/32","02d"),exact:!0},{path:"/page/33",component:d("/page/33","3d4"),exact:!0},{path:"/page/34",component:d("/page/34","4d2"),exact:!0},{path:"/page/35",component:d("/page/35","b81"),exact:!0},{path:"/page/36",component:d("/page/36","598"),exact:!0},{path:"/page/37",component:d("/page/37","eda"),exact:!0},{path:"/page/38",component:d("/page/38","9cf"),exact:!0},{path:"/page/39",component:d("/page/39","27d"),exact:!0},{path:"/page/4",component:d("/page/4","b0c"),exact:!0},{path:"/page/40",component:d("/page/40","744"),exact:!0},{path:"/page/41",component:d("/page/41","793"),exact:!0},{path:"/page/42",component:d("/page/42","0ee"),exact:!0},{path:"/page/43",component:d("/page/43","345"),exact:!0},{path:"/page/44",component:d("/page/44","3c4"),exact:!0},{path:"/page/45",component:d("/page/45","6e5"),exact:!0},{path:"/page/46",component:d("/page/46","d10"),exact:!0},{path:"/page/47",component:d("/page/47","280"),exact:!0},{path:"/page/48",component:d("/page/48","8df"),exact:!0},{path:"/page/49",component:d("/page/49","282"),exact:!0},{path:"/page/5",component:d("/page/5","87c"),exact:!0},{path:"/page/50",component:d("/page/50","3c4"),exact:!0},{path:"/page/51",component:d("/page/51","658"),exact:!0},{path:"/page/6",component:d("/page/6","a58"),exact:!0},{path:"/page/7",component:d("/page/7","bb8"),exact:!0},{path:"/page/8",component:d("/page/8","2f3"),exact:!0},{path:"/page/9",component:d("/page/9","88d"),exact:!0},{path:"/parameterized-tests",component:d("/parameterized-tests","1fb"),exact:!0},{path:"/performance-test-type",component:d("/performance-test-type","df3"),exact:!0},{path:"/racing-car-retrospective",component:d("/racing-car-retrospective","ebc"),exact:!0},{path:"/refactoring-retrospective",component:d("/refactoring-retrospective","ab4"),exact:!0},{path:"/route-image-async-with-event",component:d("/route-image-async-with-event","832"),exact:!0},{path:"/route-image-implementation",component:d("/route-image-implementation","b0f"),exact:!0},{path:"/route-image-intro",component:d("/route-image-intro","7e7"),exact:!0},{path:"/route-image-python",component:d("/route-image-python","dfd"),exact:!0},{path:"/search",component:d("/search","c1e"),exact:!0},{path:"/shopping-cart-retrospective",component:d("/shopping-cart-retrospective","28b"),exact:!0},{path:"/spring-test-isolation",component:d("/spring-test-isolation","8ed"),exact:!0},{path:"/subway-retrospective",component:d("/subway-retrospective","7db"),exact:!0},{path:"/tags",component:d("/tags","4bf"),exact:!0},{path:"/tags/async",component:d("/tags/async","a21"),exact:!0},{path:"/tags/async/page/2",component:d("/tags/async/page/2","436"),exact:!0},{path:"/tags/awt",component:d("/tags/awt","9e3"),exact:!0},{path:"/tags/awt/page/2",component:d("/tags/awt/page/2","b68"),exact:!0},{path:"/tags/book",component:d("/tags/book","4df"),exact:!0},{path:"/tags/book/page/2",component:d("/tags/book/page/2","88a"),exact:!0},{path:"/tags/book/page/3",component:d("/tags/book/page/3","128"),exact:!0},{path:"/tags/class",component:d("/tags/class","d3d"),exact:!0},{path:"/tags/cloudwatch",component:d("/tags/cloudwatch","264"),exact:!0},{path:"/tags/composite",component:d("/tags/composite","931"),exact:!0},{path:"/tags/data-base",component:d("/tags/data-base","2fe"),exact:!0},{path:"/tags/data-base/page/2",component:d("/tags/data-base/page/2","049"),exact:!0},{path:"/tags/data-base/page/3",component:d("/tags/data-base/page/3","9ac"),exact:!0},{path:"/tags/documentation",component:d("/tags/documentation","86d"),exact:!0},{path:"/tags/dto",component:d("/tags/dto","bef"),exact:!0},{path:"/tags/elastic-beanstalk",component:d("/tags/elastic-beanstalk","164"),exact:!0},{path:"/tags/event",component:d("/tags/event","56a"),exact:!0},{path:"/tags/exception",component:d("/tags/exception","5b1"),exact:!0},{path:"/tags/grasp",component:d("/tags/grasp","130"),exact:!0},{path:"/tags/image",component:d("/tags/image","067"),exact:!0},{path:"/tags/image/page/2",component:d("/tags/image/page/2","88a"),exact:!0},{path:"/tags/image/page/3",component:d("/tags/image/page/3","acc"),exact:!0},{path:"/tags/inno-db",component:d("/tags/inno-db","2aa"),exact:!0},{path:"/tags/intelli-j",component:d("/tags/intelli-j","aaa"),exact:!0},{path:"/tags/isolation",component:d("/tags/isolation","bab"),exact:!0},{path:"/tags/java",component:d("/tags/java","60d"),exact:!0},{path:"/tags/java/page/2",component:d("/tags/java/page/2","d9f"),exact:!0},{path:"/tags/java/page/3",component:d("/tags/java/page/3","d2c"),exact:!0},{path:"/tags/java/page/4",component:d("/tags/java/page/4","c97"),exact:!0},{path:"/tags/java/page/5",component:d("/tags/java/page/5","6c7"),exact:!0},{path:"/tags/jdbc",component:d("/tags/jdbc","667"),exact:!0},{path:"/tags/jenkins",component:d("/tags/jenkins","590"),exact:!0},{path:"/tags/kotlin",component:d("/tags/kotlin","b84"),exact:!0},{path:"/tags/lock",component:d("/tags/lock","059"),exact:!0},{path:"/tags/lock/page/2",component:d("/tags/lock/page/2","2e3"),exact:!0},{path:"/tags/log",component:d("/tags/log","0ae"),exact:!0},{path:"/tags/mock",component:d("/tags/mock","9dd"),exact:!0},{path:"/tags/mockito",component:d("/tags/mockito","3de"),exact:!0},{path:"/tags/monitoring",component:d("/tags/monitoring","775"),exact:!0},{path:"/tags/my-sql",component:d("/tags/my-sql","214"),exact:!0},{path:"/tags/mysql",component:d("/tags/mysql","79d"),exact:!0},{path:"/tags/oop",component:d("/tags/oop","613"),exact:!0},{path:"/tags/pattern",component:d("/tags/pattern","5e4"),exact:!0},{path:"/tags/performance-test",component:d("/tags/performance-test","d3e"),exact:!0},{path:"/tags/python",component:d("/tags/python","7fe"),exact:!0},{path:"/tags/replication",component:d("/tags/replication","77b"),exact:!0},{path:"/tags/retrospective",component:d("/tags/retrospective","b64"),exact:!0},{path:"/tags/retrospective/page/10",component:d("/tags/retrospective/page/10","ba6"),exact:!0},{path:"/tags/retrospective/page/11",component:d("/tags/retrospective/page/11","c54"),exact:!0},{path:"/tags/retrospective/page/12",component:d("/tags/retrospective/page/12","443"),exact:!0},{path:"/tags/retrospective/page/13",component:d("/tags/retrospective/page/13","b71"),exact:!0},{path:"/tags/retrospective/page/14",component:d("/tags/retrospective/page/14","e01"),exact:!0},{path:"/tags/retrospective/page/15",component:d("/tags/retrospective/page/15","64b"),exact:!0},{path:"/tags/retrospective/page/16",component:d("/tags/retrospective/page/16","703"),exact:!0},{path:"/tags/retrospective/page/17",component:d("/tags/retrospective/page/17","2d8"),exact:!0},{path:"/tags/retrospective/page/18",component:d("/tags/retrospective/page/18","1fd"),exact:!0},{path:"/tags/retrospective/page/19",component:d("/tags/retrospective/page/19","d19"),exact:!0},{path:"/tags/retrospective/page/2",component:d("/tags/retrospective/page/2","8bf"),exact:!0},{path:"/tags/retrospective/page/20",component:d("/tags/retrospective/page/20","f75"),exact:!0},{path:"/tags/retrospective/page/3",component:d("/tags/retrospective/page/3","998"),exact:!0},{path:"/tags/retrospective/page/4",component:d("/tags/retrospective/page/4","23f"),exact:!0},{path:"/tags/retrospective/page/5",component:d("/tags/retrospective/page/5","b0c"),exact:!0},{path:"/tags/retrospective/page/6",component:d("/tags/retrospective/page/6","58e"),exact:!0},{path:"/tags/retrospective/page/7",component:d("/tags/retrospective/page/7","133"),exact:!0},{path:"/tags/retrospective/page/8",component:d("/tags/retrospective/page/8","c6e"),exact:!0},{path:"/tags/retrospective/page/9",component:d("/tags/retrospective/page/9","a37"),exact:!0},{path:"/tags/spring",component:d("/tags/spring","ab2"),exact:!0},{path:"/tags/spring-boot",component:d("/tags/spring-boot","eb7"),exact:!0},{path:"/tags/static",component:d("/tags/static","dd5"),exact:!0},{path:"/tags/teco-chat",component:d("/tags/teco-chat","7a9"),exact:!0},{path:"/tags/teco-chat/page/2",component:d("/tags/teco-chat/page/2","fbf"),exact:!0},{path:"/tags/teco-chat/page/3",component:d("/tags/teco-chat/page/3","c3d"),exact:!0},{path:"/tags/test",component:d("/tags/test","84f"),exact:!0},{path:"/tags/test/page/2",component:d("/tags/test/page/2","3a8"),exact:!0},{path:"/tags/time",component:d("/tags/time","f3d"),exact:!0},{path:"/tags/transaction",component:d("/tags/transaction","622"),exact:!0},{path:"/tags/web-application",component:d("/tags/web-application","4a3"),exact:!0},{path:"/tags/web-socket",component:d("/tags/web-socket","e59"),exact:!0},{path:"/tags/woowahan-techcourse",component:d("/tags/woowahan-techcourse","77a"),exact:!0},{path:"/tags/woowahan-techcourse/page/10",component:d("/tags/woowahan-techcourse/page/10","156"),exact:!0},{path:"/tags/woowahan-techcourse/page/11",component:d("/tags/woowahan-techcourse/page/11","703"),exact:!0},{path:"/tags/woowahan-techcourse/page/12",component:d("/tags/woowahan-techcourse/page/12","38f"),exact:!0},{path:"/tags/woowahan-techcourse/page/13",component:d("/tags/woowahan-techcourse/page/13","ddd"),exact:!0},{path:"/tags/woowahan-techcourse/page/14",component:d("/tags/woowahan-techcourse/page/14","65c"),exact:!0},{path:"/tags/woowahan-techcourse/page/15",component:d("/tags/woowahan-techcourse/page/15","a2e"),exact:!0},{path:"/tags/woowahan-techcourse/page/16",component:d("/tags/woowahan-techcourse/page/16","53e"),exact:!0},{path:"/tags/woowahan-techcourse/page/2",component:d("/tags/woowahan-techcourse/page/2","047"),exact:!0},{path:"/tags/woowahan-techcourse/page/3",component:d("/tags/woowahan-techcourse/page/3","d3f"),exact:!0},{path:"/tags/woowahan-techcourse/page/4",component:d("/tags/woowahan-techcourse/page/4","5b6"),exact:!0},{path:"/tags/woowahan-techcourse/page/5",component:d("/tags/woowahan-techcourse/page/5","135"),exact:!0},{path:"/tags/woowahan-techcourse/page/6",component:d("/tags/woowahan-techcourse/page/6","5e8"),exact:!0},{path:"/tags/woowahan-techcourse/page/7",component:d("/tags/woowahan-techcourse/page/7","a11"),exact:!0},{path:"/tags/woowahan-techcourse/page/8",component:d("/tags/woowahan-techcourse/page/8","a7b"),exact:!0},{path:"/tags/woowahan-techcourse/page/9",component:d("/tags/woowahan-techcourse/page/9","be6"),exact:!0},{path:"/tecochat-retrospective-1",component:d("/tecochat-retrospective-1","ed9"),exact:!0},{path:"/tecochat-retrospective-2",component:d("/tecochat-retrospective-2","fc4"),exact:!0},{path:"/tecochat-retrospective-3",component:d("/tecochat-retrospective-3","6f4"),exact:!0},{path:"/test-double",component:d("/test-double","8ea"),exact:!0},{path:"/the-essence-of-object-orientation",component:d("/the-essence-of-object-orientation","9a2"),exact:!0},{path:"/tomcat-retrospective",component:d("/tomcat-retrospective","5a3"),exact:!0},{path:"/transaction-and-isolation",component:d("/transaction-and-isolation","d60"),exact:!0},{path:"/web-application-evolution",component:d("/web-application-evolution","c55"),exact:!0},{path:"/web-racing-car-retrospective",component:d("/web-racing-car-retrospective","ccb"),exact:!0},{path:"/websocket",component:d("/websocket","5c1"),exact:!0},{path:"/woowacourse-level1-retrospective",component:d("/woowacourse-level1-retrospective","a6a"),exact:!0},{path:"/woowacourse-level2-retrospective",component:d("/woowacourse-level2-retrospective","758"),exact:!0},{path:"/woowacourse-level3-retrospective",component:d("/woowacourse-level3-retrospective","4e5"),exact:!0},{path:"/docs",component:d("/docs","cf0"),routes:[{path:"/docs",component:d("/docs","d75"),routes:[{path:"/docs/tags",component:d("/docs/tags","0cc"),exact:!0},{path:"/docs/tags/architecture",component:d("/docs/tags/architecture","44b"),exact:!0},{path:"/docs/tags/book",component:d("/docs/tags/book","977"),exact:!0},{path:"/docs/tags/collection",component:d("/docs/tags/collection","0f6"),exact:!0},{path:"/docs/tags/deploy",component:d("/docs/tags/deploy","001"),exact:!0},{path:"/docs/tags/etc",component:d("/docs/tags/etc","dd7"),exact:!0},{path:"/docs/tags/java",component:d("/docs/tags/java","bac"),exact:!0},{path:"/docs/tags/jpa",component:d("/docs/tags/jpa","831"),exact:!0},{path:"/docs/tags/latency",component:d("/docs/tags/latency","a14"),exact:!0},{path:"/docs/tags/load-balancing",component:d("/docs/tags/load-balancing","5bb"),exact:!0},{path:"/docs/tags/monitoring",component:d("/docs/tags/monitoring","652"),exact:!0},{path:"/docs/tags/network",component:d("/docs/tags/network","5ba"),exact:!0},{path:"/docs/tags/nginx",component:d("/docs/tags/nginx","379"),exact:!0},{path:"/docs/tags/package",component:d("/docs/tags/package","dec"),exact:!0},{path:"/docs/tags/performance",component:d("/docs/tags/performance","364"),exact:!0},{path:"/docs/tags/postmortem",component:d("/docs/tags/postmortem","cb8"),exact:!0},{path:"/docs/tags/sequenced",component:d("/docs/tags/sequenced","fc4"),exact:!0},{path:"/docs/tags/spring",component:d("/docs/tags/spring","219"),exact:!0},{path:"/docs/tags/test",component:d("/docs/tags/test","df6"),exact:!0},{path:"/docs/tags/throughput",component:d("/docs/tags/throughput","760"),exact:!0},{path:"/docs/tags/zero-downtime",component:d("/docs/tags/zero-downtime","9c1"),exact:!0},{path:"/docs",component:d("/docs","02e"),routes:[{path:"/docs",component:d("/docs","818"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/architecture/virtical-slice-architecture",component:d("/docs/architecture/virtical-slice-architecture","825"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/book/getting-out-of-the-box",component:d("/docs/book/getting-out-of-the-box","8e1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/culture/postmortem",component:d("/docs/culture/postmortem","420"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/database/maximumPoolSize",component:d("/docs/database/maximumPoolSize","9ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/database/query-execution",component:d("/docs/database/query-execution","7b8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/deploy/zero-downtime",component:d("/docs/deploy/zero-downtime","20f"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/design/package",component:d("/docs/design/package","274"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/etc/communication",component:d("/docs/etc/communication","9c1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/etc/develop-with-spring",component:d("/docs/etc/develop-with-spring","9ab"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/etc/experience-and-self-question",component:d("/docs/etc/experience-and-self-question","d25"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/etc/healthful-growth",component:d("/docs/etc/healthful-growth","fcf"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/java/sequenced-collection",component:d("/docs/java/sequenced-collection","bda"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/jpa/key",component:d("/docs/jpa/key","68b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/linux/shell",component:d("/docs/linux/shell","c5b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/linux/swap",component:d("/docs/linux/swap","9d5"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/mac/java",component:d("/docs/mac/java","5a9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/monitoring/intro",component:d("/docs/monitoring/intro","5db"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/network/load-balancing",component:d("/docs/network/load-balancing","caa"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/network/load-balancing-algorithm",component:d("/docs/network/load-balancing-algorithm","a4d"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/nginx/command",component:d("/docs/nginx/command","0e3"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/nginx/static-file",component:d("/docs/nginx/static-file","629"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/performance/throughput",component:d("/docs/performance/throughput","56a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/performance/throughput-latency",component:d("/docs/performance/throughput-latency","12a"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/performance/types",component:d("/docs/performance/types","c08"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/spring/essence",component:d("/docs/spring/essence","4c6"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/test/benefit",component:d("/docs/test/benefit","6c8"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/test/first",component:d("/docs/test/first","566"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/test/heuristics",component:d("/docs/test/heuristics","b35"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/test/stairstep",component:d("/docs/test/stairstep","a57"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"/",component:d("/","3ce"),exact:!0},{path:"/",component:d("/","956"),exact:!0},{path:"*",component:d("*")}]},98934:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,t:()=>i});var a=n(67294),r=n(85893);const o=a.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,a.useState)(!1);return(0,a.useEffect)((()=>{i(!0)}),[]),(0,r.jsx)(o.Provider,{value:n,children:t})}},97221:(e,t,n)=>{"use strict";var a=n(67294),r=n(20745),o=n(73727),i=n(70405),s=n(10412);const l=[n(56657),n(32497),n(3310),n(18320),n(52295)];var c=n(723),u=n(16550),d=n(18790),p=n(85893);function f(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var g=n(35742),h=n(52263),m=n(44996),b=n(86668),y=n(10833),v=n(94711),x=n(19727),w=n(43320),_=n(18780),k=n(90197);function S(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.Z)(),a=(0,v.l)(),r=n[e].htmlLang,o=e=>e.replace("-","_");return(0,p.jsxs)(g.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:o(r)}),Object.values(n).filter((e=>r!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function E(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),a=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:a}=(0,u.TH)();return e+(0,_.applyTrailingSlash)((0,m.Z)(a),{trailingSlash:n,baseUrl:t})}(),r=t?`${n}${t}`:a;return(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("meta",{property:"og:url",content:r}),(0,p.jsx)("link",{rel:"canonical",href:r})]})}function j(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,b.L)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:x.h})]}),n&&(0,p.jsx)(y.d,{image:n}),(0,p.jsx)(E,{}),(0,p.jsx)(S,{}),(0,p.jsx)(k.Z,{tag:w.HX,locale:e}),(0,p.jsx)(g.Z,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var A=n(98934),L=n(58940),P=n(20469);function N(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];const r=l.map((t=>{const a=t.default?.[e]??t[e];return a?.(...n)}));return()=>r.forEach((e=>e?.()))}const M=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,P.Z)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const a=t.pathname===n.pathname,r=t.hash===n.hash,o=t.search===n.search;if(a&&r&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),N("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function R(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class O extends a.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?N("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=N("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),R(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(M,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const I=O,F="__docusaurus-base-url-issue-banner-container",D="__docusaurus-base-url-issue-banner",B="__docusaurus-base-url-issue-banner-suggestion-container";function z(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${F}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${D}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${B}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${B}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function $(){const{siteConfig:{baseUrl:e}}=(0,h.Z)();return(0,p.jsx)(p.Fragment,{children:!s.Z.canUseDOM&&(0,p.jsx)(g.Z,{children:(0,p.jsx)("script",{children:z(e)})})})}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?(0,p.jsx)($,{}):null}function Z(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:r}}=(0,h.Z)(),o=(0,m.Z)(e),{htmlLang:i,direction:s}=r[a];return(0,p.jsxs)(g.Z,{children:[(0,p.jsx)("html",{lang:i,dir:s}),(0,p.jsx)("title",{children:t}),(0,p.jsx)("meta",{property:"og:title",content:t}),(0,p.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,p.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,p.jsx)("link",{rel:"icon",href:o})]})}var H=n(44763),V=n(72389);function W(){const e=(0,V.Z)();return(0,p.jsx)(g.Z,{children:(0,p.jsx)("html",{"data-has-hydrated":e})})}function q(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return(0,p.jsx)(H.Z,{children:(0,p.jsx)(L.M,{children:(0,p.jsxs)(A.t,{children:[(0,p.jsxs)(f,{children:[(0,p.jsx)(Z,{}),(0,p.jsx)(j,{}),(0,p.jsx)(U,{}),(0,p.jsx)(I,{location:T(t),children:e})]}),(0,p.jsx)(W,{})]})})})}var G=n(16887);const K=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const a=document.createElement("link");a.setAttribute("rel","prefetch"),a.setAttribute("href",e),a.onload=()=>t(),a.onerror=()=>n();const r=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;r?.appendChild(a)}))}:function(e){return new Promise(((t,n)=>{const a=new XMLHttpRequest;a.open("GET",e,!0),a.withCredentials=!0,a.onload=()=>{200===a.status?t():n()},a.send(null)}))};var Y=n(99670);const Q=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!X.has(e)&&!Q.has(e))(e))return!1;Q.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?K(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),R(e))},te=Object.freeze(ee),ne=Boolean(!0);if(s.Z.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(i.B6,{children:(0,p.jsx)(o.VK,{children:(0,p.jsx)(q,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},s=()=>{if(ne)a.startTransition((()=>{r.hydrateRoot(e,t,{onRecoverableError:n})}));else{const o=r.createRoot(e,{onRecoverableError:n});a.startTransition((()=>{o.render(t)}))}};R(window.location.pathname).then(s)}},58940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var a=n(67294),r=n(36809);const o=JSON.parse('{"docusaurus-plugin-google-gtag":{"default":{"trackingID":["G-17TREGCW4H"],"anonymizeIP":true,"id":"default"}},"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"intro","docs":[{"id":"intro","path":"/docs/","sidebar":"tutorialSidebar"},{"id":"Java/SequencedCollection","path":"/docs/java/sequenced-collection","sidebar":"tutorialSidebar"},{"id":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551","path":"/docs/jpa/key","sidebar":"tutorialSidebar"},{"id":"MAC/\uc790\ubc14 \ubc84\uc804 \ubcc0\uacbd","path":"/docs/mac/java","sidebar":"tutorialSidebar"},{"id":"Nginx/\uad6c\uc870_\ubc0f_\uba85\ub839\uc5b4","path":"/docs/nginx/command","sidebar":"tutorialSidebar"},{"id":"Nginx/\uc815\uc801_\ucee8\ud150\uce20_\uc81c\uacf5","path":"/docs/nginx/static-file","sidebar":"tutorialSidebar"},{"id":"\uae30\ud0c0/\uac74\uac15\ud558\uac8c \ub098\uc544\uc9c0\uae30","path":"/docs/etc/healthful-growth","sidebar":"tutorialSidebar"},{"id":"\uae30\ud0c0/\uc2a4\ud504\ub9c1\uacfc \ud568\uaed8 \ub354 \ub098\uc740 \uac1c\ubc1c\uc790 \ub418\uae30","path":"/docs/etc/develop-with-spring","sidebar":"tutorialSidebar"},{"id":"\uae30\ud0c0/\uc790\uae30 \uc8fc\ub3c4\uc801\uc73c\ub85c \ubb38\uc81c\ub97c \ud574\uacb0\ud558\uae30 \uc704\ud55c \ub3c4\uc804 \uacbd\ud5d8","path":"/docs/etc/experience-and-self-question","sidebar":"tutorialSidebar"},{"id":"\uae30\ud0c0/\ucee4\ubba4\ub2c8\ucf00\uc774\uc158 \uc798\ud558\ub294 \uac1c\ubc1c\uc790\uc758 4\uac00\uc9c0 \uc2b5\uad00","path":"/docs/etc/communication","sidebar":"tutorialSidebar"},{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1","path":"/docs/network/load-balancing","sidebar":"tutorialSidebar"},{"id":"\ub124\ud2b8\uc6cc\ud06c/\ub85c\ub4dc \ubc38\ub7f0\uc2f1 \uc54c\uace0\ub9ac\uc998","path":"/docs/network/load-balancing-algorithm","sidebar":"tutorialSidebar"},{"id":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/Connection Pool","path":"/docs/database/maximumPoolSize","sidebar":"tutorialSidebar"},{"id":"\ub370\uc774\ud130\ubca0\uc774\uc2a4/\ucffc\ub9ac \uc2e4\ud589 \uad6c\uc870","path":"/docs/database/query-execution","sidebar":"tutorialSidebar"},{"id":"\ub3c4\uc11c/\uc0c1\uc790 \ubc16\uc73c\ub85c \ud0c8\ucd9c\ud558\uae30","path":"/docs/book/getting-out-of-the-box","sidebar":"tutorialSidebar"},{"id":"\ub9ac\ub205\uc2a4/Swap \uba54\ubaa8\ub9ac \uc124\uc815","path":"/docs/linux/swap","sidebar":"tutorialSidebar"},{"id":"\ub9ac\ub205\uc2a4/\ud130\ubbf8\ub110 \uc258 \ud504\ub86c\ud504\ud2b8 \uc124\uc815","path":"/docs/linux/shell","sidebar":"tutorialSidebar"},{"id":"\ubaa8\ub2c8\ud130\ub9c1/\ubaa8\ub2c8\ud130\ub9c1 \ud658\uacbd \uad6c\uc131","path":"/docs/monitoring/intro","sidebar":"tutorialSidebar"},{"id":"\ubb38\ud654/\ud3ec\uc2a4\ud2b8 \ubaa8\ud15c","path":"/docs/culture/postmortem","sidebar":"tutorialSidebar"},{"id":"\ubc30\ud3ec/\ubb34\uc911\ub2e8 \ubc30\ud3ec","path":"/docs/deploy/zero-downtime","sidebar":"tutorialSidebar"},{"id":"\uc124\uacc4/\ud328\ud0a4\uc9c0","path":"/docs/design/package","sidebar":"tutorialSidebar"},{"id":"\uc131\ub2a5/Throughput \ubaa9\ud46f\uac12","path":"/docs/performance/throughput","sidebar":"tutorialSidebar"},{"id":"\uc131\ub2a5/Throughput\uacfc Latency","path":"/docs/performance/throughput-latency","sidebar":"tutorialSidebar"},{"id":"\uc131\ub2a5/\uc131\ub2a5 \ud14c\uc2a4\ud2b8","path":"/docs/performance/types","sidebar":"tutorialSidebar"},{"id":"\uc2a4\ud504\ub9c1/\uc2a4\ud504\ub9c1\uc758 \ud2b9\uc9d5","path":"/docs/spring/essence","sidebar":"tutorialSidebar"},{"id":"\uc544\ud0a4\ud14d\ucc98/\ubc84\ud2f0\uceec \uc2ac\ub77c\uc774\uc2a4 \uc544\ud0a4\ud14d\ucc98","path":"/docs/architecture/virtical-slice-architecture","sidebar":"tutorialSidebar"},{"id":"\ud14c\uc2a4\ud2b8/FIRST","path":"/docs/test/first","sidebar":"tutorialSidebar"},{"id":"\ud14c\uc2a4\ud2b8/\uacc4\ub2e8 \ud14c\uc2a4\ud2b8","path":"/docs/test/stairstep","sidebar":"tutorialSidebar"},{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \uc8fc\ub3c4 \uac1c\ubc1c \uaddc\uce59","path":"/docs/test/heuristics","sidebar":"tutorialSidebar"},{"id":"\ud14c\uc2a4\ud2b8/\ud14c\uc2a4\ud2b8 \ucf54\ub4dc\uac00 \uc8fc\ub294 \ud61c\ud0dd","path":"/docs/test/benefit","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/jpa/key","label":"JPA/\uae30\ubcf8 \ud0a4 \ub9e4\ud551"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"ko","locales":["ko"],"path":"i18n","currentLocale":"ko","localeConfigs":{"ko":{"label":"\ud55c\uad6d\uc5b4","direction":"ltr","htmlLang":"ko","calendar":"gregory","path":"ko"}}}');var s=n(57529);const l=JSON.parse('{"docusaurusVersion":"3.0.0","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.0.0"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.0.0"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.0.0"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"3.0.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.0.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.0.0"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.0.0"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.0.0"}}}');var c=n(85893);const u={siteConfig:r.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},d=a.createContext(u);function p(e){let{children:t}=e;return(0,c.jsx)(d.Provider,{value:u,children:t})}},44763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var a=n(67294),r=n(10412),o=n(35742),i=n(18780),s=n(58207),l=n(85893);function c(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(u,{error:t})]})}function u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)(f,{fallback:()=>(0,l.jsx)(c,{error:t,tryAgain:n}),children:[(0,l.jsx)(o.Z,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.Z,{children:(0,l.jsx)(c,{error:t,tryAgain:n})})]})}const p=e=>(0,l.jsx)(d,{...e});class f extends a.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){r.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??p)(e)}return e??null}}},10412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const a="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,r={canUseDOM:a,canUseEventListeners:a&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:a&&"IntersectionObserver"in window,canUseViewport:a&&"screen"in window}},35742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);var a=n(70405),r=n(85893);function o(e){return(0,r.jsx)(a.ql,{...e})}},39960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var a=n(67294),r=n(73727),o=n(18780),i=n(52263),s=n(13919),l=n(10412),c=n(85893);const u=a.createContext({collectLink:()=>{}});var d=n(44996);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:g,isActive:h,"data-noBrokenLinkCheck":m,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:v,baseUrl:x}}=(0,i.Z)(),{withBaseUrl:w}=(0,d.C)(),_=(0,a.useContext)(u),k=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>k.current));const S=p||f;const E=(0,s.Z)(S),j=S?.replace("pathname://","");let C=void 0!==j?(T=j,b&&(e=>e.startsWith("/"))(T)?w(T):T):void 0;var T;C&&E&&(C=(0,o.applyTrailingSlash)(C,{trailingSlash:v,baseUrl:x}));const A=(0,a.useRef)(!1),L=n?r.OL:r.rU,P=l.Z.canUseIntersectionObserver,N=(0,a.useRef)(),M=()=>{A.current||null==C||(window.docusaurus.preload(C),A.current=!0)};(0,a.useEffect)((()=>(!P&&E&&null!=C&&window.docusaurus.prefetch(C),()=>{P&&N.current&&N.current.disconnect()})),[N,C,P,E]);const R=C?.startsWith("#")??!1,O=!C||!E||R;return O||m||_.collectLink(C),O?(0,c.jsx)("a",{ref:k,href:C,...S&&!E&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,c.jsx)(L,{...y,onMouseEnter:M,onTouchStart:M,innerRef:e=>{k.current=e,P&&e&&E&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=C&&window.docusaurus.prefetch(C))}))})),N.current.observe(e))},to:C,...n&&{isActive:h,activeClassName:g}})}const f=a.forwardRef(p)},95999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>l});var a=n(67294),r=n(85893);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,a.isValidElement)(e)))?n.map(((e,t)=>(0,a.isValidElement)(e)?a.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(57529);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function l(e,t){let{message:n,id:a}=e;return o(s({message:n,id:a}),t)}function c(e){let{children:t,id:n,values:a}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const i=s({message:t,id:n});return(0,r.jsx)(r.Fragment,{children:o(i,a)})}},29935:(e,t,n)=>{"use strict";n.d(t,{m:()=>a});const a="default"},13919:(e,t,n)=>{"use strict";function a(e){return/^(?:\w*:|\/\/)/.test(e)}function r(e){return void 0!==e&&!a(e)}n.d(t,{Z:()=>r,b:()=>a})},44996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var a=n(67294),r=n(52263),o=n(13919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,r.Z)(),n=(0,a.useCallback)(((n,a)=>function(e,t,n,a){let{forcePrependBaseUrl:r=!1,absolute:i=!1}=void 0===a?{}:a;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(r)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,a)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},52263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=n(67294),r=n(58940);function o(){return(0,a.useContext)(r._)}},72389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=n(67294),r=n(98934);function o(){return(0,a.useContext)(r._)}},20469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});var a=n(67294);const r=n(10412).Z.canUseDOM?a.useLayoutEffect:a.useEffect},99670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const a=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function r(e){const t={};return function e(n,r){Object.entries(n).forEach((n=>{let[o,i]=n;const s=r?`${r}.${o}`:o;a(i)?e(i,s):t[s]=i}))}(e),t}},30226:(e,t,n)=>{"use strict";n.d(t,{_:()=>o,z:()=>i});var a=n(67294),r=n(85893);const o=a.createContext(null);function i(e){let{children:t,value:n}=e;const i=a.useContext(o),s=(0,a.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const a={...t.data,...n?.data};return{plugin:t.plugin,data:a}}({parent:i,value:n})),[i,n]);return(0,r.jsx)(o.Provider,{value:s,children:t})}},80143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>b,gA:()=>f,WS:()=>g,_r:()=>d,Jo:()=>y,zh:()=>p,yW:()=>m,gB:()=>h});var a=n(16550),r=n(52263),o=n(29935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,r.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,a.LX)(t,{path:e.path,exact:!1,strict:!1})))}function c(e,t){const n=l(e,t),r=n?.docs.find((e=>!!(0,a.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:r,alternateDocVersions:r?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((a=>{a.id===t&&(n[e.name]=a)}))})),n}(r.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,p=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const a=i(e),r=a?.[t];if(!r&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return r}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,a.TH)();return function(e,t,n){void 0===n&&(n={});const r=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,a.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=r?{pluginId:r[0],pluginData:r[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function g(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,a.TH)();if(!t)return;return{activePlugin:t,activeVersion:l(t.pluginData,n)}}function h(e){return p(e).versions}function m(e){const t=p(e);return s(t)}function b(e){const t=p(e),{pathname:n}=(0,a.TH)();return c(t,n)}function y(e){const t=p(e),{pathname:n}=(0,a.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},56657:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});const a={onRouteDidUpdate(e){let{location:t,previousLocation:n}=e;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((()=>{window.gtag("set","page_path",t.pathname+t.search+t.hash),window.gtag("event","page_view")}))}}},18320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var a=n(74865),r=n.n(a);r().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{r().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){r().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var a=n(34798),r=n(36809);!function(e){const{themeConfig:{prism:t}}=r.default,{additionalLanguages:a}=t;globalThis.Prism=e,a.forEach((e=>{"php"===e&&n(96854),n(52811)(`./prism-${e}`)})),delete globalThis.Prism}(a.p1)},92503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});n(67294);var a=n(86010),r=n(95999),o=n(86668),i=n(39960);const s={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(85893);function c(e){let{as:t,id:n,...c}=e;const{navbar:{hideOnScroll:u}}=(0,o.L)();if("h1"===t||!n)return(0,l.jsx)(t,{...c,id:void 0});const d=(0,r.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof c.children?c.children:n});return(0,l.jsxs)(t,{...c,className:(0,a.Z)("anchor",u?s.anchorWithHideOnScrollNavbar:s.anchorWithStickyNavbar,c.className),id:n,children:[c.children,(0,l.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":d,title:d,children:"\u200b"})]})}},39471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);const a={iconExternalLink:"iconExternalLink_nPIU"};var r=n(85893);function o(e){let{width:t=13.5,height:n=13.5}=e;return(0,r.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink,children:(0,r.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},58207:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Ct});var a=n(67294),r=n(86010),o=n(44763),i=n(10833),s=n(16550),l=n(95999),c=n(85936),u=n(85893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,a.useRef)(null),{action:t}=(0,s.k6)(),n=(0,a.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,c.S)((n=>{let{location:a}=n;e.current&&!a.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,l.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??g,{containerRef:n,onClick:a}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:a,children:t})})}var m=n(35281),b=n(19727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(h,{className:y.skipToContent})}var x=n(86668),w=n(59689);function _(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:r=1.2,className:o,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:a,strokeWidth:r,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const k={closeButton:"closeButton_CVFx"};function S(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,r.Z)("clean-btn close",k.closeButton,e.className),children:(0,u.jsx)(_,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function j(e){const{announcementBar:t}=(0,x.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,r.Z)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const C={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function T(){const{announcementBar:e}=(0,x.L)(),{isActive:t,close:n}=(0,w.nT)();if(!t)return null;const{backgroundColor:a,textColor:r,isCloseable:o}=e;return(0,u.jsxs)("div",{className:C.announcementBar,style:{backgroundColor:a,color:r},role:"banner",children:[o&&(0,u.jsx)("div",{className:C.announcementBarPlaceholder}),(0,u.jsx)(j,{className:C.announcementBarContent}),o&&(0,u.jsx)(S,{onClick:n,className:C.announcementBarClose})]})}var A=n(93163),L=n(12466);var P=n(902),N=n(13102);const M=a.createContext(null);function R(e){let{children:t}=e;const n=function(){const e=(0,A.e)(),t=(0,N.HY)(),[n,r]=(0,a.useState)(!1),o=null!==t.component,i=(0,P.D9)(o);return(0,a.useEffect)((()=>{o&&!i&&r(!0)}),[o,i]),(0,a.useEffect)((()=>{o?e.shown||r(!0):r(!1)}),[e.shown,o]),(0,a.useMemo)((()=>[n,r]),[n])}();return(0,u.jsx)(M.Provider,{value:n,children:t})}function O(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function I(){const e=(0,a.useContext)(M);if(!e)throw new P.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,r=(0,a.useCallback)((()=>n(!1)),[n]),o=(0,N.HY)();return(0,a.useMemo)((()=>({shown:t,hide:r,content:O(o)})),[r,o,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:a}=e;const{shown:o}=I();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,r.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:a})]})]})}var D=n(92949),B=n(72389);function z(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Z(e){let{className:t,buttonClassName:n,value:a,onChange:o}=e;const i=(0,B.Z)(),s=(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===a?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,r.Z)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,r.Z)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>o("dark"===a?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,u.jsx)(z,{className:(0,r.Z)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,r.Z)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=a.memo(Z),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,x.L)().navbar.style,a=(0,x.L)().colorMode.disableSwitch,{colorMode:r,setColorMode:o}=(0,D.I)();return a?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:r,onChange:o})}var q=n(21327);function G(){return(0,u.jsx)(q.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,A.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,l.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(_,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(G,{}),(0,u.jsx)(W,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Q=n(39960),X=n(44996),J=n(13919),ee=n(98022),te=n(39471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:r,label:o,html:i,isDropdownLink:s,prependBaseUrlToHref:l,...c}=e;const d=(0,X.Z)(a),p=(0,X.Z)(t),f=(0,X.Z)(r,{forcePrependBaseUrl:!0}),g=o&&r&&!(0,J.Z)(r),h=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[o,g&&(0,u.jsx)(te.Z,{...s&&{width:12,height:12}})]})};return r?(0,u.jsx)(Q.Z,{href:l?f:r,...c,...h}):(0,u.jsx)(Q.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,ee.F)(n,t.pathname):t.pathname.startsWith(p)},...c,...h})}function ae(e){let{className:t,isDropdownItem:n=!1,...a}=e;const o=(0,u.jsx)(ne,{className:(0,r.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...a});return n?(0,u.jsx)("li",{children:o}):o}function re(e){let{className:t,isDropdownItem:n,...a}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,r.Z)("menu__link",t),...a})})}function oe(e){let{mobile:t=!1,position:n,...a}=e;const r=t?re:ae;return(0,u.jsx)(r,{...a,activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(86043),se=n(48596),le=n(52263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!(0,ee.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const l=(0,a.useRef)(null),[c,d]=(0,a.useState)(!1);return(0,a.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,u.jsxs)("div",{ref:l,className:(0,r.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":c,role:"button",href:s.to?void 0:"#",className:(0,r.Z)("navbar__link",o),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))},children:s.children??s.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,a.createElement)(Ze,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function de(e){let{items:t,className:n,position:o,onClick:i,...l}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ce(t,c),{collapsed:p,toggleCollapsed:f,setCollapsed:g}=(0,ie.u)({initialState:()=>!d});return(0,a.useEffect)((()=>{d&&g(!d)}),[c,d,g]),(0,u.jsxs)("li",{className:(0,r.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,r.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n),...l,onClick:e=>{e.preventDefault(),f()},children:l.children??l.label}),(0,u.jsx)(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,a.createElement)(Ze,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function pe(e){let{mobile:t=!1,...n}=e;const a=t?de:ue;return(0,u.jsx)(a,{...n})}var fe=n(94711);function ge(e){let{width:t=20,height:n=20,...a}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...a,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const he="iconLanguage_nlXk";function me(){return a.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},a.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var be=n(20830),ye=["translations"];function ve(){return ve=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},ve.apply(this,arguments)}function xe(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var a,r,o=[],i=!0,s=!1;try{for(n=n.call(e);!(i=(a=n.next()).done)&&(o.push(a.value),!t||o.length!==t);i=!0);}catch(l){s=!0,r=l}finally{try{i||null==n.return||n.return()}finally{if(s)throw r}}return o}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return we(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return we(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function we(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=new Array(t);n<t;n++)a[n]=e[n];return a}function _e(e,t){if(null==e)return{};var n,a,r=function(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var ke="Ctrl";var Se=a.forwardRef((function(e,t){var n=e.translations,r=void 0===n?{}:n,o=_e(e,ye),i=r.buttonText,s=void 0===i?"Search":i,l=r.buttonAriaLabel,c=void 0===l?"Search":l,u=xe((0,a.useState)(null),2),d=u[0],p=u[1];return(0,a.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(ke))}),[]),a.createElement("button",ve({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},o,{ref:t}),a.createElement("span",{className:"DocSearch-Button-Container"},a.createElement(be.W,null),a.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),a.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&a.createElement(a.Fragment,null,a.createElement("kbd",{className:"DocSearch-Button-Key"},d===ke?a.createElement(me,null):d),a.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),Ee=n(35742),je=n(66177),Ce=n(239),Te=n(43320);var Ae=n(73935);const Le={button:{buttonText:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,l.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,l.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,l.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,l.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,l.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,l.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,l.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,l.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,l.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,l.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,l.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,l.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,l.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,l.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Pe=null;function Ne(e){let{hit:t,children:n}=e;return(0,u.jsx)(Q.Z,{to:t.url,children:n})}function Me(e){let{state:t,onClose:n}=e;const a=(0,je.M)();return(0,u.jsx)(Q.Z,{to:a(t.query),onClick:n,children:(0,u.jsx)(l.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits},children:"See all {count} results"})})}function Re(e){let{contextualSearch:t,externalUrlRegex:r,...o}=e;const{siteMetadata:i}=(0,le.Z)(),l=(0,Ce.l)(),c=function(){const{locale:e,tags:t}=(0,Te._q)();return[`language:${e}`,t.map((e=>`docusaurus_tag:${e}`))]}(),d=o.searchParameters?.facetFilters??[],p=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(c,d):d,f={...o.searchParameters,facetFilters:p},g=(0,s.k6)(),h=(0,a.useRef)(null),m=(0,a.useRef)(null),[b,y]=(0,a.useState)(!1),[v,x]=(0,a.useState)(void 0),w=(0,a.useCallback)((()=>Pe?Promise.resolve():Promise.all([n.e(1426).then(n.bind(n,61426)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,46945)),Promise.all([n.e(532),n.e(2090)]).then(n.bind(n,18894))]).then((e=>{let[{DocSearchModal:t}]=e;Pe=t}))),[]),_=(0,a.useCallback)((()=>{w().then((()=>{h.current=document.createElement("div"),document.body.insertBefore(h.current,document.body.firstChild),y(!0)}))}),[w,y]),k=(0,a.useCallback)((()=>{y(!1),h.current?.remove()}),[y]),S=(0,a.useCallback)((e=>{w().then((()=>{y(!0),x(e.key)}))}),[w,y,x]),E=(0,a.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.F)(r,t)?window.location.href=t:g.push(t)}}).current,j=(0,a.useRef)((e=>o.transformItems?o.transformItems(e):e.map((e=>({...e,url:l(e.url)}))))).current,C=(0,a.useMemo)((()=>e=>(0,u.jsx)(Me,{...e,onClose:k})),[k]),T=(0,a.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",i.docusaurusVersion),e)),[i.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,r=e.onClose,o=e.onInput,i=e.searchButtonRef;a.useEffect((function(){function e(e){var a;(27===e.keyCode&&t||"k"===(null===(a=e.key)||void 0===a?void 0:a.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?r():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&o&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&o(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,r,o,i])}({isOpen:b,onOpen:_,onClose:k,onInput:S,searchButtonRef:m}),(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ee.Z,{children:(0,u.jsx)("link",{rel:"preconnect",href:`https://${o.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,u.jsx)(Se,{onTouchStart:w,onFocus:w,onMouseOver:w,onClick:_,ref:m,translations:Le.button}),b&&Pe&&h.current&&(0,Ae.createPortal)((0,u.jsx)(Pe,{onClose:k,initialScrollY:window.scrollY,initialQuery:v,navigator:E,transformItems:j,hitComponent:Ne,transformSearchClient:T,...o.searchPagePath&&{resultsFooterComponent:C},...o,searchParameters:f,placeholder:Le.placeholder,translations:Le.modal}),h.current)]})}function Oe(){const{siteConfig:e}=(0,le.Z)();return(0,u.jsx)(Re,{...e.themeConfig.algolia})}const Ie={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Fe(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,r.Z)(n,Ie.navbarSearchContainer),children:t})}var De=n(80143),Be=n(53438);var ze=n(60373);const $e=e=>e.docs.find((t=>t.id===e.mainDocId));const Ue={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,queryString:r="",...o}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,le.Z)(),p=(0,fe.l)(),{search:f,hash:g}=(0,s.TH)(),h=[...n,...c.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${g}${r}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],m=t?(0,l.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(pe,{...o,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(ge,{className:he}),m]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(Fe,{className:n,children:(0,u.jsx)(Oe,{})})},dropdown:pe,html:function(e){let{value:t,className:n,mobile:a=!1,isDropdownItem:o=!1}=e;const i=o?"li":"div";return(0,u.jsx)(i,{className:(0,r.Z)({navbar__item:!a&&!o,"menu__list-item":a},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...r}=e;const{activeDoc:o}=(0,De.Iw)(a),i=(0,Be.vY)(t,a),s=o?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,u.jsx)(oe,{exact:!0,...r,isActive:()=>s||!!o?.sidebar&&o.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...r}=e;const{activeDoc:o}=(0,De.Iw)(a),i=(0,Be.oz)(t,a).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(oe,{exact:!0,...r,isActive:()=>o?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...r}=e;const o=(0,Be.lO)(a)[0],i=t??o.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(o).path;return(0,u.jsx)(oe,{...r,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:r,dropdownItemsAfter:o,...i}=e;const{search:c,hash:d}=(0,s.TH)(),p=(0,De.Iw)(n),f=(0,De.gB)(n),{savePreferredVersionName:g}=(0,ze.J)(n),h=[...r,...f.map((e=>{const t=p.alternateDocVersions[e.name]??$e(e);return{label:e.label,to:`${t.path}${c}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...o],m=(0,Be.lO)(n)[0],b=t&&h.length>1?(0,l.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):m.label,y=t&&h.length>1?void 0:$e(m).path;return h.length<=1?(0,u.jsx)(oe,{...i,mobile:t,label:b,to:y,isActive:a?()=>!1:void 0}):(0,u.jsx)(pe,{...i,mobile:t,label:b,to:y,items:h,isActive:a?()=>!1:void 0})}};function Ze(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),r=Ue[a];if(!r)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(r,{...n})}function He(){const e=(0,A.e)(),t=(0,x.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,a.createElement)(Ze,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ve(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function We(){const e=0===(0,x.L)().navbar.items.length,t=I();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ve,{onClick:()=>t.hide()}),t.content]})}function qe(){const e=(0,A.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,a.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(F,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(He,{}),secondaryMenu:(0,u.jsx)(We,{})}):null}const Ge={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ke(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,r.Z)("navbar-sidebar__backdrop",e.className)})}function Ye(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,x.L)(),i=(0,A.e)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,a.useState)(e),r=(0,a.useRef)(!1),o=(0,a.useRef)(0),i=(0,a.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,L.RF)(((t,a)=>{let{scrollY:i}=t;if(!e)return;if(i<o.current)return void n(!0);if(r.current)return void(r.current=!1);const s=a?.scrollY,l=document.documentElement.scrollHeight-o.current,c=window.innerHeight;s&&i>=s?n(!1):i+c<l&&n(!0)})),(0,c.S)((t=>{if(!e)return;const a=t.location.hash;if(a?document.getElementById(a.substring(1)):void 0)return r.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,l.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,r.Z)("navbar","navbar--fixed-top",n&&[Ge.navbarHideable,!d&&Ge.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ke,{onClick:i.toggle}),(0,u.jsx)(qe,{})]})}var Qe=n(69690);const Xe="right";function Je(e){let{width:t=30,height:n=30,className:a,...r}=e;return(0,u.jsx)("svg",{className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...r,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function et(){const{toggle:e,shown:t}=(0,A.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,l.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(Je,{})})}const tt={colorModeToggle:"colorModeToggle_DEke"};function nt(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Qe.QW,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Ze,{...e})},t)))})}function at(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function rt(){const e=(0,A.e)(),t=(0,x.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??Xe)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),r=t.find((e=>"search"===e.type));return(0,u.jsx)(at,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(et,{}),(0,u.jsx)(G,{}),(0,u.jsx)(nt,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(nt,{items:a}),(0,u.jsx)(W,{className:tt.colorModeToggle}),!r&&(0,u.jsx)(Fe,{children:(0,u.jsx)(Oe,{})})]})})}function ot(){return(0,u.jsx)(Ye,{children:(0,u.jsx)(rt,{})})}function it(e){let{item:t}=e;const{to:n,href:a,label:r,prependBaseUrlToHref:o,...i}=t,s=(0,X.Z)(n),l=(0,X.Z)(a,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Q.Z,{className:"footer__link-item",...a?{href:o?l:a}:{to:s},...i,children:[r,a&&!(0,J.Z)(a)&&(0,u.jsx)(te.Z,{})]})}function st(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(it,{item:t})},t.href??t.to)}function lt(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(st,{item:e},t)))})]})}function ct(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(lt,{column:e},t)))})}function ut(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function dt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(it,{item:t})}function pt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(a.Fragment,{children:[(0,u.jsx)(dt,{item:e}),t.length!==n+1&&(0,u.jsx)(ut,{})]},n)))})})}function ft(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(ct,{columns:t}):(0,u.jsx)(pt,{links:t})}var gt=n(19965);const ht={footerLogoLink:"footerLogoLink_BH7S"};function mt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),a={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(gt.Z,{className:(0,r.Z)("footer__logo",t.className),alt:t.alt,sources:a,width:t.width,height:t.height,style:t.style})}function bt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Q.Z,{href:t.href,className:ht.footerLogoLink,target:t.target,children:(0,u.jsx)(mt,{logo:t})}):(0,u.jsx)(mt,{logo:t})}function yt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function vt(e){let{style:t,links:n,logo:a,copyright:o}=e;return(0,u.jsx)("footer",{className:(0,r.Z)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(a||o)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[a&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:a}),o]})]})})}function xt(){const{footer:e}=(0,x.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:r}=e;return(0,u.jsx)(vt,{style:r,links:n&&n.length>0&&(0,u.jsx)(ft,{links:n}),logo:a&&(0,u.jsx)(bt,{logo:a}),copyright:t&&(0,u.jsx)(yt,{copyright:t})})}const wt=a.memo(xt),_t=(0,P.Qc)([D.S,w.pl,L.OC,ze.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(N.n2,{children:(0,u.jsx)(A.M,{children:(0,u.jsx)(R,{children:t})})})}]);function kt(e){let{children:t}=e;return(0,u.jsx)(_t,{children:t})}var St=n(92503);function Et(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(St.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Qe.Cw,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Qe.aG,{error:t})})]})})})}const jt={mainWrapper:"mainWrapper_z2l0"};function Ct(e){const{children:t,noFooter:n,wrapperClassName:a,title:s,description:l}=e;return(0,b.t)(),(0,u.jsxs)(kt,{children:[(0,u.jsx)(i.d,{title:s,description:l}),(0,u.jsx)(v,{}),(0,u.jsx)(T,{}),(0,u.jsx)(ot,{}),(0,u.jsx)("div",{id:d,className:(0,r.Z)(m.k.wrapper.main,jt.mainWrapper,a),children:(0,u.jsx)(o.Z,{fallback:e=>(0,u.jsx)(Et,{...e}),children:t})}),!n&&(0,u.jsx)(wt,{})]})}},21327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(67294);var a=n(39960),r=n(44996),o=n(52263),i=n(86668),s=n(19965),l=n(85893);function c(e){let{logo:t,alt:n,imageClassName:a}=e;const o={light:(0,r.Z)(t.src),dark:(0,r.Z)(t.srcDark||t.src)},i=(0,l.jsx)(s.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return a?(0,l.jsx)("div",{className:a,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,o.Z)(),{navbar:{title:n,logo:s}}=(0,i.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,r.Z)(s?.href||"/"),g=n?"":t,h=s?.alt??g;return(0,l.jsxs)(a.Z,{to:f,...p,...s?.target&&{target:s.target},children:[s&&(0,l.jsx)(c,{logo:s,alt:h,imageClassName:u}),null!=n&&(0,l.jsx)("b",{className:d,children:n})]})}},90197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});n(67294);var a=n(35742),r=n(85893);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return(0,r.jsxs)(a.Z,{children:[t&&(0,r.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,r.jsx)("meta",{name:"docusaurus_version",content:n}),o&&(0,r.jsx)("meta",{name:"docusaurus_tag",content:o}),i&&(0,r.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,r.jsx)("meta",{name:"docsearch:version",content:n}),o&&(0,r.jsx)("meta",{name:"docsearch:docusaurus_tag",content:o})]})}},19965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var a=n(67294),r=n(86010),o=n(72389),i=n(92949);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(85893);function c(e){let{className:t,children:n}=e;const c=(0,o.Z)(),{colorMode:u}=(0,i.I)();return(0,l.jsx)(l.Fragment,{children:(c?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const o=n({theme:e,className:(0,r.Z)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,l.jsx)(a.Fragment,{children:o},e)}))})}function u(e){const{sources:t,className:n,alt:a,...r}=e;return(0,l.jsx)(c,{className:n,children:e=>{let{theme:n,className:o}=e;return(0,l.jsx)("img",{src:t[n],alt:a,className:o,...r})}})}},86043:(e,t,n)=>{"use strict";n.d(t,{u:()=>c,z:()=>b});var a=n(67294),r=n(10412),o=n(20469),i=n(91442),s=n(85893);const l="ease-in-out";function c(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??l}`,height:`${t}px`}}function s(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return p(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function g(e){if(!r.Z.canUseDOM)return e?u:d}function h(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:c}=e;const u=(0,a.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:o}),(0,s.jsx)(t,{ref:u,style:c?void 0:g(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),i?.(n))},className:l,children:r})}function m(e){let{collapsed:t,...n}=e;const[r,i]=(0,a.useState)(!t),[l,c]=(0,a.useState)(t);return(0,o.Z)((()=>{t||i(!0)}),[t]),(0,o.Z)((()=>{r&&c(t)}),[r,t]),r?(0,s.jsx)(h,{...n,collapsed:l}):null}function b(e){let{lazy:t,...n}=e;const a=t?m:h;return(0,s.jsx)(a,{...n})}},59689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>h,pl:()=>g});var a=n(67294),r=n(72389),o=n(50012),i=n(902),s=n(86668),l=n(85893);const c=(0,o.WA)("docusaurus.announcement.dismiss"),u=(0,o.WA)("docusaurus.announcement.id"),d=()=>"true"===c.get(),p=e=>c.set(String(e)),f=a.createContext(null);function g(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,r.Z)(),[n,o]=(0,a.useState)((()=>!!t&&d()));(0,a.useEffect)((()=>{o(d())}),[]);const i=(0,a.useCallback)((()=>{p(!0),o(!0)}),[]);return(0,a.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const a=t!==n;u.set(t),a&&p(!1),!a&&d()||o(!1)}),[e]),(0,a.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,l.jsx)(f.Provider,{value:n,children:t})}function h(){const e=(0,a.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},92949:(e,t,n)=>{"use strict";n.d(t,{I:()=>b,S:()=>m});var a=n(67294),r=n(10412),o=n(902),i=n(50012),s=n(86668),l=n(85893);const c=a.createContext(void 0),u="theme",d=(0,i.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,g=e=>r.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),h=e=>{d.set(f(e))};function m(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[r,o]=(0,a.useState)(g(e));(0,a.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,a.useCallback)((function(t,a){void 0===a&&(a={});const{persist:r=!0}=a;t?(o(t),r&&h(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,a.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(r))}),[r]),(0,a.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(0,a.useRef)(!1);return(0,a.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),a=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(a),()=>e.removeListener(a)}),[i,t,n]),(0,a.useMemo)((()=>({colorMode:r,setColorMode:i,get isDarkTheme(){return r===p.dark},setLightTheme(){i(p.light)},setDarkTheme(){i(p.dark)}})),[r,i])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function b(){const e=(0,a.useContext)(c);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},60373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>b,Oh:()=>x});var a=n(67294),r=n(80143),o=n(29935),i=n(86668),s=n(53438),l=n(902),c=n(50012),u=n(85893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,c.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const g=a.createContext(null);function h(){const e=(0,r._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,a.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,a.useState)((()=>f(n)));(0,a.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:a}=e;function r(e){const t=p.read(e,n);return a[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,r(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,a.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function m(e){let{children:t}=e;const n=h();return(0,u.jsx)(g.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return s.cE?(0,u.jsx)(m,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,a.useContext)(g);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,r.zh)(e),[n,i]=y(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,a.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function x(){const e=(0,r._r)(),[t]=y();function n(n){const a=e[n],{preferredVersionName:r}=t[n];return a.versions.find((e=>e.name===r))??null}const a=Object.keys(e);return Object.fromEntries(a.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,b:()=>l});var a=n(67294),r=n(902),o=n(85893);const i=Symbol("EmptyContext"),s=a.createContext(i);function l(e){let{children:t,name:n,items:r}=e;const i=(0,a.useMemo)((()=>n&&r?{name:n,items:r}:null),[n,r]);return(0,o.jsx)(s.Provider,{value:i,children:t})}function c(){const e=(0,a.useContext)(s);if(e===i)throw new r.i6("DocsSidebarProvider");return e}},74477:(e,t,n)=>{"use strict";n.d(t,{E:()=>l,q:()=>s});var a=n(67294),r=n(902),o=n(85893);const i=a.createContext(null);function s(e){let{children:t,version:n}=e;return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,a.useContext)(i);if(null===e)throw new r.i6("DocsVersionProvider");return e}},93163:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var a=n(67294),r=n(13102),o=n(87524),i=n(91980),s=n(86668),l=n(902),c=n(85893);const u=a.createContext(void 0);function d(){const e=function(){const e=(0,r.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[l,c]=(0,a.useState)(!1);(0,i.Rb)((()=>{if(l)return c(!1),!1}));const u=(0,a.useCallback)((()=>{c((e=>!e))}),[]);return(0,a.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,a.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:l})),[e,n,u,l])}function p(e){let{children:t}=e;const n=d();return(0,c.jsx)(u.Provider,{value:n,children:t})}function f(){const e=a.useContext(u);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},13102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>c,n2:()=>s});var a=n(67294),r=n(902),o=n(85893);const i=a.createContext(null);function s(e){let{children:t}=e;const n=(0,a.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,a.useContext)(i);if(!e)throw new r.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const o=(0,a.useContext)(i);if(!o)throw new r.i6("NavbarSecondaryMenuContentProvider");const[,s]=o,l=(0,r.Ql)(n);return(0,a.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,a.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},19727:(e,t,n)=>{"use strict";n.d(t,{h:()=>r,t:()=>o});var a=n(67294);const r="navigation-with-keyboard";function o(){(0,a.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(r),"mousedown"===e.type&&document.body.classList.remove(r)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(r),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},66177:(e,t,n)=>{"use strict";n.d(t,{K:()=>s,M:()=>l});var a=n(67294),r=n(52263),o=n(91980);const i="q";function s(){return(0,o.Nc)(i)}function l(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,r.Z)(),{algolia:{searchPagePath:n}}=t;return(0,a.useCallback)((t=>`${e}${n}?${i}=${encodeURIComponent(t)}`),[e,n])}},87524:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var a=n(67294),r=n(10412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){const[e,t]=(0,a.useState)((()=>"ssr"));return(0,a.useEffect)((()=>{function e(){t(function(){if(!r.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>i?o.desktop:o.mobile}())}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[]),e}},35281:(e,t,n)=>{"use strict";n.d(t,{k:()=>a});const a={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},91442:(e,t,n)=>{"use strict";function a(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>a})},53438:(e,t,n)=>{"use strict";n.d(t,{LM:()=>f,SN:()=>S,_F:()=>m,cE:()=>p,f:()=>y,lO:()=>w,oz:()=>_,s1:()=>x,vY:()=>k});var a=n(67294),r=n(16550),o=n(18790),i=n(80143),s=n(60373),l=n(74477),c=n(1116),u=n(67392),d=n(48596);const p=!!i._r;function f(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=f(t);if(e)return e}}(e):void 0:e.href}const g=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),h=(e,t)=>e.some((e=>m(e,t)));function m(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||h(e.items,t))}function b(e,t){switch(e.type){case"category":return m(e,t)||e.items.some((e=>b(e,t)));case"link":return!e.unlisted||m(e,t);default:return!1}}function y(e,t){return(0,a.useMemo)((()=>e.filter((e=>b(e,t)))),[e,t])}function v(e){let{sidebarItems:t,pathname:n,onlyCategories:a=!1}=e;const r=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.Mg)(o.href,n)){return a&&"category"!==o.type||r.unshift(o),!0}return!1}(t),r}function x(){const e=(0,c.V)(),{pathname:t}=(0,r.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?v({sidebarItems:e.items,pathname:t}):null}function w(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),r=(0,i.yW)(e);return(0,a.useMemo)((()=>(0,u.j)([t,n,r].filter(Boolean))),[t,n,r])}function _(e,t){const n=w(t);return(0,a.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),a=t.find((t=>t[0]===e));if(!a)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return a[1]}),[e,n])}function k(e,t){const n=w(t);return(0,a.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),a=t.find((t=>t.id===e));if(!a){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.j)(t.map((e=>e.id))).join("\n- ")}`)}return a}),[e,n])}function S(e){let{route:t}=e;const n=(0,r.TH)(),a=(0,l.E)(),i=t.routes,s=i.find((e=>(0,r.LX)(n.pathname,e)));if(!s)return null;const c=s.sidebar,u=c?a.docsSidebars[c]:void 0;return{docElement:(0,o.H)(i),sidebarName:c,sidebarItems:u}}},69690:(e,t,n)=>{"use strict";n.d(t,{aG:()=>u,Ac:()=>c,Cw:()=>l,QW:()=>d});var a=n(67294),r=n(95999),o=n(18780);const i={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var s=n(85893);function l(e){return(0,s.jsx)("button",{type:"button",...e,children:(0,s.jsx)(r.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function c(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)("div",{className:i.errorBoundaryFallback,children:[(0,s.jsx)("p",{children:t.message}),(0,s.jsx)(l,{onClick:n})]})}function u(e){let{error:t}=e;const n=(0,o.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,s.jsx)("p",{className:i.errorBoundaryError,children:n})}class d extends a.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},82128:(e,t,n)=>{"use strict";n.d(t,{p:()=>r});var a=n(52263);function r(e){const{siteConfig:t}=(0,a.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}},91980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>l,Rb:()=>i,_X:()=>s});var a=n(67294),r=n(16550),o=n(902);function i(e){!function(e){const t=(0,r.k6)(),n=(0,o.zX)(e);(0,a.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){return function(e){const t=(0,r.k6)();return(0,a.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function l(e){const t=s(e)??"",n=function(){const e=(0,r.k6)();return(0,a.useCallback)(((t,n,a)=>{const r=new URLSearchParams(e.location.search);n?r.set(t,n):r.delete(t),(a?.push?e.push:e.replace)({search:r.toString()})}),[e])}();return[t,(0,a.useCallback)(((t,a)=>{n(e,t,a)}),[n,e])]}},67392:(e,t,n)=>{"use strict";function a(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,a)=>e.findIndex((e=>t(e,n)))!==a))}function r(e){return Array.from(new Set(e))}n.d(t,{j:()=>r,l:()=>a})},10833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>d,VC:()=>g});var a=n(67294),r=n(86010),o=n(35742),i=n(30226);function s(){const e=a.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(44996),c=n(82128),u=n(85893);function d(e){let{title:t,description:n,keywords:a,image:r,children:i}=e;const s=(0,c.p)(t),{withBaseUrl:d}=(0,l.C)(),p=r?d(r,{absolute:!0}):void 0;return(0,u.jsxs)(o.Z,{children:[t&&(0,u.jsx)("title",{children:s}),t&&(0,u.jsx)("meta",{property:"og:title",content:s}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),a&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),p&&(0,u.jsx)("meta",{property:"og:image",content:p}),p&&(0,u.jsx)("meta",{name:"twitter:image",content:p}),i]})}const p=a.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=a.useContext(p),s=(0,r.Z)(i,t);return(0,u.jsxs)(p.Provider,{value:s,children:[(0,u.jsx)(o.Z,{children:(0,u.jsx)("html",{className:s})}),n]})}function g(e){let{children:t}=e;const n=s(),a=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,r.Z)(a,o),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>s,Qc:()=>u,Ql:()=>c,i6:()=>l,zX:()=>i});var a=n(67294),r=n(20469),o=n(85893);function i(e){const t=(0,a.useRef)(e);return(0,r.Z)((()=>{t.current=e}),[e]),(0,a.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,a.useRef)();return(0,r.Z)((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,a.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,o.jsx)(o.Fragment,{children:e.reduceRight(((e,t)=>(0,o.jsx)(t,{children:e})),n)})}}},98022:(e,t,n)=>{"use strict";function a(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>a})},48596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var a=n(67294),r=n(723),o=n(52263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,a.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function a(e){return e.path===t&&!0===e.exact}function r(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(a)||e(t.filter(r).flatMap((e=>e.routes??[])))}(n)}({routes:r.Z,baseUrl:e})),[e])}},12466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>h,OC:()=>u,RF:()=>f,o5:()=>g});var a=n(67294),r=n(10412),o=n(72389),i=n(20469),s=n(902),l=n(85893);const c=a.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,a.useRef)(!0);return(0,a.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,l.jsx)(c.Provider,{value:n,children:t})}function d(){const e=(0,a.useContext)(c);if(null==e)throw new s.i6("ScrollControllerProvider");return e}const p=()=>r.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),r=(0,a.useRef)(p()),o=(0,s.zX)(e);(0,a.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();o(e,r.current),r.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function g(){const e=d(),t=function(){const e=(0,a.useRef)({elem:null,top:0}),t=(0,a.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,a.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const a=t.getBoundingClientRect().top-n;return a&&window.scrollBy({left:0,top:a}),e.current={elem:null,top:0},{restored:0!==a}}),[]);return(0,a.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,a.useRef)(void 0),r=(0,a.useCallback)((a=>{t.save(a),e.disableScrollEvents(),n.current=()=>{const{restored:a}=t.restore();if(n.current=void 0,a){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,i.Z)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:r}}function h(){const e=(0,a.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function a(){const r=document.documentElement.scrollTop;(n&&r>e||!n&&r<e)&&(t=requestAnimationFrame(a),window.scrollTo(0,Math.floor(.85*(r-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},43320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>l,os:()=>s});var a=n(80143),r=n(52263),o=n(60373);const i="default";function s(e,t){return`docs-${e}-${t}`}function l(){const{i18n:e}=(0,r.Z)(),t=(0,a._r)(),n=(0,a.WS)(),l=(0,o.Oh)();const c=[i,...Object.keys(t).map((function(e){const a=n?.activePlugin.pluginId===e?n.activeVersion:void 0,r=l[e],o=t[e].versions.find((e=>e.isLast));return s(e,(a??r??o).name)}))];return{locale:e.currentLocale,tags:c}}},50012:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>u,WA:()=>c});var a=n(67294);const r="localStorage";function o(e){let{key:t,oldValue:n,newValue:a,storage:r}=e;if(n===a)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,a,window.location.href,r),window.dispatchEvent(o)}function i(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),s=!0),null}var t}let s=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function c(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=i(t?.persistence);return null===n?l:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const a=n.getItem(e);n.setItem(e,t),o({key:e,oldValue:a,newValue:t,storage:n})}catch(a){console.error(`Docusaurus storage error, can't set ${e}=${t}`,a)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),o({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const a=a=>{a.storageArea===n&&a.key===e&&t(a)};return window.addEventListener("storage",a),()=>window.removeEventListener("storage",a)}catch(a){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,a),()=>{}}}}}function u(e,t){const n=(0,a.useRef)((()=>null===e?l:c(e,t))).current(),r=(0,a.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,a.useSyncExternalStore)(r,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},94711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var a=n(52263),r=n(16550),o=n(18780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,a.Z)(),{pathname:l}=(0,r.TH)(),c=(0,o.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),d=c.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},85936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var a=n(67294),r=n(16550),o=n(902);function i(e){const t=(0,r.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,a.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},86668:(e,t,n)=>{"use strict";n.d(t,{L:()=>r});var a=n(52263);function r(){return(0,a.Z)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>r});var a=n(52263);function r(){const{siteConfig:{themeConfig:e}}=(0,a.Z)();return e}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var a=n(67294),r=n(98022),o=n(44996),i=n(6278);function s(){const{withBaseUrl:e}=(0,o.C)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,i.L)();return(0,a.useCallback)((a=>{const o=new URL(a);if((0,r.F)(t,o.href))return a;const i=`${o.pathname+o.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(i,n))}),[e,t,n])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:a}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[r]=e.split(/[#?]/),o="/"===r||r===a?r:(i=r,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(r,o)}},54143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},18780:function(e,t,n){"use strict";var a=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var r=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return a(r).default}});var o=n(54143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},86010:(e,t,n)=>{"use strict";function a(e){var t,n,r="";if("string"==typeof e||"number"==typeof e)r+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t<e.length;t++)e[t]&&(n=a(e[t]))&&(r&&(r+=" "),r+=n);else for(t in e)e[t]&&(r&&(r+=" "),r+=t);return r}n.d(t,{Z:()=>r});const r=function(){for(var e,t,n=0,r="";n<arguments.length;)(e=arguments[n++])&&(t=a(e))&&(r&&(r+=" "),r+=t);return r}},42358:(e,t,n)=>{"use strict";n.d(t,{lX:()=>k,q_:()=>A,ob:()=>h,PP:()=>P,Ep:()=>g,Hp:()=>m});var a=n(83117);function r(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,a=n+1,r=e.length;a<r;n+=1,a+=1)e[n]=e[a];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,a=e&&e.split("/")||[],i=t&&t.split("/")||[],s=e&&r(e),l=t&&r(t),c=s||l;if(e&&r(e)?i=a:a.length&&(i.pop(),i=i.concat(a)),!i.length)return"/";if(i.length){var u=i[i.length-1];n="."===u||".."===u||""===u}else n=!1;for(var d=0,p=i.length;p>=0;p--){var f=i[p];"."===f?o(i,p):".."===f?(o(i,p),d++):d&&(o(i,p),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&r(i[0])||i.unshift("");var g=i.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};function s(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}const l=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,a){return e(t,n[a])}));if("object"==typeof t||"object"==typeof n){var a=s(t),r=s(n);return a!==t||r!==n?e(a,r):Object.keys(Object.assign({},t,n)).every((function(a){return e(t[a],n[a])}))}return!1};var c=n(38776);function u(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function p(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function f(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function g(e){var t=e.pathname,n=e.search,a=e.hash,r=t||"/";return n&&"?"!==n&&(r+="?"===n.charAt(0)?n:"?"+n),a&&"#"!==a&&(r+="#"===a.charAt(0)?a:"#"+a),r}function h(e,t,n,r){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",a="",r=t.indexOf("#");-1!==r&&(a=t.substr(r),t=t.substr(0,r));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===a?"":a}}(e),o.state=t):(void 0===(o=(0,a.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),r?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,r.pathname)):o.pathname=r.pathname:o.pathname||(o.pathname="/"),o}function m(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&l(e.state,t.state)}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,a,r){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof a?a(o,r):r(!0):r(!1!==o)}else r(!0)},appendListener:function(e){var n=!0;function a(){n&&e.apply(void 0,arguments)}return t.push(a),function(){n=!1,t=t.filter((function(e){return e!==a}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),a=0;a<e;a++)n[a]=arguments[a];t.forEach((function(e){return e.apply(void 0,n)}))}}}var y=!("undefined"==typeof window||!window.document||!window.document.createElement);function v(e,t){t(window.confirm(e))}var x="popstate",w="hashchange";function _(){try{return window.history.state||{}}catch(e){return{}}}function k(e){void 0===e&&(e={}),y||(0,c.Z)(!1);var t,n=window.history,r=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,o=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,s=i.forceRefresh,l=void 0!==s&&s,d=i.getUserConfirmation,m=void 0===d?v:d,k=i.keyLength,S=void 0===k?6:k,E=e.basename?f(u(e.basename)):"";function j(e){var t=e||{},n=t.key,a=t.state,r=window.location,o=r.pathname+r.search+r.hash;return E&&(o=p(o,E)),h(o,a,n)}function C(){return Math.random().toString(36).substr(2,S)}var T=b();function A(e){(0,a.Z)($,e),$.length=n.length,T.notifyListeners($.location,$.action)}function L(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||M(j(e.state))}function P(){M(j(_()))}var N=!1;function M(e){if(N)N=!1,A();else{T.confirmTransitionTo(e,"POP",m,(function(t){t?A({action:"POP",location:e}):function(e){var t=$.location,n=O.indexOf(t.key);-1===n&&(n=0);var a=O.indexOf(e.key);-1===a&&(a=0);var r=n-a;r&&(N=!0,F(r))}(e)}))}}var R=j(_()),O=[R.key];function I(e){return E+g(e)}function F(e){n.go(e)}var D=0;function B(e){1===(D+=e)&&1===e?(window.addEventListener(x,L),o&&window.addEventListener(w,P)):0===D&&(window.removeEventListener(x,L),o&&window.removeEventListener(w,P))}var z=!1;var $={length:n.length,action:"POP",location:R,createHref:I,push:function(e,t){var a="PUSH",o=h(e,t,C(),$.location);T.confirmTransitionTo(o,a,m,(function(e){if(e){var t=I(o),i=o.key,s=o.state;if(r)if(n.pushState({key:i,state:s},null,t),l)window.location.href=t;else{var c=O.indexOf($.location.key),u=O.slice(0,c+1);u.push(o.key),O=u,A({action:a,location:o})}else window.location.href=t}}))},replace:function(e,t){var a="REPLACE",o=h(e,t,C(),$.location);T.confirmTransitionTo(o,a,m,(function(e){if(e){var t=I(o),i=o.key,s=o.state;if(r)if(n.replaceState({key:i,state:s},null,t),l)window.location.replace(t);else{var c=O.indexOf($.location.key);-1!==c&&(O[c]=o.key),A({action:a,location:o})}else window.location.replace(t)}}))},go:F,goBack:function(){F(-1)},goForward:function(){F(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=T.appendListener(e);return B(1),function(){B(-1),t()}}};return $}var S="hashchange",E={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+d(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:d,decodePath:u},slash:{encodePath:u,decodePath:u}};function j(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function C(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function T(e){window.location.replace(j(window.location.href)+"#"+e)}function A(e){void 0===e&&(e={}),y||(0,c.Z)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),r=n.getUserConfirmation,o=void 0===r?v:r,i=n.hashType,s=void 0===i?"slash":i,l=e.basename?f(u(e.basename)):"",d=E[s],m=d.encodePath,x=d.decodePath;function w(){var e=x(C());return l&&(e=p(e,l)),h(e)}var _=b();function k(e){(0,a.Z)(z,e),z.length=t.length,_.notifyListeners(z.location,z.action)}var A=!1,L=null;function P(){var e,t,n=C(),a=m(n);if(n!==a)T(a);else{var r=w(),i=z.location;if(!A&&(t=r,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(L===g(r))return;L=null,function(e){if(A)A=!1,k();else{var t="POP";_.confirmTransitionTo(e,t,o,(function(n){n?k({action:t,location:e}):function(e){var t=z.location,n=O.lastIndexOf(g(t));-1===n&&(n=0);var a=O.lastIndexOf(g(e));-1===a&&(a=0);var r=n-a;r&&(A=!0,I(r))}(e)}))}}(r)}}var N=C(),M=m(N);N!==M&&T(M);var R=w(),O=[g(R)];function I(e){t.go(e)}var F=0;function D(e){1===(F+=e)&&1===e?window.addEventListener(S,P):0===F&&window.removeEventListener(S,P)}var B=!1;var z={length:t.length,action:"POP",location:R,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=j(window.location.href)),n+"#"+m(l+g(e))},push:function(e,t){var n="PUSH",a=h(e,void 0,void 0,z.location);_.confirmTransitionTo(a,n,o,(function(e){if(e){var t=g(a),r=m(l+t);if(C()!==r){L=t,function(e){window.location.hash=e}(r);var o=O.lastIndexOf(g(z.location)),i=O.slice(0,o+1);i.push(t),O=i,k({action:n,location:a})}else k()}}))},replace:function(e,t){var n="REPLACE",a=h(e,void 0,void 0,z.location);_.confirmTransitionTo(a,n,o,(function(e){if(e){var t=g(a),r=m(l+t);C()!==r&&(L=t,T(r));var o=O.indexOf(g(z.location));-1!==o&&(O[o]=t),k({action:n,location:a})}}))},go:I,goBack:function(){I(-1)},goForward:function(){I(1)},block:function(e){void 0===e&&(e=!1);var t=_.setPrompt(e);return B||(D(1),B=!0),function(){return B&&(B=!1,D(-1)),t()}},listen:function(e){var t=_.appendListener(e);return D(1),function(){D(-1),t()}}};return z}function L(e,t,n){return Math.min(Math.max(e,t),n)}function P(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,r=t.initialEntries,o=void 0===r?["/"]:r,i=t.initialIndex,s=void 0===i?0:i,l=t.keyLength,c=void 0===l?6:l,u=b();function d(e){(0,a.Z)(x,e),x.length=x.entries.length,u.notifyListeners(x.location,x.action)}function p(){return Math.random().toString(36).substr(2,c)}var f=L(s,0,o.length-1),m=o.map((function(e){return h(e,void 0,"string"==typeof e?p():e.key||p())})),y=g;function v(e){var t=L(x.index+e,0,x.entries.length-1),a=x.entries[t];u.confirmTransitionTo(a,"POP",n,(function(e){e?d({action:"POP",location:a,index:t}):d()}))}var x={length:m.length,action:"POP",location:m[f],index:f,entries:m,createHref:y,push:function(e,t){var a="PUSH",r=h(e,t,p(),x.location);u.confirmTransitionTo(r,a,n,(function(e){if(e){var t=x.index+1,n=x.entries.slice(0);n.length>t?n.splice(t,n.length-t,r):n.push(r),d({action:a,location:r,index:t,entries:n})}}))},replace:function(e,t){var a="REPLACE",r=h(e,t,p(),x.location);u.confirmTransitionTo(r,a,n,(function(e){e&&(x.entries[x.index]=r,d({action:a,location:r}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=x.index+e;return t>=0&&t<x.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return x}},8679:(e,t,n)=>{"use strict";var a=n(59864),r={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return a.isMemo(e)?i:s[e.$$typeof]||r}s[a.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[a.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,a){if("string"!=typeof n){if(g){var r=f(n);r&&r!==g&&e(t,r,a)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),h=l(n),m=0;m<i.length;++m){var b=i[m];if(!(o[b]||a&&a[b]||h&&h[b]||s&&s[b])){var y=p(n,b);try{c(t,b,y)}catch(v){}}}}return t}},41143:e=>{"use strict";e.exports=function(e,t,n,a,r,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,a,r,o,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},32497:(e,t,n)=>{"use strict";n.r(t)},52295:(e,t,n)=>{"use strict";n.r(t)},74865:function(e,t,n){var a,r;a=function(){var e,t,n={version:"0.2.0"},a=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function r(e,t,n){return e<t?t:e>n?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var r;return(r="translate3d"===a.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===a.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,r}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(a[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=r(e,a.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(a.barSelector),u=a.speed,d=a.easing;return o.offsetWidth,s((function(t){""===a.positionUsing&&(a.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),a.trickleSpeed)};return a.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*r(Math.random()*t,.1,.95)),t=r(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*a.trickleRate)},e=0,t=0,n.promise=function(a){return a&&"resolved"!==a.state()?(0===t&&n.start(),e++,t++,a.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=a.template;var r,i=t.querySelector(a.barSelector),s=e?"-100":o(n.status||0),c=document.querySelector(a.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),a.showSpinner||(r=t.querySelector(a.spinnerSelector))&&f(r),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(a.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function a(t){var n=document.body.style;if(t in n)return t;for(var a,r=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);r--;)if((a=e[r]+o)in n)return a;return t}function r(e){return e=n(e),t[e]||(t[e]=a(e))}function o(e,t,n){t=r(t),e.style[t]=n}return function(e,t){var n,a,r=arguments;if(2==r.length)for(n in t)void 0!==(a=t[n])&&t.hasOwnProperty(n)&&o(e,n,a);else o(e,r[1],r[2])}}();function c(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),a=n+t;c(n,t)||(e.className=a.substring(1))}function d(e,t){var n,a=p(e);c(e,t)&&(n=a.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(r="function"==typeof a?a.call(t,n,t,e):a)||(e.exports=r)},40485:()=>{!function(e){var t={pattern:/((?:^|[^\\$])(?:\\{2})*)\$(?:\w+|\{[^{}]*\})/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:null}}};e.languages.groovy=e.languages.extend("clike",{string:{pattern:/'''(?:[^\\]|\\[\s\S])*?'''|'(?:\\.|[^\\'\r\n])*'/,greedy:!0},keyword:/\b(?:abstract|as|assert|boolean|break|byte|case|catch|char|class|const|continue|def|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|in|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,number:/\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?\d+)?)[glidf]?\b/i,operator:{pattern:/(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,lookbehind:!0},punctuation:/\.+|[{}[\];(),:$]/}),e.languages.insertBefore("groovy","string",{shebang:{pattern:/#!.+/,alias:"comment",greedy:!0},"interpolation-string":{pattern:/"""(?:[^\\]|\\[\s\S])*?"""|(["/])(?:\\.|(?!\1)[^\\\r\n])*\1|\$\/(?:[^/$]|\$(?:[/$]|(?![/$]))|\/(?!\$))*\/\$/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}}}),e.languages.insertBefore("groovy","punctuation",{"spock-block":/\b(?:and|cleanup|expect|given|setup|then|when|where):/}),e.languages.insertBefore("groovy","function",{annotation:{pattern:/(^|[^.])@\w+/,lookbehind:!0,alias:"punctuation"}}),t.inside.expression.inside=e.languages.groovy}(Prism)},52503:()=>{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,a={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[a,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:a.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:a.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:a.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!<keyword>)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},32334:()=>{!function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(Prism)},96854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,a,r,o){if(n.language===a){var i=n.tokenStack=[];n.code=n.code.replace(r,(function(e){if("function"==typeof o&&!o(e))return e;for(var r,s=i.length;-1!==n.code.indexOf(r=t(a,s));)++s;return i[s]=e,r})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,a){if(n.language===a&&n.tokenStack){n.grammar=e.languages[a];var r=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l<s.length&&!(r>=o.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[r],d=n.tokenStack[u],p="string"==typeof c?c:c.content,f=t(a,u),g=p.indexOf(f);if(g>-1){++r;var h=p.substring(0,g),m=new e.Token(a,e.tokenize(d,n.grammar),"language-"+a,d),b=p.substring(g+f.length),y=[];h&&y.push.apply(y,i([h])),y.push(m),b&&y.push.apply(y,i([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(y)):c.content=y}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(Prism)},52811:(e,t,n)=>{var a={"./prism-groovy":40485,"./prism-java":52503,"./prism-kotlin":32334};function r(e){var t=o(e);return n(t)}function o(e){if(!n.o(a,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return a[e]}r.keys=function(){return Object.keys(a)},r.resolve=o,e.exports=r,r.id=52811},92703:(e,t,n)=>{"use strict";var a=n(50414);function r(){}function o(){}o.resetWarningCache=r,e.exports=function(){function e(e,t,n,r,o,i){if(i!==a){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:r};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var a=n(67294),r=n(63840);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var i=new Set,s={};function l(e,t){c(e,t),c(e+"Capture",t)}function c(e,t){for(s[e]=t,e=0;e<t.length;e++)i.add(t[e])}var u=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),d=Object.prototype.hasOwnProperty,p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f={},g={};function h(e,t,n,a,r,o,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=a,this.attributeNamespace=r,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=o,this.removeEmptyString=i}var m={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){m[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];m[t]=new h(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){m[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){m[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){m[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){m[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){m[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){m[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){m[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var b=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function v(e,t,n,a){var r=m.hasOwnProperty(t)?m[t]:null;(null!==r?0!==r.type:a||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,a){if(null==t||function(e,t,n,a){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!a&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,a))return!0;if(a)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,r,a)&&(n=null),a||null===r?function(e){return!!d.call(g,e)||!d.call(f,e)&&(p.test(e)?g[e]=!0:(f[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):r.mustUseProperty?e[r.propertyName]=null===n?3!==r.type&&"":n:(t=r.attributeName,a=r.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(r=r.type)||4===r&&!0===n?"":""+n,a?e.setAttributeNS(a,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(b,y);m[t]=new h(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(b,y);m[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(b,y);m[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){m[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),m.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){m[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var x=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,w=Symbol.for("react.element"),_=Symbol.for("react.portal"),k=Symbol.for("react.fragment"),S=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),j=Symbol.for("react.provider"),C=Symbol.for("react.context"),T=Symbol.for("react.forward_ref"),A=Symbol.for("react.suspense"),L=Symbol.for("react.suspense_list"),P=Symbol.for("react.memo"),N=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var M=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var R=Symbol.iterator;function O(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=R&&e[R]||e["@@iterator"])?e:null}var I,F=Object.assign;function D(e){if(void 0===I)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);I=t&&t[1]||""}return"\n"+I+e}var B=!1;function z(e,t){if(!e||B)return"";B=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(c){var a=c}Reflect.construct(e,[],t)}else{try{t.call()}catch(c){a=c}e.call(t.prototype)}else{try{throw Error()}catch(c){a=c}e()}}catch(c){if(c&&a&&"string"==typeof c.stack){for(var r=c.stack.split("\n"),o=a.stack.split("\n"),i=r.length-1,s=o.length-1;1<=i&&0<=s&&r[i]!==o[s];)s--;for(;1<=i&&0<=s;i--,s--)if(r[i]!==o[s]){if(1!==i||1!==s)do{if(i--,0>--s||r[i]!==o[s]){var l="\n"+r[i].replace(" at new "," at ");return e.displayName&&l.includes("<anonymous>")&&(l=l.replace("<anonymous>",e.displayName)),l}}while(1<=i&&0<=s);break}}}finally{B=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?D(e):""}function $(e){switch(e.tag){case 5:return D(e.type);case 16:return D("Lazy");case 13:return D("Suspense");case 19:return D("SuspenseList");case 0:case 2:case 15:return e=z(e.type,!1);case 11:return e=z(e.type.render,!1);case 1:return e=z(e.type,!0);default:return""}}function U(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case k:return"Fragment";case _:return"Portal";case E:return"Profiler";case S:return"StrictMode";case A:return"Suspense";case L:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case C:return(e.displayName||"Context")+".Consumer";case j:return(e._context.displayName||"Context")+".Provider";case T:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case P:return null!==(t=e.displayName||null)?t:U(e.type)||"Memo";case N:t=e._payload,e=e._init;try{return U(e(t))}catch(n){}}return null}function Z(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=t.render).displayName||e.name||"",t.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return U(t);case 8:return t===S?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t}return null}function H(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function V(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function W(e){e._valueTracker||(e._valueTracker=function(e){var t=V(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),a=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var r=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return r.call(this)},set:function(e){a=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return a},setValue:function(e){a=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),a="";return e&&(a=V(e)?e.checked?"true":"false":e.value),(e=a)!==n&&(t.setValue(e),!0)}function G(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function K(e,t){var n=t.checked;return F({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Y(e,t){var n=null==t.defaultValue?"":t.defaultValue,a=null!=t.checked?t.checked:t.defaultChecked;n=H(null!=t.value?t.value:n),e._wrapperState={initialChecked:a,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Q(e,t){null!=(t=t.checked)&&v(e,"checked",t,!1)}function X(e,t){Q(e,t);var n=H(t.value),a=t.type;if(null!=n)"number"===a?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===a||"reset"===a)return void e.removeAttribute("value");t.hasOwnProperty("value")?ee(e,t.type,n):t.hasOwnProperty("defaultValue")&&ee(e,t.type,H(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function J(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var a=t.type;if(!("submit"!==a&&"reset"!==a||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ee(e,t,n){"number"===t&&G(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var te=Array.isArray;function ne(e,t,n,a){if(e=e.options,t){t={};for(var r=0;r<n.length;r++)t["$"+n[r]]=!0;for(n=0;n<e.length;n++)r=t.hasOwnProperty("$"+e[n].value),e[n].selected!==r&&(e[n].selected=r),r&&a&&(e[n].defaultSelected=!0)}else{for(n=""+H(n),t=null,r=0;r<e.length;r++){if(e[r].value===n)return e[r].selected=!0,void(a&&(e[r].defaultSelected=!0));null!==t||e[r].disabled||(t=e[r])}null!==t&&(t.selected=!0)}}function ae(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(o(91));return F({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function re(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(o(92));if(te(n)){if(1<n.length)throw Error(o(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:H(n)}}function oe(e,t){var n=H(t.value),a=H(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=a&&(e.defaultValue=""+a)}function ie(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function se(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function le(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?se(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var ce,ue,de=(ue=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((ce=ce||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=ce.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,a){MSApp.execUnsafeLocalFunction((function(){return ue(e,t)}))}:ue);function pe(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var fe={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ge=["Webkit","ms","Moz","O"];function he(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||fe.hasOwnProperty(e)&&fe[e]?(""+t).trim():t+"px"}function me(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var a=0===n.indexOf("--"),r=he(n,t[n],a);"float"===n&&(n="cssFloat"),a?e.setProperty(n,r):e[n]=r}}Object.keys(fe).forEach((function(e){ge.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),fe[t]=fe[e]}))}));var be=F({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ye(e,t){if(t){if(be[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(o(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(o(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(o(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(o(62))}}function ve(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var xe=null;function we(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var _e=null,ke=null,Se=null;function Ee(e){if(e=vr(e)){if("function"!=typeof _e)throw Error(o(280));var t=e.stateNode;t&&(t=wr(t),_e(e.stateNode,e.type,t))}}function je(e){ke?Se?Se.push(e):Se=[e]:ke=e}function Ce(){if(ke){var e=ke,t=Se;if(Se=ke=null,Ee(e),t)for(e=0;e<t.length;e++)Ee(t[e])}}function Te(e,t){return e(t)}function Ae(){}var Le=!1;function Pe(e,t,n){if(Le)return e(t,n);Le=!0;try{return Te(e,t,n)}finally{Le=!1,(null!==ke||null!==Se)&&(Ae(),Ce())}}function Ne(e,t){var n=e.stateNode;if(null===n)return null;var a=wr(n);if(null===a)return null;n=a[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(a=!a.disabled)||(a=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!a;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(o(231,t,typeof n));return n}var Me=!1;if(u)try{var Re={};Object.defineProperty(Re,"passive",{get:function(){Me=!0}}),window.addEventListener("test",Re,Re),window.removeEventListener("test",Re,Re)}catch(ue){Me=!1}function Oe(e,t,n,a,r,o,i,s,l){var c=Array.prototype.slice.call(arguments,3);try{t.apply(n,c)}catch(u){this.onError(u)}}var Ie=!1,Fe=null,De=!1,Be=null,ze={onError:function(e){Ie=!0,Fe=e}};function $e(e,t,n,a,r,o,i,s,l){Ie=!1,Fe=null,Oe.apply(ze,arguments)}function Ue(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Ze(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function He(e){if(Ue(e)!==e)throw Error(o(188))}function Ve(e){return null!==(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ue(e)))throw Error(o(188));return t!==e?null:e}for(var n=e,a=t;;){var r=n.return;if(null===r)break;var i=r.alternate;if(null===i){if(null!==(a=r.return)){n=a;continue}break}if(r.child===i.child){for(i=r.child;i;){if(i===n)return He(r),e;if(i===a)return He(r),t;i=i.sibling}throw Error(o(188))}if(n.return!==a.return)n=r,a=i;else{for(var s=!1,l=r.child;l;){if(l===n){s=!0,n=r,a=i;break}if(l===a){s=!0,a=r,n=i;break}l=l.sibling}if(!s){for(l=i.child;l;){if(l===n){s=!0,n=i,a=r;break}if(l===a){s=!0,a=i,n=r;break}l=l.sibling}if(!s)throw Error(o(189))}}if(n.alternate!==a)throw Error(o(190))}if(3!==n.tag)throw Error(o(188));return n.stateNode.current===n?e:t}(e))?We(e):null}function We(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var t=We(e);if(null!==t)return t;e=e.sibling}return null}var qe=r.unstable_scheduleCallback,Ge=r.unstable_cancelCallback,Ke=r.unstable_shouldYield,Ye=r.unstable_requestPaint,Qe=r.unstable_now,Xe=r.unstable_getCurrentPriorityLevel,Je=r.unstable_ImmediatePriority,et=r.unstable_UserBlockingPriority,tt=r.unstable_NormalPriority,nt=r.unstable_LowPriority,at=r.unstable_IdlePriority,rt=null,ot=null;var it=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(st(e)/lt|0)|0},st=Math.log,lt=Math.LN2;var ct=64,ut=4194304;function dt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function pt(e,t){var n=e.pendingLanes;if(0===n)return 0;var a=0,r=e.suspendedLanes,o=e.pingedLanes,i=268435455&n;if(0!==i){var s=i&~r;0!==s?a=dt(s):0!==(o&=i)&&(a=dt(o))}else 0!==(i=n&~r)?a=dt(i):0!==o&&(a=dt(o));if(0===a)return 0;if(0!==t&&t!==a&&0==(t&r)&&((r=a&-a)>=(o=t&-t)||16===r&&0!=(4194240&o)))return t;if(0!=(4&a)&&(a|=16&n),0!==(t=e.entangledLanes))for(e=e.entanglements,t&=a;0<t;)r=1<<(n=31-it(t)),a|=e[n],t&=~r;return a}function ft(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function gt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function ht(){var e=ct;return 0==(4194240&(ct<<=1))&&(ct=64),e}function mt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function bt(e,t,n){e.pendingLanes|=t,536870912!==t&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[t=31-it(t)]=n}function yt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var a=31-it(n),r=1<<a;r&t|e[a]&t&&(e[a]|=t),n&=~r}}var vt=0;function xt(e){return 1<(e&=-e)?4<e?0!=(268435455&e)?16:536870912:4:1}var wt,_t,kt,St,Et,jt=!1,Ct=[],Tt=null,At=null,Lt=null,Pt=new Map,Nt=new Map,Mt=[],Rt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function Ot(e,t){switch(e){case"focusin":case"focusout":Tt=null;break;case"dragenter":case"dragleave":At=null;break;case"mouseover":case"mouseout":Lt=null;break;case"pointerover":case"pointerout":Pt.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":Nt.delete(t.pointerId)}}function It(e,t,n,a,r,o){return null===e||e.nativeEvent!==o?(e={blockedOn:t,domEventName:n,eventSystemFlags:a,nativeEvent:o,targetContainers:[r]},null!==t&&(null!==(t=vr(t))&&_t(t)),e):(e.eventSystemFlags|=a,t=e.targetContainers,null!==r&&-1===t.indexOf(r)&&t.push(r),e)}function Ft(e){var t=yr(e.target);if(null!==t){var n=Ue(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Ze(n)))return e.blockedOn=t,void Et(e.priority,(function(){kt(n)}))}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Dt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Kt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=vr(n))&&_t(t),e.blockedOn=n,!1;var a=new(n=e.nativeEvent).constructor(n.type,n);xe=a,n.target.dispatchEvent(a),xe=null,t.shift()}return!0}function Bt(e,t,n){Dt(e)&&n.delete(t)}function zt(){jt=!1,null!==Tt&&Dt(Tt)&&(Tt=null),null!==At&&Dt(At)&&(At=null),null!==Lt&&Dt(Lt)&&(Lt=null),Pt.forEach(Bt),Nt.forEach(Bt)}function $t(e,t){e.blockedOn===t&&(e.blockedOn=null,jt||(jt=!0,r.unstable_scheduleCallback(r.unstable_NormalPriority,zt)))}function Ut(e){function t(t){return $t(t,e)}if(0<Ct.length){$t(Ct[0],e);for(var n=1;n<Ct.length;n++){var a=Ct[n];a.blockedOn===e&&(a.blockedOn=null)}}for(null!==Tt&&$t(Tt,e),null!==At&&$t(At,e),null!==Lt&&$t(Lt,e),Pt.forEach(t),Nt.forEach(t),n=0;n<Mt.length;n++)(a=Mt[n]).blockedOn===e&&(a.blockedOn=null);for(;0<Mt.length&&null===(n=Mt[0]).blockedOn;)Ft(n),null===n.blockedOn&&Mt.shift()}var Zt=x.ReactCurrentBatchConfig,Ht=!0;function Vt(e,t,n,a){var r=vt,o=Zt.transition;Zt.transition=null;try{vt=1,qt(e,t,n,a)}finally{vt=r,Zt.transition=o}}function Wt(e,t,n,a){var r=vt,o=Zt.transition;Zt.transition=null;try{vt=4,qt(e,t,n,a)}finally{vt=r,Zt.transition=o}}function qt(e,t,n,a){if(Ht){var r=Kt(e,t,n,a);if(null===r)Ha(e,t,a,Gt,n),Ot(e,a);else if(function(e,t,n,a,r){switch(t){case"focusin":return Tt=It(Tt,e,t,n,a,r),!0;case"dragenter":return At=It(At,e,t,n,a,r),!0;case"mouseover":return Lt=It(Lt,e,t,n,a,r),!0;case"pointerover":var o=r.pointerId;return Pt.set(o,It(Pt.get(o)||null,e,t,n,a,r)),!0;case"gotpointercapture":return o=r.pointerId,Nt.set(o,It(Nt.get(o)||null,e,t,n,a,r)),!0}return!1}(r,e,t,n,a))a.stopPropagation();else if(Ot(e,a),4&t&&-1<Rt.indexOf(e)){for(;null!==r;){var o=vr(r);if(null!==o&&wt(o),null===(o=Kt(e,t,n,a))&&Ha(e,t,a,Gt,n),o===r)break;r=o}null!==r&&a.stopPropagation()}else Ha(e,t,a,null,n)}}var Gt=null;function Kt(e,t,n,a){if(Gt=null,null!==(e=yr(e=we(a))))if(null===(t=Ue(e)))e=null;else if(13===(n=t.tag)){if(null!==(e=Ze(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return Gt=e,null}function Yt(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Xe()){case Je:return 1;case et:return 4;case tt:case nt:return 16;case at:return 536870912;default:return 16}default:return 16}}var Qt=null,Xt=null,Jt=null;function en(){if(Jt)return Jt;var e,t,n=Xt,a=n.length,r="value"in Qt?Qt.value:Qt.textContent,o=r.length;for(e=0;e<a&&n[e]===r[e];e++);var i=a-e;for(t=1;t<=i&&n[a-t]===r[o-t];t++);return Jt=r.slice(e,1<t?1-t:void 0)}function tn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function nn(){return!0}function an(){return!1}function rn(e){function t(t,n,a,r,o){for(var i in this._reactName=t,this._targetInst=a,this.type=n,this.nativeEvent=r,this.target=o,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(r):r[i]);return this.isDefaultPrevented=(null!=r.defaultPrevented?r.defaultPrevented:!1===r.returnValue)?nn:an,this.isPropagationStopped=an,this}return F(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=nn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=nn)},persist:function(){},isPersistent:nn}),t}var on,sn,ln,cn={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},un=rn(cn),dn=F({},cn,{view:0,detail:0}),pn=rn(dn),fn=F({},dn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:En,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==ln&&(ln&&"mousemove"===e.type?(on=e.screenX-ln.screenX,sn=e.screenY-ln.screenY):sn=on=0,ln=e),on)},movementY:function(e){return"movementY"in e?e.movementY:sn}}),gn=rn(fn),hn=rn(F({},fn,{dataTransfer:0})),mn=rn(F({},dn,{relatedTarget:0})),bn=rn(F({},cn,{animationName:0,elapsedTime:0,pseudoElement:0})),yn=F({},cn,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),vn=rn(yn),xn=rn(F({},cn,{data:0})),wn={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},_n={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},kn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Sn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=kn[e])&&!!t[e]}function En(){return Sn}var jn=F({},dn,{key:function(e){if(e.key){var t=wn[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=tn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?_n[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:En,charCode:function(e){return"keypress"===e.type?tn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Cn=rn(jn),Tn=rn(F({},fn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),An=rn(F({},dn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:En})),Ln=rn(F({},cn,{propertyName:0,elapsedTime:0,pseudoElement:0})),Pn=F({},fn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Nn=rn(Pn),Mn=[9,13,27,32],Rn=u&&"CompositionEvent"in window,On=null;u&&"documentMode"in document&&(On=document.documentMode);var In=u&&"TextEvent"in window&&!On,Fn=u&&(!Rn||On&&8<On&&11>=On),Dn=String.fromCharCode(32),Bn=!1;function zn(e,t){switch(e){case"keyup":return-1!==Mn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function $n(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Un=!1;var Zn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Hn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Zn[e.type]:"textarea"===t}function Vn(e,t,n,a){je(a),0<(t=Wa(t,"onChange")).length&&(n=new un("onChange","change",null,n,a),e.push({event:n,listeners:t}))}var Wn=null,qn=null;function Gn(e){Da(e,0)}function Kn(e){if(q(xr(e)))return e}function Yn(e,t){if("change"===e)return t}var Qn=!1;if(u){var Xn;if(u){var Jn="oninput"in document;if(!Jn){var ea=document.createElement("div");ea.setAttribute("oninput","return;"),Jn="function"==typeof ea.oninput}Xn=Jn}else Xn=!1;Qn=Xn&&(!document.documentMode||9<document.documentMode)}function ta(){Wn&&(Wn.detachEvent("onpropertychange",na),qn=Wn=null)}function na(e){if("value"===e.propertyName&&Kn(qn)){var t=[];Vn(t,qn,e,we(e)),Pe(Gn,t)}}function aa(e,t,n){"focusin"===e?(ta(),qn=n,(Wn=t).attachEvent("onpropertychange",na)):"focusout"===e&&ta()}function ra(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Kn(qn)}function oa(e,t){if("click"===e)return Kn(t)}function ia(e,t){if("input"===e||"change"===e)return Kn(t)}var sa="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function la(e,t){if(sa(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),a=Object.keys(t);if(n.length!==a.length)return!1;for(a=0;a<n.length;a++){var r=n[a];if(!d.call(t,r)||!sa(e[r],t[r]))return!1}return!0}function ca(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function ua(e,t){var n,a=ca(e);for(e=0;a;){if(3===a.nodeType){if(n=e+a.textContent.length,e<=t&&n>=t)return{node:a,offset:t-e};e=n}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=ca(a)}}function da(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?da(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function pa(){for(var e=window,t=G();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(a){n=!1}if(!n)break;t=G((e=t.contentWindow).document)}return t}function fa(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function ga(e){var t=pa(),n=e.focusedElem,a=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&da(n.ownerDocument.documentElement,n)){if(null!==a&&fa(n))if(t=a.start,void 0===(e=a.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var r=n.textContent.length,o=Math.min(a.start,r);a=void 0===a.end?o:Math.min(a.end,r),!e.extend&&o>a&&(r=a,a=o,o=r),r=ua(n,o);var i=ua(n,a);r&&i&&(1!==e.rangeCount||e.anchorNode!==r.node||e.anchorOffset!==r.offset||e.focusNode!==i.node||e.focusOffset!==i.offset)&&((t=t.createRange()).setStart(r.node,r.offset),e.removeAllRanges(),o>a?(e.addRange(t),e.extend(i.node,i.offset)):(t.setEnd(i.node,i.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var ha=u&&"documentMode"in document&&11>=document.documentMode,ma=null,ba=null,ya=null,va=!1;function xa(e,t,n){var a=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;va||null==ma||ma!==G(a)||("selectionStart"in(a=ma)&&fa(a)?a={start:a.selectionStart,end:a.selectionEnd}:a={anchorNode:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset},ya&&la(ya,a)||(ya=a,0<(a=Wa(ba,"onSelect")).length&&(t=new un("onSelect","select",null,t,n),e.push({event:t,listeners:a}),t.target=ma)))}function wa(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var _a={animationend:wa("Animation","AnimationEnd"),animationiteration:wa("Animation","AnimationIteration"),animationstart:wa("Animation","AnimationStart"),transitionend:wa("Transition","TransitionEnd")},ka={},Sa={};function Ea(e){if(ka[e])return ka[e];if(!_a[e])return e;var t,n=_a[e];for(t in n)if(n.hasOwnProperty(t)&&t in Sa)return ka[e]=n[t];return e}u&&(Sa=document.createElement("div").style,"AnimationEvent"in window||(delete _a.animationend.animation,delete _a.animationiteration.animation,delete _a.animationstart.animation),"TransitionEvent"in window||delete _a.transitionend.transition);var ja=Ea("animationend"),Ca=Ea("animationiteration"),Ta=Ea("animationstart"),Aa=Ea("transitionend"),La=new Map,Pa="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Na(e,t){La.set(e,t),l(t,[e])}for(var Ma=0;Ma<Pa.length;Ma++){var Ra=Pa[Ma];Na(Ra.toLowerCase(),"on"+(Ra[0].toUpperCase()+Ra.slice(1)))}Na(ja,"onAnimationEnd"),Na(Ca,"onAnimationIteration"),Na(Ta,"onAnimationStart"),Na("dblclick","onDoubleClick"),Na("focusin","onFocus"),Na("focusout","onBlur"),Na(Aa,"onTransitionEnd"),c("onMouseEnter",["mouseout","mouseover"]),c("onMouseLeave",["mouseout","mouseover"]),c("onPointerEnter",["pointerout","pointerover"]),c("onPointerLeave",["pointerout","pointerover"]),l("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),l("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),l("onBeforeInput",["compositionend","keypress","textInput","paste"]),l("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),l("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),l("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Oa="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Ia=new Set("cancel close invalid load scroll toggle".split(" ").concat(Oa));function Fa(e,t,n){var a=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,a,r,i,s,l,c){if($e.apply(this,arguments),Ie){if(!Ie)throw Error(o(198));var u=Fe;Ie=!1,Fe=null,De||(De=!0,Be=u)}}(a,t,void 0,e),e.currentTarget=null}function Da(e,t){t=0!=(4&t);for(var n=0;n<e.length;n++){var a=e[n],r=a.event;a=a.listeners;e:{var o=void 0;if(t)for(var i=a.length-1;0<=i;i--){var s=a[i],l=s.instance,c=s.currentTarget;if(s=s.listener,l!==o&&r.isPropagationStopped())break e;Fa(r,s,c),o=l}else for(i=0;i<a.length;i++){if(l=(s=a[i]).instance,c=s.currentTarget,s=s.listener,l!==o&&r.isPropagationStopped())break e;Fa(r,s,c),o=l}}}if(De)throw e=Be,De=!1,Be=null,e}function Ba(e,t){var n=t[hr];void 0===n&&(n=t[hr]=new Set);var a=e+"__bubble";n.has(a)||(Za(t,e,2,!1),n.add(a))}function za(e,t,n){var a=0;t&&(a|=4),Za(n,e,a,t)}var $a="_reactListening"+Math.random().toString(36).slice(2);function Ua(e){if(!e[$a]){e[$a]=!0,i.forEach((function(t){"selectionchange"!==t&&(Ia.has(t)||za(t,!1,e),za(t,!0,e))}));var t=9===e.nodeType?e:e.ownerDocument;null===t||t[$a]||(t[$a]=!0,za("selectionchange",!1,t))}}function Za(e,t,n,a){switch(Yt(t)){case 1:var r=Vt;break;case 4:r=Wt;break;default:r=qt}n=r.bind(null,t,n,e),r=void 0,!Me||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(r=!0),a?void 0!==r?e.addEventListener(t,n,{capture:!0,passive:r}):e.addEventListener(t,n,!0):void 0!==r?e.addEventListener(t,n,{passive:r}):e.addEventListener(t,n,!1)}function Ha(e,t,n,a,r){var o=a;if(0==(1&t)&&0==(2&t)&&null!==a)e:for(;;){if(null===a)return;var i=a.tag;if(3===i||4===i){var s=a.stateNode.containerInfo;if(s===r||8===s.nodeType&&s.parentNode===r)break;if(4===i)for(i=a.return;null!==i;){var l=i.tag;if((3===l||4===l)&&((l=i.stateNode.containerInfo)===r||8===l.nodeType&&l.parentNode===r))return;i=i.return}for(;null!==s;){if(null===(i=yr(s)))return;if(5===(l=i.tag)||6===l){a=o=i;continue e}s=s.parentNode}}a=a.return}Pe((function(){var a=o,r=we(n),i=[];e:{var s=La.get(e);if(void 0!==s){var l=un,c=e;switch(e){case"keypress":if(0===tn(n))break e;case"keydown":case"keyup":l=Cn;break;case"focusin":c="focus",l=mn;break;case"focusout":c="blur",l=mn;break;case"beforeblur":case"afterblur":l=mn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":l=gn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":l=hn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":l=An;break;case ja:case Ca:case Ta:l=bn;break;case Aa:l=Ln;break;case"scroll":l=pn;break;case"wheel":l=Nn;break;case"copy":case"cut":case"paste":l=vn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":l=Tn}var u=0!=(4&t),d=!u&&"scroll"===e,p=u?null!==s?s+"Capture":null:s;u=[];for(var f,g=a;null!==g;){var h=(f=g).stateNode;if(5===f.tag&&null!==h&&(f=h,null!==p&&(null!=(h=Ne(g,p))&&u.push(Va(g,h,f)))),d)break;g=g.return}0<u.length&&(s=new l(s,c,null,n,r),i.push({event:s,listeners:u}))}}if(0==(7&t)){if(l="mouseout"===e||"pointerout"===e,(!(s="mouseover"===e||"pointerover"===e)||n===xe||!(c=n.relatedTarget||n.fromElement)||!yr(c)&&!c[gr])&&(l||s)&&(s=r.window===r?r:(s=r.ownerDocument)?s.defaultView||s.parentWindow:window,l?(l=a,null!==(c=(c=n.relatedTarget||n.toElement)?yr(c):null)&&(c!==(d=Ue(c))||5!==c.tag&&6!==c.tag)&&(c=null)):(l=null,c=a),l!==c)){if(u=gn,h="onMouseLeave",p="onMouseEnter",g="mouse","pointerout"!==e&&"pointerover"!==e||(u=Tn,h="onPointerLeave",p="onPointerEnter",g="pointer"),d=null==l?s:xr(l),f=null==c?s:xr(c),(s=new u(h,g+"leave",l,n,r)).target=d,s.relatedTarget=f,h=null,yr(r)===a&&((u=new u(p,g+"enter",c,n,r)).target=f,u.relatedTarget=d,h=u),d=h,l&&c)e:{for(p=c,g=0,f=u=l;f;f=qa(f))g++;for(f=0,h=p;h;h=qa(h))f++;for(;0<g-f;)u=qa(u),g--;for(;0<f-g;)p=qa(p),f--;for(;g--;){if(u===p||null!==p&&u===p.alternate)break e;u=qa(u),p=qa(p)}u=null}else u=null;null!==l&&Ga(i,s,l,u,!1),null!==c&&null!==d&&Ga(i,d,c,u,!0)}if("select"===(l=(s=a?xr(a):window).nodeName&&s.nodeName.toLowerCase())||"input"===l&&"file"===s.type)var m=Yn;else if(Hn(s))if(Qn)m=ia;else{m=ra;var b=aa}else(l=s.nodeName)&&"input"===l.toLowerCase()&&("checkbox"===s.type||"radio"===s.type)&&(m=oa);switch(m&&(m=m(e,a))?Vn(i,m,n,r):(b&&b(e,s,a),"focusout"===e&&(b=s._wrapperState)&&b.controlled&&"number"===s.type&&ee(s,"number",s.value)),b=a?xr(a):window,e){case"focusin":(Hn(b)||"true"===b.contentEditable)&&(ma=b,ba=a,ya=null);break;case"focusout":ya=ba=ma=null;break;case"mousedown":va=!0;break;case"contextmenu":case"mouseup":case"dragend":va=!1,xa(i,n,r);break;case"selectionchange":if(ha)break;case"keydown":case"keyup":xa(i,n,r)}var y;if(Rn)e:{switch(e){case"compositionstart":var v="onCompositionStart";break e;case"compositionend":v="onCompositionEnd";break e;case"compositionupdate":v="onCompositionUpdate";break e}v=void 0}else Un?zn(e,n)&&(v="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(v="onCompositionStart");v&&(Fn&&"ko"!==n.locale&&(Un||"onCompositionStart"!==v?"onCompositionEnd"===v&&Un&&(y=en()):(Xt="value"in(Qt=r)?Qt.value:Qt.textContent,Un=!0)),0<(b=Wa(a,v)).length&&(v=new xn(v,e,null,n,r),i.push({event:v,listeners:b}),y?v.data=y:null!==(y=$n(n))&&(v.data=y))),(y=In?function(e,t){switch(e){case"compositionend":return $n(t);case"keypress":return 32!==t.which?null:(Bn=!0,Dn);case"textInput":return(e=t.data)===Dn&&Bn?null:e;default:return null}}(e,n):function(e,t){if(Un)return"compositionend"===e||!Rn&&zn(e,t)?(e=en(),Jt=Xt=Qt=null,Un=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Fn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(a=Wa(a,"onBeforeInput")).length&&(r=new xn("onBeforeInput","beforeinput",null,n,r),i.push({event:r,listeners:a}),r.data=y))}Da(i,t)}))}function Va(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Wa(e,t){for(var n=t+"Capture",a=[];null!==e;){var r=e,o=r.stateNode;5===r.tag&&null!==o&&(r=o,null!=(o=Ne(e,n))&&a.unshift(Va(e,o,r)),null!=(o=Ne(e,t))&&a.push(Va(e,o,r))),e=e.return}return a}function qa(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Ga(e,t,n,a,r){for(var o=t._reactName,i=[];null!==n&&n!==a;){var s=n,l=s.alternate,c=s.stateNode;if(null!==l&&l===a)break;5===s.tag&&null!==c&&(s=c,r?null!=(l=Ne(n,o))&&i.unshift(Va(n,l,s)):r||null!=(l=Ne(n,o))&&i.push(Va(n,l,s))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}var Ka=/\r\n?/g,Ya=/\u0000|\uFFFD/g;function Qa(e){return("string"==typeof e?e:""+e).replace(Ka,"\n").replace(Ya,"")}function Xa(e,t,n){if(t=Qa(t),Qa(e)!==t&&n)throw Error(o(425))}function Ja(){}var er=null,tr=null;function nr(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ar="function"==typeof setTimeout?setTimeout:void 0,rr="function"==typeof clearTimeout?clearTimeout:void 0,or="function"==typeof Promise?Promise:void 0,ir="function"==typeof queueMicrotask?queueMicrotask:void 0!==or?function(e){return or.resolve(null).then(e).catch(sr)}:ar;function sr(e){setTimeout((function(){throw e}))}function lr(e,t){var n=t,a=0;do{var r=n.nextSibling;if(e.removeChild(n),r&&8===r.nodeType)if("/$"===(n=r.data)){if(0===a)return e.removeChild(r),void Ut(t);a--}else"$"!==n&&"$?"!==n&&"$!"!==n||a++;n=r}while(n);Ut(t)}function cr(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t)break;if("/$"===t)return null}}return e}function ur(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var dr=Math.random().toString(36).slice(2),pr="__reactFiber$"+dr,fr="__reactProps$"+dr,gr="__reactContainer$"+dr,hr="__reactEvents$"+dr,mr="__reactListeners$"+dr,br="__reactHandles$"+dr;function yr(e){var t=e[pr];if(t)return t;for(var n=e.parentNode;n;){if(t=n[gr]||n[pr]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=ur(e);null!==e;){if(n=e[pr])return n;e=ur(e)}return t}n=(e=n).parentNode}return null}function vr(e){return!(e=e[pr]||e[gr])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function xr(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(o(33))}function wr(e){return e[fr]||null}var _r=[],kr=-1;function Sr(e){return{current:e}}function Er(e){0>kr||(e.current=_r[kr],_r[kr]=null,kr--)}function jr(e,t){kr++,_r[kr]=e.current,e.current=t}var Cr={},Tr=Sr(Cr),Ar=Sr(!1),Lr=Cr;function Pr(e,t){var n=e.type.contextTypes;if(!n)return Cr;var a=e.stateNode;if(a&&a.__reactInternalMemoizedUnmaskedChildContext===t)return a.__reactInternalMemoizedMaskedChildContext;var r,o={};for(r in n)o[r]=t[r];return a&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function Nr(e){return null!=(e=e.childContextTypes)}function Mr(){Er(Ar),Er(Tr)}function Rr(e,t,n){if(Tr.current!==Cr)throw Error(o(168));jr(Tr,t),jr(Ar,n)}function Or(e,t,n){var a=e.stateNode;if(t=t.childContextTypes,"function"!=typeof a.getChildContext)return n;for(var r in a=a.getChildContext())if(!(r in t))throw Error(o(108,Z(e)||"Unknown",r));return F({},n,a)}function Ir(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Cr,Lr=Tr.current,jr(Tr,e),jr(Ar,Ar.current),!0}function Fr(e,t,n){var a=e.stateNode;if(!a)throw Error(o(169));n?(e=Or(e,t,Lr),a.__reactInternalMemoizedMergedChildContext=e,Er(Ar),Er(Tr),jr(Tr,e)):Er(Ar),jr(Ar,n)}var Dr=null,Br=!1,zr=!1;function $r(e){null===Dr?Dr=[e]:Dr.push(e)}function Ur(){if(!zr&&null!==Dr){zr=!0;var e=0,t=vt;try{var n=Dr;for(vt=1;e<n.length;e++){var a=n[e];do{a=a(!0)}while(null!==a)}Dr=null,Br=!1}catch(r){throw null!==Dr&&(Dr=Dr.slice(e+1)),qe(Je,Ur),r}finally{vt=t,zr=!1}}return null}var Zr=[],Hr=0,Vr=null,Wr=0,qr=[],Gr=0,Kr=null,Yr=1,Qr="";function Xr(e,t){Zr[Hr++]=Wr,Zr[Hr++]=Vr,Vr=e,Wr=t}function Jr(e,t,n){qr[Gr++]=Yr,qr[Gr++]=Qr,qr[Gr++]=Kr,Kr=e;var a=Yr;e=Qr;var r=32-it(a)-1;a&=~(1<<r),n+=1;var o=32-it(t)+r;if(30<o){var i=r-r%5;o=(a&(1<<i)-1).toString(32),a>>=i,r-=i,Yr=1<<32-it(t)+r|n<<r|a,Qr=o+e}else Yr=1<<o|n<<r|a,Qr=e}function eo(e){null!==e.return&&(Xr(e,1),Jr(e,1,0))}function to(e){for(;e===Vr;)Vr=Zr[--Hr],Zr[Hr]=null,Wr=Zr[--Hr],Zr[Hr]=null;for(;e===Kr;)Kr=qr[--Gr],qr[Gr]=null,Qr=qr[--Gr],qr[Gr]=null,Yr=qr[--Gr],qr[Gr]=null}var no=null,ao=null,ro=!1,oo=null;function io(e,t){var n=Nc(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,null===(t=e.deletions)?(e.deletions=[n],e.flags|=16):t.push(n)}function so(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,no=e,ao=cr(t.firstChild),!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,no=e,ao=null,!0);case 13:return null!==(t=8!==t.nodeType?null:t)&&(n=null!==Kr?{id:Yr,overflow:Qr}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},(n=Nc(18,null,null,0)).stateNode=t,n.return=e,e.child=n,no=e,ao=null,!0);default:return!1}}function lo(e){return 0!=(1&e.mode)&&0==(128&e.flags)}function co(e){if(ro){var t=ao;if(t){var n=t;if(!so(e,t)){if(lo(e))throw Error(o(418));t=cr(n.nextSibling);var a=no;t&&so(e,t)?io(a,n):(e.flags=-4097&e.flags|2,ro=!1,no=e)}}else{if(lo(e))throw Error(o(418));e.flags=-4097&e.flags|2,ro=!1,no=e}}}function uo(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;no=e}function po(e){if(e!==no)return!1;if(!ro)return uo(e),ro=!0,!1;var t;if((t=3!==e.tag)&&!(t=5!==e.tag)&&(t="head"!==(t=e.type)&&"body"!==t&&!nr(e.type,e.memoizedProps)),t&&(t=ao)){if(lo(e))throw fo(),Error(o(418));for(;t;)io(e,t),t=cr(t.nextSibling)}if(uo(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(o(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){ao=cr(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}ao=null}}else ao=no?cr(e.stateNode.nextSibling):null;return!0}function fo(){for(var e=ao;e;)e=cr(e.nextSibling)}function go(){ao=no=null,ro=!1}function ho(e){null===oo?oo=[e]:oo.push(e)}var mo=x.ReactCurrentBatchConfig;function bo(e,t){if(e&&e.defaultProps){for(var n in t=F({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}var yo=Sr(null),vo=null,xo=null,wo=null;function _o(){wo=xo=vo=null}function ko(e){var t=yo.current;Er(yo),e._currentValue=t}function So(e,t,n){for(;null!==e;){var a=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==a&&(a.childLanes|=t)):null!==a&&(a.childLanes&t)!==t&&(a.childLanes|=t),e===n)break;e=e.return}}function Eo(e,t){vo=e,wo=xo=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!=(e.lanes&t)&&(xs=!0),e.firstContext=null)}function jo(e){var t=e._currentValue;if(wo!==e)if(e={context:e,memoizedValue:t,next:null},null===xo){if(null===vo)throw Error(o(308));xo=e,vo.dependencies={lanes:0,firstContext:e}}else xo=xo.next=e;return t}var Co=null;function To(e){null===Co?Co=[e]:Co.push(e)}function Ao(e,t,n,a){var r=t.interleaved;return null===r?(n.next=n,To(t)):(n.next=r.next,r.next=n),t.interleaved=n,Lo(e,a)}function Lo(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}var Po=!1;function No(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Mo(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Ro(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Oo(e,t,n){var a=e.updateQueue;if(null===a)return null;if(a=a.shared,0!=(2&Al)){var r=a.pending;return null===r?t.next=t:(t.next=r.next,r.next=t),a.pending=t,Lo(e,n)}return null===(r=a.interleaved)?(t.next=t,To(a)):(t.next=r.next,r.next=t),a.interleaved=t,Lo(e,n)}function Io(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,0!=(4194240&n))){var a=t.lanes;n|=a&=e.pendingLanes,t.lanes=n,yt(e,n)}}function Fo(e,t){var n=e.updateQueue,a=e.alternate;if(null!==a&&n===(a=a.updateQueue)){var r=null,o=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===o?r=o=i:o=o.next=i,n=n.next}while(null!==n);null===o?r=o=t:o=o.next=t}else r=o=t;return n={baseState:a.baseState,firstBaseUpdate:r,lastBaseUpdate:o,shared:a.shared,effects:a.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Do(e,t,n,a){var r=e.updateQueue;Po=!1;var o=r.firstBaseUpdate,i=r.lastBaseUpdate,s=r.shared.pending;if(null!==s){r.shared.pending=null;var l=s,c=l.next;l.next=null,null===i?o=c:i.next=c,i=l;var u=e.alternate;null!==u&&((s=(u=u.updateQueue).lastBaseUpdate)!==i&&(null===s?u.firstBaseUpdate=c:s.next=c,u.lastBaseUpdate=l))}if(null!==o){var d=r.baseState;for(i=0,u=c=l=null,s=o;;){var p=s.lane,f=s.eventTime;if((a&p)===p){null!==u&&(u=u.next={eventTime:f,lane:0,tag:s.tag,payload:s.payload,callback:s.callback,next:null});e:{var g=e,h=s;switch(p=t,f=n,h.tag){case 1:if("function"==typeof(g=h.payload)){d=g.call(f,d,p);break e}d=g;break e;case 3:g.flags=-65537&g.flags|128;case 0:if(null==(p="function"==typeof(g=h.payload)?g.call(f,d,p):g))break e;d=F({},d,p);break e;case 2:Po=!0}}null!==s.callback&&0!==s.lane&&(e.flags|=64,null===(p=r.effects)?r.effects=[s]:p.push(s))}else f={eventTime:f,lane:p,tag:s.tag,payload:s.payload,callback:s.callback,next:null},null===u?(c=u=f,l=d):u=u.next=f,i|=p;if(null===(s=s.next)){if(null===(s=r.shared.pending))break;s=(p=s).next,p.next=null,r.lastBaseUpdate=p,r.shared.pending=null}}if(null===u&&(l=d),r.baseState=l,r.firstBaseUpdate=c,r.lastBaseUpdate=u,null!==(t=r.shared.interleaved)){r=t;do{i|=r.lane,r=r.next}while(r!==t)}else null===o&&(r.shared.lanes=0);Fl|=i,e.lanes=i,e.memoizedState=d}}function Bo(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var a=e[t],r=a.callback;if(null!==r){if(a.callback=null,a=n,"function"!=typeof r)throw Error(o(191,r));r.call(a)}}}var zo=(new a.Component).refs;function $o(e,t,n,a){n=null==(n=n(a,t=e.memoizedState))?t:F({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var Uo={isMounted:function(e){return!!(e=e._reactInternals)&&Ue(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var a=tc(),r=nc(e),o=Ro(a,r);o.payload=t,null!=n&&(o.callback=n),null!==(t=Oo(e,o,r))&&(ac(t,e,r,a),Io(t,e,r))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var a=tc(),r=nc(e),o=Ro(a,r);o.tag=1,o.payload=t,null!=n&&(o.callback=n),null!==(t=Oo(e,o,r))&&(ac(t,e,r,a),Io(t,e,r))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=tc(),a=nc(e),r=Ro(n,a);r.tag=2,null!=t&&(r.callback=t),null!==(t=Oo(e,r,a))&&(ac(t,e,a,n),Io(t,e,a))}};function Zo(e,t,n,a,r,o,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(a,o,i):!t.prototype||!t.prototype.isPureReactComponent||(!la(n,a)||!la(r,o))}function Ho(e,t,n){var a=!1,r=Cr,o=t.contextType;return"object"==typeof o&&null!==o?o=jo(o):(r=Nr(t)?Lr:Tr.current,o=(a=null!=(a=t.contextTypes))?Pr(e,r):Cr),t=new t(n,o),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=Uo,e.stateNode=t,t._reactInternals=e,a&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=r,e.__reactInternalMemoizedMaskedChildContext=o),t}function Vo(e,t,n,a){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,a),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,a),t.state!==e&&Uo.enqueueReplaceState(t,t.state,null)}function Wo(e,t,n,a){var r=e.stateNode;r.props=n,r.state=e.memoizedState,r.refs=zo,No(e);var o=t.contextType;"object"==typeof o&&null!==o?r.context=jo(o):(o=Nr(t)?Lr:Tr.current,r.context=Pr(e,o)),r.state=e.memoizedState,"function"==typeof(o=t.getDerivedStateFromProps)&&($o(e,t,o,n),r.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof r.getSnapshotBeforeUpdate||"function"!=typeof r.UNSAFE_componentWillMount&&"function"!=typeof r.componentWillMount||(t=r.state,"function"==typeof r.componentWillMount&&r.componentWillMount(),"function"==typeof r.UNSAFE_componentWillMount&&r.UNSAFE_componentWillMount(),t!==r.state&&Uo.enqueueReplaceState(r,r.state,null),Do(e,n,r,a),r.state=e.memoizedState),"function"==typeof r.componentDidMount&&(e.flags|=4194308)}function qo(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(o(309));var a=n.stateNode}if(!a)throw Error(o(147,e));var r=a,i=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===i?t.ref:(t=function(e){var t=r.refs;t===zo&&(t=r.refs={}),null===e?delete t[i]:t[i]=e},t._stringRef=i,t)}if("string"!=typeof e)throw Error(o(284));if(!n._owner)throw Error(o(290,e))}return e}function Go(e,t){throw e=Object.prototype.toString.call(t),Error(o(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function Ko(e){return(0,e._init)(e._payload)}function Yo(e){function t(t,n){if(e){var a=t.deletions;null===a?(t.deletions=[n],t.flags|=16):a.push(n)}}function n(n,a){if(!e)return null;for(;null!==a;)t(n,a),a=a.sibling;return null}function a(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function r(e,t){return(e=Rc(e,t)).index=0,e.sibling=null,e}function i(t,n,a){return t.index=a,e?null!==(a=t.alternate)?(a=a.index)<n?(t.flags|=2,n):a:(t.flags|=2,n):(t.flags|=1048576,n)}function s(t){return e&&null===t.alternate&&(t.flags|=2),t}function l(e,t,n,a){return null===t||6!==t.tag?((t=Dc(n,e.mode,a)).return=e,t):((t=r(t,n)).return=e,t)}function c(e,t,n,a){var o=n.type;return o===k?d(e,t,n.props.children,a,n.key):null!==t&&(t.elementType===o||"object"==typeof o&&null!==o&&o.$$typeof===N&&Ko(o)===t.type)?((a=r(t,n.props)).ref=qo(e,t,n),a.return=e,a):((a=Oc(n.type,n.key,n.props,null,e.mode,a)).ref=qo(e,t,n),a.return=e,a)}function u(e,t,n,a){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Bc(n,e.mode,a)).return=e,t):((t=r(t,n.children||[])).return=e,t)}function d(e,t,n,a,o){return null===t||7!==t.tag?((t=Ic(n,e.mode,a,o)).return=e,t):((t=r(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t)return(t=Dc(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case w:return(n=Oc(t.type,t.key,t.props,null,e.mode,n)).ref=qo(e,null,t),n.return=e,n;case _:return(t=Bc(t,e.mode,n)).return=e,t;case N:return p(e,(0,t._init)(t._payload),n)}if(te(t)||O(t))return(t=Ic(t,e.mode,n,null)).return=e,t;Go(e,t)}return null}function f(e,t,n,a){var r=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n)return null!==r?null:l(e,t,""+n,a);if("object"==typeof n&&null!==n){switch(n.$$typeof){case w:return n.key===r?c(e,t,n,a):null;case _:return n.key===r?u(e,t,n,a):null;case N:return f(e,t,(r=n._init)(n._payload),a)}if(te(n)||O(n))return null!==r?null:d(e,t,n,a,null);Go(e,n)}return null}function g(e,t,n,a,r){if("string"==typeof a&&""!==a||"number"==typeof a)return l(t,e=e.get(n)||null,""+a,r);if("object"==typeof a&&null!==a){switch(a.$$typeof){case w:return c(t,e=e.get(null===a.key?n:a.key)||null,a,r);case _:return u(t,e=e.get(null===a.key?n:a.key)||null,a,r);case N:return g(e,t,n,(0,a._init)(a._payload),r)}if(te(a)||O(a))return d(t,e=e.get(n)||null,a,r,null);Go(t,a)}return null}function h(r,o,s,l){for(var c=null,u=null,d=o,h=o=0,m=null;null!==d&&h<s.length;h++){d.index>h?(m=d,d=null):m=d.sibling;var b=f(r,d,s[h],l);if(null===b){null===d&&(d=m);break}e&&d&&null===b.alternate&&t(r,d),o=i(b,o,h),null===u?c=b:u.sibling=b,u=b,d=m}if(h===s.length)return n(r,d),ro&&Xr(r,h),c;if(null===d){for(;h<s.length;h++)null!==(d=p(r,s[h],l))&&(o=i(d,o,h),null===u?c=d:u.sibling=d,u=d);return ro&&Xr(r,h),c}for(d=a(r,d);h<s.length;h++)null!==(m=g(d,r,h,s[h],l))&&(e&&null!==m.alternate&&d.delete(null===m.key?h:m.key),o=i(m,o,h),null===u?c=m:u.sibling=m,u=m);return e&&d.forEach((function(e){return t(r,e)})),ro&&Xr(r,h),c}function m(r,s,l,c){var u=O(l);if("function"!=typeof u)throw Error(o(150));if(null==(l=u.call(l)))throw Error(o(151));for(var d=u=null,h=s,m=s=0,b=null,y=l.next();null!==h&&!y.done;m++,y=l.next()){h.index>m?(b=h,h=null):b=h.sibling;var v=f(r,h,y.value,c);if(null===v){null===h&&(h=b);break}e&&h&&null===v.alternate&&t(r,h),s=i(v,s,m),null===d?u=v:d.sibling=v,d=v,h=b}if(y.done)return n(r,h),ro&&Xr(r,m),u;if(null===h){for(;!y.done;m++,y=l.next())null!==(y=p(r,y.value,c))&&(s=i(y,s,m),null===d?u=y:d.sibling=y,d=y);return ro&&Xr(r,m),u}for(h=a(r,h);!y.done;m++,y=l.next())null!==(y=g(h,r,m,y.value,c))&&(e&&null!==y.alternate&&h.delete(null===y.key?m:y.key),s=i(y,s,m),null===d?u=y:d.sibling=y,d=y);return e&&h.forEach((function(e){return t(r,e)})),ro&&Xr(r,m),u}return function e(a,o,i,l){if("object"==typeof i&&null!==i&&i.type===k&&null===i.key&&(i=i.props.children),"object"==typeof i&&null!==i){switch(i.$$typeof){case w:e:{for(var c=i.key,u=o;null!==u;){if(u.key===c){if((c=i.type)===k){if(7===u.tag){n(a,u.sibling),(o=r(u,i.props.children)).return=a,a=o;break e}}else if(u.elementType===c||"object"==typeof c&&null!==c&&c.$$typeof===N&&Ko(c)===u.type){n(a,u.sibling),(o=r(u,i.props)).ref=qo(a,u,i),o.return=a,a=o;break e}n(a,u);break}t(a,u),u=u.sibling}i.type===k?((o=Ic(i.props.children,a.mode,l,i.key)).return=a,a=o):((l=Oc(i.type,i.key,i.props,null,a.mode,l)).ref=qo(a,o,i),l.return=a,a=l)}return s(a);case _:e:{for(u=i.key;null!==o;){if(o.key===u){if(4===o.tag&&o.stateNode.containerInfo===i.containerInfo&&o.stateNode.implementation===i.implementation){n(a,o.sibling),(o=r(o,i.children||[])).return=a,a=o;break e}n(a,o);break}t(a,o),o=o.sibling}(o=Bc(i,a.mode,l)).return=a,a=o}return s(a);case N:return e(a,o,(u=i._init)(i._payload),l)}if(te(i))return h(a,o,i,l);if(O(i))return m(a,o,i,l);Go(a,i)}return"string"==typeof i&&""!==i||"number"==typeof i?(i=""+i,null!==o&&6===o.tag?(n(a,o.sibling),(o=r(o,i)).return=a,a=o):(n(a,o),(o=Dc(i,a.mode,l)).return=a,a=o),s(a)):n(a,o)}}var Qo=Yo(!0),Xo=Yo(!1),Jo={},ei=Sr(Jo),ti=Sr(Jo),ni=Sr(Jo);function ai(e){if(e===Jo)throw Error(o(174));return e}function ri(e,t){switch(jr(ni,t),jr(ti,e),jr(ei,Jo),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:le(null,"");break;default:t=le(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}Er(ei),jr(ei,t)}function oi(){Er(ei),Er(ti),Er(ni)}function ii(e){ai(ni.current);var t=ai(ei.current),n=le(t,e.type);t!==n&&(jr(ti,e),jr(ei,n))}function si(e){ti.current===e&&(Er(ei),Er(ti))}var li=Sr(0);function ci(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(128&t.flags))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var ui=[];function di(){for(var e=0;e<ui.length;e++)ui[e]._workInProgressVersionPrimary=null;ui.length=0}var pi=x.ReactCurrentDispatcher,fi=x.ReactCurrentBatchConfig,gi=0,hi=null,mi=null,bi=null,yi=!1,vi=!1,xi=0,wi=0;function _i(){throw Error(o(321))}function ki(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!sa(e[n],t[n]))return!1;return!0}function Si(e,t,n,a,r,i){if(gi=i,hi=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,pi.current=null===e||null===e.memoizedState?ss:ls,e=n(a,r),vi){i=0;do{if(vi=!1,xi=0,25<=i)throw Error(o(301));i+=1,bi=mi=null,t.updateQueue=null,pi.current=cs,e=n(a,r)}while(vi)}if(pi.current=is,t=null!==mi&&null!==mi.next,gi=0,bi=mi=hi=null,yi=!1,t)throw Error(o(300));return e}function Ei(){var e=0!==xi;return xi=0,e}function ji(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===bi?hi.memoizedState=bi=e:bi=bi.next=e,bi}function Ci(){if(null===mi){var e=hi.alternate;e=null!==e?e.memoizedState:null}else e=mi.next;var t=null===bi?hi.memoizedState:bi.next;if(null!==t)bi=t,mi=e;else{if(null===e)throw Error(o(310));e={memoizedState:(mi=e).memoizedState,baseState:mi.baseState,baseQueue:mi.baseQueue,queue:mi.queue,next:null},null===bi?hi.memoizedState=bi=e:bi=bi.next=e}return bi}function Ti(e,t){return"function"==typeof t?t(e):t}function Ai(e){var t=Ci(),n=t.queue;if(null===n)throw Error(o(311));n.lastRenderedReducer=e;var a=mi,r=a.baseQueue,i=n.pending;if(null!==i){if(null!==r){var s=r.next;r.next=i.next,i.next=s}a.baseQueue=r=i,n.pending=null}if(null!==r){i=r.next,a=a.baseState;var l=s=null,c=null,u=i;do{var d=u.lane;if((gi&d)===d)null!==c&&(c=c.next={lane:0,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),a=u.hasEagerState?u.eagerState:e(a,u.action);else{var p={lane:d,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null};null===c?(l=c=p,s=a):c=c.next=p,hi.lanes|=d,Fl|=d}u=u.next}while(null!==u&&u!==i);null===c?s=a:c.next=l,sa(a,t.memoizedState)||(xs=!0),t.memoizedState=a,t.baseState=s,t.baseQueue=c,n.lastRenderedState=a}if(null!==(e=n.interleaved)){r=e;do{i=r.lane,hi.lanes|=i,Fl|=i,r=r.next}while(r!==e)}else null===r&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function Li(e){var t=Ci(),n=t.queue;if(null===n)throw Error(o(311));n.lastRenderedReducer=e;var a=n.dispatch,r=n.pending,i=t.memoizedState;if(null!==r){n.pending=null;var s=r=r.next;do{i=e(i,s.action),s=s.next}while(s!==r);sa(i,t.memoizedState)||(xs=!0),t.memoizedState=i,null===t.baseQueue&&(t.baseState=i),n.lastRenderedState=i}return[i,a]}function Pi(){}function Ni(e,t){var n=hi,a=Ci(),r=t(),i=!sa(a.memoizedState,r);if(i&&(a.memoizedState=r,xs=!0),a=a.queue,Hi(Oi.bind(null,n,a,e),[e]),a.getSnapshot!==t||i||null!==bi&&1&bi.memoizedState.tag){if(n.flags|=2048,Bi(9,Ri.bind(null,n,a,r,t),void 0,null),null===Ll)throw Error(o(349));0!=(30&gi)||Mi(n,t,r)}return r}function Mi(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=hi.updateQueue)?(t={lastEffect:null,stores:null},hi.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Ri(e,t,n,a){t.value=n,t.getSnapshot=a,Ii(t)&&Fi(e)}function Oi(e,t,n){return n((function(){Ii(t)&&Fi(e)}))}function Ii(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!sa(e,n)}catch(a){return!0}}function Fi(e){var t=Lo(e,1);null!==t&&ac(t,e,1,-1)}function Di(e){var t=ji();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:Ti,lastRenderedState:e},t.queue=e,e=e.dispatch=ns.bind(null,hi,e),[t.memoizedState,e]}function Bi(e,t,n,a){return e={tag:e,create:t,destroy:n,deps:a,next:null},null===(t=hi.updateQueue)?(t={lastEffect:null,stores:null},hi.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(a=n.next,n.next=e,e.next=a,t.lastEffect=e),e}function zi(){return Ci().memoizedState}function $i(e,t,n,a){var r=ji();hi.flags|=e,r.memoizedState=Bi(1|t,n,void 0,void 0===a?null:a)}function Ui(e,t,n,a){var r=Ci();a=void 0===a?null:a;var o=void 0;if(null!==mi){var i=mi.memoizedState;if(o=i.destroy,null!==a&&ki(a,i.deps))return void(r.memoizedState=Bi(t,n,o,a))}hi.flags|=e,r.memoizedState=Bi(1|t,n,o,a)}function Zi(e,t){return $i(8390656,8,e,t)}function Hi(e,t){return Ui(2048,8,e,t)}function Vi(e,t){return Ui(4,2,e,t)}function Wi(e,t){return Ui(4,4,e,t)}function qi(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Gi(e,t,n){return n=null!=n?n.concat([e]):null,Ui(4,4,qi.bind(null,t,e),n)}function Ki(){}function Yi(e,t){var n=Ci();t=void 0===t?null:t;var a=n.memoizedState;return null!==a&&null!==t&&ki(t,a[1])?a[0]:(n.memoizedState=[e,t],e)}function Qi(e,t){var n=Ci();t=void 0===t?null:t;var a=n.memoizedState;return null!==a&&null!==t&&ki(t,a[1])?a[0]:(e=e(),n.memoizedState=[e,t],e)}function Xi(e,t,n){return 0==(21&gi)?(e.baseState&&(e.baseState=!1,xs=!0),e.memoizedState=n):(sa(n,t)||(n=ht(),hi.lanes|=n,Fl|=n,e.baseState=!0),t)}function Ji(e,t){var n=vt;vt=0!==n&&4>n?n:4,e(!0);var a=fi.transition;fi.transition={};try{e(!1),t()}finally{vt=n,fi.transition=a}}function es(){return Ci().memoizedState}function ts(e,t,n){var a=nc(e);if(n={lane:a,action:n,hasEagerState:!1,eagerState:null,next:null},as(e))rs(t,n);else if(null!==(n=Ao(e,t,n,a))){ac(n,e,a,tc()),os(n,t,a)}}function ns(e,t,n){var a=nc(e),r={lane:a,action:n,hasEagerState:!1,eagerState:null,next:null};if(as(e))rs(t,r);else{var o=e.alternate;if(0===e.lanes&&(null===o||0===o.lanes)&&null!==(o=t.lastRenderedReducer))try{var i=t.lastRenderedState,s=o(i,n);if(r.hasEagerState=!0,r.eagerState=s,sa(s,i)){var l=t.interleaved;return null===l?(r.next=r,To(t)):(r.next=l.next,l.next=r),void(t.interleaved=r)}}catch(c){}null!==(n=Ao(e,t,r,a))&&(ac(n,e,a,r=tc()),os(n,t,a))}}function as(e){var t=e.alternate;return e===hi||null!==t&&t===hi}function rs(e,t){vi=yi=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function os(e,t,n){if(0!=(4194240&n)){var a=t.lanes;n|=a&=e.pendingLanes,t.lanes=n,yt(e,n)}}var is={readContext:jo,useCallback:_i,useContext:_i,useEffect:_i,useImperativeHandle:_i,useInsertionEffect:_i,useLayoutEffect:_i,useMemo:_i,useReducer:_i,useRef:_i,useState:_i,useDebugValue:_i,useDeferredValue:_i,useTransition:_i,useMutableSource:_i,useSyncExternalStore:_i,useId:_i,unstable_isNewReconciler:!1},ss={readContext:jo,useCallback:function(e,t){return ji().memoizedState=[e,void 0===t?null:t],e},useContext:jo,useEffect:Zi,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,$i(4194308,4,qi.bind(null,t,e),n)},useLayoutEffect:function(e,t){return $i(4194308,4,e,t)},useInsertionEffect:function(e,t){return $i(4,2,e,t)},useMemo:function(e,t){var n=ji();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var a=ji();return t=void 0!==n?n(t):t,a.memoizedState=a.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},a.queue=e,e=e.dispatch=ts.bind(null,hi,e),[a.memoizedState,e]},useRef:function(e){return e={current:e},ji().memoizedState=e},useState:Di,useDebugValue:Ki,useDeferredValue:function(e){return ji().memoizedState=e},useTransition:function(){var e=Di(!1),t=e[0];return e=Ji.bind(null,e[1]),ji().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var a=hi,r=ji();if(ro){if(void 0===n)throw Error(o(407));n=n()}else{if(n=t(),null===Ll)throw Error(o(349));0!=(30&gi)||Mi(a,t,n)}r.memoizedState=n;var i={value:n,getSnapshot:t};return r.queue=i,Zi(Oi.bind(null,a,i,e),[e]),a.flags|=2048,Bi(9,Ri.bind(null,a,i,n,t),void 0,null),n},useId:function(){var e=ji(),t=Ll.identifierPrefix;if(ro){var n=Qr;t=":"+t+"R"+(n=(Yr&~(1<<32-it(Yr)-1)).toString(32)+n),0<(n=xi++)&&(t+="H"+n.toString(32)),t+=":"}else t=":"+t+"r"+(n=wi++).toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},ls={readContext:jo,useCallback:Yi,useContext:jo,useEffect:Hi,useImperativeHandle:Gi,useInsertionEffect:Vi,useLayoutEffect:Wi,useMemo:Qi,useReducer:Ai,useRef:zi,useState:function(){return Ai(Ti)},useDebugValue:Ki,useDeferredValue:function(e){return Xi(Ci(),mi.memoizedState,e)},useTransition:function(){return[Ai(Ti)[0],Ci().memoizedState]},useMutableSource:Pi,useSyncExternalStore:Ni,useId:es,unstable_isNewReconciler:!1},cs={readContext:jo,useCallback:Yi,useContext:jo,useEffect:Hi,useImperativeHandle:Gi,useInsertionEffect:Vi,useLayoutEffect:Wi,useMemo:Qi,useReducer:Li,useRef:zi,useState:function(){return Li(Ti)},useDebugValue:Ki,useDeferredValue:function(e){var t=Ci();return null===mi?t.memoizedState=e:Xi(t,mi.memoizedState,e)},useTransition:function(){return[Li(Ti)[0],Ci().memoizedState]},useMutableSource:Pi,useSyncExternalStore:Ni,useId:es,unstable_isNewReconciler:!1};function us(e,t){try{var n="",a=t;do{n+=$(a),a=a.return}while(a);var r=n}catch(o){r="\nError generating stack: "+o.message+"\n"+o.stack}return{value:e,source:t,stack:r,digest:null}}function ds(e,t,n){return{value:e,source:null,stack:null!=n?n:null,digest:null!=t?t:null}}function ps(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}var fs="function"==typeof WeakMap?WeakMap:Map;function gs(e,t,n){(n=Ro(-1,n)).tag=3,n.payload={element:null};var a=t.value;return n.callback=function(){Vl||(Vl=!0,Wl=a),ps(0,t)},n}function hs(e,t,n){(n=Ro(-1,n)).tag=3;var a=e.type.getDerivedStateFromError;if("function"==typeof a){var r=t.value;n.payload=function(){return a(r)},n.callback=function(){ps(0,t)}}var o=e.stateNode;return null!==o&&"function"==typeof o.componentDidCatch&&(n.callback=function(){ps(0,t),"function"!=typeof a&&(null===ql?ql=new Set([this]):ql.add(this));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}function ms(e,t,n){var a=e.pingCache;if(null===a){a=e.pingCache=new fs;var r=new Set;a.set(t,r)}else void 0===(r=a.get(t))&&(r=new Set,a.set(t,r));r.has(n)||(r.add(n),e=jc.bind(null,e,t,n),t.then(e,e))}function bs(e){do{var t;if((t=13===e.tag)&&(t=null===(t=e.memoizedState)||null!==t.dehydrated),t)return e;e=e.return}while(null!==e);return null}function ys(e,t,n,a,r){return 0==(1&e.mode)?(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((t=Ro(-1,1)).tag=2,Oo(n,t,1))),n.lanes|=1),e):(e.flags|=65536,e.lanes=r,e)}var vs=x.ReactCurrentOwner,xs=!1;function ws(e,t,n,a){t.child=null===e?Xo(t,null,n,a):Qo(t,e.child,n,a)}function _s(e,t,n,a,r){n=n.render;var o=t.ref;return Eo(t,r),a=Si(e,t,n,a,o,r),n=Ei(),null===e||xs?(ro&&n&&eo(t),t.flags|=1,ws(e,t,a,r),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~r,Vs(e,t,r))}function ks(e,t,n,a,r){if(null===e){var o=n.type;return"function"!=typeof o||Mc(o)||void 0!==o.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Oc(n.type,null,a,t,t.mode,r)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=o,Ss(e,t,o,a,r))}if(o=e.child,0==(e.lanes&r)){var i=o.memoizedProps;if((n=null!==(n=n.compare)?n:la)(i,a)&&e.ref===t.ref)return Vs(e,t,r)}return t.flags|=1,(e=Rc(o,a)).ref=t.ref,e.return=t,t.child=e}function Ss(e,t,n,a,r){if(null!==e){var o=e.memoizedProps;if(la(o,a)&&e.ref===t.ref){if(xs=!1,t.pendingProps=a=o,0==(e.lanes&r))return t.lanes=e.lanes,Vs(e,t,r);0!=(131072&e.flags)&&(xs=!0)}}return Cs(e,t,n,a,r)}function Es(e,t,n){var a=t.pendingProps,r=a.children,o=null!==e?e.memoizedState:null;if("hidden"===a.mode)if(0==(1&t.mode))t.memoizedState={baseLanes:0,cachePool:null,transitions:null},jr(Rl,Ml),Ml|=n;else{if(0==(1073741824&n))return e=null!==o?o.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,jr(Rl,Ml),Ml|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},a=null!==o?o.baseLanes:n,jr(Rl,Ml),Ml|=a}else null!==o?(a=o.baseLanes|n,t.memoizedState=null):a=n,jr(Rl,Ml),Ml|=a;return ws(e,t,r,n),t.child}function js(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Cs(e,t,n,a,r){var o=Nr(n)?Lr:Tr.current;return o=Pr(t,o),Eo(t,r),n=Si(e,t,n,a,o,r),a=Ei(),null===e||xs?(ro&&a&&eo(t),t.flags|=1,ws(e,t,n,r),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~r,Vs(e,t,r))}function Ts(e,t,n,a,r){if(Nr(n)){var o=!0;Ir(t)}else o=!1;if(Eo(t,r),null===t.stateNode)Hs(e,t),Ho(t,n,a),Wo(t,n,a,r),a=!0;else if(null===e){var i=t.stateNode,s=t.memoizedProps;i.props=s;var l=i.context,c=n.contextType;"object"==typeof c&&null!==c?c=jo(c):c=Pr(t,c=Nr(n)?Lr:Tr.current);var u=n.getDerivedStateFromProps,d="function"==typeof u||"function"==typeof i.getSnapshotBeforeUpdate;d||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(s!==a||l!==c)&&Vo(t,i,a,c),Po=!1;var p=t.memoizedState;i.state=p,Do(t,a,i,r),l=t.memoizedState,s!==a||p!==l||Ar.current||Po?("function"==typeof u&&($o(t,n,u,a),l=t.memoizedState),(s=Po||Zo(t,n,s,a,p,l,c))?(d||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4194308)):("function"==typeof i.componentDidMount&&(t.flags|=4194308),t.memoizedProps=a,t.memoizedState=l),i.props=a,i.state=l,i.context=c,a=s):("function"==typeof i.componentDidMount&&(t.flags|=4194308),a=!1)}else{i=t.stateNode,Mo(e,t),s=t.memoizedProps,c=t.type===t.elementType?s:bo(t.type,s),i.props=c,d=t.pendingProps,p=i.context,"object"==typeof(l=n.contextType)&&null!==l?l=jo(l):l=Pr(t,l=Nr(n)?Lr:Tr.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(s!==d||p!==l)&&Vo(t,i,a,l),Po=!1,p=t.memoizedState,i.state=p,Do(t,a,i,r);var g=t.memoizedState;s!==d||p!==g||Ar.current||Po?("function"==typeof f&&($o(t,n,f,a),g=t.memoizedState),(c=Po||Zo(t,n,c,a,p,g,l)||!1)?(u||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(a,g,l),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(a,g,l)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof i.componentDidUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),t.memoizedProps=a,t.memoizedState=g),i.props=a,i.state=g,i.context=l,a=c):("function"!=typeof i.componentDidUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||s===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),a=!1)}return As(e,t,n,a,o,r)}function As(e,t,n,a,r,o){js(e,t);var i=0!=(128&t.flags);if(!a&&!i)return r&&Fr(t,n,!1),Vs(e,t,o);a=t.stateNode,vs.current=t;var s=i&&"function"!=typeof n.getDerivedStateFromError?null:a.render();return t.flags|=1,null!==e&&i?(t.child=Qo(t,e.child,null,o),t.child=Qo(t,null,s,o)):ws(e,t,s,o),t.memoizedState=a.state,r&&Fr(t,n,!0),t.child}function Ls(e){var t=e.stateNode;t.pendingContext?Rr(0,t.pendingContext,t.pendingContext!==t.context):t.context&&Rr(0,t.context,!1),ri(e,t.containerInfo)}function Ps(e,t,n,a,r){return go(),ho(r),t.flags|=256,ws(e,t,n,a),t.child}var Ns,Ms,Rs,Os,Is={dehydrated:null,treeContext:null,retryLane:0};function Fs(e){return{baseLanes:e,cachePool:null,transitions:null}}function Ds(e,t,n){var a,r=t.pendingProps,i=li.current,s=!1,l=0!=(128&t.flags);if((a=l)||(a=(null===e||null!==e.memoizedState)&&0!=(2&i)),a?(s=!0,t.flags&=-129):null!==e&&null===e.memoizedState||(i|=1),jr(li,1&i),null===e)return co(t),null!==(e=t.memoizedState)&&null!==(e=e.dehydrated)?(0==(1&t.mode)?t.lanes=1:"$!"===e.data?t.lanes=8:t.lanes=1073741824,null):(l=r.children,e=r.fallback,s?(r=t.mode,s=t.child,l={mode:"hidden",children:l},0==(1&r)&&null!==s?(s.childLanes=0,s.pendingProps=l):s=Fc(l,r,0,null),e=Ic(e,r,n,null),s.return=t,e.return=t,s.sibling=e,t.child=s,t.child.memoizedState=Fs(n),t.memoizedState=Is,e):Bs(t,l));if(null!==(i=e.memoizedState)&&null!==(a=i.dehydrated))return function(e,t,n,a,r,i,s){if(n)return 256&t.flags?(t.flags&=-257,zs(e,t,s,a=ds(Error(o(422))))):null!==t.memoizedState?(t.child=e.child,t.flags|=128,null):(i=a.fallback,r=t.mode,a=Fc({mode:"visible",children:a.children},r,0,null),(i=Ic(i,r,s,null)).flags|=2,a.return=t,i.return=t,a.sibling=i,t.child=a,0!=(1&t.mode)&&Qo(t,e.child,null,s),t.child.memoizedState=Fs(s),t.memoizedState=Is,i);if(0==(1&t.mode))return zs(e,t,s,null);if("$!"===r.data){if(a=r.nextSibling&&r.nextSibling.dataset)var l=a.dgst;return a=l,zs(e,t,s,a=ds(i=Error(o(419)),a,void 0))}if(l=0!=(s&e.childLanes),xs||l){if(null!==(a=Ll)){switch(s&-s){case 4:r=2;break;case 16:r=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:r=32;break;case 536870912:r=268435456;break;default:r=0}0!==(r=0!=(r&(a.suspendedLanes|s))?0:r)&&r!==i.retryLane&&(i.retryLane=r,Lo(e,r),ac(a,e,r,-1))}return mc(),zs(e,t,s,a=ds(Error(o(421))))}return"$?"===r.data?(t.flags|=128,t.child=e.child,t=Tc.bind(null,e),r._reactRetry=t,null):(e=i.treeContext,ao=cr(r.nextSibling),no=t,ro=!0,oo=null,null!==e&&(qr[Gr++]=Yr,qr[Gr++]=Qr,qr[Gr++]=Kr,Yr=e.id,Qr=e.overflow,Kr=t),t=Bs(t,a.children),t.flags|=4096,t)}(e,t,l,r,a,i,n);if(s){s=r.fallback,l=t.mode,a=(i=e.child).sibling;var c={mode:"hidden",children:r.children};return 0==(1&l)&&t.child!==i?((r=t.child).childLanes=0,r.pendingProps=c,t.deletions=null):(r=Rc(i,c)).subtreeFlags=14680064&i.subtreeFlags,null!==a?s=Rc(a,s):(s=Ic(s,l,n,null)).flags|=2,s.return=t,r.return=t,r.sibling=s,t.child=r,r=s,s=t.child,l=null===(l=e.child.memoizedState)?Fs(n):{baseLanes:l.baseLanes|n,cachePool:null,transitions:l.transitions},s.memoizedState=l,s.childLanes=e.childLanes&~n,t.memoizedState=Is,r}return e=(s=e.child).sibling,r=Rc(s,{mode:"visible",children:r.children}),0==(1&t.mode)&&(r.lanes=n),r.return=t,r.sibling=null,null!==e&&(null===(n=t.deletions)?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=r,t.memoizedState=null,r}function Bs(e,t){return(t=Fc({mode:"visible",children:t},e.mode,0,null)).return=e,e.child=t}function zs(e,t,n,a){return null!==a&&ho(a),Qo(t,e.child,null,n),(e=Bs(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function $s(e,t,n){e.lanes|=t;var a=e.alternate;null!==a&&(a.lanes|=t),So(e.return,t,n)}function Us(e,t,n,a,r){var o=e.memoizedState;null===o?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:a,tail:n,tailMode:r}:(o.isBackwards=t,o.rendering=null,o.renderingStartTime=0,o.last=a,o.tail=n,o.tailMode=r)}function Zs(e,t,n){var a=t.pendingProps,r=a.revealOrder,o=a.tail;if(ws(e,t,a.children,n),0!=(2&(a=li.current)))a=1&a|2,t.flags|=128;else{if(null!==e&&0!=(128&e.flags))e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&$s(e,n,t);else if(19===e.tag)$s(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}a&=1}if(jr(li,a),0==(1&t.mode))t.memoizedState=null;else switch(r){case"forwards":for(n=t.child,r=null;null!==n;)null!==(e=n.alternate)&&null===ci(e)&&(r=n),n=n.sibling;null===(n=r)?(r=t.child,t.child=null):(r=n.sibling,n.sibling=null),Us(t,!1,r,n,o);break;case"backwards":for(n=null,r=t.child,t.child=null;null!==r;){if(null!==(e=r.alternate)&&null===ci(e)){t.child=r;break}e=r.sibling,r.sibling=n,n=r,r=e}Us(t,!0,n,null,o);break;case"together":Us(t,!1,null,null,void 0);break;default:t.memoizedState=null}return t.child}function Hs(e,t){0==(1&t.mode)&&null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Vs(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Fl|=t.lanes,0==(n&t.childLanes))return null;if(null!==e&&t.child!==e.child)throw Error(o(153));if(null!==t.child){for(n=Rc(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Rc(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Ws(e,t){if(!ro)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var a=null;null!==n;)null!==n.alternate&&(a=n),n=n.sibling;null===a?t||null===e.tail?e.tail=null:e.tail.sibling=null:a.sibling=null}}function qs(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,a=0;if(t)for(var r=e.child;null!==r;)n|=r.lanes|r.childLanes,a|=14680064&r.subtreeFlags,a|=14680064&r.flags,r.return=e,r=r.sibling;else for(r=e.child;null!==r;)n|=r.lanes|r.childLanes,a|=r.subtreeFlags,a|=r.flags,r.return=e,r=r.sibling;return e.subtreeFlags|=a,e.childLanes=n,t}function Gs(e,t,n){var a=t.pendingProps;switch(to(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return qs(t),null;case 1:case 17:return Nr(t.type)&&Mr(),qs(t),null;case 3:return a=t.stateNode,oi(),Er(Ar),Er(Tr),di(),a.pendingContext&&(a.context=a.pendingContext,a.pendingContext=null),null!==e&&null!==e.child||(po(t)?t.flags|=4:null===e||e.memoizedState.isDehydrated&&0==(256&t.flags)||(t.flags|=1024,null!==oo&&(sc(oo),oo=null))),Ms(e,t),qs(t),null;case 5:si(t);var r=ai(ni.current);if(n=t.type,null!==e&&null!=t.stateNode)Rs(e,t,n,a,r),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!a){if(null===t.stateNode)throw Error(o(166));return qs(t),null}if(e=ai(ei.current),po(t)){a=t.stateNode,n=t.type;var i=t.memoizedProps;switch(a[pr]=t,a[fr]=i,e=0!=(1&t.mode),n){case"dialog":Ba("cancel",a),Ba("close",a);break;case"iframe":case"object":case"embed":Ba("load",a);break;case"video":case"audio":for(r=0;r<Oa.length;r++)Ba(Oa[r],a);break;case"source":Ba("error",a);break;case"img":case"image":case"link":Ba("error",a),Ba("load",a);break;case"details":Ba("toggle",a);break;case"input":Y(a,i),Ba("invalid",a);break;case"select":a._wrapperState={wasMultiple:!!i.multiple},Ba("invalid",a);break;case"textarea":re(a,i),Ba("invalid",a)}for(var l in ye(n,i),r=null,i)if(i.hasOwnProperty(l)){var c=i[l];"children"===l?"string"==typeof c?a.textContent!==c&&(!0!==i.suppressHydrationWarning&&Xa(a.textContent,c,e),r=["children",c]):"number"==typeof c&&a.textContent!==""+c&&(!0!==i.suppressHydrationWarning&&Xa(a.textContent,c,e),r=["children",""+c]):s.hasOwnProperty(l)&&null!=c&&"onScroll"===l&&Ba("scroll",a)}switch(n){case"input":W(a),J(a,i,!0);break;case"textarea":W(a),ie(a);break;case"select":case"option":break;default:"function"==typeof i.onClick&&(a.onclick=Ja)}a=r,t.updateQueue=a,null!==a&&(t.flags|=4)}else{l=9===r.nodeType?r:r.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=se(n)),"http://www.w3.org/1999/xhtml"===e?"script"===n?((e=l.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof a.is?e=l.createElement(n,{is:a.is}):(e=l.createElement(n),"select"===n&&(l=e,a.multiple?l.multiple=!0:a.size&&(l.size=a.size))):e=l.createElementNS(e,n),e[pr]=t,e[fr]=a,Ns(e,t,!1,!1),t.stateNode=e;e:{switch(l=ve(n,a),n){case"dialog":Ba("cancel",e),Ba("close",e),r=a;break;case"iframe":case"object":case"embed":Ba("load",e),r=a;break;case"video":case"audio":for(r=0;r<Oa.length;r++)Ba(Oa[r],e);r=a;break;case"source":Ba("error",e),r=a;break;case"img":case"image":case"link":Ba("error",e),Ba("load",e),r=a;break;case"details":Ba("toggle",e),r=a;break;case"input":Y(e,a),r=K(e,a),Ba("invalid",e);break;case"option":default:r=a;break;case"select":e._wrapperState={wasMultiple:!!a.multiple},r=F({},a,{value:void 0}),Ba("invalid",e);break;case"textarea":re(e,a),r=ae(e,a),Ba("invalid",e)}for(i in ye(n,r),c=r)if(c.hasOwnProperty(i)){var u=c[i];"style"===i?me(e,u):"dangerouslySetInnerHTML"===i?null!=(u=u?u.__html:void 0)&&de(e,u):"children"===i?"string"==typeof u?("textarea"!==n||""!==u)&&pe(e,u):"number"==typeof u&&pe(e,""+u):"suppressContentEditableWarning"!==i&&"suppressHydrationWarning"!==i&&"autoFocus"!==i&&(s.hasOwnProperty(i)?null!=u&&"onScroll"===i&&Ba("scroll",e):null!=u&&v(e,i,u,l))}switch(n){case"input":W(e),J(e,a,!1);break;case"textarea":W(e),ie(e);break;case"option":null!=a.value&&e.setAttribute("value",""+H(a.value));break;case"select":e.multiple=!!a.multiple,null!=(i=a.value)?ne(e,!!a.multiple,i,!1):null!=a.defaultValue&&ne(e,!!a.multiple,a.defaultValue,!0);break;default:"function"==typeof r.onClick&&(e.onclick=Ja)}switch(n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break e;case"img":a=!0;break e;default:a=!1}}a&&(t.flags|=4)}null!==t.ref&&(t.flags|=512,t.flags|=2097152)}return qs(t),null;case 6:if(e&&null!=t.stateNode)Os(e,t,e.memoizedProps,a);else{if("string"!=typeof a&&null===t.stateNode)throw Error(o(166));if(n=ai(ni.current),ai(ei.current),po(t)){if(a=t.stateNode,n=t.memoizedProps,a[pr]=t,(i=a.nodeValue!==n)&&null!==(e=no))switch(e.tag){case 3:Xa(a.nodeValue,n,0!=(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Xa(a.nodeValue,n,0!=(1&e.mode))}i&&(t.flags|=4)}else(a=(9===n.nodeType?n:n.ownerDocument).createTextNode(a))[pr]=t,t.stateNode=a}return qs(t),null;case 13:if(Er(li),a=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(ro&&null!==ao&&0!=(1&t.mode)&&0==(128&t.flags))fo(),go(),t.flags|=98560,i=!1;else if(i=po(t),null!==a&&null!==a.dehydrated){if(null===e){if(!i)throw Error(o(318));if(!(i=null!==(i=t.memoizedState)?i.dehydrated:null))throw Error(o(317));i[pr]=t}else go(),0==(128&t.flags)&&(t.memoizedState=null),t.flags|=4;qs(t),i=!1}else null!==oo&&(sc(oo),oo=null),i=!0;if(!i)return 65536&t.flags?t:null}return 0!=(128&t.flags)?(t.lanes=n,t):((a=null!==a)!==(null!==e&&null!==e.memoizedState)&&a&&(t.child.flags|=8192,0!=(1&t.mode)&&(null===e||0!=(1&li.current)?0===Ol&&(Ol=3):mc())),null!==t.updateQueue&&(t.flags|=4),qs(t),null);case 4:return oi(),Ms(e,t),null===e&&Ua(t.stateNode.containerInfo),qs(t),null;case 10:return ko(t.type._context),qs(t),null;case 19:if(Er(li),null===(i=t.memoizedState))return qs(t),null;if(a=0!=(128&t.flags),null===(l=i.rendering))if(a)Ws(i,!1);else{if(0!==Ol||null!==e&&0!=(128&e.flags))for(e=t.child;null!==e;){if(null!==(l=ci(e))){for(t.flags|=128,Ws(i,!1),null!==(a=l.updateQueue)&&(t.updateQueue=a,t.flags|=4),t.subtreeFlags=0,a=n,n=t.child;null!==n;)e=a,(i=n).flags&=14680066,null===(l=i.alternate)?(i.childLanes=0,i.lanes=e,i.child=null,i.subtreeFlags=0,i.memoizedProps=null,i.memoizedState=null,i.updateQueue=null,i.dependencies=null,i.stateNode=null):(i.childLanes=l.childLanes,i.lanes=l.lanes,i.child=l.child,i.subtreeFlags=0,i.deletions=null,i.memoizedProps=l.memoizedProps,i.memoizedState=l.memoizedState,i.updateQueue=l.updateQueue,i.type=l.type,e=l.dependencies,i.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return jr(li,1&li.current|2),t.child}e=e.sibling}null!==i.tail&&Qe()>Zl&&(t.flags|=128,a=!0,Ws(i,!1),t.lanes=4194304)}else{if(!a)if(null!==(e=ci(l))){if(t.flags|=128,a=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Ws(i,!0),null===i.tail&&"hidden"===i.tailMode&&!l.alternate&&!ro)return qs(t),null}else 2*Qe()-i.renderingStartTime>Zl&&1073741824!==n&&(t.flags|=128,a=!0,Ws(i,!1),t.lanes=4194304);i.isBackwards?(l.sibling=t.child,t.child=l):(null!==(n=i.last)?n.sibling=l:t.child=l,i.last=l)}return null!==i.tail?(t=i.tail,i.rendering=t,i.tail=t.sibling,i.renderingStartTime=Qe(),t.sibling=null,n=li.current,jr(li,a?1&n|2:1&n),t):(qs(t),null);case 22:case 23:return pc(),a=null!==t.memoizedState,null!==e&&null!==e.memoizedState!==a&&(t.flags|=8192),a&&0!=(1&t.mode)?0!=(1073741824&Ml)&&(qs(t),6&t.subtreeFlags&&(t.flags|=8192)):qs(t),null;case 24:case 25:return null}throw Error(o(156,t.tag))}function Ks(e,t){switch(to(t),t.tag){case 1:return Nr(t.type)&&Mr(),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return oi(),Er(Ar),Er(Tr),di(),0!=(65536&(e=t.flags))&&0==(128&e)?(t.flags=-65537&e|128,t):null;case 5:return si(t),null;case 13:if(Er(li),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(o(340));go()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return Er(li),null;case 4:return oi(),null;case 10:return ko(t.type._context),null;case 22:case 23:return pc(),null;default:return null}}Ns=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Ms=function(){},Rs=function(e,t,n,a){var r=e.memoizedProps;if(r!==a){e=t.stateNode,ai(ei.current);var o,i=null;switch(n){case"input":r=K(e,r),a=K(e,a),i=[];break;case"select":r=F({},r,{value:void 0}),a=F({},a,{value:void 0}),i=[];break;case"textarea":r=ae(e,r),a=ae(e,a),i=[];break;default:"function"!=typeof r.onClick&&"function"==typeof a.onClick&&(e.onclick=Ja)}for(u in ye(n,a),n=null,r)if(!a.hasOwnProperty(u)&&r.hasOwnProperty(u)&&null!=r[u])if("style"===u){var l=r[u];for(o in l)l.hasOwnProperty(o)&&(n||(n={}),n[o]="")}else"dangerouslySetInnerHTML"!==u&&"children"!==u&&"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(s.hasOwnProperty(u)?i||(i=[]):(i=i||[]).push(u,null));for(u in a){var c=a[u];if(l=null!=r?r[u]:void 0,a.hasOwnProperty(u)&&c!==l&&(null!=c||null!=l))if("style"===u)if(l){for(o in l)!l.hasOwnProperty(o)||c&&c.hasOwnProperty(o)||(n||(n={}),n[o]="");for(o in c)c.hasOwnProperty(o)&&l[o]!==c[o]&&(n||(n={}),n[o]=c[o])}else n||(i||(i=[]),i.push(u,n)),n=c;else"dangerouslySetInnerHTML"===u?(c=c?c.__html:void 0,l=l?l.__html:void 0,null!=c&&l!==c&&(i=i||[]).push(u,c)):"children"===u?"string"!=typeof c&&"number"!=typeof c||(i=i||[]).push(u,""+c):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&(s.hasOwnProperty(u)?(null!=c&&"onScroll"===u&&Ba("scroll",e),i||l===c||(i=[])):(i=i||[]).push(u,c))}n&&(i=i||[]).push("style",n);var u=i;(t.updateQueue=u)&&(t.flags|=4)}},Os=function(e,t,n,a){n!==a&&(t.flags|=4)};var Ys=!1,Qs=!1,Xs="function"==typeof WeakSet?WeakSet:Set,Js=null;function el(e,t){var n=e.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(a){Ec(e,t,a)}else n.current=null}function tl(e,t,n){try{n()}catch(a){Ec(e,t,a)}}var nl=!1;function al(e,t,n){var a=t.updateQueue;if(null!==(a=null!==a?a.lastEffect:null)){var r=a=a.next;do{if((r.tag&e)===e){var o=r.destroy;r.destroy=void 0,void 0!==o&&tl(t,n,o)}r=r.next}while(r!==a)}}function rl(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var a=n.create;n.destroy=a()}n=n.next}while(n!==t)}}function ol(e){var t=e.ref;if(null!==t){var n=e.stateNode;e.tag,e=n,"function"==typeof t?t(e):t.current=e}}function il(e){var t=e.alternate;null!==t&&(e.alternate=null,il(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&(delete t[pr],delete t[fr],delete t[hr],delete t[mr],delete t[br])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function sl(e){return 5===e.tag||3===e.tag||4===e.tag}function ll(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||sl(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function cl(e,t,n){var a=e.tag;if(5===a||6===a)e=e.stateNode,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Ja));else if(4!==a&&null!==(e=e.child))for(cl(e,t,n),e=e.sibling;null!==e;)cl(e,t,n),e=e.sibling}function ul(e,t,n){var a=e.tag;if(5===a||6===a)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==a&&null!==(e=e.child))for(ul(e,t,n),e=e.sibling;null!==e;)ul(e,t,n),e=e.sibling}var dl=null,pl=!1;function fl(e,t,n){for(n=n.child;null!==n;)gl(e,t,n),n=n.sibling}function gl(e,t,n){if(ot&&"function"==typeof ot.onCommitFiberUnmount)try{ot.onCommitFiberUnmount(rt,n)}catch(s){}switch(n.tag){case 5:Qs||el(n,t);case 6:var a=dl,r=pl;dl=null,fl(e,t,n),pl=r,null!==(dl=a)&&(pl?(e=dl,n=n.stateNode,8===e.nodeType?e.parentNode.removeChild(n):e.removeChild(n)):dl.removeChild(n.stateNode));break;case 18:null!==dl&&(pl?(e=dl,n=n.stateNode,8===e.nodeType?lr(e.parentNode,n):1===e.nodeType&&lr(e,n),Ut(e)):lr(dl,n.stateNode));break;case 4:a=dl,r=pl,dl=n.stateNode.containerInfo,pl=!0,fl(e,t,n),dl=a,pl=r;break;case 0:case 11:case 14:case 15:if(!Qs&&(null!==(a=n.updateQueue)&&null!==(a=a.lastEffect))){r=a=a.next;do{var o=r,i=o.destroy;o=o.tag,void 0!==i&&(0!=(2&o)||0!=(4&o))&&tl(n,t,i),r=r.next}while(r!==a)}fl(e,t,n);break;case 1:if(!Qs&&(el(n,t),"function"==typeof(a=n.stateNode).componentWillUnmount))try{a.props=n.memoizedProps,a.state=n.memoizedState,a.componentWillUnmount()}catch(s){Ec(n,t,s)}fl(e,t,n);break;case 21:fl(e,t,n);break;case 22:1&n.mode?(Qs=(a=Qs)||null!==n.memoizedState,fl(e,t,n),Qs=a):fl(e,t,n);break;default:fl(e,t,n)}}function hl(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new Xs),t.forEach((function(t){var a=Ac.bind(null,e,t);n.has(t)||(n.add(t),t.then(a,a))}))}}function ml(e,t){var n=t.deletions;if(null!==n)for(var a=0;a<n.length;a++){var r=n[a];try{var i=e,s=t,l=s;e:for(;null!==l;){switch(l.tag){case 5:dl=l.stateNode,pl=!1;break e;case 3:case 4:dl=l.stateNode.containerInfo,pl=!0;break e}l=l.return}if(null===dl)throw Error(o(160));gl(i,s,r),dl=null,pl=!1;var c=r.alternate;null!==c&&(c.return=null),r.return=null}catch(u){Ec(r,t,u)}}if(12854&t.subtreeFlags)for(t=t.child;null!==t;)bl(t,e),t=t.sibling}function bl(e,t){var n=e.alternate,a=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(ml(t,e),yl(e),4&a){try{al(3,e,e.return),rl(3,e)}catch(m){Ec(e,e.return,m)}try{al(5,e,e.return)}catch(m){Ec(e,e.return,m)}}break;case 1:ml(t,e),yl(e),512&a&&null!==n&&el(n,n.return);break;case 5:if(ml(t,e),yl(e),512&a&&null!==n&&el(n,n.return),32&e.flags){var r=e.stateNode;try{pe(r,"")}catch(m){Ec(e,e.return,m)}}if(4&a&&null!=(r=e.stateNode)){var i=e.memoizedProps,s=null!==n?n.memoizedProps:i,l=e.type,c=e.updateQueue;if(e.updateQueue=null,null!==c)try{"input"===l&&"radio"===i.type&&null!=i.name&&Q(r,i),ve(l,s);var u=ve(l,i);for(s=0;s<c.length;s+=2){var d=c[s],p=c[s+1];"style"===d?me(r,p):"dangerouslySetInnerHTML"===d?de(r,p):"children"===d?pe(r,p):v(r,d,p,u)}switch(l){case"input":X(r,i);break;case"textarea":oe(r,i);break;case"select":var f=r._wrapperState.wasMultiple;r._wrapperState.wasMultiple=!!i.multiple;var g=i.value;null!=g?ne(r,!!i.multiple,g,!1):f!==!!i.multiple&&(null!=i.defaultValue?ne(r,!!i.multiple,i.defaultValue,!0):ne(r,!!i.multiple,i.multiple?[]:"",!1))}r[fr]=i}catch(m){Ec(e,e.return,m)}}break;case 6:if(ml(t,e),yl(e),4&a){if(null===e.stateNode)throw Error(o(162));r=e.stateNode,i=e.memoizedProps;try{r.nodeValue=i}catch(m){Ec(e,e.return,m)}}break;case 3:if(ml(t,e),yl(e),4&a&&null!==n&&n.memoizedState.isDehydrated)try{Ut(t.containerInfo)}catch(m){Ec(e,e.return,m)}break;case 4:default:ml(t,e),yl(e);break;case 13:ml(t,e),yl(e),8192&(r=e.child).flags&&(i=null!==r.memoizedState,r.stateNode.isHidden=i,!i||null!==r.alternate&&null!==r.alternate.memoizedState||(Ul=Qe())),4&a&&hl(e);break;case 22:if(d=null!==n&&null!==n.memoizedState,1&e.mode?(Qs=(u=Qs)||d,ml(t,e),Qs=u):ml(t,e),yl(e),8192&a){if(u=null!==e.memoizedState,(e.stateNode.isHidden=u)&&!d&&0!=(1&e.mode))for(Js=e,d=e.child;null!==d;){for(p=Js=d;null!==Js;){switch(g=(f=Js).child,f.tag){case 0:case 11:case 14:case 15:al(4,f,f.return);break;case 1:el(f,f.return);var h=f.stateNode;if("function"==typeof h.componentWillUnmount){a=f,n=f.return;try{t=a,h.props=t.memoizedProps,h.state=t.memoizedState,h.componentWillUnmount()}catch(m){Ec(a,n,m)}}break;case 5:el(f,f.return);break;case 22:if(null!==f.memoizedState){_l(p);continue}}null!==g?(g.return=f,Js=g):_l(p)}d=d.sibling}e:for(d=null,p=e;;){if(5===p.tag){if(null===d){d=p;try{r=p.stateNode,u?"function"==typeof(i=r.style).setProperty?i.setProperty("display","none","important"):i.display="none":(l=p.stateNode,s=null!=(c=p.memoizedProps.style)&&c.hasOwnProperty("display")?c.display:null,l.style.display=he("display",s))}catch(m){Ec(e,e.return,m)}}}else if(6===p.tag){if(null===d)try{p.stateNode.nodeValue=u?"":p.memoizedProps}catch(m){Ec(e,e.return,m)}}else if((22!==p.tag&&23!==p.tag||null===p.memoizedState||p===e)&&null!==p.child){p.child.return=p,p=p.child;continue}if(p===e)break e;for(;null===p.sibling;){if(null===p.return||p.return===e)break e;d===p&&(d=null),p=p.return}d===p&&(d=null),p.sibling.return=p.return,p=p.sibling}}break;case 19:ml(t,e),yl(e),4&a&&hl(e);case 21:}}function yl(e){var t=e.flags;if(2&t){try{e:{for(var n=e.return;null!==n;){if(sl(n)){var a=n;break e}n=n.return}throw Error(o(160))}switch(a.tag){case 5:var r=a.stateNode;32&a.flags&&(pe(r,""),a.flags&=-33),ul(e,ll(e),r);break;case 3:case 4:var i=a.stateNode.containerInfo;cl(e,ll(e),i);break;default:throw Error(o(161))}}catch(s){Ec(e,e.return,s)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function vl(e,t,n){Js=e,xl(e,t,n)}function xl(e,t,n){for(var a=0!=(1&e.mode);null!==Js;){var r=Js,o=r.child;if(22===r.tag&&a){var i=null!==r.memoizedState||Ys;if(!i){var s=r.alternate,l=null!==s&&null!==s.memoizedState||Qs;s=Ys;var c=Qs;if(Ys=i,(Qs=l)&&!c)for(Js=r;null!==Js;)l=(i=Js).child,22===i.tag&&null!==i.memoizedState?kl(r):null!==l?(l.return=i,Js=l):kl(r);for(;null!==o;)Js=o,xl(o,t,n),o=o.sibling;Js=r,Ys=s,Qs=c}wl(e)}else 0!=(8772&r.subtreeFlags)&&null!==o?(o.return=r,Js=o):wl(e)}}function wl(e){for(;null!==Js;){var t=Js;if(0!=(8772&t.flags)){var n=t.alternate;try{if(0!=(8772&t.flags))switch(t.tag){case 0:case 11:case 15:Qs||rl(5,t);break;case 1:var a=t.stateNode;if(4&t.flags&&!Qs)if(null===n)a.componentDidMount();else{var r=t.elementType===t.type?n.memoizedProps:bo(t.type,n.memoizedProps);a.componentDidUpdate(r,n.memoizedState,a.__reactInternalSnapshotBeforeUpdate)}var i=t.updateQueue;null!==i&&Bo(t,i,a);break;case 3:var s=t.updateQueue;if(null!==s){if(n=null,null!==t.child)switch(t.child.tag){case 5:case 1:n=t.child.stateNode}Bo(t,s,n)}break;case 5:var l=t.stateNode;if(null===n&&4&t.flags){n=l;var c=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":c.autoFocus&&n.focus();break;case"img":c.src&&(n.src=c.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===t.memoizedState){var u=t.alternate;if(null!==u){var d=u.memoizedState;if(null!==d){var p=d.dehydrated;null!==p&&Ut(p)}}}break;default:throw Error(o(163))}Qs||512&t.flags&&ol(t)}catch(f){Ec(t,t.return,f)}}if(t===e){Js=null;break}if(null!==(n=t.sibling)){n.return=t.return,Js=n;break}Js=t.return}}function _l(e){for(;null!==Js;){var t=Js;if(t===e){Js=null;break}var n=t.sibling;if(null!==n){n.return=t.return,Js=n;break}Js=t.return}}function kl(e){for(;null!==Js;){var t=Js;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{rl(4,t)}catch(l){Ec(t,n,l)}break;case 1:var a=t.stateNode;if("function"==typeof a.componentDidMount){var r=t.return;try{a.componentDidMount()}catch(l){Ec(t,r,l)}}var o=t.return;try{ol(t)}catch(l){Ec(t,o,l)}break;case 5:var i=t.return;try{ol(t)}catch(l){Ec(t,i,l)}}}catch(l){Ec(t,t.return,l)}if(t===e){Js=null;break}var s=t.sibling;if(null!==s){s.return=t.return,Js=s;break}Js=t.return}}var Sl,El=Math.ceil,jl=x.ReactCurrentDispatcher,Cl=x.ReactCurrentOwner,Tl=x.ReactCurrentBatchConfig,Al=0,Ll=null,Pl=null,Nl=0,Ml=0,Rl=Sr(0),Ol=0,Il=null,Fl=0,Dl=0,Bl=0,zl=null,$l=null,Ul=0,Zl=1/0,Hl=null,Vl=!1,Wl=null,ql=null,Gl=!1,Kl=null,Yl=0,Ql=0,Xl=null,Jl=-1,ec=0;function tc(){return 0!=(6&Al)?Qe():-1!==Jl?Jl:Jl=Qe()}function nc(e){return 0==(1&e.mode)?1:0!=(2&Al)&&0!==Nl?Nl&-Nl:null!==mo.transition?(0===ec&&(ec=ht()),ec):0!==(e=vt)?e:e=void 0===(e=window.event)?16:Yt(e.type)}function ac(e,t,n,a){if(50<Ql)throw Ql=0,Xl=null,Error(o(185));bt(e,n,a),0!=(2&Al)&&e===Ll||(e===Ll&&(0==(2&Al)&&(Dl|=n),4===Ol&&lc(e,Nl)),rc(e,a),1===n&&0===Al&&0==(1&t.mode)&&(Zl=Qe()+500,Br&&Ur()))}function rc(e,t){var n=e.callbackNode;!function(e,t){for(var n=e.suspendedLanes,a=e.pingedLanes,r=e.expirationTimes,o=e.pendingLanes;0<o;){var i=31-it(o),s=1<<i,l=r[i];-1===l?0!=(s&n)&&0==(s&a)||(r[i]=ft(s,t)):l<=t&&(e.expiredLanes|=s),o&=~s}}(e,t);var a=pt(e,e===Ll?Nl:0);if(0===a)null!==n&&Ge(n),e.callbackNode=null,e.callbackPriority=0;else if(t=a&-a,e.callbackPriority!==t){if(null!=n&&Ge(n),1===t)0===e.tag?function(e){Br=!0,$r(e)}(cc.bind(null,e)):$r(cc.bind(null,e)),ir((function(){0==(6&Al)&&Ur()})),n=null;else{switch(xt(a)){case 1:n=Je;break;case 4:n=et;break;case 16:default:n=tt;break;case 536870912:n=at}n=Lc(n,oc.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function oc(e,t){if(Jl=-1,ec=0,0!=(6&Al))throw Error(o(327));var n=e.callbackNode;if(kc()&&e.callbackNode!==n)return null;var a=pt(e,e===Ll?Nl:0);if(0===a)return null;if(0!=(30&a)||0!=(a&e.expiredLanes)||t)t=bc(e,a);else{t=a;var r=Al;Al|=2;var i=hc();for(Ll===e&&Nl===t||(Hl=null,Zl=Qe()+500,fc(e,t));;)try{vc();break}catch(l){gc(e,l)}_o(),jl.current=i,Al=r,null!==Pl?t=0:(Ll=null,Nl=0,t=Ol)}if(0!==t){if(2===t&&(0!==(r=gt(e))&&(a=r,t=ic(e,r))),1===t)throw n=Il,fc(e,0),lc(e,a),rc(e,Qe()),n;if(6===t)lc(e,a);else{if(r=e.current.alternate,0==(30&a)&&!function(e){for(var t=e;;){if(16384&t.flags){var n=t.updateQueue;if(null!==n&&null!==(n=n.stores))for(var a=0;a<n.length;a++){var r=n[a],o=r.getSnapshot;r=r.value;try{if(!sa(o(),r))return!1}catch(s){return!1}}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}(r)&&(2===(t=bc(e,a))&&(0!==(i=gt(e))&&(a=i,t=ic(e,i))),1===t))throw n=Il,fc(e,0),lc(e,a),rc(e,Qe()),n;switch(e.finishedWork=r,e.finishedLanes=a,t){case 0:case 1:throw Error(o(345));case 2:case 5:_c(e,$l,Hl);break;case 3:if(lc(e,a),(130023424&a)===a&&10<(t=Ul+500-Qe())){if(0!==pt(e,0))break;if(((r=e.suspendedLanes)&a)!==a){tc(),e.pingedLanes|=e.suspendedLanes&r;break}e.timeoutHandle=ar(_c.bind(null,e,$l,Hl),t);break}_c(e,$l,Hl);break;case 4:if(lc(e,a),(4194240&a)===a)break;for(t=e.eventTimes,r=-1;0<a;){var s=31-it(a);i=1<<s,(s=t[s])>r&&(r=s),a&=~i}if(a=r,10<(a=(120>(a=Qe()-a)?120:480>a?480:1080>a?1080:1920>a?1920:3e3>a?3e3:4320>a?4320:1960*El(a/1960))-a)){e.timeoutHandle=ar(_c.bind(null,e,$l,Hl),a);break}_c(e,$l,Hl);break;default:throw Error(o(329))}}}return rc(e,Qe()),e.callbackNode===n?oc.bind(null,e):null}function ic(e,t){var n=zl;return e.current.memoizedState.isDehydrated&&(fc(e,t).flags|=256),2!==(e=bc(e,t))&&(t=$l,$l=n,null!==t&&sc(t)),e}function sc(e){null===$l?$l=e:$l.push.apply($l,e)}function lc(e,t){for(t&=~Bl,t&=~Dl,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-it(t),a=1<<n;e[n]=-1,t&=~a}}function cc(e){if(0!=(6&Al))throw Error(o(327));kc();var t=pt(e,0);if(0==(1&t))return rc(e,Qe()),null;var n=bc(e,t);if(0!==e.tag&&2===n){var a=gt(e);0!==a&&(t=a,n=ic(e,a))}if(1===n)throw n=Il,fc(e,0),lc(e,t),rc(e,Qe()),n;if(6===n)throw Error(o(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,_c(e,$l,Hl),rc(e,Qe()),null}function uc(e,t){var n=Al;Al|=1;try{return e(t)}finally{0===(Al=n)&&(Zl=Qe()+500,Br&&Ur())}}function dc(e){null!==Kl&&0===Kl.tag&&0==(6&Al)&&kc();var t=Al;Al|=1;var n=Tl.transition,a=vt;try{if(Tl.transition=null,vt=1,e)return e()}finally{vt=a,Tl.transition=n,0==(6&(Al=t))&&Ur()}}function pc(){Ml=Rl.current,Er(Rl)}function fc(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,rr(n)),null!==Pl)for(n=Pl.return;null!==n;){var a=n;switch(to(a),a.tag){case 1:null!=(a=a.type.childContextTypes)&&Mr();break;case 3:oi(),Er(Ar),Er(Tr),di();break;case 5:si(a);break;case 4:oi();break;case 13:case 19:Er(li);break;case 10:ko(a.type._context);break;case 22:case 23:pc()}n=n.return}if(Ll=e,Pl=e=Rc(e.current,null),Nl=Ml=t,Ol=0,Il=null,Bl=Dl=Fl=0,$l=zl=null,null!==Co){for(t=0;t<Co.length;t++)if(null!==(a=(n=Co[t]).interleaved)){n.interleaved=null;var r=a.next,o=n.pending;if(null!==o){var i=o.next;o.next=r,a.next=i}n.pending=a}Co=null}return e}function gc(e,t){for(;;){var n=Pl;try{if(_o(),pi.current=is,yi){for(var a=hi.memoizedState;null!==a;){var r=a.queue;null!==r&&(r.pending=null),a=a.next}yi=!1}if(gi=0,bi=mi=hi=null,vi=!1,xi=0,Cl.current=null,null===n||null===n.return){Ol=1,Il=t,Pl=null;break}e:{var i=e,s=n.return,l=n,c=t;if(t=Nl,l.flags|=32768,null!==c&&"object"==typeof c&&"function"==typeof c.then){var u=c,d=l,p=d.tag;if(0==(1&d.mode)&&(0===p||11===p||15===p)){var f=d.alternate;f?(d.updateQueue=f.updateQueue,d.memoizedState=f.memoizedState,d.lanes=f.lanes):(d.updateQueue=null,d.memoizedState=null)}var g=bs(s);if(null!==g){g.flags&=-257,ys(g,s,l,0,t),1&g.mode&&ms(i,u,t),c=u;var h=(t=g).updateQueue;if(null===h){var m=new Set;m.add(c),t.updateQueue=m}else h.add(c);break e}if(0==(1&t)){ms(i,u,t),mc();break e}c=Error(o(426))}else if(ro&&1&l.mode){var b=bs(s);if(null!==b){0==(65536&b.flags)&&(b.flags|=256),ys(b,s,l,0,t),ho(us(c,l));break e}}i=c=us(c,l),4!==Ol&&(Ol=2),null===zl?zl=[i]:zl.push(i),i=s;do{switch(i.tag){case 3:i.flags|=65536,t&=-t,i.lanes|=t,Fo(i,gs(0,c,t));break e;case 1:l=c;var y=i.type,v=i.stateNode;if(0==(128&i.flags)&&("function"==typeof y.getDerivedStateFromError||null!==v&&"function"==typeof v.componentDidCatch&&(null===ql||!ql.has(v)))){i.flags|=65536,t&=-t,i.lanes|=t,Fo(i,hs(i,l,t));break e}}i=i.return}while(null!==i)}wc(n)}catch(x){t=x,Pl===n&&null!==n&&(Pl=n=n.return);continue}break}}function hc(){var e=jl.current;return jl.current=is,null===e?is:e}function mc(){0!==Ol&&3!==Ol&&2!==Ol||(Ol=4),null===Ll||0==(268435455&Fl)&&0==(268435455&Dl)||lc(Ll,Nl)}function bc(e,t){var n=Al;Al|=2;var a=hc();for(Ll===e&&Nl===t||(Hl=null,fc(e,t));;)try{yc();break}catch(r){gc(e,r)}if(_o(),Al=n,jl.current=a,null!==Pl)throw Error(o(261));return Ll=null,Nl=0,Ol}function yc(){for(;null!==Pl;)xc(Pl)}function vc(){for(;null!==Pl&&!Ke();)xc(Pl)}function xc(e){var t=Sl(e.alternate,e,Ml);e.memoizedProps=e.pendingProps,null===t?wc(e):Pl=t,Cl.current=null}function wc(e){var t=e;do{var n=t.alternate;if(e=t.return,0==(32768&t.flags)){if(null!==(n=Gs(n,t,Ml)))return void(Pl=n)}else{if(null!==(n=Ks(n,t)))return n.flags&=32767,void(Pl=n);if(null===e)return Ol=6,void(Pl=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}if(null!==(t=t.sibling))return void(Pl=t);Pl=t=e}while(null!==t);0===Ol&&(Ol=5)}function _c(e,t,n){var a=vt,r=Tl.transition;try{Tl.transition=null,vt=1,function(e,t,n,a){do{kc()}while(null!==Kl);if(0!=(6&Al))throw Error(o(327));n=e.finishedWork;var r=e.finishedLanes;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(o(177));e.callbackNode=null,e.callbackPriority=0;var i=n.lanes|n.childLanes;if(function(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var a=e.eventTimes;for(e=e.expirationTimes;0<n;){var r=31-it(n),o=1<<r;t[r]=0,a[r]=-1,e[r]=-1,n&=~o}}(e,i),e===Ll&&(Pl=Ll=null,Nl=0),0==(2064&n.subtreeFlags)&&0==(2064&n.flags)||Gl||(Gl=!0,Lc(tt,(function(){return kc(),null}))),i=0!=(15990&n.flags),0!=(15990&n.subtreeFlags)||i){i=Tl.transition,Tl.transition=null;var s=vt;vt=1;var l=Al;Al|=4,Cl.current=null,function(e,t){if(er=Ht,fa(e=pa())){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var a=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(a&&0!==a.rangeCount){n=a.anchorNode;var r=a.anchorOffset,i=a.focusNode;a=a.focusOffset;try{n.nodeType,i.nodeType}catch(w){n=null;break e}var s=0,l=-1,c=-1,u=0,d=0,p=e,f=null;t:for(;;){for(var g;p!==n||0!==r&&3!==p.nodeType||(l=s+r),p!==i||0!==a&&3!==p.nodeType||(c=s+a),3===p.nodeType&&(s+=p.nodeValue.length),null!==(g=p.firstChild);)f=p,p=g;for(;;){if(p===e)break t;if(f===n&&++u===r&&(l=s),f===i&&++d===a&&(c=s),null!==(g=p.nextSibling))break;f=(p=f).parentNode}p=g}n=-1===l||-1===c?null:{start:l,end:c}}else n=null}n=n||{start:0,end:0}}else n=null;for(tr={focusedElem:e,selectionRange:n},Ht=!1,Js=t;null!==Js;)if(e=(t=Js).child,0!=(1028&t.subtreeFlags)&&null!==e)e.return=t,Js=e;else for(;null!==Js;){t=Js;try{var h=t.alternate;if(0!=(1024&t.flags))switch(t.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==h){var m=h.memoizedProps,b=h.memoizedState,y=t.stateNode,v=y.getSnapshotBeforeUpdate(t.elementType===t.type?m:bo(t.type,m),b);y.__reactInternalSnapshotBeforeUpdate=v}break;case 3:var x=t.stateNode.containerInfo;1===x.nodeType?x.textContent="":9===x.nodeType&&x.documentElement&&x.removeChild(x.documentElement);break;default:throw Error(o(163))}}catch(w){Ec(t,t.return,w)}if(null!==(e=t.sibling)){e.return=t.return,Js=e;break}Js=t.return}h=nl,nl=!1}(e,n),bl(n,e),ga(tr),Ht=!!er,tr=er=null,e.current=n,vl(n,e,r),Ye(),Al=l,vt=s,Tl.transition=i}else e.current=n;if(Gl&&(Gl=!1,Kl=e,Yl=r),i=e.pendingLanes,0===i&&(ql=null),function(e){if(ot&&"function"==typeof ot.onCommitFiberRoot)try{ot.onCommitFiberRoot(rt,e,void 0,128==(128&e.current.flags))}catch(t){}}(n.stateNode),rc(e,Qe()),null!==t)for(a=e.onRecoverableError,n=0;n<t.length;n++)r=t[n],a(r.value,{componentStack:r.stack,digest:r.digest});if(Vl)throw Vl=!1,e=Wl,Wl=null,e;0!=(1&Yl)&&0!==e.tag&&kc(),i=e.pendingLanes,0!=(1&i)?e===Xl?Ql++:(Ql=0,Xl=e):Ql=0,Ur()}(e,t,n,a)}finally{Tl.transition=r,vt=a}return null}function kc(){if(null!==Kl){var e=xt(Yl),t=Tl.transition,n=vt;try{if(Tl.transition=null,vt=16>e?16:e,null===Kl)var a=!1;else{if(e=Kl,Kl=null,Yl=0,0!=(6&Al))throw Error(o(331));var r=Al;for(Al|=4,Js=e.current;null!==Js;){var i=Js,s=i.child;if(0!=(16&Js.flags)){var l=i.deletions;if(null!==l){for(var c=0;c<l.length;c++){var u=l[c];for(Js=u;null!==Js;){var d=Js;switch(d.tag){case 0:case 11:case 15:al(8,d,i)}var p=d.child;if(null!==p)p.return=d,Js=p;else for(;null!==Js;){var f=(d=Js).sibling,g=d.return;if(il(d),d===u){Js=null;break}if(null!==f){f.return=g,Js=f;break}Js=g}}}var h=i.alternate;if(null!==h){var m=h.child;if(null!==m){h.child=null;do{var b=m.sibling;m.sibling=null,m=b}while(null!==m)}}Js=i}}if(0!=(2064&i.subtreeFlags)&&null!==s)s.return=i,Js=s;else e:for(;null!==Js;){if(0!=(2048&(i=Js).flags))switch(i.tag){case 0:case 11:case 15:al(9,i,i.return)}var y=i.sibling;if(null!==y){y.return=i.return,Js=y;break e}Js=i.return}}var v=e.current;for(Js=v;null!==Js;){var x=(s=Js).child;if(0!=(2064&s.subtreeFlags)&&null!==x)x.return=s,Js=x;else e:for(s=v;null!==Js;){if(0!=(2048&(l=Js).flags))try{switch(l.tag){case 0:case 11:case 15:rl(9,l)}}catch(_){Ec(l,l.return,_)}if(l===s){Js=null;break e}var w=l.sibling;if(null!==w){w.return=l.return,Js=w;break e}Js=l.return}}if(Al=r,Ur(),ot&&"function"==typeof ot.onPostCommitFiberRoot)try{ot.onPostCommitFiberRoot(rt,e)}catch(_){}a=!0}return a}finally{vt=n,Tl.transition=t}}return!1}function Sc(e,t,n){e=Oo(e,t=gs(0,t=us(n,t),1),1),t=tc(),null!==e&&(bt(e,1,t),rc(e,t))}function Ec(e,t,n){if(3===e.tag)Sc(e,e,n);else for(;null!==t;){if(3===t.tag){Sc(t,e,n);break}if(1===t.tag){var a=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof a.componentDidCatch&&(null===ql||!ql.has(a))){t=Oo(t,e=hs(t,e=us(n,e),1),1),e=tc(),null!==t&&(bt(t,1,e),rc(t,e));break}}t=t.return}}function jc(e,t,n){var a=e.pingCache;null!==a&&a.delete(t),t=tc(),e.pingedLanes|=e.suspendedLanes&n,Ll===e&&(Nl&n)===n&&(4===Ol||3===Ol&&(130023424&Nl)===Nl&&500>Qe()-Ul?fc(e,0):Bl|=n),rc(e,t)}function Cc(e,t){0===t&&(0==(1&e.mode)?t=1:(t=ut,0==(130023424&(ut<<=1))&&(ut=4194304)));var n=tc();null!==(e=Lo(e,t))&&(bt(e,t,n),rc(e,n))}function Tc(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),Cc(e,n)}function Ac(e,t){var n=0;switch(e.tag){case 13:var a=e.stateNode,r=e.memoizedState;null!==r&&(n=r.retryLane);break;case 19:a=e.stateNode;break;default:throw Error(o(314))}null!==a&&a.delete(t),Cc(e,n)}function Lc(e,t){return qe(e,t)}function Pc(e,t,n,a){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=a,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Nc(e,t,n,a){return new Pc(e,t,n,a)}function Mc(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Rc(e,t){var n=e.alternate;return null===n?((n=Nc(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Oc(e,t,n,a,r,i){var s=2;if(a=e,"function"==typeof e)Mc(e)&&(s=1);else if("string"==typeof e)s=5;else e:switch(e){case k:return Ic(n.children,r,i,t);case S:s=8,r|=8;break;case E:return(e=Nc(12,n,t,2|r)).elementType=E,e.lanes=i,e;case A:return(e=Nc(13,n,t,r)).elementType=A,e.lanes=i,e;case L:return(e=Nc(19,n,t,r)).elementType=L,e.lanes=i,e;case M:return Fc(n,r,i,t);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case j:s=10;break e;case C:s=9;break e;case T:s=11;break e;case P:s=14;break e;case N:s=16,a=null;break e}throw Error(o(130,null==e?e:typeof e,""))}return(t=Nc(s,n,t,r)).elementType=e,t.type=a,t.lanes=i,t}function Ic(e,t,n,a){return(e=Nc(7,e,a,t)).lanes=n,e}function Fc(e,t,n,a){return(e=Nc(22,e,a,t)).elementType=M,e.lanes=n,e.stateNode={isHidden:!1},e}function Dc(e,t,n){return(e=Nc(6,e,null,t)).lanes=n,e}function Bc(e,t,n){return(t=Nc(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function zc(e,t,n,a,r){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=mt(0),this.expirationTimes=mt(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=mt(0),this.identifierPrefix=a,this.onRecoverableError=r,this.mutableSourceEagerHydrationData=null}function $c(e,t,n,a,r,o,i,s,l){return e=new zc(e,t,n,s,l),1===t?(t=1,!0===o&&(t|=8)):t=0,o=Nc(3,null,null,t),e.current=o,o.stateNode=e,o.memoizedState={element:a,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},No(o),e}function Uc(e){if(!e)return Cr;e:{if(Ue(e=e._reactInternals)!==e||1!==e.tag)throw Error(o(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(Nr(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(null!==t);throw Error(o(171))}if(1===e.tag){var n=e.type;if(Nr(n))return Or(e,n,t)}return t}function Zc(e,t,n,a,r,o,i,s,l){return(e=$c(n,a,!0,e,0,o,0,s,l)).context=Uc(null),n=e.current,(o=Ro(a=tc(),r=nc(n))).callback=null!=t?t:null,Oo(n,o,r),e.current.lanes=r,bt(e,r,a),rc(e,a),e}function Hc(e,t,n,a){var r=t.current,o=tc(),i=nc(r);return n=Uc(n),null===t.context?t.context=n:t.pendingContext=n,(t=Ro(o,i)).payload={element:e},null!==(a=void 0===a?null:a)&&(t.callback=a),null!==(e=Oo(r,t,i))&&(ac(e,r,i,o),Io(e,r,i)),i}function Vc(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Wc(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function qc(e,t){Wc(e,t),(e=e.alternate)&&Wc(e,t)}Sl=function(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps||Ar.current)xs=!0;else{if(0==(e.lanes&n)&&0==(128&t.flags))return xs=!1,function(e,t,n){switch(t.tag){case 3:Ls(t),go();break;case 5:ii(t);break;case 1:Nr(t.type)&&Ir(t);break;case 4:ri(t,t.stateNode.containerInfo);break;case 10:var a=t.type._context,r=t.memoizedProps.value;jr(yo,a._currentValue),a._currentValue=r;break;case 13:if(null!==(a=t.memoizedState))return null!==a.dehydrated?(jr(li,1&li.current),t.flags|=128,null):0!=(n&t.child.childLanes)?Ds(e,t,n):(jr(li,1&li.current),null!==(e=Vs(e,t,n))?e.sibling:null);jr(li,1&li.current);break;case 19:if(a=0!=(n&t.childLanes),0!=(128&e.flags)){if(a)return Zs(e,t,n);t.flags|=128}if(null!==(r=t.memoizedState)&&(r.rendering=null,r.tail=null,r.lastEffect=null),jr(li,li.current),a)break;return null;case 22:case 23:return t.lanes=0,Es(e,t,n)}return Vs(e,t,n)}(e,t,n);xs=0!=(131072&e.flags)}else xs=!1,ro&&0!=(1048576&t.flags)&&Jr(t,Wr,t.index);switch(t.lanes=0,t.tag){case 2:var a=t.type;Hs(e,t),e=t.pendingProps;var r=Pr(t,Tr.current);Eo(t,n),r=Si(null,t,a,e,r,n);var i=Ei();return t.flags|=1,"object"==typeof r&&null!==r&&"function"==typeof r.render&&void 0===r.$$typeof?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Nr(a)?(i=!0,Ir(t)):i=!1,t.memoizedState=null!==r.state&&void 0!==r.state?r.state:null,No(t),r.updater=Uo,t.stateNode=r,r._reactInternals=t,Wo(t,a,e,n),t=As(null,t,a,!0,i,n)):(t.tag=0,ro&&i&&eo(t),ws(null,t,r,n),t=t.child),t;case 16:a=t.elementType;e:{switch(Hs(e,t),e=t.pendingProps,a=(r=a._init)(a._payload),t.type=a,r=t.tag=function(e){if("function"==typeof e)return Mc(e)?1:0;if(null!=e){if((e=e.$$typeof)===T)return 11;if(e===P)return 14}return 2}(a),e=bo(a,e),r){case 0:t=Cs(null,t,a,e,n);break e;case 1:t=Ts(null,t,a,e,n);break e;case 11:t=_s(null,t,a,e,n);break e;case 14:t=ks(null,t,a,bo(a.type,e),n);break e}throw Error(o(306,a,""))}return t;case 0:return a=t.type,r=t.pendingProps,Cs(e,t,a,r=t.elementType===a?r:bo(a,r),n);case 1:return a=t.type,r=t.pendingProps,Ts(e,t,a,r=t.elementType===a?r:bo(a,r),n);case 3:e:{if(Ls(t),null===e)throw Error(o(387));a=t.pendingProps,r=(i=t.memoizedState).element,Mo(e,t),Do(t,a,null,n);var s=t.memoizedState;if(a=s.element,i.isDehydrated){if(i={element:a,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=i,t.memoizedState=i,256&t.flags){t=Ps(e,t,a,n,r=us(Error(o(423)),t));break e}if(a!==r){t=Ps(e,t,a,n,r=us(Error(o(424)),t));break e}for(ao=cr(t.stateNode.containerInfo.firstChild),no=t,ro=!0,oo=null,n=Xo(t,null,a,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(go(),a===r){t=Vs(e,t,n);break e}ws(e,t,a,n)}t=t.child}return t;case 5:return ii(t),null===e&&co(t),a=t.type,r=t.pendingProps,i=null!==e?e.memoizedProps:null,s=r.children,nr(a,r)?s=null:null!==i&&nr(a,i)&&(t.flags|=32),js(e,t),ws(e,t,s,n),t.child;case 6:return null===e&&co(t),null;case 13:return Ds(e,t,n);case 4:return ri(t,t.stateNode.containerInfo),a=t.pendingProps,null===e?t.child=Qo(t,null,a,n):ws(e,t,a,n),t.child;case 11:return a=t.type,r=t.pendingProps,_s(e,t,a,r=t.elementType===a?r:bo(a,r),n);case 7:return ws(e,t,t.pendingProps,n),t.child;case 8:case 12:return ws(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(a=t.type._context,r=t.pendingProps,i=t.memoizedProps,s=r.value,jr(yo,a._currentValue),a._currentValue=s,null!==i)if(sa(i.value,s)){if(i.children===r.children&&!Ar.current){t=Vs(e,t,n);break e}}else for(null!==(i=t.child)&&(i.return=t);null!==i;){var l=i.dependencies;if(null!==l){s=i.child;for(var c=l.firstContext;null!==c;){if(c.context===a){if(1===i.tag){(c=Ro(-1,n&-n)).tag=2;var u=i.updateQueue;if(null!==u){var d=(u=u.shared).pending;null===d?c.next=c:(c.next=d.next,d.next=c),u.pending=c}}i.lanes|=n,null!==(c=i.alternate)&&(c.lanes|=n),So(i.return,n,t),l.lanes|=n;break}c=c.next}}else if(10===i.tag)s=i.type===t.type?null:i.child;else if(18===i.tag){if(null===(s=i.return))throw Error(o(341));s.lanes|=n,null!==(l=s.alternate)&&(l.lanes|=n),So(s,n,t),s=i.sibling}else s=i.child;if(null!==s)s.return=i;else for(s=i;null!==s;){if(s===t){s=null;break}if(null!==(i=s.sibling)){i.return=s.return,s=i;break}s=s.return}i=s}ws(e,t,r.children,n),t=t.child}return t;case 9:return r=t.type,a=t.pendingProps.children,Eo(t,n),a=a(r=jo(r)),t.flags|=1,ws(e,t,a,n),t.child;case 14:return r=bo(a=t.type,t.pendingProps),ks(e,t,a,r=bo(a.type,r),n);case 15:return Ss(e,t,t.type,t.pendingProps,n);case 17:return a=t.type,r=t.pendingProps,r=t.elementType===a?r:bo(a,r),Hs(e,t),t.tag=1,Nr(a)?(e=!0,Ir(t)):e=!1,Eo(t,n),Ho(t,a,r),Wo(t,a,r,n),As(null,t,a,!0,e,n);case 19:return Zs(e,t,n);case 22:return Es(e,t,n)}throw Error(o(156,t.tag))};var Gc="function"==typeof reportError?reportError:function(e){console.error(e)};function Kc(e){this._internalRoot=e}function Yc(e){this._internalRoot=e}function Qc(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Xc(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Jc(){}function eu(e,t,n,a,r){var o=n._reactRootContainer;if(o){var i=o;if("function"==typeof r){var s=r;r=function(){var e=Vc(i);s.call(e)}}Hc(t,i,e,r)}else i=function(e,t,n,a,r){if(r){if("function"==typeof a){var o=a;a=function(){var e=Vc(i);o.call(e)}}var i=Zc(t,a,e,0,null,!1,0,"",Jc);return e._reactRootContainer=i,e[gr]=i.current,Ua(8===e.nodeType?e.parentNode:e),dc(),i}for(;r=e.lastChild;)e.removeChild(r);if("function"==typeof a){var s=a;a=function(){var e=Vc(l);s.call(e)}}var l=$c(e,0,!1,null,0,!1,0,"",Jc);return e._reactRootContainer=l,e[gr]=l.current,Ua(8===e.nodeType?e.parentNode:e),dc((function(){Hc(t,l,n,a)})),l}(n,t,e,r,a);return Vc(i)}Yc.prototype.render=Kc.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(o(409));Hc(e,t,null,null)},Yc.prototype.unmount=Kc.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;dc((function(){Hc(null,e,null,null)})),t[gr]=null}},Yc.prototype.unstable_scheduleHydration=function(e){if(e){var t=St();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Mt.length&&0!==t&&t<Mt[n].priority;n++);Mt.splice(n,0,e),0===n&&Ft(e)}},wt=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=dt(t.pendingLanes);0!==n&&(yt(t,1|n),rc(t,Qe()),0==(6&Al)&&(Zl=Qe()+500,Ur()))}break;case 13:dc((function(){var t=Lo(e,1);if(null!==t){var n=tc();ac(t,e,1,n)}})),qc(e,1)}},_t=function(e){if(13===e.tag){var t=Lo(e,134217728);if(null!==t)ac(t,e,134217728,tc());qc(e,134217728)}},kt=function(e){if(13===e.tag){var t=nc(e),n=Lo(e,t);if(null!==n)ac(n,e,t,tc());qc(e,t)}},St=function(){return vt},Et=function(e,t){var n=vt;try{return vt=e,t()}finally{vt=n}},_e=function(e,t,n){switch(t){case"input":if(X(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var a=n[t];if(a!==e&&a.form===e.form){var r=wr(a);if(!r)throw Error(o(90));q(a),X(a,r)}}}break;case"textarea":oe(e,n);break;case"select":null!=(t=n.value)&&ne(e,!!n.multiple,t,!1)}},Te=uc,Ae=dc;var tu={usingClientEntryPoint:!1,Events:[vr,xr,wr,je,Ce,uc]},nu={findFiberByHostInstance:yr,bundleType:0,version:"18.2.0",rendererPackageName:"react-dom"},au={bundleType:nu.bundleType,version:nu.version,rendererPackageName:nu.rendererPackageName,rendererConfig:nu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:x.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Ve(e))?null:e.stateNode},findFiberByHostInstance:nu.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.2.0-next-9e3b772b8-20220608"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var ru=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!ru.isDisabled&&ru.supportsFiber)try{rt=ru.inject(au),ot=ru}catch(ue){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=tu,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Qc(t))throw Error(o(200));return function(e,t,n){var a=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:_,key:null==a?null:""+a,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.createRoot=function(e,t){if(!Qc(e))throw Error(o(299));var n=!1,a="",r=Gc;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(a=t.identifierPrefix),void 0!==t.onRecoverableError&&(r=t.onRecoverableError)),t=$c(e,1,!1,null,0,n,0,a,r),e[gr]=t.current,Ua(8===e.nodeType?e.parentNode:e),new Kc(t)},t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(o(188));throw e=Object.keys(e).join(","),Error(o(268,e))}return e=null===(e=Ve(t))?null:e.stateNode},t.flushSync=function(e){return dc(e)},t.hydrate=function(e,t,n){if(!Xc(t))throw Error(o(200));return eu(null,e,t,!0,n)},t.hydrateRoot=function(e,t,n){if(!Qc(e))throw Error(o(405));var a=null!=n&&n.hydratedSources||null,r=!1,i="",s=Gc;if(null!=n&&(!0===n.unstable_strictMode&&(r=!0),void 0!==n.identifierPrefix&&(i=n.identifierPrefix),void 0!==n.onRecoverableError&&(s=n.onRecoverableError)),t=Zc(t,null,e,1,null!=n?n:null,r,0,i,s),e[gr]=t.current,Ua(e),a)for(e=0;e<a.length;e++)r=(r=(n=a[e])._getVersion)(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,r]:t.mutableSourceEagerHydrationData.push(n,r);return new Yc(t)},t.render=function(e,t,n){if(!Xc(t))throw Error(o(200));return eu(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Xc(e))throw Error(o(40));return!!e._reactRootContainer&&(dc((function(){eu(null,null,e,!1,(function(){e._reactRootContainer=null,e[gr]=null}))})),!0)},t.unstable_batchedUpdates=uc,t.unstable_renderSubtreeIntoContainer=function(e,t,n,a){if(!Xc(n))throw Error(o(200));if(null==e||void 0===e._reactInternals)throw Error(o(38));return eu(e,t,n,!1,a)},t.version="18.2.0-next-9e3b772b8-20220608"},20745:(e,t,n)=>{"use strict";var a=n(73935);t.createRoot=a.createRoot,t.hydrateRoot=a.hydrateRoot},73935:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(64448)},69590:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,a="function"==typeof Set,r="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function o(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var s,l,c,u;if(Array.isArray(e)){if((s=e.length)!=i.length)return!1;for(l=s;0!=l--;)if(!o(e[l],i[l]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!i.has(l.value[0]))return!1;for(u=e.entries();!(l=u.next()).done;)if(!o(l.value[1],i.get(l.value[0])))return!1;return!0}if(a&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(l=u.next()).done;)if(!i.has(l.value[0]))return!1;return!0}if(r&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((s=e.length)!=i.length)return!1;for(l=s;0!=l--;)if(e[l]!==i[l])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString)return e.toString()===i.toString();if((s=(c=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(l=s;0!=l--;)if(!Object.prototype.hasOwnProperty.call(i,c[l]))return!1;if(t&&e instanceof Element)return!1;for(l=s;0!=l--;)if(("_owner"!==c[l]&&"__v"!==c[l]&&"__o"!==c[l]||!e.$$typeof)&&!o(e[c[l]],i[c[l]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return o(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},70405:(e,t,n)=>{"use strict";n.d(t,{B6:()=>V,ql:()=>J});var a=n(67294),r=n(45697),o=n.n(r),i=n(69590),s=n.n(i),l=n(41143),c=n.n(l),u=n(96774),d=n.n(u);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},p.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,g(e,t)}function g(e,t){return g=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},g(e,t)}function h(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)t.indexOf(n=o[a])>=0||(r[n]=e[n]);return r}var m={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},y={type:["application/ld+json"]},v={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},x=Object.keys(m).map((function(e){return m[e]})),w={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},_=Object.keys(w).reduce((function(e,t){return e[w[t]]=t,e}),{}),k=function(e,t){for(var n=e.length-1;n>=0;n-=1){var a=e[n];if(Object.prototype.hasOwnProperty.call(a,t))return a[t]}return null},S=function(e){var t=k(e,m.TITLE),n=k(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var a=k(e,"defaultTitle");return t||a||void 0},E=function(e){return k(e,"onChangeClientState")||function(){}},j=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},C=function(e,t){return t.filter((function(e){return void 0!==e[m.BASE]})).map((function(e){return e[m.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var a=Object.keys(n),r=0;r<a.length;r+=1){var o=a[r].toLowerCase();if(-1!==e.indexOf(o)&&n[o])return t.concat(n)}return t}),[])},T=function(e,t,n){var a={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var r={};n.filter((function(e){for(var n,o=Object.keys(e),i=0;i<o.length;i+=1){var s=o[i],l=s.toLowerCase();-1===t.indexOf(l)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===l&&"stylesheet"===e[l].toLowerCase()||(n=l),-1===t.indexOf(s)||"innerHTML"!==s&&"cssText"!==s&&"itemprop"!==s||(n=s)}if(!n||!e[n])return!1;var c=e[n].toLowerCase();return a[n]||(a[n]={}),r[n]||(r[n]={}),!a[n][c]&&(r[n][c]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var o=Object.keys(r),i=0;i<o.length;i+=1){var s=o[i],l=p({},a[s],r[s]);a[s]=l}return e}),[]).reverse()},A=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},L=function(e){return Array.isArray(e)?e.join(""):e},P=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),a=0;a<n.length;a+=1)if(t[n[a]]&&t[n[a]].includes(e[n[a]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},N=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},M=[m.NOSCRIPT,m.SCRIPT,m.STYLE],R=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},O=function(e){return Object.keys(e).reduce((function(t,n){var a=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+a:a}),"")},I=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[w[n]||n]=e[n],t}),t)},F=function(e,t){return t.map((function(t,n){var r,o=((r={key:n})["data-rh"]=!0,r);return Object.keys(t).forEach((function(e){var n=w[e]||e;"innerHTML"===n||"cssText"===n?o.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:o[n]=t[e]})),a.createElement(e,o)}))},D=function(e,t,n){switch(e){case m.TITLE:return{toComponent:function(){return n=t.titleAttributes,(r={key:e=t.title})["data-rh"]=!0,o=I(n,r),[a.createElement(m.TITLE,o,e)];var e,n,r,o},toString:function(){return function(e,t,n,a){var r=O(n),o=L(t);return r?"<"+e+' data-rh="true" '+r+">"+R(o,a)+"</"+e+">":"<"+e+' data-rh="true">'+R(o,a)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return I(t)},toString:function(){return O(t)}};default:return{toComponent:function(){return F(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,a){var r=Object.keys(a).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var r=void 0===a[t]?t:t+'="'+R(a[t],n)+'"';return e?e+" "+r:r}),""),o=a.innerHTML||a.cssText||"",i=-1===M.indexOf(e);return t+"<"+e+' data-rh="true" '+r+(i?"/>":">"+o+"</"+e+">")}),"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,a=e.encode,r=e.htmlAttributes,o=e.noscriptTags,i=e.styleTags,s=e.title,l=void 0===s?"":s,c=e.titleAttributes,u=e.linkTags,d=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var g=function(e){var t=e.linkTags,n=e.scriptTags,a=e.encode,r=P(e.metaTags,v),o=P(t,b),i=P(n,y);return{priorityMethods:{toComponent:function(){return[].concat(F(m.META,r.priority),F(m.LINK,o.priority),F(m.SCRIPT,i.priority))},toString:function(){return D(m.META,r.priority,a)+" "+D(m.LINK,o.priority,a)+" "+D(m.SCRIPT,i.priority,a)}},metaTags:r.default,linkTags:o.default,scriptTags:i.default}}(e);f=g.priorityMethods,u=g.linkTags,d=g.metaTags,p=g.scriptTags}return{priority:f,base:D(m.BASE,t,a),bodyAttributes:D("bodyAttributes",n,a),htmlAttributes:D("htmlAttributes",r,a),link:D(m.LINK,u,a),meta:D(m.META,d,a),noscript:D(m.NOSCRIPT,o,a),script:D(m.SCRIPT,p,a),style:D(m.STYLE,i,a),title:D(m.TITLE,{title:l,titleAttributes:c},a)}},z=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=a.createContext({}),Z=o().shape({setHelmet:o().func,helmetInstances:o().shape({get:o().func,add:o().func,remove:o().func})}),H="undefined"!=typeof document,V=function(e){function t(n){var a;return(a=e.call(this,n)||this).helmetData=new $(a.props.context,t.canUseDOM),a}return f(t,e),t.prototype.render=function(){return a.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(a.Component);V.canUseDOM=H,V.propTypes={context:o().shape({helmet:o().shape()}),children:o().node.isRequired},V.defaultProps={context:{}},V.displayName="HelmetProvider";var W=function(e,t){var n,a=document.head||document.querySelector(m.HEAD),r=a.querySelectorAll(e+"[data-rh]"),o=[].slice.call(r),i=[];return t&&t.length&&t.forEach((function(t){var a=document.createElement(e);for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&("innerHTML"===r?a.innerHTML=t.innerHTML:"cssText"===r?a.styleSheet?a.styleSheet.cssText=t.cssText:a.appendChild(document.createTextNode(t.cssText)):a.setAttribute(r,void 0===t[r]?"":t[r]));a.setAttribute("data-rh","true"),o.some((function(e,t){return n=t,a.isEqualNode(e)}))?o.splice(n,1):i.push(a)})),o.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return a.appendChild(e)})),{oldTags:o,newTags:i}},q=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var a=n.getAttribute("data-rh"),r=a?a.split(","):[],o=[].concat(r),i=Object.keys(t),s=0;s<i.length;s+=1){var l=i[s],c=t[l]||"";n.getAttribute(l)!==c&&n.setAttribute(l,c),-1===r.indexOf(l)&&r.push(l);var u=o.indexOf(l);-1!==u&&o.splice(u,1)}for(var d=o.length-1;d>=0;d-=1)n.removeAttribute(o[d]);r.length===o.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},G=function(e,t){var n=e.baseTag,a=e.htmlAttributes,r=e.linkTags,o=e.metaTags,i=e.noscriptTags,s=e.onChangeClientState,l=e.scriptTags,c=e.styleTags,u=e.title,d=e.titleAttributes;q(m.BODY,e.bodyAttributes),q(m.HTML,a),function(e,t){void 0!==e&&document.title!==e&&(document.title=L(e)),q(m.TITLE,t)}(u,d);var p={baseTag:W(m.BASE,n),linkTags:W(m.LINK,r),metaTags:W(m.META,o),noscriptTags:W(m.NOSCRIPT,i),scriptTags:W(m.SCRIPT,l),styleTags:W(m.STYLE,c)},f={},g={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,a=t.oldTags;n.length&&(f[e]=n),a.length&&(g[e]=p[e].oldTags)})),t&&t(),s(e,f,g)},K=null,Y=function(e){function t(){for(var t,n=arguments.length,a=new Array(n),r=0;r<n;r++)a[r]=arguments[r];return(t=e.call.apply(e,[this].concat(a))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!d()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,a=n.setHelmet,r=null,o=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:C(["href"],e),bodyAttributes:j("bodyAttributes",e),defer:k(e,"defer"),encode:k(e,"encodeSpecialCharacters"),htmlAttributes:j("htmlAttributes",e),linkTags:T(m.LINK,["rel","href"],e),metaTags:T(m.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:T(m.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:T(m.SCRIPT,["src","innerHTML"],e),styleTags:T(m.STYLE,["cssText"],e),title:S(e),titleAttributes:j("titleAttributes",e),prioritizeSeoTags:A(e,"prioritizeSeoTags")});V.canUseDOM?(t=o,K&&cancelAnimationFrame(K),t.defer?K=requestAnimationFrame((function(){G(t,(function(){K=null}))})):(G(t),K=null)):B&&(r=B(o)),a(r)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(a.Component);Y.propTypes={context:Z.isRequired},Y.displayName="HelmetDispatcher";var Q=["children"],X=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!s()(N(this.props,"helmetData"),N(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case m.SCRIPT:case m.NOSCRIPT:return{innerHTML:t};case m.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,a=e.arrayTypeChildren;return p({},a,((t={})[n.type]=[].concat(a[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,a=e.child,r=e.newProps,o=e.newChildProps,i=e.nestedChildren;switch(a.type){case m.TITLE:return p({},r,((t={})[a.type]=i,t.titleAttributes=p({},o),t));case m.BODY:return p({},r,{bodyAttributes:p({},o)});case m.HTML:return p({},r,{htmlAttributes:p({},o)});default:return p({},r,((n={})[a.type]=p({},o),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var a;n=p({},n,((a={})[t]=e[t],a))})),n},n.warnOnInvalidChildren=function(e,t){return c()(x.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+x.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),c()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,r={};return a.Children.forEach(e,(function(e){if(e&&e.props){var a=e.props,o=a.children,i=h(a,Q),s=Object.keys(i).reduce((function(e,t){return e[_[t]||t]=i[t],e}),{}),l=e.type;switch("symbol"==typeof l?l=l.toString():n.warnOnInvalidChildren(e,o),l){case m.FRAGMENT:t=n.mapChildrenToProps(o,t);break;case m.LINK:case m.META:case m.NOSCRIPT:case m.SCRIPT:case m.STYLE:r=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:r,newChildProps:s,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:s,nestedChildren:o})}}})),this.mapArrayTypeChildrenToProps(r,t)},n.render=function(){var e=this.props,t=e.children,n=h(e,X),r=p({},n),o=n.helmetData;return t&&(r=this.mapChildrenToProps(t,r)),!o||o instanceof $||(o=new $(o.context,o.instances)),o?a.createElement(Y,p({},r,{context:o.value,helmetData:void 0})):a.createElement(U.Consumer,null,(function(e){return a.createElement(Y,p({},r,{context:e}))}))},t}(a.Component);J.propTypes={base:o().object,bodyAttributes:o().object,children:o().oneOfType([o().arrayOf(o().node),o().node]),defaultTitle:o().string,defer:o().bool,encodeSpecialCharacters:o().bool,htmlAttributes:o().object,link:o().arrayOf(o().object),meta:o().arrayOf(o().object),noscript:o().arrayOf(o().object),onChangeClientState:o().func,script:o().arrayOf(o().object),style:o().arrayOf(o().object),title:o().string,titleAttributes:o().object,titleTemplate:o().string,prioritizeSeoTags:o().bool,helmetData:o().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},69921:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,a=n?Symbol.for("react.element"):60103,r=n?Symbol.for("react.portal"):60106,o=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,s=n?Symbol.for("react.profiler"):60114,l=n?Symbol.for("react.provider"):60109,c=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,d=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,g=n?Symbol.for("react.suspense_list"):60120,h=n?Symbol.for("react.memo"):60115,m=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,y=n?Symbol.for("react.fundamental"):60117,v=n?Symbol.for("react.responder"):60118,x=n?Symbol.for("react.scope"):60119;function w(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case a:switch(e=e.type){case u:case d:case o:case s:case i:case f:return e;default:switch(e=e&&e.$$typeof){case c:case p:case m:case h:case l:return e;default:return t}}case r:return t}}}function _(e){return w(e)===d}t.AsyncMode=u,t.ConcurrentMode=d,t.ContextConsumer=c,t.ContextProvider=l,t.Element=a,t.ForwardRef=p,t.Fragment=o,t.Lazy=m,t.Memo=h,t.Portal=r,t.Profiler=s,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return _(e)||w(e)===u},t.isConcurrentMode=_,t.isContextConsumer=function(e){return w(e)===c},t.isContextProvider=function(e){return w(e)===l},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===a},t.isForwardRef=function(e){return w(e)===p},t.isFragment=function(e){return w(e)===o},t.isLazy=function(e){return w(e)===m},t.isMemo=function(e){return w(e)===h},t.isPortal=function(e){return w(e)===r},t.isProfiler=function(e){return w(e)===s},t.isStrictMode=function(e){return w(e)===i},t.isSuspense=function(e){return w(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===o||e===d||e===s||e===i||e===f||e===g||"object"==typeof e&&null!==e&&(e.$$typeof===m||e.$$typeof===h||e.$$typeof===l||e.$$typeof===c||e.$$typeof===p||e.$$typeof===y||e.$$typeof===v||e.$$typeof===x||e.$$typeof===b)},t.typeOf=w},59864:(e,t,n)=>{"use strict";e.exports=n(69921)},68356:(e,t,n)=>{"use strict";function a(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function r(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},i.apply(this,arguments)}var s=n(67294),l=n(45697),c=[],u=[];function d(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(a){var r=d(e[a]);r.loading?t.loading=!0:(t.loaded[a]=r.loaded,t.error=r.error),n.push(r.promise),r.promise.then((function(e){t.loaded[a]=e})).catch((function(e){t.error=e}))}))}catch(a){t.error=a}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return s.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function g(e,t){var d,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var g=i({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),h=null;function m(){return h||(h=e(g.loader)),h.promise}return c.push(m),"function"==typeof g.webpack&&u.push((function(){if((0,g.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return m()})),p=d=function(t){function n(n){var a;return o(r(r(a=t.call(this,n)||this)),"retry",(function(){a.setState({error:null,loading:!0,timedOut:!1}),h=e(g.loader),a._loadModule()})),m(),a.state={error:h.error,pastDelay:!1,timedOut:!1,loading:h.loading,loaded:h.loaded},a}a(n,t),n.preload=function(){return m()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context.loadable&&Array.isArray(g.modules)&&g.modules.forEach((function(t){e.context.loadable.report(t)})),h.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof g.delay&&(0===g.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),g.delay)),"number"==typeof g.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),g.timeout));var n=function(){t({error:h.error,loaded:h.loaded,loading:h.loading}),e._clearTimeouts()};h.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?s.createElement(g.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?g.render(this.state.loaded,this.props):null},n}(s.Component),o(d,"contextTypes",{loadable:l.shape({report:l.func.isRequired})}),p}function h(e){return g(d,e)}h.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return g(p,e)};var m=function(e){function t(){return e.apply(this,arguments)||this}a(t,e);var n=t.prototype;return n.getChildContext=function(){return{loadable:{report:this.props.report}}},n.render=function(){return s.Children.only(this.props.children)},t}(s.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}o(m,"propTypes",{report:l.func.isRequired}),o(m,"childContextTypes",{loadable:l.shape({report:l.func.isRequired}).isRequired}),h.Capture=m,h.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},h.preloadReady=function(){return new Promise((function(e,t){b(u).then(e,e)}))},e.exports=h},18790:(e,t,n)=>{"use strict";n.d(t,{H:()=>s,f:()=>i});var a=n(16550),r=n(83117),o=n(67294);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var r=e.path?(0,a.LX)(t,e):n.length?n[n.length-1].match:a.F0.computeRootMatch(t);return r&&(n.push({route:e,match:r}),e.routes&&i(e.routes,t,n)),r})),n}function s(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?o.createElement(a.rs,n,e.map((function(e,n){return o.createElement(a.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,r.Z)({},n,{},t,{route:e})):o.createElement(e.component,(0,r.Z)({},n,t,{route:e}))}})}))):null}},73727:(e,t,n)=>{"use strict";n.d(t,{OL:()=>v,VK:()=>u,rU:()=>m});var a=n(16550),r=n(90144),o=n(67294),i=n(42358),s=n(83117),l=n(80102),c=n(38776),u=function(e){function t(){for(var t,n=arguments.length,a=new Array(n),r=0;r<n;r++)a[r]=arguments[r];return(t=e.call.apply(e,[this].concat(a))||this).history=(0,i.lX)(t.props),t}return(0,r.Z)(t,e),t.prototype.render=function(){return o.createElement(a.F0,{history:this.history,children:this.props.children})},t}(o.Component);o.Component;var d=function(e,t){return"function"==typeof e?e(t):e},p=function(e,t){return"string"==typeof e?(0,i.ob)(e,null,null,t):e},f=function(e){return e},g=o.forwardRef;void 0===g&&(g=f);var h=g((function(e,t){var n=e.innerRef,a=e.navigate,r=e.onClick,i=(0,l.Z)(e,["innerRef","navigate","onClick"]),c=i.target,u=(0,s.Z)({},i,{onClick:function(e){try{r&&r(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||c&&"_self"!==c||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),a())}});return u.ref=f!==g&&t||n,o.createElement("a",u)}));var m=g((function(e,t){var n=e.component,r=void 0===n?h:n,u=e.replace,m=e.to,b=e.innerRef,y=(0,l.Z)(e,["component","replace","to","innerRef"]);return o.createElement(a.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=e.history,a=p(d(m,e.location),e.location),l=a?n.createHref(a):"",h=(0,s.Z)({},y,{href:l,navigate:function(){var t=d(m,e.location),a=(0,i.Ep)(e.location)===(0,i.Ep)(p(t));(u||a?n.replace:n.push)(t)}});return f!==g?h.ref=t||b:h.innerRef=b,o.createElement(r,h)}))})),b=function(e){return e},y=o.forwardRef;void 0===y&&(y=b);var v=y((function(e,t){var n=e["aria-current"],r=void 0===n?"page":n,i=e.activeClassName,u=void 0===i?"active":i,f=e.activeStyle,g=e.className,h=e.exact,v=e.isActive,x=e.location,w=e.sensitive,_=e.strict,k=e.style,S=e.to,E=e.innerRef,j=(0,l.Z)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return o.createElement(a.s6.Consumer,null,(function(e){e||(0,c.Z)(!1);var n=x||e.location,i=p(d(S,n),n),l=i.pathname,C=l&&l.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),T=C?(0,a.LX)(n.pathname,{path:C,exact:h,sensitive:w,strict:_}):null,A=!!(v?v(T,n):T),L="function"==typeof g?g(A):g,P="function"==typeof k?k(A):k;A&&(L=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(L,u),P=(0,s.Z)({},P,f));var N=(0,s.Z)({"aria-current":A&&r||null,className:L,style:P,to:i},j);return b!==y?N.ref=t||E:N.innerRef=E,o.createElement(m,N)}))}))},16550:(e,t,n)=>{"use strict";n.d(t,{AW:()=>L,F0:()=>v,LX:()=>A,TH:()=>B,k6:()=>D,l_:()=>E,rs:()=>I,s6:()=>y});var a=n(90144),r=n(67294),o=n(45697),i=n.n(o),s=n(42358),l=n(38776),c=n(83117),u=n(39658),d=n.n(u),p=(n(59864),n(80102)),f=(n(8679),1073741823),g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var h=r.createContext||function(e,t){var n,o,s="__create-react-context-"+function(){var e="__global_unique_id__";return g[e]=(g[e]||0)+1}()+"__",l=function(e){function n(){for(var t,n,a,r=arguments.length,o=new Array(r),i=0;i<r;i++)o[i]=arguments[i];return(t=e.call.apply(e,[this].concat(o))||this).emitter=(n=t.props.value,a=[],{on:function(e){a.push(e)},off:function(e){a=a.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,a.forEach((function(e){return e(n,t)}))}}),t}(0,a.Z)(n,e);var r=n.prototype;return r.getChildContext=function(){var e;return(e={})[s]=this.emitter,e},r.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,a=this.props.value,r=e.value;((o=a)===(i=r)?0!==o||1/o==1/i:o!=o&&i!=i)?n=0:(n="function"==typeof t?t(a,r):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var o,i},r.render=function(){return this.props.children},n}(r.Component);l.childContextTypes=((n={})[s]=i().object.isRequired,n);var c=function(t){function n(){for(var e,n=arguments.length,a=new Array(n),r=0;r<n;r++)a[r]=arguments[r];return(e=t.call.apply(t,[this].concat(a))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){0!=((0|e.observedBits)&n)&&e.setState({value:e.getValue()})},e}(0,a.Z)(n,t);var r=n.prototype;return r.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},r.componentDidMount=function(){this.context[s]&&this.context[s].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},r.componentWillUnmount=function(){this.context[s]&&this.context[s].off(this.onUpdate)},r.getValue=function(){return this.context[s]?this.context[s].get():e},r.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(r.Component);return c.contextTypes=((o={})[s]=i().object,o),{Provider:l,Consumer:c}},m=function(e){var t=h();return t.displayName=e,t},b=m("Router-History"),y=m("Router"),v=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,a.Z)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return r.createElement(y.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},r.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(r.Component);r.Component;var x=function(e){function t(){return e.apply(this,arguments)||this}(0,a.Z)(t,e);var n=t.prototype;return n.componentDidMount=function(){this.props.onMount&&this.props.onMount.call(this,this)},n.componentDidUpdate=function(e){this.props.onUpdate&&this.props.onUpdate.call(this,this,e)},n.componentWillUnmount=function(){this.props.onUnmount&&this.props.onUnmount.call(this,this)},n.render=function(){return null},t}(r.Component);var w={},_=1e4,k=0;function S(e,t){return void 0===e&&(e="/"),void 0===t&&(t={}),"/"===e?e:function(e){if(w[e])return w[e];var t=d().compile(e);return k<_&&(w[e]=t,k++),t}(e)(t,{pretty:!0})}function E(e){var t=e.computedMatch,n=e.to,a=e.push,o=void 0!==a&&a;return r.createElement(y.Consumer,null,(function(e){e||(0,l.Z)(!1);var a=e.history,i=e.staticContext,u=o?a.push:a.replace,d=(0,s.ob)(t?"string"==typeof n?S(n,t.params):(0,c.Z)({},n,{pathname:S(n.pathname,t.params)}):n);return i?(u(d),null):r.createElement(x,{onMount:function(){u(d)},onUpdate:function(e,t){var n=(0,s.ob)(t.to);(0,s.Hp)(n,(0,c.Z)({},d,{key:n.key}))||u(d)},to:n})}))}var j={},C=1e4,T=0;function A(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,a=n.path,r=n.exact,o=void 0!==r&&r,i=n.strict,s=void 0!==i&&i,l=n.sensitive,c=void 0!==l&&l;return[].concat(a).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var a=function(e,t){var n=""+t.end+t.strict+t.sensitive,a=j[n]||(j[n]={});if(a[e])return a[e];var r=[],o={regexp:d()(e,r,t),keys:r};return T<C&&(a[e]=o,T++),o}(n,{end:o,strict:s,sensitive:c}),r=a.regexp,i=a.keys,l=r.exec(e);if(!l)return null;var u=l[0],p=l.slice(1),f=e===u;return o&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:i.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var L=function(e){function t(){return e.apply(this,arguments)||this}return(0,a.Z)(t,e),t.prototype.render=function(){var e=this;return r.createElement(y.Consumer,null,(function(t){t||(0,l.Z)(!1);var n=e.props.location||t.location,a=e.props.computedMatch?e.props.computedMatch:e.props.path?A(n.pathname,e.props):t.match,o=(0,c.Z)({},t,{location:n,match:a}),i=e.props,s=i.children,u=i.component,d=i.render;return Array.isArray(s)&&function(e){return 0===r.Children.count(e)}(s)&&(s=null),r.createElement(y.Provider,{value:o},o.match?s?"function"==typeof s?s(o):s:u?r.createElement(u,o):d?d(o):null:"function"==typeof s?s(o):null)}))},t}(r.Component);function P(e){return"/"===e.charAt(0)?e:"/"+e}function N(e,t){if(!e)return t;var n=P(e);return 0!==t.pathname.indexOf(n)?t:(0,c.Z)({},t,{pathname:t.pathname.substr(n.length)})}function M(e){return"string"==typeof e?e:(0,s.Ep)(e)}function R(e){return function(){(0,l.Z)(!1)}}function O(){}r.Component;var I=function(e){function t(){return e.apply(this,arguments)||this}return(0,a.Z)(t,e),t.prototype.render=function(){var e=this;return r.createElement(y.Consumer,null,(function(t){t||(0,l.Z)(!1);var n,a,o=e.props.location||t.location;return r.Children.forEach(e.props.children,(function(e){if(null==a&&r.isValidElement(e)){n=e;var i=e.props.path||e.props.from;a=i?A(o.pathname,(0,c.Z)({},e.props,{path:i})):t.match}})),a?r.cloneElement(n,{location:o,computedMatch:a}):null}))},t}(r.Component);var F=r.useContext;function D(){return F(b)}function B(){return F(y).location}},39658:(e,t,n)=>{var a=n(5826);e.exports=f,e.exports.parse=o,e.exports.compile=function(e,t){return s(o(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=p;var r=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,a=[],o=0,i=0,s="",u=t&&t.delimiter||"/";null!=(n=r.exec(e));){var d=n[0],p=n[1],f=n.index;if(s+=e.slice(i,f),i=f+d.length,p)s+=p[1];else{var g=e[i],h=n[2],m=n[3],b=n[4],y=n[5],v=n[6],x=n[7];s&&(a.push(s),s="");var w=null!=h&&null!=g&&g!==h,_="+"===v||"*"===v,k="?"===v||"*"===v,S=n[2]||u,E=b||y;a.push({name:m||o++,prefix:h||"",delimiter:S,optional:k,repeat:_,partial:w,asterisk:!!x,pattern:E?c(E):x?".*":"[^"+l(S)+"]+?"})}}return i<e.length&&(s+=e.substr(i)),s&&a.push(s),a}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function s(e,t){for(var n=new Array(e.length),r=0;r<e.length;r++)"object"==typeof e[r]&&(n[r]=new RegExp("^(?:"+e[r].pattern+")$",d(t)));return function(t,r){for(var o="",s=t||{},l=(r||{}).pretty?i:encodeURIComponent,c=0;c<e.length;c++){var u=e[c];if("string"!=typeof u){var d,p=s[u.name];if(null==p){if(u.optional){u.partial&&(o+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(a(p)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var f=0;f<p.length;f++){if(d=l(p[f]),!n[c].test(d))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(d)+"`");o+=(0===f?u.prefix:u.delimiter)+d}}else{if(d=u.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):l(p),!n[c].test(d))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+d+'"');o+=u.prefix+d}}else o+=u}return o}}function l(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function d(e){return e&&e.sensitive?"":"i"}function p(e,t,n){a(t)||(n=t||n,t=[]);for(var r=(n=n||{}).strict,o=!1!==n.end,i="",s=0;s<e.length;s++){var c=e[s];if("string"==typeof c)i+=l(c);else{var p=l(c.prefix),f="(?:"+c.pattern+")";t.push(c),c.repeat&&(f+="(?:"+p+f+")*"),i+=f=c.optional?c.partial?p+"("+f+")?":"(?:"+p+"("+f+"))?":p+"("+f+")"}}var g=l(n.delimiter||"/"),h=i.slice(-g.length)===g;return r||(i=(h?i.slice(0,-g.length):i)+"(?:"+g+"(?=$))?"),i+=o?"$":r&&h?"":"(?="+g+"|$)",u(new RegExp("^"+i,d(n)),t)}function f(e,t,n){return a(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var a=0;a<n.length;a++)t.push({name:a,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):a(e)?function(e,t,n){for(var a=[],r=0;r<e.length;r++)a.push(f(e[r],t,n).source);return u(new RegExp("(?:"+a.join("|")+")",d(n)),t)}(e,t,n):function(e,t,n){return p(o(e,n),t,n)}(e,t,n)}},75251:(e,t,n)=>{"use strict";var a=n(67294),r=Symbol.for("react.element"),o=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=a.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l={key:!0,ref:!0,__self:!0,__source:!0};function c(e,t,n){var a,o={},c=null,u=null;for(a in void 0!==n&&(c=""+n),void 0!==t.key&&(c=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,a)&&!l.hasOwnProperty(a)&&(o[a]=t[a]);if(e&&e.defaultProps)for(a in t=e.defaultProps)void 0===o[a]&&(o[a]=t[a]);return{$$typeof:r,type:e,key:c,ref:u,props:o,_owner:s.current}}t.Fragment=o,t.jsx=c,t.jsxs=c},72408:(e,t)=>{"use strict";var n=Symbol.for("react.element"),a=Symbol.for("react.portal"),r=Symbol.for("react.fragment"),o=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),s=Symbol.for("react.provider"),l=Symbol.for("react.context"),c=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),d=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),f=Symbol.iterator;var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,m={};function b(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||g}function y(){}function v(e,t,n){this.props=e,this.context=t,this.refs=m,this.updater=n||g}b.prototype.isReactComponent={},b.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},b.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},y.prototype=b.prototype;var x=v.prototype=new y;x.constructor=v,h(x,b.prototype),x.isPureReactComponent=!0;var w=Array.isArray,_=Object.prototype.hasOwnProperty,k={current:null},S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,a){var r,o={},i=null,s=null;if(null!=t)for(r in void 0!==t.ref&&(s=t.ref),void 0!==t.key&&(i=""+t.key),t)_.call(t,r)&&!S.hasOwnProperty(r)&&(o[r]=t[r]);var l=arguments.length-2;if(1===l)o.children=a;else if(1<l){for(var c=Array(l),u=0;u<l;u++)c[u]=arguments[u+2];o.children=c}if(e&&e.defaultProps)for(r in l=e.defaultProps)void 0===o[r]&&(o[r]=l[r]);return{$$typeof:n,type:e,key:i,ref:s,props:o,_owner:k.current}}function j(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var C=/\/+/g;function T(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function A(e,t,r,o,i){var s=typeof e;"undefined"!==s&&"boolean"!==s||(e=null);var l=!1;if(null===e)l=!0;else switch(s){case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case n:case a:l=!0}}if(l)return i=i(l=e),e=""===o?"."+T(l,0):o,w(i)?(r="",null!=e&&(r=e.replace(C,"$&/")+"/"),A(i,t,r,"",(function(e){return e}))):null!=i&&(j(i)&&(i=function(e,t){return{$$typeof:n,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,r+(!i.key||l&&l.key===i.key?"":(""+i.key).replace(C,"$&/")+"/")+e)),t.push(i)),1;if(l=0,o=""===o?".":o+":",w(e))for(var c=0;c<e.length;c++){var u=o+T(s=e[c],c);l+=A(s,t,r,u,i)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=f&&e[f]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),c=0;!(s=e.next()).done;)l+=A(s=s.value,t,r,u=o+T(s,c++),i);else if("object"===s)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return l}function L(e,t,n){if(null==e)return e;var a=[],r=0;return A(e,a,"","",(function(e){return t.call(n,e,r++)})),a}function P(e){if(-1===e._status){var t=e._result;(t=t()).then((function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)}),(function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)})),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var N={current:null},M={transition:null},R={ReactCurrentDispatcher:N,ReactCurrentBatchConfig:M,ReactCurrentOwner:k};t.Children={map:L,forEach:function(e,t,n){L(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return L(e,(function(){t++})),t},toArray:function(e){return L(e,(function(e){return e}))||[]},only:function(e){if(!j(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=b,t.Fragment=r,t.Profiler=i,t.PureComponent=v,t.StrictMode=o,t.Suspense=u,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=R,t.cloneElement=function(e,t,a){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var r=h({},e.props),o=e.key,i=e.ref,s=e._owner;if(null!=t){if(void 0!==t.ref&&(i=t.ref,s=k.current),void 0!==t.key&&(o=""+t.key),e.type&&e.type.defaultProps)var l=e.type.defaultProps;for(c in t)_.call(t,c)&&!S.hasOwnProperty(c)&&(r[c]=void 0===t[c]&&void 0!==l?l[c]:t[c])}var c=arguments.length-2;if(1===c)r.children=a;else if(1<c){l=Array(c);for(var u=0;u<c;u++)l[u]=arguments[u+2];r.children=l}return{$$typeof:n,type:e.type,key:o,ref:i,props:r,_owner:s}},t.createContext=function(e){return(e={$$typeof:l,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:s,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:c,render:e}},t.isValidElement=j,t.lazy=function(e){return{$$typeof:p,_payload:{_status:-1,_result:e},_init:P}},t.memo=function(e,t){return{$$typeof:d,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=M.transition;M.transition={};try{e()}finally{M.transition=t}},t.unstable_act=function(){throw Error("act(...) is not supported in production builds of React.")},t.useCallback=function(e,t){return N.current.useCallback(e,t)},t.useContext=function(e){return N.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return N.current.useDeferredValue(e)},t.useEffect=function(e,t){return N.current.useEffect(e,t)},t.useId=function(){return N.current.useId()},t.useImperativeHandle=function(e,t,n){return N.current.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return N.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return N.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return N.current.useMemo(e,t)},t.useReducer=function(e,t,n){return N.current.useReducer(e,t,n)},t.useRef=function(e){return N.current.useRef(e)},t.useState=function(e){return N.current.useState(e)},t.useSyncExternalStore=function(e,t,n){return N.current.useSyncExternalStore(e,t,n)},t.useTransition=function(){return N.current.useTransition()},t.version="18.2.0"},67294:(e,t,n)=>{"use strict";e.exports=n(72408)},85893:(e,t,n)=>{"use strict";e.exports=n(75251)},60053:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var a=n-1>>>1,r=e[a];if(!(0<o(r,t)))break e;e[a]=t,e[n]=r,n=a}}function a(e){return 0===e.length?null:e[0]}function r(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var a=0,r=e.length,i=r>>>1;a<i;){var s=2*(a+1)-1,l=e[s],c=s+1,u=e[c];if(0>o(l,n))c<r&&0>o(u,l)?(e[a]=u,e[c]=n,a=c):(e[a]=l,e[s]=n,a=s);else{if(!(c<r&&0>o(u,n)))break e;e[a]=u,e[c]=n,a=c}}}return t}function o(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var s=Date,l=s.now();t.unstable_now=function(){return s.now()-l}}var c=[],u=[],d=1,p=null,f=3,g=!1,h=!1,m=!1,b="function"==typeof setTimeout?setTimeout:null,y="function"==typeof clearTimeout?clearTimeout:null,v="undefined"!=typeof setImmediate?setImmediate:null;function x(e){for(var t=a(u);null!==t;){if(null===t.callback)r(u);else{if(!(t.startTime<=e))break;r(u),t.sortIndex=t.expirationTime,n(c,t)}t=a(u)}}function w(e){if(m=!1,x(e),!h)if(null!==a(c))h=!0,M(_);else{var t=a(u);null!==t&&R(w,t.startTime-e)}}function _(e,n){h=!1,m&&(m=!1,y(j),j=-1),g=!0;var o=f;try{for(x(n),p=a(c);null!==p&&(!(p.expirationTime>n)||e&&!A());){var i=p.callback;if("function"==typeof i){p.callback=null,f=p.priorityLevel;var s=i(p.expirationTime<=n);n=t.unstable_now(),"function"==typeof s?p.callback=s:p===a(c)&&r(c),x(n)}else r(c);p=a(c)}if(null!==p)var l=!0;else{var d=a(u);null!==d&&R(w,d.startTime-n),l=!1}return l}finally{p=null,f=o,g=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var k,S=!1,E=null,j=-1,C=5,T=-1;function A(){return!(t.unstable_now()-T<C)}function L(){if(null!==E){var e=t.unstable_now();T=e;var n=!0;try{n=E(!0,e)}finally{n?k():(S=!1,E=null)}}else S=!1}if("function"==typeof v)k=function(){v(L)};else if("undefined"!=typeof MessageChannel){var P=new MessageChannel,N=P.port2;P.port1.onmessage=L,k=function(){N.postMessage(null)}}else k=function(){b(L,0)};function M(e){E=e,S||(S=!0,k())}function R(e,n){j=b((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){h||g||(h=!0,M(_))},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):C=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return f},t.unstable_getFirstCallbackNode=function(){return a(c)},t.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},t.unstable_scheduleCallback=function(e,r,o){var i=t.unstable_now();switch("object"==typeof o&&null!==o?o="number"==typeof(o=o.delay)&&0<o?i+o:i:o=i,e){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return e={id:d++,callback:r,priorityLevel:e,startTime:o,expirationTime:s=o+s,sortIndex:-1},o>i?(e.sortIndex=o,n(u,e),null===a(c)&&e===a(u)&&(m?(y(j),j=-1):m=!0,R(w,o-i))):(e.sortIndex=s,n(c,e),h||g||(h=!0,M(_))),e},t.unstable_shouldYield=A,t.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}},63840:(e,t,n)=>{"use strict";e.exports=n(60053)},96774:e=>{e.exports=function(e,t,n,a){var r=n?n.call(a,e,t):void 0;if(void 0!==r)return!!r;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var o=Object.keys(e),i=Object.keys(t);if(o.length!==i.length)return!1;for(var s=Object.prototype.hasOwnProperty.bind(t),l=0;l<o.length;l++){var c=o[l];if(!s(c))return!1;var u=e[c],d=t[c];if(!1===(r=n?n.call(a,u,d,c):void 0)||void 0===r&&u!==d)return!1}return!0}},36809:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});const a={title:"GG",url:"https://greeng00se.github.io",baseUrl:"/",onBrokenLinks:"throw",onBrokenMarkdownLinks:"warn",favicon:"img/duck.png",organizationName:"greeng00se",projectName:"greeng00se.github.io",trailingSlash:!1,i18n:{defaultLocale:"ko",locales:["ko"],path:"i18n",localeConfigs:{}},markdown:{mermaid:!0,format:"mdx",mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0}},themes:["@docusaurus/theme-mermaid"],presets:[["classic",{blog:{showReadingTime:!0,routeBasePath:"/",archiveBasePath:"/blog",postsPerPage:1,sortPosts:"descending",editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/"},docs:{sidebarPath:"/home/runner/work/greeng00se.github.io/greeng00se.github.io/sidebars.js",showLastUpdateTime:!0,editUrl:"https://github.com/greeng00se/greeng00se.github.io/tree/main/"},theme:{customCss:"/home/runner/work/greeng00se.github.io/greeng00se.github.io/src/css/custom.css"},gtag:{trackingID:"G-17TREGCW4H",anonymizeIP:!0},sitemap:{changefreq:"weekly",priority:.5,ignorePatterns:["/tags/**","/docs/**","/page/**"],filename:"sitemap.xml"}}]],themeConfig:{navbar:{title:"greeng\xf6\xf6se",items:[{to:"/blog",label:"\ube14\ub85c\uadf8",position:"left"},{position:"left",type:"doc",label:"\ubb38\uc11c",docId:"intro"},{href:"https://github.com/greeng00se",position:"right",className:"header-github-link","aria-label":"GitHub repository"}],hideOnScroll:!1},algolia:{appId:"YSMNU47L51",apiKey:"16caa11a7af7bf5db56b5f640fa738cd",indexName:"gh",contextualSearch:!0,searchParameters:{},searchPagePath:"search"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:["java","kotlin","groovy"],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},metadata:[{name:"google-site-verification",content:"APK6j79LMymudgmQDTV8u_RYyncFYyuFUjY9A0hVPv4"}],colorMode:{defaultMode:"dark",respectPrefersColorScheme:!0,disableSwitch:!1},mermaid:{theme:{light:"neutral",dark:"dark"},options:{}},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},baseUrlIssueBanner:!0,onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},plugins:[],scripts:[],headTags:[],stylesheets:[],clientModules:[],tagline:"",titleDelimiter:"|",noIndex:!1}},83117:(e,t,n)=>{"use strict";function a(){return a=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var a in n)Object.prototype.hasOwnProperty.call(n,a)&&(e[a]=n[a])}return e},a.apply(this,arguments)}n.d(t,{Z:()=>a})},90144:(e,t,n)=>{"use strict";function a(e,t){return a=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},a(e,t)}function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,a(e,t)}n.d(t,{Z:()=>r})},80102:(e,t,n)=>{"use strict";function a(e,t){if(null==e)return{};var n,a,r={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(r[n]=e[n]);return r}n.d(t,{Z:()=>a})},34798:(e,t,n)=>{"use strict";n.d(t,{p1:()=>C,y$:()=>ee});var a,r,o,i,s,l,c,u=n(67294),d=n(86010),p=Object.create,f=Object.defineProperty,g=Object.defineProperties,h=Object.getOwnPropertyDescriptor,m=Object.getOwnPropertyDescriptors,b=Object.getOwnPropertyNames,y=Object.getOwnPropertySymbols,v=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty,w=Object.prototype.propertyIsEnumerable,_=(e,t,n)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,k=(e,t)=>{for(var n in t||(t={}))x.call(t,n)&&_(e,n,t[n]);if(y)for(var n of y(t))w.call(t,n)&&_(e,n,t[n]);return e},S=(e,t)=>g(e,m(t)),E=(e,t)=>{var n={};for(var a in e)x.call(e,a)&&t.indexOf(a)<0&&(n[a]=e[a]);if(null!=e&&y)for(var a of y(e))t.indexOf(a)<0&&w.call(e,a)&&(n[a]=e[a]);return n},j=(a={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},a={util:{encode:function e(t){return t instanceof r?new r(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var r,o;switch(n=n||{},a.util.type(t)){case"Object":if(o=a.util.objId(t),n[o])return n[o];for(var i in r={},n[o]=r,t)t.hasOwnProperty(i)&&(r[i]=e(t[i],n));return r;case"Array":return o=a.util.objId(t),n[o]?n[o]:(r=[],n[o]=r,t.forEach((function(t,a){r[a]=e(t,n)})),r);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var a="no-"+t;e;){var r=e.classList;if(r.contains(t))return!0;if(r.contains(a))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=a.util.clone(a.languages[e]);for(var r in t)n[r]=t[r];return n},insertBefore:function(e,t,n,r){var o=(r=r||a.languages)[e],i={};for(var s in o)if(o.hasOwnProperty(s)){if(s==t)for(var l in n)n.hasOwnProperty(l)&&(i[l]=n[l]);n.hasOwnProperty(s)||(i[s]=o[s])}var c=r[e];return r[e]=i,a.languages.DFS(a.languages,(function(t,n){n===c&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,r,o){o=o||{};var i=a.util.objId;for(var s in t)if(t.hasOwnProperty(s)){n.call(t,s,t[s],r||s);var l=t[s],c=a.util.type(l);"Object"!==c||o[i(l)]?"Array"!==c||o[i(l)]||(o[i(l)]=!0,e(l,n,s,o)):(o[i(l)]=!0,e(l,n,null,o))}}},plugins:{},highlight:function(e,t,n){var o={code:e,grammar:t,language:n};if(a.hooks.run("before-tokenize",o),!o.grammar)throw new Error('The language "'+o.language+'" has no grammar.');return o.tokens=a.tokenize(o.code,o.grammar),a.hooks.run("after-tokenize",o),r.stringify(a.util.encode(o.tokens),o.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var a in n)t[a]=n[a];delete t.rest}var r=new s;return l(r,r.head,e),i(e,r,t,r.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(r)},hooks:{all:{},add:function(e,t){var n=a.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=a.hooks.all[e];if(n&&n.length)for(var r,o=0;r=n[o++];)r(t)}},Token:r};function r(e,t,n,a){this.type=e,this.content=t,this.alias=n,this.length=0|(a||"").length}function o(e,t,n,a){e.lastIndex=t;var r=e.exec(n);if(r&&a&&r[1]){var o=r[1].length;r.index+=o,r[0]=r[0].slice(o)}return r}function i(e,t,n,s,u,d){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var f=n[p];f=Array.isArray(f)?f:[f];for(var g=0;g<f.length;++g){if(d&&d.cause==p+","+g)return;var h=f[g],m=h.inside,b=!!h.lookbehind,y=!!h.greedy,v=h.alias;if(y&&!h.pattern.global){var x=h.pattern.toString().match(/[imsuy]*$/)[0];h.pattern=RegExp(h.pattern.source,x+"g")}for(var w=h.pattern||h,_=s.next,k=u;_!==t.tail&&!(d&&k>=d.reach);k+=_.value.length,_=_.next){var S=_.value;if(t.length>e.length)return;if(!(S instanceof r)){var E,j=1;if(y){if(!(E=o(w,k,e,b))||E.index>=e.length)break;var C=E.index,T=E.index+E[0].length,A=k;for(A+=_.value.length;C>=A;)A+=(_=_.next).value.length;if(k=A-=_.value.length,_.value instanceof r)continue;for(var L=_;L!==t.tail&&(A<T||"string"==typeof L.value);L=L.next)j++,A+=L.value.length;j--,S=e.slice(k,A),E.index-=k}else if(!(E=o(w,0,S,b)))continue;C=E.index;var P=E[0],N=S.slice(0,C),M=S.slice(C+P.length),R=k+S.length;d&&R>d.reach&&(d.reach=R);var O=_.prev;if(N&&(O=l(t,O,N),k+=N.length),c(t,O,j),_=l(t,O,new r(p,m?a.tokenize(P,m):P,v,P)),M&&l(t,_,M),j>1){var I={cause:p+","+g,reach:R};i(e,t,n,_.prev,k,I),d&&I.reach>d.reach&&(d.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var a=t.next,r={value:n,prev:t,next:a};return t.next=r,a.prev=r,e.length++,r}function c(e,t,n){for(var a=t.next,r=0;r<n&&a!==e.tail;r++)a=a.next;t.next=a,a.prev=t,e.length-=r}return r.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var r="";return t.forEach((function(t){r+=e(t,n)})),r}var o={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(o.classes,i):o.classes.push(i)),a.hooks.run("wrap",o);var s="";for(var l in o.attributes)s+=" "+l+'="'+(o.attributes[l]||"").replace(/"/g,""")+'"';return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+s+">"+o.content+"</"+o.tag+">"},a}();t.exports=n,n.default=n}},function(){return r||(0,a[b(a)[0]])((r={exports:{}}).exports,r),r.exports}),C=((e,t,n)=>(n=null!=e?p(v(e)):{},((e,t,n,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let r of b(t))x.call(e,r)||r===n||f(e,r,{get:()=>t[r],enumerable:!(a=h(t,r))||a.enumerable});return e})(!t&&e&&e.__esModule?n:f(n,"default",{value:e,enumerable:!0}),e)))(j());o=C,i={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},l="(?:[^\\\\-]|"+(s=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",l=RegExp(l+"-"+l),c={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},o.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:l,inside:{escape:s,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":i,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:s}},"special-escape":i,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":c}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:s,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":c}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}},C.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},C.languages.javascript=C.languages.extend("clike",{"class-name":[C.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),C.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,C.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:C.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:C.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:C.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:C.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:C.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),C.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:C.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),C.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),C.languages.markup&&(C.languages.markup.tag.addInlined("script","javascript"),C.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),C.languages.js=C.languages.javascript,C.languages.actionscript=C.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),C.languages.actionscript["class-name"].alias="function",delete C.languages.actionscript.parameter,delete C.languages.actionscript["literal-property"],C.languages.markup&&C.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:C.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(C),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var a=function(e){e.inside||(e.inside={}),e.inside.rest=n},r="doc-comment";if(o=e.languages[t]){var o,i=o[r];if((i=i||(o=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[r])instanceof RegExp&&(i=o[r]={pattern:i}),Array.isArray(i))for(var s=0,l=i.length;s<l;s++)i[s]instanceof RegExp&&(i[s]={pattern:i[s]}),a(i[s]);else a(i)}}))}}),t.addSupport(["java","javascript","php"],t)}(C),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(C),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(C),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,a="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",r=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return a})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return a}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return a})).replace(/<<key>>/g,(function(){return"(?:"+r+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(C),C.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},C.languages.markup.tag.inside["attr-value"].inside.entity=C.languages.markup.entity,C.languages.markup.doctype.inside["internal-subset"].inside=C.languages.markup,C.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(C.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:C.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:C.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},C.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(C.languages.markup.tag,"addAttribute",{value:function(e,t){C.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:C.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),C.languages.html=C.languages.markup,C.languages.mathml=C.languages.markup,C.languages.svg=C.languages.markup,C.languages.xml=C.languages.extend("markup",{}),C.languages.ssml=C.languages.xml,C.languages.atom=C.languages.xml,C.languages.rss=C.languages.xml,function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var a=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,r=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return a})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,i=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+r+o+"(?:"+r+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+r+o+")(?:"+r+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(a),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+r+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+r+"$"),inside:{"table-header":{pattern:RegExp(a),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,a=t.length;n<a;n++){var r,o=t[n];"code"!==o.type?e(o.content):(r=o.content[1],o=o.content[3],r&&o&&"code-language"===r.type&&"code-block"===o.type&&"string"==typeof r.content&&(r=r.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),r="language-"+(r=(/[a-z][\w-]*/i.exec(r)||[""])[0].toLowerCase()),o.alias?"string"==typeof o.alias?o.alias=[o.alias,r]:o.alias.push(r):o.alias=[r]))}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",a=0,r=t.classes.length;a<r;a++){var o=t.classes[a];if(o=/language-(.+)/.exec(o)){n=o[1];break}}var c,u=e.languages[n];u?t.content=e.highlight(t.content.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),l(n)):s[t]||e})),u,n):n&&"none"!==n&&e.plugins.autoloader&&(c="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=c,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(c);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))})))}})),RegExp(e.languages.markup.tag.pattern.source,"gi")),s={amp:"&",lt:"<",gt:">",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(C),C.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:C.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},C.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var a=t[n++];if("keyword"===a.type&&"mutation"===a.content){var r=[];if(d(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var o=p(/^\($/,/^\)$/);if(-1===o)continue;for(;n<o;n++){var i=u(0);"variable"===i.type&&(f(i,"variable-input"),r.push(i.content))}n=o+1}if(d(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),0<r.length)){var s=p(/^\{$/,/^\}$/);if(-1!==s)for(var l=n;l<s;l++){var c=t[l];"variable"===c.type&&0<=r.indexOf(c.content)&&f(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n<e.length;n++){var a=u(n+t);if(!a||a.type!==e[n])return}return 1}function p(e,a){for(var r=1,o=n;o<t.length;o++){var i=t[o],s=i.content;if("punctuation"===i.type&&"string"==typeof s)if(e.test(s))r++;else if(a.test(s)&&0==--r)return o}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),C.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,a=t.inside.interpolation,r=a.inside["interpolation-punctuation"],o=a.pattern.source;function i(t,a){if(e.languages[t])return{pattern:RegExp("((?:"+a+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(t,n,a){return t={code:t,grammar:n,language:a},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function l(t,n,i){var l=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),c=0,u={},d=(l=s(l.map((function(e){if("string"==typeof e)return e;var n,a;for(e=e.content;-1!==t.indexOf((a=c++,n="___"+i.toUpperCase()+"_"+a+"___")););return u[n]=e,n})).join(""),n,i),Object.keys(u));return c=0,function t(n){for(var o=0;o<n.length;o++){if(c>=d.length)return;var i,l,p,f,g,h,m,b=n[o];"string"==typeof b||"string"==typeof b.content?(i=d[c],-1!==(m=(h="string"==typeof b?b:b.content).indexOf(i))&&(++c,l=h.substring(0,m),g=u[i],p=void 0,(f={})["interpolation-punctuation"]=r,3===(f=e.tokenize(g,f)).length&&((p=[1,1]).push.apply(p,s(f[1],e.languages.javascript,"javascript")),f.splice.apply(f,p)),p=new e.Token("interpolation",f,a.alias,g),f=h.substring(m+i.length),g=[],l&&g.push(l),g.push(p),f&&(t(h=[f]),g.push.apply(g,h)),"string"==typeof b?(n.splice.apply(n,[o,1].concat(g)),o+=g.length-1):b.content=g)):(m=b.content,Array.isArray(m)?t(m):t([m]))}}(l),new e.Token(i,l,"language-"+i,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var c={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function u(e){return"string"==typeof e?e:Array.isArray(e)?e.map(u).join(""):u(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in c&&function t(n){for(var a=0,r=n.length;a<r;a++){var o,i,s,c=n[a];"string"!=typeof c&&(o=c.content,Array.isArray(o)?"template-string"===c.type?(c=o[1],3===o.length&&"string"!=typeof c&&"embedded-code"===c.type&&(i=u(c),c=c.alias,c=Array.isArray(c)?c[0]:c,s=e.languages[c])&&(o[1]=l(i,s,c))):t(o):"string"!=typeof o&&t([o]))}}(t.tokens)}))}(C),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(C),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,a="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(a+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(a+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(C),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(C),C.languages.n4js=C.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),C.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),C.languages.n4jsd=C.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],a=0;a<n.length;a++){var r=n[a],o=e.languages.javascript[r];r=(o="RegExp"===e.util.type(o)?e.languages.javascript[r]={pattern:o}:o).inside||{};(o.inside=r)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(C),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,a=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,r=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function o(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return a})).replace(/<SPREAD>/g,(function(){return r})),RegExp(e,t)}function i(t){for(var n=[],a=0;a<t.length;a++){var r=t[a],o=!1;"string"!=typeof r&&("tag"===r.type&&r.content[0]&&"tag"===r.content[0].type?"</"===r.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===s(r.content[0].content[1])&&n.pop():"/>"!==r.content[r.content.length-1].content&&n.push({tagName:s(r.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===r.type&&"{"===r.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===r.type&&"}"===r.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof r)&&0<n.length&&0===n[n.length-1].openedBraces&&(o=s(r),a<t.length-1&&("string"==typeof t[a+1]||"plain-text"===t[a+1].type)&&(o+=s(t[a+1]),t.splice(a+1,1)),0<a&&("string"==typeof t[a-1]||"plain-text"===t[a-1].type)&&(o=s(t[a-1])+o,t.splice(a-1,1),a--),t[a]=new e.Token("plain-text",o,null,o)),r.content&&"string"!=typeof r.content&&i(r.content)}}r=o(r).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var s=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(s).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||i(e.tokens)}))}(C),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(C),C.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},C.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=C.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(C),C.languages.c=C.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),C.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),C.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},C.languages.c.string],char:C.languages.c.char,comment:C.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:C.languages.c}}}}),C.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete C.languages.c.boolean,C.languages.objectivec=C.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete C.languages.objectivec["class-name"],C.languages.objc=C.languages.objectivec,C.languages.reason=C.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),C.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete C.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,(function(){return t}));t=t.replace(/<self>/g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(C),C.languages.go=C.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),C.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete C.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(C);((e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>T,duotoneDark:()=>A,duotoneLight:()=>L,github:()=>P,jettwaveDark:()=>H,jettwaveLight:()=>V,nightOwl:()=>N,nightOwlLight:()=>M,oceanicNext:()=>I,okaidia:()=>F,oneDark:()=>W,oneLight:()=>q,palenight:()=>D,shadesOfPurple:()=>B,synthwave84:()=>z,ultramin:()=>$,vsDark:()=>U,vsLight:()=>Z});var T={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},A={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},L={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},P={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},N={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},M={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},R="#c5a5c5",O="#8dc891",I={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:R}},{types:["attr-value"],style:{color:O}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:O}},{types:["punctuation"],style:{color:O}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:R}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},F={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},D={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},B={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},z={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},$={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},U={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},Z={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},H={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},V={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},W={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},q={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},G=(e,t)=>{const{plain:n}=e,a=e.styles.reduce(((e,n)=>{const{languages:a,style:r}=n;return a&&!a.includes(t)||n.types.forEach((t=>{const n=k(k({},e[t]),r);e[t]=n})),e}),{});return a.root=n,a.plain=S(k({},n),{backgroundColor:void 0}),a},K=/\r\n|\r|\n/,Y=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},Q=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},X=e=>{const t=[[]],n=[e],a=[0],r=[e.length];let o=0,i=0,s=[];const l=[s];for(;i>-1;){for(;(o=a[i]++)<r[i];){let e,c=t[i];const u=n[i][o];if("string"==typeof u?(c=i>0?c:["plain"],e=u):(c=Q(c,u.type),u.alias&&(c=Q(c,u.alias)),e=u.content),"string"!=typeof e){i++,t.push(c),n.push(e),a.push(0),r.push(e.length);continue}const d=e.split(K),p=d.length;s.push({types:c,content:d[0]});for(let t=1;t<p;t++)Y(s),l.push(s=[]),s.push({types:c,content:d[t]})}i--,t.pop(),n.pop(),a.pop(),r.pop()}return Y(s),l},J=({children:e,language:t,code:n,theme:a,prism:r})=>{const o=t.toLowerCase(),i=((e,t)=>{const[n,a]=(0,u.useState)(G(t,e)),r=(0,u.useRef)(),o=(0,u.useRef)();return(0,u.useEffect)((()=>{t===r.current&&e===o.current||(r.current=t,o.current=e,a(G(t,e)))}),[e,t]),n})(o,a),s=(e=>(0,u.useCallback)((t=>{var n=t,{className:a,style:r,line:o}=n,i=E(n,["className","style","line"]);const s=S(k({},i),{className:(0,d.Z)("token-line",a)});return"object"==typeof e&&"plain"in e&&(s.style=e.plain),"object"==typeof r&&(s.style=k(k({},s.style||{}),r)),s}),[e]))(i),l=(e=>{const t=(0,u.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,u.useCallback)((e=>{var n=e,{token:a,className:r,style:o}=n,i=E(n,["token","className","style"]);const s=S(k({},i),{className:(0,d.Z)("token",...a.types,r),children:a.content,style:t(a)});return null!=o&&(s.style=k(k({},s.style||{}),o)),s}),[t])})(i),c=(({prism:e,code:t,grammar:n,language:a})=>{const r=(0,u.useRef)(e);return(0,u.useMemo)((()=>{if(null==n)return X([t]);const e={code:t,grammar:n,language:a,tokens:[]};return r.current.hooks.run("before-tokenize",e),e.tokens=r.current.tokenize(t,n),r.current.hooks.run("after-tokenize",e),X(e.tokens)}),[t,n,a])})({prism:r,language:o,code:n,grammar:r.languages[o]});return e({tokens:c,className:`prism-code language-${o}`,style:null!=i?i.root:{},getLineProps:s,getTokenProps:l})},ee=e=>(0,u.createElement)(J,S(k({},e),{prism:e.prism||C,theme:e.theme||U,code:e.code,language:e.language}))},38776:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var a=!0,r="Invariant failed";function o(e,t){if(!e){if(a)throw new Error(r);var n="function"==typeof t?t():t,o=n?"".concat(r,": ").concat(n):r;throw new Error(o)}}},57529:e=>{"use strict";e.exports=JSON.parse('{"theme.AnnouncementBar.closeButtonAriaLabel":"\ub2eb\uae30","theme.BackToTopButton.buttonAriaLabel":"\ub9e8 \uc704\ub85c \uc2a4\ud06c\ub864\ud558\uae30","theme.CodeBlock.copied":"\ubcf5\uc0ac\ud588\uc2b5\ub2c8\ub2e4","theme.CodeBlock.copy":"\ubcf5\uc0ac","theme.CodeBlock.copyButtonAriaLabel":"\ud074\ub9bd\ubcf4\ub4dc\uc5d0 \ucf54\ub4dc \ubcf5\uc0ac","theme.CodeBlock.wordWrapToggle":"\uc904 \ubc14\uafc8 \uc804\ud658","theme.DocSidebarItem.collapseCategoryAriaLabel":"Collapse sidebar category \'{label}\'","theme.DocSidebarItem.expandCategoryAriaLabel":"Expand sidebar category \'{label}\'","theme.ErrorPageContent.title":"\ud398\uc774\uc9c0\uc5d0 \uc624\ub958\uac00 \ubc1c\uc0dd\ud558\uc600\uc2b5\ub2c8\ub2e4.","theme.ErrorPageContent.tryAgain":"\ub2e4\uc2dc \uc2dc\ub3c4\ud574 \ubcf4\uc138\uc694","theme.NavBar.navAriaLabel":"Main","theme.NotFound.p1":"\uc6d0\ud558\ub294 \ud398\uc774\uc9c0\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.","theme.NotFound.p2":"\uc0ac\uc774\ud2b8 \uad00\ub9ac\uc790\uc5d0\uac8c \ub9c1\ud06c\uac00 \uae68\uc9c4 \uac83\uc744 \uc54c\ub824\uc8fc\uc138\uc694.","theme.NotFound.title":"\ud398\uc774\uc9c0\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.","theme.TOCCollapsible.toggleButtonLabel":"\uc774 \ud398\uc774\uc9c0\uc5d0\uc11c","theme.admonition.caution":"\uc8fc\uc758","theme.admonition.danger":"\uc704\ud5d8","theme.admonition.info":"\uc815\ubcf4","theme.admonition.note":"\ub178\ud2b8","theme.admonition.tip":"\ud301","theme.admonition.warning":"warning","theme.blog.archive.description":"\uac8c\uc2dc\ubb3c \ubaa9\ub85d","theme.blog.archive.title":"\uac8c\uc2dc\ubb3c \ubaa9\ub85d","theme.blog.paginator.navAriaLabel":"\ube14\ub85c\uadf8 \uac8c\uc2dc\ubb3c \ubaa9\ub85d \ud0d0\uc0c9","theme.blog.paginator.newerEntries":"\uc774\uc804 \ud398\uc774\uc9c0","theme.blog.paginator.olderEntries":"\ub2e4\uc74c \ud398\uc774\uc9c0","theme.blog.post.paginator.navAriaLabel":"\ube14\ub85c\uadf8 \uac8c\uc2dc\ubb3c \ud0d0\uc0c9","theme.blog.post.paginator.newerPost":"\uc774\uc804 \uac8c\uc2dc\ubb3c","theme.blog.post.paginator.olderPost":"\ub2e4\uc74c \uac8c\uc2dc\ubb3c","theme.blog.post.plurals":"{count}\uac1c \uac8c\uc2dc\ubb3c","theme.blog.post.readMore":"\uc790\uc138\ud788 \ubcf4\uae30","theme.blog.post.readMoreLabel":"{title} \uc5d0 \ub300\ud574 \ub354 \uc77d\uc5b4\ubcf4\uae30","theme.blog.post.readingTime.plurals":"\uc57d {readingTime}\ubd84","theme.blog.sidebar.navAriaLabel":"\ucd5c\uadfc \ube14\ub85c\uadf8 \ubb38\uc11c \ub458\ub7ec\ubcf4\uae30","theme.blog.tagTitle":"\\"{tagName}\\" \ud0dc\uadf8\ub85c \uc5f0\uacb0\ub41c {nPosts}\uac1c\uc758 \uac8c\uc2dc\ubb3c\uc774 \uc788\uc2b5\ub2c8\ub2e4.","theme.colorToggle.ariaLabel":"\uc5b4\ub450\uc6b4 \ubaa8\ub4dc\uc640 \ubc1d\uc740 \ubaa8\ub4dc \uc804\ud658\ud558\uae30 (\ud604\uc7ac {mode})","theme.colorToggle.ariaLabel.mode.dark":"\uc5b4\ub450\uc6b4 \ubaa8\ub4dc","theme.colorToggle.ariaLabel.mode.light":"\ubc1d\uc740 \ubaa8\ub4dc","theme.common.editThisPage":"\ud398\uc774\uc9c0 \ud3b8\uc9d1","theme.common.headingLinkTitle":"{heading}\uc5d0 \ub300\ud55c \uc9c1\uc811 \ub9c1\ud06c","theme.common.skipToMainContent":"\ubcf8\ubb38\uc73c\ub85c \uac74\ub108\ub6f0\uae30","theme.docs.DocCard.categoryDescription":"{count} \ud56d\ubaa9","theme.docs.breadcrumbs.home":"\ud648","theme.docs.breadcrumbs.navAriaLabel":"Breadcrumbs","theme.docs.paginator.navAriaLabel":"\ubb38\uc11c \ud398\uc774\uc9c0","theme.docs.paginator.next":"\ub2e4\uc74c","theme.docs.paginator.previous":"\uc774\uc804","theme.docs.sidebar.closeSidebarButtonAriaLabel":"Close navigation bar","theme.docs.sidebar.collapseButtonAriaLabel":"\uc0ac\uc774\ub4dc\ubc14 \uc228\uae30\uae30","theme.docs.sidebar.collapseButtonTitle":"\uc0ac\uc774\ub4dc\ubc14 \uc228\uae30\uae30","theme.docs.sidebar.expandButtonAriaLabel":"\uc0ac\uc774\ub4dc\ubc14 \uc5f4\uae30","theme.docs.sidebar.expandButtonTitle":"\uc0ac\uc774\ub4dc\ubc14 \uc5f4\uae30","theme.docs.sidebar.navAriaLabel":"Docs sidebar","theme.docs.sidebar.toggleSidebarButtonAriaLabel":"Toggle navigation bar","theme.docs.tagDocListPageTitle":"{nDocsTagged} \\"{tagName}\\" \ud0dc\uadf8\uc5d0 \ubd84\ub958\ub418\uc5c8\uc2b5\ub2c8\ub2e4","theme.docs.tagDocListPageTitle.nDocsTagged":"{count}\uac1c \ubb38\uc11c\uac00","theme.docs.versionBadge.label":"\ubc84\uc804: {versionLabel}","theme.docs.versions.latestVersionLinkLabel":"\ucd5c\uc2e0 \ubc84\uc804","theme.docs.versions.latestVersionSuggestionLabel":"\ucd5c\uc2e0 \ubb38\uc11c\ub294 {latestVersionLink} ({versionLabel})\uc744 \ud655\uc778\ud558\uc138\uc694.","theme.docs.versions.unmaintainedVersionLabel":"{siteTitle} {versionLabel} \ubb38\uc11c\ub294 \ub354 \uc774\uc0c1 \uc5c5\ub370\uc774\ud2b8\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.","theme.docs.versions.unreleasedVersionLabel":"{siteTitle} {versionLabel} \ubb38\uc11c\ub294 \uc544\uc9c1 \uc815\uc2dd \uacf5\uac1c\ub418\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.","theme.lastUpdated.atDate":" {date}\uc5d0","theme.lastUpdated.byUser":" {user}\uac00","theme.lastUpdated.lastUpdatedAtBy":"\ucd5c\uc885 \uc218\uc815: {atDate}{byUser}","theme.navbar.mobileLanguageDropdown.label":"\uc5b8\uc5b4","theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel":"\u2190 \uba54\uc778 \uba54\ub274\ub85c \ub3cc\uc544\uac00\uae30","theme.navbar.mobileVersionsDropdown.label":"\ubc84\uc804","theme.tags.tagsListLabel":"\ud0dc\uadf8:","theme.tags.tagsPageLink":"\ubaa8\ub4e0 \ud0dc\uadf8 \ubcf4\uae30","theme.tags.tagsPageTitle":"\ud0dc\uadf8","theme.unlistedContent.message":"This page is unlisted. Search engines will not index it, and only users having a direct link can access it.","theme.unlistedContent.title":"Unlisted page","theme.SearchBar.label":"\uac80\uc0c9","theme.SearchBar.seeAll":"{count}\uac1c\uc758 \uacb0\uacfc \ud655\uc778\ud558\uae30","theme.SearchModal.errorScreen.helpText":"\uc778\ud130\ub137 \uc5f0\uacb0\uc744 \ub2e4\uc2dc \ud655\uc778\ud558\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.","theme.SearchModal.errorScreen.titleText":"\uacb0\uacfc\ub97c \ubd88\ub7ec\uc62c \uc218 \uc5c6\uc74c","theme.SearchModal.footer.closeKeyAriaLabel":"Esc \ud0a4","theme.SearchModal.footer.closeText":"\ub85c \uc885\ub8cc","theme.SearchModal.footer.navigateDownKeyAriaLabel":"\ud654\uc0b4\ud45c \uc544\ub798 \ud0a4","theme.SearchModal.footer.navigateText":"\ub85c \uc774\ub3d9","theme.SearchModal.footer.navigateUpKeyAriaLabel":"\ud654\uc0b4\ud45c \uc704 \ud0a4","theme.SearchModal.footer.searchByText":"\uac80\uc0c9 \uc81c\uacf5","theme.SearchModal.footer.selectKeyAriaLabel":"\uc5d4\ud130 \ud0a4","theme.SearchModal.footer.selectText":"\ub85c \uc120\ud0dd","theme.SearchModal.noResultsScreen.noResultsText":"\uac80\uc0c9 \uacb0\uacfc \uc5c6\uc74c","theme.SearchModal.noResultsScreen.reportMissingResultsLinkText":"\uc54c\ub824\uc8fc\uc2dc\uae30 \ubc14\ub78d\ub2c8\ub2e4.","theme.SearchModal.noResultsScreen.reportMissingResultsText":"\uac80\uc0c9 \uacb0\uacfc\uac00 \uc5c6\ub294 \uac83\uc774 \uc624\ub958\ub77c\uace0 \uc0dd\uac01\ub418\uc2ed\ub2c8\uae4c?","theme.SearchModal.noResultsScreen.suggestedQueryText":"\ub2e4\ub978 \ucd94\ucc9c \uac80\uc0c9\uc5b4","theme.SearchModal.placeholder":"\ubb38\uc11c \uac80\uc0c9","theme.SearchModal.searchBox.cancelButtonText":"\ucde8\uc18c","theme.SearchModal.searchBox.resetButtonTitle":"\uac80\uc0c9\uc5b4 \ucd08\uae30\ud654","theme.SearchModal.startScreen.favoriteSearchesTitle":"\uc990\uaca8\ucc3e\uae30","theme.SearchModal.startScreen.noRecentSearchesText":"\ucd5c\uadfc \uac80\uc0c9\uc5b4 \uc5c6\uc74c","theme.SearchModal.startScreen.recentSearchesTitle":"\ucd5c\uadfc","theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle":"\uc774 \uac80\uc0c9\uc5b4\ub97c \uc990\uaca8\ucc3e\uae30\uc5d0\uc11c \uc0ad\uc81c","theme.SearchModal.startScreen.removeRecentSearchButtonTitle":"\uc774 \uac80\uc0c9\uc5b4\ub97c \ucd5c\uadfc \uac80\uc0c9\uc5b4\uc5d0\uc11c \uc0ad\uc81c","theme.SearchModal.startScreen.saveRecentSearchButtonTitle":"\uc774 \uac80\uc0c9\uc5b4\ub97c \uc800\uc7a5","theme.SearchPage.algoliaLabel":"Algolia\ub85c \uac80\uc0c9","theme.SearchPage.documentsFound.plurals":"{count}\uac1c\uc758 \ubb38\uc11c\ub97c \ucc3e\uc558\uc2b5\ub2c8\ub2e4.","theme.SearchPage.emptyResultsTitle":"\ubb38\uc11c\ub97c \uac80\uc0c9\ud569\ub2c8\ub2e4.","theme.SearchPage.existingResultsTitle":"\\"{query}\\" \uac80\uc0c9 \uacb0\uacfc","theme.SearchPage.fetchingNewResults":"\uc0c8\ub85c\uc6b4 \uac80\uc0c9 \uacb0\uacfc\ub97c \ubd88\ub7ec\uc624\ub294 \uc911\uc785\ub2c8\ub2e4.","theme.SearchPage.inputLabel":"\uac80\uc0c9","theme.SearchPage.inputPlaceholder":"\uac80\uc0c9\uc5b4\ub97c \uc785\ub825\ud558\uc138\uc694.","theme.SearchPage.noResultsText":"\uac80\uc0c9 \uacb0\uacfc\uac00 \uc5c6\uc2b5\ub2c8\ub2e4."}')},16887:e=>{"use strict";e.exports=JSON.parse('{"/2022-retrospective-624":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"9b43eac8"},"/accidental-duplication-d17":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"bace0b37"},"/blackjack-retrospective-595":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"3dd4d232"},"/blog-3d8":{"__comp":"9e4087bc","__context":{"plugin":"509d519c"},"archive":"b2b675dd"},"/book-leadership-and-self-deception-ddd":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"829fa7b9"},"/book-writer-3c9":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"fa3d3942"},"/chess-retrospective-168":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"8a24850b"},"/cloudwatch-cb1":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"c1b17b3f"},"/composite-302":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"c6d04683"},"/custom-jdbc-template-cfa":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"d7955594"},"/db-replication-6f2":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"f06cb3e2"},"/docusaurus-926":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"1236fad7"},"/grasp-f9b":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"e9eabc5d"},"/innodb-lock-d18":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"130df38c"},"/intellij-settings-80e":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"14dc1923"},"/java-class-file-50e":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"8720c147"},"/java-spring-springboot-bed":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"ff4c6c5e"},"/jdbc-retrospective-158":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"b41adc00"},"/jenkins-48c":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"b2ebb6fd"},"/jsr-310-7f9":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"101b58de"},"/kotlin-null-8d3":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"d28e30d7"},"/ladder-retrospective-7ea":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"327fa616"},"/level2-interview-retrospective-c75":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"6552f31f"},"/log-async-exception-a44":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"e2326195"},"/mock-static-method-fd3":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"42957a8d"},"/mvc-retrospective-96d":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"5a473bed"},"/mysql-lock-3cb":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"cb6229c3"},"/order-retrospective-a11":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"b2c8756c"},"/page/10-c2c":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"0e33a907"}],"metadata":"f332d221"},"/page/11-89b":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f25de701"}],"metadata":"fbd57548"},"/page/12-155":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d65e25b7"}],"metadata":"f4f49e13"},"/page/13-ece":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"7159c7ff"}],"metadata":"2832e534"},"/page/14-1f9":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a59d28a9"}],"metadata":"4959fc42"},"/page/15-cc0":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8ad2f007"}],"metadata":"38d8699e"},"/page/16-813":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4d43abad"}],"metadata":"09fbb6bd"},"/page/17-843":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"26dc40bf"}],"metadata":"d1cef389"},"/page/18-84a":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f87bdf62"}],"metadata":"9cfe8fd1"},"/page/19-e4e":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"be497a8d"}],"metadata":"96adae60"},"/page/2-256":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5c07bdab"}],"metadata":"0c071de2"},"/page/20-30e":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"79a97f4e"}],"metadata":"35293ec4"},"/page/21-553":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dca6a1e3"}],"metadata":"80960b4b"},"/page/22-a88":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"08e37dbc"}],"metadata":"ef5b2427"},"/page/23-edf":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"48faf148"}],"metadata":"871c1e5a"},"/page/24-915":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d5bb232a"}],"metadata":"635a92d5"},"/page/25-4aa":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1781b1c4"}],"metadata":"226700de"},"/page/26-ec5":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6f385a52"}],"metadata":"54cb095e"},"/page/27-339":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ad3b7b62"}],"metadata":"5f81b25c"},"/page/28-376":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"21294bbb"}],"metadata":"270346fa"},"/page/29-ea0":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e1735da7"}],"metadata":"12cbeba7"},"/page/3-d5c":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5d4cff52"}],"metadata":"e4ebfe18"},"/page/30-2ff":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"aacfeabc"}],"metadata":"00931cc3"},"/page/31-d32":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"eff1d58f"}],"metadata":"d50fd269"},"/page/32-02d":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"daff1d93"}],"metadata":"754fb852"},"/page/33-3d4":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"9bad5ae7"}],"metadata":"f3e308ad"},"/page/34-4d2":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"db86613e"}],"metadata":"6dd1c948"},"/page/35-b81":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"73688d5c"}],"metadata":"c29bedb9"},"/page/36-598":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"bb221eab"}],"metadata":"69c28c32"},"/page/37-eda":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dfc7013c"}],"metadata":"494882d1"},"/page/38-9cf":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6b54f6a4"}],"metadata":"2e10a69c"},"/page/39-27d":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a8cba70f"}],"metadata":"64868a43"},"/page/4-b0c":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ae82353f"}],"metadata":"7762a24e"},"/page/40-744":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1251d98b"}],"metadata":"eec33099"},"/page/41-793":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e6a6ed43"}],"metadata":"32b2299c"},"/page/42-0ee":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4485017c"}],"metadata":"70275fcd"},"/page/43-345":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"df147deb"}],"metadata":"d2611248"},"/page/44-3c4":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"b6ffb0cb"}],"metadata":"1bb997fc"},"/page/45-6e5":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1f61820a"}],"metadata":"101cf32b"},"/page/46-d10":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"52106a5f"}],"metadata":"53e4509a"},"/page/47-280":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1f05d14a"}],"metadata":"15eddcef"},"/page/48-8df":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"537817cb"}],"metadata":"69a75ff2"},"/page/49-282":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"2c9f5501"}],"metadata":"04c55e47"},"/page/5-87c":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1664646a"}],"metadata":"8d05b77c"},"/page/50-3c4":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8a27aeff"}],"metadata":"f01ceada"},"/page/51-658":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"372ccfe9"}],"metadata":"7881a85f"},"/page/6-a58":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"cd68cda1"}],"metadata":"7af1d52f"},"/page/7-bb8":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"905ecccc"}],"metadata":"d0e4cdf1"},"/page/8-2f3":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"70834889"}],"metadata":"f75a8651"},"/page/9-88d":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"92ade856"}],"metadata":"6093f82b"},"/parameterized-tests-1fb":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"3f6ea930"},"/performance-test-type-df3":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"0571a526"},"/racing-car-retrospective-ebc":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"92fef07b"},"/refactoring-retrospective-ab4":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"1e8ecffe"},"/route-image-async-with-event-832":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"4b79a3c9"},"/route-image-implementation-b0f":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"cc519f63"},"/route-image-intro-7e7":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"9e2e3982"},"/route-image-python-dfd":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"cef46b76"},"/search-c1e":{"__comp":"1a4e3797","__context":{"plugin":"18c69d70"}},"/shopping-cart-retrospective-28b":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"6675e9ab"},"/spring-test-isolation-8ed":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"448c20a0"},"/subway-retrospective-7db":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"16f719ab"},"/tags-4bf":{"__comp":"01a85c17","__context":{"plugin":"509d519c"},"sidebar":"814f3328","tags":"c573638f"},"/tags/async-a21":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"cd68cda1"}],"tag":"8fbd512b","listMetadata":"a1877440"},"/tags/async/page/2-436":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d65e25b7"}],"tag":"6d4355d3","listMetadata":"9f586ca3"},"/tags/awt-9e3":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"7159c7ff"}],"tag":"cf8e491a","listMetadata":"9b56b618"},"/tags/awt/page/2-b68":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4d43abad"}],"tag":"f0978ee1","listMetadata":"32397cb2"},"/tags/book-4df":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"daff1d93"}],"tag":"2d3b202f","listMetadata":"14164549"},"/tags/book/page/2-88a":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"2c9f5501"}],"tag":"2bfe7c0b","listMetadata":"c0cb7215"},"/tags/book/page/3-128":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"372ccfe9"}],"tag":"df862072","listMetadata":"ffb0fa11"},"/tags/class-d3d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dfc7013c"}],"tag":"33736670","listMetadata":"8d7288fe"},"/tags/cloudwatch-264":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f25de701"}],"tag":"b7d33121","listMetadata":"6cfe3a99"},"/tags/composite-931":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d5bb232a"}],"tag":"255134d9","listMetadata":"ae1d6508"},"/tags/data-base-2fe":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"9bad5ae7"}],"tag":"0a2eaa84","listMetadata":"309173fa"},"/tags/data-base/page/2-049":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"db86613e"}],"tag":"9dec6b67","listMetadata":"66d1c769"},"/tags/data-base/page/3-9ac":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"73688d5c"}],"tag":"02689328","listMetadata":"dfa84138"},"/tags/documentation-86d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"be497a8d"}],"tag":"7bbc420e","listMetadata":"20e99c2a"},"/tags/dto-bef":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6f385a52"}],"tag":"5a6c6934","listMetadata":"d0277431"},"/tags/elastic-beanstalk-164":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"aacfeabc"}],"tag":"28a1570f","listMetadata":"0746167d"},"/tags/event-56a":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d65e25b7"}],"tag":"0cb009d1","listMetadata":"8dc09bac"},"/tags/exception-5b1":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"cd68cda1"}],"tag":"cc3bdf2f","listMetadata":"4515250b"},"/tags/grasp-130":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e6a6ed43"}],"tag":"b9bcab37","listMetadata":"2f43e44a"},"/tags/image-067":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"7159c7ff"}],"tag":"75121fd5","listMetadata":"d368e73e"},"/tags/image/page/2-88a":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a59d28a9"}],"tag":"562496aa","listMetadata":"b474adfe"},"/tags/image/page/3-acc":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4d43abad"}],"tag":"d6a3d698","listMetadata":"4b2fba3e"},"/tags/inno-db-2aa":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"9bad5ae7"}],"tag":"49b8d9dd","listMetadata":"a9221bd5"},"/tags/intelli-j-aaa":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"52106a5f"}],"tag":"fe8cce0a","listMetadata":"db7928b3"},"/tags/isolation-bab":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"73688d5c"}],"tag":"c3ea66fe","listMetadata":"d2935d14"},"/tags/java-60d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"26dc40bf"}],"tag":"274c9143","listMetadata":"fe273484"},"/tags/java/page/2-d9f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dfc7013c"}],"tag":"1893cb59","listMetadata":"54150be7"},"/tags/java/page/3-d2c":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6b54f6a4"}],"tag":"8e498bb6","listMetadata":"198f8d8a"},"/tags/java/page/4-c97":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1f61820a"}],"tag":"a3dddb77","listMetadata":"08726fcf"},"/tags/java/page/5-6c7":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"537817cb"}],"tag":"e2de2dbb","listMetadata":"35b2eb5a"},"/tags/jdbc-667":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"6b54f6a4"}],"tag":"a85e626a","listMetadata":"d40f51e1"},"/tags/jenkins-590":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"aacfeabc"}],"tag":"3b0f99e8","listMetadata":"0281109c"},"/tags/kotlin-b84":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1f05d14a"}],"tag":"633582b9","listMetadata":"9fae68e2"},"/tags/lock-059":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"9bad5ae7"}],"tag":"6a19354d","listMetadata":"5eed1665"},"/tags/lock/page/2-2e3":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"db86613e"}],"tag":"9ca52986","listMetadata":"492a6565"},"/tags/log-0ae":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f25de701"}],"tag":"19f4ae8e","listMetadata":"5088fe06"},"/tags/mock-9dd":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"bb221eab"}],"tag":"1d81daa1","listMetadata":"c6004f62"},"/tags/mockito-3de":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8ad2f007"}],"tag":"3b18521e","listMetadata":"2b479afe"},"/tags/monitoring-775":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f25de701"}],"tag":"3d6c40c1","listMetadata":"1fbde614"},"/tags/my-sql-214":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"db86613e"}],"tag":"e0e4666e","listMetadata":"bf933b37"},"/tags/mysql-79d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"92ade856"}],"tag":"280572f1","listMetadata":"75f50328"},"/tags/oop-613":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e6a6ed43"}],"tag":"9d8ee3a8","listMetadata":"d202e2c5"},"/tags/pattern-5e4":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"d5bb232a"}],"tag":"2d9296e4","listMetadata":"e9ff60ad"},"/tags/performance-test-d3e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"70834889"}],"tag":"546ec22f","listMetadata":"56e576e5"},"/tags/python-7fe":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a59d28a9"}],"tag":"c7015929","listMetadata":"f580a9d0"},"/tags/replication-77b":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"92ade856"}],"tag":"b301b20b","listMetadata":"c92f81ac"},"/tags/retrospective-b64":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"530ffa4f"}],"tag":"8c6c0796","listMetadata":"a4a1e915"},"/tags/retrospective/page/10-ba6":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1781b1c4"}],"tag":"bbc01ba0","listMetadata":"9dc4119a"},"/tags/retrospective/page/11-c54":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ad3b7b62"}],"tag":"e073eb07","listMetadata":"7405ea58"},"/tags/retrospective/page/12-443":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"21294bbb"}],"tag":"3c5aea38","listMetadata":"e0d68441"},"/tags/retrospective/page/13-b71":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e1735da7"}],"tag":"d88bdb28","listMetadata":"e9624b4f"},"/tags/retrospective/page/14-e01":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"eff1d58f"}],"tag":"7fd9a574","listMetadata":"21e890b0"},"/tags/retrospective/page/15-64b":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a8cba70f"}],"tag":"16cc6f3a","listMetadata":"b5f3dcc5"},"/tags/retrospective/page/16-703":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1251d98b"}],"tag":"49f0f498","listMetadata":"77f5fc5d"},"/tags/retrospective/page/17-2d8":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4485017c"}],"tag":"1a3abee6","listMetadata":"d60e2b0c"},"/tags/retrospective/page/18-1fd":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"df147deb"}],"tag":"02ede3c9","listMetadata":"fb48356a"},"/tags/retrospective/page/19-d19":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"b6ffb0cb"}],"tag":"0c390f0d","listMetadata":"15f27552"},"/tags/retrospective/page/2-8bf":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5c07bdab"}],"tag":"abc83b7f","listMetadata":"533bfc57"},"/tags/retrospective/page/20-f75":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8a27aeff"}],"tag":"1398b403","listMetadata":"5feaaaeb"},"/tags/retrospective/page/3-998":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5d4cff52"}],"tag":"bd2d06b5","listMetadata":"2b22d492"},"/tags/retrospective/page/4-23f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"905ecccc"}],"tag":"303c1e60","listMetadata":"d126aabd"},"/tags/retrospective/page/5-b0c":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"0e33a907"}],"tag":"ee92877e","listMetadata":"43a97218"},"/tags/retrospective/page/6-58e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"79a97f4e"}],"tag":"e8d6e7ce","listMetadata":"6bc709ad"},"/tags/retrospective/page/7-133":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dca6a1e3"}],"tag":"a0410ab5","listMetadata":"564337ec"},"/tags/retrospective/page/8-c6e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"08e37dbc"}],"tag":"e21c8cc4","listMetadata":"05b907fc"},"/tags/retrospective/page/9-a37":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"48faf148"}],"tag":"8b79a48d","listMetadata":"7e59392d"},"/tags/spring-ab2":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"26dc40bf"}],"tag":"3ed04b60","listMetadata":"7fbacf84"},"/tags/spring-boot-eb7":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"26dc40bf"}],"tag":"087c46fa","listMetadata":"41b4728f"},"/tags/static-dd5":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"8ad2f007"}],"tag":"269a2f75","listMetadata":"70a12cc4"},"/tags/teco-chat-7a9":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"48faf148"}],"tag":"af81a133","listMetadata":"f042b56c"},"/tags/teco-chat/page/2-fbf":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"e1735da7"}],"tag":"c60ea0ff","listMetadata":"d5dfecc2"},"/tags/teco-chat/page/3-c3d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"eff1d58f"}],"tag":"1a6b9123","listMetadata":"d09f7e4b"},"/tags/test-84f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ae82353f"}],"tag":"2a8faff0","listMetadata":"1a665c6f"},"/tags/test/page/2-3a8":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"bb221eab"}],"tag":"d350f5d9","listMetadata":"6ba49b42"},"/tags/time-f3d":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"537817cb"}],"tag":"f156dfb9","listMetadata":"fd5d2408"},"/tags/transaction-622":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"73688d5c"}],"tag":"d0840b01","listMetadata":"c037d168"},"/tags/web-application-4a3":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1664646a"}],"tag":"3680bd07","listMetadata":"8e9dc6b3"},"/tags/web-socket-e59":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"f87bdf62"}],"tag":"489347ff","listMetadata":"3972c49f"},"/tags/woowahan-techcourse-77a":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"530ffa4f"}],"tag":"39ee6679","listMetadata":"5a29fbab"},"/tags/woowahan-techcourse/page/10-156":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"ad3b7b62"}],"tag":"5c38e66e","listMetadata":"21d253a0"},"/tags/woowahan-techcourse/page/11-703":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"21294bbb"}],"tag":"d2770bf7","listMetadata":"64f377d6"},"/tags/woowahan-techcourse/page/12-38f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"a8cba70f"}],"tag":"f7b9d2f4","listMetadata":"6412e40a"},"/tags/woowahan-techcourse/page/13-ddd":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1251d98b"}],"tag":"ee1dd2ad","listMetadata":"bbc3f62a"},"/tags/woowahan-techcourse/page/14-65c":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"4485017c"}],"tag":"c6b037a5","listMetadata":"fb861301"},"/tags/woowahan-techcourse/page/15-a2e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"df147deb"}],"tag":"a4349a81","listMetadata":"3c9c1743"},"/tags/woowahan-techcourse/page/16-53e":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"b6ffb0cb"}],"tag":"a539c018","listMetadata":"a9c2b81a"},"/tags/woowahan-techcourse/page/2-047":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5c07bdab"}],"tag":"86b4da3d","listMetadata":"e7d2a655"},"/tags/woowahan-techcourse/page/3-d3f":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"5d4cff52"}],"tag":"dab4c683","listMetadata":"ac23d7ee"},"/tags/woowahan-techcourse/page/4-5b6":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"905ecccc"}],"tag":"8da65e83","listMetadata":"6425a984"},"/tags/woowahan-techcourse/page/5-135":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"0e33a907"}],"tag":"fed8bc04","listMetadata":"bbceb8f1"},"/tags/woowahan-techcourse/page/6-5e8":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"79a97f4e"}],"tag":"a896be03","listMetadata":"f078e301"},"/tags/woowahan-techcourse/page/7-a11":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"dca6a1e3"}],"tag":"f63a747b","listMetadata":"abb0816f"},"/tags/woowahan-techcourse/page/8-a7b":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"08e37dbc"}],"tag":"672a376b","listMetadata":"ddf9e0bd"},"/tags/woowahan-techcourse/page/9-be6":{"__comp":"6875c492","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"1781b1c4"}],"tag":"43fcf0e9","listMetadata":"7c660760"},"/tecochat-retrospective-1-ed9":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"d8775059"},"/tecochat-retrospective-2-fc4":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"454a6d0d"},"/tecochat-retrospective-3-6f4":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"bbdd7e52"},"/test-double-8ea":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"24b9bc70"},"/the-essence-of-object-orientation-9a2":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"f90d0c52"},"/tomcat-retrospective-5a3":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"a710d533"},"/transaction-and-isolation-d60":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"bd4db8ee"},"/web-application-evolution-c55":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"ac3fdf5d"},"/web-racing-car-retrospective-ccb":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"72657f57"},"/websocket-5c1":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"e1a06456"},"/woowacourse-level1-retrospective-a6a":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"a3614f73"},"/woowacourse-level2-retrospective-758":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"9d1fd2b0"},"/woowacourse-level3-retrospective-4e5":{"__comp":"ccc49370","__context":{"plugin":"509d519c"},"sidebar":"814f3328","content":"4a1c8300"},"/docs-cf0":{"__comp":"5e95c892","__context":{"plugin":"dcf70953"}},"/docs-d75":{"__comp":"a7bd4aaa","version":"935f2afb"},"/docs/tags-0cc":{"__comp":"3720c009","tags":"55960ee5"},"/docs/tags/architecture-44b":{"__comp":"df203c0f","tag":"f6807fb4"},"/docs/tags/book-977":{"__comp":"df203c0f","tag":"f4c6e7e6"},"/docs/tags/collection-0f6":{"__comp":"df203c0f","tag":"2c446262"},"/docs/tags/deploy-001":{"__comp":"df203c0f","tag":"e5e44a85"},"/docs/tags/etc-dd7":{"__comp":"df203c0f","tag":"c189d18f"},"/docs/tags/java-bac":{"__comp":"df203c0f","tag":"3b12d42b"},"/docs/tags/jpa-831":{"__comp":"df203c0f","tag":"5ffd2c10"},"/docs/tags/latency-a14":{"__comp":"df203c0f","tag":"b36d2d1d"},"/docs/tags/load-balancing-5bb":{"__comp":"df203c0f","tag":"38bf29ad"},"/docs/tags/monitoring-652":{"__comp":"df203c0f","tag":"1c93669b"},"/docs/tags/network-5ba":{"__comp":"df203c0f","tag":"6c674d03"},"/docs/tags/nginx-379":{"__comp":"df203c0f","tag":"c60995f6"},"/docs/tags/package-dec":{"__comp":"df203c0f","tag":"211d6170"},"/docs/tags/performance-364":{"__comp":"df203c0f","tag":"9e4ad429"},"/docs/tags/postmortem-cb8":{"__comp":"df203c0f","tag":"7e4c1ed7"},"/docs/tags/sequenced-fc4":{"__comp":"df203c0f","tag":"6c38e270"},"/docs/tags/spring-219":{"__comp":"df203c0f","tag":"a7e0d18f"},"/docs/tags/test-df6":{"__comp":"df203c0f","tag":"9bbc65ac"},"/docs/tags/throughput-760":{"__comp":"df203c0f","tag":"c08e7a0d"},"/docs/tags/zero-downtime-9c1":{"__comp":"df203c0f","tag":"4430ab79"},"/docs-02e":{"__comp":"a94703ab"},"/docs-818":{"__comp":"17896441","content":"f8409a7e"},"/docs/architecture/virtical-slice-architecture-825":{"__comp":"17896441","content":"eae2a611"},"/docs/book/getting-out-of-the-box-8e1":{"__comp":"17896441","content":"f3493919"},"/docs/culture/postmortem-420":{"__comp":"17896441","content":"cec43d6a"},"/docs/database/maximumPoolSize-9ab":{"__comp":"17896441","content":"aa73a035"},"/docs/database/query-execution-7b8":{"__comp":"17896441","content":"bd64a762"},"/docs/deploy/zero-downtime-20f":{"__comp":"17896441","content":"d6638f30"},"/docs/design/package-274":{"__comp":"17896441","content":"981f7647"},"/docs/etc/communication-9c1":{"__comp":"17896441","content":"04644f5f"},"/docs/etc/develop-with-spring-9ab":{"__comp":"17896441","content":"366ddb85"},"/docs/etc/experience-and-self-question-d25":{"__comp":"17896441","content":"d8cdf5ef"},"/docs/etc/healthful-growth-fcf":{"__comp":"17896441","content":"6b4e1191"},"/docs/java/sequenced-collection-bda":{"__comp":"17896441","content":"290b0a56"},"/docs/jpa/key-68b":{"__comp":"17896441","content":"6b69808d"},"/docs/linux/shell-c5b":{"__comp":"17896441","content":"051528db"},"/docs/linux/swap-9d5":{"__comp":"17896441","content":"e6e259a5"},"/docs/mac/java-5a9":{"__comp":"17896441","content":"d1e1bea4"},"/docs/monitoring/intro-5db":{"__comp":"17896441","content":"9c6e5a12"},"/docs/network/load-balancing-caa":{"__comp":"17896441","content":"caf1b628"},"/docs/network/load-balancing-algorithm-a4d":{"__comp":"17896441","content":"b88cb85b"},"/docs/nginx/command-0e3":{"__comp":"17896441","content":"c55d205b"},"/docs/nginx/static-file-629":{"__comp":"17896441","content":"d86f7a37"},"/docs/performance/throughput-56a":{"__comp":"17896441","content":"d361ad2d"},"/docs/performance/throughput-latency-12a":{"__comp":"17896441","content":"b421ebb7"},"/docs/performance/types-c08":{"__comp":"17896441","content":"87070fc3"},"/docs/spring/essence-4c6":{"__comp":"17896441","content":"da14f319"},"/docs/test/benefit-6c8":{"__comp":"17896441","content":"41c44b28"},"/docs/test/first-566":{"__comp":"17896441","content":"302370be"},"/docs/test/heuristics-b35":{"__comp":"17896441","content":"451db21d"},"/docs/test/stairstep-a57":{"__comp":"17896441","content":"a14ec7b5"},"/-3ce":{"__comp":"c4f5d8e4","__context":{"plugin":"ae3384b2"},"config":"5e9f5e1a"},"/-956":{"__comp":"a6aa9e1f","__context":{"plugin":"509d519c"},"sidebar":"814f3328","items":[{"content":"530ffa4f"}],"metadata":"a5557bb9"}}')}},e=>{e.O(0,[532],(()=>{return t=97221,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/main.8092b600.js.LICENSE.txt b/assets/js/main.eea870a2.js.LICENSE.txt similarity index 76% rename from assets/js/main.8092b600.js.LICENSE.txt rename to assets/js/main.eea870a2.js.LICENSE.txt index eb75d6910..91dc89499 100644 --- a/assets/js/main.8092b600.js.LICENSE.txt +++ b/assets/js/main.eea870a2.js.LICENSE.txt @@ -1,15 +1,22 @@ -/* -object-assign -(c) Sindre Sorhus -@license MIT -*/ - /* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress * @license MIT */ +/*! Bundled license information: + +prismjs/prism.js: + (** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + *) +*/ + /** * @license React - * use-sync-external-store-shim.production.min.js + * react-dom.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * @@ -18,16 +25,8 @@ object-assign */ /** - * Prism: Lightweight, robust, elegant syntax highlighting - * - * @license MIT <https://opensource.org/licenses/MIT> - * @author Lea Verou <https://lea.verou.me> - * @namespace - * @public - */ - -/** @license React v0.20.2 - * scheduler.production.min.js + * @license React + * react-jsx-runtime.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * @@ -35,8 +34,9 @@ object-assign * LICENSE file in the root directory of this source tree. */ -/** @license React v16.13.1 - * react-is.production.min.js +/** + * @license React + * react.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * @@ -44,8 +44,9 @@ object-assign * LICENSE file in the root directory of this source tree. */ -/** @license React v17.0.2 - * react-dom.production.min.js +/** + * @license React + * scheduler.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * @@ -53,8 +54,8 @@ object-assign * LICENSE file in the root directory of this source tree. */ -/** @license React v17.0.2 - * react.production.min.js +/** @license React v16.13.1 + * react-is.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * diff --git a/assets/js/runtime~main.32d2bfa9.js b/assets/js/runtime~main.32d2bfa9.js new file mode 100644 index 000000000..437946ef4 --- /dev/null +++ b/assets/js/runtime~main.32d2bfa9.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,b,a,f,d,c={},t={};function r(e){var b=t[e];if(void 0!==b)return b.exports;var a=t[e]={exports:{}};return c[e].call(a.exports,a,a.exports,r),a.exports}r.m=c,e=[],r.O=(b,a,f,d)=>{if(!a){var c=1/0;for(i=0;i<e.length;i++){a=e[i][0],f=e[i][1],d=e[i][2];for(var t=!0,o=0;o<a.length;o++)(!1&d||c>=d)&&Object.keys(r.O).every((e=>r.O[e](a[o])))?a.splice(o--,1):(t=!1,d<c&&(c=d));if(t){e.splice(i--,1);var n=f();void 0!==n&&(b=n)}}return b}d=d||0;for(var i=e.length;i>0&&e[i-1][2]>d;i--)e[i]=e[i-1];e[i]=[a,f,d]},r.n=e=>{var b=e&&e.__esModule?()=>e.default:()=>e;return r.d(b,{a:b}),b},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var d=Object.create(null);r.r(d);var c={};b=b||[null,a({}),a([]),a(a)];for(var t=2&f&&e;"object"==typeof t&&!~b.indexOf(t);t=a(t))Object.getOwnPropertyNames(t).forEach((b=>c[b]=()=>e[b]));return c.default=()=>e,r.d(d,c),d},r.d=(e,b)=>{for(var a in b)r.o(b,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:b[a]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((b,a)=>(r.f[a](e,b),b)),[])),r.u=e=>"assets/js/"+({26:"ad3b7b62",31:"f4c6e7e6",53:"935f2afb",71:"8a27aeff",80:"5088fe06",96:"087c46fa",100:"d50fd269",116:"0cb009d1",172:"96adae60",240:"4959fc42",286:"1893cb59",297:"9fae68e2",300:"92fef07b",321:"0c071de2",324:"280572f1",328:"4b2fba3e",372:"35b2eb5a",422:"0281109c",425:"16cc6f3a",448:"28a1570f",454:"1a665c6f",470:"8720c147",471:"38d8699e",475:"a3dddb77",498:"6ba49b42",533:"b2b675dd",548:"32397cb2",573:"b474adfe",588:"d7955594",628:"e0d68441",653:"bbceb8f1",656:"1f05d14a",693:"6a19354d",711:"bb221eab",724:"f01ceada",732:"64f377d6",734:"05b907fc",741:"8a24850b",743:"509d519c",820:"ff4c6c5e",838:"6b4e1191",843:"d2770bf7",846:"d0277431",916:"fa3d3942",917:"6552f31f",952:"86b4da3d",955:"fe8cce0a",964:"c573638f",970:"32b2299c",988:"754fb852",1065:"69c28c32",1079:"15f27552",1103:"49b8d9dd",1112:"e9eabc5d",1113:"0746167d",1196:"2d3b202f",1213:"b2c8756c",1252:"5d4cff52",1253:"e5e44a85",1255:"6675e9ab",1257:"b36d2d1d",1285:"38bf29ad",1328:"08e37dbc",1358:"cec43d6a",1391:"b41adc00",1434:"dfa84138",1436:"8e498bb6",1475:"451db21d",1501:"64868a43",1611:"e1735da7",1653:"7e4c1ed7",1659:"daff1d93",1675:"d126aabd",1677:"d5dfecc2",1711:"a710d533",1761:"dcf70953",1762:"2bfe7c0b",1772:"92ade856",1793:"309173fa",1853:"21d253a0",1883:"302370be",1906:"4485017c",1926:"f078e301",1994:"269a2f75",2012:"a59d28a9",2087:"7c660760",2098:"d350f5d9",2100:"5ffd2c10",2145:"9c6e5a12",2153:"9bad5ae7",2156:"b6ffb0cb",2181:"ae1d6508",2215:"abc83b7f",2233:"1f61820a",2245:"f25de701",2247:"d361ad2d",2261:"a8cba70f",2266:"a9c2b81a",2293:"b88cb85b",2334:"7af1d52f",2345:"7405ea58",2362:"bace0b37",2448:"633582b9",2476:"2832e534",2526:"a896be03",2530:"e9ff60ad",2535:"814f3328",2542:"ddf9e0bd",2579:"672a376b",2620:"f06cb3e2",2625:"04644f5f",2656:"303c1e60",2717:"f332d221",2742:"33736670",2753:"7762a24e",2773:"3b18521e",2793:"489347ff",2816:"8c6c0796",2889:"7fd9a574",2890:"d6a3d698",2939:"905ecccc",2947:"981f7647",2958:"f7b9d2f4",2965:"ae3384b2",2967:"5feaaaeb",3009:"bbc01ba0",3085:"c60ea0ff",3089:"a6aa9e1f",3092:"0e33a907",3095:"bf933b37",3098:"d09f7e4b",3109:"211d6170",3122:"6d4355d3",3137:"c6b037a5",3206:"f8409a7e",3213:"ac23d7ee",3239:"dca6a1e3",3259:"d2935d14",3287:"7159c7ff",3324:"4a1c8300",3333:"1e8ecffe",3365:"4d43abad",3392:"d86f7a37",3396:"bbdd7e52",3407:"327fa616",3438:"c55d205b",3457:"537817cb",3476:"d6638f30",3483:"2d9296e4",3490:"9ca52986",3519:"a7e0d18f",3530:"20e99c2a",3553:"3b0f99e8",3608:"9e4087bc",3614:"fd5d2408",3625:"77f5fc5d",3637:"b301b20b",3651:"d5bb232a",3671:"a4a1e915",3673:"9f586ca3",3691:"366ddb85",3751:"3720c009",3771:"e6e259a5",3833:"a14ec7b5",3912:"e8d6e7ce",4013:"01a85c17",4091:"b2ebb6fd",4104:"454a6d0d",4121:"55960ee5",4137:"eff1d58f",4149:"8d05b77c",4174:"abb0816f",4185:"c7015929",4195:"c4f5d8e4",4209:"15eddcef",4212:"290b0a56",4275:"04c55e47",4311:"7bbc420e",4368:"a94703ab",4393:"c92f81ac",4433:"49f0f498",4471:"494882d1",4558:"6b54f6a4",4564:"e9624b4f",4665:"e0e4666e",4722:"53e4509a",4788:"f6807fb4",4801:"8d7288fe",4815:"43a97218",4818:"530ffa4f",4889:"5f81b25c",4934:"02ede3c9",4953:"eec33099",4962:"c189d18f",5035:"1a3abee6",5046:"db7928b3",5088:"54150be7",5100:"533bfc57",5103:"df147deb",5131:"f63a747b",5173:"3680bd07",5186:"3f6ea930",5237:"26dc40bf",5294:"f90d0c52",5300:"e6a6ed43",5319:"6cfe3a99",5323:"cc519f63",5335:"75121fd5",5371:"aa73a035",5406:"9e4ad429",5421:"6412e40a",5435:"ee1dd2ad",5436:"c6d04683",5463:"bd64a762",5465:"d0e4cdf1",5467:"6425a984",5485:"da14f319",5487:"08726fcf",5507:"a9221bd5",5521:"5c38e66e",5553:"4430ab79",5602:"f156dfb9",5635:"546ec22f",5649:"564337ec",5652:"1398b403",5669:"00931cc3",5682:"70a12cc4",5717:"39ee6679",5753:"051528db",5758:"a539c018",5785:"1781b1c4",5797:"7fbacf84",5798:"24b9bc70",5819:"e073eb07",5838:"4b79a3c9",5857:"dfc7013c",5870:"cf8e491a",5873:"8fbd512b",5892:"c6004f62",5900:"3c9c1743",5919:"d8cdf5ef",5953:"5a6c6934",5962:"9d8ee3a8",5964:"09fbb6bd",5966:"871c1e5a",5990:"6b69808d",5991:"a5557bb9",6017:"6093f82b",6035:"226700de",6049:"e21c8cc4",6058:"dab4c683",6084:"101b58de",6103:"ccc49370",6123:"f3e308ad",6124:"87070fc3",6161:"562496aa",6172:"be497a8d",6180:"eae2a611",6199:"c60995f6",6204:"0571a526",6250:"3c5aea38",6276:"1251d98b",6300:"5c07bdab",6346:"02689328",6387:"d8775059",6412:"79a97f4e",6420:"ae82353f",6468:"43fcf0e9",6490:"9dc4119a",6493:"130df38c",6508:"12cbeba7",6515:"1236fad7",6526:"1c93669b",6550:"0c390f0d",6587:"c037d168",6608:"6f385a52",6629:"3972c49f",6671:"d28e30d7",6698:"c3ea66fe",6710:"e2de2dbb",6743:"2f43e44a",6750:"f87bdf62",6837:"fbd57548",6883:"bd4db8ee",6887:"f4f49e13",6908:"73688d5c",6984:"274c9143",7009:"54cb095e",7064:"6dd1c948",7108:"7881a85f",7153:"b7d33121",7157:"3ed04b60",7175:"d202e2c5",7181:"69a75ff2",7204:"cb6229c3",7210:"9bbc65ac",7230:"caf1b628",7247:"6c38e270",7268:"14164549",7281:"7e59392d",7328:"48faf148",7344:"70834889",7400:"ffb0fa11",7403:"14dc1923",7404:"c08e7a0d",7412:"70275fcd",7474:"df862072",7476:"66d1c769",7511:"75f50328",7563:"fb861301",7581:"2e10a69c",7599:"80960b4b",7600:"6c674d03",7617:"9e2e3982",7648:"a1877440",7652:"2b22d492",7680:"448c20a0",7681:"1d81daa1",7688:"b9bcab37",7697:"35293ec4",7709:"8e9dc6b3",7723:"b5f3dcc5",7725:"9cfe8fd1",7727:"3dd4d232",7740:"f0978ee1",7775:"2c9f5501",7776:"d65e25b7",7787:"af81a133",7797:"2c446262",7843:"a0410ab5",7857:"5a29fbab",7891:"635a92d5",7901:"2a8faff0",7918:"17896441",7920:"1a4e3797",7945:"d1e1bea4",7954:"d368e73e",7966:"c0cb7215",7972:"9d1fd2b0",7975:"270346fa",8036:"1664646a",8037:"d0840b01",8106:"41c44b28",8107:"3b12d42b",8110:"fed8bc04",8142:"5eed1665",8151:"255134d9",8161:"19f4ae8e",8174:"d60e2b0c",8243:"1fbde614",8262:"56e576e5",8288:"21e890b0",8338:"8dc09bac",8355:"fe273484",8360:"8ad2f007",8474:"a3614f73",8476:"f3493919",8509:"3d6c40c1",8518:"a7bd4aaa",8524:"9dec6b67",8548:"ac3fdf5d",8561:"d2611248",8610:"6875c492",8628:"41b4728f",8644:"cef46b76",8652:"e7d2a655",8683:"cd68cda1",8716:"ee92877e",8817:"cc3bdf2f",8882:"f75a8651",8894:"bbc3f62a",8909:"aacfeabc",8919:"f042b56c",8927:"c1b17b3f",8942:"0a2eaa84",9055:"b421ebb7",9059:"198f8d8a",9092:"a85e626a",9111:"372ccfe9",9171:"18c69d70",9239:"101cf32b",9242:"c29bedb9",9286:"9b43eac8",9287:"8b79a48d",9304:"4515250b",9310:"d1cef389",9312:"42957a8d",9391:"829fa7b9",9393:"6bc709ad",9396:"52106a5f",9412:"21294bbb",9427:"8da65e83",9458:"db86613e",9467:"e2326195",9534:"fb48356a",9538:"9b56b618",9581:"72657f57",9591:"2b479afe",9606:"ef5b2427",9623:"a4349a81",9633:"d40f51e1",9661:"5e95c892",9686:"5a473bed",9702:"492a6565",9713:"1bb997fc",9763:"bd2d06b5",9788:"d88bdb28",9874:"1a6b9123",9875:"16f719ab",9887:"f580a9d0",9910:"e1a06456",9924:"df203c0f",9940:"e4ebfe18"}[e]||e)+"."+{26:"f8707eac",31:"fdbb534a",53:"5b9655c6",71:"2359b403",80:"2cc977cf",96:"8ecf33d3",100:"267c41c3",116:"553227fe",130:"233dcaf1",172:"b8feb030",240:"af9f01e2",286:"7a0eb710",297:"72dfd56d",300:"fcbe78e8",321:"265b47fa",324:"4d349f70",328:"ee7b0442",360:"c968878c",372:"9ac55f69",422:"094422e8",425:"6b184b3b",448:"97a380e8",454:"ad3c5a8e",470:"b6a4b7a3",471:"24ce7018",475:"0be524dd",498:"12fc56b7",533:"adafc1ef",548:"79ba529e",573:"859d75dc",588:"3de2f6cf",628:"b9e1aa8d",653:"45b4a5d1",656:"da3635f1",693:"67483436",711:"15e3f1c0",724:"5272c56b",732:"77b06a2e",734:"e1277f6c",741:"b479905c",743:"caf52cd9",762:"2b229c76",820:"8132bff2",838:"964eb4c1",843:"b1baa87f",846:"0c6e8615",916:"73543988",917:"46a2fccb",952:"ecad1fac",955:"08ba84b5",964:"0c33f138",970:"3f86eab1",988:"1af0a567",1065:"6f23071b",1079:"e9d4d18f",1103:"3c966f04",1112:"fcb4962f",1113:"afac0769",1196:"7ed7c756",1213:"4aff2828",1252:"e443e998",1253:"f463dc37",1255:"aea6d3a6",1257:"df006be2",1285:"bf7f6732",1328:"83c072d2",1358:"0cb02c7e",1391:"633c89b0",1426:"d71a045b",1434:"4493a1cc",1436:"ad307809",1475:"8bc6a551",1501:"b31f6d0d",1611:"7747f2b7",1644:"29f069a4",1653:"3a8a4e55",1659:"268aa82a",1675:"69a06b4a",1677:"ea44f851",1688:"375d0e2c",1711:"89036d73",1761:"d0be48ac",1762:"2258198c",1772:"9c969003",1793:"f6e5e77a",1853:"c36050f0",1883:"5f8295a8",1906:"9559a624",1926:"5f6afbe2",1994:"3f56a8b3",2012:"aacad7b2",2027:"ab074e16",2087:"e38d4441",2090:"4df4088d",2098:"668ec20f",2100:"6cc0bd94",2127:"52913f0e",2145:"76e4be75",2153:"fa0f41bc",2156:"4afb0eea",2181:"f635198e",2215:"a6c12174",2233:"d2fe9ecf",2244:"3fbf946f",2245:"7bd01fad",2247:"edd5acc2",2261:"18be7e46",2266:"560a866f",2293:"19706a2f",2334:"d4c7e602",2345:"4efb653a",2362:"f928003e",2448:"6d800cdf",2476:"1096ee60",2526:"8424c86d",2530:"6425d7c1",2535:"2e60c17f",2542:"b3d7aff1",2579:"38ceaf22",2620:"536ef825",2625:"0a8f1a82",2656:"650df522",2717:"12aef286",2742:"729098c7",2753:"1551d3ca",2773:"28bc0b58",2793:"8a3de8e4",2816:"7c634fd6",2889:"7929f04e",2890:"a57e5d29",2939:"aeeb3c76",2947:"86256e1a",2958:"b710b8ae",2965:"95cb14ea",2967:"4b1e42eb",3009:"cdcbe419",3085:"f14cacef",3089:"4dfe399a",3092:"8661cb3c",3095:"56ca3009",3098:"eacc75cd",3109:"ccc60dec",3122:"bb82b9e2",3137:"3ee85e02",3206:"dfd38fb7",3213:"9149127e",3239:"52680b40",3259:"fe55055e",3287:"9f77b884",3324:"cdb79bf0",3333:"de94e202",3365:"3e067cc0",3392:"ca7f1316",3396:"3be218d1",3407:"f584e7ce",3438:"aa5a86ab",3457:"65f6a412",3476:"a35df1f5",3483:"d46cb8ea",3490:"3fac83b3",3506:"191c4e89",3519:"ae8780eb",3530:"90a43ac9",3553:"a35b4fd0",3601:"e229da18",3608:"d7673a23",3614:"f64b5f70",3625:"2ccaf719",3637:"b1bb1de7",3651:"61c24a0e",3671:"b7b0c0db",3673:"0edad504",3691:"a5ba09fa",3751:"e6613bd8",3771:"f5d4fe6a",3833:"0ab78cf6",3912:"9dce5fc8",4013:"1cd64a05",4091:"301d7a2d",4104:"64dcde7c",4121:"cf44ccd7",4137:"886bd191",4149:"f9f54172",4174:"b0d0aba5",4185:"2bf7c111",4195:"325cecb9",4209:"c113f5f0",4212:"a6af2777",4275:"442e9eb3",4311:"de2e8ae6",4368:"783432bf",4393:"e9e6baff",4433:"452bd2f4",4471:"ab916c9a",4558:"2c404bfc",4564:"522d48a7",4665:"cc580050",4697:"d30ed957",4722:"2d116db6",4788:"f409010b",4801:"5f0bac2d",4815:"8e3134d2",4818:"2cf34794",4889:"3a028eac",4926:"50b7d3b0",4934:"f2b1b1a0",4953:"645a57bb",4962:"b76768cd",5035:"b1ea2356",5046:"2a9c0fe1",5088:"a4cc9618",5100:"91265c60",5103:"ff087a25",5131:"276c7afe",5173:"43261a11",5186:"c12b117e",5237:"bd9e249d",5254:"19cc10bc",5294:"7f1a329c",5300:"a7a88c94",5319:"f51506e7",5323:"46c3d20e",5335:"ed266578",5371:"e69b92cb",5373:"41b31afd",5406:"a307a08a",5421:"1ab52c78",5435:"8c78f348",5436:"2f21610f",5463:"c0b05caa",5465:"10c574a5",5467:"576248f5",5485:"cc63b465",5487:"b0eaf3bf",5507:"3bfa9f2c",5521:"a18cbc60",5553:"91bf9599",5602:"ffae126d",5635:"826c8fef",5649:"cafb2d42",5652:"f0f9481a",5669:"d9e8855a",5682:"2db653db",5705:"d5718783",5717:"b0b1231d",5753:"96920375",5758:"11f0a959",5785:"511d5aa4",5797:"c4fc60f8",5798:"6793a550",5819:"2ce17648",5838:"c3ac845d",5857:"f3d89c0c",5870:"464ac15a",5873:"4d36cc4b",5892:"8257704e",5900:"139a7956",5919:"23e4a2d1",5953:"7bd0504f",5962:"22bab478",5964:"f3f0267e",5966:"a006189f",5990:"cfb22962",5991:"4377935f",6017:"2b0798f4",6035:"e0a4b7fd",6046:"93fe74ca",6049:"0c8d5bd8",6058:"29c4f1c4",6084:"2b9af44d",6103:"e0a78056",6123:"6ab15074",6124:"407d5246",6161:"6fbd6e7b",6172:"ef83736d",6180:"e9e2c2a6",6199:"6ea62df7",6204:"3199c893",6250:"34c3a378",6254:"febe09ff",6276:"8c5715bc",6278:"5c15eabc",6284:"f0331339",6300:"54ff7247",6346:"7a7f957d",6387:"f37a361d",6412:"6cfb3091",6420:"77430c26",6468:"37211ee7",6490:"f875b280",6493:"c25a1b6d",6508:"fc8c85de",6515:"e7249cac",6526:"857fc62a",6550:"a2395ac7",6587:"96f06126",6608:"b5af1364",6629:"411ee9ac",6671:"489aca7d",6698:"4afcd78f",6710:"441ed42b",6715:"cd1e4516",6743:"31f6617e",6750:"b1ec672d",6837:"164d143c",6883:"65f63b9c",6887:"79baf298",6908:"50416e9c",6945:"52e6a492",6984:"5b1f6476",7009:"bb1a2368",7064:"56a5cee5",7108:"5df241ab",7111:"8f25c1dd",7153:"74e8d043",7157:"6fb6f83d",7175:"1343f229",7181:"2e16faab",7204:"5653afa0",7210:"c162c71c",7230:"7ea0263c",7247:"5142239c",7268:"7a0bdef8",7281:"c1fbf51f",7328:"251b0554",7344:"15e53e1e",7400:"e327857d",7403:"1aa6fe97",7404:"9cff8a1c",7412:"1113713e",7474:"8d335144",7476:"0554fad1",7511:"0959afe8",7563:"4cca033a",7581:"d6202677",7599:"23d0b12a",7600:"32ba75ec",7617:"6ece4d4c",7648:"88e9cb51",7652:"deba5021",7680:"1a72b6ca",7681:"3c02c51a",7688:"341c6751",7697:"1448bfa5",7707:"6b080055",7709:"cb50d73f",7723:"8adc35cf",7725:"4bd5caa7",7727:"a5b347e4",7740:"a0902758",7775:"313f53d8",7776:"04063c18",7787:"cb0b4019",7797:"5e6afa9d",7807:"b82574b2",7843:"c3ca4fe1",7856:"26f0b80c",7857:"24f29dd6",7891:"a1e1a506",7901:"bab1919e",7918:"d0d75e41",7920:"3cfcc719",7945:"5c79d869",7954:"9d264eba",7966:"c03bc365",7972:"80d4a2ec",7975:"a5c01a12",8036:"eba2ca7c",8037:"30f98a8b",8106:"32755fc9",8107:"95f13260",8110:"4f833fe3",8142:"92b60a91",8151:"820e0db5",8161:"54b6b5f0",8174:"cbd24ef7",8189:"25b38ba5",8243:"de74c976",8262:"c2861079",8288:"a0551afe",8338:"44e33d7b",8355:"6eaec45f",8360:"9b356e06",8365:"83cd436c",8371:"9ec33232",8474:"63484f4e",8476:"36beefc1",8509:"145654ac",8518:"d10943b8",8524:"ce191000",8548:"9c827f3a",8561:"4a8223bd",8610:"e8e0a40f",8628:"0a266023",8644:"69423224",8652:"c38576aa",8683:"c2b122c5",8687:"c0c746b9",8716:"be8e94b0",8817:"b73cfef6",8882:"9dc7565f",8894:"db081e7b",8909:"8863a050",8919:"2fd3c78c",8927:"e63c57c6",8942:"93ab101b",9055:"fe44063d",9059:"246f1a7e",9092:"4cd274c5",9111:"2d5d0a9f",9171:"7e0e9cbb",9205:"d00839b7",9239:"0067bead",9242:"2e2eddf5",9286:"90a09cb8",9287:"84d2f0c6",9304:"7c65c757",9310:"0505ff33",9312:"205e0091",9391:"c29a2b79",9393:"9758e816",9396:"17a5eda6",9412:"58721559",9427:"b9934882",9458:"2f8f2d5c",9467:"c1345a1c",9469:"e32b0c9d",9534:"bee2d2d9",9538:"5822f5e9",9581:"cd507c93",9591:"31ea2b46",9606:"7a1f7236",9623:"dc01ce87",9633:"14bda7cc",9661:"3b35697a",9686:"c534c8ad",9702:"1392e115",9713:"96d5e1f3",9763:"f610658d",9788:"d72f94d3",9816:"71ee2fb3",9874:"f05b7812",9875:"0a2e8f52",9887:"ff66fa3d",9910:"e625e406",9924:"3bef6881",9940:"a435ae27"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,b)=>Object.prototype.hasOwnProperty.call(e,b),f={},d="my-website:",r.l=(e,b,a,c)=>{if(f[e])f[e].push(b);else{var t,o;if(void 0!==a)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==d+a){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",d+a),t.src=e),f[e]=[b];var l=(b,a)=>{t.onerror=t.onload=null,clearTimeout(s);var d=f[e];if(delete f[e],t.parentNode&&t.parentNode.removeChild(t),d&&d.forEach((e=>e(a))),b)return b(a)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={14164549:"7268",17896441:"7918",33736670:"2742",70834889:"7344",ad3b7b62:"26",f4c6e7e6:"31","935f2afb":"53","8a27aeff":"71","5088fe06":"80","087c46fa":"96",d50fd269:"100","0cb009d1":"116","96adae60":"172","4959fc42":"240","1893cb59":"286","9fae68e2":"297","92fef07b":"300","0c071de2":"321","280572f1":"324","4b2fba3e":"328","35b2eb5a":"372","0281109c":"422","16cc6f3a":"425","28a1570f":"448","1a665c6f":"454","8720c147":"470","38d8699e":"471",a3dddb77:"475","6ba49b42":"498",b2b675dd:"533","32397cb2":"548",b474adfe:"573",d7955594:"588",e0d68441:"628",bbceb8f1:"653","1f05d14a":"656","6a19354d":"693",bb221eab:"711",f01ceada:"724","64f377d6":"732","05b907fc":"734","8a24850b":"741","509d519c":"743",ff4c6c5e:"820","6b4e1191":"838",d2770bf7:"843",d0277431:"846",fa3d3942:"916","6552f31f":"917","86b4da3d":"952",fe8cce0a:"955",c573638f:"964","32b2299c":"970","754fb852":"988","69c28c32":"1065","15f27552":"1079","49b8d9dd":"1103",e9eabc5d:"1112","0746167d":"1113","2d3b202f":"1196",b2c8756c:"1213","5d4cff52":"1252",e5e44a85:"1253","6675e9ab":"1255",b36d2d1d:"1257","38bf29ad":"1285","08e37dbc":"1328",cec43d6a:"1358",b41adc00:"1391",dfa84138:"1434","8e498bb6":"1436","451db21d":"1475","64868a43":"1501",e1735da7:"1611","7e4c1ed7":"1653",daff1d93:"1659",d126aabd:"1675",d5dfecc2:"1677",a710d533:"1711",dcf70953:"1761","2bfe7c0b":"1762","92ade856":"1772","309173fa":"1793","21d253a0":"1853","302370be":"1883","4485017c":"1906",f078e301:"1926","269a2f75":"1994",a59d28a9:"2012","7c660760":"2087",d350f5d9:"2098","5ffd2c10":"2100","9c6e5a12":"2145","9bad5ae7":"2153",b6ffb0cb:"2156",ae1d6508:"2181",abc83b7f:"2215","1f61820a":"2233",f25de701:"2245",d361ad2d:"2247",a8cba70f:"2261",a9c2b81a:"2266",b88cb85b:"2293","7af1d52f":"2334","7405ea58":"2345",bace0b37:"2362","633582b9":"2448","2832e534":"2476",a896be03:"2526",e9ff60ad:"2530","814f3328":"2535",ddf9e0bd:"2542","672a376b":"2579",f06cb3e2:"2620","04644f5f":"2625","303c1e60":"2656",f332d221:"2717","7762a24e":"2753","3b18521e":"2773","489347ff":"2793","8c6c0796":"2816","7fd9a574":"2889",d6a3d698:"2890","905ecccc":"2939","981f7647":"2947",f7b9d2f4:"2958",ae3384b2:"2965","5feaaaeb":"2967",bbc01ba0:"3009",c60ea0ff:"3085",a6aa9e1f:"3089","0e33a907":"3092",bf933b37:"3095",d09f7e4b:"3098","211d6170":"3109","6d4355d3":"3122",c6b037a5:"3137",f8409a7e:"3206",ac23d7ee:"3213",dca6a1e3:"3239",d2935d14:"3259","7159c7ff":"3287","4a1c8300":"3324","1e8ecffe":"3333","4d43abad":"3365",d86f7a37:"3392",bbdd7e52:"3396","327fa616":"3407",c55d205b:"3438","537817cb":"3457",d6638f30:"3476","2d9296e4":"3483","9ca52986":"3490",a7e0d18f:"3519","20e99c2a":"3530","3b0f99e8":"3553","9e4087bc":"3608",fd5d2408:"3614","77f5fc5d":"3625",b301b20b:"3637",d5bb232a:"3651",a4a1e915:"3671","9f586ca3":"3673","366ddb85":"3691","3720c009":"3751",e6e259a5:"3771",a14ec7b5:"3833",e8d6e7ce:"3912","01a85c17":"4013",b2ebb6fd:"4091","454a6d0d":"4104","55960ee5":"4121",eff1d58f:"4137","8d05b77c":"4149",abb0816f:"4174",c7015929:"4185",c4f5d8e4:"4195","15eddcef":"4209","290b0a56":"4212","04c55e47":"4275","7bbc420e":"4311",a94703ab:"4368",c92f81ac:"4393","49f0f498":"4433","494882d1":"4471","6b54f6a4":"4558",e9624b4f:"4564",e0e4666e:"4665","53e4509a":"4722",f6807fb4:"4788","8d7288fe":"4801","43a97218":"4815","530ffa4f":"4818","5f81b25c":"4889","02ede3c9":"4934",eec33099:"4953",c189d18f:"4962","1a3abee6":"5035",db7928b3:"5046","54150be7":"5088","533bfc57":"5100",df147deb:"5103",f63a747b:"5131","3680bd07":"5173","3f6ea930":"5186","26dc40bf":"5237",f90d0c52:"5294",e6a6ed43:"5300","6cfe3a99":"5319",cc519f63:"5323","75121fd5":"5335",aa73a035:"5371","9e4ad429":"5406","6412e40a":"5421",ee1dd2ad:"5435",c6d04683:"5436",bd64a762:"5463",d0e4cdf1:"5465","6425a984":"5467",da14f319:"5485","08726fcf":"5487",a9221bd5:"5507","5c38e66e":"5521","4430ab79":"5553",f156dfb9:"5602","546ec22f":"5635","564337ec":"5649","1398b403":"5652","00931cc3":"5669","70a12cc4":"5682","39ee6679":"5717","051528db":"5753",a539c018:"5758","1781b1c4":"5785","7fbacf84":"5797","24b9bc70":"5798",e073eb07:"5819","4b79a3c9":"5838",dfc7013c:"5857",cf8e491a:"5870","8fbd512b":"5873",c6004f62:"5892","3c9c1743":"5900",d8cdf5ef:"5919","5a6c6934":"5953","9d8ee3a8":"5962","09fbb6bd":"5964","871c1e5a":"5966","6b69808d":"5990",a5557bb9:"5991","6093f82b":"6017","226700de":"6035",e21c8cc4:"6049",dab4c683:"6058","101b58de":"6084",ccc49370:"6103",f3e308ad:"6123","87070fc3":"6124","562496aa":"6161",be497a8d:"6172",eae2a611:"6180",c60995f6:"6199","0571a526":"6204","3c5aea38":"6250","1251d98b":"6276","5c07bdab":"6300","02689328":"6346",d8775059:"6387","79a97f4e":"6412",ae82353f:"6420","43fcf0e9":"6468","9dc4119a":"6490","130df38c":"6493","12cbeba7":"6508","1236fad7":"6515","1c93669b":"6526","0c390f0d":"6550",c037d168:"6587","6f385a52":"6608","3972c49f":"6629",d28e30d7:"6671",c3ea66fe:"6698",e2de2dbb:"6710","2f43e44a":"6743",f87bdf62:"6750",fbd57548:"6837",bd4db8ee:"6883",f4f49e13:"6887","73688d5c":"6908","274c9143":"6984","54cb095e":"7009","6dd1c948":"7064","7881a85f":"7108",b7d33121:"7153","3ed04b60":"7157",d202e2c5:"7175","69a75ff2":"7181",cb6229c3:"7204","9bbc65ac":"7210",caf1b628:"7230","6c38e270":"7247","7e59392d":"7281","48faf148":"7328",ffb0fa11:"7400","14dc1923":"7403",c08e7a0d:"7404","70275fcd":"7412",df862072:"7474","66d1c769":"7476","75f50328":"7511",fb861301:"7563","2e10a69c":"7581","80960b4b":"7599","6c674d03":"7600","9e2e3982":"7617",a1877440:"7648","2b22d492":"7652","448c20a0":"7680","1d81daa1":"7681",b9bcab37:"7688","35293ec4":"7697","8e9dc6b3":"7709",b5f3dcc5:"7723","9cfe8fd1":"7725","3dd4d232":"7727",f0978ee1:"7740","2c9f5501":"7775",d65e25b7:"7776",af81a133:"7787","2c446262":"7797",a0410ab5:"7843","5a29fbab":"7857","635a92d5":"7891","2a8faff0":"7901","1a4e3797":"7920",d1e1bea4:"7945",d368e73e:"7954",c0cb7215:"7966","9d1fd2b0":"7972","270346fa":"7975","1664646a":"8036",d0840b01:"8037","41c44b28":"8106","3b12d42b":"8107",fed8bc04:"8110","5eed1665":"8142","255134d9":"8151","19f4ae8e":"8161",d60e2b0c:"8174","1fbde614":"8243","56e576e5":"8262","21e890b0":"8288","8dc09bac":"8338",fe273484:"8355","8ad2f007":"8360",a3614f73:"8474",f3493919:"8476","3d6c40c1":"8509",a7bd4aaa:"8518","9dec6b67":"8524",ac3fdf5d:"8548",d2611248:"8561","6875c492":"8610","41b4728f":"8628",cef46b76:"8644",e7d2a655:"8652",cd68cda1:"8683",ee92877e:"8716",cc3bdf2f:"8817",f75a8651:"8882",bbc3f62a:"8894",aacfeabc:"8909",f042b56c:"8919",c1b17b3f:"8927","0a2eaa84":"8942",b421ebb7:"9055","198f8d8a":"9059",a85e626a:"9092","372ccfe9":"9111","18c69d70":"9171","101cf32b":"9239",c29bedb9:"9242","9b43eac8":"9286","8b79a48d":"9287","4515250b":"9304",d1cef389:"9310","42957a8d":"9312","829fa7b9":"9391","6bc709ad":"9393","52106a5f":"9396","21294bbb":"9412","8da65e83":"9427",db86613e:"9458",e2326195:"9467",fb48356a:"9534","9b56b618":"9538","72657f57":"9581","2b479afe":"9591",ef5b2427:"9606",a4349a81:"9623",d40f51e1:"9633","5e95c892":"9661","5a473bed":"9686","492a6565":"9702","1bb997fc":"9713",bd2d06b5:"9763",d88bdb28:"9788","1a6b9123":"9874","16f719ab":"9875",f580a9d0:"9887",e1a06456:"9910",df203c0f:"9924",e4ebfe18:"9940"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(b,a)=>{var f=r.o(e,b)?e[b]:void 0;if(0!==f)if(f)a.push(f[2]);else if(/^(1303|532)$/.test(b))e[b]=0;else{var d=new Promise(((a,d)=>f=e[b]=[a,d]));a.push(f[2]=d);var c=r.p+r.u(b),t=new Error;r.l(c,(a=>{if(r.o(e,b)&&(0!==(f=e[b])&&(e[b]=void 0),f)){var d=a&&("load"===a.type?"missing":a.type),c=a&&a.target&&a.target.src;t.message="Loading chunk "+b+" failed.\n("+d+": "+c+")",t.name="ChunkLoadError",t.type=d,t.request=c,f[1](t)}}),"chunk-"+b,b)}},r.O.j=b=>0===e[b];var b=(b,a)=>{var f,d,c=a[0],t=a[1],o=a[2],n=0;if(c.some((b=>0!==e[b]))){for(f in t)r.o(t,f)&&(r.m[f]=t[f]);if(o)var i=o(r)}for(b&&b(a);n<c.length;n++)d=c[n],r.o(e,d)&&e[d]&&e[d][0](),e[d]=0;return r.O(i)},a=self.webpackChunkmy_website=self.webpackChunkmy_website||[];a.forEach(b.bind(null,0)),a.push=b.bind(null,a.push.bind(a))})()})(); \ No newline at end of file diff --git a/assets/js/runtime~main.46a193ef.js b/assets/js/runtime~main.46a193ef.js deleted file mode 100644 index 51f1ea903..000000000 --- a/assets/js/runtime~main.46a193ef.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";var e,a,d,f,b,c={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var d=t[e]={id:e,loaded:!1,exports:{}};return c[e].call(d.exports,d,d.exports,r),d.loaded=!0,d.exports}r.m=c,e=[],r.O=(a,d,f,b)=>{if(!d){var c=1/0;for(i=0;i<e.length;i++){d=e[i][0],f=e[i][1],b=e[i][2];for(var t=!0,o=0;o<d.length;o++)(!1&b||c>=b)&&Object.keys(r.O).every((e=>r.O[e](d[o])))?d.splice(o--,1):(t=!1,b<c&&(c=b));if(t){e.splice(i--,1);var n=f();void 0!==n&&(a=n)}}return a}b=b||0;for(var i=e.length;i>0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[d,f,b]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},d=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,f){if(1&f&&(e=this(e)),8&f)return e;if("object"==typeof e&&e){if(4&f&&e.__esModule)return e;if(16&f&&"function"==typeof e.then)return e}var b=Object.create(null);r.r(b);var c={};a=a||[null,d({}),d([]),d(d)];for(var t=2&f&&e;"object"==typeof t&&!~a.indexOf(t);t=d(t))Object.getOwnPropertyNames(t).forEach((a=>c[a]=()=>e[a]));return c.default=()=>e,r.d(b,c),b},r.d=(e,a)=>{for(var d in a)r.o(a,d)&&!r.o(e,d)&&Object.defineProperty(e,d,{enumerable:!0,get:a[d]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,d)=>(r.f[d](e,a),a)),[])),r.u=e=>"assets/js/"+({26:"ad3b7b62",31:"f4c6e7e6",53:"935f2afb",71:"8a27aeff",80:"5088fe06",96:"087c46fa",100:"d50fd269",116:"0cb009d1",172:"96adae60",240:"4959fc42",286:"1893cb59",297:"9fae68e2",300:"92fef07b",321:"0c071de2",324:"280572f1",328:"4b2fba3e",372:"35b2eb5a",422:"0281109c",425:"16cc6f3a",448:"28a1570f",454:"1a665c6f",470:"8720c147",471:"38d8699e",475:"a3dddb77",498:"6ba49b42",533:"b2b675dd",548:"32397cb2",573:"b474adfe",588:"d7955594",628:"e0d68441",653:"bbceb8f1",656:"1f05d14a",693:"6a19354d",711:"bb221eab",724:"f01ceada",732:"64f377d6",734:"05b907fc",741:"8a24850b",743:"509d519c",820:"ff4c6c5e",838:"6b4e1191",843:"d2770bf7",846:"d0277431",916:"fa3d3942",917:"6552f31f",952:"86b4da3d",955:"fe8cce0a",964:"c573638f",970:"32b2299c",988:"754fb852",1065:"69c28c32",1079:"15f27552",1103:"49b8d9dd",1112:"e9eabc5d",1113:"0746167d",1196:"2d3b202f",1213:"b2c8756c",1252:"5d4cff52",1253:"e5e44a85",1255:"6675e9ab",1257:"b36d2d1d",1285:"38bf29ad",1328:"08e37dbc",1358:"cec43d6a",1391:"b41adc00",1434:"dfa84138",1436:"8e498bb6",1475:"451db21d",1501:"64868a43",1611:"e1735da7",1653:"7e4c1ed7",1659:"daff1d93",1675:"d126aabd",1677:"d5dfecc2",1711:"a710d533",1761:"dcf70953",1762:"2bfe7c0b",1772:"92ade856",1793:"309173fa",1853:"21d253a0",1883:"302370be",1906:"4485017c",1926:"f078e301",1994:"269a2f75",2012:"a59d28a9",2087:"7c660760",2098:"d350f5d9",2100:"5ffd2c10",2145:"9c6e5a12",2153:"9bad5ae7",2156:"b6ffb0cb",2181:"ae1d6508",2215:"abc83b7f",2233:"1f61820a",2245:"f25de701",2247:"d361ad2d",2261:"a8cba70f",2266:"a9c2b81a",2293:"b88cb85b",2334:"7af1d52f",2345:"7405ea58",2362:"bace0b37",2448:"633582b9",2476:"2832e534",2526:"a896be03",2530:"e9ff60ad",2535:"814f3328",2542:"ddf9e0bd",2579:"672a376b",2620:"f06cb3e2",2625:"04644f5f",2656:"303c1e60",2717:"f332d221",2742:"33736670",2753:"7762a24e",2773:"3b18521e",2793:"489347ff",2816:"8c6c0796",2889:"7fd9a574",2890:"d6a3d698",2939:"905ecccc",2947:"981f7647",2958:"f7b9d2f4",2965:"ae3384b2",2967:"5feaaaeb",3009:"bbc01ba0",3085:"c60ea0ff",3089:"a6aa9e1f",3092:"0e33a907",3095:"bf933b37",3098:"d09f7e4b",3109:"211d6170",3122:"6d4355d3",3137:"c6b037a5",3206:"f8409a7e",3213:"ac23d7ee",3239:"dca6a1e3",3259:"d2935d14",3287:"7159c7ff",3324:"4a1c8300",3333:"1e8ecffe",3365:"4d43abad",3392:"d86f7a37",3396:"bbdd7e52",3407:"327fa616",3438:"c55d205b",3457:"537817cb",3476:"d6638f30",3483:"2d9296e4",3490:"9ca52986",3519:"a7e0d18f",3530:"20e99c2a",3553:"3b0f99e8",3608:"9e4087bc",3614:"fd5d2408",3625:"77f5fc5d",3637:"b301b20b",3651:"d5bb232a",3671:"a4a1e915",3673:"9f586ca3",3691:"366ddb85",3751:"3720c009",3771:"e6e259a5",3833:"a14ec7b5",3912:"e8d6e7ce",4013:"01a85c17",4091:"b2ebb6fd",4104:"454a6d0d",4121:"55960ee5",4137:"eff1d58f",4149:"8d05b77c",4174:"abb0816f",4185:"c7015929",4195:"c4f5d8e4",4209:"15eddcef",4212:"290b0a56",4275:"04c55e47",4311:"7bbc420e",4393:"c92f81ac",4433:"49f0f498",4471:"494882d1",4558:"6b54f6a4",4564:"e9624b4f",4665:"e0e4666e",4722:"53e4509a",4788:"f6807fb4",4801:"8d7288fe",4815:"43a97218",4818:"530ffa4f",4889:"5f81b25c",4934:"02ede3c9",4953:"eec33099",4962:"c189d18f",5035:"1a3abee6",5046:"db7928b3",5088:"54150be7",5100:"533bfc57",5103:"df147deb",5131:"f63a747b",5173:"3680bd07",5186:"3f6ea930",5237:"26dc40bf",5294:"f90d0c52",5300:"e6a6ed43",5319:"6cfe3a99",5323:"cc519f63",5335:"75121fd5",5371:"aa73a035",5406:"9e4ad429",5421:"6412e40a",5435:"ee1dd2ad",5436:"c6d04683",5463:"bd64a762",5465:"d0e4cdf1",5467:"6425a984",5485:"da14f319",5487:"08726fcf",5507:"a9221bd5",5521:"5c38e66e",5553:"4430ab79",5602:"f156dfb9",5635:"546ec22f",5649:"564337ec",5652:"1398b403",5669:"00931cc3",5682:"70a12cc4",5717:"39ee6679",5753:"051528db",5758:"a539c018",5785:"1781b1c4",5797:"7fbacf84",5798:"24b9bc70",5819:"e073eb07",5838:"4b79a3c9",5857:"dfc7013c",5870:"cf8e491a",5873:"8fbd512b",5892:"c6004f62",5900:"3c9c1743",5919:"d8cdf5ef",5953:"5a6c6934",5962:"9d8ee3a8",5964:"09fbb6bd",5966:"871c1e5a",5990:"6b69808d",5991:"a5557bb9",6017:"6093f82b",6035:"226700de",6049:"e21c8cc4",6058:"dab4c683",6084:"101b58de",6103:"ccc49370",6123:"f3e308ad",6124:"87070fc3",6161:"562496aa",6172:"be497a8d",6180:"eae2a611",6199:"c60995f6",6204:"0571a526",6250:"3c5aea38",6276:"1251d98b",6300:"5c07bdab",6346:"02689328",6387:"d8775059",6412:"79a97f4e",6420:"ae82353f",6468:"43fcf0e9",6490:"9dc4119a",6493:"130df38c",6508:"12cbeba7",6515:"1236fad7",6526:"1c93669b",6550:"0c390f0d",6587:"c037d168",6608:"6f385a52",6629:"3972c49f",6671:"d28e30d7",6698:"c3ea66fe",6710:"e2de2dbb",6743:"2f43e44a",6750:"f87bdf62",6837:"fbd57548",6883:"bd4db8ee",6887:"f4f49e13",6908:"73688d5c",6984:"274c9143",7009:"54cb095e",7064:"6dd1c948",7108:"7881a85f",7153:"b7d33121",7157:"3ed04b60",7175:"d202e2c5",7181:"69a75ff2",7204:"cb6229c3",7210:"9bbc65ac",7230:"caf1b628",7247:"6c38e270",7268:"14164549",7281:"7e59392d",7328:"48faf148",7344:"70834889",7400:"ffb0fa11",7403:"14dc1923",7404:"c08e7a0d",7412:"70275fcd",7474:"df862072",7476:"66d1c769",7511:"75f50328",7563:"fb861301",7581:"2e10a69c",7599:"80960b4b",7600:"6c674d03",7617:"9e2e3982",7648:"a1877440",7652:"2b22d492",7680:"448c20a0",7681:"1d81daa1",7688:"b9bcab37",7697:"35293ec4",7709:"8e9dc6b3",7723:"b5f3dcc5",7725:"9cfe8fd1",7727:"3dd4d232",7740:"f0978ee1",7775:"2c9f5501",7776:"d65e25b7",7787:"af81a133",7797:"2c446262",7843:"a0410ab5",7857:"5a29fbab",7891:"635a92d5",7901:"2a8faff0",7918:"17896441",7920:"1a4e3797",7945:"d1e1bea4",7954:"d368e73e",7966:"c0cb7215",7972:"9d1fd2b0",7975:"270346fa",8036:"1664646a",8037:"d0840b01",8106:"41c44b28",8107:"3b12d42b",8110:"fed8bc04",8142:"5eed1665",8151:"255134d9",8161:"19f4ae8e",8174:"d60e2b0c",8243:"1fbde614",8262:"56e576e5",8288:"21e890b0",8338:"8dc09bac",8355:"fe273484",8360:"8ad2f007",8474:"a3614f73",8476:"f3493919",8509:"3d6c40c1",8518:"b421ebb7",8524:"9dec6b67",8548:"ac3fdf5d",8561:"d2611248",8610:"6875c492",8628:"41b4728f",8644:"cef46b76",8652:"e7d2a655",8683:"cd68cda1",8716:"ee92877e",8817:"cc3bdf2f",8882:"f75a8651",8894:"bbc3f62a",8909:"aacfeabc",8919:"f042b56c",8927:"c1b17b3f",8942:"0a2eaa84",9059:"198f8d8a",9092:"a85e626a",9111:"372ccfe9",9171:"18c69d70",9239:"101cf32b",9242:"c29bedb9",9286:"9b43eac8",9287:"8b79a48d",9304:"4515250b",9310:"d1cef389",9312:"42957a8d",9391:"829fa7b9",9393:"6bc709ad",9396:"52106a5f",9412:"21294bbb",9427:"8da65e83",9458:"db86613e",9467:"e2326195",9514:"1be78505",9534:"fb48356a",9538:"9b56b618",9581:"72657f57",9591:"2b479afe",9606:"ef5b2427",9623:"a4349a81",9633:"d40f51e1",9686:"5a473bed",9702:"492a6565",9713:"1bb997fc",9763:"bd2d06b5",9788:"d88bdb28",9874:"1a6b9123",9875:"16f719ab",9887:"f580a9d0",9910:"e1a06456",9924:"df203c0f",9940:"e4ebfe18"}[e]||e)+"."+{4:"4bc37b90",26:"a08f7c0f",31:"ae84b9cb",53:"b34f8ac9",71:"630953b4",80:"2cc977cf",96:"efcd5e69",100:"267c41c3",116:"ddadf169",172:"b8feb030",240:"af9f01e2",286:"8a4bc4b2",297:"72dfd56d",300:"c8b2c292",321:"265b47fa",324:"e70297e6",328:"ee7b0442",372:"9ac55f69",422:"094422e8",425:"f10a7b3c",448:"0cae8263",454:"ad3c5a8e",470:"05a8b5ca",471:"24ce7018",475:"2dd61ce3",498:"12fc56b7",533:"4e7704bd",548:"79ba529e",573:"859d75dc",588:"19c09353",628:"b9e1aa8d",653:"45b4a5d1",656:"8224f0a8",693:"c2212a44",711:"ee80a616",724:"5272c56b",732:"77b06a2e",734:"e1277f6c",741:"556fbbc3",743:"caf52cd9",820:"cbf81af0",838:"5ce4d8f9",843:"15235f36",846:"0c6e8615",916:"9d73b73f",917:"185b6073",952:"3bc777bd",955:"5b81fa8f",964:"0c33f138",970:"3f86eab1",988:"1af0a567",1065:"6f23071b",1079:"e9d4d18f",1103:"ce03beac",1112:"641504bc",1113:"afac0769",1196:"fad40be0",1213:"a59a1417",1252:"7e9bdf80",1253:"87bbc8e5",1255:"ab8081ba",1257:"c9ee00e8",1285:"a6eb9d38",1328:"6c646e20",1358:"e9cb4ce1",1391:"626950e4",1434:"4493a1cc",1436:"a1dd0c3d",1475:"c94c80d0",1501:"b31f6d0d",1611:"09484f33",1653:"19c4489f",1659:"928fbfe7",1675:"69a06b4a",1677:"ea44f851",1711:"dc0f0af8",1761:"d0be48ac",1762:"417a3763",1772:"3ed7370b",1793:"f6e5e77a",1853:"c36050f0",1883:"1897c05f",1906:"833a8ee1",1926:"5f6afbe2",1994:"5474eea4",2012:"8f8cdb54",2087:"e38d4441",2090:"4df4088d",2098:"3f436aab",2100:"ccf10cdb",2145:"70f826f0",2153:"ab21a5c2",2156:"5114dc6f",2181:"f635198e",2215:"9e2be049",2233:"d2bb9f6d",2245:"505cef98",2247:"23351413",2261:"a8d56601",2266:"560a866f",2293:"58b19204",2334:"d4c7e602",2345:"4efb653a",2362:"3df7fde1",2448:"05e73941",2476:"1096ee60",2526:"193fe0aa",2530:"6425d7c1",2535:"0103710c",2542:"b3d7aff1",2579:"94e40e70",2620:"e9cf765a",2625:"6c9c9166",2656:"9e56888d",2717:"12aef286",2742:"01b3f5e5",2753:"1551d3ca",2773:"c7777a60",2793:"b84e267c",2816:"8c72a84a",2889:"986af784",2890:"f4578e6a",2939:"0adeb2b8",2947:"b7830cd7",2958:"46e8275d",2965:"95cb14ea",2967:"4b1e42eb",3009:"8021a974",3085:"881f4c53",3089:"7b54bae2",3092:"f1035e02",3095:"56ca3009",3098:"eacc75cd",3109:"a3a55376",3122:"3a49ae35",3137:"97248574",3206:"bddfd935",3213:"9149127e",3239:"373e22d0",3259:"fe55055e",3287:"d0063e09",3324:"99f9cdad",3333:"3c06cdf1",3365:"89ba9d9c",3392:"cb912e58",3396:"eb9f3b5d",3407:"f65bd575",3438:"99ebdf49",3457:"b44a0ebf",3476:"965323b3",3483:"a52c556a",3490:"08ff34b4",3519:"d72749dc",3530:"90a43ac9",3553:"c4d5d643",3608:"9cf973ca",3614:"f64b5f70",3625:"2ccaf719",3637:"98eff9ce",3651:"2a47f439",3671:"b7b0c0db",3673:"0edad504",3691:"8c709735",3751:"0851b2e0",3771:"51ae33b3",3833:"53e9b93f",3912:"71026c4f",4013:"6e93ad75",4091:"a5bc8099",4104:"f73eccad",4121:"cf44ccd7",4137:"ac84edda",4149:"f9f54172",4174:"b0d0aba5",4185:"683ff471",4195:"d37ba840",4209:"c113f5f0",4212:"35146abd",4275:"442e9eb3",4311:"82f9788b",4393:"e9e6baff",4433:"c7f15397",4471:"ab916c9a",4558:"68a68fa1",4564:"522d48a7",4665:"a51bac0c",4722:"2d116db6",4788:"be958d21",4801:"5f0bac2d",4815:"8e3134d2",4818:"8ee384a9",4889:"3a028eac",4934:"16e5bf41",4953:"645a57bb",4962:"67c78fec",4972:"46e01c40",5035:"be6aaff1",5046:"2a9c0fe1",5088:"a4cc9618",5100:"91265c60",5103:"036e49b2",5131:"189a7c8a",5173:"a5c1fc21",5186:"ae70e445",5237:"31dfe6a6",5294:"28880251",5300:"db308191",5319:"f51506e7",5323:"c9506faa",5335:"27699af6",5371:"5245d1dd",5406:"26efcf8e",5421:"1ab52c78",5435:"69ff89bd",5436:"3ecb01f2",5463:"d1f2c079",5465:"10c574a5",5467:"576248f5",5485:"f8f3a39f",5487:"b0eaf3bf",5507:"3bfa9f2c",5521:"502a685d",5553:"4a43f845",5602:"5680e4f0",5635:"01a1fc0a",5649:"cafb2d42",5652:"522981cc",5669:"d9e8855a",5682:"2db653db",5717:"149b515e",5753:"29135bf1",5758:"8e8d9e35",5785:"215572b1",5797:"c4fc60f8",5798:"680ac376",5819:"48315c69",5838:"061deffc",5857:"e658333c",5870:"20189b57",5873:"23ff3cd4",5892:"8257704e",5900:"139a7956",5919:"1054df5c",5953:"8a355bab",5962:"3e89b3f5",5964:"f3f0267e",5966:"a006189f",5990:"a3797a3c",5991:"4377935f",6017:"2b0798f4",6035:"e0a4b7fd",6048:"265dbd9c",6049:"cea3918b",6058:"14fde9f3",6084:"c3fca784",6103:"7af2b68e",6123:"6ab15074",6124:"d725d20f",6161:"a42c37e7",6172:"11ef414c",6180:"d922a965",6199:"9c12eb08",6204:"e17175a4",6250:"116651cd",6276:"79f485fe",6300:"7765e80c",6346:"091cac7e",6387:"2c1a33ff",6412:"418816f9",6420:"265ad54c",6468:"f85c5112",6490:"f875b280",6493:"26766cc3",6508:"fc8c85de",6515:"f0e8ba67",6526:"866c6364",6550:"d414135a",6587:"96f06126",6608:"ac98a76a",6629:"411ee9ac",6671:"1e157fc3",6698:"73186556",6710:"9ac0053b",6743:"31f6617e",6750:"d6d127e8",6780:"71665265",6837:"164d143c",6883:"4dd36f14",6887:"79baf298",6908:"e6c6d26a",6945:"52e6a492",6984:"f313ce06",7009:"bb1a2368",7064:"56a5cee5",7108:"5df241ab",7153:"17983764",7157:"f8fa3b6d",7175:"1343f229",7181:"2e16faab",7204:"61e1a1f5",7210:"6e49b159",7230:"f649b595",7247:"5da4b5e2",7268:"7a0bdef8",7281:"c1fbf51f",7328:"36080fd6",7344:"7476dcca",7400:"e327857d",7403:"82248792",7404:"b69297ab",7412:"1113713e",7474:"cebd22e7",7476:"0554fad1",7511:"0959afe8",7563:"4cca033a",7581:"d6202677",7599:"23d0b12a",7600:"239b12b7",7617:"e9ee5729",7648:"88e9cb51",7652:"deba5021",7680:"95c05821",7681:"821e44e6",7688:"2fcdcd9c",7697:"1448bfa5",7709:"cb50d73f",7723:"8adc35cf",7725:"4bd5caa7",7727:"407474b2",7740:"fc391fa7",7775:"592c2549",7776:"e3ba3748",7787:"7821cdd8",7797:"794bbcbb",7843:"192fd50a",7857:"24f29dd6",7891:"a1e1a506",7901:"3559b72e",7918:"5e6fba35",7920:"b205bd12",7945:"03ce7300",7954:"9d264eba",7966:"c03bc365",7972:"fa60d8c7",7975:"a5c01a12",8036:"a30b9a81",8037:"850cded6",8106:"8fc30aac",8107:"3312efb5",8110:"ba13b2b6",8142:"92b60a91",8151:"a1e74e37",8161:"f32f8930",8174:"cbd24ef7",8243:"de74c976",8262:"c2861079",8288:"a0551afe",8338:"44e33d7b",8355:"6eaec45f",8360:"b27b51dd",8474:"e670cd3b",8476:"b7bbf831",8509:"6216fe06",8518:"8b29869e",8524:"a1bd30cc",8548:"91db26ff",8561:"4a8223bd",8610:"e43a4554",8628:"0a266023",8644:"722e08ea",8652:"c38576aa",8683:"533ff58c",8716:"d75057f6",8817:"5664f42d",8882:"9dc7565f",8894:"db081e7b",8909:"ff4dccf0",8919:"2fd3c78c",8927:"12ea0995",8942:"338d4c36",9059:"246f1a7e",9092:"14258449",9111:"87b936b9",9171:"7e0e9cbb",9239:"0067bead",9242:"2e2eddf5",9286:"4b06c7e4",9287:"782b4bba",9304:"7c65c757",9310:"0505ff33",9312:"eb9b613e",9391:"582cc610",9393:"9758e816",9396:"e7405ebf",9412:"8ea9233b",9427:"884cacff",9458:"2743f870",9467:"6b12f1d6",9514:"9fa0cbc0",9534:"bee2d2d9",9538:"5822f5e9",9581:"a5decd7b",9591:"31ea2b46",9606:"7a1f7236",9623:"a1bfa638",9633:"14bda7cc",9686:"c195eeae",9702:"1392e115",9713:"96d5e1f3",9763:"57d4dcf0",9788:"4d81ac29",9874:"2138ce03",9875:"a33933ef",9887:"ff66fa3d",9910:"e3f8fecc",9924:"c891d774",9940:"a435ae27"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),f={},b="my-website:",r.l=(e,a,d,c)=>{if(f[e])f[e].push(a);else{var t,o;if(void 0!==d)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var l=n[i];if(l.getAttribute("src")==e||l.getAttribute("data-webpack")==b+d){t=l;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",b+d),t.src=e),f[e]=[a];var u=(a,d)=>{t.onerror=t.onload=null,clearTimeout(s);var b=f[e];if(delete f[e],t.parentNode&&t.parentNode.removeChild(t),b&&b.forEach((e=>e(d))),a)return a(d)},s=setTimeout(u.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=u.bind(null,t.onerror),t.onload=u.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),r.p="/",r.gca=function(e){return e={14164549:"7268",17896441:"7918",33736670:"2742",70834889:"7344",ad3b7b62:"26",f4c6e7e6:"31","935f2afb":"53","8a27aeff":"71","5088fe06":"80","087c46fa":"96",d50fd269:"100","0cb009d1":"116","96adae60":"172","4959fc42":"240","1893cb59":"286","9fae68e2":"297","92fef07b":"300","0c071de2":"321","280572f1":"324","4b2fba3e":"328","35b2eb5a":"372","0281109c":"422","16cc6f3a":"425","28a1570f":"448","1a665c6f":"454","8720c147":"470","38d8699e":"471",a3dddb77:"475","6ba49b42":"498",b2b675dd:"533","32397cb2":"548",b474adfe:"573",d7955594:"588",e0d68441:"628",bbceb8f1:"653","1f05d14a":"656","6a19354d":"693",bb221eab:"711",f01ceada:"724","64f377d6":"732","05b907fc":"734","8a24850b":"741","509d519c":"743",ff4c6c5e:"820","6b4e1191":"838",d2770bf7:"843",d0277431:"846",fa3d3942:"916","6552f31f":"917","86b4da3d":"952",fe8cce0a:"955",c573638f:"964","32b2299c":"970","754fb852":"988","69c28c32":"1065","15f27552":"1079","49b8d9dd":"1103",e9eabc5d:"1112","0746167d":"1113","2d3b202f":"1196",b2c8756c:"1213","5d4cff52":"1252",e5e44a85:"1253","6675e9ab":"1255",b36d2d1d:"1257","38bf29ad":"1285","08e37dbc":"1328",cec43d6a:"1358",b41adc00:"1391",dfa84138:"1434","8e498bb6":"1436","451db21d":"1475","64868a43":"1501",e1735da7:"1611","7e4c1ed7":"1653",daff1d93:"1659",d126aabd:"1675",d5dfecc2:"1677",a710d533:"1711",dcf70953:"1761","2bfe7c0b":"1762","92ade856":"1772","309173fa":"1793","21d253a0":"1853","302370be":"1883","4485017c":"1906",f078e301:"1926","269a2f75":"1994",a59d28a9:"2012","7c660760":"2087",d350f5d9:"2098","5ffd2c10":"2100","9c6e5a12":"2145","9bad5ae7":"2153",b6ffb0cb:"2156",ae1d6508:"2181",abc83b7f:"2215","1f61820a":"2233",f25de701:"2245",d361ad2d:"2247",a8cba70f:"2261",a9c2b81a:"2266",b88cb85b:"2293","7af1d52f":"2334","7405ea58":"2345",bace0b37:"2362","633582b9":"2448","2832e534":"2476",a896be03:"2526",e9ff60ad:"2530","814f3328":"2535",ddf9e0bd:"2542","672a376b":"2579",f06cb3e2:"2620","04644f5f":"2625","303c1e60":"2656",f332d221:"2717","7762a24e":"2753","3b18521e":"2773","489347ff":"2793","8c6c0796":"2816","7fd9a574":"2889",d6a3d698:"2890","905ecccc":"2939","981f7647":"2947",f7b9d2f4:"2958",ae3384b2:"2965","5feaaaeb":"2967",bbc01ba0:"3009",c60ea0ff:"3085",a6aa9e1f:"3089","0e33a907":"3092",bf933b37:"3095",d09f7e4b:"3098","211d6170":"3109","6d4355d3":"3122",c6b037a5:"3137",f8409a7e:"3206",ac23d7ee:"3213",dca6a1e3:"3239",d2935d14:"3259","7159c7ff":"3287","4a1c8300":"3324","1e8ecffe":"3333","4d43abad":"3365",d86f7a37:"3392",bbdd7e52:"3396","327fa616":"3407",c55d205b:"3438","537817cb":"3457",d6638f30:"3476","2d9296e4":"3483","9ca52986":"3490",a7e0d18f:"3519","20e99c2a":"3530","3b0f99e8":"3553","9e4087bc":"3608",fd5d2408:"3614","77f5fc5d":"3625",b301b20b:"3637",d5bb232a:"3651",a4a1e915:"3671","9f586ca3":"3673","366ddb85":"3691","3720c009":"3751",e6e259a5:"3771",a14ec7b5:"3833",e8d6e7ce:"3912","01a85c17":"4013",b2ebb6fd:"4091","454a6d0d":"4104","55960ee5":"4121",eff1d58f:"4137","8d05b77c":"4149",abb0816f:"4174",c7015929:"4185",c4f5d8e4:"4195","15eddcef":"4209","290b0a56":"4212","04c55e47":"4275","7bbc420e":"4311",c92f81ac:"4393","49f0f498":"4433","494882d1":"4471","6b54f6a4":"4558",e9624b4f:"4564",e0e4666e:"4665","53e4509a":"4722",f6807fb4:"4788","8d7288fe":"4801","43a97218":"4815","530ffa4f":"4818","5f81b25c":"4889","02ede3c9":"4934",eec33099:"4953",c189d18f:"4962","1a3abee6":"5035",db7928b3:"5046","54150be7":"5088","533bfc57":"5100",df147deb:"5103",f63a747b:"5131","3680bd07":"5173","3f6ea930":"5186","26dc40bf":"5237",f90d0c52:"5294",e6a6ed43:"5300","6cfe3a99":"5319",cc519f63:"5323","75121fd5":"5335",aa73a035:"5371","9e4ad429":"5406","6412e40a":"5421",ee1dd2ad:"5435",c6d04683:"5436",bd64a762:"5463",d0e4cdf1:"5465","6425a984":"5467",da14f319:"5485","08726fcf":"5487",a9221bd5:"5507","5c38e66e":"5521","4430ab79":"5553",f156dfb9:"5602","546ec22f":"5635","564337ec":"5649","1398b403":"5652","00931cc3":"5669","70a12cc4":"5682","39ee6679":"5717","051528db":"5753",a539c018:"5758","1781b1c4":"5785","7fbacf84":"5797","24b9bc70":"5798",e073eb07:"5819","4b79a3c9":"5838",dfc7013c:"5857",cf8e491a:"5870","8fbd512b":"5873",c6004f62:"5892","3c9c1743":"5900",d8cdf5ef:"5919","5a6c6934":"5953","9d8ee3a8":"5962","09fbb6bd":"5964","871c1e5a":"5966","6b69808d":"5990",a5557bb9:"5991","6093f82b":"6017","226700de":"6035",e21c8cc4:"6049",dab4c683:"6058","101b58de":"6084",ccc49370:"6103",f3e308ad:"6123","87070fc3":"6124","562496aa":"6161",be497a8d:"6172",eae2a611:"6180",c60995f6:"6199","0571a526":"6204","3c5aea38":"6250","1251d98b":"6276","5c07bdab":"6300","02689328":"6346",d8775059:"6387","79a97f4e":"6412",ae82353f:"6420","43fcf0e9":"6468","9dc4119a":"6490","130df38c":"6493","12cbeba7":"6508","1236fad7":"6515","1c93669b":"6526","0c390f0d":"6550",c037d168:"6587","6f385a52":"6608","3972c49f":"6629",d28e30d7:"6671",c3ea66fe:"6698",e2de2dbb:"6710","2f43e44a":"6743",f87bdf62:"6750",fbd57548:"6837",bd4db8ee:"6883",f4f49e13:"6887","73688d5c":"6908","274c9143":"6984","54cb095e":"7009","6dd1c948":"7064","7881a85f":"7108",b7d33121:"7153","3ed04b60":"7157",d202e2c5:"7175","69a75ff2":"7181",cb6229c3:"7204","9bbc65ac":"7210",caf1b628:"7230","6c38e270":"7247","7e59392d":"7281","48faf148":"7328",ffb0fa11:"7400","14dc1923":"7403",c08e7a0d:"7404","70275fcd":"7412",df862072:"7474","66d1c769":"7476","75f50328":"7511",fb861301:"7563","2e10a69c":"7581","80960b4b":"7599","6c674d03":"7600","9e2e3982":"7617",a1877440:"7648","2b22d492":"7652","448c20a0":"7680","1d81daa1":"7681",b9bcab37:"7688","35293ec4":"7697","8e9dc6b3":"7709",b5f3dcc5:"7723","9cfe8fd1":"7725","3dd4d232":"7727",f0978ee1:"7740","2c9f5501":"7775",d65e25b7:"7776",af81a133:"7787","2c446262":"7797",a0410ab5:"7843","5a29fbab":"7857","635a92d5":"7891","2a8faff0":"7901","1a4e3797":"7920",d1e1bea4:"7945",d368e73e:"7954",c0cb7215:"7966","9d1fd2b0":"7972","270346fa":"7975","1664646a":"8036",d0840b01:"8037","41c44b28":"8106","3b12d42b":"8107",fed8bc04:"8110","5eed1665":"8142","255134d9":"8151","19f4ae8e":"8161",d60e2b0c:"8174","1fbde614":"8243","56e576e5":"8262","21e890b0":"8288","8dc09bac":"8338",fe273484:"8355","8ad2f007":"8360",a3614f73:"8474",f3493919:"8476","3d6c40c1":"8509",b421ebb7:"8518","9dec6b67":"8524",ac3fdf5d:"8548",d2611248:"8561","6875c492":"8610","41b4728f":"8628",cef46b76:"8644",e7d2a655:"8652",cd68cda1:"8683",ee92877e:"8716",cc3bdf2f:"8817",f75a8651:"8882",bbc3f62a:"8894",aacfeabc:"8909",f042b56c:"8919",c1b17b3f:"8927","0a2eaa84":"8942","198f8d8a":"9059",a85e626a:"9092","372ccfe9":"9111","18c69d70":"9171","101cf32b":"9239",c29bedb9:"9242","9b43eac8":"9286","8b79a48d":"9287","4515250b":"9304",d1cef389:"9310","42957a8d":"9312","829fa7b9":"9391","6bc709ad":"9393","52106a5f":"9396","21294bbb":"9412","8da65e83":"9427",db86613e:"9458",e2326195:"9467","1be78505":"9514",fb48356a:"9534","9b56b618":"9538","72657f57":"9581","2b479afe":"9591",ef5b2427:"9606",a4349a81:"9623",d40f51e1:"9633","5a473bed":"9686","492a6565":"9702","1bb997fc":"9713",bd2d06b5:"9763",d88bdb28:"9788","1a6b9123":"9874","16f719ab":"9875",f580a9d0:"9887",e1a06456:"9910",df203c0f:"9924",e4ebfe18:"9940"}[e]||e,r.p+r.u(e)},(()=>{var e={1303:0,532:0};r.f.j=(a,d)=>{var f=r.o(e,a)?e[a]:void 0;if(0!==f)if(f)d.push(f[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var b=new Promise(((d,b)=>f=e[a]=[d,b]));d.push(f[2]=b);var c=r.p+r.u(a),t=new Error;r.l(c,(d=>{if(r.o(e,a)&&(0!==(f=e[a])&&(e[a]=void 0),f)){var b=d&&("load"===d.type?"missing":d.type),c=d&&d.target&&d.target.src;t.message="Loading chunk "+a+" failed.\n("+b+": "+c+")",t.name="ChunkLoadError",t.type=b,t.request=c,f[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,d)=>{var f,b,c=d[0],t=d[1],o=d[2],n=0;if(c.some((a=>0!==e[a]))){for(f in t)r.o(t,f)&&(r.m[f]=t[f]);if(o)var i=o(r)}for(a&&a(d);n<c.length;n++)b=c[n],r.o(e,b)&&e[b]&&e[b][0](),e[b]=0;return r.O(i)},d=self.webpackChunkmy_website=self.webpackChunkmy_website||[];d.forEach(a.bind(null,0)),d.push=a.bind(null,d.push.bind(d))})()})(); \ No newline at end of file diff --git a/atom.xml b/atom.xml index 70c860609..1a7f2392a 100644 --- a/atom.xml +++ b/atom.xml @@ -13,27 +13,62 @@ <link href="https://greeng00se.github.io/refactoring-retrospective"/> <updated>2023-10-31T00:00:00.000Z</updated> <summary type="html"><![CDATA[1단계//github.com/woowacourse/jwp-refactoring/pull/465]]></summary> - <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>PR 링크</div><div class="admonitionContent_S0QG"><p>1단계: <a href="https://github.com/woowacourse/jwp-refactoring/pull/465" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-refactoring/pull/465</a><br> -<!-- -->2단계: <a href="https://github.com/woowacourse/jwp-refactoring/pull/547" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-refactoring/pull/547</a><br> -<!-- -->3단계: <a href="https://github.com/woowacourse/jwp-refactoring/pull/610" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-refactoring/pull/610</a><br> -<!-- -->4단계: <a href="https://github.com/woowacourse/jwp-refactoring/pull/721" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-refactoring/pull/721</a> </p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="리팩터링-미션">리팩터링 미션<a href="#리팩터링-미션" class="hash-link" aria-label="리팩터링 미션에 대한 직접 링크" title="리팩터링 미션에 대한 직접 링크">​</a></h3><p>요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.<br> -<!-- -->미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="1-2단계">1, 2단계<a href="#1-2단계" class="hash-link" aria-label="1, 2단계에 대한 직접 링크" title="1, 2단계에 대한 직접 링크">​</a></h3><p>1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. + <content type="html"><![CDATA[<admonition title="PR 링크" type="note"><p>1단계: <a href="https://github.com/woowacourse/jwp-refactoring/pull/465">https://github.com/woowacourse/jwp-refactoring/pull/465</a><br> +<!-- -->2단계: <a href="https://github.com/woowacourse/jwp-refactoring/pull/547">https://github.com/woowacourse/jwp-refactoring/pull/547</a><br> +<!-- -->3단계: <a href="https://github.com/woowacourse/jwp-refactoring/pull/610">https://github.com/woowacourse/jwp-refactoring/pull/610</a><br> +<!-- -->4단계: <a href="https://github.com/woowacourse/jwp-refactoring/pull/721">https://github.com/woowacourse/jwp-refactoring/pull/721</a></p></admonition> +<h3 id="리팩터링-미션">리팩터링 미션</h3> +<p>요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.<br> +<!-- -->미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.</p> +<h3 id="1-2단계">1, 2단계</h3> +<p>1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. 요구사항을 작성할 때 제공된 용어 사전을 최대한 활용하면서 기존의 코드를 보면서 요구사항을 정리했다. -테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다. </p><p>최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.<br> -<!-- -->리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다. </p><p>2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.<br> +테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.</p> +<p>최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.<br> +<!-- -->리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.</p> +<p>2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.<br> <!-- -->서비스에서 도메인을 직접 반환하는 구조였는데, 도메인에 JPA를 적용하면 기존 명세와 달라질 것을 우려해서 DTO로 수정하는 작업을 먼저 진행했다. DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최종적으로 JPA를 적용하는 순서로 리팩터링을 진행했다. -이 과정에서 의존성 방향이 양방향인 부분도 생겨났다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="소프트웨어의-복잡성을-다루는-지혜">소프트웨어의 복잡성을 다루는 지혜<a href="#소프트웨어의-복잡성을-다루는-지혜" class="hash-link" aria-label="소프트웨어의 복잡성을 다루는 지혜에 대한 직접 링크" title="소프트웨어의 복잡성을 다루는 지혜에 대한 직접 링크">​</a></h3><p>중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.<br> -<!-- -->소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 <code>도메인 주도 설계</code>의 부제이다. </p><p>도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.<br> -<!-- -->유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다. </p><p>간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다. </p><table><thead><tr><th>단어</th><th>설명</th></tr></thead><tbody><tr><td>도메인</td><td>소프트웨어로 해결하고자 하는 문제 영역</td></tr><tr><td>바운디드 컨텍스트</td><td>해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위</td></tr><tr><td>유비쿼터스 언어</td><td>프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어</td></tr><tr><td>전략적 설계</td><td>도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정</td></tr><tr><td>전술적 설계</td><td>전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정</td></tr></tbody></table><p>이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="3-4단계">3, 4단계<a href="#3-4단계" class="hash-link" aria-label="3, 4단계에 대한 직접 링크" title="3, 4단계에 대한 직접 링크">​</a></h3><p>제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다. </p><p>3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. -함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다. </p><p>의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. -처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다. </p><p>4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.<br> +이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.</p> +<h3 id="소프트웨어의-복잡성을-다루는-지혜">소프트웨어의 복잡성을 다루는 지혜</h3> +<p>중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.<br> +<!-- -->소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 <code>도메인 주도 설계</code>의 부제이다.</p> +<p>도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.<br> +<!-- -->유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.</p> +<p>간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.</p> +<table><thead><tr><th>단어</th><th>설명</th></tr></thead><tbody><tr><td>도메인</td><td>소프트웨어로 해결하고자 하는 문제 영역</td></tr><tr><td>바운디드 컨텍스트</td><td>해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위</td></tr><tr><td>유비쿼터스 언어</td><td>프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어</td></tr><tr><td>전략적 설계</td><td>도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정</td></tr><tr><td>전술적 설계</td><td>전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정</td></tr></tbody></table> +<p>이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.</p> +<h3 id="3-4단계">3, 4단계</h3> +<p>제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.</p> +<p>3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. +함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.</p> +<p>의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. +처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.</p> +<p>4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.<br> <!-- -->3단계에서는 함께 생성되고 삭제되는 객체 기준으로 분리했다. 4단계에서는 내가 인식하기 편한 기준으로 분리를 했다. -아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다. </p><p>추가로 테스트 격리를 위한 <code>@ServiceTest</code> 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. -따라서 TestFixtures를 사용하여 해결했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="마무리">마무리<a href="#마무리" class="hash-link" aria-label="마무리에 대한 직접 링크" title="마무리에 대한 직접 링크">​</a></h3><p>우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.<br> -<!-- -->바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h3><p><a href="https://www.youtube.com/watch?v=kmUneexSxk0" target="_blank" rel="noopener noreferrer">도메인 원정대, 우아콘 2021</a><br> -<a href="https://www.youtube.com/watch?v=dJ5C4qRqAgA" target="_blank" rel="noopener noreferrer">우아한객체지향, 우아한테크세미나</a><br> -<a href="https://kwonnam.pe.kr/wiki/gradle/testfixtures" target="_blank" rel="noopener noreferrer">TestFixtures, 권남님</a></p>]]></content> +아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.</p> +<mermaid value="graph LR + subgraph Table + OrderTable --> TableGroup + end + subgraph Order + O + end + O[Order] --> OrderTable + subgraph Menu + M[Menu] --> MenuGroup + M --> Product + end + O --> M"></mermaid> +<p>추가로 테스트 격리를 위한 직접 작성한 <code>@ServiceTest</code> 커스텀 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. +따라서 TestFixtures를 사용하여 해결했다.</p> +<h3 id="마무리">마무리</h3> +<p>우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.<br> +<!-- -->바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.</p> +<h3 id="참고-자료">참고 자료</h3> +<p><a href="https://www.youtube.com/watch?v=kmUneexSxk0">도메인 원정대, 우아콘 2021</a><br> +<a href="https://www.youtube.com/watch?v=dJ5C4qRqAgA">우아한객체지향, 우아한테크세미나</a><br> +<a href="https://kwonnam.pe.kr/wiki/gradle/testfixtures">TestFixtures, 권남님</a></p>]]></content> <category label="Woowahan Techcourse" term="Woowahan Techcourse"/> <category label="Retrospective" term="Retrospective"/> </entry> @@ -43,15 +78,88 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/jdbc-retrospective"/> <updated>2023-10-10T00:00:00.000Z</updated> <summary type="html"><![CDATA[1단계//github.com/woowacourse/jwp-dashboard-jdbc/pull/267]]></summary> - <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>PR 링크</div><div class="admonitionContent_S0QG"><p>1단계: <a href="https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267</a><br> -<!-- -->2단계: <a href="https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358</a><br> -<!-- -->3단계: <a href="https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448</a><br> -<!-- -->4단계: <a href="https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515</a> </p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="jdbc-구현">Jdbc 구현<a href="#jdbc-구현" class="hash-link" aria-label="Jdbc 구현에 대한 직접 링크" title="Jdbc 구현에 대한 직접 링크">​</a></h3><p>이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.<br> -<!-- -->미션 목표는 다음과 같다. </p><ul><li>JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.</li><li>데이터베이스에 대한 이해도를 높인다.</li></ul><p>최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="jdbctemplate">JdbcTemplate<a href="#jdbctemplate" class="hash-link" aria-label="JdbcTemplate에 대한 직접 링크" title="JdbcTemplate에 대한 직접 링크">​</a></h3><p>JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.<br> + <content type="html"><![CDATA[<admonition title="PR 링크" type="note"><p>1단계: <a href="https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267">https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267</a><br> +<!-- -->2단계: <a href="https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358">https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358</a><br> +<!-- -->3단계: <a href="https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448">https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448</a><br> +<!-- -->4단계: <a href="https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515">https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515</a></p></admonition> +<h3 id="jdbc-구현">Jdbc 구현</h3> +<p>이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.<br> +<!-- -->미션 목표는 다음과 같다.</p> +<ul> +<li>JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.</li> +<li>데이터베이스에 대한 이해도를 높인다.</li> +</ul> +<p>최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.</p> +<h3 id="jdbctemplate">JdbcTemplate</h3> +<p>JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.<br> <!-- -->템플릿 콜백 패턴을 적절하게 적용하여 중복을 비교적 간단하게 제거할 수 있었다.<br> -<!-- -->예전에도 미션을 진행하면서 <a href="/custom-jdbc-template">JdbcTemplate을 구현</a>한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">JdbcTemplate</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Logger</span><span class="token plain"> log </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">LoggerFactory</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLogger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">JdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> dataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">StatementCreator</span><span class="token plain"> statementCreator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">StatementExecutor</span><span class="token plain"> statementExecutor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">JdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> dataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">dataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">StatementCreator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">StatementExecutor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">JdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> dataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">StatementCreator</span><span class="token plain"> statementCreator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">StatementExecutor</span><span class="token plain"> statementExecutor</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">dataSource </span><span class="token operator">=</span><span class="token plain"> dataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">statementCreator </span><span class="token operator">=</span><span class="token plain"> statementCreator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">statementExecutor </span><span class="token operator">=</span><span class="token plain"> statementExecutor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token class-name">T</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> sql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">PreparedStatementCallback</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> preparedStatementCallback</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Object</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"> parameters</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Connection</span><span class="token plain"> connection </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">DataSourceUtils</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getConnection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">dataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">try</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">PreparedStatement</span><span class="token plain"> preparedStatement </span><span class="token operator">=</span><span class="token plain"> statementCreator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">create</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">connection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> sql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> preparedStatementCallback</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">execute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">preparedStatement</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">SQLException</span><span class="token plain"> e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throw</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">DataAccessException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">finally</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">DataSourceUtils</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">releaseConnection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">connection</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> dataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">update</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> sql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Object</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">sql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">PreparedStatement</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">executeUpdate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token class-name">Optional</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">queryForObject</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> sql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">RowMapper</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> rowMapper</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Object</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> results </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">sql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> statement </span><span class="token operator">-></span><span class="token plain"> statementExecutor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">execute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">statement</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> rowMapper</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">results</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">size</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">></span><span class="token plain"> </span><span class="token number">1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throw</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">DataAccessException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"2개 이상의 결과를 반환할 수 없습니다."</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> results</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">findAny</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">queryForList</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> sql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">RowMapper</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">T</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> rowMapper</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Object</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">sql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> statement </span><span class="token operator">-></span><span class="token plain"> statementExecutor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">execute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">statement</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> rowMapper</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> parameters</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="트랜잭션-적용">트랜잭션 적용<a href="#트랜잭션-적용" class="hash-link" aria-label="트랜잭션 적용에 대한 직접 링크" title="트랜잭션 적용에 대한 직접 링크">​</a></h3><p>3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.<br> +<!-- -->예전에도 미션을 진행하면서 <a href="https://greeng00se.github.io/custom-jdbc-template">JdbcTemplate을 구현</a>한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.</p> +<pre><code class="language-java">public class JdbcTemplate { + + private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class); + + private final DataSource dataSource; + private final StatementCreator statementCreator; + private final StatementExecutor statementExecutor; + + public JdbcTemplate(final DataSource dataSource) { + this(dataSource, new StatementCreator(), new StatementExecutor()); + } + + JdbcTemplate( + final DataSource dataSource, + final StatementCreator statementCreator, + final StatementExecutor statementExecutor + ) { + this.dataSource = dataSource; + this.statementCreator = statementCreator; + this.statementExecutor = statementExecutor; + } + + private <T> T query( + final String sql, + final PreparedStatementCallback<T> preparedStatementCallback, + final Object... parameters + ) { + final Connection connection = DataSourceUtils.getConnection(dataSource); + try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) { + return preparedStatementCallback.execute(preparedStatement); + } catch (final SQLException e) { + log.error(e.getMessage(), e); + throw new DataAccessException(e); + } finally { + DataSourceUtils.releaseConnection(connection, dataSource); + } + } + + public void update(final String sql, final Object... parameters) { + query(sql, PreparedStatement::executeUpdate, parameters); + } + + public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) { + final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters); + if (results.size() > 1) { + throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다."); + } + return results.stream().findAny(); + } + + public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) { + return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters); + } +} +</code></pre> +<h3 id="트랜잭션-적용">트랜잭션 적용</h3> +<p>3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.<br> <!-- -->트랜잭션 동기화란 트랜잭션을 시작하기 위한 Connection 객체를 ThreadLocal과 같은 공간에 따로 저장 후, 필요할 때 저장된 Connection을 가져다 사용하는 방식이다.<br> -<!-- -->아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="마무리">마무리<a href="#마무리" class="hash-link" aria-label="마무리에 대한 직접 링크" title="마무리에 대한 직접 링크">​</a></h3><p>Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.<br> +<!-- -->아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.</p> +<mermaid value="graph LR + TransactionTemplate --> TransactionManager + TransactionManager --> TransactionSynchronizationManager + DataSourceUtils --> TransactionSynchronizationManager + JdbcTemplate --> DataSourceUtils"></mermaid> +<h3 id="마무리">마무리</h3> +<p>Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.<br> <!-- -->꼼꼼히 코드를 봐준 리뷰어 호이 그리고 연휴 동안 계속 티키타카 하면서 재밌게 리뷰한 민트에게 감사하다.<br> <!-- -->회고 이만 끝내고 리팩터링 미션 하러가야겠다. 😊</p>]]></content> <category label="Woowahan Techcourse" term="Woowahan Techcourse"/> @@ -63,15 +171,89 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/mvc-retrospective"/> <updated>2023-10-07T00:00:00.000Z</updated> <summary type="html"><![CDATA[1단계//github.com/woowacourse/jwp-dashboard-mvc/pull/404]]></summary> - <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>PR 링크</div><div class="admonitionContent_S0QG"><p>1단계: <a href="https://github.com/woowacourse/jwp-dashboard-mvc/pull/404" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-mvc/pull/404</a><br> -<!-- -->2단계: <a href="https://github.com/woowacourse/jwp-dashboard-mvc/pull/465" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-mvc/pull/465</a><br> -<!-- -->3단계: <a href="https://github.com/woowacourse/jwp-dashboard-mvc/pull/580" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-mvc/pull/580</a> </p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="mvc-구현">MVC 구현<a href="#mvc-구현" class="hash-link" aria-label="MVC 구현에 대한 직접 링크" title="MVC 구현에 대한 직접 링크">​</a></h3><p>Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.<br> -<!-- -->미션의 목표는 다음과 같았다.</p><ul><li>MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.</li><li>점진적인 리팩토링을 경험한다.</li></ul><p>미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="애너테이션-기반-프레임워크-만들기">애너테이션 기반 프레임워크 만들기<a href="#애너테이션-기반-프레임워크-만들기" class="hash-link" aria-label="애너테이션 기반 프레임워크 만들기에 대한 직접 링크" title="애너테이션 기반 프레임워크 만들기에 대한 직접 링크">​</a></h3><p>기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.<br> + <content type="html"><![CDATA[<admonition title="PR 링크" type="note"><p>1단계: <a href="https://github.com/woowacourse/jwp-dashboard-mvc/pull/404">https://github.com/woowacourse/jwp-dashboard-mvc/pull/404</a><br> +<!-- -->2단계: <a href="https://github.com/woowacourse/jwp-dashboard-mvc/pull/465">https://github.com/woowacourse/jwp-dashboard-mvc/pull/465</a><br> +<!-- -->3단계: <a href="https://github.com/woowacourse/jwp-dashboard-mvc/pull/580">https://github.com/woowacourse/jwp-dashboard-mvc/pull/580</a></p></admonition> +<h3 id="mvc-구현">MVC 구현</h3> +<p>Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.<br> +<!-- -->미션의 목표는 다음과 같았다.</p> +<ul> +<li>MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.</li> +<li>점진적인 리팩토링을 경험한다.</li> +</ul> +<p>미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.</p> +<h3 id="애너테이션-기반-프레임워크-만들기">애너테이션 기반 프레임워크 만들기</h3> +<p>기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.<br> <!-- -->테오가 @GetMapping이나 @PostMapping 부분도 진행하면 재밌을 것 같다고 해서 같이 진행해 보았다.<br> -<!-- -->추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다. </p><p>다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다. </p><ol><li>@Controller가 적용된 클래스의 정보를 스캔하여 반환한다. </li><li>@Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다. </li><li>각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다. </li></ol><p>AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">AnnotationHandlerMapping</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">initialize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token plain">initialized</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">compareAndSet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Map</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Class</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics operator">?</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token generics"> </span><span class="token generics class-name">ControllerInstance</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> controllers </span><span class="token operator">=</span><span class="token plain"> annotationScanner</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">scanControllers</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Set</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Method</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> methods </span><span class="token operator">=</span><span class="token plain"> annotationScanner</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">scanHttpMappingMethods</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">controllers</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">keySet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Method</span><span class="token plain"> method </span><span class="token operator">:</span><span class="token plain"> methods</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">ControllerInstance</span><span class="token plain"> controller </span><span class="token operator">=</span><span class="token plain"> controllers</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">method</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getDeclaringClass</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">HandlerExecution</span><span class="token plain"> handlerExecution </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">HandlerExecution</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">controller</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getInstance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> method</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">HandlerKey</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> handlerKeys </span><span class="token operator">=</span><span class="token plain"> handlerKeyGenerator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">generate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">controller</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getUriPrefix</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> method</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> handlerKeys</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">forEach</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">handlerKey </span><span class="token operator">-></span><span class="token plain"> handlerExecutions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">put</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">handlerKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> handlerExecution</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">info</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"Initialized AnnotationHandlerMapping!"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> handlerExecutions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">keySet</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">forEach</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">key </span><span class="token operator">-></span><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">info</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"key: {}, Handler: {}"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> key</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> handlerExecutions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">key</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="legacy-mvc와-mvc-통합">Legacy MVC와 @MVC 통합<a href="#legacy-mvc와-mvc-통합" class="hash-link" aria-label="Legacy MVC와 @MVC 통합에 대한 직접 링크" title="Legacy MVC와 @MVC 통합에 대한 직접 링크">​</a></h3><p>2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.<br> +<!-- -->추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.</p> +<mermaid value="graph LR + AHM[AnnotationHandlerMapping] --> AS[AnnotationScanner] + AHM --> HKG[HandlerKeyGenerator] --> HMAP[HttpMappingAnnotationParser]"></mermaid> +<p>다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.</p> +<ol> +<li>@Controller가 적용된 클래스의 정보를 스캔하여 반환한다.</li> +<li>@Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.</li> +<li>각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 <code>Map<HandlerKey, HandlerExecution></code>에 추가한다.</li> +</ol> +<p>AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.</p> +<pre><code class="language-java" metastring="title=AnnotationHandlerMapping">public void initialize() { + if (!initialized.compareAndSet(false, true)) { + return; + } + + final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers(); + final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet()); + for (final Method method : methods) { + final ControllerInstance controller = controllers.get(method.getDeclaringClass()); + final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method); + final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method); + handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution)); + } + + log.info("Initialized AnnotationHandlerMapping!"); + handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key))); +} +</code></pre> +<h3 id="legacy-mvc와-mvc-통합">Legacy MVC와 @MVC 통합</h3> +<p>2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.<br> <!-- -->기존의 MVC와 애너테이션이 적용된 MVC 두 개를 같이 사용할 수 있어야 헀다.<br> -<!-- -->대략적인 흐름은 다음과 같다. </p><ol><li>DispatcherServlet.service(request, response) 호출</li><li>HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회</li><li>HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회</li><li>HandlerAdapter의.handle 메서드 실행</li><li>View의 render 호출</li></ol><h3 class="anchor anchorWithStickyNavbar_LWe7" id="웹-애플리케이션-발전-과정">웹 애플리케이션 발전 과정<a href="#웹-애플리케이션-발전-과정" class="hash-link" aria-label="웹 애플리케이션 발전 과정에 대한 직접 링크" title="웹 애플리케이션 발전 과정에 대한 직접 링크">​</a></h3><p>웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.<br> -<!-- -->간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.</p><p>내용이 길어져서 <a href="/web-application-evolution">다음 문서</a>에 정리했다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="추상적인-개념-학습-방법">추상적인 개념 학습 방법<a href="#추상적인-개념-학습-방법" class="hash-link" aria-label="추상적인 개념 학습 방법에 대한 직접 링크" title="추상적인 개념 학습 방법에 대한 직접 링크">​</a></h3><p>직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.</p><table><thead><tr><th>개념</th><th>구현</th></tr></thead><tbody><tr><td>OOP</td><td>Java</td></tr><tr><td>WAS</td><td>Tomcat, Jetty</td></tr><tr><td>IoC</td><td>Spring BeanFactory, Servlet Container, Framework</td></tr><tr><td>DI</td><td>Spring BeanFactory</td></tr></tbody></table><h3 class="anchor anchorWithStickyNavbar_LWe7" id="정리">정리<a href="#정리" class="hash-link" aria-label="정리에 대한 직접 링크" title="정리에 대한 직접 링크">​</a></h3><p>지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.<br> +<!-- -->대략적인 흐름은 다음과 같다.</p> +<ol> +<li>DispatcherServlet.service(request, response) 호출</li> +<li>HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회</li> +<li>HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회</li> +<li>HandlerAdapter의.handle 메서드 실행</li> +<li>View의 render 호출</li> +</ol> +<mermaid value="graph LR + D[DispatcherServlet] + D --> HMS[HandlerMappings] + D --> HAS[HandlerAdapters] + + HMS --> HandlerMapping + subgraph HandlerMapping + direction BT + AHM[AnnotationHandlerMapping] --> HM[HandlerMapping] + MHM[ManualHandlerMapping] --> HM + end + + HAS --> HandlerAdapter + subgraph HandlerAdapter + direction BT + HEHA[HandlerExecutionHandlerAdapter] --> HA[HandlerAdapter] + CHA[ControllerHandlerAdapter] --> HA + end"></mermaid> +<h3 id="웹-애플리케이션-발전-과정">웹 애플리케이션 발전 과정</h3> +<p>웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.<br> +<!-- -->간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.</p> +<mermaid value="graph LR + WWW --> CGI(Common Gateway Interface) --> Servlet --> JSP --> MVC --> Framework --> Non-Blocking"></mermaid> +<p>내용이 길어져서 <a href="https://greeng00se.github.io/web-application-evolution">다음 문서</a>에 정리했다.</p> +<h3 id="추상적인-개념-학습-방법">추상적인 개념 학습 방법</h3> +<p>직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.</p> +<table><thead><tr><th>개념</th><th>구현</th></tr></thead><tbody><tr><td>OOP</td><td>Java</td></tr><tr><td>WAS</td><td>Tomcat, Jetty</td></tr><tr><td>IoC</td><td>Spring BeanFactory, Servlet Container, Framework</td></tr><tr><td>DI</td><td>Spring BeanFactory</td></tr></tbody></table> +<h3 id="정리">정리</h3> +<p>지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.<br> <!-- -->이번 미션에서 나의 리뷰어는 루카, 리뷰이는 헤나였다.<br> <!-- -->매 단계마다 꼼꼼하게 리뷰해 준 루카에게 너무 감사하고, 헤나에게 이상한 리뷰를 많이 남긴 것 같은데 꼼꼼히 반영해줘서 감사하다.<br> <!-- -->오랫동안 기다려왔던 레벨 4 미션이 하나씩 마무리 될 때 마다 아쉬움이 남는다.</p>]]></content> @@ -84,18 +266,88 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/spring-test-isolation"/> <updated>2023-10-03T00:00:00.000Z</updated> <summary type="html"><![CDATA[테스트 격리]]></summary> - <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="테스트-격리">테스트 격리<a href="#테스트-격리" class="hash-link" aria-label="테스트 격리에 대한 직접 링크" title="테스트 격리에 대한 직접 링크">​</a></h3><p>테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 <code>@DirtiesContext</code>, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 <code>@Transactional</code>등 다양한 방법이 있다.<br> -<!-- -->해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Independent - FIRST</div><div class="admonitionContent_S0QG"><p>테스트끼리 서로 의존하면 안 된다.<br> + <content type="html"><![CDATA[<h3 id="테스트-격리">테스트 격리</h3> +<p>테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 <code>@DirtiesContext</code>, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 <code>@Transactional</code>등 다양한 방법이 있다.<br> +<!-- -->해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.</p> +<admonition title="Independent - FIRST" type="note"><p>테스트끼리 서로 의존하면 안 된다.<br> <!-- -->서로 의존하게 된다면 하나의 테스트가 실패할 때, 또 다른 하나의 테스트가 실패할 수 있다.<br> -<!-- -->다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다. </p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="testexecutionlistener">TestExecutionListener<a href="#testexecutionlistener" class="hash-link" aria-label="TestExecutionListener에 대한 직접 링크" title="TestExecutionListener에 대한 직접 링크">​</a></h3><p>스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.<br> -<!-- -->이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">TextExecutionListner</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">interface</span><span class="token plain"> </span><span class="token class-name">TestExecutionListener</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">beforeTestClass</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">prepareTestInstance</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">beforeTestMethod</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">beforeTestExecution</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">afterTestExecution</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">afterTestMethod</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">afterTestClass</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throws</span><span class="token plain"> </span><span class="token class-name">Exception</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="abstracttestexecutionlistener-상속하여-구현">AbstractTestExecutionListener 상속하여 구현<a href="#abstracttestexecutionlistener-상속하여-구현" class="hash-link" aria-label="AbstractTestExecutionListener 상속하여 구현에 대한 직접 링크" title="AbstractTestExecutionListener 상속하여 구현에 대한 직접 링크">​</a></h3><p>AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.<br> -<!-- -->다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">DatabaseCleaner</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">DatabaseCleaner</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">AbstractTestExecutionListener</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TRUNCATE_TABLE_QUERY</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)">"""</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)"> SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)"> FROM INFORMATION_SCHEMA.TABLES</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)"> WHERE TABLE_SCHEMA = 'PUBLIC'</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)"> """</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">afterTestMethod</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">JdbcTemplate</span><span class="token plain"> jdbcTemplate </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getJdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">String</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> truncateTableQueries </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getTruncateTableQueries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">jdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">truncateTables</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">jdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> truncateTableQueries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token class-name">JdbcTemplate</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getJdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TestContext</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> testContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getApplicationContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getBean</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">JdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">String</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getTruncateTableQueries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">JdbcTemplate</span><span class="token plain"> jdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> jdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">queryForList</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">TRUNCATE_TABLE_QUERY</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">truncateTables</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">JdbcTemplate</span><span class="token plain"> jdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">String</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> truncateTableQueries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> jdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">execute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"SET REFERENTIAL_INTEGRITY FALSE"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> truncateTableQueries</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">forEach</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">jdbcTemplate</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">execute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> jdbcTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">execute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"SET REFERENTIAL_INTEGRITY TRUE"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="listener-등록">Listener 등록<a href="#listener-등록" class="hash-link" aria-label="Listener 등록에 대한 직접 링크" title="Listener 등록에 대한 직접 링크">​</a></h3><p>@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.<br> +<!-- -->다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.</p></admonition> +<h3 id="testexecutionlistener">TestExecutionListener</h3> +<p>스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.<br> +<!-- -->이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.</p> +<pre><code class="language-java" metastring="title=TextExecutionListner">public interface TestExecutionListener { + default void beforeTestClass(TestContext testContext) throws Exception {} + default void prepareTestInstance(TestContext testContext) throws Exception {} + default void beforeTestMethod(TestContext testContext) throws Exception {} + default void beforeTestExecution(TestContext testContext) throws Exception {} + default void afterTestExecution(TestContext testContext) throws Exception {} + default void afterTestMethod(TestContext testContext) throws Exception {} + default void afterTestClass(TestContext testContext) throws Exception {} +} +</code></pre> +<h3 id="abstracttestexecutionlistener-상속하여-구현">AbstractTestExecutionListener 상속하여 구현</h3> +<p>AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.<br> +<!-- -->다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.</p> +<pre><code class="language-java" metastring="title=DatabaseCleaner"> +public class DatabaseCleaner extends AbstractTestExecutionListener { + + private static final String TRUNCATE_TABLE_QUERY = """ + SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = 'PUBLIC' + """; + + @Override + public void afterTestMethod(TestContext testContext) { + JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext); + List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate); + truncateTables(jdbcTemplate, truncateTableQueries); + } + + private JdbcTemplate getJdbcTemplate(TestContext testContext) { + return testContext.getApplicationContext().getBean(JdbcTemplate.class); + } + + private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) { + return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class); + } + + private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) { + jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE"); + truncateTableQueries.forEach(jdbcTemplate::execute); + jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE"); + } +} + +</code></pre> +<h3 id="listener-등록">Listener 등록</h3> +<p>@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.<br> <!-- -->mergeMode의 기본값은 REPLACE_DEFAULTS로 리스너가 이미 존재하는 경우 등록된 리스너로 변경된다.<br> <!-- -->MERGE_WITH_DEFAULTS로 설정한다면 Ordered 기준으로 순서가 결정된다.<br> -<!-- -->이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">AcceptanceTest</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@SpringBootTest</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">webEnvironment </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">SpringBootTest</span><span class="token class-name punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token class-name">WebEnvironment</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">RANDOM_PORT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@TestExecutionListeners</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> value </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">DatabaseCleaner</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> mergeMode </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">TestExecutionListeners</span><span class="token class-name punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token class-name">MergeMode</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">MERGE_WITH_DEFAULTS</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">abstract</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">AcceptanceTest</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@LocalServerPort</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@BeforeEach</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">setUp</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">RestAssured</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">port </span><span class="token operator">=</span><span class="token plain"> port</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h3><p><a href="https://www.baeldung.com/spring-testexecutionlistener" target="_blank" rel="noopener noreferrer">The Spring TestExecutionListener, Baeldung</a><br> -<a href="https://tecoble.techcourse.co.kr/post/2020-09-15-test-isolation/" target="_blank" rel="noopener noreferrer">인수테스트에서 테스트 격리하기, 테코블</a><br> -<a href="https://martinfowler.com/articles/nonDeterminism.html" target="_blank" rel="noopener noreferrer">Eradicating Non-Determinism in Tests, martin fowler</a><br> -<a href="https://mangkyu.tistory.com/264" target="_blank" rel="noopener noreferrer">@SpringBootTest의 테스트 격리시키기, MangKyu</a></p>]]></content> +<!-- -->이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.</p> +<pre><code class="language-java" metastring="title=AcceptanceTest"> +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@TestExecutionListeners( + value = DatabaseCleaner.class, + mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS +) +public abstract class AcceptanceTest { + + @LocalServerPort + private int port; + + @BeforeEach + public void setUp() { + RestAssured.port = port; + } +} + +</code></pre> +<h3 id="참고-자료">참고 자료</h3> +<p><a href="https://www.baeldung.com/spring-testexecutionlistener">The Spring TestExecutionListener, Baeldung</a><br> +<a href="https://tecoble.techcourse.co.kr/post/2020-09-15-test-isolation/">인수테스트에서 테스트 격리하기, 테코블</a><br> +<a href="https://martinfowler.com/articles/nonDeterminism.html">Eradicating Non-Determinism in Tests, martin fowler</a><br> +<a href="https://mangkyu.tistory.com/264">@SpringBootTest의 테스트 격리시키기, MangKyu</a></p>]]></content> <category label="test" term="test"/> </entry> <entry> @@ -104,29 +356,66 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/web-application-evolution"/> <updated>2023-09-30T00:00:00.000Z</updated> <summary type="html"><![CDATA[웹 애플리케이션 발전 과정]]></summary> - <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="웹-애플리케이션-발전-과정">웹 애플리케이션 발전 과정<a href="#웹-애플리케이션-발전-과정" class="hash-link" aria-label="웹 애플리케이션 발전 과정에 대한 직접 링크" title="웹 애플리케이션 발전 과정에 대한 직접 링크">​</a></h3><p>웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.<br> + <content type="html"><![CDATA[<h3 id="웹-애플리케이션-발전-과정">웹 애플리케이션 발전 과정</h3> +<p>웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.<br> <!-- -->간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.<br> -<!-- -->원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="www1989">WWW(1989)<a href="#www1989" class="hash-link" aria-label="WWW(1989)에 대한 직접 링크" title="WWW(1989)에 대한 직접 링크">​</a></h3><p>정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="cgi1993">CGI(1993)<a href="#cgi1993" class="hash-link" aria-label="CGI(1993)에 대한 직접 링크" title="CGI(1993)에 대한 직접 링크">​</a></h3><p>CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="servlet1996">Servlet(1996)<a href="#servlet1996" class="hash-link" aria-label="Servlet(1996)에 대한 직접 링크" title="Servlet(1996)에 대한 직접 링크">​</a></h3><p>Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.<br> -<!-- -->하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="jsp1999">JSP(1999)<a href="#jsp1999" class="hash-link" aria-label="JSP(1999)에 대한 직접 링크" title="JSP(1999)에 대한 직접 링크">​</a></h3><p>JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.<br> -<!-- -->JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="mvc2000">MVC(2000)<a href="#mvc2000" class="hash-link" aria-label="MVC(2000)에 대한 직접 링크" title="MVC(2000)에 대한 직접 링크">​</a></h3><p>위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다. </p><blockquote><p>I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.<br> -<!-- -->Govind Seshadri</p></blockquote><p>이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.<br> -<a href="https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html" target="_blank" rel="noopener noreferrer">해당 문서</a>를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="spring-framework2003">Spring Framework(2003)<a href="#spring-framework2003" class="hash-link" aria-label="Spring Framework(2003)에 대한 직접 링크" title="Spring Framework(2003)에 대한 직접 링크">​</a></h3><p>Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.<br> +<!-- -->원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.</p> +<mermaid value="graph LR + WWW --> CGI(Common Gateway Interface) --> Servlet --> JSP --> MVC --> Framework --> Non-Blocking"></mermaid> +<h3 id="www1989">WWW(1989)</h3> +<p>정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.</p> +<h3 id="cgi1993">CGI(1993)</h3> +<p>CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.</p> +<h3 id="servlet1996">Servlet(1996)</h3> +<p>Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.<br> +<!-- -->하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.</p> +<h3 id="jsp1999">JSP(1999)</h3> +<p>JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.<br> +<!-- -->JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.</p> +<mermaid value="--- +title: JSP Model 2 +--- +graph LR + Client -- Request --> Servlet <-- JDBC --> Database + Servlet --> Bean + Servlet --> JSP + Bean <--> JSP + JSP -- Response --> Client"></mermaid> +<h3 id="mvc2000">MVC(2000)</h3> +<p>위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.</p> +<blockquote> +<p>I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.<br> +<!-- -->Govind Seshadri</p> +</blockquote> +<p>이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.<br> +<a href="https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html">해당 문서</a>를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.</p> +<h3 id="spring-framework2003">Spring Framework(2003)</h3> +<p>Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.<br> <!-- -->J2EE는 웹 기반의 엔터프라이즈 애플리케이션을 구축하기 위한 플랫폼으로 위에서 설명한 Servlet, JSP, EJB 등의 기술을 포함하고 있다.<br> <!-- -->하지만 이중 EJB라는 기술이 J2EE의 핵심 기술이었는데, 해당 기술이 매우 복잡했기 때문에 사용에 문제가 많았다고 한다.<br> -<!-- -->2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 <code>Expert One-to-One J2EE Development</code>라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다. </p><p>스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="webflux-이전-servlet-302009-312013">WebFlux 이전 Servlet 3.0(2009), 3.1(2013)<a href="#webflux-이전-servlet-302009-312013" class="hash-link" aria-label="WebFlux 이전 Servlet 3.0(2009), 3.1(2013)에 대한 직접 링크" title="WebFlux 이전 Servlet 3.0(2009), 3.1(2013)에 대한 직접 링크">​</a></h3><p>Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.<br> -<!-- -->그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="spring-webflux2017">Spring WebFlux(2017)<a href="#spring-webflux2017" class="hash-link" aria-label="Spring WebFlux(2017)에 대한 직접 링크" title="Spring WebFlux(2017)에 대한 직접 링크">​</a></h3><p>적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.<br> -<!-- -->추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="마치며">마치며<a href="#마치며" class="hash-link" aria-label="마치며에 대한 직접 링크" title="마치며에 대한 직접 링크">​</a></h3><p>해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.<br> -<!-- -->그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h3><p>웹 애플리케이션의 발전 과정, 구구 강의<br> -<a href="https://httpd.apache.org/docs/trunk/en/howto/cgi.html" target="_blank" rel="noopener noreferrer">Dynamic Content with CGI, Apache Tutorial</a><br> -<a href="https://docs.spring.io/spring-framework/reference/overview.html#overview-history" target="_blank" rel="noopener noreferrer">History of Spring and the Spring Framework, Spring</a><br> -<a href="https://www.infoworld.com/article/2076557/understanding-javaserver-pages-model-2-architecture.html" target="_blank" rel="noopener noreferrer">Understanding JavaServer Pages Model 2 architecture, Govind Seshadri</a><br> -<a href="https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html" target="_blank" rel="noopener noreferrer">MVC, XEROX PARC</a><br> -<a href="https://www.amazon.com/Expert-One-One-Development-without/dp/0764558315" target="_blank" rel="noopener noreferrer">Expert One-to-One J2EE Development, Rod Johnson</a><br> -<a href="https://techblog.woowahan.com/2667/" target="_blank" rel="noopener noreferrer">배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족</a><br> -<a href="https://www.infoworld.com/article/2077995/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html" target="_blank" rel="noopener noreferrer">Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu</a> -<a href="https://docs.spring.io/spring-framework/reference/web/webflux/new-framework.html" target="_blank" rel="noopener noreferrer">WebFlux Overview, Spring</a> -<a href="https://d2.naver.com/helloworld/6080222" target="_blank" rel="noopener noreferrer">Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2</a><br> -<a href="https://tweety1121.tistory.com/entry/Spring-WebFlux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C" target="_blank" rel="noopener noreferrer">Spring WebFlux란 무엇일까</a></p>]]></content> +<!-- -->2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 <code>Expert One-to-One J2EE Development</code>라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.</p> +<p>스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.</p> +<h3 id="webflux-이전-servlet-302009-312013">WebFlux 이전 Servlet 3.0(2009), 3.1(2013)</h3> +<p>Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.<br> +<!-- -->그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.</p> +<h3 id="spring-webflux2017">Spring WebFlux(2017)</h3> +<p>적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.<br> +<!-- -->추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.</p> +<h3 id="마치며">마치며</h3> +<p>해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.<br> +<!-- -->그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.</p> +<h3 id="참고-자료">참고 자료</h3> +<p>웹 애플리케이션의 발전 과정, 구구 강의<br> +<a href="https://httpd.apache.org/docs/trunk/en/howto/cgi.html">Dynamic Content with CGI, Apache Tutorial</a><br> +<a href="https://docs.spring.io/spring-framework/reference/overview.html#overview-history">History of Spring and the Spring Framework, Spring</a><br> +<a href="https://www.infoworld.com/article/2076557/understanding-javaserver-pages-model-2-architecture.html">Understanding JavaServer Pages Model 2 architecture, Govind Seshadri</a><br> +<a href="https://folk.universitetetioslo.no/trygver/themes/mvc/mvc-index.html">MVC, XEROX PARC</a><br> +<a href="https://www.amazon.com/Expert-One-One-Development-without/dp/0764558315">Expert One-to-One J2EE Development, Rod Johnson</a><br> +<a href="https://techblog.woowahan.com/2667/">배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족</a><br> +<a href="https://www.infoworld.com/article/2077995/java-concurrency-asynchronous-processing-support-in-servlet-3-0.html">Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu</a> +<a href="https://docs.spring.io/spring-framework/reference/web/webflux/new-framework.html">WebFlux Overview, Spring</a> +<a href="https://d2.naver.com/helloworld/6080222">Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2</a><br> +<a href="https://tweety1121.tistory.com/entry/Spring-WebFlux-%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C">Spring WebFlux란 무엇일까</a></p>]]></content> <category label="web application" term="web application"/> </entry> <entry> @@ -135,15 +424,90 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/log-async-exception"/> <updated>2023-09-18T00:00:00.000Z</updated> <summary type="html"><![CDATA[문제 상황]]></summary> - <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="문제-상황">문제 상황<a href="#문제-상황" class="hash-link" aria-label="문제 상황에 대한 직접 링크" title="문제 상황에 대한 직접 링크">​</a></h3><p>현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 <code>@Async</code>가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.<br> -<!-- -->확인해 보니 Spring의 <code>@ControllerAdvice</code> + <code>@ExceptionHandler</code>의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="비동기-예외-발생시-로깅-설정">비동기 예외 발생시 로깅 설정<a href="#비동기-예외-발생시-로깅-설정" class="hash-link" aria-label="비동기 예외 발생시 로깅 설정에 대한 직접 링크" title="비동기 예외 발생시 로깅 설정에 대한 직접 링크">​</a></h3><p>스프링 4.1 부터 제공되는 <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html" target="_blank" rel="noopener noreferrer">AsyncUncaughtExceptionHandler</a>의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다. </p><p>따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.<br> + <content type="html"><![CDATA[<h3 id="문제-상황">문제 상황</h3> +<p>현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 <code>@Async</code>가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.<br> +<!-- -->확인해 보니 Spring의 <code>@ControllerAdvice</code> + <code>@ExceptionHandler</code>의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.</p> +<h3 id="비동기-예외-발생시-로깅-설정">비동기 예외 발생시 로깅 설정</h3> +<p>스프링 4.1 부터 제공되는 <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html">AsyncUncaughtExceptionHandler</a>의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.</p> +<p>따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.<br> <!-- -->기존의 동기 예외 처리의 경우 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다.<br> -<!-- -->비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">AsyncExceptionHandler</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Slf4j</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">AsyncExceptionHandler</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">implements</span><span class="token plain"> </span><span class="token class-name">AsyncUncaughtExceptionHandler</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">LOG_FORMAT</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"[%s] %s"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">handleUncaughtException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Throwable</span><span class="token plain"> throwable</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Method</span><span class="token plain"> method</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Object</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"> obj</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">info</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">format</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">LOG_FORMAT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">MDC</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">REQUEST_ID</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">key</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> throwable</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> throwable</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.<br> -<!-- -->getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">AsyncConfig</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@EnableAsync</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">AsyncConfig</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">implements</span><span class="token plain"> </span><span class="token class-name">AsyncConfigurer</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">AsyncUncaughtExceptionHandler</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getAsyncUncaughtExceptionHandler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">AsyncExceptionHandler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="mdc-정보-연동-문제">MDC 정보 연동 문제<a href="#mdc-정보-연동-문제" class="hash-link" aria-label="MDC 정보 연동 문제에 대한 직접 링크" title="MDC 정보 연동 문제에 대한 직접 링크">​</a></h3><p>비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다. </p><p><img loading="lazy" alt="./mdc-null.png" src="/assets/images/mdc-null-95b3bbdce99ef36ba843986413e0421a.png" width="2236" height="426" class="img_ev3q"></p><p>스프링 4.3 이상부터 제공되는 <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html" target="_blank" rel="noopener noreferrer">TaskDecorator</a>를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">MdcTaskDecorator</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">MdcTaskDecorator</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">implements</span><span class="token plain"> </span><span class="token class-name">TaskDecorator</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">Runnable</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">decorate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Runnable</span><span class="token plain"> runnable</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">Map</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">String</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token generics"> </span><span class="token generics class-name">String</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> threadContext </span><span class="token operator">=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">MDC</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getCopyOfContextMap</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-></span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">MDC</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setContextMap</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">threadContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> runnable</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">run</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>생성한 Decorator 클래스를 설정 파일에 등록해 준다.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">AsyncConfig</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@RequiredArgsConstructor</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@EnableAsync</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">AsyncConfig</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">implements</span><span class="token plain"> </span><span class="token class-name">AsyncConfigurer</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">AsyncConfigurationProperties</span><span class="token plain"> properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Bean</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">ThreadPoolTaskExecutor</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">taskExecutor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">ThreadPoolTaskExecutor</span><span class="token plain"> executor </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">ThreadPoolTaskExecutor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> executor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setCorePoolSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">coreSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> executor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setMaxPoolSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">maxSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> executor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setQueueCapacity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">properties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">queueCapacity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><br></span><span class="token-line theme-code-block-highlighted-line" style="color:#F8F8F2"><span class="token plain"> executor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setTaskDecorator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">MdcTaskDecorator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> executor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setWaitForTasksToCompleteOnShutdown</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> executor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">initialize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> executor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">AsyncUncaughtExceptionHandler</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getAsyncUncaughtExceptionHandler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">AsyncExceptionHandler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.</p><p><img loading="lazy" alt="./mdc-not-null.png" src="/assets/images/mdc-not-null-2b12c13f4f420a335c9e55dbea503f1b.png" width="2620" height="440" class="img_ev3q"></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h3><p><a href="https://www.baeldung.com/spring-async" target="_blank" rel="noopener noreferrer">spring async, baeldung</a><br> -<a href="https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception" target="_blank" rel="noopener noreferrer">@Async will not call by @ControllerAdvice for global exception</a><br> -<a href="https://blog.gangnamunni.com/post/mdc-context-task-decorator/" target="_blank" rel="noopener noreferrer">Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니</a><br> -<a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html" target="_blank" rel="noopener noreferrer">TaskDecorator, Spring docs</a><br> -<a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html" target="_blank" rel="noopener noreferrer">AsyncUncaughtExceptionHandler</a></p>]]></content> +<!-- -->비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.</p> +<pre><code class="language-java" metastring="title=AsyncExceptionHandler">@Slf4j +public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler { + + private static final String LOG_FORMAT = "[%s] %s"; + + @Override + public void handleUncaughtException(Throwable throwable, Method method, Object... obj) { + log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable); + } +} +</code></pre> +<p>AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.<br> +<!-- -->getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.</p> +<pre><code class="language-java" metastring="title=AsyncConfig">@EnableAsync +@Configuration +public class AsyncConfig implements AsyncConfigurer { + + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return new AsyncExceptionHandler(); + } +} +</code></pre> +<p>이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.</p> +<h3 id="mdc-정보-연동-문제">MDC 정보 연동 문제</h3> +<p>비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.</p> +<p><img alt="./mdc-null.png" src="https://greeng00se.github.io/assets/images/mdc-null-95b3bbdce99ef36ba843986413e0421a.png" width="2236" height="426"></p> +<p>스프링 4.3 이상부터 제공되는 <a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html">TaskDecorator</a>를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.</p> +<pre><code class="language-java" metastring="title=MdcTaskDecorator">public class MdcTaskDecorator implements TaskDecorator { + + @Override + public Runnable decorate(final Runnable runnable) { + Map<String, String> threadContext = MDC.getCopyOfContextMap(); + return () -> { + MDC.setContextMap(threadContext); + runnable.run(); + }; + } +} +</code></pre> +<p>생성한 Decorator 클래스를 설정 파일에 등록해 준다.</p> +<pre><code class="language-java" metastring="title=AsyncConfig">@RequiredArgsConstructor +@EnableAsync +@Configuration +public class AsyncConfig implements AsyncConfigurer { + + private final AsyncConfigurationProperties properties; + + @Bean + public ThreadPoolTaskExecutor taskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(properties.coreSize()); + executor.setMaxPoolSize(properties.maxSize()); + executor.setQueueCapacity(properties.queueCapacity()); + + // highlight-next-line + executor.setTaskDecorator(new MdcTaskDecorator()); + executor.setWaitForTasksToCompleteOnShutdown(true); + executor.initialize(); + return executor; + } + + @Override + public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { + return new AsyncExceptionHandler(); + } +} +</code></pre> +<p>설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.</p> +<p><img alt="./mdc-not-null.png" src="https://greeng00se.github.io/assets/images/mdc-not-null-2b12c13f4f420a335c9e55dbea503f1b.png" width="2620" height="440"></p> +<h3 id="참고-자료">참고 자료</h3> +<p><a href="https://www.baeldung.com/spring-async">spring async, baeldung</a><br> +<a href="https://stackoverflow.com/questions/61885358/async-will-not-call-by-controlleradvice-for-global-exception">@Async will not call by @ControllerAdvice for global exception</a><br> +<a href="https://blog.gangnamunni.com/post/mdc-context-task-decorator/">Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니</a><br> +<a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/task/TaskDecorator.html">TaskDecorator, Spring docs</a><br> +<a href="https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/interceptor/AsyncUncaughtExceptionHandler.html">AsyncUncaughtExceptionHandler</a></p>]]></content> <category label="async" term="async"/> <category label="exception" term="exception"/> </entry> @@ -153,36 +517,206 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/tomcat-retrospective"/> <updated>2023-09-11T00:00:00.000Z</updated> <summary type="html"><![CDATA[1, 2단계//github.com/woowacourse/jwp-dashboard-http/pull/302]]></summary> - <content type="html"><![CDATA[<div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>PR 링크 </div><div class="admonitionContent_S0QG"><p>1, 2단계: <a href="https://github.com/woowacourse/jwp-dashboard-http/pull/302" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-http/pull/302</a><br> -<!-- -->3, 4단계: <a href="https://github.com/woowacourse/jwp-dashboard-http/pull/431" target="_blank" rel="noopener noreferrer">https://github.com/woowacourse/jwp-dashboard-http/pull/431</a></p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="톰캣-구현">톰캣 구현<a href="#톰캣-구현" class="hash-link" aria-label="톰캣 구현에 대한 직접 링크" title="톰캣 구현에 대한 직접 링크">​</a></h3><p>우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.<br> -<!-- -->그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다. </p><p>이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.<br> -<!-- -->톰캣 구현 미션은 <a href="https://datatracker.ietf.org/doc/html/rfc2616/" target="_blank" rel="noopener noreferrer">RFC 2616</a>에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="다이어그램">다이어그램<a href="#다이어그램" class="hash-link" aria-label="다이어그램에 대한 직접 링크" title="다이어그램에 대한 직접 링크">​</a></h3><p>Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.<br> + <content type="html"><![CDATA[<admonition title="PR 링크" type="note"><p>1, 2단계: <a href="https://github.com/woowacourse/jwp-dashboard-http/pull/302">https://github.com/woowacourse/jwp-dashboard-http/pull/302</a><br> +<!-- -->3, 4단계: <a href="https://github.com/woowacourse/jwp-dashboard-http/pull/431">https://github.com/woowacourse/jwp-dashboard-http/pull/431</a></p></admonition> +<h3 id="톰캣-구현">톰캣 구현</h3> +<p>우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.<br> +<!-- -->그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.</p> +<p>이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.<br> +<!-- -->톰캣 구현 미션은 <a href="https://datatracker.ietf.org/doc/html/rfc2616/">RFC 2616</a>에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.</p> +<h3 id="다이어그램">다이어그램</h3> +<p>Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.<br> <!-- -->사실 내부 구조를 깊게 공부할 시간을 가지지 못해서 각 구성 요소가 왜 해당 위치에 있는지 완벽하게 설명하지는 못하지만 미션을 진행하면서 이건 여기에 있으면 좋을 것 같은데? 라는 생각이 들면 적절한 패키지에 위치시키는 방향으로 진행을 했다.<br> -<!-- -->또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="코드-리뷰">코드 리뷰<a href="#코드-리뷰" class="hash-link" aria-label="코드 리뷰에 대한 직접 링크" title="코드 리뷰에 대한 직접 링크">​</a></h3><p>크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.<br> -<!-- -->나의 리뷰어는 디노, 리뷰이는 필립이었다. </p><p>디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.<br> +<!-- -->또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.</p> +<mermaid value="graph LR + subgraph coyote + HP[Http11Processor] --> A + HP --> HttpRequestParser + HP --> HttpResponseGenerator + A[Adapter] + end + + subgraph catalina + RA[RequestAdapter] -.-> A + AC[AbstractController] -.-> C[Controller] + StaticController -.-> AC + SM[SessionManger] -.-> Manager + TC[Tomcat] --> RA + RA --> C + RA --> Manager + RA --> RM + RM[RequestMapper] --> C + end + + subgraph jwp + LC[LoginController] -.-> AC + Application --> TC + end +"></mermaid> +<h3 id="코드-리뷰">코드 리뷰</h3> +<p>크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.<br> +<!-- -->나의 리뷰어는 디노, 리뷰이는 필립이었다.</p> +<p>디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.<br> <!-- -->한 가지 아쉬운 점은 필립에게 작성한 나의 코멘트들이 미션을 진행하면서 경험 기반으로 작성한 내용이 많아 근거가 조금 부족했고, 정리되지 않은 부분이 많았던 것 같다.<br> -<!-- -->다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="sessionconfig">SessionConfig<a href="#sessionconfig" class="hash-link" aria-label="SessionConfig에 대한 직접 링크" title="SessionConfig에 대한 직접 링크">​</a></h3><p>미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 <a href="https://github.com/apache/tomcat/pull/660" target="_blank" rel="noopener noreferrer">컨트리뷰트</a>를 시도했다.<br> +<!-- -->다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.</p> +<h3 id="sessionconfig">SessionConfig</h3> +<p>미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 <a href="https://github.com/apache/tomcat/pull/660">컨트리뷰트</a>를 시도했다.<br> <!-- -->세션 쿠키의 이름을 가져오는 Util 클래스의 코드를 수정했는데 기본 값은 JSESSIONID 지만 설정에 따라서 세션 쿠키명을 다르게 사용할 수 있기 때문에 해당 로직이 있는 것으로 생각했다.<br> -<!-- -->기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다. </p><p>초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.<br> +<!-- -->기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.</p> +<p>초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.<br> <!-- -->메인테이너인 Mark Thomas 형이 해당 로직의 경우 컴파일러가 해당 부분을 최적화 할 수 있을 거라고 기대한다고 했고, 가독성을 개선시켜보라고 조언해주셨다.<br> -<!-- -->컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다. </p><p>남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.<br> -<!-- -->결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다. </p><div class="tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">기존</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">PR 요청</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">최종</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> result </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">result </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> result </span><span class="token operator">=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DEFAULT_SESSION_COOKIE_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getSessionUriParamName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> result </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">result </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> result </span><span class="token operator">=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DEFAULT_SESSION_PARAMETER_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Priority is:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 1. Cookie name defined in context</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 2. Cookie name configured for app</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 3. Default defined by spec</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> cookieName </span><span class="token operator">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cookieName </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">&&</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">length</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">></span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">SessionCookieConfig</span><span class="token plain"> scc </span><span class="token operator">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getServletContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieConfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cookieName </span><span class="token operator">=</span><span class="token plain"> scc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cookieName </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">&&</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">length</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">></span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DEFAULT_SESSION_COOKIE_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DEFAULT_SESSION_COOKIE_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getSessionUriParamName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context </span><span class="token operator">==</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DEFAULT_SESSION_PARAMETER_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DEFAULT_SESSION_PARAMETER_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> defaultName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Priority is:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 1. Cookie name defined in context</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 2. Cookie name configured for app</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 3. Default defined by spec</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> cookieName </span><span class="token operator">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cookieName </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">&&</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">length</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">></span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">SessionCookieConfig</span><span class="token plain"> scc </span><span class="token operator">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getServletContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieConfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cookieName </span><span class="token operator">=</span><span class="token plain"> scc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cookieName </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">&&</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">length</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">></span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> defaultName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DEFAULT_SESSION_COOKIE_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getSessionUriParamName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DEFAULT_SESSION_PARAMETER_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">getConfiguredSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Context</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> defaultName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Priority is:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 1. Cookie name defined in context</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 2. Cookie name configured for app</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 3. Default defined by spec</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">context </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> cookieName </span><span class="token operator">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cookieName </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">&&</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">length</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">></span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">SessionCookieConfig</span><span class="token plain"> scc </span><span class="token operator">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getServletContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getSessionCookieConfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cookieName </span><span class="token operator">=</span><span class="token plain"> scc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">cookieName </span><span class="token operator">!=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token plain"> </span><span class="token operator">&&</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">length</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">></span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> cookieName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> defaultName</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="http-수업">HTTP 수업<a href="#http-수업" class="hash-link" aria-label="HTTP 수업에 대한 직접 링크" title="HTTP 수업에 대한 직접 링크">​</a></h3><p>미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.<br> +<!-- -->컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.</p> +<p>남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.<br> +<!-- -->결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.</p> +<!-- --> +<!-- --> +<div class="tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">기존</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">PR 요청</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">최종</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><pre><code class="language-java">public static String getSessionCookieName(Context context) { + + String result = getConfiguredSessionCookieName(context); + + if (result == null) { + result = DEFAULT_SESSION_COOKIE_NAME; + } + + return result; +} + +public static String getSessionUriParamName(Context context) { + + String result = getConfiguredSessionCookieName(context); + + if (result == null) { + result = DEFAULT_SESSION_PARAMETER_NAME; + } + + return result; +} + +private static String getConfiguredSessionCookieName(Context context) { + + // Priority is: + // 1. Cookie name defined in context + // 2. Cookie name configured for app + // 3. Default defined by spec + if (context != null) { + String cookieName = context.getSessionCookieName(); + if (cookieName != null && cookieName.length() > 0) { + return cookieName; + } + + SessionCookieConfig scc = + context.getServletContext().getSessionCookieConfig(); + cookieName = scc.getName(); + if (cookieName != null && cookieName.length() > 0) { + return cookieName; + } + } + + return null; +} +</code></pre></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><pre><code class="language-java">public static String getSessionCookieName(Context context) { + if (context == null) { + return DEFAULT_SESSION_COOKIE_NAME; + } + return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME); +} + +public static String getSessionUriParamName(Context context) { + if (context == null) { + return DEFAULT_SESSION_PARAMETER_NAME; + } + return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME); +} + +private static String getConfiguredSessionCookieName(Context context, String defaultName) { + // Priority is: + // 1. Cookie name defined in context + // 2. Cookie name configured for app + // 3. Default defined by spec + String cookieName = context.getSessionCookieName(); + if (cookieName != null && cookieName.length() > 0) { + return cookieName; + } + + SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig(); + cookieName = scc.getName(); + if (cookieName != null && cookieName.length() > 0) { + return cookieName; + } + + return defaultName; +} +</code></pre></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><pre><code class="language-java">public static String getSessionCookieName(Context context) { + return getConfiguredSessionCookieName(context, DEFAULT_SESSION_COOKIE_NAME); +} + +public static String getSessionUriParamName(Context context) { + return getConfiguredSessionCookieName(context, DEFAULT_SESSION_PARAMETER_NAME); +} + +private static String getConfiguredSessionCookieName(Context context, String defaultName) { + // Priority is: + // 1. Cookie name defined in context + // 2. Cookie name configured for app + // 3. Default defined by spec + if (context != null) { + String cookieName = context.getSessionCookieName(); + if (cookieName != null && cookieName.length() > 0) { + return cookieName; + } + + SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig(); + cookieName = scc.getName(); + if (cookieName != null && cookieName.length() > 0) { + return cookieName; + } + } + return defaultName; +} +</code></pre></div></div></div> +<h3 id="http-수업">HTTP 수업</h3> +<p>미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.<br> <!-- -->항상 성능 개선을 위해 애플리케이션 단에서 최적화해보려고 노력을 했지만, 더 적은 시간을 투자해서 효율적으로 성능을 개선할 수 있는 방법에 대해 알 수 있었던 수업이었다.<br> -<!-- -->HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다. </p><p>스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다. </p><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">server</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">compression</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">enabled</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token boolean important">true</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.<br> -<!-- -->궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 <a href="https://github.com/spring-projects/spring-boot/issues/21369" target="_blank" rel="noopener noreferrer">issue</a>를 찾아주었다.<br> -<!-- -->내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다. </p><blockquote><p>If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.</p></blockquote><p>Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다. </p><p>이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>ETag</div><div class="admonitionContent_S0QG"><p>ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.<br> +<!-- -->HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.</p> +<p>스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.</p> +<pre><code class="language-yml">server: + compression: + enabled: true +</code></pre> +<p>수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.<br> +<!-- -->궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 <a href="https://github.com/spring-projects/spring-boot/issues/21369">issue</a>를 찾아주었다.<br> +<!-- -->내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.</p> +<blockquote> +<p>If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.</p> +</blockquote> +<p>Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.</p> +<p>이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.</p> +<admonition title="ETag" type="note"><p>ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.<br> <!-- -->웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐시가 더 효율적이게 된다.<br> -<!-- -->MDN</p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="thread-수업">Thread 수업<a href="#thread-수업" class="hash-link" aria-label="Thread 수업에 대한 직접 링크" title="Thread 수업에 대한 직접 링크">​</a></h3><p>스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.<br> -<!-- -->현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다. </p><p>스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.<br> -<!-- -->학습한 내용은 다음과 같다. </p><p><code>threads.max</code>: Tomcat의 최대 스레드 개수<br> +<!-- -->MDN</p></admonition> +<h3 id="thread-수업">Thread 수업</h3> +<p>스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.<br> +<!-- -->현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.</p> +<p>스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.<br> +<!-- -->학습한 내용은 다음과 같다.</p> +<p><code>threads.max</code>: Tomcat의 최대 스레드 개수<br> <code>max-connections</code>: Tomcat이 유지할 수 있는 최대 커넥션 개수<br> -<code>accept-count</code>: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="마치며">마치며<a href="#마치며" class="hash-link" aria-label="마치며에 대한 직접 링크" title="마치며에 대한 직접 링크">​</a></h3><p>시간은 너무 빠르게 가고 할 일은 많은 것 같다.<br> +<code>accept-count</code>: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.</p> +<mermaid value="graph LR + C("Client") -- request --> ACQ("운영체제에 의해 관리되는 Queue + size = accept-count") --> TCQ("Tomcat Connector에 의해 관리되는 Queue + size = max-connections") --> TP("Thread Pool + size = threads.max")"></mermaid> +<h3 id="마치며">마치며</h3> +<p>시간은 너무 빠르게 가고 할 일은 많은 것 같다.<br> <!-- -->우선순위를 잘 정하고 학습을 진행해야겠다.<br> -<!-- -->현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h3><p><a href="https://datatracker.ietf.org/doc/html/rfc2616/" target="_blank" rel="noopener noreferrer">RFC 2616</a><br> -<a href="https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/ETag" target="_blank" rel="noopener noreferrer">ETag, mdn</a><br> -<a href="https://tomcat.apache.org/tomcat-8.5-doc/config/http.html" target="_blank" rel="noopener noreferrer">Apache Tomcat 8 Configuration Reference</a><br> -<a href="https://bcho.tistory.com/788" target="_blank" rel="noopener noreferrer">Apache Tomcat Tuning, Terry Cho</a><br> -<a href="https://dev-ws.tistory.com/96" target="_blank" rel="noopener noreferrer">maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기</a></p>]]></content> +<!-- -->현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.</p> +<h3 id="참고-자료">참고 자료</h3> +<p><a href="https://datatracker.ietf.org/doc/html/rfc2616/">RFC 2616</a><br> +<a href="https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/ETag">ETag, mdn</a><br> +<a href="https://tomcat.apache.org/tomcat-8.5-doc/config/http.html">Apache Tomcat 8 Configuration Reference</a><br> +<a href="https://bcho.tistory.com/788">Apache Tomcat Tuning, Terry Cho</a><br> +<a href="https://dev-ws.tistory.com/96">maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기</a></p>]]></content> <category label="Woowahan Techcourse" term="Woowahan Techcourse"/> <category label="Retrospective" term="Retrospective"/> </entry> @@ -192,19 +726,44 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/performance-test-type"/> <updated>2023-09-10T00:00:00.000Z</updated> <summary type="html"><![CDATA[성능 테스트]]></summary> - <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="성능-테스트">성능 테스트<a href="#성능-테스트" class="hash-link" aria-label="성능 테스트에 대한 직접 링크" title="성능 테스트에 대한 직접 링크">​</a></h2><p>API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트</p><p>시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.<br> -<!-- -->다양한 상황에 대비해서 성능 테스트를 해야한다. </p><p><img loading="lazy" alt="./test.png" src="/assets/images/test-355aba93f96ef7d6a0f3161bf6a9c25e.png" width="2168" height="1002" class="img_ev3q"></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="스모크-테스트smoke-test">스모크 테스트(Smoke Test)<a href="#스모크-테스트smoke-test" class="hash-link" aria-label="스모크 테스트(Smoke Test)에 대한 직접 링크" title="스모크 테스트(Smoke Test)에 대한 직접 링크">​</a></h3><p>최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트 </p><p>VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.<br> -<!-- -->다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>가상 사용자(VU)</div><div class="admonitionContent_S0QG"><p>가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.<br> + <content type="html"><![CDATA[<h2 id="성능-테스트">성능 테스트</h2> +<p>API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트</p> +<p>시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.<br> +<!-- -->다양한 상황에 대비해서 성능 테스트를 해야한다.</p> +<p><img alt="./test.png" src="https://greeng00se.github.io/assets/images/test-355aba93f96ef7d6a0f3161bf6a9c25e.png" width="2168" height="1002"></p> +<h3 id="스모크-테스트smoke-test">스모크 테스트(Smoke Test)</h3> +<p>최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트</p> +<p>VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.<br> +<!-- -->다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.</p> +<admonition title="가상 사용자(VU)" type="note"><p>가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.<br> <!-- -->이는 다른 가상 사용자와 독립적으로 실행되며, 여러 가상 사용자를 사용하여 동시 연결을 할 수 있다.<br> -<!-- -->스레드라고 생각하면 된다. </p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="스파이크-테스트spike-test">스파이크 테스트(Spike Test)<a href="#스파이크-테스트spike-test" class="hash-link" aria-label="스파이크 테스트(Spike Test)에 대한 직접 링크" title="스파이크 테스트(Spike Test)에 대한 직접 링크">​</a></h3><p>사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트 </p><p>티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.<br> -<!-- -->스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="부하-테스트load-test">부하 테스트(Load Test)<a href="#부하-테스트load-test" class="hash-link" aria-label="부하 테스트(Load Test)에 대한 직접 링크" title="부하 테스트(Load Test)에 대한 직접 링크">​</a></h3><p>목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트 </p><p>일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.<br> -<!-- -->램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>램프 업(Ramp-up)</div><div class="admonitionContent_S0QG"><p>부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간</p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="스트레스-테스트stress-test">스트레스 테스트(Stress Test)<a href="#스트레스-테스트stress-test" class="hash-link" aria-label="스트레스 테스트(Stress Test)에 대한 직접 링크" title="스트레스 테스트(Stress Test)에 대한 직접 링크">​</a></h3><p>시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트 </p><p>그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.<br> +<!-- -->스레드라고 생각하면 된다.</p></admonition> +<h3 id="스파이크-테스트spike-test">스파이크 테스트(Spike Test)</h3> +<p>사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트</p> +<p>티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.<br> +<!-- -->스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.</p> +<h3 id="부하-테스트load-test">부하 테스트(Load Test)</h3> +<p>목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트</p> +<p>일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.<br> +<!-- -->램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.</p> +<admonition title="램프 업(Ramp-up)" type="note"><p>부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간</p></admonition> +<h3 id="스트레스-테스트stress-test">스트레스 테스트(Stress Test)</h3> +<p>시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트</p> +<p>그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.<br> <!-- -->일반적으로 평균적인 목푯값 대비 작게는 50% 이상, 필요의 경우 그 이상으로 부하를 준다.<br> <!-- -->스트레스 테스트는 부하 테스트를 실행한 후에만 실행해야 한다. 부하 테스트가 이루어지지 않은 상황에서 스트레스 테스트를 실행하는 경우에는 병목 지점이나 문제 상황을 찾기 어려워진다.<br> -<!-- -->또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="내구-테스트endurance-test">내구 테스트(Endurance Test)<a href="#내구-테스트endurance-test" class="hash-link" aria-label="내구 테스트(Endurance Test)에 대한 직접 링크" title="내구 테스트(Endurance Test)에 대한 직접 링크">​</a></h3><p>평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트 </p><p>흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.<br> -<!-- -->다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="중단점-테스트breakpoint-test">중단점 테스트(Breakpoint Test)<a href="#중단점-테스트breakpoint-test" class="hash-link" aria-label="중단점 테스트(Breakpoint Test)에 대한 직접 링크" title="중단점 테스트(Breakpoint Test)에 대한 직접 링크">​</a></h3><p>임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트</p><p>문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.<br> +<!-- -->또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.</p> +<h3 id="내구-테스트endurance-test">내구 테스트(Endurance Test)</h3> +<p>평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트</p> +<p>흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.<br> +<!-- -->다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.</p> +<h3 id="중단점-테스트breakpoint-test">중단점 테스트(Breakpoint Test)</h3> +<p>임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트</p> +<p>문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.<br> <!-- -->스트레스 테스트를 성능 튜닝과 반복해서 진행한다면, 시스템을 더욱 발전시킬 수 있다.<br> -<!-- -->다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h3><p><a href="https://k6.io/docs/test-types/load-test-types/" target="_blank" rel="noopener noreferrer">Load test types, k6</a><br> +<!-- -->다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.</p> +<h3 id="참고-자료">참고 자료</h3> +<p><a href="https://k6.io/docs/test-types/load-test-types/">Load test types, k6</a><br> <!-- -->자바 최적화 - 벤저민 J. 에번스, 제임스 고프, 크리스 뉴랜드<br> <!-- -->아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄</p>]]></content> <category label="performance test" term="performance test"/> @@ -215,58 +774,436 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/db-replication"/> <updated>2023-08-22T00:00:00.000Z</updated> <summary type="html"><![CDATA[복제(Replication)]]></summary> - <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="복제replication">복제(Replication)<a href="#복제replication" class="hash-link" aria-label="복제(Replication)에 대한 직접 링크" title="복제(Replication)에 대한 직접 링크">​</a></h2><p>한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.<br> -<!-- -->원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="복제를-하는-이유">복제를 하는 이유<a href="#복제를-하는-이유" class="hash-link" aria-label="복제를 하는 이유에 대한 직접 링크" title="복제를 하는 이유에 대한 직접 링크">​</a></h3><p><strong>1. 스케일 아웃</strong></p><p>사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.<br> -<!-- -->이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다. </p><p><strong>2. 데이터 백업</strong></p><p>실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.<br> -<!-- -->따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다. </p><p><strong>3. 데이터 분석</strong></p><p>백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.<br> -<!-- -->마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다. </p><p><strong>4. 데이터의 지리적 분산</strong></p><p>빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="바이너리-로그-파일-위치-기반-복제">바이너리 로그 파일 위치 기반 복제<a href="#바이너리-로그-파일-위치-기반-복제" class="hash-link" aria-label="바이너리 로그 파일 위치 기반 복제에 대한 직접 링크" title="바이너리 로그 파일 위치 기반 복제에 대한 직접 링크">​</a></h3><p>MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.<br> + <content type="html"><![CDATA[<h2 id="복제replication">복제(Replication)</h2> +<p>한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.<br> +<!-- -->원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.</p> +<h3 id="복제를-하는-이유">복제를 하는 이유</h3> +<p><strong>1. 스케일 아웃</strong></p> +<p>사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.<br> +<!-- -->이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.</p> +<p><strong>2. 데이터 백업</strong></p> +<p>실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.<br> +<!-- -->따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.</p> +<p><strong>3. 데이터 분석</strong></p> +<p>백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.<br> +<!-- -->마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.</p> +<p><strong>4. 데이터의 지리적 분산</strong></p> +<p>빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.</p> +<h3 id="바이너리-로그-파일-위치-기반-복제">바이너리 로그 파일 위치 기반 복제</h3> +<p>MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.<br> <!-- -->바이너리 로그를 통해 데이터 변경, 테이블 구조 변경, 계정이나 권한 변경에 대한 정보가 저장된다.<br> -<!-- -->MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>스레드별 역할</div><div class="admonitionContent_S0QG"><p>Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달<br> +<!-- -->MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.</p> +<mermaid value="graph LR + subgraph Replica + direction TB + IO[Replication I/O thread] -- save --> RL[Relay Log] + SQL[Replication SQL Thread] -- read --> RL + end + + subgraph Source + direction TB + BLD[Binary Log Dump Thread] -- Send Binary Log Dump--> IO + end +"></mermaid> +<admonition title="스레드별 역할" type="note"><p>Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달<br> <!-- -->Replication I/O Thread: Binary 로그 이벤트를 가져와 로컬 서버의 파일(Relay Log)로 저장<br> -<!-- -->Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행</p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="바이너리-로그-방식의-문제점">바이너리 로그 방식의 문제점<a href="#바이너리-로그-방식의-문제점" class="hash-link" aria-label="바이너리 로그 방식의 문제점에 대한 직접 링크" title="바이너리 로그 방식의 문제점에 대한 직접 링크">​</a></h3><p>바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.<br> -<!-- -->토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.</p><p>위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다. </p><p>A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.<br> +<!-- -->Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행</p></admonition> +<h3 id="바이너리-로그-방식의-문제점">바이너리 로그 방식의 문제점</h3> +<p>바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.<br> +<!-- -->토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.</p> +<mermaid value="graph TD + A[A binary-log:300] --> B[B Binary-log:300] + A[A binary-log:300] --> C[C Binary-log:200]"></mermaid> +<p>위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.</p> +<mermaid value="graph TD + A[A binary-log:300] + B[B Binary-log:300] --> C[C Binary-log:200 문제 발생]"></mermaid> +<p>A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.<br> <!-- -->하지만 여기서 C 서버에는 A 서버와 동기화가 안되었으니 조회 시 문제가 발생한다.<br> -<!-- -->뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="글로벌-트랜잭션-아이디gtid-기반-복제">글로벌 트랜잭션 아이디(GTID) 기반 복제<a href="#글로벌-트랜잭션-아이디gtid-기반-복제" class="hash-link" aria-label="글로벌 트랜잭션 아이디(GTID) 기반 복제에 대한 직접 링크" title="글로벌 트랜잭션 아이디(GTID) 기반 복제에 대한 직접 링크">​</a></h3><p>GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.<br> -<!-- -->위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>GTID</div><div class="admonitionContent_S0QG"><p>복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값<br> -<!-- -->[source_id]<!-- -->:<!-- -->[transaction_id]<!-- -->로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다. </p></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="복제-토폴로지">복제 토폴로지<a href="#복제-토폴로지" class="hash-link" aria-label="복제 토폴로지에 대한 직접 링크" title="복제 토폴로지에 대한 직접 링크">​</a></h3><p><strong>싱글 레플리카 복제 구성</strong></p><p>가장 간단한 구성으로 제일 많이 사용하는 형태다.<br> -<!-- -->replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다. </p><p><strong>멀티 레플리카 복제 구성</strong></p><p>2개의 replica 서버를 사용하는 형태다.<br> +<!-- -->뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.</p> +<h3 id="글로벌-트랜잭션-아이디gtid-기반-복제">글로벌 트랜잭션 아이디(GTID) 기반 복제</h3> +<p>GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.<br> +<!-- -->위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.</p> +<admonition title="GTID" type="note"><p>복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값<br> +<!-- -->[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.</p></admonition> +<h3 id="복제-토폴로지">복제 토폴로지</h3> +<p><strong>싱글 레플리카 복제 구성</strong></p> +<p>가장 간단한 구성으로 제일 많이 사용하는 형태다.<br> +<!-- -->replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.</p> +<mermaid value="graph LR + W[Web Server] -- 읽기 + 쓰기 --> S + W -- 읽기 --> R + S[Source] --> R[Replica]"></mermaid> +<p><strong>멀티 레플리카 복제 구성</strong></p> +<p>2개의 replica 서버를 사용하는 형태다.<br> <!-- -->하나의 replica는 예비 용도로 남겨두는 형태다.<br> -<!-- -->추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다. </p><p><strong>체인 복제 구성</strong></p><p>replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.<br> -<!-- -->따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다. </p><p><strong>듀얼 소스 복제 구성</strong></p><p>2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.<br> +<!-- -->추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.</p> +<mermaid value="graph LR + W[Web Server] -- 읽기 + 쓰기 --> S + W -- 읽기 --> R1 + S[Source] --> R1[Replica1] + S --> R2[Replica2]"></mermaid> +<p><strong>체인 복제 구성</strong></p> +<p>replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.<br> +<!-- -->따라서 1:M<!-- -->:M<!-- --> 구조로 체인 복제 구성을 고려할 수 있다.</p> +<mermaid value="graph LR + W[Web Server] -- 읽기 + 쓰기 --> S + W -- 읽기 --> R1 + S[Source] --> R1[Replica1] + S --> R2[Replica2] + S --> R3[Replica3] + + R3 --> R3-1[Replica 3-1] + R3 --> R3-2[Replica 3-2] + + B[Batch Server] --> R3-2"></mermaid> +<p><strong>듀얼 소스 복제 구성</strong></p> +<p>2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.<br> <!-- -->각 서버에서 변경된 데이터는 다른 서버에 반영된다.<br> <!-- -->목적에 따라 ACTIVE-ACTIVE 형태 또는 ACTIVE-PASSIVE 형태로 사용할 수 있다.<br> -<!-- -->ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>ACTIVE-ACTIVE, ACTIVE-PASSIVE</div><div class="admonitionContent_S0QG"><p>ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태<br> -<!-- -->ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태</p></div></div><p><strong>멀티 소스 복제 구성</strong></p><p>여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.<br> -<!-- -->이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="바이너리-로그-방식-replication-구성하기">바이너리 로그 방식 Replication 구성하기<a href="#바이너리-로그-방식-replication-구성하기" class="hash-link" aria-label="바이너리 로그 방식 Replication 구성하기에 대한 직접 링크" title="바이너리 로그 방식 Replication 구성하기에 대한 직접 링크">​</a></h2><p>mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.<br> -<a href="https://github.com/bbiac/db-replication" target="_blank" rel="noopener noreferrer">https://github.com/bbiac/db-replication</a> </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="mysql-환경-구성">MySQL 환경 구성<a href="#mysql-환경-구성" class="hash-link" aria-label="MySQL 환경 구성에 대한 직접 링크" title="MySQL 환경 구성에 대한 직접 링크">​</a></h3><p>MySQL 버전은 8.1을 사용했다.<br> +<!-- -->ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.</p> +<mermaid value="graph LR + W[Web Server] -- 읽기 + 쓰기 --> SR1 + W -- 읽기 + 쓰기 --> SR2 + SR1[Source/Replica 1] --> SR2[Source/Replica 2]"></mermaid> +<admonition title="ACTIVE-ACTIVE, ACTIVE-PASSIVE" type="note"><p>ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태<br> +<!-- -->ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태</p></admonition> +<p><strong>멀티 소스 복제 구성</strong></p> +<p>여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.<br> +<!-- -->이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.</p> +<mermaid value="graph LR + S1[Source 1] --> R[Replica] + S2[Source 2] --> R"></mermaid> +<h2 id="바이너리-로그-방식-replication-구성하기">바이너리 로그 방식 Replication 구성하기</h2> +<p>mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.<br> +<a href="https://github.com/bbiac/db-replication">https://github.com/bbiac/db-replication</a></p> +<h3 id="mysql-환경-구성">MySQL 환경 구성</h3> +<p>MySQL 버전은 8.1을 사용했다.<br> <!-- -->13306, 13307 포트를 사용해서 MySQL 서버 2대를 띄웠다.<br> -<!-- -->또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다. </p><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">version</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'3.8'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">services</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">source</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">platform</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> linux/x86_64</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">latest</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">restart</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> always</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">container_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">source</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">environment</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">TZ</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'Asia/Seoul'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">MYSQL_DATABASE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'db'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">MYSQL_USER</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'user'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">MYSQL_PASSWORD</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'password'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">MYSQL_ROOT_PASSWORD</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'password'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"13306:3306"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">volumes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> db</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">source</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">/var/lib/mysql</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> db</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">source</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">/var/lib/mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">files</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> ./docker/source.cnf</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">/etc/mysql/my.cnf</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">networks</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> mysql_network</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">replica</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">platform</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> linux/x86_64</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">image</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">latest</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">restart</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> always</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">container_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">replica</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">environment</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">TZ</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'Asia/Seoul'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">MYSQL_DATABASE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'db'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">MYSQL_USER</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'user'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">MYSQL_PASSWORD</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'password'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">MYSQL_ROOT_PASSWORD</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'password'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">ports</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"13307:3306"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">volumes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> db</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">replica</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">/var/lib/mysql</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> db</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">replica</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">/var/lib/mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">files</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> ./docker/replica.cnf</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">/etc/mysql/my.cnf</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">networks</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> mysql_network</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">volumes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">db-source</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">db-replica</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">networks</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">mysql_network</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">driver</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> bridge</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>또한 source, replica 각각 다음과 같이 db 설정을 했다. </p><table><thead><tr><th>설정</th><th>설명</th></tr></thead><tbody><tr><td>server_id</td><td>각각의 mysql 마다 고유한 값을 가져야 한다.</td></tr><tr><td>log_bin</td><td>바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.</td></tr><tr><td>sync_binlog</td><td>N개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.</td></tr><tr><td>relay_log</td><td>릴레이 로그 파일 경로 설정</td></tr><tr><td>relay_log_purge</td><td>필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션</td></tr><tr><td>read_only</td><td>읽기 전용 설정</td></tr><tr><td>log_replica_updates</td><td>Replication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.</td></tr></tbody></table><div class="tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">Source</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">Replica</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><div class="language-cnf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">/docker/source.cnf</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-cnf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">[mysqld]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">server_id=1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">log_bin=mysql-bin</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">sync_binlog=1</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-cnf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">/docker/replica.cnf</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-cnf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">[mysqld]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">server_id=2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">relay_log=mysql-relay-bin</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">relay_log_purge=ON</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">read_only</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">log_replica_updates</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="도커-실행">도커 실행<a href="#도커-실행" class="hash-link" aria-label="도커 실행에 대한 직접 링크" title="도커 실행에 대한 직접 링크">​</a></h3><p>docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.<br> -<!-- -->-d 옵션을 붙이면 백그라운드 모드로 실행된다. </p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">docker-compose up -d</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="replication-slave-권한-설정">replication slave 권한 설정<a href="#replication-slave-권한-설정" class="hash-link" aria-label="replication slave 권한 설정에 대한 직접 링크" title="replication slave 권한 설정에 대한 직접 링크">​</a></h3><p>REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.<br> -<!-- -->source 서버에 접근하여 user 계정에 해당 권한을 설정해준다. </p><p>SOURCE 접속</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">docker</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">exec</span><span class="token plain"> -it mysql-source mysql -u root -p</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>user 계정에 REPLICATION SLAVE 권한 추가</p><div class="language-mysql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-mysql codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">FLUSH PRIVILEGES;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="source-db-정보-확인">SOURCE DB 정보 확인<a href="#source-db-정보-확인" class="hash-link" aria-label="SOURCE DB 정보 확인에 대한 직접 링크" title="SOURCE DB 정보 확인에 대한 직접 링크">​</a></h3><p>replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.<br> +<!-- -->또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.</p> +<pre><code class="language-yml">version: '3.8' + +services: + source: + platform: linux/x86_64 + image: mysql:latest + restart: always + container_name: mysql-source + environment: + TZ: 'Asia/Seoul' + MYSQL_DATABASE: 'db' + MYSQL_USER: 'user' + MYSQL_PASSWORD: 'password' + MYSQL_ROOT_PASSWORD: 'password' + ports: + - "13306:3306" + volumes: + - db-source:/var/lib/mysql + - db-source:/var/lib/mysql-files + - ./docker/source.cnf:/etc/mysql/my.cnf + networks: + - mysql_network + + replica: + platform: linux/x86_64 + image: mysql:latest + restart: always + container_name: mysql-replica + environment: + TZ: 'Asia/Seoul' + MYSQL_DATABASE: 'db' + MYSQL_USER: 'user' + MYSQL_PASSWORD: 'password' + MYSQL_ROOT_PASSWORD: 'password' + ports: + - "13307:3306" + volumes: + - db-replica:/var/lib/mysql + - db-replica:/var/lib/mysql-files + - ./docker/replica.cnf:/etc/mysql/my.cnf + networks: + - mysql_network + +volumes: + db-source: + db-replica: + +networks: + mysql_network: + driver: bridge +</code></pre> +<p>또한 source, replica 각각 다음과 같이 db 설정을 했다.</p> +<table><thead><tr><th>설정</th><th>설명</th></tr></thead><tbody><tr><td>server_id</td><td>각각의 mysql 마다 고유한 값을 가져야 한다.</td></tr><tr><td>log_bin</td><td>바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.</td></tr><tr><td>sync_binlog</td><td>N개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.</td></tr><tr><td>relay_log</td><td>릴레이 로그 파일 경로 설정</td></tr><tr><td>relay_log_purge</td><td>필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션</td></tr><tr><td>read_only</td><td>읽기 전용 설정</td></tr><tr><td>log_replica_updates</td><td>Replication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.</td></tr></tbody></table> +<!-- --> +<!-- --> +<div class="tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">Source</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">Replica</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><pre><code class="language-cnf" metastring="title="/docker/source.cnf"">[mysqld] +server_id=1 +log_bin=mysql-bin +sync_binlog=1 +</code></pre></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><pre><code class="language-cnf" metastring="title="/docker/replica.cnf"">[mysqld] +server_id=2 +relay_log=mysql-relay-bin +relay_log_purge=ON +read_only +log_replica_updates +</code></pre></div></div></div> +<h3 id="도커-실행">도커 실행</h3> +<p>docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.<br> +<!-- -->-d 옵션을 붙이면 백그라운드 모드로 실행된다.</p> +<pre><code>docker-compose up -d +</code></pre> +<h3 id="replication-slave-권한-설정">replication slave 권한 설정</h3> +<p>REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.<br> +<!-- -->source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.</p> +<p>SOURCE 접속</p> +<pre><code class="language-bash">docker exec -it mysql-source mysql -u root -p +</code></pre> +<p>user 계정에 REPLICATION SLAVE 권한 추가</p> +<pre><code class="language-mysql">GRANT REPLICATION SLAVE ON *.* TO 'user'@'%'; +FLUSH PRIVILEGES; +</code></pre> +<h3 id="source-db-정보-확인">SOURCE DB 정보 확인</h3> +<p>replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.<br> <!-- -->Position 값은 실제 파일의 바이트 수를 의미한다.<br> -<!-- -->확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.</p><div class="language-mysql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-mysql codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">SHOW MASTER STATUS;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+------------------+----------+--------------+------------------+-------------------+</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+------------------+----------+--------------+------------------+-------------------+</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| mysql-bin.000003 | 1082 | | | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+------------------+----------+--------------+------------------+-------------------+</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="source-ip-주소-확인">SOURCE ip 주소 확인<a href="#source-ip-주소-확인" class="hash-link" aria-label="SOURCE ip 주소 확인에 대한 직접 링크" title="SOURCE ip 주소 확인에 대한 직접 링크">​</a></h3><p>docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.<br> -<!-- -->다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">docker</span><span class="token plain"> inspect -f </span><span class="token string" style="color:rgb(255, 121, 198)">"{{with index .NetworkSettings.Networks </span><span class="token string entity" style="color:rgb(255, 121, 198)">\"</span><span class="token string" style="color:rgb(255, 121, 198)">db-replication_mysql_network</span><span class="token string entity" style="color:rgb(255, 121, 198)">\"</span><span class="token string" style="color:rgb(255, 121, 198)">}}{{.IPAddress}}{{end}}"</span><span class="token plain"> mysql-source</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.<br> -<!-- -->확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="replica-mysql-접속">replica mysql 접속<a href="#replica-mysql-접속" class="hash-link" aria-label="replica mysql 접속에 대한 직접 링크" title="replica mysql 접속에 대한 직접 링크">​</a></h3><p>source db에 접속했던 방법과 동일하게 replica db에 접속한다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">docker</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">exec</span><span class="token plain"> -it mysql-replica mysql -u root -p</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="replica-설정">replica 설정<a href="#replica-설정" class="hash-link" aria-label="replica 설정에 대한 직접 링크" title="replica 설정에 대한 직접 링크">​</a></h3><p>이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.<br> +<!-- -->확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.</p> +<pre><code class="language-mysql">SHOW MASTER STATUS; + ++------------------+----------+--------------+------------------+-------------------+ +| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | ++------------------+----------+--------------+------------------+-------------------+ +| mysql-bin.000003 | 1082 | | | | ++------------------+----------+--------------+------------------+-------------------+ +</code></pre> +<h3 id="source-ip-주소-확인">SOURCE ip 주소 확인</h3> +<p>docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.<br> +<!-- -->다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.</p> +<pre><code class="language-bash">docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source +</code></pre> +<p>ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.<br> +<!-- -->확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.</p> +<h3 id="replica-mysql-접속">replica mysql 접속</h3> +<p>source db에 접속했던 방법과 동일하게 replica db에 접속한다.</p> +<pre><code class="language-bash">docker exec -it mysql-replica mysql -u root -p +</code></pre> +<h3 id="replica-설정">replica 설정</h3> +<p>이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.<br> <!-- -->실제 DB 서버에서 복제하는 경우 추가적으로 source DB의 파일을 복제해야하지만 현재 복제할 데이터가 없기 때문에 해당 부분은 생략했다.<br> -<!-- -->SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.</p><div class="language-mysql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-mysql codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">STOP REPLICA;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">CHANGE REPLICATION SOURCE TO </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">SOURCE_HOST='172.29.0.2', </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">SOURCE_USER='user', </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">SOURCE_PASSWORD='password', </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">SOURCE_LOG_FILE='mysql-bin.000001', </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">SOURCE_LOG_POS=0, </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">GET_SOURCE_PUBLIC_KEY=1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">START REPLICA;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="설정-확인">설정 확인<a href="#설정-확인" class="hash-link" aria-label="설정 확인에 대한 직접 링크" title="설정 확인에 대한 직접 링크">​</a></h3><div class="language-mysql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-mysql codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">SHOW REPLICA STATUS;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다. </p><p>설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.<br> -<!-- -->replica db에 동일한 member table이 생성된 것을 확인할 수 있다. </p><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">CREATE</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">TABLE</span><span class="token plain"> member</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> id </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">BIGINT</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">PRIMARY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">KEY</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">AUTO_INCREMENT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> name </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">VARCHAR</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">255</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="스프링-부트로-db-접근하기">스프링 부트로 DB 접근하기<a href="#스프링-부트로-db-접근하기" class="hash-link" aria-label="스프링 부트로 DB 접근하기에 대한 직접 링크" title="스프링 부트로 DB 접근하기에 대한 직접 링크">​</a></h2><p>일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="environment-설정">Environment 설정<a href="#environment-설정" class="hash-link" aria-label="Environment 설정에 대한 직접 링크" title="Environment 설정에 대한 직접 링크">​</a></h3><p>다음과 같이 source, replica로 구분하여 설정한다. </p><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">application.yml</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">spring</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">datasource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">source</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">username</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> user</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">password</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> password</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">driver-class-name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> com.mysql.cj.jdbc.Driver</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">jdbc-url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> jdbc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//localhost</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">13306/db</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">replica</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">username</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> user</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">password</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> password</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">driver-class-name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> com.mysql.cj.jdbc.Driver</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">jdbc-url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> jdbc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//localhost</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">13307/db</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="datasourcetype-설정">DataSourceType 설정<a href="#datasourcetype-설정" class="hash-link" aria-label="DataSourceType 설정에 대한 직접 링크" title="DataSourceType 설정에 대한 직접 링크">​</a></h3><p>단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.<br> -<!-- -->Key는 추후에 빈 설정에 사용한다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">DataSourceType</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">enum</span><span class="token plain"> </span><span class="token class-name">DataSourceType</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">SOURCE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">SOURCE_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">REPLICA</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">REPLICA_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> key</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">DataSourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">String</span><span class="token plain"> key</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">key </span><span class="token operator">=</span><span class="token plain"> key</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">Key</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ROUTING_NAME</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ROUTING"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">SOURCE_NAME</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"SOURCE"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">REPLICA_NAME</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"REPLICA"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="abstractroutingdatasource-설정">AbstractRoutingDataSource 설정<a href="#abstractroutingdatasource-설정" class="hash-link" aria-label="AbstractRoutingDataSource 설정에 대한 직접 링크" title="AbstractRoutingDataSource 설정에 대한 직접 링크">​</a></h3><p>스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다. </p><p>정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다. </p><ul><li>setDefaultTargetDataSource: 기본 데이터 소스를 설정한다. </li><li>setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다. </li></ul><p>determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다. </p><ul><li>isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다. </li><li>DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다. </li></ul><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">RoutingDataSource</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">RoutingDataSource</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">AbstractRoutingDataSource</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Logger</span><span class="token plain"> log </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">LoggerFactory</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLogger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">getClass</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token class-name">RoutingDataSource</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Map</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Object</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token generics"> </span><span class="token generics class-name">Object</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> dataSources</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">RoutingDataSource</span><span class="token plain"> routingDataSource </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">RoutingDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> routingDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setDefaultTargetDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">dataSources</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">get</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">DataSourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SOURCE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> routingDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">setTargetDataSources</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">dataSources</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> routingDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">protected</span><span class="token plain"> </span><span class="token class-name">Object</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">determineCurrentLookupKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">boolean</span><span class="token plain"> readOnly </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">TransactionSynchronizationManager</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">isCurrentTransactionReadOnly</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">readOnly</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">info</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"readOnly = true, request to replica"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token class-name">DataSourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">REPLICA</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> log</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">info</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"readOnly = false, request to source"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token class-name">DataSourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SOURCE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="datasource-설정">DataSource 설정<a href="#datasource-설정" class="hash-link" aria-label="DataSource 설정에 대한 직접 링크" title="DataSource 설정에 대한 직접 링크">​</a></h3><p>위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.<br> +<!-- -->SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.</p> +<pre><code class="language-mysql">STOP REPLICA; + +CHANGE REPLICATION SOURCE TO +SOURCE_HOST='172.29.0.2', +SOURCE_USER='user', +SOURCE_PASSWORD='password', +SOURCE_LOG_FILE='mysql-bin.000001', +SOURCE_LOG_POS=0, +GET_SOURCE_PUBLIC_KEY=1; + +START REPLICA; +</code></pre> +<h3 id="설정-확인">설정 확인</h3> +<pre><code class="language-mysql">SHOW REPLICA STATUS; + ++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ +| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace | ++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ +| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | | ++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+ +</code></pre> +<p>Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.</p> +<p>설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.<br> +<!-- -->replica db에 동일한 member table이 생성된 것을 확인할 수 있다.</p> +<pre><code class="language-sql">CREATE TABLE member +( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(255) +); +</code></pre> +<h2 id="스프링-부트로-db-접근하기">스프링 부트로 DB 접근하기</h2> +<p>일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.</p> +<h3 id="environment-설정">Environment 설정</h3> +<p>다음과 같이 source, replica로 구분하여 설정한다.</p> +<pre><code class="language-yml" metastring="title="application.yml"">spring: + datasource: + source: + username: user + password: password + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://localhost:13306/db + replica: + username: user + password: password + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://localhost:13307/db +</code></pre> +<h3 id="datasourcetype-설정">DataSourceType 설정</h3> +<p>단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.<br> +<!-- -->Key는 추후에 빈 설정에 사용한다.</p> +<pre><code class="language-java" metastring="title="DataSourceType"">public enum DataSourceType { + SOURCE(SOURCE_NAME), + REPLICA(REPLICA_NAME), + ; + + private final String key; + + DataSourceType(String key) { + this.key = key; + } + + public static class Key { + public static final String ROUTING_NAME = "ROUTING"; + public static final String SOURCE_NAME = "SOURCE"; + public static final String REPLICA_NAME = "REPLICA"; + } +} +</code></pre> +<h3 id="abstractroutingdatasource-설정">AbstractRoutingDataSource 설정</h3> +<p>스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.</p> +<p>정적 팩터리 메서드는 <code>Map<DataSourceKey, DataSource></code>에 해당하는 값을 받아 데이터 소스를 설정한다.</p> +<ul> +<li>setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.</li> +<li>setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.</li> +</ul> +<p>determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.</p> +<ul> +<li>isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.</li> +<li>DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.</li> +</ul> +<pre><code class="language-java" metastring="title="RoutingDataSource"">public class RoutingDataSource extends AbstractRoutingDataSource { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + public static RoutingDataSource from(Map<Object, Object> dataSources) { + RoutingDataSource routingDataSource = new RoutingDataSource(); + routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE)); + routingDataSource.setTargetDataSources(dataSources); + return routingDataSource; + } + + @Override + protected Object determineCurrentLookupKey() { + boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly(); + + if (readOnly) { + log.info("readOnly = true, request to replica"); + return DataSourceType.REPLICA; + } + log.info("readOnly = false, request to source"); + return DataSourceType.SOURCE; + } +} +</code></pre> +<h3 id="datasource-설정">DataSource 설정</h3> +<p>위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.<br> <!-- -->스프링은 트랜잭션 시작시에 커넥션의 사용여부와 상관없이 커넥션을 확보한다.<br> -<!-- -->따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다. </p><p>TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 <code>ThreadLocal<Boolean></code>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다. </p><p>LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">DataSourceConfiguration</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">DataSourceConfiguration</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Bean</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Qualifier</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">SOURCE_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@ConfigurationProperties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">prefix </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"spring.datasource.source"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">sourceDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token class-name">DataSourceBuilder</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">create</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Bean</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Qualifier</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">REPLICA_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@ConfigurationProperties</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">prefix </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"spring.datasource.replica"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">replicaDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token class-name">DataSourceBuilder</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">create</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">build</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Bean</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Qualifier</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">ROUTING_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">routingDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Qualifier</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">SOURCE_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> sourceDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Qualifier</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">REPLICA_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> replicaDataSource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token class-name">RoutingDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">of</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">DataSourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">SOURCE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> sourceDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">DataSourceType</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">REPLICA</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> replicaDataSource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Bean</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Primary</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">dataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Qualifier</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">ROUTING_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token class-name">DataSource</span><span class="token plain"> routingDataSource</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">LazyConnectionDataSourceProxy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">routingDataSource</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>최종적으로 DataSource 빈은 다음과 같은 형태가 된다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="동작-확인">동작 확인<a href="#동작-확인" class="hash-link" aria-label="동작 확인에 대한 직접 링크" title="동작 확인에 대한 직접 링크">​</a></h3><p>간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.<br> +<!-- -->따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.</p> +<p>TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 <code>ThreadLocal<Boolean></code>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.</p> +<p>LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.</p> +<pre><code class="language-java" metastring="title="DataSourceConfiguration"">@Configuration +public class DataSourceConfiguration { + + @Bean + @Qualifier(SOURCE_NAME) + @ConfigurationProperties(prefix = "spring.datasource.source") + public DataSource sourceDataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean + @Qualifier(REPLICA_NAME) + @ConfigurationProperties(prefix = "spring.datasource.replica") + public DataSource replicaDataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean + @Qualifier(ROUTING_NAME) + public DataSource routingDataSource( + @Qualifier(SOURCE_NAME) DataSource sourceDataSource, + @Qualifier(REPLICA_NAME) DataSource replicaDataSource + ) { + return RoutingDataSource.from(Map.of( + DataSourceType.SOURCE, sourceDataSource, + DataSourceType.REPLICA, replicaDataSource + )); + } + + @Bean + @Primary + public DataSource dataSource( + @Qualifier(ROUTING_NAME) DataSource routingDataSource + ) { + return new LazyConnectionDataSourceProxy(routingDataSource); + } +} +</code></pre> +<p>최종적으로 DataSource 빈은 다음과 같은 형태가 된다.</p> +<mermaid value="graph LR + DSP[LazyConnectionDataSourceProxy] --> RDS[RoutingDataSource] + RDS --> S[SourceDataSource] + RDS --> R[ReplicaDataSource]"></mermaid> +<h3 id="동작-확인">동작 확인</h3> +<p>간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.<br> <!-- -->save 메서드의 경우 <code>@Transactional</code>, findById 메서드의 경우 <code>@Transactional(readOnly = true)</code>가 설정되어있다.<br> -<!-- -->로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">MemberServiceTest</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@SpringBootTest</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">MemberServiceTest</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Autowired</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token class-name">MemberService</span><span class="token plain"> memberService</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Test</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> 사용자를_저장한다</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// RoutingDataSource log: readOnly = false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> memberService</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">save</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"bbiac"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Test</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> 사용자를_조회한다</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// RoutingDataSource log: readOnly = true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">assertThatThrownBy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-></span><span class="token plain"> memberService</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">findById</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">MAX_VALUE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">isInstanceOf</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">NoSuchElementException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다. </p><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">SET</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">GLOBAL</span><span class="token plain"> log_output </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'table'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">SET</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">GLOBAL</span><span class="token plain"> general_log </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>general log를 활성화 한 후 읽기 전용 메서드를 실행한다.<br> -<!-- -->server_id, 실행한 쿼리문을 확인할 수 있다. </p><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">SELECT</span><span class="token plain"> user_host</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> thread_id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> server_id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">convert</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">argument </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">using</span><span class="token plain"> utf8</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">FROM</span><span class="token plain"> mysql</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">general_log </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">where</span><span class="token plain"> argument </span><span class="token operator">like</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'%select%'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">+</span><span class="token comment" style="color:rgb(98, 114, 164)">----------------------------+-----------+-----------+-----------------------------------------------------------------------------+</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">|</span><span class="token plain"> user_host </span><span class="token operator">|</span><span class="token plain"> thread_id </span><span class="token operator">|</span><span class="token plain"> server_id </span><span class="token operator">|</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">convert</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">argument </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">using</span><span class="token plain"> utf8</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">+</span><span class="token comment" style="color:rgb(98, 114, 164)">----------------------------+-----------+-----------+-----------------------------------------------------------------------------+</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">|</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">user</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">user</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> @ </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">172.25</span><span class="token number">.0</span><span class="token number">.1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token number">277</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token number">2</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">select</span><span class="token plain"> m1_0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">m1_0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">name </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> member m1_0 </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">where</span><span class="token plain"> m1_0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">id</span><span class="token operator">=</span><span class="token number">9223372036854775807</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">+</span><span class="token comment" style="color:rgb(98, 114, 164)">----------------------------+-----------+-----------+-----------------------------------------------------------------------------+</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다. </p><div class="language-sql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-sql codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">SET</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">GLOBAL</span><span class="token plain"> general_log </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">SHOW</span><span class="token plain"> VARIABLES </span><span class="token operator">LIKE</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'%general%'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">+</span><span class="token comment" style="color:rgb(98, 114, 164)">------------------+---------------------------------+</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">|</span><span class="token plain"> Variable_name </span><span class="token operator">|</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">Value</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">+</span><span class="token comment" style="color:rgb(98, 114, 164)">------------------+---------------------------------+</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">|</span><span class="token plain"> general_log </span><span class="token operator">|</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">OFF</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">|</span><span class="token plain"> general_log_file </span><span class="token operator">|</span><span class="token plain"> </span><span class="token operator">/</span><span class="token plain">var</span><span class="token operator">/</span><span class="token plain">lib</span><span class="token operator">/</span><span class="token plain">mysql</span><span class="token operator">/</span><span class="token number">4</span><span class="token plain">b6b9db98290</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">log </span><span class="token operator">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token operator">+</span><span class="token comment" style="color:rgb(98, 114, 164)">------------------+---------------------------------+</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h2><p>16장 복제, Real MySQL 8.0 - 백은빈, 이성욱<br> -<a href="https://dev.mysql.com/doc/refman/8.1/en/replication.html" target="_blank" rel="noopener noreferrer">Replication, MySQL Docs</a><br> -<a href="https://huisam.tistory.com/entry/mysql-replication" target="_blank" rel="noopener noreferrer">MySql - Master Slave Replication 구조 만들어보기</a><br> -<a href="https://cheese10yun.github.io/spring-transaction/" target="_blank" rel="noopener noreferrer">Spring 레플리케이션 트랜잭션 처리 방식</a><br> -<a href="https://github.com/kwon37xi/replication-datasource" target="_blank" rel="noopener noreferrer">replication-datasource</a><br> -<a href="https://www.linkedin.com/pulse/simplified-guide-mysql-replication-docker-compose-rakesh-shekhawat/" target="_blank" rel="noopener noreferrer">Simplified Guide to MySQL Replication with Docker Compose</a><br> -<a href="https://www.daleseo.com/dockerfile/" target="_blank" rel="noopener noreferrer">Dockerfile에서 자주 쓰이는 명령어</a><br> -<a href="https://dev.mysql.com/doc/refman/8.1/en/change-replication-source-to.html" target="_blank" rel="noopener noreferrer">CHANGE REPLICATION SOURCE TO Statement</a><br> -<a href="https://kwonnam.pe.kr/wiki/springframework/lazyconnectiondatasourceproxy" target="_blank" rel="noopener noreferrer">LazyConnectionDataSourceProxy</a><br> -<a href="https://hudi.blog/database-replication-with-springboot-and-mysql/" target="_blank" rel="noopener noreferrer">데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)</a><br> -<a href="https://chagokx2.tistory.com/100" target="_blank" rel="noopener noreferrer">부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기</a><br> -<a href="https://docs.docker.com/get-started/08_using_compose/" target="_blank" rel="noopener noreferrer">Use Docker Compose, Docker</a></p>]]></content> +<!-- -->로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.</p> +<pre><code class="language-java" metastring="title="MemberServiceTest"">@SpringBootTest +class MemberServiceTest { + + @Autowired + private MemberService memberService; + + @Test + void 사용자를_저장한다() { + // RoutingDataSource log: readOnly = false + memberService.save("bbiac"); + } + + @Test + void 사용자를_조회한다() { + // RoutingDataSource log: readOnly = true + assertThatThrownBy(() -> memberService.findById(MAX_VALUE)) + .isInstanceOf(NoSuchElementException.class); + } +} +</code></pre> +<p>DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.</p> +<pre><code class="language-sql">SET GLOBAL log_output = 'table'; +SET GLOBAL general_log = 1; +</code></pre> +<p>general log를 활성화 한 후 읽기 전용 메서드를 실행한다.<br> +<!-- -->server_id, 실행한 쿼리문을 확인할 수 있다.</p> +<pre><code class="language-sql">SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%'; + ++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+ +| user_host | thread_id | server_id | convert(argument using utf8) | ++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+ +| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 | ++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+ +</code></pre> +<p>확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.</p> +<pre><code class="language-sql">SET GLOBAL general_log = 0; +SHOW VARIABLES LIKE '%general%'; + ++------------------+---------------------------------+ +| Variable_name | Value | ++------------------+---------------------------------+ +| general_log | OFF | +| general_log_file | /var/lib/mysql/4b6b9db98290.log | ++------------------+---------------------------------+ +</code></pre> +<h2 id="참고-자료">참고 자료</h2> +<p>16장 복제, Real MySQL 8.0 - 백은빈, 이성욱<br> +<a href="https://dev.mysql.com/doc/refman/8.1/en/replication.html">Replication, MySQL Docs</a><br> +<a href="https://huisam.tistory.com/entry/mysql-replication">MySql - Master Slave Replication 구조 만들어보기</a><br> +<a href="https://cheese10yun.github.io/spring-transaction/">Spring 레플리케이션 트랜잭션 처리 방식</a><br> +<a href="https://github.com/kwon37xi/replication-datasource">replication-datasource</a><br> +<a href="https://www.linkedin.com/pulse/simplified-guide-mysql-replication-docker-compose-rakesh-shekhawat/">Simplified Guide to MySQL Replication with Docker Compose</a><br> +<a href="https://www.daleseo.com/dockerfile/">Dockerfile에서 자주 쓰이는 명령어</a><br> +<a href="https://dev.mysql.com/doc/refman/8.1/en/change-replication-source-to.html">CHANGE REPLICATION SOURCE TO Statement</a><br> +<a href="https://kwonnam.pe.kr/wiki/springframework/lazyconnectiondatasourceproxy">LazyConnectionDataSourceProxy</a><br> +<a href="https://hudi.blog/database-replication-with-springboot-and-mysql/">데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)</a><br> +<a href="https://chagokx2.tistory.com/100">부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기</a><br> +<a href="https://docs.docker.com/get-started/08_using_compose/">Use Docker Compose, Docker</a></p>]]></content> <category label="mysql" term="mysql"/> <category label="replication" term="replication"/> </entry> @@ -276,20 +1213,38 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/woowacourse-level3-retrospective"/> <updated>2023-08-19T00:00:00.000Z</updated> <summary type="html"><![CDATA[회고]]></summary> - <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="회고">회고<a href="#회고" class="hash-link" aria-label="회고에 대한 직접 링크" title="회고에 대한 직접 링크">​</a></h3><p>지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.<br> + <content type="html"><![CDATA[<h3 id="회고">회고</h3> +<p>지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.<br> <!-- -->레벨 3에는 기술적인 부분에서도, 기술 외적인 부분에서도 부족함이 많이 보였던 것 같다.<br> <!-- -->부족한 부분을 알았기에, 앞으로 더욱 성장할 수 있을 것 같다.<br> -<!-- -->내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="아쉬운-점">아쉬운 점<a href="#아쉬운-점" class="hash-link" aria-label="아쉬운 점에 대한 직접 링크" title="아쉬운 점에 대한 직접 링크">​</a></h3><p><strong>문서화</strong></p><p>개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.<br> +<!-- -->내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.</p> +<h3 id="아쉬운-점">아쉬운 점</h3> +<p><strong>문서화</strong></p> +<p>개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.<br> <!-- -->프로젝트를 진행하면서 내가 한 부분을 조금 더 꼼꼼하게, 이해하기 쉽게 문서화를 했더라면 팀원들에게 더욱 도움이 되었을 텐데 이 부분에 시간을 조금 더 투자하지 못했던 부분에서 아쉬움이 많이 들었다.<br> -<!-- -->방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다. </p><p><strong>내가 못하는 부분이라면 시간을 들이자</strong></p><p>잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.<br> +<!-- -->방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.</p> +<p><strong>내가 못하는 부분이라면 시간을 들이자</strong></p> +<p>잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.<br> <!-- -->말을 하기 전에 정리해서 의견을 내는 것, 발표 준비, 감정 조절 등등 -못하는 부분을 인지하고, 개선하자. </p><p><strong>컴포트 존 벗어나기</strong></p><p>조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.<br> +못하는 부분을 인지하고, 개선하자.</p> +<p><strong>컴포트 존 벗어나기</strong></p> +<p>조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.<br> <!-- -->매번 근거를 가지고 기술을 도입하고, 코드를 작성하려고 노력했다.<br> -<!-- -->하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="좋았던-점">좋았던 점<a href="#좋았던-점" class="hash-link" aria-label="좋았던 점에 대한 직접 링크" title="좋았던 점에 대한 직접 링크">​</a></h3><p><strong>좋았던 점도 문서화</strong></p><p><a href="https://tripdraw.blog" target="_blank" rel="noopener noreferrer">팀 블로그</a>도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.<br> -<!-- -->백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다. </p><p><strong>내가 디자인한 트립드로우 로고</strong></p><img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAGwCAYAAADITjAqAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAABauSURBVHgB7d1viF3lncDx59yJsZpWU6wxoqmjLthGS2vBP4u7dEqb7FIXVKIFX9Qa3xTqiyisfWeNyEKphWZgLesbxyqLi4m0wiprXHCWIlUD1bKaRljt1CjGfzSmjdaYzNn73Dg2f5wkk8w95/nd+/nANCaZ0HHM3O/8nuc551SpRYvHJhYvXLhgrJquR+sqfblK9WiqqtGPfns0AdC6uk7bq6qaSvX09jpVU52q/kOanp78y+703PbJ1dtTS6rUoI+DVU2Ppbq6IokUQHRT3QFksvua/vCuXbsnmwxaIwFb+s2JsbozsqZb8W680uIEwEDqxuzeHLM3N37nl6nP+hawj6atNd3Z8ybRAhg6U1Wdbk8f7pncNrl6KvXBvAdMuADYx1R33+ze7kR2e5pn8xqwpSvuu747Pt6W7G0BsL/eRLbt8evuTfNkXgK2dGxitD5uwUSq6rEEALP7ZbVrz83zsazYScfotBX3r5k+buRZ8QLgCFxZLxx5Nq/YpWN01BNY3us6fuFIXi68KQHAXFVp3RuPXXdzOkpHFbDekuHCkXxE8ssJAI5a9Vy1a/dVR7OkOOeAfRSvJ5KDGgDMj6nuvtjX5xqxOQVMvADokzlH7IgDJl4A9NmcInZEARMvABpyxBE7omP0Hx3YGE0A0F/dgWnBL/JJ98O942EDdtrK+36anDYEoDH1V44/vneZ1iGNHOo3exeaVelHCQCademn/+aqd3e+9IunZnuHWffA8r5XvsOGG/IC0JLt3f2wC2fbD5t1CbG77/VT8QKgRYvr4zsTs/3mJwbso3tUXZkAoE11NTbbfRM7n/z+6bCbZwDQhNykTzqVeFDAlqy83/O8ACjJ6KcWdg66cfx+hzhcsAxAobZ/sGvP2dsnV2+f+YX9J7DjRsaSeAFQnsUHTmH7BczeFwClqlO1Zt+ffxywJd+4P586HE0AUKbFS785MTbzk79OYCPTjs0DULS6M/LxFNY7xJGPJx6/cOSPCQDK9vFhjt4EtnBkwVgCgPItPmHh3mbtXUK0fAhAENNVGss/9gJWpeprCQAiqOsr8g+V/S8Aounug32286kF6SsJAALJ+2Cd1OmMJQAIZLqqR/Me2GgCgECqlL7cqevOWQkAAqmnuxNYnTx1GYBgqiovIdajCQCC6VSVCQyAcEY7CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQlqQAPrkzCUnpi+edXI6adFx3X8+IZ104nHp5EULP/F93925K+1478P0p50fps1TO9KO3o/vJpiNgLUkf0FfPbYsrbjo9HTmqSf2vtCJ49U33+u9uD6+6fW0YXJrIqVLz/9cWj56Uvdtcbpk+Snz9nc6f57z5/vpzW/3wvbUC28nyKrTVt5XJxqVv7AfWHtZL1zEl19gv3fnM70X2WGS/x6vvGhp75uw5aN7p6ym5Ijlbx42bto2dJ93/krAGiZegym/oF679sk06PLf31VfW9ZdPfh8MasG+RuIiUdeSk9tfkfMhowlxIb1llbEa+Dk5bM8jeSJYNDsu9yd/z1Lk6e/O2/8au+fNz6zd0k3T2cMPgFr2DVjZyUG06ruVDJIAcvhWv2tc9INl5/b6PLgsVh58em9t1ffei+NP7jF/uSAE7CGfbG7yc1gWn72yWkQ5KXBNdec11smjCqvcuSpbM23vyBkA8weWMN+v/6KxOA6+5qHU1SDEK7Z5InslruedYJxwJjAYMhFXCqcqzyR5cNTeRIbX7/FYY8BIWAwxFaNLUs/vP5LAxuuA+XDKJeef4plxQEhYDCE8nLhnd+/sMhThf02sz92yfmnmsaCcy9EGDJ5qfCRH48NZbz2laex3jWZ7oITloDBkMjLhLdef0HvbViWDA8nT2O/umtFbw+QeCwhwhDIU8bdt1zcu+iXg/1w9d59wPH1LybiMIHBgMvRyktl4nVoN337C929sQsTcZjAYIDNxMuS4ZHJ18DlR77ka8byo10omwkMBpR4HZ18K6oHbr+sFzLKJmAwgMTr2OTP362rL0iUTcBgwMw8ske8jk1eTrQnVjYBgwEiXvMrRyzfH5IyCRgMiBwtD0udf/l04iDe4HgQCBgMiHyBsnj1R/7cugyhPAIGA+Cma0wJ/ZSn27t/cLGTiYURMAiu9xyvb9un6bc83eYHZFIOAYPg8r4Xzbjh8nPSiotOT5RBwCCwvHRo36tZP7nxQkuJhRAwCMrSYTvyfpilxDIIGARl6bA9eSlx2J+nVgIBg4DyQyktHbbLBc7tEzAIJi8drr7cAxjblicwU1i7BAyCyd/5m77K4F6J7RIwCCRPXy5YLkf+RuLqsWWJdggYBGLfpTyrfEPRGgGDebJjZ3+f4Gv6KpO9sPYIWMNefeu9xGDq939b01e5/Ldpx4JEozZPvWsDfkBtntqR+iXy9JUn0xz3P+3cvd+vf2bRgoG5w3uewPLdOXa8198pnP0JWMMemtyaVrqX2kAaf3BL6pdI3+HnYG2YfCU9vfmd3jdsr7556Mk0RywHIH9dXHL+KSmq1f90TvfvwIuJ5lSnrbyvTjTqP9b+XegvVA52zyMvpTvufT71Q56+fnXXilS6p154O42vf7H349HKqxM5ZvkWWdFWKvKU+ffffzzRnJFPn3vV2kSj8hd4vp+aB+TFl6eNf3v4/9KP/31z6pcVFy1NKy8ud2rfuGlbuv5ffp0mHn35mPcB8xJcntomHnk5vfbW+2n52Sf3vlYiyB9nnjrtczfHBNai/B1m/gL94uhJadmpi1IbzlhyQrp0ecwTVE9tfju99ub7qQ1b39rZXRp7Pz3+zOt93/f41c9WFDmN5BfqW+569pgmrsPZ+wyu88Ls/61bv8UyYoPsgbUovwDkt43dF8G2rBpbFjZgG554pbenOMjyclqJ8cp7XHdMPN/3eM9E8ndTO9Kt11+QSpe/lsaTgDXFMXoo2KoC7/KQp4wclSZP3OU9xstvmez7tXbHauY0Is0QMChUiUfn21wiy3tj1659sviIrbh4aaIZAgaFumR5WSdVS9jfyRH73p3PpJI5nNUcAYNCXTN2VipFXsIr5XBCPjTSr0sW5kPJJ0YHjYBBgfLyYSnXCuaDFKUFIwf16RfeSSXKh27sgzVDwKBAJd2t5drbnkwl+ue7flPsflj+BoT+EzAoUCkBy/tepV6Ymz+ufPF0ifK1nfSfgEFhSlk+zIF46Imyr7PLS4klTmEOcjRDwKAwpZw+zIc2Sr8tUo5XiVOYJ040Q8CgMKWcPuznLaLmU57CSmMPrBkCBgXJN4QtYflww+TWMDelzVNYaScSTWDNEDAoSCl7J4+3eH/Oo5Fv7FySKHfQj07AoCCl3IZo46ZgAStwudMU1n8CBgUp4ckAUfa+9pVvMcXwETAoRN74L2EJMWIM8j6YB0kOHwGDQpRy8WvUELT1cNPZOInYfwIGhSjl7hv54ZER5adkM1wEDArh7g0wNwIGBcjHrksJ2Ktv2ksiBgGDApi+jt2yUxelkvhGoP8EDApQyrO/MocPiELAoAB/u/zUVIqoD2Ms7REmjvX3n4BBAUp68T1jyQkpmjw1un3T8BEwaFlpL74R9+NMX8NJwKBlpb34Xnp++7ezmqtSrqGb4QBHMwQMWlbaxJNvQhttH6y06JrAmiFg0LISl+xWfX1ZiiLHq7Q7vwtYMwQMWlbiYzdKW5I7lFVj5cX2d7+PeTuuaAQMWlbiBJanmgh7YfkAzNVjn0+lMYE1Q8CgRcvPLvfE35przkulK/Vj9HyyZggYtOiMU8u95qr0KSxPriVOXxEfCBqVgEGLSr/mquQp7O4fXJxKZPpqjoBBi0oPWJ7AVn/rnFSaW6+/oMjDL9nTL7yTaIaAQYtOPnFhKt0PV3+pqKXEGy4/t/dWKhNYcwQMWlTaXThmc/ctFxdxl/q855Wnr1LleDmB2BwBg5bk+x9GuQFt/jgfWHtZqxHL8brzxgtTyRzgaJaAQUuiPXcr7znliLWxb5eXDEuPV/b4pm2J5ggYtCTic7dyxB65c6yxgx158rvz+xcWvWw4Iy8dmsCatSABrYj42JIZ+WDH8rMXp/H1W/p25/V8cCRPXaWeNjzQU04fNk7AoCWfWRT7y+/qsWW9t3seeSlNPPryvIUshytffxbtsS7jD25JNEvAoCWRJ7B9zRxr3zC5NT00+cpRLaPlpcIcwxUXnR7yeWT539npw+YJGLQkwjVgczEzke3Y+WHvBf3pzW+nzVM7ej/f8d6H+71vXhY8o/u2fPSkXrCix3x8/YuJ5gkYtCT6EuJs8jS18uLTe2/DwOGN9jiFCC2JcjiBQxt/0PTVFgGDFkS6iJnZ5elrQ3ffj3YIGLQg4jVgHOyWu55NtEfAoAXR7sLBwfKpS3tf7RIwgDnKJytd99U+AYMWlPwkZg7vnkdfct1XAQQMWmAJMa4cLicPyyBgAEcoLx1ee9uTiTIIGLTANWAx5TtuWDosh4ABHIF80+L8RjkEDFqw7NRFiTjse5VJwAAOIccr73sdeENi2idg0IJBvZHvIPrej5+x71UoAYMWuA9iDLf87Nm0eerdRJkEDOATrFu/JW14wo16SyZg0ALH6MuW4+XQRvkEDGAf4hWHgAF8RLxiETCAJF4ROcsLDbP/VZ477n3eXTYCEjBgaOWb8+anKm/c9HoiHgEDhlK+ODlfpOw6r7gEDBg6OVrusBGfgAFDZcPkK+mOiefd23AACBgwNBzWGCwCBgy8vFSYD2s89cLbicEhYMBA27hpW7rlX39jyXAACRg07MwlrgNrQj4iP77+RUuGA0zAoGEmgf7LS4V5ydApw8EmYNCwHX8WsH7KU9e6B7ckBp+AAQPB1DV8BAwIzV7X8BIwIKx8wvCOif81dQ0pAQPCcV0XmYABYeTlwolHX3ZIgx4BA0LIe1z5gZMuQ2CGgAFFc7qQ2QgYNMwL8ZHJ4cqnC+1zMRsBA4oiXBwpAQOKIFzMlYABrRIujpaAQQvyPtiZpw73XemFi2MlYECjNkxuTQ9NviJcHDMBA/pu5gLke/7zJddxMW8EDFrw2pvvD8US4uapd7vT1ta04YlXhIt5J2DAvLO/RRMEDFqw9a2d6ZJ0ShoklglpmoABx8S0RVsEDFoQfULJe1uPb9pm2qJVAgYtyMtt0eSPecPkK71wmbYogYBBC/60c3eKIEcrT1t5iXDz7981bVEUAYMWvLtzVypZnrDypOX4OyUTMGhBiVEQLaIRMGjBa2+9n9o2szwoWkQlYNCCHX9uJxY5WjlYv87T1jOvixahCRhhlTDFHK18N/qm7kj/6pvvpY2bXnd6kIEjYEPu6RfeSVHlU3GR5XsErrnmvDTf9l0azOHKAYNBJGBDLk8B+QXvpEXHpUjyJBF9+eueR15Kq8aWzcsUloM1cwjDcXeGhYDRu8bn1usvSJHk6SW6/I3Dtbc9mR64/bI5R2xmWXDz1A57WQyt6rSV99WJoXfr6gvSDd86N0Wwbv2WNP7gi2lQ5Hj95MavpkvOn/3mvjlYT29+p3f44unNb1sWhCRg7OPS8z/XW9JaPnpy70W1lGXFPKnkpc6ZJbJBPYiQP/8rLlqali1Z1Pv51jd3mrDgEAQMgJA6CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAELKAZtKABDLdhMYAAFVU51UV1MJACKpp7d3qmr6DwkAAqk63Qmsnq6eSwAQSV3/oVNbQgQgmunpyc6uPbsnEwAE8pfd6bnO9snV25Oj9ABEUaWp3K69x+jr+uEEAAFUKU3mH3sBq6c7kwkAAqjqqjd09QKW98HqOm1PAFC493ftPbvRC1heS6yq+n8SABSsqtK9H53d+OvNfKvp6XUJAAo2s3zY++d9f2PJivv+2K3b4gQApanS1BuPXXf2zE/3u5lvp6rHEwAUqJpOt+/78/0C9pdd0+sc5gCgON3pK43smdz3l/YLWO/CMFMYAIWp6vrn2/5r9dS+v3bQ88DyFNYrHQCUoNukbRu/u/bAXz4oYL0j9QesMwJAW2ZrUjXbHzjtH+5/ItX1WAKA1lS/fGPjd676pN/pzPpHqt2rHegAoC11d1Gw6uy+ebbfnzVgebOsqi0lAtCOTp1uPvDgxr5GDvWHd778i6c+fc6Vn+2OY5cmAGhKVY2/sfG6Hx3qXTrpMD74cHptnarnEgA047dvPPadmw73TocNWO/asM7uqxytB6Dvuq2pOnuuPLJ3PUJL/3FitK5Hnujuqo0mAJhvOV7Vnq8fat9r/3efAxEDoC/mGK+9f2SORAyAeXUU8coOuwd2oN7x+u7/kYMdAMyD3x5NvLI5T2D7Om3Fz9elqlqTAGCuqmr8gw92r515wvKc/3g6RktX3Hf9dEo/9SBMAI5E7w4bVbr9jceuW5eOwTEHLOvti013uh9IdUUCgNnU1WQ1snv10SwZHmheAjYjT2N1J93mgAcA+8kHNabT7dsev+7eNE/mNWAzlq78+dq6qr4rZADDLS8XdlI9np81ebR7XbPpS8CyvKyY9oyMmcgAhk8/wzWjbwHb15JvTFzZGelcWafuVAbAQOodzkjdPa7p3ePb/nv1ZOqzRgI2Y/HYxOKFI2msF7Oq+prJDCC8qVTVD9e7pyd37UmT/Zq2PkmjATtQDtqnFqSvpE5nbLquzuqWe7Rb8MXdT8ZolRzLByjEVO9/62qqTnV+VuRv63rPVNPBOtD/A6oeNVega6lDAAAAAElFTkSuQmCC" width="100" class="img_ev3q"><p>트립드로우 로고를 만들었다.<br> +<!-- -->하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.</p> +<h3 id="좋았던-점">좋았던 점</h3> +<p><strong>좋았던 점도 문서화</strong></p> +<p><a href="https://tripdraw.blog/">팀 블로그</a>도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.<br> +<!-- -->백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.</p> +<p><strong>내가 디자인한 트립드로우 로고</strong></p> +<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAbAAAAGwCAYAAADITjAqAAAACXBIWXMAACxLAAAsSwGlPZapAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAABauSURBVHgB7d1viF3lncDx59yJsZpWU6wxoqmjLthGS2vBP4u7dEqb7FIXVKIFX9Qa3xTqiyisfWeNyEKphWZgLesbxyqLi4m0wiprXHCWIlUD1bKaRljt1CjGfzSmjdaYzNn73Dg2f5wkk8w95/nd+/nANCaZ0HHM3O/8nuc551SpRYvHJhYvXLhgrJquR+sqfblK9WiqqtGPfns0AdC6uk7bq6qaSvX09jpVU52q/kOanp78y+703PbJ1dtTS6rUoI+DVU2Ppbq6IokUQHRT3QFksvua/vCuXbsnmwxaIwFb+s2JsbozsqZb8W680uIEwEDqxuzeHLM3N37nl6nP+hawj6atNd3Z8ybRAhg6U1Wdbk8f7pncNrl6KvXBvAdMuADYx1R33+ze7kR2e5pn8xqwpSvuu747Pt6W7G0BsL/eRLbt8evuTfNkXgK2dGxitD5uwUSq6rEEALP7ZbVrz83zsazYScfotBX3r5k+buRZ8QLgCFxZLxx5Nq/YpWN01BNY3us6fuFIXi68KQHAXFVp3RuPXXdzOkpHFbDekuHCkXxE8ssJAI5a9Vy1a/dVR7OkOOeAfRSvJ5KDGgDMj6nuvtjX5xqxOQVMvADokzlH7IgDJl4A9NmcInZEARMvABpyxBE7omP0Hx3YGE0A0F/dgWnBL/JJ98O942EDdtrK+36anDYEoDH1V44/vneZ1iGNHOo3exeaVelHCQCademn/+aqd3e+9IunZnuHWffA8r5XvsOGG/IC0JLt3f2wC2fbD5t1CbG77/VT8QKgRYvr4zsTs/3mJwbso3tUXZkAoE11NTbbfRM7n/z+6bCbZwDQhNykTzqVeFDAlqy83/O8ACjJ6KcWdg66cfx+hzhcsAxAobZ/sGvP2dsnV2+f+YX9J7DjRsaSeAFQnsUHTmH7BczeFwClqlO1Zt+ffxywJd+4P586HE0AUKbFS785MTbzk79OYCPTjs0DULS6M/LxFNY7xJGPJx6/cOSPCQDK9vFhjt4EtnBkwVgCgPItPmHh3mbtXUK0fAhAENNVGss/9gJWpeprCQAiqOsr8g+V/S8Aounug32286kF6SsJAALJ+2Cd1OmMJQAIZLqqR/Me2GgCgECqlL7cqevOWQkAAqmnuxNYnTx1GYBgqiovIdajCQCC6VSVCQyAcEY7CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQlqQAPrkzCUnpi+edXI6adFx3X8+IZ104nHp5EULP/F93925K+1478P0p50fps1TO9KO3o/vJpiNgLUkf0FfPbYsrbjo9HTmqSf2vtCJ49U33+u9uD6+6fW0YXJrIqVLz/9cWj56Uvdtcbpk+Snz9nc6f57z5/vpzW/3wvbUC28nyKrTVt5XJxqVv7AfWHtZL1zEl19gv3fnM70X2WGS/x6vvGhp75uw5aN7p6ym5Ijlbx42bto2dJ93/krAGiZegym/oF679sk06PLf31VfW9ZdPfh8MasG+RuIiUdeSk9tfkfMhowlxIb1llbEa+Dk5bM8jeSJYNDsu9yd/z1Lk6e/O2/8au+fNz6zd0k3T2cMPgFr2DVjZyUG06ruVDJIAcvhWv2tc9INl5/b6PLgsVh58em9t1ffei+NP7jF/uSAE7CGfbG7yc1gWn72yWkQ5KXBNdec11smjCqvcuSpbM23vyBkA8weWMN+v/6KxOA6+5qHU1SDEK7Z5InslruedYJxwJjAYMhFXCqcqzyR5cNTeRIbX7/FYY8BIWAwxFaNLUs/vP5LAxuuA+XDKJeef4plxQEhYDCE8nLhnd+/sMhThf02sz92yfmnmsaCcy9EGDJ5qfCRH48NZbz2laex3jWZ7oITloDBkMjLhLdef0HvbViWDA8nT2O/umtFbw+QeCwhwhDIU8bdt1zcu+iXg/1w9d59wPH1LybiMIHBgMvRyktl4nVoN337C929sQsTcZjAYIDNxMuS4ZHJ18DlR77ka8byo10omwkMBpR4HZ18K6oHbr+sFzLKJmAwgMTr2OTP362rL0iUTcBgwMw8ske8jk1eTrQnVjYBgwEiXvMrRyzfH5IyCRgMiBwtD0udf/l04iDe4HgQCBgMiHyBsnj1R/7cugyhPAIGA+Cma0wJ/ZSn27t/cLGTiYURMAiu9xyvb9un6bc83eYHZFIOAYPg8r4Xzbjh8nPSiotOT5RBwCCwvHRo36tZP7nxQkuJhRAwCMrSYTvyfpilxDIIGARl6bA9eSlx2J+nVgIBg4DyQyktHbbLBc7tEzAIJi8drr7cAxjblicwU1i7BAyCyd/5m77K4F6J7RIwCCRPXy5YLkf+RuLqsWWJdggYBGLfpTyrfEPRGgGDebJjZ3+f4Gv6KpO9sPYIWMNefeu9xGDq939b01e5/Ldpx4JEozZPvWsDfkBtntqR+iXy9JUn0xz3P+3cvd+vf2bRgoG5w3uewPLdOXa8198pnP0JWMMemtyaVrqX2kAaf3BL6pdI3+HnYG2YfCU9vfmd3jdsr7556Mk0RywHIH9dXHL+KSmq1f90TvfvwIuJ5lSnrbyvTjTqP9b+XegvVA52zyMvpTvufT71Q56+fnXXilS6p154O42vf7H349HKqxM5ZvkWWdFWKvKU+ffffzzRnJFPn3vV2kSj8hd4vp+aB+TFl6eNf3v4/9KP/31z6pcVFy1NKy8ud2rfuGlbuv5ffp0mHn35mPcB8xJcntomHnk5vfbW+2n52Sf3vlYiyB9nnjrtczfHBNai/B1m/gL94uhJadmpi1IbzlhyQrp0ecwTVE9tfju99ub7qQ1b39rZXRp7Pz3+zOt93/f41c9WFDmN5BfqW+569pgmrsPZ+wyu88Ls/61bv8UyYoPsgbUovwDkt43dF8G2rBpbFjZgG554pbenOMjyclqJ8cp7XHdMPN/3eM9E8ndTO9Kt11+QSpe/lsaTgDXFMXoo2KoC7/KQp4wclSZP3OU9xstvmez7tXbHauY0Is0QMChUiUfn21wiy3tj1659sviIrbh4aaIZAgaFumR5WSdVS9jfyRH73p3PpJI5nNUcAYNCXTN2VipFXsIr5XBCPjTSr0sW5kPJJ0YHjYBBgfLyYSnXCuaDFKUFIwf16RfeSSXKh27sgzVDwKBAJd2t5drbnkwl+ue7flPsflj+BoT+EzAoUCkBy/tepV6Ymz+ufPF0ifK1nfSfgEFhSlk+zIF46Imyr7PLS4klTmEOcjRDwKAwpZw+zIc2Sr8tUo5XiVOYJ040Q8CgMKWcPuznLaLmU57CSmMPrBkCBgXJN4QtYflww+TWMDelzVNYaScSTWDNEDAoSCl7J4+3eH/Oo5Fv7FySKHfQj07AoCCl3IZo46ZgAStwudMU1n8CBgUp4ckAUfa+9pVvMcXwETAoRN74L2EJMWIM8j6YB0kOHwGDQpRy8WvUELT1cNPZOInYfwIGhSjl7hv54ZER5adkM1wEDArh7g0wNwIGBcjHrksJ2Ktv2ksiBgGDApi+jt2yUxelkvhGoP8EDApQyrO/MocPiELAoAB/u/zUVIqoD2Ms7REmjvX3n4BBAUp68T1jyQkpmjw1un3T8BEwaFlpL74R9+NMX8NJwKBlpb34Xnp++7ezmqtSrqGb4QBHMwQMWlbaxJNvQhttH6y06JrAmiFg0LISl+xWfX1ZiiLHq7Q7vwtYMwQMWlbiYzdKW5I7lFVj5cX2d7+PeTuuaAQMWlbiBJanmgh7YfkAzNVjn0+lMYE1Q8CgRcvPLvfE35przkulK/Vj9HyyZggYtOiMU8u95qr0KSxPriVOXxEfCBqVgEGLSr/mquQp7O4fXJxKZPpqjoBBi0oPWJ7AVn/rnFSaW6+/oMjDL9nTL7yTaIaAQYtOPnFhKt0PV3+pqKXEGy4/t/dWKhNYcwQMWlTaXThmc/ctFxdxl/q855Wnr1LleDmB2BwBg5bk+x9GuQFt/jgfWHtZqxHL8brzxgtTyRzgaJaAQUuiPXcr7znliLWxb5eXDEuPV/b4pm2J5ggYtCTic7dyxB65c6yxgx158rvz+xcWvWw4Iy8dmsCatSABrYj42JIZ+WDH8rMXp/H1W/p25/V8cCRPXaWeNjzQU04fNk7AoCWfWRT7y+/qsWW9t3seeSlNPPryvIUshytffxbtsS7jD25JNEvAoCWRJ7B9zRxr3zC5NT00+cpRLaPlpcIcwxUXnR7yeWT539npw+YJGLQkwjVgczEzke3Y+WHvBf3pzW+nzVM7ej/f8d6H+71vXhY8o/u2fPSkXrCix3x8/YuJ5gkYtCT6EuJs8jS18uLTe2/DwOGN9jiFCC2JcjiBQxt/0PTVFgGDFkS6iJnZ5elrQ3ffj3YIGLQg4jVgHOyWu55NtEfAoAXR7sLBwfKpS3tf7RIwgDnKJytd99U+AYMWlPwkZg7vnkdfct1XAQQMWmAJMa4cLicPyyBgAEcoLx1ee9uTiTIIGLTANWAx5TtuWDosh4ABHIF80+L8RjkEDFqw7NRFiTjse5VJwAAOIccr73sdeENi2idg0IJBvZHvIPrej5+x71UoAYMWuA9iDLf87Nm0eerdRJkEDOATrFu/JW14wo16SyZg0ALH6MuW4+XQRvkEDGAf4hWHgAF8RLxiETCAJF4ROcsLDbP/VZ477n3eXTYCEjBgaOWb8+anKm/c9HoiHgEDhlK+ODlfpOw6r7gEDBg6OVrusBGfgAFDZcPkK+mOiefd23AACBgwNBzWGCwCBgy8vFSYD2s89cLbicEhYMBA27hpW7rlX39jyXAACRg07MwlrgNrQj4iP77+RUuGA0zAoGEmgf7LS4V5ydApw8EmYNCwHX8WsH7KU9e6B7ckBp+AAQPB1DV8BAwIzV7X8BIwIKx8wvCOif81dQ0pAQPCcV0XmYABYeTlwolHX3ZIgx4BA0LIe1z5gZMuQ2CGgAFFc7qQ2QgYNMwL8ZHJ4cqnC+1zMRsBA4oiXBwpAQOKIFzMlYABrRIujpaAQQvyPtiZpw73XemFi2MlYECjNkxuTQ9NviJcHDMBA/pu5gLke/7zJddxMW8EDFrw2pvvD8US4uapd7vT1ta04YlXhIt5J2DAvLO/RRMEDFqw9a2d6ZJ0ShoklglpmoABx8S0RVsEDFoQfULJe1uPb9pm2qJVAgYtyMtt0eSPecPkK71wmbYogYBBC/60c3eKIEcrT1t5iXDz7981bVEUAYMWvLtzVypZnrDypOX4OyUTMGhBiVEQLaIRMGjBa2+9n9o2szwoWkQlYNCCHX9uJxY5WjlYv87T1jOvixahCRhhlTDFHK18N/qm7kj/6pvvpY2bXnd6kIEjYEPu6RfeSVHlU3GR5XsErrnmvDTf9l0azOHKAYNBJGBDLk8B+QXvpEXHpUjyJBF9+eueR15Kq8aWzcsUloM1cwjDcXeGhYDRu8bn1usvSJHk6SW6/I3Dtbc9mR64/bI5R2xmWXDz1A57WQyt6rSV99WJoXfr6gvSDd86N0Wwbv2WNP7gi2lQ5Hj95MavpkvOn/3mvjlYT29+p3f44unNb1sWhCRg7OPS8z/XW9JaPnpy70W1lGXFPKnkpc6ZJbJBPYiQP/8rLlqali1Z1Pv51jd3mrDgEAQMgJA6CQACEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAEISMABCEjAAQhIwAELKAZtKABDLdhMYAAFVU51UV1MJACKpp7d3qmr6DwkAAqk63Qmsnq6eSwAQSV3/oVNbQgQgmunpyc6uPbsnEwAE8pfd6bnO9snV25Oj9ABEUaWp3K69x+jr+uEEAAFUKU3mH3sBq6c7kwkAAqjqqjd09QKW98HqOm1PAFC493ftPbvRC1heS6yq+n8SABSsqtK9H53d+OvNfKvp6XUJAAo2s3zY++d9f2PJivv+2K3b4gQApanS1BuPXXf2zE/3u5lvp6rHEwAUqJpOt+/78/0C9pdd0+sc5gCgON3pK43smdz3l/YLWO/CMFMYAIWp6vrn2/5r9dS+v3bQ88DyFNYrHQCUoNukbRu/u/bAXz4oYL0j9QesMwJAW2ZrUjXbHzjtH+5/ItX1WAKA1lS/fGPjd676pN/pzPpHqt2rHegAoC11d1Gw6uy+ebbfnzVgebOsqi0lAtCOTp1uPvDgxr5GDvWHd778i6c+fc6Vn+2OY5cmAGhKVY2/sfG6Hx3qXTrpMD74cHptnarnEgA047dvPPadmw73TocNWO/asM7uqxytB6Dvuq2pOnuuPLJ3PUJL/3FitK5Hnujuqo0mAJhvOV7Vnq8fat9r/3efAxEDoC/mGK+9f2SORAyAeXUU8coOuwd2oN7x+u7/kYMdAMyD3x5NvLI5T2D7Om3Fz9elqlqTAGCuqmr8gw92r515wvKc/3g6RktX3Hf9dEo/9SBMAI5E7w4bVbr9jceuW5eOwTEHLOvti013uh9IdUUCgNnU1WQ1snv10SwZHmheAjYjT2N1J93mgAcA+8kHNabT7dsev+7eNE/mNWAzlq78+dq6qr4rZADDLS8XdlI9np81ebR7XbPpS8CyvKyY9oyMmcgAhk8/wzWjbwHb15JvTFzZGelcWafuVAbAQOodzkjdPa7p3ePb/nv1ZOqzRgI2Y/HYxOKFI2msF7Oq+prJDCC8qVTVD9e7pyd37UmT/Zq2PkmjATtQDtqnFqSvpE5nbLquzuqWe7Rb8MXdT8ZolRzLByjEVO9/62qqTnV+VuRv63rPVNPBOtD/A6oeNVega6lDAAAAAElFTkSuQmCC" width="100"> +<p>트립드로우 로고를 만들었다.<br> <!-- -->팀원들이 대표 색상(파란색)을 정해줬고, 주말 동안 신나게 로고 디자인을 했던 것 같다.<br> -<!-- -->아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다. </p><p><strong>기술 선택의 이유</strong></p><p>기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.<br> -<!-- -->100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="마치며">마치며<a href="#마치며" class="hash-link" aria-label="마치며에 대한 직접 링크" title="마치며에 대한 직접 링크">​</a></h3><p>플레이스토어에 앱이 올라가 있는 거 너무 신기하다.<br> +<!-- -->아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.</p> +<p><strong>기술 선택의 이유</strong></p> +<p>기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.<br> +<!-- -->100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.</p> +<h3 id="마치며">마치며</h3> +<p>플레이스토어에 앱이 올라가 있는 거 너무 신기하다.<br> <!-- -->안드로이드 브레멘 음악대(멧돼지, 수달, 핑구), 그리고 백엔드 팀원들(체인저, 후추, 리오) 너무 고생이 많았다.</p>]]></content> <category label="Woowahan Techcourse" term="Woowahan Techcourse"/> <category label="Retrospective" term="Retrospective"/> @@ -300,26 +1255,88 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/cloudwatch"/> <updated>2023-08-17T00:00:00.000Z</updated> <summary type="html"><![CDATA[CloudWatch]]></summary> - <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="cloudwatch">CloudWatch<a href="#cloudwatch" class="hash-link" aria-label="CloudWatch에 대한 직접 링크" title="CloudWatch에 대한 직접 링크">​</a></h2><p>AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.<br> + <content type="html"><![CDATA[<h2 id="cloudwatch">CloudWatch</h2> +<p>AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.<br> <!-- -->지표를 감시하여 알림을 보내는 기능도 제공한다.<br> <!-- -->프리티어를 사용하지 않는 경우 대시보드당 3$/M 의 비용이 청구되고, 지표나 로그의 양에 따라 비용이 추가적으로 청구된다.<br> -<!-- -->요금 정보에 대한 자세한 정보는 <a href="https://aws.amazon.com/ko/cloudwatch/pricing/" target="_blank" rel="noopener noreferrer">다음 링크</a>에서 확인할 수 있다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="cloudwatch-metrics">CloudWatch Metrics<a href="#cloudwatch-metrics" class="hash-link" aria-label="CloudWatch Metrics에 대한 직접 링크" title="CloudWatch Metrics에 대한 직접 링크">​</a></h2><p>기본적으로 5분마다 지표에 대한 정보가 수집된다.<br> +<!-- -->요금 정보에 대한 자세한 정보는 <a href="https://aws.amazon.com/ko/cloudwatch/pricing/">다음 링크</a>에서 확인할 수 있다.</p> +<h2 id="cloudwatch-metrics">CloudWatch Metrics</h2> +<p>기본적으로 5분마다 지표에 대한 정보가 수집된다.<br> <!-- -->세부 모니터링(Detailed Monitoring)을 활성화하면 1분마다 지표를 수집한다.<br> -<!-- -->대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.</p><p><img loading="lazy" alt="./cloudwatch1.png" src="/assets/images/cloudwatch1-859296155df6c20d0846f1388022a86c.png" width="3214" height="1636" class="img_ev3q"></p><p>CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="cloudwatch-agent-설치">CloudWatch Agent 설치<a href="#cloudwatch-agent-설치" class="hash-link" aria-label="CloudWatch Agent 설치에 대한 직접 링크" title="CloudWatch Agent 설치에 대한 직접 링크">​</a></h2><p>CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="iam-역할-설정">IAM 역할 설정<a href="#iam-역할-설정" class="hash-link" aria-label="IAM 역할 설정에 대한 직접 링크" title="IAM 역할 설정에 대한 직접 링크">​</a></h3><p>기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.<br> -<!-- -->IAM → 역할에서 역할 생성을 클릭한다.</p><p><img loading="lazy" alt="./cloudwatch2.png" src="/assets/images/cloudwatch2-ca9c26868dec08ea7133e2774f49798a.png" width="2614" height="1602" class="img_ev3q"></p><p>CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.</p><p><img loading="lazy" alt="./cloudwatch3.png" src="/assets/images/cloudwatch3-da10422b87e1901286b6d3e85e2c01cc.png" width="2650" height="1616" class="img_ev3q"></p><p>EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.<br> -<!-- -->작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.</p><p><img loading="lazy" alt="./cloudwatch4.png" src="/assets/images/cloudwatch4-1e7eddc7e8dd890ac18352e900df8e07.png" width="1764" height="800" class="img_ev3q"></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="설치">설치<a href="#설치" class="hash-link" aria-label="설치에 대한 직접 링크" title="설치에 대한 직접 링크">​</a></h3><p>환경은 다음과 같다. </p><p>OS: ubuntu 22.04<br> -<!-- -->인스턴스 유형: t4g.small (ARM64) </p><p>아래 명령어를 입력하여 설치한다.</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">wget</span><span class="token plain"> https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">sudo</span><span class="token plain"> dpkg -i -E ./amazon-cloudwatch-agent.deb</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><a href="https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html" target="_blank" rel="noopener noreferrer">사용 설명서</a>에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="wizard">Wizard<a href="#wizard" class="hash-link" aria-label="Wizard에 대한 직접 링크" title="Wizard에 대한 직접 링크">​</a></h3><p>CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.<br> +<!-- -->대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.</p> +<p><img alt="./cloudwatch1.png" src="https://greeng00se.github.io/assets/images/cloudwatch1-859296155df6c20d0846f1388022a86c.png" width="3214" height="1636"></p> +<p>CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.</p> +<h2 id="cloudwatch-agent-설치">CloudWatch Agent 설치</h2> +<p>CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.</p> +<h3 id="iam-역할-설정">IAM 역할 설정</h3> +<p>기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.<br> +<!-- -->IAM → 역할에서 역할 생성을 클릭한다.</p> +<p><img alt="./cloudwatch2.png" src="https://greeng00se.github.io/assets/images/cloudwatch2-ca9c26868dec08ea7133e2774f49798a.png" width="2614" height="1602"></p> +<p>CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.</p> +<p><img alt="./cloudwatch3.png" src="https://greeng00se.github.io/assets/images/cloudwatch3-da10422b87e1901286b6d3e85e2c01cc.png" width="2650" height="1616"></p> +<p>EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.<br> +<!-- -->작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.</p> +<p><img alt="./cloudwatch4.png" src="https://greeng00se.github.io/assets/images/cloudwatch4-1e7eddc7e8dd890ac18352e900df8e07.png" width="1764" height="800"></p> +<h3 id="설치">설치</h3> +<p>환경은 다음과 같다.</p> +<p>OS: ubuntu 22.04<br> +<!-- -->인스턴스 유형: t4g.small (ARM64)</p> +<p>아래 명령어를 입력하여 설치한다.</p> +<pre><code class="language-bash">wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb +sudo dpkg -i -E ./amazon-cloudwatch-agent.deb +</code></pre> +<p><a href="https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html">사용 설명서</a>에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.</p> +<h3 id="wizard">Wizard</h3> +<p>CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.<br> <!-- -->로그를 수집하도록 설정하는 경우 Wizard 실행 명령어 입력 전 log 파일의 절대 경로를 복사해두는 것이 좋다.<br> -<!-- -->아래의 명령어를 입력하여 Wizard를 실행할 수 있다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">sudo</span><span class="token plain"> /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.<br> -<!-- -->로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다. </p><p><img loading="lazy" alt="./cloudwatch5.png" src="/assets/images/cloudwatch5-67d1bd59d4552f4fe481452eddc78a5e.png" width="2320" height="1328" class="img_ev3q"></p><p>중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Do you want to store the config </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">in</span><span class="token plain"> the SSM parameter store?</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">1</span><span class="token plain">. </span><span class="token function" style="color:rgb(80, 250, 123)">yes</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token number">2</span><span class="token plain">. no</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>추가적으로 설정하지 않는 경우 2번을 선택한다.<br> -<!-- -->Parameter Store 관리에 대한 내용은 다음의 <a href="https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/" target="_blank" rel="noopener noreferrer">문서</a>를 참고하면 좋을 거 같다.<br> -<!-- -->설정이 완료되면 <code>/opt/aws/amazon-cloudwatch-agent/bin/config.json</code> 에 설정에 대한 내용이 저장된다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="설정-파일-적용">설정 파일 적용<a href="#설정-파일-적용" class="hash-link" aria-label="설정 파일 적용에 대한 직접 링크" title="설정 파일 적용에 대한 직접 링크">​</a></h3><p>아래의 명령어를 입력하여 설정파일을 적용할 수 있다.<br> -<!-- -->file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">sudo</span><span class="token plain"> /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="typesdb-no-such-file-or-directory-에러">types.db: no such file or directory 에러<a href="#typesdb-no-such-file-or-directory-에러" class="hash-link" aria-label="types.db: no such file or directory 에러에 대한 직접 링크" title="types.db: no such file or directory 에러에 대한 직접 링크">​</a></h3><p>다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Error running agent: Error loading config </span><span class="token function" style="color:rgb(80, 250, 123)">file</span><span class="token plain"> /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, </span><span class="token function" style="color:rgb(80, 250, 123)">open</span><span class="token plain"> /usr/share/collectd/types.db: no such </span><span class="token function" style="color:rgb(80, 250, 123)">file</span><span class="token plain"> or directory</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>types.db 파일 생성</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">sudo</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">mkdir</span><span class="token plain"> /usr/share/collectd</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token function" style="color:rgb(80, 250, 123)">sudo</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">touch</span><span class="token plain"> /usr/share/collectd/types.db</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="지표-확인">지표 확인<a href="#지표-확인" class="hash-link" aria-label="지표 확인에 대한 직접 링크" title="지표 확인에 대한 직접 링크">​</a></h3><p>CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다. </p><p><img loading="lazy" alt="./cloudwatch6.png" src="/assets/images/cloudwatch6-06ead809f7510938baee41505bc72b97.png" width="2638" height="708" class="img_ev3q"></p><p>다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다. </p><div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"metrics"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"namespace"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"2023-hello-world"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ......</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="로그">로그<a href="#로그" class="hash-link" aria-label="로그에 대한 직접 링크" title="로그에 대한 직접 링크">​</a></h3><p>CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.</p><p><img loading="lazy" alt="./cloudwatch7.png" src="/assets/images/cloudwatch7-a86dfc0db307ddf7d1660d2b9e419c96.png" width="2792" height="1652" class="img_ev3q"></p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h2><p><a href="https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html" target="_blank" rel="noopener noreferrer">CloudWatch란 무엇입니까?</a><br> -<a href="https://aws.amazon.com/ko/cloudwatch/pricing/" target="_blank" rel="noopener noreferrer">Amazon CloudWatch 요금</a><br> -<a href="https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html" target="_blank" rel="noopener noreferrer">Linux 인스턴스 지표</a><br> -<a href="https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html" target="_blank" rel="noopener noreferrer">서버에 CloudWatch 에이전트 설치 및 실행</a><br> -<a href="https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/" target="_blank" rel="noopener noreferrer">CloudWatch Agent를 Parameter Store에서 관리해 보기</a><br> -<a href="https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html" target="_blank" rel="noopener noreferrer">CloudWatch에이전트 구성 파일</a></p>]]></content> +<!-- -->아래의 명령어를 입력하여 Wizard를 실행할 수 있다.</p> +<pre><code class="language-bash">sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard +</code></pre> +<p>설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.<br> +<!-- -->로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.</p> +<p><img alt="./cloudwatch5.png" src="https://greeng00se.github.io/assets/images/cloudwatch5-67d1bd59d4552f4fe481452eddc78a5e.png" width="2320" height="1328"></p> +<p>중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.</p> +<pre><code class="language-bash">Do you want to store the config in the SSM parameter store? +1. yes +2. no +</code></pre> +<p>추가적으로 설정하지 않는 경우 2번을 선택한다.<br> +<!-- -->Parameter Store 관리에 대한 내용은 다음의 <a href="https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/">문서</a>를 참고하면 좋을 거 같다.<br> +<!-- -->설정이 완료되면 <code>/opt/aws/amazon-cloudwatch-agent/bin/config.json</code> 에 설정에 대한 내용이 저장된다.</p> +<h3 id="설정-파일-적용">설정 파일 적용</h3> +<p>아래의 명령어를 입력하여 설정파일을 적용할 수 있다.<br> +<!-- -->file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.</p> +<pre><code class="language-bash">sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json +</code></pre> +<h3 id="typesdb-no-such-file-or-directory-에러">types.db: no such file or directory 에러</h3> +<p>다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.</p> +<pre><code class="language-bash">Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory +</code></pre> +<p>types.db 파일 생성</p> +<pre><code class="language-bash">sudo mkdir /usr/share/collectd +sudo touch /usr/share/collectd/types.db +</code></pre> +<h3 id="지표-확인">지표 확인</h3> +<p>CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.</p> +<p><img alt="./cloudwatch6.png" src="https://greeng00se.github.io/assets/images/cloudwatch6-06ead809f7510938baee41505bc72b97.png" width="2638" height="708"></p> +<p>다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.</p> +<pre><code class="language-json">{ + "metrics": { + "namespace": "2023-hello-world", + ...... + }, +} +</code></pre> +<h3 id="로그">로그</h3> +<p>CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.</p> +<p><img alt="./cloudwatch7.png" src="https://greeng00se.github.io/assets/images/cloudwatch7-a86dfc0db307ddf7d1660d2b9e419c96.png" width="2792" height="1652"></p> +<h2 id="참고-자료">참고 자료</h2> +<p><a href="https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html">CloudWatch란 무엇입니까?</a><br> +<a href="https://aws.amazon.com/ko/cloudwatch/pricing/">Amazon CloudWatch 요금</a><br> +<a href="https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/viewing_metrics_with_cloudwatch.html">Linux 인스턴스 지표</a><br> +<a href="https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/install-CloudWatch-Agent-commandline-fleet.html">서버에 CloudWatch 에이전트 설치 및 실행</a><br> +<a href="https://dev.classmethod.jp/articles/manage-the-cloudwatch-agent-from-the-parameter-store/">CloudWatch Agent를 Parameter Store에서 관리해 보기</a><br> +<a href="https://docs.aws.amazon.com/ko_kr/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html">CloudWatch에이전트 구성 파일</a></p>]]></content> <category label="cloudwatch" term="cloudwatch"/> <category label="log" term="log"/> <category label="monitoring" term="monitoring"/> @@ -330,33 +1347,213 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/route-image-async-with-event"/> <updated>2023-08-13T00:00:00.000Z</updated> <summary type="html"><![CDATA[이전 글]]></summary> - <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="이전-글">이전 글<a href="#이전-글" class="hash-link" aria-label="이전 글에 대한 직접 링크" title="이전 글에 대한 직접 링크">​</a></h2><p><a href="/route-image-intro">경로 이미지 생성하기 - 기술 선택</a><br> -<a href="/route-image-implementation">경로 이미지 생성하기 - 구현</a></p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="개요">개요<a href="#개요" class="hash-link" aria-label="개요에 대한 직접 링크" title="개요에 대한 직접 링크">​</a></h2><p>현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.<br> + <content type="html"><![CDATA[<h2 id="이전-글">이전 글</h2> +<p><a href="https://greeng00se.github.io/route-image-intro">경로 이미지 생성하기 - 기술 선택</a><br> +<a href="https://greeng00se.github.io/route-image-implementation">경로 이미지 생성하기 - 구현</a></p> +<h2 id="개요">개요</h2> +<p>현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.<br> <!-- -->경로 이미지 생성의 경우 위치 정보의 개수에 정비례하여 생성 시간이 증가한다.<br> -<!-- -->따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="주기능의-응답속도-개선">주기능의 응답속도 개선<a href="#주기능의-응답속도-개선" class="hash-link" aria-label="주기능의 응답속도 개선에 대한 직접 링크" title="주기능의 응답속도 개선에 대한 직접 링크">​</a></h3><p>여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.<br> +<!-- -->따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.</p> +<h3 id="주기능의-응답속도-개선">주기능의 응답속도 개선</h3> +<p>여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.<br> <!-- -->하지만 현재 여행 종료와 감상 생성의 응답 속도가 경로 이미지 생성 시간에 영향을 받고 있다.<br> <!-- -->경로 이미지 생성은 비동기 처리하여도 애플리케이션 사용에 문제가 되지 않는다.<br> -<!-- -->소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="확장성-대비">확장성 대비<a href="#확장성-대비" class="hash-link" aria-label="확장성 대비에 대한 직접 링크" title="확장성 대비에 대한 직접 링크">​</a></h3><p>현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.<br> +<!-- -->소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.</p> +<h3 id="확장성-대비">확장성 대비</h3> +<p>현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.<br> <!-- -->조금 더 짧은 간격으로 위치 정보를 그리는 경우 하나의 여행에 많은 위치 정보가 저장될 수밖에 없고 따라서 경로 이미지 생성에 걸리는 시간이 더 길어질 수 있다.<br> -<!-- -->따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="비동기-처리">비동기 처리<a href="#비동기-처리" class="hash-link" aria-label="비동기 처리에 대한 직접 링크" title="비동기 처리에 대한 직접 링크">​</a></h2><p>@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="비동기-설정">비동기 설정<a href="#비동기-설정" class="hash-link" aria-label="비동기 설정에 대한 직접 링크" title="비동기 설정에 대한 직접 링크">​</a></h3><p>사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.<br> -<!-- -->해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">AsyncConfig</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@EnableAsync</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Configuration</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">AsyncConfig</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다. </p><blockquote><p>In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. -7.7. Task Execution and Scheduling, Spring Boot Docs</p></blockquote><h3 class="anchor anchorWithStickyNavbar_LWe7" id="async-적용">@Async 적용<a href="#async-적용" class="hash-link" aria-label="@Async 적용에 대한 직접 링크" title="@Async 적용에 대한 직접 링크">​</a></h3><p>이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">RouteImageGenerator</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Async</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">generate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> latitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> longitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> pointedLatitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> pointedLongitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">Long</span><span class="token plain"> tripId</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 이미지 생성</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">RouteImageDrawer</span><span class="token plain"> routeImageDrawer </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">RouteImageDrawer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">from</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">IMAGE_SIZE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">Coordinates</span><span class="token plain"> coordinates </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">Coordinates</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">of</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">latitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> longitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">Coordinates</span><span class="token plain"> pointedCoordinates </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">Coordinates</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">of</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">pointedLatitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> pointedLongitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">drawImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">coordinates</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> routeImageDrawer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> pointedCoordinates</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 이미지 저장</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> imageName </span><span class="token operator">=</span><span class="token plain"> routeImageUploader</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">upload</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">routeImageDrawer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">bufferedImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 자원 할당 해제</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> routeImageDrawer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">dispose</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 데이터베이스 값 변경</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">Trip</span><span class="token plain"> trip </span><span class="token operator">=</span><span class="token plain"> tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">findById</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tripId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">orElseThrow</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">changeRouteImageUrl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">imageUrl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">save</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="비동기-처리시-문제점">비동기 처리시 문제점<a href="#비동기-처리시-문제점" class="hash-link" aria-label="비동기 처리시 문제점에 대한 직접 링크" title="비동기 처리시 문제점에 대한 직접 링크">​</a></h3><p>현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.<br> -<!-- -->따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다. </p><p>이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.<br> -<!-- -->인터페이스를 사용한다면 다음과 같은 구조가 된다. </p><p>패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.<br> -<!-- -->따라서 이벤트를 사용하기로 했다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="이벤트-사용">이벤트 사용<a href="#이벤트-사용" class="hash-link" aria-label="이벤트 사용에 대한 직접 링크" title="이벤트 사용에 대한 직접 링크">​</a></h2><p>스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="이벤트-발행">이벤트 발행<a href="#이벤트-발행" class="hash-link" aria-label="이벤트 발행에 대한 직접 링크" title="이벤트 발행에 대한 직접 링크">​</a></h3><p>이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.<br> +<!-- -->따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.</p> +<h2 id="비동기-처리">비동기 처리</h2> +<p>@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.</p> +<h3 id="비동기-설정">비동기 설정</h3> +<p>사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.<br> +<!-- -->해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.</p> +<pre><code class="language-java" metastring="title="AsyncConfig"">@EnableAsync +@Configuration +public class AsyncConfig { +} +</code></pre> +<p>스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.</p> +<blockquote> +<p>In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. +7.7. Task Execution and Scheduling, Spring Boot Docs</p> +</blockquote> +<h3 id="async-적용">@Async 적용</h3> +<p>이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.</p> +<pre><code class="language-java" metastring="title="RouteImageGenerator"">@Async +public void generate( + List<Double> latitudes, + List<Double> longitudes, + List<Double> pointedLatitudes, + List<Double> pointedLongitudes, + Long tripId +) { + // 이미지 생성 + RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE); + Coordinates coordinates = Coordinates.of(latitudes, longitudes); + Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes); + drawImage(coordinates, routeImageDrawer, pointedCoordinates); + + // 이미지 저장 + String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage()); + + // 자원 할당 해제 + routeImageDrawer.dispose(); + + // 데이터베이스 값 변경 + Trip trip = tripRepository.findById(tripId) + .orElseThrow(); + trip.changeRouteImageUrl(imageUrl); + tripRepository.save(trip); +} +</code></pre> +<h3 id="비동기-처리시-문제점">비동기 처리시 문제점</h3> +<p>현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.<br> +<!-- -->따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.</p> +<mermaid value="graph LR + trip[trip: 여행 관련 패키지] --> draw[draw: 이미지 생성 기능을 포함하고 있는 패키지] + draw --> trip"></mermaid> +<p>이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.<br> +<!-- -->인터페이스를 사용한다면 다음과 같은 구조가 된다.</p> +<mermaid value="graph LR + subgraph draw + direction LR + RG[RouteImageGenerator] -- DB 반영 요청 --> ILR[ImageLinkTripRepository] + end + subgraph trip + direction LR + TS[TripService] -- 이미지 생성 --> RG + ILRI[ImageLinkTripRepositoryImpl] -- 구현 --> ILR + end + + trip --> draw"></mermaid> +<p>패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.<br> +<!-- -->따라서 이벤트를 사용하기로 했다.</p> +<h2 id="이벤트-사용">이벤트 사용</h2> +<p>스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.</p> +<h3 id="이벤트-발행">이벤트 발행</h3> +<p>이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.<br> <!-- -->스프링에서는 ApplicationEventPublisher 인터페이스를 사용하여 이벤트를 발행할 수 있다.<br> -<!-- -->해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">TripService & TripUpdateEvent</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">updateTripById</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">LoginUser</span><span class="token plain"> loginUser</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Long</span><span class="token plain"> tripId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">TripUpdateRequest</span><span class="token plain"> tripUpdateRequest</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 이벤트 발행</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> applicationEventPublisher</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">publishEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">TripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">id</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">record</span><span class="token plain"> </span><span class="token class-name">TripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Long</span><span class="token plain"> tripId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>이벤트를 발행할 때 발행하는 이벤트명이 중요하다.<br> +<!-- -->해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.</p> +<pre><code class="language-java" metastring="title="TripService & TripUpdateEvent"">public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) { + ... + + // 이벤트 발행 + applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id())); +} + +public record TripUpdateEvent(Long tripId) { +} +</code></pre> +<p>이벤트를 발행할 때 발행하는 이벤트명이 중요하다.<br> <!-- -->이벤트를 구독하는 도메인의 행위를 담고 있는 이벤트를 발행(ex. RouteImageGenerateEvent)한다면 논리적인 의존 관계가 남아있기에 이벤트를 적절히 사용했다고 보기 어렵다.<br> -<!-- -->발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="이벤트-구독">이벤트 구독<a href="#이벤트-구독" class="hash-link" aria-label="이벤트 구독에 대한 직접 링크" title="이벤트 구독에 대한 직접 링크">​</a></h3><p>이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 <code>@Async</code> 애너테이션을 적용했다.<br> -<!-- -->이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 <code>@TransactionalEventListener</code>를 사용했다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>TransactionPhase 설정</div><div class="admonitionContent_S0QG"><p>TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.</p><p>AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행<br> +<!-- -->발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.</p> +<h3 id="이벤트-구독">이벤트 구독</h3> +<p>이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 <code>@Async</code> 애너테이션을 적용했다.<br> +<!-- -->이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 <code>@TransactionalEventListener</code>를 사용했다.</p> +<admonition title="TransactionPhase 설정" type="note"><p>TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.</p><p>AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행<br> <!-- -->AFTER_ROLLBACK: 트랜잭션이 롤백되는 경우 이벤트 실행<br> <!-- -->AFTER_COMPLETION: 트랜잭션이 커밋 또는 롤백 되었을 경우 이벤트 실행<br> -<!-- -->BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행 </p></div></div><p>이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">TripUpdateEventHandler</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">TripUpdateEventHandler</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">RouteImageGenerator</span><span class="token plain"> routeImageGenerator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">TripRepository</span><span class="token plain"> tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">TripUpdateEventHandler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">RouteImageGenerator</span><span class="token plain"> routeImageGenerator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">TripRepository</span><span class="token plain"> tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">routeImageGenerator </span><span class="token operator">=</span><span class="token plain"> routeImageGenerator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">tripRepository </span><span class="token operator">=</span><span class="token plain"> tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Async</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@TransactionalEventListener</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">phase </span><span class="token operator">=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">AFTER_COMMIT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">handle</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">TripUpdateEvent</span><span class="token plain"> tripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">Trip</span><span class="token plain"> trip </span><span class="token operator">=</span><span class="token plain"> tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getTripWithPoints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">tripId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> imageUrl </span><span class="token operator">=</span><span class="token plain"> routeImageGenerator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">generate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLatitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getLongitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getPointedLatitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getPointedLongitudes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">changeRouteImageUrl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">imageUrl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">save</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">trip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.<br> -<!-- -->또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="테스트">테스트<a href="#테스트" class="hash-link" aria-label="테스트에 대한 직접 링크" title="테스트에 대한 직접 링크">​</a></h3><p>비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다. </p><div class="tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">비동기 메서드가 종료될 때까지 대기 후 검증</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">테스트 할 때만 비동기를 동기로 변경하여 검증</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@SpringBootTest</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">TripUpdateEventHandlerIntegrationTest</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Test</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// given</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">TripUpdateEvent</span><span class="token plain"> tripUpdateEvent </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">TripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">1L</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">given</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getTripWithPoints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">tripId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">willReturn</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">여행</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// when</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> transactionTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">executeWithoutResult</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">action </span><span class="token operator">-></span><span class="token plain"> applicationEventPublisher</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">publishEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// then</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">then</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">routeImageGenerator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">should</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Mockito</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">timeout</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">5000</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">times</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">generate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><div role="tabpanel" class="tabItem_Ymn6"><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@ContextConfiguration</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">classes </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">TestSyncConfig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@SpringBootTest</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token plain"> </span><span class="token class-name">TripUpdateEventHandlerIntegrationTest</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Test</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// given</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">TripUpdateEvent</span><span class="token plain"> tripUpdateEvent </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">TripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">1L</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">given</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tripRepository</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">getTripWithPoints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">tripId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">willReturn</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">여행</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// when</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> transactionTemplate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">executeWithoutResult</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">action </span><span class="token operator">-></span><span class="token plain"> applicationEventPublisher</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">publishEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">tripUpdateEvent</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// then</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">then</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">routeImageGenerator</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">should</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">times</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">generate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></div><p>처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.<br> -<!-- -->통합 테스트에선 <code>트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지</code> 검증이 필요했기 때문에 최종적으로 <code>Mockito.timeout</code> 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="결과">결과<a href="#결과" class="hash-link" aria-label="결과에 대한 직접 링크" title="결과에 대한 직접 링크">​</a></h2><p><img loading="lazy" alt="./time.png" src="/assets/images/time-8bef9a6cf2dcace85f12ae5624da94f5.png" width="1682" height="678" class="img_ev3q"></p><p>위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.<br> -<!-- -->응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h2><p><a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.task-execution-and-scheduling" target="_blank" rel="noopener noreferrer">7.7. Task Execution and Scheduling, Spring Boot Docs</a><br> -<a href="https://www.baeldung.com/spring-events" target="_blank" rel="noopener noreferrer">Spring Events, Baeldung</a><br> -<a href="https://techblog.woowahan.com/7835/" target="_blank" rel="noopener noreferrer">회원시스템 이벤트기반 아키텍처 구축하기</a></p>]]></content> +<!-- -->BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행</p></admonition> +<p>이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.</p> +<pre><code class="language-java" metastring="title="TripUpdateEventHandler"">@Component +public class TripUpdateEventHandler { + + private final RouteImageGenerator routeImageGenerator; + private final TripRepository tripRepository; + + public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) { + this.routeImageGenerator = routeImageGenerator; + this.tripRepository = tripRepository; + } + + @Async + @TransactionalEventListener(phase = AFTER_COMMIT) + public void handle(TripUpdateEvent tripUpdateEvent) { + Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId()); + + String imageUrl = routeImageGenerator.generate( + trip.getLatitudes(), + trip.getLongitudes(), + trip.getPointedLatitudes(), + trip.getPointedLongitudes() + ); + + trip.changeRouteImageUrl(imageUrl); + tripRepository.save(trip); + } +} +</code></pre> +<p>이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.<br> +<!-- -->또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.</p> +<mermaid value="graph LR + subgraph trip + TripServcie -- 발행 --> TripUpdateEvent + TripRepository + end + + subgraph draw + TripUpdateEventHandler -- 구독 후 이미지 생성 --> TripUpdateEvent + TripUpdateEventHandler -- 생성된 이미지 경로 저장 --> TripRepository + end"></mermaid> +<h3 id="테스트">테스트</h3> +<p>비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.</p> +<!-- --> +<!-- --> +<div class="tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">비동기 메서드가 종료될 때까지 대기 후 검증</li><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">테스트 할 때만 비동기를 동기로 변경하여 검증</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6" hidden=""><pre><code class="language-java">@SpringBootTest +public class TripUpdateEventHandlerIntegrationTest { + + ... + + @Test + void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() { + // given + TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L); + given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId())) + .willReturn(여행()); + + // when + transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent)); + + // then + then(routeImageGenerator) + .should(Mockito.timeout(5000).times(1)) + .generate(any(), any(), any(), any()); + } +} +</code></pre></div><div role="tabpanel" class="tabItem_Ymn6"><pre><code class="language-java">@ContextConfiguration(classes = TestSyncConfig.class) +@SpringBootTest +public class TripUpdateEventHandlerIntegrationTest { + + ... + + @Test + void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() { + // given + TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L); + given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId())) + .willReturn(여행()); + + // when + transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent)); + + // then + then(routeImageGenerator) + .should(times(1)) + .generate(any(), any(), any(), any()); + } +} +</code></pre></div></div></div> +<p>처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.<br> +<!-- -->통합 테스트에선 <code>트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지</code> 검증이 필요했기 때문에 최종적으로 <code>Mockito.timeout</code> 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.</p> +<h2 id="결과">결과</h2> +<p><img alt="./time.png" src="https://greeng00se.github.io/assets/images/time-8bef9a6cf2dcace85f12ae5624da94f5.png" width="1682" height="678"></p> +<p>위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.<br> +<!-- -->응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.</p> +<h2 id="참고-자료">참고 자료</h2> +<p><a href="https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.task-execution-and-scheduling">7.7. Task Execution and Scheduling, Spring Boot Docs</a><br> +<a href="https://www.baeldung.com/spring-events">Spring Events, Baeldung</a><br> +<a href="https://techblog.woowahan.com/7835/">회원시스템 이벤트기반 아키텍처 구축하기</a></p>]]></content> <category label="async" term="async"/> <category label="event" term="event"/> </entry> @@ -366,17 +1563,198 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/route-image-implementation"/> <updated>2023-08-02T00:00:00.000Z</updated> <summary type="html"><![CDATA[개요]]></summary> - <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="개요">개요<a href="#개요" class="hash-link" aria-label="개요에 대한 직접 링크" title="개요에 대한 직접 링크">​</a></h2><p>여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.<br> -<!-- -->경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 <a href="/route-image-intro">링크</a>에 있다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="구현-결과">구현 결과<a href="#구현-결과" class="hash-link" aria-label="구현 결과에 대한 직접 링크" title="구현 결과에 대한 직접 링크">​</a></h3><p><img loading="lazy" alt="./result.png" src="/assets/images/result-c2887223d62510a96c9c8f733bf5edf6.png" width="1840" height="714" class="img_ev3q"></p><p>예시 데이터는 다음과 같다.<br> -<strong>서울역(점)</strong> → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → <strong>구로역(점)</strong> → 신림역 → 발산역</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">예시 데이터</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> x </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">of</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token number">126.97094933811682</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">127.02154822802501</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">126.94218991864345</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">126.92402556641424</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token number">126.99265358592287</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">127.01779856076462</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">126.88474839801178</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">126.92900751277035</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">126.83930056313639</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> y </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">of</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token number">37.55302829553499</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.51619698970427</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.51294119442773</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.5565933969331</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token number">37.57034879708931</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.54027238225762</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.50129417536773</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.48258811529137</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.557607696911184</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> xPoints </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">of</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">126.97094933811682</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">126.88474839801178</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> yPoints </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">of</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">37.55302829553499</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.50129417536773</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="image_size--route_size">IMAGE_SIZE & ROUTE_SIZE<a href="#image_size--route_size" class="hash-link" aria-label="IMAGE_SIZE & ROUTE_SIZE에 대한 직접 링크" title="IMAGE_SIZE & ROUTE_SIZE에 대한 직접 링크">​</a></h3><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">RouteImageGenerator.java</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">IMAGE_SIZE</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">800</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ROUTE_SIZE</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">600</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.<br> + <content type="html"><![CDATA[<h2 id="개요">개요</h2> +<p>여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.<br> +<!-- -->경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 <a href="https://greeng00se.github.io/route-image-intro">링크</a>에 있다.</p> +<h3 id="구현-결과">구현 결과</h3> +<p><img alt="./result.png" src="https://greeng00se.github.io/assets/images/result-c2887223d62510a96c9c8f733bf5edf6.png" width="1840" height="714"></p> +<p>예시 데이터는 다음과 같다.<br> +<strong>서울역(점)</strong> → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → <strong>구로역(점)</strong> → 신림역 → 발산역</p> +<pre><code class="language-java" metastring="title="예시 데이터"">List<Double> x = List.of( + 126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424, + 126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639 +); +List<Double> y = List.of( + 37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331, + 37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184 +); +List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178); +List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773); +</code></pre> +<h3 id="image_size--route_size">IMAGE_SIZE & ROUTE_SIZE</h3> +<pre><code class="language-java" metastring="title="RouteImageGenerator.java"">private static final int IMAGE_SIZE = 800; +private static final int ROUTE_SIZE = 600; +</code></pre> +<p>코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.<br> <!-- -->IMAGE_SIZE는 말 그대로 이미지의 width와 height를 의미한다.<br> <!-- -->ROUTE_SIZE의 경우 상하좌우 100px 만큼의 간격을 위해 존재한다.<br> -<!-- -->따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다. </p><p><img loading="lazy" alt="./600.png" src="/assets/images/600-50ee65176288cb73d2c777d255460f4f.png" width="976" height="970" class="img_ev3q"></p><p><strong>사이즈 변경의 이유</strong></p><p>255 <em> 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 </em> 800 사이즈로 변경했다.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="주요-클래스">주요 클래스<a href="#주요-클래스" class="hash-link" aria-label="주요 클래스에 대한 직접 링크" title="주요 클래스에 대한 직접 링크">​</a></h2><h3 class="anchor anchorWithStickyNavbar_LWe7" id="요약">요약<a href="#요약" class="hash-link" aria-label="요약에 대한 직접 링크" title="요약에 대한 직접 링크">​</a></h3><table><thead><tr><th>클래스명</th><th>설명</th><th>특이사항</th></tr></thead><tbody><tr><td>Coordinate</td><td>위도, 경도로 이루어진 위치 값</td><td>좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용</td></tr><tr><td>Coordinates</td><td>Coordinate의 일급 컬렉션</td><td>-</td></tr><tr><td>Position</td><td>실제 이미지 생성에 사용할 위치 값</td><td>Integer 타입의 x, y 사용</td></tr><tr><td>Positions</td><td>Positions의 일급 컬렉션</td><td>-</td></tr><tr><td>RouteImageDrawer</td><td>실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음</td><td>이미지 생성에 필요한 상수가 정의되어 있음</td></tr><tr><td>RouteImageUploader</td><td>BufferedImage를 받아 서버에 업로드 하는 클래스</td><td>현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성</td></tr><tr><td>RouteImageGenerator</td><td>이미지를 생성하고 업로드하는 서비스</td><td>여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청</td></tr><tr><td>BufferedImage(AWT)</td><td>이미지 데이터를 처리하고 조작하는 데 사용</td><td>왼쪽 상단의 좌표가 (0, 0)</td></tr><tr><td>Graphics2D(AWT)</td><td>선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림</td><td>JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성</td></tr></tbody></table><h3 class="anchor anchorWithStickyNavbar_LWe7" id="의존관계">의존관계<a href="#의존관계" class="hash-link" aria-label="의존관계에 대한 직접 링크" title="의존관계에 대한 직접 링크">​</a></h3><h3 class="anchor anchorWithStickyNavbar_LWe7" id="coordinates위도-경도의-일급-컬렉션">Coordinates(위도, 경도의 일급 컬렉션)<a href="#coordinates위도-경도의-일급-컬렉션" class="hash-link" aria-label="Coordinates(위도, 경도의 일급 컬렉션)에 대한 직접 링크" title="Coordinates(위도, 경도의 일급 컬렉션)에 대한 직접 링크">​</a></h3><p><code>List<Double></code> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.<br> -<!-- -->Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.</p><ul><li>calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환</li><li>indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는 </li></ul><p>Positions 계산 로직은 다음과 같다.<br> -<!-- -->위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">Coordinates.java</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// 호출</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Integer</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">toPositions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Double</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Double</span><span class="token plain"> maxDifference</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Integer</span><span class="token plain"> routeImageSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">Double</span><span class="token plain"> minValue </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">Collections</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">value </span><span class="token operator">-></span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">normalizeCoordinate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> maxDifference</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> minValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">value </span><span class="token operator">-></span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">mapToPosition</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> routeImageSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toList</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">double</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">normalizeCoordinate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Double</span><span class="token plain"> coordinate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Double</span><span class="token plain"> maxDifference</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Double</span><span class="token plain"> minValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">coordinate </span><span class="token operator">-</span><span class="token plain"> minValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">/</span><span class="token plain"> maxDifference</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">mapToPosition</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Double</span><span class="token plain"> coordinate</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Integer</span><span class="token plain"> routeImageSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">coordinate </span><span class="token operator">*</span><span class="token plain"> routeImageSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>위도로 예시든 내용이다.</p><ol><li>Collections.min(values) → 위도 리스트의 최소값을 구한다.</li><li>normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 <strong>위경도의 최대 차이</strong>로 나눈다.</li><li>mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.</li></ol><h3 class="anchor anchorWithStickyNavbar_LWe7" id="positions실제-이미지-생성에-사용할-위치">Positions(실제 이미지 생성에 사용할 위치)<a href="#positions실제-이미지-생성에-사용할-위치" class="hash-link" aria-label="Positions(실제 이미지 생성에 사용할 위치)에 대한 직접 링크" title="Positions(실제 이미지 생성에 사용할 위치)에 대한 직접 링크">​</a></h3><p>Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.</p><ul><li>align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.</li><li>getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.</li><li>size: 크기를 반환한다.</li><li>xPositions: x 값들을 반환한다.</li><li>yPositions: y 값들을 반환한다.</li></ul><p>중앙 정렬 로직은 다음과 같다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">Positions.java</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token class-name">Positions</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">align</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> imageSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> routeSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> xOffset </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">calculateOffset</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Position</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> imageSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> yOffset </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">calculateOffset</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Position</span><span class="token operator">::</span><span class="token function" style="color:rgb(80, 250, 123)">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> imageSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> items</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">item </span><span class="token operator">-></span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">Position</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">item</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> xOffset</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> imageSize </span><span class="token operator">-</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">item</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> yOffset</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">collect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">collectingAndThen</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">toList</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">Positions</span><span class="token operator">::</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">calculateOffset</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">ToIntFunction</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Position</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> positionToInteger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> imageSize</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Integer</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> positions </span><span class="token operator">=</span><span class="token plain"> items</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">mapToInt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">positionToInteger</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">boxed</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">toList</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> midValue </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">Collections</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">positions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">+</span><span class="token plain"> </span><span class="token class-name">Collections</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">max</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">positions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">/</span><span class="token plain"> </span><span class="token number">2</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> imageSize </span><span class="token operator">/</span><span class="token plain"> </span><span class="token number">2</span><span class="token plain"> </span><span class="token operator">-</span><span class="token plain"> midValue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.<br> -<!-- -->BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다. </p><p><img loading="lazy" alt="./800.png" src="/assets/images/800-88542ba3914ad40b45b999e95df96cdf.png" width="968" height="978" class="img_ev3q"></p><p>따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.</p><p>x 값 → 계산한 offset 그대로 더한다.<br> -<!-- -->y 값 → imageSize(800)에서 y + offset 값을 뺀다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="routeimagedrawer실제-이미지에-경로를-그려주는-클래스">RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)<a href="#routeimagedrawer실제-이미지에-경로를-그려주는-클래스" class="hash-link" aria-label="RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)에 대한 직접 링크" title="RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)에 대한 직접 링크">​</a></h3><p>BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.<br> -<!-- -->그림을 그리기 위해 설정한 상수들이 존재한다.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">RouteImageDrawer.java</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 이를 RGBA라고 부른다.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">IMAGE_TYPE</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">BufferedImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">TYPE_INT_ARGB</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 배경 투명색</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Color</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">TRANSPARENT</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">Color</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 경로를 위한 STROKE</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">LINE_STROKE_WIDTH</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">7</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Stroke</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">LINE_STROKE</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">BasicStroke</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">LINE_STROKE_WIDTH</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">CAP_ROUND</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">JOIN_ROUND</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 위치 점을 위한 STROKE</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">POINT_STROKE_WIDTH</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">20</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Stroke</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">POINT_STROKE</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">BasicStroke</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">POINT_STROKE_WIDTH</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">CAP_ROUND</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">JOIN_ROUND</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 안티앨리어싱 등 화질 개선을 위한 설정</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">private</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">final</span><span class="token plain"> </span><span class="token class-name">Map</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Object</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token generics"> </span><span class="token generics class-name">Object</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> renderingHints </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">Map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">of</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">RenderingHints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">KEY_ANTIALIASING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">RenderingHints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">VALUE_ANTIALIAS_ON</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">RenderingHints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">KEY_RENDERING</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">RenderingHints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">VALUE_RENDER_QUALITY</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">RenderingHints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">KEY_INTERPOLATION</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">RenderingHints</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">VALUE_INTERPOLATION_BICUBIC</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.</p><ul><li>drawLine: 선을 그린다.</li><li>drawPoint: 점을 찍는다.</li><li>dispose: 자원 할당을 해제한다. </li></ul><p>dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="이미지-생성-flow">이미지 생성 Flow<a href="#이미지-생성-flow" class="hash-link" aria-label="이미지 생성 Flow에 대한 직접 링크" title="이미지 생성 Flow에 대한 직접 링크">​</a></h2><h3 class="anchor anchorWithStickyNavbar_LWe7" id="1-이미지-생성-준비">1. 이미지 생성 준비<a href="#1-이미지-생성-준비" class="hash-link" aria-label="1. 이미지 생성 준비에 대한 직접 링크" title="1. 이미지 생성 준비에 대한 직접 링크">​</a></h3><h3 class="anchor anchorWithStickyNavbar_LWe7" id="2-선-그리기-요청">2. 선 그리기 요청<a href="#2-선-그리기-요청" class="hash-link" aria-label="2. 선 그리기 요청에 대한 직접 링크" title="2. 선 그리기 요청에 대한 직접 링크">​</a></h3><h3 class="anchor anchorWithStickyNavbar_LWe7" id="3-위치-점-그리기-요청">3. 위치 점 그리기 요청<a href="#3-위치-점-그리기-요청" class="hash-link" aria-label="3. 위치 점 그리기 요청에 대한 직접 링크" title="3. 위치 점 그리기 요청에 대한 직접 링크">​</a></h3><h3 class="anchor anchorWithStickyNavbar_LWe7" id="4-업로드-요청">4. 업로드 요청<a href="#4-업로드-요청" class="hash-link" aria-label="4. 업로드 요청에 대한 직접 링크" title="4. 업로드 요청에 대한 직접 링크">​</a></h3><h3 class="anchor anchorWithStickyNavbar_LWe7" id="전체-flow">전체 Flow<a href="#전체-flow" class="hash-link" aria-label="전체 Flow에 대한 직접 링크" title="전체 Flow에 대한 직접 링크">​</a></h3>]]></content> +<!-- -->따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.</p> +<p><img alt="./600.png" src="https://greeng00se.github.io/assets/images/600-50ee65176288cb73d2c777d255460f4f.png" width="976" height="970"></p> +<p><strong>사이즈 변경의 이유</strong></p> +<p>255 * 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 * 800 사이즈로 변경했다.</p> +<h2 id="주요-클래스">주요 클래스</h2> +<h3 id="요약">요약</h3> +<table><thead><tr><th>클래스명</th><th>설명</th><th>특이사항</th></tr></thead><tbody><tr><td>Coordinate</td><td>위도, 경도로 이루어진 위치 값</td><td>좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용</td></tr><tr><td>Coordinates</td><td>Coordinate의 일급 컬렉션</td><td>-</td></tr><tr><td>Position</td><td>실제 이미지 생성에 사용할 위치 값</td><td>Integer 타입의 x, y 사용</td></tr><tr><td>Positions</td><td>Positions의 일급 컬렉션</td><td>-</td></tr><tr><td>RouteImageDrawer</td><td>실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음</td><td>이미지 생성에 필요한 상수가 정의되어 있음</td></tr><tr><td>RouteImageUploader</td><td>BufferedImage를 받아 서버에 업로드 하는 클래스</td><td>현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성</td></tr><tr><td>RouteImageGenerator</td><td>이미지를 생성하고 업로드하는 서비스</td><td>여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청</td></tr><tr><td>BufferedImage(AWT)</td><td>이미지 데이터를 처리하고 조작하는 데 사용</td><td>왼쪽 상단의 좌표가 (0, 0)</td></tr><tr><td>Graphics2D(AWT)</td><td>선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림</td><td>JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성</td></tr></tbody></table> +<h3 id="의존관계">의존관계</h3> +<mermaid value="graph TD + C1[Coordinates] --> C[Coordinate] + P1[Positions] --> P[Position] + + RID[RouteImageDrawer] -- "중앙 정렬된 Positions를 받아 이미지 생성" --> P1 + RID --> B[BufferedImage] + RID --> G[Graphics2D] + + C1 -- "calculatePositions 실제 이미지에 생성에 필요한 위치 계산" --> P1 + + RIU[RouteImageUploader] --> B + RIG[RouteImageGenerator] --> RID + RIG --> RIU + RIG --> C1 + RIG --> P1"></mermaid> +<h3 id="coordinates위도-경도의-일급-컬렉션">Coordinates(위도, 경도의 일급 컬렉션)</h3> +<p><code>List<Double></code> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.<br> +<!-- -->Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.</p> +<ul> +<li>calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환</li> +<li>indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는</li> +</ul> +<p>Positions 계산 로직은 다음과 같다.<br> +<!-- -->위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.</p> +<pre><code class="language-java" metastring="title="Coordinates.java"">// 호출 +// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize); +// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize); + +private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) { + Double minValue = Collections.min(values); + return values.stream() + .map(value -> normalizeCoordinate(value, maxDifference, minValue)) + .map(value -> mapToPosition(value, routeImageSize)) + .toList(); +} + +private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) { + return (coordinate - minValue) / maxDifference; +} + +private int mapToPosition(Double coordinate, Integer routeImageSize) { + return (int) (coordinate * routeImageSize); +} +</code></pre> +<p>위도로 예시든 내용이다.</p> +<ol> +<li>Collections.min(values) → 위도 리스트의 최소값을 구한다.</li> +<li>normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 <strong>위경도의 최대 차이</strong>로 나눈다.</li> +<li>mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.</li> +</ol> +<h3 id="positions실제-이미지-생성에-사용할-위치">Positions(실제 이미지 생성에 사용할 위치)</h3> +<p>Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.</p> +<ul> +<li>align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.</li> +<li>getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.</li> +<li>size: 크기를 반환한다.</li> +<li>xPositions: x 값들을 반환한다.</li> +<li>yPositions: y 값들을 반환한다.</li> +</ul> +<p>중앙 정렬 로직은 다음과 같다.</p> +<pre><code class="language-java" metastring="title="Positions.java"">public Positions align(int imageSize, int routeSize) { + int xOffset = calculateOffset(Position::x, imageSize); + int yOffset = calculateOffset(Position::y, imageSize); + + return items.stream() + .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset))) + .collect(collectingAndThen(toList(), Positions::new)); +} + +private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) { + List<Integer> positions = items.stream() + .mapToInt(positionToInteger) + .boxed() + .toList(); + + int midValue = (Collections.min(positions) + Collections.max(positions)) / 2; + return imageSize / 2 - midValue; +} +</code></pre> +<p>상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.<br> +<!-- -->BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.</p> +<p><img alt="./800.png" src="https://greeng00se.github.io/assets/images/800-88542ba3914ad40b45b999e95df96cdf.png" width="968" height="978"></p> +<p>따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.</p> +<p>x 값 → 계산한 offset 그대로 더한다.<br> +<!-- -->y 값 → imageSize(800)에서 y + offset 값을 뺀다.</p> +<h3 id="routeimagedrawer실제-이미지에-경로를-그려주는-클래스">RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)</h3> +<p>BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.<br> +<!-- -->그림을 그리기 위해 설정한 상수들이 존재한다.</p> +<pre><code class="language-java" metastring="title="RouteImageDrawer.java"">// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다. +// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다. +// 이를 RGBA라고 부른다. +private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB; +// 배경 투명색 +private static final Color TRANSPARENT = new Color(0, 0, 0, 0); +// 경로를 위한 STROKE +private static final int LINE_STROKE_WIDTH = 7; +private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND); +// 위치 점을 위한 STROKE +private static final int POINT_STROKE_WIDTH = 20; +private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND); +// 안티앨리어싱 등 화질 개선을 위한 설정 +private static final Map<Object, Object> renderingHints = Map.of( + RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON, + RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY, + RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC +); +</code></pre> +<p>RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.</p> +<ul> +<li>drawLine: 선을 그린다.</li> +<li>drawPoint: 점을 찍는다.</li> +<li>dispose: 자원 할당을 해제한다.</li> +</ul> +<p>dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.</p> +<h2 id="이미지-생성-flow">이미지 생성 Flow</h2> +<h3 id="1-이미지-생성-준비">1. 이미지 생성 준비</h3> +<mermaid value="sequenceDiagram + 외부 클래스 ->> RouteImageGenerator: 이미지 생성 요청(위경도, 위치 점을 찍을 값 전달) + RouteImageGenerator->>RouteImageDrawer: ImageSize를 전달하여 객체 생성, 내부에서 BufferedImage, Graphincs2D 생성 + RouteImageGenerator->>Coordinates1(위경도): 위경도 이용하여 Coordinates1 생성 + RouteImageGenerator->>Coordinates2(위치점): 위치점 이용하여 Coordinates2 생성 +"></mermaid> +<h3 id="2-선-그리기-요청">2. 선 그리기 요청</h3> +<mermaid value="sequenceDiagram + RouteImageGenerator->>Coordinates1(위경도): 정렬된 Positions를 생성 요청 + Coordinates1(위경도)->>RouteImageGenerator: 정렬된 Positions 반환 + RouteImageGenerator->>RouteImageDrawer: 정렬된 Positions를 경로 그리기 요청"></mermaid> +<h3 id="3-위치-점-그리기-요청">3. 위치 점 그리기 요청</h3> +<mermaid value="sequenceDiagram + RouteImageGenerator->>Coordinates1(위경도): Coordinate2(위치점)를 전달하고 해당 위치점과 일치하는 Coordinate의 인덱스 생성 요청 + Coordinates1(위경도)->>RouteImageGenerator: 위치점에 해당하는 인덱스(List<Integer>) 반환 + RouteImageGenerator->>정렬된 Positions: 인덱스(List<Integer>)를 전달하여 인덱스에 해당하는 Positions 생성 요청 + 정렬된 Positions->>RouteImageGenerator: 위치점에 해당하는 Positions 반환(pointPositions) + + RouteImageGenerator->>RouteImageDrawer: pointPositions를 전달하여 위치 점 그리기 요청"></mermaid> +<h3 id="4-업로드-요청">4. 업로드 요청</h3> +<mermaid value="sequenceDiagram + RouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer에서 getter 사용)를 전달하여 이미지 저장 요청 + RouteImageUploader->>RouteImageGenerator: 저장 후 저장된 이미지명(또는 url) 반환 + RouteImageGenerator->>외부 클래스: 저장된 이미지명(또는 url) 반환"></mermaid> +<h3 id="전체-flow">전체 Flow</h3> +<mermaid value="sequenceDiagram + 외부 클래스 ->> RouteImageGenerator: 이미지 생성 요청(위경도, 위치 점을 찍을 값 전달) + RouteImageGenerator->>RouteImageDrawer: ImageSize를 전달하여 객체 생성, 내부에서 BufferedImage, Graphincs2D 생성 + RouteImageGenerator->>Coordinates1(위경도): 위경도 이용하여 Coordinates1 생성 + RouteImageGenerator->>Coordinates2(위치점): 위치점 이용하여 Coordinates2 생성 + RouteImageGenerator->>Coordinates1(위경도): 정렬된 Positions를 생성 요청 + Coordinates1(위경도)->>RouteImageGenerator: 정렬된 Positions 반환 + RouteImageGenerator->>RouteImageDrawer: 정렬된 Positions를 경로 그리기 요청 + RouteImageGenerator->>Coordinates1(위경도): Coordinate2(위치점)를 전달하고 해당 위치점과 일치하는 Coordinate의 인덱스 생성 요청 + Coordinates1(위경도)->>RouteImageGenerator: 위치점에 해당하는 인덱스(List<Integer>) 반환 + RouteImageGenerator->>정렬된 Positions: 인덱스(List<Integer>)를 전달하여 인덱스에 해당하는 Positions 생성 요청 + 정렬된 Positions->>RouteImageGenerator: 위치점에 해당하는 Positions 반환(pointPositions) + + RouteImageGenerator->>RouteImageDrawer: pointPositions를 전달하여 위치 점 그리기 요청 + RouteImageGenerator->>RouteImageUploader: bufferedImage(RouteImageDrawer에서 getter 사용)를 전달하여 이미지 저장 요청 + RouteImageUploader->>RouteImageGenerator: 저장 후 저장된 이미지명(또는 url) 반환 + RouteImageGenerator->>외부 클래스: 저장된 이미지명(또는 url) 반환 + "></mermaid>]]></content> <category label="image" term="image"/> <category label="awt" term="awt"/> </entry> @@ -386,27 +1764,178 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/route-image-python"/> <updated>2023-07-31T00:00:00.000Z</updated> <summary type="html"><![CDATA[개요]]></summary> - <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="개요">개요<a href="#개요" class="hash-link" aria-label="개요에 대한 직접 링크" title="개요에 대한 직접 링크">​</a></h3><p>이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="사용-기술">사용 기술<a href="#사용-기술" class="hash-link" aria-label="사용 기술에 대한 직접 링크" title="사용 기술에 대한 직접 링크">​</a></h3><p>언어: Python 3.10<br> + <content type="html"><![CDATA[<h3 id="개요">개요</h3> +<p>이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.</p> +<h3 id="사용-기술">사용 기술</h3> +<p>언어: Python 3.10<br> <!-- -->이미지 생성: matplotlib<br> <!-- -->서비스: AWS Lambda, AWS API Gateway<br> -<!-- -->이미지 저장 및 URL: AWS S3, AWS CloudFront </p><p>플로우는 다음과 같다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="요구사항">요구사항<a href="#요구사항" class="hash-link" aria-label="요구사항에 대한 직접 링크" title="요구사항에 대한 직접 링크">​</a></h3><p><img loading="lazy" alt="./route.png" src="/assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png" width="1014" height="902" class="img_ev3q"></p><p>우측 상단의 경로 이미지를 생성하려고 한다.<br> -<!-- -->경로 이미지 생성에 대한 요구사항은 다음과 같다.</p><ul><li>위도, 경도로 이루어진 배열을 입력받는다. </li><li>이미지 생성</li><li>선과 점 표현</li><li>투명한 배경색</li><li>위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다. </li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="이미지-출력-방식">이미지 출력 방식<a href="#이미지-출력-방식" class="hash-link" aria-label="이미지 출력 방식에 대한 직접 링크" title="이미지 출력 방식에 대한 직접 링크">​</a></h3><ol><li>위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장</li><li>플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장</li></ol><p>이미지 출력 방식의 경우 1번과 2번을 고민했었다.<br> -<!-- -->파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="로컬에서-기능-구현">로컬에서 기능 구현<a href="#로컬에서-기능-구현" class="hash-link" aria-label="로컬에서 기능 구현에 대한 직접 링크" title="로컬에서 기능 구현에 대한 직접 링크">​</a></h3><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> time</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> matplotlib</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">pyplot </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> plt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">draw</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">point</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> start </span><span class="token operator">=</span><span class="token plain"> time</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">time</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">zip</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">*</span><span class="token plain">point</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> pixel_x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> pixel_y </span><span class="token operator">=</span><span class="token plain"> convert_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> draw_lines</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">pixel_x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> pixel_y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> end </span><span class="token operator">=</span><span class="token plain"> time</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">time</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">print</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">end </span><span class="token operator">-</span><span class="token plain"> start</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">convert_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> max_diff </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">max</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token builtin" style="color:rgb(189, 147, 249)">max</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">max</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> scale_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> max_diff</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> scale_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> max_diff</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">scale_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">points</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> max_diff</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> min_value </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">points</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> scaled_coordinates </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">p </span><span class="token operator">-</span><span class="token plain"> min_value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">/</span><span class="token plain"> max_diff </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> p </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">in</span><span class="token plain"> points</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> scaled_coordinates</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">draw_lines</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> figure </span><span class="token operator">=</span><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">gcf</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> figure</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">set_size_inches</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">5</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">5</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">plot</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> c </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'w'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">linewidth</span><span class="token operator">=</span><span class="token number">5</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">scatter</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> c </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'w'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> s </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">125</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">axis</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">'off'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">savefig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">'name.png'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> transparent</span><span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">format</span><span class="token operator">=</span><span class="token string" style="color:rgb(255, 121, 198)">'png'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">point </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">126.96352960597338</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.590841000217125</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">126.96987292787792</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.58435564234159</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">126.98128481452298</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.58594375113966</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">126.99360339342958</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.58248524741927</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">126.99867565340067</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.56778118088622</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">127.001935378366117</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.55985240444085</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">126.9831048919687</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.548030119488665</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">126.97189273528845</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.5119879225856</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">127.02689859997221</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">37.48488593333883</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">draw</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">point</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)</p><p><img loading="lazy" alt="./routeImage.png" src="/assets/images/routeImage-0eac25ba9b356cd034ade6e062c1ce19.png" width="500" height="500" class="img_ev3q"></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="aws-lambda">AWS Lambda<a href="#aws-lambda" class="hash-link" aria-label="AWS Lambda에 대한 직접 링크" title="AWS Lambda에 대한 직접 링크">​</a></h3><p>썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.<br> +<!-- -->이미지 저장 및 URL: AWS S3, AWS CloudFront</p> +<p>플로우는 다음과 같다.</p> +<mermaid value="graph LR + Server -- 생성 요청 --> AG[API Gateway] --> Lambda --> S3 + Client --> CloudFront --> S3"></mermaid> +<h3 id="요구사항">요구사항</h3> +<p><img alt="./route.png" src="https://greeng00se.github.io/assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png" width="1014" height="902"></p> +<p>우측 상단의 경로 이미지를 생성하려고 한다.<br> +<!-- -->경로 이미지 생성에 대한 요구사항은 다음과 같다.</p> +<ul> +<li>위도, 경도로 이루어진 배열을 입력받는다.</li> +<li>이미지 생성</li> +<li>선과 점 표현</li> +<li>투명한 배경색</li> +<li>위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.</li> +</ul> +<h3 id="이미지-출력-방식">이미지 출력 방식</h3> +<ol> +<li>위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장</li> +<li>플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장</li> +</ol> +<p>이미지 출력 방식의 경우 1번과 2번을 고민했었다.<br> +<!-- -->파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.</p> +<h3 id="로컬에서-기능-구현">로컬에서 기능 구현</h3> +<pre><code class="language-python">import time + +import matplotlib.pyplot as plt + + +def draw(point): + start = time.time() + x, y = zip(*point) + pixel_x, pixel_y = convert_to_pixel_values(x, y) + draw_lines(pixel_x, pixel_y) + end = time.time() + print(end - start) + +def convert_to_pixel_values(x, y): + max_diff = max(max(x) - min(x), max(y) - min(y)) + return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff) + + +def scale_to_pixel_values(points, max_diff): + min_value = min(points) + scaled_coordinates = [(p - min_value) / max_diff for p in points] + return scaled_coordinates + + +def draw_lines(x, y): + figure = plt.gcf() + figure.set_size_inches(5, 5) + plt.plot(x, y, c = 'w',linewidth=5) + plt.scatter(x[3],y[3], c = 'w', s = 125) + plt.axis('off') + plt.savefig('name.png', transparent=True, format='png') + +point = [ + [126.96352960597338, 37.590841000217125], + [126.96987292787792, 37.58435564234159], + [126.98128481452298, 37.58594375113966], + [126.99360339342958, 37.58248524741927], + [126.99867565340067, 37.56778118088622], + [127.001935378366117, 37.55985240444085], + [126.9831048919687, 37.548030119488665], + [126.97189273528845, 37.5119879225856], + [127.02689859997221, 37.48488593333883] +] + +draw(point) +</code></pre> +<p>생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)</p> +<p><img alt="./routeImage.png" src="https://greeng00se.github.io/assets/images/routeImage-0eac25ba9b356cd034ade6e062c1ce19.png" width="500" height="500"></p> +<h3 id="aws-lambda">AWS Lambda</h3> +<p>썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.<br> <!-- -->따라서 서버리스로 파일을 처리했다.<br> -<!-- -->추가로 s3 접근은 boto3를 사용했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="람다-s3-접근을-위한-iam-생성">람다 S3 접근을 위한 IAM 생성<a href="#람다-s3-접근을-위한-iam-생성" class="hash-link" aria-label="람다 S3 접근을 위한 IAM 생성에 대한 직접 링크" title="람다 S3 접근을 위한 IAM 생성에 대한 직접 링크">​</a></h3><p>AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="람다-배포용-코드">람다 배포용 코드<a href="#람다-배포용-코드" class="hash-link" aria-label="람다 배포용 코드에 대한 직접 링크" title="람다 배포용 코드에 대한 직접 링크">​</a></h3><p>기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다. </p><div class="language-python codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-python codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> io</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> uuid</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> boto3</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> matplotlib</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">pyplot </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">as</span><span class="token plain"> plt</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">PIXEL </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">255</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">BUCKET_NAME </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'image-plot'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">S3 </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'s3'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">lambda_handler</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> x </span><span class="token operator">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">'x'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> y </span><span class="token operator">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">'y'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> image_name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">str</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">uuid</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">uuid4</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> img_data </span><span class="token operator">=</span><span class="token plain"> draw</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> s3 </span><span class="token operator">=</span><span class="token plain"> boto3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">client</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">S3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> s3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">put_object</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">Body</span><span class="token operator">=</span><span class="token plain">img_data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">getvalue</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> ContentType</span><span class="token operator">=</span><span class="token string" style="color:rgb(255, 121, 198)">'image/png'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> Bucket</span><span class="token operator">=</span><span class="token plain">BUCKET_NAME</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> Key</span><span class="token operator">=</span><span class="token plain">image_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> url </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string-interpolation string" style="color:rgb(255, 121, 198)">f'https://</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string-interpolation interpolation">BUCKET_NAME</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string-interpolation string" style="color:rgb(255, 121, 198)">.s3.ap-northeast-2.amazonaws.com/</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token string-interpolation interpolation">image_name</span><span class="token string-interpolation interpolation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token string-interpolation string" style="color:rgb(255, 121, 198)">'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'statusCode'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">200</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'body'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> url</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">draw</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> pixel_x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> pixel_y </span><span class="token operator">=</span><span class="token plain"> convert_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> img_data </span><span class="token operator">=</span><span class="token plain"> draw_lines</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">pixel_x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> pixel_y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">close</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> img_data</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">convert_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> max_diff </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">max</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token builtin" style="color:rgb(189, 147, 249)">max</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">max</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> scale_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> max_diff</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> scale_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> max_diff</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">scale_to_pixel_values</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">points</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> max_diff</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> min_value </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">min</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">points</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> scaled_coordinates </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">p </span><span class="token operator">-</span><span class="token plain"> min_value</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">/</span><span class="token plain"> max_diff </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> p </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">in</span><span class="token plain"> points</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> pixel_values </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token builtin" style="color:rgb(189, 147, 249)">int</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">p </span><span class="token operator">*</span><span class="token plain"> PIXEL</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> p </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">in</span><span class="token plain"> scaled_coordinates</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> pixel_values</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">draw_lines</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">plot</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'k-'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> linewidth</span><span class="token operator">=</span><span class="token number">10</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">axis</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">'off'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> img_data </span><span class="token operator">=</span><span class="token plain"> io</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">BytesIO</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> plt</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">savefig</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">img_data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> transparent</span><span class="token operator">=</span><span class="token boolean">True</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">format</span><span class="token operator">=</span><span class="token string" style="color:rgb(255, 121, 198)">'png'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> img_data</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">seek</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> img_data</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="layer-추가를-위한-zip-파일-생성">Layer 추가를 위한 zip 파일 생성<a href="#layer-추가를-위한-zip-파일-생성" class="hash-link" aria-label="Layer 추가를 위한 zip 파일 생성에 대한 직접 링크" title="Layer 추가를 위한 zip 파일 생성에 대한 직접 링크">​</a></h3><p>matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.<br> +<!-- -->추가로 s3 접근은 boto3를 사용했다.</p> +<h3 id="람다-s3-접근을-위한-iam-생성">람다 S3 접근을 위한 IAM 생성</h3> +<p>AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.</p> +<h3 id="람다-배포용-코드">람다 배포용 코드</h3> +<p>기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.</p> +<pre><code class="language-python"> +import io +import uuid + +import boto3 +import matplotlib.pyplot as plt + +PIXEL = 255 +BUCKET_NAME = 'image-plot' +S3 = 's3' + +def lambda_handler(event, context): + x = event['x'] + y = event['y'] + image_name = str(uuid.uuid4()) + + img_data = draw(x, y) + s3 = boto3.client(S3) + s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name) + url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}' + + return { + 'statusCode': 200, + 'body': url + } + +def draw(x, y): + pixel_x, pixel_y = convert_to_pixel_values(x, y) + img_data = draw_lines(pixel_x, pixel_y) + plt.close() + return img_data + +def convert_to_pixel_values(x, y): + max_diff = max(max(x) - min(x), max(y) - min(y)) + return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff) + +def scale_to_pixel_values(points, max_diff): + min_value = min(points) + scaled_coordinates = [(p - min_value) / max_diff for p in points] + pixel_values = [int(p * PIXEL) for p in scaled_coordinates] + return pixel_values + +def draw_lines(x, y): + plt.plot(x, y, 'k-', linewidth=10) + plt.axis('off') + img_data = io.BytesIO() + plt.savefig(img_data, transparent=True, format='png') + img_data.seek(0) + return img_data + +</code></pre> +<h3 id="layer-추가를-위한-zip-파일-생성">Layer 추가를 위한 zip 파일 생성</h3> +<p>matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.<br> <!-- -->zip 파일을 만들어서 업로드해야한다.<br> <!-- -->이때 python의 Lambda 런타임에 대한 계층 경로는 python이다.<br> -<!-- -->따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다. </p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">pillow.zip</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">│ python/PIL</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">└ python/Pillow-5.3.0.dist-info</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다. </p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt update</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt install zip</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">sudo apt install python3-pip</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">mkdir python</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="no-module-named-numpycore_multiarray_umath-에러"><code>No module named 'numpy.core._multiarray_umath'</code> 에러<a href="#no-module-named-numpycore_multiarray_umath-에러" class="hash-link" aria-label="no-module-named-numpycore_multiarray_umath-에러에 대한 직접 링크" title="no-module-named-numpycore_multiarray_umath-에러에 대한 직접 링크">​</a></h3><p>Layer 추가 후 람다 실행 시 발생한 에러였다.<br> +<!-- -->따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.</p> +<pre><code>pillow.zip +│ python/PIL +└ python/Pillow-5.3.0.dist-info +</code></pre> +<p>Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.</p> +<pre><code>sudo apt update +sudo apt install zip +sudo apt install python3-pip + +mkdir python +pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로 +zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로 +</code></pre> +<h3 id="no-module-named-numpycore_multiarray_umath-에러"><code>No module named 'numpy.core._multiarray_umath'</code> 에러</h3> +<p>Layer 추가 후 람다 실행 시 발생한 에러였다.<br> <!-- -->처음에 mac에서 zip 파일을 생성해서 업로드했는데 해당 문제가 발생했다.<br> <!-- -->이는 lambda가 돌아가는 동일한 환경에서 layer를 위한 zip 파일을 만들지 않아서 발생하는 문제다.<br> -<!-- -->간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="적정기술에-대한-생각">적정기술에 대한 생각<a href="#적정기술에-대한-생각" class="hash-link" aria-label="적정기술에 대한 생각에 대한 직접 링크" title="적정기술에 대한 생각에 대한 직접 링크">​</a></h3><p>프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.<br> +<!-- -->간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.</p> +<h3 id="적정기술에-대한-생각">적정기술에 대한 생각</h3> +<p>프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.<br> <!-- -->AWS Lambda를 사용하는 것은 인스턴스에 해당 코드를 배포하는 것보다 더 효율적인 방법일 수 있다.<br> <!-- -->하지만 현재 프로젝트에서 가용 가능한 자원, 기술의 난이도, 사용하는 팀원을 고려한다면 Lambda는 적정기술이 아닐 수 있다.<br> -<!-- -->따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다. </p><p><strong>최종적으로 Java AWT를 사용하기로 결정했다.</strong></p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h2><p><a href="https://aws.amazon.com/ko/lambda/" target="_blank" rel="noopener noreferrer">AWS Lambda</a><br> -<a href="https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-layers.html" target="_blank" rel="noopener noreferrer">Lambda Layer</a><br> -<a href="https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-package.html" target="_blank" rel="noopener noreferrer">Python Lambda 함수에 대한 .zip 파일 아카이브 작업</a><br> -<a href="https://gist.github.com/ksmin23/0f3f243408a8497f766b43cf589fea7b" target="_blank" rel="noopener noreferrer">No module named 'numpy.core._multiarray_umath'</a><br> -<a href="https://techblog.woowahan.com/6217/" target="_blank" rel="noopener noreferrer">사례별로 알아본 안전한 S3 사용 가이드</a></p>]]></content> +<!-- -->따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.</p> +<p><strong>최종적으로 Java AWT를 사용하기로 결정했다.</strong></p> +<h2 id="참고-자료">참고 자료</h2> +<p><a href="https://aws.amazon.com/ko/lambda/">AWS Lambda</a><br> +<a href="https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-layers.html">Lambda Layer</a><br> +<a href="https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/python-package.html">Python Lambda 함수에 대한 .zip 파일 아카이브 작업</a><br> +<a href="https://gist.github.com/ksmin23/0f3f243408a8497f766b43cf589fea7b">No module named 'numpy.core._multiarray_umath'</a><br> +<a href="https://techblog.woowahan.com/6217/">사례별로 알아본 안전한 S3 사용 가이드</a></p>]]></content> <category label="Image" term="Image"/> <category label="Python" term="Python"/> </entry> @@ -416,15 +1945,47 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/mock-static-method"/> <updated>2023-07-30T00:00:00.000Z</updated> <summary type="html"><![CDATA[개요]]></summary> - <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="개요">개요<a href="#개요" class="hash-link" aria-label="개요에 대한 직접 링크" title="개요에 대한 직접 링크">​</a></h3><p>정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.<br> -<!-- -->하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다. </p><p>예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다. </p><p>프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.<br> + <content type="html"><![CDATA[<h3 id="개요">개요</h3> +<p>정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.<br> +<!-- -->하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.</p> +<p>예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.</p> +<p>프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.<br> <!-- -->해당 static 메서드를 호출하는 부분을 따로 RouteImageUploader 클래스로 최대한 분리했다.<br> -<!-- -->이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">upload</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">BufferedImage</span><span class="token plain"> bufferedImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">File</span><span class="token plain"> file </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">File</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">파일경로</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">try</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">ImageIO</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">write</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">bufferedImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">ROUTE_IMAGE_FORMAT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> file</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">catch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">IOException</span><span class="token plain"> e</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">throw</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">DrawException</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token constant" style="color:rgb(189, 147, 249)">IMAGE_SAVE_FAIL</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="mocking-static-methods">Mocking static methods<a href="#mocking-static-methods" class="hash-link" aria-label="Mocking static methods에 대한 직접 링크" title="Mocking static methods에 대한 직접 링크">​</a></h3><p>Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.<br> -<!-- -->mockStatic을 사용하면 <code>MockedStatic<T></code>이 반환되는데 사용 후 꼭 close를 해줘야 한다. </p><p>JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 <code>MockedStatic<T></code>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// given</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token class-name">BufferedImage</span><span class="token plain"> bufferedImage </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">BufferedImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">800</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token number">800</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">BufferedImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">TYPE_INT_ARGB</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token class-name">RouteImageUploader</span><span class="token plain"> routeImageUploader </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">RouteImageUploader</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// expect</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">try</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">MockedStatic</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">ImageIO</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> imageIO </span><span class="token operator">=</span><span class="token plain"> </span><span class="token class-name">Mockito</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">mockStatic</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">ImageIO</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> routeImageUploader</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">upload</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">bufferedImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> imageIO</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">verify</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-></span><span class="token plain"> </span><span class="token class-name">ImageIO</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">write</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">BufferedImage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">String</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">File</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">class</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">times</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="마치며">마치며<a href="#마치며" class="hash-link" aria-label="마치며에 대한 직접 링크" title="마치며에 대한 직접 링크">​</a></h3><p>정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.<br> +<!-- -->이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.</p> +<pre><code class="language-java">public void upload(BufferedImage bufferedImage) { + File file = new File(파일경로); + try { + ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file); + } catch (IOException e) { + throw new DrawException(IMAGE_SAVE_FAIL); + } +} +</code></pre> +<h3 id="mocking-static-methods">Mocking static methods</h3> +<p>Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.<br> +<!-- -->mockStatic을 사용하면 <code>MockedStatic<T></code>이 반환되는데 사용 후 꼭 close를 해줘야 한다.</p> +<p>JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 <code>MockedStatic<T></code>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.</p> +<pre><code class="language-java">// given +BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB); +RouteImageUploader routeImageUploader = new RouteImageUploader(); + +// expect +try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) { + routeImageUploader.upload(bufferedImage); + imageIO.verify( + () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)), + times(1) + ); +} +</code></pre> +<h3 id="마치며">마치며</h3> +<p>정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.<br> <!-- -->하지만 추상화를 하면 할 수록 코드의 복잡도는 증가한다.<br> -<!-- -->항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h3><p><a href="https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks" target="_blank" rel="noopener noreferrer">Mocking static methods</a><br> -<a href="https://www.baeldung.com/mockito-mock-static-methods" target="_blank" rel="noopener noreferrer">Mockito mock static methods</a><br> -<a href="https://github.com/mockito/mockito/issues/1013" target="_blank" rel="noopener noreferrer">Enable mocking static methods in Mockito</a></p>]]></content> +<!-- -->항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.</p> +<h3 id="참고-자료">참고 자료</h3> +<p><a href="https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#static_mocks">Mocking static methods</a><br> +<a href="https://www.baeldung.com/mockito-mock-static-methods">Mockito mock static methods</a><br> +<a href="https://github.com/mockito/mockito/issues/1013">Enable mocking static methods in Mockito</a></p>]]></content> <category label="Mockito" term="Mockito"/> <category label="static" term="static"/> </entry> @@ -434,12 +1995,56 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/route-image-intro"/> <updated>2023-07-27T00:00:00.000Z</updated> <summary type="html"><![CDATA[./route.png]]></summary> - <content type="html"><![CDATA[<p><img loading="lazy" alt="./route.png" src="/assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png" width="1014" height="902" class="img_ev3q"></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="이미지-생성의-책임">이미지 생성의 책임<a href="#이미지-생성의-책임" class="hash-link" aria-label="이미지 생성의 책임에 대한 직접 링크" title="이미지 생성의 책임에 대한 직접 링크">​</a></h3><p>위 와이어 프레임에서 <code>여행 히스토리</code>와 <code>여행에 대한 감상을 위한 경로 이미지</code>의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.<br> -<!-- -->따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.</p><p>해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.</p><ul><li>이미지 생성</li><li>선과 점 표현</li><li>투명한 배경색</li></ul><p>현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="고려한-기술">고려한 기술<a href="#고려한-기술" class="hash-link" aria-label="고려한 기술에 대한 직접 링크" title="고려한 기술에 대한 직접 링크">​</a></h3><p>백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다. </p><ul><li>Python의 Matplotlib</li><li><strong>AWT(Abstract Window Toolkit) <!-- -->[최종 선택]</strong></li><li>이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)</li><li>Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)</li></ul><h2 class="anchor anchorWithStickyNavbar_LWe7" id="python--matplotlib">Python & Matplotlib<a href="#python--matplotlib" class="hash-link" aria-label="Python & Matplotlib에 대한 직접 링크" title="Python & Matplotlib에 대한 직접 링크">​</a></h2><p>데이터 시각화 라이브러리<br> -<!-- -->이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초 </p><ul><li>코드가 간단해서 유지 보수성이 좋다. </li><li>AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.</li><li>Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.</li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="java-awt-이외의-라이브러리">Java AWT 이외의 라이브러리<a href="#java-awt-이외의-라이브러리" class="hash-link" aria-label="Java AWT 이외의 라이브러리에 대한 직접 링크" title="Java AWT 이외의 라이브러리에 대한 직접 링크">​</a></h3><p>Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.</p><table><thead><tr><th>라이브러리</th><th>설명</th><th>제외 이유</th></tr></thead><tbody><tr><td>Swing</td><td>AWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함</td><td>요구사항에 비해 무겁고 복잡도가 높음</td></tr><tr><td>JavaFX</td><td>Swing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함</td><td>요구사항에 비해 무겁고 복잡도가 높음</td></tr><tr><td><a href="https://github.com/yuriy-g/simple-java-plot" target="_blank" rel="noopener noreferrer">simple-java-plot</a></td><td>AWT로 구현된 플로팅 라이브러리</td><td>AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음</td></tr><tr><td><a href="https://github.com/sh0nk/matplotlib4j" target="_blank" rel="noopener noreferrer">matplotlib4j</a></td><td>Matplotlib를 Java에서 사용할 수 있게 하는 라이브러리</td><td>내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음</td></tr></tbody></table><h3 class="anchor anchorWithStickyNavbar_LWe7" id="java--awtabstract-window-toolkit">Java & AWT(Abstract Window Toolkit)<a href="#java--awtabstract-window-toolkit" class="hash-link" aria-label="Java & AWT(Abstract Window Toolkit)에 대한 직접 링크" title="Java & AWT(Abstract Window Toolkit)에 대한 직접 링크">​</a></h3><p>그래픽과 이미지를 그리기 위한 도구<br> -<!-- -->이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초 </p><ul><li>플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.</li><li>이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.</li><li>추가적인 api 호출을 하지 않아도 된다.</li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="기술-선택">기술 선택<a href="#기술-선택" class="hash-link" aria-label="기술 선택에 대한 직접 링크" title="기술 선택에 대한 직접 링크">​</a></h3><p>AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.<br> -<!-- -->하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="유지-보수">유지 보수<a href="#유지-보수" class="hash-link" aria-label="유지 보수에 대한 직접 링크" title="유지 보수에 대한 직접 링크">​</a></h3><p>AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.<br> -<!-- -->따라서 다음과 같은 방법으로 공유하기로 했다. </p><ol><li>코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다. </li><li>AWT를 사용한 부분을 문서화하여 공유한다.</li></ol><h3 class="anchor anchorWithStickyNavbar_LWe7" id="레벨-3를-마무리하며-내용-추가">레벨 3를 마무리하며 내용 추가<a href="#레벨-3를-마무리하며-내용-추가" class="hash-link" aria-label="레벨 3를 마무리하며 내용 추가에 대한 직접 링크" title="레벨 3를 마무리하며 내용 추가에 대한 직접 링크">​</a></h3><p>기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.<br> + <content type="html"><![CDATA[<p><img alt="./route.png" src="https://greeng00se.github.io/assets/images/route-89cacb9b7815a3191ab1f9d9e23c43a1.png" width="1014" height="902"></p> +<h3 id="이미지-생성의-책임">이미지 생성의 책임</h3> +<p>위 와이어 프레임에서 <code>여행 히스토리</code>와 <code>여행에 대한 감상을 위한 경로 이미지</code>의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.<br> +<!-- -->따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.</p> +<p>해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.</p> +<ul> +<li>이미지 생성</li> +<li>선과 점 표현</li> +<li>투명한 배경색</li> +</ul> +<p>현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.</p> +<h3 id="고려한-기술">고려한 기술</h3> +<p>백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.</p> +<ul> +<li>Python의 Matplotlib</li> +<li><strong>AWT(Abstract Window Toolkit) [최종 선택]</strong></li> +<li>이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)</li> +<li>Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)</li> +</ul> +<h2 id="python--matplotlib">Python & Matplotlib</h2> +<p>데이터 시각화 라이브러리<br> +<!-- -->이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초</p> +<ul> +<li>코드가 간단해서 유지 보수성이 좋다.</li> +<li>AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.</li> +<li>Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.</li> +</ul> +<h3 id="java-awt-이외의-라이브러리">Java AWT 이외의 라이브러리</h3> +<p>Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.</p> +<table><thead><tr><th>라이브러리</th><th>설명</th><th>제외 이유</th></tr></thead><tbody><tr><td>Swing</td><td>AWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함</td><td>요구사항에 비해 무겁고 복잡도가 높음</td></tr><tr><td>JavaFX</td><td>Swing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함</td><td>요구사항에 비해 무겁고 복잡도가 높음</td></tr><tr><td><a href="https://github.com/yuriy-g/simple-java-plot">simple-java-plot</a></td><td>AWT로 구현된 플로팅 라이브러리</td><td>AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음</td></tr><tr><td><a href="https://github.com/sh0nk/matplotlib4j">matplotlib4j</a></td><td>Matplotlib를 Java에서 사용할 수 있게 하는 라이브러리</td><td>내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음</td></tr></tbody></table> +<h3 id="java--awtabstract-window-toolkit">Java & AWT(Abstract Window Toolkit)</h3> +<p>그래픽과 이미지를 그리기 위한 도구<br> +<!-- -->이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초</p> +<ul> +<li>플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.</li> +<li>이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.</li> +<li>추가적인 api 호출을 하지 않아도 된다.</li> +</ul> +<h3 id="기술-선택">기술 선택</h3> +<p>AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.<br> +<!-- -->하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.</p> +<h3 id="유지-보수">유지 보수</h3> +<p>AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.<br> +<!-- -->따라서 다음과 같은 방법으로 공유하기로 했다.</p> +<ol> +<li>코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.</li> +<li>AWT를 사용한 부분을 문서화하여 공유한다.</li> +</ol> +<h3 id="레벨-3를-마무리하며-내용-추가">레벨 3를 마무리하며 내용 추가</h3> +<p>기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.<br> <!-- -->AWT를 사용하는 부분에서 애플리케이션 실행 시간을 제외하면 파이썬과 비슷한 시간안에 이미지를 생성할 수 있었다.</p>]]></content> <category label="image" term="image"/> <category label="awt" term="awt"/> @@ -450,22 +2055,96 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/java-spring-springboot"/> <updated>2023-07-24T00:00:00.000Z</updated> <summary type="html"><![CDATA[자바 17, 스프링 6.0, 스프링 부트 3.1]]></summary> - <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_LWe7" id="자바-17-스프링-60-스프링-부트-31">자바 17, 스프링 6.0, 스프링 부트 3.1<a href="#자바-17-스프링-60-스프링-부트-31" class="hash-link" aria-label="자바 17, 스프링 6.0, 스프링 부트 3.1에 대한 직접 링크" title="자바 17, 스프링 6.0, 스프링 부트 3.1에 대한 직접 링크">​</a></h2><p>팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.<br> -<!-- -->2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="자바-변경-사항">자바 변경 사항<a href="#자바-변경-사항" class="hash-link" aria-label="자바 변경 사항에 대한 직접 링크" title="자바 변경 사항에 대한 직접 링크">​</a></h2><p>우아한테크코스 레벨 2까지는 자바 11을 사용했었다.<br> -<!-- -->따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="switch-expressionsjava-14">Switch Expressions(Java 14)<a href="#switch-expressionsjava-14" class="hash-link" aria-label="Switch Expressions(Java 14)에 대한 직접 링크" title="Switch Expressions(Java 14)에 대한 직접 링크">​</a></h3><p>Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">enum</span><span class="token plain"> </span><span class="token class-name">RESULT</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">WIN</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">LOSE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DRAW</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token class-name">RESULT</span><span class="token plain"> result </span><span class="token operator">=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">RESULT</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token constant" style="color:rgb(189, 147, 249)">WIN</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">int</span><span class="token plain"> prize </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">result</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">WIN</span><span class="token plain"> </span><span class="token operator">-></span><span class="token plain"> </span><span class="token number">10_000_000</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">case</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">LOSE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">DRAW</span><span class="token plain"> </span><span class="token operator">-></span><span class="token plain"> </span><span class="token number">5_000_000</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token operator">-></span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>주요 특징은 다음과 같다.</p><ul><li><code>-></code> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.</li><li>case를 콤마(<code>,</code>)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.</li><li>break 문이 필요 없다.</li><li>default 블록을 통해 기본 값을 지정할 수 있다.</li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="text-blockjava-15">Text Block(Java 15)<a href="#text-blockjava-15" class="hash-link" aria-label="Text Block(Java 15)에 대한 직접 링크" title="Text Block(Java 15)에 대한 직접 링크">​</a></h3><p>Java 15에는 새로운 문자열 표현방식이 추가되었다.<br> -<!-- -->긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Repository</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">interface</span><span class="token plain"> </span><span class="token class-name">PostRepository</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">extends</span><span class="token plain"> </span><span class="token class-name">JpaRepository</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Post</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token generics"> </span><span class="token generics class-name">Long</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token annotation punctuation" style="color:rgb(248, 248, 242)">@Query</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)">"""</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)"> SELECT p FROM Post p</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)"> WHERE p.title LIKE %:keyword%</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)"> OR p.content LIKE %:keyword%</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token triple-quoted-string string" style="color:rgb(255, 121, 198)"> """</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token class-name">List</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)"><</span><span class="token generics class-name">Post</span><span class="token generics punctuation" style="color:rgb(248, 248, 242)">></span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">findPostsByTitleOrContentContainingKeyword</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">String</span><span class="token plain"> keyword</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="npe-메시지java-15">NPE 메시지(Java 15)<a href="#npe-메시지java-15" class="hash-link" aria-label="NPE 메시지(Java 15)에 대한 직접 링크" title="NPE 메시지(Java 15)에 대한 직접 링크">​</a></h3><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token class-name">String</span><span class="token plain"> name </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token function" style="color:rgb(80, 250, 123)">chars</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">/** </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># before</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">java.lang.NullPointerException</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"> at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="display:inline-block;color:rgb(98, 114, 164)"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># after</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">Cannot invoke "String.chars()" because "name" is null</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">*/</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="recordjava-16">Record(Java 16)<a href="#recordjava-16" class="hash-link" aria-label="Record(Java 16)에 대한 직접 링크" title="Record(Java 16)에 대한 직접 링크">​</a></h3><p>Lombok의 <code>@Data</code>, kotlin의 data 클래스와 유사한 기능을 제공한다.<br> + <content type="html"><![CDATA[<h2 id="자바-17-스프링-60-스프링-부트-31">자바 17, 스프링 6.0, 스프링 부트 3.1</h2> +<p>팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.<br> +<!-- -->2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.</p> +<h2 id="자바-변경-사항">자바 변경 사항</h2> +<p>우아한테크코스 레벨 2까지는 자바 11을 사용했었다.<br> +<!-- -->따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.</p> +<h3 id="switch-expressionsjava-14">Switch Expressions(Java 14)</h3> +<p>Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.</p> +<pre><code class="language-java">enum RESULT { + WIN, LOSE, DRAW +} + +RESULT result = RESULT.WIN; + +int prize = switch (result) { + case WIN -> 10_000_000; + case LOSE, DRAW -> 5_000_000; + default -> 0; +}; +</code></pre> +<p>주요 특징은 다음과 같다.</p> +<ul> +<li><code>-></code> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.</li> +<li>case를 콤마(<code>,</code>)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.</li> +<li>break 문이 필요 없다.</li> +<li>default 블록을 통해 기본 값을 지정할 수 있다.</li> +</ul> +<h3 id="text-blockjava-15">Text Block(Java 15)</h3> +<p>Java 15에는 새로운 문자열 표현방식이 추가되었다.<br> +<!-- -->긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.</p> +<pre><code class="language-java">@Repository +public interface PostRepository extends JpaRepository<Post, Long> { + @Query(""" + SELECT p FROM Post p + WHERE p.title LIKE %:keyword% + OR p.content LIKE %:keyword% + """) + List<Post> findPostsByTitleOrContentContainingKeyword(String keyword); +} +</code></pre> +<h3 id="npe-메시지java-15">NPE 메시지(Java 15)</h3> +<pre><code class="language-java">String name = null; +name.chars(); + +/** +# before +java.lang.NullPointerException + at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61) + +# after +Cannot invoke "String.chars()" because "name" is null +java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null +*/ +</code></pre> +<h3 id="recordjava-16">Record(Java 16)</h3> +<p>Lombok의 <code>@Data</code>, kotlin의 data 클래스와 유사한 기능을 제공한다.<br> <!-- -->Record를 선언하는 경우 접근자, 생성자, equals & hashcode, toString이 제공된다.<br> -<!-- -->데이터 전송 용도로 적합해 보인다. </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">public</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">record</span><span class="token plain"> </span><span class="token class-name">PostDto</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token class-name">String</span><span class="token plain"> title</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token plain"> content</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="추가적인-변경사항">추가적인 변경사항<a href="#추가적인-변경사항" class="hash-link" aria-label="추가적인 변경사항에 대한 직접 링크" title="추가적인 변경사항에 대한 직접 링크">​</a></h3><p>이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="스프링-스프링-부트-변경-사항">스프링, 스프링 부트 변경 사항<a href="#스프링-스프링-부트-변경-사항" class="hash-link" aria-label="스프링, 스프링 부트 변경 사항에 대한 직접 링크" title="스프링, 스프링 부트 변경 사항에 대한 직접 링크">​</a></h2><p>스프링과 스프링 부트에도 많은 변경 사항이 있었다.<br> -<!-- -->따라서 필요해보이는 몇개 정도만 정리했다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="스프링-요구사항">스프링 요구사항<a href="#스프링-요구사항" class="hash-link" aria-label="스프링 요구사항에 대한 직접 링크" title="스프링 요구사항에 대한 직접 링크">​</a></h3><p>Java 17, Jakarta EE 9 이상이어야 한다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="네임스페이스-변경">네임스페이스 변경<a href="#네임스페이스-변경" class="hash-link" aria-label="네임스페이스 변경에 대한 직접 링크" title="네임스페이스 변경에 대한 직접 링크">​</a></h3><p>Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="pathpatternparser---trailing-slash-허용하지-않음">PathPatternParser - trailing slash 허용하지 않음<a href="#pathpatternparser---trailing-slash-허용하지-않음" class="hash-link" aria-label="PathPatternParser - trailing slash 허용하지 않음에 대한 직접 링크" title="PathPatternParser - trailing slash 허용하지 않음에 대한 직접 링크">​</a></h3><p>6.0 이전의 경우 기본 설정 기준으로 <code>@GetMapping("/hello")</code>와 <code>@GetMapping("/hello/")</code>가 동일했다.<br> -<!-- -->6.0 이후의 PathPatternParser가 기본으로 사용되고, <code>/hello</code>와 <code>/hello/</code>는 서로 다른 URL로 매칭된다. </p><blockquote><p>PathPatternParser used by default (with the ability to opt into PathMatcher). </p></blockquote><h3 class="anchor anchorWithStickyNavbar_LWe7" id="http-interface-client">HTTP interface client<a href="#http-interface-client" class="hash-link" aria-label="HTTP interface client에 대한 직접 링크" title="HTTP interface client에 대한 직접 링크">​</a></h3><p>자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.<br> -<!-- -->자세한 내용은 <a href="https://www.youtube.com/watch?v=Kb37Q5GCyZs" target="_blank" rel="noopener noreferrer">토비님의 강의</a>를 참고하면 좋을 것 같다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="스프링-부트-최소-요구사항">스프링 부트 최소 요구사항<a href="#스프링-부트-최소-요구사항" class="hash-link" aria-label="스프링 부트 최소 요구사항에 대한 직접 링크" title="스프링 부트 최소 요구사항에 대한 직접 링크">​</a></h3><p>Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6<br> -<!-- -->이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h2><p><a href="https://www.youtube.com/watch?v=1WT6oxchM9M" target="_blank" rel="noopener noreferrer">어느 월급쟁이개발자 의 스프링 부트 따라잡기</a><br> -<a href="https://www.youtube.com/watch?v=7SlDdzVk6GE" target="_blank" rel="noopener noreferrer">자바 9-16 주요 특징 복습하기</a><br> -<a href="https://www.samsungsds.com/kr/insights/java_jakarta.html" target="_blank" rel="noopener noreferrer">Java EE에서 Jakarta EE로의 전환</a><br> -<a href="https://www.youtube.com/watch?v=Kb37Q5GCyZs" target="_blank" rel="noopener noreferrer">Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩</a><br> -<a href="https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x" target="_blank" rel="noopener noreferrer">What's New in Spring Framework 6.x</a><br> -<a href="https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes" target="_blank" rel="noopener noreferrer">Spring Boot 3.0 Release Notes</a><br> -<a href="https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes" target="_blank" rel="noopener noreferrer">Spring Boot 3.1 Release Notes</a></p>]]></content> +<!-- -->데이터 전송 용도로 적합해 보인다.</p> +<pre><code class="language-java">public record PostDto(String title, String content) { +} +</code></pre> +<h3 id="추가적인-변경사항">추가적인 변경사항</h3> +<p>이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.</p> +<h2 id="스프링-스프링-부트-변경-사항">스프링, 스프링 부트 변경 사항</h2> +<p>스프링과 스프링 부트에도 많은 변경 사항이 있었다.<br> +<!-- -->따라서 필요해보이는 몇개 정도만 정리했다.</p> +<h3 id="스프링-요구사항">스프링 요구사항</h3> +<p>Java 17, Jakarta EE 9 이상이어야 한다.</p> +<h3 id="네임스페이스-변경">네임스페이스 변경</h3> +<p>Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.</p> +<h3 id="pathpatternparser---trailing-slash-허용하지-않음">PathPatternParser - trailing slash 허용하지 않음</h3> +<p>6.0 이전의 경우 기본 설정 기준으로 <code>@GetMapping("/hello")</code>와 <code>@GetMapping("/hello/")</code>가 동일했다.<br> +<!-- -->6.0 이후의 PathPatternParser가 기본으로 사용되고, <code>/hello</code>와 <code>/hello/</code>는 서로 다른 URL로 매칭된다.</p> +<blockquote> +<p>PathPatternParser used by default (with the ability to opt into PathMatcher).</p> +</blockquote> +<h3 id="http-interface-client">HTTP interface client</h3> +<p>자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.<br> +<!-- -->자세한 내용은 <a href="https://www.youtube.com/watch?v=Kb37Q5GCyZs">토비님의 강의</a>를 참고하면 좋을 것 같다.</p> +<h3 id="스프링-부트-최소-요구사항">스프링 부트 최소 요구사항</h3> +<p>Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6<br> +<!-- -->이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.</p> +<h2 id="참고-자료">참고 자료</h2> +<p><a href="https://www.youtube.com/watch?v=1WT6oxchM9M">어느 월급쟁이개발자 의 스프링 부트 따라잡기</a><br> +<a href="https://www.youtube.com/watch?v=7SlDdzVk6GE">자바 9-16 주요 특징 복습하기</a><br> +<a href="https://www.samsungsds.com/kr/insights/java_jakarta.html">Java EE에서 Jakarta EE로의 전환</a><br> +<a href="https://www.youtube.com/watch?v=Kb37Q5GCyZs">Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩</a><br> +<a href="https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-6.x">What's New in Spring Framework 6.x</a><br> +<a href="https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes">Spring Boot 3.0 Release Notes</a><br> +<a href="https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes">Spring Boot 3.1 Release Notes</a></p>]]></content> <category label="Java" term="Java"/> <category label="Spring Boot" term="Spring Boot"/> <category label="Spring" term="Spring"/> @@ -476,20 +2155,67 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/websocket"/> <updated>2023-06-26T00:00:00.000Z</updated> <summary type="html"><![CDATA[웹소켓]]></summary> - <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="웹소켓">웹소켓<a href="#웹소켓" class="hash-link" aria-label="웹소켓에 대한 직접 링크" title="웹소켓에 대한 직접 링크">​</a></h3><p>단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜<br> -<!-- -->웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다. </p><p>웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="웹소켓-등장-배경">웹소켓 등장 배경<a href="#웹소켓-등장-배경" class="hash-link" aria-label="웹소켓 등장 배경에 대한 직접 링크" title="웹소켓 등장 배경에 대한 직접 링크">​</a></h3><p>웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.<br> -<!-- -->이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다. </p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_LlT9"><div class="admonitionHeading_tbUL"><span class="admonitionIcon_kALy"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>polling, long polling, streaming</div><div class="admonitionContent_S0QG"><p>Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법</p><ul><li>서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다. </li><li>계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다. </li></ul><p>Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법</p><ul><li>폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.</li></ul><p>Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법</p><ul><li>클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다. </li></ul></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="웹소켓의-동작">웹소켓의 동작<a href="#웹소켓의-동작" class="hash-link" aria-label="웹소켓의 동작에 대한 직접 링크" title="웹소켓의 동작에 대한 직접 링크">​</a></h3><h3 class="anchor anchorWithStickyNavbar_LWe7" id="1-upgrade-요청">1. Upgrade 요청<a href="#1-upgrade-요청" class="hash-link" aria-label="1. Upgrade 요청에 대한 직접 링크" title="1. Upgrade 요청에 대한 직접 링크">​</a></h3><p>WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.<br> + <content type="html"><![CDATA[<h3 id="웹소켓">웹소켓</h3> +<p>단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜<br> +<!-- -->웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.</p> +<p>웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.</p> +<h3 id="웹소켓-등장-배경">웹소켓 등장 배경</h3> +<p>웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.<br> +<!-- -->이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.</p> +<admonition title="polling, long polling, streaming" type="note"><p>Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법</p><ul> +<li>서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.</li> +<li>계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.</li> +</ul><p>Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법</p><ul> +<li>폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.</li> +</ul><p>Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법</p><ul> +<li>클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.</li> +</ul></admonition> +<h3 id="웹소켓의-동작">웹소켓의 동작</h3> +<mermaid value="sequenceDiagram + participant Client + participant Server + Client->>Server: Handshake - Upgrade를 이용한 WebSocket 전환 요청 + Server->>Client: Handshake - HttpStatus 101(Switching Protocols) + + Client->>Server: 양방향 통신 + Server->>Client: + + Client->>Server: 종료 + Server->>Client: "></mermaid> +<h3 id="1-upgrade-요청">1. Upgrade 요청</h3> +<p>WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.<br> <!-- -->이는 HTTP와 같이 80, 443 포트를 사용한다.<br> <!-- -->웹소켓으로 전환하기 위해서는 Upgrade: websocket, Connection: Upgrade 헤더가 필요하다.<br> <!-- -->Sec-WebSocket-Key는 서버에서 Sec-WebSocket-Accept를 계산하여 응답하고 이 값이 예상한 값과 다르면 연결이 수립되지 않는다.<br> <!-- -->Sec-WebSocket-Protocol의 경우 서브프로토콜의 목록으로 서버 측에서는 해당 목록 중 하나를 선택하여 반환해야 한다.<br> -<!-- -->만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다. </p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">GET /chats HTTP/1.1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Host: localhost:8080</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Upgrade: websocket</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Connection: Upgrade</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Sec-WebSocket-Protocol: v10.stomp, v11.stomp</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Sec-WebSocket-Version: 13</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Origin: http://localhost:8080</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="2-switching-protocols">2. Switching Protocols<a href="#2-switching-protocols" class="hash-link" aria-label="2. Switching Protocols에 대한 직접 링크" title="2. Switching Protocols에 대한 직접 링크">​</a></h3><p>서버는 101 Switching Protocols 응답을 반환한다.<br> +<!-- -->만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.</p> +<pre><code>GET /chats HTTP/1.1 +Host: localhost:8080 +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg== +Sec-WebSocket-Protocol: v10.stomp, v11.stomp +Sec-WebSocket-Version: 13 +Origin: http://localhost:8080 +</code></pre> +<h3 id="2-switching-protocols">2. Switching Protocols</h3> +<p>서버는 101 Switching Protocols 응답을 반환한다.<br> <!-- -->Sec-WebSocket-Accept은 Sec-WebSocket-Key 뒤에 <code>258EAFA5-E914-47DA-95CA-C5AB0DC85B11</code>를 붙이고 SHA1로 해싱 후 Base64로 인코딩하여 반환한다.<br> -<!-- -->이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다. </p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">HTTP/1.1 101 Switching Protocols </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Upgrade: websocket</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Connection: Upgrade</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Sec-WebSocket-Protocol: v10.stomp</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="3-통신-후-종료">3. 통신 후 종료<a href="#3-통신-후-종료" class="hash-link" aria-label="3. 통신 후 종료에 대한 직접 링크" title="3. 통신 후 종료에 대한 직접 링크">​</a></h3><p>연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.<br> -<!-- -->연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="참고-자료">참고 자료<a href="#참고-자료" class="hash-link" aria-label="참고 자료에 대한 직접 링크" title="참고 자료에 대한 직접 링크">​</a></h3><p><a href="https://datatracker.ietf.org/doc/html/rfc6455" target="_blank" rel="noopener noreferrer">https://datatracker.ietf.org/doc/html/rfc6455</a><br> -<a href="https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications" target="_blank" rel="noopener noreferrer">https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications</a><br> -<a href="https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers" target="_blank" rel="noopener noreferrer">https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers</a><br> -<a href="https://docs.spring.io/spring-framework/reference/web/websocket.html" target="_blank" rel="noopener noreferrer">https://docs.spring.io/spring-framework/reference/web/websocket.html</a></p>]]></content> +<!-- -->이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.</p> +<pre><code>HTTP/1.1 101 Switching Protocols +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0= +Sec-WebSocket-Protocol: v10.stomp +</code></pre> +<h3 id="3-통신-후-종료">3. 통신 후 종료</h3> +<p>연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.<br> +<!-- -->연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.</p> +<h3 id="참고-자료">참고 자료</h3> +<p><a href="https://datatracker.ietf.org/doc/html/rfc6455">https://datatracker.ietf.org/doc/html/rfc6455</a><br> +<a href="https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications">https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications</a><br> +<a href="https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers">https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers</a><br> +<a href="https://docs.spring.io/spring-framework/reference/web/websocket.html">https://docs.spring.io/spring-framework/reference/web/websocket.html</a></p>]]></content> <category label="WebSocket" term="WebSocket"/> </entry> <entry> @@ -498,27 +2224,355 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <link href="https://greeng00se.github.io/docusaurus"/> <updated>2023-06-18T00:00:00.000Z</updated> <summary type="html"><![CDATA[팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.]]></summary> - <content type="html"><![CDATA[<p>팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다. </p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="설치">설치<a href="#설치" class="hash-link" aria-label="설치에 대한 직접 링크" title="설치에 대한 직접 링크">​</a></h2><p><a href="https://docusaurus.io/docs/installation" target="_blank" rel="noopener noreferrer">공식 홈페이지</a>에 들어가서 최신 버전을 설치한다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">yarn</span><span class="token plain"> create docusaurus</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="배포">배포<a href="#배포" class="hash-link" aria-label="배포에 대한 직접 링크" title="배포에 대한 직접 링크">​</a></h2><p><a href="https://docusaurus.io/docs/next/deployment#deploying-to-github-pages" target="_blank" rel="noopener noreferrer">배포 안내 문서</a><br> + <content type="html"><![CDATA[<p>팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.</p> +<h2 id="설치">설치</h2> +<p><a href="https://docusaurus.io/docs/installation">공식 홈페이지</a>에 들어가서 최신 버전을 설치한다.</p> +<pre><code class="language-bash">yarn create docusaurus +</code></pre> +<h2 id="배포">배포</h2> +<p><a href="https://docusaurus.io/docs/next/deployment#deploying-to-github-pages">배포 안내 문서</a><br> <!-- -->netlify나 vercel 같은 서버리스 플랫폼을 추천하고 있고, 간단하고, 빠른 시간 안에 배포를 할 수 있다.<br> -<!-- -->이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="레포지토리-생성">레포지토리 생성<a href="#레포지토리-생성" class="hash-link" aria-label="레포지토리 생성에 대한 직접 링크" title="레포지토리 생성에 대한 직접 링크">​</a></h3><p>github pages를 이용하려면 <a href="https://github.com/greeng00se/greeng00se.github.io" target="_blank" rel="noopener noreferrer">예시</a>와 같이 <code>username.github.io</code> 형태의 레포지토리를 생성해야 한다.<br> -<!-- -->이때 organization을 사용하는 경우 <code>organization.github.io</code> 형태의 레포지토리를 생성해서 사용한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="설정-파일-수정">설정 파일 수정<a href="#설정-파일-수정" class="hash-link" aria-label="설정 파일 수정에 대한 직접 링크" title="설정 파일 수정에 대한 직접 링크">​</a></h3><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">docusaurus.config</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">module</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">url</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'https://greeng00se.github.io'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">baseUrl</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'/'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">projectName</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'greeng00se.github.io'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">organizationName</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'greeng00se'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">trailingSlash</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="토큰-설정">토큰 설정<a href="#토큰-설정" class="hash-link" aria-label="토큰 설정에 대한 직접 링크" title="토큰 설정에 대한 직접 링크">​</a></h3><p>github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.<br> -<!-- -->이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 <!-- -->[repo, user, workflow]<!-- --> 을 설정했다. </p><p><img loading="lazy" alt="github" src="/assets/images/github-d866f69755a1e17d4f17a262bd30d56d.png" width="1598" height="1670" class="img_ev3q"></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="브랜치-생성">브랜치 생성<a href="#브랜치-생성" class="hash-link" aria-label="브랜치 생성에 대한 직접 링크" title="브랜치 생성에 대한 직접 링크">​</a></h3><p>github에서 gh-pages 브랜치를 하나 생성한다.<br> +<!-- -->이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.</p> +<h3 id="레포지토리-생성">레포지토리 생성</h3> +<p>github pages를 이용하려면 <a href="https://github.com/greeng00se/greeng00se.github.io">예시</a>와 같이 <code>username.github.io</code> 형태의 레포지토리를 생성해야 한다.<br> +<!-- -->이때 organization을 사용하는 경우 <code>organization.github.io</code> 형태의 레포지토리를 생성해서 사용한다.</p> +<h3 id="설정-파일-수정">설정 파일 수정</h3> +<pre><code class="language-js" metastring="title="docusaurus.config"">module.exports = { + // ... + url: 'https://greeng00se.github.io', + baseUrl: '/', + projectName: 'greeng00se.github.io', + organizationName: 'greeng00se', + trailingSlash: false, + // ... +}; +</code></pre> +<h3 id="토큰-설정">토큰 설정</h3> +<p>github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.<br> +<!-- -->이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.</p> +<p><img alt="github" src="https://greeng00se.github.io/assets/images/github-d866f69755a1e17d4f17a262bd30d56d.png" width="1598" height="1670"></p> +<h3 id="브랜치-생성">브랜치 생성</h3> +<p>github에서 gh-pages 브랜치를 하나 생성한다.<br> <!-- -->repository -> settings -> pages -> branch에서 생성한 gh-pages로 브랜치를 변경한다.<br> -<!-- -->설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="워크플로-작성">워크플로 작성<a href="#워크플로-작성" class="hash-link" aria-label="워크플로 작성에 대한 직접 링크" title="워크플로 작성에 대한 직접 링크">​</a></h3><p>Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.<br> -<!-- -->배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다. </p><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">.github/workflows/deploy.yml</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> blog</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">on</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">push</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">branches</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">main</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">jobs</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">deploy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Deploy to GitHub Pages</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">runs-on</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ubuntu</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">latest</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">steps</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">uses</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> actions/checkout@v2</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">uses</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> actions/setup</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">node@v3</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">node-version</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">18</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">cache</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> yarn</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Install dependencies</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">run</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> yarn install </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">frozen</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">lockfile</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Build website</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">run</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> yarn build</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Deploy to GitHub Pages</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">uses</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> peaceiris/actions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">gh</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">pages@v3</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">with</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">github_token</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> $</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> secrets.DEPLOY_TOKEN </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">publish_dir</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> ./build</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">user_name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> github</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">actions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">bot</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">user_email</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 41898282+github</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">actions</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">bot</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain">@users.noreply.github.com</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="댓글-기능">댓글 기능<a href="#댓글-기능" class="hash-link" aria-label="댓글 기능에 대한 직접 링크" title="댓글 기능에 대한 직접 링크">​</a></h2><p>giscus를 이용하여 댓글 기능을 추가한다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="giscus-설정">giscus 설정<a href="#giscus-설정" class="hash-link" aria-label="giscus 설정에 대한 직접 링크" title="giscus 설정에 대한 직접 링크">​</a></h3><ol><li>공개 저장소여야 한다.</li><li>giscus 앱이 설치되어 있어야 한다.</li><li>Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.</li></ol><p>자세한 내용은 <a href="https://giscus.app/ko" target="_blank" rel="noopener noreferrer">giscus</a>를 확인하자.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="docusaurus-설정">docusaurus 설정<a href="#docusaurus-설정" class="hash-link" aria-label="docusaurus 설정에 대한 직접 링크" title="docusaurus 설정에 대한 직접 링크">​</a></h3><p><a href="https://docusaurus.io/ko/docs/next/swizzling" target="_blank" rel="noopener noreferrer">swizzling</a>을 이용하여 컴포넌트를 감싼다.<br> +<!-- -->설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.</p> +<h3 id="워크플로-작성">워크플로 작성</h3> +<p>Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.<br> +<!-- -->배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.</p> +<pre><code class="language-yml" metastring="title=".github/workflows/deploy.yml"">name: blog + +on: + push: + branches: [main] + +jobs: + deploy: + name: Deploy to GitHub Pages + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v3 + with: + node-version: 18 + cache: yarn + + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: Build website + run: yarn build + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.DEPLOY_TOKEN }} + publish_dir: ./build + user_name: github-actions[bot] + user_email: 41898282+github-actions[bot]@users.noreply.github.com +</code></pre> +<h2 id="댓글-기능">댓글 기능</h2> +<p>giscus를 이용하여 댓글 기능을 추가한다.</p> +<h3 id="giscus-설정">giscus 설정</h3> +<ol> +<li>공개 저장소여야 한다.</li> +<li>giscus 앱이 설치되어 있어야 한다.</li> +<li>Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.</li> +</ol> +<p>자세한 내용은 <a href="https://giscus.app/ko">giscus</a>를 확인하자.</p> +<h3 id="docusaurus-설정">docusaurus 설정</h3> +<p><a href="https://docusaurus.io/ko/docs/next/swizzling">swizzling</a>을 이용하여 컴포넌트를 감싼다.<br> <!-- -->기존에 게시물을 giscus가 포함된 리액트 컴포넌트로 감싸는 형태가 된다.<br> -<!-- -->아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">yarn</span><span class="token plain"> run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>명령어를 입력하면 <code>/src/theme/BlogPostItem/index.js</code> 위치에 파일이 생성된다.<br> -<!-- -->파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다. </p><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">/src/theme/BlogPostItem/index.js</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">OriginalBlogPostItem</span><span class="token plain"> </span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"@theme-original/BlogPostItem"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">React</span><span class="token imports punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token imports"> </span><span class="token imports punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token imports"> useEffect</span><span class="token imports punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token imports"> useRef </span><span class="token imports punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"react"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// @ts-expect-error internal code</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token imports"> useColorMode </span><span class="token imports punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"@docusaurus/theme-common"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token imports"> useBlogPost </span><span class="token imports punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">from</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"@docusaurus/theme-common/internal"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> giscusSelector </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"iframe.giscus-frame"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:rgb(80, 250, 123)">BlogPostItem</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token parameter">props</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> colorMode </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">useColorMode</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> isBlogPostPage </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">useBlogPost</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> giscusTheme </span><span class="token operator">=</span><span class="token plain"> colorMode </span><span class="token operator">===</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"dark"</span><span class="token plain"> </span><span class="token operator">?</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"dark"</span><span class="token plain"> </span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"light"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> containerRef </span><span class="token operator">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">useRef</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword null nil" style="color:rgb(189, 147, 249);font-style:italic">null</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">useEffect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token arrow operator">=></span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token operator">!</span><span class="token plain">isBlogPostPage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> giscusEl </span><span class="token operator">=</span><span class="token plain"> containerRef</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">current</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">querySelector</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">giscusSelector</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:rgb(80, 250, 123)">createGiscusEl</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token arrow operator">=></span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> script </span><span class="token operator">=</span><span class="token plain"> </span><span class="token dom variable" style="color:rgb(189, 147, 249);font-style:italic">document</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">createElement</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"script"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">src</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://giscus.app/client.js"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-repo"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"teco-chat/teco-chat.github.io"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-repo-id"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"R_kgDOJZ5j0Q"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-category"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Announcements"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-category-id"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"DIC_kwDOJZ5j0c4CXS_Q"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-mapping"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"pathname"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-strict"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-reactions-enabled"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-emit-metadata"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"0"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-input-position"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"bottom"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-theme"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> giscusTheme</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">setAttribute</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">"data-lang"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ko"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">crossOrigin</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"anonymous"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">async</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> containerRef</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">current</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">appendChild</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">script</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:rgb(80, 250, 123)">postThemeMessage</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token arrow operator">=></span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> message </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">setConfig</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">theme</span><span class="token operator">:</span><span class="token plain"> giscusTheme</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> giscusEl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">contentWindow</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">postMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token literal-property property">giscus</span><span class="token operator">:</span><span class="token plain"> message </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://giscus.app"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> giscusEl </span><span class="token operator">?</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">postThemeMessage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">createGiscusEl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain">giscusTheme</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token operator"><</span><span class="token operator">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token operator"><</span><span class="token maybe-class-name">OriginalBlogPostItem</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token spread operator">...</span><span class="token plain">props</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token operator">/</span><span class="token operator">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">isBlogPostPage </span><span class="token operator">&&</span><span class="token plain"> </span><span class="token operator"><</span><span class="token plain">div ref</span><span class="token operator">=</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain">containerRef</span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"> </span><span class="token operator">/</span><span class="token operator">></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token operator"><</span><span class="token operator">/</span><span class="token operator">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">export</span><span class="token plain"> </span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">default</span><span class="token plain"> </span><span class="token maybe-class-name">BlogPostItem</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="알고리아-설정-및-직접-관리하기">알고리아 설정 및 직접 관리하기<a href="#알고리아-설정-및-직접-관리하기" class="hash-link" aria-label="알고리아 설정 및 직접 관리하기에 대한 직접 링크" title="알고리아 설정 및 직접 관리하기에 대한 직접 링크">​</a></h2><p>알고리아를 사용하면 검색 기능을 추가할 수 있다.<br> -<!-- -->유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다. </p><p>무료 플랜은 직접 인덱스를 수집하는 방법과, <a href="https://docsearch.algolia.com/" target="_blank" rel="noopener noreferrer">docsearch</a>를 이용하는 방법이 있다.<br> +<!-- -->아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.</p> +<pre><code class="language-bash">yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap +</code></pre> +<p>명령어를 입력하면 <code>/src/theme/BlogPostItem/index.js</code> 위치에 파일이 생성된다.<br> +<!-- -->파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.</p> +<pre><code class="language-js" metastring="title="/src/theme/BlogPostItem/index.js"">import OriginalBlogPostItem from "@theme-original/BlogPostItem"; +import React, { useEffect, useRef } from "react"; +// @ts-expect-error internal code +import { useColorMode } from "@docusaurus/theme-common"; +import { useBlogPost } from "@docusaurus/theme-common/internal"; + +const giscusSelector = "iframe.giscus-frame"; + +function BlogPostItem(props) { + const { colorMode } = useColorMode(); + const { isBlogPostPage } = useBlogPost(); + const giscusTheme = colorMode === "dark" ? "dark" : "light"; + const containerRef = useRef(null); + + useEffect(() => { + if (!isBlogPostPage) return; + + const giscusEl = containerRef.current.querySelector(giscusSelector); + + const createGiscusEl = () => { + const script = document.createElement("script"); + + script.src = "https://giscus.app/client.js"; + script.setAttribute("data-repo", "teco-chat/teco-chat.github.io"); + script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q"); + script.setAttribute("data-category", "Announcements"); + script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q"); + script.setAttribute("data-mapping", "pathname"); + script.setAttribute("data-strict", "0"); + script.setAttribute("data-reactions-enabled", "1"); + script.setAttribute("data-emit-metadata", "0"); + script.setAttribute("data-input-position", "bottom"); + script.setAttribute("data-theme", giscusTheme); + script.setAttribute("data-lang", "ko"); + script.crossOrigin = "anonymous"; + script.async = true; + + containerRef.current.appendChild(script); + }; + + const postThemeMessage = () => { + const message = { + setConfig: { + theme: giscusTheme, + } + }; + + giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app"); + }; + + giscusEl ? postThemeMessage() : createGiscusEl(); + }, [giscusTheme]); + + return ( + <> + <OriginalBlogPostItem {...props} /> + {isBlogPostPage && <div ref={containerRef} />} + </> + ); +} + +export default BlogPostItem; +</code></pre> +<h2 id="알고리아-설정-및-직접-관리하기">알고리아 설정 및 직접 관리하기</h2> +<p>알고리아를 사용하면 검색 기능을 추가할 수 있다.<br> +<!-- -->유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.</p> +<p>무료 플랜은 직접 인덱스를 수집하는 방법과, <a href="https://docsearch.algolia.com/">docsearch</a>를 이용하는 방법이 있다.<br> <!-- -->docsearch에 등록한다면 일주일에 한 번씩 크롤링이 진행된다.<br> -<!-- -->이 글에서는 직접 인덱스를 수집하는 방법을 사용한다. </p><ul><li><a href="https://docsearch.algolia.com/docs/legacy/run-your-own/" target="_blank" rel="noopener noreferrer">직접 인덱스 수집</a> </li><li><a href="https://docsearch.algolia.com/docs/legacy/config-file" target="_blank" rel="noopener noreferrer">설정 파일</a></li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="알고리아-애플리케이션-생성-및-키-확인">알고리아 애플리케이션 생성 및 키 확인<a href="#알고리아-애플리케이션-생성-및-키-확인" class="hash-link" aria-label="알고리아 애플리케이션 생성 및 키 확인에 대한 직접 링크" title="알고리아 애플리케이션 생성 및 키 확인에 대한 직접 링크">​</a></h3><p>회원가입을 하고 새로운 애플리케이션 생성을 누른다.<br> -<!-- -->생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다. </p><p><img loading="lazy" alt="algolia" src="/assets/images/algolia-3dbac5c1606f7f0daed9cb27a429db50.png" width="3194" height="1520" class="img_ev3q"></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="키-생성">키 생성<a href="#키-생성" class="hash-link" aria-label="키 생성에 대한 직접 링크" title="키 생성에 대한 직접 링크">​</a></h3><p>직접 인덱스를 수집하기 위한 키를 생성한다.<br> -<!-- -->addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다. </p><p><img loading="lazy" alt="key" src="/assets/images/key-2d0b59e69e9ca0b21c49b76159266e74.png" width="2496" height="832" class="img_ev3q"></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="env-파일-생성">.env 파일 생성<a href="#env-파일-생성" class="hash-link" aria-label=".env 파일 생성에 대한 직접 링크" title=".env 파일 생성에 대한 직접 링크">​</a></h3><p>프로젝트 폴더 상단에 .env 파일을 생성한다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">.env</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">APPLICATION_ID</span><span class="token operator">=</span><span class="token plain">MVIU5UEMOM</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">API_KEY</span><span class="token operator">=</span><span class="token plain">인덱스_생성용_키</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="config-파일-생성">config 파일 생성<a href="#config-파일-생성" class="hash-link" aria-label="config 파일 생성에 대한 직접 링크" title="config 파일 생성에 대한 직접 링크">​</a></h3><p>마찬가지로 최상단에 config.json 파일을 생성한다. -설정 파일은 해당 <a href="https://docsearch.algolia.com/docs/legacy/config-file" target="_blank" rel="noopener noreferrer">링크</a>를 참고한다.<br> -<!-- -->또는 Docusaurus의 <a href="https://github.com/algolia/docsearch-configs/blob/master/configs/docusaurus-2.json" target="_blank" rel="noopener noreferrer">설정 파일</a>을 참고한다.</p><div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">config.json</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"index_name"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"teco"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"start_urls"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://teco-chat.github.io/"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"sitemap_urls"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://teco-chat.github.io/sitemap.xml"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"sitemap_alternate_links"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"stop_urls"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"/tests"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"selectors"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"lvl0"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"selector"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"type"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"xpath"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"global"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"default_value"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Documentation"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"lvl1"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"header h1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"lvl2"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"article h2"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"lvl3"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"article h3"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"lvl4"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"article h4"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"lvl5"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"article h5, article td:first-child"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"lvl6"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"article h6"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"text"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"article p, article li, article td:last-child"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"strip_chars"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">" .,;:#"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"custom_settings"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"separatorsToIndex"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"_"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"attributesForFaceting"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"language"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"version"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"type"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"docusaurus_tag"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"attributesToRetrieve"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"hierarchy"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"content"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"anchor"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"url"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"url_without_anchor"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"type"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"conversation_id"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"833762294"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">"nb_hits"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">46250</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="docker-이용하여-크롤링">docker 이용하여 크롤링<a href="#docker-이용하여-크롤링" class="hash-link" aria-label="docker 이용하여 크롤링에 대한 직접 링크" title="docker 이용하여 크롤링에 대한 직접 링크">​</a></h3><p>docker와 jq가 필요하다.<br> -<!-- -->jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">brew </span><span class="token function" style="color:rgb(80, 250, 123)">install</span><span class="token plain"> jq</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다. </p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">docker</span><span class="token plain"> run -it --env-file</span><span class="token operator">=</span><span class="token plain">.env -e </span><span class="token string" style="color:rgb(255, 121, 198)">"CONFIG=</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">$(</span><span class="token string variable function" style="color:rgb(80, 250, 123);font-style:italic">cat</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> ./config.json </span><span class="token string variable operator" style="color:rgb(189, 147, 249);font-style:italic">|</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> jq -r tostring</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">)</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"> algolia/docsearch-scraper</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="docusaurus-설정-1">docusaurus 설정<a href="#docusaurus-설정-1" class="hash-link" aria-label="docusaurus 설정에 대한 직접 링크" title="docusaurus 설정에 대한 직접 링크">​</a></h3><p>전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다. </p><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">docusaurus.config</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token literal-property property">themeConfig</span><span class="token operator">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">/** @type {import('@docusaurus/preset-classic').ThemeConfig} */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token spread operator">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">algolia</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">appId</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'MVIU5UEMOM'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Application ID</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">apiKey</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'b68f378013817d9a190df88cdde226a0'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Search-Only API Key</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">indexName</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'teco'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// config.json에 설정한 인덱스명</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">contextualSearch</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="부가-설정">부가 설정<a href="#부가-설정" class="hash-link" aria-label="부가 설정에 대한 직접 링크" title="부가 설정에 대한 직접 링크">​</a></h2><h3 class="anchor anchorWithStickyNavbar_LWe7" id="화면-상단-github-icon">화면 상단 Github Icon<a href="#화면-상단-github-icon" class="hash-link" aria-label="화면 상단 Github Icon에 대한 직접 링크" title="화면 상단 Github Icon에 대한 직접 링크">​</a></h3><p>파일 최하단에 아래 css 구문을 추가한다.</p><div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">/src/css/custom.css</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token selector class" style="color:rgb(255, 121, 198)">.header-github-link</span><span class="token selector pseudo-class" style="color:rgb(255, 121, 198)">:hover</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">opacity</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">0.6</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token selector class" style="color:rgb(255, 121, 198)">.header-github-link</span><span class="token selector pseudo-element" style="color:rgb(255, 121, 198)">:before</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">content</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">''</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">width</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">24</span><span class="token unit">px</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">height</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token number">24</span><span class="token unit">px</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">display</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> flex</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">background</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token url function" style="color:rgb(80, 250, 123)">url</span><span class="token url punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token url string url" style="color:rgb(255, 121, 198)">"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E"</span><span class="token url punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> no-repeat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token selector" style="color:rgb(255, 121, 198)">html</span><span class="token selector attribute punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token selector attribute attr-name" style="color:rgb(241, 250, 140)">data-theme</span><span class="token selector attribute operator" style="color:rgb(255, 121, 198)">=</span><span class="token selector attribute attr-value" style="color:rgb(255, 121, 198)">'dark'</span><span class="token selector attribute punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token selector" style="color:rgb(255, 121, 198)"> </span><span class="token selector class" style="color:rgb(255, 121, 198)">.header-github-link</span><span class="token selector pseudo-element" style="color:rgb(255, 121, 198)">:before</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">background</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token url function" style="color:rgb(80, 250, 123)">url</span><span class="token url punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token url string url" style="color:rgb(255, 121, 198)">"data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E"</span><span class="token url punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> no-repeat</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>themeconfig -> navbar에 github link를 설정한다. </p><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">docusaurus.config</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token literal-property property">navbar</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">title</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'HELLO'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">items</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">href</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'https://github.com/greeng00se'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">position</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'right'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">className</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'header-github-link'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string-property property">'aria-label'</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'GitHub repository'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="코드블럭">코드블럭<a href="#코드블럭" class="hash-link" aria-label="코드블럭에 대한 직접 링크" title="코드블럭에 대한 직접 링크">​</a></h3><p>java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.<br> -<!-- -->prism 설정을 아래와 같이 변경해 준다. </p><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">docusaurus.config</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token literal-property property">prism</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">theme</span><span class="token operator">:</span><span class="token plain"> lightCodeTheme</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">darkTheme</span><span class="token operator">:</span><span class="token plain"> darkCodeTheme</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">additionalLanguages</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">'java'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'kotlin'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="mermaid">mermaid<a href="#mermaid" class="hash-link" aria-label="mermaid에 대한 직접 링크" title="mermaid에 대한 직접 링크">​</a></h3><p>mermaid를 사용하려면 <code>@docusaurus/theme-mermaid</code> 를 설치해야 한다.</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">yarn</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">add</span><span class="token plain"> @docusaurus/theme-mermaid</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>설치 후 아래와 같이 설정을 추가한다.</p><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">docusaurus.config</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> config </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token spread operator">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">markdown</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">mermaid</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">themes</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'@docusaurus/theme-mermaid'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>themeConfig에서 mermaid의 테마를 지정할 수 있다. </p><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">docusaurus.config</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token literal-property property">themeConfig</span><span class="token operator">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">/** @type {import('@docusaurus/preset-classic').ThemeConfig} */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token spread operator">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">mermaid</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">theme</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">light</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'neutral'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">dark</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'dark'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="국제화-설정">국제화 설정<a href="#국제화-설정" class="hash-link" aria-label="국제화 설정에 대한 직접 링크" title="국제화 설정에 대한 직접 링크">​</a></h3><p>국제화 설정을 한다면 <code>Older Entries</code> 형태의 설명이 <code>다음 페이지</code> 로 변경된다.<br> -<!-- -->설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다. </p><div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">docusaurus.config</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token literal-property property">i18n</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">defaultLocale</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ko"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token literal-property property">locales</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">"ko"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="블로그-글-author">블로그 글 author<a href="#블로그-글-author" class="hash-link" aria-label="블로그 글 author에 대한 직접 링크" title="블로그 글 author에 대한 직접 링크">​</a></h3><p>팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다. </p><p><img loading="lazy" alt="author" src="/assets/images/author-1bd517bb7763257e2139e1063fd92492.png" width="2362" height="1076" class="img_ev3q"></p><p><code>authors.yml</code> 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다. </p><div class="language-yml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockTitle_Ktv7">/blog/authors.yml</div><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-yml codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token key atrule">herb</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 허브</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">title</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Backend</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//github.com/greeng00se</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">image_url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//github.com/greeng00se.png</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token key atrule">mallang</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">name</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> 말랑</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">title</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> Backend</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//github.com/shin</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">mallang</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token key atrule">image_url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain">//github.com/shin</span><span class="token punctuation" style="color:rgb(248, 248, 242)">-</span><span class="token plain">mallang.png</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다. </p><div class="language-mdx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-mdx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">slug: 1</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">title: Hello World</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">authors: [herb, mallang]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">tags: [hello, docusaurus]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">---</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">첫 번째 문서 내용</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="클립보드에 코드 복사" title="복사" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content> +<!-- -->이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.</p> +<ul> +<li><a href="https://docsearch.algolia.com/docs/legacy/run-your-own/">직접 인덱스 수집</a></li> +<li><a href="https://docsearch.algolia.com/docs/legacy/config-file">설정 파일</a></li> +</ul> +<h3 id="알고리아-애플리케이션-생성-및-키-확인">알고리아 애플리케이션 생성 및 키 확인</h3> +<p>회원가입을 하고 새로운 애플리케이션 생성을 누른다.<br> +<!-- -->생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.</p> +<p><img alt="algolia" src="https://greeng00se.github.io/assets/images/algolia-3dbac5c1606f7f0daed9cb27a429db50.png" width="3194" height="1520"></p> +<h3 id="키-생성">키 생성</h3> +<p>직접 인덱스를 수집하기 위한 키를 생성한다.<br> +<!-- -->addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.</p> +<p><img alt="key" src="https://greeng00se.github.io/assets/images/key-2d0b59e69e9ca0b21c49b76159266e74.png" width="2496" height="832"></p> +<h3 id="env-파일-생성">.env 파일 생성</h3> +<p>프로젝트 폴더 상단에 .env 파일을 생성한다.</p> +<pre><code class="language-bash" metastring="title=".env"">APPLICATION_ID=MVIU5UEMOM +API_KEY=인덱스_생성용_키 +</code></pre> +<h3 id="config-파일-생성">config 파일 생성</h3> +<p>마찬가지로 최상단에 config.json 파일을 생성한다. +설정 파일은 해당 <a href="https://docsearch.algolia.com/docs/legacy/config-file">링크</a>를 참고한다.<br> +<!-- -->또는 Docusaurus의 <a href="https://github.com/algolia/docsearch-configs/blob/master/configs/docusaurus-2.json">설정 파일</a>을 참고한다.</p> +<pre><code class="language-json" metastring="title="config.json"">{ + "index_name": "teco", + "start_urls": [ + "https://teco-chat.github.io/" + ], + "sitemap_urls": [ + "https://teco-chat.github.io/sitemap.xml" + ], + "sitemap_alternate_links": true, + "stop_urls": [ + "/tests" + ], + "selectors": { + "lvl0": { + "selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]", + "type": "xpath", + "global": true, + "default_value": "Documentation" + }, + "lvl1": "header h1", + "lvl2": "article h2", + "lvl3": "article h3", + "lvl4": "article h4", + "lvl5": "article h5, article td:first-child", + "lvl6": "article h6", + "text": "article p, article li, article td:last-child" + }, + "strip_chars": " .,;:#", + "custom_settings": { + "separatorsToIndex": "_", + "attributesForFaceting": [ + "language", + "version", + "type", + "docusaurus_tag" + ], + "attributesToRetrieve": [ + "hierarchy", + "content", + "anchor", + "url", + "url_without_anchor", + "type" + ] + }, + "conversation_id": [ + "833762294" + ], + "nb_hits": 46250 +} +</code></pre> +<h3 id="docker-이용하여-크롤링">docker 이용하여 크롤링</h3> +<p>docker와 jq가 필요하다.<br> +<!-- -->jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.</p> +<pre><code class="language-bash">brew install jq +</code></pre> +<p>다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.</p> +<pre><code class="language-bash">docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper +</code></pre> +<h3 id="docusaurus-설정-1">docusaurus 설정</h3> +<p>전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.</p> +<pre><code class="language-js" metastring="title="docusaurus.config"">themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + ... + algolia: { + appId: 'MVIU5UEMOM', // Application ID + apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key + indexName: 'teco', // config.json에 설정한 인덱스명 + contextualSearch: true, + }, + }) +</code></pre> +<h2 id="부가-설정">부가 설정</h2> +<h3 id="화면-상단-github-icon">화면 상단 Github Icon</h3> +<p>파일 최하단에 아래 css 구문을 추가한다.</p> +<pre><code class="language-css" metastring="title="/src/css/custom.css"">.header-github-link:hover { + opacity: 0.6; +} + +.header-github-link:before { + content: ''; + width: 24px; + height: 24px; + display: flex; + background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") + no-repeat; +} + +html[data-theme='dark'] .header-github-link:before { + background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") + no-repeat; +} +</code></pre> +<p>themeconfig -> navbar에 github link를 설정한다.</p> +<pre><code class="language-js" metastring="title="docusaurus.config"">navbar: { + title: 'HELLO', + items: [ + { + href: 'https://github.com/greeng00se', + position: 'right', + className: 'header-github-link', + 'aria-label': 'GitHub repository', + }, + ], +}, +</code></pre> +<h3 id="코드블럭">코드블럭</h3> +<p>java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.<br> +<!-- -->prism 설정을 아래와 같이 변경해 준다.</p> +<pre><code class="language-js" metastring="title="docusaurus.config"">prism: { + theme: lightCodeTheme, + darkTheme: darkCodeTheme, + additionalLanguages: ['java', 'kotlin'], +} +</code></pre> +<h3 id="mermaid">mermaid</h3> +<p>mermaid를 사용하려면 <code>@docusaurus/theme-mermaid</code> 를 설치해야 한다.</p> +<pre><code class="language-bash">yarn add @docusaurus/theme-mermaid +</code></pre> +<p>설치 후 아래와 같이 설정을 추가한다.</p> +<pre><code class="language-js" metastring="title="docusaurus.config"">const config = { + ... + markdown: { + mermaid: true, + }, + themes: [ + '@docusaurus/theme-mermaid' + ], +}; +</code></pre> +<p>themeConfig에서 mermaid의 테마를 지정할 수 있다.</p> +<pre><code class="language-js" metastring="title="docusaurus.config"">themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + ... + mermaid: { + theme: { + light: 'neutral', + dark: 'dark' + }, + }, + }), +</code></pre> +<h3 id="국제화-설정">국제화 설정</h3> +<p>국제화 설정을 한다면 <code>Older Entries</code> 형태의 설명이 <code>다음 페이지</code> 로 변경된다.<br> +<!-- -->설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.</p> +<pre><code class="language-js" metastring="title="docusaurus.config"">i18n: { + defaultLocale: "ko", + locales: ["ko"], +}, +</code></pre> +<h3 id="블로그-글-author">블로그 글 author</h3> +<p>팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.</p> +<p><img alt="author" src="https://greeng00se.github.io/assets/images/author-1bd517bb7763257e2139e1063fd92492.png" width="2362" height="1076"></p> +<p><code>authors.yml</code> 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.</p> +<pre><code class="language-yml" metastring="title="/blog/authors.yml"">herb: + name: 허브 + title: Backend + url: https://github.com/greeng00se + image_url: https://github.com/greeng00se.png + +mallang: + name: 말랑 + title: Backend + url: https://github.com/shin-mallang + image_url: https://github.com/shin-mallang.png +</code></pre> +<p>블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.</p> +<pre><code class="language-mdx">--- +slug: 1 +title: Hello World +authors: [herb, mallang] +tags: [hello, docusaurus] +--- + +첫 번째 문서 내용 +</code></pre>]]></content> <category label="Documentation" term="Documentation"/> </entry> <entry> @@ -528,847 +2582,28 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 <updated>2023-06-11T00:00:00.000Z</updated> <summary type="html"><![CDATA[23년의 6월이 오고, 레벨 2가 끝났다.]]></summary> <content type="html"><![CDATA[<p>23년의 6월이 오고, 레벨 2가 끝났다.<br> -<!-- -->빠르게 지나가서 조금 아쉽다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="학습">학습<a href="#학습" class="hash-link" aria-label="학습에 대한 직접 링크" title="학습에 대한 직접 링크">​</a></h3><p>회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.<br> +<!-- -->빠르게 지나가서 조금 아쉽다.</p> +<h3 id="학습">학습</h3> +<p>회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.<br> <!-- -->항상 아쉬운 곳은 있기 마련이지만, 잘 학습한 것 같다.<br> -<!-- -->미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다. </p><p>고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.<br> -<!-- -->방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다. </p><p>점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.<br> -<!-- -->필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="수면">수면<a href="#수면" class="hash-link" aria-label="수면에 대한 직접 링크" title="수면에 대한 직접 링크">​</a></h3><p>레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.<br> -<!-- -->앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="협업">협업<a href="#협업" class="hash-link" aria-label="협업에 대한 직접 링크" title="협업에 대한 직접 링크">​</a></h3><p>레벨 2 마지막에 협업 미션이 있었다.<br> +<!-- -->미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.</p> +<p>고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.<br> +<!-- -->방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.</p> +<p>점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.<br> +<!-- -->필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.</p> +<h3 id="수면">수면</h3> +<p>레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.<br> +<!-- -->앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.</p> +<h3 id="협업">협업</h3> +<p>레벨 2 마지막에 협업 미션이 있었다.<br> <!-- -->지금까지는 백엔드 크루들과 페어 프로그래밍을 하면서 협업을 경험했다.<br> -<!-- -->이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다. </p><p>레벨 3 때부터 본격적으로 프로젝트가 시작된다.<br> -<!-- -->팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="레벨-2를-마무리하며">레벨 2를 마무리하며<a href="#레벨-2를-마무리하며" class="hash-link" aria-label="레벨 2를 마무리하며에 대한 직접 링크" title="레벨 2를 마무리하며에 대한 직접 링크">​</a></h3><p>회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. +<!-- -->이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.</p> +<p>레벨 3 때부터 본격적으로 프로젝트가 시작된다.<br> +<!-- -->팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.</p> +<h3 id="레벨-2를-마무리하며">레벨 2를 마무리하며</h3> +<p>회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. 읽고 싶은 책도 읽고, 부족한 부분 채우면서 쉬어야겠다.</p>]]></content> <category label="Woowahan Techcourse" term="Woowahan Techcourse"/> <category label="Retrospective" term="Retrospective"/> </entry> - <entry> - <title type="html"><![CDATA[레벨 2 - 레벨 인터뷰 회고]]> - https://greeng00se.github.io/level2-interview-retrospective - - 2023-06-08T00:00:00.000Z - - 레벨 인터뷰

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
-따라서 레벨 1 레벨 인터뷰 회고는 레벨 1 회고를 작성할 때 끼워넣었다.
-이번에는 범위도 제한되어 있어 어떻게 준비해야 할지 당황했고, 답변에도 부족한 부분이 많았었다.
-기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

API 문서 도구 선택

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
-백엔드 팀원이 함께 의사결정을 했고, 미션 기간이 짧은 만큼 팀 차원에서 비교적 학습하기 쉬운 Swagger를 선택했다.
-추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
-앞으로도 학습 비용은 주요하게 고려해야 할 사항

PUT과 PATCH & 토큰과 세션

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
-토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
-실제로 레벨 2 때 이론적인 학습 시간이 매우 적었고, 집중력도 많이 부족했다.
-앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

그 외 개선할 점

인터뷰할 때 특유의 말버릇을 개선하기
-생각할 시간을 가졌을 때 "다시 말씀드려도 될까요?"라고 말하고 답변을 이어나가기
-기술적으로 깊이가 부족하다고 생각이 많이 들어서 조금 더 깊게 공부하고 정리하기
-이전에 공부했던거 되돌아 보는 시간 가지기

]]>
- - - - - <![CDATA[장바구니 주문 미션 회고]]> - https://greeng00se.github.io/order-retrospective - - 2023-06-04T00:00:00.000Z - -
PR 링크

장바구니 주문 미션

배포 및 협업을 할 수 있는 미션이었다.
-마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

배포

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
-각자 하나의 EC2 인스턴스를 제공받을 수 있었고, 팀 별로 DB를 위한 추가 인스턴스를 제공받았다.
-배포 스크립트를 작성하는 경험을 해볼 수 있었다.
-배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

echo "Start Deploy Script"
REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
PROJECT_NAME=jwp-shopping-order

echo "Change Directory"
cd $REPOSITORY_NAME

echo "Git Pull"
git pull origin step2

echo "Build"
./gradlew bootJar

echo "Copy, Start Server"
mv ./build/libs/$PROJECT_NAME.jar .

PID=$(pgrep -f $PROJECT_NAME)

if [ -n $PID ]; then
kill -9 $PID
sleep 5
fi

nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &

협업

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
-백엔드가 아닌 다른 크루들과 해보는 첫 협업이라 약간 두근거렸다.
-예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

부족했던 부분

여러가지 방법에 대한 장단점을 고려해보기

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
-조금 더 시간을 많이 들여서 장단점을 고려했다면 더 좋은 결과물이 나오지 않았을까?
-앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

새로 배운 부분

expose headers

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
-기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
-이를 expose headers 설정을 통해 해결할 수 있었다.
-nginx 설정에 다음과 같이 추가해 주었다.

add_header 'Access-Control-Expose-Headers' 'Location'

읽기 전용 트랜잭션

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
-이번에 코멘트가 달려서 조금 더 자세히 공부해 보기로 했다.
-Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
-추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

DAO에 @Transactional 적용

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
-Service 계층에 이미 트랜잭션을 보장해 주고 있기에 필요 없지 않을까 생각했었다.
-DAO를 다른 곳에서 사용하더라도 트랜잭션을 보장하기 위해(확장성 고려) @Transactional을 적용하는 것도 괜찮은 것 같다.

]]> - - - - - <![CDATA[[테코챗] 3. 기능 구현]]> - https://greeng00se.github.io/tecochat-retrospective-3 - - 2023-06-01T00:00:00.000Z - - 개요

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
-레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

나의 채팅 확인하고 이어하는 기능

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
-예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

chat1

좋아요와 댓글 기능

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
-누가 좋아요를 눌렀는지, 어떤 채팅이 좋아요를 가장 많이 받았는지 확인할 수 있는 기능을 추가했다.
-또한 댓글 추가 및 삭제 기능도 추가했다.

키워드 추출

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
-해당 부분은 첫 질문에 대한 키워드만 추출하도록 했다.
-백엔드에선 말랑이 이벤트 이용해서 첫 채팅 요청이 이루어지면, 비동기로 키워드를 추출하는 질문을 추가로 날리도록 구현하였다.
-CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

chat2

다른 크루의 채팅 복사해서 이어하는 기능

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
-채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

사용성 고려하기

chat3

위 화면은 회원가입 창이다.
-사실 가장 마음에 드는 부분이고, 회원가입(닉네임만 입력하지만)할 때 익명을 원하는 사람들의 고민을 도와주게 끔 음식, 과일, 과자 등의 요소들을 입력하도록 유도했다! -추가로 GPT의 답변이 오면 자동으로 화면을 스크롤 해주는 것과 같이 사용성을 개선해 보려고 노력했지만 쉽지 않았다.
-제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

향후 계획

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
-크루들이 직접 사용해 주니까 너무 고맙고, 한편으로는 신기하다.
-일단 방학 때 stream/text 관련된 부분 동작되도록 구현해보려고 하고, 그 외의 부분은 조금 더 고민해야될 것 같다.

]]>
- - -
- - <![CDATA[컴포지트 패턴으로 요금 정책 추상화하기]]> - https://greeng00se.github.io/composite - - 2023-05-26T00:00:00.000Z - - 요구사항

지하철 미션에는 다음과 같은 요구사항이 있었다.

  • 거리별 추가 요금 정책
  • 노선별 추가 요금 정책
  • 연령별 요금 할인 정책

인터페이스 사용

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
-요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

public interface FarePolicy {
int calculate(Path path, Passenger passenger, int fare);
}

public class BaseFarePolicy implements FarePolicy { ... }
public class DistanceFarePolicy implements FarePolicy { ... }
public class AgeDiscountFarePolicy implements FarePolicy { ... }

composite1

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
-이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

public class SubwayFarePolicy implements FarePolicy {

private final List<FarePolicy> farePolicies;

public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
this.farePolicies = farePolicies;
}

@Override
public int calculate(final Path path, final Passenger passenger, final int fare) {
int calculatedFare = fare;
for (FarePolicy farePolicy : farePolicies) {
calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
}
return calculatedFare;
}
}

따라서 그림으로 본다면 다음과 같은 구조가 된다.

composite2

정책의 순서

지하철 요구사항은 순서가 중요했다.
-금액의 총합을 구하고, 그 후에 할인 정책이 들어가야했다.
-따라서 자식들의 순서를 관리할 때 주의를 기울여야 했다.
-Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

@Configuration
public class FareConfiguration {

@Bean
public FarePolicy farePolicy() {
return new SubwayFarePolicy(List.of(
new BaseFarePolicy(),
new DistanceFarePolicy(),
new AgeDiscountFarePolicy()
));
}
}

컴포지트 패턴이란?

composite3

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
-사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

컴포지트 패턴의 구성요소

Component

  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • ex) 요금 정책(FarePolicy)

Leaf

  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • ex) 거리 별 요금 정책(DistanceFarePolicy)

Composite

  • 여러 개의 개발 객체를 포함하는 합성 객체
  • ex) 지하철 요금 정책(SubwayFarePolicy)

Client

  • 인터페이스를 사용하는 클라이언트

컴포지트 패턴의 사용과 주요 목표

부분 - 전체의 관계를 표현하고 싶을 때
-Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

패턴 사용시 주의해야할 부분

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
-반복되는 문제를 효율적으로 해결할 수 있지만 패턴에 매몰되서는 안된다.
-패턴을 맹목적으로 사용해서는 안되고, 현재의 요구사항에 따라 패턴을 유동적으로 수정해가면서 적용하는 것이 좋다.
-항상 트레이드오프를 생각하자!

참고 자료

컴포지트 패턴, GoF의 디자인 패턴
-디자인 패턴과 프레임워크, 오브젝트

]]>
- - -
- - <![CDATA[지하철 미션 회고]]> - https://greeng00se.github.io/subway-retrospective - - 2023-05-25T00:00:00.000Z - -
PR 링크

지하철 미션

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
-지하철 미션은 밀리랑 페어를 진행했다.
-간단한 CRUD만 있던 이전 미션들과 달리, 조금 복잡한 도메인 요구사항이 있었다.
-이때 API, 테이블, 도메인 설계를 해야 했는데 어떤 것부터 해야 할지 고민을 많이 했다.
-API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

노선의 구간 추가 및 삭제

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. 변경된 요소만 데이터베이스에 반영하는 방법

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
-추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

부족했던 부분

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
-우아한테크코스를 진행하면서 알아야 하는 게 많아지면서 가끔 조바심을 가질 때가 있는 것 같은데, 조바심을 경계할 필요가 있을 것 같다.
-부족한 부분은 인정하고, 앞으로 나아가야겠다.

새로 학습한 부분

컴포지트 패턴으로 요금 정책 추상화

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
-요금을 더하는 부분과, 할인하는 부분이 있어서 이 둘을 분리할까 생각했지만, 이 정도 크기의 애플리케이션에서는 오히려 분리하지 않고 하나로 합치는 게 더 좋다고 생각했다.
-또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

도메인에 특정 기술의 의존성을 분리

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
-따라서 도메인 패키지 내에는 경로 검색에 대한 인터페이스를 두고, 세부 구현은 도메인 패키지 외부로 분리했다.
-최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

컴포지트 패턴

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

인수 테스트 작성

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
-브라운이 해주신 강의 + 유튜브에 있는 브라운의 강의를 보고 지하철 미션에 인수 테스트를 적용해 보았다.
-메서드, 변수명을 전부 한글로 작성했는데 전체적인 흐름을 알기 편하고 읽기도 좋았다.
-그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

결과는 아래와 같다.

@Nested
public class 노선을_전체_조회할_때 {

@Test
void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
// given
노선_생성_요청("2호선", "초록", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);

노선_생성_요청("9호선", "고동", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);

// when
final var 조회_결과 = 노선_전체_조회_요청();

// then
요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
노선_전체_조회_결과를_확인한다(
조회_결과,
노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
);
}
}

페어에게 배울 부분

의견 조율하기

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
-의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

꼼꼼하게 코딩하기

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
-변수명, 메서드명을 중요하게 생각했고, 좋은 변수명을 잘 짓는 것 같다.
-또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

편한 분위기

전체적으로 페어 할 때 편하게 진행했던 것 같다.
-일정도 그렇고, 페어 진행할 때도 그렇고 큰 문제가 없었던 것 같아서 좋았다.
-나는 과연 다른 사람들에게 편한 사람일까?

]]> - - - - - <![CDATA[중복과 우발적 중복]]> - https://greeng00se.github.io/accidental-duplication - - 2023-05-24T00:00:00.000Z - - 장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.
-요청에 담긴 Body를 통해 전달받은 값을 DTO로 매핑하여 추가와 수정을 했다.

장바구니 미션에서의 상품 추가 및 수정

중복1

클래스명을 제외하고 필드와 검증로직 그 외 모든게 같은 DTO를 보며 중복이라고 생각했다.
-하지만 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-위 경우는 중복일까? 중복이 아닐까?

이 부분에 대해서 다음과 같은 리뷰를 받았다.

ProductSaveRequestProductUpdateRequest가 완전히 동일한데, 재사용할 수 없을까? 라는 리뷰를 남겼었어요. 사실 생성과 수정은 서로 달라질 개연성이 높아서 미리 분리해놓는 게 더 좋은 방법이긴 한데, 그래도 중복은 싫어서 저도 요즘 이런저런 방법들을 시도해보는 중 입니다. 허브는 이 부분에 대해 어떤 생각을 가지고 있을지 궁금하네요 ㅎㅎ

질문에 대해 아래와 같이 답변을 했다.

저장과 수정할 때 필요한 필드값이 동일하여 현재 구조에서는 하나로 사용해도 된다고 생각을 하지만, 말씀해주신대로 요구사항이 변경된다면 달라질 가능성이 높다고 판단하였습니다!

중복과 우발적 중복

로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 거짓된 중복, 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다. -그렇기 때문에 위 상황은 우발적 중복으로 보인다. 그래도 중복을 제거해볼 수 있지 않을까?

하나로 사용하는 건 안좋아보이고, 중복은 제거하고 싶은 마음

지금은 추가, 수정 2가지 경우 밖에 없지만 조금 더 복잡한 요구사항이 주어져서 10가지 경우로 입력을 받으면 어떻게 해야할까?
-서비스 계층에서도 계층의 분리를 위해서 다른 DTO를 사용하고 있다면 20개의 DTO를 만들어야 할까?
-리뷰어가 알려준 의존 역전을 이용한 방법을 통해 이를 해결해보자!

중복 제거 전 코드

현재 코드에서는 아래와 같은 구조로 되어있다.
-Controller와 Service에서 저장, 수정할 때 각각의 DTO를 사용하고 있다. -현재 DTO는 controller, service 패키지 내에 있는 것이 아니라 dto라는 패키지에 위치하고 있다.

├── controller
│   └── ProductController
├── service
│   └── ProductService
├── dto
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest

중복2

인터페이스 작성하기

중복3

서비스 레이어에서 필요로 하는 값들을 인터페이스로 정의한다.
-해당 인터페이스는 서비스에서 사용하기 때문에 service 패키지 내부로 옮겨준다.

├── controller
│   └── ProductController
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public interface ProductSaveRequest {

String getName();

String getImage();

Long getPrice();
}

// ProductService
public Long save(final ProductSaveRequest request) {
final Product product = new Product(request.getName(), request.getImage(), request.getPrice());
return productDao.saveAndGetId(product);
}

구현체 작성하기

중복4

위에서 작성한 인터페이스를 구현하는 클래스를 작성한다.
-요청은 ProductRequest 클래스로 받고, 서비스에 전달할 땐 해당 인터페이스의 명세만 맞추면 문제없이 사용할 수 있다.

├── controller
│   ├── ProductController
│   └── ProductRequest
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {

@NotBlank(message = "이름은 공백일 수 없습니다.")
@Size(min = 1, max = 100, message = "이름은 최소 {min}자 이상, {max}자 이하여야 합니다.")
private final String name;

@NotBlank(message = "이미지는 공백일 수 없습니다.")
private final String image;

@Range(message = "가격은 최소 {min}원 이상, {max}원 이하여야 합니다.")
private final long price;

public ProductRequest(final String name, final String image, final long price) {
this.name = name;
this.image = image;
this.price = price;
}

@Override
public String getName() {
return name;
}

@Override
public String getImage() {
return image;
}

@Override
public long getPrice() {
return price;
}
}

// ProductController
@PostMapping("/products")
public ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {
final Long id = productService.save(request);
return ResponseEntity.created(URI.create("/products/" + id)).build();
}

정리

위와 같이 구현한다면 다음과 같은 장점을 얻을 수 있다.

  1. Service에서 모든 클라이언트 요청에 대한 DTO를 알지 않아도 된다.
  2. 공통적으로 사용하는 DTO를 제외하고 DTO 패키지에 대한 결합도가 낮아지고, 각 레이어의 응집도가 증가한다.
  3. 요청 객체만 다르고 서비스에서 동일한 행위를 수행하는 경우 중복을 제거할 수 있다.

위 방법을 지금 미션에서 바로 적용할까 하다가, 나중에 필요할 때 적용하면 더 좋을 것 같아서 미션에는 적용하지 않았다.
-상황에 맞춰 적재적소에 의존 역전을 이용해보는 것도 좋을 것 같다.

참고 자료

클린 아키텍처 16장 독립성, 로버트 C. 마틴
-https://techblog.woowahan.com/2647/
-https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/

]]>
- -
- - <![CDATA[웹 장바구니 미션 회고]]> - https://greeng00se.github.io/shopping-cart-retrospective - - 2023-05-12T00:00:00.000Z - -
PR 링크

웹 장바구니 미션

장바구니 미션은 블랙캣이랑 진행했다.
-요구사항이 엄청 복잡한 미션은 아니었고, 스프링을 사용하여 기본적인 CRUD를 구현하는 미션이었다.
-2단계에서는 Basic 인증을 통해 자신의 장바구니에만 상품을 담고, 제거할 수 있도록 구현하는 요구사항이 추가되었다.
-Interceptor나 Argument Resolver에 대한 이해도가 높지 않았는데, 이번 미션을 통해 조금 더 알아간 느낌이다.
-이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

새로 학습한 부분

DTO 우발적 중복

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

dto1

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
-따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

dto2

Interceptor에서 인증한 값 재사용

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
-일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
-웨지는 email에 index를 걸어두고 dao 재조회를 사용할 것이라고 했다.
-재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

페어에게 배울 부분

기록

블랙캣은 기록을 굉장히 잘 하는 크루였다.
-노션에 페어를 진행하면서 했던 내용 + 고민했던 부분 + 회고를 꼼꼼하게 기록해서 공유해 주었다.
-추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

의견 일치시키기

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
-따라서 적당히 타협을 봐서 의견을 빠르게 수용해 데드라인을 맞추는 것도 중요하다고 생각한다.
-블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

]]> - - - - - <![CDATA[웹 자동차 미션 회고]]> - https://greeng00se.github.io/web-racing-car-retrospective - - 2023-05-02T00:00:00.000Z - -
PR 링크

웹 자동차 미션

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
-웹 자동차 미션에서는 비버와 페어가 매칭되었다.
-레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
-첫 미션이라 그런지 특별한 부분은 없었고, 최대한 깔끔하게 작성하려고 노력했다.
-난이도 높은 미션이 아니었지만 리뷰어인 라빈에게 칭찬을 많이 받아서 기분이 좋았다.
-라빈 감사합니다!

부족했던 부분

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
-미션이 다소 여유롭다고 느껴져서, 시간에 대한 부분도 잘 관리하지 못한 것 같다.
-미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
-도전적이지 않거나 시간이 부족하지 않으면 집중을 잘 못하는 것 같다.
-머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

새로 학습한 부분

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@Transactional
@AutoConfigureMockMvc
@SpringBootTest
public class RacingGameIntegrationTest {

페어에게 배울 부분

비버의 성격
-비버가 성격이 좋아서 편하게 페어를 할 수 있었다.
-미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

미션에 집중하는 부분
-내가 미션에 잘 집중하지 못했는데도 같이 페어를 잘 진행한 것 같아서 좋았다.
-비버가 미션에 잘 집중해서 그렇지 않았나 생각했다.
-근육맨 비버라 그런지 체력이 좋아서 그런가?
-중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

학습에 대한 열정
-추가적으로 알고 싶은 부분을 따로 학습하는 열정이 좋다고 생각했다.
-비버와 스프링에 대해 알아가는 시간을 많이 가진 부분이 매우 좋았다.
-나도 5월부터 조금 더 화이팅 해야겠다.

]]> - - - - - <![CDATA[[테코챗] 2. 배포]]> - https://greeng00se.github.io/tecochat-retrospective-2 - - 2023-05-01T00:00:00.000Z - - 프론트엔트

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
-추가로 채팅을 이어나갈 수 있게 하는 기능도 추가했다.
-자잘하게 신경 쓸 부분이 많아서, 프론트엔드 하는 사람들이 대단하다고 생각되었다.
-여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

백엔드

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
-말랑이 한 부분이 너무 많아서 내가 못 따라가는 것 같다.
-나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

Http Request Header

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
-말랑이 한글은 안된다고 말해줘서 Base64로 인코딩하고, 백엔드에서 디코딩 하여 사용하기로 했다.
-아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

const encodedName = () => {
const uriComponent = unescape(encodeURIComponent(name.value));
return btoa(uriComponent);
};

Elastic Beanstalk

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
-Elastic Beanstalk를 사용하면 인프라에 대해 잘 알지 못해도 애플리케이션을 빠르게 배포하고 관리할 수 있다.
-모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

Elastic Beanstalk RDS 설정 후 분리

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
-RDS 분리 시 Beanstalk에 기본적으로 설정되어 있는 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD와 같은 환경 변수가 같이 제거된다.
-추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

Elastic Beanstalk nginx 설정

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

Jenkins

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
-작년에 확인했을 땐 2022년 12월 31일까지 EC2 ARM 기반 t4g.small이 무료였는데, 다시 들어가 보니 2023년까지 12월 31일까지 t4g.small을 무료로 사용할 수 있었다.
-t4g.small은 램이 2G인데, 예전에는 부족하지 않았다고 생각했는데 Java 17을 써서 그런가 빌드 할 때 램이 많이 부족한 것 같아서 Swap 메모리 2기가를 추가로 설정했다.
-추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

test {
maxHeapSize = "1024m"
}

Jenkins Blue Ocean

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
-시각화도 잘 되어있고, 설정도 편리한 것 같다.
-오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

참고 자료

Elastic Beanstalk, AWS
-EC2 AWS Graviton, AWS
-Default Memory Settings, AWS

]]>
- - -
- - <![CDATA[Jenkins로 CI/CD 설정]]> - https://greeng00se.github.io/jenkins - - 2023-04-30T00:00:00.000Z - - 설정 환경

소프트웨어 이미지: Amazon Linux 2023 AMI
-아키텍쳐: ARM
-인스턴스 유형: t4g.small
-환경 구성이 완료된 Elastic Beanstalk
-단일 Spring Boot 프로젝트가 존재하는 Github Repository

[EC2 CLI] Swap 메모리 설정

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
-아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

# fallocate 이용하여 스왑 파일 생성
sudo fallocate -l 2G /swapfile

# 권한 설정
sudo chmod 600 /swapfile

# 파일을 Swap 포맷으로 변경 후 시스템에 등록
sudo mkswap /swapfile
sudo swapon /swapfile

# Swap 메모리 부팅시 자동으로 마운트하도록 적용
# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
sudo vim /etc/fstab

[EC2 CLI] jenkins 설치

sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install java-17-amazon-corretto-devel
sudo yum install jenkins
sudo systemctl daemon-reload

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

[EC2 CLI] Jenkins 시작

sudo systemctl enable jenkins
sudo systemctl start jenkins

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

[EC2 CLI] nginx & git 설치

sudo yum install nginx
sudo systemctl enable nginx
sudo systemctl start nginx

sudo yum install git

nginx와 코드를 불러올 때 사용할 git을 설치한다.

[EC2 CLI] nginx 리버스 프록시 설정

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

upstream jenkins {
keepalive 32; # keepalive connections
server 127.0.0.1:8080; # jenkins ip and port
}

# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 80; # Listen on port 80 for IPv4 requests

server_name jenkins.example.com; # replace 'jenkins.example.com' with your server domain name

# this is the jenkins web root directory
# (mentioned in the output of "systemctl cat jenkins")
root /var/run/jenkins/war/;

access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;

# pass through headers from Jenkins that Nginx considers invalid
ignore_invalid_headers off;

location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
# rewrite all static files into requests to the root
# E.g /static/12345678/css/something.css will become /css/something.css
rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
}

location /userContent {
# have nginx handle all the static requests to userContent folder
# note : This is the $JENKINS_HOME dir
root /var/lib/jenkins/;
if (!-f $request_filename){
# this file does not exist, might be a directory or a /**view** url
rewrite (.*) /$1 last;
break;
}
sendfile on;
}

location / {
sendfile off;
proxy_pass http://jenkins;
proxy_redirect default;
proxy_http_version 1.1;

# Required for Jenkins websocket agents
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_max_temp_file_size 0;

#this is the maximum upload size
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffering off;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection ""; # Clear for keepalive
}

}

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
-/etc/nginx/conf.d 아래 default.conf 파일을 하나 생성하고 위와 같이 입력하고 저장한다.
-nginx의 기본 설정 파일에 존재하는 include /etc/nginx/conf.d/*.conf; 설정 때문에 .conf 로 끝난다면 설정이 적용된다.
-설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

[Jenkins] Jenkins 접속

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
-EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

jenkins-start

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
-비밀번호를 입력하면 플러그인 설정 창이 나올텐데 install suggested plugins을 클릭하여 Jenkins가 추천하는 기본 플러그인들을 설치하면 된다.
-플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

[Jenkins] Jenkins Blue Ocean 설치

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
-IAM에서 다음과 같이 역할을 하나 새로 생성한다.

  1. 엔터티 선택

aws-iam1

  1. 권한 추가

aws-iam2

  1. 이름 지정, 검토 및 생성

aws-iam3

  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정

aws-iam4

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단

aws-s3

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

repo, user:email 권한이 있는 토큰이 필요하다.

[Jenkins] 블루 오션 시작

jenkins-blue-ocean1

블루 오션 열기로 파이프라인을 생성한다.
-토큰 입력 → 조직 선택 → CI/CD 설정할 Repository 선택을 하면 파이프라인 창으로 넘어간다.
-Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

jenkins-blue-ocean2

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

jenkins-blue-ocean3

[Github Repsoitory] Jenkinsfile 설정

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

pipeline {
agent any
stages {
stage('build and test') {
steps {
sh '/gradlew clean build'
}
}
stage('zip') {
steps {
sh 'mv ./build/libs/woowachat.jar .'
sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
}
}
stage('upload') {
steps {
sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
}
}
stage('deploy') {
steps {
sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
}
}
}
}

[Github] Webhooks 설정

github-hook

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

참고 자료

Install Jenkins - CentOS, Jenkins
-Nginx Reverse Proxy Configuration, Jenkins
-Amazon Corretto 17 JDK Install, AWS
-Amazon Linux 2023 packages, AWS

]]>
- - -
- - <![CDATA[[테코챗] 1. 프로토타입 만들기]]> - https://greeng00se.github.io/tecochat-retrospective-1 - - 2023-04-22T00:00:00.000Z - - 4월 21일 금요일

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
-레벨 3, 4에서 나만의 강점을 가지고 싶어 고민을 많이 했다.
-단순히 스프링을 깊게 공부하는 건 효율이 많이 떨어진다고 생각했다.
-글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
-Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
-프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

이건 못참지

도메인 구입 성공?

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
-마치 어릴 때 했던 게임 닉네임 정하는 것처럼 시간이 오래 걸렸다.
-dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

말랑의 DM

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
-우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
-추가로 도메인에 관한 이야기를 하다가 woowachat이 언급되었고, namecheap에서 chat 도메인을 사용한 woowa.chat으로 구매했다.
-이후에 teco.chat으로 변경했다!

도메인 설정 및 배포

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
-나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

GPT

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
-일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

Sonarcloud

정적 코드 분석 도구로 Sonarcloud를 적용했다.
-Sonarcloud는 SonarQube의 SaaS 버전이고 사용이 매우 편하다.
-예전에 Sonarcloud를 사용할 땐 버튼 몇 번 누르면 적용할 수 있었는데, 이번에는 바로 github action을 사용하라는 안내 페이지로 이동했다.
-Sonarcloud가 자체적으로 github repository에 push 하면 정적 분석을 해주는 기능을 원했고, Administration -> Analysis Method에 Automatic Analysis를 설정하니 되었다.
-너무 꽁꽁 숨겨져있네

Tiptap

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
-Tiptap은 Headless WYSIWYG 에디터로 사용자 정의 기능에 특화되어있는 에디터다.
-아직 Tiptap이 제공하는 모든 기능을 자연스럽게 사용하지는 못하지만 CodeBlockLowlight 플러그인을 사용하여 코드 블록을 예쁘게 출력할 수 있었다.
-api 반환값 그대로 tiptap의 content에 설정했더니 코드 블록이 설정되지 않아서 백 틱 3개를 <pre><code>로 변환했다.
-추가로 띄어쓰기도 적용되지 않아서 \n<br>태그로 변환했다.
-변환하는 로직은 GPT의 도움을 많이 받았다.

const replaceCodeFences = (input: String) => {
const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
return input
.replace(codeFencesRegex, (match, p1, p2) => {
const languageClass = p1 ? ` class="language-${p1}"` : "";
return `<pre><code${languageClass}>${p2}</code></pre>`;
})
.replace(/\n/g, "<br>");
};

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

tecochat

폰트 및 favicon 적용

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
-추가로 favicon도 간단하게 적용해서 만족스러웠다.

]]>
- - -
- - <![CDATA[[책] 상자 밖에 있는 사람]]> - https://greeng00se.github.io/book-leadership-and-self-deception - - 2023-04-08T00:00:00.000Z - - 책 정보

상자 밖에 있는 사람
-아빈저연구소

자기기만과 자기배반

책에서는 자기기만과 자기배반에 대한 내용을 다룬다.

  • 자기기만: 자신의 문제를 인정하지 않는 것
  • 자기배반: 다른 사람을 위해 무언가 해야만 한다는 생각을 반하는 행위

자기배반을 한다면 자기기만 상태가 된다.
-자기기만 상태에 빠지는 것을 책에서는 상자 안에 들어간다고 표현한다.

읽고 나서

최근에 읽은 책 중 가장 마음이 불편했다.
-그렇기에 더더욱 나에게 필요한 내용이 담겨있었다.

살면서 많은 선택의 순간이 존재했고, 그 순간마다 자기배반을 택하는 경우가 많았다.
-작게는 집안일을 해야 하는데 몸이 조금 힘들다고 하지 않거나
-크게는 잘못을 인정해야 하는 상황에서 그러지 않은 경우가 있었다.
-이런 상황이 반복되어 결국 상자 안에 나 자신을 가두는 경우가 많았다.

더 나은 삶을 위해 내가 상자 안에 있는지 지속적으로 확인하고, 상자 밖으로 나가려는 연습을 해야겠다.
-넓은 시선을 가지고, 항상 내가 틀릴 수 있다는 것을 생각하고 살아가자.

밑줄 친 문장들

우리의 생각은 지식보다 작다.
-우리의 지식은 사랑보다 작다.
-우리의 사랑은 존재보다 작다.
-그리고 우리가 생각하는 나는 실제의 나보다 그만큼 작다.
-R. D. 랭
-p.19

우리가 외적으로 어떤 행동을 하든지 간에, 사람들은 우리 마음에서 그들을 어떻게 대하고 있는지에 따라 주로 반응합니다.
-우리가 사람들에 대해 어떻게 느끼게 되는지는 우리가 상자 안에 있는지 혹은 상자 밖에 있는지에 따라 달라지게 됩니다.
-p.66

비난은 감정에 속하고 낙관은 의지에 속한다.
-인간은 감정보다 더 큰 존재이다.
-알랭, 탁닛한
-p.103

우리가 자신에게만 집중하고 있는 한, 혼자서 일하는 것 이상의 창조적인 결과나 협력을 이끌어 낸다는 것은 불가능합니다.
-오늘날 경제 환경에서는 혼자서는 일의 결과를 탁월하게 만들어 내기가 어렵습니다.
-내가 중심이어야 된다는 폐쇄적인 사고는 함께 일하는 사람들의 열정을 불러오지 못합니다.
-p.175

솔직함은 우리의 문제를 해결하는 열쇠입니다.
-그것은 자신의 행동과 관련된 사람에 대해 기꺼이 사과를 하는 것입니다.
-그것만이 실타래처럼 엉킨 관계의 문제를 해결할 수 있기 때문이죠.
-p.188

누군가를 나와 같이 동일한 가치를 지닌 한 인간으로 생각해서 그 사람을 위해 내가 상자 밖에 계속 머무르고 싶은 열망이 생길 때, 나는 이미 그 사람에 대해 상자 밖에 있다.
-p.214

대부분의 사람들이 관계 기술을 가지고 그들이 겪고 있는 문제를 바로잡으려고 하는 노력이 결실을 얻지 못하는 것은 결코 그러한 기술 부족 때문에 생기는 것이 아닙니다.
-그것들은 자기배반 때문에 생겨납니다.
-p.224

우리는 함께 일하고 우리와 함께 살아가는 사람이 진정으로 누구인지 알지 못합니다.
-우리가 그들과 진정으로 함께 소통하기 전까지는 우리는 그들의 가치를 잘 모릅니다.
-우리의 위대함이란 다른 사람들의 위대한 점을 발견해 주는 것에 있습니다.
-p.280

]]>
- -
- - <![CDATA[InnoDB 스토리지 엔진의 잠금]]> - https://greeng00se.github.io/innodb-lock - - 2023-04-07T00:00:00.000Z - - InnoDB 스토리지 엔진의 잠금

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
-보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
-InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

낙관적 동시성 제어(OCC, Optimistic concurrency control)

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

비관적 동시성 제어(PCC, Pessimistic Concurrency Control)

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
-일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

Shared & Exclusive Locks

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

공유 잠금(S, shared lock)

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
-다른 트랜잭션에서 읽기가 가능하지만, 쓰기는 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

배타적 잠금(X, exclusive lock)

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
-락을 건 트랜잭션만이 해당 데이터에 접근 가능하다. 다른 트랜잭션의 경우 읽기, 쓰기가 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

Intention Locks

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
-테이블에 있는 로우에 대해서 나중에 요청되는 것이 어떤 형태의 잠금인지 가리키기 위해 사용된다.
-기본적으로 로우 단위 잠금을 수행하기 전에 인텐션 잠금을 먼저 획득한다.
-인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

인텐션 공유 잠금(IS, intention shared lock)

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

인텐션 배타적 잠금(IX, intention exclusive lock)

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

잠금간의 호환성

XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

Record Locks

레코드 자체만을 잠그는 락이다.
-InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

Gap Locks

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

Next-Key Locks

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
-REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

AUTO-INC Locks

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
-InnoDB 는 내부적으로 AUTO-INC 락이라고 하는 테이블 수준의 잠금을 사용한다.
-트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

잠금 예시

-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
-- Record Locks: 10에 대해 락이 걸린다.
SELECT * FROM table_name where id = 10 for update;

-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
SELECT * FROM table_name where id > 100 for update;

-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Optimistic and Pessimistic record locking, IBM
-MySQL Innodb Locks, cecil1018
-MySQL 8.0 InnoDB Locks, MySQL
-Locks Set by Different SQL Statements in InnoDB, MySQL

]]>
- - - -
- - <![CDATA[MySQL 엔진의 잠금]]> - https://greeng00se.github.io/mysql-lock - - 2023-04-06T00:00:00.000Z - - MySQL 엔진의 잠금

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
-MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

글로벌 락(Global lock)

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

  • 영향을 미치는 범위는 해당 서버 전체이다.
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
-데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 일관된 백업을 받아야할 때 사용한다.
-InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

-- GLOBAL LOCK
FLUSH TABLES WITH READ LOCK;
-- UNLOCK
UNLOCK TABLES;

-- BACKUP LOCK
LOCK INSTANCE FOR BACKUP;
-- UNLOCK
UNLOCK INSTANCE;
MyISAM

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
-트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

테이블 락(Table lock)

개별 테이블 단위로 설정되는 잠금이다.
-명시적 또는 묵시적으로 특정 테이블의 락을 획득할 수 있다.
-묵시적 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.
-InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

-- TABLE LOCK
LOCK TABLES table_name [ READ | WRITE ]

-- UNLOCK
UNLOCK TABLES;

네임드 락(Named lock)

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
-여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
SELECT GET_LOCK('aGVyYg==', 1);

-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
SELECT IS_FREE_LOCK('aGVyYg==');

-- 문자열에 대한 잠금을 해제한다.
SELECT RELEASE_LOCK('aGVyYg==');

-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.

-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
SELECT RELEASE_ALL_LOCKS();

메타데이터 락(Metadata lock)

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
-명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
-보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
RENAME TABLE rank TO rank_backup, rank_new TO rank;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-MySQL의 User Level Lock를 활용한다면?, gywndi
-Locking Functions, MySQL 5.7 Reference
-Locking Functions, MySQL 8.0 Reference

]]>
- - - -
- - <![CDATA[트랜잭션과 격리수준]]> - https://greeng00se.github.io/transaction-and-isolation - - 2023-04-05T00:00:00.000Z - - 트랜잭션(Transaction)

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
-트랜잭션은 작업의 완전성과 데이터의 정합성을 보장해 준다.
-논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

트랜잭션의 속성(ACID)

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
-일관성(Consistency): 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지해야 한다.
-격리성(Isolation): 각각의 트랜잭션은 독립적이라 서로에게 영향을 주지 않아야 한다.
-지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

트랜잭션 주의사항

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
-구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

왜 네트워크 작업이 있을 때 트랜잭션에서 배제해야 할까? 🤔

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
-네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)

격리 수준(Isolation level)

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
-격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

READ UNCOMMITTED

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
-더티 리드 현상이 발생하기 때문에 정합성의 문제가 많은 격리 수준이다.
-MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

READ COMMITTED

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
-오라클 DBMS에서 기본으로 사용되는 격리 수준이다.
-REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

REPEATABLE READ

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
-MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준이다.
-MVCC를 이용해 언두(Undo) 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
-동일한 결과를 보장하는 방법은 다음과 같다.

  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

갭 랍(Gap lock)과 넥스트 키 락(Next-key lock)

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

MVCC(Multi Version Concurrency Control)

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

SERIALIZABLE

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
-트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 접근할 수 없고 단순한 읽기 작업도 공유 잠금(읽기 잠금)을 획득해야만 한다.
-InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

격리 수준에 따른 부정합 문제

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX

더티 리드(Dirty read)

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
-트랜잭션 격리 수준이 READ UNCOMMITTED일 때 발생한다.
-예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

반복 가능하지 않은 조회(Non-repeatable read)

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
-예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

팬텀 리드(Phantom read, Phantom row)

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
-예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Isolation Level, MySQL

]]>
- - - -
- - <![CDATA[테스트 대역]]> - https://greeng00se.github.io/test-double - - 2023-04-04T00:00:00.000Z - - 테스트 대역이란?

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
-Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
-외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

테스트 대역의 타입 계층 구조

더미(Dummy)

가장 단순하고, 원시적인 유형의 테스트 대역이다.
-기본적으로 아무 일도 하지 않는 구현체로 인스턴스화가 필요한 경우 사용한다.
-만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

스텁(Stub)

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
-이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

스파이(Spy)

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
-예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

목, 모의 객체(Mock)

목은 더미, 스텁, 스파이를 포함한다.
-호출 시 사전에 정의된 결과를 반환하고, 예상치 못한 호출이 있을 경우 예외를 던질 수 있다.
-또한 호출에 대한 검증을 할 수 있다.

가짜(Fake)

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
-예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

DOC(depended-on component)

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
-테스트 더블은 DOC와 동일한 API를 제공해야 한다.

상호작용에 따른 목과 스텁 구분

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
-목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
SUT(system under test)

테스트 대상 시스템
-테스트를 하려는 대상

참고 자료

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
-단위 테스트 - 5장 목과 테스트 취약성, 블라디미르 코리코프
-테스트 주도 개발 시작하기 - 7장 대역, 최범균
-테스트 더블, Martin Fowler
-테스트 관련 용어 정리, Johngrib
-Test Double, Gerard Meszaros

]]>
- - -
- - <![CDATA[자바 클래스 파일 구조]]> - https://greeng00se.github.io/java-class-file - - 2023-04-03T00:00:00.000Z - - 클래스 파일

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
-컴파일된 클래스파일은 어떤 구조로 되어있을까?

클래스 파일의 데이터 형식

8비트 바이트의 스트림으로 구성된다.
-16비트 및 32비트의 데이터는 각각 2개, 4개의 연속된 8비트를 읽어서 구성된다.
-멀티바이트의 경우 항상 big endian 순서로 저장된다.

u1 → unsigned 1byte
-u2 → unsigned 2byte
-u4 → unsigned 4byte

클래스 파일 구조

ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

매직넘버

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
-보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

클래스 파일 포맷 버전

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

class file format major versions

Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61

상수 풀

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
-클래스명, 상수명, 상수 값, 필드명, 메서드명과 같은 값들이 존재한다.
-JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

액세스 플래그

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
-예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

Class access and property modifiers

Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.

this_class

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
-해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

super_class

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
-아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

interface, field, method

각각의 개수와, 정보에 대한 값이 들어있다.
-interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

attributes

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
-정해진 클래스 파일의 구조를 확장하는 역할을 한다.

클래스 파일 확인하면서 사용한 툴

IntelliJ plugin - BinEd
-IntelliJ plugin - jclasslib Bytecode Viewer

참고 자료

2장 JVM 이야기, 자바 최적화
-Class file in Java, File Format
-java se11 Class 파일 형식, Oracle
-java se17 Class 파일 형식, Oracle

]]>
- - -
- - <![CDATA[커스텀 JdbcTemplate 만들기]]> - https://greeng00se.github.io/custom-jdbc-template - - 2023-04-02T00:00:00.000Z - - 체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
-이 때 JDBC를 사용할 때 데이터베이스의 커넥션을 얻고, try-with-resource를 사용하는 부분이 반복되었다.
-템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

기존 코드

public class User {
private final int id;
private final String name;

public User(final int id, final String name) {
this.id = id;
this.name = name;
}

public int getId() {
return id;
}

public String getName() {
return name;
}
}

SELECT, DELETE 중복 제거

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
-변하는 부분: SQL Query, 매개변수

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
executeUpdate(query, userId);
}

private void executeUpdate(final String query, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
preparedStatement.executeUpdate();
} catch (final SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
-이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

콜백(Callback)

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
-자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
-executeQuery로 조회한 값은 ResultSet 안에 들어가있다.
-이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

@FunctionalInterface
public interface RowMapper {
User mapRow(final ResultSet resultSet) throws SQLException;
}

조회 분리하기 - 2. 단건 조회

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
-아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

public User findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return queryForSingleResult(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
}, userId);
}

private User queryForSingleResult(
final String query,
final RowMapper rowMapper,
final Object... parameters
) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
if (resultSet.next()) {
return rowMapper.mapRow(resultSet);
}
return null;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

조회 분리하기 - 3. 다건 조회

단건 조회와 유사하다.

public List<User> findAll() {
final String query = "SELECT * FROM user";
return query(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
});
}

private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
final List<User> result = new ArrayList<>();
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
return result;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

제네릭 사용하기

위의 코드는 User를 조회할 때만 사용할 수 있다.
-아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

@FunctionalInterface
public interface RowMapper<T> {
T mapRow(final ResultSet resultSet) throws SQLException;
}

private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
-또한 null을 반환하기 보단 Optional로 감싸서 반환하도록 변경한다.
-최종적으로 아래와 같은 코드가 완성된다.

public class UserDao {
private final RowMapper<User> rowMapper = resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
};
private final JdbcTemplate jdbcTemplate;

public UserDao(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
jdbcTemplate.executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
jdbcTemplate.executeUpdate(query, userId);
}

public Optional<User> findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
}

public List<User> findAll() {
final String query = "SELECT * FROM user";
return jdbcTemplate.query(query, rowMapper);
}
}
]]>
- - -
- - <![CDATA[우아한테크코스 레벨 1 회고]]> - https://greeng00se.github.io/woowacourse-level1-retrospective - - 2023-04-01T00:00:00.000Z - - 레벨 1이 끝났다.
-우테코를 시작하기 전 내가 정해두었던 목표 이상으로 달성했기 때문에 매우 만족스럽다.
-혼자 독학을 할 땐 이 방향으로 공부하는 게 맞는지 계속 반추하다 결국 무기력함에 빠져들었다.
-하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

Keep

나만의 루틴 만들기

스스로가 외부의 영향을 많이 받는다고 생각한다.
-최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
-소화능력이 부족하기 때문에 점심은 도시락(그래봤자 계란2개)을 준비하고
-항상 똑같은 컨디션을 유지하기 위해 항상 6시에 집에 간다.
-이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

크루들과 친하게 지내기

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
-하다 보니 더 많은 크루들의 닉네임을 외운 것 같다.
-앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

글쓰기

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
-매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
-사실 겉으로 드러내지 않았지만 꼭 받아보고 싶었다.
-글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

코드 리뷰 스터디

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
-과연 도움이 될까 생각했지만 결과적으로는 코드 리뷰를 하면서 성장을 많이 한 것 같다.
-투자한 시간 대비 가성비가 좋은 활동이었다.
-누누가 스터디장인데 과연 꾸준히 이어나가려나?

레벨 인터뷰

인터뷰할 때 많이 떨지 않아서 좋았다.
-남들 앞에서 이야기를 하거나, 면접을 보면 항상 엄청 떨어서 걱정했는데
-기술적인 질문을 받았을 때 떨지 않고 잘 대답할 수 있었다.
-우아한테크코스 생활을 하면서 다른 크루가 질문했을 때, 최대한 이해하기 쉽게 설명하려고 했던 경험이 도움이 된 것 같다.
-이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • 두괄식 표현
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • 설명할 수 있을만큼 시간 충분히 가지기
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • 끝맺는 부분 연습하기(자신감 있게)
  • 기술적인 집착가지기
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기

Problem

페어프로그래밍

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
-페어는 매번 바뀌고, 미션의 복잡도도 증가하기 때문인 것 같다.
-소통 능력, 시간관리가 부족했고, 만족스럽지 않았다.
-하지만 페어를 진행하고, 회고를 하다 보니 나만의 노하우가 쌓이는 느낌이다.
-레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

집중하는 시간⏱️ 부족

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
-이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

Try

허브🌿와의 티타임?

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
-예를 들어 잡담방에 저와 커피챗 하실 분 :) 하면서 올릴 수 있을 것 같다.
-참여하는 사람이 있을지, 안 좋게 보는 게 아닐지 걱정되지만 그래도 재밌을 것 같다.
-저랑 허브티 한잔 하실래요?

기술적인 부분

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
-시간의 여유가 될 때 책을 조금씩 읽어야겠다.
-블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

레벨 1을 마무리하며

시간이 빠르게 흘러갔다.
-타인에게 좋은 영향을 주기위해, 방학동안 나를 챙기는 시간을 가져야겠다.
-또한 함께 일하고 싶은 사람을 목표로 앞으로도 꾸준히 의식적 노력을 해야겠다.

]]>
- - -
- - <![CDATA[체스 미션 회고]]> - https://greeng00se.github.io/chess-retrospective - - 2023-03-31T00:00:00.000Z - -
PR 링크

체스

체스 미션에는 가비와 페어가 매칭되었다!
-체스는 이전 미션들보다 훨씬 복잡한 도메인이었다.
-하지만 가비와 나는 체스 도메인이 익숙해서 더 편한 마음으로 시작할 수 있었다.
-미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
-최종적으로 결정한 부분은 다음과 같다.

각 기물의 이동 가능여부
-Rank와 File은 각각 위치값을 가지고 있고, 값의 차이를 이용해서 각 기물의 이동 가능 여부를 계산했다.
-직선 → Rank와 File 차이 중 하나가 0이어야 한다.
-대각선 → Rank와 File 차이의 절대값이 같아야 한다. ex) abs(-2) == abs(2)
-나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

도착 칸의 기물 여부
-아군 → 이동이 불가능하다.
-적군 → 이동이 가능하다. 적군을 잡는다.

중간에 기물 존재 여부
-이동 경로에 기물이 존재하면 안된다.

데이터베이스 사용
-체스 미션은 특별하게 데이터베이스와 연결하는 부분이 있었다.
-체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

  • 기물 전체를 저장하는 방법
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
-기물 전체를 저장하지 않은 이유는 다음과 같다.

  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
-보드저장: 초기상태에서 32개의 Insert 쿼리(기물의 위치) + 기물 이동 시 움직임 변경(잡히는 경우 2개의 쿼리)
-기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

추가로 기보저장이 구현도 더욱 간단하다. 👍

부가적인 부분

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

  • 누누의 도움으로 ConnectionPool 구현
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

부족했던 부분

꼼꼼하게 코드를 작성하지 못한 부분
-DB 관련 부분을 꼼꼼하게 코딩을 하지 못했다.
-도메인 로직에만 집중하다보니 정적 중요한 DB의 코드의 예외처리, 빈 값을 반환 하는 부분을 꼼꼼하게 처리하지 못했다.
-하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

시간에 대한 부담감
-초반에는 여유롭지만 제출 마감에 가까워질 수록 사람이 급해지는 것 같다.
-다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

새로 학습한 부분

DAO 중복 제거

프롤로그에 을 작성했다.
-DAO를 작성하는데 try-catch-resources와 여러 코드가 중복되서 제거하고싶었다.
-템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

페어에게 배울 부분

페어 생각하기
-가비는 누구보다 페어를 생각하고, 배려해주는 페어였다.
-중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

미션 몰입하기
-최근에 미션에 잘 몰입하지 못했다.
-가비는 페어를 진행할 때 미션에 대한 몰입도가 매우 좋았다.
-집에가서도 체스 이동에 대한 로직을 어떻게 구현할 지 생각한 뒤 꼼꼼해서 정리해서 나에게 보내주었다.
-덕분에 나도 가비의 생각을 알 수 있어서 미션을 진행하는데 가속도가 붙은 것 같다.
-또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

솔직함
-먼저 회고하자고 말 걸어줘서 정말 고마웠다고 표현해주는 부분
-모르는게 있으면 솔직하게 말해주는 부분
-나의 의견을 정리하지 못한 상태로 전달할 때 이해가 안되었다고 정확히 전달해주는 부분
-솔직함은 페어할 때 중요한 부분인 것 같다.

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

]]> - - - - - <![CDATA[일반적인 책임 할당을 위한 패턴]]> - https://greeng00se.github.io/grasp - - 2023-03-30T00:00:00.000Z - - GRASP(General Responsibility Assignment Software Pattern)

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

각 패턴마다 Solution과 Problem로 구성되어 있다.

정보 전문가 패턴(Information Expert)

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

필요한 정보를 가진 객체들로 책임이 분산된다.

창조자 패턴(Creator)

Q: 누가 객체 A를 생성하는가?

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A 객체를 긴밀하게 사용한다.
  • B가 A 객체의 초기값을 가지고 있다.

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

낮은 결합도 패턴(Low Coupling)

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

결합도(Coupling) -객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

  • 오브젝트 p.17

결합도를 낮춘다면 다음과 같은 이점이 있다.

  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • 재사용이 편리해진다.
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)

높은 응집도 패턴(High Cohesion)

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

응집도(Cohesion) -연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

  • 오브젝트 p.26

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • 유지보수가 쉬워진다.
  • 낮은 결합도 또한 지원한다.
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.

컨트롤러 패턴(Controller)

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

어떤 서브시스템이 존재한다고 가정할 때

  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.

다형성 패턴(Polymorphism)

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

변경 보호 패턴(Protected Variations)

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

간접 참조 패턴(Indirection)

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

순수한 가공물 패턴(Pure Fabrication)

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.

참고 자료

오브젝트 5장. 책임 할당하기, 조영호

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

GRASP, 한빛 네트워크

]]>
- - -
- - <![CDATA[블랙잭 미션 회고]]> - https://greeng00se.github.io/blackjack-retrospective - - 2023-03-14T00:00:00.000Z - -
PR 링크

사다리 타기

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
-이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

2단계에서는 2가지 방법으로 구현해봤다.

  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법

Position 기준으로 사다리 게임을 진행하는 방법

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
-구현하고 나니 다른 클래스들이 Position에 대한 의존도가 너무 높은 것 같았다.
-또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

public LadderGameResult play() {
final Map<Player, Item> result = new LinkedHashMap<>();
// 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
for (Position position : Position.range(players.count())) {
final Position resultPosition = ladder.play(position);
result.put(players.get(position), items.get(resultPosition));
}
return new LadderGameResult(result);
}

Player에게 Ladder를 전달하여 게임을 진행하는 방법

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
-이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

public LadderGameResult play() {
// 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
final Map<Player, Position> playResult = players.play(ladder);

final Map<Player, Item> result = new LinkedHashMap<>();
for (Player player : playResult.keySet()) {
result.put(player, toItem(playResult.get(player)));
}
return new LadderGameResult(result);
}

부족했던 부분

유비쿼터스 언어에 시간을 들이기
-유비쿼터스 언어를 정하는데 시간을 조금 더 들여야겠다고 생각했다.
-사다리 타기의 실행 결과를 Item으로 짓다니.. 뭔가 만족스럽지 않다.
-이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

페어와 조금 더 친해지기
-첫날은 페어와 친해지는 시간을 조금 더 가져야겠다고 생각했다.
-우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

README를 조금 더 꼼꼼하게
-이상하게 코딩에 집중하면 README를 업데이트하면서 같이 커밋 하는 걸 항상 까먹는다.
-다음 미션에는 조금 더 신경 써야겠다.

좋은 질문을 생각하기
-첫 PR때 리뷰어에게 질문을 남기지 못했다.
-리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

PR 후에도 꼼꼼하게 확인하기
-분명 알고 있는 부분이지만, 놓친 부분이 많은 것 같았다.
-PR 하기 전에도 계속 확인을 했지만, 아무래도 IntelliJ에서 보니 코드에 익숙해져서 그런지 변경해야 할 부분이 잘 안보였다.
-github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

적극적으로 나의 의견을 말하기
-의견을 적극적으로 내는 부분에 대해서 페어의 의견이 괜찮다고 생각하면 수용 후 개선을 하는 방향으로 진행을 했었는데, 조금 더 개선할 수 있는 방향이 있다면 나도 적극적으로 의견을 말해야겠다고 생각이 든다.
-나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

새로 학습한 부분

객체의 생성 책임
-Players가 Position을 생성하고 Player의 생성자에 넣어주었다. 하지만 이 부분에 대해서 생성 책임에 관련된 코멘트가 달렸다. -시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A를 긴밀하게 사용한다.
  • B가 A의 초깃값을 가지고 있다.

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

패키지 분리 기준
-패키지 분리에 대한 나만의 기준이 아직 명확하지 않아 질문이 들어와도 명확하게 답변을 하지 못했다.
-마지막 제출 전에 도메인 패키지 내부를 분리해 봤는데, 기준이 명확하지 않았기 때문에 좋지 않은 선택이었던 것 같다. -현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
-Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(0~19)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
-이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0~19의 값이 보장되어 있다고 생각할 것이기 때문이다.
-따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

페어에게 배울 부분

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
-이번에 페어 할 때 컨디션 관리를 제대로 못해서 많이 미안했다. 다음에는 최상의 컨디션으로 페어를 준비해 봐야겠다.
-그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
-또한 페어 진행이 느린 것 같다고 말해줘서 안정적으로 시간 안에 미션을 완료할 수 있었다.
-페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
-웃는 것만으로도 사람이 밝아 보여서 너무 좋은 것 같다!

]]> - - - - - <![CDATA[자동차 경주 미션 회고]]> - https://greeng00se.github.io/racing-car-retrospective - - 2023-02-14T00:00:00.000Z - -
PR 링크

자동차 경주

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
-우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
-시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
-mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
-리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

부족했던 부분

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
-객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
-내가 좋아하는 주제, 관심가는 주제인 프로그래밍에 대한 이야기를 할 땐 말이 많아진다.
-다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

새로 학습한 부분

Assertions extracting

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
-이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

@Test
void extracting() {
final Cars cars = new Cars(List.of("car1", "car2"));

assertThat(cars.getCars())
.extracting(Car::getName)
.containsExactly("car1", "car2");
}

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

제어할 수 없는 부분에 대한 테스트

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
-이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

단순 위임을 하는 메서드에 대한 테스트

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
-호출 횟수를 검증하는 것보다 결과에 대한 테스트하는 것이 좋다.
-단순히 위임만 하는 테스트의 경우 결과를 검증한다면 테스트가 중복되지 않을까 생각했었다.
-따라서 중복된 테스트를 줄이기 위해 내부의 메서드를 호출하는지 검증하는 방법도 있다는 것을 알게 되었지만
-안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

테스트를 위한 getter 사용

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
-필요의 경우 생성해서 사용할 수 있지만, 기존에 있는 메서드들을 활용해보는 것이 더 좋은 방법이다.
-이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

페어에게 배울 부분

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
-생각을 정리한 후 자신의 의견을 명료하게 전달해주었다.
-그렇기 때문에 지식을 효율적으로 습득한다.
-난 생각을 잘 정리하지 않은 채로 내버려 둔 얕은 지식이 많은 것 같다. (이런 것도 아는 것이라고 할 수 있을까?)
-앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

개발에 열정을 가진 게 느껴진다.
-나도 개발을 좋아하지만, 최근에는 의지가 약해졌었다.
-열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
-칭찬은 고래도 춤추게 하던가?
-그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
-이건 바로 배울 수 없지만.
-나도 같이 일할 때 편한 사람, 같이 일하고 싶은 사람이 되기 위해 깊이 고민해봐야겠다.

]]> - - - - - <![CDATA[Parameterized Tests]]> - https://greeng00se.github.io/parameterized-tests - - 2023-02-12T00:00:00.000Z - - 테스트를 작성하다보면 매개변수에 따라 반복이 되는 테스트들이 생긴다.
-이 때 @ParameterizedTest를 사용하면 단일 테스트를 매개변수를 사용하여 여러 번 반복할 수 있다.

Argument Sources

@ParameterizedTest를 사용하려면 최소 하나 이상의 Source 애노테이션이 필요하다.
-JUnit이 제공하는 다양한 Source가 있기 때문에, 테스트에 맞춰 다양하게 사용할 수 있다.

Value Source

값을 이용하여 제공하는 형태로, 다음과 같은 타입의 값을 매개변수로 제공할 수 있다.

  • short, int, long, float, double
  • byte, char, boolean, String, Class
@ParameterizedTest
@ValueSource(ints = {1, 100, Integer.MAX_VALUE})
void valueTest(final int value) {
Assertions.assertThat(value).isPositive();
}

Null & Empty Source

null 값, 빈 값을 제공한다.
-Empty Source의 경우 다음과 같은 타입에 한해 매개변수로 제공할 수 있다.

  • String
  • java.util.List, java.util.Set, java.util.Map
  • primitive arrays — ex) int[]
  • object arrays — ex) String[]
@ParameterizedTest
@NullAndEmptySource
void nullAndEmptyTest(final String value) {
Assertions.assertThat(value).isNullOrEmpty();
}

Enum Source

EnumSource를 이용하여 Enum 또한 매개변수로 제공할 수 있다.

enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

@ParameterizedTest
@EnumSource(Day.class)
void enumTest(final Day day) {
assertThat(day).isInstanceOf(Day.class);
}

다음과 같이 mode 값을 이용하여 특징 Enum을 제외하거나, 포함시킬 수 있다. (default: Mode.Include)

@ParameterizedTest
@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)
void enumTest(final Day day) {
// MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
assertThat(day).isInstanceOf(Day.class);
}

CSV Source

csv 형식의 값을 이용하여 매개변수를 제공한다.
-구분자의 기본값은 쉼표(,)로 구분자를 변경하고 싶을 땐 delimeter 값을 따로 전달하여 사용할 수 있다. -개인적으로 2개 정도의 값을 매개변수로 전달하는 경우 CsvSource를 사용한다.

@ParameterizedTest
@CsvSource({"1,1", "2,4", "3,9", "4,16"})
void csvTest(final int number, final int result) {
assertThat(number * number).isEqualTo(result);
}

Method Source

복잡한 타입의 값을 전달할 때 사용한다.
-메서드명을 입력하여 매개변수를 제공하는 메서드를 지정할 수 있다.
-메서드명을 따로 입력하지 않으면 테스트명과 동일한 static 메서드가 지정된다.

@ParameterizedTest
@MethodSource
void methodTest(final List<Integer> numbers, final int count) {
assertThat(numbers).hasSize(count);
}

private static Stream<Arguments> methodTest() {
return Stream.of(
Arguments.of(List.of(1), 1),
Arguments.of(List.of(1, 2), 2),
Arguments.of(List.of(1, 2, 3), 3)
);
}

ETC.

위에서 언급한 방법 이외에도 다양한 방법으로 매개변수를 제공할 수 있다.

  • CSV 파일을 이용한 CsvFileSource
  • ArgumentsProvider 구현한 클래스를 이용하는 ArgumentsSource

참고 자료

]]>
- -
- - <![CDATA[IntelliJ 설정]]> - https://greeng00se.github.io/intellij-settings - - 2023-01-30T00:00:00.000Z - - Import 자동 적용

Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly

auto-import

저장시 동작

Prefrences > Tools > Actions on Save

actions-on-save

Reformat Code: Code Reformmating

Optimize imports: 사용하지 않는 Import 제거

Rearrange: Code Style > Arrangement 설정 기반 코드 재정렬

메소드 추출, 변수 추출시 final 적용

Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier

final-modifier

]]>
- -
- - <![CDATA[Kotlin에서 null을 다루는 방법]]> - https://greeng00se.github.io/kotlin-null - - 2023-01-16T00:00:00.000Z - - nullable 타입

코틀린은 NullPointerException 예외를 최대한 발생시키지 않기 위해 타입 시스템이 설계되어 있다.
-이는 실행 시점이 아닌 컴파일 시 미리 오류가 발생할 가능성이 있는 부분을 미리 감지하여 NPE 발생의 가능성을 줄여준다.

코틀린의 경우 nullable 타입을 다음과 같이 표현한다.

val number: Int?

타입 뒤에 ?를 붙여 해당 값이 null이 될 수 있다는 것을 의미한다.
-만약 ?를 붙이지 않을 때 null을 받는 경우 컴파일 시 오류가 발생한다.

?. Safe Calls 연산자

자바에서 NPE를 발생시키지 않기 위해 null을 처리하는 가장 간단한 방법으로는 분기를 사용하는 방법이 있다.

코틀린은 안전한 호출 연산자인 ?. 연산자를 지원한다.
-따라서 참조 값이 null이 아닐 경우에만 메서드 호출을 할 수 있다.
-참조 값이 null인 경우 메서드 호출이 무시되고, null을 반환한다.

public String repeat(String word) {
if (word == null) {
return null;
}
return word.repeat(2);
}

?: 엘비스 연산자

참조하려는 값이 null일 경우 기본 값을 반환하고 싶을 때는 어떻게 해야 할까?
-코틀린은 null이 아닌 경우 기본 값을 지정할 때 사용할 수 있는 엘비스 연산자를 지원한다.

public String stringSafe(String word) {
if (word == null) {
return "";
}
return word;
}

코틀린에서는 throw도 식이기 때문에 엘비스 연산자를 이용하여 예외를 던질 수 있다.
-예를 들어 사용자 정보가 있는 저장소에 찾는 사용자가 없는 경우 아래와 같이 사용할 수 있다.

userRepository.findByName(name) ?: throw IllegalArgumentException()

!! 널 아님 단언 연산자

!! 연산자를 이용한다면 강제로 어떤 값이든 non-nullable 타입으로 변경할 수 있다.
-하지만 null인 값에 사용한다면 NPE가 발생하게 된다.
-일반적인 경우에는 !! 연산자를 사용하는 것은 위험하다.
-사용하기 쉽지만, 리스크가 크고 혹시나 해당 값이 추후에는 null이 될 수 있기 때문에 지양해야 된다고 생각한다.

val length: Int = word!!.length

as? 안전한 캐스팅

타입 변환을 할 때 지정한 타입으로 변경할 수 없다면 ClassCastException이 발생한다.
-코틀린에서는 as 뒤에 ?를 붙여 안전하게 타입 변환을 할 수 있다.
-따라서 미리 변환 가능한 타입인지 확인하지 않고, 안전하게 타입을 변환 할 수 있다.

타입 변환이 불가능 할 경우 예외를 발생시키지 않고 null을 반환한다.

val value: Int? = something as? Int

List에서의 null 처리

List에는 null이 아닌 값만 반환하는 filterNotNull 유틸리티 메서드를 제공한다.

val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")
val foods = foodsWithNull.filterNotNull()

참고 자료

]]>
- -
- - <![CDATA[JSR-310]]> - https://greeng00se.github.io/jsr-310 - - 2023-01-08T00:00:00.000Z - - 이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
-ISO-8601을 기반으로 작성
-설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

ISO-8601

날짜와 시간에 관련된 데이터를 다루는 국제 표준

LocalDate, LocalTime, LocalDateTime

날짜와 시간을 표현하는 클래스

Instant

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
-기계의 관점에서 시간 표현

Duration, Period

간격을 표현하는 클래스

TemporalAdjusters

복잡한 날짜 조정이 필요할 때 사용
-필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}

DateTimeFormatter

날짜와 시간 포맷 클래스
-특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

ZoneId, ZoneOffset

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
-ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

Instant instant = Instant.now();
LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

참고 자료

]]>
- - -
- - <![CDATA[[책] 객체지향의 사실과 오해]]> - https://greeng00se.github.io/the-essence-of-object-orientation - - 2023-01-07T00:00:00.000Z - - 책 정보

객체지향의 사실과 오해
-조영호

읽고 나서

조영호님의 오브젝트를 읽고 나서 다시 한 번 읽어보았다.
-아직 이해가 안되는 부분이 많지만, 그래도 항상 새로움을 느낀다.
-더할 나위 없이 휼륭한 객체지향 책이고, 조금 더 공부하고 다시 읽어봐야될 것 같다.

커피 전문점, 지하철 노선도, 이상한 나라의 엘리스를 예시로 든 설명이 너무 좋았고
-좋은 내용을 담고 있지만 그렇다고 너무 무겁지 않아 가볍게 읽기도 좋은 것 같다.

책임의 자율성을 강조하는 이유 p.173

협력을 단순하게 만든다.

  • 의도를 명확하게 표현 → 협력의 복잡함 저하
  • 책임의 추상화

외부와 내부를 명확하게 분리한다.

  • 요청하는 객체가 몰라도 되는 부분이 캡슐화됨으로 인터페이스와 구현의 분리

책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

  • 변경의 파급효과를 객체 내부로 캡슐화 → 메시지를 보내는 객체와의 결합도 저하

협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

  • 유연한 설계 → 재사용성 증가

객체의 역할을 이해하기 쉬워진다.

  • 응집도를 높은 상태로 유지

밑줄 친 문장들

객체지향의 목표는 실세계를 모방하는 것이 아니다. -오히려 새로운 세계를 창조하는 것이다. -소프트웨어 개발자의 역할은 단순히 실세계를 소프트웨어 안으로 옮겨 담는 것이 아니라 고객과 사용자를 만족시킬 수 있는 신세계를 창조하는 것이다. -p.21

과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. -이에 반해 객체지향에서는 데이터와 프로세스를 객체라는 하나의 틀 안에 함께 묶어 놓음으로써 객체의 자율성을 보장한다. -자율적인 객체로 구성된 공동체는 유지 보수가 쉽고 재사용이 용이한 시스템을 구축할 수 있는 가능성을 제시한다. -p.33

객체지향의 본질

시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. -p.35

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. -객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다. -p.38

객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행위’다. -클래스는 타입을 구현하기 위해 프로그래밍 언어에서 제공하는 구현 메커니즘이라는 사실을 기억하라. -p.105

책임 주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. -이 과정을 흔히 What/Who 사이클이라고 한다. -’어떤 행위(What)’를 수행할 것인지 결정한 후 ‘누가(who)’ 그 행위를 수행할 것인지 결정해야 한다. -여기서 ‘어떤 행위’가 바로 메시지다. -p.158

]]>
- -
- - <![CDATA[2022년 회고]]> - https://greeng00se.github.io/2022-retrospective - - 2023-01-02T00:00:00.000Z - - 적당한 전환점, 2022년을 돌아보며

전역

약 1년 6개월간의 공군 정보보호병 생활을 마치고 전역을 했다.
-조기 전역 때문에 2021년 12월에 나왔지만, 실제 전역 날짜는 2022년이니 회고에 적어도 상관없겠지.

조금 더 미래에 대한 생각을 해볼걸 그랬다.
-전역을 했지만 뭐 하나 제대로 할 줄 아는 것도 없으니 넓은 바닷속에 덩그러니 놓아진 기분이 괜히 들었었다.
-일찍 생각을 정리하여 방향을 잡지 못했기에 아쉬움이 많이 남았다.

자바

전역을 하고 진로를 고민하다 향로님의 자바 공화국 포스팅을 읽고 나서 자바 공부를 시작했다.
-유명한 인프런의 김영한님의 스프링 강의도 있고, 좋은 자바 개발 서적이 많아서 독학하기로 결정했다.
-하다 보니 자바와 스프링을 공부하면서 “왜 진작하지 않았지”라는 생각도 많이 들었다.
-양질의 자료도 많았기 때문에, 예전에 노드로 개발했을 때 풀지 못했던 답답함을 많이 해소했던 것 같다.

23년에는 조금 더 깊게 자바를 공부해볼 생각이다.
-언어를 하나 깊게 공부하는 건 많은 도움이 되는 것 같다.

스터디

김영한님의 강의를 거의 다 들었을 때쯤, 항상 강의에서 언급되는 토비의 스프링을 읽어보고 싶어졌고
-혼자 공부하기에는 동기부여도 부족했기 때문에 스터디를 시작했다.
-다른 사람에게 설명을 해야 했기 때문에 더욱 꼼꼼하게 공부를 할 수 있어서 좋았지만 나에게는 내용이 꽤나 어려워서 시간을 많이 소비했다.
-같이 스터디하시는 분과 7개월 동안 스터디를 꾸준히 이어나가 총 3권의 책을 읽을 수 있었다.

우아한 테크코스

군 복무 중일 때 지원했다 떨어진 우아한 테크코스를 다시 지원했다.
-이번 연도에 취업을 하는 게 목표였지만 내가 가지고 있는 특별한 무기가 없다는 걸 깨달았다.
-적지 않은 시간을 투자해 준비를 했고, 감사하게도 이번에는 최종 합격을 했다.

난 사람들과 소통하고, 협업하는 능력이 부족하다고 생각을 많이 했다.
-우아한 테크코스를 통해 그 빈 부분을 채우도록 노력해야겠다.

2023년에는

마음의 여유가 없었던 2022년이었던 것 같다.
-하고 싶은 건 많지만, 이번에는 여유를 가지고 할 수 있는 것에 최선을 다해야겠다.

]]>
- -
- - <![CDATA[[책] 글, 우리도 잘 쓸 수 있습니다.]]> - https://greeng00se.github.io/book-writer - - 2023-01-01T00:00:00.000Z - - 책 정보

글, 우리도 잘 쓸 수 있습니다.
-박솔미

읽고 나서

저자의 경험과 함께 글쓰기에 대한 가벼운 조언이 담겨있어 가볍게 읽기 좋았다.
-글을 잘 작성해 보고 싶을 때 적용해 볼 수 있는 정보가 많아서 도움이 되었다.

우아한 테크코스의 프리코스를 진행할 때 후기를 작성하고 나면 항상 글이 딱딱하다는 느낌을 받았다.
-다른 지원자들의 읽기 편하고, 밝은 느낌을 주는 글을 보면 부러운 마음을 가지기도 했다.
-이 책을 읽었으니 2023년에는 조금 더 글을 잘 적어보려고 한다.

밑줄 친 문장들

문장이 심심하고 지루하다면 -내용을 일목요연하게 정리했고, 글의 의도도 삐뚤지 않고, 단어도 적절한 것으로 골랐는데… 그런데도 어딘가가 심심하고 지루하다면? 축축 처지고 따분하다면? 말꼬리를 모조리 ‘~다’로 통일한 건 아닌지 점검해 보세요.

말꼬리를 잘 갖고 놀아야 합니다. 문장의 마지막 글자를 매번 다르게 고쳐쓰는 것만으로도 글에 활기를 더할 수 있죠. 때론 문장을 다 마치지 않고, 단어로만 끝맺는 것도 방법. 문장과 문장 사이에 쉼표가 들어서며 글 전체에 활기가 돌게 돼요. 문장의 길이도 다채로워지는 덕분에 덤으로 얻게 되는 것도 있습니다. 바로, 글의 리듬.

이전 문장에서 끝난 글자로, 다음 문장을 끝맺지 않기. 한두 문단마다 단어 수준의 아주 짧은 문장 배치하기.

글의 진짜 이유, 글의 진짜 목적, 글의 진짜 대상을 찾으려고 애썼습니다. 지금처럼 틀을 떠올린다거나, 눈치를 본다거나, 정치적인 셈도 하지 않았어요.

제목은 짧게, 보기 쉽게, 읽기 쉽게, 발음이 비슷하게, 순서를 바꿔서

글을 마지막으로 다듬을 때, 노래에 가까워질 방법은 없을지 고민해봅니다. 감히 가 닿을 수 없는 목표이겠지만, 할 수 있는 최소한의 리듬이라도 붙여주고 싶어요.

여는 말과 마지막 말에 작정하고 마음을 담는 연습을 해봅시다. 글의 어느 구석이라도 뻔한 글자는 남기지 않겠노라 다짐하며 써보는 겁니다. 나만이 가진 유일한 메시지에 집중하면서요. 그럼 생각이 달라지고, 고르는 단어도 달라지고, 남긴 문장도 달라져요. 결국에는 글을 쓴 사람인 나 자신도 남달라질 겁니다.

맞춤법은 중요합니다. 하지만 맞춤법보다 더 중요한 건 거기에 담긴 마음입니다. 내 마음을 글에 담아 실어 보내기 전, 맞춤법을 점검하는 이유 역시 그겁니다. 오직 내 마음이 남에게 읽히는 동안 방해가 되지 않기를 바라기 때문이죠. 내가 쓴 글도, 남이 쓴 글도. 언제나 그 안에 담긴 마음이 먼저입니다.

글을 쓴다고 글이 완성되는 게 아니에요. 글과 닮은 모습으로 살 때, 글은 비로소 완성됩니다.

]]>
- -
\ No newline at end of file diff --git a/blackjack-retrospective.html b/blackjack-retrospective.html index 6241af5ba..2aada443b 100644 --- a/blackjack-retrospective.html +++ b/blackjack-retrospective.html @@ -2,8 +2,8 @@ - -블랙잭 미션 회고 | GG + +블랙잭 미션 회고 | GG @@ -12,44 +12,60 @@ - - - + + + -
-

블랙잭 미션 회고

· 약 6분

블랙잭

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
-이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
-후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
-"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
-중간 중간 회고를 하고, 나의 소프트스킬을 높히는게 답일까?
-부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
-터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

부족했던 부분

페어 신경쓰기
+

블랙잭 미션 회고

· 약 6분

1단계: https://github.com/woowacourse/java-blackjack/pull/427
+2단계: https://github.com/woowacourse/java-blackjack/pull/537

+

블랙잭

+

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
+이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

+

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
+후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

+

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
+"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

+

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
+중간 중간 회고를 하고, 나의 소프트스킬을 높히는게 답일까?
+부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

+

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
+터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

+

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

+

부족했던 부분

+

페어 신경쓰기
이번 페어할 때 적극적으로 의견을 내보도록 했다. 그렇기에 너무 의견을 강하게 밀어붙인 느낌이 들어서 미안했다.
후추가 압박을 느꼈을 수도 있을 것 같다는 생각이 든다.
-중간 중간 작은 회고를 진행해보는 것이 좋을까?

체력 관리
+중간 중간 작은 회고를 진행해보는 것이 좋을까?

+

체력 관리
요즘 잘 못먹는 것 같다.
-앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

중간 중간 돌아보기
+앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

+

중간 중간 돌아보기
이번 미션과 관련된 내용은 아니지만 우테코를 잘 활용 하고 있는지 생각을 해봐야겠다.
-내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

새로 학습한 부분

상태 패턴
+내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

+

새로 학습한 부분

+

상태 패턴
객체의 내부 상태에 따라 스스로 행동을 변경하도록 하는 패턴으로 if/else/switch와 같은 조건문을 효과적으로 제거할 수 있다.
블랙잭 미션을 진행하면서 상태 패턴에 대한 부분을 처음 적용해보았다.
-처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

일관성, 가독성, 추상화
+처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

+

일관성, 가독성, 추상화
이번 리뷰어는 검프🍫 였다!
-검프의 리뷰는 간결함에 관련된 내용이 많았다.
+검프의 리뷰는 간결함에 관련된 내용이 많았다.
일관성이 있는 코드, 가독성이 좋은 코드, 추상화가 잘 되어있는 코드
읽기 좋고, 간결한 방향으로 코드를 작성하는 방법을 배운 것 같다.
-코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

페어에게 배울 부분

생각 정리
+코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

+

페어에게 배울 부분

+

생각 정리
중간 중간 현재 상황에 대해 그림을 그리거나, 글을 적으면서 정리한다.
페어와 동일한 부분을 이해하고 있는지 확인한다.
진행하는데 매우 도움이 되었던 것 같다.
-나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

가감없이 의견을 말해주는 부분
+나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

+

가감없이 의견을 말해주는 부분
진행 상황에 대한 부분, 진행 속도, 지금 자신이 이해하고 있는 부분을 말해줘서 편했다.
-회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

도메인 언어에 신경쓰는 부분
+회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

+

도메인 언어에 신경쓰는 부분
클래스명, 변수명과 같은 언어를 세심하게 신경쓴다.
-요구사항 정리도 깔끔하게 잘하는 것 같다.

후추 최고 👍

- - +요구사항 정리도 깔끔하게 잘하는 것 같다.

+

후추 최고 👍

\ No newline at end of file diff --git a/blog.html b/blog.html index a1166c725..e797adc77 100644 --- a/blog.html +++ b/blog.html @@ -2,8 +2,8 @@ - -게시물 목록 | GG + +게시물 목록 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

게시물 목록

게시물 목록

2023

- - +

게시물 목록

게시물 목록

2023

\ No newline at end of file diff --git a/book-leadership-and-self-deception.html b/book-leadership-and-self-deception.html index e21d382a5..1cdc34ff7 100644 --- a/book-leadership-and-self-deception.html +++ b/book-leadership-and-self-deception.html @@ -2,8 +2,8 @@ - -[책] 상자 밖에 있는 사람 | GG + +[책] 상자 밖에 있는 사람 | GG @@ -12,43 +12,79 @@ - - - + + + -
-

[책] 상자 밖에 있는 사람

· 약 6분

책 정보

상자 밖에 있는 사람
-아빈저연구소

자기기만과 자기배반

책에서는 자기기만과 자기배반에 대한 내용을 다룬다.

  • 자기기만: 자신의 문제를 인정하지 않는 것
  • 자기배반: 다른 사람을 위해 무언가 해야만 한다는 생각을 반하는 행위

자기배반을 한다면 자기기만 상태가 된다.
-자기기만 상태에 빠지는 것을 책에서는 상자 안에 들어간다고 표현한다.

읽고 나서

최근에 읽은 책 중 가장 마음이 불편했다.
-그렇기에 더더욱 나에게 필요한 내용이 담겨있었다.

살면서 많은 선택의 순간이 존재했고, 그 순간마다 자기배반을 택하는 경우가 많았다.
+

[책] 상자 밖에 있는 사람

· 약 6분

책 정보

+
+

상자 밖에 있는 사람
+아빈저연구소

+
+

자기기만과 자기배반

+

책에서는 자기기만과 자기배반에 대한 내용을 다룬다.

+
    +
  • 자기기만: 자신의 문제를 인정하지 않는 것
  • +
  • 자기배반: 다른 사람을 위해 무언가 해야만 한다는 생각을 반하는 행위
  • +
+

자기배반을 한다면 자기기만 상태가 된다.
+자기기만 상태에 빠지는 것을 책에서는 상자 안에 들어간다고 표현한다.

+

읽고 나서

+

최근에 읽은 책 중 가장 마음이 불편했다.
+그렇기에 더더욱 나에게 필요한 내용이 담겨있었다.

+

살면서 많은 선택의 순간이 존재했고, 그 순간마다 자기배반을 택하는 경우가 많았다.
작게는 집안일을 해야 하는데 몸이 조금 힘들다고 하지 않거나
크게는 잘못을 인정해야 하는 상황에서 그러지 않은 경우가 있었다.
-이런 상황이 반복되어 결국 상자 안에 나 자신을 가두는 경우가 많았다.

더 나은 삶을 위해 내가 상자 안에 있는지 지속적으로 확인하고, 상자 밖으로 나가려는 연습을 해야겠다.
-넓은 시선을 가지고, 항상 내가 틀릴 수 있다는 것을 생각하고 살아가자.

밑줄 친 문장들

우리의 생각은 지식보다 작다.
+이런 상황이 반복되어 결국 상자 안에 나 자신을 가두는 경우가 많았다.

+

더 나은 삶을 위해 내가 상자 안에 있는지 지속적으로 확인하고, 상자 밖으로 나가려는 연습을 해야겠다.
+넓은 시선을 가지고, 항상 내가 틀릴 수 있다는 것을 생각하고 살아가자.

+

밑줄 친 문장들

+
+

우리의 생각은 지식보다 작다.
우리의 지식은 사랑보다 작다.
우리의 사랑은 존재보다 작다.
그리고 우리가 생각하는 나는 실제의 나보다 그만큼 작다.
R. D. 랭
-p.19

우리가 외적으로 어떤 행동을 하든지 간에, 사람들은 우리 마음에서 그들을 어떻게 대하고 있는지에 따라 주로 반응합니다.
+p.19

+
+
+

우리가 외적으로 어떤 행동을 하든지 간에, 사람들은 우리 마음에서 그들을 어떻게 대하고 있는지에 따라 주로 반응합니다.
우리가 사람들에 대해 어떻게 느끼게 되는지는 우리가 상자 안에 있는지 혹은 상자 밖에 있는지에 따라 달라지게 됩니다.
-p.66

비난은 감정에 속하고 낙관은 의지에 속한다.
+p.66

+
+
+

비난은 감정에 속하고 낙관은 의지에 속한다.
인간은 감정보다 더 큰 존재이다.
알랭, 탁닛한
-p.103

우리가 자신에게만 집중하고 있는 한, 혼자서 일하는 것 이상의 창조적인 결과나 협력을 이끌어 낸다는 것은 불가능합니다.
+p.103

+
+
+

우리가 자신에게만 집중하고 있는 한, 혼자서 일하는 것 이상의 창조적인 결과나 협력을 이끌어 낸다는 것은 불가능합니다.
오늘날 경제 환경에서는 혼자서는 일의 결과를 탁월하게 만들어 내기가 어렵습니다.
내가 중심이어야 된다는 폐쇄적인 사고는 함께 일하는 사람들의 열정을 불러오지 못합니다.
-p.175

솔직함은 우리의 문제를 해결하는 열쇠입니다.
+p.175

+
+
+

솔직함은 우리의 문제를 해결하는 열쇠입니다.
그것은 자신의 행동과 관련된 사람에 대해 기꺼이 사과를 하는 것입니다.
그것만이 실타래처럼 엉킨 관계의 문제를 해결할 수 있기 때문이죠.
-p.188

누군가를 나와 같이 동일한 가치를 지닌 한 인간으로 생각해서 그 사람을 위해 내가 상자 밖에 계속 머무르고 싶은 열망이 생길 때, 나는 이미 그 사람에 대해 상자 밖에 있다.
-p.214

대부분의 사람들이 관계 기술을 가지고 그들이 겪고 있는 문제를 바로잡으려고 하는 노력이 결실을 얻지 못하는 것은 결코 그러한 기술 부족 때문에 생기는 것이 아닙니다.
+p.188

+
+
+

누군가를 나와 같이 동일한 가치를 지닌 한 인간으로 생각해서 그 사람을 위해 내가 상자 밖에 계속 머무르고 싶은 열망이 생길 때, 나는 이미 그 사람에 대해 상자 밖에 있다.
+p.214

+
+
+

대부분의 사람들이 관계 기술을 가지고 그들이 겪고 있는 문제를 바로잡으려고 하는 노력이 결실을 얻지 못하는 것은 결코 그러한 기술 부족 때문에 생기는 것이 아닙니다.
그것들은 자기배반 때문에 생겨납니다.
-p.224

우리는 함께 일하고 우리와 함께 살아가는 사람이 진정으로 누구인지 알지 못합니다.
+p.224

+
+
+

우리는 함께 일하고 우리와 함께 살아가는 사람이 진정으로 누구인지 알지 못합니다.
우리가 그들과 진정으로 함께 소통하기 전까지는 우리는 그들의 가치를 잘 모릅니다.
우리의 위대함이란 다른 사람들의 위대한 점을 발견해 주는 것에 있습니다.
-p.280

- - +p.280

+
\ No newline at end of file diff --git a/book-writer.html b/book-writer.html index c08589b44..61ab1e24b 100644 --- a/book-writer.html +++ b/book-writer.html @@ -2,8 +2,8 @@ - -[책] 글, 우리도 잘 쓸 수 있습니다. | GG + +[책] 글, 우리도 잘 쓸 수 있습니다. | GG @@ -12,19 +12,50 @@ - - - + + + -
-

[책] 글, 우리도 잘 쓸 수 있습니다.

· 약 5분

책 정보

글, 우리도 잘 쓸 수 있습니다.
-박솔미

읽고 나서

저자의 경험과 함께 글쓰기에 대한 가벼운 조언이 담겨있어 가볍게 읽기 좋았다.
-글을 잘 작성해 보고 싶을 때 적용해 볼 수 있는 정보가 많아서 도움이 되었다.

우아한 테크코스의 프리코스를 진행할 때 후기를 작성하고 나면 항상 글이 딱딱하다는 느낌을 받았다.
+

[책] 글, 우리도 잘 쓸 수 있습니다.

· 약 5분

책 정보

+
+

글, 우리도 잘 쓸 수 있습니다.
+박솔미

+
+

읽고 나서

+

저자의 경험과 함께 글쓰기에 대한 가벼운 조언이 담겨있어 가볍게 읽기 좋았다.
+글을 잘 작성해 보고 싶을 때 적용해 볼 수 있는 정보가 많아서 도움이 되었다.

+

우아한 테크코스의 프리코스를 진행할 때 후기를 작성하고 나면 항상 글이 딱딱하다는 느낌을 받았다.
다른 지원자들의 읽기 편하고, 밝은 느낌을 주는 글을 보면 부러운 마음을 가지기도 했다.
-이 책을 읽었으니 2023년에는 조금 더 글을 잘 적어보려고 한다.

밑줄 친 문장들

문장이 심심하고 지루하다면 -내용을 일목요연하게 정리했고, 글의 의도도 삐뚤지 않고, 단어도 적절한 것으로 골랐는데… 그런데도 어딘가가 심심하고 지루하다면? 축축 처지고 따분하다면? 말꼬리를 모조리 ‘~다’로 통일한 건 아닌지 점검해 보세요.

말꼬리를 잘 갖고 놀아야 합니다. 문장의 마지막 글자를 매번 다르게 고쳐쓰는 것만으로도 글에 활기를 더할 수 있죠. 때론 문장을 다 마치지 않고, 단어로만 끝맺는 것도 방법. 문장과 문장 사이에 쉼표가 들어서며 글 전체에 활기가 돌게 돼요. 문장의 길이도 다채로워지는 덕분에 덤으로 얻게 되는 것도 있습니다. 바로, 글의 리듬.

이전 문장에서 끝난 글자로, 다음 문장을 끝맺지 않기. 한두 문단마다 단어 수준의 아주 짧은 문장 배치하기.

글의 진짜 이유, 글의 진짜 목적, 글의 진짜 대상을 찾으려고 애썼습니다. 지금처럼 틀을 떠올린다거나, 눈치를 본다거나, 정치적인 셈도 하지 않았어요.

제목은 짧게, 보기 쉽게, 읽기 쉽게, 발음이 비슷하게, 순서를 바꿔서

글을 마지막으로 다듬을 때, 노래에 가까워질 방법은 없을지 고민해봅니다. 감히 가 닿을 수 없는 목표이겠지만, 할 수 있는 최소한의 리듬이라도 붙여주고 싶어요.

여는 말과 마지막 말에 작정하고 마음을 담는 연습을 해봅시다. 글의 어느 구석이라도 뻔한 글자는 남기지 않겠노라 다짐하며 써보는 겁니다. 나만이 가진 유일한 메시지에 집중하면서요. 그럼 생각이 달라지고, 고르는 단어도 달라지고, 남긴 문장도 달라져요. 결국에는 글을 쓴 사람인 나 자신도 남달라질 겁니다.

맞춤법은 중요합니다. 하지만 맞춤법보다 더 중요한 건 거기에 담긴 마음입니다. 내 마음을 글에 담아 실어 보내기 전, 맞춤법을 점검하는 이유 역시 그겁니다. 오직 내 마음이 남에게 읽히는 동안 방해가 되지 않기를 바라기 때문이죠. 내가 쓴 글도, 남이 쓴 글도. 언제나 그 안에 담긴 마음이 먼저입니다.

글을 쓴다고 글이 완성되는 게 아니에요. 글과 닮은 모습으로 살 때, 글은 비로소 완성됩니다.

- - +이 책을 읽었으니 2023년에는 조금 더 글을 잘 적어보려고 한다.

+

밑줄 친 문장들

+
+

문장이 심심하고 지루하다면 +내용을 일목요연하게 정리했고, 글의 의도도 삐뚤지 않고, 단어도 적절한 것으로 골랐는데… 그런데도 어딘가가 심심하고 지루하다면? 축축 처지고 따분하다면? 말꼬리를 모조리 ‘~다’로 통일한 건 아닌지 점검해 보세요.

+
+
+

말꼬리를 잘 갖고 놀아야 합니다. 문장의 마지막 글자를 매번 다르게 고쳐쓰는 것만으로도 글에 활기를 더할 수 있죠. 때론 문장을 다 마치지 않고, 단어로만 끝맺는 것도 방법. 문장과 문장 사이에 쉼표가 들어서며 글 전체에 활기가 돌게 돼요. 문장의 길이도 다채로워지는 덕분에 덤으로 얻게 되는 것도 있습니다. 바로, 글의 리듬.

+
+
+

이전 문장에서 끝난 글자로, 다음 문장을 끝맺지 않기. 한두 문단마다 단어 수준의 아주 짧은 문장 배치하기.

+
+
+

글의 진짜 이유, 글의 진짜 목적, 글의 진짜 대상을 찾으려고 애썼습니다. 지금처럼 틀을 떠올린다거나, 눈치를 본다거나, 정치적인 셈도 하지 않았어요.

+
+
+

제목은 짧게, 보기 쉽게, 읽기 쉽게, 발음이 비슷하게, 순서를 바꿔서

+
+
+

글을 마지막으로 다듬을 때, 노래에 가까워질 방법은 없을지 고민해봅니다. 감히 가 닿을 수 없는 목표이겠지만, 할 수 있는 최소한의 리듬이라도 붙여주고 싶어요.

+
+
+

여는 말과 마지막 말에 작정하고 마음을 담는 연습을 해봅시다. 글의 어느 구석이라도 뻔한 글자는 남기지 않겠노라 다짐하며 써보는 겁니다. 나만이 가진 유일한 메시지에 집중하면서요. 그럼 생각이 달라지고, 고르는 단어도 달라지고, 남긴 문장도 달라져요. 결국에는 글을 쓴 사람인 나 자신도 남달라질 겁니다.

+
+
+

맞춤법은 중요합니다. 하지만 맞춤법보다 더 중요한 건 거기에 담긴 마음입니다. 내 마음을 글에 담아 실어 보내기 전, 맞춤법을 점검하는 이유 역시 그겁니다. 오직 내 마음이 남에게 읽히는 동안 방해가 되지 않기를 바라기 때문이죠. 내가 쓴 글도, 남이 쓴 글도. 언제나 그 안에 담긴 마음이 먼저입니다.

+
+
+

글을 쓴다고 글이 완성되는 게 아니에요. 글과 닮은 모습으로 살 때, 글은 비로소 완성됩니다.

+
\ No newline at end of file diff --git a/chess-retrospective.html b/chess-retrospective.html index ee241ad82..84479065a 100644 --- a/chess-retrospective.html +++ b/chess-retrospective.html @@ -2,8 +2,8 @@ - -체스 미션 회고 | GG + +체스 미션 회고 | GG @@ -12,49 +12,84 @@ - - - + + + -
-

체스 미션 회고

· 약 8분

체스

체스 미션에는 가비와 페어가 매칭되었다!
+

체스 미션 회고

· 약 8분

1, 2단계: https://github.com/woowacourse/java-chess/pull/441
+3, 4단계: https://github.com/woowacourse/java-chess/pull/529

+

체스

+

체스 미션에는 가비와 페어가 매칭되었다!
체스는 이전 미션들보다 훨씬 복잡한 도메인이었다.
하지만 가비와 나는 체스 도메인이 익숙해서 더 편한 마음으로 시작할 수 있었다.
-미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
-최종적으로 결정한 부분은 다음과 같다.

각 기물의 이동 가능여부
+미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

+

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
+최종적으로 결정한 부분은 다음과 같다.

+

각 기물의 이동 가능여부
Rank와 File은 각각 위치값을 가지고 있고, 값의 차이를 이용해서 각 기물의 이동 가능 여부를 계산했다.
직선 → Rank와 File 차이 중 하나가 0이어야 한다.
대각선 → Rank와 File 차이의 절대값이 같아야 한다. ex) abs(-2) == abs(2)
-나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

도착 칸의 기물 여부
+나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

+

도착 칸의 기물 여부
아군 → 이동이 불가능하다.
-적군 → 이동이 가능하다. 적군을 잡는다.

중간에 기물 존재 여부
-이동 경로에 기물이 존재하면 안된다.

데이터베이스 사용
+적군 → 이동이 가능하다. 적군을 잡는다.

+

중간에 기물 존재 여부
+이동 경로에 기물이 존재하면 안된다.

+

데이터베이스 사용
체스 미션은 특별하게 데이터베이스와 연결하는 부분이 있었다.
-체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

  • 기물 전체를 저장하는 방법
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
-기물 전체를 저장하지 않은 이유는 다음과 같다.

  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
+체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

+
    +
  • 기물 전체를 저장하는 방법
  • +
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법
  • +
+

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
+기물 전체를 저장하지 않은 이유는 다음과 같다.

+
    +
  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • +
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • +
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.
  • +
+

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
보드저장: 초기상태에서 32개의 Insert 쿼리(기물의 위치) + 기물 이동 시 움직임 변경(잡히는 경우 2개의 쿼리)
-기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

추가로 기보저장이 구현도 더욱 간단하다. 👍

부가적인 부분

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

  • 누누의 도움으로 ConnectionPool 구현
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

부족했던 부분

꼼꼼하게 코드를 작성하지 못한 부분
+기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

+

추가로 기보저장이 구현도 더욱 간단하다. 👍

+

부가적인 부분

+

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

+
    +
  • 누누의 도움으로 ConnectionPool 구현
  • +
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • +
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)
  • +
+

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

+

부족했던 부분

+

꼼꼼하게 코드를 작성하지 못한 부분
DB 관련 부분을 꼼꼼하게 코딩을 하지 못했다.
도메인 로직에만 집중하다보니 정적 중요한 DB의 코드의 예외처리, 빈 값을 반환 하는 부분을 꼼꼼하게 처리하지 못했다.
-하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

시간에 대한 부담감
+하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

+

시간에 대한 부담감
초반에는 여유롭지만 제출 마감에 가까워질 수록 사람이 급해지는 것 같다.
-다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

새로 학습한 부분

DAO 중복 제거

프롤로그에 을 작성했다.
+다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

+

새로 학습한 부분

+

DAO 중복 제거

+

프롤로그에 을 작성했다.
DAO를 작성하는데 try-catch-resources와 여러 코드가 중복되서 제거하고싶었다.
-템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

페어에게 배울 부분

페어 생각하기
+템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

+

페어에게 배울 부분

+

페어 생각하기
가비는 누구보다 페어를 생각하고, 배려해주는 페어였다.
-중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

미션 몰입하기
+중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

+

미션 몰입하기
최근에 미션에 잘 몰입하지 못했다.
가비는 페어를 진행할 때 미션에 대한 몰입도가 매우 좋았다.
집에가서도 체스 이동에 대한 로직을 어떻게 구현할 지 생각한 뒤 꼼꼼해서 정리해서 나에게 보내주었다.
덕분에 나도 가비의 생각을 알 수 있어서 미션을 진행하는데 가속도가 붙은 것 같다.
-또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

솔직함
+또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

+

솔직함
먼저 회고하자고 말 걸어줘서 정말 고마웠다고 표현해주는 부분
모르는게 있으면 솔직하게 말해주는 부분
나의 의견을 정리하지 못한 상태로 전달할 때 이해가 안되었다고 정확히 전달해주는 부분
-솔직함은 페어할 때 중요한 부분인 것 같다.

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

- - +솔직함은 페어할 때 중요한 부분인 것 같다.

+

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

\ No newline at end of file diff --git a/cloudwatch.html b/cloudwatch.html index 5251bd139..fd7293e1a 100644 --- a/cloudwatch.html +++ b/cloudwatch.html @@ -2,8 +2,8 @@ - -CloudWatch를 이용한 로깅, 메트릭 모니터링 환경 구성 | GG + +CloudWatch를 이용한 로깅, 메트릭 모니터링 환경 구성 | GG @@ -12,33 +12,92 @@ - - - + + + -
-

CloudWatch를 이용한 로깅, 메트릭 모니터링 환경 구성

· 약 6분

CloudWatch

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
+

CloudWatch를 이용한 로깅, 메트릭 모니터링 환경 구성

· 약 6분

CloudWatch

+

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
지표를 감시하여 알림을 보내는 기능도 제공한다.
프리티어를 사용하지 않는 경우 대시보드당 3$/M 의 비용이 청구되고, 지표나 로그의 양에 따라 비용이 추가적으로 청구된다.
-요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

CloudWatch Metrics

기본적으로 5분마다 지표에 대한 정보가 수집된다.
+요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

+

CloudWatch Metrics

+

기본적으로 5분마다 지표에 대한 정보가 수집된다.
세부 모니터링(Detailed Monitoring)을 활성화하면 1분마다 지표를 수집한다.
-대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

./cloudwatch1.png

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

CloudWatch Agent 설치

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

IAM 역할 설정

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
-IAM → 역할에서 역할 생성을 클릭한다.

./cloudwatch2.png

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

./cloudwatch3.png

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
-작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

./cloudwatch4.png

설치

환경은 다음과 같다.

OS: ubuntu 22.04
-인스턴스 유형: t4g.small (ARM64)

아래 명령어를 입력하여 설치한다.

wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i -E ./amazon-cloudwatch-agent.deb

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

Wizard

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
+대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

+

./cloudwatch1.png

+

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

+

CloudWatch Agent 설치

+

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

+

IAM 역할 설정

+

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
+IAM → 역할에서 역할 생성을 클릭한다.

+

./cloudwatch2.png

+

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

+

./cloudwatch3.png

+

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
+작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

+

./cloudwatch4.png

+

설치

+

환경은 다음과 같다.

+

OS: ubuntu 22.04
+인스턴스 유형: t4g.small (ARM64)

+

아래 명령어를 입력하여 설치한다.

+
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
+sudo dpkg -i -E ./amazon-cloudwatch-agent.deb
+
+

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

+

Wizard

+

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
로그를 수집하도록 설정하는 경우 Wizard 실행 명령어 입력 전 log 파일의 절대 경로를 복사해두는 것이 좋다.
-아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
-로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

./cloudwatch5.png

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

Do you want to store the config in the SSM parameter store?
1. yes
2. no

추가적으로 설정하지 않는 경우 2번을 선택한다.
-Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
-설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

설정 파일 적용

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
-file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

types.db: no such file or directory 에러

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory

types.db 파일 생성

sudo mkdir /usr/share/collectd
sudo touch /usr/share/collectd/types.db

지표 확인

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

./cloudwatch6.png

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

{
"metrics": {
"namespace": "2023-hello-world",
......
},
}

로그

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

./cloudwatch7.png

참고 자료

CloudWatch란 무엇입니까?
-Amazon CloudWatch 요금
-Linux 인스턴스 지표
-서버에 CloudWatch 에이전트 설치 및 실행
-CloudWatch Agent를 Parameter Store에서 관리해 보기
-CloudWatch에이전트 구성 파일

- - +아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
+
+

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
+로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

+

./cloudwatch5.png

+

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

+
Do you want to store the config in the SSM parameter store?
+1. yes
+2. no
+
+

추가적으로 설정하지 않는 경우 2번을 선택한다.
+Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
+설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

+

설정 파일 적용

+

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
+file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
+
+

types.db: no such file or directory 에러

+

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

+
Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory
+
+

types.db 파일 생성

+
sudo mkdir /usr/share/collectd
+sudo touch /usr/share/collectd/types.db
+
+

지표 확인

+

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

+

./cloudwatch6.png

+

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

+
{
+  "metrics": {
+    "namespace": "2023-hello-world",
+    ......
+   },
+} 
+
+

로그

+

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

+

./cloudwatch7.png

+

참고 자료

+

CloudWatch란 무엇입니까?
+Amazon CloudWatch 요금
+Linux 인스턴스 지표
+서버에 CloudWatch 에이전트 설치 및 실행
+CloudWatch Agent를 Parameter Store에서 관리해 보기
+CloudWatch에이전트 구성 파일

\ No newline at end of file diff --git a/composite.html b/composite.html index 809022e3d..eaaa4b9ea 100644 --- a/composite.html +++ b/composite.html @@ -2,8 +2,8 @@ - -컴포지트 패턴으로 요금 정책 추상화하기 | GG + +컴포지트 패턴으로 요금 정책 추상화하기 | GG @@ -12,26 +12,110 @@ - - - + + + -
-

컴포지트 패턴으로 요금 정책 추상화하기

· 약 5분

요구사항

지하철 미션에는 다음과 같은 요구사항이 있었다.

  • 거리별 추가 요금 정책
  • 노선별 추가 요금 정책
  • 연령별 요금 할인 정책

인터페이스 사용

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
-요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

public interface FarePolicy {
int calculate(Path path, Passenger passenger, int fare);
}

public class BaseFarePolicy implements FarePolicy { ... }
public class DistanceFarePolicy implements FarePolicy { ... }
public class AgeDiscountFarePolicy implements FarePolicy { ... }

composite1

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
-이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

public class SubwayFarePolicy implements FarePolicy {

private final List<FarePolicy> farePolicies;

public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
this.farePolicies = farePolicies;
}

@Override
public int calculate(final Path path, final Passenger passenger, final int fare) {
int calculatedFare = fare;
for (FarePolicy farePolicy : farePolicies) {
calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
}
return calculatedFare;
}
}

따라서 그림으로 본다면 다음과 같은 구조가 된다.

composite2

정책의 순서

지하철 요구사항은 순서가 중요했다.
+

컴포지트 패턴으로 요금 정책 추상화하기

· 약 5분

요구사항

+

지하철 미션에는 다음과 같은 요구사항이 있었다.

+
    +
  • 거리별 추가 요금 정책
  • +
  • 노선별 추가 요금 정책
  • +
  • 연령별 요금 할인 정책
  • +
+

인터페이스 사용

+

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
+요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

+
public interface FarePolicy {
+    int calculate(Path path, Passenger passenger, int fare);
+}
+
+public class BaseFarePolicy implements FarePolicy { ... }
+public class DistanceFarePolicy implements FarePolicy { ... }
+public class AgeDiscountFarePolicy implements FarePolicy { ... }
+
+

composite1

+

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

+

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
+이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

+
public class SubwayFarePolicy implements FarePolicy {
+
+    private final List<FarePolicy> farePolicies;
+
+    public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
+        this.farePolicies = farePolicies;
+    }
+
+    @Override
+    public int calculate(final Path path, final Passenger passenger, final int fare) {
+        int calculatedFare = fare;
+        for (FarePolicy farePolicy : farePolicies) {
+            calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
+        }
+        return calculatedFare;
+    }
+}
+
+

따라서 그림으로 본다면 다음과 같은 구조가 된다.

+

composite2

+

정책의 순서

+

지하철 요구사항은 순서가 중요했다.
금액의 총합을 구하고, 그 후에 할인 정책이 들어가야했다.
따라서 자식들의 순서를 관리할 때 주의를 기울여야 했다.
-Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

@Configuration
public class FareConfiguration {

@Bean
public FarePolicy farePolicy() {
return new SubwayFarePolicy(List.of(
new BaseFarePolicy(),
new DistanceFarePolicy(),
new AgeDiscountFarePolicy()
));
}
}

컴포지트 패턴이란?

composite3

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
-사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

컴포지트 패턴의 구성요소

Component

  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • ex) 요금 정책(FarePolicy)

Leaf

  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • ex) 거리 별 요금 정책(DistanceFarePolicy)

Composite

  • 여러 개의 개발 객체를 포함하는 합성 객체
  • ex) 지하철 요금 정책(SubwayFarePolicy)

Client

  • 인터페이스를 사용하는 클라이언트

컴포지트 패턴의 사용과 주요 목표

부분 - 전체의 관계를 표현하고 싶을 때
-Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

패턴 사용시 주의해야할 부분

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
+Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

+
@Configuration
+public class FareConfiguration {
+
+    @Bean
+    public FarePolicy farePolicy() {
+        return new SubwayFarePolicy(List.of(
+                new BaseFarePolicy(),
+                new DistanceFarePolicy(),
+                new AgeDiscountFarePolicy()
+        ));
+    }
+}
+
+

컴포지트 패턴이란?

+

composite3

+

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

+
+

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
+사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

+
+

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
+이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

+

컴포지트 패턴의 구성요소

+

Component

+
    +
  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • +
  • ex) 요금 정책(FarePolicy)
  • +
+

Leaf

+
    +
  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • +
  • ex) 거리 별 요금 정책(DistanceFarePolicy)
  • +
+

Composite

+
    +
  • 여러 개의 개발 객체를 포함하는 합성 객체
  • +
  • ex) 지하철 요금 정책(SubwayFarePolicy)
  • +
+

Client

+
    +
  • 인터페이스를 사용하는 클라이언트
  • +
+

컴포지트 패턴의 사용과 주요 목표

+

부분 - 전체의 관계를 표현하고 싶을 때
+Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

+

패턴 사용시 주의해야할 부분

+

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
반복되는 문제를 효율적으로 해결할 수 있지만 패턴에 매몰되서는 안된다.
패턴을 맹목적으로 사용해서는 안되고, 현재의 요구사항에 따라 패턴을 유동적으로 수정해가면서 적용하는 것이 좋다.
-항상 트레이드오프를 생각하자!

참고 자료

컴포지트 패턴, GoF의 디자인 패턴
-디자인 패턴과 프레임워크, 오브젝트

- - +항상 트레이드오프를 생각하자!

+

참고 자료

+

컴포지트 패턴, GoF의 디자인 패턴
+디자인 패턴과 프레임워크, 오브젝트

\ No newline at end of file diff --git a/custom-jdbc-template.html b/custom-jdbc-template.html index 7343a023a..543fca9a4 100644 --- a/custom-jdbc-template.html +++ b/custom-jdbc-template.html @@ -2,8 +2,8 @@ - -커스텀 JdbcTemplate 만들기 | GG + +커스텀 JdbcTemplate 만들기 | GG @@ -12,25 +12,356 @@ - - - + + + -
-

커스텀 JdbcTemplate 만들기

· 약 10분

체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
+

커스텀 JdbcTemplate 만들기

· 약 10분

체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
이 때 JDBC를 사용할 때 데이터베이스의 커넥션을 얻고, try-with-resource를 사용하는 부분이 반복되었다.
-템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

기존 코드

public class User {
private final int id;
private final String name;

public User(final int id, final String name) {
this.id = id;
this.name = name;
}

public int getId() {
return id;
}

public String getName() {
return name;
}
}

SELECT, DELETE 중복 제거

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
-변하는 부분: SQL Query, 매개변수

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
executeUpdate(query, userId);
}

private void executeUpdate(final String query, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
preparedStatement.executeUpdate();
} catch (final SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
-이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

콜백(Callback)

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
-자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
+템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

+

기존 코드

+
public class User {
+    private final int id;
+    private final String name;
+
+    public User(final int id, final String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
+
+

SELECT, DELETE 중복 제거

+

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
+변하는 부분: SQL Query, 매개변수

+

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

+
public void insert(final String name) {
+    final String query = "INSERT INTO User (name) VALUES (?)";
+    executeUpdate(query, name);
+}
+
+public void delete(final int userId) {
+    final String query = "DELETE FROM user WHERE user_id = ?";
+    executeUpdate(query, userId);
+}
+
+private void executeUpdate(final String query, final Object... parameters) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
+        for (int i = 1; i <= parameters.length; i++) {
+            preparedStatement.setObject(i, parameters[i - 1]);
+        }
+        preparedStatement.executeUpdate();
+    } catch (final SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

+

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
+이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

+

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
+자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

+

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
executeQuery로 조회한 값은 ResultSet 안에 들어가있다.
-이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

@FunctionalInterface
public interface RowMapper {
User mapRow(final ResultSet resultSet) throws SQLException;
}

조회 분리하기 - 2. 단건 조회

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
-아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

public User findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return queryForSingleResult(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
}, userId);
}

private User queryForSingleResult(
final String query,
final RowMapper rowMapper,
final Object... parameters
) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
if (resultSet.next()) {
return rowMapper.mapRow(resultSet);
}
return null;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

조회 분리하기 - 3. 다건 조회

단건 조회와 유사하다.

public List<User> findAll() {
final String query = "SELECT * FROM user";
return query(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
});
}

private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
final List<User> result = new ArrayList<>();
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
return result;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

제네릭 사용하기

위의 코드는 User를 조회할 때만 사용할 수 있다.
-아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

@FunctionalInterface
public interface RowMapper<T> {
T mapRow(final ResultSet resultSet) throws SQLException;
}

private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
+이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

+
@FunctionalInterface
+public interface RowMapper {
+    User mapRow(final ResultSet resultSet) throws SQLException;
+}
+
+

조회 분리하기 - 2. 단건 조회

+

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
+아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

+
public User findById(final int userId) {
+    final String query = "SELECT * FROM user WHERE id = ?";
+    return queryForSingleResult(query, resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    }, userId);
+}
+
+private User queryForSingleResult(
+        final String query,
+        final RowMapper rowMapper,
+        final Object... parameters
+) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
+         final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
+        if (resultSet.next()) {
+            return rowMapper.mapRow(resultSet);
+        }
+        return null;
+    } catch (SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+private ResultSet executeQuery(
+        final PreparedStatement preparedStatement,
+        final Object[] parameters) throws SQLException {
+    for (int i = 1; i <= parameters.length; i++) {
+        preparedStatement.setObject(i, parameters[i - 1]);
+    }
+    return preparedStatement.executeQuery();
+}
+
+

조회 분리하기 - 3. 다건 조회

+

단건 조회와 유사하다.

+
public List<User> findAll() {
+    final String query = "SELECT * FROM user";
+    return query(query, resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    });
+}
+
+private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
+         final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
+        final List<User> result = new ArrayList<>();
+        while (resultSet.next()) {
+            result.add(rowMapper.mapRow(resultSet));
+        }
+        return result;
+    } catch (SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+private ResultSet executeQuery(
+        final PreparedStatement preparedStatement,
+        final Object[] parameters) throws SQLException {
+    for (int i = 1; i <= parameters.length; i++) {
+        preparedStatement.setObject(i, parameters[i - 1]);
+    }
+    return preparedStatement.executeQuery();
+}
+
+

제네릭 사용하기

+

위의 코드는 User를 조회할 때만 사용할 수 있다.
+아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

+
@FunctionalInterface
+public interface RowMapper<T> {
+    T mapRow(final ResultSet resultSet) throws SQLException;
+}
+
+private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
+private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
+
+

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

+

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
또한 null을 반환하기 보단 Optional로 감싸서 반환하도록 변경한다.
-최종적으로 아래와 같은 코드가 완성된다.

public class UserDao {
private final RowMapper<User> rowMapper = resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
};
private final JdbcTemplate jdbcTemplate;

public UserDao(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
jdbcTemplate.executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
jdbcTemplate.executeUpdate(query, userId);
}

public Optional<User> findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
}

public List<User> findAll() {
final String query = "SELECT * FROM user";
return jdbcTemplate.query(query, rowMapper);
}
}
- - +최종적으로 아래와 같은 코드가 완성된다.

+
public class UserDao {
+    private final RowMapper<User> rowMapper = resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    };
+    private final JdbcTemplate jdbcTemplate;
+
+    public UserDao(final JdbcTemplate jdbcTemplate) {
+        this.jdbcTemplate = jdbcTemplate;
+    }
+
+    public void insert(final String name) {
+        final String query = "INSERT INTO User (name) VALUES (?)";
+        jdbcTemplate.executeUpdate(query, name);
+    }
+
+    public void delete(final int userId) {
+        final String query = "DELETE FROM user WHERE user_id = ?";
+        jdbcTemplate.executeUpdate(query, userId);
+    }
+
+    public Optional<User> findById(final int userId) {
+        final String query = "SELECT * FROM user WHERE id = ?";
+        return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
+    }
+
+    public List<User> findAll() {
+        final String query = "SELECT * FROM user";
+        return jdbcTemplate.query(query, rowMapper);
+    }
+}
+
\ No newline at end of file diff --git a/db-replication.html b/db-replication.html index 76dac6316..a3782a614 100644 --- a/db-replication.html +++ b/db-replication.html @@ -2,8 +2,8 @@ - -DB 복제, @Transactional에 따라 요청 분리해보기 | GG + +DB 복제, @Transactional에 따라 요청 분리해보기 | GG @@ -12,65 +12,440 @@ - - - + + + -
-

DB 복제, @Transactional에 따라 요청 분리해보기

· 약 21분

복제(Replication)

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
-원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

복제를 하는 이유

1. 스케일 아웃

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
-이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

2. 데이터 백업

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
-따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

3. 데이터 분석

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
-마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

4. 데이터의 지리적 분산

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

바이너리 로그 파일 위치 기반 복제

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
+

DB 복제, @Transactional에 따라 요청 분리해보기

· 약 21분

복제(Replication)

+

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
+원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

+

복제를 하는 이유

+

1. 스케일 아웃

+

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
+이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

+

2. 데이터 백업

+

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
+따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

+

3. 데이터 분석

+

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
+마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

+

4. 데이터의 지리적 분산

+

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

+

바이너리 로그 파일 위치 기반 복제

+

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
바이너리 로그를 통해 데이터 변경, 테이블 구조 변경, 계정이나 권한 변경에 대한 정보가 저장된다.
-MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

스레드별 역할

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
+MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

+ +

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
Replication I/O Thread: Binary 로그 이벤트를 가져와 로컬 서버의 파일(Relay Log)로 저장
-Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

바이너리 로그 방식의 문제점

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
-토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
+Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

+

바이너리 로그 방식의 문제점

+

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
+토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

+ +

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

+ +

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
하지만 여기서 C 서버에는 A 서버와 동기화가 안되었으니 조회 시 문제가 발생한다.
-뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

글로벌 트랜잭션 아이디(GTID) 기반 복제

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
-위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

GTID

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
-[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

복제 토폴로지

싱글 레플리카 복제 구성

가장 간단한 구성으로 제일 많이 사용하는 형태다.
-replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

멀티 레플리카 복제 구성

2개의 replica 서버를 사용하는 형태다.
+뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

+

글로벌 트랜잭션 아이디(GTID) 기반 복제

+

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
+위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

+

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
+[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

+

복제 토폴로지

+

싱글 레플리카 복제 구성

+

가장 간단한 구성으로 제일 많이 사용하는 형태다.
+replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

+ +

멀티 레플리카 복제 구성

+

2개의 replica 서버를 사용하는 형태다.
하나의 replica는 예비 용도로 남겨두는 형태다.
-추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

체인 복제 구성

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
-따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

듀얼 소스 복제 구성

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
+추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

+ +

체인 복제 구성

+

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
+따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

+ +

듀얼 소스 복제 구성

+

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
각 서버에서 변경된 데이터는 다른 서버에 반영된다.
목적에 따라 ACTIVE-ACTIVE 형태 또는 ACTIVE-PASSIVE 형태로 사용할 수 있다.
-ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

ACTIVE-ACTIVE, ACTIVE-PASSIVE

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
-ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

멀티 소스 복제 구성

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
-이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

바이너리 로그 방식 Replication 구성하기

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
-https://github.com/bbiac/db-replication

MySQL 환경 구성

MySQL 버전은 8.1을 사용했다.
+ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

+ +

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
+ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

+

멀티 소스 복제 구성

+

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
+이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

+ +

바이너리 로그 방식 Replication 구성하기

+

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
+https://github.com/bbiac/db-replication

+

MySQL 환경 구성

+

MySQL 버전은 8.1을 사용했다.
13306, 13307 포트를 사용해서 MySQL 서버 2대를 띄웠다.
-또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

version: '3.8'

services:
source:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-source
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13306:3306"
volumes:
- db-source:/var/lib/mysql
- db-source:/var/lib/mysql-files
- ./docker/source.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

replica:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-replica
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13307:3306"
volumes:
- db-replica:/var/lib/mysql
- db-replica:/var/lib/mysql-files
- ./docker/replica.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

volumes:
db-source:
db-replica:

networks:
mysql_network:
driver: bridge

또한 source, replica 각각 다음과 같이 db 설정을 했다.

설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
/docker/source.cnf
[mysqld]
server_id=1
log_bin=mysql-bin
sync_binlog=1

도커 실행

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
--d 옵션을 붙이면 백그라운드 모드로 실행된다.

docker-compose up -d

replication slave 권한 설정

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
-source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

SOURCE 접속

docker exec -it mysql-source mysql -u root -p

user 계정에 REPLICATION SLAVE 권한 추가

GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
FLUSH PRIVILEGES;

SOURCE DB 정보 확인

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
+또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

+
version: '3.8'
+
+services:
+  source:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-source
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13306:3306"
+    volumes:
+      - db-source:/var/lib/mysql
+      - db-source:/var/lib/mysql-files
+      - ./docker/source.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+  replica:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-replica
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13307:3306"
+    volumes:
+      - db-replica:/var/lib/mysql
+      - db-replica:/var/lib/mysql-files
+      - ./docker/replica.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+volumes:
+  db-source:
+  db-replica:
+
+networks:
+  mysql_network:
+    driver: bridge
+
+

또한 source, replica 각각 다음과 같이 db 설정을 했다.

+
설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
+ + +
[mysqld]
+server_id=1
+log_bin=mysql-bin
+sync_binlog=1
+
+

도커 실행

+

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
+-d 옵션을 붙이면 백그라운드 모드로 실행된다.

+
docker-compose up -d
+
+

replication slave 권한 설정

+

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
+source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

+

SOURCE 접속

+
docker exec -it mysql-source mysql -u root -p
+
+

user 계정에 REPLICATION SLAVE 권한 추가

+
GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
+FLUSH PRIVILEGES;
+
+

SOURCE DB 정보 확인

+

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
Position 값은 실제 파일의 바이트 수를 의미한다.
-확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 1082 | | | |
+------------------+----------+--------------+------------------+-------------------+

SOURCE ip 주소 확인

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
-다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
-확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

replica mysql 접속

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

docker exec -it mysql-replica mysql -u root -p

replica 설정

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
+확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

+
SHOW MASTER STATUS;
+
++------------------+----------+--------------+------------------+-------------------+
+| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
++------------------+----------+--------------+------------------+-------------------+
+| mysql-bin.000003 |     1082 |              |                  |                   |
++------------------+----------+--------------+------------------+-------------------+
+
+

SOURCE ip 주소 확인

+

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
+다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

+
docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source
+
+

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
+확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

+

replica mysql 접속

+

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

+
docker exec -it mysql-replica mysql -u root -p
+
+

replica 설정

+

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
실제 DB 서버에서 복제하는 경우 추가적으로 source DB의 파일을 복제해야하지만 현재 복제할 데이터가 없기 때문에 해당 부분은 생략했다.
-SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

STOP REPLICA;

CHANGE REPLICATION SOURCE TO
SOURCE_HOST='172.29.0.2',
SOURCE_USER='user',
SOURCE_PASSWORD='password',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=0,
GET_SOURCE_PUBLIC_KEY=1;

START REPLICA;

설정 확인

SHOW REPLICA STATUS;

+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
-replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

CREATE TABLE member
(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);

스프링 부트로 DB 접근하기

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

Environment 설정

다음과 같이 source, replica로 구분하여 설정한다.

application.yml
spring:
datasource:
source:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13306/db
replica:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13307/db

DataSourceType 설정

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
-Key는 추후에 빈 설정에 사용한다.

DataSourceType
public enum DataSourceType {
SOURCE(SOURCE_NAME),
REPLICA(REPLICA_NAME),
;

private final String key;

DataSourceType(String key) {
this.key = key;
}

public static class Key {
public static final String ROUTING_NAME = "ROUTING";
public static final String SOURCE_NAME = "SOURCE";
public static final String REPLICA_NAME = "REPLICA";
}
}

AbstractRoutingDataSource 설정

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
RoutingDataSource
public class RoutingDataSource extends AbstractRoutingDataSource {

private final Logger log = LoggerFactory.getLogger(getClass());

public static RoutingDataSource from(Map<Object, Object> dataSources) {
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
routingDataSource.setTargetDataSources(dataSources);
return routingDataSource;
}

@Override
protected Object determineCurrentLookupKey() {
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();

if (readOnly) {
log.info("readOnly = true, request to replica");
return DataSourceType.REPLICA;
}
log.info("readOnly = false, request to source");
return DataSourceType.SOURCE;
}
}

DataSource 설정

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
+SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

+
STOP REPLICA;
+
+CHANGE REPLICATION SOURCE TO 
+SOURCE_HOST='172.29.0.2', 
+SOURCE_USER='user', 
+SOURCE_PASSWORD='password', 
+SOURCE_LOG_FILE='mysql-bin.000001', 
+SOURCE_LOG_POS=0, 
+GET_SOURCE_PUBLIC_KEY=1;
+
+START REPLICA;
+
+

설정 확인

+
SHOW REPLICA STATUS;
+
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Replica_IO_State                 | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File  | Read_Source_Log_Pos | Relay_Log_File         | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID                          | Source_Info_File        | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State                                | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Waiting for source to send event | 172.25.0.3  | user        |        3306 |            60 | mysql-bin.000003 |                1082 | mysql-relay-bin.000002 |           868 | mysql-bin.000003      | Yes                | Yes                 |                 |                     |                    |                        |                         |                             |          0 |            |            0 |                1082 |            1078 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 | No                            |             0 |               |              0 |                |                             |                1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info |         0 |                NULL | Replica has read all relay log; waiting for more updates |              86400 |             |                         |                          |                |                    |                    |                   |             0 |                      |              |                    |                        |                     1 |                   |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+
+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

+

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
+replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

+
CREATE TABLE member
+(
+    id   BIGINT PRIMARY KEY AUTO_INCREMENT,
+    name VARCHAR(255)
+);
+
+

스프링 부트로 DB 접근하기

+

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

+

Environment 설정

+

다음과 같이 source, replica로 구분하여 설정한다.

+
spring:
+  datasource:
+    source:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13306/db
+    replica:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13307/db
+
+

DataSourceType 설정

+

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
+Key는 추후에 빈 설정에 사용한다.

+
public enum DataSourceType {
+    SOURCE(SOURCE_NAME),
+    REPLICA(REPLICA_NAME),
+    ;
+
+    private final String key;
+
+    DataSourceType(String key) {
+        this.key = key;
+    }
+
+    public static class Key {
+        public static final String ROUTING_NAME = "ROUTING";
+        public static final String SOURCE_NAME = "SOURCE";
+        public static final String REPLICA_NAME = "REPLICA";
+    }
+}
+
+

AbstractRoutingDataSource 설정

+

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

+

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

+
    +
  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • +
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.
  • +
+

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

+
    +
  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • +
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
  • +
+
public class RoutingDataSource extends AbstractRoutingDataSource {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public static RoutingDataSource from(Map<Object, Object> dataSources) {
+        RoutingDataSource routingDataSource = new RoutingDataSource();
+        routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
+        routingDataSource.setTargetDataSources(dataSources);
+        return routingDataSource;
+    }
+
+    @Override
+    protected Object determineCurrentLookupKey() {
+        boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
+
+        if (readOnly) {
+            log.info("readOnly = true, request to replica");
+            return DataSourceType.REPLICA;
+        }
+        log.info("readOnly = false, request to source");
+        return DataSourceType.SOURCE;
+    }
+}
+
+

DataSource 설정

+

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
스프링은 트랜잭션 시작시에 커넥션의 사용여부와 상관없이 커넥션을 확보한다.
-따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

DataSourceConfiguration
@Configuration
public class DataSourceConfiguration {

@Bean
@Qualifier(SOURCE_NAME)
@ConfigurationProperties(prefix = "spring.datasource.source")
public DataSource sourceDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(REPLICA_NAME)
@ConfigurationProperties(prefix = "spring.datasource.replica")
public DataSource replicaDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(ROUTING_NAME)
public DataSource routingDataSource(
@Qualifier(SOURCE_NAME) DataSource sourceDataSource,
@Qualifier(REPLICA_NAME) DataSource replicaDataSource
) {
return RoutingDataSource.from(Map.of(
DataSourceType.SOURCE, sourceDataSource,
DataSourceType.REPLICA, replicaDataSource
));
}

@Bean
@Primary
public DataSource dataSource(
@Qualifier(ROUTING_NAME) DataSource routingDataSource
) {
return new LazyConnectionDataSourceProxy(routingDataSource);
}
}

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

동작 확인

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
+따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

+

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

+

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

+
@Configuration
+public class DataSourceConfiguration {
+
+    @Bean
+    @Qualifier(SOURCE_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.source")
+    public DataSource sourceDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(REPLICA_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.replica")
+    public DataSource replicaDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(ROUTING_NAME)
+    public DataSource routingDataSource(
+            @Qualifier(SOURCE_NAME) DataSource sourceDataSource,
+            @Qualifier(REPLICA_NAME) DataSource replicaDataSource
+    ) {
+        return RoutingDataSource.from(Map.of(
+                DataSourceType.SOURCE, sourceDataSource,
+                DataSourceType.REPLICA, replicaDataSource
+        ));
+    }
+
+    @Bean
+    @Primary
+    public DataSource dataSource(
+            @Qualifier(ROUTING_NAME) DataSource routingDataSource
+    ) {
+        return new LazyConnectionDataSourceProxy(routingDataSource);
+    }
+}
+
+

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

+ +

동작 확인

+

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
save 메서드의 경우 @Transactional, findById 메서드의 경우 @Transactional(readOnly = true)가 설정되어있다.
-로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

MemberServiceTest
@SpringBootTest
class MemberServiceTest {

@Autowired
private MemberService memberService;

@Test
void 사용자를_저장한다() {
// RoutingDataSource log: readOnly = false
memberService.save("bbiac");
}

@Test
void 사용자를_조회한다() {
// RoutingDataSource log: readOnly = true
assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
.isInstanceOf(NoSuchElementException.class);
}
}

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

SET GLOBAL log_output = 'table';
SET GLOBAL general_log = 1;

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
-server_id, 실행한 쿼리문을 확인할 수 있다.

SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';

+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user_host | thread_id | server_id | convert(argument using utf8) |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

SET GLOBAL general_log = 0;
SHOW VARIABLES LIKE '%general%';

+------------------+---------------------------------+
| Variable_name | Value |
+------------------+---------------------------------+
| general_log | OFF |
| general_log_file | /var/lib/mysql/4b6b9db98290.log |
+------------------+---------------------------------+

참고 자료

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
-Replication, MySQL Docs
-MySql - Master Slave Replication 구조 만들어보기
-Spring 레플리케이션 트랜잭션 처리 방식
-replication-datasource
-Simplified Guide to MySQL Replication with Docker Compose
-Dockerfile에서 자주 쓰이는 명령어
-CHANGE REPLICATION SOURCE TO Statement
-LazyConnectionDataSourceProxy
-데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
-부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
-Use Docker Compose, Docker

- - +로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

+
@SpringBootTest
+class MemberServiceTest {
+
+    @Autowired
+    private MemberService memberService;
+
+    @Test
+    void 사용자를_저장한다() {
+        // RoutingDataSource log: readOnly = false
+        memberService.save("bbiac");
+    }
+
+    @Test
+    void 사용자를_조회한다() {
+        // RoutingDataSource log: readOnly = true
+        assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
+                .isInstanceOf(NoSuchElementException.class);
+    }
+}
+
+

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

+
SET GLOBAL log_output = 'table';
+SET GLOBAL general_log = 1;
+
+

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
+server_id, 실행한 쿼리문을 확인할 수 있다.

+
SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';
+
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user_host                  | thread_id | server_id | convert(argument using utf8)                                                |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user[user] @  [172.25.0.1] |       277 |         2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+
+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

+
SET GLOBAL general_log = 0;
+SHOW VARIABLES LIKE '%general%';
+
++------------------+---------------------------------+
+| Variable_name    | Value                           |
++------------------+---------------------------------+
+| general_log      | OFF                             |
+| general_log_file | /var/lib/mysql/4b6b9db98290.log |
++------------------+---------------------------------+
+
+

참고 자료

+

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
+Replication, MySQL Docs
+MySql - Master Slave Replication 구조 만들어보기
+Spring 레플리케이션 트랜잭션 처리 방식
+replication-datasource
+Simplified Guide to MySQL Replication with Docker Compose
+Dockerfile에서 자주 쓰이는 명령어
+CHANGE REPLICATION SOURCE TO Statement
+LazyConnectionDataSourceProxy
+데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
+부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
+Use Docker Compose, Docker

\ No newline at end of file diff --git a/docs.html b/docs.html index f1e53ebdd..eaa03e72c 100644 --- a/docs.html +++ b/docs.html @@ -1,9 +1,9 @@ - + - -문서 | GG + +문서 | GG @@ -12,14 +12,11 @@ - - - + + + - - - + \ No newline at end of file diff --git a/docs/architecture/virtical-slice-architecture.html b/docs/architecture/virtical-slice-architecture.html index 60f5c29c0..c162045dc 100644 --- a/docs/architecture/virtical-slice-architecture.html +++ b/docs/architecture/virtical-slice-architecture.html @@ -1,9 +1,9 @@ - + - -버티컬 슬라이스 아키텍처 | GG + +버티컬 슬라이스 아키텍처 | GG @@ -12,22 +12,28 @@ - - - + + + -
-

버티컬 슬라이스 아키텍처

개요

기존의 Layered Architecture → 레이어별 역할과 책임을 나눠서 구현
-Virtical Slice Architecture → Feature라는 하나의 클래스에 응집시켜 구현하는 구조

특징

Transactional과 Controller가 같이 붙어있는 형태를 띈다.
+

버티컬 슬라이스 아키텍처

개요

+

기존의 Layered Architecture → 레이어별 역할과 책임을 나눠서 구현
+Virtical Slice Architecture → Feature라는 하나의 클래스에 응집시켜 구현하는 구조

+

특징

+

Transactional과 Controller가 같이 붙어있는 형태를 띈다.
빠른 피드백 사이클을 가진 신규 서비스의 경우 핵심 비즈니스 로직에 집중이 가능하다.
기능별로 구현하기 때문에 사이드 이펙트가 적다.
-작은 규모의 조직, 코드 품질 관리가 이루어지는 조직에 적합하다.

주의 사항

한 곳에 기능이 집중되어 있기 때문에 스파게티 코드가 되지 않도록 지속적으로 코드 품질을 관리해야한다.
-DB에 바로 접근할 수 있기 때문에 DB 중심의 개발이 되지 않도록 주의해야 한다.

테스트 작성

API → 통합 테스트 -도메인 -> 단위 테스트

참고 자료

버티컬 슬라이스 아키텍처, 유스콘 23
-Vertical Slice Architecture, NDC, Jimmy Bogard
-Vertical Slice Architecture, Jimmy Bogard

- - +작은 규모의 조직, 코드 품질 관리가 이루어지는 조직에 적합하다.

+

주의 사항

+

한 곳에 기능이 집중되어 있기 때문에 스파게티 코드가 되지 않도록 지속적으로 코드 품질을 관리해야한다.
+DB에 바로 접근할 수 있기 때문에 DB 중심의 개발이 되지 않도록 주의해야 한다.

+

테스트 작성

+

API → 통합 테스트 +도메인 -> 단위 테스트

+

참고 자료

+

버티컬 슬라이스 아키텍처, 유스콘 23
+Vertical Slice Architecture, NDC, Jimmy Bogard
+Vertical Slice Architecture, Jimmy Bogard

\ No newline at end of file diff --git a/docs/book/getting-out-of-the-box.html b/docs/book/getting-out-of-the-box.html index 5e15c71a4..d4764d2b8 100644 --- a/docs/book/getting-out-of-the-box.html +++ b/docs/book/getting-out-of-the-box.html @@ -1,9 +1,9 @@ - + - -상자 밖으로 탈출하기 | GG + +상자 밖으로 탈출하기 | GG @@ -12,14 +12,49 @@ - - - + + + -
-

상자 밖으로 탈출하기

⚠️ 자기배반의 원리

  1. 다른 사람을 위해 내가 무엇인가 해야만 한다는 생각과 느낌에 대해 반하는 행위를 자기배반이라고 한다.
  2. 내가 자기배반할 때, 나는 자기배반을 정당화시키는 방식으로 세상을 보기 시작한다.
  3. 자신을 정당화시키는 방식으로 세상을 볼 때, 사실을 보는 나의 시각은 왜곡된다.
  4. 자기배반할 때, 나는 상자 안에 들어가게 된다.
  5. 시간이 지나면서 어떤 상자들은 나의 특성이 되고 일상적으로 나는 그 상자들을 지니고 다닌다.
  6. 내가 상자 안에 있음으로 인하여, 나는 다른 사람들도 상자 안에 들어가도록 이끌게 된다.
  7. 상자 안에서 우리는 서로 잘못 대하는 것을 부추기고 상호 정당화를 얻게 된다. 우리는 서로에게 상자 안에 머물기 위한 이유를 주도록 공모한다.

❌ 상자 안에서 소용없는 일

  1. 다른 사람들을 변화시키려고 하는 것
  2. 다른 사람들에게 "맞춰주기" 위해 최선을 다하기
  3. 두고 떠나기
  4. 커뮤니케이션
  5. 새로운 기술이나 테크닉 활용하기
  6. 나의 행동을 변화시키는 것

📖 학습자료

  1. 자기배반은 자기기만과 "상자"안으로 이끈다.
  2. 상자 안에 있을 때, 당신은 결과(성과)에 집중할 수 없다.
  3. 당신의 영향력과 성공의 크기는 얼마나 상자 밖에 존재하느냐에 달려있다.
  4. 다른 사람들에게 저항하는 것을 그만둘 때 당신은 상자 밖에 있게 된다.

🏃 실천하기

  1. 완벽해지려고 노력하지 말고, 지금보다 더 좋아지려고 노력하라.
  2. 아직 학습내용을 알지 못하는 사람들에게 '상자'나 기타 단어들을 사용하지 마라. 다만 당신 자신의 삶에서 그 원리들을 적용하라.
  3. 다른 사람들의 상자를 찾지 말고, 먼저 당신 자신의 상자를 찾아라.
  4. 다른 사람들이 상자 안에 있다고 힐난하지 말고, 당신이 상자 밖에 있도록 노력하라.
  5. 당신이 상자 안에 있다는 것을 발견했을 때 자신에 대해 포기하지 마라. 계속 노력하라.
  6. 당신이 상자 안에 있다는 것을 부인하지 마라. 사과하고, 계속해서 전진하라. 미래에 다른 사람에게 더 도움이 되도록 노력하라.
  7. 다른 사람들이 잘못하고 있는 것에 초점을 맞추지 마라. 그들을 돕기 위해 당신이 올바르게 행할 수 있는 일에 초점을 맞춰라.
  8. 다른 사람들이 당신을 돕고 있는지에 대해 염려하지 마라. 당신이 다른 사람들을 돕고 있는지에 대해 걱정하라.

참고 자료

상자 밖에 있는 사람, 아빈저연구소

- - +

상자 밖으로 탈출하기

⚠️ 자기배반의 원리

+
    +
  1. 다른 사람을 위해 내가 무엇인가 해야만 한다는 생각과 느낌에 대해 반하는 행위를 자기배반이라고 한다.
  2. +
  3. 내가 자기배반할 때, 나는 자기배반을 정당화시키는 방식으로 세상을 보기 시작한다.
  4. +
  5. 자신을 정당화시키는 방식으로 세상을 볼 때, 사실을 보는 나의 시각은 왜곡된다.
  6. +
  7. 자기배반할 때, 나는 상자 안에 들어가게 된다.
  8. +
  9. 시간이 지나면서 어떤 상자들은 나의 특성이 되고 일상적으로 나는 그 상자들을 지니고 다닌다.
  10. +
  11. 내가 상자 안에 있음으로 인하여, 나는 다른 사람들도 상자 안에 들어가도록 이끌게 된다.
  12. +
  13. 상자 안에서 우리는 서로 잘못 대하는 것을 부추기고 상호 정당화를 얻게 된다. 우리는 서로에게 상자 안에 머물기 위한 이유를 주도록 공모한다.
  14. +
+

❌ 상자 안에서 소용없는 일

+
    +
  1. 다른 사람들을 변화시키려고 하는 것
  2. +
  3. 다른 사람들에게 "맞춰주기" 위해 최선을 다하기
  4. +
  5. 두고 떠나기
  6. +
  7. 커뮤니케이션
  8. +
  9. 새로운 기술이나 테크닉 활용하기
  10. +
  11. 나의 행동을 변화시키는 것
  12. +
+

📖 학습자료

+
    +
  1. 자기배반은 자기기만과 "상자"안으로 이끈다.
  2. +
  3. 상자 안에 있을 때, 당신은 결과(성과)에 집중할 수 없다.
  4. +
  5. 당신의 영향력과 성공의 크기는 얼마나 상자 밖에 존재하느냐에 달려있다.
  6. +
  7. 다른 사람들에게 저항하는 것을 그만둘 때 당신은 상자 밖에 있게 된다.
  8. +
+

🏃 실천하기

+
    +
  1. 완벽해지려고 노력하지 말고, 지금보다 더 좋아지려고 노력하라.
  2. +
  3. 아직 학습내용을 알지 못하는 사람들에게 '상자'나 기타 단어들을 사용하지 마라. 다만 당신 자신의 삶에서 그 원리들을 적용하라.
  4. +
  5. 다른 사람들의 상자를 찾지 말고, 먼저 당신 자신의 상자를 찾아라.
  6. +
  7. 다른 사람들이 상자 안에 있다고 힐난하지 말고, 당신이 상자 밖에 있도록 노력하라.
  8. +
  9. 당신이 상자 안에 있다는 것을 발견했을 때 자신에 대해 포기하지 마라. 계속 노력하라.
  10. +
  11. 당신이 상자 안에 있다는 것을 부인하지 마라. 사과하고, 계속해서 전진하라. 미래에 다른 사람에게 더 도움이 되도록 노력하라.
  12. +
  13. 다른 사람들이 잘못하고 있는 것에 초점을 맞추지 마라. 그들을 돕기 위해 당신이 올바르게 행할 수 있는 일에 초점을 맞춰라.
  14. +
  15. 다른 사람들이 당신을 돕고 있는지에 대해 염려하지 마라. 당신이 다른 사람들을 돕고 있는지에 대해 걱정하라.
  16. +
+

참고 자료

+

상자 밖에 있는 사람, 아빈저연구소

\ No newline at end of file diff --git a/docs/culture/postmortem.html b/docs/culture/postmortem.html index 8488d2a69..851623c40 100644 --- a/docs/culture/postmortem.html +++ b/docs/culture/postmortem.html @@ -1,9 +1,9 @@ - + - -포스트 모템 | GG + +포스트 모템 | GG @@ -12,21 +12,23 @@ - - - + + + -
-

포스트 모템

포스트 모템(Postmortem)

실패한 근본 원인을 분석하여 문서로 남기는 것

포스트 모템에 담겨야 하는 내용

사건의 개요
+

포스트 모템

포스트 모템(Postmortem)

+

실패한 근본 원인을 분석하여 문서로 남기는 것

+

포스트 모템에 담겨야 하는 내용

+

사건의 개요
사건을 인지하고 해결에 이르기까지의 타임라인
사건의 근본 원인
영향과 피해 평가
문제를 즉시 해결하기 위한 조치 항목(소유자 명시)
개발 방지를 위한 조치 항목
-해당 경험에서 얻은 교훈

참고 자료

구글 엔지니어는 이렇게 일한다, 타이터스 윈터스, 톰 맨쉬렉, 하이럼 라이트 p.86
-우아한 장애대응

- - +해당 경험에서 얻은 교훈

+

참고 자료

+

구글 엔지니어는 이렇게 일한다, 타이터스 윈터스, 톰 맨쉬렉, 하이럼 라이트 p.86
+우아한 장애대응

\ No newline at end of file diff --git a/docs/database/maximumPoolSize.html b/docs/database/maximumPoolSize.html index 2f45117f3..92486ef2b 100644 --- a/docs/database/maximumPoolSize.html +++ b/docs/database/maximumPoolSize.html @@ -1,9 +1,9 @@ - + - -maximumPoolSize | GG + +maximumPoolSize | GG @@ -12,17 +12,29 @@ - - - + + + -
-

maximumPoolSize

maximumPoolSize

커넥션 풀이 도달할 수 있는 최대 크기

HikariCP 공식 문서에는 다음과 같은 공식으로 소개하고 있다.

connections = ((core_count * 2) + effective_spindle_count)

core count의 경우 하이퍼스레딩을 제외한 CPU 코어 수를 의미한다.
-effective spindle count의 경우 하드디스크와 관련이 있다. 한 개의 하드디스크는 하나의 spindle을 가진다.

2개의 코어를 가지고 있는 t4g.small의 경우 해당 공식을 적용하면 (2 * 2) + 1이 된다.
+

maximumPoolSize

maximumPoolSize

+

커넥션 풀이 도달할 수 있는 최대 크기

+

HikariCP 공식 문서에는 다음과 같은 공식으로 소개하고 있다.

+
+

connections = ((core_count * 2) + effective_spindle_count)

+
+

core count의 경우 하이퍼스레딩을 제외한 CPU 코어 수를 의미한다.
+effective spindle count의 경우 하드디스크와 관련이 있다. 한 개의 하드디스크는 하나의 spindle을 가진다.

+

2개의 코어를 가지고 있는 t4g.small의 경우 해당 공식을 적용하면 (2 * 2) + 1이 된다.
해당 공식이 SSD를 사용해도 잘 적용하는지에 대한 내용은 없었지만, 클라우드 환경에서는 해당 공식이 잘 적용된 것 같다.
-쿼리를 실행하는데 시간이 많이 걸리는 경우 상황에 따라서 풀 사이즈를 늘릴 수 있을 것 같다.

만약 하나의 스레드가 여러 개의 커넥션을 들고 있는 경우 데드락이 문제가 될 수 있는데 이를 방지하려면 다음과 같은 공식을 사용할 수 있다.

pool size = Tn x (Cm - 1) + 1

Tn은 코어 수, Cm의 경우 단일 요청이 사용하는 최대 동시 연결 수다.

공식이 존재하지만 결국 애플리케이션이 작동하는 방식에 따라 적합한 pool size가 존재하니 애플리케이션의 성격이나, 성능 테스트를 통해 적합한 사이즈를 설정하는 것이 적합하다고 생각한다.

참고 자료

https://github.com/brettwooldridge/HikariCP

- - +쿼리를 실행하는데 시간이 많이 걸리는 경우 상황에 따라서 풀 사이즈를 늘릴 수 있을 것 같다.

+

만약 하나의 스레드가 여러 개의 커넥션을 들고 있는 경우 데드락이 문제가 될 수 있는데 이를 방지하려면 다음과 같은 공식을 사용할 수 있다.

+
+

pool size = Tn x (Cm - 1) + 1

+
+

Tn은 코어 수, Cm의 경우 단일 요청이 사용하는 최대 동시 연결 수다.

+

공식이 존재하지만 결국 애플리케이션이 작동하는 방식에 따라 적합한 pool size가 존재하니 애플리케이션의 성격이나, 성능 테스트를 통해 적합한 사이즈를 설정하는 것이 적합하다고 생각한다.

+

참고 자료

+

https://github.com/brettwooldridge/HikariCP

\ No newline at end of file diff --git a/docs/database/query-execution.html b/docs/database/query-execution.html index 910eee84c..5f7781ac5 100644 --- a/docs/database/query-execution.html +++ b/docs/database/query-execution.html @@ -1,9 +1,9 @@ - + - -쿼리 실행 구조 | GG + +쿼리 실행 구조 | GG @@ -12,20 +12,37 @@ - - - + + + -
-

쿼리 실행 구조

실행 구조

파서(Parser)

실행된 SQL문을 최소 단위로 분리해서 트리를 만든다.
-트리를 만들며 기본적인 문법 검사를 수행한다.

전처리기(Preprocessor)

파서에서 생성한 파서 트리를 바탕으로 SQL문에 구조적인 문제점이 없는지 파악한다.
-SQL 구문에 작성된 테이블, 열과 같은 오브젝트가 실제로 존재하는지, 접근 권한이 있는지 확인한다.

옵티마이저(Optimizer)

파서 트리를 바탕으로 필요하지 않은 조건은 제거하거나 연산 과정을 단순화 시킨다.
-테이블의 접근 순서, 인덱스 사용 여부와 같은 실행 계획을 수립한다.

쿼리 실행 엔진(Query Execution Engine)

옵티마이저에서 수립한 실행 계획을 참고하여, 스토리지 엔진에서 데이터를 가져온다.
-MySQL 엔진의 부하를 줄이려면 스토리지 엔진에서 가져오는 데이터양을 줄이는 게 매우 중요하다.

참고 자료

2장 SQL 튜닝 용어를 직관적으로 이해하기, 업무에 바로 쓰는 SQL 튜닝 - 양바른
+

쿼리 실행 구조

실행 구조

+ +

파서(Parser)

+

실행된 SQL문을 최소 단위로 분리해서 트리를 만든다.
+트리를 만들며 기본적인 문법 검사를 수행한다.

+

전처리기(Preprocessor)

+

파서에서 생성한 파서 트리를 바탕으로 SQL문에 구조적인 문제점이 없는지 파악한다.
+SQL 구문에 작성된 테이블, 열과 같은 오브젝트가 실제로 존재하는지, 접근 권한이 있는지 확인한다.

+

옵티마이저(Optimizer)

+

파서 트리를 바탕으로 필요하지 않은 조건은 제거하거나 연산 과정을 단순화 시킨다.
+테이블의 접근 순서, 인덱스 사용 여부와 같은 실행 계획을 수립한다.

+

쿼리 실행 엔진(Query Execution Engine)

+

옵티마이저에서 수립한 실행 계획을 참고하여, 스토리지 엔진에서 데이터를 가져온다.
+MySQL 엔진의 부하를 줄이려면 스토리지 엔진에서 가져오는 데이터양을 줄이는 게 매우 중요하다.

+

참고 자료

+

2장 SQL 튜닝 용어를 직관적으로 이해하기, 업무에 바로 쓰는 SQL 튜닝 - 양바른
16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
-https://dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html

- - +https://dev.mysql.com/doc/refman/8.0/en/pluggable-storage-overview.html

\ No newline at end of file diff --git a/docs/deploy/zero-downtime.html b/docs/deploy/zero-downtime.html index 72bad26b3..ba032afea 100644 --- a/docs/deploy/zero-downtime.html +++ b/docs/deploy/zero-downtime.html @@ -1,9 +1,9 @@ - + - -무중단 배포 | GG + +무중단 배포 | GG @@ -12,23 +12,29 @@ - - - + + + -
-

무중단 배포

무중단 배포

운영중인 서버를 중단하지 않고, 새로운 애플리케이션을 배포하는 것
-로드밸런서를 통해 트래픽을 제어하는 방법으로 배포할 수 있다.

롤링 배포(Rolling Deployment)

애플리케이션이 실행되는 환경을 완전히 전환하여, 이전 버전의 애플리케이션을 새로운 버전으로 점진적으로 대체하는 전략이다.
+

무중단 배포

무중단 배포

+

운영중인 서버를 중단하지 않고, 새로운 애플리케이션을 배포하는 것
+로드밸런서를 통해 트래픽을 제어하는 방법으로 배포할 수 있다.

+

롤링 배포(Rolling Deployment)

+

애플리케이션이 실행되는 환경을 완전히 전환하여, 이전 버전의 애플리케이션을 새로운 버전으로 점진적으로 대체하는 전략이다.
롤링 배포는 일반적으로 블루/그린 배포보다 빠르지만, 블루/그린 배포와 달리 격리된 환경에서 배포가 이루어지지 않는다.
-격리된 환경에서 이루어지지 않기 때문에, 새로운 버전이 이전 버전과 호환이 되지 않는다면 배포 시점에 문제가 발생하거나, 배포 실패시 롤백을 하기 어려워질 수 있다.

블루 그린 배포(Blue/Green Deployment)

블루를 이전 버전, 그린을 새로운 버전으로 구성한 후, 로드밸런서를 이용하여 그린으로 트래픽을 전환하는 배포 방식이다.
-배포가 실패할 경우, 간단하게 롤백을 할 수 있기 때문에 배포 위험을 줄일 수 있지만 시스템 자원이 두 배로 필요하다는 단점이 있다.

카나리 배포(Canary Deployment)

애플리케이션을 단계적으로 배포하는 방식이다.
+격리된 환경에서 이루어지지 않기 때문에, 새로운 버전이 이전 버전과 호환이 되지 않는다면 배포 시점에 문제가 발생하거나, 배포 실패시 롤백을 하기 어려워질 수 있다.

+

블루 그린 배포(Blue/Green Deployment)

+

블루를 이전 버전, 그린을 새로운 버전으로 구성한 후, 로드밸런서를 이용하여 그린으로 트래픽을 전환하는 배포 방식이다.
+배포가 실패할 경우, 간단하게 롤백을 할 수 있기 때문에 배포 위험을 줄일 수 있지만 시스템 자원이 두 배로 필요하다는 단점이 있다.

+

카나리 배포(Canary Deployment)

+

애플리케이션을 단계적으로 배포하는 방식이다.
위험을 알려주는 카나리아 새를 탄광에 먼저 보내는 것 처럼, 일정 비율을 먼저 신버전으로 전환하고 문제가 없는 경우 늘려나가는 형태로 배포한다.
-카나리는 테스트가 부족하거나 신뢰할 수 없는 경우, 새 릴리스의 안정성에 대한 확신이 없는 경우에 주로 사용된다.

참고 자료

무중단 배포 아키텍처, SAMSUNG SDS
-Rolling Deployments, AWS
-Software Deployment, codefresh
-Deployment Strategies, Etienne Tremel

- - +카나리는 테스트가 부족하거나 신뢰할 수 없는 경우, 새 릴리스의 안정성에 대한 확신이 없는 경우에 주로 사용된다.

+

참고 자료

+

무중단 배포 아키텍처, SAMSUNG SDS
+Rolling Deployments, AWS
+Software Deployment, codefresh
+Deployment Strategies, Etienne Tremel

\ No newline at end of file diff --git a/docs/design/package.html b/docs/design/package.html index d2dccda22..25a710d87 100644 --- a/docs/design/package.html +++ b/docs/design/package.html @@ -1,9 +1,9 @@ - + - -패키지 | GG + +패키지 | GG @@ -12,16 +12,22 @@ - - - + + + -
-

패키지

계층 기반 패키지

전통적인 수평 계층형 아키텍처
-기술적인 관점에서 해당 코드가 하는 일에 기반해 코드를 분할

기능 기반 패키지

서로 연관된 기능, 도메인 개념, 또는 Aggregate Root에 기반하여 수직의 얇은 조각으로 코드를 나누는 방식

포트와 어댑터

업무/도메인에 초점을 둔 코드가 프레임워크 데이터베이스 같은 기술적인 세부 구현과 독립적이며 분리된 아키텍처를 만들기 위해 사용

컴포넌트 기반 패키지

큰 단위의 단일 컴포넌트와 관련된 모든 책임을 하나의 자바 패키지로 묶는 데 주안점을 둠
-모노리틱 애플리케이션에서 컴포넌트를 잘 정의하면 MSA로 가기 위한 발판으로 삼을 수 있음

참고 자료

클린 아키텍처, 로버트 C. 마틴 p.316

- - +

패키지

계층 기반 패키지

+

전통적인 수평 계층형 아키텍처
+기술적인 관점에서 해당 코드가 하는 일에 기반해 코드를 분할

+

기능 기반 패키지

+

서로 연관된 기능, 도메인 개념, 또는 Aggregate Root에 기반하여 수직의 얇은 조각으로 코드를 나누는 방식

+

포트와 어댑터

+

업무/도메인에 초점을 둔 코드가 프레임워크 데이터베이스 같은 기술적인 세부 구현과 독립적이며 분리된 아키텍처를 만들기 위해 사용

+

컴포넌트 기반 패키지

+

큰 단위의 단일 컴포넌트와 관련된 모든 책임을 하나의 자바 패키지로 묶는 데 주안점을 둠
+모노리틱 애플리케이션에서 컴포넌트를 잘 정의하면 MSA로 가기 위한 발판으로 삼을 수 있음

+

참고 자료

+

클린 아키텍처, 로버트 C. 마틴 p.316

\ No newline at end of file diff --git a/docs/etc/communication.html b/docs/etc/communication.html index d47ba1a76..dd2fb9a5d 100644 --- a/docs/etc/communication.html +++ b/docs/etc/communication.html @@ -1,9 +1,9 @@ - + - -커뮤니케이션 잘하는 개발자의 4가지 습관 | GG + +커뮤니케이션 잘하는 개발자의 4가지 습관 | GG @@ -12,16 +12,39 @@ - - - + + + -
-

커뮤니케이션 잘하는 개발자의 4가지 습관

커뮤니케이션 잘 하는 개발자?

스펙 구현형 개발자 vs 문제 해결형 개발자

개발자 != 스펙을 주면 잘 구현하는 사람
-구현에 집중한다면 일의 시야가 좁아진다.

의도와 맥락을 이해해서, 더 좋은 스펙을 만들어내려고 하는 개발자가 되어야 한다.

변화를 만들려면 습관이 필요하다.

주니어 개발자는 스펙 구현 개발자에서 시작한다.
-변화를 위해 실제로 행동하는 습관이 필요하다.

좋은 습관 4가지

  1. 해결하려는 문제의도/상황에 대해 묻는다.
  2. 상대방의 말을 듣고 내가 이해한 바를 요약하여 공유한다.
    • 한 번 정리한다면 1... 2... 이렇게 이해했는데 맞을까요?
  3. 안 된다고 말할 때는 상대방에 관점에서 대안을 제시한다.
    • 제약을 덜 받는 다른 방향성/대안 제시
  4. 문제를 해결할 또 다른 방법은 없을지 고민해본다.
    • 단정대신 한 번 더 질문하고 생각

참고 자료

커뮤니케이션 잘하는 개발자의 4가지 습관 - 송범근, INFCON 2023

- - +

커뮤니케이션 잘하는 개발자의 4가지 습관

커뮤니케이션 잘 하는 개발자?

+

스펙 구현형 개발자 vs 문제 해결형 개발자

+

개발자 != 스펙을 주면 잘 구현하는 사람
+구현에 집중한다면 일의 시야가 좁아진다.

+

의도와 맥락을 이해해서, 더 좋은 스펙을 만들어내려고 하는 개발자가 되어야 한다.

+

변화를 만들려면 습관이 필요하다.

+

주니어 개발자는 스펙 구현 개발자에서 시작한다.
+변화를 위해 실제로 행동하는 습관이 필요하다.

+

좋은 습관 4가지

+
    +
  1. 해결하려는 문제의도/상황에 대해 묻는다.
  2. +
  3. 상대방의 말을 듣고 내가 이해한 바를 요약하여 공유한다. +
      +
    • 한 번 정리한다면 1... 2... 이렇게 이해했는데 맞을까요?
    • +
    +
  4. +
  5. 안 된다고 말할 때는 상대방에 관점에서 대안을 제시한다. +
      +
    • 제약을 덜 받는 다른 방향성/대안 제시
    • +
    +
  6. +
  7. 문제를 해결할 또 다른 방법은 없을지 고민해본다. +
      +
    • 단정대신 한 번 더 질문하고 생각
    • +
    +
  8. +
+

참고 자료

+

커뮤니케이션 잘하는 개발자의 4가지 습관 - 송범근, INFCON 2023

\ No newline at end of file diff --git a/docs/etc/develop-with-spring.html b/docs/etc/develop-with-spring.html index 7502af7a8..5106d4f6b 100644 --- a/docs/etc/develop-with-spring.html +++ b/docs/etc/develop-with-spring.html @@ -1,9 +1,9 @@ - + - -스프링과 함께 더 나은 개발자 되기 | GG + +스프링과 함께 더 나은 개발자 되기 | GG @@ -12,27 +12,34 @@ - - - + + + -
-

스프링과 함께 더 나은 개발자 되기

어떤 기술을 통해서도 성장할 수 있다.

실전 사용

단순 기술의 사용으로는 성장이 어렵다.
-실전 적용으로 성장할 수 있다.

질문과 탐구

내가 사용하는 기술은 왜 이렇게 만들어졌는가?
+

스프링과 함께 더 나은 개발자 되기

어떤 기술을 통해서도 성장할 수 있다.

+

실전 사용

+

단순 기술의 사용으로는 성장이 어렵다.
+실전 적용으로 성장할 수 있다.

+

질문과 탐구

+

내가 사용하는 기술은 왜 이렇게 만들어졌는가?
나는 왜 이렇게 설계하고, 코드를 작성해야 하는가?
장단점은 무엇인가?
다른 대안은 없을까?
-지금도 좋긴한데 다음에는 개선할 부분이 있을까?

훈련과 개선

배운 것을 응용해보는 코딩을 꾸준히
+지금도 좋긴한데 다음에는 개선할 부분이 있을까?

+

훈련과 개선

+

배운 것을 응용해보는 코딩을 꾸준히
튜토리얼 예제를 반복해서 작성
새로운 기능을 추가하고 설계 구조를 변경해보는 시도
실무에서 사용하지 못했던 기술 도입
연습용 애플리케이션을 구상하고 설계
-초기 개발 생산성, 변경 용이성 등을 관찰

공유와 논쟁

문서, 발표 자료로 정리
+초기 개발 생산성, 변경 용이성 등을 관찰

+

공유와 논쟁

+

문서, 발표 자료로 정리
정리에 시간을 많이 들이면 효율성이 떨어지기에 중요한 부분만 정리
간단한 작성, 검색이 가능한 도구 활용
-나만의 정의와 설명을 만들어가기 -> 한 문장, 한 문단, 5분간 설명, 점점 늘려가며

참고 자료

스프링과 함께 더 나은 개발자 되기 - 토비, INFCON 2023

- - +나만의 정의와 설명을 만들어가기 -> 한 문장, 한 문단, 5분간 설명, 점점 늘려가며

+

참고 자료

+

스프링과 함께 더 나은 개발자 되기 - 토비, INFCON 2023

\ No newline at end of file diff --git a/docs/etc/experience-and-self-question.html b/docs/etc/experience-and-self-question.html index 766eb1541..9525a9631 100644 --- a/docs/etc/experience-and-self-question.html +++ b/docs/etc/experience-and-self-question.html @@ -1,9 +1,9 @@ - + - -경험과 질문 | GG + +경험과 질문 | GG @@ -12,23 +12,24 @@ - - - + + + -
-

경험과 질문

우아한테크코스 2023년 10월 6일
-포비 특강

자기 주도적으로 문제를 해결하기 위한 도전 경험

팀 프로젝트에서 발생한 팀원 간의 갈등을 해결하기 위해 도전한 경험
+

경험과 질문

우아한테크코스 2023년 10월 6일
+포비 특강

+

자기 주도적으로 문제를 해결하기 위한 도전 경험

+

팀 프로젝트에서 발생한 팀원 간의 갈등을 해결하기 위해 도전한 경험
팀 프로젝트에서 실 사용자를 모집하기 위해 도전한 경험
팀에서 관심을 가지지 않는 문제를 해결하기 위해 끝까지 도전한 경험
내가 끌리는 주제에 대해 깊이 있게 학습하고 프로젝트에 적용한 경험
-사용자 경험을 한 단계 더 높이기 위해 도전한 경험
-당연하다 생각하는 해결책에 의구심을 가지고 새로운 접근 방식으로 도전한 경험

자신에게 던져봐야할 질문

나는 프로그래밍 자체를 즐기고 있는가?
+사용자 경험을 한 단계 더 높이기 위해 도전한 경험
+당연하다 생각하는 해결책에 의구심을 가지고 새로운 접근 방식으로 도전한 경험

+

자신에게 던져봐야할 질문

+

나는 프로그래밍 자체를 즐기고 있는가?
나는 왜 프로그래머가 되려고 하는가?
나는 나답게 살고 있나?
-나는 주도적으로 살고 있나?

- - +나는 주도적으로 살고 있나?

\ No newline at end of file diff --git a/docs/etc/healthful-growth.html b/docs/etc/healthful-growth.html index e0f680c73..b9780b13e 100644 --- a/docs/etc/healthful-growth.html +++ b/docs/etc/healthful-growth.html @@ -1,9 +1,9 @@ - + - -건강하게 나아지기 | GG + +건강하게 나아지기 | GG @@ -12,32 +12,48 @@ - - - + + + -
-

건강하게 나아지기

우아한테크코스 2023년 4월 19일
-이동욱님 특강

자존감 기둥 만들기

뛰어난 동료, 새로운 환경 그리고 프로젝트를 실패하면서 자존감이 떨어질 수 있다.
-자존감이 무너지지 않도록 나를 지탱할 수 있는 기둥이 필요하다. (한 개가 아닌 여러 개)

나만의 학습 방법 찾기

회사 일을 지속적으로 한다면 회사 일의 숙련자가 되지만, 개발 전문가가 되지 않는다.
+

건강하게 나아지기

우아한테크코스 2023년 4월 19일
+이동욱님 특강

+

자존감 기둥 만들기

+

뛰어난 동료, 새로운 환경 그리고 프로젝트를 실패하면서 자존감이 떨어질 수 있다.
+자존감이 무너지지 않도록 나를 지탱할 수 있는 기둥이 필요하다. (한 개가 아닌 여러 개)

+

나만의 학습 방법 찾기

+

회사 일을 지속적으로 한다면 회사 일의 숙련자가 되지만, 개발 전문가가 되지 않는다.
주니어 일때는 성과가 아닌 학습으로!
-지속적으로 성장할 수 있는 사람인지? 고민하기

동욱님이 그동안 시도한 방법

사이드 프로젝트 진행하기 → A-Z 구현 경험
+지속적으로 성장할 수 있는 사람인지? 고민하기

+

동욱님이 그동안 시도한 방법

+

사이드 프로젝트 진행하기 → A-Z 구현 경험
책 스터디 → 높은 완주율, 하지만 내가 발표한 주제만 기억에 남는다.
강의 준비 → 100% 내용 습득, 낮은 시간 가성비, 강의 외적인 부가작업
-블로그 → 온라인 모두가 리뷰어, 동료와 공유 가능, 피드백의 부끄러움 😳

실패하거나, 잘못 적어도 남들의 시선보단 나 자신의 성장이 중요하다.
+블로그 → 온라인 모두가 리뷰어, 동료와 공유 가능, 피드백의 부끄러움 😳

+

실패하거나, 잘못 적어도 남들의 시선보단 나 자신의 성장이 중요하다.
가능하면 인증되고, 정제된 자료로 습득한다.
-나에게 맞는 가장 효율이 좋은 학습 방법으로 찾고, 수시로 점검하여 더 좋은 방법을 찾고 시도한다.

새로운 환경을 잘 배우는 방법

시간 > 돈이기 때문에 시간을 돈으로 구매하자.
+나에게 맞는 가장 효율이 좋은 학습 방법으로 찾고, 수시로 점검하여 더 좋은 방법을 찾고 시도한다.

+

새로운 환경을 잘 배우는 방법

+

시간 > 돈이기 때문에 시간을 돈으로 구매하자.
신뢰할만한 분께 질문 또는 코드 리뷰가 가능한 강의를 구매한다.
-어떤 학습 방식, 언제 집중이 잘 되는지, 어떤 환경에서 집중이 잘 되는지 확인한다.

학습 주제

회사 업무에서 만난 문제를 연구, 정리, 해결해서 커뮤니티에 공유하고 피드백을 받는다.
-주변 동료들에게 인정받는게 우선이다.

산만함 관리하기

컨텍스트 스위칭이 자주 일어나면 산만해지기 때문에 집중할 수 있는 환경을 가져야 한다.
-ex) 집중이 잘 되는 환경 구성하기, 출근 전 1~2시간 집중하고 출근하기, 점심 저녁 산책하기, 주 2~3회 운동하기

거인에 어깨위에 올라타기

뛰어난 사람 옆에서 배워야 한다.
-C레벨, 테크 리드와 같이 일할 수 있는 것은 큰 기회다.
-커뮤니케이션 방법, 신뢰 자산을 확보하는 방법, 문화를 만들어가는 방법, 결정의 기준과 같은 부분을 학습할 수 있다.

보상

시련 뒤에는 항상 보물이 기다리고 있다.
-보상을 통해 꾸준함을 유지할 수 있도록 만들어라.

남을 설득하는 방법 배우기

팀원들이 매번 내 의견을 반대한다면 완벽한 논리가 중요한게 아니다.
+어떤 학습 방식, 언제 집중이 잘 되는지, 어떤 환경에서 집중이 잘 되는지 확인한다.

+

학습 주제

+

회사 업무에서 만난 문제를 연구, 정리, 해결해서 커뮤니티에 공유하고 피드백을 받는다.
+주변 동료들에게 인정받는게 우선이다.

+

산만함 관리하기

+

컨텍스트 스위칭이 자주 일어나면 산만해지기 때문에 집중할 수 있는 환경을 가져야 한다.
+ex) 집중이 잘 되는 환경 구성하기, 출근 전 12시간 집중하고 출근하기, 점심 저녁 산책하기, 주 23회 운동하기

+

거인에 어깨위에 올라타기

+

뛰어난 사람 옆에서 배워야 한다.
+C레벨, 테크 리드와 같이 일할 수 있는 것은 큰 기회다.
+커뮤니케이션 방법, 신뢰 자산을 확보하는 방법, 문화를 만들어가는 방법, 결정의 기준과 같은 부분을 학습할 수 있다.

+

보상

+

시련 뒤에는 항상 보물이 기다리고 있다.
+보상을 통해 꾸준함을 유지할 수 있도록 만들어라.

+

남을 설득하는 방법 배우기

+

팀원들이 매번 내 의견을 반대한다면 완벽한 논리가 중요한게 아니다.
어떻게 하면 신뢰 자산을 확보할 수 있는가?
-커뮤니케이션, 협업, 소프트 스킬에서 부족함이 있으면 안된다.

- - +커뮤니케이션, 협업, 소프트 스킬에서 부족함이 있으면 안된다.

\ No newline at end of file diff --git a/docs/java/sequenced-collection.html b/docs/java/sequenced-collection.html index 8e55d00e0..ea2f1eb42 100644 --- a/docs/java/sequenced-collection.html +++ b/docs/java/sequenced-collection.html @@ -1,9 +1,9 @@ - + - -SequencedCollection | GG + +SequencedCollection | GG @@ -12,17 +12,50 @@ - - - + + + -
-

SequencedCollection

JEP 431: Sequenced Collections

첫 번째, 마지막 원소를 접근할 때 번거로운 부분이 해결되었다.
+

SequencedCollection

JEP 431: Sequenced Collections

+

첫 번째, 마지막 원소를 접근할 때 번거로운 부분이 해결되었다.
기존의 자바의 리스트를 사용하는 경우 list.get(0)이나 list.get(list.size() - 1)를 사용했어야 했다.
-자바 21에서 추가된 Sequenced Collections을 이용하면 간편하게 해당 기능을 사용할 수 있다.

./SequencedCollectionDiagram.png

SequencedCollection

기존의 Deque를 사용하는 것 처럼 편 하게 사용할 수 있다.
-reversed의 경우 순서만 반대로 제공하는 컬렉션의 뷰를 반환한다.

SequencedCollection
interface SequencedCollection<E> extends Collection<E> {
SequencedCollection<E> reversed();
void addFirst(E);
void addLast(E);
E getFirst();
E getLast();
E removeFirst();
E removeLast();
}

SequencedSet

SequencedSet
interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {
SequencedSet<E> reversed(); // covariant override
}

SequencedMaps

firstEntry, lastEntry의 경우 키 값을 기준으로 결정된다.

SequencedMap
interface SequencedMap<K,V> extends Map<K,V> {
SequencedMap<K,V> reversed();
SequencedSet<K> sequencedKeySet();
SequencedCollection<V> sequencedValues();
SequencedSet<Entry<K,V>> sequencedEntrySet();
V putFirst(K, V);
V putLast(K, V);
Entry<K, V> firstEntry();
Entry<K, V> lastEntry();
Entry<K, V> pollFirstEntry();
Entry<K, V> pollLastEntry();
}

참고 자료 및 이미지 출처

SequencedCollection, openjdk

- - +자바 21에서 추가된 Sequenced Collections을 이용하면 간편하게 해당 기능을 사용할 수 있다.

+

./SequencedCollectionDiagram.png

+

SequencedCollection

+

기존의 Deque를 사용하는 것 처럼 편 하게 사용할 수 있다.
+reversed의 경우 순서만 반대로 제공하는 컬렉션의 뷰를 반환한다.

+
interface SequencedCollection<E> extends Collection<E> {
+    SequencedCollection<E> reversed();
+    void addFirst(E);
+    void addLast(E);
+    E getFirst();
+    E getLast();
+    E removeFirst();
+    E removeLast();
+}
+
+

SequencedSet

+
interface SequencedSet<E> extends Set<E>, SequencedCollection<E> {
+    SequencedSet<E> reversed(); // covariant override
+}
+
+

SequencedMaps

+

firstEntry, lastEntry의 경우 키 값을 기준으로 결정된다.

+
interface SequencedMap<K,V> extends Map<K,V> {
+    SequencedMap<K,V> reversed();
+    SequencedSet<K> sequencedKeySet();
+    SequencedCollection<V> sequencedValues();
+    SequencedSet<Entry<K,V>> sequencedEntrySet();
+    V putFirst(K, V);
+    V putLast(K, V);
+    Entry<K, V> firstEntry();
+    Entry<K, V> lastEntry();
+    Entry<K, V> pollFirstEntry();
+    Entry<K, V> pollLastEntry();
+}
+
+

참고 자료 및 이미지 출처

+

SequencedCollection, openjdk

\ No newline at end of file diff --git a/docs/jpa/key.html b/docs/jpa/key.html index 6b86cd8a5..75ff1a0bd 100644 --- a/docs/jpa/key.html +++ b/docs/jpa/key.html @@ -1,9 +1,9 @@ - + - -기본 키 매핑 | GG + +기본 키 매핑 | GG @@ -12,25 +12,97 @@ - - - + + + -
-

기본 키 매핑

기본 키 매핑

기본 키 매핑 전략에는 직접 할당하는 방법이 있고 자동 생성해서 사용하는 방법이 있다.
-자동 생성을 선택한다면 애플리케이션에서 키에 대한 부분을 직접 할당하지 않고, 데이터베이스가 생성해주는 값을 사용할 수 있다.

직접 할당

기본 키를 직접 할당하는 경우에 @Id만 사용한다.
-자동 할당하는 경우 @Id에 추가적으로 @GeneratedValue를 사용해야 한다.

IDENTITY

데이터베이스가 생성한 키를 사용하는 전략
+

기본 키 매핑

기본 키 매핑

+

기본 키 매핑 전략에는 직접 할당하는 방법이 있고 자동 생성해서 사용하는 방법이 있다.
+자동 생성을 선택한다면 애플리케이션에서 키에 대한 부분을 직접 할당하지 않고, 데이터베이스가 생성해주는 값을 사용할 수 있다.

+

직접 할당

+

기본 키를 직접 할당하는 경우에 @Id만 사용한다.
+자동 할당하는 경우 @Id에 추가적으로 @GeneratedValue를 사용해야 한다.

+

IDENTITY

+

데이터베이스가 생성한 키를 사용하는 전략
MySQL, PostgreSQL과 같은 DB에서 주로 사용한다.
-Hibernate는 JDBC3에 추가된 Statement.getGeneratedKeys()를 사용하여 생성과 동시에 키 값을 얻어 올 수 있다.

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Member {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
}

SEQUENCE

시퀀스는 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트다.
+Hibernate는 JDBC3에 추가된 Statement.getGeneratedKeys()를 사용하여 생성과 동시에 키 값을 얻어 올 수 있다.

+
@Getter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Entity
+public class Member {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+}
+
+

SEQUENCE

+

시퀀스는 유일한 값을 순서대로 생성하는 데이터베이스 오브젝트다.
IDENTITY의 경우 데이터베이스에 저장한 후 식별자를 조회해서 엔티티의 식별자에 할당한다.
-SEQUENCE의 경우 call next value for member_seq와 같이 시퀀스를 사용해서 식별자를

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@SequenceGenerator(
name = "MEMBER_SEQ_GENERATOR",
sequenceName = "MEMBER_SEQ",
initialValue = 1,
allocationSize = 1
)
@Entity
public class Member {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
private Long id;
}

TABLE

키 생성용 테이블을 별도로 두어 시퀀스와 유사하게 식별자 키를 얻는 전략이다.
-조회와 업데이트를 해야한다는 단점이 있다.

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@TableGenerator(
name = "MEMBER_SEQ_GENERATOR",
table = "MEMBER_SEQUENCES",
pkColumnValue = "MEMBER_SEQ",
allocationSize = 1
)
@Entity
public class Member {

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
private Long id;
}

AUTO

데이터베이스에 따라 위에 언급된 전략 중 하나를 자동으로 선택한다.
-MySQL의 경우 IDENTITY Oracle의 경우 SEQUENCE를 선택한다.

UUID

JPA 3.1.0 UUID 생성 전략이 추가되었다.
-Hibernate 6.2부터 JPA 3.1.0을 지원하기 때문에 스프링 부트 3.1 이상인 경우 사용할 수 있다.

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Entity
public class Member {

@Id
@GeneratedValue(strategy = GenerationType.UUID)
@UuidGenerator(style = Style.RANDOM)
private Long id;
}

UuidGenerator를 이용하여 UUID 생성 방식도 설정할 수 있다.
-생성 방식은 3가지가 있다.

  • RANDOM - 난수 기반 UUID 생성(uuid v4)
  • TIME – 시간 기반 UUID 생성(uuid v1)
  • AUTO – 기본 옵션, RANDOM과 동일

UUID의 경우 많은 양의 저장 공간을 필요로 하고, 성능 문제가 발생할 수 있기에 UUID를 사용해야 하는 경우 TSID를 고려할 수 있을 것 같다.

참고 자료

자바 ORM 표준 JPA 프로그래밍, 김영한 p.131 ~ p.144
-Generate UUIDs as Primary Keys With Hibernate

- - +SEQUENCE의 경우 call next value for member_seq와 같이 시퀀스를 사용해서 식별자를

+
@Getter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@SequenceGenerator(
+        name = "MEMBER_SEQ_GENERATOR",
+        sequenceName = "MEMBER_SEQ",
+        initialValue = 1,
+        allocationSize = 1
+)
+@Entity
+public class Member {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "MEMBER_SEQ_GENERATOR")
+    private Long id;
+}
+
+

TABLE

+

키 생성용 테이블을 별도로 두어 시퀀스와 유사하게 식별자 키를 얻는 전략이다.
+조회와 업데이트를 해야한다는 단점이 있다.

+
@Getter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@TableGenerator(
+        name = "MEMBER_SEQ_GENERATOR",
+        table = "MEMBER_SEQUENCES",
+        pkColumnValue = "MEMBER_SEQ",
+        allocationSize = 1
+)
+@Entity
+public class Member {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.TABLE, generator = "MEMBER_SEQ_GENERATOR")
+    private Long id;
+}
+
+

AUTO

+

데이터베이스에 따라 위에 언급된 전략 중 하나를 자동으로 선택한다.
+MySQL의 경우 IDENTITY Oracle의 경우 SEQUENCE를 선택한다.

+

UUID

+

JPA 3.1.0 UUID 생성 전략이 추가되었다.
+Hibernate 6.2부터 JPA 3.1.0을 지원하기 때문에 스프링 부트 3.1 이상인 경우 사용할 수 있다.

+
@Getter
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Entity
+public class Member {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.UUID)
+    @UuidGenerator(style = Style.RANDOM)
+    private Long id;
+}
+
+

UuidGenerator를 이용하여 UUID 생성 방식도 설정할 수 있다.
+생성 방식은 3가지가 있다.

+
    +
  • RANDOM - 난수 기반 UUID 생성(uuid v4)
  • +
  • TIME – 시간 기반 UUID 생성(uuid v1)
  • +
  • AUTO – 기본 옵션, RANDOM과 동일
  • +
+

UUID의 경우 많은 양의 저장 공간을 필요로 하고, 성능 문제가 발생할 수 있기에 UUID를 사용해야 하는 경우 TSID를 고려할 수 있을 것 같다.

+

참고 자료

+

자바 ORM 표준 JPA 프로그래밍, 김영한 p.131 ~ p.144
+Generate UUIDs as Primary Keys With Hibernate

\ No newline at end of file diff --git a/docs/linux/shell.html b/docs/linux/shell.html index 35b226281..b9ebd1369 100644 --- a/docs/linux/shell.html +++ b/docs/linux/shell.html @@ -1,9 +1,9 @@ - + - -터미널 쉘 프롬프트 설정 | GG + +터미널 쉘 프롬프트 설정 | GG @@ -12,18 +12,37 @@ - - - + + + -
-

터미널 쉘 프롬프트 설정

계정 별 터미널 설정

PS1은 리눅스 기반 운영 체제에서 사용자의 쉘 프롬프트를 설정하기 위해 사용되는 환경 변수다.
+

터미널 쉘 프롬프트 설정

계정 별 터미널 설정

+

PS1은 리눅스 기반 운영 체제에서 사용자의 쉘 프롬프트를 설정하기 위해 사용되는 환경 변수다.
해당 환경 변수를 변경하면 사용자명, 시간 정보 등 필요한 정보를 원하는 대로 설정할 수 있다.
-~/.bashrc 파일에 PS1에 대한 값을 설정하여 동일한 계정으로 재접속하여도 설정을 유지할 수 있다.

이스케이프 문자

이스케이프 문자를 사용하여 쉘 프롬프트에 서버에 대한 정보를 추가할 수 있다.

이스케이프 문자설명
\u사용자 이름
\h호스트 이름
\w현재 작업 디렉토리 (전체 경로)
\W현재 작업 디렉토리 (디렉토리 이름)
\d현재 날짜 (YYYY-MM-DD)
\t현재 시간 (HH:MM:SS)
\n줄 바꿈 문자
\$일반 사용자 $ root의 경우 #

색상 설정

\e[ - 색상 변경을 시작하고 싶을 때 사용한다.
+~/.bashrc 파일에 PS1에 대한 값을 설정하여 동일한 계정으로 재접속하여도 설정을 유지할 수 있다.

+

이스케이프 문자

+

이스케이프 문자를 사용하여 쉘 프롬프트에 서버에 대한 정보를 추가할 수 있다.

+
이스케이프 문자설명
\u사용자 이름
\h호스트 이름
\w현재 작업 디렉토리 (전체 경로)
\W현재 작업 디렉토리 (디렉토리 이름)
\d현재 날짜 (YYYY-MM-DD)
\t현재 시간 (HH:MM:SS)
\n줄 바꿈 문자
$일반 사용자 $ root의 경우 #
+

색상 설정

+

\e[ - 색상 변경을 시작하고 싶을 때 사용한다.
색상코드m - 색상을 선택한다.
-\e[0m - 색상 변경을 종료하고 싶을 때 사용한다.

빨간색 hello world → "\e[31mhello world!\e[0m"

echo -e 옵션을 사용하여 색상이 정상적으로 적용되었는지 확인할 수 있다.

echo -e "\e[31mhello world! \e[0m"

색상표

색상글자색배경색
Black3040
Red3141
Green3242
Yellow3343
Blue3444
Purple3545
Cyan3646
White3747

~/.bashrc 파일에 적용

sudo vim ~/.bashrc 을 입력하여 설정 파일을 연 후에 적용하고 싶은 문자를 PS1 환경변수에 할당하고 저장한다.

~/.bashrc
PS1="\e[32m[\t TRIPDRAW-DEV \u]\$ \e[0m"

적용은 source 명령어를 이용하면 된다.

source ~/.bashrc

참고 자료

Linux Hint

- - +\e[0m - 색상 변경을 종료하고 싶을 때 사용한다.

+
빨간색 hello world → "\e[31mhello world!\e[0m"
+
+

echo -e 옵션을 사용하여 색상이 정상적으로 적용되었는지 확인할 수 있다.

+
echo -e "\e[31mhello world! \e[0m"
+
+

색상표

+
색상글자색배경색
Black3040
Red3141
Green3242
Yellow3343
Blue3444
Purple3545
Cyan3646
White3747
+

~/.bashrc 파일에 적용

+

sudo vim ~/.bashrc 을 입력하여 설정 파일을 연 후에 적용하고 싶은 문자를 PS1 환경변수에 할당하고 저장한다.

+
PS1="\e[32m[\t TRIPDRAW-DEV \u]\$ \e[0m"
+
+

적용은 source 명령어를 이용하면 된다.

+
source ~/.bashrc
+
+

참고 자료

+

Linux Hint

\ No newline at end of file diff --git a/docs/linux/swap.html b/docs/linux/swap.html index ac1691897..723e7def3 100644 --- a/docs/linux/swap.html +++ b/docs/linux/swap.html @@ -1,9 +1,9 @@ - + - -Swap 메모리 설정 | GG + +Swap 메모리 설정 | GG @@ -12,19 +12,62 @@ - - - + + + -
-

Swap 메모리 설정

Swap 메모리

하드디스크 공간의 일부분을 메모리로 사용하는 방법이다.
-하드디스크를 사용하는 만큼 기존 메모리보다 속도가 현저히 떨어진다.

설정

보통 Swap 파일의 용량은 기존 메모리의 1.5~2배 정도의 용량을 권장하고 있다.
-fallocate또는 dd 명령어를 이용하여 스왑 파일을 생성할 수 있다.

# fallocate
sudo fallocate -l 2G /swapfile

# dd
sudo dd if=/dev/zero of=/swapfile bs=1MiB count=2048

일반 사용자가 해당 파일에 접근할 수 없도록 권한을 설정한다.

sudo chmod 600 /swapfile
  • 파일을 Swap 포맷으로 변경 후 시스템에 등록한다.
sudo mkswap /swapfile
sudo swapon /swapfile

Swap 메모리 부팅시 자동으로 마운트하도록 적용

인스턴스가 종료되거나 재부팅을 하는 경우 Swap 설정이 초기화된다.
-/etc/fstab 파일을 수정하여 Swap 메모리를 영구적으로 적용할 수 있다.

  • 해당 파일은 리눅스 부팅시 마운트정보를 저장하고 있다.
# vim을 이용하여 해당 파일을 수정한다.
sudo vim /etc/fstab
# 최하단에 다음과 같이 설정하면 된다.
/swapfile swap swap defaults 0 0

Swap 메모리 적용되었는지 확인

리눅스에서는 free 명령어를 통해 메모리를 확인할 수 있다.
--h 옵션을 주면 좀 더 읽기 편한 형태로 출력된다.

free -h
total used free shared buff/cache available
Mem: 905Mi 570Mi 65Mi 0.0Ki 270Mi 186Mi
Swap: 2.0Gi 626Mi 1.4Gi

아래에 Swap 메모리가 적용되어있는 것을 확인할 수 있다.
-추가로 swapon 명령어로도 확인할 수 있다.

Swap 메모리 비활성화

swapoff 명령어를 사용하여 비활성화 한 후 파일을 삭제하면 된다.

# swap 설정한 파일 비활성화
sudo swapoff -v /swapfile
# 삭제
sudo rm /swapfile

만약 /etc/fstab에 값을 설정했을 경우 해당 값을 지워야한다.

참고 자료

How to Add Swap Space on Ubuntu 20.04, Lunuxize

- - +

Swap 메모리 설정

Swap 메모리

+

하드디스크 공간의 일부분을 메모리로 사용하는 방법이다.
+하드디스크를 사용하는 만큼 기존 메모리보다 속도가 현저히 떨어진다.

+

설정

+

보통 Swap 파일의 용량은 기존 메모리의 1.5~2배 정도의 용량을 권장하고 있다.
+fallocate또는 dd 명령어를 이용하여 스왑 파일을 생성할 수 있다.

+
# fallocate
+sudo fallocate -l 2G /swapfile
+
+# dd
+sudo dd if=/dev/zero of=/swapfile bs=1MiB count=2048
+
+

일반 사용자가 해당 파일에 접근할 수 없도록 권한을 설정한다.

+
sudo chmod 600 /swapfile
+
+
    +
  • 파일을 Swap 포맷으로 변경 후 시스템에 등록한다.
  • +
+
sudo mkswap /swapfile
+sudo swapon /swapfile
+
+

Swap 메모리 부팅시 자동으로 마운트하도록 적용

+

인스턴스가 종료되거나 재부팅을 하는 경우 Swap 설정이 초기화된다.
+/etc/fstab 파일을 수정하여 Swap 메모리를 영구적으로 적용할 수 있다.

+
    +
  • 해당 파일은 리눅스 부팅시 마운트정보를 저장하고 있다.
  • +
+
# vim을 이용하여 해당 파일을 수정한다.
+sudo vim /etc/fstab
+# 최하단에 다음과 같이 설정하면 된다.
+/swapfile swap swap defaults 0 0
+
+

Swap 메모리 적용되었는지 확인

+

리눅스에서는 free 명령어를 통해 메모리를 확인할 수 있다.
+-h 옵션을 주면 좀 더 읽기 편한 형태로 출력된다.

+
free -h
+              total        used        free      shared  buff/cache   available
+Mem:          905Mi       570Mi        65Mi       0.0Ki       270Mi       186Mi
+Swap:         2.0Gi       626Mi       1.4Gi
+
+

아래에 Swap 메모리가 적용되어있는 것을 확인할 수 있다.
+추가로 swapon 명령어로도 확인할 수 있다.

+

Swap 메모리 비활성화

+

swapoff 명령어를 사용하여 비활성화 한 후 파일을 삭제하면 된다.

+
# swap 설정한 파일 비활성화
+sudo swapoff -v /swapfile
+# 삭제
+sudo rm /swapfile
+
+

만약 /etc/fstab에 값을 설정했을 경우 해당 값을 지워야한다.

+

참고 자료

+

How to Add Swap Space on Ubuntu 20.04, Lunuxize

\ No newline at end of file diff --git a/docs/mac/java.html b/docs/mac/java.html index 0c57d0c94..7c502ec9d 100644 --- a/docs/mac/java.html +++ b/docs/mac/java.html @@ -1,9 +1,9 @@ - + - -맥 OS 자바 버전 변경 | GG + +맥 OS 자바 버전 변경 | GG @@ -12,14 +12,28 @@ - - - + + + -
-

맥 OS 자바 버전 변경

설치된 자바 버전 확인

/usr/libexec/java_home -V

자바 설치

brew를 최신 버전으로 업데이트하고 jdk를 검색한다.

brew update
brew search jdk

필요한 버전을 선택하여 설치한다.

brew install openjdk@11

자바 11 버전으로 변경

export JAVA_HOME=$(/usr/libexec/java_home -v 11)

터미널 재시작시에도 자바 버전 유지

~/.zshrc 파일 아래 JAVA_HOME 환경변수 설정 명령어를 추가한다.

~/.zshrc
export JAVA_HOME=$(/usr/libexec/java_home -v 11)
- - +

맥 OS 자바 버전 변경

설치된 자바 버전 확인

+
/usr/libexec/java_home -V
+
+

자바 설치

+

brew를 최신 버전으로 업데이트하고 jdk를 검색한다.

+
brew update
+brew search jdk
+
+

필요한 버전을 선택하여 설치한다.

+
brew install openjdk@11
+
+

자바 11 버전으로 변경

+
export JAVA_HOME=$(/usr/libexec/java_home -v 11)
+
+

터미널 재시작시에도 자바 버전 유지

+

~/.zshrc 파일 아래 JAVA_HOME 환경변수 설정 명령어를 추가한다.

+
export JAVA_HOME=$(/usr/libexec/java_home -v 11)
+
\ No newline at end of file diff --git a/docs/monitoring/intro.html b/docs/monitoring/intro.html index 52ae2a6bd..440e08cde 100644 --- a/docs/monitoring/intro.html +++ b/docs/monitoring/intro.html @@ -1,9 +1,9 @@ - + - -모니터링 환경 구성 | GG + +모니터링 환경 구성 | GG @@ -12,22 +12,33 @@ - - - + + + -
-

모니터링 환경 구성

모니터링 3단계

대시보드
+

모니터링 환경 구성

모니터링 3단계

+

대시보드
애플리케이션 추적 - 핀포인트
-로그

모니터링 대상

시스템 메트릭(CPU, 메모리)
+로그

+

모니터링 대상

+

시스템 메트릭(CPU, 메모리)
애플리케이션 메트릭(Thread Pool, Connection Pool, 호출 수)
-비즈니스 메트릭

애플리케이션 추적

각각의 HTTP 요청 추적
-핀포인트, 스카우트, 와탭, 제니퍼

로그

가장 세세한 추적
+비즈니스 메트릭

+

애플리케이션 추적

+

각각의 HTTP 요청 추적
+핀포인트, 스카우트, 와탭, 제니퍼

+

로그

+

가장 세세한 추적
같은 HTTP 요청을 묶어서 확인할 수 있는 방법이 중요하다.
-MDC(Mapped Diagnostic Context) 적용

파일로 직접 로그를 남기는 경우 → 일반 로그와 에러 로그 파일을 구분해서 남겨야 한다.
-클라우드에 저장하는 경우 → 검색이 잘 되도록 구분한다.

모니터링

관찰의 경우 전체 → 좁게

알람

알람의 경우 2가지 종류(경고, 심각)로 구분해서 관리한다.

참고 자료

스프링 부트 핵심 원리와 활용, 김영한

- - +MDC(Mapped Diagnostic Context) 적용

+

파일로 직접 로그를 남기는 경우 → 일반 로그와 에러 로그 파일을 구분해서 남겨야 한다.
+클라우드에 저장하는 경우 → 검색이 잘 되도록 구분한다.

+

모니터링

+

관찰의 경우 전체 → 좁게

+

알람

+

알람의 경우 2가지 종류(경고, 심각)로 구분해서 관리한다.

+

참고 자료

+

스프링 부트 핵심 원리와 활용, 김영한

\ No newline at end of file diff --git a/docs/network/load-balancing-algorithm.html b/docs/network/load-balancing-algorithm.html index 5adc780a5..547a1e3f9 100644 --- a/docs/network/load-balancing-algorithm.html +++ b/docs/network/load-balancing-algorithm.html @@ -1,9 +1,9 @@ - + - -로드 밸런싱 알고리즘 | GG + +로드 밸런싱 알고리즘 | GG @@ -12,18 +12,43 @@ - - - + + + -
-

로드 밸런싱 알고리즘

라운드로빈 방식(Round Robin Method)

클라이언트로부터 받은 요청을 로드 밸런싱 대상 서버에 순서대로 할당받는 방식

가중 기반 라운드 로빈 방식(Weighted Round Robin Method)

실제 서버에 서로 다른 처리 용량을 지정하는 방식

최소 연결 기반 방식(Least Connection Method)

로드 밸런서는 활성 연결이 가장 적은 서버를 확인하고 해당 서버로 트래픽을 전송

IP 해시 방식(IP Hash Method)

각 클라이언트에 대해 Hashing key를 가지고 경로를 지정
+

로드 밸런싱 알고리즘

라운드로빈 방식(Round Robin Method)

+

클라이언트로부터 받은 요청을 로드 밸런싱 대상 서버에 순서대로 할당받는 방식

+ +

가중 기반 라운드 로빈 방식(Weighted Round Robin Method)

+

실제 서버에 서로 다른 처리 용량을 지정하는 방식

+ +

최소 연결 기반 방식(Least Connection Method)

+

로드 밸런서는 활성 연결이 가장 적은 서버를 확인하고 해당 서버로 트래픽을 전송

+ +

IP 해시 방식(IP Hash Method)

+

각 클라이언트에 대해 Hashing key를 가지고 경로를 지정
Hashing key는 클라이언트의 IP + port 혹은 IP 주소만으로 결정
-사용자가 항상 동일한 서버로 연결되는 것을 보장

최소 응답 시간 방식(Least Response Time Method)

서버의 현재 연결 상태, 응답 시간 고려하여 트래픽을 전송
-가장 적은 연결 상태와 가장 짧은 응답 시간을 보이는 서버에 우선적으로 로드를 배분하는 방식

참고 자료

load balancing, AWS
-로드 밸런싱에 대해 알아보자, 테코블

- - +사용자가 항상 동일한 서버로 연결되는 것을 보장

+ +

최소 응답 시간 방식(Least Response Time Method)

+

서버의 현재 연결 상태, 응답 시간 고려하여 트래픽을 전송
+가장 적은 연결 상태와 가장 짧은 응답 시간을 보이는 서버에 우선적으로 로드를 배분하는 방식

+ +

참고 자료

+

load balancing, AWS
+로드 밸런싱에 대해 알아보자, 테코블

\ No newline at end of file diff --git a/docs/network/load-balancing.html b/docs/network/load-balancing.html index 05ee7461a..5ed43b2f8 100644 --- a/docs/network/load-balancing.html +++ b/docs/network/load-balancing.html @@ -1,9 +1,9 @@ - + - -로드 밸런싱 | GG + +로드 밸런싱 | GG @@ -12,21 +12,32 @@ - - - + + + -
-

로드 밸런싱

로드 밸런싱이란?

서버가 처리해야 할 요청을 여러 대의 서버로 나누어 처리하는 것을 의미한다.
-로드 밸런싱은 로드 밸런서를 통해 이루어진다.

로드 밸런싱과 로드 밸런서

로드 밸런싱: 애플리케이션을 지원하는 리소스 풀 전체에 네트워크 트래픽을 균등하게 배포하는 방법
-로드 밸런서: 사용자와 서버 그룹 사이에 위치하며 보이지 않는 촉진자 역할을 하여 모든 리소스 서버가 동일하게 사용되도록 하는 디바이스

로드 밸런싱의 장점

가용성

서버에 문제가 발생하는 경우 로드밸런서가 해당 문제를 감지(헬스 체크를 통해)하여 트래픽을 사용 가능한 서버로 보냄으로써 내결함성을 높힌다.
-로드밸런서를 활용한 무중단 배포

확장성

수평 확장성(Horizontal Scalability) 용이
+

로드 밸런싱

로드 밸런싱이란?

+

서버가 처리해야 할 요청을 여러 대의 서버로 나누어 처리하는 것을 의미한다.
+로드 밸런싱은 로드 밸런서를 통해 이루어진다.

+

로드 밸런싱: 애플리케이션을 지원하는 리소스 풀 전체에 네트워크 트래픽을 균등하게 배포하는 방법
+로드 밸런서: 사용자와 서버 그룹 사이에 위치하며 보이지 않는 촉진자 역할을 하여 모든 리소스 서버가 동일하게 사용되도록 하는 디바이스

+

로드 밸런싱의 장점

+

가용성

+

서버에 문제가 발생하는 경우 로드밸런서가 해당 문제를 감지(헬스 체크를 통해)하여 트래픽을 사용 가능한 서버로 보냄으로써 내결함성을 높힌다.
+로드밸런서를 활용한 무중단 배포

+

확장성

+

수평 확장성(Horizontal Scalability) 용이
트래픽이 증가하는 경우 AutoScaling을 통해 서버를 자동으로 확장(Scale-out)
-트래픽이 감소하는 경우 축소(Scale-in)

보안

분산 서비스 거부 공격(DDoS)이 발생하는 경우 해당 트래픽을 부하 분산할 수 있다.

성능

서버 간 로드를 균등하게 배포하여 애플리케이션의 성능을 향상 시킨다.
-클라이언트 요청을 지리적으로 더 가까운 서버로 리다이렉션하여 지연 시간을 단축시킨다.

내결함성(Fault Tolerance)과 확장성(Scalability)

내결함성: 시스템의 일부 구성 요소가 작동하지 않더라도 계속 작동할 수 있는 기능
-확장성: 대규모적인 재설계/재설치 등의 필요없이 확장이 얼마나 쉽고 가능한가에 대한 용이성

참고 자료

load balancing, AWS

- - +트래픽이 감소하는 경우 축소(Scale-in)

+

보안

+

분산 서비스 거부 공격(DDoS)이 발생하는 경우 해당 트래픽을 부하 분산할 수 있다.

+

성능

+

서버 간 로드를 균등하게 배포하여 애플리케이션의 성능을 향상 시킨다.
+클라이언트 요청을 지리적으로 더 가까운 서버로 리다이렉션하여 지연 시간을 단축시킨다.

+

내결함성: 시스템의 일부 구성 요소가 작동하지 않더라도 계속 작동할 수 있는 기능
+확장성: 대규모적인 재설계/재설치 등의 필요없이 확장이 얼마나 쉽고 가능한가에 대한 용이성

+

참고 자료

+

load balancing, AWS

\ No newline at end of file diff --git a/docs/nginx/command.html b/docs/nginx/command.html index 96156203e..c19cdcdc7 100644 --- a/docs/nginx/command.html +++ b/docs/nginx/command.html @@ -1,9 +1,9 @@ - + - -구조 및 명령어 | GG + +구조 및 명령어 | GG @@ -12,20 +12,48 @@ - - - + + + -
-

구조 및 명령어

폴더 및 파일

/etc/nginx/

기본 설정이 저장된 루트 디렉터리

/etc/nginx/nginx.conf

기본 설정 파일로 모든 설정에 대한 진입점
-디렉터리에 위치한 모든 설정 파일을 포함하는 최상위 Http 블록을 포함한다.

nginx에 포함된 설정 파일 포함 include 구문
http {
...
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

/etc/nginx/conf.d/

기본 HTTP 서버 설정 파일에 대한 디렉터리
+

구조 및 명령어

폴더 및 파일

+

/etc/nginx/

+

기본 설정이 저장된 루트 디렉터리

+

/etc/nginx/nginx.conf

+

기본 설정 파일로 모든 설정에 대한 진입점
+디렉터리에 위치한 모든 설정 파일을 포함하는 최상위 Http 블록을 포함한다.

+
http {
+        ...
+        include /etc/nginx/conf.d/*.conf;
+        include /etc/nginx/sites-enabled/*;
+}
+
+

/etc/nginx/conf.d/

+

기본 HTTP 서버 설정 파일에 대한 디렉터리
.conf 로 끝나는 경우 위의 include 설정에 의해 최상위 http 블록에 포함된다.
-conf.d 디렉터리 대신 site-enabled 디렉터리와 symlink를 통해 설정 파일을 연결하는 방법은 더 이상 사용하지 않는다.

NIGNX 설정

nginx 설정의 경우 include 구문을 활용해 구조화하여 설정 파일을 간결하게 유지하는 것이 좋다.

/var/log/nginx/

엔진엑스 로그가 저장되는 디렉터리로 access 로그와 error 로그를 확인할 수 있다.
-로그 형식의 경우 설정 파일의 log_format 구문을 이용해서 변경할 수 있다.

명령어

nginx -t

nginx 설정이 정상인지 확인한다.

nginx -T

nginx 설정 확인의 결과를 조금 더 자세하게 출력해준다.

nginx -s <SIGNAL>

여기서 SIGNAL은 다음 중 하나를 선택할 수 있다.

  • quit: 정상적으로 종료(SIGQUIT)
  • reload: 설정 파일 리로드(SIGHUP)
  • reopen: 로그 파일을 다시 열도록 요청(SIGUSR1)
  • stop: 종료 요청(SIGTERM)

여기서 SIGQUIT & SIGTREM 모두 graceful shutdown을 수행한다.

참고 자료

NGINX 쿡북, 데릭 디용기 p.22 ~ p.23
-https://docs.nginx.com/
-https://docs.nginx.com/nginx/admin-guide/monitoring/logging/

- - +conf.d 디렉터리 대신 site-enabled 디렉터리와 symlink를 통해 설정 파일을 연결하는 방법은 더 이상 사용하지 않는다.

+

nginx 설정의 경우 include 구문을 활용해 구조화하여 설정 파일을 간결하게 유지하는 것이 좋다.

+

/var/log/nginx/

+

엔진엑스 로그가 저장되는 디렉터리로 access 로그와 error 로그를 확인할 수 있다.
+로그 형식의 경우 설정 파일의 log_format 구문을 이용해서 변경할 수 있다.

+

명령어

+

nginx -t

+

nginx 설정이 정상인지 확인한다.

+

nginx -T

+

nginx 설정 확인의 결과를 조금 더 자세하게 출력해준다.

+

nginx -s <SIGNAL>

+

여기서 SIGNAL은 다음 중 하나를 선택할 수 있다.

+
    +
  • quit: 정상적으로 종료(SIGQUIT)
  • +
  • reload: 설정 파일 리로드(SIGHUP)
  • +
  • reopen: 로그 파일을 다시 열도록 요청(SIGUSR1)
  • +
  • stop: 종료 요청(SIGTERM)
  • +
+

여기서 SIGQUIT & SIGTREM 모두 graceful shutdown을 수행한다.

+

참고 자료

+

NGINX 쿡북, 데릭 디용기 p.22 ~ p.23
+https://docs.nginx.com/
+https://docs.nginx.com/nginx/admin-guide/monitoring/logging/

\ No newline at end of file diff --git a/docs/nginx/static-file.html b/docs/nginx/static-file.html index c7751ee16..e83dbbad2 100644 --- a/docs/nginx/static-file.html +++ b/docs/nginx/static-file.html @@ -1,9 +1,9 @@ - + - -정적 컨텐츠 제공 | GG + +정적 컨텐츠 제공 | GG @@ -12,16 +12,45 @@ - - - + + + -
-

정적 컨텐츠 제공

root

클라이언트에게 파일을 제공할 때 사용되는 경로를 지정하는 데 사용한다.
-root의 경우 locaiton으로 넘어온 경로를 root 경로 뒤에 추가한다.

root
# localhost/images/1.png 호출 /var/www/images/images/1.png 검색
location /images/ {
root /var/www/images;
}

alias

location으로 매칭된 부분을 제거한다.

alias
# localhost/images/1.png 호출 /var/www/images/1.png 검색
location /images/ {
alias /var/www/images;
}

try_files

try_files 디렉티브를 이용해서 파일이 존재하지 않으면 적절한 값을 반환할 수 있다.
-설정하지 않으면 기본으로 404를 반환한다.

location /images/ {
alias /var/www/images;
try_files $uri $uri/ =404;
}

다음과 같이 proxy 설정으로도 구성할 수도 있다.

location /images/ {
root /root;
try_files $uri $uri/ default-image;
}

location default-image {
proxy_pass http://localhost/images/default_image.jpg;
}

참고 자료

Serving Static Content

- - +

정적 컨텐츠 제공

root

+

클라이언트에게 파일을 제공할 때 사용되는 경로를 지정하는 데 사용한다.
+root의 경우 locaiton으로 넘어온 경로를 root 경로 뒤에 추가한다.

+
# localhost/images/1.png 호출 /var/www/images/images/1.png 검색
+location /images/ {
+    root /var/www/images;
+}
+
+

alias

+

location으로 매칭된 부분을 제거한다.

+
# localhost/images/1.png 호출 /var/www/images/1.png 검색
+location /images/ {
+    alias /var/www/images;
+}
+
+

try_files

+

try_files 디렉티브를 이용해서 파일이 존재하지 않으면 적절한 값을 반환할 수 있다.
+설정하지 않으면 기본으로 404를 반환한다.

+
location /images/ {
+    alias /var/www/images;
+    try_files $uri $uri/ =404;
+}
+
+

다음과 같이 proxy 설정으로도 구성할 수도 있다.

+
location /images/ {
+    root /root;
+    try_files $uri $uri/ default-image;
+}
+
+location default-image {
+    proxy_pass http://localhost/images/default_image.jpg;
+}
+
+

참고 자료

+

Serving Static Content

\ No newline at end of file diff --git a/docs/performance/throughput-latency.html b/docs/performance/throughput-latency.html index d2bc27291..20fd6cf63 100644 --- a/docs/performance/throughput-latency.html +++ b/docs/performance/throughput-latency.html @@ -1,9 +1,9 @@ - + - -시스템 성능 지표 | GG + +시스템 성능 지표 | GG @@ -12,22 +12,39 @@ - - - + + + -
-

시스템 성능 지표

시스템 성능 지표

시스템 성능은 어떻게 측정할까?
+

시스템 성능 지표

시스템 성능 지표

+

시스템 성능은 어떻게 측정할까?
성능이 빨라졌다. 라는 것을 어떻게 수치화할 수 있을까?
-일반적으로 시스템 성능은 Throughput과 Latency라는 성능 지표로 측정을 한다.

Throughput

초당 처리하는 작업의 수, 즉 처리량을 의미한다.
+일반적으로 시스템 성능은 Throughput과 Latency라는 성능 지표로 측정을 한다.

+

Throughput

+

초당 처리하는 작업의 수, 즉 처리량을 의미한다.
일반적으로 초당 몇 개의 요청을 처리하는지(RPS, Request Per Second)를 기준으로 측정을 한다.
-다음과 같은 시스템이 있다고 가정해보자.

  • 시스템 A: 초당 약 100개의 요청 처리
  • 시스템 B: 초당 약 200개의 요청 처리

시스템 B가 동시간 대비 더 높은 처리량을 보여주고 있으니, 시스템 B의 성능이 더 좋다고 할 수 있다.

Latency

시스템의 평균 응답 시간, 즉 처리 시간을 의미한다.
-Latency는 다음과 같이 두 가지로 구분할 수 있다.

사용자가 본 처리 시간: 사용자가 요청을 보내고 응답을 받을 때까지의 시간
-시스템에서 본 처리 시간: 시스템이 요청을 받고 응답을 보낼 때까지의 시간

사용자가 본 처리 시간의 경우 네트워크에 대한 시간이 포함된다.
-따라서 성능 측정과 개선은 시스템에서 본 처리 시간으로 측정하고 개선하는 것이 더 정확해 보인다.

다음과 같은 시스템이 있다고 가정해보자.

  • 시스템 A: 요청시 평균 200ms 내 응답
  • 시스템 B: 요청시 평균 100ms 내 응답

시스템 B가 요청에 대한 응답이 더 빠르니, 시스템 B의 성능이 더 좋다고 할 수 있다.

참고 자료

아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄
-difference between throughput and latency, AWS - 해당 내용은 네트워크 기준이다.

- - +다음과 같은 시스템이 있다고 가정해보자.

+
    +
  • 시스템 A: 초당 약 100개의 요청 처리
  • +
  • 시스템 B: 초당 약 200개의 요청 처리
  • +
+

시스템 B가 동시간 대비 더 높은 처리량을 보여주고 있으니, 시스템 B의 성능이 더 좋다고 할 수 있다.

+

Latency

+

시스템의 평균 응답 시간, 즉 처리 시간을 의미한다.
+Latency는 다음과 같이 두 가지로 구분할 수 있다.

+

사용자가 본 처리 시간: 사용자가 요청을 보내고 응답을 받을 때까지의 시간
+시스템에서 본 처리 시간: 시스템이 요청을 받고 응답을 보낼 때까지의 시간

+

사용자가 본 처리 시간의 경우 네트워크에 대한 시간이 포함된다.
+따라서 성능 측정과 개선은 시스템에서 본 처리 시간으로 측정하고 개선하는 것이 더 정확해 보인다.

+

다음과 같은 시스템이 있다고 가정해보자.

+
    +
  • 시스템 A: 요청시 평균 200ms 내 응답
  • +
  • 시스템 B: 요청시 평균 100ms 내 응답
  • +
+

시스템 B가 요청에 대한 응답이 더 빠르니, 시스템 B의 성능이 더 좋다고 할 수 있다.

+

참고 자료

+

아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄
+difference between throughput and latency, AWS - 해당 내용은 네트워크 기준이다.

\ No newline at end of file diff --git a/docs/performance/throughput.html b/docs/performance/throughput.html index 085120f72..89a5bf26d 100644 --- a/docs/performance/throughput.html +++ b/docs/performance/throughput.html @@ -1,9 +1,9 @@ - + - -Throughput 목푯값 | GG + +Throughput 목푯값 | GG @@ -12,19 +12,24 @@ - - - + + + -
-

Throughput 목푯값

Throughput

1일 사용자 수, 1명당 1일 평균 접속 수, 1일 평균 접속 수에 대한 피크 때의 배율을 확인한다.

throughput

1일 총 접속 수: 1일 사용자 수 x 1인당 1일 평균 접속 수
+

Throughput 목푯값

Throughput

+

1일 사용자 수, 1명당 1일 평균 접속 수, 1일 평균 접속 수에 대한 피크 때의 배율을 확인한다.

+

1일 총 접속 수: 1일 사용자 수 x 1인당 1일 평균 접속 수
1일 평균 rps: 1일 총 접속 수 / 86400
-최대 rps: 1일 평균 rps x 최대 피크 때의 비율(평균 접속 수 대비)

최대 rps * 안전계수(2 ~ 3배)를 Throughput의 목표치로 한다.

계산 예시

DAU: 10만명
+최대 rps: 1일 평균 rps x 최대 피크 때의 비율(평균 접속 수 대비)

+

최대 rps * 안전계수(2 ~ 3배)를 Throughput의 목표치로 한다.

+

계산 예시

+

DAU: 10만명
1명당 평균 접속수: 10회
평균 접속 수 대비 최대 피크 비율: 4배
-안전계수: 3배

100000 x 10 / 86400 x 4 x 3 -> 약 138rps

참고 자료

아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄

- - +안전계수: 3배

+

100000 x 10 / 86400 x 4 x 3 -> 약 138rps

+

참고 자료

+

아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄

\ No newline at end of file diff --git a/docs/performance/types.html b/docs/performance/types.html index 0d80c73ac..762b41e1d 100644 --- a/docs/performance/types.html +++ b/docs/performance/types.html @@ -1,9 +1,9 @@ - + - -성능 테스트 유형 | GG + +성능 테스트 유형 | GG @@ -12,14 +12,13 @@ - - - + + + -
-

성능 테스트 유형

테스트설명
지연 테스트(latency test)요청에 대한 응답 시간을 측정
처리율 테스트(throughput test)시스템 성능이 급락하기 직전, 최대 처리율 수치를 측정
부하 테스트(load test)비즈니스 이벤트를 대비해 트래픽을 견딜 수 있는지 확인
스트레스 테스트(stress test)시스템의 한계점을 확인
내구 테스트(endurance test)장시간 실행할 경우 성능 이상이 발생하는지 확인
용량 계획 테스트(capacity planning test)리소스를 추가한 만큼 시스템이 확장되는지 확인
저하 테스트(degradation test)시스템이 부분적으로 실패할 경우 어떤 일이 발생하는지 확인(장애 복구 및 회복 등)

참고 자료

자바 최적화 - 벤저민 J. 에번스, 제임스 고프, 크리스 뉴랜드

- - +

성능 테스트 유형

테스트설명
지연 테스트(latency test)요청에 대한 응답 시간을 측정
처리율 테스트(throughput test)시스템 성능이 급락하기 직전, 최대 처리율 수치를 측정
부하 테스트(load test)비즈니스 이벤트를 대비해 트래픽을 견딜 수 있는지 확인
스트레스 테스트(stress test)시스템의 한계점을 확인
내구 테스트(endurance test)장시간 실행할 경우 성능 이상이 발생하는지 확인
용량 계획 테스트(capacity planning test)리소스를 추가한 만큼 시스템이 확장되는지 확인
저하 테스트(degradation test)시스템이 부분적으로 실패할 경우 어떤 일이 발생하는지 확인(장애 복구 및 회복 등)
+

참고 자료

+

자바 최적화 - 벤저민 J. 에번스, 제임스 고프, 크리스 뉴랜드

\ No newline at end of file diff --git a/docs/spring/essence.html b/docs/spring/essence.html index 6a946ce7a..8cc317b21 100644 --- a/docs/spring/essence.html +++ b/docs/spring/essence.html @@ -1,9 +1,9 @@ - + - -스프링의 특징 | GG + +스프링의 특징 | GG @@ -12,25 +12,36 @@ - - - + + + -
-

스프링의 특징

스프링의 핵심 개발자들이 쓴 Professional Spring Framework 라는 책에서는 스프링의 정수(essence)는 "엔터프라이즈 서비스 기능을 POJO에 제공하는 것" 이라고 했다.

POJO(Plain Old Java Object)

객제지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트 -스프링 애플리케이션은 POJO를 이용해서 만든 애플리케이션 코드와, POJO가 어떻게 관계를 맺고 동작하는지 정의해놓은 설계 정보로 구분된다.

IoC/DI(Inversion of Control/Dependency Injection)

제어의 역전(IoC)은 스프링에서만 적용되는 개념은 아니다.
+

스프링의 특징

스프링의 핵심 개발자들이 쓴 Professional Spring Framework 라는 책에서는 스프링의 정수(essence)는 "엔터프라이즈 서비스 기능을 POJO에 제공하는 것" 이라고 했다.

+

POJO(Plain Old Java Object)

+

객제지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트 +스프링 애플리케이션은 POJO를 이용해서 만든 애플리케이션 코드와, POJO가 어떻게 관계를 맺고 동작하는지 정의해놓은 설계 정보로 구분된다.

+

IoC/DI(Inversion of Control/Dependency Injection)

+

제어의 역전(IoC)은 스프링에서만 적용되는 개념은 아니다.
간단하게 설명하자면 프로그램의 제어 흐름 구조가 바뀌는 것이다.
프레임워크는 제어의 역전이 적용된 대표적인 기술이라고 볼 수 있다.
의존성 주입(DI)은 클래스 사이의 의존관계를 설정 정보를 바탕으로 컨테이너가 자동적으로 연결해 주는 것을 의미한다.
-스프링은 IoC/DI를 통해 싱글톤 형태의 오브젝트의 생성, 관계 설정, 공급에 대한 기능을 제공한다. 그렇기 때문에 IoC 컨테이너 또는 DI 컨테이너라고도 불린다.

토비의 스프링에서는 DI 컨테이너라는 용어에 대해 다음과 같이 설명하고 있다.

IoC가 매우 느슨하게 정의돼서 폭넓게 사용되는 용어라는 점이다. 때문에 스프링을 IoC 컨테이너라고만 해서는 스프링이 제공하는 기능의 특징을 명확하게 설명하지 못한다. … 새로운 용어를 만드는 데 탁월한 재능이 있는 몇몇 사람의 제안으로 스프링이 제공하는 IoC 방식의 핵심을 짚어주는 의존관계 주입(DI)이라는, 좀 더 의도가 명확히 드러나는 이름을 사용하기 시작했다. 스프링 IoC 기능의 대표적인 동작원리는 주로 의존관계 주입이라고 불린다. … 그래서 초기에는 주로 IoC 컨테이너라고 불리던 스프링이 지금은 의존관계 주입 컨테이너 또는 DI 컨테이너라고 많이 불린다.
-토비의 스프링 p.111

AOP(Aspect Oriented Programming)

애플리케이션의 핵심적인 기능에서 부가적인 기능을 분리해서 모듈화하는 것
+스프링은 IoC/DI를 통해 싱글톤 형태의 오브젝트의 생성, 관계 설정, 공급에 대한 기능을 제공한다. 그렇기 때문에 IoC 컨테이너 또는 DI 컨테이너라고도 불린다.

+

토비의 스프링에서는 DI 컨테이너라는 용어에 대해 다음과 같이 설명하고 있다.

+
+

IoC가 매우 느슨하게 정의돼서 폭넓게 사용되는 용어라는 점이다. 때문에 스프링을 IoC 컨테이너라고만 해서는 스프링이 제공하는 기능의 특징을 명확하게 설명하지 못한다. … 새로운 용어를 만드는 데 탁월한 재능이 있는 몇몇 사람의 제안으로 스프링이 제공하는 IoC 방식의 핵심을 짚어주는 의존관계 주입(DI)이라는, 좀 더 의도가 명확히 드러나는 이름을 사용하기 시작했다. 스프링 IoC 기능의 대표적인 동작원리는 주로 의존관계 주입이라고 불린다. … 그래서 초기에는 주로 IoC 컨테이너라고 불리던 스프링이 지금은 의존관계 주입 컨테이너 또는 DI 컨테이너라고 많이 불린다.
+토비의 스프링 p.111

+
+

AOP(Aspect Oriented Programming)

+

애플리케이션의 핵심적인 기능에서 부가적인 기능을 분리해서 모듈화하는 것
예) 핵심 기능 = 비즈니스 로직, 부가 기능 = 로깅, 트랜잭션
-관점 지향 프로그래밍이라고 하는데 이는 OOP와 같이 독립적인 프로그래밍 패러다임이 아닌 보조적인 기술이다.

PSA(Portable Service Abstraction)

환경과 세부 기술의 변화에 관계없이 일관된 방식으로 기술에 접근할 수 있게 해주는 기술이다.
+관점 지향 프로그래밍이라고 하는데 이는 OOP와 같이 독립적인 프로그래밍 패러다임이 아닌 보조적인 기술이다.

+

PSA(Portable Service Abstraction)

+

환경과 세부 기술의 변화에 관계없이 일관된 방식으로 기술에 접근할 수 있게 해주는 기술이다.
POJO로 개발된 코드는 특정 환경이나 구현 방식에 종속적이지 않아야 한다.
-스프링은 POJO 코드가 특정 기술에 종속되지 않게 일관성 있는 서비스 추상화 기술을 제공한다.

참고 자료

Spring Core, Spring.io
-토비의 스프링 3.1, 이일민

- - +스프링은 POJO 코드가 특정 기술에 종속되지 않게 일관성 있는 서비스 추상화 기술을 제공한다.

+

참고 자료

+

Spring Core, Spring.io
+토비의 스프링 3.1, 이일민

\ No newline at end of file diff --git a/docs/tags.html b/docs/tags.html index 3d9ef4cf3..f179004fe 100644 --- a/docs/tags.html +++ b/docs/tags.html @@ -1,9 +1,9 @@ - + - -태그 | GG + +태그 | GG @@ -12,14 +12,11 @@ - - - + + + - - - + \ No newline at end of file diff --git a/docs/tags/architecture.html b/docs/tags/architecture.html index af30b36cf..ca55572a0 100644 --- a/docs/tags/architecture.html +++ b/docs/tags/architecture.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "architecture" 태그에 분류되었습니다 | GG + +1개 문서가 "architecture" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "architecture" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "architecture" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/book.html b/docs/tags/book.html index c96a82e5b..c017c3ce9 100644 --- a/docs/tags/book.html +++ b/docs/tags/book.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "book" 태그에 분류되었습니다 | GG + +1개 문서가 "book" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "book" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "book" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/collection.html b/docs/tags/collection.html index 2d09ebd83..b89d6e710 100644 --- a/docs/tags/collection.html +++ b/docs/tags/collection.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "collection" 태그에 분류되었습니다 | GG + +1개 문서가 "collection" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "collection" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "collection" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/deploy.html b/docs/tags/deploy.html index 9a2e54dcf..b78040149 100644 --- a/docs/tags/deploy.html +++ b/docs/tags/deploy.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "deploy" 태그에 분류되었습니다 | GG + +1개 문서가 "deploy" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "deploy" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "deploy" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/etc.html b/docs/tags/etc.html index 1e6c7b4eb..1a4ad92ae 100644 --- a/docs/tags/etc.html +++ b/docs/tags/etc.html @@ -1,9 +1,9 @@ - + - -4개 문서가 "etc" 태그에 분류되었습니다 | GG + +4개 문서가 "etc" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

4개 문서가 "etc" 태그에 분류되었습니다

모든 태그 보기
- - +

4개 문서가 "etc" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/java.html b/docs/tags/java.html index ad1d86afd..16e665530 100644 --- a/docs/tags/java.html +++ b/docs/tags/java.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "java" 태그에 분류되었습니다 | GG + +1개 문서가 "java" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "java" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "java" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/jpa.html b/docs/tags/jpa.html index 65cbd85fe..c9537987b 100644 --- a/docs/tags/jpa.html +++ b/docs/tags/jpa.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "JPA" 태그에 분류되었습니다 | GG + +1개 문서가 "JPA" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "JPA" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "JPA" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/latency.html b/docs/tags/latency.html index f9087e1d7..1563d2863 100644 --- a/docs/tags/latency.html +++ b/docs/tags/latency.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "latency" 태그에 분류되었습니다 | GG + +1개 문서가 "latency" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "latency" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "latency" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/load-balancing.html b/docs/tags/load-balancing.html index 99a4faffb..071d8222c 100644 --- a/docs/tags/load-balancing.html +++ b/docs/tags/load-balancing.html @@ -1,9 +1,9 @@ - + - -2개 문서가 "load balancing" 태그에 분류되었습니다 | GG + +2개 문서가 "load balancing" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

2개 문서가 "load balancing" 태그에 분류되었습니다

모든 태그 보기
- - +

2개 문서가 "load balancing" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/monitoring.html b/docs/tags/monitoring.html index a97dcd115..0277fb3e3 100644 --- a/docs/tags/monitoring.html +++ b/docs/tags/monitoring.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "monitoring" 태그에 분류되었습니다 | GG + +1개 문서가 "monitoring" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "monitoring" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "monitoring" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/network.html b/docs/tags/network.html index 82dd443a1..8bfa8b5e3 100644 --- a/docs/tags/network.html +++ b/docs/tags/network.html @@ -1,9 +1,9 @@ - + - -2개 문서가 "network" 태그에 분류되었습니다 | GG + +2개 문서가 "network" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

2개 문서가 "network" 태그에 분류되었습니다

모든 태그 보기
- - +

2개 문서가 "network" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/nginx.html b/docs/tags/nginx.html index c97a4d29f..de5985985 100644 --- a/docs/tags/nginx.html +++ b/docs/tags/nginx.html @@ -1,9 +1,9 @@ - + - -2개 문서가 "nginx" 태그에 분류되었습니다 | GG + +2개 문서가 "nginx" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

2개 문서가 "nginx" 태그에 분류되었습니다

모든 태그 보기
- - +

2개 문서가 "nginx" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/package.html b/docs/tags/package.html index 7e2eda78d..d2157932d 100644 --- a/docs/tags/package.html +++ b/docs/tags/package.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "package" 태그에 분류되었습니다 | GG + +1개 문서가 "package" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "package" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "package" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/performance.html b/docs/tags/performance.html index 855a09d08..f31cb428d 100644 --- a/docs/tags/performance.html +++ b/docs/tags/performance.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "performance" 태그에 분류되었습니다 | GG + +1개 문서가 "performance" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "performance" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "performance" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/postmortem.html b/docs/tags/postmortem.html index 0d4a3399b..c46d256b5 100644 --- a/docs/tags/postmortem.html +++ b/docs/tags/postmortem.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "postmortem" 태그에 분류되었습니다 | GG + +1개 문서가 "postmortem" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "postmortem" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "postmortem" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/sequenced.html b/docs/tags/sequenced.html index 7332b6e1b..ec9736c88 100644 --- a/docs/tags/sequenced.html +++ b/docs/tags/sequenced.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "sequenced" 태그에 분류되었습니다 | GG + +1개 문서가 "sequenced" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "sequenced" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "sequenced" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/spring.html b/docs/tags/spring.html index 59e1ce8f0..b9b3845e1 100644 --- a/docs/tags/spring.html +++ b/docs/tags/spring.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "spring" 태그에 분류되었습니다 | GG + +1개 문서가 "spring" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "spring" 태그에 분류되었습니다

모든 태그 보기

스프링의 특징

스프링의 핵심 개발자들이 쓴 Professional Spring Framework 라는 책에서는 스프링의 정수(essence)는 "엔터프라이즈 서비스 기능을 POJO에 제공하는 것" 이라고 했다.

- - +

1개 문서가 "spring" 태그에 분류되었습니다

모든 태그 보기

스프링의 특징

스프링의 핵심 개발자들이 쓴 Professional Spring Framework 라는 책에서는 스프링의 정수(essence)는 "엔터프라이즈 서비스 기능을 POJO에 제공하는 것" 이라고 했다.

\ No newline at end of file diff --git a/docs/tags/test.html b/docs/tags/test.html index 474ce8d33..bfbbd48d1 100644 --- a/docs/tags/test.html +++ b/docs/tags/test.html @@ -1,9 +1,9 @@ - + - -5개 문서가 "test" 태그에 분류되었습니다 | GG + +5개 문서가 "test" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

5개 문서가 "test" 태그에 분류되었습니다

모든 태그 보기
- - +

5개 문서가 "test" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/throughput.html b/docs/tags/throughput.html index a95f9899d..5488653cb 100644 --- a/docs/tags/throughput.html +++ b/docs/tags/throughput.html @@ -1,9 +1,9 @@ - + - -2개 문서가 "throughput" 태그에 분류되었습니다 | GG + +2개 문서가 "throughput" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

2개 문서가 "throughput" 태그에 분류되었습니다

모든 태그 보기
- - +

2개 문서가 "throughput" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/tags/zero-downtime.html b/docs/tags/zero-downtime.html index c19f97221..a5b11cf5e 100644 --- a/docs/tags/zero-downtime.html +++ b/docs/tags/zero-downtime.html @@ -1,9 +1,9 @@ - + - -1개 문서가 "zero-downtime" 태그에 분류되었습니다 | GG + +1개 문서가 "zero-downtime" 태그에 분류되었습니다 | GG @@ -12,14 +12,11 @@ - - - + + + -
-

1개 문서가 "zero-downtime" 태그에 분류되었습니다

모든 태그 보기
- - +

1개 문서가 "zero-downtime" 태그에 분류되었습니다

모든 태그 보기
\ No newline at end of file diff --git a/docs/test/benefit.html b/docs/test/benefit.html index aa36cdf25..c667ec0d3 100644 --- a/docs/test/benefit.html +++ b/docs/test/benefit.html @@ -1,9 +1,9 @@ - + - -테스트 코드가 주는 혜택 | GG + +테스트 코드가 주는 혜택 | GG @@ -12,20 +12,30 @@ - - - + + + -
-

테스트 코드가 주는 혜택

디버깅 감소

테스트를 한 번 작성해두면 프로젝트의 생존 주기동안 값비싼 결함을 예방해 준다.
+

테스트 코드가 주는 혜택

디버깅 감소

+

테스트를 한 번 작성해두면 프로젝트의 생존 주기동안 값비싼 결함을 예방해 준다.
또한 전체적인 결함이 해결되어 디버깅에서 해방시켜준다.
-소프트웨어 장인 정신 이야기에서 언급된 TDD heuristics 15. 디버거 사용을 피하라 와 연결되는 내용이다.

자신 있게 변경

소프트웨어는 항상 변경된다.
-리팩터링할 때 자신감을 가지고 변경 사항을 반영할 수 있다.

더 나은 문서 자료

하나의 행위만 집중해 검증하는 테스트는 실행 가능한 문서와 같다.
-이 때 테스트는 명확하고 간결해야지만 문서 자료로서의 역할을 훌륭히 수행할 수 있다.

더 단순한 리뷰

정확성, 극단 상황, 오류 상황 등의 다양한 측면에서 코드를 검사해주는 테스트가 준비되어 있다면 리뷰어가 검증하는 시간을 크게 줄여준다.

사려 깊은 설계

새로 작성한 코드의 테스트를 작성하는 일은 실질적으로 해당 코드의 API가 잘 설계되어 있는지를 시험하는 행위다.
+소프트웨어 장인 정신 이야기에서 언급된 TDD heuristics 15. 디버거 사용을 피하라 와 연결되는 내용이다.

+

자신 있게 변경

+

소프트웨어는 항상 변경된다.
+리팩터링할 때 자신감을 가지고 변경 사항을 반영할 수 있다.

+

더 나은 문서 자료

+

하나의 행위만 집중해 검증하는 테스트는 실행 가능한 문서와 같다.
+이 때 테스트는 명확하고 간결해야지만 문서 자료로서의 역할을 훌륭히 수행할 수 있다.

+

더 단순한 리뷰

+

정확성, 극단 상황, 오류 상황 등의 다양한 측면에서 코드를 검사해주는 테스트가 준비되어 있다면 리뷰어가 검증하는 시간을 크게 줄여준다.

+

사려 깊은 설계

+

새로 작성한 코드의 테스트를 작성하는 일은 실질적으로 해당 코드의 API가 잘 설계되어 있는지를 시험하는 행위다.
테스트하기 어려운 코드는 너무 많은 책임을 가지고 있거나, 의존성이 복잡한 경우가 많다.
-잘 설계된 코드라면 모듈화가 잘 되어있어야 한다.

고품질의 릴리스를 빠르게

자동화된 테스트를 갖춘다면 새로운 버전을 릴리스할 때 불안에 떨지 않아도 된다.

참고 자료

구글 엔지니어는 이렇게 일한다, 타이터스 윈터스, 톰 맨쉬렉, 하이럼 라이트 p.288

- - +잘 설계된 코드라면 모듈화가 잘 되어있어야 한다.

+

고품질의 릴리스를 빠르게

+

자동화된 테스트를 갖춘다면 새로운 버전을 릴리스할 때 불안에 떨지 않아도 된다.

+

참고 자료

+

구글 엔지니어는 이렇게 일한다, 타이터스 윈터스, 톰 맨쉬렉, 하이럼 라이트 p.288

\ No newline at end of file diff --git a/docs/test/first.html b/docs/test/first.html index 46e608f4a..3a5a15500 100644 --- a/docs/test/first.html +++ b/docs/test/first.html @@ -1,9 +1,9 @@ - + - -FIRST | GG + +FIRST | GG @@ -12,23 +12,33 @@ - - - + + + -
-

FIRST

FIRST란?

Fast, Independent, Repeatable, Self-Validating, Timely의 약자로 좋은 단위 테스트를 작성하는데 도움이 되는 원칙들이다.

Fast(빠르게)

테스트가 빠르게 돌아가지 않으면, 테스트를 매 순간 실행하지 않을 것이다.
+

FIRST

FIRST란?

+

Fast, Independent, Repeatable, Self-Validating, Timely의 약자로 좋은 단위 테스트를 작성하는데 도움이 되는 원칙들이다.

+

Fast(빠르게)

+

테스트가 빠르게 돌아가지 않으면, 테스트를 매 순간 실행하지 않을 것이다.
테스트를 자주 실행하지 않으면, 버그를 놓칠 수 있다.
-따라서 빠르게 테스트를 돌려 피드백 받는 주기를 짧게 만드는 것이 좋다.

Independent(독립적으로)

테스트끼리 서로 의존하면 안된다.
+따라서 빠르게 테스트를 돌려 피드백 받는 주기를 짧게 만드는 것이 좋다.

+

Independent(독립적으로)

+

테스트끼리 서로 의존하면 안된다.
서로 의존하게 된다면 하나의 테스트가 실패할 때, 또 다른 하나의 테스트가 실패할 수 있다.
-다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

Repeatable(반복 가능한)

테스트는 어떠한 환경에서라도 반복 가능해야 한다.
-또한 반복적으로 수행해도 같은 결과를 낼 수 있어야 한다.

Self-Validating(자가 검증하는)

테스트는 성공 또는 실패로 bool 값으로 결과를 내어 자체적으로 검증해야 된다.
-JUnit과 같은 자동화된 테스트 도구를 사용해야 한다.

Timely(적시에)

테스트는 적시에 작성해야 한다.
+다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

+

Repeatable(반복 가능한)

+

테스트는 어떠한 환경에서라도 반복 가능해야 한다.
+또한 반복적으로 수행해도 같은 결과를 낼 수 있어야 한다.

+

Self-Validating(자가 검증하는)

+

테스트는 성공 또는 실패로 bool 값으로 결과를 내어 자체적으로 검증해야 된다.
+JUnit과 같은 자동화된 테스트 도구를 사용해야 한다.

+

Timely(적시에)

+

테스트는 적시에 작성해야 한다.
단위 테스트는 테스트 하려는 실제 코드를 구현하기 직전에 구현해야 한다.(TDD)
-실제 코드를 구현한 다음에 테스트 코드를 작성한다면, 테스트 하기 어려운 코드를 작성했다는 것을 뒤늦게 발견할 수 있다.

참고 자료

A clean test, TDD Manifasto
-Clean Code 9장 단위테스트, 로버트 C. 마틴

- - +실제 코드를 구현한 다음에 테스트 코드를 작성한다면, 테스트 하기 어려운 코드를 작성했다는 것을 뒤늦게 발견할 수 있다.

+

참고 자료

+

A clean test, TDD Manifasto
+Clean Code 9장 단위테스트, 로버트 C. 마틴

\ No newline at end of file diff --git a/docs/test/heuristics.html b/docs/test/heuristics.html index 3ff9c4171..0aa2fd5ca 100644 --- a/docs/test/heuristics.html +++ b/docs/test/heuristics.html @@ -1,9 +1,9 @@ - + - -TDD heuristics | GG + +TDD heuristics | GG @@ -12,14 +12,30 @@ - - - + + + -
-

TDD heuristics

TDD heuristics

  1. 여러분이 작성하고 싶은 코드를 작성하도록 만드는 테스트를 작성하라.
  2. 실패시켜라. 통과시켜라. 그리고 정리하라.
  3. 최상의 결과를 추구하지 말라.
  4. 실패하는 가장 간단하고, 가장 구체적이며, 가장 퇴화한 테스트를 작성하라.
  5. 가능하면 일반화하라.
  6. 코드가 틀렸다고 느껴지면 잠시 멈춰서 설계를 고쳐라.
  7. 더 복잡한 다음 경우로 넘어가기 전, 지금 다루고 있는 더 단순한 경우를 모조리 테스트하라.
  8. 현재 테스트를 통과시키기 위해 너무 많은 구현을 해야 한다면, 테스트를 지우고 더 쉽게 통과할 수 있는 더 단순한 테스트를 작성하라.
  9. 테스트 공간(test space)을 전부 포괄하는 신중하고 점진적인 패턴을 따르라.
  10. 필요 없는 것을 여러분의 테스트에 넣지 말라.
  11. 테스트에 실제 서비스 데이터를 사용하지 말라.
  12. 테스트 구조를 제품 코드 구조로부터 분리하라.
  13. 테스트가 구체적(specific)이 될수록 코드는 일반적(generic)이 된다.
  14. 변환을 적용한 결과 최적이 아닌 해답에 도달했다면 다른 변환을 시도해보라.
  15. 디버거 사용을 피하라

참고 자료

소프트웨어 장인 정신 이야기, 로버트 C. 마틴 p.44 ~ p.209

- - +

TDD heuristics

TDD heuristics

+
    +
  1. 여러분이 작성하고 싶은 코드를 작성하도록 만드는 테스트를 작성하라.
  2. +
  3. 실패시켜라. 통과시켜라. 그리고 정리하라.
  4. +
  5. 최상의 결과를 추구하지 말라.
  6. +
  7. 실패하는 가장 간단하고, 가장 구체적이며, 가장 퇴화한 테스트를 작성하라.
  8. +
  9. 가능하면 일반화하라.
  10. +
  11. 코드가 틀렸다고 느껴지면 잠시 멈춰서 설계를 고쳐라.
  12. +
  13. 더 복잡한 다음 경우로 넘어가기 전, 지금 다루고 있는 더 단순한 경우를 모조리 테스트하라.
  14. +
  15. 현재 테스트를 통과시키기 위해 너무 많은 구현을 해야 한다면, 테스트를 지우고 더 쉽게 통과할 수 있는 더 단순한 테스트를 작성하라.
  16. +
  17. 테스트 공간(test space)을 전부 포괄하는 신중하고 점진적인 패턴을 따르라.
  18. +
  19. 필요 없는 것을 여러분의 테스트에 넣지 말라.
  20. +
  21. 테스트에 실제 서비스 데이터를 사용하지 말라.
  22. +
  23. 테스트 구조를 제품 코드 구조로부터 분리하라.
  24. +
  25. 테스트가 구체적(specific)이 될수록 코드는 일반적(generic)이 된다.
  26. +
  27. 변환을 적용한 결과 최적이 아닌 해답에 도달했다면 다른 변환을 시도해보라.
  28. +
  29. 디버거 사용을 피하라
  30. +
+

참고 자료

+

소프트웨어 장인 정신 이야기, 로버트 C. 마틴 p.44 ~ p.209

\ No newline at end of file diff --git a/docs/test/stairstep.html b/docs/test/stairstep.html index 8199fc9d8..591bfc046 100644 --- a/docs/test/stairstep.html +++ b/docs/test/stairstep.html @@ -1,9 +1,9 @@ - + - -계단 테스트 | GG + +계단 테스트 | GG @@ -12,16 +12,16 @@ - - - + + + -
-

계단 테스트

계단 테스트(Stairstep Test)

추후에 필요로 할 클래스, 함수, 다른 구조를 만들도록 강제하기 위해 작성하는 테스트
+

계단 테스트

계단 테스트(Stairstep Test)

+

추후에 필요로 할 클래스, 함수, 다른 구조를 만들도록 강제하기 위해 작성하는 테스트
아무런 단정문이 없을 수도 있고, 기능이 조금 더 구현된다면 제거하고 포괄적인 테스트로 대신할 수 있다.
-복잡도를 필요한 수준까지 점진적으로 증가시킬 수 있게 도와주는 계단 역할을 하기 때문에 계단 테스트라고 부른다.

참고 자료

소프트웨어 장인 정신 이야기, 로버트 C. 마틴 p.74

- - +복잡도를 필요한 수준까지 점진적으로 증가시킬 수 있게 도와주는 계단 역할을 하기 때문에 계단 테스트라고 부른다.

+

참고 자료

+

소프트웨어 장인 정신 이야기, 로버트 C. 마틴 p.74

\ No newline at end of file diff --git a/docusaurus.html b/docusaurus.html index 4bdc5137c..c16e52451 100644 --- a/docusaurus.html +++ b/docusaurus.html @@ -2,8 +2,8 @@ - -Docusaurus | GG + +Docusaurus | GG @@ -12,34 +12,359 @@ - - - + + + -
-

Docusaurus

· 약 11분

팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.

설치

공식 홈페이지에 들어가서 최신 버전을 설치한다.

yarn create docusaurus

배포

배포 안내 문서
+

Docusaurus

· 약 11분

팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.

+

설치

+

공식 홈페이지에 들어가서 최신 버전을 설치한다.

+
yarn create docusaurus
+
+

배포

+

배포 안내 문서
netlify나 vercel 같은 서버리스 플랫폼을 추천하고 있고, 간단하고, 빠른 시간 안에 배포를 할 수 있다.
-이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.

레포지토리 생성

github pages를 이용하려면 예시와 같이 username.github.io 형태의 레포지토리를 생성해야 한다.
-이때 organization을 사용하는 경우 organization.github.io 형태의 레포지토리를 생성해서 사용한다.

설정 파일 수정

docusaurus.config
module.exports = {
// ...
url: 'https://greeng00se.github.io',
baseUrl: '/',
projectName: 'greeng00se.github.io',
organizationName: 'greeng00se',
trailingSlash: false,
// ...
};

토큰 설정

github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.
-이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.

github

브랜치 생성

github에서 gh-pages 브랜치를 하나 생성한다.
+이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.

+

레포지토리 생성

+

github pages를 이용하려면 예시와 같이 username.github.io 형태의 레포지토리를 생성해야 한다.
+이때 organization을 사용하는 경우 organization.github.io 형태의 레포지토리를 생성해서 사용한다.

+

설정 파일 수정

+
module.exports = {
+  // ...
+  url: 'https://greeng00se.github.io',
+  baseUrl: '/',
+  projectName: 'greeng00se.github.io',
+  organizationName: 'greeng00se',
+  trailingSlash: false,
+  // ...
+};
+
+

토큰 설정

+

github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.
+이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.

+

github

+

브랜치 생성

+

github에서 gh-pages 브랜치를 하나 생성한다.
repository -> settings -> pages -> branch에서 생성한 gh-pages로 브랜치를 변경한다.
-설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.

워크플로 작성

Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.
-배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.

.github/workflows/deploy.yml
name: blog

on:
push:
branches: [main]

jobs:
deploy:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build website
run: yarn build

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.DEPLOY_TOKEN }}
publish_dir: ./build
user_name: github-actions[bot]
user_email: 41898282+github-actions[bot]@users.noreply.github.com

댓글 기능

giscus를 이용하여 댓글 기능을 추가한다.

giscus 설정

  1. 공개 저장소여야 한다.
  2. giscus 앱이 설치되어 있어야 한다.
  3. Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.

자세한 내용은 giscus를 확인하자.

docusaurus 설정

swizzling을 이용하여 컴포넌트를 감싼다.
+설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.

+

워크플로 작성

+

Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.
+배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.

+
name: blog
+
+on:
+  push:
+    branches: [main]
+
+jobs:
+  deploy:
+    name: Deploy to GitHub Pages
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@v3
+        with:
+          node-version: 18
+          cache: yarn
+
+      - name: Install dependencies
+        run: yarn install --frozen-lockfile
+      - name: Build website
+        run: yarn build
+
+      - name: Deploy to GitHub Pages
+        uses: peaceiris/actions-gh-pages@v3
+        with:
+          github_token: ${{ secrets.DEPLOY_TOKEN }}
+          publish_dir: ./build
+          user_name: github-actions[bot]
+          user_email: 41898282+github-actions[bot]@users.noreply.github.com
+
+

댓글 기능

+

giscus를 이용하여 댓글 기능을 추가한다.

+

giscus 설정

+
    +
  1. 공개 저장소여야 한다.
  2. +
  3. giscus 앱이 설치되어 있어야 한다.
  4. +
  5. Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.
  6. +
+

자세한 내용은 giscus를 확인하자.

+

docusaurus 설정

+

swizzling을 이용하여 컴포넌트를 감싼다.
기존에 게시물을 giscus가 포함된 리액트 컴포넌트로 감싸는 형태가 된다.
-아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.

yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap

명령어를 입력하면 /src/theme/BlogPostItem/index.js 위치에 파일이 생성된다.
-파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.

/src/theme/BlogPostItem/index.js
import OriginalBlogPostItem from "@theme-original/BlogPostItem";
import React, { useEffect, useRef } from "react";
// @ts-expect-error internal code
import { useColorMode } from "@docusaurus/theme-common";
import { useBlogPost } from "@docusaurus/theme-common/internal";

const giscusSelector = "iframe.giscus-frame";

function BlogPostItem(props) {
const { colorMode } = useColorMode();
const { isBlogPostPage } = useBlogPost();
const giscusTheme = colorMode === "dark" ? "dark" : "light";
const containerRef = useRef(null);

useEffect(() => {
if (!isBlogPostPage) return;

const giscusEl = containerRef.current.querySelector(giscusSelector);

const createGiscusEl = () => {
const script = document.createElement("script");

script.src = "https://giscus.app/client.js";
script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");
script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");
script.setAttribute("data-category", "Announcements");
script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");
script.setAttribute("data-mapping", "pathname");
script.setAttribute("data-strict", "0");
script.setAttribute("data-reactions-enabled", "1");
script.setAttribute("data-emit-metadata", "0");
script.setAttribute("data-input-position", "bottom");
script.setAttribute("data-theme", giscusTheme);
script.setAttribute("data-lang", "ko");
script.crossOrigin = "anonymous";
script.async = true;

containerRef.current.appendChild(script);
};

const postThemeMessage = () => {
const message = {
setConfig: {
theme: giscusTheme,
}
};

giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
};

giscusEl ? postThemeMessage() : createGiscusEl();
}, [giscusTheme]);

return (
<>
<OriginalBlogPostItem {...props} />
{isBlogPostPage && <div ref={containerRef} />}
</>
);
}

export default BlogPostItem;

알고리아 설정 및 직접 관리하기

알고리아를 사용하면 검색 기능을 추가할 수 있다.
-유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.

무료 플랜은 직접 인덱스를 수집하는 방법과, docsearch를 이용하는 방법이 있다.
+아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.

+
yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap
+
+

명령어를 입력하면 /src/theme/BlogPostItem/index.js 위치에 파일이 생성된다.
+파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.

+
import OriginalBlogPostItem from "@theme-original/BlogPostItem";
+import React, { useEffect, useRef } from "react";
+// @ts-expect-error internal code
+import { useColorMode } from "@docusaurus/theme-common";
+import { useBlogPost } from "@docusaurus/theme-common/internal";
+
+const giscusSelector = "iframe.giscus-frame";
+
+function BlogPostItem(props) {
+  const { colorMode } = useColorMode();
+  const { isBlogPostPage } = useBlogPost();
+  const giscusTheme = colorMode === "dark" ? "dark" : "light";
+  const containerRef = useRef(null);
+
+  useEffect(() => {
+    if (!isBlogPostPage) return;
+
+    const giscusEl = containerRef.current.querySelector(giscusSelector);
+
+    const createGiscusEl = () => {
+      const script = document.createElement("script");
+
+      script.src = "https://giscus.app/client.js";
+      script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");
+      script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");
+      script.setAttribute("data-category", "Announcements");
+      script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");
+      script.setAttribute("data-mapping", "pathname");
+      script.setAttribute("data-strict", "0");
+      script.setAttribute("data-reactions-enabled", "1");
+      script.setAttribute("data-emit-metadata", "0");
+      script.setAttribute("data-input-position", "bottom");
+      script.setAttribute("data-theme", giscusTheme);
+      script.setAttribute("data-lang", "ko");
+      script.crossOrigin = "anonymous";
+      script.async = true;
+      
+      containerRef.current.appendChild(script);
+    };
+
+    const postThemeMessage = () => {
+      const message = {
+        setConfig: {
+          theme: giscusTheme,
+        }
+      };
+
+      giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
+    };
+
+    giscusEl ? postThemeMessage() : createGiscusEl();
+  }, [giscusTheme]);
+
+  return (
+    <>
+      <OriginalBlogPostItem {...props} />
+      {isBlogPostPage && <div ref={containerRef} />}
+    </>
+  );
+}
+
+export default BlogPostItem;
+
+

알고리아 설정 및 직접 관리하기

+

알고리아를 사용하면 검색 기능을 추가할 수 있다.
+유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.

+

무료 플랜은 직접 인덱스를 수집하는 방법과, docsearch를 이용하는 방법이 있다.
docsearch에 등록한다면 일주일에 한 번씩 크롤링이 진행된다.
-이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.

알고리아 애플리케이션 생성 및 키 확인

회원가입을 하고 새로운 애플리케이션 생성을 누른다.
-생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.

algolia

키 생성

직접 인덱스를 수집하기 위한 키를 생성한다.
-addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.

key

.env 파일 생성

프로젝트 폴더 상단에 .env 파일을 생성한다.

.env
APPLICATION_ID=MVIU5UEMOM
API_KEY=인덱스_생성용_키

config 파일 생성

마찬가지로 최상단에 config.json 파일을 생성한다. -설정 파일은 해당 링크를 참고한다.
-또는 Docusaurus의 설정 파일을 참고한다.

config.json
{
"index_name": "teco",
"start_urls": [
"https://teco-chat.github.io/"
],
"sitemap_urls": [
"https://teco-chat.github.io/sitemap.xml"
],
"sitemap_alternate_links": true,
"stop_urls": [
"/tests"
],
"selectors": {
"lvl0": {
"selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
"type": "xpath",
"global": true,
"default_value": "Documentation"
},
"lvl1": "header h1",
"lvl2": "article h2",
"lvl3": "article h3",
"lvl4": "article h4",
"lvl5": "article h5, article td:first-child",
"lvl6": "article h6",
"text": "article p, article li, article td:last-child"
},
"strip_chars": " .,;:#",
"custom_settings": {
"separatorsToIndex": "_",
"attributesForFaceting": [
"language",
"version",
"type",
"docusaurus_tag"
],
"attributesToRetrieve": [
"hierarchy",
"content",
"anchor",
"url",
"url_without_anchor",
"type"
]
},
"conversation_id": [
"833762294"
],
"nb_hits": 46250
}

docker 이용하여 크롤링

docker와 jq가 필요하다.
-jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.

brew install jq

다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.

docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper

docusaurus 설정

전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.

docusaurus.config
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...
algolia: {
appId: 'MVIU5UEMOM', // Application ID
apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key
indexName: 'teco', // config.json에 설정한 인덱스명
contextualSearch: true,
},
})

부가 설정

화면 상단 Github Icon

파일 최하단에 아래 css 구문을 추가한다.

/src/css/custom.css
.header-github-link:hover {
opacity: 0.6;
}

.header-github-link:before {
content: '';
width: 24px;
height: 24px;
display: flex;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}

html[data-theme='dark'] .header-github-link:before {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}

themeconfig -> navbar에 github link를 설정한다.

docusaurus.config
navbar: {
title: 'HELLO',
items: [
{
href: 'https://github.com/greeng00se',
position: 'right',
className: 'header-github-link',
'aria-label': 'GitHub repository',
},
],
},

코드블럭

java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.
-prism 설정을 아래와 같이 변경해 준다.

docusaurus.config
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
additionalLanguages: ['java', 'kotlin'],
}

mermaid

mermaid를 사용하려면 @docusaurus/theme-mermaid 를 설치해야 한다.

yarn add @docusaurus/theme-mermaid

설치 후 아래와 같이 설정을 추가한다.

docusaurus.config
const config = {
...
markdown: {
mermaid: true,
},
themes: [
'@docusaurus/theme-mermaid'
],
};

themeConfig에서 mermaid의 테마를 지정할 수 있다.

docusaurus.config
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...
mermaid: {
theme: {
light: 'neutral',
dark: 'dark'
},
},
}),

국제화 설정

국제화 설정을 한다면 Older Entries 형태의 설명이 다음 페이지 로 변경된다.
-설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.

docusaurus.config
i18n: {
defaultLocale: "ko",
locales: ["ko"],
},

블로그 글 author

팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.

author

authors.yml 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.

/blog/authors.yml
herb:
name: 허브
title: Backend
url: https://github.com/greeng00se
image_url: https://github.com/greeng00se.png

mallang:
name: 말랑
title: Backend
url: https://github.com/shin-mallang
image_url: https://github.com/shin-mallang.png

블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.

---
slug: 1
title: Hello World
authors: [herb, mallang]
tags: [hello, docusaurus]
---

첫 번째 문서 내용
- - +이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.

+ +

알고리아 애플리케이션 생성 및 키 확인

+

회원가입을 하고 새로운 애플리케이션 생성을 누른다.
+생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.

+

algolia

+

키 생성

+

직접 인덱스를 수집하기 위한 키를 생성한다.
+addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.

+

key

+

.env 파일 생성

+

프로젝트 폴더 상단에 .env 파일을 생성한다.

+
APPLICATION_ID=MVIU5UEMOM
+API_KEY=인덱스_생성용_키
+
+

config 파일 생성

+

마찬가지로 최상단에 config.json 파일을 생성한다. +설정 파일은 해당 링크를 참고한다.
+또는 Docusaurus의 설정 파일을 참고한다.

+
{
+  "index_name": "teco",
+  "start_urls": [
+    "https://teco-chat.github.io/"
+  ],
+  "sitemap_urls": [
+    "https://teco-chat.github.io/sitemap.xml"
+  ],
+  "sitemap_alternate_links": true,
+  "stop_urls": [
+    "/tests"
+  ],
+  "selectors": {
+    "lvl0": {
+      "selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
+      "type": "xpath",
+      "global": true,
+      "default_value": "Documentation"
+    },
+    "lvl1": "header h1",
+    "lvl2": "article h2",
+    "lvl3": "article h3",
+    "lvl4": "article h4",
+    "lvl5": "article h5, article td:first-child",
+    "lvl6": "article h6",
+    "text": "article p, article li, article td:last-child"
+  },
+  "strip_chars": " .,;:#",
+  "custom_settings": {
+    "separatorsToIndex": "_",
+    "attributesForFaceting": [
+      "language",
+      "version",
+      "type",
+      "docusaurus_tag"
+    ],
+    "attributesToRetrieve": [
+      "hierarchy",
+      "content",
+      "anchor",
+      "url",
+      "url_without_anchor",
+      "type"
+    ]
+  },
+  "conversation_id": [
+    "833762294"
+  ],
+  "nb_hits": 46250
+}
+
+

docker 이용하여 크롤링

+

docker와 jq가 필요하다.
+jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.

+
brew install jq
+
+

다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.

+
docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper
+
+

docusaurus 설정

+

전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.

+
themeConfig:
+  /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+  ({
+    ...
+    algolia: {
+      appId: 'MVIU5UEMOM', // Application ID
+      apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key
+      indexName: 'teco', // config.json에 설정한 인덱스명
+      contextualSearch: true,
+    },
+  })
+
+

부가 설정

+

화면 상단 Github Icon

+

파일 최하단에 아래 css 구문을 추가한다.

+
.header-github-link:hover {
+  opacity: 0.6;
+}
+
+.header-github-link:before {
+  content: '';
+  width: 24px;
+  height: 24px;
+  display: flex;
+  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
+    no-repeat;
+}
+
+html[data-theme='dark'] .header-github-link:before {
+  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
+    no-repeat;
+}
+
+

themeconfig -> navbar에 github link를 설정한다.

+
navbar: {
+  title: 'HELLO',
+  items: [
+    {
+        href: 'https://github.com/greeng00se',
+        position: 'right',
+        className: 'header-github-link',
+        'aria-label': 'GitHub repository',
+    },
+  ],
+},
+
+

코드블럭

+

java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.
+prism 설정을 아래와 같이 변경해 준다.

+
prism: {
+  theme: lightCodeTheme,
+  darkTheme: darkCodeTheme,
+  additionalLanguages: ['java', 'kotlin'],
+}
+
+

mermaid

+

mermaid를 사용하려면 @docusaurus/theme-mermaid 를 설치해야 한다.

+
yarn add @docusaurus/theme-mermaid
+
+

설치 후 아래와 같이 설정을 추가한다.

+
const config = {
+  ...
+  markdown: {
+    mermaid: true,
+  },
+  themes: [
+    '@docusaurus/theme-mermaid'
+  ],
+};
+
+

themeConfig에서 mermaid의 테마를 지정할 수 있다.

+
themeConfig:
+    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+    ({
+      ...
+      mermaid: {
+        theme: {
+          light: 'neutral', 
+          dark: 'dark'
+        },
+      },
+    }),
+
+

국제화 설정

+

국제화 설정을 한다면 Older Entries 형태의 설명이 다음 페이지 로 변경된다.
+설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.

+
i18n: {
+  defaultLocale: "ko",
+  locales: ["ko"],
+},
+
+

블로그 글 author

+

팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.

+

author

+

authors.yml 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.

+
herb:
+  name: 허브
+  title: Backend
+  url: https://github.com/greeng00se
+  image_url: https://github.com/greeng00se.png
+
+mallang:
+  name: 말랑
+  title: Backend
+  url: https://github.com/shin-mallang
+  image_url: https://github.com/shin-mallang.png
+
+

블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.

+
---
+slug: 1
+title: Hello World
+authors: [herb, mallang]
+tags: [hello, docusaurus]
+---
+
+첫 번째 문서 내용
+
\ No newline at end of file diff --git a/grasp.html b/grasp.html index e8fffb933..2c8305a1a 100644 --- a/grasp.html +++ b/grasp.html @@ -2,8 +2,8 @@ - -일반적인 책임 할당을 위한 패턴 | GG + +일반적인 책임 할당을 위한 패턴 | GG @@ -12,16 +12,101 @@ - - - + + + -
-

일반적인 책임 할당을 위한 패턴

· 약 9분

GRASP(General Responsibility Assignment Software Pattern)

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

각 패턴마다 Solution과 Problem로 구성되어 있다.

정보 전문가 패턴(Information Expert)

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

필요한 정보를 가진 객체들로 책임이 분산된다.

창조자 패턴(Creator)

Q: 누가 객체 A를 생성하는가?

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A 객체를 긴밀하게 사용한다.
  • B가 A 객체의 초기값을 가지고 있다.

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

낮은 결합도 패턴(Low Coupling)

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

결합도(Coupling) -객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

  • 오브젝트 p.17

결합도를 낮춘다면 다음과 같은 이점이 있다.

  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • 재사용이 편리해진다.
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)

높은 응집도 패턴(High Cohesion)

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

응집도(Cohesion) -연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

  • 오브젝트 p.26

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • 유지보수가 쉬워진다.
  • 낮은 결합도 또한 지원한다.
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.

컨트롤러 패턴(Controller)

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

어떤 서브시스템이 존재한다고 가정할 때

  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.

다형성 패턴(Polymorphism)

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

변경 보호 패턴(Protected Variations)

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

간접 참조 패턴(Indirection)

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

순수한 가공물 패턴(Pure Fabrication)

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.

참고 자료

오브젝트 5장. 책임 할당하기, 조영호

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

GRASP, 한빛 네트워크

- - +

일반적인 책임 할당을 위한 패턴

· 약 9분

GRASP(General Responsibility Assignment Software Pattern)

+

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

+

각 패턴마다 Solution과 Problem로 구성되어 있다.

+

정보 전문가 패턴(Information Expert)

+

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

+

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

+

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

+

필요한 정보를 가진 객체들로 책임이 분산된다.

+

창조자 패턴(Creator)

+

Q: 누가 객체 A를 생성하는가?

+

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

+
    +
  • B가 A 객체를 포함 또는 참조한다.
  • +
  • B가 A 객체를 기록한다.
  • +
  • B가 A 객체를 긴밀하게 사용한다.
  • +
  • B가 A 객체의 초기값을 가지고 있다.
  • +
+

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

+

낮은 결합도 패턴(Low Coupling)

+

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

+

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

+
+

결합도(Coupling) +객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

+
+
    +
  • 오브젝트 p.17
  • +
+
+
+

결합도를 낮춘다면 다음과 같은 이점이 있다.

+
    +
  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • +
  • 재사용이 편리해진다.
  • +
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)
  • +
+

높은 응집도 패턴(High Cohesion)

+

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

+

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

+
+

응집도(Cohesion) +연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

+
+
    +
  • 오브젝트 p.26
  • +
+
+
+

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

+
    +
  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • +
  • 유지보수가 쉬워진다.
  • +
  • 낮은 결합도 또한 지원한다.
  • +
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.
  • +
+

컨트롤러 패턴(Controller)

+

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

+

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

+

어떤 서브시스템이 존재한다고 가정할 때

+
    +
  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • +
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • +
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.
  • +
+

다형성 패턴(Polymorphism)

+

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

+

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

+

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

+

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

+

변경 보호 패턴(Protected Variations)

+

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

+

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

+

간접 참조 패턴(Indirection)

+

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

+

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

+

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

+

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

+

순수한 가공물 패턴(Pure Fabrication)

+

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

+

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

+

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

+

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

+

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

+
    +
  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • +
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.
  • +
+

참고 자료

+

오브젝트 5장. 책임 할당하기, 조영호

+

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

+

GRASP, 한빛 네트워크

\ No newline at end of file diff --git a/index.html b/index.html index cdcd83b9d..eb66c4a65 100644 --- a/index.html +++ b/index.html @@ -2,8 +2,8 @@ - -GG + +GG @@ -12,14 +12,11 @@ - - - + + + -
-
- - +
\ No newline at end of file diff --git a/innodb-lock.html b/innodb-lock.html index d1884144e..17a062791 100644 --- a/innodb-lock.html +++ b/innodb-lock.html @@ -2,8 +2,8 @@ - -InnoDB 스토리지 엔진의 잠금 | GG + +InnoDB 스토리지 엔진의 잠금 | GG @@ -12,33 +12,69 @@ - - - + + + -
-

InnoDB 스토리지 엔진의 잠금

· 약 6분

InnoDB 스토리지 엔진의 잠금

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
-보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
-InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

낙관적 동시성 제어(OCC, Optimistic concurrency control)

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

비관적 동시성 제어(PCC, Pessimistic Concurrency Control)

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
-일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

Shared & Exclusive Locks

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

공유 잠금(S, shared lock)

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
+

InnoDB 스토리지 엔진의 잠금

· 약 6분

InnoDB 스토리지 엔진의 잠금

+

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
+보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

+

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
+InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

+

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

+

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
+일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

+

Shared & Exclusive Locks

+

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

+

공유 잠금(S, shared lock)

+

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
다른 트랜잭션에서 읽기가 가능하지만, 쓰기는 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

배타적 잠금(X, exclusive lock)

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
+예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

+

배타적 잠금(X, exclusive lock)

+

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
락을 건 트랜잭션만이 해당 데이터에 접근 가능하다. 다른 트랜잭션의 경우 읽기, 쓰기가 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

Intention Locks

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
+예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

+

Intention Locks

+

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
테이블에 있는 로우에 대해서 나중에 요청되는 것이 어떤 형태의 잠금인지 가리키기 위해 사용된다.
기본적으로 로우 단위 잠금을 수행하기 전에 인텐션 잠금을 먼저 획득한다.
-인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

인텐션 공유 잠금(IS, intention shared lock)

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

인텐션 배타적 잠금(IX, intention exclusive lock)

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

잠금간의 호환성

XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

Record Locks

레코드 자체만을 잠그는 락이다.
-InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

Gap Locks

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

Next-Key Locks

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
-REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

AUTO-INC Locks

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
+인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

+

인텐션 공유 잠금(IS, intention shared lock)

+

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

+

인텐션 배타적 잠금(IX, intention exclusive lock)

+

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

+

** 잠금간의 호환성 **

+
XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible
+

Record Locks

+

레코드 자체만을 잠그는 락이다.
+InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

+

Gap Locks

+

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

+

Next-Key Locks

+

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
+REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

+

AUTO-INC Locks

+

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
InnoDB 는 내부적으로 AUTO-INC 락이라고 하는 테이블 수준의 잠금을 사용한다.
-트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

잠금 예시

-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
-- Record Locks: 10에 대해 락이 걸린다.
SELECT * FROM table_name where id = 10 for update;

-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
SELECT * FROM table_name where id > 100 for update;

-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Optimistic and Pessimistic record locking, IBM
-MySQL Innodb Locks, cecil1018
-MySQL 8.0 InnoDB Locks, MySQL
-Locks Set by Different SQL Statements in InnoDB, MySQL

- - +트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

+

잠금 예시

+
-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
+-- Record Locks: 10에 대해 락이 걸린다.
+SELECT * FROM table_name where id = 10 for update;
+
+-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
+SELECT * FROM table_name where id > 100 for update;
+
+-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
+SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Optimistic and Pessimistic record locking, IBM
+MySQL Innodb Locks, cecil1018
+MySQL 8.0 InnoDB Locks, MySQL
+Locks Set by Different SQL Statements in InnoDB, MySQL

\ No newline at end of file diff --git a/intellij-settings.html b/intellij-settings.html index 971679cf1..4f64f8f5c 100644 --- a/intellij-settings.html +++ b/intellij-settings.html @@ -2,8 +2,8 @@ - -IntelliJ 설정 | GG + +IntelliJ 설정 | GG @@ -12,14 +12,22 @@ - - - + + + -
-

IntelliJ 설정

· 약 1분

Import 자동 적용

Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly

auto-import

저장시 동작

Prefrences > Tools > Actions on Save

actions-on-save

Reformat Code: Code Reformmating

Optimize imports: 사용하지 않는 Import 제거

Rearrange: Code Style > Arrangement 설정 기반 코드 재정렬

메소드 추출, 변수 추출시 final 적용

Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier

final-modifier

- - +

IntelliJ 설정

· 약 1분

Import 자동 적용

+

Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly

+

auto-import

+

저장시 동작

+

Prefrences > Tools > Actions on Save

+

actions-on-save

+

Reformat Code: Code Reformmating

+

Optimize imports: 사용하지 않는 Import 제거

+

Rearrange: Code Style > Arrangement 설정 기반 코드 재정렬

+

메소드 추출, 변수 추출시 final 적용

+

Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier

+

final-modifier

\ No newline at end of file diff --git a/java-class-file.html b/java-class-file.html index d020ce7bc..036cf01d4 100644 --- a/java-class-file.html +++ b/java-class-file.html @@ -2,8 +2,8 @@ - -자바 클래스 파일 구조 | GG + +자바 클래스 파일 구조 | GG @@ -12,31 +12,84 @@ - - - + + + -
-

자바 클래스 파일 구조

· 약 6분

클래스 파일

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
-컴파일된 클래스파일은 어떤 구조로 되어있을까?

클래스 파일의 데이터 형식

8비트 바이트의 스트림으로 구성된다.
+

자바 클래스 파일 구조

· 약 6분

클래스 파일

+

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
+컴파일된 클래스파일은 어떤 구조로 되어있을까?

+

클래스 파일의 데이터 형식

+

8비트 바이트의 스트림으로 구성된다.
16비트 및 32비트의 데이터는 각각 2개, 4개의 연속된 8비트를 읽어서 구성된다.
-멀티바이트의 경우 항상 big endian 순서로 저장된다.

u1 → unsigned 1byte
+멀티바이트의 경우 항상 big endian 순서로 저장된다.

+

u1 → unsigned 1byte
u2 → unsigned 2byte
-u4 → unsigned 4byte

클래스 파일 구조

ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

매직넘버

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
-보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

클래스 파일 포맷 버전

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

class file format major versions

Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61

상수 풀

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
+u4 → unsigned 4byte

+

클래스 파일 구조

+
ClassFile {
+    u4             magic;
+    u2             minor_version;
+    u2             major_version;
+    u2             constant_pool_count;
+    cp_info        constant_pool[constant_pool_count-1];
+    u2             access_flags;
+    u2             this_class;
+    u2             super_class;
+    u2             interfaces_count;
+    u2             interfaces[interfaces_count];
+    u2             fields_count;
+    field_info     fields[fields_count];
+    u2             methods_count;
+    method_info    methods[methods_count];
+    u2             attributes_count;
+    attribute_info attributes[attributes_count];
+}
+
+

매직넘버

+

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
+보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

+

클래스 파일 포맷 버전

+

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

+
    +
  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D
  • +
+

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

+

class file format major versions

+
Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61
+

상수 풀

+

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
클래스명, 상수명, 상수 값, 필드명, 메서드명과 같은 값들이 존재한다.
-JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

액세스 플래그

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
-예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

Class access and property modifiers

Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.

this_class

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
-해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

super_class

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
-아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

interface, field, method

각각의 개수와, 정보에 대한 값이 들어있다.
-interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

attributes

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
-정해진 클래스 파일의 구조를 확장하는 역할을 한다.

클래스 파일 확인하면서 사용한 툴

IntelliJ plugin - BinEd
-IntelliJ plugin - jclasslib Bytecode Viewer

참고 자료

2장 JVM 이야기, 자바 최적화
-Class file in Java, File Format
-java se11 Class 파일 형식, Oracle
-java se17 Class 파일 형식, Oracle

- - +JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

+

액세스 플래그

+

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
+예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

+
    +
  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT
  • +
+

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

+

Class access and property modifiers

+
Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.
+

this_class

+

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
+해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

+

super_class

+

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
+아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

+

interface, field, method

+

각각의 개수와, 정보에 대한 값이 들어있다.
+interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

+

attributes

+

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
+정해진 클래스 파일의 구조를 확장하는 역할을 한다.

+

클래스 파일 확인하면서 사용한 툴

+

IntelliJ plugin - BinEd
+IntelliJ plugin - jclasslib Bytecode Viewer

+

참고 자료

+

2장 JVM 이야기, 자바 최적화
+Class file in Java, File Format
+java se11 Class 파일 형식, Oracle
+java se17 Class 파일 형식, Oracle

\ No newline at end of file diff --git a/java-spring-springboot.html b/java-spring-springboot.html index 80f93d832..934809e62 100644 --- a/java-spring-springboot.html +++ b/java-spring-springboot.html @@ -2,8 +2,8 @@ - -자바 17, 스프링 6.0, 스프링 부트 3.1 | GG + +자바 17, 스프링 6.0, 스프링 부트 3.1 | GG @@ -12,29 +12,100 @@ - - - + + + -
-

자바 17, 스프링 6.0, 스프링 부트 3.1

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
-2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

자바 변경 사항

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
-따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

Switch Expressions(Java 14)

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

enum RESULT {
WIN, LOSE, DRAW
}

RESULT result = RESULT.WIN;

int prize = switch (result) {
case WIN -> 10_000_000;
case LOSE, DRAW -> 5_000_000;
default -> 0;
};

주요 특징은 다음과 같다.

  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • break 문이 필요 없다.
  • default 블록을 통해 기본 값을 지정할 수 있다.

Text Block(Java 15)

Java 15에는 새로운 문자열 표현방식이 추가되었다.
-긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("""
SELECT p FROM Post p
WHERE p.title LIKE %:keyword%
OR p.content LIKE %:keyword%
""")
List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
}

NPE 메시지(Java 15)

String name = null;
name.chars();

/**
# before
java.lang.NullPointerException
at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)

# after
Cannot invoke "String.chars()" because "name" is null
java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
*/

Record(Java 16)

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
+

자바 17, 스프링 6.0, 스프링 부트 3.1

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

+

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
+2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

+

자바 변경 사항

+

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
+따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

+

Switch Expressions(Java 14)

+

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

+
enum RESULT {
+    WIN, LOSE, DRAW
+}
+
+RESULT result = RESULT.WIN;
+
+int prize = switch (result) {
+    case WIN -> 10_000_000;
+    case LOSE, DRAW -> 5_000_000;
+	default -> 0;
+};
+
+

주요 특징은 다음과 같다.

+
    +
  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • +
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • +
  • break 문이 필요 없다.
  • +
  • default 블록을 통해 기본 값을 지정할 수 있다.
  • +
+

Text Block(Java 15)

+

Java 15에는 새로운 문자열 표현방식이 추가되었다.
+긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

+
@Repository
+public interface PostRepository extends JpaRepository<Post, Long> {
+    @Query("""
+        SELECT p FROM Post p
+        WHERE p.title LIKE %:keyword%
+        OR p.content LIKE %:keyword%
+        """)
+    List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
+}
+
+

NPE 메시지(Java 15)

+
String name = null;
+name.chars();
+
+/** 
+# before
+java.lang.NullPointerException
+	at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)
+
+# after
+Cannot invoke "String.chars()" because "name" is null
+java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
+*/
+
+

Record(Java 16)

+

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
Record를 선언하는 경우 접근자, 생성자, equals & hashcode, toString이 제공된다.
-데이터 전송 용도로 적합해 보인다.

public record PostDto(String title, String content) {
}

추가적인 변경사항

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

스프링, 스프링 부트 변경 사항

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
-따라서 필요해보이는 몇개 정도만 정리했다.

스프링 요구사항

Java 17, Jakarta EE 9 이상이어야 한다.

네임스페이스 변경

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

PathPatternParser - trailing slash 허용하지 않음

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
-6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

PathPatternParser used by default (with the ability to opt into PathMatcher).

HTTP interface client

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
-자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

스프링 부트 최소 요구사항

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
-이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

참고 자료

어느 월급쟁이개발자 의 스프링 부트 따라잡기
-자바 9-16 주요 특징 복습하기
-Java EE에서 Jakarta EE로의 전환
-Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
-What's New in Spring Framework 6.x
-Spring Boot 3.0 Release Notes
-Spring Boot 3.1 Release Notes

- - +데이터 전송 용도로 적합해 보인다.

+
public record PostDto(String title, String content) {
+}
+
+

추가적인 변경사항

+

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

+

스프링, 스프링 부트 변경 사항

+

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
+따라서 필요해보이는 몇개 정도만 정리했다.

+

스프링 요구사항

+

Java 17, Jakarta EE 9 이상이어야 한다.

+

네임스페이스 변경

+

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

+

PathPatternParser - trailing slash 허용하지 않음

+

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
+6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

+
+

PathPatternParser used by default (with the ability to opt into PathMatcher).

+
+

HTTP interface client

+

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
+자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

+

스프링 부트 최소 요구사항

+

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
+이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

+

참고 자료

+

어느 월급쟁이개발자 의 스프링 부트 따라잡기
+자바 9-16 주요 특징 복습하기
+Java EE에서 Jakarta EE로의 전환
+Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
+What's New in Spring Framework 6.x
+Spring Boot 3.0 Release Notes
+Spring Boot 3.1 Release Notes

\ No newline at end of file diff --git a/jdbc-retrospective.html b/jdbc-retrospective.html index 07532c01a..c72e0fcf0 100644 --- a/jdbc-retrospective.html +++ b/jdbc-retrospective.html @@ -2,8 +2,8 @@ - -Jdbc 라이브러리 구현 미션 회고 | GG + +Jdbc 라이브러리 구현 미션 회고 | GG @@ -12,24 +12,94 @@ - - - + + + -
-

Jdbc 라이브러리 구현 미션 회고

· 약 4분

Jdbc 구현

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
-미션 목표는 다음과 같다.

  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • 데이터베이스에 대한 이해도를 높인다.

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

JdbcTemplate

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
+

Jdbc 라이브러리 구현 미션 회고

· 약 4분

1단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267
+2단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358
+3단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448
+4단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515

+

Jdbc 구현

+

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
+미션 목표는 다음과 같다.

+
    +
  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • +
  • 데이터베이스에 대한 이해도를 높인다.
  • +
+

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

+

JdbcTemplate

+

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
템플릿 콜백 패턴을 적절하게 적용하여 중복을 비교적 간단하게 제거할 수 있었다.
-예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

public class JdbcTemplate {

private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);

private final DataSource dataSource;
private final StatementCreator statementCreator;
private final StatementExecutor statementExecutor;

public JdbcTemplate(final DataSource dataSource) {
this(dataSource, new StatementCreator(), new StatementExecutor());
}

JdbcTemplate(
final DataSource dataSource,
final StatementCreator statementCreator,
final StatementExecutor statementExecutor
) {
this.dataSource = dataSource;
this.statementCreator = statementCreator;
this.statementExecutor = statementExecutor;
}

private <T> T query(
final String sql,
final PreparedStatementCallback<T> preparedStatementCallback,
final Object... parameters
) {
final Connection connection = DataSourceUtils.getConnection(dataSource);
try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
return preparedStatementCallback.execute(preparedStatement);
} catch (final SQLException e) {
log.error(e.getMessage(), e);
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(connection, dataSource);
}
}

public void update(final String sql, final Object... parameters) {
query(sql, PreparedStatement::executeUpdate, parameters);
}

public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
if (results.size() > 1) {
throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
}
return results.stream().findAny();
}

public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
}
}

트랜잭션 적용

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
+예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

+
public class JdbcTemplate {
+
+    private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);
+
+    private final DataSource dataSource;
+    private final StatementCreator statementCreator;
+    private final StatementExecutor statementExecutor;
+
+    public JdbcTemplate(final DataSource dataSource) {
+        this(dataSource, new StatementCreator(), new StatementExecutor());
+    }
+
+    JdbcTemplate(
+            final DataSource dataSource,
+            final StatementCreator statementCreator,
+            final StatementExecutor statementExecutor
+    ) {
+        this.dataSource = dataSource;
+        this.statementCreator = statementCreator;
+        this.statementExecutor = statementExecutor;
+    }
+
+    private <T> T query(
+            final String sql,
+            final PreparedStatementCallback<T> preparedStatementCallback,
+            final Object... parameters
+    ) {
+        final Connection connection = DataSourceUtils.getConnection(dataSource);
+        try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
+            return preparedStatementCallback.execute(preparedStatement);
+        } catch (final SQLException e) {
+            log.error(e.getMessage(), e);
+            throw new DataAccessException(e);
+        } finally {
+            DataSourceUtils.releaseConnection(connection, dataSource);
+        }
+    }
+
+    public void update(final String sql, final Object... parameters) {
+        query(sql, PreparedStatement::executeUpdate, parameters);
+    }
+
+    public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+        if (results.size() > 1) {
+            throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
+        }
+        return results.stream().findAny();
+    }
+
+    public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+    }
+}
+
+

트랜잭션 적용

+

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
트랜잭션 동기화란 트랜잭션을 시작하기 위한 Connection 객체를 ThreadLocal과 같은 공간에 따로 저장 후, 필요할 때 저장된 Connection을 가져다 사용하는 방식이다.
-아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

마무리

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
+아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

+ +

마무리

+

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
꼼꼼히 코드를 봐준 리뷰어 호이 그리고 연휴 동안 계속 티키타카 하면서 재밌게 리뷰한 민트에게 감사하다.
-회고 이만 끝내고 리팩터링 미션 하러가야겠다. 😊

- - +회고 이만 끝내고 리팩터링 미션 하러가야겠다. 😊

\ No newline at end of file diff --git a/jenkins.html b/jenkins.html index 56c282cfc..6be283ba9 100644 --- a/jenkins.html +++ b/jenkins.html @@ -2,8 +2,8 @@ - -Jenkins로 CI/CD 설정 | GG + +Jenkins로 CI/CD 설정 | GG @@ -12,31 +12,218 @@ - - - + + + -
-

Jenkins로 CI/CD 설정

· 약 8분

설정 환경

소프트웨어 이미지: Amazon Linux 2023 AMI
+

Jenkins로 CI/CD 설정

· 약 8분

설정 환경

+

소프트웨어 이미지: Amazon Linux 2023 AMI
아키텍쳐: ARM
인스턴스 유형: t4g.small
환경 구성이 완료된 Elastic Beanstalk
-단일 Spring Boot 프로젝트가 존재하는 Github Repository

[EC2 CLI] Swap 메모리 설정

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
-아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

# fallocate 이용하여 스왑 파일 생성
sudo fallocate -l 2G /swapfile

# 권한 설정
sudo chmod 600 /swapfile

# 파일을 Swap 포맷으로 변경 후 시스템에 등록
sudo mkswap /swapfile
sudo swapon /swapfile

# Swap 메모리 부팅시 자동으로 마운트하도록 적용
# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
sudo vim /etc/fstab

[EC2 CLI] jenkins 설치

sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install java-17-amazon-corretto-devel
sudo yum install jenkins
sudo systemctl daemon-reload

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

[EC2 CLI] Jenkins 시작

sudo systemctl enable jenkins
sudo systemctl start jenkins

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

[EC2 CLI] nginx & git 설치

sudo yum install nginx
sudo systemctl enable nginx
sudo systemctl start nginx

sudo yum install git

nginx와 코드를 불러올 때 사용할 git을 설치한다.

[EC2 CLI] nginx 리버스 프록시 설정

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

upstream jenkins {
keepalive 32; # keepalive connections
server 127.0.0.1:8080; # jenkins ip and port
}

# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 80; # Listen on port 80 for IPv4 requests

server_name jenkins.example.com; # replace 'jenkins.example.com' with your server domain name

# this is the jenkins web root directory
# (mentioned in the output of "systemctl cat jenkins")
root /var/run/jenkins/war/;

access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;

# pass through headers from Jenkins that Nginx considers invalid
ignore_invalid_headers off;

location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
# rewrite all static files into requests to the root
# E.g /static/12345678/css/something.css will become /css/something.css
rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
}

location /userContent {
# have nginx handle all the static requests to userContent folder
# note : This is the $JENKINS_HOME dir
root /var/lib/jenkins/;
if (!-f $request_filename){
# this file does not exist, might be a directory or a /**view** url
rewrite (.*) /$1 last;
break;
}
sendfile on;
}

location / {
sendfile off;
proxy_pass http://jenkins;
proxy_redirect default;
proxy_http_version 1.1;

# Required for Jenkins websocket agents
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_max_temp_file_size 0;

#this is the maximum upload size
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffering off;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection ""; # Clear for keepalive
}

}

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
+단일 Spring Boot 프로젝트가 존재하는 Github Repository

+

[EC2 CLI] Swap 메모리 설정

+

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
+아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

+
# fallocate 이용하여 스왑 파일 생성
+sudo fallocate -l 2G /swapfile
+
+# 권한 설정
+sudo chmod 600 /swapfile
+
+# 파일을 Swap 포맷으로 변경 후 시스템에 등록
+sudo mkswap /swapfile
+sudo swapon /swapfile
+
+# Swap 메모리 부팅시 자동으로 마운트하도록 적용
+# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
+sudo vim /etc/fstab
+
+

[EC2 CLI] jenkins 설치

+
sudo wget -O /etc/yum.repos.d/jenkins.repo \
+    https://pkg.jenkins.io/redhat-stable/jenkins.repo
+sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
+sudo yum upgrade
+sudo yum install java-17-amazon-corretto-devel
+sudo yum install jenkins
+sudo systemctl daemon-reload
+
+

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

+

[EC2 CLI] Jenkins 시작

+
sudo systemctl enable jenkins
+sudo systemctl start jenkins
+
+

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

+

[EC2 CLI] nginx & git 설치

+
sudo yum install nginx
+sudo systemctl enable nginx
+sudo systemctl start nginx
+
+sudo yum install git
+
+

nginx와 코드를 불러올 때 사용할 git을 설치한다.

+

[EC2 CLI] nginx 리버스 프록시 설정

+

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

+
upstream jenkins {
+  keepalive 32; # keepalive connections
+  server 127.0.0.1:8080; # jenkins ip and port
+}
+
+# Required for Jenkins websocket agents
+map $http_upgrade $connection_upgrade {
+  default upgrade;
+  '' close;
+}
+
+server {
+  listen          80;       # Listen on port 80 for IPv4 requests
+
+  server_name     jenkins.example.com;  # replace 'jenkins.example.com' with your server domain name
+
+  # this is the jenkins web root directory
+  # (mentioned in the output of "systemctl cat jenkins")
+  root            /var/run/jenkins/war/;
+
+  access_log      /var/log/nginx/jenkins.access.log;
+  error_log       /var/log/nginx/jenkins.error.log;
+
+  # pass through headers from Jenkins that Nginx considers invalid
+  ignore_invalid_headers off;
+
+  location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
+    # rewrite all static files into requests to the root
+    # E.g /static/12345678/css/something.css will become /css/something.css
+    rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
+  }
+
+  location /userContent {
+    # have nginx handle all the static requests to userContent folder
+    # note : This is the $JENKINS_HOME dir
+    root /var/lib/jenkins/;
+    if (!-f $request_filename){
+      # this file does not exist, might be a directory or a /**view** url
+      rewrite (.*) /$1 last;
+      break;
+    }
+    sendfile on;
+  }
+
+  location / {
+      sendfile off;
+      proxy_pass         http://jenkins;
+      proxy_redirect     default;
+      proxy_http_version 1.1;
+
+      # Required for Jenkins websocket agents
+      proxy_set_header   Connection        $connection_upgrade;
+      proxy_set_header   Upgrade           $http_upgrade;
+
+      proxy_set_header   Host              $host;
+      proxy_set_header   X-Real-IP         $remote_addr;
+      proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
+      proxy_set_header   X-Forwarded-Proto $scheme;
+      proxy_max_temp_file_size 0;
+
+      #this is the maximum upload size
+      client_max_body_size       10m;
+      client_body_buffer_size    128k;
+
+      proxy_connect_timeout      90;
+      proxy_send_timeout         90;
+      proxy_read_timeout         90;
+      proxy_buffering            off;
+      proxy_request_buffering    off; # Required for HTTP CLI commands
+      proxy_set_header Connection ""; # Clear for keepalive
+  }
+
+}
+
+

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
/etc/nginx/conf.d 아래 default.conf 파일을 하나 생성하고 위와 같이 입력하고 저장한다.
nginx의 기본 설정 파일에 존재하는 include /etc/nginx/conf.d/*.conf; 설정 때문에 .conf 로 끝난다면 설정이 적용된다.
-설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

[Jenkins] Jenkins 접속

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
-EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

jenkins-start

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
+설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

+

[Jenkins] Jenkins 접속

+

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
+EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

+

jenkins-start

+

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
비밀번호를 입력하면 플러그인 설정 창이 나올텐데 install suggested plugins을 클릭하여 Jenkins가 추천하는 기본 플러그인들을 설치하면 된다.
-플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

[Jenkins] Jenkins Blue Ocean 설치

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
-IAM에서 다음과 같이 역할을 하나 새로 생성한다.

  1. 엔터티 선택

aws-iam1

  1. 권한 추가

aws-iam2

  1. 이름 지정, 검토 및 생성

aws-iam3

  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정

aws-iam4

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단

aws-s3

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

repo, user:email 권한이 있는 토큰이 필요하다.

[Jenkins] 블루 오션 시작

jenkins-blue-ocean1

블루 오션 열기로 파이프라인을 생성한다.
+플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

+

[Jenkins] Jenkins Blue Ocean 설치

+

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

+

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

+

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
+IAM에서 다음과 같이 역할을 하나 새로 생성한다.

+
    +
  1. 엔터티 선택
  2. +
+

aws-iam1

+
    +
  1. 권한 추가
  2. +
+

aws-iam2

+
    +
  1. 이름 지정, 검토 및 생성
  2. +
+

aws-iam3

+
    +
  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정
  2. +
+

aws-iam4

+

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

+

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

+
    +
  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단
  • +
+

aws-s3

+

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

+

repo, user:email 권한이 있는 토큰이 필요하다.

+

[Jenkins] 블루 오션 시작

+

jenkins-blue-ocean1

+

블루 오션 열기로 파이프라인을 생성한다.
토큰 입력 → 조직 선택 → CI/CD 설정할 Repository 선택을 하면 파이프라인 창으로 넘어간다.
-Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

jenkins-blue-ocean2

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

jenkins-blue-ocean3

[Github Repsoitory] Jenkinsfile 설정

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

pipeline {
agent any
stages {
stage('build and test') {
steps {
sh '/gradlew clean build'
}
}
stage('zip') {
steps {
sh 'mv ./build/libs/woowachat.jar .'
sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
}
}
stage('upload') {
steps {
sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
}
}
stage('deploy') {
steps {
sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
}
}
}
}

[Github] Webhooks 설정

github-hook

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

참고 자료

Install Jenkins - CentOS, Jenkins
-Nginx Reverse Proxy Configuration, Jenkins
-Amazon Corretto 17 JDK Install, AWS
-Amazon Linux 2023 packages, AWS

- - +Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

+

jenkins-blue-ocean2

+

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

+

jenkins-blue-ocean3

+

[Github Repsoitory] Jenkinsfile 설정

+

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

+
pipeline {
+  agent any
+  stages {
+    stage('build and test') {
+      steps {
+        sh '/gradlew clean build'
+      }
+    }
+    stage('zip') {
+      steps {
+        sh 'mv ./build/libs/woowachat.jar .'
+        sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
+      }
+    }
+    stage('upload') {
+      steps {
+        sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
+      }
+    }
+    stage('deploy') {
+      steps {
+        sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
+        sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
+      }
+    }
+  }
+}
+
+

[Github] Webhooks 설정

+

github-hook

+

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

+

참고 자료

+

Install Jenkins - CentOS, Jenkins
+Nginx Reverse Proxy Configuration, Jenkins
+Amazon Corretto 17 JDK Install, AWS
+Amazon Linux 2023 packages, AWS

\ No newline at end of file diff --git a/jsr-310.html b/jsr-310.html index 2cf8dd682..70030156f 100644 --- a/jsr-310.html +++ b/jsr-310.html @@ -2,8 +2,8 @@ - -JSR-310 | GG + +JSR-310 | GG @@ -12,20 +12,47 @@ - - - + + + -
-

JSR-310

· 약 2분

이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
+

JSR-310

· 약 2분

이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
ISO-8601을 기반으로 작성
-설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

ISO-8601

날짜와 시간에 관련된 데이터를 다루는 국제 표준

LocalDate, LocalTime, LocalDateTime

날짜와 시간을 표현하는 클래스

Instant

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
-기계의 관점에서 시간 표현

Duration, Period

간격을 표현하는 클래스

TemporalAdjusters

복잡한 날짜 조정이 필요할 때 사용
-필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}

DateTimeFormatter

날짜와 시간 포맷 클래스
-특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

ZoneId, ZoneOffset

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
-ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

Instant instant = Instant.now();
LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

참고 자료

- - +설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

+

날짜와 시간에 관련된 데이터를 다루는 국제 표준

+

LocalDate, LocalTime, LocalDateTime

+

날짜와 시간을 표현하는 클래스

+

Instant

+

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
+기계의 관점에서 시간 표현

+

Duration, Period

+

간격을 표현하는 클래스

+

TemporalAdjusters

+

복잡한 날짜 조정이 필요할 때 사용
+필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

+
@FunctionalInterface
+public interface TemporalAdjuster {
+    Temporal adjustInto(Temporal temporal);
+}
+
+

DateTimeFormatter

+

날짜와 시간 포맷 클래스
+특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

+

ZoneId, ZoneOffset

+

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
+ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

+
Instant instant = Instant.now();
+LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+
+

참고 자료

+
\ No newline at end of file diff --git a/kotlin-null.html b/kotlin-null.html index 6e2b2d1c0..ac9809c20 100644 --- a/kotlin-null.html +++ b/kotlin-null.html @@ -2,8 +2,8 @@ - -Kotlin에서 null을 다루는 방법 | GG + +Kotlin에서 null을 다루는 방법 | GG @@ -12,25 +12,76 @@ - - - + + + -
-

Kotlin에서 null을 다루는 방법

· 약 5분

nullable 타입

코틀린은 NullPointerException 예외를 최대한 발생시키지 않기 위해 타입 시스템이 설계되어 있다.
-이는 실행 시점이 아닌 컴파일 시 미리 오류가 발생할 가능성이 있는 부분을 미리 감지하여 NPE 발생의 가능성을 줄여준다.

코틀린의 경우 nullable 타입을 다음과 같이 표현한다.

val number: Int?

타입 뒤에 ?를 붙여 해당 값이 null이 될 수 있다는 것을 의미한다.
-만약 ?를 붙이지 않을 때 null을 받는 경우 컴파일 시 오류가 발생한다.

?. Safe Calls 연산자

자바에서 NPE를 발생시키지 않기 위해 null을 처리하는 가장 간단한 방법으로는 분기를 사용하는 방법이 있다.

코틀린은 안전한 호출 연산자인 ?. 연산자를 지원한다.
+

Kotlin에서 null을 다루는 방법

· 약 5분

nullable 타입

+

코틀린은 NullPointerException 예외를 최대한 발생시키지 않기 위해 타입 시스템이 설계되어 있다.
+이는 실행 시점이 아닌 컴파일 시 미리 오류가 발생할 가능성이 있는 부분을 미리 감지하여 NPE 발생의 가능성을 줄여준다.

+

코틀린의 경우 nullable 타입을 다음과 같이 표현한다.

+
val number: Int?
+
+

타입 뒤에 ?를 붙여 해당 값이 null이 될 수 있다는 것을 의미한다.
+만약 ?를 붙이지 않을 때 null을 받는 경우 컴파일 시 오류가 발생한다.

+

?. Safe Calls 연산자

+

자바에서 NPE를 발생시키지 않기 위해 null을 처리하는 가장 간단한 방법으로는 분기를 사용하는 방법이 있다.

+

코틀린은 안전한 호출 연산자인 ?. 연산자를 지원한다.
따라서 참조 값이 null이 아닐 경우에만 메서드 호출을 할 수 있다.
-참조 값이 null인 경우 메서드 호출이 무시되고, null을 반환한다.

public String repeat(String word) {
if (word == null) {
return null;
}
return word.repeat(2);
}

?: 엘비스 연산자

참조하려는 값이 null일 경우 기본 값을 반환하고 싶을 때는 어떻게 해야 할까?
-코틀린은 null이 아닌 경우 기본 값을 지정할 때 사용할 수 있는 엘비스 연산자를 지원한다.

public String stringSafe(String word) {
if (word == null) {
return "";
}
return word;
}

코틀린에서는 throw도 식이기 때문에 엘비스 연산자를 이용하여 예외를 던질 수 있다.
-예를 들어 사용자 정보가 있는 저장소에 찾는 사용자가 없는 경우 아래와 같이 사용할 수 있다.

userRepository.findByName(name) ?: throw IllegalArgumentException()

!! 널 아님 단언 연산자

!! 연산자를 이용한다면 강제로 어떤 값이든 non-nullable 타입으로 변경할 수 있다.
+참조 값이 null인 경우 메서드 호출이 무시되고, null을 반환한다.

+
public String repeat(String word) {
+    if (word == null) {
+        return null;
+    }
+    return word.repeat(2);
+}
+
+

?: 엘비스 연산자

+

참조하려는 값이 null일 경우 기본 값을 반환하고 싶을 때는 어떻게 해야 할까?
+코틀린은 null이 아닌 경우 기본 값을 지정할 때 사용할 수 있는 엘비스 연산자를 지원한다.

+
public String stringSafe(String word) {
+    if (word == null) {
+        return "";
+    }
+    return word;
+}
+
+

코틀린에서는 throw도 식이기 때문에 엘비스 연산자를 이용하여 예외를 던질 수 있다.
+예를 들어 사용자 정보가 있는 저장소에 찾는 사용자가 없는 경우 아래와 같이 사용할 수 있다.

+
userRepository.findByName(name) ?: throw IllegalArgumentException()
+
+

!! 널 아님 단언 연산자

+

!! 연산자를 이용한다면 강제로 어떤 값이든 non-nullable 타입으로 변경할 수 있다.
하지만 null인 값에 사용한다면 NPE가 발생하게 된다.
일반적인 경우에는 !! 연산자를 사용하는 것은 위험하다.
-사용하기 쉽지만, 리스크가 크고 혹시나 해당 값이 추후에는 null이 될 수 있기 때문에 지양해야 된다고 생각한다.

val length: Int = word!!.length

as? 안전한 캐스팅

타입 변환을 할 때 지정한 타입으로 변경할 수 없다면 ClassCastException이 발생한다.
+사용하기 쉽지만, 리스크가 크고 혹시나 해당 값이 추후에는 null이 될 수 있기 때문에 지양해야 된다고 생각한다.

+
val length: Int = word!!.length
+
+

as? 안전한 캐스팅

+

타입 변환을 할 때 지정한 타입으로 변경할 수 없다면 ClassCastException이 발생한다.
코틀린에서는 as 뒤에 ?를 붙여 안전하게 타입 변환을 할 수 있다.
-따라서 미리 변환 가능한 타입인지 확인하지 않고, 안전하게 타입을 변환 할 수 있다.

타입 변환이 불가능 할 경우 예외를 발생시키지 않고 null을 반환한다.

val value: Int? = something as? Int

List에서의 null 처리

List에는 null이 아닌 값만 반환하는 filterNotNull 유틸리티 메서드를 제공한다.

val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")
val foods = foodsWithNull.filterNotNull()

참고 자료

- - +따라서 미리 변환 가능한 타입인지 확인하지 않고, 안전하게 타입을 변환 할 수 있다.

+

타입 변환이 불가능 할 경우 예외를 발생시키지 않고 null을 반환한다.

+
val value: Int? = something as? Int
+
+

List에서의 null 처리

+

List에는 null이 아닌 값만 반환하는 filterNotNull 유틸리티 메서드를 제공한다.

+
val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")
+val foods = foodsWithNull.filterNotNull()
+
+

참고 자료

+
\ No newline at end of file diff --git a/ladder-retrospective.html b/ladder-retrospective.html index f6de0a33f..adfc97a3a 100644 --- a/ladder-retrospective.html +++ b/ladder-retrospective.html @@ -2,8 +2,8 @@ - -사다리 타기 미션 회고 | GG + +사다리 타기 미션 회고 | GG @@ -12,46 +12,150 @@ - - - + + + -
-

사다리 타기 미션 회고

· 약 11분

사다리 타기

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
-이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

2단계에서는 2가지 방법으로 구현해봤다.

  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법

Position 기준으로 사다리 게임을 진행하는 방법

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
+

사다리 타기 미션 회고

· 약 11분

1단계: https://github.com/woowacourse/java-ladder/pull/97
+2단계: https://github.com/woowacourse/java-ladder/pull/234

+

사다리 타기

+

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
+이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

+

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

+

2단계에서는 2가지 방법으로 구현해봤다.

+
    +
  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. +
  3. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법
  4. +
+

Position 기준으로 사다리 게임을 진행하는 방법

+

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
구현하고 나니 다른 클래스들이 Position에 대한 의존도가 너무 높은 것 같았다.
-또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

public LadderGameResult play() {
final Map<Player, Item> result = new LinkedHashMap<>();
// 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
for (Position position : Position.range(players.count())) {
final Position resultPosition = ladder.play(position);
result.put(players.get(position), items.get(resultPosition));
}
return new LadderGameResult(result);
}

Player에게 Ladder를 전달하여 게임을 진행하는 방법

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
-이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

public LadderGameResult play() {
// 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
final Map<Player, Position> playResult = players.play(ladder);

final Map<Player, Item> result = new LinkedHashMap<>();
for (Player player : playResult.keySet()) {
result.put(player, toItem(playResult.get(player)));
}
return new LadderGameResult(result);
}

부족했던 부분

유비쿼터스 언어에 시간을 들이기
+또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

+ +
public LadderGameResult play() {
+    final Map<Player, Item> result = new LinkedHashMap<>();
+    // 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
+    for (Position position : Position.range(players.count())) {
+        final Position resultPosition = ladder.play(position);
+        result.put(players.get(position), items.get(resultPosition));
+    }
+    return new LadderGameResult(result);
+}
+
+

Player에게 Ladder를 전달하여 게임을 진행하는 방법

+

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
+이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

+ +
public LadderGameResult play() {
+    // 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
+    final Map<Player, Position> playResult = players.play(ladder);
+
+    final Map<Player, Item> result = new LinkedHashMap<>();
+    for (Player player : playResult.keySet()) {
+        result.put(player, toItem(playResult.get(player)));
+    }
+    return new LadderGameResult(result);
+}
+
+

부족했던 부분

+

유비쿼터스 언어에 시간을 들이기
유비쿼터스 언어를 정하는데 시간을 조금 더 들여야겠다고 생각했다.
사다리 타기의 실행 결과를 Item으로 짓다니.. 뭔가 만족스럽지 않다.
-이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

페어와 조금 더 친해지기
+이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

+

페어와 조금 더 친해지기
첫날은 페어와 친해지는 시간을 조금 더 가져야겠다고 생각했다.
-우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

README를 조금 더 꼼꼼하게
+우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

+

README를 조금 더 꼼꼼하게
이상하게 코딩에 집중하면 README를 업데이트하면서 같이 커밋 하는 걸 항상 까먹는다.
-다음 미션에는 조금 더 신경 써야겠다.

좋은 질문을 생각하기
+다음 미션에는 조금 더 신경 써야겠다.

+

좋은 질문을 생각하기
첫 PR때 리뷰어에게 질문을 남기지 못했다.
-리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

PR 후에도 꼼꼼하게 확인하기
+리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

+

PR 후에도 꼼꼼하게 확인하기
분명 알고 있는 부분이지만, 놓친 부분이 많은 것 같았다.
PR 하기 전에도 계속 확인을 했지만, 아무래도 IntelliJ에서 보니 코드에 익숙해져서 그런지 변경해야 할 부분이 잘 안보였다.
-github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

적극적으로 나의 의견을 말하기
+github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

+

적극적으로 나의 의견을 말하기
의견을 적극적으로 내는 부분에 대해서 페어의 의견이 괜찮다고 생각하면 수용 후 개선을 하는 방향으로 진행을 했었는데, 조금 더 개선할 수 있는 방향이 있다면 나도 적극적으로 의견을 말해야겠다고 생각이 든다.
-나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

새로 학습한 부분

객체의 생성 책임
+나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

+

새로 학습한 부분

+

객체의 생성 책임
Players가 Position을 생성하고 Player의 생성자에 넣어주었다. 하지만 이 부분에 대해서 생성 책임에 관련된 코멘트가 달렸다. -시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A를 긴밀하게 사용한다.
  • B가 A의 초깃값을 가지고 있다.

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

패키지 분리 기준
+시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

+

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

+
    +
  • B가 A 객체를 포함 또는 참조한다.
  • +
  • B가 A 객체를 기록한다.
  • +
  • B가 A를 긴밀하게 사용한다.
  • +
  • B가 A의 초깃값을 가지고 있다.
  • +
+

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

+

패키지 분리 기준
패키지 분리에 대한 나만의 기준이 아직 명확하지 않아 질문이 들어와도 명확하게 답변을 하지 못했다.
마지막 제출 전에 도메인 패키지 내부를 분리해 봤는데, 기준이 명확하지 않았기 때문에 좋지 않은 선택이었던 것 같다. -현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
-Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(0~19)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
-이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0~19의 값이 보장되어 있다고 생각할 것이기 때문이다.
-따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

페어에게 배울 부분

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
+현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

+

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
+Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(019)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
+이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0
19의 값이 보장되어 있다고 생각할 것이기 때문이다.
+따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

+

페어에게 배울 부분

+

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
이번에 페어 할 때 컨디션 관리를 제대로 못해서 많이 미안했다. 다음에는 최상의 컨디션으로 페어를 준비해 봐야겠다.
-그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
+그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

+

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
또한 페어 진행이 느린 것 같다고 말해줘서 안정적으로 시간 안에 미션을 완료할 수 있었다.
-페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
-웃는 것만으로도 사람이 밝아 보여서 너무 좋은 것 같다!

- - +페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

+

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
+웃는 것만으로도 사람이 밝아 보여서 너무 좋은 것 같다!

\ No newline at end of file diff --git a/level2-interview-retrospective.html b/level2-interview-retrospective.html index d2f366a45..1b85d28b0 100644 --- a/level2-interview-retrospective.html +++ b/level2-interview-retrospective.html @@ -2,8 +2,8 @@ - -레벨 2 - 레벨 인터뷰 회고 | GG + +레벨 2 - 레벨 인터뷰 회고 | GG @@ -12,26 +12,36 @@ - - - + + + -
-

레벨 2 - 레벨 인터뷰 회고

· 약 4분

레벨 인터뷰

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
+

레벨 2 - 레벨 인터뷰 회고

· 약 4분

레벨 인터뷰

+

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
따라서 레벨 1 레벨 인터뷰 회고는 레벨 1 회고를 작성할 때 끼워넣었다.
이번에는 범위도 제한되어 있어 어떻게 준비해야 할지 당황했고, 답변에도 부족한 부분이 많았었다.
-기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

API 문서 도구 선택

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
+기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

+

API 문서 도구 선택

+

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
백엔드 팀원이 함께 의사결정을 했고, 미션 기간이 짧은 만큼 팀 차원에서 비교적 학습하기 쉬운 Swagger를 선택했다.
-추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
-앞으로도 학습 비용은 주요하게 고려해야 할 사항

PUT과 PATCH & 토큰과 세션

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
-토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
+추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

+

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

+
+

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
+앞으로도 학습 비용은 주요하게 고려해야 할 사항

+
+

PUT과 PATCH & 토큰과 세션

+

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
+토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

+

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
실제로 레벨 2 때 이론적인 학습 시간이 매우 적었고, 집중력도 많이 부족했다.
-앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

그 외 개선할 점

인터뷰할 때 특유의 말버릇을 개선하기
+앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

+

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

+

그 외 개선할 점

+

인터뷰할 때 특유의 말버릇을 개선하기
생각할 시간을 가졌을 때 "다시 말씀드려도 될까요?"라고 말하고 답변을 이어나가기
기술적으로 깊이가 부족하다고 생각이 많이 들어서 조금 더 깊게 공부하고 정리하기
-이전에 공부했던거 되돌아 보는 시간 가지기

- - +이전에 공부했던거 되돌아 보는 시간 가지기

\ No newline at end of file diff --git a/log-async-exception.html b/log-async-exception.html index 0af83cbd4..46c897b8a 100644 --- a/log-async-exception.html +++ b/log-async-exception.html @@ -2,8 +2,8 @@ - -비동기 예외 로깅 | GG + +비동기 예외 로깅 | GG @@ -12,22 +12,94 @@ - - - + + + -
-

비동기 예외 로깅

· 약 4분

문제 상황

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
-확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

비동기 예외 발생시 로깅 설정

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
+

비동기 예외 로깅

· 약 4분

문제 상황

+

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
+확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

+

비동기 예외 발생시 로깅 설정

+

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

+

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
기존의 동기 예외 처리의 경우 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다.
-비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

AsyncExceptionHandler
@Slf4j
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

private static final String LOG_FORMAT = "[%s] %s";

@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
}
}

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
-getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

MDC 정보 연동 문제

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

./mdc-null.png

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

MdcTaskDecorator
public class MdcTaskDecorator implements TaskDecorator {

@Override
public Runnable decorate(final Runnable runnable) {
Map<String, String> threadContext = MDC.getCopyOfContextMap();
return () -> {
MDC.setContextMap(threadContext);
runnable.run();
};
}
}

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

AsyncConfig
@RequiredArgsConstructor
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

private final AsyncConfigurationProperties properties;

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(properties.coreSize());
executor.setMaxPoolSize(properties.maxSize());
executor.setQueueCapacity(properties.queueCapacity());

executor.setTaskDecorator(new MdcTaskDecorator());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

./mdc-not-null.png

참고 자료

spring async, baeldung
-@Async will not call by @ControllerAdvice for global exception
-Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
-TaskDecorator, Spring docs
-AsyncUncaughtExceptionHandler

- - +비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

+
@Slf4j
+public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
+
+    private static final String LOG_FORMAT = "[%s] %s";
+
+    @Override
+    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
+        log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
+    }
+}
+
+

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
+getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

+

MDC 정보 연동 문제

+

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

+

./mdc-null.png

+

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

+
public class MdcTaskDecorator implements TaskDecorator {
+
+    @Override
+    public Runnable decorate(final Runnable runnable) {
+        Map<String, String> threadContext = MDC.getCopyOfContextMap();
+        return () -> {
+            MDC.setContextMap(threadContext);
+            runnable.run();
+        };
+    }
+}
+
+

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

+
@RequiredArgsConstructor
+@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    private final AsyncConfigurationProperties properties;
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(properties.coreSize());
+        executor.setMaxPoolSize(properties.maxSize());
+        executor.setQueueCapacity(properties.queueCapacity());
+        
+        // highlight-next-line
+        executor.setTaskDecorator(new MdcTaskDecorator());
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.initialize();
+        return executor;
+    }
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

+

./mdc-not-null.png

+

참고 자료

+

spring async, baeldung
+@Async will not call by @ControllerAdvice for global exception
+Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
+TaskDecorator, Spring docs
+AsyncUncaughtExceptionHandler

\ No newline at end of file diff --git a/mock-static-method.html b/mock-static-method.html index fa6d6511b..fd579c55f 100644 --- a/mock-static-method.html +++ b/mock-static-method.html @@ -2,8 +2,8 @@ - -Mockito 이용해서 static 메서드 모킹하기 | GG + +Mockito 이용해서 static 메서드 모킹하기 | GG @@ -12,22 +12,51 @@ - - - + + + -
-

Mockito 이용해서 static 메서드 모킹하기

· 약 3분

개요

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
-하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
+

Mockito 이용해서 static 메서드 모킹하기

· 약 3분

개요

+

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
+하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

+

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

+

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
해당 static 메서드를 호출하는 부분을 따로 RouteImageUploader 클래스로 최대한 분리했다.
-이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

public void upload(BufferedImage bufferedImage) {
File file = new File(파일경로);
try {
ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
} catch (IOException e) {
throw new DrawException(IMAGE_SAVE_FAIL);
}
}

Mocking static methods

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
-mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

// given
BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
RouteImageUploader routeImageUploader = new RouteImageUploader();

// expect
try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
routeImageUploader.upload(bufferedImage);
imageIO.verify(
() -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
times(1)
);
}

마치며

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
+이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

+
public void upload(BufferedImage bufferedImage) {
+    File file = new File(파일경로);
+    try {
+        ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
+    } catch (IOException e) {
+        throw new DrawException(IMAGE_SAVE_FAIL);
+    }
+}
+
+

Mocking static methods

+

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
+mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

+

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

+
// given
+BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
+RouteImageUploader routeImageUploader = new RouteImageUploader();
+
+// expect
+try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
+    routeImageUploader.upload(bufferedImage);
+    imageIO.verify(
+            () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
+            times(1)
+    );
+}
+
+

마치며

+

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
하지만 추상화를 하면 할 수록 코드의 복잡도는 증가한다.
-항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

참고 자료

Mocking static methods
-Mockito mock static methods
-Enable mocking static methods in Mockito

- - +항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

+

참고 자료

+

Mocking static methods
+Mockito mock static methods
+Enable mocking static methods in Mockito

\ No newline at end of file diff --git a/mvc-retrospective.html b/mvc-retrospective.html index 3ccd21952..a165ddc6d 100644 --- a/mvc-retrospective.html +++ b/mvc-retrospective.html @@ -2,8 +2,8 @@ - -MVC 구현 미션 회고 | GG + +MVC 구현 미션 회고 | GG @@ -12,25 +12,96 @@ - - - + + + -
-

MVC 구현 미션 회고

· 약 6분

MVC 구현

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
-미션의 목표는 다음과 같았다.

  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • 점진적인 리팩토링을 경험한다.

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

애너테이션 기반 프레임워크 만들기

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
+

MVC 구현 미션 회고

· 약 6분

1단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/404
+2단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/465
+3단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/580

+

MVC 구현

+

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
+미션의 목표는 다음과 같았다.

+
    +
  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • +
  • 점진적인 리팩토링을 경험한다.
  • +
+

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

+

애너테이션 기반 프레임워크 만들기

+

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
테오가 @GetMapping이나 @PostMapping 부분도 진행하면 재밌을 것 같다고 해서 같이 진행해 보았다.
-추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  3. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

AnnotationHandlerMapping
public void initialize() {
if (!initialized.compareAndSet(false, true)) {
return;
}

final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
for (final Method method : methods) {
final ControllerInstance controller = controllers.get(method.getDeclaringClass());
final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
}

log.info("Initialized AnnotationHandlerMapping!");
handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
}

Legacy MVC와 @MVC 통합

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
+추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

+ +

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

+
    +
  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. +
  3. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  4. +
  5. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.
  6. +
+

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

+
public void initialize() {
+    if (!initialized.compareAndSet(false, true)) {
+        return;
+    }
+
+    final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
+    final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
+    for (final Method method : methods) {
+        final ControllerInstance controller = controllers.get(method.getDeclaringClass());
+        final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
+        final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
+        handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
+    }
+
+    log.info("Initialized AnnotationHandlerMapping!");
+    handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
+}
+
+

Legacy MVC와 @MVC 통합

+

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
기존의 MVC와 애너테이션이 적용된 MVC 두 개를 같이 사용할 수 있어야 헀다.
-대략적인 흐름은 다음과 같다.

  1. DispatcherServlet.service(request, response) 호출
  2. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  3. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  4. HandlerAdapter의.handle 메서드 실행
  5. View의 render 호출

웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
-간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

내용이 길어져서 다음 문서에 정리했다.

추상적인 개념 학습 방법

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory

정리

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
+대략적인 흐름은 다음과 같다.

+
    +
  1. DispatcherServlet.service(request, response) 호출
  2. +
  3. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  4. +
  5. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  6. +
  7. HandlerAdapter의.handle 메서드 실행
  8. +
  9. View의 render 호출
  10. +
+ +

웹 애플리케이션 발전 과정

+

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

+ +

내용이 길어져서 다음 문서에 정리했다.

+

추상적인 개념 학습 방법

+

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

+
개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory
+

정리

+

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
이번 미션에서 나의 리뷰어는 루카, 리뷰이는 헤나였다.
매 단계마다 꼼꼼하게 리뷰해 준 루카에게 너무 감사하고, 헤나에게 이상한 리뷰를 많이 남긴 것 같은데 꼼꼼히 반영해줘서 감사하다.
-오랫동안 기다려왔던 레벨 4 미션이 하나씩 마무리 될 때 마다 아쉬움이 남는다.

- - +오랫동안 기다려왔던 레벨 4 미션이 하나씩 마무리 될 때 마다 아쉬움이 남는다.

\ No newline at end of file diff --git a/mysql-lock.html b/mysql-lock.html index cf32bcc72..56a855a27 100644 --- a/mysql-lock.html +++ b/mysql-lock.html @@ -2,8 +2,8 @@ - -MySQL 엔진의 잠금 | GG + +MySQL 엔진의 잠금 | GG @@ -12,27 +12,75 @@ - - - + + + -
-

MySQL 엔진의 잠금

· 약 5분

MySQL 엔진의 잠금

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
-MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

글로벌 락(Global lock)

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

  • 영향을 미치는 범위는 해당 서버 전체이다.
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
+

MySQL 엔진의 잠금

· 약 5분

MySQL 엔진의 잠금

+

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
+MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

+

글로벌 락(Global lock)

+

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

+
    +
  • 영향을 미치는 범위는 해당 서버 전체이다.
  • +
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.
  • +
+

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 일관된 백업을 받아야할 때 사용한다.
-InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

-- GLOBAL LOCK
FLUSH TABLES WITH READ LOCK;
-- UNLOCK
UNLOCK TABLES;

-- BACKUP LOCK
LOCK INSTANCE FOR BACKUP;
-- UNLOCK
UNLOCK INSTANCE;
MyISAM

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
-트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

테이블 락(Table lock)

개별 테이블 단위로 설정되는 잠금이다.
+InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

+
-- GLOBAL LOCK
+FLUSH TABLES WITH READ LOCK;
+-- UNLOCK
+UNLOCK TABLES;
+
+-- BACKUP LOCK
+LOCK INSTANCE FOR BACKUP;
+-- UNLOCK
+UNLOCK INSTANCE;
+
+

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
+트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

+

테이블 락(Table lock)

+

개별 테이블 단위로 설정되는 잠금이다.
명시적 또는 묵시적으로 특정 테이블의 락을 획득할 수 있다.
묵시적 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.
-InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

-- TABLE LOCK
LOCK TABLES table_name [ READ | WRITE ]

-- UNLOCK
UNLOCK TABLES;

네임드 락(Named lock)

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
-여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
SELECT GET_LOCK('aGVyYg==', 1);

-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
SELECT IS_FREE_LOCK('aGVyYg==');

-- 문자열에 대한 잠금을 해제한다.
SELECT RELEASE_LOCK('aGVyYg==');

-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.

-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
SELECT RELEASE_ALL_LOCKS();

메타데이터 락(Metadata lock)

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
-명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
-보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
RENAME TABLE rank TO rank_backup, rank_new TO rank;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-MySQL의 User Level Lock를 활용한다면?, gywndi
-Locking Functions, MySQL 5.7 Reference
-Locking Functions, MySQL 8.0 Reference

- - +InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

+
-- TABLE LOCK
+LOCK TABLES table_name [ READ | WRITE ]
+
+-- UNLOCK
+UNLOCK TABLES;
+
+

네임드 락(Named lock)

+

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
+여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

+
-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
+SELECT GET_LOCK('aGVyYg==', 1);
+
+-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
+SELECT IS_FREE_LOCK('aGVyYg==');
+
+-- 문자열에 대한 잠금을 해제한다.
+SELECT RELEASE_LOCK('aGVyYg==');
+
+-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.
+
+-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
+SELECT RELEASE_ALL_LOCKS();
+
+

메타데이터 락(Metadata lock)

+

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
+명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
+보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

+
-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
+-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
+RENAME TABLE rank TO rank_backup, rank_new TO rank;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+MySQL의 User Level Lock를 활용한다면?, gywndi
+Locking Functions, MySQL 5.7 Reference
+Locking Functions, MySQL 8.0 Reference

\ No newline at end of file diff --git a/order-retrospective.html b/order-retrospective.html index e1174900f..47041d89e 100644 --- a/order-retrospective.html +++ b/order-retrospective.html @@ -2,8 +2,8 @@ - -장바구니 주문 미션 회고 | GG + +장바구니 주문 미션 회고 | GG @@ -12,31 +12,77 @@ - - - + + + -
-

장바구니 주문 미션 회고

· 약 5분
PR 링크

장바구니 주문 미션

배포 및 협업을 할 수 있는 미션이었다.
-마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

배포

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
+

장바구니 주문 미션 회고

· 약 5분

1단계: AWS 배포
+2단계: https://github.com/woowacourse/jwp-shopping-order/pull/7

+

장바구니 주문 미션

+

배포 및 협업을 할 수 있는 미션이었다.
+마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

+

배포

+

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
각자 하나의 EC2 인스턴스를 제공받을 수 있었고, 팀 별로 DB를 위한 추가 인스턴스를 제공받았다.
배포 스크립트를 작성하는 경험을 해볼 수 있었다.
-배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

echo "Start Deploy Script"
REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
PROJECT_NAME=jwp-shopping-order

echo "Change Directory"
cd $REPOSITORY_NAME

echo "Git Pull"
git pull origin step2

echo "Build"
./gradlew bootJar

echo "Copy, Start Server"
mv ./build/libs/$PROJECT_NAME.jar .

PID=$(pgrep -f $PROJECT_NAME)

if [ -n $PID ]; then
kill -9 $PID
sleep 5
fi

nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &

협업

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
+배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

+
echo "Start Deploy Script"
+REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
+PROJECT_NAME=jwp-shopping-order
+
+echo "Change Directory"
+cd $REPOSITORY_NAME
+
+echo "Git Pull"
+git pull origin step2
+
+echo "Build"
+./gradlew bootJar
+
+echo "Copy, Start Server"
+mv ./build/libs/$PROJECT_NAME.jar .
+
+PID=$(pgrep -f $PROJECT_NAME)
+
+if [ -n $PID ]; then
+        kill -9 $PID
+	sleep 5
+fi
+
+nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &
+
+

협업

+

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
백엔드가 아닌 다른 크루들과 해보는 첫 협업이라 약간 두근거렸다.
-예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

부족했던 부분

여러가지 방법에 대한 장단점을 고려해보기

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
+예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

+

부족했던 부분

+

여러가지 방법에 대한 장단점을 고려해보기

+

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
조금 더 시간을 많이 들여서 장단점을 고려했다면 더 좋은 결과물이 나오지 않았을까?
-앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

새로 배운 부분

expose headers

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
-기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
+앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

+

새로 배운 부분

+

expose headers

+

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
+기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
이를 expose headers 설정을 통해 해결할 수 있었다.
-nginx 설정에 다음과 같이 추가해 주었다.

add_header 'Access-Control-Expose-Headers' 'Location'

읽기 전용 트랜잭션

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
+nginx 설정에 다음과 같이 추가해 주었다.

+
add_header 'Access-Control-Expose-Headers' 'Location'
+
+

읽기 전용 트랜잭션

+

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
이번에 코멘트가 달려서 조금 더 자세히 공부해 보기로 했다.
-Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
-추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

DAO에 @Transactional 적용

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
+Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

+

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

+
    +
  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • +
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.
  • +
+

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
+추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

+

DAO에 @Transactional 적용

+

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
Service 계층에 이미 트랜잭션을 보장해 주고 있기에 필요 없지 않을까 생각했었다.
-DAO를 다른 곳에서 사용하더라도 트랜잭션을 보장하기 위해(확장성 고려) @Transactional을 적용하는 것도 괜찮은 것 같다.

- - +DAO를 다른 곳에서 사용하더라도 트랜잭션을 보장하기 위해(확장성 고려) @Transactional을 적용하는 것도 괜찮은 것 같다.

\ No newline at end of file diff --git a/page/10.html b/page/10.html index a13e04b47..e02b8c22f 100644 --- a/page/10.html +++ b/page/10.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,28 +12,43 @@ - - - + + + -
-

· 약 4분

회고

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
+

· 약 4분

회고

+

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
레벨 3에는 기술적인 부분에서도, 기술 외적인 부분에서도 부족함이 많이 보였던 것 같다.
부족한 부분을 알았기에, 앞으로 더욱 성장할 수 있을 것 같다.
-내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

아쉬운 점

문서화

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
+내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

+

아쉬운 점

+

문서화

+

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
프로젝트를 진행하면서 내가 한 부분을 조금 더 꼼꼼하게, 이해하기 쉽게 문서화를 했더라면 팀원들에게 더욱 도움이 되었을 텐데 이 부분에 시간을 조금 더 투자하지 못했던 부분에서 아쉬움이 많이 들었다.
-방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

내가 못하는 부분이라면 시간을 들이자

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
+방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

+

내가 못하는 부분이라면 시간을 들이자

+

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
말을 하기 전에 정리해서 의견을 내는 것, 발표 준비, 감정 조절 등등 -못하는 부분을 인지하고, 개선하자.

컴포트 존 벗어나기

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
+못하는 부분을 인지하고, 개선하자.

+

컴포트 존 벗어나기

+

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
매번 근거를 가지고 기술을 도입하고, 코드를 작성하려고 노력했다.
-하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

좋았던 점

좋았던 점도 문서화

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
-백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

내가 디자인한 트립드로우 로고

트립드로우 로고를 만들었다.
+하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

+

좋았던 점

+

좋았던 점도 문서화

+

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
+백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

+

내가 디자인한 트립드로우 로고

+ +

트립드로우 로고를 만들었다.
팀원들이 대표 색상(파란색)을 정해줬고, 주말 동안 신나게 로고 디자인을 했던 것 같다.
-아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

기술 선택의 이유

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
-100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

마치며

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
+아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

+

기술 선택의 이유

+

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
+100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

+

마치며

+

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
안드로이드 브레멘 음악대(멧돼지, 수달, 핑구), 그리고 백엔드 팀원들(체인저, 후추, 리오) 너무 고생이 많았다.

- - \ No newline at end of file diff --git a/page/11.html b/page/11.html index 18d82c788..de459d6e3 100644 --- a/page/11.html +++ b/page/11.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,33 +12,92 @@ - - - + + + -
-

· 약 6분

CloudWatch

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
+

· 약 6분

CloudWatch

+

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
지표를 감시하여 알림을 보내는 기능도 제공한다.
프리티어를 사용하지 않는 경우 대시보드당 3$/M 의 비용이 청구되고, 지표나 로그의 양에 따라 비용이 추가적으로 청구된다.
-요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

CloudWatch Metrics

기본적으로 5분마다 지표에 대한 정보가 수집된다.
+요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

+

CloudWatch Metrics

+

기본적으로 5분마다 지표에 대한 정보가 수집된다.
세부 모니터링(Detailed Monitoring)을 활성화하면 1분마다 지표를 수집한다.
-대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

./cloudwatch1.png

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

CloudWatch Agent 설치

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

IAM 역할 설정

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
-IAM → 역할에서 역할 생성을 클릭한다.

./cloudwatch2.png

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

./cloudwatch3.png

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
-작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

./cloudwatch4.png

설치

환경은 다음과 같다.

OS: ubuntu 22.04
-인스턴스 유형: t4g.small (ARM64)

아래 명령어를 입력하여 설치한다.

wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i -E ./amazon-cloudwatch-agent.deb

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

Wizard

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
+대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

+

./cloudwatch1.png

+

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

+

CloudWatch Agent 설치

+

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

+

IAM 역할 설정

+

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
+IAM → 역할에서 역할 생성을 클릭한다.

+

./cloudwatch2.png

+

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

+

./cloudwatch3.png

+

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
+작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

+

./cloudwatch4.png

+

설치

+

환경은 다음과 같다.

+

OS: ubuntu 22.04
+인스턴스 유형: t4g.small (ARM64)

+

아래 명령어를 입력하여 설치한다.

+
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
+sudo dpkg -i -E ./amazon-cloudwatch-agent.deb
+
+

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

+

Wizard

+

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
로그를 수집하도록 설정하는 경우 Wizard 실행 명령어 입력 전 log 파일의 절대 경로를 복사해두는 것이 좋다.
-아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
-로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

./cloudwatch5.png

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

Do you want to store the config in the SSM parameter store?
1. yes
2. no

추가적으로 설정하지 않는 경우 2번을 선택한다.
-Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
-설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

설정 파일 적용

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
-file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

types.db: no such file or directory 에러

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory

types.db 파일 생성

sudo mkdir /usr/share/collectd
sudo touch /usr/share/collectd/types.db

지표 확인

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

./cloudwatch6.png

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

{
"metrics": {
"namespace": "2023-hello-world",
......
},
}

로그

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

./cloudwatch7.png

참고 자료

CloudWatch란 무엇입니까?
-Amazon CloudWatch 요금
-Linux 인스턴스 지표
-서버에 CloudWatch 에이전트 설치 및 실행
-CloudWatch Agent를 Parameter Store에서 관리해 보기
-CloudWatch에이전트 구성 파일

- - +아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
+
+

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
+로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

+

./cloudwatch5.png

+

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

+
Do you want to store the config in the SSM parameter store?
+1. yes
+2. no
+
+

추가적으로 설정하지 않는 경우 2번을 선택한다.
+Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
+설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

+

설정 파일 적용

+

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
+file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
+
+

types.db: no such file or directory 에러

+

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

+
Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory
+
+

types.db 파일 생성

+
sudo mkdir /usr/share/collectd
+sudo touch /usr/share/collectd/types.db
+
+

지표 확인

+

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

+

./cloudwatch6.png

+

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

+
{
+  "metrics": {
+    "namespace": "2023-hello-world",
+    ......
+   },
+} 
+
+

로그

+

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

+

./cloudwatch7.png

+

참고 자료

+

CloudWatch란 무엇입니까?
+Amazon CloudWatch 요금
+Linux 인스턴스 지표
+서버에 CloudWatch 에이전트 설치 및 실행
+CloudWatch Agent를 Parameter Store에서 관리해 보기
+CloudWatch에이전트 구성 파일

\ No newline at end of file diff --git a/page/12.html b/page/12.html index 2d89f3b1c..4e17761f0 100644 --- a/page/12.html +++ b/page/12.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,40 +12,217 @@ - - - + + + -
-

· 약 12분

이전 글

경로 이미지 생성하기 - 기술 선택
-경로 이미지 생성하기 - 구현

개요

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
+

· 약 12분

이전 글

+

경로 이미지 생성하기 - 기술 선택
+경로 이미지 생성하기 - 구현

+

개요

+

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
경로 이미지 생성의 경우 위치 정보의 개수에 정비례하여 생성 시간이 증가한다.
-따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

주기능의 응답속도 개선

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
+따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

+

주기능의 응답속도 개선

+

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
하지만 현재 여행 종료와 감상 생성의 응답 속도가 경로 이미지 생성 시간에 영향을 받고 있다.
경로 이미지 생성은 비동기 처리하여도 애플리케이션 사용에 문제가 되지 않는다.
-소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

확장성 대비

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
+소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

+

확장성 대비

+

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
조금 더 짧은 간격으로 위치 정보를 그리는 경우 하나의 여행에 많은 위치 정보가 저장될 수밖에 없고 따라서 경로 이미지 생성에 걸리는 시간이 더 길어질 수 있다.
-따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

비동기 처리

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

비동기 설정

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
-해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig {
}

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. -7.7. Task Execution and Scheduling, Spring Boot Docs

@Async 적용

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

RouteImageGenerator
@Async
public void generate(
List<Double> latitudes,
List<Double> longitudes,
List<Double> pointedLatitudes,
List<Double> pointedLongitudes,
Long tripId
) {
// 이미지 생성
RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
Coordinates coordinates = Coordinates.of(latitudes, longitudes);
Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
drawImage(coordinates, routeImageDrawer, pointedCoordinates);

// 이미지 저장
String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());

// 자원 할당 해제
routeImageDrawer.dispose();

// 데이터베이스 값 변경
Trip trip = tripRepository.findById(tripId)
.orElseThrow();
trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}

비동기 처리시 문제점

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
-따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
-인터페이스를 사용한다면 다음과 같은 구조가 된다.

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
-따라서 이벤트를 사용하기로 했다.

이벤트 사용

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

이벤트 발행

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
+따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

+

비동기 처리

+

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

+

비동기 설정

+

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
+해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig {
+}
+
+

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

+
+

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. +7.7. Task Execution and Scheduling, Spring Boot Docs

+
+

@Async 적용

+

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

+
@Async
+public void generate(
+        List<Double> latitudes,
+        List<Double> longitudes,
+        List<Double> pointedLatitudes,
+        List<Double> pointedLongitudes,
+        Long tripId
+) {
+    // 이미지 생성
+    RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
+    Coordinates coordinates = Coordinates.of(latitudes, longitudes);
+    Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
+    drawImage(coordinates, routeImageDrawer, pointedCoordinates);
+
+    // 이미지 저장
+    String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());
+
+    // 자원 할당 해제
+    routeImageDrawer.dispose();
+
+    // 데이터베이스 값 변경
+    Trip trip = tripRepository.findById(tripId)
+        .orElseThrow();
+    trip.changeRouteImageUrl(imageUrl);
+    tripRepository.save(trip);
+}
+
+

비동기 처리시 문제점

+

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
+따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

+ +

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
+인터페이스를 사용한다면 다음과 같은 구조가 된다.

+ +

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
+따라서 이벤트를 사용하기로 했다.

+

이벤트 사용

+

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

+

이벤트 발행

+

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
스프링에서는 ApplicationEventPublisher 인터페이스를 사용하여 이벤트를 발행할 수 있다.
-해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

TripService & TripUpdateEvent
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
...

// 이벤트 발행
applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
}

public record TripUpdateEvent(Long tripId) {
}

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
+해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

+
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
+    ...
+
+    // 이벤트 발행
+    applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
+}
+
+public record TripUpdateEvent(Long tripId) {
+}
+
+

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
이벤트를 구독하는 도메인의 행위를 담고 있는 이벤트를 발행(ex. RouteImageGenerateEvent)한다면 논리적인 의존 관계가 남아있기에 이벤트를 적절히 사용했다고 보기 어렵다.
-발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

이벤트 구독

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
-이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

TransactionPhase 설정

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
+발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

+

이벤트 구독

+

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
+이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

+

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
AFTER_ROLLBACK: 트랜잭션이 롤백되는 경우 이벤트 실행
AFTER_COMPLETION: 트랜잭션이 커밋 또는 롤백 되었을 경우 이벤트 실행
-BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

TripUpdateEventHandler
@Component
public class TripUpdateEventHandler {

private final RouteImageGenerator routeImageGenerator;
private final TripRepository tripRepository;

public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
this.routeImageGenerator = routeImageGenerator;
this.tripRepository = tripRepository;
}

@Async
@TransactionalEventListener(phase = AFTER_COMMIT)
public void handle(TripUpdateEvent tripUpdateEvent) {
Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());

String imageUrl = routeImageGenerator.generate(
trip.getLatitudes(),
trip.getLongitudes(),
trip.getPointedLatitudes(),
trip.getPointedLongitudes()
);

trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}
}

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
-또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

테스트

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

@ContextConfiguration(classes = TestSyncConfig.class)
@SpringBootTest
public class TripUpdateEventHandlerIntegrationTest {

...

@Test
void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
// given
TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
.willReturn(여행());

// when
transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));

// then
then(routeImageGenerator)
.should(times(1))
.generate(any(), any(), any(), any());
}
}

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
-통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

결과

./time.png

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
-응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

참고 자료

7.7. Task Execution and Scheduling, Spring Boot Docs
-Spring Events, Baeldung
-회원시스템 이벤트기반 아키텍처 구축하기

- - +BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

+

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

+
@Component
+public class TripUpdateEventHandler {
+
+    private final RouteImageGenerator routeImageGenerator;
+    private final TripRepository tripRepository;
+
+    public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
+        this.routeImageGenerator = routeImageGenerator;
+        this.tripRepository = tripRepository;
+    }
+
+    @Async
+    @TransactionalEventListener(phase = AFTER_COMMIT)
+    public void handle(TripUpdateEvent tripUpdateEvent) {
+        Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());
+
+        String imageUrl = routeImageGenerator.generate(
+                trip.getLatitudes(),
+                trip.getLongitudes(),
+                trip.getPointedLatitudes(),
+                trip.getPointedLongitudes()
+        );
+
+        trip.changeRouteImageUrl(imageUrl);
+        tripRepository.save(trip);
+    }
+}
+
+

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
+또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

+ +

테스트

+

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

+ + +
@ContextConfiguration(classes = TestSyncConfig.class)
+@SpringBootTest
+public class TripUpdateEventHandlerIntegrationTest {
+
+    ...
+
+    @Test
+    void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
+        // given
+        TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
+        given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
+                .willReturn(여행());
+
+        // when
+        transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));
+
+        // then
+        then(routeImageGenerator)
+                .should(times(1))
+                .generate(any(), any(), any(), any());
+    }
+}
+
+

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
+통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

+

결과

+

./time.png

+

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
+응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

+

참고 자료

+

7.7. Task Execution and Scheduling, Spring Boot Docs
+Spring Events, Baeldung
+회원시스템 이벤트기반 아키텍처 구축하기

\ No newline at end of file diff --git a/page/13.html b/page/13.html index 0240525cd..b2e838115 100644 --- a/page/13.html +++ b/page/13.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,24 +12,202 @@ - - - + + + -
-

· 약 12분

개요

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
-경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

구현 결과

./result.png

예시 데이터는 다음과 같다.
-서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

예시 데이터
List<Double> x = List.of(
126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
);
List<Double> y = List.of(
37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
);
List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);

IMAGE_SIZE & ROUTE_SIZE

RouteImageGenerator.java
private static final int IMAGE_SIZE = 800;
private static final int ROUTE_SIZE = 600;

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
+

· 약 12분

개요

+

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
+경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

+

구현 결과

+

./result.png

+

예시 데이터는 다음과 같다.
+서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

+
List<Double> x = List.of(
+        126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
+        126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
+);
+List<Double> y = List.of(
+        37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
+        37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
+);
+List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
+List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);
+
+

IMAGE_SIZE & ROUTE_SIZE

+
private static final int IMAGE_SIZE = 800;
+private static final int ROUTE_SIZE = 600;
+
+

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
IMAGE_SIZE는 말 그대로 이미지의 width와 height를 의미한다.
ROUTE_SIZE의 경우 상하좌우 100px 만큼의 간격을 위해 존재한다.
-따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

./600.png

사이즈 변경의 이유

255 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 800 사이즈로 변경했다.

주요 클래스

요약

클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성

의존관계

Coordinates(위도, 경도의 일급 컬렉션)

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
-Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는

Positions 계산 로직은 다음과 같다.
-위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

Coordinates.java
// 호출
// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);

private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
Double minValue = Collections.min(values);
return values.stream()
.map(value -> normalizeCoordinate(value, maxDifference, minValue))
.map(value -> mapToPosition(value, routeImageSize))
.toList();
}

private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
return (coordinate - minValue) / maxDifference;
}

private int mapToPosition(Double coordinate, Integer routeImageSize) {
return (int) (coordinate * routeImageSize);
}

위도로 예시든 내용이다.

  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  3. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.

Positions(실제 이미지 생성에 사용할 위치)

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • size: 크기를 반환한다.
  • xPositions: x 값들을 반환한다.
  • yPositions: y 값들을 반환한다.

중앙 정렬 로직은 다음과 같다.

Positions.java
public Positions align(int imageSize, int routeSize) {
int xOffset = calculateOffset(Position::x, imageSize);
int yOffset = calculateOffset(Position::y, imageSize);

return items.stream()
.map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
.collect(collectingAndThen(toList(), Positions::new));
}

private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
List<Integer> positions = items.stream()
.mapToInt(positionToInteger)
.boxed()
.toList();

int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
return imageSize / 2 - midValue;
}

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
-BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

./800.png

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

x 값 → 계산한 offset 그대로 더한다.
-y 값 → imageSize(800)에서 y + offset 값을 뺀다.

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
-그림을 그리기 위해 설정한 상수들이 존재한다.

RouteImageDrawer.java
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
// 이를 RGBA라고 부른다.
private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
// 배경 투명색
private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
// 경로를 위한 STROKE
private static final int LINE_STROKE_WIDTH = 7;
private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 위치 점을 위한 STROKE
private static final int POINT_STROKE_WIDTH = 20;
private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 안티앨리어싱 등 화질 개선을 위한 설정
private static final Map<Object, Object> renderingHints = Map.of(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
);

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

  • drawLine: 선을 그린다.
  • drawPoint: 점을 찍는다.
  • dispose: 자원 할당을 해제한다.

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

이미지 생성 Flow

1. 이미지 생성 준비

2. 선 그리기 요청

3. 위치 점 그리기 요청

4. 업로드 요청

전체 Flow

- - +따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

+

./600.png

+

사이즈 변경의 이유

+

255 * 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 * 800 사이즈로 변경했다.

+

주요 클래스

+

요약

+
클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성
+

의존관계

+ +

Coordinates(위도, 경도의 일급 컬렉션)

+

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
+Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

+
    +
  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • +
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는
  • +
+

Positions 계산 로직은 다음과 같다.
+위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

+
// 호출
+// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
+// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);
+
+private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
+    Double minValue = Collections.min(values);
+    return values.stream()
+            .map(value -> normalizeCoordinate(value, maxDifference, minValue))
+            .map(value -> mapToPosition(value, routeImageSize))
+            .toList();
+}
+
+private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
+    return (coordinate - minValue) / maxDifference;
+}
+
+private int mapToPosition(Double coordinate, Integer routeImageSize) {
+    return (int) (coordinate * routeImageSize);
+}
+
+

위도로 예시든 내용이다.

+
    +
  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. +
  3. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  4. +
  5. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.
  6. +
+

Positions(실제 이미지 생성에 사용할 위치)

+

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

+
    +
  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • +
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • +
  • size: 크기를 반환한다.
  • +
  • xPositions: x 값들을 반환한다.
  • +
  • yPositions: y 값들을 반환한다.
  • +
+

중앙 정렬 로직은 다음과 같다.

+
public Positions align(int imageSize, int routeSize) {
+    int xOffset = calculateOffset(Position::x, imageSize);
+    int yOffset = calculateOffset(Position::y, imageSize);
+
+    return items.stream()
+            .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
+            .collect(collectingAndThen(toList(), Positions::new));
+}
+
+private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
+    List<Integer> positions = items.stream()
+            .mapToInt(positionToInteger)
+            .boxed()
+            .toList();
+
+    int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
+    return imageSize / 2 - midValue;
+}
+
+

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
+BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

+

./800.png

+

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

+

x 값 → 계산한 offset 그대로 더한다.
+y 값 → imageSize(800)에서 y + offset 값을 뺀다.

+

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

+

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
+그림을 그리기 위해 설정한 상수들이 존재한다.

+
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
+// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
+// 이를 RGBA라고 부른다.
+private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
+// 배경 투명색
+private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
+// 경로를 위한 STROKE
+private static final int LINE_STROKE_WIDTH = 7;
+private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 위치 점을 위한 STROKE
+private static final int POINT_STROKE_WIDTH = 20;
+private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 안티앨리어싱 등 화질 개선을 위한 설정
+private static final Map<Object, Object> renderingHints = Map.of(
+        RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
+        RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
+        RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
+);
+
+

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

+
    +
  • drawLine: 선을 그린다.
  • +
  • drawPoint: 점을 찍는다.
  • +
  • dispose: 자원 할당을 해제한다.
  • +
+

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

+

이미지 생성 Flow

+

1. 이미지 생성 준비

+ +

2. 선 그리기 요청

+ +

3. 위치 점 그리기 요청

+ +

4. 업로드 요청

+ +

전체 Flow

+
\ No newline at end of file diff --git a/page/14.html b/page/14.html index ed6109b59..0bcfb7614 100644 --- a/page/14.html +++ b/page/14.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,34 +12,182 @@ - - - + + + -
-

· 약 7분

개요

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

사용 기술

언어: Python 3.10
+

· 약 7분

개요

+

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

+

사용 기술

+

언어: Python 3.10
이미지 생성: matplotlib
서비스: AWS Lambda, AWS API Gateway
-이미지 저장 및 URL: AWS S3, AWS CloudFront

플로우는 다음과 같다.

요구사항

./route.png

우측 상단의 경로 이미지를 생성하려고 한다.
-경로 이미지 생성에 대한 요구사항은 다음과 같다.

  • 위도, 경도로 이루어진 배열을 입력받는다.
  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.

이미지 출력 방식

  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
-파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

로컬에서 기능 구현

import time

import matplotlib.pyplot as plt


def draw(point):
start = time.time()
x, y = zip(*point)
pixel_x, pixel_y = convert_to_pixel_values(x, y)
draw_lines(pixel_x, pixel_y)
end = time.time()
print(end - start)

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)


def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
return scaled_coordinates


def draw_lines(x, y):
figure = plt.gcf()
figure.set_size_inches(5, 5)
plt.plot(x, y, c = 'w',linewidth=5)
plt.scatter(x[3],y[3], c = 'w', s = 125)
plt.axis('off')
plt.savefig('name.png', transparent=True, format='png')

point = [
[126.96352960597338, 37.590841000217125],
[126.96987292787792, 37.58435564234159],
[126.98128481452298, 37.58594375113966],
[126.99360339342958, 37.58248524741927],
[126.99867565340067, 37.56778118088622],
[127.001935378366117, 37.55985240444085],
[126.9831048919687, 37.548030119488665],
[126.97189273528845, 37.5119879225856],
[127.02689859997221, 37.48488593333883]
]

draw(point)

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

./routeImage.png

AWS Lambda

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
+이미지 저장 및 URL: AWS S3, AWS CloudFront

+

플로우는 다음과 같다.

+ +

요구사항

+

./route.png

+

우측 상단의 경로 이미지를 생성하려고 한다.
+경로 이미지 생성에 대한 요구사항은 다음과 같다.

+
    +
  • 위도, 경도로 이루어진 배열을 입력받는다.
  • +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.
  • +
+

이미지 출력 방식

+
    +
  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. +
  3. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장
  4. +
+

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
+파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

+

로컬에서 기능 구현

+
import time
+
+import matplotlib.pyplot as plt
+
+
+def draw(point):
+    start = time.time()
+    x, y = zip(*point)
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    draw_lines(pixel_x, pixel_y)
+    end = time.time()
+    print(end - start)
+    
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    return scaled_coordinates
+
+
+def draw_lines(x, y):
+    figure = plt.gcf()
+    figure.set_size_inches(5, 5)
+    plt.plot(x, y, c = 'w',linewidth=5)
+    plt.scatter(x[3],y[3], c = 'w', s = 125)
+    plt.axis('off')
+    plt.savefig('name.png', transparent=True, format='png')
+
+point = [
+    [126.96352960597338, 37.590841000217125],
+    [126.96987292787792, 37.58435564234159],
+    [126.98128481452298, 37.58594375113966],
+    [126.99360339342958, 37.58248524741927],
+    [126.99867565340067, 37.56778118088622],
+    [127.001935378366117, 37.55985240444085],
+    [126.9831048919687, 37.548030119488665],
+    [126.97189273528845, 37.5119879225856],
+    [127.02689859997221, 37.48488593333883]
+]
+
+draw(point)
+
+

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

+

./routeImage.png

+

AWS Lambda

+

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
따라서 서버리스로 파일을 처리했다.
-추가로 s3 접근은 boto3를 사용했다.

람다 S3 접근을 위한 IAM 생성

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

람다 배포용 코드

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.


import io
import uuid

import boto3
import matplotlib.pyplot as plt

PIXEL = 255
BUCKET_NAME = 'image-plot'
S3 = 's3'

def lambda_handler(event, context):
x = event['x']
y = event['y']
image_name = str(uuid.uuid4())

img_data = draw(x, y)
s3 = boto3.client(S3)
s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'

return {
'statusCode': 200,
'body': url
}

def draw(x, y):
pixel_x, pixel_y = convert_to_pixel_values(x, y)
img_data = draw_lines(pixel_x, pixel_y)
plt.close()
return img_data

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)

def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
return pixel_values

def draw_lines(x, y):
plt.plot(x, y, 'k-', linewidth=10)
plt.axis('off')
img_data = io.BytesIO()
plt.savefig(img_data, transparent=True, format='png')
img_data.seek(0)
return img_data

Layer 추가를 위한 zip 파일 생성

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
+추가로 s3 접근은 boto3를 사용했다.

+

람다 S3 접근을 위한 IAM 생성

+

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

+

람다 배포용 코드

+

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.

+

+import io
+import uuid
+
+import boto3
+import matplotlib.pyplot as plt
+
+PIXEL = 255
+BUCKET_NAME = 'image-plot'
+S3 = 's3'
+
+def lambda_handler(event, context):
+    x = event['x']
+    y = event['y']
+    image_name = str(uuid.uuid4())
+
+    img_data = draw(x, y)
+    s3 = boto3.client(S3)
+    s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
+    url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'
+
+    return {
+        'statusCode': 200,
+        'body': url
+    }
+
+def draw(x, y):
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    img_data = draw_lines(pixel_x, pixel_y)
+    plt.close()
+    return img_data
+
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
+    return pixel_values
+
+def draw_lines(x, y):
+    plt.plot(x, y, 'k-', linewidth=10)
+    plt.axis('off')
+    img_data = io.BytesIO()
+    plt.savefig(img_data, transparent=True, format='png')
+    img_data.seek(0)
+    return img_data
+
+
+

Layer 추가를 위한 zip 파일 생성

+

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
zip 파일을 만들어서 업로드해야한다.
이때 python의 Lambda 런타임에 대한 계층 경로는 python이다.
-따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

pillow.zip
│ python/PIL
└ python/Pillow-5.3.0.dist-info

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

sudo apt update
sudo apt install zip
sudo apt install python3-pip

mkdir python
pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로

No module named 'numpy.core._multiarray_umath' 에러

Layer 추가 후 람다 실행 시 발생한 에러였다.
+따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

+
pillow.zip
+│ python/PIL
+└ python/Pillow-5.3.0.dist-info
+
+

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

+
sudo apt update
+sudo apt install zip
+sudo apt install python3-pip
+
+mkdir python
+pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
+zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로
+
+

No module named 'numpy.core._multiarray_umath' 에러

+

Layer 추가 후 람다 실행 시 발생한 에러였다.
처음에 mac에서 zip 파일을 생성해서 업로드했는데 해당 문제가 발생했다.
이는 lambda가 돌아가는 동일한 환경에서 layer를 위한 zip 파일을 만들지 않아서 발생하는 문제다.
-간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

적정기술에 대한 생각

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
+간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

+

적정기술에 대한 생각

+

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
AWS Lambda를 사용하는 것은 인스턴스에 해당 코드를 배포하는 것보다 더 효율적인 방법일 수 있다.
하지만 현재 프로젝트에서 가용 가능한 자원, 기술의 난이도, 사용하는 팀원을 고려한다면 Lambda는 적정기술이 아닐 수 있다.
-따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

최종적으로 Java AWT를 사용하기로 결정했다.

참고 자료

AWS Lambda
-Lambda Layer
-Python Lambda 함수에 대한 .zip 파일 아카이브 작업
-No module named 'numpy.core._multiarray_umath'
-사례별로 알아본 안전한 S3 사용 가이드

- - +따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

+

최종적으로 Java AWT를 사용하기로 결정했다.

+

참고 자료

+

AWS Lambda
+Lambda Layer
+Python Lambda 함수에 대한 .zip 파일 아카이브 작업
+No module named 'numpy.core._multiarray_umath'
+사례별로 알아본 안전한 S3 사용 가이드

\ No newline at end of file diff --git a/page/15.html b/page/15.html index 4d63e4602..c7bdce98b 100644 --- a/page/15.html +++ b/page/15.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,22 +12,51 @@ - - - + + + -
-

· 약 3분

개요

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
-하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
+

· 약 3분

개요

+

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
+하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

+

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

+

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
해당 static 메서드를 호출하는 부분을 따로 RouteImageUploader 클래스로 최대한 분리했다.
-이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

public void upload(BufferedImage bufferedImage) {
File file = new File(파일경로);
try {
ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
} catch (IOException e) {
throw new DrawException(IMAGE_SAVE_FAIL);
}
}

Mocking static methods

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
-mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

// given
BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
RouteImageUploader routeImageUploader = new RouteImageUploader();

// expect
try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
routeImageUploader.upload(bufferedImage);
imageIO.verify(
() -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
times(1)
);
}

마치며

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
+이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

+
public void upload(BufferedImage bufferedImage) {
+    File file = new File(파일경로);
+    try {
+        ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
+    } catch (IOException e) {
+        throw new DrawException(IMAGE_SAVE_FAIL);
+    }
+}
+
+

Mocking static methods

+

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
+mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

+

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

+
// given
+BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
+RouteImageUploader routeImageUploader = new RouteImageUploader();
+
+// expect
+try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
+    routeImageUploader.upload(bufferedImage);
+    imageIO.verify(
+            () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
+            times(1)
+    );
+}
+
+

마치며

+

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
하지만 추상화를 하면 할 수록 코드의 복잡도는 증가한다.
-항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

참고 자료

Mocking static methods
-Mockito mock static methods
-Enable mocking static methods in Mockito

- - +항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

+

참고 자료

+

Mocking static methods
+Mockito mock static methods
+Enable mocking static methods in Mockito

\ No newline at end of file diff --git a/page/16.html b/page/16.html index 154c8588f..0eba9f0ac 100644 --- a/page/16.html +++ b/page/16.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,20 +12,61 @@ - - - + + + -
-

· 약 6분

./route.png

이미지 생성의 책임

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
-따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

고려한 기술

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

  • Python의 Matplotlib
  • AWT(Abstract Window Toolkit) [최종 선택]
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)

Python & Matplotlib

데이터 시각화 라이브러리
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

  • 코드가 간단해서 유지 보수성이 좋다.
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.

Java AWT 이외의 라이브러리

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음

Java & AWT(Abstract Window Toolkit)

그래픽과 이미지를 그리기 위한 도구
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • 추가적인 api 호출을 하지 않아도 된다.

기술 선택

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
-하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

유지 보수

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
-따라서 다음과 같은 방법으로 공유하기로 했다.

  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. AWT를 사용한 부분을 문서화하여 공유한다.

레벨 3를 마무리하며 내용 추가

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
+

· 약 6분

./route.png

+

이미지 생성의 책임

+

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
+따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

+

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

+
    +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
+

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

+

고려한 기술

+

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

+
    +
  • Python의 Matplotlib
  • +
  • AWT(Abstract Window Toolkit) [최종 선택]
  • +
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • +
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)
  • +
+

Python & Matplotlib

+

데이터 시각화 라이브러리
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

+
    +
  • 코드가 간단해서 유지 보수성이 좋다.
  • +
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • +
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.
  • +
+

Java AWT 이외의 라이브러리

+

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

+
라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음
+

Java & AWT(Abstract Window Toolkit)

+

그래픽과 이미지를 그리기 위한 도구
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

+
    +
  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • +
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • +
  • 추가적인 api 호출을 하지 않아도 된다.
  • +
+

기술 선택

+

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
+하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

+

유지 보수

+

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
+따라서 다음과 같은 방법으로 공유하기로 했다.

+
    +
  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. +
  3. AWT를 사용한 부분을 문서화하여 공유한다.
  4. +
+

레벨 3를 마무리하며 내용 추가

+

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
AWT를 사용하는 부분에서 애플리케이션 실행 시간을 제외하면 파이썬과 비슷한 시간안에 이미지를 생성할 수 있었다.

- - \ No newline at end of file diff --git a/page/17.html b/page/17.html index 50fa02461..c92a7a7b8 100644 --- a/page/17.html +++ b/page/17.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,29 +12,100 @@ - - - + + + -
-

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
-2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

자바 변경 사항

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
-따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

Switch Expressions(Java 14)

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

enum RESULT {
WIN, LOSE, DRAW
}

RESULT result = RESULT.WIN;

int prize = switch (result) {
case WIN -> 10_000_000;
case LOSE, DRAW -> 5_000_000;
default -> 0;
};

주요 특징은 다음과 같다.

  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • break 문이 필요 없다.
  • default 블록을 통해 기본 값을 지정할 수 있다.

Text Block(Java 15)

Java 15에는 새로운 문자열 표현방식이 추가되었다.
-긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("""
SELECT p FROM Post p
WHERE p.title LIKE %:keyword%
OR p.content LIKE %:keyword%
""")
List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
}

NPE 메시지(Java 15)

String name = null;
name.chars();

/**
# before
java.lang.NullPointerException
at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)

# after
Cannot invoke "String.chars()" because "name" is null
java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
*/

Record(Java 16)

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
+

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

+

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
+2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

+

자바 변경 사항

+

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
+따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

+

Switch Expressions(Java 14)

+

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

+
enum RESULT {
+    WIN, LOSE, DRAW
+}
+
+RESULT result = RESULT.WIN;
+
+int prize = switch (result) {
+    case WIN -> 10_000_000;
+    case LOSE, DRAW -> 5_000_000;
+	default -> 0;
+};
+
+

주요 특징은 다음과 같다.

+
    +
  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • +
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • +
  • break 문이 필요 없다.
  • +
  • default 블록을 통해 기본 값을 지정할 수 있다.
  • +
+

Text Block(Java 15)

+

Java 15에는 새로운 문자열 표현방식이 추가되었다.
+긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

+
@Repository
+public interface PostRepository extends JpaRepository<Post, Long> {
+    @Query("""
+        SELECT p FROM Post p
+        WHERE p.title LIKE %:keyword%
+        OR p.content LIKE %:keyword%
+        """)
+    List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
+}
+
+

NPE 메시지(Java 15)

+
String name = null;
+name.chars();
+
+/** 
+# before
+java.lang.NullPointerException
+	at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)
+
+# after
+Cannot invoke "String.chars()" because "name" is null
+java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
+*/
+
+

Record(Java 16)

+

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
Record를 선언하는 경우 접근자, 생성자, equals & hashcode, toString이 제공된다.
-데이터 전송 용도로 적합해 보인다.

public record PostDto(String title, String content) {
}

추가적인 변경사항

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

스프링, 스프링 부트 변경 사항

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
-따라서 필요해보이는 몇개 정도만 정리했다.

스프링 요구사항

Java 17, Jakarta EE 9 이상이어야 한다.

네임스페이스 변경

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

PathPatternParser - trailing slash 허용하지 않음

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
-6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

PathPatternParser used by default (with the ability to opt into PathMatcher).

HTTP interface client

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
-자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

스프링 부트 최소 요구사항

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
-이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

참고 자료

어느 월급쟁이개발자 의 스프링 부트 따라잡기
-자바 9-16 주요 특징 복습하기
-Java EE에서 Jakarta EE로의 전환
-Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
-What's New in Spring Framework 6.x
-Spring Boot 3.0 Release Notes
-Spring Boot 3.1 Release Notes

- - +데이터 전송 용도로 적합해 보인다.

+
public record PostDto(String title, String content) {
+}
+
+

추가적인 변경사항

+

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

+

스프링, 스프링 부트 변경 사항

+

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
+따라서 필요해보이는 몇개 정도만 정리했다.

+

스프링 요구사항

+

Java 17, Jakarta EE 9 이상이어야 한다.

+

네임스페이스 변경

+

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

+

PathPatternParser - trailing slash 허용하지 않음

+

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
+6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

+
+

PathPatternParser used by default (with the ability to opt into PathMatcher).

+
+

HTTP interface client

+

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
+자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

+

스프링 부트 최소 요구사항

+

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
+이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

+

참고 자료

+

어느 월급쟁이개발자 의 스프링 부트 따라잡기
+자바 9-16 주요 특징 복습하기
+Java EE에서 Jakarta EE로의 전환
+Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
+What's New in Spring Framework 6.x
+Spring Boot 3.0 Release Notes
+Spring Boot 3.1 Release Notes

\ No newline at end of file diff --git a/page/18.html b/page/18.html index 39b95c024..69bc3e615 100644 --- a/page/18.html +++ b/page/18.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,27 +12,71 @@ - - - + + + -
-

· 약 5분

웹소켓

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
-웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

웹소켓 등장 배경

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
-이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

polling, long polling, streaming

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.

웹소켓의 동작

1. Upgrade 요청

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
+

· 약 5분

웹소켓

+

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
+웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

+

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

+

웹소켓 등장 배경

+

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
+이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

+

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

    +
  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • +
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.
  • +

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

    +
  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.
  • +

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

    +
  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.
  • +
+

웹소켓의 동작

+ +

1. Upgrade 요청

+

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
이는 HTTP와 같이 80, 443 포트를 사용한다.
웹소켓으로 전환하기 위해서는 Upgrade: websocket, Connection: Upgrade 헤더가 필요하다.
Sec-WebSocket-Key는 서버에서 Sec-WebSocket-Accept를 계산하여 응답하고 이 값이 예상한 값과 다르면 연결이 수립되지 않는다.
Sec-WebSocket-Protocol의 경우 서브프로토콜의 목록으로 서버 측에서는 해당 목록 중 하나를 선택하여 반환해야 한다.
-만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

GET /chats HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

2. Switching Protocols

서버는 101 Switching Protocols 응답을 반환한다.
+만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

+
GET /chats HTTP/1.1
+Host: localhost:8080
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
+Sec-WebSocket-Protocol: v10.stomp, v11.stomp
+Sec-WebSocket-Version: 13
+Origin: http://localhost:8080
+
+

2. Switching Protocols

+

서버는 101 Switching Protocols 응답을 반환한다.
Sec-WebSocket-Accept은 Sec-WebSocket-Key 뒤에 258EAFA5-E914-47DA-95CA-C5AB0DC85B11를 붙이고 SHA1로 해싱 후 Base64로 인코딩하여 반환한다.
-이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

3. 통신 후 종료

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
-연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

참고 자료

https://datatracker.ietf.org/doc/html/rfc6455
-https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
-https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
-https://docs.spring.io/spring-framework/reference/web/websocket.html

- - +이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

+
HTTP/1.1 101 Switching Protocols 
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
+Sec-WebSocket-Protocol: v10.stomp
+
+

3. 통신 후 종료

+

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
+연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

+

참고 자료

+

https://datatracker.ietf.org/doc/html/rfc6455
+https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
+https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
+https://docs.spring.io/spring-framework/reference/web/websocket.html

\ No newline at end of file diff --git a/page/19.html b/page/19.html index a6a888b4a..30a8f04ff 100644 --- a/page/19.html +++ b/page/19.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,34 +12,359 @@ - - - + + + -
-

· 약 11분

팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.

설치

공식 홈페이지에 들어가서 최신 버전을 설치한다.

yarn create docusaurus

배포

배포 안내 문서
+

· 약 11분

팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.

+

설치

+

공식 홈페이지에 들어가서 최신 버전을 설치한다.

+
yarn create docusaurus
+
+

배포

+

배포 안내 문서
netlify나 vercel 같은 서버리스 플랫폼을 추천하고 있고, 간단하고, 빠른 시간 안에 배포를 할 수 있다.
-이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.

레포지토리 생성

github pages를 이용하려면 예시와 같이 username.github.io 형태의 레포지토리를 생성해야 한다.
-이때 organization을 사용하는 경우 organization.github.io 형태의 레포지토리를 생성해서 사용한다.

설정 파일 수정

docusaurus.config
module.exports = {
// ...
url: 'https://greeng00se.github.io',
baseUrl: '/',
projectName: 'greeng00se.github.io',
organizationName: 'greeng00se',
trailingSlash: false,
// ...
};

토큰 설정

github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.
-이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.

github

브랜치 생성

github에서 gh-pages 브랜치를 하나 생성한다.
+이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.

+

레포지토리 생성

+

github pages를 이용하려면 예시와 같이 username.github.io 형태의 레포지토리를 생성해야 한다.
+이때 organization을 사용하는 경우 organization.github.io 형태의 레포지토리를 생성해서 사용한다.

+

설정 파일 수정

+
module.exports = {
+  // ...
+  url: 'https://greeng00se.github.io',
+  baseUrl: '/',
+  projectName: 'greeng00se.github.io',
+  organizationName: 'greeng00se',
+  trailingSlash: false,
+  // ...
+};
+
+

토큰 설정

+

github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.
+이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.

+

github

+

브랜치 생성

+

github에서 gh-pages 브랜치를 하나 생성한다.
repository -> settings -> pages -> branch에서 생성한 gh-pages로 브랜치를 변경한다.
-설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.

워크플로 작성

Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.
-배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.

.github/workflows/deploy.yml
name: blog

on:
push:
branches: [main]

jobs:
deploy:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build website
run: yarn build

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.DEPLOY_TOKEN }}
publish_dir: ./build
user_name: github-actions[bot]
user_email: 41898282+github-actions[bot]@users.noreply.github.com

댓글 기능

giscus를 이용하여 댓글 기능을 추가한다.

giscus 설정

  1. 공개 저장소여야 한다.
  2. giscus 앱이 설치되어 있어야 한다.
  3. Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.

자세한 내용은 giscus를 확인하자.

docusaurus 설정

swizzling을 이용하여 컴포넌트를 감싼다.
+설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.

+

워크플로 작성

+

Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.
+배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.

+
name: blog
+
+on:
+  push:
+    branches: [main]
+
+jobs:
+  deploy:
+    name: Deploy to GitHub Pages
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@v3
+        with:
+          node-version: 18
+          cache: yarn
+
+      - name: Install dependencies
+        run: yarn install --frozen-lockfile
+      - name: Build website
+        run: yarn build
+
+      - name: Deploy to GitHub Pages
+        uses: peaceiris/actions-gh-pages@v3
+        with:
+          github_token: ${{ secrets.DEPLOY_TOKEN }}
+          publish_dir: ./build
+          user_name: github-actions[bot]
+          user_email: 41898282+github-actions[bot]@users.noreply.github.com
+
+

댓글 기능

+

giscus를 이용하여 댓글 기능을 추가한다.

+

giscus 설정

+
    +
  1. 공개 저장소여야 한다.
  2. +
  3. giscus 앱이 설치되어 있어야 한다.
  4. +
  5. Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.
  6. +
+

자세한 내용은 giscus를 확인하자.

+

docusaurus 설정

+

swizzling을 이용하여 컴포넌트를 감싼다.
기존에 게시물을 giscus가 포함된 리액트 컴포넌트로 감싸는 형태가 된다.
-아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.

yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap

명령어를 입력하면 /src/theme/BlogPostItem/index.js 위치에 파일이 생성된다.
-파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.

/src/theme/BlogPostItem/index.js
import OriginalBlogPostItem from "@theme-original/BlogPostItem";
import React, { useEffect, useRef } from "react";
// @ts-expect-error internal code
import { useColorMode } from "@docusaurus/theme-common";
import { useBlogPost } from "@docusaurus/theme-common/internal";

const giscusSelector = "iframe.giscus-frame";

function BlogPostItem(props) {
const { colorMode } = useColorMode();
const { isBlogPostPage } = useBlogPost();
const giscusTheme = colorMode === "dark" ? "dark" : "light";
const containerRef = useRef(null);

useEffect(() => {
if (!isBlogPostPage) return;

const giscusEl = containerRef.current.querySelector(giscusSelector);

const createGiscusEl = () => {
const script = document.createElement("script");

script.src = "https://giscus.app/client.js";
script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");
script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");
script.setAttribute("data-category", "Announcements");
script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");
script.setAttribute("data-mapping", "pathname");
script.setAttribute("data-strict", "0");
script.setAttribute("data-reactions-enabled", "1");
script.setAttribute("data-emit-metadata", "0");
script.setAttribute("data-input-position", "bottom");
script.setAttribute("data-theme", giscusTheme);
script.setAttribute("data-lang", "ko");
script.crossOrigin = "anonymous";
script.async = true;

containerRef.current.appendChild(script);
};

const postThemeMessage = () => {
const message = {
setConfig: {
theme: giscusTheme,
}
};

giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
};

giscusEl ? postThemeMessage() : createGiscusEl();
}, [giscusTheme]);

return (
<>
<OriginalBlogPostItem {...props} />
{isBlogPostPage && <div ref={containerRef} />}
</>
);
}

export default BlogPostItem;

알고리아 설정 및 직접 관리하기

알고리아를 사용하면 검색 기능을 추가할 수 있다.
-유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.

무료 플랜은 직접 인덱스를 수집하는 방법과, docsearch를 이용하는 방법이 있다.
+아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.

+
yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap
+
+

명령어를 입력하면 /src/theme/BlogPostItem/index.js 위치에 파일이 생성된다.
+파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.

+
import OriginalBlogPostItem from "@theme-original/BlogPostItem";
+import React, { useEffect, useRef } from "react";
+// @ts-expect-error internal code
+import { useColorMode } from "@docusaurus/theme-common";
+import { useBlogPost } from "@docusaurus/theme-common/internal";
+
+const giscusSelector = "iframe.giscus-frame";
+
+function BlogPostItem(props) {
+  const { colorMode } = useColorMode();
+  const { isBlogPostPage } = useBlogPost();
+  const giscusTheme = colorMode === "dark" ? "dark" : "light";
+  const containerRef = useRef(null);
+
+  useEffect(() => {
+    if (!isBlogPostPage) return;
+
+    const giscusEl = containerRef.current.querySelector(giscusSelector);
+
+    const createGiscusEl = () => {
+      const script = document.createElement("script");
+
+      script.src = "https://giscus.app/client.js";
+      script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");
+      script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");
+      script.setAttribute("data-category", "Announcements");
+      script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");
+      script.setAttribute("data-mapping", "pathname");
+      script.setAttribute("data-strict", "0");
+      script.setAttribute("data-reactions-enabled", "1");
+      script.setAttribute("data-emit-metadata", "0");
+      script.setAttribute("data-input-position", "bottom");
+      script.setAttribute("data-theme", giscusTheme);
+      script.setAttribute("data-lang", "ko");
+      script.crossOrigin = "anonymous";
+      script.async = true;
+      
+      containerRef.current.appendChild(script);
+    };
+
+    const postThemeMessage = () => {
+      const message = {
+        setConfig: {
+          theme: giscusTheme,
+        }
+      };
+
+      giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
+    };
+
+    giscusEl ? postThemeMessage() : createGiscusEl();
+  }, [giscusTheme]);
+
+  return (
+    <>
+      <OriginalBlogPostItem {...props} />
+      {isBlogPostPage && <div ref={containerRef} />}
+    </>
+  );
+}
+
+export default BlogPostItem;
+
+

알고리아 설정 및 직접 관리하기

+

알고리아를 사용하면 검색 기능을 추가할 수 있다.
+유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.

+

무료 플랜은 직접 인덱스를 수집하는 방법과, docsearch를 이용하는 방법이 있다.
docsearch에 등록한다면 일주일에 한 번씩 크롤링이 진행된다.
-이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.

알고리아 애플리케이션 생성 및 키 확인

회원가입을 하고 새로운 애플리케이션 생성을 누른다.
-생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.

algolia

키 생성

직접 인덱스를 수집하기 위한 키를 생성한다.
-addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.

key

.env 파일 생성

프로젝트 폴더 상단에 .env 파일을 생성한다.

.env
APPLICATION_ID=MVIU5UEMOM
API_KEY=인덱스_생성용_키

config 파일 생성

마찬가지로 최상단에 config.json 파일을 생성한다. -설정 파일은 해당 링크를 참고한다.
-또는 Docusaurus의 설정 파일을 참고한다.

config.json
{
"index_name": "teco",
"start_urls": [
"https://teco-chat.github.io/"
],
"sitemap_urls": [
"https://teco-chat.github.io/sitemap.xml"
],
"sitemap_alternate_links": true,
"stop_urls": [
"/tests"
],
"selectors": {
"lvl0": {
"selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
"type": "xpath",
"global": true,
"default_value": "Documentation"
},
"lvl1": "header h1",
"lvl2": "article h2",
"lvl3": "article h3",
"lvl4": "article h4",
"lvl5": "article h5, article td:first-child",
"lvl6": "article h6",
"text": "article p, article li, article td:last-child"
},
"strip_chars": " .,;:#",
"custom_settings": {
"separatorsToIndex": "_",
"attributesForFaceting": [
"language",
"version",
"type",
"docusaurus_tag"
],
"attributesToRetrieve": [
"hierarchy",
"content",
"anchor",
"url",
"url_without_anchor",
"type"
]
},
"conversation_id": [
"833762294"
],
"nb_hits": 46250
}

docker 이용하여 크롤링

docker와 jq가 필요하다.
-jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.

brew install jq

다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.

docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper

docusaurus 설정

전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.

docusaurus.config
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...
algolia: {
appId: 'MVIU5UEMOM', // Application ID
apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key
indexName: 'teco', // config.json에 설정한 인덱스명
contextualSearch: true,
},
})

부가 설정

화면 상단 Github Icon

파일 최하단에 아래 css 구문을 추가한다.

/src/css/custom.css
.header-github-link:hover {
opacity: 0.6;
}

.header-github-link:before {
content: '';
width: 24px;
height: 24px;
display: flex;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}

html[data-theme='dark'] .header-github-link:before {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}

themeconfig -> navbar에 github link를 설정한다.

docusaurus.config
navbar: {
title: 'HELLO',
items: [
{
href: 'https://github.com/greeng00se',
position: 'right',
className: 'header-github-link',
'aria-label': 'GitHub repository',
},
],
},

코드블럭

java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.
-prism 설정을 아래와 같이 변경해 준다.

docusaurus.config
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
additionalLanguages: ['java', 'kotlin'],
}

mermaid

mermaid를 사용하려면 @docusaurus/theme-mermaid 를 설치해야 한다.

yarn add @docusaurus/theme-mermaid

설치 후 아래와 같이 설정을 추가한다.

docusaurus.config
const config = {
...
markdown: {
mermaid: true,
},
themes: [
'@docusaurus/theme-mermaid'
],
};

themeConfig에서 mermaid의 테마를 지정할 수 있다.

docusaurus.config
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...
mermaid: {
theme: {
light: 'neutral',
dark: 'dark'
},
},
}),

국제화 설정

국제화 설정을 한다면 Older Entries 형태의 설명이 다음 페이지 로 변경된다.
-설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.

docusaurus.config
i18n: {
defaultLocale: "ko",
locales: ["ko"],
},

블로그 글 author

팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.

author

authors.yml 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.

/blog/authors.yml
herb:
name: 허브
title: Backend
url: https://github.com/greeng00se
image_url: https://github.com/greeng00se.png

mallang:
name: 말랑
title: Backend
url: https://github.com/shin-mallang
image_url: https://github.com/shin-mallang.png

블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.

---
slug: 1
title: Hello World
authors: [herb, mallang]
tags: [hello, docusaurus]
---

첫 번째 문서 내용
- - +이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.

+ +

알고리아 애플리케이션 생성 및 키 확인

+

회원가입을 하고 새로운 애플리케이션 생성을 누른다.
+생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.

+

algolia

+

키 생성

+

직접 인덱스를 수집하기 위한 키를 생성한다.
+addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.

+

key

+

.env 파일 생성

+

프로젝트 폴더 상단에 .env 파일을 생성한다.

+
APPLICATION_ID=MVIU5UEMOM
+API_KEY=인덱스_생성용_키
+
+

config 파일 생성

+

마찬가지로 최상단에 config.json 파일을 생성한다. +설정 파일은 해당 링크를 참고한다.
+또는 Docusaurus의 설정 파일을 참고한다.

+
{
+  "index_name": "teco",
+  "start_urls": [
+    "https://teco-chat.github.io/"
+  ],
+  "sitemap_urls": [
+    "https://teco-chat.github.io/sitemap.xml"
+  ],
+  "sitemap_alternate_links": true,
+  "stop_urls": [
+    "/tests"
+  ],
+  "selectors": {
+    "lvl0": {
+      "selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
+      "type": "xpath",
+      "global": true,
+      "default_value": "Documentation"
+    },
+    "lvl1": "header h1",
+    "lvl2": "article h2",
+    "lvl3": "article h3",
+    "lvl4": "article h4",
+    "lvl5": "article h5, article td:first-child",
+    "lvl6": "article h6",
+    "text": "article p, article li, article td:last-child"
+  },
+  "strip_chars": " .,;:#",
+  "custom_settings": {
+    "separatorsToIndex": "_",
+    "attributesForFaceting": [
+      "language",
+      "version",
+      "type",
+      "docusaurus_tag"
+    ],
+    "attributesToRetrieve": [
+      "hierarchy",
+      "content",
+      "anchor",
+      "url",
+      "url_without_anchor",
+      "type"
+    ]
+  },
+  "conversation_id": [
+    "833762294"
+  ],
+  "nb_hits": 46250
+}
+
+

docker 이용하여 크롤링

+

docker와 jq가 필요하다.
+jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.

+
brew install jq
+
+

다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.

+
docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper
+
+

docusaurus 설정

+

전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.

+
themeConfig:
+  /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+  ({
+    ...
+    algolia: {
+      appId: 'MVIU5UEMOM', // Application ID
+      apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key
+      indexName: 'teco', // config.json에 설정한 인덱스명
+      contextualSearch: true,
+    },
+  })
+
+

부가 설정

+

화면 상단 Github Icon

+

파일 최하단에 아래 css 구문을 추가한다.

+
.header-github-link:hover {
+  opacity: 0.6;
+}
+
+.header-github-link:before {
+  content: '';
+  width: 24px;
+  height: 24px;
+  display: flex;
+  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
+    no-repeat;
+}
+
+html[data-theme='dark'] .header-github-link:before {
+  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
+    no-repeat;
+}
+
+

themeconfig -> navbar에 github link를 설정한다.

+
navbar: {
+  title: 'HELLO',
+  items: [
+    {
+        href: 'https://github.com/greeng00se',
+        position: 'right',
+        className: 'header-github-link',
+        'aria-label': 'GitHub repository',
+    },
+  ],
+},
+
+

코드블럭

+

java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.
+prism 설정을 아래와 같이 변경해 준다.

+
prism: {
+  theme: lightCodeTheme,
+  darkTheme: darkCodeTheme,
+  additionalLanguages: ['java', 'kotlin'],
+}
+
+

mermaid

+

mermaid를 사용하려면 @docusaurus/theme-mermaid 를 설치해야 한다.

+
yarn add @docusaurus/theme-mermaid
+
+

설치 후 아래와 같이 설정을 추가한다.

+
const config = {
+  ...
+  markdown: {
+    mermaid: true,
+  },
+  themes: [
+    '@docusaurus/theme-mermaid'
+  ],
+};
+
+

themeConfig에서 mermaid의 테마를 지정할 수 있다.

+
themeConfig:
+    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+    ({
+      ...
+      mermaid: {
+        theme: {
+          light: 'neutral', 
+          dark: 'dark'
+        },
+      },
+    }),
+
+

국제화 설정

+

국제화 설정을 한다면 Older Entries 형태의 설명이 다음 페이지 로 변경된다.
+설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.

+
i18n: {
+  defaultLocale: "ko",
+  locales: ["ko"],
+},
+
+

블로그 글 author

+

팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.

+

author

+

authors.yml 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.

+
herb:
+  name: 허브
+  title: Backend
+  url: https://github.com/greeng00se
+  image_url: https://github.com/greeng00se.png
+
+mallang:
+  name: 말랑
+  title: Backend
+  url: https://github.com/shin-mallang
+  image_url: https://github.com/shin-mallang.png
+
+

블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.

+
---
+slug: 1
+title: Hello World
+authors: [herb, mallang]
+tags: [hello, docusaurus]
+---
+
+첫 번째 문서 내용
+
\ No newline at end of file diff --git a/page/2.html b/page/2.html index 451f12fb6..c5838c58d 100644 --- a/page/2.html +++ b/page/2.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,24 +12,94 @@ - - - + + + -
-

· 약 4분

Jdbc 구현

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
-미션 목표는 다음과 같다.

  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • 데이터베이스에 대한 이해도를 높인다.

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

JdbcTemplate

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
+

· 약 4분

1단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267
+2단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358
+3단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448
+4단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515

+

Jdbc 구현

+

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
+미션 목표는 다음과 같다.

+
    +
  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • +
  • 데이터베이스에 대한 이해도를 높인다.
  • +
+

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

+

JdbcTemplate

+

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
템플릿 콜백 패턴을 적절하게 적용하여 중복을 비교적 간단하게 제거할 수 있었다.
-예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

public class JdbcTemplate {

private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);

private final DataSource dataSource;
private final StatementCreator statementCreator;
private final StatementExecutor statementExecutor;

public JdbcTemplate(final DataSource dataSource) {
this(dataSource, new StatementCreator(), new StatementExecutor());
}

JdbcTemplate(
final DataSource dataSource,
final StatementCreator statementCreator,
final StatementExecutor statementExecutor
) {
this.dataSource = dataSource;
this.statementCreator = statementCreator;
this.statementExecutor = statementExecutor;
}

private <T> T query(
final String sql,
final PreparedStatementCallback<T> preparedStatementCallback,
final Object... parameters
) {
final Connection connection = DataSourceUtils.getConnection(dataSource);
try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
return preparedStatementCallback.execute(preparedStatement);
} catch (final SQLException e) {
log.error(e.getMessage(), e);
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(connection, dataSource);
}
}

public void update(final String sql, final Object... parameters) {
query(sql, PreparedStatement::executeUpdate, parameters);
}

public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
if (results.size() > 1) {
throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
}
return results.stream().findAny();
}

public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
}
}

트랜잭션 적용

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
+예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

+
public class JdbcTemplate {
+
+    private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);
+
+    private final DataSource dataSource;
+    private final StatementCreator statementCreator;
+    private final StatementExecutor statementExecutor;
+
+    public JdbcTemplate(final DataSource dataSource) {
+        this(dataSource, new StatementCreator(), new StatementExecutor());
+    }
+
+    JdbcTemplate(
+            final DataSource dataSource,
+            final StatementCreator statementCreator,
+            final StatementExecutor statementExecutor
+    ) {
+        this.dataSource = dataSource;
+        this.statementCreator = statementCreator;
+        this.statementExecutor = statementExecutor;
+    }
+
+    private <T> T query(
+            final String sql,
+            final PreparedStatementCallback<T> preparedStatementCallback,
+            final Object... parameters
+    ) {
+        final Connection connection = DataSourceUtils.getConnection(dataSource);
+        try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
+            return preparedStatementCallback.execute(preparedStatement);
+        } catch (final SQLException e) {
+            log.error(e.getMessage(), e);
+            throw new DataAccessException(e);
+        } finally {
+            DataSourceUtils.releaseConnection(connection, dataSource);
+        }
+    }
+
+    public void update(final String sql, final Object... parameters) {
+        query(sql, PreparedStatement::executeUpdate, parameters);
+    }
+
+    public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+        if (results.size() > 1) {
+            throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
+        }
+        return results.stream().findAny();
+    }
+
+    public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+    }
+}
+
+

트랜잭션 적용

+

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
트랜잭션 동기화란 트랜잭션을 시작하기 위한 Connection 객체를 ThreadLocal과 같은 공간에 따로 저장 후, 필요할 때 저장된 Connection을 가져다 사용하는 방식이다.
-아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

마무리

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
+아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

+ +

마무리

+

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
꼼꼼히 코드를 봐준 리뷰어 호이 그리고 연휴 동안 계속 티키타카 하면서 재밌게 리뷰한 민트에게 감사하다.
회고 이만 끝내고 리팩터링 미션 하러가야겠다. 😊

- - \ No newline at end of file diff --git a/page/20.html b/page/20.html index 08c01ff4b..ce7f0043c 100644 --- a/page/20.html +++ b/page/20.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,24 +12,32 @@ - - - + + + -
-

· 약 3분

23년의 6월이 오고, 레벨 2가 끝났다.
-빠르게 지나가서 조금 아쉽다.

학습

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
+

· 약 3분

23년의 6월이 오고, 레벨 2가 끝났다.
+빠르게 지나가서 조금 아쉽다.

+

학습

+

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
항상 아쉬운 곳은 있기 마련이지만, 잘 학습한 것 같다.
-미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
-방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
-필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

수면

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
-앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

협업

레벨 2 마지막에 협업 미션이 있었다.
+미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

+

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
+방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

+

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
+필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

+

수면

+

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
+앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

+

협업

+

레벨 2 마지막에 협업 미션이 있었다.
지금까지는 백엔드 크루들과 페어 프로그래밍을 하면서 협업을 경험했다.
-이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
-팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

레벨 2를 마무리하며

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. +이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

+

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
+팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

+

레벨 2를 마무리하며

+

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. 읽고 싶은 책도 읽고, 부족한 부분 채우면서 쉬어야겠다.

- - \ No newline at end of file diff --git a/page/21.html b/page/21.html index fe9df3f22..eb181b3a2 100644 --- a/page/21.html +++ b/page/21.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,26 +12,36 @@ - - - + + + -
-

· 약 4분

레벨 인터뷰

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
+

· 약 4분

레벨 인터뷰

+

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
따라서 레벨 1 레벨 인터뷰 회고는 레벨 1 회고를 작성할 때 끼워넣었다.
이번에는 범위도 제한되어 있어 어떻게 준비해야 할지 당황했고, 답변에도 부족한 부분이 많았었다.
-기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

API 문서 도구 선택

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
+기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

+

API 문서 도구 선택

+

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
백엔드 팀원이 함께 의사결정을 했고, 미션 기간이 짧은 만큼 팀 차원에서 비교적 학습하기 쉬운 Swagger를 선택했다.
-추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
-앞으로도 학습 비용은 주요하게 고려해야 할 사항

PUT과 PATCH & 토큰과 세션

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
-토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
+추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

+

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

+
+

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
+앞으로도 학습 비용은 주요하게 고려해야 할 사항

+
+

PUT과 PATCH & 토큰과 세션

+

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
+토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

+

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
실제로 레벨 2 때 이론적인 학습 시간이 매우 적었고, 집중력도 많이 부족했다.
-앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

그 외 개선할 점

인터뷰할 때 특유의 말버릇을 개선하기
+앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

+

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

+

그 외 개선할 점

+

인터뷰할 때 특유의 말버릇을 개선하기
생각할 시간을 가졌을 때 "다시 말씀드려도 될까요?"라고 말하고 답변을 이어나가기
기술적으로 깊이가 부족하다고 생각이 많이 들어서 조금 더 깊게 공부하고 정리하기
이전에 공부했던거 되돌아 보는 시간 가지기

- - \ No newline at end of file diff --git a/page/22.html b/page/22.html index ecf6a97e4..933e11cd2 100644 --- a/page/22.html +++ b/page/22.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,31 +12,77 @@ - - - + + + -
-

· 약 5분
PR 링크

장바구니 주문 미션

배포 및 협업을 할 수 있는 미션이었다.
-마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

배포

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
+

· 약 5분

1단계: AWS 배포
+2단계: https://github.com/woowacourse/jwp-shopping-order/pull/7

+

장바구니 주문 미션

+

배포 및 협업을 할 수 있는 미션이었다.
+마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

+

배포

+

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
각자 하나의 EC2 인스턴스를 제공받을 수 있었고, 팀 별로 DB를 위한 추가 인스턴스를 제공받았다.
배포 스크립트를 작성하는 경험을 해볼 수 있었다.
-배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

echo "Start Deploy Script"
REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
PROJECT_NAME=jwp-shopping-order

echo "Change Directory"
cd $REPOSITORY_NAME

echo "Git Pull"
git pull origin step2

echo "Build"
./gradlew bootJar

echo "Copy, Start Server"
mv ./build/libs/$PROJECT_NAME.jar .

PID=$(pgrep -f $PROJECT_NAME)

if [ -n $PID ]; then
kill -9 $PID
sleep 5
fi

nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &

협업

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
+배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

+
echo "Start Deploy Script"
+REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
+PROJECT_NAME=jwp-shopping-order
+
+echo "Change Directory"
+cd $REPOSITORY_NAME
+
+echo "Git Pull"
+git pull origin step2
+
+echo "Build"
+./gradlew bootJar
+
+echo "Copy, Start Server"
+mv ./build/libs/$PROJECT_NAME.jar .
+
+PID=$(pgrep -f $PROJECT_NAME)
+
+if [ -n $PID ]; then
+        kill -9 $PID
+	sleep 5
+fi
+
+nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &
+
+

협업

+

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
백엔드가 아닌 다른 크루들과 해보는 첫 협업이라 약간 두근거렸다.
-예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

부족했던 부분

여러가지 방법에 대한 장단점을 고려해보기

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
+예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

+

부족했던 부분

+

여러가지 방법에 대한 장단점을 고려해보기

+

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
조금 더 시간을 많이 들여서 장단점을 고려했다면 더 좋은 결과물이 나오지 않았을까?
-앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

새로 배운 부분

expose headers

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
-기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
+앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

+

새로 배운 부분

+

expose headers

+

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
+기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
이를 expose headers 설정을 통해 해결할 수 있었다.
-nginx 설정에 다음과 같이 추가해 주었다.

add_header 'Access-Control-Expose-Headers' 'Location'

읽기 전용 트랜잭션

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
+nginx 설정에 다음과 같이 추가해 주었다.

+
add_header 'Access-Control-Expose-Headers' 'Location'
+
+

읽기 전용 트랜잭션

+

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
이번에 코멘트가 달려서 조금 더 자세히 공부해 보기로 했다.
-Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
-추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

DAO에 @Transactional 적용

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
+Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

+

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

+
    +
  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • +
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.
  • +
+

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
+추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

+

DAO에 @Transactional 적용

+

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
Service 계층에 이미 트랜잭션을 보장해 주고 있기에 필요 없지 않을까 생각했었다.
DAO를 다른 곳에서 사용하더라도 트랜잭션을 보장하기 위해(확장성 고려) @Transactional을 적용하는 것도 괜찮은 것 같다.

- - \ No newline at end of file diff --git a/page/23.html b/page/23.html index 22f1c7479..3031f88b7 100644 --- a/page/23.html +++ b/page/23.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,27 +12,40 @@ - - - + + + -
-

· 약 5분

개요

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
-레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

나의 채팅 확인하고 이어하는 기능

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
-예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

chat1

좋아요와 댓글 기능

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
+

· 약 5분

개요

+

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
+레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

+

나의 채팅 확인하고 이어하는 기능

+

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
+예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

+

chat1

+

좋아요와 댓글 기능

+

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
누가 좋아요를 눌렀는지, 어떤 채팅이 좋아요를 가장 많이 받았는지 확인할 수 있는 기능을 추가했다.
-또한 댓글 추가 및 삭제 기능도 추가했다.

키워드 추출

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
+또한 댓글 추가 및 삭제 기능도 추가했다.

+

키워드 추출

+

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
해당 부분은 첫 질문에 대한 키워드만 추출하도록 했다.
백엔드에선 말랑이 이벤트 이용해서 첫 채팅 요청이 이루어지면, 비동기로 키워드를 추출하는 질문을 추가로 날리도록 구현하였다.
-CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

chat2

다른 크루의 채팅 복사해서 이어하는 기능

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
-채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

사용성 고려하기

chat3

위 화면은 회원가입 창이다.
+CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

+

chat2

+

다른 크루의 채팅 복사해서 이어하는 기능

+

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
+채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

+

사용성 고려하기

+

chat3

+

위 화면은 회원가입 창이다.
사실 가장 마음에 드는 부분이고, 회원가입(닉네임만 입력하지만)할 때 익명을 원하는 사람들의 고민을 도와주게 끔 음식, 과일, 과자 등의 요소들을 입력하도록 유도했다! 추가로 GPT의 답변이 오면 자동으로 화면을 스크롤 해주는 것과 같이 사용성을 개선해 보려고 노력했지만 쉽지 않았다.
-제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

향후 계획

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
+제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

+

향후 계획

+

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
크루들이 직접 사용해 주니까 너무 고맙고, 한편으로는 신기하다.
일단 방학 때 stream/text 관련된 부분 동작되도록 구현해보려고 하고, 그 외의 부분은 조금 더 고민해야될 것 같다.

- - \ No newline at end of file diff --git a/page/24.html b/page/24.html index 797b5e7d6..b3680fe6b 100644 --- a/page/24.html +++ b/page/24.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,26 +12,110 @@ - - - + + + -
-

· 약 5분

요구사항

지하철 미션에는 다음과 같은 요구사항이 있었다.

  • 거리별 추가 요금 정책
  • 노선별 추가 요금 정책
  • 연령별 요금 할인 정책

인터페이스 사용

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
-요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

public interface FarePolicy {
int calculate(Path path, Passenger passenger, int fare);
}

public class BaseFarePolicy implements FarePolicy { ... }
public class DistanceFarePolicy implements FarePolicy { ... }
public class AgeDiscountFarePolicy implements FarePolicy { ... }

composite1

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
-이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

public class SubwayFarePolicy implements FarePolicy {

private final List<FarePolicy> farePolicies;

public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
this.farePolicies = farePolicies;
}

@Override
public int calculate(final Path path, final Passenger passenger, final int fare) {
int calculatedFare = fare;
for (FarePolicy farePolicy : farePolicies) {
calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
}
return calculatedFare;
}
}

따라서 그림으로 본다면 다음과 같은 구조가 된다.

composite2

정책의 순서

지하철 요구사항은 순서가 중요했다.
+

· 약 5분

요구사항

+

지하철 미션에는 다음과 같은 요구사항이 있었다.

+
    +
  • 거리별 추가 요금 정책
  • +
  • 노선별 추가 요금 정책
  • +
  • 연령별 요금 할인 정책
  • +
+

인터페이스 사용

+

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
+요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

+
public interface FarePolicy {
+    int calculate(Path path, Passenger passenger, int fare);
+}
+
+public class BaseFarePolicy implements FarePolicy { ... }
+public class DistanceFarePolicy implements FarePolicy { ... }
+public class AgeDiscountFarePolicy implements FarePolicy { ... }
+
+

composite1

+

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

+

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
+이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

+
public class SubwayFarePolicy implements FarePolicy {
+
+    private final List<FarePolicy> farePolicies;
+
+    public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
+        this.farePolicies = farePolicies;
+    }
+
+    @Override
+    public int calculate(final Path path, final Passenger passenger, final int fare) {
+        int calculatedFare = fare;
+        for (FarePolicy farePolicy : farePolicies) {
+            calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
+        }
+        return calculatedFare;
+    }
+}
+
+

따라서 그림으로 본다면 다음과 같은 구조가 된다.

+

composite2

+

정책의 순서

+

지하철 요구사항은 순서가 중요했다.
금액의 총합을 구하고, 그 후에 할인 정책이 들어가야했다.
따라서 자식들의 순서를 관리할 때 주의를 기울여야 했다.
-Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

@Configuration
public class FareConfiguration {

@Bean
public FarePolicy farePolicy() {
return new SubwayFarePolicy(List.of(
new BaseFarePolicy(),
new DistanceFarePolicy(),
new AgeDiscountFarePolicy()
));
}
}

컴포지트 패턴이란?

composite3

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
-사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

컴포지트 패턴의 구성요소

Component

  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • ex) 요금 정책(FarePolicy)

Leaf

  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • ex) 거리 별 요금 정책(DistanceFarePolicy)

Composite

  • 여러 개의 개발 객체를 포함하는 합성 객체
  • ex) 지하철 요금 정책(SubwayFarePolicy)

Client

  • 인터페이스를 사용하는 클라이언트

컴포지트 패턴의 사용과 주요 목표

부분 - 전체의 관계를 표현하고 싶을 때
-Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

패턴 사용시 주의해야할 부분

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
+Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

+
@Configuration
+public class FareConfiguration {
+
+    @Bean
+    public FarePolicy farePolicy() {
+        return new SubwayFarePolicy(List.of(
+                new BaseFarePolicy(),
+                new DistanceFarePolicy(),
+                new AgeDiscountFarePolicy()
+        ));
+    }
+}
+
+

컴포지트 패턴이란?

+

composite3

+

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

+
+

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
+사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

+
+

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
+이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

+

컴포지트 패턴의 구성요소

+

Component

+
    +
  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • +
  • ex) 요금 정책(FarePolicy)
  • +
+

Leaf

+
    +
  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • +
  • ex) 거리 별 요금 정책(DistanceFarePolicy)
  • +
+

Composite

+
    +
  • 여러 개의 개발 객체를 포함하는 합성 객체
  • +
  • ex) 지하철 요금 정책(SubwayFarePolicy)
  • +
+

Client

+
    +
  • 인터페이스를 사용하는 클라이언트
  • +
+

컴포지트 패턴의 사용과 주요 목표

+

부분 - 전체의 관계를 표현하고 싶을 때
+Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

+

패턴 사용시 주의해야할 부분

+

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
반복되는 문제를 효율적으로 해결할 수 있지만 패턴에 매몰되서는 안된다.
패턴을 맹목적으로 사용해서는 안되고, 현재의 요구사항에 따라 패턴을 유동적으로 수정해가면서 적용하는 것이 좋다.
-항상 트레이드오프를 생각하자!

참고 자료

컴포지트 패턴, GoF의 디자인 패턴
+항상 트레이드오프를 생각하자!

+

참고 자료

+

컴포지트 패턴, GoF의 디자인 패턴
디자인 패턴과 프레임워크, 오브젝트

- - \ No newline at end of file diff --git a/page/25.html b/page/25.html index 3ff8ba6b5..d12c565eb 100644 --- a/page/25.html +++ b/page/25.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,35 +12,86 @@ - - - + + + -
-

· 약 8분

지하철 미션

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
+

· 약 8분

1단계: https://github.com/woowacourse/jwp-subway-path/pull/16
+2, 3단계: https://github.com/woowacourse/jwp-subway-path/pull/126

+

지하철 미션

+

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
지하철 미션은 밀리랑 페어를 진행했다.
간단한 CRUD만 있던 이전 미션들과 달리, 조금 복잡한 도메인 요구사항이 있었다.
이때 API, 테이블, 도메인 설계를 해야 했는데 어떤 것부터 해야 할지 고민을 많이 했다.
-API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

노선의 구간 추가 및 삭제

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. 변경된 요소만 데이터베이스에 반영하는 방법

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
-추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

부족했던 부분

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
+API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

+

노선의 구간 추가 및 삭제

+

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

+
    +
  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. +
  3. 변경된 요소만 데이터베이스에 반영하는 방법
  4. +
+

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
+추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

+

부족했던 부분

+

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
우아한테크코스를 진행하면서 알아야 하는 게 많아지면서 가끔 조바심을 가질 때가 있는 것 같은데, 조바심을 경계할 필요가 있을 것 같다.
-부족한 부분은 인정하고, 앞으로 나아가야겠다.

새로 학습한 부분

컴포지트 패턴으로 요금 정책 추상화

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
+부족한 부분은 인정하고, 앞으로 나아가야겠다.

+

새로 학습한 부분

+

컴포지트 패턴으로 요금 정책 추상화

+

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
요금을 더하는 부분과, 할인하는 부분이 있어서 이 둘을 분리할까 생각했지만, 이 정도 크기의 애플리케이션에서는 오히려 분리하지 않고 하나로 합치는 게 더 좋다고 생각했다.
-또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

도메인에 특정 기술의 의존성을 분리

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
+또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

+

도메인에 특정 기술의 의존성을 분리

+

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
따라서 도메인 패키지 내에는 경로 검색에 대한 인터페이스를 두고, 세부 구현은 도메인 패키지 외부로 분리했다.
-최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

컴포지트 패턴

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

인수 테스트 작성

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
+최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

+

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
+이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

+

인수 테스트 작성

+

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
브라운이 해주신 강의 + 유튜브에 있는 브라운의 강의를 보고 지하철 미션에 인수 테스트를 적용해 보았다.
메서드, 변수명을 전부 한글로 작성했는데 전체적인 흐름을 알기 편하고 읽기도 좋았다.
-그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

결과는 아래와 같다.

@Nested
public class 노선을_전체_조회할_때 {

@Test
void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
// given
노선_생성_요청("2호선", "초록", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);

노선_생성_요청("9호선", "고동", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);

// when
final var 조회_결과 = 노선_전체_조회_요청();

// then
요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
노선_전체_조회_결과를_확인한다(
조회_결과,
노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
);
}
}

페어에게 배울 부분

의견 조율하기

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
-의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

꼼꼼하게 코딩하기

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
+그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

+

결과는 아래와 같다.

+
@Nested
+public class 노선을_전체_조회할_때 {
+
+    @Test
+    void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
+        // given
+        노선_생성_요청("2호선", "초록", 0);
+        노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
+        구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);
+
+        노선_생성_요청("9호선", "고동", 0);
+        노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
+        구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);
+
+        // when
+        final var 조회_결과 = 노선_전체_조회_요청();
+
+        // then
+        요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
+        노선_전체_조회_결과를_확인한다(
+                조회_결과,
+                노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
+                노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
+        );
+    }
+}
+
+

페어에게 배울 부분

+

의견 조율하기

+

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
+의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

+

꼼꼼하게 코딩하기

+

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
변수명, 메서드명을 중요하게 생각했고, 좋은 변수명을 잘 짓는 것 같다.
-또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

편한 분위기

전체적으로 페어 할 때 편하게 진행했던 것 같다.
+또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

+

편한 분위기

+

전체적으로 페어 할 때 편하게 진행했던 것 같다.
일정도 그렇고, 페어 진행할 때도 그렇고 큰 문제가 없었던 것 같아서 좋았다.
나는 과연 다른 사람들에게 편한 사람일까?

- - \ No newline at end of file diff --git a/page/26.html b/page/26.html index 6932db416..744361db6 100644 --- a/page/26.html +++ b/page/26.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,27 +12,142 @@ - - - + + + -
-

· 약 8분

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.
-요청에 담긴 Body를 통해 전달받은 값을 DTO로 매핑하여 추가와 수정을 했다.

장바구니 미션에서의 상품 추가 및 수정

중복1

클래스명을 제외하고 필드와 검증로직 그 외 모든게 같은 DTO를 보며 중복이라고 생각했다.
+

· 약 8분

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.
+요청에 담긴 Body를 통해 전달받은 값을 DTO로 매핑하여 추가와 수정을 했다.

+

장바구니 미션에서의 상품 추가 및 수정

+

중복1

+

클래스명을 제외하고 필드와 검증로직 그 외 모든게 같은 DTO를 보며 중복이라고 생각했다.
하지만 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-위 경우는 중복일까? 중복이 아닐까?

이 부분에 대해서 다음과 같은 리뷰를 받았다.

ProductSaveRequestProductUpdateRequest가 완전히 동일한데, 재사용할 수 없을까? 라는 리뷰를 남겼었어요. 사실 생성과 수정은 서로 달라질 개연성이 높아서 미리 분리해놓는 게 더 좋은 방법이긴 한데, 그래도 중복은 싫어서 저도 요즘 이런저런 방법들을 시도해보는 중 입니다. 허브는 이 부분에 대해 어떤 생각을 가지고 있을지 궁금하네요 ㅎㅎ

질문에 대해 아래와 같이 답변을 했다.

저장과 수정할 때 필요한 필드값이 동일하여 현재 구조에서는 하나로 사용해도 된다고 생각을 하지만, 말씀해주신대로 요구사항이 변경된다면 달라질 가능성이 높다고 판단하였습니다!

중복과 우발적 중복

로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 거짓된 중복, 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다. -그렇기 때문에 위 상황은 우발적 중복으로 보인다. 그래도 중복을 제거해볼 수 있지 않을까?

하나로 사용하는 건 안좋아보이고, 중복은 제거하고 싶은 마음

지금은 추가, 수정 2가지 경우 밖에 없지만 조금 더 복잡한 요구사항이 주어져서 10가지 경우로 입력을 받으면 어떻게 해야할까?
+위 경우는 중복일까? 중복이 아닐까?

+

이 부분에 대해서 다음과 같은 리뷰를 받았다.

+
+

ProductSaveRequestProductUpdateRequest가 완전히 동일한데, 재사용할 수 없을까? 라는 리뷰를 남겼었어요. 사실 생성과 수정은 서로 달라질 개연성이 높아서 미리 분리해놓는 게 더 좋은 방법이긴 한데, 그래도 중복은 싫어서 저도 요즘 이런저런 방법들을 시도해보는 중 입니다. 허브는 이 부분에 대해 어떤 생각을 가지고 있을지 궁금하네요 ㅎㅎ

+
+

질문에 대해 아래와 같이 답변을 했다.

+
+

저장과 수정할 때 필요한 필드값이 동일하여 현재 구조에서는 하나로 사용해도 된다고 생각을 하지만, 말씀해주신대로 요구사항이 변경된다면 달라질 가능성이 높다고 판단하였습니다!

+
+

중복과 우발적 중복

+

로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러가지 종류로 나누어 설명하고 있다.

+
    +
  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • +
  • 거짓된 중복, 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.
  • +
+

추가와 수정은 초기에는 중복으로 보이지만 초기 생성시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다. +그렇기 때문에 위 상황은 우발적 중복으로 보인다. 그래도 중복을 제거해볼 수 있지 않을까?

+

하나로 사용하는 건 안좋아보이고, 중복은 제거하고 싶은 마음

+

지금은 추가, 수정 2가지 경우 밖에 없지만 조금 더 복잡한 요구사항이 주어져서 10가지 경우로 입력을 받으면 어떻게 해야할까?
서비스 계층에서도 계층의 분리를 위해서 다른 DTO를 사용하고 있다면 20개의 DTO를 만들어야 할까?
-리뷰어가 알려준 의존 역전을 이용한 방법을 통해 이를 해결해보자!

중복 제거 전 코드

현재 코드에서는 아래와 같은 구조로 되어있다.
+리뷰어가 알려준 의존 역전을 이용한 방법을 통해 이를 해결해보자!

+

중복 제거 전 코드

+

현재 코드에서는 아래와 같은 구조로 되어있다.
Controller와 Service에서 저장, 수정할 때 각각의 DTO를 사용하고 있다. -현재 DTO는 controller, service 패키지 내에 있는 것이 아니라 dto라는 패키지에 위치하고 있다.

├── controller
│   └── ProductController
├── service
│   └── ProductService
├── dto
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest

중복2

인터페이스 작성하기

중복3

서비스 레이어에서 필요로 하는 값들을 인터페이스로 정의한다.
-해당 인터페이스는 서비스에서 사용하기 때문에 service 패키지 내부로 옮겨준다.

├── controller
│   └── ProductController
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public interface ProductSaveRequest {

String getName();

String getImage();

Long getPrice();
}

// ProductService
public Long save(final ProductSaveRequest request) {
final Product product = new Product(request.getName(), request.getImage(), request.getPrice());
return productDao.saveAndGetId(product);
}

구현체 작성하기

중복4

위에서 작성한 인터페이스를 구현하는 클래스를 작성한다.
-요청은 ProductRequest 클래스로 받고, 서비스에 전달할 땐 해당 인터페이스의 명세만 맞추면 문제없이 사용할 수 있다.

├── controller
│   ├── ProductController
│   └── ProductRequest
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {

@NotBlank(message = "이름은 공백일 수 없습니다.")
@Size(min = 1, max = 100, message = "이름은 최소 {min}자 이상, {max}자 이하여야 합니다.")
private final String name;

@NotBlank(message = "이미지는 공백일 수 없습니다.")
private final String image;

@Range(message = "가격은 최소 {min}원 이상, {max}원 이하여야 합니다.")
private final long price;

public ProductRequest(final String name, final String image, final long price) {
this.name = name;
this.image = image;
this.price = price;
}

@Override
public String getName() {
return name;
}

@Override
public String getImage() {
return image;
}

@Override
public long getPrice() {
return price;
}
}

// ProductController
@PostMapping("/products")
public ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {
final Long id = productService.save(request);
return ResponseEntity.created(URI.create("/products/" + id)).build();
}

정리

위와 같이 구현한다면 다음과 같은 장점을 얻을 수 있다.

  1. Service에서 모든 클라이언트 요청에 대한 DTO를 알지 않아도 된다.
  2. 공통적으로 사용하는 DTO를 제외하고 DTO 패키지에 대한 결합도가 낮아지고, 각 레이어의 응집도가 증가한다.
  3. 요청 객체만 다르고 서비스에서 동일한 행위를 수행하는 경우 중복을 제거할 수 있다.

위 방법을 지금 미션에서 바로 적용할까 하다가, 나중에 필요할 때 적용하면 더 좋을 것 같아서 미션에는 적용하지 않았다.
-상황에 맞춰 적재적소에 의존 역전을 이용해보는 것도 좋을 것 같다.

참고 자료

클린 아키텍처 16장 독립성, 로버트 C. 마틴
-https://techblog.woowahan.com/2647/
-https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/

- - +현재 DTO는 controller, service 패키지 내에 있는 것이 아니라 dto라는 패키지에 위치하고 있다.

+
├── controller
+│   └── ProductController
+├── service
+│   └── ProductService
+├── dto
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+

중복2

+

인터페이스 작성하기

+

중복3

+

서비스 레이어에서 필요로 하는 값들을 인터페이스로 정의한다.
+해당 인터페이스는 서비스에서 사용하기 때문에 service 패키지 내부로 옮겨준다.

+
├── controller
+│   └── ProductController
+├── service
+│   ├── ProductService
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+
public interface ProductSaveRequest {
+
+    String getName();
+
+    String getImage();
+
+    Long getPrice();
+}
+
+// ProductService
+public Long save(final ProductSaveRequest request) {
+    final Product product = new Product(request.getName(), request.getImage(), request.getPrice());
+    return productDao.saveAndGetId(product);
+}
+
+

구현체 작성하기

+

중복4

+

위에서 작성한 인터페이스를 구현하는 클래스를 작성한다.
+요청은 ProductRequest 클래스로 받고, 서비스에 전달할 땐 해당 인터페이스의 명세만 맞추면 문제없이 사용할 수 있다.

+
├── controller
+│   ├── ProductController
+│   └── ProductRequest
+├── service
+│   ├── ProductService
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+
public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {
+
+    @NotBlank(message = "이름은 공백일 수 없습니다.")
+    @Size(min = 1, max = 100, message = "이름은 최소 {min}자 이상, {max}자 이하여야 합니다.")
+    private final String name;
+
+    @NotBlank(message = "이미지는 공백일 수 없습니다.")
+    private final String image;
+
+    @Range(message = "가격은 최소 {min}원 이상, {max}원 이하여야 합니다.")
+    private final long price;
+
+    public ProductRequest(final String name, final String image, final long price) {
+        this.name = name;
+        this.image = image;
+        this.price = price;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getImage() {
+        return image;
+    }
+
+    @Override
+    public long getPrice() {
+        return price;
+    }
+}
+
+// ProductController
+@PostMapping("/products")
+public ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {
+    final Long id = productService.save(request);
+    return ResponseEntity.created(URI.create("/products/" + id)).build();
+}
+
+

정리

+

위와 같이 구현한다면 다음과 같은 장점을 얻을 수 있다.

+
    +
  1. Service에서 모든 클라이언트 요청에 대한 DTO를 알지 않아도 된다.
  2. +
  3. 공통적으로 사용하는 DTO를 제외하고 DTO 패키지에 대한 결합도가 낮아지고, 각 레이어의 응집도가 증가한다.
  4. +
  5. 요청 객체만 다르고 서비스에서 동일한 행위를 수행하는 경우 중복을 제거할 수 있다.
  6. +
+

위 방법을 지금 미션에서 바로 적용할까 하다가, 나중에 필요할 때 적용하면 더 좋을 것 같아서 미션에는 적용하지 않았다.
+상황에 맞춰 적재적소에 의존 역전을 이용해보는 것도 좋을 것 같다.

+

참고 자료

+

클린 아키텍처 16장 독립성, 로버트 C. 마틴
+https://techblog.woowahan.com/2647/
+https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/

\ No newline at end of file diff --git a/page/27.html b/page/27.html index b1d957943..d7ed635a3 100644 --- a/page/27.html +++ b/page/27.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,28 +12,47 @@ - - - + + + -
-

· 약 5분

웹 장바구니 미션

장바구니 미션은 블랙캣이랑 진행했다.
+

· 약 5분

1단계: https://github.com/woowacourse/jwp-shopping-cart/pull/244
+2단계: https://github.com/woowacourse/jwp-shopping-cart/pull/300

+

웹 장바구니 미션

+

장바구니 미션은 블랙캣이랑 진행했다.
요구사항이 엄청 복잡한 미션은 아니었고, 스프링을 사용하여 기본적인 CRUD를 구현하는 미션이었다.
2단계에서는 Basic 인증을 통해 자신의 장바구니에만 상품을 담고, 제거할 수 있도록 구현하는 요구사항이 추가되었다.
Interceptor나 Argument Resolver에 대한 이해도가 높지 않았는데, 이번 미션을 통해 조금 더 알아간 느낌이다.
-이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

새로 학습한 부분

DTO 우발적 중복

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

dto1

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
-따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

dto2

Interceptor에서 인증한 값 재사용

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
-일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
+이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

+

새로 학습한 부분

+

DTO 우발적 중복

+

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

+

dto1

+

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
+로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

+
    +
  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • +
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.
  • +
+

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
+따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

+

dto2

+

Interceptor에서 인증한 값 재사용

+

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
+일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

+

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
웨지는 email에 index를 걸어두고 dao 재조회를 사용할 것이라고 했다.
-재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

페어에게 배울 부분

기록

블랙캣은 기록을 굉장히 잘 하는 크루였다.
+재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

+

페어에게 배울 부분

+

기록

+

블랙캣은 기록을 굉장히 잘 하는 크루였다.
노션에 페어를 진행하면서 했던 내용 + 고민했던 부분 + 회고를 꼼꼼하게 기록해서 공유해 주었다.
-추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

의견 일치시키기

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
+추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

+

의견 일치시키기

+

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
따라서 적당히 타협을 봐서 의견을 빠르게 수용해 데드라인을 맞추는 것도 중요하다고 생각한다.
-블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

- - +블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

+

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

\ No newline at end of file diff --git a/page/28.html b/page/28.html index dcc91b326..332aed923 100644 --- a/page/28.html +++ b/page/28.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,33 +12,50 @@ - - - + + + -
-

· 약 4분

웹 자동차 미션

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
+

· 약 4분

1단계: https://github.com/woowacourse/jwp-racingcar/pull/24
+2단계: https://github.com/woowacourse/jwp-racingcar/pull/128

+

웹 자동차 미션

+

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
웹 자동차 미션에서는 비버와 페어가 매칭되었다.
-레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
+레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

+

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
첫 미션이라 그런지 특별한 부분은 없었고, 최대한 깔끔하게 작성하려고 노력했다.
난이도 높은 미션이 아니었지만 리뷰어인 라빈에게 칭찬을 많이 받아서 기분이 좋았다.
-라빈 감사합니다!

부족했던 부분

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
+라빈 감사합니다!

+

부족했던 부분

+

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
미션이 다소 여유롭다고 느껴져서, 시간에 대한 부분도 잘 관리하지 못한 것 같다.
-미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
+미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

+

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
도전적이지 않거나 시간이 부족하지 않으면 집중을 잘 못하는 것 같다.
-머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

새로 학습한 부분

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@Transactional
@AutoConfigureMockMvc
@SpringBootTest
public class RacingGameIntegrationTest {

페어에게 배울 부분

비버의 성격
+머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

+

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

+

새로 학습한 부분

+

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

+
@SuppressWarnings("NonAsciiCharacters")
+@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
+@Transactional
+@AutoConfigureMockMvc
+@SpringBootTest
+public class RacingGameIntegrationTest {
+
+

페어에게 배울 부분

+

비버의 성격
비버가 성격이 좋아서 편하게 페어를 할 수 있었다.
-미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

미션에 집중하는 부분
+미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

+

미션에 집중하는 부분
내가 미션에 잘 집중하지 못했는데도 같이 페어를 잘 진행한 것 같아서 좋았다.
비버가 미션에 잘 집중해서 그렇지 않았나 생각했다.
근육맨 비버라 그런지 체력이 좋아서 그런가?
-중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

학습에 대한 열정
+중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

+

학습에 대한 열정
추가적으로 알고 싶은 부분을 따로 학습하는 열정이 좋다고 생각했다.
비버와 스프링에 대해 알아가는 시간을 많이 가진 부분이 매우 좋았다.
나도 5월부터 조금 더 화이팅 해야겠다.

- - \ No newline at end of file diff --git a/page/29.html b/page/29.html index 495609614..917120565 100644 --- a/page/29.html +++ b/page/29.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,32 +12,55 @@ - - - + + + -
-

· 약 5분

프론트엔트

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
+

· 약 5분

프론트엔트

+

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
추가로 채팅을 이어나갈 수 있게 하는 기능도 추가했다.
자잘하게 신경 쓸 부분이 많아서, 프론트엔드 하는 사람들이 대단하다고 생각되었다.
-여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

백엔드

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
+여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

+

백엔드

+

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
말랑이 한 부분이 너무 많아서 내가 못 따라가는 것 같다.
-나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

Http Request Header

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
+나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

+

Http Request Header

+

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
말랑이 한글은 안된다고 말해줘서 Base64로 인코딩하고, 백엔드에서 디코딩 하여 사용하기로 했다.
-아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

const encodedName = () => {
const uriComponent = unescape(encodeURIComponent(name.value));
return btoa(uriComponent);
};

Elastic Beanstalk

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
+아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

+
const encodedName = () => {
+  const uriComponent = unescape(encodeURIComponent(name.value));
+  return btoa(uriComponent);
+};
+
+

Elastic Beanstalk

+

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
Elastic Beanstalk를 사용하면 인프라에 대해 잘 알지 못해도 애플리케이션을 빠르게 배포하고 관리할 수 있다.
-모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

Elastic Beanstalk RDS 설정 후 분리

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
+모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

+

Elastic Beanstalk RDS 설정 후 분리

+

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
RDS 분리 시 Beanstalk에 기본적으로 설정되어 있는 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD와 같은 환경 변수가 같이 제거된다.
-추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

Elastic Beanstalk nginx 설정

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

Jenkins

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
+추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

+

Elastic Beanstalk nginx 설정

+

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

+

Jenkins

+

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
작년에 확인했을 땐 2022년 12월 31일까지 EC2 ARM 기반 t4g.small이 무료였는데, 다시 들어가 보니 2023년까지 12월 31일까지 t4g.small을 무료로 사용할 수 있었다.
t4g.small은 램이 2G인데, 예전에는 부족하지 않았다고 생각했는데 Java 17을 써서 그런가 빌드 할 때 램이 많이 부족한 것 같아서 Swap 메모리 2기가를 추가로 설정했다.
-추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

test {
maxHeapSize = "1024m"
}

Jenkins Blue Ocean

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
+추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

+
test {
+    maxHeapSize = "1024m"
+}
+
+

Jenkins Blue Ocean

+

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
시각화도 잘 되어있고, 설정도 편리한 것 같다.
-오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

참고 자료

Elastic Beanstalk, AWS
-EC2 AWS Graviton, AWS
-Default Memory Settings, AWS

- - +오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

+

참고 자료

+

Elastic Beanstalk, AWS
+EC2 AWS Graviton, AWS
+Default Memory Settings, AWS

\ No newline at end of file diff --git a/page/3.html b/page/3.html index ed4b15837..ff2d2be69 100644 --- a/page/3.html +++ b/page/3.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,25 +12,96 @@ - - - + + + -
-

· 약 6분

MVC 구현

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
-미션의 목표는 다음과 같았다.

  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • 점진적인 리팩토링을 경험한다.

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

애너테이션 기반 프레임워크 만들기

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
+

· 약 6분

1단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/404
+2단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/465
+3단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/580

+

MVC 구현

+

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
+미션의 목표는 다음과 같았다.

+
    +
  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • +
  • 점진적인 리팩토링을 경험한다.
  • +
+

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

+

애너테이션 기반 프레임워크 만들기

+

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
테오가 @GetMapping이나 @PostMapping 부분도 진행하면 재밌을 것 같다고 해서 같이 진행해 보았다.
-추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  3. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

AnnotationHandlerMapping
public void initialize() {
if (!initialized.compareAndSet(false, true)) {
return;
}

final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
for (final Method method : methods) {
final ControllerInstance controller = controllers.get(method.getDeclaringClass());
final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
}

log.info("Initialized AnnotationHandlerMapping!");
handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
}

Legacy MVC와 @MVC 통합

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
+추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

+ +

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

+
    +
  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. +
  3. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  4. +
  5. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.
  6. +
+

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

+
public void initialize() {
+    if (!initialized.compareAndSet(false, true)) {
+        return;
+    }
+
+    final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
+    final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
+    for (final Method method : methods) {
+        final ControllerInstance controller = controllers.get(method.getDeclaringClass());
+        final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
+        final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
+        handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
+    }
+
+    log.info("Initialized AnnotationHandlerMapping!");
+    handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
+}
+
+

Legacy MVC와 @MVC 통합

+

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
기존의 MVC와 애너테이션이 적용된 MVC 두 개를 같이 사용할 수 있어야 헀다.
-대략적인 흐름은 다음과 같다.

  1. DispatcherServlet.service(request, response) 호출
  2. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  3. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  4. HandlerAdapter의.handle 메서드 실행
  5. View의 render 호출

웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
-간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

내용이 길어져서 다음 문서에 정리했다.

추상적인 개념 학습 방법

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory

정리

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
+대략적인 흐름은 다음과 같다.

+
    +
  1. DispatcherServlet.service(request, response) 호출
  2. +
  3. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  4. +
  5. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  6. +
  7. HandlerAdapter의.handle 메서드 실행
  8. +
  9. View의 render 호출
  10. +
+ +

웹 애플리케이션 발전 과정

+

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

+ +

내용이 길어져서 다음 문서에 정리했다.

+

추상적인 개념 학습 방법

+

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

+
개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory
+

정리

+

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
이번 미션에서 나의 리뷰어는 루카, 리뷰이는 헤나였다.
매 단계마다 꼼꼼하게 리뷰해 준 루카에게 너무 감사하고, 헤나에게 이상한 리뷰를 많이 남긴 것 같은데 꼼꼼히 반영해줘서 감사하다.
오랫동안 기다려왔던 레벨 4 미션이 하나씩 마무리 될 때 마다 아쉬움이 남는다.

- - \ No newline at end of file diff --git a/page/30.html b/page/30.html index 9e59e5221..2d851c607 100644 --- a/page/30.html +++ b/page/30.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,31 +12,218 @@ - - - + + + -
-

· 약 8분

설정 환경

소프트웨어 이미지: Amazon Linux 2023 AMI
+

· 약 8분

설정 환경

+

소프트웨어 이미지: Amazon Linux 2023 AMI
아키텍쳐: ARM
인스턴스 유형: t4g.small
환경 구성이 완료된 Elastic Beanstalk
-단일 Spring Boot 프로젝트가 존재하는 Github Repository

[EC2 CLI] Swap 메모리 설정

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
-아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

# fallocate 이용하여 스왑 파일 생성
sudo fallocate -l 2G /swapfile

# 권한 설정
sudo chmod 600 /swapfile

# 파일을 Swap 포맷으로 변경 후 시스템에 등록
sudo mkswap /swapfile
sudo swapon /swapfile

# Swap 메모리 부팅시 자동으로 마운트하도록 적용
# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
sudo vim /etc/fstab

[EC2 CLI] jenkins 설치

sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install java-17-amazon-corretto-devel
sudo yum install jenkins
sudo systemctl daemon-reload

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

[EC2 CLI] Jenkins 시작

sudo systemctl enable jenkins
sudo systemctl start jenkins

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

[EC2 CLI] nginx & git 설치

sudo yum install nginx
sudo systemctl enable nginx
sudo systemctl start nginx

sudo yum install git

nginx와 코드를 불러올 때 사용할 git을 설치한다.

[EC2 CLI] nginx 리버스 프록시 설정

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

upstream jenkins {
keepalive 32; # keepalive connections
server 127.0.0.1:8080; # jenkins ip and port
}

# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 80; # Listen on port 80 for IPv4 requests

server_name jenkins.example.com; # replace 'jenkins.example.com' with your server domain name

# this is the jenkins web root directory
# (mentioned in the output of "systemctl cat jenkins")
root /var/run/jenkins/war/;

access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;

# pass through headers from Jenkins that Nginx considers invalid
ignore_invalid_headers off;

location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
# rewrite all static files into requests to the root
# E.g /static/12345678/css/something.css will become /css/something.css
rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
}

location /userContent {
# have nginx handle all the static requests to userContent folder
# note : This is the $JENKINS_HOME dir
root /var/lib/jenkins/;
if (!-f $request_filename){
# this file does not exist, might be a directory or a /**view** url
rewrite (.*) /$1 last;
break;
}
sendfile on;
}

location / {
sendfile off;
proxy_pass http://jenkins;
proxy_redirect default;
proxy_http_version 1.1;

# Required for Jenkins websocket agents
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_max_temp_file_size 0;

#this is the maximum upload size
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffering off;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection ""; # Clear for keepalive
}

}

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
+단일 Spring Boot 프로젝트가 존재하는 Github Repository

+

[EC2 CLI] Swap 메모리 설정

+

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
+아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

+
# fallocate 이용하여 스왑 파일 생성
+sudo fallocate -l 2G /swapfile
+
+# 권한 설정
+sudo chmod 600 /swapfile
+
+# 파일을 Swap 포맷으로 변경 후 시스템에 등록
+sudo mkswap /swapfile
+sudo swapon /swapfile
+
+# Swap 메모리 부팅시 자동으로 마운트하도록 적용
+# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
+sudo vim /etc/fstab
+
+

[EC2 CLI] jenkins 설치

+
sudo wget -O /etc/yum.repos.d/jenkins.repo \
+    https://pkg.jenkins.io/redhat-stable/jenkins.repo
+sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
+sudo yum upgrade
+sudo yum install java-17-amazon-corretto-devel
+sudo yum install jenkins
+sudo systemctl daemon-reload
+
+

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

+

[EC2 CLI] Jenkins 시작

+
sudo systemctl enable jenkins
+sudo systemctl start jenkins
+
+

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

+

[EC2 CLI] nginx & git 설치

+
sudo yum install nginx
+sudo systemctl enable nginx
+sudo systemctl start nginx
+
+sudo yum install git
+
+

nginx와 코드를 불러올 때 사용할 git을 설치한다.

+

[EC2 CLI] nginx 리버스 프록시 설정

+

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

+
upstream jenkins {
+  keepalive 32; # keepalive connections
+  server 127.0.0.1:8080; # jenkins ip and port
+}
+
+# Required for Jenkins websocket agents
+map $http_upgrade $connection_upgrade {
+  default upgrade;
+  '' close;
+}
+
+server {
+  listen          80;       # Listen on port 80 for IPv4 requests
+
+  server_name     jenkins.example.com;  # replace 'jenkins.example.com' with your server domain name
+
+  # this is the jenkins web root directory
+  # (mentioned in the output of "systemctl cat jenkins")
+  root            /var/run/jenkins/war/;
+
+  access_log      /var/log/nginx/jenkins.access.log;
+  error_log       /var/log/nginx/jenkins.error.log;
+
+  # pass through headers from Jenkins that Nginx considers invalid
+  ignore_invalid_headers off;
+
+  location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
+    # rewrite all static files into requests to the root
+    # E.g /static/12345678/css/something.css will become /css/something.css
+    rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
+  }
+
+  location /userContent {
+    # have nginx handle all the static requests to userContent folder
+    # note : This is the $JENKINS_HOME dir
+    root /var/lib/jenkins/;
+    if (!-f $request_filename){
+      # this file does not exist, might be a directory or a /**view** url
+      rewrite (.*) /$1 last;
+      break;
+    }
+    sendfile on;
+  }
+
+  location / {
+      sendfile off;
+      proxy_pass         http://jenkins;
+      proxy_redirect     default;
+      proxy_http_version 1.1;
+
+      # Required for Jenkins websocket agents
+      proxy_set_header   Connection        $connection_upgrade;
+      proxy_set_header   Upgrade           $http_upgrade;
+
+      proxy_set_header   Host              $host;
+      proxy_set_header   X-Real-IP         $remote_addr;
+      proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
+      proxy_set_header   X-Forwarded-Proto $scheme;
+      proxy_max_temp_file_size 0;
+
+      #this is the maximum upload size
+      client_max_body_size       10m;
+      client_body_buffer_size    128k;
+
+      proxy_connect_timeout      90;
+      proxy_send_timeout         90;
+      proxy_read_timeout         90;
+      proxy_buffering            off;
+      proxy_request_buffering    off; # Required for HTTP CLI commands
+      proxy_set_header Connection ""; # Clear for keepalive
+  }
+
+}
+
+

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
/etc/nginx/conf.d 아래 default.conf 파일을 하나 생성하고 위와 같이 입력하고 저장한다.
nginx의 기본 설정 파일에 존재하는 include /etc/nginx/conf.d/*.conf; 설정 때문에 .conf 로 끝난다면 설정이 적용된다.
-설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

[Jenkins] Jenkins 접속

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
-EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

jenkins-start

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
+설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

+

[Jenkins] Jenkins 접속

+

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
+EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

+

jenkins-start

+

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
비밀번호를 입력하면 플러그인 설정 창이 나올텐데 install suggested plugins을 클릭하여 Jenkins가 추천하는 기본 플러그인들을 설치하면 된다.
-플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

[Jenkins] Jenkins Blue Ocean 설치

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
-IAM에서 다음과 같이 역할을 하나 새로 생성한다.

  1. 엔터티 선택

aws-iam1

  1. 권한 추가

aws-iam2

  1. 이름 지정, 검토 및 생성

aws-iam3

  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정

aws-iam4

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단

aws-s3

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

repo, user:email 권한이 있는 토큰이 필요하다.

[Jenkins] 블루 오션 시작

jenkins-blue-ocean1

블루 오션 열기로 파이프라인을 생성한다.
+플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

+

[Jenkins] Jenkins Blue Ocean 설치

+

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

+

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

+

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
+IAM에서 다음과 같이 역할을 하나 새로 생성한다.

+
    +
  1. 엔터티 선택
  2. +
+

aws-iam1

+
    +
  1. 권한 추가
  2. +
+

aws-iam2

+
    +
  1. 이름 지정, 검토 및 생성
  2. +
+

aws-iam3

+
    +
  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정
  2. +
+

aws-iam4

+

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

+

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

+
    +
  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단
  • +
+

aws-s3

+

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

+

repo, user:email 권한이 있는 토큰이 필요하다.

+

[Jenkins] 블루 오션 시작

+

jenkins-blue-ocean1

+

블루 오션 열기로 파이프라인을 생성한다.
토큰 입력 → 조직 선택 → CI/CD 설정할 Repository 선택을 하면 파이프라인 창으로 넘어간다.
-Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

jenkins-blue-ocean2

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

jenkins-blue-ocean3

[Github Repsoitory] Jenkinsfile 설정

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

pipeline {
agent any
stages {
stage('build and test') {
steps {
sh '/gradlew clean build'
}
}
stage('zip') {
steps {
sh 'mv ./build/libs/woowachat.jar .'
sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
}
}
stage('upload') {
steps {
sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
}
}
stage('deploy') {
steps {
sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
}
}
}
}

[Github] Webhooks 설정

github-hook

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

참고 자료

Install Jenkins - CentOS, Jenkins
-Nginx Reverse Proxy Configuration, Jenkins
-Amazon Corretto 17 JDK Install, AWS
-Amazon Linux 2023 packages, AWS

- - +Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

+

jenkins-blue-ocean2

+

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

+

jenkins-blue-ocean3

+

[Github Repsoitory] Jenkinsfile 설정

+

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

+
pipeline {
+  agent any
+  stages {
+    stage('build and test') {
+      steps {
+        sh '/gradlew clean build'
+      }
+    }
+    stage('zip') {
+      steps {
+        sh 'mv ./build/libs/woowachat.jar .'
+        sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
+      }
+    }
+    stage('upload') {
+      steps {
+        sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
+      }
+    }
+    stage('deploy') {
+      steps {
+        sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
+        sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
+      }
+    }
+  }
+}
+
+

[Github] Webhooks 설정

+

github-hook

+

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

+

참고 자료

+

Install Jenkins - CentOS, Jenkins
+Nginx Reverse Proxy Configuration, Jenkins
+Amazon Corretto 17 JDK Install, AWS
+Amazon Linux 2023 packages, AWS

\ No newline at end of file diff --git a/page/31.html b/page/31.html index e37d53fa8..29f74a111 100644 --- a/page/31.html +++ b/page/31.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,36 +12,64 @@ - - - + + + -
-

· 약 6분

4월 21일 금요일

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
+

· 약 6분

4월 21일 금요일

+

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
레벨 3, 4에서 나만의 강점을 가지고 싶어 고민을 많이 했다.
단순히 스프링을 깊게 공부하는 건 효율이 많이 떨어진다고 생각했다.
-글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
-Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
-프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

이건 못참지

도메인 구입 성공?

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
+글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

+

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
+Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

+

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
+프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

+

이건 못참지

+

도메인 구입 성공?

+

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
마치 어릴 때 했던 게임 닉네임 정하는 것처럼 시간이 오래 걸렸다.
-dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

말랑의 DM

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
-우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
+dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

+

말랑의 DM

+

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
+우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

+

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
추가로 도메인에 관한 이야기를 하다가 woowachat이 언급되었고, namecheap에서 chat 도메인을 사용한 woowa.chat으로 구매했다.
-이후에 teco.chat으로 변경했다!

도메인 설정 및 배포

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
-나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

GPT

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
-일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

Sonarcloud

정적 코드 분석 도구로 Sonarcloud를 적용했다.
+이후에 teco.chat으로 변경했다!

+

도메인 설정 및 배포

+

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
+나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

+

GPT

+

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
+일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

+

Sonarcloud

+

정적 코드 분석 도구로 Sonarcloud를 적용했다.
Sonarcloud는 SonarQube의 SaaS 버전이고 사용이 매우 편하다.
예전에 Sonarcloud를 사용할 땐 버튼 몇 번 누르면 적용할 수 있었는데, 이번에는 바로 github action을 사용하라는 안내 페이지로 이동했다.
Sonarcloud가 자체적으로 github repository에 push 하면 정적 분석을 해주는 기능을 원했고, Administration -> Analysis Method에 Automatic Analysis를 설정하니 되었다.
-너무 꽁꽁 숨겨져있네

Tiptap

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
+너무 꽁꽁 숨겨져있네

+

Tiptap

+

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
Tiptap은 Headless WYSIWYG 에디터로 사용자 정의 기능에 특화되어있는 에디터다.
아직 Tiptap이 제공하는 모든 기능을 자연스럽게 사용하지는 못하지만 CodeBlockLowlight 플러그인을 사용하여 코드 블록을 예쁘게 출력할 수 있었다.
api 반환값 그대로 tiptap의 content에 설정했더니 코드 블록이 설정되지 않아서 백 틱 3개를 <pre><code>로 변환했다.
추가로 띄어쓰기도 적용되지 않아서 \n<br>태그로 변환했다.
-변환하는 로직은 GPT의 도움을 많이 받았다.

const replaceCodeFences = (input: String) => {
const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
return input
.replace(codeFencesRegex, (match, p1, p2) => {
const languageClass = p1 ? ` class="language-${p1}"` : "";
return `<pre><code${languageClass}>${p2}</code></pre>`;
})
.replace(/\n/g, "<br>");
};

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

tecochat

폰트 및 favicon 적용

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
+변환하는 로직은 GPT의 도움을 많이 받았다.

+
const replaceCodeFences = (input: String) => {
+    const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
+    return input
+        .replace(codeFencesRegex, (match, p1, p2) => {
+        const languageClass = p1 ? ` class="language-${p1}"` : "";
+        return `<pre><code${languageClass}>${p2}</code></pre>`;
+        })
+        .replace(/\n/g, "<br>");
+};
+
+

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

+

tecochat

+

폰트 및 favicon 적용

+

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
추가로 favicon도 간단하게 적용해서 만족스러웠다.

- - \ No newline at end of file diff --git a/page/32.html b/page/32.html index 67aadbcbb..00de2d657 100644 --- a/page/32.html +++ b/page/32.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,43 +12,79 @@ - - - + + + -
-

· 약 6분

책 정보

상자 밖에 있는 사람
-아빈저연구소

자기기만과 자기배반

책에서는 자기기만과 자기배반에 대한 내용을 다룬다.

  • 자기기만: 자신의 문제를 인정하지 않는 것
  • 자기배반: 다른 사람을 위해 무언가 해야만 한다는 생각을 반하는 행위

자기배반을 한다면 자기기만 상태가 된다.
-자기기만 상태에 빠지는 것을 책에서는 상자 안에 들어간다고 표현한다.

읽고 나서

최근에 읽은 책 중 가장 마음이 불편했다.
-그렇기에 더더욱 나에게 필요한 내용이 담겨있었다.

살면서 많은 선택의 순간이 존재했고, 그 순간마다 자기배반을 택하는 경우가 많았다.
+

· 약 6분

책 정보

+
+

상자 밖에 있는 사람
+아빈저연구소

+
+

자기기만과 자기배반

+

책에서는 자기기만과 자기배반에 대한 내용을 다룬다.

+
    +
  • 자기기만: 자신의 문제를 인정하지 않는 것
  • +
  • 자기배반: 다른 사람을 위해 무언가 해야만 한다는 생각을 반하는 행위
  • +
+

자기배반을 한다면 자기기만 상태가 된다.
+자기기만 상태에 빠지는 것을 책에서는 상자 안에 들어간다고 표현한다.

+

읽고 나서

+

최근에 읽은 책 중 가장 마음이 불편했다.
+그렇기에 더더욱 나에게 필요한 내용이 담겨있었다.

+

살면서 많은 선택의 순간이 존재했고, 그 순간마다 자기배반을 택하는 경우가 많았다.
작게는 집안일을 해야 하는데 몸이 조금 힘들다고 하지 않거나
크게는 잘못을 인정해야 하는 상황에서 그러지 않은 경우가 있었다.
-이런 상황이 반복되어 결국 상자 안에 나 자신을 가두는 경우가 많았다.

더 나은 삶을 위해 내가 상자 안에 있는지 지속적으로 확인하고, 상자 밖으로 나가려는 연습을 해야겠다.
-넓은 시선을 가지고, 항상 내가 틀릴 수 있다는 것을 생각하고 살아가자.

밑줄 친 문장들

우리의 생각은 지식보다 작다.
+이런 상황이 반복되어 결국 상자 안에 나 자신을 가두는 경우가 많았다.

+

더 나은 삶을 위해 내가 상자 안에 있는지 지속적으로 확인하고, 상자 밖으로 나가려는 연습을 해야겠다.
+넓은 시선을 가지고, 항상 내가 틀릴 수 있다는 것을 생각하고 살아가자.

+

밑줄 친 문장들

+
+

우리의 생각은 지식보다 작다.
우리의 지식은 사랑보다 작다.
우리의 사랑은 존재보다 작다.
그리고 우리가 생각하는 나는 실제의 나보다 그만큼 작다.
R. D. 랭
-p.19

우리가 외적으로 어떤 행동을 하든지 간에, 사람들은 우리 마음에서 그들을 어떻게 대하고 있는지에 따라 주로 반응합니다.
+p.19

+
+
+

우리가 외적으로 어떤 행동을 하든지 간에, 사람들은 우리 마음에서 그들을 어떻게 대하고 있는지에 따라 주로 반응합니다.
우리가 사람들에 대해 어떻게 느끼게 되는지는 우리가 상자 안에 있는지 혹은 상자 밖에 있는지에 따라 달라지게 됩니다.
-p.66

비난은 감정에 속하고 낙관은 의지에 속한다.
+p.66

+
+
+

비난은 감정에 속하고 낙관은 의지에 속한다.
인간은 감정보다 더 큰 존재이다.
알랭, 탁닛한
-p.103

우리가 자신에게만 집중하고 있는 한, 혼자서 일하는 것 이상의 창조적인 결과나 협력을 이끌어 낸다는 것은 불가능합니다.
+p.103

+
+
+

우리가 자신에게만 집중하고 있는 한, 혼자서 일하는 것 이상의 창조적인 결과나 협력을 이끌어 낸다는 것은 불가능합니다.
오늘날 경제 환경에서는 혼자서는 일의 결과를 탁월하게 만들어 내기가 어렵습니다.
내가 중심이어야 된다는 폐쇄적인 사고는 함께 일하는 사람들의 열정을 불러오지 못합니다.
-p.175

솔직함은 우리의 문제를 해결하는 열쇠입니다.
+p.175

+
+
+

솔직함은 우리의 문제를 해결하는 열쇠입니다.
그것은 자신의 행동과 관련된 사람에 대해 기꺼이 사과를 하는 것입니다.
그것만이 실타래처럼 엉킨 관계의 문제를 해결할 수 있기 때문이죠.
-p.188

누군가를 나와 같이 동일한 가치를 지닌 한 인간으로 생각해서 그 사람을 위해 내가 상자 밖에 계속 머무르고 싶은 열망이 생길 때, 나는 이미 그 사람에 대해 상자 밖에 있다.
-p.214

대부분의 사람들이 관계 기술을 가지고 그들이 겪고 있는 문제를 바로잡으려고 하는 노력이 결실을 얻지 못하는 것은 결코 그러한 기술 부족 때문에 생기는 것이 아닙니다.
+p.188

+
+
+

누군가를 나와 같이 동일한 가치를 지닌 한 인간으로 생각해서 그 사람을 위해 내가 상자 밖에 계속 머무르고 싶은 열망이 생길 때, 나는 이미 그 사람에 대해 상자 밖에 있다.
+p.214

+
+
+

대부분의 사람들이 관계 기술을 가지고 그들이 겪고 있는 문제를 바로잡으려고 하는 노력이 결실을 얻지 못하는 것은 결코 그러한 기술 부족 때문에 생기는 것이 아닙니다.
그것들은 자기배반 때문에 생겨납니다.
-p.224

우리는 함께 일하고 우리와 함께 살아가는 사람이 진정으로 누구인지 알지 못합니다.
+p.224

+
+
+

우리는 함께 일하고 우리와 함께 살아가는 사람이 진정으로 누구인지 알지 못합니다.
우리가 그들과 진정으로 함께 소통하기 전까지는 우리는 그들의 가치를 잘 모릅니다.
우리의 위대함이란 다른 사람들의 위대한 점을 발견해 주는 것에 있습니다.
-p.280

- - +p.280

+
\ No newline at end of file diff --git a/page/33.html b/page/33.html index 6b3639947..376dcf039 100644 --- a/page/33.html +++ b/page/33.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,33 +12,69 @@ - - - + + + -
-

· 약 6분

InnoDB 스토리지 엔진의 잠금

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
-보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
-InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

낙관적 동시성 제어(OCC, Optimistic concurrency control)

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

비관적 동시성 제어(PCC, Pessimistic Concurrency Control)

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
-일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

Shared & Exclusive Locks

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

공유 잠금(S, shared lock)

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
+

· 약 6분

InnoDB 스토리지 엔진의 잠금

+

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
+보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

+

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
+InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

+

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

+

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
+일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

+

Shared & Exclusive Locks

+

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

+

공유 잠금(S, shared lock)

+

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
다른 트랜잭션에서 읽기가 가능하지만, 쓰기는 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

배타적 잠금(X, exclusive lock)

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
+예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

+

배타적 잠금(X, exclusive lock)

+

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
락을 건 트랜잭션만이 해당 데이터에 접근 가능하다. 다른 트랜잭션의 경우 읽기, 쓰기가 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

Intention Locks

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
+예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

+

Intention Locks

+

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
테이블에 있는 로우에 대해서 나중에 요청되는 것이 어떤 형태의 잠금인지 가리키기 위해 사용된다.
기본적으로 로우 단위 잠금을 수행하기 전에 인텐션 잠금을 먼저 획득한다.
-인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

인텐션 공유 잠금(IS, intention shared lock)

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

인텐션 배타적 잠금(IX, intention exclusive lock)

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

잠금간의 호환성

XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

Record Locks

레코드 자체만을 잠그는 락이다.
-InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

Gap Locks

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

Next-Key Locks

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
-REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

AUTO-INC Locks

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
+인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

+

인텐션 공유 잠금(IS, intention shared lock)

+

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

+

인텐션 배타적 잠금(IX, intention exclusive lock)

+

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

+

** 잠금간의 호환성 **

+
XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible
+

Record Locks

+

레코드 자체만을 잠그는 락이다.
+InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

+

Gap Locks

+

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

+

Next-Key Locks

+

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
+REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

+

AUTO-INC Locks

+

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
InnoDB 는 내부적으로 AUTO-INC 락이라고 하는 테이블 수준의 잠금을 사용한다.
-트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

잠금 예시

-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
-- Record Locks: 10에 대해 락이 걸린다.
SELECT * FROM table_name where id = 10 for update;

-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
SELECT * FROM table_name where id > 100 for update;

-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Optimistic and Pessimistic record locking, IBM
-MySQL Innodb Locks, cecil1018
-MySQL 8.0 InnoDB Locks, MySQL
-Locks Set by Different SQL Statements in InnoDB, MySQL

- - +트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

+

잠금 예시

+
-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
+-- Record Locks: 10에 대해 락이 걸린다.
+SELECT * FROM table_name where id = 10 for update;
+
+-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
+SELECT * FROM table_name where id > 100 for update;
+
+-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
+SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Optimistic and Pessimistic record locking, IBM
+MySQL Innodb Locks, cecil1018
+MySQL 8.0 InnoDB Locks, MySQL
+Locks Set by Different SQL Statements in InnoDB, MySQL

\ No newline at end of file diff --git a/page/34.html b/page/34.html index 01ef8c117..c50f635a5 100644 --- a/page/34.html +++ b/page/34.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,27 +12,75 @@ - - - + + + -
-

· 약 5분

MySQL 엔진의 잠금

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
-MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

글로벌 락(Global lock)

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

  • 영향을 미치는 범위는 해당 서버 전체이다.
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
+

· 약 5분

MySQL 엔진의 잠금

+

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
+MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

+

글로벌 락(Global lock)

+

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

+
    +
  • 영향을 미치는 범위는 해당 서버 전체이다.
  • +
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.
  • +
+

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 일관된 백업을 받아야할 때 사용한다.
-InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

-- GLOBAL LOCK
FLUSH TABLES WITH READ LOCK;
-- UNLOCK
UNLOCK TABLES;

-- BACKUP LOCK
LOCK INSTANCE FOR BACKUP;
-- UNLOCK
UNLOCK INSTANCE;
MyISAM

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
-트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

테이블 락(Table lock)

개별 테이블 단위로 설정되는 잠금이다.
+InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

+
-- GLOBAL LOCK
+FLUSH TABLES WITH READ LOCK;
+-- UNLOCK
+UNLOCK TABLES;
+
+-- BACKUP LOCK
+LOCK INSTANCE FOR BACKUP;
+-- UNLOCK
+UNLOCK INSTANCE;
+
+

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
+트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

+

테이블 락(Table lock)

+

개별 테이블 단위로 설정되는 잠금이다.
명시적 또는 묵시적으로 특정 테이블의 락을 획득할 수 있다.
묵시적 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.
-InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

-- TABLE LOCK
LOCK TABLES table_name [ READ | WRITE ]

-- UNLOCK
UNLOCK TABLES;

네임드 락(Named lock)

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
-여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
SELECT GET_LOCK('aGVyYg==', 1);

-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
SELECT IS_FREE_LOCK('aGVyYg==');

-- 문자열에 대한 잠금을 해제한다.
SELECT RELEASE_LOCK('aGVyYg==');

-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.

-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
SELECT RELEASE_ALL_LOCKS();

메타데이터 락(Metadata lock)

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
-명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
-보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
RENAME TABLE rank TO rank_backup, rank_new TO rank;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-MySQL의 User Level Lock를 활용한다면?, gywndi
-Locking Functions, MySQL 5.7 Reference
-Locking Functions, MySQL 8.0 Reference

- - +InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

+
-- TABLE LOCK
+LOCK TABLES table_name [ READ | WRITE ]
+
+-- UNLOCK
+UNLOCK TABLES;
+
+

네임드 락(Named lock)

+

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
+여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

+
-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
+SELECT GET_LOCK('aGVyYg==', 1);
+
+-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
+SELECT IS_FREE_LOCK('aGVyYg==');
+
+-- 문자열에 대한 잠금을 해제한다.
+SELECT RELEASE_LOCK('aGVyYg==');
+
+-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.
+
+-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
+SELECT RELEASE_ALL_LOCKS();
+
+

메타데이터 락(Metadata lock)

+

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
+명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
+보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

+
-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
+-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
+RENAME TABLE rank TO rank_backup, rank_new TO rank;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+MySQL의 User Level Lock를 활용한다면?, gywndi
+Locking Functions, MySQL 5.7 Reference
+Locking Functions, MySQL 8.0 Reference

\ No newline at end of file diff --git a/page/35.html b/page/35.html index eb865546b..78e6bd21f 100644 --- a/page/35.html +++ b/page/35.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,37 +12,139 @@ - - - + + + -
-

· 약 10분

트랜잭션(Transaction)

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
+

· 약 10분

트랜잭션(Transaction)

+

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
트랜잭션은 작업의 완전성과 데이터의 정합성을 보장해 준다.
-논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

트랜잭션의 속성(ACID)

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
+논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

+

트랜잭션의 속성(ACID)

+

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
일관성(Consistency): 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지해야 한다.
격리성(Isolation): 각각의 트랜잭션은 독립적이라 서로에게 영향을 주지 않아야 한다.
-지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

트랜잭션 주의사항

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
-구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

왜 네트워크 작업이 있을 때 트랜잭션에서 배제해야 할까? 🤔

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
-네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)

격리 수준(Isolation level)

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
-격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

READ UNCOMMITTED

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
+지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

+

트랜잭션 주의사항

+

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
+구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

+

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
+네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

    +
  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • +
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)
  • +
+

격리 수준(Isolation level)

+

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
+격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

+

READ UNCOMMITTED

+

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
더티 리드 현상이 발생하기 때문에 정합성의 문제가 많은 격리 수준이다.
-MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

READ COMMITTED

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
+MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

+ +

READ COMMITTED

+

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
오라클 DBMS에서 기본으로 사용되는 격리 수준이다.
-REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

REPEATABLE READ

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
+REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

+ +

REPEATABLE READ

+

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준이다.
MVCC를 이용해 언두(Undo) 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
-동일한 결과를 보장하는 방법은 다음과 같다.

  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

갭 랍(Gap lock)과 넥스트 키 락(Next-key lock)

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

MVCC(Multi Version Concurrency Control)

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

SERIALIZABLE

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
+동일한 결과를 보장하는 방법은 다음과 같다.

+
    +
  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • +
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • +
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • +
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.
  • +
+

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

+ +

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

+

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

    +
  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • +
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)
  • +

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

+

SERIALIZABLE

+

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 접근할 수 없고 단순한 읽기 작업도 공유 잠금(읽기 잠금)을 획득해야만 한다.
-InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

격리 수준에 따른 부정합 문제

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX

더티 리드(Dirty read)

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
+InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

+

격리 수준에 따른 부정합 문제

+

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

+
격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX
+

더티 리드(Dirty read)

+

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
트랜잭션 격리 수준이 READ UNCOMMITTED일 때 발생한다.
-예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

반복 가능하지 않은 조회(Non-repeatable read)

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
-예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

팬텀 리드(Phantom read, Phantom row)

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
-예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Isolation Level, MySQL

- - +예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

+

반복 가능하지 않은 조회(Non-repeatable read)

+

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
+예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

+ +

팬텀 리드(Phantom read, Phantom row)

+

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
+예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

+ +

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Isolation Level, MySQL

\ No newline at end of file diff --git a/page/36.html b/page/36.html index 733fd9b15..f5a1704e4 100644 --- a/page/36.html +++ b/page/36.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,31 +12,51 @@ - - - + + + -
-

· 약 5분

테스트 대역이란?

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
-Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
-외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

테스트 대역의 타입 계층 구조

더미(Dummy)

가장 단순하고, 원시적인 유형의 테스트 대역이다.
+

· 약 5분

테스트 대역이란?

+

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
+Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

+

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
+외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

+

테스트 대역의 타입 계층 구조

+ +

더미(Dummy)

+

가장 단순하고, 원시적인 유형의 테스트 대역이다.
기본적으로 아무 일도 하지 않는 구현체로 인스턴스화가 필요한 경우 사용한다.
-만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

스텁(Stub)

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
-이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

스파이(Spy)

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
-예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

목, 모의 객체(Mock)

목은 더미, 스텁, 스파이를 포함한다.
+만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

+

스텁(Stub)

+

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
+이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

+

스파이(Spy)

+

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
+예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

+

목, 모의 객체(Mock)

+

목은 더미, 스텁, 스파이를 포함한다.
호출 시 사전에 정의된 결과를 반환하고, 예상치 못한 호출이 있을 경우 예외를 던질 수 있다.
-또한 호출에 대한 검증을 할 수 있다.

가짜(Fake)

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
-예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

DOC(depended-on component)

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
-테스트 더블은 DOC와 동일한 API를 제공해야 한다.

상호작용에 따른 목과 스텁 구분

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
-목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
SUT(system under test)

테스트 대상 시스템
-테스트를 하려는 대상

참고 자료

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
+또한 호출에 대한 검증을 할 수 있다.

+

가짜(Fake)

+

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
+예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

+

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
+테스트 더블은 DOC와 동일한 API를 제공해야 한다.

+

상호작용에 따른 목과 스텁 구분

+

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
+목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

+
TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
+

테스트 대상 시스템
+테스트를 하려는 대상

+

참고 자료

+

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
단위 테스트 - 5장 목과 테스트 취약성, 블라디미르 코리코프
테스트 주도 개발 시작하기 - 7장 대역, 최범균
-테스트 더블, Martin Fowler
-테스트 관련 용어 정리, Johngrib
-Test Double, Gerard Meszaros

- - +테스트 더블, Martin Fowler
+테스트 관련 용어 정리, Johngrib
+Test Double, Gerard Meszaros

\ No newline at end of file diff --git a/page/37.html b/page/37.html index 798c6a9b7..5c5beb413 100644 --- a/page/37.html +++ b/page/37.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,31 +12,84 @@ - - - + + + -
-

· 약 6분

클래스 파일

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
-컴파일된 클래스파일은 어떤 구조로 되어있을까?

클래스 파일의 데이터 형식

8비트 바이트의 스트림으로 구성된다.
+

· 약 6분

클래스 파일

+

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
+컴파일된 클래스파일은 어떤 구조로 되어있을까?

+

클래스 파일의 데이터 형식

+

8비트 바이트의 스트림으로 구성된다.
16비트 및 32비트의 데이터는 각각 2개, 4개의 연속된 8비트를 읽어서 구성된다.
-멀티바이트의 경우 항상 big endian 순서로 저장된다.

u1 → unsigned 1byte
+멀티바이트의 경우 항상 big endian 순서로 저장된다.

+

u1 → unsigned 1byte
u2 → unsigned 2byte
-u4 → unsigned 4byte

클래스 파일 구조

ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

매직넘버

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
-보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

클래스 파일 포맷 버전

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

class file format major versions

Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61

상수 풀

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
+u4 → unsigned 4byte

+

클래스 파일 구조

+
ClassFile {
+    u4             magic;
+    u2             minor_version;
+    u2             major_version;
+    u2             constant_pool_count;
+    cp_info        constant_pool[constant_pool_count-1];
+    u2             access_flags;
+    u2             this_class;
+    u2             super_class;
+    u2             interfaces_count;
+    u2             interfaces[interfaces_count];
+    u2             fields_count;
+    field_info     fields[fields_count];
+    u2             methods_count;
+    method_info    methods[methods_count];
+    u2             attributes_count;
+    attribute_info attributes[attributes_count];
+}
+
+

매직넘버

+

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
+보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

+

클래스 파일 포맷 버전

+

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

+
    +
  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D
  • +
+

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

+

class file format major versions

+
Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61
+

상수 풀

+

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
클래스명, 상수명, 상수 값, 필드명, 메서드명과 같은 값들이 존재한다.
-JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

액세스 플래그

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
-예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

Class access and property modifiers

Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.

this_class

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
-해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

super_class

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
-아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

interface, field, method

각각의 개수와, 정보에 대한 값이 들어있다.
-interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

attributes

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
-정해진 클래스 파일의 구조를 확장하는 역할을 한다.

클래스 파일 확인하면서 사용한 툴

IntelliJ plugin - BinEd
-IntelliJ plugin - jclasslib Bytecode Viewer

참고 자료

2장 JVM 이야기, 자바 최적화
-Class file in Java, File Format
-java se11 Class 파일 형식, Oracle
-java se17 Class 파일 형식, Oracle

- - +JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

+

액세스 플래그

+

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
+예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

+
    +
  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT
  • +
+

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

+

Class access and property modifiers

+
Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.
+

this_class

+

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
+해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

+

super_class

+

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
+아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

+

interface, field, method

+

각각의 개수와, 정보에 대한 값이 들어있다.
+interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

+

attributes

+

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
+정해진 클래스 파일의 구조를 확장하는 역할을 한다.

+

클래스 파일 확인하면서 사용한 툴

+

IntelliJ plugin - BinEd
+IntelliJ plugin - jclasslib Bytecode Viewer

+

참고 자료

+

2장 JVM 이야기, 자바 최적화
+Class file in Java, File Format
+java se11 Class 파일 형식, Oracle
+java se17 Class 파일 형식, Oracle

\ No newline at end of file diff --git a/page/38.html b/page/38.html index fa8afe25b..b39338460 100644 --- a/page/38.html +++ b/page/38.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,25 +12,356 @@ - - - + + + -
-

· 약 10분

체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
+

· 약 10분

체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
이 때 JDBC를 사용할 때 데이터베이스의 커넥션을 얻고, try-with-resource를 사용하는 부분이 반복되었다.
-템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

기존 코드

public class User {
private final int id;
private final String name;

public User(final int id, final String name) {
this.id = id;
this.name = name;
}

public int getId() {
return id;
}

public String getName() {
return name;
}
}

SELECT, DELETE 중복 제거

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
-변하는 부분: SQL Query, 매개변수

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
executeUpdate(query, userId);
}

private void executeUpdate(final String query, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
preparedStatement.executeUpdate();
} catch (final SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
-이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

콜백(Callback)

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
-자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
+템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

+

기존 코드

+
public class User {
+    private final int id;
+    private final String name;
+
+    public User(final int id, final String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
+
+

SELECT, DELETE 중복 제거

+

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
+변하는 부분: SQL Query, 매개변수

+

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

+
public void insert(final String name) {
+    final String query = "INSERT INTO User (name) VALUES (?)";
+    executeUpdate(query, name);
+}
+
+public void delete(final int userId) {
+    final String query = "DELETE FROM user WHERE user_id = ?";
+    executeUpdate(query, userId);
+}
+
+private void executeUpdate(final String query, final Object... parameters) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
+        for (int i = 1; i <= parameters.length; i++) {
+            preparedStatement.setObject(i, parameters[i - 1]);
+        }
+        preparedStatement.executeUpdate();
+    } catch (final SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

+

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
+이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

+

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
+자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

+

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
executeQuery로 조회한 값은 ResultSet 안에 들어가있다.
-이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

@FunctionalInterface
public interface RowMapper {
User mapRow(final ResultSet resultSet) throws SQLException;
}

조회 분리하기 - 2. 단건 조회

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
-아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

public User findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return queryForSingleResult(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
}, userId);
}

private User queryForSingleResult(
final String query,
final RowMapper rowMapper,
final Object... parameters
) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
if (resultSet.next()) {
return rowMapper.mapRow(resultSet);
}
return null;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

조회 분리하기 - 3. 다건 조회

단건 조회와 유사하다.

public List<User> findAll() {
final String query = "SELECT * FROM user";
return query(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
});
}

private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
final List<User> result = new ArrayList<>();
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
return result;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

제네릭 사용하기

위의 코드는 User를 조회할 때만 사용할 수 있다.
-아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

@FunctionalInterface
public interface RowMapper<T> {
T mapRow(final ResultSet resultSet) throws SQLException;
}

private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
+이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

+
@FunctionalInterface
+public interface RowMapper {
+    User mapRow(final ResultSet resultSet) throws SQLException;
+}
+
+

조회 분리하기 - 2. 단건 조회

+

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
+아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

+
public User findById(final int userId) {
+    final String query = "SELECT * FROM user WHERE id = ?";
+    return queryForSingleResult(query, resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    }, userId);
+}
+
+private User queryForSingleResult(
+        final String query,
+        final RowMapper rowMapper,
+        final Object... parameters
+) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
+         final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
+        if (resultSet.next()) {
+            return rowMapper.mapRow(resultSet);
+        }
+        return null;
+    } catch (SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+private ResultSet executeQuery(
+        final PreparedStatement preparedStatement,
+        final Object[] parameters) throws SQLException {
+    for (int i = 1; i <= parameters.length; i++) {
+        preparedStatement.setObject(i, parameters[i - 1]);
+    }
+    return preparedStatement.executeQuery();
+}
+
+

조회 분리하기 - 3. 다건 조회

+

단건 조회와 유사하다.

+
public List<User> findAll() {
+    final String query = "SELECT * FROM user";
+    return query(query, resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    });
+}
+
+private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
+         final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
+        final List<User> result = new ArrayList<>();
+        while (resultSet.next()) {
+            result.add(rowMapper.mapRow(resultSet));
+        }
+        return result;
+    } catch (SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+private ResultSet executeQuery(
+        final PreparedStatement preparedStatement,
+        final Object[] parameters) throws SQLException {
+    for (int i = 1; i <= parameters.length; i++) {
+        preparedStatement.setObject(i, parameters[i - 1]);
+    }
+    return preparedStatement.executeQuery();
+}
+
+

제네릭 사용하기

+

위의 코드는 User를 조회할 때만 사용할 수 있다.
+아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

+
@FunctionalInterface
+public interface RowMapper<T> {
+    T mapRow(final ResultSet resultSet) throws SQLException;
+}
+
+private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
+private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
+
+

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

+

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
또한 null을 반환하기 보단 Optional로 감싸서 반환하도록 변경한다.
-최종적으로 아래와 같은 코드가 완성된다.

public class UserDao {
private final RowMapper<User> rowMapper = resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
};
private final JdbcTemplate jdbcTemplate;

public UserDao(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
jdbcTemplate.executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
jdbcTemplate.executeUpdate(query, userId);
}

public Optional<User> findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
}

public List<User> findAll() {
final String query = "SELECT * FROM user";
return jdbcTemplate.query(query, rowMapper);
}
}
- - +최종적으로 아래와 같은 코드가 완성된다.

+
public class UserDao {
+    private final RowMapper<User> rowMapper = resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    };
+    private final JdbcTemplate jdbcTemplate;
+
+    public UserDao(final JdbcTemplate jdbcTemplate) {
+        this.jdbcTemplate = jdbcTemplate;
+    }
+
+    public void insert(final String name) {
+        final String query = "INSERT INTO User (name) VALUES (?)";
+        jdbcTemplate.executeUpdate(query, name);
+    }
+
+    public void delete(final int userId) {
+        final String query = "DELETE FROM user WHERE user_id = ?";
+        jdbcTemplate.executeUpdate(query, userId);
+    }
+
+    public Optional<User> findById(final int userId) {
+        final String query = "SELECT * FROM user WHERE id = ?";
+        return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
+    }
+
+    public List<User> findAll() {
+        final String query = "SELECT * FROM user";
+        return jdbcTemplate.query(query, rowMapper);
+    }
+}
+
\ No newline at end of file diff --git a/page/39.html b/page/39.html index 29642d1da..716a6b9ac 100644 --- a/page/39.html +++ b/page/39.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,45 +12,78 @@ - - - + + + -
-

· 약 8분

레벨 1이 끝났다.
+

· 약 8분

레벨 1이 끝났다.
우테코를 시작하기 전 내가 정해두었던 목표 이상으로 달성했기 때문에 매우 만족스럽다.
혼자 독학을 할 땐 이 방향으로 공부하는 게 맞는지 계속 반추하다 결국 무기력함에 빠져들었다.
-하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

Keep

나만의 루틴 만들기

스스로가 외부의 영향을 많이 받는다고 생각한다.
-최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
+하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

+

Keep

+

나만의 루틴 만들기

+

스스로가 외부의 영향을 많이 받는다고 생각한다.
+최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

+

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
소화능력이 부족하기 때문에 점심은 도시락(그래봤자 계란2개)을 준비하고
항상 똑같은 컨디션을 유지하기 위해 항상 6시에 집에 간다.
-이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

크루들과 친하게 지내기

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
+이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

+

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

+

크루들과 친하게 지내기

+

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
하다 보니 더 많은 크루들의 닉네임을 외운 것 같다.
-앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

글쓰기

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
-매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
+앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

+

글쓰기

+

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
+매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

+

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
사실 겉으로 드러내지 않았지만 꼭 받아보고 싶었다.
-글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

코드 리뷰 스터디

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
+글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

+

코드 리뷰 스터디

+

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
과연 도움이 될까 생각했지만 결과적으로는 코드 리뷰를 하면서 성장을 많이 한 것 같다.
투자한 시간 대비 가성비가 좋은 활동이었다.
-누누가 스터디장인데 과연 꾸준히 이어나가려나?

레벨 인터뷰

인터뷰할 때 많이 떨지 않아서 좋았다.
+누누가 스터디장인데 과연 꾸준히 이어나가려나?

+

레벨 인터뷰

+

인터뷰할 때 많이 떨지 않아서 좋았다.
남들 앞에서 이야기를 하거나, 면접을 보면 항상 엄청 떨어서 걱정했는데
기술적인 질문을 받았을 때 떨지 않고 잘 대답할 수 있었다.
우아한테크코스 생활을 하면서 다른 크루가 질문했을 때, 최대한 이해하기 쉽게 설명하려고 했던 경험이 도움이 된 것 같다.
-이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • 두괄식 표현
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • 설명할 수 있을만큼 시간 충분히 가지기
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • 끝맺는 부분 연습하기(자신감 있게)
  • 기술적인 집착가지기
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기

Problem

페어프로그래밍

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
+이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

+
    +
  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • +
  • 두괄식 표현
  • +
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • +
  • 설명할 수 있을만큼 시간 충분히 가지기
  • +
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • +
  • 끝맺는 부분 연습하기(자신감 있게)
  • +
  • 기술적인 집착가지기
  • +
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기
  • +
+

Problem

+

페어프로그래밍

+

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
페어는 매번 바뀌고, 미션의 복잡도도 증가하기 때문인 것 같다.
소통 능력, 시간관리가 부족했고, 만족스럽지 않았다.
하지만 페어를 진행하고, 회고를 하다 보니 나만의 노하우가 쌓이는 느낌이다.
-레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

집중하는 시간⏱️ 부족

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
-이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

Try

허브🌿와의 티타임?

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
+레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

+

집중하는 시간⏱️ 부족

+

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
+이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

+

Try

+

허브🌿와의 티타임?

+

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
예를 들어 잡담방에 저와 커피챗 하실 분 :) 하면서 올릴 수 있을 것 같다.
참여하는 사람이 있을지, 안 좋게 보는 게 아닐지 걱정되지만 그래도 재밌을 것 같다.
-저랑 허브티 한잔 하실래요?

기술적인 부분

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
+저랑 허브티 한잔 하실래요?

+

기술적인 부분

+

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
시간의 여유가 될 때 책을 조금씩 읽어야겠다.
-블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

레벨 1을 마무리하며

시간이 빠르게 흘러갔다.
+블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

+

레벨 1을 마무리하며

+

시간이 빠르게 흘러갔다.
타인에게 좋은 영향을 주기위해, 방학동안 나를 챙기는 시간을 가져야겠다.
또한 함께 일하고 싶은 사람을 목표로 앞으로도 꾸준히 의식적 노력을 해야겠다.

- - \ No newline at end of file diff --git a/page/4.html b/page/4.html index 6a847edb9..4f0a97236 100644 --- a/page/4.html +++ b/page/4.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,25 +12,92 @@ - - - + + + -
-

· 약 5분

테스트 격리

테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 @DirtiesContext, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 @Transactional등 다양한 방법이 있다.
-해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.

Independent - FIRST

테스트끼리 서로 의존하면 안 된다.
+

· 약 5분

테스트 격리

+

테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 @DirtiesContext, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 @Transactional등 다양한 방법이 있다.
+해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.

+

테스트끼리 서로 의존하면 안 된다.
서로 의존하게 된다면 하나의 테스트가 실패할 때, 또 다른 하나의 테스트가 실패할 수 있다.
-다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

TestExecutionListener

스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.
-이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.

TextExecutionListner
public interface TestExecutionListener {
default void beforeTestClass(TestContext testContext) throws Exception {}
default void prepareTestInstance(TestContext testContext) throws Exception {}
default void beforeTestMethod(TestContext testContext) throws Exception {}
default void beforeTestExecution(TestContext testContext) throws Exception {}
default void afterTestExecution(TestContext testContext) throws Exception {}
default void afterTestMethod(TestContext testContext) throws Exception {}
default void afterTestClass(TestContext testContext) throws Exception {}
}

AbstractTestExecutionListener 상속하여 구현

AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.
-다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.

DatabaseCleaner

public class DatabaseCleaner extends AbstractTestExecutionListener {

private static final String TRUNCATE_TABLE_QUERY = """
SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'PUBLIC'
""";

@Override
public void afterTestMethod(TestContext testContext) {
JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);
List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);
truncateTables(jdbcTemplate, truncateTableQueries);
}

private JdbcTemplate getJdbcTemplate(TestContext testContext) {
return testContext.getApplicationContext().getBean(JdbcTemplate.class);
}

private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {
return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);
}

private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");
truncateTableQueries.forEach(jdbcTemplate::execute);
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");
}
}

Listener 등록

@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.
+다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

+

TestExecutionListener

+

스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.
+이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.

+
public interface TestExecutionListener {
+    default void beforeTestClass(TestContext testContext) throws Exception {}
+    default void prepareTestInstance(TestContext testContext) throws Exception {}
+    default void beforeTestMethod(TestContext testContext) throws Exception {}
+    default void beforeTestExecution(TestContext testContext) throws Exception {}
+    default void afterTestExecution(TestContext testContext) throws Exception {}
+    default void afterTestMethod(TestContext testContext) throws Exception {}
+    default void afterTestClass(TestContext testContext) throws Exception {}
+}
+
+

AbstractTestExecutionListener 상속하여 구현

+

AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.
+다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.

+

+public class DatabaseCleaner extends AbstractTestExecutionListener {
+
+    private static final String TRUNCATE_TABLE_QUERY = """
+            SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') 
+            FROM INFORMATION_SCHEMA.TABLES
+            WHERE TABLE_SCHEMA = 'PUBLIC'
+            """;
+
+    @Override
+    public void afterTestMethod(TestContext testContext) {
+        JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);
+        List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);
+        truncateTables(jdbcTemplate, truncateTableQueries);
+    }
+
+    private JdbcTemplate getJdbcTemplate(TestContext testContext) {
+        return testContext.getApplicationContext().getBean(JdbcTemplate.class);
+    }
+
+    private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {
+        return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);
+    }
+
+    private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {
+        jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");
+        truncateTableQueries.forEach(jdbcTemplate::execute);
+        jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");
+    }
+}
+
+
+

Listener 등록

+

@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.
mergeMode의 기본값은 REPLACE_DEFAULTS로 리스너가 이미 존재하는 경우 등록된 리스너로 변경된다.
MERGE_WITH_DEFAULTS로 설정한다면 Ordered 기준으로 순서가 결정된다.
-이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.

AcceptanceTest

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestExecutionListeners(
value = DatabaseCleaner.class,
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
)
public abstract class AcceptanceTest {

@LocalServerPort
private int port;

@BeforeEach
public void setUp() {
RestAssured.port = port;
}
}

참고 자료

The Spring TestExecutionListener, Baeldung
-인수테스트에서 테스트 격리하기, 테코블
-Eradicating Non-Determinism in Tests, martin fowler
-@SpringBootTest의 테스트 격리시키기, MangKyu

- - +이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.

+

+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@TestExecutionListeners(
+        value = DatabaseCleaner.class,
+        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
+)
+public abstract class AcceptanceTest {
+
+    @LocalServerPort
+    private int port;
+
+    @BeforeEach
+    public void setUp() {
+        RestAssured.port = port;
+    }
+}
+
+
+

참고 자료

+

The Spring TestExecutionListener, Baeldung
+인수테스트에서 테스트 격리하기, 테코블
+Eradicating Non-Determinism in Tests, martin fowler
+@SpringBootTest의 테스트 격리시키기, MangKyu

\ No newline at end of file diff --git a/page/40.html b/page/40.html index 84aca2d51..8b5c8d746 100644 --- a/page/40.html +++ b/page/40.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,49 +12,84 @@ - - - + + + -
-

· 약 8분

체스

체스 미션에는 가비와 페어가 매칭되었다!
+

· 약 8분

1, 2단계: https://github.com/woowacourse/java-chess/pull/441
+3, 4단계: https://github.com/woowacourse/java-chess/pull/529

+

체스

+

체스 미션에는 가비와 페어가 매칭되었다!
체스는 이전 미션들보다 훨씬 복잡한 도메인이었다.
하지만 가비와 나는 체스 도메인이 익숙해서 더 편한 마음으로 시작할 수 있었다.
-미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
-최종적으로 결정한 부분은 다음과 같다.

각 기물의 이동 가능여부
-Rank와 File은 각각 위치값을 가지고 있고, 값의 차이를 이용해서 각 기물의 이동 가능 여부를 계산했다.
+미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

+

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
+최종적으로 결정한 부분은 다음과 같다.

+

각 기물의 이동 가능여부
+Rank와 File은 각각 위치값을 가지고 있고, 값의 차이를 이용해서 각 기물의 이동 가능 여부를 계산했다.
직선 → Rank와 File 차이 중 하나가 0이어야 한다.
대각선 → Rank와 File 차이의 절대값이 같아야 한다. ex) abs(-2) == abs(2)
-나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

도착 칸의 기물 여부
+나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

+

도착 칸의 기물 여부
아군 → 이동이 불가능하다.
-적군 → 이동이 가능하다. 적군을 잡는다.

중간에 기물 존재 여부
-이동 경로에 기물이 존재하면 안된다.

데이터베이스 사용
+적군 → 이동이 가능하다. 적군을 잡는다.

+

중간에 기물 존재 여부
+이동 경로에 기물이 존재하면 안된다.

+

데이터베이스 사용
체스 미션은 특별하게 데이터베이스와 연결하는 부분이 있었다.
-체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

  • 기물 전체를 저장하는 방법
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
-기물 전체를 저장하지 않은 이유는 다음과 같다.

  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
+체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

+
    +
  • 기물 전체를 저장하는 방법
  • +
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법
  • +
+

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
+기물 전체를 저장하지 않은 이유는 다음과 같다.

+
    +
  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • +
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • +
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.
  • +
+

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
보드저장: 초기상태에서 32개의 Insert 쿼리(기물의 위치) + 기물 이동 시 움직임 변경(잡히는 경우 2개의 쿼리)
-기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

추가로 기보저장이 구현도 더욱 간단하다. 👍

부가적인 부분

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

  • 누누의 도움으로 ConnectionPool 구현
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

부족했던 부분

꼼꼼하게 코드를 작성하지 못한 부분
+기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

+

추가로 기보저장이 구현도 더욱 간단하다. 👍

+

부가적인 부분

+

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

+
    +
  • 누누의 도움으로 ConnectionPool 구현
  • +
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • +
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)
  • +
+

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

+

부족했던 부분

+

꼼꼼하게 코드를 작성하지 못한 부분
DB 관련 부분을 꼼꼼하게 코딩을 하지 못했다.
도메인 로직에만 집중하다보니 정적 중요한 DB의 코드의 예외처리, 빈 값을 반환 하는 부분을 꼼꼼하게 처리하지 못했다.
-하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

시간에 대한 부담감
+하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

+

시간에 대한 부담감
초반에는 여유롭지만 제출 마감에 가까워질 수록 사람이 급해지는 것 같다.
-다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

새로 학습한 부분

DAO 중복 제거

프롤로그에 을 작성했다.
+다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

+

새로 학습한 부분

+

DAO 중복 제거

+

프롤로그에 을 작성했다.
DAO를 작성하는데 try-catch-resources와 여러 코드가 중복되서 제거하고싶었다.
-템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

페어에게 배울 부분

페어 생각하기
+템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

+

페어에게 배울 부분

+

페어 생각하기
가비는 누구보다 페어를 생각하고, 배려해주는 페어였다.
-중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

미션 몰입하기
+중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

+

미션 몰입하기
최근에 미션에 잘 몰입하지 못했다.
가비는 페어를 진행할 때 미션에 대한 몰입도가 매우 좋았다.
집에가서도 체스 이동에 대한 로직을 어떻게 구현할 지 생각한 뒤 꼼꼼해서 정리해서 나에게 보내주었다.
덕분에 나도 가비의 생각을 알 수 있어서 미션을 진행하는데 가속도가 붙은 것 같다.
-또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

솔직함
+또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

+

솔직함
먼저 회고하자고 말 걸어줘서 정말 고마웠다고 표현해주는 부분
모르는게 있으면 솔직하게 말해주는 부분
나의 의견을 정리하지 못한 상태로 전달할 때 이해가 안되었다고 정확히 전달해주는 부분
-솔직함은 페어할 때 중요한 부분인 것 같다.

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

- - +솔직함은 페어할 때 중요한 부분인 것 같다.

+

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

\ No newline at end of file diff --git a/page/41.html b/page/41.html index 8f57a31e8..8e27a38f5 100644 --- a/page/41.html +++ b/page/41.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,16 +12,101 @@ - - - + + + -
-

· 약 9분

GRASP(General Responsibility Assignment Software Pattern)

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

각 패턴마다 Solution과 Problem로 구성되어 있다.

정보 전문가 패턴(Information Expert)

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

필요한 정보를 가진 객체들로 책임이 분산된다.

창조자 패턴(Creator)

Q: 누가 객체 A를 생성하는가?

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A 객체를 긴밀하게 사용한다.
  • B가 A 객체의 초기값을 가지고 있다.

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

낮은 결합도 패턴(Low Coupling)

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

결합도(Coupling) -객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

  • 오브젝트 p.17

결합도를 낮춘다면 다음과 같은 이점이 있다.

  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • 재사용이 편리해진다.
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)

높은 응집도 패턴(High Cohesion)

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

응집도(Cohesion) -연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

  • 오브젝트 p.26

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • 유지보수가 쉬워진다.
  • 낮은 결합도 또한 지원한다.
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.

컨트롤러 패턴(Controller)

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

어떤 서브시스템이 존재한다고 가정할 때

  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.

다형성 패턴(Polymorphism)

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

변경 보호 패턴(Protected Variations)

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

간접 참조 패턴(Indirection)

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

순수한 가공물 패턴(Pure Fabrication)

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.

참고 자료

오브젝트 5장. 책임 할당하기, 조영호

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

GRASP, 한빛 네트워크

- - +

· 약 9분

GRASP(General Responsibility Assignment Software Pattern)

+

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

+

각 패턴마다 Solution과 Problem로 구성되어 있다.

+

정보 전문가 패턴(Information Expert)

+

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

+

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

+

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

+

필요한 정보를 가진 객체들로 책임이 분산된다.

+

창조자 패턴(Creator)

+

Q: 누가 객체 A를 생성하는가?

+

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

+
    +
  • B가 A 객체를 포함 또는 참조한다.
  • +
  • B가 A 객체를 기록한다.
  • +
  • B가 A 객체를 긴밀하게 사용한다.
  • +
  • B가 A 객체의 초기값을 가지고 있다.
  • +
+

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

+

낮은 결합도 패턴(Low Coupling)

+

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

+

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

+
+

결합도(Coupling) +객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

+
+
    +
  • 오브젝트 p.17
  • +
+
+
+

결합도를 낮춘다면 다음과 같은 이점이 있다.

+
    +
  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • +
  • 재사용이 편리해진다.
  • +
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)
  • +
+

높은 응집도 패턴(High Cohesion)

+

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

+

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

+
+

응집도(Cohesion) +연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

+
+
    +
  • 오브젝트 p.26
  • +
+
+
+

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

+
    +
  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • +
  • 유지보수가 쉬워진다.
  • +
  • 낮은 결합도 또한 지원한다.
  • +
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.
  • +
+

컨트롤러 패턴(Controller)

+

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

+

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

+

어떤 서브시스템이 존재한다고 가정할 때

+
    +
  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • +
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • +
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.
  • +
+

다형성 패턴(Polymorphism)

+

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

+

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

+

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

+

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

+

변경 보호 패턴(Protected Variations)

+

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

+

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

+

간접 참조 패턴(Indirection)

+

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

+

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

+

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

+

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

+

순수한 가공물 패턴(Pure Fabrication)

+

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

+

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

+

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

+

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

+

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

+
    +
  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • +
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.
  • +
+

참고 자료

+

오브젝트 5장. 책임 할당하기, 조영호

+

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

+

GRASP, 한빛 네트워크

\ No newline at end of file diff --git a/page/42.html b/page/42.html index a5af1a4ad..c406f8d4d 100644 --- a/page/42.html +++ b/page/42.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,44 +12,60 @@ - - - + + + -
-

· 약 6분

블랙잭

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
-이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
-후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
-"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
-중간 중간 회고를 하고, 나의 소프트스킬을 높히는게 답일까?
-부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
-터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

부족했던 부분

페어 신경쓰기
+

· 약 6분

1단계: https://github.com/woowacourse/java-blackjack/pull/427
+2단계: https://github.com/woowacourse/java-blackjack/pull/537

+

블랙잭

+

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
+이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

+

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
+후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

+

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
+"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

+

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
+중간 중간 회고를 하고, 나의 소프트스킬을 높히는게 답일까?
+부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

+

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
+터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

+

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

+

부족했던 부분

+

페어 신경쓰기
이번 페어할 때 적극적으로 의견을 내보도록 했다. 그렇기에 너무 의견을 강하게 밀어붙인 느낌이 들어서 미안했다.
후추가 압박을 느꼈을 수도 있을 것 같다는 생각이 든다.
-중간 중간 작은 회고를 진행해보는 것이 좋을까?

체력 관리
+중간 중간 작은 회고를 진행해보는 것이 좋을까?

+

체력 관리
요즘 잘 못먹는 것 같다.
-앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

중간 중간 돌아보기
+앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

+

중간 중간 돌아보기
이번 미션과 관련된 내용은 아니지만 우테코를 잘 활용 하고 있는지 생각을 해봐야겠다.
-내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

새로 학습한 부분

상태 패턴
+내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

+

새로 학습한 부분

+

상태 패턴
객체의 내부 상태에 따라 스스로 행동을 변경하도록 하는 패턴으로 if/else/switch와 같은 조건문을 효과적으로 제거할 수 있다.
블랙잭 미션을 진행하면서 상태 패턴에 대한 부분을 처음 적용해보았다.
-처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

일관성, 가독성, 추상화
-이번 리뷰어는 검프🍫 였다!
+처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

+

일관성, 가독성, 추상화
+이번 리뷰어는 검프🍫 였다!
검프의 리뷰는 간결함에 관련된 내용이 많았다.
일관성이 있는 코드, 가독성이 좋은 코드, 추상화가 잘 되어있는 코드
읽기 좋고, 간결한 방향으로 코드를 작성하는 방법을 배운 것 같다.
-코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

페어에게 배울 부분

생각 정리
+코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

+

페어에게 배울 부분

+

생각 정리
중간 중간 현재 상황에 대해 그림을 그리거나, 글을 적으면서 정리한다.
페어와 동일한 부분을 이해하고 있는지 확인한다.
진행하는데 매우 도움이 되었던 것 같다.
-나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

가감없이 의견을 말해주는 부분
+나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

+

가감없이 의견을 말해주는 부분
진행 상황에 대한 부분, 진행 속도, 지금 자신이 이해하고 있는 부분을 말해줘서 편했다.
-회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

도메인 언어에 신경쓰는 부분
+회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

+

도메인 언어에 신경쓰는 부분
클래스명, 변수명과 같은 언어를 세심하게 신경쓴다.
-요구사항 정리도 깔끔하게 잘하는 것 같다.

후추 최고 👍

- - +요구사항 정리도 깔끔하게 잘하는 것 같다.

+

후추 최고 👍

\ No newline at end of file diff --git a/page/43.html b/page/43.html index 49003abce..ac8fc72c6 100644 --- a/page/43.html +++ b/page/43.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,46 +12,150 @@ - - - + + + -
-

· 약 11분

사다리 타기

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
-이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

2단계에서는 2가지 방법으로 구현해봤다.

  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법

Position 기준으로 사다리 게임을 진행하는 방법

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
+

· 약 11분

1단계: https://github.com/woowacourse/java-ladder/pull/97
+2단계: https://github.com/woowacourse/java-ladder/pull/234

+

사다리 타기

+

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
+이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

+

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

+

2단계에서는 2가지 방법으로 구현해봤다.

+
    +
  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. +
  3. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법
  4. +
+

Position 기준으로 사다리 게임을 진행하는 방법

+

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
구현하고 나니 다른 클래스들이 Position에 대한 의존도가 너무 높은 것 같았다.
-또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

public LadderGameResult play() {
final Map<Player, Item> result = new LinkedHashMap<>();
// 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
for (Position position : Position.range(players.count())) {
final Position resultPosition = ladder.play(position);
result.put(players.get(position), items.get(resultPosition));
}
return new LadderGameResult(result);
}

Player에게 Ladder를 전달하여 게임을 진행하는 방법

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
-이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

public LadderGameResult play() {
// 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
final Map<Player, Position> playResult = players.play(ladder);

final Map<Player, Item> result = new LinkedHashMap<>();
for (Player player : playResult.keySet()) {
result.put(player, toItem(playResult.get(player)));
}
return new LadderGameResult(result);
}

부족했던 부분

유비쿼터스 언어에 시간을 들이기
+또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

+ +
public LadderGameResult play() {
+    final Map<Player, Item> result = new LinkedHashMap<>();
+    // 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
+    for (Position position : Position.range(players.count())) {
+        final Position resultPosition = ladder.play(position);
+        result.put(players.get(position), items.get(resultPosition));
+    }
+    return new LadderGameResult(result);
+}
+
+

Player에게 Ladder를 전달하여 게임을 진행하는 방법

+

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
+이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

+ +
public LadderGameResult play() {
+    // 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
+    final Map<Player, Position> playResult = players.play(ladder);
+
+    final Map<Player, Item> result = new LinkedHashMap<>();
+    for (Player player : playResult.keySet()) {
+        result.put(player, toItem(playResult.get(player)));
+    }
+    return new LadderGameResult(result);
+}
+
+

부족했던 부분

+

유비쿼터스 언어에 시간을 들이기
유비쿼터스 언어를 정하는데 시간을 조금 더 들여야겠다고 생각했다.
사다리 타기의 실행 결과를 Item으로 짓다니.. 뭔가 만족스럽지 않다.
-이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

페어와 조금 더 친해지기
+이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

+

페어와 조금 더 친해지기
첫날은 페어와 친해지는 시간을 조금 더 가져야겠다고 생각했다.
-우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

README를 조금 더 꼼꼼하게
+우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

+

README를 조금 더 꼼꼼하게
이상하게 코딩에 집중하면 README를 업데이트하면서 같이 커밋 하는 걸 항상 까먹는다.
-다음 미션에는 조금 더 신경 써야겠다.

좋은 질문을 생각하기
+다음 미션에는 조금 더 신경 써야겠다.

+

좋은 질문을 생각하기
첫 PR때 리뷰어에게 질문을 남기지 못했다.
-리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

PR 후에도 꼼꼼하게 확인하기
+리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

+

PR 후에도 꼼꼼하게 확인하기
분명 알고 있는 부분이지만, 놓친 부분이 많은 것 같았다.
PR 하기 전에도 계속 확인을 했지만, 아무래도 IntelliJ에서 보니 코드에 익숙해져서 그런지 변경해야 할 부분이 잘 안보였다.
-github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

적극적으로 나의 의견을 말하기
+github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

+

적극적으로 나의 의견을 말하기
의견을 적극적으로 내는 부분에 대해서 페어의 의견이 괜찮다고 생각하면 수용 후 개선을 하는 방향으로 진행을 했었는데, 조금 더 개선할 수 있는 방향이 있다면 나도 적극적으로 의견을 말해야겠다고 생각이 든다.
-나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

새로 학습한 부분

객체의 생성 책임
+나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

+

새로 학습한 부분

+

객체의 생성 책임
Players가 Position을 생성하고 Player의 생성자에 넣어주었다. 하지만 이 부분에 대해서 생성 책임에 관련된 코멘트가 달렸다. -시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A를 긴밀하게 사용한다.
  • B가 A의 초깃값을 가지고 있다.

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

패키지 분리 기준
+시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

+

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

+
    +
  • B가 A 객체를 포함 또는 참조한다.
  • +
  • B가 A 객체를 기록한다.
  • +
  • B가 A를 긴밀하게 사용한다.
  • +
  • B가 A의 초깃값을 가지고 있다.
  • +
+

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

+

패키지 분리 기준
패키지 분리에 대한 나만의 기준이 아직 명확하지 않아 질문이 들어와도 명확하게 답변을 하지 못했다.
마지막 제출 전에 도메인 패키지 내부를 분리해 봤는데, 기준이 명확하지 않았기 때문에 좋지 않은 선택이었던 것 같다. -현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
-Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(0~19)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
-이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0~19의 값이 보장되어 있다고 생각할 것이기 때문이다.
-따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

페어에게 배울 부분

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
+현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

+

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
+Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(019)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
+이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0
19의 값이 보장되어 있다고 생각할 것이기 때문이다.
+따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

+

페어에게 배울 부분

+

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
이번에 페어 할 때 컨디션 관리를 제대로 못해서 많이 미안했다. 다음에는 최상의 컨디션으로 페어를 준비해 봐야겠다.
-그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
+그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

+

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
또한 페어 진행이 느린 것 같다고 말해줘서 안정적으로 시간 안에 미션을 완료할 수 있었다.
-페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
+페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

+

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
웃는 것만으로도 사람이 밝아 보여서 너무 좋은 것 같다!

- - \ No newline at end of file diff --git a/page/44.html b/page/44.html index 20e398b32..eb30d7111 100644 --- a/page/44.html +++ b/page/44.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,40 +12,90 @@ - - - + + + -
-

· 약 8분

자동차 경주

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
-우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
-시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
-mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
-리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

부족했던 부분

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
-객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
+

· 약 8분

1단계: https://github.com/woowacourse/java-racingcar/pull/510
+2단계: https://github.com/woowacourse/java-racingcar/pull/538

+

자동차 경주

+

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
+우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

+

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
+시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

+

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
+mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

+
    +
  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • +
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.
  • +
+ +

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

+

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
+리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

+

부족했던 부분

+

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
+객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

+

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
내가 좋아하는 주제, 관심가는 주제인 프로그래밍에 대한 이야기를 할 땐 말이 많아진다.
-다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

새로 학습한 부분

Assertions extracting

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
-이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

@Test
void extracting() {
final Cars cars = new Cars(List.of("car1", "car2"));

assertThat(cars.getCars())
.extracting(Car::getName)
.containsExactly("car1", "car2");
}

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

제어할 수 없는 부분에 대한 테스트

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
-이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

단순 위임을 하는 메서드에 대한 테스트

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
+다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

+

새로 학습한 부분

+

Assertions extracting

+

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
+이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

+
@Test
+void extracting() {
+    final Cars cars = new Cars(List.of("car1", "car2"));
+
+    assertThat(cars.getCars())
+            .extracting(Car::getName)
+            .containsExactly("car1", "car2");
+}
+
+
+

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

+

제어할 수 없는 부분에 대한 테스트

+

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
+이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

+

단순 위임을 하는 메서드에 대한 테스트

+

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
호출 횟수를 검증하는 것보다 결과에 대한 테스트하는 것이 좋다.
단순히 위임만 하는 테스트의 경우 결과를 검증한다면 테스트가 중복되지 않을까 생각했었다.
따라서 중복된 테스트를 줄이기 위해 내부의 메서드를 호출하는지 검증하는 방법도 있다는 것을 알게 되었지만
-안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

테스트를 위한 getter 사용

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
+안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

+

테스트를 위한 getter 사용

+

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
필요의 경우 생성해서 사용할 수 있지만, 기존에 있는 메서드들을 활용해보는 것이 더 좋은 방법이다.
-이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

페어에게 배울 부분

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
+이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

+

페어에게 배울 부분

+

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
생각을 정리한 후 자신의 의견을 명료하게 전달해주었다.
그렇기 때문에 지식을 효율적으로 습득한다.
난 생각을 잘 정리하지 않은 채로 내버려 둔 얕은 지식이 많은 것 같다. (이런 것도 아는 것이라고 할 수 있을까?)
-앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

개발에 열정을 가진 게 느껴진다.
+앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

+

개발에 열정을 가진 게 느껴진다.
나도 개발을 좋아하지만, 최근에는 의지가 약해졌었다.
-열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
+열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

+

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
칭찬은 고래도 춤추게 하던가?
-그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
+그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

+

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
이건 바로 배울 수 없지만.
나도 같이 일할 때 편한 사람, 같이 일하고 싶은 사람이 되기 위해 깊이 고민해봐야겠다.

- - \ No newline at end of file diff --git a/page/45.html b/page/45.html index b1ecc0123..4e6c9e4b8 100644 --- a/page/45.html +++ b/page/45.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,21 +12,100 @@ - - - + + + -
-

· 약 4분

테스트를 작성하다보면 매개변수에 따라 반복이 되는 테스트들이 생긴다.
-이 때 @ParameterizedTest를 사용하면 단일 테스트를 매개변수를 사용하여 여러 번 반복할 수 있다.

Argument Sources

@ParameterizedTest를 사용하려면 최소 하나 이상의 Source 애노테이션이 필요하다.
-JUnit이 제공하는 다양한 Source가 있기 때문에, 테스트에 맞춰 다양하게 사용할 수 있다.

Value Source

값을 이용하여 제공하는 형태로, 다음과 같은 타입의 값을 매개변수로 제공할 수 있다.

  • short, int, long, float, double
  • byte, char, boolean, String, Class
@ParameterizedTest
@ValueSource(ints = {1, 100, Integer.MAX_VALUE})
void valueTest(final int value) {
Assertions.assertThat(value).isPositive();
}

Null & Empty Source

null 값, 빈 값을 제공한다.
-Empty Source의 경우 다음과 같은 타입에 한해 매개변수로 제공할 수 있다.

  • String
  • java.util.List, java.util.Set, java.util.Map
  • primitive arrays — ex) int[]
  • object arrays — ex) String[]
@ParameterizedTest
@NullAndEmptySource
void nullAndEmptyTest(final String value) {
Assertions.assertThat(value).isNullOrEmpty();
}

Enum Source

EnumSource를 이용하여 Enum 또한 매개변수로 제공할 수 있다.

enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

@ParameterizedTest
@EnumSource(Day.class)
void enumTest(final Day day) {
assertThat(day).isInstanceOf(Day.class);
}

다음과 같이 mode 값을 이용하여 특징 Enum을 제외하거나, 포함시킬 수 있다. (default: Mode.Include)

@ParameterizedTest
@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)
void enumTest(final Day day) {
// MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
assertThat(day).isInstanceOf(Day.class);
}

CSV Source

csv 형식의 값을 이용하여 매개변수를 제공한다.
+

· 약 4분

테스트를 작성하다보면 매개변수에 따라 반복이 되는 테스트들이 생긴다.
+이 때 @ParameterizedTest를 사용하면 단일 테스트를 매개변수를 사용하여 여러 번 반복할 수 있다.

+

Argument Sources

+

@ParameterizedTest를 사용하려면 최소 하나 이상의 Source 애노테이션이 필요하다.
+JUnit이 제공하는 다양한 Source가 있기 때문에, 테스트에 맞춰 다양하게 사용할 수 있다.

+

Value Source

+

값을 이용하여 제공하는 형태로, 다음과 같은 타입의 값을 매개변수로 제공할 수 있다.

+
    +
  • short, int, long, float, double
  • +
  • byte, char, boolean, String, Class
  • +
+
@ParameterizedTest
+@ValueSource(ints = {1, 100, Integer.MAX_VALUE})
+void valueTest(final int value) {
+    Assertions.assertThat(value).isPositive();
+}
+
+

Null & Empty Source

+

null 값, 빈 값을 제공한다.
+Empty Source의 경우 다음과 같은 타입에 한해 매개변수로 제공할 수 있다.

+
    +
  • String
  • +
  • java.util.List, java.util.Set, java.util.Map
  • +
  • primitive arrays — ex) int[]
  • +
  • object arrays — ex) String[]
  • +
+
@ParameterizedTest
+@NullAndEmptySource
+void nullAndEmptyTest(final String value) {
+    Assertions.assertThat(value).isNullOrEmpty();
+}
+
+

Enum Source

+

EnumSource를 이용하여 Enum 또한 매개변수로 제공할 수 있다.

+
enum Day {
+    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
+}
+
+@ParameterizedTest
+@EnumSource(Day.class)
+void enumTest(final Day day) {
+    assertThat(day).isInstanceOf(Day.class);
+}
+
+

다음과 같이 mode 값을 이용하여 특징 Enum을 제외하거나, 포함시킬 수 있다. (default: Mode.Include)

+
@ParameterizedTest
+@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)
+void enumTest(final Day day) {
+    // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
+    assertThat(day).isInstanceOf(Day.class);
+}
+
+

CSV Source

+

csv 형식의 값을 이용하여 매개변수를 제공한다.
구분자의 기본값은 쉼표(,)로 구분자를 변경하고 싶을 땐 delimeter 값을 따로 전달하여 사용할 수 있다. -개인적으로 2개 정도의 값을 매개변수로 전달하는 경우 CsvSource를 사용한다.

@ParameterizedTest
@CsvSource({"1,1", "2,4", "3,9", "4,16"})
void csvTest(final int number, final int result) {
assertThat(number * number).isEqualTo(result);
}

Method Source

복잡한 타입의 값을 전달할 때 사용한다.
+개인적으로 2개 정도의 값을 매개변수로 전달하는 경우 CsvSource를 사용한다.

+
@ParameterizedTest
+@CsvSource({"1,1", "2,4", "3,9", "4,16"})
+void csvTest(final int number, final int result) {
+    assertThat(number * number).isEqualTo(result);
+}
+
+

Method Source

+

복잡한 타입의 값을 전달할 때 사용한다.
메서드명을 입력하여 매개변수를 제공하는 메서드를 지정할 수 있다.
-메서드명을 따로 입력하지 않으면 테스트명과 동일한 static 메서드가 지정된다.

@ParameterizedTest
@MethodSource
void methodTest(final List<Integer> numbers, final int count) {
assertThat(numbers).hasSize(count);
}

private static Stream<Arguments> methodTest() {
return Stream.of(
Arguments.of(List.of(1), 1),
Arguments.of(List.of(1, 2), 2),
Arguments.of(List.of(1, 2, 3), 3)
);
}

ETC.

위에서 언급한 방법 이외에도 다양한 방법으로 매개변수를 제공할 수 있다.

  • CSV 파일을 이용한 CsvFileSource
  • ArgumentsProvider 구현한 클래스를 이용하는 ArgumentsSource

참고 자료

- - +메서드명을 따로 입력하지 않으면 테스트명과 동일한 static 메서드가 지정된다.

+
@ParameterizedTest
+@MethodSource
+void methodTest(final List<Integer> numbers, final int count) {
+    assertThat(numbers).hasSize(count);
+}
+
+private static Stream<Arguments> methodTest() {
+    return Stream.of(
+            Arguments.of(List.of(1), 1),
+            Arguments.of(List.of(1, 2), 2),
+            Arguments.of(List.of(1, 2, 3), 3)
+    );
+}
+
+

ETC.

+

위에서 언급한 방법 이외에도 다양한 방법으로 매개변수를 제공할 수 있다.

+
    +
  • CSV 파일을 이용한 CsvFileSource
  • +
  • ArgumentsProvider 구현한 클래스를 이용하는 ArgumentsSource
  • +
+

참고 자료

+
\ No newline at end of file diff --git a/page/46.html b/page/46.html index f67168ce6..9476f4a0d 100644 --- a/page/46.html +++ b/page/46.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,14 +12,22 @@ - - - + + + -
-

· 약 1분

Import 자동 적용

Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly

auto-import

저장시 동작

Prefrences > Tools > Actions on Save

actions-on-save

Reformat Code: Code Reformmating

Optimize imports: 사용하지 않는 Import 제거

Rearrange: Code Style > Arrangement 설정 기반 코드 재정렬

메소드 추출, 변수 추출시 final 적용

Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier

final-modifier

- - +

· 약 1분

Import 자동 적용

+

Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly

+

auto-import

+

저장시 동작

+

Prefrences > Tools > Actions on Save

+

actions-on-save

+

Reformat Code: Code Reformmating

+

Optimize imports: 사용하지 않는 Import 제거

+

Rearrange: Code Style > Arrangement 설정 기반 코드 재정렬

+

메소드 추출, 변수 추출시 final 적용

+

Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier

+

final-modifier

\ No newline at end of file diff --git a/page/47.html b/page/47.html index 4351f5915..56065aa4c 100644 --- a/page/47.html +++ b/page/47.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,25 +12,76 @@ - - - + + + -
-

· 약 5분

nullable 타입

코틀린은 NullPointerException 예외를 최대한 발생시키지 않기 위해 타입 시스템이 설계되어 있다.
-이는 실행 시점이 아닌 컴파일 시 미리 오류가 발생할 가능성이 있는 부분을 미리 감지하여 NPE 발생의 가능성을 줄여준다.

코틀린의 경우 nullable 타입을 다음과 같이 표현한다.

val number: Int?

타입 뒤에 ?를 붙여 해당 값이 null이 될 수 있다는 것을 의미한다.
-만약 ?를 붙이지 않을 때 null을 받는 경우 컴파일 시 오류가 발생한다.

?. Safe Calls 연산자

자바에서 NPE를 발생시키지 않기 위해 null을 처리하는 가장 간단한 방법으로는 분기를 사용하는 방법이 있다.

코틀린은 안전한 호출 연산자인 ?. 연산자를 지원한다.
+

· 약 5분

nullable 타입

+

코틀린은 NullPointerException 예외를 최대한 발생시키지 않기 위해 타입 시스템이 설계되어 있다.
+이는 실행 시점이 아닌 컴파일 시 미리 오류가 발생할 가능성이 있는 부분을 미리 감지하여 NPE 발생의 가능성을 줄여준다.

+

코틀린의 경우 nullable 타입을 다음과 같이 표현한다.

+
val number: Int?
+
+

타입 뒤에 ?를 붙여 해당 값이 null이 될 수 있다는 것을 의미한다.
+만약 ?를 붙이지 않을 때 null을 받는 경우 컴파일 시 오류가 발생한다.

+

?. Safe Calls 연산자

+

자바에서 NPE를 발생시키지 않기 위해 null을 처리하는 가장 간단한 방법으로는 분기를 사용하는 방법이 있다.

+

코틀린은 안전한 호출 연산자인 ?. 연산자를 지원한다.
따라서 참조 값이 null이 아닐 경우에만 메서드 호출을 할 수 있다.
-참조 값이 null인 경우 메서드 호출이 무시되고, null을 반환한다.

public String repeat(String word) {
if (word == null) {
return null;
}
return word.repeat(2);
}

?: 엘비스 연산자

참조하려는 값이 null일 경우 기본 값을 반환하고 싶을 때는 어떻게 해야 할까?
-코틀린은 null이 아닌 경우 기본 값을 지정할 때 사용할 수 있는 엘비스 연산자를 지원한다.

public String stringSafe(String word) {
if (word == null) {
return "";
}
return word;
}

코틀린에서는 throw도 식이기 때문에 엘비스 연산자를 이용하여 예외를 던질 수 있다.
-예를 들어 사용자 정보가 있는 저장소에 찾는 사용자가 없는 경우 아래와 같이 사용할 수 있다.

userRepository.findByName(name) ?: throw IllegalArgumentException()

!! 널 아님 단언 연산자

!! 연산자를 이용한다면 강제로 어떤 값이든 non-nullable 타입으로 변경할 수 있다.
+참조 값이 null인 경우 메서드 호출이 무시되고, null을 반환한다.

+
public String repeat(String word) {
+    if (word == null) {
+        return null;
+    }
+    return word.repeat(2);
+}
+
+

?: 엘비스 연산자

+

참조하려는 값이 null일 경우 기본 값을 반환하고 싶을 때는 어떻게 해야 할까?
+코틀린은 null이 아닌 경우 기본 값을 지정할 때 사용할 수 있는 엘비스 연산자를 지원한다.

+
public String stringSafe(String word) {
+    if (word == null) {
+        return "";
+    }
+    return word;
+}
+
+

코틀린에서는 throw도 식이기 때문에 엘비스 연산자를 이용하여 예외를 던질 수 있다.
+예를 들어 사용자 정보가 있는 저장소에 찾는 사용자가 없는 경우 아래와 같이 사용할 수 있다.

+
userRepository.findByName(name) ?: throw IllegalArgumentException()
+
+

!! 널 아님 단언 연산자

+

!! 연산자를 이용한다면 강제로 어떤 값이든 non-nullable 타입으로 변경할 수 있다.
하지만 null인 값에 사용한다면 NPE가 발생하게 된다.
일반적인 경우에는 !! 연산자를 사용하는 것은 위험하다.
-사용하기 쉽지만, 리스크가 크고 혹시나 해당 값이 추후에는 null이 될 수 있기 때문에 지양해야 된다고 생각한다.

val length: Int = word!!.length

as? 안전한 캐스팅

타입 변환을 할 때 지정한 타입으로 변경할 수 없다면 ClassCastException이 발생한다.
+사용하기 쉽지만, 리스크가 크고 혹시나 해당 값이 추후에는 null이 될 수 있기 때문에 지양해야 된다고 생각한다.

+
val length: Int = word!!.length
+
+

as? 안전한 캐스팅

+

타입 변환을 할 때 지정한 타입으로 변경할 수 없다면 ClassCastException이 발생한다.
코틀린에서는 as 뒤에 ?를 붙여 안전하게 타입 변환을 할 수 있다.
-따라서 미리 변환 가능한 타입인지 확인하지 않고, 안전하게 타입을 변환 할 수 있다.

타입 변환이 불가능 할 경우 예외를 발생시키지 않고 null을 반환한다.

val value: Int? = something as? Int

List에서의 null 처리

List에는 null이 아닌 값만 반환하는 filterNotNull 유틸리티 메서드를 제공한다.

val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")
val foods = foodsWithNull.filterNotNull()

참고 자료

- - +따라서 미리 변환 가능한 타입인지 확인하지 않고, 안전하게 타입을 변환 할 수 있다.

+

타입 변환이 불가능 할 경우 예외를 발생시키지 않고 null을 반환한다.

+
val value: Int? = something as? Int
+
+

List에서의 null 처리

+

List에는 null이 아닌 값만 반환하는 filterNotNull 유틸리티 메서드를 제공한다.

+
val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")
+val foods = foodsWithNull.filterNotNull()
+
+

참고 자료

+
\ No newline at end of file diff --git a/page/48.html b/page/48.html index d8611a6f3..442a7c953 100644 --- a/page/48.html +++ b/page/48.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,20 +12,47 @@ - - - + + + -
-

· 약 2분

이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
+

· 약 2분

이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
ISO-8601을 기반으로 작성
-설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

ISO-8601

날짜와 시간에 관련된 데이터를 다루는 국제 표준

LocalDate, LocalTime, LocalDateTime

날짜와 시간을 표현하는 클래스

Instant

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
-기계의 관점에서 시간 표현

Duration, Period

간격을 표현하는 클래스

TemporalAdjusters

복잡한 날짜 조정이 필요할 때 사용
-필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}

DateTimeFormatter

날짜와 시간 포맷 클래스
-특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

ZoneId, ZoneOffset

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
-ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

Instant instant = Instant.now();
LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

참고 자료

- - +설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

+

날짜와 시간에 관련된 데이터를 다루는 국제 표준

+

LocalDate, LocalTime, LocalDateTime

+

날짜와 시간을 표현하는 클래스

+

Instant

+

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
+기계의 관점에서 시간 표현

+

Duration, Period

+

간격을 표현하는 클래스

+

TemporalAdjusters

+

복잡한 날짜 조정이 필요할 때 사용
+필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

+
@FunctionalInterface
+public interface TemporalAdjuster {
+    Temporal adjustInto(Temporal temporal);
+}
+
+

DateTimeFormatter

+

날짜와 시간 포맷 클래스
+특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

+

ZoneId, ZoneOffset

+

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
+ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

+
Instant instant = Instant.now();
+LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+
+

참고 자료

+
\ No newline at end of file diff --git a/page/49.html b/page/49.html index 4e3e72cc9..831464d8a 100644 --- a/page/49.html +++ b/page/49.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,33 +12,81 @@ - - - + + + -
-

· 약 6분

책 정보

객체지향의 사실과 오해
-조영호

읽고 나서

조영호님의 오브젝트를 읽고 나서 다시 한 번 읽어보았다.
+

· 약 6분

책 정보

+
+

객체지향의 사실과 오해
+조영호

+
+

읽고 나서

+

조영호님의 오브젝트를 읽고 나서 다시 한 번 읽어보았다.
아직 이해가 안되는 부분이 많지만, 그래도 항상 새로움을 느낀다.
-더할 나위 없이 휼륭한 객체지향 책이고, 조금 더 공부하고 다시 읽어봐야될 것 같다.

커피 전문점, 지하철 노선도, 이상한 나라의 엘리스를 예시로 든 설명이 너무 좋았고
-좋은 내용을 담고 있지만 그렇다고 너무 무겁지 않아 가볍게 읽기도 좋은 것 같다.

책임의 자율성을 강조하는 이유 p.173

협력을 단순하게 만든다.

  • 의도를 명확하게 표현 → 협력의 복잡함 저하
  • 책임의 추상화

외부와 내부를 명확하게 분리한다.

  • 요청하는 객체가 몰라도 되는 부분이 캡슐화됨으로 인터페이스와 구현의 분리

책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

  • 변경의 파급효과를 객체 내부로 캡슐화 → 메시지를 보내는 객체와의 결합도 저하

협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

  • 유연한 설계 → 재사용성 증가

객체의 역할을 이해하기 쉬워진다.

  • 응집도를 높은 상태로 유지

밑줄 친 문장들

객체지향의 목표는 실세계를 모방하는 것이 아니다. +더할 나위 없이 휼륭한 객체지향 책이고, 조금 더 공부하고 다시 읽어봐야될 것 같다.

+

커피 전문점, 지하철 노선도, 이상한 나라의 엘리스를 예시로 든 설명이 너무 좋았고
+좋은 내용을 담고 있지만 그렇다고 너무 무겁지 않아 가볍게 읽기도 좋은 것 같다.

+

책임의 자율성을 강조하는 이유 p.173

+

협력을 단순하게 만든다.

+
    +
  • 의도를 명확하게 표현 → 협력의 복잡함 저하
  • +
  • 책임의 추상화
  • +
+

외부와 내부를 명확하게 분리한다.

+
    +
  • 요청하는 객체가 몰라도 되는 부분이 캡슐화됨으로 인터페이스와 구현의 분리
  • +
+

책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

+
    +
  • 변경의 파급효과를 객체 내부로 캡슐화 → 메시지를 보내는 객체와의 결합도 저하
  • +
+

협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

+
    +
  • 유연한 설계 → 재사용성 증가
  • +
+

객체의 역할을 이해하기 쉬워진다.

+
    +
  • 응집도를 높은 상태로 유지
  • +
+

밑줄 친 문장들

+
+

객체지향의 목표는 실세계를 모방하는 것이 아니다. 오히려 새로운 세계를 창조하는 것이다. 소프트웨어 개발자의 역할은 단순히 실세계를 소프트웨어 안으로 옮겨 담는 것이 아니라 고객과 사용자를 만족시킬 수 있는 신세계를 창조하는 것이다. -p.21

과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. +p.21

+
+
+

과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. 이에 반해 객체지향에서는 데이터와 프로세스를 객체라는 하나의 틀 안에 함께 묶어 놓음으로써 객체의 자율성을 보장한다. 자율적인 객체로 구성된 공동체는 유지 보수가 쉽고 재사용이 용이한 시스템을 구축할 수 있는 가능성을 제시한다. -p.33

객체지향의 본질

시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. -p.35

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. +p.33

+
+
+

객체지향의 본질

+

시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

+

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

+

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

+

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. +p.35

+
+
+

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. 객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다. -p.38

객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행위’다. +p.38

+
+
+

객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행위’다. 클래스는 타입을 구현하기 위해 프로그래밍 언어에서 제공하는 구현 메커니즘이라는 사실을 기억하라. -p.105

책임 주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. +p.105

+
+
+

책임 주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. 이 과정을 흔히 What/Who 사이클이라고 한다. ’어떤 행위(What)’를 수행할 것인지 결정한 후 ‘누가(who)’ 그 행위를 수행할 것인지 결정해야 한다. 여기서 ‘어떤 행위’가 바로 메시지다. -p.158

- - +p.158

+
\ No newline at end of file diff --git a/page/5.html b/page/5.html index e6dd5a547..a20e4663e 100644 --- a/page/5.html +++ b/page/5.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,36 +12,70 @@ - - - + + + -
-

· 약 8분

웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+

· 약 8분

웹 애플리케이션 발전 과정

+

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.
-원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.

WWW(1989)

정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.

CGI(1993)

CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.

Servlet(1996)

Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.
-하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.

JSP(1999)

JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.
-JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.

MVC(2000)

위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.

I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
-Govind Seshadri

이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.
-해당 문서를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.

Spring Framework(2003)

Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.
+원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.

+ +

WWW(1989)

+

정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.

+

CGI(1993)

+

CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.

+

Servlet(1996)

+

Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.
+하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.

+

JSP(1999)

+

JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.
+JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.

+ +

MVC(2000)

+

위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.

+
+

I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
+Govind Seshadri

+
+

이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.
+해당 문서를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.

+

Spring Framework(2003)

+

Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.
J2EE는 웹 기반의 엔터프라이즈 애플리케이션을 구축하기 위한 플랫폼으로 위에서 설명한 Servlet, JSP, EJB 등의 기술을 포함하고 있다.
하지만 이중 EJB라는 기술이 J2EE의 핵심 기술이었는데, 해당 기술이 매우 복잡했기 때문에 사용에 문제가 많았다고 한다.
-2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 Expert One-to-One J2EE Development라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.

스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.

WebFlux 이전 Servlet 3.0(2009), 3.1(2013)

Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.
-그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.

Spring WebFlux(2017)

적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.
-추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.

마치며

해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.
-그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.

참고 자료

웹 애플리케이션의 발전 과정, 구구 강의
-Dynamic Content with CGI, Apache Tutorial
-History of Spring and the Spring Framework, Spring
-Understanding JavaServer Pages Model 2 architecture, Govind Seshadri
-MVC, XEROX PARC
-Expert One-to-One J2EE Development, Rod Johnson
-배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족
-Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu -WebFlux Overview, Spring -Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2
-Spring WebFlux란 무엇일까

- - +2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 Expert One-to-One J2EE Development라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.

+

스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.

+

WebFlux 이전 Servlet 3.0(2009), 3.1(2013)

+

Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.
+그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.

+

Spring WebFlux(2017)

+

적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.
+추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.

+

마치며

+

해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.
+그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.

+

참고 자료

+

웹 애플리케이션의 발전 과정, 구구 강의
+Dynamic Content with CGI, Apache Tutorial
+History of Spring and the Spring Framework, Spring
+Understanding JavaServer Pages Model 2 architecture, Govind Seshadri
+MVC, XEROX PARC
+Expert One-to-One J2EE Development, Rod Johnson
+배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족
+Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu +WebFlux Overview, Spring +Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2
+Spring WebFlux란 무엇일까

\ No newline at end of file diff --git a/page/50.html b/page/50.html index 3ebd00790..a4659c216 100644 --- a/page/50.html +++ b/page/50.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,28 +12,38 @@ - - - + + + -
-

· 약 4분

적당한 전환점, 2022년을 돌아보며

전역

약 1년 6개월간의 공군 정보보호병 생활을 마치고 전역을 했다.
-조기 전역 때문에 2021년 12월에 나왔지만, 실제 전역 날짜는 2022년이니 회고에 적어도 상관없겠지.

조금 더 미래에 대한 생각을 해볼걸 그랬다.
+

· 약 4분

적당한 전환점, 2022년을 돌아보며

+

전역

+

약 1년 6개월간의 공군 정보보호병 생활을 마치고 전역을 했다.
+조기 전역 때문에 2021년 12월에 나왔지만, 실제 전역 날짜는 2022년이니 회고에 적어도 상관없겠지.

+

조금 더 미래에 대한 생각을 해볼걸 그랬다.
전역을 했지만 뭐 하나 제대로 할 줄 아는 것도 없으니 넓은 바닷속에 덩그러니 놓아진 기분이 괜히 들었었다.
-일찍 생각을 정리하여 방향을 잡지 못했기에 아쉬움이 많이 남았다.

자바

전역을 하고 진로를 고민하다 향로님의 자바 공화국 포스팅을 읽고 나서 자바 공부를 시작했다.
+일찍 생각을 정리하여 방향을 잡지 못했기에 아쉬움이 많이 남았다.

+

자바

+

전역을 하고 진로를 고민하다 향로님의 자바 공화국 포스팅을 읽고 나서 자바 공부를 시작했다.
유명한 인프런의 김영한님의 스프링 강의도 있고, 좋은 자바 개발 서적이 많아서 독학하기로 결정했다.
하다 보니 자바와 스프링을 공부하면서 “왜 진작하지 않았지”라는 생각도 많이 들었다.
-양질의 자료도 많았기 때문에, 예전에 노드로 개발했을 때 풀지 못했던 답답함을 많이 해소했던 것 같다.

23년에는 조금 더 깊게 자바를 공부해볼 생각이다.
-언어를 하나 깊게 공부하는 건 많은 도움이 되는 것 같다.

스터디

김영한님의 강의를 거의 다 들었을 때쯤, 항상 강의에서 언급되는 토비의 스프링을 읽어보고 싶어졌고
+양질의 자료도 많았기 때문에, 예전에 노드로 개발했을 때 풀지 못했던 답답함을 많이 해소했던 것 같다.

+

23년에는 조금 더 깊게 자바를 공부해볼 생각이다.
+언어를 하나 깊게 공부하는 건 많은 도움이 되는 것 같다.

+

스터디

+

김영한님의 강의를 거의 다 들었을 때쯤, 항상 강의에서 언급되는 토비의 스프링을 읽어보고 싶어졌고
혼자 공부하기에는 동기부여도 부족했기 때문에 스터디를 시작했다.
다른 사람에게 설명을 해야 했기 때문에 더욱 꼼꼼하게 공부를 할 수 있어서 좋았지만 나에게는 내용이 꽤나 어려워서 시간을 많이 소비했다.
-같이 스터디하시는 분과 7개월 동안 스터디를 꾸준히 이어나가 총 3권의 책을 읽을 수 있었다.

우아한 테크코스

군 복무 중일 때 지원했다 떨어진 우아한 테크코스를 다시 지원했다.
+같이 스터디하시는 분과 7개월 동안 스터디를 꾸준히 이어나가 총 3권의 책을 읽을 수 있었다.

+

우아한 테크코스

+

군 복무 중일 때 지원했다 떨어진 우아한 테크코스를 다시 지원했다.
이번 연도에 취업을 하는 게 목표였지만 내가 가지고 있는 특별한 무기가 없다는 걸 깨달았다.
-적지 않은 시간을 투자해 준비를 했고, 감사하게도 이번에는 최종 합격을 했다.

난 사람들과 소통하고, 협업하는 능력이 부족하다고 생각을 많이 했다.
-우아한 테크코스를 통해 그 빈 부분을 채우도록 노력해야겠다.

2023년에는

마음의 여유가 없었던 2022년이었던 것 같다.
+적지 않은 시간을 투자해 준비를 했고, 감사하게도 이번에는 최종 합격을 했다.

+

난 사람들과 소통하고, 협업하는 능력이 부족하다고 생각을 많이 했다.
+우아한 테크코스를 통해 그 빈 부분을 채우도록 노력해야겠다.

+

2023년에는

+

마음의 여유가 없었던 2022년이었던 것 같다.
하고 싶은 건 많지만, 이번에는 여유를 가지고 할 수 있는 것에 최선을 다해야겠다.

- - \ No newline at end of file diff --git a/page/51.html b/page/51.html index 3af06b34a..9ce48ff8a 100644 --- a/page/51.html +++ b/page/51.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,19 +12,50 @@ - - - + + + -
-

· 약 5분

책 정보

글, 우리도 잘 쓸 수 있습니다.
-박솔미

읽고 나서

저자의 경험과 함께 글쓰기에 대한 가벼운 조언이 담겨있어 가볍게 읽기 좋았다.
-글을 잘 작성해 보고 싶을 때 적용해 볼 수 있는 정보가 많아서 도움이 되었다.

우아한 테크코스의 프리코스를 진행할 때 후기를 작성하고 나면 항상 글이 딱딱하다는 느낌을 받았다.
+

· 약 5분

책 정보

+
+

글, 우리도 잘 쓸 수 있습니다.
+박솔미

+
+

읽고 나서

+

저자의 경험과 함께 글쓰기에 대한 가벼운 조언이 담겨있어 가볍게 읽기 좋았다.
+글을 잘 작성해 보고 싶을 때 적용해 볼 수 있는 정보가 많아서 도움이 되었다.

+

우아한 테크코스의 프리코스를 진행할 때 후기를 작성하고 나면 항상 글이 딱딱하다는 느낌을 받았다.
다른 지원자들의 읽기 편하고, 밝은 느낌을 주는 글을 보면 부러운 마음을 가지기도 했다.
-이 책을 읽었으니 2023년에는 조금 더 글을 잘 적어보려고 한다.

밑줄 친 문장들

문장이 심심하고 지루하다면 -내용을 일목요연하게 정리했고, 글의 의도도 삐뚤지 않고, 단어도 적절한 것으로 골랐는데… 그런데도 어딘가가 심심하고 지루하다면? 축축 처지고 따분하다면? 말꼬리를 모조리 ‘~다’로 통일한 건 아닌지 점검해 보세요.

말꼬리를 잘 갖고 놀아야 합니다. 문장의 마지막 글자를 매번 다르게 고쳐쓰는 것만으로도 글에 활기를 더할 수 있죠. 때론 문장을 다 마치지 않고, 단어로만 끝맺는 것도 방법. 문장과 문장 사이에 쉼표가 들어서며 글 전체에 활기가 돌게 돼요. 문장의 길이도 다채로워지는 덕분에 덤으로 얻게 되는 것도 있습니다. 바로, 글의 리듬.

이전 문장에서 끝난 글자로, 다음 문장을 끝맺지 않기. 한두 문단마다 단어 수준의 아주 짧은 문장 배치하기.

글의 진짜 이유, 글의 진짜 목적, 글의 진짜 대상을 찾으려고 애썼습니다. 지금처럼 틀을 떠올린다거나, 눈치를 본다거나, 정치적인 셈도 하지 않았어요.

제목은 짧게, 보기 쉽게, 읽기 쉽게, 발음이 비슷하게, 순서를 바꿔서

글을 마지막으로 다듬을 때, 노래에 가까워질 방법은 없을지 고민해봅니다. 감히 가 닿을 수 없는 목표이겠지만, 할 수 있는 최소한의 리듬이라도 붙여주고 싶어요.

여는 말과 마지막 말에 작정하고 마음을 담는 연습을 해봅시다. 글의 어느 구석이라도 뻔한 글자는 남기지 않겠노라 다짐하며 써보는 겁니다. 나만이 가진 유일한 메시지에 집중하면서요. 그럼 생각이 달라지고, 고르는 단어도 달라지고, 남긴 문장도 달라져요. 결국에는 글을 쓴 사람인 나 자신도 남달라질 겁니다.

맞춤법은 중요합니다. 하지만 맞춤법보다 더 중요한 건 거기에 담긴 마음입니다. 내 마음을 글에 담아 실어 보내기 전, 맞춤법을 점검하는 이유 역시 그겁니다. 오직 내 마음이 남에게 읽히는 동안 방해가 되지 않기를 바라기 때문이죠. 내가 쓴 글도, 남이 쓴 글도. 언제나 그 안에 담긴 마음이 먼저입니다.

글을 쓴다고 글이 완성되는 게 아니에요. 글과 닮은 모습으로 살 때, 글은 비로소 완성됩니다.

- - +이 책을 읽었으니 2023년에는 조금 더 글을 잘 적어보려고 한다.

+

밑줄 친 문장들

+
+

문장이 심심하고 지루하다면 +내용을 일목요연하게 정리했고, 글의 의도도 삐뚤지 않고, 단어도 적절한 것으로 골랐는데… 그런데도 어딘가가 심심하고 지루하다면? 축축 처지고 따분하다면? 말꼬리를 모조리 ‘~다’로 통일한 건 아닌지 점검해 보세요.

+
+
+

말꼬리를 잘 갖고 놀아야 합니다. 문장의 마지막 글자를 매번 다르게 고쳐쓰는 것만으로도 글에 활기를 더할 수 있죠. 때론 문장을 다 마치지 않고, 단어로만 끝맺는 것도 방법. 문장과 문장 사이에 쉼표가 들어서며 글 전체에 활기가 돌게 돼요. 문장의 길이도 다채로워지는 덕분에 덤으로 얻게 되는 것도 있습니다. 바로, 글의 리듬.

+
+
+

이전 문장에서 끝난 글자로, 다음 문장을 끝맺지 않기. 한두 문단마다 단어 수준의 아주 짧은 문장 배치하기.

+
+
+

글의 진짜 이유, 글의 진짜 목적, 글의 진짜 대상을 찾으려고 애썼습니다. 지금처럼 틀을 떠올린다거나, 눈치를 본다거나, 정치적인 셈도 하지 않았어요.

+
+
+

제목은 짧게, 보기 쉽게, 읽기 쉽게, 발음이 비슷하게, 순서를 바꿔서

+
+
+

글을 마지막으로 다듬을 때, 노래에 가까워질 방법은 없을지 고민해봅니다. 감히 가 닿을 수 없는 목표이겠지만, 할 수 있는 최소한의 리듬이라도 붙여주고 싶어요.

+
+
+

여는 말과 마지막 말에 작정하고 마음을 담는 연습을 해봅시다. 글의 어느 구석이라도 뻔한 글자는 남기지 않겠노라 다짐하며 써보는 겁니다. 나만이 가진 유일한 메시지에 집중하면서요. 그럼 생각이 달라지고, 고르는 단어도 달라지고, 남긴 문장도 달라져요. 결국에는 글을 쓴 사람인 나 자신도 남달라질 겁니다.

+
+
+

맞춤법은 중요합니다. 하지만 맞춤법보다 더 중요한 건 거기에 담긴 마음입니다. 내 마음을 글에 담아 실어 보내기 전, 맞춤법을 점검하는 이유 역시 그겁니다. 오직 내 마음이 남에게 읽히는 동안 방해가 되지 않기를 바라기 때문이죠. 내가 쓴 글도, 남이 쓴 글도. 언제나 그 안에 담긴 마음이 먼저입니다.

+
+
+

글을 쓴다고 글이 완성되는 게 아니에요. 글과 닮은 모습으로 살 때, 글은 비로소 완성됩니다.

+
\ No newline at end of file diff --git a/page/6.html b/page/6.html index 67bcb73eb..f8011a4a4 100644 --- a/page/6.html +++ b/page/6.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,22 +12,94 @@ - - - + + + -
-

· 약 4분

문제 상황

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
-확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

비동기 예외 발생시 로깅 설정

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
-기존의 동기 예외 처리의 경우 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다.
-비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

AsyncExceptionHandler
@Slf4j
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

private static final String LOG_FORMAT = "[%s] %s";

@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
}
}

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
-getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

MDC 정보 연동 문제

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

./mdc-null.png

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

MdcTaskDecorator
public class MdcTaskDecorator implements TaskDecorator {

@Override
public Runnable decorate(final Runnable runnable) {
Map<String, String> threadContext = MDC.getCopyOfContextMap();
return () -> {
MDC.setContextMap(threadContext);
runnable.run();
};
}
}

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

AsyncConfig
@RequiredArgsConstructor
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

private final AsyncConfigurationProperties properties;

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(properties.coreSize());
executor.setMaxPoolSize(properties.maxSize());
executor.setQueueCapacity(properties.queueCapacity());

executor.setTaskDecorator(new MdcTaskDecorator());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

./mdc-not-null.png

참고 자료

spring async, baeldung
-@Async will not call by @ControllerAdvice for global exception
-Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
-TaskDecorator, Spring docs
-AsyncUncaughtExceptionHandler

- - +

· 약 4분

문제 상황

+

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
+확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

+

비동기 예외 발생시 로깅 설정

+

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

+

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
+기존의 동기 예외 처리의 경우 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다.
+비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

+
@Slf4j
+public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
+
+    private static final String LOG_FORMAT = "[%s] %s";
+
+    @Override
+    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
+        log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
+    }
+}
+
+

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
+getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

+

MDC 정보 연동 문제

+

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

+

./mdc-null.png

+

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

+
public class MdcTaskDecorator implements TaskDecorator {
+
+    @Override
+    public Runnable decorate(final Runnable runnable) {
+        Map<String, String> threadContext = MDC.getCopyOfContextMap();
+        return () -> {
+            MDC.setContextMap(threadContext);
+            runnable.run();
+        };
+    }
+}
+
+

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

+
@RequiredArgsConstructor
+@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    private final AsyncConfigurationProperties properties;
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(properties.coreSize());
+        executor.setMaxPoolSize(properties.maxSize());
+        executor.setQueueCapacity(properties.queueCapacity());
+        
+        // highlight-next-line
+        executor.setTaskDecorator(new MdcTaskDecorator());
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.initialize();
+        return executor;
+    }
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

+

./mdc-not-null.png

+

참고 자료

+

spring async, baeldung
+@Async will not call by @ControllerAdvice for global exception
+Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
+TaskDecorator, Spring docs
+AsyncUncaughtExceptionHandler

\ No newline at end of file diff --git a/page/7.html b/page/7.html index 048a645cb..b7b19caf8 100644 --- a/page/7.html +++ b/page/7.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,43 +12,210 @@ - - - + + + -
-

· 약 13분

톰캣 구현

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
-그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
-톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

다이어그램

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
+

· 약 13분

1, 2단계: https://github.com/woowacourse/jwp-dashboard-http/pull/302
+3, 4단계: https://github.com/woowacourse/jwp-dashboard-http/pull/431

+

톰캣 구현

+

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
+그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

+

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
+톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

+

다이어그램

+

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
사실 내부 구조를 깊게 공부할 시간을 가지지 못해서 각 구성 요소가 왜 해당 위치에 있는지 완벽하게 설명하지는 못하지만 미션을 진행하면서 이건 여기에 있으면 좋을 것 같은데? 라는 생각이 들면 적절한 패키지에 위치시키는 방향으로 진행을 했다.
-또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

코드 리뷰

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
-나의 리뷰어는 디노, 리뷰이는 필립이었다.

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
+또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

+ +

코드 리뷰

+

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
+나의 리뷰어는 디노, 리뷰이는 필립이었다.

+

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
한 가지 아쉬운 점은 필립에게 작성한 나의 코멘트들이 미션을 진행하면서 경험 기반으로 작성한 내용이 많아 근거가 조금 부족했고, 정리되지 않은 부분이 많았던 것 같다.
-다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

SessionConfig

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
+다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

+

SessionConfig

+

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
세션 쿠키의 이름을 가져오는 Util 클래스의 코드를 수정했는데 기본 값은 JSESSIONID 지만 설정에 따라서 세션 쿠키명을 다르게 사용할 수 있기 때문에 해당 로직이 있는 것으로 생각했다.
-기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
+기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

+

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
메인테이너인 Mark Thomas 형이 해당 로직의 경우 컴파일러가 해당 부분을 최적화 할 수 있을 거라고 기대한다고 했고, 가독성을 개선시켜보라고 조언해주셨다.
-컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
-결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

public static String getSessionCookieName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_COOKIE_NAME;
}

return result;
}

public static String getSessionUriParamName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_PARAMETER_NAME;
}

return result;
}

private static String getConfiguredSessionCookieName(Context context) {

// Priority is:
// 1. Cookie name defined in context
// 2. Cookie name configured for app
// 3. Default defined by spec
if (context != null) {
String cookieName = context.getSessionCookieName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}

SessionCookieConfig scc =
context.getServletContext().getSessionCookieConfig();
cookieName = scc.getName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}
}

return null;
}

HTTP 수업

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
+컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

+

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
+결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

+ + +
public static String getSessionCookieName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_COOKIE_NAME;
+    }
+
+    return result;
+}
+
+public static String getSessionUriParamName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_PARAMETER_NAME;
+    }
+
+    return result;
+}
+
+private static String getConfiguredSessionCookieName(Context context) {
+
+    // Priority is:
+    // 1. Cookie name defined in context
+    // 2. Cookie name configured for app
+    // 3. Default defined by spec
+    if (context != null) {
+        String cookieName = context.getSessionCookieName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+
+        SessionCookieConfig scc =
+            context.getServletContext().getSessionCookieConfig();
+        cookieName = scc.getName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+    }
+
+    return null;
+}
+
+

HTTP 수업

+

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
항상 성능 개선을 위해 애플리케이션 단에서 최적화해보려고 노력을 했지만, 더 적은 시간을 투자해서 효율적으로 성능을 개선할 수 있는 방법에 대해 알 수 있었던 수업이었다.
-HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

server:
compression:
enabled: true

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
-궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
-내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

ETag

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
+HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

+

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

+
server:
+  compression:
+    enabled: true
+
+

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
+궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
+내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

+
+

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

+
+

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

+

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

+

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐시가 더 효율적이게 된다.
-MDN

Thread 수업

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
-현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
-학습한 내용은 다음과 같다.

threads.max: Tomcat의 최대 스레드 개수
+MDN

+

Thread 수업

+

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
+현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

+

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
+학습한 내용은 다음과 같다.

+

threads.max: Tomcat의 최대 스레드 개수
max-connections: Tomcat이 유지할 수 있는 최대 커넥션 개수
-accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

마치며

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
+accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

+ +

마치며

+

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
우선순위를 잘 정하고 학습을 진행해야겠다.
-현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

참고 자료

RFC 2616
-ETag, mdn
-Apache Tomcat 8 Configuration Reference
-Apache Tomcat Tuning, Terry Cho
-maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

- - +현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

+

참고 자료

+

RFC 2616
+ETag, mdn
+Apache Tomcat 8 Configuration Reference
+Apache Tomcat Tuning, Terry Cho
+maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

\ No newline at end of file diff --git a/page/8.html b/page/8.html index c9ca0e1ab..b5e1ff22d 100644 --- a/page/8.html +++ b/page/8.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,28 +12,50 @@ - - - + + + -
-

· 약 6분

성능 테스트

API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트

시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.
-다양한 상황에 대비해서 성능 테스트를 해야한다.

./test.png

스모크 테스트(Smoke Test)

최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트

VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.
-다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.

가상 사용자(VU)

가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.
+

· 약 6분

성능 테스트

+

API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트

+

시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.
+다양한 상황에 대비해서 성능 테스트를 해야한다.

+

./test.png

+

스모크 테스트(Smoke Test)

+

최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트

+

VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.
+다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.

+

가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.
이는 다른 가상 사용자와 독립적으로 실행되며, 여러 가상 사용자를 사용하여 동시 연결을 할 수 있다.
-스레드라고 생각하면 된다.

스파이크 테스트(Spike Test)

사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트

티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.
-스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.

부하 테스트(Load Test)

목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트

일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.
-램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.

램프 업(Ramp-up)

부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간

스트레스 테스트(Stress Test)

시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트

그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.
+스레드라고 생각하면 된다.

+

스파이크 테스트(Spike Test)

+

사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트

+

티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.
+스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.

+

부하 테스트(Load Test)

+

목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트

+

일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.
+램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.

+

부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간

+

스트레스 테스트(Stress Test)

+

시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트

+

그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.
일반적으로 평균적인 목푯값 대비 작게는 50% 이상, 필요의 경우 그 이상으로 부하를 준다.
스트레스 테스트는 부하 테스트를 실행한 후에만 실행해야 한다. 부하 테스트가 이루어지지 않은 상황에서 스트레스 테스트를 실행하는 경우에는 병목 지점이나 문제 상황을 찾기 어려워진다.
-또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.

내구 테스트(Endurance Test)

평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트

흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.
-다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.

중단점 테스트(Breakpoint Test)

임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트

문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.
+또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.

+

내구 테스트(Endurance Test)

+

평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트

+

흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.
+다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.

+

중단점 테스트(Breakpoint Test)

+

임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트

+

문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.
스트레스 테스트를 성능 튜닝과 반복해서 진행한다면, 시스템을 더욱 발전시킬 수 있다.
-다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.

참고 자료

Load test types, k6
+다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.

+

참고 자료

+

Load test types, k6
자바 최적화 - 벤저민 J. 에번스, 제임스 고프, 크리스 뉴랜드
아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄

- - \ No newline at end of file diff --git a/page/9.html b/page/9.html index 665f07cfc..bb9d1151a 100644 --- a/page/9.html +++ b/page/9.html @@ -2,8 +2,8 @@ - -Blog | GG + +Blog | GG @@ -12,65 +12,440 @@ - - - + + + -
-

· 약 21분

복제(Replication)

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
-원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

복제를 하는 이유

1. 스케일 아웃

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
-이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

2. 데이터 백업

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
-따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

3. 데이터 분석

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
-마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

4. 데이터의 지리적 분산

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

바이너리 로그 파일 위치 기반 복제

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
+

· 약 21분

복제(Replication)

+

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
+원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

+

복제를 하는 이유

+

1. 스케일 아웃

+

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
+이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

+

2. 데이터 백업

+

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
+따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

+

3. 데이터 분석

+

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
+마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

+

4. 데이터의 지리적 분산

+

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

+

바이너리 로그 파일 위치 기반 복제

+

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
바이너리 로그를 통해 데이터 변경, 테이블 구조 변경, 계정이나 권한 변경에 대한 정보가 저장된다.
-MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

스레드별 역할

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
+MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

+ +

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
Replication I/O Thread: Binary 로그 이벤트를 가져와 로컬 서버의 파일(Relay Log)로 저장
-Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

바이너리 로그 방식의 문제점

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
-토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
+Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

+

바이너리 로그 방식의 문제점

+

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
+토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

+ +

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

+ +

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
하지만 여기서 C 서버에는 A 서버와 동기화가 안되었으니 조회 시 문제가 발생한다.
-뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

글로벌 트랜잭션 아이디(GTID) 기반 복제

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
-위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

GTID

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
-[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

복제 토폴로지

싱글 레플리카 복제 구성

가장 간단한 구성으로 제일 많이 사용하는 형태다.
-replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

멀티 레플리카 복제 구성

2개의 replica 서버를 사용하는 형태다.
+뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

+

글로벌 트랜잭션 아이디(GTID) 기반 복제

+

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
+위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

+

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
+[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

+

복제 토폴로지

+

싱글 레플리카 복제 구성

+

가장 간단한 구성으로 제일 많이 사용하는 형태다.
+replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

+ +

멀티 레플리카 복제 구성

+

2개의 replica 서버를 사용하는 형태다.
하나의 replica는 예비 용도로 남겨두는 형태다.
-추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

체인 복제 구성

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
-따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

듀얼 소스 복제 구성

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
+추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

+ +

체인 복제 구성

+

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
+따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

+ +

듀얼 소스 복제 구성

+

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
각 서버에서 변경된 데이터는 다른 서버에 반영된다.
목적에 따라 ACTIVE-ACTIVE 형태 또는 ACTIVE-PASSIVE 형태로 사용할 수 있다.
-ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

ACTIVE-ACTIVE, ACTIVE-PASSIVE

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
-ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

멀티 소스 복제 구성

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
-이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

바이너리 로그 방식 Replication 구성하기

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
-https://github.com/bbiac/db-replication

MySQL 환경 구성

MySQL 버전은 8.1을 사용했다.
+ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

+ +

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
+ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

+

멀티 소스 복제 구성

+

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
+이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

+ +

바이너리 로그 방식 Replication 구성하기

+

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
+https://github.com/bbiac/db-replication

+

MySQL 환경 구성

+

MySQL 버전은 8.1을 사용했다.
13306, 13307 포트를 사용해서 MySQL 서버 2대를 띄웠다.
-또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

version: '3.8'

services:
source:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-source
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13306:3306"
volumes:
- db-source:/var/lib/mysql
- db-source:/var/lib/mysql-files
- ./docker/source.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

replica:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-replica
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13307:3306"
volumes:
- db-replica:/var/lib/mysql
- db-replica:/var/lib/mysql-files
- ./docker/replica.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

volumes:
db-source:
db-replica:

networks:
mysql_network:
driver: bridge

또한 source, replica 각각 다음과 같이 db 설정을 했다.

설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
/docker/source.cnf
[mysqld]
server_id=1
log_bin=mysql-bin
sync_binlog=1

도커 실행

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
--d 옵션을 붙이면 백그라운드 모드로 실행된다.

docker-compose up -d

replication slave 권한 설정

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
-source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

SOURCE 접속

docker exec -it mysql-source mysql -u root -p

user 계정에 REPLICATION SLAVE 권한 추가

GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
FLUSH PRIVILEGES;

SOURCE DB 정보 확인

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
+또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

+
version: '3.8'
+
+services:
+  source:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-source
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13306:3306"
+    volumes:
+      - db-source:/var/lib/mysql
+      - db-source:/var/lib/mysql-files
+      - ./docker/source.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+  replica:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-replica
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13307:3306"
+    volumes:
+      - db-replica:/var/lib/mysql
+      - db-replica:/var/lib/mysql-files
+      - ./docker/replica.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+volumes:
+  db-source:
+  db-replica:
+
+networks:
+  mysql_network:
+    driver: bridge
+
+

또한 source, replica 각각 다음과 같이 db 설정을 했다.

+
설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
+ + +
[mysqld]
+server_id=1
+log_bin=mysql-bin
+sync_binlog=1
+
+

도커 실행

+

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
+-d 옵션을 붙이면 백그라운드 모드로 실행된다.

+
docker-compose up -d
+
+

replication slave 권한 설정

+

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
+source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

+

SOURCE 접속

+
docker exec -it mysql-source mysql -u root -p
+
+

user 계정에 REPLICATION SLAVE 권한 추가

+
GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
+FLUSH PRIVILEGES;
+
+

SOURCE DB 정보 확인

+

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
Position 값은 실제 파일의 바이트 수를 의미한다.
-확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 1082 | | | |
+------------------+----------+--------------+------------------+-------------------+

SOURCE ip 주소 확인

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
-다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
-확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

replica mysql 접속

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

docker exec -it mysql-replica mysql -u root -p

replica 설정

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
+확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

+
SHOW MASTER STATUS;
+
++------------------+----------+--------------+------------------+-------------------+
+| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
++------------------+----------+--------------+------------------+-------------------+
+| mysql-bin.000003 |     1082 |              |                  |                   |
++------------------+----------+--------------+------------------+-------------------+
+
+

SOURCE ip 주소 확인

+

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
+다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

+
docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source
+
+

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
+확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

+

replica mysql 접속

+

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

+
docker exec -it mysql-replica mysql -u root -p
+
+

replica 설정

+

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
실제 DB 서버에서 복제하는 경우 추가적으로 source DB의 파일을 복제해야하지만 현재 복제할 데이터가 없기 때문에 해당 부분은 생략했다.
-SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

STOP REPLICA;

CHANGE REPLICATION SOURCE TO
SOURCE_HOST='172.29.0.2',
SOURCE_USER='user',
SOURCE_PASSWORD='password',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=0,
GET_SOURCE_PUBLIC_KEY=1;

START REPLICA;

설정 확인

SHOW REPLICA STATUS;

+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
-replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

CREATE TABLE member
(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);

스프링 부트로 DB 접근하기

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

Environment 설정

다음과 같이 source, replica로 구분하여 설정한다.

application.yml
spring:
datasource:
source:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13306/db
replica:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13307/db

DataSourceType 설정

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
-Key는 추후에 빈 설정에 사용한다.

DataSourceType
public enum DataSourceType {
SOURCE(SOURCE_NAME),
REPLICA(REPLICA_NAME),
;

private final String key;

DataSourceType(String key) {
this.key = key;
}

public static class Key {
public static final String ROUTING_NAME = "ROUTING";
public static final String SOURCE_NAME = "SOURCE";
public static final String REPLICA_NAME = "REPLICA";
}
}

AbstractRoutingDataSource 설정

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
RoutingDataSource
public class RoutingDataSource extends AbstractRoutingDataSource {

private final Logger log = LoggerFactory.getLogger(getClass());

public static RoutingDataSource from(Map<Object, Object> dataSources) {
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
routingDataSource.setTargetDataSources(dataSources);
return routingDataSource;
}

@Override
protected Object determineCurrentLookupKey() {
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();

if (readOnly) {
log.info("readOnly = true, request to replica");
return DataSourceType.REPLICA;
}
log.info("readOnly = false, request to source");
return DataSourceType.SOURCE;
}
}

DataSource 설정

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
+SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

+
STOP REPLICA;
+
+CHANGE REPLICATION SOURCE TO 
+SOURCE_HOST='172.29.0.2', 
+SOURCE_USER='user', 
+SOURCE_PASSWORD='password', 
+SOURCE_LOG_FILE='mysql-bin.000001', 
+SOURCE_LOG_POS=0, 
+GET_SOURCE_PUBLIC_KEY=1;
+
+START REPLICA;
+
+

설정 확인

+
SHOW REPLICA STATUS;
+
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Replica_IO_State                 | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File  | Read_Source_Log_Pos | Relay_Log_File         | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID                          | Source_Info_File        | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State                                | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Waiting for source to send event | 172.25.0.3  | user        |        3306 |            60 | mysql-bin.000003 |                1082 | mysql-relay-bin.000002 |           868 | mysql-bin.000003      | Yes                | Yes                 |                 |                     |                    |                        |                         |                             |          0 |            |            0 |                1082 |            1078 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 | No                            |             0 |               |              0 |                |                             |                1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info |         0 |                NULL | Replica has read all relay log; waiting for more updates |              86400 |             |                         |                          |                |                    |                    |                   |             0 |                      |              |                    |                        |                     1 |                   |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+
+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

+

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
+replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

+
CREATE TABLE member
+(
+    id   BIGINT PRIMARY KEY AUTO_INCREMENT,
+    name VARCHAR(255)
+);
+
+

스프링 부트로 DB 접근하기

+

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

+

Environment 설정

+

다음과 같이 source, replica로 구분하여 설정한다.

+
spring:
+  datasource:
+    source:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13306/db
+    replica:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13307/db
+
+

DataSourceType 설정

+

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
+Key는 추후에 빈 설정에 사용한다.

+
public enum DataSourceType {
+    SOURCE(SOURCE_NAME),
+    REPLICA(REPLICA_NAME),
+    ;
+
+    private final String key;
+
+    DataSourceType(String key) {
+        this.key = key;
+    }
+
+    public static class Key {
+        public static final String ROUTING_NAME = "ROUTING";
+        public static final String SOURCE_NAME = "SOURCE";
+        public static final String REPLICA_NAME = "REPLICA";
+    }
+}
+
+

AbstractRoutingDataSource 설정

+

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

+

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

+
    +
  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • +
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.
  • +
+

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

+
    +
  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • +
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
  • +
+
public class RoutingDataSource extends AbstractRoutingDataSource {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public static RoutingDataSource from(Map<Object, Object> dataSources) {
+        RoutingDataSource routingDataSource = new RoutingDataSource();
+        routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
+        routingDataSource.setTargetDataSources(dataSources);
+        return routingDataSource;
+    }
+
+    @Override
+    protected Object determineCurrentLookupKey() {
+        boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
+
+        if (readOnly) {
+            log.info("readOnly = true, request to replica");
+            return DataSourceType.REPLICA;
+        }
+        log.info("readOnly = false, request to source");
+        return DataSourceType.SOURCE;
+    }
+}
+
+

DataSource 설정

+

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
스프링은 트랜잭션 시작시에 커넥션의 사용여부와 상관없이 커넥션을 확보한다.
-따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

DataSourceConfiguration
@Configuration
public class DataSourceConfiguration {

@Bean
@Qualifier(SOURCE_NAME)
@ConfigurationProperties(prefix = "spring.datasource.source")
public DataSource sourceDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(REPLICA_NAME)
@ConfigurationProperties(prefix = "spring.datasource.replica")
public DataSource replicaDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(ROUTING_NAME)
public DataSource routingDataSource(
@Qualifier(SOURCE_NAME) DataSource sourceDataSource,
@Qualifier(REPLICA_NAME) DataSource replicaDataSource
) {
return RoutingDataSource.from(Map.of(
DataSourceType.SOURCE, sourceDataSource,
DataSourceType.REPLICA, replicaDataSource
));
}

@Bean
@Primary
public DataSource dataSource(
@Qualifier(ROUTING_NAME) DataSource routingDataSource
) {
return new LazyConnectionDataSourceProxy(routingDataSource);
}
}

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

동작 확인

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
+따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

+

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

+

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

+
@Configuration
+public class DataSourceConfiguration {
+
+    @Bean
+    @Qualifier(SOURCE_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.source")
+    public DataSource sourceDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(REPLICA_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.replica")
+    public DataSource replicaDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(ROUTING_NAME)
+    public DataSource routingDataSource(
+            @Qualifier(SOURCE_NAME) DataSource sourceDataSource,
+            @Qualifier(REPLICA_NAME) DataSource replicaDataSource
+    ) {
+        return RoutingDataSource.from(Map.of(
+                DataSourceType.SOURCE, sourceDataSource,
+                DataSourceType.REPLICA, replicaDataSource
+        ));
+    }
+
+    @Bean
+    @Primary
+    public DataSource dataSource(
+            @Qualifier(ROUTING_NAME) DataSource routingDataSource
+    ) {
+        return new LazyConnectionDataSourceProxy(routingDataSource);
+    }
+}
+
+

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

+ +

동작 확인

+

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
save 메서드의 경우 @Transactional, findById 메서드의 경우 @Transactional(readOnly = true)가 설정되어있다.
-로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

MemberServiceTest
@SpringBootTest
class MemberServiceTest {

@Autowired
private MemberService memberService;

@Test
void 사용자를_저장한다() {
// RoutingDataSource log: readOnly = false
memberService.save("bbiac");
}

@Test
void 사용자를_조회한다() {
// RoutingDataSource log: readOnly = true
assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
.isInstanceOf(NoSuchElementException.class);
}
}

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

SET GLOBAL log_output = 'table';
SET GLOBAL general_log = 1;

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
-server_id, 실행한 쿼리문을 확인할 수 있다.

SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';

+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user_host | thread_id | server_id | convert(argument using utf8) |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

SET GLOBAL general_log = 0;
SHOW VARIABLES LIKE '%general%';

+------------------+---------------------------------+
| Variable_name | Value |
+------------------+---------------------------------+
| general_log | OFF |
| general_log_file | /var/lib/mysql/4b6b9db98290.log |
+------------------+---------------------------------+

참고 자료

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
-Replication, MySQL Docs
-MySql - Master Slave Replication 구조 만들어보기
-Spring 레플리케이션 트랜잭션 처리 방식
-replication-datasource
-Simplified Guide to MySQL Replication with Docker Compose
-Dockerfile에서 자주 쓰이는 명령어
-CHANGE REPLICATION SOURCE TO Statement
-LazyConnectionDataSourceProxy
-데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
-부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
-Use Docker Compose, Docker

- - +로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

+
@SpringBootTest
+class MemberServiceTest {
+
+    @Autowired
+    private MemberService memberService;
+
+    @Test
+    void 사용자를_저장한다() {
+        // RoutingDataSource log: readOnly = false
+        memberService.save("bbiac");
+    }
+
+    @Test
+    void 사용자를_조회한다() {
+        // RoutingDataSource log: readOnly = true
+        assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
+                .isInstanceOf(NoSuchElementException.class);
+    }
+}
+
+

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

+
SET GLOBAL log_output = 'table';
+SET GLOBAL general_log = 1;
+
+

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
+server_id, 실행한 쿼리문을 확인할 수 있다.

+
SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';
+
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user_host                  | thread_id | server_id | convert(argument using utf8)                                                |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user[user] @  [172.25.0.1] |       277 |         2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+
+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

+
SET GLOBAL general_log = 0;
+SHOW VARIABLES LIKE '%general%';
+
++------------------+---------------------------------+
+| Variable_name    | Value                           |
++------------------+---------------------------------+
+| general_log      | OFF                             |
+| general_log_file | /var/lib/mysql/4b6b9db98290.log |
++------------------+---------------------------------+
+
+

참고 자료

+

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
+Replication, MySQL Docs
+MySql - Master Slave Replication 구조 만들어보기
+Spring 레플리케이션 트랜잭션 처리 방식
+replication-datasource
+Simplified Guide to MySQL Replication with Docker Compose
+Dockerfile에서 자주 쓰이는 명령어
+CHANGE REPLICATION SOURCE TO Statement
+LazyConnectionDataSourceProxy
+데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
+부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
+Use Docker Compose, Docker

\ No newline at end of file diff --git a/parameterized-tests.html b/parameterized-tests.html index fc89de6fe..1c9fbf8a0 100644 --- a/parameterized-tests.html +++ b/parameterized-tests.html @@ -2,8 +2,8 @@ - -Parameterized Tests | GG + +Parameterized Tests | GG @@ -12,21 +12,100 @@ - - - + + + -
-

Parameterized Tests

· 약 4분

테스트를 작성하다보면 매개변수에 따라 반복이 되는 테스트들이 생긴다.
-이 때 @ParameterizedTest를 사용하면 단일 테스트를 매개변수를 사용하여 여러 번 반복할 수 있다.

Argument Sources

@ParameterizedTest를 사용하려면 최소 하나 이상의 Source 애노테이션이 필요하다.
-JUnit이 제공하는 다양한 Source가 있기 때문에, 테스트에 맞춰 다양하게 사용할 수 있다.

Value Source

값을 이용하여 제공하는 형태로, 다음과 같은 타입의 값을 매개변수로 제공할 수 있다.

  • short, int, long, float, double
  • byte, char, boolean, String, Class
@ParameterizedTest
@ValueSource(ints = {1, 100, Integer.MAX_VALUE})
void valueTest(final int value) {
Assertions.assertThat(value).isPositive();
}

Null & Empty Source

null 값, 빈 값을 제공한다.
-Empty Source의 경우 다음과 같은 타입에 한해 매개변수로 제공할 수 있다.

  • String
  • java.util.List, java.util.Set, java.util.Map
  • primitive arrays — ex) int[]
  • object arrays — ex) String[]
@ParameterizedTest
@NullAndEmptySource
void nullAndEmptyTest(final String value) {
Assertions.assertThat(value).isNullOrEmpty();
}

Enum Source

EnumSource를 이용하여 Enum 또한 매개변수로 제공할 수 있다.

enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

@ParameterizedTest
@EnumSource(Day.class)
void enumTest(final Day day) {
assertThat(day).isInstanceOf(Day.class);
}

다음과 같이 mode 값을 이용하여 특징 Enum을 제외하거나, 포함시킬 수 있다. (default: Mode.Include)

@ParameterizedTest
@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)
void enumTest(final Day day) {
// MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
assertThat(day).isInstanceOf(Day.class);
}

CSV Source

csv 형식의 값을 이용하여 매개변수를 제공한다.
+

Parameterized Tests

· 약 4분

테스트를 작성하다보면 매개변수에 따라 반복이 되는 테스트들이 생긴다.
+이 때 @ParameterizedTest를 사용하면 단일 테스트를 매개변수를 사용하여 여러 번 반복할 수 있다.

+

Argument Sources

+

@ParameterizedTest를 사용하려면 최소 하나 이상의 Source 애노테이션이 필요하다.
+JUnit이 제공하는 다양한 Source가 있기 때문에, 테스트에 맞춰 다양하게 사용할 수 있다.

+

Value Source

+

값을 이용하여 제공하는 형태로, 다음과 같은 타입의 값을 매개변수로 제공할 수 있다.

+
    +
  • short, int, long, float, double
  • +
  • byte, char, boolean, String, Class
  • +
+
@ParameterizedTest
+@ValueSource(ints = {1, 100, Integer.MAX_VALUE})
+void valueTest(final int value) {
+    Assertions.assertThat(value).isPositive();
+}
+
+

Null & Empty Source

+

null 값, 빈 값을 제공한다.
+Empty Source의 경우 다음과 같은 타입에 한해 매개변수로 제공할 수 있다.

+
    +
  • String
  • +
  • java.util.List, java.util.Set, java.util.Map
  • +
  • primitive arrays — ex) int[]
  • +
  • object arrays — ex) String[]
  • +
+
@ParameterizedTest
+@NullAndEmptySource
+void nullAndEmptyTest(final String value) {
+    Assertions.assertThat(value).isNullOrEmpty();
+}
+
+

Enum Source

+

EnumSource를 이용하여 Enum 또한 매개변수로 제공할 수 있다.

+
enum Day {
+    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
+}
+
+@ParameterizedTest
+@EnumSource(Day.class)
+void enumTest(final Day day) {
+    assertThat(day).isInstanceOf(Day.class);
+}
+
+

다음과 같이 mode 값을 이용하여 특징 Enum을 제외하거나, 포함시킬 수 있다. (default: Mode.Include)

+
@ParameterizedTest
+@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)
+void enumTest(final Day day) {
+    // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
+    assertThat(day).isInstanceOf(Day.class);
+}
+
+

CSV Source

+

csv 형식의 값을 이용하여 매개변수를 제공한다.
구분자의 기본값은 쉼표(,)로 구분자를 변경하고 싶을 땐 delimeter 값을 따로 전달하여 사용할 수 있다. -개인적으로 2개 정도의 값을 매개변수로 전달하는 경우 CsvSource를 사용한다.

@ParameterizedTest
@CsvSource({"1,1", "2,4", "3,9", "4,16"})
void csvTest(final int number, final int result) {
assertThat(number * number).isEqualTo(result);
}

Method Source

복잡한 타입의 값을 전달할 때 사용한다.
+개인적으로 2개 정도의 값을 매개변수로 전달하는 경우 CsvSource를 사용한다.

+
@ParameterizedTest
+@CsvSource({"1,1", "2,4", "3,9", "4,16"})
+void csvTest(final int number, final int result) {
+    assertThat(number * number).isEqualTo(result);
+}
+
+

Method Source

+

복잡한 타입의 값을 전달할 때 사용한다.
메서드명을 입력하여 매개변수를 제공하는 메서드를 지정할 수 있다.
-메서드명을 따로 입력하지 않으면 테스트명과 동일한 static 메서드가 지정된다.

@ParameterizedTest
@MethodSource
void methodTest(final List<Integer> numbers, final int count) {
assertThat(numbers).hasSize(count);
}

private static Stream<Arguments> methodTest() {
return Stream.of(
Arguments.of(List.of(1), 1),
Arguments.of(List.of(1, 2), 2),
Arguments.of(List.of(1, 2, 3), 3)
);
}

ETC.

위에서 언급한 방법 이외에도 다양한 방법으로 매개변수를 제공할 수 있다.

  • CSV 파일을 이용한 CsvFileSource
  • ArgumentsProvider 구현한 클래스를 이용하는 ArgumentsSource

참고 자료

- - +메서드명을 따로 입력하지 않으면 테스트명과 동일한 static 메서드가 지정된다.

+
@ParameterizedTest
+@MethodSource
+void methodTest(final List<Integer> numbers, final int count) {
+    assertThat(numbers).hasSize(count);
+}
+
+private static Stream<Arguments> methodTest() {
+    return Stream.of(
+            Arguments.of(List.of(1), 1),
+            Arguments.of(List.of(1, 2), 2),
+            Arguments.of(List.of(1, 2, 3), 3)
+    );
+}
+
+

ETC.

+

위에서 언급한 방법 이외에도 다양한 방법으로 매개변수를 제공할 수 있다.

+
    +
  • CSV 파일을 이용한 CsvFileSource
  • +
  • ArgumentsProvider 구현한 클래스를 이용하는 ArgumentsSource
  • +
+

참고 자료

+
\ No newline at end of file diff --git a/performance-test-type.html b/performance-test-type.html index 42e0779ec..dd9deac1c 100644 --- a/performance-test-type.html +++ b/performance-test-type.html @@ -2,8 +2,8 @@ - -성능 테스트 종류 | GG + +성능 테스트 종류 | GG @@ -12,28 +12,50 @@ - - - + + + -
-

성능 테스트 종류

· 약 6분

성능 테스트

API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트

시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.
-다양한 상황에 대비해서 성능 테스트를 해야한다.

./test.png

스모크 테스트(Smoke Test)

최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트

VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.
-다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.

가상 사용자(VU)

가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.
+

성능 테스트 종류

· 약 6분

성능 테스트

+

API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트

+

시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.
+다양한 상황에 대비해서 성능 테스트를 해야한다.

+

./test.png

+

스모크 테스트(Smoke Test)

+

최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트

+

VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.
+다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.

+

가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.
이는 다른 가상 사용자와 독립적으로 실행되며, 여러 가상 사용자를 사용하여 동시 연결을 할 수 있다.
-스레드라고 생각하면 된다.

스파이크 테스트(Spike Test)

사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트

티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.
-스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.

부하 테스트(Load Test)

목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트

일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.
-램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.

램프 업(Ramp-up)

부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간

스트레스 테스트(Stress Test)

시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트

그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.
+스레드라고 생각하면 된다.

+

스파이크 테스트(Spike Test)

+

사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트

+

티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.
+스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.

+

부하 테스트(Load Test)

+

목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트

+

일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.
+램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.

+

부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간

+

스트레스 테스트(Stress Test)

+

시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트

+

그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.
일반적으로 평균적인 목푯값 대비 작게는 50% 이상, 필요의 경우 그 이상으로 부하를 준다.
스트레스 테스트는 부하 테스트를 실행한 후에만 실행해야 한다. 부하 테스트가 이루어지지 않은 상황에서 스트레스 테스트를 실행하는 경우에는 병목 지점이나 문제 상황을 찾기 어려워진다.
-또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.

내구 테스트(Endurance Test)

평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트

흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.
-다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.

중단점 테스트(Breakpoint Test)

임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트

문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.
+또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.

+

내구 테스트(Endurance Test)

+

평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트

+

흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.
+다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.

+

중단점 테스트(Breakpoint Test)

+

임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트

+

문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.
스트레스 테스트를 성능 튜닝과 반복해서 진행한다면, 시스템을 더욱 발전시킬 수 있다.
-다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.

참고 자료

Load test types, k6
+다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.

+

참고 자료

+

Load test types, k6
자바 최적화 - 벤저민 J. 에번스, 제임스 고프, 크리스 뉴랜드
-아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄

- - +아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄

\ No newline at end of file diff --git a/racing-car-retrospective.html b/racing-car-retrospective.html index d3f1934fb..5147f5c9d 100644 --- a/racing-car-retrospective.html +++ b/racing-car-retrospective.html @@ -2,8 +2,8 @@ - -자동차 경주 미션 회고 | GG + +자동차 경주 미션 회고 | GG @@ -12,40 +12,90 @@ - - - + + + -
-

자동차 경주 미션 회고

· 약 8분

자동차 경주

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
-우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
-시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
-mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
-리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

부족했던 부분

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
-객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
+

자동차 경주 미션 회고

· 약 8분

1단계: https://github.com/woowacourse/java-racingcar/pull/510
+2단계: https://github.com/woowacourse/java-racingcar/pull/538

+

자동차 경주

+

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
+우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

+

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
+시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

+

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
+mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

+
    +
  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • +
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.
  • +
+ +

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

+

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
+리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

+

부족했던 부분

+

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
+객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

+

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
내가 좋아하는 주제, 관심가는 주제인 프로그래밍에 대한 이야기를 할 땐 말이 많아진다.
-다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

새로 학습한 부분

Assertions extracting

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
-이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

@Test
void extracting() {
final Cars cars = new Cars(List.of("car1", "car2"));

assertThat(cars.getCars())
.extracting(Car::getName)
.containsExactly("car1", "car2");
}

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

제어할 수 없는 부분에 대한 테스트

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
-이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

단순 위임을 하는 메서드에 대한 테스트

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
+다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

+

새로 학습한 부분

+

Assertions extracting

+

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
+이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

+
@Test
+void extracting() {
+    final Cars cars = new Cars(List.of("car1", "car2"));
+
+    assertThat(cars.getCars())
+            .extracting(Car::getName)
+            .containsExactly("car1", "car2");
+}
+
+
+

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

+

제어할 수 없는 부분에 대한 테스트

+

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
+이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

+

단순 위임을 하는 메서드에 대한 테스트

+

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
호출 횟수를 검증하는 것보다 결과에 대한 테스트하는 것이 좋다.
단순히 위임만 하는 테스트의 경우 결과를 검증한다면 테스트가 중복되지 않을까 생각했었다.
따라서 중복된 테스트를 줄이기 위해 내부의 메서드를 호출하는지 검증하는 방법도 있다는 것을 알게 되었지만
-안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

테스트를 위한 getter 사용

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
+안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

+

테스트를 위한 getter 사용

+

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
필요의 경우 생성해서 사용할 수 있지만, 기존에 있는 메서드들을 활용해보는 것이 더 좋은 방법이다.
-이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

페어에게 배울 부분

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
+이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

+

페어에게 배울 부분

+

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
생각을 정리한 후 자신의 의견을 명료하게 전달해주었다.
그렇기 때문에 지식을 효율적으로 습득한다.
난 생각을 잘 정리하지 않은 채로 내버려 둔 얕은 지식이 많은 것 같다. (이런 것도 아는 것이라고 할 수 있을까?)
-앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

개발에 열정을 가진 게 느껴진다.
+앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

+

개발에 열정을 가진 게 느껴진다.
나도 개발을 좋아하지만, 최근에는 의지가 약해졌었다.
-열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
+열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

+

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
칭찬은 고래도 춤추게 하던가?
-그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
+그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

+

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
이건 바로 배울 수 없지만.
-나도 같이 일할 때 편한 사람, 같이 일하고 싶은 사람이 되기 위해 깊이 고민해봐야겠다.

- - +나도 같이 일할 때 편한 사람, 같이 일하고 싶은 사람이 되기 위해 깊이 고민해봐야겠다.

\ No newline at end of file diff --git a/refactoring-retrospective.html b/refactoring-retrospective.html index 480ff66f7..c9ee0ae24 100644 --- a/refactoring-retrospective.html +++ b/refactoring-retrospective.html @@ -2,8 +2,8 @@ - -레거시 코드 리팩터링 미션 회고 | GG + +레거시 코드 리팩터링 미션 회고 | GG @@ -12,34 +12,66 @@ - - - + + + -
-

레거시 코드 리팩터링 미션 회고

· 약 9분

리팩터링 미션

요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.
-미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.

1, 2단계

1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. +

레거시 코드 리팩터링 미션 회고

· 약 9분

1단계: https://github.com/woowacourse/jwp-refactoring/pull/465
+2단계: https://github.com/woowacourse/jwp-refactoring/pull/547
+3단계: https://github.com/woowacourse/jwp-refactoring/pull/610
+4단계: https://github.com/woowacourse/jwp-refactoring/pull/721

+

리팩터링 미션

+

요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.
+미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.

+

1, 2단계

+

1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. 요구사항을 작성할 때 제공된 용어 사전을 최대한 활용하면서 기존의 코드를 보면서 요구사항을 정리했다. -테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.

최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.
-리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.

2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.
+테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.

+

최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.
+리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.

+

2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.
서비스에서 도메인을 직접 반환하는 구조였는데, 도메인에 JPA를 적용하면 기존 명세와 달라질 것을 우려해서 DTO로 수정하는 작업을 먼저 진행했다. DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최종적으로 JPA를 적용하는 순서로 리팩터링을 진행했다. -이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.

소프트웨어의 복잡성을 다루는 지혜

중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.
-소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 도메인 주도 설계의 부제이다.

도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.
-유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.

간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.

단어설명
도메인소프트웨어로 해결하고자 하는 문제 영역
바운디드 컨텍스트해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위
유비쿼터스 언어프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어
전략적 설계도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정
전술적 설계전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정

이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.

3, 4단계

제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.

3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. -함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.

의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. -처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.

4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.
+이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.

+

소프트웨어의 복잡성을 다루는 지혜

+

중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.
+소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 도메인 주도 설계의 부제이다.

+

도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.
+유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.

+

간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.

+
단어설명
도메인소프트웨어로 해결하고자 하는 문제 영역
바운디드 컨텍스트해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위
유비쿼터스 언어프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어
전략적 설계도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정
전술적 설계전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정
+

이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.

+

3, 4단계

+

제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.

+

3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. +함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.

+

의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. +처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.

+

4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.
3단계에서는 함께 생성되고 삭제되는 객체 기준으로 분리했다. 4단계에서는 내가 인식하기 편한 기준으로 분리를 했다. -아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.

추가로 테스트 격리를 위한 @ServiceTest 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. -따라서 TestFixtures를 사용하여 해결했다.

마무리

우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.
-바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.

참고 자료

도메인 원정대, 우아콘 2021
-우아한객체지향, 우아한테크세미나
-TestFixtures, 권남님

- - +아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.

+ +

추가로 테스트 격리를 위한 직접 작성한 @ServiceTest 커스텀 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. +따라서 TestFixtures를 사용하여 해결했다.

+

마무리

+

우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.
+바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.

+

참고 자료

+

도메인 원정대, 우아콘 2021
+우아한객체지향, 우아한테크세미나
+TestFixtures, 권남님

\ No newline at end of file diff --git a/route-image-async-with-event.html b/route-image-async-with-event.html index eb3090c7d..1c6aa2693 100644 --- a/route-image-async-with-event.html +++ b/route-image-async-with-event.html @@ -2,8 +2,8 @@ - -경로 이미지 생성하기 - 비동기 처리 | GG + +경로 이미지 생성하기 - 비동기 처리 | GG @@ -12,40 +12,217 @@ - - - + + + -
-

경로 이미지 생성하기 - 비동기 처리

· 약 12분

이전 글

경로 이미지 생성하기 - 기술 선택
-경로 이미지 생성하기 - 구현

개요

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
+

경로 이미지 생성하기 - 비동기 처리

· 약 12분

이전 글

+

경로 이미지 생성하기 - 기술 선택
+경로 이미지 생성하기 - 구현

+

개요

+

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
경로 이미지 생성의 경우 위치 정보의 개수에 정비례하여 생성 시간이 증가한다.
-따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

주기능의 응답속도 개선

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
+따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

+

주기능의 응답속도 개선

+

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
하지만 현재 여행 종료와 감상 생성의 응답 속도가 경로 이미지 생성 시간에 영향을 받고 있다.
경로 이미지 생성은 비동기 처리하여도 애플리케이션 사용에 문제가 되지 않는다.
-소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

확장성 대비

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
+소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

+

확장성 대비

+

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
조금 더 짧은 간격으로 위치 정보를 그리는 경우 하나의 여행에 많은 위치 정보가 저장될 수밖에 없고 따라서 경로 이미지 생성에 걸리는 시간이 더 길어질 수 있다.
-따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

비동기 처리

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

비동기 설정

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
-해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig {
}

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. -7.7. Task Execution and Scheduling, Spring Boot Docs

@Async 적용

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

RouteImageGenerator
@Async
public void generate(
List<Double> latitudes,
List<Double> longitudes,
List<Double> pointedLatitudes,
List<Double> pointedLongitudes,
Long tripId
) {
// 이미지 생성
RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
Coordinates coordinates = Coordinates.of(latitudes, longitudes);
Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
drawImage(coordinates, routeImageDrawer, pointedCoordinates);

// 이미지 저장
String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());

// 자원 할당 해제
routeImageDrawer.dispose();

// 데이터베이스 값 변경
Trip trip = tripRepository.findById(tripId)
.orElseThrow();
trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}

비동기 처리시 문제점

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
-따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
-인터페이스를 사용한다면 다음과 같은 구조가 된다.

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
-따라서 이벤트를 사용하기로 했다.

이벤트 사용

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

이벤트 발행

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
+따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

+

비동기 처리

+

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

+

비동기 설정

+

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
+해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig {
+}
+
+

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

+
+

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. +7.7. Task Execution and Scheduling, Spring Boot Docs

+
+

@Async 적용

+

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

+
@Async
+public void generate(
+        List<Double> latitudes,
+        List<Double> longitudes,
+        List<Double> pointedLatitudes,
+        List<Double> pointedLongitudes,
+        Long tripId
+) {
+    // 이미지 생성
+    RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
+    Coordinates coordinates = Coordinates.of(latitudes, longitudes);
+    Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
+    drawImage(coordinates, routeImageDrawer, pointedCoordinates);
+
+    // 이미지 저장
+    String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());
+
+    // 자원 할당 해제
+    routeImageDrawer.dispose();
+
+    // 데이터베이스 값 변경
+    Trip trip = tripRepository.findById(tripId)
+        .orElseThrow();
+    trip.changeRouteImageUrl(imageUrl);
+    tripRepository.save(trip);
+}
+
+

비동기 처리시 문제점

+

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
+따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

+ +

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
+인터페이스를 사용한다면 다음과 같은 구조가 된다.

+ +

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
+따라서 이벤트를 사용하기로 했다.

+

이벤트 사용

+

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

+

이벤트 발행

+

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
스프링에서는 ApplicationEventPublisher 인터페이스를 사용하여 이벤트를 발행할 수 있다.
-해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

TripService & TripUpdateEvent
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
...

// 이벤트 발행
applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
}

public record TripUpdateEvent(Long tripId) {
}

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
+해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

+
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
+    ...
+
+    // 이벤트 발행
+    applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
+}
+
+public record TripUpdateEvent(Long tripId) {
+}
+
+

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
이벤트를 구독하는 도메인의 행위를 담고 있는 이벤트를 발행(ex. RouteImageGenerateEvent)한다면 논리적인 의존 관계가 남아있기에 이벤트를 적절히 사용했다고 보기 어렵다.
-발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

이벤트 구독

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
-이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

TransactionPhase 설정

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
+발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

+

이벤트 구독

+

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
+이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

+

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
AFTER_ROLLBACK: 트랜잭션이 롤백되는 경우 이벤트 실행
AFTER_COMPLETION: 트랜잭션이 커밋 또는 롤백 되었을 경우 이벤트 실행
-BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

TripUpdateEventHandler
@Component
public class TripUpdateEventHandler {

private final RouteImageGenerator routeImageGenerator;
private final TripRepository tripRepository;

public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
this.routeImageGenerator = routeImageGenerator;
this.tripRepository = tripRepository;
}

@Async
@TransactionalEventListener(phase = AFTER_COMMIT)
public void handle(TripUpdateEvent tripUpdateEvent) {
Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());

String imageUrl = routeImageGenerator.generate(
trip.getLatitudes(),
trip.getLongitudes(),
trip.getPointedLatitudes(),
trip.getPointedLongitudes()
);

trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}
}

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
-또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

테스트

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

@ContextConfiguration(classes = TestSyncConfig.class)
@SpringBootTest
public class TripUpdateEventHandlerIntegrationTest {

...

@Test
void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
// given
TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
.willReturn(여행());

// when
transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));

// then
then(routeImageGenerator)
.should(times(1))
.generate(any(), any(), any(), any());
}
}

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
-통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

결과

./time.png

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
-응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

참고 자료

7.7. Task Execution and Scheduling, Spring Boot Docs
-Spring Events, Baeldung
-회원시스템 이벤트기반 아키텍처 구축하기

- - +BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

+

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

+
@Component
+public class TripUpdateEventHandler {
+
+    private final RouteImageGenerator routeImageGenerator;
+    private final TripRepository tripRepository;
+
+    public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
+        this.routeImageGenerator = routeImageGenerator;
+        this.tripRepository = tripRepository;
+    }
+
+    @Async
+    @TransactionalEventListener(phase = AFTER_COMMIT)
+    public void handle(TripUpdateEvent tripUpdateEvent) {
+        Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());
+
+        String imageUrl = routeImageGenerator.generate(
+                trip.getLatitudes(),
+                trip.getLongitudes(),
+                trip.getPointedLatitudes(),
+                trip.getPointedLongitudes()
+        );
+
+        trip.changeRouteImageUrl(imageUrl);
+        tripRepository.save(trip);
+    }
+}
+
+

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
+또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

+ +

테스트

+

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

+ + +
@ContextConfiguration(classes = TestSyncConfig.class)
+@SpringBootTest
+public class TripUpdateEventHandlerIntegrationTest {
+
+    ...
+
+    @Test
+    void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
+        // given
+        TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
+        given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
+                .willReturn(여행());
+
+        // when
+        transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));
+
+        // then
+        then(routeImageGenerator)
+                .should(times(1))
+                .generate(any(), any(), any(), any());
+    }
+}
+
+

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
+통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

+

결과

+

./time.png

+

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
+응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

+

참고 자료

+

7.7. Task Execution and Scheduling, Spring Boot Docs
+Spring Events, Baeldung
+회원시스템 이벤트기반 아키텍처 구축하기

\ No newline at end of file diff --git a/route-image-implementation.html b/route-image-implementation.html index d11efd6d1..f2f8c4e12 100644 --- a/route-image-implementation.html +++ b/route-image-implementation.html @@ -2,8 +2,8 @@ - -경로 이미지 생성하기 - 구현 | GG + +경로 이미지 생성하기 - 구현 | GG @@ -12,24 +12,202 @@ - - - + + + -
-

경로 이미지 생성하기 - 구현

· 약 12분

개요

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
-경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

구현 결과

./result.png

예시 데이터는 다음과 같다.
-서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

예시 데이터
List<Double> x = List.of(
126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
);
List<Double> y = List.of(
37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
);
List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);

IMAGE_SIZE & ROUTE_SIZE

RouteImageGenerator.java
private static final int IMAGE_SIZE = 800;
private static final int ROUTE_SIZE = 600;

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
+

경로 이미지 생성하기 - 구현

· 약 12분

개요

+

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
+경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

+

구현 결과

+

./result.png

+

예시 데이터는 다음과 같다.
+서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

+
List<Double> x = List.of(
+        126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
+        126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
+);
+List<Double> y = List.of(
+        37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
+        37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
+);
+List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
+List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);
+
+

IMAGE_SIZE & ROUTE_SIZE

+
private static final int IMAGE_SIZE = 800;
+private static final int ROUTE_SIZE = 600;
+
+

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
IMAGE_SIZE는 말 그대로 이미지의 width와 height를 의미한다.
ROUTE_SIZE의 경우 상하좌우 100px 만큼의 간격을 위해 존재한다.
-따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

./600.png

사이즈 변경의 이유

255 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 800 사이즈로 변경했다.

주요 클래스

요약

클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성

의존관계

Coordinates(위도, 경도의 일급 컬렉션)

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
-Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는

Positions 계산 로직은 다음과 같다.
-위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

Coordinates.java
// 호출
// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);

private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
Double minValue = Collections.min(values);
return values.stream()
.map(value -> normalizeCoordinate(value, maxDifference, minValue))
.map(value -> mapToPosition(value, routeImageSize))
.toList();
}

private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
return (coordinate - minValue) / maxDifference;
}

private int mapToPosition(Double coordinate, Integer routeImageSize) {
return (int) (coordinate * routeImageSize);
}

위도로 예시든 내용이다.

  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  3. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.

Positions(실제 이미지 생성에 사용할 위치)

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • size: 크기를 반환한다.
  • xPositions: x 값들을 반환한다.
  • yPositions: y 값들을 반환한다.

중앙 정렬 로직은 다음과 같다.

Positions.java
public Positions align(int imageSize, int routeSize) {
int xOffset = calculateOffset(Position::x, imageSize);
int yOffset = calculateOffset(Position::y, imageSize);

return items.stream()
.map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
.collect(collectingAndThen(toList(), Positions::new));
}

private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
List<Integer> positions = items.stream()
.mapToInt(positionToInteger)
.boxed()
.toList();

int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
return imageSize / 2 - midValue;
}

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
-BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

./800.png

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

x 값 → 계산한 offset 그대로 더한다.
-y 값 → imageSize(800)에서 y + offset 값을 뺀다.

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
-그림을 그리기 위해 설정한 상수들이 존재한다.

RouteImageDrawer.java
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
// 이를 RGBA라고 부른다.
private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
// 배경 투명색
private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
// 경로를 위한 STROKE
private static final int LINE_STROKE_WIDTH = 7;
private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 위치 점을 위한 STROKE
private static final int POINT_STROKE_WIDTH = 20;
private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 안티앨리어싱 등 화질 개선을 위한 설정
private static final Map<Object, Object> renderingHints = Map.of(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
);

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

  • drawLine: 선을 그린다.
  • drawPoint: 점을 찍는다.
  • dispose: 자원 할당을 해제한다.

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

이미지 생성 Flow

1. 이미지 생성 준비

2. 선 그리기 요청

3. 위치 점 그리기 요청

4. 업로드 요청

전체 Flow

- - +따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

+

./600.png

+

사이즈 변경의 이유

+

255 * 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 * 800 사이즈로 변경했다.

+

주요 클래스

+

요약

+
클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성
+

의존관계

+ +

Coordinates(위도, 경도의 일급 컬렉션)

+

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
+Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

+
    +
  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • +
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는
  • +
+

Positions 계산 로직은 다음과 같다.
+위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

+
// 호출
+// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
+// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);
+
+private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
+    Double minValue = Collections.min(values);
+    return values.stream()
+            .map(value -> normalizeCoordinate(value, maxDifference, minValue))
+            .map(value -> mapToPosition(value, routeImageSize))
+            .toList();
+}
+
+private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
+    return (coordinate - minValue) / maxDifference;
+}
+
+private int mapToPosition(Double coordinate, Integer routeImageSize) {
+    return (int) (coordinate * routeImageSize);
+}
+
+

위도로 예시든 내용이다.

+
    +
  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. +
  3. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  4. +
  5. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.
  6. +
+

Positions(실제 이미지 생성에 사용할 위치)

+

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

+
    +
  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • +
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • +
  • size: 크기를 반환한다.
  • +
  • xPositions: x 값들을 반환한다.
  • +
  • yPositions: y 값들을 반환한다.
  • +
+

중앙 정렬 로직은 다음과 같다.

+
public Positions align(int imageSize, int routeSize) {
+    int xOffset = calculateOffset(Position::x, imageSize);
+    int yOffset = calculateOffset(Position::y, imageSize);
+
+    return items.stream()
+            .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
+            .collect(collectingAndThen(toList(), Positions::new));
+}
+
+private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
+    List<Integer> positions = items.stream()
+            .mapToInt(positionToInteger)
+            .boxed()
+            .toList();
+
+    int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
+    return imageSize / 2 - midValue;
+}
+
+

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
+BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

+

./800.png

+

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

+

x 값 → 계산한 offset 그대로 더한다.
+y 값 → imageSize(800)에서 y + offset 값을 뺀다.

+

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

+

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
+그림을 그리기 위해 설정한 상수들이 존재한다.

+
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
+// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
+// 이를 RGBA라고 부른다.
+private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
+// 배경 투명색
+private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
+// 경로를 위한 STROKE
+private static final int LINE_STROKE_WIDTH = 7;
+private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 위치 점을 위한 STROKE
+private static final int POINT_STROKE_WIDTH = 20;
+private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 안티앨리어싱 등 화질 개선을 위한 설정
+private static final Map<Object, Object> renderingHints = Map.of(
+        RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
+        RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
+        RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
+);
+
+

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

+
    +
  • drawLine: 선을 그린다.
  • +
  • drawPoint: 점을 찍는다.
  • +
  • dispose: 자원 할당을 해제한다.
  • +
+

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

+

이미지 생성 Flow

+

1. 이미지 생성 준비

+ +

2. 선 그리기 요청

+ +

3. 위치 점 그리기 요청

+ +

4. 업로드 요청

+ +

전체 Flow

+
\ No newline at end of file diff --git a/route-image-intro.html b/route-image-intro.html index 19660eb96..d2d44f319 100644 --- a/route-image-intro.html +++ b/route-image-intro.html @@ -2,8 +2,8 @@ - -경로 이미지 생성하기 - 기술 선택 | GG + +경로 이미지 생성하기 - 기술 선택 | GG @@ -12,20 +12,61 @@ - - - + + + -
-

경로 이미지 생성하기 - 기술 선택

· 약 6분

./route.png

이미지 생성의 책임

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
-따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

고려한 기술

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

  • Python의 Matplotlib
  • AWT(Abstract Window Toolkit) [최종 선택]
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)

Python & Matplotlib

데이터 시각화 라이브러리
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

  • 코드가 간단해서 유지 보수성이 좋다.
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.

Java AWT 이외의 라이브러리

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음

Java & AWT(Abstract Window Toolkit)

그래픽과 이미지를 그리기 위한 도구
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • 추가적인 api 호출을 하지 않아도 된다.

기술 선택

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
-하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

유지 보수

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
-따라서 다음과 같은 방법으로 공유하기로 했다.

  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. AWT를 사용한 부분을 문서화하여 공유한다.

레벨 3를 마무리하며 내용 추가

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
-AWT를 사용하는 부분에서 애플리케이션 실행 시간을 제외하면 파이썬과 비슷한 시간안에 이미지를 생성할 수 있었다.

- - +

경로 이미지 생성하기 - 기술 선택

· 약 6분

./route.png

+

이미지 생성의 책임

+

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
+따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

+

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

+
    +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
+

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

+

고려한 기술

+

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

+
    +
  • Python의 Matplotlib
  • +
  • AWT(Abstract Window Toolkit) [최종 선택]
  • +
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • +
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)
  • +
+

Python & Matplotlib

+

데이터 시각화 라이브러리
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

+
    +
  • 코드가 간단해서 유지 보수성이 좋다.
  • +
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • +
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.
  • +
+

Java AWT 이외의 라이브러리

+

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

+
라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음
+

Java & AWT(Abstract Window Toolkit)

+

그래픽과 이미지를 그리기 위한 도구
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

+
    +
  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • +
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • +
  • 추가적인 api 호출을 하지 않아도 된다.
  • +
+

기술 선택

+

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
+하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

+

유지 보수

+

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
+따라서 다음과 같은 방법으로 공유하기로 했다.

+
    +
  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. +
  3. AWT를 사용한 부분을 문서화하여 공유한다.
  4. +
+

레벨 3를 마무리하며 내용 추가

+

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
+AWT를 사용하는 부분에서 애플리케이션 실행 시간을 제외하면 파이썬과 비슷한 시간안에 이미지를 생성할 수 있었다.

\ No newline at end of file diff --git a/route-image-python.html b/route-image-python.html index e412672f7..f750f8108 100644 --- a/route-image-python.html +++ b/route-image-python.html @@ -2,8 +2,8 @@ - -경로 이미지 생성하기 - 파이썬 | GG + +경로 이미지 생성하기 - 파이썬 | GG @@ -12,34 +12,182 @@ - - - + + + -
-

경로 이미지 생성하기 - 파이썬

· 약 7분

개요

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

사용 기술

언어: Python 3.10
+

경로 이미지 생성하기 - 파이썬

· 약 7분

개요

+

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

+

사용 기술

+

언어: Python 3.10
이미지 생성: matplotlib
서비스: AWS Lambda, AWS API Gateway
-이미지 저장 및 URL: AWS S3, AWS CloudFront

플로우는 다음과 같다.

요구사항

./route.png

우측 상단의 경로 이미지를 생성하려고 한다.
-경로 이미지 생성에 대한 요구사항은 다음과 같다.

  • 위도, 경도로 이루어진 배열을 입력받는다.
  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.

이미지 출력 방식

  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
-파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

로컬에서 기능 구현

import time

import matplotlib.pyplot as plt


def draw(point):
start = time.time()
x, y = zip(*point)
pixel_x, pixel_y = convert_to_pixel_values(x, y)
draw_lines(pixel_x, pixel_y)
end = time.time()
print(end - start)

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)


def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
return scaled_coordinates


def draw_lines(x, y):
figure = plt.gcf()
figure.set_size_inches(5, 5)
plt.plot(x, y, c = 'w',linewidth=5)
plt.scatter(x[3],y[3], c = 'w', s = 125)
plt.axis('off')
plt.savefig('name.png', transparent=True, format='png')

point = [
[126.96352960597338, 37.590841000217125],
[126.96987292787792, 37.58435564234159],
[126.98128481452298, 37.58594375113966],
[126.99360339342958, 37.58248524741927],
[126.99867565340067, 37.56778118088622],
[127.001935378366117, 37.55985240444085],
[126.9831048919687, 37.548030119488665],
[126.97189273528845, 37.5119879225856],
[127.02689859997221, 37.48488593333883]
]

draw(point)

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

./routeImage.png

AWS Lambda

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
+이미지 저장 및 URL: AWS S3, AWS CloudFront

+

플로우는 다음과 같다.

+ +

요구사항

+

./route.png

+

우측 상단의 경로 이미지를 생성하려고 한다.
+경로 이미지 생성에 대한 요구사항은 다음과 같다.

+
    +
  • 위도, 경도로 이루어진 배열을 입력받는다.
  • +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.
  • +
+

이미지 출력 방식

+
    +
  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. +
  3. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장
  4. +
+

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
+파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

+

로컬에서 기능 구현

+
import time
+
+import matplotlib.pyplot as plt
+
+
+def draw(point):
+    start = time.time()
+    x, y = zip(*point)
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    draw_lines(pixel_x, pixel_y)
+    end = time.time()
+    print(end - start)
+    
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    return scaled_coordinates
+
+
+def draw_lines(x, y):
+    figure = plt.gcf()
+    figure.set_size_inches(5, 5)
+    plt.plot(x, y, c = 'w',linewidth=5)
+    plt.scatter(x[3],y[3], c = 'w', s = 125)
+    plt.axis('off')
+    plt.savefig('name.png', transparent=True, format='png')
+
+point = [
+    [126.96352960597338, 37.590841000217125],
+    [126.96987292787792, 37.58435564234159],
+    [126.98128481452298, 37.58594375113966],
+    [126.99360339342958, 37.58248524741927],
+    [126.99867565340067, 37.56778118088622],
+    [127.001935378366117, 37.55985240444085],
+    [126.9831048919687, 37.548030119488665],
+    [126.97189273528845, 37.5119879225856],
+    [127.02689859997221, 37.48488593333883]
+]
+
+draw(point)
+
+

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

+

./routeImage.png

+

AWS Lambda

+

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
따라서 서버리스로 파일을 처리했다.
-추가로 s3 접근은 boto3를 사용했다.

람다 S3 접근을 위한 IAM 생성

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

람다 배포용 코드

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.


import io
import uuid

import boto3
import matplotlib.pyplot as plt

PIXEL = 255
BUCKET_NAME = 'image-plot'
S3 = 's3'

def lambda_handler(event, context):
x = event['x']
y = event['y']
image_name = str(uuid.uuid4())

img_data = draw(x, y)
s3 = boto3.client(S3)
s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'

return {
'statusCode': 200,
'body': url
}

def draw(x, y):
pixel_x, pixel_y = convert_to_pixel_values(x, y)
img_data = draw_lines(pixel_x, pixel_y)
plt.close()
return img_data

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)

def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
return pixel_values

def draw_lines(x, y):
plt.plot(x, y, 'k-', linewidth=10)
plt.axis('off')
img_data = io.BytesIO()
plt.savefig(img_data, transparent=True, format='png')
img_data.seek(0)
return img_data

Layer 추가를 위한 zip 파일 생성

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
+추가로 s3 접근은 boto3를 사용했다.

+

람다 S3 접근을 위한 IAM 생성

+

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

+

람다 배포용 코드

+

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.

+

+import io
+import uuid
+
+import boto3
+import matplotlib.pyplot as plt
+
+PIXEL = 255
+BUCKET_NAME = 'image-plot'
+S3 = 's3'
+
+def lambda_handler(event, context):
+    x = event['x']
+    y = event['y']
+    image_name = str(uuid.uuid4())
+
+    img_data = draw(x, y)
+    s3 = boto3.client(S3)
+    s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
+    url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'
+
+    return {
+        'statusCode': 200,
+        'body': url
+    }
+
+def draw(x, y):
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    img_data = draw_lines(pixel_x, pixel_y)
+    plt.close()
+    return img_data
+
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
+    return pixel_values
+
+def draw_lines(x, y):
+    plt.plot(x, y, 'k-', linewidth=10)
+    plt.axis('off')
+    img_data = io.BytesIO()
+    plt.savefig(img_data, transparent=True, format='png')
+    img_data.seek(0)
+    return img_data
+
+
+

Layer 추가를 위한 zip 파일 생성

+

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
zip 파일을 만들어서 업로드해야한다.
이때 python의 Lambda 런타임에 대한 계층 경로는 python이다.
-따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

pillow.zip
│ python/PIL
└ python/Pillow-5.3.0.dist-info

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

sudo apt update
sudo apt install zip
sudo apt install python3-pip

mkdir python
pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로

No module named 'numpy.core._multiarray_umath' 에러

Layer 추가 후 람다 실행 시 발생한 에러였다.
+따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

+
pillow.zip
+│ python/PIL
+└ python/Pillow-5.3.0.dist-info
+
+

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

+
sudo apt update
+sudo apt install zip
+sudo apt install python3-pip
+
+mkdir python
+pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
+zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로
+
+

No module named 'numpy.core._multiarray_umath' 에러

+

Layer 추가 후 람다 실행 시 발생한 에러였다.
처음에 mac에서 zip 파일을 생성해서 업로드했는데 해당 문제가 발생했다.
이는 lambda가 돌아가는 동일한 환경에서 layer를 위한 zip 파일을 만들지 않아서 발생하는 문제다.
-간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

적정기술에 대한 생각

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
+간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

+

적정기술에 대한 생각

+

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
AWS Lambda를 사용하는 것은 인스턴스에 해당 코드를 배포하는 것보다 더 효율적인 방법일 수 있다.
하지만 현재 프로젝트에서 가용 가능한 자원, 기술의 난이도, 사용하는 팀원을 고려한다면 Lambda는 적정기술이 아닐 수 있다.
-따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

최종적으로 Java AWT를 사용하기로 결정했다.

참고 자료

AWS Lambda
-Lambda Layer
-Python Lambda 함수에 대한 .zip 파일 아카이브 작업
-No module named 'numpy.core._multiarray_umath'
-사례별로 알아본 안전한 S3 사용 가이드

- - +따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

+

최종적으로 Java AWT를 사용하기로 결정했다.

+

참고 자료

+

AWS Lambda
+Lambda Layer
+Python Lambda 함수에 대한 .zip 파일 아카이브 작업
+No module named 'numpy.core._multiarray_umath'
+사례별로 알아본 안전한 S3 사용 가이드

\ No newline at end of file diff --git a/rss.xml b/rss.xml index d46756a95..04b6b8447 100644 --- a/rss.xml +++ b/rss.xml @@ -14,27 +14,62 @@ https://greeng00se.github.io/refactoring-retrospective Tue, 31 Oct 2023 00:00:00 GMT -
PR 링크

리팩터링 미션

요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.
-미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.

1, 2단계

1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. +

1단계: https://github.com/woowacourse/jwp-refactoring/pull/465
+2단계: https://github.com/woowacourse/jwp-refactoring/pull/547
+3단계: https://github.com/woowacourse/jwp-refactoring/pull/610
+4단계: https://github.com/woowacourse/jwp-refactoring/pull/721

+

리팩터링 미션

+

요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.
+미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.

+

1, 2단계

+

1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. 요구사항을 작성할 때 제공된 용어 사전을 최대한 활용하면서 기존의 코드를 보면서 요구사항을 정리했다. -테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.

최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.
-리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.

2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.
+테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.

+

최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.
+리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.

+

2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.
서비스에서 도메인을 직접 반환하는 구조였는데, 도메인에 JPA를 적용하면 기존 명세와 달라질 것을 우려해서 DTO로 수정하는 작업을 먼저 진행했다. DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최종적으로 JPA를 적용하는 순서로 리팩터링을 진행했다. -이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.

소프트웨어의 복잡성을 다루는 지혜

중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.
-소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 도메인 주도 설계의 부제이다.

도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.
-유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.

간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.

단어설명
도메인소프트웨어로 해결하고자 하는 문제 영역
바운디드 컨텍스트해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위
유비쿼터스 언어프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어
전략적 설계도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정
전술적 설계전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정

이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.

3, 4단계

제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.

3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. -함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.

의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. -처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.

4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.
+이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.

+

소프트웨어의 복잡성을 다루는 지혜

+

중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.
+소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 도메인 주도 설계의 부제이다.

+

도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.
+유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.

+

간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.

+
단어설명
도메인소프트웨어로 해결하고자 하는 문제 영역
바운디드 컨텍스트해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위
유비쿼터스 언어프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어
전략적 설계도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정
전술적 설계전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정
+

이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.

+

3, 4단계

+

제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.

+

3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. +함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.

+

의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. +처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.

+

4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.
3단계에서는 함께 생성되고 삭제되는 객체 기준으로 분리했다. 4단계에서는 내가 인식하기 편한 기준으로 분리를 했다. -아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.

추가로 테스트 격리를 위한 @ServiceTest 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. -따라서 TestFixtures를 사용하여 해결했다.

마무리

우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.
-바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.

참고 자료

도메인 원정대, 우아콘 2021
-우아한객체지향, 우아한테크세미나
-TestFixtures, 권남님

]]> +아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.

+ +

추가로 테스트 격리를 위한 직접 작성한 @ServiceTest 커스텀 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. +따라서 TestFixtures를 사용하여 해결했다.

+

마무리

+

우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.
+바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.

+

참고 자료

+

도메인 원정대, 우아콘 2021
+우아한객체지향, 우아한테크세미나
+TestFixtures, 권남님

]]> Woowahan Techcourse Retrospective @@ -44,15 +79,88 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/jdbc-retrospective Tue, 10 Oct 2023 00:00:00 GMT -
PR 링크

Jdbc 구현

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
-미션 목표는 다음과 같다.

  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • 데이터베이스에 대한 이해도를 높인다.

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

JdbcTemplate

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
+

1단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267
+2단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358
+3단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448
+4단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515

+

Jdbc 구현

+

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
+미션 목표는 다음과 같다.

+
    +
  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • +
  • 데이터베이스에 대한 이해도를 높인다.
  • +
+

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

+

JdbcTemplate

+

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
템플릿 콜백 패턴을 적절하게 적용하여 중복을 비교적 간단하게 제거할 수 있었다.
-예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

public class JdbcTemplate {

private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);

private final DataSource dataSource;
private final StatementCreator statementCreator;
private final StatementExecutor statementExecutor;

public JdbcTemplate(final DataSource dataSource) {
this(dataSource, new StatementCreator(), new StatementExecutor());
}

JdbcTemplate(
final DataSource dataSource,
final StatementCreator statementCreator,
final StatementExecutor statementExecutor
) {
this.dataSource = dataSource;
this.statementCreator = statementCreator;
this.statementExecutor = statementExecutor;
}

private <T> T query(
final String sql,
final PreparedStatementCallback<T> preparedStatementCallback,
final Object... parameters
) {
final Connection connection = DataSourceUtils.getConnection(dataSource);
try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
return preparedStatementCallback.execute(preparedStatement);
} catch (final SQLException e) {
log.error(e.getMessage(), e);
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(connection, dataSource);
}
}

public void update(final String sql, final Object... parameters) {
query(sql, PreparedStatement::executeUpdate, parameters);
}

public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
if (results.size() > 1) {
throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
}
return results.stream().findAny();
}

public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
}
}

트랜잭션 적용

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
+예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

+
public class JdbcTemplate {
+
+    private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);
+
+    private final DataSource dataSource;
+    private final StatementCreator statementCreator;
+    private final StatementExecutor statementExecutor;
+
+    public JdbcTemplate(final DataSource dataSource) {
+        this(dataSource, new StatementCreator(), new StatementExecutor());
+    }
+
+    JdbcTemplate(
+            final DataSource dataSource,
+            final StatementCreator statementCreator,
+            final StatementExecutor statementExecutor
+    ) {
+        this.dataSource = dataSource;
+        this.statementCreator = statementCreator;
+        this.statementExecutor = statementExecutor;
+    }
+
+    private <T> T query(
+            final String sql,
+            final PreparedStatementCallback<T> preparedStatementCallback,
+            final Object... parameters
+    ) {
+        final Connection connection = DataSourceUtils.getConnection(dataSource);
+        try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
+            return preparedStatementCallback.execute(preparedStatement);
+        } catch (final SQLException e) {
+            log.error(e.getMessage(), e);
+            throw new DataAccessException(e);
+        } finally {
+            DataSourceUtils.releaseConnection(connection, dataSource);
+        }
+    }
+
+    public void update(final String sql, final Object... parameters) {
+        query(sql, PreparedStatement::executeUpdate, parameters);
+    }
+
+    public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+        if (results.size() > 1) {
+            throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
+        }
+        return results.stream().findAny();
+    }
+
+    public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+    }
+}
+
+

트랜잭션 적용

+

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
트랜잭션 동기화란 트랜잭션을 시작하기 위한 Connection 객체를 ThreadLocal과 같은 공간에 따로 저장 후, 필요할 때 저장된 Connection을 가져다 사용하는 방식이다.
-아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

마무리

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
+아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

+ +

마무리

+

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
꼼꼼히 코드를 봐준 리뷰어 호이 그리고 연휴 동안 계속 티키타카 하면서 재밌게 리뷰한 민트에게 감사하다.
회고 이만 끝내고 리팩터링 미션 하러가야겠다. 😊

]]> Woowahan Techcourse @@ -64,15 +172,89 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/mvc-retrospective Sat, 07 Oct 2023 00:00:00 GMT -
PR 링크

MVC 구현

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
-미션의 목표는 다음과 같았다.

  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • 점진적인 리팩토링을 경험한다.

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

애너테이션 기반 프레임워크 만들기

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
+

1단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/404
+2단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/465
+3단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/580

+

MVC 구현

+

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
+미션의 목표는 다음과 같았다.

+
    +
  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • +
  • 점진적인 리팩토링을 경험한다.
  • +
+

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

+

애너테이션 기반 프레임워크 만들기

+

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
테오가 @GetMapping이나 @PostMapping 부분도 진행하면 재밌을 것 같다고 해서 같이 진행해 보았다.
-추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  3. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

AnnotationHandlerMapping
public void initialize() {
if (!initialized.compareAndSet(false, true)) {
return;
}

final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
for (final Method method : methods) {
final ControllerInstance controller = controllers.get(method.getDeclaringClass());
final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
}

log.info("Initialized AnnotationHandlerMapping!");
handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
}

Legacy MVC와 @MVC 통합

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
+추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

+ +

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

+
    +
  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. +
  3. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  4. +
  5. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.
  6. +
+

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

+
public void initialize() {
+    if (!initialized.compareAndSet(false, true)) {
+        return;
+    }
+
+    final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
+    final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
+    for (final Method method : methods) {
+        final ControllerInstance controller = controllers.get(method.getDeclaringClass());
+        final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
+        final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
+        handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
+    }
+
+    log.info("Initialized AnnotationHandlerMapping!");
+    handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
+}
+
+

Legacy MVC와 @MVC 통합

+

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
기존의 MVC와 애너테이션이 적용된 MVC 두 개를 같이 사용할 수 있어야 헀다.
-대략적인 흐름은 다음과 같다.

  1. DispatcherServlet.service(request, response) 호출
  2. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  3. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  4. HandlerAdapter의.handle 메서드 실행
  5. View의 render 호출

웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
-간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

내용이 길어져서 다음 문서에 정리했다.

추상적인 개념 학습 방법

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory

정리

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
+대략적인 흐름은 다음과 같다.

+
    +
  1. DispatcherServlet.service(request, response) 호출
  2. +
  3. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  4. +
  5. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  6. +
  7. HandlerAdapter의.handle 메서드 실행
  8. +
  9. View의 render 호출
  10. +
+ +

웹 애플리케이션 발전 과정

+

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

+ +

내용이 길어져서 다음 문서에 정리했다.

+

추상적인 개념 학습 방법

+

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

+
개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory
+

정리

+

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
이번 미션에서 나의 리뷰어는 루카, 리뷰이는 헤나였다.
매 단계마다 꼼꼼하게 리뷰해 준 루카에게 너무 감사하고, 헤나에게 이상한 리뷰를 많이 남긴 것 같은데 꼼꼼히 반영해줘서 감사하다.
오랫동안 기다려왔던 레벨 4 미션이 하나씩 마무리 될 때 마다 아쉬움이 남는다.

]]> @@ -85,18 +267,88 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/spring-test-isolation Tue, 03 Oct 2023 00:00:00 GMT - 테스트 격리

테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 @DirtiesContext, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 @Transactional등 다양한 방법이 있다.
-해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.

Independent - FIRST

테스트끼리 서로 의존하면 안 된다.
+ 테스트 격리 +

테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 @DirtiesContext, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 @Transactional등 다양한 방법이 있다.
+해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.

+

테스트끼리 서로 의존하면 안 된다.
서로 의존하게 된다면 하나의 테스트가 실패할 때, 또 다른 하나의 테스트가 실패할 수 있다.
-다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

TestExecutionListener

스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.
-이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.

TextExecutionListner
public interface TestExecutionListener {
default void beforeTestClass(TestContext testContext) throws Exception {}
default void prepareTestInstance(TestContext testContext) throws Exception {}
default void beforeTestMethod(TestContext testContext) throws Exception {}
default void beforeTestExecution(TestContext testContext) throws Exception {}
default void afterTestExecution(TestContext testContext) throws Exception {}
default void afterTestMethod(TestContext testContext) throws Exception {}
default void afterTestClass(TestContext testContext) throws Exception {}
}

AbstractTestExecutionListener 상속하여 구현

AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.
-다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.

DatabaseCleaner

public class DatabaseCleaner extends AbstractTestExecutionListener {

private static final String TRUNCATE_TABLE_QUERY = """
SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'PUBLIC'
""";

@Override
public void afterTestMethod(TestContext testContext) {
JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);
List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);
truncateTables(jdbcTemplate, truncateTableQueries);
}

private JdbcTemplate getJdbcTemplate(TestContext testContext) {
return testContext.getApplicationContext().getBean(JdbcTemplate.class);
}

private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {
return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);
}

private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");
truncateTableQueries.forEach(jdbcTemplate::execute);
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");
}
}

Listener 등록

@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.
+다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

+

TestExecutionListener

+

스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.
+이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.

+
public interface TestExecutionListener {
+    default void beforeTestClass(TestContext testContext) throws Exception {}
+    default void prepareTestInstance(TestContext testContext) throws Exception {}
+    default void beforeTestMethod(TestContext testContext) throws Exception {}
+    default void beforeTestExecution(TestContext testContext) throws Exception {}
+    default void afterTestExecution(TestContext testContext) throws Exception {}
+    default void afterTestMethod(TestContext testContext) throws Exception {}
+    default void afterTestClass(TestContext testContext) throws Exception {}
+}
+
+

AbstractTestExecutionListener 상속하여 구현

+

AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.
+다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.

+

+public class DatabaseCleaner extends AbstractTestExecutionListener {
+
+    private static final String TRUNCATE_TABLE_QUERY = """
+            SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') 
+            FROM INFORMATION_SCHEMA.TABLES
+            WHERE TABLE_SCHEMA = 'PUBLIC'
+            """;
+
+    @Override
+    public void afterTestMethod(TestContext testContext) {
+        JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);
+        List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);
+        truncateTables(jdbcTemplate, truncateTableQueries);
+    }
+
+    private JdbcTemplate getJdbcTemplate(TestContext testContext) {
+        return testContext.getApplicationContext().getBean(JdbcTemplate.class);
+    }
+
+    private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {
+        return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);
+    }
+
+    private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {
+        jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");
+        truncateTableQueries.forEach(jdbcTemplate::execute);
+        jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");
+    }
+}
+
+
+

Listener 등록

+

@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.
mergeMode의 기본값은 REPLACE_DEFAULTS로 리스너가 이미 존재하는 경우 등록된 리스너로 변경된다.
MERGE_WITH_DEFAULTS로 설정한다면 Ordered 기준으로 순서가 결정된다.
-이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.

AcceptanceTest

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestExecutionListeners(
value = DatabaseCleaner.class,
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
)
public abstract class AcceptanceTest {

@LocalServerPort
private int port;

@BeforeEach
public void setUp() {
RestAssured.port = port;
}
}

참고 자료

The Spring TestExecutionListener, Baeldung
-인수테스트에서 테스트 격리하기, 테코블
-Eradicating Non-Determinism in Tests, martin fowler
-@SpringBootTest의 테스트 격리시키기, MangKyu

]]>
+이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.

+

+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@TestExecutionListeners(
+        value = DatabaseCleaner.class,
+        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
+)
+public abstract class AcceptanceTest {
+
+    @LocalServerPort
+    private int port;
+
+    @BeforeEach
+    public void setUp() {
+        RestAssured.port = port;
+    }
+}
+
+
+

참고 자료

+

The Spring TestExecutionListener, Baeldung
+인수테스트에서 테스트 격리하기, 테코블
+Eradicating Non-Determinism in Tests, martin fowler
+@SpringBootTest의 테스트 격리시키기, MangKyu

]]> test @@ -105,29 +357,66 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/web-application-evolution Sat, 30 Sep 2023 00:00:00 GMT - 웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+ 웹 애플리케이션 발전 과정 +

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.
-원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.

WWW(1989)

정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.

CGI(1993)

CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.

Servlet(1996)

Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.
-하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.

JSP(1999)

JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.
-JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.

MVC(2000)

위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.

I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
-Govind Seshadri

이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.
-해당 문서를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.

Spring Framework(2003)

Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.
+원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.

+ +

WWW(1989)

+

정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.

+

CGI(1993)

+

CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.

+

Servlet(1996)

+

Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.
+하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.

+

JSP(1999)

+

JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.
+JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.

+ +

MVC(2000)

+

위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.

+
+

I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
+Govind Seshadri

+
+

이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.
+해당 문서를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.

+

Spring Framework(2003)

+

Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.
J2EE는 웹 기반의 엔터프라이즈 애플리케이션을 구축하기 위한 플랫폼으로 위에서 설명한 Servlet, JSP, EJB 등의 기술을 포함하고 있다.
하지만 이중 EJB라는 기술이 J2EE의 핵심 기술이었는데, 해당 기술이 매우 복잡했기 때문에 사용에 문제가 많았다고 한다.
-2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 Expert One-to-One J2EE Development라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.

스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.

WebFlux 이전 Servlet 3.0(2009), 3.1(2013)

Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.
-그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.

Spring WebFlux(2017)

적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.
-추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.

마치며

해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.
-그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.

참고 자료

웹 애플리케이션의 발전 과정, 구구 강의
-Dynamic Content with CGI, Apache Tutorial
-History of Spring and the Spring Framework, Spring
-Understanding JavaServer Pages Model 2 architecture, Govind Seshadri
-MVC, XEROX PARC
-Expert One-to-One J2EE Development, Rod Johnson
-배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족
-Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu -WebFlux Overview, Spring -Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2
-Spring WebFlux란 무엇일까

]]>
+2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 Expert One-to-One J2EE Development라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.

+

스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.

+

WebFlux 이전 Servlet 3.0(2009), 3.1(2013)

+

Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.
+그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.

+

Spring WebFlux(2017)

+

적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.
+추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.

+

마치며

+

해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.
+그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.

+

참고 자료

+

웹 애플리케이션의 발전 과정, 구구 강의
+Dynamic Content with CGI, Apache Tutorial
+History of Spring and the Spring Framework, Spring
+Understanding JavaServer Pages Model 2 architecture, Govind Seshadri
+MVC, XEROX PARC
+Expert One-to-One J2EE Development, Rod Johnson
+배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족
+Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu +WebFlux Overview, Spring +Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2
+Spring WebFlux란 무엇일까

]]> web application
@@ -136,15 +425,90 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/log-async-exception Mon, 18 Sep 2023 00:00:00 GMT - 문제 상황

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
-확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

비동기 예외 발생시 로깅 설정

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
+ 문제 상황 +

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
+확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

+

비동기 예외 발생시 로깅 설정

+

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

+

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
기존의 동기 예외 처리의 경우 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다.
-비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

AsyncExceptionHandler
@Slf4j
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

private static final String LOG_FORMAT = "[%s] %s";

@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
}
}

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
-getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

MDC 정보 연동 문제

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

./mdc-null.png

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

MdcTaskDecorator
public class MdcTaskDecorator implements TaskDecorator {

@Override
public Runnable decorate(final Runnable runnable) {
Map<String, String> threadContext = MDC.getCopyOfContextMap();
return () -> {
MDC.setContextMap(threadContext);
runnable.run();
};
}
}

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

AsyncConfig
@RequiredArgsConstructor
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

private final AsyncConfigurationProperties properties;

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(properties.coreSize());
executor.setMaxPoolSize(properties.maxSize());
executor.setQueueCapacity(properties.queueCapacity());

executor.setTaskDecorator(new MdcTaskDecorator());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

./mdc-not-null.png

참고 자료

spring async, baeldung
-@Async will not call by @ControllerAdvice for global exception
-Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
-TaskDecorator, Spring docs
-AsyncUncaughtExceptionHandler

]]>
+비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

+
@Slf4j
+public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
+
+    private static final String LOG_FORMAT = "[%s] %s";
+
+    @Override
+    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
+        log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
+    }
+}
+
+

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
+getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

+

MDC 정보 연동 문제

+

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

+

./mdc-null.png

+

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

+
public class MdcTaskDecorator implements TaskDecorator {
+
+    @Override
+    public Runnable decorate(final Runnable runnable) {
+        Map<String, String> threadContext = MDC.getCopyOfContextMap();
+        return () -> {
+            MDC.setContextMap(threadContext);
+            runnable.run();
+        };
+    }
+}
+
+

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

+
@RequiredArgsConstructor
+@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    private final AsyncConfigurationProperties properties;
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(properties.coreSize());
+        executor.setMaxPoolSize(properties.maxSize());
+        executor.setQueueCapacity(properties.queueCapacity());
+        
+        // highlight-next-line
+        executor.setTaskDecorator(new MdcTaskDecorator());
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.initialize();
+        return executor;
+    }
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

+

./mdc-not-null.png

+

참고 자료

+

spring async, baeldung
+@Async will not call by @ControllerAdvice for global exception
+Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
+TaskDecorator, Spring docs
+AsyncUncaughtExceptionHandler

]]> async exception
@@ -154,36 +518,206 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/tomcat-retrospective Mon, 11 Sep 2023 00:00:00 GMT -
PR 링크

톰캣 구현

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
-그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
-톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

다이어그램

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
+

1, 2단계: https://github.com/woowacourse/jwp-dashboard-http/pull/302
+3, 4단계: https://github.com/woowacourse/jwp-dashboard-http/pull/431

+

톰캣 구현

+

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
+그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

+

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
+톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

+

다이어그램

+

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
사실 내부 구조를 깊게 공부할 시간을 가지지 못해서 각 구성 요소가 왜 해당 위치에 있는지 완벽하게 설명하지는 못하지만 미션을 진행하면서 이건 여기에 있으면 좋을 것 같은데? 라는 생각이 들면 적절한 패키지에 위치시키는 방향으로 진행을 했다.
-또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

코드 리뷰

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
-나의 리뷰어는 디노, 리뷰이는 필립이었다.

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
+또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

+ +

코드 리뷰

+

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
+나의 리뷰어는 디노, 리뷰이는 필립이었다.

+

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
한 가지 아쉬운 점은 필립에게 작성한 나의 코멘트들이 미션을 진행하면서 경험 기반으로 작성한 내용이 많아 근거가 조금 부족했고, 정리되지 않은 부분이 많았던 것 같다.
-다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

SessionConfig

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
+다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

+

SessionConfig

+

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
세션 쿠키의 이름을 가져오는 Util 클래스의 코드를 수정했는데 기본 값은 JSESSIONID 지만 설정에 따라서 세션 쿠키명을 다르게 사용할 수 있기 때문에 해당 로직이 있는 것으로 생각했다.
-기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
+기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

+

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
메인테이너인 Mark Thomas 형이 해당 로직의 경우 컴파일러가 해당 부분을 최적화 할 수 있을 거라고 기대한다고 했고, 가독성을 개선시켜보라고 조언해주셨다.
-컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
-결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

public static String getSessionCookieName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_COOKIE_NAME;
}

return result;
}

public static String getSessionUriParamName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_PARAMETER_NAME;
}

return result;
}

private static String getConfiguredSessionCookieName(Context context) {

// Priority is:
// 1. Cookie name defined in context
// 2. Cookie name configured for app
// 3. Default defined by spec
if (context != null) {
String cookieName = context.getSessionCookieName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}

SessionCookieConfig scc =
context.getServletContext().getSessionCookieConfig();
cookieName = scc.getName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}
}

return null;
}

HTTP 수업

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
+컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

+

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
+결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

+ + +
public static String getSessionCookieName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_COOKIE_NAME;
+    }
+
+    return result;
+}
+
+public static String getSessionUriParamName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_PARAMETER_NAME;
+    }
+
+    return result;
+}
+
+private static String getConfiguredSessionCookieName(Context context) {
+
+    // Priority is:
+    // 1. Cookie name defined in context
+    // 2. Cookie name configured for app
+    // 3. Default defined by spec
+    if (context != null) {
+        String cookieName = context.getSessionCookieName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+
+        SessionCookieConfig scc =
+            context.getServletContext().getSessionCookieConfig();
+        cookieName = scc.getName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+    }
+
+    return null;
+}
+
+

HTTP 수업

+

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
항상 성능 개선을 위해 애플리케이션 단에서 최적화해보려고 노력을 했지만, 더 적은 시간을 투자해서 효율적으로 성능을 개선할 수 있는 방법에 대해 알 수 있었던 수업이었다.
-HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

server:
compression:
enabled: true

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
-궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
-내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

ETag

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
+HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

+

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

+
server:
+  compression:
+    enabled: true
+
+

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
+궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
+내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

+
+

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

+
+

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

+

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

+

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐시가 더 효율적이게 된다.
-MDN

Thread 수업

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
-현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
-학습한 내용은 다음과 같다.

threads.max: Tomcat의 최대 스레드 개수
+MDN

+

Thread 수업

+

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
+현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

+

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
+학습한 내용은 다음과 같다.

+

threads.max: Tomcat의 최대 스레드 개수
max-connections: Tomcat이 유지할 수 있는 최대 커넥션 개수
-accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

마치며

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
+accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

+ +

마치며

+

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
우선순위를 잘 정하고 학습을 진행해야겠다.
-현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

참고 자료

RFC 2616
-ETag, mdn
-Apache Tomcat 8 Configuration Reference
-Apache Tomcat Tuning, Terry Cho
-maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

]]> +현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

+

참고 자료

+

RFC 2616
+ETag, mdn
+Apache Tomcat 8 Configuration Reference
+Apache Tomcat Tuning, Terry Cho
+maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

]]> Woowahan Techcourse Retrospective @@ -193,19 +727,44 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/performance-test-type Sun, 10 Sep 2023 00:00:00 GMT - 성능 테스트

API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트

시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.
-다양한 상황에 대비해서 성능 테스트를 해야한다.

./test.png

스모크 테스트(Smoke Test)

최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트

VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.
-다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.

가상 사용자(VU)

가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.
+ 성능 테스트 +

API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트

+

시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.
+다양한 상황에 대비해서 성능 테스트를 해야한다.

+

./test.png

+

스모크 테스트(Smoke Test)

+

최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트

+

VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.
+다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.

+

가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.
이는 다른 가상 사용자와 독립적으로 실행되며, 여러 가상 사용자를 사용하여 동시 연결을 할 수 있다.
-스레드라고 생각하면 된다.

스파이크 테스트(Spike Test)

사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트

티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.
-스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.

부하 테스트(Load Test)

목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트

일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.
-램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.

램프 업(Ramp-up)

부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간

스트레스 테스트(Stress Test)

시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트

그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.
+스레드라고 생각하면 된다.

+

스파이크 테스트(Spike Test)

+

사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트

+

티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.
+스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.

+

부하 테스트(Load Test)

+

목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트

+

일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.
+램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.

+

부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간

+

스트레스 테스트(Stress Test)

+

시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트

+

그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.
일반적으로 평균적인 목푯값 대비 작게는 50% 이상, 필요의 경우 그 이상으로 부하를 준다.
스트레스 테스트는 부하 테스트를 실행한 후에만 실행해야 한다. 부하 테스트가 이루어지지 않은 상황에서 스트레스 테스트를 실행하는 경우에는 병목 지점이나 문제 상황을 찾기 어려워진다.
-또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.

내구 테스트(Endurance Test)

평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트

흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.
-다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.

중단점 테스트(Breakpoint Test)

임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트

문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.
+또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.

+

내구 테스트(Endurance Test)

+

평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트

+

흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.
+다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.

+

중단점 테스트(Breakpoint Test)

+

임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트

+

문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.
스트레스 테스트를 성능 튜닝과 반복해서 진행한다면, 시스템을 더욱 발전시킬 수 있다.
-다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.

참고 자료

Load test types, k6
+다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.

+

참고 자료

+

Load test types, k6
자바 최적화 - 벤저민 J. 에번스, 제임스 고프, 크리스 뉴랜드
아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄

]]>
performance test @@ -216,58 +775,436 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/db-replication Tue, 22 Aug 2023 00:00:00 GMT - 복제(Replication)

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
-원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

복제를 하는 이유

1. 스케일 아웃

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
-이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

2. 데이터 백업

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
-따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

3. 데이터 분석

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
-마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

4. 데이터의 지리적 분산

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

바이너리 로그 파일 위치 기반 복제

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
+ 복제(Replication) +

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
+원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

+

복제를 하는 이유

+

1. 스케일 아웃

+

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
+이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

+

2. 데이터 백업

+

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
+따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

+

3. 데이터 분석

+

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
+마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

+

4. 데이터의 지리적 분산

+

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

+

바이너리 로그 파일 위치 기반 복제

+

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
바이너리 로그를 통해 데이터 변경, 테이블 구조 변경, 계정이나 권한 변경에 대한 정보가 저장된다.
-MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

스레드별 역할

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
+MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

+ +

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
Replication I/O Thread: Binary 로그 이벤트를 가져와 로컬 서버의 파일(Relay Log)로 저장
-Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

바이너리 로그 방식의 문제점

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
-토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
+Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

+

바이너리 로그 방식의 문제점

+

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
+토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

+ +

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

+ +

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
하지만 여기서 C 서버에는 A 서버와 동기화가 안되었으니 조회 시 문제가 발생한다.
-뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

글로벌 트랜잭션 아이디(GTID) 기반 복제

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
-위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

GTID

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
-[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

복제 토폴로지

싱글 레플리카 복제 구성

가장 간단한 구성으로 제일 많이 사용하는 형태다.
-replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

멀티 레플리카 복제 구성

2개의 replica 서버를 사용하는 형태다.
+뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

+

글로벌 트랜잭션 아이디(GTID) 기반 복제

+

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
+위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

+

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
+[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

+

복제 토폴로지

+

싱글 레플리카 복제 구성

+

가장 간단한 구성으로 제일 많이 사용하는 형태다.
+replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

+ +

멀티 레플리카 복제 구성

+

2개의 replica 서버를 사용하는 형태다.
하나의 replica는 예비 용도로 남겨두는 형태다.
-추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

체인 복제 구성

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
-따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

듀얼 소스 복제 구성

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
+추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

+ +

체인 복제 구성

+

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
+따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

+ +

듀얼 소스 복제 구성

+

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
각 서버에서 변경된 데이터는 다른 서버에 반영된다.
목적에 따라 ACTIVE-ACTIVE 형태 또는 ACTIVE-PASSIVE 형태로 사용할 수 있다.
-ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

ACTIVE-ACTIVE, ACTIVE-PASSIVE

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
-ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

멀티 소스 복제 구성

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
-이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

바이너리 로그 방식 Replication 구성하기

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
-https://github.com/bbiac/db-replication

MySQL 환경 구성

MySQL 버전은 8.1을 사용했다.
+ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

+ +

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
+ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

+

멀티 소스 복제 구성

+

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
+이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

+ +

바이너리 로그 방식 Replication 구성하기

+

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
+https://github.com/bbiac/db-replication

+

MySQL 환경 구성

+

MySQL 버전은 8.1을 사용했다.
13306, 13307 포트를 사용해서 MySQL 서버 2대를 띄웠다.
-또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

version: '3.8'

services:
source:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-source
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13306:3306"
volumes:
- db-source:/var/lib/mysql
- db-source:/var/lib/mysql-files
- ./docker/source.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

replica:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-replica
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13307:3306"
volumes:
- db-replica:/var/lib/mysql
- db-replica:/var/lib/mysql-files
- ./docker/replica.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

volumes:
db-source:
db-replica:

networks:
mysql_network:
driver: bridge

또한 source, replica 각각 다음과 같이 db 설정을 했다.

설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
/docker/source.cnf
[mysqld]
server_id=1
log_bin=mysql-bin
sync_binlog=1

도커 실행

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
--d 옵션을 붙이면 백그라운드 모드로 실행된다.

docker-compose up -d

replication slave 권한 설정

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
-source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

SOURCE 접속

docker exec -it mysql-source mysql -u root -p

user 계정에 REPLICATION SLAVE 권한 추가

GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
FLUSH PRIVILEGES;

SOURCE DB 정보 확인

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
+또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

+
version: '3.8'
+
+services:
+  source:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-source
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13306:3306"
+    volumes:
+      - db-source:/var/lib/mysql
+      - db-source:/var/lib/mysql-files
+      - ./docker/source.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+  replica:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-replica
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13307:3306"
+    volumes:
+      - db-replica:/var/lib/mysql
+      - db-replica:/var/lib/mysql-files
+      - ./docker/replica.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+volumes:
+  db-source:
+  db-replica:
+
+networks:
+  mysql_network:
+    driver: bridge
+
+

또한 source, replica 각각 다음과 같이 db 설정을 했다.

+
설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
+ + +
[mysqld]
+server_id=1
+log_bin=mysql-bin
+sync_binlog=1
+
+

도커 실행

+

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
+-d 옵션을 붙이면 백그라운드 모드로 실행된다.

+
docker-compose up -d
+
+

replication slave 권한 설정

+

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
+source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

+

SOURCE 접속

+
docker exec -it mysql-source mysql -u root -p
+
+

user 계정에 REPLICATION SLAVE 권한 추가

+
GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
+FLUSH PRIVILEGES;
+
+

SOURCE DB 정보 확인

+

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
Position 값은 실제 파일의 바이트 수를 의미한다.
-확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 1082 | | | |
+------------------+----------+--------------+------------------+-------------------+

SOURCE ip 주소 확인

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
-다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
-확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

replica mysql 접속

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

docker exec -it mysql-replica mysql -u root -p

replica 설정

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
+확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

+
SHOW MASTER STATUS;
+
++------------------+----------+--------------+------------------+-------------------+
+| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
++------------------+----------+--------------+------------------+-------------------+
+| mysql-bin.000003 |     1082 |              |                  |                   |
++------------------+----------+--------------+------------------+-------------------+
+
+

SOURCE ip 주소 확인

+

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
+다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

+
docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source
+
+

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
+확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

+

replica mysql 접속

+

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

+
docker exec -it mysql-replica mysql -u root -p
+
+

replica 설정

+

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
실제 DB 서버에서 복제하는 경우 추가적으로 source DB의 파일을 복제해야하지만 현재 복제할 데이터가 없기 때문에 해당 부분은 생략했다.
-SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

STOP REPLICA;

CHANGE REPLICATION SOURCE TO
SOURCE_HOST='172.29.0.2',
SOURCE_USER='user',
SOURCE_PASSWORD='password',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=0,
GET_SOURCE_PUBLIC_KEY=1;

START REPLICA;

설정 확인

SHOW REPLICA STATUS;

+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
-replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

CREATE TABLE member
(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);

스프링 부트로 DB 접근하기

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

Environment 설정

다음과 같이 source, replica로 구분하여 설정한다.

application.yml
spring:
datasource:
source:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13306/db
replica:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13307/db

DataSourceType 설정

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
-Key는 추후에 빈 설정에 사용한다.

DataSourceType
public enum DataSourceType {
SOURCE(SOURCE_NAME),
REPLICA(REPLICA_NAME),
;

private final String key;

DataSourceType(String key) {
this.key = key;
}

public static class Key {
public static final String ROUTING_NAME = "ROUTING";
public static final String SOURCE_NAME = "SOURCE";
public static final String REPLICA_NAME = "REPLICA";
}
}

AbstractRoutingDataSource 설정

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
RoutingDataSource
public class RoutingDataSource extends AbstractRoutingDataSource {

private final Logger log = LoggerFactory.getLogger(getClass());

public static RoutingDataSource from(Map<Object, Object> dataSources) {
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
routingDataSource.setTargetDataSources(dataSources);
return routingDataSource;
}

@Override
protected Object determineCurrentLookupKey() {
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();

if (readOnly) {
log.info("readOnly = true, request to replica");
return DataSourceType.REPLICA;
}
log.info("readOnly = false, request to source");
return DataSourceType.SOURCE;
}
}

DataSource 설정

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
+SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

+
STOP REPLICA;
+
+CHANGE REPLICATION SOURCE TO 
+SOURCE_HOST='172.29.0.2', 
+SOURCE_USER='user', 
+SOURCE_PASSWORD='password', 
+SOURCE_LOG_FILE='mysql-bin.000001', 
+SOURCE_LOG_POS=0, 
+GET_SOURCE_PUBLIC_KEY=1;
+
+START REPLICA;
+
+

설정 확인

+
SHOW REPLICA STATUS;
+
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Replica_IO_State                 | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File  | Read_Source_Log_Pos | Relay_Log_File         | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID                          | Source_Info_File        | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State                                | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Waiting for source to send event | 172.25.0.3  | user        |        3306 |            60 | mysql-bin.000003 |                1082 | mysql-relay-bin.000002 |           868 | mysql-bin.000003      | Yes                | Yes                 |                 |                     |                    |                        |                         |                             |          0 |            |            0 |                1082 |            1078 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 | No                            |             0 |               |              0 |                |                             |                1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info |         0 |                NULL | Replica has read all relay log; waiting for more updates |              86400 |             |                         |                          |                |                    |                    |                   |             0 |                      |              |                    |                        |                     1 |                   |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+
+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

+

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
+replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

+
CREATE TABLE member
+(
+    id   BIGINT PRIMARY KEY AUTO_INCREMENT,
+    name VARCHAR(255)
+);
+
+

스프링 부트로 DB 접근하기

+

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

+

Environment 설정

+

다음과 같이 source, replica로 구분하여 설정한다.

+
spring:
+  datasource:
+    source:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13306/db
+    replica:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13307/db
+
+

DataSourceType 설정

+

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
+Key는 추후에 빈 설정에 사용한다.

+
public enum DataSourceType {
+    SOURCE(SOURCE_NAME),
+    REPLICA(REPLICA_NAME),
+    ;
+
+    private final String key;
+
+    DataSourceType(String key) {
+        this.key = key;
+    }
+
+    public static class Key {
+        public static final String ROUTING_NAME = "ROUTING";
+        public static final String SOURCE_NAME = "SOURCE";
+        public static final String REPLICA_NAME = "REPLICA";
+    }
+}
+
+

AbstractRoutingDataSource 설정

+

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

+

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

+
    +
  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • +
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.
  • +
+

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

+
    +
  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • +
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
  • +
+
public class RoutingDataSource extends AbstractRoutingDataSource {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public static RoutingDataSource from(Map<Object, Object> dataSources) {
+        RoutingDataSource routingDataSource = new RoutingDataSource();
+        routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
+        routingDataSource.setTargetDataSources(dataSources);
+        return routingDataSource;
+    }
+
+    @Override
+    protected Object determineCurrentLookupKey() {
+        boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
+
+        if (readOnly) {
+            log.info("readOnly = true, request to replica");
+            return DataSourceType.REPLICA;
+        }
+        log.info("readOnly = false, request to source");
+        return DataSourceType.SOURCE;
+    }
+}
+
+

DataSource 설정

+

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
스프링은 트랜잭션 시작시에 커넥션의 사용여부와 상관없이 커넥션을 확보한다.
-따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

DataSourceConfiguration
@Configuration
public class DataSourceConfiguration {

@Bean
@Qualifier(SOURCE_NAME)
@ConfigurationProperties(prefix = "spring.datasource.source")
public DataSource sourceDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(REPLICA_NAME)
@ConfigurationProperties(prefix = "spring.datasource.replica")
public DataSource replicaDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(ROUTING_NAME)
public DataSource routingDataSource(
@Qualifier(SOURCE_NAME) DataSource sourceDataSource,
@Qualifier(REPLICA_NAME) DataSource replicaDataSource
) {
return RoutingDataSource.from(Map.of(
DataSourceType.SOURCE, sourceDataSource,
DataSourceType.REPLICA, replicaDataSource
));
}

@Bean
@Primary
public DataSource dataSource(
@Qualifier(ROUTING_NAME) DataSource routingDataSource
) {
return new LazyConnectionDataSourceProxy(routingDataSource);
}
}

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

동작 확인

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
+따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

+

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

+

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

+
@Configuration
+public class DataSourceConfiguration {
+
+    @Bean
+    @Qualifier(SOURCE_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.source")
+    public DataSource sourceDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(REPLICA_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.replica")
+    public DataSource replicaDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(ROUTING_NAME)
+    public DataSource routingDataSource(
+            @Qualifier(SOURCE_NAME) DataSource sourceDataSource,
+            @Qualifier(REPLICA_NAME) DataSource replicaDataSource
+    ) {
+        return RoutingDataSource.from(Map.of(
+                DataSourceType.SOURCE, sourceDataSource,
+                DataSourceType.REPLICA, replicaDataSource
+        ));
+    }
+
+    @Bean
+    @Primary
+    public DataSource dataSource(
+            @Qualifier(ROUTING_NAME) DataSource routingDataSource
+    ) {
+        return new LazyConnectionDataSourceProxy(routingDataSource);
+    }
+}
+
+

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

+ +

동작 확인

+

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
save 메서드의 경우 @Transactional, findById 메서드의 경우 @Transactional(readOnly = true)가 설정되어있다.
-로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

MemberServiceTest
@SpringBootTest
class MemberServiceTest {

@Autowired
private MemberService memberService;

@Test
void 사용자를_저장한다() {
// RoutingDataSource log: readOnly = false
memberService.save("bbiac");
}

@Test
void 사용자를_조회한다() {
// RoutingDataSource log: readOnly = true
assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
.isInstanceOf(NoSuchElementException.class);
}
}

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

SET GLOBAL log_output = 'table';
SET GLOBAL general_log = 1;

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
-server_id, 실행한 쿼리문을 확인할 수 있다.

SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';

+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user_host | thread_id | server_id | convert(argument using utf8) |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

SET GLOBAL general_log = 0;
SHOW VARIABLES LIKE '%general%';

+------------------+---------------------------------+
| Variable_name | Value |
+------------------+---------------------------------+
| general_log | OFF |
| general_log_file | /var/lib/mysql/4b6b9db98290.log |
+------------------+---------------------------------+

참고 자료

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
-Replication, MySQL Docs
-MySql - Master Slave Replication 구조 만들어보기
-Spring 레플리케이션 트랜잭션 처리 방식
-replication-datasource
-Simplified Guide to MySQL Replication with Docker Compose
-Dockerfile에서 자주 쓰이는 명령어
-CHANGE REPLICATION SOURCE TO Statement
-LazyConnectionDataSourceProxy
-데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
-부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
-Use Docker Compose, Docker

]]>
+로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

+
@SpringBootTest
+class MemberServiceTest {
+
+    @Autowired
+    private MemberService memberService;
+
+    @Test
+    void 사용자를_저장한다() {
+        // RoutingDataSource log: readOnly = false
+        memberService.save("bbiac");
+    }
+
+    @Test
+    void 사용자를_조회한다() {
+        // RoutingDataSource log: readOnly = true
+        assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
+                .isInstanceOf(NoSuchElementException.class);
+    }
+}
+
+

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

+
SET GLOBAL log_output = 'table';
+SET GLOBAL general_log = 1;
+
+

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
+server_id, 실행한 쿼리문을 확인할 수 있다.

+
SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';
+
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user_host                  | thread_id | server_id | convert(argument using utf8)                                                |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user[user] @  [172.25.0.1] |       277 |         2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+
+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

+
SET GLOBAL general_log = 0;
+SHOW VARIABLES LIKE '%general%';
+
++------------------+---------------------------------+
+| Variable_name    | Value                           |
++------------------+---------------------------------+
+| general_log      | OFF                             |
+| general_log_file | /var/lib/mysql/4b6b9db98290.log |
++------------------+---------------------------------+
+
+

참고 자료

+

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
+Replication, MySQL Docs
+MySql - Master Slave Replication 구조 만들어보기
+Spring 레플리케이션 트랜잭션 처리 방식
+replication-datasource
+Simplified Guide to MySQL Replication with Docker Compose
+Dockerfile에서 자주 쓰이는 명령어
+CHANGE REPLICATION SOURCE TO Statement
+LazyConnectionDataSourceProxy
+데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
+부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
+Use Docker Compose, Docker

]]> mysql replication @@ -277,20 +1214,38 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/woowacourse-level3-retrospective Sat, 19 Aug 2023 00:00:00 GMT - 회고

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
+ 회고 +

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
레벨 3에는 기술적인 부분에서도, 기술 외적인 부분에서도 부족함이 많이 보였던 것 같다.
부족한 부분을 알았기에, 앞으로 더욱 성장할 수 있을 것 같다.
-내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

아쉬운 점

문서화

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
+내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

+

아쉬운 점

+

문서화

+

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
프로젝트를 진행하면서 내가 한 부분을 조금 더 꼼꼼하게, 이해하기 쉽게 문서화를 했더라면 팀원들에게 더욱 도움이 되었을 텐데 이 부분에 시간을 조금 더 투자하지 못했던 부분에서 아쉬움이 많이 들었다.
-방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

내가 못하는 부분이라면 시간을 들이자

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
+방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

+

내가 못하는 부분이라면 시간을 들이자

+

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
말을 하기 전에 정리해서 의견을 내는 것, 발표 준비, 감정 조절 등등 -못하는 부분을 인지하고, 개선하자.

컴포트 존 벗어나기

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
+못하는 부분을 인지하고, 개선하자.

+

컴포트 존 벗어나기

+

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
매번 근거를 가지고 기술을 도입하고, 코드를 작성하려고 노력했다.
-하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

좋았던 점

좋았던 점도 문서화

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
-백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

내가 디자인한 트립드로우 로고

트립드로우 로고를 만들었다.
+하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

+

좋았던 점

+

좋았던 점도 문서화

+

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
+백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

+

내가 디자인한 트립드로우 로고

+ +

트립드로우 로고를 만들었다.
팀원들이 대표 색상(파란색)을 정해줬고, 주말 동안 신나게 로고 디자인을 했던 것 같다.
-아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

기술 선택의 이유

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
-100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

마치며

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
+아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

+

기술 선택의 이유

+

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
+100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

+

마치며

+

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
안드로이드 브레멘 음악대(멧돼지, 수달, 핑구), 그리고 백엔드 팀원들(체인저, 후추, 리오) 너무 고생이 많았다.

]]>
Woowahan Techcourse Retrospective @@ -301,26 +1256,88 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/cloudwatch Thu, 17 Aug 2023 00:00:00 GMT - CloudWatch

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
+ CloudWatch +

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
지표를 감시하여 알림을 보내는 기능도 제공한다.
프리티어를 사용하지 않는 경우 대시보드당 3$/M 의 비용이 청구되고, 지표나 로그의 양에 따라 비용이 추가적으로 청구된다.
-요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

CloudWatch Metrics

기본적으로 5분마다 지표에 대한 정보가 수집된다.
+요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

+

CloudWatch Metrics

+

기본적으로 5분마다 지표에 대한 정보가 수집된다.
세부 모니터링(Detailed Monitoring)을 활성화하면 1분마다 지표를 수집한다.
-대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

./cloudwatch1.png

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

CloudWatch Agent 설치

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

IAM 역할 설정

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
-IAM → 역할에서 역할 생성을 클릭한다.

./cloudwatch2.png

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

./cloudwatch3.png

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
-작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

./cloudwatch4.png

설치

환경은 다음과 같다.

OS: ubuntu 22.04
-인스턴스 유형: t4g.small (ARM64)

아래 명령어를 입력하여 설치한다.

wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i -E ./amazon-cloudwatch-agent.deb

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

Wizard

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
+대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

+

./cloudwatch1.png

+

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

+

CloudWatch Agent 설치

+

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

+

IAM 역할 설정

+

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
+IAM → 역할에서 역할 생성을 클릭한다.

+

./cloudwatch2.png

+

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

+

./cloudwatch3.png

+

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
+작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

+

./cloudwatch4.png

+

설치

+

환경은 다음과 같다.

+

OS: ubuntu 22.04
+인스턴스 유형: t4g.small (ARM64)

+

아래 명령어를 입력하여 설치한다.

+
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
+sudo dpkg -i -E ./amazon-cloudwatch-agent.deb
+
+

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

+

Wizard

+

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
로그를 수집하도록 설정하는 경우 Wizard 실행 명령어 입력 전 log 파일의 절대 경로를 복사해두는 것이 좋다.
-아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
-로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

./cloudwatch5.png

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

Do you want to store the config in the SSM parameter store?
1. yes
2. no

추가적으로 설정하지 않는 경우 2번을 선택한다.
-Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
-설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

설정 파일 적용

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
-file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

types.db: no such file or directory 에러

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory

types.db 파일 생성

sudo mkdir /usr/share/collectd
sudo touch /usr/share/collectd/types.db

지표 확인

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

./cloudwatch6.png

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

{
"metrics": {
"namespace": "2023-hello-world",
......
},
}

로그

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

./cloudwatch7.png

참고 자료

CloudWatch란 무엇입니까?
-Amazon CloudWatch 요금
-Linux 인스턴스 지표
-서버에 CloudWatch 에이전트 설치 및 실행
-CloudWatch Agent를 Parameter Store에서 관리해 보기
-CloudWatch에이전트 구성 파일

]]>
+아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
+
+

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
+로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

+

./cloudwatch5.png

+

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

+
Do you want to store the config in the SSM parameter store?
+1. yes
+2. no
+
+

추가적으로 설정하지 않는 경우 2번을 선택한다.
+Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
+설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

+

설정 파일 적용

+

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
+file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
+
+

types.db: no such file or directory 에러

+

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

+
Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory
+
+

types.db 파일 생성

+
sudo mkdir /usr/share/collectd
+sudo touch /usr/share/collectd/types.db
+
+

지표 확인

+

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

+

./cloudwatch6.png

+

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

+
{
+  "metrics": {
+    "namespace": "2023-hello-world",
+    ......
+   },
+} 
+
+

로그

+

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

+

./cloudwatch7.png

+

참고 자료

+

CloudWatch란 무엇입니까?
+Amazon CloudWatch 요금
+Linux 인스턴스 지표
+서버에 CloudWatch 에이전트 설치 및 실행
+CloudWatch Agent를 Parameter Store에서 관리해 보기
+CloudWatch에이전트 구성 파일

]]> cloudwatch log monitoring @@ -331,33 +1348,213 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/route-image-async-with-event Sun, 13 Aug 2023 00:00:00 GMT - 이전 글

경로 이미지 생성하기 - 기술 선택
-경로 이미지 생성하기 - 구현

개요

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
+ 이전 글 +

경로 이미지 생성하기 - 기술 선택
+경로 이미지 생성하기 - 구현

+

개요

+

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
경로 이미지 생성의 경우 위치 정보의 개수에 정비례하여 생성 시간이 증가한다.
-따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

주기능의 응답속도 개선

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
+따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

+

주기능의 응답속도 개선

+

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
하지만 현재 여행 종료와 감상 생성의 응답 속도가 경로 이미지 생성 시간에 영향을 받고 있다.
경로 이미지 생성은 비동기 처리하여도 애플리케이션 사용에 문제가 되지 않는다.
-소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

확장성 대비

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
+소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

+

확장성 대비

+

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
조금 더 짧은 간격으로 위치 정보를 그리는 경우 하나의 여행에 많은 위치 정보가 저장될 수밖에 없고 따라서 경로 이미지 생성에 걸리는 시간이 더 길어질 수 있다.
-따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

비동기 처리

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

비동기 설정

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
-해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig {
}

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. -7.7. Task Execution and Scheduling, Spring Boot Docs

@Async 적용

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

RouteImageGenerator
@Async
public void generate(
List<Double> latitudes,
List<Double> longitudes,
List<Double> pointedLatitudes,
List<Double> pointedLongitudes,
Long tripId
) {
// 이미지 생성
RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
Coordinates coordinates = Coordinates.of(latitudes, longitudes);
Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
drawImage(coordinates, routeImageDrawer, pointedCoordinates);

// 이미지 저장
String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());

// 자원 할당 해제
routeImageDrawer.dispose();

// 데이터베이스 값 변경
Trip trip = tripRepository.findById(tripId)
.orElseThrow();
trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}

비동기 처리시 문제점

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
-따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
-인터페이스를 사용한다면 다음과 같은 구조가 된다.

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
-따라서 이벤트를 사용하기로 했다.

이벤트 사용

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

이벤트 발행

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
+따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

+

비동기 처리

+

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

+

비동기 설정

+

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
+해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig {
+}
+
+

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

+
+

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. +7.7. Task Execution and Scheduling, Spring Boot Docs

+
+

@Async 적용

+

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

+
@Async
+public void generate(
+        List<Double> latitudes,
+        List<Double> longitudes,
+        List<Double> pointedLatitudes,
+        List<Double> pointedLongitudes,
+        Long tripId
+) {
+    // 이미지 생성
+    RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
+    Coordinates coordinates = Coordinates.of(latitudes, longitudes);
+    Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
+    drawImage(coordinates, routeImageDrawer, pointedCoordinates);
+
+    // 이미지 저장
+    String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());
+
+    // 자원 할당 해제
+    routeImageDrawer.dispose();
+
+    // 데이터베이스 값 변경
+    Trip trip = tripRepository.findById(tripId)
+        .orElseThrow();
+    trip.changeRouteImageUrl(imageUrl);
+    tripRepository.save(trip);
+}
+
+

비동기 처리시 문제점

+

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
+따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

+ +

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
+인터페이스를 사용한다면 다음과 같은 구조가 된다.

+ +

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
+따라서 이벤트를 사용하기로 했다.

+

이벤트 사용

+

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

+

이벤트 발행

+

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
스프링에서는 ApplicationEventPublisher 인터페이스를 사용하여 이벤트를 발행할 수 있다.
-해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

TripService & TripUpdateEvent
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
...

// 이벤트 발행
applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
}

public record TripUpdateEvent(Long tripId) {
}

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
+해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

+
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
+    ...
+
+    // 이벤트 발행
+    applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
+}
+
+public record TripUpdateEvent(Long tripId) {
+}
+
+

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
이벤트를 구독하는 도메인의 행위를 담고 있는 이벤트를 발행(ex. RouteImageGenerateEvent)한다면 논리적인 의존 관계가 남아있기에 이벤트를 적절히 사용했다고 보기 어렵다.
-발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

이벤트 구독

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
-이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

TransactionPhase 설정

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
+발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

+

이벤트 구독

+

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
+이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

+

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
AFTER_ROLLBACK: 트랜잭션이 롤백되는 경우 이벤트 실행
AFTER_COMPLETION: 트랜잭션이 커밋 또는 롤백 되었을 경우 이벤트 실행
-BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

TripUpdateEventHandler
@Component
public class TripUpdateEventHandler {

private final RouteImageGenerator routeImageGenerator;
private final TripRepository tripRepository;

public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
this.routeImageGenerator = routeImageGenerator;
this.tripRepository = tripRepository;
}

@Async
@TransactionalEventListener(phase = AFTER_COMMIT)
public void handle(TripUpdateEvent tripUpdateEvent) {
Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());

String imageUrl = routeImageGenerator.generate(
trip.getLatitudes(),
trip.getLongitudes(),
trip.getPointedLatitudes(),
trip.getPointedLongitudes()
);

trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}
}

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
-또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

테스트

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

@ContextConfiguration(classes = TestSyncConfig.class)
@SpringBootTest
public class TripUpdateEventHandlerIntegrationTest {

...

@Test
void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
// given
TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
.willReturn(여행());

// when
transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));

// then
then(routeImageGenerator)
.should(times(1))
.generate(any(), any(), any(), any());
}
}

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
-통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

결과

./time.png

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
-응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

참고 자료

7.7. Task Execution and Scheduling, Spring Boot Docs
-Spring Events, Baeldung
-회원시스템 이벤트기반 아키텍처 구축하기

]]>
+BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

+

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

+
@Component
+public class TripUpdateEventHandler {
+
+    private final RouteImageGenerator routeImageGenerator;
+    private final TripRepository tripRepository;
+
+    public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
+        this.routeImageGenerator = routeImageGenerator;
+        this.tripRepository = tripRepository;
+    }
+
+    @Async
+    @TransactionalEventListener(phase = AFTER_COMMIT)
+    public void handle(TripUpdateEvent tripUpdateEvent) {
+        Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());
+
+        String imageUrl = routeImageGenerator.generate(
+                trip.getLatitudes(),
+                trip.getLongitudes(),
+                trip.getPointedLatitudes(),
+                trip.getPointedLongitudes()
+        );
+
+        trip.changeRouteImageUrl(imageUrl);
+        tripRepository.save(trip);
+    }
+}
+
+

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
+또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

+ +

테스트

+

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

+ + +
@ContextConfiguration(classes = TestSyncConfig.class)
+@SpringBootTest
+public class TripUpdateEventHandlerIntegrationTest {
+
+    ...
+
+    @Test
+    void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
+        // given
+        TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
+        given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
+                .willReturn(여행());
+
+        // when
+        transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));
+
+        // then
+        then(routeImageGenerator)
+                .should(times(1))
+                .generate(any(), any(), any(), any());
+    }
+}
+
+

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
+통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

+

결과

+

./time.png

+

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
+응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

+

참고 자료

+

7.7. Task Execution and Scheduling, Spring Boot Docs
+Spring Events, Baeldung
+회원시스템 이벤트기반 아키텍처 구축하기

]]> async event @@ -367,17 +1564,198 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/route-image-implementation Wed, 02 Aug 2023 00:00:00 GMT - 개요

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
-경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

구현 결과

./result.png

예시 데이터는 다음과 같다.
-서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

예시 데이터
List<Double> x = List.of(
126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
);
List<Double> y = List.of(
37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
);
List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);

IMAGE_SIZE & ROUTE_SIZE

RouteImageGenerator.java
private static final int IMAGE_SIZE = 800;
private static final int ROUTE_SIZE = 600;

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
+ 개요 +

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
+경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

+

구현 결과

+

./result.png

+

예시 데이터는 다음과 같다.
+서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

+
List<Double> x = List.of(
+        126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
+        126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
+);
+List<Double> y = List.of(
+        37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
+        37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
+);
+List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
+List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);
+
+

IMAGE_SIZE & ROUTE_SIZE

+
private static final int IMAGE_SIZE = 800;
+private static final int ROUTE_SIZE = 600;
+
+

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
IMAGE_SIZE는 말 그대로 이미지의 width와 height를 의미한다.
ROUTE_SIZE의 경우 상하좌우 100px 만큼의 간격을 위해 존재한다.
-따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

./600.png

사이즈 변경의 이유

255 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 800 사이즈로 변경했다.

주요 클래스

요약

클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성

의존관계

Coordinates(위도, 경도의 일급 컬렉션)

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
-Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는

Positions 계산 로직은 다음과 같다.
-위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

Coordinates.java
// 호출
// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);

private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
Double minValue = Collections.min(values);
return values.stream()
.map(value -> normalizeCoordinate(value, maxDifference, minValue))
.map(value -> mapToPosition(value, routeImageSize))
.toList();
}

private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
return (coordinate - minValue) / maxDifference;
}

private int mapToPosition(Double coordinate, Integer routeImageSize) {
return (int) (coordinate * routeImageSize);
}

위도로 예시든 내용이다.

  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  3. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.

Positions(실제 이미지 생성에 사용할 위치)

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • size: 크기를 반환한다.
  • xPositions: x 값들을 반환한다.
  • yPositions: y 값들을 반환한다.

중앙 정렬 로직은 다음과 같다.

Positions.java
public Positions align(int imageSize, int routeSize) {
int xOffset = calculateOffset(Position::x, imageSize);
int yOffset = calculateOffset(Position::y, imageSize);

return items.stream()
.map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
.collect(collectingAndThen(toList(), Positions::new));
}

private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
List<Integer> positions = items.stream()
.mapToInt(positionToInteger)
.boxed()
.toList();

int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
return imageSize / 2 - midValue;
}

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
-BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

./800.png

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

x 값 → 계산한 offset 그대로 더한다.
-y 값 → imageSize(800)에서 y + offset 값을 뺀다.

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
-그림을 그리기 위해 설정한 상수들이 존재한다.

RouteImageDrawer.java
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
// 이를 RGBA라고 부른다.
private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
// 배경 투명색
private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
// 경로를 위한 STROKE
private static final int LINE_STROKE_WIDTH = 7;
private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 위치 점을 위한 STROKE
private static final int POINT_STROKE_WIDTH = 20;
private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 안티앨리어싱 등 화질 개선을 위한 설정
private static final Map<Object, Object> renderingHints = Map.of(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
);

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

  • drawLine: 선을 그린다.
  • drawPoint: 점을 찍는다.
  • dispose: 자원 할당을 해제한다.

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

이미지 생성 Flow

1. 이미지 생성 준비

2. 선 그리기 요청

3. 위치 점 그리기 요청

4. 업로드 요청

전체 Flow

]]>
+따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

+

./600.png

+

사이즈 변경의 이유

+

255 * 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 * 800 사이즈로 변경했다.

+

주요 클래스

+

요약

+
클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성
+

의존관계

+ +

Coordinates(위도, 경도의 일급 컬렉션)

+

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
+Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

+
    +
  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • +
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는
  • +
+

Positions 계산 로직은 다음과 같다.
+위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

+
// 호출
+// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
+// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);
+
+private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
+    Double minValue = Collections.min(values);
+    return values.stream()
+            .map(value -> normalizeCoordinate(value, maxDifference, minValue))
+            .map(value -> mapToPosition(value, routeImageSize))
+            .toList();
+}
+
+private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
+    return (coordinate - minValue) / maxDifference;
+}
+
+private int mapToPosition(Double coordinate, Integer routeImageSize) {
+    return (int) (coordinate * routeImageSize);
+}
+
+

위도로 예시든 내용이다.

+
    +
  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. +
  3. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  4. +
  5. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.
  6. +
+

Positions(실제 이미지 생성에 사용할 위치)

+

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

+
    +
  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • +
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • +
  • size: 크기를 반환한다.
  • +
  • xPositions: x 값들을 반환한다.
  • +
  • yPositions: y 값들을 반환한다.
  • +
+

중앙 정렬 로직은 다음과 같다.

+
public Positions align(int imageSize, int routeSize) {
+    int xOffset = calculateOffset(Position::x, imageSize);
+    int yOffset = calculateOffset(Position::y, imageSize);
+
+    return items.stream()
+            .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
+            .collect(collectingAndThen(toList(), Positions::new));
+}
+
+private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
+    List<Integer> positions = items.stream()
+            .mapToInt(positionToInteger)
+            .boxed()
+            .toList();
+
+    int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
+    return imageSize / 2 - midValue;
+}
+
+

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
+BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

+

./800.png

+

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

+

x 값 → 계산한 offset 그대로 더한다.
+y 값 → imageSize(800)에서 y + offset 값을 뺀다.

+

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

+

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
+그림을 그리기 위해 설정한 상수들이 존재한다.

+
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
+// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
+// 이를 RGBA라고 부른다.
+private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
+// 배경 투명색
+private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
+// 경로를 위한 STROKE
+private static final int LINE_STROKE_WIDTH = 7;
+private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 위치 점을 위한 STROKE
+private static final int POINT_STROKE_WIDTH = 20;
+private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 안티앨리어싱 등 화질 개선을 위한 설정
+private static final Map<Object, Object> renderingHints = Map.of(
+        RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
+        RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
+        RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
+);
+
+

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

+
    +
  • drawLine: 선을 그린다.
  • +
  • drawPoint: 점을 찍는다.
  • +
  • dispose: 자원 할당을 해제한다.
  • +
+

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

+

이미지 생성 Flow

+

1. 이미지 생성 준비

+ +

2. 선 그리기 요청

+ +

3. 위치 점 그리기 요청

+ +

4. 업로드 요청

+ +

전체 Flow

+]]> image awt @@ -387,27 +1765,178 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/route-image-python Mon, 31 Jul 2023 00:00:00 GMT - 개요

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

사용 기술

언어: Python 3.10
+ 개요 +

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

+

사용 기술

+

언어: Python 3.10
이미지 생성: matplotlib
서비스: AWS Lambda, AWS API Gateway
-이미지 저장 및 URL: AWS S3, AWS CloudFront

플로우는 다음과 같다.

요구사항

./route.png

우측 상단의 경로 이미지를 생성하려고 한다.
-경로 이미지 생성에 대한 요구사항은 다음과 같다.

  • 위도, 경도로 이루어진 배열을 입력받는다.
  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.

이미지 출력 방식

  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
-파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

로컬에서 기능 구현

import time

import matplotlib.pyplot as plt


def draw(point):
start = time.time()
x, y = zip(*point)
pixel_x, pixel_y = convert_to_pixel_values(x, y)
draw_lines(pixel_x, pixel_y)
end = time.time()
print(end - start)

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)


def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
return scaled_coordinates


def draw_lines(x, y):
figure = plt.gcf()
figure.set_size_inches(5, 5)
plt.plot(x, y, c = 'w',linewidth=5)
plt.scatter(x[3],y[3], c = 'w', s = 125)
plt.axis('off')
plt.savefig('name.png', transparent=True, format='png')

point = [
[126.96352960597338, 37.590841000217125],
[126.96987292787792, 37.58435564234159],
[126.98128481452298, 37.58594375113966],
[126.99360339342958, 37.58248524741927],
[126.99867565340067, 37.56778118088622],
[127.001935378366117, 37.55985240444085],
[126.9831048919687, 37.548030119488665],
[126.97189273528845, 37.5119879225856],
[127.02689859997221, 37.48488593333883]
]

draw(point)

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

./routeImage.png

AWS Lambda

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
+이미지 저장 및 URL: AWS S3, AWS CloudFront

+

플로우는 다음과 같다.

+ +

요구사항

+

./route.png

+

우측 상단의 경로 이미지를 생성하려고 한다.
+경로 이미지 생성에 대한 요구사항은 다음과 같다.

+
    +
  • 위도, 경도로 이루어진 배열을 입력받는다.
  • +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.
  • +
+

이미지 출력 방식

+
    +
  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. +
  3. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장
  4. +
+

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
+파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

+

로컬에서 기능 구현

+
import time
+
+import matplotlib.pyplot as plt
+
+
+def draw(point):
+    start = time.time()
+    x, y = zip(*point)
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    draw_lines(pixel_x, pixel_y)
+    end = time.time()
+    print(end - start)
+    
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    return scaled_coordinates
+
+
+def draw_lines(x, y):
+    figure = plt.gcf()
+    figure.set_size_inches(5, 5)
+    plt.plot(x, y, c = 'w',linewidth=5)
+    plt.scatter(x[3],y[3], c = 'w', s = 125)
+    plt.axis('off')
+    plt.savefig('name.png', transparent=True, format='png')
+
+point = [
+    [126.96352960597338, 37.590841000217125],
+    [126.96987292787792, 37.58435564234159],
+    [126.98128481452298, 37.58594375113966],
+    [126.99360339342958, 37.58248524741927],
+    [126.99867565340067, 37.56778118088622],
+    [127.001935378366117, 37.55985240444085],
+    [126.9831048919687, 37.548030119488665],
+    [126.97189273528845, 37.5119879225856],
+    [127.02689859997221, 37.48488593333883]
+]
+
+draw(point)
+
+

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

+

./routeImage.png

+

AWS Lambda

+

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
따라서 서버리스로 파일을 처리했다.
-추가로 s3 접근은 boto3를 사용했다.

람다 S3 접근을 위한 IAM 생성

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

람다 배포용 코드

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.


import io
import uuid

import boto3
import matplotlib.pyplot as plt

PIXEL = 255
BUCKET_NAME = 'image-plot'
S3 = 's3'

def lambda_handler(event, context):
x = event['x']
y = event['y']
image_name = str(uuid.uuid4())

img_data = draw(x, y)
s3 = boto3.client(S3)
s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'

return {
'statusCode': 200,
'body': url
}

def draw(x, y):
pixel_x, pixel_y = convert_to_pixel_values(x, y)
img_data = draw_lines(pixel_x, pixel_y)
plt.close()
return img_data

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)

def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
return pixel_values

def draw_lines(x, y):
plt.plot(x, y, 'k-', linewidth=10)
plt.axis('off')
img_data = io.BytesIO()
plt.savefig(img_data, transparent=True, format='png')
img_data.seek(0)
return img_data

Layer 추가를 위한 zip 파일 생성

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
+추가로 s3 접근은 boto3를 사용했다.

+

람다 S3 접근을 위한 IAM 생성

+

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

+

람다 배포용 코드

+

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.

+

+import io
+import uuid
+
+import boto3
+import matplotlib.pyplot as plt
+
+PIXEL = 255
+BUCKET_NAME = 'image-plot'
+S3 = 's3'
+
+def lambda_handler(event, context):
+    x = event['x']
+    y = event['y']
+    image_name = str(uuid.uuid4())
+
+    img_data = draw(x, y)
+    s3 = boto3.client(S3)
+    s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
+    url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'
+
+    return {
+        'statusCode': 200,
+        'body': url
+    }
+
+def draw(x, y):
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    img_data = draw_lines(pixel_x, pixel_y)
+    plt.close()
+    return img_data
+
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
+    return pixel_values
+
+def draw_lines(x, y):
+    plt.plot(x, y, 'k-', linewidth=10)
+    plt.axis('off')
+    img_data = io.BytesIO()
+    plt.savefig(img_data, transparent=True, format='png')
+    img_data.seek(0)
+    return img_data
+
+
+

Layer 추가를 위한 zip 파일 생성

+

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
zip 파일을 만들어서 업로드해야한다.
이때 python의 Lambda 런타임에 대한 계층 경로는 python이다.
-따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

pillow.zip
│ python/PIL
└ python/Pillow-5.3.0.dist-info

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

sudo apt update
sudo apt install zip
sudo apt install python3-pip

mkdir python
pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로

No module named 'numpy.core._multiarray_umath' 에러

Layer 추가 후 람다 실행 시 발생한 에러였다.
+따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

+
pillow.zip
+│ python/PIL
+└ python/Pillow-5.3.0.dist-info
+
+

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

+
sudo apt update
+sudo apt install zip
+sudo apt install python3-pip
+
+mkdir python
+pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
+zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로
+
+

No module named 'numpy.core._multiarray_umath' 에러

+

Layer 추가 후 람다 실행 시 발생한 에러였다.
처음에 mac에서 zip 파일을 생성해서 업로드했는데 해당 문제가 발생했다.
이는 lambda가 돌아가는 동일한 환경에서 layer를 위한 zip 파일을 만들지 않아서 발생하는 문제다.
-간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

적정기술에 대한 생각

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
+간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

+

적정기술에 대한 생각

+

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
AWS Lambda를 사용하는 것은 인스턴스에 해당 코드를 배포하는 것보다 더 효율적인 방법일 수 있다.
하지만 현재 프로젝트에서 가용 가능한 자원, 기술의 난이도, 사용하는 팀원을 고려한다면 Lambda는 적정기술이 아닐 수 있다.
-따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

최종적으로 Java AWT를 사용하기로 결정했다.

참고 자료

AWS Lambda
-Lambda Layer
-Python Lambda 함수에 대한 .zip 파일 아카이브 작업
-No module named 'numpy.core._multiarray_umath'
-사례별로 알아본 안전한 S3 사용 가이드

]]>
+따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

+

최종적으로 Java AWT를 사용하기로 결정했다.

+

참고 자료

+

AWS Lambda
+Lambda Layer
+Python Lambda 함수에 대한 .zip 파일 아카이브 작업
+No module named 'numpy.core._multiarray_umath'
+사례별로 알아본 안전한 S3 사용 가이드

]]> Image Python @@ -417,15 +1946,47 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/mock-static-method Sun, 30 Jul 2023 00:00:00 GMT - 개요

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
-하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
+ 개요 +

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
+하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

+

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

+

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
해당 static 메서드를 호출하는 부분을 따로 RouteImageUploader 클래스로 최대한 분리했다.
-이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

public void upload(BufferedImage bufferedImage) {
File file = new File(파일경로);
try {
ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
} catch (IOException e) {
throw new DrawException(IMAGE_SAVE_FAIL);
}
}

Mocking static methods

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
-mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

// given
BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
RouteImageUploader routeImageUploader = new RouteImageUploader();

// expect
try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
routeImageUploader.upload(bufferedImage);
imageIO.verify(
() -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
times(1)
);
}

마치며

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
+이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

+
public void upload(BufferedImage bufferedImage) {
+    File file = new File(파일경로);
+    try {
+        ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
+    } catch (IOException e) {
+        throw new DrawException(IMAGE_SAVE_FAIL);
+    }
+}
+
+

Mocking static methods

+

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
+mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

+

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

+
// given
+BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
+RouteImageUploader routeImageUploader = new RouteImageUploader();
+
+// expect
+try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
+    routeImageUploader.upload(bufferedImage);
+    imageIO.verify(
+            () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
+            times(1)
+    );
+}
+
+

마치며

+

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
하지만 추상화를 하면 할 수록 코드의 복잡도는 증가한다.
-항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

참고 자료

Mocking static methods
-Mockito mock static methods
-Enable mocking static methods in Mockito

]]>
+항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

+

참고 자료

+

Mocking static methods
+Mockito mock static methods
+Enable mocking static methods in Mockito

]]> Mockito static @@ -435,12 +1996,56 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/route-image-intro Thu, 27 Jul 2023 00:00:00 GMT - ./route.png

이미지 생성의 책임

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
-따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

고려한 기술

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

  • Python의 Matplotlib
  • AWT(Abstract Window Toolkit) [최종 선택]
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)

Python & Matplotlib

데이터 시각화 라이브러리
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

  • 코드가 간단해서 유지 보수성이 좋다.
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.

Java AWT 이외의 라이브러리

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음

Java & AWT(Abstract Window Toolkit)

그래픽과 이미지를 그리기 위한 도구
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • 추가적인 api 호출을 하지 않아도 된다.

기술 선택

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
-하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

유지 보수

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
-따라서 다음과 같은 방법으로 공유하기로 했다.

  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. AWT를 사용한 부분을 문서화하여 공유한다.

레벨 3를 마무리하며 내용 추가

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
+ ./route.png

+

이미지 생성의 책임

+

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
+따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

+

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

+
    +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
+

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

+

고려한 기술

+

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

+
    +
  • Python의 Matplotlib
  • +
  • AWT(Abstract Window Toolkit) [최종 선택]
  • +
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • +
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)
  • +
+

Python & Matplotlib

+

데이터 시각화 라이브러리
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

+
    +
  • 코드가 간단해서 유지 보수성이 좋다.
  • +
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • +
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.
  • +
+

Java AWT 이외의 라이브러리

+

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

+
라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음
+

Java & AWT(Abstract Window Toolkit)

+

그래픽과 이미지를 그리기 위한 도구
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

+
    +
  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • +
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • +
  • 추가적인 api 호출을 하지 않아도 된다.
  • +
+

기술 선택

+

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
+하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

+

유지 보수

+

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
+따라서 다음과 같은 방법으로 공유하기로 했다.

+
    +
  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. +
  3. AWT를 사용한 부분을 문서화하여 공유한다.
  4. +
+

레벨 3를 마무리하며 내용 추가

+

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
AWT를 사용하는 부분에서 애플리케이션 실행 시간을 제외하면 파이썬과 비슷한 시간안에 이미지를 생성할 수 있었다.

]]>
image awt @@ -451,22 +2056,96 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/java-spring-springboot Mon, 24 Jul 2023 00:00:00 GMT - 자바 17, 스프링 6.0, 스프링 부트 3.1

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
-2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

자바 변경 사항

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
-따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

Switch Expressions(Java 14)

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

enum RESULT {
WIN, LOSE, DRAW
}

RESULT result = RESULT.WIN;

int prize = switch (result) {
case WIN -> 10_000_000;
case LOSE, DRAW -> 5_000_000;
default -> 0;
};

주요 특징은 다음과 같다.

  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • break 문이 필요 없다.
  • default 블록을 통해 기본 값을 지정할 수 있다.

Text Block(Java 15)

Java 15에는 새로운 문자열 표현방식이 추가되었다.
-긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("""
SELECT p FROM Post p
WHERE p.title LIKE %:keyword%
OR p.content LIKE %:keyword%
""")
List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
}

NPE 메시지(Java 15)

String name = null;
name.chars();

/**
# before
java.lang.NullPointerException
at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)

# after
Cannot invoke "String.chars()" because "name" is null
java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
*/

Record(Java 16)

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
+ 자바 17, 스프링 6.0, 스프링 부트 3.1 +

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
+2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

+

자바 변경 사항

+

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
+따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

+

Switch Expressions(Java 14)

+

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

+
enum RESULT {
+    WIN, LOSE, DRAW
+}
+
+RESULT result = RESULT.WIN;
+
+int prize = switch (result) {
+    case WIN -> 10_000_000;
+    case LOSE, DRAW -> 5_000_000;
+	default -> 0;
+};
+
+

주요 특징은 다음과 같다.

+
    +
  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • +
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • +
  • break 문이 필요 없다.
  • +
  • default 블록을 통해 기본 값을 지정할 수 있다.
  • +
+

Text Block(Java 15)

+

Java 15에는 새로운 문자열 표현방식이 추가되었다.
+긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

+
@Repository
+public interface PostRepository extends JpaRepository<Post, Long> {
+    @Query("""
+        SELECT p FROM Post p
+        WHERE p.title LIKE %:keyword%
+        OR p.content LIKE %:keyword%
+        """)
+    List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
+}
+
+

NPE 메시지(Java 15)

+
String name = null;
+name.chars();
+
+/** 
+# before
+java.lang.NullPointerException
+	at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)
+
+# after
+Cannot invoke "String.chars()" because "name" is null
+java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
+*/
+
+

Record(Java 16)

+

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
Record를 선언하는 경우 접근자, 생성자, equals & hashcode, toString이 제공된다.
-데이터 전송 용도로 적합해 보인다.

public record PostDto(String title, String content) {
}

추가적인 변경사항

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

스프링, 스프링 부트 변경 사항

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
-따라서 필요해보이는 몇개 정도만 정리했다.

스프링 요구사항

Java 17, Jakarta EE 9 이상이어야 한다.

네임스페이스 변경

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

PathPatternParser - trailing slash 허용하지 않음

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
-6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

PathPatternParser used by default (with the ability to opt into PathMatcher).

HTTP interface client

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
-자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

스프링 부트 최소 요구사항

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
-이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

참고 자료

어느 월급쟁이개발자 의 스프링 부트 따라잡기
-자바 9-16 주요 특징 복습하기
-Java EE에서 Jakarta EE로의 전환
-Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
-What's New in Spring Framework 6.x
-Spring Boot 3.0 Release Notes
-Spring Boot 3.1 Release Notes

]]>
+데이터 전송 용도로 적합해 보인다.

+
public record PostDto(String title, String content) {
+}
+
+

추가적인 변경사항

+

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

+

스프링, 스프링 부트 변경 사항

+

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
+따라서 필요해보이는 몇개 정도만 정리했다.

+

스프링 요구사항

+

Java 17, Jakarta EE 9 이상이어야 한다.

+

네임스페이스 변경

+

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

+

PathPatternParser - trailing slash 허용하지 않음

+

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
+6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

+
+

PathPatternParser used by default (with the ability to opt into PathMatcher).

+
+

HTTP interface client

+

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
+자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

+

스프링 부트 최소 요구사항

+

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
+이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

+

참고 자료

+

어느 월급쟁이개발자 의 스프링 부트 따라잡기
+자바 9-16 주요 특징 복습하기
+Java EE에서 Jakarta EE로의 전환
+Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
+What's New in Spring Framework 6.x
+Spring Boot 3.0 Release Notes
+Spring Boot 3.1 Release Notes

]]> Java Spring Boot Spring @@ -477,20 +2156,67 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/websocket Mon, 26 Jun 2023 00:00:00 GMT - 웹소켓

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
-웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

웹소켓 등장 배경

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
-이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

polling, long polling, streaming

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.

웹소켓의 동작

1. Upgrade 요청

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
+ 웹소켓 +

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
+웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

+

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

+

웹소켓 등장 배경

+

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
+이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

+

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

    +
  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • +
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.
  • +

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

    +
  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.
  • +

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

    +
  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.
  • +
+

웹소켓의 동작

+ +

1. Upgrade 요청

+

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
이는 HTTP와 같이 80, 443 포트를 사용한다.
웹소켓으로 전환하기 위해서는 Upgrade: websocket, Connection: Upgrade 헤더가 필요하다.
Sec-WebSocket-Key는 서버에서 Sec-WebSocket-Accept를 계산하여 응답하고 이 값이 예상한 값과 다르면 연결이 수립되지 않는다.
Sec-WebSocket-Protocol의 경우 서브프로토콜의 목록으로 서버 측에서는 해당 목록 중 하나를 선택하여 반환해야 한다.
-만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

GET /chats HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

2. Switching Protocols

서버는 101 Switching Protocols 응답을 반환한다.
+만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

+
GET /chats HTTP/1.1
+Host: localhost:8080
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
+Sec-WebSocket-Protocol: v10.stomp, v11.stomp
+Sec-WebSocket-Version: 13
+Origin: http://localhost:8080
+
+

2. Switching Protocols

+

서버는 101 Switching Protocols 응답을 반환한다.
Sec-WebSocket-Accept은 Sec-WebSocket-Key 뒤에 258EAFA5-E914-47DA-95CA-C5AB0DC85B11를 붙이고 SHA1로 해싱 후 Base64로 인코딩하여 반환한다.
-이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

3. 통신 후 종료

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
-연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

참고 자료

https://datatracker.ietf.org/doc/html/rfc6455
-https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
-https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
-https://docs.spring.io/spring-framework/reference/web/websocket.html

]]>
+이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

+
HTTP/1.1 101 Switching Protocols 
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
+Sec-WebSocket-Protocol: v10.stomp
+
+

3. 통신 후 종료

+

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
+연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

+

참고 자료

+

https://datatracker.ietf.org/doc/html/rfc6455
+https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
+https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
+https://docs.spring.io/spring-framework/reference/web/websocket.html

]]> WebSocket @@ -499,27 +2225,355 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 https://greeng00se.github.io/docusaurus Sun, 18 Jun 2023 00:00:00 GMT - 팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.

설치

공식 홈페이지에 들어가서 최신 버전을 설치한다.

yarn create docusaurus

배포

배포 안내 문서
+ 팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.

+

설치

+

공식 홈페이지에 들어가서 최신 버전을 설치한다.

+
yarn create docusaurus
+
+

배포

+

배포 안내 문서
netlify나 vercel 같은 서버리스 플랫폼을 추천하고 있고, 간단하고, 빠른 시간 안에 배포를 할 수 있다.
-이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.

레포지토리 생성

github pages를 이용하려면 예시와 같이 username.github.io 형태의 레포지토리를 생성해야 한다.
-이때 organization을 사용하는 경우 organization.github.io 형태의 레포지토리를 생성해서 사용한다.

설정 파일 수정

docusaurus.config
module.exports = {
// ...
url: 'https://greeng00se.github.io',
baseUrl: '/',
projectName: 'greeng00se.github.io',
organizationName: 'greeng00se',
trailingSlash: false,
// ...
};

토큰 설정

github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.
-이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.

github

브랜치 생성

github에서 gh-pages 브랜치를 하나 생성한다.
+이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.

+

레포지토리 생성

+

github pages를 이용하려면 예시와 같이 username.github.io 형태의 레포지토리를 생성해야 한다.
+이때 organization을 사용하는 경우 organization.github.io 형태의 레포지토리를 생성해서 사용한다.

+

설정 파일 수정

+
module.exports = {
+  // ...
+  url: 'https://greeng00se.github.io',
+  baseUrl: '/',
+  projectName: 'greeng00se.github.io',
+  organizationName: 'greeng00se',
+  trailingSlash: false,
+  // ...
+};
+
+

토큰 설정

+

github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.
+이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.

+

github

+

브랜치 생성

+

github에서 gh-pages 브랜치를 하나 생성한다.
repository -> settings -> pages -> branch에서 생성한 gh-pages로 브랜치를 변경한다.
-설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.

워크플로 작성

Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.
-배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.

.github/workflows/deploy.yml
name: blog

on:
push:
branches: [main]

jobs:
deploy:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build website
run: yarn build

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.DEPLOY_TOKEN }}
publish_dir: ./build
user_name: github-actions[bot]
user_email: 41898282+github-actions[bot]@users.noreply.github.com

댓글 기능

giscus를 이용하여 댓글 기능을 추가한다.

giscus 설정

  1. 공개 저장소여야 한다.
  2. giscus 앱이 설치되어 있어야 한다.
  3. Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.

자세한 내용은 giscus를 확인하자.

docusaurus 설정

swizzling을 이용하여 컴포넌트를 감싼다.
+설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.

+

워크플로 작성

+

Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.
+배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.

+
name: blog
+
+on:
+  push:
+    branches: [main]
+
+jobs:
+  deploy:
+    name: Deploy to GitHub Pages
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@v3
+        with:
+          node-version: 18
+          cache: yarn
+
+      - name: Install dependencies
+        run: yarn install --frozen-lockfile
+      - name: Build website
+        run: yarn build
+
+      - name: Deploy to GitHub Pages
+        uses: peaceiris/actions-gh-pages@v3
+        with:
+          github_token: ${{ secrets.DEPLOY_TOKEN }}
+          publish_dir: ./build
+          user_name: github-actions[bot]
+          user_email: 41898282+github-actions[bot]@users.noreply.github.com
+
+

댓글 기능

+

giscus를 이용하여 댓글 기능을 추가한다.

+

giscus 설정

+
    +
  1. 공개 저장소여야 한다.
  2. +
  3. giscus 앱이 설치되어 있어야 한다.
  4. +
  5. Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.
  6. +
+

자세한 내용은 giscus를 확인하자.

+

docusaurus 설정

+

swizzling을 이용하여 컴포넌트를 감싼다.
기존에 게시물을 giscus가 포함된 리액트 컴포넌트로 감싸는 형태가 된다.
-아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.

yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap

명령어를 입력하면 /src/theme/BlogPostItem/index.js 위치에 파일이 생성된다.
-파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.

/src/theme/BlogPostItem/index.js
import OriginalBlogPostItem from "@theme-original/BlogPostItem";
import React, { useEffect, useRef } from "react";
// @ts-expect-error internal code
import { useColorMode } from "@docusaurus/theme-common";
import { useBlogPost } from "@docusaurus/theme-common/internal";

const giscusSelector = "iframe.giscus-frame";

function BlogPostItem(props) {
const { colorMode } = useColorMode();
const { isBlogPostPage } = useBlogPost();
const giscusTheme = colorMode === "dark" ? "dark" : "light";
const containerRef = useRef(null);

useEffect(() => {
if (!isBlogPostPage) return;

const giscusEl = containerRef.current.querySelector(giscusSelector);

const createGiscusEl = () => {
const script = document.createElement("script");

script.src = "https://giscus.app/client.js";
script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");
script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");
script.setAttribute("data-category", "Announcements");
script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");
script.setAttribute("data-mapping", "pathname");
script.setAttribute("data-strict", "0");
script.setAttribute("data-reactions-enabled", "1");
script.setAttribute("data-emit-metadata", "0");
script.setAttribute("data-input-position", "bottom");
script.setAttribute("data-theme", giscusTheme);
script.setAttribute("data-lang", "ko");
script.crossOrigin = "anonymous";
script.async = true;

containerRef.current.appendChild(script);
};

const postThemeMessage = () => {
const message = {
setConfig: {
theme: giscusTheme,
}
};

giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
};

giscusEl ? postThemeMessage() : createGiscusEl();
}, [giscusTheme]);

return (
<>
<OriginalBlogPostItem {...props} />
{isBlogPostPage && <div ref={containerRef} />}
</>
);
}

export default BlogPostItem;

알고리아 설정 및 직접 관리하기

알고리아를 사용하면 검색 기능을 추가할 수 있다.
-유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.

무료 플랜은 직접 인덱스를 수집하는 방법과, docsearch를 이용하는 방법이 있다.
+아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.

+
yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap
+
+

명령어를 입력하면 /src/theme/BlogPostItem/index.js 위치에 파일이 생성된다.
+파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.

+
import OriginalBlogPostItem from "@theme-original/BlogPostItem";
+import React, { useEffect, useRef } from "react";
+// @ts-expect-error internal code
+import { useColorMode } from "@docusaurus/theme-common";
+import { useBlogPost } from "@docusaurus/theme-common/internal";
+
+const giscusSelector = "iframe.giscus-frame";
+
+function BlogPostItem(props) {
+  const { colorMode } = useColorMode();
+  const { isBlogPostPage } = useBlogPost();
+  const giscusTheme = colorMode === "dark" ? "dark" : "light";
+  const containerRef = useRef(null);
+
+  useEffect(() => {
+    if (!isBlogPostPage) return;
+
+    const giscusEl = containerRef.current.querySelector(giscusSelector);
+
+    const createGiscusEl = () => {
+      const script = document.createElement("script");
+
+      script.src = "https://giscus.app/client.js";
+      script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");
+      script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");
+      script.setAttribute("data-category", "Announcements");
+      script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");
+      script.setAttribute("data-mapping", "pathname");
+      script.setAttribute("data-strict", "0");
+      script.setAttribute("data-reactions-enabled", "1");
+      script.setAttribute("data-emit-metadata", "0");
+      script.setAttribute("data-input-position", "bottom");
+      script.setAttribute("data-theme", giscusTheme);
+      script.setAttribute("data-lang", "ko");
+      script.crossOrigin = "anonymous";
+      script.async = true;
+      
+      containerRef.current.appendChild(script);
+    };
+
+    const postThemeMessage = () => {
+      const message = {
+        setConfig: {
+          theme: giscusTheme,
+        }
+      };
+
+      giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
+    };
+
+    giscusEl ? postThemeMessage() : createGiscusEl();
+  }, [giscusTheme]);
+
+  return (
+    <>
+      <OriginalBlogPostItem {...props} />
+      {isBlogPostPage && <div ref={containerRef} />}
+    </>
+  );
+}
+
+export default BlogPostItem;
+
+

알고리아 설정 및 직접 관리하기

+

알고리아를 사용하면 검색 기능을 추가할 수 있다.
+유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.

+

무료 플랜은 직접 인덱스를 수집하는 방법과, docsearch를 이용하는 방법이 있다.
docsearch에 등록한다면 일주일에 한 번씩 크롤링이 진행된다.
-이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.

알고리아 애플리케이션 생성 및 키 확인

회원가입을 하고 새로운 애플리케이션 생성을 누른다.
-생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.

algolia

키 생성

직접 인덱스를 수집하기 위한 키를 생성한다.
-addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.

key

.env 파일 생성

프로젝트 폴더 상단에 .env 파일을 생성한다.

.env
APPLICATION_ID=MVIU5UEMOM
API_KEY=인덱스_생성용_키

config 파일 생성

마찬가지로 최상단에 config.json 파일을 생성한다. -설정 파일은 해당 링크를 참고한다.
-또는 Docusaurus의 설정 파일을 참고한다.

config.json
{
"index_name": "teco",
"start_urls": [
"https://teco-chat.github.io/"
],
"sitemap_urls": [
"https://teco-chat.github.io/sitemap.xml"
],
"sitemap_alternate_links": true,
"stop_urls": [
"/tests"
],
"selectors": {
"lvl0": {
"selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
"type": "xpath",
"global": true,
"default_value": "Documentation"
},
"lvl1": "header h1",
"lvl2": "article h2",
"lvl3": "article h3",
"lvl4": "article h4",
"lvl5": "article h5, article td:first-child",
"lvl6": "article h6",
"text": "article p, article li, article td:last-child"
},
"strip_chars": " .,;:#",
"custom_settings": {
"separatorsToIndex": "_",
"attributesForFaceting": [
"language",
"version",
"type",
"docusaurus_tag"
],
"attributesToRetrieve": [
"hierarchy",
"content",
"anchor",
"url",
"url_without_anchor",
"type"
]
},
"conversation_id": [
"833762294"
],
"nb_hits": 46250
}

docker 이용하여 크롤링

docker와 jq가 필요하다.
-jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.

brew install jq

다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.

docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper

docusaurus 설정

전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.

docusaurus.config
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...
algolia: {
appId: 'MVIU5UEMOM', // Application ID
apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key
indexName: 'teco', // config.json에 설정한 인덱스명
contextualSearch: true,
},
})

부가 설정

화면 상단 Github Icon

파일 최하단에 아래 css 구문을 추가한다.

/src/css/custom.css
.header-github-link:hover {
opacity: 0.6;
}

.header-github-link:before {
content: '';
width: 24px;
height: 24px;
display: flex;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}

html[data-theme='dark'] .header-github-link:before {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}

themeconfig -> navbar에 github link를 설정한다.

docusaurus.config
navbar: {
title: 'HELLO',
items: [
{
href: 'https://github.com/greeng00se',
position: 'right',
className: 'header-github-link',
'aria-label': 'GitHub repository',
},
],
},

코드블럭

java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.
-prism 설정을 아래와 같이 변경해 준다.

docusaurus.config
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
additionalLanguages: ['java', 'kotlin'],
}

mermaid

mermaid를 사용하려면 @docusaurus/theme-mermaid 를 설치해야 한다.

yarn add @docusaurus/theme-mermaid

설치 후 아래와 같이 설정을 추가한다.

docusaurus.config
const config = {
...
markdown: {
mermaid: true,
},
themes: [
'@docusaurus/theme-mermaid'
],
};

themeConfig에서 mermaid의 테마를 지정할 수 있다.

docusaurus.config
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...
mermaid: {
theme: {
light: 'neutral',
dark: 'dark'
},
},
}),

국제화 설정

국제화 설정을 한다면 Older Entries 형태의 설명이 다음 페이지 로 변경된다.
-설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.

docusaurus.config
i18n: {
defaultLocale: "ko",
locales: ["ko"],
},

블로그 글 author

팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.

author

authors.yml 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.

/blog/authors.yml
herb:
name: 허브
title: Backend
url: https://github.com/greeng00se
image_url: https://github.com/greeng00se.png

mallang:
name: 말랑
title: Backend
url: https://github.com/shin-mallang
image_url: https://github.com/shin-mallang.png

블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.

---
slug: 1
title: Hello World
authors: [herb, mallang]
tags: [hello, docusaurus]
---

첫 번째 문서 내용
]]>
+이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.

+ +

알고리아 애플리케이션 생성 및 키 확인

+

회원가입을 하고 새로운 애플리케이션 생성을 누른다.
+생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.

+

algolia

+

키 생성

+

직접 인덱스를 수집하기 위한 키를 생성한다.
+addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.

+

key

+

.env 파일 생성

+

프로젝트 폴더 상단에 .env 파일을 생성한다.

+
APPLICATION_ID=MVIU5UEMOM
+API_KEY=인덱스_생성용_키
+
+

config 파일 생성

+

마찬가지로 최상단에 config.json 파일을 생성한다. +설정 파일은 해당 링크를 참고한다.
+또는 Docusaurus의 설정 파일을 참고한다.

+
{
+  "index_name": "teco",
+  "start_urls": [
+    "https://teco-chat.github.io/"
+  ],
+  "sitemap_urls": [
+    "https://teco-chat.github.io/sitemap.xml"
+  ],
+  "sitemap_alternate_links": true,
+  "stop_urls": [
+    "/tests"
+  ],
+  "selectors": {
+    "lvl0": {
+      "selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
+      "type": "xpath",
+      "global": true,
+      "default_value": "Documentation"
+    },
+    "lvl1": "header h1",
+    "lvl2": "article h2",
+    "lvl3": "article h3",
+    "lvl4": "article h4",
+    "lvl5": "article h5, article td:first-child",
+    "lvl6": "article h6",
+    "text": "article p, article li, article td:last-child"
+  },
+  "strip_chars": " .,;:#",
+  "custom_settings": {
+    "separatorsToIndex": "_",
+    "attributesForFaceting": [
+      "language",
+      "version",
+      "type",
+      "docusaurus_tag"
+    ],
+    "attributesToRetrieve": [
+      "hierarchy",
+      "content",
+      "anchor",
+      "url",
+      "url_without_anchor",
+      "type"
+    ]
+  },
+  "conversation_id": [
+    "833762294"
+  ],
+  "nb_hits": 46250
+}
+
+

docker 이용하여 크롤링

+

docker와 jq가 필요하다.
+jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.

+
brew install jq
+
+

다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.

+
docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper
+
+

docusaurus 설정

+

전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.

+
themeConfig:
+  /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+  ({
+    ...
+    algolia: {
+      appId: 'MVIU5UEMOM', // Application ID
+      apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key
+      indexName: 'teco', // config.json에 설정한 인덱스명
+      contextualSearch: true,
+    },
+  })
+
+

부가 설정

+

화면 상단 Github Icon

+

파일 최하단에 아래 css 구문을 추가한다.

+
.header-github-link:hover {
+  opacity: 0.6;
+}
+
+.header-github-link:before {
+  content: '';
+  width: 24px;
+  height: 24px;
+  display: flex;
+  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
+    no-repeat;
+}
+
+html[data-theme='dark'] .header-github-link:before {
+  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
+    no-repeat;
+}
+
+

themeconfig -> navbar에 github link를 설정한다.

+
navbar: {
+  title: 'HELLO',
+  items: [
+    {
+        href: 'https://github.com/greeng00se',
+        position: 'right',
+        className: 'header-github-link',
+        'aria-label': 'GitHub repository',
+    },
+  ],
+},
+
+

코드블럭

+

java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.
+prism 설정을 아래와 같이 변경해 준다.

+
prism: {
+  theme: lightCodeTheme,
+  darkTheme: darkCodeTheme,
+  additionalLanguages: ['java', 'kotlin'],
+}
+
+

mermaid

+

mermaid를 사용하려면 @docusaurus/theme-mermaid 를 설치해야 한다.

+
yarn add @docusaurus/theme-mermaid
+
+

설치 후 아래와 같이 설정을 추가한다.

+
const config = {
+  ...
+  markdown: {
+    mermaid: true,
+  },
+  themes: [
+    '@docusaurus/theme-mermaid'
+  ],
+};
+
+

themeConfig에서 mermaid의 테마를 지정할 수 있다.

+
themeConfig:
+    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+    ({
+      ...
+      mermaid: {
+        theme: {
+          light: 'neutral', 
+          dark: 'dark'
+        },
+      },
+    }),
+
+

국제화 설정

+

국제화 설정을 한다면 Older Entries 형태의 설명이 다음 페이지 로 변경된다.
+설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.

+
i18n: {
+  defaultLocale: "ko",
+  locales: ["ko"],
+},
+
+

블로그 글 author

+

팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.

+

author

+

authors.yml 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.

+
herb:
+  name: 허브
+  title: Backend
+  url: https://github.com/greeng00se
+  image_url: https://github.com/greeng00se.png
+
+mallang:
+  name: 말랑
+  title: Backend
+  url: https://github.com/shin-mallang
+  image_url: https://github.com/shin-mallang.png
+
+

블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.

+
---
+slug: 1
+title: Hello World
+authors: [herb, mallang]
+tags: [hello, docusaurus]
+---
+
+첫 번째 문서 내용
+
]]> Documentation
@@ -529,848 +2583,29 @@ DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최 Sun, 11 Jun 2023 00:00:00 GMT 23년의 6월이 오고, 레벨 2가 끝났다.
-빠르게 지나가서 조금 아쉽다.

학습

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
+빠르게 지나가서 조금 아쉽다.

+

학습

+

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
항상 아쉬운 곳은 있기 마련이지만, 잘 학습한 것 같다.
-미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
-방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
-필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

수면

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
-앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

협업

레벨 2 마지막에 협업 미션이 있었다.
+미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

+

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
+방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

+

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
+필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

+

수면

+

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
+앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

+

협업

+

레벨 2 마지막에 협업 미션이 있었다.
지금까지는 백엔드 크루들과 페어 프로그래밍을 하면서 협업을 경험했다.
-이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
-팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

레벨 2를 마무리하며

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. +이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

+

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
+팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

+

레벨 2를 마무리하며

+

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. 읽고 싶은 책도 읽고, 부족한 부분 채우면서 쉬어야겠다.

]]>
Woowahan Techcourse Retrospective
- - <![CDATA[레벨 2 - 레벨 인터뷰 회고]]> - https://greeng00se.github.io/level2-interview-retrospective - https://greeng00se.github.io/level2-interview-retrospective - Thu, 08 Jun 2023 00:00:00 GMT - - 레벨 인터뷰

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
-따라서 레벨 1 레벨 인터뷰 회고는 레벨 1 회고를 작성할 때 끼워넣었다.
-이번에는 범위도 제한되어 있어 어떻게 준비해야 할지 당황했고, 답변에도 부족한 부분이 많았었다.
-기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

API 문서 도구 선택

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
-백엔드 팀원이 함께 의사결정을 했고, 미션 기간이 짧은 만큼 팀 차원에서 비교적 학습하기 쉬운 Swagger를 선택했다.
-추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
-앞으로도 학습 비용은 주요하게 고려해야 할 사항

PUT과 PATCH & 토큰과 세션

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
-토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
-실제로 레벨 2 때 이론적인 학습 시간이 매우 적었고, 집중력도 많이 부족했다.
-앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

그 외 개선할 점

인터뷰할 때 특유의 말버릇을 개선하기
-생각할 시간을 가졌을 때 "다시 말씀드려도 될까요?"라고 말하고 답변을 이어나가기
-기술적으로 깊이가 부족하다고 생각이 많이 들어서 조금 더 깊게 공부하고 정리하기
-이전에 공부했던거 되돌아 보는 시간 가지기

]]>
- Woowahan Techcourse - Retrospective -
- - <![CDATA[장바구니 주문 미션 회고]]> - https://greeng00se.github.io/order-retrospective - https://greeng00se.github.io/order-retrospective - Sun, 04 Jun 2023 00:00:00 GMT - -
PR 링크

장바구니 주문 미션

배포 및 협업을 할 수 있는 미션이었다.
-마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

배포

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
-각자 하나의 EC2 인스턴스를 제공받을 수 있었고, 팀 별로 DB를 위한 추가 인스턴스를 제공받았다.
-배포 스크립트를 작성하는 경험을 해볼 수 있었다.
-배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

echo "Start Deploy Script"
REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
PROJECT_NAME=jwp-shopping-order

echo "Change Directory"
cd $REPOSITORY_NAME

echo "Git Pull"
git pull origin step2

echo "Build"
./gradlew bootJar

echo "Copy, Start Server"
mv ./build/libs/$PROJECT_NAME.jar .

PID=$(pgrep -f $PROJECT_NAME)

if [ -n $PID ]; then
kill -9 $PID
sleep 5
fi

nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &

협업

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
-백엔드가 아닌 다른 크루들과 해보는 첫 협업이라 약간 두근거렸다.
-예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

부족했던 부분

여러가지 방법에 대한 장단점을 고려해보기

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
-조금 더 시간을 많이 들여서 장단점을 고려했다면 더 좋은 결과물이 나오지 않았을까?
-앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

새로 배운 부분

expose headers

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
-기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
-이를 expose headers 설정을 통해 해결할 수 있었다.
-nginx 설정에 다음과 같이 추가해 주었다.

add_header 'Access-Control-Expose-Headers' 'Location'

읽기 전용 트랜잭션

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
-이번에 코멘트가 달려서 조금 더 자세히 공부해 보기로 했다.
-Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
-추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

DAO에 @Transactional 적용

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
-Service 계층에 이미 트랜잭션을 보장해 주고 있기에 필요 없지 않을까 생각했었다.
-DAO를 다른 곳에서 사용하더라도 트랜잭션을 보장하기 위해(확장성 고려) @Transactional을 적용하는 것도 괜찮은 것 같다.

]]> - Woowahan Techcourse - Retrospective - - - <![CDATA[[테코챗] 3. 기능 구현]]> - https://greeng00se.github.io/tecochat-retrospective-3 - https://greeng00se.github.io/tecochat-retrospective-3 - Thu, 01 Jun 2023 00:00:00 GMT - - 개요

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
-레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

나의 채팅 확인하고 이어하는 기능

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
-예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

chat1

좋아요와 댓글 기능

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
-누가 좋아요를 눌렀는지, 어떤 채팅이 좋아요를 가장 많이 받았는지 확인할 수 있는 기능을 추가했다.
-또한 댓글 추가 및 삭제 기능도 추가했다.

키워드 추출

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
-해당 부분은 첫 질문에 대한 키워드만 추출하도록 했다.
-백엔드에선 말랑이 이벤트 이용해서 첫 채팅 요청이 이루어지면, 비동기로 키워드를 추출하는 질문을 추가로 날리도록 구현하였다.
-CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

chat2

다른 크루의 채팅 복사해서 이어하는 기능

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
-채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

사용성 고려하기

chat3

위 화면은 회원가입 창이다.
-사실 가장 마음에 드는 부분이고, 회원가입(닉네임만 입력하지만)할 때 익명을 원하는 사람들의 고민을 도와주게 끔 음식, 과일, 과자 등의 요소들을 입력하도록 유도했다! -추가로 GPT의 답변이 오면 자동으로 화면을 스크롤 해주는 것과 같이 사용성을 개선해 보려고 노력했지만 쉽지 않았다.
-제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

향후 계획

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
-크루들이 직접 사용해 주니까 너무 고맙고, 한편으로는 신기하다.
-일단 방학 때 stream/text 관련된 부분 동작되도록 구현해보려고 하고, 그 외의 부분은 조금 더 고민해야될 것 같다.

]]>
- TecoChat - Retrospective -
- - <![CDATA[컴포지트 패턴으로 요금 정책 추상화하기]]> - https://greeng00se.github.io/composite - https://greeng00se.github.io/composite - Fri, 26 May 2023 00:00:00 GMT - - 요구사항

지하철 미션에는 다음과 같은 요구사항이 있었다.

  • 거리별 추가 요금 정책
  • 노선별 추가 요금 정책
  • 연령별 요금 할인 정책

인터페이스 사용

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
-요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

public interface FarePolicy {
int calculate(Path path, Passenger passenger, int fare);
}

public class BaseFarePolicy implements FarePolicy { ... }
public class DistanceFarePolicy implements FarePolicy { ... }
public class AgeDiscountFarePolicy implements FarePolicy { ... }

composite1

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
-이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

public class SubwayFarePolicy implements FarePolicy {

private final List<FarePolicy> farePolicies;

public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
this.farePolicies = farePolicies;
}

@Override
public int calculate(final Path path, final Passenger passenger, final int fare) {
int calculatedFare = fare;
for (FarePolicy farePolicy : farePolicies) {
calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
}
return calculatedFare;
}
}

따라서 그림으로 본다면 다음과 같은 구조가 된다.

composite2

정책의 순서

지하철 요구사항은 순서가 중요했다.
-금액의 총합을 구하고, 그 후에 할인 정책이 들어가야했다.
-따라서 자식들의 순서를 관리할 때 주의를 기울여야 했다.
-Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

@Configuration
public class FareConfiguration {

@Bean
public FarePolicy farePolicy() {
return new SubwayFarePolicy(List.of(
new BaseFarePolicy(),
new DistanceFarePolicy(),
new AgeDiscountFarePolicy()
));
}
}

컴포지트 패턴이란?

composite3

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
-사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

컴포지트 패턴의 구성요소

Component

  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • ex) 요금 정책(FarePolicy)

Leaf

  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • ex) 거리 별 요금 정책(DistanceFarePolicy)

Composite

  • 여러 개의 개발 객체를 포함하는 합성 객체
  • ex) 지하철 요금 정책(SubwayFarePolicy)

Client

  • 인터페이스를 사용하는 클라이언트

컴포지트 패턴의 사용과 주요 목표

부분 - 전체의 관계를 표현하고 싶을 때
-Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

패턴 사용시 주의해야할 부분

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
-반복되는 문제를 효율적으로 해결할 수 있지만 패턴에 매몰되서는 안된다.
-패턴을 맹목적으로 사용해서는 안되고, 현재의 요구사항에 따라 패턴을 유동적으로 수정해가면서 적용하는 것이 좋다.
-항상 트레이드오프를 생각하자!

참고 자료

컴포지트 패턴, GoF의 디자인 패턴
-디자인 패턴과 프레임워크, 오브젝트

]]>
- Pattern - Composite -
- - <![CDATA[지하철 미션 회고]]> - https://greeng00se.github.io/subway-retrospective - https://greeng00se.github.io/subway-retrospective - Thu, 25 May 2023 00:00:00 GMT - -
PR 링크

지하철 미션

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
-지하철 미션은 밀리랑 페어를 진행했다.
-간단한 CRUD만 있던 이전 미션들과 달리, 조금 복잡한 도메인 요구사항이 있었다.
-이때 API, 테이블, 도메인 설계를 해야 했는데 어떤 것부터 해야 할지 고민을 많이 했다.
-API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

노선의 구간 추가 및 삭제

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. 변경된 요소만 데이터베이스에 반영하는 방법

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
-추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

부족했던 부분

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
-우아한테크코스를 진행하면서 알아야 하는 게 많아지면서 가끔 조바심을 가질 때가 있는 것 같은데, 조바심을 경계할 필요가 있을 것 같다.
-부족한 부분은 인정하고, 앞으로 나아가야겠다.

새로 학습한 부분

컴포지트 패턴으로 요금 정책 추상화

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
-요금을 더하는 부분과, 할인하는 부분이 있어서 이 둘을 분리할까 생각했지만, 이 정도 크기의 애플리케이션에서는 오히려 분리하지 않고 하나로 합치는 게 더 좋다고 생각했다.
-또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

도메인에 특정 기술의 의존성을 분리

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
-따라서 도메인 패키지 내에는 경로 검색에 대한 인터페이스를 두고, 세부 구현은 도메인 패키지 외부로 분리했다.
-최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

컴포지트 패턴

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

인수 테스트 작성

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
-브라운이 해주신 강의 + 유튜브에 있는 브라운의 강의를 보고 지하철 미션에 인수 테스트를 적용해 보았다.
-메서드, 변수명을 전부 한글로 작성했는데 전체적인 흐름을 알기 편하고 읽기도 좋았다.
-그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

결과는 아래와 같다.

@Nested
public class 노선을_전체_조회할_때 {

@Test
void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
// given
노선_생성_요청("2호선", "초록", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);

노선_생성_요청("9호선", "고동", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);

// when
final var 조회_결과 = 노선_전체_조회_요청();

// then
요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
노선_전체_조회_결과를_확인한다(
조회_결과,
노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
);
}
}

페어에게 배울 부분

의견 조율하기

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
-의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

꼼꼼하게 코딩하기

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
-변수명, 메서드명을 중요하게 생각했고, 좋은 변수명을 잘 짓는 것 같다.
-또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

편한 분위기

전체적으로 페어 할 때 편하게 진행했던 것 같다.
-일정도 그렇고, 페어 진행할 때도 그렇고 큰 문제가 없었던 것 같아서 좋았다.
-나는 과연 다른 사람들에게 편한 사람일까?

]]> - Woowahan Techcourse - Retrospective - - - <![CDATA[중복과 우발적 중복]]> - https://greeng00se.github.io/accidental-duplication - https://greeng00se.github.io/accidental-duplication - Wed, 24 May 2023 00:00:00 GMT - - 장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.
-요청에 담긴 Body를 통해 전달받은 값을 DTO로 매핑하여 추가와 수정을 했다.

장바구니 미션에서의 상품 추가 및 수정

중복1

클래스명을 제외하고 필드와 검증로직 그 외 모든게 같은 DTO를 보며 중복이라고 생각했다.
-하지만 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-위 경우는 중복일까? 중복이 아닐까?

이 부분에 대해서 다음과 같은 리뷰를 받았다.

ProductSaveRequestProductUpdateRequest가 완전히 동일한데, 재사용할 수 없을까? 라는 리뷰를 남겼었어요. 사실 생성과 수정은 서로 달라질 개연성이 높아서 미리 분리해놓는 게 더 좋은 방법이긴 한데, 그래도 중복은 싫어서 저도 요즘 이런저런 방법들을 시도해보는 중 입니다. 허브는 이 부분에 대해 어떤 생각을 가지고 있을지 궁금하네요 ㅎㅎ

질문에 대해 아래와 같이 답변을 했다.

저장과 수정할 때 필요한 필드값이 동일하여 현재 구조에서는 하나로 사용해도 된다고 생각을 하지만, 말씀해주신대로 요구사항이 변경된다면 달라질 가능성이 높다고 판단하였습니다!

중복과 우발적 중복

로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 거짓된 중복, 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다. -그렇기 때문에 위 상황은 우발적 중복으로 보인다. 그래도 중복을 제거해볼 수 있지 않을까?

하나로 사용하는 건 안좋아보이고, 중복은 제거하고 싶은 마음

지금은 추가, 수정 2가지 경우 밖에 없지만 조금 더 복잡한 요구사항이 주어져서 10가지 경우로 입력을 받으면 어떻게 해야할까?
-서비스 계층에서도 계층의 분리를 위해서 다른 DTO를 사용하고 있다면 20개의 DTO를 만들어야 할까?
-리뷰어가 알려준 의존 역전을 이용한 방법을 통해 이를 해결해보자!

중복 제거 전 코드

현재 코드에서는 아래와 같은 구조로 되어있다.
-Controller와 Service에서 저장, 수정할 때 각각의 DTO를 사용하고 있다. -현재 DTO는 controller, service 패키지 내에 있는 것이 아니라 dto라는 패키지에 위치하고 있다.

├── controller
│   └── ProductController
├── service
│   └── ProductService
├── dto
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest

중복2

인터페이스 작성하기

중복3

서비스 레이어에서 필요로 하는 값들을 인터페이스로 정의한다.
-해당 인터페이스는 서비스에서 사용하기 때문에 service 패키지 내부로 옮겨준다.

├── controller
│   └── ProductController
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public interface ProductSaveRequest {

String getName();

String getImage();

Long getPrice();
}

// ProductService
public Long save(final ProductSaveRequest request) {
final Product product = new Product(request.getName(), request.getImage(), request.getPrice());
return productDao.saveAndGetId(product);
}

구현체 작성하기

중복4

위에서 작성한 인터페이스를 구현하는 클래스를 작성한다.
-요청은 ProductRequest 클래스로 받고, 서비스에 전달할 땐 해당 인터페이스의 명세만 맞추면 문제없이 사용할 수 있다.

├── controller
│   ├── ProductController
│   └── ProductRequest
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {

@NotBlank(message = "이름은 공백일 수 없습니다.")
@Size(min = 1, max = 100, message = "이름은 최소 {min}자 이상, {max}자 이하여야 합니다.")
private final String name;

@NotBlank(message = "이미지는 공백일 수 없습니다.")
private final String image;

@Range(message = "가격은 최소 {min}원 이상, {max}원 이하여야 합니다.")
private final long price;

public ProductRequest(final String name, final String image, final long price) {
this.name = name;
this.image = image;
this.price = price;
}

@Override
public String getName() {
return name;
}

@Override
public String getImage() {
return image;
}

@Override
public long getPrice() {
return price;
}
}

// ProductController
@PostMapping("/products")
public ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {
final Long id = productService.save(request);
return ResponseEntity.created(URI.create("/products/" + id)).build();
}

정리

위와 같이 구현한다면 다음과 같은 장점을 얻을 수 있다.

  1. Service에서 모든 클라이언트 요청에 대한 DTO를 알지 않아도 된다.
  2. 공통적으로 사용하는 DTO를 제외하고 DTO 패키지에 대한 결합도가 낮아지고, 각 레이어의 응집도가 증가한다.
  3. 요청 객체만 다르고 서비스에서 동일한 행위를 수행하는 경우 중복을 제거할 수 있다.

위 방법을 지금 미션에서 바로 적용할까 하다가, 나중에 필요할 때 적용하면 더 좋을 것 같아서 미션에는 적용하지 않았다.
-상황에 맞춰 적재적소에 의존 역전을 이용해보는 것도 좋을 것 같다.

참고 자료

클린 아키텍처 16장 독립성, 로버트 C. 마틴
-https://techblog.woowahan.com/2647/
-https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/

]]>
- DTO -
- - <![CDATA[웹 장바구니 미션 회고]]> - https://greeng00se.github.io/shopping-cart-retrospective - https://greeng00se.github.io/shopping-cart-retrospective - Fri, 12 May 2023 00:00:00 GMT - -
PR 링크

웹 장바구니 미션

장바구니 미션은 블랙캣이랑 진행했다.
-요구사항이 엄청 복잡한 미션은 아니었고, 스프링을 사용하여 기본적인 CRUD를 구현하는 미션이었다.
-2단계에서는 Basic 인증을 통해 자신의 장바구니에만 상품을 담고, 제거할 수 있도록 구현하는 요구사항이 추가되었다.
-Interceptor나 Argument Resolver에 대한 이해도가 높지 않았는데, 이번 미션을 통해 조금 더 알아간 느낌이다.
-이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

새로 학습한 부분

DTO 우발적 중복

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

dto1

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
-따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

dto2

Interceptor에서 인증한 값 재사용

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
-일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
-웨지는 email에 index를 걸어두고 dao 재조회를 사용할 것이라고 했다.
-재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

페어에게 배울 부분

기록

블랙캣은 기록을 굉장히 잘 하는 크루였다.
-노션에 페어를 진행하면서 했던 내용 + 고민했던 부분 + 회고를 꼼꼼하게 기록해서 공유해 주었다.
-추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

의견 일치시키기

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
-따라서 적당히 타협을 봐서 의견을 빠르게 수용해 데드라인을 맞추는 것도 중요하다고 생각한다.
-블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

]]> - Woowahan Techcourse - Retrospective - - - <![CDATA[웹 자동차 미션 회고]]> - https://greeng00se.github.io/web-racing-car-retrospective - https://greeng00se.github.io/web-racing-car-retrospective - Tue, 02 May 2023 00:00:00 GMT - -
PR 링크

웹 자동차 미션

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
-웹 자동차 미션에서는 비버와 페어가 매칭되었다.
-레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
-첫 미션이라 그런지 특별한 부분은 없었고, 최대한 깔끔하게 작성하려고 노력했다.
-난이도 높은 미션이 아니었지만 리뷰어인 라빈에게 칭찬을 많이 받아서 기분이 좋았다.
-라빈 감사합니다!

부족했던 부분

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
-미션이 다소 여유롭다고 느껴져서, 시간에 대한 부분도 잘 관리하지 못한 것 같다.
-미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
-도전적이지 않거나 시간이 부족하지 않으면 집중을 잘 못하는 것 같다.
-머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

새로 학습한 부분

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@Transactional
@AutoConfigureMockMvc
@SpringBootTest
public class RacingGameIntegrationTest {

페어에게 배울 부분

비버의 성격
-비버가 성격이 좋아서 편하게 페어를 할 수 있었다.
-미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

미션에 집중하는 부분
-내가 미션에 잘 집중하지 못했는데도 같이 페어를 잘 진행한 것 같아서 좋았다.
-비버가 미션에 잘 집중해서 그렇지 않았나 생각했다.
-근육맨 비버라 그런지 체력이 좋아서 그런가?
-중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

학습에 대한 열정
-추가적으로 알고 싶은 부분을 따로 학습하는 열정이 좋다고 생각했다.
-비버와 스프링에 대해 알아가는 시간을 많이 가진 부분이 매우 좋았다.
-나도 5월부터 조금 더 화이팅 해야겠다.

]]> - Woowahan Techcourse - Retrospective - - - <![CDATA[[테코챗] 2. 배포]]> - https://greeng00se.github.io/tecochat-retrospective-2 - https://greeng00se.github.io/tecochat-retrospective-2 - Mon, 01 May 2023 00:00:00 GMT - - 프론트엔트

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
-추가로 채팅을 이어나갈 수 있게 하는 기능도 추가했다.
-자잘하게 신경 쓸 부분이 많아서, 프론트엔드 하는 사람들이 대단하다고 생각되었다.
-여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

백엔드

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
-말랑이 한 부분이 너무 많아서 내가 못 따라가는 것 같다.
-나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

Http Request Header

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
-말랑이 한글은 안된다고 말해줘서 Base64로 인코딩하고, 백엔드에서 디코딩 하여 사용하기로 했다.
-아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

const encodedName = () => {
const uriComponent = unescape(encodeURIComponent(name.value));
return btoa(uriComponent);
};

Elastic Beanstalk

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
-Elastic Beanstalk를 사용하면 인프라에 대해 잘 알지 못해도 애플리케이션을 빠르게 배포하고 관리할 수 있다.
-모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

Elastic Beanstalk RDS 설정 후 분리

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
-RDS 분리 시 Beanstalk에 기본적으로 설정되어 있는 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD와 같은 환경 변수가 같이 제거된다.
-추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

Elastic Beanstalk nginx 설정

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

Jenkins

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
-작년에 확인했을 땐 2022년 12월 31일까지 EC2 ARM 기반 t4g.small이 무료였는데, 다시 들어가 보니 2023년까지 12월 31일까지 t4g.small을 무료로 사용할 수 있었다.
-t4g.small은 램이 2G인데, 예전에는 부족하지 않았다고 생각했는데 Java 17을 써서 그런가 빌드 할 때 램이 많이 부족한 것 같아서 Swap 메모리 2기가를 추가로 설정했다.
-추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

test {
maxHeapSize = "1024m"
}

Jenkins Blue Ocean

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
-시각화도 잘 되어있고, 설정도 편리한 것 같다.
-오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

참고 자료

Elastic Beanstalk, AWS
-EC2 AWS Graviton, AWS
-Default Memory Settings, AWS

]]>
- TecoChat - Retrospective -
- - <![CDATA[Jenkins로 CI/CD 설정]]> - https://greeng00se.github.io/jenkins - https://greeng00se.github.io/jenkins - Sun, 30 Apr 2023 00:00:00 GMT - - 설정 환경

소프트웨어 이미지: Amazon Linux 2023 AMI
-아키텍쳐: ARM
-인스턴스 유형: t4g.small
-환경 구성이 완료된 Elastic Beanstalk
-단일 Spring Boot 프로젝트가 존재하는 Github Repository

[EC2 CLI] Swap 메모리 설정

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
-아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

# fallocate 이용하여 스왑 파일 생성
sudo fallocate -l 2G /swapfile

# 권한 설정
sudo chmod 600 /swapfile

# 파일을 Swap 포맷으로 변경 후 시스템에 등록
sudo mkswap /swapfile
sudo swapon /swapfile

# Swap 메모리 부팅시 자동으로 마운트하도록 적용
# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
sudo vim /etc/fstab

[EC2 CLI] jenkins 설치

sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install java-17-amazon-corretto-devel
sudo yum install jenkins
sudo systemctl daemon-reload

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

[EC2 CLI] Jenkins 시작

sudo systemctl enable jenkins
sudo systemctl start jenkins

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

[EC2 CLI] nginx & git 설치

sudo yum install nginx
sudo systemctl enable nginx
sudo systemctl start nginx

sudo yum install git

nginx와 코드를 불러올 때 사용할 git을 설치한다.

[EC2 CLI] nginx 리버스 프록시 설정

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

upstream jenkins {
keepalive 32; # keepalive connections
server 127.0.0.1:8080; # jenkins ip and port
}

# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 80; # Listen on port 80 for IPv4 requests

server_name jenkins.example.com; # replace 'jenkins.example.com' with your server domain name

# this is the jenkins web root directory
# (mentioned in the output of "systemctl cat jenkins")
root /var/run/jenkins/war/;

access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;

# pass through headers from Jenkins that Nginx considers invalid
ignore_invalid_headers off;

location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
# rewrite all static files into requests to the root
# E.g /static/12345678/css/something.css will become /css/something.css
rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
}

location /userContent {
# have nginx handle all the static requests to userContent folder
# note : This is the $JENKINS_HOME dir
root /var/lib/jenkins/;
if (!-f $request_filename){
# this file does not exist, might be a directory or a /**view** url
rewrite (.*) /$1 last;
break;
}
sendfile on;
}

location / {
sendfile off;
proxy_pass http://jenkins;
proxy_redirect default;
proxy_http_version 1.1;

# Required for Jenkins websocket agents
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_max_temp_file_size 0;

#this is the maximum upload size
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffering off;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection ""; # Clear for keepalive
}

}

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
-/etc/nginx/conf.d 아래 default.conf 파일을 하나 생성하고 위와 같이 입력하고 저장한다.
-nginx의 기본 설정 파일에 존재하는 include /etc/nginx/conf.d/*.conf; 설정 때문에 .conf 로 끝난다면 설정이 적용된다.
-설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

[Jenkins] Jenkins 접속

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
-EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

jenkins-start

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
-비밀번호를 입력하면 플러그인 설정 창이 나올텐데 install suggested plugins을 클릭하여 Jenkins가 추천하는 기본 플러그인들을 설치하면 된다.
-플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

[Jenkins] Jenkins Blue Ocean 설치

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
-IAM에서 다음과 같이 역할을 하나 새로 생성한다.

  1. 엔터티 선택

aws-iam1

  1. 권한 추가

aws-iam2

  1. 이름 지정, 검토 및 생성

aws-iam3

  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정

aws-iam4

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단

aws-s3

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

repo, user:email 권한이 있는 토큰이 필요하다.

[Jenkins] 블루 오션 시작

jenkins-blue-ocean1

블루 오션 열기로 파이프라인을 생성한다.
-토큰 입력 → 조직 선택 → CI/CD 설정할 Repository 선택을 하면 파이프라인 창으로 넘어간다.
-Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

jenkins-blue-ocean2

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

jenkins-blue-ocean3

[Github Repsoitory] Jenkinsfile 설정

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

pipeline {
agent any
stages {
stage('build and test') {
steps {
sh '/gradlew clean build'
}
}
stage('zip') {
steps {
sh 'mv ./build/libs/woowachat.jar .'
sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
}
}
stage('upload') {
steps {
sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
}
}
stage('deploy') {
steps {
sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
}
}
}
}

[Github] Webhooks 설정

github-hook

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

참고 자료

Install Jenkins - CentOS, Jenkins
-Nginx Reverse Proxy Configuration, Jenkins
-Amazon Corretto 17 JDK Install, AWS
-Amazon Linux 2023 packages, AWS

]]>
- Jenkins - Elastic Beanstalk -
- - <![CDATA[[테코챗] 1. 프로토타입 만들기]]> - https://greeng00se.github.io/tecochat-retrospective-1 - https://greeng00se.github.io/tecochat-retrospective-1 - Sat, 22 Apr 2023 00:00:00 GMT - - 4월 21일 금요일

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
-레벨 3, 4에서 나만의 강점을 가지고 싶어 고민을 많이 했다.
-단순히 스프링을 깊게 공부하는 건 효율이 많이 떨어진다고 생각했다.
-글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
-Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
-프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

이건 못참지

도메인 구입 성공?

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
-마치 어릴 때 했던 게임 닉네임 정하는 것처럼 시간이 오래 걸렸다.
-dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

말랑의 DM

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
-우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
-추가로 도메인에 관한 이야기를 하다가 woowachat이 언급되었고, namecheap에서 chat 도메인을 사용한 woowa.chat으로 구매했다.
-이후에 teco.chat으로 변경했다!

도메인 설정 및 배포

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
-나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

GPT

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
-일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

Sonarcloud

정적 코드 분석 도구로 Sonarcloud를 적용했다.
-Sonarcloud는 SonarQube의 SaaS 버전이고 사용이 매우 편하다.
-예전에 Sonarcloud를 사용할 땐 버튼 몇 번 누르면 적용할 수 있었는데, 이번에는 바로 github action을 사용하라는 안내 페이지로 이동했다.
-Sonarcloud가 자체적으로 github repository에 push 하면 정적 분석을 해주는 기능을 원했고, Administration -> Analysis Method에 Automatic Analysis를 설정하니 되었다.
-너무 꽁꽁 숨겨져있네

Tiptap

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
-Tiptap은 Headless WYSIWYG 에디터로 사용자 정의 기능에 특화되어있는 에디터다.
-아직 Tiptap이 제공하는 모든 기능을 자연스럽게 사용하지는 못하지만 CodeBlockLowlight 플러그인을 사용하여 코드 블록을 예쁘게 출력할 수 있었다.
-api 반환값 그대로 tiptap의 content에 설정했더니 코드 블록이 설정되지 않아서 백 틱 3개를 <pre><code>로 변환했다.
-추가로 띄어쓰기도 적용되지 않아서 \n<br>태그로 변환했다.
-변환하는 로직은 GPT의 도움을 많이 받았다.

const replaceCodeFences = (input: String) => {
const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
return input
.replace(codeFencesRegex, (match, p1, p2) => {
const languageClass = p1 ? ` class="language-${p1}"` : "";
return `<pre><code${languageClass}>${p2}</code></pre>`;
})
.replace(/\n/g, "<br>");
};

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

tecochat

폰트 및 favicon 적용

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
-추가로 favicon도 간단하게 적용해서 만족스러웠다.

]]>
- TecoChat - Retrospective -
- - <![CDATA[[책] 상자 밖에 있는 사람]]> - https://greeng00se.github.io/book-leadership-and-self-deception - https://greeng00se.github.io/book-leadership-and-self-deception - Sat, 08 Apr 2023 00:00:00 GMT - - 책 정보

상자 밖에 있는 사람
-아빈저연구소

자기기만과 자기배반

책에서는 자기기만과 자기배반에 대한 내용을 다룬다.

  • 자기기만: 자신의 문제를 인정하지 않는 것
  • 자기배반: 다른 사람을 위해 무언가 해야만 한다는 생각을 반하는 행위

자기배반을 한다면 자기기만 상태가 된다.
-자기기만 상태에 빠지는 것을 책에서는 상자 안에 들어간다고 표현한다.

읽고 나서

최근에 읽은 책 중 가장 마음이 불편했다.
-그렇기에 더더욱 나에게 필요한 내용이 담겨있었다.

살면서 많은 선택의 순간이 존재했고, 그 순간마다 자기배반을 택하는 경우가 많았다.
-작게는 집안일을 해야 하는데 몸이 조금 힘들다고 하지 않거나
-크게는 잘못을 인정해야 하는 상황에서 그러지 않은 경우가 있었다.
-이런 상황이 반복되어 결국 상자 안에 나 자신을 가두는 경우가 많았다.

더 나은 삶을 위해 내가 상자 안에 있는지 지속적으로 확인하고, 상자 밖으로 나가려는 연습을 해야겠다.
-넓은 시선을 가지고, 항상 내가 틀릴 수 있다는 것을 생각하고 살아가자.

밑줄 친 문장들

우리의 생각은 지식보다 작다.
-우리의 지식은 사랑보다 작다.
-우리의 사랑은 존재보다 작다.
-그리고 우리가 생각하는 나는 실제의 나보다 그만큼 작다.
-R. D. 랭
-p.19

우리가 외적으로 어떤 행동을 하든지 간에, 사람들은 우리 마음에서 그들을 어떻게 대하고 있는지에 따라 주로 반응합니다.
-우리가 사람들에 대해 어떻게 느끼게 되는지는 우리가 상자 안에 있는지 혹은 상자 밖에 있는지에 따라 달라지게 됩니다.
-p.66

비난은 감정에 속하고 낙관은 의지에 속한다.
-인간은 감정보다 더 큰 존재이다.
-알랭, 탁닛한
-p.103

우리가 자신에게만 집중하고 있는 한, 혼자서 일하는 것 이상의 창조적인 결과나 협력을 이끌어 낸다는 것은 불가능합니다.
-오늘날 경제 환경에서는 혼자서는 일의 결과를 탁월하게 만들어 내기가 어렵습니다.
-내가 중심이어야 된다는 폐쇄적인 사고는 함께 일하는 사람들의 열정을 불러오지 못합니다.
-p.175

솔직함은 우리의 문제를 해결하는 열쇠입니다.
-그것은 자신의 행동과 관련된 사람에 대해 기꺼이 사과를 하는 것입니다.
-그것만이 실타래처럼 엉킨 관계의 문제를 해결할 수 있기 때문이죠.
-p.188

누군가를 나와 같이 동일한 가치를 지닌 한 인간으로 생각해서 그 사람을 위해 내가 상자 밖에 계속 머무르고 싶은 열망이 생길 때, 나는 이미 그 사람에 대해 상자 밖에 있다.
-p.214

대부분의 사람들이 관계 기술을 가지고 그들이 겪고 있는 문제를 바로잡으려고 하는 노력이 결실을 얻지 못하는 것은 결코 그러한 기술 부족 때문에 생기는 것이 아닙니다.
-그것들은 자기배반 때문에 생겨납니다.
-p.224

우리는 함께 일하고 우리와 함께 살아가는 사람이 진정으로 누구인지 알지 못합니다.
-우리가 그들과 진정으로 함께 소통하기 전까지는 우리는 그들의 가치를 잘 모릅니다.
-우리의 위대함이란 다른 사람들의 위대한 점을 발견해 주는 것에 있습니다.
-p.280

]]>
- Book -
- - <![CDATA[InnoDB 스토리지 엔진의 잠금]]> - https://greeng00se.github.io/innodb-lock - https://greeng00se.github.io/innodb-lock - Fri, 07 Apr 2023 00:00:00 GMT - - InnoDB 스토리지 엔진의 잠금

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
-보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
-InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

낙관적 동시성 제어(OCC, Optimistic concurrency control)

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

비관적 동시성 제어(PCC, Pessimistic Concurrency Control)

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
-일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

Shared & Exclusive Locks

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

공유 잠금(S, shared lock)

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
-다른 트랜잭션에서 읽기가 가능하지만, 쓰기는 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

배타적 잠금(X, exclusive lock)

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
-락을 건 트랜잭션만이 해당 데이터에 접근 가능하다. 다른 트랜잭션의 경우 읽기, 쓰기가 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

Intention Locks

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
-테이블에 있는 로우에 대해서 나중에 요청되는 것이 어떤 형태의 잠금인지 가리키기 위해 사용된다.
-기본적으로 로우 단위 잠금을 수행하기 전에 인텐션 잠금을 먼저 획득한다.
-인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

인텐션 공유 잠금(IS, intention shared lock)

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

인텐션 배타적 잠금(IX, intention exclusive lock)

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

잠금간의 호환성

XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

Record Locks

레코드 자체만을 잠그는 락이다.
-InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

Gap Locks

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

Next-Key Locks

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
-REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

AUTO-INC Locks

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
-InnoDB 는 내부적으로 AUTO-INC 락이라고 하는 테이블 수준의 잠금을 사용한다.
-트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

잠금 예시

-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
-- Record Locks: 10에 대해 락이 걸린다.
SELECT * FROM table_name where id = 10 for update;

-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
SELECT * FROM table_name where id > 100 for update;

-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Optimistic and Pessimistic record locking, IBM
-MySQL Innodb Locks, cecil1018
-MySQL 8.0 InnoDB Locks, MySQL
-Locks Set by Different SQL Statements in InnoDB, MySQL

]]>
- DataBase - Lock - InnoDB -
- - <![CDATA[MySQL 엔진의 잠금]]> - https://greeng00se.github.io/mysql-lock - https://greeng00se.github.io/mysql-lock - Thu, 06 Apr 2023 00:00:00 GMT - - MySQL 엔진의 잠금

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
-MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

글로벌 락(Global lock)

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

  • 영향을 미치는 범위는 해당 서버 전체이다.
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
-데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 일관된 백업을 받아야할 때 사용한다.
-InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

-- GLOBAL LOCK
FLUSH TABLES WITH READ LOCK;
-- UNLOCK
UNLOCK TABLES;

-- BACKUP LOCK
LOCK INSTANCE FOR BACKUP;
-- UNLOCK
UNLOCK INSTANCE;
MyISAM

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
-트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

테이블 락(Table lock)

개별 테이블 단위로 설정되는 잠금이다.
-명시적 또는 묵시적으로 특정 테이블의 락을 획득할 수 있다.
-묵시적 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.
-InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

-- TABLE LOCK
LOCK TABLES table_name [ READ | WRITE ]

-- UNLOCK
UNLOCK TABLES;

네임드 락(Named lock)

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
-여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
SELECT GET_LOCK('aGVyYg==', 1);

-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
SELECT IS_FREE_LOCK('aGVyYg==');

-- 문자열에 대한 잠금을 해제한다.
SELECT RELEASE_LOCK('aGVyYg==');

-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.

-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
SELECT RELEASE_ALL_LOCKS();

메타데이터 락(Metadata lock)

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
-명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
-보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
RENAME TABLE rank TO rank_backup, rank_new TO rank;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-MySQL의 User Level Lock를 활용한다면?, gywndi
-Locking Functions, MySQL 5.7 Reference
-Locking Functions, MySQL 8.0 Reference

]]>
- DataBase - Lock - MySQL -
- - <![CDATA[트랜잭션과 격리수준]]> - https://greeng00se.github.io/transaction-and-isolation - https://greeng00se.github.io/transaction-and-isolation - Wed, 05 Apr 2023 00:00:00 GMT - - 트랜잭션(Transaction)

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
-트랜잭션은 작업의 완전성과 데이터의 정합성을 보장해 준다.
-논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

트랜잭션의 속성(ACID)

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
-일관성(Consistency): 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지해야 한다.
-격리성(Isolation): 각각의 트랜잭션은 독립적이라 서로에게 영향을 주지 않아야 한다.
-지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

트랜잭션 주의사항

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
-구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

왜 네트워크 작업이 있을 때 트랜잭션에서 배제해야 할까? 🤔

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
-네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)

격리 수준(Isolation level)

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
-격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

READ UNCOMMITTED

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
-더티 리드 현상이 발생하기 때문에 정합성의 문제가 많은 격리 수준이다.
-MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

READ COMMITTED

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
-오라클 DBMS에서 기본으로 사용되는 격리 수준이다.
-REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

REPEATABLE READ

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
-MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준이다.
-MVCC를 이용해 언두(Undo) 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
-동일한 결과를 보장하는 방법은 다음과 같다.

  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

갭 랍(Gap lock)과 넥스트 키 락(Next-key lock)

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

MVCC(Multi Version Concurrency Control)

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

SERIALIZABLE

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
-트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 접근할 수 없고 단순한 읽기 작업도 공유 잠금(읽기 잠금)을 획득해야만 한다.
-InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

격리 수준에 따른 부정합 문제

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX

더티 리드(Dirty read)

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
-트랜잭션 격리 수준이 READ UNCOMMITTED일 때 발생한다.
-예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

반복 가능하지 않은 조회(Non-repeatable read)

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
-예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

팬텀 리드(Phantom read, Phantom row)

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
-예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Isolation Level, MySQL

]]>
- DataBase - Transaction - Isolation -
- - <![CDATA[테스트 대역]]> - https://greeng00se.github.io/test-double - https://greeng00se.github.io/test-double - Tue, 04 Apr 2023 00:00:00 GMT - - 테스트 대역이란?

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
-Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
-외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

테스트 대역의 타입 계층 구조

더미(Dummy)

가장 단순하고, 원시적인 유형의 테스트 대역이다.
-기본적으로 아무 일도 하지 않는 구현체로 인스턴스화가 필요한 경우 사용한다.
-만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

스텁(Stub)

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
-이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

스파이(Spy)

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
-예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

목, 모의 객체(Mock)

목은 더미, 스텁, 스파이를 포함한다.
-호출 시 사전에 정의된 결과를 반환하고, 예상치 못한 호출이 있을 경우 예외를 던질 수 있다.
-또한 호출에 대한 검증을 할 수 있다.

가짜(Fake)

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
-예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

DOC(depended-on component)

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
-테스트 더블은 DOC와 동일한 API를 제공해야 한다.

상호작용에 따른 목과 스텁 구분

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
-목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
SUT(system under test)

테스트 대상 시스템
-테스트를 하려는 대상

참고 자료

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
-단위 테스트 - 5장 목과 테스트 취약성, 블라디미르 코리코프
-테스트 주도 개발 시작하기 - 7장 대역, 최범균
-테스트 더블, Martin Fowler
-테스트 관련 용어 정리, Johngrib
-Test Double, Gerard Meszaros

]]>
- Test - Mock -
- - <![CDATA[자바 클래스 파일 구조]]> - https://greeng00se.github.io/java-class-file - https://greeng00se.github.io/java-class-file - Mon, 03 Apr 2023 00:00:00 GMT - - 클래스 파일

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
-컴파일된 클래스파일은 어떤 구조로 되어있을까?

클래스 파일의 데이터 형식

8비트 바이트의 스트림으로 구성된다.
-16비트 및 32비트의 데이터는 각각 2개, 4개의 연속된 8비트를 읽어서 구성된다.
-멀티바이트의 경우 항상 big endian 순서로 저장된다.

u1 → unsigned 1byte
-u2 → unsigned 2byte
-u4 → unsigned 4byte

클래스 파일 구조

ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

매직넘버

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
-보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

클래스 파일 포맷 버전

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

class file format major versions

Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61

상수 풀

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
-클래스명, 상수명, 상수 값, 필드명, 메서드명과 같은 값들이 존재한다.
-JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

액세스 플래그

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
-예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

Class access and property modifiers

Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.

this_class

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
-해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

super_class

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
-아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

interface, field, method

각각의 개수와, 정보에 대한 값이 들어있다.
-interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

attributes

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
-정해진 클래스 파일의 구조를 확장하는 역할을 한다.

클래스 파일 확인하면서 사용한 툴

IntelliJ plugin - BinEd
-IntelliJ plugin - jclasslib Bytecode Viewer

참고 자료

2장 JVM 이야기, 자바 최적화
-Class file in Java, File Format
-java se11 Class 파일 형식, Oracle
-java se17 Class 파일 형식, Oracle

]]>
- Java - Class -
- - <![CDATA[커스텀 JdbcTemplate 만들기]]> - https://greeng00se.github.io/custom-jdbc-template - https://greeng00se.github.io/custom-jdbc-template - Sun, 02 Apr 2023 00:00:00 GMT - - 체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
-이 때 JDBC를 사용할 때 데이터베이스의 커넥션을 얻고, try-with-resource를 사용하는 부분이 반복되었다.
-템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

기존 코드

public class User {
private final int id;
private final String name;

public User(final int id, final String name) {
this.id = id;
this.name = name;
}

public int getId() {
return id;
}

public String getName() {
return name;
}
}

SELECT, DELETE 중복 제거

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
-변하는 부분: SQL Query, 매개변수

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
executeUpdate(query, userId);
}

private void executeUpdate(final String query, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
preparedStatement.executeUpdate();
} catch (final SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
-이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

콜백(Callback)

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
-자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
-executeQuery로 조회한 값은 ResultSet 안에 들어가있다.
-이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

@FunctionalInterface
public interface RowMapper {
User mapRow(final ResultSet resultSet) throws SQLException;
}

조회 분리하기 - 2. 단건 조회

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
-아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

public User findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return queryForSingleResult(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
}, userId);
}

private User queryForSingleResult(
final String query,
final RowMapper rowMapper,
final Object... parameters
) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
if (resultSet.next()) {
return rowMapper.mapRow(resultSet);
}
return null;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

조회 분리하기 - 3. 다건 조회

단건 조회와 유사하다.

public List<User> findAll() {
final String query = "SELECT * FROM user";
return query(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
});
}

private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
final List<User> result = new ArrayList<>();
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
return result;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

제네릭 사용하기

위의 코드는 User를 조회할 때만 사용할 수 있다.
-아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

@FunctionalInterface
public interface RowMapper<T> {
T mapRow(final ResultSet resultSet) throws SQLException;
}

private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
-또한 null을 반환하기 보단 Optional로 감싸서 반환하도록 변경한다.
-최종적으로 아래와 같은 코드가 완성된다.

public class UserDao {
private final RowMapper<User> rowMapper = resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
};
private final JdbcTemplate jdbcTemplate;

public UserDao(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
jdbcTemplate.executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
jdbcTemplate.executeUpdate(query, userId);
}

public Optional<User> findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
}

public List<User> findAll() {
final String query = "SELECT * FROM user";
return jdbcTemplate.query(query, rowMapper);
}
}
]]>
- JDBC - Java -
- - <![CDATA[우아한테크코스 레벨 1 회고]]> - https://greeng00se.github.io/woowacourse-level1-retrospective - https://greeng00se.github.io/woowacourse-level1-retrospective - Sat, 01 Apr 2023 00:00:00 GMT - - 레벨 1이 끝났다.
-우테코를 시작하기 전 내가 정해두었던 목표 이상으로 달성했기 때문에 매우 만족스럽다.
-혼자 독학을 할 땐 이 방향으로 공부하는 게 맞는지 계속 반추하다 결국 무기력함에 빠져들었다.
-하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

Keep

나만의 루틴 만들기

스스로가 외부의 영향을 많이 받는다고 생각한다.
-최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
-소화능력이 부족하기 때문에 점심은 도시락(그래봤자 계란2개)을 준비하고
-항상 똑같은 컨디션을 유지하기 위해 항상 6시에 집에 간다.
-이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

크루들과 친하게 지내기

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
-하다 보니 더 많은 크루들의 닉네임을 외운 것 같다.
-앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

글쓰기

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
-매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
-사실 겉으로 드러내지 않았지만 꼭 받아보고 싶었다.
-글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

코드 리뷰 스터디

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
-과연 도움이 될까 생각했지만 결과적으로는 코드 리뷰를 하면서 성장을 많이 한 것 같다.
-투자한 시간 대비 가성비가 좋은 활동이었다.
-누누가 스터디장인데 과연 꾸준히 이어나가려나?

레벨 인터뷰

인터뷰할 때 많이 떨지 않아서 좋았다.
-남들 앞에서 이야기를 하거나, 면접을 보면 항상 엄청 떨어서 걱정했는데
-기술적인 질문을 받았을 때 떨지 않고 잘 대답할 수 있었다.
-우아한테크코스 생활을 하면서 다른 크루가 질문했을 때, 최대한 이해하기 쉽게 설명하려고 했던 경험이 도움이 된 것 같다.
-이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • 두괄식 표현
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • 설명할 수 있을만큼 시간 충분히 가지기
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • 끝맺는 부분 연습하기(자신감 있게)
  • 기술적인 집착가지기
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기

Problem

페어프로그래밍

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
-페어는 매번 바뀌고, 미션의 복잡도도 증가하기 때문인 것 같다.
-소통 능력, 시간관리가 부족했고, 만족스럽지 않았다.
-하지만 페어를 진행하고, 회고를 하다 보니 나만의 노하우가 쌓이는 느낌이다.
-레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

집중하는 시간⏱️ 부족

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
-이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

Try

허브🌿와의 티타임?

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
-예를 들어 잡담방에 저와 커피챗 하실 분 :) 하면서 올릴 수 있을 것 같다.
-참여하는 사람이 있을지, 안 좋게 보는 게 아닐지 걱정되지만 그래도 재밌을 것 같다.
-저랑 허브티 한잔 하실래요?

기술적인 부분

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
-시간의 여유가 될 때 책을 조금씩 읽어야겠다.
-블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

레벨 1을 마무리하며

시간이 빠르게 흘러갔다.
-타인에게 좋은 영향을 주기위해, 방학동안 나를 챙기는 시간을 가져야겠다.
-또한 함께 일하고 싶은 사람을 목표로 앞으로도 꾸준히 의식적 노력을 해야겠다.

]]>
- Woowahan Techcourse - Retrospective -
- - <![CDATA[체스 미션 회고]]> - https://greeng00se.github.io/chess-retrospective - https://greeng00se.github.io/chess-retrospective - Fri, 31 Mar 2023 00:00:00 GMT - -
PR 링크

체스

체스 미션에는 가비와 페어가 매칭되었다!
-체스는 이전 미션들보다 훨씬 복잡한 도메인이었다.
-하지만 가비와 나는 체스 도메인이 익숙해서 더 편한 마음으로 시작할 수 있었다.
-미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
-최종적으로 결정한 부분은 다음과 같다.

각 기물의 이동 가능여부
-Rank와 File은 각각 위치값을 가지고 있고, 값의 차이를 이용해서 각 기물의 이동 가능 여부를 계산했다.
-직선 → Rank와 File 차이 중 하나가 0이어야 한다.
-대각선 → Rank와 File 차이의 절대값이 같아야 한다. ex) abs(-2) == abs(2)
-나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

도착 칸의 기물 여부
-아군 → 이동이 불가능하다.
-적군 → 이동이 가능하다. 적군을 잡는다.

중간에 기물 존재 여부
-이동 경로에 기물이 존재하면 안된다.

데이터베이스 사용
-체스 미션은 특별하게 데이터베이스와 연결하는 부분이 있었다.
-체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

  • 기물 전체를 저장하는 방법
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
-기물 전체를 저장하지 않은 이유는 다음과 같다.

  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
-보드저장: 초기상태에서 32개의 Insert 쿼리(기물의 위치) + 기물 이동 시 움직임 변경(잡히는 경우 2개의 쿼리)
-기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

추가로 기보저장이 구현도 더욱 간단하다. 👍

부가적인 부분

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

  • 누누의 도움으로 ConnectionPool 구현
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

부족했던 부분

꼼꼼하게 코드를 작성하지 못한 부분
-DB 관련 부분을 꼼꼼하게 코딩을 하지 못했다.
-도메인 로직에만 집중하다보니 정적 중요한 DB의 코드의 예외처리, 빈 값을 반환 하는 부분을 꼼꼼하게 처리하지 못했다.
-하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

시간에 대한 부담감
-초반에는 여유롭지만 제출 마감에 가까워질 수록 사람이 급해지는 것 같다.
-다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

새로 학습한 부분

DAO 중복 제거

프롤로그에 을 작성했다.
-DAO를 작성하는데 try-catch-resources와 여러 코드가 중복되서 제거하고싶었다.
-템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

페어에게 배울 부분

페어 생각하기
-가비는 누구보다 페어를 생각하고, 배려해주는 페어였다.
-중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

미션 몰입하기
-최근에 미션에 잘 몰입하지 못했다.
-가비는 페어를 진행할 때 미션에 대한 몰입도가 매우 좋았다.
-집에가서도 체스 이동에 대한 로직을 어떻게 구현할 지 생각한 뒤 꼼꼼해서 정리해서 나에게 보내주었다.
-덕분에 나도 가비의 생각을 알 수 있어서 미션을 진행하는데 가속도가 붙은 것 같다.
-또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

솔직함
-먼저 회고하자고 말 걸어줘서 정말 고마웠다고 표현해주는 부분
-모르는게 있으면 솔직하게 말해주는 부분
-나의 의견을 정리하지 못한 상태로 전달할 때 이해가 안되었다고 정확히 전달해주는 부분
-솔직함은 페어할 때 중요한 부분인 것 같다.

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

]]> - Woowahan Techcourse - Retrospective - - - <![CDATA[일반적인 책임 할당을 위한 패턴]]> - https://greeng00se.github.io/grasp - https://greeng00se.github.io/grasp - Thu, 30 Mar 2023 00:00:00 GMT - - GRASP(General Responsibility Assignment Software Pattern)

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

각 패턴마다 Solution과 Problem로 구성되어 있다.

정보 전문가 패턴(Information Expert)

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

필요한 정보를 가진 객체들로 책임이 분산된다.

창조자 패턴(Creator)

Q: 누가 객체 A를 생성하는가?

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A 객체를 긴밀하게 사용한다.
  • B가 A 객체의 초기값을 가지고 있다.

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

낮은 결합도 패턴(Low Coupling)

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

결합도(Coupling) -객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

  • 오브젝트 p.17

결합도를 낮춘다면 다음과 같은 이점이 있다.

  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • 재사용이 편리해진다.
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)

높은 응집도 패턴(High Cohesion)

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

응집도(Cohesion) -연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

  • 오브젝트 p.26

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • 유지보수가 쉬워진다.
  • 낮은 결합도 또한 지원한다.
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.

컨트롤러 패턴(Controller)

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

어떤 서브시스템이 존재한다고 가정할 때

  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.

다형성 패턴(Polymorphism)

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

변경 보호 패턴(Protected Variations)

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

간접 참조 패턴(Indirection)

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

순수한 가공물 패턴(Pure Fabrication)

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.

참고 자료

오브젝트 5장. 책임 할당하기, 조영호

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

GRASP, 한빛 네트워크

]]>
- GRASP - OOP -
- - <![CDATA[블랙잭 미션 회고]]> - https://greeng00se.github.io/blackjack-retrospective - https://greeng00se.github.io/blackjack-retrospective - Tue, 14 Mar 2023 00:00:00 GMT - -
PR 링크

블랙잭

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
-이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
-후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
-"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
-중간 중간 회고를 하고, 나의 소프트스킬을 높히는게 답일까?
-부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
-터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

부족했던 부분

페어 신경쓰기
-이번 페어할 때 적극적으로 의견을 내보도록 했다. 그렇기에 너무 의견을 강하게 밀어붙인 느낌이 들어서 미안했다.
-후추가 압박을 느꼈을 수도 있을 것 같다는 생각이 든다.
-중간 중간 작은 회고를 진행해보는 것이 좋을까?

체력 관리
-요즘 잘 못먹는 것 같다.
-앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

중간 중간 돌아보기
-이번 미션과 관련된 내용은 아니지만 우테코를 잘 활용 하고 있는지 생각을 해봐야겠다.
-내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

새로 학습한 부분

상태 패턴
-객체의 내부 상태에 따라 스스로 행동을 변경하도록 하는 패턴으로 if/else/switch와 같은 조건문을 효과적으로 제거할 수 있다.
-블랙잭 미션을 진행하면서 상태 패턴에 대한 부분을 처음 적용해보았다.
-처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

일관성, 가독성, 추상화
-이번 리뷰어는 검프🍫 였다!
-검프의 리뷰는 간결함에 관련된 내용이 많았다.
-일관성이 있는 코드, 가독성이 좋은 코드, 추상화가 잘 되어있는 코드
-읽기 좋고, 간결한 방향으로 코드를 작성하는 방법을 배운 것 같다.
-코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

페어에게 배울 부분

생각 정리
-중간 중간 현재 상황에 대해 그림을 그리거나, 글을 적으면서 정리한다.
-페어와 동일한 부분을 이해하고 있는지 확인한다.
-진행하는데 매우 도움이 되었던 것 같다.
-나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

가감없이 의견을 말해주는 부분
-진행 상황에 대한 부분, 진행 속도, 지금 자신이 이해하고 있는 부분을 말해줘서 편했다.
-회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

도메인 언어에 신경쓰는 부분
-클래스명, 변수명과 같은 언어를 세심하게 신경쓴다.
-요구사항 정리도 깔끔하게 잘하는 것 같다.

후추 최고 👍

]]> - Woowahan Techcourse - Retrospective - - - <![CDATA[사다리 타기 미션 회고]]> - https://greeng00se.github.io/ladder-retrospective - https://greeng00se.github.io/ladder-retrospective - Sun, 26 Feb 2023 00:00:00 GMT - -
PR 링크

사다리 타기

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
-이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

2단계에서는 2가지 방법으로 구현해봤다.

  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법

Position 기준으로 사다리 게임을 진행하는 방법

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
-구현하고 나니 다른 클래스들이 Position에 대한 의존도가 너무 높은 것 같았다.
-또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

public LadderGameResult play() {
final Map<Player, Item> result = new LinkedHashMap<>();
// 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
for (Position position : Position.range(players.count())) {
final Position resultPosition = ladder.play(position);
result.put(players.get(position), items.get(resultPosition));
}
return new LadderGameResult(result);
}

Player에게 Ladder를 전달하여 게임을 진행하는 방법

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
-이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

public LadderGameResult play() {
// 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
final Map<Player, Position> playResult = players.play(ladder);

final Map<Player, Item> result = new LinkedHashMap<>();
for (Player player : playResult.keySet()) {
result.put(player, toItem(playResult.get(player)));
}
return new LadderGameResult(result);
}

부족했던 부분

유비쿼터스 언어에 시간을 들이기
-유비쿼터스 언어를 정하는데 시간을 조금 더 들여야겠다고 생각했다.
-사다리 타기의 실행 결과를 Item으로 짓다니.. 뭔가 만족스럽지 않다.
-이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

페어와 조금 더 친해지기
-첫날은 페어와 친해지는 시간을 조금 더 가져야겠다고 생각했다.
-우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

README를 조금 더 꼼꼼하게
-이상하게 코딩에 집중하면 README를 업데이트하면서 같이 커밋 하는 걸 항상 까먹는다.
-다음 미션에는 조금 더 신경 써야겠다.

좋은 질문을 생각하기
-첫 PR때 리뷰어에게 질문을 남기지 못했다.
-리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

PR 후에도 꼼꼼하게 확인하기
-분명 알고 있는 부분이지만, 놓친 부분이 많은 것 같았다.
-PR 하기 전에도 계속 확인을 했지만, 아무래도 IntelliJ에서 보니 코드에 익숙해져서 그런지 변경해야 할 부분이 잘 안보였다.
-github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

적극적으로 나의 의견을 말하기
-의견을 적극적으로 내는 부분에 대해서 페어의 의견이 괜찮다고 생각하면 수용 후 개선을 하는 방향으로 진행을 했었는데, 조금 더 개선할 수 있는 방향이 있다면 나도 적극적으로 의견을 말해야겠다고 생각이 든다.
-나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

새로 학습한 부분

객체의 생성 책임
-Players가 Position을 생성하고 Player의 생성자에 넣어주었다. 하지만 이 부분에 대해서 생성 책임에 관련된 코멘트가 달렸다. -시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A를 긴밀하게 사용한다.
  • B가 A의 초깃값을 가지고 있다.

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

패키지 분리 기준
-패키지 분리에 대한 나만의 기준이 아직 명확하지 않아 질문이 들어와도 명확하게 답변을 하지 못했다.
-마지막 제출 전에 도메인 패키지 내부를 분리해 봤는데, 기준이 명확하지 않았기 때문에 좋지 않은 선택이었던 것 같다. -현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
-Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(0~19)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
-이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0~19의 값이 보장되어 있다고 생각할 것이기 때문이다.
-따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

페어에게 배울 부분

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
-이번에 페어 할 때 컨디션 관리를 제대로 못해서 많이 미안했다. 다음에는 최상의 컨디션으로 페어를 준비해 봐야겠다.
-그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
-또한 페어 진행이 느린 것 같다고 말해줘서 안정적으로 시간 안에 미션을 완료할 수 있었다.
-페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
-웃는 것만으로도 사람이 밝아 보여서 너무 좋은 것 같다!

]]> - Woowahan Techcourse - Retrospective - - - <![CDATA[자동차 경주 미션 회고]]> - https://greeng00se.github.io/racing-car-retrospective - https://greeng00se.github.io/racing-car-retrospective - Tue, 14 Feb 2023 00:00:00 GMT - -
PR 링크

자동차 경주

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
-우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
-시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
-mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
-리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

부족했던 부분

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
-객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
-내가 좋아하는 주제, 관심가는 주제인 프로그래밍에 대한 이야기를 할 땐 말이 많아진다.
-다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

새로 학습한 부분

Assertions extracting

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
-이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

@Test
void extracting() {
final Cars cars = new Cars(List.of("car1", "car2"));

assertThat(cars.getCars())
.extracting(Car::getName)
.containsExactly("car1", "car2");
}

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

제어할 수 없는 부분에 대한 테스트

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
-이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

단순 위임을 하는 메서드에 대한 테스트

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
-호출 횟수를 검증하는 것보다 결과에 대한 테스트하는 것이 좋다.
-단순히 위임만 하는 테스트의 경우 결과를 검증한다면 테스트가 중복되지 않을까 생각했었다.
-따라서 중복된 테스트를 줄이기 위해 내부의 메서드를 호출하는지 검증하는 방법도 있다는 것을 알게 되었지만
-안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

테스트를 위한 getter 사용

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
-필요의 경우 생성해서 사용할 수 있지만, 기존에 있는 메서드들을 활용해보는 것이 더 좋은 방법이다.
-이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

페어에게 배울 부분

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
-생각을 정리한 후 자신의 의견을 명료하게 전달해주었다.
-그렇기 때문에 지식을 효율적으로 습득한다.
-난 생각을 잘 정리하지 않은 채로 내버려 둔 얕은 지식이 많은 것 같다. (이런 것도 아는 것이라고 할 수 있을까?)
-앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

개발에 열정을 가진 게 느껴진다.
-나도 개발을 좋아하지만, 최근에는 의지가 약해졌었다.
-열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
-칭찬은 고래도 춤추게 하던가?
-그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
-이건 바로 배울 수 없지만.
-나도 같이 일할 때 편한 사람, 같이 일하고 싶은 사람이 되기 위해 깊이 고민해봐야겠다.

]]> - Woowahan Techcourse - Retrospective - - - <![CDATA[Parameterized Tests]]> - https://greeng00se.github.io/parameterized-tests - https://greeng00se.github.io/parameterized-tests - Sun, 12 Feb 2023 00:00:00 GMT - - 테스트를 작성하다보면 매개변수에 따라 반복이 되는 테스트들이 생긴다.
-이 때 @ParameterizedTest를 사용하면 단일 테스트를 매개변수를 사용하여 여러 번 반복할 수 있다.

Argument Sources

@ParameterizedTest를 사용하려면 최소 하나 이상의 Source 애노테이션이 필요하다.
-JUnit이 제공하는 다양한 Source가 있기 때문에, 테스트에 맞춰 다양하게 사용할 수 있다.

Value Source

값을 이용하여 제공하는 형태로, 다음과 같은 타입의 값을 매개변수로 제공할 수 있다.

  • short, int, long, float, double
  • byte, char, boolean, String, Class
@ParameterizedTest
@ValueSource(ints = {1, 100, Integer.MAX_VALUE})
void valueTest(final int value) {
Assertions.assertThat(value).isPositive();
}

Null & Empty Source

null 값, 빈 값을 제공한다.
-Empty Source의 경우 다음과 같은 타입에 한해 매개변수로 제공할 수 있다.

  • String
  • java.util.List, java.util.Set, java.util.Map
  • primitive arrays — ex) int[]
  • object arrays — ex) String[]
@ParameterizedTest
@NullAndEmptySource
void nullAndEmptyTest(final String value) {
Assertions.assertThat(value).isNullOrEmpty();
}

Enum Source

EnumSource를 이용하여 Enum 또한 매개변수로 제공할 수 있다.

enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

@ParameterizedTest
@EnumSource(Day.class)
void enumTest(final Day day) {
assertThat(day).isInstanceOf(Day.class);
}

다음과 같이 mode 값을 이용하여 특징 Enum을 제외하거나, 포함시킬 수 있다. (default: Mode.Include)

@ParameterizedTest
@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)
void enumTest(final Day day) {
// MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
assertThat(day).isInstanceOf(Day.class);
}

CSV Source

csv 형식의 값을 이용하여 매개변수를 제공한다.
-구분자의 기본값은 쉼표(,)로 구분자를 변경하고 싶을 땐 delimeter 값을 따로 전달하여 사용할 수 있다. -개인적으로 2개 정도의 값을 매개변수로 전달하는 경우 CsvSource를 사용한다.

@ParameterizedTest
@CsvSource({"1,1", "2,4", "3,9", "4,16"})
void csvTest(final int number, final int result) {
assertThat(number * number).isEqualTo(result);
}

Method Source

복잡한 타입의 값을 전달할 때 사용한다.
-메서드명을 입력하여 매개변수를 제공하는 메서드를 지정할 수 있다.
-메서드명을 따로 입력하지 않으면 테스트명과 동일한 static 메서드가 지정된다.

@ParameterizedTest
@MethodSource
void methodTest(final List<Integer> numbers, final int count) {
assertThat(numbers).hasSize(count);
}

private static Stream<Arguments> methodTest() {
return Stream.of(
Arguments.of(List.of(1), 1),
Arguments.of(List.of(1, 2), 2),
Arguments.of(List.of(1, 2, 3), 3)
);
}

ETC.

위에서 언급한 방법 이외에도 다양한 방법으로 매개변수를 제공할 수 있다.

  • CSV 파일을 이용한 CsvFileSource
  • ArgumentsProvider 구현한 클래스를 이용하는 ArgumentsSource

참고 자료

]]>
- Java -
- - <![CDATA[IntelliJ 설정]]> - https://greeng00se.github.io/intellij-settings - https://greeng00se.github.io/intellij-settings - Mon, 30 Jan 2023 00:00:00 GMT - - Import 자동 적용

Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly

auto-import

저장시 동작

Prefrences > Tools > Actions on Save

actions-on-save

Reformat Code: Code Reformmating

Optimize imports: 사용하지 않는 Import 제거

Rearrange: Code Style > Arrangement 설정 기반 코드 재정렬

메소드 추출, 변수 추출시 final 적용

Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier

final-modifier

]]>
- IntelliJ -
- - <![CDATA[Kotlin에서 null을 다루는 방법]]> - https://greeng00se.github.io/kotlin-null - https://greeng00se.github.io/kotlin-null - Mon, 16 Jan 2023 00:00:00 GMT - - nullable 타입

코틀린은 NullPointerException 예외를 최대한 발생시키지 않기 위해 타입 시스템이 설계되어 있다.
-이는 실행 시점이 아닌 컴파일 시 미리 오류가 발생할 가능성이 있는 부분을 미리 감지하여 NPE 발생의 가능성을 줄여준다.

코틀린의 경우 nullable 타입을 다음과 같이 표현한다.

val number: Int?

타입 뒤에 ?를 붙여 해당 값이 null이 될 수 있다는 것을 의미한다.
-만약 ?를 붙이지 않을 때 null을 받는 경우 컴파일 시 오류가 발생한다.

?. Safe Calls 연산자

자바에서 NPE를 발생시키지 않기 위해 null을 처리하는 가장 간단한 방법으로는 분기를 사용하는 방법이 있다.

코틀린은 안전한 호출 연산자인 ?. 연산자를 지원한다.
-따라서 참조 값이 null이 아닐 경우에만 메서드 호출을 할 수 있다.
-참조 값이 null인 경우 메서드 호출이 무시되고, null을 반환한다.

public String repeat(String word) {
if (word == null) {
return null;
}
return word.repeat(2);
}

?: 엘비스 연산자

참조하려는 값이 null일 경우 기본 값을 반환하고 싶을 때는 어떻게 해야 할까?
-코틀린은 null이 아닌 경우 기본 값을 지정할 때 사용할 수 있는 엘비스 연산자를 지원한다.

public String stringSafe(String word) {
if (word == null) {
return "";
}
return word;
}

코틀린에서는 throw도 식이기 때문에 엘비스 연산자를 이용하여 예외를 던질 수 있다.
-예를 들어 사용자 정보가 있는 저장소에 찾는 사용자가 없는 경우 아래와 같이 사용할 수 있다.

userRepository.findByName(name) ?: throw IllegalArgumentException()

!! 널 아님 단언 연산자

!! 연산자를 이용한다면 강제로 어떤 값이든 non-nullable 타입으로 변경할 수 있다.
-하지만 null인 값에 사용한다면 NPE가 발생하게 된다.
-일반적인 경우에는 !! 연산자를 사용하는 것은 위험하다.
-사용하기 쉽지만, 리스크가 크고 혹시나 해당 값이 추후에는 null이 될 수 있기 때문에 지양해야 된다고 생각한다.

val length: Int = word!!.length

as? 안전한 캐스팅

타입 변환을 할 때 지정한 타입으로 변경할 수 없다면 ClassCastException이 발생한다.
-코틀린에서는 as 뒤에 ?를 붙여 안전하게 타입 변환을 할 수 있다.
-따라서 미리 변환 가능한 타입인지 확인하지 않고, 안전하게 타입을 변환 할 수 있다.

타입 변환이 불가능 할 경우 예외를 발생시키지 않고 null을 반환한다.

val value: Int? = something as? Int

List에서의 null 처리

List에는 null이 아닌 값만 반환하는 filterNotNull 유틸리티 메서드를 제공한다.

val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")
val foods = foodsWithNull.filterNotNull()

참고 자료

]]>
- Kotlin -
- - <![CDATA[JSR-310]]> - https://greeng00se.github.io/jsr-310 - https://greeng00se.github.io/jsr-310 - Sun, 08 Jan 2023 00:00:00 GMT - - 이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
-ISO-8601을 기반으로 작성
-설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

ISO-8601

날짜와 시간에 관련된 데이터를 다루는 국제 표준

LocalDate, LocalTime, LocalDateTime

날짜와 시간을 표현하는 클래스

Instant

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
-기계의 관점에서 시간 표현

Duration, Period

간격을 표현하는 클래스

TemporalAdjusters

복잡한 날짜 조정이 필요할 때 사용
-필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}

DateTimeFormatter

날짜와 시간 포맷 클래스
-특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

ZoneId, ZoneOffset

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
-ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

Instant instant = Instant.now();
LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

참고 자료

]]>
- Java - Time -
- - <![CDATA[[책] 객체지향의 사실과 오해]]> - https://greeng00se.github.io/the-essence-of-object-orientation - https://greeng00se.github.io/the-essence-of-object-orientation - Sat, 07 Jan 2023 00:00:00 GMT - - 책 정보

객체지향의 사실과 오해
-조영호

읽고 나서

조영호님의 오브젝트를 읽고 나서 다시 한 번 읽어보았다.
-아직 이해가 안되는 부분이 많지만, 그래도 항상 새로움을 느낀다.
-더할 나위 없이 휼륭한 객체지향 책이고, 조금 더 공부하고 다시 읽어봐야될 것 같다.

커피 전문점, 지하철 노선도, 이상한 나라의 엘리스를 예시로 든 설명이 너무 좋았고
-좋은 내용을 담고 있지만 그렇다고 너무 무겁지 않아 가볍게 읽기도 좋은 것 같다.

책임의 자율성을 강조하는 이유 p.173

협력을 단순하게 만든다.

  • 의도를 명확하게 표현 → 협력의 복잡함 저하
  • 책임의 추상화

외부와 내부를 명확하게 분리한다.

  • 요청하는 객체가 몰라도 되는 부분이 캡슐화됨으로 인터페이스와 구현의 분리

책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

  • 변경의 파급효과를 객체 내부로 캡슐화 → 메시지를 보내는 객체와의 결합도 저하

협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

  • 유연한 설계 → 재사용성 증가

객체의 역할을 이해하기 쉬워진다.

  • 응집도를 높은 상태로 유지

밑줄 친 문장들

객체지향의 목표는 실세계를 모방하는 것이 아니다. -오히려 새로운 세계를 창조하는 것이다. -소프트웨어 개발자의 역할은 단순히 실세계를 소프트웨어 안으로 옮겨 담는 것이 아니라 고객과 사용자를 만족시킬 수 있는 신세계를 창조하는 것이다. -p.21

과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. -이에 반해 객체지향에서는 데이터와 프로세스를 객체라는 하나의 틀 안에 함께 묶어 놓음으로써 객체의 자율성을 보장한다. -자율적인 객체로 구성된 공동체는 유지 보수가 쉽고 재사용이 용이한 시스템을 구축할 수 있는 가능성을 제시한다. -p.33

객체지향의 본질

시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. -p.35

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. -객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다. -p.38

객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행위’다. -클래스는 타입을 구현하기 위해 프로그래밍 언어에서 제공하는 구현 메커니즘이라는 사실을 기억하라. -p.105

책임 주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. -이 과정을 흔히 What/Who 사이클이라고 한다. -’어떤 행위(What)’를 수행할 것인지 결정한 후 ‘누가(who)’ 그 행위를 수행할 것인지 결정해야 한다. -여기서 ‘어떤 행위’가 바로 메시지다. -p.158

]]>
- Book -
- - <![CDATA[2022년 회고]]> - https://greeng00se.github.io/2022-retrospective - https://greeng00se.github.io/2022-retrospective - Mon, 02 Jan 2023 00:00:00 GMT - - 적당한 전환점, 2022년을 돌아보며

전역

약 1년 6개월간의 공군 정보보호병 생활을 마치고 전역을 했다.
-조기 전역 때문에 2021년 12월에 나왔지만, 실제 전역 날짜는 2022년이니 회고에 적어도 상관없겠지.

조금 더 미래에 대한 생각을 해볼걸 그랬다.
-전역을 했지만 뭐 하나 제대로 할 줄 아는 것도 없으니 넓은 바닷속에 덩그러니 놓아진 기분이 괜히 들었었다.
-일찍 생각을 정리하여 방향을 잡지 못했기에 아쉬움이 많이 남았다.

자바

전역을 하고 진로를 고민하다 향로님의 자바 공화국 포스팅을 읽고 나서 자바 공부를 시작했다.
-유명한 인프런의 김영한님의 스프링 강의도 있고, 좋은 자바 개발 서적이 많아서 독학하기로 결정했다.
-하다 보니 자바와 스프링을 공부하면서 “왜 진작하지 않았지”라는 생각도 많이 들었다.
-양질의 자료도 많았기 때문에, 예전에 노드로 개발했을 때 풀지 못했던 답답함을 많이 해소했던 것 같다.

23년에는 조금 더 깊게 자바를 공부해볼 생각이다.
-언어를 하나 깊게 공부하는 건 많은 도움이 되는 것 같다.

스터디

김영한님의 강의를 거의 다 들었을 때쯤, 항상 강의에서 언급되는 토비의 스프링을 읽어보고 싶어졌고
-혼자 공부하기에는 동기부여도 부족했기 때문에 스터디를 시작했다.
-다른 사람에게 설명을 해야 했기 때문에 더욱 꼼꼼하게 공부를 할 수 있어서 좋았지만 나에게는 내용이 꽤나 어려워서 시간을 많이 소비했다.
-같이 스터디하시는 분과 7개월 동안 스터디를 꾸준히 이어나가 총 3권의 책을 읽을 수 있었다.

우아한 테크코스

군 복무 중일 때 지원했다 떨어진 우아한 테크코스를 다시 지원했다.
-이번 연도에 취업을 하는 게 목표였지만 내가 가지고 있는 특별한 무기가 없다는 걸 깨달았다.
-적지 않은 시간을 투자해 준비를 했고, 감사하게도 이번에는 최종 합격을 했다.

난 사람들과 소통하고, 협업하는 능력이 부족하다고 생각을 많이 했다.
-우아한 테크코스를 통해 그 빈 부분을 채우도록 노력해야겠다.

2023년에는

마음의 여유가 없었던 2022년이었던 것 같다.
-하고 싶은 건 많지만, 이번에는 여유를 가지고 할 수 있는 것에 최선을 다해야겠다.

]]>
- Retrospective -
- - <![CDATA[[책] 글, 우리도 잘 쓸 수 있습니다.]]> - https://greeng00se.github.io/book-writer - https://greeng00se.github.io/book-writer - Sun, 01 Jan 2023 00:00:00 GMT - - 책 정보

글, 우리도 잘 쓸 수 있습니다.
-박솔미

읽고 나서

저자의 경험과 함께 글쓰기에 대한 가벼운 조언이 담겨있어 가볍게 읽기 좋았다.
-글을 잘 작성해 보고 싶을 때 적용해 볼 수 있는 정보가 많아서 도움이 되었다.

우아한 테크코스의 프리코스를 진행할 때 후기를 작성하고 나면 항상 글이 딱딱하다는 느낌을 받았다.
-다른 지원자들의 읽기 편하고, 밝은 느낌을 주는 글을 보면 부러운 마음을 가지기도 했다.
-이 책을 읽었으니 2023년에는 조금 더 글을 잘 적어보려고 한다.

밑줄 친 문장들

문장이 심심하고 지루하다면 -내용을 일목요연하게 정리했고, 글의 의도도 삐뚤지 않고, 단어도 적절한 것으로 골랐는데… 그런데도 어딘가가 심심하고 지루하다면? 축축 처지고 따분하다면? 말꼬리를 모조리 ‘~다’로 통일한 건 아닌지 점검해 보세요.

말꼬리를 잘 갖고 놀아야 합니다. 문장의 마지막 글자를 매번 다르게 고쳐쓰는 것만으로도 글에 활기를 더할 수 있죠. 때론 문장을 다 마치지 않고, 단어로만 끝맺는 것도 방법. 문장과 문장 사이에 쉼표가 들어서며 글 전체에 활기가 돌게 돼요. 문장의 길이도 다채로워지는 덕분에 덤으로 얻게 되는 것도 있습니다. 바로, 글의 리듬.

이전 문장에서 끝난 글자로, 다음 문장을 끝맺지 않기. 한두 문단마다 단어 수준의 아주 짧은 문장 배치하기.

글의 진짜 이유, 글의 진짜 목적, 글의 진짜 대상을 찾으려고 애썼습니다. 지금처럼 틀을 떠올린다거나, 눈치를 본다거나, 정치적인 셈도 하지 않았어요.

제목은 짧게, 보기 쉽게, 읽기 쉽게, 발음이 비슷하게, 순서를 바꿔서

글을 마지막으로 다듬을 때, 노래에 가까워질 방법은 없을지 고민해봅니다. 감히 가 닿을 수 없는 목표이겠지만, 할 수 있는 최소한의 리듬이라도 붙여주고 싶어요.

여는 말과 마지막 말에 작정하고 마음을 담는 연습을 해봅시다. 글의 어느 구석이라도 뻔한 글자는 남기지 않겠노라 다짐하며 써보는 겁니다. 나만이 가진 유일한 메시지에 집중하면서요. 그럼 생각이 달라지고, 고르는 단어도 달라지고, 남긴 문장도 달라져요. 결국에는 글을 쓴 사람인 나 자신도 남달라질 겁니다.

맞춤법은 중요합니다. 하지만 맞춤법보다 더 중요한 건 거기에 담긴 마음입니다. 내 마음을 글에 담아 실어 보내기 전, 맞춤법을 점검하는 이유 역시 그겁니다. 오직 내 마음이 남에게 읽히는 동안 방해가 되지 않기를 바라기 때문이죠. 내가 쓴 글도, 남이 쓴 글도. 언제나 그 안에 담긴 마음이 먼저입니다.

글을 쓴다고 글이 완성되는 게 아니에요. 글과 닮은 모습으로 살 때, 글은 비로소 완성됩니다.

]]>
- Book -
\ No newline at end of file diff --git a/search.html b/search.html index c091ccc07..830c8b259 100644 --- a/search.html +++ b/search.html @@ -2,8 +2,8 @@ - -문서를 검색합니다. | GG + +문서를 검색합니다. | GG @@ -12,14 +12,11 @@ - - - + + + - - - + \ No newline at end of file diff --git a/shopping-cart-retrospective.html b/shopping-cart-retrospective.html index 0abbf7998..7f433858b 100644 --- a/shopping-cart-retrospective.html +++ b/shopping-cart-retrospective.html @@ -2,8 +2,8 @@ - -웹 장바구니 미션 회고 | GG + +웹 장바구니 미션 회고 | GG @@ -12,28 +12,47 @@ - - - + + + -
-

웹 장바구니 미션 회고

· 약 5분

웹 장바구니 미션

장바구니 미션은 블랙캣이랑 진행했다.
+

웹 장바구니 미션 회고

· 약 5분

1단계: https://github.com/woowacourse/jwp-shopping-cart/pull/244
+2단계: https://github.com/woowacourse/jwp-shopping-cart/pull/300

+

웹 장바구니 미션

+

장바구니 미션은 블랙캣이랑 진행했다.
요구사항이 엄청 복잡한 미션은 아니었고, 스프링을 사용하여 기본적인 CRUD를 구현하는 미션이었다.
2단계에서는 Basic 인증을 통해 자신의 장바구니에만 상품을 담고, 제거할 수 있도록 구현하는 요구사항이 추가되었다.
Interceptor나 Argument Resolver에 대한 이해도가 높지 않았는데, 이번 미션을 통해 조금 더 알아간 느낌이다.
-이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

새로 학습한 부분

DTO 우발적 중복

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

dto1

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
-따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

dto2

Interceptor에서 인증한 값 재사용

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
-일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
+이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

+

새로 학습한 부분

+

DTO 우발적 중복

+

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

+

dto1

+

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
+로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

+
    +
  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • +
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.
  • +
+

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
+따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

+

dto2

+

Interceptor에서 인증한 값 재사용

+

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
+일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

+

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
웨지는 email에 index를 걸어두고 dao 재조회를 사용할 것이라고 했다.
-재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

페어에게 배울 부분

기록

블랙캣은 기록을 굉장히 잘 하는 크루였다.
+재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

+

페어에게 배울 부분

+

기록

+

블랙캣은 기록을 굉장히 잘 하는 크루였다.
노션에 페어를 진행하면서 했던 내용 + 고민했던 부분 + 회고를 꼼꼼하게 기록해서 공유해 주었다.
-추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

의견 일치시키기

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
+추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

+

의견 일치시키기

+

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
따라서 적당히 타협을 봐서 의견을 빠르게 수용해 데드라인을 맞추는 것도 중요하다고 생각한다.
-블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

- - +블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

+

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

\ No newline at end of file diff --git a/spring-test-isolation.html b/spring-test-isolation.html index 7597051e1..18bd8faa1 100644 --- a/spring-test-isolation.html +++ b/spring-test-isolation.html @@ -2,8 +2,8 @@ - -스프링 테스트 격리 | GG + +스프링 테스트 격리 | GG @@ -12,25 +12,92 @@ - - - + + + -
-

스프링 테스트 격리

· 약 5분

테스트 격리

테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 @DirtiesContext, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 @Transactional등 다양한 방법이 있다.
-해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.

Independent - FIRST

테스트끼리 서로 의존하면 안 된다.
+

스프링 테스트 격리

· 약 5분

테스트 격리

+

테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 @DirtiesContext, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 @Transactional등 다양한 방법이 있다.
+해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.

+

테스트끼리 서로 의존하면 안 된다.
서로 의존하게 된다면 하나의 테스트가 실패할 때, 또 다른 하나의 테스트가 실패할 수 있다.
-다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

TestExecutionListener

스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.
-이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.

TextExecutionListner
public interface TestExecutionListener {
default void beforeTestClass(TestContext testContext) throws Exception {}
default void prepareTestInstance(TestContext testContext) throws Exception {}
default void beforeTestMethod(TestContext testContext) throws Exception {}
default void beforeTestExecution(TestContext testContext) throws Exception {}
default void afterTestExecution(TestContext testContext) throws Exception {}
default void afterTestMethod(TestContext testContext) throws Exception {}
default void afterTestClass(TestContext testContext) throws Exception {}
}

AbstractTestExecutionListener 상속하여 구현

AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.
-다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.

DatabaseCleaner

public class DatabaseCleaner extends AbstractTestExecutionListener {

private static final String TRUNCATE_TABLE_QUERY = """
SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'PUBLIC'
""";

@Override
public void afterTestMethod(TestContext testContext) {
JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);
List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);
truncateTables(jdbcTemplate, truncateTableQueries);
}

private JdbcTemplate getJdbcTemplate(TestContext testContext) {
return testContext.getApplicationContext().getBean(JdbcTemplate.class);
}

private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {
return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);
}

private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");
truncateTableQueries.forEach(jdbcTemplate::execute);
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");
}
}

Listener 등록

@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.
+다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

+

TestExecutionListener

+

스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.
+이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.

+
public interface TestExecutionListener {
+    default void beforeTestClass(TestContext testContext) throws Exception {}
+    default void prepareTestInstance(TestContext testContext) throws Exception {}
+    default void beforeTestMethod(TestContext testContext) throws Exception {}
+    default void beforeTestExecution(TestContext testContext) throws Exception {}
+    default void afterTestExecution(TestContext testContext) throws Exception {}
+    default void afterTestMethod(TestContext testContext) throws Exception {}
+    default void afterTestClass(TestContext testContext) throws Exception {}
+}
+
+

AbstractTestExecutionListener 상속하여 구현

+

AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.
+다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.

+

+public class DatabaseCleaner extends AbstractTestExecutionListener {
+
+    private static final String TRUNCATE_TABLE_QUERY = """
+            SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') 
+            FROM INFORMATION_SCHEMA.TABLES
+            WHERE TABLE_SCHEMA = 'PUBLIC'
+            """;
+
+    @Override
+    public void afterTestMethod(TestContext testContext) {
+        JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);
+        List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);
+        truncateTables(jdbcTemplate, truncateTableQueries);
+    }
+
+    private JdbcTemplate getJdbcTemplate(TestContext testContext) {
+        return testContext.getApplicationContext().getBean(JdbcTemplate.class);
+    }
+
+    private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {
+        return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);
+    }
+
+    private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {
+        jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");
+        truncateTableQueries.forEach(jdbcTemplate::execute);
+        jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");
+    }
+}
+
+
+

Listener 등록

+

@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.
mergeMode의 기본값은 REPLACE_DEFAULTS로 리스너가 이미 존재하는 경우 등록된 리스너로 변경된다.
MERGE_WITH_DEFAULTS로 설정한다면 Ordered 기준으로 순서가 결정된다.
-이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.

AcceptanceTest

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestExecutionListeners(
value = DatabaseCleaner.class,
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
)
public abstract class AcceptanceTest {

@LocalServerPort
private int port;

@BeforeEach
public void setUp() {
RestAssured.port = port;
}
}

참고 자료

The Spring TestExecutionListener, Baeldung
-인수테스트에서 테스트 격리하기, 테코블
-Eradicating Non-Determinism in Tests, martin fowler
-@SpringBootTest의 테스트 격리시키기, MangKyu

- - +이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.

+

+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@TestExecutionListeners(
+        value = DatabaseCleaner.class,
+        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
+)
+public abstract class AcceptanceTest {
+
+    @LocalServerPort
+    private int port;
+
+    @BeforeEach
+    public void setUp() {
+        RestAssured.port = port;
+    }
+}
+
+
+

참고 자료

+

The Spring TestExecutionListener, Baeldung
+인수테스트에서 테스트 격리하기, 테코블
+Eradicating Non-Determinism in Tests, martin fowler
+@SpringBootTest의 테스트 격리시키기, MangKyu

\ No newline at end of file diff --git a/subway-retrospective.html b/subway-retrospective.html index 40907f7c1..9626657f2 100644 --- a/subway-retrospective.html +++ b/subway-retrospective.html @@ -2,8 +2,8 @@ - -지하철 미션 회고 | GG + +지하철 미션 회고 | GG @@ -12,35 +12,86 @@ - - - + + + -
-

지하철 미션 회고

· 약 8분

지하철 미션

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
+

지하철 미션 회고

· 약 8분

1단계: https://github.com/woowacourse/jwp-subway-path/pull/16
+2, 3단계: https://github.com/woowacourse/jwp-subway-path/pull/126

+

지하철 미션

+

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
지하철 미션은 밀리랑 페어를 진행했다.
간단한 CRUD만 있던 이전 미션들과 달리, 조금 복잡한 도메인 요구사항이 있었다.
이때 API, 테이블, 도메인 설계를 해야 했는데 어떤 것부터 해야 할지 고민을 많이 했다.
-API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

노선의 구간 추가 및 삭제

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. 변경된 요소만 데이터베이스에 반영하는 방법

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
-추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

부족했던 부분

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
+API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

+

노선의 구간 추가 및 삭제

+

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

+
    +
  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. +
  3. 변경된 요소만 데이터베이스에 반영하는 방법
  4. +
+

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
+추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

+

부족했던 부분

+

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
우아한테크코스를 진행하면서 알아야 하는 게 많아지면서 가끔 조바심을 가질 때가 있는 것 같은데, 조바심을 경계할 필요가 있을 것 같다.
-부족한 부분은 인정하고, 앞으로 나아가야겠다.

새로 학습한 부분

컴포지트 패턴으로 요금 정책 추상화

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
+부족한 부분은 인정하고, 앞으로 나아가야겠다.

+

새로 학습한 부분

+

컴포지트 패턴으로 요금 정책 추상화

+

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
요금을 더하는 부분과, 할인하는 부분이 있어서 이 둘을 분리할까 생각했지만, 이 정도 크기의 애플리케이션에서는 오히려 분리하지 않고 하나로 합치는 게 더 좋다고 생각했다.
-또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

도메인에 특정 기술의 의존성을 분리

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
-따라서 도메인 패키지 내에는 경로 검색에 대한 인터페이스를 두고, 세부 구현은 도메인 패키지 외부로 분리했다.
-최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

컴포지트 패턴

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

인수 테스트 작성

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
+또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

+

도메인에 특정 기술의 의존성을 분리

+

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
+따라서 도메인 패키지 내에는 경로 검색에 대한 인터페이스를 두고, 세부 구현은 도메인 패키지 외부로 분리했다.
+최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

+

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
+이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

+

인수 테스트 작성

+

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
브라운이 해주신 강의 + 유튜브에 있는 브라운의 강의를 보고 지하철 미션에 인수 테스트를 적용해 보았다.
메서드, 변수명을 전부 한글로 작성했는데 전체적인 흐름을 알기 편하고 읽기도 좋았다.
-그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

결과는 아래와 같다.

@Nested
public class 노선을_전체_조회할_때 {

@Test
void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
// given
노선_생성_요청("2호선", "초록", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);

노선_생성_요청("9호선", "고동", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);

// when
final var 조회_결과 = 노선_전체_조회_요청();

// then
요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
노선_전체_조회_결과를_확인한다(
조회_결과,
노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
);
}
}

페어에게 배울 부분

의견 조율하기

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
-의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

꼼꼼하게 코딩하기

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
+그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

+

결과는 아래와 같다.

+
@Nested
+public class 노선을_전체_조회할_때 {
+
+    @Test
+    void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
+        // given
+        노선_생성_요청("2호선", "초록", 0);
+        노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
+        구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);
+
+        노선_생성_요청("9호선", "고동", 0);
+        노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
+        구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);
+
+        // when
+        final var 조회_결과 = 노선_전체_조회_요청();
+
+        // then
+        요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
+        노선_전체_조회_결과를_확인한다(
+                조회_결과,
+                노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
+                노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
+        );
+    }
+}
+
+

페어에게 배울 부분

+

의견 조율하기

+

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
+의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

+

꼼꼼하게 코딩하기

+

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
변수명, 메서드명을 중요하게 생각했고, 좋은 변수명을 잘 짓는 것 같다.
-또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

편한 분위기

전체적으로 페어 할 때 편하게 진행했던 것 같다.
+또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

+

편한 분위기

+

전체적으로 페어 할 때 편하게 진행했던 것 같다.
일정도 그렇고, 페어 진행할 때도 그렇고 큰 문제가 없었던 것 같아서 좋았다.
-나는 과연 다른 사람들에게 편한 사람일까?

- - +나는 과연 다른 사람들에게 편한 사람일까?

\ No newline at end of file diff --git a/tags.html b/tags.html index 9d9b21837..bd4ec0932 100644 --- a/tags.html +++ b/tags.html @@ -2,8 +2,8 @@ - -태그 | GG + +태그 | GG @@ -12,14 +12,11 @@ - - - + + + - - - + \ No newline at end of file diff --git a/tags/async.html b/tags/async.html index 15ef1bdcb..337934873 100644 --- a/tags/async.html +++ b/tags/async.html @@ -2,8 +2,8 @@ - -"async" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG + +"async" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG @@ -12,22 +12,94 @@ - - - + + + -
-

"async" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

문제 상황

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
-확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

비동기 예외 발생시 로깅 설정

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
+

"async" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

문제 상황

+

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
+확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

+

비동기 예외 발생시 로깅 설정

+

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

+

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
기존의 동기 예외 처리의 경우 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다.
-비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

AsyncExceptionHandler
@Slf4j
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

private static final String LOG_FORMAT = "[%s] %s";

@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
}
}

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
-getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

MDC 정보 연동 문제

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

./mdc-null.png

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

MdcTaskDecorator
public class MdcTaskDecorator implements TaskDecorator {

@Override
public Runnable decorate(final Runnable runnable) {
Map<String, String> threadContext = MDC.getCopyOfContextMap();
return () -> {
MDC.setContextMap(threadContext);
runnable.run();
};
}
}

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

AsyncConfig
@RequiredArgsConstructor
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

private final AsyncConfigurationProperties properties;

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(properties.coreSize());
executor.setMaxPoolSize(properties.maxSize());
executor.setQueueCapacity(properties.queueCapacity());

executor.setTaskDecorator(new MdcTaskDecorator());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

./mdc-not-null.png

참고 자료

spring async, baeldung
-@Async will not call by @ControllerAdvice for global exception
-Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
-TaskDecorator, Spring docs
-AsyncUncaughtExceptionHandler

- - +비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

+
@Slf4j
+public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
+
+    private static final String LOG_FORMAT = "[%s] %s";
+
+    @Override
+    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
+        log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
+    }
+}
+
+

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
+getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

+

MDC 정보 연동 문제

+

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

+

./mdc-null.png

+

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

+
public class MdcTaskDecorator implements TaskDecorator {
+
+    @Override
+    public Runnable decorate(final Runnable runnable) {
+        Map<String, String> threadContext = MDC.getCopyOfContextMap();
+        return () -> {
+            MDC.setContextMap(threadContext);
+            runnable.run();
+        };
+    }
+}
+
+

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

+
@RequiredArgsConstructor
+@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    private final AsyncConfigurationProperties properties;
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(properties.coreSize());
+        executor.setMaxPoolSize(properties.maxSize());
+        executor.setQueueCapacity(properties.queueCapacity());
+        
+        // highlight-next-line
+        executor.setTaskDecorator(new MdcTaskDecorator());
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.initialize();
+        return executor;
+    }
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

+

./mdc-not-null.png

+

참고 자료

+

spring async, baeldung
+@Async will not call by @ControllerAdvice for global exception
+Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
+TaskDecorator, Spring docs
+AsyncUncaughtExceptionHandler

\ No newline at end of file diff --git a/tags/async/page/2.html b/tags/async/page/2.html index 87643345a..d4f505235 100644 --- a/tags/async/page/2.html +++ b/tags/async/page/2.html @@ -2,8 +2,8 @@ - -"async" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG + +"async" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG @@ -12,40 +12,217 @@ - - - + + + -
-

"async" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 12분

이전 글

경로 이미지 생성하기 - 기술 선택
-경로 이미지 생성하기 - 구현

개요

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
+

"async" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 12분

이전 글

+

경로 이미지 생성하기 - 기술 선택
+경로 이미지 생성하기 - 구현

+

개요

+

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
경로 이미지 생성의 경우 위치 정보의 개수에 정비례하여 생성 시간이 증가한다.
-따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

주기능의 응답속도 개선

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
+따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

+

주기능의 응답속도 개선

+

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
하지만 현재 여행 종료와 감상 생성의 응답 속도가 경로 이미지 생성 시간에 영향을 받고 있다.
-경로 이미지 생성은 비동기 처리하여도 애플리케이션 사용에 문제가 되지 않는다.
-소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

확장성 대비

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
+경로 이미지 생성은 비동기 처리하여도 애플리케이션 사용에 문제가 되지 않는다.
+소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

+

확장성 대비

+

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
조금 더 짧은 간격으로 위치 정보를 그리는 경우 하나의 여행에 많은 위치 정보가 저장될 수밖에 없고 따라서 경로 이미지 생성에 걸리는 시간이 더 길어질 수 있다.
-따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

비동기 처리

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

비동기 설정

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
-해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig {
}

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. -7.7. Task Execution and Scheduling, Spring Boot Docs

@Async 적용

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

RouteImageGenerator
@Async
public void generate(
List<Double> latitudes,
List<Double> longitudes,
List<Double> pointedLatitudes,
List<Double> pointedLongitudes,
Long tripId
) {
// 이미지 생성
RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
Coordinates coordinates = Coordinates.of(latitudes, longitudes);
Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
drawImage(coordinates, routeImageDrawer, pointedCoordinates);

// 이미지 저장
String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());

// 자원 할당 해제
routeImageDrawer.dispose();

// 데이터베이스 값 변경
Trip trip = tripRepository.findById(tripId)
.orElseThrow();
trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}

비동기 처리시 문제점

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
-따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
-인터페이스를 사용한다면 다음과 같은 구조가 된다.

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
-따라서 이벤트를 사용하기로 했다.

이벤트 사용

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

이벤트 발행

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
+따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

+

비동기 처리

+

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

+

비동기 설정

+

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
+해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig {
+}
+
+

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

+
+

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. +7.7. Task Execution and Scheduling, Spring Boot Docs

+
+

@Async 적용

+

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

+
@Async
+public void generate(
+        List<Double> latitudes,
+        List<Double> longitudes,
+        List<Double> pointedLatitudes,
+        List<Double> pointedLongitudes,
+        Long tripId
+) {
+    // 이미지 생성
+    RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
+    Coordinates coordinates = Coordinates.of(latitudes, longitudes);
+    Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
+    drawImage(coordinates, routeImageDrawer, pointedCoordinates);
+
+    // 이미지 저장
+    String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());
+
+    // 자원 할당 해제
+    routeImageDrawer.dispose();
+
+    // 데이터베이스 값 변경
+    Trip trip = tripRepository.findById(tripId)
+        .orElseThrow();
+    trip.changeRouteImageUrl(imageUrl);
+    tripRepository.save(trip);
+}
+
+

비동기 처리시 문제점

+

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
+따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

+ +

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
+인터페이스를 사용한다면 다음과 같은 구조가 된다.

+ +

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
+따라서 이벤트를 사용하기로 했다.

+

이벤트 사용

+

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

+

이벤트 발행

+

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
스프링에서는 ApplicationEventPublisher 인터페이스를 사용하여 이벤트를 발행할 수 있다.
-해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

TripService & TripUpdateEvent
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
...

// 이벤트 발행
applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
}

public record TripUpdateEvent(Long tripId) {
}

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
+해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

+
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
+    ...
+
+    // 이벤트 발행
+    applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
+}
+
+public record TripUpdateEvent(Long tripId) {
+}
+
+

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
이벤트를 구독하는 도메인의 행위를 담고 있는 이벤트를 발행(ex. RouteImageGenerateEvent)한다면 논리적인 의존 관계가 남아있기에 이벤트를 적절히 사용했다고 보기 어렵다.
-발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

이벤트 구독

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
-이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

TransactionPhase 설정

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
+발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

+

이벤트 구독

+

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
+이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

+

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
AFTER_ROLLBACK: 트랜잭션이 롤백되는 경우 이벤트 실행
AFTER_COMPLETION: 트랜잭션이 커밋 또는 롤백 되었을 경우 이벤트 실행
-BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

TripUpdateEventHandler
@Component
public class TripUpdateEventHandler {

private final RouteImageGenerator routeImageGenerator;
private final TripRepository tripRepository;

public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
this.routeImageGenerator = routeImageGenerator;
this.tripRepository = tripRepository;
}

@Async
@TransactionalEventListener(phase = AFTER_COMMIT)
public void handle(TripUpdateEvent tripUpdateEvent) {
Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());

String imageUrl = routeImageGenerator.generate(
trip.getLatitudes(),
trip.getLongitudes(),
trip.getPointedLatitudes(),
trip.getPointedLongitudes()
);

trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}
}

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
-또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

테스트

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

@ContextConfiguration(classes = TestSyncConfig.class)
@SpringBootTest
public class TripUpdateEventHandlerIntegrationTest {

...

@Test
void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
// given
TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
.willReturn(여행());

// when
transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));

// then
then(routeImageGenerator)
.should(times(1))
.generate(any(), any(), any(), any());
}
}

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
-통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

결과

./time.png

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
-응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

참고 자료

7.7. Task Execution and Scheduling, Spring Boot Docs
-Spring Events, Baeldung
-회원시스템 이벤트기반 아키텍처 구축하기

- - +BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

+

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

+
@Component
+public class TripUpdateEventHandler {
+
+    private final RouteImageGenerator routeImageGenerator;
+    private final TripRepository tripRepository;
+
+    public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
+        this.routeImageGenerator = routeImageGenerator;
+        this.tripRepository = tripRepository;
+    }
+
+    @Async
+    @TransactionalEventListener(phase = AFTER_COMMIT)
+    public void handle(TripUpdateEvent tripUpdateEvent) {
+        Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());
+
+        String imageUrl = routeImageGenerator.generate(
+                trip.getLatitudes(),
+                trip.getLongitudes(),
+                trip.getPointedLatitudes(),
+                trip.getPointedLongitudes()
+        );
+
+        trip.changeRouteImageUrl(imageUrl);
+        tripRepository.save(trip);
+    }
+}
+
+

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
+또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

+ +

테스트

+

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

+ + +
@ContextConfiguration(classes = TestSyncConfig.class)
+@SpringBootTest
+public class TripUpdateEventHandlerIntegrationTest {
+
+    ...
+
+    @Test
+    void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
+        // given
+        TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
+        given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
+                .willReturn(여행());
+
+        // when
+        transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));
+
+        // then
+        then(routeImageGenerator)
+                .should(times(1))
+                .generate(any(), any(), any(), any());
+    }
+}
+
+

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
+통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

+

결과

+

./time.png

+

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
+응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

+

참고 자료

+

7.7. Task Execution and Scheduling, Spring Boot Docs
+Spring Events, Baeldung
+회원시스템 이벤트기반 아키텍처 구축하기

\ No newline at end of file diff --git a/tags/awt.html b/tags/awt.html index a5e860ec8..c60af67a9 100644 --- a/tags/awt.html +++ b/tags/awt.html @@ -2,8 +2,8 @@ - -"awt" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG + +"awt" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG @@ -12,24 +12,202 @@ - - - + + + -
-

"awt" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 12분

개요

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
-경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

구현 결과

./result.png

예시 데이터는 다음과 같다.
-서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

예시 데이터
List<Double> x = List.of(
126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
);
List<Double> y = List.of(
37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
);
List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);

IMAGE_SIZE & ROUTE_SIZE

RouteImageGenerator.java
private static final int IMAGE_SIZE = 800;
private static final int ROUTE_SIZE = 600;

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
+

"awt" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 12분

개요

+

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
+경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

+

구현 결과

+

./result.png

+

예시 데이터는 다음과 같다.
+서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

+
List<Double> x = List.of(
+        126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
+        126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
+);
+List<Double> y = List.of(
+        37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
+        37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
+);
+List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
+List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);
+
+

IMAGE_SIZE & ROUTE_SIZE

+
private static final int IMAGE_SIZE = 800;
+private static final int ROUTE_SIZE = 600;
+
+

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
IMAGE_SIZE는 말 그대로 이미지의 width와 height를 의미한다.
ROUTE_SIZE의 경우 상하좌우 100px 만큼의 간격을 위해 존재한다.
-따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

./600.png

사이즈 변경의 이유

255 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 800 사이즈로 변경했다.

주요 클래스

요약

클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성

의존관계

Coordinates(위도, 경도의 일급 컬렉션)

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
-Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는

Positions 계산 로직은 다음과 같다.
-위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

Coordinates.java
// 호출
// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);

private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
Double minValue = Collections.min(values);
return values.stream()
.map(value -> normalizeCoordinate(value, maxDifference, minValue))
.map(value -> mapToPosition(value, routeImageSize))
.toList();
}

private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
return (coordinate - minValue) / maxDifference;
}

private int mapToPosition(Double coordinate, Integer routeImageSize) {
return (int) (coordinate * routeImageSize);
}

위도로 예시든 내용이다.

  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  3. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.

Positions(실제 이미지 생성에 사용할 위치)

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • size: 크기를 반환한다.
  • xPositions: x 값들을 반환한다.
  • yPositions: y 값들을 반환한다.

중앙 정렬 로직은 다음과 같다.

Positions.java
public Positions align(int imageSize, int routeSize) {
int xOffset = calculateOffset(Position::x, imageSize);
int yOffset = calculateOffset(Position::y, imageSize);

return items.stream()
.map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
.collect(collectingAndThen(toList(), Positions::new));
}

private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
List<Integer> positions = items.stream()
.mapToInt(positionToInteger)
.boxed()
.toList();

int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
return imageSize / 2 - midValue;
}

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
-BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

./800.png

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

x 값 → 계산한 offset 그대로 더한다.
-y 값 → imageSize(800)에서 y + offset 값을 뺀다.

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
-그림을 그리기 위해 설정한 상수들이 존재한다.

RouteImageDrawer.java
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
// 이를 RGBA라고 부른다.
private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
// 배경 투명색
private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
// 경로를 위한 STROKE
private static final int LINE_STROKE_WIDTH = 7;
private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 위치 점을 위한 STROKE
private static final int POINT_STROKE_WIDTH = 20;
private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 안티앨리어싱 등 화질 개선을 위한 설정
private static final Map<Object, Object> renderingHints = Map.of(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
);

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

  • drawLine: 선을 그린다.
  • drawPoint: 점을 찍는다.
  • dispose: 자원 할당을 해제한다.

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

이미지 생성 Flow

1. 이미지 생성 준비

2. 선 그리기 요청

3. 위치 점 그리기 요청

4. 업로드 요청

전체 Flow

- - +따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

+

./600.png

+

사이즈 변경의 이유

+

255 * 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 * 800 사이즈로 변경했다.

+

주요 클래스

+

요약

+
클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성
+

의존관계

+ +

Coordinates(위도, 경도의 일급 컬렉션)

+

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
+Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

+
    +
  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • +
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는
  • +
+

Positions 계산 로직은 다음과 같다.
+위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

+
// 호출
+// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
+// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);
+
+private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
+    Double minValue = Collections.min(values);
+    return values.stream()
+            .map(value -> normalizeCoordinate(value, maxDifference, minValue))
+            .map(value -> mapToPosition(value, routeImageSize))
+            .toList();
+}
+
+private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
+    return (coordinate - minValue) / maxDifference;
+}
+
+private int mapToPosition(Double coordinate, Integer routeImageSize) {
+    return (int) (coordinate * routeImageSize);
+}
+
+

위도로 예시든 내용이다.

+
    +
  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. +
  3. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  4. +
  5. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.
  6. +
+

Positions(실제 이미지 생성에 사용할 위치)

+

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

+
    +
  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • +
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • +
  • size: 크기를 반환한다.
  • +
  • xPositions: x 값들을 반환한다.
  • +
  • yPositions: y 값들을 반환한다.
  • +
+

중앙 정렬 로직은 다음과 같다.

+
public Positions align(int imageSize, int routeSize) {
+    int xOffset = calculateOffset(Position::x, imageSize);
+    int yOffset = calculateOffset(Position::y, imageSize);
+
+    return items.stream()
+            .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
+            .collect(collectingAndThen(toList(), Positions::new));
+}
+
+private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
+    List<Integer> positions = items.stream()
+            .mapToInt(positionToInteger)
+            .boxed()
+            .toList();
+
+    int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
+    return imageSize / 2 - midValue;
+}
+
+

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
+BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

+

./800.png

+

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

+

x 값 → 계산한 offset 그대로 더한다.
+y 값 → imageSize(800)에서 y + offset 값을 뺀다.

+

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

+

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
+그림을 그리기 위해 설정한 상수들이 존재한다.

+
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
+// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
+// 이를 RGBA라고 부른다.
+private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
+// 배경 투명색
+private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
+// 경로를 위한 STROKE
+private static final int LINE_STROKE_WIDTH = 7;
+private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 위치 점을 위한 STROKE
+private static final int POINT_STROKE_WIDTH = 20;
+private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 안티앨리어싱 등 화질 개선을 위한 설정
+private static final Map<Object, Object> renderingHints = Map.of(
+        RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
+        RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
+        RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
+);
+
+

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

+
    +
  • drawLine: 선을 그린다.
  • +
  • drawPoint: 점을 찍는다.
  • +
  • dispose: 자원 할당을 해제한다.
  • +
+

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

+

이미지 생성 Flow

+

1. 이미지 생성 준비

+ +

2. 선 그리기 요청

+ +

3. 위치 점 그리기 요청

+ +

4. 업로드 요청

+ +

전체 Flow

+
\ No newline at end of file diff --git a/tags/awt/page/2.html b/tags/awt/page/2.html index be6c7ca68..da63520e4 100644 --- a/tags/awt/page/2.html +++ b/tags/awt/page/2.html @@ -2,8 +2,8 @@ - -"awt" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG + +"awt" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG @@ -12,20 +12,61 @@ - - - + + + -
-

"awt" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

./route.png

이미지 생성의 책임

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
-따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

고려한 기술

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

  • Python의 Matplotlib
  • AWT(Abstract Window Toolkit) [최종 선택]
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)

Python & Matplotlib

데이터 시각화 라이브러리
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

  • 코드가 간단해서 유지 보수성이 좋다.
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.

Java AWT 이외의 라이브러리

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음

Java & AWT(Abstract Window Toolkit)

그래픽과 이미지를 그리기 위한 도구
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • 추가적인 api 호출을 하지 않아도 된다.

기술 선택

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
-하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

유지 보수

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
-따라서 다음과 같은 방법으로 공유하기로 했다.

  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. AWT를 사용한 부분을 문서화하여 공유한다.

레벨 3를 마무리하며 내용 추가

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
-AWT를 사용하는 부분에서 애플리케이션 실행 시간을 제외하면 파이썬과 비슷한 시간안에 이미지를 생성할 수 있었다.

- - +

"awt" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

./route.png

+

이미지 생성의 책임

+

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
+따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

+

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

+
    +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
+

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

+

고려한 기술

+

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

+
    +
  • Python의 Matplotlib
  • +
  • AWT(Abstract Window Toolkit) [최종 선택]
  • +
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • +
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)
  • +
+

Python & Matplotlib

+

데이터 시각화 라이브러리
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

+
    +
  • 코드가 간단해서 유지 보수성이 좋다.
  • +
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • +
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.
  • +
+

Java AWT 이외의 라이브러리

+

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

+
라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음
+

Java & AWT(Abstract Window Toolkit)

+

그래픽과 이미지를 그리기 위한 도구
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

+
    +
  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • +
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • +
  • 추가적인 api 호출을 하지 않아도 된다.
  • +
+

기술 선택

+

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
+하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

+

유지 보수

+

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
+따라서 다음과 같은 방법으로 공유하기로 했다.

+
    +
  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. +
  3. AWT를 사용한 부분을 문서화하여 공유한다.
  4. +
+

레벨 3를 마무리하며 내용 추가

+

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
+AWT를 사용하는 부분에서 애플리케이션 실행 시간을 제외하면 파이썬과 비슷한 시간안에 이미지를 생성할 수 있었다.

\ No newline at end of file diff --git a/tags/book.html b/tags/book.html index 07f190d01..ff2cbb49a 100644 --- a/tags/book.html +++ b/tags/book.html @@ -2,8 +2,8 @@ - -"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,43 +12,79 @@ - - - + + + -
-

"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

책 정보

상자 밖에 있는 사람
-아빈저연구소

자기기만과 자기배반

책에서는 자기기만과 자기배반에 대한 내용을 다룬다.

  • 자기기만: 자신의 문제를 인정하지 않는 것
  • 자기배반: 다른 사람을 위해 무언가 해야만 한다는 생각을 반하는 행위

자기배반을 한다면 자기기만 상태가 된다.
-자기기만 상태에 빠지는 것을 책에서는 상자 안에 들어간다고 표현한다.

읽고 나서

최근에 읽은 책 중 가장 마음이 불편했다.
-그렇기에 더더욱 나에게 필요한 내용이 담겨있었다.

살면서 많은 선택의 순간이 존재했고, 그 순간마다 자기배반을 택하는 경우가 많았다.
+

"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

책 정보

+
+

상자 밖에 있는 사람
+아빈저연구소

+
+

자기기만과 자기배반

+

책에서는 자기기만과 자기배반에 대한 내용을 다룬다.

+
    +
  • 자기기만: 자신의 문제를 인정하지 않는 것
  • +
  • 자기배반: 다른 사람을 위해 무언가 해야만 한다는 생각을 반하는 행위
  • +
+

자기배반을 한다면 자기기만 상태가 된다.
+자기기만 상태에 빠지는 것을 책에서는 상자 안에 들어간다고 표현한다.

+

읽고 나서

+

최근에 읽은 책 중 가장 마음이 불편했다.
+그렇기에 더더욱 나에게 필요한 내용이 담겨있었다.

+

살면서 많은 선택의 순간이 존재했고, 그 순간마다 자기배반을 택하는 경우가 많았다.
작게는 집안일을 해야 하는데 몸이 조금 힘들다고 하지 않거나
크게는 잘못을 인정해야 하는 상황에서 그러지 않은 경우가 있었다.
-이런 상황이 반복되어 결국 상자 안에 나 자신을 가두는 경우가 많았다.

더 나은 삶을 위해 내가 상자 안에 있는지 지속적으로 확인하고, 상자 밖으로 나가려는 연습을 해야겠다.
-넓은 시선을 가지고, 항상 내가 틀릴 수 있다는 것을 생각하고 살아가자.

밑줄 친 문장들

우리의 생각은 지식보다 작다.
+이런 상황이 반복되어 결국 상자 안에 나 자신을 가두는 경우가 많았다.

+

더 나은 삶을 위해 내가 상자 안에 있는지 지속적으로 확인하고, 상자 밖으로 나가려는 연습을 해야겠다.
+넓은 시선을 가지고, 항상 내가 틀릴 수 있다는 것을 생각하고 살아가자.

+

밑줄 친 문장들

+
+

우리의 생각은 지식보다 작다.
우리의 지식은 사랑보다 작다.
우리의 사랑은 존재보다 작다.
그리고 우리가 생각하는 나는 실제의 나보다 그만큼 작다.
R. D. 랭
-p.19

우리가 외적으로 어떤 행동을 하든지 간에, 사람들은 우리 마음에서 그들을 어떻게 대하고 있는지에 따라 주로 반응합니다.
+p.19

+
+
+

우리가 외적으로 어떤 행동을 하든지 간에, 사람들은 우리 마음에서 그들을 어떻게 대하고 있는지에 따라 주로 반응합니다.
우리가 사람들에 대해 어떻게 느끼게 되는지는 우리가 상자 안에 있는지 혹은 상자 밖에 있는지에 따라 달라지게 됩니다.
-p.66

비난은 감정에 속하고 낙관은 의지에 속한다.
+p.66

+
+
+

비난은 감정에 속하고 낙관은 의지에 속한다.
인간은 감정보다 더 큰 존재이다.
알랭, 탁닛한
-p.103

우리가 자신에게만 집중하고 있는 한, 혼자서 일하는 것 이상의 창조적인 결과나 협력을 이끌어 낸다는 것은 불가능합니다.
+p.103

+
+
+

우리가 자신에게만 집중하고 있는 한, 혼자서 일하는 것 이상의 창조적인 결과나 협력을 이끌어 낸다는 것은 불가능합니다.
오늘날 경제 환경에서는 혼자서는 일의 결과를 탁월하게 만들어 내기가 어렵습니다.
내가 중심이어야 된다는 폐쇄적인 사고는 함께 일하는 사람들의 열정을 불러오지 못합니다.
-p.175

솔직함은 우리의 문제를 해결하는 열쇠입니다.
+p.175

+
+
+

솔직함은 우리의 문제를 해결하는 열쇠입니다.
그것은 자신의 행동과 관련된 사람에 대해 기꺼이 사과를 하는 것입니다.
그것만이 실타래처럼 엉킨 관계의 문제를 해결할 수 있기 때문이죠.
-p.188

누군가를 나와 같이 동일한 가치를 지닌 한 인간으로 생각해서 그 사람을 위해 내가 상자 밖에 계속 머무르고 싶은 열망이 생길 때, 나는 이미 그 사람에 대해 상자 밖에 있다.
-p.214

대부분의 사람들이 관계 기술을 가지고 그들이 겪고 있는 문제를 바로잡으려고 하는 노력이 결실을 얻지 못하는 것은 결코 그러한 기술 부족 때문에 생기는 것이 아닙니다.
+p.188

+
+
+

누군가를 나와 같이 동일한 가치를 지닌 한 인간으로 생각해서 그 사람을 위해 내가 상자 밖에 계속 머무르고 싶은 열망이 생길 때, 나는 이미 그 사람에 대해 상자 밖에 있다.
+p.214

+
+
+

대부분의 사람들이 관계 기술을 가지고 그들이 겪고 있는 문제를 바로잡으려고 하는 노력이 결실을 얻지 못하는 것은 결코 그러한 기술 부족 때문에 생기는 것이 아닙니다.
그것들은 자기배반 때문에 생겨납니다.
-p.224

우리는 함께 일하고 우리와 함께 살아가는 사람이 진정으로 누구인지 알지 못합니다.
+p.224

+
+
+

우리는 함께 일하고 우리와 함께 살아가는 사람이 진정으로 누구인지 알지 못합니다.
우리가 그들과 진정으로 함께 소통하기 전까지는 우리는 그들의 가치를 잘 모릅니다.
우리의 위대함이란 다른 사람들의 위대한 점을 발견해 주는 것에 있습니다.
-p.280

- - +p.280

+
\ No newline at end of file diff --git a/tags/book/page/2.html b/tags/book/page/2.html index 94354e163..1a4b47295 100644 --- a/tags/book/page/2.html +++ b/tags/book/page/2.html @@ -2,8 +2,8 @@ - -"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,81 @@ - - - + + + -
-

"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

책 정보

객체지향의 사실과 오해
-조영호

읽고 나서

조영호님의 오브젝트를 읽고 나서 다시 한 번 읽어보았다.
+

"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

책 정보

+
+

객체지향의 사실과 오해
+조영호

+
+

읽고 나서

+

조영호님의 오브젝트를 읽고 나서 다시 한 번 읽어보았다.
아직 이해가 안되는 부분이 많지만, 그래도 항상 새로움을 느낀다.
-더할 나위 없이 휼륭한 객체지향 책이고, 조금 더 공부하고 다시 읽어봐야될 것 같다.

커피 전문점, 지하철 노선도, 이상한 나라의 엘리스를 예시로 든 설명이 너무 좋았고
-좋은 내용을 담고 있지만 그렇다고 너무 무겁지 않아 가볍게 읽기도 좋은 것 같다.

책임의 자율성을 강조하는 이유 p.173

협력을 단순하게 만든다.

  • 의도를 명확하게 표현 → 협력의 복잡함 저하
  • 책임의 추상화

외부와 내부를 명확하게 분리한다.

  • 요청하는 객체가 몰라도 되는 부분이 캡슐화됨으로 인터페이스와 구현의 분리

책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

  • 변경의 파급효과를 객체 내부로 캡슐화 → 메시지를 보내는 객체와의 결합도 저하

협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

  • 유연한 설계 → 재사용성 증가

객체의 역할을 이해하기 쉬워진다.

  • 응집도를 높은 상태로 유지

밑줄 친 문장들

객체지향의 목표는 실세계를 모방하는 것이 아니다. +더할 나위 없이 휼륭한 객체지향 책이고, 조금 더 공부하고 다시 읽어봐야될 것 같다.

+

커피 전문점, 지하철 노선도, 이상한 나라의 엘리스를 예시로 든 설명이 너무 좋았고
+좋은 내용을 담고 있지만 그렇다고 너무 무겁지 않아 가볍게 읽기도 좋은 것 같다.

+

책임의 자율성을 강조하는 이유 p.173

+

협력을 단순하게 만든다.

+
    +
  • 의도를 명확하게 표현 → 협력의 복잡함 저하
  • +
  • 책임의 추상화
  • +
+

외부와 내부를 명확하게 분리한다.

+
    +
  • 요청하는 객체가 몰라도 되는 부분이 캡슐화됨으로 인터페이스와 구현의 분리
  • +
+

책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

+
    +
  • 변경의 파급효과를 객체 내부로 캡슐화 → 메시지를 보내는 객체와의 결합도 저하
  • +
+

협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

+
    +
  • 유연한 설계 → 재사용성 증가
  • +
+

객체의 역할을 이해하기 쉬워진다.

+
    +
  • 응집도를 높은 상태로 유지
  • +
+

밑줄 친 문장들

+
+

객체지향의 목표는 실세계를 모방하는 것이 아니다. 오히려 새로운 세계를 창조하는 것이다. 소프트웨어 개발자의 역할은 단순히 실세계를 소프트웨어 안으로 옮겨 담는 것이 아니라 고객과 사용자를 만족시킬 수 있는 신세계를 창조하는 것이다. -p.21

과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. +p.21

+
+
+

과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. 이에 반해 객체지향에서는 데이터와 프로세스를 객체라는 하나의 틀 안에 함께 묶어 놓음으로써 객체의 자율성을 보장한다. 자율적인 객체로 구성된 공동체는 유지 보수가 쉽고 재사용이 용이한 시스템을 구축할 수 있는 가능성을 제시한다. -p.33

객체지향의 본질

시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. -p.35

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. +p.33

+
+
+

객체지향의 본질

+

시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

+

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

+

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

+

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. +p.35

+
+
+

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. 객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다. -p.38

객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행위’다. +p.38

+
+
+

객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행위’다. 클래스는 타입을 구현하기 위해 프로그래밍 언어에서 제공하는 구현 메커니즘이라는 사실을 기억하라. -p.105

책임 주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. +p.105

+
+
+

책임 주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. 이 과정을 흔히 What/Who 사이클이라고 한다. ’어떤 행위(What)’를 수행할 것인지 결정한 후 ‘누가(who)’ 그 행위를 수행할 것인지 결정해야 한다. 여기서 ‘어떤 행위’가 바로 메시지다. -p.158

- - +p.158

+
\ No newline at end of file diff --git a/tags/book/page/3.html b/tags/book/page/3.html index 5c231a8ff..4caa34776 100644 --- a/tags/book/page/3.html +++ b/tags/book/page/3.html @@ -2,8 +2,8 @@ - -"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,19 +12,50 @@ - - - + + + -
-

"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

책 정보

글, 우리도 잘 쓸 수 있습니다.
-박솔미

읽고 나서

저자의 경험과 함께 글쓰기에 대한 가벼운 조언이 담겨있어 가볍게 읽기 좋았다.
-글을 잘 작성해 보고 싶을 때 적용해 볼 수 있는 정보가 많아서 도움이 되었다.

우아한 테크코스의 프리코스를 진행할 때 후기를 작성하고 나면 항상 글이 딱딱하다는 느낌을 받았다.
+

"Book" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

책 정보

+
+

글, 우리도 잘 쓸 수 있습니다.
+박솔미

+
+

읽고 나서

+

저자의 경험과 함께 글쓰기에 대한 가벼운 조언이 담겨있어 가볍게 읽기 좋았다.
+글을 잘 작성해 보고 싶을 때 적용해 볼 수 있는 정보가 많아서 도움이 되었다.

+

우아한 테크코스의 프리코스를 진행할 때 후기를 작성하고 나면 항상 글이 딱딱하다는 느낌을 받았다.
다른 지원자들의 읽기 편하고, 밝은 느낌을 주는 글을 보면 부러운 마음을 가지기도 했다.
-이 책을 읽었으니 2023년에는 조금 더 글을 잘 적어보려고 한다.

밑줄 친 문장들

문장이 심심하고 지루하다면 -내용을 일목요연하게 정리했고, 글의 의도도 삐뚤지 않고, 단어도 적절한 것으로 골랐는데… 그런데도 어딘가가 심심하고 지루하다면? 축축 처지고 따분하다면? 말꼬리를 모조리 ‘~다’로 통일한 건 아닌지 점검해 보세요.

말꼬리를 잘 갖고 놀아야 합니다. 문장의 마지막 글자를 매번 다르게 고쳐쓰는 것만으로도 글에 활기를 더할 수 있죠. 때론 문장을 다 마치지 않고, 단어로만 끝맺는 것도 방법. 문장과 문장 사이에 쉼표가 들어서며 글 전체에 활기가 돌게 돼요. 문장의 길이도 다채로워지는 덕분에 덤으로 얻게 되는 것도 있습니다. 바로, 글의 리듬.

이전 문장에서 끝난 글자로, 다음 문장을 끝맺지 않기. 한두 문단마다 단어 수준의 아주 짧은 문장 배치하기.

글의 진짜 이유, 글의 진짜 목적, 글의 진짜 대상을 찾으려고 애썼습니다. 지금처럼 틀을 떠올린다거나, 눈치를 본다거나, 정치적인 셈도 하지 않았어요.

제목은 짧게, 보기 쉽게, 읽기 쉽게, 발음이 비슷하게, 순서를 바꿔서

글을 마지막으로 다듬을 때, 노래에 가까워질 방법은 없을지 고민해봅니다. 감히 가 닿을 수 없는 목표이겠지만, 할 수 있는 최소한의 리듬이라도 붙여주고 싶어요.

여는 말과 마지막 말에 작정하고 마음을 담는 연습을 해봅시다. 글의 어느 구석이라도 뻔한 글자는 남기지 않겠노라 다짐하며 써보는 겁니다. 나만이 가진 유일한 메시지에 집중하면서요. 그럼 생각이 달라지고, 고르는 단어도 달라지고, 남긴 문장도 달라져요. 결국에는 글을 쓴 사람인 나 자신도 남달라질 겁니다.

맞춤법은 중요합니다. 하지만 맞춤법보다 더 중요한 건 거기에 담긴 마음입니다. 내 마음을 글에 담아 실어 보내기 전, 맞춤법을 점검하는 이유 역시 그겁니다. 오직 내 마음이 남에게 읽히는 동안 방해가 되지 않기를 바라기 때문이죠. 내가 쓴 글도, 남이 쓴 글도. 언제나 그 안에 담긴 마음이 먼저입니다.

글을 쓴다고 글이 완성되는 게 아니에요. 글과 닮은 모습으로 살 때, 글은 비로소 완성됩니다.

- - +이 책을 읽었으니 2023년에는 조금 더 글을 잘 적어보려고 한다.

+

밑줄 친 문장들

+
+

문장이 심심하고 지루하다면 +내용을 일목요연하게 정리했고, 글의 의도도 삐뚤지 않고, 단어도 적절한 것으로 골랐는데… 그런데도 어딘가가 심심하고 지루하다면? 축축 처지고 따분하다면? 말꼬리를 모조리 ‘~다’로 통일한 건 아닌지 점검해 보세요.

+
+
+

말꼬리를 잘 갖고 놀아야 합니다. 문장의 마지막 글자를 매번 다르게 고쳐쓰는 것만으로도 글에 활기를 더할 수 있죠. 때론 문장을 다 마치지 않고, 단어로만 끝맺는 것도 방법. 문장과 문장 사이에 쉼표가 들어서며 글 전체에 활기가 돌게 돼요. 문장의 길이도 다채로워지는 덕분에 덤으로 얻게 되는 것도 있습니다. 바로, 글의 리듬.

+
+
+

이전 문장에서 끝난 글자로, 다음 문장을 끝맺지 않기. 한두 문단마다 단어 수준의 아주 짧은 문장 배치하기.

+
+
+

글의 진짜 이유, 글의 진짜 목적, 글의 진짜 대상을 찾으려고 애썼습니다. 지금처럼 틀을 떠올린다거나, 눈치를 본다거나, 정치적인 셈도 하지 않았어요.

+
+
+

제목은 짧게, 보기 쉽게, 읽기 쉽게, 발음이 비슷하게, 순서를 바꿔서

+
+
+

글을 마지막으로 다듬을 때, 노래에 가까워질 방법은 없을지 고민해봅니다. 감히 가 닿을 수 없는 목표이겠지만, 할 수 있는 최소한의 리듬이라도 붙여주고 싶어요.

+
+
+

여는 말과 마지막 말에 작정하고 마음을 담는 연습을 해봅시다. 글의 어느 구석이라도 뻔한 글자는 남기지 않겠노라 다짐하며 써보는 겁니다. 나만이 가진 유일한 메시지에 집중하면서요. 그럼 생각이 달라지고, 고르는 단어도 달라지고, 남긴 문장도 달라져요. 결국에는 글을 쓴 사람인 나 자신도 남달라질 겁니다.

+
+
+

맞춤법은 중요합니다. 하지만 맞춤법보다 더 중요한 건 거기에 담긴 마음입니다. 내 마음을 글에 담아 실어 보내기 전, 맞춤법을 점검하는 이유 역시 그겁니다. 오직 내 마음이 남에게 읽히는 동안 방해가 되지 않기를 바라기 때문이죠. 내가 쓴 글도, 남이 쓴 글도. 언제나 그 안에 담긴 마음이 먼저입니다.

+
+
+

글을 쓴다고 글이 완성되는 게 아니에요. 글과 닮은 모습으로 살 때, 글은 비로소 완성됩니다.

+
\ No newline at end of file diff --git a/tags/class.html b/tags/class.html index f1d8d3109..e043889cb 100644 --- a/tags/class.html +++ b/tags/class.html @@ -2,8 +2,8 @@ - -"Class" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Class" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,31 +12,84 @@ - - - + + + -
-

"Class" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

클래스 파일

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
-컴파일된 클래스파일은 어떤 구조로 되어있을까?

클래스 파일의 데이터 형식

8비트 바이트의 스트림으로 구성된다.
+

"Class" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

클래스 파일

+

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
+컴파일된 클래스파일은 어떤 구조로 되어있을까?

+

클래스 파일의 데이터 형식

+

8비트 바이트의 스트림으로 구성된다.
16비트 및 32비트의 데이터는 각각 2개, 4개의 연속된 8비트를 읽어서 구성된다.
-멀티바이트의 경우 항상 big endian 순서로 저장된다.

u1 → unsigned 1byte
+멀티바이트의 경우 항상 big endian 순서로 저장된다.

+

u1 → unsigned 1byte
u2 → unsigned 2byte
-u4 → unsigned 4byte

클래스 파일 구조

ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

매직넘버

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
-보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

클래스 파일 포맷 버전

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

class file format major versions

Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61

상수 풀

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
+u4 → unsigned 4byte

+

클래스 파일 구조

+
ClassFile {
+    u4             magic;
+    u2             minor_version;
+    u2             major_version;
+    u2             constant_pool_count;
+    cp_info        constant_pool[constant_pool_count-1];
+    u2             access_flags;
+    u2             this_class;
+    u2             super_class;
+    u2             interfaces_count;
+    u2             interfaces[interfaces_count];
+    u2             fields_count;
+    field_info     fields[fields_count];
+    u2             methods_count;
+    method_info    methods[methods_count];
+    u2             attributes_count;
+    attribute_info attributes[attributes_count];
+}
+
+

매직넘버

+

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
+보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

+

클래스 파일 포맷 버전

+

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

+
    +
  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D
  • +
+

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

+

class file format major versions

+
Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61
+

상수 풀

+

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
클래스명, 상수명, 상수 값, 필드명, 메서드명과 같은 값들이 존재한다.
-JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

액세스 플래그

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
-예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

Class access and property modifiers

Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.

this_class

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
-해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

super_class

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
-아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

interface, field, method

각각의 개수와, 정보에 대한 값이 들어있다.
-interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

attributes

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
-정해진 클래스 파일의 구조를 확장하는 역할을 한다.

클래스 파일 확인하면서 사용한 툴

IntelliJ plugin - BinEd
-IntelliJ plugin - jclasslib Bytecode Viewer

참고 자료

2장 JVM 이야기, 자바 최적화
-Class file in Java, File Format
-java se11 Class 파일 형식, Oracle
-java se17 Class 파일 형식, Oracle

- - +JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

+

액세스 플래그

+

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
+예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

+
    +
  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT
  • +
+

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

+

Class access and property modifiers

+
Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.
+

this_class

+

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
+해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

+

super_class

+

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
+아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

+

interface, field, method

+

각각의 개수와, 정보에 대한 값이 들어있다.
+interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

+

attributes

+

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
+정해진 클래스 파일의 구조를 확장하는 역할을 한다.

+

클래스 파일 확인하면서 사용한 툴

+

IntelliJ plugin - BinEd
+IntelliJ plugin - jclasslib Bytecode Viewer

+

참고 자료

+

2장 JVM 이야기, 자바 최적화
+Class file in Java, File Format
+java se11 Class 파일 형식, Oracle
+java se17 Class 파일 형식, Oracle

\ No newline at end of file diff --git a/tags/cloudwatch.html b/tags/cloudwatch.html index f1445148a..648e9c8c6 100644 --- a/tags/cloudwatch.html +++ b/tags/cloudwatch.html @@ -2,8 +2,8 @@ - -"cloudwatch" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"cloudwatch" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,92 @@ - - - + + + -
-

"cloudwatch" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

CloudWatch

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
+

"cloudwatch" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

CloudWatch

+

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
지표를 감시하여 알림을 보내는 기능도 제공한다.
프리티어를 사용하지 않는 경우 대시보드당 3$/M 의 비용이 청구되고, 지표나 로그의 양에 따라 비용이 추가적으로 청구된다.
-요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

CloudWatch Metrics

기본적으로 5분마다 지표에 대한 정보가 수집된다.
+요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

+

CloudWatch Metrics

+

기본적으로 5분마다 지표에 대한 정보가 수집된다.
세부 모니터링(Detailed Monitoring)을 활성화하면 1분마다 지표를 수집한다.
-대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

./cloudwatch1.png

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

CloudWatch Agent 설치

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

IAM 역할 설정

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
-IAM → 역할에서 역할 생성을 클릭한다.

./cloudwatch2.png

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

./cloudwatch3.png

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
-작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

./cloudwatch4.png

설치

환경은 다음과 같다.

OS: ubuntu 22.04
-인스턴스 유형: t4g.small (ARM64)

아래 명령어를 입력하여 설치한다.

wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i -E ./amazon-cloudwatch-agent.deb

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

Wizard

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
+대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

+

./cloudwatch1.png

+

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

+

CloudWatch Agent 설치

+

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

+

IAM 역할 설정

+

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
+IAM → 역할에서 역할 생성을 클릭한다.

+

./cloudwatch2.png

+

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

+

./cloudwatch3.png

+

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
+작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

+

./cloudwatch4.png

+

설치

+

환경은 다음과 같다.

+

OS: ubuntu 22.04
+인스턴스 유형: t4g.small (ARM64)

+

아래 명령어를 입력하여 설치한다.

+
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
+sudo dpkg -i -E ./amazon-cloudwatch-agent.deb
+
+

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

+

Wizard

+

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
로그를 수집하도록 설정하는 경우 Wizard 실행 명령어 입력 전 log 파일의 절대 경로를 복사해두는 것이 좋다.
-아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
-로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

./cloudwatch5.png

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

Do you want to store the config in the SSM parameter store?
1. yes
2. no

추가적으로 설정하지 않는 경우 2번을 선택한다.
-Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
-설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

설정 파일 적용

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
-file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

types.db: no such file or directory 에러

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory

types.db 파일 생성

sudo mkdir /usr/share/collectd
sudo touch /usr/share/collectd/types.db

지표 확인

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

./cloudwatch6.png

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

{
"metrics": {
"namespace": "2023-hello-world",
......
},
}

로그

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

./cloudwatch7.png

참고 자료

CloudWatch란 무엇입니까?
-Amazon CloudWatch 요금
-Linux 인스턴스 지표
-서버에 CloudWatch 에이전트 설치 및 실행
-CloudWatch Agent를 Parameter Store에서 관리해 보기
-CloudWatch에이전트 구성 파일

- - +아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
+
+

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
+로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

+

./cloudwatch5.png

+

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

+
Do you want to store the config in the SSM parameter store?
+1. yes
+2. no
+
+

추가적으로 설정하지 않는 경우 2번을 선택한다.
+Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
+설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

+

설정 파일 적용

+

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
+file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
+
+

types.db: no such file or directory 에러

+

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

+
Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory
+
+

types.db 파일 생성

+
sudo mkdir /usr/share/collectd
+sudo touch /usr/share/collectd/types.db
+
+

지표 확인

+

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

+

./cloudwatch6.png

+

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

+
{
+  "metrics": {
+    "namespace": "2023-hello-world",
+    ......
+   },
+} 
+
+

로그

+

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

+

./cloudwatch7.png

+

참고 자료

+

CloudWatch란 무엇입니까?
+Amazon CloudWatch 요금
+Linux 인스턴스 지표
+서버에 CloudWatch 에이전트 설치 및 실행
+CloudWatch Agent를 Parameter Store에서 관리해 보기
+CloudWatch에이전트 구성 파일

\ No newline at end of file diff --git a/tags/composite.html b/tags/composite.html index 72297f31a..6d52081ed 100644 --- a/tags/composite.html +++ b/tags/composite.html @@ -2,8 +2,8 @@ - -"Composite" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Composite" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,26 +12,110 @@ - - - + + + -
-

"Composite" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

요구사항

지하철 미션에는 다음과 같은 요구사항이 있었다.

  • 거리별 추가 요금 정책
  • 노선별 추가 요금 정책
  • 연령별 요금 할인 정책

인터페이스 사용

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
-요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

public interface FarePolicy {
int calculate(Path path, Passenger passenger, int fare);
}

public class BaseFarePolicy implements FarePolicy { ... }
public class DistanceFarePolicy implements FarePolicy { ... }
public class AgeDiscountFarePolicy implements FarePolicy { ... }

composite1

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
-이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

public class SubwayFarePolicy implements FarePolicy {

private final List<FarePolicy> farePolicies;

public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
this.farePolicies = farePolicies;
}

@Override
public int calculate(final Path path, final Passenger passenger, final int fare) {
int calculatedFare = fare;
for (FarePolicy farePolicy : farePolicies) {
calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
}
return calculatedFare;
}
}

따라서 그림으로 본다면 다음과 같은 구조가 된다.

composite2

정책의 순서

지하철 요구사항은 순서가 중요했다.
+

"Composite" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

요구사항

+

지하철 미션에는 다음과 같은 요구사항이 있었다.

+
    +
  • 거리별 추가 요금 정책
  • +
  • 노선별 추가 요금 정책
  • +
  • 연령별 요금 할인 정책
  • +
+

인터페이스 사용

+

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
+요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

+
public interface FarePolicy {
+    int calculate(Path path, Passenger passenger, int fare);
+}
+
+public class BaseFarePolicy implements FarePolicy { ... }
+public class DistanceFarePolicy implements FarePolicy { ... }
+public class AgeDiscountFarePolicy implements FarePolicy { ... }
+
+

composite1

+

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

+

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
+이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

+
public class SubwayFarePolicy implements FarePolicy {
+
+    private final List<FarePolicy> farePolicies;
+
+    public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
+        this.farePolicies = farePolicies;
+    }
+
+    @Override
+    public int calculate(final Path path, final Passenger passenger, final int fare) {
+        int calculatedFare = fare;
+        for (FarePolicy farePolicy : farePolicies) {
+            calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
+        }
+        return calculatedFare;
+    }
+}
+
+

따라서 그림으로 본다면 다음과 같은 구조가 된다.

+

composite2

+

정책의 순서

+

지하철 요구사항은 순서가 중요했다.
금액의 총합을 구하고, 그 후에 할인 정책이 들어가야했다.
따라서 자식들의 순서를 관리할 때 주의를 기울여야 했다.
-Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

@Configuration
public class FareConfiguration {

@Bean
public FarePolicy farePolicy() {
return new SubwayFarePolicy(List.of(
new BaseFarePolicy(),
new DistanceFarePolicy(),
new AgeDiscountFarePolicy()
));
}
}

컴포지트 패턴이란?

composite3

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
-사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

컴포지트 패턴의 구성요소

Component

  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • ex) 요금 정책(FarePolicy)

Leaf

  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • ex) 거리 별 요금 정책(DistanceFarePolicy)

Composite

  • 여러 개의 개발 객체를 포함하는 합성 객체
  • ex) 지하철 요금 정책(SubwayFarePolicy)

Client

  • 인터페이스를 사용하는 클라이언트

컴포지트 패턴의 사용과 주요 목표

부분 - 전체의 관계를 표현하고 싶을 때
-Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

패턴 사용시 주의해야할 부분

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
+Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

+
@Configuration
+public class FareConfiguration {
+
+    @Bean
+    public FarePolicy farePolicy() {
+        return new SubwayFarePolicy(List.of(
+                new BaseFarePolicy(),
+                new DistanceFarePolicy(),
+                new AgeDiscountFarePolicy()
+        ));
+    }
+}
+
+

컴포지트 패턴이란?

+

composite3

+

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

+
+

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
+사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

+
+

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
+이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

+

컴포지트 패턴의 구성요소

+

Component

+
    +
  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • +
  • ex) 요금 정책(FarePolicy)
  • +
+

Leaf

+
    +
  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • +
  • ex) 거리 별 요금 정책(DistanceFarePolicy)
  • +
+

Composite

+
    +
  • 여러 개의 개발 객체를 포함하는 합성 객체
  • +
  • ex) 지하철 요금 정책(SubwayFarePolicy)
  • +
+

Client

+
    +
  • 인터페이스를 사용하는 클라이언트
  • +
+

컴포지트 패턴의 사용과 주요 목표

+

부분 - 전체의 관계를 표현하고 싶을 때
+Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

+

패턴 사용시 주의해야할 부분

+

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
반복되는 문제를 효율적으로 해결할 수 있지만 패턴에 매몰되서는 안된다.
-패턴을 맹목적으로 사용해서는 안되고, 현재의 요구사항에 따라 패턴을 유동적으로 수정해가면서 적용하는 것이 좋다.
-항상 트레이드오프를 생각하자!

참고 자료

컴포지트 패턴, GoF의 디자인 패턴
+패턴을 맹목적으로 사용해서는 안되고, 현재의 요구사항에 따라 패턴을 유동적으로 수정해가면서 적용하는 것이 좋다.
+항상 트레이드오프를 생각하자!

+

참고 자료

+

컴포지트 패턴, GoF의 디자인 패턴
디자인 패턴과 프레임워크, 오브젝트

- - \ No newline at end of file diff --git a/tags/data-base.html b/tags/data-base.html index cd2b877c4..c015ba31f 100644 --- a/tags/data-base.html +++ b/tags/data-base.html @@ -2,8 +2,8 @@ - -"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,69 @@ - - - + + + -
-

"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

InnoDB 스토리지 엔진의 잠금

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
-보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
-InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

낙관적 동시성 제어(OCC, Optimistic concurrency control)

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

비관적 동시성 제어(PCC, Pessimistic Concurrency Control)

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
-일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

Shared & Exclusive Locks

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

공유 잠금(S, shared lock)

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
+

"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

InnoDB 스토리지 엔진의 잠금

+

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
+보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

+

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
+InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

+

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

+

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
+일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

+

Shared & Exclusive Locks

+

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

+

공유 잠금(S, shared lock)

+

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
다른 트랜잭션에서 읽기가 가능하지만, 쓰기는 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

배타적 잠금(X, exclusive lock)

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
+예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

+

배타적 잠금(X, exclusive lock)

+

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
락을 건 트랜잭션만이 해당 데이터에 접근 가능하다. 다른 트랜잭션의 경우 읽기, 쓰기가 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

Intention Locks

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
+예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

+

Intention Locks

+

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
테이블에 있는 로우에 대해서 나중에 요청되는 것이 어떤 형태의 잠금인지 가리키기 위해 사용된다.
기본적으로 로우 단위 잠금을 수행하기 전에 인텐션 잠금을 먼저 획득한다.
-인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

인텐션 공유 잠금(IS, intention shared lock)

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

인텐션 배타적 잠금(IX, intention exclusive lock)

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

잠금간의 호환성

XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

Record Locks

레코드 자체만을 잠그는 락이다.
-InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

Gap Locks

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

Next-Key Locks

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
-REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

AUTO-INC Locks

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
+인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

+

인텐션 공유 잠금(IS, intention shared lock)

+

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

+

인텐션 배타적 잠금(IX, intention exclusive lock)

+

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

+

** 잠금간의 호환성 **

+
XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible
+

Record Locks

+

레코드 자체만을 잠그는 락이다.
+InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

+

Gap Locks

+

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

+

Next-Key Locks

+

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
+REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

+

AUTO-INC Locks

+

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
InnoDB 는 내부적으로 AUTO-INC 락이라고 하는 테이블 수준의 잠금을 사용한다.
-트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

잠금 예시

-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
-- Record Locks: 10에 대해 락이 걸린다.
SELECT * FROM table_name where id = 10 for update;

-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
SELECT * FROM table_name where id > 100 for update;

-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Optimistic and Pessimistic record locking, IBM
-MySQL Innodb Locks, cecil1018
-MySQL 8.0 InnoDB Locks, MySQL
-Locks Set by Different SQL Statements in InnoDB, MySQL

- - +트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

+

잠금 예시

+
-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
+-- Record Locks: 10에 대해 락이 걸린다.
+SELECT * FROM table_name where id = 10 for update;
+
+-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
+SELECT * FROM table_name where id > 100 for update;
+
+-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
+SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Optimistic and Pessimistic record locking, IBM
+MySQL Innodb Locks, cecil1018
+MySQL 8.0 InnoDB Locks, MySQL
+Locks Set by Different SQL Statements in InnoDB, MySQL

\ No newline at end of file diff --git a/tags/data-base/page/2.html b/tags/data-base/page/2.html index 7f703237a..59328ea64 100644 --- a/tags/data-base/page/2.html +++ b/tags/data-base/page/2.html @@ -2,8 +2,8 @@ - -"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,27 +12,75 @@ - - - + + + -
-

"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

MySQL 엔진의 잠금

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
-MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

글로벌 락(Global lock)

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

  • 영향을 미치는 범위는 해당 서버 전체이다.
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
+

"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

MySQL 엔진의 잠금

+

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
+MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

+

글로벌 락(Global lock)

+

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

+
    +
  • 영향을 미치는 범위는 해당 서버 전체이다.
  • +
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.
  • +
+

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 일관된 백업을 받아야할 때 사용한다.
-InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

-- GLOBAL LOCK
FLUSH TABLES WITH READ LOCK;
-- UNLOCK
UNLOCK TABLES;

-- BACKUP LOCK
LOCK INSTANCE FOR BACKUP;
-- UNLOCK
UNLOCK INSTANCE;
MyISAM

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
-트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

테이블 락(Table lock)

개별 테이블 단위로 설정되는 잠금이다.
+InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

+
-- GLOBAL LOCK
+FLUSH TABLES WITH READ LOCK;
+-- UNLOCK
+UNLOCK TABLES;
+
+-- BACKUP LOCK
+LOCK INSTANCE FOR BACKUP;
+-- UNLOCK
+UNLOCK INSTANCE;
+
+

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
+트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

+

테이블 락(Table lock)

+

개별 테이블 단위로 설정되는 잠금이다.
명시적 또는 묵시적으로 특정 테이블의 락을 획득할 수 있다.
묵시적 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.
-InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

-- TABLE LOCK
LOCK TABLES table_name [ READ | WRITE ]

-- UNLOCK
UNLOCK TABLES;

네임드 락(Named lock)

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
-여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
SELECT GET_LOCK('aGVyYg==', 1);

-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
SELECT IS_FREE_LOCK('aGVyYg==');

-- 문자열에 대한 잠금을 해제한다.
SELECT RELEASE_LOCK('aGVyYg==');

-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.

-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
SELECT RELEASE_ALL_LOCKS();

메타데이터 락(Metadata lock)

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
+InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

+
-- TABLE LOCK
+LOCK TABLES table_name [ READ | WRITE ]
+
+-- UNLOCK
+UNLOCK TABLES;
+
+

네임드 락(Named lock)

+

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
+여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

+
-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
+SELECT GET_LOCK('aGVyYg==', 1);
+
+-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
+SELECT IS_FREE_LOCK('aGVyYg==');
+
+-- 문자열에 대한 잠금을 해제한다.
+SELECT RELEASE_LOCK('aGVyYg==');
+
+-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.
+
+-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
+SELECT RELEASE_ALL_LOCKS();
+
+

메타데이터 락(Metadata lock)

+

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
-보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
RENAME TABLE rank TO rank_backup, rank_new TO rank;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-MySQL의 User Level Lock를 활용한다면?, gywndi
-Locking Functions, MySQL 5.7 Reference
-Locking Functions, MySQL 8.0 Reference

- - +보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

+
-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
+-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
+RENAME TABLE rank TO rank_backup, rank_new TO rank;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+MySQL의 User Level Lock를 활용한다면?, gywndi
+Locking Functions, MySQL 5.7 Reference
+Locking Functions, MySQL 8.0 Reference

\ No newline at end of file diff --git a/tags/data-base/page/3.html b/tags/data-base/page/3.html index db2d86dd0..82b01cbfa 100644 --- a/tags/data-base/page/3.html +++ b/tags/data-base/page/3.html @@ -2,8 +2,8 @@ - -"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,37 +12,139 @@ - - - + + + -
-

"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

트랜잭션(Transaction)

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
+

"DataBase" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

트랜잭션(Transaction)

+

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
트랜잭션은 작업의 완전성과 데이터의 정합성을 보장해 준다.
-논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

트랜잭션의 속성(ACID)

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
+논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

+

트랜잭션의 속성(ACID)

+

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
일관성(Consistency): 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지해야 한다.
격리성(Isolation): 각각의 트랜잭션은 독립적이라 서로에게 영향을 주지 않아야 한다.
-지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

트랜잭션 주의사항

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
-구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

왜 네트워크 작업이 있을 때 트랜잭션에서 배제해야 할까? 🤔

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
-네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)

격리 수준(Isolation level)

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
-격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

READ UNCOMMITTED

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
+지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

+

트랜잭션 주의사항

+

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
+구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

+

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
+네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

    +
  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • +
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)
  • +
+

격리 수준(Isolation level)

+

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
+격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

+

READ UNCOMMITTED

+

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
더티 리드 현상이 발생하기 때문에 정합성의 문제가 많은 격리 수준이다.
-MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

READ COMMITTED

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
+MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

+ +

READ COMMITTED

+

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
오라클 DBMS에서 기본으로 사용되는 격리 수준이다.
-REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

REPEATABLE READ

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
+REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

+ +

REPEATABLE READ

+

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준이다.
MVCC를 이용해 언두(Undo) 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
-동일한 결과를 보장하는 방법은 다음과 같다.

  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

갭 랍(Gap lock)과 넥스트 키 락(Next-key lock)

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

MVCC(Multi Version Concurrency Control)

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

SERIALIZABLE

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
+동일한 결과를 보장하는 방법은 다음과 같다.

+
    +
  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • +
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • +
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • +
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.
  • +
+

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

+ +

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

+

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

    +
  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • +
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)
  • +

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

+

SERIALIZABLE

+

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 접근할 수 없고 단순한 읽기 작업도 공유 잠금(읽기 잠금)을 획득해야만 한다.
-InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

격리 수준에 따른 부정합 문제

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX

더티 리드(Dirty read)

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
+InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

+

격리 수준에 따른 부정합 문제

+

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

+
격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX
+

더티 리드(Dirty read)

+

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
트랜잭션 격리 수준이 READ UNCOMMITTED일 때 발생한다.
-예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

반복 가능하지 않은 조회(Non-repeatable read)

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
-예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

팬텀 리드(Phantom read, Phantom row)

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
-예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Isolation Level, MySQL

- - +예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

+

반복 가능하지 않은 조회(Non-repeatable read)

+

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
+예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

+ +

팬텀 리드(Phantom read, Phantom row)

+

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
+예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

+ +

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Isolation Level, MySQL

\ No newline at end of file diff --git a/tags/documentation.html b/tags/documentation.html index cf8c73531..c56299be5 100644 --- a/tags/documentation.html +++ b/tags/documentation.html @@ -2,8 +2,8 @@ - -"Documentation" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Documentation" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,34 +12,359 @@ - - - + + + -
-

"Documentation" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 11분

팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.

설치

공식 홈페이지에 들어가서 최신 버전을 설치한다.

yarn create docusaurus

배포

배포 안내 문서
+

"Documentation" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 11분

팀 블로그 또는 문서화를 위해 Docusaurus를 사용하는 방법을 정리하려고 한다.

+

설치

+

공식 홈페이지에 들어가서 최신 버전을 설치한다.

+
yarn create docusaurus
+
+

배포

+

배포 안내 문서
netlify나 vercel 같은 서버리스 플랫폼을 추천하고 있고, 간단하고, 빠른 시간 안에 배포를 할 수 있다.
-이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.

레포지토리 생성

github pages를 이용하려면 예시와 같이 username.github.io 형태의 레포지토리를 생성해야 한다.
-이때 organization을 사용하는 경우 organization.github.io 형태의 레포지토리를 생성해서 사용한다.

설정 파일 수정

docusaurus.config
module.exports = {
// ...
url: 'https://greeng00se.github.io',
baseUrl: '/',
projectName: 'greeng00se.github.io',
organizationName: 'greeng00se',
trailingSlash: false,
// ...
};

토큰 설정

github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.
-이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.

github

브랜치 생성

github에서 gh-pages 브랜치를 하나 생성한다.
+이 글에서는 github pages를 이용해서 배포하는 방법을 설명한다.

+

레포지토리 생성

+

github pages를 이용하려면 예시와 같이 username.github.io 형태의 레포지토리를 생성해야 한다.
+이때 organization을 사용하는 경우 organization.github.io 형태의 레포지토리를 생성해서 사용한다.

+

설정 파일 수정

+
module.exports = {
+  // ...
+  url: 'https://greeng00se.github.io',
+  baseUrl: '/',
+  projectName: 'greeng00se.github.io',
+  organizationName: 'greeng00se',
+  trailingSlash: false,
+  // ...
+};
+
+

토큰 설정

+

github action을 위해 배포용 토큰을 하나 생성하여 생성한 레포지토리에 Repository secrets으로 설정한다.
+이 글에서는 토큰을 클래식 방식으로 생성했고 스코프는 [repo, user, workflow] 을 설정했다.

+

github

+

브랜치 생성

+

github에서 gh-pages 브랜치를 하나 생성한다.
repository -> settings -> pages -> branch에서 생성한 gh-pages로 브랜치를 변경한다.
-설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.

워크플로 작성

Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.
-배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.

.github/workflows/deploy.yml
name: blog

on:
push:
branches: [main]

jobs:
deploy:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build website
run: yarn build

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.DEPLOY_TOKEN }}
publish_dir: ./build
user_name: github-actions[bot]
user_email: 41898282+github-actions[bot]@users.noreply.github.com

댓글 기능

giscus를 이용하여 댓글 기능을 추가한다.

giscus 설정

  1. 공개 저장소여야 한다.
  2. giscus 앱이 설치되어 있어야 한다.
  3. Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.

자세한 내용은 giscus를 확인하자.

docusaurus 설정

swizzling을 이용하여 컴포넌트를 감싼다.
+설정한 브랜치가 배포 브랜치가 되며, 해당 브랜치에 있는 파일들을 이용해서 정적 웹사이트를 제공한다.

+

워크플로 작성

+

Docusaurus 2.0 기준 Node.js 16.14 이상의 버전을 사용해야 합니다.
+배포시에는 Repository secrets으로 설정한 DEPLOY_TOKEN 을 이용합니다.

+
name: blog
+
+on:
+  push:
+    branches: [main]
+
+jobs:
+  deploy:
+    name: Deploy to GitHub Pages
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/setup-node@v3
+        with:
+          node-version: 18
+          cache: yarn
+
+      - name: Install dependencies
+        run: yarn install --frozen-lockfile
+      - name: Build website
+        run: yarn build
+
+      - name: Deploy to GitHub Pages
+        uses: peaceiris/actions-gh-pages@v3
+        with:
+          github_token: ${{ secrets.DEPLOY_TOKEN }}
+          publish_dir: ./build
+          user_name: github-actions[bot]
+          user_email: 41898282+github-actions[bot]@users.noreply.github.com
+
+

댓글 기능

+

giscus를 이용하여 댓글 기능을 추가한다.

+

giscus 설정

+
    +
  1. 공개 저장소여야 한다.
  2. +
  3. giscus 앱이 설치되어 있어야 한다.
  4. +
  5. Discussions 기능이 해당 저장소에서 활성화되어 있어야 한다.
  6. +
+

자세한 내용은 giscus를 확인하자.

+

docusaurus 설정

+

swizzling을 이용하여 컴포넌트를 감싼다.
기존에 게시물을 giscus가 포함된 리액트 컴포넌트로 감싸는 형태가 된다.
-아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.

yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap

명령어를 입력하면 /src/theme/BlogPostItem/index.js 위치에 파일이 생성된다.
-파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.

/src/theme/BlogPostItem/index.js
import OriginalBlogPostItem from "@theme-original/BlogPostItem";
import React, { useEffect, useRef } from "react";
// @ts-expect-error internal code
import { useColorMode } from "@docusaurus/theme-common";
import { useBlogPost } from "@docusaurus/theme-common/internal";

const giscusSelector = "iframe.giscus-frame";

function BlogPostItem(props) {
const { colorMode } = useColorMode();
const { isBlogPostPage } = useBlogPost();
const giscusTheme = colorMode === "dark" ? "dark" : "light";
const containerRef = useRef(null);

useEffect(() => {
if (!isBlogPostPage) return;

const giscusEl = containerRef.current.querySelector(giscusSelector);

const createGiscusEl = () => {
const script = document.createElement("script");

script.src = "https://giscus.app/client.js";
script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");
script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");
script.setAttribute("data-category", "Announcements");
script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");
script.setAttribute("data-mapping", "pathname");
script.setAttribute("data-strict", "0");
script.setAttribute("data-reactions-enabled", "1");
script.setAttribute("data-emit-metadata", "0");
script.setAttribute("data-input-position", "bottom");
script.setAttribute("data-theme", giscusTheme);
script.setAttribute("data-lang", "ko");
script.crossOrigin = "anonymous";
script.async = true;

containerRef.current.appendChild(script);
};

const postThemeMessage = () => {
const message = {
setConfig: {
theme: giscusTheme,
}
};

giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
};

giscusEl ? postThemeMessage() : createGiscusEl();
}, [giscusTheme]);

return (
<>
<OriginalBlogPostItem {...props} />
{isBlogPostPage && <div ref={containerRef} />}
</>
);
}

export default BlogPostItem;

알고리아 설정 및 직접 관리하기

알고리아를 사용하면 검색 기능을 추가할 수 있다.
-유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.

무료 플랜은 직접 인덱스를 수집하는 방법과, docsearch를 이용하는 방법이 있다.
+아래 명령어를 이용하여 BlogPostItem을 추출할 수 있다.

+
yarn run swizzle @docusaurus/theme-classic BlogPostItem -- --wrap
+
+

명령어를 입력하면 /src/theme/BlogPostItem/index.js 위치에 파일이 생성된다.
+파일의 내용을 아래와 같이 수정하고, 이때 setAttribute 부분은 적절하게 자신의 giscus 설정을 이용한다.

+
import OriginalBlogPostItem from "@theme-original/BlogPostItem";
+import React, { useEffect, useRef } from "react";
+// @ts-expect-error internal code
+import { useColorMode } from "@docusaurus/theme-common";
+import { useBlogPost } from "@docusaurus/theme-common/internal";
+
+const giscusSelector = "iframe.giscus-frame";
+
+function BlogPostItem(props) {
+  const { colorMode } = useColorMode();
+  const { isBlogPostPage } = useBlogPost();
+  const giscusTheme = colorMode === "dark" ? "dark" : "light";
+  const containerRef = useRef(null);
+
+  useEffect(() => {
+    if (!isBlogPostPage) return;
+
+    const giscusEl = containerRef.current.querySelector(giscusSelector);
+
+    const createGiscusEl = () => {
+      const script = document.createElement("script");
+
+      script.src = "https://giscus.app/client.js";
+      script.setAttribute("data-repo", "teco-chat/teco-chat.github.io");
+      script.setAttribute("data-repo-id", "R_kgDOJZ5j0Q");
+      script.setAttribute("data-category", "Announcements");
+      script.setAttribute("data-category-id", "DIC_kwDOJZ5j0c4CXS_Q");
+      script.setAttribute("data-mapping", "pathname");
+      script.setAttribute("data-strict", "0");
+      script.setAttribute("data-reactions-enabled", "1");
+      script.setAttribute("data-emit-metadata", "0");
+      script.setAttribute("data-input-position", "bottom");
+      script.setAttribute("data-theme", giscusTheme);
+      script.setAttribute("data-lang", "ko");
+      script.crossOrigin = "anonymous";
+      script.async = true;
+      
+      containerRef.current.appendChild(script);
+    };
+
+    const postThemeMessage = () => {
+      const message = {
+        setConfig: {
+          theme: giscusTheme,
+        }
+      };
+
+      giscusEl.contentWindow.postMessage({ giscus: message }, "https://giscus.app");
+    };
+
+    giscusEl ? postThemeMessage() : createGiscusEl();
+  }, [giscusTheme]);
+
+  return (
+    <>
+      <OriginalBlogPostItem {...props} />
+      {isBlogPostPage && <div ref={containerRef} />}
+    </>
+  );
+}
+
+export default BlogPostItem;
+
+

알고리아 설정 및 직접 관리하기

+

알고리아를 사용하면 검색 기능을 추가할 수 있다.
+유료 플랜이나 netlify를 사용하는 경우 크롤러를 따로 제공해 주는 것 같다.

+

무료 플랜은 직접 인덱스를 수집하는 방법과, docsearch를 이용하는 방법이 있다.
docsearch에 등록한다면 일주일에 한 번씩 크롤링이 진행된다.
-이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.

알고리아 애플리케이션 생성 및 키 확인

회원가입을 하고 새로운 애플리케이션 생성을 누른다.
-생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.

algolia

키 생성

직접 인덱스를 수집하기 위한 키를 생성한다.
-addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.

key

.env 파일 생성

프로젝트 폴더 상단에 .env 파일을 생성한다.

.env
APPLICATION_ID=MVIU5UEMOM
API_KEY=인덱스_생성용_키

config 파일 생성

마찬가지로 최상단에 config.json 파일을 생성한다. -설정 파일은 해당 링크를 참고한다.
-또는 Docusaurus의 설정 파일을 참고한다.

config.json
{
"index_name": "teco",
"start_urls": [
"https://teco-chat.github.io/"
],
"sitemap_urls": [
"https://teco-chat.github.io/sitemap.xml"
],
"sitemap_alternate_links": true,
"stop_urls": [
"/tests"
],
"selectors": {
"lvl0": {
"selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
"type": "xpath",
"global": true,
"default_value": "Documentation"
},
"lvl1": "header h1",
"lvl2": "article h2",
"lvl3": "article h3",
"lvl4": "article h4",
"lvl5": "article h5, article td:first-child",
"lvl6": "article h6",
"text": "article p, article li, article td:last-child"
},
"strip_chars": " .,;:#",
"custom_settings": {
"separatorsToIndex": "_",
"attributesForFaceting": [
"language",
"version",
"type",
"docusaurus_tag"
],
"attributesToRetrieve": [
"hierarchy",
"content",
"anchor",
"url",
"url_without_anchor",
"type"
]
},
"conversation_id": [
"833762294"
],
"nb_hits": 46250
}

docker 이용하여 크롤링

docker와 jq가 필요하다.
-jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.

brew install jq

다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.

docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper

docusaurus 설정

전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.

docusaurus.config
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...
algolia: {
appId: 'MVIU5UEMOM', // Application ID
apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key
indexName: 'teco', // config.json에 설정한 인덱스명
contextualSearch: true,
},
})

부가 설정

화면 상단 Github Icon

파일 최하단에 아래 css 구문을 추가한다.

/src/css/custom.css
.header-github-link:hover {
opacity: 0.6;
}

.header-github-link:before {
content: '';
width: 24px;
height: 24px;
display: flex;
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}

html[data-theme='dark'] .header-github-link:before {
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
no-repeat;
}

themeconfig -> navbar에 github link를 설정한다.

docusaurus.config
navbar: {
title: 'HELLO',
items: [
{
href: 'https://github.com/greeng00se',
position: 'right',
className: 'header-github-link',
'aria-label': 'GitHub repository',
},
],
},

코드블럭

java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.
-prism 설정을 아래와 같이 변경해 준다.

docusaurus.config
prism: {
theme: lightCodeTheme,
darkTheme: darkCodeTheme,
additionalLanguages: ['java', 'kotlin'],
}

mermaid

mermaid를 사용하려면 @docusaurus/theme-mermaid 를 설치해야 한다.

yarn add @docusaurus/theme-mermaid

설치 후 아래와 같이 설정을 추가한다.

docusaurus.config
const config = {
...
markdown: {
mermaid: true,
},
themes: [
'@docusaurus/theme-mermaid'
],
};

themeConfig에서 mermaid의 테마를 지정할 수 있다.

docusaurus.config
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
...
mermaid: {
theme: {
light: 'neutral',
dark: 'dark'
},
},
}),

국제화 설정

국제화 설정을 한다면 Older Entries 형태의 설명이 다음 페이지 로 변경된다.
-설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.

docusaurus.config
i18n: {
defaultLocale: "ko",
locales: ["ko"],
},

블로그 글 author

팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.

author

authors.yml 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.

/blog/authors.yml
herb:
name: 허브
title: Backend
url: https://github.com/greeng00se
image_url: https://github.com/greeng00se.png

mallang:
name: 말랑
title: Backend
url: https://github.com/shin-mallang
image_url: https://github.com/shin-mallang.png

블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.

---
slug: 1
title: Hello World
authors: [herb, mallang]
tags: [hello, docusaurus]
---

첫 번째 문서 내용
- - +이 글에서는 직접 인덱스를 수집하는 방법을 사용한다.

+ +

알고리아 애플리케이션 생성 및 키 확인

+

회원가입을 하고 새로운 애플리케이션 생성을 누른다.
+생성을 다 마치면 다음과 같이 api 키를 확인할 수 있다.

+

algolia

+

키 생성

+

직접 인덱스를 수집하기 위한 키를 생성한다.
+addObject, editSettings, deleteIndex acl(접근 제어 목록)이 있으면 된다.

+

key

+

.env 파일 생성

+

프로젝트 폴더 상단에 .env 파일을 생성한다.

+
APPLICATION_ID=MVIU5UEMOM
+API_KEY=인덱스_생성용_키
+
+

config 파일 생성

+

마찬가지로 최상단에 config.json 파일을 생성한다. +설정 파일은 해당 링크를 참고한다.
+또는 Docusaurus의 설정 파일을 참고한다.

+
{
+  "index_name": "teco",
+  "start_urls": [
+    "https://teco-chat.github.io/"
+  ],
+  "sitemap_urls": [
+    "https://teco-chat.github.io/sitemap.xml"
+  ],
+  "sitemap_alternate_links": true,
+  "stop_urls": [
+    "/tests"
+  ],
+  "selectors": {
+    "lvl0": {
+      "selector": "(//ul[contains(@class,'menu__list')]//a[contains(@class, 'menu__link menu__link--sublist menu__link--active')]/text() | //nav[contains(@class, 'navbar')]//a[contains(@class, 'navbar__link--active')]/text())[last()]",
+      "type": "xpath",
+      "global": true,
+      "default_value": "Documentation"
+    },
+    "lvl1": "header h1",
+    "lvl2": "article h2",
+    "lvl3": "article h3",
+    "lvl4": "article h4",
+    "lvl5": "article h5, article td:first-child",
+    "lvl6": "article h6",
+    "text": "article p, article li, article td:last-child"
+  },
+  "strip_chars": " .,;:#",
+  "custom_settings": {
+    "separatorsToIndex": "_",
+    "attributesForFaceting": [
+      "language",
+      "version",
+      "type",
+      "docusaurus_tag"
+    ],
+    "attributesToRetrieve": [
+      "hierarchy",
+      "content",
+      "anchor",
+      "url",
+      "url_without_anchor",
+      "type"
+    ]
+  },
+  "conversation_id": [
+    "833762294"
+  ],
+  "nb_hits": 46250
+}
+
+

docker 이용하여 크롤링

+

docker와 jq가 필요하다.
+jq가 설치되어 있지 않으면 mac 기준 brew를 이용해서 설치할 수 있다.

+
brew install jq
+
+

다음 명령어를 이용하여 .env와 config.json을 이용하여 크롤링을 한다.

+
docker run -it --env-file=.env -e "CONFIG=$(cat ./config.json | jq -r tostring)" algolia/docsearch-scraper
+
+

docusaurus 설정

+

전에 확인한 APP ID, Search-Only API KEY, IndexName을 이용하여 docusaurus.config 파일에 설정한다.

+
themeConfig:
+  /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+  ({
+    ...
+    algolia: {
+      appId: 'MVIU5UEMOM', // Application ID
+      apiKey: 'b68f378013817d9a190df88cdde226a0', // Search-Only API Key
+      indexName: 'teco', // config.json에 설정한 인덱스명
+      contextualSearch: true,
+    },
+  })
+
+

부가 설정

+

화면 상단 Github Icon

+

파일 최하단에 아래 css 구문을 추가한다.

+
.header-github-link:hover {
+  opacity: 0.6;
+}
+
+.header-github-link:before {
+  content: '';
+  width: 24px;
+  height: 24px;
+  display: flex;
+  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
+    no-repeat;
+}
+
+html[data-theme='dark'] .header-github-link:before {
+  background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
+    no-repeat;
+}
+
+

themeconfig -> navbar에 github link를 설정한다.

+
navbar: {
+  title: 'HELLO',
+  items: [
+    {
+        href: 'https://github.com/greeng00se',
+        position: 'right',
+        className: 'header-github-link',
+        'aria-label': 'GitHub repository',
+    },
+  ],
+},
+
+

코드블럭

+

java나 kotlin의 경우 기본적으로 하이라이팅을 지원해 주지 않는다.
+prism 설정을 아래와 같이 변경해 준다.

+
prism: {
+  theme: lightCodeTheme,
+  darkTheme: darkCodeTheme,
+  additionalLanguages: ['java', 'kotlin'],
+}
+
+

mermaid

+

mermaid를 사용하려면 @docusaurus/theme-mermaid 를 설치해야 한다.

+
yarn add @docusaurus/theme-mermaid
+
+

설치 후 아래와 같이 설정을 추가한다.

+
const config = {
+  ...
+  markdown: {
+    mermaid: true,
+  },
+  themes: [
+    '@docusaurus/theme-mermaid'
+  ],
+};
+
+

themeConfig에서 mermaid의 테마를 지정할 수 있다.

+
themeConfig:
+    /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
+    ({
+      ...
+      mermaid: {
+        theme: {
+          light: 'neutral', 
+          dark: 'dark'
+        },
+      },
+    }),
+
+

국제화 설정

+

국제화 설정을 한다면 Older Entries 형태의 설명이 다음 페이지 로 변경된다.
+설정파일에서 i18n에 있는 로케일 설정을 ko로 변경하면 된다.

+
i18n: {
+  defaultLocale: "ko",
+  locales: ["ko"],
+},
+
+

블로그 글 author

+

팀원 별로 문서를 관리한다면 다음과 같이 어떤 팀원이 글을 작성했는지 설정해야 한다.

+

author

+

authors.yml 파일을 이용하여 사용자에 대한 기본 설정을 할 수 있다.

+
herb:
+  name: 허브
+  title: Backend
+  url: https://github.com/greeng00se
+  image_url: https://github.com/greeng00se.png
+
+mallang:
+  name: 말랑
+  title: Backend
+  url: https://github.com/shin-mallang
+  image_url: https://github.com/shin-mallang.png
+
+

블로그 글을 작성할 때 다음과 같이 authors에 넣어주기만 하면 된다.

+
---
+slug: 1
+title: Hello World
+authors: [herb, mallang]
+tags: [hello, docusaurus]
+---
+
+첫 번째 문서 내용
+
\ No newline at end of file diff --git a/tags/dto.html b/tags/dto.html index 469e1fd18..e589593e6 100644 --- a/tags/dto.html +++ b/tags/dto.html @@ -2,8 +2,8 @@ - -"DTO" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"DTO" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,27 +12,142 @@ - - - + + + -
-

"DTO" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.
-요청에 담긴 Body를 통해 전달받은 값을 DTO로 매핑하여 추가와 수정을 했다.

장바구니 미션에서의 상품 추가 및 수정

중복1

클래스명을 제외하고 필드와 검증로직 그 외 모든게 같은 DTO를 보며 중복이라고 생각했다.
+

"DTO" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.
+요청에 담긴 Body를 통해 전달받은 값을 DTO로 매핑하여 추가와 수정을 했다.

+

장바구니 미션에서의 상품 추가 및 수정

+

중복1

+

클래스명을 제외하고 필드와 검증로직 그 외 모든게 같은 DTO를 보며 중복이라고 생각했다.
하지만 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-위 경우는 중복일까? 중복이 아닐까?

이 부분에 대해서 다음과 같은 리뷰를 받았다.

ProductSaveRequestProductUpdateRequest가 완전히 동일한데, 재사용할 수 없을까? 라는 리뷰를 남겼었어요. 사실 생성과 수정은 서로 달라질 개연성이 높아서 미리 분리해놓는 게 더 좋은 방법이긴 한데, 그래도 중복은 싫어서 저도 요즘 이런저런 방법들을 시도해보는 중 입니다. 허브는 이 부분에 대해 어떤 생각을 가지고 있을지 궁금하네요 ㅎㅎ

질문에 대해 아래와 같이 답변을 했다.

저장과 수정할 때 필요한 필드값이 동일하여 현재 구조에서는 하나로 사용해도 된다고 생각을 하지만, 말씀해주신대로 요구사항이 변경된다면 달라질 가능성이 높다고 판단하였습니다!

중복과 우발적 중복

로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 거짓된 중복, 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다. -그렇기 때문에 위 상황은 우발적 중복으로 보인다. 그래도 중복을 제거해볼 수 있지 않을까?

하나로 사용하는 건 안좋아보이고, 중복은 제거하고 싶은 마음

지금은 추가, 수정 2가지 경우 밖에 없지만 조금 더 복잡한 요구사항이 주어져서 10가지 경우로 입력을 받으면 어떻게 해야할까?
+위 경우는 중복일까? 중복이 아닐까?

+

이 부분에 대해서 다음과 같은 리뷰를 받았다.

+
+

ProductSaveRequestProductUpdateRequest가 완전히 동일한데, 재사용할 수 없을까? 라는 리뷰를 남겼었어요. 사실 생성과 수정은 서로 달라질 개연성이 높아서 미리 분리해놓는 게 더 좋은 방법이긴 한데, 그래도 중복은 싫어서 저도 요즘 이런저런 방법들을 시도해보는 중 입니다. 허브는 이 부분에 대해 어떤 생각을 가지고 있을지 궁금하네요 ㅎㅎ

+
+

질문에 대해 아래와 같이 답변을 했다.

+
+

저장과 수정할 때 필요한 필드값이 동일하여 현재 구조에서는 하나로 사용해도 된다고 생각을 하지만, 말씀해주신대로 요구사항이 변경된다면 달라질 가능성이 높다고 판단하였습니다!

+
+

중복과 우발적 중복

+

로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러가지 종류로 나누어 설명하고 있다.

+
    +
  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • +
  • 거짓된 중복, 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.
  • +
+

추가와 수정은 초기에는 중복으로 보이지만 초기 생성시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다. +그렇기 때문에 위 상황은 우발적 중복으로 보인다. 그래도 중복을 제거해볼 수 있지 않을까?

+

하나로 사용하는 건 안좋아보이고, 중복은 제거하고 싶은 마음

+

지금은 추가, 수정 2가지 경우 밖에 없지만 조금 더 복잡한 요구사항이 주어져서 10가지 경우로 입력을 받으면 어떻게 해야할까?
서비스 계층에서도 계층의 분리를 위해서 다른 DTO를 사용하고 있다면 20개의 DTO를 만들어야 할까?
-리뷰어가 알려준 의존 역전을 이용한 방법을 통해 이를 해결해보자!

중복 제거 전 코드

현재 코드에서는 아래와 같은 구조로 되어있다.
+리뷰어가 알려준 의존 역전을 이용한 방법을 통해 이를 해결해보자!

+

중복 제거 전 코드

+

현재 코드에서는 아래와 같은 구조로 되어있다.
Controller와 Service에서 저장, 수정할 때 각각의 DTO를 사용하고 있다. -현재 DTO는 controller, service 패키지 내에 있는 것이 아니라 dto라는 패키지에 위치하고 있다.

├── controller
│   └── ProductController
├── service
│   └── ProductService
├── dto
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest

중복2

인터페이스 작성하기

중복3

서비스 레이어에서 필요로 하는 값들을 인터페이스로 정의한다.
-해당 인터페이스는 서비스에서 사용하기 때문에 service 패키지 내부로 옮겨준다.

├── controller
│   └── ProductController
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public interface ProductSaveRequest {

String getName();

String getImage();

Long getPrice();
}

// ProductService
public Long save(final ProductSaveRequest request) {
final Product product = new Product(request.getName(), request.getImage(), request.getPrice());
return productDao.saveAndGetId(product);
}

구현체 작성하기

중복4

위에서 작성한 인터페이스를 구현하는 클래스를 작성한다.
-요청은 ProductRequest 클래스로 받고, 서비스에 전달할 땐 해당 인터페이스의 명세만 맞추면 문제없이 사용할 수 있다.

├── controller
│   ├── ProductController
│   └── ProductRequest
├── service
│   ├── ProductService
│   ├── ProductSaveRequest
│   └── ProductUpdateRequest
public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {

@NotBlank(message = "이름은 공백일 수 없습니다.")
@Size(min = 1, max = 100, message = "이름은 최소 {min}자 이상, {max}자 이하여야 합니다.")
private final String name;

@NotBlank(message = "이미지는 공백일 수 없습니다.")
private final String image;

@Range(message = "가격은 최소 {min}원 이상, {max}원 이하여야 합니다.")
private final long price;

public ProductRequest(final String name, final String image, final long price) {
this.name = name;
this.image = image;
this.price = price;
}

@Override
public String getName() {
return name;
}

@Override
public String getImage() {
return image;
}

@Override
public long getPrice() {
return price;
}
}

// ProductController
@PostMapping("/products")
public ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {
final Long id = productService.save(request);
return ResponseEntity.created(URI.create("/products/" + id)).build();
}

정리

위와 같이 구현한다면 다음과 같은 장점을 얻을 수 있다.

  1. Service에서 모든 클라이언트 요청에 대한 DTO를 알지 않아도 된다.
  2. 공통적으로 사용하는 DTO를 제외하고 DTO 패키지에 대한 결합도가 낮아지고, 각 레이어의 응집도가 증가한다.
  3. 요청 객체만 다르고 서비스에서 동일한 행위를 수행하는 경우 중복을 제거할 수 있다.

위 방법을 지금 미션에서 바로 적용할까 하다가, 나중에 필요할 때 적용하면 더 좋을 것 같아서 미션에는 적용하지 않았다.
-상황에 맞춰 적재적소에 의존 역전을 이용해보는 것도 좋을 것 같다.

참고 자료

클린 아키텍처 16장 독립성, 로버트 C. 마틴
-https://techblog.woowahan.com/2647/
-https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/

- - +현재 DTO는 controller, service 패키지 내에 있는 것이 아니라 dto라는 패키지에 위치하고 있다.

+
├── controller
+│   └── ProductController
+├── service
+│   └── ProductService
+├── dto
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+

중복2

+

인터페이스 작성하기

+

중복3

+

서비스 레이어에서 필요로 하는 값들을 인터페이스로 정의한다.
+해당 인터페이스는 서비스에서 사용하기 때문에 service 패키지 내부로 옮겨준다.

+
├── controller
+│   └── ProductController
+├── service
+│   ├── ProductService
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+
public interface ProductSaveRequest {
+
+    String getName();
+
+    String getImage();
+
+    Long getPrice();
+}
+
+// ProductService
+public Long save(final ProductSaveRequest request) {
+    final Product product = new Product(request.getName(), request.getImage(), request.getPrice());
+    return productDao.saveAndGetId(product);
+}
+
+

구현체 작성하기

+

중��복4

+

위에서 작성한 인터페이스를 구현하는 클래스를 작성한다.
+요청은 ProductRequest 클래스로 받고, 서비스에 전달할 땐 해당 인터페이스의 명세만 맞추면 문제없이 사용할 수 있다.

+
├── controller
+│   ├── ProductController
+│   └── ProductRequest
+├── service
+│   ├── ProductService
+│   ├── ProductSaveRequest
+│   └── ProductUpdateRequest
+
+
public class ProductRequest implements ProductSaveRequest, ProductUpdateRequest {
+
+    @NotBlank(message = "이름은 공백일 수 없습니다.")
+    @Size(min = 1, max = 100, message = "이름은 최소 {min}자 이상, {max}자 이하여야 합니다.")
+    private final String name;
+
+    @NotBlank(message = "이미지는 공백일 수 없습니다.")
+    private final String image;
+
+    @Range(message = "가격은 최소 {min}원 이상, {max}원 이하여야 합니다.")
+    private final long price;
+
+    public ProductRequest(final String name, final String image, final long price) {
+        this.name = name;
+        this.image = image;
+        this.price = price;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getImage() {
+        return image;
+    }
+
+    @Override
+    public long getPrice() {
+        return price;
+    }
+}
+
+// ProductController
+@PostMapping("/products")
+public ResponseEntity<Void> save(@Valid @RequestBody final ProductRequest request) {
+    final Long id = productService.save(request);
+    return ResponseEntity.created(URI.create("/products/" + id)).build();
+}
+
+

정리

+

위와 같이 구현한다면 다음과 같은 장점을 얻을 수 있다.

+
    +
  1. Service에서 모든 클라이언트 요청에 대한 DTO를 알지 않아도 된다.
  2. +
  3. 공통적으로 사용하는 DTO를 제외하고 DTO 패키지에 대한 결합도가 낮아지고, 각 레이어의 응집도가 증가한다.
  4. +
  5. 요청 객체만 다르고 서비스에서 동일한 행위를 수행하는 경우 중복을 제거할 수 있다.
  6. +
+

위 방법을 지금 미션에서 바로 적용할까 하다가, 나중에 필요할 때 적용하면 더 좋을 것 같아서 미션에는 적용하지 않았다.
+상황에 맞춰 적재적소에 의존 역전을 이용해보는 것도 좋을 것 같다.

+

참고 자료

+

클린 아키텍처 16장 독립성, 로버트 C. 마틴
+https://techblog.woowahan.com/2647/
+https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/

\ No newline at end of file diff --git a/tags/elastic-beanstalk.html b/tags/elastic-beanstalk.html index a7091f566..1edcb7aab 100644 --- a/tags/elastic-beanstalk.html +++ b/tags/elastic-beanstalk.html @@ -2,8 +2,8 @@ - -"Elastic Beanstalk" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Elastic Beanstalk" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,31 +12,218 @@ - - - + + + -
-

"Elastic Beanstalk" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

설정 환경

소프트웨어 이미지: Amazon Linux 2023 AMI
+

"Elastic Beanstalk" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

설정 환경

+

소프트웨어 이미지: Amazon Linux 2023 AMI
아키텍쳐: ARM
인스턴스 유형: t4g.small
환경 구성이 완료된 Elastic Beanstalk
-단일 Spring Boot 프로젝트가 존재하는 Github Repository

[EC2 CLI] Swap 메모리 설정

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
-아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

# fallocate 이용하여 스왑 파일 생성
sudo fallocate -l 2G /swapfile

# 권한 설정
sudo chmod 600 /swapfile

# 파일을 Swap 포맷으로 변경 후 시스템에 등록
sudo mkswap /swapfile
sudo swapon /swapfile

# Swap 메모리 부팅시 자동으로 마운트하도록 적용
# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
sudo vim /etc/fstab

[EC2 CLI] jenkins 설치

sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install java-17-amazon-corretto-devel
sudo yum install jenkins
sudo systemctl daemon-reload

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

[EC2 CLI] Jenkins 시작

sudo systemctl enable jenkins
sudo systemctl start jenkins

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

[EC2 CLI] nginx & git 설치

sudo yum install nginx
sudo systemctl enable nginx
sudo systemctl start nginx

sudo yum install git

nginx와 코드를 불러올 때 사용할 git을 설치한다.

[EC2 CLI] nginx 리버스 프록시 설정

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

upstream jenkins {
keepalive 32; # keepalive connections
server 127.0.0.1:8080; # jenkins ip and port
}

# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 80; # Listen on port 80 for IPv4 requests

server_name jenkins.example.com; # replace 'jenkins.example.com' with your server domain name

# this is the jenkins web root directory
# (mentioned in the output of "systemctl cat jenkins")
root /var/run/jenkins/war/;

access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;

# pass through headers from Jenkins that Nginx considers invalid
ignore_invalid_headers off;

location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
# rewrite all static files into requests to the root
# E.g /static/12345678/css/something.css will become /css/something.css
rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
}

location /userContent {
# have nginx handle all the static requests to userContent folder
# note : This is the $JENKINS_HOME dir
root /var/lib/jenkins/;
if (!-f $request_filename){
# this file does not exist, might be a directory or a /**view** url
rewrite (.*) /$1 last;
break;
}
sendfile on;
}

location / {
sendfile off;
proxy_pass http://jenkins;
proxy_redirect default;
proxy_http_version 1.1;

# Required for Jenkins websocket agents
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_max_temp_file_size 0;

#this is the maximum upload size
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffering off;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection ""; # Clear for keepalive
}

}

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
+단일 Spring Boot 프로젝트가 존재하는 Github Repository

+

[EC2 CLI] Swap 메모리 설정

+

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
+아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

+
# fallocate 이용하여 스왑 파일 생성
+sudo fallocate -l 2G /swapfile
+
+# 권한 설정
+sudo chmod 600 /swapfile
+
+# 파일을 Swap 포맷으로 변경 후 시스템에 등록
+sudo mkswap /swapfile
+sudo swapon /swapfile
+
+# Swap 메모리 부팅시 자동으로 마운트하도록 적용
+# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
+sudo vim /etc/fstab
+
+

[EC2 CLI] jenkins 설치

+
sudo wget -O /etc/yum.repos.d/jenkins.repo \
+    https://pkg.jenkins.io/redhat-stable/jenkins.repo
+sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
+sudo yum upgrade
+sudo yum install java-17-amazon-corretto-devel
+sudo yum install jenkins
+sudo systemctl daemon-reload
+
+

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

+

[EC2 CLI] Jenkins 시작

+
sudo systemctl enable jenkins
+sudo systemctl start jenkins
+
+

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

+

[EC2 CLI] nginx & git 설치

+
sudo yum install nginx
+sudo systemctl enable nginx
+sudo systemctl start nginx
+
+sudo yum install git
+
+

nginx와 코드를 불러올 때 사용할 git을 설치한다.

+

[EC2 CLI] nginx 리버스 프록시 설정

+

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

+
upstream jenkins {
+  keepalive 32; # keepalive connections
+  server 127.0.0.1:8080; # jenkins ip and port
+}
+
+# Required for Jenkins websocket agents
+map $http_upgrade $connection_upgrade {
+  default upgrade;
+  '' close;
+}
+
+server {
+  listen          80;       # Listen on port 80 for IPv4 requests
+
+  server_name     jenkins.example.com;  # replace 'jenkins.example.com' with your server domain name
+
+  # this is the jenkins web root directory
+  # (mentioned in the output of "systemctl cat jenkins")
+  root            /var/run/jenkins/war/;
+
+  access_log      /var/log/nginx/jenkins.access.log;
+  error_log       /var/log/nginx/jenkins.error.log;
+
+  # pass through headers from Jenkins that Nginx considers invalid
+  ignore_invalid_headers off;
+
+  location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
+    # rewrite all static files into requests to the root
+    # E.g /static/12345678/css/something.css will become /css/something.css
+    rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
+  }
+
+  location /userContent {
+    # have nginx handle all the static requests to userContent folder
+    # note : This is the $JENKINS_HOME dir
+    root /var/lib/jenkins/;
+    if (!-f $request_filename){
+      # this file does not exist, might be a directory or a /**view** url
+      rewrite (.*) /$1 last;
+      break;
+    }
+    sendfile on;
+  }
+
+  location / {
+      sendfile off;
+      proxy_pass         http://jenkins;
+      proxy_redirect     default;
+      proxy_http_version 1.1;
+
+      # Required for Jenkins websocket agents
+      proxy_set_header   Connection        $connection_upgrade;
+      proxy_set_header   Upgrade           $http_upgrade;
+
+      proxy_set_header   Host              $host;
+      proxy_set_header   X-Real-IP         $remote_addr;
+      proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
+      proxy_set_header   X-Forwarded-Proto $scheme;
+      proxy_max_temp_file_size 0;
+
+      #this is the maximum upload size
+      client_max_body_size       10m;
+      client_body_buffer_size    128k;
+
+      proxy_connect_timeout      90;
+      proxy_send_timeout         90;
+      proxy_read_timeout         90;
+      proxy_buffering            off;
+      proxy_request_buffering    off; # Required for HTTP CLI commands
+      proxy_set_header Connection ""; # Clear for keepalive
+  }
+
+}
+
+

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
/etc/nginx/conf.d 아래 default.conf 파일을 하나 생성하고 위와 같이 입력하고 저장한다.
nginx의 기본 설정 파일에 존재하는 include /etc/nginx/conf.d/*.conf; 설정 때문에 .conf 로 끝난다면 설정이 적용된다.
-설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

[Jenkins] Jenkins 접속

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
-EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

jenkins-start

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
+설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

+

[Jenkins] Jenkins 접속

+

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
+EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

+

jenkins-start

+

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
비밀번호를 입력하면 플러그인 설정 창이 나올텐데 install suggested plugins을 클릭하여 Jenkins가 추천하는 기본 플러그인들을 설치하면 된다.
-플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

[Jenkins] Jenkins Blue Ocean 설치

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
-IAM에서 다음과 같이 역할을 하나 새로 생성한다.

  1. 엔터티 선택

aws-iam1

  1. 권한 추가

aws-iam2

  1. 이름 지정, 검토 및 생성

aws-iam3

  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정

aws-iam4

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단

aws-s3

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

repo, user:email 권한이 있는 토큰이 필요하다.

[Jenkins] 블루 오션 시작

jenkins-blue-ocean1

블루 오션 열기로 파이프라인을 생성한다.
+플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

+

[Jenkins] Jenkins Blue Ocean 설치

+

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

+

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

+

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
+IAM에서 다음과 같이 역할을 하나 새로 생성한다.

+
    +
  1. 엔터티 선택
  2. +
+

aws-iam1

+
    +
  1. 권한 추가
  2. +
+

aws-iam2

+
    +
  1. 이름 지정, 검토 및 생성
  2. +
+

aws-iam3

+
    +
  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정
  2. +
+

aws-iam4

+

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

+

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

+
    +
  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단
  • +
+

aws-s3

+

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

+

repo, user:email 권한이 있는 토큰이 필요하다.

+

[Jenkins] 블루 오션 시작

+

jenkins-blue-ocean1

+

블루 오션 열기로 파이프라인을 생성한다.
토큰 입력 → 조직 선택 → CI/CD 설정할 Repository 선택을 하면 파이프라인 창으로 넘어간다.
-Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

jenkins-blue-ocean2

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

jenkins-blue-ocean3

[Github Repsoitory] Jenkinsfile 설정

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

pipeline {
agent any
stages {
stage('build and test') {
steps {
sh '/gradlew clean build'
}
}
stage('zip') {
steps {
sh 'mv ./build/libs/woowachat.jar .'
sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
}
}
stage('upload') {
steps {
sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
}
}
stage('deploy') {
steps {
sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
}
}
}
}

[Github] Webhooks 설정

github-hook

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

참고 자료

Install Jenkins - CentOS, Jenkins
-Nginx Reverse Proxy Configuration, Jenkins
-Amazon Corretto 17 JDK Install, AWS
-Amazon Linux 2023 packages, AWS

- - +Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

+

jenkins-blue-ocean2

+

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

+

jenkins-blue-ocean3

+

[Github Repsoitory] Jenkinsfile 설정

+

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

+
pipeline {
+  agent any
+  stages {
+    stage('build and test') {
+      steps {
+        sh '/gradlew clean build'
+      }
+    }
+    stage('zip') {
+      steps {
+        sh 'mv ./build/libs/woowachat.jar .'
+        sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
+      }
+    }
+    stage('upload') {
+      steps {
+        sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
+      }
+    }
+    stage('deploy') {
+      steps {
+        sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
+        sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
+      }
+    }
+  }
+}
+
+

[Github] Webhooks 설정

+

github-hook

+

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

+

참고 자료

+

Install Jenkins - CentOS, Jenkins
+Nginx Reverse Proxy Configuration, Jenkins
+Amazon Corretto 17 JDK Install, AWS
+Amazon Linux 2023 packages, AWS

\ No newline at end of file diff --git a/tags/event.html b/tags/event.html index 6e2178175..de33ae880 100644 --- a/tags/event.html +++ b/tags/event.html @@ -2,8 +2,8 @@ - -"event" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"event" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,40 +12,217 @@ - - - + + + -
-

"event" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 12분

이전 글

경로 이미지 생성하기 - 기술 선택
-경로 이미지 생성하기 - 구현

개요

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
+

"event" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 12분

이전 글

+

경로 이미지 생성하기 - 기술 선택
+경로 이미지 생성하기 - 구현

+

개요

+

현재 여행을 마치는 경우, 감상을 생성하는 경우 이미지 생성 요청이 이루어진다.
경로 이미지 생성의 경우 위치 정보의 개수에 정비례하여 생성 시간이 증가한다.
-따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

주기능의 응답속도 개선

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
+따라서 비동기로 이미지 생성 요청을 처리하여 사용자의 경험을 개선시킬 수 있다고 생각했다.

+

주기능의 응답속도 개선

+

여행 종료와 감상 생성이 주기능이고, 이미지 생성 기능은 부기능이다.
하지만 현재 여행 종료와 감상 생성의 응답 속도가 경로 이미지 생성 시간에 영향을 받고 있다.
-경로 이미지 생성은 비동기 처리하여도 애플리케이션 사용에 문제가 되지 않는다.
-소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

확장성 대비

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
+경로 이미지 생성은 비동기 처리하여도 애플리케이션 사용에 문제가 되지 않는다.
+소요 시간이 1초 이상 걸리는 경우가 존재하기에 이미지 생성을 비동기 처리하고 여행 종료와 감상 생성 기능의 응답 시간을 개선하는 것이 더 중요하다.

+

확장성 대비

+

현재 10분 간격으로 위치 정보를 서버에 저장하고 있다.
조금 더 짧은 간격으로 위치 정보를 그리는 경우 하나의 여행에 많은 위치 정보가 저장될 수밖에 없고 따라서 경로 이미지 생성에 걸리는 시간이 더 길어질 수 있다.
-따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

비동기 처리

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

비동기 설정

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
-해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig {
}

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. -7.7. Task Execution and Scheduling, Spring Boot Docs

@Async 적용

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

RouteImageGenerator
@Async
public void generate(
List<Double> latitudes,
List<Double> longitudes,
List<Double> pointedLatitudes,
List<Double> pointedLongitudes,
Long tripId
) {
// 이미지 생성
RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
Coordinates coordinates = Coordinates.of(latitudes, longitudes);
Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
drawImage(coordinates, routeImageDrawer, pointedCoordinates);

// 이미지 저장
String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());

// 자원 할당 해제
routeImageDrawer.dispose();

// 데이터베이스 값 변경
Trip trip = tripRepository.findById(tripId)
.orElseThrow();
trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}

비동기 처리시 문제점

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
-따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
-인터페이스를 사용한다면 다음과 같은 구조가 된다.

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
-따라서 이벤트를 사용하기로 했다.

이벤트 사용

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

이벤트 발행

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
+따라서 추후에 더 짧은 간격으로 위치 정보를 저장하는 경우를 대비하여 이미지 생성은 비동기로 처리하는 것이 합당하다.

+

비동기 처리

+

@Async를 사용하면 간단하게 메서드를 비동기로 동작하도록 만들 수 있다.

+

비동기 설정

+

사용하기 전에 설정 파일을 하나 만들어서 EnableAsync 설정을 해야한다.
+해당 설정을 적용하면 비동기적으로 실행하려는 메서드에 @Async 애너테이션을 붙여주기만 하면 비동기로 동작한다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig {
+}
+
+

스프링 부트를 사용하지 않는 경우 기본적으로 비동기 처리를 할 때 매번 새로운 스레드를 생성하기 때문에 스레드 풀 설정을 따로 해줘야 한다. 하지만 스프링 부트를 사용하는 경우 ThreadPoolTaskExecutor를 따로 설정하지 않아도 기본적으로 스프링 부트가 생성을 도와준다.

+
+

In the absence of an Executor bean in the context, Spring Boot auto-configures a ThreadPoolTaskExecutor with sensible defaults that can be automatically associated to asynchronous task execution (@EnableAsync) and Spring MVC asynchronous request processing. +7.7. Task Execution and Scheduling, Spring Boot Docs

+
+

@Async 적용

+

이미지 생성기에 Async 애너테이션을 붙여 비동기로 동작하도록 한다.

+
@Async
+public void generate(
+        List<Double> latitudes,
+        List<Double> longitudes,
+        List<Double> pointedLatitudes,
+        List<Double> pointedLongitudes,
+        Long tripId
+) {
+    // 이미지 생성
+    RouteImageDrawer routeImageDrawer = RouteImageDrawer.from(IMAGE_SIZE);
+    Coordinates coordinates = Coordinates.of(latitudes, longitudes);
+    Coordinates pointedCoordinates = Coordinates.of(pointedLatitudes, pointedLongitudes);
+    drawImage(coordinates, routeImageDrawer, pointedCoordinates);
+
+    // 이미지 저장
+    String imageName = routeImageUploader.upload(routeImageDrawer.bufferedImage());
+
+    // 자원 할당 해제
+    routeImageDrawer.dispose();
+
+    // 데이터베이스 값 변경
+    Trip trip = tripRepository.findById(tripId)
+        .orElseThrow();
+    trip.changeRouteImageUrl(imageUrl);
+    tripRepository.save(trip);
+}
+
+

비동기 처리시 문제점

+

현재 이미지 생성을 하고 저장 후, 저장 경로를 DB에 반영해야 한다.
+따라서 패키지 간 순환 참조 형태가 되며 의존성 방향이 문제가 생긴다.

+ +

이를 해결하기 위해서는 인터페이스를 사용하는 방법과 이벤트를 사용하는 방법이 있다.
+인터페이스를 사용한다면 다음과 같은 구조가 된다.

+ +

패키지 간 의존성은 해결되었지만, 이미지 경로 저장을 위해 tripId를 받아야하는 등의 논리적인 의존성은 아직 해결되지 않았다.
+따라서 이벤트를 사용하기로 했다.

+

이벤트 사용

+

스프링의 애플리케이션 이벤트를 사용하면 비즈니스 로직의 비관심사(ex. 경로 이미지 생성)을 효율적인 방법으로 처리할 수 있다.

+

이벤트 발행

+

이벤트를 사용하려면 먼저 이벤트를 발행해야 한다.
스프링에서는 ApplicationEventPublisher 인터페이스를 사용하여 이벤트를 발행할 수 있다.
-해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

TripService & TripUpdateEvent
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
...

// 이벤트 발행
applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
}

public record TripUpdateEvent(Long tripId) {
}

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
+해당 인터페이스는 내부적으로 ApplicationContext가 구현하여 이벤트를 발행한다.

+
public void updateTripById(LoginUser loginUser, Long tripId, TripUpdateRequest tripUpdateRequest) {
+    ...
+
+    // 이벤트 발행
+    applicationEventPublisher.publishEvent(new TripUpdateEvent(trip.id()));
+}
+
+public record TripUpdateEvent(Long tripId) {
+}
+
+

이벤트를 발행할 때 발행하는 이벤트명이 중요하다.
이벤트를 구독하는 도메인의 행위를 담고 있는 이벤트를 발행(ex. RouteImageGenerateEvent)한다면 논리적인 의존 관계가 남아있기에 이벤트를 적절히 사용했다고 보기 어렵다.
-발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

이벤트 구독

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
-이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

TransactionPhase 설정

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
+발행하는 이벤트명은 주기능이 어떤 행위(ex. TripUpdateEvent)를 했는지에 대한 정보가 담겨있는 이벤트명으로 발행하는 것이 중요하다.

+

이벤트 구독

+

이벤트를 구독하여 실행하는 메서드는 비동기로 처리하기 위하여 @Async 애너테이션을 적용했다.
+이벤트의 구독은 여행이 정상적으로 종료될 때 여행에 대한 정보를 가지고 경로 이미지를 생성하기 위해 @TransactionalEventListener를 사용했다.

+

TransactionPhase을 사용하여 트랜잭션 이벤트를 어떤 단계에서 수신하고 처리할지를 지정할 수 있다.

AFTER_COMMIT(기본값): 트랜잭션이 정상적으로 커밋 되는 경우 이벤트 실행
AFTER_ROLLBACK: 트랜잭션이 롤백되는 경우 이벤트 실행
AFTER_COMPLETION: 트랜잭션이 커밋 또는 롤백 되었을 경우 이벤트 실행
-BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

TripUpdateEventHandler
@Component
public class TripUpdateEventHandler {

private final RouteImageGenerator routeImageGenerator;
private final TripRepository tripRepository;

public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
this.routeImageGenerator = routeImageGenerator;
this.tripRepository = tripRepository;
}

@Async
@TransactionalEventListener(phase = AFTER_COMMIT)
public void handle(TripUpdateEvent tripUpdateEvent) {
Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());

String imageUrl = routeImageGenerator.generate(
trip.getLatitudes(),
trip.getLongitudes(),
trip.getPointedLatitudes(),
trip.getPointedLongitudes()
);

trip.changeRouteImageUrl(imageUrl);
tripRepository.save(trip);
}
}

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
-또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

테스트

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

@ContextConfiguration(classes = TestSyncConfig.class)
@SpringBootTest
public class TripUpdateEventHandlerIntegrationTest {

...

@Test
void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
// given
TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
.willReturn(여행());

// when
transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));

// then
then(routeImageGenerator)
.should(times(1))
.generate(any(), any(), any(), any());
}
}

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
-통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

결과

./time.png

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
-응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

참고 자료

7.7. Task Execution and Scheduling, Spring Boot Docs
-Spring Events, Baeldung
-회원시스템 이벤트기반 아키텍처 구축하기

- - +BEFORE_COMMIT: 트랜잭션이 커밋 되기 전 이벤트 실행

+

이미지 생성의 경우 트랜잭션에서 제외하기 위해 @Transactional 애너테이션을 사용하지 않았다.

+
@Component
+public class TripUpdateEventHandler {
+
+    private final RouteImageGenerator routeImageGenerator;
+    private final TripRepository tripRepository;
+
+    public TripUpdateEventHandler(RouteImageGenerator routeImageGenerator, TripRepository tripRepository) {
+        this.routeImageGenerator = routeImageGenerator;
+        this.tripRepository = tripRepository;
+    }
+
+    @Async
+    @TransactionalEventListener(phase = AFTER_COMMIT)
+    public void handle(TripUpdateEvent tripUpdateEvent) {
+        Trip trip = tripRepository.getTripWithPoints(tripUpdateEvent.tripId());
+
+        String imageUrl = routeImageGenerator.generate(
+                trip.getLatitudes(),
+                trip.getLongitudes(),
+                trip.getPointedLatitudes(),
+                trip.getPointedLongitudes()
+        );
+
+        trip.changeRouteImageUrl(imageUrl);
+        tripRepository.save(trip);
+    }
+}
+
+

이벤트를 사용함으로써 패키지 간 순환 참조 문제가 다음과 같이 해결되었다.
+또한 주기능과 부기능을 분리함으로써 경로 이미지 생성 기능에 대한 전체적인 결합도를 낮추었다.

+ +

테스트

+

비동기로 동작하는 메서드를 테스트하기 위해서는 아래와 같은 방법이 있다.

+ + +
@ContextConfiguration(classes = TestSyncConfig.class)
+@SpringBootTest
+public class TripUpdateEventHandlerIntegrationTest {
+
+    ...
+
+    @Test
+    void 여행수정_이벤트를_발생시키면_이미지를_생성_요청을_한다() {
+        // given
+        TripUpdateEvent tripUpdateEvent = new TripUpdateEvent(1L);
+        given(tripRepository.getTripWithPoints(tripUpdateEvent.tripId()))
+                .willReturn(여행());
+
+        // when
+        transactionTemplate.executeWithoutResult(action -> applicationEventPublisher.publishEvent(tripUpdateEvent));
+
+        // then
+        then(routeImageGenerator)
+                .should(times(1))
+                .generate(any(), any(), any(), any());
+    }
+}
+
+

처음에는 테스트에서만 동기로 설정 후 검증하려고 했다.
+통합 테스트에선 트랜잭션이 정상 종료되었을 때 비동기로 이벤트를 구독하여 이미지 생성 메서드를 호출하는지 검증이 필요했기 때문에 최종적으로 Mockito.timeout 메서드를 사용하여 비동기 메서드가 통과될 때까지 대기하는 방향으로 변경했다.

+

결과

+

./time.png

+

위 응답 시간은 위치 정보 1000개를 기준으로 테스트한 값이다.
+응답 시간에 이미지 생성 시간이 포함되지 않아서 성능이 개선된 것을 볼 수 있다.

+

참고 자료

+

7.7. Task Execution and Scheduling, Spring Boot Docs
+Spring Events, Baeldung
+회원시스템 이벤트기반 아키텍처 구축하기

\ No newline at end of file diff --git a/tags/exception.html b/tags/exception.html index 3dd25c0fe..8e97acab6 100644 --- a/tags/exception.html +++ b/tags/exception.html @@ -2,8 +2,8 @@ - -"exception" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"exception" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,22 +12,94 @@ - - - + + + -
-

"exception" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

문제 상황

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
-확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

비동기 예외 발생시 로깅 설정

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
+

"exception" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

문제 상황

+

현재 트립드로우의 경로 이미지 생성 기능은 비동기로 처리되고 있다. 로그를 확인하는 도중 @Async가 적용된 메서드에서 예외가 발생하는 경우 로그가 정상적으로 출력되지 않는 문제가 발생했다.
+확인해 보니 Spring의 @ControllerAdvice + @ExceptionHandler의 경우 동기 예외만 처리하고, 비동기 예외를 처리하지 않았기 때문에 발생한 문제였다.

+

비동기 예외 발생시 로깅 설정

+

스프링 4.1 부터 제공되는 AsyncUncaughtExceptionHandler의 경우 반환 타입이 void인 비동기 메서드를 예외 처리하기 쉽도록 도와준다.

+

따라서 AsyncUncaughtExceptionHandler 인터페이스를 구현해서 예외를 핸들링하는 클래스를 생성했다.
기존의 동기 예외 처리의 경우 예외가 발생할 때 실행 흐름을 추적하기 위해 MDC(Mapped Diagnostic Context)를 사용하고 있다.
-비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

AsyncExceptionHandler
@Slf4j
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {

private static final String LOG_FORMAT = "[%s] %s";

@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
}
}

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
-getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

AsyncConfig
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

MDC 정보 연동 문제

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

./mdc-null.png

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

MdcTaskDecorator
public class MdcTaskDecorator implements TaskDecorator {

@Override
public Runnable decorate(final Runnable runnable) {
Map<String, String> threadContext = MDC.getCopyOfContextMap();
return () -> {
MDC.setContextMap(threadContext);
runnable.run();
};
}
}

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

AsyncConfig
@RequiredArgsConstructor
@EnableAsync
@Configuration
public class AsyncConfig implements AsyncConfigurer {

private final AsyncConfigurationProperties properties;

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(properties.coreSize());
executor.setMaxPoolSize(properties.maxSize());
executor.setQueueCapacity(properties.queueCapacity());

executor.setTaskDecorator(new MdcTaskDecorator());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.initialize();
return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new AsyncExceptionHandler();
}
}

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

./mdc-not-null.png

참고 자료

spring async, baeldung
-@Async will not call by @ControllerAdvice for global exception
-Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
-TaskDecorator, Spring docs
-AsyncUncaughtExceptionHandler

- - +비동기 예외 처리도 마찬가지로 MDC의 정보를 가져와서 로그를 출력하도록 설정했다.

+
@Slf4j
+public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
+
+    private static final String LOG_FORMAT = "[%s] %s";
+
+    @Override
+    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
+        log.info(String.format(LOG_FORMAT, MDC.get(REQUEST_ID.key()), throwable.getMessage()), throwable);
+    }
+}
+
+

AsyncExceptionHandler의 경우 AsyncConfigurer를 구현한 Configuration 클래스를 사용하여 등록할 수 있다.
+getAsyncUncaughtExceptionHandler() 메서드를 오버라이딩하여 AsyncExceptionHandler를 반환하도록 설정하면 된다.

+
@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

이제 비동기 상황에서 예외가 발생하는 경우 AsyncUncaughtExceptionHandler의 구현체인 AsyncExceptionHandler가 예외를 잡아 처리한다.

+

MDC 정보 연동 문제

+

비동기 처리의 경우 별도의 스레드에서 동작하기 때문에 ThreadLocal 기반으로 동작하는 MDC의 정보를 얻어올 수 없는 문제가 발생했다.

+

./mdc-null.png

+

스프링 4.3 이상부터 제공되는 TaskDecorator를 이용하면 TaskExecutor를 커스터마이징 할 수 있다. TaskDecorator를 구현한 클래스를 하나 생성하고, Task가 실행되기 전 MDC의 정보를 복사하도록 설정한다.

+
public class MdcTaskDecorator implements TaskDecorator {
+
+    @Override
+    public Runnable decorate(final Runnable runnable) {
+        Map<String, String> threadContext = MDC.getCopyOfContextMap();
+        return () -> {
+            MDC.setContextMap(threadContext);
+            runnable.run();
+        };
+    }
+}
+
+

생성한 Decorator 클래스를 설정 파일에 등록해 준다.

+
@RequiredArgsConstructor
+@EnableAsync
+@Configuration
+public class AsyncConfig implements AsyncConfigurer {
+
+    private final AsyncConfigurationProperties properties;
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(properties.coreSize());
+        executor.setMaxPoolSize(properties.maxSize());
+        executor.setQueueCapacity(properties.queueCapacity());
+        
+        // highlight-next-line
+        executor.setTaskDecorator(new MdcTaskDecorator());
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.initialize();
+        return executor;
+    }
+
+    @Override
+    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+        return new AsyncExceptionHandler();
+    }
+}
+
+

설정 후에는 정상적으로 MDC에 들어가 있는 UUID가 출력되는 것을 볼 수 있다.

+

./mdc-not-null.png

+

참고 자료

+

spring async, baeldung
+@Async will not call by @ControllerAdvice for global exception
+Spring 의 동기, 비동기, 배치 처리시 항상 context 를 유지하고 로깅하기, 강남언니
+TaskDecorator, Spring docs
+AsyncUncaughtExceptionHandler

\ No newline at end of file diff --git a/tags/grasp.html b/tags/grasp.html index 4685aa59f..f5c796db0 100644 --- a/tags/grasp.html +++ b/tags/grasp.html @@ -2,8 +2,8 @@ - -"GRASP" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"GRASP" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,16 +12,101 @@ - - - + + + -
-

"GRASP" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 9분

GRASP(General Responsibility Assignment Software Pattern)

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

각 패턴마다 Solution과 Problem로 구성되어 있다.

정보 전문가 패턴(Information Expert)

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

필요한 정보를 가진 객체들로 책임이 분산된다.

창조자 패턴(Creator)

Q: 누가 객체 A를 생성하는가?

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A 객체를 긴밀하게 사용한다.
  • B가 A 객체의 초기값을 가지고 있다.

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

낮은 결합도 패턴(Low Coupling)

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

결합도(Coupling) -객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

  • 오브젝트 p.17

결합도를 낮춘다면 다음과 같은 이점이 있다.

  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • 재사용이 편리해진다.
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)

높은 응집도 패턴(High Cohesion)

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

응집도(Cohesion) -연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

  • 오브젝트 p.26

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • 유지보수가 쉬워진다.
  • 낮은 결합도 또한 지원한다.
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.

컨트롤러 패턴(Controller)

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

어떤 서브시스템이 존재한다고 가정할 때

  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.

다형성 패턴(Polymorphism)

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

변경 보호 패턴(Protected Variations)

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

간접 참조 패턴(Indirection)

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

순수한 가공물 패턴(Pure Fabrication)

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.

참고 자료

오브젝트 5장. 책임 할당하기, 조영호

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

GRASP, 한빛 네트워크

- - +

"GRASP" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 9분

GRASP(General Responsibility Assignment Software Pattern)

+

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

+

각 패턴마다 Solution과 Problem로 구성되어 있다.

+

정보 전문가 패턴(Information Expert)

+

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

+

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

+

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

+

필요한 정보를 가진 객체들로 책임이 분산된다.

+

창조자 패턴(Creator)

+

Q: 누가 객체 A를 생성하는가?

+

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

+
    +
  • B가 A 객체를 포함 또는 참조한다.
  • +
  • B가 A 객체를 기록한다.
  • +
  • B가 A 객체를 긴밀하게 사용한다.
  • +
  • B가 A 객체의 초기값을 가지고 있다.
  • +
+

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

+

낮은 결합도 패턴(Low Coupling)

+

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

+

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

+
+

결합도(Coupling) +객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

+
+
    +
  • 오브젝트 p.17
  • +
+
+
+

결합도를 낮춘다면 다음과 같은 이점이 있다.

+
    +
  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • +
  • 재사용이 편리해진다.
  • +
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)
  • +
+

높은 응집도 패턴(High Cohesion)

+

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

+

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

+
+

응집도(Cohesion) +연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

+
+
    +
  • 오브젝트 p.26
  • +
+
+
+

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

+
    +
  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • +
  • 유지보수가 쉬워진다.
  • +
  • 낮은 결합도 또한 지원한다.
  • +
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.
  • +
+

컨트롤러 패턴(Controller)

+

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

+

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

+

어떤 서브시스템이 존재한다고 가정할 때

+
    +
  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • +
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • +
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.
  • +
+

다형성 패턴(Polymorphism)

+

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

+

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

+

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

+

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

+

변경 보호 패턴(Protected Variations)

+

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

+

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

+

간접 참조 패턴(Indirection)

+

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

+

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

+

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

+

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

+

순수한 가공물 패턴(Pure Fabrication)

+

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

+

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

+

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

+

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

+

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

+
    +
  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • +
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.
  • +
+

참고 자료

+

오브젝트 5장. 책임 할당하기, 조영호

+

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

+

GRASP, 한빛 네트워크

\ No newline at end of file diff --git a/tags/image.html b/tags/image.html index 639afddf8..3cc08313b 100644 --- a/tags/image.html +++ b/tags/image.html @@ -2,8 +2,8 @@ - -"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,24 +12,202 @@ - - - + + + -
-

"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 12분

개요

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
-경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

구현 결과

./result.png

예시 데이터는 다음과 같다.
-서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

예시 데이터
List<Double> x = List.of(
126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
);
List<Double> y = List.of(
37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
);
List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);

IMAGE_SIZE & ROUTE_SIZE

RouteImageGenerator.java
private static final int IMAGE_SIZE = 800;
private static final int ROUTE_SIZE = 600;

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
+

"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 12분

개요

+

여행에 대한 경로를 보여주기 위해 경로 이미지를 생성하는 기능을 추가했다.
+경로 이미지에 대한 요구사항 및 기술 선택에 대한 내용은 링크에 있다.

+

구현 결과

+

./result.png

+

예시 데이터는 다음과 같다.
+서울역(점) → 신사역 → 노량진역 → 홍대입구역 → 종로3가역 → 옥수역 → 구로역(점) → 신림역 → 발산역

+
List<Double> x = List.of(
+        126.97094933811682, 127.02154822802501, 126.94218991864345, 126.92402556641424,
+        126.99265358592287, 127.01779856076462, 126.88474839801178, 126.92900751277035, 126.83930056313639
+);
+List<Double> y = List.of(
+        37.55302829553499, 37.51619698970427, 37.51294119442773, 37.5565933969331,
+        37.57034879708931, 37.54027238225762, 37.50129417536773, 37.48258811529137, 37.557607696911184
+);
+List<Double> xPoints = List.of(126.97094933811682, 126.88474839801178);
+List<Double> yPoints = List.of(37.55302829553499, 37.50129417536773);
+
+

IMAGE_SIZE & ROUTE_SIZE

+
private static final int IMAGE_SIZE = 800;
+private static final int ROUTE_SIZE = 600;
+
+

코드를 보면 IMAGE_SIZE와 ROUTE_SIZE가 있다.
IMAGE_SIZE는 말 그대로 이미지의 width와 height를 의미한다.
ROUTE_SIZE의 경우 상하좌우 100px 만큼의 간격을 위해 존재한다.
-따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

./600.png

사이즈 변경의 이유

255 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 800 사이즈로 변경했다.

주요 클래스

요약

클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성

의존관계

Coordinates(위도, 경도의 일급 컬렉션)

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
-Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는

Positions 계산 로직은 다음과 같다.
-위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

Coordinates.java
// 호출
// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);

private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
Double minValue = Collections.min(values);
return values.stream()
.map(value -> normalizeCoordinate(value, maxDifference, minValue))
.map(value -> mapToPosition(value, routeImageSize))
.toList();
}

private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
return (coordinate - minValue) / maxDifference;
}

private int mapToPosition(Double coordinate, Integer routeImageSize) {
return (int) (coordinate * routeImageSize);
}

위도로 예시든 내용이다.

  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  3. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.

Positions(실제 이미지 생성에 사용할 위치)

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • size: 크기를 반환한다.
  • xPositions: x 값들을 반환한다.
  • yPositions: y 값들을 반환한다.

중앙 정렬 로직은 다음과 같다.

Positions.java
public Positions align(int imageSize, int routeSize) {
int xOffset = calculateOffset(Position::x, imageSize);
int yOffset = calculateOffset(Position::y, imageSize);

return items.stream()
.map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
.collect(collectingAndThen(toList(), Positions::new));
}

private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
List<Integer> positions = items.stream()
.mapToInt(positionToInteger)
.boxed()
.toList();

int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
return imageSize / 2 - midValue;
}

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
-BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

./800.png

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

x 값 → 계산한 offset 그대로 더한다.
-y 값 → imageSize(800)에서 y + offset 값을 뺀다.

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
-그림을 그리기 위해 설정한 상수들이 존재한다.

RouteImageDrawer.java
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
// 이를 RGBA라고 부른다.
private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
// 배경 투명색
private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
// 경로를 위한 STROKE
private static final int LINE_STROKE_WIDTH = 7;
private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 위치 점을 위한 STROKE
private static final int POINT_STROKE_WIDTH = 20;
private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
// 안티앨리어싱 등 화질 개선을 위한 설정
private static final Map<Object, Object> renderingHints = Map.of(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
);

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

  • drawLine: 선을 그린다.
  • drawPoint: 점을 찍는다.
  • dispose: 자원 할당을 해제한다.

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

이미지 생성 Flow

1. 이미지 생성 준비

2. 선 그리기 요청

3. 위치 점 그리기 요청

4. 업로드 요청

전체 Flow

- - +따라서 실제 경로 이미지의 크기는 600 * 600 사이즈로 생성된다.

+

./600.png

+

사이즈 변경의 이유

+

255 * 255 정도의 작은 사이즈로 이미지를 생성해보려고 했는데, 이미지의 선명도가 좋지 않아 800 * 800 사이즈로 변경했다.

+

주요 클래스

+

요약

+
클래스명설명특이사항
Coordinate위도, 경도로 이루어진 위치 값좌표를 뜻하지만 여행 도메인에 포함된 Point 클래스와 구분하기 위해 longitude, latitude를 사용하지 않고 x, y 사용
CoordinatesCoordinate의 일급 컬렉션-
Position실제 이미지 생성에 사용할 위치 값Integer 타입의 x, y 사용
PositionsPositions의 일급 컬렉션-
RouteImageDrawer실제 이미지에 경로를 그려주는 클래스 BufferedImage, Graphics2D를 가지고 있음이미지 생성에 필요한 상수가 정의되어 있음
RouteImageUploaderBufferedImage를 받아 서버에 업로드 하는 클래스현재 업로드 위치가 정해지지 않아 일단 기본(프로젝트 루트) 위치에 생성
RouteImageGenerator이미지를 생성하고 업로드하는 서비스여행 종료, 감상 저장시 해당 클래스를 통해 이미지 생성 요청
BufferedImage(AWT)이미지 데이터를 처리하고 조작하는 데 사용왼쪽 상단의 좌표가 (0, 0)
Graphics2D(AWT)선 그리기, 색상 관리 등을 지원하는 클래스 실제 해당 클래스의 draw 메서드를 경로를 그림JDK 1.2 이후에 추가됨, 2D(평면) 그래픽 환경을 지원, bufferedImage.createGraphics 메서드를 통해 생성
+

의존관계

+ +

Coordinates(위도, 경도의 일급 컬렉션)

+

List<Double> 2개(위도, 경도)인 형태로 관리하는 방법이 있었지만, 위치 점을 여러개 찍는 부분에서 로직이 복잡해 질 것 같아서 Coordinate(x, y)와 일급 컬렉션인 Coordinates로 관리하기로 했다.
+Coordinates 클래스에는 다음 두 개의 인터페이스가 존재한다.

+
    +
  • calculatePositions: 경로 이미지의 크기를 받아 실제 이미지 생성시 사용될 Positions를 반환
  • +
  • indexOf: 다른 Coordinates를 받아 동일한 위치점에 해당하는 인덱스를 반환하는
  • +
+

Positions 계산 로직은 다음과 같다.
+위도, 경도 각각에 대한 부분을 이미지 생성시 필요한 값으로 변환한다.

+
// 호출
+// List<Integer> xPositions = toPositions(xValues, maxDifference, routeImageSize);
+// List<Integer> yPositions = toPositions(yValues, maxDifference, routeImageSize);
+
+private List<Integer> toPositions(List<Double> values, Double maxDifference, Integer routeImageSize) {
+    Double minValue = Collections.min(values);
+    return values.stream()
+            .map(value -> normalizeCoordinate(value, maxDifference, minValue))
+            .map(value -> mapToPosition(value, routeImageSize))
+            .toList();
+}
+
+private double normalizeCoordinate(Double coordinate, Double maxDifference, Double minValue) {
+    return (coordinate - minValue) / maxDifference;
+}
+
+private int mapToPosition(Double coordinate, Integer routeImageSize) {
+    return (int) (coordinate * routeImageSize);
+}
+
+

위도로 예시든 내용이다.

+
    +
  1. Collections.min(values) → 위도 리스트의 최소값을 구한다.
  2. +
  3. normalizeCoordinate → 각각의 위도 값에서 최소값을 빼고 0 ~ 1 사이 값으로 변환 후 위경도의 최대 차이로 나눈다.
  4. +
  5. mapToPosition → 그래프 크기를 받아 0 ~ 1 사이 값을 실제 이미지를 위한 위치값으로 변환한다.
  6. +
+

Positions(실제 이미지 생성에 사용할 위치)

+

Positions 클래스에는 다음 다섯 개의 인터페이스가 존재한다.

+
    +
  • align: 이미지 사이즈와 경로 이미지 사이즈를 받아 Position 값들을 중앙 정렬한다.
  • +
  • getPositionsByIndexes: 인덱스 리스트를 받아 입력받은 인덱스에 해당하는 값들을 반환한다.
  • +
  • size: 크기를 반환한다.
  • +
  • xPositions: x 값들을 반환한다.
  • +
  • yPositions: y 값들을 반환한다.
  • +
+

중앙 정렬 로직은 다음과 같다.

+
public Positions align(int imageSize, int routeSize) {
+    int xOffset = calculateOffset(Position::x, imageSize);
+    int yOffset = calculateOffset(Position::y, imageSize);
+
+    return items.stream()
+            .map(item -> new Position(item.x() + xOffset, imageSize - (item.y() + yOffset)))
+            .collect(collectingAndThen(toList(), Positions::new));
+}
+
+private int calculateOffset(ToIntFunction<Position> positionToInteger, int imageSize) {
+    List<Integer> positions = items.stream()
+            .mapToInt(positionToInteger)
+            .boxed()
+            .toList();
+
+    int midValue = (Collections.min(positions) + Collections.max(positions)) / 2;
+    return imageSize / 2 - midValue;
+}
+
+

상하좌우 여백을 동일하게 주기 위해서 offset 값을 구해서 x, y 값에 각각 더하는 형태로 중앙 정렬을 수행했다.
+BufferedImage를 사용할 때 왼쪽 상단의 좌표 (0, 0) 기준으로 아래로 내려갈수록 y 값이 커지고, 오른쪽으로 갈 수록 x 값이 커진다.

+

./800.png

+

따라서 최종적으로 이미지를 생성하기 위한 값을 다음과 같이 구했다.

+

x 값 → 계산한 offset 그대로 더한다.
+y 값 → imageSize(800)에서 y + offset 값을 뺀다.

+

RouteImageDrawer(실제 이미지에 경로를 그려주는 클래스)

+

BufferedImage, Graphics2D를 필드로 가지고 있는 클래스다.
+그림을 그리기 위해 설정한 상수들이 존재한다.

+
// RGB에 각각 8비트씩 할당한 값을 24비트 트루컬러라 부른다.
+// 해당 설정은 24비트 + 8비트(alpha, 투명도)를 추가한 32비트 이미지 타입이다.
+// 이를 RGBA라고 부른다.
+private static final int IMAGE_TYPE = BufferedImage.TYPE_INT_ARGB;
+// 배경 투명색
+private static final Color TRANSPARENT = new Color(0, 0, 0, 0);
+// 경로를 위한 STROKE
+private static final int LINE_STROKE_WIDTH = 7;
+private static final Stroke LINE_STROKE = new BasicStroke(LINE_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 위치 점을 위한 STROKE
+private static final int POINT_STROKE_WIDTH = 20;
+private static final Stroke POINT_STROKE = new BasicStroke(POINT_STROKE_WIDTH, CAP_ROUND, JOIN_ROUND);
+// 안티앨리어싱 등 화질 개선을 위한 설정
+private static final Map<Object, Object> renderingHints = Map.of(
+        RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON,
+        RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY,
+        RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC
+);
+
+

RouteImageDrawer 클래스에는 다음 세 개의 인터페이스가 존재한다.

+
    +
  • drawLine: 선을 그린다.
  • +
  • drawPoint: 점을 찍는다.
  • +
  • dispose: 자원 할당을 해제한다.
  • +
+

dispose의 경우 내부에서 생성된 graphics2D에 대한 자원 할당을 해제하는 메서드인 graphics2D.dispose를 호출한다.

+

이미지 생성 Flow

+

1. 이미지 생성 준비

+ +

2. 선 그리기 요청

+ +

3. 위치 점 그리기 요청

+ +

4. 업로드 요청

+ +

전체 Flow

+
\ No newline at end of file diff --git a/tags/image/page/2.html b/tags/image/page/2.html index 0615d31c8..02990529e 100644 --- a/tags/image/page/2.html +++ b/tags/image/page/2.html @@ -2,8 +2,8 @@ - -"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,34 +12,182 @@ - - - + + + -
-

"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 7분

개요

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

사용 기술

언어: Python 3.10
+

"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 7분

개요

+

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

+

사용 기술

+

언어: Python 3.10
이미지 생성: matplotlib
서비스: AWS Lambda, AWS API Gateway
-이미지 저장 및 URL: AWS S3, AWS CloudFront

플로우는 다음과 같다.

요구사항

./route.png

우측 상단의 경로 이미지를 생성하려고 한다.
-경로 이미지 생성에 대한 요구사항은 다음과 같다.

  • 위도, 경도로 이루어진 배열을 입력받는다.
  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.

이미지 출력 방식

  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
-파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

로컬에서 기능 구현

import time

import matplotlib.pyplot as plt


def draw(point):
start = time.time()
x, y = zip(*point)
pixel_x, pixel_y = convert_to_pixel_values(x, y)
draw_lines(pixel_x, pixel_y)
end = time.time()
print(end - start)

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)


def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
return scaled_coordinates


def draw_lines(x, y):
figure = plt.gcf()
figure.set_size_inches(5, 5)
plt.plot(x, y, c = 'w',linewidth=5)
plt.scatter(x[3],y[3], c = 'w', s = 125)
plt.axis('off')
plt.savefig('name.png', transparent=True, format='png')

point = [
[126.96352960597338, 37.590841000217125],
[126.96987292787792, 37.58435564234159],
[126.98128481452298, 37.58594375113966],
[126.99360339342958, 37.58248524741927],
[126.99867565340067, 37.56778118088622],
[127.001935378366117, 37.55985240444085],
[126.9831048919687, 37.548030119488665],
[126.97189273528845, 37.5119879225856],
[127.02689859997221, 37.48488593333883]
]

draw(point)

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

./routeImage.png

AWS Lambda

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
+이미지 저장 및 URL: AWS S3, AWS CloudFront

+

플로우는 다음과 같다.

+ +

요구사항

+

./route.png

+

우측 상단의 경로 이미지를 생성하려고 한다.
+경로 이미지 생성에 대한 요구사항은 다음과 같다.

+
    +
  • 위도, 경도로 이루어진 배열을 입력받는다.
  • +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.
  • +
+

이미지 출력 방식

+
    +
  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. +
  3. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장
  4. +
+

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
+파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

+

로컬에서 기능 구현

+
import time
+
+import matplotlib.pyplot as plt
+
+
+def draw(point):
+    start = time.time()
+    x, y = zip(*point)
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    draw_lines(pixel_x, pixel_y)
+    end = time.time()
+    print(end - start)
+    
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    return scaled_coordinates
+
+
+def draw_lines(x, y):
+    figure = plt.gcf()
+    figure.set_size_inches(5, 5)
+    plt.plot(x, y, c = 'w',linewidth=5)
+    plt.scatter(x[3],y[3], c = 'w', s = 125)
+    plt.axis('off')
+    plt.savefig('name.png', transparent=True, format='png')
+
+point = [
+    [126.96352960597338, 37.590841000217125],
+    [126.96987292787792, 37.58435564234159],
+    [126.98128481452298, 37.58594375113966],
+    [126.99360339342958, 37.58248524741927],
+    [126.99867565340067, 37.56778118088622],
+    [127.001935378366117, 37.55985240444085],
+    [126.9831048919687, 37.548030119488665],
+    [126.97189273528845, 37.5119879225856],
+    [127.02689859997221, 37.48488593333883]
+]
+
+draw(point)
+
+

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

+

./routeImage.png

+

AWS Lambda

+

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
따라서 서버리스로 파일을 처리했다.
-추가로 s3 접근은 boto3를 사용했다.

람다 S3 접근을 위한 IAM 생성

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

람다 배포용 코드

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.


import io
import uuid

import boto3
import matplotlib.pyplot as plt

PIXEL = 255
BUCKET_NAME = 'image-plot'
S3 = 's3'

def lambda_handler(event, context):
x = event['x']
y = event['y']
image_name = str(uuid.uuid4())

img_data = draw(x, y)
s3 = boto3.client(S3)
s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'

return {
'statusCode': 200,
'body': url
}

def draw(x, y):
pixel_x, pixel_y = convert_to_pixel_values(x, y)
img_data = draw_lines(pixel_x, pixel_y)
plt.close()
return img_data

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)

def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
return pixel_values

def draw_lines(x, y):
plt.plot(x, y, 'k-', linewidth=10)
plt.axis('off')
img_data = io.BytesIO()
plt.savefig(img_data, transparent=True, format='png')
img_data.seek(0)
return img_data

Layer 추가를 위한 zip 파일 생성

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
+추가로 s3 접근은 boto3를 사용했다.

+

람다 S3 접근을 위한 IAM 생성

+

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

+

람다 배포용 코드

+

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.

+

+import io
+import uuid
+
+import boto3
+import matplotlib.pyplot as plt
+
+PIXEL = 255
+BUCKET_NAME = 'image-plot'
+S3 = 's3'
+
+def lambda_handler(event, context):
+    x = event['x']
+    y = event['y']
+    image_name = str(uuid.uuid4())
+
+    img_data = draw(x, y)
+    s3 = boto3.client(S3)
+    s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
+    url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'
+
+    return {
+        'statusCode': 200,
+        'body': url
+    }
+
+def draw(x, y):
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    img_data = draw_lines(pixel_x, pixel_y)
+    plt.close()
+    return img_data
+
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
+    return pixel_values
+
+def draw_lines(x, y):
+    plt.plot(x, y, 'k-', linewidth=10)
+    plt.axis('off')
+    img_data = io.BytesIO()
+    plt.savefig(img_data, transparent=True, format='png')
+    img_data.seek(0)
+    return img_data
+
+
+

Layer 추가를 위한 zip 파일 생성

+

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
zip 파일을 만들어서 업로드해야한다.
이때 python의 Lambda 런타임에 대한 계층 경로는 python이다.
-따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

pillow.zip
│ python/PIL
└ python/Pillow-5.3.0.dist-info

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

sudo apt update
sudo apt install zip
sudo apt install python3-pip

mkdir python
pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로

No module named 'numpy.core._multiarray_umath' 에러

Layer 추가 후 람다 실행 시 발생한 에러였다.
+따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

+
pillow.zip
+│ python/PIL
+└ python/Pillow-5.3.0.dist-info
+
+

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

+
sudo apt update
+sudo apt install zip
+sudo apt install python3-pip
+
+mkdir python
+pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
+zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로
+
+

No module named 'numpy.core._multiarray_umath' 에러

+

Layer 추가 후 람다 실행 시 발생한 에러였다.
처음에 mac에서 zip 파일을 생성해서 업로드했는데 해당 문제가 발생했다.
이는 lambda가 돌아가는 동일한 환경에서 layer를 위한 zip 파일을 만들지 않아서 발생하는 문제다.
-간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

적정기술에 대한 생각

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
+간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

+

적정기술에 대한 생각

+

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
AWS Lambda를 사용하는 것은 인스턴스에 해당 코드를 배포하는 것보다 더 효율적인 방법일 수 있다.
하지만 현재 프로젝트에서 가용 가능한 자원, 기술의 난이도, 사용하는 팀원을 고려한다면 Lambda는 적정기술이 아닐 수 있다.
-따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

최종적으로 Java AWT를 사용하기로 결정했다.

참고 자료

AWS Lambda
-Lambda Layer
-Python Lambda 함수에 대한 .zip 파일 아카이브 작업
-No module named 'numpy.core._multiarray_umath'
-사례별로 알아본 안전한 S3 사용 가이드

- - +따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

+

최종적으로 Java AWT를 사용하기로 결정했다.

+

참고 자료

+

AWS Lambda
+Lambda Layer
+Python Lambda 함수에 대한 .zip 파일 아카이브 작업
+No module named 'numpy.core._multiarray_umath'
+사례별로 알아본 안전한 S3 사용 가이드

\ No newline at end of file diff --git a/tags/image/page/3.html b/tags/image/page/3.html index d3a487416..f497f48fb 100644 --- a/tags/image/page/3.html +++ b/tags/image/page/3.html @@ -2,8 +2,8 @@ - -"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,20 +12,61 @@ - - - + + + -
-

"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

./route.png

이미지 생성의 책임

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
-따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

고려한 기술

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

  • Python의 Matplotlib
  • AWT(Abstract Window Toolkit) [최종 선택]
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)

Python & Matplotlib

데이터 시각화 라이브러리
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

  • 코드가 간단해서 유지 보수성이 좋다.
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.

Java AWT 이외의 라이브러리

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음

Java & AWT(Abstract Window Toolkit)

그래픽과 이미지를 그리기 위한 도구
-이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • 추가적인 api 호출을 하지 않아도 된다.

기술 선택

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
-하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

유지 보수

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
-따라서 다음과 같은 방법으로 공유하기로 했다.

  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. AWT를 사용한 부분을 문서화하여 공유한다.

레벨 3를 마무리하며 내용 추가

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
+

"image" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

./route.png

+

이미지 생성의 책임

+

위 와이어 프레임에서 여행 히스토리여행에 대한 감상을 위한 경로 이미지의 경우 네이버 지도를 사용하여 해당 기능을 구현할 수 없으니 당연히 맵 API에서 제공하는 도형 그리기 API(네이버 맵 API 기준 Polyline)를 사용할 수 없다.
+따라서 이미지를 직접 생성하거나, 클라이언트에서 직접 위경도를 이용하여 그려야 한다.

+

해당 요구사항을 해결하기 위해서는 다음과 같은 기능을 가진 라이브러리가 필요하다.

+
    +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
+

현재 클라이언트의 바쁜 일정과 기능 구현에 있어 약간의 연산이 들어간다는 부분을 고려하여 백엔드에서 이미지를 생성하기로 결정을 내렸다.

+

고려한 기술

+

백엔드에서 이미지 생성을 하기 위해 다음과 같은 라이브러리 또는 기술들을 확인해 보았다.

+
    +
  • Python의 Matplotlib
  • +
  • AWT(Abstract Window Toolkit) [최종 선택]
  • +
  • 이미지 처리 라이브러리 및 Java에서 내부적으로 Matplotlib 사용할 수 있는 라이브러리 (원하는 기능 없음)
  • +
  • Java Swing, Java FX (단순한 선 그리기 + 점 찍기라 불필요)
  • +
+

Python & Matplotlib

+

데이터 시각화 라이브러리
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 0.2초

+
    +
  • 코드가 간단해서 유지 보수성이 좋다.
  • +
  • AWS Lambda 같은 서버리스 컴퓨팅 서비스나 FastAPI와 같은 웹 프레임워크로 추가적인 API를 구현해야 한다.
  • +
  • Spring Boot에서 추가적인 API 호출을 해야하고, 확장성과 비동기 처리 등 고려 해야 할 부분이 많다.
  • +
+

Java AWT 이외의 라이브러리

+

Python이 아닌 Java에서의 라이브러리도 고려를 해봤지만 요구사항에 적합하지 않거나, 적은 요구사항에 비해 무거운 라이브러리들이 많아서 제외했다.

+
라이브러리설명제외 이유
SwingAWT 이후에 나온 GUI 라이브러리, 네이티브 UI를 사용하지 않고 모든 운영체제 상에서 동일한 UI를 가지도록 함요구사항에 비해 무겁고 복잡도가 높음
JavaFXSwing 이후에 나온 GUI 라이브러리, 3차원 그래픽을 지원함요구사항에 비해 무겁고 복잡도가 높음
simple-java-plotAWT로 구현된 플로팅 라이브러리AWT 기반이긴 하지만 직접 AWT를 사용하는 것에 비해 메리트가 없음, 커스텀 설정 기능이 없음
matplotlib4jMatplotlib를 Java에서 사용할 수 있게 하는 라이브러리내부적으로 파이썬 사용하기에 무거움, 배경 투명화 기능 없음
+

Java & AWT(Abstract Window Toolkit)

+

그래픽과 이미지를 그리기 위한 도구
+이미지 생성 및 로컬에 저장까지 걸리는 시간: 1.75초

+
    +
  • 플로팅 라이브러리를 사용하는 것보다 구현의 난이도가 다소 존재한다.
  • +
  • 이미지 생성 시간이 다소 소요되기 때문에 빠른 응답 반환을 위해 비동기 처리를 고려할 수 있을 것 같다.
  • +
  • 추가적인 api 호출을 하지 않아도 된다.
  • +
+

기술 선택

+

AWT의 경우 Matplotlib에 비해 구현의 난이도가 다소 있고, 이미지 생성 시간이 더 많이 걸리는 단점이 있다.
+하지만 추가적인 api 호출을 하지 않아도 되는 부분, Python을 사용하는 경우 추가적인 웹 프레임워크의 학습 비용을 고려하여 AWT를 사용하기로 결정했다.

+

유지 보수

+

AWT라는 생소한 기술을 사용하기 때문에 유지 보수성을 위해 팀원들과 공유하는 것이 중요하다고 생각했다.
+따라서 다음과 같은 방법으로 공유하기로 했다.

+
    +
  1. 코드 리뷰와 PR을 통해 작성한 AWT 코드에 대한 설명 및 리뷰 받는다.
  2. +
  3. AWT를 사용한 부분을 문서화하여 공유한다.
  4. +
+

레벨 3를 마무리하며 내용 추가

+

기술 선택을 하기 위한 실행 시간 측정에 오류가 있었다.
AWT를 사용하는 부분에서 애플리케이션 실행 시간을 제외하면 파이썬과 비슷한 시간안에 이미지를 생성할 수 있었다.

- - \ No newline at end of file diff --git a/tags/inno-db.html b/tags/inno-db.html index 44185720b..e395ce24d 100644 --- a/tags/inno-db.html +++ b/tags/inno-db.html @@ -2,8 +2,8 @@ - -"InnoDB" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"InnoDB" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,69 @@ - - - + + + -
-

"InnoDB" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

InnoDB 스토리지 엔진의 잠금

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
-보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
-InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

낙관적 동시성 제어(OCC, Optimistic concurrency control)

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

비관적 동시성 제어(PCC, Pessimistic Concurrency Control)

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
-일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

Shared & Exclusive Locks

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

공유 잠금(S, shared lock)

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
+

"InnoDB" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

InnoDB 스토리지 엔진의 잠금

+

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
+보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

+

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
+InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

+

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

+

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
+일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

+

Shared & Exclusive Locks

+

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

+

공유 잠금(S, shared lock)

+

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
다른 트랜잭션에서 읽기가 가능하지만, 쓰기는 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

배타적 잠금(X, exclusive lock)

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
+예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

+

배타적 잠금(X, exclusive lock)

+

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
락을 건 트랜잭션만이 해당 데이터에 접근 가능하다. 다른 트랜잭션의 경우 읽기, 쓰기가 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

Intention Locks

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
+예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

+

Intention Locks

+

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
테이블에 있는 로우에 대해서 나중에 요청되는 것이 어떤 형태의 잠금인지 가리키기 위해 사용된다.
기본적으로 로우 단위 잠금을 수행하기 전에 인텐션 잠금을 먼저 획득한다.
-인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

인텐션 공유 잠금(IS, intention shared lock)

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

인텐션 배타적 잠금(IX, intention exclusive lock)

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

잠금간의 호환성

XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

Record Locks

레코드 자체만을 잠그는 락이다.
-InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

Gap Locks

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

Next-Key Locks

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
-REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

AUTO-INC Locks

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
+인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

+

인텐션 공유 잠금(IS, intention shared lock)

+

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

+

인텐션 배타적 잠금(IX, intention exclusive lock)

+

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

+

** 잠금간의 호환성 **

+
XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible
+

Record Locks

+

레코드 자체만을 잠그는 락이다.
+InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

+

Gap Locks

+

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

+

Next-Key Locks

+

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
+REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

+

AUTO-INC Locks

+

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
InnoDB 는 내부적으로 AUTO-INC 락이라고 하는 테이블 수준의 잠금을 사용한다.
-트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

잠금 예시

-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
-- Record Locks: 10에 대해 락이 걸린다.
SELECT * FROM table_name where id = 10 for update;

-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
SELECT * FROM table_name where id > 100 for update;

-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Optimistic and Pessimistic record locking, IBM
-MySQL Innodb Locks, cecil1018
-MySQL 8.0 InnoDB Locks, MySQL
-Locks Set by Different SQL Statements in InnoDB, MySQL

- - +트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

+

잠금 예시

+
-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
+-- Record Locks: 10에 대해 락이 걸린다.
+SELECT * FROM table_name where id = 10 for update;
+
+-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
+SELECT * FROM table_name where id > 100 for update;
+
+-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
+SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Optimistic and Pessimistic record locking, IBM
+MySQL Innodb Locks, cecil1018
+MySQL 8.0 InnoDB Locks, MySQL
+Locks Set by Different SQL Statements in InnoDB, MySQL

\ No newline at end of file diff --git a/tags/intelli-j.html b/tags/intelli-j.html index 8cfad9cc4..2bd00fe14 100644 --- a/tags/intelli-j.html +++ b/tags/intelli-j.html @@ -2,8 +2,8 @@ - -"IntelliJ" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"IntelliJ" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,14 +12,22 @@ - - - + + + -
-

"IntelliJ" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 1분

Import 자동 적용

Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly

auto-import

저장시 동작

Prefrences > Tools > Actions on Save

actions-on-save

Reformat Code: Code Reformmating

Optimize imports: 사용하지 않는 Import 제거

Rearrange: Code Style > Arrangement 설정 기반 코드 재정렬

메소드 추출, 변수 추출시 final 적용

Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier

final-modifier

- - +

"IntelliJ" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 1분

Import 자동 적용

+

Prefrences > Editor > General > Auto Import > Add unambiguous imports on the fly

+

auto-import

+

저장시 동작

+

Prefrences > Tools > Actions on Save

+

actions-on-save

+

Reformat Code: Code Reformmating

+

Optimize imports: 사용하지 않는 Import 제거

+

Rearrange: Code Style > Arrangement 설정 기반 코드 재정렬

+

메소드 추출, 변수 추출시 final 적용

+

Prefrences > Editor > Code Style > Java > Code Generation > Final Modifier

+

final-modifier

\ No newline at end of file diff --git a/tags/isolation.html b/tags/isolation.html index 79226b2fa..c51400020 100644 --- a/tags/isolation.html +++ b/tags/isolation.html @@ -2,8 +2,8 @@ - -"Isolation" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Isolation" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,37 +12,139 @@ - - - + + + -
-

"Isolation" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

트랜잭션(Transaction)

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
+

"Isolation" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

트랜잭션(Transaction)

+

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
트랜잭션은 작업의 완전성과 데이터의 정합성을 보장해 준다.
-논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

트랜잭션의 속성(ACID)

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
+논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

+

트랜잭션의 속성(ACID)

+

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
일관성(Consistency): 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지해야 한다.
격리성(Isolation): 각각의 트랜잭션은 독립적이라 서로에게 영향을 주지 않아야 한다.
-지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

트랜잭션 주의사항

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
-구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

왜 네트워크 작업이 있을 때 트랜잭션에서 배제해야 할까? 🤔

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
-네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)

격리 수준(Isolation level)

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
-격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

READ UNCOMMITTED

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
+지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

+

트랜잭션 주의사항

+

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
+구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

+

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
+네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

    +
  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • +
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)
  • +
+

격리 수준(Isolation level)

+

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
+격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

+

READ UNCOMMITTED

+

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
더티 리드 현상이 발생하기 때문에 정합성의 문제가 많은 격리 수준이다.
-MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

READ COMMITTED

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
+MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

+ +

READ COMMITTED

+

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
오라클 DBMS에서 기본으로 사용되는 격리 수준이다.
-REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

REPEATABLE READ

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
+REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

+ +

REPEATABLE READ

+

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준이다.
MVCC를 이용해 언두(Undo) 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
-동일한 결과를 보장하는 방법은 다음과 같다.

  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

갭 랍(Gap lock)과 넥스트 키 락(Next-key lock)

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

MVCC(Multi Version Concurrency Control)

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

SERIALIZABLE

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
+동일한 결과를 보장하는 방법은 다음과 같다.

+
    +
  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • +
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • +
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • +
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.
  • +
+

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

+ +

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

+

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

    +
  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • +
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)
  • +

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

+

SERIALIZABLE

+

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 접근할 수 없고 단순한 읽기 작업도 공유 잠금(읽기 잠금)을 획득해야만 한다.
-InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

격리 수준에 따른 부정합 문제

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX

더티 리드(Dirty read)

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
+InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

+

격리 수준에 따른 부정합 문제

+

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

+
격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX
+

더티 리드(Dirty read)

+

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
트랜잭션 격리 수준이 READ UNCOMMITTED일 때 발생한다.
-예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

반복 가능하지 않은 조회(Non-repeatable read)

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
-예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

팬텀 리드(Phantom read, Phantom row)

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
-예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Isolation Level, MySQL

- - +예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

+

반복 가능하지 않은 조회(Non-repeatable read)

+

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
+예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

+ +

팬텀 리드(Phantom read, Phantom row)

+

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
+예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

+ +

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Isolation Level, MySQL

\ No newline at end of file diff --git a/tags/java.html b/tags/java.html index 994cf54ae..4c9a74f16 100644 --- a/tags/java.html +++ b/tags/java.html @@ -2,8 +2,8 @@ - -"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG + +"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG @@ -12,29 +12,100 @@ - - - + + + -
-

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
-2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

자바 변경 사항

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
-따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

Switch Expressions(Java 14)

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

enum RESULT {
WIN, LOSE, DRAW
}

RESULT result = RESULT.WIN;

int prize = switch (result) {
case WIN -> 10_000_000;
case LOSE, DRAW -> 5_000_000;
default -> 0;
};

주요 특징은 다음과 같다.

  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • break 문이 필요 없다.
  • default 블록을 통해 기본 값을 지정할 수 있다.

Text Block(Java 15)

Java 15에는 새로운 문자열 표현방식이 추가되었다.
-긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("""
SELECT p FROM Post p
WHERE p.title LIKE %:keyword%
OR p.content LIKE %:keyword%
""")
List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
}

NPE 메시지(Java 15)

String name = null;
name.chars();

/**
# before
java.lang.NullPointerException
at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)

# after
Cannot invoke "String.chars()" because "name" is null
java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
*/

Record(Java 16)

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
+

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

+

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
+2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

+

자바 변경 사항

+

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
+따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

+

Switch Expressions(Java 14)

+

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

+
enum RESULT {
+    WIN, LOSE, DRAW
+}
+
+RESULT result = RESULT.WIN;
+
+int prize = switch (result) {
+    case WIN -> 10_000_000;
+    case LOSE, DRAW -> 5_000_000;
+	default -> 0;
+};
+
+

주요 특징은 다음과 같다.

+
    +
  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • +
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • +
  • break 문이 필요 없다.
  • +
  • default 블록을 통해 기본 값을 지정할 수 있다.
  • +
+

Text Block(Java 15)

+

Java 15에는 새로운 문자열 표현방식이 추가되었다.
+긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

+
@Repository
+public interface PostRepository extends JpaRepository<Post, Long> {
+    @Query("""
+        SELECT p FROM Post p
+        WHERE p.title LIKE %:keyword%
+        OR p.content LIKE %:keyword%
+        """)
+    List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
+}
+
+

NPE 메시지(Java 15)

+
String name = null;
+name.chars();
+
+/** 
+# before
+java.lang.NullPointerException
+	at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)
+
+# after
+Cannot invoke "String.chars()" because "name" is null
+java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
+*/
+
+

Record(Java 16)

+

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
Record를 선언하는 경우 접근자, 생성자, equals & hashcode, toString이 제공된다.
-데이터 전송 용도로 적합해 보인다.

public record PostDto(String title, String content) {
}

추가적인 변경사항

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

스프링, 스프링 부트 변경 사항

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
-따라서 필요해보이는 몇개 정도만 정리했다.

스프링 요구사항

Java 17, Jakarta EE 9 이상이어야 한다.

네임스페이스 변경

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

PathPatternParser - trailing slash 허용하지 않음

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
-6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

PathPatternParser used by default (with the ability to opt into PathMatcher).

HTTP interface client

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
-자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

스프링 부트 최소 요구사항

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
-이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

참고 자료

어느 월급쟁이개발자 의 스프링 부트 따라잡기
-자바 9-16 주요 특징 복습하기
-Java EE에서 Jakarta EE로의 전환
-Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
-What's New in Spring Framework 6.x
-Spring Boot 3.0 Release Notes
-Spring Boot 3.1 Release Notes

- - +데이터 전송 용도로 적합해 보인다.

+
public record PostDto(String title, String content) {
+}
+
+

추가적인 변경사항

+

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

+

스프링, 스프링 부트 변경 사항

+

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
+따라서 필요해보이는 몇개 정도만 정리했다.

+

스프링 요구사항

+

Java 17, Jakarta EE 9 이상이어야 한다.

+

네임스페이스 변경

+

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

+

PathPatternParser - trailing slash 허용하지 않음

+

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
+6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

+
+

PathPatternParser used by default (with the ability to opt into PathMatcher).

+
+

HTTP interface client

+

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
+자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

+

스프링 부트 최소 요구사항

+

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
+이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

+

참고 자료

+

어느 월급쟁이개발자 의 스프링 부트 따라잡기
+자바 9-16 주요 특징 복습하기
+Java EE에서 Jakarta EE로의 전환
+Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
+What's New in Spring Framework 6.x
+Spring Boot 3.0 Release Notes
+Spring Boot 3.1 Release Notes

\ No newline at end of file diff --git a/tags/java/page/2.html b/tags/java/page/2.html index c0abf5f43..8e608a727 100644 --- a/tags/java/page/2.html +++ b/tags/java/page/2.html @@ -2,8 +2,8 @@ - -"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG + +"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG @@ -12,31 +12,84 @@ - - - + + + -
-

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

클래스 파일

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
-컴파일된 클래스파일은 어떤 구조로 되어있을까?

클래스 파일의 데이터 형식

8비트 바이트의 스트림으로 구성된다.
+

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

클래스 파일

+

자바 소스코드가 실행이 되려면 자바 컴파일러(javac)를 통해 소스코드를 클래스파일로 변환해야 한다.
+컴파일된 클래스파일은 어떤 구조로 되어있을까?

+

클래스 파일의 데이터 형식

+

8비트 바이트의 스트림으로 구성된다.
16비트 및 32비트의 데이터는 각각 2개, 4개의 연속된 8비트를 읽어서 구성된다.
-멀티바이트의 경우 항상 big endian 순서로 저장된다.

u1 → unsigned 1byte
+멀티바이트의 경우 항상 big endian 순서로 저장된다.

+

u1 → unsigned 1byte
u2 → unsigned 2byte
-u4 → unsigned 4byte

클래스 파일 구조

ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}

매직넘버

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
-보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

클래스 파일 포맷 버전

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

class file format major versions

Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61

상수 풀

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
+u4 → unsigned 4byte

+

클래스 파일 구조

+
ClassFile {
+    u4             magic;
+    u2             minor_version;
+    u2             major_version;
+    u2             constant_pool_count;
+    cp_info        constant_pool[constant_pool_count-1];
+    u2             access_flags;
+    u2             this_class;
+    u2             super_class;
+    u2             interfaces_count;
+    u2             interfaces[interfaces_count];
+    u2             fields_count;
+    field_info     fields[fields_count];
+    u2             methods_count;
+    method_info    methods[methods_count];
+    u2             attributes_count;
+    attribute_info attributes[attributes_count];
+}
+
+

매직넘버

+

모든 클래스 파일은 0xCAFEBABE라는 매직넘버로 시작한다.
+보통 매직넘버는 파일 종류를 식별하는 용도로 사용된다.

+

클래스 파일 포맷 버전

+

클래스 파일 버전 값은 클래스로더의 호환성 보장을 위해 꼭 필요한 값이다.

+
    +
  • Java 17 버전으로 빌드한다면 class version 61 ex) 00 00 00 3D
  • +
+

호환되지 않는 버전의 클래스 파일을 로딩하려고 하는 경우 런타임에 UnsupportedClassVersionError 예외가 발생한다.

+

class file format major versions

+
Java SEReleasedMajorSupported majors
8March 20145245 .. 52
9September 20175345 .. 53
10March 20185445 .. 54
11September 20185545 .. 55
12March 20195645 .. 56
13September 20195745 .. 57
14March 20205845 .. 58
15September 20205945 .. 59
16March 20216045 .. 60
17September 20216145 .. 61
+

상수 풀

+

2바이트의 상수의 개수값이 먼저오고 그 뒤로 코드에 등장하는 상수값이 모여있다.
클래스명, 상수명, 상수 값, 필드명, 메서드명과 같은 값들이 존재한다.
-JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

액세스 플래그

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
-예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

Class access and property modifiers

Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.

this_class

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
-해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

super_class

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
-아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

interface, field, method

각각의 개수와, 정보에 대한 값이 들어있다.
-interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

attributes

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
-정해진 클래스 파일의 구조를 확장하는 역할을 한다.

클래스 파일 확인하면서 사용한 툴

IntelliJ plugin - BinEd
-IntelliJ plugin - jclasslib Bytecode Viewer

참고 자료

2장 JVM 이야기, 자바 최적화
-Class file in Java, File Format
-java se11 Class 파일 형식, Oracle
-java se17 Class 파일 형식, Oracle

- - +JVM은 코드 실행 시 런타임에 배치된 메모리가 아니라, 해당 상수 풀 테이블을 찾아보고 필요한 값을 참조한다.

+

액세스 플래그

+

클래스, 인터페이스와 같은 파일의 속성을 표시한다.
+예를 들어 public interface로 정의된 인터페이스의 플래그는 0x0601이다.

+
    +
  • 계산은 다음과 같이 이루어진다. ACC_PUBLIC xor ACC_INTERFACE xor ACC_ABSTRACT
  • +
+

공식문서에 들어가면 각 플래그에 대한 설명 + 플래그 설정시 동시에 설정되면 안되는 플래그와 같은 설명이 자세하게 나와있다.

+

Class access and property modifiers

+
Flag NameValueInterpretation
ACC_PUBLIC0x0001Declared public; may be accessed from outside its package.
ACC_FINAL0x0010Declared final; no subclasses allowed.
ACC_SUPER0x0020Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE0x0200Is an interface, not a class.
ACC_ABSTRACT0x0400Declared abstract; must not be instantiated.
ACC_SYNTHETIC0x1000Declared synthetic; not present in the source code.
ACC_ANNOTATION0x2000Declared as an annotation type.
ACC_ENUM0x4000Declared as an enum type.
ACC_MODULE0x8000Is a module, not a class or interface.
+

this_class

+

클래스명과 같은 이름을 표현하는 값으로, 상수 풀에서 클래스명과 일치하는 항목의 인덱스를 참조한다.
+해당 인덱스의 항목은 CONSTANT_Class_infoclass 형식의 값이어야 한다.

+

super_class

+

상수 풀에서 슈퍼 클래스의 이름과 일치하는 항목의 인덱스를 참조한다.
+아무것도 상속하지 않는 클래스의 경우 java.lang.Object의 인덱스 값이 들어있다.

+

interface, field, method

+

각각의 개수와, 정보에 대한 값이 들어있다.
+interface, field, method를 표시하는 방법이 각각 다르고, 접근자에 대한 플래그도 각각 다르다.

+

attributes

+

해당 클래스 파일에서 사용하는 추가 정보의 모음이다. 예) 소스파일명
+정해진 클래스 파일의 구조를 확장하는 역할을 한다.

+

클래스 파일 확인하면서 사용한 툴

+

IntelliJ plugin - BinEd
+IntelliJ plugin - jclasslib Bytecode Viewer

+

참고 자료

+

2장 JVM 이야기, 자바 최적화
+Class file in Java, File Format
+java se11 Class 파일 형식, Oracle
+java se17 Class 파일 형식, Oracle

\ No newline at end of file diff --git a/tags/java/page/3.html b/tags/java/page/3.html index e0058f729..64321df41 100644 --- a/tags/java/page/3.html +++ b/tags/java/page/3.html @@ -2,8 +2,8 @@ - -"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG + +"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG @@ -12,25 +12,356 @@ - - - + + + -
-

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
+

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
이 때 JDBC를 사용할 때 데이터베이스의 커넥션을 얻고, try-with-resource를 사용하는 부분이 반복되었다.
-템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

기존 코드

public class User {
private final int id;
private final String name;

public User(final int id, final String name) {
this.id = id;
this.name = name;
}

public int getId() {
return id;
}

public String getName() {
return name;
}
}

SELECT, DELETE 중복 제거

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
-변하는 부분: SQL Query, 매개변수

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
executeUpdate(query, userId);
}

private void executeUpdate(final String query, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
preparedStatement.executeUpdate();
} catch (final SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
-이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

콜백(Callback)

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
-자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
+템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

+

기존 코드

+
public class User {
+    private final int id;
+    private final String name;
+
+    public User(final int id, final String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
+
+

SELECT, DELETE 중복 제거

+

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
+변하는 부분: SQL Query, 매개변수

+

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

+
public void insert(final String name) {
+    final String query = "INSERT INTO User (name) VALUES (?)";
+    executeUpdate(query, name);
+}
+
+public void delete(final int userId) {
+    final String query = "DELETE FROM user WHERE user_id = ?";
+    executeUpdate(query, userId);
+}
+
+private void executeUpdate(final String query, final Object... parameters) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
+        for (int i = 1; i <= parameters.length; i++) {
+            preparedStatement.setObject(i, parameters[i - 1]);
+        }
+        preparedStatement.executeUpdate();
+    } catch (final SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

+

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
+이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

+

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
+자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

+

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
executeQuery로 조회한 값은 ResultSet 안에 들어가있다.
-이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

@FunctionalInterface
public interface RowMapper {
User mapRow(final ResultSet resultSet) throws SQLException;
}

조회 분리하기 - 2. 단건 조회

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
-아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

public User findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return queryForSingleResult(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
}, userId);
}

private User queryForSingleResult(
final String query,
final RowMapper rowMapper,
final Object... parameters
) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
if (resultSet.next()) {
return rowMapper.mapRow(resultSet);
}
return null;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

조회 분리하기 - 3. 다건 조회

단건 조회와 유사하다.

public List<User> findAll() {
final String query = "SELECT * FROM user";
return query(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
});
}

private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
final List<User> result = new ArrayList<>();
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
return result;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

제네릭 사용하기

위의 코드는 User를 조회할 때만 사용할 수 있다.
-아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

@FunctionalInterface
public interface RowMapper<T> {
T mapRow(final ResultSet resultSet) throws SQLException;
}

private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
+이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

+
@FunctionalInterface
+public interface RowMapper {
+    User mapRow(final ResultSet resultSet) throws SQLException;
+}
+
+

조회 분리하기 - 2. 단건 조회

+

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
+아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

+
public User findById(final int userId) {
+    final String query = "SELECT * FROM user WHERE id = ?";
+    return queryForSingleResult(query, resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    }, userId);
+}
+
+private User queryForSingleResult(
+        final String query,
+        final RowMapper rowMapper,
+        final Object... parameters
+) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
+         final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
+        if (resultSet.next()) {
+            return rowMapper.mapRow(resultSet);
+        }
+        return null;
+    } catch (SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+private ResultSet executeQuery(
+        final PreparedStatement preparedStatement,
+        final Object[] parameters) throws SQLException {
+    for (int i = 1; i <= parameters.length; i++) {
+        preparedStatement.setObject(i, parameters[i - 1]);
+    }
+    return preparedStatement.executeQuery();
+}
+
+

조회 분리하기 - 3. 다건 조회

+

단건 조회와 유사하다.

+
public List<User> findAll() {
+    final String query = "SELECT * FROM user";
+    return query(query, resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    });
+}
+
+private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
+         final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
+        final List<User> result = new ArrayList<>();
+        while (resultSet.next()) {
+            result.add(rowMapper.mapRow(resultSet));
+        }
+        return result;
+    } catch (SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+private ResultSet executeQuery(
+        final PreparedStatement preparedStatement,
+        final Object[] parameters) throws SQLException {
+    for (int i = 1; i <= parameters.length; i++) {
+        preparedStatement.setObject(i, parameters[i - 1]);
+    }
+    return preparedStatement.executeQuery();
+}
+
+

제네릭 사용하기

+

위의 코드는 User를 조회할 때만 사용할 수 있다.
+아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

+
@FunctionalInterface
+public interface RowMapper<T> {
+    T mapRow(final ResultSet resultSet) throws SQLException;
+}
+
+private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
+private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
+
+

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

+

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
또한 null을 반환하기 보단 Optional로 감싸서 반환하도록 변경한다.
-최종적으로 아래와 같은 코드가 완성된다.

public class UserDao {
private final RowMapper<User> rowMapper = resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
};
private final JdbcTemplate jdbcTemplate;

public UserDao(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
jdbcTemplate.executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
jdbcTemplate.executeUpdate(query, userId);
}

public Optional<User> findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
}

public List<User> findAll() {
final String query = "SELECT * FROM user";
return jdbcTemplate.query(query, rowMapper);
}
}
- - +최종적으로 아래와 같은 코드가 완성된다.

+
public class UserDao {
+    private final RowMapper<User> rowMapper = resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    };
+    private final JdbcTemplate jdbcTemplate;
+
+    public UserDao(final JdbcTemplate jdbcTemplate) {
+        this.jdbcTemplate = jdbcTemplate;
+    }
+
+    public void insert(final String name) {
+        final String query = "INSERT INTO User (name) VALUES (?)";
+        jdbcTemplate.executeUpdate(query, name);
+    }
+
+    public void delete(final int userId) {
+        final String query = "DELETE FROM user WHERE user_id = ?";
+        jdbcTemplate.executeUpdate(query, userId);
+    }
+
+    public Optional<User> findById(final int userId) {
+        final String query = "SELECT * FROM user WHERE id = ?";
+        return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
+    }
+
+    public List<User> findAll() {
+        final String query = "SELECT * FROM user";
+        return jdbcTemplate.query(query, rowMapper);
+    }
+}
+
\ No newline at end of file diff --git a/tags/java/page/4.html b/tags/java/page/4.html index 48e2b5d38..7efe699ef 100644 --- a/tags/java/page/4.html +++ b/tags/java/page/4.html @@ -2,8 +2,8 @@ - -"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG + +"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG @@ -12,21 +12,100 @@ - - - + + + -
-

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

테스트를 작성하다보면 매개변수에 따라 반복이 되는 테스트들이 생긴다.
-이 때 @ParameterizedTest를 사용하면 단일 테스트를 매개변수를 사용하여 여러 번 반복할 수 있다.

Argument Sources

@ParameterizedTest를 사용하려면 최소 하나 이상의 Source 애노테이션이 필요하다.
-JUnit이 제공하는 다양한 Source가 있기 때문에, 테스트에 맞춰 다양하게 사용할 수 있다.

Value Source

값을 이용하여 제공하는 형태로, 다음과 같은 타입의 값을 매개변수로 제공할 수 있다.

  • short, int, long, float, double
  • byte, char, boolean, String, Class
@ParameterizedTest
@ValueSource(ints = {1, 100, Integer.MAX_VALUE})
void valueTest(final int value) {
Assertions.assertThat(value).isPositive();
}

Null & Empty Source

null 값, 빈 값을 제공한다.
-Empty Source의 경우 다음과 같은 타입에 한해 매개변수로 제공할 수 있다.

  • String
  • java.util.List, java.util.Set, java.util.Map
  • primitive arrays — ex) int[]
  • object arrays — ex) String[]
@ParameterizedTest
@NullAndEmptySource
void nullAndEmptyTest(final String value) {
Assertions.assertThat(value).isNullOrEmpty();
}

Enum Source

EnumSource를 이용하여 Enum 또한 매개변수로 제공할 수 있다.

enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

@ParameterizedTest
@EnumSource(Day.class)
void enumTest(final Day day) {
assertThat(day).isInstanceOf(Day.class);
}

다음과 같이 mode 값을 이용하여 특징 Enum을 제외하거나, 포함시킬 수 있다. (default: Mode.Include)

@ParameterizedTest
@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)
void enumTest(final Day day) {
// MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
assertThat(day).isInstanceOf(Day.class);
}

CSV Source

csv 형식의 값을 이용하여 매개변수를 제공한다.
+

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

테스트를 작성하다보면 매개변수에 따라 반복이 되는 테스트들이 생긴다.
+이 때 @ParameterizedTest를 사용하면 단일 테스트를 매개변수를 사용하여 여러 번 반복할 수 있다.

+

Argument Sources

+

@ParameterizedTest를 사용하려면 최소 하나 이상의 Source 애노테이션이 필요하다.
+JUnit이 제공하는 다양한 Source가 있기 때문에, 테스트에 맞춰 다양하게 사용할 수 있다.

+

Value Source

+

값을 이용하여 제공하는 형태로, 다음과 같은 타입의 값을 매개변수로 제공할 수 있다.

+
    +
  • short, int, long, float, double
  • +
  • byte, char, boolean, String, Class
  • +
+
@ParameterizedTest
+@ValueSource(ints = {1, 100, Integer.MAX_VALUE})
+void valueTest(final int value) {
+    Assertions.assertThat(value).isPositive();
+}
+
+

Null & Empty Source

+

null 값, 빈 값을 제공한다.
+Empty Source의 경우 다음과 같은 타입에 한해 매개변수로 제공할 수 있다.

+
    +
  • String
  • +
  • java.util.List, java.util.Set, java.util.Map
  • +
  • primitive arrays — ex) int[]
  • +
  • object arrays — ex) String[]
  • +
+
@ParameterizedTest
+@NullAndEmptySource
+void nullAndEmptyTest(final String value) {
+    Assertions.assertThat(value).isNullOrEmpty();
+}
+
+

Enum Source

+

EnumSource를 이용하여 Enum 또한 매개변수로 제공할 수 있다.

+
enum Day {
+    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
+}
+
+@ParameterizedTest
+@EnumSource(Day.class)
+void enumTest(final Day day) {
+    assertThat(day).isInstanceOf(Day.class);
+}
+
+

다음과 같이 mode 값을 이용하여 특징 Enum을 제외하거나, 포함시킬 수 있다. (default: Mode.Include)

+
@ParameterizedTest
+@EnumSource(value = Day.class, names = {"SATURDAY", "SUNDAY"}, mode = Mode.EXCLUDE)
+void enumTest(final Day day) {
+    // MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
+    assertThat(day).isInstanceOf(Day.class);
+}
+
+

CSV Source

+

csv 형식의 값을 이용하여 매개변수를 제공한다.
구분자의 기본값은 쉼표(,)로 구분자를 변경하고 싶을 땐 delimeter 값을 따로 전달하여 사용할 수 있다. -개인적으로 2개 정도의 값을 매개변수로 전달하는 경우 CsvSource를 사용한다.

@ParameterizedTest
@CsvSource({"1,1", "2,4", "3,9", "4,16"})
void csvTest(final int number, final int result) {
assertThat(number * number).isEqualTo(result);
}

Method Source

복잡한 타입의 값을 전달할 때 사용한다.
+개인적으로 2개 정도의 값을 매개변수로 전달하는 경우 CsvSource를 사용한다.

+
@ParameterizedTest
+@CsvSource({"1,1", "2,4", "3,9", "4,16"})
+void csvTest(final int number, final int result) {
+    assertThat(number * number).isEqualTo(result);
+}
+
+

Method Source

+

복잡한 타입의 값을 전달할 때 사용한다.
메서드명을 입력하여 매개변수를 제공하는 메서드를 지정할 수 있다.
-메서드명을 따로 입력하지 않으면 테스트명과 동일한 static 메서드가 지정된다.

@ParameterizedTest
@MethodSource
void methodTest(final List<Integer> numbers, final int count) {
assertThat(numbers).hasSize(count);
}

private static Stream<Arguments> methodTest() {
return Stream.of(
Arguments.of(List.of(1), 1),
Arguments.of(List.of(1, 2), 2),
Arguments.of(List.of(1, 2, 3), 3)
);
}

ETC.

위에서 언급한 방법 이외에도 다양한 방법으로 매개변수를 제공할 수 있다.

  • CSV 파일을 이용한 CsvFileSource
  • ArgumentsProvider 구현한 클래스를 이용하는 ArgumentsSource

참고 자료

- - +메서드명을 따로 입력하지 않으면 테스트명과 동일한 static 메서드가 지정된다.

+
@ParameterizedTest
+@MethodSource
+void methodTest(final List<Integer> numbers, final int count) {
+    assertThat(numbers).hasSize(count);
+}
+
+private static Stream<Arguments> methodTest() {
+    return Stream.of(
+            Arguments.of(List.of(1), 1),
+            Arguments.of(List.of(1, 2), 2),
+            Arguments.of(List.of(1, 2, 3), 3)
+    );
+}
+
+

ETC.

+

위에서 언급한 방법 이외에도 다양한 방법으로 매개변수를 제공할 수 있다.

+
    +
  • CSV 파일을 이용한 CsvFileSource
  • +
  • ArgumentsProvider 구현한 클래스를 이용하는 ArgumentsSource
  • +
+

참고 자료

+
\ No newline at end of file diff --git a/tags/java/page/5.html b/tags/java/page/5.html index 922946c32..0e23085a1 100644 --- a/tags/java/page/5.html +++ b/tags/java/page/5.html @@ -2,8 +2,8 @@ - -"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG + +"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다. | GG @@ -12,20 +12,47 @@ - - - + + + -
-

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 2분

이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
+

"Java" 태그로 연결된 5개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 2분

이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
ISO-8601을 기반으로 작성
-설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

ISO-8601

날짜와 시간에 관련된 데이터를 다루는 국제 표준

LocalDate, LocalTime, LocalDateTime

날짜와 시간을 표현하는 클래스

Instant

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
-기계의 관점에서 시간 표현

Duration, Period

간격을 표현하는 클래스

TemporalAdjusters

복잡한 날짜 조정이 필요할 때 사용
-필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}

DateTimeFormatter

날짜와 시간 포맷 클래스
-특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

ZoneId, ZoneOffset

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
-ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

Instant instant = Instant.now();
LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

참고 자료

- - +설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

+

날짜와 시간에 관련된 데이터를 다루는 국제 표준

+

LocalDate, LocalTime, LocalDateTime

+

날짜와 시간을 표현하는 클래스

+

Instant

+

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
+기계의 관점에서 시간 표현

+

Duration, Period

+

간격을 표현하는 클래스

+

TemporalAdjusters

+

복잡한 날짜 조정이 필요할 때 사용
+필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

+
@FunctionalInterface
+public interface TemporalAdjuster {
+    Temporal adjustInto(Temporal temporal);
+}
+
+

DateTimeFormatter

+

날짜와 시간 포맷 클래스
+특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

+

ZoneId, ZoneOffset

+

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
+ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

+
Instant instant = Instant.now();
+LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+
+

참고 자료

+
\ No newline at end of file diff --git a/tags/jdbc.html b/tags/jdbc.html index 3767e197a..a4afdd120 100644 --- a/tags/jdbc.html +++ b/tags/jdbc.html @@ -2,8 +2,8 @@ - -"JDBC" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"JDBC" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,25 +12,356 @@ - - - + + + -
-

"JDBC" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
+

"JDBC" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

체스 미션에서는 데이터베이스에서 값을 가져오기 위해 DAO를 사용했다.
이 때 JDBC를 사용할 때 데이터베이스의 커넥션을 얻고, try-with-resource를 사용하는 부분이 반복되었다.
-템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

기존 코드

public class User {
private final int id;
private final String name;

public User(final int id, final String name) {
this.id = id;
this.name = name;
}

public int getId() {
return id;
}

public String getName() {
return name;
}
}

SELECT, DELETE 중복 제거

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
-변하는 부분: SQL Query, 매개변수

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
executeUpdate(query, userId);
}

private void executeUpdate(final String query, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
preparedStatement.executeUpdate();
} catch (final SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
-이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

콜백(Callback)

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
-자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
+템플릿 콜백 패턴을 이용하여 나만의 JdbcTemplate을 만들어보았다.

+

기존 코드

+
public class User {
+    private final int id;
+    private final String name;
+
+    public User(final int id, final String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
+
+

SELECT, DELETE 중복 제거

+

변하지 않는 부분: try-with-resource, preparedStatement를 사용하는 부분, executeUpdate로 실행 등등
+변하는 부분: SQL Query, 매개변수

+

다음과 같이 쿼리를 실행하는 부분을 분리하고 가변인수를 사용한다면 SELECT와 DELETE의 중복을 제거할 수 있다.

+
public void insert(final String name) {
+    final String query = "INSERT INTO User (name) VALUES (?)";
+    executeUpdate(query, name);
+}
+
+public void delete(final int userId) {
+    final String query = "DELETE FROM user WHERE user_id = ?";
+    executeUpdate(query, userId);
+}
+
+private void executeUpdate(final String query, final Object... parameters) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query)) {
+        for (int i = 1; i <= parameters.length; i++) {
+            preparedStatement.setObject(i, parameters[i - 1]);
+        }
+        preparedStatement.executeUpdate();
+    } catch (final SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+

조회 분리하기 - 1. 콜백을 위한 인터페이스 정의

+

조회는 INSERT, DELETE와 달리 값을 반환받아야 하기 때문에 다른 방법을 사용해야 한다.
+이 때 콜백이라는 것을 사용하여 중복을 제거할 수 있다.

+

프로그래밍에서 콜백은 다른 코드의 인수로 넘겨주는 실행 가능한 코드를 뜻한다.
+자바에서는 람다나 익명 클래스를 넘겨서 사용할 수 있다.

+

데이터베이스에서 값을 조회하고, 해당 값을 객체로 매핑하여 값을 반환해야 한다.
executeQuery로 조회한 값은 ResultSet 안에 들어가있다.
-이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

@FunctionalInterface
public interface RowMapper {
User mapRow(final ResultSet resultSet) throws SQLException;
}

조회 분리하기 - 2. 단건 조회

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
-아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

public User findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return queryForSingleResult(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
}, userId);
}

private User queryForSingleResult(
final String query,
final RowMapper rowMapper,
final Object... parameters
) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
if (resultSet.next()) {
return rowMapper.mapRow(resultSet);
}
return null;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

조회 분리하기 - 3. 다건 조회

단건 조회와 유사하다.

public List<User> findAll() {
final String query = "SELECT * FROM user";
return query(query, resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
});
}

private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
final Connection connection = connectionPool.getConnection();
try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
final List<User> result = new ArrayList<>();
while (resultSet.next()) {
result.add(rowMapper.mapRow(resultSet));
}
return result;
} catch (SQLException e) {
throw new IllegalArgumentException(e.getMessage());
}
}

private ResultSet executeQuery(
final PreparedStatement preparedStatement,
final Object[] parameters) throws SQLException {
for (int i = 1; i <= parameters.length; i++) {
preparedStatement.setObject(i, parameters[i - 1]);
}
return preparedStatement.executeQuery();
}

제네릭 사용하기

위의 코드는 User를 조회할 때만 사용할 수 있다.
-아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

@FunctionalInterface
public interface RowMapper<T> {
T mapRow(final ResultSet resultSet) throws SQLException;
}

private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
+이를 원하는 타입의 값으로 변환해야하니 일단 콜백을 위한 인터페이스를 만들어야 한다.

+
@FunctionalInterface
+public interface RowMapper {
+    User mapRow(final ResultSet resultSet) throws SQLException;
+}
+
+

조회 분리하기 - 2. 단건 조회

+

위에서 정의한 RowMapper를 메서드에서 어떻게 사용해야 할까?
+아래와 같이 SQL 쿼리, RowMapper, 파라미터를 분리한 메서드에 넘겨주고 쿼리 실행 후 매핑한 값을 반환하도록 한다.

+
public User findById(final int userId) {
+    final String query = "SELECT * FROM user WHERE id = ?";
+    return queryForSingleResult(query, resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    }, userId);
+}
+
+private User queryForSingleResult(
+        final String query,
+        final RowMapper rowMapper,
+        final Object... parameters
+) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
+         final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
+        if (resultSet.next()) {
+            return rowMapper.mapRow(resultSet);
+        }
+        return null;
+    } catch (SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+private ResultSet executeQuery(
+        final PreparedStatement preparedStatement,
+        final Object[] parameters) throws SQLException {
+    for (int i = 1; i <= parameters.length; i++) {
+        preparedStatement.setObject(i, parameters[i - 1]);
+    }
+    return preparedStatement.executeQuery();
+}
+
+

조회 분리하기 - 3. 다건 조회

+

단건 조회와 유사하다.

+
public List<User> findAll() {
+    final String query = "SELECT * FROM user";
+    return query(query, resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    });
+}
+
+private List<User> query(final String query, final RowMapper rowMapper, final Object... parameters) {
+    final Connection connection = connectionPool.getConnection();
+    try (final PreparedStatement preparedStatement = connection.prepareStatement(query);
+         final ResultSet resultSet = executeQuery(preparedStatement, parameters)) {
+        final List<User> result = new ArrayList<>();
+        while (resultSet.next()) {
+            result.add(rowMapper.mapRow(resultSet));
+        }
+        return result;
+    } catch (SQLException e) {
+        throw new IllegalArgumentException(e.getMessage());
+    }
+}
+
+private ResultSet executeQuery(
+        final PreparedStatement preparedStatement,
+        final Object[] parameters) throws SQLException {
+    for (int i = 1; i <= parameters.length; i++) {
+        preparedStatement.setObject(i, parameters[i - 1]);
+    }
+    return preparedStatement.executeQuery();
+}
+
+

제네릭 사용하기

+

위의 코드는 User를 조회할 때만 사용할 수 있다.
+아래와 같이 제네릭을 적용하여 다른 Dao에서도 사용 가능하도록 변경할 수 있다.

+
@FunctionalInterface
+public interface RowMapper<T> {
+    T mapRow(final ResultSet resultSet) throws SQLException;
+}
+
+private <T> List<T> query(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
+private <T> T queryForSingleResult(final String query, final RowMapper<T> rowMapper, final Object... parameters) {...}
+
+

메서드 분리한 부분 클래스로 분리하기 + Optional 사용하기

+

메서드로 분리한 부분을 JdbcTemplate이라는 클래스를 만들어 옮긴다.
또한 null을 반환하기 보단 Optional로 감싸서 반환하도록 변경한다.
-최종적으로 아래와 같은 코드가 완성된다.

public class UserDao {
private final RowMapper<User> rowMapper = resultSet -> {
final int id = resultSet.getInt("id");
final String name = resultSet.getString("name");
return new User(id, name);
};
private final JdbcTemplate jdbcTemplate;

public UserDao(final JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public void insert(final String name) {
final String query = "INSERT INTO User (name) VALUES (?)";
jdbcTemplate.executeUpdate(query, name);
}

public void delete(final int userId) {
final String query = "DELETE FROM user WHERE user_id = ?";
jdbcTemplate.executeUpdate(query, userId);
}

public Optional<User> findById(final int userId) {
final String query = "SELECT * FROM user WHERE id = ?";
return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
}

public List<User> findAll() {
final String query = "SELECT * FROM user";
return jdbcTemplate.query(query, rowMapper);
}
}
- - +최종적으로 아래와 같은 코드가 완성된다.

+
public class UserDao {
+    private final RowMapper<User> rowMapper = resultSet -> {
+        final int id = resultSet.getInt("id");
+        final String name = resultSet.getString("name");
+        return new User(id, name);
+    };
+    private final JdbcTemplate jdbcTemplate;
+
+    public UserDao(final JdbcTemplate jdbcTemplate) {
+        this.jdbcTemplate = jdbcTemplate;
+    }
+
+    public void insert(final String name) {
+        final String query = "INSERT INTO User (name) VALUES (?)";
+        jdbcTemplate.executeUpdate(query, name);
+    }
+
+    public void delete(final int userId) {
+        final String query = "DELETE FROM user WHERE user_id = ?";
+        jdbcTemplate.executeUpdate(query, userId);
+    }
+
+    public Optional<User> findById(final int userId) {
+        final String query = "SELECT * FROM user WHERE id = ?";
+        return jdbcTemplate.queryForSingleResult(query, rowMapper, userId);
+    }
+
+    public List<User> findAll() {
+        final String query = "SELECT * FROM user";
+        return jdbcTemplate.query(query, rowMapper);
+    }
+}
+
\ No newline at end of file diff --git a/tags/jenkins.html b/tags/jenkins.html index 54c2d51f8..1c8ba244a 100644 --- a/tags/jenkins.html +++ b/tags/jenkins.html @@ -2,8 +2,8 @@ - -"Jenkins" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Jenkins" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,31 +12,218 @@ - - - + + + -
-

"Jenkins" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

설정 환경

소프트웨어 이미지: Amazon Linux 2023 AMI
+

"Jenkins" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

설정 환경

+

소프트웨어 이미지: Amazon Linux 2023 AMI
아키텍쳐: ARM
인스턴스 유형: t4g.small
환경 구성이 완료된 Elastic Beanstalk
-단일 Spring Boot 프로젝트가 존재하는 Github Repository

[EC2 CLI] Swap 메모리 설정

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
-아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

# fallocate 이용하여 스왑 파일 생성
sudo fallocate -l 2G /swapfile

# 권한 설정
sudo chmod 600 /swapfile

# 파일을 Swap 포맷으로 변경 후 시스템에 등록
sudo mkswap /swapfile
sudo swapon /swapfile

# Swap 메모리 부팅시 자동으로 마운트하도록 적용
# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
sudo vim /etc/fstab

[EC2 CLI] jenkins 설치

sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
sudo yum upgrade
sudo yum install java-17-amazon-corretto-devel
sudo yum install jenkins
sudo systemctl daemon-reload

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

[EC2 CLI] Jenkins 시작

sudo systemctl enable jenkins
sudo systemctl start jenkins

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

[EC2 CLI] nginx & git 설치

sudo yum install nginx
sudo systemctl enable nginx
sudo systemctl start nginx

sudo yum install git

nginx와 코드를 불러올 때 사용할 git을 설치한다.

[EC2 CLI] nginx 리버스 프록시 설정

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

upstream jenkins {
keepalive 32; # keepalive connections
server 127.0.0.1:8080; # jenkins ip and port
}

# Required for Jenkins websocket agents
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
listen 80; # Listen on port 80 for IPv4 requests

server_name jenkins.example.com; # replace 'jenkins.example.com' with your server domain name

# this is the jenkins web root directory
# (mentioned in the output of "systemctl cat jenkins")
root /var/run/jenkins/war/;

access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;

# pass through headers from Jenkins that Nginx considers invalid
ignore_invalid_headers off;

location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
# rewrite all static files into requests to the root
# E.g /static/12345678/css/something.css will become /css/something.css
rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
}

location /userContent {
# have nginx handle all the static requests to userContent folder
# note : This is the $JENKINS_HOME dir
root /var/lib/jenkins/;
if (!-f $request_filename){
# this file does not exist, might be a directory or a /**view** url
rewrite (.*) /$1 last;
break;
}
sendfile on;
}

location / {
sendfile off;
proxy_pass http://jenkins;
proxy_redirect default;
proxy_http_version 1.1;

# Required for Jenkins websocket agents
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_max_temp_file_size 0;

#this is the maximum upload size
client_max_body_size 10m;
client_body_buffer_size 128k;

proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffering off;
proxy_request_buffering off; # Required for HTTP CLI commands
proxy_set_header Connection ""; # Clear for keepalive
}

}

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
+단일 Spring Boot 프로젝트가 존재하는 Github Repository

+

[EC2 CLI] Swap 메모리 설정

+

t4g.small이 램이 2G인데 램이 부족하다고 느껴져서 swap 메모리를 설정했다.
+아래 명령어를 따라 swap 메모리를 설정하고 free -h 명령어를 통해 잘 설정되었는지 확인할 수 있다.

+
# fallocate 이용하여 스왑 파일 생성
+sudo fallocate -l 2G /swapfile
+
+# 권한 설정
+sudo chmod 600 /swapfile
+
+# 파일을 Swap 포맷으로 변경 후 시스템에 등록
+sudo mkswap /swapfile
+sudo swapon /swapfile
+
+# Swap 메모리 부팅시 자동으로 마운트하도록 적용
+# 최하단에 다음 구문 설정 -> /swapfile swap swap defaults 0 0
+sudo vim /etc/fstab
+
+

[EC2 CLI] jenkins 설치

+
sudo wget -O /etc/yum.repos.d/jenkins.repo \
+    https://pkg.jenkins.io/redhat-stable/jenkins.repo
+sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
+sudo yum upgrade
+sudo yum install java-17-amazon-corretto-devel
+sudo yum install jenkins
+sudo systemctl daemon-reload
+
+

Jenkins 공식 홈페이지 를 참고하여 설치하는 게 좋다.

+

[EC2 CLI] Jenkins 시작

+
sudo systemctl enable jenkins
+sudo systemctl start jenkins
+
+

enable로 설정하여 부팅시 자동시작 되도록 설정한다.

+

[EC2 CLI] nginx & git 설치

+
sudo yum install nginx
+sudo systemctl enable nginx
+sudo systemctl start nginx
+
+sudo yum install git
+
+

nginx와 코드를 불러올 때 사용할 git을 설치한다.

+

[EC2 CLI] nginx 리버스 프록시 설정

+

아래 설정 파일은 공식 홈페이지에서 안내한 기본적인 설정 파일이다.

+
upstream jenkins {
+  keepalive 32; # keepalive connections
+  server 127.0.0.1:8080; # jenkins ip and port
+}
+
+# Required for Jenkins websocket agents
+map $http_upgrade $connection_upgrade {
+  default upgrade;
+  '' close;
+}
+
+server {
+  listen          80;       # Listen on port 80 for IPv4 requests
+
+  server_name     jenkins.example.com;  # replace 'jenkins.example.com' with your server domain name
+
+  # this is the jenkins web root directory
+  # (mentioned in the output of "systemctl cat jenkins")
+  root            /var/run/jenkins/war/;
+
+  access_log      /var/log/nginx/jenkins.access.log;
+  error_log       /var/log/nginx/jenkins.error.log;
+
+  # pass through headers from Jenkins that Nginx considers invalid
+  ignore_invalid_headers off;
+
+  location ~ "^/static/[0-9a-fA-F]{8}\/(.*)$" {
+    # rewrite all static files into requests to the root
+    # E.g /static/12345678/css/something.css will become /css/something.css
+    rewrite "^/static/[0-9a-fA-F]{8}\/(.*)" /$1 last;
+  }
+
+  location /userContent {
+    # have nginx handle all the static requests to userContent folder
+    # note : This is the $JENKINS_HOME dir
+    root /var/lib/jenkins/;
+    if (!-f $request_filename){
+      # this file does not exist, might be a directory or a /**view** url
+      rewrite (.*) /$1 last;
+      break;
+    }
+    sendfile on;
+  }
+
+  location / {
+      sendfile off;
+      proxy_pass         http://jenkins;
+      proxy_redirect     default;
+      proxy_http_version 1.1;
+
+      # Required for Jenkins websocket agents
+      proxy_set_header   Connection        $connection_upgrade;
+      proxy_set_header   Upgrade           $http_upgrade;
+
+      proxy_set_header   Host              $host;
+      proxy_set_header   X-Real-IP         $remote_addr;
+      proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
+      proxy_set_header   X-Forwarded-Proto $scheme;
+      proxy_max_temp_file_size 0;
+
+      #this is the maximum upload size
+      client_max_body_size       10m;
+      client_body_buffer_size    128k;
+
+      proxy_connect_timeout      90;
+      proxy_send_timeout         90;
+      proxy_read_timeout         90;
+      proxy_buffering            off;
+      proxy_request_buffering    off; # Required for HTTP CLI commands
+      proxy_set_header Connection ""; # Clear for keepalive
+  }
+
+}
+
+

Jenkins는 8080 포트로 동작하기 때문에 리버스 프록시를 설정해준다.
/etc/nginx/conf.d 아래 default.conf 파일을 하나 생성하고 위와 같이 입력하고 저장한다.
nginx의 기본 설정 파일에 존재하는 include /etc/nginx/conf.d/*.conf; 설정 때문에 .conf 로 끝난다면 설정이 적용된다.
-설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

[Jenkins] Jenkins 접속

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
-EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

jenkins-start

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
+설정 후 sudo nginx -t로 설정파일이 정상인지 확인하고, sudo systemctl restart nginx 명령어로 nginx를 재시작한다.

+

[Jenkins] Jenkins 접속

+

Jenkins를 설치한 EC2 인스턴스 인바운드 설정에 80번 포트가 열려있는지 확인한다.
+EC2의 아이피 주소를 입력하고 들어가면 비밀번호를 입력하라는 창이 나온다.

+

jenkins-start

+

초기 비밀번호를 입력해야 하는데 sudo cat /var/lib/jenkins/secrets/initialAdminPasswor 를 입력해 초기 비밀번호를 얻을 수 있다.
비밀번호를 입력하면 플러그인 설정 창이 나올텐데 install suggested plugins을 클릭하여 Jenkins가 추천하는 기본 플러그인들을 설치하면 된다.
-플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

[Jenkins] Jenkins Blue Ocean 설치

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
-IAM에서 다음과 같이 역할을 하나 새로 생성한다.

  1. 엔터티 선택

aws-iam1

  1. 권한 추가

aws-iam2

  1. 이름 지정, 검토 및 생성

aws-iam3

  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정

aws-iam4

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단

aws-s3

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

repo, user:email 권한이 있는 토큰이 필요하다.

[Jenkins] 블루 오션 시작

jenkins-blue-ocean1

블루 오션 열기로 파이프라인을 생성한다.
+플러그인을 설치하면 계정 및 주소 설정을 해야하는데 이건 편하게 설정하면 된다.

+

[Jenkins] Jenkins Blue Ocean 설치

+

Jenkins 관리 → Plugin Manager에서 Blue Ocean을 검색해 설치한다.

+

[AWS IAM & EC2] IAM으로 EC2 인스턴스 권한 설정하기

+

S3와 Elastic Beanstalk에 접근할 수 있는 권한을 부여하려면 AmazonS3FullAccess, AdministratorAccess-AWSElasticBeanstalk 두 개의 정책을 가지고 있는 역할을 생성해야 한다.
+IAM에서 다음과 같이 역할을 하나 새로 생성한다.

+
    +
  1. 엔터티 선택
  2. +
+

aws-iam1

+
    +
  1. 권한 추가
  2. +
+

aws-iam2

+
    +
  1. 이름 지정, 검토 및 생성
  2. +
+

aws-iam3

+
    +
  1. 생성한 IAM EC2 Jenkins 인스턴스를 선택하고, 작업 → 보안 → IAM 역할 수정을 눌러 Role 설정
  2. +
+

aws-iam4

+

[AWS S3] Jar 파일을 업로드 할 S3 버킷 생성

+

버킷을 생성할 때 다음 설정을 제외하고 모두 차단 활성화를 해준다.

+
    +
  • 새 ACL(액세스 제어 목록)을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단
  • +
+

aws-s3

+

[Github] Blue Ocean에서 파이프라인 생성에 필요한 Github Token 생성

+

repo, user:email 권한이 있는 토큰이 필요하다.

+

[Jenkins] 블루 오션 시작

+

jenkins-blue-ocean1

+

블루 오션 열기로 파이프라인을 생성한다.
토큰 입력 → 조직 선택 → CI/CD 설정할 Repository 선택을 하면 파이프라인 창으로 넘어간다.
-Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

jenkins-blue-ocean2

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

jenkins-blue-ocean3

[Github Repsoitory] Jenkinsfile 설정

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

pipeline {
agent any
stages {
stage('build and test') {
steps {
sh '/gradlew clean build'
}
}
stage('zip') {
steps {
sh 'mv ./build/libs/woowachat.jar .'
sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
}
}
stage('upload') {
steps {
sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
}
}
stage('deploy') {
steps {
sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
}
}
}
}

[Github] Webhooks 설정

github-hook

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

참고 자료

Install Jenkins - CentOS, Jenkins
-Nginx Reverse Proxy Configuration, Jenkins
-Amazon Corretto 17 JDK Install, AWS
-Amazon Linux 2023 packages, AWS

- - +Jenkinsfile을 직접 작성하여 설정하기 위해 간단하게 print 하나 출력하는 것으로 설정했다.

+

jenkins-blue-ocean2

+

파이프라인이 실행될 텐데 pipeline status에서 아래와 같이 초록불이 뜨면 된다.

+

jenkins-blue-ocean3

+

[Github Repsoitory] Jenkinsfile 설정

+

블루 오션 시작을 통해 설정하면 Jenkinsfile이 하나 만들어지고, 아래와 같이 원하는 파이프라인을 설정한다.

+
pipeline {
+  agent any
+  stages {
+    stage('build and test') {
+      steps {
+        sh '/gradlew clean build'
+      }
+    }
+    stage('zip') {
+      steps {
+        sh 'mv ./build/libs/woowachat.jar .'
+        sh 'zip -r woowachat.zip .platform delivery.jar Procfile'
+      }
+    }
+    stage('upload') {
+      steps {
+        sh 'aws s3 cp woowachat.zip s3://woowa-chat/woowachat.zip --region ap-northeast-2'
+      }
+    }
+    stage('deploy') {
+      steps {
+        sh 'aws elasticbeanstalk create-application-version --region ap-northeast-2 --application-name woowachat --version-label ${BUILD_TAG} --source-bundle S3Bucket="woowa-chat",S3Key="woowachat.zip"'
+        sh 'aws elasticbeanstalk update-environment --region ap-northeast-2 --environment-name Woowachat-env --version-label ${BUILD_TAG}'
+      }
+    }
+  }
+}
+
+

[Github] Webhooks 설정

+

github-hook

+

push 이벤트가 발생할 때 http://Jenkins주소/github-webhook/ 로 post request를 하도록 웹훅을 설정한다.

+

참고 자료

+

Install Jenkins - CentOS, Jenkins
+Nginx Reverse Proxy Configuration, Jenkins
+Amazon Corretto 17 JDK Install, AWS
+Amazon Linux 2023 packages, AWS

\ No newline at end of file diff --git a/tags/kotlin.html b/tags/kotlin.html index 1b50b1041..70aed4114 100644 --- a/tags/kotlin.html +++ b/tags/kotlin.html @@ -2,8 +2,8 @@ - -"Kotlin" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Kotlin" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,25 +12,76 @@ - - - + + + -
-

"Kotlin" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

nullable 타입

코틀린은 NullPointerException 예외를 최대한 발생시키지 않기 위해 타입 시스템이 설계되어 있다.
-이는 실행 시점이 아닌 컴파일 시 미리 오류가 발생할 가능성이 있는 부분을 미리 감지하여 NPE 발생의 가능성을 줄여준다.

코틀린의 경우 nullable 타입을 다음과 같이 표현한다.

val number: Int?

타입 뒤에 ?를 붙여 해당 값이 null이 될 수 있다는 것을 의미한다.
-만약 ?를 붙이지 않을 때 null을 받는 경우 컴파일 시 오류가 발생한다.

?. Safe Calls 연산자

자바에서 NPE를 발생시키지 않기 위해 null을 처리하는 가장 간단한 방법으로는 분기를 사용하는 방법이 있다.

코틀린은 안전한 호출 연산자인 ?. 연산자를 지원한다.
+

"Kotlin" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

nullable 타입

+

코틀린은 NullPointerException 예외를 최대한 발생시키지 않기 위해 타입 시스템이 설계되어 있다.
+이는 실행 시점이 아닌 컴파일 시 미리 오류가 발생할 가능성이 있는 부분을 미리 감지하여 NPE 발생의 가능성을 줄여준다.

+

코틀린의 경우 nullable 타입을 다음과 같이 표현한다.

+
val number: Int?
+
+

타입 뒤에 ?를 붙여 해당 값이 null이 될 수 있다는 것을 의미한다.
+만약 ?를 붙이지 않을 때 null을 받는 경우 컴파일 시 오류가 발생한다.

+

?. Safe Calls 연산자

+

자바에서 NPE를 발생시키지 않기 위해 null을 처리하는 가장 간단한 방법으로는 분기를 사용하는 방법이 있다.

+

코틀린은 안전한 호출 연산자인 ?. 연산자를 지원한다.
따라서 참조 값이 null이 아닐 경우에만 메서드 호출을 할 수 있다.
-참조 값이 null인 경우 메서드 호출이 무시되고, null을 반환한다.

public String repeat(String word) {
if (word == null) {
return null;
}
return word.repeat(2);
}

?: 엘비스 연산자

참조하려는 값이 null일 경우 기본 값을 반환하고 싶을 때는 어떻게 해야 할까?
-코틀린은 null이 아닌 경우 기본 값을 지정할 때 사용할 수 있는 엘비스 연산자를 지원한다.

public String stringSafe(String word) {
if (word == null) {
return "";
}
return word;
}

코틀린에서는 throw도 식이기 때문에 엘비스 연산자를 이용하여 예외를 던질 수 있다.
-예를 들어 사용자 정보가 있는 저장소에 찾는 사용자가 없는 경우 아래와 같이 사용할 수 있다.

userRepository.findByName(name) ?: throw IllegalArgumentException()

!! 널 아님 단언 연산자

!! 연산자를 이용한다면 강제로 어떤 값이든 non-nullable 타입으로 변경할 수 있다.
+참조 값이 null인 경우 메서드 호출이 무시되고, null을 반환한다.

+
public String repeat(String word) {
+    if (word == null) {
+        return null;
+    }
+    return word.repeat(2);
+}
+
+

?: 엘비스 연산자

+

참조하려는 값이 null일 경우 기본 값을 반환하고 싶을 때는 어떻게 해야 할까?
+코틀린은 null이 아닌 경우 기본 값을 지정할 때 사용할 수 있는 엘비스 연산자를 지원한다.

+
public String stringSafe(String word) {
+    if (word == null) {
+        return "";
+    }
+    return word;
+}
+
+

코틀린에서는 throw도 식이기 때문에 엘비스 연산자를 이용하여 예외를 던질 수 있다.
+예를 들어 사용자 정보가 있는 저장소에 찾는 사용자가 없는 경우 아래와 같이 사용할 수 있다.

+
userRepository.findByName(name) ?: throw IllegalArgumentException()
+
+

!! 널 아님 단언 연산자

+

!! 연산자를 이용한다면 강제로 어떤 값이든 non-nullable 타입으로 변경할 수 있다.
하지만 null인 값에 사용한다면 NPE가 발생하게 된다.
일반적인 경우에는 !! 연산자를 사용하는 것은 위험하다.
-사용하기 쉽지만, 리스크가 크고 혹시나 해당 값이 추후에는 null이 될 수 있기 때문에 지양해야 된다고 생각한다.

val length: Int = word!!.length

as? 안전한 캐스팅

타입 변환을 할 때 지정한 타입으로 변경할 수 없다면 ClassCastException이 발생한다.
+사용하기 쉽지만, 리스크가 크고 혹시나 해당 값이 추후에는 null이 될 수 있기 때문에 지양해야 된다고 생각한다.

+
val length: Int = word!!.length
+
+

as? 안전한 캐스팅

+

타입 변환을 할 때 지정한 타입으로 변경할 수 없다면 ClassCastException이 발생한다.
코틀린에서는 as 뒤에 ?를 붙여 안전하게 타입 변환을 할 수 있다.
-따라서 미리 변환 가능한 타입인지 확인하지 않고, 안전하게 타입을 변환 할 수 있다.

타입 변환이 불가능 할 경우 예외를 발생시키지 않고 null을 반환한다.

val value: Int? = something as? Int

List에서의 null 처리

List에는 null이 아닌 값만 반환하는 filterNotNull 유틸리티 메서드를 제공한다.

val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")
val foods = foodsWithNull.filterNotNull()

참고 자료

- - +따라서 미리 변환 가능한 타입인지 확인하지 않고, 안전하게 타입을 변환 할 수 있다.

+

타입 변환이 불가능 할 경우 예외를 발생시키지 않고 null을 반환한다.

+
val value: Int? = something as? Int
+
+

List에서의 null 처리

+

List에는 null이 아닌 값만 반환하는 filterNotNull 유틸리티 메서드를 제공한다.

+
val foodsWithNull: List<String?> = listOf("Pizza", "Cheese", null, "Potato")
+val foods = foodsWithNull.filterNotNull()
+
+

참고 자료

+
\ No newline at end of file diff --git a/tags/lock.html b/tags/lock.html index 8aee678f7..f894b20ea 100644 --- a/tags/lock.html +++ b/tags/lock.html @@ -2,8 +2,8 @@ - -"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG + +"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,69 @@ - - - + + + -
-

"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

InnoDB 스토리지 엔진의 잠금

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
-보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
-InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

낙관적 동시성 제어(OCC, Optimistic concurrency control)

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

비관적 동시성 제어(PCC, Pessimistic Concurrency Control)

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
-일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

Shared & Exclusive Locks

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

공유 잠금(S, shared lock)

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
+

"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

InnoDB 스토리지 엔진의 잠금

+

MySQL에서 제공하는 잠금과 별개로 스토리지 엔진 내부에서 로우 단위의 잠금을 지원한다.
+보통 명시적으로 잠금을 사용하는 경우는 드물고, 격리 수준에 따라 묵시적으로 잠금이 사용된다.

+

동시성 제어 방식에는 낙관적인 방식과 비관적인 방식이 있다.
+InnoDB는 기본적으로 MVCC(다중 버전 동시성 제어)를 통해 낙관적인 방식을 사용하고 락을 통해 특정 상황에서 비관적인 방식을 사용한다.

+

트랜잭션이 서로 충돌하지 않는다고 가정하는 방식

+

트랜잭션이 충돌하는 가정하에 잠금을 거는 방식
+일반적으로 Shared Lock, Exclusive Lock을 통해 이를 구현한다.

+

Shared & Exclusive Locks

+

InnoDB는 로우 단위의 잠금을 수행할 때 공유 잠금과 배타적 잠금을 사용한다.

+

공유 잠금(S, shared lock)

+

데이터 조회를 위한 락, 읽기 잠금(read lock)으로도 불린다.
다른 트랜잭션에서 읽기가 가능하지만, 쓰기는 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

배타적 잠금(X, exclusive lock)

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
+예) SELECT * FROM table_name WHERE id = 1 LOCK IN SHARE MODE;

+

배타적 잠금(X, exclusive lock)

+

데이터 변경을 위한 락, 쓰기 잠금(write lock)으로도 불린다.
락을 건 트랜잭션만이 해당 데이터에 접근 가능하다. 다른 트랜잭션의 경우 읽기, 쓰기가 불가능하다.
-예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

Intention Locks

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
+예) SELECT * FROM table_name WHERE id = 1 FOR UPDATE;

+

Intention Locks

+

InnoDB는 로우 단위 잠금과 테이블 잠금의 공존을 위해 인텍션 잠금을 지원한다.
테이블에 있는 로우에 대해서 나중에 요청되는 것이 어떤 형태의 잠금인지 가리키기 위해 사용된다.
기본적으로 로우 단위 잠금을 수행하기 전에 인텐션 잠금을 먼저 획득한다.
-인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

인텐션 공유 잠금(IS, intention shared lock)

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

인텐션 배타적 잠금(IX, intention exclusive lock)

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

잠금간의 호환성

XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible

Record Locks

레코드 자체만을 잠그는 락이다.
-InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

Gap Locks

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

Next-Key Locks

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
-REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

AUTO-INC Locks

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
+인텐션 락은 기본적으로 충돌을 방지하고 데드락을 방지하는 역할을 한다.

+

인텐션 공유 잠금(IS, intention shared lock)

+

트랜잭션이 테이블의 개별 로우에 대한 공유 잠금을 수행하는 것을 의미한다.

+

인텐션 배타적 잠금(IX, intention exclusive lock)

+

트랜잭션이 테이블의 개별 로우에 대한 배타적 잠금을 수행하는 것을 의미한다.

+

** 잠금간의 호환성 **

+
XIXSIS
XConflictConflictConflictConflict
IXConflictCompatibleConflictCompatible
SConflictConflictCompatibleCompatible
ISConflictCompatibleCompatibleCompatible
+

Record Locks

+

레코드 자체만을 잠그는 락이다.
+InnoDB 스토리지 엔진은 레코드 자체가 아니라 인덱스의 레코드를 잠근다.

+

Gap Locks

+

레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+레코드와 레코드 사이의 간격에 새로운 레코드가 생성되는 것을 제어하고, 넥스트 키 락의 일부로 사용된다.

+

Next-Key Locks

+

레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.
+REPEATABLE READ 격리 수준에서 팬텀 리드를 방지하기 위한 잠금이다.

+

AUTO-INC Locks

+

AUTO_INCREMENT 칼림이 사용된 테이블에 동시에 여러 레코드가 INSERT되는 경우, 각 레코드는 중복되지 않고 저장된 순서대로 증가하는 일련번호 값을 가져야 한다.
InnoDB 는 내부적으로 AUTO-INC 락이라고 하는 테이블 수준의 잠금을 사용한다.
-트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

잠금 예시

-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
-- Record Locks: 10에 대해 락이 걸린다.
SELECT * FROM table_name where id = 10 for update;

-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
SELECT * FROM table_name where id > 100 for update;

-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Optimistic and Pessimistic record locking, IBM
-MySQL Innodb Locks, cecil1018
-MySQL 8.0 InnoDB Locks, MySQL
-Locks Set by Different SQL Statements in InnoDB, MySQL

- - +트랜잭션과 관계 없이 INSERTREPLACE 문장에서 AUTO_INCREMENT 값을 가져오는 순간만 락이 걸렸다가 해제된다.

+

잠금 예시

+
-- 레코드는 id 기준 10, 20, 30, 40, 50이 있다고 가정
+-- Record Locks: 10에 대해 락이 걸린다.
+SELECT * FROM table_name where id = 10 for update;
+
+-- Gap Locks: 51부터 PositiveInfinity까지 락이 걸린다.
+SELECT * FROM table_name where id > 100 for update;
+
+-- Next-Key Locks: 21부터 30, 31부터 40에 락이 걸린다.
+SELECT * FROM table_name where id BETWEEN 25 AND 35 for update;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Optimistic and Pessimistic record locking, IBM
+MySQL Innodb Locks, cecil1018
+MySQL 8.0 InnoDB Locks, MySQL
+Locks Set by Different SQL Statements in InnoDB, MySQL

\ No newline at end of file diff --git a/tags/lock/page/2.html b/tags/lock/page/2.html index 62cfec901..aed131f01 100644 --- a/tags/lock/page/2.html +++ b/tags/lock/page/2.html @@ -2,8 +2,8 @@ - -"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG + +"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG @@ -12,27 +12,75 @@ - - - + + + -
-

"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

MySQL 엔진의 잠금

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
-MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

글로벌 락(Global lock)

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

  • 영향을 미치는 범위는 해당 서버 전체이다.
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
+

"Lock" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

MySQL 엔진의 잠금

+

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
+MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

+

글로벌 락(Global lock)

+

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

+
    +
  • 영향을 미치는 범위는 해당 서버 전체이다.
  • +
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.
  • +
+

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 일관된 백업을 받아야할 때 사용한다.
-InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

-- GLOBAL LOCK
FLUSH TABLES WITH READ LOCK;
-- UNLOCK
UNLOCK TABLES;

-- BACKUP LOCK
LOCK INSTANCE FOR BACKUP;
-- UNLOCK
UNLOCK INSTANCE;
MyISAM

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
-트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

테이블 락(Table lock)

개별 테이블 단위로 설정되는 잠금이다.
+InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

+
-- GLOBAL LOCK
+FLUSH TABLES WITH READ LOCK;
+-- UNLOCK
+UNLOCK TABLES;
+
+-- BACKUP LOCK
+LOCK INSTANCE FOR BACKUP;
+-- UNLOCK
+UNLOCK INSTANCE;
+
+

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
+트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

+

테이블 락(Table lock)

+

개별 테이블 단위로 설정되는 잠금이다.
명시적 또는 묵시적으로 특정 테이블의 락을 획득할 수 있다.
묵시적 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.
-InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

-- TABLE LOCK
LOCK TABLES table_name [ READ | WRITE ]

-- UNLOCK
UNLOCK TABLES;

네임드 락(Named lock)

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
-여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
SELECT GET_LOCK('aGVyYg==', 1);

-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
SELECT IS_FREE_LOCK('aGVyYg==');

-- 문자열에 대한 잠금을 해제한다.
SELECT RELEASE_LOCK('aGVyYg==');

-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.

-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
SELECT RELEASE_ALL_LOCKS();

메타데이터 락(Metadata lock)

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
+InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

+
-- TABLE LOCK
+LOCK TABLES table_name [ READ | WRITE ]
+
+-- UNLOCK
+UNLOCK TABLES;
+
+

네임드 락(Named lock)

+

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
+여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

+
-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
+SELECT GET_LOCK('aGVyYg==', 1);
+
+-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
+SELECT IS_FREE_LOCK('aGVyYg==');
+
+-- 문자열에 대한 잠금을 해제한다.
+SELECT RELEASE_LOCK('aGVyYg==');
+
+-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.
+
+-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
+SELECT RELEASE_ALL_LOCKS();
+
+

메타데이터 락(Metadata lock)

+

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
-보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
RENAME TABLE rank TO rank_backup, rank_new TO rank;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-MySQL의 User Level Lock를 활용한다면?, gywndi
-Locking Functions, MySQL 5.7 Reference
-Locking Functions, MySQL 8.0 Reference

- - +보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

+
-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
+-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
+RENAME TABLE rank TO rank_backup, rank_new TO rank;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+MySQL의 User Level Lock를 활용한다면?, gywndi
+Locking Functions, MySQL 5.7 Reference
+Locking Functions, MySQL 8.0 Reference

\ No newline at end of file diff --git a/tags/log.html b/tags/log.html index 1943f8ffb..1e9b4b768 100644 --- a/tags/log.html +++ b/tags/log.html @@ -2,8 +2,8 @@ - -"log" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"log" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,92 @@ - - - + + + -
-

"log" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

CloudWatch

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
+

"log" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

CloudWatch

+

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
지표를 감시하여 알림을 보내는 기능도 제공한다.
프리티어를 사용하지 않는 경우 대시보드당 3$/M 의 비용이 청구되고, 지표나 로그의 양에 따라 비용이 추가적으로 청구된다.
-요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

CloudWatch Metrics

기본적으로 5분마다 지표에 대한 정보가 수집된다.
+요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

+

CloudWatch Metrics

+

기본적으로 5분마다 지표에 대한 정보가 수집된다.
세부 모니터링(Detailed Monitoring)을 활성화하면 1분마다 지표를 수집한다.
-대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

./cloudwatch1.png

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

CloudWatch Agent 설치

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

IAM 역할 설정

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
-IAM → 역할에서 역할 생성을 클릭한다.

./cloudwatch2.png

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

./cloudwatch3.png

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
-작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

./cloudwatch4.png

설치

환경은 다음과 같다.

OS: ubuntu 22.04
-인스턴스 유형: t4g.small (ARM64)

아래 명령어를 입력하여 설치한다.

wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i -E ./amazon-cloudwatch-agent.deb

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

Wizard

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
+대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

+

./cloudwatch1.png

+

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

+

CloudWatch Agent 설치

+

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

+

IAM 역할 설정

+

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
+IAM → 역할에서 역할 생성을 클릭한다.

+

./cloudwatch2.png

+

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

+

./cloudwatch3.png

+

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
+작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

+

./cloudwatch4.png

+

설치

+

환경은 다음과 같다.

+

OS: ubuntu 22.04
+인스턴스 유형: t4g.small (ARM64)

+

아래 명령어를 입력하여 설치한다.

+
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
+sudo dpkg -i -E ./amazon-cloudwatch-agent.deb
+
+

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

+

Wizard

+

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
로그를 수집하도록 설정하는 경우 Wizard 실행 명령어 입력 전 log 파일의 절대 경로를 복사해두는 것이 좋다.
-아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
-로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

./cloudwatch5.png

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

Do you want to store the config in the SSM parameter store?
1. yes
2. no

추가적으로 설정하지 않는 경우 2번을 선택한다.
-Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
-설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

설정 파일 적용

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
-file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

types.db: no such file or directory 에러

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory

types.db 파일 생성

sudo mkdir /usr/share/collectd
sudo touch /usr/share/collectd/types.db

지표 확인

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

./cloudwatch6.png

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

{
"metrics": {
"namespace": "2023-hello-world",
......
},
}

로그

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

./cloudwatch7.png

참고 자료

CloudWatch란 무엇입니까?
-Amazon CloudWatch 요금
-Linux 인스턴스 지표
-서버에 CloudWatch 에이전트 설치 및 실행
-CloudWatch Agent를 Parameter Store에서 관리해 보기
-CloudWatch에이전트 구성 파일

- - +아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
+
+

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
+로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

+

./cloudwatch5.png

+

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

+
Do you want to store the config in the SSM parameter store?
+1. yes
+2. no
+
+

추가적으로 설정하지 않는 경우 2번을 선택한다.
+Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
+설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

+

설정 파일 적용

+

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
+file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
+
+

types.db: no such file or directory 에러

+

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

+
Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory
+
+

types.db 파일 생성

+
sudo mkdir /usr/share/collectd
+sudo touch /usr/share/collectd/types.db
+
+

지표 확인

+

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

+

./cloudwatch6.png

+

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

+
{
+  "metrics": {
+    "namespace": "2023-hello-world",
+    ......
+   },
+} 
+
+

로그

+

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

+

./cloudwatch7.png

+

참고 자료

+

CloudWatch란 무엇입니까?
+Amazon CloudWatch 요금
+Linux 인스턴스 지표
+서버에 CloudWatch 에이전트 설치 및 실행
+CloudWatch Agent를 Parameter Store에서 관리해 보기
+CloudWatch에이전트 구성 파일

\ No newline at end of file diff --git a/tags/mock.html b/tags/mock.html index 973ea952f..1e9480d22 100644 --- a/tags/mock.html +++ b/tags/mock.html @@ -2,8 +2,8 @@ - -"Mock" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Mock" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,31 +12,51 @@ - - - + + + -
-

"Mock" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

테스트 대역이란?

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
-Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
-외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

테스트 대역의 타입 계층 구조

더미(Dummy)

가장 단순하고, 원시적인 유형의 테스트 대역이다.
-기본적으로 아무 일도 하지 않는 구현체로 인스턴스화가 필요한 경우 사용한다.
-만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

스텁(Stub)

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
-이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

스파이(Spy)

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
-예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

목, 모의 객체(Mock)

목은 더미, 스텁, 스파이를 포함한다.
+

"Mock" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

테스트 대역이란?

+

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
+Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

+

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
+외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

+

테스트 대역의 타입 계층 구조

+ +

더미(Dummy)

+

가장 단순하고, 원시적인 유형의 테스트 대역이다.
+기본적으로 아무 일도 하지 않는 구현체로 인스턴스화가 필요한 경우 사용한다.
+만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

+

스텁(Stub)

+

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
+이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

+

스파이(Spy)

+

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
+예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

+

목, 모의 객체(Mock)

+

목은 더미, 스텁, 스파이를 포함한다.
호출 시 사전에 정의된 결과를 반환하고, 예상치 못한 호출이 있을 경우 예외를 던질 수 있다.
-또한 호출에 대한 검증을 할 수 있다.

가짜(Fake)

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
-예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

DOC(depended-on component)

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
-테스트 더블은 DOC와 동일한 API를 제공해야 한다.

상호작용에 따른 목과 스텁 구분

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
-목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
SUT(system under test)

테스트 대상 시스템
-테스트를 하려는 대상

참고 자료

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
+또한 호출에 대한 검증을 할 수 있다.

+

가짜(Fake)

+

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
+예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

+

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
+테스트 더블은 DOC와 동일한 API를 제공해야 한다.

+

상호작용에 따른 목과 스텁 구분

+

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
+목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

+
TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
+

테스트 대상 시스템
+테스트를 하려는 대상

+

참고 자료

+

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
단위 테스트 - 5장 목과 테스트 취약성, 블라디미르 코리코프
테스트 주도 개발 시작하기 - 7장 대역, 최범균
-테스트 더블, Martin Fowler
-테스트 관련 용어 정리, Johngrib
-Test Double, Gerard Meszaros

- - +테스트 더블, Martin Fowler
+테스트 관련 용어 정리, Johngrib
+Test Double, Gerard Meszaros

\ No newline at end of file diff --git a/tags/mockito.html b/tags/mockito.html index 06bf2a9b9..83dfb5128 100644 --- a/tags/mockito.html +++ b/tags/mockito.html @@ -2,8 +2,8 @@ - -"Mockito" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Mockito" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,22 +12,51 @@ - - - + + + -
-

"Mockito" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 3분

개요

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
-하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
+

"Mockito" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 3분

개요

+

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
+하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

+

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

+

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
해당 static 메서드를 호출하는 부분을 따로 RouteImageUploader 클래스로 최대한 분리했다.
-이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

public void upload(BufferedImage bufferedImage) {
File file = new File(파일경로);
try {
ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
} catch (IOException e) {
throw new DrawException(IMAGE_SAVE_FAIL);
}
}

Mocking static methods

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
-mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

// given
BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
RouteImageUploader routeImageUploader = new RouteImageUploader();

// expect
try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
routeImageUploader.upload(bufferedImage);
imageIO.verify(
() -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
times(1)
);
}

마치며

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
+이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

+
public void upload(BufferedImage bufferedImage) {
+    File file = new File(파일경로);
+    try {
+        ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
+    } catch (IOException e) {
+        throw new DrawException(IMAGE_SAVE_FAIL);
+    }
+}
+
+

Mocking static methods

+

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
+mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

+

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

+
// given
+BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
+RouteImageUploader routeImageUploader = new RouteImageUploader();
+
+// expect
+try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
+    routeImageUploader.upload(bufferedImage);
+    imageIO.verify(
+            () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
+            times(1)
+    );
+}
+
+

마치며

+

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
하지만 추상화를 하면 할 수록 코드의 복잡도는 증가한다.
-항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

참고 자료

Mocking static methods
-Mockito mock static methods
-Enable mocking static methods in Mockito

- - +항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

+

참고 자료

+

Mocking static methods
+Mockito mock static methods
+Enable mocking static methods in Mockito

\ No newline at end of file diff --git a/tags/monitoring.html b/tags/monitoring.html index 2511c572e..26bdac8b1 100644 --- a/tags/monitoring.html +++ b/tags/monitoring.html @@ -2,8 +2,8 @@ - -"monitoring" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"monitoring" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,92 @@ - - - + + + -
-

"monitoring" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

CloudWatch

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
+

"monitoring" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

CloudWatch

+

AWS 리소스와 애플리케이션의 지표와 로그에 대한 모니터링을 제공하는 서비스다.
지표를 감시하여 알림을 보내는 기능도 제공한다.
프리티어를 사용하지 않는 경우 대시보드당 3$/M 의 비용이 청구되고, 지표나 로그의 양에 따라 비용이 추가적으로 청구된다.
-요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

CloudWatch Metrics

기본적으로 5분마다 지표에 대한 정보가 수집된다.
+요금 정보에 대한 자세한 정보는 다음 링크에서 확인할 수 있다.

+

CloudWatch Metrics

+

기본적으로 5분마다 지표에 대한 정보가 수집된다.
세부 모니터링(Detailed Monitoring)을 활성화하면 1분마다 지표를 수집한다.
-대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

./cloudwatch1.png

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

CloudWatch Agent 설치

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

IAM 역할 설정

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
-IAM → 역할에서 역할 생성을 클릭한다.

./cloudwatch2.png

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

./cloudwatch3.png

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
-작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

./cloudwatch4.png

설치

환경은 다음과 같다.

OS: ubuntu 22.04
-인스턴스 유형: t4g.small (ARM64)

아래 명령어를 입력하여 설치한다.

wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i -E ./amazon-cloudwatch-agent.deb

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

Wizard

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
+대시보드에서 InstanceId로 검색하여 수집된 지표를 확인할 수 있다.

+

./cloudwatch1.png

+

CPUUtilization, NetworkIn, NetworkOut과 같은 기본적인 지표를 제공하고, 메모리, 디스크 공간과 같은 지표를 확인하려면 사용자 지정 지표를 설정해야 한다.

+

CloudWatch Agent 설치

+

CloudWatch Agent 사용자 지정 지표와 로그를 수집할 수 있다.

+

IAM 역할 설정

+

기본적으로 EC2 인스턴스가 CloudWatchAgentServerPolicy에 대한 권한이 있어야 한다.
+IAM → 역할에서 역할 생성을 클릭한다.

+

./cloudwatch2.png

+

CloudWatchAgentServerPolicy 권한 정책을 선택하고, 적당한 역할 이름을 입력해서 역할을 생성한다.

+

./cloudwatch3.png

+

EC2 인스턴스 목록으로 들어가서, CloudWatch Agent를 설치할 EC2 인스턴스를 클릭한다.
+작업 → 보안 → IAM 역할 수정에서 이전에 생성한 역할을 지정한다.

+

./cloudwatch4.png

+

설치

+

환경은 다음과 같다.

+

OS: ubuntu 22.04
+인스턴스 유형: t4g.small (ARM64)

+

아래 명령어를 입력하여 설치한다.

+
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/arm64/latest/amazon-cloudwatch-agent.deb
+sudo dpkg -i -E ./amazon-cloudwatch-agent.deb
+
+

사용 설명서에 각 인스턴스 유형마다 다운로드 링크가 자세하게 안내되어 있다.

+

Wizard

+

CloudWatch Wizard를 사용하면 간단하게 설정 파일 생성할 수 있다.
로그를 수집하도록 설정하는 경우 Wizard 실행 명령어 입력 전 log 파일의 절대 경로를 복사해두는 것이 좋다.
-아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
-로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

./cloudwatch5.png

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

Do you want to store the config in the SSM parameter store?
1. yes
2. no

추가적으로 설정하지 않는 경우 2번을 선택한다.
-Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
-설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

설정 파일 적용

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
-file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json

types.db: no such file or directory 에러

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory

types.db 파일 생성

sudo mkdir /usr/share/collectd
sudo touch /usr/share/collectd/types.db

지표 확인

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

./cloudwatch6.png

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

{
"metrics": {
"namespace": "2023-hello-world",
......
},
}

로그

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

./cloudwatch7.png

참고 자료

CloudWatch란 무엇입니까?
-Amazon CloudWatch 요금
-Linux 인스턴스 지표
-서버에 CloudWatch 에이전트 설치 및 실행
-CloudWatch Agent를 Parameter Store에서 관리해 보기
-CloudWatch에이전트 구성 파일

- - +아래의 명령어를 입력하여 Wizard를 실행할 수 있다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard
+
+

설정을 진행하다 보면 설정 파일이 어떻게 구성될지 확인할 수 있다.
+로그를 추가할 것이냐고 물어보는 입력창이 나오면 준비해뒀던 로그 파일의 절대 경로를 입력한다.

+

./cloudwatch5.png

+

중간에 SSM parameter store에 설정 파일을 저장할 것이냐고 물어보는 창이 나온다.

+
Do you want to store the config in the SSM parameter store?
+1. yes
+2. no
+
+

추가적으로 설정하지 않는 경우 2번을 선택한다.
+Parameter Store 관리에 대한 내용은 다음의 문서를 참고하면 좋을 거 같다.
+설정이 완료되면 /opt/aws/amazon-cloudwatch-agent/bin/config.json 에 설정에 대한 내용이 저장된다.

+

설정 파일 적용

+

아래의 명령어를 입력하여 설정파일을 적용할 수 있다.
+file 뒤에는 설정 파일에 대한 절대경로(아래 명령어 기준 기본 생성 위치)를 입력하면 된다.

+
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c file:/opt/aws/amazon-cloudwatch-agent/bin/config.json
+
+

types.db: no such file or directory 에러

+

다음과 같은 에러가 발생한다면 types.db 파일을 생성해서 문제를 해결할 수 있다.

+
Error running agent: Error loading config file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.toml: error parsing socket_listener, open /usr/share/collectd/types.db: no such file or directory
+
+

types.db 파일 생성

+
sudo mkdir /usr/share/collectd
+sudo touch /usr/share/collectd/types.db
+
+

지표 확인

+

CloudWatch Metrics에 가보면 CWAgent라는 네임스페이스가 추가된 것을 볼 수 있다.

+

./cloudwatch6.png

+

다음과 같이 설정 파일에 네임스페이스를 추가하여 지표에 대한 네임스페이스를 변경할 수 있다.

+
{
+  "metrics": {
+    "namespace": "2023-hello-world",
+    ......
+   },
+} 
+
+

로그

+

CloudWatch → 로그 그룹으로 가면 Wizard로 추가한 로그를 확인할 수 있다.

+

./cloudwatch7.png

+

참고 자료

+

CloudWatch란 무엇입니까?
+Amazon CloudWatch 요금
+Linux 인스턴스 지표
+서버에 CloudWatch 에이전트 설치 및 실행
+CloudWatch Agent를 Parameter Store에서 관리해 보기
+CloudWatch에이전트 구성 파일

\ No newline at end of file diff --git a/tags/my-sql.html b/tags/my-sql.html index 54a5d5edb..384b2d134 100644 --- a/tags/my-sql.html +++ b/tags/my-sql.html @@ -2,8 +2,8 @@ - -"MySQL" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"MySQL" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,27 +12,75 @@ - - - + + + -
-

"MySQL" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

MySQL 엔진의 잠금

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
-MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

글로벌 락(Global lock)

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

  • 영향을 미치는 범위는 해당 서버 전체이다.
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
+

"MySQL" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

MySQL 엔진의 잠금

+

MySQL에서의 락은 스토리지 엔진 레벨과, MySQL 엔진 레벨로 나눌 수 있다.
+MySQL 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미친다.

+

글로벌 락(Global lock)

+

MySQL에서 제공하는 잠금 중 가장 넓은 범위를 가지고 있는 잠금이다.

+
    +
  • 영향을 미치는 범위는 해당 서버 전체이다.
  • +
  • 작업 대상 테이블, 데이터베이스 상관 없이 동일하게 영향을 받는다.
  • +
+

한 세션에서 글로벌 락을 획득하면 해제 될 때 까지 조회를 제외한 대부분의 명령이 대기 상태가 된다.
데이터베이스에 존재하는 MyISAM이나 MEMORY 테이블에 대해 일관된 백업을 받아야할 때 사용한다.
-InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

-- GLOBAL LOCK
FLUSH TABLES WITH READ LOCK;
-- UNLOCK
UNLOCK TABLES;

-- BACKUP LOCK
LOCK INSTANCE FOR BACKUP;
-- UNLOCK
UNLOCK INSTANCE;
MyISAM

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
-트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

테이블 락(Table lock)

개별 테이블 단위로 설정되는 잠금이다.
+InnoDB 스토리지 엔진에서는 백업 시 조금 더 가벼운 백업 락을 사용할 수 있다.

+
-- GLOBAL LOCK
+FLUSH TABLES WITH READ LOCK;
+-- UNLOCK
+UNLOCK TABLES;
+
+-- BACKUP LOCK
+LOCK INSTANCE FOR BACKUP;
+-- UNLOCK
+UNLOCK INSTANCE;
+
+

MySQL 5.5 버전 이전의 기본 스토리지 엔진이다.
+트랜잭션을 지원하지 않고, SELECT 작업 속도가 빠르다.

+

테이블 락(Table lock)

+

개별 테이블 단위로 설정되는 잠금이다.
명시적 또는 묵시적으로 특정 테이블의 락을 획득할 수 있다.
묵시적 락은 MyISAM이나 MEMORY 테이블에 데이터를 변경하는 쿼리를 실행하면 발생한다.
-InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

-- TABLE LOCK
LOCK TABLES table_name [ READ | WRITE ]

-- UNLOCK
UNLOCK TABLES;

네임드 락(Named lock)

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
-여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
SELECT GET_LOCK('aGVyYg==', 1);

-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
SELECT IS_FREE_LOCK('aGVyYg==');

-- 문자열에 대한 잠금을 해제한다.
SELECT RELEASE_LOCK('aGVyYg==');

-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.

-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
SELECT RELEASE_ALL_LOCKS();

메타데이터 락(Metadata lock)

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
+InnoDB 테이블에는 DML 쿼리는 무시되고 DDL 일 경우에만 묵시적으로 락을 획득한다.

+
-- TABLE LOCK
+LOCK TABLES table_name [ READ | WRITE ]
+
+-- UNLOCK
+UNLOCK TABLES;
+
+

네임드 락(Named lock)

+

임의의 문자열에 대한 잠금을 설정할 수 있는 잠금으로 유저 레벨 락으로도 불린다.
+여러 스레드나 프로세스가 동일한 데이터를 수정하려는 경우, 동시에 수정하지 못하도록 보호할 수 있다.

+
-- aGVyYg== 라는 문자열에 대한 잠금 획득, 이미 잠금을 사용중인 경우 1초 동안만 대기
+SELECT GET_LOCK('aGVyYg==', 1);
+
+-- 문자열에 대한 잠금이 설정되어 있는지 확인한다.
+SELECT IS_FREE_LOCK('aGVyYg==');
+
+-- 문자열에 대한 잠금을 해제한다.
+SELECT RELEASE_LOCK('aGVyYg==');
+
+-- 위 3개 함수 모두 정상적으로 락을 획득하거나 해제한 경우에 1을, 아니면 0을 반환한다.
+
+-- 모든 문자열에 대한 잠금을 해제한다. 해제된 잠금의 개수를 반환한다.
+SELECT RELEASE_ALL_LOCKS();
+
+

메타데이터 락(Metadata lock)

+

데이터베이스 객체의 이름이나 구조를 변경하는 경우 획득하는 잠금이다.
명시적으로 획득 또는 해제 할 수 없지만 테이블의 이름을 변경하는 경우 자동으로 획득한다.
-보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
RENAME TABLE rank TO rank_backup, rank_new TO rank;

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-MySQL의 User Level Lock를 활용한다면?, gywndi
-Locking Functions, MySQL 5.7 Reference
-Locking Functions, MySQL 8.0 Reference

- - +보통 배치 프로그램에서 실시간으로 테이블을 바꿔야하는 경우에 사용된다.

+
-- 배치 프로그램에서 별도의 임시 테이블에 서비스용 랭킹 데이터 생성 후 기존 테이블을 백업하는 경우
+-- 아래 구문 실행 시 메타데이터 락을 자동으로 획득한다.
+RENAME TABLE rank TO rank_backup, rank_new TO rank;
+
+

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+MySQL의 User Level Lock를 활용한다면?, gywndi
+Locking Functions, MySQL 5.7 Reference
+Locking Functions, MySQL 8.0 Reference

\ No newline at end of file diff --git a/tags/mysql.html b/tags/mysql.html index 9b90c60f3..7c22ee55b 100644 --- a/tags/mysql.html +++ b/tags/mysql.html @@ -2,8 +2,8 @@ - -"mysql" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"mysql" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,65 +12,440 @@ - - - + + + -
-

"mysql" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 21분

복제(Replication)

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
-원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

복제를 하는 이유

1. 스케일 아웃

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
-이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

2. 데이터 백업

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
-따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

3. 데이터 분석

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
-마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

4. 데이터의 지리적 분산

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

바이너리 로그 파일 위치 기반 복제

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
+

"mysql" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 21분

복제(Replication)

+

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
+원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

+

복제를 하는 이유

+

1. 스케일 아웃

+

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
+이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

+

2. 데이터 백업

+

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
+따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

+

3. 데이터 분석

+

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
+마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

+

4. 데이터의 지리적 분산

+

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

+

바이너리 로그 파일 위치 기반 복제

+

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
바이너리 로그를 통해 데이터 변경, 테이블 구조 변경, 계정이나 권한 변경에 대한 정보가 저장된다.
-MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

스레드별 역할

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
+MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

+ +

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
Replication I/O Thread: Binary 로그 이벤트를 가져와 로컬 서버의 파일(Relay Log)로 저장
-Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

바이너리 로그 방식의 문제점

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
-토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
+Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

+

바이너리 로그 방식의 문제점

+

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
+토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

+ +

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

+ +

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
하지만 여기서 C 서버에는 A 서버와 동기화가 안되었으니 조회 시 문제가 발생한다.
-뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

글로벌 트랜잭션 아이디(GTID) 기반 복제

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
-위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

GTID

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
-[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

복제 토폴로지

싱글 레플리카 복제 구성

가장 간단한 구성으로 제일 많이 사용하는 형태다.
-replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

멀티 레플리카 복제 구성

2개의 replica 서버를 사용하는 형태다.
+뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

+

글로벌 트랜잭션 아이디(GTID) 기반 복제

+

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
+위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

+

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
+[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

+

복제 토폴로지

+

싱글 레플리카 복제 구성

+

가장 간단한 구성으로 제일 많이 사용하는 형태다.
+replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

+ +

멀티 레플리카 복제 구성

+

2개의 replica 서버를 사용하는 형태다.
하나의 replica는 예비 용도로 남겨두는 형태다.
-추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

체인 복제 구성

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
-따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

듀얼 소스 복제 구성

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
+추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

+ +

체인 복제 구성

+

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
+따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

+ +

듀얼 소스 복제 구성

+

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
각 서버에서 변경된 데이터는 다른 서버에 반영된다.
목적에 따라 ACTIVE-ACTIVE 형태 또는 ACTIVE-PASSIVE 형태로 사용할 수 있다.
-ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

ACTIVE-ACTIVE, ACTIVE-PASSIVE

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
-ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

멀티 소스 복제 구성

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
-이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

바이너리 로그 방식 Replication 구성하기

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
-https://github.com/bbiac/db-replication

MySQL 환경 구성

MySQL 버전은 8.1을 사용했다.
+ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

+ +

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
+ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

+

멀티 소스 복제 구성

+

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
+이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

+ +

바이너리 로그 방식 Replication 구성하기

+

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
+https://github.com/bbiac/db-replication

+

MySQL 환경 구성

+

MySQL 버전은 8.1을 사용했다.
13306, 13307 포트를 사용해서 MySQL 서버 2대를 띄웠다.
-또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

version: '3.8'

services:
source:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-source
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13306:3306"
volumes:
- db-source:/var/lib/mysql
- db-source:/var/lib/mysql-files
- ./docker/source.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

replica:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-replica
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13307:3306"
volumes:
- db-replica:/var/lib/mysql
- db-replica:/var/lib/mysql-files
- ./docker/replica.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

volumes:
db-source:
db-replica:

networks:
mysql_network:
driver: bridge

또한 source, replica 각각 다음과 같이 db 설정을 했다.

설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
/docker/source.cnf
[mysqld]
server_id=1
log_bin=mysql-bin
sync_binlog=1

도커 실행

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
--d 옵션을 붙이면 백그라운드 모드로 실행된다.

docker-compose up -d

replication slave 권한 설정

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
-source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

SOURCE 접속

docker exec -it mysql-source mysql -u root -p

user 계정에 REPLICATION SLAVE 권한 추가

GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
FLUSH PRIVILEGES;

SOURCE DB 정보 확인

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
+또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

+
version: '3.8'
+
+services:
+  source:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-source
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13306:3306"
+    volumes:
+      - db-source:/var/lib/mysql
+      - db-source:/var/lib/mysql-files
+      - ./docker/source.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+  replica:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-replica
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13307:3306"
+    volumes:
+      - db-replica:/var/lib/mysql
+      - db-replica:/var/lib/mysql-files
+      - ./docker/replica.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+volumes:
+  db-source:
+  db-replica:
+
+networks:
+  mysql_network:
+    driver: bridge
+
+

또한 source, replica 각각 다음과 같이 db 설정을 했다.

+
설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
+ + +
[mysqld]
+server_id=1
+log_bin=mysql-bin
+sync_binlog=1
+
+

도커 실행

+

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
+-d 옵션을 붙이면 백그라운드 모드로 실행된다.

+
docker-compose up -d
+
+

replication slave 권한 설정

+

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
+source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

+

SOURCE 접속

+
docker exec -it mysql-source mysql -u root -p
+
+

user 계정에 REPLICATION SLAVE 권한 추가

+
GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
+FLUSH PRIVILEGES;
+
+

SOURCE DB 정보 확인

+

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
Position 값은 실제 파일의 바이트 수를 의미한다.
-확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 1082 | | | |
+------------------+----------+--------------+------------------+-------------------+

SOURCE ip 주소 확인

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
-다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
-확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

replica mysql 접속

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

docker exec -it mysql-replica mysql -u root -p

replica 설정

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
+확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

+
SHOW MASTER STATUS;
+
++------------------+----------+--------------+------------------+-------------------+
+| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
++------------------+----------+--------------+------------------+-------------------+
+| mysql-bin.000003 |     1082 |              |                  |                   |
++------------------+----------+--------------+------------------+-------------------+
+
+

SOURCE ip 주소 확인

+

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
+다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

+
docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source
+
+

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
+확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

+

replica mysql 접속

+

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

+
docker exec -it mysql-replica mysql -u root -p
+
+

replica 설정

+

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
실제 DB 서버에서 복제하는 경우 추가적으로 source DB의 파일을 복제해야하지만 현재 복제할 데이터가 없기 때문에 해당 부분은 생략했다.
-SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

STOP REPLICA;

CHANGE REPLICATION SOURCE TO
SOURCE_HOST='172.29.0.2',
SOURCE_USER='user',
SOURCE_PASSWORD='password',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=0,
GET_SOURCE_PUBLIC_KEY=1;

START REPLICA;

설정 확인

SHOW REPLICA STATUS;

+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
-replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

CREATE TABLE member
(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);

스프링 부트로 DB 접근하기

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

Environment 설정

다음과 같이 source, replica로 구분하여 설정한다.

application.yml
spring:
datasource:
source:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13306/db
replica:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13307/db

DataSourceType 설정

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
-Key는 추후에 빈 설정에 사용한다.

DataSourceType
public enum DataSourceType {
SOURCE(SOURCE_NAME),
REPLICA(REPLICA_NAME),
;

private final String key;

DataSourceType(String key) {
this.key = key;
}

public static class Key {
public static final String ROUTING_NAME = "ROUTING";
public static final String SOURCE_NAME = "SOURCE";
public static final String REPLICA_NAME = "REPLICA";
}
}

AbstractRoutingDataSource 설정

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
RoutingDataSource
public class RoutingDataSource extends AbstractRoutingDataSource {

private final Logger log = LoggerFactory.getLogger(getClass());

public static RoutingDataSource from(Map<Object, Object> dataSources) {
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
routingDataSource.setTargetDataSources(dataSources);
return routingDataSource;
}

@Override
protected Object determineCurrentLookupKey() {
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();

if (readOnly) {
log.info("readOnly = true, request to replica");
return DataSourceType.REPLICA;
}
log.info("readOnly = false, request to source");
return DataSourceType.SOURCE;
}
}

DataSource 설정

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
+SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

+
STOP REPLICA;
+
+CHANGE REPLICATION SOURCE TO 
+SOURCE_HOST='172.29.0.2', 
+SOURCE_USER='user', 
+SOURCE_PASSWORD='password', 
+SOURCE_LOG_FILE='mysql-bin.000001', 
+SOURCE_LOG_POS=0, 
+GET_SOURCE_PUBLIC_KEY=1;
+
+START REPLICA;
+
+

설정 확인

+
SHOW REPLICA STATUS;
+
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Replica_IO_State                 | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File  | Read_Source_Log_Pos | Relay_Log_File         | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID                          | Source_Info_File        | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State                                | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Waiting for source to send event | 172.25.0.3  | user        |        3306 |            60 | mysql-bin.000003 |                1082 | mysql-relay-bin.000002 |           868 | mysql-bin.000003      | Yes                | Yes                 |                 |                     |                    |                        |                         |                             |          0 |            |            0 |                1082 |            1078 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 | No                            |             0 |               |              0 |                |                             |                1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info |         0 |                NULL | Replica has read all relay log; waiting for more updates |              86400 |             |                         |                          |                |                    |                    |                   |             0 |                      |              |                    |                        |                     1 |                   |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+
+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

+

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
+replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

+
CREATE TABLE member
+(
+    id   BIGINT PRIMARY KEY AUTO_INCREMENT,
+    name VARCHAR(255)
+);
+
+

스프링 부트로 DB 접근하기

+

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

+

Environment 설정

+

다음과 같이 source, replica로 구분하여 설정한다.

+
spring:
+  datasource:
+    source:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13306/db
+    replica:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13307/db
+
+

DataSourceType 설정

+

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
+Key는 추후에 빈 설정에 사용한다.

+
public enum DataSourceType {
+    SOURCE(SOURCE_NAME),
+    REPLICA(REPLICA_NAME),
+    ;
+
+    private final String key;
+
+    DataSourceType(String key) {
+        this.key = key;
+    }
+
+    public static class Key {
+        public static final String ROUTING_NAME = "ROUTING";
+        public static final String SOURCE_NAME = "SOURCE";
+        public static final String REPLICA_NAME = "REPLICA";
+    }
+}
+
+

AbstractRoutingDataSource 설정

+

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

+

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

+
    +
  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • +
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.
  • +
+

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

+
    +
  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • +
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
  • +
+
public class RoutingDataSource extends AbstractRoutingDataSource {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public static RoutingDataSource from(Map<Object, Object> dataSources) {
+        RoutingDataSource routingDataSource = new RoutingDataSource();
+        routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
+        routingDataSource.setTargetDataSources(dataSources);
+        return routingDataSource;
+    }
+
+    @Override
+    protected Object determineCurrentLookupKey() {
+        boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
+
+        if (readOnly) {
+            log.info("readOnly = true, request to replica");
+            return DataSourceType.REPLICA;
+        }
+        log.info("readOnly = false, request to source");
+        return DataSourceType.SOURCE;
+    }
+}
+
+

DataSource 설정

+

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
스프링은 트랜잭션 시작시에 커넥션의 사용여부와 상관없이 커넥션을 확보한다.
-따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

DataSourceConfiguration
@Configuration
public class DataSourceConfiguration {

@Bean
@Qualifier(SOURCE_NAME)
@ConfigurationProperties(prefix = "spring.datasource.source")
public DataSource sourceDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(REPLICA_NAME)
@ConfigurationProperties(prefix = "spring.datasource.replica")
public DataSource replicaDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(ROUTING_NAME)
public DataSource routingDataSource(
@Qualifier(SOURCE_NAME) DataSource sourceDataSource,
@Qualifier(REPLICA_NAME) DataSource replicaDataSource
) {
return RoutingDataSource.from(Map.of(
DataSourceType.SOURCE, sourceDataSource,
DataSourceType.REPLICA, replicaDataSource
));
}

@Bean
@Primary
public DataSource dataSource(
@Qualifier(ROUTING_NAME) DataSource routingDataSource
) {
return new LazyConnectionDataSourceProxy(routingDataSource);
}
}

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

동작 확인

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
+따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

+

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

+

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

+
@Configuration
+public class DataSourceConfiguration {
+
+    @Bean
+    @Qualifier(SOURCE_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.source")
+    public DataSource sourceDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(REPLICA_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.replica")
+    public DataSource replicaDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(ROUTING_NAME)
+    public DataSource routingDataSource(
+            @Qualifier(SOURCE_NAME) DataSource sourceDataSource,
+            @Qualifier(REPLICA_NAME) DataSource replicaDataSource
+    ) {
+        return RoutingDataSource.from(Map.of(
+                DataSourceType.SOURCE, sourceDataSource,
+                DataSourceType.REPLICA, replicaDataSource
+        ));
+    }
+
+    @Bean
+    @Primary
+    public DataSource dataSource(
+            @Qualifier(ROUTING_NAME) DataSource routingDataSource
+    ) {
+        return new LazyConnectionDataSourceProxy(routingDataSource);
+    }
+}
+
+

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

+ +

동작 확인

+

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
save 메서드의 경우 @Transactional, findById 메서드의 경우 @Transactional(readOnly = true)가 설정되어있다.
-로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

MemberServiceTest
@SpringBootTest
class MemberServiceTest {

@Autowired
private MemberService memberService;

@Test
void 사용자를_저장한다() {
// RoutingDataSource log: readOnly = false
memberService.save("bbiac");
}

@Test
void 사용자를_조회한다() {
// RoutingDataSource log: readOnly = true
assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
.isInstanceOf(NoSuchElementException.class);
}
}

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

SET GLOBAL log_output = 'table';
SET GLOBAL general_log = 1;

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
-server_id, 실행한 쿼리문을 확인할 수 있다.

SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';

+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user_host | thread_id | server_id | convert(argument using utf8) |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

SET GLOBAL general_log = 0;
SHOW VARIABLES LIKE '%general%';

+------------------+---------------------------------+
| Variable_name | Value |
+------------------+---------------------------------+
| general_log | OFF |
| general_log_file | /var/lib/mysql/4b6b9db98290.log |
+------------------+---------------------------------+

참고 자료

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
-Replication, MySQL Docs
-MySql - Master Slave Replication 구조 만들어보기
-Spring 레플리케이션 트랜잭션 처리 방식
-replication-datasource
-Simplified Guide to MySQL Replication with Docker Compose
-Dockerfile에서 자주 쓰이는 명령어
-CHANGE REPLICATION SOURCE TO Statement
-LazyConnectionDataSourceProxy
-데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
-부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
-Use Docker Compose, Docker

- - +로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

+
@SpringBootTest
+class MemberServiceTest {
+
+    @Autowired
+    private MemberService memberService;
+
+    @Test
+    void 사용자를_저장한다() {
+        // RoutingDataSource log: readOnly = false
+        memberService.save("bbiac");
+    }
+
+    @Test
+    void 사용자를_조회한다() {
+        // RoutingDataSource log: readOnly = true
+        assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
+                .isInstanceOf(NoSuchElementException.class);
+    }
+}
+
+

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

+
SET GLOBAL log_output = 'table';
+SET GLOBAL general_log = 1;
+
+

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
+server_id, 실행한 쿼리문을 확인할 수 있다.

+
SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';
+
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user_host                  | thread_id | server_id | convert(argument using utf8)                                                |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user[user] @  [172.25.0.1] |       277 |         2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+
+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

+
SET GLOBAL general_log = 0;
+SHOW VARIABLES LIKE '%general%';
+
++------------------+---------------------------------+
+| Variable_name    | Value                           |
++------------------+---------------------------------+
+| general_log      | OFF                             |
+| general_log_file | /var/lib/mysql/4b6b9db98290.log |
++------------------+---------------------------------+
+
+

참고 자료

+

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
+Replication, MySQL Docs
+MySql - Master Slave Replication 구조 만들어보기
+Spring 레플리케이션 트랜잭션 처리 방식
+replication-datasource
+Simplified Guide to MySQL Replication with Docker Compose
+Dockerfile에서 자주 쓰이는 명령어
+CHANGE REPLICATION SOURCE TO Statement
+LazyConnectionDataSourceProxy
+데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
+부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
+Use Docker Compose, Docker

\ No newline at end of file diff --git a/tags/oop.html b/tags/oop.html index 24a716910..bae12f057 100644 --- a/tags/oop.html +++ b/tags/oop.html @@ -2,8 +2,8 @@ - -"OOP" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"OOP" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,16 +12,101 @@ - - - + + + -
-

"OOP" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 9분

GRASP(General Responsibility Assignment Software Pattern)

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

각 패턴마다 Solution과 Problem로 구성되어 있다.

정보 전문가 패턴(Information Expert)

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

필요한 정보를 가진 객체들로 책임이 분산된다.

창조자 패턴(Creator)

Q: 누가 객체 A를 생성하는가?

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A 객체를 긴밀하게 사용한다.
  • B가 A 객체의 초기값을 가지고 있다.

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

낮은 결합도 패턴(Low Coupling)

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

결합도(Coupling) -객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

  • 오브젝트 p.17

결합도를 낮춘다면 다음과 같은 이점이 있다.

  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • 재사용이 편리해진다.
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)

높은 응집도 패턴(High Cohesion)

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

응집도(Cohesion) -연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

  • 오브젝트 p.26

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • 유지보수가 쉬워진다.
  • 낮은 결합도 또한 지원한다.
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.

컨트롤러 패턴(Controller)

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

어떤 서브시스템이 존재한다고 가정할 때

  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.

다형성 패턴(Polymorphism)

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

변경 보호 패턴(Protected Variations)

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

간접 참조 패턴(Indirection)

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

순수한 가공물 패턴(Pure Fabrication)

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.

참고 자료

오브젝트 5장. 책임 할당하기, 조영호

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

GRASP, 한빛 네트워크

- - +

"OOP" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 9분

GRASP(General Responsibility Assignment Software Pattern)

+

크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴

+

각 패턴마다 Solution과 Problem로 구성되어 있다.

+

정보 전문가 패턴(Information Expert)

+

Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?

+

A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.

+

정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.

+

필요한 정보를 가진 객체들로 책임이 분산된다.

+

창조자 패턴(Creator)

+

Q: 누가 객체 A를 생성하는가?

+

A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.

+
    +
  • B가 A 객체를 포함 또는 참조한다.
  • +
  • B가 A 객체를 기록한다.
  • +
  • B가 A 객체를 긴밀하게 사용한다.
  • +
  • B가 A 객체의 초기값을 가지고 있다.
  • +
+

생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.

+

낮은 결합도 패턴(Low Coupling)

+

Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?

+

A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.

+
+

결합도(Coupling) +객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.

+
+
    +
  • 오브젝트 p.17
  • +
+
+
+

결합도를 낮춘다면 다음과 같은 이점이 있다.

+
    +
  • 다른 구성 요소의 변화에 영향을 받지 않는다.
  • +
  • 재사용이 편리해진다.
  • +
  • 해당 클래스에 대한 이해가 쉬워진다. (의존하는 클래스가 적기 때문에)
  • +
+

높은 응집도 패턴(High Cohesion)

+

Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?

+

A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.

+
+

응집도(Cohesion) +연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.

+
+
    +
  • 오브젝트 p.26
  • +
+
+
+

변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.

+
    +
  • 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
  • +
  • 유지보수가 쉬워진다.
  • +
  • 낮은 결합도 또한 지원한다.
  • +
  • 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.
  • +
+

컨트롤러 패턴(Controller)

+

Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?

+

A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.

+

어떤 서브시스템이 존재한다고 가정할 때

+
    +
  • 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
  • +
  • 서브 시스템에 들어오는 요청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
  • +
  • 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.
  • +
+

다형성 패턴(Polymorphism)

+

Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?

+

A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)

+

객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.

+

새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.

+

변경 보호 패턴(Protected Variations)

+

Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?

+

A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.

+

간접 참조 패턴(Indirection)

+

Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?

+

A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.

+

중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.

+

중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.

+

순수한 가공물 패턴(Pure Fabrication)

+

Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?

+

A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.

+

행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.

+

객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.

+

예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정

+
    +
  • 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
  • +
  • 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.
  • +
+

참고 자료

+

오브젝트 5장. 책임 할당하기, 조영호

+

Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman

+

GRASP, 한빛 네트워크

\ No newline at end of file diff --git a/tags/pattern.html b/tags/pattern.html index f25f196b7..ddebed146 100644 --- a/tags/pattern.html +++ b/tags/pattern.html @@ -2,8 +2,8 @@ - -"Pattern" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Pattern" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,26 +12,110 @@ - - - + + + -
-

"Pattern" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

요구사항

지하철 미션에는 다음과 같은 요구사항이 있었다.

  • 거리별 추가 요금 정책
  • 노선별 추가 요금 정책
  • 연령별 요금 할인 정책

인터페이스 사용

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
-요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

public interface FarePolicy {
int calculate(Path path, Passenger passenger, int fare);
}

public class BaseFarePolicy implements FarePolicy { ... }
public class DistanceFarePolicy implements FarePolicy { ... }
public class AgeDiscountFarePolicy implements FarePolicy { ... }

composite1

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
-이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

public class SubwayFarePolicy implements FarePolicy {

private final List<FarePolicy> farePolicies;

public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
this.farePolicies = farePolicies;
}

@Override
public int calculate(final Path path, final Passenger passenger, final int fare) {
int calculatedFare = fare;
for (FarePolicy farePolicy : farePolicies) {
calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
}
return calculatedFare;
}
}

따라서 그림으로 본다면 다음과 같은 구조가 된다.

composite2

정책의 순서

지하철 요구사항은 순서가 중요했다.
+

"Pattern" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

요구사항

+

지하철 미션에는 다음과 같은 요구사항이 있었다.

+
    +
  • 거리별 추가 요금 정책
  • +
  • 노선별 추가 요금 정책
  • +
  • 연령별 요금 할인 정책
  • +
+

인터페이스 사용

+

요금 정책은 다음과 같이 인터페이스로 표현할 수 있다.
+요금을 계산하는 메서드는 최단 경로 계산의 결과, 사용자의 정보, 요금을 받아 요금을 계산한다.

+
public interface FarePolicy {
+    int calculate(Path path, Passenger passenger, int fare);
+}
+
+public class BaseFarePolicy implements FarePolicy { ... }
+public class DistanceFarePolicy implements FarePolicy { ... }
+public class AgeDiscountFarePolicy implements FarePolicy { ... }
+
+

composite1

+

모든 요금 정책을 포함하는 새로운 요금 정책 만들기

+

나머지 구현체를 모두 가지고 있는 하나의 구현체를 만들었다.
+이 또한 FarePolicy를 구현한 형태가 되고, 필드로는 나머지 구현체들을 가지고 있다.

+
public class SubwayFarePolicy implements FarePolicy {
+
+    private final List<FarePolicy> farePolicies;
+
+    public SubwayFarePolicy(final List<FarePolicy> farePolicies) {
+        this.farePolicies = farePolicies;
+    }
+
+    @Override
+    public int calculate(final Path path, final Passenger passenger, final int fare) {
+        int calculatedFare = fare;
+        for (FarePolicy farePolicy : farePolicies) {
+            calculatedFare = farePolicy.calculate(path, passenger, calculatedFare);
+        }
+        return calculatedFare;
+    }
+}
+
+

따라서 그림으로 본다면 다음과 같은 구조가 된다.

+

composite2

+

정책의 순서

+

지하철 요구사항은 순서가 중요했다.
금액의 총합을 구하고, 그 후에 할인 정책이 들어가야했다.
따라서 자식들의 순서를 관리할 때 주의를 기울여야 했다.
-Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

@Configuration
public class FareConfiguration {

@Bean
public FarePolicy farePolicy() {
return new SubwayFarePolicy(List.of(
new BaseFarePolicy(),
new DistanceFarePolicy(),
new AgeDiscountFarePolicy()
));
}
}

컴포지트 패턴이란?

composite3

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
-사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

컴포지트 패턴의 구성요소

Component

  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • ex) 요금 정책(FarePolicy)

Leaf

  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • ex) 거리 별 요금 정책(DistanceFarePolicy)

Composite

  • 여러 개의 개발 객체를 포함하는 합성 객체
  • ex) 지하철 요금 정책(SubwayFarePolicy)

Client

  • 인터페이스를 사용하는 클라이언트

컴포지트 패턴의 사용과 주요 목표

부분 - 전체의 관계를 표현하고 싶을 때
-Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

패턴 사용시 주의해야할 부분

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
+Configuration 클래스에 다음과 같이 순서를 직접 적용시켰다.

+
@Configuration
+public class FareConfiguration {
+
+    @Bean
+    public FarePolicy farePolicy() {
+        return new SubwayFarePolicy(List.of(
+                new BaseFarePolicy(),
+                new DistanceFarePolicy(),
+                new AgeDiscountFarePolicy()
+        ));
+    }
+}
+
+

컴포지트 패턴이란?

+

composite3

+

GOF의 디자인 패턴 책에서는 컴포지트 패턴을 다음과 같이 설명하고 있다.

+
+

부분과 전체의 계층을 표현하기 위해 객체들을 모아 트리 구조로 구성합니다.
+사용자로 하여금 개별 객체와 복합 객체를 모두 동일하게 다룰 수 있도록 하는 패턴입니다.

+
+

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
+이 때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

+

컴포지트 패턴의 구성요소

+

Component

+
    +
  • 집합 관계에 정의될 모든 객체에 대한 인터페이스
  • +
  • ex) 요금 정책(FarePolicy)
  • +
+

Leaf

+
    +
  • 개별 객체, 객체 합성에 기본이 되는 객체의 행동
  • +
  • ex) 거리 별 요금 정책(DistanceFarePolicy)
  • +
+

Composite

+
    +
  • 여러 개의 개발 객체를 포함하는 합성 객체
  • +
  • ex) 지하철 요금 정책(SubwayFarePolicy)
  • +
+

Client

+
    +
  • 인터페이스를 사용하는 클라이언트
  • +
+

컴포지트 패턴의 사용과 주요 목표

+

부분 - 전체의 관계를 표현하고 싶을 때
+Client 기준으로 Composite와 Leaf의 차이를 알지 못해도 잘 사용할 수 있도록 해야될 때

+

패턴 사용시 주의해야할 부분

+

패턴은 공통으로 사용 가능한 역할, 책임, 협력의 템플릿이다.
반복되는 문제를 효율적으로 해결할 수 있지만 패턴에 매몰되서는 안된다.
-패턴을 맹목적으로 사용해서는 안되고, 현재의 요구사항에 따라 패턴을 유동적으로 수정해가면서 적용하는 것이 좋다.
-항상 트레이드오프를 생각하자!

참고 자료

컴포지트 패턴, GoF의 디자인 패턴
+패턴을 맹목적으로 사용해서는 안되고, 현재의 요구사항에 따라 패턴을 유동적으로 수정해가면서 적용하는 것이 좋다.
+항상 트레이드오프를 생각하자!

+

참고 자료

+

컴포지트 패턴, GoF의 디자인 패턴
디자인 패턴과 프레임워크, 오브젝트

- - \ No newline at end of file diff --git a/tags/performance-test.html b/tags/performance-test.html index b81d8f493..a643bbcba 100644 --- a/tags/performance-test.html +++ b/tags/performance-test.html @@ -2,8 +2,8 @@ - -"performance test" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"performance test" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,28 +12,50 @@ - - - + + + -
-

"performance test" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

성능 테스트

API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트

시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.
-다양한 상황에 대비해서 성능 테스트를 해야한다.

./test.png

스모크 테스트(Smoke Test)

최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트

VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.
-다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.

가상 사용자(VU)

가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.
+

"performance test" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

성능 테스트

+

API의 요청이 많은 상황에서 서버가 어떻게 동작하는지 확인하는 테스트

+

시스템에 부하가 걸리면 문제 상황이 발생할 수 있다.
+다양한 상황에 대비해서 성능 테스트를 해야한다.

+

./test.png

+

스모크 테스트(Smoke Test)

+

최소한의 부하를 주어 시스템이 정상적으로 동작하는지 확인하는 테스트

+

VU를 최소한으로 두고, 짧은 시간을 가지고 테스트한다.
+다른 테스트를 시작하기 전에 스모크 테스트를 함으로써 테스트 스크립트에 오류가 없는지 확인할 수 있고, 성능 지표가 정상적으로 수집, 모니터링 되고 있는지 확인할 수 있다.

+

가상 사용자는 서버 애플리케이션에 대해 특정 테스트를 실행한다.
이는 다른 가상 사용자와 독립적으로 실행되며, 여러 가상 사용자를 사용하여 동시 연결을 할 수 있다.
-스레드라고 생각하면 된다.

스파이크 테스트(Spike Test)

사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트

티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.
-스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.

부하 테스트(Load Test)

목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트

일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.
-램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.

램프 업(Ramp-up)

부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간

스트레스 테스트(Stress Test)

시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트

그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.
+스레드라고 생각하면 된다.

+

스파이크 테스트(Spike Test)

+

사용량이 급증하는 상황에서 시스템이 견디고 성능에 문제가 없는지 확인하는 테스트

+

티켓 발급, 할인 쿠폰 발급과 같은 이벤트를 하는 경우 대규모 트래픽이 들어온다.
+스파이크 테스트를 통해 급증하는 부하 상황에서 시스템이 어떻게 동작하고, 부하를 잘 버티는지 확인할 수 있다.

+

부하 테스트(Load Test)

+

목푯값에 해당되는 부하를 견딜 수 있을지 확인하는 테스트

+

일반적인 부하 상황에서 시스템이 어떻게 동작하는지 확인하는 테스트다.
+램프업 또는 묙푯값에 해당하는 부하 기간동안 성능이 문제가 있는지 확인하고, 시스템 변경 후에도 부하 테스트를 돌려 동일하게 목푯값을 처리하는지 확인할 수 있다.

+

부하 테스트를 위해 설정한 가상 사용자 수에 도달하는 데 걸리는 시간

+

스트레스 테스트(Stress Test)

+

시스템의 최대치에 해당되는 부하를 받았을 때 시스템이 어떻게 동작하는지 확인하는 테스트

+

그래프를 봤을 때 부하 테스트와 유사한 형태로 보이지만, 부하량이 다르다.
일반적으로 평균적인 목푯값 대비 작게는 50% 이상, 필요의 경우 그 이상으로 부하를 준다.
스트레스 테스트는 부하 테스트를 실행한 후에만 실행해야 한다. 부하 테스트가 이루어지지 않은 상황에서 스트레스 테스트를 실행하는 경우에는 병목 지점이나 문제 상황을 찾기 어려워진다.
-또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.

내구 테스트(Endurance Test)

평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트

흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.
-다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.

중단점 테스트(Breakpoint Test)

임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트

문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.
+또한 부하 테스트에서 사용한 스크립트를 VU값(스레드 수)만 수정하여 재사용하는 것이 좋다.

+

내구 테스트(Endurance Test)

+

평균 사용률로 일정 부하를 지속적으로 주며 시스템이 문제되는 지점을 확인하는 테스트

+

흡수 테스트(Soak Test)라고도 하며, 기본적인 부하 테스트의 변형이라고 볼 수 있다.
+다른 테스트와 달리 긴 시간동안 테스트를 하는 것이 특징이며, 메모리 누수 문제와 같이 장시간 애플리케이션을 실행할 때 시스템의 문제가 발생하는 부분을 확인하는 것이 목적이다.

+

중단점 테스트(Breakpoint Test)

+

임계 지점을 찾기 위해 부하를 점진적으로 증가시키며 진행하는 테스트

+

문제되는 부분을 더 빨리 찾기 위해 다른 테스트를 통과한 다음에 중단점 테스트를 진행하고, 이 때 점진적으로 부하를 늘려나가는 것이 좋다.
스트레스 테스트를 성능 튜닝과 반복해서 진행한다면, 시스템을 더욱 발전시킬 수 있다.
-다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.

참고 자료

Load test types, k6
+다만 Auto Scaling이 적용된 클라우드 환경에서는 진행하지 않아야 한다.

+

참고 자료

+

Load test types, k6
자바 최적화 - 벤저민 J. 에번스, 제임스 고프, 크리스 뉴랜드
아마존 웹 서비스 부하 테스트 입문 - 나카가와 타루하치, 모리시타 켄

- - \ No newline at end of file diff --git a/tags/python.html b/tags/python.html index 60402db0b..60b2fc571 100644 --- a/tags/python.html +++ b/tags/python.html @@ -2,8 +2,8 @@ - -"Python" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Python" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,34 +12,182 @@ - - - + + + -
-

"Python" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 7분

개요

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

사용 기술

언어: Python 3.10
+

"Python" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 7분

개요

+

이전에 기술 구현 가능 여부를 조사하면서 파이썬을 사용한 내용을 정리한 내용이다.

+

사용 기술

+

언어: Python 3.10
이미지 생성: matplotlib
서비스: AWS Lambda, AWS API Gateway
-이미지 저장 및 URL: AWS S3, AWS CloudFront

플로우는 다음과 같다.

요구사항

./route.png

우측 상단의 경로 이미지를 생성하려고 한다.
-경로 이미지 생성에 대한 요구사항은 다음과 같다.

  • 위도, 경도로 이루어진 배열을 입력받는다.
  • 이미지 생성
  • 선과 점 표현
  • 투명한 배경색
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.

이미지 출력 방식

  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
-파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

로컬에서 기능 구현

import time

import matplotlib.pyplot as plt


def draw(point):
start = time.time()
x, y = zip(*point)
pixel_x, pixel_y = convert_to_pixel_values(x, y)
draw_lines(pixel_x, pixel_y)
end = time.time()
print(end - start)

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)


def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
return scaled_coordinates


def draw_lines(x, y):
figure = plt.gcf()
figure.set_size_inches(5, 5)
plt.plot(x, y, c = 'w',linewidth=5)
plt.scatter(x[3],y[3], c = 'w', s = 125)
plt.axis('off')
plt.savefig('name.png', transparent=True, format='png')

point = [
[126.96352960597338, 37.590841000217125],
[126.96987292787792, 37.58435564234159],
[126.98128481452298, 37.58594375113966],
[126.99360339342958, 37.58248524741927],
[126.99867565340067, 37.56778118088622],
[127.001935378366117, 37.55985240444085],
[126.9831048919687, 37.548030119488665],
[126.97189273528845, 37.5119879225856],
[127.02689859997221, 37.48488593333883]
]

draw(point)

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

./routeImage.png

AWS Lambda

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
+이미지 저장 및 URL: AWS S3, AWS CloudFront

+

플로우는 다음과 같다.

+ +

요구사항

+

./route.png

+

우측 상단의 경로 이미지를 생성하려고 한다.
+경로 이미지 생성에 대한 요구사항은 다음과 같다.

+
    +
  • 위도, 경도로 이루어진 배열을 입력받는다.
  • +
  • 이미지 생성
  • +
  • 선과 점 표현
  • +
  • 투명한 배경색
  • +
  • 위경도 차이가 크든 작든 제공하는 이미지 내에 경로가 다 포함되어 있어야 한다.
  • +
+

이미지 출력 방식

+
    +
  1. 위경도를 처리한 값으로 직접 경로를 그린 다음 이미지 형태로 저장
  2. +
  3. 플롯을 그려주는 라이브러리 사용하여 이미지 형태로 저장
  4. +
+

이미지 출력 방식의 경우 1번과 2번을 고민했었다.
+파이썬으로는 플롯을 그려주는 라이브러리인 matplotlib을 사용했다.

+

로컬에서 기능 구현

+
import time
+
+import matplotlib.pyplot as plt
+
+
+def draw(point):
+    start = time.time()
+    x, y = zip(*point)
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    draw_lines(pixel_x, pixel_y)
+    end = time.time()
+    print(end - start)
+    
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    return scaled_coordinates
+
+
+def draw_lines(x, y):
+    figure = plt.gcf()
+    figure.set_size_inches(5, 5)
+    plt.plot(x, y, c = 'w',linewidth=5)
+    plt.scatter(x[3],y[3], c = 'w', s = 125)
+    plt.axis('off')
+    plt.savefig('name.png', transparent=True, format='png')
+
+point = [
+    [126.96352960597338, 37.590841000217125],
+    [126.96987292787792, 37.58435564234159],
+    [126.98128481452298, 37.58594375113966],
+    [126.99360339342958, 37.58248524741927],
+    [126.99867565340067, 37.56778118088622],
+    [127.001935378366117, 37.55985240444085],
+    [126.9831048919687, 37.548030119488665],
+    [126.97189273528845, 37.5119879225856],
+    [127.02689859997221, 37.48488593333883]
+]
+
+draw(point)
+
+

생성 결과는 아래와 같다. (예시를 위해 검은색으로 출력)

+

./routeImage.png

+

AWS Lambda

+

썸네일 생성 서버를 따로 두기는 기능 대비 비용이 너무 클 것이라고 생각했다.
따라서 서버리스로 파일을 처리했다.
-추가로 s3 접근은 boto3를 사용했다.

람다 S3 접근을 위한 IAM 생성

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

람다 배포용 코드

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.


import io
import uuid

import boto3
import matplotlib.pyplot as plt

PIXEL = 255
BUCKET_NAME = 'image-plot'
S3 = 's3'

def lambda_handler(event, context):
x = event['x']
y = event['y']
image_name = str(uuid.uuid4())

img_data = draw(x, y)
s3 = boto3.client(S3)
s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'

return {
'statusCode': 200,
'body': url
}

def draw(x, y):
pixel_x, pixel_y = convert_to_pixel_values(x, y)
img_data = draw_lines(pixel_x, pixel_y)
plt.close()
return img_data

def convert_to_pixel_values(x, y):
max_diff = max(max(x) - min(x), max(y) - min(y))
return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)

def scale_to_pixel_values(points, max_diff):
min_value = min(points)
scaled_coordinates = [(p - min_value) / max_diff for p in points]
pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
return pixel_values

def draw_lines(x, y):
plt.plot(x, y, 'k-', linewidth=10)
plt.axis('off')
img_data = io.BytesIO()
plt.savefig(img_data, transparent=True, format='png')
img_data.seek(0)
return img_data

Layer 추가를 위한 zip 파일 생성

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
+추가로 s3 접근은 boto3를 사용했다.

+

람다 S3 접근을 위한 IAM 생성

+

AmazonS3FullAccess, AmazonS3ObjectLambdaExecutionRolePolicy 두가지를 추가해서 Lambda 전용 역할을 만들어 사용했다.

+

람다 배포용 코드

+

기술 구현 가능 여부를 확인할 땐 위치 점을 찍는 기능을 람다에 배포하지 않았다.

+

+import io
+import uuid
+
+import boto3
+import matplotlib.pyplot as plt
+
+PIXEL = 255
+BUCKET_NAME = 'image-plot'
+S3 = 's3'
+
+def lambda_handler(event, context):
+    x = event['x']
+    y = event['y']
+    image_name = str(uuid.uuid4())
+
+    img_data = draw(x, y)
+    s3 = boto3.client(S3)
+    s3.put_object(Body=img_data.getvalue(), ContentType='image/png', Bucket=BUCKET_NAME, Key=image_name)
+    url = f'https://{BUCKET_NAME}.s3.ap-northeast-2.amazonaws.com/{image_name}'
+
+    return {
+        'statusCode': 200,
+        'body': url
+    }
+
+def draw(x, y):
+    pixel_x, pixel_y = convert_to_pixel_values(x, y)
+    img_data = draw_lines(pixel_x, pixel_y)
+    plt.close()
+    return img_data
+
+def convert_to_pixel_values(x, y):
+    max_diff = max(max(x) - min(x), max(y) - min(y))
+    return scale_to_pixel_values(x, max_diff), scale_to_pixel_values(y, max_diff)
+
+def scale_to_pixel_values(points, max_diff):
+    min_value = min(points)
+    scaled_coordinates = [(p - min_value) / max_diff for p in points]
+    pixel_values = [int(p * PIXEL) for p in scaled_coordinates]
+    return pixel_values
+
+def draw_lines(x, y):
+    plt.plot(x, y, 'k-', linewidth=10)
+    plt.axis('off')
+    img_data = io.BytesIO()
+    plt.savefig(img_data, transparent=True, format='png')
+    img_data.seek(0)
+    return img_data
+
+
+

Layer 추가를 위한 zip 파일 생성

+

matplotlib의 경우 외부 라이브러리기 때문에 따로 Layer를 추가해야 한다.
zip 파일을 만들어서 업로드해야한다.
이때 python의 Lambda 런타임에 대한 계층 경로는 python이다.
-따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

pillow.zip
│ python/PIL
└ python/Pillow-5.3.0.dist-info

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

sudo apt update
sudo apt install zip
sudo apt install python3-pip

mkdir python
pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로

No module named 'numpy.core._multiarray_umath' 에러

Layer 추가 후 람다 실행 시 발생한 에러였다.
+따라서 압축한 zip 파일은 다음과 같은 구조를 띄어야 한다.

+
pillow.zip
+│ python/PIL
+└ python/Pillow-5.3.0.dist-info
+
+

Ubuntu 기준 다음 명령어를 입력하여 생성을 진행했다.

+
sudo apt update
+sudo apt install zip
+sudo apt install python3-pip
+
+mkdir python
+pip3 install matplotlib -t python # pip3 install 설치할_패키지 -t 설치_경로
+zip -r my_layer.zip python # zip -r 압축_파일명 압축_파일이_존재하는_경로
+
+

No module named 'numpy.core._multiarray_umath' 에러

+

Layer 추가 후 람다 실행 시 발생한 에러였다.
처음에 mac에서 zip 파일을 생성해서 업로드했는데 해당 문제가 발생했다.
이는 lambda가 돌아가는 동일한 환경에서 layer를 위한 zip 파일을 만들지 않아서 발생하는 문제다.
-간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

적정기술에 대한 생각

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
+간단하게 ec2 인스턴스를 하나 만들어서 따로 Layer를 생성하면 문제가 발생하지 않는다.

+

적정기술에 대한 생각

+

프로젝트에 Lambda와 Python을 사용하려고 했지만 아쉽게도 반려당했다.
AWS Lambda를 사용하는 것은 인스턴스에 해당 코드를 배포하는 것보다 더 효율적인 방법일 수 있다.
하지만 현재 프로젝트에서 가용 가능한 자원, 기술의 난이도, 사용하는 팀원을 고려한다면 Lambda는 적정기술이 아닐 수 있다.
-따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

최종적으로 Java AWT를 사용하기로 결정했다.

참고 자료

AWS Lambda
-Lambda Layer
-Python Lambda 함수에 대한 .zip 파일 아카이브 작업
-No module named 'numpy.core._multiarray_umath'
-사례별로 알아본 안전한 S3 사용 가이드

- - +따라서 해당 이미지 생성기를 어떻게 적용할지 조금 더 고려를 해야 될 것으로 보인다.

+

최종적으로 Java AWT를 사용하기로 결정했다.

+

참고 자료

+

AWS Lambda
+Lambda Layer
+Python Lambda 함수에 대한 .zip 파일 아카이브 작업
+No module named 'numpy.core._multiarray_umath'
+사례별로 알아본 안전한 S3 사용 가이드

\ No newline at end of file diff --git a/tags/replication.html b/tags/replication.html index a8c777e9d..2e266a066 100644 --- a/tags/replication.html +++ b/tags/replication.html @@ -2,8 +2,8 @@ - -"replication" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"replication" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,65 +12,440 @@ - - - + + + -
-

"replication" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 21분

복제(Replication)

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
-원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

복제를 하는 이유

1. 스케일 아웃

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
-이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

2. 데이터 백업

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
-따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

3. 데이터 분석

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
-마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

4. 데이터의 지리적 분산

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

바이너리 로그 파일 위치 기반 복제

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
+

"replication" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 21분

복제(Replication)

+

한 서버에서 다른 서버로 데이터를 동기화하는 것을 의미한다.
+원본 데이터를 가지는 서버를 Primary 또는 Source 라고 부르고, 복제된 데이터를 가지는 서버를 Secondary 또는 Replica 라고 부른다.

+

복제를 하는 이유

+

1. 스케일 아웃

+

사용자의 트래픽이 증가하는 경우, 데이터베이스에 가해지는 부하도 자연스럽게 증가한다.
+이를 처리하기 위해 복제를 통한 스케일 아웃을 적용하여 애플리케이션에서 사용하는 쿼리들을 각각의 데이터베이스로 분산 시킬 수 있다.

+

2. 데이터 백업

+

실제 운영되는 서비스가 사용하고 있는 DB에서 백업을 진행하는 경우, 서비스에 영향을 미칠 수 있다.
+따라서 실제 서비스에 영향이 가지 않도록 복제를 통해 Replica 서버를 구축하여, Replica 서버에서 복제를 진행하는 방법으로 영향을 최소화 할 수 있다.

+

3. 데이터 분석

+

백업과 마찬가지로 복잡하고 무거운 분석용 쿼리의 서비스에 영향을 미칠 수 있다.
+마찬가지로 복제를 사용해 분석용 쿼리를 사용할 수 있는 환경을 만들 수 있다.

+

4. 데이터의 지리적 분산

+

빠른 응답을 위해 애플리케이션 서버에 가깝게 서버를 구성하거나, 고가용성(High Availability)을 위해서도 사용된다.

+

바이너리 로그 파일 위치 기반 복제

+

MySQL 서버에서 발생하는 변경사항에 대한 로그 파일을 바이너리 로그라고 한다.
바이너리 로그를 통해 데이터 변경, 테이블 구조 변경, 계정이나 권한 변경에 대한 정보가 저장된다.
-MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

스레드별 역할

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
+MySQL의 복제는 바이너리 로그 기반으로 구현되어 있다. 이를 Replica 서버로 전달하고 바이너리 로그 기반으로 데이터를 변경 사항을 반영한다.

+ +

Binary Log Dump Thread: 바이너리 로그의 내용을 Replica 서버로 전달
Replication I/O Thread: Binary 로그 이벤트를 가져와 로컬 서버의 파일(Relay Log)로 저장
-Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

바이너리 로그 방식의 문제점

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
-토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
+Replication SQL Thread: 릴레이 로그 파일의 이벤트를 읽고 실행

+

바이너리 로그 방식의 문제점

+

바이너리 로그 방식은 서버에 장애가 발생했을 때 복제 토폴로지 변경이 까다롭다.
+토폴로지란 네트워크의 요소들을 물리적으로 연결해 놓은 것, 또는 그 연결 방식을 말한다.

+ +

위와 같이 Source 서버, Replica 2대가 존재하고, C 서버에 복제 지연이 되었을 때 문제가 발생한다.

+ +

A 서버에서 장애가 발생한다면 B 서버를 Source 서버로 승격하고, C에게 조회 쿼리를 분산시킨다.
하지만 여기서 C 서버에는 A 서버와 동기화가 안되었으니 조회 시 문제가 발생한다.
-뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

글로벌 트랜잭션 아이디(GTID) 기반 복제

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
-위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

GTID

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
-[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

복제 토폴로지

싱글 레플리카 복제 구성

가장 간단한 구성으로 제일 많이 사용하는 형태다.
-replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

멀티 레플리카 복제 구성

2개의 replica 서버를 사용하는 형태다.
+뒤늦게 B 서버와 동기화를 하려고 해도, 어떤 바이너리 로그, 어떤 위치와 동기화해야하는지 알기 어렵다.

+

글로벌 트랜잭션 아이디(GTID) 기반 복제

+

GTID 방식을 사용하여 참여한 모든 데이터베이스가 발생한 이벤트에 고유한 식별값을 부여한다면, 동기화에 대한 문제를 간단하게 해결할 수 있다.
+위의 예시와 같이 복제 지연과 함께 장애가 발생한다해도 특정 GTID 부터 복제를 재개하면 된다.

+

복제 토폴로지에 참여한 모든 서버에서 고유하도록 각 이벤트에 부여된 식별값
+[source_id]:[transaction_id]로 구성되며, source_id는 서버를 식별하기 위한 값이고 transaction_id는 커밋된 트랜잭션을 식별하기 위한 값으로 1씩 증가하는 형태로 발급된다.

+

복제 토폴로지

+

싱글 레플리카 복제 구성

+

가장 간단한 구성으로 제일 많이 사용하는 형태다.
+replica 서버를 읽기 전용, 예비 서버, 백업 용도로 많이 사용한다.

+ +

멀티 레플리카 복제 구성

+

2개의 replica 서버를 사용하는 형태다.
하나의 replica는 예비 용도로 남겨두는 형태다.
-추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

체인 복제 구성

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
-따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

듀얼 소스 복제 구성

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
+추후에 트래픽이 증가하는 경우 예비 용도의 replica를 사용함으로 읽기 요청의 부하 분산을 할 수 있다.

+ +

체인 복제 구성

+

replica 서버가 많은 경우 바이너리 로그를 전달하는 작업 자체가 부하가 될 수 있다.
+따라서 1:M:M 구조로 체인 복제 구성을 고려할 수 있다.

+ +

듀얼 소스 복제 구성

+

2개의 MySQL 서버 모두 읽기와 쓰기가 가능하도록 하는 구성이다.
각 서버에서 변경된 데이터는 다른 서버에 반영된다.
목적에 따라 ACTIVE-ACTIVE 형태 또는 ACTIVE-PASSIVE 형태로 사용할 수 있다.
-ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

ACTIVE-ACTIVE, ACTIVE-PASSIVE

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
-ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

멀티 소스 복제 구성

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
-이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

바이너리 로그 방식 Replication 구성하기

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
-https://github.com/bbiac/db-replication

MySQL 환경 구성

MySQL 버전은 8.1을 사용했다.
+ACTIVE-PASSIVE 형태인 경우 싱글 레플리카 복제 구성과 동일해보이지만, ACTIVE 서버에서 문제가 발생하면 설정의 변경없이 PASSIVE 서버로 쓰기 작업을 전환할 수 있다는 것이 장점이다.

+ +

ACTIVE-ACTIVE: 2개의 서버 모두 쓰기 작업을 수행하는 형태
+ACTIVE-PASSIVE: 하나의 서버에서만 쓰기 작업을 수행하는 형태

+

멀티 소스 복제 구성

+

여러개의 source 서버와 하나의 replica 서버를 사용하는 구성이다.
+이는 source 서버의 데이터를 한 곳에 백업하는 용도로 사용, 여러 서버에 존재하는 데이터를 통합, 샤딩되어있는 테이블 데이터를 통합할 때 사용한다.

+ +

바이너리 로그 방식 Replication 구성하기

+

mysql 2대를 이용하여 replication을 구성하고, spring boot application으로 source, replica 데이터베이스에 접근해보는 예제이다.
+https://github.com/bbiac/db-replication

+

MySQL 환경 구성

+

MySQL 버전은 8.1을 사용했다.
13306, 13307 포트를 사용해서 MySQL 서버 2대를 띄웠다.
-또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

version: '3.8'

services:
source:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-source
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13306:3306"
volumes:
- db-source:/var/lib/mysql
- db-source:/var/lib/mysql-files
- ./docker/source.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

replica:
platform: linux/x86_64
image: mysql:latest
restart: always
container_name: mysql-replica
environment:
TZ: 'Asia/Seoul'
MYSQL_DATABASE: 'db'
MYSQL_USER: 'user'
MYSQL_PASSWORD: 'password'
MYSQL_ROOT_PASSWORD: 'password'
ports:
- "13307:3306"
volumes:
- db-replica:/var/lib/mysql
- db-replica:/var/lib/mysql-files
- ./docker/replica.cnf:/etc/mysql/my.cnf
networks:
- mysql_network

volumes:
db-source:
db-replica:

networks:
mysql_network:
driver: bridge

또한 source, replica 각각 다음과 같이 db 설정을 했다.

설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
/docker/source.cnf
[mysqld]
server_id=1
log_bin=mysql-bin
sync_binlog=1

도커 실행

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
--d 옵션을 붙이면 백그라운드 모드로 실행된다.

docker-compose up -d

replication slave 권한 설정

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
-source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

SOURCE 접속

docker exec -it mysql-source mysql -u root -p

user 계정에 REPLICATION SLAVE 권한 추가

GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
FLUSH PRIVILEGES;

SOURCE DB 정보 확인

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
+또한 사실 IP 대역으로 통신할 수 있도록 커스텀 네트워크를 추가했다.

+
version: '3.8'
+
+services:
+  source:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-source
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13306:3306"
+    volumes:
+      - db-source:/var/lib/mysql
+      - db-source:/var/lib/mysql-files
+      - ./docker/source.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+  replica:
+    platform: linux/x86_64
+    image: mysql:latest
+    restart: always
+    container_name: mysql-replica
+    environment:
+      TZ: 'Asia/Seoul'
+      MYSQL_DATABASE: 'db'
+      MYSQL_USER: 'user'
+      MYSQL_PASSWORD: 'password'
+      MYSQL_ROOT_PASSWORD: 'password'
+    ports:
+      - "13307:3306"
+    volumes:
+      - db-replica:/var/lib/mysql
+      - db-replica:/var/lib/mysql-files
+      - ./docker/replica.cnf:/etc/mysql/my.cnf
+    networks:
+      - mysql_network
+
+volumes:
+  db-source:
+  db-replica:
+
+networks:
+  mysql_network:
+    driver: bridge
+
+

또한 source, replica 각각 다음과 같이 db 설정을 했다.

+
설정설명
server_id각각의 mysql 마다 고유한 값을 가져야 한다.
log_bin바이너리 로그 파일 경로 설정으로 절대경로를 사용하지 않는다면 /var/lib/mysql 아래 해당 log_bin에 설정된 값으로 로그가 생성된다.
sync_binlogN개의 트랜잭션 당 바이너리 로그를 디스크와 동기화 작업을 하도록 한다. 1은 기본값으로 안정적이지만, 가장 느리다.
relay_log릴레이 로그 파일 경로 설정
relay_log_purge필요 없는 릴레이 로그 파일을 자동으로 삭제하는 옵션
read_only읽기 전용 설정
log_replica_updatesReplication SQL Thread로 인해 실행되는 정보를 바이너리 로그에 기록 추후에 소스 서버로 승격되는 경우를 고려하면 설정하는 것이 좋다.
+ + +
[mysqld]
+server_id=1
+log_bin=mysql-bin
+sync_binlog=1
+
+

도커 실행

+

docker-compose up 명령어로 docker-compose 설정으로 docker를 띄운다.
+-d 옵션을 붙이면 백그라운드 모드로 실행된다.

+
docker-compose up -d
+
+

replication slave 권한 설정

+

REPLICATION SLAVE 권한이 설정되어 있어야 replica 서버에서 source 서버에 접근하여 로그를 읽어올 수 있다.
+source 서버에 접근하여 user 계정에 해당 권한을 설정해준다.

+

SOURCE 접속

+
docker exec -it mysql-source mysql -u root -p
+
+

user 계정에 REPLICATION SLAVE 권한 추가

+
GRANT REPLICATION SLAVE ON *.* TO 'user'@'%';
+FLUSH PRIVILEGES;
+
+

SOURCE DB 정보 확인

+

replica 설정에 필요한 source db의 바이너리 로그 파일명과 Position을 확인한다.
Position 값은 실제 파일의 바이트 수를 의미한다.
-확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 1082 | | | |
+------------------+----------+--------------+------------------+-------------------+

SOURCE ip 주소 확인

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
-다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
-확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

replica mysql 접속

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

docker exec -it mysql-replica mysql -u root -p

replica 설정

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
+확인한 File(SOURCE_LOG_FILE)과 Position(SOURCE_LOG_POS) 값은 replica 설정에서 사용한다.

+
SHOW MASTER STATUS;
+
++------------------+----------+--------------+------------------+-------------------+
+| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
++------------------+----------+--------------+------------------+-------------------+
+| mysql-bin.000003 |     1082 |              |                  |                   |
++------------------+----------+--------------+------------------+-------------------+
+
+

SOURCE ip 주소 확인

+

docker inspect -f 옵션을 사용하면 해당 컨테이너의 세부 정보를 확인할 수 있다.
+다음 명령어를 이용해 docker-compose 파일에 설정해둔 mysql_network에서 사용되는 사설 아이피 주소를 확인한다.

+
docker inspect -f "{{with index .NetworkSettings.Networks \"db-replication_mysql_network\"}}{{.IPAddress}}{{end}}" mysql-source
+
+

ip 주소가 나오지 않는 경우 docker inspect mysql-source로 확인한다.
+확인한 IP주소(SOURCE_HOST) 값은 replica 설정에서 사용한다.

+

replica mysql 접속

+

source db에 접속했던 방법과 동일하게 replica db에 접속한다.

+
docker exec -it mysql-replica mysql -u root -p
+
+

replica 설정

+

이전에 source db에서 얻었던 정보들을 사용하여 replica 설정을 진행한다.
실제 DB 서버에서 복제하는 경우 추가적으로 source DB의 파일을 복제해야하지만 현재 복제할 데이터가 없기 때문에 해당 부분은 생략했다.
-SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

STOP REPLICA;

CHANGE REPLICATION SOURCE TO
SOURCE_HOST='172.29.0.2',
SOURCE_USER='user',
SOURCE_PASSWORD='password',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=0,
GET_SOURCE_PUBLIC_KEY=1;

START REPLICA;

설정 확인

SHOW REPLICA STATUS;

+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Replica_IO_State | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File | Read_Source_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID | Source_Info_File | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
| Waiting for source to send event | 172.25.0.3 | user | 3306 | 60 | mysql-bin.000003 | 1082 | mysql-relay-bin.000002 | 868 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 1082 | 1078 | None | | 0 | No | | | | | | 0 | No | 0 | | 0 | | | 1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info | 0 | NULL | Replica has read all relay log; waiting for more updates | 86400 | | | | | | | | 0 | | | | | 1 | |
+----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
-replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

CREATE TABLE member
(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);

스프링 부트로 DB 접근하기

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

Environment 설정

다음과 같이 source, replica로 구분하여 설정한다.

application.yml
spring:
datasource:
source:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13306/db
replica:
username: user
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:13307/db

DataSourceType 설정

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
-Key는 추후에 빈 설정에 사용한다.

DataSourceType
public enum DataSourceType {
SOURCE(SOURCE_NAME),
REPLICA(REPLICA_NAME),
;

private final String key;

DataSourceType(String key) {
this.key = key;
}

public static class Key {
public static final String ROUTING_NAME = "ROUTING";
public static final String SOURCE_NAME = "SOURCE";
public static final String REPLICA_NAME = "REPLICA";
}
}

AbstractRoutingDataSource 설정

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
RoutingDataSource
public class RoutingDataSource extends AbstractRoutingDataSource {

private final Logger log = LoggerFactory.getLogger(getClass());

public static RoutingDataSource from(Map<Object, Object> dataSources) {
RoutingDataSource routingDataSource = new RoutingDataSource();
routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
routingDataSource.setTargetDataSources(dataSources);
return routingDataSource;
}

@Override
protected Object determineCurrentLookupKey() {
boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();

if (readOnly) {
log.info("readOnly = true, request to replica");
return DataSourceType.REPLICA;
}
log.info("readOnly = false, request to source");
return DataSourceType.SOURCE;
}
}

DataSource 설정

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
+SOURCE_HOST, SOURCE_LOG_FILE, SOURCE_LOG_POS 를 적절히 변경한다.

+
STOP REPLICA;
+
+CHANGE REPLICATION SOURCE TO 
+SOURCE_HOST='172.29.0.2', 
+SOURCE_USER='user', 
+SOURCE_PASSWORD='password', 
+SOURCE_LOG_FILE='mysql-bin.000001', 
+SOURCE_LOG_POS=0, 
+GET_SOURCE_PUBLIC_KEY=1;
+
+START REPLICA;
+
+

설정 확인

+
SHOW REPLICA STATUS;
+
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Replica_IO_State                 | Source_Host | Source_User | Source_Port | Connect_Retry | Source_Log_File  | Read_Source_Log_Pos | Relay_Log_File         | Relay_Log_Pos | Relay_Source_Log_File | Replica_IO_Running | Replica_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Source_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Source_SSL_Allowed | Source_SSL_CA_File | Source_SSL_CA_Path | Source_SSL_Cert | Source_SSL_Cipher | Source_SSL_Key | Seconds_Behind_Source | Source_SSL_Verify_Server_Cert | Last_IO_Errno | Last_IO_Error | Last_SQL_Errno | Last_SQL_Error | Replicate_Ignore_Server_Ids | Source_Server_Id | Source_UUID                          | Source_Info_File        | SQL_Delay | SQL_Remaining_Delay | Replica_SQL_Running_State                                | Source_Retry_Count | Source_Bind | Last_IO_Error_Timestamp | Last_SQL_Error_Timestamp | Source_SSL_Crl | Source_SSL_Crlpath | Retrieved_Gtid_Set | Executed_Gtid_Set | Auto_Position | Replicate_Rewrite_DB | Channel_Name | Source_TLS_Version | Source_public_key_path | Get_Source_public_key | Network_Namespace |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+| Waiting for source to send event | 172.25.0.3  | user        |        3306 |            60 | mysql-bin.000003 |                1082 | mysql-relay-bin.000002 |           868 | mysql-bin.000003      | Yes                | Yes                 |                 |                     |                    |                        |                         |                             |          0 |            |            0 |                1082 |            1078 | None            |                |             0 | No                 |                    |                    |                 |                   |                |                     0 | No                            |             0 |               |              0 |                |                             |                1 | 5a396b02-41c6-11ee-a56d-0242ac190003 | mysql.slave_master_info |         0 |                NULL | Replica has read all relay log; waiting for more updates |              86400 |             |                         |                          |                |                    |                    |                   |             0 |                      |              |                    |                        |                     1 |                   |
++----------------------------------+-------------+-------------+-------------+---------------+------------------+---------------------+------------------------+---------------+-----------------------+--------------------+---------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+-------------------------------+---------------+---------------+----------------+----------------+-----------------------------+------------------+--------------------------------------+-------------------------+-----------+---------------------+----------------------------------------------------------+--------------------+-------------+-------------------------+--------------------------+----------------+--------------------+--------------------+-------------------+---------------+----------------------+--------------+--------------------+------------------------+-----------------------+-------------------+
+
+

Replica_IO_Running, Replica_SQL_Running 값이 YES라면 정상적으로 replication 구성이 완료된 것이다.

+

설정을 마친 후 source db에 다음과 같이 create table 명령어를 입력한다.
+replica db에 동일한 member table이 생성된 것을 확인할 수 있다.

+
CREATE TABLE member
+(
+    id   BIGINT PRIMARY KEY AUTO_INCREMENT,
+    name VARCHAR(255)
+);
+
+

스프링 부트로 DB 접근하기

+

일반적인 트랜잭션의 경우 source, 읽기 전용 트랜잭션인 경우 replica로 요청이 가도록 구성해보자.

+

Environment 설정

+

다음과 같이 source, replica로 구분하여 설정한다.

+
spring:
+  datasource:
+    source:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13306/db
+    replica:
+      username: user
+      password: password
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      jdbc-url: jdbc:mysql://localhost:13307/db
+
+

DataSourceType 설정

+

단순 문자열로도 구분할 수 있지만, enum을 이용해서 트랜잭션을 구분하도록 생성한다.
+Key는 추후에 빈 설정에 사용한다.

+
public enum DataSourceType {
+    SOURCE(SOURCE_NAME),
+    REPLICA(REPLICA_NAME),
+    ;
+
+    private final String key;
+
+    DataSourceType(String key) {
+        this.key = key;
+    }
+
+    public static class Key {
+        public static final String ROUTING_NAME = "ROUTING";
+        public static final String SOURCE_NAME = "SOURCE";
+        public static final String REPLICA_NAME = "REPLICA";
+    }
+}
+
+

AbstractRoutingDataSource 설정

+

스프링이 지원해주는 AbstractRoutingDataSource를 상속받아 트랜잭션의 읽기 여부에 따라 다른 DataSource를 향하도록 설정한다.

+

정적 팩터리 메서드는 Map<DataSourceKey, DataSource>에 해당하는 값을 받아 데이터 소스를 설정한다.

+
    +
  • setDefaultTargetDataSource: 기본 데이터 소스를 설정한다.
  • +
  • setTargetDataSources: 맵 형태로 받은 데이터 소스 값들을 설정한다.
  • +
+

determineCurrentLookupKey를 오버라이딩하여 트랜잭션의 읽기 여부에 따라 다른 DataSourceType을 반환하도록 설정한다.

+
    +
  • isCurrentTransactionReadOnly() 메서드를 통해 트랜잭션이 읽기 전용인지 확인할 수 있다.
  • +
  • DataSourceType을 반환하도록 설정하고, 반환한 값에 해당하는 데이터 소스가 사용된다.
  • +
+
public class RoutingDataSource extends AbstractRoutingDataSource {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    public static RoutingDataSource from(Map<Object, Object> dataSources) {
+        RoutingDataSource routingDataSource = new RoutingDataSource();
+        routingDataSource.setDefaultTargetDataSource(dataSources.get(DataSourceType.SOURCE));
+        routingDataSource.setTargetDataSources(dataSources);
+        return routingDataSource;
+    }
+
+    @Override
+    protected Object determineCurrentLookupKey() {
+        boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
+
+        if (readOnly) {
+            log.info("readOnly = true, request to replica");
+            return DataSourceType.REPLICA;
+        }
+        log.info("readOnly = false, request to source");
+        return DataSourceType.SOURCE;
+    }
+}
+
+

DataSource 설정

+

위에서부터 순서대로 Source, Replica, RoutingDataSource, LazyConnectionDataSourceProxy 설정이다.
스프링은 트랜잭션 시작시에 커넥션의 사용여부와 상관없이 커넥션을 확보한다.
-따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

DataSourceConfiguration
@Configuration
public class DataSourceConfiguration {

@Bean
@Qualifier(SOURCE_NAME)
@ConfigurationProperties(prefix = "spring.datasource.source")
public DataSource sourceDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(REPLICA_NAME)
@ConfigurationProperties(prefix = "spring.datasource.replica")
public DataSource replicaDataSource() {
return DataSourceBuilder.create().build();
}

@Bean
@Qualifier(ROUTING_NAME)
public DataSource routingDataSource(
@Qualifier(SOURCE_NAME) DataSource sourceDataSource,
@Qualifier(REPLICA_NAME) DataSource replicaDataSource
) {
return RoutingDataSource.from(Map.of(
DataSourceType.SOURCE, sourceDataSource,
DataSourceType.REPLICA, replicaDataSource
));
}

@Bean
@Primary
public DataSource dataSource(
@Qualifier(ROUTING_NAME) DataSource routingDataSource
) {
return new LazyConnectionDataSourceProxy(routingDataSource);
}
}

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

동작 확인

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
+따라서 readOnly 트랜잭션이 설정된 메서드를 사용하더라도 미리 확보된 커넥션을 사용하기 때문에 replica db로 요청을 하지 않고 source db로 요청을 한다.

+

TransactionSynchronizationManager.isCurrentTransactionReadOnly() 메서드 호출 시 currentTransactionReadOnly라는 ThreadLocal<Boolean>에 설정된 값을 반환하는데 readOnly 설정이 되면 이 값을 true로 설정한다. 하지만 determineCurrentLookupKey를 호출하여 key 값을 가져오는 부분보다 이후에 설정되기 때문에 determineCurrentLookupKey 메서드에서 항상 DataSourceType.SOURCE가 반환되어 source db로 요청을 한다.

+

LazyConnectionDataSourceProxy를 설정하는 경우 실제 DataSource를 사용하는 시점에 커넥션을 획득해서 사용하기 때문에 설정한대로 replica db로 조회 요청을 한다.

+
@Configuration
+public class DataSourceConfiguration {
+
+    @Bean
+    @Qualifier(SOURCE_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.source")
+    public DataSource sourceDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(REPLICA_NAME)
+    @ConfigurationProperties(prefix = "spring.datasource.replica")
+    public DataSource replicaDataSource() {
+        return DataSourceBuilder.create().build();
+    }
+
+    @Bean
+    @Qualifier(ROUTING_NAME)
+    public DataSource routingDataSource(
+            @Qualifier(SOURCE_NAME) DataSource sourceDataSource,
+            @Qualifier(REPLICA_NAME) DataSource replicaDataSource
+    ) {
+        return RoutingDataSource.from(Map.of(
+                DataSourceType.SOURCE, sourceDataSource,
+                DataSourceType.REPLICA, replicaDataSource
+        ));
+    }
+
+    @Bean
+    @Primary
+    public DataSource dataSource(
+            @Qualifier(ROUTING_NAME) DataSource routingDataSource
+    ) {
+        return new LazyConnectionDataSourceProxy(routingDataSource);
+    }
+}
+
+

최종적으로 DataSource 빈은 다음과 같은 형태가 된다.

+ +

동작 확인

+

간단하게 테스트를 작성해서 설정한대로 동작이 되는지 확인해보았다.
save 메서드의 경우 @Transactional, findById 메서드의 경우 @Transactional(readOnly = true)가 설정되어있다.
-로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

MemberServiceTest
@SpringBootTest
class MemberServiceTest {

@Autowired
private MemberService memberService;

@Test
void 사용자를_저장한다() {
// RoutingDataSource log: readOnly = false
memberService.save("bbiac");
}

@Test
void 사용자를_조회한다() {
// RoutingDataSource log: readOnly = true
assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
.isInstanceOf(NoSuchElementException.class);
}
}

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

SET GLOBAL log_output = 'table';
SET GLOBAL general_log = 1;

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
-server_id, 실행한 쿼리문을 확인할 수 있다.

SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';

+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user_host | thread_id | server_id | convert(argument using utf8) |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
| user[user] @ [172.25.0.1] | 277 | 2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
+----------------------------+-----------+-----------+-----------------------------------------------------------------------------+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

SET GLOBAL general_log = 0;
SHOW VARIABLES LIKE '%general%';

+------------------+---------------------------------+
| Variable_name | Value |
+------------------+---------------------------------+
| general_log | OFF |
| general_log_file | /var/lib/mysql/4b6b9db98290.log |
+------------------+---------------------------------+

참고 자료

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
-Replication, MySQL Docs
-MySql - Master Slave Replication 구조 만들어보기
-Spring 레플리케이션 트랜잭션 처리 방식
-replication-datasource
-Simplified Guide to MySQL Replication with Docker Compose
-Dockerfile에서 자주 쓰이는 명령어
-CHANGE REPLICATION SOURCE TO Statement
-LazyConnectionDataSourceProxy
-데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
-부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
-Use Docker Compose, Docker

- - +로그를 통해 save의 경우 source db로 findById의 경우 replica db로 요청을 하는 것을 알 수 있다.

+
@SpringBootTest
+class MemberServiceTest {
+
+    @Autowired
+    private MemberService memberService;
+
+    @Test
+    void 사용자를_저장한다() {
+        // RoutingDataSource log: readOnly = false
+        memberService.save("bbiac");
+    }
+
+    @Test
+    void 사용자를_조회한다() {
+        // RoutingDataSource log: readOnly = true
+        assertThatThrownBy(() -> memberService.findById(MAX_VALUE))
+                .isInstanceOf(NoSuchElementException.class);
+    }
+}
+
+

DB에서는 확인하려면 root 계정으로 접속한 후 general log를 활성화 시킨다.

+
SET GLOBAL log_output = 'table';
+SET GLOBAL general_log = 1;
+
+

general log를 활성화 한 후 읽기 전용 메서드를 실행한다.
+server_id, 실행한 쿼리문을 확인할 수 있다.

+
SELECT user_host, thread_id, server_id, convert(argument using utf8) FROM mysql.general_log where argument like '%select%';
+
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user_host                  | thread_id | server_id | convert(argument using utf8)                                                |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+| user[user] @  [172.25.0.1] |       277 |         2 | select m1_0.id,m1_0.name from member m1_0 where m1_0.id=9223372036854775807 |
++----------------------------+-----------+-----------+-----------------------------------------------------------------------------+
+
+

확인 후 general log를 비활성화 한 후 비활성화 되었는지 확인한다.

+
SET GLOBAL general_log = 0;
+SHOW VARIABLES LIKE '%general%';
+
++------------------+---------------------------------+
+| Variable_name    | Value                           |
++------------------+---------------------------------+
+| general_log      | OFF                             |
+| general_log_file | /var/lib/mysql/4b6b9db98290.log |
++------------------+---------------------------------+
+
+

참고 자료

+

16장 복제, Real MySQL 8.0 - 백은빈, 이성욱
+Replication, MySQL Docs
+MySql - Master Slave Replication 구조 만들어보기
+Spring 레플리케이션 트랜잭션 처리 방식
+replication-datasource
+Simplified Guide to MySQL Replication with Docker Compose
+Dockerfile에서 자주 쓰이는 명령어
+CHANGE REPLICATION SOURCE TO Statement
+LazyConnectionDataSourceProxy
+데이터베이스 레플리케이션을 통한 쿼리 성능 개선 (feat. Mysql, SpringBoot)
+부하 분산을 위한 MySQL Replication 구성 및 쿼리 요청 분기
+Use Docker Compose, Docker

\ No newline at end of file diff --git a/tags/retrospective.html b/tags/retrospective.html index 986f7192e..2dcb5bc29 100644 --- a/tags/retrospective.html +++ b/tags/retrospective.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,34 +12,66 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 9분

리팩터링 미션

요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.
-미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.

1, 2단계

1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. +

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 9분

1단계: https://github.com/woowacourse/jwp-refactoring/pull/465
+2단계: https://github.com/woowacourse/jwp-refactoring/pull/547
+3단계: https://github.com/woowacourse/jwp-refactoring/pull/610
+4단계: https://github.com/woowacourse/jwp-refactoring/pull/721

+

리팩터링 미션

+

요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.
+미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.

+

1, 2단계

+

1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. 요구사항을 작성할 때 제공된 용어 사전을 최대한 활용하면서 기존의 코드를 보면서 요구사항을 정리했다. -테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.

최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.
-리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.

2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.
+테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.

+

최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.
+리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.

+

2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.
서비스에서 도메인을 직접 반환하는 구조였는데, 도메인에 JPA를 적용하면 기존 명세와 달라질 것을 우려해서 DTO로 수정하는 작업을 먼저 진행했다. DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최종적으로 JPA를 적용하는 순서로 리팩터링을 진행했다. -이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.

소프트웨어의 복잡성을 다루는 지혜

중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.
-소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 도메인 주도 설계의 부제이다.

도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.
-유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.

간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.

단어설명
도메인소프트웨어로 해결하고자 하는 문제 영역
바운디드 컨텍스트해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위
유비쿼터스 언어프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어
전략적 설계도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정
전술적 설계전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정

이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.

3, 4단계

제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.

3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. -함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.

의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. -처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.

4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.
+이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.

+

소프트웨어의 복잡성을 다루는 지혜

+

중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.
+소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 도메인 주도 설계의 부제이다.

+

도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.
+유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.

+

간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.

+
단어설명
도메인소프트웨어로 해결하고자 하는 문제 영역
바운디드 컨텍스트해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위
유비쿼터스 언어프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어
전략적 설계도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정
전술적 설계전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정
+

이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.

+

3, 4단계

+

제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.

+

3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. +함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.

+

의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. +처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.

+

4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.
3단계에서는 함께 생성되고 삭제되는 객체 기준으로 분리했다. 4단계에서는 내가 인식하기 편한 기준으로 분리를 했다. -아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.

추가로 테스트 격리를 위한 @ServiceTest 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. -따라서 TestFixtures를 사용하여 해결했다.

마무리

우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.
-바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.

참고 자료

도메인 원정대, 우아콘 2021
-우아한객체지향, 우아한테크세미나
-TestFixtures, 권남님

- - +아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.

+ +

추가로 테스트 격리를 위한 직접 작성한 @ServiceTest 커스텀 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. +따라서 TestFixtures를 사용하여 해결했다.

+

마무리

+

우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.
+바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.

+

참고 자료

+

도메인 원정대, 우아콘 2021
+우아한객체지향, 우아한테크세미나
+TestFixtures, 권남님

\ No newline at end of file diff --git a/tags/retrospective/page/10.html b/tags/retrospective/page/10.html index e2311954d..c3258c63d 100644 --- a/tags/retrospective/page/10.html +++ b/tags/retrospective/page/10.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,35 +12,86 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

지하철 미션

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

1단계: https://github.com/woowacourse/jwp-subway-path/pull/16
+2, 3단계: https://github.com/woowacourse/jwp-subway-path/pull/126

+

지하철 미션

+

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
지하철 미션은 밀리랑 페어를 진행했다.
간단한 CRUD만 있던 이전 미션들과 달리, 조금 복잡한 도메인 요구사항이 있었다.
이때 API, 테이블, 도메인 설계를 해야 했는데 어떤 것부터 해야 할지 고민을 많이 했다.
-API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

노선의 구간 추가 및 삭제

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. 변경된 요소만 데이터베이스에 반영하는 방법

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
-추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

부족했던 부분

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
+API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

+

노선의 구간 추가 및 삭제

+

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

+
    +
  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. +
  3. 변경된 요소만 데이터베이스에 반영하는 방법
  4. +
+

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
+추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

+

부족했던 부분

+

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
우아한테크코스를 진행하면서 알아야 하는 게 많아지면서 가끔 조바심을 가질 때가 있는 것 같은데, 조바심을 경계할 필요가 있을 것 같다.
-부족한 부분은 인정하고, 앞으로 나아가야겠다.

새로 학습한 부분

컴포지트 패턴으로 요금 정책 추상화

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
+부족한 부분은 인정하고, 앞으로 나아가야겠다.

+

새로 학습한 부분

+

컴포지트 패턴으로 요금 정책 추상화

+

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
요금을 더하는 부분과, 할인하는 부분이 있어서 이 둘을 분리할까 생각했지만, 이 정도 크기의 애플리케이션에서는 오히려 분리하지 않고 하나로 합치는 게 더 좋다고 생각했다.
-또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

도메인에 특정 기술의 의존성을 분리

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
+또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

+

도메인에 특정 기술의 의존성을 분리

+

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
따라서 도메인 패키지 내에는 경로 검색에 대한 인터페이스를 두고, 세부 구현은 도메인 패키지 외부로 분리했다.
-최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

컴포지트 패턴

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

인수 테스트 작성

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
+최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

+

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
+이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

+

인수 테스트 작성

+

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
브라운이 해주신 강의 + 유튜브에 있는 브라운의 강의를 보고 지하철 미션에 인수 테스트를 적용해 보았다.
메서드, 변수명을 전부 한글로 작성했는데 전체적인 흐름을 알기 편하고 읽기도 좋았다.
-그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

결과는 아래와 같다.

@Nested
public class 노선을_전체_조회할_때 {

@Test
void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
// given
노선_생성_요청("2호선", "초록", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);

노선_생성_요청("9호선", "고동", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);

// when
final var 조회_결과 = 노선_전체_조회_요청();

// then
요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
노선_전체_조회_결과를_확인한다(
조회_결과,
노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
);
}
}

페어에게 배울 부분

의견 조율하기

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
-의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

꼼꼼하게 코딩하기

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
+그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

+

결과는 아래와 같다.

+
@Nested
+public class 노선을_전체_조회할_때 {
+
+    @Test
+    void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
+        // given
+        노선_생성_요청("2호선", "초록", 0);
+        노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
+        구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);
+
+        노선_생성_요청("9호선", "고동", 0);
+        노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
+        구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);
+
+        // when
+        final var 조회_결과 = 노선_전체_조회_요청();
+
+        // then
+        요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
+        노선_전체_조회_결과를_확인한다(
+                조회_결과,
+                노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
+                노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
+        );
+    }
+}
+
+

페어에게 배울 부분

+

의견 조율하기

+

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
+의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

+

꼼꼼하게 코딩하기

+

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
변수명, 메서드명을 중요하게 생각했고, 좋은 변수명을 잘 짓는 것 같다.
-또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

편한 분위기

전체적으로 페어 할 때 편하게 진행했던 것 같다.
+또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

+

편한 분위기

+

전체적으로 페어 할 때 편하게 진행했던 것 같다.
일정도 그렇고, 페어 진행할 때도 그렇고 큰 문제가 없었던 것 같아서 좋았다.
나는 과연 다른 사람들에게 편한 사람일까?

- - \ No newline at end of file diff --git a/tags/retrospective/page/11.html b/tags/retrospective/page/11.html index 989ffaff9..4b0d810bb 100644 --- a/tags/retrospective/page/11.html +++ b/tags/retrospective/page/11.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,28 +12,47 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

웹 장바구니 미션

장바구니 미션은 블랙캣이랑 진행했다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

1단계: https://github.com/woowacourse/jwp-shopping-cart/pull/244
+2단계: https://github.com/woowacourse/jwp-shopping-cart/pull/300

+

웹 장바구니 미션

+

장바구니 미션은 블랙캣이랑 진행했다.
요구사항이 엄청 복잡한 미션은 아니었고, 스프링을 사용하여 기본적인 CRUD를 구현하는 미션이었다.
2단계에서는 Basic 인증을 통해 자신의 장바구니에만 상품을 담고, 제거할 수 있도록 구현하는 요구사항이 추가되었다.
Interceptor나 Argument Resolver에 대한 이해도가 높지 않았는데, 이번 미션을 통해 조금 더 알아간 느낌이다.
-이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

새로 학습한 부분

DTO 우발적 중복

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

dto1

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
-따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

dto2

Interceptor에서 인증한 값 재사용

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
-일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
+이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

+

새로 학습한 부분

+

DTO 우발적 중복

+

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

+

dto1

+

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
+로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

+
    +
  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • +
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.
  • +
+

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
+따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

+

dto2

+

Interceptor에서 인증한 값 재사용

+

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
+일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

+

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
웨지는 email에 index를 걸어두고 dao 재조회를 사용할 것이라고 했다.
-재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

페어에게 배울 부분

기록

블랙캣은 기록을 굉장히 잘 하는 크루였다.
+재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

+

페어에게 배울 부분

+

기록

+

블랙캣은 기록을 굉장히 잘 하는 크루였다.
노션에 페어를 진행하면서 했던 내용 + 고민했던 부분 + 회고를 꼼꼼하게 기록해서 공유해 주었다.
-추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

의견 일치시키기

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
+추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

+

의견 일치시키기

+

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
따라서 적당히 타협을 봐서 의견을 빠르게 수용해 데드라인을 맞추는 것도 중요하다고 생각한다.
-블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

- - +블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

+

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

\ No newline at end of file diff --git a/tags/retrospective/page/12.html b/tags/retrospective/page/12.html index bd07e4187..932fa3603 100644 --- a/tags/retrospective/page/12.html +++ b/tags/retrospective/page/12.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,50 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

웹 자동차 미션

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

1단계: https://github.com/woowacourse/jwp-racingcar/pull/24
+2단계: https://github.com/woowacourse/jwp-racingcar/pull/128

+

웹 자동차 미션

+

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
웹 자동차 미션에서는 비버와 페어가 매칭되었다.
-레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
-첫 미션이라 그런지 특별한 부분은 없었고, 최대한 깔끔하게 작성하려고 노력했다.
+레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

+

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
+첫 미션이라 그런지 특별한 부분은 없었고, 최대한 깔끔하게 작성하려고 노력했다.
난이도 높은 미션이 아니었지만 리뷰어인 라빈에게 칭찬을 많이 받아서 기분이 좋았다.
-라빈 감사합니다!

부족했던 부분

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
+라빈 감사합니다!

+

부족했던 부분

+

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
미션이 다소 여유롭다고 느껴져서, 시간에 대한 부분도 잘 관리하지 못한 것 같다.
-미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
+미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

+

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
도전적이지 않거나 시간이 부족하지 않으면 집중을 잘 못하는 것 같다.
-머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

새로 학습한 부분

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@Transactional
@AutoConfigureMockMvc
@SpringBootTest
public class RacingGameIntegrationTest {

페어에게 배울 부분

비버의 성격
+머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

+

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

+

새로 학습한 부분

+

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

+
@SuppressWarnings("NonAsciiCharacters")
+@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
+@Transactional
+@AutoConfigureMockMvc
+@SpringBootTest
+public class RacingGameIntegrationTest {
+
+

페어에게 배울 부분

+

비버의 성격
비버가 성격이 좋아서 편하게 페어를 할 수 있었다.
-미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

미션에 집중하는 부분
+미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

+

미션에 집중하는 부분
내가 미션에 잘 집중하지 못했는데도 같이 페어를 잘 진행한 것 같아서 좋았다.
비버가 미션에 잘 집중해서 그렇지 않았나 생각했다.
-근육맨 비버라 그런지 체력이 좋아서 그런가?
-중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

학습에 대한 열정
+근육맨 비버라 그런지 체력이 좋아서 그런가?
+중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

+

학습에 대한 열정
추가적으로 알고 싶은 부분을 따로 학습하는 열정이 좋다고 생각했다.
비버와 스프링에 대해 알아가는 시간을 많이 가진 부분이 매우 좋았다.
나도 5월부터 조금 더 화이팅 해야겠다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/13.html b/tags/retrospective/page/13.html index 3e37d186d..85e823c21 100644 --- a/tags/retrospective/page/13.html +++ b/tags/retrospective/page/13.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,32 +12,55 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

프론트엔트

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

프론트엔트

+

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
추가로 채팅을 이어나갈 수 있게 하는 기능도 추가했다.
자잘하게 신경 쓸 부분이 많아서, 프론트엔드 하는 사람들이 대단하다고 생각되었다.
-여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

백엔드

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
+여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

+

백엔드

+

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
말랑이 한 부분이 너무 많아서 내가 못 따라가는 것 같다.
-나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

Http Request Header

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
+나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

+

Http Request Header

+

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
말랑이 한글은 안된다고 말해줘서 Base64로 인코딩하고, 백엔드에서 디코딩 하여 사용하기로 했다.
-아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

const encodedName = () => {
const uriComponent = unescape(encodeURIComponent(name.value));
return btoa(uriComponent);
};

Elastic Beanstalk

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
+아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

+
const encodedName = () => {
+  const uriComponent = unescape(encodeURIComponent(name.value));
+  return btoa(uriComponent);
+};
+
+

Elastic Beanstalk

+

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
Elastic Beanstalk를 사용하면 인프라에 대해 잘 알지 못해도 애플리케이션을 빠르게 배포하고 관리할 수 있다.
-모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

Elastic Beanstalk RDS 설정 후 분리

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
+모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

+

Elastic Beanstalk RDS 설정 후 분리

+

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
RDS 분리 시 Beanstalk에 기본적으로 설정되어 있는 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD와 같은 환경 변수가 같이 제거된다.
-추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

Elastic Beanstalk nginx 설정

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

Jenkins

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
-작년에 확인했을 땐 2022년 12월 31일까지 EC2 ARM 기반 t4g.small이 무료였는데, 다시 들어가 보니 2023년까지 12월 31일까지 t4g.small을 무료로 사용할 수 있었다.
+추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

+

Elastic Beanstalk nginx 설정

+

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

+

Jenkins

+

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
+작년에 확인했을 땐 2022년 12월 31일까지 EC2 ARM 기반 t4g.small이 무료였는데, 다시 들어가 보니 2023년까지 12월 31일까지 t4g.small을 무료로 사용할 수 있었다.
t4g.small은 램이 2G인데, 예전에는 부족하지 않았다고 생각했는데 Java 17을 써서 그런가 빌드 할 때 램이 많이 부족한 것 같아서 Swap 메모리 2기가를 추가로 설정했다.
-추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

test {
maxHeapSize = "1024m"
}

Jenkins Blue Ocean

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
+추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

+
test {
+    maxHeapSize = "1024m"
+}
+
+

Jenkins Blue Ocean

+

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
시각화도 잘 되어있고, 설정도 편리한 것 같다.
-오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

참고 자료

Elastic Beanstalk, AWS
-EC2 AWS Graviton, AWS
-Default Memory Settings, AWS

- - +오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

+

참고 자료

+

Elastic Beanstalk, AWS
+EC2 AWS Graviton, AWS
+Default Memory Settings, AWS

\ No newline at end of file diff --git a/tags/retrospective/page/14.html b/tags/retrospective/page/14.html index a26b8c62c..9de02540c 100644 --- a/tags/retrospective/page/14.html +++ b/tags/retrospective/page/14.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,36 +12,64 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

4월 21일 금요일

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

4월 21일 금요일

+

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
레벨 3, 4에서 나만의 강점을 가지고 싶어 고민을 많이 했다.
단순히 스프링을 깊게 공부하는 건 효율이 많이 떨어진다고 생각했다.
-글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
-Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
-프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

이건 못참지

도메인 구입 성공?

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
+글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

+

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
+Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

+

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
+프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

+

이건 못참지

+

도메인 구입 성공?

+

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
마치 어릴 때 했던 게임 닉네임 정하는 것처럼 시간이 오래 걸렸다.
-dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

말랑의 DM

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
-우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
+dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

+

말랑의 DM

+

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
+우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

+

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
추가로 도메인에 관한 이야기를 하다가 woowachat이 언급되었고, namecheap에서 chat 도메인을 사용한 woowa.chat으로 구매했다.
-이후에 teco.chat으로 변경했다!

도메인 설정 및 배포

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
-나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

GPT

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
-일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

Sonarcloud

정적 코드 분석 도구로 Sonarcloud를 적용했다.
+이후에 teco.chat으로 변경했다!

+

도메인 설정 및 배포

+

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
+나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

+

GPT

+

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
+일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

+

Sonarcloud

+

정적 코드 분석 도구로 Sonarcloud를 적용했다.
Sonarcloud는 SonarQube의 SaaS 버전이고 사용이 매우 편하다.
예전에 Sonarcloud를 사용할 땐 버튼 몇 번 누르면 적용할 수 있었는데, 이번에는 바로 github action을 사용하라는 안내 페이지로 이동했다.
Sonarcloud가 자체적으로 github repository에 push 하면 정적 분석을 해주는 기능을 원했고, Administration -> Analysis Method에 Automatic Analysis를 설정하니 되었다.
-너무 꽁꽁 숨겨져있네

Tiptap

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
+너무 꽁꽁 숨겨져있네

+

Tiptap

+

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
Tiptap은 Headless WYSIWYG 에디터로 사용자 정의 기능에 특화되어있는 에디터다.
아직 Tiptap이 제공하는 모든 기능을 자연스럽게 사용하지는 못하지만 CodeBlockLowlight 플러그인을 사용하여 코드 블록을 예쁘게 출력할 수 있었다.
api 반환값 그대로 tiptap의 content에 설정했더니 코드 블록이 설정되지 않아서 백 틱 3개를 <pre><code>로 변환했다.
추가로 띄어쓰기도 적용되지 않아서 \n<br>태그로 변환했다.
-변환하는 로직은 GPT의 도움을 많이 받았다.

const replaceCodeFences = (input: String) => {
const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
return input
.replace(codeFencesRegex, (match, p1, p2) => {
const languageClass = p1 ? ` class="language-${p1}"` : "";
return `<pre><code${languageClass}>${p2}</code></pre>`;
})
.replace(/\n/g, "<br>");
};

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

tecochat

폰트 및 favicon 적용

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
+변환하는 로직은 GPT의 도움을 많이 받았다.

+
const replaceCodeFences = (input: String) => {
+    const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
+    return input
+        .replace(codeFencesRegex, (match, p1, p2) => {
+        const languageClass = p1 ? ` class="language-${p1}"` : "";
+        return `<pre><code${languageClass}>${p2}</code></pre>`;
+        })
+        .replace(/\n/g, "<br>");
+};
+
+

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

+

tecochat

+

폰트 및 favicon 적용

+

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
추가로 favicon도 간단하게 적용해서 만족스러웠다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/15.html b/tags/retrospective/page/15.html index b2f4fd9c5..06936f84c 100644 --- a/tags/retrospective/page/15.html +++ b/tags/retrospective/page/15.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,45 +12,78 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

레벨 1이 끝났다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

레벨 1이 끝났다.
우테코를 시작하기 전 내가 정해두었던 목표 이상으로 달성했기 때문에 매우 만족스럽다.
혼자 독학을 할 땐 이 방향으로 공부하는 게 맞는지 계속 반추하다 결국 무기력함에 빠져들었다.
-하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

Keep

나만의 루틴 만들기

스스로가 외부의 영향을 많이 받는다고 생각한다.
-최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
+하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

+

Keep

+

나만의 루틴 만들기

+

스스로가 외부의 영향을 많이 받는다고 생각한다.
+최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

+

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
소화능력이 부족하기 때문에 점심은 도시락(그래봤자 계란2개)을 준비하고
-항상 똑같은 컨디션을 유지하기 위해 항상 6시에 집에 간다.
-이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

크루들과 친하게 지내기

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
+항상 똑같은 컨디션을 유지하기 위해 항상 6시에 집에 간다.
+이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

+

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

+

크루들과 친하게 지내기

+

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
하다 보니 더 많은 크루들의 닉네임을 외운 것 같다.
-앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

글쓰기

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
-매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
+앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

+

글쓰기

+

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
+매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

+

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
사실 겉으로 드러내지 않았지만 꼭 받아보고 싶었다.
-글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

코드 리뷰 스터디

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
+글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

+

코드 리뷰 스터디

+

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
과연 도움이 될까 생각했지만 결과적으로는 코드 리뷰를 하면서 성장을 많이 한 것 같다.
투자한 시간 대비 가성비가 좋은 활동이었다.
-누누가 스터디장인데 과연 꾸준히 이어나가려나?

레벨 인터뷰

인터뷰할 때 많이 떨지 않아서 좋았다.
+누누가 스터디장인데 과연 꾸준히 이어나가려나?

+

레벨 인터뷰

+

인터뷰할 때 많이 떨지 않아서 좋았다.
남들 앞에서 이야기를 하거나, 면접을 보면 항상 엄청 떨어서 걱정했는데
기술적인 질문을 받았을 때 떨지 않고 잘 대답할 수 있었다.
우아한테크코스 생활을 하면서 다른 크루가 질문했을 때, 최대한 이해하기 쉽게 설명하려고 했던 경험이 도움이 된 것 같다.
-이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • 두괄식 표현
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • 설명할 수 있을만큼 시간 충분히 가지기
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • 끝맺는 부분 연습하기(자신감 있게)
  • 기술적인 집착가지기
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기

Problem

페어프로그래밍

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
+이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

+
    +
  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • +
  • 두괄식 표현
  • +
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • +
  • 설명할 수 있을만큼 시간 충분히 가지기
  • +
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • +
  • 끝맺는 부분 연습하기(자신감 있게)
  • +
  • 기술적인 집착가지기
  • +
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기
  • +
+

Problem

+

페어프로그래밍

+

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
페어는 매번 바뀌고, 미션의 복잡도도 증가하기 때문인 것 같다.
소통 능력, 시간관리가 부족했고, 만족스럽지 않았다.
하지만 페어를 진행하고, 회고를 하다 보니 나만의 노하우가 쌓이는 느낌이다.
-레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

집중하는 시간⏱️ 부족

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
-이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

Try

허브🌿와의 티타임?

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
+레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

+

집중하는 시간⏱️ 부족

+

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
+이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

+

Try

+

허브🌿와의 티타임?

+

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
예를 들어 잡담방에 저와 커피챗 하실 분 :) 하면서 올릴 수 있을 것 같다.
-참여하는 사람이 있을지, 안 좋게 보는 게 아닐지 걱정되지만 그래도 재밌을 것 같다.
-저랑 허브티 한잔 하실래요?

기술적인 부분

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
+참여하는 사람이 있을지, 안 좋게 보는 게 아닐지 걱정되지만 그래도 재밌을 것 같다.
+저랑 허브티 한잔 하실래요?

+

기술적인 부분

+

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
시간의 여유가 될 때 책을 조금씩 읽어야겠다.
-블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

레벨 1을 마무리하며

시간이 빠르게 흘러갔다.
+블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

+

레벨 1을 마무리하며

+

시간이 빠르게 흘러갔다.
타인에게 좋은 영향을 주기위해, 방학동안 나를 챙기는 시간을 가져야겠다.
또한 함께 일하고 싶은 사람을 목표로 앞으로도 꾸준히 의식적 노력을 해야겠다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/16.html b/tags/retrospective/page/16.html index a759df9c2..e10194579 100644 --- a/tags/retrospective/page/16.html +++ b/tags/retrospective/page/16.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,49 +12,84 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

체스

체스 미션에는 가비와 페어가 매칭되었다!
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

1, 2단계: https://github.com/woowacourse/java-chess/pull/441
+3, 4단계: https://github.com/woowacourse/java-chess/pull/529

+

체스

+

체스 미션에는 가비와 페어가 매칭되었다!
체스는 이전 미션들보다 훨씬 복잡한 도메인이었다.
하지만 가비와 나는 체스 도메인이 익숙해서 더 편한 마음으로 시작할 수 있었다.
-미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
-최종적으로 결정한 부분은 다음과 같다.

각 기물의 이동 가능여부
+미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

+

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
+최종적으로 결정한 부분은 다음과 같다.

+

각 기물의 이동 가능여부
Rank와 File은 각각 위치값을 가지고 있고, 값의 차이를 이용해서 각 기물의 이동 가능 여부를 계산했다.
직선 → Rank와 File 차이 중 하나가 0이어야 한다.
대각선 → Rank와 File 차이의 절대값이 같아야 한다. ex) abs(-2) == abs(2)
-나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

도착 칸의 기물 여부
+나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

+

도착 칸의 기물 여부
아군 → 이동이 불가능하다.
-적군 → 이동이 가능하다. 적군을 잡는다.

중간에 기물 존재 여부
-이동 경로에 기물이 존재하면 안된다.

데이터베이스 사용
+적군 → 이동이 가능하다. 적군을 잡는다.

+

중간에 기물 존재 여부
+이동 경로에 기물이 존재하면 안된다.

+

데이터베이스 사용
체스 미션은 특별하게 데이터베이스와 연결하는 부분이 있었다.
-체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

  • 기물 전체를 저장하는 방법
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
-기물 전체를 저장하지 않은 이유는 다음과 같다.

  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
+체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

+
    +
  • 기물 전체를 저장하는 방법
  • +
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법
  • +
+

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
+기물 전체를 저장하지 않은 이유는 다음과 같다.

+
    +
  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • +
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • +
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.
  • +
+

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
보드저장: 초기상태에서 32개의 Insert 쿼리(기물의 위치) + 기물 이동 시 움직임 변경(잡히는 경우 2개의 쿼리)
-기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

추가로 기보저장이 구현도 더욱 간단하다. 👍

부가적인 부분

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

  • 누누의 도움으로 ConnectionPool 구현
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

부족했던 부분

꼼꼼하게 코드를 작성하지 못한 부분
+기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

+

추가로 기보저장이 구현도 더욱 간단하다. 👍

+

부가적인 부분

+

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

+
    +
  • 누누의 도움으로 ConnectionPool 구현
  • +
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • +
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)
  • +
+

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

+

부족했던 부분

+

꼼꼼하게 코드를 작성하지 못한 부분
DB 관련 부분을 꼼꼼하게 코딩을 하지 못했다.
도메인 로직에만 집중하다보니 정적 중요한 DB의 코드의 예외처리, 빈 값을 반환 하는 부분을 꼼꼼하게 처리하지 못했다.
-하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

시간에 대한 부담감
+하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

+

시간에 대한 부담감
초반에는 여유롭지만 제출 마감에 가까워질 수록 사람이 급해지는 것 같다.
-다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

새로 학습한 부분

DAO 중복 제거

프롤로그에 을 작성했다.
+다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

+

새로 학습한 부분

+

DAO 중복 제거

+

프롤로그에 을 작성했다.
DAO를 작성하는데 try-catch-resources와 여러 코드가 중복되서 제거하고싶었다.
-템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

페어에게 배울 부분

페어 생각하기
+템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

+

페어에게 배울 부분

+

페어 생각하기
가비는 누구보다 페어를 생각하고, 배려해주는 페어였다.
-중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

미션 몰입하기
+중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

+

미션 몰입하기
최근에 미션에 잘 몰입하지 못했다.
가비는 페어를 진행할 때 미션에 대한 몰입도가 매우 좋았다.
집에가서도 체스 이동에 대한 로직을 어떻게 구현할 지 생각한 뒤 꼼꼼해서 정리해서 나에게 보내주었다.
덕분에 나도 가비의 생각을 알 수 있어서 미션을 진행하는데 가속도가 붙은 것 같다.
-또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

솔직함
+또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

+

솔직함
먼저 회고하자고 말 걸어줘서 정말 고마웠다고 표현해주는 부분
모르는게 있으면 솔직하게 말해주는 부분
나의 의견을 정리하지 못한 상태로 전달할 때 이해가 안되었다고 정확히 전달해주는 부분
-솔직함은 페어할 때 중요한 부분인 것 같다.

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

- - +솔직함은 페어할 때 중요한 부분인 것 같다.

+

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

\ No newline at end of file diff --git a/tags/retrospective/page/17.html b/tags/retrospective/page/17.html index a356d863f..c262b3602 100644 --- a/tags/retrospective/page/17.html +++ b/tags/retrospective/page/17.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,44 +12,60 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

블랙잭

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
-이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
-후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
-"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

1단계: https://github.com/woowacourse/java-blackjack/pull/427
+2단계: https://github.com/woowacourse/java-blackjack/pull/537

+

블랙잭

+

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
+이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

+

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
+후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

+

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
+"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

+

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
중간 중간 회고를 하고, 나의 소프트스킬을 높히는게 답일까?
-부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
-터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

부족했던 부분

페어 신경쓰기
+부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

+

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
+터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

+

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

+

부족했던 부분

+

페어 신경쓰기
이번 페어할 때 적극적으로 의견을 내보도록 했다. 그렇기에 너무 의견을 강하게 밀어붙인 느낌이 들어서 미안했다.
후추가 압박을 느꼈을 수도 있을 것 같다는 생각이 든다.
-중간 중간 작은 회고를 진행해보는 것이 좋을까?

체력 관리
+중간 중간 작은 회고를 진행해보는 것이 좋을까?

+

체력 관리
요즘 잘 못먹는 것 같다.
-앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

중간 중간 돌아보기
+앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

+

중간 중간 돌아보기
이번 미션과 관련된 내용은 아니지만 우테코를 잘 활용 하고 있는지 생각을 해봐야겠다.
-내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

새로 학습한 부분

상태 패턴
+내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

+

새로 학습한 부분

+

상태 패턴
객체의 내부 상태에 따라 스스로 행동을 변경하도록 하는 패턴으로 if/else/switch와 같은 조건문을 효과적으로 제거할 수 있다.
블랙잭 미션을 진행하면서 상태 패턴에 대한 부분을 처음 적용해보았다.
-처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

일관성, 가독성, 추상화
+처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

+

일관성, 가독성, 추상화
이번 리뷰어는 검프🍫 였다!
검프의 리뷰는 간결함에 관련된 내용이 많았다.
일관성이 있는 코드, 가독성이 좋은 코드, 추상화가 잘 되어있는 코드
읽기 좋고, 간결한 방향으로 코드를 작성하는 방법을 배운 것 같다.
-코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

페어에게 배울 부분

생각 정리
+코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

+

페어에게 배울 부분

+

생각 정리
중간 중간 현재 상황에 대해 그림을 그리거나, 글을 적으면서 정리한다.
페어와 동일한 부분을 이해하고 있는지 확인한다.
진행하는데 매우 도움이 되었던 것 같다.
-나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

가감없이 의견을 말해주는 부분
+나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

+

가감없이 의견을 말해주는 부분
진행 상황에 대한 부분, 진행 속도, 지금 자신이 이해하고 있는 부분을 말해줘서 편했다.
-회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

도메인 언어에 신경쓰는 부분
+회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

+

도메인 언어에 신경쓰는 부분
클래스명, 변수명과 같은 언어를 세심하게 신경쓴다.
-요구사항 정리도 깔끔하게 잘하는 것 같다.

후추 최고 👍

- - +요구사항 정리도 깔끔하게 잘하는 것 같다.

+

후추 최고 👍

\ No newline at end of file diff --git a/tags/retrospective/page/18.html b/tags/retrospective/page/18.html index c8ecf8480..8782c1e02 100644 --- a/tags/retrospective/page/18.html +++ b/tags/retrospective/page/18.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,46 +12,150 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 11분

사다리 타기

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
-이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

2단계에서는 2가지 방법으로 구현해봤다.

  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법

Position 기준으로 사다리 게임을 진행하는 방법

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 11분

1단계: https://github.com/woowacourse/java-ladder/pull/97
+2단계: https://github.com/woowacourse/java-ladder/pull/234

+

사다리 타기

+

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
+이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

+

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

+

2단계에서는 2가지 방법으로 구현해봤다.

+
    +
  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. +
  3. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법
  4. +
+

Position 기준으로 사다리 게임을 진행하는 방법

+

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
구현하고 나니 다른 클래스들이 Position에 대한 의존도가 너무 높은 것 같았다.
-또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

public LadderGameResult play() {
final Map<Player, Item> result = new LinkedHashMap<>();
// 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
for (Position position : Position.range(players.count())) {
final Position resultPosition = ladder.play(position);
result.put(players.get(position), items.get(resultPosition));
}
return new LadderGameResult(result);
}

Player에게 Ladder를 전달하여 게임을 진행하는 방법

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
-이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

public LadderGameResult play() {
// 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
final Map<Player, Position> playResult = players.play(ladder);

final Map<Player, Item> result = new LinkedHashMap<>();
for (Player player : playResult.keySet()) {
result.put(player, toItem(playResult.get(player)));
}
return new LadderGameResult(result);
}

부족했던 부분

유비쿼터스 언어에 시간을 들이기
+또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

+ +
public LadderGameResult play() {
+    final Map<Player, Item> result = new LinkedHashMap<>();
+    // 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
+    for (Position position : Position.range(players.count())) {
+        final Position resultPosition = ladder.play(position);
+        result.put(players.get(position), items.get(resultPosition));
+    }
+    return new LadderGameResult(result);
+}
+
+

Player에게 Ladder를 전달하여 게임을 진행하는 방법

+

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
+이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

+ +
public LadderGameResult play() {
+    // 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
+    final Map<Player, Position> playResult = players.play(ladder);
+
+    final Map<Player, Item> result = new LinkedHashMap<>();
+    for (Player player : playResult.keySet()) {
+        result.put(player, toItem(playResult.get(player)));
+    }
+    return new LadderGameResult(result);
+}
+
+

부족했던 부분

+

유비쿼터스 언어에 시간을 들이기
유비쿼터스 언어를 정하는데 시간을 조금 더 들여야겠다고 생각했다.
사다리 타기의 실행 결과를 Item으로 짓다니.. 뭔가 만족스럽지 않다.
-이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

페어와 조금 더 친해지기
+이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

+

페어와 조금 더 친해지기
첫날은 페어와 친해지는 시간을 조금 더 가져야겠다고 생각했다.
-우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

README를 조금 더 꼼꼼하게
+우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

+

README를 조금 더 꼼꼼하게
이상하게 코딩에 집중하면 README를 업데이트하면서 같이 커밋 하는 걸 항상 까먹는다.
-다음 미션에는 조금 더 신경 써야겠다.

좋은 질문을 생각하기
+다음 미션에는 조금 더 신경 써야겠다.

+

좋은 질문을 생각하기
첫 PR때 리뷰어에게 질문을 남기지 못했다.
-리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

PR 후에도 꼼꼼하게 확인하기
+리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

+

PR 후에도 꼼꼼하게 확인하기
분명 알고 있는 부분이지만, 놓친 부분이 많은 것 같았다.
PR 하기 전에도 계속 확인을 했지만, 아무래도 IntelliJ에서 보니 코드에 익숙해져서 그런지 변경해야 할 부분이 잘 안보였다.
-github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

적극적으로 나의 의견을 말하기
+github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

+

적극적으로 나의 의견을 말하기
의견을 적극적으로 내는 부분에 대해서 페어의 의견이 괜찮다고 생각하면 수용 후 개선을 하는 방향으로 진행을 했었는데, 조금 더 개선할 수 있는 방향이 있다면 나도 적극적으로 의견을 말해야겠다고 생각이 든다.
-나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

새로 학습한 부분

객체의 생성 책임
+나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

+

새로 학습한 부분

+

객체의 생성 책임
Players가 Position을 생성하고 Player의 생성자에 넣어주었다. 하지만 이 부분에 대해서 생성 책임에 관련된 코멘트가 달렸다. -시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A를 긴밀하게 사용한다.
  • B가 A의 초깃값을 가지고 있다.

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

패키지 분리 기준
+시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

+

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

+
    +
  • B가 A 객체를 포함 또는 참조한다.
  • +
  • B가 A 객체를 기록한다.
  • +
  • B가 A를 긴밀하게 사용한다.
  • +
  • B가 A의 초깃값을 가지고 있다.
  • +
+

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

+

패키지 분리 기준
패키지 분리에 대한 나만의 기준이 아직 명확하지 않아 질문이 들어와도 명확하게 답변을 하지 못했다.
마지막 제출 전에 도메인 패키지 내부를 분리해 봤는데, 기준이 명확하지 않았기 때문에 좋지 않은 선택이었던 것 같다. -현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
-Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(0~19)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
-이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0~19의 값이 보장되어 있다고 생각할 것이기 때문이다.
-따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

페어에게 배울 부분

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
+현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

+

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
+Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(019)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
+이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0
19의 값이 보장되어 있다고 생각할 것이기 때문이다.
+따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

+

페어에게 배울 부분

+

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
이번에 페어 할 때 컨디션 관리를 제대로 못해서 많이 미안했다. 다음에는 최상의 컨디션으로 페어를 준비해 봐야겠다.
-그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
+그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

+

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
또한 페어 진행이 느린 것 같다고 말해줘서 안정적으로 시간 안에 미션을 완료할 수 있었다.
-페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
+페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

+

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
웃는 것만으로도 사람이 밝아 보여서 너무 좋은 것 같다!

- - \ No newline at end of file diff --git a/tags/retrospective/page/19.html b/tags/retrospective/page/19.html index 88fea4b5a..a1abab685 100644 --- a/tags/retrospective/page/19.html +++ b/tags/retrospective/page/19.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,40 +12,90 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

자동차 경주

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
-우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
-시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
-mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
-리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

부족했던 부분

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
-객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

1단계: https://github.com/woowacourse/java-racingcar/pull/510
+2단계: https://github.com/woowacourse/java-racingcar/pull/538

+

자동차 경주

+

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
+우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

+

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
+시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

+

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
+mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

+
    +
  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • +
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.
  • +
+ +

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

+

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
+리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

+

부족했던 부분

+

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
+객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

+

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
내가 좋아하는 주제, 관심가는 주제인 프로그래밍에 대한 이야기를 할 땐 말이 많아진다.
-다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

새로 학습한 부분

Assertions extracting

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
-이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

@Test
void extracting() {
final Cars cars = new Cars(List.of("car1", "car2"));

assertThat(cars.getCars())
.extracting(Car::getName)
.containsExactly("car1", "car2");
}

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

제어할 수 없는 부분에 대한 테스트

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
-이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

단순 위임을 하는 메서드에 대한 테스트

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
+다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

+

새로 학습한 부분

+

Assertions extracting

+

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
+이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

+
@Test
+void extracting() {
+    final Cars cars = new Cars(List.of("car1", "car2"));
+
+    assertThat(cars.getCars())
+            .extracting(Car::getName)
+            .containsExactly("car1", "car2");
+}
+
+
+

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

+

제어할 수 없는 부분에 대한 테스트

+

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
+이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

+

단순 위임을 하는 메서드에 대한 테스트

+

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
호출 횟수를 검증하는 것보다 결과에 대한 테스트하는 것이 좋다.
단순히 위임만 하는 테스트의 경우 결과를 검증한다면 테스트가 중복되지 않을까 생각했었다.
따라서 중복된 테스트를 줄이기 위해 내부의 메서드를 호출하는지 검증하는 방법도 있다는 것을 알게 되었지만
-안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

테스트를 위한 getter 사용

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
-필요의 경우 생성해서 사용할 수 있지만, 기존에 있는 메서드들을 활용해보는 것이 더 좋은 방법이다.
-이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

페어에게 배울 부분

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
+안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

+

테스트를 위한 getter 사용

+

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
+필요의 경우 생성해서 사용할 수 있지만, 기존에 있는 메서드들을 활용해보는 것이 더 좋은 방법이다.
+이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

+

페어에게 배울 부분

+

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
생각을 정리한 후 자신의 의견을 명료하게 전달해주었다.
그렇기 때문에 지식을 효율적으로 습득한다.
난 생각을 잘 정리하지 않은 채로 내버려 둔 얕은 지식이 많은 것 같다. (이런 것도 아는 것이라고 할 수 있을까?)
-앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

개발에 열정을 가진 게 느껴진다.
+앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

+

개발에 열정을 가진 게 느껴진다.
나도 개발을 좋아하지만, 최근에는 의지가 약해졌었다.
-열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
+열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

+

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
칭찬은 고래도 춤추게 하던가?
-그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
+그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

+

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
이건 바로 배울 수 없지만.
나도 같이 일할 때 편한 사람, 같이 일하고 싶은 사람이 되기 위해 깊이 고민해봐야겠다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/2.html b/tags/retrospective/page/2.html index 276d0046b..0cf6eeba2 100644 --- a/tags/retrospective/page/2.html +++ b/tags/retrospective/page/2.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,24 +12,94 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

Jdbc 구현

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
-미션 목표는 다음과 같다.

  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • 데이터베이스에 대한 이해도를 높인다.

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

JdbcTemplate

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

1단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267
+2단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358
+3단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448
+4단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515

+

Jdbc 구현

+

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
+미션 목표는 다음과 같다.

+
    +
  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • +
  • 데이터베이스에 대한 이해도를 높인다.
  • +
+

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

+

JdbcTemplate

+

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
템플릿 콜백 패턴을 적절하게 적용하여 중복을 비교적 간단하게 제거할 수 있었다.
-예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

public class JdbcTemplate {

private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);

private final DataSource dataSource;
private final StatementCreator statementCreator;
private final StatementExecutor statementExecutor;

public JdbcTemplate(final DataSource dataSource) {
this(dataSource, new StatementCreator(), new StatementExecutor());
}

JdbcTemplate(
final DataSource dataSource,
final StatementCreator statementCreator,
final StatementExecutor statementExecutor
) {
this.dataSource = dataSource;
this.statementCreator = statementCreator;
this.statementExecutor = statementExecutor;
}

private <T> T query(
final String sql,
final PreparedStatementCallback<T> preparedStatementCallback,
final Object... parameters
) {
final Connection connection = DataSourceUtils.getConnection(dataSource);
try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
return preparedStatementCallback.execute(preparedStatement);
} catch (final SQLException e) {
log.error(e.getMessage(), e);
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(connection, dataSource);
}
}

public void update(final String sql, final Object... parameters) {
query(sql, PreparedStatement::executeUpdate, parameters);
}

public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
if (results.size() > 1) {
throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
}
return results.stream().findAny();
}

public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
}
}

트랜잭션 적용

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
+예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

+
public class JdbcTemplate {
+
+    private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);
+
+    private final DataSource dataSource;
+    private final StatementCreator statementCreator;
+    private final StatementExecutor statementExecutor;
+
+    public JdbcTemplate(final DataSource dataSource) {
+        this(dataSource, new StatementCreator(), new StatementExecutor());
+    }
+
+    JdbcTemplate(
+            final DataSource dataSource,
+            final StatementCreator statementCreator,
+            final StatementExecutor statementExecutor
+    ) {
+        this.dataSource = dataSource;
+        this.statementCreator = statementCreator;
+        this.statementExecutor = statementExecutor;
+    }
+
+    private <T> T query(
+            final String sql,
+            final PreparedStatementCallback<T> preparedStatementCallback,
+            final Object... parameters
+    ) {
+        final Connection connection = DataSourceUtils.getConnection(dataSource);
+        try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
+            return preparedStatementCallback.execute(preparedStatement);
+        } catch (final SQLException e) {
+            log.error(e.getMessage(), e);
+            throw new DataAccessException(e);
+        } finally {
+            DataSourceUtils.releaseConnection(connection, dataSource);
+        }
+    }
+
+    public void update(final String sql, final Object... parameters) {
+        query(sql, PreparedStatement::executeUpdate, parameters);
+    }
+
+    public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+        if (results.size() > 1) {
+            throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
+        }
+        return results.stream().findAny();
+    }
+
+    public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+    }
+}
+
+

트랜잭션 적용

+

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
트랜잭션 동기화란 트랜잭션을 시작하기 위한 Connection 객체를 ThreadLocal과 같은 공간에 따로 저장 후, 필요할 때 저장된 Connection을 가져다 사용하는 방식이다.
-아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

마무리

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
+아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

+ +

마무리

+

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
꼼꼼히 코드를 봐준 리뷰어 호이 그리고 연휴 동안 계속 티키타카 하면서 재밌게 리뷰한 민트에게 감사하다.
회고 이만 끝내고 리팩터링 미션 하러가야겠다. 😊

- - \ No newline at end of file diff --git a/tags/retrospective/page/20.html b/tags/retrospective/page/20.html index 94f18fbd1..653cced53 100644 --- a/tags/retrospective/page/20.html +++ b/tags/retrospective/page/20.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,28 +12,38 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

적당한 전환점, 2022년을 돌아보며

전역

약 1년 6개월간의 공군 정보보호병 생활을 마치고 전역을 했다.
-조기 전역 때문에 2021년 12월에 나왔지만, 실제 전역 날짜는 2022년이니 회고에 적어도 상관없겠지.

조금 더 미래에 대한 생각을 해볼걸 그랬다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

적당한 전환점, 2022년을 돌아보며

+

전역

+

약 1년 6개월간의 공군 정보보호병 생활을 마치고 전역을 했다.
+조기 전역 때문에 2021년 12월에 나왔지만, 실제 전역 날짜는 2022년이니 회고에 적어도 상관없겠지.

+

조금 더 미래에 대한 생각을 해볼걸 그랬다.
전역을 했지만 뭐 하나 제대로 할 줄 아는 것도 없으니 넓은 바닷속에 덩그러니 놓아진 기분이 괜히 들었었다.
-일찍 생각을 정리하여 방향을 잡지 못했기에 아쉬움이 많이 남았다.

자바

전역을 하고 진로를 고민하다 향로님의 자바 공화국 포스팅을 읽고 나서 자바 공부를 시작했다.
-유명한 인프런의 김영한님의 스프링 강의도 있고, 좋은 자바 개발 서적이 많아서 독학하기로 결정했다.
+일찍 생각을 정리하여 방향을 잡지 못했기에 아쉬움이 많이 남았다.

+

자바

+

전역을 하고 진로를 고민하다 향로님의 자바 공화국 포스팅을 읽고 나서 자바 공부를 시작했다.
+유명한 인프런의 김영한님의 스프링 강의도 있고, 좋은 자바 개발 서적이 많아서 독학하기로 결정했다.
하다 보니 자바와 스프링을 공부하면서 “왜 진작하지 않았지”라는 생각도 많이 들었다.
-양질의 자료도 많았기 때문에, 예전에 노드로 개발했을 때 풀지 못했던 답답함을 많이 해소했던 것 같다.

23년에는 조금 더 깊게 자바를 공부해볼 생각이다.
-언어를 하나 깊게 공부하는 건 많은 도움이 되는 것 같다.

스터디

김영한님의 강의를 거의 다 들었을 때쯤, 항상 강의에서 언급되는 토비의 스프링을 읽어보고 싶어졌고
+양질의 자료도 많았기 때문에, 예전에 노드로 개발했을 때 풀지 못했던 답답함을 많이 해소했던 것 같다.

+

23년에는 조금 더 깊게 자바를 공부해볼 생각이다.
+언어를 하나 깊게 공부하는 건 많은 도움이 되는 것 같다.

+

스터디

+

김영한님의 강의를 거의 다 들었을 때쯤, 항상 강의에서 언급되는 토비의 스프링을 읽어보고 싶어졌고
혼자 공부하기에는 동기부여도 부족했기 때문에 스터디를 시작했다.
다른 사람에게 설명을 해야 했기 때문에 더욱 꼼꼼하게 공부를 할 수 있어서 좋았지만 나에게는 내용이 꽤나 어려워서 시간을 많이 소비했다.
-같이 스터디하시는 분과 7개월 동안 스터디를 꾸준히 이어나가 총 3권의 책을 읽을 수 있었다.

우아한 테크코스

군 복무 중일 때 지원했다 떨어진 우아한 테크코스를 다시 지원했다.
+같이 스터디하시는 분과 7개월 동안 스터디를 꾸준히 이어나가 총 3권의 책을 읽을 수 있었다.

+

우아한 테크코스

+

군 복무 중일 때 지원했다 떨어진 우아한 테크코스를 다시 지원했다.
이번 연도에 취업을 하는 게 목표였지만 내가 가지고 있는 특별한 무기가 없다는 걸 깨달았다.
-적지 않은 시간을 투자해 준비를 했고, 감사하게도 이번에는 최종 합격을 했다.

난 사람들과 소통하고, 협업하는 능력이 부족하다고 생각을 많이 했다.
-우아한 테크코스를 통해 그 빈 부분을 채우도록 노력해야겠다.

2023년에는

마음의 여유가 없었던 2022년이었던 것 같다.
+적지 않은 시간을 투자해 준비를 했고, 감사하게도 이번에는 최종 합격을 했다.

+

난 사람들과 소통하고, 협업하는 능력이 부족하다고 생각을 많이 했다.
+우아한 테크코스를 통해 그 빈 부분을 채우도록 노력해야겠다.

+

2023년에는

+

마음의 여유가 없었던 2022년이었던 것 같다.
하고 싶은 건 많지만, 이번에는 여유를 가지고 할 수 있는 것에 최선을 다해야겠다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/3.html b/tags/retrospective/page/3.html index 2bfc1f334..8e470742f 100644 --- a/tags/retrospective/page/3.html +++ b/tags/retrospective/page/3.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,25 +12,96 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

MVC 구현

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
-미션의 목표는 다음과 같았다.

  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • 점진적인 리팩토링을 경험한다.

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

애너테이션 기반 프레임워크 만들기

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

1단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/404
+2단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/465
+3단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/580

+

MVC 구현

+

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
+미션의 목표는 다음과 같았다.

+
    +
  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • +
  • 점진적인 리팩토링을 경험한다.
  • +
+

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

+

애너테이션 기반 프레임워크 만들기

+

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
테오가 @GetMapping이나 @PostMapping 부분도 진행하면 재밌을 것 같다고 해서 같이 진행해 보았다.
-추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  3. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

AnnotationHandlerMapping
public void initialize() {
if (!initialized.compareAndSet(false, true)) {
return;
}

final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
for (final Method method : methods) {
final ControllerInstance controller = controllers.get(method.getDeclaringClass());
final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
}

log.info("Initialized AnnotationHandlerMapping!");
handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
}

Legacy MVC와 @MVC 통합

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
+추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

+ +

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

+
    +
  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. +
  3. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  4. +
  5. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.
  6. +
+

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

+
public void initialize() {
+    if (!initialized.compareAndSet(false, true)) {
+        return;
+    }
+
+    final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
+    final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
+    for (final Method method : methods) {
+        final ControllerInstance controller = controllers.get(method.getDeclaringClass());
+        final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
+        final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
+        handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
+    }
+
+    log.info("Initialized AnnotationHandlerMapping!");
+    handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
+}
+
+

Legacy MVC와 @MVC 통합

+

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
기존의 MVC와 애너테이션이 적용된 MVC 두 개를 같이 사용할 수 있어야 헀다.
-대략적인 흐름은 다음과 같다.

  1. DispatcherServlet.service(request, response) 호출
  2. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  3. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  4. HandlerAdapter의.handle 메서드 실행
  5. View의 render 호출

웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
-간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

내용이 길어져서 다음 문서에 정리했다.

추상적인 개념 학습 방법

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory

정리

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
+대략적인 흐름은 다음과 같다.

+
    +
  1. DispatcherServlet.service(request, response) 호출
  2. +
  3. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  4. +
  5. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  6. +
  7. HandlerAdapter의.handle 메서드 실행
  8. +
  9. View의 render 호출
  10. +
+ +

웹 애플리케이션 발전 과정

+

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

+ +

내용이 길어져서 다음 문서에 정리했다.

+

추상적인 개념 학습 방법

+

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

+
개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory
+

정리

+

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
이번 미션에서 나의 리뷰어는 루카, 리뷰이는 헤나였다.
매 단계마다 꼼꼼하게 리뷰해 준 루카에게 너무 감사하고, 헤나에게 이상한 리뷰를 많이 남긴 것 같은데 꼼꼼히 반영해줘서 감사하다.
오랫동안 기다려왔던 레벨 4 미션이 하나씩 마무리 될 때 마다 아쉬움이 남는다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/4.html b/tags/retrospective/page/4.html index 5b276ba0f..07d1821b5 100644 --- a/tags/retrospective/page/4.html +++ b/tags/retrospective/page/4.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,43 +12,210 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 13분

톰캣 구현

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
-그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
-톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

다이어그램

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 13분

1, 2단계: https://github.com/woowacourse/jwp-dashboard-http/pull/302
+3, 4단계: https://github.com/woowacourse/jwp-dashboard-http/pull/431

+

톰캣 구현

+

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
+그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

+

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
+톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

+

다이어그램

+

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
사실 내부 구조를 깊게 공부할 시간을 가지지 못해서 각 구성 요소가 왜 해당 위치에 있는지 완벽하게 설명하지는 못하지만 미션을 진행하면서 이건 여기에 있으면 좋을 것 같은데? 라는 생각이 들면 적절한 패키지에 위치시키는 방향으로 진행을 했다.
-또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

코드 리뷰

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
-나의 리뷰어는 디노, 리뷰이는 필립이었다.

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
+또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

+ +

코드 리뷰

+

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
+나의 리뷰어는 디노, 리뷰이는 필립이었다.

+

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
한 가지 아쉬운 점은 필립에게 작성한 나의 코멘트들이 미션을 진행하면서 경험 기반으로 작성한 내용이 많아 근거가 조금 부족했고, 정리되지 않은 부분이 많았던 것 같다.
-다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

SessionConfig

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
+다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

+

SessionConfig

+

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
세션 쿠키의 이름을 가져오는 Util 클래스의 코드를 수정했는데 기본 값은 JSESSIONID 지만 설정에 따라서 세션 쿠키명을 다르게 사용할 수 있기 때문에 해당 로직이 있는 것으로 생각했다.
-기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
+기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

+

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
메인테이너인 Mark Thomas 형이 해당 로직의 경우 컴파일러가 해당 부분을 최적화 할 수 있을 거라고 기대한다고 했고, 가독성을 개선시켜보라고 조언해주셨다.
-컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
-결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

public static String getSessionCookieName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_COOKIE_NAME;
}

return result;
}

public static String getSessionUriParamName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_PARAMETER_NAME;
}

return result;
}

private static String getConfiguredSessionCookieName(Context context) {

// Priority is:
// 1. Cookie name defined in context
// 2. Cookie name configured for app
// 3. Default defined by spec
if (context != null) {
String cookieName = context.getSessionCookieName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}

SessionCookieConfig scc =
context.getServletContext().getSessionCookieConfig();
cookieName = scc.getName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}
}

return null;
}

HTTP 수업

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
+컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

+

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
+결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

+ + +
public static String getSessionCookieName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_COOKIE_NAME;
+    }
+
+    return result;
+}
+
+public static String getSessionUriParamName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_PARAMETER_NAME;
+    }
+
+    return result;
+}
+
+private static String getConfiguredSessionCookieName(Context context) {
+
+    // Priority is:
+    // 1. Cookie name defined in context
+    // 2. Cookie name configured for app
+    // 3. Default defined by spec
+    if (context != null) {
+        String cookieName = context.getSessionCookieName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+
+        SessionCookieConfig scc =
+            context.getServletContext().getSessionCookieConfig();
+        cookieName = scc.getName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+    }
+
+    return null;
+}
+
+

HTTP 수업

+

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
항상 성능 개선을 위해 애플리케이션 단에서 최적화해보려고 노력을 했지만, 더 적은 시간을 투자해서 효율적으로 성능을 개선할 수 있는 방법에 대해 알 수 있었던 수업이었다.
-HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

server:
compression:
enabled: true

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
-궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
-내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

ETag

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
+HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

+

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

+
server:
+  compression:
+    enabled: true
+
+

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
+궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
+내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

+
+

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

+
+

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

+

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

+

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐시가 더 효율적이게 된다.
-MDN

Thread 수업

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
-현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
-학습한 내용은 다음과 같다.

threads.max: Tomcat의 최대 스레드 개수
+MDN

+

Thread 수업

+

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
+현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

+

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
+학습한 내용은 다음과 같다.

+

threads.max: Tomcat의 최대 스레드 개수
max-connections: Tomcat이 유지할 수 있는 최대 커넥션 개수
-accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

마치며

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
+accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

+ +

마치며

+

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
우선순위를 잘 정하고 학습을 진행해야겠다.
-현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

참고 자료

RFC 2616
-ETag, mdn
-Apache Tomcat 8 Configuration Reference
-Apache Tomcat Tuning, Terry Cho
-maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

- - +현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

+

참고 자료

+

RFC 2616
+ETag, mdn
+Apache Tomcat 8 Configuration Reference
+Apache Tomcat Tuning, Terry Cho
+maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

\ No newline at end of file diff --git a/tags/retrospective/page/5.html b/tags/retrospective/page/5.html index c48335714..598ab0fb9 100644 --- a/tags/retrospective/page/5.html +++ b/tags/retrospective/page/5.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,28 +12,43 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

회고

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

회고

+

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
레벨 3에는 기술적인 부분에서도, 기술 외적인 부분에서도 부족함이 많이 보였던 것 같다.
부족한 부분을 알았기에, 앞으로 더욱 성장할 수 있을 것 같다.
-내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

아쉬운 점

문서화

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
+내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

+

아쉬운 점

+

문서화

+

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
프로젝트를 진행하면서 내가 한 부분을 조금 더 꼼꼼하게, 이해하기 쉽게 문서화를 했더라면 팀원들에게 더욱 도움이 되었을 텐데 이 부분에 시간을 조금 더 투자하지 못했던 부분에서 아쉬움이 많이 들었다.
-방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

내가 못하는 부분이라면 시간을 들이자

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
+방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

+

내가 못하는 부분이라면 시간을 들이자

+

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
말을 하기 전에 정리해서 의견을 내는 것, 발표 준비, 감정 조절 등등 -못하는 부분을 인지하고, 개선하자.

컴포트 존 벗어나기

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
+못하는 부분을 인지하고, 개선하자.

+

컴포트 존 벗어나기

+

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
매번 근거를 가지고 기술을 도입하고, 코드를 작성하려고 노력했다.
-하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

좋았던 점

좋았던 점도 문서화

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
-백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

내가 디자인한 트립드로우 로고

트립드로우 로고를 만들었다.
+하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

+

좋았던 점

+

좋았던 점도 문서화

+

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
+백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

+

내가 디자인한 트립드로우 로고

+ +

트립드로우 로고를 만들었다.
팀원들이 대표 색상(파란색)을 정해줬고, 주말 동안 신나게 로고 디자인을 했던 것 같다.
-아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

기술 선택의 이유

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
-100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

마치며

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
+아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

+

기술 선택의 이유

+

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
+100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

+

마치며

+

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
안드로이드 브레멘 음악대(멧돼지, 수달, 핑구), 그리고 백엔드 팀원들(체인저, 후추, 리오) 너무 고생이 많았다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/6.html b/tags/retrospective/page/6.html index fefda384d..a13936e26 100644 --- a/tags/retrospective/page/6.html +++ b/tags/retrospective/page/6.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,24 +12,32 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 3분

23년의 6월이 오고, 레벨 2가 끝났다.
-빠르게 지나가서 조금 아쉽다.

학습

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 3분

23년의 6월이 오고, 레벨 2가 끝났다.
+빠르게 지나가서 조금 아쉽다.

+

학습

+

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
항상 아쉬운 곳은 있기 마련이지만, 잘 학습한 것 같다.
-미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
-방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
-필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

수면

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
-앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

협업

레벨 2 마지막에 협업 미션이 있었다.
+미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

+

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
+방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

+

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
+필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

+

수면

+

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
+앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

+

협업

+

레벨 2 마지막에 협업 미션이 있었다.
지금까지는 백엔드 크루들과 페어 프로그래밍을 하면서 협업을 경험했다.
-이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
-팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

레벨 2를 마무리하며

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. +이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

+

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
+팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

+

레벨 2를 마무리하며

+

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. 읽고 싶은 책도 읽고, 부족한 부분 채우면서 쉬어야겠다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/7.html b/tags/retrospective/page/7.html index 8f360bc59..954d03a7b 100644 --- a/tags/retrospective/page/7.html +++ b/tags/retrospective/page/7.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,26 +12,36 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

레벨 인터뷰

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

레벨 인터뷰

+

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
따라서 레벨 1 레벨 인터뷰 회고는 레벨 1 회고를 작성할 때 끼워넣었다.
이번에는 범위도 제한되어 있어 어떻게 준비해야 할지 당황했고, 답변에도 부족한 부분이 많았었다.
-기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

API 문서 도구 선택

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
+기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

+

API 문서 도구 선택

+

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
백엔드 팀원이 함께 의사결정을 했고, 미션 기간이 짧은 만큼 팀 차원에서 비교적 학습하기 쉬운 Swagger를 선택했다.
-추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
-앞으로도 학습 비용은 주요하게 고려해야 할 사항

PUT과 PATCH & 토큰과 세션

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
-토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
+추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

+

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

+
+

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
+앞으로도 학습 비용은 주요하게 고려해야 할 사항

+
+

PUT과 PATCH & 토큰과 세션

+

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
+토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

+

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
실제로 레벨 2 때 이론적인 학습 시간이 매우 적었고, 집중력도 많이 부족했다.
-앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

그 외 개선할 점

인터뷰할 때 특유의 말버릇을 개선하기
+앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

+

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

+

그 외 개선할 점

+

인터뷰할 때 특유의 말버릇을 개선하기
생각할 시간을 가졌을 때 "다시 말씀드려도 될까요?"라고 말하고 답변을 이어나가기
기술적으로 깊이가 부족하다고 생각이 많이 들어서 조금 더 깊게 공부하고 정리하기
이전에 공부했던거 되돌아 보는 시간 가지기

- - \ No newline at end of file diff --git a/tags/retrospective/page/8.html b/tags/retrospective/page/8.html index e9e92562b..e1a3195ca 100644 --- a/tags/retrospective/page/8.html +++ b/tags/retrospective/page/8.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,31 +12,77 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분
PR 링크

장바구니 주문 미션

배포 및 협업을 할 수 있는 미션이었다.
-마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

배포

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

1단계: AWS 배포
+2단계: https://github.com/woowacourse/jwp-shopping-order/pull/7

+

장바구니 주문 미션

+

배포 및 협업을 할 수 있는 미션이었다.
+마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

+

배포

+

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
각자 하나의 EC2 인스턴스를 제공받을 수 있었고, 팀 별로 DB를 위한 추가 인스턴스를 제공받았다.
배포 스크립트를 작성하는 경험을 해볼 수 있었다.
-배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

echo "Start Deploy Script"
REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
PROJECT_NAME=jwp-shopping-order

echo "Change Directory"
cd $REPOSITORY_NAME

echo "Git Pull"
git pull origin step2

echo "Build"
./gradlew bootJar

echo "Copy, Start Server"
mv ./build/libs/$PROJECT_NAME.jar .

PID=$(pgrep -f $PROJECT_NAME)

if [ -n $PID ]; then
kill -9 $PID
sleep 5
fi

nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &

협업

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
+배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

+
echo "Start Deploy Script"
+REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
+PROJECT_NAME=jwp-shopping-order
+
+echo "Change Directory"
+cd $REPOSITORY_NAME
+
+echo "Git Pull"
+git pull origin step2
+
+echo "Build"
+./gradlew bootJar
+
+echo "Copy, Start Server"
+mv ./build/libs/$PROJECT_NAME.jar .
+
+PID=$(pgrep -f $PROJECT_NAME)
+
+if [ -n $PID ]; then
+        kill -9 $PID
+	sleep 5
+fi
+
+nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &
+
+

협업

+

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
백엔드가 아닌 다른 크루들과 해보는 첫 협업이라 약간 두근거렸다.
-예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

부족했던 부분

여러가지 방법에 대한 장단점을 고려해보기

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
+예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

+

부족했던 부분

+

여러가지 방법에 대한 장단점을 고려해보기

+

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
조금 더 시간을 많이 들여서 장단점을 고려했다면 더 좋은 결과물이 나오지 않았을까?
-앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

새로 배운 부분

expose headers

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
-기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
+앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

+

새로 배운 부분

+

expose headers

+

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
+기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
이를 expose headers 설정을 통해 해결할 수 있었다.
-nginx 설정에 다음과 같이 추가해 주었다.

add_header 'Access-Control-Expose-Headers' 'Location'

읽기 전용 트랜잭션

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
+nginx 설정에 다음과 같이 추가해 주었다.

+
add_header 'Access-Control-Expose-Headers' 'Location'
+
+

읽기 전용 트랜잭션

+

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
이번에 코멘트가 달려서 조금 더 자세히 공부해 보기로 했다.
-Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
-추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

DAO에 @Transactional 적용

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
+Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

+

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

+
    +
  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • +
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.
  • +
+

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
+추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

+

DAO에 @Transactional 적용

+

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
Service 계층에 이미 트랜잭션을 보장해 주고 있기에 필요 없지 않을까 생각했었다.
DAO를 다른 곳에서 사용하더라도 트랜잭션을 보장하기 위해(확장성 고려) @Transactional을 적용하는 것도 괜찮은 것 같다.

- - \ No newline at end of file diff --git a/tags/retrospective/page/9.html b/tags/retrospective/page/9.html index 6bb8dc785..1b7fd174c 100644 --- a/tags/retrospective/page/9.html +++ b/tags/retrospective/page/9.html @@ -2,8 +2,8 @@ - -"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG + +"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다. | GG @@ -12,27 +12,40 @@ - - - + + + -
-

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

개요

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
-레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

나의 채팅 확인하고 이어하는 기능

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
-예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

chat1

좋아요와 댓글 기능

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
-누가 좋아요를 눌렀는지, 어떤 채팅이 좋아요를 가장 많이 받았는지 확인할 수 있는 기능을 추가했다.
-또한 댓글 추가 및 삭제 기능도 추가했다.

키워드 추출

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
+

"Retrospective" 태그로 연결된 20개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

개요

+

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
+레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

+

나의 채팅 확인하고 이어하는 기능

+

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
+예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

+

chat1

+

좋아요와 댓글 기능

+

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
+누가 좋아요를 눌렀는지, 어떤 채팅이 좋아요를 가장 많이 받았는지 확인할 수 있는 기능을 추가했다.
+또한 댓글 추가 및 삭제 기능도 추가했다.

+

키워드 추출

+

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
해당 부분은 첫 질문에 대한 키워드만 추출하도록 했다.
백엔드에선 말랑이 이벤트 이용해서 첫 채팅 요청이 이루어지면, 비동기로 키워드를 추출하는 질문을 추가로 날리도록 구현하였다.
-CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

chat2

다른 크루의 채팅 복사해서 이어하는 기능

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
-채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

사용성 고려하기

chat3

위 화면은 회원가입 창이다.
+CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

+

chat2

+

다른 크루의 채팅 복사해서 이어하는 기능

+

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
+채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

+

사용성 고려하기

+

chat3

+

위 화면은 회원가입 창이다.
사실 가장 마음에 드는 부분이고, 회원가입(닉네임만 입력하지만)할 때 익명을 원하는 사람들의 고민을 도와주게 끔 음식, 과일, 과자 등의 요소들을 입력하도록 유도했다! 추가로 GPT의 답변이 오면 자동으로 화면을 스크롤 해주는 것과 같이 사용성을 개선해 보려고 노력했지만 쉽지 않았다.
-제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

향후 계획

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
+제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

+

향후 계획

+

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
크루들이 직접 사용해 주니까 너무 고맙고, 한편으로는 신기하다.
일단 방학 때 stream/text 관련된 부분 동작되도록 구현해보려고 하고, 그 외의 부분은 조금 더 고민해야될 것 같다.

- - \ No newline at end of file diff --git a/tags/spring-boot.html b/tags/spring-boot.html index e9d83b510..4647f011a 100644 --- a/tags/spring-boot.html +++ b/tags/spring-boot.html @@ -2,8 +2,8 @@ - -"Spring Boot" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Spring Boot" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,29 +12,100 @@ - - - + + + -
-

"Spring Boot" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
-2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

자바 변경 사항

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
-따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

Switch Expressions(Java 14)

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

enum RESULT {
WIN, LOSE, DRAW
}

RESULT result = RESULT.WIN;

int prize = switch (result) {
case WIN -> 10_000_000;
case LOSE, DRAW -> 5_000_000;
default -> 0;
};

주요 특징은 다음과 같다.

  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • break 문이 필요 없다.
  • default 블록을 통해 기본 값을 지정할 수 있다.

Text Block(Java 15)

Java 15에는 새로운 문자열 표현방식이 추가되었다.
-긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("""
SELECT p FROM Post p
WHERE p.title LIKE %:keyword%
OR p.content LIKE %:keyword%
""")
List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
}

NPE 메시지(Java 15)

String name = null;
name.chars();

/**
# before
java.lang.NullPointerException
at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)

# after
Cannot invoke "String.chars()" because "name" is null
java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
*/

Record(Java 16)

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
+

"Spring Boot" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

+

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
+2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

+

자바 변경 사항

+

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
+따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

+

Switch Expressions(Java 14)

+

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

+
enum RESULT {
+    WIN, LOSE, DRAW
+}
+
+RESULT result = RESULT.WIN;
+
+int prize = switch (result) {
+    case WIN -> 10_000_000;
+    case LOSE, DRAW -> 5_000_000;
+	default -> 0;
+};
+
+

주요 특징은 다음과 같다.

+
    +
  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • +
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • +
  • break 문이 필요 없다.
  • +
  • default 블록을 통해 기본 값을 지정할 수 있다.
  • +
+

Text Block(Java 15)

+

Java 15에는 새로운 문자열 표현방식이 추가되었다.
+긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

+
@Repository
+public interface PostRepository extends JpaRepository<Post, Long> {
+    @Query("""
+        SELECT p FROM Post p
+        WHERE p.title LIKE %:keyword%
+        OR p.content LIKE %:keyword%
+        """)
+    List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
+}
+
+

NPE 메시지(Java 15)

+
String name = null;
+name.chars();
+
+/** 
+# before
+java.lang.NullPointerException
+	at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)
+
+# after
+Cannot invoke "String.chars()" because "name" is null
+java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
+*/
+
+

Record(Java 16)

+

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
Record를 선언하는 경우 접근자, 생성자, equals & hashcode, toString이 제공된다.
-데이터 전송 용도로 적합해 보인다.

public record PostDto(String title, String content) {
}

추가적인 변경사항

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

스프링, 스프링 부트 변경 사항

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
-따라서 필요해보이는 몇개 정도만 정리했다.

스프링 요구사항

Java 17, Jakarta EE 9 이상이어야 한다.

네임스페이스 변경

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

PathPatternParser - trailing slash 허용하지 않음

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
-6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

PathPatternParser used by default (with the ability to opt into PathMatcher).

HTTP interface client

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
-자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

스프링 부트 최소 요구사항

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
-이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

참고 자료

어느 월급쟁이개발자 의 스프링 부트 따라잡기
-자바 9-16 주요 특징 복습하기
-Java EE에서 Jakarta EE로의 전환
-Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
-What's New in Spring Framework 6.x
-Spring Boot 3.0 Release Notes
-Spring Boot 3.1 Release Notes

- - +데이터 전송 용도로 적합해 보인다.

+
public record PostDto(String title, String content) {
+}
+
+

추가적인 변경사항

+

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

+

스프링, 스프링 부트 변경 사항

+

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
+따라서 필요해보이는 몇개 정도만 정리했다.

+

스프링 요구사항

+

Java 17, Jakarta EE 9 이상이어야 한다.

+

네임스페이스 변경

+

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

+

PathPatternParser - trailing slash 허용하지 않음

+

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
+6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

+
+

PathPatternParser used by default (with the ability to opt into PathMatcher).

+
+

HTTP interface client

+

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
+자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

+

스프링 부트 최소 요구사항

+

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
+이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

+

참고 자료

+

어느 월급쟁이개발자 의 스프링 부트 따라잡기
+자바 9-16 주요 특징 복습하기
+Java EE에서 Jakarta EE로의 전환
+Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
+What's New in Spring Framework 6.x
+Spring Boot 3.0 Release Notes
+Spring Boot 3.1 Release Notes

\ No newline at end of file diff --git a/tags/spring.html b/tags/spring.html index 2de5c36ec..740c8c4e9 100644 --- a/tags/spring.html +++ b/tags/spring.html @@ -2,8 +2,8 @@ - -"Spring" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Spring" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,29 +12,100 @@ - - - + + + -
-

"Spring" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
-2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

자바 변경 사항

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
-따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

Switch Expressions(Java 14)

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

enum RESULT {
WIN, LOSE, DRAW
}

RESULT result = RESULT.WIN;

int prize = switch (result) {
case WIN -> 10_000_000;
case LOSE, DRAW -> 5_000_000;
default -> 0;
};

주요 특징은 다음과 같다.

  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • break 문이 필요 없다.
  • default 블록을 통해 기본 값을 지정할 수 있다.

Text Block(Java 15)

Java 15에는 새로운 문자열 표현방식이 추가되었다.
-긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@Query("""
SELECT p FROM Post p
WHERE p.title LIKE %:keyword%
OR p.content LIKE %:keyword%
""")
List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
}

NPE 메시지(Java 15)

String name = null;
name.chars();

/**
# before
java.lang.NullPointerException
at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)

# after
Cannot invoke "String.chars()" because "name" is null
java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
*/

Record(Java 16)

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
+

"Spring" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

자바 17, 스프링 6.0, 스프링 부트 3.1

+

팀 프로젝트를 진행하면서 스프링 부트 3.1을 사용하게 되었다.
+2.7 버전을 사용할 수도 있었지만 LTS 기간과 취약점 패치로 인한 버전업 등을 고려했을 때 3.1과 자바 17을 사용하는 것이 더 효율적이라고 판단했다.

+

자바 변경 사항

+

우아한테크코스 레벨 2까지는 자바 11을 사용했었다.
+따라서 자바 11부터 자바 17까지의 변경사항을 정식 릴리즈 기준으로 정리해보려고 한다.

+

Switch Expressions(Java 14)

+

Java 14에서는 기존의 Switch 문을 간결하게 작성할 수 있는 Switch 식이 추가되었다.

+
enum RESULT {
+    WIN, LOSE, DRAW
+}
+
+RESULT result = RESULT.WIN;
+
+int prize = switch (result) {
+    case WIN -> 10_000_000;
+    case LOSE, DRAW -> 5_000_000;
+	default -> 0;
+};
+
+

주요 특징은 다음과 같다.

+
    +
  • -> 연산자를 이용하여 각 case에 대한 결과를 바로 반환할 수 있다.
  • +
  • case를 콤마(,)로 연결하여 하나의 case에 여러 값을 지정할 수 있다.
  • +
  • break 문이 필요 없다.
  • +
  • default 블록을 통해 기본 값을 지정할 수 있다.
  • +
+

Text Block(Java 15)

+

Java 15에는 새로운 문자열 표현방식이 추가되었다.
+긴 문자열을 + 연산자의 도움 없이 가독성있게 작성할 수 있다.

+
@Repository
+public interface PostRepository extends JpaRepository<Post, Long> {
+    @Query("""
+        SELECT p FROM Post p
+        WHERE p.title LIKE %:keyword%
+        OR p.content LIKE %:keyword%
+        """)
+    List<Post> findPostsByTitleOrContentContainingKeyword(String keyword);
+}
+
+

NPE 메시지(Java 15)

+
String name = null;
+name.chars();
+
+/** 
+# before
+java.lang.NullPointerException
+	at com.example.DiscountPolicyTest.test(NullPointerExceptionTest.java:61)
+
+# after
+Cannot invoke "String.chars()" because "name" is null
+java.lang.NullPointerException: Cannot invoke "String.chars()" because "name" is null
+*/
+
+

Record(Java 16)

+

Lombok의 @Data, kotlin의 data 클래스와 유사한 기능을 제공한다.
Record를 선언하는 경우 접근자, 생성자, equals & hashcode, toString이 제공된다.
-데이터 전송 용도로 적합해 보인다.

public record PostDto(String title, String content) {
}

추가적인 변경사항

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

스프링, 스프링 부트 변경 사항

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
-따라서 필요해보이는 몇개 정도만 정리했다.

스프링 요구사항

Java 17, Jakarta EE 9 이상이어야 한다.

네임스페이스 변경

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

PathPatternParser - trailing slash 허용하지 않음

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
-6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

PathPatternParser used by default (with the ability to opt into PathMatcher).

HTTP interface client

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
-자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

스프링 부트 최소 요구사항

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
-이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

참고 자료

어느 월급쟁이개발자 의 스프링 부트 따라잡기
-자바 9-16 주요 특징 복습하기
-Java EE에서 Jakarta EE로의 전환
-Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
-What's New in Spring Framework 6.x
-Spring Boot 3.0 Release Notes
-Spring Boot 3.1 Release Notes

- - +데이터 전송 용도로 적합해 보인다.

+
public record PostDto(String title, String content) {
+}
+
+

추가적인 변경사항

+

이외에도 stream의 toList, 인스턴스의 타입을 간편하게 체크하는 Pattern Matching Instanceof, Sealed class 등이 추가되었다.

+

스프링, 스프링 부트 변경 사항

+

스프링과 스프링 부트에도 많은 변경 사항이 있었다.
+따라서 필요해보이는 몇개 정도만 정리했다.

+

스프링 요구사항

+

Java 17, Jakarta EE 9 이상이어야 한다.

+

네임스페이스 변경

+

Jakarta EE 9가 적용되면서 네임스페이스도 전반적으로 javax -> jakarta로 변경되었다.

+

PathPatternParser - trailing slash 허용하지 않음

+

6.0 이전의 경우 기본 설정 기준으로 @GetMapping("/hello")@GetMapping("/hello/")가 동일했다.
+6.0 이후의 PathPatternParser가 기본으로 사용되고, /hello/hello/는 서로 다른 URL로 매칭된다.

+
+

PathPatternParser used by default (with the ability to opt into PathMatcher).

+
+

HTTP interface client

+

자바 인터페이스와 어노테이션을 이용하여 HTTP 요청을 위한 서비스를 정의할 수 있는 방법이 추가되었다.
+자세한 내용은 토비님의 강의를 참고하면 좋을 것 같다.

+

스프링 부트 최소 요구사항

+

Gradle 7.3, Java 17, Kotlin 1.6, Jakarta EE 9, Spring Framework 6
+이외에도 서드파티들의 최신 릴리즈 버전을 사용함으로, 문제가 발생하는 경우 해당 버전에 맞는 릴리즈 노트를 참고할 수 있을 것 같다.

+

참고 자료

+

어느 월급쟁이개발자 의 스프링 부트 따라잡기
+자바 9-16 주요 특징 복습하기
+Java EE에서 Jakarta EE로의 전환
+Spring 6의 새로운 HTTP Interface와 3 가지 REST Clients 라이브 코딩
+What's New in Spring Framework 6.x
+Spring Boot 3.0 Release Notes
+Spring Boot 3.1 Release Notes

\ No newline at end of file diff --git a/tags/static.html b/tags/static.html index fa9a45e54..1305d1a19 100644 --- a/tags/static.html +++ b/tags/static.html @@ -2,8 +2,8 @@ - -"static" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"static" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,22 +12,51 @@ - - - + + + -
-

"static" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 3분

개요

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
-하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
+

"static" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 3분

개요

+

정적 팩터리 메서드를 모킹한다는 것은 객체지향적인 관점에서 볼 때 안티패턴이다.
+하지만 특수한 경우에는 정적 메서드를 모킹하는 것이 필요할 수 있다고 생각한다.

+

예를 들어 레거시 코드를 테스트 한다던지, IO 관련한 부분을 테스트 할 때 정말 필요한 부분에만 적용할 수 있을 것이다.

+

프로젝트를 진행하며 ImageIo.write 메서드가 호출되는 지 검증이 필요했다.
해당 static 메서드를 호출하는 부분을 따로 RouteImageUploader 클래스로 최대한 분리했다.
-이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

public void upload(BufferedImage bufferedImage) {
File file = new File(파일경로);
try {
ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
} catch (IOException e) {
throw new DrawException(IMAGE_SAVE_FAIL);
}
}

Mocking static methods

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
-mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

// given
BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
RouteImageUploader routeImageUploader = new RouteImageUploader();

// expect
try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
routeImageUploader.upload(bufferedImage);
imageIO.verify(
() -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
times(1)
);
}

마치며

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
+이미지 저장 기능 자체가 외부로 나가는 상호작용이고, 호출 횟수를 검사하는데는 mock을 사용하는게 적절하다고 판단했다.

+
public void upload(BufferedImage bufferedImage) {
+    File file = new File(파일경로);
+    try {
+        ImageIO.write(bufferedImage, ROUTE_IMAGE_FORMAT, file);
+    } catch (IOException e) {
+        throw new DrawException(IMAGE_SAVE_FAIL);
+    }
+}
+
+

Mocking static methods

+

Mockito 3.4.0 이후에는 static method를 모킹할 수 있는 Mockito.mockStatic 메서드를 지원한다.
+mockStatic을 사용하면 MockedStatic<T>이 반환되는데 사용 후 꼭 close를 해줘야 한다.

+

JUnit의 @BeforeAll로 설정하고 @AfterAll 메서드로 종료하는 방법도 있지만 MockedStatic<T>의 상위 인터페이스인 ScopedMock이 AutoCloseable을 구현하고 있기에 try-with-resources를 사용하는 방법이 더욱 좋은 것 같다.

+
// given
+BufferedImage bufferedImage = new BufferedImage(800, 800, BufferedImage.TYPE_INT_ARGB);
+RouteImageUploader routeImageUploader = new RouteImageUploader();
+
+// expect
+try (MockedStatic<ImageIO> imageIO = Mockito.mockStatic(ImageIO.class)) {
+    routeImageUploader.upload(bufferedImage);
+    imageIO.verify(
+            () -> ImageIO.write(any(BufferedImage.class), any(String.class), any(File.class)),
+            times(1)
+    );
+}
+
+

마치며

+

정적 메서드를 모킹하는 것은 안티패턴이으로 적절한 추상화를 이용해 테스트 하기 좋은 코드를 만드는 연습을 하자.
하지만 추상화를 하면 할 수록 코드의 복잡도는 증가한다.
-항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

참고 자료

Mocking static methods
-Mockito mock static methods
-Enable mocking static methods in Mockito

- - +항상 상황을 고려하고 간결함을 포기할 만큼 중요한 부분인지 적절한 트레이드오프를 고려하자.

+

참고 자료

+

Mocking static methods
+Mockito mock static methods
+Enable mocking static methods in Mockito

\ No newline at end of file diff --git a/tags/teco-chat.html b/tags/teco-chat.html index 69a96e12b..fad4a0150 100644 --- a/tags/teco-chat.html +++ b/tags/teco-chat.html @@ -2,8 +2,8 @@ - -"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,27 +12,40 @@ - - - + + + -
-

"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

개요

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
-레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

나의 채팅 확인하고 이어하는 기능

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
-예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

chat1

좋아요와 댓글 기능

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
-누가 좋아요를 눌렀는지, 어떤 채팅이 좋아요를 가장 많이 받았는지 확인할 수 있는 기능을 추가했다.
-또한 댓글 추가 및 삭제 기능도 추가했다.

키워드 추출

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
+

"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

개요

+

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
+레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

+

나의 채팅 확인하고 이어하는 기능

+

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
+예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

+

chat1

+

좋아요와 댓글 기능

+

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
+누가 좋아요를 눌렀는지, 어떤 채팅이 좋아요를 가장 많이 받았는지 확인할 수 있는 기능을 추가했다.
+또한 댓글 추가 및 삭제 기능도 추가했다.

+

키워드 추출

+

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
해당 부분은 첫 질문에 대한 키워드만 추출하도록 했다.
백엔드에선 말랑이 이벤트 이용해서 첫 채팅 요청이 이루어지면, 비동기로 키워드를 추출하는 질문을 추가로 날리도록 구현하였다.
-CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

chat2

다른 크루의 채팅 복사해서 이어하는 기능

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
-채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

사용성 고려하기

chat3

위 화면은 회원가입 창이다.
+CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

+

chat2

+

다른 크루의 채팅 복사해서 이어하는 기능

+

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
+채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

+

사용성 고려하기

+

chat3

+

위 화면은 회원가입 창이다.
사실 가장 마음에 드는 부분이고, 회원가입(닉네임만 입력하지만)할 때 익명을 원하는 사람들의 고민을 도와주게 끔 음식, 과일, 과자 등의 요소들을 입력하도록 유도했다! 추가로 GPT의 답변이 오면 자동으로 화면을 스크롤 해주는 것과 같이 사용성을 개선해 보려고 노력했지만 쉽지 않았다.
-제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

향후 계획

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
+제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

+

향후 계획

+

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
크루들이 직접 사용해 주니까 너무 고맙고, 한편으로는 신기하다.
일단 방학 때 stream/text 관련된 부분 동작되도록 구현해보려고 하고, 그 외의 부분은 조금 더 고민해야될 것 같다.

- - \ No newline at end of file diff --git a/tags/teco-chat/page/2.html b/tags/teco-chat/page/2.html index 28f40374e..6e2757941 100644 --- a/tags/teco-chat/page/2.html +++ b/tags/teco-chat/page/2.html @@ -2,8 +2,8 @@ - -"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,32 +12,55 @@ - - - + + + -
-

"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

프론트엔트

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
+

"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

프론트엔트

+

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
추가로 채팅을 이어나갈 수 있게 하는 기능도 추가했다.
자잘하게 신경 쓸 부분이 많아서, 프론트엔드 하는 사람들이 대단하다고 생각되었다.
-여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

백엔드

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
+여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

+

백엔드

+

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
말랑이 한 부분이 너무 많아서 내가 못 따라가는 것 같다.
-나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

Http Request Header

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
+나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

+

Http Request Header

+

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
말랑이 한글은 안된다고 말해줘서 Base64로 인코딩하고, 백엔드에서 디코딩 하여 사용하기로 했다.
-아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

const encodedName = () => {
const uriComponent = unescape(encodeURIComponent(name.value));
return btoa(uriComponent);
};

Elastic Beanstalk

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
+아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

+
const encodedName = () => {
+  const uriComponent = unescape(encodeURIComponent(name.value));
+  return btoa(uriComponent);
+};
+
+

Elastic Beanstalk

+

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
Elastic Beanstalk를 사용하면 인프라에 대해 잘 알지 못해도 애플리케이션을 빠르게 배포하고 관리할 수 있다.
-모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

Elastic Beanstalk RDS 설정 후 분리

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
+모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

+

Elastic Beanstalk RDS 설정 후 분리

+

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
RDS 분리 시 Beanstalk에 기본적으로 설정되어 있는 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD와 같은 환경 변수가 같이 제거된다.
-추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

Elastic Beanstalk nginx 설정

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

Jenkins

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
+추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

+

Elastic Beanstalk nginx 설정

+

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

+

Jenkins

+

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
작년에 확인했을 땐 2022년 12월 31일까지 EC2 ARM 기반 t4g.small이 무료였는데, 다시 들어가 보니 2023년까지 12월 31일까지 t4g.small을 무료로 사용할 수 있었다.
t4g.small은 램이 2G인데, 예전에는 부족하지 않았다고 생각했는데 Java 17을 써서 그런가 빌드 할 때 램이 많이 부족한 것 같아서 Swap 메모리 2기가를 추가로 설정했다.
-추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

test {
maxHeapSize = "1024m"
}

Jenkins Blue Ocean

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
+추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

+
test {
+    maxHeapSize = "1024m"
+}
+
+

Jenkins Blue Ocean

+

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
시각화도 잘 되어있고, 설정도 편리한 것 같다.
-오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

참고 자료

Elastic Beanstalk, AWS
-EC2 AWS Graviton, AWS
-Default Memory Settings, AWS

- - +오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

+

참고 자료

+

Elastic Beanstalk, AWS
+EC2 AWS Graviton, AWS
+Default Memory Settings, AWS

\ No newline at end of file diff --git a/tags/teco-chat/page/3.html b/tags/teco-chat/page/3.html index 0950a8ba1..ab7ba183c 100644 --- a/tags/teco-chat/page/3.html +++ b/tags/teco-chat/page/3.html @@ -2,8 +2,8 @@ - -"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG + +"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다. | GG @@ -12,36 +12,64 @@ - - - + + + -
-

"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

4월 21일 금요일

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
+

"TecoChat" 태그로 연결된 3개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

4월 21일 금요일

+

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
레벨 3, 4에서 나만의 강점을 가지고 싶어 고민을 많이 했다.
단순히 스프링을 깊게 공부하는 건 효율이 많이 떨어진다고 생각했다.
-글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
-Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
-프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

이건 못참지

도메인 구입 성공?

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
+글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

+

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
+Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

+

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
+프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

+

이건 못참지

+

도메인 구입 성공?

+

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
마치 어릴 때 했던 게임 닉네임 정하는 것처럼 시간이 오래 걸렸다.
-dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

말랑의 DM

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
-우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
+dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

+

말랑의 DM

+

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
+우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

+

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
추가로 도메인에 관한 이야기를 하다가 woowachat이 언급되었고, namecheap에서 chat 도메인을 사용한 woowa.chat으로 구매했다.
-이후에 teco.chat으로 변경했다!

도메인 설정 및 배포

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
-나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

GPT

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
-일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

Sonarcloud

정적 코드 분석 도구로 Sonarcloud를 적용했다.
+이후에 teco.chat으로 변경했다!

+

도메인 설정 및 배포

+

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
+나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

+

GPT

+

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
+일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

+

Sonarcloud

+

정적 코드 분석 도구로 Sonarcloud를 적용했다.
Sonarcloud는 SonarQube의 SaaS 버전이고 사용이 매우 편하다.
예전에 Sonarcloud를 사용할 땐 버튼 몇 번 누르면 적용할 수 있었는데, 이번에는 바로 github action을 사용하라는 안내 페이지로 이동했다.
Sonarcloud가 자체적으로 github repository에 push 하면 정적 분석을 해주는 기능을 원했고, Administration -> Analysis Method에 Automatic Analysis를 설정하니 되었다.
-너무 꽁꽁 숨겨져있네

Tiptap

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
+너무 꽁꽁 숨겨져있네

+

Tiptap

+

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
Tiptap은 Headless WYSIWYG 에디터로 사용자 정의 기능에 특화되어있는 에디터다.
아직 Tiptap이 제공하는 모든 기능을 자연스럽게 사용하지는 못하지만 CodeBlockLowlight 플러그인을 사용하여 코드 블록을 예쁘게 출력할 수 있었다.
api 반환값 그대로 tiptap의 content에 설정했더니 코드 블록이 설정되지 않아서 백 틱 3개를 <pre><code>로 변환했다.
추가로 띄어쓰기도 적용되지 않아서 \n<br>태그로 변환했다.
-변환하는 로직은 GPT의 도움을 많이 받았다.

const replaceCodeFences = (input: String) => {
const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
return input
.replace(codeFencesRegex, (match, p1, p2) => {
const languageClass = p1 ? ` class="language-${p1}"` : "";
return `<pre><code${languageClass}>${p2}</code></pre>`;
})
.replace(/\n/g, "<br>");
};

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

tecochat

폰트 및 favicon 적용

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
+변환하는 로직은 GPT의 도움을 많이 받았다.

+
const replaceCodeFences = (input: String) => {
+    const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
+    return input
+        .replace(codeFencesRegex, (match, p1, p2) => {
+        const languageClass = p1 ? ` class="language-${p1}"` : "";
+        return `<pre><code${languageClass}>${p2}</code></pre>`;
+        })
+        .replace(/\n/g, "<br>");
+};
+
+

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

+

tecochat

+

폰트 및 favicon 적용

+

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
추가로 favicon도 간단하게 적용해서 만족스러웠다.

- - \ No newline at end of file diff --git a/tags/test.html b/tags/test.html index 83153eb86..e4594ba99 100644 --- a/tags/test.html +++ b/tags/test.html @@ -2,8 +2,8 @@ - -"test" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG + +"test" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG @@ -12,25 +12,92 @@ - - - + + + -
-

"test" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

테스트 격리

테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 @DirtiesContext, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 @Transactional등 다양한 방법이 있다.
-해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.

Independent - FIRST

테스트끼리 서로 의존하면 안 된다.
+

"test" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

테스트 격리

+

테스트의 순서에 따라 성공 실패 여부가 결정되는 비결정적인(non-determinism) 테스트가 되어서는 안되고, 테스트는 항상 순서에 상관없이 독립적으로 수행되도록 보장되어야 한다. 일반적으로 자원의 공유, 외부 API, 시간 등으로 비결정적인 테스트가 된다. 이를 해결하기 위해 테스트 대역을 사용하거나, 컨텍스트를 재실행하는 @DirtiesContext, 자원을 초기화하기 위해 테스트 이후에 테이블을 롤백 하는 @Transactional등 다양한 방법이 있다.
+해당 글에서는 스프링에서 데이터베이스 자원의 공유를 방지하기 위해 테스트 격리를 수행하는 부분에 대해 설명한다.

+

테스트끼리 서로 의존하면 안 된다.
서로 의존하게 된다면 하나의 테스트가 실패할 때, 또 다른 하나의 테스트가 실패할 수 있다.
-다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

TestExecutionListener

스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.
-이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.

TextExecutionListner
public interface TestExecutionListener {
default void beforeTestClass(TestContext testContext) throws Exception {}
default void prepareTestInstance(TestContext testContext) throws Exception {}
default void beforeTestMethod(TestContext testContext) throws Exception {}
default void beforeTestExecution(TestContext testContext) throws Exception {}
default void afterTestExecution(TestContext testContext) throws Exception {}
default void afterTestMethod(TestContext testContext) throws Exception {}
default void afterTestClass(TestContext testContext) throws Exception {}
}

AbstractTestExecutionListener 상속하여 구현

AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.
-다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.

DatabaseCleaner

public class DatabaseCleaner extends AbstractTestExecutionListener {

private static final String TRUNCATE_TABLE_QUERY = """
SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'PUBLIC'
""";

@Override
public void afterTestMethod(TestContext testContext) {
JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);
List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);
truncateTables(jdbcTemplate, truncateTableQueries);
}

private JdbcTemplate getJdbcTemplate(TestContext testContext) {
return testContext.getApplicationContext().getBean(JdbcTemplate.class);
}

private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {
return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);
}

private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");
truncateTableQueries.forEach(jdbcTemplate::execute);
jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");
}
}

Listener 등록

@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.
+다른 테스트에 의존하지 않고, 독립적으로 실행 가능한 테스트가 좋은 테스트다.

+

TestExecutionListener

+

스프링에서는 TextExecutionListner를 이용하여 각 테스트 실행 단계에서 이벤트를 수신할 수 있다.
+이를 이용하면 JUnit의 @BeforeEach를 사용하는 것과 유사하게, 테스트의 생명주기 이전 또는 이후에 필요한 작업을 실행시킬 수 있다.

+
public interface TestExecutionListener {
+    default void beforeTestClass(TestContext testContext) throws Exception {}
+    default void prepareTestInstance(TestContext testContext) throws Exception {}
+    default void beforeTestMethod(TestContext testContext) throws Exception {}
+    default void beforeTestExecution(TestContext testContext) throws Exception {}
+    default void afterTestExecution(TestContext testContext) throws Exception {}
+    default void afterTestMethod(TestContext testContext) throws Exception {}
+    default void afterTestClass(TestContext testContext) throws Exception {}
+}
+
+

AbstractTestExecutionListener 상속하여 구현

+

AbstractTestExecutionListener를 상속받아 테스트 격리 환경을 만들어주는 클래스로, 인터페이스인 TextExecutionListner와 달리 Ordered가 구현되어 있어 해당 클래스를 상속받아 구현한 클래스는 프레임워크가 제공하는 리스너 다음에 실행시키도록 해준다.
+다음과 같이 데이터베이스에서 각각의 테이블에 해당하는 Truncate 쿼리를 만들어서 조회하고, Test 메서드가 끝날때 마다 해당 쿼리를 실행하여 테이블을 초기화시키도록 설정한다.

+

+public class DatabaseCleaner extends AbstractTestExecutionListener {
+
+    private static final String TRUNCATE_TABLE_QUERY = """
+            SELECT Concat('TRUNCATE TABLE ', TABLE_NAME, ';') 
+            FROM INFORMATION_SCHEMA.TABLES
+            WHERE TABLE_SCHEMA = 'PUBLIC'
+            """;
+
+    @Override
+    public void afterTestMethod(TestContext testContext) {
+        JdbcTemplate jdbcTemplate = getJdbcTemplate(testContext);
+        List<String> truncateTableQueries = getTruncateTableQueries(jdbcTemplate);
+        truncateTables(jdbcTemplate, truncateTableQueries);
+    }
+
+    private JdbcTemplate getJdbcTemplate(TestContext testContext) {
+        return testContext.getApplicationContext().getBean(JdbcTemplate.class);
+    }
+
+    private List<String> getTruncateTableQueries(JdbcTemplate jdbcTemplate) {
+        return jdbcTemplate.queryForList(TRUNCATE_TABLE_QUERY, String.class);
+    }
+
+    private void truncateTables(JdbcTemplate jdbcTemplate, List<String> truncateTableQueries) {
+        jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY FALSE");
+        truncateTableQueries.forEach(jdbcTemplate::execute);
+        jdbcTemplate.execute("SET REFERENTIAL_INTEGRITY TRUE");
+    }
+}
+
+
+

Listener 등록

+

@TestExecutionListeners를 이용하여 사용자 정의 리스너를 등록할 수 있다.
mergeMode의 기본값은 REPLACE_DEFAULTS로 리스너가 이미 존재하는 경우 등록된 리스너로 변경된다.
MERGE_WITH_DEFAULTS로 설정한다면 Ordered 기준으로 순서가 결정된다.
-이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.

AcceptanceTest

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestExecutionListeners(
value = DatabaseCleaner.class,
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
)
public abstract class AcceptanceTest {

@LocalServerPort
private int port;

@BeforeEach
public void setUp() {
RestAssured.port = port;
}
}

참고 자료

The Spring TestExecutionListener, Baeldung
-인수테스트에서 테스트 격리하기, 테코블
-Eradicating Non-Determinism in Tests, martin fowler
-@SpringBootTest의 테스트 격리시키기, MangKyu

- - +이후 격리가 필요한 테스트들은 다음의 추상 클래스를 상속하여 사용하면 된다.

+

+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@TestExecutionListeners(
+        value = DatabaseCleaner.class,
+        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS
+)
+public abstract class AcceptanceTest {
+
+    @LocalServerPort
+    private int port;
+
+    @BeforeEach
+    public void setUp() {
+        RestAssured.port = port;
+    }
+}
+
+
+

참고 자료

+

The Spring TestExecutionListener, Baeldung
+인수테스트에서 테스트 격리하기, 테코블
+Eradicating Non-Determinism in Tests, martin fowler
+@SpringBootTest의 테스트 격리시키기, MangKyu

\ No newline at end of file diff --git a/tags/test/page/2.html b/tags/test/page/2.html index e00a60727..fb434725e 100644 --- a/tags/test/page/2.html +++ b/tags/test/page/2.html @@ -2,8 +2,8 @@ - -"test" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG + +"test" 태그로 연결된 2개 게시물개의 게시물이 있습니다. | GG @@ -12,31 +12,51 @@ - - - + + + -
-

"test" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

테스트 대역이란?

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
-Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
-외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

테스트 대역의 타입 계층 구조

더미(Dummy)

가장 단순하고, 원시적인 유형의 테스트 대역이다.
-기본적으로 아무 일도 하지 않는 구현체로 인스턴스화가 필요한 경우 사용한다.
-만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

스텁(Stub)

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
-이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

스파이(Spy)

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
-예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

목, 모의 객체(Mock)

목은 더미, 스텁, 스파이를 포함한다.
+

"test" 태그로 연결된 2개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

테스트 대역이란?

+

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
+Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

+

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
+외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

+

테스트 대역의 타입 계층 구조

+ +

더미(Dummy)

+

가장 단순하고, 원시적인 유형의 테스트 대역이다.
+기본적으로 아무 일도 하지 않는 구현체로 인스턴스화가 필요한 경우 사용한다.
+만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

+

스텁(Stub)

+

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
+이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

+

스파이(Spy)

+

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
+예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

+

목, 모의 객체(Mock)

+

목은 더미, 스텁, 스파이를 포함한다.
호출 시 사전에 정의된 결과를 반환하고, 예상치 못한 호출이 있을 경우 예외를 던질 수 있다.
-또한 호출에 대한 검증을 할 수 있다.

가짜(Fake)

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
-예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

DOC(depended-on component)

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
-테스트 더블은 DOC와 동일한 API를 제공해야 한다.

상호작용에 따른 목과 스텁 구분

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
-목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
SUT(system under test)

테스트 대상 시스템
-테스트를 하려는 대상

참고 자료

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
+또한 호출에 대한 검증을 할 수 있다.

+

가짜(Fake)

+

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
+예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

+

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
+테스트 더블은 DOC와 동일한 API를 제공해야 한다.

+

상호작용에 따른 목과 스텁 구분

+

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
+목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

+
TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
+

테스트 대상 시스템
+테스트를 하려는 대상

+

참고 자료

+

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
단위 테스트 - 5장 목과 테스트 취약성, 블라디미르 코리코프
테스트 주도 개발 시작하기 - 7장 대역, 최범균
-테스트 더블, Martin Fowler
-테스트 관련 용어 정리, Johngrib
-Test Double, Gerard Meszaros

- - +테스트 더블, Martin Fowler
+테스트 관련 용어 정리, Johngrib
+Test Double, Gerard Meszaros

\ No newline at end of file diff --git a/tags/time.html b/tags/time.html index d8b5601f4..8067c1b9f 100644 --- a/tags/time.html +++ b/tags/time.html @@ -2,8 +2,8 @@ - -"Time" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Time" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,20 +12,47 @@ - - - + + + -
-

"Time" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 2분

이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
+

"Time" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 2분

이전에 많은 문제가 있던 자바의 클래스(Calendar, Date)를 대체하는 날짜와 시간 API
ISO-8601을 기반으로 작성
-설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

ISO-8601

날짜와 시간에 관련된 데이터를 다루는 국제 표준

LocalDate, LocalTime, LocalDateTime

날짜와 시간을 표현하는 클래스

Instant

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
-기계의 관점에서 시간 표현

Duration, Period

간격을 표현하는 클래스

TemporalAdjusters

복잡한 날짜 조정이 필요할 때 사용
-필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal temporal);
}

DateTimeFormatter

날짜와 시간 포맷 클래스
-특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

ZoneId, ZoneOffset

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
-ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

Instant instant = Instant.now();
LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

참고 자료

- - +설계 목표 → 불변, Fluent API, 명확하고 명시적, 확장 가능성

+

날짜와 시간에 관련된 데이터를 다루는 국제 표준

+

LocalDate, LocalTime, LocalDateTime

+

날짜와 시간을 표현하는 클래스

+

Instant

+

유닉스 시간(1970-01-01, 00:00:00 UTC) 기준으로 특정 지점까지의 시간을 초로 표현하는 클래스
+기계의 관점에서 시간 표현

+

Duration, Period

+

간격을 표현하는 클래스

+

TemporalAdjusters

+

복잡한 날짜 조정이 필요할 때 사용
+필요한 경우 다음 인터페이스를 구현하여 커스텀 TemporalAdjuster를 구현 가능

+
@FunctionalInterface
+public interface TemporalAdjuster {
+    Temporal adjustInto(Temporal temporal);
+}
+
+

DateTimeFormatter

+

날짜와 시간 포맷 클래스
+특정 날짜 패턴이나, DateTimeFormatterBuilder를 이용해서 커스텀한 포맷을 생성 가능

+

ZoneId, ZoneOffset

+

ZoneId는 지역 ID는 ‘지역/도시’ 형식, ZoneOffset은 시차 UTC 기준 고정된 시간 차이 이용
+ZoneId의 경우 IANA Time Zone Database에서 제공하는 지역 집합 정보 사용

+
Instant instant = Instant.now();
+LocalDateTime utc = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
+
+

참고 자료

+
\ No newline at end of file diff --git a/tags/transaction.html b/tags/transaction.html index 1e7c2c935..e08d1317d 100644 --- a/tags/transaction.html +++ b/tags/transaction.html @@ -2,8 +2,8 @@ - -"Transaction" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"Transaction" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,37 +12,139 @@ - - - + + + -
-

"Transaction" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

트랜잭션(Transaction)

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
+

"Transaction" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 10분

트랜잭션(Transaction)

+

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
트랜잭션은 작업의 완전성과 데이터의 정합성을 보장해 준다.
-논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

트랜잭션의 속성(ACID)

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
+논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

+

트랜잭션의 속성(ACID)

+

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
일관성(Consistency): 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지해야 한다.
격리성(Isolation): 각각의 트랜잭션은 독립적이라 서로에게 영향을 주지 않아야 한다.
-지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

트랜잭션 주의사항

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
-구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

왜 네트워크 작업이 있을 때 트랜잭션에서 배제해야 할까? 🤔

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
-네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)

격리 수준(Isolation level)

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
-격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

READ UNCOMMITTED

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
+지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

+

트랜잭션 주의사항

+

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
+구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

+

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
+네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

    +
  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • +
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)
  • +
+

격리 수준(Isolation level)

+

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
+격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

+

READ UNCOMMITTED

+

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
더티 리드 현상이 발생하기 때문에 정합성의 문제가 많은 격리 수준이다.
-MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

READ COMMITTED

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
+MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

+ +

READ COMMITTED

+

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
오라클 DBMS에서 기본으로 사용되는 격리 수준이다.
-REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

REPEATABLE READ

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
+REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

+ +

REPEATABLE READ

+

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준이다.
MVCC를 이용해 언두(Undo) 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
-동일한 결과를 보장하는 방법은 다음과 같다.

  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

갭 랍(Gap lock)과 넥스트 키 락(Next-key lock)

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

MVCC(Multi Version Concurrency Control)

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

SERIALIZABLE

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
+동일한 결과를 보장하는 방법은 다음과 같다.

+
    +
  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • +
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • +
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • +
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.
  • +
+

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

+ +

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

+

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

    +
  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • +
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)
  • +

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

+

SERIALIZABLE

+

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 접근할 수 없고 단순한 읽기 작업도 공유 잠금(읽기 잠금)을 획득해야만 한다.
-InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

격리 수준에 따른 부정합 문제

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX

더티 리드(Dirty read)

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
+InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

+

격리 수준에 따른 부정합 문제

+

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

+
격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX
+

더티 리드(Dirty read)

+

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
트랜잭션 격리 수준이 READ UNCOMMITTED일 때 발생한다.
-예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

반복 가능하지 않은 조회(Non-repeatable read)

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
-예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

팬텀 리드(Phantom read, Phantom row)

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
-예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Isolation Level, MySQL

- - +예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

+

반복 가능하지 않은 조회(Non-repeatable read)

+

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
+예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

+ +

팬텀 리드(Phantom read, Phantom row)

+

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
+예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

+ +

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Isolation Level, MySQL

\ No newline at end of file diff --git a/tags/web-application.html b/tags/web-application.html index 37d4c418d..0babb0194 100644 --- a/tags/web-application.html +++ b/tags/web-application.html @@ -2,8 +2,8 @@ - -"web application" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"web application" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,36 +12,70 @@ - - - + + + -
-

"web application" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+

"web application" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

웹 애플리케이션 발전 과정

+

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.
-원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.

WWW(1989)

정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.

CGI(1993)

CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.

Servlet(1996)

Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.
-하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.

JSP(1999)

JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.
-JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.

MVC(2000)

위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.

I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
-Govind Seshadri

이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.
-해당 문서를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.

Spring Framework(2003)

Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.
+원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.

+ +

WWW(1989)

+

정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.

+

CGI(1993)

+

CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.

+

Servlet(1996)

+

Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.
+하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.

+

JSP(1999)

+

JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.
+JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.

+ +

MVC(2000)

+

위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.

+
+

I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
+Govind Seshadri

+
+

이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.
+해당 문서를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.

+

Spring Framework(2003)

+

Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.
J2EE는 웹 기반의 엔터프라이즈 애플리케이션을 구축하기 위한 플랫폼으로 위에서 설명한 Servlet, JSP, EJB 등의 기술을 포함하고 있다.
하지만 이중 EJB라는 기술이 J2EE의 핵심 기술이었는데, 해당 기술이 매우 복잡했기 때문에 사용에 문제가 많았다고 한다.
-2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 Expert One-to-One J2EE Development라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.

스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.

WebFlux 이전 Servlet 3.0(2009), 3.1(2013)

Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.
-그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.

Spring WebFlux(2017)

적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.
-추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.

마치며

해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.
-그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.

참고 자료

웹 애플리케이션의 발전 과정, 구구 강의
-Dynamic Content with CGI, Apache Tutorial
-History of Spring and the Spring Framework, Spring
-Understanding JavaServer Pages Model 2 architecture, Govind Seshadri
-MVC, XEROX PARC
-Expert One-to-One J2EE Development, Rod Johnson
-배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족
-Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu -WebFlux Overview, Spring -Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2
-Spring WebFlux란 무엇일까

- - +2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 Expert One-to-One J2EE Development라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.

+

스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.

+

WebFlux 이전 Servlet 3.0(2009), 3.1(2013)

+

Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.
+그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.

+

Spring WebFlux(2017)

+

적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.
+추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.

+

마치며

+

해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.
+그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.

+

참고 자료

+

웹 애플리케이션의 발전 과정, 구구 강의
+Dynamic Content with CGI, Apache Tutorial
+History of Spring and the Spring Framework, Spring
+Understanding JavaServer Pages Model 2 architecture, Govind Seshadri
+MVC, XEROX PARC
+Expert One-to-One J2EE Development, Rod Johnson
+배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족
+Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu +WebFlux Overview, Spring +Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2
+Spring WebFlux란 무엇일까

\ No newline at end of file diff --git a/tags/web-socket.html b/tags/web-socket.html index 64cbd8456..326a7d9a1 100644 --- a/tags/web-socket.html +++ b/tags/web-socket.html @@ -2,8 +2,8 @@ - -"WebSocket" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG + +"WebSocket" 태그로 연결된 1개 게시물개의 게시물이 있습니다. | GG @@ -12,27 +12,71 @@ - - - + + + -
-

"WebSocket" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

웹소켓

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
-웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

웹소켓 등장 배경

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
-이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

polling, long polling, streaming

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.

웹소켓의 동작

1. Upgrade 요청

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
+

"WebSocket" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

웹소켓

+

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
+웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

+

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

+

웹소켓 등장 배경

+

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
+이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

+

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

    +
  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • +
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.
  • +

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

    +
  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.
  • +

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

    +
  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.
  • +
+

웹소켓의 동작

+ +

1. Upgrade 요청

+

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
이는 HTTP와 같이 80, 443 포트를 사용한다.
웹소켓으로 전환하기 위해서는 Upgrade: websocket, Connection: Upgrade 헤더가 필요하다.
Sec-WebSocket-Key는 서버에서 Sec-WebSocket-Accept를 계산하여 응답하고 이 값이 예상한 값과 다르면 연결이 수립되지 않는다.
Sec-WebSocket-Protocol의 경우 서브프로토콜의 목록으로 서버 측에서는 해당 목록 중 하나를 선택하여 반환해야 한다.
-만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

GET /chats HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

2. Switching Protocols

서버는 101 Switching Protocols 응답을 반환한다.
+만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

+
GET /chats HTTP/1.1
+Host: localhost:8080
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
+Sec-WebSocket-Protocol: v10.stomp, v11.stomp
+Sec-WebSocket-Version: 13
+Origin: http://localhost:8080
+
+

2. Switching Protocols

+

서버는 101 Switching Protocols 응답을 반환한다.
Sec-WebSocket-Accept은 Sec-WebSocket-Key 뒤에 258EAFA5-E914-47DA-95CA-C5AB0DC85B11를 붙이고 SHA1로 해싱 후 Base64로 인코딩하여 반환한다.
-이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

3. 통신 후 종료

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
-연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

참고 자료

https://datatracker.ietf.org/doc/html/rfc6455
-https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
-https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
-https://docs.spring.io/spring-framework/reference/web/websocket.html

- - +이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

+
HTTP/1.1 101 Switching Protocols 
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
+Sec-WebSocket-Protocol: v10.stomp
+
+

3. 통신 후 종료

+

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
+연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

+

참고 자료

+

https://datatracker.ietf.org/doc/html/rfc6455
+https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
+https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
+https://docs.spring.io/spring-framework/reference/web/websocket.html

\ No newline at end of file diff --git a/tags/woowahan-techcourse.html b/tags/woowahan-techcourse.html index 0fb5f1c31..6a6d9c128 100644 --- a/tags/woowahan-techcourse.html +++ b/tags/woowahan-techcourse.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,34 +12,66 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 9분

리팩터링 미션

요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.
-미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.

1, 2단계

1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. +

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 9분

1단계: https://github.com/woowacourse/jwp-refactoring/pull/465
+2단계: https://github.com/woowacourse/jwp-refactoring/pull/547
+3단계: https://github.com/woowacourse/jwp-refactoring/pull/610
+4단계: https://github.com/woowacourse/jwp-refactoring/pull/721

+

리팩터링 미션

+

요구사항 작성 → 테스트를 통한 코드 보호 → 리팩터링 → 의존성 리팩터링 → 멀티모듈 순서로 미션을 진행했다.
+미션에 온전히 집중하고 싶었지만, 프로젝트와 병행하면서 진행했기에 어느정도 타협보고 진행한 부분이 많아서 아쉬웠다.

+

1, 2단계

+

1단계는 요구사항을 작성하고, 테스트 코드를 작성하여 추후에 리팩터링 할 때 안정감 있게 진행할 수 있도록 준비하는 과정이었다. 요구사항을 작성할 때 제공된 용어 사전을 최대한 활용하면서 기존의 코드를 보면서 요구사항을 정리했다. -테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.

최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.
-리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.

2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.
+테스트는 시간 관계상 API, 서비스 둘 중 하나만 통합 테스트를 진행해야겠다는 생각이 들었다.

+

최종적으로 서비스 기준으로 통합 테스트를 작성했는데 약간 후회되는 결정이었던 것 같다.
+리팩터링 과정에서 API 명세가 바뀌지 않아야 한다는 것을 기준을 잡고 이번 미션을 한다고 가정했을 때 API 기준으로 테스트를 작성하고, 리팩터링을 진행하는 것이 더 안정감 있다고 생각한다.

+

2단계는 작성된 테스트 기반으로 리팩터링 하는 미션이었다.
서비스에서 도메인을 직접 반환하는 구조였는데, 도메인에 JPA를 적용하면 기존 명세와 달라질 것을 우려해서 DTO로 수정하는 작업을 먼저 진행했다. DTO 이후에 서비스에 있는 로직을 도메인으로 이동시키고, 최종적으로 JPA를 적용하는 순서로 리팩터링을 진행했다. -이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.

소프트웨어의 복잡성을 다루는 지혜

중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.
-소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 도메인 주도 설계의 부제이다.

도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.
-유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.

간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.

단어설명
도메인소프트웨어로 해결하고자 하는 문제 영역
바운디드 컨텍스트해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위
유비쿼터스 언어프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어
전략적 설계도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정
전술적 설계전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정

이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.

3, 4단계

제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.

3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. -함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.

의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. -처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.

4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.
+이 과정에서 의존성 방향이 양방향인 부분도 생겨났다.

+

소프트웨어의 복잡성을 다루는 지혜

+

중간에 소프트웨어 복잡성을 다루는 지혜에 관한 제이슨의 강의가 있었다.
+소프트웨어의 복잡성을 다루는 지혜는 에릭 에반스의 저서 도메인 주도 설계의 부제이다.

+

도메인 주도 설계는 유비쿼터스 언어, 전략적 설계, 전술적 설계가 중요하다고 한다.
+유비쿼터스 언어, 전략적 설계가 전체의 90%에 해당할 정도로 중요하다고 한다. 또한 전술적 설계만 하는 경우를 DDD Lite 라고 한다.

+

간단히 도메인 주도 설계에서 나오는 단어를 정리한다면 다음과 같다.

+
단어설명
도메인소프트웨어로 해결하고자 하는 문제 영역
바운디드 컨텍스트해결 영역, 관심사를 분리하고 격리하여 문제 해결에 집중할 범위
유비쿼터스 언어프로젝트에 이해관계자들의 공통된 언어로, 서로의 의사소통 비용을 줄이기 위해 사용하는 언어
전략적 설계도메인 전문가와 개발자가 함께 유비쿼터스 언어를 이용하여 도메인과 관련된 지식을 이해하고 이를 바탕으로 경계를 나눠 바운디드 컨텍스트를 정의하고, 컨텍스트 맵을 생성하는 것을 포함하는 과정
전술적 설계전략적 설계에서 정의한 바운디드 컨텍스트와 도메인을 이용하여 애그리거트, Entity와 VO, Repository 등을 구현하는 과정
+

이 외에도 다양한 내용들이 나왔지만, 지식을 제대로 흡수하지는 못했다.

+

3, 4단계

+

제이슨의 강의를 듣고, 조영호님의 우아한객체지향 유튜브 영상을 본 다음 3, 4단계를 진행했다.

+

3단계는 의존성 리팩터링에 관한 내용이었다. 클래스 간 방향, 패키지 간 방향을 단방향이 되도록 리팩터링을 진행해야 했었다. +함께 생성되고 삭제되는 객체들을 묶고, 결합도를 낮추기 위해 생명주기가 다르다면 id를 이용하여 참조하도록 변경했다.

+

의존성을 분리하기 위해 이벤트도 사용해보았다. 이벤트는 현재 기준으로 과거에 벌어진 것을 표현하기 때문에 이벤트명은 과거 시제가 되어야하는 것을 알았다. +처음에는 애플리케이션 이벤트를 사용했지만, 서비스 로직을 최대한 간단하게 하기 위해 도메인 이벤트도 사용해보았다.

+

4단계는 멀티모듈로 분리하는 미션이었는데 3단계에서 분리해둔 패키지 그대로 분리하지는 않았다.
3단계에서는 함께 생성되고 삭제되는 객체 기준으로 분리했다. 4단계에서는 내가 인식하기 편한 기준으로 분리를 했다. -아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.

추가로 테스트 격리를 위한 @ServiceTest 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. -따라서 TestFixtures를 사용하여 해결했다.

마무리

우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.
-바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.

참고 자료

도메인 원정대, 우아콘 2021
-우아한객체지향, 우아한테크세미나
-TestFixtures, 권남님

- - +아직 분리한 기준에 대한 근거가 모호했고, 이에 대한 공부를 조금 더 해야겠다고 생각했다.

+ +

추가로 테스트 격리를 위한 직접 작성한 @ServiceTest 커스텀 애너테이션이 있었는데, 상위 모듈의 테스트에서 만든 클래스를 하위 모듈에서는 사용할 수 없었다. +따라서 TestFixtures를 사용하여 해결했다.

+

마무리

+

우아한테크코스의 마지막 미션이니 만큼, 가장 흥미로운 미션이었고 배울점도 많았던 것 같다.
+바쁜 기간이라 많은 리뷰를 남기지 못했던 리뷰이 호이에게 미안하고, 코멘트 꼼꼼하게 달아주고 미션에 대한 이야기도 오프라인으로 많이 나눈 리뷰어 테오에게 너무 감사하다.

+

참고 자료

+

도메인 원정대, 우아콘 2021
+우아한객체지향, 우아한테크세미나
+TestFixtures, 권남님

\ No newline at end of file diff --git a/tags/woowahan-techcourse/page/10.html b/tags/woowahan-techcourse/page/10.html index 78fd5dc26..78527eadd 100644 --- a/tags/woowahan-techcourse/page/10.html +++ b/tags/woowahan-techcourse/page/10.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,28 +12,47 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

웹 장바구니 미션

장바구니 미션은 블랙캣이랑 진행했다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

1단계: https://github.com/woowacourse/jwp-shopping-cart/pull/244
+2단계: https://github.com/woowacourse/jwp-shopping-cart/pull/300

+

웹 장바구니 미션

+

장바구니 미션은 블랙캣이랑 진행했다.
요구사항이 엄청 복잡한 미션은 아니었고, 스프링을 사용하여 기본적인 CRUD를 구현하는 미션이었다.
2단계에서는 Basic 인증을 통해 자신의 장바구니에만 상품을 담고, 제거할 수 있도록 구현하는 요구사항이 추가되었다.
Interceptor나 Argument Resolver에 대한 이해도가 높지 않았는데, 이번 미션을 통해 조금 더 알아간 느낌이다.
-이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

새로 학습한 부분

DTO 우발적 중복

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

dto1

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
-로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
-따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

dto2

Interceptor에서 인증한 값 재사용

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
-일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
+이전에 스프링 사용할 때는 아무 생각 없이 코드를 작성하는 경우가 많았는데, 코드를 작성할 때 근거가 생기고 있는 것 같다.

+

새로 학습한 부분

+

DTO 우발적 중복

+

장바구니 미션에서는 상품 추가와 상품 수정에 대한 요구사항이 있었다.

+

dto1

+

클래스명을 제외하고 필드와 검증 로직 그 외 모든 게 같은 DTO를 보며 중복이라고 생각을 했고, 반대로 용도가 다르기 때문에 중복이 아니라고 생각하기도 했다.
+로버트 마틴님이 집필하신 클린 아키텍처는 아래와 같이 중복을 여러 가지 종류로 나누어 설명하고 있다.

+
    +
  • 진짜 중복: 한 인스턴스가 변경되면, 동일한 변경을 그 인스턴스의 모드 복사본에 반드시 적용해야 한다.
  • +
  • 우발적 중복: 중복으로 보이는 두 코드 영역이 각자의 경로로 발전한다면, 즉 서로 다른 속도와 다른 이유로 변경된다면 이 두 코드는 진짜 중복이 아니다.
  • +
+

추가와 수정은 초기에는 중복으로 보이지만 초기 생성 시에만 기입하는 데이터들이 추가되거나, 시간이 지나면서 서로 달라질 가능성이 높아진다.
+따라서 리뷰어 웨지가 아래와 같이 의존 역전을 이용하는 방법도 있다고 알려주셨다.

+

dto2

+

Interceptor에서 인증한 값 재사용

+

사실 조회를 두 번 하기 싫어서 다양한 방법을 생각했었는데 이번 미션에서는 ThreadLocal을 사용했다.
+일단 Tomcat은 요청마다 다른 스레드를 사용하고, Interceptor에서 조회해서 만든 Credential을 ThreadLocal에 넣어두었다가 ArgumentResolver에서 꺼낸 다음 ThreadLocal을 clear 하면 문제가 없을 거라 판단했다.

+

리뷰어인 웨지에게도 어떤 방법을 사용할지 궁금증을 작성했었다.
웨지는 email에 index를 걸어두고 dao 재조회를 사용할 것이라고 했다.
-재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

페어에게 배울 부분

기록

블랙캣은 기록을 굉장히 잘 하는 크루였다.
+재사용하지 않고 db에 인덱스를 걸 생각은 하지 못했는데, 제일 직관적이고 좋은 방법이라고 생각했다.

+

페어에게 배울 부분

+

기록

+

블랙캣은 기록을 굉장히 잘 하는 크루였다.
노션에 페어를 진행하면서 했던 내용 + 고민했던 부분 + 회고를 꼼꼼하게 기록해서 공유해 주었다.
-추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

의견 일치시키기

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
+추가적으로 이모지를 적극적으로 사용하여 더욱 좋았다!

+

의견 일치시키기

+

페어 시간은 한정되어 있고, 기간 내 요구사항을 만족해야 한다.
따라서 적당히 타협을 봐서 의견을 빠르게 수용해 데드라인을 맞추는 것도 중요하다고 생각한다.
-블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

- - +블랙캣은 내 의견을 잘 들어줬고, 덕분에 막히는 부분 없이 빠르게 미션을 진행할 수 있었다.

+

빨리 친해졌고, 의사소통이 잘 돼서 재밌게 코딩할 수 있었다!

\ No newline at end of file diff --git a/tags/woowahan-techcourse/page/11.html b/tags/woowahan-techcourse/page/11.html index c66b67b24..924fc5d93 100644 --- a/tags/woowahan-techcourse/page/11.html +++ b/tags/woowahan-techcourse/page/11.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,33 +12,50 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

웹 자동차 미션

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

1단계: https://github.com/woowacourse/jwp-racingcar/pull/24
+2단계: https://github.com/woowacourse/jwp-racingcar/pull/128

+

웹 자동차 미션

+

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
웹 자동차 미션에서는 비버와 페어가 매칭되었다.
-레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
-첫 미션이라 그런지 특별한 부분은 없었고, 최대한 깔끔하게 작성하려고 노력했다.
+레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

+

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
+첫 미션이라 그런지 특별한 부분은 없었고, 최대한 깔끔하게 작성하려고 노력했다.
난이도 높은 미션이 아니었지만 리뷰어인 라빈에게 칭찬을 많이 받아서 기분이 좋았다.
-라빈 감사합니다!

부족했던 부분

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
+라빈 감사합니다!

+

부족했던 부분

+

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
미션이 다소 여유롭다고 느껴져서, 시간에 대한 부분도 잘 관리하지 못한 것 같다.
-미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
+미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

+

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
도전적이지 않거나 시간이 부족하지 않으면 집중을 잘 못하는 것 같다.
-머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

새로 학습한 부분

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@Transactional
@AutoConfigureMockMvc
@SpringBootTest
public class RacingGameIntegrationTest {

페어에게 배울 부분

비버의 성격
+머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

+

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

+

새로 학습한 부분

+

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

+
@SuppressWarnings("NonAsciiCharacters")
+@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
+@Transactional
+@AutoConfigureMockMvc
+@SpringBootTest
+public class RacingGameIntegrationTest {
+
+

페어에게 배울 부분

+

비버의 성격
비버가 성격이 좋아서 편하게 페어를 할 수 있었다.
-미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

미션에 집중하는 부분
+미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

+

미션에 집중하는 부분
내가 미션에 잘 집중하지 못했는데도 같이 페어를 잘 진행한 것 같아서 좋았다.
비버가 미션에 잘 집중해서 그렇지 않았나 생각했다.
근육맨 비버라 그런지 체력이 좋아서 그런가?
-중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

학습에 대한 열정
+중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

+

학습에 대한 열정
추가적으로 알고 싶은 부분을 따로 학습하는 열정이 좋다고 생각했다.
비버와 스프링에 대해 알아가는 시간을 많이 가진 부분이 매우 좋았다.
나도 5월부터 조금 더 화이팅 해야겠다.

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/12.html b/tags/woowahan-techcourse/page/12.html index d1e3129af..1ded3cf94 100644 --- a/tags/woowahan-techcourse/page/12.html +++ b/tags/woowahan-techcourse/page/12.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,45 +12,78 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

레벨 1이 끝났다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

레벨 1이 끝났다.
우테코를 시작하기 전 내가 정해두었던 목표 이상으로 달성했기 때문에 매우 만족스럽다.
혼자 독학을 할 땐 이 방향으로 공부하는 게 맞는지 계속 반추하다 결국 무기력함에 빠져들었다.
-하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

Keep

나만의 루틴 만들기

스스로가 외부의 영향을 많이 받는다고 생각한다.
-최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
+하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

+

Keep

+

나만의 루틴 만들기

+

스스로가 외부의 영향을 많이 받는다고 생각한다.
+최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

+

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
소화능력이 부족하기 때문에 점심은 도시락(그래봤자 계란2개)을 준비하고
항상 똑같은 컨디션을 유지하기 위해 항상 6시에 집에 간다.
-이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

크루들과 친하게 지내기

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
+이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

+

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

+

크루들과 친하게 지내기

+

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
하다 보니 더 많은 크루들의 닉네임을 외운 것 같다.
-앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

글쓰기

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
-매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
+앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

+

글쓰기

+

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
+매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

+

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
사실 겉으로 드러내지 않았지만 꼭 받아보고 싶었다.
-글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

코드 리뷰 스터디

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
+글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

+

코드 리뷰 스터디

+

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
과연 도움이 될까 생각했지만 결과적으로는 코드 리뷰를 하면서 성장을 많이 한 것 같다.
투자한 시간 대비 가성비가 좋은 활동이었다.
-누누가 스터디장인데 과연 꾸준히 이어나가려나?

레벨 인터뷰

인터뷰할 때 많이 떨지 않아서 좋았다.
+누누가 스터디장인데 과연 꾸준히 이어나가려나?

+

레벨 인터뷰

+

인터뷰할 때 많이 떨지 않아서 좋았다.
남들 앞에서 이야기를 하거나, 면접을 보면 항상 엄청 떨어서 걱정했는데
기술적인 질문을 받았을 때 떨지 않고 잘 대답할 수 있었다.
-우아한테크코스 생활을 하면서 다른 크루가 질문했을 때, 최대한 이해하기 쉽게 설명하려고 했던 경험이 도움이 된 것 같다.
-이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • 두괄식 표현
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • 설명할 수 있을만큼 시간 충분히 가지기
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • 끝맺는 부분 연습하기(자신감 있게)
  • 기술적인 집착가지기
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기

Problem

페어프로그래밍

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
+우아한테크코스 생활을 하면서 다른 크루가 질문했을 때, 최대한 이해하기 쉽게 설명하려고 했던 경험이 도움이 된 것 같다.
+이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

+
    +
  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • +
  • 두괄식 표현
  • +
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • +
  • 설명할 수 있을만큼 시간 충분히 가지기
  • +
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • +
  • 끝맺는 부분 연습하기(자신감 있게)
  • +
  • 기술적인 집착가지기
  • +
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기
  • +
+

Problem

+

페어프로그래밍

+

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
페어는 매번 바뀌고, 미션의 복잡도도 증가하기 때문인 것 같다.
소통 능력, 시간관리가 부족했고, 만족스럽지 않았다.
하지만 페어를 진행하고, 회고를 하다 보니 나만의 노하우가 쌓이는 느낌이다.
-레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

집중하는 시간⏱️ 부족

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
-이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

Try

허브🌿와의 티타임?

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
+레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

+

집중하는 시간⏱️ 부족

+

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
+이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

+

Try

+

허브🌿와의 티타임?

+

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
예를 들어 잡담방에 저와 커피챗 하실 분 :) 하면서 올릴 수 있을 것 같다.
참여하는 사람이 있을지, 안 좋게 보는 게 아닐지 걱정되지만 그래도 재밌을 것 같다.
-저랑 허브티 한잔 하실래요?

기술적인 부분

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
+저랑 허브티 한잔 하실래요?

+

기술적인 부분

+

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
시간의 여유가 될 때 책을 조금씩 읽어야겠다.
-블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

레벨 1을 마무리하며

시간이 빠르게 흘러갔다.
+블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

+

레벨 1을 마무리하며

+

시간이 빠르게 흘러갔다.
타인에게 좋은 영향을 주기위해, 방학동안 나를 챙기는 시간을 가져야겠다.
또한 함께 일하고 싶은 사람을 목표로 앞으로도 꾸준히 의식적 노력을 해야겠다.

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/13.html b/tags/woowahan-techcourse/page/13.html index 6f0147ed8..0e903d9b6 100644 --- a/tags/woowahan-techcourse/page/13.html +++ b/tags/woowahan-techcourse/page/13.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,49 +12,84 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

체스

체스 미션에는 가비와 페어가 매칭되었다!
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

1, 2단계: https://github.com/woowacourse/java-chess/pull/441
+3, 4단계: https://github.com/woowacourse/java-chess/pull/529

+

체스

+

체스 미션에는 가비와 페어가 매칭되었다!
체스는 이전 미션들보다 훨씬 복잡한 도메인이었다.
하지만 가비와 나는 체스 도메인이 익숙해서 더 편한 마음으로 시작할 수 있었다.
-미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
-최종적으로 결정한 부분은 다음과 같다.

각 기물의 이동 가능여부
+미션을 진행하면서 어려웠던 부분은 기물의 이동, 이동시 경로에 기물이 존재하는지 확인하는 부분이었다.

+

가비가 집에가서도 기물의 이동 관련해 생각 정리한 글을 보내줘서 더욱 빨리 진행할 수 있었다.
+최종적으로 결정한 부분은 다음과 같다.

+

각 기물의 이동 가능여부
Rank와 File은 각각 위치값을 가지고 있고, 값의 차이를 이용해서 각 기물의 이동 가능 여부를 계산했다.
직선 → Rank와 File 차이 중 하나가 0이어야 한다.
대각선 → Rank와 File 차이의 절대값이 같아야 한다. ex) abs(-2) == abs(2)
-나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

도착 칸의 기물 여부
+나이트 → 차이의 절대값이 하나는 2 나머지 하나는 1이어야 한다.

+

도착 칸의 기물 여부
아군 → 이동이 불가능하다.
-적군 → 이동이 가능하다. 적군을 잡는다.

중간에 기물 존재 여부
-이동 경로에 기물이 존재하면 안된다.

데이터베이스 사용
+적군 → 이동이 가능하다. 적군을 잡는다.

+

중간에 기물 존재 여부
+이동 경로에 기물이 존재하면 안된다.

+

데이터베이스 사용
체스 미션은 특별하게 데이터베이스와 연결하는 부분이 있었다.
-체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

  • 기물 전체를 저장하는 방법
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
-기물 전체를 저장하지 않은 이유는 다음과 같다.

  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
+체스 게임의 상태를 다음의 두가지 방법으로 정할 수 있다고 생각했다.

+
    +
  • 기물 전체를 저장하는 방법
  • +
  • 기보를 저장하고 게임을 불러와 기보대로 이동시키는 방법
  • +
+

기물이 이동할 때마다 값을 저장하고 싶었고, 기보를 저장하는 방법을 선택했다.
+기물 전체를 저장하지 않은 이유는 다음과 같다.

+
    +
  • 턴과 같은 부가적인 요소를 저장해야 한다.
  • +
  • 이동을 할 때 기물이 잡히는 경우 update 쿼리(이동 기물)와 delete(잡힌 기물) 2개의 쿼리를 날려야 한다.
  • +
  • 현재 구조에서 도메인의 변경이 크게(초기 상태를 구성하는 부분) 일어나야 한다.
  • +
+

정리하자면 기물 전체 저장과 기보 저장은 다음과 차이가 있다.
보드저장: 초기상태에서 32개의 Insert 쿼리(기물의 위치) + 기물 이동 시 움직임 변경(잡히는 경우 2개의 쿼리)
-기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

추가로 기보저장이 구현도 더욱 간단하다. 👍

부가적인 부분

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

  • 누누의 도움으로 ConnectionPool 구현
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

부족했던 부분

꼼꼼하게 코드를 작성하지 못한 부분
+기보저장: 초기상태 애플리케이션에서 구성 + 저장된 기보를 select 쿼리로 조회해서 사용(1회) + insert 쿼리(이동 당 1회)

+

추가로 기보저장이 구현도 더욱 간단하다. 👍

+

부가적인 부분

+

리뷰어인 찰리🍫가 동시에 여러 게임이 진행된다면 어떨지? 에 대한 코멘트를 남겨주셔서 다양한 시도를 해봤다.

+
    +
  • 누누의 도움으로 ConnectionPool 구현
  • +
  • ThreadLocal 사용해서 쓰레드 별 세션 관리
  • +
  • 실제로 애플리케이션 내에서 체스 게임이 진행되는 Board를 ConcurrentHashMap으로 저장(사실 이 부분은 현재 구조에서 필요없지만 2명이 서로 게임하는 경우를 생각해서 넣어보았다.)
  • +
+

두 명이 서로 같은 방에 입장하여 게임을 진행한다면 출력하는 부분이 까다로워질 것 같다고 예상되어(Board에 옵저버 패턴을 사용해야되나?) 해볼 엄두가 나지 않았다.

+

부족했던 부분

+

꼼꼼하게 코드를 작성하지 못한 부분
DB 관련 부분을 꼼꼼하게 코딩을 하지 못했다.
도메인 로직에만 집중하다보니 정적 중요한 DB의 코드의 예외처리, 빈 값을 반환 하는 부분을 꼼꼼하게 처리하지 못했다.
-하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

시간에 대한 부담감
+하지만 찰리의 꼼꼼한 리뷰로 DB부분과 나만의 JdbcTemplate을 깔끔하게 구현할 수 있었다.

+

시간에 대한 부담감
초반에는 여유롭지만 제출 마감에 가까워질 수록 사람이 급해지는 것 같다.
-다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

새로 학습한 부분

DAO 중복 제거

프롤로그에 을 작성했다.
+다음 페어프로그래밍할 땐 속도를 조절하고, 마음에 여유를 가져야겠다.

+

새로 학습한 부분

+

DAO 중복 제거

+

프롤로그에 을 작성했다.
DAO를 작성하는데 try-catch-resources와 여러 코드가 중복되서 제거하고싶었다.
-템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

페어에게 배울 부분

페어 생각하기
+템플릿 콜백 패턴으로 깔끔하게 중복을 제거할 수 있었다.👍

+

페어에게 배울 부분

+

페어 생각하기
가비는 누구보다 페어를 생각하고, 배려해주는 페어였다.
-중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

미션 몰입하기
+중간 중간 당 떨어질까봐 걱정도 해주고, 나의 컨디션도 확인해줬다!

+

미션 몰입하기
최근에 미션에 잘 몰입하지 못했다.
가비는 페어를 진행할 때 미션에 대한 몰입도가 매우 좋았다.
집에가서도 체스 이동에 대한 로직을 어떻게 구현할 지 생각한 뒤 꼼꼼해서 정리해서 나에게 보내주었다.
덕분에 나도 가비의 생각을 알 수 있어서 미션을 진행하는데 가속도가 붙은 것 같다.
-또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

솔직함
+또한 미션을 잘 마무리하고 싶은 마음이 전달되서 그런지 나도 덩달아 열심히 미션을 할 수 있었다.😄

+

솔직함
먼저 회고하자고 말 걸어줘서 정말 고마웠다고 표현해주는 부분
모르는게 있으면 솔직하게 말해주는 부분
나의 의견을 정리하지 못한 상태로 전달할 때 이해가 안되었다고 정확히 전달해주는 부분
-솔직함은 페어할 때 중요한 부분인 것 같다.

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

- - +솔직함은 페어할 때 중요한 부분인 것 같다.

+

마지막으로 찰리🍫 체스 미션때 꼼꼼하게 리뷰 남겨주셔서 감사합니다!

\ No newline at end of file diff --git a/tags/woowahan-techcourse/page/14.html b/tags/woowahan-techcourse/page/14.html index 408b33357..db69153eb 100644 --- a/tags/woowahan-techcourse/page/14.html +++ b/tags/woowahan-techcourse/page/14.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,44 +12,60 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

블랙잭

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
-이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
-후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
-"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

1단계: https://github.com/woowacourse/java-blackjack/pull/427
+2단계: https://github.com/woowacourse/java-blackjack/pull/537

+

블랙잭

+

블랙잭 미션에서는 후추와 페어(조미료 듀오?)가 매칭되었다.
+이번에는 실수하지 않고, 바로 미션을 진행하지 않고 친해지기 부터 시작했다.

+

블랙잭은 구현해야 될 내용이 많아 시간이 많이 부족할 것 같았지만
+후추와 함께 전략적(삼일절에 미션 이야기 나누기)으로 미션을 진행해 시간 내에 제출할 수 있었다.

+

미션을 끝나고 회고를 했을 때 후추가 고민거리를 하나 내줬다.
+"페어를 진행할 때 압박감을 느끼는 페어가 있다면 허브가 해줄 수 있는게 뭐가 있을까?"

+

곰곰히 생각해봤지만 쉽게 답을 내릴 수 없었다.
중간 중간 회고를 하고, 나의 소프트스킬을 높히는게 답일까?
-부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
-터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

부족했던 부분

페어 신경쓰기
+부담감을 느끼지 않고 같이 일하고 싶은 사람이 될 수 있도록 계속 생각해봐야겠다.

+

이 부분에 대해 생각이 많아져서 전 리뷰어인 터틀🐢과도 대화를 나누었다.
+터틀은 제어할 수 없는 부분보다 제어할 수 있는 부분(궁극적인 목표인 좋은 코드를 작성하는 것)에 집중해보라고 하셨다.

+

좋은 코드, 좋은 페어에 대한 부분을 일단 지속적으로 생각해봐야겠다.

+

부족했던 부분

+

페어 신경쓰기
이번 페어할 때 적극적으로 의견을 내보도록 했다. 그렇기에 너무 의견을 강하게 밀어붙인 느낌이 들어서 미안했다.
후추가 압박을 느꼈을 수도 있을 것 같다는 생각이 든다.
-중간 중간 작은 회고를 진행해보는 것이 좋을까?

체력 관리
+중간 중간 작은 회고를 진행해보는 것이 좋을까?

+

체력 관리
요즘 잘 못먹는 것 같다.
-앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

중간 중간 돌아보기
+앞으로 살 날이 많은데 잘 챙겨먹고, 힘내야겠다.

+

중간 중간 돌아보기
이번 미션과 관련된 내용은 아니지만 우테코를 잘 활용 하고 있는지 생각을 해봐야겠다.
-내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

새로 학습한 부분

상태 패턴
+내가 우테코에 지원한 이유를 항상 잊지 않아야겠다.

+

새로 학습한 부분

+

상태 패턴
객체의 내부 상태에 따라 스스로 행동을 변경하도록 하는 패턴으로 if/else/switch와 같은 조건문을 효과적으로 제거할 수 있다.
블랙잭 미션을 진행하면서 상태 패턴에 대한 부분을 처음 적용해보았다.
-처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

일관성, 가독성, 추상화
+처음 적용하기 전에는 별로라고 생각했는데, 생각보다 괜찮은 것 같다.

+

일관성, 가독성, 추상화
이번 리뷰어는 검프🍫 였다!
검프의 리뷰는 간결함에 관련된 내용이 많았다.
일관성이 있는 코드, 가독성이 좋은 코드, 추상화가 잘 되어있는 코드
읽기 좋고, 간결한 방향으로 코드를 작성하는 방법을 배운 것 같다.
-코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

페어에게 배울 부분

생각 정리
+코드를 바라보는 시점이 하나 늘어난 기분이다!(앞으로 적용하는 것은 나의 몫이지만)

+

페어에게 배울 부분

+

생각 정리
중간 중간 현재 상황에 대해 그림을 그리거나, 글을 적으면서 정리한다.
페어와 동일한 부분을 이해하고 있는지 확인한다.
진행하는데 매우 도움이 되었던 것 같다.
-나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

가감없이 의견을 말해주는 부분
+나도 다음 페어때부터 펜이랑 종이를 준비해야겠다.

+

가감없이 의견을 말해주는 부분
진행 상황에 대한 부분, 진행 속도, 지금 자신이 이해하고 있는 부분을 말해줘서 편했다.
-회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

도메인 언어에 신경쓰는 부분
+회고때도 서로 솔직하게 의견을 주고 받아서 좋았다.

+

도메인 언어에 신경쓰는 부분
클래스명, 변수명과 같은 언어를 세심하게 신경쓴다.
-요구사항 정리도 깔끔하게 잘하는 것 같다.

후추 최고 👍

- - +요구사항 정리도 깔끔하게 잘하는 것 같다.

+

후추 최고 👍

\ No newline at end of file diff --git a/tags/woowahan-techcourse/page/15.html b/tags/woowahan-techcourse/page/15.html index fd59eceb8..3569c4856 100644 --- a/tags/woowahan-techcourse/page/15.html +++ b/tags/woowahan-techcourse/page/15.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,46 +12,150 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 11분

사다리 타기

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
-이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

2단계에서는 2가지 방법으로 구현해봤다.

  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법

Position 기준으로 사다리 게임을 진행하는 방법

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 11분

1단계: https://github.com/woowacourse/java-ladder/pull/97
+2단계: https://github.com/woowacourse/java-ladder/pull/234

+

사다리 타기

+

사다리 타기 미션에서는 우가와 페어가 매칭되었다.
+이전 미션과 달리 TDD로 진행하는 것이 필수였기 때문에 익숙하지 않았지만, 우가와 미션에 관한 소통이 잘 되어서 큰 문제 없이 미션을 마무리할 수 있었다.

+

우가와 이야기가 잘 통해서 그런지 1단계는 크게 어렵지 않게 진행할 수 있었는데, 2단계에서 많이 고전한 것 같다.

+

2단계에서는 2가지 방법으로 구현해봤다.

+
    +
  1. LadderGame에서 Position 기준으로 사다리 게임을 진행하는 방법
  2. +
  3. Player에게 Ladder를 넘겨서 Ladder에게 Position을 넘겨주며 메시지를 보내는 방법
  4. +
+

Position 기준으로 사다리 게임을 진행하는 방법

+

사실상 index를 Ladder에게 넘겨주고, 해당 index에 대한 결과를 받는 방법과 유사했다.
구현하고 나니 다른 클래스들이 Position에 대한 의존도가 너무 높은 것 같았다.
-또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

public LadderGameResult play() {
final Map<Player, Item> result = new LinkedHashMap<>();
// 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
for (Position position : Position.range(players.count())) {
final Position resultPosition = ladder.play(position);
result.put(players.get(position), items.get(resultPosition));
}
return new LadderGameResult(result);
}

Player에게 Ladder를 전달하여 게임을 진행하는 방법

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
-이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

public LadderGameResult play() {
// 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
final Map<Player, Position> playResult = players.play(ladder);

final Map<Player, Item> result = new LinkedHashMap<>();
for (Player player : playResult.keySet()) {
result.put(player, toItem(playResult.get(player)));
}
return new LadderGameResult(result);
}

부족했던 부분

유비쿼터스 언어에 시간을 들이기
+또한 Players가 별다른 책임을 가지고 있지 않다고 느꼈다.

+ +
public LadderGameResult play() {
+    final Map<Player, Item> result = new LinkedHashMap<>();
+    // 사용자 수만큼 Position을 가져와서 사다리 게임을 진행한다.
+    for (Position position : Position.range(players.count())) {
+        final Position resultPosition = ladder.play(position);
+        result.put(players.get(position), items.get(resultPosition));
+    }
+    return new LadderGameResult(result);
+}
+
+

Player에게 Ladder를 전달하여 게임을 진행하는 방법

+

Position에 대한 값을 가지고 있는 Player에게 Ladder를 넘겨서, Player가 Ladder에게 메시지를 보내도록 구현하였다.
+이 방법이 사다리 게임을 위해서 객체들이 긴밀하게 협력하고, 조금 더 책임의 분배가 잘 되어있다고 생각이 되었다.

+ +
public LadderGameResult play() {
+    // 참가자들에게 사다리를 전달해서 사다리에게 메시지를 보내도록 한다.
+    final Map<Player, Position> playResult = players.play(ladder);
+
+    final Map<Player, Item> result = new LinkedHashMap<>();
+    for (Player player : playResult.keySet()) {
+        result.put(player, toItem(playResult.get(player)));
+    }
+    return new LadderGameResult(result);
+}
+
+

부족했던 부분

+

유비쿼터스 언어에 시간을 들이기
유비쿼터스 언어를 정하는데 시간을 조금 더 들여야겠다고 생각했다.
사다리 타기의 실행 결과를 Item으로 짓다니.. 뭔가 만족스럽지 않다.
-이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

페어와 조금 더 친해지기
+이전 미션과 마찬가지로, 명명하는 부분에서 부족함을 많이 느꼈다.

+

페어와 조금 더 친해지기
첫날은 페어와 친해지는 시간을 조금 더 가져야겠다고 생각했다.
-우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

README를 조금 더 꼼꼼하게
-이상하게 코딩에 집중하면 README를 업데이트하면서 같이 커밋 하는 걸 항상 까먹는다.
-다음 미션에는 조금 더 신경 써야겠다.

좋은 질문을 생각하기
+우가랑 회고할 때 내가 시작하자마자 컨벤션 정하자고 해서 많이 당황스러웠다고 한다. 우가 미안.. 🥲

+

README를 조금 더 꼼꼼하게
+이상하게 코딩에 집중하면 README를 업데이트하면서 같이 커밋 하는 걸 항상 까먹는다.
+다음 미션에는 조금 더 신경 써야겠다.

+

좋은 질문을 생각하기
첫 PR때 리뷰어에게 질문을 남기지 못했다.
-리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

PR 후에도 꼼꼼하게 확인하기
+리뷰어와의 시간이 소중한 시간이라는 것을 까먹지 말고, 나의 성장에 도움이 될 수 있는 질문을 생각해야겠다.

+

PR 후에도 꼼꼼하게 확인하기
분명 알고 있는 부분이지만, 놓친 부분이 많은 것 같았다.
PR 하기 전에도 계속 확인을 했지만, 아무래도 IntelliJ에서 보니 코드에 익숙해져서 그런지 변경해야 할 부분이 잘 안보였다.
-github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

적극적으로 나의 의견을 말하기
+github pr에서는 전체 변경사항을 확인할 수 있으니 PR 후에도 꼭 확인해야겠다.

+

적극적으로 나의 의견을 말하기
의견을 적극적으로 내는 부분에 대해서 페어의 의견이 괜찮다고 생각하면 수용 후 개선을 하는 방향으로 진행을 했었는데, 조금 더 개선할 수 있는 방향이 있다면 나도 적극적으로 의견을 말해야겠다고 생각이 든다.
-나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

새로 학습한 부분

객체의 생성 책임
+나도 설득하는 힘을 기르고, 페어도 좋은 방향을 알 수 있고, 결과물도 좋은 방향으로 나오지 않을까? (고민 들어주신 리뷰어 터틀🐢 감사합니다.)

+

새로 학습한 부분

+

객체의 생성 책임
Players가 Position을 생성하고 Player의 생성자에 넣어주었다. 하지만 이 부분에 대해서 생성 책임에 관련된 코멘트가 달렸다. -시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

  • B가 A 객체를 포함 또는 참조한다.
  • B가 A 객체를 기록한다.
  • B가 A를 긴밀하게 사용한다.
  • B가 A의 초깃값을 가지고 있다.

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

패키지 분리 기준
+시간을 가지고 생각해 보니 Position을 가지고 있는 건 Player기 때문에 생성 책임을 Player가 담당하는 것이 좋다고 생각되었다.

+

생성 책임에 관한 패턴으로 GRASP의 Creator 패턴이 있는데 다음의 요소를 최대한 만족하는 클래스에 생성 책임을 할당하는 것이 좋다.

+
    +
  • B가 A 객체를 포함 또는 참조한다.
  • +
  • B가 A 객체를 기록한다.
  • +
  • B가 A를 긴밀하게 사용한다.
  • +
  • B가 A의 초깃값을 가지고 있다.
  • +
+

실제로 객체의 생성 책임에 관해서 깊이 생각하면서 코딩을 하지 않았는데, 이번 미션을 통해 시야가 넓어진 것 같다.

+

패키지 분리 기준
패키지 분리에 대한 나만의 기준이 아직 명확하지 않아 질문이 들어와도 명확하게 답변을 하지 못했다.
마지막 제출 전에 도메인 패키지 내부를 분리해 봤는데, 기준이 명확하지 않았기 때문에 좋지 않은 선택이었던 것 같다. -현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
-Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(0~19)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
-이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0~19의 값이 보장되어 있다고 생각할 것이기 때문이다.
-따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

페어에게 배울 부분

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
+현재 진행하는 미션의 애플리케이션 크기가 그렇게 크지 않으니, domain 패키지에서 세부 패키지로 분리하지 않아도 될 것 같다.

+

사용하는 쪽에서 생각하기 & 예측가능한 코드 작성하기
+Position에서 다음 위치나 이전 위치를 반환하는 메서드를 허용 범위(019)가 벗어난다면, 의미 없는 값이 들어간 Position을 반환하도록 했다.
+이건 Position을 사용하는 입장을 고려하지 못한 코딩이었는데, 사용하는 입장에서는 0
19의 값이 보장되어 있다고 생각할 것이기 때문이다.
+따라서 hasNext, hasPrevious라는 이전 값, 이후 값이 범위 내에 있는지 확인하는 메서드를 추가하고, 기존의 값을 가져오는 메서드는 범위가 벗어나면 예외를 던지는 방향으로 해결하였다.

+

페어에게 배울 부분

+

밝은 기운을 가지고 있고 다른 사람들과 친화력이 좋은 것 같았다.
이번에 페어 할 때 컨디션 관리를 제대로 못해서 많이 미안했다. 다음에는 최상의 컨디션으로 페어를 준비해 봐야겠다.
-그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
+그리고 우가랑 페어를 하고 나서, 나도 다른 사람들과 더 잘 지내봐야겠다는 생각이 들어 조금 더 용기를 내 잡담 중이다!

+

의견을 적극적으로 내줘서 페어프로그래밍 진행이 잘 되었다.
또한 페어 진행이 느린 것 같다고 말해줘서 안정적으로 시간 안에 미션을 완료할 수 있었다.
-페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
+페어프로그래밍 진행 속도에 대해 조금 더 생각을 해봐야겠다!

+

항상 지나갈 때마다 웃어주는데, 나도 자주 웃어야겠다고 생각했다.
웃는 것만으로도 사람이 밝아 보여서 너무 좋은 것 같다!

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/16.html b/tags/woowahan-techcourse/page/16.html index 3d5ccebdb..ef5704944 100644 --- a/tags/woowahan-techcourse/page/16.html +++ b/tags/woowahan-techcourse/page/16.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,40 +12,90 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

자동차 경주

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
-우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
-시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
-mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
-리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

부족했던 부분

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
-객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

1단계: https://github.com/woowacourse/java-racingcar/pull/510
+2단계: https://github.com/woowacourse/java-racingcar/pull/538

+

자동차 경주

+

자동차 경주 미션에서는 다즐과 페어가 매칭되었다.
+우테코 들어와서 첫 페어프로그래밍이라 많이 떨렸지만, 다즐이 대화를 잘 이끌어줘 너무 즐거웠다.

+

첫날은 간단히 컨벤션과 환경을 설정하는 시간을 가졌고 다음 날부터 자동차 경주를 시작했다.
+시작은 간단하게 요구사항을 정리하고, 어떻게 코드를 작성할지 같이 고민했다.

+

시작하기 전 아래와 같이 mermaid를 이용하여 의존성 방향에 대해서 간단한 다이어그램을 만들고 시작했다.
+mermaid는 코드로 다이어그램을 생성 해주는 도구로 다음과 같은 장점이 있다고 생각한다.

+
    +
  • 코드 기반이라 빠른 시간 안에 생각한 것을 시각화할 수 있다.
  • +
  • github에서 mermaid를 지원하기 때문에 리뷰어에게 코드를 이해할 수 있는 부가적인 정보를 제공할 수 있다.
  • +
+ +

미션을 진행하는 데 큰 어려움이 있지는 않았고, 페어를 마치기 전 서로 고민되는 부분을 정리했을 때 좋았다.

+

페어하면서 잘했다고 생각했던 점은 서로의 생각과 리뷰 받은 것을 공유한 것이다.
+리팩터링을 어떻게 했는지? 이런 리뷰에 대해 어떻게 생각하는지 깊게 고민하는 시간을 가질 수 있었다.

+

부족했던 부분

+

리팩터링이 끝난 후 메서드명, 테스트시 출력하는 메시지에 대한 코멘트가 많이 달렸다.
+객체가 어떤 책임과 역할을 가지는지 생각하는 시간을 가지고 명확한 메서드명을 작성해야겠다고 생각했다.

+

평소에 프로그래밍 이야기가 아닌 다른 주제로 이야기하면 잘 들으려고 하는 편이지만
내가 좋아하는 주제, 관심가는 주제인 프로그래밍에 대한 이야기를 할 땐 말이 많아진다.
-다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

새로 학습한 부분

Assertions extracting

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
-이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

@Test
void extracting() {
final Cars cars = new Cars(List.of("car1", "car2"));

assertThat(cars.getCars())
.extracting(Car::getName)
.containsExactly("car1", "car2");
}

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

제어할 수 없는 부분에 대한 테스트

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
-이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

단순 위임을 하는 메서드에 대한 테스트

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
+다음 미션부터는 더 많은 시간을 페어의 의견과 이야기를 듣는 곳에 사용해야겠다.

+

새로 학습한 부분

+

Assertions extracting

+

결과 내부에 있는 값을 확인하고 싶을 때 extracting 키워드를 이용해서 내부의 값을 검증할 수 있다.
+이전에는 필요에 따라 stream을 이용하여 검증할 값을 생성했지만, 해당 방법을 이용해서 절차를 줄일 수 있었다.

+
@Test
+void extracting() {
+    final Cars cars = new Cars(List.of("car1", "car2"));
+
+    assertThat(cars.getCars())
+            .extracting(Car::getName)
+            .containsExactly("car1", "car2");
+}
+
+
+

아래는 리뷰어님과 대화를 나누면서 얻은 답변 + 나의 의견이다.

+

제어할 수 없는 부분에 대한 테스트

+

테스트 대상이 검증된 것이라면 작성하지 않거나, 제어할 수 있는 부분에 대한 테스트를 더욱 꼼꼼하게 작성한다.
+이건 개인적인 생각이지만 내가 안정감이 들 수 있을 정도로 출력 범위 내의 결과를 반환하는지 정도 테스트할 수 있지 않을까?

+

단순 위임을 하는 메서드에 대한 테스트

+

위임이라는 것은 역할과 책임을 넘겨준다는 것이다.
호출 횟수를 검증하는 것보다 결과에 대한 테스트하는 것이 좋다.
단순히 위임만 하는 테스트의 경우 결과를 검증한다면 테스트가 중복되지 않을까 생각했었다.
따라서 중복된 테스트를 줄이기 위해 내부의 메서드를 호출하는지 검증하는 방법도 있다는 것을 알게 되었지만
-안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

테스트를 위한 getter 사용

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
-필요의 경우 생성해서 사용할 수 있지만, 기존에 있는 메서드들을 활용해보는 것이 더 좋은 방법이다.
-이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

페어에게 배울 부분

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
+안정적으로 결과를 테스트 하는 것이 더 좋은 방법인 것 같다.

+

테스트를 위한 getter 사용

+

테스트 용도로 도메인에 새로운 메서드가 생성되는 것은 좋지 못하다.
+필요의 경우 생성해서 사용할 수 있지만, 기존에 있는 메서드들을 활용해보는 것이 더 좋은 방법이다.
+이 부분에 대해서 매우 동의하고, 앞으로도 최대한 테스트를 위한 코드를 도메인에 작성하지 않을 것 같다.

+

페어에게 배울 부분

+

질문이나 생각할 점이 있을 때 매우 깊게 고민하는 것 같았다.
생각을 정리한 후 자신의 의견을 명료하게 전달해주었다.
그렇기 때문에 지식을 효율적으로 습득한다.
난 생각을 잘 정리하지 않은 채로 내버려 둔 얕은 지식이 많은 것 같다. (이런 것도 아는 것이라고 할 수 있을까?)
-앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

개발에 열정을 가진 게 느껴진다.
+앞으로 조금 더 머릿속에서 정리하고, 문제에 대해 깊게 고민하는 시간을 늘려야겠다.

+

개발에 열정을 가진 게 느껴진다.
나도 개발을 좋아하지만, 최근에는 의지가 약해졌었다.
-열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
+열정이 가득한 사람을 만나니 나도 열정적인 사람이 되는 것 같다.

+

칭찬을 많이 해준다. 단순히 많이 해주는 것이 아니라, 진심을 담긴 칭찬을 해줬다.
칭찬은 고래도 춤추게 하던가?
-그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
+그래서 즐거운 마음으로 페어 프로그래밍을 했었던 것 같다.

+

어떤 이유 때문인지 모르겠지만 같이 페어하는데 편한 마음이 들었다.
이건 바로 배울 수 없지만.
나도 같이 일할 때 편한 사람, 같이 일하고 싶은 사람이 되기 위해 깊이 고민해봐야겠다.

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/2.html b/tags/woowahan-techcourse/page/2.html index 6a1d72345..edac3798c 100644 --- a/tags/woowahan-techcourse/page/2.html +++ b/tags/woowahan-techcourse/page/2.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,24 +12,94 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

Jdbc 구현

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
-미션 목표는 다음과 같다.

  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • 데이터베이스에 대한 이해도를 높인다.

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

JdbcTemplate

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

1단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/267
+2단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/358
+3단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/448
+4단계: https://github.com/woowacourse/jwp-dashboard-jdbc/pull/515

+

Jdbc 구현

+

이번 미션은 Jdbc 라이브러리를 구현하고, Transaction 경계 설정과 동기화하는 부분을 구현해 보는 미션이었다.
+미션 목표는 다음과 같다.

+
    +
  • JDBC 라이브러리를 구현하면서 중복을 제거하는 연습을 한다.
  • +
  • 데이터베이스에 대한 이해도를 높인다.
  • +
+

최대한 Java가 제공하는 기능을 사용하여 리팩터링 하는 방향으로 코드를 작성했다.

+

JdbcTemplate

+

JdbcTemplate은 Connection을 이용하여 PreparedStatement를 생성하는 부분, 그리고 PreparedStatement가 어떻게 동작하는지에 대한 부분을 분리했다.
템플릿 콜백 패턴을 적절하게 적용하여 중복을 비교적 간단하게 제거할 수 있었다.
-예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

public class JdbcTemplate {

private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);

private final DataSource dataSource;
private final StatementCreator statementCreator;
private final StatementExecutor statementExecutor;

public JdbcTemplate(final DataSource dataSource) {
this(dataSource, new StatementCreator(), new StatementExecutor());
}

JdbcTemplate(
final DataSource dataSource,
final StatementCreator statementCreator,
final StatementExecutor statementExecutor
) {
this.dataSource = dataSource;
this.statementCreator = statementCreator;
this.statementExecutor = statementExecutor;
}

private <T> T query(
final String sql,
final PreparedStatementCallback<T> preparedStatementCallback,
final Object... parameters
) {
final Connection connection = DataSourceUtils.getConnection(dataSource);
try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
return preparedStatementCallback.execute(preparedStatement);
} catch (final SQLException e) {
log.error(e.getMessage(), e);
throw new DataAccessException(e);
} finally {
DataSourceUtils.releaseConnection(connection, dataSource);
}
}

public void update(final String sql, final Object... parameters) {
query(sql, PreparedStatement::executeUpdate, parameters);
}

public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
if (results.size() > 1) {
throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
}
return results.stream().findAny();
}

public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
}
}

트랜잭션 적용

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
+예전에도 미션을 진행하면서 JdbcTemplate을 구현한 적이 있었는데, 이번에는 자원 할당과 해제 부분에 대한 중복도 제거했다.

+
public class JdbcTemplate {
+
+    private static final Logger log = LoggerFactory.getLogger(JdbcTemplate.class);
+
+    private final DataSource dataSource;
+    private final StatementCreator statementCreator;
+    private final StatementExecutor statementExecutor;
+
+    public JdbcTemplate(final DataSource dataSource) {
+        this(dataSource, new StatementCreator(), new StatementExecutor());
+    }
+
+    JdbcTemplate(
+            final DataSource dataSource,
+            final StatementCreator statementCreator,
+            final StatementExecutor statementExecutor
+    ) {
+        this.dataSource = dataSource;
+        this.statementCreator = statementCreator;
+        this.statementExecutor = statementExecutor;
+    }
+
+    private <T> T query(
+            final String sql,
+            final PreparedStatementCallback<T> preparedStatementCallback,
+            final Object... parameters
+    ) {
+        final Connection connection = DataSourceUtils.getConnection(dataSource);
+        try (final PreparedStatement preparedStatement = statementCreator.create(connection, sql, parameters)) {
+            return preparedStatementCallback.execute(preparedStatement);
+        } catch (final SQLException e) {
+            log.error(e.getMessage(), e);
+            throw new DataAccessException(e);
+        } finally {
+            DataSourceUtils.releaseConnection(connection, dataSource);
+        }
+    }
+
+    public void update(final String sql, final Object... parameters) {
+        query(sql, PreparedStatement::executeUpdate, parameters);
+    }
+
+    public <T> Optional<T> queryForObject(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        final List<T> results = query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+        if (results.size() > 1) {
+            throw new DataAccessException("2개 이상의 결과를 반환할 수 없습니다.");
+        }
+        return results.stream().findAny();
+    }
+
+    public <T> List<T> queryForList(final String sql, final RowMapper<T> rowMapper, final Object... parameters) {
+        return query(sql, statement -> statementExecutor.execute(statement, rowMapper), parameters);
+    }
+}
+
+

트랜잭션 적용

+

3, 4단계는 기존의 코드에 트랜잭션을 시작하고 끝나는 부분인 트랜잭션 경계를 설정하고 ThreadLocal을 이용하여 트랜잭션 동기화(Transaction synchronization)를 적용하는 미션이었다.
트랜잭션 동기화란 트랜잭션을 시작하기 위한 Connection 객체를 ThreadLocal과 같은 공간에 따로 저장 후, 필요할 때 저장된 Connection을 가져다 사용하는 방식이다.
-아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

마무리

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
+아래와 같은 구조로 미션을 진행했는데, ThreadLocal에 Connection 객체가 아닌, Connection 객체와 Transaction이 진행 중인지 확인할 수 있는 flag를 가지고 있는 클래스를 저장해서 사용하도록 했다.

+ +

마무리

+

Jdbc 미션을 진행하면서 AOP나 Transactional에 대한 학습 테스트도 진행하고, 약간 알찬 미션이었던 것 같다.
꼼꼼히 코드를 봐준 리뷰어 호이 그리고 연휴 동안 계속 티키타카 하면서 재밌게 리뷰한 민트에게 감사하다.
회고 이만 끝내고 리팩터링 미션 하러가야겠다. 😊

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/3.html b/tags/woowahan-techcourse/page/3.html index 6602ca748..94f50385b 100644 --- a/tags/woowahan-techcourse/page/3.html +++ b/tags/woowahan-techcourse/page/3.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,25 +12,96 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

MVC 구현

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
-미션의 목표는 다음과 같았다.

  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • 점진적인 리팩토링을 경험한다.

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

애너테이션 기반 프레임워크 만들기

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 6분

1단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/404
+2단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/465
+3단계: https://github.com/woowacourse/jwp-dashboard-mvc/pull/580

+

MVC 구현

+

Reflection을 이용하여 Spring MVC와 유사한 기능을 구현하는 미션이었다.
+미션의 목표는 다음과 같았다.

+
    +
  • MVC 프레임워크를 구현하면서 내부 동작 원리를 학습한다.
  • +
  • 점진적인 리팩토링을 경험한다.
  • +
+

미션의 목표와 더불어 각 클래스들이 역할과 책임을 적절히 가지도록 하고, 패키지의 의존 방향을 고민하면서 미션을 진행하는 것에 중점을 두었다.

+

애너테이션 기반 프레임워크 만들기

+

기존 코드에 ManualHandlerMapping이라는 서블릿을 직접 등록해서 사용하는 HandlerMapping 클래스가 있었고, 1단계에서는 애너테이션 기반의 AnnotationHandlerMapping을 구현해야 했기 때문에 @Controller, @RequestMapping을 Reflection을 이용하여 스캔하고, 핸들러 매핑을 등록하는 부분까지 진행해야 했다.
테오가 @GetMapping이나 @PostMapping 부분도 진행하면 재밌을 것 같다고 해서 같이 진행해 보았다.
-추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  3. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

AnnotationHandlerMapping
public void initialize() {
if (!initialized.compareAndSet(false, true)) {
return;
}

final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
for (final Method method : methods) {
final ControllerInstance controller = controllers.get(method.getDeclaringClass());
final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
}

log.info("Initialized AnnotationHandlerMapping!");
handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
}

Legacy MVC와 @MVC 통합

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
+추가로 미션 요구사항은 아니었지만 클래스 레벨에 적용된 @RequestMapping도 동작하도록 구현해보았다.

+ +

다음과 같은 Flow로 Handler(실제 요청을 처리하는 메서드) 등록을 진행한다.

+
    +
  1. @Controller가 적용된 클래스의 정보를 스캔하여 반환한다.
  2. +
  3. @Controller가 적용된 클래스의 @RequestMapping이 적용된 메서드들의 정보를 반환한다.
  4. +
  5. 각 메서드들을 순회하며 HandlerKey(uri + httpMethod 정보)와 HandlerExecution(인스턴스 + 실행하려는 메서드)을 생성하여 Map<HandlerKey, HandlerExecution>에 추가한다.
  6. +
+

AnnotationHandlerMapping의 initialize 메서드에서 Handler를 등록한다. 코드는 다음과 같다.

+
public void initialize() {
+    if (!initialized.compareAndSet(false, true)) {
+        return;
+    }
+
+    final Map<Class<?>, ControllerInstance> controllers = annotationScanner.scanControllers();
+    final Set<Method> methods = annotationScanner.scanHttpMappingMethods(controllers.keySet());
+    for (final Method method : methods) {
+        final ControllerInstance controller = controllers.get(method.getDeclaringClass());
+        final HandlerExecution handlerExecution = new HandlerExecution(controller.getInstance(), method);
+        final List<HandlerKey> handlerKeys = handlerKeyGenerator.generate(controller.getUriPrefix(), method);
+        handlerKeys.forEach(handlerKey -> handlerExecutions.put(handlerKey, handlerExecution));
+    }
+
+    log.info("Initialized AnnotationHandlerMapping!");
+    handlerExecutions.keySet().forEach(key -> log.info("key: {}, Handler: {}", key, handlerExecutions.get(key)));
+}
+
+

Legacy MVC와 @MVC 통합

+

2단계는 Legacy MVC와 AnnotationHandlerMapping을 통합하는 부분이었다.
기존의 MVC와 애너테이션이 적용된 MVC 두 개를 같이 사용할 수 있어야 헀다.
-대략적인 흐름은 다음과 같다.

  1. DispatcherServlet.service(request, response) 호출
  2. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  3. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  4. HandlerAdapter의.handle 메서드 실행
  5. View의 render 호출

웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
-간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

내용이 길어져서 다음 문서에 정리했다.

추상적인 개념 학습 방법

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory

정리

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
+대략적인 흐름은 다음과 같다.

+
    +
  1. DispatcherServlet.service(request, response) 호출
  2. +
  3. HandlerMappings를 통해 입력받은 request에 해당하는 Handler 조회
  4. +
  5. HandlerAdapters를 통해 Handler를 실행시킬 수 있는 HandlerAdapter 조회
  6. +
  7. HandlerAdapter의.handle 메서드 실행
  8. +
  9. View의 render 호출
  10. +
+ +

웹 애플리케이션 발전 과정

+

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.

+ +

내용이 길어져서 다음 문서에 정리했다.

+

추상적인 개념 학습 방법

+

직관적이지 않은 추상적인 개념을 학습할 때는 개념의 구현을 참고하면 학습에 도움이 된다고 한다.

+
개념구현
OOPJava
WASTomcat, Jetty
IoCSpring BeanFactory, Servlet Container, Framework
DISpring BeanFactory
+

정리

+

지금까지 스프링의 DispatcherServlet의 동작을 이론적으로만 알고 있었는데, 실제로 구현해 보니 조금 더 이해가 잘 가는 것 같다.
이번 미션에서 나의 리뷰어는 루카, 리뷰이는 헤나였다.
매 단계마다 꼼꼼하게 리뷰해 준 루카에게 너무 감사하고, 헤나에게 이상한 리뷰를 많이 남긴 것 같은데 꼼꼼히 반영해줘서 감사하다.
오랫동안 기다려왔던 레벨 4 미션이 하나씩 마무리 될 때 마다 아쉬움이 남는다.

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/4.html b/tags/woowahan-techcourse/page/4.html index d6a249fd0..78413c386 100644 --- a/tags/woowahan-techcourse/page/4.html +++ b/tags/woowahan-techcourse/page/4.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,43 +12,210 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 13분

톰캣 구현

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
-그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
-톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

다이어그램

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 13분

1, 2단계: https://github.com/woowacourse/jwp-dashboard-http/pull/302
+3, 4단계: https://github.com/woowacourse/jwp-dashboard-http/pull/431

+

톰캣 구현

+

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
+그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

+

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
+톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

+

다이어그램

+

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
사실 내부 구조를 깊게 공부할 시간을 가지지 못해서 각 구성 요소가 왜 해당 위치에 있는지 완벽하게 설명하지는 못하지만 미션을 진행하면서 이건 여기에 있으면 좋을 것 같은데? 라는 생각이 들면 적절한 패키지에 위치시키는 방향으로 진행을 했다.
-또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

코드 리뷰

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
-나의 리뷰어는 디노, 리뷰이는 필립이었다.

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
+또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

+ +

코드 리뷰

+

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
+나의 리뷰어는 디노, 리뷰이는 필립이었다.

+

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
한 가지 아쉬운 점은 필립에게 작성한 나의 코멘트들이 미션을 진행하면서 경험 기반으로 작성한 내용이 많아 근거가 조금 부족했고, 정리되지 않은 부분이 많았던 것 같다.
-다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

SessionConfig

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
+다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

+

SessionConfig

+

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
세션 쿠키의 이름을 가져오는 Util 클래스의 코드를 수정했는데 기본 값은 JSESSIONID 지만 설정에 따라서 세션 쿠키명을 다르게 사용할 수 있기 때문에 해당 로직이 있는 것으로 생각했다.
-기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
+기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

+

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
메인테이너인 Mark Thomas 형이 해당 로직의 경우 컴파일러가 해당 부분을 최적화 할 수 있을 거라고 기대한다고 했고, 가독성을 개선시켜보라고 조언해주셨다.
-컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
-결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

public static String getSessionCookieName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_COOKIE_NAME;
}

return result;
}

public static String getSessionUriParamName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_PARAMETER_NAME;
}

return result;
}

private static String getConfiguredSessionCookieName(Context context) {

// Priority is:
// 1. Cookie name defined in context
// 2. Cookie name configured for app
// 3. Default defined by spec
if (context != null) {
String cookieName = context.getSessionCookieName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}

SessionCookieConfig scc =
context.getServletContext().getSessionCookieConfig();
cookieName = scc.getName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}
}

return null;
}

HTTP 수업

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
+컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

+

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
+결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

+ + +
public static String getSessionCookieName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_COOKIE_NAME;
+    }
+
+    return result;
+}
+
+public static String getSessionUriParamName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_PARAMETER_NAME;
+    }
+
+    return result;
+}
+
+private static String getConfiguredSessionCookieName(Context context) {
+
+    // Priority is:
+    // 1. Cookie name defined in context
+    // 2. Cookie name configured for app
+    // 3. Default defined by spec
+    if (context != null) {
+        String cookieName = context.getSessionCookieName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+
+        SessionCookieConfig scc =
+            context.getServletContext().getSessionCookieConfig();
+        cookieName = scc.getName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+    }
+
+    return null;
+}
+
+

HTTP 수업

+

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
항상 성능 개선을 위해 애플리케이션 단에서 최적화해보려고 노력을 했지만, 더 적은 시간을 투자해서 효율적으로 성능을 개선할 수 있는 방법에 대해 알 수 있었던 수업이었다.
-HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

server:
compression:
enabled: true

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
-궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
-내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

ETag

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
+HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

+

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

+
server:
+  compression:
+    enabled: true
+
+

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
+궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
+내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

+
+

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

+
+

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

+

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

+

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐시가 더 효율적이게 된다.
-MDN

Thread 수업

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
-현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
-학습한 내용은 다음과 같다.

threads.max: Tomcat의 최대 스레드 개수
+MDN

+

Thread 수업

+

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
+현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

+

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
+학습한 내용은 다음과 같다.

+

threads.max: Tomcat의 최대 스레드 개수
max-connections: Tomcat이 유지할 수 있는 최대 커넥션 개수
-accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

마치며

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
+accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

+ +

마치며

+

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
우선순위를 잘 정하고 학습을 진행해야겠다.
-현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

참고 자료

RFC 2616
-ETag, mdn
-Apache Tomcat 8 Configuration Reference
-Apache Tomcat Tuning, Terry Cho
-maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

- - +현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

+

참고 자료

+

RFC 2616
+ETag, mdn
+Apache Tomcat 8 Configuration Reference
+Apache Tomcat Tuning, Terry Cho
+maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

\ No newline at end of file diff --git a/tags/woowahan-techcourse/page/5.html b/tags/woowahan-techcourse/page/5.html index 749355f19..2e8be6d4f 100644 --- a/tags/woowahan-techcourse/page/5.html +++ b/tags/woowahan-techcourse/page/5.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,28 +12,43 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

회고

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

회고

+

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
레벨 3에는 기술적인 부분에서도, 기술 외적인 부분에서도 부족함이 많이 보였던 것 같다.
부족한 부분을 알았기에, 앞으로 더욱 성장할 수 있을 것 같다.
-내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

아쉬운 점

문서화

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
+내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

+

아쉬운 점

+

문서화

+

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
프로젝트를 진행하면서 내가 한 부분을 조금 더 꼼꼼하게, 이해하기 쉽게 문서화를 했더라면 팀원들에게 더욱 도움이 되었을 텐데 이 부분에 시간을 조금 더 투자하지 못했던 부분에서 아쉬움이 많이 들었다.
-방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

내가 못하는 부분이라면 시간을 들이자

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
+방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

+

내가 못하는 부분이라면 시간을 들이자

+

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
말을 하기 전에 정리해서 의견을 내는 것, 발표 준비, 감정 조절 등등 -못하는 부분을 인지하고, 개선하자.

컴포트 존 벗어나기

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
+못하는 부분을 인지하고, 개선하자.

+

컴포트 존 벗어나기

+

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
매번 근거를 가지고 기술을 도입하고, 코드를 작성하려고 노력했다.
-하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

좋았던 점

좋았던 점도 문서화

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
-백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

내가 디자인한 트립드로우 로고

트립드로우 로고를 만들었다.
+하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

+

좋았던 점

+

좋았던 점도 문서화

+

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
+백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

+

내가 디자인한 트립드로우 로고

+ +

트립드로우 로고를 만들었다.
팀원들이 대표 색상(파란색)을 정해줬고, 주말 동안 신나게 로고 디자인을 했던 것 같다.
-아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

기술 선택의 이유

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
-100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

마치며

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
+아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

+

기술 선택의 이유

+

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
+100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

+

마치며

+

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
안드로이드 브레멘 음악대(멧돼지, 수달, 핑구), 그리고 백엔드 팀원들(체인저, 후추, 리오) 너무 고생이 많았다.

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/6.html b/tags/woowahan-techcourse/page/6.html index cb24101e3..ce4c40266 100644 --- a/tags/woowahan-techcourse/page/6.html +++ b/tags/woowahan-techcourse/page/6.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,24 +12,32 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 3분

23년의 6월이 오고, 레벨 2가 끝났다.
-빠르게 지나가서 조금 아쉽다.

학습

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 3분

23년의 6월이 오고, 레벨 2가 끝났다.
+빠르게 지나가서 조금 아쉽다.

+

학습

+

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
항상 아쉬운 곳은 있기 마련이지만, 잘 학습한 것 같다.
-미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
-방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
-필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

수면

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
-앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

협업

레벨 2 마지막에 협업 미션이 있었다.
+미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

+

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
+방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

+

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
+필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

+

수면

+

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
+앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

+

협업

+

레벨 2 마지막에 협업 미션이 있었다.
지금까지는 백엔드 크루들과 페어 프로그래밍을 하면서 협업을 경험했다.
-이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
-팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

레벨 2를 마무리하며

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. +이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

+

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
+팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

+

레벨 2를 마무리하며

+

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. 읽고 싶은 책도 읽고, 부족한 부분 채우면서 쉬어야겠다.

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/7.html b/tags/woowahan-techcourse/page/7.html index 791c677b6..68ca46ad8 100644 --- a/tags/woowahan-techcourse/page/7.html +++ b/tags/woowahan-techcourse/page/7.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,26 +12,36 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

레벨 인터뷰

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 4분

레벨 인터뷰

+

레벨 1 때는 준비해둔 내용으로 인터뷰를 진행해서 그렇게 특별한 부분이 없었다.
따라서 레벨 1 레벨 인터뷰 회고는 레벨 1 회고를 작성할 때 끼워넣었다.
이번에는 범위도 제한되어 있어 어떻게 준비해야 할지 당황했고, 답변에도 부족한 부분이 많았었다.
-기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

API 문서 도구 선택

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
+기억이 사라지기 전에 큰 문제 없이 답변한 내용을 제외하고, 기억 남는 것 위주로 작성해 보려고 한다.

+

API 문서 도구 선택

+

큰 문제 없이 답변을 했는데 앞으로도 팀 프로젝트를 하면서 도움 될 것 같은 내용이 있어서 남겨두려고 한다.
백엔드 팀원이 함께 의사결정을 했고, 미션 기간이 짧은 만큼 팀 차원에서 비교적 학습하기 쉬운 Swagger를 선택했다.
-추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
-앞으로도 학습 비용은 주요하게 고려해야 할 사항

PUT과 PATCH & 토큰과 세션

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
-토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
+추가로 들어가는 시간 대비 하이 리턴이라고 생각했다고 답변했다.

+

팀 차원의 학습 비용을 언급해서, 다음과 같은 좋은 피드백을 받았다.

+
+

특히 팀으로 의사결정하는 과정을 공유해 준 점이 좋았고 기술적 의사결정 과정에서 팀의 학습비용을 고려한 점이 좋았음.
+앞으로도 학습 비용은 주요하게 고려해야 할 사항

+
+

PUT과 PATCH & 토큰과 세션

+

PUT과 PATCH 차이를 설명하는 부분에서는 PATCH를 사용할 때 페이로드가 적어진다는 내용을 빼먹고 답변을 했다.
+토큰과 세션의 경우 기술을 잘 모르는 사람에게 설명해달라는 제약조건이 추가되었다.

+

해당 내용을 답변하면서 기술적인 깊이가 많이 부족했다는 생각이 든다.
실제로 레벨 2 때 이론적인 학습 시간이 매우 적었고, 집중력도 많이 부족했다.
-앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

그 외 개선할 점

인터뷰할 때 특유의 말버릇을 개선하기
+앞으로 어떻게 깊이를 채울지 고민을 할 수 있는 질문들이었다.

+

추가로 기술을 잘 모르는 사람에게 설명하는 가정을 두고 학습을 한다면 큰 도움이 될 거라는 피드백을 받았다.

+

그 외 개선할 점

+

인터뷰할 때 특유의 말버릇을 개선하기
생각할 시간을 가졌을 때 "다시 말씀드려도 될까요?"라고 말하고 답변을 이어나가기
기술적으로 깊이가 부족하다고 생각이 많이 들어서 조금 더 깊게 공부하고 정리하기
이전에 공부했던거 되돌아 보는 시간 가지기

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/8.html b/tags/woowahan-techcourse/page/8.html index 5b1ca7b8d..38ef8b2cf 100644 --- a/tags/woowahan-techcourse/page/8.html +++ b/tags/woowahan-techcourse/page/8.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,31 +12,77 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분
PR 링크

장바구니 주문 미션

배포 및 협업을 할 수 있는 미션이었다.
-마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

배포

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 5분

1단계: AWS 배포
+2단계: https://github.com/woowacourse/jwp-shopping-order/pull/7

+

장바구니 주문 미션

+

배포 및 협업을 할 수 있는 미션이었다.
+마코, 우가, 우코, 우스 그리고 나까지 합쳐서 5명이 한 팀이 되었다.

+

배포

+

이전 미션들과 달리 AWS를 이용해 배포를 해야 했다.
각자 하나의 EC2 인스턴스를 제공받을 수 있었고, 팀 별로 DB를 위한 추가 인스턴스를 제공받았다.
배포 스크립트를 작성하는 경험을 해볼 수 있었다.
-배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

echo "Start Deploy Script"
REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
PROJECT_NAME=jwp-shopping-order

echo "Change Directory"
cd $REPOSITORY_NAME

echo "Git Pull"
git pull origin step2

echo "Build"
./gradlew bootJar

echo "Copy, Start Server"
mv ./build/libs/$PROJECT_NAME.jar .

PID=$(pgrep -f $PROJECT_NAME)

if [ -n $PID ]; then
kill -9 $PID
sleep 5
fi

nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &

협업

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
+배포 스크립트에 시간을 많이 투자하진 않았고, 다음과 같이 간단하게 작성했다.

+
echo "Start Deploy Script"
+REPOSITORY_NAME=/home/ubuntu/jwp-shopping-order
+PROJECT_NAME=jwp-shopping-order
+
+echo "Change Directory"
+cd $REPOSITORY_NAME
+
+echo "Git Pull"
+git pull origin step2
+
+echo "Build"
+./gradlew bootJar
+
+echo "Copy, Start Server"
+mv ./build/libs/$PROJECT_NAME.jar .
+
+PID=$(pgrep -f $PROJECT_NAME)
+
+if [ -n $PID ]; then
+        kill -9 $PID
+	sleep 5
+fi
+
+nohup java -Dspring.profiles.active=prod -jar $PROJECT_NAME.jar 1>stdout.txt 2>err.txt &
+
+

협업

+

일단 우스랑 우코가 먼저 잠실로 와줘서 너무 감사했다.
백엔드가 아닌 다른 크루들과 해보는 첫 협업이라 약간 두근거렸다.
-예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

부족했던 부분

여러가지 방법에 대한 장단점을 고려해보기

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
+예상외로 대화가 잘 되어서, 빠르게 명세를 정할 수 있었다.

+

부족했던 부분

+

여러가지 방법에 대한 장단점을 고려해보기

+

백엔드와 테이블 명세나 쿠폰 구현에 대해서 이야기할 때 장단에 대해 많이 고려하지 못한 것 같다.
조금 더 시간을 많이 들여서 장단점을 고려했다면 더 좋은 결과물이 나오지 않았을까?
-앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

새로 배운 부분

expose headers

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
-기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
+앞으로 선택의 순간에서 조금 더 시간을 들여보는 것도 좋을 것 같다.

+

새로 배운 부분

+

expose headers

+

웹 페이지에서 Location 헤더를 받을 수 없는 문제가 있었다.
+기본적으로 허용 목록에 존재하는 응답헤더만 반환한다는 것을 모르고 있었다.
이를 expose headers 설정을 통해 해결할 수 있었다.
-nginx 설정에 다음과 같이 추가해 주었다.

add_header 'Access-Control-Expose-Headers' 'Location'

읽기 전용 트랜잭션

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
+nginx 설정에 다음과 같이 추가해 주었다.

+
add_header 'Access-Control-Expose-Headers' 'Location'
+
+

읽기 전용 트랜잭션

+

단순 조회 요청에 대한 성능을 향상시켜준다는 것이라고 간단히만 알고 있었다.
이번에 코멘트가 달려서 조금 더 자세히 공부해 보기로 했다.
-Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
-추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

DAO에 @Transactional 적용

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
+Transactional(readOnly = true)를 사용하는 경우 다음과 같이 동작한다.

+

setReadOnly(true) 설정이 된 Connection으로 연결을 시도를 한다. 이 설정을 하는 경우 DB마다 다르게 동작한다.

+
    +
  • h2의 Connection 구현체는 readOnly 설정을 무시하는 방향으로 구현되어 Transactional 적용되지 않는다.
  • +
  • MySQL 8.0(InnoDB 사용 시)의 경우 읽기 전용으로 알려진 트랜잭션의 경우 트랜잭션 ID를 설정하지 않기 때문에 조회 속도가 더 빨라진다.
  • +
+

ORM 프레임워크를 사용한다면 prepareTransactionalConnection를 호출한다고 한다.
+추가로 현업에서는 고가용성 내결함성 등을 위하여 클러스터를 구성하여 사용하는 경우가 많고, 이 경우 readOnly 설정이 되어있다면 읽기 전용 DB로 질의가 들어가서 부하 분산의 효과가 있다고 한다.

+

DAO에 @Transactional 적용

+

DAO에 트랜잭션을 보장해 보는 건 어떻겠냐고 리뷰가 달려서 고민을 많이 했다.
Service 계층에 이미 트랜잭션을 보장해 주고 있기에 필요 없지 않을까 생각했었다.
DAO를 다른 곳에서 사용하더라도 트랜잭션을 보장하기 위해(확장성 고려) @Transactional을 적용하는 것도 괜찮은 것 같다.

- - \ No newline at end of file diff --git a/tags/woowahan-techcourse/page/9.html b/tags/woowahan-techcourse/page/9.html index c070b0577..1badea588 100644 --- a/tags/woowahan-techcourse/page/9.html +++ b/tags/woowahan-techcourse/page/9.html @@ -2,8 +2,8 @@ - -"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG + +"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다. | GG @@ -12,35 +12,86 @@ - - - + + + -
-

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

지하철 미션

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
+

"Woowahan Techcourse" 태그로 연결된 16개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 8분

1단계: https://github.com/woowacourse/jwp-subway-path/pull/16
+2, 3단계: https://github.com/woowacourse/jwp-subway-path/pull/126

+

지하철 미션

+

점점 일정이 많아지는 느낌이 들면서 회고가 늦어진다.
지하철 미션은 밀리랑 페어를 진행했다.
간단한 CRUD만 있던 이전 미션들과 달리, 조금 복잡한 도메인 요구사항이 있었다.
이때 API, 테이블, 도메인 설계를 해야 했는데 어떤 것부터 해야 할지 고민을 많이 했다.
-API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

노선의 구간 추가 및 삭제

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. 변경된 요소만 데이터베이스에 반영하는 방법

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
-추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

부족했던 부분

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
+API와 테이블 구조를 우리가 정할 수 있는 상황이었고, 도메인 로직이 복잡했기 때문에 도메인을 먼저 구현했다.

+

노선의 구간 추가 및 삭제

+

노선을 저장하는 방법에 대해서 밀리와 이야기를 나눴다.

+
    +
  1. 구간을 데이터베이스에서 전부 제거하고 전부 추가하는 방법
  2. +
  3. 변경된 요소만 데이터베이스에 반영하는 방법
  4. +
+

페어 시간이 짧아서 더욱 간단한 1번을 선택했고, 시간 내 요구사항을 만족시키기 위해 더 간단하게 구현하는 방법을 선택하는 것도 좋은 트레이드오프였던 것 같다.
+추후 페어가 끝나고 리뷰어인 서브웨이가 일부분만 반영하는 것으로 개선해 보는 것도 좋을 것 같다고 코멘트를 남겨주셔서 추가 및 제거된 요소만 반영하도록 변경했다.

+

부족했던 부분

+

미션의 난이도가 올라간 만큼, 페어 할 땐 컨디션 관리도 잘하려고 노력하고 미션 할 때도 집중해서 잘 끝낸 것 같다.
우아한테크코스를 진행하면서 알아야 하는 게 많아지면서 가끔 조바심을 가질 때가 있는 것 같은데, 조바심을 경계할 필요가 있을 것 같다.
-부족한 부분은 인정하고, 앞으로 나아가야겠다.

새로 학습한 부분

컴포지트 패턴으로 요금 정책 추상화

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
+부족한 부분은 인정하고, 앞으로 나아가야겠다.

+

새로 학습한 부분

+

컴포지트 패턴으로 요금 정책 추상화

+

요금 정책은 기본요금 정책, 거리별 요금 정책, 연령별 할인 정책이 있었다.
요금을 더하는 부분과, 할인하는 부분이 있어서 이 둘을 분리할까 생각했지만, 이 정도 크기의 애플리케이션에서는 오히려 분리하지 않고 하나로 합치는 게 더 좋다고 생각했다.
-또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

도메인에 특정 기술의 의존성을 분리

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
+또한 분리하지 않는다면 정책의 순서가 중요한데, 연령별 할인 정책을 마지막에 두어야 했기 때문에 책임 연쇄 패턴도 고려를 했지만 조금 더 간결해 보이는 컴포지트 패턴을 선택했다.

+

도메인에 특정 기술의 의존성을 분리

+

처음에 도메인 패키지에 jgrapht 라이브러리를 의존하고 있는 클래스를 두어서 도메인 패키지가 jgrapht와 강결합이 되어버렸다.
따라서 도메인 패키지 내에는 경로 검색에 대한 인터페이스를 두고, 세부 구현은 도메인 패키지 외부로 분리했다.
-최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

컴포지트 패턴

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
-이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

인수 테스트 작성

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
+최대한 간결하게 구현한다고 생각을 해도, 이런 부분은 인터페이스를 두어 결합을 피하는 것이 좋을 것 같다.

+

컴포지트 패턴은 인터페이스를 구현한 개별 객체가 존재하고, 그 개별 객체들을 포함하는 하나의 구현체가 따로 존재하는 패턴이다.
+이때 사용자는 개별 객체와 합성 객체(개별 객체들을 포함하고 있는)를 똑같이 사용할 수 있다.

+

인수 테스트 작성

+

인수 테스트는 사용자 스토리 시나리오 기반 테스트다.
브라운이 해주신 강의 + 유튜브에 있는 브라운의 강의를 보고 지하철 미션에 인수 테스트를 적용해 보았다.
메서드, 변수명을 전부 한글로 작성했는데 전체적인 흐름을 알기 편하고 읽기도 좋았다.
-그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

결과는 아래와 같다.

@Nested
public class 노선을_전체_조회할_때 {

@Test
void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
// given
노선_생성_요청("2호선", "초록", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);

노선_생성_요청("9호선", "고동", 0);
노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);

// when
final var 조회_결과 = 노선_전체_조회_요청();

// then
요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
노선_전체_조회_결과를_확인한다(
조회_결과,
노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
);
}
}

페어에게 배울 부분

의견 조율하기

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
-의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

꼼꼼하게 코딩하기

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
+그리고 인수 테스트에 필요한 Steps를 만드는 과정이 너무 재밌었다.

+

결과는 아래와 같다.

+
@Nested
+public class 노선을_전체_조회할_때 {
+
+    @Test
+    void 상행종점역_부터_하행종점역으로_정렬된_결과를_반환한다() {
+        // given
+        노선_생성_요청("2호선", "초록", 0);
+        노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("2호선", "잠실", "잠실새내", 5);
+        구간_생성_요청("2호선", "잠실새내", "종합운동장", 오른쪽, 5);
+
+        노선_생성_요청("9호선", "고동", 0);
+        노선에_구간이_존재하지_않을_때_초기_구간_생성_요청("9호선", "봉은사", "종합운동장", 3);
+        구간_생성_요청("9호선", "종합운동장", "삼전", 오른쪽, 7);
+
+        // when
+        final var 조회_결과 = 노선_전체_조회_요청();
+
+        // then
+        요청_결과의_상태를_검증한다(조회_결과, 정상_요청);
+        노선_전체_조회_결과를_확인한다(
+                조회_결과,
+                노선_정보("2호선", "초록", 0, "잠실", "잠실새내", "종합운동장"),
+                노선_정보("9호선", "고동", 0, "봉은사", "종합운동장", "삼전")
+        );
+    }
+}
+
+

페어에게 배울 부분

+

의견 조율하기

+

밀리가 필요한 부분에서 의견을 적극적으로 내줘서 진행이 수월했다.
+의사소통이 매우 잘 돼서 좋았고 덕분에 시간 내에 요구사항을 만족해 미션을 제출할 수 있었던 것 같다.

+

꼼꼼하게 코딩하기

+

밀리는 코딩을 엄청 꼼꼼하게 하는 것 같다.
변수명, 메서드명을 중요하게 생각했고, 좋은 변수명을 잘 짓는 것 같다.
-또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

편한 분위기

전체적으로 페어 할 때 편하게 진행했던 것 같다.
+또한 코딩할 때 내가 평소에 사용하는 코딩 컨벤션에 맞춰주는 것 같아서 페어 할 때 편했다!

+

편한 분위기

+

전체적으로 페어 할 때 편하게 진행했던 것 같다.
일정도 그렇고, 페어 진행할 때도 그렇고 큰 문제가 없었던 것 같아서 좋았다.
나는 과연 다른 사람들에게 편한 사람일까?

- - \ No newline at end of file diff --git a/tecochat-retrospective-1.html b/tecochat-retrospective-1.html index faad05851..e86478fca 100644 --- a/tecochat-retrospective-1.html +++ b/tecochat-retrospective-1.html @@ -2,8 +2,8 @@ - -[테코챗] 1. 프로토타입 만들기 | GG + +[테코챗] 1. 프로토타입 만들기 | GG @@ -12,36 +12,64 @@ - - - + + + -
-

[테코챗] 1. 프로토타입 만들기

· 약 6분

4월 21일 금요일

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
+

[테코챗] 1. 프로토타입 만들기

· 약 6분

4월 21일 금요일

+

레벨 2를 시작한 뒤 내가 학습에 대한 방향을 잃어버렸다는 생각이 들었다.
레벨 3, 4에서 나만의 강점을 가지고 싶어 고민을 많이 했다.
단순히 스프링을 깊게 공부하는 건 효율이 많이 떨어진다고 생각했다.
-글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
-Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
-프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

이건 못참지

도메인 구입 성공?

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
+글쓰기 수상으로 받은 쿠폰을 사용해 브라운에게 커피챗을 신청했고, 사이드 프로젝트를 해보라는 답을 받았다.

+

나는 아이디어를 못내는 편인데 브라운이 아이디어까지 던져주셨다.
+Chat-GPT 서비스를 크루들에게 제공하고, 해당 크루들이 질문한 내용을 공유할 수 있는 건 어떤지?

+

기술이 목적인 사이드 프로젝트를 진행하면 좋을 것 같다는 답변을 들었고, 혼자 아니면 페어할 수 있을 정도의 인원으로 진행하면 좋겠다고 하셨다.
+프론트랑 간단하게 배포까지 해본 경험이 있어서 혼자해도 크게 어렵지 않을 것 같아서 혼자 하기로 마음을 먹었다.

+

이건 못참지

+

도메인 구입 성공?

+

커피챗이 끝나고 집으로 돌아가는 길에 바로 도메인을 구매하려고 namecheap에서 적당한 도메인이 없을까 검색을 계속했다.
마치 어릴 때 했던 게임 닉네임 정하는 것처럼 시간이 오래 걸렸다.
-dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

말랑의 DM

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
-우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
+dev, io, chat 도메인이 후보였고 집 가는 길에 결정만 하다가 구매하지 못했다.

+

말랑의 DM

+

집에 가서 밥을 먹고 말랑이랑 DM 하다 프로젝트를 같이 하자는 이야기가 나왔다.
+우테코 최고 고수 말랑의 요구라 수락하지 않으면 후폭풍을 감당할 수 없었다.

+

이런저런 대화를 나누다가 난 빠르게 프로토타입을 만들어 보고 싶어서 프론트를 구현한다고 했고, 말랑은 GPT api를 조사하기로 했다.
추가로 도메인에 관한 이야기를 하다가 woowachat이 언급되었고, namecheap에서 chat 도메인을 사용한 woowa.chat으로 구매했다.
-이후에 teco.chat으로 변경했다!

도메인 설정 및 배포

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
-나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

GPT

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
-일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

Sonarcloud

정적 코드 분석 도구로 Sonarcloud를 적용했다.
+이후에 teco.chat으로 변경했다!

+

도메인 설정 및 배포

+

토요일에 구매한 도메인을 CDN, 보안 등 다양한 기능을 제공하는 Cloudflare에 도메인 등록을 했다.
+나에게 익숙한 Nuxt3를 사용하기로 했고, Cloudflare Pages를 이용하여 배포했다.

+

GPT

+

무료 크레딧을 사용하니 api limit이 있어 분당 3번밖에 사용할 수 없었다.
+일단 백엔드를 구축하기 전에는 무료 크레딧을 사용할 생각이다.

+

Sonarcloud

+

정적 코드 분석 도구로 Sonarcloud를 적용했다.
Sonarcloud는 SonarQube의 SaaS 버전이고 사용이 매우 편하다.
예전에 Sonarcloud를 사용할 땐 버튼 몇 번 누르면 적용할 수 있었는데, 이번에는 바로 github action을 사용하라는 안내 페이지로 이동했다.
-Sonarcloud가 자체적으로 github repository에 push 하면 정적 분석을 해주는 기능을 원했고, Administration -> Analysis Method에 Automatic Analysis를 설정하니 되었다.
-너무 꽁꽁 숨겨져있네

Tiptap

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
+Sonarcloud가 자체적으로 github repository에 push 하면 정적 분석을 해주는 기능을 원했고, Administration -> Analysis Method에 Automatic Analysis를 설정하니 되었다.
+너무 꽁꽁 숨겨져있네

+

Tiptap

+

코드 하이라이팅 기능을 넣고 싶어서 Tiptap을 사용했다.
Tiptap은 Headless WYSIWYG 에디터로 사용자 정의 기능에 특화되어있는 에디터다.
아직 Tiptap이 제공하는 모든 기능을 자연스럽게 사용하지는 못하지만 CodeBlockLowlight 플러그인을 사용하여 코드 블록을 예쁘게 출력할 수 있었다.
api 반환값 그대로 tiptap의 content에 설정했더니 코드 블록이 설정되지 않아서 백 틱 3개를 <pre><code>로 변환했다.
추가로 띄어쓰기도 적용되지 않아서 \n<br>태그로 변환했다.
-변환하는 로직은 GPT의 도움을 많이 받았다.

const replaceCodeFences = (input: String) => {
const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
return input
.replace(codeFencesRegex, (match, p1, p2) => {
const languageClass = p1 ? ` class="language-${p1}"` : "";
return `<pre><code${languageClass}>${p2}</code></pre>`;
})
.replace(/\n/g, "<br>");
};

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

tecochat

폰트 및 favicon 적용

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
-추가로 favicon도 간단하게 적용해서 만족스러웠다.

- - +변환하는 로직은 GPT의 도움을 많이 받았다.

+
const replaceCodeFences = (input: String) => {
+    const codeFencesRegex = /```([\w-]*)\n([\s\S]*?)\n```/g;
+    return input
+        .replace(codeFencesRegex, (match, p1, p2) => {
+        const languageClass = p1 ? ` class="language-${p1}"` : "";
+        return `<pre><code${languageClass}>${p2}</code></pre>`;
+        })
+        .replace(/\n/g, "<br>");
+};
+
+

Tiptap을 적용하니 다음과 같이 깔끔한 코드 블록을 볼 수 있었다.

+

tecochat

+

폰트 및 favicon 적용

+

타이틀은 배달의민족 도현체, 내용은 IBM Plex Sans를 사용했다.
+추가로 favicon도 간단하게 적용해서 만족스러웠다.

\ No newline at end of file diff --git a/tecochat-retrospective-2.html b/tecochat-retrospective-2.html index 0b3b40a2a..180579dc5 100644 --- a/tecochat-retrospective-2.html +++ b/tecochat-retrospective-2.html @@ -2,8 +2,8 @@ - -[테코챗] 2. 배포 | GG + +[테코챗] 2. 배포 | GG @@ -12,32 +12,55 @@ - - - + + + -
-

[테코챗] 2. 배포

· 약 5분

프론트엔트

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
+

[테코챗] 2. 배포

· 약 5분

프론트엔트

+

닉네임을 입력하여 간단히 로그인하는 화면, 채팅 목록을 보여주는 화면도 만들었고 단일 채팅을 확인할 수 있는 화면도 만들었다.
추가로 채팅을 이어나갈 수 있게 하는 기능도 추가했다.
자잘하게 신경 쓸 부분이 많아서, 프론트엔드 하는 사람들이 대단하다고 생각되었다.
-여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

백엔드

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
+여유가 된다면 자신의 채팅을 볼 수 있는 기능이나, 채팅을 이어서 할 수 있는 기능, 댓글 기능도 추가할 예정이다.

+

백엔드

+

최대한 빨리 서비스를 크루들에게 제공하기로 정해서, 백엔드는 말랑이 일단 다 만들고 있다.
말랑이 한 부분이 너무 많아서 내가 못 따라가는 것 같다.
-나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

Http Request Header

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
+나중에 백엔드 코드를 이해하는 시간을 가져야겠다.

+

Http Request Header

+

아직 인증에 대한 부분을 하지 않아서 요청 헤더에 이름을 보내기로 했다.
말랑이 한글은 안된다고 말해줘서 Base64로 인코딩하고, 백엔드에서 디코딩 하여 사용하기로 했다.
-아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

const encodedName = () => {
const uriComponent = unescape(encodeURIComponent(name.value));
return btoa(uriComponent);
};

Elastic Beanstalk

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
+아래는 pinia에 있는 name 값을 인코딩 하는 코드다. deprecated 되었다는데, 다른 방법을 사용할 줄 몰라서 일단 이걸 사용했다.

+
const encodedName = () => {
+  const uriComponent = unescape(encodeURIComponent(name.value));
+  return btoa(uriComponent);
+};
+
+

Elastic Beanstalk

+

가장 빠르게 백엔드를 배포할 수 있는 방법이 뭘지 고민하다가 Elastic Beanstalk를 사용하기로 했다.
Elastic Beanstalk를 사용하면 인프라에 대해 잘 알지 못해도 애플리케이션을 빠르게 배포하고 관리할 수 있다.
-모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

Elastic Beanstalk RDS 설정 후 분리

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
+모니터링, 로깅, 로드 밸런싱 등 다양한 기능을 제공한다.

+

Elastic Beanstalk RDS 설정 후 분리

+

초기 설정 시 RDS를 연결하고 설정 완료 후 분리한다면, Beanstalk 인스턴스 -> RDS 요청 시 인바운드 설정을 안 해도 된다.
RDS 분리 시 Beanstalk에 기본적으로 설정되어 있는 RDS_HOSTNAME, RDS_PORT, RDS_USERNAME, RDS_PASSWORD와 같은 환경 변수가 같이 제거된다.
-추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

Elastic Beanstalk nginx 설정

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

Jenkins

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
+추가로 Elastic Beanstalk로 RDS를 설정하면 기본 데이터베이스 명은 ebdb다.

+

Elastic Beanstalk nginx 설정

+

업로드하는 zip 파일 내부에 .platform/nginx/conf.d/ 경로에 설정 파일을 추가하면 nginx 설정을 할 수 있다.

+

Jenkins

+

백엔드 코드를 일일히 배포하기 불편해서 Jenkins를 이용하여 Repository에 코드를 push 할 때 자동으로 배포가 되게 설정하기로 했다.
작년에 확인했을 땐 2022년 12월 31일까지 EC2 ARM 기반 t4g.small이 무료였는데, 다시 들어가 보니 2023년까지 12월 31일까지 t4g.small을 무료로 사용할 수 있었다.
t4g.small은 램이 2G인데, 예전에는 부족하지 않았다고 생각했는데 Java 17을 써서 그런가 빌드 할 때 램이 많이 부족한 것 같아서 Swap 메모리 2기가를 추가로 설정했다.
-추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

test {
maxHeapSize = "1024m"
}

Jenkins Blue Ocean

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
+추가로 build.gradle에서 아래와 같이 설정한다면 테스트 시 사용하는 램을 늘릴 수 있다. 기본값은 512MB라고 한다.

+
test {
+    maxHeapSize = "1024m"
+}
+
+

Jenkins Blue Ocean

+

Blue Ocean은 Jenkins Pipeline을 구성하는 데에 있어 편리하게 해주는 도구다.
시각화도 잘 되어있고, 설정도 편리한 것 같다.
-오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

참고 자료

Elastic Beanstalk, AWS
-EC2 AWS Graviton, AWS
-Default Memory Settings, AWS

- - +오늘 적용해 보니 램이 부족하여 중간에 잘 안되기도 하고 그래서 그냥 "Pipeline만 사용할 걸 그랬나?" 라는 생각이 든다.

+

참고 자료

+

Elastic Beanstalk, AWS
+EC2 AWS Graviton, AWS
+Default Memory Settings, AWS

\ No newline at end of file diff --git a/tecochat-retrospective-3.html b/tecochat-retrospective-3.html index 4679fae77..825cbadb2 100644 --- a/tecochat-retrospective-3.html +++ b/tecochat-retrospective-3.html @@ -2,8 +2,8 @@ - -[테코챗] 3. 기능 구현 | GG + +[테코챗] 3. 기능 구현 | GG @@ -12,27 +12,40 @@ - - - + + + -
-

[테코챗] 3. 기능 구현

· 약 5분

개요

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
-레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

나의 채팅 확인하고 이어하는 기능

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
-예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

chat1

좋아요와 댓글 기능

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
+

[테코챗] 3. 기능 구현

· 약 5분

개요

+

원래 목적인 크루들의 학습에 도움을 주기 위해 어떤 기능을 추가해야 할지 고민을 많이 했다.
+레벨 2가 거의 끝나가는 시점, 그동안 했던 것을 정리해 보려고 한다.

+

나의 채팅 확인하고 이어하는 기능

+

GPT에도 있는 기능인데, 내가 이전에 했던 채팅을 이어할 수 있는 기능을 추가했다.
+예전에 어떤 질문을 남겼는지, 또한 해당 채팅을 이어서 할 수 있다.

+

chat1

+

좋아요와 댓글 기능

+

다른 사람들이 질문한 내용에 반응할 수 있는 무언가가 있었으면 좋겠다는 의견들이 많았다.
누가 좋아요를 눌렀는지, 어떤 채팅이 좋아요를 가장 많이 받았는지 확인할 수 있는 기능을 추가했다.
-또한 댓글 추가 및 삭제 기능도 추가했다.

키워드 추출

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
+또한 댓글 추가 및 삭제 기능도 추가했다.

+

키워드 추출

+

어떻게 키워드 추출을 할지 고민을 많이 했는데, 일단 GPT를 이용해서 키워드를 추출하기로 했다.
해당 부분은 첫 질문에 대한 키워드만 추출하도록 했다.
백엔드에선 말랑이 이벤트 이용해서 첫 채팅 요청이 이루어지면, 비동기로 키워드를 추출하는 질문을 추가로 날리도록 구현하였다.
-CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

chat2

다른 크루의 채팅 복사해서 이어하는 기능

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
-채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

사용성 고려하기

chat3

위 화면은 회원가입 창이다.
+CSV 형식으로 GPT에게 답변을 입력해달라고 요청받는데, 이 부분이 문제(프롬프트 엔지니어링 부분이 반환된다.)가 좀 있는 것 같아서 개선이 필요한 것 같다.

+

chat2

+

다른 크루의 채팅 복사해서 이어하는 기능

+

다른 크루들의 채팅을 읽다가 궁금한 점이 있다면 복사해서 바로 질문을 할 수 있는 기능을 추가했다.
+채팅이 복사된 후 바로 GPT와 대화를 할 수 있는 메인 화면으로 이동한다.

+

사용성 고려하기

+

chat3

+

위 화면은 회원가입 창이다.
사실 가장 마음에 드는 부분이고, 회원가입(닉네임만 입력하지만)할 때 익명을 원하는 사람들의 고민을 도와주게 끔 음식, 과일, 과자 등의 요소들을 입력하도록 유도했다! 추가로 GPT의 답변이 오면 자동으로 화면을 스크롤 해주는 것과 같이 사용성을 개선해 보려고 노력했지만 쉽지 않았다.
-제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

향후 계획

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
+제일 하고 싶은 것은 실제 GPT를 사용하는 것처럼 stream/text 값을 처리하고 싶은데 이 부분은 방학 때 기회가 되면 도전해 봐야겠다.

+

향후 계획

+

실제 크루들이 사용해 주는 서비스를 직접 만들어보면서 사용자의 입장에서 고민도 하게 되는 것 같다.
크루들이 직접 사용해 주니까 너무 고맙고, 한편으로는 신기하다.
-일단 방학 때 stream/text 관련된 부분 동작되도록 구현해보려고 하고, 그 외의 부분은 조금 더 고민해야될 것 같다.

- - +일단 방학 때 stream/text 관련된 부분 동작되도록 구현해보려고 하고, 그 외의 부분은 조금 더 고민해야될 것 같다.

\ No newline at end of file diff --git a/test-double.html b/test-double.html index 8670b33fa..74c74dce9 100644 --- a/test-double.html +++ b/test-double.html @@ -2,8 +2,8 @@ - -테스트 대역 | GG + +테스트 대역 | GG @@ -12,31 +12,51 @@ - - - + + + -
-

테스트 대역

· 약 5분

테스트 대역이란?

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
-Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
-외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

테스트 대역의 타입 계층 구조

더미(Dummy)

가장 단순하고, 원시적인 유형의 테스트 대역이다.
+

테스트 대역

· 약 5분

테스트 대역이란?

+

모든 유형의 테스트를 위한 가짜 의존성을 의미하고, 테스트가 실행될 때 다른 객체를 대신한다.
+Gerard Meszaros의 xUnit Test Patterns라는 책에서는 테스트 대역을 다섯 가지(더미, 스텁, 스파이, 목, 페이크)로 구분한다.

+

테스트 대역의 기본 메커니즘은 다형성을 이용하는 방법이다.
+외부 서비스를 사용하는 코드를 테스트 하는 경우, 인터페이스를 정의하고 외부 서비스 대신 테스트 용도의 구현체를 생성하는 것이다.

+

테스트 대역의 타입 계층 구조

+ +

더미(Dummy)

+

가장 단순하고, 원시적인 유형의 테스트 대역이다.
기본적으로 아무 일도 하지 않는 구현체로 인스턴스화가 필요한 경우 사용한다.
-만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

스텁(Stub)

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
-이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

스파이(Spy)

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
-예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

목, 모의 객체(Mock)

목은 더미, 스텁, 스파이를 포함한다.
+만약 메서드가 무언가 반환을 해야하는 경우 0, null과 같은 값을 반환한다.

+

스텁(Stub)

+

시나리오마다 다른 값(미리 준비 된 결과)을 반환한다.
+이를 통해 특정 조건에서 메서드가 예상한대로 동작하는지 확인할 수 있다.

+

스파이(Spy)

+

스텁과 유사하지만 호출 여부를 기록하거나 호출할 때 전달한 인자값을 기록할 수 있다.
+예) 메일 전송 기능을 가진 객체를 테스트 대역으로 구현했을 때 메일 전송 횟수를 기록한다.

+

목, 모의 객체(Mock)

+

목은 더미, 스텁, 스파이를 포함한다.
호출 시 사전에 정의된 결과를 반환하고, 예상치 못한 호출이 있을 경우 예외를 던질 수 있다.
-또한 호출에 대한 검증을 할 수 있다.

가짜(Fake)

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
-예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

DOC(depended-on component)

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
-테스트 더블은 DOC와 동일한 API를 제공해야 한다.

상호작용에 따른 목과 스텁 구분

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
-목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
SUT(system under test)

테스트 대상 시스템
-테스트를 하려는 대상

참고 자료

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
+또한 호출에 대한 검증을 할 수 있다.

+

가짜(Fake)

+

DOC와 동일한 기능을 제공하지만, 더욱 간단한 방법으로 구현된 것이다.
+예) 실제 데이터베이스와 유사하게 동작하는 가짜 객체를 만들어 테스트할 수 있다.

+

의존 구성 요소, DOC를 테스트 더블로 대체할 수 있다.
+테스트 더블은 DOC와 동일한 API를 제공해야 한다.

+

상호작용에 따른 목과 스텁 구분

+

단위 테스트 p.149 에서는 테스트 대역을 크게 목과 스텁으로 구분한다.
+목은 SUT와 관련된 상호작용을 모방하고 검사하는 반면, 스텁은 단순 모방만 한다.

+
TestDoubleMockStub
포함 유형목, 스파이스텁, 더미, 페이크
용도외부로 나가는 상호작용을 모방하고 검사하는 데 사용내부로 들어오는 상호작용을 모방하는 데 사용
설명SUT가 상태를 변경하기 위한 의존성을 호출하는 것에 해당SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당
예시이메일 발송데이터 검색
+

테스트 대상 시스템
+테스트를 하려는 대상

+

참고 자료

+

소프트웨어 장인 정신 이야기 - 3장 고급 테스트 주도 개발, 로버트 C. 마틴
단위 테스트 - 5장 목과 테스트 취약성, 블라디미르 코리코프
테스트 주도 개발 시작하기 - 7장 대역, 최범균
-테스트 더블, Martin Fowler
-테스트 관련 용어 정리, Johngrib
-Test Double, Gerard Meszaros

- - +테스트 더블, Martin Fowler
+테스트 관련 용어 정리, Johngrib
+Test Double, Gerard Meszaros

\ No newline at end of file diff --git a/the-essence-of-object-orientation.html b/the-essence-of-object-orientation.html index 0aeeeb457..989bfcfad 100644 --- a/the-essence-of-object-orientation.html +++ b/the-essence-of-object-orientation.html @@ -2,8 +2,8 @@ - -[책] 객체지향의 사실과 오해 | GG + +[책] 객체지향의 사실과 오해 | GG @@ -12,33 +12,81 @@ - - - + + + -
-

[책] 객체지향의 사실과 오해

· 약 6분

책 정보

객체지향의 사실과 오해
-조영호

읽고 나서

조영호님의 오브젝트를 읽고 나서 다시 한 번 읽어보았다.
+

[책] 객체지향의 사실과 오해

· 약 6분

책 정보

+
+

객체지향의 사실과 오해
+조영호

+
+

읽고 나서

+

조영호님의 오브젝트를 읽고 나서 다시 한 번 읽어보았다.
아직 이해가 안되는 부분이 많지만, 그래도 항상 새로움을 느낀다.
-더할 나위 없이 휼륭한 객체지향 책이고, 조금 더 공부하고 다시 읽어봐야될 것 같다.

커피 전문점, 지하철 노선도, 이상한 나라의 엘리스를 예시로 든 설명이 너무 좋았고
-좋은 내용을 담고 있지만 그렇다고 너무 무겁지 않아 가볍게 읽기도 좋은 것 같다.

책임의 자율성을 강조하는 이유 p.173

협력을 단순하게 만든다.

  • 의도를 명확하게 표현 → 협력의 복잡함 저하
  • 책임의 추상화

외부와 내부를 명확하게 분리한다.

  • 요청하는 객체가 몰라도 되는 부분이 캡슐화됨으로 인터페이스와 구현의 분리

책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

  • 변경의 파급효과를 객체 내부로 캡슐화 → 메시지를 보내는 객체와의 결합도 저하

협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

  • 유연한 설계 → 재사용성 증가

객체의 역할을 이해하기 쉬워진다.

  • 응집도를 높은 상태로 유지

밑줄 친 문장들

객체지향의 목표는 실세계를 모방하는 것이 아니다. +더할 나위 없이 휼륭한 객체지향 책이고, 조금 더 공부하고 다시 읽어봐야될 것 같다.

+

커피 전문점, 지하철 노선도, 이상한 나라의 엘리스를 예시로 든 설명이 너무 좋았고
+좋은 내용을 담고 있지만 그렇다고 너무 무겁지 않아 가볍게 읽기도 좋은 것 같다.

+

책임의 자율성을 강조하는 이유 p.173

+

협력을 단순하게 만든다.

+
    +
  • 의도를 명확하게 표현 → 협력의 복잡함 저하
  • +
  • 책임의 추상화
  • +
+

외부와 내부를 명확하게 분리한다.

+
    +
  • 요청하는 객체가 몰라도 되는 부분이 캡슐화됨으로 인터페이스와 구현의 분리
  • +
+

책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

+
    +
  • 변경의 파급효과를 객체 내부로 캡슐화 → 메시지를 보내는 객체와의 결합도 저하
  • +
+

협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

+
    +
  • 유연한 설계 → 재사용성 증가
  • +
+

객체의 역할을 이해하기 쉬워진다.

+
    +
  • 응집도를 높은 상태로 유지
  • +
+

밑줄 친 문장들

+
+

객체지향의 목표는 실세계를 모방하는 것이 아니다. 오히려 새로운 세계를 창조하는 것이다. 소프트웨어 개발자의 역할은 단순히 실세계를 소프트웨어 안으로 옮겨 담는 것이 아니라 고객과 사용자를 만족시킬 수 있는 신세계를 창조하는 것이다. -p.21

과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. +p.21

+
+
+

과거의 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. 이에 반해 객체지향에서는 데이터와 프로세스를 객체라는 하나의 틀 안에 함께 묶어 놓음으로써 객체의 자율성을 보장한다. 자율적인 객체로 구성된 공동체는 유지 보수가 쉽고 재사용이 용이한 시스템을 구축할 수 있는 가능성을 제시한다. -p.33

객체지향의 본질

시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. -p.35

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. +p.33

+
+
+

객체지향의 본질

+

시스템을 상호작용하는 자율적인 객체들의 공동체로 바라보고 객체를 이용해 시스템을 분할하는 방법

+

자율적인 객체란 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체를 의미한다.

+

객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

+

객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. +p.35

+
+
+

클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하라. 객체지향은 객체를 지향하는 것이지 클래스를 지향하는 것이 아니다. -p.38

객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행위’다. +p.38

+
+
+

객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행위’다. 클래스는 타입을 구현하기 위해 프로그래밍 언어에서 제공하는 구현 메커니즘이라는 사실을 기억하라. -p.105

책임 주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. +p.105

+
+
+

책임 주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다. 이 과정을 흔히 What/Who 사이클이라고 한다. ’어떤 행위(What)’를 수행할 것인지 결정한 후 ‘누가(who)’ 그 행위를 수행할 것인지 결정해야 한다. 여기서 ‘어떤 행위’가 바로 메시지다. -p.158

- - +p.158

+
\ No newline at end of file diff --git a/tomcat-retrospective.html b/tomcat-retrospective.html index 08700fbfc..7f52e5253 100644 --- a/tomcat-retrospective.html +++ b/tomcat-retrospective.html @@ -2,8 +2,8 @@ - -톰캣 구현 미션 회고 | GG + +톰캣 구현 미션 회고 | GG @@ -12,43 +12,210 @@ - - - + + + -
-

톰캣 구현 미션 회고

· 약 13분

톰캣 구현

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
-그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
-톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

다이어그램

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
+

톰캣 구현 미션 회고

· 약 13분

1, 2단계: https://github.com/woowacourse/jwp-dashboard-http/pull/302
+3, 4단계: https://github.com/woowacourse/jwp-dashboard-http/pull/431

+

톰캣 구현

+

우아한테크코스를 지원할 때 객체지향과 관련된 미션도 기대를 많이 했지만 레벨 4에 진행하는 미션이 정말 하고 싶었다.
+그래서 미션을 할 수 있을까라는 걱정 반, 미션에 대한 기대 반으로 부푼 마음을 가지고 미션을 시작했던 것 같다.

+

이번 미션에서는 적절하게 추상화하고, 미션의 본질을 이해하려고 노력했다.
+톰캣 구현 미션은 RFC 2616에 명시된 스펙(완벽하지 않지만 미션에서 주어진 요구사항만 만족하도록)으로 요청을 받아 처리 후 반환하는데 집중했다.

+

다이어그램

+

Catalina는 Tomcat의 서블릿 컨테이너, Coyote는 HTTP 1.1 웹 서버를 지원하는 구성 요소라고 생각하고 아래와 같이 구성했다.
사실 내부 구조를 깊게 공부할 시간을 가지지 못해서 각 구성 요소가 왜 해당 위치에 있는지 완벽하게 설명하지는 못하지만 미션을 진행하면서 이건 여기에 있으면 좋을 것 같은데? 라는 생각이 들면 적절한 패키지에 위치시키는 방향으로 진행을 했다.
-또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

코드 리뷰

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
-나의 리뷰어는 디노, 리뷰이는 필립이었다.

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
+또한 적절하게 인터페이스를 사용하여 의존성 방향을 단방향으로 하려고 노력했다.

+ +

코드 리뷰

+

크루 중 한 명이 나의 리뷰어가 되고, 내가 다른 크루의 리뷰어가 되는 형태로 진행이 되었다.
+나의 리뷰어는 디노, 리뷰이는 필립이었다.

+

디노(매의 눈이 아닌 공룡의 눈?)가 매우 꼼꼼하게 코드 리뷰를 해주어서 조금 더 나은 코드를 작성할 수 있었고, 필립의 코드에서는 꼼꼼하게 예외처리 하는 부분을 배울 수 있었다.
한 가지 아쉬운 점은 필립에게 작성한 나의 코멘트들이 미션을 진행하면서 경험 기반으로 작성한 내용이 많아 근거가 조금 부족했고, 정리되지 않은 부분이 많았던 것 같다.
-다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

SessionConfig

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
+다음 미션부터 리뷰할 때 조금 더 시간을 투자해서 더 좋은 내용을 크루들과 공유할 수 있도록 노력해야겠다.

+

SessionConfig

+

미션을 진행 중 catalina 패키지의 Session 관련 부분을 보면서 중복 로직을 개선해 볼 수 있을 것 같아 컨트리뷰트를 시도했다.
세션 쿠키의 이름을 가져오는 Util 클래스의 코드를 수정했는데 기본 값은 JSESSIONID 지만 설정에 따라서 세션 쿠키명을 다르게 사용할 수 있기 때문에 해당 로직이 있는 것으로 생각했다.
-기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
+기존의 코드는 명시된 주석의 내용과 코드의 흐름이 일치하지 않아서 약간 이해하기 어려웠다.

+

초기에 요청했던 PR은 기존의 코드보다 전체적으로 비교 연산을 한 번 줄일 수 있었고, context가 null인 경우 바로 기본 값을 반환함으로써 성능 개선의 효과가 있을 거라고 생각했다.
메인테이너인 Mark Thomas 형이 해당 로직의 경우 컴파일러가 해당 부분을 최적화 할 수 있을 거라고 기대한다고 했고, 가독성을 개선시켜보라고 조언해주셨다.
-컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
-결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

public static String getSessionCookieName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_COOKIE_NAME;
}

return result;
}

public static String getSessionUriParamName(Context context) {

String result = getConfiguredSessionCookieName(context);

if (result == null) {
result = DEFAULT_SESSION_PARAMETER_NAME;
}

return result;
}

private static String getConfiguredSessionCookieName(Context context) {

// Priority is:
// 1. Cookie name defined in context
// 2. Cookie name configured for app
// 3. Default defined by spec
if (context != null) {
String cookieName = context.getSessionCookieName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}

SessionCookieConfig scc =
context.getServletContext().getSessionCookieConfig();
cookieName = scc.getName();
if (cookieName != null && cookieName.length() > 0) {
return cookieName;
}
}

return null;
}

HTTP 수업

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
+컴파일러 최적화는 고려해보지 못한 부분인데, 앞으로 학습해야 할 부분이 산더미라고 생각했다.

+

남겨준 코멘트에 따라 최종적으로는 중복된 코드를 줄이는 방향으로 코드를 수정했다.
+결과적으로 기존 로직 대비 비교 연산을 한 번 줄일 수 있었고, 명시된 주석의 내용과 유사한 흐름의 코드를 작성하여 좋은 방향으로 리팩터링을 했다고 생각한다.

+ + +
public static String getSessionCookieName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_COOKIE_NAME;
+    }
+
+    return result;
+}
+
+public static String getSessionUriParamName(Context context) {
+
+    String result = getConfiguredSessionCookieName(context);
+
+    if (result == null) {
+        result = DEFAULT_SESSION_PARAMETER_NAME;
+    }
+
+    return result;
+}
+
+private static String getConfiguredSessionCookieName(Context context) {
+
+    // Priority is:
+    // 1. Cookie name defined in context
+    // 2. Cookie name configured for app
+    // 3. Default defined by spec
+    if (context != null) {
+        String cookieName = context.getSessionCookieName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+
+        SessionCookieConfig scc =
+            context.getServletContext().getSessionCookieConfig();
+        cookieName = scc.getName();
+        if (cookieName != null && cookieName.length() > 0) {
+            return cookieName;
+        }
+    }
+
+    return null;
+}
+
+

HTTP 수업

+

미션 중간에 진행되었던 HTTP 수업에는 HTTP를 적절하게 활용하는 부분에 대해 학습했다.
항상 성능 개선을 위해 애플리케이션 단에서 최적화해보려고 노력을 했지만, 더 적은 시간을 투자해서 효율적으로 성능을 개선할 수 있는 방법에 대해 알 수 있었던 수업이었다.
-HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

server:
compression:
enabled: true

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
-궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
-내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

ETag

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
+HTTP 압축, HTTP 캐싱, 리소스 최적화 기법에 대해 학습했다.

+

스프링 부트에서는 다음 옵션을 설정하여 http의 송수신의 압축을 진행할 수 있다.

+
server:
+  compression:
+    enabled: true
+
+

수업 중 해당 압축 성능이 좋다면 왜 스프링 부트에서는 기본 값으로 설정을 하지 않았는지 궁금해졌다.
+궁금증을 해소하지 못했는데 말랑이 잡담 채널에 다음과 같은 issue를 찾아주었다.
+내용을 요약해 보자면 WAS 별로 압축을 하기 위해 설정해야 하는 것이 다르고, 무조건 압축을 하는 것이 최적의 경우가 아닐 수 있기 때문에 기본값으로 설정하지 않는 것 같다.

+
+

If you're developing a public-facing application then it's probably likely gzip compression would be worthwhile. If, however, you're a microservice application and you're in a dataceter, you may well prefer to reduce CPU load because you know you'll only be talking to other microservices and you have a reliable gigabit network.

+
+

Phil Webb 형님의 말에 따르면 일반적인 애플리케이션을 개발하는 경우 gzip 압축을 사용하는 것이 좋지만, MSA 환경 + 데이터 센터에서 사용하는 경우 오직 다른 MSA 애플리케이션과 통신하고, 고성능 네트워크가 있기 때문에 CPU 부하를 줄이는 것이 우선시 될 수도 있다는 것이었다.

+

이외에도 의도하지 않은 캐싱을 막기 위해 휴리스틱 캐싱을 제거하거나, 개인 정보 유출을 막기 위해 응답 헤더에 private을 설정, ETag도 학습했다.

+

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자다.
웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐시가 더 효율적이게 된다.
-MDN

Thread 수업

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
-현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
-학습한 내용은 다음과 같다.

threads.max: Tomcat의 최대 스레드 개수
+MDN

+

Thread 수업

+

스레드에 대한 수업을 들었지만, 복잡한 내용도 워낙 많았기 때문에 설명하라고 하면 잘 못할 것 같은 느낌이 든다.
+현재 프로젝트, 미션, 테코톡 준비를 병행해야 해서 세부적인 내용은 시간 날 때 복습하려고 한다.

+

스레드를 이해하고, WAS에 스레드 설정 관련한 실습이 있었는데 테오와 같이 1시간 정도 페어로 Thread 실습을 진행해 보았다.
+학습한 내용은 다음과 같다.

+

threads.max: Tomcat의 최대 스레드 개수
max-connections: Tomcat이 유지할 수 있는 최대 커넥션 개수
-accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

마치며

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
+accept-count: 최대 연결 수에 도달했을 때 연결 요청에 대해 운영 체제에서 제공하는 대기열의 최대 길이. 해당 Queue에 요청이 쌓이는 것은 Tomcat이 더 이상 요청을 받을 수 없다는 뜻이다. accpet-count queue에도 요청이 가득차면 그 이후에 오는 요청은 거부된다.

+ +

마치며

+

시간은 너무 빠르게 가고 할 일은 많은 것 같다.
우선순위를 잘 정하고 학습을 진행해야겠다.
-현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

참고 자료

RFC 2616
-ETag, mdn
-Apache Tomcat 8 Configuration Reference
-Apache Tomcat Tuning, Terry Cho
-maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

- - +현재 데이터 다루는 부분(DB)에 대한 학습이 많이 부족한 것 같다. 해당 부분은 테코톡이 끝나는대로 채워야겠다.

+

참고 자료

+

RFC 2616
+ETag, mdn
+Apache Tomcat 8 Configuration Reference
+Apache Tomcat Tuning, Terry Cho
+maxThreads, maxConnections, acceptCount로 Tomcat 튜닝하기

\ No newline at end of file diff --git a/transaction-and-isolation.html b/transaction-and-isolation.html index 5a10d5e21..eb8d6350c 100644 --- a/transaction-and-isolation.html +++ b/transaction-and-isolation.html @@ -2,8 +2,8 @@ - -트랜잭션과 격리수준 | GG + +트랜잭션과 격리수준 | GG @@ -12,37 +12,139 @@ - - - + + + -
-

트랜잭션과 격리수준

· 약 10분

트랜잭션(Transaction)

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
+

트랜잭션과 격리수준

· 약 10분

트랜잭션(Transaction)

+

데이터베이스에서 논리적 기능을 수행하기 위한 작업의 단위를 말한다.
트랜잭션은 작업의 완전성과 데이터의 정합성을 보장해 준다.
-논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

트랜잭션의 속성(ACID)

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
+논리적인 작업 셋을 완벽하게 처리하거나, 오류 시 작업의 일부만 적용되는 현상을 막아준다.

+

트랜잭션의 속성(ACID)

+

원자성(Atomicity): 트랜잭션 내에서 실행된 작업들은 모두 성공하거나, 실패해야 한다.
일관성(Consistency): 트랜잭션이 수행되기 전과 후에 데이터베이스가 일관된 상태를 유지해야 한다.
격리성(Isolation): 각각의 트랜잭션은 독립적이라 서로에게 영향을 주지 않아야 한다.
-지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

트랜잭션 주의사항

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
-구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

왜 네트워크 작업이 있을 때 트랜잭션에서 배제해야 할까? 🤔

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
-네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)

격리 수준(Isolation level)

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
-격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

READ UNCOMMITTED

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
+지속성(Durability): 트랜잭션이 성공적으로 완료된다면 영구적으로 결과에 반영되어야 한다.

+

트랜잭션 주의사항

+

트랜잭션은 꼭 필요한 최소의 코드에만 적용하는 것이 좋다.(트랜잭션의 범위를 최소화하라)
+구현해야 하는 업무에 따라 트랜잭션을 묶거나 트랜잭션에서 제외하고, 네트워크 작업이 있는 경우 반드시 트랜잭션에서 배제해야 한다.

+

데이터의 일관성과 안전성을 보장하기 위해 배제해야 한다.
+네트워크 작업을 트랜잭션 내부에 포함한다면 다음과 같은 문제가 발생할 수 있다.

    +
  • 네트워크 작업이 중간에 실패할 가능성(안전성 X)
  • +
  • 통신으로 인해 데이터가 변경될 수 있는 부분(일관성 X)
  • +
+

격리 수준(Isolation level)

+

여러 트랜잭션이 동시에 처리될 때 특정 트랜잭션이 다른 트랜잭션에서 데이터의 조회 및 변경을 허용할지 결정하는 것을 말한다.
+격리 수준이 높아질 수록 동시 처리 성능이 떨어지는 것이 일반적이지만, SERIALIZABLE이 아니라면 크게 성능의 저하가 발생하지 않는다.

+

READ UNCOMMITTED

+

각 트랜잭션에서의 변경 내용이 COMMIT이나 ROLLBACK 여부에 상관없이 다른 트랜잭션에서 보인다.
더티 리드 현상이 발생하기 때문에 정합성의 문제가 많은 격리 수준이다.
-MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

READ COMMITTED

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
+MySQL 사용시 최소 READ COMMITTED 이상의 격리 수준 사용을 권장한다.

+ +

READ COMMITTED

+

트랜잭션에서 데이터를 변경하더라도 COMMIT이 완료된 데이터만 다른 트랜잭션에서 조회할 수 있다.
오라클 DBMS에서 기본으로 사용되는 격리 수준이다.
-REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

REPEATABLE READ

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
+REPEATABLE READ가 보장되지 않기 때문에 NON-REPEATABLE READ 문제가 발생한다.

+ +

REPEATABLE READ

+

트랜잭션이 시작되기 전에 COMMIT이 완료된 내용에 대해서만 조회할 수 있다.
MySQL의 InnoDB 스토리지 엔진에서 기본으로 사용되는 격리 수준이다.
MVCC를 이용해 언두(Undo) 영역에 백업된 이전 데이터를 이용해 동일 트랜잭션 내에서는 동일한 결과를 보여줄 수 있게 보장한다.
-동일한 결과를 보장하는 방법은 다음과 같다.

  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

갭 랍(Gap lock)과 넥스트 키 락(Next-key lock)

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
-넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

MVCC(Multi Version Concurrency Control)

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

SERIALIZABLE

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
+동일한 결과를 보장하는 방법은 다음과 같다.

+
    +
  • 모든 InnoDB 트랜잭션은 순차적으로 증가하는 고유한 트랜잭션 번호를 가진다.
  • +
  • Undo 영역에 백업된 레코드에는 변경을 발생시킨 트랜잭션의 번호가 포함되어있다.
  • +
  • Undo 영역의 백업된 데이터는 스토리지 엔진이 불필요하다고 판단하는 경우 삭제된다.
  • +
  • REPEATABLE READ 격리 수준에서는 MVCC를 보장하기 위해 가장 오래된 트랜잭션 번호보다 앞선 Undo 영역의 데이터는 삭제하지 않는다.
  • +
+

InnoDB에서는 갭 락과 넥스트 키 락을 이용하여 팬텀 리드 현상을 방지한다.

+ +

갭 락: 레코드와 바로 인접한 레코드 사이의 간격만을 잠그는 락이다.
+넥스트 키 락: 레코드 락과 갭 락을 합쳐놓은 형태의 잠금으로 레코드와 그 레코드 앞의 갭 락을 포함한다.

+

동시성을 제어하는 방법 중 하나로 하나의 레코드에 대해 여러 개의 버전이 동시에 관리되는 것이다.

    +
  • PostgreSQL은 다중 버전의 데이터를 저장하는 것으로 MVCC를 구현한다.
  • +
  • Oracle, InnoDB는 Undo log를 이용해 이 기능을 구현한다.(최신 버전의 데이터만 DB에 저장)
  • +

잠금을 사용하지 않는 읽관된 읽기를 제공하는 것이 목적이다.

+

SERIALIZABLE

+

트랜잭션을 순차적으로 진행시키는 격리 수준이고 따라서 동시 처리 성능도 다른 격리 수준보다 떨어진다.
트랜잭션에서 읽고 쓰는 레코드를 다른 트랜잭션에서는 접근할 수 없고 단순한 읽기 작업도 공유 잠금(읽기 잠금)을 획득해야만 한다.
-InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

격리 수준에 따른 부정합 문제

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX

더티 리드(Dirty read)

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
+InnoDB에서는 팬텀 리드 현상이 REPEATABLE READ 격리 수준에서 발생하지 않기 때문에 굳이 사용할 필요는 없다.

+

격리 수준에 따른 부정합 문제

+

격리 수준에 따라 더티 리드, 반복 가능하지 않은 조회, 팬텀 리드 문제가 발생한다.

+
격리 수준 / 부정합 문제더티 리드반복 가능하지 않은 조회팬텀 리드
READ UNCOMMITTEDOOO
READ COMMITTEDXOO
REPEATABLE READXXO(InnoDB는 X)
SERIALIZABLEXXX
+

더티 리드(Dirty read)

+

어떤 트랜잭션에서 처리한 작업이 완료되지 않았어도 다른 트랜잭션에서 볼 수 있는 현상
트랜잭션 격리 수준이 READ UNCOMMITTED일 때 발생한다.
-예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

반복 가능하지 않은 조회(Non-repeatable read)

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
-예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

팬텀 리드(Phantom read, Phantom row)

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
-예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

참고 자료

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
-Isolation Level, MySQL

- - +예) B가 레코드를 추가하고 커밋을 하지 않았지만, A가 해당 레코드를 조회할 수 있는 경우

+

반복 가능하지 않은 조회(Non-repeatable read)

+

한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 현상
+예) A가 레코드를 여러 번 조회하던 중 B가 레코드를 변경하여 A가 조회한 값이 달라지는 경우

+ +

팬텀 리드(Phantom read, Phantom row)

+

한 트랜잭션 내에서 동일한 쿼리 수행시, 수행 결과가 다른 현상
+예) A가 레코드를 조회하고 B가 레코드를 추가하여 A가 다시 조회할 때 존재하지 않은 레코드가 조회되는 경우

+ +

참고 자료

+

Real My SQL 8.0 - 5장 트랜잭션과 잠금, 백은빈, 이성욱
+Isolation Level, MySQL

\ No newline at end of file diff --git a/web-application-evolution.html b/web-application-evolution.html index 65a79b1e9..7d44d05df 100644 --- a/web-application-evolution.html +++ b/web-application-evolution.html @@ -2,8 +2,8 @@ - -웹 애플리케이션 발전 과정 | GG + +웹 애플리케이션 발전 과정 | GG @@ -12,36 +12,70 @@ - - - + + + -
-

웹 애플리케이션 발전 과정

· 약 8분

웹 애플리케이션 발전 과정

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
+

웹 애플리케이션 발전 과정

· 약 8분

웹 애플리케이션 발전 과정

+

웹 애플리케이션의 발전 과정 대한 구구의 강의가 있었다.
간단하게 정리하자면 다음과 같은 흐름으로 웹 애플리케이션이 발전했다.
-원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.

WWW(1989)

정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.

CGI(1993)

CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.

Servlet(1996)

Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.
-하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.

JSP(1999)

JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.
-JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.

MVC(2000)

위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.

I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
-Govind Seshadri

이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.
-해당 문서를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.

Spring Framework(2003)

Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.
+원래 회고에 작성하려고 했지만, 정리하다 보니 조금 길어져서 따로 분리했다.

+ +

WWW(1989)

+

정적 페이지를 제공하는 웹 서버를 시작으로 동적 페이지가 필요했기 때문에 CGI가 등장했다.

+

CGI(1993)

+

CGI는 동적 콘텐츠를 제공하기 위한 규약으로, 해당 인터페이스를 구현한 스크립트를 이용해서 매 요청마다 프로세스를 실행시켜 정보를 반환하도록 한다. 하지만 매 요청마다 프로세스를 실행시키기 때문에 서버에 많은 부하가 발생할 수 있다. 따라서 이러한 단점을 극복하기 위해 나온 것이 Servlet이다.

+

Servlet(1996)

+

Servlet은 웹 서버에서 실행되는 자바 프로그램으로 HTTP를 이용하여 웹 클라이언트의 요청을 수신하고 응답한다. CGI와 다르게 매 요청마다 프로세스가 아닌 스레드를 생성하여 응답한다.
+하지만 View 영역의 코드를 작성하기 위해 Servlet의 소스 코드를 알아야 하는 등 복잡도가 너무 높았다. 따라서 해당 문제를 해결하기 위해 JSP가 등장했다.

+

JSP(1999)

+

JSP는 HTML에 자바 코드를 작성하여 동적 웹 페이지를 생성하는 기술로, 유사한 기술로는 ASP, PHP가 있다.
+JSP만 사용하여 프로그래밍한다면 Model 1, 아래 구성도와 같이 JSP가 View 영역만 담당한다면 Model 2라고 한다.

+ +

MVC(2000)

+

위 JSP의 구성도를 보면 현재 MVC와 매우 유사한데, Govind Seshadri라는 사람이 JSP Model 2를 MVC 패턴으로 공식화를 제안했다.

+
+

I provide an in-depth look at how you can gain optimal separation of presentation from content by using the JSP Model 2 architecture. This model can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
+Govind Seshadri

+
+

이때 MVC 패턴이 처음 탄생한 것은 아니고, 서버 측 구현이라고 하는 것을 보니 MVC가 처음 등장한 건 아닌 것 같다.
+해당 문서를 보면 MVC라는 용어의 등장은 1978년에 등장한 것으로 보인다.

+

Spring Framework(2003)

+

Spring은 복잡했던 J2EE을 대체하기 위해 2003년에 등장했다.
J2EE는 웹 기반의 엔터프라이즈 애플리케이션을 구축하기 위한 플랫폼으로 위에서 설명한 Servlet, JSP, EJB 등의 기술을 포함하고 있다.
하지만 이중 EJB라는 기술이 J2EE의 핵심 기술이었는데, 해당 기술이 매우 복잡했기 때문에 사용에 문제가 많았다고 한다.
-2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 Expert One-to-One J2EE Development라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.

스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.

WebFlux 이전 Servlet 3.0(2009), 3.1(2013)

Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.
-그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.

Spring WebFlux(2017)

적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.
-추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.

마치며

해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.
-그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.

참고 자료

웹 애플리케이션의 발전 과정, 구구 강의
-Dynamic Content with CGI, Apache Tutorial
-History of Spring and the Spring Framework, Spring
-Understanding JavaServer Pages Model 2 architecture, Govind Seshadri
-MVC, XEROX PARC
-Expert One-to-One J2EE Development, Rod Johnson
-배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족
-Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu -WebFlux Overview, Spring -Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2
-Spring WebFlux란 무엇일까

- - +2002년에 Rod Johnson이 EJB를 사용하지 않고 J2EE 애플리케이션을 구축하는 방법에 대해 저술한 Expert One-to-One J2EE Development라는 책을 발행했고, 출간 후 Juergen Hoeller, Yann Caroff가 Rod Johnson에게 오픈소스 제안을 하여 스프링이 탄생했다고 한다.

+

스프링은 엔터프라이즈 서비스 기능을 POJO에 제공하며, 이 덕분에 스프링을 사용하여 비즈니스 로직에 집중할 수 있다.

+

WebFlux 이전 Servlet 3.0(2009), 3.1(2013)

+

Tomcat의 NIO 동작 방식을 보면 Poller가 소켓 커넥션을 들고 있다가 처리가 가능할 때 스레드를 할당하는 식으로 처리를 한다. 하지만 할당 후 Servlet과 통신하는 부분은 블로킹 방식으로 요청이 끝날 때까지 스레드를 점유하고 있었고, 스레드 점유로 인해 요청이 max thread에 도달하면 요청을 처리할 수 없었다.
+그래서 비동기 방식의 Servlet이 Servlet 3.0에 등장했다. 하지만 전통적인 I/O 방식을 사용하는 부분은 블로킹 방식으로 동작했다. Servlet 3.1에서 논블로킹 I/O가 추가되었지만, 많이 사용되지 않았다고 한다.

+

Spring WebFlux(2017)

+

적은 수의 스레드로 동시성을 처리하고, 적은 리소스로 확장이 가능한 논블로킹 방식의 웹 기술이 필요했고, 기존의 Servlet의 경우 비동기를 지원한다 해도 동기식 API들이 많이 남아있었기 때문에 이러한 Servlet에 영향을 받지 않는 기술이 필요했다. 또한 기존에 Netty와 같이 비동기, 논블로킹 방식 서버로 자리를 잘 잡은 서버를 위해 Spring WebFlux가 등장했다.
+추가로 데이터 접근을 위해 사용하는 JDBC의 경우 Blocking API라, Spring Webflux에서는 R2DBC를 사용한다고 한다.

+

마치며

+

해당 정리 내용의 경우 Async, Non Blocking 관련된 내용을 깊게 공부한 적이 없어서 정확하지 않을 수 있다.
+그래도 기술의 등장 배경이나 과정을 알고 있다면 조금 더 깊이 있는 학습에 도움이 된다고 생각한다.

+

참고 자료

+

웹 애플리케이션의 발전 과정, 구구 강의
+Dynamic Content with CGI, Apache Tutorial
+History of Spring and the Spring Framework, Spring
+Understanding JavaServer Pages Model 2 architecture, Govind Seshadri
+MVC, XEROX PARC
+Expert One-to-One J2EE Development, Rod Johnson
+배달의민족 최전방 시스템! ‘가게노출 시스템’을 소개합니다, 배달의민족
+Asynchronous processing support in Servlet 3.0, Dr. Xinyu Liu +WebFlux Overview, Spring +Spring WebFlux와 Armeria를 이용하여 Microservice에 필요한 Reactive + RPC 동시에 잡기, Naver D2
+Spring WebFlux란 무엇일까

\ No newline at end of file diff --git a/web-racing-car-retrospective.html b/web-racing-car-retrospective.html index d62c16b34..8045ac9b5 100644 --- a/web-racing-car-retrospective.html +++ b/web-racing-car-retrospective.html @@ -2,8 +2,8 @@ - -웹 자동차 미션 회고 | GG + +웹 자동차 미션 회고 | GG @@ -12,33 +12,50 @@ - - - + + + -
-

웹 자동차 미션 회고

· 약 4분

웹 자동차 미션

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
+

웹 자동차 미션 회고

· 약 4분

1단계: https://github.com/woowacourse/jwp-racingcar/pull/24
+2단계: https://github.com/woowacourse/jwp-racingcar/pull/128

+

웹 자동차 미션

+

사이드 프로젝트를 한다고 시간이 많이 없어서 회고가 늦어졌다.
웹 자동차 미션에서는 비버와 페어가 매칭되었다.
-레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
+레벨 2에서 진행하는 첫 미션이라 많이 긴장되었지만, 그래도 비버랑 초반에 맛있는 것도 많이 먹으면서 빨리 친해져서 재밌게 할 수 있었다.

+

스프링을 조금 사용할 줄 알아서, 비버랑 같이 학습하면서 미션을 진행했다.
첫 미션이라 그런지 특별한 부분은 없었고, 최대한 깔끔하게 작성하려고 노력했다.
난이도 높은 미션이 아니었지만 리뷰어인 라빈에게 칭찬을 많이 받아서 기분이 좋았다.
-라빈 감사합니다!

부족했던 부분

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
+라빈 감사합니다!

+

부족했던 부분

+

컨디션도 좋지 않고 열정도 식은 것 같은 느낌이 들었다.
미션이 다소 여유롭다고 느껴져서, 시간에 대한 부분도 잘 관리하지 못한 것 같다.
-미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
+미션에 잘 집중하지 못해서 페어에게 많이 미안했고, 나 자신에게 아쉬웠던 부분이 많았다.

+

지난번 회고를 다시 보는데 집중을 잘 못한 경우가 많은 것 같다.
도전적이지 않거나 시간이 부족하지 않으면 집중을 잘 못하는 것 같다.
-머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

새로 학습한 부분

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

@SuppressWarnings("NonAsciiCharacters")
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
@Transactional
@AutoConfigureMockMvc
@SpringBootTest
public class RacingGameIntegrationTest {

페어에게 배울 부분

비버의 성격
+머릿속에서 시간적 여유가 있다고 생각할 때가 가장 위험한 순간인 것 같다.

+

함께 자라기에서 나온 난이도 높이기가 필요해지는 순간이다.

+

새로 학습한 부분

+

중요도가 있는 어노테이션부터 클래스 이름에 가깝게 명시하기

+
@SuppressWarnings("NonAsciiCharacters")
+@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
+@Transactional
+@AutoConfigureMockMvc
+@SpringBootTest
+public class RacingGameIntegrationTest {
+
+

페어에게 배울 부분

+

비버의 성격
비버가 성격이 좋아서 편하게 페어를 할 수 있었다.
-미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

미션에 집중하는 부분
+미션을 진행하면서 성급하지 않고 여유로워서 좋았다.

+

미션에 집중하는 부분
내가 미션에 잘 집중하지 못했는데도 같이 페어를 잘 진행한 것 같아서 좋았다.
비버가 미션에 잘 집중해서 그렇지 않았나 생각했다.
근육맨 비버라 그런지 체력이 좋아서 그런가?
-중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

학습에 대한 열정
-추가적으로 알고 싶은 부분을 따로 학습하는 열정이 좋다고 생각했다.
+중간에 잘 안 쉬고도 집중해서 미션을 진행하는 걸 보고 대단하다고 생각했다.

+

학습에 대한 열정
+추가적으로 알고 싶은 부분을 따로 학습하는 열정이 좋다고 생각했다.
비버와 스프링에 대해 알아가는 시간을 많이 가진 부분이 매우 좋았다.
-나도 5월부터 조금 더 화이팅 해야겠다.

- - +나도 5월부터 조금 더 화이팅 해야겠다.

\ No newline at end of file diff --git a/websocket.html b/websocket.html index 9ceacf352..721865915 100644 --- a/websocket.html +++ b/websocket.html @@ -2,8 +2,8 @@ - -웹소켓 | GG + +웹소켓 | GG @@ -12,27 +12,71 @@ - - - + + + -
-

웹소켓

· 약 5분

웹소켓

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
-웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

웹소켓 등장 배경

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
-이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

polling, long polling, streaming

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.

웹소켓의 동작

1. Upgrade 요청

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
+

웹소켓

· 약 5분

웹소켓

+

단일 TCP 연결을 통해 클라이언트와 서버 간 전이중 양방향 통신을 지원하는 프로토콜
+웹 환경에서 연속된 데이터를 실시간으로 처리할 수 있다.

+

웹소켓은 HTTP의 포트를 그대로 사용하고 각각 포트 80과 포트 443을 사용하여 HTTP(ws://) 및 HTTPS(wss://)로 서버에 연결한다.

+

웹소켓 등장 배경

+

웹소켓이 등장하기 이전, 실시간성을 보장하기 위해 Polling, Long polling, Streaming 같은 기술을 사용했어야 했다.
+이는 실시간성이나 양방향성을 만족시키지 못했고, HTTP를 이용하기 때문에 과도한 오버헤드가 발생했다.

+

Polling: 주기적으로 서버에 요청을 보내 수신할 정보가 있는지 확인하는 방법

    +
  • 서버에서 보낼 내용이 없어도 클라이언트는 알 수 없다.
  • +
  • 계속해서 요청을 보내 확인을 해야하기 때문에 서버에 불필요한 부하를 주어야 한다.
  • +

Long Polling: 클라이언트의 요청에 대해 응답을 보내지 않고 있다가 이벤트가 발생했을때 응답하는 방법

    +
  • 폴링 방식보다 서버에 적은 부하를 줄 수 있지만, 요청의 주기가 짧으면 폴링과 차이가 없어진다.
  • +

Streaming: 클라이언트가 request를 보내면 커넥션을 맺고, 이 커넥션을 유지하면서 서버가 계속 데이터를 보내는 방법

    +
  • 클라이언트가 서버에 요청을 하고 싶다면 새로운 커넥션을 맺어야 한다.
  • +
+

웹소켓의 동작

+ +

1. Upgrade 요청

+

WebSocket 프로토콜로 전환하는 HTTP 요청을 보낸다.
이는 HTTP와 같이 80, 443 포트를 사용한다.
웹소켓으로 전환하기 위해서는 Upgrade: websocket, Connection: Upgrade 헤더가 필요하다.
Sec-WebSocket-Key는 서버에서 Sec-WebSocket-Accept를 계산하여 응답하고 이 값이 예상한 값과 다르면 연결이 수립되지 않는다.
Sec-WebSocket-Protocol의 경우 서브프로토콜의 목록으로 서버 측에서는 해당 목록 중 하나를 선택하여 반환해야 한다.
-만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

GET /chats HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
Sec-WebSocket-Protocol: v10.stomp, v11.stomp
Sec-WebSocket-Version: 13
Origin: http://localhost:8080

2. Switching Protocols

서버는 101 Switching Protocols 응답을 반환한다.
+만약 서버측에서 여러 개 지원이 가능한 경우 지원 가능한 프로토콜 중 첫번째 프로토콜을 클라이언트측으로 보낸다.

+
GET /chats HTTP/1.1
+Host: localhost:8080
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Key: Uc9l9TMkWGbHFD2qnFHltg==
+Sec-WebSocket-Protocol: v10.stomp, v11.stomp
+Sec-WebSocket-Version: 13
+Origin: http://localhost:8080
+
+

2. Switching Protocols

+

서버는 101 Switching Protocols 응답을 반환한다.
Sec-WebSocket-Accept은 Sec-WebSocket-Key 뒤에 258EAFA5-E914-47DA-95CA-C5AB0DC85B11를 붙이고 SHA1로 해싱 후 Base64로 인코딩하여 반환한다.
-이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

HTTP/1.1 101 Switching Protocols 
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
Sec-WebSocket-Protocol: v10.stomp

3. 통신 후 종료

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
-연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

참고 자료

https://datatracker.ietf.org/doc/html/rfc6455
-https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
-https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
-https://docs.spring.io/spring-framework/reference/web/websocket.html

- - +이는 서버 웹소켓 프로토콜의 지원 여부를 클라이언트에게 명확히 알리기 위해 존재한다.

+
HTTP/1.1 101 Switching Protocols 
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Accept: 1qVdfYHU9hPOl4JYYNXF623Gzn0=
+Sec-WebSocket-Protocol: v10.stomp
+
+

3. 통신 후 종료

+

연결이 수립되면 웹소켓 프레임 단위로 양방향 통신을 한다.
+연결 종료를 원하는 경우 클라이언트, 서버 모두 연결 종료를 요청할 수 있다.

+

참고 자료

+

https://datatracker.ietf.org/doc/html/rfc6455
+https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications
+https://developer.mozilla.org/ko/docs/Web/API/WebSockets_API/Writing_WebSocket_servers
+https://docs.spring.io/spring-framework/reference/web/websocket.html

\ No newline at end of file diff --git a/woowacourse-level1-retrospective.html b/woowacourse-level1-retrospective.html index ed227e50c..5e254db4f 100644 --- a/woowacourse-level1-retrospective.html +++ b/woowacourse-level1-retrospective.html @@ -2,8 +2,8 @@ - -우아한테크코스 레벨 1 회고 | GG + +우아한테크코스 레벨 1 회고 | GG @@ -12,45 +12,78 @@ - - - + + + -
-

우아한테크코스 레벨 1 회고

· 약 8분

레벨 1이 끝났다.
+

우아한테크코스 레벨 1 회고

· 약 8분

레벨 1이 끝났다.
우테코를 시작하기 전 내가 정해두었던 목표 이상으로 달성했기 때문에 매우 만족스럽다.
혼자 독학을 할 땐 이 방향으로 공부하는 게 맞는지 계속 반추하다 결국 무기력함에 빠져들었다.
-하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

Keep

나만의 루틴 만들기

스스로가 외부의 영향을 많이 받는다고 생각한다.
-최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
+하지만 이제는 같이 공부할 사람도 있고, 이야기할 사람도 있기 때문에 즐기는 일만 남은 것 같다.

+

Keep

+

나만의 루틴 만들기

+

스스로가 외부의 영향을 많이 받는다고 생각한다.
+최대한 꾸준히 할 수 있는 시간을 만드는 것이 중요하다고 생각한다.

+

매일 8시에 도착하여 아침에 해야 할 일을 정리하거나, 우선순위에 따라 처리하고
소화능력이 부족하기 때문에 점심은 도시락(그래봤자 계란2개)을 준비하고
항상 똑같은 컨디션을 유지하기 위해 항상 6시에 집에 간다.
-이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

크루들과 친하게 지내기

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
+이제 바빠질 테니 일찍 집에 가는 일은 어쩔 수 없이 줄어들겠지만😢

+

선택도 비용이다. 앞으로 의사결정이 필요 없는 부분을 최대한 많이 만들어야겠다.

+

크루들과 친하게 지내기

+

10명 정도의 크루의 닉네임을 외우고 친하게 지낸다면 성공적이라고 생각했었다.
하다 보니 더 많은 크루들의 닉네임을 외운 것 같다.
-앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

글쓰기

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
-매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
+앞으로도 크루들과 친하게 지내고 아무 때나 말을 걸 수 있는 크루가 늘어나길 :)

+

글쓰기

+

글을 잘 쓰는 편은 아니지만 꾸준히 작성하려고 노력했다.
+매 미션마다 회고를 작성하니 생각도 정리되고 개선점도 찾을 수 있어서 좋았다.

+

우아한테크코스에는 레벨마다 글쓰기를 진행하는데, 운이 좋게 글쓰기 상을 받았다.
사실 겉으로 드러내지 않았지만 꼭 받아보고 싶었다.
-글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

코드 리뷰 스터디

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
+글쓰기 조원, 투표해 준 크루들에게 너무 감사하다.

+

코드 리뷰 스터디

+

누누, 주노, 다즐, 말랑, 박스터, 오잉, 깃짱와 코드 리뷰 스터디를 진행했다.
과연 도움이 될까 생각했지만 결과적으로는 코드 리뷰를 하면서 성장을 많이 한 것 같다.
투자한 시간 대비 가성비가 좋은 활동이었다.
-누누가 스터디장인데 과연 꾸준히 이어나가려나?

레벨 인터뷰

인터뷰할 때 많이 떨지 않아서 좋았다.
+누누가 스터디장인데 과연 꾸준히 이어나가려나?

+

레벨 인터뷰

+

인터뷰할 때 많이 떨지 않아서 좋았다.
남들 앞에서 이야기를 하거나, 면접을 보면 항상 엄청 떨어서 걱정했는데
기술적인 질문을 받았을 때 떨지 않고 잘 대답할 수 있었다.
우아한테크코스 생활을 하면서 다른 크루가 질문했을 때, 최대한 이해하기 쉽게 설명하려고 했던 경험이 도움이 된 것 같다.
-이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • 두괄식 표현
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • 설명할 수 있을만큼 시간 충분히 가지기
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • 끝맺는 부분 연습하기(자신감 있게)
  • 기술적인 집착가지기
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기

Problem

페어프로그래밍

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
+이후 레벨 인터뷰를 진행할 때 다음과 같은 부분을 고려하면 더 좋을 것 같다.

+
    +
  • 대답하면서 질문을 계속 생각하며 잊어버리지 말기
  • +
  • 두괄식 표현
  • +
  • 설명하다가 잘못 설명한 것 같으면 다 끊고 다시 이야기해도 될지 물어보기
  • +
  • 설명할 수 있을만큼 시간 충분히 가지기
  • +
  • 인터뷰어의 질문 의도를 명확히 이해하지 못했다면 의도 다시 물어보기
  • +
  • 끝맺는 부분 연습하기(자신감 있게)
  • +
  • 기술적인 집착가지기
  • +
  • 기술적인 부분을 꼼꼼히 준비했으면 협업 관련 질문도 준비하기
  • +
+

Problem

+

페어프로그래밍

+

우아한테크코스를 진행하면서 가장 어려운 활동 중 하나라고 생각한다.
페어는 매번 바뀌고, 미션의 복잡도도 증가하기 때문인 것 같다.
소통 능력, 시간관리가 부족했고, 만족스럽지 않았다.
하지만 페어를 진행하고, 회고를 하다 보니 나만의 노하우가 쌓이는 느낌이다.
-레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

집중하는 시간⏱️ 부족

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
-이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

Try

허브🌿와의 티타임?

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
+레벨 2에서는 부족했던 부분을 개선하여 함께하고 싶은 페어가 되고 싶다.

+

집중하는 시간⏱️ 부족

+

레벨 1을 진행하면서 집중하는 시간이 많이 부족했다.
+이른 아침과 오후에 개인적으로 집중할 수 있는 공간을 예약해서 온전히 나만의 시간을 가져야겠다.

+

Try

+

허브🌿와의 티타임?

+

소프트 스킬을 늘릴 방법을 생각하다가 대화를 나누지 못한 다른 크루들과 깜짝 커피챗을 하면 어떨까 생각했다.
예를 들어 잡담방에 저와 커피챗 하실 분 :) 하면서 올릴 수 있을 것 같다.
참여하는 사람이 있을지, 안 좋게 보는 게 아닐지 걱정되지만 그래도 재밌을 것 같다.
-저랑 허브티 한잔 하실래요?

기술적인 부분

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
+저랑 허브티 한잔 하실래요?

+

기술적인 부분

+

우아한테크코스 생활을 하면서 소프트 스킬에 조금 더 무게를 두다 보니 이론적인 부분이 부족할 수 있다고 생각했다.
시간의 여유가 될 때 책을 조금씩 읽어야겠다.
-블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

레벨 1을 마무리하며

시간이 빠르게 흘러갔다.
+블로그에 기술적인 부분을 많이 정리하지 않았는데, 조금 더 깊게 공부하고 정리하는 시간도 가져야겠다.

+

레벨 1을 마무리하며

+

시간이 빠르게 흘러갔다.
타인에게 좋은 영향을 주기위해, 방학동안 나를 챙기는 시간을 가져야겠다.
-또한 함께 일하고 싶은 사람을 목표로 앞으로도 꾸준히 의식적 노력을 해야겠다.

- - +또한 함께 일하고 싶은 사람을 목표로 앞으로도 꾸준히 의식적 노력을 해야겠다.

\ No newline at end of file diff --git a/woowacourse-level2-retrospective.html b/woowacourse-level2-retrospective.html index b4a62d634..16caa9c8d 100644 --- a/woowacourse-level2-retrospective.html +++ b/woowacourse-level2-retrospective.html @@ -2,8 +2,8 @@ - -우아한테크코스 레벨 2 회고 | GG + +우아한테크코스 레벨 2 회고 | GG @@ -12,24 +12,32 @@ - - - + + + -
-

우아한테크코스 레벨 2 회고

· 약 3분

23년의 6월이 오고, 레벨 2가 끝났다.
-빠르게 지나가서 조금 아쉽다.

학습

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
+

우아한테크코스 레벨 2 회고

· 약 3분

23년의 6월이 오고, 레벨 2가 끝났다.
+빠르게 지나가서 조금 아쉽다.

+

학습

+

회고를 작성하기 전에 레벨 2 동안 보냈던 PR과 회고를 쭉 읽어봤다.
항상 아쉬운 곳은 있기 마련이지만, 잘 학습한 것 같다.
-미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
-방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
-필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

수면

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
-앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

협업

레벨 2 마지막에 협업 미션이 있었다.
+미션을 하면서 기술을 어떻게 선택하고, 적용할 것인지 고민하는 과정에서 꽤나 많은 성장을 한 것 같다.

+

고민은 깊었지만 이론적인 학습이 부족한 레벨 2였다.
+방학 그리고 레벨 3 때는 조금 더 이론적인 부분을 학습하는데 집중해야겠다.

+

점차 학습 범위가 넓어지면서 자연스럽게 모르는 내용이 쌓여간다.
+필요한 내용은 앞으로 천천히 학습하면 되니까 조급해지지 말아야겠다.

+

수면

+

레벨 2를 진행하는 동안 수면이 많이 부족했었고, 결과적으로는 그날의 컨디션을 많이 좌우했던 것 같다.
+앞으로 수면 시간을 늘리고, 좋은 수면 습관을 가지도록 노력해야겠다.

+

협업

+

레벨 2 마지막에 협업 미션이 있었다.
지금까지는 백엔드 크루들과 페어 프로그래밍을 하면서 협업을 경험했다.
-이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
-팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

레벨 2를 마무리하며

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. -읽고 싶은 책도 읽고, 부족한 부분 채우면서 쉬어야겠다.

- - +이번에는 프런트엔드 크루와 협업을 했다. 소통은 잘 된 것 같지만 API 명세를 정하는 부분이 아직 미숙한 것 같다.

+

레벨 3 때부터 본격적으로 프로젝트가 시작된다.
+팀을 위해 어떤 것을 할 수 있을지 고민을 많이 해봐야겠다.

+

레벨 2를 마무리하며

+

회고 작성하면서 레벨 2에서 했던 것들을 반추해 봤는데 부족한 점은 많았어도 좋은 방향으로 가고 있는 것 같다. +읽고 싶은 책도 읽고, 부족한 부분 채우면서 쉬어야겠다.

\ No newline at end of file diff --git a/woowacourse-level3-retrospective.html b/woowacourse-level3-retrospective.html index e6c086adb..c5366e8e7 100644 --- a/woowacourse-level3-retrospective.html +++ b/woowacourse-level3-retrospective.html @@ -2,8 +2,8 @@ - -우아한테크코스 레벨 3 회고 | GG + +우아한테크코스 레벨 3 회고 | GG @@ -12,28 +12,43 @@ - - - + + + -
-

우아한테크코스 레벨 3 회고

· 약 4분

회고

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
+

우아한테크코스 레벨 3 회고

· 약 4분

회고

+

지난 8주는 레벨 1, 2 때보다 5배 정도 빠르게 지나간 것 같은 느낌이 들었다.
레벨 3에는 기술적인 부분에서도, 기술 외적인 부분에서도 부족함이 많이 보였던 것 같다.
부족한 부분을 알았기에, 앞으로 더욱 성장할 수 있을 것 같다.
-내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

아쉬운 점

문서화

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
+내가 부족했던 부분을 팀원들이 잘 보충해 줘서 든든했다.

+

아쉬운 점

+

문서화

+

개인적으로는 기술 외적으로 학습한 부분을 잘 정리하지 못했다.
프로젝트를 진행하면서 내가 한 부분을 조금 더 꼼꼼하게, 이해하기 쉽게 문서화를 했더라면 팀원들에게 더욱 도움이 되었을 텐데 이 부분에 시간을 조금 더 투자하지 못했던 부분에서 아쉬움이 많이 들었다.
-방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

내가 못하는 부분이라면 시간을 들이자

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
+방학 기간 동안 문서화를 하지 못했던 부분을 개인 블로그 올리면서 조금 더 채워보려고 한다.

+

내가 못하는 부분이라면 시간을 들이자

+

잘 못하는 부분이라면 시간을 들여서라도 중간은 가도록 해야겠다는 생각이 많이 들었다.
말을 하기 전에 정리해서 의견을 내는 것, 발표 준비, 감정 조절 등등 -못하는 부분을 인지하고, 개선하자.

컴포트 존 벗어나기

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
+못하는 부분을 인지하고, 개선하자.

+

컴포트 존 벗어나기

+

조금 더 도전적으로 목표를 잡았으면 좋았을 것 같다.
매번 근거를 가지고 기술을 도입하고, 코드를 작성하려고 노력했다.
-하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

좋았던 점

좋았던 점도 문서화

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
-백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

내가 디자인한 트립드로우 로고

트립드로우 로고를 만들었다.
+하지만 지속적으로 개선하려고 하는 부분이 다소 부족했다.

+

좋았던 점

+

좋았던 점도 문서화

+

팀 블로그도 먼저 도입하자고 제안하고, 내가 했던 부분은 문서화를 꽤 많이 해서 팀원들과 공유할 수 있었다.
+백엔드 크루 4명이서 같이 한 부분에 대해서는 기능 구현한다고 문서화가 조금 미흡해서 보충을 해야겠다.

+

내가 디자인한 트립드로우 로고

+ +

트립드로우 로고를 만들었다.
팀원들이 대표 색상(파란색)을 정해줬고, 주말 동안 신나게 로고 디자인을 했던 것 같다.
-아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

기술 선택의 이유

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
-100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

마치며

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
-안드로이드 브레멘 음악대(멧돼지, 수달, 핑구), 그리고 백엔드 팀원들(체인저, 후추, 리오) 너무 고생이 많았다.

- - +아래의 D 부분은 유튜브 강의 들으면서 직접 만들어서 뿌듯하다.

+

기술 선택의 이유

+

기술의 학습 비용, 현재 구조에 적합한지, 실제 가지고 있는 리소스를 고려해서 기술 선택을 하고, 도입했던 부분이 좋았다.
+100% 좋은 선택일 순 없지만, 그래도 선택에 대한 근거가 존재한다면 확률을 높혀주는 것 같다.

+

마치며

+

플레이스토어에 앱이 올라가 있는 거 너무 신기하다.
+안드로이드 브레멘 음악대(멧돼지, 수달, 핑구), 그리고 백엔드 팀원들(체인저, 후추, 리오) 너무 고생이 많았다.

\ No newline at end of file